diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml index 2284a5fb36b..e45dc2d4365 100644 --- a/.azure-pipelines/ci.yml +++ b/.azure-pipelines/ci.yml @@ -1,14 +1,14 @@ variables: coverage: false -trigger: ['main', '3.10', '3.9', '3.8', '3.7'] +trigger: ['main', '3.11', '3.10', '3.9', '3.8', '3.7'] jobs: - job: Prebuild displayName: Pre-build checks pool: - vmImage: ubuntu-20.04 + vmImage: ubuntu-22.04 steps: - template: ./prebuild-checks.yml @@ -20,7 +20,7 @@ jobs: condition: and(succeeded(), eq(dependencies.Prebuild.outputs['docs.run'], 'true')) pool: - vmImage: ubuntu-20.04 + vmImage: ubuntu-22.04 steps: - template: ./docs-steps.yml @@ -52,12 +52,12 @@ jobs: condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true')) pool: - vmImage: ubuntu-20.04 + vmImage: ubuntu-22.04 variables: testRunTitle: '$(build.sourceBranchName)-linux' testRunPlatform: linux - openssl_version: 1.1.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: diff --git a/.azure-pipelines/find-tools.yml b/.azure-pipelines/find-tools.yml deleted file mode 100644 index 9ad0f5622bb..00000000000 --- a/.azure-pipelines/find-tools.yml +++ /dev/null @@ -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' diff --git a/.azure-pipelines/libffi-build.yml b/.azure-pipelines/libffi-build.yml deleted file mode 100644 index dd26ff215a8..00000000000 --- a/.azure-pipelines/libffi-build.yml +++ /dev/null @@ -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' diff --git a/.azure-pipelines/openssl-build.yml b/.azure-pipelines/openssl-build.yml deleted file mode 100644 index 8aab7ea0b94..00000000000 --- a/.azure-pipelines/openssl-build.yml +++ /dev/null @@ -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)' diff --git a/.azure-pipelines/posix-steps.yml b/.azure-pipelines/posix-steps.yml index b6dde593019..9d7c5e1279f 100644 --- a/.azure-pipelines/posix-steps.yml +++ b/.azure-pipelines/posix-steps.yml @@ -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')) diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml index 1a3bf75ed4c..af94ebf78c8 100644 --- a/.azure-pipelines/pr.yml +++ b/.azure-pipelines/pr.yml @@ -1,14 +1,14 @@ variables: coverage: false -pr: ['main', '3.10', '3.9', '3.8', '3.7'] +pr: ['main', '3.11', '3.10', '3.9', '3.8', '3.7'] jobs: - job: Prebuild displayName: Pre-build checks pool: - vmImage: ubuntu-20.04 + vmImage: ubuntu-22.04 steps: - template: ./prebuild-checks.yml @@ -20,7 +20,7 @@ jobs: condition: and(succeeded(), eq(dependencies.Prebuild.outputs['docs.run'], 'true')) pool: - vmImage: ubuntu-20.04 + vmImage: ubuntu-22.04 steps: - template: ./docs-steps.yml @@ -52,12 +52,12 @@ jobs: condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true')) pool: - vmImage: ubuntu-20.04 + vmImage: ubuntu-22.04 variables: testRunTitle: '$(system.pullRequest.TargetBranch)-linux' testRunPlatform: linux - openssl_version: 1.1.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: diff --git a/.azure-pipelines/tcltk-build.yml b/.azure-pipelines/tcltk-build.yml deleted file mode 100644 index 27968e886cc..00000000000 --- a/.azure-pipelines/tcltk-build.yml +++ /dev/null @@ -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' diff --git a/.azure-pipelines/windows-layout-steps.yml b/.azure-pipelines/windows-layout-steps.yml index e15729fac34..afd89781790 100644 --- a/.azure-pipelines/windows-layout-steps.yml +++ b/.azure-pipelines/windows-layout-steps.yml @@ -12,7 +12,7 @@ steps: displayName: Show layout info (${{ parameters.kind }}) - ${{ if eq(parameters.fulltest, 'true') }}: - - script: .\python.exe -m test -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 --junit-xml="$(Build.BinariesDirectory)\test-results-${{ parameters.kind }}.xml" --tempdir "$(Build.BinariesDirectory)\tmp-${{ parameters.kind }}-$(arch)" + - script: .\python.exe -m test -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 --junit-xml="$(Build.BinariesDirectory)\test-results-${{ parameters.kind }}.xml" --tempdir "$(Build.BinariesDirectory)\tmp-${{ parameters.kind }}-$(arch)" -i test_launcher workingDirectory: $(Build.BinariesDirectory)\layout-${{ parameters.kind }}-$(arch) displayName: ${{ parameters.kind }} Tests env: diff --git a/.azure-pipelines/windows-release.yml b/.azure-pipelines/windows-release.yml deleted file mode 100644 index 3d072e3b43e..00000000000 --- a/.azure-pipelines/windows-release.yml +++ /dev/null @@ -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 diff --git a/.azure-pipelines/windows-release/build-steps.yml b/.azure-pipelines/windows-release/build-steps.yml deleted file mode 100644 index 5ca2016d65f..00000000000 --- a/.azure-pipelines/windows-release/build-steps.yml +++ /dev/null @@ -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 diff --git a/.azure-pipelines/windows-release/checkout.yml b/.azure-pipelines/windows-release/checkout.yml deleted file mode 100644 index d42d55fff08..00000000000 --- a/.azure-pipelines/windows-release/checkout.yml +++ /dev/null @@ -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 (/$(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)/)' - 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']))) diff --git a/.azure-pipelines/windows-release/find-sdk.yml b/.azure-pipelines/windows-release/find-sdk.yml deleted file mode 100644 index e4de78555b3..00000000000 --- a/.azure-pipelines/windows-release/find-sdk.yml +++ /dev/null @@ -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' diff --git a/.azure-pipelines/windows-release/gpg-sign.yml b/.azure-pipelines/windows-release/gpg-sign.yml deleted file mode 100644 index 0855af8d703..00000000000 --- a/.azure-pipelines/windows-release/gpg-sign.yml +++ /dev/null @@ -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 diff --git a/.azure-pipelines/windows-release/layout-command.yml b/.azure-pipelines/windows-release/layout-command.yml deleted file mode 100644 index 406ccd859fa..00000000000 --- a/.azure-pipelines/windows-release/layout-command.yml +++ /dev/null @@ -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' diff --git a/.azure-pipelines/windows-release/mingw-lib.yml b/.azure-pipelines/windows-release/mingw-lib.yml deleted file mode 100644 index 30f7d34fa61..00000000000 --- a/.azure-pipelines/windows-release/mingw-lib.yml +++ /dev/null @@ -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) diff --git a/.azure-pipelines/windows-release/msi-steps.yml b/.azure-pipelines/windows-release/msi-steps.yml deleted file mode 100644 index 307510a40dd..00000000000 --- a/.azure-pipelines/windows-release/msi-steps.yml +++ /dev/null @@ -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 diff --git a/.azure-pipelines/windows-release/stage-build.yml b/.azure-pipelines/windows-release/stage-build.yml deleted file mode 100644 index 69f3b1e1645..00000000000 --- a/.azure-pipelines/windows-release/stage-build.yml +++ /dev/null @@ -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 diff --git a/.azure-pipelines/windows-release/stage-layout-embed.yml b/.azure-pipelines/windows-release/stage-layout-embed.yml deleted file mode 100644 index dbccdead143..00000000000 --- a/.azure-pipelines/windows-release/stage-layout-embed.yml +++ /dev/null @@ -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 diff --git a/.azure-pipelines/windows-release/stage-layout-full.yml b/.azure-pipelines/windows-release/stage-layout-full.yml deleted file mode 100644 index 8fc8da3e52f..00000000000 --- a/.azure-pipelines/windows-release/stage-layout-full.yml +++ /dev/null @@ -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) diff --git a/.azure-pipelines/windows-release/stage-layout-msix.yml b/.azure-pipelines/windows-release/stage-layout-msix.yml deleted file mode 100644 index def4f7d3c6b..00000000000 --- a/.azure-pipelines/windows-release/stage-layout-msix.yml +++ /dev/null @@ -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) diff --git a/.azure-pipelines/windows-release/stage-layout-nuget.yml b/.azure-pipelines/windows-release/stage-layout-nuget.yml deleted file mode 100644 index 41cdff850e8..00000000000 --- a/.azure-pipelines/windows-release/stage-layout-nuget.yml +++ /dev/null @@ -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) diff --git a/.azure-pipelines/windows-release/stage-msi.yml b/.azure-pipelines/windows-release/stage-msi.yml deleted file mode 100644 index 9b965b09c14..00000000000 --- a/.azure-pipelines/windows-release/stage-msi.yml +++ /dev/null @@ -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 diff --git a/.azure-pipelines/windows-release/stage-pack-msix.yml b/.azure-pipelines/windows-release/stage-pack-msix.yml deleted file mode 100644 index f967cfdbe32..00000000000 --- a/.azure-pipelines/windows-release/stage-pack-msix.yml +++ /dev/null @@ -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 diff --git a/.azure-pipelines/windows-release/stage-pack-nuget.yml b/.azure-pipelines/windows-release/stage-pack-nuget.yml deleted file mode 100644 index 8dfea382c35..00000000000 --- a/.azure-pipelines/windows-release/stage-pack-nuget.yml +++ /dev/null @@ -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 diff --git a/.azure-pipelines/windows-release/stage-publish-nugetorg.yml b/.azure-pipelines/windows-release/stage-publish-nugetorg.yml deleted file mode 100644 index d5edf44ef5c..00000000000 --- a/.azure-pipelines/windows-release/stage-publish-nugetorg.yml +++ /dev/null @@ -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' diff --git a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml deleted file mode 100644 index 4b88bdebf8c..00000000000 --- a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml +++ /dev/null @@ -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 diff --git a/.azure-pipelines/windows-release/stage-publish-store.yml b/.azure-pipelines/windows-release/stage-publish-store.yml deleted file mode 100644 index e0512b95f27..00000000000 --- a/.azure-pipelines/windows-release/stage-publish-store.yml +++ /dev/null @@ -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 diff --git a/.azure-pipelines/windows-release/stage-sign.yml b/.azure-pipelines/windows-release/stage-sign.yml deleted file mode 100644 index c21e1c9f2b0..00000000000 --- a/.azure-pipelines/windows-release/stage-sign.yml +++ /dev/null @@ -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' diff --git a/.azure-pipelines/windows-release/stage-test-embed.yml b/.azure-pipelines/windows-release/stage-test-embed.yml deleted file mode 100644 index d99bd74722b..00000000000 --- a/.azure-pipelines/windows-release/stage-test-embed.yml +++ /dev/null @@ -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' diff --git a/.azure-pipelines/windows-release/stage-test-msi.yml b/.azure-pipelines/windows-release/stage-test-msi.yml deleted file mode 100644 index 21e38c39590..00000000000 --- a/.azure-pipelines/windows-release/stage-test-msi.yml +++ /dev/null @@ -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 diff --git a/.azure-pipelines/windows-release/stage-test-nuget.yml b/.azure-pipelines/windows-release/stage-test-nuget.yml deleted file mode 100644 index 94d815e9522..00000000000 --- a/.azure-pipelines/windows-release/stage-test-nuget.yml +++ /dev/null @@ -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' diff --git a/.gitattributes b/.gitattributes index 3363ea8e4e7..13289182400 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 82f81e34529..8dd07d911f5 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -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 diff --git a/.github/CONTRIBUTING.rst b/.github/CONTRIBUTING.rst index 2ac148e3965..2ef9cdc1914 100644 --- a/.github/CONTRIBUTING.rst +++ b/.github/CONTRIBUTING.rst @@ -4,21 +4,9 @@ Contributing to Python Build Status ------------ -- main +- `Buildbot status overview `_ - + `Stable buildbots `_ - -- 3.9 - - + `Stable buildbots `_ - -- 3.8 - - + `Stable buildbots `_ - -- 3.7 - - + `Stable buildbots `_ +- `GitHub Actions status `_ 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 `_. +`Lifecycle of a Pull Request `_. We utilize various bots and status checks to help with this, so do follow the comments they leave and their "Details" links, respectively. The key points of our workflow that are not covered by a bot or status check are: - 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 `_. - Upon your first non-trivial pull request (which includes documentation changes), feel free to add yourself to ``Misc/ACKS`` diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index b08459313ac..00000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,2 +0,0 @@ -custom: https://www.python.org/psf/donations/python-dev/ -github: [python] diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 00000000000..1d93e0735e5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,32 @@ +--- +name: Bug report +about: Submit a bug report +labels: "type-bug" +--- + + + +# 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 + + + +- CPython versions tested on: +- Operating system and architecture: + + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000000..75d174307ce --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -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" diff --git a/.github/ISSUE_TEMPLATE/crash.md b/.github/ISSUE_TEMPLATE/crash.md new file mode 100644 index 00000000000..dad3423db03 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/crash.md @@ -0,0 +1,33 @@ +--- +name: Crash report +about: A hard crash of the interpreter, possibly with a core dump +labels: "type-crash" +--- + + + +# 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 + + + +- CPython versions tested on: +- Operating system and architecture: + + diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md new file mode 100644 index 00000000000..174fd39171d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation.md @@ -0,0 +1,9 @@ +--- +name: Documentation +about: Report a problem with the documentation +labels: "docs" +--- + +# Documentation + +(A clear and concise description of the issue.) diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md new file mode 100644 index 00000000000..ed051e945f8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.md @@ -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 + + + + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 79ceb175c28..4cc2f461dbe 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -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. diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 2aebc5a0bf7..923720bce0b 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -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 diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e90677b9f77..555e246e402 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,3 +7,8 @@ updates: labels: - "skip issue" - "skip news" + ignore: + - dependency-name: "*" + update-types: + - "version-update:semver-minor" + - "version-update:semver-patch" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a11a368fd83..f798992d8af 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -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" diff --git a/.github/workflows/build_msi.yml b/.github/workflows/build_msi.yml index 476a0b1bc07..5f1dcae190e 100644 --- a/.github/workflows/build_msi.yml +++ b/.github/workflows/build_msi.yml @@ -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 }} diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 755a4d5e173..465da12fa1b 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -5,6 +5,7 @@ on: #push: # branches: # - 'main' + # - '3.11' # - '3.10' # - '3.9' # - '3.8' @@ -14,6 +15,7 @@ on: pull_request: branches: - 'main' + - '3.11' - '3.10' - '3.9' - '3.8' @@ -21,15 +23,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 diff --git a/.github/workflows/new-bugs-announce-notifier.yml b/.github/workflows/new-bugs-announce-notifier.yml new file mode 100644 index 00000000000..b2b63472d83 --- /dev/null +++ b/.github/workflows/new-bugs-announce-notifier.yml @@ -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 ", + 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)); diff --git a/.github/workflows/posix-deps-apt.sh b/.github/workflows/posix-deps-apt.sh index fc4aaba552a..a220896f2cd 100755 --- a/.github/workflows/posix-deps-apt.sh +++ b/.github/workflows/posix-deps-apt.sh @@ -7,6 +7,7 @@ apt-get -yq install \ ccache \ gdb \ lcov \ + libb2-dev \ libbz2-dev \ libffi-dev \ libgdbm-dev \ diff --git a/.github/workflows/project-updater.yml b/.github/workflows/project-updater.yml new file mode 100644 index 00000000000..99c7a05ae8c --- /dev/null +++ b/.github/workflows/project-updater.yml @@ -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 }} diff --git a/.github/workflows/regen-abidump.sh b/.github/workflows/regen-abidump.sh new file mode 100644 index 00000000000..251bb3857ec --- /dev/null +++ b/.github/workflows/regen-abidump.sh @@ -0,0 +1,8 @@ +set -ex + +export DEBIAN_FRONTEND=noninteractive +./.github/workflows/posix-deps-apt.sh +apt-get install -yq abigail-tools python3 +export CFLAGS="-g3 -O0" +./configure --enable-shared && make +make regen-abidump diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index e3b8b9f942d..07dbcfe31d6 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -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 diff --git a/.github/workflows/verify-ensurepip-wheels.yml b/.github/workflows/verify-ensurepip-wheels.yml new file mode 100644 index 00000000000..969515ed287 --- /dev/null +++ b/.github/workflows/verify-ensurepip-wheels.yml @@ -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 diff --git a/.gitignore b/.gitignore index 0831c58d367..d9c4a7972f0 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b2f7e274587..00000000000 --- a/.travis.yml +++ /dev/null @@ -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=&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 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index c5f24abe2ca..00000000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -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. - diff --git a/Doc/Makefile b/Doc/Makefile index 24528a1c4f3..3d484ac3ae7 100644 --- a/Doc/Makefile +++ b/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 ' where 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."; \ diff --git a/Doc/README.rst b/Doc/README.rst index 7e8a27b4066..a3bb5fa5445 100644 --- a/Doc/README.rst +++ b/Doc/README.rst @@ -40,7 +40,7 @@ If you'd like to create the virtual environment in a different location, you can specify it using the ``VENVDIR`` variable. You can also skip creating the virtual environment altogether, in which case -the Makefile will look for instances of ``sphinxbuild`` and ``blurb`` +the Makefile will look for instances of ``sphinx-build`` and ``blurb`` installed on your process ``PATH`` (configurable with the ``SPHINXBUILD`` and ``BLURB`` variables). @@ -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 `_. +`Python bug tracker `_. Bugs in the toolset should be reported to the tools themselves. diff --git a/Doc/_static/og-image.png b/Doc/_static/og-image.png new file mode 100644 index 00000000000..0e80751e740 Binary files /dev/null and b/Doc/_static/og-image.png differ diff --git a/Doc/about.rst b/Doc/about.rst index f0b908487b2..5e6160ff270 100644 --- a/Doc/about.rst +++ b/Doc/about.rst @@ -6,8 +6,8 @@ About these documents These documents are generated from `reStructuredText`_ sources by `Sphinx`_, a document processor specifically written for the Python documentation. -.. _reStructuredText: http://docutils.sourceforge.net/rst.html -.. _Sphinx: http://sphinx-doc.org/ +.. _reStructuredText: https://docutils.sourceforge.io/rst.html +.. _Sphinx: https://www.sphinx-doc.org/ .. In the online version of these documents, you can submit comments and suggest changes directly on the documentation pages. @@ -21,7 +21,7 @@ Many thanks go to: * Fred L. Drake, Jr., the creator of the original Python documentation toolset and writer of much of the content; -* the `Docutils `_ project for creating +* the `Docutils `_ project for creating reStructuredText and the Docutils suite; * Fredrik Lundh for his Alternative Python Reference project from which Sphinx got many good ideas. diff --git a/Doc/bugs.rst b/Doc/bugs.rst index b3d057797c2..69d7c27410d 100644 --- a/Doc/bugs.rst +++ b/Doc/bugs.rst @@ -35,43 +35,48 @@ though it may take a while to be processed. `Helping with Documentation `_ Comprehensive guide for individuals that are interested in contributing to Python documentation. + `Documentation Translations `_ + 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/ diff --git a/Doc/c-api/allocation.rst b/Doc/c-api/allocation.rst index 33b0c06a9eb..0a8fcc5ae5f 100644 --- a/Doc/c-api/allocation.rst +++ b/Doc/c-api/allocation.rst @@ -14,7 +14,7 @@ Allocating Objects on the Heap .. c:function:: PyObject* PyObject_Init(PyObject *op, PyTypeObject *type) - Initialize a newly-allocated object *op* with its type and initial + Initialize a newly allocated object *op* with its type and initial reference. Returns the initialized object. If *type* indicates that the object participates in the cyclic garbage detector, it is added to the detector's set of observed objects. Other fields of the object are not diff --git a/Doc/c-api/apiabiversion.rst b/Doc/c-api/apiabiversion.rst index 04050f7dabe..62d54296662 100644 --- a/Doc/c-api/apiabiversion.rst +++ b/Doc/c-api/apiabiversion.rst @@ -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`. diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index 1d93b35dc1c..9713431688d 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -34,24 +34,39 @@ These formats allow accessing an object as a contiguous chunk of memory. You don't have to provide raw storage for the returned unicode or bytes area. -In general, when a format sets a pointer to a buffer, the buffer is -managed by the corresponding Python object, and the buffer shares -the lifetime of this object. You won't have to release any memory yourself. -The only exceptions are ``es``, ``es#``, ``et`` and ``et#``. - -However, when a :c:type:`Py_buffer` structure gets filled, the underlying -buffer is locked so that the caller can subsequently use the buffer even -inside a :c:type:`Py_BEGIN_ALLOW_THREADS` block without the risk of mutable data -being resized or destroyed. As a result, **you have to call** -:c:func:`PyBuffer_Release` after you have finished processing the data (or -in any early abort case). - Unless otherwise stated, buffers are not NUL-terminated. -Some formats require a read-only :term:`bytes-like object`, and set a -pointer instead of a buffer structure. They work by checking that -the object's :c:member:`PyBufferProcs.bf_releasebuffer` field is ``NULL``, -which disallows mutable objects such as :class:`bytearray`. +There are three ways strings and buffers can be converted to C: + +* Formats such as ``y*`` and ``s*`` fill a :c:type:`Py_buffer` structure. + This locks the underlying buffer so that the caller can subsequently use + the buffer even inside a :c:type:`Py_BEGIN_ALLOW_THREADS` + block without the risk of mutable data being resized or destroyed. + As a result, **you have to call** :c:func:`PyBuffer_Release` after you have + finished processing the data (or in any early abort case). + +* The ``es``, ``es#``, ``et`` and ``et#`` formats allocate the result buffer. + **You have to call** :c:func:`PyMem_Free` after you have finished + processing the data (or in any early abort case). + +* .. _c-arg-borrowed-buffer: + + Other formats take a :class:`str` or a read-only :term:`bytes-like object`, + such as :class:`bytes`, and provide a ``const char *`` pointer to + its buffer. + In this case the buffer is "borrowed": it is managed by the corresponding + Python object, and shares the lifetime of this object. + You won't have to release any memory yourself. + + To ensure that the underlying buffer may be safely borrowed, the object's + :c:member:`PyBufferProcs.bf_releasebuffer` field must be ``NULL``. + This disallows common mutable objects such as :class:`bytearray`, + but also some read-only objects such as :class:`memoryview` of + :class:`bytes`. + + Besides this ``bf_releasebuffer`` requirement, there is no check to verify + whether the input object is immutable (e.g. whether it would honor a request + for a writable buffer, or whether another thread can mutate the data). .. note:: @@ -89,7 +104,7 @@ which disallows mutable objects such as :class:`bytearray`. Unicode objects are converted to C strings using ``'utf-8'`` encoding. ``s#`` (:class:`str`, read-only :term:`bytes-like object`) [const char \*, :c:type:`Py_ssize_t`] - Like ``s*``, except that it doesn't accept mutable objects. + Like ``s*``, except that it provides a :ref:`borrowed buffer `. The result is stored into two C variables, the first one a pointer to a C string, the second one its length. The string may contain embedded null bytes. Unicode objects are converted @@ -108,8 +123,9 @@ which disallows mutable objects such as :class:`bytearray`. pointer is set to ``NULL``. ``y`` (read-only :term:`bytes-like object`) [const char \*] - This format converts a bytes-like object to a C pointer to a character - string; it does not accept Unicode objects. The bytes buffer must not + This format converts a bytes-like object to a C pointer to a + :ref:`borrowed ` character string; + it does not accept Unicode objects. The bytes buffer must not contain embedded null bytes; if it does, a :exc:`ValueError` exception is raised. @@ -129,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 `. 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. diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst index e32719373cc..a04062fb2a6 100644 --- a/Doc/c-api/buffer.rst +++ b/Doc/c-api/buffer.rst @@ -99,7 +99,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. For :term:`contiguous` arrays, the value points to the beginning of the memory block. - .. c:member:: void *obj + .. c:member:: PyObject *obj A new reference to the exporting object. The reference is owned by the consumer and automatically decremented and set to ``NULL`` by @@ -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 diff --git a/Doc/c-api/bytearray.rst b/Doc/c-api/bytearray.rst index 30bcfc7cf9f..4bf3cfe100c 100644 --- a/Doc/c-api/bytearray.rst +++ b/Doc/c-api/bytearray.rst @@ -42,8 +42,6 @@ Direct API functions Return a new bytearray object from any object, *o*, that implements the :ref:`buffer protocol `. - .. 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. diff --git a/Doc/c-api/bytes.rst b/Doc/c-api/bytes.rst index de65701037a..d62962cab45 100644 --- a/Doc/c-api/bytes.rst +++ b/Doc/c-api/bytes.rst @@ -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) diff --git a/Doc/c-api/call.rst b/Doc/c-api/call.rst index 739b5e97d15..4dc66e318cd 100644 --- a/Doc/c-api/call.rst +++ b/Doc/c-api/call.rst @@ -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 `. @@ -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 ` 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 `. - .. 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 `. - .. 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 `. - .. 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 `. - .. 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 `. - .. 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 `. - .. 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 `. - .. 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 `. - .. 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 `. - .. versionadded:: 3.9 diff --git a/Doc/c-api/capsule.rst b/Doc/c-api/capsule.rst index 908e92653dd..1c8f432505e 100644 --- a/Doc/c-api/capsule.rst +++ b/Doc/c-api/capsule.rst @@ -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) diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index 2b0cdf43243..a6eb86f1a0b 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -1,9 +1,9 @@ .. highlight:: c -.. _codeobjects: - .. index:: object; code, code object +.. _codeobjects: + Code Objects ------------ @@ -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 - `_. + `_. .. 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 diff --git a/Doc/c-api/complex.rst b/Doc/c-api/complex.rst index c25894681bc..9228ce85200 100644 --- a/Doc/c-api/complex.rst +++ b/Doc/c-api/complex.rst @@ -115,12 +115,12 @@ Complex Numbers as Python Objects .. c:function:: double PyComplex_RealAsDouble(PyObject *op) - Return the real part of *op* as a C :c:type:`double`. + Return the real part of *op* as a C :c:expr:`double`. .. c:function:: double PyComplex_ImagAsDouble(PyObject *op) - Return the imaginary part of *op* as a C :c:type:`double`. + Return the imaginary part of *op* as a C :c:expr:`double`. .. c:function:: Py_complex PyComplex_AsCComplex(PyObject *op) diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst index 84224dcca52..8d3124a12fa 100644 --- a/Doc/c-api/concrete.rst +++ b/Doc/c-api/concrete.rst @@ -111,6 +111,7 @@ Other Objects memoryview.rst weakref.rst capsule.rst + frame.rst gen.rst coro.rst contextvars.rst diff --git a/Doc/c-api/conversion.rst b/Doc/c-api/conversion.rst index 7b4cc1cacdd..fdb321fe7ab 100644 --- a/Doc/c-api/conversion.rst +++ b/Doc/c-api/conversion.rst @@ -28,7 +28,8 @@ not. The wrappers ensure that ``str[size-1]`` is always ``'\0'`` upon return. They never write more than *size* bytes (including the trailing ``'\0'``) into str. Both functions require that ``str != NULL``, ``size > 0``, ``format != NULL`` -and ``size < INT_MAX``. +and ``size < INT_MAX``. Note that this means there is no equivalent to the C99 +``n = snprintf(NULL, 0, ...)`` which would determine the necessary buffer size. The return value (*rv*) for these functions should be interpreted as follows: @@ -49,7 +50,7 @@ The following functions provide locale-independent string to number conversions. .. c:function:: double PyOS_string_to_double(const char *s, char **endptr, PyObject *overflow_exception) - Convert a string ``s`` to a :c:type:`double`, raising a Python + Convert a string ``s`` to a :c:expr:`double`, raising a Python exception on failure. The set of accepted strings corresponds to the set of strings accepted by Python's :func:`float` constructor, except that ``s`` must not have leading or trailing whitespace. @@ -83,7 +84,7 @@ The following functions provide locale-independent string to number conversions. .. c:function:: char* PyOS_double_to_string(double val, char format_code, int precision, int flags, int *ptype) - Convert a :c:type:`double` *val* to a string using supplied + Convert a :c:expr:`double` *val* to a string using supplied *format_code*, *precision*, and *flags*. *format_code* must be one of ``'e'``, ``'E'``, ``'f'``, ``'F'``, diff --git a/Doc/c-api/datetime.rst b/Doc/c-api/datetime.rst index 4c4e4bcfa63..72fc07afbf1 100644 --- a/Doc/c-api/datetime.rst +++ b/Doc/c-api/datetime.rst @@ -132,6 +132,7 @@ Macros to create objects: resulting number of microseconds and seconds lie in the ranges documented for :class:`datetime.timedelta` objects. + .. c:function:: PyObject* PyTimeZone_FromOffset(PyDateTime_DeltaType* offset) Return a :class:`datetime.timezone` object with an unnamed fixed offset @@ -139,6 +140,7 @@ Macros to create objects: .. versionadded:: 3.7 + .. c:function:: PyObject* PyTimeZone_FromOffsetAndName(PyDateTime_DeltaType* offset, PyUnicode* name) Return a :class:`datetime.timezone` object with a fixed offset represented @@ -190,12 +192,21 @@ must not be ``NULL``, and the type is not checked: Return the microsecond, as an int from 0 through 999999. + +.. c:function:: int PyDateTime_DATE_GET_FOLD(PyDateTime_DateTime *o) + + Return the fold, as an int from 0 through 1. + + .. versionadded:: 3.6 + + .. c:function:: PyObject* PyDateTime_DATE_GET_TZINFO(PyDateTime_DateTime *o) Return the tzinfo (which may be ``None``). .. versionadded:: 3.10 + Macros to extract fields from time objects. The argument must be an instance of :c:data:`PyDateTime_Time`, including subclasses. The argument must not be ``NULL``, and the type is not checked: @@ -219,6 +230,14 @@ and the type is not checked: Return the microsecond, as an int from 0 through 999999. + +.. c:function:: int PyDateTime_TIME_GET_FOLD(PyDateTime_Time *o) + + Return the fold, as an int from 0 through 1. + + .. versionadded:: 3.6 + + .. c:function:: PyObject* PyDateTime_TIME_GET_TZINFO(PyDateTime_Time *o) Return the tzinfo (which may be ``None``). diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index d257c9b5f76..e5f28b59a70 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -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 diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 5d90248f85a..087e0a61d12 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -14,7 +14,7 @@ there is a global indicator (per thread) of the last error that occurred. Most C API functions don't clear this on success, but will set it to indicate the cause of the error on failure. Most C API functions also return an error indicator, usually ``NULL`` if they are supposed to return a pointer, or ``-1`` -if they return an integer (exception: the :c:func:`PyArg_\*` functions +if they return an integer (exception: the ``PyArg_*`` functions return ``1`` for success and ``0`` for failure). Concretely, the error indicator consists of three object pointers: the @@ -189,7 +189,7 @@ For convenience, some of these functions will always return a .. c:function:: PyObject* PyErr_SetFromWindowsErr(int ierr) This is a convenience function to raise :exc:`WindowsError`. If called with - *ierr* of :c:data:`0`, the error code returned by a call to :c:func:`GetLastError` + *ierr* of ``0``, the error code returned by a call to :c:func:`GetLastError` is used instead. It calls the Win32 function :c:func:`FormatMessage` to retrieve the Windows description of error code given by *ierr* or :c:func:`GetLastError`, then it constructs a tuple object whose first item is the *ierr* value and whose @@ -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. diff --git a/Doc/c-api/file.rst b/Doc/c-api/file.rst index ed3735aa836..58ed58e5466 100644 --- a/Doc/c-api/file.rst +++ b/Doc/c-api/file.rst @@ -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 diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst index c107243a88d..023b12c20b7 100644 --- a/Doc/c-api/float.rst +++ b/Doc/c-api/float.rst @@ -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. diff --git a/Doc/c-api/frame.rst b/Doc/c-api/frame.rst new file mode 100644 index 00000000000..1ac8f03d6e4 --- /dev/null +++ b/Doc/c-api/frame.rst @@ -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 ` + 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 `. + +.. c:var:: PyTypeObject PyFrame_Type + + The type of frame objects. + It is the same object as :py:class:`types.FrameType` in the Python layer. + + .. versionchanged:: 3.11 + + Previously, this type was only available after including + ````. + +.. c:function:: int PyFrame_Check(PyObject *obj) + + Return non-zero if *obj* is a frame object. + + .. versionchanged:: 3.11 + + Previously, this function was only available after including + ````. + +.. c:function:: PyFrameObject* PyFrame_GetBack(PyFrameObject *frame) + + 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. diff --git a/Doc/c-api/function.rst b/Doc/c-api/function.rst index 56c18396d32..3cce18bdde3 100644 --- a/Doc/c-api/function.rst +++ b/Doc/c-api/function.rst @@ -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 diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst index d2ae6b6d4e4..a51619db6d3 100644 --- a/Doc/c-api/import.rst +++ b/Doc/c-api/import.rst @@ -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 diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 09dfc68fee5..ad06616eeb0 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -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 `. + 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 `. + 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 `. + 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 `. + 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 + `. + 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 `. + 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 `. + 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 `. + 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 `. + 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 `. + 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 `. + 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 `. + 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 `. + Don't add the :data:`user site-packages directory ` 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 `. + 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 `. + 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 `. + 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 `. + 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 `. + .. 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 `. + .. 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 `. + 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 `. @@ -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 `. + 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 `. .. 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. diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index 989660caeda..161def0b4ba 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -16,12 +16,12 @@ There are two kinds of configuration: * The :ref:`Python Configuration ` 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 ` 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 `: - see :c:member:`PyConfig.dev_mode`. + :ref:`Python Development Mode `: see + :c:member:`PyConfig.dev_mode`. Default: ``-1`` in Python mode, ``0`` in isolated mode. @@ -329,8 +329,10 @@ PyPreConfig If non-zero, enable the :ref:`Python UTF-8 Mode `. - Set by the :option:`-X utf8 <-X>` command line option and the - :envvar:`PYTHONUTF8` environment variable. + Set to ``0`` or ``1`` by the :option:`-X utf8 <-X>` command line option + and the :envvar:`PYTHONUTF8` environment variable. + + Also set to ``1`` if the ``LC_CTYPE`` locale is ``C`` or ``POSIX``. Default: ``-1`` in Python config and ``0`` in isolated config. @@ -479,6 +481,9 @@ PyConfig Fields which are already initialized are left unchanged. + Fields for :ref:`path configuration ` 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 ` 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] ` 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 `. + 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 + `. 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 ` 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 ` 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 ` - 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 ` (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 - ` 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 ` 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 ` (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 `? @@ -1110,6 +1194,8 @@ PyConfig If equals to zero, ignore the :ref:`environment variables `. + Set to ``0`` by the :option:`-E` environment variable. + Default: ``1`` in Python config and ``0`` in isolated config. .. c:member:: int user_site_directory @@ -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 ` ("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 `, 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 ` in Python, after the Core phase and before the Main phase, which is one of the :pep:`432` motivation. diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index 3e7890cb766..85eb24a495b 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -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 `. 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 `. diff --git a/Doc/c-api/iter.rst b/Doc/c-api/iter.rst index 3e388bb917a..434d2021cea 100644 --- a/Doc/c-api/iter.rst +++ b/Doc/c-api/iter.rst @@ -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 diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst index f338e2ae066..f9e65354a25 100644 --- a/Doc/c-api/list.rst +++ b/Doc/c-api/list.rst @@ -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) diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index 4201490286b..41b5632d230 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -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. diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst index 682160d1475..3c9d282c6d0 100644 --- a/Doc/c-api/mapping.rst +++ b/Doc/c-api/mapping.rst @@ -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) diff --git a/Doc/c-api/marshal.rst b/Doc/c-api/marshal.rst index 7bb0dad2b6b..8e25968c690 100644 --- a/Doc/c-api/marshal.rst +++ b/Doc/c-api/marshal.rst @@ -21,9 +21,9 @@ unmarshalling. Version 2 uses a binary format for floating point numbers. .. c:function:: void PyMarshal_WriteLongToFile(long value, FILE *file, int version) - Marshal a :c:type:`long` integer, *value*, to *file*. This will only write + Marshal a :c:expr:`long` integer, *value*, to *file*. This will only write the least-significant 32 bits of *value*; regardless of the size of the - native :c:type:`long` type. *version* indicates the file format. + native :c:expr:`long` type. *version* indicates the file format. .. c:function:: void PyMarshal_WriteObjectToFile(PyObject *value, FILE *file, int version) @@ -43,9 +43,9 @@ The following functions allow marshalled values to be read back in. .. c:function:: long PyMarshal_ReadLongFromFile(FILE *file) - Return a C :c:type:`long` from the data stream in a :c:type:`FILE*` opened + Return a C :c:expr:`long` from the data stream in a :c:expr:`FILE*` opened for reading. Only a 32-bit value can be read in using this function, - regardless of the native size of :c:type:`long`. + regardless of the native size of :c:expr:`long`. On error, sets the appropriate exception (:exc:`EOFError`) and returns ``-1``. @@ -53,9 +53,9 @@ The following functions allow marshalled values to be read back in. .. c:function:: int PyMarshal_ReadShortFromFile(FILE *file) - Return a C :c:type:`short` from the data stream in a :c:type:`FILE*` opened + Return a C :c:expr:`short` from the data stream in a :c:expr:`FILE*` opened for reading. Only a 16-bit value can be read in using this function, - regardless of the native size of :c:type:`short`. + regardless of the native size of :c:expr:`short`. On error, sets the appropriate exception (:exc:`EOFError`) and returns ``-1``. @@ -63,7 +63,7 @@ The following functions allow marshalled values to be read back in. .. c:function:: PyObject* PyMarshal_ReadObjectFromFile(FILE *file) - Return a Python object from the data stream in a :c:type:`FILE*` opened for + Return a Python object from the data stream in a :c:expr:`FILE*` opened for reading. On error, sets the appropriate exception (:exc:`EOFError`, :exc:`ValueError` @@ -72,7 +72,7 @@ The following functions allow marshalled values to be read back in. .. c:function:: PyObject* PyMarshal_ReadLastObjectFromFile(FILE *file) - Return a Python object from the data stream in a :c:type:`FILE*` opened for + Return a Python object from the data stream in a :c:expr:`FILE*` opened for reading. Unlike :c:func:`PyMarshal_ReadObjectFromFile`, this function assumes that no further objects will be read from the file, allowing it to aggressively load file data into memory so that the de-serialization can diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index 01b646c226e..7041c15d23f 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -75,7 +75,7 @@ memory manager. For example, this is required when the interpreter is extended with new object types written in C. Another reason for using the Python heap is the desire to *inform* the Python memory manager about the memory needs of the extension module. Even when the requested memory is used exclusively for -internal, highly-specific purposes, delegating all memory requests to the Python +internal, highly specific purposes, delegating all memory requests to the Python memory manager causes the interpreter to have a more accurate image of its memory footprint as a whole. Consequently, under certain circumstances, the Python memory manager may or may not trigger appropriate actions, like garbage @@ -95,6 +95,8 @@ for the I/O buffer escapes completely the Python memory manager. Allocator Domains ================= +.. _allocator-domains: + All allocating functions belong to one of three different "domains" (see also :c:type:`PyMemAllocatorDomain`). These domains represent different allocation strategies and are optimized for different purposes. The specific details on @@ -141,7 +143,7 @@ zero bytes. .. c:function:: void* PyMem_RawMalloc(size_t n) - Allocates *n* bytes and returns a pointer of type :c:type:`void*` to the + Allocates *n* bytes and returns a pointer of type :c:expr:`void*` to the allocated memory, or ``NULL`` if the request fails. Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as @@ -152,7 +154,7 @@ zero bytes. .. c:function:: void* PyMem_RawCalloc(size_t nelem, size_t elsize) Allocates *nelem* elements each whose size in bytes is *elsize* and returns - a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the + a pointer of type :c:expr:`void*` to the allocated memory, or ``NULL`` if the request fails. The memory is initialized to zeros. Requesting zero elements or elements of size zero bytes returns a distinct @@ -212,7 +214,7 @@ The :ref:`default memory allocator ` uses the .. c:function:: void* PyMem_Malloc(size_t n) - Allocates *n* bytes and returns a pointer of type :c:type:`void*` to the + Allocates *n* bytes and returns a pointer of type :c:expr:`void*` to the allocated memory, or ``NULL`` if the request fails. Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as @@ -223,7 +225,7 @@ The :ref:`default memory allocator ` uses the .. c:function:: void* PyMem_Calloc(size_t nelem, size_t elsize) Allocates *nelem* elements each whose size in bytes is *elsize* and returns - a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the + a pointer of type :c:expr:`void*` to the allocated memory, or ``NULL`` if the request fails. The memory is initialized to zeros. Requesting zero elements or elements of size zero bytes returns a distinct @@ -265,14 +267,14 @@ The following type-oriented macros are provided for convenience. Note that .. c:function:: TYPE* PyMem_New(TYPE, size_t n) Same as :c:func:`PyMem_Malloc`, but allocates ``(n * sizeof(TYPE))`` bytes of - memory. Returns a pointer cast to :c:type:`TYPE*`. The memory will not have + memory. Returns a pointer cast to :c:expr:`TYPE*`. The memory will not have been initialized in any way. .. c:function:: TYPE* PyMem_Resize(void *p, TYPE, size_t n) Same as :c:func:`PyMem_Realloc`, but the memory block is resized to ``(n * - sizeof(TYPE))`` bytes. Returns a pointer cast to :c:type:`TYPE*`. On return, + sizeof(TYPE))`` bytes. Returns a pointer cast to :c:expr:`TYPE*`. On return, *p* will be a pointer to the new memory area, or ``NULL`` in the event of failure. @@ -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 ` section. @@ -320,7 +322,7 @@ The :ref:`default object allocator ` uses the .. c:function:: void* PyObject_Malloc(size_t n) - Allocates *n* bytes and returns a pointer of type :c:type:`void*` to the + Allocates *n* bytes and returns a pointer of type :c:expr:`void*` to the allocated memory, or ``NULL`` if the request fails. Requesting zero bytes returns a distinct non-``NULL`` pointer if possible, as @@ -331,7 +333,7 @@ The :ref:`default object allocator ` uses the .. c:function:: void* PyObject_Calloc(size_t nelem, size_t elsize) Allocates *nelem* elements each whose size in bytes is *elsize* and returns - a pointer of type :c:type:`void*` to the allocated memory, or ``NULL`` if the + a pointer of type :c:expr:`void*` to the allocated memory, or ``NULL`` if the request fails. The memory is initialized to zeros. Requesting zero elements or elements of size zero bytes returns a distinct @@ -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 `. + .. warning:: + + :c:func:`PyMem_SetAllocator` does have the following contract: + + * It can be called after :c:func:`Py_PreInitialize` and before + :c:func:`Py_InitializeFromConfig` to install a custom memory + allocator. There are no restrictions over the installed allocator + other than the ones imposed by the domain (for instance, the Raw + Domain allows the allocator to be called without the GIL held). See + :ref:`the section on allocator domains ` for more + information. + + * If called after Python has finish initializing (after + :c:func:`Py_InitializeFromConfig` has been called) the allocator + **must** wrap the existing allocator. Substituting the current + allocator for some other arbitrary one is **not supported**. + + + .. c:function:: void PyMem_SetupDebugHooks(void) Setup :ref:`debug hooks in the Python memory allocators ` diff --git a/Doc/c-api/memoryview.rst b/Doc/c-api/memoryview.rst index 24f8c935302..ebd5c776043 100644 --- a/Doc/c-api/memoryview.rst +++ b/Doc/c-api/memoryview.rst @@ -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. - diff --git a/Doc/c-api/method.rst b/Doc/c-api/method.rst index 23852251dfe..6e7e1e21aa9 100644 --- a/Doc/c-api/method.rst +++ b/Doc/c-api/method.rst @@ -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. diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index 94c8d9f9817..e2ba157b32c 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -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__`. diff --git a/Doc/c-api/number.rst b/Doc/c-api/number.rst index 37979bb506b..70b91f8c2d0 100644 --- a/Doc/c-api/number.rst +++ b/Doc/c-api/number.rst @@ -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. diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 17e37077994..5a25a2b6c9d 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -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. diff --git a/Doc/c-api/refcounting.rst b/Doc/c-api/refcounting.rst index 391907c8c29..d8e9c2da6f3 100644 --- a/Doc/c-api/refcounting.rst +++ b/Doc/c-api/refcounting.rst @@ -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. diff --git a/Doc/c-api/reflection.rst b/Doc/c-api/reflection.rst index 64ce4d1d0c3..4b1c4770848 100644 --- a/Doc/c-api/reflection.rst +++ b/Doc/c-api/reflection.rst @@ -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 diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst index 65818859041..c78d273f9f1 100644 --- a/Doc/c-api/sequence.rst +++ b/Doc/c-api/sequence.rst @@ -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. diff --git a/Doc/c-api/set.rst b/Doc/c-api/set.rst index eca19c4d816..f0d905bae8a 100644 --- a/Doc/c-api/set.rst +++ b/Doc/c-api/set.rst @@ -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 diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 49f2a614e35..9618a0cf676 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -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 `. .. 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 `: - there is an additional fourth :c:type:`PyObject*` parameter + there is an additional fourth :c:expr:`PyObject*` parameter which is a tuple representing the names of the keyword arguments (which are guaranteed to be strings) or possibly ``NULL`` if there are no keywords. The values of the keyword arguments are stored in the *args* array, after the positional arguments. - This is not part of the :ref:`limited API `. - .. versionadded:: 3.7 @@ -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 `` 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 ` + 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 *); diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index cca8b7bb6d6..6fc8a3aff95 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -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 ``''`` 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 `. + 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. diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst index 6919e610227..5acddf7849a 100644 --- a/Doc/c-api/tuple.rst +++ b/Doc/c-api/tuple.rst @@ -69,7 +69,7 @@ Tuple Objects Return the slice of the tuple pointed to by *p* between *low* and *high*, or ``NULL`` on failure. This is the equivalent of the Python expression - ``p[low:high]``. Indexing from the end of the list is not supported. + ``p[low:high]``. Indexing from the end of the tuple is not supported. .. c:function:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o) @@ -91,7 +91,7 @@ Tuple Objects .. note:: - This macro "steals" a reference to *o*, and, unlike + This function "steals" a reference to *o*, and, unlike :c:func:`PyTuple_SetItem`, does *not* discard a reference to any item that is being replaced; any reference in the tuple at position *pos* will be leaked. @@ -161,7 +161,7 @@ type. .. c:type:: PyStructSequence_Field Describes a field of a struct sequence. As a struct sequence is modeled as a - tuple, all fields are typed as :c:type:`PyObject*`. The index in the + tuple, all fields are typed as :c:expr:`PyObject*`. The index in the :attr:`fields` array of the :c:type:`PyStructSequence_Desc` determines which field of the struct sequence is described. @@ -215,7 +215,8 @@ type. .. c:function:: void PyStructSequence_SET_ITEM(PyObject *p, Py_ssize_t *pos, PyObject *o) - Macro equivalent of :c:func:`PyStructSequence_SetItem`. + Similar to :c:func:`PyStructSequence_SetItem`, but implemented as a static + inlined function. .. note:: diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index f96886985e9..7b5d1fac40e 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -40,7 +40,7 @@ Type Objects .. c:function:: unsigned long PyType_GetFlags(PyTypeObject* type) Return the :c:member:`~PyTypeObject.tp_flags` member of *type*. This function is primarily - meant for use with `Py_LIMITED_API`; the individual flag bits are + meant for use with ``Py_LIMITED_API``; the individual flag bits are guaranteed to be stable across Python releases, but access to :c:member:`~PyTypeObject.tp_flags` itself is not part of the limited API. @@ -57,6 +57,55 @@ Type Objects modification of the attributes or base classes of the type. +.. c:function:: int PyType_AddWatcher(PyType_WatchCallback callback) + + Register *callback* as a type watcher. Return a non-negative integer ID + which must be passed to future calls to :c:func:`PyType_Watch`. In case of + error (e.g. no more watcher IDs available), return ``-1`` and set an + exception. + + .. versionadded:: 3.12 + + +.. c:function:: int PyType_ClearWatcher(int watcher_id) + + Clear watcher identified by *watcher_id* (previously returned from + :c:func:`PyType_AddWatcher`). Return ``0`` on success, ``-1`` on error (e.g. + if *watcher_id* was never registered.) + + An extension should never call ``PyType_ClearWatcher`` with a *watcher_id* + that was not returned to it by a previous call to + :c:func:`PyType_AddWatcher`. + + .. versionadded:: 3.12 + + +.. c:function:: int PyType_Watch(int watcher_id, PyObject *type) + + Mark *type* as watched. The callback granted *watcher_id* by + :c:func:`PyType_AddWatcher` will be called whenever + :c:func:`PyType_Modified` reports a change to *type*. (The callback may be + called only once for a series of consecutive modifications to *type*, if + :c:func:`PyType_Lookup` is not called on *type* between the modifications; + this is an implementation detail and subject to change.) + + An extension should never call ``PyType_Watch`` with a *watcher_id* that was + not returned to it by a previous call to :c:func:`PyType_AddWatcher`. + + .. versionadded:: 3.12 + + +.. c:type:: int (*PyType_WatchCallback)(PyObject *type) + + Type of a type-watcher callback function. + + The callback must not modify *type* or cause :c:func:`PyType_Modified` to be + called on *type* or any type in its MRO; violating this rule could cause + infinite recursion. + + .. versionadded:: 3.12 + + .. c:function:: int PyType_HasFeature(PyTypeObject *o, int feature) Return non-zero if the type object *o* sets the feature *feature*. @@ -149,6 +198,8 @@ Type Objects ``Py_TYPE(self)`` may be a *subclass* of the intended class, and subclasses are not necessarily defined in the same module as their superclass. See :c:type:`PyCMethod` to get the class that defines the method. + See :c:func:`PyType_GetModuleByDef` for cases when ``PyCMethod`` cannot + be used. .. versionadded:: 3.9 @@ -166,6 +217,21 @@ Type Objects .. versionadded:: 3.9 +.. c:function:: PyObject* PyType_GetModuleByDef(PyTypeObject *type, struct PyModuleDef *def) + + Find the first superclass whose module was created from + the given :c:type:`PyModuleDef` *def*, and return that module. + + If no module is found, raises a :py:class:`TypeError` and returns ``NULL``. + + This function is intended to be used together with + :c:func:`PyModule_GetState()` to get module state from slot methods (such as + :c:member:`~PyTypeObject.tp_init` or :c:member:`~PyNumberMethods.nb_add`) + and other places where a method's defining class cannot be passed using the + :c:type:`PyCMethod` calling convention. + + .. versionadded:: 3.11 + Creating Heap-Allocated Types ............................. @@ -173,10 +239,16 @@ Creating Heap-Allocated Types The following functions and structs are used to create :ref:`heap types `. -.. c:function:: PyObject* PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) +.. c:function:: PyObject* PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases) - Creates and returns a :ref:`heap type ` from the *spec* - (:const:`Py_TPFLAGS_HEAPTYPE`). + Create and return a :ref:`heap type ` from the *spec* + (see :const:`Py_TPFLAGS_HEAPTYPE`). + + The metaclass *metaclass* is used to construct the resulting type object. + When *metaclass* is ``NULL``, the metaclass is derived from *bases* + (or *Py_tp_base[s]* slots if *bases* is ``NULL``, see below). + Note that metaclasses that override + :c:member:`~PyTypeObject.tp_new` are not supported. The *bases* argument can be used to specify base classes; it can either be only one class or a tuple of classes. @@ -193,6 +265,25 @@ The following functions and structs are used to create This function calls :c:func:`PyType_Ready` on the new type. + Note that this function does *not* fully match the behavior of + calling :py:class:`type() ` or using the :keyword:`class` statement. + With user-provided base types or metaclasses, prefer + :ref:`calling ` :py:class:`type` (or the metaclass) + over ``PyType_From*`` functions. + Specifically: + + * :py:meth:`~object.__new__` is not called on the new class + (and it must be set to ``type.__new__``). + * :py:meth:`~object.__init__` is not called on the new class. + * :py:meth:`~object.__init_subclass__` is not called on any bases. + * :py:meth:`~object.__set_name__` is not called on new descriptors. + + .. versionadded:: 3.12 + +.. c:function:: PyObject* PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) + + Equivalent to ``PyType_FromMetaclass(NULL, module, spec, bases)``. + .. versionadded:: 3.9 .. versionchanged:: 3.10 @@ -200,15 +291,32 @@ The following functions and structs are used to create The function now accepts a single class as the *bases* argument and ``NULL`` as the ``tp_doc`` slot. + .. versionchanged:: 3.12 + + The function now finds and uses a metaclass corresponding to the provided + base classes. Previously, only :class:`type` instances were returned. + + .. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) - Equivalent to ``PyType_FromModuleAndSpec(NULL, spec, bases)``. + Equivalent to ``PyType_FromMetaclass(NULL, NULL, spec, bases)``. .. versionadded:: 3.3 + .. versionchanged:: 3.12 + + The function now finds and uses a metaclass corresponding to the provided + base classes. Previously, only :class:`type` instances were returned. + .. c:function:: PyObject* PyType_FromSpec(PyType_Spec *spec) - Equivalent to ``PyType_FromSpecWithBases(spec, NULL)``. + Equivalent to ``PyType_FromMetaclass(NULL, NULL, spec, NULL)``. + + .. versionchanged:: 3.12 + + The function now finds and uses a metaclass corresponding to the + base classes provided in *Py_tp_base[s]* slots. + Previously, only :class:`type` instances were returned. .. c:type:: PyType_Spec @@ -237,6 +345,8 @@ The following functions and structs are used to create Array of :c:type:`PyType_Slot` structures. Terminated by the special slot value ``{0, NULL}``. + Each slot ID should be specified at most once. + .. c:type:: PyType_Slot Structure defining optional functionality of a type, containing a slot ID @@ -266,18 +376,12 @@ The following functions and structs are used to create * :c:member:`~PyTypeObject.tp_weaklist` * :c:member:`~PyTypeObject.tp_vectorcall` * :c:member:`~PyTypeObject.tp_weaklistoffset` - (see :ref:`PyMemberDef `) + (use :const:`Py_TPFLAGS_MANAGED_WEAKREF` instead) * :c:member:`~PyTypeObject.tp_dictoffset` - (see :ref:`PyMemberDef `) + (use :const:`Py_TPFLAGS_MANAGED_DICT` instead) * :c:member:`~PyTypeObject.tp_vectorcall_offset` (see :ref:`PyMemberDef `) - The following fields cannot be set using :c:type:`PyType_Spec` and - :c:type:`PyType_Slot` under the limited API: - - * :c:member:`~PyBufferProcs.bf_getbuffer` - * :c:member:`~PyBufferProcs.bf_releasebuffer` - Setting :c:data:`Py_tp_bases` or :c:data:`Py_tp_base` may be problematic on some platforms. To avoid issues, use the *bases* argument of @@ -285,7 +389,12 @@ The following functions and structs are used to create .. versionchanged:: 3.9 - Slots in :c:type:`PyBufferProcs` in may be set in the unlimited API. + Slots in :c:type:`PyBufferProcs` may be set in the unlimited API. + + .. versionchanged:: 3.11 + :c:member:`~PyBufferProcs.bf_getbuffer` and + :c:member:`~PyBufferProcs.bf_releasebuffer` are now available + under the limited API. .. c:member:: void *PyType_Slot.pfunc diff --git a/Doc/c-api/typehints.rst b/Doc/c-api/typehints.rst index 8b0b9b651e8..4c1957a2a1d 100644 --- a/Doc/c-api/typehints.rst +++ b/Doc/c-api/typehints.rst @@ -15,8 +15,8 @@ two types exist -- :ref:`GenericAlias ` and Equivalent to calling the Python class :class:`types.GenericAlias`. The *origin* and *args* arguments set the ``GenericAlias``\ 's ``__origin__`` and ``__args__`` attributes respectively. - *origin* should be a :c:type:`PyTypeObject*`, and *args* can be a - :c:type:`PyTupleObject*` or any ``PyObject*``. If *args* passed is + *origin* should be a :c:expr:`PyTypeObject*`, and *args* can be a + :c:expr:`PyTupleObject*` or any ``PyObject*``. If *args* passed is not a tuple, a 1-tuple is automatically constructed and ``__args__`` is set to ``(args,)``. Minimal checking is done for the arguments, so the function will succeed even diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index cd8723efef6..644830b940b 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -7,8 +7,8 @@ Type Objects Perhaps one of the most important structures of the Python object system is the structure that defines a new type: the :c:type:`PyTypeObject` structure. Type -objects can be handled using any of the :c:func:`PyObject_\*` or -:c:func:`PyType_\*` functions, but do not offer much that's interesting to most +objects can be handled using any of the ``PyObject_*`` or +``PyType_*`` functions, but do not offer much that's interesting to most Python applications. These objects are fundamental to how objects behave, so they are very important to the interpreter itself and to any extension module that implements new types. @@ -43,13 +43,13 @@ Quick Reference +================================================+===================================+===================+===+===+===+===+ | :c:member:`~PyTypeObject.tp_name` | const char * | __name__ | X | X | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_basicsize` | Py_ssize_t | | X | X | | X | + | :c:member:`~PyTypeObject.tp_basicsize` | :c:type:`Py_ssize_t` | | X | X | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_itemsize` | Py_ssize_t | | | X | | X | + | :c:member:`~PyTypeObject.tp_itemsize` | :c:type:`Py_ssize_t` | | | X | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | :c:member:`~PyTypeObject.tp_dealloc` | :c:type:`destructor` | | X | X | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_vectorcall_offset` | Py_ssize_t | | | X | | X | + | :c:member:`~PyTypeObject.tp_vectorcall_offset` | :c:type:`Py_ssize_t` | | | X | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | (:c:member:`~PyTypeObject.tp_getattr`) | :c:type:`getattrfunc` | __getattribute__, | | | | G | | | | __getattr__ | | | | | @@ -96,7 +96,7 @@ Quick Reference | | | __gt__, | | | | | | | | __ge__ | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_weaklistoffset` | Py_ssize_t | | | X | | ? | + | (:c:member:`~PyTypeObject.tp_weaklistoffset`) | :c:type:`Py_ssize_t` | | | X | | ? | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | :c:member:`~PyTypeObject.tp_iter` | :c:type:`getiterfunc` | __iter__ | | | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ @@ -117,7 +117,7 @@ Quick Reference | :c:member:`~PyTypeObject.tp_descr_set` | :c:type:`descrsetfunc` | __set__, | | | | X | | | | __delete__ | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_dictoffset` | Py_ssize_t | | | X | | ? | + | (:c:member:`~PyTypeObject.tp_dictoffset`) | :c:type:`Py_ssize_t` | | | X | | ? | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | :c:member:`~PyTypeObject.tp_init` | :c:type:`initproc` | __init__ | X | X | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ @@ -135,7 +135,7 @@ Quick Reference +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | [:c:member:`~PyTypeObject.tp_cache`] | :c:type:`PyObject` * | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | [:c:member:`~PyTypeObject.tp_subclasses`] | :c:type:`PyObject` * | __subclasses__ | | | | + | [:c:member:`~PyTypeObject.tp_subclasses`] | void * | __subclasses__ | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | [:c:member:`~PyTypeObject.tp_weaklist`] | :c:type:`PyObject` * | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ @@ -147,12 +147,20 @@ Quick Reference +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | :c:member:`~PyTypeObject.tp_vectorcall` | :c:type:`vectorcallfunc` | | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | [:c:member:`~PyTypeObject.tp_watched`] | char | | | | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ .. [#slots] - A slot name in parentheses indicates it is (effectively) deprecated. - Names in angle brackets should be treated as read-only. - Names in square brackets are for internal use only. - "" (as a prefix) means the field is required (must be non-``NULL``). + + **()**: A slot name in parentheses indicates it is (effectively) deprecated. + + **<>**: Names in angle brackets should be initially set to ``NULL`` and + treated as read-only. + + **[]**: Names in square brackets are for internal use only. + + **** (as a prefix) means the field is required (must be non-``NULL``). + .. [#cols] Columns: **"O"**: set on :c:type:`PyBaseObject_Type` @@ -333,7 +341,7 @@ slot typedefs | :c:type:`allocfunc` | .. line-block:: | :c:type:`PyObject` * | | | | | | | :c:type:`PyTypeObject` * | | -| | Py_ssize_t | | +| | :c:type:`Py_ssize_t` | | +-----------------------------+-----------------------------+----------------------+ | :c:type:`destructor` | void * | void | +-----------------------------+-----------------------------+----------------------+ @@ -405,7 +413,7 @@ slot typedefs +-----------------------------+-----------------------------+----------------------+ | :c:type:`iternextfunc` | :c:type:`PyObject` * | :c:type:`PyObject` * | +-----------------------------+-----------------------------+----------------------+ -| :c:type:`lenfunc` | :c:type:`PyObject` * | Py_ssize_t | +| :c:type:`lenfunc` | :c:type:`PyObject` * | :c:type:`Py_ssize_t` | +-----------------------------+-----------------------------+----------------------+ | :c:type:`getbufferproc` | .. line-block:: | int | | | | | @@ -438,12 +446,13 @@ slot typedefs | :c:type:`ssizeargfunc` | .. line-block:: | :c:type:`PyObject` * | | | | | | | :c:type:`PyObject` * | | -| | Py_ssize_t | | +| | :c:type:`Py_ssize_t` | | +-----------------------------+-----------------------------+----------------------+ | :c:type:`ssizeobjargproc` | .. line-block:: | int | | | | | | | :c:type:`PyObject` * | | -| | Py_ssize_t | | +| | :c:type:`Py_ssize_t` | | +| | :c:type:`PyObject` * | | +-----------------------------+-----------------------------+----------------------+ | :c:type:`objobjproc` | .. line-block:: | int | | | | | @@ -476,7 +485,7 @@ PyObject Slots -------------- The type object structure extends the :c:type:`PyVarObject` structure. The -:attr:`ob_size` field is used for dynamic types (created by :func:`type_new`, +:attr:`ob_size` field is used for dynamic types (created by :func:`type_new`, usually called from a class statement). Note that :c:data:`PyType_Type` (the metatype) initializes :c:member:`~PyTypeObject.tp_itemsize`, which means that its instances (i.e. type objects) *must* have the :attr:`ob_size` field. @@ -529,7 +538,7 @@ type objects) *must* have the :attr:`ob_size` field. ``PyObject_HEAD_INIT`` macro. For :ref:`statically allocated objects `, these fields always remain ``NULL``. For :ref:`dynamically allocated objects `, these two fields are used to link the - object into a doubly-linked list of *all* live objects on the heap. + object into a doubly linked list of *all* live objects on the heap. This could be used for various debugging purposes; currently the only uses are the :func:`sys.getobjects` function and to print the objects that are @@ -720,35 +729,29 @@ and :c:type:`PyType_Type` effectively act as defaults.) with the *vectorcallfunc* function. This can be done by setting *tp_call* to :c:func:`PyVectorcall_Call`. - .. warning:: - - It is not recommended for :ref:`mutable heap types ` to implement - the vectorcall protocol. - When a user sets :attr:`__call__` in Python code, only *tp_call* is updated, - likely making it inconsistent with the vectorcall function. - - .. note:: - - The semantics of the ``tp_vectorcall_offset`` slot are provisional and - expected to be finalized in Python 3.9. - If you use vectorcall, plan for updating your code for Python 3.9. - .. versionchanged:: 3.8 Before version 3.8, this slot was named ``tp_print``. In Python 2.x, it was used for printing to a file. In Python 3.0 to 3.7, it was unused. + .. versionchanged:: 3.12 + + Before version 3.12, it was not recommended for + :ref:`mutable heap types ` to implement the vectorcall + protocol. + When a user sets :attr:`~type.__call__` in Python code, only *tp_call* is + updated, likely making it inconsistent with the vectorcall function. + Since 3.12, setting ``__call__`` will disable vectorcall optimization + by clearing the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag. + **Inheritance:** This field is always inherited. However, the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is not - always inherited. If it's not, then the subclass won't use + always inherited. If it's not set, then the subclass won't use :ref:`vectorcall `, except when :c:func:`PyVectorcall_Call` is explicitly called. - This is in particular the case for types without the - :const:`Py_TPFLAGS_IMMUTABLETYPE` flag set (including subclasses defined in - Python). .. c:member:: getattrfunc PyTypeObject.tp_getattr @@ -1024,7 +1027,6 @@ and :c:type:`PyType_Type` effectively act as defaults.) :const:`Py_TPFLAGS_HAVE_GC` flag bit is clear in the subtype and the :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` fields in the subtype exist and have ``NULL`` values. - .. XXX are most flag bits *really* inherited individually? **Default:** @@ -1141,6 +1143,33 @@ and :c:type:`PyType_Type` effectively act as defaults.) :const:`Py_TPFLAGS_IMMUTABLETYPE` flag set. For extension types, it is inherited whenever :c:member:`~PyTypeObject.tp_descr_get` is inherited. + .. data:: Py_TPFLAGS_MANAGED_DICT + + This bit indicates that instances of the class have a ``__dict___`` + attribute, and that the space for the dictionary is managed by the VM. + + If this flag is set, :const:`Py_TPFLAGS_HAVE_GC` should also be set. + + .. versionadded:: 3.12 + + **Inheritance:** + + This flag is inherited unless the + :c:member:`~PyTypeObject.tp_dictoffset` field is set in a superclass. + + + .. data:: Py_TPFLAGS_MANAGED_WEAKREF + + This bit indicates that instances of the class should be weakly + referenceable. + + .. versionadded:: 3.12 + + **Inheritance:** + + This flag is inherited unless the + :c:member:`~PyTypeObject.tp_weaklistoffset` field is set in a superclass. + .. XXX Document more flags here? @@ -1184,12 +1213,18 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - This bit is inherited for types with the - :const:`Py_TPFLAGS_IMMUTABLETYPE` flag set, if - :c:member:`~PyTypeObject.tp_call` is also inherited. + This bit is inherited if :c:member:`~PyTypeObject.tp_call` is also + inherited. .. versionadded:: 3.9 + .. versionchanged:: 3.12 + + This flag is now removed from a class when the class's + :py:meth:`~object.__call__` method is reassigned. + + This flag can now be inherited by mutable classes. + .. data:: Py_TPFLAGS_IMMUTABLETYPE This bit is set for type objects that are immutable: type attributes cannot be set nor deleted. @@ -1219,6 +1254,17 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** This flag is not inherited. + However, subclasses will not be instantiable unless they provide a + non-NULL :c:member:`~PyTypeObject.tp_new` (which is only possible + via the C API). + + .. note:: + + To disallow instantiating a class directly but allow instantiating + its subclasses (e.g. for an :term:`abstract base class`), + do not use this flag. + Instead, make :c:member:`~PyTypeObject.tp_new` only succeed for + subclasses. .. versionadded:: 3.10 @@ -1233,7 +1279,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. note:: :const:`Py_TPFLAGS_MAPPING` and :const:`Py_TPFLAGS_SEQUENCE` are - mutually exclusive; it is an error enable both flags simultaneously. + mutually exclusive; it is an error to enable both flags simultaneously. **Inheritance:** @@ -1255,7 +1301,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. note:: :const:`Py_TPFLAGS_MAPPING` and :const:`Py_TPFLAGS_SEQUENCE` are - mutually exclusive; it is an error enable both flags simultaneously. + mutually exclusive; it is an error to enable both flags simultaneously. **Inheritance:** @@ -1487,16 +1533,22 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. c:member:: Py_ssize_t PyTypeObject.tp_weaklistoffset + While this field is still supported, :const:`Py_TPFLAGS_MANAGED_WEAKREF` + should be used instead, if at all possible. + If the instances of this type are weakly referenceable, this field is greater than zero and contains the offset in the instance structure of the weak reference list head (ignoring the GC header, if present); this offset is used by - :c:func:`PyObject_ClearWeakRefs` and the :c:func:`PyWeakref_\*` functions. The - instance structure needs to include a field of type :c:type:`PyObject*` which is + :c:func:`PyObject_ClearWeakRefs` and the ``PyWeakref_*`` functions. The + instance structure needs to include a field of type :c:expr:`PyObject*` which is initialized to ``NULL``. Do not confuse this field with :c:member:`~PyTypeObject.tp_weaklist`; that is the list head for weak references to the type object itself. + It is an error to set both the :const:`Py_TPFLAGS_MANAGED_WEAKREF` bit and + :c:member:`~PyTypeObject.tp_weaklist`. + **Inheritance:** This field is inherited by subtypes, but see the rules listed below. A subtype @@ -1504,19 +1556,12 @@ and :c:type:`PyType_Type` effectively act as defaults.) reference list head than the base type. Since the list head is always found via :c:member:`~PyTypeObject.tp_weaklistoffset`, this should not be a problem. - When a type defined by a class statement has no :attr:`~object.__slots__` declaration, - and none of its base types are weakly referenceable, the type is made weakly - referenceable by adding a weak reference list head slot to the instance layout - and setting the :c:member:`~PyTypeObject.tp_weaklistoffset` of that slot's offset. + **Default:** - When a type's :attr:`__slots__` declaration contains a slot named - :attr:`__weakref__`, that slot becomes the weak reference list head for - instances of the type, and the slot's offset is stored in the type's - :c:member:`~PyTypeObject.tp_weaklistoffset`. - - When a type's :attr:`__slots__` declaration does not contain a slot named - :attr:`__weakref__`, the type inherits its :c:member:`~PyTypeObject.tp_weaklistoffset` from its - base type. + If the :const:`Py_TPFLAGS_MANAGED_WEAKREF` bit is set in the + :c:member:`~PyTypeObject.tp_dict` field, then + :c:member:`~PyTypeObject.tp_weaklistoffset` will be set to a negative value, + to indicate that it is unsafe to use this field. .. c:member:: getiterfunc PyTypeObject.tp_iter @@ -1695,6 +1740,9 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. c:member:: Py_ssize_t PyTypeObject.tp_dictoffset + While this field is still supported, :const:`Py_TPFLAGS_MANAGED_DICT` should be + used instead, if at all possible. + If the instances of this type have a dictionary containing instance variables, this field is non-zero and contains the offset in the instances of the type of the instance variable dictionary; this offset is used by @@ -1703,55 +1751,34 @@ and :c:type:`PyType_Type` effectively act as defaults.) Do not confuse this field with :c:member:`~PyTypeObject.tp_dict`; that is the dictionary for attributes of the type object itself. - If the value of this field is greater than zero, it specifies the offset from - the start of the instance structure. If the value is less than zero, it - specifies the offset from the *end* of the instance structure. A negative - offset is more expensive to use, and should only be used when the instance - structure contains a variable-length part. This is used for example to add an - instance variable dictionary to subtypes of :class:`str` or :class:`tuple`. Note - that the :c:member:`~PyTypeObject.tp_basicsize` field should account for the dictionary added to - the end in that case, even though the dictionary is not included in the basic - object layout. On a system with a pointer size of 4 bytes, - :c:member:`~PyTypeObject.tp_dictoffset` should be set to ``-4`` to indicate that the dictionary is - at the very end of the structure. + The value specifies the offset of the dictionary from the start of the instance structure. - The real dictionary offset in an instance can be computed from a negative - :c:member:`~PyTypeObject.tp_dictoffset` as follows:: + The :c:member:`~PyTypeObject.tp_dictoffset` should be regarded as write-only. + To get the pointer to the dictionary call :c:func:`PyObject_GenericGetDict`. + Calling :c:func:`PyObject_GenericGetDict` may need to allocate memory for the + dictionary, so it is may be more efficient to call :c:func:`PyObject_GetAttr` + when accessing an attribute on the object. - dictoffset = tp_basicsize + abs(ob_size)*tp_itemsize + tp_dictoffset - if dictoffset is not aligned on sizeof(void*): - round up to sizeof(void*) - - where :c:member:`~PyTypeObject.tp_basicsize`, :c:member:`~PyTypeObject.tp_itemsize` and :c:member:`~PyTypeObject.tp_dictoffset` are - taken from the type object, and :attr:`ob_size` is taken from the instance. The - absolute value is taken because ints use the sign of :attr:`ob_size` to - store the sign of the number. (There's never a need to do this calculation - yourself; it is done for you by :c:func:`_PyObject_GetDictPtr`.) + It is an error to set both the :const:`Py_TPFLAGS_MANAGED_WEAKREF` bit and + :c:member:`~PyTypeObject.tp_dictoffset`. **Inheritance:** - This field is inherited by subtypes, but see the rules listed below. A subtype - may override this offset; this means that the subtype instances store the - dictionary at a difference offset than the base type. Since the dictionary is - always found via :c:member:`~PyTypeObject.tp_dictoffset`, this should not be a problem. - - When a type defined by a class statement has no :attr:`~object.__slots__` declaration, - and none of its base types has an instance variable dictionary, a dictionary - slot is added to the instance layout and the :c:member:`~PyTypeObject.tp_dictoffset` is set to - that slot's offset. - - When a type defined by a class statement has a :attr:`__slots__` declaration, - the type inherits its :c:member:`~PyTypeObject.tp_dictoffset` from its base type. - - (Adding a slot named :attr:`~object.__dict__` to the :attr:`__slots__` declaration does - not have the expected effect, it just causes confusion. Maybe this should be - added as a feature just like :attr:`__weakref__` though.) + This field is inherited by subtypes. A subtype should not override this offset; + doing so could be unsafe, if C code tries to access the dictionary at the + previous offset. + To properly support inheritance, use :const:`Py_TPFLAGS_MANAGED_DICT`. **Default:** This slot has no default. For :ref:`static types `, if the field is ``NULL`` then no :attr:`__dict__` gets created for instances. + If the :const:`Py_TPFLAGS_MANAGED_DICT` bit is set in the + :c:member:`~PyTypeObject.tp_dict` field, then + :c:member:`~PyTypeObject.tp_dictoffset` will be set to ``-1``, to indicate + that it is unsafe to use this field. + .. c:member:: initproc PyTypeObject.tp_init @@ -1905,8 +1932,19 @@ and :c:type:`PyType_Type` effectively act as defaults.) Tuple of base types. - This is set for types created by a class statement. It should be ``NULL`` for - statically defined types. + This field should be set to ``NULL`` and treated as read-only. + Python will fill it in when the type is :c:func:`initialized `. + + For dynamically created classes, the ``Py_tp_bases`` + :c:type:`slot ` can be used instead of the *bases* argument + of :c:func:`PyType_FromSpecWithBases`. + The argument form is preferred. + + .. warning:: + + Multiple inheritance does not work well for statically defined types. + If you set ``tp_bases`` to a tuple, Python will not raise an error, + but some slots will only be inherited from the first base. **Inheritance:** @@ -1918,6 +1956,8 @@ and :c:type:`PyType_Type` effectively act as defaults.) Tuple containing the expanded set of base types, starting with the type itself and ending with :class:`object`, in Method Resolution Order. + This field should be set to ``NULL`` and treated as read-only. + Python will fill it in when the type is :c:func:`initialized `. **Inheritance:** @@ -1934,9 +1974,17 @@ and :c:type:`PyType_Type` effectively act as defaults.) This field is not inherited. -.. c:member:: PyObject* PyTypeObject.tp_subclasses +.. c:member:: void* PyTypeObject.tp_subclasses - List of weak references to subclasses. Internal use only. + A collection of subclasses. Internal use only. May be an invalid pointer. + + To get a list of subclasses, call the Python method + :py:meth:`~class.__subclasses__`. + + .. versionchanged:: 3.12 + + For some types, this field does not hold a valid :c:expr:`PyObject*`. + The type was changed to :c:expr:`void*` to indicate this. **Inheritance:** @@ -1948,6 +1996,13 @@ and :c:type:`PyType_Type` effectively act as defaults.) Weak reference list head, for weak references to this type object. Not inherited. Internal use only. + .. versionchanged:: 3.12 + + Internals detail: For the static builtin types this is always ``NULL``, + even if weakrefs are added. Instead, the weakrefs for each are stored + on ``PyInterpreterState``. Use the public C-API or the internal + ``_PyObject_GET_WEAKREFS_LISTPTR()`` macro to avoid the distinction. + **Inheritance:** This field is not inherited. @@ -1997,8 +2052,16 @@ and :c:type:`PyType_Type` effectively act as defaults.) PyErr_Restore(error_type, error_value, error_traceback); } - For this field to be taken into account (even through inheritance), - you must also set the :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit. + Also, note that, in a garbage collected Python, + :c:member:`~PyTypeObject.tp_dealloc` may be called from + any Python thread, not just the thread which created the object (if the object + becomes part of a refcount cycle, that cycle might be collected by a garbage + collection on any thread). This is not a problem for Python API calls, since + the thread on which tp_dealloc is called will own the Global Interpreter Lock + (GIL). However, if the object being destroyed in turn destroys objects from some + other C or C++ library, care should be taken to ensure that destroying those + objects on the thread which called tp_dealloc will not violate any assumptions + of the library. **Inheritance:** @@ -2006,6 +2069,12 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. versionadded:: 3.4 + .. versionchanged:: 3.8 + + Before version 3.8 it was necessary to set the + :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit in order for this field to be + used. This is no longer required. + .. seealso:: "Safe object finalization" (:pep:`442`) @@ -2024,15 +2093,11 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. versionadded:: 3.9 (the field exists since 3.8 but it's only used since 3.9) -Also, note that, in a garbage collected Python, :c:member:`~PyTypeObject.tp_dealloc` may be called from -any Python thread, not just the thread which created the object (if the object -becomes part of a refcount cycle, that cycle might be collected by a garbage -collection on any thread). This is not a problem for Python API calls, since -the thread on which tp_dealloc is called will own the Global Interpreter Lock -(GIL). However, if the object being destroyed in turn destroys objects from some -other C or C++ library, care should be taken to ensure that destroying those -objects on the thread which called tp_dealloc will not violate any assumptions -of the library. +.. c:member:: char PyTypeObject.tp_watched + + Internal. Do not use. + + .. versionadded:: 3.12 .. _static-types: @@ -2054,9 +2119,9 @@ This results in types that are limited relative to types defined in Python: :ref:`sub-interpreters `, so they should not include any subinterpreter-specific state. -Also, since :c:type:`PyTypeObject` is not part of the :ref:`stable ABI `, -any extension modules using static types must be compiled for a specific -Python minor version. +Also, since :c:type:`PyTypeObject` is only part of the :ref:`Limited API +` as an opaque struct, any extension modules using static types must be +compiled for a specific Python minor version. .. _heap-types: @@ -2071,7 +2136,7 @@ flag set. This is done by filling a :c:type:`PyType_Spec` structure and calling :c:func:`PyType_FromSpec`, :c:func:`PyType_FromSpecWithBases`, -or :c:func:`PyType_FromModuleAndSpec`. +:c:func:`PyType_FromModuleAndSpec`, or :c:func:`PyType_FromMetaclass`. .. _number-structs: @@ -2331,13 +2396,13 @@ Buffer Object Structures steps: (1) Check if the request can be met. If not, raise :c:data:`PyExc_BufferError`, - set :c:data:`view->obj` to ``NULL`` and return ``-1``. + set :c:expr:`view->obj` to ``NULL`` and return ``-1``. (2) Fill in the requested fields. (3) Increment an internal counter for the number of exports. - (4) Set :c:data:`view->obj` to *exporter* and increment :c:data:`view->obj`. + (4) Set :c:expr:`view->obj` to *exporter* and increment :c:expr:`view->obj`. (5) Return ``0``. @@ -2345,10 +2410,10 @@ Buffer Object Structures schemes can be used: * Re-export: Each member of the tree acts as the exporting object and - sets :c:data:`view->obj` to a new reference to itself. + sets :c:expr:`view->obj` to a new reference to itself. * Redirect: The buffer request is redirected to the root object of the - tree. Here, :c:data:`view->obj` will be a new reference to the root + tree. Here, :c:expr:`view->obj` will be a new reference to the root object. The individual fields of *view* are described in section @@ -2390,7 +2455,7 @@ Buffer Object Structures *view* argument. - This function MUST NOT decrement :c:data:`view->obj`, since that is + This function MUST NOT decrement :c:expr:`view->obj`, since that is done automatically in :c:func:`PyBuffer_Release` (this scheme is useful for breaking reference cycles). @@ -2440,7 +2505,8 @@ Async Object Structures PyObject *am_aiter(PyObject *self); - Must return an :term:`awaitable` object. See :meth:`__anext__` for details. + Must return an :term:`asynchronous iterator` object. + See :meth:`__anext__` for details. This slot may be set to ``NULL`` if an object does not implement asynchronous iteration protocol. @@ -2528,11 +2594,11 @@ Slot Type typedefs .. c:type:: PyObject *(*descrgetfunc)(PyObject *, PyObject *, PyObject *) - See :c:member:`~PyTypeObject.tp_descrget`. + See :c:member:`~PyTypeObject.tp_descr_get`. .. c:type:: int (*descrsetfunc)(PyObject *, PyObject *, PyObject *) - See :c:member:`~PyTypeObject.tp_descrset`. + See :c:member:`~PyTypeObject.tp_descr_set`. .. c:type:: Py_hash_t (*hashfunc)(PyObject *) @@ -2568,7 +2634,7 @@ Slot Type typedefs .. c:type:: PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t) -.. c:type:: int (*ssizeobjargproc)(PyObject *, Py_ssize_t) +.. c:type:: int (*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *) .. c:type:: int (*objobjproc)(PyObject *, PyObject *) @@ -2596,7 +2662,7 @@ A basic :ref:`static type `:: PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "mymod.MyObject", .tp_basicsize = sizeof(MyObject), - .tp_doc = "My objects", + .tp_doc = PyDoc_STR("My objects"), .tp_new = myobj_new, .tp_dealloc = (destructor)myobj_dealloc, .tp_repr = (reprfunc)myobj_repr, @@ -2626,7 +2692,7 @@ with a more verbose initializer:: 0, /* tp_setattro */ 0, /* tp_as_buffer */ 0, /* tp_flags */ - "My objects", /* tp_doc */ + PyDoc_STR("My objects"), /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -2651,18 +2717,16 @@ A type that supports weakrefs, instance dicts, and hashing:: typedef struct { PyObject_HEAD const char *data; - PyObject *inst_dict; - PyObject *weakreflist; } MyObject; static PyTypeObject MyObject_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "mymod.MyObject", .tp_basicsize = sizeof(MyObject), - .tp_doc = "My objects", - .tp_weaklistoffset = offsetof(MyObject, weakreflist), - .tp_dictoffset = offsetof(MyObject, inst_dict), - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .tp_doc = PyDoc_STR("My objects"), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_DICT | + Py_TPFLAGS_MANAGED_WEAKREF, .tp_new = myobj_new, .tp_traverse = (traverseproc)myobj_traverse, .tp_clear = (inquiry)myobj_clear, @@ -2687,7 +2751,7 @@ to create instances (e.g. uses a separate factory func) using .tp_name = "mymod.MyStr", .tp_basicsize = sizeof(MyStr), .tp_base = NULL, // set to &PyUnicode_Type in module init - .tp_doc = "my custom str", + .tp_doc = PyDoc_STR("my custom str"), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, .tp_repr = (reprfunc)myobj_repr, }; diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index 6cb453ef010..f062f14e9a7 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -17,26 +17,12 @@ of Unicode characters while staying memory efficient. There are special cases for strings where all code points are below 128, 256, or 65536; otherwise, code points must be below 1114112 (which is the full Unicode range). -:c:type:`Py_UNICODE*` and UTF-8 representations are created on demand and cached -in the Unicode object. The :c:type:`Py_UNICODE*` representation is deprecated -and inefficient. - -Due to the transition between the old APIs and the new APIs, Unicode objects -can internally be in two states depending on how they were created: - -* "canonical" Unicode objects are all objects created by a non-deprecated - Unicode API. They use the most efficient representation allowed by the - implementation. - -* "legacy" Unicode objects have been created through one of the deprecated - APIs (typically :c:func:`PyUnicode_FromUnicode`) and only bear the - :c:type:`Py_UNICODE*` representation; you will have to call - :c:func:`PyUnicode_READY` on them before calling any other API. +UTF-8 representation is created on demand and cached in the Unicode object. .. note:: - The "legacy" Unicode object will be removed in Python 3.12 with deprecated - APIs. All Unicode objects will be "canonical" since then. See :pep:`623` - for more information. + The :c:type:`Py_UNICODE` representation has been removed since Python 3.12 + with deprecated APIs. + See :pep:`623` for more information. Unicode Type @@ -58,7 +44,7 @@ Python: .. c:type:: Py_UNICODE - This is a typedef of :c:type:`wchar_t`, which is a 16-bit type or 32-bit type + This is a typedef of :c:expr:`wchar_t`, which is a 16-bit type or 32-bit type depending on the platform. .. versionchanged:: 3.3 @@ -84,8 +70,8 @@ Python: is exposed to Python code as ``str``. -The following APIs are really C macros and can be used to do fast checks and to -access internal read-only data of Unicode objects: +The following APIs are C macros and static inlined functions for fast checks and +access to internal read-only data of Unicode objects: .. c:function:: int PyUnicode_Check(PyObject *o) @@ -101,18 +87,12 @@ access internal read-only data of Unicode objects: .. c:function:: int PyUnicode_READY(PyObject *o) - Ensure the string object *o* is in the "canonical" representation. This is - required before using any of the access macros described below. - - .. XXX expand on when it is not required - - Returns ``0`` on success and ``-1`` with an exception set on failure, which in - particular happens if memory allocation fails. + Returns ``0``. This API is kept only for backward compatibility. .. versionadded:: 3.3 - .. deprecated-removed:: 3.10 3.12 - This API will be removed with :c:func:`PyUnicode_FromUnicode`. + .. deprecated:: 3.10 + This API does nothing since Python 3.12. .. c:function:: Py_ssize_t PyUnicode_GET_LENGTH(PyObject *o) @@ -130,14 +110,12 @@ access internal read-only data of Unicode objects: Return a pointer to the canonical representation cast to UCS1, UCS2 or UCS4 integer types for direct character access. No checks are performed if the canonical representation has the correct character size; use - :c:func:`PyUnicode_KIND` to select the right macro. Make sure - :c:func:`PyUnicode_READY` has been called before accessing this. + :c:func:`PyUnicode_KIND` to select the right function. .. versionadded:: 3.3 -.. c:macro:: PyUnicode_WCHAR_KIND - PyUnicode_1BYTE_KIND +.. c:macro:: PyUnicode_1BYTE_KIND PyUnicode_2BYTE_KIND PyUnicode_4BYTE_KIND @@ -145,18 +123,16 @@ access internal read-only data of Unicode objects: .. versionadded:: 3.3 - .. deprecated-removed:: 3.10 3.12 - ``PyUnicode_WCHAR_KIND`` is deprecated. + .. versionchanged:: 3.12 + ``PyUnicode_WCHAR_KIND`` has been removed. -.. c:function:: unsigned int PyUnicode_KIND(PyObject *o) +.. c:function:: int PyUnicode_KIND(PyObject *o) Return one of the PyUnicode kind constants (see above) that indicate how many bytes per character this Unicode object uses to store its data. *o* has to be a Unicode object in the "canonical" representation (not checked). - .. XXX document "0" return value? - .. versionadded:: 3.3 @@ -168,20 +144,21 @@ access internal read-only data of Unicode objects: .. versionadded:: 3.3 -.. c:function:: void PyUnicode_WRITE(int kind, void *data, Py_ssize_t index, \ - Py_UCS4 value) +.. c:function:: void PyUnicode_WRITE(int kind, void *data, \ + Py_ssize_t index, Py_UCS4 value) Write into a canonical representation *data* (as obtained with - :c:func:`PyUnicode_DATA`). This macro does not do any sanity checks and is + :c:func:`PyUnicode_DATA`). This function performs no sanity checks, and is intended for usage in loops. The caller should cache the *kind* value and - *data* pointer as obtained from other macro calls. *index* is the index in + *data* pointer as obtained from other calls. *index* is the index in the string (starts at 0) and *value* is the new code point value which should be written to that location. .. versionadded:: 3.3 -.. c:function:: Py_UCS4 PyUnicode_READ(int kind, void *data, Py_ssize_t index) +.. c:function:: Py_UCS4 PyUnicode_READ(int kind, void *data, \ + Py_ssize_t index) Read a code point from a canonical representation *data* (as obtained with :c:func:`PyUnicode_DATA`). No checks or ready calls are performed. @@ -198,7 +175,7 @@ access internal read-only data of Unicode objects: .. versionadded:: 3.3 -.. c:macro:: PyUnicode_MAX_CHAR_VALUE(o) +.. c:function:: Py_UCS4 PyUnicode_MAX_CHAR_VALUE(PyObject *o) Return the maximum code point that is suitable for creating another string based on *o*, which must be in the "canonical" representation. This is @@ -207,49 +184,6 @@ access internal read-only data of Unicode objects: .. versionadded:: 3.3 -.. c:function:: Py_ssize_t PyUnicode_GET_SIZE(PyObject *o) - - Return the size of the deprecated :c:type:`Py_UNICODE` representation, in - code units (this includes surrogate pairs as 2 units). *o* has to be a - Unicode object (not checked). - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style Unicode API, please migrate to using - :c:func:`PyUnicode_GET_LENGTH`. - - -.. c:function:: Py_ssize_t PyUnicode_GET_DATA_SIZE(PyObject *o) - - Return the size of the deprecated :c:type:`Py_UNICODE` representation in - bytes. *o* has to be a Unicode object (not checked). - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style Unicode API, please migrate to using - :c:func:`PyUnicode_GET_LENGTH`. - - -.. c:function:: Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *o) - const char* PyUnicode_AS_DATA(PyObject *o) - - Return a pointer to a :c:type:`Py_UNICODE` representation of the object. The - returned buffer is always terminated with an extra null code point. It - may also contain embedded null code points, which would cause the string - to be truncated when used in most C functions. The ``AS_DATA`` form - casts the pointer to :c:type:`const char *`. The *o* argument has to be - a Unicode object (not checked). - - .. versionchanged:: 3.3 - This macro is now inefficient -- because in many cases the - :c:type:`Py_UNICODE` representation does not exist and needs to be created - -- and can fail (return ``NULL`` with an exception set). Try to port the - code to use the new :c:func:`PyUnicode_nBYTE_DATA` macros or use - :c:func:`PyUnicode_WRITE` or :c:func:`PyUnicode_READ`. - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style Unicode API, please migrate to using the - :c:func:`PyUnicode_nBYTE_DATA` family of macros. - - .. c:function:: int PyUnicode_IsIdentifier(PyObject *o) Return ``1`` if the string is a valid identifier according to the language @@ -268,57 +202,57 @@ are available through these macros which are mapped to C functions depending on the Python configuration. -.. c:function:: int Py_UNICODE_ISSPACE(Py_UNICODE ch) +.. c:function:: int Py_UNICODE_ISSPACE(Py_UCS4 ch) Return ``1`` or ``0`` depending on whether *ch* is a whitespace character. -.. c:function:: int Py_UNICODE_ISLOWER(Py_UNICODE ch) +.. c:function:: int Py_UNICODE_ISLOWER(Py_UCS4 ch) Return ``1`` or ``0`` depending on whether *ch* is a lowercase character. -.. c:function:: int Py_UNICODE_ISUPPER(Py_UNICODE ch) +.. c:function:: int Py_UNICODE_ISUPPER(Py_UCS4 ch) Return ``1`` or ``0`` depending on whether *ch* is an uppercase character. -.. c:function:: int Py_UNICODE_ISTITLE(Py_UNICODE ch) +.. c:function:: int Py_UNICODE_ISTITLE(Py_UCS4 ch) Return ``1`` or ``0`` depending on whether *ch* is a titlecase character. -.. c:function:: int Py_UNICODE_ISLINEBREAK(Py_UNICODE ch) +.. c:function:: int Py_UNICODE_ISLINEBREAK(Py_UCS4 ch) Return ``1`` or ``0`` depending on whether *ch* is a linebreak character. -.. c:function:: int Py_UNICODE_ISDECIMAL(Py_UNICODE ch) +.. c:function:: int Py_UNICODE_ISDECIMAL(Py_UCS4 ch) Return ``1`` or ``0`` depending on whether *ch* is a decimal character. -.. c:function:: int Py_UNICODE_ISDIGIT(Py_UNICODE ch) +.. c:function:: int Py_UNICODE_ISDIGIT(Py_UCS4 ch) Return ``1`` or ``0`` depending on whether *ch* is a digit character. -.. c:function:: int Py_UNICODE_ISNUMERIC(Py_UNICODE ch) +.. c:function:: int Py_UNICODE_ISNUMERIC(Py_UCS4 ch) Return ``1`` or ``0`` depending on whether *ch* is a numeric character. -.. c:function:: int Py_UNICODE_ISALPHA(Py_UNICODE ch) +.. c:function:: int Py_UNICODE_ISALPHA(Py_UCS4 ch) Return ``1`` or ``0`` depending on whether *ch* is an alphabetic character. -.. c:function:: int Py_UNICODE_ISALNUM(Py_UNICODE ch) +.. c:function:: int Py_UNICODE_ISALNUM(Py_UCS4 ch) Return ``1`` or ``0`` depending on whether *ch* is an alphanumeric character. -.. c:function:: int Py_UNICODE_ISPRINTABLE(Py_UNICODE ch) +.. c:function:: int Py_UNICODE_ISPRINTABLE(Py_UCS4 ch) Return ``1`` or ``0`` depending on whether *ch* is a printable character. Nonprintable characters are those characters defined in the Unicode character @@ -332,7 +266,7 @@ the Python configuration. These APIs can be used for fast direct character conversions: -.. c:function:: Py_UNICODE Py_UNICODE_TOLOWER(Py_UNICODE ch) +.. c:function:: Py_UCS4 Py_UNICODE_TOLOWER(Py_UCS4 ch) Return the character *ch* converted to lower case. @@ -340,7 +274,7 @@ These APIs can be used for fast direct character conversions: This function uses simple case mappings. -.. c:function:: Py_UNICODE Py_UNICODE_TOUPPER(Py_UNICODE ch) +.. c:function:: Py_UCS4 Py_UNICODE_TOUPPER(Py_UCS4 ch) Return the character *ch* converted to upper case. @@ -348,7 +282,7 @@ These APIs can be used for fast direct character conversions: This function uses simple case mappings. -.. c:function:: Py_UNICODE Py_UNICODE_TOTITLE(Py_UNICODE ch) +.. c:function:: Py_UCS4 Py_UNICODE_TOTITLE(Py_UCS4 ch) Return the character *ch* converted to title case. @@ -356,43 +290,44 @@ These APIs can be used for fast direct character conversions: This function uses simple case mappings. -.. c:function:: int Py_UNICODE_TODECIMAL(Py_UNICODE ch) +.. c:function:: int Py_UNICODE_TODECIMAL(Py_UCS4 ch) Return the character *ch* converted to a decimal positive integer. Return - ``-1`` if this is not possible. This macro does not raise exceptions. + ``-1`` if this is not possible. This function does not raise exceptions. -.. c:function:: int Py_UNICODE_TODIGIT(Py_UNICODE ch) +.. c:function:: int Py_UNICODE_TODIGIT(Py_UCS4 ch) Return the character *ch* converted to a single digit integer. Return ``-1`` if - this is not possible. This macro does not raise exceptions. + this is not possible. This function does not raise exceptions. -.. c:function:: double Py_UNICODE_TONUMERIC(Py_UNICODE ch) +.. c:function:: double Py_UNICODE_TONUMERIC(Py_UCS4 ch) Return the character *ch* converted to a double. Return ``-1.0`` if this is not - possible. This macro does not raise exceptions. + possible. This function does not raise exceptions. These APIs can be used to work with surrogates: -.. c:macro:: Py_UNICODE_IS_SURROGATE(ch) +.. c:function:: int Py_UNICODE_IS_SURROGATE(Py_UCS4 ch) Check if *ch* is a surrogate (``0xD800 <= ch <= 0xDFFF``). -.. c:macro:: Py_UNICODE_IS_HIGH_SURROGATE(ch) +.. c:function:: int Py_UNICODE_IS_HIGH_SURROGATE(Py_UCS4 ch) Check if *ch* is a high surrogate (``0xD800 <= ch <= 0xDBFF``). -.. c:macro:: Py_UNICODE_IS_LOW_SURROGATE(ch) +.. c:function:: int Py_UNICODE_IS_LOW_SURROGATE(Py_UCS4 ch) Check if *ch* is a low surrogate (``0xDC00 <= ch <= 0xDFFF``). -.. c:macro:: Py_UNICODE_JOIN_SURROGATES(high, low) +.. c:function:: Py_UCS4 Py_UNICODE_JOIN_SURROGATES(Py_UCS4 high, Py_UCS4 low) - Join two surrogate characters and return a single Py_UCS4 value. + Join two surrogate characters and return a single :c:type:`Py_UCS4` value. *high* and *low* are respectively the leading and trailing surrogates in a - surrogate pair. + surrogate pair. *high* must be in the range [0xD800; 0xDBFF] and *low* must + be in the range [0xDC00; 0xDFFF]. Creating and accessing Unicode strings @@ -434,12 +369,17 @@ APIs: Create a Unicode object from the char buffer *u*. The bytes will be interpreted as being UTF-8 encoded. The buffer is copied into the new - object. If the buffer is not ``NULL``, the return value might be a shared - object, i.e. modification of the data is not allowed. + object. + The return value might be a shared object, i.e. modification of the data is + not allowed. - If *u* is ``NULL``, this function behaves like :c:func:`PyUnicode_FromUnicode` - with the buffer set to ``NULL``. This usage is deprecated in favor of - :c:func:`PyUnicode_New`, and will be removed in Python 3.12. + This function raises :exc:`SystemError` when: + + * *size* < 0, + * *u* is ``NULL`` and *size* > 0 + + .. versionchanged:: 3.12 + *u* == ``NULL`` with *size* > 0 is not allowed anymore. .. c:function:: PyObject *PyUnicode_FromString(const char *u) @@ -457,10 +397,6 @@ APIs: ASCII-encoded string. The following format characters are allowed: .. % This should be exactly the same as the table in PyErr_Format. - .. % 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. - .. % Similar comments apply to the %ll width modifier and .. tabularcolumns:: |l|l|L| @@ -496,11 +432,11 @@ APIs: | :attr:`%llu` | unsigned long long | Equivalent to | | | | ``printf("%llu")``. [1]_ | +-------------------+---------------------+----------------------------------+ - | :attr:`%zd` | Py_ssize_t | Equivalent to | - | | | ``printf("%zd")``. [1]_ | + | :attr:`%zd` | :c:type:`\ | Equivalent to | + | | Py_ssize_t` | ``printf("%zd")``. [1]_ | +-------------------+---------------------+----------------------------------+ - | :attr:`%zi` | Py_ssize_t | Equivalent to | - | | | ``printf("%zi")``. [1]_ | + | :attr:`%zi` | :c:type:`\ | Equivalent to | + | | Py_ssize_t` | ``printf("%zi")``. [1]_ | +-------------------+---------------------+----------------------------------+ | :attr:`%zu` | size_t | Equivalent to | | | | ``printf("%zu")``. [1]_ | @@ -541,9 +477,6 @@ APIs: | | | :c:func:`PyObject_Repr`. | +-------------------+---------------------+----------------------------------+ - An unrecognized format character causes all the rest of the format string to be - copied as-is to the result string, and any extra arguments discarded. - .. note:: The width formatter unit is number of characters rather than bytes. The precision formatter unit is number of bytes for ``"%s"`` and @@ -564,6 +497,11 @@ APIs: Support width and precision formatter for ``"%s"``, ``"%A"``, ``"%U"``, ``"%V"``, ``"%S"``, ``"%R"`` added. + .. versionchanged:: 3.12 + An unrecognized format character now sets a :exc:`SystemError`. + In previous versions it caused all the rest of the format string to be + copied as-is to the result string, and any extra arguments discarded. + .. c:function:: PyObject* PyUnicode_FromFormatV(const char *format, va_list vargs) @@ -642,8 +580,8 @@ APIs: .. c:function:: Py_UCS4 PyUnicode_ReadChar(PyObject *unicode, Py_ssize_t index) Read a character from a string. This function checks that *unicode* is a - Unicode object and the index is not out of bounds, in contrast to the macro - version :c:func:`PyUnicode_READ_CHAR`. + Unicode object and the index is not out of bounds, in contrast to + :c:func:`PyUnicode_READ_CHAR`, which performs no error checking. .. versionadded:: 3.3 @@ -678,79 +616,6 @@ APIs: .. versionadded:: 3.3 -Deprecated Py_UNICODE APIs -"""""""""""""""""""""""""" - -.. deprecated-removed:: 3.3 3.12 - -These API functions are deprecated with the implementation of :pep:`393`. -Extension modules can continue using them, as they will not be removed in Python -3.x, but need to be aware that their use can now cause performance and memory hits. - - -.. c:function:: PyObject* PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size) - - Create a Unicode object from the Py_UNICODE buffer *u* of the given size. *u* - may be ``NULL`` which causes the contents to be undefined. It is the user's - responsibility to fill in the needed data. The buffer is copied into the new - object. - - If the buffer is not ``NULL``, the return value might be a shared object. - Therefore, modification of the resulting Unicode object is only allowed when - *u* is ``NULL``. - - If the buffer is ``NULL``, :c:func:`PyUnicode_READY` must be called once the - string content has been filled before using any of the access macros such as - :c:func:`PyUnicode_KIND`. - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style Unicode API, please migrate to using - :c:func:`PyUnicode_FromKindAndData`, :c:func:`PyUnicode_FromWideChar`, or - :c:func:`PyUnicode_New`. - - -.. c:function:: Py_UNICODE* PyUnicode_AsUnicode(PyObject *unicode) - - Return a read-only pointer to the Unicode object's internal - :c:type:`Py_UNICODE` buffer, or ``NULL`` on error. This will create the - :c:type:`Py_UNICODE*` representation of the object if it is not yet - available. The buffer is always terminated with an extra null code point. - Note that the resulting :c:type:`Py_UNICODE` string may also contain - embedded null code points, which would cause the string to be truncated when - used in most C functions. - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style Unicode API, please migrate to using - :c:func:`PyUnicode_AsUCS4`, :c:func:`PyUnicode_AsWideChar`, - :c:func:`PyUnicode_ReadChar` or similar new APIs. - - -.. c:function:: Py_UNICODE* PyUnicode_AsUnicodeAndSize(PyObject *unicode, Py_ssize_t *size) - - Like :c:func:`PyUnicode_AsUnicode`, but also saves the :c:func:`Py_UNICODE` - array length (excluding the extra null terminator) in *size*. - Note that the resulting :c:type:`Py_UNICODE*` string - may contain embedded null code points, which would cause the string to be - truncated when used in most C functions. - - .. versionadded:: 3.3 - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style Unicode API, please migrate to using - :c:func:`PyUnicode_AsUCS4`, :c:func:`PyUnicode_AsWideChar`, - :c:func:`PyUnicode_ReadChar` or similar new APIs. - - -.. c:function:: Py_ssize_t PyUnicode_GetSize(PyObject *unicode) - - Return the size of the deprecated :c:type:`Py_UNICODE` representation, in - code units (this includes surrogate pairs as 2 units). - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style Unicode API, please migrate to using - :c:func:`PyUnicode_GET_LENGTH`. - - .. c:function:: PyObject* PyUnicode_FromObject(PyObject *obj) Copy an instance of a Unicode subtype to a new true Unicode object if @@ -778,8 +643,7 @@ system. cannot contain embedded null characters. Use :c:func:`PyUnicode_DecodeFSDefaultAndSize` to decode a string from - :c:data:`Py_FileSystemDefaultEncoding` (the locale encoding read at - Python startup). + the :term:`filesystem encoding and error handler`. This function ignores the :ref:`Python UTF-8 Mode `. @@ -813,9 +677,8 @@ system. *errors* is ``NULL``. Return a :class:`bytes` object. *unicode* cannot contain embedded null characters. - Use :c:func:`PyUnicode_EncodeFSDefault` to encode a string to - :c:data:`Py_FileSystemDefaultEncoding` (the locale encoding read at - Python startup). + Use :c:func:`PyUnicode_EncodeFSDefault` to encode a string to the + :term:`filesystem encoding and error handler`. This function ignores the :ref:`Python UTF-8 Mode `. @@ -836,19 +699,19 @@ system. File System Encoding """""""""""""""""""" -To encode and decode file names and other environment strings, -:c:data:`Py_FileSystemDefaultEncoding` should be used as the encoding, and -:c:data:`Py_FileSystemDefaultEncodeErrors` should be used as the error handler -(:pep:`383` and :pep:`529`). To encode file names to :class:`bytes` during -argument parsing, the ``"O&"`` converter should be used, passing -:c:func:`PyUnicode_FSConverter` as the conversion function: +Functions encoding to and decoding from the :term:`filesystem encoding and +error handler` (:pep:`383` and :pep:`529`). + +To encode file names to :class:`bytes` during argument parsing, the ``"O&"`` +converter should be used, passing :c:func:`PyUnicode_FSConverter` as the +conversion function: .. c:function:: int PyUnicode_FSConverter(PyObject* obj, void* result) ParseTuple converter: encode :class:`str` objects -- obtained directly or through the :class:`os.PathLike` interface -- to :class:`bytes` using :c:func:`PyUnicode_EncodeFSDefault`; :class:`bytes` objects are output as-is. - *result* must be a :c:type:`PyBytesObject*` which must be released when it is + *result* must be a :c:expr:`PyBytesObject*` which must be released when it is no longer used. .. versionadded:: 3.1 @@ -865,7 +728,7 @@ conversion function: ParseTuple converter: decode :class:`bytes` objects -- obtained either directly or indirectly through the :class:`os.PathLike` interface -- to :class:`str` using :c:func:`PyUnicode_DecodeFSDefaultAndSize`; :class:`str` - objects are output as-is. *result* must be a :c:type:`PyUnicodeObject*` which + objects are output as-is. *result* must be a :c:expr:`PyUnicodeObject*` which must be released when it is no longer used. .. versionadded:: 3.2 @@ -878,12 +741,7 @@ conversion function: Decode a string from the :term:`filesystem encoding and error handler`. - If :c:data:`Py_FileSystemDefaultEncoding` is not set, fall back to the - locale encoding. - - :c:data:`Py_FileSystemDefaultEncoding` is initialized at startup from the - locale encoding and cannot be modified later. If you need to decode a string - from the current locale encoding, use + If you need to decode a string from the current locale encoding, use :c:func:`PyUnicode_DecodeLocaleAndSize`. .. seealso:: @@ -891,7 +749,8 @@ conversion function: The :c:func:`Py_DecodeLocale` function. .. versionchanged:: 3.6 - Use :c:data:`Py_FileSystemDefaultEncodeErrors` error handler. + The :term:`filesystem error handler ` is now used. .. c:function:: PyObject* PyUnicode_DecodeFSDefault(const char *s) @@ -899,28 +758,22 @@ conversion function: Decode a null-terminated string from the :term:`filesystem encoding and error handler`. - If :c:data:`Py_FileSystemDefaultEncoding` is not set, fall back to the - locale encoding. - - Use :c:func:`PyUnicode_DecodeFSDefaultAndSize` if you know the string length. + If the string length is known, use + :c:func:`PyUnicode_DecodeFSDefaultAndSize`. .. versionchanged:: 3.6 - Use :c:data:`Py_FileSystemDefaultEncodeErrors` error handler. + The :term:`filesystem error handler ` is now used. .. c:function:: PyObject* PyUnicode_EncodeFSDefault(PyObject *unicode) - Encode a Unicode object to :c:data:`Py_FileSystemDefaultEncoding` with the - :c:data:`Py_FileSystemDefaultEncodeErrors` error handler, and return - :class:`bytes`. Note that the resulting :class:`bytes` object may contain - null bytes. + Encode a Unicode object to the :term:`filesystem encoding and error + handler`, and return :class:`bytes`. Note that the resulting :class:`bytes` + object can contain null bytes. - If :c:data:`Py_FileSystemDefaultEncoding` is not set, fall back to the - locale encoding. - - :c:data:`Py_FileSystemDefaultEncoding` is initialized at startup from the - locale encoding and cannot be modified later. If you need to encode a string - to the current locale encoding, use :c:func:`PyUnicode_EncodeLocale`. + If you need to encode a string to the current locale encoding, use + :c:func:`PyUnicode_EncodeLocale`. .. seealso:: @@ -929,16 +782,17 @@ conversion function: .. versionadded:: 3.2 .. versionchanged:: 3.6 - Use :c:data:`Py_FileSystemDefaultEncodeErrors` error handler. + The :term:`filesystem error handler ` is now used. wchar_t Support """"""""""""""" -:c:type:`wchar_t` support for platforms which support it: +:c:expr:`wchar_t` support for platforms which support it: .. c:function:: PyObject* PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size) - Create a Unicode object from the :c:type:`wchar_t` buffer *w* of the given *size*. + Create a Unicode object from the :c:expr:`wchar_t` buffer *w* of the given *size*. Passing ``-1`` as the *size* indicates that the function must itself compute the length, using wcslen. Return ``NULL`` on failure. @@ -946,13 +800,13 @@ wchar_t Support .. c:function:: Py_ssize_t PyUnicode_AsWideChar(PyObject *unicode, wchar_t *w, Py_ssize_t size) - Copy the Unicode object contents into the :c:type:`wchar_t` buffer *w*. At most - *size* :c:type:`wchar_t` characters are copied (excluding a possibly trailing - null termination character). Return the number of :c:type:`wchar_t` characters - copied or ``-1`` in case of an error. Note that the resulting :c:type:`wchar_t*` + Copy the Unicode object contents into the :c:expr:`wchar_t` buffer *w*. At most + *size* :c:expr:`wchar_t` characters are copied (excluding a possibly trailing + null termination character). Return the number of :c:expr:`wchar_t` characters + copied or ``-1`` in case of an error. Note that the resulting :c:expr:`wchar_t*` string may or may not be null-terminated. It is the responsibility of the caller - to make sure that the :c:type:`wchar_t*` string is null-terminated in case this is - required by the application. Also, note that the :c:type:`wchar_t*` string + to make sure that the :c:expr:`wchar_t*` string is null-terminated in case this is + required by the application. Also, note that the :c:expr:`wchar_t*` string might contain null characters, which would cause the string to be truncated when used with most C functions. @@ -962,12 +816,12 @@ wchar_t Support Convert the Unicode object to a wide character string. The output string always ends with a null character. If *size* is not ``NULL``, write the number of wide characters (excluding the trailing null termination character) into - *\*size*. Note that the resulting :c:type:`wchar_t` string might contain + *\*size*. Note that the resulting :c:expr:`wchar_t` string might contain null characters, which would cause the string to be truncated when used with - most C functions. If *size* is ``NULL`` and the :c:type:`wchar_t*` string + most C functions. If *size* is ``NULL`` and the :c:expr:`wchar_t*` string contains null characters a :exc:`ValueError` is raised. - Returns a buffer allocated by :c:func:`PyMem_Alloc` (use + Returns a buffer allocated by :c:func:`PyMem_New` (use :c:func:`PyMem_Free` to free it) on success. On error, returns ``NULL`` and *\*size* is undefined. Raises a :exc:`MemoryError` if memory allocation is failed. @@ -975,7 +829,7 @@ wchar_t Support .. versionadded:: 3.2 .. versionchanged:: 3.7 - Raises a :exc:`ValueError` if *size* is ``NULL`` and the :c:type:`wchar_t*` + Raises a :exc:`ValueError` if *size* is ``NULL`` and the :c:expr:`wchar_t*` string contains null characters. @@ -994,16 +848,13 @@ constructor. Setting encoding to ``NULL`` causes the default encoding to be used which is UTF-8. The file system calls should use :c:func:`PyUnicode_FSConverter` for encoding file names. This uses the -variable :c:data:`Py_FileSystemDefaultEncoding` internally. This -variable should be treated as read-only: on some systems, it will be a -pointer to a static string, on others, it will change at run-time -(such as when the application invokes setlocale). +:term:`filesystem encoding and error handler` internally. Error handling is set by errors which may also be set to ``NULL`` meaning to use the default handling defined for the codec. Default error handling for all built-in codecs is "strict" (:exc:`ValueError` is raised). -The codecs all use a similar interface. Only deviation from the following +The codecs all use a similar interface. Only deviations from the following generic ones are documented for simplicity. @@ -1074,7 +925,8 @@ These are the UTF-8 codec APIs: This caches the UTF-8 representation of the string in the Unicode object, and subsequent calls will return a pointer to the same buffer. The caller is not - responsible for deallocating the buffer. + responsible for deallocating the buffer. The buffer is deallocated and + pointers to it become invalid when the Unicode object is garbage collected. .. versionadded:: 3.3 @@ -1171,7 +1023,7 @@ These are the UTF-16 codec APIs: ``1``, any byte order mark is copied to the output (where it will result in either a ``\ufeff`` or a ``\ufffe`` character). - After completion, *\*byteorder* is set to the current byte order at the end + After completion, ``*byteorder`` is set to the current byte order at the end of input data. If *byteorder* is ``NULL``, the codec starts in native order mode. @@ -1302,7 +1154,7 @@ Character Map Codecs This codec is special in that it can be used to implement many different codecs (and this is in fact what was done to obtain most of the standard codecs -included in the :mod:`encodings` package). The codec uses mapping to encode and +included in the :mod:`encodings` package). The codec uses mappings to encode and decode characters. The mapping objects provided must support the :meth:`__getitem__` mapping interface; dictionaries and sequences work well. @@ -1426,7 +1278,7 @@ They all return ``NULL`` or ``-1`` if an exception occurs. .. c:function:: PyObject* PyUnicode_Splitlines(PyObject *s, int keepend) Split a Unicode string at line breaks, returning a list of Unicode strings. - CRLF is considered to be one line break. If *keepend* is ``0``, the Line break + CRLF is considered to be one line break. If *keepend* is ``0``, the line break characters are not included in the resulting strings. diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 3354a2b976f..513856d8a48 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -16,11 +16,11 @@ parameter. The available start symbols are :const:`Py_eval_input`, :const:`Py_file_input`, and :const:`Py_single_input`. These are described following the functions which accept them as parameters. -Note also that several of these functions take :c:type:`FILE*` parameters. One -particular issue which needs to be handled carefully is that the :c:type:`FILE` +Note also that several of these functions take :c:expr:`FILE*` parameters. One +particular issue which needs to be handled carefully is that the :c:expr:`FILE` structure for different C libraries can be different and incompatible. Under Windows (at least), it is possible for dynamically linked extensions to actually -use different libraries, so care should be taken that :c:type:`FILE*` parameters +use different libraries, so care should be taken that :c:expr:`FILE*` parameters are only passed to these functions if it is certain that they were created by the same library that the Python runtime is using. @@ -39,7 +39,7 @@ the same library that the Python runtime is using. Note that if an otherwise unhandled :exc:`SystemExit` is raised, this function will not return ``1``, but exit the process, as long as - ``Py_InspectFlag`` is not set. + :c:member:`PyConfig.inspect` is zero. .. c:function:: int Py_BytesMain(int argc, char **argv) @@ -75,12 +75,14 @@ the same library that the Python runtime is using. :c:func:`PyRun_SimpleFile`. *filename* is decoded from the filesystem encoding (:func:`sys.getfilesystemencoding`). If *filename* is ``NULL``, this function uses ``"???"`` as the filename. + If *closeit* is true, the file is closed before + ``PyRun_SimpleFileExFlags()`` returns. .. c:function:: int PyRun_SimpleString(const char *command) This is a simplified interface to :c:func:`PyRun_SimpleStringFlags` below, - leaving the :c:type:`PyCompilerFlags`\* argument set to ``NULL``. + leaving the :c:struct:`PyCompilerFlags`\* argument set to ``NULL``. .. c:function:: int PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags) @@ -93,7 +95,7 @@ the same library that the Python runtime is using. Note that if an otherwise unhandled :exc:`SystemExit` is raised, this function will not return ``-1``, but exit the process, as long as - ``Py_InspectFlag`` is not set. + :c:member:`PyConfig.inspect` is zero. .. c:function:: int PyRun_SimpleFile(FILE *fp, const char *filename) @@ -284,12 +286,6 @@ the same library that the Python runtime is using. ` arguments and a closure tuple of cells. -.. c:type:: PyFrameObject - - The C structure of the objects used to describe frame objects. The - fields of this type are subject to change at any time. - - .. c:function:: PyObject* PyEval_EvalFrame(PyFrameObject *f) Evaluate an execution frame. This is a simplified interface to @@ -342,7 +338,7 @@ the same library that the Python runtime is using. interpreter loop. -.. c:type:: struct PyCompilerFlags +.. c:struct:: PyCompilerFlags This is the structure used to hold compiler flags. In cases where code is only being compiled, it is passed as ``int flags``, and in cases where code is being diff --git a/Doc/c-api/weakref.rst b/Doc/c-api/weakref.rst index 98ebe711ada..ace743ba01c 100644 --- a/Doc/c-api/weakref.rst +++ b/Doc/c-api/weakref.rst @@ -35,7 +35,7 @@ as much as it can. callable object that receives notification when *ob* is garbage collected; it should accept a single parameter, which will be the weak reference object itself. *callback* may also be ``None`` or ``NULL``. If *ob* is not a - weakly-referencable object, or if *callback* is not callable, ``None``, or + weakly referencable object, or if *callback* is not callable, ``None``, or ``NULL``, this will return ``NULL`` and raise :exc:`TypeError`. @@ -47,7 +47,7 @@ as much as it can. be a callable object that receives notification when *ob* is garbage collected; it should accept a single parameter, which will be the weak reference object itself. *callback* may also be ``None`` or ``NULL``. If *ob* - is not a weakly-referencable object, or if *callback* is not callable, + is not a weakly referencable object, or if *callback* is not callable, ``None``, or ``NULL``, this will return ``NULL`` and raise :exc:`TypeError`. @@ -66,5 +66,4 @@ as much as it can. .. c:function:: PyObject* PyWeakref_GET_OBJECT(PyObject *ref) - Similar to :c:func:`PyWeakref_GetObject`, but implemented as a macro that does no - error checking. + Similar to :c:func:`PyWeakref_GetObject`, but does no error checking. diff --git a/Doc/conf.py b/Doc/conf.py index f626ce67b3c..b3da8fa9ec4 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -13,15 +13,36 @@ sys.path.append(os.path.abspath('includes')) # General configuration # --------------------- -extensions = ['sphinx.ext.coverage', 'sphinx.ext.doctest', - 'pyspecific', 'c_annotations', 'escape4chm', - 'asdl_highlight', 'peg_highlight', 'glossary_search'] +extensions = [ + 'asdl_highlight', + 'c_annotations', + 'escape4chm', + 'glossary_search', + 'peg_highlight', + 'pyspecific', + 'sphinx.ext.coverage', + 'sphinx.ext.doctest', +] + +# Skip if downstream redistributors haven't installed it +try: + import sphinxext.opengraph +except ImportError: + pass +else: + extensions.append('sphinxext.opengraph') + doctest_global_setup = ''' try: import _tkinter except ImportError: _tkinter = None +# Treat warnings as errors, done here to prevent warnings in Sphinx code from +# causing spurious test failures. +import warnings +warnings.simplefilter('error') +del warnings ''' manpages_url = 'https://manpages.debian.org/{path}' @@ -45,7 +66,7 @@ today_fmt = '%B %d, %Y' highlight_language = 'python3' # Minimum version of sphinx required -needs_sphinx = '1.8' +needs_sphinx = '3.2' # Ignore any .rst files in the venv/ directory. exclude_patterns = ['venv/*', 'README.rst'] @@ -69,13 +90,29 @@ html_theme = 'python_docs_theme' html_theme_path = ['tools'] html_theme_options = { 'collapsiblesidebar': True, - 'issues_url': 'https://docs.python.org/3/bugs.html', + 'issues_url': '/bugs.html', + 'license_url': '/license.html', 'root_include_title': False # We use the version switcher instead. } +# Override stylesheet fingerprinting for Windows CHM htmlhelp to fix GH-91207 +# https://github.com/python/cpython/issues/91207 +if any('htmlhelp' in arg for arg in sys.argv): + html_style = 'pydoctheme.css' + print("\nWARNING: Windows CHM Help is no longer supported.") + print("It may be removed in the future\n") + # Short title used e.g. for HTML tags. html_short_title = '%s Documentation' % release +# Deployment preview information, from Netlify +# (See netlify.toml and https://docs.netlify.com/configure-builds/environment-variables/#git-metadata) +html_context = { + "is_deployment_preview": os.getenv("IS_DEPLOYMENT_PREVIEW"), + "repository_url": os.getenv("REPOSITORY_URL"), + "pr_id": os.getenv("REVIEW_ID") +} + # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%b %d, %Y' @@ -101,7 +138,7 @@ html_additional_pages = { html_use_opensearch = 'https://docs.python.org/' + version # Additional static files. -html_static_path = ['tools/static'] +html_static_path = ['_static', 'tools/static'] # Output file base name for HTML help builder. htmlhelp_basename = 'python' + release.replace('.', '') @@ -138,7 +175,7 @@ latex_elements['pointsize'] = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). -_stdauthor = r'Guido van Rossum\\and the Python development team' +_stdauthor = 'Guido van Rossum and the Python development team' latex_documents = [ ('c-api/index', 'c-api.tex', 'The Python/C API', _stdauthor, 'manual'), @@ -184,7 +221,6 @@ epub_publisher = 'Python Software Foundation' coverage_ignore_modules = [ r'[T|t][k|K]', r'Tix', - r'distutils.*', ] coverage_ignore_functions = [ @@ -217,9 +253,7 @@ coverage_ignore_c_items = { # ---------------------------- # Ignore certain URLs. -linkcheck_ignore = [r'https://bugs.python.org/(issue)?\d+', - # Ignore PEPs for now, they all have permanent redirects. - r'http://www.python.org/dev/peps/pep-\d+'] +linkcheck_ignore = [r'https://bugs.python.org/(issue)?\d+'] # Options for extensions @@ -229,14 +263,12 @@ linkcheck_ignore = [r'https://bugs.python.org/(issue)?\d+', refcount_file = 'data/refcounts.dat' stable_abi_file = 'data/stable_abi.dat' -# Sphinx 2 and Sphinx 3 compatibility -# ----------------------------------- - -# bpo-40204: Allow Sphinx 2 syntax in the C domain -c_allow_pre_v3 = True - -# bpo-40204: Disable warnings on Sphinx 2 syntax of the C domain since the -# documentation is built with -W (warnings treated as errors). -c_warn_on_allowed_pre_v3 = False - -strip_signature_backslash = True +# sphinxext-opengraph config +ogp_site_url = 'https://docs.python.org/3/' +ogp_site_name = 'Python documentation' +ogp_image = '_static/og-image.png' +ogp_custom_meta_tags = [ + '<meta property="og:image:width" content="200">', + '<meta property="og:image:height" content="200">', + '<meta name="theme-color" content="#3776ab">', +] diff --git a/Doc/contents.rst b/Doc/contents.rst index 8690de77bf3..464f93bdf85 100644 --- a/Doc/contents.rst +++ b/Doc/contents.rst @@ -27,5 +27,4 @@ .. toctree:: :hidden: - distutils/index.rst install/index.rst diff --git a/Doc/copyright.rst b/Doc/copyright.rst index 4191c0bb63a..9b71683155e 100644 --- a/Doc/copyright.rst +++ b/Doc/copyright.rst @@ -4,7 +4,7 @@ Copyright Python and this documentation is: -Copyright © 2001-2021 Python Software Foundation. All rights reserved. +Copyright © 2001-2023 Python Software Foundation. All rights reserved. Copyright © 2000 BeOpen.com. All rights reserved. diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index 1694cad6f43..349c4dd5be3 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -796,10 +796,18 @@ PyEval_SetProfile:void::: PyEval_SetProfile:Py_tracefunc:func:: PyEval_SetProfile:PyObject*:obj:+1: +PyEval_SetProfileAllThreads:void::: +PyEval_SetProfileAllThreads:Py_tracefunc:func:: +PyEval_SetProfileAllThreads:PyObject*:obj:+1: + PyEval_SetTrace:void::: PyEval_SetTrace:Py_tracefunc:func:: PyEval_SetTrace:PyObject*:obj:+1: +PyEval_SetTraceAllThreads:void::: +PyEval_SetTraceAllThreads:Py_tracefunc:func:: +PyEval_SetTraceAllThreads:PyObject*:obj:+1: + PyEval_EvalCode:PyObject*::+1: PyEval_EvalCode:PyObject*:co:0: PyEval_EvalCode:PyObject*:globals:0: @@ -1010,10 +1018,10 @@ PyImport_Import:PyObject*::+1: PyImport_Import:PyObject*:name:0: PyImport_ImportFrozenModule:int::: -PyImport_ImportFrozenModule:const char*::: +PyImport_ImportFrozenModule:const char*:name:: PyImport_ImportFrozenModuleObject:int::: -PyImport_ImportFrozenModuleObject:PyObject*::+1: +PyImport_ImportFrozenModuleObject:PyObject*:name:+1: PyImport_ImportModule:PyObject*::+1: PyImport_ImportModule:const char*:name:: diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index 64a0a2a247c..53895bbced8 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -1,867 +1,896 @@ -role,name,added,ifdef_note -function,PyAIter_Check,3.10, -function,PyArg_Parse,3.2, -function,PyArg_ParseTuple,3.2, -function,PyArg_ParseTupleAndKeywords,3.2, -function,PyArg_UnpackTuple,3.2, -function,PyArg_VaParse,3.2, -function,PyArg_VaParseTupleAndKeywords,3.2, -function,PyArg_ValidateKeywordArguments,3.2, -var,PyBaseObject_Type,3.2, -function,PyBool_FromLong,3.2, -var,PyBool_Type,3.2, -var,PyByteArrayIter_Type,3.2, -function,PyByteArray_AsString,3.2, -function,PyByteArray_Concat,3.2, -function,PyByteArray_FromObject,3.2, -function,PyByteArray_FromStringAndSize,3.2, -function,PyByteArray_Resize,3.2, -function,PyByteArray_Size,3.2, -var,PyByteArray_Type,3.2, -var,PyBytesIter_Type,3.2, -function,PyBytes_AsString,3.2, -function,PyBytes_AsStringAndSize,3.2, -function,PyBytes_Concat,3.2, -function,PyBytes_ConcatAndDel,3.2, -function,PyBytes_DecodeEscape,3.2, -function,PyBytes_FromFormat,3.2, -function,PyBytes_FromFormatV,3.2, -function,PyBytes_FromObject,3.2, -function,PyBytes_FromString,3.2, -function,PyBytes_FromStringAndSize,3.2, -function,PyBytes_Repr,3.2, -function,PyBytes_Size,3.2, -var,PyBytes_Type,3.2, -type,PyCFunction,3.2, -type,PyCFunctionWithKeywords,3.2, -function,PyCFunction_Call,3.2, -function,PyCFunction_GetFlags,3.2, -function,PyCFunction_GetFunction,3.2, -function,PyCFunction_GetSelf,3.2, -function,PyCFunction_New,3.4, -function,PyCFunction_NewEx,3.2, -var,PyCFunction_Type,3.2, -function,PyCMethod_New,3.9, -function,PyCallIter_New,3.2, -var,PyCallIter_Type,3.2, -function,PyCallable_Check,3.2, -type,PyCapsule_Destructor,3.2, -function,PyCapsule_GetContext,3.2, -function,PyCapsule_GetDestructor,3.2, -function,PyCapsule_GetName,3.2, -function,PyCapsule_GetPointer,3.2, -function,PyCapsule_Import,3.2, -function,PyCapsule_IsValid,3.2, -function,PyCapsule_New,3.2, -function,PyCapsule_SetContext,3.2, -function,PyCapsule_SetDestructor,3.2, -function,PyCapsule_SetName,3.2, -function,PyCapsule_SetPointer,3.2, -var,PyCapsule_Type,3.2, -var,PyClassMethodDescr_Type,3.2, -function,PyCodec_BackslashReplaceErrors,3.2, -function,PyCodec_Decode,3.2, -function,PyCodec_Decoder,3.2, -function,PyCodec_Encode,3.2, -function,PyCodec_Encoder,3.2, -function,PyCodec_IgnoreErrors,3.2, -function,PyCodec_IncrementalDecoder,3.2, -function,PyCodec_IncrementalEncoder,3.2, -function,PyCodec_KnownEncoding,3.2, -function,PyCodec_LookupError,3.2, -function,PyCodec_NameReplaceErrors,3.7, -function,PyCodec_Register,3.2, -function,PyCodec_RegisterError,3.2, -function,PyCodec_ReplaceErrors,3.2, -function,PyCodec_StreamReader,3.2, -function,PyCodec_StreamWriter,3.2, -function,PyCodec_StrictErrors,3.2, -function,PyCodec_Unregister,3.10, -function,PyCodec_XMLCharRefReplaceErrors,3.2, -function,PyComplex_FromDoubles,3.2, -function,PyComplex_ImagAsDouble,3.2, -function,PyComplex_RealAsDouble,3.2, -var,PyComplex_Type,3.2, -function,PyDescr_NewClassMethod,3.2, -function,PyDescr_NewGetSet,3.2, -function,PyDescr_NewMember,3.2, -function,PyDescr_NewMethod,3.2, -var,PyDictItems_Type,3.2, -var,PyDictIterItem_Type,3.2, -var,PyDictIterKey_Type,3.2, -var,PyDictIterValue_Type,3.2, -var,PyDictKeys_Type,3.2, -function,PyDictProxy_New,3.2, -var,PyDictProxy_Type,3.2, -var,PyDictRevIterItem_Type,3.8, -var,PyDictRevIterKey_Type,3.8, -var,PyDictRevIterValue_Type,3.8, -var,PyDictValues_Type,3.2, -function,PyDict_Clear,3.2, -function,PyDict_Contains,3.2, -function,PyDict_Copy,3.2, -function,PyDict_DelItem,3.2, -function,PyDict_DelItemString,3.2, -function,PyDict_GetItem,3.2, -function,PyDict_GetItemString,3.2, -function,PyDict_GetItemWithError,3.2, -function,PyDict_Items,3.2, -function,PyDict_Keys,3.2, -function,PyDict_Merge,3.2, -function,PyDict_MergeFromSeq2,3.2, -function,PyDict_New,3.2, -function,PyDict_Next,3.2, -function,PyDict_SetItem,3.2, -function,PyDict_SetItemString,3.2, -function,PyDict_Size,3.2, -var,PyDict_Type,3.2, -function,PyDict_Update,3.2, -function,PyDict_Values,3.2, -var,PyEllipsis_Type,3.2, -var,PyEnum_Type,3.2, -function,PyErr_BadArgument,3.2, -function,PyErr_BadInternalCall,3.2, -function,PyErr_CheckSignals,3.2, -function,PyErr_Clear,3.2, -function,PyErr_Display,3.2, -function,PyErr_ExceptionMatches,3.2, -function,PyErr_Fetch,3.2, -function,PyErr_Format,3.2, -function,PyErr_FormatV,3.5, -function,PyErr_GetExcInfo,3.7, -function,PyErr_GivenExceptionMatches,3.2, -function,PyErr_NewException,3.2, -function,PyErr_NewExceptionWithDoc,3.2, -function,PyErr_NoMemory,3.2, -function,PyErr_NormalizeException,3.2, -function,PyErr_Occurred,3.2, -function,PyErr_Print,3.2, -function,PyErr_PrintEx,3.2, -function,PyErr_ProgramText,3.2, -function,PyErr_ResourceWarning,3.6, -function,PyErr_Restore,3.2, -function,PyErr_SetExcFromWindowsErr,3.7,on Windows -function,PyErr_SetExcFromWindowsErrWithFilename,3.7,on Windows -function,PyErr_SetExcFromWindowsErrWithFilenameObject,3.7,on Windows -function,PyErr_SetExcFromWindowsErrWithFilenameObjects,3.7,on Windows -function,PyErr_SetExcInfo,3.7, -function,PyErr_SetFromErrno,3.2, -function,PyErr_SetFromErrnoWithFilename,3.2, -function,PyErr_SetFromErrnoWithFilenameObject,3.2, -function,PyErr_SetFromErrnoWithFilenameObjects,3.7, -function,PyErr_SetFromWindowsErr,3.7,on Windows -function,PyErr_SetFromWindowsErrWithFilename,3.7,on Windows -function,PyErr_SetImportError,3.7, -function,PyErr_SetImportErrorSubclass,3.6, -function,PyErr_SetInterrupt,3.2, -function,PyErr_SetInterruptEx,3.10, -function,PyErr_SetNone,3.2, -function,PyErr_SetObject,3.2, -function,PyErr_SetString,3.2, -function,PyErr_SyntaxLocation,3.2, -function,PyErr_SyntaxLocationEx,3.7, -function,PyErr_WarnEx,3.2, -function,PyErr_WarnExplicit,3.2, -function,PyErr_WarnFormat,3.2, -function,PyErr_WriteUnraisable,3.2, -function,PyEval_AcquireLock,3.2, -function,PyEval_AcquireThread,3.2, -function,PyEval_CallFunction,3.2, -function,PyEval_CallMethod,3.2, -function,PyEval_CallObjectWithKeywords,3.2, -function,PyEval_EvalCode,3.2, -function,PyEval_EvalCodeEx,3.2, -function,PyEval_EvalFrame,3.2, -function,PyEval_EvalFrameEx,3.2, -function,PyEval_GetBuiltins,3.2, -function,PyEval_GetFrame,3.2, -function,PyEval_GetFuncDesc,3.2, -function,PyEval_GetFuncName,3.2, -function,PyEval_GetGlobals,3.2, -function,PyEval_GetLocals,3.2, -function,PyEval_InitThreads,3.2, -function,PyEval_ReleaseLock,3.2, -function,PyEval_ReleaseThread,3.2, -function,PyEval_RestoreThread,3.2, -function,PyEval_SaveThread,3.2, -function,PyEval_ThreadsInitialized,3.2, -var,PyExc_ArithmeticError,3.2, -var,PyExc_AssertionError,3.2, -var,PyExc_AttributeError,3.2, -var,PyExc_BaseException,3.2, -var,PyExc_BaseExceptionGroup,3.11, -var,PyExc_BlockingIOError,3.7, -var,PyExc_BrokenPipeError,3.7, -var,PyExc_BufferError,3.2, -var,PyExc_BytesWarning,3.2, -var,PyExc_ChildProcessError,3.7, -var,PyExc_ConnectionAbortedError,3.7, -var,PyExc_ConnectionError,3.7, -var,PyExc_ConnectionRefusedError,3.7, -var,PyExc_ConnectionResetError,3.7, -var,PyExc_DeprecationWarning,3.2, -var,PyExc_EOFError,3.2, -var,PyExc_EncodingWarning,3.10, -var,PyExc_EnvironmentError,3.2, -var,PyExc_Exception,3.2, -var,PyExc_FileExistsError,3.7, -var,PyExc_FileNotFoundError,3.7, -var,PyExc_FloatingPointError,3.2, -var,PyExc_FutureWarning,3.2, -var,PyExc_GeneratorExit,3.2, -var,PyExc_IOError,3.2, -var,PyExc_ImportError,3.2, -var,PyExc_ImportWarning,3.2, -var,PyExc_IndentationError,3.2, -var,PyExc_IndexError,3.2, -var,PyExc_InterruptedError,3.7, -var,PyExc_IsADirectoryError,3.7, -var,PyExc_KeyError,3.2, -var,PyExc_KeyboardInterrupt,3.2, -var,PyExc_LookupError,3.2, -var,PyExc_MemoryError,3.2, -var,PyExc_ModuleNotFoundError,3.6, -var,PyExc_NameError,3.2, -var,PyExc_NotADirectoryError,3.7, -var,PyExc_NotImplementedError,3.2, -var,PyExc_OSError,3.2, -var,PyExc_OverflowError,3.2, -var,PyExc_PendingDeprecationWarning,3.2, -var,PyExc_PermissionError,3.7, -var,PyExc_ProcessLookupError,3.7, -var,PyExc_RecursionError,3.7, -var,PyExc_ReferenceError,3.2, -var,PyExc_ResourceWarning,3.7, -var,PyExc_RuntimeError,3.2, -var,PyExc_RuntimeWarning,3.2, -var,PyExc_StopAsyncIteration,3.7, -var,PyExc_StopIteration,3.2, -var,PyExc_SyntaxError,3.2, -var,PyExc_SyntaxWarning,3.2, -var,PyExc_SystemError,3.2, -var,PyExc_SystemExit,3.2, -var,PyExc_TabError,3.2, -var,PyExc_TimeoutError,3.7, -var,PyExc_TypeError,3.2, -var,PyExc_UnboundLocalError,3.2, -var,PyExc_UnicodeDecodeError,3.2, -var,PyExc_UnicodeEncodeError,3.2, -var,PyExc_UnicodeError,3.2, -var,PyExc_UnicodeTranslateError,3.2, -var,PyExc_UnicodeWarning,3.2, -var,PyExc_UserWarning,3.2, -var,PyExc_ValueError,3.2, -var,PyExc_Warning,3.2, -var,PyExc_WindowsError,3.7,on Windows -var,PyExc_ZeroDivisionError,3.2, -function,PyExceptionClass_Name,3.8, -function,PyException_GetCause,3.2, -function,PyException_GetContext,3.2, -function,PyException_GetTraceback,3.2, -function,PyException_SetCause,3.2, -function,PyException_SetContext,3.2, -function,PyException_SetTraceback,3.2, -function,PyFile_FromFd,3.2, -function,PyFile_GetLine,3.2, -function,PyFile_WriteObject,3.2, -function,PyFile_WriteString,3.2, -var,PyFilter_Type,3.2, -function,PyFloat_AsDouble,3.2, -function,PyFloat_FromDouble,3.2, -function,PyFloat_FromString,3.2, -function,PyFloat_GetInfo,3.2, -function,PyFloat_GetMax,3.2, -function,PyFloat_GetMin,3.2, -var,PyFloat_Type,3.2, -type,PyFrameObject,3.2, -function,PyFrame_GetCode,3.10, -function,PyFrame_GetLineNumber,3.10, -function,PyFrozenSet_New,3.2, -var,PyFrozenSet_Type,3.2, -function,PyGC_Collect,3.2, -function,PyGC_Disable,3.10, -function,PyGC_Enable,3.10, -function,PyGC_IsEnabled,3.10, -function,PyGILState_Ensure,3.2, -function,PyGILState_GetThisThreadState,3.2, -function,PyGILState_Release,3.2, -type,PyGILState_STATE,3.2, -type,PyGetSetDef,3.2, -var,PyGetSetDescr_Type,3.2, -function,PyImport_AddModule,3.2, -function,PyImport_AddModuleObject,3.7, -function,PyImport_AppendInittab,3.2, -function,PyImport_ExecCodeModule,3.2, -function,PyImport_ExecCodeModuleEx,3.2, -function,PyImport_ExecCodeModuleObject,3.7, -function,PyImport_ExecCodeModuleWithPathnames,3.2, -function,PyImport_GetImporter,3.2, -function,PyImport_GetMagicNumber,3.2, -function,PyImport_GetMagicTag,3.2, -function,PyImport_GetModule,3.8, -function,PyImport_GetModuleDict,3.2, -function,PyImport_Import,3.2, -function,PyImport_ImportFrozenModule,3.2, -function,PyImport_ImportFrozenModuleObject,3.7, -function,PyImport_ImportModule,3.2, -function,PyImport_ImportModuleLevel,3.2, -function,PyImport_ImportModuleLevelObject,3.7, -function,PyImport_ImportModuleNoBlock,3.2, -function,PyImport_ReloadModule,3.2, -function,PyIndex_Check,3.8, -type,PyInterpreterState,3.2, -function,PyInterpreterState_Clear,3.2, -function,PyInterpreterState_Delete,3.2, -function,PyInterpreterState_Get,3.9, -function,PyInterpreterState_GetDict,3.8, -function,PyInterpreterState_GetID,3.7, -function,PyInterpreterState_New,3.2, -function,PyIter_Check,3.8, -function,PyIter_Next,3.2, -function,PyIter_Send,3.10, -var,PyListIter_Type,3.2, -var,PyListRevIter_Type,3.2, -function,PyList_Append,3.2, -function,PyList_AsTuple,3.2, -function,PyList_GetItem,3.2, -function,PyList_GetSlice,3.2, -function,PyList_Insert,3.2, -function,PyList_New,3.2, -function,PyList_Reverse,3.2, -function,PyList_SetItem,3.2, -function,PyList_SetSlice,3.2, -function,PyList_Size,3.2, -function,PyList_Sort,3.2, -var,PyList_Type,3.2, -type,PyLongObject,3.2, -var,PyLongRangeIter_Type,3.2, -function,PyLong_AsDouble,3.2, -function,PyLong_AsLong,3.2, -function,PyLong_AsLongAndOverflow,3.2, -function,PyLong_AsLongLong,3.2, -function,PyLong_AsLongLongAndOverflow,3.2, -function,PyLong_AsSize_t,3.2, -function,PyLong_AsSsize_t,3.2, -function,PyLong_AsUnsignedLong,3.2, -function,PyLong_AsUnsignedLongLong,3.2, -function,PyLong_AsUnsignedLongLongMask,3.2, -function,PyLong_AsUnsignedLongMask,3.2, -function,PyLong_AsVoidPtr,3.2, -function,PyLong_FromDouble,3.2, -function,PyLong_FromLong,3.2, -function,PyLong_FromLongLong,3.2, -function,PyLong_FromSize_t,3.2, -function,PyLong_FromSsize_t,3.2, -function,PyLong_FromString,3.2, -function,PyLong_FromUnsignedLong,3.2, -function,PyLong_FromUnsignedLongLong,3.2, -function,PyLong_FromVoidPtr,3.2, -function,PyLong_GetInfo,3.2, -var,PyLong_Type,3.2, -var,PyMap_Type,3.2, -function,PyMapping_Check,3.2, -function,PyMapping_GetItemString,3.2, -function,PyMapping_HasKey,3.2, -function,PyMapping_HasKeyString,3.2, -function,PyMapping_Items,3.2, -function,PyMapping_Keys,3.2, -function,PyMapping_Length,3.2, -function,PyMapping_SetItemString,3.2, -function,PyMapping_Size,3.2, -function,PyMapping_Values,3.2, -function,PyMem_Calloc,3.7, -function,PyMem_Free,3.2, -function,PyMem_Malloc,3.2, -function,PyMem_Realloc,3.2, -type,PyMemberDef,3.2, -var,PyMemberDescr_Type,3.2, -function,PyMemoryView_FromMemory,3.7, -function,PyMemoryView_FromObject,3.2, -function,PyMemoryView_GetContiguous,3.2, -var,PyMemoryView_Type,3.2, -type,PyMethodDef,3.2, -var,PyMethodDescr_Type,3.2, -type,PyModuleDef,3.2, -type,PyModuleDef_Base,3.2, -function,PyModuleDef_Init,3.5, -var,PyModuleDef_Type,3.5, -function,PyModule_AddFunctions,3.7, -function,PyModule_AddIntConstant,3.2, -function,PyModule_AddObject,3.2, -function,PyModule_AddObjectRef,3.10, -function,PyModule_AddStringConstant,3.2, -function,PyModule_AddType,3.10, -function,PyModule_Create2,3.2, -function,PyModule_ExecDef,3.7, -function,PyModule_FromDefAndSpec2,3.7, -function,PyModule_GetDef,3.2, -function,PyModule_GetDict,3.2, -function,PyModule_GetFilename,3.2, -function,PyModule_GetFilenameObject,3.2, -function,PyModule_GetName,3.2, -function,PyModule_GetNameObject,3.7, -function,PyModule_GetState,3.2, -function,PyModule_New,3.2, -function,PyModule_NewObject,3.7, -function,PyModule_SetDocString,3.7, -var,PyModule_Type,3.2, -function,PyNumber_Absolute,3.2, -function,PyNumber_Add,3.2, -function,PyNumber_And,3.2, -function,PyNumber_AsSsize_t,3.2, -function,PyNumber_Check,3.2, -function,PyNumber_Divmod,3.2, -function,PyNumber_Float,3.2, -function,PyNumber_FloorDivide,3.2, -function,PyNumber_InPlaceAdd,3.2, -function,PyNumber_InPlaceAnd,3.2, -function,PyNumber_InPlaceFloorDivide,3.2, -function,PyNumber_InPlaceLshift,3.2, -function,PyNumber_InPlaceMatrixMultiply,3.7, -function,PyNumber_InPlaceMultiply,3.2, -function,PyNumber_InPlaceOr,3.2, -function,PyNumber_InPlacePower,3.2, -function,PyNumber_InPlaceRemainder,3.2, -function,PyNumber_InPlaceRshift,3.2, -function,PyNumber_InPlaceSubtract,3.2, -function,PyNumber_InPlaceTrueDivide,3.2, -function,PyNumber_InPlaceXor,3.2, -function,PyNumber_Index,3.2, -function,PyNumber_Invert,3.2, -function,PyNumber_Long,3.2, -function,PyNumber_Lshift,3.2, -function,PyNumber_MatrixMultiply,3.7, -function,PyNumber_Multiply,3.2, -function,PyNumber_Negative,3.2, -function,PyNumber_Or,3.2, -function,PyNumber_Positive,3.2, -function,PyNumber_Power,3.2, -function,PyNumber_Remainder,3.2, -function,PyNumber_Rshift,3.2, -function,PyNumber_Subtract,3.2, -function,PyNumber_ToBase,3.2, -function,PyNumber_TrueDivide,3.2, -function,PyNumber_Xor,3.2, -function,PyOS_AfterFork,3.2,on platforms with fork() -function,PyOS_AfterFork_Child,3.7,on platforms with fork() -function,PyOS_AfterFork_Parent,3.7,on platforms with fork() -function,PyOS_BeforeFork,3.7,on platforms with fork() -function,PyOS_CheckStack,3.7,on platforms with USE_STACKCHECK -function,PyOS_FSPath,3.6, -var,PyOS_InputHook,3.2, -function,PyOS_InterruptOccurred,3.2, -function,PyOS_double_to_string,3.2, -function,PyOS_getsig,3.2, -function,PyOS_mystricmp,3.2, -function,PyOS_mystrnicmp,3.2, -function,PyOS_setsig,3.2, -type,PyOS_sighandler_t,3.2, -function,PyOS_snprintf,3.2, -function,PyOS_string_to_double,3.2, -function,PyOS_strtol,3.2, -function,PyOS_strtoul,3.2, -function,PyOS_vsnprintf,3.2, -type,PyObject,3.2, -function,PyObject_ASCII,3.2, -function,PyObject_AsCharBuffer,3.2, -function,PyObject_AsFileDescriptor,3.2, -function,PyObject_AsReadBuffer,3.2, -function,PyObject_AsWriteBuffer,3.2, -function,PyObject_Bytes,3.2, -function,PyObject_Call,3.2, -function,PyObject_CallFunction,3.2, -function,PyObject_CallFunctionObjArgs,3.2, -function,PyObject_CallMethod,3.2, -function,PyObject_CallMethodObjArgs,3.2, -function,PyObject_CallNoArgs,3.10, -function,PyObject_CallObject,3.2, -function,PyObject_Calloc,3.7, -function,PyObject_CheckReadBuffer,3.2, -function,PyObject_ClearWeakRefs,3.2, -function,PyObject_DelItem,3.2, -function,PyObject_DelItemString,3.2, -function,PyObject_Dir,3.2, -function,PyObject_Format,3.2, -function,PyObject_Free,3.2, -function,PyObject_GC_Del,3.2, -function,PyObject_GC_IsFinalized,3.9, -function,PyObject_GC_IsTracked,3.9, -function,PyObject_GC_Track,3.2, -function,PyObject_GC_UnTrack,3.2, -function,PyObject_GenericGetAttr,3.2, -function,PyObject_GenericGetDict,3.10, -function,PyObject_GenericSetAttr,3.2, -function,PyObject_GenericSetDict,3.7, -function,PyObject_GetAIter,3.10, -function,PyObject_GetAttr,3.2, -function,PyObject_GetAttrString,3.2, -function,PyObject_GetItem,3.2, -function,PyObject_GetIter,3.2, -function,PyObject_HasAttr,3.2, -function,PyObject_HasAttrString,3.2, -function,PyObject_Hash,3.2, -function,PyObject_HashNotImplemented,3.2, -function,PyObject_Init,3.2, -function,PyObject_InitVar,3.2, -function,PyObject_IsInstance,3.2, -function,PyObject_IsSubclass,3.2, -function,PyObject_IsTrue,3.2, -function,PyObject_Length,3.2, -function,PyObject_Malloc,3.2, -function,PyObject_Not,3.2, -function,PyObject_Realloc,3.2, -function,PyObject_Repr,3.2, -function,PyObject_RichCompare,3.2, -function,PyObject_RichCompareBool,3.2, -function,PyObject_SelfIter,3.2, -function,PyObject_SetAttr,3.2, -function,PyObject_SetAttrString,3.2, -function,PyObject_SetItem,3.2, -function,PyObject_Size,3.2, -function,PyObject_Str,3.2, -function,PyObject_Type,3.2, -var,PyProperty_Type,3.2, -var,PyRangeIter_Type,3.2, -var,PyRange_Type,3.2, -var,PyReversed_Type,3.2, -function,PySeqIter_New,3.2, -var,PySeqIter_Type,3.2, -function,PySequence_Check,3.2, -function,PySequence_Concat,3.2, -function,PySequence_Contains,3.2, -function,PySequence_Count,3.2, -function,PySequence_DelItem,3.2, -function,PySequence_DelSlice,3.2, -function,PySequence_Fast,3.2, -function,PySequence_GetItem,3.2, -function,PySequence_GetSlice,3.2, -function,PySequence_In,3.2, -function,PySequence_InPlaceConcat,3.2, -function,PySequence_InPlaceRepeat,3.2, -function,PySequence_Index,3.2, -function,PySequence_Length,3.2, -function,PySequence_List,3.2, -function,PySequence_Repeat,3.2, -function,PySequence_SetItem,3.2, -function,PySequence_SetSlice,3.2, -function,PySequence_Size,3.2, -function,PySequence_Tuple,3.2, -var,PySetIter_Type,3.2, -function,PySet_Add,3.2, -function,PySet_Clear,3.2, -function,PySet_Contains,3.2, -function,PySet_Discard,3.2, -function,PySet_New,3.2, -function,PySet_Pop,3.2, -function,PySet_Size,3.2, -var,PySet_Type,3.2, -function,PySlice_AdjustIndices,3.7, -function,PySlice_GetIndices,3.2, -function,PySlice_GetIndicesEx,3.2, -function,PySlice_New,3.2, -var,PySlice_Type,3.2, -function,PySlice_Unpack,3.7, -function,PyState_AddModule,3.3, -function,PyState_FindModule,3.2, -function,PyState_RemoveModule,3.3, -type,PyStructSequence_Desc,3.2, -type,PyStructSequence_Field,3.2, -function,PyStructSequence_GetItem,3.2, -function,PyStructSequence_New,3.2, -function,PyStructSequence_NewType,3.2, -function,PyStructSequence_SetItem,3.2, -var,PyStructSequence_UnnamedField,3.11, -var,PySuper_Type,3.2, -function,PySys_AddWarnOption,3.2, -function,PySys_AddWarnOptionUnicode,3.2, -function,PySys_AddXOption,3.7, -function,PySys_FormatStderr,3.2, -function,PySys_FormatStdout,3.2, -function,PySys_GetObject,3.2, -function,PySys_GetXOptions,3.7, -function,PySys_HasWarnOptions,3.2, -function,PySys_ResetWarnOptions,3.2, -function,PySys_SetArgv,3.2, -function,PySys_SetArgvEx,3.2, -function,PySys_SetObject,3.2, -function,PySys_SetPath,3.2, -function,PySys_WriteStderr,3.2, -function,PySys_WriteStdout,3.2, -type,PyThreadState,3.2, -function,PyThreadState_Clear,3.2, -function,PyThreadState_Delete,3.2, -function,PyThreadState_Get,3.2, -function,PyThreadState_GetDict,3.2, -function,PyThreadState_GetFrame,3.10, -function,PyThreadState_GetID,3.10, -function,PyThreadState_GetInterpreter,3.10, -function,PyThreadState_New,3.2, -function,PyThreadState_SetAsyncExc,3.2, -function,PyThreadState_Swap,3.2, -function,PyThread_GetInfo,3.3, -function,PyThread_ReInitTLS,3.2, -function,PyThread_acquire_lock,3.2, -function,PyThread_acquire_lock_timed,3.2, -function,PyThread_allocate_lock,3.2, -function,PyThread_create_key,3.2, -function,PyThread_delete_key,3.2, -function,PyThread_delete_key_value,3.2, -function,PyThread_exit_thread,3.2, -function,PyThread_free_lock,3.2, -function,PyThread_get_key_value,3.2, -function,PyThread_get_stacksize,3.2, -function,PyThread_get_thread_ident,3.2, -function,PyThread_get_thread_native_id,3.2, -function,PyThread_init_thread,3.2, -function,PyThread_release_lock,3.2, -function,PyThread_set_key_value,3.2, -function,PyThread_set_stacksize,3.2, -function,PyThread_start_new_thread,3.2, -function,PyThread_tss_alloc,3.7, -function,PyThread_tss_create,3.7, -function,PyThread_tss_delete,3.7, -function,PyThread_tss_free,3.7, -function,PyThread_tss_get,3.7, -function,PyThread_tss_is_created,3.7, -function,PyThread_tss_set,3.7, -function,PyTraceBack_Here,3.2, -function,PyTraceBack_Print,3.2, -var,PyTraceBack_Type,3.2, -var,PyTupleIter_Type,3.2, -function,PyTuple_GetItem,3.2, -function,PyTuple_GetSlice,3.2, -function,PyTuple_New,3.2, -function,PyTuple_Pack,3.2, -function,PyTuple_SetItem,3.2, -function,PyTuple_Size,3.2, -var,PyTuple_Type,3.2, -type,PyTypeObject,3.2, -function,PyType_ClearCache,3.2, -function,PyType_FromModuleAndSpec,3.10, -function,PyType_FromSpec,3.2, -function,PyType_FromSpecWithBases,3.3, -function,PyType_GenericAlloc,3.2, -function,PyType_GenericNew,3.2, -function,PyType_GetFlags,3.2, -function,PyType_GetModule,3.10, -function,PyType_GetModuleState,3.10, -function,PyType_GetName,3.11, -function,PyType_GetQualName,3.11, -function,PyType_GetSlot,3.4, -function,PyType_IsSubtype,3.2, -function,PyType_Modified,3.2, -function,PyType_Ready,3.2, -type,PyType_Slot,3.2, -type,PyType_Spec,3.2, -var,PyType_Type,3.2, -function,PyUnicodeDecodeError_Create,3.2, -function,PyUnicodeDecodeError_GetEncoding,3.2, -function,PyUnicodeDecodeError_GetEnd,3.2, -function,PyUnicodeDecodeError_GetObject,3.2, -function,PyUnicodeDecodeError_GetReason,3.2, -function,PyUnicodeDecodeError_GetStart,3.2, -function,PyUnicodeDecodeError_SetEnd,3.2, -function,PyUnicodeDecodeError_SetReason,3.2, -function,PyUnicodeDecodeError_SetStart,3.2, -function,PyUnicodeEncodeError_GetEncoding,3.2, -function,PyUnicodeEncodeError_GetEnd,3.2, -function,PyUnicodeEncodeError_GetObject,3.2, -function,PyUnicodeEncodeError_GetReason,3.2, -function,PyUnicodeEncodeError_GetStart,3.2, -function,PyUnicodeEncodeError_SetEnd,3.2, -function,PyUnicodeEncodeError_SetReason,3.2, -function,PyUnicodeEncodeError_SetStart,3.2, -var,PyUnicodeIter_Type,3.2, -function,PyUnicodeTranslateError_GetEnd,3.2, -function,PyUnicodeTranslateError_GetObject,3.2, -function,PyUnicodeTranslateError_GetReason,3.2, -function,PyUnicodeTranslateError_GetStart,3.2, -function,PyUnicodeTranslateError_SetEnd,3.2, -function,PyUnicodeTranslateError_SetReason,3.2, -function,PyUnicodeTranslateError_SetStart,3.2, -function,PyUnicode_Append,3.2, -function,PyUnicode_AppendAndDel,3.2, -function,PyUnicode_AsASCIIString,3.2, -function,PyUnicode_AsCharmapString,3.2, -function,PyUnicode_AsDecodedObject,3.2, -function,PyUnicode_AsDecodedUnicode,3.2, -function,PyUnicode_AsEncodedObject,3.2, -function,PyUnicode_AsEncodedString,3.2, -function,PyUnicode_AsEncodedUnicode,3.2, -function,PyUnicode_AsLatin1String,3.2, -function,PyUnicode_AsMBCSString,3.7,on Windows -function,PyUnicode_AsRawUnicodeEscapeString,3.2, -function,PyUnicode_AsUCS4,3.7, -function,PyUnicode_AsUCS4Copy,3.7, -function,PyUnicode_AsUTF16String,3.2, -function,PyUnicode_AsUTF32String,3.2, -function,PyUnicode_AsUTF8AndSize,3.10, -function,PyUnicode_AsUTF8String,3.2, -function,PyUnicode_AsUnicodeEscapeString,3.2, -function,PyUnicode_AsWideChar,3.2, -function,PyUnicode_AsWideCharString,3.7, -function,PyUnicode_BuildEncodingMap,3.2, -function,PyUnicode_Compare,3.2, -function,PyUnicode_CompareWithASCIIString,3.2, -function,PyUnicode_Concat,3.2, -function,PyUnicode_Contains,3.2, -function,PyUnicode_Count,3.2, -function,PyUnicode_Decode,3.2, -function,PyUnicode_DecodeASCII,3.2, -function,PyUnicode_DecodeCharmap,3.2, -function,PyUnicode_DecodeCodePageStateful,3.7,on Windows -function,PyUnicode_DecodeFSDefault,3.2, -function,PyUnicode_DecodeFSDefaultAndSize,3.2, -function,PyUnicode_DecodeLatin1,3.2, -function,PyUnicode_DecodeLocale,3.7, -function,PyUnicode_DecodeLocaleAndSize,3.7, -function,PyUnicode_DecodeMBCS,3.7,on Windows -function,PyUnicode_DecodeMBCSStateful,3.7,on Windows -function,PyUnicode_DecodeRawUnicodeEscape,3.2, -function,PyUnicode_DecodeUTF16,3.2, -function,PyUnicode_DecodeUTF16Stateful,3.2, -function,PyUnicode_DecodeUTF32,3.2, -function,PyUnicode_DecodeUTF32Stateful,3.2, -function,PyUnicode_DecodeUTF7,3.2, -function,PyUnicode_DecodeUTF7Stateful,3.2, -function,PyUnicode_DecodeUTF8,3.2, -function,PyUnicode_DecodeUTF8Stateful,3.2, -function,PyUnicode_DecodeUnicodeEscape,3.2, -function,PyUnicode_EncodeCodePage,3.7,on Windows -function,PyUnicode_EncodeFSDefault,3.2, -function,PyUnicode_EncodeLocale,3.7, -function,PyUnicode_FSConverter,3.2, -function,PyUnicode_FSDecoder,3.2, -function,PyUnicode_Find,3.2, -function,PyUnicode_FindChar,3.7, -function,PyUnicode_Format,3.2, -function,PyUnicode_FromEncodedObject,3.2, -function,PyUnicode_FromFormat,3.2, -function,PyUnicode_FromFormatV,3.2, -function,PyUnicode_FromObject,3.2, -function,PyUnicode_FromOrdinal,3.2, -function,PyUnicode_FromString,3.2, -function,PyUnicode_FromStringAndSize,3.2, -function,PyUnicode_FromWideChar,3.2, -function,PyUnicode_GetDefaultEncoding,3.2, -function,PyUnicode_GetLength,3.7, -function,PyUnicode_GetSize,3.2, -function,PyUnicode_InternFromString,3.2, -function,PyUnicode_InternImmortal,3.2, -function,PyUnicode_InternInPlace,3.2, -function,PyUnicode_IsIdentifier,3.2, -function,PyUnicode_Join,3.2, -function,PyUnicode_Partition,3.2, -function,PyUnicode_RPartition,3.2, -function,PyUnicode_RSplit,3.2, -function,PyUnicode_ReadChar,3.7, -function,PyUnicode_Replace,3.2, -function,PyUnicode_Resize,3.2, -function,PyUnicode_RichCompare,3.2, -function,PyUnicode_Split,3.2, -function,PyUnicode_Splitlines,3.2, -function,PyUnicode_Substring,3.7, -function,PyUnicode_Tailmatch,3.2, -function,PyUnicode_Translate,3.2, -var,PyUnicode_Type,3.2, -function,PyUnicode_WriteChar,3.7, -type,PyVarObject,3.2, -type,PyWeakReference,3.2, -function,PyWeakref_GetObject,3.2, -function,PyWeakref_NewProxy,3.2, -function,PyWeakref_NewRef,3.2, -var,PyWrapperDescr_Type,3.2, -function,PyWrapper_New,3.2, -var,PyZip_Type,3.2, -function,Py_AddPendingCall,3.2, -function,Py_AtExit,3.2, -macro,Py_BEGIN_ALLOW_THREADS,3.2, -macro,Py_BLOCK_THREADS,3.2, -function,Py_BuildValue,3.2, -function,Py_BytesMain,3.8, -function,Py_CompileString,3.2, -function,Py_DecRef,3.2, -function,Py_DecodeLocale,3.7, -macro,Py_END_ALLOW_THREADS,3.2, -function,Py_EncodeLocale,3.7, -function,Py_EndInterpreter,3.2, -function,Py_EnterRecursiveCall,3.9, -function,Py_Exit,3.2, -function,Py_FatalError,3.2, -var,Py_FileSystemDefaultEncodeErrors,3.10, -var,Py_FileSystemDefaultEncoding,3.2, -function,Py_Finalize,3.2, -function,Py_FinalizeEx,3.6, -function,Py_GenericAlias,3.9, -var,Py_GenericAliasType,3.9, -function,Py_GetBuildInfo,3.2, -function,Py_GetCompiler,3.2, -function,Py_GetCopyright,3.2, -function,Py_GetExecPrefix,3.2, -function,Py_GetPath,3.2, -function,Py_GetPlatform,3.2, -function,Py_GetPrefix,3.2, -function,Py_GetProgramFullPath,3.2, -function,Py_GetProgramName,3.2, -function,Py_GetPythonHome,3.2, -function,Py_GetRecursionLimit,3.2, -function,Py_GetVersion,3.2, -var,Py_HasFileSystemDefaultEncoding,3.2, -function,Py_IncRef,3.2, -function,Py_Initialize,3.2, -function,Py_InitializeEx,3.2, -function,Py_Is,3.10, -function,Py_IsFalse,3.10, -function,Py_IsInitialized,3.2, -function,Py_IsNone,3.10, -function,Py_IsTrue,3.10, -function,Py_LeaveRecursiveCall,3.9, -function,Py_Main,3.2, -function,Py_MakePendingCalls,3.2, -function,Py_NewInterpreter,3.2, -function,Py_NewRef,3.10, -function,Py_ReprEnter,3.2, -function,Py_ReprLeave,3.2, -function,Py_SetPath,3.7, -function,Py_SetProgramName,3.2, -function,Py_SetPythonHome,3.2, -function,Py_SetRecursionLimit,3.2, -type,Py_UCS4,3.2, -macro,Py_UNBLOCK_THREADS,3.2, -var,Py_UTF8Mode,3.8, -function,Py_VaBuildValue,3.2, -function,Py_XNewRef,3.10, -type,Py_intptr_t,3.2, -type,Py_ssize_t,3.2, -type,Py_uintptr_t,3.2, -type,allocfunc,3.2, -type,binaryfunc,3.2, -type,descrgetfunc,3.2, -type,descrsetfunc,3.2, -type,destructor,3.2, -type,getattrfunc,3.2, -type,getattrofunc,3.2, -type,getiterfunc,3.2, -type,getter,3.2, -type,hashfunc,3.2, -type,initproc,3.2, -type,inquiry,3.2, -type,iternextfunc,3.2, -type,lenfunc,3.2, -type,newfunc,3.2, -type,objobjargproc,3.2, -type,objobjproc,3.2, -type,reprfunc,3.2, -type,richcmpfunc,3.2, -type,setattrfunc,3.2, -type,setattrofunc,3.2, -type,setter,3.2, -type,ssizeargfunc,3.2, -type,ssizeobjargproc,3.2, -type,ssizessizeargfunc,3.2, -type,ssizessizeobjargproc,3.2, -type,symtable,3.2, -type,ternaryfunc,3.2, -type,traverseproc,3.2, -type,unaryfunc,3.2, -type,visitproc,3.2, +role,name,added,ifdef_note,struct_abi_kind +macro,PY_VECTORCALL_ARGUMENTS_OFFSET,3.12,, +function,PyAIter_Check,3.10,, +function,PyArg_Parse,3.2,, +function,PyArg_ParseTuple,3.2,, +function,PyArg_ParseTupleAndKeywords,3.2,, +function,PyArg_UnpackTuple,3.2,, +function,PyArg_VaParse,3.2,, +function,PyArg_VaParseTupleAndKeywords,3.2,, +function,PyArg_ValidateKeywordArguments,3.2,, +var,PyBaseObject_Type,3.2,, +function,PyBool_FromLong,3.2,, +var,PyBool_Type,3.2,, +function,PyBuffer_FillContiguousStrides,3.11,, +function,PyBuffer_FillInfo,3.11,, +function,PyBuffer_FromContiguous,3.11,, +function,PyBuffer_GetPointer,3.11,, +function,PyBuffer_IsContiguous,3.11,, +function,PyBuffer_Release,3.11,, +function,PyBuffer_SizeFromFormat,3.11,, +function,PyBuffer_ToContiguous,3.11,, +var,PyByteArrayIter_Type,3.2,, +function,PyByteArray_AsString,3.2,, +function,PyByteArray_Concat,3.2,, +function,PyByteArray_FromObject,3.2,, +function,PyByteArray_FromStringAndSize,3.2,, +function,PyByteArray_Resize,3.2,, +function,PyByteArray_Size,3.2,, +var,PyByteArray_Type,3.2,, +var,PyBytesIter_Type,3.2,, +function,PyBytes_AsString,3.2,, +function,PyBytes_AsStringAndSize,3.2,, +function,PyBytes_Concat,3.2,, +function,PyBytes_ConcatAndDel,3.2,, +function,PyBytes_DecodeEscape,3.2,, +function,PyBytes_FromFormat,3.2,, +function,PyBytes_FromFormatV,3.2,, +function,PyBytes_FromObject,3.2,, +function,PyBytes_FromString,3.2,, +function,PyBytes_FromStringAndSize,3.2,, +function,PyBytes_Repr,3.2,, +function,PyBytes_Size,3.2,, +var,PyBytes_Type,3.2,, +type,PyCFunction,3.2,, +type,PyCFunctionWithKeywords,3.2,, +function,PyCFunction_Call,3.2,, +function,PyCFunction_GetFlags,3.2,, +function,PyCFunction_GetFunction,3.2,, +function,PyCFunction_GetSelf,3.2,, +function,PyCFunction_New,3.4,, +function,PyCFunction_NewEx,3.2,, +var,PyCFunction_Type,3.2,, +function,PyCMethod_New,3.9,, +function,PyCallIter_New,3.2,, +var,PyCallIter_Type,3.2,, +function,PyCallable_Check,3.2,, +type,PyCapsule_Destructor,3.2,, +function,PyCapsule_GetContext,3.2,, +function,PyCapsule_GetDestructor,3.2,, +function,PyCapsule_GetName,3.2,, +function,PyCapsule_GetPointer,3.2,, +function,PyCapsule_Import,3.2,, +function,PyCapsule_IsValid,3.2,, +function,PyCapsule_New,3.2,, +function,PyCapsule_SetContext,3.2,, +function,PyCapsule_SetDestructor,3.2,, +function,PyCapsule_SetName,3.2,, +function,PyCapsule_SetPointer,3.2,, +var,PyCapsule_Type,3.2,, +var,PyClassMethodDescr_Type,3.2,, +function,PyCodec_BackslashReplaceErrors,3.2,, +function,PyCodec_Decode,3.2,, +function,PyCodec_Decoder,3.2,, +function,PyCodec_Encode,3.2,, +function,PyCodec_Encoder,3.2,, +function,PyCodec_IgnoreErrors,3.2,, +function,PyCodec_IncrementalDecoder,3.2,, +function,PyCodec_IncrementalEncoder,3.2,, +function,PyCodec_KnownEncoding,3.2,, +function,PyCodec_LookupError,3.2,, +function,PyCodec_NameReplaceErrors,3.7,, +function,PyCodec_Register,3.2,, +function,PyCodec_RegisterError,3.2,, +function,PyCodec_ReplaceErrors,3.2,, +function,PyCodec_StreamReader,3.2,, +function,PyCodec_StreamWriter,3.2,, +function,PyCodec_StrictErrors,3.2,, +function,PyCodec_Unregister,3.10,, +function,PyCodec_XMLCharRefReplaceErrors,3.2,, +function,PyComplex_FromDoubles,3.2,, +function,PyComplex_ImagAsDouble,3.2,, +function,PyComplex_RealAsDouble,3.2,, +var,PyComplex_Type,3.2,, +function,PyDescr_NewClassMethod,3.2,, +function,PyDescr_NewGetSet,3.2,, +function,PyDescr_NewMember,3.2,, +function,PyDescr_NewMethod,3.2,, +var,PyDictItems_Type,3.2,, +var,PyDictIterItem_Type,3.2,, +var,PyDictIterKey_Type,3.2,, +var,PyDictIterValue_Type,3.2,, +var,PyDictKeys_Type,3.2,, +function,PyDictProxy_New,3.2,, +var,PyDictProxy_Type,3.2,, +var,PyDictRevIterItem_Type,3.8,, +var,PyDictRevIterKey_Type,3.8,, +var,PyDictRevIterValue_Type,3.8,, +var,PyDictValues_Type,3.2,, +function,PyDict_Clear,3.2,, +function,PyDict_Contains,3.2,, +function,PyDict_Copy,3.2,, +function,PyDict_DelItem,3.2,, +function,PyDict_DelItemString,3.2,, +function,PyDict_GetItem,3.2,, +function,PyDict_GetItemString,3.2,, +function,PyDict_GetItemWithError,3.2,, +function,PyDict_Items,3.2,, +function,PyDict_Keys,3.2,, +function,PyDict_Merge,3.2,, +function,PyDict_MergeFromSeq2,3.2,, +function,PyDict_New,3.2,, +function,PyDict_Next,3.2,, +function,PyDict_SetItem,3.2,, +function,PyDict_SetItemString,3.2,, +function,PyDict_Size,3.2,, +var,PyDict_Type,3.2,, +function,PyDict_Update,3.2,, +function,PyDict_Values,3.2,, +var,PyEllipsis_Type,3.2,, +var,PyEnum_Type,3.2,, +function,PyErr_BadArgument,3.2,, +function,PyErr_BadInternalCall,3.2,, +function,PyErr_CheckSignals,3.2,, +function,PyErr_Clear,3.2,, +function,PyErr_Display,3.2,, +function,PyErr_ExceptionMatches,3.2,, +function,PyErr_Fetch,3.2,, +function,PyErr_Format,3.2,, +function,PyErr_FormatV,3.5,, +function,PyErr_GetExcInfo,3.7,, +function,PyErr_GetHandledException,3.11,, +function,PyErr_GivenExceptionMatches,3.2,, +function,PyErr_NewException,3.2,, +function,PyErr_NewExceptionWithDoc,3.2,, +function,PyErr_NoMemory,3.2,, +function,PyErr_NormalizeException,3.2,, +function,PyErr_Occurred,3.2,, +function,PyErr_Print,3.2,, +function,PyErr_PrintEx,3.2,, +function,PyErr_ProgramText,3.2,, +function,PyErr_ResourceWarning,3.6,, +function,PyErr_Restore,3.2,, +function,PyErr_SetExcFromWindowsErr,3.7,on Windows, +function,PyErr_SetExcFromWindowsErrWithFilename,3.7,on Windows, +function,PyErr_SetExcFromWindowsErrWithFilenameObject,3.7,on Windows, +function,PyErr_SetExcFromWindowsErrWithFilenameObjects,3.7,on Windows, +function,PyErr_SetExcInfo,3.7,, +function,PyErr_SetFromErrno,3.2,, +function,PyErr_SetFromErrnoWithFilename,3.2,, +function,PyErr_SetFromErrnoWithFilenameObject,3.2,, +function,PyErr_SetFromErrnoWithFilenameObjects,3.7,, +function,PyErr_SetFromWindowsErr,3.7,on Windows, +function,PyErr_SetFromWindowsErrWithFilename,3.7,on Windows, +function,PyErr_SetHandledException,3.11,, +function,PyErr_SetImportError,3.7,, +function,PyErr_SetImportErrorSubclass,3.6,, +function,PyErr_SetInterrupt,3.2,, +function,PyErr_SetInterruptEx,3.10,, +function,PyErr_SetNone,3.2,, +function,PyErr_SetObject,3.2,, +function,PyErr_SetString,3.2,, +function,PyErr_SyntaxLocation,3.2,, +function,PyErr_SyntaxLocationEx,3.7,, +function,PyErr_WarnEx,3.2,, +function,PyErr_WarnExplicit,3.2,, +function,PyErr_WarnFormat,3.2,, +function,PyErr_WriteUnraisable,3.2,, +function,PyEval_AcquireLock,3.2,, +function,PyEval_AcquireThread,3.2,, +function,PyEval_CallFunction,3.2,, +function,PyEval_CallMethod,3.2,, +function,PyEval_CallObjectWithKeywords,3.2,, +function,PyEval_EvalCode,3.2,, +function,PyEval_EvalCodeEx,3.2,, +function,PyEval_EvalFrame,3.2,, +function,PyEval_EvalFrameEx,3.2,, +function,PyEval_GetBuiltins,3.2,, +function,PyEval_GetFrame,3.2,, +function,PyEval_GetFuncDesc,3.2,, +function,PyEval_GetFuncName,3.2,, +function,PyEval_GetGlobals,3.2,, +function,PyEval_GetLocals,3.2,, +function,PyEval_InitThreads,3.2,, +function,PyEval_ReleaseLock,3.2,, +function,PyEval_ReleaseThread,3.2,, +function,PyEval_RestoreThread,3.2,, +function,PyEval_SaveThread,3.2,, +function,PyEval_ThreadsInitialized,3.2,, +var,PyExc_ArithmeticError,3.2,, +var,PyExc_AssertionError,3.2,, +var,PyExc_AttributeError,3.2,, +var,PyExc_BaseException,3.2,, +var,PyExc_BaseExceptionGroup,3.11,, +var,PyExc_BlockingIOError,3.7,, +var,PyExc_BrokenPipeError,3.7,, +var,PyExc_BufferError,3.2,, +var,PyExc_BytesWarning,3.2,, +var,PyExc_ChildProcessError,3.7,, +var,PyExc_ConnectionAbortedError,3.7,, +var,PyExc_ConnectionError,3.7,, +var,PyExc_ConnectionRefusedError,3.7,, +var,PyExc_ConnectionResetError,3.7,, +var,PyExc_DeprecationWarning,3.2,, +var,PyExc_EOFError,3.2,, +var,PyExc_EncodingWarning,3.10,, +var,PyExc_EnvironmentError,3.2,, +var,PyExc_Exception,3.2,, +var,PyExc_FileExistsError,3.7,, +var,PyExc_FileNotFoundError,3.7,, +var,PyExc_FloatingPointError,3.2,, +var,PyExc_FutureWarning,3.2,, +var,PyExc_GeneratorExit,3.2,, +var,PyExc_IOError,3.2,, +var,PyExc_ImportError,3.2,, +var,PyExc_ImportWarning,3.2,, +var,PyExc_IndentationError,3.2,, +var,PyExc_IndexError,3.2,, +var,PyExc_InterruptedError,3.7,, +var,PyExc_IsADirectoryError,3.7,, +var,PyExc_KeyError,3.2,, +var,PyExc_KeyboardInterrupt,3.2,, +var,PyExc_LookupError,3.2,, +var,PyExc_MemoryError,3.2,, +var,PyExc_ModuleNotFoundError,3.6,, +var,PyExc_NameError,3.2,, +var,PyExc_NotADirectoryError,3.7,, +var,PyExc_NotImplementedError,3.2,, +var,PyExc_OSError,3.2,, +var,PyExc_OverflowError,3.2,, +var,PyExc_PendingDeprecationWarning,3.2,, +var,PyExc_PermissionError,3.7,, +var,PyExc_ProcessLookupError,3.7,, +var,PyExc_RecursionError,3.7,, +var,PyExc_ReferenceError,3.2,, +var,PyExc_ResourceWarning,3.7,, +var,PyExc_RuntimeError,3.2,, +var,PyExc_RuntimeWarning,3.2,, +var,PyExc_StopAsyncIteration,3.7,, +var,PyExc_StopIteration,3.2,, +var,PyExc_SyntaxError,3.2,, +var,PyExc_SyntaxWarning,3.2,, +var,PyExc_SystemError,3.2,, +var,PyExc_SystemExit,3.2,, +var,PyExc_TabError,3.2,, +var,PyExc_TimeoutError,3.7,, +var,PyExc_TypeError,3.2,, +var,PyExc_UnboundLocalError,3.2,, +var,PyExc_UnicodeDecodeError,3.2,, +var,PyExc_UnicodeEncodeError,3.2,, +var,PyExc_UnicodeError,3.2,, +var,PyExc_UnicodeTranslateError,3.2,, +var,PyExc_UnicodeWarning,3.2,, +var,PyExc_UserWarning,3.2,, +var,PyExc_ValueError,3.2,, +var,PyExc_Warning,3.2,, +var,PyExc_WindowsError,3.7,on Windows, +var,PyExc_ZeroDivisionError,3.2,, +function,PyExceptionClass_Name,3.8,, +function,PyException_GetCause,3.2,, +function,PyException_GetContext,3.2,, +function,PyException_GetTraceback,3.2,, +function,PyException_SetCause,3.2,, +function,PyException_SetContext,3.2,, +function,PyException_SetTraceback,3.2,, +function,PyFile_FromFd,3.2,, +function,PyFile_GetLine,3.2,, +function,PyFile_WriteObject,3.2,, +function,PyFile_WriteString,3.2,, +var,PyFilter_Type,3.2,, +function,PyFloat_AsDouble,3.2,, +function,PyFloat_FromDouble,3.2,, +function,PyFloat_FromString,3.2,, +function,PyFloat_GetInfo,3.2,, +function,PyFloat_GetMax,3.2,, +function,PyFloat_GetMin,3.2,, +var,PyFloat_Type,3.2,, +type,PyFrameObject,3.2,,opaque +function,PyFrame_GetCode,3.10,, +function,PyFrame_GetLineNumber,3.10,, +function,PyFrozenSet_New,3.2,, +var,PyFrozenSet_Type,3.2,, +function,PyGC_Collect,3.2,, +function,PyGC_Disable,3.10,, +function,PyGC_Enable,3.10,, +function,PyGC_IsEnabled,3.10,, +function,PyGILState_Ensure,3.2,, +function,PyGILState_GetThisThreadState,3.2,, +function,PyGILState_Release,3.2,, +type,PyGILState_STATE,3.2,, +type,PyGetSetDef,3.2,,full-abi +var,PyGetSetDescr_Type,3.2,, +function,PyImport_AddModule,3.2,, +function,PyImport_AddModuleObject,3.7,, +function,PyImport_AppendInittab,3.2,, +function,PyImport_ExecCodeModule,3.2,, +function,PyImport_ExecCodeModuleEx,3.2,, +function,PyImport_ExecCodeModuleObject,3.7,, +function,PyImport_ExecCodeModuleWithPathnames,3.2,, +function,PyImport_GetImporter,3.2,, +function,PyImport_GetMagicNumber,3.2,, +function,PyImport_GetMagicTag,3.2,, +function,PyImport_GetModule,3.8,, +function,PyImport_GetModuleDict,3.2,, +function,PyImport_Import,3.2,, +function,PyImport_ImportFrozenModule,3.2,, +function,PyImport_ImportFrozenModuleObject,3.7,, +function,PyImport_ImportModule,3.2,, +function,PyImport_ImportModuleLevel,3.2,, +function,PyImport_ImportModuleLevelObject,3.7,, +function,PyImport_ImportModuleNoBlock,3.2,, +function,PyImport_ReloadModule,3.2,, +function,PyIndex_Check,3.8,, +type,PyInterpreterState,3.2,,opaque +function,PyInterpreterState_Clear,3.2,, +function,PyInterpreterState_Delete,3.2,, +function,PyInterpreterState_Get,3.9,, +function,PyInterpreterState_GetDict,3.8,, +function,PyInterpreterState_GetID,3.7,, +function,PyInterpreterState_New,3.2,, +function,PyIter_Check,3.8,, +function,PyIter_Next,3.2,, +function,PyIter_Send,3.10,, +var,PyListIter_Type,3.2,, +var,PyListRevIter_Type,3.2,, +function,PyList_Append,3.2,, +function,PyList_AsTuple,3.2,, +function,PyList_GetItem,3.2,, +function,PyList_GetSlice,3.2,, +function,PyList_Insert,3.2,, +function,PyList_New,3.2,, +function,PyList_Reverse,3.2,, +function,PyList_SetItem,3.2,, +function,PyList_SetSlice,3.2,, +function,PyList_Size,3.2,, +function,PyList_Sort,3.2,, +var,PyList_Type,3.2,, +type,PyLongObject,3.2,,opaque +var,PyLongRangeIter_Type,3.2,, +function,PyLong_AsDouble,3.2,, +function,PyLong_AsLong,3.2,, +function,PyLong_AsLongAndOverflow,3.2,, +function,PyLong_AsLongLong,3.2,, +function,PyLong_AsLongLongAndOverflow,3.2,, +function,PyLong_AsSize_t,3.2,, +function,PyLong_AsSsize_t,3.2,, +function,PyLong_AsUnsignedLong,3.2,, +function,PyLong_AsUnsignedLongLong,3.2,, +function,PyLong_AsUnsignedLongLongMask,3.2,, +function,PyLong_AsUnsignedLongMask,3.2,, +function,PyLong_AsVoidPtr,3.2,, +function,PyLong_FromDouble,3.2,, +function,PyLong_FromLong,3.2,, +function,PyLong_FromLongLong,3.2,, +function,PyLong_FromSize_t,3.2,, +function,PyLong_FromSsize_t,3.2,, +function,PyLong_FromString,3.2,, +function,PyLong_FromUnsignedLong,3.2,, +function,PyLong_FromUnsignedLongLong,3.2,, +function,PyLong_FromVoidPtr,3.2,, +function,PyLong_GetInfo,3.2,, +var,PyLong_Type,3.2,, +var,PyMap_Type,3.2,, +function,PyMapping_Check,3.2,, +function,PyMapping_GetItemString,3.2,, +function,PyMapping_HasKey,3.2,, +function,PyMapping_HasKeyString,3.2,, +function,PyMapping_Items,3.2,, +function,PyMapping_Keys,3.2,, +function,PyMapping_Length,3.2,, +function,PyMapping_SetItemString,3.2,, +function,PyMapping_Size,3.2,, +function,PyMapping_Values,3.2,, +function,PyMem_Calloc,3.7,, +function,PyMem_Free,3.2,, +function,PyMem_Malloc,3.2,, +function,PyMem_Realloc,3.2,, +type,PyMemberDef,3.2,,full-abi +var,PyMemberDescr_Type,3.2,, +function,PyMember_GetOne,3.2,, +function,PyMember_SetOne,3.2,, +function,PyMemoryView_FromBuffer,3.11,, +function,PyMemoryView_FromMemory,3.7,, +function,PyMemoryView_FromObject,3.2,, +function,PyMemoryView_GetContiguous,3.2,, +var,PyMemoryView_Type,3.2,, +type,PyMethodDef,3.2,,full-abi +var,PyMethodDescr_Type,3.2,, +type,PyModuleDef,3.2,,full-abi +type,PyModuleDef_Base,3.2,,full-abi +function,PyModuleDef_Init,3.5,, +var,PyModuleDef_Type,3.5,, +function,PyModule_AddFunctions,3.7,, +function,PyModule_AddIntConstant,3.2,, +function,PyModule_AddObject,3.2,, +function,PyModule_AddObjectRef,3.10,, +function,PyModule_AddStringConstant,3.2,, +function,PyModule_AddType,3.10,, +function,PyModule_Create2,3.2,, +function,PyModule_ExecDef,3.7,, +function,PyModule_FromDefAndSpec2,3.7,, +function,PyModule_GetDef,3.2,, +function,PyModule_GetDict,3.2,, +function,PyModule_GetFilename,3.2,, +function,PyModule_GetFilenameObject,3.2,, +function,PyModule_GetName,3.2,, +function,PyModule_GetNameObject,3.7,, +function,PyModule_GetState,3.2,, +function,PyModule_New,3.2,, +function,PyModule_NewObject,3.7,, +function,PyModule_SetDocString,3.7,, +var,PyModule_Type,3.2,, +function,PyNumber_Absolute,3.2,, +function,PyNumber_Add,3.2,, +function,PyNumber_And,3.2,, +function,PyNumber_AsSsize_t,3.2,, +function,PyNumber_Check,3.2,, +function,PyNumber_Divmod,3.2,, +function,PyNumber_Float,3.2,, +function,PyNumber_FloorDivide,3.2,, +function,PyNumber_InPlaceAdd,3.2,, +function,PyNumber_InPlaceAnd,3.2,, +function,PyNumber_InPlaceFloorDivide,3.2,, +function,PyNumber_InPlaceLshift,3.2,, +function,PyNumber_InPlaceMatrixMultiply,3.7,, +function,PyNumber_InPlaceMultiply,3.2,, +function,PyNumber_InPlaceOr,3.2,, +function,PyNumber_InPlacePower,3.2,, +function,PyNumber_InPlaceRemainder,3.2,, +function,PyNumber_InPlaceRshift,3.2,, +function,PyNumber_InPlaceSubtract,3.2,, +function,PyNumber_InPlaceTrueDivide,3.2,, +function,PyNumber_InPlaceXor,3.2,, +function,PyNumber_Index,3.2,, +function,PyNumber_Invert,3.2,, +function,PyNumber_Long,3.2,, +function,PyNumber_Lshift,3.2,, +function,PyNumber_MatrixMultiply,3.7,, +function,PyNumber_Multiply,3.2,, +function,PyNumber_Negative,3.2,, +function,PyNumber_Or,3.2,, +function,PyNumber_Positive,3.2,, +function,PyNumber_Power,3.2,, +function,PyNumber_Remainder,3.2,, +function,PyNumber_Rshift,3.2,, +function,PyNumber_Subtract,3.2,, +function,PyNumber_ToBase,3.2,, +function,PyNumber_TrueDivide,3.2,, +function,PyNumber_Xor,3.2,, +function,PyOS_AfterFork,3.2,on platforms with fork(), +function,PyOS_AfterFork_Child,3.7,on platforms with fork(), +function,PyOS_AfterFork_Parent,3.7,on platforms with fork(), +function,PyOS_BeforeFork,3.7,on platforms with fork(), +function,PyOS_CheckStack,3.7,on platforms with USE_STACKCHECK, +function,PyOS_FSPath,3.6,, +var,PyOS_InputHook,3.2,, +function,PyOS_InterruptOccurred,3.2,, +function,PyOS_double_to_string,3.2,, +function,PyOS_getsig,3.2,, +function,PyOS_mystricmp,3.2,, +function,PyOS_mystrnicmp,3.2,, +function,PyOS_setsig,3.2,, +type,PyOS_sighandler_t,3.2,, +function,PyOS_snprintf,3.2,, +function,PyOS_string_to_double,3.2,, +function,PyOS_strtol,3.2,, +function,PyOS_strtoul,3.2,, +function,PyOS_vsnprintf,3.2,, +type,PyObject,3.2,,members +member,PyObject.ob_refcnt,3.2,, +member,PyObject.ob_type,3.2,, +function,PyObject_ASCII,3.2,, +function,PyObject_AsCharBuffer,3.2,, +function,PyObject_AsFileDescriptor,3.2,, +function,PyObject_AsReadBuffer,3.2,, +function,PyObject_AsWriteBuffer,3.2,, +function,PyObject_Bytes,3.2,, +function,PyObject_Call,3.2,, +function,PyObject_CallFunction,3.2,, +function,PyObject_CallFunctionObjArgs,3.2,, +function,PyObject_CallMethod,3.2,, +function,PyObject_CallMethodObjArgs,3.2,, +function,PyObject_CallNoArgs,3.10,, +function,PyObject_CallObject,3.2,, +function,PyObject_Calloc,3.7,, +function,PyObject_CheckBuffer,3.11,, +function,PyObject_CheckReadBuffer,3.2,, +function,PyObject_ClearWeakRefs,3.2,, +function,PyObject_CopyData,3.11,, +function,PyObject_DelItem,3.2,, +function,PyObject_DelItemString,3.2,, +function,PyObject_Dir,3.2,, +function,PyObject_Format,3.2,, +function,PyObject_Free,3.2,, +function,PyObject_GC_Del,3.2,, +function,PyObject_GC_IsFinalized,3.9,, +function,PyObject_GC_IsTracked,3.9,, +function,PyObject_GC_Track,3.2,, +function,PyObject_GC_UnTrack,3.2,, +function,PyObject_GenericGetAttr,3.2,, +function,PyObject_GenericGetDict,3.10,, +function,PyObject_GenericSetAttr,3.2,, +function,PyObject_GenericSetDict,3.7,, +function,PyObject_GetAIter,3.10,, +function,PyObject_GetAttr,3.2,, +function,PyObject_GetAttrString,3.2,, +function,PyObject_GetBuffer,3.11,, +function,PyObject_GetItem,3.2,, +function,PyObject_GetIter,3.2,, +function,PyObject_HasAttr,3.2,, +function,PyObject_HasAttrString,3.2,, +function,PyObject_Hash,3.2,, +function,PyObject_HashNotImplemented,3.2,, +function,PyObject_Init,3.2,, +function,PyObject_InitVar,3.2,, +function,PyObject_IsInstance,3.2,, +function,PyObject_IsSubclass,3.2,, +function,PyObject_IsTrue,3.2,, +function,PyObject_Length,3.2,, +function,PyObject_Malloc,3.2,, +function,PyObject_Not,3.2,, +function,PyObject_Realloc,3.2,, +function,PyObject_Repr,3.2,, +function,PyObject_RichCompare,3.2,, +function,PyObject_RichCompareBool,3.2,, +function,PyObject_SelfIter,3.2,, +function,PyObject_SetAttr,3.2,, +function,PyObject_SetAttrString,3.2,, +function,PyObject_SetItem,3.2,, +function,PyObject_Size,3.2,, +function,PyObject_Str,3.2,, +function,PyObject_Type,3.2,, +function,PyObject_Vectorcall,3.12,, +function,PyObject_VectorcallMethod,3.12,, +var,PyProperty_Type,3.2,, +var,PyRangeIter_Type,3.2,, +var,PyRange_Type,3.2,, +var,PyReversed_Type,3.2,, +function,PySeqIter_New,3.2,, +var,PySeqIter_Type,3.2,, +function,PySequence_Check,3.2,, +function,PySequence_Concat,3.2,, +function,PySequence_Contains,3.2,, +function,PySequence_Count,3.2,, +function,PySequence_DelItem,3.2,, +function,PySequence_DelSlice,3.2,, +function,PySequence_Fast,3.2,, +function,PySequence_GetItem,3.2,, +function,PySequence_GetSlice,3.2,, +function,PySequence_In,3.2,, +function,PySequence_InPlaceConcat,3.2,, +function,PySequence_InPlaceRepeat,3.2,, +function,PySequence_Index,3.2,, +function,PySequence_Length,3.2,, +function,PySequence_List,3.2,, +function,PySequence_Repeat,3.2,, +function,PySequence_SetItem,3.2,, +function,PySequence_SetSlice,3.2,, +function,PySequence_Size,3.2,, +function,PySequence_Tuple,3.2,, +var,PySetIter_Type,3.2,, +function,PySet_Add,3.2,, +function,PySet_Clear,3.2,, +function,PySet_Contains,3.2,, +function,PySet_Discard,3.2,, +function,PySet_New,3.2,, +function,PySet_Pop,3.2,, +function,PySet_Size,3.2,, +var,PySet_Type,3.2,, +function,PySlice_AdjustIndices,3.7,, +function,PySlice_GetIndices,3.2,, +function,PySlice_GetIndicesEx,3.2,, +function,PySlice_New,3.2,, +var,PySlice_Type,3.2,, +function,PySlice_Unpack,3.7,, +function,PyState_AddModule,3.3,, +function,PyState_FindModule,3.2,, +function,PyState_RemoveModule,3.3,, +type,PyStructSequence_Desc,3.2,,full-abi +type,PyStructSequence_Field,3.2,,full-abi +function,PyStructSequence_GetItem,3.2,, +function,PyStructSequence_New,3.2,, +function,PyStructSequence_NewType,3.2,, +function,PyStructSequence_SetItem,3.2,, +var,PyStructSequence_UnnamedField,3.11,, +var,PySuper_Type,3.2,, +function,PySys_AddWarnOption,3.2,, +function,PySys_AddWarnOptionUnicode,3.2,, +function,PySys_AddXOption,3.7,, +function,PySys_FormatStderr,3.2,, +function,PySys_FormatStdout,3.2,, +function,PySys_GetObject,3.2,, +function,PySys_GetXOptions,3.7,, +function,PySys_HasWarnOptions,3.2,, +function,PySys_ResetWarnOptions,3.2,, +function,PySys_SetArgv,3.2,, +function,PySys_SetArgvEx,3.2,, +function,PySys_SetObject,3.2,, +function,PySys_SetPath,3.2,, +function,PySys_WriteStderr,3.2,, +function,PySys_WriteStdout,3.2,, +type,PyThreadState,3.2,,opaque +function,PyThreadState_Clear,3.2,, +function,PyThreadState_Delete,3.2,, +function,PyThreadState_Get,3.2,, +function,PyThreadState_GetDict,3.2,, +function,PyThreadState_GetFrame,3.10,, +function,PyThreadState_GetID,3.10,, +function,PyThreadState_GetInterpreter,3.10,, +function,PyThreadState_New,3.2,, +function,PyThreadState_SetAsyncExc,3.2,, +function,PyThreadState_Swap,3.2,, +function,PyThread_GetInfo,3.3,, +function,PyThread_ReInitTLS,3.2,, +function,PyThread_acquire_lock,3.2,, +function,PyThread_acquire_lock_timed,3.2,, +function,PyThread_allocate_lock,3.2,, +function,PyThread_create_key,3.2,, +function,PyThread_delete_key,3.2,, +function,PyThread_delete_key_value,3.2,, +function,PyThread_exit_thread,3.2,, +function,PyThread_free_lock,3.2,, +function,PyThread_get_key_value,3.2,, +function,PyThread_get_stacksize,3.2,, +function,PyThread_get_thread_ident,3.2,, +function,PyThread_get_thread_native_id,3.2,on platforms with native thread IDs, +function,PyThread_init_thread,3.2,, +function,PyThread_release_lock,3.2,, +function,PyThread_set_key_value,3.2,, +function,PyThread_set_stacksize,3.2,, +function,PyThread_start_new_thread,3.2,, +function,PyThread_tss_alloc,3.7,, +function,PyThread_tss_create,3.7,, +function,PyThread_tss_delete,3.7,, +function,PyThread_tss_free,3.7,, +function,PyThread_tss_get,3.7,, +function,PyThread_tss_is_created,3.7,, +function,PyThread_tss_set,3.7,, +function,PyTraceBack_Here,3.2,, +function,PyTraceBack_Print,3.2,, +var,PyTraceBack_Type,3.2,, +var,PyTupleIter_Type,3.2,, +function,PyTuple_GetItem,3.2,, +function,PyTuple_GetSlice,3.2,, +function,PyTuple_New,3.2,, +function,PyTuple_Pack,3.2,, +function,PyTuple_SetItem,3.2,, +function,PyTuple_Size,3.2,, +var,PyTuple_Type,3.2,, +type,PyTypeObject,3.2,,opaque +function,PyType_ClearCache,3.2,, +function,PyType_FromMetaclass,3.12,, +function,PyType_FromModuleAndSpec,3.10,, +function,PyType_FromSpec,3.2,, +function,PyType_FromSpecWithBases,3.3,, +function,PyType_GenericAlloc,3.2,, +function,PyType_GenericNew,3.2,, +function,PyType_GetFlags,3.2,, +function,PyType_GetModule,3.10,, +function,PyType_GetModuleState,3.10,, +function,PyType_GetName,3.11,, +function,PyType_GetQualName,3.11,, +function,PyType_GetSlot,3.4,, +function,PyType_IsSubtype,3.2,, +function,PyType_Modified,3.2,, +function,PyType_Ready,3.2,, +type,PyType_Slot,3.2,,full-abi +type,PyType_Spec,3.2,,full-abi +var,PyType_Type,3.2,, +function,PyUnicodeDecodeError_Create,3.2,, +function,PyUnicodeDecodeError_GetEncoding,3.2,, +function,PyUnicodeDecodeError_GetEnd,3.2,, +function,PyUnicodeDecodeError_GetObject,3.2,, +function,PyUnicodeDecodeError_GetReason,3.2,, +function,PyUnicodeDecodeError_GetStart,3.2,, +function,PyUnicodeDecodeError_SetEnd,3.2,, +function,PyUnicodeDecodeError_SetReason,3.2,, +function,PyUnicodeDecodeError_SetStart,3.2,, +function,PyUnicodeEncodeError_GetEncoding,3.2,, +function,PyUnicodeEncodeError_GetEnd,3.2,, +function,PyUnicodeEncodeError_GetObject,3.2,, +function,PyUnicodeEncodeError_GetReason,3.2,, +function,PyUnicodeEncodeError_GetStart,3.2,, +function,PyUnicodeEncodeError_SetEnd,3.2,, +function,PyUnicodeEncodeError_SetReason,3.2,, +function,PyUnicodeEncodeError_SetStart,3.2,, +var,PyUnicodeIter_Type,3.2,, +function,PyUnicodeTranslateError_GetEnd,3.2,, +function,PyUnicodeTranslateError_GetObject,3.2,, +function,PyUnicodeTranslateError_GetReason,3.2,, +function,PyUnicodeTranslateError_GetStart,3.2,, +function,PyUnicodeTranslateError_SetEnd,3.2,, +function,PyUnicodeTranslateError_SetReason,3.2,, +function,PyUnicodeTranslateError_SetStart,3.2,, +function,PyUnicode_Append,3.2,, +function,PyUnicode_AppendAndDel,3.2,, +function,PyUnicode_AsASCIIString,3.2,, +function,PyUnicode_AsCharmapString,3.2,, +function,PyUnicode_AsDecodedObject,3.2,, +function,PyUnicode_AsDecodedUnicode,3.2,, +function,PyUnicode_AsEncodedObject,3.2,, +function,PyUnicode_AsEncodedString,3.2,, +function,PyUnicode_AsEncodedUnicode,3.2,, +function,PyUnicode_AsLatin1String,3.2,, +function,PyUnicode_AsMBCSString,3.7,on Windows, +function,PyUnicode_AsRawUnicodeEscapeString,3.2,, +function,PyUnicode_AsUCS4,3.7,, +function,PyUnicode_AsUCS4Copy,3.7,, +function,PyUnicode_AsUTF16String,3.2,, +function,PyUnicode_AsUTF32String,3.2,, +function,PyUnicode_AsUTF8AndSize,3.10,, +function,PyUnicode_AsUTF8String,3.2,, +function,PyUnicode_AsUnicodeEscapeString,3.2,, +function,PyUnicode_AsWideChar,3.2,, +function,PyUnicode_AsWideCharString,3.7,, +function,PyUnicode_BuildEncodingMap,3.2,, +function,PyUnicode_Compare,3.2,, +function,PyUnicode_CompareWithASCIIString,3.2,, +function,PyUnicode_Concat,3.2,, +function,PyUnicode_Contains,3.2,, +function,PyUnicode_Count,3.2,, +function,PyUnicode_Decode,3.2,, +function,PyUnicode_DecodeASCII,3.2,, +function,PyUnicode_DecodeCharmap,3.2,, +function,PyUnicode_DecodeCodePageStateful,3.7,on Windows, +function,PyUnicode_DecodeFSDefault,3.2,, +function,PyUnicode_DecodeFSDefaultAndSize,3.2,, +function,PyUnicode_DecodeLatin1,3.2,, +function,PyUnicode_DecodeLocale,3.7,, +function,PyUnicode_DecodeLocaleAndSize,3.7,, +function,PyUnicode_DecodeMBCS,3.7,on Windows, +function,PyUnicode_DecodeMBCSStateful,3.7,on Windows, +function,PyUnicode_DecodeRawUnicodeEscape,3.2,, +function,PyUnicode_DecodeUTF16,3.2,, +function,PyUnicode_DecodeUTF16Stateful,3.2,, +function,PyUnicode_DecodeUTF32,3.2,, +function,PyUnicode_DecodeUTF32Stateful,3.2,, +function,PyUnicode_DecodeUTF7,3.2,, +function,PyUnicode_DecodeUTF7Stateful,3.2,, +function,PyUnicode_DecodeUTF8,3.2,, +function,PyUnicode_DecodeUTF8Stateful,3.2,, +function,PyUnicode_DecodeUnicodeEscape,3.2,, +function,PyUnicode_EncodeCodePage,3.7,on Windows, +function,PyUnicode_EncodeFSDefault,3.2,, +function,PyUnicode_EncodeLocale,3.7,, +function,PyUnicode_FSConverter,3.2,, +function,PyUnicode_FSDecoder,3.2,, +function,PyUnicode_Find,3.2,, +function,PyUnicode_FindChar,3.7,, +function,PyUnicode_Format,3.2,, +function,PyUnicode_FromEncodedObject,3.2,, +function,PyUnicode_FromFormat,3.2,, +function,PyUnicode_FromFormatV,3.2,, +function,PyUnicode_FromObject,3.2,, +function,PyUnicode_FromOrdinal,3.2,, +function,PyUnicode_FromString,3.2,, +function,PyUnicode_FromStringAndSize,3.2,, +function,PyUnicode_FromWideChar,3.2,, +function,PyUnicode_GetDefaultEncoding,3.2,, +function,PyUnicode_GetLength,3.7,, +function,PyUnicode_InternFromString,3.2,, +function,PyUnicode_InternInPlace,3.2,, +function,PyUnicode_IsIdentifier,3.2,, +function,PyUnicode_Join,3.2,, +function,PyUnicode_Partition,3.2,, +function,PyUnicode_RPartition,3.2,, +function,PyUnicode_RSplit,3.2,, +function,PyUnicode_ReadChar,3.7,, +function,PyUnicode_Replace,3.2,, +function,PyUnicode_Resize,3.2,, +function,PyUnicode_RichCompare,3.2,, +function,PyUnicode_Split,3.2,, +function,PyUnicode_Splitlines,3.2,, +function,PyUnicode_Substring,3.7,, +function,PyUnicode_Tailmatch,3.2,, +function,PyUnicode_Translate,3.2,, +var,PyUnicode_Type,3.2,, +function,PyUnicode_WriteChar,3.7,, +type,PyVarObject,3.2,,members +member,PyVarObject.ob_base,3.2,, +member,PyVarObject.ob_size,3.2,, +function,PyVectorcall_Call,3.12,, +function,PyVectorcall_NARGS,3.12,, +type,PyWeakReference,3.2,,opaque +function,PyWeakref_GetObject,3.2,, +function,PyWeakref_NewProxy,3.2,, +function,PyWeakref_NewRef,3.2,, +var,PyWrapperDescr_Type,3.2,, +function,PyWrapper_New,3.2,, +var,PyZip_Type,3.2,, +function,Py_AddPendingCall,3.2,, +function,Py_AtExit,3.2,, +macro,Py_BEGIN_ALLOW_THREADS,3.2,, +macro,Py_BLOCK_THREADS,3.2,, +function,Py_BuildValue,3.2,, +function,Py_BytesMain,3.8,, +function,Py_CompileString,3.2,, +function,Py_DecRef,3.2,, +function,Py_DecodeLocale,3.7,, +macro,Py_END_ALLOW_THREADS,3.2,, +function,Py_EncodeLocale,3.7,, +function,Py_EndInterpreter,3.2,, +function,Py_EnterRecursiveCall,3.9,, +function,Py_Exit,3.2,, +function,Py_FatalError,3.2,, +var,Py_FileSystemDefaultEncodeErrors,3.10,, +var,Py_FileSystemDefaultEncoding,3.2,, +function,Py_Finalize,3.2,, +function,Py_FinalizeEx,3.6,, +function,Py_GenericAlias,3.9,, +var,Py_GenericAliasType,3.9,, +function,Py_GetBuildInfo,3.2,, +function,Py_GetCompiler,3.2,, +function,Py_GetCopyright,3.2,, +function,Py_GetExecPrefix,3.2,, +function,Py_GetPath,3.2,, +function,Py_GetPlatform,3.2,, +function,Py_GetPrefix,3.2,, +function,Py_GetProgramFullPath,3.2,, +function,Py_GetProgramName,3.2,, +function,Py_GetPythonHome,3.2,, +function,Py_GetRecursionLimit,3.2,, +function,Py_GetVersion,3.2,, +var,Py_HasFileSystemDefaultEncoding,3.2,, +function,Py_IncRef,3.2,, +function,Py_Initialize,3.2,, +function,Py_InitializeEx,3.2,, +function,Py_Is,3.10,, +function,Py_IsFalse,3.10,, +function,Py_IsInitialized,3.2,, +function,Py_IsNone,3.10,, +function,Py_IsTrue,3.10,, +function,Py_LeaveRecursiveCall,3.9,, +function,Py_Main,3.2,, +function,Py_MakePendingCalls,3.2,, +function,Py_NewInterpreter,3.2,, +function,Py_NewRef,3.10,, +function,Py_ReprEnter,3.2,, +function,Py_ReprLeave,3.2,, +function,Py_SetPath,3.7,, +function,Py_SetProgramName,3.2,, +function,Py_SetPythonHome,3.2,, +function,Py_SetRecursionLimit,3.2,, +type,Py_UCS4,3.2,, +macro,Py_UNBLOCK_THREADS,3.2,, +var,Py_UTF8Mode,3.8,, +function,Py_VaBuildValue,3.2,, +var,Py_Version,3.11,, +function,Py_XNewRef,3.10,, +type,Py_buffer,3.11,,full-abi +type,Py_intptr_t,3.2,, +type,Py_ssize_t,3.2,, +type,Py_uintptr_t,3.2,, +type,allocfunc,3.2,, +type,binaryfunc,3.2,, +type,descrgetfunc,3.2,, +type,descrsetfunc,3.2,, +type,destructor,3.2,, +type,getattrfunc,3.2,, +type,getattrofunc,3.2,, +type,getbufferproc,3.12,, +type,getiterfunc,3.2,, +type,getter,3.2,, +type,hashfunc,3.2,, +type,initproc,3.2,, +type,inquiry,3.2,, +type,iternextfunc,3.2,, +type,lenfunc,3.2,, +type,newfunc,3.2,, +type,objobjargproc,3.2,, +type,objobjproc,3.2,, +type,releasebufferproc,3.12,, +type,reprfunc,3.2,, +type,richcmpfunc,3.2,, +type,setattrfunc,3.2,, +type,setattrofunc,3.2,, +type,setter,3.2,, +type,ssizeargfunc,3.2,, +type,ssizeobjargproc,3.2,, +type,ssizessizeargfunc,3.2,, +type,ssizessizeobjargproc,3.2,, +type,symtable,3.2,,opaque +type,ternaryfunc,3.2,, +type,traverseproc,3.2,, +type,unaryfunc,3.2,, +type,vectorcallfunc,3.12,, +type,visitproc,3.2,, diff --git a/Doc/distributing/index.rst b/Doc/distributing/index.rst index 136cf4e77b1..2ae2726d4e4 100644 --- a/Doc/distributing/index.rst +++ b/Doc/distributing/index.rst @@ -41,21 +41,21 @@ Key terms file format standards. They maintain a variety of tools, documentation and issue trackers on both `GitHub <https://github.com/pypa>`__ and `Bitbucket <https://bitbucket.org/pypa/>`__. -* :mod:`distutils` is the original build and distribution system first added - to the Python standard library in 1998. While direct use of :mod:`distutils` +* ``distutils`` is the original build and distribution system first added + to the Python standard library in 1998. While direct use of ``distutils`` is being phased out, it still laid the foundation for the current packaging and distribution infrastructure, and it not only remains part of the standard library, but its name lives on in other ways (such as the name of the mailing list used to coordinate Python packaging standards development). -* `setuptools`_ is a (largely) drop-in replacement for :mod:`distutils` first +* `setuptools`_ is a (largely) drop-in replacement for ``distutils`` first published in 2004. Its most notable addition over the unmodified - :mod:`distutils` tools was the ability to declare dependencies on other + ``distutils`` tools was the ability to declare dependencies on other packages. It is currently recommended as a more regularly updated - alternative to :mod:`distutils` that offers consistent support for more + alternative to ``distutils`` that offers consistent support for more recent packaging standards across a wide range of Python versions. * `wheel`_ (in this context) is a project that adds the ``bdist_wheel`` - command to :mod:`distutils`/`setuptools`_. This produces a cross platform + command to ``distutils``/`setuptools`_. This produces a cross platform binary packaging format (called "wheels" or "wheel files" and defined in :pep:`427`) that allows Python libraries, even those including binary extensions, to be installed on a system without needing to be built diff --git a/Doc/distutils/_setuptools_disclaimer.rst b/Doc/distutils/_setuptools_disclaimer.rst deleted file mode 100644 index cc75858326d..00000000000 --- a/Doc/distutils/_setuptools_disclaimer.rst +++ /dev/null @@ -1,5 +0,0 @@ -.. note:: - - This document is being retained solely until the ``setuptools`` documentation - at https://setuptools.readthedocs.io/en/latest/setuptools.html - independently covers all of the relevant information currently included here. diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst deleted file mode 100644 index 18a4aac4f70..00000000000 --- a/Doc/distutils/apiref.rst +++ /dev/null @@ -1,2041 +0,0 @@ -.. _api-reference: - -************* -API Reference -************* - -.. seealso:: - - `New and changed setup.py arguments in setuptools`_ - The ``setuptools`` project adds new capabilities to the ``setup`` function - and other APIs, makes the API consistent across different Python versions, - and is hence recommended over using ``distutils`` directly. - -.. _New and changed setup.py arguments in setuptools: https://setuptools.readthedocs.io/en/latest/setuptools.html#new-and-changed-setup-keywords - -.. include:: ./_setuptools_disclaimer.rst - -:mod:`distutils.core` --- Core Distutils functionality -====================================================== - -.. module:: distutils.core - :synopsis: The core Distutils functionality - - -The :mod:`distutils.core` module is the only module that needs to be installed -to use the Distutils. It provides the :func:`setup` (which is called from the -setup script). Indirectly provides the :class:`distutils.dist.Distribution` and -:class:`distutils.cmd.Command` class. - - -.. function:: setup(arguments) - - The basic do-everything function that does most everything you could ever ask - for from a Distutils method. - - The setup function takes a large number of arguments. These are laid out in the - following table. - - .. tabularcolumns:: |l|L|L| - - +--------------------+--------------------------------+-------------------------------------------------------------+ - | argument name | value | type | - +====================+================================+=============================================================+ - | *name* | The name of the package | a string | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *version* | The version number of the | a string | - | | package; see | | - | | :mod:`distutils.version` | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *description* | A single line describing the | a string | - | | package | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *long_description* | Longer description of the | a string | - | | package | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *author* | The name of the package author | a string | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *author_email* | The email address of the | a string | - | | package author | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *maintainer* | The name of the current | a string | - | | maintainer, if different from | | - | | the author. Note that if | | - | | the maintainer is provided, | | - | | distutils will use it as the | | - | | author in :file:`PKG-INFO` | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *maintainer_email* | The email address of the | a string | - | | current maintainer, if | | - | | different from the author | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *url* | A URL for the package | a string | - | | (homepage) | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *download_url* | A URL to download the package | a string | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *packages* | A list of Python packages that | a list of strings | - | | distutils will manipulate | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *py_modules* | A list of Python modules that | a list of strings | - | | distutils will manipulate | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *scripts* | A list of standalone script | a list of strings | - | | files to be built and | | - | | installed | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *ext_modules* | A list of Python extensions to | a list of instances of | - | | be built | :class:`distutils.core.Extension` | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *classifiers* | A list of categories for the | a list of strings; valid classifiers are listed on `PyPI | - | | package | <https://pypi.org/classifiers>`_. | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *distclass* | the :class:`Distribution` | a subclass of | - | | class to use | :class:`distutils.core.Distribution` | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *script_name* | The name of the setup.py | a string | - | | script - defaults to | | - | | ``sys.argv[0]`` | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *script_args* | Arguments to supply to the | a list of strings | - | | setup script | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *options* | default options for the setup | a dictionary | - | | script | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *license* | The license for the package | a string | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *keywords* | Descriptive meta-data, see | a list of strings or a comma-separated string | - | | :pep:`314` | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *platforms* | | a list of strings or a comma-separated string | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *cmdclass* | A mapping of command names to | a dictionary | - | | :class:`Command` subclasses | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *data_files* | A list of data files to | a list | - | | install | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *package_dir* | A mapping of package to | a dictionary | - | | directory names | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - - - -.. function:: run_setup(script_name[, script_args=None, stop_after='run']) - - Run a setup script in a somewhat controlled environment, and return the - :class:`distutils.dist.Distribution` instance that drives things. This is - useful if you need to find out the distribution meta-data (passed as keyword - args from *script* to :func:`setup`), or the contents of the config files or - command-line. - - *script_name* is a file that will be read and run with :func:`exec`. ``sys.argv[0]`` - will be replaced with *script* for the duration of the call. *script_args* is a - list of strings; if supplied, ``sys.argv[1:]`` will be replaced by *script_args* - for the duration of the call. - - *stop_after* tells :func:`setup` when to stop processing; possible values: - - .. tabularcolumns:: |l|L| - - +---------------+---------------------------------------------+ - | value | description | - +===============+=============================================+ - | *init* | Stop after the :class:`Distribution` | - | | instance has been created and populated | - | | with the keyword arguments to :func:`setup` | - +---------------+---------------------------------------------+ - | *config* | Stop after config files have been parsed | - | | (and their data stored in the | - | | :class:`Distribution` instance) | - +---------------+---------------------------------------------+ - | *commandline* | Stop after the command-line | - | | (``sys.argv[1:]`` or *script_args*) have | - | | been parsed (and the data stored in the | - | | :class:`Distribution` instance.) | - +---------------+---------------------------------------------+ - | *run* | Stop after all commands have been run (the | - | | same as if :func:`setup` had been called | - | | in the usual way). This is the default | - | | value. | - +---------------+---------------------------------------------+ - -In addition, the :mod:`distutils.core` module exposed a number of classes that -live elsewhere. - -* :class:`~distutils.extension.Extension` from :mod:`distutils.extension` - -* :class:`~distutils.cmd.Command` from :mod:`distutils.cmd` - -* :class:`~distutils.dist.Distribution` from :mod:`distutils.dist` - -A short description of each of these follows, but see the relevant module for -the full reference. - - -.. class:: Extension - - The Extension class describes a single C or C++ extension module in a setup - script. It accepts the following keyword arguments in its constructor: - - .. tabularcolumns:: |l|L|l| - - +------------------------+--------------------------------+---------------------------+ - | argument name | value | type | - +========================+================================+===========================+ - | *name* | the full name of the | a string | - | | extension, including any | | - | | packages --- ie. *not* a | | - | | filename or pathname, but | | - | | Python dotted name | | - +------------------------+--------------------------------+---------------------------+ - | *sources* | list of source filenames, | a list of strings | - | | relative to the distribution | | - | | root (where the setup script | | - | | lives), in Unix form | | - | | (slash-separated) for | | - | | portability. | | - | | Source files may be C, C++, | | - | | SWIG (.i), platform-specific | | - | | resource files, or whatever | | - | | else is recognized by the | | - | | :command:`build_ext` command | | - | | as source for a Python | | - | | extension. | | - +------------------------+--------------------------------+---------------------------+ - | *include_dirs* | list of directories to search | a list of strings | - | | for C/C++ header files (in | | - | | Unix form for portability) | | - +------------------------+--------------------------------+---------------------------+ - | *define_macros* | list of macros to define; each | a list of tuples | - | | macro is defined using a | | - | | 2-tuple ``(name, value)``, | | - | | where *value* is | | - | | either the string to define it | | - | | to or ``None`` to define it | | - | | without a particular value | | - | | (equivalent of ``#define FOO`` | | - | | in source or :option:`!-DFOO` | | - | | on Unix C compiler command | | - | | line) | | - +------------------------+--------------------------------+---------------------------+ - | *undef_macros* | list of macros to undefine | a list of strings | - | | explicitly | | - +------------------------+--------------------------------+---------------------------+ - | *library_dirs* | list of directories to search | a list of strings | - | | for C/C++ libraries at link | | - | | time | | - +------------------------+--------------------------------+---------------------------+ - | *libraries* | list of library names (not | a list of strings | - | | filenames or paths) to link | | - | | against | | - +------------------------+--------------------------------+---------------------------+ - | *runtime_library_dirs* | list of directories to search | a list of strings | - | | for C/C++ libraries at run | | - | | time (for shared extensions, | | - | | this is when the extension is | | - | | loaded) | | - +------------------------+--------------------------------+---------------------------+ - | *extra_objects* | list of extra files to link | a list of strings | - | | with (eg. object files not | | - | | implied by 'sources', static | | - | | library that must be | | - | | explicitly specified, binary | | - | | resource files, etc.) | | - +------------------------+--------------------------------+---------------------------+ - | *extra_compile_args* | any extra platform- and | a list of strings | - | | compiler-specific information | | - | | to use when compiling the | | - | | source files in 'sources'. For | | - | | platforms and compilers where | | - | | a command line makes sense, | | - | | this is typically a list of | | - | | command-line arguments, but | | - | | for other platforms it could | | - | | be anything. | | - +------------------------+--------------------------------+---------------------------+ - | *extra_link_args* | any extra platform- and | a list of strings | - | | compiler-specific information | | - | | to use when linking object | | - | | files together to create the | | - | | extension (or to create a new | | - | | static Python interpreter). | | - | | Similar interpretation as for | | - | | 'extra_compile_args'. | | - +------------------------+--------------------------------+---------------------------+ - | *export_symbols* | list of symbols to be exported | a list of strings | - | | from a shared extension. Not | | - | | used on all platforms, and not | | - | | generally necessary for Python | | - | | extensions, which typically | | - | | export exactly one symbol: | | - | | ``init`` + extension_name. | | - +------------------------+--------------------------------+---------------------------+ - | *depends* | list of files that the | a list of strings | - | | extension depends on | | - +------------------------+--------------------------------+---------------------------+ - | *language* | extension language (i.e. | a string | - | | ``'c'``, ``'c++'``, | | - | | ``'objc'``). Will be detected | | - | | from the source extensions if | | - | | not provided. | | - +------------------------+--------------------------------+---------------------------+ - | *optional* | specifies that a build failure | a boolean | - | | in the extension should not | | - | | abort the build process, but | | - | | simply skip the extension. | | - +------------------------+--------------------------------+---------------------------+ - - .. versionchanged:: 3.8 - - On Unix, C extensions are no longer linked to libpython except on - Android and Cygwin. - - -.. class:: Distribution - - A :class:`Distribution` describes how to build, install and package up a Python - software package. - - See the :func:`setup` function for a list of keyword arguments accepted by the - Distribution constructor. :func:`setup` creates a Distribution instance. - - .. versionchanged:: 3.7 - :class:`~distutils.core.Distribution` now warns if ``classifiers``, - ``keywords`` and ``platforms`` fields are not specified as a list or - a string. - -.. class:: Command - - A :class:`Command` class (or rather, an instance of one of its subclasses) - implement a single distutils command. - - -:mod:`distutils.ccompiler` --- CCompiler base class -=================================================== - -.. module:: distutils.ccompiler - :synopsis: Abstract CCompiler class - - -This module provides the abstract base class for the :class:`CCompiler` -classes. A :class:`CCompiler` instance can be used for all the compile and -link steps needed to build a single project. Methods are provided to set -options for the compiler --- macro definitions, include directories, link path, -libraries and the like. - -This module provides the following functions. - - -.. function:: gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries) - - Generate linker options for searching library directories and linking with - specific libraries. *libraries* and *library_dirs* are, respectively, lists of - library names (not filenames!) and search directories. Returns a list of - command-line options suitable for use with some compiler (depending on the two - format strings passed in). - - -.. function:: gen_preprocess_options(macros, include_dirs) - - Generate C pre-processor options (:option:`!-D`, :option:`!-U`, :option:`!-I`) as - used by at least two types of compilers: the typical Unix compiler and Visual - C++. *macros* is the usual thing, a list of 1- or 2-tuples, where ``(name,)`` - means undefine (:option:`!-U`) macro *name*, and ``(name, value)`` means define - (:option:`!-D`) macro *name* to *value*. *include_dirs* is just a list of - directory names to be added to the header file search path (:option:`!-I`). - Returns a list of command-line options suitable for either Unix compilers or - Visual C++. - - -.. function:: get_default_compiler(osname, platform) - - Determine the default compiler to use for the given platform. - - *osname* should be one of the standard Python OS names (i.e. the ones returned - by ``os.name``) and *platform* the common value returned by ``sys.platform`` for - the platform in question. - - The default values are ``os.name`` and ``sys.platform`` in case the parameters - are not given. - - -.. function:: new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0) - - Factory function to generate an instance of some CCompiler subclass for the - supplied platform/compiler combination. *plat* defaults to ``os.name`` (eg. - ``'posix'``, ``'nt'``), and *compiler* defaults to the default compiler for - that platform. Currently only ``'posix'`` and ``'nt'`` are supported, and the - default compilers are "traditional Unix interface" (:class:`UnixCCompiler` - class) and Visual C++ (:class:`MSVCCompiler` class). Note that it's perfectly - possible to ask for a Unix compiler object under Windows, and a Microsoft - compiler object under Unix---if you supply a value for *compiler*, *plat* is - ignored. - - .. % Is the posix/nt only thing still true? macOS seems to work, and - .. % returns a UnixCCompiler instance. How to document this... hmm. - - -.. function:: show_compilers() - - Print list of available compilers (used by the :option:`!--help-compiler` options - to :command:`build`, :command:`build_ext`, :command:`build_clib`). - - -.. class:: CCompiler([verbose=0, dry_run=0, force=0]) - - The abstract base class :class:`CCompiler` defines the interface that must be - implemented by real compiler classes. The class also has some utility methods - used by several compiler classes. - - The basic idea behind a compiler abstraction class is that each instance can be - used for all the compile/link steps in building a single project. Thus, - attributes common to all of those compile and link steps --- include - directories, macros to define, libraries to link against, etc. --- are - attributes of the compiler instance. To allow for variability in how individual - files are treated, most of those attributes may be varied on a per-compilation - or per-link basis. - - The constructor for each subclass creates an instance of the Compiler object. - Flags are *verbose* (show verbose output), *dry_run* (don't actually execute the - steps) and *force* (rebuild everything, regardless of dependencies). All of - these flags default to ``0`` (off). Note that you probably don't want to - instantiate :class:`CCompiler` or one of its subclasses directly - use the - :func:`distutils.CCompiler.new_compiler` factory function instead. - - The following methods allow you to manually alter compiler options for the - instance of the Compiler class. - - - .. method:: CCompiler.add_include_dir(dir) - - Add *dir* to the list of directories that will be searched for header files. - The compiler is instructed to search directories in the order in which they are - supplied by successive calls to :meth:`add_include_dir`. - - - .. method:: CCompiler.set_include_dirs(dirs) - - Set the list of directories that will be searched to *dirs* (a list of strings). - Overrides any preceding calls to :meth:`add_include_dir`; subsequent calls to - :meth:`add_include_dir` add to the list passed to :meth:`set_include_dirs`. - This does not affect any list of standard include directories that the compiler - may search by default. - - - .. method:: CCompiler.add_library(libname) - - Add *libname* to the list of libraries that will be included in all links driven - by this compiler object. Note that *libname* should \*not\* be the name of a - file containing a library, but the name of the library itself: the actual - filename will be inferred by the linker, the compiler, or the compiler class - (depending on the platform). - - The linker will be instructed to link against libraries in the order they were - supplied to :meth:`add_library` and/or :meth:`set_libraries`. It is perfectly - valid to duplicate library names; the linker will be instructed to link against - libraries as many times as they are mentioned. - - - .. method:: CCompiler.set_libraries(libnames) - - Set the list of libraries to be included in all links driven by this compiler - object to *libnames* (a list of strings). This does not affect any standard - system libraries that the linker may include by default. - - - .. method:: CCompiler.add_library_dir(dir) - - Add *dir* to the list of directories that will be searched for libraries - specified to :meth:`add_library` and :meth:`set_libraries`. The linker will be - instructed to search for libraries in the order they are supplied to - :meth:`add_library_dir` and/or :meth:`set_library_dirs`. - - - .. method:: CCompiler.set_library_dirs(dirs) - - Set the list of library search directories to *dirs* (a list of strings). This - does not affect any standard library search path that the linker may search by - default. - - - .. method:: CCompiler.add_runtime_library_dir(dir) - - Add *dir* to the list of directories that will be searched for shared libraries - at runtime. - - - .. method:: CCompiler.set_runtime_library_dirs(dirs) - - Set the list of directories to search for shared libraries at runtime to *dirs* - (a list of strings). This does not affect any standard search path that the - runtime linker may search by default. - - - .. method:: CCompiler.define_macro(name[, value=None]) - - Define a preprocessor macro for all compilations driven by this compiler object. - The optional parameter *value* should be a string; if it is not supplied, then - the macro will be defined without an explicit value and the exact outcome - depends on the compiler used. - - .. XXX true? does ANSI say anything about this? - - - .. method:: CCompiler.undefine_macro(name) - - Undefine a preprocessor macro for all compilations driven by this compiler - object. If the same macro is defined by :meth:`define_macro` and - undefined by :meth:`undefine_macro` the last call takes precedence - (including multiple redefinitions or undefinitions). If the macro is - redefined/undefined on a per-compilation basis (ie. in the call to - :meth:`compile`), then that takes precedence. - - - .. method:: CCompiler.add_link_object(object) - - Add *object* to the list of object files (or analogues, such as explicitly named - library files or the output of "resource compilers") to be included in every - link driven by this compiler object. - - - .. method:: CCompiler.set_link_objects(objects) - - Set the list of object files (or analogues) to be included in every link to - *objects*. This does not affect any standard object files that the linker may - include by default (such as system libraries). - - The following methods implement methods for autodetection of compiler options, - providing some functionality similar to GNU :program:`autoconf`. - - - .. method:: CCompiler.detect_language(sources) - - Detect the language of a given file, or list of files. Uses the instance - attributes :attr:`language_map` (a dictionary), and :attr:`language_order` (a - list) to do the job. - - - .. method:: CCompiler.find_library_file(dirs, lib[, debug=0]) - - Search the specified list of directories for a static or shared library file - *lib* and return the full path to that file. If *debug* is true, look for a - debugging version (if that makes sense on the current platform). Return - ``None`` if *lib* wasn't found in any of the specified directories. - - - .. method:: CCompiler.has_function(funcname [, includes=None, include_dirs=None, libraries=None, library_dirs=None]) - - Return a boolean indicating whether *funcname* is supported on the current - platform. The optional arguments can be used to augment the compilation - environment by providing additional include files and paths and libraries and - paths. - - - .. method:: CCompiler.library_dir_option(dir) - - Return the compiler option to add *dir* to the list of directories searched for - libraries. - - - .. method:: CCompiler.library_option(lib) - - Return the compiler option to add *lib* to the list of libraries linked into the - shared library or executable. - - - .. method:: CCompiler.runtime_library_dir_option(dir) - - Return the compiler option to add *dir* to the list of directories searched for - runtime libraries. - - - .. method:: CCompiler.set_executables(**args) - - Define the executables (and options for them) that will be run to perform the - various stages of compilation. The exact set of executables that may be - specified here depends on the compiler class (via the 'executables' class - attribute), but most will have: - - +--------------+------------------------------------------+ - | attribute | description | - +==============+==========================================+ - | *compiler* | the C/C++ compiler | - +--------------+------------------------------------------+ - | *linker_so* | linker used to create shared objects and | - | | libraries | - +--------------+------------------------------------------+ - | *linker_exe* | linker used to create binary executables | - +--------------+------------------------------------------+ - | *archiver* | static library creator | - +--------------+------------------------------------------+ - - On platforms with a command-line (Unix, DOS/Windows), each of these is a string - that will be split into executable name and (optional) list of arguments. - (Splitting the string is done similarly to how Unix shells operate: words are - delimited by spaces, but quotes and backslashes can override this. See - :func:`distutils.util.split_quoted`.) - - The following methods invoke stages in the build process. - - - .. method:: CCompiler.compile(sources[, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None]) - - Compile one or more source files. Generates object files (e.g. transforms a - :file:`.c` file to a :file:`.o` file.) - - *sources* must be a list of filenames, most likely C/C++ files, but in reality - anything that can be handled by a particular compiler and compiler class (eg. - :class:`MSVCCompiler` can handle resource files in *sources*). Return a list of - object filenames, one per source filename in *sources*. Depending on the - implementation, not all source files will necessarily be compiled, but all - corresponding object filenames will be returned. - - If *output_dir* is given, object files will be put under it, while retaining - their original path component. That is, :file:`foo/bar.c` normally compiles to - :file:`foo/bar.o` (for a Unix implementation); if *output_dir* is *build*, then - it would compile to :file:`build/foo/bar.o`. - - *macros*, if given, must be a list of macro definitions. A macro definition is - either a ``(name, value)`` 2-tuple or a ``(name,)`` 1-tuple. The former defines - a macro; if the value is ``None``, the macro is defined without an explicit - value. The 1-tuple case undefines a macro. Later - definitions/redefinitions/undefinitions take precedence. - - *include_dirs*, if given, must be a list of strings, the directories to add to - the default include file search path for this compilation only. - - *debug* is a boolean; if true, the compiler will be instructed to output debug - symbols in (or alongside) the object file(s). - - *extra_preargs* and *extra_postargs* are implementation-dependent. On platforms - that have the notion of a command-line (e.g. Unix, DOS/Windows), they are most - likely lists of strings: extra command-line arguments to prepend/append to the - compiler command line. On other platforms, consult the implementation class - documentation. In any event, they are intended as an escape hatch for those - occasions when the abstract compiler framework doesn't cut the mustard. - - *depends*, if given, is a list of filenames that all targets depend on. If a - source file is older than any file in depends, then the source file will be - recompiled. This supports dependency tracking, but only at a coarse - granularity. - - Raises :exc:`CompileError` on failure. - - - .. method:: CCompiler.create_static_lib(objects, output_libname[, output_dir=None, debug=0, target_lang=None]) - - Link a bunch of stuff together to create a static library file. The "bunch of - stuff" consists of the list of object files supplied as *objects*, the extra - object files supplied to :meth:`add_link_object` and/or - :meth:`set_link_objects`, the libraries supplied to :meth:`add_library` and/or - :meth:`set_libraries`, and the libraries supplied as *libraries* (if any). - - *output_libname* should be a library name, not a filename; the filename will be - inferred from the library name. *output_dir* is the directory where the library - file will be put. - - .. XXX defaults to what? - - *debug* is a boolean; if true, debugging information will be included in the - library (note that on most platforms, it is the compile step where this matters: - the *debug* flag is included here just for consistency). - - *target_lang* is the target language for which the given objects are being - compiled. This allows specific linkage time treatment of certain languages. - - Raises :exc:`LibError` on failure. - - - .. method:: CCompiler.link(target_desc, objects, output_filename[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None]) - - Link a bunch of stuff together to create an executable or shared library file. - - The "bunch of stuff" consists of the list of object files supplied as *objects*. - *output_filename* should be a filename. If *output_dir* is supplied, - *output_filename* is relative to it (i.e. *output_filename* can provide - directory components if needed). - - *libraries* is a list of libraries to link against. These are library names, - not filenames, since they're translated into filenames in a platform-specific - way (eg. *foo* becomes :file:`libfoo.a` on Unix and :file:`foo.lib` on - DOS/Windows). However, they can include a directory component, which means the - linker will look in that specific directory rather than searching all the normal - locations. - - *library_dirs*, if supplied, should be a list of directories to search for - libraries that were specified as bare library names (ie. no directory - component). These are on top of the system default and those supplied to - :meth:`add_library_dir` and/or :meth:`set_library_dirs`. *runtime_library_dirs* - is a list of directories that will be embedded into the shared library and used - to search for other shared libraries that \*it\* depends on at run-time. (This - may only be relevant on Unix.) - - *export_symbols* is a list of symbols that the shared library will export. - (This appears to be relevant only on Windows.) - - *debug* is as for :meth:`compile` and :meth:`create_static_lib`, with the - slight distinction that it actually matters on most platforms (as opposed to - :meth:`create_static_lib`, which includes a *debug* flag mostly for form's - sake). - - *extra_preargs* and *extra_postargs* are as for :meth:`compile` (except of - course that they supply command-line arguments for the particular linker being - used). - - *target_lang* is the target language for which the given objects are being - compiled. This allows specific linkage time treatment of certain languages. - - Raises :exc:`LinkError` on failure. - - - .. method:: CCompiler.link_executable(objects, output_progname[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, target_lang=None]) - - Link an executable. *output_progname* is the name of the file executable, while - *objects* are a list of object filenames to link in. Other arguments are as for - the :meth:`link` method. - - - .. method:: CCompiler.link_shared_lib(objects, output_libname[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None]) - - Link a shared library. *output_libname* is the name of the output library, - while *objects* is a list of object filenames to link in. Other arguments are - as for the :meth:`link` method. - - - .. method:: CCompiler.link_shared_object(objects, output_filename[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None]) - - Link a shared object. *output_filename* is the name of the shared object that - will be created, while *objects* is a list of object filenames to link in. - Other arguments are as for the :meth:`link` method. - - - .. method:: CCompiler.preprocess(source[, output_file=None, macros=None, include_dirs=None, extra_preargs=None, extra_postargs=None]) - - Preprocess a single C/C++ source file, named in *source*. Output will be written - to file named *output_file*, or *stdout* if *output_file* not supplied. - *macros* is a list of macro definitions as for :meth:`compile`, which will - augment the macros set with :meth:`define_macro` and :meth:`undefine_macro`. - *include_dirs* is a list of directory names that will be added to the default - list, in the same way as :meth:`add_include_dir`. - - Raises :exc:`PreprocessError` on failure. - - The following utility methods are defined by the :class:`CCompiler` class, for - use by the various concrete subclasses. - - - .. method:: CCompiler.executable_filename(basename[, strip_dir=0, output_dir='']) - - Returns the filename of the executable for the given *basename*. Typically for - non-Windows platforms this is the same as the basename, while Windows will get - a :file:`.exe` added. - - - .. method:: CCompiler.library_filename(libname[, lib_type='static', strip_dir=0, output_dir='']) - - Returns the filename for the given library name on the current platform. On Unix - a library with *lib_type* of ``'static'`` will typically be of the form - :file:`liblibname.a`, while a *lib_type* of ``'dynamic'`` will be of the form - :file:`liblibname.so`. - - - .. method:: CCompiler.object_filenames(source_filenames[, strip_dir=0, output_dir='']) - - Returns the name of the object files for the given source files. - *source_filenames* should be a list of filenames. - - - .. method:: CCompiler.shared_object_filename(basename[, strip_dir=0, output_dir='']) - - Returns the name of a shared object file for the given file name *basename*. - - - .. method:: CCompiler.execute(func, args[, msg=None, level=1]) - - Invokes :func:`distutils.util.execute`. This method invokes a Python function - *func* with the given arguments *args*, after logging and taking into account - the *dry_run* flag. - - - .. method:: CCompiler.spawn(cmd) - - Invokes :func:`distutils.util.spawn`. This invokes an external process to run - the given command. - - - .. method:: CCompiler.mkpath(name[, mode=511]) - - Invokes :func:`distutils.dir_util.mkpath`. This creates a directory and any - missing ancestor directories. - - - .. method:: CCompiler.move_file(src, dst) - - Invokes :meth:`distutils.file_util.move_file`. Renames *src* to *dst*. - - - .. method:: CCompiler.announce(msg[, level=1]) - - Write a message using :func:`distutils.log.debug`. - - - .. method:: CCompiler.warn(msg) - - Write a warning message *msg* to standard error. - - - .. method:: CCompiler.debug_print(msg) - - If the *debug* flag is set on this :class:`CCompiler` instance, print *msg* to - standard output, otherwise do nothing. - -.. % \subsection{Compiler-specific modules} -.. % -.. % The following modules implement concrete subclasses of the abstract -.. % \class{CCompiler} class. They should not be instantiated directly, but should -.. % be created using \function{distutils.ccompiler.new_compiler()} factory -.. % function. - - -:mod:`distutils.unixccompiler` --- Unix C Compiler -================================================== - -.. module:: distutils.unixccompiler - :synopsis: UNIX C Compiler - - -This module provides the :class:`UnixCCompiler` class, a subclass of -:class:`CCompiler` that handles the typical Unix-style command-line C compiler: - -* macros defined with :option:`!-Dname[=value]` - -* macros undefined with :option:`!-Uname` - -* include search directories specified with :option:`!-Idir` - -* libraries specified with :option:`!-llib` - -* library search directories specified with :option:`!-Ldir` - -* compile handled by :program:`cc` (or similar) executable with :option:`!-c` - option: compiles :file:`.c` to :file:`.o` - -* link static library handled by :program:`ar` command (possibly with - :program:`ranlib`) - -* link shared library handled by :program:`cc` :option:`!-shared` - - -:mod:`distutils.msvccompiler` --- Microsoft Compiler -==================================================== - -.. module:: distutils.msvccompiler - :synopsis: Microsoft Compiler - -.. XXX: This is *waaaaay* out of date! - -This module provides :class:`MSVCCompiler`, an implementation of the abstract -:class:`CCompiler` class for Microsoft Visual Studio. Typically, extension -modules need to be compiled with the same compiler that was used to compile -Python. For Python 2.3 and earlier, the compiler was Visual Studio 6. For Python -2.4 and 2.5, the compiler is Visual Studio .NET 2003. - -:class:`MSVCCompiler` will normally choose the right compiler, linker etc. on -its own. To override this choice, the environment variables *DISTUTILS_USE_SDK* -and *MSSdk* must be both set. *MSSdk* indicates that the current environment has -been setup by the SDK's ``SetEnv.Cmd`` script, or that the environment variables -had been registered when the SDK was installed; *DISTUTILS_USE_SDK* indicates -that the distutils user has made an explicit choice to override the compiler -selection by :class:`MSVCCompiler`. - - -:mod:`distutils.bcppcompiler` --- Borland Compiler -================================================== - -.. module:: distutils.bcppcompiler - - -This module provides :class:`BorlandCCompiler`, a subclass of the abstract -:class:`CCompiler` class for the Borland C++ compiler. - - -:mod:`distutils.cygwincompiler` --- Cygwin Compiler -=================================================== - -.. module:: distutils.cygwinccompiler - - -This module provides the :class:`CygwinCCompiler` class, a subclass of -:class:`UnixCCompiler` that handles the Cygwin port of the GNU C compiler to -Windows. It also contains the Mingw32CCompiler class which handles the mingw32 -port of GCC (same as cygwin in no-cygwin mode). - - -:mod:`distutils.archive_util` --- Archiving utilities -====================================================== - -.. module:: distutils.archive_util - :synopsis: Utility functions for creating archive files (tarballs, zip files, ...) - - -This module provides a few functions for creating archive files, such as -tarballs or zipfiles. - - -.. function:: make_archive(base_name, format[, root_dir=None, base_dir=None, verbose=0, dry_run=0]) - - Create an archive file (eg. ``zip`` or ``tar``). *base_name* is the name of - the file to create, minus any format-specific extension; *format* is the - archive format: one of ``zip``, ``tar``, ``gztar``, ``bztar``, ``xztar``, or - ``ztar``. *root_dir* is a directory that will be the root directory of the - archive; ie. we typically ``chdir`` into *root_dir* before creating the - archive. *base_dir* is the directory where we start archiving from; ie. - *base_dir* will be the common prefix of all files and directories in the - archive. *root_dir* and *base_dir* both default to the current directory. - Returns the name of the archive file. - - .. versionchanged:: 3.5 - Added support for the ``xztar`` format. - - -.. function:: make_tarball(base_name, base_dir[, compress='gzip', verbose=0, dry_run=0]) - - 'Create an (optional compressed) archive as a tar file from all files in and - under *base_dir*. *compress* must be ``'gzip'`` (the default), - ``'bzip2'``, ``'xz'``, ``'compress'``, or ``None``. For the ``'compress'`` - method the compression utility named by :program:`compress` must be on the - default program search path, so this is probably Unix-specific. The output - tar file will be named :file:`base_dir.tar`, possibly plus the appropriate - compression extension (``.gz``, ``.bz2``, ``.xz`` or ``.Z``). Return the - output filename. - - .. versionchanged:: 3.5 - Added support for the ``xz`` compression. - - -.. function:: make_zipfile(base_name, base_dir[, verbose=0, dry_run=0]) - - Create a zip file from all files in and under *base_dir*. The output zip file - will be named *base_name* + :file:`.zip`. Uses either the :mod:`zipfile` Python - module (if available) or the InfoZIP :file:`zip` utility (if installed and - found on the default search path). If neither tool is available, raises - :exc:`DistutilsExecError`. Returns the name of the output zip file. - - -:mod:`distutils.dep_util` --- Dependency checking -================================================= - -.. module:: distutils.dep_util - :synopsis: Utility functions for simple dependency checking - - -This module provides functions for performing simple, timestamp-based -dependency of files and groups of files; also, functions based entirely on such -timestamp dependency analysis. - - -.. function:: newer(source, target) - - Return true if *source* exists and is more recently modified than *target*, or - if *source* exists and *target* doesn't. Return false if both exist and *target* - is the same age or newer than *source*. Raise :exc:`DistutilsFileError` if - *source* does not exist. - - -.. function:: newer_pairwise(sources, targets) - - Walk two filename lists in parallel, testing if each source is newer than its - corresponding target. Return a pair of lists (*sources*, *targets*) where - source is newer than target, according to the semantics of :func:`newer`. - - .. % % equivalent to a listcomp... - - -.. function:: newer_group(sources, target[, missing='error']) - - Return true if *target* is out-of-date with respect to any file listed in - *sources*. In other words, if *target* exists and is newer than every file in - *sources*, return false; otherwise return true. *missing* controls what we do - when a source file is missing; the default (``'error'``) is to blow up with an - :exc:`OSError` from inside :func:`os.stat`; if it is ``'ignore'``, we silently - drop any missing source files; if it is ``'newer'``, any missing source files - make us assume that *target* is out-of-date (this is handy in "dry-run" mode: - it'll make you pretend to carry out commands that wouldn't work because inputs - are missing, but that doesn't matter because you're not actually going to run - the commands). - - -:mod:`distutils.dir_util` --- Directory tree operations -======================================================= - -.. module:: distutils.dir_util - :synopsis: Utility functions for operating on directories and directory trees - - -This module provides functions for operating on directories and trees of -directories. - - -.. function:: mkpath(name[, mode=0o777, verbose=0, dry_run=0]) - - Create a directory and any missing ancestor directories. If the directory - already exists (or if *name* is the empty string, which means the current - directory, which of course exists), then do nothing. Raise - :exc:`DistutilsFileError` if unable to create some directory along the way (eg. - some sub-path exists, but is a file rather than a directory). If *verbose* is - true, print a one-line summary of each mkdir to stdout. Return the list of - directories actually created. - - -.. function:: create_tree(base_dir, files[, mode=0o777, verbose=0, dry_run=0]) - - Create all the empty directories under *base_dir* needed to put *files* there. - *base_dir* is just the name of a directory which doesn't necessarily exist - yet; *files* is a list of filenames to be interpreted relative to *base_dir*. - *base_dir* + the directory portion of every file in *files* will be created if - it doesn't already exist. *mode*, *verbose* and *dry_run* flags are as for - :func:`mkpath`. - - -.. function:: copy_tree(src, dst[, preserve_mode=1, preserve_times=1, preserve_symlinks=0, update=0, verbose=0, dry_run=0]) - - Copy an entire directory tree *src* to a new location *dst*. Both *src* and - *dst* must be directory names. If *src* is not a directory, raise - :exc:`DistutilsFileError`. If *dst* does not exist, it is created with - :func:`mkpath`. The end result of the copy is that every file in *src* is - copied to *dst*, and directories under *src* are recursively copied to *dst*. - Return the list of files that were copied or might have been copied, using their - output name. The return value is unaffected by *update* or *dry_run*: it is - simply the list of all files under *src*, with the names changed to be under - *dst*. - - *preserve_mode* and *preserve_times* are the same as for - :func:`distutils.file_util.copy_file`; note that they only apply to - regular files, not to - directories. If *preserve_symlinks* is true, symlinks will be copied as - symlinks (on platforms that support them!); otherwise (the default), the - destination of the symlink will be copied. *update* and *verbose* are the same - as for :func:`copy_file`. - - Files in *src* that begin with :file:`.nfs` are skipped (more information on - these files is available in answer D2 of the `NFS FAQ page - <http://nfs.sourceforge.net/#section_d>`_). - - .. versionchanged:: 3.3.1 - NFS files are ignored. - -.. function:: remove_tree(directory[, verbose=0, dry_run=0]) - - Recursively remove *directory* and all files and directories underneath it. Any - errors are ignored (apart from being reported to ``sys.stdout`` if *verbose* is - true). - - -:mod:`distutils.file_util` --- Single file operations -===================================================== - -.. module:: distutils.file_util - :synopsis: Utility functions for operating on single files - - -This module contains some utility functions for operating on individual files. - - -.. function:: copy_file(src, dst[, preserve_mode=1, preserve_times=1, update=0, link=None, verbose=0, dry_run=0]) - - Copy file *src* to *dst*. If *dst* is a directory, then *src* is copied there - with the same name; otherwise, it must be a filename. (If the file exists, it - will be ruthlessly clobbered.) If *preserve_mode* is true (the default), the - file's mode (type and permission bits, or whatever is analogous on the - current platform) is copied. If *preserve_times* is true (the default), the - last-modified and last-access times are copied as well. If *update* is true, - *src* will only be copied if *dst* does not exist, or if *dst* does exist but - is older than *src*. - - *link* allows you to make hard links (using :func:`os.link`) or symbolic links - (using :func:`os.symlink`) instead of copying: set it to ``'hard'`` or - ``'sym'``; if it is ``None`` (the default), files are copied. Don't set *link* - on systems that don't support it: :func:`copy_file` doesn't check if hard or - symbolic linking is available. It uses :func:`_copy_file_contents` to copy file - contents. - - Return a tuple ``(dest_name, copied)``: *dest_name* is the actual name of the - output file, and *copied* is true if the file was copied (or would have been - copied, if *dry_run* true). - - .. % XXX if the destination file already exists, we clobber it if - .. % copying, but blow up if linking. Hmmm. And I don't know what - .. % macostools.copyfile() does. Should definitely be consistent, and - .. % should probably blow up if destination exists and we would be - .. % changing it (ie. it's not already a hard/soft link to src OR - .. % (not update) and (src newer than dst)). - - -.. function:: move_file(src, dst[, verbose, dry_run]) - - Move file *src* to *dst*. If *dst* is a directory, the file will be moved into - it with the same name; otherwise, *src* is just renamed to *dst*. Returns the - new full name of the file. - - .. warning:: - - Handles cross-device moves on Unix using :func:`copy_file`. What about - other systems? - - -.. function:: write_file(filename, contents) - - Create a file called *filename* and write *contents* (a sequence of strings - without line terminators) to it. - - -:mod:`distutils.util` --- Miscellaneous other utility functions -=============================================================== - -.. module:: distutils.util - :synopsis: Miscellaneous other utility functions - - -This module contains other assorted bits and pieces that don't fit into any -other utility module. - - -.. function:: get_platform() - - Return a string that identifies the current platform. This is used mainly to - distinguish platform-specific build directories and platform-specific built - distributions. Typically includes the OS name and version and the - architecture (as supplied by 'os.uname()'), although the exact information - included depends on the OS; e.g., on Linux, the kernel version isn't - particularly important. - - Examples of returned values: - - * ``linux-i586`` - * ``linux-alpha`` - * ``solaris-2.6-sun4u`` - - For non-POSIX platforms, currently just returns ``sys.platform``. - - For macOS systems the OS version reflects the minimal version on which - binaries will run (that is, the value of ``MACOSX_DEPLOYMENT_TARGET`` - during the build of Python), not the OS version of the current system. - - For universal binary builds on macOS the architecture value reflects - the universal binary status instead of the architecture of the current - processor. For 32-bit universal binaries the architecture is ``fat``, - for 64-bit universal binaries the architecture is ``fat64``, and - for 4-way universal binaries the architecture is ``universal``. Starting - from Python 2.7 and Python 3.2 the architecture ``fat3`` is used for - a 3-way universal build (ppc, i386, x86_64) and ``intel`` is used for - a universal build with the i386 and x86_64 architectures - - Examples of returned values on macOS: - - * ``macosx-10.3-ppc`` - - * ``macosx-10.3-fat`` - - * ``macosx-10.5-universal`` - - * ``macosx-10.6-intel`` - - For AIX, Python 3.9 and later return a string starting with "aix", followed - by additional fields (separated by ``'-'``) that represent the combined - values of AIX Version, Release and Technology Level (first field), Build Date - (second field), and bit-size (third field). Python 3.8 and earlier returned - only a single additional field with the AIX Version and Release. - - Examples of returned values on AIX: - - * ``aix-5307-0747-32`` # 32-bit build on AIX ``oslevel -s``: 5300-07-00-0000 - - * ``aix-7105-1731-64`` # 64-bit build on AIX ``oslevel -s``: 7100-05-01-1731 - - * ``aix-7.2`` # Legacy form reported in Python 3.8 and earlier - - .. versionchanged:: 3.9 - The AIX platform string format now also includes the technology level, - build date, and ABI bit-size. - - -.. function:: convert_path(pathname) - - Return 'pathname' as a name that will work on the native filesystem, i.e. split - it on '/' and put it back together again using the current directory separator. - Needed because filenames in the setup script are always supplied in Unix style, - and have to be converted to the local convention before we can actually use them - in the filesystem. Raises :exc:`ValueError` on non-Unix-ish systems if - *pathname* either starts or ends with a slash. - - -.. function:: change_root(new_root, pathname) - - Return *pathname* with *new_root* prepended. If *pathname* is relative, this is - equivalent to ``os.path.join(new_root,pathname)`` Otherwise, it requires making - *pathname* relative and then joining the two, which is tricky on DOS/Windows. - - -.. function:: check_environ() - - Ensure that 'os.environ' has all the environment variables we guarantee that - users can use in config files, command-line options, etc. Currently this - includes: - - * :envvar:`HOME` - user's home directory (Unix only) - * :envvar:`PLAT` - description of the current platform, including hardware and - OS (see :func:`get_platform`) - - -.. function:: subst_vars(s, local_vars) - - Perform shell/Perl-style variable substitution on *s*. Every occurrence of - ``$`` followed by a name is considered a variable, and variable is substituted - by the value found in the *local_vars* dictionary, or in ``os.environ`` if it's - not in *local_vars*. *os.environ* is first checked/augmented to guarantee that - it contains certain values: see :func:`check_environ`. Raise :exc:`ValueError` - for any variables not found in either *local_vars* or ``os.environ``. - - Note that this is not a fully-fledged string interpolation function. A valid - ``$variable`` can consist only of upper and lower case letters, numbers and an - underscore. No { } or ( ) style quoting is available. - - -.. function:: split_quoted(s) - - Split a string up according to Unix shell-like rules for quotes and backslashes. - In short: words are delimited by spaces, as long as those spaces are not escaped - by a backslash, or inside a quoted string. Single and double quotes are - equivalent, and the quote characters can be backslash-escaped. The backslash is - stripped from any two-character escape sequence, leaving only the escaped - character. The quote characters are stripped from any quoted string. Returns a - list of words. - - .. % Should probably be moved into the standard library. - - -.. function:: execute(func, args[, msg=None, verbose=0, dry_run=0]) - - Perform some action that affects the outside world (for instance, writing to the - filesystem). Such actions are special because they are disabled by the - *dry_run* flag. This method takes care of all that bureaucracy for you; all - you have to do is supply the function to call and an argument tuple for it (to - embody the "external action" being performed), and an optional message to print. - - -.. function:: strtobool(val) - - Convert a string representation of truth to true (1) or false (0). - - True values are ``y``, ``yes``, ``t``, ``true``, ``on`` and ``1``; false values - are ``n``, ``no``, ``f``, ``false``, ``off`` and ``0``. Raises - :exc:`ValueError` if *val* is anything else. - - -.. function:: byte_compile(py_files[, optimize=0, force=0, prefix=None, base_dir=None, verbose=1, dry_run=0, direct=None]) - - Byte-compile a collection of Python source files to :file:`.pyc` files in a - :file:`__pycache__` subdirectory (see :pep:`3147` and :pep:`488`). - *py_files* is a list of files to compile; any files that don't end in - :file:`.py` are silently skipped. *optimize* must be one of the following: - - * ``0`` - don't optimize - * ``1`` - normal optimization (like ``python -O``) - * ``2`` - extra optimization (like ``python -OO``) - - If *force* is true, all files are recompiled regardless of timestamps. - - The source filename encoded in each :term:`bytecode` file defaults to the filenames - listed in *py_files*; you can modify these with *prefix* and *basedir*. - *prefix* is a string that will be stripped off of each source filename, and - *base_dir* is a directory name that will be prepended (after *prefix* is - stripped). You can supply either or both (or neither) of *prefix* and - *base_dir*, as you wish. - - If *dry_run* is true, doesn't actually do anything that would affect the - filesystem. - - Byte-compilation is either done directly in this interpreter process with the - standard :mod:`py_compile` module, or indirectly by writing a temporary script - and executing it. Normally, you should let :func:`byte_compile` figure out to - use direct compilation or not (see the source for details). The *direct* flag - is used by the script generated in indirect mode; unless you know what you're - doing, leave it set to ``None``. - - .. versionchanged:: 3.2.3 - Create ``.pyc`` files with an :func:`import magic tag - <imp.get_tag>` in their name, in a :file:`__pycache__` subdirectory - instead of files without tag in the current directory. - - .. versionchanged:: 3.5 - Create ``.pyc`` files according to :pep:`488`. - - -.. function:: rfc822_escape(header) - - Return a version of *header* escaped for inclusion in an :rfc:`822` header, by - ensuring there are 8 spaces space after each newline. Note that it does no other - modification of the string. - - .. % this _can_ be replaced - -.. % \subsection{Distutils objects} - - -:mod:`distutils.dist` --- The Distribution class -================================================ - -.. module:: distutils.dist - :synopsis: Provides the Distribution class, which represents the module distribution being - built/installed/distributed - - -This module provides the :class:`~distutils.core.Distribution` class, which -represents the module distribution being built/installed/distributed. - - -:mod:`distutils.extension` --- The Extension class -================================================== - -.. module:: distutils.extension - :synopsis: Provides the Extension class, used to describe C/C++ extension modules in setup - scripts - - -This module provides the :class:`Extension` class, used to describe C/C++ -extension modules in setup scripts. - -.. % \subsection{Ungrouped modules} -.. % The following haven't been moved into a more appropriate section yet. - - -:mod:`distutils.debug` --- Distutils debug mode -=============================================== - -.. module:: distutils.debug - :synopsis: Provides the debug flag for distutils - - -This module provides the DEBUG flag. - - -:mod:`distutils.errors` --- Distutils exceptions -================================================ - -.. module:: distutils.errors - :synopsis: Provides standard distutils exceptions - - -Provides exceptions used by the Distutils modules. Note that Distutils modules -may raise standard exceptions; in particular, SystemExit is usually raised for -errors that are obviously the end-user's fault (eg. bad command-line arguments). - -This module is safe to use in ``from ... import *`` mode; it only exports -symbols whose names start with ``Distutils`` and end with ``Error``. - - -:mod:`distutils.fancy_getopt` --- Wrapper around the standard getopt module -=========================================================================== - -.. module:: distutils.fancy_getopt - :synopsis: Additional getopt functionality - - -This module provides a wrapper around the standard :mod:`getopt` module that -provides the following additional features: - -* short and long options are tied together - -* options have help strings, so :func:`fancy_getopt` could potentially create a - complete usage summary - -* options set attributes of a passed-in object - -* boolean options can have "negative aliases" --- eg. if :option:`!--quiet` is - the "negative alias" of :option:`!--verbose`, then :option:`!--quiet` on the - command line sets *verbose* to false. - -.. function:: fancy_getopt(options, negative_opt, object, args) - - Wrapper function. *options* is a list of ``(long_option, short_option, - help_string)`` 3-tuples as described in the constructor for - :class:`FancyGetopt`. *negative_opt* should be a dictionary mapping option names - to option names, both the key and value should be in the *options* list. - *object* is an object which will be used to store values (see the :meth:`getopt` - method of the :class:`FancyGetopt` class). *args* is the argument list. Will use - ``sys.argv[1:]`` if you pass ``None`` as *args*. - - -.. function:: wrap_text(text, width) - - Wraps *text* to less than *width* wide. - - -.. class:: FancyGetopt([option_table=None]) - - The option_table is a list of 3-tuples: ``(long_option, short_option, - help_string)`` - - If an option takes an argument, its *long_option* should have ``'='`` appended; - *short_option* should just be a single character, no ``':'`` in any case. - *short_option* should be ``None`` if a *long_option* doesn't have a - corresponding *short_option*. All option tuples must have long options. - -The :class:`FancyGetopt` class provides the following methods: - - -.. method:: FancyGetopt.getopt([args=None, object=None]) - - Parse command-line options in args. Store as attributes on *object*. - - If *args* is ``None`` or not supplied, uses ``sys.argv[1:]``. If *object* is - ``None`` or not supplied, creates a new :class:`OptionDummy` instance, stores - option values there, and returns a tuple ``(args, object)``. If *object* is - supplied, it is modified in place and :func:`getopt` just returns *args*; in - both cases, the returned *args* is a modified copy of the passed-in *args* list, - which is left untouched. - - .. % and args returned are? - - -.. method:: FancyGetopt.get_option_order() - - Returns the list of ``(option, value)`` tuples processed by the previous run of - :meth:`getopt` Raises :exc:`RuntimeError` if :meth:`getopt` hasn't been called - yet. - - -.. method:: FancyGetopt.generate_help([header=None]) - - Generate help text (a list of strings, one per suggested line of output) from - the option table for this :class:`FancyGetopt` object. - - If supplied, prints the supplied *header* at the top of the help. - - -:mod:`distutils.filelist` --- The FileList class -================================================ - -.. module:: distutils.filelist - :synopsis: The FileList class, used for poking about the file system and - building lists of files. - - -This module provides the :class:`FileList` class, used for poking about the -filesystem and building lists of files. - - -:mod:`distutils.log` --- Simple :pep:`282`-style logging -======================================================== - -.. module:: distutils.log - :synopsis: A simple logging mechanism, :pep:`282`-style - - -:mod:`distutils.spawn` --- Spawn a sub-process -============================================== - -.. module:: distutils.spawn - :synopsis: Provides the spawn() function - - -This module provides the :func:`spawn` function, a front-end to various -platform-specific functions for launching another program in a sub-process. -Also provides :func:`find_executable` to search the path for a given executable -name. - - -:mod:`distutils.sysconfig` --- System configuration information -=============================================================== - -.. module:: distutils.sysconfig - :synopsis: Low-level access to configuration information of the Python interpreter. -.. deprecated:: 3.10 - :mod:`distutils.sysconfig` has been merged into :mod:`sysconfig`. -.. moduleauthor:: Fred L. Drake, Jr. <fdrake@acm.org> -.. moduleauthor:: Greg Ward <gward@python.net> -.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org> - - -The :mod:`distutils.sysconfig` module provides access to Python's low-level -configuration information. The specific configuration variables available -depend heavily on the platform and configuration. The specific variables depend -on the build process for the specific version of Python being run; the variables -are those found in the :file:`Makefile` and configuration header that are -installed with Python on Unix systems. The configuration header is called -:file:`pyconfig.h` for Python versions starting with 2.2, and :file:`config.h` -for earlier versions of Python. - -Some additional functions are provided which perform some useful manipulations -for other parts of the :mod:`distutils` package. - - -.. data:: PREFIX - - The result of ``os.path.normpath(sys.prefix)``. - - -.. data:: EXEC_PREFIX - - The result of ``os.path.normpath(sys.exec_prefix)``. - - -.. function:: get_config_var(name) - - Return the value of a single variable. This is equivalent to - ``get_config_vars().get(name)``. - - -.. function:: get_config_vars(...) - - Return a set of variable definitions. If there are no arguments, this returns a - dictionary mapping names of configuration variables to values. If arguments are - provided, they should be strings, and the return value will be a sequence giving - the associated values. If a given name does not have a corresponding value, - ``None`` will be included for that variable. - - -.. function:: get_config_h_filename() - - Return the full path name of the configuration header. For Unix, this will be - the header generated by the :program:`configure` script; for other platforms the - header will have been supplied directly by the Python source distribution. The - file is a platform-specific text file. - - -.. function:: get_makefile_filename() - - Return the full path name of the :file:`Makefile` used to build Python. For - Unix, this will be a file generated by the :program:`configure` script; the - meaning for other platforms will vary. The file is a platform-specific text - file, if it exists. This function is only useful on POSIX platforms. - -The following functions are deprecated together with this module and they -have no direct replacement. - - -.. function:: get_python_inc([plat_specific[, prefix]]) - - Return the directory for either the general or platform-dependent C include - files. If *plat_specific* is true, the platform-dependent include directory is - returned; if false or omitted, the platform-independent directory is returned. - If *prefix* is given, it is used as either the prefix instead of - :const:`PREFIX`, or as the exec-prefix instead of :const:`EXEC_PREFIX` if - *plat_specific* is true. - - -.. function:: get_python_lib([plat_specific[, standard_lib[, prefix]]]) - - Return the directory for either the general or platform-dependent library - installation. If *plat_specific* is true, the platform-dependent include - directory is returned; if false or omitted, the platform-independent directory - is returned. If *prefix* is given, it is used as either the prefix instead of - :const:`PREFIX`, or as the exec-prefix instead of :const:`EXEC_PREFIX` if - *plat_specific* is true. If *standard_lib* is true, the directory for the - standard library is returned rather than the directory for the installation of - third-party extensions. - -The following function is only intended for use within the :mod:`distutils` -package. - - -.. function:: customize_compiler(compiler) - - Do any platform-specific customization of a - :class:`distutils.ccompiler.CCompiler` instance. - - This function is only needed on Unix at this time, but should be called - consistently to support forward-compatibility. It inserts the information that - varies across Unix flavors and is stored in Python's :file:`Makefile`. This - information includes the selected compiler, compiler and linker options, and the - extension used by the linker for shared objects. - -This function is even more special-purpose, and should only be used from -Python's own build procedures. - - -.. function:: set_python_build() - - Inform the :mod:`distutils.sysconfig` module that it is being used as part of - the build process for Python. This changes a lot of relative locations for - files, allowing them to be located in the build area rather than in an installed - Python. - - -:mod:`distutils.text_file` --- The TextFile class -================================================= - -.. module:: distutils.text_file - :synopsis: Provides the TextFile class, a simple interface to text files - - -This module provides the :class:`TextFile` class, which gives an interface to -text files that (optionally) takes care of stripping comments, ignoring blank -lines, and joining lines with backslashes. - - -.. class:: TextFile([filename=None, file=None, **options]) - - This class provides a file-like object that takes care of all the things you - commonly want to do when processing a text file that has some line-by-line - syntax: strip comments (as long as ``#`` is your comment character), skip blank - lines, join adjacent lines by escaping the newline (ie. backslash at end of - line), strip leading and/or trailing whitespace. All of these are optional and - independently controllable. - - The class provides a :meth:`warn` method so you can generate warning messages - that report physical line number, even if the logical line in question spans - multiple physical lines. Also provides :meth:`unreadline` for implementing - line-at-a-time lookahead. - - :class:`TextFile` instances are create with either *filename*, *file*, or both. - :exc:`RuntimeError` is raised if both are ``None``. *filename* should be a - string, and *file* a file object (or something that provides :meth:`readline` - and :meth:`close` methods). It is recommended that you supply at least - *filename*, so that :class:`TextFile` can include it in warning messages. If - *file* is not supplied, :class:`TextFile` creates its own using the - :func:`open` built-in function. - - The options are all boolean, and affect the values returned by :meth:`readline` - - .. tabularcolumns:: |l|L|l| - - +------------------+--------------------------------+---------+ - | option name | description | default | - +==================+================================+=========+ - | *strip_comments* | strip from ``'#'`` to | true | - | | end-of-line, as well as any | | - | | whitespace leading up to the | | - | | ``'#'``\ ---unless it is | | - | | escaped by a backslash | | - +------------------+--------------------------------+---------+ - | *lstrip_ws* | strip leading whitespace from | false | - | | each line before returning it | | - +------------------+--------------------------------+---------+ - | *rstrip_ws* | strip trailing whitespace | true | - | | (including line terminator!) | | - | | from each line before | | - | | returning it. | | - +------------------+--------------------------------+---------+ - | *skip_blanks* | skip lines that are empty | true | - | | \*after\* stripping comments | | - | | and whitespace. (If both | | - | | lstrip_ws and rstrip_ws are | | - | | false, then some lines may | | - | | consist of solely whitespace: | | - | | these will \*not\* be skipped, | | - | | even if *skip_blanks* is | | - | | true.) | | - +------------------+--------------------------------+---------+ - | *join_lines* | if a backslash is the last | false | - | | non-newline character on a | | - | | line after stripping comments | | - | | and whitespace, join the | | - | | following line to it to form | | - | | one logical line; if N | | - | | consecutive lines end with a | | - | | backslash, then N+1 physical | | - | | lines will be joined to form | | - | | one logical line. | | - +------------------+--------------------------------+---------+ - | *collapse_join* | strip leading whitespace from | false | - | | lines that are joined to their | | - | | predecessor; only matters if | | - | | ``(join_lines and not | | - | | lstrip_ws)`` | | - +------------------+--------------------------------+---------+ - - Note that since *rstrip_ws* can strip the trailing newline, the semantics of - :meth:`readline` must differ from those of the built-in file object's - :meth:`readline` method! In particular, :meth:`readline` returns ``None`` for - end-of-file: an empty string might just be a blank line (or an all-whitespace - line), if *rstrip_ws* is true but *skip_blanks* is not. - - - .. method:: TextFile.open(filename) - - Open a new file *filename*. This overrides any *file* or *filename* - constructor arguments. - - - .. method:: TextFile.close() - - Close the current file and forget everything we know about it (including the - filename and the current line number). - - - .. method:: TextFile.warn(msg[,line=None]) - - Print (to stderr) a warning message tied to the current logical line in the - current file. If the current logical line in the file spans multiple physical - lines, the warning refers to the whole range, such as ``"lines 3-5"``. If - *line* is supplied, it overrides the current line number; it may be a list or - tuple to indicate a range of physical lines, or an integer for a single - physical line. - - - .. method:: TextFile.readline() - - Read and return a single logical line from the current file (or from an internal - buffer if lines have previously been "unread" with :meth:`unreadline`). If the - *join_lines* option is true, this may involve reading multiple physical lines - concatenated into a single string. Updates the current line number, so calling - :meth:`warn` after :meth:`readline` emits a warning about the physical line(s) - just read. Returns ``None`` on end-of-file, since the empty string can occur - if *rstrip_ws* is true but *strip_blanks* is not. - - - .. method:: TextFile.readlines() - - Read and return the list of all logical lines remaining in the current file. - This updates the current line number to the last line of the file. - - - .. method:: TextFile.unreadline(line) - - Push *line* (a string) onto an internal buffer that will be checked by future - :meth:`readline` calls. Handy for implementing a parser with line-at-a-time - lookahead. Note that lines that are "unread" with :meth:`unreadline` are not - subsequently re-cleansed (whitespace stripped, or whatever) when read with - :meth:`readline`. If multiple calls are made to :meth:`unreadline` before a call - to :meth:`readline`, the lines will be returned most in most recent first order. - - -:mod:`distutils.version` --- Version number classes -=================================================== - -.. module:: distutils.version - :synopsis: Implements classes that represent module version numbers. - - -.. % todo -.. % \section{Distutils Commands} -.. % -.. % This part of Distutils implements the various Distutils commands, such -.. % as \code{build}, \code{install} \&c. Each command is implemented as a -.. % separate module, with the command name as the name of the module. - - -:mod:`distutils.cmd` --- Abstract base class for Distutils commands -=================================================================== - -.. module:: distutils.cmd - :synopsis: Provides the abstract base class :class:`~distutils.cmd.Command`. This class - is subclassed by the modules in the distutils.command subpackage. - - -This module supplies the abstract base class :class:`Command`. - - -.. class:: Command(dist) - - Abstract base class for defining command classes, the "worker bees" of the - Distutils. A useful analogy for command classes is to think of them as - subroutines with local variables called *options*. The options are declared - in :meth:`initialize_options` and defined (given their final values) in - :meth:`finalize_options`, both of which must be defined by every command - class. The distinction between the two is necessary because option values - might come from the outside world (command line, config file, ...), and any - options dependent on other options must be computed after these outside - influences have been processed --- hence :meth:`finalize_options`. The body - of the subroutine, where it does all its work based on the values of its - options, is the :meth:`run` method, which must also be implemented by every - command class. - - The class constructor takes a single argument *dist*, a - :class:`~distutils.core.Distribution` instance. - - -Creating a new Distutils command -================================ - -This section outlines the steps to create a new Distutils command. - -A new command lives in a module in the :mod:`distutils.command` package. There -is a sample template in that directory called :file:`command_template`. Copy -this file to a new module with the same name as the new command you're -implementing. This module should implement a class with the same name as the -module (and the command). So, for instance, to create the command -``peel_banana`` (so that users can run ``setup.py peel_banana``), you'd copy -:file:`command_template` to :file:`distutils/command/peel_banana.py`, then edit -it so that it's implementing the class :class:`peel_banana`, a subclass of -:class:`distutils.cmd.Command`. - -Subclasses of :class:`Command` must define the following methods. - -.. method:: Command.initialize_options() - - Set default values for all the options that this command supports. Note that - these defaults may be overridden by other commands, by the setup script, by - config files, or by the command-line. Thus, this is not the place to code - dependencies between options; generally, :meth:`initialize_options` - implementations are just a bunch of ``self.foo = None`` assignments. - - -.. method:: Command.finalize_options() - - Set final values for all the options that this command supports. This is - always called as late as possible, ie. after any option assignments from the - command-line or from other commands have been done. Thus, this is the place - to code option dependencies: if *foo* depends on *bar*, then it is safe to - set *foo* from *bar* as long as *foo* still has the same value it was - assigned in :meth:`initialize_options`. - - -.. method:: Command.run() - - A command's raison d'etre: carry out the action it exists to perform, controlled - by the options initialized in :meth:`initialize_options`, customized by other - commands, the setup script, the command-line, and config files, and finalized in - :meth:`finalize_options`. All terminal output and filesystem interaction should - be done by :meth:`run`. - - -.. attribute:: Command.sub_commands - - *sub_commands* formalizes the notion of a "family" of commands, - e.g. ``install`` as the parent with sub-commands ``install_lib``, - ``install_headers``, etc. The parent of a family of commands defines - *sub_commands* as a class attribute; it's a list of 2-tuples ``(command_name, - predicate)``, with *command_name* a string and *predicate* a function, a - string or ``None``. *predicate* is a method of the parent command that - determines whether the corresponding command is applicable in the current - situation. (E.g. ``install_headers`` is only applicable if we have any C - header files to install.) If *predicate* is ``None``, that command is always - applicable. - - *sub_commands* is usually defined at the *end* of a class, because - predicates can be methods of the class, so they must already have been - defined. The canonical example is the :command:`install` command. - - -:mod:`distutils.command` --- Individual Distutils commands -========================================================== - -.. module:: distutils.command - :synopsis: Contains one module for each standard Distutils command. - - -.. % \subsubsection{Individual Distutils commands} -.. % todo - - -:mod:`distutils.command.bdist` --- Build a binary installer -=========================================================== - -.. module:: distutils.command.bdist - :synopsis: Build a binary installer for a package - - -.. % todo - - -:mod:`distutils.command.bdist_packager` --- Abstract base class for packagers -============================================================================= - -.. module:: distutils.command.bdist_packager - :synopsis: Abstract base class for packagers - - -.. % todo - - -:mod:`distutils.command.bdist_dumb` --- Build a "dumb" installer -================================================================ - -.. module:: distutils.command.bdist_dumb - :synopsis: Build a "dumb" installer - a simple archive of files - - -.. % todo - - -:mod:`distutils.command.bdist_rpm` --- Build a binary distribution as a Redhat RPM and SRPM -=========================================================================================== - -.. module:: distutils.command.bdist_rpm - :synopsis: Build a binary distribution as a Redhat RPM and SRPM - - -.. % todo - - -:mod:`distutils.command.sdist` --- Build a source distribution -============================================================== - -.. module:: distutils.command.sdist - :synopsis: Build a source distribution - - -.. % todo - - -:mod:`distutils.command.build` --- Build all files of a package -=============================================================== - -.. module:: distutils.command.build - :synopsis: Build all files of a package - - -.. % todo - - -:mod:`distutils.command.build_clib` --- Build any C libraries in a package -========================================================================== - -.. module:: distutils.command.build_clib - :synopsis: Build any C libraries in a package - - -.. % todo - - -:mod:`distutils.command.build_ext` --- Build any extensions in a package -======================================================================== - -.. module:: distutils.command.build_ext - :synopsis: Build any extensions in a package - - -.. % todo - - -:mod:`distutils.command.build_py` --- Build the .py/.pyc files of a package -=========================================================================== - -.. module:: distutils.command.build_py - :synopsis: Build the .py/.pyc files of a package - - -.. class:: build_py - -.. class:: build_py_2to3 - - Alternative implementation of build_py which also runs the - 2to3 conversion library on each .py file that is going to be - installed. To use this in a setup.py file for a distribution - that is designed to run with both Python 2.x and 3.x, add:: - - try: - from distutils.command.build_py import build_py_2to3 as build_py - except ImportError: - from distutils.command.build_py import build_py - - to your setup.py, and later:: - - cmdclass = {'build_py': build_py} - - to the invocation of setup(). - - -:mod:`distutils.command.build_scripts` --- Build the scripts of a package -========================================================================= - -.. module:: distutils.command.build_scripts - :synopsis: Build the scripts of a package - - -.. % todo - - -:mod:`distutils.command.clean` --- Clean a package build area -============================================================= - -.. module:: distutils.command.clean - :synopsis: Clean a package build area - -This command removes the temporary files created by :command:`build` -and its subcommands, like intermediary compiled object files. With -the ``--all`` option, the complete build directory will be removed. - -Extension modules built :ref:`in place <distutils-build-ext-inplace>` -will not be cleaned, as they are not in the build directory. - - -:mod:`distutils.command.config` --- Perform package configuration -================================================================= - -.. module:: distutils.command.config - :synopsis: Perform package configuration - - -.. % todo - - -:mod:`distutils.command.install` --- Install a package -====================================================== - -.. module:: distutils.command.install - :synopsis: Install a package - - -.. % todo - - -:mod:`distutils.command.install_data` --- Install data files from a package -=========================================================================== - -.. module:: distutils.command.install_data - :synopsis: Install data files from a package - - -.. % todo - - -:mod:`distutils.command.install_headers` --- Install C/C++ header files from a package -====================================================================================== - -.. module:: distutils.command.install_headers - :synopsis: Install C/C++ header files from a package - - -.. % todo - - -:mod:`distutils.command.install_lib` --- Install library files from a package -============================================================================= - -.. module:: distutils.command.install_lib - :synopsis: Install library files from a package - - -.. % todo - - -:mod:`distutils.command.install_scripts` --- Install script files from a package -================================================================================ - -.. module:: distutils.command.install_scripts - :synopsis: Install script files from a package - - -.. % todo - - -:mod:`distutils.command.register` --- Register a module with the Python Package Index -===================================================================================== - -.. module:: distutils.command.register - :synopsis: Register a module with the Python Package Index - - -The ``register`` command registers the package with the Python Package Index. -This is described in more detail in :pep:`301`. - -.. % todo - - -:mod:`distutils.command.check` --- Check the meta-data of a package -=================================================================== - -.. module:: distutils.command.check - :synopsis: Check the meta-data of a package - - -The ``check`` command performs some tests on the meta-data of a package. -For example, it verifies that all required meta-data are provided as -the arguments passed to the :func:`setup` function. - -.. % todo diff --git a/Doc/distutils/builtdist.rst b/Doc/distutils/builtdist.rst deleted file mode 100644 index c1d9ea533da..00000000000 --- a/Doc/distutils/builtdist.rst +++ /dev/null @@ -1,392 +0,0 @@ -.. _built-dist: - -**************************** -Creating Built Distributions -**************************** - -.. include:: ./_setuptools_disclaimer.rst - -A "built distribution" is what you're probably used to thinking of either as a -"binary package" or an "installer" (depending on your background). It's not -necessarily binary, though, because it might contain only Python source code -and/or byte-code; and we don't call it a package, because that word is already -spoken for in Python. (And "installer" is a term specific to the world of -mainstream desktop systems.) - -A built distribution is how you make life as easy as possible for installers of -your module distribution: for users of RPM-based Linux systems, it's a binary -RPM; for Windows users, it's an executable installer; for Debian-based Linux -users, it's a Debian package; and so forth. Obviously, no one person will be -able to create built distributions for every platform under the sun, so the -Distutils are designed to enable module developers to concentrate on their -specialty---writing code and creating source distributions---while an -intermediary species called *packagers* springs up to turn source distributions -into built distributions for as many platforms as there are packagers. - -Of course, the module developer could be their own packager; or the packager could -be a volunteer "out there" somewhere who has access to a platform which the -original developer does not; or it could be software periodically grabbing new -source distributions and turning them into built distributions for as many -platforms as the software has access to. Regardless of who they are, a packager -uses the setup script and the :command:`bdist` command family to generate built -distributions. - -As a simple example, if I run the following command in the Distutils source -tree:: - - python setup.py bdist - -then the Distutils builds my module distribution (the Distutils itself in this -case), does a "fake" installation (also in the :file:`build` directory), and -creates the default type of built distribution for my platform. The default -format for built distributions is a "dumb" tar file on Unix, and a simple -executable installer on Windows. (That tar file is considered "dumb" because it -has to be unpacked in a specific location to work.) - -Thus, the above command on a Unix system creates -:file:`Distutils-1.0.{plat}.tar.gz`; unpacking this tarball from the right place -installs the Distutils just as though you had downloaded the source distribution -and run ``python setup.py install``. (The "right place" is either the root of -the filesystem or Python's :file:`{prefix}` directory, depending on the options -given to the :command:`bdist_dumb` command; the default is to make dumb -distributions relative to :file:`{prefix}`.) - -Obviously, for pure Python distributions, this isn't any simpler than just -running ``python setup.py install``\ ---but for non-pure distributions, which -include extensions that would need to be compiled, it can mean the difference -between someone being able to use your extensions or not. And creating "smart" -built distributions, such as an RPM package or an executable installer for -Windows, is far more convenient for users even if your distribution doesn't -include any extensions. - -The :command:`bdist` command has a :option:`!--formats` option, similar to the -:command:`sdist` command, which you can use to select the types of built -distribution to generate: for example, :: - - python setup.py bdist --format=zip - -would, when run on a Unix system, create -:file:`Distutils-1.0.{plat}.zip`\ ---again, this archive would be unpacked -from the root directory to install the Distutils. - -The available formats for built distributions are: - -+-------------+------------------------------+---------+ -| Format | Description | Notes | -+=============+==============================+=========+ -| ``gztar`` | gzipped tar file | \(1) | -| | (:file:`.tar.gz`) | | -+-------------+------------------------------+---------+ -| ``bztar`` | bzipped tar file | | -| | (:file:`.tar.bz2`) | | -+-------------+------------------------------+---------+ -| ``xztar`` | xzipped tar file | | -| | (:file:`.tar.xz`) | | -+-------------+------------------------------+---------+ -| ``ztar`` | compressed tar file | \(3) | -| | (:file:`.tar.Z`) | | -+-------------+------------------------------+---------+ -| ``tar`` | tar file (:file:`.tar`) | | -+-------------+------------------------------+---------+ -| ``zip`` | zip file (:file:`.zip`) | (2),(4) | -+-------------+------------------------------+---------+ -| ``rpm`` | RPM | \(5) | -+-------------+------------------------------+---------+ -| ``pkgtool`` | Solaris :program:`pkgtool` | | -+-------------+------------------------------+---------+ -| ``sdux`` | HP-UX :program:`swinstall` | | -+-------------+------------------------------+---------+ -| ``msi`` | Microsoft Installer. | | -+-------------+------------------------------+---------+ - -.. versionchanged:: 3.5 - Added support for the ``xztar`` format. - - -Notes: - -(1) - default on Unix - -(2) - default on Windows - -(3) - requires external :program:`compress` utility. - -(4) - requires either external :program:`zip` utility or :mod:`zipfile` module (part - of the standard Python library since Python 1.6) - -(5) - requires external :program:`rpm` utility, version 3.0.4 or better (use ``rpm - --version`` to find out which version you have) - -You don't have to use the :command:`bdist` command with the :option:`!--formats` -option; you can also use the command that directly implements the format you're -interested in. Some of these :command:`bdist` "sub-commands" actually generate -several similar formats; for instance, the :command:`bdist_dumb` command -generates all the "dumb" archive formats (``tar``, ``gztar``, ``bztar``, -``xztar``, ``ztar``, and ``zip``), and :command:`bdist_rpm` generates both -binary and source RPMs. The :command:`bdist` sub-commands, and the formats -generated by each, are: - -+--------------------------+-------------------------------------+ -| Command | Formats | -+==========================+=====================================+ -| :command:`bdist_dumb` | tar, gztar, bztar, xztar, ztar, zip | -+--------------------------+-------------------------------------+ -| :command:`bdist_rpm` | rpm, srpm | -+--------------------------+-------------------------------------+ - -The following sections give details on the individual :command:`bdist_\*` -commands. - - -.. .. _creating-dumb: - -.. Creating dumb built distributions -.. ================================= - -.. XXX Need to document absolute vs. prefix-relative packages here, but first - I have to implement it! - - -.. _creating-rpms: - -Creating RPM packages -===================== - -The RPM format is used by many popular Linux distributions, including Red Hat, -SuSE, and Mandrake. If one of these (or any of the other RPM-based Linux -distributions) is your usual environment, creating RPM packages for other users -of that same distribution is trivial. Depending on the complexity of your module -distribution and differences between Linux distributions, you may also be able -to create RPMs that work on different RPM-based distributions. - -The usual way to create an RPM of your module distribution is to run the -:command:`bdist_rpm` command:: - - python setup.py bdist_rpm - -or the :command:`bdist` command with the :option:`!--format` option:: - - python setup.py bdist --formats=rpm - -The former allows you to specify RPM-specific options; the latter allows you to -easily specify multiple formats in one run. If you need to do both, you can -explicitly specify multiple :command:`bdist_\*` commands and their options:: - - python setup.py bdist_rpm --packager="John Doe <jdoe@example.org>" - -Creating RPM packages is driven by a :file:`.spec` file, much as using the -Distutils is driven by the setup script. To make your life easier, the -:command:`bdist_rpm` command normally creates a :file:`.spec` file based on the -information you supply in the setup script, on the command line, and in any -Distutils configuration files. Various options and sections in the -:file:`.spec` file are derived from options in the setup script as follows: - -+------------------------------------------+----------------------------------------------+ -| RPM :file:`.spec` file option or section | Distutils setup script option | -+==========================================+==============================================+ -| Name | ``name`` | -+------------------------------------------+----------------------------------------------+ -| Summary (in preamble) | ``description`` | -+------------------------------------------+----------------------------------------------+ -| Version | ``version`` | -+------------------------------------------+----------------------------------------------+ -| Vendor | ``author`` and ``author_email``, | -| | or --- & ``maintainer`` and | -| | ``maintainer_email`` | -+------------------------------------------+----------------------------------------------+ -| Copyright | ``license`` | -+------------------------------------------+----------------------------------------------+ -| Url | ``url`` | -+------------------------------------------+----------------------------------------------+ -| %description (section) | ``long_description`` | -+------------------------------------------+----------------------------------------------+ - -Additionally, there are many options in :file:`.spec` files that don't have -corresponding options in the setup script. Most of these are handled through -options to the :command:`bdist_rpm` command as follows: - -+-------------------------------+-----------------------------+-------------------------+ -| RPM :file:`.spec` file option | :command:`bdist_rpm` option | default value | -| or section | | | -+===============================+=============================+=========================+ -| Release | ``release`` | "1" | -+-------------------------------+-----------------------------+-------------------------+ -| Group | ``group`` | "Development/Libraries" | -+-------------------------------+-----------------------------+-------------------------+ -| Vendor | ``vendor`` | (see above) | -+-------------------------------+-----------------------------+-------------------------+ -| Packager | ``packager`` | (none) | -+-------------------------------+-----------------------------+-------------------------+ -| Provides | ``provides`` | (none) | -+-------------------------------+-----------------------------+-------------------------+ -| Requires | ``requires`` | (none) | -+-------------------------------+-----------------------------+-------------------------+ -| Conflicts | ``conflicts`` | (none) | -+-------------------------------+-----------------------------+-------------------------+ -| Obsoletes | ``obsoletes`` | (none) | -+-------------------------------+-----------------------------+-------------------------+ -| Distribution | ``distribution_name`` | (none) | -+-------------------------------+-----------------------------+-------------------------+ -| BuildRequires | ``build_requires`` | (none) | -+-------------------------------+-----------------------------+-------------------------+ -| Icon | ``icon`` | (none) | -+-------------------------------+-----------------------------+-------------------------+ - -Obviously, supplying even a few of these options on the command-line would be -tedious and error-prone, so it's usually best to put them in the setup -configuration file, :file:`setup.cfg`\ ---see section :ref:`setup-config`. If -you distribute or package many Python module distributions, you might want to -put options that apply to all of them in your personal Distutils configuration -file (:file:`~/.pydistutils.cfg`). If you want to temporarily disable -this file, you can pass the :option:`!--no-user-cfg` option to :file:`setup.py`. - -There are three steps to building a binary RPM package, all of which are -handled automatically by the Distutils: - -#. create a :file:`.spec` file, which describes the package (analogous to the - Distutils setup script; in fact, much of the information in the setup script - winds up in the :file:`.spec` file) - -#. create the source RPM - -#. create the "binary" RPM (which may or may not contain binary code, depending - on whether your module distribution contains Python extensions) - -Normally, RPM bundles the last two steps together; when you use the Distutils, -all three steps are typically bundled together. - -If you wish, you can separate these three steps. You can use the -:option:`!--spec-only` option to make :command:`bdist_rpm` just create the -:file:`.spec` file and exit; in this case, the :file:`.spec` file will be -written to the "distribution directory"---normally :file:`dist/`, but -customizable with the :option:`!--dist-dir` option. (Normally, the :file:`.spec` -file winds up deep in the "build tree," in a temporary directory created by -:command:`bdist_rpm`.) - -.. % \XXX{this isn't implemented yet---is it needed?!} -.. % You can also specify a custom \file{.spec} file with the -.. % \longprogramopt{spec-file} option; used in conjunction with -.. % \longprogramopt{spec-only}, this gives you an opportunity to customize -.. % the \file{.spec} file manually: -.. % -.. % \ begin{verbatim} -.. % > python setup.py bdist_rpm --spec-only -.. % # ...edit dist/FooBar-1.0.spec -.. % > python setup.py bdist_rpm --spec-file=dist/FooBar-1.0.spec -.. % \ end{verbatim} -.. % -.. % (Although a better way to do this is probably to override the standard -.. % \command{bdist\_rpm} command with one that writes whatever else you want -.. % to the \file{.spec} file.) - - -.. _cross-compile-windows: - -Cross-compiling on Windows -========================== - -Starting with Python 2.6, distutils is capable of cross-compiling between -Windows platforms. In practice, this means that with the correct tools -installed, you can use a 32bit version of Windows to create 64bit extensions -and vice-versa. - -To build for an alternate platform, specify the :option:`!--plat-name` option -to the build command. Valid values are currently 'win32', and 'win-amd64'. -For example, on a 32bit version of Windows, you could execute:: - - python setup.py build --plat-name=win-amd64 - -to build a 64bit version of your extension. - -would create a 64bit installation executable on your 32bit version of Windows. - -To cross-compile, you must download the Python source code and cross-compile -Python itself for the platform you are targeting - it is not possible from a -binary installation of Python (as the .lib etc file for other platforms are -not included.) In practice, this means the user of a 32 bit operating -system will need to use Visual Studio 2008 to open the -:file:`PCbuild/PCbuild.sln` solution in the Python source tree and build the -"x64" configuration of the 'pythoncore' project before cross-compiling -extensions is possible. - -Note that by default, Visual Studio 2008 does not install 64bit compilers or -tools. You may need to reexecute the Visual Studio setup process and select -these tools (using Control Panel->[Add/Remove] Programs is a convenient way to -check or modify your existing install.) - -.. _postinstallation-script: - -The Postinstallation script ---------------------------- - -Starting with Python 2.3, a postinstallation script can be specified with the -:option:`!--install-script` option. The basename of the script must be -specified, and the script filename must also be listed in the scripts argument -to the setup function. - -This script will be run at installation time on the target system after all the -files have been copied, with ``argv[1]`` set to :option:`!-install`, and again at -uninstallation time before the files are removed with ``argv[1]`` set to -:option:`!-remove`. - -The installation script runs embedded in the windows installer, every output -(``sys.stdout``, ``sys.stderr``) is redirected into a buffer and will be -displayed in the GUI after the script has finished. - -Some functions especially useful in this context are available as additional -built-in functions in the installation script. - - -.. function:: directory_created(path) - file_created(path) - - These functions should be called when a directory or file is created by the - postinstall script at installation time. It will register *path* with the - uninstaller, so that it will be removed when the distribution is uninstalled. - To be safe, directories are only removed if they are empty. - - -.. function:: get_special_folder_path(csidl_string) - - This function can be used to retrieve special folder locations on Windows like - the Start Menu or the Desktop. It returns the full path to the folder. - *csidl_string* must be one of the following strings:: - - "CSIDL_APPDATA" - - "CSIDL_COMMON_STARTMENU" - "CSIDL_STARTMENU" - - "CSIDL_COMMON_DESKTOPDIRECTORY" - "CSIDL_DESKTOPDIRECTORY" - - "CSIDL_COMMON_STARTUP" - "CSIDL_STARTUP" - - "CSIDL_COMMON_PROGRAMS" - "CSIDL_PROGRAMS" - - "CSIDL_FONTS" - - If the folder cannot be retrieved, :exc:`OSError` is raised. - - Which folders are available depends on the exact Windows version, and probably - also the configuration. For details refer to Microsoft's documentation of the - :c:func:`SHGetSpecialFolderPath` function. - - -.. function:: create_shortcut(target, description, filename[, arguments[, workdir[, iconpath[, iconindex]]]]) - - This function creates a shortcut. *target* is the path to the program to be - started by the shortcut. *description* is the description of the shortcut. - *filename* is the title of the shortcut that the user will see. *arguments* - specifies the command line arguments, if any. *workdir* is the working directory - for the program. *iconpath* is the file containing the icon for the shortcut, - and *iconindex* is the index of the icon in the file *iconpath*. Again, for - details consult the Microsoft documentation for the :class:`IShellLink` - interface. diff --git a/Doc/distutils/commandref.rst b/Doc/distutils/commandref.rst deleted file mode 100644 index 3e247e68d3a..00000000000 --- a/Doc/distutils/commandref.rst +++ /dev/null @@ -1,105 +0,0 @@ -.. _reference: - -***************** -Command Reference -***************** - -.. include:: ./_setuptools_disclaimer.rst - -.. % \section{Building modules: the \protect\command{build} command family} -.. % \label{build-cmds} -.. % \subsubsection{\protect\command{build}} -.. % \label{build-cmd} -.. % \subsubsection{\protect\command{build\_py}} -.. % \label{build-py-cmd} -.. % \subsubsection{\protect\command{build\_ext}} -.. % \label{build-ext-cmd} -.. % \subsubsection{\protect\command{build\_clib}} -.. % \label{build-clib-cmd} - - -.. _install-cmd: - -Installing modules: the :command:`install` command family -========================================================= - -The install command ensures that the build commands have been run and then runs -the subcommands :command:`install_lib`, :command:`install_data` and -:command:`install_scripts`. - -.. % \subsubsection{\protect\command{install\_lib}} -.. % \label{install-lib-cmd} - - -.. _install-data-cmd: - -:command:`install_data` ------------------------ - -This command installs all data files provided with the distribution. - - -.. _install-scripts-cmd: - -:command:`install_scripts` --------------------------- - -This command installs all (Python) scripts in the distribution. - -.. % \subsection{Cleaning up: the \protect\command{clean} command} -.. % \label{clean-cmd} - - -.. _sdist-cmd: - -Creating a source distribution: the :command:`sdist` command -============================================================ - -.. XXX fragment moved down from above: needs context! - -The manifest template commands are: - -+-------------------------------------------+-----------------------------------------------+ -| Command | Description | -+===========================================+===============================================+ -| :command:`include pat1 pat2 ...` | include all files matching any of the listed | -| | patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`exclude pat1 pat2 ...` | exclude all files matching any of the listed | -| | patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`recursive-include dir pat1 pat2 | include all files under *dir* matching any of | -| ...` | the listed patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`recursive-exclude dir pat1 pat2 | exclude all files under *dir* matching any of | -| ...` | the listed patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`global-include pat1 pat2 ...` | include all files anywhere in the source tree | -| | matching --- & any of the listed patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`global-exclude pat1 pat2 ...` | exclude all files anywhere in the source tree | -| | matching --- & any of the listed patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`prune dir` | exclude all files under *dir* | -+-------------------------------------------+-----------------------------------------------+ -| :command:`graft dir` | include all files under *dir* | -+-------------------------------------------+-----------------------------------------------+ - -The patterns here are Unix-style "glob" patterns: ``*`` matches any sequence of -regular filename characters, ``?`` matches any single regular filename -character, and ``[range]`` matches any of the characters in *range* (e.g., -``a-z``, ``a-zA-Z``, ``a-f0-9_.``). The definition of "regular filename -character" is platform-specific: on Unix it is anything except slash; on Windows -anything except backslash or colon. - -.. XXX Windows support not there yet - -.. % \section{Creating a built distribution: the -.. % \protect\command{bdist} command family} -.. % \label{bdist-cmds} - -.. % \subsection{\protect\command{bdist}} -.. % \subsection{\protect\command{bdist\_dumb}} -.. % \subsection{\protect\command{bdist\_rpm}} - - diff --git a/Doc/distutils/configfile.rst b/Doc/distutils/configfile.rst deleted file mode 100644 index 2a5c8329e31..00000000000 --- a/Doc/distutils/configfile.rst +++ /dev/null @@ -1,144 +0,0 @@ -.. _setup-config: - -************************************ -Writing the Setup Configuration File -************************************ - -.. include:: ./_setuptools_disclaimer.rst - -Often, it's not possible to write down everything needed to build a distribution -*a priori*: you may need to get some information from the user, or from the -user's system, in order to proceed. As long as that information is fairly -simple---a list of directories to search for C header files or libraries, for -example---then providing a configuration file, :file:`setup.cfg`, for users to -edit is a cheap and easy way to solicit it. Configuration files also let you -provide default values for any command option, which the installer can then -override either on the command-line or by editing the config file. - -The setup configuration file is a useful middle-ground between the setup -script---which, ideally, would be opaque to installers [#]_---and the command-line to -the setup script, which is outside of your control and entirely up to the -installer. In fact, :file:`setup.cfg` (and any other Distutils configuration -files present on the target system) are processed after the contents of the -setup script, but before the command-line. This has several useful -consequences: - -.. % (If you have more advanced needs, such as determining which extensions -.. % to build based on what capabilities are present on the target system, -.. % then you need the Distutils ``auto-configuration'' facility. This -.. % started to appear in Distutils 0.9 but, as of this writing, isn't mature -.. % or stable enough yet for real-world use.) - -* installers can override some of what you put in :file:`setup.py` by editing - :file:`setup.cfg` - -* you can provide non-standard defaults for options that are not easily set in - :file:`setup.py` - -* installers can override anything in :file:`setup.cfg` using the command-line - options to :file:`setup.py` - -The basic syntax of the configuration file is simple: - -.. code-block:: ini - - [command] - option=value - ... - -where *command* is one of the Distutils commands (e.g. :command:`build_py`, -:command:`install`), and *option* is one of the options that command supports. -Any number of options can be supplied for each command, and any number of -command sections can be included in the file. Blank lines are ignored, as are -comments, which run from a ``'#'`` character until the end of the line. Long -option values can be split across multiple lines simply by indenting the -continuation lines. - -You can find out the list of options supported by a particular command with the -universal :option:`!--help` option, e.g. - -.. code-block:: shell-session - - $ python setup.py --help build_ext - [...] - Options for 'build_ext' command: - --build-lib (-b) directory for compiled extension modules - --build-temp (-t) directory for temporary files (build by-products) - --inplace (-i) ignore build-lib and put compiled extensions into the - source directory alongside your pure Python modules - --include-dirs (-I) list of directories to search for header files - --define (-D) C preprocessor macros to define - --undef (-U) C preprocessor macros to undefine - --swig-opts list of SWIG command line options - [...] - -Note that an option spelled :option:`!--foo-bar` on the command-line is spelled -``foo_bar`` in configuration files. - -.. _distutils-build-ext-inplace: - -For example, say you want your extensions to be built "in-place"---that is, you -have an extension :mod:`pkg.ext`, and you want the compiled extension file -(:file:`ext.so` on Unix, say) to be put in the same source directory as your -pure Python modules :mod:`pkg.mod1` and :mod:`pkg.mod2`. You can always use the -:option:`!--inplace` option on the command-line to ensure this: - -.. code-block:: sh - - python setup.py build_ext --inplace - -But this requires that you always specify the :command:`build_ext` command -explicitly, and remember to provide :option:`!--inplace`. An easier way is to -"set and forget" this option, by encoding it in :file:`setup.cfg`, the -configuration file for this distribution: - -.. code-block:: ini - - [build_ext] - inplace=1 - -This will affect all builds of this module distribution, whether or not you -explicitly specify :command:`build_ext`. If you include :file:`setup.cfg` in -your source distribution, it will also affect end-user builds---which is -probably a bad idea for this option, since always building extensions in-place -would break installation of the module distribution. In certain peculiar cases, -though, modules are built right in their installation directory, so this is -conceivably a useful ability. (Distributing extensions that expect to be built -in their installation directory is almost always a bad idea, though.) - -Another example: certain commands take a lot of options that don't change from -run to run; for example, :command:`bdist_rpm` needs to know everything required -to generate a "spec" file for creating an RPM distribution. Some of this -information comes from the setup script, and some is automatically generated by -the Distutils (such as the list of files installed). But some of it has to be -supplied as options to :command:`bdist_rpm`, which would be very tedious to do -on the command-line for every run. Hence, here is a snippet from the Distutils' -own :file:`setup.cfg`: - -.. code-block:: ini - - [bdist_rpm] - release = 1 - packager = Greg Ward <gward@python.net> - doc_files = CHANGES.txt - README.txt - USAGE.txt - doc/ - examples/ - -Note that the ``doc_files`` option is simply a whitespace-separated string -split across multiple lines for readability. - - -.. seealso:: - - :ref:`inst-config-syntax` in "Installing Python Modules" - More information on the configuration files is available in the manual for - system administrators. - - -.. rubric:: Footnotes - -.. [#] This ideal probably won't be achieved until auto-configuration is fully - supported by the Distutils. - diff --git a/Doc/distutils/examples.rst b/Doc/distutils/examples.rst deleted file mode 100644 index e492b7f6057..00000000000 --- a/Doc/distutils/examples.rst +++ /dev/null @@ -1,340 +0,0 @@ -.. _distutils_examples: - -****************** -Distutils Examples -****************** - -.. include:: ./_setuptools_disclaimer.rst - -This chapter provides a number of basic examples to help get started with -distutils. Additional information about using distutils can be found in the -Distutils Cookbook. - - -.. seealso:: - - `Distutils Cookbook <https://wiki.python.org/moin/Distutils/Cookbook>`_ - Collection of recipes showing how to achieve more control over distutils. - - -.. _pure-mod: - -Pure Python distribution (by module) -==================================== - -If you're just distributing a couple of modules, especially if they don't live -in a particular package, you can specify them individually using the -``py_modules`` option in the setup script. - -In the simplest case, you'll have two files to worry about: a setup script and -the single module you're distributing, :file:`foo.py` in this example:: - - <root>/ - setup.py - foo.py - -(In all diagrams in this section, *<root>* will refer to the distribution root -directory.) A minimal setup script to describe this situation would be:: - - from distutils.core import setup - setup(name='foo', - version='1.0', - py_modules=['foo'], - ) - -Note that the name of the distribution is specified independently with the -``name`` option, and there's no rule that says it has to be the same as -the name of the sole module in the distribution (although that's probably a good -convention to follow). However, the distribution name is used to generate -filenames, so you should stick to letters, digits, underscores, and hyphens. - -Since ``py_modules`` is a list, you can of course specify multiple -modules, eg. if you're distributing modules :mod:`foo` and :mod:`bar`, your -setup might look like this:: - - <root>/ - setup.py - foo.py - bar.py - -and the setup script might be :: - - from distutils.core import setup - setup(name='foobar', - version='1.0', - py_modules=['foo', 'bar'], - ) - -You can put module source files into another directory, but if you have enough -modules to do that, it's probably easier to specify modules by package rather -than listing them individually. - - -.. _pure-pkg: - -Pure Python distribution (by package) -===================================== - -If you have more than a couple of modules to distribute, especially if they are -in multiple packages, it's probably easier to specify whole packages rather than -individual modules. This works even if your modules are not in a package; you -can just tell the Distutils to process modules from the root package, and that -works the same as any other package (except that you don't have to have an -:file:`__init__.py` file). - -The setup script from the last example could also be written as :: - - from distutils.core import setup - setup(name='foobar', - version='1.0', - packages=[''], - ) - -(The empty string stands for the root package.) - -If those two files are moved into a subdirectory, but remain in the root -package, e.g.:: - - <root>/ - setup.py - src/ foo.py - bar.py - -then you would still specify the root package, but you have to tell the -Distutils where source files in the root package live:: - - from distutils.core import setup - setup(name='foobar', - version='1.0', - package_dir={'': 'src'}, - packages=[''], - ) - -More typically, though, you will want to distribute multiple modules in the same -package (or in sub-packages). For example, if the :mod:`foo` and :mod:`bar` -modules belong in package :mod:`foobar`, one way to layout your source tree is -:: - - <root>/ - setup.py - foobar/ - __init__.py - foo.py - bar.py - -This is in fact the default layout expected by the Distutils, and the one that -requires the least work to describe in your setup script:: - - from distutils.core import setup - setup(name='foobar', - version='1.0', - packages=['foobar'], - ) - -If you want to put modules in directories not named for their package, then you -need to use the ``package_dir`` option again. For example, if the -:file:`src` directory holds modules in the :mod:`foobar` package:: - - <root>/ - setup.py - src/ - __init__.py - foo.py - bar.py - -an appropriate setup script would be :: - - from distutils.core import setup - setup(name='foobar', - version='1.0', - package_dir={'foobar': 'src'}, - packages=['foobar'], - ) - -Or, you might put modules from your main package right in the distribution -root:: - - <root>/ - setup.py - __init__.py - foo.py - bar.py - -in which case your setup script would be :: - - from distutils.core import setup - setup(name='foobar', - version='1.0', - package_dir={'foobar': ''}, - packages=['foobar'], - ) - -(The empty string also stands for the current directory.) - -If you have sub-packages, they must be explicitly listed in ``packages``, -but any entries in ``package_dir`` automatically extend to sub-packages. -(In other words, the Distutils does *not* scan your source tree, trying to -figure out which directories correspond to Python packages by looking for -:file:`__init__.py` files.) Thus, if the default layout grows a sub-package:: - - <root>/ - setup.py - foobar/ - __init__.py - foo.py - bar.py - subfoo/ - __init__.py - blah.py - -then the corresponding setup script would be :: - - from distutils.core import setup - setup(name='foobar', - version='1.0', - packages=['foobar', 'foobar.subfoo'], - ) - - -.. _single-ext: - -Single extension module -======================= - -Extension modules are specified using the ``ext_modules`` option. -``package_dir`` has no effect on where extension source files are found; -it only affects the source for pure Python modules. The simplest case, a -single extension module in a single C source file, is:: - - <root>/ - setup.py - foo.c - -If the :mod:`foo` extension belongs in the root package, the setup script for -this could be :: - - from distutils.core import setup - from distutils.extension import Extension - setup(name='foobar', - version='1.0', - ext_modules=[Extension('foo', ['foo.c'])], - ) - -If the extension actually belongs in a package, say :mod:`foopkg`, then - -With exactly the same source tree layout, this extension can be put in the -:mod:`foopkg` package simply by changing the name of the extension:: - - from distutils.core import setup - from distutils.extension import Extension - setup(name='foobar', - version='1.0', - ext_modules=[Extension('foopkg.foo', ['foo.c'])], - ) - -Checking a package -================== - -The ``check`` command allows you to verify if your package meta-data -meet the minimum requirements to build a distribution. - -To run it, just call it using your :file:`setup.py` script. If something is -missing, ``check`` will display a warning. - -Let's take an example with a simple script:: - - from distutils.core import setup - - setup(name='foobar') - -Running the ``check`` command will display some warnings: - -.. code-block:: shell-session - - $ python setup.py check - running check - warning: check: missing required meta-data: version, url - warning: check: missing meta-data: either (author and author_email) or - (maintainer and maintainer_email) should be supplied - - -If you use the reStructuredText syntax in the ``long_description`` field and -`docutils`_ is installed you can check if the syntax is fine with the -``check`` command, using the ``restructuredtext`` option. - -For example, if the :file:`setup.py` script is changed like this:: - - from distutils.core import setup - - desc = """\ - My description - ============== - - This is the description of the ``foobar`` package. - """ - - setup(name='foobar', version='1', author='tarek', - author_email='tarek@ziade.org', - url='http://example.com', long_description=desc) - -Where the long description is broken, ``check`` will be able to detect it -by using the :mod:`docutils` parser: - -.. code-block:: shell-session - - $ python setup.py check --restructuredtext - running check - warning: check: Title underline too short. (line 2) - warning: check: Could not finish the parsing. - -Reading the metadata -===================== - -The :func:`distutils.core.setup` function provides a command-line interface -that allows you to query the metadata fields of a project through the -``setup.py`` script of a given project: - -.. code-block:: shell-session - - $ python setup.py --name - distribute - -This call reads the ``name`` metadata by running the -:func:`distutils.core.setup` function. Although, when a source or binary -distribution is created with Distutils, the metadata fields are written -in a static file called :file:`PKG-INFO`. When a Distutils-based project is -installed in Python, the :file:`PKG-INFO` file is copied alongside the modules -and packages of the distribution under :file:`NAME-VERSION-pyX.X.egg-info`, -where ``NAME`` is the name of the project, ``VERSION`` its version as defined -in the Metadata, and ``pyX.X`` the major and minor version of Python like -``2.7`` or ``3.2``. - -You can read back this static file, by using the -:class:`distutils.dist.DistributionMetadata` class and its -:func:`read_pkg_file` method:: - - >>> from distutils.dist import DistributionMetadata - >>> metadata = DistributionMetadata() - >>> metadata.read_pkg_file(open('distribute-0.6.8-py2.7.egg-info')) - >>> metadata.name - 'distribute' - >>> metadata.version - '0.6.8' - >>> metadata.description - 'Easily download, build, install, upgrade, and uninstall Python packages' - -Notice that the class can also be instantiated with a metadata file path to -loads its values:: - - >>> pkg_info_path = 'distribute-0.6.8-py2.7.egg-info' - >>> DistributionMetadata(pkg_info_path).name - 'distribute' - - -.. % \section{Multiple extension modules} -.. % \label{multiple-ext} - -.. % \section{Putting it all together} - - -.. _docutils: http://docutils.sourceforge.net diff --git a/Doc/distutils/extending.rst b/Doc/distutils/extending.rst deleted file mode 100644 index 1075e81779a..00000000000 --- a/Doc/distutils/extending.rst +++ /dev/null @@ -1,98 +0,0 @@ -.. _extending-distutils: - -******************* -Extending Distutils -******************* - -.. include:: ./_setuptools_disclaimer.rst - -Distutils can be extended in various ways. Most extensions take the form of new -commands or replacements for existing commands. New commands may be written to -support new types of platform-specific packaging, for example, while -replacements for existing commands may be made to modify details of how the -command operates on a package. - -Most extensions of the distutils are made within :file:`setup.py` scripts that -want to modify existing commands; many simply add a few file extensions that -should be copied into packages in addition to :file:`.py` files as a -convenience. - -Most distutils command implementations are subclasses of the -:class:`distutils.cmd.Command` class. New commands may directly inherit from -:class:`Command`, while replacements often derive from :class:`Command` -indirectly, directly subclassing the command they are replacing. Commands are -required to derive from :class:`Command`. - -.. % \section{Extending existing commands} -.. % \label{extend-existing} - -.. % \section{Writing new commands} -.. % \label{new-commands} -.. % \XXX{Would an uninstall command be a good example here?} - - -Integrating new commands -======================== - -There are different ways to integrate new command implementations into -distutils. The most difficult is to lobby for the inclusion of the new features -in distutils itself, and wait for (and require) a version of Python that -provides that support. This is really hard for many reasons. - -The most common, and possibly the most reasonable for most needs, is to include -the new implementations with your :file:`setup.py` script, and cause the -:func:`distutils.core.setup` function use them:: - - from distutils.command.build_py import build_py as _build_py - from distutils.core import setup - - class build_py(_build_py): - """Specialized Python source builder.""" - - # implement whatever needs to be different... - - setup(cmdclass={'build_py': build_py}, - ...) - -This approach is most valuable if the new implementations must be used to use a -particular package, as everyone interested in the package will need to have the -new command implementation. - -Beginning with Python 2.4, a third option is available, intended to allow new -commands to be added which can support existing :file:`setup.py` scripts without -requiring modifications to the Python installation. This is expected to allow -third-party extensions to provide support for additional packaging systems, but -the commands can be used for anything distutils commands can be used for. A new -configuration option, ``command_packages`` (command-line option -:option:`!--command-packages`), can be used to specify additional packages to be -searched for modules implementing commands. Like all distutils options, this -can be specified on the command line or in a configuration file. This option -can only be set in the ``[global]`` section of a configuration file, or before -any commands on the command line. If set in a configuration file, it can be -overridden from the command line; setting it to an empty string on the command -line causes the default to be used. This should never be set in a configuration -file provided with a package. - -This new option can be used to add any number of packages to the list of -packages searched for command implementations; multiple package names should be -separated by commas. When not specified, the search is only performed in the -:mod:`distutils.command` package. When :file:`setup.py` is run with the option -``--command-packages distcmds,buildcmds``, however, the packages -:mod:`distutils.command`, :mod:`distcmds`, and :mod:`buildcmds` will be searched -in that order. New commands are expected to be implemented in modules of the -same name as the command by classes sharing the same name. Given the example -command line option above, the command :command:`bdist_openpkg` could be -implemented by the class :class:`distcmds.bdist_openpkg.bdist_openpkg` or -:class:`buildcmds.bdist_openpkg.bdist_openpkg`. - - -Adding new distribution types -============================= - -Commands that create distributions (files in the :file:`dist/` directory) need -to add ``(command, filename)`` pairs to ``self.distribution.dist_files`` so that -:command:`upload` can upload it to PyPI. The *filename* in the pair contains no -path information, only the name of the file itself. In dry-run mode, pairs -should still be added to represent what would have been created. - - diff --git a/Doc/distutils/index.rst b/Doc/distutils/index.rst deleted file mode 100644 index 2ccddc38b5f..00000000000 --- a/Doc/distutils/index.rst +++ /dev/null @@ -1,49 +0,0 @@ -.. _distutils-index: - -############################################## - Distributing Python Modules (Legacy version) -############################################## - -:Authors: Greg Ward, Anthony Baxter -:Email: distutils-sig@python.org - -.. seealso:: - - :ref:`distributing-index` - The up to date module distribution documentations - -.. note:: - - The entire ``distutils`` package has been deprecated and will be - removed in Python 3.12. This documentation is retained as a - reference only, and will be removed with the package. See the - :ref:`What's New <distutils-deprecated>` entry for more information. - -.. include:: ./_setuptools_disclaimer.rst - -.. note:: - - This guide only covers the basic tools for building and distributing - extensions that are provided as part of this version of Python. Third party - tools offer easier to use and more secure alternatives. Refer to the `quick - recommendations section <https://packaging.python.org/guides/tool-recommendations/>`__ - in the Python Packaging User Guide for more information. - -This document describes the Python Distribution Utilities ("Distutils") from -the module developer's point of view, describing the underlying capabilities -that ``setuptools`` builds on to allow Python developers to make Python modules -and extensions readily available to a wider audience. - -.. toctree:: - :maxdepth: 2 - :numbered: - - introduction.rst - setupscript.rst - configfile.rst - sourcedist.rst - builtdist.rst - examples.rst - extending.rst - commandref.rst - apiref.rst diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst deleted file mode 100644 index 87ed178e52b..00000000000 --- a/Doc/distutils/introduction.rst +++ /dev/null @@ -1,203 +0,0 @@ -.. _distutils-intro: - -**************************** -An Introduction to Distutils -**************************** - -.. include:: ./_setuptools_disclaimer.rst - -This document covers using the Distutils to distribute your Python modules, -concentrating on the role of developer/distributor: if you're looking for -information on installing Python modules, you should refer to the -:ref:`install-index` chapter. - - -.. _distutils-concepts: - -Concepts & Terminology -====================== - -Using the Distutils is quite simple, both for module developers and for -users/administrators installing third-party modules. As a developer, your -responsibilities (apart from writing solid, well-documented and well-tested -code, of course!) are: - -* write a setup script (:file:`setup.py` by convention) - -* (optional) write a setup configuration file - -* create a source distribution - -* (optional) create one or more built (binary) distributions - -Each of these tasks is covered in this document. - -Not all module developers have access to a multitude of platforms, so it's not -always feasible to expect them to create a multitude of built distributions. It -is hoped that a class of intermediaries, called *packagers*, will arise to -address this need. Packagers will take source distributions released by module -developers, build them on one or more platforms, and release the resulting built -distributions. Thus, users on the most popular platforms will be able to -install most popular Python module distributions in the most natural way for -their platform, without having to run a single setup script or compile a line of -code. - - -.. _distutils-simple-example: - -A Simple Example -================ - -The setup script is usually quite simple, although since it's written in Python, -there are no arbitrary limits to what you can do with it, though you should be -careful about putting arbitrarily expensive operations in your setup script. -Unlike, say, Autoconf-style configure scripts, the setup script may be run -multiple times in the course of building and installing your module -distribution. - -If all you want to do is distribute a module called :mod:`foo`, contained in a -file :file:`foo.py`, then your setup script can be as simple as this:: - - from distutils.core import setup - setup(name='foo', - version='1.0', - py_modules=['foo'], - ) - -Some observations: - -* most information that you supply to the Distutils is supplied as keyword - arguments to the :func:`setup` function - -* those keyword arguments fall into two categories: package metadata (name, - version number) and information about what's in the package (a list of pure - Python modules, in this case) - -* modules are specified by module name, not filename (the same will hold true - for packages and extensions) - -* it's recommended that you supply a little more metadata, in particular your - name, email address and a URL for the project (see section :ref:`setup-script` - for an example) - -To create a source distribution for this module, you would create a setup -script, :file:`setup.py`, containing the above code, and run this command from a -terminal:: - - python setup.py sdist - -For Windows, open a command prompt window (:menuselection:`Start --> -Accessories`) and change the command to:: - - setup.py sdist - -:command:`sdist` will create an archive file (e.g., tarball on Unix, ZIP file on Windows) -containing your setup script :file:`setup.py`, and your module :file:`foo.py`. -The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and -will unpack into a directory :file:`foo-1.0`. - -If an end-user wishes to install your :mod:`foo` module, all they have to do is -download :file:`foo-1.0.tar.gz` (or :file:`.zip`), unpack it, and---from the -:file:`foo-1.0` directory---run :: - - python setup.py install - -which will ultimately copy :file:`foo.py` to the appropriate directory for -third-party modules in their Python installation. - -This simple example demonstrates some fundamental concepts of the Distutils. -First, both developers and installers have the same basic user interface, i.e. -the setup script. The difference is which Distutils *commands* they use: the -:command:`sdist` command is almost exclusively for module developers, while -:command:`install` is more often for installers (although most developers will -want to install their own code occasionally). - -Other useful built distribution formats are RPM, implemented by the -:command:`bdist_rpm` command, Solaris :program:`pkgtool` -(:command:`bdist_pkgtool`), and HP-UX :program:`swinstall` -(:command:`bdist_sdux`). For example, the following command will create an RPM -file called :file:`foo-1.0.noarch.rpm`:: - - python setup.py bdist_rpm - -(The :command:`bdist_rpm` command uses the :command:`rpm` executable, therefore -this has to be run on an RPM-based system such as Red Hat Linux, SuSE Linux, or -Mandrake Linux.) - -You can find out what distribution formats are available at any time by running -:: - - python setup.py bdist --help-formats - - -.. _python-terms: - -General Python terminology -========================== - -If you're reading this document, you probably have a good idea of what modules, -extensions, and so forth are. Nevertheless, just to be sure that everyone is -operating from a common starting point, we offer the following glossary of -common Python terms: - -module - the basic unit of code reusability in Python: a block of code imported by some - other code. Three types of modules concern us here: pure Python modules, - extension modules, and packages. - -pure Python module - a module written in Python and contained in a single :file:`.py` file (and - possibly associated :file:`.pyc` files). Sometimes referred to as a - "pure module." - -extension module - a module written in the low-level language of the Python implementation: C/C++ - for Python, Java for Jython. Typically contained in a single dynamically - loadable pre-compiled file, e.g. a shared object (:file:`.so`) file for Python - extensions on Unix, a DLL (given the :file:`.pyd` extension) for Python - extensions on Windows, or a Java class file for Jython extensions. (Note that - currently, the Distutils only handles C/C++ extensions for Python.) - -package - a module that contains other modules; typically contained in a directory in the - filesystem and distinguished from other directories by the presence of a file - :file:`__init__.py`. - -root package - the root of the hierarchy of packages. (This isn't really a package, since it - doesn't have an :file:`__init__.py` file. But we have to call it something.) - The vast majority of the standard library is in the root package, as are many - small, standalone third-party modules that don't belong to a larger module - collection. Unlike regular packages, modules in the root package can be found in - many directories: in fact, every directory listed in ``sys.path`` contributes - modules to the root package. - - -.. _distutils-term: - -Distutils-specific terminology -============================== - -The following terms apply more specifically to the domain of distributing Python -modules using the Distutils: - -module distribution - a collection of Python modules distributed together as a single downloadable - resource and meant to be installed *en masse*. Examples of some well-known - module distributions are NumPy, SciPy, Pillow, - or mxBase. (This would be called a *package*, except that term is - already taken in the Python context: a single module distribution may contain - zero, one, or many Python packages.) - -pure module distribution - a module distribution that contains only pure Python modules and packages. - Sometimes referred to as a "pure distribution." - -non-pure module distribution - a module distribution that contains at least one extension module. Sometimes - referred to as a "non-pure distribution." - -distribution root - the top-level directory of your source tree (or source distribution); the - directory where :file:`setup.py` exists. Generally :file:`setup.py` will be - run from this directory. diff --git a/Doc/distutils/packageindex.rst b/Doc/distutils/packageindex.rst deleted file mode 100644 index ccb9a598b2b..00000000000 --- a/Doc/distutils/packageindex.rst +++ /dev/null @@ -1,16 +0,0 @@ -:orphan: - -.. _package-index: - -******************************* -The Python Package Index (PyPI) -******************************* - -The `Python Package Index (PyPI)`_ stores metadata describing distributions -packaged with distutils and other publishing tools, as well the distribution -archives themselves. - -References to up to date PyPI documentation can be found at -:ref:`publishing-python-packages`. - -.. _Python Package Index (PyPI): https://pypi.org diff --git a/Doc/distutils/setupscript.rst b/Doc/distutils/setupscript.rst deleted file mode 100644 index 4386a60b664..00000000000 --- a/Doc/distutils/setupscript.rst +++ /dev/null @@ -1,713 +0,0 @@ -.. _setup-script: - -************************ -Writing the Setup Script -************************ - -.. include:: ./_setuptools_disclaimer.rst - -The setup script is the centre of all activity in building, distributing, and -installing modules using the Distutils. The main purpose of the setup script is -to describe your module distribution to the Distutils, so that the various -commands that operate on your modules do the right thing. As we saw in section -:ref:`distutils-simple-example` above, the setup script consists mainly of a call to -:func:`setup`, and most information supplied to the Distutils by the module -developer is supplied as keyword arguments to :func:`setup`. - -Here's a slightly more involved example, which we'll follow for the next couple -of sections: the Distutils' own setup script. (Keep in mind that although the -Distutils are included with Python 1.6 and later, they also have an independent -existence so that Python 1.5.2 users can use them to install other module -distributions. The Distutils' own setup script, shown here, is used to install -the package into Python 1.5.2.) :: - - #!/usr/bin/env python - - from distutils.core import setup - - setup(name='Distutils', - version='1.0', - description='Python Distribution Utilities', - author='Greg Ward', - author_email='gward@python.net', - url='https://www.python.org/sigs/distutils-sig/', - packages=['distutils', 'distutils.command'], - ) - -There are only two differences between this and the trivial one-file -distribution presented in section :ref:`distutils-simple-example`: more metadata, and the -specification of pure Python modules by package, rather than by module. This is -important since the Distutils consist of a couple of dozen modules split into -(so far) two packages; an explicit list of every module would be tedious to -generate and difficult to maintain. For more information on the additional -meta-data, see section :ref:`meta-data`. - -Note that any pathnames (files or directories) supplied in the setup script -should be written using the Unix convention, i.e. slash-separated. The -Distutils will take care of converting this platform-neutral representation into -whatever is appropriate on your current platform before actually using the -pathname. This makes your setup script portable across operating systems, which -of course is one of the major goals of the Distutils. In this spirit, all -pathnames in this document are slash-separated. - -This, of course, only applies to pathnames given to Distutils functions. If -you, for example, use standard Python functions such as :func:`glob.glob` or -:func:`os.listdir` to specify files, you should be careful to write portable -code instead of hardcoding path separators:: - - glob.glob(os.path.join('mydir', 'subdir', '*.html')) - os.listdir(os.path.join('mydir', 'subdir')) - - -.. _listing-packages: - -Listing whole packages -====================== - -The ``packages`` option tells the Distutils to process (build, distribute, -install, etc.) all pure Python modules found in each package mentioned in the -``packages`` list. In order to do this, of course, there has to be a -correspondence between package names and directories in the filesystem. The -default correspondence is the most obvious one, i.e. package :mod:`distutils` is -found in the directory :file:`distutils` relative to the distribution root. -Thus, when you say ``packages = ['foo']`` in your setup script, you are -promising that the Distutils will find a file :file:`foo/__init__.py` (which -might be spelled differently on your system, but you get the idea) relative to -the directory where your setup script lives. If you break this promise, the -Distutils will issue a warning but still process the broken package anyway. - -If you use a different convention to lay out your source directory, that's no -problem: you just have to supply the ``package_dir`` option to tell the -Distutils about your convention. For example, say you keep all Python source -under :file:`lib`, so that modules in the "root package" (i.e., not in any -package at all) are in :file:`lib`, modules in the :mod:`foo` package are in -:file:`lib/foo`, and so forth. Then you would put :: - - package_dir = {'': 'lib'} - -in your setup script. The keys to this dictionary are package names, and an -empty package name stands for the root package. The values are directory names -relative to your distribution root. In this case, when you say ``packages = -['foo']``, you are promising that the file :file:`lib/foo/__init__.py` exists. - -Another possible convention is to put the :mod:`foo` package right in -:file:`lib`, the :mod:`foo.bar` package in :file:`lib/bar`, etc. This would be -written in the setup script as :: - - package_dir = {'foo': 'lib'} - -A ``package: dir`` entry in the ``package_dir`` dictionary implicitly -applies to all packages below *package*, so the :mod:`foo.bar` case is -automatically handled here. In this example, having ``packages = ['foo', -'foo.bar']`` tells the Distutils to look for :file:`lib/__init__.py` and -:file:`lib/bar/__init__.py`. (Keep in mind that although ``package_dir`` -applies recursively, you must explicitly list all packages in -``packages``: the Distutils will *not* recursively scan your source tree -looking for any directory with an :file:`__init__.py` file.) - - -.. _listing-modules: - -Listing individual modules -========================== - -For a small module distribution, you might prefer to list all modules rather -than listing packages---especially the case of a single module that goes in the -"root package" (i.e., no package at all). This simplest case was shown in -section :ref:`distutils-simple-example`; here is a slightly more involved example:: - - py_modules = ['mod1', 'pkg.mod2'] - -This describes two modules, one of them in the "root" package, the other in the -:mod:`pkg` package. Again, the default package/directory layout implies that -these two modules can be found in :file:`mod1.py` and :file:`pkg/mod2.py`, and -that :file:`pkg/__init__.py` exists as well. And again, you can override the -package/directory correspondence using the ``package_dir`` option. - - -.. _describing-extensions: - -Describing extension modules -============================ - -Just as writing Python extension modules is a bit more complicated than writing -pure Python modules, describing them to the Distutils is a bit more complicated. -Unlike pure modules, it's not enough just to list modules or packages and expect -the Distutils to go out and find the right files; you have to specify the -extension name, source file(s), and any compile/link requirements (include -directories, libraries to link with, etc.). - -.. XXX read over this section - -All of this is done through another keyword argument to :func:`setup`, the -``ext_modules`` option. ``ext_modules`` is just a list of -:class:`~distutils.core.Extension` instances, each of which describes a -single extension module. -Suppose your distribution includes a single extension, called :mod:`foo` and -implemented by :file:`foo.c`. If no additional instructions to the -compiler/linker are needed, describing this extension is quite simple:: - - Extension('foo', ['foo.c']) - -The :class:`Extension` class can be imported from :mod:`distutils.core` along -with :func:`setup`. Thus, the setup script for a module distribution that -contains only this one extension and nothing else might be:: - - from distutils.core import setup, Extension - setup(name='foo', - version='1.0', - ext_modules=[Extension('foo', ['foo.c'])], - ) - -The :class:`Extension` class (actually, the underlying extension-building -machinery implemented by the :command:`build_ext` command) supports a great deal -of flexibility in describing Python extensions, which is explained in the -following sections. - - -Extension names and packages ----------------------------- - -The first argument to the :class:`~distutils.core.Extension` constructor is -always the name of the extension, including any package names. For example, :: - - Extension('foo', ['src/foo1.c', 'src/foo2.c']) - -describes an extension that lives in the root package, while :: - - Extension('pkg.foo', ['src/foo1.c', 'src/foo2.c']) - -describes the same extension in the :mod:`pkg` package. The source files and -resulting object code are identical in both cases; the only difference is where -in the filesystem (and therefore where in Python's namespace hierarchy) the -resulting extension lives. - -If you have a number of extensions all in the same package (or all under the -same base package), use the ``ext_package`` keyword argument to -:func:`setup`. For example, :: - - setup(..., - ext_package='pkg', - ext_modules=[Extension('foo', ['foo.c']), - Extension('subpkg.bar', ['bar.c'])], - ) - -will compile :file:`foo.c` to the extension :mod:`pkg.foo`, and :file:`bar.c` to -:mod:`pkg.subpkg.bar`. - - -Extension source files ----------------------- - -The second argument to the :class:`~distutils.core.Extension` constructor is -a list of source -files. Since the Distutils currently only support C, C++, and Objective-C -extensions, these are normally C/C++/Objective-C source files. (Be sure to use -appropriate extensions to distinguish C++ source files: :file:`.cc` and -:file:`.cpp` seem to be recognized by both Unix and Windows compilers.) - -However, you can also include SWIG interface (:file:`.i`) files in the list; the -:command:`build_ext` command knows how to deal with SWIG extensions: it will run -SWIG on the interface file and compile the resulting C/C++ file into your -extension. - -.. XXX SWIG support is rough around the edges and largely untested! - -This warning notwithstanding, options to SWIG can be currently passed like -this:: - - setup(..., - ext_modules=[Extension('_foo', ['foo.i'], - swig_opts=['-modern', '-I../include'])], - py_modules=['foo'], - ) - -Or on the commandline like this:: - - > python setup.py build_ext --swig-opts="-modern -I../include" - -On some platforms, you can include non-source files that are processed by the -compiler and included in your extension. Currently, this just means Windows -message text (:file:`.mc`) files and resource definition (:file:`.rc`) files for -Visual C++. These will be compiled to binary resource (:file:`.res`) files and -linked into the executable. - - -Preprocessor options --------------------- - -Three optional arguments to :class:`~distutils.core.Extension` will help if -you need to specify include directories to search or preprocessor macros to -define/undefine: ``include_dirs``, ``define_macros``, and ``undef_macros``. - -For example, if your extension requires header files in the :file:`include` -directory under your distribution root, use the ``include_dirs`` option:: - - Extension('foo', ['foo.c'], include_dirs=['include']) - -You can specify absolute directories there; if you know that your extension will -only be built on Unix systems with X11R6 installed to :file:`/usr`, you can get -away with :: - - Extension('foo', ['foo.c'], include_dirs=['/usr/include/X11']) - -You should avoid this sort of non-portable usage if you plan to distribute your -code: it's probably better to write C code like :: - - #include <X11/Xlib.h> - -If you need to include header files from some other Python extension, you can -take advantage of the fact that header files are installed in a consistent way -by the Distutils :command:`install_headers` command. For example, the Numerical -Python header files are installed (on a standard Unix installation) to -:file:`/usr/local/include/python1.5/Numerical`. (The exact location will differ -according to your platform and Python installation.) Since the Python include -directory---\ :file:`/usr/local/include/python1.5` in this case---is always -included in the search path when building Python extensions, the best approach -is to write C code like :: - - #include <Numerical/arrayobject.h> - -If you must put the :file:`Numerical` include directory right into your header -search path, though, you can find that directory using the Distutils -:mod:`distutils.sysconfig` module:: - - from distutils.sysconfig import get_python_inc - incdir = os.path.join(get_python_inc(plat_specific=1), 'Numerical') - setup(..., - Extension(..., include_dirs=[incdir]), - ) - -Even though this is quite portable---it will work on any Python installation, -regardless of platform---it's probably easier to just write your C code in the -sensible way. - -You can define and undefine pre-processor macros with the ``define_macros`` and -``undef_macros`` options. ``define_macros`` takes a list of ``(name, value)`` -tuples, where ``name`` is the name of the macro to define (a string) and -``value`` is its value: either a string or ``None``. (Defining a macro ``FOO`` -to ``None`` is the equivalent of a bare ``#define FOO`` in your C source: with -most compilers, this sets ``FOO`` to the string ``1``.) ``undef_macros`` is -just a list of macros to undefine. - -For example:: - - Extension(..., - define_macros=[('NDEBUG', '1'), - ('HAVE_STRFTIME', None)], - undef_macros=['HAVE_FOO', 'HAVE_BAR']) - -is the equivalent of having this at the top of every C source file:: - - #define NDEBUG 1 - #define HAVE_STRFTIME - #undef HAVE_FOO - #undef HAVE_BAR - - -Library options ---------------- - -You can also specify the libraries to link against when building your extension, -and the directories to search for those libraries. The ``libraries`` option is -a list of libraries to link against, ``library_dirs`` is a list of directories -to search for libraries at link-time, and ``runtime_library_dirs`` is a list of -directories to search for shared (dynamically loaded) libraries at run-time. - -For example, if you need to link against libraries known to be in the standard -library search path on target systems :: - - Extension(..., - libraries=['gdbm', 'readline']) - -If you need to link with libraries in a non-standard location, you'll have to -include the location in ``library_dirs``:: - - Extension(..., - library_dirs=['/usr/X11R6/lib'], - libraries=['X11', 'Xt']) - -(Again, this sort of non-portable construct should be avoided if you intend to -distribute your code.) - -.. XXX Should mention clib libraries here or somewhere else! - - -Other options -------------- - -There are still some other options which can be used to handle special cases. - -The ``optional`` option is a boolean; if it is true, -a build failure in the extension will not abort the build process, but -instead simply not install the failing extension. - -The ``extra_objects`` option is a list of object files to be passed to the -linker. These files must not have extensions, as the default extension for the -compiler is used. - -``extra_compile_args`` and ``extra_link_args`` can be used to -specify additional command line options for the respective compiler and linker -command lines. - -``export_symbols`` is only useful on Windows. It can contain a list of -symbols (functions or variables) to be exported. This option is not needed when -building compiled extensions: Distutils will automatically add ``initmodule`` -to the list of exported symbols. - -The ``depends`` option is a list of files that the extension depends on -(for example header files). The build command will call the compiler on the -sources to rebuild extension if any on this files has been modified since the -previous build. - -Relationships between Distributions and Packages -================================================ - -A distribution may relate to packages in three specific ways: - -#. It can require packages or modules. - -#. It can provide packages or modules. - -#. It can obsolete packages or modules. - -These relationships can be specified using keyword arguments to the -:func:`distutils.core.setup` function. - -Dependencies on other Python modules and packages can be specified by supplying -the *requires* keyword argument to :func:`setup`. The value must be a list of -strings. Each string specifies a package that is required, and optionally what -versions are sufficient. - -To specify that any version of a module or package is required, the string -should consist entirely of the module or package name. Examples include -``'mymodule'`` and ``'xml.parsers.expat'``. - -If specific versions are required, a sequence of qualifiers can be supplied in -parentheses. Each qualifier may consist of a comparison operator and a version -number. The accepted comparison operators are:: - - < > == - <= >= != - -These can be combined by using multiple qualifiers separated by commas (and -optional whitespace). In this case, all of the qualifiers must be matched; a -logical AND is used to combine the evaluations. - -Let's look at a bunch of examples: - -+-------------------------+----------------------------------------------+ -| Requires Expression | Explanation | -+=========================+==============================================+ -| ``==1.0`` | Only version ``1.0`` is compatible | -+-------------------------+----------------------------------------------+ -| ``>1.0, !=1.5.1, <2.0`` | Any version after ``1.0`` and before ``2.0`` | -| | is compatible, except ``1.5.1`` | -+-------------------------+----------------------------------------------+ - -Now that we can specify dependencies, we also need to be able to specify what we -provide that other distributions can require. This is done using the *provides* -keyword argument to :func:`setup`. The value for this keyword is a list of -strings, each of which names a Python module or package, and optionally -identifies the version. If the version is not specified, it is assumed to match -that of the distribution. - -Some examples: - -+---------------------+----------------------------------------------+ -| Provides Expression | Explanation | -+=====================+==============================================+ -| ``mypkg`` | Provide ``mypkg``, using the distribution | -| | version | -+---------------------+----------------------------------------------+ -| ``mypkg (1.1)`` | Provide ``mypkg`` version 1.1, regardless of | -| | the distribution version | -+---------------------+----------------------------------------------+ - -A package can declare that it obsoletes other packages using the *obsoletes* -keyword argument. The value for this is similar to that of the *requires* -keyword: a list of strings giving module or package specifiers. Each specifier -consists of a module or package name optionally followed by one or more version -qualifiers. Version qualifiers are given in parentheses after the module or -package name. - -The versions identified by the qualifiers are those that are obsoleted by the -distribution being described. If no qualifiers are given, all versions of the -named module or package are understood to be obsoleted. - -.. _distutils-installing-scripts: - -Installing Scripts -================== - -So far we have been dealing with pure and non-pure Python modules, which are -usually not run by themselves but imported by scripts. - -Scripts are files containing Python source code, intended to be started from the -command line. Scripts don't require Distutils to do anything very complicated. -The only clever feature is that if the first line of the script starts with -``#!`` and contains the word "python", the Distutils will adjust the first line -to refer to the current interpreter location. By default, it is replaced with -the current interpreter location. The :option:`!--executable` (or :option:`!-e`) -option will allow the interpreter path to be explicitly overridden. - -The ``scripts`` option simply is a list of files to be handled in this -way. From the PyXML setup script:: - - setup(..., - scripts=['scripts/xmlproc_parse', 'scripts/xmlproc_val'] - ) - -.. versionchanged:: 3.1 - All the scripts will also be added to the ``MANIFEST`` file if no template is - provided. See :ref:`manifest`. - - -.. _distutils-installing-package-data: - -Installing Package Data -======================= - -Often, additional files need to be installed into a package. These files are -often data that's closely related to the package's implementation, or text files -containing documentation that might be of interest to programmers using the -package. These files are called :dfn:`package data`. - -Package data can be added to packages using the ``package_data`` keyword -argument to the :func:`setup` function. The value must be a mapping from -package name to a list of relative path names that should be copied into the -package. The paths are interpreted as relative to the directory containing the -package (information from the ``package_dir`` mapping is used if appropriate); -that is, the files are expected to be part of the package in the source -directories. They may contain glob patterns as well. - -The path names may contain directory portions; any necessary directories will be -created in the installation. - -For example, if a package should contain a subdirectory with several data files, -the files can be arranged like this in the source tree:: - - setup.py - src/ - mypkg/ - __init__.py - module.py - data/ - tables.dat - spoons.dat - forks.dat - -The corresponding call to :func:`setup` might be:: - - setup(..., - packages=['mypkg'], - package_dir={'mypkg': 'src/mypkg'}, - package_data={'mypkg': ['data/*.dat']}, - ) - - -.. versionchanged:: 3.1 - All the files that match ``package_data`` will be added to the ``MANIFEST`` - file if no template is provided. See :ref:`manifest`. - - -.. _distutils-additional-files: - -Installing Additional Files -=========================== - -The ``data_files`` option can be used to specify additional files needed -by the module distribution: configuration files, message catalogs, data files, -anything which doesn't fit in the previous categories. - -``data_files`` specifies a sequence of (*directory*, *files*) pairs in the -following way:: - - setup(..., - data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']), - ('config', ['cfg/data.cfg'])], - ) - -Each (*directory*, *files*) pair in the sequence specifies the installation -directory and the files to install there. - -Each file name in *files* is interpreted relative to the :file:`setup.py` -script at the top of the package source distribution. Note that you can -specify the directory where the data files will be installed, but you cannot -rename the data files themselves. - -The *directory* should be a relative path. It is interpreted relative to the -installation prefix (Python's ``sys.prefix`` for system installations; -``site.USER_BASE`` for user installations). Distutils allows *directory* to be -an absolute installation path, but this is discouraged since it is -incompatible with the wheel packaging format. No directory information from -*files* is used to determine the final location of the installed file; only -the name of the file is used. - -You can specify the ``data_files`` options as a simple sequence of files -without specifying a target directory, but this is not recommended, and the -:command:`install` command will print a warning in this case. To install data -files directly in the target directory, an empty string should be given as the -directory. - -.. versionchanged:: 3.1 - All the files that match ``data_files`` will be added to the ``MANIFEST`` - file if no template is provided. See :ref:`manifest`. - - -.. _meta-data: - -Additional meta-data -==================== - -The setup script may include additional meta-data beyond the name and version. -This information includes: - -+----------------------+---------------------------+-----------------+--------+ -| Meta-Data | Description | Value | Notes | -+======================+===========================+=================+========+ -| ``name`` | name of the package | short string | \(1) | -+----------------------+---------------------------+-----------------+--------+ -| ``version`` | version of this release | short string | (1)(2) | -+----------------------+---------------------------+-----------------+--------+ -| ``author`` | package author's name | short string | \(3) | -+----------------------+---------------------------+-----------------+--------+ -| ``author_email`` | email address of the | email address | \(3) | -| | package author | | | -+----------------------+---------------------------+-----------------+--------+ -| ``maintainer`` | package maintainer's name | short string | \(3) | -+----------------------+---------------------------+-----------------+--------+ -| ``maintainer_email`` | email address of the | email address | \(3) | -| | package maintainer | | | -+----------------------+---------------------------+-----------------+--------+ -| ``url`` | home page for the package | URL | \(1) | -+----------------------+---------------------------+-----------------+--------+ -| ``description`` | short, summary | short string | | -| | description of the | | | -| | package | | | -+----------------------+---------------------------+-----------------+--------+ -| ``long_description`` | longer description of the | long string | \(4) | -| | package | | | -+----------------------+---------------------------+-----------------+--------+ -| ``download_url`` | location where the | URL | | -| | package may be downloaded | | | -+----------------------+---------------------------+-----------------+--------+ -| ``classifiers`` | a list of classifiers | list of strings | (6)(7) | -+----------------------+---------------------------+-----------------+--------+ -| ``platforms`` | a list of platforms | list of strings | (6)(8) | -+----------------------+---------------------------+-----------------+--------+ -| ``keywords`` | a list of keywords | list of strings | (6)(8) | -+----------------------+---------------------------+-----------------+--------+ -| ``license`` | license for the package | short string | \(5) | -+----------------------+---------------------------+-----------------+--------+ - -Notes: - -(1) - These fields are required. - -(2) - It is recommended that versions take the form *major.minor[.patch[.sub]]*. - -(3) - Either the author or the maintainer must be identified. If maintainer is - provided, distutils lists it as the author in :file:`PKG-INFO`. - -(4) - The ``long_description`` field is used by PyPI when you publish a package, - to build its project page. - -(5) - The ``license`` field is a text indicating the license covering the - package where the license is not a selection from the "License" Trove - classifiers. See the ``Classifier`` field. Notice that - there's a ``licence`` distribution option which is deprecated but still - acts as an alias for ``license``. - -(6) - This field must be a list. - -(7) - The valid classifiers are listed on - `PyPI <https://pypi.org/classifiers>`_. - -(8) - To preserve backward compatibility, this field also accepts a string. If - you pass a comma-separated string ``'foo, bar'``, it will be converted to - ``['foo', 'bar']``, Otherwise, it will be converted to a list of one - string. - -'short string' - A single line of text, not more than 200 characters. - -'long string' - Multiple lines of plain text in reStructuredText format (see - http://docutils.sourceforge.net/). - -'list of strings' - See below. - -Encoding the version information is an art in itself. Python packages generally -adhere to the version format *major.minor[.patch][sub]*. The major number is 0 -for initial, experimental releases of software. It is incremented for releases -that represent major milestones in a package. The minor number is incremented -when important new features are added to the package. The patch number -increments when bug-fix releases are made. Additional trailing version -information is sometimes used to indicate sub-releases. These are -"a1,a2,...,aN" (for alpha releases, where functionality and API may change), -"b1,b2,...,bN" (for beta releases, which only fix bugs) and "pr1,pr2,...,prN" -(for final pre-release release testing). Some examples: - -0.1.0 - the first, experimental release of a package - -1.0.1a2 - the second alpha release of the first patch version of 1.0 - -``classifiers`` must be specified in a list:: - - setup(..., - classifiers=[ - 'Development Status :: 4 - Beta', - 'Environment :: Console', - 'Environment :: Web Environment', - 'Intended Audience :: End Users/Desktop', - 'Intended Audience :: Developers', - 'Intended Audience :: System Administrators', - 'License :: OSI Approved :: Python Software Foundation License', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: POSIX', - 'Programming Language :: Python', - 'Topic :: Communications :: Email', - 'Topic :: Office/Business', - 'Topic :: Software Development :: Bug Tracking', - ], - ) - -.. versionchanged:: 3.7 - :class:`~distutils.core.setup` now warns when ``classifiers``, ``keywords`` - or ``platforms`` fields are not specified as a list or a string. - -.. _debug-setup-script: - -Debugging the setup script -========================== - -Sometimes things go wrong, and the setup script doesn't do what the developer -wants. - -Distutils catches any exceptions when running the setup script, and print a -simple error message before the script is terminated. The motivation for this -behaviour is to not confuse administrators who don't know much about Python and -are trying to install a package. If they get a big long traceback from deep -inside the guts of Distutils, they may think the package or the Python -installation is broken because they don't read all the way down to the bottom -and see that it's a permission problem. - -On the other hand, this doesn't help the developer to find the cause of the -failure. For this purpose, the :envvar:`DISTUTILS_DEBUG` environment variable can be set -to anything except an empty string, and distutils will now print detailed -information about what it is doing, dump the full traceback when an exception -occurs, and print the whole command line when an external program (like a C -compiler) fails. diff --git a/Doc/distutils/sourcedist.rst b/Doc/distutils/sourcedist.rst deleted file mode 100644 index 0600663d00e..00000000000 --- a/Doc/distutils/sourcedist.rst +++ /dev/null @@ -1,242 +0,0 @@ -.. _source-dist: - -****************************** -Creating a Source Distribution -****************************** - -.. include:: ./_setuptools_disclaimer.rst - -As shown in section :ref:`distutils-simple-example`, you use the :command:`sdist` command -to create a source distribution. In the simplest case, :: - - python setup.py sdist - -(assuming you haven't specified any :command:`sdist` options in the setup script -or config file), :command:`sdist` creates the archive of the default format for -the current platform. The default format is a gzip'ed tar file -(:file:`.tar.gz`) on Unix, and ZIP file on Windows. - -You can specify as many formats as you like using the :option:`!--formats` -option, for example:: - - python setup.py sdist --formats=gztar,zip - -to create a gzipped tarball and a zip file. The available formats are: - -+-----------+-------------------------+---------+ -| Format | Description | Notes | -+===========+=========================+=========+ -| ``zip`` | zip file (:file:`.zip`) | (1),(3) | -+-----------+-------------------------+---------+ -| ``gztar`` | gzip'ed tar file | \(2) | -| | (:file:`.tar.gz`) | | -+-----------+-------------------------+---------+ -| ``bztar`` | bzip2'ed tar file | | -| | (:file:`.tar.bz2`) | | -+-----------+-------------------------+---------+ -| ``xztar`` | xz'ed tar file | | -| | (:file:`.tar.xz`) | | -+-----------+-------------------------+---------+ -| ``ztar`` | compressed tar file | \(4) | -| | (:file:`.tar.Z`) | | -+-----------+-------------------------+---------+ -| ``tar`` | tar file (:file:`.tar`) | | -+-----------+-------------------------+---------+ - -.. versionchanged:: 3.5 - Added support for the ``xztar`` format. - -Notes: - -(1) - default on Windows - -(2) - default on Unix - -(3) - requires either external :program:`zip` utility or :mod:`zipfile` module (part - of the standard Python library since Python 1.6) - -(4) - requires the :program:`compress` program. Notice that this format is now - pending for deprecation and will be removed in the future versions of Python. - -When using any ``tar`` format (``gztar``, ``bztar``, ``xztar``, ``ztar`` or -``tar``), under Unix you can specify the ``owner`` and ``group`` names -that will be set for each member of the archive. - -For example, if you want all files of the archive to be owned by root:: - - python setup.py sdist --owner=root --group=root - - -.. _manifest: - -Specifying the files to distribute -================================== - -If you don't supply an explicit list of files (or instructions on how to -generate one), the :command:`sdist` command puts a minimal default set into the -source distribution: - -* all Python source files implied by the ``py_modules`` and - ``packages`` options - -* all C source files mentioned in the ``ext_modules`` or - ``libraries`` options - - .. XXX getting C library sources currently broken---no - :meth:`get_source_files` method in :file:`build_clib.py`! - -* scripts identified by the ``scripts`` option - See :ref:`distutils-installing-scripts`. - -* anything that looks like a test script: :file:`test/test\*.py` (currently, the - Distutils don't do anything with test scripts except include them in source - distributions, but in the future there will be a standard for testing Python - module distributions) - -* Any of the standard README files (:file:`README`, :file:`README.txt`, - or :file:`README.rst`), :file:`setup.py` (or whatever you called your setup - script), and :file:`setup.cfg`. - -* all files that matches the ``package_data`` metadata. - See :ref:`distutils-installing-package-data`. - -* all files that matches the ``data_files`` metadata. - See :ref:`distutils-additional-files`. - -Sometimes this is enough, but usually you will want to specify additional files -to distribute. The typical way to do this is to write a *manifest template*, -called :file:`MANIFEST.in` by default. The manifest template is just a list of -instructions for how to generate your manifest file, :file:`MANIFEST`, which is -the exact list of files to include in your source distribution. The -:command:`sdist` command processes this template and generates a manifest based -on its instructions and what it finds in the filesystem. - -If you prefer to roll your own manifest file, the format is simple: one filename -per line, regular files (or symlinks to them) only. If you do supply your own -:file:`MANIFEST`, you must specify everything: the default set of files -described above does not apply in this case. - -.. versionchanged:: 3.1 - An existing generated :file:`MANIFEST` will be regenerated without - :command:`sdist` comparing its modification time to the one of - :file:`MANIFEST.in` or :file:`setup.py`. - -.. versionchanged:: 3.1.3 - :file:`MANIFEST` files start with a comment indicating they are generated. - Files without this comment are not overwritten or removed. - -.. versionchanged:: 3.2.2 - :command:`sdist` will read a :file:`MANIFEST` file if no :file:`MANIFEST.in` - exists, like it used to do. - -.. versionchanged:: 3.7 - :file:`README.rst` is now included in the list of distutils standard READMEs. - - -The manifest template has one command per line, where each command specifies a -set of files to include or exclude from the source distribution. For an -example, again we turn to the Distutils' own manifest template: - -.. code-block:: none - - include *.txt - recursive-include examples *.txt *.py - prune examples/sample?/build - -The meanings should be fairly clear: include all files in the distribution root -matching :file:`\*.txt`, all files anywhere under the :file:`examples` directory -matching :file:`\*.txt` or :file:`\*.py`, and exclude all directories matching -:file:`examples/sample?/build`. All of this is done *after* the standard -include set, so you can exclude files from the standard set with explicit -instructions in the manifest template. (Or, you can use the -:option:`!--no-defaults` option to disable the standard set entirely.) There are -several other commands available in the manifest template mini-language; see -section :ref:`sdist-cmd`. - -The order of commands in the manifest template matters: initially, we have the -list of default files as described above, and each command in the template adds -to or removes from that list of files. Once we have fully processed the -manifest template, we remove files that should not be included in the source -distribution: - -* all files in the Distutils "build" tree (default :file:`build/`) - -* all files in directories named :file:`RCS`, :file:`CVS`, :file:`.svn`, - :file:`.hg`, :file:`.git`, :file:`.bzr` or :file:`_darcs` - -Now we have our complete list of files, which is written to the manifest for -future reference, and then used to build the source distribution archive(s). - -You can disable the default set of included files with the -:option:`!--no-defaults` option, and you can disable the standard exclude set -with :option:`!--no-prune`. - -Following the Distutils' own manifest template, let's trace how the -:command:`sdist` command builds the list of files to include in the Distutils -source distribution: - -#. include all Python source files in the :file:`distutils` and - :file:`distutils/command` subdirectories (because packages corresponding to - those two directories were mentioned in the ``packages`` option in the - setup script---see section :ref:`setup-script`) - -#. include :file:`README.txt`, :file:`setup.py`, and :file:`setup.cfg` (standard - files) - -#. include :file:`test/test\*.py` (standard files) - -#. include :file:`\*.txt` in the distribution root (this will find - :file:`README.txt` a second time, but such redundancies are weeded out later) - -#. include anything matching :file:`\*.txt` or :file:`\*.py` in the sub-tree - under :file:`examples`, - -#. exclude all files in the sub-trees starting at directories matching - :file:`examples/sample?/build`\ ---this may exclude files included by the - previous two steps, so it's important that the ``prune`` command in the manifest - template comes after the ``recursive-include`` command - -#. exclude the entire :file:`build` tree, and any :file:`RCS`, :file:`CVS`, - :file:`.svn`, :file:`.hg`, :file:`.git`, :file:`.bzr` and :file:`_darcs` - directories - -Just like in the setup script, file and directory names in the manifest template -should always be slash-separated; the Distutils will take care of converting -them to the standard representation on your platform. That way, the manifest -template is portable across operating systems. - - -.. _manifest-options: - -Manifest-related options -======================== - -The normal course of operations for the :command:`sdist` command is as follows: - -* if the manifest file (:file:`MANIFEST` by default) exists and the first line - does not have a comment indicating it is generated from :file:`MANIFEST.in`, - then it is used as is, unaltered - -* if the manifest file doesn't exist or has been previously automatically - generated, read :file:`MANIFEST.in` and create the manifest - -* if neither :file:`MANIFEST` nor :file:`MANIFEST.in` exist, create a manifest - with just the default file set - -* use the list of files now in :file:`MANIFEST` (either just generated or read - in) to create the source distribution archive(s) - -There are a couple of options that modify this behaviour. First, use the -:option:`!--no-defaults` and :option:`!--no-prune` to disable the standard -"include" and "exclude" sets. - -Second, you might just want to (re)generate the manifest, but not create a source -distribution:: - - python setup.py sdist --manifest-only - -:option:`!-o` is a shortcut for :option:`!--manifest-only`. diff --git a/Doc/distutils/uploading.rst b/Doc/distutils/uploading.rst deleted file mode 100644 index 4c391cab072..00000000000 --- a/Doc/distutils/uploading.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -*************************************** -Uploading Packages to the Package Index -*************************************** - -References to up to date PyPI documentation can be found at -:ref:`publishing-python-packages`. diff --git a/Doc/extending/building.rst b/Doc/extending/building.rst index 69dffbd56ab..880bb33ee56 100644 --- a/Doc/extending/building.rst +++ b/Doc/extending/building.rst @@ -11,13 +11,13 @@ A C extension for CPython is a shared library (e.g. a ``.so`` file on Linux, To be importable, the shared library must be available on :envvar:`PYTHONPATH`, and must be named after the module name, with an appropriate extension. -When using distutils, the correct filename is generated automatically. +When using setuptools, the correct filename is generated automatically. The initialization function has the signature: .. c:function:: PyObject* PyInit_modulename(void) -It returns either a fully-initialized module, or a :c:type:`PyModuleDef` +It returns either a fully initialized module, or a :c:type:`PyModuleDef` instance. See :ref:`initializing-modules` for details. .. highlight:: python @@ -45,122 +45,12 @@ See the *"Multiple modules in one library"* section in :pep:`489` for details. .. highlight:: c -Building C and C++ Extensions with distutils -============================================ +.. _setuptools-index: -.. sectionauthor:: Martin v. Löwis <martin@v.loewis.de> +Building C and C++ Extensions with setuptools +============================================= -Extension modules can be built using distutils, which is included in Python. -Since distutils also supports creation of binary packages, users don't -necessarily need a compiler and distutils to install the extension. - -A distutils package contains a driver script, :file:`setup.py`. This is a plain -Python file, which, in the most simple case, could look like this: - -.. code-block:: python3 - - from distutils.core import setup, Extension - - module1 = Extension('demo', - sources = ['demo.c']) - - setup (name = 'PackageName', - version = '1.0', - description = 'This is a demo package', - ext_modules = [module1]) - - -With this :file:`setup.py`, and a file :file:`demo.c`, running :: - - python setup.py build - -will compile :file:`demo.c`, and produce an extension module named ``demo`` in -the :file:`build` directory. Depending on the system, the module file will end -up in a subdirectory :file:`build/lib.system`, and may have a name like -:file:`demo.so` or :file:`demo.pyd`. - -In the :file:`setup.py`, all execution is performed by calling the ``setup`` -function. This takes a variable number of keyword arguments, of which the -example above uses only a subset. Specifically, the example specifies -meta-information to build packages, and it specifies the contents of the -package. Normally, a package will contain additional modules, like Python -source modules, documentation, subpackages, etc. Please refer to the distutils -documentation in :ref:`distutils-index` to learn more about the features of -distutils; this section explains building extension modules only. - -It is common to pre-compute arguments to :func:`setup`, to better structure the -driver script. In the example above, the ``ext_modules`` argument to -:func:`~distutils.core.setup` is a list of extension modules, each of which is -an instance of -the :class:`~distutils.extension.Extension`. In the example, the instance -defines an extension named ``demo`` which is build by compiling a single source -file, :file:`demo.c`. - -In many cases, building an extension is more complex, since additional -preprocessor defines and libraries may be needed. This is demonstrated in the -example below. - -.. code-block:: python3 - - from distutils.core import setup, Extension - - module1 = Extension('demo', - define_macros = [('MAJOR_VERSION', '1'), - ('MINOR_VERSION', '0')], - include_dirs = ['/usr/local/include'], - libraries = ['tcl83'], - library_dirs = ['/usr/local/lib'], - sources = ['demo.c']) - - setup (name = 'PackageName', - version = '1.0', - description = 'This is a demo package', - author = 'Martin v. Loewis', - author_email = 'martin@v.loewis.de', - url = 'https://docs.python.org/extending/building', - long_description = ''' - This is really just a demo package. - ''', - ext_modules = [module1]) - - -In this example, :func:`~distutils.core.setup` is called with additional -meta-information, which -is recommended when distribution packages have to be built. For the extension -itself, it specifies preprocessor defines, include directories, library -directories, and libraries. Depending on the compiler, distutils passes this -information in different ways to the compiler. For example, on Unix, this may -result in the compilation commands :: - - gcc -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -fPIC -DMAJOR_VERSION=1 -DMINOR_VERSION=0 -I/usr/local/include -I/usr/local/include/python2.2 -c demo.c -o build/temp.linux-i686-2.2/demo.o - - gcc -shared build/temp.linux-i686-2.2/demo.o -L/usr/local/lib -ltcl83 -o build/lib.linux-i686-2.2/demo.so - -These lines are for demonstration purposes only; distutils users should trust -that distutils gets the invocations right. - - -.. _distributing: - -Distributing your extension modules -=================================== - -When an extension has been successfully built, there are three ways to use it. - -End-users will typically want to install the module, they do so by running :: - - python setup.py install - -Module maintainers should produce source packages; to do so, they run :: - - python setup.py sdist - -In some cases, additional files need to be included in a source distribution; -this is done through a :file:`MANIFEST.in` file; see :ref:`manifest` for details. - -If the source distribution has been built successfully, maintainers can also -create binary distributions. Depending on the platform, one of the following -commands can be used to do so. :: - - python setup.py bdist_rpm - python setup.py bdist_dumb +Python 3.12 and newer no longer come with distutils. Please refer to the +``setuptools`` documentation at +https://setuptools.readthedocs.io/en/latest/setuptools.html +to learn more about how build and distribute C/C++ extensions with setuptools. diff --git a/Doc/extending/embedding.rst b/Doc/extending/embedding.rst index 5f5abdf9c15..e64db373344 100644 --- a/Doc/extending/embedding.rst +++ b/Doc/extending/embedding.rst @@ -298,16 +298,16 @@ be directly useful to you: .. code-block:: shell-session - $ /opt/bin/python3.4-config --cflags - -I/opt/include/python3.4m -I/opt/include/python3.4m -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes + $ /opt/bin/python3.11-config --cflags + -I/opt/include/python3.11 -I/opt/include/python3.11 -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -* ``pythonX.Y-config --ldflags`` will give you the recommended flags when - linking: +* ``pythonX.Y-config --ldflags --embed`` will give you the recommended flags + when linking: .. code-block:: shell-session - $ /opt/bin/python3.4-config --ldflags - -L/opt/lib/python3.4/config-3.4m -lpthread -ldl -lutil -lm -lpython3.4m -Xlinker -export-dynamic + $ /opt/bin/python3.11-config --ldflags --embed + -L/opt/lib/python3.11/config-3.11-x86_64-linux-gnu -L/opt/lib -lpython3.11 -lpthread -ldl -lutil -lm .. note:: To avoid confusion between several Python installations (and especially diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst index 2e3362b834e..d9bf4fd6c7a 100644 --- a/Doc/extending/extending.rst +++ b/Doc/extending/extending.rst @@ -157,16 +157,16 @@ since you should be able to tell from the return value. When a function *f* that calls another function *g* detects that the latter fails, *f* should itself return an error value (usually ``NULL`` or ``-1``). It -should *not* call one of the :c:func:`PyErr_\*` functions --- one has already +should *not* call one of the ``PyErr_*`` functions --- one has already been called by *g*. *f*'s caller is then supposed to also return an error -indication to *its* caller, again *without* calling :c:func:`PyErr_\*`, and so on +indication to *its* caller, again *without* calling ``PyErr_*``, and so on --- the most detailed cause of the error was already reported by the function that first detected it. Once the error reaches the Python interpreter's main loop, this aborts the currently executing Python code and tries to find an exception handler specified by the Python programmer. (There are situations where a module can actually give a more detailed error -message by calling another :c:func:`PyErr_\*` function, and in such cases it is +message by calling another ``PyErr_*`` function, and in such cases it is fine to do so. As a general rule, however, this is not necessary, and can cause information about the cause of the error to be lost: most operations can fail for a variety of reasons.) @@ -298,7 +298,7 @@ In this case, it will return an integer object. (Yes, even integers are objects on the heap in Python!) If you have a C function that returns no useful argument (a function returning -:c:type:`void`), the corresponding Python function must return ``None``. You +:c:expr:`void`), the corresponding Python function must return ``None``. You need this idiom to do so (which is implemented by the :c:macro:`Py_RETURN_NONE` macro):: @@ -1171,7 +1171,7 @@ other extension modules must be exported in a different way. Python provides a special mechanism to pass C-level information (pointers) from one extension module to another one: Capsules. A Capsule is a Python data type -which stores a pointer (:c:type:`void \*`). Capsules can only be created and +which stores a pointer (:c:expr:`void \*`). Capsules can only be created and accessed via their C API, but they can be passed around like any other Python object. In particular, they can be assigned to a name in an extension module's namespace. Other extension modules can then import this module, retrieve the @@ -1185,7 +1185,7 @@ different ways between the module providing the code and the client modules. Whichever method you choose, it's important to name your Capsules properly. The function :c:func:`PyCapsule_New` takes a name parameter -(:c:type:`const char \*`); you're permitted to pass in a ``NULL`` name, but +(:c:expr:`const char \*`); you're permitted to pass in a ``NULL`` name, but we strongly encourage you to specify a name. Properly named Capsules provide a degree of runtime type-safety; there is no feasible way to tell one unnamed Capsule from another. @@ -1203,7 +1203,7 @@ of certainty that the Capsule they load contains the correct C API. The following example demonstrates an approach that puts most of the burden on the writer of the exporting module, which is appropriate for commonly used library modules. It stores all C API pointers (just one in the example!) in an -array of :c:type:`void` pointers which becomes the value of a Capsule. The header +array of :c:expr:`void` pointers which becomes the value of a Capsule. The header file corresponding to the module provides a macro that takes care of importing the module and retrieving its C API pointers; client modules only have to call this macro before accessing the C API. diff --git a/Doc/extending/index.rst b/Doc/extending/index.rst index 0994e3e8627..01b4df6d44a 100644 --- a/Doc/extending/index.rst +++ b/Doc/extending/index.rst @@ -27,8 +27,8 @@ Recommended third party tools This guide only covers the basic tools for creating extensions provided as part of this version of CPython. Third party tools like -`Cython <http://cython.org/>`_, `cffi <https://cffi.readthedocs.io>`_, -`SWIG <http://www.swig.org>`_ and `Numba <https://numba.pydata.org/>`_ +`Cython <https://cython.org/>`_, `cffi <https://cffi.readthedocs.io>`_, +`SWIG <https://www.swig.org>`_ and `Numba <https://numba.pydata.org/>`_ offer both simpler and more sophisticated approaches to creating C and C++ extensions for Python. diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst index f75bee9e6f2..80a1387db20 100644 --- a/Doc/extending/newtypes.rst +++ b/Doc/extending/newtypes.rst @@ -175,7 +175,7 @@ example:: } If no :c:member:`~PyTypeObject.tp_repr` handler is specified, the interpreter will supply a -representation that uses the type's :c:member:`~PyTypeObject.tp_name` and a uniquely-identifying +representation that uses the type's :c:member:`~PyTypeObject.tp_name` and a uniquely identifying value for the object. The :c:member:`~PyTypeObject.tp_str` handler is to :func:`str` what the :c:member:`~PyTypeObject.tp_repr` handler @@ -207,8 +207,8 @@ a special case, for which the new value passed to the handler is ``NULL``. Python supports two pairs of attribute handlers; a type that supports attributes only needs to implement the functions for one pair. The difference is that one -pair takes the name of the attribute as a :c:type:`char\*`, while the other -accepts a :c:type:`PyObject\*`. Each type can use whichever pair makes more +pair takes the name of the attribute as a :c:expr:`char\*`, while the other +accepts a :c:expr:`PyObject*`. Each type can use whichever pair makes more sense for the implementation's convenience. :: getattrfunc tp_getattr; /* char * version */ @@ -219,7 +219,7 @@ sense for the implementation's convenience. :: If accessing attributes of an object is always a simple operation (this will be explained shortly), there are generic implementations which can be used to -provide the :c:type:`PyObject\*` version of the attribute management functions. +provide the :c:expr:`PyObject*` version of the attribute management functions. The actual need for type-specific attribute handlers almost completely disappeared starting with Python 2.2, though there are many examples which have not been updated to use some of the new generic mechanism that is available. @@ -286,36 +286,11 @@ be read-only or read-write. The structures in the table are defined as:: For each entry in the table, a :term:`descriptor` will be constructed and added to the type which will be able to extract a value from the instance structure. The -:attr:`type` field should contain one of the type codes defined in the -:file:`structmember.h` header; the value will be used to determine how to +:attr:`type` field should contain a type code like :c:macro:`Py_T_INT` or +:c:macro:`Py_T_DOUBLE`; the value will be used to determine how to convert Python values to and from C values. The :attr:`flags` field is used to -store flags which control how the attribute can be accessed. - -The following flag constants are defined in :file:`structmember.h`; they may be -combined using bitwise-OR. - -+---------------------------+----------------------------------------------+ -| Constant | Meaning | -+===========================+==============================================+ -| :const:`READONLY` | Never writable. | -+---------------------------+----------------------------------------------+ -| :const:`PY_AUDIT_READ` | Emit an ``object.__getattr__`` | -| | :ref:`audit events <audit-events>` before | -| | reading. | -+---------------------------+----------------------------------------------+ - -.. versionchanged:: 3.10 - :const:`RESTRICTED`, :const:`READ_RESTRICTED` and :const:`WRITE_RESTRICTED` - are deprecated. However, :const:`READ_RESTRICTED` is an alias for - :const:`PY_AUDIT_READ`, so fields that specify either :const:`RESTRICTED` - or :const:`READ_RESTRICTED` will also raise an audit event. - -.. index:: - single: READONLY - single: READ_RESTRICTED - single: WRITE_RESTRICTED - single: RESTRICTED - single: PY_AUDIT_READ +store flags which control how the attribute can be accessed: you can set it to +:c:macro:`Py_READONLY` to prevent Python code from setting it. An interesting advantage of using the :c:member:`~PyTypeObject.tp_members` table to build descriptors that are used at runtime is that any attribute defined this way can @@ -339,9 +314,9 @@ of ``NULL`` is required. Type-specific Attribute Management ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -For simplicity, only the :c:type:`char\*` version will be demonstrated here; the -type of the name parameter is the only difference between the :c:type:`char\*` -and :c:type:`PyObject\*` flavors of the interface. This example effectively does +For simplicity, only the :c:expr:`char\*` version will be demonstrated here; the +type of the name parameter is the only difference between the :c:expr:`char\*` +and :c:expr:`PyObject*` flavors of the interface. This example effectively does the same thing as the generic example above, but does not use the generic support added in Python 2.2. It explains how the handler functions are called, so that if you do need to extend their functionality, you'll understand @@ -570,43 +545,28 @@ performance-critical objects (such as numbers). .. seealso:: Documentation for the :mod:`weakref` module. -For an object to be weakly referencable, the extension type must do two things: +For an object to be weakly referencable, the extension type must set the +``Py_TPFLAGS_MANAGED_WEAKREF`` bit of the :c:member:`~PyTypeObject.tp_flags` +field. The legacy :c:member:`~PyTypeObject.tp_weaklistoffset` field should +be left as zero. -#. Include a :c:type:`PyObject\*` field in the C object structure dedicated to - the weak reference mechanism. The object's constructor should leave it - ``NULL`` (which is automatic when using the default - :c:member:`~PyTypeObject.tp_alloc`). - -#. Set the :c:member:`~PyTypeObject.tp_weaklistoffset` type member - to the offset of the aforementioned field in the C object structure, - so that the interpreter knows how to access and modify that field. - -Concretely, here is how a trivial object structure would be augmented -with the required field:: - - typedef struct { - PyObject_HEAD - PyObject *weakreflist; /* List of weak references */ - } TrivialObject; - -And the corresponding member in the statically-declared type object:: +Concretely, here is how the statically declared type object would look:: static PyTypeObject TrivialType = { PyVarObject_HEAD_INIT(NULL, 0) /* ... other members omitted for brevity ... */ - .tp_weaklistoffset = offsetof(TrivialObject, weakreflist), + .tp_flags = Py_TPFLAGS_MANAGED_WEAKREF | ..., }; + The only further addition is that ``tp_dealloc`` needs to clear any weak -references (by calling :c:func:`PyObject_ClearWeakRefs`) if the field is -non-``NULL``:: +references (by calling :c:func:`PyObject_ClearWeakRefs`):: static void Trivial_dealloc(TrivialObject *self) { /* Clear weakrefs first before calling any destructors */ - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); + PyObject_ClearWeakRefs((PyObject *) self); /* ... remainder of destruction code omitted for brevity ... */ Py_TYPE(self)->tp_free((PyObject *) self); } diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst index 530e2c4d35f..54de3fd4243 100644 --- a/Doc/extending/newtypes_tutorial.rst +++ b/Doc/extending/newtypes_tutorial.rst @@ -24,7 +24,7 @@ The Basics ========== The :term:`CPython` runtime sees all Python objects as variables of type -:c:type:`PyObject\*`, which serves as a "base type" for all Python objects. +:c:expr:`PyObject*`, which serves as a "base type" for all Python objects. The :c:type:`PyObject` structure itself only contains the object's :term:`reference count` and a pointer to the object's "type object". This is where the action is; the type object determines which (C) functions @@ -67,8 +67,8 @@ The first bit is:: This is what a Custom object will contain. ``PyObject_HEAD`` is mandatory at the start of each object struct and defines a field called ``ob_base`` of type :c:type:`PyObject`, containing a pointer to a type object and a -reference count (these can be accessed using the macros :c:macro:`Py_REFCNT` -and :c:macro:`Py_TYPE` respectively). The reason for the macro is to +reference count (these can be accessed using the macros :c:macro:`Py_TYPE` +and :c:macro:`Py_REFCNT` respectively). The reason for the macro is to abstract away the layout and to enable additional fields in :ref:`debug builds <debug-build>`. @@ -90,7 +90,7 @@ The second bit is the definition of the type object. :: static PyTypeObject CustomType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "custom.Custom", - .tp_doc = "Custom objects", + .tp_doc = PyDoc_STR("Custom objects"), .tp_basicsize = sizeof(CustomObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT, @@ -161,7 +161,7 @@ you will need to OR the corresponding flags. We provide a doc string for the type in :c:member:`~PyTypeObject.tp_doc`. :: - .tp_doc = "Custom objects", + .tp_doc = PyDoc_STR("Custom objects"), To enable object creation, we have to provide a :c:member:`~PyTypeObject.tp_new` handler. This is the equivalent of the Python method :meth:`__new__`, but @@ -239,13 +239,6 @@ adds these capabilities: This version of the module has a number of changes. -We've added an extra include:: - - #include <structmember.h> - -This include provides declarations that we use to handle attributes, as -described a bit later. - The :class:`Custom` type now has three data attributes in its C struct, *first*, *last*, and *number*. The *first* and *last* variables are Python strings containing first and last names. The *number* attribute is a C integer. @@ -436,11 +429,11 @@ We want to expose our instance variables as attributes. There are a number of ways to do that. The simplest way is to define member definitions:: static PyMemberDef Custom_members[] = { - {"first", T_OBJECT_EX, offsetof(CustomObject, first), 0, + {"first", Py_T_OBJECT_EX, offsetof(CustomObject, first), 0, "first name"}, - {"last", T_OBJECT_EX, offsetof(CustomObject, last), 0, + {"last", Py_T_OBJECT_EX, offsetof(CustomObject, last), 0, "last name"}, - {"number", T_INT, offsetof(CustomObject, number), 0, + {"number", Py_T_INT, offsetof(CustomObject, number), 0, "custom number"}, {NULL} /* Sentinel */ }; @@ -609,7 +602,7 @@ above. In this case, we aren't using a closure, so we just pass ``NULL``. We also remove the member definitions for these attributes:: static PyMemberDef Custom_members[] = { - {"number", T_INT, offsetof(CustomObject, number), 0, + {"number", Py_T_INT, offsetof(CustomObject, number), 0, "custom number"}, {NULL} /* Sentinel */ }; diff --git a/Doc/extending/windows.rst b/Doc/extending/windows.rst index c7b92c6ea24..1129b0968bc 100644 --- a/Doc/extending/windows.rst +++ b/Doc/extending/windows.rst @@ -34,10 +34,10 @@ A Cookbook Approach =================== There are two approaches to building extension modules on Windows, just as there -are on Unix: use the :mod:`distutils` package to control the build process, or -do things manually. The distutils approach works well for most extensions; -documentation on using :mod:`distutils` to build and package extension modules -is available in :ref:`distutils-index`. If you find you really need to do +are on Unix: use the ``setuptools`` package to control the build process, or +do things manually. The setuptools approach works well for most extensions; +documentation on using ``setuptools`` to build and package extension modules +is available in :ref:`setuptools-index`. If you find you really need to do things manually, it may be instructive to study the project file for the :source:`winsound <PCbuild/winsound.vcxproj>` standard library module. @@ -106,8 +106,7 @@ Using DLLs in Practice Windows Python is built in Microsoft Visual C++; using other compilers may or -may not work (though Borland seems to). The rest of this section is MSVC++ -specific. +may not work. The rest of this section is MSVC++ specific. When creating DLLs in Windows, you must pass :file:`pythonXY.lib` to the linker. To build two DLLs, spam and ni (which uses C functions found in spam), you could @@ -134,4 +133,3 @@ Developer Studio will throw in a lot of import libraries that you do not really need, adding about 100K to your executable. To get rid of them, use the Project Settings dialog, Link tab, to specify *ignore default libraries*. Add the correct :file:`msvcrtxx.lib` to the list of libraries. - diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index 0437b59d55d..11d01374dc1 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -129,7 +129,7 @@ reference or call the method from a particular class. In C++, if you want to use a method from a base class which is overridden in a derived class, you have to use the ``::`` operator -- in Python you can write ``baseclass.methodname(self, <argument list>)``. This is particularly useful -for :meth:`__init__` methods, and in general in cases where a derived class +for :meth:`~object.__init__` methods, and in general in cases where a derived class method wants to extend the base class method of the same name and thus has to call the base class method somehow. @@ -155,7 +155,7 @@ Why can't I use an assignment in an expression? Starting in Python 3.8, you can! -Assignment expressions using the walrus operator `:=` assign a variable in an +Assignment expressions using the walrus operator ``:=`` assign a variable in an expression:: while chunk := fp.read(200): @@ -232,7 +232,8 @@ Similar methods exist for bytes and bytearray objects. How fast are exceptions? ------------------------ -A try/except block is extremely efficient if no exceptions are raised. Actually +A :keyword:`try`/:keyword:`except` block is extremely efficient if no exceptions +are raised. Actually catching an exception is expensive. In versions of Python prior to 2.0 it was common to use this idiom:: @@ -266,12 +267,9 @@ For cases where you need to choose from a very large number of possibilities, you can create a dictionary mapping case values to functions to call. For example:: - def function_1(...): - ... - functions = {'a': function_1, 'b': function_2, - 'c': self.method_1, ...} + 'c': self.method_1} func = functions[value] func() @@ -279,14 +277,14 @@ example:: For calling methods on objects, you can simplify yet further by using the :func:`getattr` built-in to retrieve methods with a particular name:: - def visit_a(self, ...): - ... - ... + class MyVisitor: + def visit_a(self): + ... - def dispatch(self, value): - method_name = 'visit_' + str(value) - method = getattr(self, method_name) - method() + def dispatch(self, value): + method_name = 'visit_' + str(value) + method = getattr(self, method_name) + method() It's suggested that you use a prefix for the method names, such as ``visit_`` in this example. Without such a prefix, if values are coming from an untrusted @@ -316,7 +314,7 @@ you're too lazy to define a function. Functions are already first class objects in Python, and can be declared in a local scope. Therefore the only advantage of using a lambda instead of a -locally-defined function is that you don't need to invent a name for the +locally defined function is that you don't need to invent a name for the function -- but that's just a local variable to which the function object (which is exactly the same type of object that a lambda expression yields) is assigned! @@ -324,11 +322,10 @@ is exactly the same type of object that a lambda expression yields) is assigned! Can Python be compiled to machine code, C or some other language? ----------------------------------------------------------------- -`Cython <http://cython.org/>`_ compiles a modified version of Python with -optional annotations into C extensions. `Nuitka <http://www.nuitka.net/>`_ is +`Cython <https://cython.org/>`_ compiles a modified version of Python with +optional annotations into C extensions. `Nuitka <https://www.nuitka.net/>`_ is an up-and-coming compiler of Python into C++ code, aiming to support the full -Python language. For compiling to Java you can consider -`VOC <https://voc.readthedocs.io>`_. +Python language. How does Python manage memory? @@ -342,8 +339,8 @@ cycles and deletes the objects involved. The :mod:`gc` module provides functions to perform a garbage collection, obtain debugging statistics, and tune the collector's parameters. -Other implementations (such as `Jython <http://www.jython.org>`_ or -`PyPy <http://www.pypy.org>`_), however, can rely on a different mechanism +Other implementations (such as `Jython <https://www.jython.org>`_ or +`PyPy <https://www.pypy.org>`_), however, can rely on a different mechanism such as a full-blown garbage collector. This difference can cause some subtle porting problems if your Python code depends on the behavior of the reference counting implementation. @@ -356,7 +353,7 @@ will probably run out of file descriptors:: c = f.read(1) Indeed, using CPython's reference counting and destructor scheme, each new -assignment to *f* closes the previous file. With a traditional GC, however, +assignment to ``f`` closes the previous file. With a traditional GC, however, those file objects will only get collected (and closed) at varying and possibly long intervals. @@ -380,10 +377,10 @@ Python to work with it.) Traditional GC also becomes a problem when Python is embedded into other applications. While in a standalone Python it's fine to replace the standard -malloc() and free() with versions provided by the GC library, an application -embedding Python may want to have its *own* substitute for malloc() and free(), +``malloc()`` and ``free()`` with versions provided by the GC library, an application +embedding Python may want to have its *own* substitute for ``malloc()`` and ``free()``, and may not want Python's. Right now, CPython works with anything that -implements malloc() and free() properly. +implements ``malloc()`` and ``free()`` properly. Why isn't all memory freed when CPython exits? @@ -405,14 +402,15 @@ Why are there separate tuple and list data types? Lists and tuples, while similar in many respects, are generally used in fundamentally different ways. Tuples can be thought of as being similar to -Pascal records or C structs; they're small collections of related data which may +Pascal ``records`` or C ``structs``; they're small collections of related data which may be of different types which are operated on as a group. For example, a Cartesian coordinate is appropriately represented as a tuple of two or three numbers. Lists, on the other hand, are more like arrays in other languages. They tend to hold a varying number of objects all of which have the same type and which are -operated on one-by-one. For example, ``os.listdir('.')`` returns a list of +operated on one-by-one. For example, :func:`os.listdir('.') <os.listdir>` +returns a list of strings representing the files in the current directory. Functions which operate on this output would generally not break if you added another file or two to the directory. @@ -448,9 +446,9 @@ far) under most circumstances, and the implementation is simpler. Dictionaries work by computing a hash code for each key stored in the dictionary using the :func:`hash` built-in function. The hash code varies widely depending -on the key and a per-process seed; for example, "Python" could hash to --539294296 while "python", a string that differs by a single bit, could hash -to 1142331976. The hash code is then used to calculate a location in an +on the key and a per-process seed; for example, ``'Python'`` could hash to +``-539294296`` while ``'python'``, a string that differs by a single bit, could hash +to ``1142331976``. The hash code is then used to calculate a location in an internal array where the value will be stored. Assuming that you're storing keys that all have different hash values, this means that dictionaries take constant time -- O(1), in Big-O notation -- to retrieve a key. @@ -501,7 +499,8 @@ Some unacceptable solutions that have been proposed: There is a trick to get around this if you need to, but use it at your own risk: You can wrap a mutable structure inside a class instance which has both a -:meth:`__eq__` and a :meth:`__hash__` method. You must then make sure that the +:meth:`~object.__eq__` and a :meth:`~object.__hash__` method. +You must then make sure that the hash value for all such wrapper objects that reside in a dictionary (or other hash based structure), remain fixed while the object is in the dictionary (or other structure). :: @@ -532,7 +531,7 @@ is True``) then ``hash(o1) == hash(o2)`` (ie, ``o1.__hash__() == o2.__hash__()`` regardless of whether the object is in a dictionary or not. If you fail to meet these restrictions dictionaries and other hash based structures will misbehave. -In the case of ListWrapper, whenever the wrapper object is in a dictionary the +In the case of :class:`!ListWrapper`, whenever the wrapper object is in a dictionary the wrapped list must not change to avoid anomalies. Don't do this unless you are prepared to think hard about the requirements and the consequences of not meeting them correctly. Consider yourself warned. @@ -585,9 +584,9 @@ exhaustive test suites that exercise every line of code in a module. An appropriate testing discipline can help build large complex applications in Python as well as having interface specifications would. In fact, it can be better because an interface specification cannot test certain properties of a -program. For example, the :meth:`append` method is expected to add new elements +program. For example, the :meth:`list.append` method is expected to add new elements to the end of some internal list; an interface specification cannot test that -your :meth:`append` implementation will actually do this correctly, but it's +your :meth:`list.append` implementation will actually do this correctly, but it's trivial to check this property in a test suite. Writing test suites is very helpful, and you might want to design your code to @@ -603,14 +602,14 @@ Why is there no goto? In the 1970s people realized that unrestricted goto could lead to messy "spaghetti" code that was hard to understand and revise. In a high-level language, it is also unneeded as long as there -are ways to branch (in Python, with ``if`` statements and ``or``, -``and``, and ``if-else`` expressions) and loop (with ``while`` -and ``for`` statements, possibly containing ``continue`` and ``break``). +are ways to branch (in Python, with :keyword:`if` statements and :keyword:`or`, +:keyword:`and`, and :keyword:`if`/:keyword:`else` expressions) and loop (with :keyword:`while` +and :keyword:`for` statements, possibly containing :keyword:`continue` and :keyword:`break`). One can also use exceptions to provide a "structured goto" that works even across function calls. Many feel that exceptions can conveniently emulate all -reasonable uses of the "go" or "goto" constructs of C, Fortran, and other +reasonable uses of the ``go`` or ``goto`` constructs of C, Fortran, and other languages. For example:: class label(Exception): pass # declare a label @@ -624,7 +623,7 @@ languages. For example:: ... This doesn't allow you to jump into the middle of a loop, but that's usually -considered an abuse of goto anyway. Use sparingly. +considered an abuse of ``goto`` anyway. Use sparingly. Why can't raw strings (r-strings) end with a backslash? @@ -656,7 +655,7 @@ If you're trying to build a pathname for a DOS command, try e.g. one of :: Why doesn't Python have a "with" statement for attribute assignments? --------------------------------------------------------------------- -Python has a 'with' statement that wraps the execution of a block, calling code +Python has a :keyword:`with` statement that wraps the execution of a block, calling code on the entrance and exit from the block. Some languages have a construct that looks like this:: @@ -683,13 +682,13 @@ For instance, take the following incomplete snippet:: with a: print(x) -The snippet assumes that "a" must have a member attribute called "x". However, +The snippet assumes that ``a`` must have a member attribute called ``x``. However, there is nothing in Python that tells the interpreter this. What should happen -if "a" is, let us say, an integer? If there is a global variable named "x", -will it be used inside the with block? As you see, the dynamic nature of Python +if ``a`` is, let us say, an integer? If there is a global variable named ``x``, +will it be used inside the :keyword:`with` block? As you see, the dynamic nature of Python makes such choices much harder. -The primary benefit of "with" and similar language features (reduction of code +The primary benefit of :keyword:`with` and similar language features (reduction of code volume) can, however, easily be achieved in Python by assignment. Instead of:: function(args).mydict[index][index].a = 21 @@ -707,6 +706,10 @@ This also has the side-effect of increasing execution speed because name bindings are resolved at run-time in Python, and the second version only needs to perform the resolution once. +Similar proposals that would introduce syntax to further reduce code volume, +such as using a 'leading dot', have been rejected in favour of explicitness (see +https://mail.python.org/pipermail/python-ideas/2016-May/040070.html). + Why don't generators support the with statement? ------------------------------------------------ @@ -714,7 +717,8 @@ Why don't generators support the with statement? For technical reasons, a generator used directly as a context manager would not work correctly. When, as is most common, a generator is used as an iterator run to completion, no closing is needed. When it is, wrap -it as "contextlib.closing(generator)" in the 'with' statement. +it as :func:`contextlib.closing(generator) <contextlib.closing>` +in the :keyword:`with` statement. Why are colons required for the if/while/def/class statements? diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst index fd32b097335..07282639e4f 100644 --- a/Doc/faq/extending.rst +++ b/Doc/faq/extending.rst @@ -41,7 +41,7 @@ on what you're trying to do. .. XXX make sure these all work -`Cython <http://cython.org>`_ and its relative `Pyrex +`Cython <https://cython.org>`_ and its relative `Pyrex <https://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/>`_ are compilers that accept a slightly modified form of Python and generate the corresponding C code. Cython and Pyrex make it possible to write an extension without having @@ -49,10 +49,10 @@ to learn Python's C API. If you need to interface to some C or C++ library for which no Python extension currently exists, you can try wrapping the library's data types and functions -with a tool such as `SWIG <http://www.swig.org>`_. `SIP +with a tool such as `SWIG <https://www.swig.org>`_. `SIP <https://riverbankcomputing.com/software/sip/intro>`__, `CXX -<http://cxx.sourceforge.net/>`_ `Boost -<http://www.boost.org/libs/python/doc/index.html>`_, or `Weave +<https://cxx.sourceforge.net/>`_ `Boost +<https://www.boost.org/libs/python/doc/index.html>`_, or `Weave <https://github.com/scipy/weave>`_ are also alternatives for wrapping C++ libraries. @@ -254,7 +254,6 @@ For Red Hat, install the python-devel RPM to get the necessary files. For Debian, run ``apt-get install python-dev``. - How do I tell "incomplete input" from "invalid input"? ------------------------------------------------------ @@ -273,127 +272,6 @@ you. You can also set the :c:func:`PyOS_ReadlineFunctionPointer` to point at you custom input function. See ``Modules/readline.c`` and ``Parser/myreadline.c`` for more hints. -However sometimes you have to run the embedded Python interpreter in the same -thread as your rest application and you can't allow the -:c:func:`PyRun_InteractiveLoop` to stop while waiting for user input. -A solution is trying to compile the received string with -:c:func:`Py_CompileString`. If it compiles without errors, try to execute the -returned code object by calling :c:func:`PyEval_EvalCode`. Otherwise save the -input for later. If the compilation fails, find out if it's an error or just -more input is required - by extracting the message string from the exception -tuple and comparing it to the string "unexpected EOF while parsing". Here is a -complete example using the GNU readline library (you may want to ignore -**SIGINT** while calling readline()):: - - #include <stdio.h> - #include <readline.h> - - #define PY_SSIZE_T_CLEAN - #include <Python.h> - - int main (int argc, char* argv[]) - { - int i, j, done = 0; /* lengths of line, code */ - char ps1[] = ">>> "; - char ps2[] = "... "; - char *prompt = ps1; - char *msg, *line, *code = NULL; - PyObject *src, *glb, *loc; - PyObject *exc, *val, *trb, *obj, *dum; - - Py_Initialize (); - loc = PyDict_New (); - glb = PyDict_New (); - PyDict_SetItemString (glb, "__builtins__", PyEval_GetBuiltins ()); - - while (!done) - { - line = readline (prompt); - - if (NULL == line) /* Ctrl-D pressed */ - { - done = 1; - } - else - { - i = strlen (line); - - if (i > 0) - add_history (line); /* save non-empty lines */ - - if (NULL == code) /* nothing in code yet */ - j = 0; - else - j = strlen (code); - - code = realloc (code, i + j + 2); - if (NULL == code) /* out of memory */ - exit (1); - - if (0 == j) /* code was empty, so */ - code[0] = '\0'; /* keep strncat happy */ - - strncat (code, line, i); /* append line to code */ - code[i + j] = '\n'; /* append '\n' to code */ - code[i + j + 1] = '\0'; - - src = Py_CompileString (code, "<stdin>", Py_single_input); - - if (NULL != src) /* compiled just fine - */ - { - if (ps1 == prompt || /* ">>> " or */ - '\n' == code[i + j - 1]) /* "... " and double '\n' */ - { /* so execute it */ - dum = PyEval_EvalCode (src, glb, loc); - Py_XDECREF (dum); - Py_XDECREF (src); - free (code); - code = NULL; - if (PyErr_Occurred ()) - PyErr_Print (); - prompt = ps1; - } - } /* syntax error or E_EOF? */ - else if (PyErr_ExceptionMatches (PyExc_SyntaxError)) - { - PyErr_Fetch (&exc, &val, &trb); /* clears exception! */ - - if (PyArg_ParseTuple (val, "sO", &msg, &obj) && - !strcmp (msg, "unexpected EOF while parsing")) /* E_EOF */ - { - Py_XDECREF (exc); - Py_XDECREF (val); - Py_XDECREF (trb); - prompt = ps2; - } - else /* some other syntax error */ - { - PyErr_Restore (exc, val, trb); - PyErr_Print (); - free (code); - code = NULL; - prompt = ps1; - } - } - else /* some non-syntax error */ - { - PyErr_Print (); - free (code); - code = NULL; - prompt = ps1; - } - - free (line); - } - } - - Py_XDECREF(glb); - Py_XDECREF(loc); - Py_Finalize(); - exit(0); - } - - How do I find undefined g++ symbols __builtin_new or __pure_virtual? -------------------------------------------------------------------- @@ -408,6 +286,6 @@ Can I create an object class with some methods implemented in C and others in Py Yes, you can inherit from built-in classes such as :class:`int`, :class:`list`, :class:`dict`, etc. -The Boost Python Library (BPL, http://www.boost.org/libs/python/doc/index.html) +The Boost Python Library (BPL, https://www.boost.org/libs/python/doc/index.html) provides a way of doing this from C++ (i.e. you can inherit from an extension class written in C++ using the BPL). diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst index 7723114bcc1..489bca76432 100644 --- a/Doc/faq/general.rst +++ b/Doc/faq/general.rst @@ -113,8 +113,8 @@ to many different classes of problems. The language comes with a large standard library that covers areas such as string processing (regular expressions, Unicode, calculating differences between -files), internet protocols (HTTP, FTP, SMTP, XML-RPC, POP, IMAP, CGI -programming), software engineering (unit testing, logging, profiling, parsing +files), internet protocols (HTTP, FTP, SMTP, XML-RPC, POP, IMAP), +software engineering (unit testing, logging, profiling, parsing Python code), and operating system interfaces (system calls, filesystems, TCP/IP sockets). Look at the table of contents for :ref:`library-index` to get an idea of what's available. A wide variety of third-party extensions are also @@ -125,11 +125,15 @@ find packages of interest to you. How does the Python version numbering scheme work? -------------------------------------------------- -Python versions are numbered A.B.C or A.B. A is the major version number -- it -is only incremented for really major changes in the language. B is the minor -version number, incremented for less earth-shattering changes. C is the -micro-level -- it is incremented for each bugfix release. See :pep:`6` for more -information about bugfix releases. +Python versions are numbered "A.B.C" or "A.B": + +* *A* is the major version number -- it is only incremented for really major + changes in the language. +* *B* is the minor version number -- it is incremented for less earth-shattering + changes. +* *C* is the micro version number -- it is incremented for each bugfix release. + +See :pep:`6` for more information about bugfix releases. Not all releases are bugfix releases. In the run-up to a new major release, a series of development releases are made, denoted as alpha, beta, or release @@ -139,12 +143,14 @@ Betas are more stable, preserving existing interfaces but possibly adding new modules, and release candidates are frozen, making no changes except as needed to fix critical bugs. -Alpha, beta and release candidate versions have an additional suffix. The -suffix for an alpha version is "aN" for some small number N, the suffix for a -beta version is "bN" for some small number N, and the suffix for a release -candidate version is "rcN" for some small number N. In other words, all versions -labeled 2.0aN precede the versions labeled 2.0bN, which precede versions labeled -2.0rcN, and *those* precede 2.0. +Alpha, beta and release candidate versions have an additional suffix: + +* The suffix for an alpha version is "aN" for some small number *N*. +* The suffix for a beta version is "bN" for some small number *N*. +* The suffix for a release candidate version is "rcN" for some small number *N*. + +In other words, all versions labeled *2.0aN* precede the versions labeled +*2.0bN*, which precede versions labeled *2.0rcN*, and *those* precede 2.0. You may also find version numbers with a "+" suffix, e.g. "2.2+". These are unreleased versions, built directly from the CPython development repository. In @@ -182,7 +188,7 @@ at https://docs.python.org/3/. PDF, plain text, and downloadable HTML versions also available at https://docs.python.org/3/download.html. The documentation is written in reStructuredText and processed by `the Sphinx -documentation tool <http://sphinx-doc.org/>`__. The reStructuredText source for +documentation tool <https://www.sphinx-doc.org/>`__. The reStructuredText source for the documentation is part of the Python source distribution. @@ -230,14 +236,8 @@ You can also access the development version of Python through Git. See How do I submit bug reports and patches for Python? --------------------------------------------------- -To report a bug or submit a patch, please use the Roundup installation at -https://bugs.python.org/. - -You must have a Roundup account to report bugs; this makes it possible for us to -contact you if we have follow-up questions. It will also enable Roundup to send -you updates as we act on your bug. If you had previously used SourceForge to -report bugs to Python, you can obtain your Roundup password through Roundup's -`password reset procedure <https://bugs.python.org/user?@template=forgotten>`_. +To report a bug or submit a patch, use the issue tracker at +https://github.com/python/cpython/issues. For more information on how Python is developed, consult `the Python Developer's Guide <https://devguide.python.org/>`_. @@ -270,7 +270,7 @@ Where in the world is www.python.org located? --------------------------------------------- The Python project's infrastructure is located all over the world and is managed -by the Python Infrastructure Team. Details `here <http://infra.psf.io>`__. +by the Python Infrastructure Team. Details `here <https://infra.psf.io>`__. Why is it called Python? @@ -310,7 +310,7 @@ The latest stable releases can always be found on the `Python download page <https://www.python.org/downloads/>`_. There are two production-ready versions of Python: 2.x and 3.x. The recommended version is 3.x, which is supported by most widely used libraries. Although 2.x is still widely used, `it is not -maintained anymore <https://www.python.org/dev/peps/pep-0373/>`_. +maintained anymore <https://peps.python.org/pep-0373/>`_. How many people are using Python? --------------------------------- @@ -335,8 +335,8 @@ Consulting the proceedings for `past Python conferences different companies and organizations. High-profile Python projects include `the Mailman mailing list manager -<http://www.list.org>`_ and `the Zope application server -<http://www.zope.org>`_. Several Linux distributions, most notably `Red Hat +<https://www.list.org>`_ and `the Zope application server +<https://www.zope.dev>`_. Several Linux distributions, most notably `Red Hat <https://www.redhat.com>`_, have written part or all of their installer and system administration software in Python. Companies that use Python internally include Google, Yahoo, and Lucasfilm Ltd. @@ -345,7 +345,7 @@ include Google, Yahoo, and Lucasfilm Ltd. What new developments are expected for Python in the future? ------------------------------------------------------------ -See https://www.python.org/dev/peps/ for the Python Enhancement Proposals +See https://peps.python.org/ for the Python Enhancement Proposals (PEPs). PEPs are design documents describing a suggested new feature for Python, providing a concise technical specification and a rationale. Look for a PEP titled "Python X.Y Release Schedule", where X.Y is a version that hasn't been @@ -435,7 +435,7 @@ With the interpreter, documentation is never far from the student as they are programming. There are also good IDEs for Python. IDLE is a cross-platform IDE for Python -that is written in Python using Tkinter. PythonWin is a Windows-specific IDE. +that is written in Python using Tkinter. Emacs users will be happy to know that there is a very good Python mode for Emacs. All of these programming environments provide syntax highlighting, auto-indenting, and access to the interactive interpreter while coding. Consult diff --git a/Doc/faq/gui.rst b/Doc/faq/gui.rst index 86c56d957cd..023ffdf0db5 100644 --- a/Doc/faq/gui.rst +++ b/Doc/faq/gui.rst @@ -49,7 +49,7 @@ environment variables. To get truly stand-alone applications, the Tcl scripts that form the library have to be integrated into the application as well. One tool supporting that is SAM (stand-alone modules), which is part of the Tix distribution -(http://tix.sourceforge.net/). +(https://tix.sourceforge.net/). Build Tix with SAM enabled, perform the appropriate call to :c:func:`Tclsam_init`, etc. inside Python's diff --git a/Doc/faq/library.rst b/Doc/faq/library.rst index b9e541c150d..a9cde456575 100644 --- a/Doc/faq/library.rst +++ b/Doc/faq/library.rst @@ -180,8 +180,8 @@ How do I create documentation from doc strings? The :mod:`pydoc` module can create HTML from the doc strings in your Python source code. An alternative for creating API documentation purely from -docstrings is `epydoc <http://epydoc.sourceforge.net/>`_. `Sphinx -<http://sphinx-doc.org>`_ can also include docstring content. +docstrings is `epydoc <https://epydoc.sourceforge.net/>`_. `Sphinx +<https://www.sphinx-doc.org>`_ can also include docstring content. How do I get a single keypress at a time? @@ -483,8 +483,14 @@ including :func:`~shutil.copyfile`, :func:`~shutil.copytree`, and How do I copy a file? --------------------- -The :mod:`shutil` module contains a :func:`~shutil.copyfile` function. Note -that on MacOS 9 it doesn't copy the resource fork and Finder info. +The :mod:`shutil` module contains a :func:`~shutil.copyfile` function. +Note that on Windows NTFS volumes, it does not copy +`alternate data streams +<https://en.wikipedia.org/wiki/NTFS#Alternate_data_stream_(ADS)>`_ +nor `resource forks <https://en.wikipedia.org/wiki/Resource_fork>`__ +on macOS HFS+ volumes, though both are now rarely used. +It also doesn't copy file permissions and metadata, though using +:func:`shutil.copy2` instead will preserve most (though not all) of it. How do I read (or write) binary data? @@ -603,7 +609,7 @@ use ``p.read(n)``. substituted for standard input and output. You will have to use pseudo ttys ("ptys") instead of pipes. Or you can use a Python interface to Don Libes' "expect" library. A Python extension that interfaces to expect is called - "expy" and available from http://expectpy.sourceforge.net. A pure Python + "expy" and available from https://expectpy.sourceforge.net. A pure Python solution that works like expect is `pexpect <https://pypi.org/project/pexpect/>`_. @@ -664,7 +670,7 @@ A summary of available frameworks is maintained by Paul Boddie at https://wiki.python.org/moin/WebProgramming\ . Cameron Laird maintains a useful set of pages about Python web technologies at -http://phaseit.net/claird/comp.lang.python/web_python. +https://web.archive.org/web/20210224183619/http://phaseit.net/claird/comp.lang.python/web_python. How can I mimic CGI form submission (METHOD=POST)? diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 154563a859e..ba42289f346 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -25,8 +25,9 @@ Reference Manual <pdb>`. You can also write your own debugger by using the code for pdb as an example. The IDLE interactive development environment, which is part of the standard -Python distribution (normally available as Tools/scripts/idle), includes a -graphical debugger. +Python distribution (normally available as +`Tools/scripts/idle3 <https://github.com/python/cpython/blob/main/Tools/scripts/idle3>`_), +includes a graphical debugger. PythonWin is a Python IDE that includes a GUI debugger based on pdb. The PythonWin debugger colors breakpoints and has quite a few cool features such as @@ -35,7 +36,7 @@ debugging non-PythonWin programs. PythonWin is available as part of as a part of the `ActivePython <https://www.activestate.com/products/python/>`_ distribution. -`Eric <http://eric-ide.python-projects.org/>`_ is an IDE built on PyQt +`Eric <https://eric-ide.python-projects.org/>`_ is an IDE built on PyQt and the Scintilla editing component. `trepan3k <https://github.com/rocky/python3-trepan/>`_ is a gdb-like debugger. @@ -56,7 +57,7 @@ Are there tools to help find bugs or perform static analysis? Yes. -`Pylint <https://www.pylint.org/>`_ and +`Pylint <https://pylint.pycqa.org/en/latest/index.html>`_ and `Pyflakes <https://github.com/PyCQA/pyflakes>`_ do basic checking that will help you catch bugs sooner. @@ -78,7 +79,8 @@ set of modules required by a program and bind these modules together with a Python binary to produce a single executable. One is to use the freeze tool, which is included in the Python source tree as -``Tools/freeze``. It converts Python byte code to C arrays; a C compiler you can +`Tools/freeze <https://github.com/python/cpython/tree/main/Tools/freeze>`_. +It converts Python byte code to C arrays; with a C compiler you can embed all your modules into a new program, which is then linked with the standard Python modules. @@ -95,11 +97,11 @@ The following packages can help with the creation of console and GUI executables: * `Nuitka <https://nuitka.net/>`_ (Cross-platform) -* `PyInstaller <http://www.pyinstaller.org/>`_ (Cross-platform) +* `PyInstaller <https://pyinstaller.org/>`_ (Cross-platform) * `PyOxidizer <https://pyoxidizer.readthedocs.io/en/stable/>`_ (Cross-platform) * `cx_Freeze <https://marcelotduarte.github.io/cx_Freeze/>`_ (Cross-platform) * `py2app <https://github.com/ronaldoussoren/py2app>`_ (macOS only) -* `py2exe <http://www.py2exe.org/>`_ (Windows only) +* `py2exe <https://www.py2exe.org/>`_ (Windows only) Are there coding standards or a style guide for Python programs? ---------------------------------------------------------------- @@ -111,10 +113,12 @@ Yes. The coding style required for standard library modules is documented as Core Language ============= +.. _faq-unboundlocalerror: + Why am I getting an UnboundLocalError when the variable has a value? -------------------------------------------------------------------- -It can be a surprise to get the UnboundLocalError in previously working +It can be a surprise to get the :exc:`UnboundLocalError` in previously working code when it is modified by adding an assignment statement somewhere in the body of a function. @@ -123,6 +127,7 @@ This code: >>> x = 10 >>> def bar(): ... print(x) + ... >>> bar() 10 @@ -133,7 +138,7 @@ works, but this code: ... print(x) ... x += 1 -results in an UnboundLocalError: +results in an :exc:`!UnboundLocalError`: >>> foo() Traceback (most recent call last): @@ -155,6 +160,7 @@ global: ... global x ... print(x) ... x += 1 + ... >>> foobar() 10 @@ -176,6 +182,7 @@ keyword: ... x += 1 ... bar() ... print(x) + ... >>> foo() 10 11 @@ -273,7 +280,7 @@ main.py:: import mod print(config.x) -Note that using a module is also the basis for implementing the Singleton design +Note that using a module is also the basis for implementing the singleton design pattern, for the same reason. @@ -291,10 +298,10 @@ using multiple imports per line uses less screen space. It's good practice if you import modules in the following order: -1. standard library modules -- e.g. ``sys``, ``os``, ``getopt``, ``re`` +1. standard library modules -- e.g. :mod:`sys`, :mod:`os`, :mod:`argparse`, :mod:`re` 2. third-party library modules (anything installed in Python's site-packages - directory) -- e.g. mx.DateTime, ZODB, PIL.Image, etc. -3. locally-developed modules + directory) -- e.g. :mod:`!dateutil`, :mod:`!requests`, :mod:`!PIL.Image` +3. locally developed modules It is sometimes necessary to move imports to a function or class to avoid problems with circular imports. Gordon McMillan says: @@ -409,8 +416,9 @@ What is the difference between arguments and parameters? :term:`Parameters <parameter>` are defined by the names that appear in a function definition, whereas :term:`arguments <argument>` are the values -actually passed to a function when calling it. Parameters define what types of -arguments a function can accept. For example, given the function definition:: +actually passed to a function when calling it. Parameters define what +:term:`kind of arguments <parameter>` a function can accept. For +example, given the function definition:: def func(foo, bar=None, **kwargs): pass @@ -470,7 +478,7 @@ object ``x`` refers to). After this assignment we have two objects (the ints Some operations (for example ``y.append(10)`` and ``y.sort()``) mutate the object, whereas superficially similar operations (for example ``y = y + [10]`` -and ``sorted(y)``) create a new object. In general in Python (and in all cases +and :func:`sorted(y) <sorted>`) create a new object. In general in Python (and in all cases in the standard library) a method that mutates an object will return ``None`` to help avoid getting the two types of operations confused. So if you mistakenly write ``y.sort()`` thinking it will give you a sorted copy of ``y``, @@ -643,7 +651,7 @@ Sequences can be copied by slicing:: How can I find the methods or attributes of an object? ------------------------------------------------------ -For an instance x of a user-defined class, ``dir(x)`` returns an alphabetized +For an instance ``x`` of a user-defined class, :func:`dir(x) <dir>` returns an alphabetized list of the names containing the instance attributes and methods and attributes defined by its class. @@ -668,9 +676,9 @@ callable. Consider the following code:: <__main__.A object at 0x16D07CC> Arguably the class has a name: even though it is bound to two names and invoked -through the name B the created instance is still reported as an instance of -class A. However, it is impossible to say whether the instance's name is a or -b, since both names are bound to the same value. +through the name ``B`` the created instance is still reported as an instance of +class ``A``. However, it is impossible to say whether the instance's name is ``a`` or +``b``, since both names are bound to the same value. Generally speaking it should not be necessary for your code to "know the names" of particular values. Unless you are deliberately writing introspective @@ -734,7 +742,7 @@ Is it possible to write obfuscated one-liners in Python? -------------------------------------------------------- Yes. Usually this is done by nesting :keyword:`lambda` within -:keyword:`!lambda`. See the following three examples, due to Ulf Bartelt:: +:keyword:`!lambda`. See the following three examples, slightly adapted from Ulf Bartelt:: from functools import reduce @@ -747,7 +755,7 @@ Yes. Usually this is done by nesting :keyword:`lambda` within f(x,f), range(10)))) # Mandelbrot set - print((lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y, + print((lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+'\n'+y,map(lambda y, Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,i=IM, Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro, i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f:(k<=0)or (x*x+y*y @@ -770,7 +778,7 @@ What does the slash(/) in the parameter list of a function mean? A slash in the argument list of a function denotes that the parameters prior to it are positional-only. Positional-only parameters are the ones without an -externally-usable name. Upon calling a function that accepts positional-only +externally usable name. Upon calling a function that accepts positional-only parameters, arguments are mapped to parameters based solely on their position. For example, :func:`divmod` is a function that accepts positional-only parameters. Its documentation looks like this:: @@ -840,7 +848,7 @@ How do I get int literal attribute instead of SyntaxError? ---------------------------------------------------------- Trying to lookup an ``int`` literal attribute in the normal manner gives -a syntax error because the period is seen as a decimal point:: +a :exc:`SyntaxError` because the period is seen as a decimal point:: >>> 1.__class__ File "<stdin>", line 1 @@ -886,7 +894,7 @@ leading '0' in a decimal number (except '0'). How do I convert a number to a string? -------------------------------------- -To convert, e.g., the number 144 to the string '144', use the built-in type +To convert, e.g., the number ``144`` to the string ``'144'``, use the built-in type constructor :func:`str`. If you want a hexadecimal or octal representation, use the built-in functions :func:`hex` or :func:`oct`. For fancy formatting, see the :ref:`f-strings` and :ref:`formatstrings` sections, @@ -1005,11 +1013,11 @@ Not as such. For simple input parsing, the easiest approach is usually to split the line into whitespace-delimited words using the :meth:`~str.split` method of string objects and then convert decimal strings to numeric values using :func:`int` or -:func:`float`. ``split()`` supports an optional "sep" parameter which is useful +:func:`float`. :meth:`!split()` supports an optional "sep" parameter which is useful if the line uses something other than whitespace as a separator. For more complicated input parsing, regular expressions are more powerful -than C's :c:func:`sscanf` and better suited for the task. +than C's ``sscanf`` and better suited for the task. What does 'UnicodeDecodeError' or 'UnicodeEncodeError' error mean? @@ -1018,6 +1026,46 @@ What does 'UnicodeDecodeError' or 'UnicodeEncodeError' error mean? See the :ref:`unicode-howto`. +.. _faq-programming-raw-string-backslash: + +Can I end a raw string with an odd number of backslashes? +--------------------------------------------------------- + +A raw string ending with an odd number of backslashes will escape the string's quote:: + + >>> r'C:\this\will\not\work\' + File "<stdin>", line 1 + r'C:\this\will\not\work\' + ^ + SyntaxError: unterminated string literal (detected at line 1) + +There are several workarounds for this. One is to use regular strings and double +the backslashes:: + + >>> 'C:\\this\\will\\work\\' + 'C:\\this\\will\\work\\' + +Another is to concatenate a regular string containing an escaped backslash to the +raw string:: + + >>> r'C:\this\will\work' '\\' + 'C:\\this\\will\\work\\' + +It is also possible to use :func:`os.path.join` to append a backslash on Windows:: + + >>> os.path.join(r'C:\this\will\work', '') + 'C:\\this\\will\\work\\' + +Note that while a backslash will "escape" a quote for the purposes of +determining where the raw string ends, no escaping occurs when interpreting the +value of the raw string. That is, the backslash remains present in the value of +the raw string:: + + >>> r'backslash\'preserved' + "backslash\\'preserved" + +Also see the specification in the :ref:`language reference <strings>`. + Performance =========== @@ -1065,7 +1113,7 @@ performance levels: detrimental to readability). If you have reached the limit of what pure Python can allow, there are tools -to take you further away. For example, `Cython <http://cython.org>`_ can +to take you further away. For example, `Cython <https://cython.org>`_ can compile a slightly modified version of Python code into a C extension, and can be used on many different platforms. Cython can take advantage of compilation (and optional type annotations) to make your code significantly @@ -1205,15 +1253,16 @@ difference is that a Python list can contain objects of many different types. The ``array`` module also provides methods for creating arrays of fixed types with compact representations, but they are slower to index than lists. Also -note that NumPy and other third party packages define array-like structures with +note that `NumPy <https://numpy.org/>`_ +and other third party packages define array-like structures with various characteristics as well. -To get Lisp-style linked lists, you can emulate cons cells using tuples:: +To get Lisp-style linked lists, you can emulate *cons cells* using tuples:: lisp_list = ("like", ("this", ("example", None) ) ) If mutability is desired, you could use lists instead of tuples. Here the -analogue of lisp car is ``lisp_list[0]`` and the analogue of cdr is +analogue of a Lisp *car* is ``lisp_list[0]`` and the analogue of *cdr* is ``lisp_list[1]``. Only do this if you're sure you really need to, because it's usually a lot slower than using Python lists. @@ -1269,16 +1318,28 @@ use a list comprehension:: A = [[None] * w for i in range(h)] Or, you can use an extension that provides a matrix datatype; `NumPy -<http://www.numpy.org/>`_ is the best known. +<https://numpy.org/>`_ is the best known. -How do I apply a method to a sequence of objects? -------------------------------------------------- +How do I apply a method or function to a sequence of objects? +------------------------------------------------------------- -Use a list comprehension:: +To call a method or function and accumulate the return values is a list, +a :term:`list comprehension` is an elegant solution:: result = [obj.method() for obj in mylist] + result = [function(obj) for obj in mylist] + +To just run the method or function without saving the return values, +a plain :keyword:`for` loop will suffice:: + + for obj in mylist: + obj.method() + + for obj in mylist: + function(obj) + .. _faq-augmented-assignment-tuple-error: Why does a_tuple[i] += ['item'] raise an exception when the addition works? @@ -1333,11 +1394,12 @@ that even though there was an error, the append worked:: ['foo', 'item'] To see why this happens, you need to know that (a) if an object implements an -``__iadd__`` magic method, it gets called when the ``+=`` augmented assignment +:meth:`~object.__iadd__` magic method, it gets called when the ``+=`` augmented +assignment is executed, and its return value is what gets used in the assignment statement; -and (b) for lists, ``__iadd__`` is equivalent to calling ``extend`` on the list +and (b) for lists, :meth:`!__iadd__` is equivalent to calling :meth:`~list.extend` on the list and returning the list. That's why we say that for lists, ``+=`` is a -"shorthand" for ``list.extend``:: +"shorthand" for :meth:`!list.extend`:: >>> a_list = [] >>> a_list += [1] @@ -1362,7 +1424,7 @@ Thus, in our tuple example what is happening is equivalent to:: ... TypeError: 'tuple' object does not support item assignment -The ``__iadd__`` succeeds, and thus the list is extended, but even though +The :meth:`!__iadd__` succeeds, and thus the list is extended, but even though ``result`` points to the same object that ``a_tuple[0]`` already points to, that final assignment still results in an error, because tuples are immutable. @@ -1439,7 +1501,8 @@ See also :ref:`why-self`. How do I check if an object is an instance of a given class or of a subclass of it? ----------------------------------------------------------------------------------- -Use the built-in function ``isinstance(obj, cls)``. You can check if an object +Use the built-in function :func:`isinstance(obj, cls) <isinstance>`. You can +check if an object is an instance of any of a number of classes by providing a tuple instead of a single class, e.g. ``isinstance(obj, (class1, class2, ...))``, and can also check whether an object is one of Python's built-in types, e.g. @@ -1536,13 +1599,13 @@ Here the ``UpperOut`` class redefines the ``write()`` method to convert the argument string to uppercase before calling the underlying ``self._outfile.write()`` method. All other methods are delegated to the underlying ``self._outfile`` object. The delegation is accomplished via the -``__getattr__`` method; consult :ref:`the language reference <attribute-access>` +:meth:`~object.__getattr__` method; consult :ref:`the language reference <attribute-access>` for more information about controlling attribute access. Note that for more general cases delegation can get trickier. When attributes -must be set as well as retrieved, the class must define a :meth:`__setattr__` +must be set as well as retrieved, the class must define a :meth:`~object.__setattr__` method too, and it must do so carefully. The basic implementation of -:meth:`__setattr__` is roughly equivalent to the following:: +:meth:`!__setattr__` is roughly equivalent to the following:: class X: ... @@ -1550,7 +1613,8 @@ method too, and it must do so carefully. The basic implementation of self.__dict__[name] = value ... -Most :meth:`__setattr__` implementations must modify ``self.__dict__`` to store +Most :meth:`!__setattr__` implementations must modify +:meth:`self.__dict__ <object.__dict__>` to store local state for self without causing an infinite recursion. @@ -1688,17 +1752,17 @@ My class defines __del__ but it is not called when I delete the object. There are several possible reasons for this. -The del statement does not necessarily call :meth:`__del__` -- it simply +The :keyword:`del` statement does not necessarily call :meth:`~object.__del__` -- it simply decrements the object's reference count, and if this reaches zero -:meth:`__del__` is called. +:meth:`!__del__` is called. If your data structures contain circular links (e.g. a tree where each child has a parent reference and each parent has a list of children) the reference counts will never go back to zero. Once in a while Python runs an algorithm to detect such cycles, but the garbage collector might run some time after the last -reference to your data structure vanishes, so your :meth:`__del__` method may be +reference to your data structure vanishes, so your :meth:`!__del__` method may be called at an inconvenient and random time. This is inconvenient if you're trying -to reproduce a problem. Worse, the order in which object's :meth:`__del__` +to reproduce a problem. Worse, the order in which object's :meth:`!__del__` methods are executed is arbitrary. You can run :func:`gc.collect` to force a collection, but there *are* pathological cases where objects will never be collected. @@ -1706,7 +1770,7 @@ collected. Despite the cycle collector, it's still a good idea to define an explicit ``close()`` method on objects to be called whenever you're done with them. The ``close()`` method can then remove attributes that refer to subobjects. Don't -call :meth:`__del__` directly -- :meth:`__del__` should call ``close()`` and +call :meth:`!__del__` directly -- :meth:`!__del__` should call ``close()`` and ``close()`` should make sure that it can be called more than once for the same object. @@ -1723,7 +1787,7 @@ and sibling references (if they need them!). Normally, calling :func:`sys.exc_clear` will take care of this by clearing the last recorded exception. -Finally, if your :meth:`__del__` method raises an exception, a warning message +Finally, if your :meth:`!__del__` method raises an exception, a warning message is printed to :data:`sys.stderr`. @@ -1819,7 +1883,7 @@ for ``None``. This reads like plain English in code and avoids confusion with other objects that may have boolean values that evaluate to false. 2) Detecting optional arguments can be tricky when ``None`` is a valid input -value. In those situations, you can create an singleton sentinel object +value. In those situations, you can create a singleton sentinel object guaranteed to be distinct from other objects. For example, here is how to implement a method that behaves like :meth:`dict.pop`:: @@ -1851,8 +1915,8 @@ For example, here is the implementation of How can a subclass control what data is stored in an immutable instance? ------------------------------------------------------------------------ -When subclassing an immutable type, override the :meth:`__new__` method -instead of the :meth:`__init__` method. The latter only runs *after* an +When subclassing an immutable type, override the :meth:`~object.__new__` method +instead of the :meth:`~object.__init__` method. The latter only runs *after* an instance is created, which is too late to alter data in an immutable instance. @@ -1896,6 +1960,8 @@ The classes can be used like this: 'blog-why-python-rocks' +.. _faq-cache-method-calls: + How do I cache method calls? ---------------------------- @@ -1908,7 +1974,7 @@ The *cached_property* approach only works with methods that do not take any arguments. It does not create a reference to the instance. The cached method result will be kept only as long as the instance is alive. -The advantage is that when an instance is not longer used, the cached +The advantage is that when an instance is no longer used, the cached method result will be released right away. The disadvantage is that if instances accumulate, so too will the accumulated method results. They can grow without bound. @@ -1951,9 +2017,9 @@ relevant instance attributes are mutable, the *cached_property* approach can't be made to work because it cannot detect changes to the attributes. -The *lru_cache* approach can be made to work, but the class needs to define the -*__eq__* and *__hash__* methods so the cache can detect relevant attribute -updates:: +To make the *lru_cache* approach work when the *station_id* is mutable, +the class needs to define the :meth:`~object.__eq__` and :meth:`~object.__hash__` +methods so that the cache can detect relevant attribute updates:: class Weather: "Example with a mutable station identifier" diff --git a/Doc/faq/windows.rst b/Doc/faq/windows.rst index 6b95819c8ee..c0c92fdbbc8 100644 --- a/Doc/faq/windows.rst +++ b/Doc/faq/windows.rst @@ -26,8 +26,8 @@ with running programs from the Windows command line then everything will seem obvious; otherwise, you might need a little more guidance. Unless you use some sort of integrated development environment, you will end up -*typing* Windows commands into what is variously referred to as a "DOS window" -or "Command prompt window". Usually you can create such a window from your +*typing* Windows commands into what is referred to as a +"Command prompt window". Usually you can create such a window from your search bar by searching for ``cmd``. You should be able to recognize when you have started such a window because you will see a Windows "command prompt", which usually looks like this: @@ -167,7 +167,7 @@ How can I embed Python into a Windows application? Embedding the Python interpreter in a Windows app can be summarized as follows: -1. Do _not_ build Python into your .exe file directly. On Windows, Python must +1. Do **not** build Python into your .exe file directly. On Windows, Python must be a DLL to handle importing modules that are themselves DLL's. (This is the first key undocumented fact.) Instead, link to :file:`python{NN}.dll`; it is typically installed in ``C:\Windows\System``. *NN* is the Python version, a @@ -186,15 +186,12 @@ Embedding the Python interpreter in a Windows app can be summarized as follows: by the Windows ``GetProcAddress()`` routine. Macros can make using these pointers transparent to any C code that calls routines in Python's C API. - Borland note: convert :file:`python{NN}.lib` to OMF format using Coff2Omf.exe - first. - .. XXX what about static linking? 2. If you use SWIG, it is easy to create a Python "extension module" that will make the app's data and methods available to Python. SWIG will handle just about all the grungy details for you. The result is C code that you link - *into* your .exe file (!) You do _not_ have to create a DLL file, and this + *into* your .exe file (!) You do **not** have to create a DLL file, and this also simplifies linking. 3. SWIG will create an init function (a C function) whose name depends on the @@ -221,10 +218,10 @@ Embedding the Python interpreter in a Windows app can be summarized as follows: 5. There are two problems with Python's C API which will become apparent if you use a compiler other than MSVC, the compiler used to build pythonNN.dll. - Problem 1: The so-called "Very High Level" functions that take FILE * + Problem 1: The so-called "Very High Level" functions that take ``FILE *`` arguments will not work in a multi-compiler environment because each - compiler's notion of a struct FILE will be different. From an implementation - standpoint these are very _low_ level functions. + compiler's notion of a ``struct FILE`` will be different. From an implementation + standpoint these are very low level functions. Problem 2: SWIG generates the following code when generating wrappers to void functions: @@ -280,3 +277,10 @@ Use the :mod:`msvcrt` module. This is a standard Windows-specific extension mod It defines a function ``kbhit()`` which checks whether a keyboard hit is present, and ``getch()`` which gets one character without echoing it. +How do I solve the missing api-ms-win-crt-runtime-l1-1-0.dll error? +------------------------------------------------------------------- + +This can occur on Python 3.5 and later when using Windows 8.1 or earlier without all updates having been installed. +First ensure your operating system is supported and is up to date, and if that does not resolve the issue, +visit the `Microsoft support page <https://support.microsoft.com/en-us/help/3118401/>`_ +for guidance on manually installing the C Runtime update. diff --git a/Doc/glossary.rst b/Doc/glossary.rst index e71f6c0406a..3d74d550dc3 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -136,10 +136,17 @@ Glossary :exc:`StopAsyncIteration` exception. Introduced by :pep:`492`. attribute - A value associated with an object which is referenced by name using - dotted expressions. For example, if an object *o* has an attribute + A value associated with an object which is usually referenced by name + using dotted expressions. + For example, if an object *o* has an attribute *a* it would be referenced as *o.a*. + It is possible to give an object an attribute whose name is not an + identifier as defined by :ref:`identifiers`, for example using + :func:`setattr`, if the object allows it. + Such an attribute will not be accessible using a dotted expression, + and would instead need to be retrieved with :func:`getattr`. + awaitable An object that can be used in an :keyword:`await` expression. Can be a :term:`coroutine` or an object with an :meth:`__await__` method. @@ -203,6 +210,16 @@ Glossary A list of bytecode instructions can be found in the documentation for :ref:`the dis module <bytecodes>`. + callable + A callable is an object that can be called, possibly with a set + of arguments (see :term:`argument`), with the following syntax:: + + callable(argument1, argument2, ...) + + A :term:`function`, and by extension a :term:`method`, is a callable. + An instance of a class that implements the :meth:`~object.__call__` + method is also a callable. + callback A subroutine function which is passed as an argument to be executed at some point in the future. @@ -282,12 +299,12 @@ Glossary The decorator syntax is merely syntactic sugar, the following two function definitions are semantically equivalent:: - def f(...): + def f(arg): ... f = staticmethod(f) @staticmethod - def f(...): + def f(arg): ... The same concept exists for classes, but is less commonly used there. See @@ -532,7 +549,7 @@ Glossary machines. However, some extension modules, either standard or third-party, - are designed so as to release the GIL when doing computationally-intensive + are designed so as to release the GIL when doing computationally intensive tasks such as compression or hashing. Also, the GIL is always released when doing I/O. @@ -566,9 +583,9 @@ Glossary from their :func:`id`. IDLE - An Integrated Development Environment for Python. IDLE is a basic editor - and interpreter environment which ships with the standard distribution of - Python. + An Integrated Development and Learning Environment for Python. + :ref:`idle` is a basic editor and interpreter environment + which ships with the standard distribution of Python. immutable An object with a fixed value. Immutable objects include numbers, strings and @@ -628,7 +645,7 @@ Glossary and :class:`tuple`) and some non-sequence types like :class:`dict`, :term:`file objects <file object>`, and objects of any classes you define with an :meth:`__iter__` method or with a :meth:`__getitem__` method - that implements :term:`Sequence <sequence>` semantics. + that implements :term:`sequence` semantics. Iterables can be used in a :keyword:`for` loop and in many other places where a sequence is @@ -680,9 +697,8 @@ Glossary :meth:`str.lower` method can serve as a key function for case insensitive sorts. Alternatively, a key function can be built from a :keyword:`lambda` expression such as ``lambda r: (r[0], r[2])``. Also, - the :mod:`operator` module provides three key function constructors: - :func:`~operator.attrgetter`, :func:`~operator.itemgetter`, and - :func:`~operator.methodcaller`. See the :ref:`Sorting HOW TO + :func:`operator.attrgetter`, :func:`operator.itemgetter`, and + :func:`operator.methodcaller` are three key function constructors. See the :ref:`Sorting HOW TO <sortinghowto>` for examples of how to create and use key functions. keyword argument @@ -707,15 +723,15 @@ Glossary locale encoding On Unix, it is the encoding of the LC_CTYPE locale. It can be set with - ``locale.setlocale(locale.LC_CTYPE, new_locale)``. + :func:`locale.setlocale(locale.LC_CTYPE, new_locale) <locale.setlocale>`. - On Windows, it is the ANSI code page (ex: ``cp1252``). + On Windows, it is the ANSI code page (ex: ``"cp1252"``). - ``locale.getpreferredencoding(False)`` can be used to get the locale - encoding. + On Android and VxWorks, Python uses ``"utf-8"`` as the locale encoding. - Python uses the :term:`filesystem encoding and error handler` to convert - between Unicode filenames and bytes filenames. + ``locale.getencoding()`` can be used to get the locale encoding. + + See also the :term:`filesystem encoding and error handler`. list A built-in Python :term:`sequence`. Despite its name it is more akin @@ -743,8 +759,8 @@ Glossary mapping A container object that supports arbitrary key lookups and implements the - methods specified in the :class:`~collections.abc.Mapping` or - :class:`~collections.abc.MutableMapping` + methods specified in the :class:`collections.abc.Mapping` or + :class:`collections.abc.MutableMapping` :ref:`abstract base classes <collections-abstract-base-classes>`. Examples include :class:`dict`, :class:`collections.defaultdict`, :class:`collections.OrderedDict` and :class:`collections.Counter`. @@ -866,7 +882,7 @@ Glossary package A Python :term:`module` which can contain submodules or recursively, - subpackages. Technically, a package is a Python module with an + subpackages. Technically, a package is a Python module with a ``__path__`` attribute. See also :term:`regular package` and :term:`namespace package`. @@ -1049,8 +1065,8 @@ Glossary The number of references to an object. When the reference count of an object drops to zero, it is deallocated. Reference counting is generally not visible to Python code, but it is a key element of the - :term:`CPython` implementation. The :mod:`sys` module defines a - :func:`~sys.getrefcount` function that programmers can call to return the + :term:`CPython` implementation. Programmers can call the + :func:`sys.getrefcount` function to return the reference count for a particular object. regular package @@ -1126,7 +1142,16 @@ Glossary See also :term:`borrowed reference`. text encoding - A codec which encodes Unicode strings to bytes. + A string in Python is a sequence of Unicode code points (in range + ``U+0000``--``U+10FFFF``). To store or transfer a string, it needs to be + serialized as a sequence of bytes. + + Serializing a string into a sequence of bytes is known as "encoding", and + recreating the string from the sequence of bytes is known as "decoding". + + There are a variety of different text serialization + :ref:`codecs <standard-encodings>`, which are collectively referred to as + "text encodings". text file A :term:`file object` able to read and write :class:`str` objects. diff --git a/Doc/howto/annotations.rst b/Doc/howto/annotations.rst index 3e61103e99c..472069032d6 100644 --- a/Doc/howto/annotations.rst +++ b/Doc/howto/annotations.rst @@ -57,6 +57,12 @@ Accessing The Annotations Dict Of An Object In Python 3.10 And Newer newer is to call :func:`getattr` with three arguments, for example ``getattr(o, '__annotations__', None)``. + Before Python 3.10, accessing ``__annotations__`` on a class that + defines no annotations but that has a parent class with + annotations would return the parent's ``__annotations__``. + In Python 3.10 and newer, the child class's annotations + will be an empty dict instead. + Accessing The Annotations Dict Of An Object In Python 3.9 And Older =================================================================== @@ -156,7 +162,7 @@ Manually Un-Stringizing Stringized Annotations require annotating with string values that specifically *can't* be evaluated. For example: - * :pep:`604` union types using `|`, before support for this + * :pep:`604` union types using ``|``, before support for this was added to Python 3.10. * Definitions that aren't needed at runtime, only imported when :const:`typing.TYPE_CHECKING` is true. diff --git a/Doc/howto/argparse.rst b/Doc/howto/argparse.rst index a97d10cfe6b..f682587488a 100644 --- a/Doc/howto/argparse.rst +++ b/Doc/howto/argparse.rst @@ -2,7 +2,7 @@ Argparse Tutorial ***************** -:author: Tshepang Lekhonkhobe +:author: Tshepang Mbambo .. _argparse-tutorial: @@ -79,16 +79,16 @@ Following is a result of running the code: .. code-block:: shell-session - $ python3 prog.py - $ python3 prog.py --help + $ python prog.py + $ python prog.py --help usage: prog.py [-h] options: -h, --help show this help message and exit - $ python3 prog.py --verbose + $ python prog.py --verbose usage: prog.py [-h] prog.py: error: unrecognized arguments: --verbose - $ python3 prog.py foo + $ python prog.py foo usage: prog.py [-h] prog.py: error: unrecognized arguments: foo @@ -121,10 +121,10 @@ And running the code: .. code-block:: shell-session - $ python3 prog.py + $ python prog.py usage: prog.py [-h] echo prog.py: error: the following arguments are required: echo - $ python3 prog.py --help + $ python prog.py --help usage: prog.py [-h] echo positional arguments: @@ -132,7 +132,7 @@ And running the code: options: -h, --help show this help message and exit - $ python3 prog.py foo + $ python prog.py foo foo Here is what's happening: @@ -166,7 +166,7 @@ And we get: .. code-block:: shell-session - $ python3 prog.py -h + $ python prog.py -h usage: prog.py [-h] echo positional arguments: @@ -187,7 +187,7 @@ Following is a result of running the code: .. code-block:: shell-session - $ python3 prog.py 4 + $ python prog.py 4 Traceback (most recent call last): File "prog.py", line 5, in <module> print(args.square**2) @@ -208,9 +208,9 @@ Following is a result of running the code: .. code-block:: shell-session - $ python3 prog.py 4 + $ python prog.py 4 16 - $ python3 prog.py four + $ python prog.py four usage: prog.py [-h] square prog.py: error: argument square: invalid int value: 'four' @@ -235,17 +235,17 @@ And the output: .. code-block:: shell-session - $ python3 prog.py --verbosity 1 + $ python prog.py --verbosity 1 verbosity turned on - $ python3 prog.py - $ python3 prog.py --help + $ python prog.py + $ python prog.py --help usage: prog.py [-h] [--verbosity VERBOSITY] options: -h, --help show this help message and exit --verbosity VERBOSITY increase output verbosity - $ python3 prog.py --verbosity + $ python prog.py --verbosity usage: prog.py [-h] [--verbosity VERBOSITY] prog.py: error: argument --verbosity: expected one argument @@ -281,12 +281,12 @@ And the output: .. code-block:: shell-session - $ python3 prog.py --verbose + $ python prog.py --verbose verbosity turned on - $ python3 prog.py --verbose 1 + $ python prog.py --verbose 1 usage: prog.py [-h] [--verbose] prog.py: error: unrecognized arguments: 1 - $ python3 prog.py --help + $ python prog.py --help usage: prog.py [-h] [--verbose] options: @@ -327,9 +327,9 @@ And here goes: .. code-block:: shell-session - $ python3 prog.py -v + $ python prog.py -v verbosity turned on - $ python3 prog.py --help + $ python prog.py --help usage: prog.py [-h] [-v] options: @@ -361,14 +361,14 @@ And now the output: .. code-block:: shell-session - $ python3 prog.py + $ python prog.py usage: prog.py [-h] [-v] square prog.py: error: the following arguments are required: square - $ python3 prog.py 4 + $ python prog.py 4 16 - $ python3 prog.py 4 --verbose + $ python prog.py 4 --verbose the square of 4 equals 16 - $ python3 prog.py --verbose 4 + $ python prog.py --verbose 4 the square of 4 equals 16 * We've brought back a positional argument, hence the complaint. @@ -397,16 +397,16 @@ And the output: .. code-block:: shell-session - $ python3 prog.py 4 + $ python prog.py 4 16 - $ python3 prog.py 4 -v + $ python prog.py 4 -v usage: prog.py [-h] [-v VERBOSITY] square prog.py: error: argument -v/--verbosity: expected one argument - $ python3 prog.py 4 -v 1 + $ python prog.py 4 -v 1 4^2 == 16 - $ python3 prog.py 4 -v 2 + $ python prog.py 4 -v 2 the square of 4 equals 16 - $ python3 prog.py 4 -v 3 + $ python prog.py 4 -v 3 16 These all look good except the last one, which exposes a bug in our program. @@ -431,10 +431,10 @@ And the output: .. code-block:: shell-session - $ python3 prog.py 4 -v 3 + $ python prog.py 4 -v 3 usage: prog.py [-h] [-v {0,1,2}] square prog.py: error: argument -v/--verbosity: invalid choice: 3 (choose from 0, 1, 2) - $ python3 prog.py 4 -h + $ python prog.py 4 -h usage: prog.py [-h] [-v {0,1,2}] square positional arguments: @@ -473,18 +473,18 @@ to count the number of occurrences of specific options. .. code-block:: shell-session - $ python3 prog.py 4 + $ python prog.py 4 16 - $ python3 prog.py 4 -v + $ python prog.py 4 -v 4^2 == 16 - $ python3 prog.py 4 -vv + $ python prog.py 4 -vv the square of 4 equals 16 - $ python3 prog.py 4 --verbosity --verbosity + $ python prog.py 4 --verbosity --verbosity the square of 4 equals 16 - $ python3 prog.py 4 -v 1 + $ python prog.py 4 -v 1 usage: prog.py [-h] [-v] square prog.py: error: unrecognized arguments: 1 - $ python3 prog.py 4 -h + $ python prog.py 4 -h usage: prog.py [-h] [-v] square positional arguments: @@ -493,7 +493,7 @@ to count the number of occurrences of specific options. options: -h, --help show this help message and exit -v, --verbosity increase output verbosity - $ python3 prog.py 4 -vvv + $ python prog.py 4 -vvv 16 * Yes, it's now more of a flag (similar to ``action="store_true"``) in the @@ -540,11 +540,11 @@ And this is what it gives: .. code-block:: shell-session - $ python3 prog.py 4 -vvv + $ python prog.py 4 -vvv the square of 4 equals 16 - $ python3 prog.py 4 -vvvv + $ python prog.py 4 -vvvv the square of 4 equals 16 - $ python3 prog.py 4 + $ python prog.py 4 Traceback (most recent call last): File "prog.py", line 11, in <module> if args.verbosity >= 2: @@ -584,7 +584,7 @@ And: .. code-block:: shell-session - $ python3 prog.py 4 + $ python prog.py 4 16 You can go quite far just with what we've learned so far, @@ -617,10 +617,10 @@ Output: .. code-block:: shell-session - $ python3 prog.py + $ python prog.py usage: prog.py [-h] [-v] x y prog.py: error: the following arguments are required: x, y - $ python3 prog.py -h + $ python prog.py -h usage: prog.py [-h] [-v] x y positional arguments: @@ -630,7 +630,7 @@ Output: options: -h, --help show this help message and exit -v, --verbosity - $ python3 prog.py 4 2 -v + $ python prog.py 4 2 -v 4^2 == 16 @@ -655,15 +655,44 @@ Output: .. code-block:: shell-session - $ python3 prog.py 4 2 + $ python prog.py 4 2 16 - $ python3 prog.py 4 2 -v + $ python prog.py 4 2 -v 4^2 == 16 - $ python3 prog.py 4 2 -vv + $ python prog.py 4 2 -vv Running 'prog.py' 4^2 == 16 +.. _specifying-ambiguous-arguments: + +Specifying ambiguous arguments +------------------------------ + +When there is ambiguity in deciding whether an argument is positional or for an +argument, ``--`` can be used to tell :meth:`~ArgumentParser.parse_args` that +everything after that is a positional argument:: + + >>> parser = argparse.ArgumentParser(prog='PROG') + >>> parser.add_argument('-n', nargs='+') + >>> parser.add_argument('args', nargs='*') + + >>> # ambiguous, so parse_args assumes it's an option + >>> parser.parse_args(['-f']) + usage: PROG [-h] [-n N [N ...]] [args ...] + PROG: error: unrecognized arguments: -f + + >>> parser.parse_args(['--', '-f']) + Namespace(args=['-f'], n=None) + + >>> # ambiguous, so the -n option greedily accepts arguments + >>> parser.parse_args(['-n', '1', '2', '3']) + Namespace(args=[], n=['1', '2', '3']) + + >>> parser.parse_args(['-n', '1', '--', '2', '3']) + Namespace(args=['2', '3'], n=['1']) + + Conflicting options ------------------- @@ -698,16 +727,16 @@ demonstration. Anyways, here's the output: .. code-block:: shell-session - $ python3 prog.py 4 2 + $ python prog.py 4 2 4^2 == 16 - $ python3 prog.py 4 2 -q + $ python prog.py 4 2 -q 16 - $ python3 prog.py 4 2 -v + $ python prog.py 4 2 -v 4 to the power 2 equals 16 - $ python3 prog.py 4 2 -vq + $ python prog.py 4 2 -vq usage: prog.py [-h] [-v | -q] x y prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose - $ python3 prog.py 4 2 -v --quiet + $ python prog.py 4 2 -v --quiet usage: prog.py [-h] [-v | -q] x y prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose @@ -732,9 +761,9 @@ your program, just in case they don't know:: if args.quiet: print(answer) elif args.verbose: - print("{} to the power {} equals {}".format(args.x, args.y, answer)) + print(f"{args.x} to the power {args.y} equals {answer}") else: - print("{}^{} == {}".format(args.x, args.y, answer)) + print(f"{args.x}^{args.y} == {answer}") Note that slight difference in the usage text. Note the ``[-v | -q]``, which tells us that we can either use ``-v`` or ``-q``, @@ -742,7 +771,7 @@ but not both at the same time: .. code-block:: shell-session - $ python3 prog.py --help + $ python prog.py --help usage: prog.py [-h] [-v | -q] x y calculate X to the power of Y diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index a3c4330296b..8a10fe32735 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1,5 +1,7 @@ .. highlight:: c +.. _howto-clinic: + ********************** Argument Clinic How-To ********************** @@ -84,7 +86,7 @@ If you run that script, specifying a C file as an argument: .. code-block:: shell-session - $ python3 Tools/clinic/clinic.py foo.c + $ python Tools/clinic/clinic.py foo.c Argument Clinic will scan over the file looking for lines that look exactly like this: @@ -539,9 +541,17 @@ Let's dive in! }; -16. Compile, then run the relevant portions of the regression-test suite. +16. Argument Clinic may generate new instances of ``_Py_ID``. For example:: + + &_Py_ID(new_unique_py_id) + + If it does, you'll have to run ``Tools/scripts/generate_global_objects.py`` + to regenerate the list of precompiled identifiers at this point. + + +17. Compile, then run the relevant portions of the regression-test suite. This change should not introduce any new compile-time warnings or errors, - and there should be no externally-visible change to Python's behavior. + and there should be no externally visible change to Python's behavior. Well, except for one difference: ``inspect.signature()`` run on your function should now provide a valid signature! @@ -848,15 +858,15 @@ on the right is the text you'd replace it with. ``'s#'`` ``str(zeroes=True)`` ``'s*'`` ``Py_buffer(accept={buffer, str})`` ``'U'`` ``unicode`` -``'u'`` ``Py_UNICODE`` -``'u#'`` ``Py_UNICODE(zeroes=True)`` +``'u'`` ``wchar_t`` +``'u#'`` ``wchar_t(zeroes=True)`` ``'w*'`` ``Py_buffer(accept={rwbuffer})`` ``'Y'`` ``PyByteArrayObject`` ``'y'`` ``str(accept={bytes})`` ``'y#'`` ``str(accept={robuffer}, zeroes=True)`` ``'y*'`` ``Py_buffer`` -``'Z'`` ``Py_UNICODE(accept={str, NoneType})`` -``'Z#'`` ``Py_UNICODE(accept={str, NoneType}, zeroes=True)`` +``'Z'`` ``wchar_t(accept={str, NoneType})`` +``'Z#'`` ``wchar_t(accept={str, NoneType}, zeroes=True)`` ``'z'`` ``str(accept={str, NoneType})`` ``'z#'`` ``str(accept={str, NoneType}, zeroes=True)`` ``'z*'`` ``Py_buffer(accept={buffer, str, NoneType})`` @@ -1070,11 +1080,6 @@ None of these take parameters. For the first three, return -1 to indicate error. For ``DecodeFSDefault``, the return type is ``const char *``; return a ``NULL`` pointer to indicate an error. -(There's also an experimental ``NoneType`` converter, which lets you -return ``Py_None`` on success or ``NULL`` on failure, without having -to increment the reference count on ``Py_None``. I'm not sure it adds -enough clarity to be worth using.) - To see all the return converters Argument Clinic supports, along with their parameters (if any), just run ``Tools/clinic/clinic.py --converters`` for the full list. @@ -1117,7 +1122,7 @@ Here's the syntax for cloning a function:: ``module.class`` in the sample just to illustrate that you must use the full path to *both* functions.) -Sorry, there's no syntax for partially-cloning a function, or cloning a function +Sorry, there's no syntax for partially cloning a function, or cloning a function then modifying it. Cloning is an all-or nothing proposition. Also, the function you are cloning from must have been previously defined @@ -1249,15 +1254,15 @@ The ``defining_class`` converter is not compatible with ``__init__`` and ``__new methods, which cannot use the ``METH_METHOD`` convention. It is not possible to use ``defining_class`` with slot methods. In order to -fetch the module state from such methods, use ``_PyType_GetModuleByDef`` to -look up the module and then :c:func:`PyModule_GetState` to fetch the module +fetch the module state from such methods, use :c:func:`PyType_GetModuleByDef` +to look up the module and then :c:func:`PyModule_GetState` to fetch the module state. Example from the ``setattro`` slot method in ``Modules/_threadmodule.c``:: static int local_setattro(localobject *self, PyObject *name, PyObject *v) { - PyObject *module = _PyType_GetModuleByDef(Py_TYPE(self), &thread_module); + PyObject *module = PyType_GetModuleByDef(Py_TYPE(self), &thread_module); thread_module_state *state = get_thread_state(module); ... } @@ -1315,7 +1320,7 @@ to specify in your subclass. Here's the current list: there is no default, but not specifying a default may result in an "uninitialized variable" warning. This can easily happen when using option groups—although - properly-written code will never actually use this value, + properly written code will never actually use this value, the variable does get passed in to the impl, and the C compiler will complain about the "use" of the uninitialized value. This value should always be a @@ -1347,7 +1352,7 @@ Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c`` /*[python end generated code: output=da39a3ee5e6b4b0d input=35521e4e733823c7]*/ This block adds a converter to Argument Clinic named ``ssize_t``. Parameters -declared as ``ssize_t`` will be declared as type ``Py_ssize_t``, and will +declared as ``ssize_t`` will be declared as type :c:type:`Py_ssize_t`, and will be parsed by the ``'O&'`` format unit, which will call the ``ssize_t_converter`` converter function. ``ssize_t`` variables automatically support default values. diff --git a/Doc/howto/cporting.rst b/Doc/howto/cporting.rst index ce7700fc599..7773620b40b 100644 --- a/Doc/howto/cporting.rst +++ b/Doc/howto/cporting.rst @@ -22,5 +22,5 @@ We recommend the following resources for porting extension modules to Python 3: .. _Migrating C extensions: http://python3porting.com/cextensions.html .. _Porting guide: https://py3c.readthedocs.io/en/latest/guide.html -.. _Cython: http://cython.org/ +.. _Cython: https://cython.org/ .. _CFFI: https://cffi.readthedocs.io/en/latest/ diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst index c0149ffff37..83d80471ffc 100644 --- a/Doc/howto/curses.rst +++ b/Doc/howto/curses.rst @@ -299,8 +299,7 @@ The :meth:`~curses.window.addstr` method takes a Python string or bytestring as the value to be displayed. The contents of bytestrings are sent to the terminal as-is. Strings are encoded to bytes using the value of the window's :attr:`encoding` attribute; this defaults to -the default system encoding as returned by -:func:`locale.getpreferredencoding`. +the default system encoding as returned by :func:`locale.getencoding`. The :meth:`~curses.window.addch` methods take a character, which can be either a string of length 1, a bytestring of length 1, or an integer. @@ -537,12 +536,12 @@ Patches adding support for these would be welcome; see `the Python Developer's Guide <https://devguide.python.org/>`_ to learn more about submitting patches to Python. -* `Writing Programs with NCURSES <http://invisible-island.net/ncurses/ncurses-intro.html>`_: +* `Writing Programs with NCURSES <https://invisible-island.net/ncurses/ncurses-intro.html>`_: a lengthy tutorial for C programmers. * `The ncurses man page <https://linux.die.net/man/3/ncurses>`_ -* `The ncurses FAQ <http://invisible-island.net/ncurses/ncurses.faq.html>`_ +* `The ncurses FAQ <https://invisible-island.net/ncurses/ncurses.faq.html>`_ * `"Use curses... don't swear" <https://www.youtube.com/watch?v=eN1eZtjLEnU>`_: video of a PyCon 2013 talk on controlling terminals using curses or Urwid. -* `"Console Applications with Urwid" <http://www.pyvideo.org/video/1568/console-applications-with-urwid>`_: +* `"Console Applications with Urwid" <https://pyvideo.org/video/1568/console-applications-with-urwid>`_: video of a PyCon CA 2012 talk demonstrating some applications written using Urwid. diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index 6ce062d0fa8..74710d9b3fc 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -582,11 +582,18 @@ a pure Python equivalent: .. testcode:: + def find_name_in_mro(cls, name, default): + "Emulate _PyType_Lookup() in Objects/typeobject.c" + for base in cls.__mro__: + if name in vars(base): + return vars(base)[name] + return default + def object_getattribute(obj, name): "Emulate PyObject_GenericGetAttr() in Objects/object.c" null = object() objtype = type(obj) - cls_var = getattr(objtype, name, null) + cls_var = find_name_in_mro(objtype, name, null) descr_get = getattr(type(cls_var), '__get__', null) if descr_get is not null: if (hasattr(type(cls_var), '__set__') @@ -663,6 +670,15 @@ a pure Python equivalent: def __getattr__(self, name): return ('getattr_hook', self, name) + class D1: + def __get__(self, obj, objtype=None): + return type(self), obj, objtype + + class U1: + x = D1() + + class U2(U1): + pass .. doctest:: :hide: @@ -696,10 +712,18 @@ a pure Python equivalent: >>> b.g == b['g'] == ('getattr_hook', b, 'g') True + >>> u2 = U2() + >>> object_getattribute(u2, 'x') == u2.x == (D1, u2, U2) + True -Interestingly, attribute lookup doesn't call :meth:`object.__getattribute__` -directly. Instead, both the dot operator and the :func:`getattr` function -perform attribute lookup by way of a helper function: +Note, there is no :meth:`__getattr__` hook in the :meth:`__getattribute__` +code. That is why calling :meth:`__getattribute__` directly or with +``super().__getattribute__`` will bypass :meth:`__getattr__` entirely. + +Instead, it is the dot operator and the :func:`getattr` function that are +responsible for invoking :meth:`__getattr__` whenever :meth:`__getattribute__` +raises an :exc:`AttributeError`. Their logic is encapsulated in a helper +function: .. testcode:: @@ -744,12 +768,6 @@ perform attribute lookup by way of a helper function: ... AttributeError: 'ClassWithoutGetAttr' object has no attribute 'z' -So if :meth:`__getattr__` exists, it is called whenever :meth:`__getattribute__` -raises :exc:`AttributeError` (either directly or in one of the descriptor calls). - -Also, if a user calls :meth:`object.__getattribute__` directly, the -:meth:`__getattr__` hook is bypassed entirely. - Invocation from a class ----------------------- @@ -829,7 +847,7 @@ afterwards, :meth:`__set_name__` will need to be called manually. ORM example ----------- -The following code is simplified skeleton showing how data descriptors could +The following code is a simplified skeleton showing how data descriptors could be used to implement an `object relational mapping <https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping>`_. @@ -991,17 +1009,17 @@ here is a pure Python equivalent: if obj is None: return self if self.fget is None: - raise AttributeError(f'unreadable attribute {self._name}') + raise AttributeError(f"property '{self._name}' has no getter") return self.fget(obj) def __set__(self, obj, value): if self.fset is None: - raise AttributeError(f"can't set attribute {self._name}") + raise AttributeError(f"property '{self._name}' has no setter") self.fset(obj, value) def __delete__(self, obj): if self.fdel is None: - raise AttributeError(f"can't delete attribute {self._name}") + raise AttributeError(f"property '{self._name}' has no deleter") self.fdel(obj) def getter(self, fget): @@ -1351,6 +1369,8 @@ Using the non-data descriptor protocol, a pure Python version of if cls is None: cls = type(obj) if hasattr(type(self.f), '__get__'): + # This code path was added in Python 3.9 + # and was deprecated in Python 3.11. return self.f.__get__(cls, cls) return MethodType(self.f, cls) @@ -1388,7 +1408,7 @@ Using the non-data descriptor protocol, a pure Python version of The code path for ``hasattr(type(self.f), '__get__')`` was added in Python 3.9 and makes it possible for :func:`classmethod` to support chained decorators. For example, a classmethod and property could be -chained together: +chained together. In Python 3.11, this functionality was deprecated. .. testcode:: @@ -1456,7 +1476,7 @@ attributes stored in ``__slots__``: >>> mark.dept = 'Space Pirate' Traceback (most recent call last): ... - AttributeError: can't set attribute + AttributeError: property 'dept' of 'Immutable' object has no setter >>> mark.location = 'Mars' Traceback (most recent call last): ... @@ -1515,6 +1535,8 @@ by member descriptors: def __get__(self, obj, objtype=None): 'Emulate member_get() in Objects/descrobject.c' # Also see PyMember_GetOne() in Python/structmember.c + if obj is None: + return self value = obj._slotvalues[self.offset] if value is null: raise AttributeError(self.name) @@ -1543,13 +1565,13 @@ variables: class Type(type): 'Simulate how the type metaclass adds member objects for slots' - def __new__(mcls, clsname, bases, mapping): - 'Emuluate type_new() in Objects/typeobject.c' + def __new__(mcls, clsname, bases, mapping, **kwargs): + 'Emulate type_new() in Objects/typeobject.c' # type_new() calls PyTypeReady() which calls add_methods() slot_names = mapping.get('slot_names', []) for offset, name in enumerate(slot_names): mapping[name] = Member(name, clsname, offset) - return type.__new__(mcls, clsname, bases, mapping) + return type.__new__(mcls, clsname, bases, mapping, **kwargs) The :meth:`object.__new__` method takes care of creating instances that have slots instead of an instance dictionary. Here is a rough simulation in pure @@ -1560,7 +1582,7 @@ Python: class Object: 'Simulate how object.__new__() allocates memory for __slots__' - def __new__(cls, *args): + def __new__(cls, *args, **kwargs): 'Emulate object_new() in Objects/typeobject.c' inst = super().__new__(cls) if hasattr(cls, 'slot_names'): @@ -1573,7 +1595,7 @@ Python: cls = type(self) if hasattr(cls, 'slot_names') and name not in cls.slot_names: raise AttributeError( - f'{type(self).__name__!r} object has no attribute {name!r}' + f'{cls.__name__!r} object has no attribute {name!r}' ) super().__setattr__(name, value) @@ -1582,7 +1604,7 @@ Python: cls = type(self) if hasattr(cls, 'slot_names') and name not in cls.slot_names: raise AttributeError( - f'{type(self).__name__!r} object has no attribute {name!r}' + f'{cls.__name__!r} object has no attribute {name!r}' ) super().__delattr__(name) diff --git a/Doc/howto/enum.rst b/Doc/howto/enum.rst index b0b17b1669f..4525acb0450 100644 --- a/Doc/howto/enum.rst +++ b/Doc/howto/enum.rst @@ -2,15 +2,10 @@ Enum HOWTO ========== -:Author: Ethan Furman <ethan at stoneleaf dot us> - .. _enum-basic-tutorial: .. currentmodule:: enum -Basic Enum Tutorial -------------------- - An :class:`Enum` is a set of symbolic names bound to unique values. They are similar to global variables, but they offer a more useful :func:`repr()`, grouping, type-safety, and a few other features. @@ -28,6 +23,14 @@ selection of values. For example, the days of the week:: ... SATURDAY = 6 ... SUNDAY = 7 +Or perhaps the RGB primary colors:: + + >>> from enum import Enum + >>> class Color(Enum): + ... RED = 1 + ... GREEN = 2 + ... BLUE = 3 + As you can see, creating an :class:`Enum` is as simple as writing a class that inherits from :class:`Enum` itself. @@ -41,13 +44,14 @@ important, but either way that value can be used to get the corresponding member:: >>> Weekday(3) - Weekday.WEDNESDAY + <Weekday.WEDNESDAY: 3> -As you can see, the ``repr()`` of a member shows the enum name and the -member name. The ``str()`` on a member shows only its name:: +As you can see, the ``repr()`` of a member shows the enum name, the member name, +and the value. The ``str()`` of a member shows only the enum name and member +name:: >>> print(Weekday.THURSDAY) - THURSDAY + Weekday.THURSDAY The *type* of an enumeration member is the enum it belongs to:: @@ -97,8 +101,8 @@ The complete :class:`Weekday` enum now looks like this:: Now we can find out what today is! Observe:: >>> from datetime import date - >>> Weekday.from_date(date.today()) - Weekday.TUESDAY + >>> Weekday.from_date(date.today()) # doctest: +SKIP + <Weekday.TUESDAY: 2> Of course, if you're reading this on some other day, you'll see that day instead. @@ -124,21 +128,21 @@ Just like the original :class:`Weekday` enum above, we can have a single selecti >>> first_week_day = Weekday.MONDAY >>> first_week_day - Weekday.MONDAY + <Weekday.MONDAY: 1> But :class:`Flag` also allows us to combine several members into a single variable:: >>> weekend = Weekday.SATURDAY | Weekday.SUNDAY >>> weekend - Weekday.SATURDAY|Weekday.SUNDAY + <Weekday.SATURDAY|SUNDAY: 96> You can even iterate over a :class:`Flag` variable:: >>> for day in weekend: ... print(day) - SATURDAY - SUNDAY + Weekday.SATURDAY + Weekday.SUNDAY Okay, let's get some chores set up:: @@ -154,6 +158,7 @@ And a function to display the chores for a given day:: ... for chore, days in chores.items(): ... if day in days: ... print(chore) + ... >>> show_chores(chores_for_ethan, Weekday.SATURDAY) answer SO questions @@ -169,10 +174,12 @@ yourself some work and use :func:`auto()` for the values:: ... FRIDAY = auto() ... SATURDAY = auto() ... SUNDAY = auto() + ... WEEKEND = SATURDAY | SUNDAY .. _enum-advanced-tutorial: + Programmatic access to enumeration members and their attributes --------------------------------------------------------------- @@ -181,16 +188,16 @@ situations where ``Color.RED`` won't do because the exact color is not known at program-writing time). ``Enum`` allows such access:: >>> Color(1) - Color.RED + <Color.RED: 1> >>> Color(3) - Color.BLUE + <Color.BLUE: 3> If you want to access enum members by *name*, use item access:: >>> Color['RED'] - Color.RED + <Color.RED: 1> >>> Color['GREEN'] - Color.GREEN + <Color.GREEN: 2> If you have an enum member and need its :attr:`name` or :attr:`value`:: @@ -212,7 +219,7 @@ Having two enum members with the same name is invalid:: ... Traceback (most recent call last): ... - TypeError: 'SQUARE' already defined as: 2 + TypeError: 'SQUARE' already defined as 2 However, an enum member can have other names associated with it. Given two entries ``A`` and ``B`` with the same value (and ``A`` defined first), ``B`` @@ -227,11 +234,11 @@ By-name lookup of ``B`` will also return the member ``A``:: ... ALIAS_FOR_SQUARE = 2 ... >>> Shape.SQUARE - Shape.SQUARE + <Shape.SQUARE: 2> >>> Shape.ALIAS_FOR_SQUARE - Shape.SQUARE + <Shape.SQUARE: 2> >>> Shape(2) - Shape.SQUARE + <Shape.SQUARE: 2> .. note:: @@ -299,7 +306,11 @@ Iteration Iterating over the members of an enum does not provide the aliases:: >>> list(Shape) - [Shape.SQUARE, Shape.DIAMOND, Shape.CIRCLE] + [<Shape.SQUARE: 2>, <Shape.DIAMOND: 1>, <Shape.CIRCLE: 3>] + >>> list(Weekday) + [<Weekday.MONDAY: 1>, <Weekday.TUESDAY: 2>, <Weekday.WEDNESDAY: 4>, <Weekday.THURSDAY: 8>, <Weekday.FRIDAY: 16>, <Weekday.SATURDAY: 32>, <Weekday.SUNDAY: 64>] + +Note that the aliases ``Shape.ALIAS_FOR_SQUARE`` and ``Weekday.WEEKEND`` aren't shown. The special attribute ``__members__`` is a read-only ordered mapping of names to members. It includes all names defined in the enumeration, including the @@ -308,10 +319,10 @@ aliases:: >>> for name, member in Shape.__members__.items(): ... name, member ... - ('SQUARE', Shape.SQUARE) - ('DIAMOND', Shape.DIAMOND) - ('CIRCLE', Shape.CIRCLE) - ('ALIAS_FOR_SQUARE', Shape.SQUARE) + ('SQUARE', <Shape.SQUARE: 2>) + ('DIAMOND', <Shape.DIAMOND: 1>) + ('CIRCLE', <Shape.CIRCLE: 3>) + ('ALIAS_FOR_SQUARE', <Shape.SQUARE: 2>) The ``__members__`` attribute can be used for detailed programmatic access to the enumeration members. For example, finding all the aliases:: @@ -319,6 +330,11 @@ the enumeration members. For example, finding all the aliases:: >>> [name for name, member in Shape.__members__.items() if member.name != name] ['ALIAS_FOR_SQUARE'] +.. note:: + + Aliases for flags include values with multiple flags set, such as ``3``, + and no flags set, i.e. ``0``. + Comparisons ----------- @@ -360,8 +376,8 @@ below):: Allowed members and attributes of enumerations ---------------------------------------------- -Most of the examples above use integers for enumeration values. Using integers is -short and handy (and provided by default by the `Functional API`_), but not +Most of the examples above use integers for enumeration values. Using integers +is short and handy (and provided by default by the `Functional API`_), but not strictly enforced. In the vast majority of use-cases, one doesn't care what the actual value of an enumeration is. But if the value *is* important, enumerations can have arbitrary values. @@ -389,7 +405,7 @@ usual. If we have this enumeration:: Then:: >>> Mood.favorite_mood() - Mood.HAPPY + <Mood.HAPPY: 3> >>> Mood.HAPPY.describe() ('HAPPY', 3) >>> str(Mood.FUNKY) @@ -425,7 +441,7 @@ any members. So this is forbidden:: ... Traceback (most recent call last): ... - TypeError: MoreColor: cannot extend enumeration 'Color' + TypeError: <enum 'MoreColor'> cannot extend <enum 'Color'> But this is allowed:: @@ -444,6 +460,31 @@ sense to allow sharing some common behavior between a group of enumerations. (See `OrderedEnum`_ for an example.) +.. _enum-dataclass-support: + +Dataclass support +----------------- + +When inheriting from a :class:`~dataclasses.dataclass`, +the :meth:`~Enum.__repr__` omits the inherited class' name. For example:: + + >>> @dataclass + ... class CreatureDataMixin: + ... size: str + ... legs: int + ... tail: bool = field(repr=False, default=True) + ... + >>> class Creature(CreatureDataMixin, Enum): + ... BEETLE = 'small', 6 + ... DOG = 'medium', 4 + ... + >>> Creature.DOG + <Creature.DOG: size='medium', legs=4> + +Use the :func:`!dataclass` argument ``repr=False`` +to use the standard :func:`repr`. + + Pickling -------- @@ -476,11 +517,9 @@ The :class:`Enum` class is callable, providing the following functional API:: >>> Animal <enum 'Animal'> >>> Animal.ANT - Animal.ANT - >>> Animal.ANT.value - 1 + <Animal.ANT: 1> >>> list(Animal) - [Animal.ANT, Animal.BEE, Animal.CAT, Animal.DOG] + [<Animal.ANT: 1>, <Animal.BEE: 2>, <Animal.CAT: 3>, <Animal.DOG: 4>] The semantics of this API resemble :class:`~collections.namedtuple`. The first argument of the call to :class:`Enum` is the name of the enumeration. @@ -625,16 +664,7 @@ StrEnum The second variation of :class:`Enum` that is provided is also a subclass of :class:`str`. Members of a :class:`StrEnum` can be compared to strings; by extension, string enumerations of different types can also be compared -to each other. :class:`StrEnum` exists to help avoid the problem of getting -an incorrect member:: - - >>> from enum import StrEnum - >>> class Directions(StrEnum): - ... NORTH = 'north', # notice the trailing comma - ... SOUTH = 'south' - -Before :class:`StrEnum`, ``Directions.NORTH`` would have been the :class:`tuple` -``('north',)``. +to each other. .. versionadded:: 3.11 @@ -645,9 +675,8 @@ IntFlag The next variation of :class:`Enum` provided, :class:`IntFlag`, is also based on :class:`int`. The difference being :class:`IntFlag` members can be combined using the bitwise operators (&, \|, ^, ~) and the result is still an -:class:`IntFlag` member, if possible. However, as the name implies, :class:`IntFlag` -members also subclass :class:`int` and can be used wherever an :class:`int` is -used. +:class:`IntFlag` member, if possible. Like :class:`IntEnum`, :class:`IntFlag` +members are also integers and can be used wherever an :class:`int` is used. .. note:: @@ -670,7 +699,7 @@ Sample :class:`IntFlag` class:: ... X = 1 ... >>> Perm.R | Perm.W - Perm.R|Perm.W + <Perm.R|W: 6> >>> Perm.R + Perm.W 6 >>> RW = Perm.R | Perm.W @@ -684,12 +713,13 @@ It is also possible to name the combinations:: ... W = 2 ... X = 1 ... RWX = 7 + ... >>> Perm.RWX - Perm.RWX + <Perm.RWX: 7> >>> ~Perm.RWX - Perm(0) + <Perm: 0> >>> Perm(7) - Perm.RWX + <Perm.RWX: 7> .. note:: @@ -702,7 +732,7 @@ Another important difference between :class:`IntFlag` and :class:`Enum` is that if no flags are set (the value is 0), its boolean evaluation is :data:`False`:: >>> Perm.R & Perm.X - Perm(0) + <Perm: 0> >>> bool(Perm.R & Perm.X) False @@ -710,7 +740,7 @@ Because :class:`IntFlag` members are also subclasses of :class:`int` they can be combined with them (but may lose :class:`IntFlag` membership:: >>> Perm.X | 4 - Perm.R|Perm.X + <Perm.R|X: 5> >>> Perm.X | 8 9 @@ -726,7 +756,7 @@ be combined with them (but may lose :class:`IntFlag` membership:: :class:`IntFlag` members can also be iterated over:: >>> list(RW) - [Perm.R, Perm.W] + [<Perm.R: 4>, <Perm.W: 2>] .. versionadded:: 3.11 @@ -753,12 +783,12 @@ flags being set, the boolean evaluation is :data:`False`:: ... GREEN = auto() ... >>> Color.RED & Color.GREEN - Color(0) + <Color: 0> >>> bool(Color.RED & Color.GREEN) False Individual flags should have values that are powers of two (1, 2, 4, 8, ...), -while combinations of flags won't:: +while combinations of flags will not:: >>> class Color(Flag): ... RED = auto() @@ -767,7 +797,7 @@ while combinations of flags won't:: ... WHITE = RED | BLUE | GREEN ... >>> Color.WHITE - Color.WHITE + <Color.WHITE: 7> Giving a name to the "no flags set" condition does not change its boolean value:: @@ -779,7 +809,7 @@ value:: ... GREEN = auto() ... >>> Color.BLACK - Color.BLACK + <Color.BLACK: 0> >>> bool(Color.BLACK) False @@ -787,7 +817,7 @@ value:: >>> purple = Color.RED | Color.BLUE >>> list(purple) - [Color.RED, Color.BLUE] + [<Color.RED: 1>, <Color.BLUE: 2>] .. versionadded:: 3.11 @@ -812,29 +842,35 @@ simple to implement independently:: pass This demonstrates how similar derived enumerations can be defined; for example -a :class:`StrEnum` that mixes in :class:`str` instead of :class:`int`. +a :class:`FloatEnum` that mixes in :class:`float` instead of :class:`int`. Some rules: 1. When subclassing :class:`Enum`, mix-in types must appear before :class:`Enum` itself in the sequence of bases, as in the :class:`IntEnum` example above. -2. While :class:`Enum` can have members of any type, once you mix in an +2. Mix-in types must be subclassable. For example, :class:`bool` and + :class:`range` are not subclassable and will throw an error during Enum + creation if used as the mix-in type. +3. While :class:`Enum` can have members of any type, once you mix in an additional type, all the members must have values of that type, e.g. :class:`int` above. This restriction does not apply to mix-ins which only add methods and don't specify another type. -3. When another data type is mixed in, the :attr:`value` attribute is *not the +4. When another data type is mixed in, the :attr:`value` attribute is *not the same* as the enum member itself, although it is equivalent and will compare equal. -4. %-style formatting: `%s` and `%r` call the :class:`Enum` class's +5. %-style formatting: ``%s`` and ``%r`` call the :class:`Enum` class's :meth:`__str__` and :meth:`__repr__` respectively; other codes (such as - `%i` or `%h` for IntEnum) treat the enum member as its mixed-in type. -5. :ref:`Formatted string literals <f-strings>`, :meth:`str.format`, - and :func:`format` will use the mixed-in type's :meth:`__format__` - unless :meth:`__str__` or :meth:`__format__` is overridden in the subclass, - in which case the overridden methods or :class:`Enum` methods will be used. - Use the !s and !r format codes to force usage of the :class:`Enum` class's - :meth:`__str__` and :meth:`__repr__` methods. + ``%i`` or ``%h`` for IntEnum) treat the enum member as its mixed-in type. +6. :ref:`Formatted string literals <f-strings>`, :meth:`str.format`, + and :func:`format` will use the enum's :meth:`__str__` method. + +.. note:: + + Because :class:`IntEnum`, :class:`IntFlag`, and :class:`StrEnum` are + designed to be drop-in replacements for existing constants, their + :meth:`__str__` method has been reset to their data types + :meth:`__str__` method. When to use :meth:`__new__` vs. :meth:`__init__` ------------------------------------------------ @@ -863,10 +899,10 @@ want one of them to be the value:: ... >>> print(Coordinate['PY']) - PY + Coordinate.PY >>> print(Coordinate(3)) - VY + Coordinate.VY Finer Points @@ -924,8 +960,8 @@ and raise an error if the two do not match:: Traceback (most recent call last): ... TypeError: member order does not match _order_: - ['RED', 'BLUE', 'GREEN'] - ['RED', 'GREEN', 'BLUE'] + ['RED', 'BLUE', 'GREEN'] + ['RED', 'GREEN', 'BLUE'] .. note:: @@ -946,35 +982,25 @@ but remain normal attributes. """""""""""""""""""" Enum members are instances of their enum class, and are normally accessed as -``EnumClass.member``. In Python versions ``3.5`` to ``3.9`` you could access -members from other members -- this practice was discouraged, and in ``3.12`` -:class:`Enum` will return to not allowing it, while in ``3.10`` and ``3.11`` -it will raise a :exc:`DeprecationWarning`:: - - >>> class FieldTypes(Enum): - ... name = 0 - ... value = 1 - ... size = 2 - ... - >>> FieldTypes.value.size # doctest: +SKIP - DeprecationWarning: accessing one member from another is not supported, - and will be disabled in 3.12 - <FieldTypes.size: 2> +``EnumClass.member``. In Python versions starting with ``3.5`` you could access +members from other members -- this practice is discouraged, is deprecated +in ``3.12``, and will be removed in ``3.14``. .. versionchanged:: 3.5 +.. versionchanged:: 3.12 Creating members that are mixed with other data types """"""""""""""""""""""""""""""""""""""""""""""""""""" When subclassing other data types, such as :class:`int` or :class:`str`, with -an :class:`Enum`, all values after the `=` are passed to that data type's +an :class:`Enum`, all values after the ``=`` are passed to that data type's constructor. For example:: - >>> class MyEnum(IntEnum): - ... example = '11', 16 # '11' will be interpreted as a hexadecimal - ... # number - >>> MyEnum.example.value + >>> class MyEnum(IntEnum): # help(int) -> int(x, base=10) -> integer + ... example = '11', 16 # so x='11' and base=16 + ... + >>> MyEnum.example.value # and hex(11) is... 17 @@ -1000,9 +1026,9 @@ If you give your enum subclass extra methods, like the `Planet`_ class below, those methods will show up in a :func:`dir` of the member, but not of the class:: - >>> dir(Planet) + >>> dir(Planet) # doctest: +SKIP ['EARTH', 'JUPITER', 'MARS', 'MERCURY', 'NEPTUNE', 'SATURN', 'URANUS', 'VENUS', '__class__', '__doc__', '__members__', '__module__'] - >>> dir(Planet.EARTH) + >>> dir(Planet.EARTH) # doctest: +SKIP ['__class__', '__doc__', '__module__', 'mass', 'name', 'radius', 'surface_gravity', 'value'] @@ -1021,19 +1047,10 @@ are comprised of a single bit:: ... CYAN = GREEN | BLUE ... >>> Color(3) # named combination - Color.YELLOW + <Color.YELLOW: 3> >>> Color(7) # not named combination - Color.RED|Color.GREEN|Color.BLUE + <Color.RED|GREEN|BLUE: 7> -``StrEnum`` and :meth:`str.__str__` -""""""""""""""""""""""""""""""""""" - -An important difference between :class:`StrEnum` and other Enums is the -:meth:`__str__` method; because :class:`StrEnum` members are strings, some -parts of Python will read the string data directly, while others will call -:meth:`str()`. To make those two operations have the same result, -:meth:`StrEnum.__str__` will be the same as :meth:`str.__str__` so that -``str(StrEnum.member) == StrEnum.member`` is true. ``Flag`` and ``IntFlag`` minutia """""""""""""""""""""""""""""""" @@ -1056,16 +1073,16 @@ the following are true: - only canonical flags are returned during iteration:: >>> list(Color.WHITE) - [Color.RED, Color.GREEN, Color.BLUE] + [<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 4>] - negating a flag or flag set returns a new flag/flag set with the corresponding positive integer value:: >>> Color.BLUE - Color.BLUE + <Color.BLUE: 4> >>> ~Color.BLUE - Color.RED|Color.GREEN + <Color.RED|GREEN: 3> - names of pseudo-flags are constructed from their members' names:: @@ -1075,25 +1092,29 @@ the following are true: - multi-bit flags, aka aliases, can be returned from operations:: >>> Color.RED | Color.BLUE - Color.PURPLE + <Color.PURPLE: 5> >>> Color(7) # or Color(-1) - Color.WHITE + <Color.WHITE: 7> >>> Color(0) - Color.BLACK + <Color.BLACK: 0> -- membership / containment checking has changed slightly -- zero-valued flags - are never considered to be contained:: +- membership / containment checking: zero-valued flags are always considered + to be contained:: >>> Color.BLACK in Color.WHITE - False + True - otherwise, if all bits of one flag are in the other flag, True is returned:: + otherwise, only if all bits of one flag are in the other flag will True + be returned:: >>> Color.PURPLE in Color.WHITE True + >>> Color.GREEN in Color.PURPLE + False + There is a new boundary mechanism that controls how out-of-range / invalid bits are handled: ``STRICT``, ``CONFORM``, ``EJECT``, and ``KEEP``: @@ -1112,8 +1133,8 @@ example of when ``KEEP`` is needed). .. _enum-class-differences: -How are Enums different? ------------------------- +How are Enums and Flags different? +---------------------------------- Enums have a custom metaclass that affects many aspects of both derived :class:`Enum` classes and their instances (members). @@ -1125,11 +1146,18 @@ Enum Classes The :class:`EnumType` metaclass is responsible for providing the :meth:`__contains__`, :meth:`__dir__`, :meth:`__iter__` and other methods that allow one to do things with an :class:`Enum` class that fail on a typical -class, such as `list(Color)` or `some_enum_var in Color`. :class:`EnumType` is +class, such as ``list(Color)`` or ``some_enum_var in Color``. :class:`EnumType` is responsible for ensuring that various other methods on the final :class:`Enum` class are correct (such as :meth:`__new__`, :meth:`__getnewargs__`, :meth:`__str__` and :meth:`__repr__`). +Flag Classes +^^^^^^^^^^^^ + +Flags have an expanded view of aliasing: to be canonical, the value of a flag +needs to be a power-of-two value, and not a duplicate name. So, in addition to the +:class:`Enum` definition of alias, a flag with no value (a.k.a. ``0``) or with more than one +power-of-two value (e.g. ``3``) is considered an alias. Enum Members (aka instances) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1139,9 +1167,35 @@ The most interesting thing about enum members is that they are singletons. and then puts a custom :meth:`__new__` in place to ensure that no new ones are ever instantiated by returning only the existing member instances. +Flag Members +^^^^^^^^^^^^ + +Flag members can be iterated over just like the :class:`Flag` class, and only the +canonical members will be returned. For example:: + + >>> list(Color) + [<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 4>] + +(Note that ``BLACK``, ``PURPLE``, and ``WHITE`` do not show up.) + +Inverting a flag member returns the corresponding positive value, +rather than a negative value --- for example:: + + >>> ~Color.RED + <Color.GREEN|BLUE: 6> + +Flag members have a length corresponding to the number of power-of-two values +they contain. For example:: + + >>> len(Color.PURPLE) + 2 + .. _enum-cookbook: +Enum Cookbook +------------- + While :class:`Enum`, :class:`IntEnum`, :class:`StrEnum`, :class:`Flag`, and :class:`IntFlag` are expected to cover the majority of use-cases, they cannot @@ -1177,7 +1231,7 @@ Using :class:`auto` would look like:: ... GREEN = auto() ... >>> Color.GREEN - <Color.GREEN> + <Color.GREEN: 3> Using :class:`object` @@ -1190,10 +1244,24 @@ Using :class:`object` would look like:: ... GREEN = object() ... BLUE = object() ... + >>> Color.GREEN # doctest: +SKIP + <Color.GREEN: <object object at 0x...>> + +This is also a good example of why you might want to write your own +:meth:`__repr__`:: + + >>> class Color(Enum): + ... RED = object() + ... GREEN = object() + ... BLUE = object() + ... def __repr__(self): + ... return "<%s.%s>" % (self.__class__.__name__, self._name_) + ... >>> Color.GREEN <Color.GREEN> + Using a descriptive string """""""""""""""""""""""""" @@ -1205,9 +1273,7 @@ Using a string as the value would look like:: ... BLUE = 'too fast!' ... >>> Color.GREEN - <Color.GREEN> - >>> Color.GREEN.value - 'go' + <Color.GREEN: 'go'> Using a custom :meth:`__new__` @@ -1228,9 +1294,7 @@ Using an auto-numbering :meth:`__new__` would look like:: ... BLUE = () ... >>> Color.GREEN - <Color.GREEN> - >>> Color.GREEN.value - 2 + <Color.GREEN: 2> To make a more general purpose ``AutoNumber``, add ``*args`` to the signature:: @@ -1253,7 +1317,7 @@ to handle any extra arguments:: ... BLEACHED_CORAL = () # New color, no Pantone code yet! ... >>> Swatch.SEA_GREEN - <Swatch.SEA_GREEN> + <Swatch.SEA_GREEN: 2> >>> Swatch.SEA_GREEN.pantone '1246' >>> Swatch.BLEACHED_CORAL.pantone @@ -1305,7 +1369,7 @@ enumerations):: DuplicateFreeEnum ^^^^^^^^^^^^^^^^^ -Raises an error if a duplicate member name is found instead of creating an +Raises an error if a duplicate member value is found instead of creating an alias:: >>> class DuplicateFreeEnum(Enum): @@ -1380,30 +1444,9 @@ An example to show the :attr:`_ignore_` attribute in use:: ... Period['day_%d' % i] = i ... >>> list(Period)[:2] - [Period.day_0, Period.day_1] + [<Period.day_0: datetime.timedelta(0)>, <Period.day_1: datetime.timedelta(days=1)>] >>> list(Period)[-2:] - [Period.day_365, Period.day_366] - - -Conforming input to Flag -^^^^^^^^^^^^^^^^^^^^^^^^ - -To create a :class:`Flag` enum that is more resilient to out-of-bounds results -from mathematical operations, you can use the :attr:`FlagBoundary.CONFORM` -setting:: - - >>> from enum import Flag, CONFORM, auto - >>> class Weekday(Flag, boundary=CONFORM): - ... MONDAY = auto() - ... TUESDAY = auto() - ... WEDNESDAY = auto() - ... THURSDAY = auto() - ... FRIDAY = auto() - ... SATURDAY = auto() - ... SUNDAY = auto() - >>> today = Weekday.TUESDAY - >>> Weekday(today + 22) # what day is three weeks from tomorrow? - >>> Weekday.WEDNESDAY + [<Period.day_365: datetime.timedelta(days=365)>, <Period.day_366: datetime.timedelta(days=366)>] .. _enumtype-examples: @@ -1414,4 +1457,3 @@ Subclassing EnumType While most enum needs can be met by customizing :class:`Enum` subclasses, either with class decorators or custom functions, :class:`EnumType` can be subclassed to provide a different Enum experience. - diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst index c7f8bc8f17f..38a651b0f96 100644 --- a/Doc/howto/functional.rst +++ b/Doc/howto/functional.rst @@ -315,9 +315,15 @@ line of a file like this:: Sets can take their contents from an iterable and let you iterate over the set's elements:: - S = {2, 3, 5, 7, 11, 13} - for i in S: - print(i) + >>> S = {2, 3, 5, 7, 11, 13} + >>> for i in S: + ... print(i) + 2 + 3 + 5 + 7 + 11 + 13 @@ -335,18 +341,18 @@ List comprehensions and generator expressions (short form: "listcomps" and functional programming language Haskell (https://www.haskell.org/). You can strip all the whitespace from a stream of strings with the following code:: - line_list = [' line 1\n', 'line 2 \n', ...] + >>> line_list = [' line 1\n', 'line 2 \n', ' \n', ''] - # Generator expression -- returns iterator - stripped_iter = (line.strip() for line in line_list) + >>> # Generator expression -- returns iterator + >>> stripped_iter = (line.strip() for line in line_list) - # List comprehension -- returns list - stripped_list = [line.strip() for line in line_list] + >>> # List comprehension -- returns list + >>> stripped_list = [line.strip() for line in line_list] You can select only certain elements by adding an ``"if"`` condition:: - stripped_list = [line.strip() for line in line_list - if line != ""] + >>> stripped_list = [line.strip() for line in line_list + ... if line != ""] With a list comprehension, you get back a Python list; ``stripped_list`` is a list containing the resulting lines, not an iterator. Generator expressions @@ -363,7 +369,8 @@ have the form:: if condition1 for expr2 in sequence2 if condition2 - for expr3 in sequence3 ... + for expr3 in sequence3 + ... if condition3 for exprN in sequenceN if conditionN ) @@ -589,7 +596,7 @@ generator function. In addition to :meth:`~generator.send`, there are two other methods on generators: -* :meth:`throw(type, value=None, traceback=None) <generator.throw>` is used to +* :meth:`throw(value) <generator.throw>` is used to raise an exception inside the generator; the exception is raised by the ``yield`` expression where the generator's execution is paused. @@ -734,7 +741,7 @@ further because you risk skipping a discarded element. The itertools module ==================== -The :mod:`itertools` module contains a number of commonly-used iterators as well +The :mod:`itertools` module contains a number of commonly used iterators as well as functions for combining several iterators. This section will introduce the module's contents by showing small examples. @@ -987,7 +994,7 @@ requesting iterator-2 and its corresponding key. The functools module ==================== -The :mod:`functools` module in Python 2.5 contains some higher-order functions. +The :mod:`functools` module contains some higher-order functions. A **higher-order function** takes one or more functions as input and returns a new function. The most useful tool in this module is the :func:`functools.partial` function. @@ -1208,7 +1215,7 @@ flow inside a program. The book uses Scheme for its examples, but many of the design approaches described in these chapters are applicable to functional-style Python code. -http://www.defmacro.org/ramblings/fp.html: A general introduction to functional +https://www.defmacro.org/ramblings/fp.html: A general introduction to functional programming that uses Java examples and has a lengthy historical introduction. https://en.wikipedia.org/wiki/Functional_programming: General Wikipedia entry @@ -1216,12 +1223,14 @@ describing functional programming. https://en.wikipedia.org/wiki/Coroutine: Entry for coroutines. +https://en.wikipedia.org/wiki/Partial_application: Entry for the concept of partial function application. + https://en.wikipedia.org/wiki/Currying: Entry for the concept of currying. Python-specific --------------- -http://gnosis.cx/TPiP/: The first chapter of David Mertz's book +https://gnosis.cx/TPiP/: The first chapter of David Mertz's book :title-reference:`Text Processing in Python` discusses functional programming for text processing, in the section titled "Utilizing Higher-Order Functions in Text Processing". diff --git a/Doc/howto/index.rst b/Doc/howto/index.rst index eae8f143ee2..f521276a5a8 100644 --- a/Doc/howto/index.rst +++ b/Doc/howto/index.rst @@ -30,5 +30,7 @@ Currently, the HOWTOs are: ipaddress.rst clinic.rst instrumentation.rst + perf_profiling.rst annotations.rst + isolating-extensions.rst diff --git a/Doc/howto/instrumentation.rst b/Doc/howto/instrumentation.rst index 4a59ae82f96..4ce15c69dac 100644 --- a/Doc/howto/instrumentation.rst +++ b/Doc/howto/instrumentation.rst @@ -123,7 +123,7 @@ Sufficiently modern readelf can print the metadata:: Arguments: 8@%rbp 8@%r12 -4@%eax The above metadata contains information for SystemTap describing how it -can patch strategically-placed machine code instructions to enable the +can patch strategically placed machine code instructions to enable the tracing hooks used by a SystemTap script. @@ -410,7 +410,7 @@ needing to directly name the static markers: The following script uses the tapset above to provide a top-like view of all -running CPython code, showing the top 20 most frequently-entered bytecode +running CPython code, showing the top 20 most frequently entered bytecode frames, each second, across the whole system: .. code-block:: none diff --git a/Doc/howto/isolating-extensions.rst b/Doc/howto/isolating-extensions.rst new file mode 100644 index 00000000000..2eddb582da7 --- /dev/null +++ b/Doc/howto/isolating-extensions.rst @@ -0,0 +1,536 @@ +.. highlight:: c + +*************************** +Isolating Extension Modules +*************************** + +.. topic:: Abstract + + Traditionally, state belonging to Python extension modules was kept in C + ``static`` variables, which have process-wide scope. This document + describes problems of such per-process state and shows a safer way: + per-module state. + + The document also describes how to switch to per-module state where + possible. This transition involves allocating space for that state, potentially + switching from static types to heap types, and—perhaps most + importantly—accessing per-module state from code. + + +Who should read this +==================== + +This guide is written for maintainers of :ref:`C-API <c-api-index>` extensions +who would like to make that extension safer to use in applications where +Python itself is used as a library. + + +Background +========== + +An *interpreter* is the context in which Python code runs. It contains +configuration (e.g. the import path) and runtime state (e.g. the set of +imported modules). + +Python supports running multiple interpreters in one process. There are +two cases to think about—users may run interpreters: + +- in sequence, with several :c:func:`Py_InitializeEx`/:c:func:`Py_FinalizeEx` + cycles, and +- in parallel, managing "sub-interpreters" using + :c:func:`Py_NewInterpreter`/:c:func:`Py_EndInterpreter`. + +Both cases (and combinations of them) would be most useful when +embedding Python within a library. Libraries generally shouldn't make +assumptions about the application that uses them, which include +assuming a process-wide "main Python interpreter". + +Historically, Python extension modules don't handle this use case well. +Many extension modules (and even some stdlib modules) use *per-process* +global state, because C ``static`` variables are extremely easy to use. +Thus, data that should be specific to an interpreter ends up being shared +between interpreters. Unless the extension developer is careful, it is very +easy to introduce edge cases that lead to crashes when a module is loaded in +more than one interpreter in the same process. + +Unfortunately, *per-interpreter* state is not easy to achieve. Extension +authors tend to not keep multiple interpreters in mind when developing, +and it is currently cumbersome to test the behavior. + +Enter Per-Module State +---------------------- + +Instead of focusing on per-interpreter state, Python's C API is evolving +to better support the more granular *per-module* state. +This means that C-level data is be attached to a *module object*. +Each interpreter creates its own module object, keeping the data separate. +For testing the isolation, multiple module objects corresponding to a single +extension can even be loaded in a single interpreter. + +Per-module state provides an easy way to think about lifetime and +resource ownership: the extension module will initialize when a +module object is created, and clean up when it's freed. In this regard, +a module is just like any other :c:expr:`PyObject *`; there are no "on +interpreter shutdown" hooks to think—or forget—about. + +Note that there are use cases for different kinds of "globals": +per-process, per-interpreter, per-thread or per-task state. +With per-module state as the default, these are still possible, +but you should treat them as exceptional cases: +if you need them, you should give them additional care and testing. +(Note that this guide does not cover them.) + + +Isolated Module Objects +----------------------- + +The key point to keep in mind when developing an extension module is +that several module objects can be created from a single shared library. +For example: + +.. code-block:: pycon + + >>> import sys + >>> import binascii + >>> old_binascii = binascii + >>> del sys.modules['binascii'] + >>> import binascii # create a new module object + >>> old_binascii == binascii + False + +As a rule of thumb, the two modules should be completely independent. +All objects and state specific to the module should be encapsulated +within the module object, not shared with other module objects, and +cleaned up when the module object is deallocated. +Since this just is a rule of thumb, exceptions are possible +(see `Managing Global State`_), but they will need more +thought and attention to edge cases. + +While some modules could do with less stringent restrictions, isolated +modules make it easier to set clear expectations and guidelines that +work across a variety of use cases. + + +Surprising Edge Cases +--------------------- + +Note that isolated modules do create some surprising edge cases. Most +notably, each module object will typically not share its classes and +exceptions with other similar modules. Continuing from the +`example above <Isolated Module Objects_>`__, +note that ``old_binascii.Error`` and ``binascii.Error`` are +separate objects. In the following code, the exception is *not* caught: + +.. code-block:: pycon + + >>> old_binascii.Error == binascii.Error + False + >>> try: + ... old_binascii.unhexlify(b'qwertyuiop') + ... except binascii.Error: + ... print('boo') + ... + Traceback (most recent call last): + File "<stdin>", line 2, in <module> + binascii.Error: Non-hexadecimal digit found + +This is expected. Notice that pure-Python modules behave the same way: +it is a part of how Python works. + +The goal is to make extension modules safe at the C level, not to make +hacks behave intuitively. Mutating ``sys.modules`` "manually" counts +as a hack. + + +Making Modules Safe with Multiple Interpreters +============================================== + + +Managing Global State +--------------------- + +Sometimes, the state associated with a Python module is not specific to that module, but +to the entire process (or something else "more global" than a module). +For example: + +- The ``readline`` module manages *the* terminal. +- A module running on a circuit board wants to control *the* on-board + LED. + +In these cases, the Python module should provide *access* to the global +state, rather than *own* it. If possible, write the module so that +multiple copies of it can access the state independently (along with +other libraries, whether for Python or other languages). If that is not +possible, consider explicit locking. + +If it is necessary to use process-global state, the simplest way to +avoid issues with multiple interpreters is to explicitly prevent a +module from being loaded more than once per process—see +`Opt-Out: Limiting to One Module Object per Process`_. + + +Managing Per-Module State +------------------------- + +To use per-module state, use +:ref:`multi-phase extension module initialization <multi-phase-initialization>`. +This signals that your module supports multiple interpreters correctly. + +Set ``PyModuleDef.m_size`` to a positive number to request that many +bytes of storage local to the module. Usually, this will be set to the +size of some module-specific ``struct``, which can store all of the +module's C-level state. In particular, it is where you should put +pointers to classes (including exceptions, but excluding static types) +and settings (e.g. ``csv``'s :py:data:`~csv.field_size_limit`) +which the C code needs to function. + +.. note:: + Another option is to store state in the module's ``__dict__``, + but you must avoid crashing when users modify ``__dict__`` from + Python code. This usually means error- and type-checking at the C level, + which is easy to get wrong and hard to test sufficiently. + + However, if module state is not needed in C code, storing it in + ``__dict__`` only is a good idea. + +If the module state includes ``PyObject`` pointers, the module object +must hold references to those objects and implement the module-level hooks +``m_traverse``, ``m_clear`` and ``m_free``. These work like +``tp_traverse``, ``tp_clear`` and ``tp_free`` of a class. Adding them will +require some work and make the code longer; this is the price for +modules which can be unloaded cleanly. + +An example of a module with per-module state is currently available as +`xxlimited <https://github.com/python/cpython/blob/master/Modules/xxlimited.c>`__; +example module initialization shown at the bottom of the file. + + +Opt-Out: Limiting to One Module Object per Process +-------------------------------------------------- + +A non-negative ``PyModuleDef.m_size`` signals that a module supports +multiple interpreters correctly. If this is not yet the case for your +module, you can explicitly make your module loadable only once per +process. For example:: + + static int loaded = 0; + + static int + exec_module(PyObject* module) + { + if (loaded) { + PyErr_SetString(PyExc_ImportError, + "cannot load module more than once per process"); + return -1; + } + loaded = 1; + // ... rest of initialization + } + + +Module State Access from Functions +---------------------------------- + +Accessing the state from module-level functions is straightforward. +Functions get the module object as their first argument; for extracting +the state, you can use ``PyModule_GetState``:: + + static PyObject * + func(PyObject *module, PyObject *args) + { + my_struct *state = (my_struct*)PyModule_GetState(module); + if (state == NULL) { + return NULL; + } + // ... rest of logic + } + +.. note:: + ``PyModule_GetState`` may return ``NULL`` without setting an + exception if there is no module state, i.e. ``PyModuleDef.m_size`` was + zero. In your own module, you're in control of ``m_size``, so this is + easy to prevent. + + +Heap Types +========== + +Traditionally, types defined in C code are *static*; that is, +``static PyTypeObject`` structures defined directly in code and +initialized using ``PyType_Ready()``. + +Such types are necessarily shared across the process. Sharing them +between module objects requires paying attention to any state they own +or access. To limit the possible issues, static types are immutable at +the Python level: for example, you can't set ``str.myattribute = 123``. + +.. impl-detail:: + Sharing truly immutable objects between interpreters is fine, + as long as they don't provide access to mutable objects. + However, in CPython, every Python object has a mutable implementation + detail: the reference count. Changes to the refcount are guarded by the GIL. + Thus, code that shares any Python objects across interpreters implicitly + depends on CPython's current, process-wide GIL. + +Because they are immutable and process-global, static types cannot access +"their" module state. +If any method of such a type requires access to module state, +the type must be converted to a *heap-allocated type*, or *heap type* +for short. These correspond more closely to classes created by Python's +``class`` statement. + +For new modules, using heap types by default is a good rule of thumb. + + +Changing Static Types to Heap Types +----------------------------------- + +Static types can be converted to heap types, but note that +the heap type API was not designed for "lossless" conversion +from static types—that is, creating a type that works exactly like a given +static type. +So, when rewriting the class definition in a new API, +you are likely to unintentionally change a few details (e.g. pickleability +or inherited slots). +Always test the details that are important to you. + +Watch out for the following two points in particular (but note that this is not +a comprehensive list): + +* Unlike static types, heap type objects are mutable by default. + Use the :c:data:`Py_TPFLAGS_IMMUTABLETYPE` flag to prevent mutability. +* Heap types inherit :c:member:`~PyTypeObject.tp_new` by default, + so it may become possible to instantiate them from Python code. + You can prevent this with the :c:data:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag. + + +Defining Heap Types +------------------- + +Heap types can be created by filling a :c:struct:`PyType_Spec` structure, a +description or "blueprint" of a class, and calling +:c:func:`PyType_FromModuleAndSpec` to construct a new class object. + +.. note:: + Other functions, like :c:func:`PyType_FromSpec`, can also create + heap types, but :c:func:`PyType_FromModuleAndSpec` associates the module + with the class, allowing access to the module state from methods. + +The class should generally be stored in *both* the module state (for +safe access from C) and the module's ``__dict__`` (for access from +Python code). + + +Garbage-Collection Protocol +--------------------------- + +Instances of heap types hold a reference to their type. +This ensures that the type isn't destroyed before all its instances are, +but may result in reference cycles that need to be broken by the +garbage collector. + +To avoid memory leaks, instances of heap types must implement the +garbage collection protocol. +That is, heap types should: + +- Have the :c:data:`Py_TPFLAGS_HAVE_GC` flag. +- Define a traverse function using ``Py_tp_traverse``, which + visits the type (e.g. using :c:expr:`Py_VISIT(Py_TYPE(self))`). + +Please refer to the :ref:`the documentation <type-structs>` of +:c:data:`Py_TPFLAGS_HAVE_GC` and :c:member:`~PyTypeObject.tp_traverse` +for additional considerations. + +If your traverse function delegates to the ``tp_traverse`` of its base class +(or another type), ensure that ``Py_TYPE(self)`` is visited only once. +Note that only heap type are expected to visit the type in ``tp_traverse``. + +For example, if your traverse function includes:: + + base->tp_traverse(self, visit, arg) + +...and ``base`` may be a static type, then it should also include:: + + if (base->tp_flags & Py_TPFLAGS_HEAPTYPE) { + // a heap type's tp_traverse already visited Py_TYPE(self) + } else { + Py_VISIT(Py_TYPE(self)); + } + +It is not necessary to handle the type's reference count in ``tp_new`` +and ``tp_clear``. + + +Module State Access from Classes +-------------------------------- + +If you have a type object defined with :c:func:`PyType_FromModuleAndSpec`, +you can call :c:func:`PyType_GetModule` to get the associated module, and then +:c:func:`PyModule_GetState` to get the module's state. + +To save a some tedious error-handling boilerplate code, you can combine +these two steps with :c:func:`PyType_GetModuleState`, resulting in:: + + my_struct *state = (my_struct*)PyType_GetModuleState(type); + if (state === NULL) { + return NULL; + } + + +Module State Access from Regular Methods +---------------------------------------- + +Accessing the module-level state from methods of a class is somewhat more +complicated, but is possible thanks to API introduced in Python 3.9. +To get the state, you need to first get the *defining class*, and then +get the module state from it. + +The largest roadblock is getting *the class a method was defined in*, or +that method's "defining class" for short. The defining class can have a +reference to the module it is part of. + +Do not confuse the defining class with :c:expr:`Py_TYPE(self)`. If the method +is called on a *subclass* of your type, ``Py_TYPE(self)`` will refer to +that subclass, which may be defined in different module than yours. + +.. note:: + The following Python code can illustrate the concept. + ``Base.get_defining_class`` returns ``Base`` even + if ``type(self) == Sub``: + + .. code-block:: python + + class Base: + def get_type_of_self(self): + return type(self) + + def get_defining_class(self): + return __class__ + + class Sub(Base): + pass + +For a method to get its "defining class", it must use the +:data:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS` +:c:type:`calling convention <PyMethodDef>` +and the corresponding :c:type:`PyCMethod` signature:: + + PyObject *PyCMethod( + PyObject *self, // object the method was called on + PyTypeObject *defining_class, // defining class + PyObject *const *args, // C array of arguments + Py_ssize_t nargs, // length of "args" + PyObject *kwnames) // NULL, or dict of keyword arguments + +Once you have the defining class, call :c:func:`PyType_GetModuleState` to get +the state of its associated module. + +For example:: + + static PyObject * + example_method(PyObject *self, + PyTypeObject *defining_class, + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwnames) + { + my_struct *state = (my_struct*)PyType_GetModuleState(defining_class); + if (state === NULL) { + return NULL; + } + ... // rest of logic + } + + PyDoc_STRVAR(example_method_doc, "..."); + + static PyMethodDef my_methods[] = { + {"example_method", + (PyCFunction)(void(*)(void))example_method, + METH_METHOD|METH_FASTCALL|METH_KEYWORDS, + example_method_doc} + {NULL}, + } + + +Module State Access from Slot Methods, Getters and Setters +---------------------------------------------------------- + +.. note:: + + This is new in Python 3.11. + + .. After adding to limited API: + + If you use the :ref:`limited API <stable>, + you must update ``Py_LIMITED_API`` to ``0x030b0000``, losing ABI + compatibility with earlier versions. + +Slot methods—the fast C equivalents for special methods, such as +:c:member:`~PyNumberMethods.nb_add` for :py:attr:`~object.__add__` or +:c:member:`~PyType.tp_new` for initialization—have a very simple API that +doesn't allow passing in the defining class, unlike with :c:type:`PyCMethod`. +The same goes for getters and setters defined with +:c:type:`PyGetSetDef`. + +To access the module state in these cases, use the +:c:func:`PyType_GetModuleByDef` function, and pass in the module definition. +Once you have the module, call :c:func:`PyModule_GetState` +to get the state:: + + PyObject *module = PyType_GetModuleByDef(Py_TYPE(self), &module_def); + my_struct *state = (my_struct*)PyModule_GetState(module); + if (state === NULL) { + return NULL; + } + +``PyType_GetModuleByDef`` works by searching the +:term:`method resolution order` (i.e. all superclasses) for the first +superclass that has a corresponding module. + +.. note:: + + In very exotic cases (inheritance chains spanning multiple modules + created from the same definition), ``PyType_GetModuleByDef`` might not + return the module of the true defining class. However, it will always + return a module with the same definition, ensuring a compatible + C memory layout. + + +Lifetime of the Module State +---------------------------- + +When a module object is garbage-collected, its module state is freed. +For each pointer to (a part of) the module state, you must hold a reference +to the module object. + +Usually this is not an issue, because types created with +:c:func:`PyType_FromModuleAndSpec`, and their instances, hold a reference +to the module. +However, you must be careful in reference counting when you reference +module state from other places, such as callbacks for external +libraries. + + +Open Issues +=========== + +Several issues around per-module state and heap types are still open. + +Discussions about improving the situation are best held on the `capi-sig +mailing list <https://mail.python.org/mailman3/lists/capi-sig.python.org/>`__. + + +Per-Class Scope +--------------- + +It is currently (as of Python 3.11) not possible to attach state to individual +*types* without relying on CPython implementation details (which may change +in the future—perhaps, ironically, to allow a proper solution for +per-class scope). + + +Lossless Conversion to Heap Types +--------------------------------- + +The heap type API was not designed for "lossless" conversion from static types; +that is, creating a type that works exactly like a given static type. diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index 5a8d92ad512..26cf40274fd 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -7,7 +7,8 @@ Logging Cookbook :Author: Vinay Sajip <vinay_sajip at red-dove dot com> This page contains a number of recipes related to logging, which have been found -useful in the past. +useful in the past. For links to tutorial and reference information, please see +:ref:`cookbook-ref-links`. .. currentmodule:: logging @@ -218,7 +219,7 @@ messages should not. Here's how you can achieve this:: logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', datefmt='%m-%d %H:%M', - filename='/temp/myapp.log', + filename='/tmp/myapp.log', filemode='w') # define a Handler which writes INFO messages or higher to the sys.stderr console = logging.StreamHandler() @@ -269,6 +270,216 @@ are sent to both destinations. This example uses console and file handlers, but you can use any number and combination of handlers you choose. +Note that the above choice of log filename ``/tmp/myapp.log`` implies use of a +standard location for temporary files on POSIX systems. On Windows, you may need to +choose a different directory name for the log - just ensure that the directory exists +and that you have the permissions to create and update files in it. + + +.. _custom-level-handling: + +Custom handling of levels +------------------------- + +Sometimes, you might want to do something slightly different from the standard +handling of levels in handlers, where all levels above a threshold get +processed by a handler. To do this, you need to use filters. Let's look at a +scenario where you want to arrange things as follows: + +* Send messages of severity ``INFO`` and ``WARNING`` to ``sys.stdout`` +* Send messages of severity ``ERROR`` and above to ``sys.stderr`` +* Send messages of severity ``DEBUG`` and above to file ``app.log`` + +Suppose you configure logging with the following JSON: + +.. code-block:: json + + { + "version": 1, + "disable_existing_loggers": false, + "formatters": { + "simple": { + "format": "%(levelname)-8s - %(message)s" + } + }, + "handlers": { + "stdout": { + "class": "logging.StreamHandler", + "level": "INFO", + "formatter": "simple", + "stream": "ext://sys.stdout", + }, + "stderr": { + "class": "logging.StreamHandler", + "level": "ERROR", + "formatter": "simple", + "stream": "ext://sys.stderr" + }, + "file": { + "class": "logging.FileHandler", + "formatter": "simple", + "filename": "app.log", + "mode": "w" + } + }, + "root": { + "level": "DEBUG", + "handlers": [ + "stderr", + "stdout", + "file" + ] + } + } + +This configuration does *almost* what we want, except that ``sys.stdout`` would +show messages of severity ``ERROR`` and above as well as ``INFO`` and +``WARNING`` messages. To prevent this, we can set up a filter which excludes +those messages and add it to the relevant handler. This can be configured by +adding a ``filters`` section parallel to ``formatters`` and ``handlers``: + +.. code-block:: json + + "filters": { + "warnings_and_below": { + "()" : "__main__.filter_maker", + "level": "WARNING" + } + } + +and changing the section on the ``stdout`` handler to add it: + +.. code-block:: json + + "stdout": { + "class": "logging.StreamHandler", + "level": "INFO", + "formatter": "simple", + "stream": "ext://sys.stdout", + "filters": ["warnings_and_below"] + } + +A filter is just a function, so we can define the ``filter_maker`` (a factory +function) as follows: + +.. code-block:: python + + def filter_maker(level): + level = getattr(logging, level) + + def filter(record): + return record.levelno <= level + + return filter + +This converts the string argument passed in to a numeric level, and returns a +function which only returns ``True`` if the level of the passed in record is +at or below the specified level. Note that in this example I have defined the +``filter_maker`` in a test script ``main.py`` that I run from the command line, +so its module will be ``__main__`` - hence the ``__main__.filter_maker`` in the +filter configuration. You will need to change that if you define it in a +different module. + +With the filter added, we can run ``main.py``, which in full is: + +.. code-block:: python + + import json + import logging + import logging.config + + CONFIG = ''' + { + "version": 1, + "disable_existing_loggers": false, + "formatters": { + "simple": { + "format": "%(levelname)-8s - %(message)s" + } + }, + "filters": { + "warnings_and_below": { + "()" : "__main__.filter_maker", + "level": "WARNING" + } + }, + "handlers": { + "stdout": { + "class": "logging.StreamHandler", + "level": "INFO", + "formatter": "simple", + "stream": "ext://sys.stdout", + "filters": ["warnings_and_below"] + }, + "stderr": { + "class": "logging.StreamHandler", + "level": "ERROR", + "formatter": "simple", + "stream": "ext://sys.stderr" + }, + "file": { + "class": "logging.FileHandler", + "formatter": "simple", + "filename": "app.log", + "mode": "w" + } + }, + "root": { + "level": "DEBUG", + "handlers": [ + "stderr", + "stdout", + "file" + ] + } + } + ''' + + def filter_maker(level): + level = getattr(logging, level) + + def filter(record): + return record.levelno <= level + + return filter + + logging.config.dictConfig(json.loads(CONFIG)) + logging.debug('A DEBUG message') + logging.info('An INFO message') + logging.warning('A WARNING message') + logging.error('An ERROR message') + logging.critical('A CRITICAL message') + +And after running it like this: + +.. code-block:: shell + + python main.py 2>stderr.log >stdout.log + +We can see the results are as expected: + +.. code-block:: shell + + $ more *.log + :::::::::::::: + app.log + :::::::::::::: + DEBUG - A DEBUG message + INFO - An INFO message + WARNING - A WARNING message + ERROR - An ERROR message + CRITICAL - A CRITICAL message + :::::::::::::: + stderr.log + :::::::::::::: + ERROR - An ERROR message + CRITICAL - A CRITICAL message + :::::::::::::: + stdout.log + :::::::::::::: + INFO - An INFO message + WARNING - A WARNING message + Configuration server example ---------------------------- @@ -326,6 +537,8 @@ configuration:: print('complete') +.. _blocking-handlers: + Dealing with handlers that block -------------------------------- @@ -391,6 +604,14 @@ which, when run, will produce: MainThread: Look out! +.. note:: Although the earlier discussion wasn't specifically talking about + async code, but rather about slow logging handlers, it should be noted that + when logging from async code, network and even file handlers could lead to + problems (blocking the event loop) because some logging is done from + :mod:`asyncio` internals. It might be best, if any async code is used in an + application, to use the above approach for logging, so that any blocking code + runs only in the ``QueueListener`` thread. + .. versionchanged:: 3.5 Prior to Python 3.5, the :class:`QueueListener` always passed every message received from the queue to every handler it was initialized with. (This was @@ -541,6 +762,75 @@ alternative there, as well as adapting the above script to use your alternative serialization. +Running a logging socket listener in production +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. _socket-listener-gist: https://gist.github.com/vsajip/4b227eeec43817465ca835ca66f75e2b + +To run a logging listener in production, you may need to use a +process-management tool such as `Supervisor <http://supervisord.org/>`_. +`Here is a Gist <socket-listener-gist_>`__ +which provides the bare-bones files to run the above functionality using +Supervisor. It consists of the following files: + ++-------------------------+----------------------------------------------------+ +| File | Purpose | ++=========================+====================================================+ +| :file:`prepare.sh` | A Bash script to prepare the environment for | +| | testing | ++-------------------------+----------------------------------------------------+ +| :file:`supervisor.conf` | The Supervisor configuration file, which has | +| | entries for the listener and a multi-process web | +| | application | ++-------------------------+----------------------------------------------------+ +| :file:`ensure_app.sh` | A Bash script to ensure that Supervisor is running | +| | with the above configuration | ++-------------------------+----------------------------------------------------+ +| :file:`log_listener.py` | The socket listener program which receives log | +| | events and records them to a file | ++-------------------------+----------------------------------------------------+ +| :file:`main.py` | A simple web application which performs logging | +| | via a socket connected to the listener | ++-------------------------+----------------------------------------------------+ +| :file:`webapp.json` | A JSON configuration file for the web application | ++-------------------------+----------------------------------------------------+ +| :file:`client.py` | A Python script to exercise the web application | ++-------------------------+----------------------------------------------------+ + +The web application uses `Gunicorn <https://gunicorn.org/>`_, which is a +popular web application server that starts multiple worker processes to handle +requests. This example setup shows how the workers can write to the same log file +without conflicting with one another --- they all go through the socket listener. + +To test these files, do the following in a POSIX environment: + +#. Download `the Gist <socket-listener-gist_>`__ + as a ZIP archive using the :guilabel:`Download ZIP` button. + +#. Unzip the above files from the archive into a scratch directory. + +#. In the scratch directory, run ``bash prepare.sh`` to get things ready. + This creates a :file:`run` subdirectory to contain Supervisor-related and + log files, and a :file:`venv` subdirectory to contain a virtual environment + into which ``bottle``, ``gunicorn`` and ``supervisor`` are installed. + +#. Run ``bash ensure_app.sh`` to ensure that Supervisor is running with + the above configuration. + +#. Run ``venv/bin/python client.py`` to exercise the web application, + which will lead to records being written to the log. + +#. Inspect the log files in the :file:`run` subdirectory. You should see the + most recent log lines in files matching the pattern :file:`app.log*`. They won't be in + any particular order, since they have been handled concurrently by different + worker processes in a non-deterministic way. + +#. You can shut down the listener and the web application by running + ``venv/bin/supervisorctl -c supervisor.conf shutdown``. + +You may need to tweak the configuration files in the unlikely event that the +configured ports clash with something else in your test environment. + .. _context-info: Adding contextual information to your logging output @@ -702,6 +992,254 @@ which, when run, produces something like: 2010-09-06 22:38:15,301 d.e.f DEBUG IP: 123.231.231.123 User: fred A message at DEBUG level with 2 parameters 2010-09-06 22:38:15,301 d.e.f INFO IP: 123.231.231.123 User: fred A message at INFO level with 2 parameters +Use of ``contextvars`` +---------------------- + +Since Python 3.7, the :mod:`contextvars` module has provided context-local storage +which works for both :mod:`threading` and :mod:`asyncio` processing needs. This type +of storage may thus be generally preferable to thread-locals. The following example +shows how, in a multi-threaded environment, logs can populated with contextual +information such as, for example, request attributes handled by web applications. + +For the purposes of illustration, say that you have different web applications, each +independent of the other but running in the same Python process and using a library +common to them. How can each of these applications have their own log, where all +logging messages from the library (and other request processing code) are directed to +the appropriate application's log file, while including in the log additional +contextual information such as client IP, HTTP request method and client username? + +Let's assume that the library can be simulated by the following code: + +.. code-block:: python + + # webapplib.py + import logging + import time + + logger = logging.getLogger(__name__) + + def useful(): + # Just a representative event logged from the library + logger.debug('Hello from webapplib!') + # Just sleep for a bit so other threads get to run + time.sleep(0.01) + +We can simulate the multiple web applications by means of two simple classes, +``Request`` and ``WebApp``. These simulate how real threaded web applications work - +each request is handled by a thread: + +.. code-block:: python + + # main.py + import argparse + from contextvars import ContextVar + import logging + import os + from random import choice + import threading + import webapplib + + logger = logging.getLogger(__name__) + root = logging.getLogger() + root.setLevel(logging.DEBUG) + + class Request: + """ + A simple dummy request class which just holds dummy HTTP request method, + client IP address and client username + """ + def __init__(self, method, ip, user): + self.method = method + self.ip = ip + self.user = user + + # A dummy set of requests which will be used in the simulation - we'll just pick + # from this list randomly. Note that all GET requests are from 192.168.2.XXX + # addresses, whereas POST requests are from 192.16.3.XXX addresses. Three users + # are represented in the sample requests. + + REQUESTS = [ + Request('GET', '192.168.2.20', 'jim'), + Request('POST', '192.168.3.20', 'fred'), + Request('GET', '192.168.2.21', 'sheila'), + Request('POST', '192.168.3.21', 'jim'), + Request('GET', '192.168.2.22', 'fred'), + Request('POST', '192.168.3.22', 'sheila'), + ] + + # Note that the format string includes references to request context information + # such as HTTP method, client IP and username + + formatter = logging.Formatter('%(threadName)-11s %(appName)s %(name)-9s %(user)-6s %(ip)s %(method)-4s %(message)s') + + # Create our context variables. These will be filled at the start of request + # processing, and used in the logging that happens during that processing + + ctx_request = ContextVar('request') + ctx_appname = ContextVar('appname') + + class InjectingFilter(logging.Filter): + """ + A filter which injects context-specific information into logs and ensures + that only information for a specific webapp is included in its log + """ + def __init__(self, app): + self.app = app + + def filter(self, record): + request = ctx_request.get() + record.method = request.method + record.ip = request.ip + record.user = request.user + record.appName = appName = ctx_appname.get() + return appName == self.app.name + + class WebApp: + """ + A dummy web application class which has its own handler and filter for a + webapp-specific log. + """ + def __init__(self, name): + self.name = name + handler = logging.FileHandler(name + '.log', 'w') + f = InjectingFilter(self) + handler.setFormatter(formatter) + handler.addFilter(f) + root.addHandler(handler) + self.num_requests = 0 + + def process_request(self, request): + """ + This is the dummy method for processing a request. It's called on a + different thread for every request. We store the context information into + the context vars before doing anything else. + """ + ctx_request.set(request) + ctx_appname.set(self.name) + self.num_requests += 1 + logger.debug('Request processing started') + webapplib.useful() + logger.debug('Request processing finished') + + def main(): + fn = os.path.splitext(os.path.basename(__file__))[0] + adhf = argparse.ArgumentDefaultsHelpFormatter + ap = argparse.ArgumentParser(formatter_class=adhf, prog=fn, + description='Simulate a couple of web ' + 'applications handling some ' + 'requests, showing how request ' + 'context can be used to ' + 'populate logs') + aa = ap.add_argument + aa('--count', '-c', type=int, default=100, help='How many requests to simulate') + options = ap.parse_args() + + # Create the dummy webapps and put them in a list which we can use to select + # from randomly + app1 = WebApp('app1') + app2 = WebApp('app2') + apps = [app1, app2] + threads = [] + # Add a common handler which will capture all events + handler = logging.FileHandler('app.log', 'w') + handler.setFormatter(formatter) + root.addHandler(handler) + + # Generate calls to process requests + for i in range(options.count): + try: + # Pick an app at random and a request for it to process + app = choice(apps) + request = choice(REQUESTS) + # Process the request in its own thread + t = threading.Thread(target=app.process_request, args=(request,)) + threads.append(t) + t.start() + except KeyboardInterrupt: + break + + # Wait for the threads to terminate + for t in threads: + t.join() + + for app in apps: + print('%s processed %s requests' % (app.name, app.num_requests)) + + if __name__ == '__main__': + main() + +If you run the above, you should find that roughly half the requests go +into :file:`app1.log` and the rest into :file:`app2.log`, and the all the requests are +logged to :file:`app.log`. Each webapp-specific log will contain only log entries for +only that webapp, and the request information will be displayed consistently in the +log (i.e. the information in each dummy request will always appear together in a log +line). This is illustrated by the following shell output: + +.. code-block:: shell + + ~/logging-contextual-webapp$ python main.py + app1 processed 51 requests + app2 processed 49 requests + ~/logging-contextual-webapp$ wc -l *.log + 153 app1.log + 147 app2.log + 300 app.log + 600 total + ~/logging-contextual-webapp$ head -3 app1.log + Thread-3 (process_request) app1 __main__ jim 192.168.3.21 POST Request processing started + Thread-3 (process_request) app1 webapplib jim 192.168.3.21 POST Hello from webapplib! + Thread-5 (process_request) app1 __main__ jim 192.168.3.21 POST Request processing started + ~/logging-contextual-webapp$ head -3 app2.log + Thread-1 (process_request) app2 __main__ sheila 192.168.2.21 GET Request processing started + Thread-1 (process_request) app2 webapplib sheila 192.168.2.21 GET Hello from webapplib! + Thread-2 (process_request) app2 __main__ jim 192.168.2.20 GET Request processing started + ~/logging-contextual-webapp$ head app.log + Thread-1 (process_request) app2 __main__ sheila 192.168.2.21 GET Request processing started + Thread-1 (process_request) app2 webapplib sheila 192.168.2.21 GET Hello from webapplib! + Thread-2 (process_request) app2 __main__ jim 192.168.2.20 GET Request processing started + Thread-3 (process_request) app1 __main__ jim 192.168.3.21 POST Request processing started + Thread-2 (process_request) app2 webapplib jim 192.168.2.20 GET Hello from webapplib! + Thread-3 (process_request) app1 webapplib jim 192.168.3.21 POST Hello from webapplib! + Thread-4 (process_request) app2 __main__ fred 192.168.2.22 GET Request processing started + Thread-5 (process_request) app1 __main__ jim 192.168.3.21 POST Request processing started + Thread-4 (process_request) app2 webapplib fred 192.168.2.22 GET Hello from webapplib! + Thread-6 (process_request) app1 __main__ jim 192.168.3.21 POST Request processing started + ~/logging-contextual-webapp$ grep app1 app1.log | wc -l + 153 + ~/logging-contextual-webapp$ grep app2 app2.log | wc -l + 147 + ~/logging-contextual-webapp$ grep app1 app.log | wc -l + 153 + ~/logging-contextual-webapp$ grep app2 app.log | wc -l + 147 + + +Imparting contextual information in handlers +-------------------------------------------- + +Each :class:`~Handler` has its own chain of filters. +If you want to add contextual information to a :class:`LogRecord` without leaking +it to other handlers, you can use a filter that returns +a new :class:`~LogRecord` instead of modifying it in-place, as shown in the following script:: + + import copy + import logging + + def filter(record: logging.LogRecord): + record = copy.copy(record) + record.user = 'jim' + return record + + if __name__ == '__main__': + logger = logging.getLogger() + logger.setLevel(logging.INFO) + handler = logging.StreamHandler() + formatter = logging.Formatter('%(message)s from %(user)-8s') + handler.setFormatter(formatter) + handler.addFilter(filter) + logger.addHandler(handler) + + logger.info('A log message') .. _multiple-processes: @@ -982,6 +1520,17 @@ to this (remembering to first import :mod:`concurrent.futures`):: for i in range(10): executor.submit(worker_process, queue, worker_configurer) +Deploying Web applications using Gunicorn and uWSGI +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When deploying Web applications using `Gunicorn <https://gunicorn.org/>`_ or `uWSGI +<https://uwsgi-docs.readthedocs.io/en/latest/>`_ (or similar), multiple worker +processes are created to handle client requests. In such environments, avoid creating +file-based handlers directly in your web application. Instead, use a +:class:`SocketHandler` to log from the web application to a listener in a separate +process. This can be set up using a process management tool such as Supervisor - see +`Running a logging socket listener in production`_ for more details. + Using file rotation ------------------- @@ -1433,26 +1982,47 @@ Using a rotator and namer to customize log rotation processing -------------------------------------------------------------- An example of how you can define a namer and rotator is given in the following -snippet, which shows zlib-based compression of the log file:: +runnable script, which shows gzip compression of the log file:: + + import gzip + import logging + import logging.handlers + import os + import shutil def namer(name): return name + ".gz" def rotator(source, dest): - with open(source, "rb") as sf: - data = sf.read() - compressed = zlib.compress(data, 9) - with open(dest, "wb") as df: - df.write(compressed) + with open(source, 'rb') as f_in: + with gzip.open(dest, 'wb') as f_out: + shutil.copyfileobj(f_in, f_out) os.remove(source) - rh = logging.handlers.RotatingFileHandler(...) + + rh = logging.handlers.RotatingFileHandler('rotated.log', maxBytes=128, backupCount=5) rh.rotator = rotator rh.namer = namer -These are not "true" .gz files, as they are bare compressed data, with no -"container" such as you’d find in an actual gzip file. This snippet is just -for illustration purposes. + root = logging.getLogger() + root.setLevel(logging.INFO) + root.addHandler(rh) + f = logging.Formatter('%(asctime)s %(message)s') + rh.setFormatter(f) + for i in range(1000): + root.info(f'Message no. {i + 1}') + +After running this, you will see six new files, five of which are compressed: + +.. code-block:: shell-session + + $ ls rotated.log* + rotated.log rotated.log.2.gz rotated.log.4.gz + rotated.log.1.gz rotated.log.3.gz rotated.log.5.gz + $ zcat rotated.log.1.gz + 2023-01-20 02:28:17,767 Message no. 996 + 2023-01-20 02:28:17,767 Message no. 997 + 2023-01-20 02:28:17,767 Message no. 998 A more elaborate multiprocessing example ---------------------------------------- @@ -1766,22 +2336,15 @@ Python used. If you need more specialised processing, you can use a custom JSON encoder, as in the following complete example:: - from __future__ import unicode_literals - import json import logging - # This next bit is to ensure the script runs unchanged on 2.x and 3.x - try: - unicode - except NameError: - unicode = str class Encoder(json.JSONEncoder): def default(self, o): if isinstance(o, set): return tuple(o) - elif isinstance(o, unicode): + elif isinstance(o, str): return o.encode('unicode_escape').decode('ascii') return super().default(o) @@ -2409,13 +2972,95 @@ You can of course use the conventional means of decoration:: ... +.. _buffered-smtp: + +Sending logging messages to email, with buffering +------------------------------------------------- + +To illustrate how you can send log messages via email, so that a set number of +messages are sent per email, you can subclass +:class:`~logging.handlers.BufferingHandler`. In the following example, which you can +adapt to suit your specific needs, a simple test harness is provided which allows you +to run the script with command line arguments specifying what you typically need to +send things via SMTP. (Run the downloaded script with the ``-h`` argument to see the +required and optional arguments.) + +.. code-block:: python + + import logging + import logging.handlers + import smtplib + + class BufferingSMTPHandler(logging.handlers.BufferingHandler): + def __init__(self, mailhost, port, username, password, fromaddr, toaddrs, + subject, capacity): + logging.handlers.BufferingHandler.__init__(self, capacity) + self.mailhost = mailhost + self.mailport = port + self.username = username + self.password = password + self.fromaddr = fromaddr + if isinstance(toaddrs, str): + toaddrs = [toaddrs] + self.toaddrs = toaddrs + self.subject = subject + self.setFormatter(logging.Formatter("%(asctime)s %(levelname)-5s %(message)s")) + + def flush(self): + if len(self.buffer) > 0: + try: + smtp = smtplib.SMTP(self.mailhost, self.mailport) + smtp.starttls() + smtp.login(self.username, self.password) + msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (self.fromaddr, ','.join(self.toaddrs), self.subject) + for record in self.buffer: + s = self.format(record) + msg = msg + s + "\r\n" + smtp.sendmail(self.fromaddr, self.toaddrs, msg) + smtp.quit() + except Exception: + if logging.raiseExceptions: + raise + self.buffer = [] + + if __name__ == '__main__': + import argparse + + ap = argparse.ArgumentParser() + aa = ap.add_argument + aa('host', metavar='HOST', help='SMTP server') + aa('--port', '-p', type=int, default=587, help='SMTP port') + aa('user', metavar='USER', help='SMTP username') + aa('password', metavar='PASSWORD', help='SMTP password') + aa('to', metavar='TO', help='Addressee for emails') + aa('sender', metavar='SENDER', help='Sender email address') + aa('--subject', '-s', + default='Test Logging email from Python logging module (buffering)', + help='Subject of email') + options = ap.parse_args() + logger = logging.getLogger() + logger.setLevel(logging.DEBUG) + h = BufferingSMTPHandler(options.host, options.port, options.user, + options.password, options.sender, + options.to, options.subject, 10) + logger.addHandler(h) + for i in range(102): + logger.info("Info index = %d", i) + h.flush() + h.close() + +If you run this script and your SMTP server is correctly set up, you should find that +it sends eleven emails to the addressee you specify. The first ten emails will each +have ten log messages, and the eleventh will have two messages. That makes up 102 +messages as specified in the script. + .. _utc-formatting: Formatting times using UTC (GMT) via configuration -------------------------------------------------- Sometimes you want to format times using UTC, which can be done using a class -such as `UTCFormatter`, shown below:: +such as ``UTCFormatter``, shown below:: import logging import time @@ -2980,6 +3625,236 @@ refer to the comments in the code snippet for more detailed information. if __name__=='__main__': main() +Logging to syslog with RFC5424 support +-------------------------------------- + +Although :rfc:`5424` dates from 2009, most syslog servers are configured by default to +use the older :rfc:`3164`, which hails from 2001. When ``logging`` was added to Python +in 2003, it supported the earlier (and only existing) protocol at the time. Since +RFC5424 came out, as there has not been widespread deployment of it in syslog +servers, the :class:`~logging.handlers.SysLogHandler` functionality has not been +updated. + +RFC 5424 contains some useful features such as support for structured data, and if you +need to be able to log to a syslog server with support for it, you can do so with a +subclassed handler which looks something like this:: + + import datetime + import logging.handlers + import re + import socket + import time + + class SysLogHandler5424(logging.handlers.SysLogHandler): + + tz_offset = re.compile(r'([+-]\d{2})(\d{2})$') + escaped = re.compile(r'([\]"\\])') + + def __init__(self, *args, **kwargs): + self.msgid = kwargs.pop('msgid', None) + self.appname = kwargs.pop('appname', None) + super().__init__(*args, **kwargs) + + def format(self, record): + version = 1 + asctime = datetime.datetime.fromtimestamp(record.created).isoformat() + m = self.tz_offset.match(time.strftime('%z')) + has_offset = False + if m and time.timezone: + hrs, mins = m.groups() + if int(hrs) or int(mins): + has_offset = True + if not has_offset: + asctime += 'Z' + else: + asctime += f'{hrs}:{mins}' + try: + hostname = socket.gethostname() + except Exception: + hostname = '-' + appname = self.appname or '-' + procid = record.process + msgid = '-' + msg = super().format(record) + sdata = '-' + if hasattr(record, 'structured_data'): + sd = record.structured_data + # This should be a dict where the keys are SD-ID and the value is a + # dict mapping PARAM-NAME to PARAM-VALUE (refer to the RFC for what these + # mean) + # There's no error checking here - it's purely for illustration, and you + # can adapt this code for use in production environments + parts = [] + + def replacer(m): + g = m.groups() + return '\\' + g[0] + + for sdid, dv in sd.items(): + part = f'[{sdid}' + for k, v in dv.items(): + s = str(v) + s = self.escaped.sub(replacer, s) + part += f' {k}="{s}"' + part += ']' + parts.append(part) + sdata = ''.join(parts) + return f'{version} {asctime} {hostname} {appname} {procid} {msgid} {sdata} {msg}' + +You'll need to be familiar with RFC 5424 to fully understand the above code, and it +may be that you have slightly different needs (e.g. for how you pass structural data +to the log). Nevertheless, the above should be adaptable to your speciric needs. With +the above handler, you'd pass structured data using something like this:: + + sd = { + 'foo@12345': {'bar': 'baz', 'baz': 'bozz', 'fizz': r'buzz'}, + 'foo@54321': {'rab': 'baz', 'zab': 'bozz', 'zzif': r'buzz'} + } + extra = {'structured_data': sd} + i = 1 + logger.debug('Message %d', i, extra=extra) + +How to treat a logger like an output stream +------------------------------------------- + +Sometimes, you need to interface to a third-party API which expects a file-like +object to write to, but you want to direct the API's output to a logger. You +can do this using a class which wraps a logger with a file-like API. +Here's a short script illustrating such a class: + +.. code-block:: python + + import logging + + class LoggerWriter: + def __init__(self, logger, level): + self.logger = logger + self.level = level + + def write(self, message): + if message != '\n': # avoid printing bare newlines, if you like + self.logger.log(self.level, message) + + def flush(self): + # doesn't actually do anything, but might be expected of a file-like + # object - so optional depending on your situation + pass + + def close(self): + # doesn't actually do anything, but might be expected of a file-like + # object - so optional depending on your situation. You might want + # to set a flag so that later calls to write raise an exception + pass + + def main(): + logging.basicConfig(level=logging.DEBUG) + logger = logging.getLogger('demo') + info_fp = LoggerWriter(logger, logging.INFO) + debug_fp = LoggerWriter(logger, logging.DEBUG) + print('An INFO message', file=info_fp) + print('A DEBUG message', file=debug_fp) + + if __name__ == "__main__": + main() + +When this script is run, it prints + +.. code-block:: text + + INFO:demo:An INFO message + DEBUG:demo:A DEBUG message + +You could also use ``LoggerWriter`` to redirect ``sys.stdout`` and +``sys.stderr`` by doing something like this: + +.. code-block:: python + + import sys + + sys.stdout = LoggerWriter(logger, logging.INFO) + sys.stderr = LoggerWriter(logger, logging.WARNING) + +You should do this *after* configuring logging for your needs. In the above +example, the :func:`~logging.basicConfig` call does this (using the +``sys.stderr`` value *before* it is overwritten by a ``LoggerWriter`` +instance). Then, you'd get this kind of result: + +.. code-block:: pycon + + >>> print('Foo') + INFO:demo:Foo + >>> print('Bar', file=sys.stderr) + WARNING:demo:Bar + >>> + +Of course, the examples above show output according to the format used by +:func:`~logging.basicConfig`, but you can use a different formatter when you +configure logging. + +Note that with the above scheme, you are somewhat at the mercy of buffering and +the sequence of write calls which you are intercepting. For example, with the +definition of ``LoggerWriter`` above, if you have the snippet + +.. code-block:: python + + sys.stderr = LoggerWriter(logger, logging.WARNING) + 1 / 0 + +then running the script results in + +.. code-block:: text + + WARNING:demo:Traceback (most recent call last): + + WARNING:demo: File "/home/runner/cookbook-loggerwriter/test.py", line 53, in <module> + + WARNING:demo: + WARNING:demo:main() + WARNING:demo: File "/home/runner/cookbook-loggerwriter/test.py", line 49, in main + + WARNING:demo: + WARNING:demo:1 / 0 + WARNING:demo:ZeroDivisionError + WARNING:demo:: + WARNING:demo:division by zero + +As you can see, this output isn't ideal. That's because the underlying code +which writes to ``sys.stderr`` makes multiple writes, each of which results in a +separate logged line (for example, the last three lines above). To get around +this problem, you need to buffer things and only output log lines when newlines +are seen. Let's use a slghtly better implementation of ``LoggerWriter``: + +.. code-block:: python + + class BufferingLoggerWriter(LoggerWriter): + def __init__(self, logger, level): + super().__init__(logger, level) + self.buffer = '' + + def write(self, message): + if '\n' not in message: + self.buffer += message + else: + parts = message.split('\n') + if self.buffer: + s = self.buffer + parts.pop(0) + self.logger.log(self.level, s) + self.buffer = parts.pop() + for part in parts: + self.logger.log(self.level, part) + +This just buffers up stuff until a newline is seen, and then logs complete +lines. With this approach, you get better output: + +.. code-block:: text + + WARNING:demo:Traceback (most recent call last): + WARNING:demo: File "/home/runner/cookbook-loggerwriter/main.py", line 55, in <module> + WARNING:demo: main() + WARNING:demo: File "/home/runner/cookbook-loggerwriter/main.py", line 52, in main + WARNING:demo: 1/0 + WARNING:demo:ZeroDivisionError: division by zero + .. patterns-to-avoid: @@ -2991,7 +3866,6 @@ need to do or deal with, it is worth mentioning some usage patterns which are *unhelpful*, and which should therefore be avoided in most cases. The following sections are in no particular order. - Opening the same log file multiple times ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -3040,7 +3914,6 @@ that in other languages such as Java and C#, loggers are often static class attributes. However, this pattern doesn't make sense in Python, where the module (and not the class) is the unit of software decomposition. - Adding handlers other than :class:`NullHandler` to a logger in a library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -3049,7 +3922,6 @@ responsibility of the application developer, not the library developer. If you are maintaining a library, ensure that you don't add handlers to any of your loggers other than a :class:`~logging.NullHandler` instance. - Creating a lot of loggers ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -3060,3 +3932,23 @@ the :ref:`existing mechanisms <context-info>` for passing contextual information into your logs and restrict the loggers created to those describing areas within your application (generally modules, but occasionally slightly more fine-grained than that). + +.. _cookbook-ref-links: + +Other resources +--------------- + +.. seealso:: + + Module :mod:`logging` + API reference for the logging module. + + Module :mod:`logging.config` + Configuration API for the logging module. + + Module :mod:`logging.handlers` + Useful handlers included with the logging module. + + :ref:`Basic Tutorial <logging-basic-tutorial>` + + :ref:`Advanced Tutorial <logging-advanced-tutorial>` diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst index fcc6bec7688..145449b2dfb 100644 --- a/Doc/howto/logging.rst +++ b/Doc/howto/logging.rst @@ -8,6 +8,9 @@ Logging HOWTO .. currentmodule:: logging +This page contains tutorial information. For links to reference information and a +logging cookbook, please see :ref:`tutorial-ref-links`. + Basic Logging Tutorial ---------------------- @@ -124,7 +127,7 @@ Logging to a file ^^^^^^^^^^^^^^^^^ A very common situation is that of recording logging events in a file, so let's -look at that next. Be sure to try the following in a newly-started Python +look at that next. Be sure to try the following in a newly started Python interpreter, and don't just continue from the session described above:: import logging @@ -178,10 +181,11 @@ following example:: raise ValueError('Invalid log level: %s' % loglevel) logging.basicConfig(level=numeric_level, ...) -The call to :func:`basicConfig` should come *before* any calls to :func:`debug`, -:func:`info` etc. As it's intended as a one-off simple configuration facility, -only the first call will actually do anything: subsequent calls are effectively -no-ops. +The call to :func:`basicConfig` should come *before* any calls to +:func:`debug`, :func:`info`, etc. Otherwise, those functions will call +:func:`basicConfig` for you with the default options. As it's intended as a +one-off simple configuration facility, only the first call will actually do +anything: subsequent calls are effectively no-ops. If you run the above script several times, the messages from successive runs are appended to the file *example.log*. If you want each run to start afresh, @@ -335,7 +339,7 @@ favourite beverage and carry on. If your logging needs are simple, then use the above examples to incorporate logging into your own scripts, and if you run into problems or don't understand something, please post a question on the comp.lang.python Usenet -group (available at https://groups.google.com/forum/#!forum/comp.lang.python) and you +group (available at https://groups.google.com/g/comp.lang.python) and you should receive help before too long. Still here? You can carry on reading the next few sections, which provide a @@ -551,14 +555,14 @@ raw message. If there is no date format string, the default date format is: %Y-%m-%d %H:%M:%S -with the milliseconds tacked on at the end. The ``style`` is one of `%`, '{' -or '$'. If one of these is not specified, then '%' will be used. +with the milliseconds tacked on at the end. The ``style`` is one of ``'%'``, +``'{'``, or ``'$'``. If one of these is not specified, then ``'%'`` will be used. -If the ``style`` is '%', the message format string uses +If the ``style`` is ``'%'``, the message format string uses ``%(<dictionary key>)s`` styled string substitution; the possible keys are -documented in :ref:`logrecord-attributes`. If the style is '{', the message +documented in :ref:`logrecord-attributes`. If the style is ``'{'``, the message format string is assumed to be compatible with :meth:`str.format` (using -keyword arguments), while if the style is '$' then the message format string +keyword arguments), while if the style is ``'$'`` then the message format string should conform to what is expected by :meth:`string.Template.substitute`. .. versionchanged:: 3.2 @@ -831,6 +835,13 @@ should have the desired effect. If an organisation produces a number of libraries, then the logger name specified can be 'orgname.foo' rather than just 'foo'. +.. note:: It is strongly advised that you *do not log to the root logger* + in your library. Instead, use a logger with a unique and easily + identifiable name, such as the ``__name__`` for your library's top-level package + or module. Logging to the root logger will make it difficult or impossible for + the application developer to configure the logging verbosity or handlers of + your library as they wish. + .. note:: It is strongly advised that you *do not add any handlers other than* :class:`~logging.NullHandler` *to your library's loggers*. This is because the configuration of handlers is the prerogative of the application @@ -1093,11 +1104,19 @@ need: | Current process name when using ``multiprocessing`` | Set ``logging.logMultiprocessing`` to ``False``. | | to manage multiple processes. | | +-----------------------------------------------------+---------------------------------------------------+ +| Current :class:`asyncio.Task` name when using | Set ``logging.logAsyncioTasks`` to ``False``. | +| ``asyncio``. | | ++-----------------------------------------------------+---------------------------------------------------+ Also note that the core logging module only includes the basic handlers. If you don't import :mod:`logging.handlers` and :mod:`logging.config`, they won't take up any memory. +.. _tutorial-ref-links: + +Other resources +--------------- + .. seealso:: Module :mod:`logging` diff --git a/Doc/howto/logging_flow.png b/Doc/howto/logging_flow.png index fac4acd7755..d65e597f811 100644 Binary files a/Doc/howto/logging_flow.png and b/Doc/howto/logging_flow.png differ diff --git a/Doc/howto/perf_profiling.rst b/Doc/howto/perf_profiling.rst new file mode 100644 index 00000000000..ad2eb7b4d58 --- /dev/null +++ b/Doc/howto/perf_profiling.rst @@ -0,0 +1,210 @@ +.. highlight:: shell-session + +.. _perf_profiling: + +============================================== +Python support for the Linux ``perf`` profiler +============================================== + +:author: Pablo Galindo + +`The Linux perf profiler <https://perf.wiki.kernel.org>`_ +is a very powerful tool that allows you to profile and obtain +information about the performance of your application. +``perf`` also has a very vibrant ecosystem of tools +that aid with the analysis of the data that it produces. + +The main problem with using the ``perf`` profiler with Python applications is that +``perf`` only allows to get information about native symbols, this is, the names of +the functions and procedures written in C. This means that the names and file names +of the Python functions in your code will not appear in the output of the ``perf``. + +Since Python 3.12, the interpreter can run in a special mode that allows Python +functions to appear in the output of the ``perf`` profiler. When this mode is +enabled, the interpreter will interpose a small piece of code compiled on the +fly before the execution of every Python function and it will teach ``perf`` the +relationship between this piece of code and the associated Python function using +`perf map files`_. + +.. note:: + + Support for the ``perf`` profiler is only currently available for Linux on + selected architectures. Check the output of the configure build step or + check the output of ``python -m sysconfig | grep HAVE_PERF_TRAMPOLINE`` + to see if your system is supported. + +For example, consider the following script: + +.. code-block:: python + + def foo(n): + result = 0 + for _ in range(n): + result += 1 + return result + + def bar(n): + foo(n) + + def baz(n): + bar(n) + + if __name__ == "__main__": + baz(1000000) + +We can run ``perf`` to sample CPU stack traces at 9999 Hertz:: + + $ perf record -F 9999 -g -o perf.data python my_script.py + +Then we can use ``perf`` report to analyze the data: + +.. code-block:: shell-session + + $ perf report --stdio -n -g + + # Children Self Samples Command Shared Object Symbol + # ........ ........ ............ .......... .................. .......................................... + # + 91.08% 0.00% 0 python.exe python.exe [.] _start + | + ---_start + | + --90.71%--__libc_start_main + Py_BytesMain + | + |--56.88%--pymain_run_python.constprop.0 + | | + | |--56.13%--_PyRun_AnyFileObject + | | _PyRun_SimpleFileObject + | | | + | | |--55.02%--run_mod + | | | | + | | | --54.65%--PyEval_EvalCode + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | | + | | | |--51.67%--_PyEval_EvalFrameDefault + | | | | | + | | | | |--11.52%--_PyLong_Add + | | | | | | + | | | | | |--2.97%--_PyObject_Malloc + ... + +As you can see here, the Python functions are not shown in the output, only ``_Py_Eval_EvalFrameDefault`` appears +(the function that evaluates the Python bytecode) shows up. Unfortunately that's not very useful because all Python +functions use the same C function to evaluate bytecode so we cannot know which Python function corresponds to which +bytecode-evaluating function. + +Instead, if we run the same experiment with ``perf`` support enabled we get: + +.. code-block:: shell-session + + $ perf report --stdio -n -g + + # Children Self Samples Command Shared Object Symbol + # ........ ........ ............ .......... .................. ..................................................................... + # + 90.58% 0.36% 1 python.exe python.exe [.] _start + | + ---_start + | + --89.86%--__libc_start_main + Py_BytesMain + | + |--55.43%--pymain_run_python.constprop.0 + | | + | |--54.71%--_PyRun_AnyFileObject + | | _PyRun_SimpleFileObject + | | | + | | |--53.62%--run_mod + | | | | + | | | --53.26%--PyEval_EvalCode + | | | py::<module>:/src/script.py + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | py::baz:/src/script.py + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | py::bar:/src/script.py + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | py::foo:/src/script.py + | | | | + | | | |--51.81%--_PyEval_EvalFrameDefault + | | | | | + | | | | |--13.77%--_PyLong_Add + | | | | | | + | | | | | |--3.26%--_PyObject_Malloc + + + +How to enable ``perf`` profiling support +---------------------------------------- + +``perf`` profiling support can either be enabled from the start using +the environment variable :envvar:`PYTHONPERFSUPPORT` or the +:option:`-X perf <-X>` option, +or dynamically using :func:`sys.activate_stack_trampoline` and +:func:`sys.deactivate_stack_trampoline`. + +The :mod:`!sys` functions take precedence over the :option:`!-X` option, +the :option:`!-X` option takes precedence over the environment variable. + +Example, using the environment variable:: + + $ PYTHONPERFSUPPORT=1 + $ python script.py + $ perf report -g -i perf.data + +Example, using the :option:`!-X` option:: + + $ python -X perf script.py + $ perf report -g -i perf.data + +Example, using the :mod:`sys` APIs in file :file:`example.py`: + +.. code-block:: python + + import sys + + sys.activate_stack_trampoline("perf") + do_profiled_stuff() + sys.deactivate_stack_trampoline() + + non_profiled_stuff() + +...then:: + + $ python ./example.py + $ perf report -g -i perf.data + + +How to obtain the best results +------------------------------ + +For the best results, Python should be compiled with +``CFLAGS="-fno-omit-frame-pointer -mno-omit-leaf-frame-pointer"`` as this allows +profilers to unwind using only the frame pointer and not on DWARF debug +information. This is because as the code that is interposed to allow ``perf`` +support is dynamically generated it doesn't have any DWARF debugging information +available. + +You can check if your system has been compiled with this flag by running:: + + $ python -m sysconfig | grep 'no-omit-frame-pointer' + +If you don't see any output it means that your interpreter has not been compiled with +frame pointers and therefore it may not be able to show Python functions in the output +of ``perf``. + +.. _perf map files: https://github.com/torvalds/linux/blob/0513e464f9007b70b96740271a948ca5ab6e7dd7/tools/perf/Documentation/jit-interface.txt diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst index abcc34287e3..add1c11be53 100644 --- a/Doc/howto/pyporting.rst +++ b/Doc/howto/pyporting.rst @@ -433,9 +433,9 @@ to make sure everything functions as expected in both versions of Python. .. _caniusepython3: https://pypi.org/project/caniusepython3 -.. _cheat sheet: http://python-future.org/compatible_idioms.html +.. _cheat sheet: https://python-future.org/compatible_idioms.html .. _coverage.py: https://pypi.org/project/coverage -.. _Futurize: http://python-future.org/automatic_conversion.html +.. _Futurize: https://python-future.org/automatic_conversion.html .. _importlib2: https://pypi.org/project/importlib2 .. _Modernize: https://python-modernize.readthedocs.io/ .. _mypy: http://mypy-lang.org/ @@ -445,7 +445,7 @@ to make sure everything functions as expected in both versions of Python. .. _Python 3 Q & A: https://ncoghlan-devs-python-notes.readthedocs.io/en/latest/python3/questions_and_answers.html .. _pytype: https://github.com/google/pytype -.. _python-future: http://python-future.org/ +.. _python-future: https://python-future.org/ .. _python-porting: https://mail.python.org/pipermail/python-porting/ .. _six: https://pypi.org/project/six .. _tox: https://pypi.org/project/tox diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst index d574c3736b1..655df59e27b 100644 --- a/Doc/howto/regex.rst +++ b/Doc/howto/regex.rst @@ -89,7 +89,7 @@ is the same as ``[a-c]``, which uses a range to express the same set of characters. If you wanted to match only lowercase letters, your RE would be ``[a-z]``. -Metacharacters are not active inside classes. For example, ``[akm$]`` will +Metacharacters (except ``\``) are not active inside classes. For example, ``[akm$]`` will match any of the characters ``'a'``, ``'k'``, ``'m'``, or ``'$'``; ``'$'`` is usually a metacharacter, but inside a character class it's stripped of its special nature. @@ -230,13 +230,13 @@ while ``+`` requires at least *one* occurrence. To use a similar example, ``ca+t`` will match ``'cat'`` (1 ``'a'``), ``'caaat'`` (3 ``'a'``\ s), but won't match ``'ct'``. -There are two more repeating qualifiers. The question mark character, ``?``, +There are two more repeating operators or quantifiers. The question mark character, ``?``, matches either once or zero times; you can think of it as marking something as being optional. For example, ``home-?brew`` matches either ``'homebrew'`` or ``'home-brew'``. -The most complicated repeated qualifier is ``{m,n}``, where *m* and *n* are -decimal integers. This qualifier means there must be at least *m* repetitions, +The most complicated quantifier is ``{m,n}``, where *m* and *n* are +decimal integers. This quantifier means there must be at least *m* repetitions, and at most *n*. For example, ``a/{1,3}b`` will match ``'a/b'``, ``'a//b'``, and ``'a///b'``. It won't match ``'ab'``, which has no slashes, or ``'a////b'``, which has four. @@ -245,7 +245,7 @@ You can omit either *m* or *n*; in that case, a reasonable value is assumed for the missing value. Omitting *m* is interpreted as a lower limit of 0, while omitting *n* results in an upper bound of infinity. -Readers of a reductionist bent may notice that the three other qualifiers can +Readers of a reductionist bent may notice that the three other quantifiers can all be expressed using this notation. ``{0,}`` is the same as ``*``, ``{1,}`` is equivalent to ``+``, and ``{0,1}`` is the same as ``?``. It's better to use ``*``, ``+``, or ``?`` when you can, simply because they're shorter and easier @@ -378,11 +378,7 @@ containing information about the match: where it starts and ends, the substring it matched, and more. You can learn about this by interactively experimenting with the :mod:`re` -module. If you have :mod:`tkinter` available, you may also want to look at -:source:`Tools/demo/redemo.py`, a demonstration program included with the -Python distribution. It allows you to enter REs and strings, and displays -whether the RE matches or fails. :file:`redemo.py` can be quite useful when -trying to debug a complicated RE. +module. This HOWTO uses the standard Python interpreter for its examples. First, run the Python interpreter, import the :mod:`re` module, and compile a RE:: @@ -803,7 +799,7 @@ which matches the header's value. Groups are marked by the ``'('``, ``')'`` metacharacters. ``'('`` and ``')'`` have much the same meaning as they do in mathematical expressions; they group together the expressions contained inside them, and you can repeat the contents -of a group with a repeating qualifier, such as ``*``, ``+``, ``?``, or +of a group with a quantifier, such as ``*``, ``+``, ``?``, or ``{m,n}``. For example, ``(ab)*`` will match zero or more repetitions of ``ab``. :: @@ -949,7 +945,7 @@ Additionally, you can retrieve named groups as a dictionary with >>> m.groupdict() {'first': 'Jane', 'last': 'Doe'} -Named groups are handy because they let you use easily-remembered names, instead +Named groups are handy because they let you use easily remembered names, instead of having to remember numbers. Here's an example RE from the :mod:`imaplib` module:: @@ -1326,7 +1322,7 @@ backtrack character by character until it finds a match for the ``>``. The final match extends from the ``'<'`` in ``'<html>'`` to the ``'>'`` in ``''``, which isn't what you want. -In this case, the solution is to use the non-greedy qualifiers ``*?``, ``+?``, +In this case, the solution is to use the non-greedy quantifiers ``*?``, ``+?``, ``??``, or ``{m,n}?``, which match as *little* text as possible. In the above example, the ``'>'`` is tried immediately after the first ``'<'`` matches, and when it fails, the engine advances a character at a time, retrying the ``'>'`` diff --git a/Doc/howto/sockets.rst b/Doc/howto/sockets.rst index e58f78a7cb0..0bbf97da397 100644 --- a/Doc/howto/sockets.rst +++ b/Doc/howto/sockets.rst @@ -252,20 +252,25 @@ Binary Data ----------- It is perfectly possible to send binary data over a socket. The major problem is -that not all machines use the same formats for binary data. For example, a -Motorola chip will represent a 16 bit integer with the value 1 as the two hex -bytes 00 01. Intel and DEC, however, are byte-reversed - that same 1 is 01 00. +that not all machines use the same formats for binary data. For example, +`network byte order `_ +is big-endian, with the most significant byte first, +so a 16 bit integer with the value ``1`` would be the two hex bytes ``00 01``. +However, most common processors (x86/AMD64, ARM, RISC-V), are little-endian, +with the least significant byte first - that same ``1`` would be ``01 00``. + Socket libraries have calls for converting 16 and 32 bit integers - ``ntohl, htonl, ntohs, htons`` where "n" means *network* and "h" means *host*, "s" means *short* and "l" means *long*. Where network order is host order, these do nothing, but where the machine is byte-reversed, these swap the bytes around appropriately. -In these days of 32 bit machines, the ascii representation of binary data is +In these days of 64-bit machines, the ASCII representation of binary data is frequently smaller than the binary representation. That's because a surprising -amount of the time, all those longs have the value 0, or maybe 1. The string "0" -would be two bytes, while binary is four. Of course, this doesn't fit well with -fixed-length messages. Decisions, decisions. +amount of the time, most integers have the value 0, or maybe 1. +The string ``"0"`` would be two bytes, while a full 64-bit integer would be 8. +Of course, this doesn't fit well with fixed-length messages. +Decisions, decisions. Disconnecting diff --git a/Doc/howto/sorting.rst b/Doc/howto/sorting.rst index 37328c82dff..decce12bf3f 100644 --- a/Doc/howto/sorting.rst +++ b/Doc/howto/sorting.rst @@ -186,8 +186,8 @@ The `Timsort `_ algorithm used in Python does multiple sorts efficiently because it can take advantage of any ordering already present in a dataset. -The Old Way Using Decorate-Sort-Undecorate -========================================== +Decorate-Sort-Undecorate +======================== This idiom is called Decorate-Sort-Undecorate after its three steps: @@ -226,90 +226,36 @@ after Randal L. Schwartz, who popularized it among Perl programmers. Now that Python sorting provides key-functions, this technique is not often needed. +Comparison Functions +==================== -The Old Way Using the *cmp* Parameter -===================================== +Unlike key functions that return an absolute value for sorting, a comparison +function computes the relative ordering for two inputs. -Many constructs given in this HOWTO assume Python 2.4 or later. Before that, -there was no :func:`sorted` builtin and :meth:`list.sort` took no keyword -arguments. Instead, all of the Py2.x versions supported a *cmp* parameter to -handle user specified comparison functions. +For example, a `balance scale +`_ +compares two samples giving a relative ordering: lighter, equal, or heavier. +Likewise, a comparison function such as ``cmp(a, b)`` will return a negative +value for less-than, zero if the inputs are equal, or a positive value for +greater-than. -In Py3.0, the *cmp* parameter was removed entirely (as part of a larger effort to -simplify and unify the language, eliminating the conflict between rich -comparisons and the :meth:`__cmp__` magic method). +It is common to encounter comparison functions when translating algorithms from +other languages. Also, some libraries provide comparison functions as part of +their API. For example, :func:`locale.strcoll` is a comparison function. -In Py2.x, sort allowed an optional function which can be called for doing the -comparisons. That function should take two arguments to be compared and then -return a negative value for less-than, return zero if they are equal, or return -a positive value for greater-than. For example, we can do: +To accommodate those situations, Python provides +:class:`functools.cmp_to_key` to wrap the comparison function +to make it usable as a key function:: -.. doctest:: + sorted(words, key=cmp_to_key(strcoll)) # locale-aware sort order - >>> def numeric_compare(x, y): - ... return x - y - >>> sorted([5, 2, 4, 1, 3], cmp=numeric_compare) # doctest: +SKIP - [1, 2, 3, 4, 5] - -Or you can reverse the order of comparison with: - -.. doctest:: - - >>> def reverse_numeric(x, y): - ... return y - x - >>> sorted([5, 2, 4, 1, 3], cmp=reverse_numeric) # doctest: +SKIP - [5, 4, 3, 2, 1] - -When porting code from Python 2.x to 3.x, the situation can arise when you have -the user supplying a comparison function and you need to convert that to a key -function. The following wrapper makes that easy to do: - -.. testcode:: - - def cmp_to_key(mycmp): - 'Convert a cmp= function into a key= function' - class K: - def __init__(self, obj, *args): - self.obj = obj - def __lt__(self, other): - return mycmp(self.obj, other.obj) < 0 - def __gt__(self, other): - return mycmp(self.obj, other.obj) > 0 - def __eq__(self, other): - return mycmp(self.obj, other.obj) == 0 - def __le__(self, other): - return mycmp(self.obj, other.obj) <= 0 - def __ge__(self, other): - return mycmp(self.obj, other.obj) >= 0 - def __ne__(self, other): - return mycmp(self.obj, other.obj) != 0 - return K - -.. doctest:: - :hide: - - >>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric)) - [5, 4, 3, 2, 1] - -To convert to a key function, just wrap the old comparison function: - -.. testsetup:: - - from functools import cmp_to_key - -.. doctest:: - - >>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric)) - [5, 4, 3, 2, 1] - -In Python 3.2, the :func:`functools.cmp_to_key` function was added to the -:mod:`functools` module in the standard library. - -Odd and Ends -============ +Odds and Ends +============= * For locale aware sorting, use :func:`locale.strxfrm` for a key function or - :func:`locale.strcoll` for a comparison function. + :func:`locale.strcoll` for a comparison function. This is necessary + because "alphabetical" sort orderings can vary across cultures even + if the underlying alphabet is the same. * The *reverse* parameter still maintains sort stability (so that records with equal keys retain the original order). Interestingly, that effect can be @@ -325,7 +271,7 @@ Odd and Ends >>> standard_way [('red', 1), ('red', 2), ('blue', 1), ('blue', 2)] -* The sort routines are guaranteed to use :meth:`__lt__` when making comparisons +* The sort routines use ``<`` when making comparisons between two objects. So, it is easy to add a standard sort order to a class by defining an :meth:`__lt__` method: @@ -335,6 +281,9 @@ Odd and Ends >>> sorted(student_objects) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] + However, note that ``<`` can fall back to using :meth:`__gt__` if + :meth:`__lt__` is not implemented (see :func:`object.__lt__`). + * Key functions need not depend directly on the objects being sorted. A key function can also access external resources. For instance, if the student grades are stored in a dictionary, they can be used to sort a separate list of student diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst index 535b21bd4a5..b0faa68d240 100644 --- a/Doc/howto/unicode.rst +++ b/Doc/howto/unicode.rst @@ -167,7 +167,7 @@ On the Computerphile Youtube channel, Tom Scott briefly (9 minutes 36 seconds). To help understand the standard, Jukka Korpela has written `an introductory -guide `_ to reading the +guide `_ to reading the Unicode character tables. Another `good introductory article `_ @@ -449,7 +449,7 @@ When run, this outputs: .. code-block:: shell-session - $ python3 compare-strs.py + $ python compare-strs.py length of first string= 1 length of second string= 2 True @@ -517,7 +517,7 @@ References Some good alternative discussions of Python's Unicode support are: -* `Processing Text Files in Python 3 `_, by Nick Coghlan. +* `Processing Text Files in Python 3 `_, by Nick Coghlan. * `Pragmatic Unicode `_, a PyCon 2012 presentation by Ned Batchelder. The :class:`str` type is described in the Python library reference at @@ -735,7 +735,7 @@ References ---------- One section of `Mastering Python 3 Input/Output -`_, +`_, a PyCon 2010 talk by David Beazley, discusses text processing and binary data handling. The `PDF slides for Marc-André Lemburg's presentation "Writing Unicode-aware @@ -745,7 +745,7 @@ discuss questions of character encodings as well as how to internationalize and localize an application. These slides cover Python 2.x only. `The Guts of Unicode in Python -`_ +`_ is a PyCon 2013 talk by Benjamin Peterson that discusses the internal Unicode representation in Python 3.3. diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst index 12d525771dd..69af3c3a85c 100644 --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -4,13 +4,13 @@ HOWTO Fetch Internet Resources Using The urllib Package *********************************************************** -:Author: `Michael Foord `_ +:Author: `Michael Foord `_ .. note:: There is a French translation of an earlier revision of this HOWTO, available at `urllib2 - Le Manuel manquant - `_. + `_. @@ -22,7 +22,7 @@ Introduction You may also find useful the following article on fetching web resources with Python: - * `Basic Authentication `_ + * `Basic Authentication `_ A tutorial on *Basic Authentication*, with examples in Python. @@ -411,7 +411,7 @@ fetched, particularly the headers sent by the server. It is currently an :class:`http.client.HTTPMessage` instance. Typical headers include 'Content-length', 'Content-type', and so on. See the -`Quick Reference to HTTP Headers `_ +`Quick Reference to HTTP Headers `_ for a useful listing of HTTP headers with brief explanations of their meaning and use. @@ -420,7 +420,7 @@ Openers and Handlers ==================== When you fetch a URL you use an opener (an instance of the perhaps -confusingly-named :class:`urllib.request.OpenerDirector`). Normally we have been using +confusingly named :class:`urllib.request.OpenerDirector`). Normally we have been using the default opener - via ``urlopen`` - but you can create custom openers. Openers use handlers. All the "heavy lifting" is done by the handlers. Each handler knows how to open URLs for a particular URL scheme (http, diff --git a/Doc/includes/custom.c b/Doc/includes/custom.c index f361baf830d..26ca7549647 100644 --- a/Doc/includes/custom.c +++ b/Doc/includes/custom.c @@ -9,7 +9,7 @@ typedef struct { static PyTypeObject CustomType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "custom.Custom", - .tp_doc = "Custom objects", + .tp_doc = PyDoc_STR("Custom objects"), .tp_basicsize = sizeof(CustomObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT, diff --git a/Doc/includes/custom2.c b/Doc/includes/custom2.c index 5bacab7a2a9..a3b2d6ab78d 100644 --- a/Doc/includes/custom2.c +++ b/Doc/includes/custom2.c @@ -1,6 +1,6 @@ #define PY_SSIZE_T_CLEAN #include -#include "structmember.h" +#include /* for offsetof() */ typedef struct { PyObject_HEAD @@ -42,7 +42,7 @@ static int Custom_init(CustomObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"first", "last", "number", NULL}; - PyObject *first = NULL, *last = NULL, *tmp; + PyObject *first = NULL, *last = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist, &first, &last, @@ -50,26 +50,20 @@ Custom_init(CustomObject *self, PyObject *args, PyObject *kwds) return -1; if (first) { - tmp = self->first; - Py_INCREF(first); - self->first = first; - Py_XDECREF(tmp); + Py_XSETREF(self->first, Py_NewRef(first)); } if (last) { - tmp = self->last; - Py_INCREF(last); - self->last = last; - Py_XDECREF(tmp); + Py_XSETREF(self->last, Py_NewRef(last)); } return 0; } static PyMemberDef Custom_members[] = { - {"first", T_OBJECT_EX, offsetof(CustomObject, first), 0, + {"first", Py_T_OBJECT_EX, offsetof(CustomObject, first), 0, "first name"}, - {"last", T_OBJECT_EX, offsetof(CustomObject, last), 0, + {"last", Py_T_OBJECT_EX, offsetof(CustomObject, last), 0, "last name"}, - {"number", T_INT, offsetof(CustomObject, number), 0, + {"number", Py_T_INT, offsetof(CustomObject, number), 0, "custom number"}, {NULL} /* Sentinel */ }; @@ -98,7 +92,7 @@ static PyMethodDef Custom_methods[] = { static PyTypeObject CustomType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "custom2.Custom", - .tp_doc = "Custom objects", + .tp_doc = PyDoc_STR("Custom objects"), .tp_basicsize = sizeof(CustomObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, @@ -127,9 +121,7 @@ PyInit_custom2(void) if (m == NULL) return NULL; - Py_INCREF(&CustomType); - if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) { - Py_DECREF(&CustomType); + if (PyModule_AddObjectRef(m, "Custom", (PyObject *) &CustomType) < 0) { Py_DECREF(m); return NULL; } diff --git a/Doc/includes/custom3.c b/Doc/includes/custom3.c index 2b7a99ecf96..1a68bc4be8c 100644 --- a/Doc/includes/custom3.c +++ b/Doc/includes/custom3.c @@ -1,6 +1,6 @@ #define PY_SSIZE_T_CLEAN #include -#include "structmember.h" +#include /* for offsetof() */ typedef struct { PyObject_HEAD @@ -42,7 +42,7 @@ static int Custom_init(CustomObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"first", "last", "number", NULL}; - PyObject *first = NULL, *last = NULL, *tmp; + PyObject *first = NULL, *last = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist, &first, &last, @@ -50,22 +50,16 @@ Custom_init(CustomObject *self, PyObject *args, PyObject *kwds) return -1; if (first) { - tmp = self->first; - Py_INCREF(first); - self->first = first; - Py_DECREF(tmp); + Py_SETREF(self->first, Py_NewRef(first)); } if (last) { - tmp = self->last; - Py_INCREF(last); - self->last = last; - Py_DECREF(tmp); + Py_SETREF(self->last, Py_NewRef(last)); } return 0; } static PyMemberDef Custom_members[] = { - {"number", T_INT, offsetof(CustomObject, number), 0, + {"number", Py_T_INT, offsetof(CustomObject, number), 0, "custom number"}, {NULL} /* Sentinel */ }; @@ -73,14 +67,12 @@ static PyMemberDef Custom_members[] = { static PyObject * Custom_getfirst(CustomObject *self, void *closure) { - Py_INCREF(self->first); - return self->first; + return Py_NewRef(self->first); } static int Custom_setfirst(CustomObject *self, PyObject *value, void *closure) { - PyObject *tmp; if (value == NULL) { PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute"); return -1; @@ -90,24 +82,19 @@ Custom_setfirst(CustomObject *self, PyObject *value, void *closure) "The first attribute value must be a string"); return -1; } - tmp = self->first; - Py_INCREF(value); - self->first = value; - Py_DECREF(tmp); + Py_SETREF(self->first, Py_NewRef(value)); return 0; } static PyObject * Custom_getlast(CustomObject *self, void *closure) { - Py_INCREF(self->last); - return self->last; + return Py_NewRef(self->last); } static int Custom_setlast(CustomObject *self, PyObject *value, void *closure) { - PyObject *tmp; if (value == NULL) { PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute"); return -1; @@ -117,10 +104,7 @@ Custom_setlast(CustomObject *self, PyObject *value, void *closure) "The last attribute value must be a string"); return -1; } - tmp = self->last; - Py_INCREF(value); - self->last = value; - Py_DECREF(tmp); + Py_SETREF(self->last, Py_NewRef(value)); return 0; } @@ -148,7 +132,7 @@ static PyMethodDef Custom_methods[] = { static PyTypeObject CustomType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "custom3.Custom", - .tp_doc = "Custom objects", + .tp_doc = PyDoc_STR("Custom objects"), .tp_basicsize = sizeof(CustomObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, @@ -178,9 +162,7 @@ PyInit_custom3(void) if (m == NULL) return NULL; - Py_INCREF(&CustomType); - if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) { - Py_DECREF(&CustomType); + if (PyModule_AddObjectRef(m, "Custom", (PyObject *) &CustomType) < 0) { Py_DECREF(m); return NULL; } diff --git a/Doc/includes/custom4.c b/Doc/includes/custom4.c index 584992fc5f1..b932d159d26 100644 --- a/Doc/includes/custom4.c +++ b/Doc/includes/custom4.c @@ -1,6 +1,6 @@ #define PY_SSIZE_T_CLEAN #include -#include "structmember.h" +#include /* for offsetof() */ typedef struct { PyObject_HEAD @@ -58,7 +58,7 @@ static int Custom_init(CustomObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"first", "last", "number", NULL}; - PyObject *first = NULL, *last = NULL, *tmp; + PyObject *first = NULL, *last = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist, &first, &last, @@ -66,22 +66,16 @@ Custom_init(CustomObject *self, PyObject *args, PyObject *kwds) return -1; if (first) { - tmp = self->first; - Py_INCREF(first); - self->first = first; - Py_DECREF(tmp); + Py_SETREF(self->first, Py_NewRef(first)); } if (last) { - tmp = self->last; - Py_INCREF(last); - self->last = last; - Py_DECREF(tmp); + Py_SETREF(self->last, Py_NewRef(last)); } return 0; } static PyMemberDef Custom_members[] = { - {"number", T_INT, offsetof(CustomObject, number), 0, + {"number", Py_T_INT, offsetof(CustomObject, number), 0, "custom number"}, {NULL} /* Sentinel */ }; @@ -89,8 +83,7 @@ static PyMemberDef Custom_members[] = { static PyObject * Custom_getfirst(CustomObject *self, void *closure) { - Py_INCREF(self->first); - return self->first; + return Py_NewRef(self->first); } static int @@ -105,17 +98,14 @@ Custom_setfirst(CustomObject *self, PyObject *value, void *closure) "The first attribute value must be a string"); return -1; } - Py_INCREF(value); - Py_CLEAR(self->first); - self->first = value; + Py_XSETREF(self->first, Py_NewRef(value)); return 0; } static PyObject * Custom_getlast(CustomObject *self, void *closure) { - Py_INCREF(self->last); - return self->last; + return Py_NewRef(self->last); } static int @@ -130,9 +120,7 @@ Custom_setlast(CustomObject *self, PyObject *value, void *closure) "The last attribute value must be a string"); return -1; } - Py_INCREF(value); - Py_CLEAR(self->last); - self->last = value; + Py_XSETREF(self->last, Py_NewRef(value)); return 0; } @@ -160,7 +148,7 @@ static PyMethodDef Custom_methods[] = { static PyTypeObject CustomType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "custom4.Custom", - .tp_doc = "Custom objects", + .tp_doc = PyDoc_STR("Custom objects"), .tp_basicsize = sizeof(CustomObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, @@ -192,9 +180,7 @@ PyInit_custom4(void) if (m == NULL) return NULL; - Py_INCREF(&CustomType); - if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) { - Py_DECREF(&CustomType); + if (PyModule_AddObjectRef(m, "Custom", (PyObject *) &CustomType) < 0) { Py_DECREF(m); return NULL; } diff --git a/Tools/scripts/diff.py b/Doc/includes/diff.py old mode 100755 new mode 100644 similarity index 98% rename from Tools/scripts/diff.py rename to Doc/includes/diff.py index 96199b85116..001619f5f83 --- a/Tools/scripts/diff.py +++ b/Doc/includes/diff.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 """ Command line interface to difflib.py providing diffs in four formats: * ndiff: lists every line and highlights interline changes. diff --git a/Doc/includes/email-headers.py b/Doc/includes/email-headers.py index 2c421451a8e..5def0c90d28 100644 --- a/Doc/includes/email-headers.py +++ b/Doc/includes/email-headers.py @@ -1,5 +1,6 @@ # Import the email modules we'll need -from email.parser import BytesParser, Parser +#from email.parser import BytesParser +from email.parser import Parser from email.policy import default # If the e-mail headers are in a file, uncomment these two lines: diff --git a/Doc/includes/email-mime.py b/Doc/includes/email-mime.py index 6af2be0b08a..34c6bdb60ff 100644 --- a/Doc/includes/email-mime.py +++ b/Doc/includes/email-mime.py @@ -1,10 +1,7 @@ -# Import smtplib for the actual sending function +# Import smtplib for the actual sending function. import smtplib -# And imghdr to find the types of our images -import imghdr - -# Here are the email package modules we'll need +# Here are the email package modules we'll need. from email.message import EmailMessage # Create the container email message. @@ -16,13 +13,13 @@ msg['From'] = me msg['To'] = ', '.join(family) msg.preamble = 'You will not see this in a MIME-aware mail reader.\n' -# Open the files in binary mode. Use imghdr to figure out the -# MIME subtype for each specific image. +# Open the files in binary mode. You can also omit the subtype +# if you want MIMEImage to guess it. for file in pngfiles: with open(file, 'rb') as fp: img_data = fp.read() msg.add_attachment(img_data, maintype='image', - subtype=imghdr.what(None, img_data)) + subtype='png') # Send the email via our own SMTP server. with smtplib.SMTP('localhost') as s: diff --git a/Doc/includes/email-read-alternative.py b/Doc/includes/email-read-alternative.py index 5ea84e62584..8d0b4e6eb6b 100644 --- a/Doc/includes/email-read-alternative.py +++ b/Doc/includes/email-read-alternative.py @@ -8,8 +8,15 @@ import webbrowser from email import policy from email.parser import BytesParser -# An imaginary module that would make this work and be safe. -from imaginary import magic_html_parser + +def magic_html_parser(html_text, partfiles): + """Return safety-sanitized html linked to partfiles. + + Rewrite the href="cid:...." attributes to point to the filenames in partfiles. + Though not trivial, this should be possible using html.parser. + """ + raise NotImplementedError("Add the magic needed") + # In a real program you'd get the filename from the arguments. with open('outgoing.msg', 'rb') as fp: @@ -62,9 +69,6 @@ else: print("Don't know how to display {}".format(richest.get_content_type())) sys.exit() with tempfile.NamedTemporaryFile(mode='w', delete=False) as f: - # The magic_html_parser has to rewrite the href="cid:...." attributes to - # point to the filenames in partfiles. It also has to do a safety-sanitize - # of the html. It could be written using html.parser. f.write(magic_html_parser(body.get_content(), partfiles)) webbrowser.open(f.name) os.remove(f.name) diff --git a/Doc/includes/minidom-example.py b/Doc/includes/minidom-example.py index 5ee7682c192..3b9e9ee2db2 100644 --- a/Doc/includes/minidom-example.py +++ b/Doc/includes/minidom-example.py @@ -42,10 +42,10 @@ def handleSlide(slide): handlePoints(slide.getElementsByTagName("point")) def handleSlideshowTitle(title): - print("%s" % getText(title.childNodes)) + print(f"{getText(title.childNodes)}") def handleSlideTitle(title): - print("

%s

" % getText(title.childNodes)) + print(f"

{getText(title.childNodes)}

") def handlePoints(points): print("
    ") @@ -54,11 +54,11 @@ def handlePoints(points): print("
") def handlePoint(point): - print("
  • %s
  • " % getText(point.childNodes)) + print(f"
  • {getText(point.childNodes)}
  • ") def handleToc(slides): for slide in slides: title = slide.getElementsByTagName("title")[0] - print("

    %s

    " % getText(title.childNodes)) + print(f"

    {getText(title.childNodes)}

    ") handleSlideshow(dom) diff --git a/Tools/scripts/ndiff.py b/Doc/includes/ndiff.py old mode 100755 new mode 100644 similarity index 80% rename from Tools/scripts/ndiff.py rename to Doc/includes/ndiff.py index c6d09b8f242..32c251bce91 --- a/Tools/scripts/ndiff.py +++ b/Doc/includes/ndiff.py @@ -1,16 +1,3 @@ -#! /usr/bin/env python3 - -# Module ndiff version 1.7.0 -# Released to the public domain 08-Dec-2000, -# by Tim Peters (tim.one@home.com). - -# Provided as-is; use at your own risk; no warranty; no promises; enjoy! - -# ndiff.py is now simply a front-end to the difflib.ndiff() function. -# Originally, it contained the difflib.SequenceMatcher class as well. -# This completes the raiding of reusable code from this formerly -# self-contained script. - """ndiff [-q] file1 file2 or ndiff (-r1 | -r2) < ndiff_output > file1_or_file2 @@ -121,13 +108,4 @@ def restore(which): sys.stdout.writelines(restored) if __name__ == '__main__': - args = sys.argv[1:] - if "-profile" in args: - import profile, pstats - args.remove("-profile") - statf = "ndiff.pro" - profile.run("main(args)", statf) - stats = pstats.Stats(statf) - stats.strip_dirs().sort_stats('time').print_stats() - else: - main(args) + main(sys.argv[1:]) diff --git a/Doc/includes/sqlite3/adapter_datetime.py b/Doc/includes/sqlite3/adapter_datetime.py deleted file mode 100644 index d5221d80c35..00000000000 --- a/Doc/includes/sqlite3/adapter_datetime.py +++ /dev/null @@ -1,17 +0,0 @@ -import sqlite3 -import datetime -import time - -def adapt_datetime(ts): - return time.mktime(ts.timetuple()) - -sqlite3.register_adapter(datetime.datetime, adapt_datetime) - -con = sqlite3.connect(":memory:") -cur = con.cursor() - -now = datetime.datetime.now() -cur.execute("select ?", (now,)) -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/adapter_point_1.py b/Doc/includes/sqlite3/adapter_point_1.py deleted file mode 100644 index 77daf8f16d2..00000000000 --- a/Doc/includes/sqlite3/adapter_point_1.py +++ /dev/null @@ -1,18 +0,0 @@ -import sqlite3 - -class Point: - def __init__(self, x, y): - self.x, self.y = x, y - - def __conform__(self, protocol): - if protocol is sqlite3.PrepareProtocol: - return "%f;%f" % (self.x, self.y) - -con = sqlite3.connect(":memory:") -cur = con.cursor() - -p = Point(4.0, -3.2) -cur.execute("select ?", (p,)) -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/adapter_point_2.py b/Doc/includes/sqlite3/adapter_point_2.py deleted file mode 100644 index cb86331692b..00000000000 --- a/Doc/includes/sqlite3/adapter_point_2.py +++ /dev/null @@ -1,19 +0,0 @@ -import sqlite3 - -class Point: - def __init__(self, x, y): - self.x, self.y = x, y - -def adapt_point(point): - return "%f;%f" % (point.x, point.y) - -sqlite3.register_adapter(Point, adapt_point) - -con = sqlite3.connect(":memory:") -cur = con.cursor() - -p = Point(4.0, -3.2) -cur.execute("select ?", (p,)) -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/collation_reverse.py b/Doc/includes/sqlite3/collation_reverse.py deleted file mode 100644 index 3504a350a04..00000000000 --- a/Doc/includes/sqlite3/collation_reverse.py +++ /dev/null @@ -1,20 +0,0 @@ -import sqlite3 - -def collate_reverse(string1, string2): - if string1 == string2: - return 0 - elif string1 < string2: - return 1 - else: - return -1 - -con = sqlite3.connect(":memory:") -con.create_collation("reverse", collate_reverse) - -cur = con.cursor() -cur.execute("create table test(x)") -cur.executemany("insert into test(x) values (?)", [("a",), ("b",)]) -cur.execute("select x from test order by x collate reverse") -for row in cur: - print(row) -con.close() diff --git a/Doc/includes/sqlite3/complete_statement.py b/Doc/includes/sqlite3/complete_statement.py deleted file mode 100644 index a5c94796991..00000000000 --- a/Doc/includes/sqlite3/complete_statement.py +++ /dev/null @@ -1,33 +0,0 @@ -# A minimal SQLite shell for experiments - -import sqlite3 - -con = sqlite3.connect(":memory:") -con.isolation_level = None -cur = con.cursor() - -buffer = "" - -print("Enter your SQL commands to execute in sqlite3.") -print("Enter a blank line to exit.") - -while True: - line = input() - if line == "": - break - buffer += line - if sqlite3.complete_statement(buffer): - try: - buffer = buffer.strip() - cur.execute(buffer) - - if buffer.lstrip().upper().startswith("SELECT"): - print(cur.fetchall()) - except sqlite3.Error as e: - err_msg = str(e) - err_code = e.sqlite_errorcode - err_name = e.sqlite_errorname - print(f"{err_name} ({err_code}): {err_msg}") - buffer = "" - -con.close() diff --git a/Doc/includes/sqlite3/converter_point.py b/Doc/includes/sqlite3/converter_point.py deleted file mode 100644 index 5df828e3361..00000000000 --- a/Doc/includes/sqlite3/converter_point.py +++ /dev/null @@ -1,47 +0,0 @@ -import sqlite3 - -class Point: - def __init__(self, x, y): - self.x, self.y = x, y - - def __repr__(self): - return "(%f;%f)" % (self.x, self.y) - -def adapt_point(point): - return ("%f;%f" % (point.x, point.y)).encode('ascii') - -def convert_point(s): - x, y = list(map(float, s.split(b";"))) - return Point(x, y) - -# Register the adapter -sqlite3.register_adapter(Point, adapt_point) - -# Register the converter -sqlite3.register_converter("point", convert_point) - -p = Point(4.0, -3.2) - -######################### -# 1) Using declared types -con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES) -cur = con.cursor() -cur.execute("create table test(p point)") - -cur.execute("insert into test(p) values (?)", (p,)) -cur.execute("select p from test") -print("with declared types:", cur.fetchone()[0]) -cur.close() -con.close() - -####################### -# 1) Using column names -con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES) -cur = con.cursor() -cur.execute("create table test(p)") - -cur.execute("insert into test(p) values (?)", (p,)) -cur.execute('select p as "p [point]" from test') -print("with column names:", cur.fetchone()[0]) -cur.close() -con.close() diff --git a/Doc/includes/sqlite3/ctx_manager.py b/Doc/includes/sqlite3/ctx_manager.py deleted file mode 100644 index 2e1175ef44c..00000000000 --- a/Doc/includes/sqlite3/ctx_manager.py +++ /dev/null @@ -1,20 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -con.execute("create table lang (id integer primary key, name varchar unique)") - -# Successful, con.commit() is called automatically afterwards -with con: - con.execute("insert into lang(name) values (?)", ("Python",)) - -# con.rollback() is called after the with block finishes with an exception, the -# exception is still raised and must be caught -try: - with con: - con.execute("insert into lang(name) values (?)", ("Python",)) -except sqlite3.IntegrityError: - print("couldn't add Python twice") - -# Connection object used as context manager only commits or rollbacks transactions, -# so the connection object should be closed manually -con.close() diff --git a/Doc/includes/sqlite3/execute_1.py b/Doc/includes/sqlite3/execute_1.py deleted file mode 100644 index ee0000e2b94..00000000000 --- a/Doc/includes/sqlite3/execute_1.py +++ /dev/null @@ -1,22 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -cur = con.cursor() -cur.execute("create table lang (name, first_appeared)") - -# This is the qmark style: -cur.execute("insert into lang values (?, ?)", ("C", 1972)) - -# The qmark style used with executemany(): -lang_list = [ - ("Fortran", 1957), - ("Python", 1991), - ("Go", 2009), -] -cur.executemany("insert into lang values (?, ?)", lang_list) - -# And this is the named style: -cur.execute("select * from lang where first_appeared=:year", {"year": 1972}) -print(cur.fetchall()) - -con.close() diff --git a/Doc/includes/sqlite3/executemany_1.py b/Doc/includes/sqlite3/executemany_1.py deleted file mode 100644 index edf6f8b7ebe..00000000000 --- a/Doc/includes/sqlite3/executemany_1.py +++ /dev/null @@ -1,26 +0,0 @@ -import sqlite3 - -class IterChars: - def __init__(self): - self.count = ord('a') - - def __iter__(self): - return self - - def __next__(self): - if self.count > ord('z'): - raise StopIteration - self.count += 1 - return (chr(self.count - 1),) # this is a 1-tuple - -con = sqlite3.connect(":memory:") -cur = con.cursor() -cur.execute("create table characters(c)") - -theIter = IterChars() -cur.executemany("insert into characters(c) values (?)", theIter) - -cur.execute("select c from characters") -print(cur.fetchall()) - -con.close() diff --git a/Doc/includes/sqlite3/executemany_2.py b/Doc/includes/sqlite3/executemany_2.py deleted file mode 100644 index 02a594c861e..00000000000 --- a/Doc/includes/sqlite3/executemany_2.py +++ /dev/null @@ -1,17 +0,0 @@ -import sqlite3 -import string - -def char_generator(): - for c in string.ascii_lowercase: - yield (c,) - -con = sqlite3.connect(":memory:") -cur = con.cursor() -cur.execute("create table characters(c)") - -cur.executemany("insert into characters(c) values (?)", char_generator()) - -cur.execute("select c from characters") -print(cur.fetchall()) - -con.close() diff --git a/Doc/includes/sqlite3/executescript.py b/Doc/includes/sqlite3/executescript.py deleted file mode 100644 index aea8943fbee..00000000000 --- a/Doc/includes/sqlite3/executescript.py +++ /dev/null @@ -1,25 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -cur = con.cursor() -cur.executescript(""" - create table person( - firstname, - lastname, - age - ); - - create table book( - title, - author, - published - ); - - insert into book(title, author, published) - values ( - 'Dirk Gently''s Holistic Detective Agency', - 'Douglas Adams', - 1987 - ); - """) -con.close() diff --git a/Doc/includes/sqlite3/load_extension.py b/Doc/includes/sqlite3/load_extension.py deleted file mode 100644 index 624cfe262f3..00000000000 --- a/Doc/includes/sqlite3/load_extension.py +++ /dev/null @@ -1,28 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") - -# enable extension loading -con.enable_load_extension(True) - -# Load the fulltext search extension -con.execute("select load_extension('./fts3.so')") - -# alternatively you can load the extension using an API call: -# con.load_extension("./fts3.so") - -# disable extension loading again -con.enable_load_extension(False) - -# example from SQLite wiki -con.execute("create virtual table recipe using fts3(name, ingredients)") -con.executescript(""" - insert into recipe (name, ingredients) values ('broccoli stew', 'broccoli peppers cheese tomatoes'); - insert into recipe (name, ingredients) values ('pumpkin stew', 'pumpkin onions garlic celery'); - insert into recipe (name, ingredients) values ('broccoli pie', 'broccoli cheese onions flour'); - insert into recipe (name, ingredients) values ('pumpkin pie', 'pumpkin sugar flour butter'); - """) -for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"): - print(row) - -con.close() diff --git a/Doc/includes/sqlite3/md5func.py b/Doc/includes/sqlite3/md5func.py deleted file mode 100644 index 16dc348bf00..00000000000 --- a/Doc/includes/sqlite3/md5func.py +++ /dev/null @@ -1,13 +0,0 @@ -import sqlite3 -import hashlib - -def md5sum(t): - return hashlib.md5(t).hexdigest() - -con = sqlite3.connect(":memory:") -con.create_function("md5", 1, md5sum) -cur = con.cursor() -cur.execute("select md5(?)", (b"foo",)) -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/mysumaggr.py b/Doc/includes/sqlite3/mysumaggr.py deleted file mode 100644 index 11f96395b6c..00000000000 --- a/Doc/includes/sqlite3/mysumaggr.py +++ /dev/null @@ -1,22 +0,0 @@ -import sqlite3 - -class MySum: - def __init__(self): - self.count = 0 - - def step(self, value): - self.count += value - - def finalize(self): - return self.count - -con = sqlite3.connect(":memory:") -con.create_aggregate("mysum", 1, MySum) -cur = con.cursor() -cur.execute("create table test(i)") -cur.execute("insert into test(i) values (1)") -cur.execute("insert into test(i) values (2)") -cur.execute("select mysum(i) from test") -print(cur.fetchone()[0]) - -con.close() diff --git a/Doc/includes/sqlite3/pysqlite_datetime.py b/Doc/includes/sqlite3/pysqlite_datetime.py deleted file mode 100644 index 5d843f906b3..00000000000 --- a/Doc/includes/sqlite3/pysqlite_datetime.py +++ /dev/null @@ -1,22 +0,0 @@ -import sqlite3 -import datetime - -con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES) -cur = con.cursor() -cur.execute("create table test(d date, ts timestamp)") - -today = datetime.date.today() -now = datetime.datetime.now() - -cur.execute("insert into test(d, ts) values (?, ?)", (today, now)) -cur.execute("select d, ts from test") -row = cur.fetchone() -print(today, "=>", row[0], type(row[0])) -print(now, "=>", row[1], type(row[1])) - -cur.execute('select current_date as "d [date]", current_timestamp as "ts [timestamp]"') -row = cur.fetchone() -print("current_date", row[0], type(row[0])) -print("current_timestamp", row[1], type(row[1])) - -con.close() diff --git a/Doc/includes/sqlite3/row_factory.py b/Doc/includes/sqlite3/row_factory.py deleted file mode 100644 index 9de6e7b1b90..00000000000 --- a/Doc/includes/sqlite3/row_factory.py +++ /dev/null @@ -1,15 +0,0 @@ -import sqlite3 - -def dict_factory(cursor, row): - d = {} - for idx, col in enumerate(cursor.description): - d[col[0]] = row[idx] - return d - -con = sqlite3.connect(":memory:") -con.row_factory = dict_factory -cur = con.cursor() -cur.execute("select 1 as a") -print(cur.fetchone()["a"]) - -con.close() diff --git a/Doc/includes/sqlite3/rowclass.py b/Doc/includes/sqlite3/rowclass.py deleted file mode 100644 index fc60287069a..00000000000 --- a/Doc/includes/sqlite3/rowclass.py +++ /dev/null @@ -1,14 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -con.row_factory = sqlite3.Row - -cur = con.cursor() -cur.execute("select 'John' as name, 42 as age") -for row in cur: - assert row[0] == row["name"] - assert row["name"] == row["nAmE"] - assert row[1] == row["age"] - assert row[1] == row["AgE"] - -con.close() diff --git a/Doc/includes/sqlite3/shortcut_methods.py b/Doc/includes/sqlite3/shortcut_methods.py deleted file mode 100644 index 48ea6fad15a..00000000000 --- a/Doc/includes/sqlite3/shortcut_methods.py +++ /dev/null @@ -1,24 +0,0 @@ -import sqlite3 - -langs = [ - ("C++", 1985), - ("Objective-C", 1984), -] - -con = sqlite3.connect(":memory:") - -# Create the table -con.execute("create table lang(name, first_appeared)") - -# Fill the table -con.executemany("insert into lang(name, first_appeared) values (?, ?)", langs) - -# Print the table contents -for row in con.execute("select name, first_appeared from lang"): - print(row) - -print("I just deleted", con.execute("delete from lang").rowcount, "rows") - -# close is not a shortcut method and it's not called automatically, -# so the connection object should be closed manually -con.close() diff --git a/Doc/includes/sqlite3/text_factory.py b/Doc/includes/sqlite3/text_factory.py deleted file mode 100644 index c0d87cd5591..00000000000 --- a/Doc/includes/sqlite3/text_factory.py +++ /dev/null @@ -1,29 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -cur = con.cursor() - -AUSTRIA = "Österreich" - -# by default, rows are returned as str -cur.execute("select ?", (AUSTRIA,)) -row = cur.fetchone() -assert row[0] == AUSTRIA - -# but we can make sqlite3 always return bytestrings ... -con.text_factory = bytes -cur.execute("select ?", (AUSTRIA,)) -row = cur.fetchone() -assert type(row[0]) is bytes -# the bytestrings will be encoded in UTF-8, unless you stored garbage in the -# database ... -assert row[0] == AUSTRIA.encode("utf-8") - -# we can also implement a custom text_factory ... -# here we implement one that appends "foo" to all strings -con.text_factory = lambda x: x.decode("utf-8") + "foo" -cur.execute("select ?", ("bar",)) -row = cur.fetchone() -assert row[0] == "barfoo" - -con.close() diff --git a/Doc/includes/sublist.c b/Doc/includes/sublist.c index b2c26e73eba..b36dadf07ea 100644 --- a/Doc/includes/sublist.c +++ b/Doc/includes/sublist.c @@ -31,7 +31,7 @@ SubList_init(SubListObject *self, PyObject *args, PyObject *kwds) static PyTypeObject SubListType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "sublist.SubList", - .tp_doc = "SubList objects", + .tp_doc = PyDoc_STR("SubList objects"), .tp_basicsize = sizeof(SubListObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, diff --git a/Doc/includes/typestruct.h b/Doc/includes/typestruct.h index 02f8ccfe443..f0ad1e47cb0 100644 --- a/Doc/includes/typestruct.h +++ b/Doc/includes/typestruct.h @@ -80,4 +80,7 @@ typedef struct _typeobject { destructor tp_finalize; vectorcallfunc tp_vectorcall; + + /* bitset of which type-watchers care about this type */ + char tp_watched; } PyTypeObject; diff --git a/Doc/includes/tzinfo_examples.py b/Doc/includes/tzinfo_examples.py index 9b9e32a553e..1fa6e615e46 100644 --- a/Doc/includes/tzinfo_examples.py +++ b/Doc/includes/tzinfo_examples.py @@ -71,7 +71,7 @@ def first_sunday_on_or_after(dt): # DST start and end times. For a complete and up-to-date set of DST rules # and timezone definitions, visit the Olson Database (or try pytz): # http://www.twinsun.com/tz/tz-link.htm -# http://sourceforge.net/projects/pytz/ (might not be up-to-date) +# https://sourceforge.net/projects/pytz/ (might not be up-to-date) # # In the US, since 2007, DST starts at 2am (standard time) on the second # Sunday in March, which is the first Sunday on or after Mar 8. diff --git a/Doc/includes/wasm-notavail.rst b/Doc/includes/wasm-notavail.rst new file mode 100644 index 00000000000..e680e1f9b43 --- /dev/null +++ b/Doc/includes/wasm-notavail.rst @@ -0,0 +1,7 @@ +.. include for modules that don't work on WASM + +.. availability:: not Emscripten, not WASI. + + This module does not work or is not available on WebAssembly platforms + ``wasm32-emscripten`` and ``wasm32-wasi``. See + :ref:`wasm-availability` for more information. diff --git a/Doc/install/index.rst b/Doc/install/index.rst index 7f7be117009..ab581d785ef 100644 --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -23,7 +23,11 @@ The up to date module installation documentation. For regular Python usage, you almost certainly want that document rather than this one. -.. include:: ../distutils/_setuptools_disclaimer.rst +.. note:: + + This document is being retained solely until the ``setuptools`` documentation + at https://setuptools.readthedocs.io/en/latest/setuptools.html + independently covers all of the relevant information currently included here. .. note:: @@ -65,7 +69,7 @@ If you download a module source distribution, you can tell pretty quickly if it was packaged and distributed in the standard way, i.e. using the Distutils. First, the distribution's name and version number will be featured prominently in the name of the downloaded archive, e.g. :file:`foo-1.0.tar.gz` or -:file:`widget-0.9.7.zip`. Next, the archive will unpack into a similarly-named +:file:`widget-0.9.7.zip`. Next, the archive will unpack into a similarly named directory: :file:`foo-1.0` or :file:`widget-0.9.7`. Additionally, the distribution will contain a setup script :file:`setup.py`, and a file named :file:`README.txt` or possibly just :file:`README`, which should explain that @@ -761,7 +765,7 @@ And on Windows, the configuration files are: +--------------+-------------------------------------------------+-------+ On all platforms, the "personal" file can be temporarily disabled by -passing the `--no-user-cfg` option. +passing the ``--no-user-cfg`` option. Notes: @@ -1062,7 +1066,7 @@ normal libraries do. .. seealso:: - `Building Python modules on MS Windows platform with MinGW `_ + `Building Python modules on MS Windows platform with MinGW `_ Information about building the required libraries for the MinGW environment. diff --git a/Doc/installing/index.rst b/Doc/installing/index.rst index 4bacc7ba0c2..e158bf1c4c0 100644 --- a/Doc/installing/index.rst +++ b/Doc/installing/index.rst @@ -214,7 +214,7 @@ It is possible that ``pip`` does not get installed by default. One potential fix python -m ensurepip --default-pip There are also additional resources for `installing pip. -`__ +`__ Installing binary extensions diff --git a/Doc/library/2to3.rst b/Doc/library/2to3.rst index 9a1644a97c0..d85ad94e9b7 100644 --- a/Doc/library/2to3.rst +++ b/Doc/library/2to3.rst @@ -1,7 +1,7 @@ .. _2to3-reference: -2to3 - Automated Python 2 to 3 code translation -=============================================== +2to3 --- Automated Python 2 to 3 code translation +================================================= .. sectionauthor:: Benjamin Peterson @@ -338,7 +338,8 @@ and off individually. They are described here in more detail. .. 2to3fixer:: nonzero - Renames :meth:`__nonzero__` to :meth:`~object.__bool__`. + Renames definitions of methods called :meth:`__nonzero__` + to :meth:`~object.__bool__`. .. 2to3fixer:: numliterals @@ -455,8 +456,8 @@ and off individually. They are described here in more detail. ``from future_builtins import zip`` appears. -:mod:`lib2to3` - 2to3's library -------------------------------- +:mod:`lib2to3` --- 2to3's library +--------------------------------- .. module:: lib2to3 :synopsis: The 2to3 library diff --git a/Doc/library/__future__.rst b/Doc/library/__future__.rst index 24bbd90d02c..8bd23daee73 100644 --- a/Doc/library/__future__.rst +++ b/Doc/library/__future__.rst @@ -90,12 +90,20 @@ language using this mechanism: | generator_stop | 3.5.0b1 | 3.7 | :pep:`479`: | | | | | *StopIteration handling inside generators* | +------------------+-------------+--------------+---------------------------------------------+ -| annotations | 3.7.0b1 | 3.11 | :pep:`563`: | +| annotations | 3.7.0b1 | TBD [1]_ | :pep:`563`: | | | | | *Postponed evaluation of annotations* | +------------------+-------------+--------------+---------------------------------------------+ .. XXX Adding a new entry? Remember to update simple_stmts.rst, too. +.. [1] + ``from __future__ import annotations`` was previously scheduled to + become mandatory in Python 3.10, but the Python Steering Council + twice decided to delay the change + (`announcement for Python 3.10 `__; + `announcement for Python 3.11 `__). + No final decision has been made yet. See also :pep:`563` and :pep:`649`. + .. seealso:: diff --git a/Doc/library/__main__.rst b/Doc/library/__main__.rst index c5f36a7fcf0..6a2a7a7317f 100644 --- a/Doc/library/__main__.rst +++ b/Doc/library/__main__.rst @@ -61,7 +61,7 @@ The top-level code environment can be: .. code-block:: shell-session - $ python3 helloworld.py + $ python helloworld.py Hello, world! * the Python module or package passed to the Python interpreter with the @@ -69,14 +69,14 @@ The top-level code environment can be: .. code-block:: shell-session - $ python3 -m tarfile + $ python -m tarfile usage: tarfile.py [-h] [-v] (...) * Python code read by the Python interpreter from standard input: .. code-block:: shell-session - $ echo "import this" | python3 + $ echo "import this" | python The Zen of Python, by Tim Peters Beautiful is better than ugly. @@ -87,7 +87,7 @@ The top-level code environment can be: .. code-block:: shell-session - $ python3 -c "import this" + $ python -c "import this" The Zen of Python, by Tim Peters Beautiful is better than ugly. @@ -178,7 +178,7 @@ that your function will return some value acceptable as an input to returned if your function does not have a return statement). By proactively following this convention ourselves, our module will have the -same behavior when run directly (i.e. ``python3 echo.py``) as it will have if +same behavior when run directly (i.e. ``python echo.py``) as it will have if we later package it as a console script entry-point in a pip-installable package. @@ -215,7 +215,7 @@ directly from the command line using the :option:`-m` flag. For example: .. code-block:: shell-session - $ python3 -m bandclass + $ python -m bandclass This command will cause ``__main__.py`` to run. How you utilize this mechanism will depend on the nature of the package you are writing, but in this @@ -253,7 +253,7 @@ attribute will include the package's path if imported:: This won't work for ``__main__.py`` files in the root directory of a .zip file though. Hence, for consistency, minimal ``__main__.py`` like the :mod:`venv` -one mentioned above are preferred. +one mentioned below are preferred. .. seealso:: @@ -320,7 +320,7 @@ Now, if we started our program, the result would look like this: .. code-block:: shell-session - $ python3 start.py + $ python start.py Define the variable `my_name`! The exit code of the program would be 1, indicating an error. Uncommenting the @@ -329,7 +329,7 @@ status code 0, indicating success: .. code-block:: shell-session - $ python3 start.py + $ python start.py Dinsdale found in file /path/to/start.py Note that importing ``__main__`` doesn't cause any issues with unintentionally diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index 1e6452b7b82..122692a4285 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -57,6 +57,8 @@ This module defines the following constants and functions: When the function raises a :exc:`SystemExit` exception, it is silently ignored. + .. audit-event:: _thread.start_new_thread function,args,kwargs start_new_thread + .. versionchanged:: 3.8 :func:`sys.unraisablehook` is now used to handle unhandled exceptions. @@ -118,7 +120,7 @@ This module defines the following constants and functions: Its value may be used to uniquely identify this particular thread system-wide (until the thread terminates, after which the value may be recycled by the OS). - .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX. + .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD. .. versionadded:: 3.8 @@ -140,7 +142,9 @@ This module defines the following constants and functions: information (4 KiB pages are common; using multiples of 4096 for the stack size is the suggested approach in the absence of more specific information). - .. availability:: Windows, systems with POSIX threads. + .. availability:: Windows, pthreads. + + Unix platforms with POSIX threads support. .. data:: TIMEOUT_MAX @@ -155,21 +159,21 @@ This module defines the following constants and functions: Lock objects have the following methods: -.. method:: lock.acquire(waitflag=1, timeout=-1) +.. method:: lock.acquire(blocking=True, timeout=-1) Without any optional argument, this method acquires the lock unconditionally, if necessary waiting until it is released by another thread (only one thread at a time can acquire a lock --- that's their reason for existence). - If the integer *waitflag* argument is present, the action depends on its - value: if it is zero, the lock is only acquired if it can be acquired - immediately without waiting, while if it is nonzero, the lock is acquired + If the *blocking* argument is present, the action depends on its + value: if it is False, the lock is only acquired if it can be acquired + immediately without waiting, while if it is True, the lock is acquired unconditionally as above. If the floating-point *timeout* argument is present and positive, it specifies the maximum wait time in seconds before returning. A negative *timeout* argument specifies an unbounded wait. You cannot specify - a *timeout* if *waitflag* is zero. + a *timeout* if *blocking* is False. The return value is ``True`` if the lock is acquired successfully, ``False`` if not. diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst index 1a6ed474ff2..3b74622e7ff 100644 --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -186,15 +186,15 @@ The :mod:`abc` module also provides the following decorator: class C(ABC): @abstractmethod - def my_abstract_method(self, ...): + def my_abstract_method(self, arg1): ... @classmethod @abstractmethod - def my_abstract_classmethod(cls, ...): + def my_abstract_classmethod(cls, arg2): ... @staticmethod @abstractmethod - def my_abstract_staticmethod(...): + def my_abstract_staticmethod(arg3): ... @property @@ -255,7 +255,7 @@ The :mod:`abc` module also supports the following legacy decorators: class C(ABC): @classmethod @abstractmethod - def my_abstract_classmethod(cls, ...): + def my_abstract_classmethod(cls, arg): ... @@ -276,7 +276,7 @@ The :mod:`abc` module also supports the following legacy decorators: class C(ABC): @staticmethod @abstractmethod - def my_abstract_staticmethod(...): + def my_abstract_staticmethod(arg): ... diff --git a/Doc/library/aifc.rst b/Doc/library/aifc.rst index 2e917cf7321..9f20a30193f 100644 --- a/Doc/library/aifc.rst +++ b/Doc/library/aifc.rst @@ -3,6 +3,7 @@ .. module:: aifc :synopsis: Read and write audio files in AIFF or AIFC format. + :deprecated: **Source code:** :source:`Lib/aifc.py` @@ -11,6 +12,11 @@ single: AIFF single: AIFF-C + +.. deprecated-removed:: 3.11 3.13 + The :mod:`aifc` module is deprecated + (see :pep:`PEP 594 <594#aifc>` for details). + -------------- This module provides support for reading and writing AIFF and AIFF-C files. diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 2edf84e5f04..475cac70291 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -22,8 +22,55 @@ The :mod:`argparse` module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and :mod:`argparse` will figure out how to parse those out of :data:`sys.argv`. The :mod:`argparse` -module also automatically generates help and usage messages and issues errors -when users give the program invalid arguments. +module also automatically generates help and usage messages. The module +will also issue errors when users give the program invalid arguments. + + +Core Functionality +------------------ + +The :mod:`argparse` module's support for command-line interfaces is built +around an instance of :class:`argparse.ArgumentParser`. It is a container for +argument specifications and has options that apply the parser as whole:: + + parser = argparse.ArgumentParser( + prog = 'ProgramName', + description = 'What the program does', + epilog = 'Text at the bottom of help') + +The :meth:`ArgumentParser.add_argument` method attaches individual argument +specifications to the parser. It supports positional arguments, options that +accept values, and on/off flags:: + + parser.add_argument('filename') # positional argument + parser.add_argument('-c', '--count') # option that takes a value + parser.add_argument('-v', '--verbose', + action='store_true') # on/off flag + +The :meth:`ArgumentParser.parse_args` method runs the parser and places +the extracted data in a :class:`argparse.Namespace` object:: + + args = parser.parse_args() + print(args.filename, args.count, args.verbose) + + +Quick Links for add_argument() +------------------------------ + +====================== =========================================================== ========================================================================================================================== +Name Description Values +====================== =========================================================== ========================================================================================================================== +action_ Specify how an argument should be handled ``'store'``, ``'store_const'``, ``'store_true'``, ``'append'``, ``'append_const'``, ``'count'``, ``'help'``, ``'version'`` +choices_ Limit values to a specific set of choices ``['foo', 'bar']``, ``range(1, 10)``, or :class:`~collections.abc.Container` instance +const_ Store a constant value +default_ Default value used when an argument is not provided Defaults to ``None`` +dest_ Specify the attribute name used in the result namespace +help_ Help message for an argument +metavar_ Alternate display name for the argument as shown in help +nargs_ Number of times the argument can be used :class:`int`, ``'?'``, ``'*'``, ``'+'``, or ``argparse.REMAINDER`` +required_ Indicate whether an argument is required or optional ``True`` or ``False`` +type_ Automatically convert an argument to the given type :class:`int`, :class:`float`, ``argparse.FileType('w')``, or callable function +====================== =========================================================== ========================================================================================================================== Example @@ -44,8 +91,8 @@ produces either the sum or the max:: args = parser.parse_args() print(args.accumulate(args.integers)) -Assuming the Python code above is saved into a file called ``prog.py``, it can -be run at the command line and provides useful help messages: +Assuming the above Python code is saved into a file called ``prog.py``, it can +be run at the command line and it provides useful help messages: .. code-block:: shell-session @@ -72,7 +119,7 @@ the command-line integers: $ python prog.py 1 2 3 4 --sum 10 -If invalid arguments are passed in, it will issue an error: +If invalid arguments are passed in, an error will be displayed: .. code-block:: shell-session @@ -112,7 +159,7 @@ used when :meth:`~ArgumentParser.parse_args` is called. For example:: Later, calling :meth:`~ArgumentParser.parse_args` will return an object with two attributes, ``integers`` and ``accumulate``. The ``integers`` attribute -will be a list of one or more ints, and the ``accumulate`` attribute will be +will be a list of one or more integers, and the ``accumulate`` attribute will be either the :func:`sum` function, if ``--sum`` was specified at the command line, or the :func:`max` function if it was not. @@ -148,14 +195,16 @@ ArgumentParser objects as keyword arguments. Each parameter has its own more detailed description below, but in short they are: - * prog_ - The name of the program (default: ``sys.argv[0]``) + * prog_ - The name of the program (default: + ``os.path.basename(sys.argv[0])``) * usage_ - The string describing the program usage (default: generated from arguments added to parser) - * description_ - Text to display before the argument help (default: none) + * description_ - Text to display before the argument help + (by default, no text) - * epilog_ - Text to display after the argument help (default: none) + * epilog_ - Text to display after the argument help (by default, no text) * parents_ - A list of :class:`ArgumentParser` objects whose arguments should also be included @@ -195,6 +244,8 @@ ArgumentParser objects The following sections describe how each of these are used. +.. _prog: + prog ^^^^ @@ -292,6 +343,8 @@ The ``%(prog)s`` format specifier is available to fill in the program name in your usage messages. +.. _description: + description ^^^^^^^^^^^ @@ -372,6 +425,8 @@ and one in the child) and raise an error. not be reflected in the child. +.. _formatter_class: + formatter_class ^^^^^^^^^^^^^^^ @@ -501,15 +556,16 @@ disallowed. fromfile_prefix_chars ^^^^^^^^^^^^^^^^^^^^^ -Sometimes, for example when dealing with a particularly long argument lists, it +Sometimes, when dealing with a particularly long argument list, it may make sense to keep the list of arguments in a file rather than typing it out at the command line. If the ``fromfile_prefix_chars=`` argument is given to the :class:`ArgumentParser` constructor, then arguments that start with any of the specified characters will be treated as files, and will be replaced by the arguments they contain. For example:: - >>> with open('args.txt', 'w') as fp: + >>> with open('args.txt', 'w', encoding=sys.getfilesystemencoding()) as fp: ... fp.write('-f\nbar') + ... >>> parser = argparse.ArgumentParser(fromfile_prefix_chars='@') >>> parser.add_argument('-f') >>> parser.parse_args(['-f', 'foo', '@args.txt']) @@ -521,9 +577,18 @@ were in the same place as the original file referencing argument on the command line. So in the example above, the expression ``['-f', 'foo', '@args.txt']`` is considered equivalent to the expression ``['-f', 'foo', '-f', 'bar']``. +:class:`ArgumentParser` uses :term:`filesystem encoding and error handler` +to read the file containing arguments. + The ``fromfile_prefix_chars=`` argument defaults to ``None``, meaning that arguments will never be treated as file references. +.. versionchanged:: 3.12 + :class:`ArgumentParser` changed encoding and errors to read arguments files + from default (e.g. :func:`locale.getpreferredencoding(False)` and + ``"strict"``) to :term:`filesystem encoding and error handler`. + Arguments file should be encoded in UTF-8 instead of ANSI Codepage on Windows. + argument_default ^^^^^^^^^^^^^^^^ @@ -700,7 +765,7 @@ The add_argument() method * type_ - The type to which the command-line argument should be converted. - * choices_ - A container of the allowable values for the argument. + * choices_ - A sequence of the allowable values for the argument. * required_ - Whether or not the command-line option may be omitted (optionals only). @@ -715,6 +780,8 @@ The add_argument() method The following sections describe how each of these are used. +.. _name_or_flags: + name or flags ^^^^^^^^^^^^^ @@ -748,6 +815,8 @@ be positional:: PROG: error: the following arguments are required: bar +.. _action: + action ^^^^^^ @@ -788,8 +857,10 @@ how the command-line arguments should be handled. The supplied actions are: Namespace(foo=True, bar=False, baz=True) * ``'append'`` - This stores a list, and appends each argument value to the - list. This is useful to allow an option to be specified multiple times. - Example usage:: + list. It is useful to allow an option to be specified multiple times. + If the default value is non-empty, the default elements will be present + in the parsed value for the option, with any values from the + command line appended after those default values. Example usage:: >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action='append') @@ -883,13 +954,16 @@ An example of a custom action:: For more details, see :class:`Action`. + +.. _nargs: + nargs ^^^^^ ArgumentParser objects usually associate a single command-line argument with a single action to be taken. The ``nargs`` keyword argument associates a -different number of command-line arguments with a single action. The supported -values are: +different number of command-line arguments with a single action. +See also :ref:`specifying-ambiguous-arguments`. The supported values are: * ``N`` (an integer). ``N`` arguments from the command line will be gathered together into a list. For example:: @@ -970,6 +1044,8 @@ is determined by the action_. Generally this means a single command-line argume will be consumed and a single item (not a list) will be produced. +.. _const: + const ^^^^^ @@ -996,6 +1072,8 @@ the various :class:`ArgumentParser` actions. The two most common uses of it are ``const=None`` by default, including when ``action='append_const'`` or ``action='store_const'``. +.. _default: + default ^^^^^^^ @@ -1054,6 +1132,8 @@ command-line argument was not present:: Namespace(foo='1') +.. _type: + type ^^^^ @@ -1123,11 +1203,13 @@ For type checkers that simply check against a fixed set of values, consider using the choices_ keyword instead. +.. _choices: + choices ^^^^^^^ Some command-line arguments should be selected from a restricted set of values. -These can be handled by passing a container object as the *choices* keyword +These can be handled by passing a sequence object as the *choices* keyword argument to :meth:`~ArgumentParser.add_argument`. When the command line is parsed, argument values will be checked, and an error message will be displayed if the argument was not one of the acceptable values:: @@ -1141,9 +1223,9 @@ if the argument was not one of the acceptable values:: game.py: error: argument move: invalid choice: 'fire' (choose from 'rock', 'paper', 'scissors') -Note that inclusion in the *choices* container is checked after any type_ +Note that inclusion in the *choices* sequence is checked after any type_ conversions have been performed, so the type of the objects in the *choices* -container should match the type_ specified:: +sequence should match the type_ specified:: >>> parser = argparse.ArgumentParser(prog='doors.py') >>> parser.add_argument('door', type=int, choices=range(1, 4)) @@ -1153,18 +1235,20 @@ container should match the type_ specified:: usage: doors.py [-h] {1,2,3} doors.py: error: argument door: invalid choice: 4 (choose from 1, 2, 3) -Any container can be passed as the *choices* value, so :class:`list` objects, -:class:`set` objects, and custom containers are all supported. +Any sequence can be passed as the *choices* value, so :class:`list` objects, +:class:`tuple` objects, and custom sequences are all supported. Use of :class:`enum.Enum` is not recommended because it is difficult to control its appearance in usage, help, and error messages. -Formatted choices overrides the default *metavar* which is normally derived +Formatted choices override the default *metavar* which is normally derived from *dest*. This is usually what you want because the user never sees the *dest* parameter. If this display isn't desirable (perhaps because there are many choices), just specify an explicit metavar_. +.. _required: + required ^^^^^^^^ @@ -1191,6 +1275,8 @@ present at the command line. *options* to be *optional*, and thus they should be avoided when possible. +.. _help: + help ^^^^ @@ -1246,6 +1332,8 @@ setting the ``help`` value to ``argparse.SUPPRESS``:: -h, --help show this help message and exit +.. _metavar: + metavar ^^^^^^^ @@ -1310,6 +1398,8 @@ arguments:: --foo bar baz +.. _dest: + dest ^^^^ @@ -1531,6 +1621,9 @@ argument:: >>> parser.parse_args(['--', '-f']) Namespace(foo='-f', one=None) +See also :ref:`the argparse howto on ambiguous arguments ` +for more details. + .. _prefix-matching: Argument abbreviations (prefix matching) @@ -1619,7 +1712,7 @@ Sub-commands .. method:: ArgumentParser.add_subparsers([title], [description], [prog], \ [parser_class], [action], \ - [option_string], [dest], [required], \ + [option_strings], [dest], [required], \ [help], [metavar]) Many programs split up their functionality into a number of sub-commands, @@ -1835,8 +1928,8 @@ FileType objects Namespace(out=<_io.TextIOWrapper name='file.txt' mode='w' encoding='UTF-8'>, raw=<_io.FileIO name='raw.dat' mode='wb'>) FileType objects understand the pseudo-argument ``'-'`` and automatically - convert this into ``sys.stdin`` for readable :class:`FileType` objects and - ``sys.stdout`` for writable :class:`FileType` objects:: + convert this into :data:`sys.stdin` for readable :class:`FileType` objects and + :data:`sys.stdout` for writable :class:`FileType` objects:: >>> parser = argparse.ArgumentParser() >>> parser.add_argument('infile', type=argparse.FileType('r')) @@ -1853,7 +1946,7 @@ Argument groups .. method:: ArgumentParser.add_argument_group(title=None, description=None) By default, :class:`ArgumentParser` groups command-line arguments into - "positional arguments" and "optional arguments" when displaying help + "positional arguments" and "options" when displaying help messages. When there is a better conceptual grouping of arguments than this default one, appropriate groups can be created using the :meth:`add_argument_group` method:: @@ -1898,6 +1991,12 @@ Argument groups Note that any arguments not in your user-defined groups will end up back in the usual "positional arguments" and "optional arguments" sections. + .. versionchanged:: 3.11 + Calling :meth:`add_argument_group` on an argument group is deprecated. + This feature was never supported and does not always work correctly. + The function exists on the API by accident through inheritance and + will be removed in the future. + Mutual exclusion ^^^^^^^^^^^^^^^^ @@ -1934,7 +2033,32 @@ Mutual exclusion Note that currently mutually exclusive argument groups do not support the *title* and *description* arguments of - :meth:`~ArgumentParser.add_argument_group`. + :meth:`~ArgumentParser.add_argument_group`. However, a mutually exclusive + group can be added to an argument group that has a title and description. + For example:: + + >>> parser = argparse.ArgumentParser(prog='PROG') + >>> group = parser.add_argument_group('Group title', 'Group description') + >>> exclusive_group = group.add_mutually_exclusive_group(required=True) + >>> exclusive_group.add_argument('--foo', help='foo help') + >>> exclusive_group.add_argument('--bar', help='bar help') + >>> parser.print_help() + usage: PROG [-h] (--foo FOO | --bar BAR) + + options: + -h, --help show this help message and exit + + Group title: + Group description + + --foo FOO foo help + --bar BAR bar help + + .. versionchanged:: 3.11 + Calling :meth:`add_argument_group` or :meth:`add_mutually_exclusive_group` + on a mutually exclusive group is deprecated. These features were never + supported and do not always work correctly. The functions exist on the + API by accident through inheritance and will be removed in the future. Parser defaults diff --git a/Doc/library/array.rst b/Doc/library/array.rst index c7f137d15b4..95f1eaf401b 100644 --- a/Doc/library/array.rst +++ b/Doc/library/array.rst @@ -52,7 +52,7 @@ Notes: .. versionchanged:: 3.9 ``array('u')`` now uses ``wchar_t`` as C type instead of deprecated - ``Py_UNICODE``. This change doesn't affect to its behavior because + ``Py_UNICODE``. This change doesn't affect its behavior because ``Py_UNICODE`` is alias of ``wchar_t`` since Python 3.3. .. deprecated-removed:: 3.3 4.0 @@ -62,6 +62,14 @@ The actual representation of values is determined by the machine architecture (strictly speaking, by the C implementation). The actual size can be accessed through the :attr:`itemsize` attribute. +The module defines the following item: + + +.. data:: typecodes + + A string with all available type codes. + + The module defines the following type: @@ -79,9 +87,6 @@ The module defines the following type: .. audit-event:: array.__new__ typecode,initializer array.array -.. data:: typecodes - - A string with all available type codes. Array objects support the ordinary sequence operations of indexing, slicing, concatenation, and multiplication. When using slice assignment, the assigned diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index e29b5e88d71..0811b3fa0e7 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -45,7 +45,7 @@ Node classes This is the base of all AST node classes. The actual node classes are derived from the :file:`Parser/Python.asdl` file, which is reproduced - :ref:`below `. They are defined in the :mod:`_ast` C + :ref:`above `. They are defined in the :mod:`_ast` C module and re-exported in :mod:`ast`. There is one class defined for each left-hand side symbol in the abstract @@ -1028,10 +1028,11 @@ Control flow .. class:: For(target, iter, body, orelse, type_comment) A ``for`` loop. ``target`` holds the variable(s) the loop assigns to, as a - single :class:`Name`, :class:`Tuple` or :class:`List` node. ``iter`` holds - the item to be looped over, again as a single node. ``body`` and ``orelse`` - contain lists of nodes to execute. Those in ``orelse`` are executed if the - loop finishes normally, rather than via a ``break`` statement. + single :class:`Name`, :class:`Tuple`, :class:`List`, :class:`Attribute` or + :class:`Subscript` node. ``iter`` holds the item to be looped over, again + as a single node. ``body`` and ``orelse`` contain lists of nodes to execute. + Those in ``orelse`` are executed if the loop finishes normally, rather than + via a ``break`` statement. .. attribute:: type_comment @@ -1167,6 +1168,37 @@ Control flow type_ignores=[]) +.. class:: TryStar(body, handlers, orelse, finalbody) + + ``try`` blocks which are followed by ``except*`` clauses. The attributes are the + same as for :class:`Try` but the :class:`ExceptHandler` nodes in ``handlers`` + are interpreted as ``except*`` blocks rather then ``except``. + + .. doctest:: + + >>> print(ast.dump(ast.parse(""" + ... try: + ... ... + ... except* Exception: + ... ... + ... """), indent=4)) + Module( + body=[ + TryStar( + body=[ + Expr( + value=Constant(value=Ellipsis))], + handlers=[ + ExceptHandler( + type=Name(id='Exception', ctx=Load()), + body=[ + Expr( + value=Constant(value=Ellipsis))])], + orelse=[], + finalbody=[])], + type_ignores=[]) + + .. class:: ExceptHandler(type, name, body) A single ``except`` clause. ``type`` is the exception type it will match, @@ -1795,7 +1827,7 @@ Function and class definitions * ``bases`` is a list of nodes for explicitly specified base classes. * ``keywords`` is a list of :class:`keyword` nodes, principally for 'metaclass'. Other keywords will be passed to the metaclass, as per `PEP-3115 - `_. + `_. * ``starargs`` and ``kwargs`` are each a single node, as in a function call. starargs will be expanded to join the list of base classes, and kwargs will be passed to the metaclass. @@ -1919,7 +1951,7 @@ and classes for traversing abstract syntax trees: If source contains a null character ('\0'), :exc:`ValueError` is raised. - .. warning:: + .. warning:: Note that successfully parsing source code into an AST object doesn't guarantee that the source code provided is valid Python code that can be executed as the compilation step can raise further :exc:`SyntaxError` @@ -1959,20 +1991,28 @@ and classes for traversing abstract syntax trees: .. function:: literal_eval(node_or_string) - Safely evaluate an expression node or a string containing a Python literal or + Evaluate an expression node or a string containing only a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, ``None`` and ``Ellipsis``. - This can be used for safely evaluating strings containing Python values from - untrusted sources without the need to parse the values oneself. It is not - capable of evaluating arbitrarily complex expressions, for example involving - operators or indexing. + This can be used for evaluating strings containing Python values without the + need to parse the values oneself. It is not capable of evaluating + arbitrarily complex expressions, for example involving operators or + indexing. + + This function had been documented as "safe" in the past without defining + what that meant. That was misleading. This is specifically designed not to + execute Python code, unlike the more general :func:`eval`. There is no + namespace, no name lookups, or ability to call out. But it is not free from + attack: A relatively small input can lead to memory exhaustion or to C stack + exhaustion, crashing the process. There is also the possibility for + excessive CPU consumption denial of service on some inputs. Calling it on + untrusted data is thus not recommended. .. warning:: - It is possible to crash the Python interpreter with a - sufficiently large/complex string due to stack depth limitations - in Python's AST compiler. + It is possible to crash the Python interpreter due to stack depth + limitations in Python's AST compiler. It can raise :exc:`ValueError`, :exc:`TypeError`, :exc:`SyntaxError`, :exc:`MemoryError` and :exc:`RecursionError` depending on the malformed @@ -2237,7 +2277,7 @@ to stdout. Otherwise, the content is read from stdin. code that generated them. This is helpful for tools that make source code transformations. - `leoAst.py `_ unifies the + `leoAst.py `_ unifies the token-based and parse-tree-based views of python programs by inserting two-way links between tokens and ast nodes. diff --git a/Doc/library/asyncio-api-index.rst b/Doc/library/asyncio-api-index.rst index f558724d4a3..ad475150fe7 100644 --- a/Doc/library/asyncio-api-index.rst +++ b/Doc/library/asyncio-api-index.rst @@ -21,8 +21,25 @@ await on multiple things with timeouts. * - :func:`run` - Create event loop, run a coroutine, close the loop. + * - :class:`Runner` + - A context manager that simplifies multiple async function calls. + + * - :class:`Task` + - Task object. + + * - :class:`TaskGroup` + - A context manager that holds a group of tasks. Provides + a convenient and reliable way to wait for all tasks in the group to + finish. + * - :func:`create_task` - - Start an asyncio Task. + - Start an asyncio Task, then returns it. + + * - :func:`current_task` + - Return the current Task. + + * - :func:`all_tasks` + - Return all tasks that are not yet finished for an event loop. * - ``await`` :func:`sleep` - Sleep for a number of seconds. @@ -39,14 +56,8 @@ await on multiple things with timeouts. * - ``await`` :func:`wait` - Monitor for completion. - * - :func:`current_task` - - Return the current Task. - - * - :func:`all_tasks` - - Return all tasks for an event loop. - - * - :class:`Task` - - Task object. + * - :func:`timeout` + - Run with a timeout. Useful in cases when ``wait_for`` is not suitable. * - :func:`to_thread` - Asynchronously run a function in a separate OS thread. @@ -186,11 +197,16 @@ Threading-like synchronization primitives that can be used in Tasks. * - :class:`BoundedSemaphore` - A bounded semaphore. + * - :class:`Barrier` + - A barrier object. + .. rubric:: Examples * :ref:`Using asyncio.Event `. +* :ref:`Using asyncio.Barrier `. + * See also the documentation of asyncio :ref:`synchronization primitives `. @@ -203,14 +219,12 @@ Exceptions :class: full-width-table - * - :exc:`asyncio.TimeoutError` - - Raised on timeout by functions like :func:`wait_for`. - Keep in mind that ``asyncio.TimeoutError`` is **unrelated** - to the built-in :exc:`TimeoutError` exception. - * - :exc:`asyncio.CancelledError` - Raised when a Task is cancelled. See also :meth:`Task.cancel`. + * - :exc:`asyncio.BrokenBarrierError` + - Raised when a Barrier is broken. See also :meth:`Barrier.wait`. + .. rubric:: Examples diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst index 77f1128de50..921a394a59f 100644 --- a/Doc/library/asyncio-dev.rst +++ b/Doc/library/asyncio-dev.rst @@ -109,7 +109,7 @@ that the event loop runs in. There is currently no way to schedule coroutines or callbacks directly from a different process (such as one started with -:mod:`multiprocessing`). The :ref:`Event Loop Methods ` +:mod:`multiprocessing`). The :ref:`asyncio-event-loop-methods` section lists APIs that can read from pipes and watch file descriptors without blocking the event loop. In addition, asyncio's :ref:`Subprocess ` APIs provide a way to start a @@ -148,6 +148,11 @@ adjusted:: logging.getLogger("asyncio").setLevel(logging.WARNING) +Network logging can block the event loop. It is recommended to use +a separate thread for handling logs or use non-blocking IO. For example, +see :ref:`blocking-handlers`. + + .. _asyncio-coroutine-not-scheduled: Detect never-awaited coroutines diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index c4408f122c3..db63a5dd11a 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -1,6 +1,8 @@ .. currentmodule:: asyncio +.. _asyncio-event-loop: + ========== Event Loop ========== @@ -31,7 +33,8 @@ an event loop: Return the running event loop in the current OS thread. - If there is no running event loop a :exc:`RuntimeError` is raised. + Raise a :exc:`RuntimeError` if there is no running event loop. + This function can only be called from a coroutine or a callback. .. versionadded:: 3.7 @@ -40,31 +43,33 @@ an event loop: Get the current event loop. - If there is no current event loop set in the current OS thread, - the OS thread is main, and :func:`set_event_loop` has not yet - been called, asyncio will create a new event loop and set it as the - current one. + When called from a coroutine or a callback (e.g. scheduled with + call_soon or similar API), this function will always return the + running event loop. + + If there is no running event loop set, the function will return + the result of the ``get_event_loop_policy().get_event_loop()`` call. Because this function has rather complex behavior (especially when custom event loop policies are in use), using the :func:`get_running_loop` function is preferred to :func:`get_event_loop` in coroutines and callbacks. - Consider also using the :func:`asyncio.run` function instead of using - lower level functions to manually create and close an event loop. + As noted above, consider using the higher-level :func:`asyncio.run` function, + instead of using these lower level functions to manually create and close an + event loop. - .. deprecated:: 3.10 - Deprecation warning is emitted if there is no running event loop. - In future Python releases, this function will be an alias of - :func:`get_running_loop`. + .. deprecated:: 3.12 + Deprecation warning is emitted if there is no current event loop. + In some future Python release this will become an error. .. function:: set_event_loop(loop) - Set *loop* as a current event loop for the current OS thread. + Set *loop* as the current event loop for the current OS thread. .. function:: new_event_loop() - Create a new event loop object. + Create and return a new event loop object. Note that the behaviour of :func:`get_event_loop`, :func:`set_event_loop`, and :func:`new_event_loop` functions can be altered by @@ -92,7 +97,7 @@ This documentation page contains the following sections: loop APIs. -.. _asyncio-event-loop: +.. _asyncio-event-loop-methods: Event Loop Methods ================== @@ -178,18 +183,27 @@ Running and stopping the loop .. versionadded:: 3.6 -.. coroutinemethod:: loop.shutdown_default_executor() +.. coroutinemethod:: loop.shutdown_default_executor(timeout=None) Schedule the closure of the default executor and wait for it to join all of the threads in the :class:`ThreadPoolExecutor`. After calling this method, a :exc:`RuntimeError` will be raised if :meth:`loop.run_in_executor` is called while using the default executor. + The *timeout* parameter specifies the amount of time the executor will + be given to finish joining. The default value is ``None``, which means the + executor will be given an unlimited amount of time. + + If the timeout duration is reached, a warning is emitted and executor is + terminated without waiting for its threads to finish joining. + Note that there is no need to call this function when :func:`asyncio.run` is used. .. versionadded:: 3.9 + .. versionchanged:: 3.12 + Added the *timeout* parameter. Scheduling callbacks ^^^^^^^^^^^^^^^^^^^^ @@ -330,9 +344,9 @@ Creating Futures and Tasks .. versionadded:: 3.5.2 -.. method:: loop.create_task(coro, *, name=None) +.. method:: loop.create_task(coro, *, name=None, context=None) - Schedule the execution of a :ref:`coroutine`. + Schedule the execution of :ref:`coroutine ` *coro*. Return a :class:`Task` object. Third-party event loops can use their own subclass of :class:`Task` @@ -342,8 +356,15 @@ Creating Futures and Tasks If the *name* argument is provided and not ``None``, it is set as the name of the task using :meth:`Task.set_name`. + An optional keyword-only *context* argument allows specifying a + custom :class:`contextvars.Context` for the *coro* to run in. + The current context copy is created when no *context* is provided. + .. versionchanged:: 3.8 - Added the ``name`` parameter. + Added the *name* parameter. + + .. versionchanged:: 3.11 + Added the *context* parameter. .. method:: loop.set_task_factory(factory) @@ -352,7 +373,7 @@ Creating Futures and Tasks If *factory* is ``None`` the default task factory will be set. Otherwise, *factory* must be a *callable* with the signature matching - ``(loop, coro)``, where *loop* is a reference to the active + ``(loop, coro, context=None)``, where *loop* is a reference to the active event loop, and *coro* is a coroutine object. The callable must return a :class:`asyncio.Future`-compatible object. @@ -369,7 +390,9 @@ Opening network connections family=0, proto=0, flags=0, sock=None, \ local_addr=None, server_hostname=None, \ ssl_handshake_timeout=None, \ - happy_eyeballs_delay=None, interleave=None) + ssl_shutdown_timeout=None, \ + happy_eyeballs_delay=None, interleave=None, \ + all_errors=False) Open a streaming transport connection to a given address specified by *host* and *port*. @@ -448,6 +471,12 @@ Opening network connections *happy_eyeballs_delay*, *interleave* and *local_addr* should be specified. + .. note:: + + The *sock* argument transfers ownership of the socket to the + transport created. To close the socket, call the transport's + :meth:`~asyncio.BaseTransport.close` method. + * *local_addr*, if given, is a ``(local_host, local_port)`` tuple used to bind the socket locally. The *local_host* and *local_port* are looked up using ``getaddrinfo()``, similarly to *host* and *port*. @@ -456,7 +485,32 @@ Opening network connections to wait for the TLS handshake to complete before aborting the connection. ``60.0`` seconds if ``None`` (default). - .. versionadded:: 3.8 + * *ssl_shutdown_timeout* is the time in seconds to wait for the SSL shutdown + to complete before aborting the connection. ``30.0`` seconds if ``None`` + (default). + + * *all_errors* determines what exceptions are raised when a connection cannot + be created. By default, only a single ``Exception`` is raised: the first + exception if there is only one or all errors have same message, or a single + ``OSError`` with the error messages combined. When ``all_errors`` is ``True``, + an ``ExceptionGroup`` will be raised containing all exceptions (even if there + is only one). + + + .. versionchanged:: 3.5 + + Added support for SSL/TLS in :class:`ProactorEventLoop`. + + .. versionchanged:: 3.6 + + The socket option :py:data:`~socket.TCP_NODELAY` is set by default + for all TCP connections. + + .. versionchanged:: 3.7 + + Added the *ssl_handshake_timeout* parameter. + + .. versionchanged:: 3.8 Added the *happy_eyeballs_delay* and *interleave* parameters. @@ -471,18 +525,12 @@ Opening network connections For more information: https://tools.ietf.org/html/rfc6555 - .. versionadded:: 3.7 + .. versionchanged:: 3.11 - The *ssl_handshake_timeout* parameter. + Added the *ssl_shutdown_timeout* parameter. - .. versionchanged:: 3.6 - - The socket option :py:data:`~socket.TCP_NODELAY` is set by default - for all TCP connections. - - .. versionchanged:: 3.5 - - Added support for SSL/TLS in :class:`ProactorEventLoop`. + .. versionchanged:: 3.12 + *all_errors* was added. .. seealso:: @@ -538,6 +586,12 @@ Opening network connections transport. If specified, *local_addr* and *remote_addr* should be omitted (must be :const:`None`). + .. note:: + + The *sock* argument transfers ownership of the socket to the + transport created. To close the socket, call the transport's + :meth:`~asyncio.BaseTransport.close` method. + See :ref:`UDP echo client protocol ` and :ref:`UDP echo server protocol ` examples. @@ -569,7 +623,8 @@ Opening network connections .. coroutinemethod:: loop.create_unix_connection(protocol_factory, \ path=None, *, ssl=None, sock=None, \ - server_hostname=None, ssl_handshake_timeout=None) + server_hostname=None, ssl_handshake_timeout=None, \ + ssl_shutdown_timeout=None) Create a Unix connection. @@ -588,14 +643,14 @@ Opening network connections .. availability:: Unix. - .. versionadded:: 3.7 - - The *ssl_handshake_timeout* parameter. - .. versionchanged:: 3.7 - + Added the *ssl_handshake_timeout* parameter. The *path* parameter can now be a :term:`path-like object`. + .. versionchanged:: 3.11 + + Added the *ssl_shutdown_timeout* parameter. + Creating network servers ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -606,7 +661,9 @@ Creating network servers flags=socket.AI_PASSIVE, \ sock=None, backlog=100, ssl=None, \ reuse_address=None, reuse_port=None, \ - ssl_handshake_timeout=None, start_serving=True) + ssl_handshake_timeout=None, \ + ssl_shutdown_timeout=None, \ + start_serving=True) Create a TCP server (socket type :data:`~socket.SOCK_STREAM`) listening on *port* of the *host* address. @@ -631,6 +688,11 @@ Creating network servers assumed and a list of multiple sockets will be returned (most likely one for IPv4 and another one for IPv6). + * The *port* parameter can be set to specify which port the server should + listen on. If ``0`` or ``None`` (the default), a random unused port will + be selected (note that if *host* resolves to multiple network interfaces, + a different random port will be selected for each interface). + * *family* can be set to either :data:`socket.AF_INET` or :data:`~socket.AF_INET6` to force the socket to use IPv4 or IPv6. If not set, the *family* will be determined from host name @@ -641,6 +703,12 @@ Creating network servers * *sock* can optionally be specified in order to use a preexisting socket object. If specified, *host* and *port* must not be specified. + .. note:: + + The *sock* argument transfers ownership of the socket to the + server created. To close the socket, call the server's + :meth:`~asyncio.Server.close` method. + * *backlog* is the maximum number of queued connections passed to :meth:`~socket.socket.listen` (defaults to 100). @@ -661,21 +729,16 @@ Creating network servers for the TLS handshake to complete before aborting the connection. ``60.0`` seconds if ``None`` (default). + * *ssl_shutdown_timeout* is the time in seconds to wait for the SSL shutdown + to complete before aborting the connection. ``30.0`` seconds if ``None`` + (default). + * *start_serving* set to ``True`` (the default) causes the created server to start accepting connections immediately. When set to ``False``, the user should await on :meth:`Server.start_serving` or :meth:`Server.serve_forever` to make the server to start accepting connections. - .. versionadded:: 3.7 - - Added *ssl_handshake_timeout* and *start_serving* parameters. - - .. versionchanged:: 3.6 - - The socket option :py:data:`~socket.TCP_NODELAY` is set by default - for all TCP connections. - .. versionchanged:: 3.5 Added support for SSL/TLS in :class:`ProactorEventLoop`. @@ -684,6 +747,16 @@ Creating network servers The *host* parameter can be a sequence of strings. + .. versionchanged:: 3.6 + + Added *ssl_handshake_timeout* and *start_serving* parameters. + The socket option :py:data:`~socket.TCP_NODELAY` is set by default + for all TCP connections. + + .. versionchanged:: 3.11 + + Added the *ssl_shutdown_timeout* parameter. + .. seealso:: The :func:`start_server` function is a higher-level alternative API @@ -693,7 +766,9 @@ Creating network servers .. coroutinemethod:: loop.create_unix_server(protocol_factory, path=None, \ *, sock=None, backlog=100, ssl=None, \ - ssl_handshake_timeout=None, start_serving=True) + ssl_handshake_timeout=None, \ + ssl_shutdown_timeout=None, \ + start_serving=True) Similar to :meth:`loop.create_server` but works with the :py:data:`~socket.AF_UNIX` socket family. @@ -708,16 +783,19 @@ Creating network servers .. availability:: Unix. - .. versionadded:: 3.7 - - The *ssl_handshake_timeout* and *start_serving* parameters. - .. versionchanged:: 3.7 + Added the *ssl_handshake_timeout* and *start_serving* parameters. The *path* parameter can now be a :class:`~pathlib.Path` object. + .. versionchanged:: 3.11 + + Added the *ssl_shutdown_timeout* parameter. + + .. coroutinemethod:: loop.connect_accepted_socket(protocol_factory, \ - sock, *, ssl=None, ssl_handshake_timeout=None) + sock, *, ssl=None, ssl_handshake_timeout=None, \ + ssl_shutdown_timeout=None) Wrap an already accepted connection into a transport/protocol pair. @@ -732,6 +810,12 @@ Creating network servers * *sock* is a preexisting socket object returned from :meth:`socket.accept `. + .. note:: + + The *sock* argument transfers ownership of the socket to the + transport created. To close the socket, call the transport's + :meth:`~asyncio.BaseTransport.close` method. + * *ssl* can be set to an :class:`~ssl.SSLContext` to enable SSL over the accepted connections. @@ -739,14 +823,22 @@ Creating network servers wait for the SSL handshake to complete before aborting the connection. ``60.0`` seconds if ``None`` (default). + * *ssl_shutdown_timeout* is the time in seconds to wait for the SSL shutdown + to complete before aborting the connection. ``30.0`` seconds if ``None`` + (default). + Returns a ``(transport, protocol)`` pair. - .. versionadded:: 3.7 - - The *ssl_handshake_timeout* parameter. - .. versionadded:: 3.5.3 + .. versionchanged:: 3.7 + + Added the *ssl_handshake_timeout* parameter. + + .. versionchanged:: 3.11 + + Added the *ssl_shutdown_timeout* parameter. + Transferring files ^^^^^^^^^^^^^^^^^^ @@ -783,13 +875,19 @@ TLS Upgrade .. coroutinemethod:: loop.start_tls(transport, protocol, \ sslcontext, *, server_side=False, \ - server_hostname=None, ssl_handshake_timeout=None) + server_hostname=None, ssl_handshake_timeout=None, \ + ssl_shutdown_timeout=None) Upgrade an existing transport-based connection to TLS. - Return a new transport instance, that the *protocol* must start using - immediately after the *await*. The *transport* instance passed to - the *start_tls* method should never be used again. + Create a TLS coder/decoder instance and insert it between the *transport* + and the *protocol*. The coder/decoder implements both *transport*-facing + protocol and *protocol*-facing transport. + + Return the created two-interface instance. After *await*, the *protocol* + must stop using the original *transport* and communicate with the returned + object only because the coder caches *protocol*-side data and sporadically + exchanges extra TLS session packets with *transport*. Parameters: @@ -809,8 +907,17 @@ TLS Upgrade wait for the TLS handshake to complete before aborting the connection. ``60.0`` seconds if ``None`` (default). + * *ssl_shutdown_timeout* is the time in seconds to wait for the SSL shutdown + to complete before aborting the connection. ``30.0`` seconds if ``None`` + (default). + .. versionadded:: 3.7 + .. versionchanged:: 3.11 + + Added the *ssl_shutdown_timeout* parameter. + + Watching file descriptors ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -823,7 +930,8 @@ Watching file descriptors .. method:: loop.remove_reader(fd) - Stop monitoring the *fd* file descriptor for read availability. + Stop monitoring the *fd* file descriptor for read availability. Returns + ``True`` if *fd* was previously being monitored for reads. .. method:: loop.add_writer(fd, callback, *args) @@ -836,7 +944,8 @@ Watching file descriptors .. method:: loop.remove_writer(fd) - Stop monitoring the *fd* file descriptor for write availability. + Stop monitoring the *fd* file descriptor for write availability. Returns + ``True`` if *fd* was previously being monitored for writes. See also :ref:`Platform Support ` section for some limitations of these methods. @@ -877,6 +986,29 @@ convenient. .. versionadded:: 3.7 +.. coroutinemethod:: loop.sock_recvfrom(sock, bufsize) + + Receive a datagram of up to *bufsize* from *sock*. Asynchronous version of + :meth:`socket.recvfrom() `. + + Return a tuple of (received data, remote address). + + *sock* must be a non-blocking socket. + + .. versionadded:: 3.11 + +.. coroutinemethod:: loop.sock_recvfrom_into(sock, buf, nbytes=0) + + Receive a datagram of up to *nbytes* from *sock* into *buf*. + Asynchronous version of + :meth:`socket.recvfrom_into() `. + + Return a tuple of (number of bytes received, remote address). + + *sock* must be a non-blocking socket. + + .. versionadded:: 3.11 + .. coroutinemethod:: loop.sock_sendall(sock, data) Send *data* to the *sock* socket. Asynchronous version of @@ -892,9 +1024,21 @@ convenient. .. versionchanged:: 3.7 Even though the method was always documented as a coroutine - method, before Python 3.7 it returned an :class:`Future`. + method, before Python 3.7 it returned a :class:`Future`. Since Python 3.7, this is an ``async def`` method. +.. coroutinemethod:: loop.sock_sendto(sock, data, address) + + Send a datagram from *sock* to *address*. + Asynchronous version of + :meth:`socket.sendto() `. + + Return the number of bytes sent. + + *sock* must be a non-blocking socket. + + .. versionadded:: 3.11 + .. coroutinemethod:: loop.sock_connect(sock, address) Connect *sock* to a remote socket at *address*. @@ -1119,7 +1263,13 @@ Executing code in thread or process pools pool, cpu_bound) print('custom process pool', result) - asyncio.run(main()) + if __name__ == '__main__': + asyncio.run(main()) + + Note that the entry point guard (``if __name__ == '__main__'``) + is required for option 3 due to the peculiarities of :mod:`multiprocessing`, + which is used by :class:`~concurrent.futures.ProcessPoolExecutor`. + See :ref:`Safe importing of main module `. This method returns a :class:`asyncio.Future` object. @@ -1161,6 +1311,15 @@ Allows customizing how exceptions are handled in the event loop. (see :meth:`call_exception_handler` documentation for details about context). + If the handler is called on behalf of a :class:`~asyncio.Task` or + :class:`~asyncio.Handle`, it is run in the + :class:`contextvars.Context` of that task or callback handle. + + .. versionchanged:: 3.12 + + The handler may be called in the :class:`~contextvars.Context` + of the task or handle where the exception originated. + .. method:: loop.get_exception_handler() Return the current exception handler, or ``None`` if no custom @@ -1238,9 +1397,10 @@ async/await code consider using the high-level .. note:: - The default asyncio event loop on **Windows** does not support - subprocesses. See :ref:`Subprocess Support on Windows - ` for details. + On Windows, the default event loop :class:`ProactorEventLoop` supports + subprocesses, whereas :class:`SelectorEventLoop` does not. See + :ref:`Subprocess Support on Windows ` for + details. .. coroutinemethod:: loop.subprocess_exec(protocol_factory, *args, \ stdin=subprocess.PIPE, stdout=subprocess.PIPE, \ @@ -1363,6 +1523,13 @@ Callback Handles A callback wrapper object returned by :meth:`loop.call_soon`, :meth:`loop.call_soon_threadsafe`. + .. method:: get_context() + + Return the :class:`contextvars.Context` object + associated with the handle. + + .. versionadded:: 3.12 + .. method:: cancel() Cancel the callback. If the callback has already been canceled @@ -1498,6 +1665,7 @@ Do not instantiate the class directly. .. _asyncio-event-loops: +.. _asyncio-event-loop-implementations: Event Loop Implementations ========================== @@ -1520,9 +1688,12 @@ on Unix and :class:`ProactorEventLoop` on Windows. import asyncio import selectors - selector = selectors.SelectSelector() - loop = asyncio.SelectorEventLoop(selector) - asyncio.set_event_loop(loop) + class MyPolicy(asyncio.DefaultEventLoopPolicy): + def new_event_loop(self): + selector = selectors.SelectSelector() + return asyncio.SelectorEventLoop(selector) + + asyncio.set_event_loop_policy(MyPolicy()) .. availability:: Unix, Windows. @@ -1544,7 +1715,7 @@ on Unix and :class:`ProactorEventLoop` on Windows. Abstract base class for asyncio-compliant event loops. - The :ref:`Event Loop Methods ` section lists all + The :ref:`asyncio-event-loop-methods` section lists all methods that an alternative implementation of ``AbstractEventLoop`` should have defined. @@ -1575,7 +1746,7 @@ event loop:: print('Hello World') loop.stop() - loop = asyncio.get_event_loop() + loop = asyncio.new_event_loop() # Schedule a call to hello_world() loop.call_soon(hello_world, loop) @@ -1611,7 +1782,7 @@ after 5 seconds, and then stops the event loop:: else: loop.stop() - loop = asyncio.get_event_loop() + loop = asyncio.new_event_loop() # Schedule the first call to display_date() end_time = loop.time() + 5.0 @@ -1643,7 +1814,7 @@ Wait until a file descriptor received some data using the # Create a pair of connected file descriptors rsock, wsock = socketpair() - loop = asyncio.get_event_loop() + loop = asyncio.new_event_loop() def reader(): data = rsock.recv(100) diff --git a/Doc/library/asyncio-exceptions.rst b/Doc/library/asyncio-exceptions.rst index 7166d5c4bd8..9250f01b8a0 100644 --- a/Doc/library/asyncio-exceptions.rst +++ b/Doc/library/asyncio-exceptions.rst @@ -13,11 +13,12 @@ Exceptions .. exception:: TimeoutError - The operation has exceeded the given deadline. + A deprecated alias of :exc:`TimeoutError`, + raised when the operation has exceeded the given deadline. - .. important:: - This exception is different from the builtin :exc:`TimeoutError` - exception. + .. versionchanged:: 3.11 + + This class was made an alias of :exc:`TimeoutError`. .. exception:: CancelledError diff --git a/Doc/library/asyncio-extending.rst b/Doc/library/asyncio-extending.rst new file mode 100644 index 00000000000..8ffd356f2d1 --- /dev/null +++ b/Doc/library/asyncio-extending.rst @@ -0,0 +1,98 @@ +.. currentmodule:: asyncio + + +========= +Extending +========= + +The main direction for :mod:`asyncio` extending is writing custom *event loop* +classes. Asyncio has helpers that could be used to simplify this task. + +.. note:: + + Third-parties should reuse existing asyncio code with caution, + a new Python version is free to break backward compatibility + in *internal* part of API. + + +Writing a Custom Event Loop +=========================== + +:class:`asyncio.AbstractEventLoop` declares very many methods. Implementing all them +from scratch is a tedious job. + +A loop can get many common methods implementation for free by inheriting from +:class:`asyncio.BaseEventLoop`. + +In turn, the successor should implement a bunch of *private* methods declared but not +implemented in :class:`asyncio.BaseEventLoop`. + +For example, ``loop.create_connection()`` checks arguments, resolves DNS addresses, and +calls ``loop._make_socket_transport()`` that should be implemented by inherited class. +The ``_make_socket_transport()`` method is not documented and is considered as an +*internal* API. + + + +Future and Task private constructors +==================================== + +:class:`asyncio.Future` and :class:`asyncio.Task` should be never created directly, +please use corresponding :meth:`loop.create_future` and :meth:`loop.create_task`, +or :func:`asyncio.create_task` factories instead. + +However, third-party *event loops* may *reuse* built-in future and task implementations +for the sake of getting a complex and highly optimized code for free. + +For this purpose the following, *private* constructors are listed: + +.. method:: Future.__init__(*, loop=None) + + Create a built-in future instance. + + *loop* is an optional event loop instance. + +.. method:: Task.__init__(coro, *, loop=None, name=None, context=None) + + Create a built-in task instance. + + *loop* is an optional event loop instance. The rest of arguments are described in + :meth:`loop.create_task` description. + + .. versionchanged:: 3.11 + + *context* argument is added. + + + +Task lifetime support +===================== + +A third party task implementation should call the following functions to keep a task +visible by :func:`asyncio.get_tasks` and :func:`asyncio.current_task`: + +.. function:: _register_task(task) + + Register a new *task* as managed by *asyncio*. + + Call the function from a task constructor. + +.. function:: _unregister_task(task) + + Unregister a *task* from *asyncio* internal structures. + + The function should be called when a task is about to finish. + +.. function:: _enter_task(loop, task) + + Switch the current task to the *task* argument. + + Call the function just before executing a portion of embedded *coroutine* + (:meth:`coroutine.send` or :meth:`coroutine.throw`). + +.. function:: _leave_task(loop, task) + + Switch the current task back from *task* to ``None``. + + Call the function just after :meth:`coroutine.send` or :meth:`coroutine.throw` + execution. diff --git a/Doc/library/asyncio-future.rst b/Doc/library/asyncio-future.rst index 3496387c178..70cec9b2f90 100644 --- a/Doc/library/asyncio-future.rst +++ b/Doc/library/asyncio-future.rst @@ -55,7 +55,7 @@ Future Functions preferred way for creating new Tasks. Save a reference to the result of this function, to avoid - a task disappearing mid execution. + a task disappearing mid-execution. .. versionchanged:: 3.5.1 The function accepts any :term:`awaitable` object. @@ -85,7 +85,8 @@ Future Object Future is an :term:`awaitable` object. Coroutines can await on Future objects until they either have a result or an exception - set, or until they are cancelled. + set, or until they are cancelled. A Future can be awaited multiple + times and the result is same. Typically Futures are used to enable low-level callback-based code (e.g. in protocols implemented using asyncio @@ -194,7 +195,7 @@ Future Object schedule the callbacks, and return ``True``. .. versionchanged:: 3.9 - Added the ``msg`` parameter. + Added the *msg* parameter. .. method:: exception() diff --git a/Doc/library/asyncio-llapi-index.rst b/Doc/library/asyncio-llapi-index.rst index 0ab322af6dc..9ce48a24444 100644 --- a/Doc/library/asyncio-llapi-index.rst +++ b/Doc/library/asyncio-llapi-index.rst @@ -19,7 +19,7 @@ Obtaining the Event Loop - The **preferred** function to get the running event loop. * - :func:`asyncio.get_event_loop` - - Get an event loop instance (current or via the policy). + - Get an event loop instance (running or current via the current policy). * - :func:`asyncio.set_event_loop` - Set the event loop as current via the current policy. @@ -37,7 +37,7 @@ Event Loop Methods ================== See also the main documentation section about the -:ref:`event loop methods `. +:ref:`asyncio-event-loop-methods`. .. rubric:: Lifecycle .. list-table:: @@ -189,9 +189,18 @@ See also the main documentation section about the * - ``await`` :meth:`loop.sock_recv_into` - Receive data from the :class:`~socket.socket` into a buffer. + * - ``await`` :meth:`loop.sock_recvfrom` + - Receive a datagram from the :class:`~socket.socket`. + + * - ``await`` :meth:`loop.sock_recvfrom_into` + - Receive a datagram from the :class:`~socket.socket` into a buffer. + * - ``await`` :meth:`loop.sock_sendall` - Send data to the :class:`~socket.socket`. + * - ``await`` :meth:`loop.sock_sendto` + - Send a datagram via the :class:`~socket.socket` to the given address. + * - ``await`` :meth:`loop.sock_connect` - Connect the :class:`~socket.socket`. @@ -258,7 +267,7 @@ See also the main documentation section about the .. rubric:: Examples -* :ref:`Using asyncio.get_event_loop() and loop.run_forever() +* :ref:`Using asyncio.new_event_loop() and loop.run_forever() `. * :ref:`Using loop.call_later() `. @@ -349,6 +358,10 @@ pipes, etc). Returned from methods like * - :meth:`transport.get_write_buffer_size() ` + - Return the current size of the output buffer. + + * - :meth:`transport.get_write_buffer_limits() + ` - Return high and low water marks for write flow control. * - :meth:`transport.set_write_buffer_limits() diff --git a/Doc/library/asyncio-policy.rst b/Doc/library/asyncio-policy.rst index ef6a0588506..0d7821e608e 100644 --- a/Doc/library/asyncio-policy.rst +++ b/Doc/library/asyncio-policy.rst @@ -7,22 +7,29 @@ Policies ======== -An event loop policy is a global per-process object that controls -the management of the event loop. Each event loop has a default -policy, which can be changed and customized using the policy API. +An event loop policy is a global object +used to get and set the current :ref:`event loop `, +as well as create new event loops. +The default policy can be :ref:`replaced ` with +:ref:`built-in alternatives ` +to use different event loop implementations, +or substituted by a :ref:`custom policy ` +that can override these behaviors. -A policy defines the notion of *context* and manages a -separate event loop per context. The default policy -defines *context* to be the current thread. +The :ref:`policy object ` +gets and sets a separate event loop per *context*. +This is per-thread by default, +though custom policies could define *context* differently. -By using a custom event loop policy, the behavior of -:func:`get_event_loop`, :func:`set_event_loop`, and -:func:`new_event_loop` functions can be customized. +Custom event loop policies can control the behavior of +:func:`get_event_loop`, :func:`set_event_loop`, and :func:`new_event_loop`. Policy objects should implement the APIs defined in the :class:`AbstractEventLoopPolicy` abstract base class. +.. _asyncio-policy-get-set: + Getting and Setting the Policy ============================== @@ -40,6 +47,8 @@ for the current process: If *policy* is set to ``None``, the default policy is restored. +.. _asyncio-policy-objects: + Policy Objects ============== @@ -79,12 +88,18 @@ The abstract event loop policy base class is defined as follows: This function is Unix specific. + .. deprecated:: 3.12 + .. method:: set_child_watcher(watcher) Set the current child process watcher to *watcher*. This function is Unix specific. + .. deprecated:: 3.12 + + +.. _asyncio-policy-builtin: asyncio ships with the following built-in policies: @@ -101,6 +116,12 @@ asyncio ships with the following built-in policies: On Windows, :class:`ProactorEventLoop` is now used by default. + .. deprecated:: 3.12 + The :meth:`get_event_loop` method of the default asyncio policy now emits + a :exc:`DeprecationWarning` if there is no current event loop set and it + decides to create one. + In some future Python release this will become an error. + .. class:: WindowsSelectorEventLoopPolicy @@ -117,6 +138,7 @@ asyncio ships with the following built-in policies: .. availability:: Windows. + .. _asyncio-watchers: Process Watchers @@ -146,12 +168,16 @@ implementation used by the asyncio event loop: Return the current child watcher for the current policy. + .. deprecated:: 3.12 + .. function:: set_child_watcher(watcher) Set the current child watcher to *watcher* for the current policy. *watcher* must implement methods defined in the :class:`AbstractChildWatcher` base class. + .. deprecated:: 3.12 + .. note:: Third-party event loops implementations might not support custom child watchers. For such event loops, using @@ -202,6 +228,9 @@ implementation used by the asyncio event loop: This method has to be called to ensure that underlying resources are cleaned-up. + .. deprecated:: 3.12 + + .. class:: ThreadedChildWatcher This implementation starts a new waiting thread for every subprocess spawn. @@ -233,6 +262,8 @@ implementation used by the asyncio event loop: .. versionadded:: 3.8 + .. deprecated:: 3.12 + .. class:: SafeChildWatcher This implementation uses active event loop from the main thread to handle @@ -245,6 +276,8 @@ implementation used by the asyncio event loop: This solution is as safe as :class:`MultiLoopChildWatcher` and has the same *O(N)* complexity but requires a running event loop in the main thread to work. + .. deprecated:: 3.12 + .. class:: FastChildWatcher This implementation reaps every terminated processes by calling @@ -257,6 +290,8 @@ implementation used by the asyncio event loop: This solution requires a running event loop in the main thread to work, as :class:`SafeChildWatcher`. + .. deprecated:: 3.12 + .. class:: PidfdChildWatcher This implementation polls process file descriptors (pidfds) to await child @@ -270,6 +305,8 @@ implementation used by the asyncio event loop: .. versionadded:: 3.9 +.. _asyncio-custom-policies: + Custom Policies =============== diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst index 8b67f4b8957..7bc906eaafc 100644 --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -156,7 +156,8 @@ Base Transport will be received. After all buffered data is flushed, the protocol's :meth:`protocol.connection_lost() ` method will be called with - :const:`None` as its argument. + :const:`None` as its argument. The transport should not be + used once it is closed. .. method:: BaseTransport.is_closing() @@ -553,7 +554,7 @@ accept factories that return streaming protocols. a connection is open. However, :meth:`protocol.eof_received() ` - is called at most once. Once `eof_received()` is called, + is called at most once. Once ``eof_received()`` is called, ``data_received()`` is not called anymore. .. method:: Protocol.eof_received() diff --git a/Doc/library/asyncio-queue.rst b/Doc/library/asyncio-queue.rst index e6f26bb9598..d86fbc21351 100644 --- a/Doc/library/asyncio-queue.rst +++ b/Doc/library/asyncio-queue.rst @@ -36,6 +36,9 @@ Queue the queue is always known and can be returned by calling the :meth:`qsize` method. + .. versionchanged:: 3.10 + Removed the *loop* parameter. + This class is :ref:`not thread safe `. @@ -105,13 +108,6 @@ Queue Raises :exc:`ValueError` if called more times than there were items placed in the queue. - .. deprecated-removed:: 3.8 3.10 - - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. - Priority Queue ============== diff --git a/Doc/library/asyncio-runner.rst b/Doc/library/asyncio-runner.rst new file mode 100644 index 00000000000..b68b2570ef0 --- /dev/null +++ b/Doc/library/asyncio-runner.rst @@ -0,0 +1,160 @@ +.. currentmodule:: asyncio + + +======= +Runners +======= + +**Source code:** :source:`Lib/asyncio/runners.py` + + +This section outlines high-level asyncio primitives to run asyncio code. + +They are built on top of an :ref:`event loop ` with the aim +to simplify async code usage for common wide-spread scenarios. + +.. contents:: + :depth: 1 + :local: + + + +Running an asyncio Program +========================== + +.. function:: run(coro, *, debug=None, loop_factory=None) + + Execute the :term:`coroutine` *coro* and return the result. + + This function runs the passed coroutine, taking care of + managing the asyncio event loop, *finalizing asynchronous + generators*, and closing the executor. + + This function cannot be called when another asyncio event loop is + running in the same thread. + + If *debug* is ``True``, the event loop will be run in debug mode. ``False`` disables + debug mode explicitly. ``None`` is used to respect the global + :ref:`asyncio-debug-mode` settings. + + If *loop_factory* is not ``None``, it is used to create a new event loop; + otherwise :func:`asyncio.new_event_loop` is used. The loop is closed at the end. + This function should be used as a main entry point for asyncio programs, + and should ideally only be called once. It is recommended to use + *loop_factory* to configure the event loop instead of policies. + + The executor is given a timeout duration of 5 minutes to shutdown. + If the executor hasn't finished within that duration, a warning is + emitted and the executor is closed. + + Example:: + + async def main(): + await asyncio.sleep(1) + print('hello') + + asyncio.run(main()) + + .. versionadded:: 3.7 + + .. versionchanged:: 3.9 + Updated to use :meth:`loop.shutdown_default_executor`. + + .. versionchanged:: 3.10 + + *debug* is ``None`` by default to respect the global debug mode settings. + + .. versionchanged:: 3.12 + + Added *loop_factory* parameter. + + +Runner context manager +====================== + +.. class:: Runner(*, debug=None, loop_factory=None) + + A context manager that simplifies *multiple* async function calls in the same + context. + + Sometimes several top-level async functions should be called in the same :ref:`event + loop ` and :class:`contextvars.Context`. + + If *debug* is ``True``, the event loop will be run in debug mode. ``False`` disables + debug mode explicitly. ``None`` is used to respect the global + :ref:`asyncio-debug-mode` settings. + + *loop_factory* could be used for overriding the loop creation. + It is the responsibility of the *loop_factory* to set the created loop as the + current one. By default :func:`asyncio.new_event_loop` is used and set as + current event loop with :func:`asyncio.set_event_loop` if *loop_factory* is ``None``. + + Basically, :func:`asyncio.run()` example can be rewritten with the runner usage:: + + async def main(): + await asyncio.sleep(1) + print('hello') + + with asyncio.Runner() as runner: + runner.run(main()) + + .. versionadded:: 3.11 + + .. method:: run(coro, *, context=None) + + Run a :term:`coroutine ` *coro* in the embedded loop. + + Return the coroutine's result or raise its exception. + + An optional keyword-only *context* argument allows specifying a + custom :class:`contextvars.Context` for the *coro* to run in. + The runner's default context is used if ``None``. + + This function cannot be called when another asyncio event loop is + running in the same thread. + + .. method:: close() + + Close the runner. + + Finalize asynchronous generators, shutdown default executor, close the event loop + and release embedded :class:`contextvars.Context`. + + .. method:: get_loop() + + Return the event loop associated with the runner instance. + + .. note:: + + :class:`Runner` uses the lazy initialization strategy, its constructor doesn't + initialize underlying low-level structures. + + Embedded *loop* and *context* are created at the :keyword:`with` body entering + or the first call of :meth:`run` or :meth:`get_loop`. + + +Handling Keyboard Interruption +============================== + +.. versionadded:: 3.11 + +When :const:`signal.SIGINT` is raised by :kbd:`Ctrl-C`, :exc:`KeyboardInterrupt` +exception is raised in the main thread by default. However this doesn't work with +:mod:`asyncio` because it can interrupt asyncio internals and can hang the program from +exiting. + +To mitigate this issue, :mod:`asyncio` handles :const:`signal.SIGINT` as follows: + +1. :meth:`asyncio.Runner.run` installs a custom :const:`signal.SIGINT` handler before + any user code is executed and removes it when exiting from the function. +2. The :class:`~asyncio.Runner` creates the main task for the passed coroutine for its + execution. +3. When :const:`signal.SIGINT` is raised by :kbd:`Ctrl-C`, the custom signal handler + cancels the main task by calling :meth:`asyncio.Task.cancel` which raises + :exc:`asyncio.CancelledError` inside the main task. This causes the Python stack + to unwind, ``try/except`` and ``try/finally`` blocks can be used for resource + cleanup. After the main task is cancelled, :meth:`asyncio.Runner.run` raises + :exc:`KeyboardInterrupt`. +4. A user could write a tight loop which cannot be interrupted by + :meth:`asyncio.Task.cancel`, in which case the second following :kbd:`Ctrl-C` + immediately raises the :exc:`KeyboardInterrupt` without cancelling the main task. diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst index 95a8e4649be..c1ae8abb9ab 100644 --- a/Doc/library/asyncio-stream.rst +++ b/Doc/library/asyncio-stream.rst @@ -51,7 +51,9 @@ and work with streams: .. coroutinefunction:: open_connection(host=None, port=None, *, \ limit=None, ssl=None, family=0, proto=0, \ flags=0, sock=None, local_addr=None, \ - server_hostname=None, ssl_handshake_timeout=None) + server_hostname=None, ssl_handshake_timeout=None, \ + ssl_shutdown_timeout=None, \ + happy_eyeballs_delay=None, interleave=None) Establish a network connection and return a pair of ``(reader, writer)`` objects. @@ -66,16 +68,23 @@ and work with streams: The rest of the arguments are passed directly to :meth:`loop.create_connection`. - .. versionadded:: 3.7 + .. note:: - The *ssl_handshake_timeout* parameter. + The *sock* argument transfers ownership of the socket to the + :class:`StreamWriter` created. To close the socket, call its + :meth:`~asyncio.StreamWriter.close` method. - .. deprecated-removed:: 3.8 3.10 + .. versionchanged:: 3.7 + Added the *ssl_handshake_timeout* parameter. - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. versionadded:: 3.8 + Added *happy_eyeballs_delay* and *interleave* parameters. + + .. versionchanged:: 3.10 + Removed the *loop* parameter. + + .. versionchanged:: 3.11 + Added the *ssl_shutdown_timeout* parameter. .. coroutinefunction:: start_server(client_connected_cb, host=None, \ @@ -84,7 +93,7 @@ and work with streams: flags=socket.AI_PASSIVE, sock=None, \ backlog=100, ssl=None, reuse_address=None, \ reuse_port=None, ssl_handshake_timeout=None, \ - start_serving=True) + ssl_shutdown_timeout=None, start_serving=True) Start a socket server. @@ -104,23 +113,27 @@ and work with streams: The rest of the arguments are passed directly to :meth:`loop.create_server`. - .. versionadded:: 3.7 + .. note:: - The *ssl_handshake_timeout* and *start_serving* parameters. + The *sock* argument transfers ownership of the socket to the + server created. To close the socket, call the server's + :meth:`~asyncio.Server.close` method. - .. deprecated-removed:: 3.8 3.10 + .. versionchanged:: 3.7 + Added the *ssl_handshake_timeout* and *start_serving* parameters. - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. versionchanged:: 3.10 + Removed the *loop* parameter. + + .. versionchanged:: 3.11 + Added the *ssl_shutdown_timeout* parameter. .. rubric:: Unix Sockets .. coroutinefunction:: open_unix_connection(path=None, *, limit=None, \ ssl=None, sock=None, server_hostname=None, \ - ssl_handshake_timeout=None) + ssl_handshake_timeout=None, ssl_shutdown_timeout=None) Establish a Unix socket connection and return a pair of ``(reader, writer)``. @@ -129,27 +142,29 @@ and work with streams: See also the documentation of :meth:`loop.create_unix_connection`. + .. note:: + + The *sock* argument transfers ownership of the socket to the + :class:`StreamWriter` created. To close the socket, call its + :meth:`~asyncio.StreamWriter.close` method. + .. availability:: Unix. - .. versionadded:: 3.7 - - The *ssl_handshake_timeout* parameter. - .. versionchanged:: 3.7 - + Added the *ssl_handshake_timeout* parameter. The *path* parameter can now be a :term:`path-like object` - .. deprecated-removed:: 3.8 3.10 + .. versionchanged:: 3.10 + Removed the *loop* parameter. - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. versionchanged:: 3.11 + Added the *ssl_shutdown_timeout* parameter. .. coroutinefunction:: start_unix_server(client_connected_cb, path=None, \ *, limit=None, sock=None, backlog=100, ssl=None, \ - ssl_handshake_timeout=None, start_serving=True) + ssl_handshake_timeout=None, \ + ssl_shutdown_timeout=None, start_serving=True) Start a Unix socket server. @@ -157,22 +172,23 @@ and work with streams: See also the documentation of :meth:`loop.create_unix_server`. + .. note:: + + The *sock* argument transfers ownership of the socket to the + server created. To close the socket, call the server's + :meth:`~asyncio.Server.close` method. + .. availability:: Unix. - .. versionadded:: 3.7 - - The *ssl_handshake_timeout* and *start_serving* parameters. - .. versionchanged:: 3.7 - + Added the *ssl_handshake_timeout* and *start_serving* parameters. The *path* parameter can now be a :term:`path-like object`. - .. deprecated-removed:: 3.8 3.10 + .. versionchanged:: 3.10 + Removed the *loop* parameter. - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. versionchanged:: 3.11 + Added the *ssl_shutdown_timeout* parameter. StreamReader @@ -181,7 +197,8 @@ StreamReader .. class:: StreamReader Represents a reader object that provides APIs to read data - from the IO stream. + from the IO stream. As an :term:`asynchronous iterable`, the + object supports the :keyword:`async for` statement. It is not recommended to instantiate *StreamReader* objects directly; use :func:`open_connection` and :func:`start_server` @@ -214,7 +231,7 @@ StreamReader can be read. Use the :attr:`IncompleteReadError.partial` attribute to get the partially read data. - .. coroutinemethod:: readuntil(separator=b'\\n') + .. coroutinemethod:: readuntil(separator=b'\n') Read data from the stream until *separator* is found. @@ -317,6 +334,24 @@ StreamWriter be resumed. When there is nothing to wait for, the :meth:`drain` returns immediately. + .. coroutinemethod:: start_tls(sslcontext, \*, server_hostname=None, \ + ssl_handshake_timeout=None) + + Upgrade an existing stream-based connection to TLS. + + Parameters: + + * *sslcontext*: a configured instance of :class:`~ssl.SSLContext`. + + * *server_hostname*: sets or overrides the host name that the target + server's certificate will be matched against. + + * *ssl_handshake_timeout* is the time in seconds to wait for the TLS + handshake to complete before aborting the connection. ``60.0`` seconds + if ``None`` (default). + + .. versionadded:: 3.11 + .. method:: is_closing() Return ``True`` if the stream is closed or in the process of @@ -352,6 +387,7 @@ TCP echo client using the :func:`asyncio.open_connection` function:: print(f'Send: {message!r}') writer.write(message.encode()) + await writer.drain() data = await reader.read(100) print(f'Received: {data.decode()!r}') diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst index fd1f9c99578..4274638c5e8 100644 --- a/Doc/library/asyncio-subprocess.rst +++ b/Doc/library/asyncio-subprocess.rst @@ -75,12 +75,8 @@ Creating Subprocesses See the documentation of :meth:`loop.subprocess_exec` for other parameters. - .. deprecated-removed:: 3.8 3.10 - - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. versionchanged:: 3.10 + Removed the *loop* parameter. .. coroutinefunction:: create_subprocess_shell(cmd, stdin=None, \ @@ -106,12 +102,8 @@ Creating Subprocesses escape whitespace and special shell characters in strings that are going to be used to construct shell commands. - .. deprecated-removed:: 3.8 3.10 - - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. versionchanged:: 3.10 + Removed the *loop* parameter. .. note:: @@ -132,6 +124,7 @@ Constants ========= .. data:: asyncio.subprocess.PIPE + :module: Can be passed to the *stdin*, *stdout* or *stderr* parameters. @@ -145,11 +138,13 @@ Constants attributes will point to :class:`StreamReader` instances. .. data:: asyncio.subprocess.STDOUT + :module: Special value that can be used as the *stderr* argument and indicates that standard error should be redirected into standard output. .. data:: asyncio.subprocess.DEVNULL + :module: Special value that can be used as the *stdin*, *stdout* or *stderr* argument to process creation functions. It indicates that the special file @@ -165,6 +160,7 @@ wrapper that allows communicating with subprocesses and watching for their completion. .. class:: asyncio.subprocess.Process + :module: An object that wraps OS processes created by the :func:`create_subprocess_exec` and :func:`create_subprocess_shell` @@ -179,7 +175,7 @@ their completion. * the :meth:`~asyncio.subprocess.Process.communicate` and :meth:`~asyncio.subprocess.Process.wait` methods don't have a - *timeout* parameter: use the :func:`wait_for` function; + *timeout* parameter: use the :func:`~asyncio.wait_for` function; * the :meth:`Process.wait() ` method is asynchronous, whereas :meth:`subprocess.Popen.wait` method @@ -283,7 +279,7 @@ their completion. Use the :meth:`communicate` method rather than :attr:`process.stdin.write() `, :attr:`await process.stdout.read() ` or - :attr:`await process.stderr.read `. + :attr:`await process.stderr.read() `. This avoids deadlocks due to streams pausing reading or writing and blocking the child process. diff --git a/Doc/library/asyncio-sync.rst b/Doc/library/asyncio-sync.rst index 88e523af0b8..05bdf5488af 100644 --- a/Doc/library/asyncio-sync.rst +++ b/Doc/library/asyncio-sync.rst @@ -28,6 +28,7 @@ asyncio has the following basic synchronization primitives: * :class:`Condition` * :class:`Semaphore` * :class:`BoundedSemaphore` +* :class:`Barrier` --------- @@ -63,11 +64,8 @@ Lock finally: lock.release() - .. deprecated-removed:: 3.8 3.10 - The ``loop`` parameter. This class has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. versionchanged:: 3.10 + Removed the *loop* parameter. .. coroutinemethod:: acquire() @@ -111,11 +109,8 @@ Event :meth:`clear` method. The :meth:`~Event.wait` method blocks until the flag is set to *true*. The flag is set to *false* initially. - .. deprecated-removed:: 3.8 3.10 - The ``loop`` parameter. This class has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. versionchanged:: 3.10 + Removed the *loop* parameter. .. _asyncio_example_sync_event: @@ -189,11 +184,8 @@ Condition ``None``. In the latter case a new Lock object is created automatically. - .. deprecated-removed:: 3.8 3.10 - The ``loop`` parameter. This class has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. versionchanged:: 3.10 + Removed the *loop* parameter. The preferred way to use a Condition is an :keyword:`async with` statement:: @@ -291,11 +283,8 @@ Semaphore internal counter (``1`` by default). If the given value is less than ``0`` a :exc:`ValueError` is raised. - .. deprecated-removed:: 3.8 3.10 - The ``loop`` parameter. This class has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. versionchanged:: 3.10 + Removed the *loop* parameter. The preferred way to use a Semaphore is an :keyword:`async with` statement:: @@ -349,12 +338,117 @@ BoundedSemaphore a :exc:`ValueError` in :meth:`~Semaphore.release` if it increases the internal counter above the initial *value*. - .. deprecated-removed:: 3.8 3.10 + .. versionchanged:: 3.10 + Removed the *loop* parameter. - The ``loop`` parameter. This class has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + +Barrier +======= + +.. class:: Barrier(parties) + + A barrier object. Not thread-safe. + + A barrier is a simple synchronization primitive that allows to block until + *parties* number of tasks are waiting on it. + Tasks can wait on the :meth:`~Barrier.wait` method and would be blocked until + the specified number of tasks end up waiting on :meth:`~Barrier.wait`. + At that point all of the waiting tasks would unblock simultaneously. + + :keyword:`async with` can be used as an alternative to awaiting on + :meth:`~Barrier.wait`. + + The barrier can be reused any number of times. + + .. _asyncio_example_barrier: + + Example:: + + async def example_barrier(): + # barrier with 3 parties + b = asyncio.Barrier(3) + + # create 2 new waiting tasks + asyncio.create_task(b.wait()) + asyncio.create_task(b.wait()) + + await asyncio.sleep(0) + print(b) + + # The third .wait() call passes the barrier + await b.wait() + print(b) + print("barrier passed") + + await asyncio.sleep(0) + print(b) + + asyncio.run(example_barrier()) + + Result of this example is:: + + + + barrier passed + + + .. versionadded:: 3.11 + + .. coroutinemethod:: wait() + + Pass the barrier. When all the tasks party to the barrier have called + this function, they are all unblocked simultaneously. + + When a waiting or blocked task in the barrier is cancelled, + this task exits the barrier which stays in the same state. + If the state of the barrier is "filling", the number of waiting task + decreases by 1. + + The return value is an integer in the range of 0 to ``parties-1``, different + for each task. This can be used to select a task to do some special + housekeeping, e.g.:: + + ... + async with barrier as position: + if position == 0: + # Only one task prints this + print('End of *draining phase*') + + This method may raise a :class:`BrokenBarrierError` exception if the + barrier is broken or reset while a task is waiting. + It could raise a :exc:`CancelledError` if a task is cancelled. + + .. coroutinemethod:: reset() + + Return the barrier to the default, empty state. Any tasks waiting on it + will receive the :class:`BrokenBarrierError` exception. + + If a barrier is broken it may be better to just leave it and create a new one. + + .. coroutinemethod:: abort() + + Put the barrier into a broken state. This causes any active or future + calls to :meth:`wait` to fail with the :class:`BrokenBarrierError`. + Use this for example if one of the tasks needs to abort, to avoid infinite + waiting tasks. + + .. attribute:: parties + + The number of tasks required to pass the barrier. + + .. attribute:: n_waiting + + The number of tasks currently waiting in the barrier while filling. + + .. attribute:: broken + + A boolean that is ``True`` if the barrier is in the broken state. + + +.. exception:: BrokenBarrierError + + This exception, a subclass of :exc:`RuntimeError`, is raised when the + :class:`Barrier` object is reset or broken. --------- diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 36e13f92956..631a5ddc1f6 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -18,9 +18,13 @@ and Tasks. Coroutines ========== +**Source code:** :source:`Lib/asyncio/coroutines.py` + +---------------------------------------------------- + :term:`Coroutines ` declared with the async/await syntax is the preferred way of writing asyncio applications. For example, the following -snippet of code (requires Python 3.7+) prints "hello", waits 1 second, +snippet of code prints "hello", waits 1 second, and then prints "world":: >>> import asyncio @@ -40,7 +44,7 @@ be executed:: >>> main() -To actually run a coroutine, asyncio provides three main mechanisms: +To actually run a coroutine, asyncio provides the following mechanisms: * The :func:`asyncio.run` function to run the top-level entry point "main()" function (see the above example.) @@ -103,6 +107,29 @@ To actually run a coroutine, asyncio provides three main mechanisms: world finished at 17:14:34 +* The :class:`asyncio.TaskGroup` class provides a more modern + alternative to :func:`create_task`. + Using this API, the last example becomes:: + + async def main(): + async with asyncio.TaskGroup() as tg: + task1 = tg.create_task( + say_after(1, 'hello')) + + task2 = tg.create_task( + say_after(2, 'world')) + + print(f"started at {time.strftime('%X')}") + + # The wait is implicit when the context manager exits. + + print(f"finished at {time.strftime('%X')}") + + The timing and output should be the same as for the previous version. + + .. versionadded:: 3.11 + :class:`asyncio.TaskGroup`. + .. _asyncio-awaitables: @@ -204,47 +231,14 @@ A good example of a low-level function that returns a Future object is :meth:`loop.run_in_executor`. -Running an asyncio Program -========================== - -.. function:: run(coro, *, debug=False) - - Execute the :term:`coroutine` *coro* and return the result. - - This function runs the passed coroutine, taking care of - managing the asyncio event loop, *finalizing asynchronous - generators*, and closing the threadpool. - - This function cannot be called when another asyncio event loop is - running in the same thread. - - If *debug* is ``True``, the event loop will be run in debug mode. - - This function always creates a new event loop and closes it at - the end. It should be used as a main entry point for asyncio - programs, and should ideally only be called once. - - Example:: - - async def main(): - await asyncio.sleep(1) - print('hello') - - asyncio.run(main()) - - .. versionadded:: 3.7 - - .. versionchanged:: 3.9 - Updated to use :meth:`loop.shutdown_default_executor`. - - .. note:: - The source code for ``asyncio.run()`` can be found in - :source:`Lib/asyncio/runners.py`. - Creating Tasks ============== -.. function:: create_task(coro, *, name=None) +**Source code:** :source:`Lib/asyncio/tasks.py` + +----------------------------------------------- + +.. function:: create_task(coro, *, name=None, context=None) Wrap the *coro* :ref:`coroutine ` into a :class:`Task` and schedule its execution. Return the Task object. @@ -252,34 +246,139 @@ Creating Tasks If *name* is not ``None``, it is set as the name of the task using :meth:`Task.set_name`. + An optional keyword-only *context* argument allows specifying a + custom :class:`contextvars.Context` for the *coro* to run in. + The current context copy is created when no *context* is provided. + The task is executed in the loop returned by :func:`get_running_loop`, :exc:`RuntimeError` is raised if there is no running loop in current thread. - This function has been **added in Python 3.7**. Prior to - Python 3.7, the low-level :func:`asyncio.ensure_future` function - can be used instead:: + .. note:: - async def coro(): - ... - - # In Python 3.7+ - task = asyncio.create_task(coro()) - ... - - # This works in all Python versions but is less readable - task = asyncio.ensure_future(coro()) - ... + :meth:`asyncio.TaskGroup.create_task` is a newer alternative + that allows for convenient waiting for a group of related tasks. .. important:: Save a reference to the result of this function, to avoid - a task disappearing mid execution. + a task disappearing mid-execution. The event loop only keeps + weak references to tasks. A task that isn't referenced elsewhere + may get garbage collected at any time, even before it's done. + For reliable "fire-and-forget" background tasks, gather them in + a collection:: + + background_tasks = set() + + for i in range(10): + task = asyncio.create_task(some_coro(param=i)) + + # Add task to the set. This creates a strong reference. + background_tasks.add(task) + + # To prevent keeping references to finished tasks forever, + # make each task remove its own reference from the set after + # completion: + task.add_done_callback(background_tasks.discard) .. versionadded:: 3.7 .. versionchanged:: 3.8 - Added the ``name`` parameter. + Added the *name* parameter. + + .. versionchanged:: 3.11 + Added the *context* parameter. + + +Task Cancellation +================= + +Tasks can easily and safely be cancelled. +When a task is cancelled, :exc:`asyncio.CancelledError` will be raised +in the task at the next opportunity. + +It is recommended that coroutines use ``try/finally`` blocks to robustly +perform clean-up logic. In case :exc:`asyncio.CancelledError` +is explicitly caught, it should generally be propagated when +clean-up is complete. Most code can safely ignore :exc:`asyncio.CancelledError`. + +The asyncio components that enable structured concurrency, like +:class:`asyncio.TaskGroup` and :func:`asyncio.timeout`, +are implemented using cancellation internally and might misbehave if +a coroutine swallows :exc:`asyncio.CancelledError`. Similarly, user code +should not call :meth:`uncancel `. + +.. _taskgroups: + +Task Groups +=========== + +Task groups combine a task creation API with a convenient +and reliable way to wait for all tasks in the group to finish. + +.. class:: TaskGroup() + + An :ref:`asynchronous context manager ` + holding a group of tasks. + Tasks can be added to the group using :meth:`create_task`. + All tasks are awaited when the context manager exits. + + .. versionadded:: 3.11 + + .. method:: create_task(coro, *, name=None, context=None) + + Create a task in this task group. + The signature matches that of :func:`asyncio.create_task`. + +Example:: + + async def main(): + async with asyncio.TaskGroup() as tg: + task1 = tg.create_task(some_coro(...)) + task2 = tg.create_task(another_coro(...)) + print("Both tasks have completed now.") + +The ``async with`` statement will wait for all tasks in the group to finish. +While waiting, new tasks may still be added to the group +(for example, by passing ``tg`` into one of the coroutines +and calling ``tg.create_task()`` in that coroutine). +Once the last task has finished and the ``async with`` block is exited, +no new tasks may be added to the group. + +The first time any of the tasks belonging to the group fails +with an exception other than :exc:`asyncio.CancelledError`, +the remaining tasks in the group are cancelled. +No further tasks can then be added to the group. +At this point, if the body of the ``async with`` statement is still active +(i.e., :meth:`~object.__aexit__` hasn't been called yet), +the task directly containing the ``async with`` statement is also cancelled. +The resulting :exc:`asyncio.CancelledError` will interrupt an ``await``, +but it will not bubble out of the containing ``async with`` statement. + +Once all tasks have finished, if any tasks have failed +with an exception other than :exc:`asyncio.CancelledError`, +those exceptions are combined in an +:exc:`ExceptionGroup` or :exc:`BaseExceptionGroup` +(as appropriate; see their documentation) +which is then raised. + +Two base exceptions are treated specially: +If any task fails with :exc:`KeyboardInterrupt` or :exc:`SystemExit`, +the task group still cancels the remaining tasks and waits for them, +but then the initial :exc:`KeyboardInterrupt` or :exc:`SystemExit` +is re-raised instead of :exc:`ExceptionGroup` or :exc:`BaseExceptionGroup`. + +If the body of the ``async with`` statement exits with an exception +(so :meth:`~object.__aexit__` is called with an exception set), +this is treated the same as if one of the tasks failed: +the remaining tasks are cancelled and then waited for, +and non-cancellation exceptions are grouped into an +exception group and raised. +The exception passed into :meth:`~object.__aexit__`, +unless it is :exc:`asyncio.CancelledError`, +is also included in the exception group. +The same special case is made for +:exc:`KeyboardInterrupt` and :exc:`SystemExit` as in the previous paragraph. Sleeping @@ -299,12 +398,6 @@ Sleeping tasks to run. This can be used by long-running functions to avoid blocking the event loop for the full duration of the function call. - .. deprecated-removed:: 3.8 3.10 - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. - .. _asyncio_example_sleep: Example of coroutine displaying the current date every second @@ -325,12 +418,8 @@ Sleeping asyncio.run(display_date()) - .. deprecated-removed:: 3.8 3.10 - - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. versionchanged:: 3.10 + Removed the *loop* parameter. Running Tasks Concurrently @@ -365,11 +454,9 @@ Running Tasks Concurrently cancellation of one submitted Task/Future to cause other Tasks/Futures to be cancelled. - .. deprecated-removed:: 3.8 3.10 - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. note:: + A more modern way to create and run tasks concurrently and + wait for their completion is :class:`asyncio.TaskGroup`. .. _asyncio_example_gather: @@ -422,11 +509,8 @@ Running Tasks Concurrently If the *gather* itself is cancelled, the cancellation is propagated regardless of *return_exceptions*. - .. deprecated-removed:: 3.8 3.10 - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. versionchanged:: 3.10 + Removed the *loop* parameter. .. deprecated:: 3.10 Deprecation warning is emitted if no positional arguments are provided @@ -446,7 +530,8 @@ Shielding From Cancellation The statement:: - res = await shield(something()) + task = asyncio.create_task(something()) + res = await shield(task) is equivalent to:: @@ -465,16 +550,21 @@ Shielding From Cancellation the ``shield()`` function should be combined with a try/except clause, as follows:: + task = asyncio.create_task(something()) try: - res = await shield(something()) + res = await shield(task) except CancelledError: res = None - .. deprecated-removed:: 3.8 3.10 - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. important:: + + Save a reference to tasks passed to this function, to avoid + a task disappearing mid-execution. The event loop only keeps + weak references to tasks. A task that isn't referenced elsewhere + may get garbage collected at any time, even before it's done. + + .. versionchanged:: 3.10 + Removed the *loop* parameter. .. deprecated:: 3.10 Deprecation warning is emitted if *aw* is not Future-like object @@ -484,6 +574,125 @@ Shielding From Cancellation Timeouts ======== +.. coroutinefunction:: timeout(delay) + + An :ref:`asynchronous context manager ` + that can be used to limit the amount of time spent waiting on + something. + + *delay* can either be ``None``, or a float/int number of + seconds to wait. If *delay* is ``None``, no time limit will + be applied; this can be useful if the delay is unknown when + the context manager is created. + + In either case, the context manager can be rescheduled after + creation using :meth:`Timeout.reschedule`. + + Example:: + + async def main(): + async with asyncio.timeout(10): + await long_running_task() + + If ``long_running_task`` takes more than 10 seconds to complete, + the context manager will cancel the current task and handle + the resulting :exc:`asyncio.CancelledError` internally, transforming it + into an :exc:`asyncio.TimeoutError` which can be caught and handled. + + .. note:: + + The :func:`asyncio.timeout` context manager is what transforms + the :exc:`asyncio.CancelledError` into an :exc:`asyncio.TimeoutError`, + which means the :exc:`asyncio.TimeoutError` can only be caught + *outside* of the context manager. + + Example of catching :exc:`asyncio.TimeoutError`:: + + async def main(): + try: + async with asyncio.timeout(10): + await long_running_task() + except TimeoutError: + print("The long operation timed out, but we've handled it.") + + print("This statement will run regardless.") + + The context manager produced by :func:`asyncio.timeout` can be + rescheduled to a different deadline and inspected. + + .. class:: Timeout() + + An :ref:`asynchronous context manager ` + that limits time spent inside of it. + + .. versionadded:: 3.11 + + .. method:: when() -> float | None + + Return the current deadline, or ``None`` if the current + deadline is not set. + + The deadline is a float, consistent with the time returned by + :meth:`loop.time`. + + .. method:: reschedule(when: float | None) + + Change the time the timeout will trigger. + + If *when* is ``None``, any current deadline will be removed, and the + context manager will wait indefinitely. + + If *when* is a float, it is set as the new deadline. + + if *when* is in the past, the timeout will trigger on the next + iteration of the event loop. + + .. method:: expired() -> bool + + Return whether the context manager has exceeded its deadline + (expired). + + Example:: + + async def main(): + try: + # We do not know the timeout when starting, so we pass ``None``. + async with asyncio.timeout(None) as cm: + # We know the timeout now, so we reschedule it. + new_deadline = get_running_loop().time() + 10 + cm.reschedule(new_deadline) + + await long_running_task() + except TimeoutError: + pass + + if cm.expired: + print("Looks like we haven't finished on time.") + + Timeout context managers can be safely nested. + + .. versionadded:: 3.11 + +.. coroutinefunction:: timeout_at(when) + + Similar to :func:`asyncio.timeout`, except *when* is the absolute time + to stop waiting, or ``None``. + + Example:: + + async def main(): + loop = get_running_loop() + deadline = loop.time() + 20 + try: + async with asyncio.timeout_at(deadline): + await long_running_task() + except TimeoutError: + print("The long operation timed out, but we've handled it.") + + print("This statement will run regardless.") + + .. versionadded:: 3.11 + .. coroutinefunction:: wait_for(aw, timeout) Wait for the *aw* :ref:`awaitable ` @@ -496,7 +705,7 @@ Timeouts completes. If a timeout occurs, it cancels the task and raises - :exc:`asyncio.TimeoutError`. + :exc:`TimeoutError`. To avoid the task :meth:`cancellation `, wrap it in :func:`shield`. @@ -507,11 +716,8 @@ Timeouts If the wait is cancelled, the future *aw* is also cancelled. - .. deprecated-removed:: 3.8 3.10 - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. versionchanged:: 3.10 + Removed the *loop* parameter. .. _asyncio_example_waitfor: @@ -526,7 +732,7 @@ Timeouts # Wait for at most 1 second try: await asyncio.wait_for(eternity(), timeout=1.0) - except asyncio.TimeoutError: + except TimeoutError: print('timeout!') asyncio.run(main()) @@ -538,13 +744,10 @@ Timeouts .. versionchanged:: 3.7 When *aw* is cancelled due to a timeout, ``wait_for`` waits for *aw* to be cancelled. Previously, it raised - :exc:`asyncio.TimeoutError` immediately. + :exc:`TimeoutError` immediately. - .. deprecated-removed:: 3.8 3.10 - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. versionchanged:: 3.10 + Removed the *loop* parameter. Waiting Primitives @@ -552,7 +755,7 @@ Waiting Primitives .. coroutinefunction:: wait(aws, *, timeout=None, return_when=ALL_COMPLETED) - Run :ref:`awaitable objects ` in the *aws* + Run :class:`~asyncio.Future` and :class:`~asyncio.Task` instances in the *aws* iterable concurrently and block until the condition specified by *return_when*. @@ -567,7 +770,7 @@ Waiting Primitives *timeout* (a float or int), if specified, can be used to control the maximum number of seconds to wait before returning. - Note that this function does not raise :exc:`asyncio.TimeoutError`. + Note that this function does not raise :exc:`TimeoutError`. Futures or Tasks that aren't done when the timeout occurs are simply returned in the second set. @@ -595,58 +798,11 @@ Waiting Primitives Unlike :func:`~asyncio.wait_for`, ``wait()`` does not cancel the futures when a timeout occurs. - .. deprecated:: 3.8 - - If any awaitable in *aws* is a coroutine, it is automatically - scheduled as a Task. Passing coroutines objects to - ``wait()`` directly is deprecated as it leads to - :ref:`confusing behavior `. - - .. deprecated-removed:: 3.8 3.10 - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. - - .. _asyncio_example_wait_coroutine: - .. note:: - - ``wait()`` schedules coroutines as Tasks automatically and later - returns those implicitly created Task objects in ``(done, pending)`` - sets. Therefore the following code won't work as expected:: - - async def foo(): - return 42 - - coro = foo() - done, pending = await asyncio.wait({coro}) - - if coro in done: - # This branch will never be run! - - Here is how the above snippet can be fixed:: - - async def foo(): - return 42 - - task = asyncio.create_task(foo()) - done, pending = await asyncio.wait({task}) - - if task in done: - # Everything will work as expected now. - - .. deprecated-removed:: 3.8 3.10 - - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. - - .. deprecated-removed:: 3.8 3.11 - - Passing coroutine objects to ``wait()`` directly is - deprecated. + .. versionchanged:: 3.10 + Removed the *loop* parameter. + .. versionchanged:: 3.11 + Passing coroutine objects to ``wait()`` directly is forbidden. .. function:: as_completed(aws, *, timeout=None) @@ -655,14 +811,11 @@ Waiting Primitives Each coroutine returned can be awaited to get the earliest next result from the iterable of the remaining awaitables. - Raises :exc:`asyncio.TimeoutError` if the timeout occurs before + Raises :exc:`TimeoutError` if the timeout occurs before all Futures are done. - .. deprecated-removed:: 3.8 3.10 - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. versionchanged:: 3.10 + Removed the *loop* parameter. Example:: @@ -670,11 +823,8 @@ Waiting Primitives earliest_result = await coro # ... - .. deprecated-removed:: 3.8 3.10 - The ``loop`` parameter. This function has been implicitly getting the - current running loop since 3.7. See - :ref:`What's New in 3.10's Removed section ` - for more information. + .. versionchanged:: 3.10 + Removed the *loop* parameter. .. deprecated:: 3.10 Deprecation warning is emitted if not all awaitable objects in the *aws* @@ -725,17 +875,17 @@ Running in Threads # blocking_io complete at 19:50:54 # finished main at 19:50:54 - Directly calling `blocking_io()` in any coroutine would block the event loop + Directly calling ``blocking_io()`` in any coroutine would block the event loop for its duration, resulting in an additional 1 second of run time. Instead, - by using `asyncio.to_thread()`, we can run it in a separate thread without + by using ``asyncio.to_thread()``, we can run it in a separate thread without blocking the event loop. .. note:: - Due to the :term:`GIL`, `asyncio.to_thread()` can typically only be used + Due to the :term:`GIL`, ``asyncio.to_thread()`` can typically only be used to make IO-bound functions non-blocking. However, for extension modules that release the GIL or alternative Python implementations that don't - have one, `asyncio.to_thread()` can also be used for CPU-bound functions. + have one, ``asyncio.to_thread()`` can also be used for CPU-bound functions. .. versionadded:: 3.9 @@ -768,7 +918,7 @@ Scheduling From Other Threads try: result = future.result(timeout) - except concurrent.futures.TimeoutError: + except TimeoutError: print('The coroutine took too long, cancelling the task...') future.cancel() except Exception as exc: @@ -857,80 +1007,12 @@ Task Object Added support for the :mod:`contextvars` module. .. versionchanged:: 3.8 - Added the ``name`` parameter. - - .. deprecated-removed:: 3.8 3.10 - The *loop* parameter. + Added the *name* parameter. .. deprecated:: 3.10 Deprecation warning is emitted if *loop* is not specified and there is no running event loop. - .. method:: cancel(msg=None) - - Request the Task to be cancelled. - - This arranges for a :exc:`CancelledError` exception to be thrown - into the wrapped coroutine on the next cycle of the event loop. - - The coroutine then has a chance to clean up or even deny the - request by suppressing the exception with a :keyword:`try` ... - ... ``except CancelledError`` ... :keyword:`finally` block. - Therefore, unlike :meth:`Future.cancel`, :meth:`Task.cancel` does - not guarantee that the Task will be cancelled, although - suppressing cancellation completely is not common and is actively - discouraged. - - .. versionchanged:: 3.9 - Added the ``msg`` parameter. - - .. _asyncio_example_task_cancel: - - The following example illustrates how coroutines can intercept - the cancellation request:: - - async def cancel_me(): - print('cancel_me(): before sleep') - - try: - # Wait for 1 hour - await asyncio.sleep(3600) - except asyncio.CancelledError: - print('cancel_me(): cancel sleep') - raise - finally: - print('cancel_me(): after sleep') - - async def main(): - # Create a "cancel_me" Task - task = asyncio.create_task(cancel_me()) - - # Wait for 1 second - await asyncio.sleep(1) - - task.cancel() - try: - await task - except asyncio.CancelledError: - print("main(): cancel_me is cancelled now") - - asyncio.run(main()) - - # Expected output: - # - # cancel_me(): before sleep - # cancel_me(): cancel sleep - # cancel_me(): after sleep - # main(): cancel_me is cancelled now - - .. method:: cancelled() - - Return ``True`` if the Task is *cancelled*. - - The Task is *cancelled* when the cancellation was requested with - :meth:`cancel` and the wrapped coroutine propagated the - :exc:`CancelledError` exception thrown into it. - .. method:: done() Return ``True`` if the Task is *done*. @@ -1023,6 +1105,13 @@ Task Object .. versionadded:: 3.8 + .. method:: get_context() + + Return the :class:`contextvars.Context` object + associated with the task. + + .. versionadded:: 3.12 + .. method:: get_name() Return the name of the Task. @@ -1044,3 +1133,123 @@ Task Object in the :func:`repr` output of a task object. .. versionadded:: 3.8 + + .. method:: cancel(msg=None) + + Request the Task to be cancelled. + + This arranges for a :exc:`CancelledError` exception to be thrown + into the wrapped coroutine on the next cycle of the event loop. + + The coroutine then has a chance to clean up or even deny the + request by suppressing the exception with a :keyword:`try` ... + ... ``except CancelledError`` ... :keyword:`finally` block. + Therefore, unlike :meth:`Future.cancel`, :meth:`Task.cancel` does + not guarantee that the Task will be cancelled, although + suppressing cancellation completely is not common and is actively + discouraged. + + .. versionchanged:: 3.9 + Added the *msg* parameter. + + .. versionchanged:: 3.11 + The ``msg`` parameter is propagated from cancelled task to its awaiter. + + .. _asyncio_example_task_cancel: + + The following example illustrates how coroutines can intercept + the cancellation request:: + + async def cancel_me(): + print('cancel_me(): before sleep') + + try: + # Wait for 1 hour + await asyncio.sleep(3600) + except asyncio.CancelledError: + print('cancel_me(): cancel sleep') + raise + finally: + print('cancel_me(): after sleep') + + async def main(): + # Create a "cancel_me" Task + task = asyncio.create_task(cancel_me()) + + # Wait for 1 second + await asyncio.sleep(1) + + task.cancel() + try: + await task + except asyncio.CancelledError: + print("main(): cancel_me is cancelled now") + + asyncio.run(main()) + + # Expected output: + # + # cancel_me(): before sleep + # cancel_me(): cancel sleep + # cancel_me(): after sleep + # main(): cancel_me is cancelled now + + .. method:: cancelled() + + Return ``True`` if the Task is *cancelled*. + + The Task is *cancelled* when the cancellation was requested with + :meth:`cancel` and the wrapped coroutine propagated the + :exc:`CancelledError` exception thrown into it. + + .. method:: uncancel() + + Decrement the count of cancellation requests to this Task. + + Returns the remaining number of cancellation requests. + + Note that once execution of a cancelled task completed, further + calls to :meth:`uncancel` are ineffective. + + .. versionadded:: 3.11 + + This method is used by asyncio's internals and isn't expected to be + used by end-user code. In particular, if a Task gets successfully + uncancelled, this allows for elements of structured concurrency like + :ref:`taskgroups` and :func:`asyncio.timeout` to continue running, + isolating cancellation to the respective structured block. + For example:: + + async def make_request_with_timeout(): + try: + async with asyncio.timeout(1): + # Structured block affected by the timeout: + await make_request() + await make_another_request() + except TimeoutError: + log("There was a timeout") + # Outer code not affected by the timeout: + await unrelated_code() + + While the block with ``make_request()`` and ``make_another_request()`` + might get cancelled due to the timeout, ``unrelated_code()`` should + continue running even in case of the timeout. This is implemented + with :meth:`uncancel`. :class:`TaskGroup` context managers use + :func:`uncancel` in a similar fashion. + + .. method:: cancelling() + + Return the number of pending cancellation requests to this Task, i.e., + the number of calls to :meth:`cancel` less the number of + :meth:`uncancel` calls. + + Note that if this number is greater than zero but the Task is + still executing, :meth:`cancelled` will still return ``False``. + This is because this number can be lowered by calling :meth:`uncancel`, + which can lead to the task not being cancelled after all if the + cancellation requests go down to zero. + + This method is used by asyncio's internals and isn't expected to be + used by end-user code. See :meth:`uncancel` for more details. + + .. versionadded:: 3.11 diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst index 94a853259d3..c6a046f534e 100644 --- a/Doc/library/asyncio.rst +++ b/Doc/library/asyncio.rst @@ -17,7 +17,6 @@ await asyncio.sleep(1) print('... World!') - # Python 3.7+ asyncio.run(main()) asyncio is a library to write **concurrent** code using @@ -57,6 +56,19 @@ Additionally, there are **low-level** APIs for * :ref:`bridge ` callback-based libraries and code with async/await syntax. +You can experiment with an ``asyncio`` concurrent context in the REPL: + +.. code-block:: pycon + + $ python -m asyncio + asyncio REPL ... + Use "await" directly instead of "asyncio.run()". + Type "help", "copyright", "credits" or "license" for more information. + >>> import asyncio + >>> await asyncio.sleep(10, result='hello') + 'hello' + +.. include:: ../includes/wasm-notavail.rst .. We use the "rubric" directive here to avoid creating the "Reference" subsection in the TOC. @@ -67,6 +79,7 @@ Additionally, there are **low-level** APIs for :caption: High-level APIs :maxdepth: 1 + asyncio-runner.rst asyncio-task.rst asyncio-stream.rst asyncio-sync.rst @@ -83,6 +96,7 @@ Additionally, there are **low-level** APIs for asyncio-protocol.rst asyncio-policy.rst asyncio-platforms.rst + asyncio-extending.rst .. toctree:: :caption: Guides and Tutorials diff --git a/Doc/library/audioop.rst b/Doc/library/audioop.rst index bad9da2ec62..1f96575d08f 100644 --- a/Doc/library/audioop.rst +++ b/Doc/library/audioop.rst @@ -3,6 +3,11 @@ .. module:: audioop :synopsis: Manipulate raw audio data. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + The :mod:`audioop` module is deprecated + (see :pep:`PEP 594 <594#audioop>` for details). -------------- diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst index 4ff038c8d29..4ca3768f827 100644 --- a/Doc/library/base64.rst +++ b/Doc/library/base64.rst @@ -53,11 +53,13 @@ The modern interface provides: Encode the :term:`bytes-like object` *s* using Base64 and return the encoded :class:`bytes`. - Optional *altchars* must be a :term:`bytes-like object` of at least - length 2 (additional characters are ignored) which specifies an alternative - alphabet for the ``+`` and ``/`` characters. This allows an application to e.g. - generate URL or filesystem safe Base64 strings. The default is ``None``, for - which the standard Base64 alphabet is used. + Optional *altchars* must be a :term:`bytes-like object` of length 2 which + specifies an alternative alphabet for the ``+`` and ``/`` characters. + This allows an application to e.g. generate URL or filesystem safe Base64 + strings. The default is ``None``, for which the standard Base64 alphabet is used. + + May assert or raise a a :exc:`ValueError` if the length of *altchars* is not 2. Raises a + :exc:`TypeError` if *altchars* is not a :term:`bytes-like object`. .. function:: b64decode(s, altchars=None, validate=False) @@ -65,9 +67,9 @@ The modern interface provides: Decode the Base64 encoded :term:`bytes-like object` or ASCII string *s* and return the decoded :class:`bytes`. - Optional *altchars* must be a :term:`bytes-like object` or ASCII string of - at least length 2 (additional characters are ignored) which specifies the - alternative alphabet used instead of the ``+`` and ``/`` characters. + Optional *altchars* must be a :term:`bytes-like object` or ASCII string + of length 2 which specifies the alternative alphabet used instead of the + ``+`` and ``/`` characters. A :exc:`binascii.Error` exception is raised if *s* is incorrectly padded. @@ -80,6 +82,7 @@ The modern interface provides: For more information about the strict base64 check, see :func:`binascii.a2b_base64` + May assert or raise a :exc:`ValueError` if the length of *altchars* is not 2. .. function:: standard_b64encode(s) @@ -201,7 +204,7 @@ The modern interface provides: .. versionadded:: 3.4 -.. function:: a85decode(b, *, foldspaces=False, adobe=False, ignorechars=b' \\t\\n\\r\\v') +.. function:: a85decode(b, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v') Decode the Ascii85 encoded :term:`bytes-like object` or ASCII string *b* and return the decoded :class:`bytes`. diff --git a/Doc/library/bdb.rst b/Doc/library/bdb.rst index 7e4066cd436..d201dc963b5 100644 --- a/Doc/library/bdb.rst +++ b/Doc/library/bdb.rst @@ -20,20 +20,21 @@ The following exception is defined: The :mod:`bdb` module also defines two classes: -.. class:: Breakpoint(self, file, line, temporary=0, cond=None, funcname=None) +.. class:: Breakpoint(self, file, line, temporary=False, cond=None, funcname=None) This class implements temporary breakpoints, ignore counts, disabling and (re-)enabling, and conditionals. Breakpoints are indexed by number through a list called :attr:`bpbynumber` - and by ``(file, line)`` pairs through :attr:`bplist`. The former points to a - single instance of class :class:`Breakpoint`. The latter points to a list of - such instances since there may be more than one breakpoint per line. + and by ``(file, line)`` pairs through :attr:`bplist`. The former points to + a single instance of class :class:`Breakpoint`. The latter points to a list + of such instances since there may be more than one breakpoint per line. - When creating a breakpoint, its associated filename should be in canonical - form. If a *funcname* is defined, a breakpoint hit will be counted when the - first line of that function is executed. A conditional breakpoint always - counts a hit. + When creating a breakpoint, its associated :attr:`file name ` should + be in canonical form. If a :attr:`funcname` is defined, a breakpoint + :attr:`hit ` will be counted when the first line of that function is + executed. A :attr:`conditional ` breakpoint always counts a + :attr:`hit `. :class:`Breakpoint` instances have the following methods: @@ -59,12 +60,12 @@ The :mod:`bdb` module also defines two classes: Return a string with all the information about the breakpoint, nicely formatted: - * The breakpoint number. - * If it is temporary or not. - * Its file,line position. - * The condition that causes a break. - * If it must be ignored the next N times. - * The breakpoint hit count. + * Breakpoint number. + * Temporary status (del or keep). + * File/line position. + * Break condition. + * Number of times to ignore. + * Number of times hit. .. versionadded:: 3.2 @@ -73,6 +74,49 @@ The :mod:`bdb` module also defines two classes: Print the output of :meth:`bpformat` to the file *out*, or if it is ``None``, to standard output. + :class:`Breakpoint` instances have the following attributes: + + .. attribute:: file + + File name of the :class:`Breakpoint`. + + .. attribute:: line + + Line number of the :class:`Breakpoint` within :attr:`file`. + + .. attribute:: temporary + + True if a :class:`Breakpoint` at (file, line) is temporary. + + .. attribute:: cond + + Condition for evaluating a :class:`Breakpoint` at (file, line). + + .. attribute:: funcname + + Function name that defines whether a :class:`Breakpoint` is hit upon + entering the function. + + .. attribute:: enabled + + True if :class:`Breakpoint` is enabled. + + .. attribute:: bpbynumber + + Numeric index for a single instance of a :class:`Breakpoint`. + + .. attribute:: bplist + + Dictionary of :class:`Breakpoint` instances indexed by + (:attr:`file`, :attr:`line`) tuples. + + .. attribute:: ignore + + Number of times to ignore a :class:`Breakpoint`. + + .. attribute:: hits + + Count of the number of times a :class:`Breakpoint` has been hit. .. class:: Bdb(skip=None) @@ -95,9 +139,12 @@ The :mod:`bdb` module also defines two classes: .. method:: canonic(filename) - Auxiliary method for getting a filename in a canonical form, that is, as a - case-normalized (on case-insensitive filesystems) absolute path, stripped - of surrounding angle brackets. + Return canonical form of *filename*. + + For real file names, the canonical form is an operating-system-dependent, + :func:`case-normalized ` :func:`absolute path + `. A *filename* with angle brackets, such as ``""`` + generated in interactive mode, is returned unchanged. .. method:: reset() @@ -166,45 +213,46 @@ The :mod:`bdb` module also defines two classes: Normally derived classes don't override the following methods, but they may if they want to redefine the definition of stopping and breakpoints. + .. method:: is_skipped_line(module_name) + + Return True if *module_name* matches any skip pattern. + .. method:: stop_here(frame) - This method checks if the *frame* is somewhere below :attr:`botframe` in - the call stack. :attr:`botframe` is the frame in which debugging started. + Return True if *frame* is below the starting frame in the stack. .. method:: break_here(frame) - This method checks if there is a breakpoint in the filename and line - belonging to *frame* or, at least, in the current function. If the - breakpoint is a temporary one, this method deletes it. + Return True if there is an effective breakpoint for this line. + + Check whether a line or function breakpoint exists and is in effect. Delete temporary + breakpoints based on information from :func:`effective`. .. method:: break_anywhere(frame) - This method checks if there is a breakpoint in the filename of the current - frame. + Return True if any breakpoint exists for *frame*'s filename. Derived classes should override these methods to gain control over debugger operation. .. method:: user_call(frame, argument_list) - This method is called from :meth:`dispatch_call` when there is the - possibility that a break might be necessary anywhere inside the called - function. + Called from :meth:`dispatch_call` if a break might stop inside the + called function. .. method:: user_line(frame) - This method is called from :meth:`dispatch_line` when either - :meth:`stop_here` or :meth:`break_here` yields ``True``. + Called from :meth:`dispatch_line` when either :meth:`stop_here` or + :meth:`break_here` returns ``True``. .. method:: user_return(frame, return_value) - This method is called from :meth:`dispatch_return` when :meth:`stop_here` - yields ``True``. + Called from :meth:`dispatch_return` when :meth:`stop_here` returns ``True``. .. method:: user_exception(frame, exc_info) - This method is called from :meth:`dispatch_exception` when - :meth:`stop_here` yields ``True``. + Called from :meth:`dispatch_exception` when :meth:`stop_here` + returns ``True``. .. method:: do_clear(arg) @@ -228,9 +276,9 @@ The :mod:`bdb` module also defines two classes: Stop when returning from the given frame. - .. method:: set_until(frame) + .. method:: set_until(frame, lineno=None) - Stop when the line with the line no greater than the current one is + Stop when the line with the *lineno* greater than the current one is reached or when returning from current frame. .. method:: set_trace([frame]) @@ -253,7 +301,7 @@ The :mod:`bdb` module also defines two classes: breakpoints. These methods return a string containing an error message if something went wrong, or ``None`` if all is well. - .. method:: set_break(filename, lineno, temporary=0, cond, funcname) + .. method:: set_break(filename, lineno, temporary=False, cond=None, funcname=None) Set a new breakpoint. If the *lineno* line doesn't exist for the *filename* passed as argument, return an error message. The *filename* @@ -261,8 +309,8 @@ The :mod:`bdb` module also defines two classes: .. method:: clear_break(filename, lineno) - Delete the breakpoints in *filename* and *lineno*. If none were set, an - error message is returned. + Delete the breakpoints in *filename* and *lineno*. If none were set, + return an error message. .. method:: clear_bpbynumber(arg) @@ -272,12 +320,13 @@ The :mod:`bdb` module also defines two classes: .. method:: clear_all_file_breaks(filename) - Delete all breakpoints in *filename*. If none were set, an error message - is returned. + Delete all breakpoints in *filename*. If none were set, return an error + message. .. method:: clear_all_breaks() - Delete all existing breakpoints. + Delete all existing breakpoints. If none were set, return an error + message. .. method:: get_bpbynumber(arg) @@ -290,7 +339,7 @@ The :mod:`bdb` module also defines two classes: .. method:: get_break(filename, lineno) - Check if there is a breakpoint for *lineno* of *filename*. + Return True if there is a breakpoint for *lineno* in *filename*. .. method:: get_breaks(filename, lineno) @@ -311,16 +360,18 @@ The :mod:`bdb` module also defines two classes: .. method:: get_stack(f, t) - Get a list of records for a frame and all higher (calling) and lower - frames, and the size of the higher part. + Return a list of (frame, lineno) tuples in a stack trace, and a size. + + The most recently called frame is last in the list. The size is the number + of frames below the frame where the debugger was invoked. .. method:: format_stack_entry(frame_lineno, lprefix=': ') - Return a string with information about a stack entry, identified by a - ``(frame, lineno)`` tuple: + Return a string with information about a stack entry, which is a + ``(frame, lineno)`` tuple. The return string contains: - * The canonical form of the filename which contains the frame. - * The function name, or ``""``. + * The canonical filename which contains the frame. + * The function name or ``""``. * The input arguments. * The return value. * The line of code (if it exists). @@ -352,20 +403,34 @@ Finally, the module defines the following functions: .. function:: checkfuncname(b, frame) - Check whether we should break here, depending on the way the breakpoint *b* - was set. + Return True if we should break here, depending on the way the + :class:`Breakpoint` *b* was set. - If it was set via line number, it checks if ``b.line`` is the same as the one - in the frame also passed as argument. If the breakpoint was set via function - name, we have to check we are in the right frame (the right function) and if - we are in its first executable line. + If it was set via line number, it checks if + :attr:`b.line ` is the same as the one in *frame*. + If the breakpoint was set via + :attr:`function name `, we have to check we are in + the right *frame* (the right function) and if we are on its first executable + line. .. function:: effective(file, line, frame) - Determine if there is an effective (active) breakpoint at this line of code. - Return a tuple of the breakpoint and a boolean that indicates if it is ok - to delete a temporary breakpoint. Return ``(None, None)`` if there is no - matching breakpoint. + Return ``(active breakpoint, delete temporary flag)`` or ``(None, None)`` as the + breakpoint to act upon. + + The *active breakpoint* is the first entry in + :attr:`bplist ` for the + (:attr:`file `, :attr:`line `) + (which must exist) that is :attr:`enabled `, for + which :func:`checkfuncname` is True, and that has neither a False + :attr:`condition ` nor positive + :attr:`ignore ` count. The *flag*, meaning that a + temporary breakpoint should be deleted, is False only when the + :attr:`cond ` cannot be evaluated (in which case, + :attr:`ignore ` count is ignored). + + If no such entry exists, then (None, None) is returned. + .. function:: set_trace() diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst index 62d7efe34ab..5a0815faa38 100644 --- a/Doc/library/binascii.rst +++ b/Doc/library/binascii.rst @@ -49,7 +49,7 @@ The :mod:`binascii` module defines the following functions: Added the *backtick* parameter. -.. function:: a2b_base64(string, strict_mode=False) +.. function:: a2b_base64(string, /, *, strict_mode=False) Convert a block of base64 data back to binary and return the binary data. More than one line may be passed at a time. @@ -107,7 +107,7 @@ The :mod:`binascii` module defines the following functions: .. function:: crc32(data[, value]) - Compute CRC-32, the 32-bit checksum of *data*, starting with an + Compute CRC-32, the unsigned 32-bit checksum of *data*, starting with an initial CRC of *value*. The default initial CRC is zero. The algorithm is consistent with the ZIP file checksum. Since the algorithm is designed for use as a checksum algorithm, it is not suitable for use as a general hash @@ -121,9 +121,6 @@ The :mod:`binascii` module defines the following functions: .. versionchanged:: 3.0 The result is always unsigned. - To generate the same numeric value across all Python versions and - platforms, use ``crc32(data) & 0xffffffff``. - .. function:: b2a_hex(data[, sep[, bytes_per_sep=1]]) hexlify(data[, sep[, bytes_per_sep=1]]) diff --git a/Doc/library/bisect.rst b/Doc/library/bisect.rst index f34ee175ba6..b85564f1786 100644 --- a/Doc/library/bisect.rst +++ b/Doc/library/bisect.rst @@ -13,10 +13,16 @@ This module provides support for maintaining a list in sorted order without having to sort the list after each insertion. For long lists of items with -expensive comparison operations, this can be an improvement over the more common -approach. The module is called :mod:`bisect` because it uses a basic bisection -algorithm to do its work. The source code may be most useful as a working -example of the algorithm (the boundary conditions are already right!). +expensive comparison operations, this can be an improvement over +linear searches or frequent resorting. + +The module is called :mod:`bisect` because it uses a basic bisection +algorithm to do its work. Unlike other bisection tools that search for a +specific value, the functions in this module are designed to locate an +insertion point. Accordingly, the functions never call an :meth:`__eq__` +method to determine whether a value has been found. Instead, the +functions only call the :meth:`__lt__` method and will return an insertion +point between values in an array. The following functions are provided: @@ -30,31 +36,31 @@ The following functions are provided: any existing entries. The return value is suitable for use as the first parameter to ``list.insert()`` assuming that *a* is already sorted. - The returned insertion point *i* partitions the array *a* into two halves so - that ``all(val < x for val in a[lo : i])`` for the left side and - ``all(val >= x for val in a[i : hi])`` for the right side. + The returned insertion point *ip* partitions the array *a* into two + slices such that ``all(elem < x for elem in a[lo : ip])`` is true for the + left slice and ``all(elem >= x for elem in a[ip : hi])`` is true for the + right slice. *key* specifies a :term:`key function` of one argument that is used to - extract a comparison key from each input element. The default value is - ``None`` (compare the elements directly). + extract a comparison key from each element in the array. To support + searching complex records, the key function is not applied to the *x* value. + + If *key* is ``None``, the elements are compared directly and + no key function is called. .. versionchanged:: 3.10 Added the *key* parameter. .. function:: bisect_right(a, x, lo=0, hi=len(a), *, key=None) - bisect(a, x, lo=0, hi=len(a)) + bisect(a, x, lo=0, hi=len(a), *, key=None) Similar to :func:`bisect_left`, but returns an insertion point which comes after (to the right of) any existing entries of *x* in *a*. - The returned insertion point *i* partitions the array *a* into two halves so - that ``all(val <= x for val in a[lo : i])`` for the left side and - ``all(val > x for val in a[i : hi])`` for the right side. - - *key* specifies a :term:`key function` of one argument that is used to - extract a comparison key from each input element. The default value is - ``None`` (compare the elements directly). + The returned insertion point *ip* partitions the array *a* into two slices + such that ``all(elem <= x for elem in a[lo : ip])`` is true for the left slice and + ``all(elem > x for elem in a[ip : hi])`` is true for the right slice. .. versionchanged:: 3.10 Added the *key* parameter. @@ -64,14 +70,13 @@ The following functions are provided: Insert *x* in *a* in sorted order. - *key* specifies a :term:`key function` of one argument that is used to - extract a comparison key from each input element. The default value is - ``None`` (compare the elements directly). - This function first runs :func:`bisect_left` to locate an insertion point. Next, it runs the :meth:`insert` method on *a* to insert *x* at the appropriate position to maintain sort order. + To support inserting records in a table, the *key* function (if any) is + applied to *x* for the search step but not for the insertion step. + Keep in mind that the ``O(log n)`` search is dominated by the slow O(n) insertion step. @@ -80,19 +85,18 @@ The following functions are provided: .. function:: insort_right(a, x, lo=0, hi=len(a), *, key=None) - insort(a, x, lo=0, hi=len(a)) + insort(a, x, lo=0, hi=len(a), *, key=None) Similar to :func:`insort_left`, but inserting *x* in *a* after any existing entries of *x*. - *key* specifies a :term:`key function` of one argument that is used to - extract a comparison key from each input element. The default value is - ``None`` (compare the elements directly). - This function first runs :func:`bisect_right` to locate an insertion point. Next, it runs the :meth:`insert` method on *a* to insert *x* at the appropriate position to maintain sort order. + To support inserting records in a table, the *key* function (if any) is + applied to *x* for the search step but not for the insertion step. + Keep in mind that the ``O(log n)`` search is dominated by the slow O(n) insertion step. @@ -123,7 +127,7 @@ thoughts in mind: .. seealso:: * `Sorted Collections - `_ is a high performance + `_ is a high performance module that uses *bisect* to managed sorted collections of data. * The `SortedCollection recipe @@ -194,8 +198,42 @@ a 'B', and so on:: >>> [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]] ['F', 'A', 'C', 'C', 'B', 'A', 'A'] -One technique to avoid repeated calls to a key function is to search a list of -precomputed keys to find the index of a record:: +The :func:`bisect` and :func:`insort` functions also work with lists of +tuples. The *key* argument can serve to extract the field used for ordering +records in a table:: + + >>> from collections import namedtuple + >>> from operator import attrgetter + >>> from bisect import bisect, insort + >>> from pprint import pprint + + >>> Movie = namedtuple('Movie', ('name', 'released', 'director')) + + >>> movies = [ + ... Movie('Jaws', 1975, 'Speilberg'), + ... Movie('Titanic', 1997, 'Cameron'), + ... Movie('The Birds', 1963, 'Hitchcock'), + ... Movie('Aliens', 1986, 'Scott') + ... ] + + >>> # Find the first movie released after 1960 + >>> by_year = attrgetter('released') + >>> movies.sort(key=by_year) + >>> movies[bisect(movies, 1960, key=by_year)] + Movie(name='The Birds', released=1963, director='Hitchcock') + + >>> # Insert a movie while maintaining sort order + >>> romance = Movie('Love Story', 1970, 'Hiller') + >>> insort(movies, romance, key=by_year) + >>> pprint(movies) + [Movie(name='The Birds', released=1963, director='Hitchcock'), + Movie(name='Love Story', released=1970, director='Hiller'), + Movie(name='Jaws', released=1975, director='Speilberg'), + Movie(name='Aliens', released=1986, director='Scott'), + Movie(name='Titanic', released=1997, director='Cameron')] + +If the key function is expensive, it is possible to avoid repeated function +calls by searching a list of precomputed keys to find the index of a record:: >>> data = [('red', 5), ('blue', 1), ('yellow', 8), ('black', 0)] >>> data.sort(key=lambda r: r[1]) # Or use operator.itemgetter(1). @@ -208,4 +246,3 @@ precomputed keys to find the index of a record:: ('red', 5) >>> data[bisect_left(keys, 8)] ('yellow', 8) - diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst index 999892e95f4..32df99869eb 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -206,7 +206,7 @@ Incremental (de)compression will be set to ``True``. Attempting to decompress data after the end of stream is reached - raises an `EOFError`. Any data found after the end of the + raises an :exc:`EOFError`. Any data found after the end of the stream is ignored and saved in the :attr:`~.unused_data` attribute. .. versionchanged:: 3.5 @@ -303,7 +303,7 @@ Using :class:`BZ2Compressor` for incremental compression: >>> out = out + comp.flush() The example above uses a very "nonrandom" stream of data -(a stream of `b"z"` chunks). Random data tends to compress poorly, +(a stream of ``b"z"`` chunks). Random data tends to compress poorly, while ordered, repetitive data usually yields a high compression ratio. Writing and reading a bzip2-compressed file in binary mode: @@ -320,9 +320,11 @@ Writing and reading a bzip2-compressed file in binary mode: >>> with bz2.open("myfile.bz2", "wb") as f: ... # Write compressed data to file ... unused = f.write(data) + ... >>> with bz2.open("myfile.bz2", "rb") as f: ... # Decompress data from file ... content = f.read() + ... >>> content == data # Check equality to original object after round-trip True diff --git a/Doc/library/calendar.rst b/Doc/library/calendar.rst index 6050ff5607a..66f59f0e2ce 100644 --- a/Doc/library/calendar.rst +++ b/Doc/library/calendar.rst @@ -31,7 +31,7 @@ interpreted as prescribed by the ISO 8601 standard. Year 0 is 1 BC, year -1 is .. class:: Calendar(firstweekday=0) Creates a :class:`Calendar` object. *firstweekday* is an integer specifying the - first day of the week. ``0`` is Monday (the default), ``6`` is Sunday. + first day of the week. :const:`MONDAY` is ``0`` (the default), :const:`SUNDAY` is ``6``. A :class:`Calendar` object provides several methods that can be used for preparing the calendar data for formatting. This class doesn't do any formatting @@ -289,9 +289,10 @@ interpreted as prescribed by the ISO 8601 standard. Year 0 is 1 BC, year -1 is .. note:: - The :meth:`formatweekday` and :meth:`formatmonthname` methods of these two - classes temporarily change the current locale to the given *locale*. Because - the current locale is a process-wide setting, they are not thread-safe. + The constructor, :meth:`formatweekday` and :meth:`formatmonthname` methods + of these two classes temporarily change the ``LC_TIME`` locale to the given + *locale*. Because the current locale is a process-wide setting, they are + not thread-safe. For simple text calendars this module provides the following functions. @@ -406,6 +407,15 @@ The :mod:`calendar` module exports the following data attributes: locale. This follows normal convention of January being month number 1, so it has a length of 13 and ``month_abbr[0]`` is the empty string. +.. data:: MONDAY + TUESDAY + WEDNESDAY + THURSDAY + FRIDAY + SATURDAY + SUNDAY + + Aliases for day numbers, where ``MONDAY`` is ``0`` and ``SUNDAY`` is ``6``. .. seealso:: diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst index c151f04dfb8..295a601a7bf 100644 --- a/Doc/library/cgi.rst +++ b/Doc/library/cgi.rst @@ -3,6 +3,7 @@ .. module:: cgi :synopsis: Helpers for running Python scripts via the Common Gateway Interface. + :deprecated: **Source code:** :source:`Lib/cgi.py` @@ -14,6 +15,16 @@ single: URL single: Common Gateway Interface +.. deprecated-removed:: 3.11 3.13 + The :mod:`cgi` module is deprecated + (see :pep:`PEP 594 <594#cgi>` for details and alternatives). + + The :class:`FieldStorage` class can typically be replaced with + :func:`urllib.parse.parse_qsl` for ``GET`` and ``HEAD`` requests, + and the :mod:`email.message` module or + `multipart `_ for ``POST`` and ``PUT``. + Most :ref:`utility functions ` have replacements. + -------------- Support module for Common Gateway Interface (CGI) scripts. @@ -21,6 +32,12 @@ Support module for Common Gateway Interface (CGI) scripts. This module defines a number of utilities for use by CGI scripts written in Python. +The global variable ``maxlen`` can be set to an integer indicating the maximum +size of a POST request. POST requests larger than this size will result in a +:exc:`ValueError` being raised during parsing. The default value of this +variable is ``0``, meaning the request size is unlimited. + +.. include:: ../includes/wasm-notavail.rst Introduction ------------ @@ -283,6 +300,12 @@ algorithms implemented in this module in other circumstances. ``sys.stdin``). The *keep_blank_values*, *strict_parsing* and *separator* parameters are passed to :func:`urllib.parse.parse_qs` unchanged. + .. deprecated-removed:: 3.11 3.13 + This function, like the rest of the :mod:`cgi` module, is deprecated. + It can be replaced by calling :func:`urllib.parse.parse_qs` directly + on the desired query string (except for ``multipart/form-data`` input, + which can be handled as described for :func:`parse_multipart`). + .. function:: parse_multipart(fp, pdict, encoding="utf-8", errors="replace", separator="&") @@ -306,12 +329,31 @@ algorithms implemented in this module in other circumstances. .. versionchanged:: 3.10 Added the *separator* parameter. + .. deprecated-removed:: 3.11 3.13 + This function, like the rest of the :mod:`cgi` module, is deprecated. + It can be replaced with the functionality in the :mod:`email` package + (e.g. :class:`email.message.EmailMessage`/:class:`email.message.Message`) + which implements the same MIME RFCs, or with the + `multipart `__ PyPI project. + .. function:: parse_header(string) Parse a MIME header (such as :mailheader:`Content-Type`) into a main value and a dictionary of parameters. + .. deprecated-removed:: 3.11 3.13 + This function, like the rest of the :mod:`cgi` module, is deprecated. + It can be replaced with the functionality in the :mod:`email` package, + which implements the same MIME RFCs. + + For example, with :class:`email.message.EmailMessage`:: + + from email.message import EmailMessage + msg = EmailMessage() + msg['content-type'] = 'application/json; charset="utf8"' + main, params = msg.get_content_type(), msg['content-type'].params + .. function:: test() diff --git a/Doc/library/cgitb.rst b/Doc/library/cgitb.rst index 5f3a6476dd8..7f00bcd55c1 100644 --- a/Doc/library/cgitb.rst +++ b/Doc/library/cgitb.rst @@ -3,6 +3,7 @@ .. module:: cgitb :synopsis: Configurable traceback handler for CGI scripts. + :deprecated: .. moduleauthor:: Ka-Ping Yee .. sectionauthor:: Fred L. Drake, Jr. @@ -15,6 +16,10 @@ single: exceptions; in CGI scripts single: tracebacks; in CGI scripts +.. deprecated-removed:: 3.11 3.13 + The :mod:`cgitb` module is deprecated + (see :pep:`PEP 594 <594#cgitb>` for details). + -------------- The :mod:`cgitb` module provides a special exception handler for Python scripts. diff --git a/Doc/library/chunk.rst b/Doc/library/chunk.rst index 5e24df923ed..3b88e55b147 100644 --- a/Doc/library/chunk.rst +++ b/Doc/library/chunk.rst @@ -3,6 +3,7 @@ .. module:: chunk :synopsis: Module to read IFF chunks. + :deprecated: .. moduleauthor:: Sjoerd Mullender .. sectionauthor:: Sjoerd Mullender @@ -16,6 +17,10 @@ single: Real Media File Format single: RMFF +.. deprecated-removed:: 3.11 3.13 + The :mod:`chunk` module is deprecated + (see :pep:`PEP 594 <594#chunk>` for details). + -------------- This module provides an interface for reading files that use EA IFF 85 chunks. diff --git a/Doc/library/cmath.rst b/Doc/library/cmath.rst index 28cd96b0e12..c575b90e646 100644 --- a/Doc/library/cmath.rst +++ b/Doc/library/cmath.rst @@ -89,7 +89,7 @@ Power and logarithmic functions logarithms. -.. function:: log(x[, base]) +.. function:: log(x, base=None) Returns the logarithm of *x* to the given *base*. If the *base* is not specified, returns the natural logarithm of *x*. There is one branch cut, from 0 diff --git a/Doc/library/cmd.rst b/Doc/library/cmd.rst index d57edb7eb16..fd5df96dfd0 100644 --- a/Doc/library/cmd.rst +++ b/Doc/library/cmd.rst @@ -121,6 +121,13 @@ A :class:`Cmd` instance has the following methods: :meth:`complete_\*` method is available. By default, it returns an empty list. +.. method:: Cmd.columnize(list, displaywidth=80) + + Method called to display a list of strings as a compact set of columns. + Each column is only as wide as necessary. + Columns are separated by two spaces for readability. + + .. method:: Cmd.precmd(line) Hook method executed just before the command line *line* is interpreted, but diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index 949288b7c6d..8225236350d 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -23,11 +23,11 @@ This module defines base classes for standard Python codecs (encoders and decoders) and provides access to the internal Python codec registry, which manages the codec and error handling lookup process. Most standard codecs -are :term:`text encodings `, which encode text to bytes, -but there are also codecs provided that encode text to text, and bytes to -bytes. Custom codecs may encode and decode between arbitrary types, but some -module features are restricted to use specifically with -:term:`text encodings `, or with codecs that encode to +are :term:`text encodings `, which encode text to bytes (and +decode bytes to text), but there are also codecs provided that encode text to +text, and bytes to bytes. Custom codecs may encode and decode between arbitrary +types, but some module features are restricted to be used specifically with +:term:`text encodings ` or with codecs that encode to :class:`bytes`. The module defines the following functions for encoding and decoding with @@ -189,7 +189,8 @@ wider range of codecs when working with binary files: .. note:: - Underlying encoded files are always opened in binary mode. + If *encoding* is not ``None``, then the + underlying encoded files are always opened in binary mode. No automatic conversion of ``'\n'`` is done on reading and writing. The *mode* argument may be any binary mode acceptable to the built-in :func:`open` function; the ``'b'`` is automatically added. @@ -300,58 +301,56 @@ codec will handle encoding and decoding errors. Error Handlers ^^^^^^^^^^^^^^ -To simplify and standardize error handling, -codecs may implement different error handling schemes by -accepting the *errors* string argument. The following string values are -defined and implemented by all standard Python codecs: +To simplify and standardize error handling, codecs may implement different +error handling schemes by accepting the *errors* string argument: + + >>> 'German ß, ♬'.encode(encoding='ascii', errors='backslashreplace') + b'German \\xdf, \\u266c' + >>> 'German ß, ♬'.encode(encoding='ascii', errors='xmlcharrefreplace') + b'German ß, ♬' + +.. index:: + pair: strict; error handler's name + pair: ignore; error handler's name + pair: replace; error handler's name + pair: backslashreplace; error handler's name + pair: surrogateescape; error handler's name + single: ? (question mark); replacement character + single: \ (backslash); escape sequence + single: \x; escape sequence + single: \u; escape sequence + single: \U; escape sequence + +The following error handlers can be used with all Python +:ref:`standard-encodings` codecs: .. tabularcolumns:: |l|L| +-------------------------+-----------------------------------------------+ | Value | Meaning | +=========================+===============================================+ -| ``'strict'`` | Raise :exc:`UnicodeError` (or a subclass); | +| ``'strict'`` | Raise :exc:`UnicodeError` (or a subclass), | | | this is the default. Implemented in | | | :func:`strict_errors`. | +-------------------------+-----------------------------------------------+ -| ``'ignore'`` | Ignore the malformed data and continue | -| | without further notice. Implemented in | +| ``'ignore'`` | Ignore the malformed data and continue without| +| | further notice. Implemented in | | | :func:`ignore_errors`. | +-------------------------+-----------------------------------------------+ - -The following error handlers are only applicable to -:term:`text encodings `: - -.. index:: - single: ? (question mark); replacement character - single: \ (backslash); escape sequence - single: \x; escape sequence - single: \u; escape sequence - single: \U; escape sequence - single: \N; escape sequence - -+-------------------------+-----------------------------------------------+ -| Value | Meaning | -+=========================+===============================================+ -| ``'replace'`` | Replace with a suitable replacement | -| | marker; Python will use the official | -| | ``U+FFFD`` REPLACEMENT CHARACTER for the | -| | built-in codecs on decoding, and '?' on | -| | encoding. Implemented in | +| ``'replace'`` | Replace with a replacement marker. On | +| | encoding, use ``?`` (ASCII character). On | +| | decoding, use ``�`` (U+FFFD, the official | +| | REPLACEMENT CHARACTER). Implemented in | | | :func:`replace_errors`. | +-------------------------+-----------------------------------------------+ -| ``'xmlcharrefreplace'`` | Replace with the appropriate XML character | -| | reference (only for encoding). Implemented | -| | in :func:`xmlcharrefreplace_errors`. | -+-------------------------+-----------------------------------------------+ | ``'backslashreplace'`` | Replace with backslashed escape sequences. | +| | On encoding, use hexadecimal form of Unicode | +| | code point with formats ``\xhh`` ``\uxxxx`` | +| | ``\Uxxxxxxxx``. On decoding, use hexadecimal | +| | form of byte value with format ``\xhh``. | | | Implemented in | | | :func:`backslashreplace_errors`. | +-------------------------+-----------------------------------------------+ -| ``'namereplace'`` | Replace with ``\N{...}`` escape sequences | -| | (only for encoding). Implemented in | -| | :func:`namereplace_errors`. | -+-------------------------+-----------------------------------------------+ | ``'surrogateescape'`` | On decoding, replace byte with individual | | | surrogate code ranging from ``U+DC80`` to | | | ``U+DCFF``. This code will then be turned | @@ -361,27 +360,55 @@ The following error handlers are only applicable to | | more.) | +-------------------------+-----------------------------------------------+ +.. index:: + pair: xmlcharrefreplace; error handler's name + pair: namereplace; error handler's name + single: \N; escape sequence + +The following error handlers are only applicable to encoding (within +:term:`text encodings `): + ++-------------------------+-----------------------------------------------+ +| Value | Meaning | ++=========================+===============================================+ +| ``'xmlcharrefreplace'`` | Replace with XML/HTML numeric character | +| | reference, which is a decimal form of Unicode | +| | code point with format ``&#num;`` Implemented | +| | in :func:`xmlcharrefreplace_errors`. | ++-------------------------+-----------------------------------------------+ +| ``'namereplace'`` | Replace with ``\N{...}`` escape sequences, | +| | what appears in the braces is the Name | +| | property from Unicode Character Database. | +| | Implemented in :func:`namereplace_errors`. | ++-------------------------+-----------------------------------------------+ + +.. index:: + pair: surrogatepass; error handler's name + In addition, the following error handler is specific to the given codecs: +-------------------+------------------------+-------------------------------------------+ | Value | Codecs | Meaning | +===================+========================+===========================================+ -|``'surrogatepass'``| utf-8, utf-16, utf-32, | Allow encoding and decoding of surrogate | -| | utf-16-be, utf-16-le, | codes. These codecs normally treat the | -| | utf-32-be, utf-32-le | presence of surrogates as an error. | +|``'surrogatepass'``| utf-8, utf-16, utf-32, | Allow encoding and decoding surrogate code| +| | utf-16-be, utf-16-le, | point (``U+D800`` - ``U+DFFF``) as normal | +| | utf-32-be, utf-32-le | code point. Otherwise these codecs treat | +| | | the presence of surrogate code point in | +| | | :class:`str` as an error. | +-------------------+------------------------+-------------------------------------------+ .. versionadded:: 3.1 The ``'surrogateescape'`` and ``'surrogatepass'`` error handlers. .. versionchanged:: 3.4 - The ``'surrogatepass'`` error handlers now works with utf-16\* and utf-32\* codecs. + The ``'surrogatepass'`` error handler now works with utf-16\* and utf-32\* + codecs. .. versionadded:: 3.5 The ``'namereplace'`` error handler. .. versionchanged:: 3.5 - The ``'backslashreplace'`` error handlers now works with decoding and + The ``'backslashreplace'`` error handler now works with decoding and translating. The set of allowed values can be extended by registering a new named error @@ -424,42 +451,59 @@ functions: .. function:: strict_errors(exception) - Implements the ``'strict'`` error handling: each encoding or - decoding error raises a :exc:`UnicodeError`. + Implements the ``'strict'`` error handling. - -.. function:: replace_errors(exception) - - Implements the ``'replace'`` error handling (for :term:`text encodings - ` only): substitutes ``'?'`` for encoding errors - (to be encoded by the codec), and ``'\ufffd'`` (the Unicode replacement - character) for decoding errors. + Each encoding or decoding error raises a :exc:`UnicodeError`. .. function:: ignore_errors(exception) - Implements the ``'ignore'`` error handling: malformed data is ignored and - encoding or decoding is continued without further notice. + Implements the ``'ignore'`` error handling. + + Malformed data is ignored; encoding or decoding is continued without + further notice. -.. function:: xmlcharrefreplace_errors(exception) +.. function:: replace_errors(exception) - Implements the ``'xmlcharrefreplace'`` error handling (for encoding with - :term:`text encodings ` only): the - unencodable character is replaced by an appropriate XML character reference. + Implements the ``'replace'`` error handling. + + Substitutes ``?`` (ASCII character) for encoding errors or ``�`` (U+FFFD, + the official REPLACEMENT CHARACTER) for decoding errors. .. function:: backslashreplace_errors(exception) - Implements the ``'backslashreplace'`` error handling (for - :term:`text encodings ` only): malformed data is - replaced by a backslashed escape sequence. + Implements the ``'backslashreplace'`` error handling. + + Malformed data is replaced by a backslashed escape sequence. + On encoding, use the hexadecimal form of Unicode code point with formats + ``\xhh`` ``\uxxxx`` ``\Uxxxxxxxx``. On decoding, use the hexadecimal form of + byte value with format ``\xhh``. + + .. versionchanged:: 3.5 + Works with decoding and translating. + + +.. function:: xmlcharrefreplace_errors(exception) + + Implements the ``'xmlcharrefreplace'`` error handling (for encoding within + :term:`text encoding` only). + + The unencodable character is replaced by an appropriate XML/HTML numeric + character reference, which is a decimal form of Unicode code point with + format ``&#num;`` . + .. function:: namereplace_errors(exception) - Implements the ``'namereplace'`` error handling (for encoding with - :term:`text encodings ` only): the - unencodable character is replaced by a ``\N{...}`` escape sequence. + Implements the ``'namereplace'`` error handling (for encoding within + :term:`text encoding` only). + + The unencodable character is replaced by a ``\N{...}`` escape sequence. The + set of characters that appear in the braces is the Name property from + Unicode Character Database. For example, the German lowercase letter ``'ß'`` + will be converted to byte sequence ``\N{LATIN SMALL LETTER SHARP S}`` . .. versionadded:: 3.5 @@ -473,7 +517,7 @@ The base :class:`Codec` class defines these methods which also define the function interfaces of the stateless encoder and decoder: -.. method:: Codec.encode(input[, errors]) +.. method:: Codec.encode(input, errors='strict') Encodes the object *input* and returns a tuple (output object, length consumed). For instance, :term:`text encoding` converts @@ -491,7 +535,7 @@ function interfaces of the stateless encoder and decoder: of the output object type in this situation. -.. method:: Codec.decode(input[, errors]) +.. method:: Codec.decode(input, errors='strict') Decodes the object *input* and returns a tuple (output object, length consumed). For instance, for a :term:`text encoding`, decoding converts @@ -558,7 +602,7 @@ define in order to be compatible with the Python codec registry. object. - .. method:: encode(object[, final]) + .. method:: encode(object, final=False) Encodes *object* (taking the current state of the encoder into account) and returns the resulting encoded object. If this is the last call to @@ -615,7 +659,7 @@ define in order to be compatible with the Python codec registry. object. - .. method:: decode(object[, final]) + .. method:: decode(object, final=False) Decodes *object* (taking the current state of the decoder into account) and returns the resulting decoded object. If this is the last call to @@ -697,8 +741,9 @@ compatible with the Python codec registry. .. method:: writelines(list) - Writes the concatenated list of strings to the stream (possibly by reusing - the :meth:`write` method). The standard bytes-to-bytes codecs + Writes the concatenated iterable of strings to the stream (possibly by reusing + the :meth:`write` method). Infinite or + very large iterables are not supported. The standard bytes-to-bytes codecs do not support this method. @@ -748,7 +793,7 @@ compatible with the Python codec registry. :func:`register_error`. - .. method:: read([size[, chars, [firstline]]]) + .. method:: read(size=-1, chars=-1, firstline=False) Decodes data from the stream and returns the resulting object. @@ -774,7 +819,7 @@ compatible with the Python codec registry. available on the stream, these should be read too. - .. method:: readline([size[, keepends]]) + .. method:: readline(size=None, keepends=True) Read one line from the input stream and return the decoded data. @@ -785,7 +830,7 @@ compatible with the Python codec registry. returned. - .. method:: readlines([sizehint[, keepends]]) + .. method:: readlines(sizehint=None, keepends=True) Read all lines available on the input stream and return them as a list of lines. @@ -876,7 +921,7 @@ Encodings and Unicode --------------------- Strings are stored internally as sequences of code points in -range ``0x0``--``0x10FFFF``. (See :pep:`393` for +range ``U+0000``--``U+10FFFF``. (See :pep:`393` for more details about the implementation.) Once a string object is used outside of CPU and memory, endianness and how these arrays are stored as bytes become an issue. As with other @@ -914,7 +959,7 @@ there's the so called BOM ("Byte Order Mark"). This is the Unicode character ``U+FEFF``. This character can be prepended to every ``UTF-16`` or ``UTF-32`` byte sequence. The byte swapped version of this character (``0xFFFE``) is an illegal character that may not appear in a Unicode text. So when the -first character in an ``UTF-16`` or ``UTF-32`` byte sequence +first character in a ``UTF-16`` or ``UTF-32`` byte sequence appears to be a ``U+FFFE`` the bytes have to be swapped on decoding. Unfortunately the character ``U+FEFF`` had a second purpose as a ``ZERO WIDTH NO-BREAK SPACE``: a character that has no width and doesn't allow @@ -957,7 +1002,7 @@ encoding was used for encoding a string. Each charmap encoding can decode any random byte sequence. However that's not possible with UTF-8, as UTF-8 byte sequences have a structure that doesn't allow arbitrary byte sequences. To increase the reliability with which a UTF-8 encoding can be -detected, Microsoft invented a variant of UTF-8 (that Python 2.5 calls +detected, Microsoft invented a variant of UTF-8 (that Python calls ``"utf-8-sig"``) for its Notepad program: Before any of the Unicode characters is written to the file, a UTF-8 encoded BOM (which looks like this as a byte sequence: ``0xef``, ``0xbb``, ``0xbf``) is written. As it's rather improbable @@ -1425,7 +1470,7 @@ Internationalized Domain Names (IDN)). It builds upon the ``punycode`` encoding and :mod:`stringprep`. If you need the IDNA 2008 standard from :rfc:`5891` and :rfc:`5895`, use the -third-party `idna module _`. +third-party `idna module `_. These RFCs together define a protocol to support non-ASCII characters in domain names. A domain name containing non-ASCII characters (such as @@ -1486,7 +1531,7 @@ functions can be used directly if desired. This module implements the ANSI codepage (CP_ACP). -.. availability:: Windows only. +.. availability:: Windows. .. versionchanged:: 3.3 Support any error handler. diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 8bf3cb6cb12..2cffc2300a2 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -229,6 +229,7 @@ For example:: >>> cnt = Counter() >>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']: ... cnt[word] += 1 + ... >>> cnt Counter({'blue': 3, 'red': 2, 'green': 1}) @@ -271,12 +272,12 @@ For example:: .. versionadded:: 3.1 .. versionchanged:: 3.7 As a :class:`dict` subclass, :class:`Counter` - Inherited the capability to remember insertion order. Math operations + inherited the capability to remember insertion order. Math operations on *Counter* objects also preserve order. Results are ordered according to when an element is first encountered in the left operand and then by the order encountered in the right operand. - Counter objects support three methods beyond those available for all + Counter objects support additional methods beyond those available for all dictionaries: .. method:: elements() @@ -366,19 +367,26 @@ Several mathematical operations are provided for combining :class:`Counter` objects to produce multisets (counters that have counts greater than zero). Addition and subtraction combine counters by adding or subtracting the counts of corresponding elements. Intersection and union return the minimum and -maximum of corresponding counts. Each operation can accept inputs with signed +maximum of corresponding counts. Equality and inclusion compare +corresponding counts. Each operation can accept inputs with signed counts, but the output will exclude results with counts of zero or less. +.. doctest:: + >>> c = Counter(a=3, b=1) >>> d = Counter(a=1, b=2) >>> c + d # add two counters together: c[x] + d[x] Counter({'a': 4, 'b': 3}) >>> c - d # subtract (keeping only positive counts) Counter({'a': 2}) - >>> c & d # intersection: min(c[x], d[x]) # doctest: +SKIP + >>> c & d # intersection: min(c[x], d[x]) Counter({'a': 1, 'b': 1}) >>> c | d # union: max(c[x], d[x]) Counter({'a': 3, 'b': 2}) + >>> c == d # equality: c[x] == d[x] + False + >>> c <= d # inclusion: c[x] <= d[x] + False Unary addition and subtraction are shortcuts for adding an empty counter or subtracting from an empty counter. @@ -657,7 +665,7 @@ added elements by appending to the right and popping to the left:: def moving_average(iterable, n=3): # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0 - # http://en.wikipedia.org/wiki/Moving_average + # https://en.wikipedia.org/wiki/Moving_average it = iter(iterable) d = deque(itertools.islice(it, n-1)) d.appendleft(0) @@ -811,6 +819,7 @@ zero): >>> def constant_factory(value): ... return lambda: value + ... >>> d = defaultdict(constant_factory('')) >>> d.update(name='John', action='ran') >>> '%(name)s %(action)s to %(object)s' % d @@ -1085,18 +1094,35 @@ Some differences from :class:`dict` still remain: Space efficiency, iteration speed, and the performance of update operations were secondary. -* Algorithmically, :class:`OrderedDict` can handle frequent reordering - operations better than :class:`dict`. This makes it suitable for tracking - recent accesses (for example in an `LRU cache - `_). +* The :class:`OrderedDict` algorithm can handle frequent reordering operations + better than :class:`dict`. As shown in the recipes below, this makes it + suitable for implementing various kinds of LRU caches. * The equality operation for :class:`OrderedDict` checks for matching order. + A regular :class:`dict` can emulate the order sensitive equality test with + ``p == q and all(k1 == k2 for k1, k2 in zip(p, q))``. + * The :meth:`popitem` method of :class:`OrderedDict` has a different signature. It accepts an optional argument to specify which item is popped. -* :class:`OrderedDict` has a :meth:`move_to_end` method to - efficiently reposition an element to an endpoint. + A regular :class:`dict` can emulate OrderedDict's ``od.popitem(last=True)`` + with ``d.popitem()`` which is guaranteed to pop the rightmost (last) item. + + A regular :class:`dict` can emulate OrderedDict's ``od.popitem(last=False)`` + with ``(k := next(iter(d)), d.pop(k))`` which will return and remove the + leftmost (first) item if it exists. + +* :class:`OrderedDict` has a :meth:`move_to_end` method to efficiently + reposition an element to an endpoint. + + A regular :class:`dict` can emulate OrderedDict's ``od.move_to_end(k, + last=True)`` with ``d[k] = d.pop(k)`` which will move the key and its + associated value to the rightmost (last) position. + + A regular :class:`dict` does not have an efficient equivalent for + OrderedDict's ``od.move_to_end(k, last=False)`` which moves the key + and its associated value to the leftmost (first) position. * Until Python 3.8, :class:`dict` lacked a :meth:`__reversed__` method. @@ -1120,14 +1146,16 @@ Some differences from :class:`dict` still remain: Move an existing *key* to either end of an ordered dictionary. The item is moved to the right end if *last* is true (the default) or to the beginning if *last* is false. Raises :exc:`KeyError` if the *key* does - not exist:: + not exist: + + .. doctest:: >>> d = OrderedDict.fromkeys('abcde') >>> d.move_to_end('b') - >>> ''.join(d.keys()) + >>> ''.join(d) 'acdeb' >>> d.move_to_end('b', last=False) - >>> ''.join(d.keys()) + >>> ''.join(d) 'bacde' .. versionadded:: 3.2 @@ -1175,6 +1203,7 @@ variants of :func:`functools.lru_cache`: .. testcode:: + from collections import OrderedDict from time import time class TimeBoundedLRU: diff --git a/Doc/library/compileall.rst b/Doc/library/compileall.rst index de34664acb8..180f5b81c2b 100644 --- a/Doc/library/compileall.rst +++ b/Doc/library/compileall.rst @@ -14,6 +14,7 @@ This module can be used to create the cached byte-code files at library installation time, which makes them available for use even by users who don't have write permission to the library directories. +.. include:: ../includes/wasm-notavail.rst Command-line use ---------------- @@ -198,7 +199,7 @@ Public functions The *stripdir*, *prependdir* and *limit_sl_dest* arguments correspond to the ``-s``, ``-p`` and ``-e`` options described above. - They may be specified as ``str``, ``bytes`` or :py:class:`os.PathLike`. + They may be specified as ``str`` or :py:class:`os.PathLike`. If *hardlink_dupes* is true and two ``.pyc`` files with different optimization level have the same content, use hard links to consolidate duplicate files. @@ -268,7 +269,7 @@ Public functions The *stripdir*, *prependdir* and *limit_sl_dest* arguments correspond to the ``-s``, ``-p`` and ``-e`` options described above. - They may be specified as ``str``, ``bytes`` or :py:class:`os.PathLike`. + They may be specified as ``str`` or :py:class:`os.PathLike`. If *hardlink_dupes* is true and two ``.pyc`` files with different optimization level have the same content, use hard links to consolidate duplicate files. diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index b4213b45115..8106cc235e5 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -19,6 +19,7 @@ The asynchronous execution can be performed with threads, using :class:`ProcessPoolExecutor`. Both implement the same interface, which is defined by the abstract :class:`Executor` class. +.. include:: ../includes/wasm-notavail.rst Executor Objects ---------------- @@ -30,7 +31,7 @@ Executor Objects .. method:: submit(fn, /, *args, **kwargs) - Schedules the callable, *fn*, to be executed as ``fn(*args **kwargs)`` + Schedules the callable, *fn*, to be executed as ``fn(*args, **kwargs)`` and returns a :class:`Future` object representing the execution of the callable. :: @@ -47,7 +48,7 @@ Executor Objects * *func* is executed asynchronously and several calls to *func* may be made concurrently. - The returned iterator raises a :exc:`concurrent.futures.TimeoutError` + The returned iterator raises a :exc:`TimeoutError` if :meth:`~iterator.__next__` is called and the result isn't available after *timeout* seconds from the original call to :meth:`Executor.map`. *timeout* can be an int or a float. If *timeout* is not specified or @@ -149,6 +150,13 @@ And:: An :class:`Executor` subclass that uses a pool of at most *max_workers* threads to execute calls asynchronously. + All threads enqueued to ``ThreadPoolExecutor`` will be joined before the + interpreter can exit. Note that the exit handler which does this is + executed *before* any exit handlers added using ``atexit``. This means + exceptions in the main thread must be caught and handled in order to + signal threads to exit gracefully. For this reason, it is recommended + that ``ThreadPoolExecutor`` not be used for long-running tasks. + *initializer* is an optional callable that is called at the start of each worker thread; *initargs* is a tuple of arguments passed to the initializer. Should *initializer* raise an exception, all currently @@ -254,8 +262,11 @@ to a :class:`ProcessPoolExecutor` will result in deadlock. *max_tasks_per_child* is an optional argument that specifies the maximum number of tasks a single process can execute before it will exit and be - replaced with a fresh worker process. The default *max_tasks_per_child* is - ``None`` which means worker processes will live as long as the pool. + replaced with a fresh worker process. By default *max_tasks_per_child* is + ``None`` which means worker processes will live as long as the pool. When + a max is specified, the "spawn" multiprocessing start method will be used by + default in absence of a *mp_context* parameter. This feature is incompatible + with the "fork" start method. .. versionchanged:: 3.3 When one of the worker processes terminates abruptly, a @@ -352,7 +363,7 @@ The :class:`Future` class encapsulates the asynchronous execution of a callable. Return the value returned by the call. If the call hasn't yet completed then this method will wait up to *timeout* seconds. If the call hasn't completed in *timeout* seconds, then a - :exc:`concurrent.futures.TimeoutError` will be raised. *timeout* can be + :exc:`TimeoutError` will be raised. *timeout* can be an int or float. If *timeout* is not specified or ``None``, there is no limit to the wait time. @@ -366,7 +377,7 @@ The :class:`Future` class encapsulates the asynchronous execution of a callable. Return the exception raised by the call. If the call hasn't yet completed then this method will wait up to *timeout* seconds. If the call hasn't completed in *timeout* seconds, then a - :exc:`concurrent.futures.TimeoutError` will be raised. *timeout* can be + :exc:`TimeoutError` will be raised. *timeout* can be an int or float. If *timeout* is not specified or ``None``, there is no limit to the wait time. @@ -400,13 +411,13 @@ The :class:`Future` class encapsulates the asynchronous execution of a callable. tests. If the method returns ``False`` then the :class:`Future` was cancelled, - i.e. :meth:`Future.cancel` was called and returned `True`. Any threads + i.e. :meth:`Future.cancel` was called and returned ``True``. Any threads waiting on the :class:`Future` completing (i.e. through :func:`as_completed` or :func:`wait`) will be woken up. If the method returns ``True`` then the :class:`Future` was not cancelled and has been put in the running state, i.e. calls to - :meth:`Future.running` will return `True`. + :meth:`Future.running` will return ``True``. This method can only be called once and cannot be called after :meth:`Future.set_result` or :meth:`Future.set_exception` have been @@ -444,7 +455,8 @@ Module Functions .. function:: wait(fs, timeout=None, return_when=ALL_COMPLETED) Wait for the :class:`Future` instances (possibly created by different - :class:`Executor` instances) given by *fs* to complete. Returns a named + :class:`Executor` instances) given by *fs* to complete. Duplicate futures + given to *fs* are removed and will be returned only once. Returns a named 2-tuple of sets. The first set, named ``done``, contains the futures that completed (finished or cancelled futures) before the wait completed. The second set, named ``not_done``, contains the futures that did not complete @@ -482,7 +494,7 @@ Module Functions they complete (finished or cancelled futures). Any futures given by *fs* that are duplicated will be returned once. Any futures that completed before :func:`as_completed` is called will be yielded first. The returned iterator - raises a :exc:`concurrent.futures.TimeoutError` if :meth:`~iterator.__next__` + raises a :exc:`TimeoutError` if :meth:`~iterator.__next__` is called and the result isn't available after *timeout* seconds from the original call to :func:`as_completed`. *timeout* can be an int or float. If *timeout* is not specified or ``None``, there is no limit to the wait time. @@ -506,7 +518,13 @@ Exception classes .. exception:: TimeoutError - Raised when a future operation exceeds the given timeout. + A deprecated alias of :exc:`TimeoutError`, + raised when a future operation exceeds the given timeout. + + .. versionchanged:: 3.11 + + This class was made an alias of :exc:`TimeoutError`. + .. exception:: BrokenExecutor diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index d31452edb97..a925a3dd4fb 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -33,13 +33,17 @@ can be customized by end users easily. .. seealso:: + Module :mod:`tomllib` + TOML is a well-specified format for application configuration files. + It is specifically designed to be an improved version of INI. + Module :mod:`shlex` - Support for creating Unix shell-like mini-languages which can be used as - an alternate format for application configuration files. + Support for creating Unix shell-like mini-languages which can also + be used for application configuration files. Module :mod:`json` - The json module implements a subset of JavaScript syntax which can also - be used for this purpose. + The ``json`` module implements a subset of JavaScript syntax which is + sometimes used for configuration, but does not support comments. .. testsetup:: @@ -267,6 +271,9 @@ out. Values can also span multiple lines, as long as they are indented deeper than the first line of the value. Depending on the parser's mode, blank lines may be treated as parts of multiline values or ignored. +By default, a valid section name can be any string that does not contain '\\n' or ']'. +To change this, see :attr:`ConfigParser.SECTCRE`. + Configuration files may include comments, prefixed by specific characters (``#`` and ``;`` by default [1]_). Comments may appear on their own on an otherwise empty line, possibly indented. [1]_ @@ -344,7 +351,8 @@ from ``get()`` calls. my_pictures: %(my_dir)s/Pictures [Escape] - gain: 80%% # use a %% to escape the % sign (% is the only character that needs to be escaped) + # use a %% to escape the % sign (% is the only character that needs to be escaped): + gain: 80%% In the example above, :class:`ConfigParser` with *interpolation* set to ``BasicInterpolation()`` would resolve ``%(home_dir)s`` to the value of @@ -379,7 +387,8 @@ from ``get()`` calls. my_pictures: ${my_dir}/Pictures [Escape] - cost: $$80 # use a $$ to escape the $ sign ($ is the only character that needs to be escaped) + # use a $$ to escape the $ sign ($ is the only character that needs to be escaped): + cost: $$80 Values from other sections can be fetched as well: @@ -1334,13 +1343,9 @@ Exceptions Exception raised when errors occur attempting to parse a file. - .. versionchanged:: 3.2 - The ``filename`` attribute and :meth:`__init__` argument were renamed to - ``source`` for consistency. - - .. versionchanged:: 3.11 - The deprecated ``filename`` attribute was removed. - +.. versionchanged:: 3.12 + The ``filename`` attribute and :meth:`__init__` constructor argument were + removed. They have been available using the name ``source`` since 3.2. .. rubric:: Footnotes diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index a800a0b8dee..1b55868c3aa 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -66,6 +66,8 @@ Functions and classes provided: # Code to release resource, e.g.: release_resource(resource) + The function can then be used like this:: + >>> with managed_resource(timeout=3600) as resource: ... # Resource is released at the end of this block, ... # even if code in the block raises an exception @@ -130,7 +132,9 @@ Functions and classes provided: either as decorators or with :keyword:`async with` statements:: import time + from contextlib import asynccontextmanager + @asynccontextmanager async def timeit(): now = time.monotonic() try: @@ -138,9 +142,9 @@ Functions and classes provided: finally: print(f'it took {time.monotonic() - now}s to run') - @timeit() - async def main(): - # ... async code ... + @timeit() + async def main(): + # ... async code ... When used as a decorator, a new generator instance is implicitly created on each function call. This allows the otherwise "one-shot" context managers @@ -179,7 +183,7 @@ Functions and classes provided: ``page.close()`` will be called when the :keyword:`with` block is exited. -.. class:: aclosing(thing) +.. function:: aclosing(thing) Return an async context manager that calls the ``aclose()`` method of *thing* upon completion of the block. This is basically equivalent to:: @@ -247,15 +251,15 @@ Functions and classes provided: :ref:`asynchronous context managers `:: async def send_http(session=None): - if not session: - # If no http session, create it with aiohttp - cm = aiohttp.ClientSession() - else: - # Caller is responsible for closing the session - cm = nullcontext(session) + if not session: + # If no http session, create it with aiohttp + cm = aiohttp.ClientSession() + else: + # Caller is responsible for closing the session + cm = nullcontext(session) - async with cm as session: - # Send http requests with session + async with cm as session: + # Send http requests with session .. versionadded:: 3.7 @@ -359,7 +363,7 @@ Functions and classes provided: As this changes a global state, the working directory, it is not suitable for use in most threaded or async contexts. It is also not suitable for most non-linear code execution, like generators, where the program execution is - temporarily relinquished -- unless explicitely desired, you should not yield + temporarily relinquished -- unless explicitly desired, you should not yield when this context manager is active. This is a simple wrapper around :func:`~os.chdir`, it changes the current @@ -394,6 +398,8 @@ Functions and classes provided: print('Finishing') return False + The class can then be used like this:: + >>> @mycontext() ... def function(): ... print('The bit in the middle') @@ -464,6 +470,8 @@ Functions and classes provided: print('Finishing') return False + The class can then be used like this:: + >>> @mycontext() ... async def function(): ... print('The bit in the middle') @@ -500,6 +508,9 @@ Functions and classes provided: # the with statement, even if attempts to open files later # in the list raise an exception + The :meth:`__enter__` method returns the :class:`ExitStack` instance, and + performs no additional operations. + Each instance maintains a stack of registered callbacks that are called in reverse order when the instance is closed (either explicitly or implicitly at the end of a :keyword:`with` statement). Note that callbacks are *not* diff --git a/Doc/library/contextvars.rst b/Doc/library/contextvars.rst index be1dd0c9eb5..0ac2f3d8574 100644 --- a/Doc/library/contextvars.rst +++ b/Doc/library/contextvars.rst @@ -110,7 +110,7 @@ Context Variables A read-only property. Set to the value the variable had before the :meth:`ContextVar.set` method call that created the token. - It points to :attr:`Token.MISSING` is the variable was not set + It points to :attr:`Token.MISSING` if the variable was not set before the call. .. attribute:: Token.MISSING @@ -144,6 +144,11 @@ Manual Context Management To get a copy of the current context use the :func:`~contextvars.copy_context` function. + Every thread will have a different top-level :class:`~contextvars.Context` + object. This means that a :class:`ContextVar` object behaves in a similar + fashion to :func:`threading.local()` when values are assigned in different + threads. + Context implements the :class:`collections.abc.Mapping` interface. .. method:: run(callable, *args, **kwargs) diff --git a/Doc/library/copyreg.rst b/Doc/library/copyreg.rst index 43920210095..866b180f4bc 100644 --- a/Doc/library/copyreg.rst +++ b/Doc/library/copyreg.rst @@ -25,20 +25,17 @@ Such constructors may be factory functions or class instances. hence not valid as a constructor), raises :exc:`TypeError`. -.. function:: pickle(type, function, constructor=None) +.. function:: pickle(type, function, constructor_ob=None) Declares that *function* should be used as a "reduction" function for objects of type *type*. *function* should return either a string or a tuple - containing two or three elements. + containing two or three elements. See the :attr:`~pickle.Pickler.dispatch_table` + for more details on the interface of *function*. - The optional *constructor* parameter, if provided, is a callable object which - can be used to reconstruct the object when called with the tuple of arguments - returned by *function* at pickling time. :exc:`TypeError` will be raised if - *object* is a class or *constructor* is not callable. + The *constructor_ob* parameter is a legacy feature and is now ignored, but if + passed it must be a callable. - See the :mod:`pickle` module for more details on the interface - expected of *function* and *constructor*. Note that the - :attr:`~pickle.Pickler.dispatch_table` attribute of a pickler + Note that the :attr:`~pickle.Pickler.dispatch_table` attribute of a pickler object or subclass of :class:`pickle.Pickler` can also be used for declaring reduction functions. diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst index d25c626a175..740084b40c5 100644 --- a/Doc/library/crypt.rst +++ b/Doc/library/crypt.rst @@ -4,6 +4,7 @@ .. module:: crypt :platform: Unix :synopsis: The crypt() function used to check Unix passwords. + :deprecated: .. moduleauthor:: Steven D. Majewski .. sectionauthor:: Steven D. Majewski @@ -15,6 +16,11 @@ single: crypt(3) pair: cipher; DES +.. deprecated-removed:: 3.11 3.13 + The :mod:`crypt` module is deprecated + (see :pep:`PEP 594 <594#crypt>` for details and alternatives). + The :mod:`hashlib` module is a potential replacement for certain use cases. + -------------- This module implements an interface to the :manpage:`crypt(3)` routine, which is @@ -30,7 +36,9 @@ the :manpage:`crypt(3)` routine in the running system. Therefore, any extensions available on the current implementation will also be available on this module. -.. availability:: Unix. Not available on VxWorks. +.. availability:: Unix, not VxWorks. + +.. include:: ../includes/wasm-notavail.rst Hashing Methods --------------- @@ -92,8 +100,7 @@ The :mod:`crypt` module defines the following functions: :func:`mksalt`, one of the ``crypt.METHOD_*`` values (though not all may be available on all platforms), or a full encrypted password including salt, as returned by this function. If *salt* is not - provided, the strongest method will be used (as returned by - :func:`methods`). + provided, the strongest method available in :attr:`methods` will be used. Checking a password is usually done by passing the plain-text password as *word* and the full results of a previous :func:`crypt` call, @@ -121,8 +128,8 @@ The :mod:`crypt` module defines the following functions: .. function:: mksalt(method=None, *, rounds=None) Return a randomly generated salt of the specified method. If no - *method* is given, the strongest method available as returned by - :func:`methods` is used. + *method* is given, the strongest method available in :attr:`methods` is + used. The return value is a string suitable for passing as the *salt* argument to :func:`crypt`. diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index 3a7817cfdfa..41f11505aa1 100644 --- a/Doc/library/csv.rst +++ b/Doc/library/csv.rst @@ -167,6 +167,8 @@ The :mod:`csv` module defines the following classes: All other optional or keyword arguments are passed to the underlying :class:`reader` instance. + If the argument passed to *fieldnames* is an iterator, it will be coerced to a :class:`list`. + .. versionchanged:: 3.6 Returned rows are now of type :class:`OrderedDict`. @@ -209,6 +211,8 @@ The :mod:`csv` module defines the following classes: Note that unlike the :class:`DictReader` class, the *fieldnames* parameter of the :class:`DictWriter` class is not optional. + If the argument passed to *fieldnames* is an iterator, it will be coerced to a :class:`list`. + A short usage example:: import csv @@ -416,7 +420,7 @@ Dialects support the following attributes: .. attribute:: Dialect.skipinitialspace - When :const:`True`, whitespace immediately following the *delimiter* is ignored. + When :const:`True`, spaces immediately following the *delimiter* are ignored. The default is :const:`False`. @@ -542,7 +546,7 @@ The corresponding simplest possible writing example is:: Since :func:`open` is used to open a CSV file for reading, the file will by default be decoded into unicode using the system default -encoding (see :func:`locale.getpreferredencoding`). To decode a file +encoding (see :func:`locale.getencoding`). To decode a file using a different encoding, use the ``encoding`` argument of open:: import csv diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index b58b961a30d..4de5c820f2c 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -6,6 +6,8 @@ .. moduleauthor:: Thomas Heller +**Source code:** :source:`Lib/ctypes` + -------------- :mod:`ctypes` is a foreign function library for Python. It provides C compatible @@ -148,15 +150,14 @@ Calling functions ^^^^^^^^^^^^^^^^^ You can call these functions like any other Python callable. This example uses -the ``time()`` function, which returns system time in seconds since the Unix -epoch, and the ``GetModuleHandleA()`` function, which returns a win32 module -handle. +the ``rand()`` function, which takes no arguments and returns a pseudo-random integer:: -This example calls both functions with a ``NULL`` pointer (``None`` should be used -as the ``NULL`` pointer):: + >>> print(libc.rand()) # doctest: +SKIP + 1804289383 + +On Windows, you can call the ``GetModuleHandleA()`` function, which returns a win32 module +handle (passing ``None`` as single argument to call it with a ``NULL`` pointer):: - >>> print(libc.time(None)) # doctest: +SKIP - 1150640792 >>> print(hex(windll.kernel32.GetModuleHandleA(None))) # doctest: +WINDOWS 0x1d000000 >>> @@ -197,9 +198,9 @@ calls). ``None``, integers, bytes objects and (unicode) strings are the only native Python objects that can directly be used as parameters in these function calls. ``None`` is passed as a C ``NULL`` pointer, bytes objects and strings are passed -as pointer to the memory block that contains their data (:c:type:`char *` or -:c:type:`wchar_t *`). Python integers are passed as the platforms default C -:c:type:`int` type, their value is masked to fit into the C type. +as pointer to the memory block that contains their data (:c:expr:`char *` or +:c:expr:`wchar_t *`). Python integers are passed as the platforms default C +:c:expr:`int` type, their value is masked to fit into the C type. Before we move on calling functions with other parameter types, we have to learn more about :mod:`ctypes` data types. @@ -215,49 +216,51 @@ Fundamental data types +----------------------+------------------------------------------+----------------------------+ | ctypes type | C type | Python type | +======================+==========================================+============================+ -| :class:`c_bool` | :c:type:`_Bool` | bool (1) | +| :class:`c_bool` | :c:expr:`_Bool` | bool (1) | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_char` | :c:type:`char` | 1-character bytes object | +| :class:`c_char` | :c:expr:`char` | 1-character bytes object | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_wchar` | :c:type:`wchar_t` | 1-character string | +| :class:`c_wchar` | :c:expr:`wchar_t` | 1-character string | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_byte` | :c:type:`char` | int | +| :class:`c_byte` | :c:expr:`char` | int | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_ubyte` | :c:type:`unsigned char` | int | +| :class:`c_ubyte` | :c:expr:`unsigned char` | int | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_short` | :c:type:`short` | int | +| :class:`c_short` | :c:expr:`short` | int | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_ushort` | :c:type:`unsigned short` | int | +| :class:`c_ushort` | :c:expr:`unsigned short` | int | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_int` | :c:type:`int` | int | +| :class:`c_int` | :c:expr:`int` | int | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_uint` | :c:type:`unsigned int` | int | +| :class:`c_uint` | :c:expr:`unsigned int` | int | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_long` | :c:type:`long` | int | +| :class:`c_long` | :c:expr:`long` | int | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_ulong` | :c:type:`unsigned long` | int | +| :class:`c_ulong` | :c:expr:`unsigned long` | int | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_longlong` | :c:type:`__int64` or :c:type:`long long` | int | +| :class:`c_longlong` | :c:expr:`__int64` or :c:expr:`long long` | int | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_ulonglong` | :c:type:`unsigned __int64` or | int | -| | :c:type:`unsigned long long` | | +| :class:`c_ulonglong` | :c:expr:`unsigned __int64` or | int | +| | :c:expr:`unsigned long long` | | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_size_t` | :c:type:`size_t` | int | +| :class:`c_size_t` | :c:expr:`size_t` | int | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_ssize_t` | :c:type:`ssize_t` or | int | -| | :c:type:`Py_ssize_t` | | +| :class:`c_ssize_t` | :c:expr:`ssize_t` or | int | +| | :c:expr:`Py_ssize_t` | | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_float` | :c:type:`float` | float | +| :class:`c_time_t` | :c:type:`time_t` | int | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_double` | :c:type:`double` | float | +| :class:`c_float` | :c:expr:`float` | float | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_longdouble`| :c:type:`long double` | float | +| :class:`c_double` | :c:expr:`double` | float | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_char_p` | :c:type:`char *` (NUL terminated) | bytes object or ``None`` | +| :class:`c_longdouble`| :c:expr:`long double` | float | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_wchar_p` | :c:type:`wchar_t *` (NUL terminated) | string or ``None`` | +| :class:`c_char_p` | :c:expr:`char *` (NUL terminated) | bytes object or ``None`` | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_void_p` | :c:type:`void *` | int or ``None`` | +| :class:`c_wchar_p` | :c:expr:`wchar_t *` (NUL terminated) | string or ``None`` | ++----------------------+------------------------------------------+----------------------------+ +| :class:`c_void_p` | :c:expr:`void *` | int or ``None`` | +----------------------+------------------------------------------+----------------------------+ (1) @@ -332,7 +335,7 @@ property:: The :func:`create_string_buffer` function replaces the old :func:`c_buffer` function (which is still available as an alias). To create a mutable memory -block containing unicode characters of the C type :c:type:`wchar_t`, use the +block containing unicode characters of the C type :c:expr:`wchar_t`, use the :func:`create_unicode_buffer` function. @@ -358,7 +361,7 @@ from within *IDLE* or *PythonWin*:: >>> printf(b"%f bottles of beer\n", 42.5) Traceback (most recent call last): File "", line 1, in - ArgumentError: argument 2: exceptions.TypeError: Don't know how to convert parameter 2 + ArgumentError: argument 2: TypeError: Don't know how to convert parameter 2 >>> As has been mentioned before, all Python types except integers, strings, and @@ -370,6 +373,26 @@ that they can be converted to the required C data type:: 31 >>> +.. _ctypes-calling-variadic-functions: + +Calling varadic functions +^^^^^^^^^^^^^^^^^^^^^^^^^ + +On a lot of platforms calling variadic functions through ctypes is exactly the same +as calling functions with a fixed number of parameters. On some platforms, and in +particular ARM64 for Apple Platforms, the calling convention for variadic functions +is different than that for regular functions. + +On those platforms it is required to specify the *argtypes* attribute for the +regular, non-variadic, function arguments: + +.. code-block:: python3 + + libc.printf.argtypes = [ctypes.c_char_p] + +Because specifying the attribute does inhibit portability it is advised to always +specify ``argtypes`` for all variadic functions. + .. _ctypes-calling-functions-with-own-custom-data-types: @@ -421,7 +444,7 @@ prototype for a C function), and tries to convert the arguments to valid types:: >>> printf(b"%d %d %d", 1, 2, 3) Traceback (most recent call last): File "", line 1, in - ArgumentError: argument 2: exceptions.TypeError: wrong type + ArgumentError: argument 2: TypeError: wrong type >>> printf(b"%s %d %f\n", b"X", 2, 3) X 2 3.000000 13 @@ -443,10 +466,33 @@ integer, string, bytes, a :mod:`ctypes` instance, or an object with an Return types ^^^^^^^^^^^^ -By default functions are assumed to return the C :c:type:`int` type. Other +.. testsetup:: + + from ctypes import CDLL, c_char, c_char_p + from ctypes.util import find_library + libc = CDLL(find_library('c')) + strchr = libc.strchr + + +By default functions are assumed to return the C :c:expr:`int` type. Other return types can be specified by setting the :attr:`restype` attribute of the function object. +The C prototype of ``time()`` is ``time_t time(time_t *)``. Because ``time_t`` +might be of a different type than the default return type ``int``, you should +specify the ``restype``:: + + >>> libc.time.restype = c_time_t + +The argument types can be specified using ``argtypes``:: + + >>> libc.time.argtypes = (POINTER(c_time_t),) + +To call the function with a ``NULL`` pointer as first argument, use ``None``:: + + >>> print(libc.time(None)) # doctest: +SKIP + 1150640792 + Here is a more advanced example, it uses the ``strchr`` function, which expects a string pointer and a char, and returns a pointer to a string:: @@ -464,18 +510,19 @@ If you want to avoid the ``ord("x")`` calls above, you can set the :attr:`argtypes` attribute, and the second argument will be converted from a single character Python bytes object into a C char:: +.. doctest:: + >>> strchr.restype = c_char_p >>> strchr.argtypes = [c_char_p, c_char] >>> strchr(b"abcdef", b"d") - 'def' + b'def' >>> strchr(b"abcdef", b"def") Traceback (most recent call last): - File "", line 1, in - ArgumentError: argument 2: exceptions.TypeError: one character string expected + ctypes.ArgumentError: argument 2: TypeError: one character bytes, bytearray or integer expected >>> print(strchr(b"abcdef", b"x")) None >>> strchr(b"abcdef", b"d") - 'def' + b'def' >>> You can also use a callable Python object (a function or a class for example) as @@ -1052,18 +1099,16 @@ Accessing values exported from dlls ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Some shared libraries not only export functions, they also export variables. An -example in the Python library itself is the :c:data:`Py_OptimizeFlag`, an integer -set to 0, 1, or 2, depending on the :option:`-O` or :option:`-OO` flag given on -startup. +example in the Python library itself is the :c:data:`Py_Version`, Python +runtime version number encoded in a single constant integer. :mod:`ctypes` can access values like this with the :meth:`in_dll` class methods of the type. *pythonapi* is a predefined symbol giving access to the Python C api:: - >>> opt_flag = c_int.in_dll(pythonapi, "Py_OptimizeFlag") - >>> print(opt_flag) - c_long(0) - >>> + >>> version = ctypes.c_int.in_dll(ctypes.pythonapi, "Py_Version") + >>> print(hex(version.value)) + 0x30c00a0 If the interpreter would have been started with :option:`-O`, the sample would have printed ``c_long(1)``, or ``c_long(2)`` if :option:`-OO` would have been @@ -1074,7 +1119,7 @@ An extended example which also demonstrates the use of pointers accesses the Quoting the docs for that value: - 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. @@ -1093,7 +1138,7 @@ size, we show only how this table can be read with :mod:`ctypes`:: ... >>> -We have defined the :c:type:`struct _frozen` data type, so we can get the pointer +We have defined the :c:struct:`_frozen` data type, so we can get the pointer to the table:: >>> FrozenTable = POINTER(struct_frozen) @@ -1319,11 +1364,11 @@ There are several ways to load shared libraries into the Python process. One way is to instantiate one of the following classes: -.. class:: CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=0) +.. class:: CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None) Instances of this class represent loaded shared libraries. Functions in these libraries use the standard C calling convention, and are assumed to return - :c:type:`int`. + :c:expr:`int`. On Windows creating a :class:`CDLL` instance may fail even if the DLL name exists. When a dependent DLL of the loaded DLL is not found, a @@ -1341,7 +1386,7 @@ way is to instantiate one of the following classes: -- A tool to find DLL dependents. -.. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=0) +.. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None) Windows only: Instances of this class represent loaded shared libraries, functions in these libraries use the ``stdcall`` calling convention, and are @@ -1354,15 +1399,11 @@ way is to instantiate one of the following classes: :exc:`WindowsError` used to be raised. -.. class:: WinDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=0) +.. class:: WinDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None) Windows only: Instances of this class represent loaded shared libraries, functions in these libraries use the ``stdcall`` calling convention, and are - assumed to return :c:type:`int` by default. - - On Windows CE only the standard calling convention is used, for convenience the - :class:`WinDLL` and :class:`OleDLL` use the standard calling convention on this - platform. + assumed to return :c:expr:`int` by default. The Python :term:`global interpreter lock` is released before calling any function exported by these libraries, and reacquired afterwards. @@ -1408,8 +1449,8 @@ copy of the windows error code. The *winmode* parameter is used on Windows to specify how the library is loaded (since *mode* is ignored). It takes any value that is valid for the Win32 API -``LoadLibraryEx`` flags parameter. When omitted, the default is to use the flags -that result in the most secure DLL load to avoiding issues such as DLL +``LoadLibraryEx`` flags parameter. When omitted, the default is to use the +flags that result in the most secure DLL load, which avoids issues such as DLL hijacking. Passing the full path to the DLL is the safest way to ensure the correct library and dependencies are loaded. @@ -1518,7 +1559,7 @@ object is available: An instance of :class:`PyDLL` that exposes Python C API functions as attributes. Note that all these functions are assumed to return C - :c:type:`int`, which is of course not always the truth, so you have to assign + :c:expr:`int`, which is of course not always the truth, so you have to assign the correct :attr:`restype` attribute to use these functions. .. audit-event:: ctypes.dlopen name ctypes.LibraryLoader @@ -1564,10 +1605,10 @@ They are instances of a private class: .. attribute:: restype Assign a ctypes type to specify the result type of the foreign function. - Use ``None`` for :c:type:`void`, a function not returning anything. + Use ``None`` for :c:expr:`void`, a function not returning anything. It is possible to assign a callable Python object that is not a ctypes - type, in this case the function is assumed to return a C :c:type:`int`, and + type, in this case the function is assumed to return a C :c:expr:`int`, and the callable will be called with this integer, allowing further processing or error checking. Using this is deprecated, for more flexible post processing or error checking use a ctypes data type as @@ -1624,12 +1665,12 @@ They are instances of a private class: passed arguments. -.. audit-event:: ctypes.seh_exception code foreign-functions +.. audit-event:: ctypes.set_exception code foreign-functions On Windows, when a foreign function call raises a system exception (for example, due to an access violation), it will be captured and replaced with a suitable Python exception. Further, an auditing event - ``ctypes.seh_exception`` with argument ``code`` will be raised, allowing an + ``ctypes.set_exception`` with argument ``code`` will be raised, allowing an audit hook to replace the exception with its own. .. audit-event:: ctypes.call_function func_pointer,arguments foreign-functions @@ -1664,8 +1705,7 @@ See :ref:`ctypes-callback-functions` for examples. .. function:: WINFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False) Windows only: The returned function prototype creates functions that use the - ``stdcall`` calling convention, except on Windows CE where - :func:`WINFUNCTYPE` is the same as :func:`CFUNCTYPE`. The function will + ``stdcall`` calling convention. The function will release the GIL during the call. *use_errno* and *use_last_error* have the same meaning as above. @@ -1939,7 +1979,7 @@ Utility functions .. function:: GetLastError() Windows only: Returns the last error code set by Windows in the calling thread. - This function calls the Windows `GetLastError()` function directly, + This function calls the Windows ``GetLastError()`` function directly, it does not return the ctypes-private copy of the error code. .. function:: get_errno() @@ -2181,21 +2221,21 @@ These are the fundamental ctypes data types: .. class:: c_byte - Represents the C :c:type:`signed char` datatype, and interprets the value as + Represents the C :c:expr:`signed char` datatype, and interprets the value as small integer. The constructor accepts an optional integer initializer; no overflow checking is done. .. class:: c_char - Represents the C :c:type:`char` datatype, and interprets the value as a single + Represents the C :c:expr:`char` datatype, and interprets the value as a single character. The constructor accepts an optional string initializer, the length of the string must be exactly one character. .. class:: c_char_p - Represents the C :c:type:`char *` datatype when it points to a zero-terminated + Represents the C :c:expr:`char *` datatype when it points to a zero-terminated string. For a general character pointer that may also point to binary data, ``POINTER(c_char)`` must be used. The constructor accepts an integer address, or a bytes object. @@ -2203,68 +2243,68 @@ These are the fundamental ctypes data types: .. class:: c_double - Represents the C :c:type:`double` datatype. The constructor accepts an + Represents the C :c:expr:`double` datatype. The constructor accepts an optional float initializer. .. class:: c_longdouble - Represents the C :c:type:`long double` datatype. The constructor accepts an + Represents the C :c:expr:`long double` datatype. The constructor accepts an optional float initializer. On platforms where ``sizeof(long double) == sizeof(double)`` it is an alias to :class:`c_double`. .. class:: c_float - Represents the C :c:type:`float` datatype. The constructor accepts an + Represents the C :c:expr:`float` datatype. The constructor accepts an optional float initializer. .. class:: c_int - Represents the C :c:type:`signed int` datatype. The constructor accepts an + Represents the C :c:expr:`signed int` datatype. The constructor accepts an optional integer initializer; no overflow checking is done. On platforms where ``sizeof(int) == sizeof(long)`` it is an alias to :class:`c_long`. .. class:: c_int8 - Represents the C 8-bit :c:type:`signed int` datatype. Usually an alias for + Represents the C 8-bit :c:expr:`signed int` datatype. Usually an alias for :class:`c_byte`. .. class:: c_int16 - Represents the C 16-bit :c:type:`signed int` datatype. Usually an alias for + Represents the C 16-bit :c:expr:`signed int` datatype. Usually an alias for :class:`c_short`. .. class:: c_int32 - Represents the C 32-bit :c:type:`signed int` datatype. Usually an alias for + Represents the C 32-bit :c:expr:`signed int` datatype. Usually an alias for :class:`c_int`. .. class:: c_int64 - Represents the C 64-bit :c:type:`signed int` datatype. Usually an alias for + Represents the C 64-bit :c:expr:`signed int` datatype. Usually an alias for :class:`c_longlong`. .. class:: c_long - Represents the C :c:type:`signed long` datatype. The constructor accepts an + Represents the C :c:expr:`signed long` datatype. The constructor accepts an optional integer initializer; no overflow checking is done. .. class:: c_longlong - Represents the C :c:type:`signed long long` datatype. The constructor accepts + Represents the C :c:expr:`signed long long` datatype. The constructor accepts an optional integer initializer; no overflow checking is done. .. class:: c_short - Represents the C :c:type:`signed short` datatype. The constructor accepts an + Represents the C :c:expr:`signed short` datatype. The constructor accepts an optional integer initializer; no overflow checking is done. @@ -2280,85 +2320,92 @@ These are the fundamental ctypes data types: .. versionadded:: 3.2 +.. class:: c_time_t + + Represents the C :c:type:`time_t` datatype. + + .. versionadded:: 3.12 + + .. class:: c_ubyte - Represents the C :c:type:`unsigned char` datatype, it interprets the value as + Represents the C :c:expr:`unsigned char` datatype, it interprets the value as small integer. The constructor accepts an optional integer initializer; no overflow checking is done. .. class:: c_uint - Represents the C :c:type:`unsigned int` datatype. The constructor accepts an + Represents the C :c:expr:`unsigned int` datatype. The constructor accepts an optional integer initializer; no overflow checking is done. On platforms where ``sizeof(int) == sizeof(long)`` it is an alias for :class:`c_ulong`. .. class:: c_uint8 - Represents the C 8-bit :c:type:`unsigned int` datatype. Usually an alias for + Represents the C 8-bit :c:expr:`unsigned int` datatype. Usually an alias for :class:`c_ubyte`. .. class:: c_uint16 - Represents the C 16-bit :c:type:`unsigned int` datatype. Usually an alias for + Represents the C 16-bit :c:expr:`unsigned int` datatype. Usually an alias for :class:`c_ushort`. .. class:: c_uint32 - Represents the C 32-bit :c:type:`unsigned int` datatype. Usually an alias for + Represents the C 32-bit :c:expr:`unsigned int` datatype. Usually an alias for :class:`c_uint`. .. class:: c_uint64 - Represents the C 64-bit :c:type:`unsigned int` datatype. Usually an alias for + Represents the C 64-bit :c:expr:`unsigned int` datatype. Usually an alias for :class:`c_ulonglong`. .. class:: c_ulong - Represents the C :c:type:`unsigned long` datatype. The constructor accepts an + Represents the C :c:expr:`unsigned long` datatype. The constructor accepts an optional integer initializer; no overflow checking is done. .. class:: c_ulonglong - Represents the C :c:type:`unsigned long long` datatype. The constructor + Represents the C :c:expr:`unsigned long long` datatype. The constructor accepts an optional integer initializer; no overflow checking is done. .. class:: c_ushort - Represents the C :c:type:`unsigned short` datatype. The constructor accepts + Represents the C :c:expr:`unsigned short` datatype. The constructor accepts an optional integer initializer; no overflow checking is done. .. class:: c_void_p - Represents the C :c:type:`void *` type. The value is represented as integer. + Represents the C :c:expr:`void *` type. The value is represented as integer. The constructor accepts an optional integer initializer. .. class:: c_wchar - Represents the C :c:type:`wchar_t` datatype, and interprets the value as a + Represents the C :c:expr:`wchar_t` datatype, and interprets the value as a single character unicode string. The constructor accepts an optional string initializer, the length of the string must be exactly one character. .. class:: c_wchar_p - Represents the C :c:type:`wchar_t *` datatype, which must be a pointer to a + Represents the C :c:expr:`wchar_t *` datatype, which must be a pointer to a zero-terminated wide character string. The constructor accepts an integer address, or a string. .. class:: c_bool - Represent the C :c:type:`bool` datatype (more accurately, :c:type:`_Bool` from + Represent the C :c:expr:`bool` datatype (more accurately, :c:expr:`_Bool` from C99). Its value can be ``True`` or ``False``, and the constructor accepts any object that has a truth value. @@ -2371,8 +2418,8 @@ These are the fundamental ctypes data types: .. class:: py_object - Represents the C :c:type:`PyObject *` datatype. Calling this without an - argument creates a ``NULL`` :c:type:`PyObject *` pointer. + Represents the C :c:expr:`PyObject *` datatype. Calling this without an + argument creates a ``NULL`` :c:expr:`PyObject *` pointer. The :mod:`ctypes.wintypes` module provides quite some other Windows specific data types, for example :c:type:`HWND`, :c:type:`WPARAM`, or :c:type:`DWORD`. Some @@ -2390,6 +2437,18 @@ Structured data types Abstract base class for unions in native byte order. +.. class:: BigEndianUnion(*args, **kw) + + Abstract base class for unions in *big endian* byte order. + + .. versionadded:: 3.11 + +.. class:: LittleEndianUnion(*args, **kw) + + Abstract base class for unions in *little endian* byte order. + + .. versionadded:: 3.11 + .. class:: BigEndianStructure(*args, **kw) Abstract base class for structures in *big endian* byte order. @@ -2399,8 +2458,8 @@ Structured data types Abstract base class for structures in *little endian* byte order. -Structures with non-native byte order cannot contain pointer type fields, or any -other data types containing pointer type fields. +Structures and unions with non-native byte order cannot contain pointer type +fields, or any other data types containing pointer type fields. .. class:: Structure(*args, **kw) @@ -2512,7 +2571,7 @@ Arrays and pointers Abstract base class for arrays. The recommended way to create concrete array types is by multiplying any - :mod:`ctypes` data type with a positive integer. Alternatively, you can subclass + :mod:`ctypes` data type with a non-negative integer. Alternatively, you can subclass this type and define :attr:`_length_` and :attr:`_type_` class variables. Array elements can be read and written using standard subscript and slice accesses; for slice reads, the resulting object is diff --git a/Doc/library/curses.ascii.rst b/Doc/library/curses.ascii.rst index a69dbb2ac06..e1d1171927c 100644 --- a/Doc/library/curses.ascii.rst +++ b/Doc/library/curses.ascii.rst @@ -7,6 +7,8 @@ .. moduleauthor:: Eric S. Raymond .. sectionauthor:: Eric S. Raymond +**Source code:** :source:`Lib/curses/ascii.py` + -------------- The :mod:`curses.ascii` module supplies name constants for ASCII characters and diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index 37e822c0e2b..f50b51c3780 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -9,6 +9,8 @@ .. sectionauthor:: Moshe Zadka .. sectionauthor:: Eric Raymond +**Source code:** :source:`Lib/curses` + -------------- The :mod:`curses` module provides an interface to the curses library, the @@ -27,20 +29,6 @@ Linux and the BSD variants of Unix. Whenever the documentation mentions a *character string* it can be specified as a Unicode string or a byte string. -.. note:: - - Since version 5.4, the ncurses library decides how to interpret non-ASCII data - using the ``nl_langinfo`` function. That means that you have to call - :func:`locale.setlocale` in the application and encode Unicode strings - using one of the system's available encodings. This example uses the - system's default encoding:: - - import locale - locale.setlocale(locale.LC_ALL, '') - code = locale.getpreferredencoding() - - Then use *code* as the encoding for :meth:`str.encode` calls. - .. seealso:: Module :mod:`curses.ascii` @@ -56,9 +44,6 @@ Linux and the BSD variants of Unix. Tutorial material on using curses with Python, by Andrew Kuchling and Eric Raymond. - The :source:`Tools/demo/` directory in the Python source distribution contains - some example programs using the curses bindings provided by this module. - .. _curses-functions: @@ -292,7 +277,7 @@ The module :mod:`curses` defines the following functions: Change the definition of a color, taking the number of the color to be changed followed by three RGB values (for the amounts of red, green, and blue components). The value of *color_number* must be between ``0`` and - `COLORS - 1`. Each of *r*, *g*, *b*, must be a value between ``0`` and + ``COLORS - 1``. Each of *r*, *g*, *b*, must be a value between ``0`` and ``1000``. When :func:`init_color` is used, all occurrences of that color on the screen immediately change to the new definition. This function is a no-op on most terminals; it is active only if :func:`can_change_color` returns ``True``. @@ -923,8 +908,8 @@ the following methods and attributes: Encoding used to encode method arguments (Unicode strings and characters). The encoding attribute is inherited from the parent window when a subwindow - is created, for example with :meth:`window.subwin`. By default, the locale - encoding is used (see :func:`locale.getpreferredencoding`). + is created, for example with :meth:`window.subwin`. + By default, current locale encoding is used (see :func:`locale.getencoding`). .. versionadded:: 3.3 @@ -1312,11 +1297,11 @@ the following methods and attributes: :meth:`refresh`. -.. method:: window.vline(ch, n) - window.vline(y, x, ch, n) +.. method:: window.vline(ch, n[, attr]) + window.vline(y, x, ch, n[, attr]) Display a vertical line starting at ``(y, x)`` with length *n* consisting of the - character *ch*. + character *ch* with attributes *attr*. Constants diff --git a/Doc/library/custominterp.rst b/Doc/library/custominterp.rst index 5eeced20a9a..9ea9e901372 100644 --- a/Doc/library/custominterp.rst +++ b/Doc/library/custominterp.rst @@ -8,7 +8,7 @@ The modules described in this chapter allow writing interfaces similar to Python's interactive interpreter. If you want a Python interpreter that supports some special feature in addition to the Python language, you should look at the :mod:`code` module. (The :mod:`codeop` module is lower-level, used -to support compiling a possibly-incomplete chunk of Python code.) +to support compiling a possibly incomplete chunk of Python code.) The full list of modules described in this chapter is: diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst index a7144094c68..82faa7b7745 100644 --- a/Doc/library/dataclasses.rst +++ b/Doc/library/dataclasses.rst @@ -46,7 +46,7 @@ directly specified in the ``InventoryItem`` definition shown above. Module contents --------------- -.. decorator:: dataclass(*, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False) +.. decorator:: dataclass(*, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False) This function is a :term:`decorator` that is used to add generated :term:`special method`\s to classes, as described below. @@ -79,9 +79,10 @@ Module contents class C: ... - @dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False) + @dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, + match_args=True, kw_only=False, slots=False, weakref_slot=False) class C: - ... + ... The parameters to :func:`dataclass` are: @@ -188,6 +189,23 @@ Module contents .. versionadded:: 3.10 + .. versionchanged:: 3.11 + If a field name is already included in the ``__slots__`` + of a base class, it will not be included in the generated ``__slots__`` + to prevent :ref:`overriding them `. + Therefore, do not use ``__slots__`` to retrieve the field names of a + dataclass. Use :func:`fields` instead. + To be able to determine inherited slots, + base class ``__slots__`` may be any iterable, but *not* an iterator. + + + - ``weakref_slot``: If true (the default is ``False``), add a slot + named "__weakref__", which is required to make an instance + weakref-able. It is an error to specify ``weakref_slot=True`` + without also specifying ``slots=True``. + + .. versionadded:: 3.11 + ``field``\s may optionally specify a default value, using normal Python syntax:: @@ -319,12 +337,15 @@ Module contents Raises :exc:`TypeError` if not passed a dataclass or instance of one. Does not return pseudo-fields which are ``ClassVar`` or ``InitVar``. -.. function:: asdict(instance, *, dict_factory=dict) +.. function:: asdict(obj, *, dict_factory=dict) - Converts the dataclass ``instance`` to a dict (by using the + Converts the dataclass ``obj`` to a dict (by using the factory function ``dict_factory``). Each dataclass is converted to a dict of its fields, as ``name: value`` pairs. dataclasses, dicts, - lists, and tuples are recursed into. For example:: + lists, and tuples are recursed into. Other objects are copied with + :func:`copy.deepcopy`. + + Example of using :func:`asdict` on nested dataclasses:: @dataclass class Point: @@ -341,23 +362,34 @@ Module contents c = C([Point(0, 0), Point(10, 4)]) assert asdict(c) == {'mylist': [{'x': 0, 'y': 0}, {'x': 10, 'y': 4}]} - Raises :exc:`TypeError` if ``instance`` is not a dataclass instance. + To create a shallow copy, the following workaround may be used:: -.. function:: astuple(instance, *, tuple_factory=tuple) + dict((field.name, getattr(obj, field.name)) for field in fields(obj)) - Converts the dataclass ``instance`` to a tuple (by using the + :func:`asdict` raises :exc:`TypeError` if ``obj`` is not a dataclass + instance. + +.. function:: astuple(obj, *, tuple_factory=tuple) + + Converts the dataclass ``obj`` to a tuple (by using the factory function ``tuple_factory``). Each dataclass is converted to a tuple of its field values. dataclasses, dicts, lists, and - tuples are recursed into. + tuples are recursed into. Other objects are copied with + :func:`copy.deepcopy`. Continuing from the previous example:: assert astuple(p) == (10, 20) assert astuple(c) == ([(0, 0), (10, 4)],) - Raises :exc:`TypeError` if ``instance`` is not a dataclass instance. + To create a shallow copy, the following workaround may be used:: -.. function:: make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False) + tuple(getattr(obj, field.name) for field in dataclasses.fields(obj)) + + :func:`astuple` raises :exc:`TypeError` if ``obj`` is not a dataclass + instance. + +.. function:: make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False) Creates a new dataclass with name ``cls_name``, fields as defined in ``fields``, base classes as given in ``bases``, and initialized @@ -366,8 +398,8 @@ Module contents or ``(name, type, Field)``. If just ``name`` is supplied, ``typing.Any`` is used for ``type``. The values of ``init``, ``repr``, ``eq``, ``order``, ``unsafe_hash``, ``frozen``, - ``match_args``, ``kw_only``, and ``slots`` have the same meaning as - they do in :func:`dataclass`. + ``match_args``, ``kw_only``, ``slots``, and ``weakref_slot`` have + the same meaning as they do in :func:`dataclass`. This function is not strictly required, because any Python mechanism for creating a new class with ``__annotations__`` can @@ -392,10 +424,10 @@ Module contents def add_one(self): return self.x + 1 -.. function:: replace(instance, /, **changes) +.. function:: replace(obj, /, **changes) - Creates a new object of the same type as ``instance``, replacing - fields with values from ``changes``. If ``instance`` is not a Data + Creates a new object of the same type as ``obj``, replacing + fields with values from ``changes``. If ``obj`` is not a Data Class, raises :exc:`TypeError`. If values in ``changes`` do not specify fields, raises :exc:`TypeError`. @@ -420,7 +452,7 @@ Module contents ``replace()`` (or similarly named) method which handles instance copying. -.. function:: is_dataclass(class_or_instance) +.. function:: is_dataclass(obj) Return ``True`` if its parameter is a dataclass or an instance of one, otherwise return ``False``. @@ -451,16 +483,18 @@ Module contents @dataclass class Point: - x: float - _: KW_ONLY - y: float - z: float + x: float + _: KW_ONLY + y: float + z: float p = Point(0, y=1.5, z=2.0) In a single dataclass, it is an error to specify more than one field whose type is :const:`KW_ONLY`. + .. versionadded:: 3.10 + .. exception:: FrozenInstanceError Raised when an implicitly defined :meth:`__setattr__` or @@ -518,7 +552,7 @@ parameters to :meth:`__post_init__`. Also see the warning about how Class variables --------------- -One of two places where :func:`dataclass` actually inspects the type +One of the few places where :func:`dataclass` actually inspects the type of a field is to determine if a field is a class variable as defined in :pep:`526`. It does this by checking if the type of the field is ``typing.ClassVar``. If a field is a ``ClassVar``, it is excluded @@ -529,7 +563,7 @@ module-level :func:`fields` function. Init-only variables ------------------- -The other place where :func:`dataclass` inspects a type annotation is to +Another place where :func:`dataclass` inspects a type annotation is to determine if a field is an init-only variable. It does this by seeing if the type of a field is of type ``dataclasses.InitVar``. If a field is an ``InitVar``, it is considered a pseudo-field called an init-only @@ -545,8 +579,8 @@ value is not provided when creating the class:: @dataclass class C: i: int - j: int = None - database: InitVar[DatabaseType] = None + j: int | None = None + database: InitVar[DatabaseType | None] = None def __post_init__(self, database): if self.j is None and database is not None: @@ -639,74 +673,131 @@ re-ordered :meth:`__init__` parameter list. Default factory functions ------------------------- - If a :func:`field` specifies a ``default_factory``, it is called with - zero arguments when a default value for the field is needed. For - example, to create a new instance of a list, use:: +If a :func:`field` specifies a ``default_factory``, it is called with +zero arguments when a default value for the field is needed. For +example, to create a new instance of a list, use:: - mylist: list = field(default_factory=list) + mylist: list = field(default_factory=list) - If a field is excluded from :meth:`__init__` (using ``init=False``) - and the field also specifies ``default_factory``, then the default - factory function will always be called from the generated - :meth:`__init__` function. This happens because there is no other - way to give the field an initial value. +If a field is excluded from :meth:`__init__` (using ``init=False``) +and the field also specifies ``default_factory``, then the default +factory function will always be called from the generated +:meth:`__init__` function. This happens because there is no other +way to give the field an initial value. Mutable default values ---------------------- - Python stores default member variable values in class attributes. - Consider this example, not using dataclasses:: +Python stores default member variable values in class attributes. +Consider this example, not using dataclasses:: - class C: - x = [] - def add(self, element): - self.x.append(element) + class C: + x = [] + def add(self, element): + self.x.append(element) - o1 = C() - o2 = C() - o1.add(1) - o2.add(2) - assert o1.x == [1, 2] - assert o1.x is o2.x + o1 = C() + o2 = C() + o1.add(1) + o2.add(2) + assert o1.x == [1, 2] + assert o1.x is o2.x - Note that the two instances of class ``C`` share the same class - variable ``x``, as expected. +Note that the two instances of class ``C`` share the same class +variable ``x``, as expected. - Using dataclasses, *if* this code was valid:: +Using dataclasses, *if* this code was valid:: - @dataclass - class D: - x: List = [] - def add(self, element): - self.x += element + @dataclass + class D: + x: List = [] + def add(self, element): + self.x += element - it would generate code similar to:: +it would generate code similar to:: - class D: - x = [] - def __init__(self, x=x): - self.x = x - def add(self, element): - self.x += element + class D: + x = [] + def __init__(self, x=x): + self.x = x + def add(self, element): + self.x += element - assert D().x is D().x + assert D().x is D().x - This has the same issue as the original example using class ``C``. - That is, two instances of class ``D`` that do not specify a value - for ``x`` when creating a class instance will share the same copy - of ``x``. Because dataclasses just use normal Python class - creation they also share this behavior. There is no general way - for Data Classes to detect this condition. Instead, the - :func:`dataclass` decorator will raise a :exc:`TypeError` if it - detects a default parameter of type ``list``, ``dict``, or ``set``. - This is a partial solution, but it does protect against many common - errors. +This has the same issue as the original example using class ``C``. +That is, two instances of class ``D`` that do not specify a value +for ``x`` when creating a class instance will share the same copy +of ``x``. Because dataclasses just use normal Python class +creation they also share this behavior. There is no general way +for Data Classes to detect this condition. Instead, the +:func:`dataclass` decorator will raise a :exc:`TypeError` if it +detects an unhashable default parameter. The assumption is that if +a value is unhashable, it is mutable. This is a partial solution, +but it does protect against many common errors. - Using default factory functions is a way to create new instances of - mutable types as default values for fields:: +Using default factory functions is a way to create new instances of +mutable types as default values for fields:: - @dataclass - class D: - x: list = field(default_factory=list) + @dataclass + class D: + x: list = field(default_factory=list) - assert D().x is not D().x + assert D().x is not D().x + +.. versionchanged:: 3.11 + Instead of looking for and disallowing objects of type ``list``, + ``dict``, or ``set``, unhashable objects are now not allowed as + default values. Unhashability is used to approximate + mutability. + +Descriptor-typed fields +----------------------- + +Fields that are assigned :ref:`descriptor objects ` as their +default value have the following special behaviors: + +* The value for the field passed to the dataclass's ``__init__`` method is + passed to the descriptor's ``__set__`` method rather than overwriting the + descriptor object. +* Similarly, when getting or setting the field, the descriptor's + ``__get__`` or ``__set__`` method is called rather than returning or + overwriting the descriptor object. +* To determine whether a field contains a default value, ``dataclasses`` + will call the descriptor's ``__get__`` method using its class access + form (i.e. ``descriptor.__get__(obj=None, type=cls)``. If the + descriptor returns a value in this case, it will be used as the + field's default. On the other hand, if the descriptor raises + :exc:`AttributeError` in this situation, no default value will be + provided for the field. + +:: + + class IntConversionDescriptor: + def __init__(self, *, default): + self._default = default + + def __set_name__(self, owner, name): + self._name = "_" + name + + def __get__(self, obj, type): + if obj is None: + return self._default + + return getattr(obj, self._name, self._default) + + def __set__(self, obj, value): + setattr(obj, self._name, int(value)) + + @dataclass + class InventoryItem: + quantity_on_hand: IntConversionDescriptor = IntConversionDescriptor(default=100) + + i = InventoryItem() + print(i.quantity_on_hand) # 100 + i.quantity_on_hand = 2.5 # calls __set__ with 2.5 + print(i.quantity_on_hand) # 2 + +Note that if a field is annotated with a descriptor type, but is not assigned +a descriptor object as its default value, the field will act like a normal +field. diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 0f8b70cdedb..ebb5f319efd 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -84,6 +84,12 @@ The :mod:`datetime` module exports the following constants: The largest year number allowed in a :class:`date` or :class:`.datetime` object. :const:`MAXYEAR` is ``9999``. +.. attribute:: UTC + + Alias for the UTC timezone singleton :attr:`datetime.timezone.utc`. + + .. versionadded:: 3.11 + Available Types --------------- @@ -520,18 +526,20 @@ Other constructors, all class methods: .. classmethod:: date.fromisoformat(date_string) - Return a :class:`date` corresponding to a *date_string* given in the format - ``YYYY-MM-DD``:: + Return a :class:`date` corresponding to a *date_string* given in any valid + ISO 8601 format, except ordinal dates (e.g. ``YYYY-DDD``):: >>> from datetime import date >>> date.fromisoformat('2019-12-04') datetime.date(2019, 12, 4) - - This is the inverse of :meth:`date.isoformat`. It only supports the format - ``YYYY-MM-DD``. + >>> date.fromisoformat('20191204') + datetime.date(2019, 12, 4) + >>> date.fromisoformat('2021-W01-1') + datetime.date(2021, 1, 4) .. versionadded:: 3.7 - + .. versionchanged:: 3.11 + Previously, this method only supported the format ``YYYY-MM-DD``. .. classmethod:: date.fromisocalendar(year, week, day) @@ -581,8 +589,8 @@ Supported operations: +-------------------------------+----------------------------------------------+ | Operation | Result | +===============================+==============================================+ -| ``date2 = date1 + timedelta`` | *date2* is ``timedelta.days`` days removed | -| | from *date1*. (1) | +| ``date2 = date1 + timedelta`` | *date2* will be ``timedelta.days`` days | +| | after *date1*. (1) | +-------------------------------+----------------------------------------------+ | ``date2 = date1 - timedelta`` | Computes *date2* such that ``date2 + | | | timedelta == date1``. (2) | @@ -704,8 +712,6 @@ Instance methods: >>> date(2002, 12, 4).isoformat() '2002-12-04' - This is the inverse of :meth:`date.fromisoformat`. - .. method:: date.__str__() For a date *d*, ``str(d)`` is equivalent to ``d.isoformat()``. @@ -759,6 +765,7 @@ Example of counting days to an event:: >>> my_birthday = date(today.year, 6, 24) >>> if my_birthday < today: ... my_birthday = my_birthday.replace(year=today.year + 1) + ... >>> my_birthday datetime.date(2008, 6, 24) >>> time_to_birthday = abs(my_birthday - today) @@ -975,12 +982,11 @@ Other constructors, all class methods: are equal to the given :class:`.time` object's. If the *tzinfo* argument is provided, its value is used to set the :attr:`.tzinfo` attribute of the result, otherwise the :attr:`~.time.tzinfo` attribute of the *time* argument - is used. + is used. If the *date* argument is a :class:`.datetime` object, its time components + and :attr:`.tzinfo` attributes are ignored. For any :class:`.datetime` object *d*, - ``d == datetime.combine(d.date(), d.time(), d.tzinfo)``. If date is a - :class:`.datetime` object, its time components and :attr:`.tzinfo` attributes - are ignored. + ``d == datetime.combine(d.date(), d.time(), d.tzinfo)``. .. versionchanged:: 3.6 Added the *tzinfo* argument. @@ -988,31 +994,29 @@ Other constructors, all class methods: .. classmethod:: datetime.fromisoformat(date_string) - Return a :class:`.datetime` corresponding to a *date_string* in one of the - formats emitted by :meth:`date.isoformat` and :meth:`datetime.isoformat`. + Return a :class:`.datetime` corresponding to a *date_string* in any valid + ISO 8601 format, with the following exceptions: - Specifically, this function supports strings in the format: - - .. code-block:: none - - YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]] - - where ``*`` can match any single character. - - .. caution:: - - This does *not* support parsing arbitrary ISO 8601 strings - it is only intended - as the inverse operation of :meth:`datetime.isoformat`. A more full-featured - ISO 8601 parser, ``dateutil.parser.isoparse`` is available in the third-party package - `dateutil `__. + 1. Time zone offsets may have fractional seconds. + 2. The ``T`` separator may be replaced by any single unicode character. + 3. Ordinal dates are not currently supported. + 4. Fractional hours and minutes are not supported. Examples:: >>> from datetime import datetime >>> datetime.fromisoformat('2011-11-04') datetime.datetime(2011, 11, 4, 0, 0) + >>> datetime.fromisoformat('20111104') + datetime.datetime(2011, 11, 4, 0, 0) >>> datetime.fromisoformat('2011-11-04T00:05:23') datetime.datetime(2011, 11, 4, 0, 5, 23) + >>> datetime.fromisoformat('2011-11-04T00:05:23Z') + datetime.datetime(2011, 11, 4, 0, 5, 23, tzinfo=datetime.timezone.utc) + >>> datetime.fromisoformat('20111104T000523') + datetime.datetime(2011, 11, 4, 0, 5, 23) + >>> datetime.fromisoformat('2011-W01-2T00:05:23.283') + datetime.datetime(2011, 1, 4, 0, 5, 23, 283000) >>> datetime.fromisoformat('2011-11-04 00:05:23.283') datetime.datetime(2011, 11, 4, 0, 5, 23, 283000) >>> datetime.fromisoformat('2011-11-04 00:05:23.283+00:00') @@ -1022,6 +1026,10 @@ Other constructors, all class methods: tzinfo=datetime.timezone(datetime.timedelta(seconds=14400))) .. versionadded:: 3.7 + .. versionchanged:: 3.11 + Previously, this method only supported formats that could be emitted by + :meth:`date.isoformat()` or :meth:`datetime.isoformat()`. + .. classmethod:: datetime.fromisocalendar(year, week, day) @@ -1342,7 +1350,7 @@ Instance methods: Because naive ``datetime`` objects are treated by many ``datetime`` methods as local times, it is preferred to use aware datetimes to represent times - in UTC; as a result, using ``utcfromtimetuple`` may give misleading + in UTC; as a result, using :meth:`datetime.utctimetuple` may give misleading results. If you have a naive ``datetime`` representing UTC, use ``datetime.replace(tzinfo=timezone.utc)`` to make it aware, at which point you can use :meth:`.datetime.timetuple`. @@ -1362,8 +1370,8 @@ Instance methods: time and this method relies on the platform C :c:func:`mktime` function to perform the conversion. Since :class:`.datetime` supports wider range of values than :c:func:`mktime` on many - platforms, this method may raise :exc:`OverflowError` for times far - in the past or far in the future. + platforms, this method may raise :exc:`OverflowError` or :exc:`OSError` + for times far in the past or far in the future. For aware :class:`.datetime` instances, the return value is computed as:: @@ -1757,30 +1765,41 @@ Other constructor: .. classmethod:: time.fromisoformat(time_string) - Return a :class:`.time` corresponding to a *time_string* in one of the - formats emitted by :meth:`time.isoformat`. Specifically, this function supports - strings in the format: + Return a :class:`.time` corresponding to a *time_string* in any valid + ISO 8601 format, with the following exceptions: - .. code-block:: none - - HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]] - - .. caution:: - - This does *not* support parsing arbitrary ISO 8601 strings. It is only - intended as the inverse operation of :meth:`time.isoformat`. + 1. Time zone offsets may have fractional seconds. + 2. The leading ``T``, normally required in cases where there may be ambiguity between + a date and a time, is not required. + 3. Fractional seconds may have any number of digits (anything beyond 6 will + be truncated). + 4. Fractional hours and minutes are not supported. Examples:: >>> from datetime import time >>> time.fromisoformat('04:23:01') datetime.time(4, 23, 1) + >>> time.fromisoformat('T04:23:01') + datetime.time(4, 23, 1) + >>> time.fromisoformat('T042301') + datetime.time(4, 23, 1) >>> time.fromisoformat('04:23:01.000384') datetime.time(4, 23, 1, 384) + >>> time.fromisoformat('04:23:01,000') + datetime.time(4, 23, 1, 384) >>> time.fromisoformat('04:23:01+04:00') datetime.time(4, 23, 1, tzinfo=datetime.timezone(datetime.timedelta(seconds=14400))) + >>> time.fromisoformat('04:23:01Z') + datetime.time(4, 23, 1, tzinfo=datetime.timezone.utc) + >>> time.fromisoformat('04:23:01+00:00') + datetime.time(4, 23, 1, tzinfo=datetime.timezone.utc) + .. versionadded:: 3.7 + .. versionchanged:: 3.11 + Previously, this method only supported formats that could be emitted by + :meth:`time.isoformat()`. Instance methods: @@ -2246,7 +2265,7 @@ where historical changes have been made to civil time. two digits of ``offset.hours`` and ``offset.minutes`` respectively. .. versionchanged:: 3.6 - Name generated from ``offset=timedelta(0)`` is now plain `'UTC'`, not + Name generated from ``offset=timedelta(0)`` is now plain ``'UTC'``, not ``'UTC+00:00'``. @@ -2359,8 +2378,8 @@ requires, and these work on all platforms with a standard C implementation. | | decimal number. | | \(9) | +-----------+--------------------------------+------------------------+-------+ | ``%f`` | Microsecond as a decimal | 000000, 000001, ..., | \(5) | -| | number, zero-padded on the | 999999 | | -| | left. | | | +| | number, zero-padded to 6 | 999999 | | +| | digits. | | | +-----------+--------------------------------+------------------------+-------+ | ``%z`` | UTC offset in the form | (empty), +0000, | \(6) | | | ``±HHMM[SS[.ffffff]]`` (empty | -0400, +1030, | | @@ -2375,7 +2394,7 @@ requires, and these work on all platforms with a standard C implementation. +-----------+--------------------------------+------------------------+-------+ | ``%U`` | Week number of the year | 00, 01, ..., 53 | \(7), | | | (Sunday as the first day of | | \(9) | -| | the week) as a zero padded | | | +| | the week) as a zero-padded | | | | | decimal number. All days in a | | | | | new year preceding the first | | | | | Sunday are considered to be in | | | @@ -2383,10 +2402,10 @@ requires, and these work on all platforms with a standard C implementation. +-----------+--------------------------------+------------------------+-------+ | ``%W`` | Week number of the year | 00, 01, ..., 53 | \(7), | | | (Monday as the first day of | | \(9) | -| | the week) as a decimal number. | | | -| | All days in a new year | | | -| | preceding the first Monday | | | -| | are considered to be in | | | +| | the week) as a zero-padded | | | +| | decimal number. All days in a | | | +| | new year preceding the first | | | +| | Monday are considered to be in | | | | | week 0. | | | +-----------+--------------------------------+------------------------+-------+ | ``%c`` | Locale's appropriate date and || Tue Aug 16 21:30:00 | \(1) | @@ -2424,6 +2443,11 @@ convenience. These parameters all correspond to ISO 8601 date values. | | Week 01 is the week containing | | | | | Jan 4. | | | +-----------+--------------------------------+------------------------+-------+ +| ``%:z`` | UTC offset in the form | (empty), +00:00, | \(6) | +| | ``±HH:MM[:SS[.ffffff]]`` | -04:00, +10:30, | | +| | (empty string if the object is | +06:34:15, | | +| | naive). | -03:07:12.345216 | | ++-----------+--------------------------------+------------------------+-------+ These may not be available on all platforms when used with the :meth:`strftime` method. The ISO 8601 year and ISO 8601 week directives are not interchangeable @@ -2439,6 +2463,9 @@ differences between platforms in handling of unsupported format specifiers. .. versionadded:: 3.6 ``%G``, ``%u`` and ``%V`` were added. +.. versionadded:: 3.12 + ``%:z`` was added. + Technical Detail ^^^^^^^^^^^^^^^^ @@ -2511,8 +2538,8 @@ Notes: available). (6) - For a naive object, the ``%z`` and ``%Z`` format codes are replaced by empty - strings. + For a naive object, the ``%z``, ``%:z`` and ``%Z`` format codes are replaced + by empty strings. For an aware object: @@ -2538,6 +2565,10 @@ Notes: For example, ``'+01:00:00'`` will be parsed as an offset of one hour. In addition, providing ``'Z'`` is identical to ``'+00:00'``. + ``%:z`` + Behaves exactly as ``%z``, but has a colon separator added between + hours, minutes and seconds. + ``%Z`` In :meth:`strftime`, ``%Z`` is replaced by an empty string if :meth:`tzname` returns ``None``; otherwise ``%Z`` is replaced by the @@ -2570,7 +2601,7 @@ Notes: (9) When used with the :meth:`strptime` method, the leading zero is optional - for formats ``%d``, ``%m``, ``%H``, ``%I``, ``%M``, ``%S``, ``%J``, ``%U``, + for formats ``%d``, ``%m``, ``%H``, ``%I``, ``%M``, ``%S``, ``%j``, ``%U``, ``%W``, and ``%V``. Format ``%y`` does require a leading zero. .. rubric:: Footnotes @@ -2584,7 +2615,7 @@ Notes: many other calendar systems. .. [#] See R. H. van Gent's `guide to the mathematics of the ISO 8601 calendar - `_ + `_ for a good explanation. .. [#] Passing ``datetime.strptime('Feb 29', '%b %d')`` will fail since ``1900`` is not a leap year. diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index e759c5cf23b..fec9b86864c 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -30,7 +30,7 @@ -------------- -The :mod:`decimal` module provides support for fast correctly-rounded +The :mod:`decimal` module provides support for fast correctly rounded decimal floating point arithmetic. It offers several advantages over the :class:`float` datatype: @@ -114,7 +114,7 @@ reset them before monitoring a calculation. .. seealso:: * IBM's General Decimal Arithmetic Specification, `The General Decimal Arithmetic - Specification `_. + Specification `_. .. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -571,15 +571,16 @@ Decimal objects >>> Decimal(321).exp() Decimal('2.561702493119680037517373933E+139') - .. method:: from_float(f) + .. classmethod:: from_float(f) - Classmethod that converts a float to a decimal number, exactly. + Alternative constructor that only accepts instances of :class:`float` or + :class:`int`. - Note `Decimal.from_float(0.1)` is not the same as `Decimal('0.1')`. + Note ``Decimal.from_float(0.1)`` is not the same as ``Decimal('0.1')``. Since 0.1 is not exactly representable in binary floating point, the value is stored as the nearest representable value which is - `0x1.999999999999ap-4`. That equivalent value in decimal is - `0.1000000000000000055511151231257827021181583404541015625`. + ``0x1.999999999999ap-4``. That equivalent value in decimal is + ``0.1000000000000000055511151231257827021181583404541015625``. .. note:: From Python 3.2 onwards, a :class:`Decimal` instance can also be constructed directly from a :class:`float`. @@ -925,12 +926,13 @@ Each thread has its own current context which is accessed or changed using the You can also use the :keyword:`with` statement and the :func:`localcontext` function to temporarily change the active context. -.. function:: localcontext(ctx=None) +.. function:: localcontext(ctx=None, \*\*kwargs) Return a context manager that will set the current context for the active thread to a copy of *ctx* on entry to the with-statement and restore the previous context when exiting the with-statement. If no context is specified, a copy of the - current context is used. + current context is used. The *kwargs* argument is used to set the attributes + of the new context. For example, the following code sets the current decimal precision to 42 places, performs a calculation, and then automatically restores the previous context:: @@ -942,6 +944,21 @@ function to temporarily change the active context. s = calculate_something() s = +s # Round the final result back to the default precision + Using keyword arguments, the code would be the following:: + + from decimal import localcontext + + with localcontext(prec=42) as ctx: + s = calculate_something() + s = +s + + Raises :exc:`TypeError` if *kwargs* supplies an attribute that :class:`Context` doesn't + support. Raises either :exc:`TypeError` or :exc:`ValueError` if *kwargs* supplies an + invalid value for an attribute. + + .. versionchanged:: 3.11 + :meth:`localcontext` now supports setting context attributes through the use of keyword arguments. + New contexts can also be created using the :class:`Context` constructor described below. In addition, the module provides three pre-made contexts: @@ -1192,7 +1209,7 @@ In addition to the three supplied contexts, new contexts can be created with the .. method:: exp(x) - Returns `e ** x`. + Returns ``e ** x``. .. method:: fma(x, y, z) @@ -1354,16 +1371,16 @@ In addition to the three supplied contexts, new contexts can be created with the With two arguments, compute ``x**y``. If ``x`` is negative then ``y`` must be integral. The result will be inexact unless ``y`` is integral and the result is finite and can be expressed exactly in 'precision' digits. - The rounding mode of the context is used. Results are always correctly-rounded + The rounding mode of the context is used. Results are always correctly rounded in the Python version. ``Decimal(0) ** Decimal(0)`` results in ``InvalidOperation``, and if ``InvalidOperation`` is not trapped, then results in ``Decimal('NaN')``. .. versionchanged:: 3.3 - The C module computes :meth:`power` in terms of the correctly-rounded + The C module computes :meth:`power` in terms of the correctly rounded :meth:`exp` and :meth:`ln` functions. The result is well-defined but - only "almost always correctly-rounded". + only "almost always correctly rounded". With three arguments, compute ``(x**y) % modulo``. For the three argument form, the following restrictions on the arguments hold: @@ -2040,6 +2057,7 @@ to handle the :meth:`quantize` step: >>> def mul(x, y, fp=TWOPLACES): ... return (x * y).quantize(fp) + ... >>> def div(x, y, fp=TWOPLACES): ... return (x / y).quantize(fp) @@ -2134,7 +2152,7 @@ Q. Is the CPython implementation fast for large numbers? A. Yes. In the CPython and PyPy3 implementations, the C/CFFI versions of the decimal module integrate the high speed `libmpdec `_ library for -arbitrary precision correctly-rounded decimal floating point arithmetic [#]_. +arbitrary precision correctly rounded decimal floating point arithmetic [#]_. ``libmpdec`` uses `Karatsuba multiplication `_ for medium-sized numbers and the `Number Theoretic Transform diff --git a/Doc/library/devmode.rst b/Doc/library/devmode.rst index 44e7d4f541d..977735990ff 100644 --- a/Doc/library/devmode.rst +++ b/Doc/library/devmode.rst @@ -21,7 +21,7 @@ Effects of the Python Development Mode Enabling the Python Development Mode is similar to the following command, but with additional effects described below:: - PYTHONMALLOC=debug PYTHONASYNCIODEBUG=1 python3 -W default -X faulthandler + PYTHONMALLOC=debug PYTHONASYNCIODEBUG=1 python -W default -X faulthandler Effects of the Python Development Mode: @@ -128,14 +128,14 @@ any warning. Example using README.txt, which has 269 lines: .. code-block:: shell-session - $ python3 script.py README.txt + $ python script.py README.txt 269 Enabling the Python Development Mode displays a :exc:`ResourceWarning` warning: .. code-block:: shell-session - $ python3 -X dev script.py README.txt + $ python -X dev script.py README.txt 269 script.py:10: ResourceWarning: unclosed file <_io.TextIOWrapper name='README.rst' mode='r' encoding='UTF-8'> main() @@ -146,7 +146,7 @@ opened: .. code-block:: shell-session - $ python3 -X dev -X tracemalloc=5 script.py README.rst + $ python -X dev -X tracemalloc=5 script.py README.rst 269 script.py:10: ResourceWarning: unclosed file <_io.TextIOWrapper name='README.rst' mode='r' encoding='UTF-8'> main() @@ -190,7 +190,7 @@ By default, Python does not emit any warning: .. code-block:: shell-session - $ python3 script.py + $ python script.py import os The Python Development Mode shows a :exc:`ResourceWarning` and logs a "Bad file @@ -198,7 +198,7 @@ descriptor" error when finalizing the file object: .. code-block:: shell-session - $ python3 script.py + $ python script.py import os script.py:10: ResourceWarning: unclosed file <_io.TextIOWrapper name='script.py' mode='r' encoding='UTF-8'> main() diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index aa08988c8b3..5ee1f4a02c6 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -79,7 +79,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. Lines beginning with '``?``' attempt to guide the eye to intraline differences, and were not present in either input sequence. These lines can be confusing if - the sequences contain tab characters. + the sequences contain whitespace characters, such as spaces, tabs or line breaks. .. class:: HtmlDiff @@ -145,11 +145,9 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. The arguments for this method are the same as those for the :meth:`make_file` method. - :file:`Tools/scripts/diff.py` is a command-line front-end to this class and - contains a good example of its use. -.. function:: context_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\\n') +.. function:: context_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\n') Compare *a* and *b* (lists of strings); return a delta (a :term:`generator` generating the delta lines) in context diff format. @@ -240,8 +238,6 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. function :func:`IS_CHARACTER_JUNK`, which filters out whitespace characters (a blank or tab; it's a bad idea to include newline in this!). - :file:`Tools/scripts/ndiff.py` is a command-line front-end to this function. - >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(keepends=True), ... 'ore\ntree\nemu\n'.splitlines(keepends=True)) >>> print(''.join(diff), end="") @@ -279,7 +275,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. emu -.. function:: unified_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\\n') +.. function:: unified_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\n') Compare *a* and *b* (lists of strings); return a delta (a :term:`generator` generating the delta lines) in unified diff format. @@ -321,7 +317,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. See :ref:`difflib-interface` for a more detailed example. -.. function:: diff_bytes(dfunc, a, b, fromfile=b'', tofile=b'', fromfiledate=b'', tofiledate=b'', n=3, lineterm=b'\\n') +.. function:: diff_bytes(dfunc, a, b, fromfile=b'', tofile=b'', fromfiledate=b'', tofiledate=b'', n=3, lineterm=b'\n') Compare *a* and *b* (lists of bytes objects) using *dfunc*; yield a sequence of delta lines (also bytes) in the format returned by *dfunc*. @@ -353,9 +349,9 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. .. seealso:: - `Pattern Matching: The Gestalt Approach `_ + `Pattern Matching: The Gestalt Approach `_ Discussion of a similar algorithm by John W. Ratcliff and D. E. Metzener. This - was published in `Dr. Dobb's Journal `_ in July, 1988. + was published in `Dr. Dobb's Journal `_ in July, 1988. .. _sequence-matcher: @@ -759,7 +755,12 @@ A command-line interface to difflib ----------------------------------- This example shows how to use difflib to create a ``diff``-like utility. -It is also contained in the Python source distribution, as -:file:`Tools/scripts/diff.py`. -.. literalinclude:: ../../Tools/scripts/diff.py +.. literalinclude:: ../includes/diff.py + +ndiff example +------------- + +This example shows how to use :func:`difflib.ndiff`. + +.. literalinclude:: ../includes/ndiff.py diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 5fe9f65f46a..6a68ec4b14b 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -6,6 +6,12 @@ **Source code:** :source:`Lib/dis.py` +.. testsetup:: + + import dis + def myfunc(alist): + return len(alist) + -------------- The :mod:`dis` module supports the analysis of CPython :term:`bytecode` by @@ -24,6 +30,18 @@ interpreter. Use 2 bytes for each instruction. Previously the number of bytes varied by instruction. + .. versionchanged:: 3.10 + The argument of jump, exception handling and loop instructions is now + the instruction offset rather than the byte offset. + + .. versionchanged:: 3.11 + Some instructions are accompanied by one or more inline cache entries, + which take the form of :opcode:`CACHE` instructions. These instructions + are hidden by default, but can be shown by passing ``show_caches=True`` to + any :mod:`dis` utility. Furthermore, the interpreter now adapts the + bytecode to specialize it for different runtime conditions. The + adaptive bytecode can be shown by passing ``adaptive=True``. + Example: Given the function :func:`myfunc`:: @@ -31,13 +49,17 @@ Example: Given the function :func:`myfunc`:: return len(alist) the following command can be used to display the disassembly of -:func:`myfunc`:: +:func:`myfunc`: + +.. doctest:: >>> dis.dis(myfunc) - 2 0 LOAD_GLOBAL 0 (len) - 2 LOAD_FAST 0 (alist) - 4 CALL_FUNCTION 1 - 6 RETURN_VALUE + 2 0 RESUME 0 + + 3 2 LOAD_GLOBAL 1 (NULL + len) + 14 LOAD_FAST 0 (alist) + 16 CALL 1 + 26 RETURN_VALUE (The "2" is a line number). @@ -50,8 +72,8 @@ The bytecode analysis API allows pieces of Python code to be wrapped in a :class:`Bytecode` object that provides easy access to details of the compiled code. -.. class:: Bytecode(x, *, first_line=None, current_offset=None) - +.. class:: Bytecode(x, *, first_line=None, current_offset=None,\ + show_caches=False, adaptive=False) Analyse the bytecode corresponding to a function, generator, asynchronous generator, coroutine, method, string of source code, or a code object (as @@ -70,7 +92,13 @@ code. disassembled code. Setting this means :meth:`.dis` will display a "current instruction" marker against the specified opcode. - .. classmethod:: from_traceback(tb) + If *show_caches* is ``True``, :meth:`.dis` will display inline cache + entries used by the interpreter to specialize the bytecode. + + If *adaptive* is ``True``, :meth:`.dis` will display specialized bytecode + that may be different from the original bytecode. + + .. classmethod:: from_traceback(tb, *, show_caches=False) Construct a :class:`Bytecode` instance from the given traceback, setting *current_offset* to the instruction responsible for the exception. @@ -96,15 +124,21 @@ code. .. versionchanged:: 3.7 This can now handle coroutine and asynchronous generator objects. -Example:: + .. versionchanged:: 3.11 + Added the *show_caches* and *adaptive* parameters. + +Example: + +.. doctest:: >>> bytecode = dis.Bytecode(myfunc) >>> for instr in bytecode: ... print(instr.opname) ... + RESUME LOAD_GLOBAL LOAD_FAST - CALL_FUNCTION + CALL RETURN_VALUE @@ -146,7 +180,7 @@ operation is being performed, so the intermediate analysis object isn't useful: Added *file* parameter. -.. function:: dis(x=None, *, file=None, depth=None) +.. function:: dis(x=None, *, file=None, depth=None, show_caches=False, adaptive=False) Disassemble the *x* object. *x* can denote either a module, a class, a method, a function, a generator, an asynchronous generator, a coroutine, @@ -167,6 +201,12 @@ operation is being performed, so the intermediate analysis object isn't useful: The maximal depth of recursion is limited by *depth* unless it is ``None``. ``depth=0`` means no recursion. + If *show_caches* is ``True``, this function will display inline cache + entries used by the interpreter to specialize the bytecode. + + If *adaptive* is ``True``, this function will display specialized bytecode + that may be different from the original bytecode. + .. versionchanged:: 3.4 Added *file* parameter. @@ -176,8 +216,11 @@ operation is being performed, so the intermediate analysis object isn't useful: .. versionchanged:: 3.7 This can now handle coroutine and asynchronous generator objects. + .. versionchanged:: 3.11 + Added the *show_caches* and *adaptive* parameters. -.. function:: distb(tb=None, *, file=None) + +.. function:: distb(tb=None, *, file=None, show_caches=False, adaptive=False) Disassemble the top-of-stack function of a traceback, using the last traceback if none was passed. The instruction causing the exception is @@ -189,9 +232,12 @@ operation is being performed, so the intermediate analysis object isn't useful: .. versionchanged:: 3.4 Added *file* parameter. + .. versionchanged:: 3.11 + Added the *show_caches* and *adaptive* parameters. -.. function:: disassemble(code, lasti=-1, *, file=None) - disco(code, lasti=-1, *, file=None) + +.. function:: disassemble(code, lasti=-1, *, file=None, show_caches=False, adaptive=False) + disco(code, lasti=-1, *, file=None, show_caches=False, adaptive=False) Disassemble a code object, indicating the last instruction if *lasti* was provided. The output is divided in the following columns: @@ -213,8 +259,11 @@ operation is being performed, so the intermediate analysis object isn't useful: .. versionchanged:: 3.4 Added *file* parameter. + .. versionchanged:: 3.11 + Added the *show_caches* and *adaptive* parameters. -.. function:: get_instructions(x, *, first_line=None) + +.. function:: get_instructions(x, *, first_line=None, show_caches=False, adaptive=False) Return an iterator over the instructions in the supplied function, method, source code string or code object. @@ -227,20 +276,27 @@ operation is being performed, so the intermediate analysis object isn't useful: source line information (if any) is taken directly from the disassembled code object. + The *show_caches* and *adaptive* parameters work as they do in :func:`dis`. + .. versionadded:: 3.4 + .. versionchanged:: 3.11 + Added the *show_caches* and *adaptive* parameters. + .. function:: findlinestarts(code) - This generator function uses the ``co_firstlineno`` and ``co_lnotab`` - attributes of the code object *code* to find the offsets which are starts of + This generator function uses the ``co_lines`` method + of the code object *code* to find the offsets which are starts of lines in the source code. They are generated as ``(offset, lineno)`` pairs. - See :source:`Objects/lnotab_notes.txt` for the ``co_lnotab`` format and - how to decode it. .. versionchanged:: 3.6 Line numbers can be decreasing. Before, they were always increasing. + .. versionchanged:: 3.10 + The :pep:`626` ``co_lines`` method is used instead of the ``co_firstlineno`` + and ``co_lnotab`` attributes of the code object. + .. function:: findlabels(code) @@ -316,56 +372,98 @@ details of bytecode instructions as :class:`Instruction` instances: ``True`` if other code jumps to here, otherwise ``False`` + + .. data:: positions + + :class:`dis.Positions` object holding the + start and end locations that are covered by this instruction. + .. versionadded:: 3.4 + .. versionchanged:: 3.11 + + Field ``positions`` is added. + + +.. class:: Positions + + In case the information is not available, some fields might be ``None``. + + .. data:: lineno + .. data:: end_lineno + .. data:: col_offset + .. data:: end_col_offset + + .. versionadded:: 3.11 + The Python compiler currently generates the following bytecode instructions. **General instructions** +In the following, We will refer to the interpreter stack as STACK and describe +operations on it as if it was a Python list. The top of the stack corresponds to +``STACK[-1]`` in this language. + .. opcode:: NOP - Do nothing code. Used as a placeholder by the bytecode optimizer. + Do nothing code. Used as a placeholder by the bytecode optimizer, and to + generate line tracing events. .. opcode:: POP_TOP - Removes the top-of-stack (TOS) item. + Removes the top-of-stack item.:: + + STACK.pop() -.. opcode:: ROT_TWO +.. opcode:: END_FOR - Swaps the two top-most stack items. + Removes the top two values from the stack. + Equivalent to POP_TOP; POP_TOP. + Used to clean up at the end of loops, hence the name. + + .. versionadded:: 3.12 -.. opcode:: ROT_THREE +.. opcode:: COPY (i) - Lifts second and third stack item one position up, moves top down to position - three. + Push the i-th item to the top of the stack without removing it from its original + location.:: + + assert i > 0 + STACK.append(STACK[-i]) + + .. versionadded:: 3.11 -.. opcode:: ROT_FOUR +.. opcode:: SWAP (i) - Lifts second, third and fourth stack items one position up, moves top down - to position four. + Swap the top of the stack with the i-th element.:: - .. versionadded:: 3.8 + STACK[-i], STACK[-1] = stack[-1], STACK[-i] + + .. versionadded:: 3.11 -.. opcode:: DUP_TOP +.. opcode:: CACHE - Duplicates the reference on top of the stack. + Rather than being an actual instruction, this opcode is used to mark extra + space for the interpreter to cache useful data directly in the bytecode + itself. It is automatically hidden by all ``dis`` utilities, but can be + viewed with ``show_caches=True``. - .. versionadded:: 3.2 + Logically, this space is part of the preceding instruction. Many opcodes + expect to be followed by an exact number of caches, and will instruct the + interpreter to skip over them at runtime. + Populated caches can look like arbitrary instructions, so great care should + be taken when reading or modifying raw, adaptive bytecode containing + quickened data. -.. opcode:: DUP_TOP_TWO - - Duplicates the two references on top of the stack, leaving them in the - same order. - - .. versionadded:: 3.2 + .. versionadded:: 3.11 **Unary operations** @@ -373,89 +471,133 @@ The Python compiler currently generates the following bytecode instructions. Unary operations take the top of the stack, apply the operation, and push the result back on the stack. -.. opcode:: UNARY_POSITIVE - - Implements ``TOS = +TOS``. - .. opcode:: UNARY_NEGATIVE - Implements ``TOS = -TOS``. + Implements ``STACK[-1] = -STACK[-1]``. .. opcode:: UNARY_NOT - Implements ``TOS = not TOS``. + Implements ``STACK[-1] = not STACK[-1]``. .. opcode:: UNARY_INVERT - Implements ``TOS = ~TOS``. + Implements ``STACK[-1] = ~STACK[-1]``. .. opcode:: GET_ITER - Implements ``TOS = iter(TOS)``. + Implements ``STACK[-1] = iter(STACK[-1])``. .. opcode:: GET_YIELD_FROM_ITER - If ``TOS`` is a :term:`generator iterator` or :term:`coroutine` object - it is left as is. Otherwise, implements ``TOS = iter(TOS)``. + If ``STACK[-1]`` is a :term:`generator iterator` or :term:`coroutine` object + it is left as is. Otherwise, implements ``STACK[-1] = iter(STACK[-1])``. .. versionadded:: 3.5 **Binary and in-place operations** -Binary operations remove the top of the stack (TOS) and the second top-most -stack item (TOS1) from the stack. They perform the operation, and put the -result back on the stack. +Binary operations remove the top two items from the stack (``STACK[-1]`` and +``STACK[-2]``). They perform the operation, then put the result back on the stack. -In-place operations are like binary operations, in that they remove TOS and -TOS1, and push the result back on the stack, but the operation is done in-place -when TOS1 supports it, and the resulting TOS may be (but does not have to be) -the original TOS1. +In-place operations are like binary operations, but the operation is done in-place +when ``STACK[-2]`` supports it, and the resulting ``STACK[-1]`` may be (but does +not have to be) the original ``STACK[-2]``. .. opcode:: BINARY_OP (op) Implements the binary and in-place operators (depending on the value of - *op*). + *op*).:: + + rhs = STACK.pop() + lhs = STACK.pop() + STACK.append(lhs op rhs) .. versionadded:: 3.11 .. opcode:: BINARY_SUBSCR - Implements ``TOS = TOS1[TOS]``. + Implements:: + + key = STACK.pop() + container = STACK.pop() + STACK.append(container[index]) .. opcode:: STORE_SUBSCR - Implements ``TOS1[TOS] = TOS2``. + Implements:: + + key = STACK.pop() + container = STACK.pop() + value = STACK.pop() + container[key] = value .. opcode:: DELETE_SUBSCR - Implements ``del TOS1[TOS]``. + Implements:: + + key = STACK.pop() + container = STACK.pop() + del container[key] + +.. opcode:: BINARY_SLICE + + Implements:: + + end = STACK.pop() + start = STACK.pop() + container = STACK.pop() + STACK.append(container[start:end]) + + .. versionadded:: 3.12 + + +.. opcode:: STORE_SLICE + + Implements:: + + end = STACK.pop() + start = STACK.pop() + container = STACK.pop() + values = STACK.pop() + container[start:end] = value + + .. versionadded:: 3.12 **Coroutine opcodes** -.. opcode:: GET_AWAITABLE +.. opcode:: GET_AWAITABLE (where) - Implements ``TOS = get_awaitable(TOS)``, where ``get_awaitable(o)`` + Implements ``STACK[-1] = get_awaitable(STACK[-1])``, where ``get_awaitable(o)`` returns ``o`` if ``o`` is a coroutine object or a generator object with the CO_ITERABLE_COROUTINE flag, or resolves ``o.__await__``. + If the ``where`` operand is nonzero, it indicates where the instruction + occurs: + + * ``1`` After a call to ``__aenter__`` + * ``2`` After a call to ``__aexit__`` + .. versionadded:: 3.5 + .. versionchanged:: 3.11 + Previously, this instruction did not have an oparg. + .. opcode:: GET_AITER - Implements ``TOS = TOS.__aiter__()``. + Implements ``STACK[-1] = STACK[-1].__aiter__()``. .. versionadded:: 3.5 .. versionchanged:: 3.7 @@ -465,8 +607,8 @@ the original TOS1. .. opcode:: GET_ANEXT - Implements ``PUSH(get_awaitable(TOS.__anext__()))``. See ``GET_AWAITABLE`` - for details about ``get_awaitable`` + Implement ``STACK.append(get_awaitable(STACK[-1].__anext__()))`` to the stack. + See ``GET_AWAITABLE`` for details about ``get_awaitable``. .. versionadded:: 3.5 @@ -474,18 +616,33 @@ the original TOS1. .. opcode:: END_ASYNC_FOR Terminates an :keyword:`async for` loop. Handles an exception raised - when awaiting a next item. If TOS is :exc:`StopAsyncIteration` pop 7 + when awaiting a next item. If ``STACK[-1]`` is :exc:`StopAsyncIteration` pop 3 values from the stack and restore the exception state using the second - three of them. Otherwise re-raise the exception using the three values + of them. Otherwise re-raise the exception using the value from the stack. An exception handler block is removed from the block stack. .. versionadded:: 3.8 + .. versionchanged:: 3.11 + Exception representation on the stack now consist of one, not three, items. + + +.. opcode:: CLEANUP_THROW + + Handles an exception raised during a :meth:`~generator.throw` or + :meth:`~generator.close` call through the current frame. If ``STACK[-1]`` is an + instance of :exc:`StopIteration`, pop three values from the stack and push + its ``value`` member. Otherwise, re-raise ``STACK[-1]``. + + .. versionadded:: 3.12 + .. opcode:: BEFORE_ASYNC_WITH - Resolves ``__aenter__`` and ``__aexit__`` from the object on top of the - stack. Pushes ``__aexit__`` and result of ``__aenter__()`` to the stack. + Resolves ``__aenter__`` and ``__aexit__`` from ``STACK[-1]``. + Pushes ``__aexit__`` and result of ``__aenter__()`` to the stack:: + + STACK.extend((__aexit__, __aenter__()) .. versionadded:: 3.5 @@ -493,31 +650,39 @@ the original TOS1. **Miscellaneous opcodes** -.. opcode:: PRINT_EXPR - - Implements the expression statement for the interactive mode. TOS is removed - from the stack and printed. In non-interactive mode, an expression statement - is terminated with :opcode:`POP_TOP`. - - .. opcode:: SET_ADD (i) - Calls ``set.add(TOS1[-i], TOS)``. Used to implement set comprehensions. + Implements:: + item = STACK.pop() + set.add(STACK[-i], item) + + Used to implement set comprehensions. .. opcode:: LIST_APPEND (i) - Calls ``list.append(TOS1[-i], TOS)``. Used to implement list comprehensions. + Implements:: + + item = STACK.pop() + list.append(STACK[-i], item) + + Used to implement list comprehensions. .. opcode:: MAP_ADD (i) - Calls ``dict.__setitem__(TOS1[-i], TOS1, TOS)``. Used to implement dict - comprehensions. + Implements:: + + value = STACK.pop() + key = STACK.pop() + dict.__setitem__(STACK[-i], key, value) + + Used to implement dict comprehensions. .. versionadded:: 3.1 .. versionchanged:: 3.8 - Map value is TOS and map key is TOS1. Before, those were reversed. + Map value is ``STACK[-1]`` and map key is ``STACK[-2]``. Before, those + were reversed. For all of the :opcode:`SET_ADD`, :opcode:`LIST_APPEND` and :opcode:`MAP_ADD` instructions, while the added value or key/value pair is popped off, the @@ -527,19 +692,18 @@ iterations of the loop. .. opcode:: RETURN_VALUE - Returns with TOS to the caller of the function. + Returns with ``STACK[-1]`` to the caller of the function. .. opcode:: YIELD_VALUE - Pops TOS and yields it from a :term:`generator`. + Yields ``STACK.pop()`` from a :term:`generator`. + .. versionchanged:: 3.11 + oparg set to be the stack depth. -.. opcode:: YIELD_FROM - - Pops TOS and delegates to it as a subiterator from a :term:`generator`. - - .. versionadded:: 3.3 + .. versionchanged:: 3.12 + oparg set to be the exception block depth, for efficient closing of generators. .. opcode:: SETUP_ANNOTATIONS @@ -552,17 +716,12 @@ iterations of the loop. .. versionadded:: 3.6 -.. opcode:: IMPORT_STAR - - Loads all symbols not starting with ``'_'`` directly from the module TOS to - the local namespace. The module is popped after loading all names. This - opcode implements ``from module import *``. - - .. opcode:: POP_EXCEPT - Pops three values from the stack, which are used to restore the exception state. + Pops a value from the stack, which is used to restore the exception state. + .. versionchanged:: 3.11 + Exception representation on the stack now consist of one, not three, items. .. opcode:: RERAISE @@ -572,35 +731,59 @@ iterations of the loop. .. versionadded:: 3.9 + .. versionchanged:: 3.11 + Exception representation on the stack now consist of one, not three, items. .. opcode:: PUSH_EXC_INFO - Pops the three values from the stack. Pushes the current exception to the top of the stack. - Pushes the three values originally popped back to the stack. + Pops a value from the stack. Pushes the current exception to the top of the stack. + Pushes the value originally popped back to the stack. Used in exception handlers. .. versionadded:: 3.11 +.. opcode:: CHECK_EXC_MATCH + + Performs exception matching for ``except``. Tests whether the ``STACK[-2]`` + is an exception matching ``STACK[-1]``. Pops STACK[-1] and pushes the boolean + result of the test. + + .. versionadded:: 3.11 + +.. opcode:: CHECK_EG_MATCH + + Performs exception matching for ``except*``. Applies ``split(STACK[-1])`` on + the exception group representing ``STACK[-2]``. + + In case of a match, pops two items from the stack and pushes the + non-matching subgroup (``None`` in case of full match) followed by the + matching subgroup. When there is no match, pops one item (the match + type) and pushes ``None``. + + .. versionadded:: 3.11 + +.. opcode:: PREP_RERAISE_STAR + + Combines the raised and reraised exceptions list from ``STACK[-1]``, into an + exception group to propagate from a try-except* block. Uses the original exception + group from ``STACK[-2]`` to reconstruct the structure of reraised exceptions. Pops + two items from the stack and pushes the exception to reraise or ``None`` + if there isn't one. + + .. versionadded:: 3.11 .. opcode:: WITH_EXCEPT_START - Calls the function in position 7 on the stack with the top three - items on the stack as arguments. + Calls the function in position 4 on the stack with arguments (type, val, tb) + representing the exception at the top of the stack. Used to implement the call ``context_manager.__exit__(*exc_info())`` when an exception has occurred in a :keyword:`with` statement. .. versionadded:: 3.9 - -.. opcode:: POP_EXCEPT_AND_RERAISE - - Pops the exception currently on top of the stack. Pops the integer value on top - of the stack and sets the ``f_lasti`` attribute of the frame with that value. - Then pops the next exception from the stack uses it to restore the current exception. - Finally it re-raises the originally popped exception. - Used in exception handler cleanup. - - .. versionadded:: 3.11 + .. versionchanged:: 3.11 + The ``__exit__`` function is in position 4 of the stack rather than 7. + Exception representation on the stack now consist of one, not three, items. .. opcode:: LOAD_ASSERTION_ERROR @@ -614,10 +797,10 @@ iterations of the loop. .. opcode:: LOAD_BUILD_CLASS Pushes :func:`builtins.__build_class__` onto the stack. It is later called - by :opcode:`CALL_FUNCTION` to construct a class. + to construct a class. -.. opcode:: BEFORE_WITH (delta) +.. opcode:: BEFORE_WITH This opcode performs several operations before a with block starts. First, it loads :meth:`~object.__exit__` from the context manager and pushes it onto @@ -630,24 +813,24 @@ iterations of the loop. .. opcode:: GET_LEN - Push ``len(TOS)`` onto the stack. + Perform ``STACK.append(len(STACK[-1]))``. .. versionadded:: 3.10 .. opcode:: MATCH_MAPPING - If TOS is an instance of :class:`collections.abc.Mapping` (or, more technically: if - it has the :const:`Py_TPFLAGS_MAPPING` flag set in its - :c:member:`~PyTypeObject.tp_flags`), push ``True`` onto the stack. Otherwise, push - ``False``. + If ``STACK[-1]`` is an instance of :class:`collections.abc.Mapping` (or, more + technically: if it has the :const:`Py_TPFLAGS_MAPPING` flag set in its + :c:member:`~PyTypeObject.tp_flags`), push ``True`` onto the stack. Otherwise, + push ``False``. .. versionadded:: 3.10 .. opcode:: MATCH_SEQUENCE - If TOS is an instance of :class:`collections.abc.Sequence` and is *not* an instance + If ``STACK[-1]`` is an instance of :class:`collections.abc.Sequence` and is *not* an instance of :class:`str`/:class:`bytes`/:class:`bytearray` (or, more technically: if it has the :const:`Py_TPFLAGS_SEQUENCE` flag set in its :c:member:`~PyTypeObject.tp_flags`), push ``True`` onto the stack. Otherwise, push ``False``. @@ -657,9 +840,9 @@ iterations of the loop. .. opcode:: MATCH_KEYS - TOS is a tuple of mapping keys, and TOS1 is the match subject. If TOS1 - contains all of the keys in TOS, push a :class:`tuple` containing the - corresponding values. Otherwise, push ``None``. + ``STACK[-1]`` is a tuple of mapping keys, and ``STACK[-2]`` is the match subject. + If ``STACK[-2]`` contains all of the keys in ``STACK[-1]``, push a :class:`tuple` + containing the corresponding values. Otherwise, push ``None``. .. versionadded:: 3.10 @@ -668,11 +851,9 @@ iterations of the loop. success (``True``) or failure (``False``). -All of the following opcodes use their arguments. - .. opcode:: STORE_NAME (namei) - Implements ``name = TOS``. *namei* is the index of *name* in the attribute + Implements ``name = STACK.pop()``. *namei* is the index of *name* in the attribute :attr:`co_names` of the code object. The compiler tries to use :opcode:`STORE_FAST` or :opcode:`STORE_GLOBAL` if possible. @@ -685,31 +866,49 @@ All of the following opcodes use their arguments. .. opcode:: UNPACK_SEQUENCE (count) - Unpacks TOS into *count* individual values, which are put onto the stack - right-to-left. + Unpacks ``STACK[-1]`` into *count* individual values, which are put onto the stack + right-to-left.:: + + STACK.extend(STACK.pop()[:count:-1]) .. opcode:: UNPACK_EX (counts) - Implements assignment with a starred target: Unpacks an iterable in TOS into - individual values, where the total number of values can be smaller than the + Implements assignment with a starred target: Unpacks an iterable in ``STACK[-1]`` + into individual values, where the total number of values can be smaller than the number of items in the iterable: one of the new values will be a list of all leftover items. - The low byte of *counts* is the number of values before the list value, the - high byte of *counts* the number of values after it. The resulting values - are put onto the stack right-to-left. + The number of values before and after the list value is limited to 255. + + The number of values before the list value is encoded in the argument of the + opcode. The number of values after the list if any is encoded using an + ``EXTENDED_ARG``. As a consequence, the argument can be seen as a two bytes values + where the low byte of *counts* is the number of values before the list value, the + high byte of *counts* the number of values after it. + + The extracted values are put onto the stack right-to-left, i.e. ``a, *b, c = d`` + will be stored after execution as ``STACK.extend((a, b, c))``. .. opcode:: STORE_ATTR (namei) - Implements ``TOS.name = TOS1``, where *namei* is the index of name in - :attr:`co_names`. + Implements:: + obj = STACK.pop() + value = STACK.pop() + obj.name = value + + where *namei* is the index of name in :attr:`co_names`. .. opcode:: DELETE_ATTR (namei) - Implements ``del TOS.name``, using *namei* as index into :attr:`co_names`. + Implements:: + + obj = STACK.pop() + del obj.name + + where *namei* is the index of name into :attr:`co_names`. .. opcode:: STORE_GLOBAL (namei) @@ -735,7 +934,11 @@ All of the following opcodes use their arguments. .. opcode:: BUILD_TUPLE (count) Creates a tuple consuming *count* items from the stack, and pushes the - resulting tuple onto the stack. + resulting tuple onto the stack.:: + + assert count > 0 + STACK, values = STACK[:-count], STACK[-count:] + STACK.append(tuple(values)) .. opcode:: BUILD_LIST (count) @@ -752,7 +955,7 @@ All of the following opcodes use their arguments. Pushes a new dictionary object onto the stack. Pops ``2 * count`` items so that the dictionary holds *count* entries: - ``{..., TOS3: TOS2, TOS1: TOS}``. + ``{..., STACK[-4]: STACK[-3], STACK[-2]: STACK[-1]}``. .. versionchanged:: 3.5 The dictionary is created from stack items instead of creating an @@ -763,7 +966,7 @@ All of the following opcodes use their arguments. The version of :opcode:`BUILD_MAP` specialized for constant keys. Pops the top element on the stack which contains a tuple of keys, then starting from - ``TOS1``, pops *count* values to form values in the built dictionary. + ``STACK[-2]``, pops *count* values to form values in the built dictionary. .. versionadded:: 3.6 @@ -776,30 +979,38 @@ All of the following opcodes use their arguments. .. versionadded:: 3.6 -.. opcode:: LIST_TO_TUPLE - - Pops a list from the stack and pushes a tuple containing the same values. - - .. versionadded:: 3.9 - - .. opcode:: LIST_EXTEND (i) - Calls ``list.extend(TOS1[-i], TOS)``. Used to build lists. + Implements:: + + seq = STACK.pop() + list.extend(STACK[-i], seq) + + Used to build lists. .. versionadded:: 3.9 .. opcode:: SET_UPDATE (i) - Calls ``set.update(TOS1[-i], TOS)``. Used to build sets. + Implements:: + + seq = STACK.pop() + set.update(STACK[-i], seq) + + Used to build sets. .. versionadded:: 3.9 .. opcode:: DICT_UPDATE (i) - Calls ``dict.update(TOS1[-i], TOS)``. Used to build dicts. + Implements:: + + map = STACK.pop() + dict.update(STACK[-i], map) + + Used to build dicts. .. versionadded:: 3.9 @@ -813,7 +1024,20 @@ All of the following opcodes use their arguments. .. opcode:: LOAD_ATTR (namei) - Replaces TOS with ``getattr(TOS, co_names[namei])``. + If the low bit of ``namei`` is not set, this replaces ``STACK[-1]`` with + ``getattr(STACK[-1], co_names[namei>>1])``. + + If the low bit of ``namei`` is set, this will attempt to load a method named + ``co_names[namei>>1]`` from the ``STACK[-1]`` object. ``STACK[-1]`` is popped. + This bytecode distinguishes two cases: if ``STACK[-1]`` has a method with the + correct name, the bytecode pushes the unbound method and ``STACK[-1]``. + ``STACK[-1]`` will be used as the first argument (``self``) by :opcode:`CALL` + when calling the unbound method. Otherwise, ``NULL`` and the object return by + the attribute lookup are pushed. + + .. versionchanged:: 3.12 + If the low bit of ``namei`` is set, then a ``NULL`` or ``self`` is + pushed to the stack before the attribute or unbound method respectively. .. opcode:: COMPARE_OP (opname) @@ -822,6 +1046,15 @@ All of the following opcodes use their arguments. ``cmp_op[opname]``. +.. opcode:: COMPARE_AND_BRANCH (opname) + + Compares the top two values on the stack, popping them, then branches. + The direction and offset of the jump is embedded as a ``POP_JUMP_IF_TRUE`` + or ``POP_JUMP_IF_FALSE`` instruction immediately following the cache. + + .. versionadded:: 3.12 + + .. opcode:: IS_OP (invert) Performs ``is`` comparison, or ``is not`` if ``invert`` is 1. @@ -838,17 +1071,16 @@ All of the following opcodes use their arguments. .. opcode:: IMPORT_NAME (namei) - Imports the module ``co_names[namei]``. TOS and TOS1 are popped and provide - the *fromlist* and *level* arguments of :func:`__import__`. The module - object is pushed onto the stack. The current namespace is not affected: for - a proper import statement, a subsequent :opcode:`STORE_FAST` instruction + Imports the module ``co_names[namei]``. ``STACK[-1]`` and ``STACK[-2]`` are + popped and provide the *fromlist* and *level* arguments of :func:`__import__`. + The module object is pushed onto the stack. The current namespace is not affected: for a proper import statement, a subsequent :opcode:`STORE_FAST` instruction modifies the namespace. .. opcode:: IMPORT_FROM (namei) - Loads the attribute ``co_names[namei]`` from the module found in TOS. The - resulting object is pushed onto the stack, to be subsequently stored by a + Loads the attribute ``co_names[namei]`` from the module found in ``STACK[-1]``. + The resulting object is pushed onto the stack, to be subsequently stored by a :opcode:`STORE_FAST` instruction. @@ -857,72 +1089,134 @@ All of the following opcodes use their arguments. Increments bytecode counter by *delta*. -.. opcode:: POP_JUMP_IF_TRUE (target) +.. opcode:: JUMP_BACKWARD (delta) - If TOS is true, sets the bytecode counter to *target*. TOS is popped. + Decrements bytecode counter by *delta*. Checks for interrupts. - .. versionadded:: 3.1 + .. versionadded:: 3.11 -.. opcode:: POP_JUMP_IF_FALSE (target) +.. opcode:: JUMP_BACKWARD_NO_INTERRUPT (delta) - If TOS is false, sets the bytecode counter to *target*. TOS is popped. + Decrements bytecode counter by *delta*. Does not check for interrupts. - .. versionadded:: 3.1 + .. versionadded:: 3.11 -.. opcode:: JUMP_IF_NOT_EXC_MATCH (target) - Tests whether the second value on the stack is an exception matching TOS, - and jumps if it is not. Pops one value from the stack. +.. opcode:: POP_JUMP_IF_TRUE (delta) - .. versionadded:: 3.9 + If ``STACK[-1]`` is true, increments the bytecode counter by *delta*. + ``STACK[-1]`` is popped. .. versionchanged:: 3.11 - This opcode no longer pops the active exception. + The oparg is now a relative delta rather than an absolute target. + This opcode is a pseudo-instruction, replaced in final bytecode by + the directed versions (forward/backward). + + .. versionchanged:: 3.12 + This is no longer a pseudo-instruction. + +.. opcode:: POP_JUMP_IF_FALSE (delta) + + If ``STACK[-1]`` is false, increments the bytecode counter by *delta*. + ``STACK[-1]`` is popped. + + .. versionchanged:: 3.11 + The oparg is now a relative delta rather than an absolute target. + This opcode is a pseudo-instruction, replaced in final bytecode by + the directed versions (forward/backward). + + .. versionchanged:: 3.12 + This is no longer a pseudo-instruction. + +.. opcode:: POP_JUMP_IF_NOT_NONE (delta) + + If ``STACK[-1]`` is not ``None``, increments the bytecode counter by *delta*. + ``STACK[-1]`` is popped. + + This opcode is a pseudo-instruction, replaced in final bytecode by + the directed versions (forward/backward). + + .. versionadded:: 3.11 + + .. versionchanged:: 3.12 + This is no longer a pseudo-instruction. -.. opcode:: JUMP_IF_TRUE_OR_POP (target) +.. opcode:: POP_JUMP_IF_NONE (delta) - If TOS is true, sets the bytecode counter to *target* and leaves TOS on the - stack. Otherwise (TOS is false), TOS is popped. + If ``STACK[-1]`` is ``None``, increments the bytecode counter by *delta*. + ``STACK[-1]`` is popped. + + This opcode is a pseudo-instruction, replaced in final bytecode by + the directed versions (forward/backward). + + .. versionadded:: 3.11 + + .. versionchanged:: 3.12 + This is no longer a pseudo-instruction. + + +.. opcode:: JUMP_IF_TRUE_OR_POP (delta) + + If ``STACK[-1]`` is true, increments the bytecode counter by *delta* and leaves + ``STACK[-1]`` on the stack. Otherwise (``STACK[-1]`` is false), ``STACK[-1]`` + is popped. .. versionadded:: 3.1 + .. versionchanged:: 3.11 + The oparg is now a relative delta rather than an absolute target. -.. opcode:: JUMP_IF_FALSE_OR_POP (target) +.. opcode:: JUMP_IF_FALSE_OR_POP (delta) - If TOS is false, sets the bytecode counter to *target* and leaves TOS on the - stack. Otherwise (TOS is true), TOS is popped. + If ``STACK[-1]`` is false, increments the bytecode counter by *delta* and leaves + ``STACK[-1]`` on the stack. Otherwise (``STACK[-1]`` is true), ``STACK[-1]`` is + popped. .. versionadded:: 3.1 - -.. opcode:: JUMP_ABSOLUTE (target) - - Set bytecode counter to *target*. + .. versionchanged:: 3.11 + The oparg is now a relative delta rather than an absolute target. .. opcode:: FOR_ITER (delta) - TOS is an :term:`iterator`. Call its :meth:`~iterator.__next__` method. If - this yields a new value, push it on the stack (leaving the iterator below - it). If the iterator indicates it is exhausted, TOS is popped, and the byte - code counter is incremented by *delta*. + ``STACK[-1]`` is an :term:`iterator`. Call its :meth:`~iterator.__next__` method. + If this yields a new value, push it on the stack (leaving the iterator below + it). If the iterator indicates it is exhausted then the byte code counter is + incremented by *delta*. + .. versionchanged:: 3.12 + Up until 3.11 the iterator was popped when it was exhausted. .. opcode:: LOAD_GLOBAL (namei) - Loads the global named ``co_names[namei]`` onto the stack. + Loads the global named ``co_names[namei>>1]`` onto the stack. + .. versionchanged:: 3.11 + If the low bit of ``namei`` is set, then a ``NULL`` is pushed to the + stack before the global variable. .. opcode:: LOAD_FAST (var_num) Pushes a reference to the local ``co_varnames[var_num]`` onto the stack. + .. versionchanged:: 3.12 + This opcode is now only used in situations where the local variable is + guaranteed to be initialized. It cannot raise :exc:`UnboundLocalError`. + +.. opcode:: LOAD_FAST_CHECK (var_num) + + Pushes a reference to the local ``co_varnames[var_num]`` onto the stack, + raising an :exc:`UnboundLocalError` if the local variable has not been + initialized. + + .. versionadded:: 3.12 .. opcode:: STORE_FAST (var_num) - Stores TOS into the local ``co_varnames[var_num]``. + Stores ``STACK.pop()`` into the local ``co_varnames[var_num]``. .. opcode:: DELETE_FAST (var_num) @@ -973,7 +1267,7 @@ All of the following opcodes use their arguments. .. opcode:: STORE_DEREF (i) - Stores TOS into the cell contained in slot ``i`` of the "fast locals" + Stores ``STACK.pop()`` into the cell contained in slot ``i`` of the "fast locals" storage. .. versionchanged:: 3.11 @@ -991,48 +1285,53 @@ All of the following opcodes use their arguments. ``i`` is no longer offset by the length of ``co_varnames``. +.. opcode:: COPY_FREE_VARS (n) + + Copies the ``n`` free variables from the closure into the frame. + Removes the need for special code on the caller's side when calling + closures. + + .. versionadded:: 3.11 + + .. opcode:: RAISE_VARARGS (argc) Raises an exception using one of the 3 forms of the ``raise`` statement, depending on the value of *argc*: * 0: ``raise`` (re-raise previous exception) - * 1: ``raise TOS`` (raise exception instance or type at ``TOS``) - * 2: ``raise TOS1 from TOS`` (raise exception instance or type at ``TOS1`` - with ``__cause__`` set to ``TOS``) + * 1: ``raise STACK[-1]`` (raise exception instance or type at ``STACK[-1]``) + * 2: ``raise STACK[-2] from STACK[-1]`` (raise exception instance or type at + ``STACK[-2]`` with ``__cause__`` set to ``STACK[-1]``) -.. opcode:: CALL_FUNCTION (argc) +.. opcode:: CALL (argc) - Calls a callable object with positional arguments. - *argc* indicates the number of positional arguments. - The top of the stack contains positional arguments, with the right-most - argument on top. Below the arguments is a callable object to call. - ``CALL_FUNCTION`` pops all arguments and the callable object off the stack, + Calls a callable object with the number of arguments specified by ``argc``, + including the named arguments specified by the preceding + :opcode:`KW_NAMES`, if any. + On the stack are (in ascending order), either: + + * NULL + * The callable + * The positional arguments + * The named arguments + + or: + + * The callable + * ``self`` + * The remaining positional arguments + * The named arguments + + ``argc`` is the total of the positional and named arguments, excluding + ``self`` when a ``NULL`` is not present. + + ``CALL`` pops all arguments and the callable object off the stack, calls the callable object with those arguments, and pushes the return value returned by the callable object. - .. versionchanged:: 3.6 - This opcode is used only for calls with positional arguments. - - -.. opcode:: CALL_FUNCTION_KW (argc) - - Calls a callable object with positional (if any) and keyword arguments. - *argc* indicates the total number of positional and keyword arguments. - The top element on the stack contains a tuple with the names of the - keyword arguments, which must be strings. - Below that are the values for the keyword arguments, - in the order corresponding to the tuple. - Below that are positional arguments, with the right-most parameter on - top. Below the arguments is a callable object to call. - ``CALL_FUNCTION_KW`` pops all arguments and the callable object off the stack, - calls the callable object with those arguments, and pushes the return value - returned by the callable object. - - .. versionchanged:: 3.6 - Keyword arguments are packed in a tuple instead of a dictionary, - *argc* indicates the total number of arguments. + .. versionadded:: 3.11 .. opcode:: CALL_FUNCTION_EX (flags) @@ -1050,42 +1349,24 @@ All of the following opcodes use their arguments. .. versionadded:: 3.6 -.. opcode:: LOAD_METHOD (namei) +.. opcode:: PUSH_NULL - Loads a method named ``co_names[namei]`` from the TOS object. TOS is popped. - This bytecode distinguishes two cases: if TOS has a method with the correct - name, the bytecode pushes the unbound method and TOS. TOS will be used as - the first argument (``self``) by :opcode:`CALL_METHOD` when calling the - unbound method. Otherwise, ``NULL`` and the object return by the attribute - lookup are pushed. - - .. versionadded:: 3.7 - - -.. opcode:: CALL_METHOD (argc) - - Calls a method. *argc* is the number of positional arguments. - Keyword arguments are not supported. This opcode is designed to be used - with :opcode:`LOAD_METHOD`. Positional arguments are on top of the stack. - Below them, the two items described in :opcode:`LOAD_METHOD` are on the - stack (either ``self`` and an unbound method object or ``NULL`` and an - arbitrary callable). All of them are popped and the return value is pushed. - - .. versionadded:: 3.7 - - -.. opcode:: CALL_METHOD_KW (argc) - - Calls a method in a similar fashion as :opcode:`CALL_METHOD`, but also supports keyword arguments. - *argc* is the number of positional and keyword arguments. - This opcode is designed to be used with :opcode:`LOAD_METHOD`. TOS is a - tuple of keyword argument names. Argument values are below that. - Below them, the two items described in :opcode:`LOAD_METHOD` are on the - stack (either ``self`` and an unbound method object or ``NULL`` and an - arbitrary callable). All of them are popped from the stack and the return value is pushed. + Pushes a ``NULL`` to the stack. + Used in the call sequence to match the ``NULL`` pushed by + :opcode:`LOAD_METHOD` for non-method calls. .. versionadded:: 3.11 + +.. opcode:: KW_NAMES (consti) + + Prefixes :opcode:`CALL`. + Stores a reference to ``co_consts[consti]`` into an internal variable + for use by :opcode:`CALL`. ``co_consts[consti]`` must be a tuple of strings. + + .. versionadded:: 3.11 + + .. opcode:: MAKE_FUNCTION (flags) Pushes a new function object on the stack. From bottom to top, the consumed @@ -1096,8 +1377,8 @@ All of the following opcodes use their arguments. * ``0x02`` a dictionary of keyword-only parameters' default values * ``0x04`` a tuple of strings containing parameters' annotations * ``0x08`` a tuple containing cells for free variables, making a closure - * the code associated with the function (at TOS1) - * the :term:`qualified name` of the function (at TOS) + * the code associated with the function (at ``STACK[-2]``) + * the :term:`qualified name` of the function (at ``STACK[-1]``) .. versionchanged:: 3.10 Flag value ``0x04`` is a tuple of strings instead of dictionary @@ -1106,9 +1387,20 @@ All of the following opcodes use their arguments. .. index:: builtin: slice - Pushes a slice object on the stack. *argc* must be 2 or 3. If it is 2, - ``slice(TOS1, TOS)`` is pushed; if it is 3, ``slice(TOS2, TOS1, TOS)`` is - pushed. See the :func:`slice` built-in function for more information. + Pushes a slice object on the stack. *argc* must be 2 or 3. If it is 2, implements:: + + end = STACK.pop() + start = STACK.pop() + STACK.append(slice(start, stop)) + + if it is 3, implements:: + + step = STACK.pop() + end = STACK.pop() + start = STACK.pop() + STACK.append(slice(start, end, step)) + + See the :func:`slice` built-in function for more information. .. opcode:: EXTENDED_ARG (ext) @@ -1143,13 +1435,14 @@ All of the following opcodes use their arguments. .. opcode:: MATCH_CLASS (count) - TOS is a tuple of keyword attribute names, TOS1 is the class being matched - against, and TOS2 is the match subject. *count* is the number of positional - sub-patterns. + ``STACK[-1]`` is a tuple of keyword attribute names, ``STACK[-2]`` is the class + being matched against, and ``STACK[-3]`` is the match subject. *count* is the + number of positional sub-patterns. - Pop TOS, TOS1, and TOS2. If TOS2 is an instance of TOS1 and has the - positional and keyword attributes required by *count* and TOS, push a tuple - of extracted attributes. Otherwise, push ``None``. + Pop ``STACK[-1]``, ``STACK[-2]``, and ``STACK[-3]``. If ``STACK[-3]`` is an + instance of ``STACK[-2]`` and has the positional and keyword attributes + required by *count* and ``STACK[-1]``, push a tuple of extracted attributes. + Otherwise, push ``None``. .. versionadded:: 3.10 @@ -1157,42 +1450,128 @@ All of the following opcodes use their arguments. Previously, this instruction also pushed a boolean value indicating success (``True``) or failure (``False``). -.. opcode:: GEN_START (kind) - Pops TOS. If TOS was not ``None``, raises an exception. The ``kind`` - operand corresponds to the type of generator or coroutine and determines - the error message. The legal kinds are 0 for generator, 1 for coroutine, - and 2 for async generator. +.. opcode:: RESUME (where) - .. versionadded:: 3.10 + A no-op. Performs internal tracing, debugging and optimization checks. + The ``where`` operand marks where the ``RESUME`` occurs: -.. opcode:: ROT_N (count) - - Lift the top *count* stack items one position up, and move TOS down to - position *count*. - - .. versionadded:: 3.10 - - -.. opcode:: COPY (i) - - Push the *i*-th item to the top of the stack. The item is not removed from its - original location. + * ``0`` The start of a function, which is neither a generator, coroutine + nor an async generator + * ``1`` After a ``yield`` expression + * ``2`` After a ``yield from`` expression + * ``3`` After an ``await`` expression .. versionadded:: 3.11 +.. opcode:: RETURN_GENERATOR + + Create a generator, coroutine, or async generator from the current frame. + Used as first opcode of in code object for the above mentioned callables. + Clear the current frame and return the newly created generator. + + .. versionadded:: 3.11 + + +.. opcode:: SEND (delta) + + Equivalent to ``STACK[-1] = STACK[-2].send(STACK[-1])``. Used in ``yield from`` + and ``await`` statements. + + If the call raises :exc:`StopIteration`, pop both items, push the + exception's ``value`` attribute, and increment the bytecode counter by + *delta*. + + .. versionadded:: 3.11 + + .. opcode:: HAVE_ARGUMENT This is not really an opcode. It identifies the dividing line between - opcodes which don't use their argument and those that do - (``< HAVE_ARGUMENT`` and ``>= HAVE_ARGUMENT``, respectively). + opcodes in the range [0,255] which don't use their argument and those + that do (``< HAVE_ARGUMENT`` and ``>= HAVE_ARGUMENT``, respectively). + + If your application uses pseudo instructions, use the :data:`hasarg` + collection instead. .. versionchanged:: 3.6 Now every instruction has an argument, but opcodes ``< HAVE_ARGUMENT`` ignore it. Before, only opcodes ``>= HAVE_ARGUMENT`` had an argument. + .. versionchanged:: 3.12 + Pseudo instructions were added to the :mod:`dis` module, and for them + it is not true that comparison with ``HAVE_ARGUMENT`` indicates whether + they use their arg. + + +.. opcode:: CALL_INTRINSIC_1 + + Calls an intrinsic function with one argument. Passes ``STACK[-1]`` as the + argument and sets ``STACK[-1]`` to the result. Used to implement functionality that is necessary but not performance critical. + + The operand determines which intrinsic function is called: + + * ``0`` Not valid + * ``1`` Prints the argument to standard out. Used in the REPL. + * ``2`` Performs ``import *`` for the named module. + * ``3`` Extracts the return value from a ``StopIteration`` exception. + * ``4`` Wraps an aync generator value + * ``5`` Performs the unary ``+`` operation + * ``6`` Converts a list to a tuple + + .. versionadded:: 3.12 + + +**Pseudo-instructions** + +These opcodes do not appear in python bytecode, they are used by the compiler +but are replaced by real opcodes or removed before bytecode is generated. + +.. opcode:: SETUP_FINALLY (target) + + Set up an exception handler for the following code block. If an exception + occurs, the value stack level is restored to its current state and control + is transferred to the exception handler at ``target``. + + +.. opcode:: SETUP_CLEANUP (target) + + Like ``SETUP_FINALLY``, but in case of exception also pushes the last + instruction (``lasti``) to the stack so that ``RERAISE`` can restore it. + If an exception occurs, the value stack level and the last instruction on + the frame are restored to their current state, and control is transferred + to the exception handler at ``target``. + + +.. opcode:: SETUP_WITH (target) + + Like ``SETUP_CLEANUP``, but in case of exception one more item is popped + from the stack before control is transferred to the exception handler at + ``target``. + + This variant is used in :keyword:`with` and :keyword:`async with` + constructs, which push the return value of the context manager's + :meth:`~object.__enter__` or :meth:`~object.__aenter__` to the stack. + + +.. opcode:: POP_BLOCK + + Marks the end of the code block associated with the last ``SETUP_FINALLY``, + ``SETUP_CLEANUP`` or ``SETUP_WITH``. + +.. opcode:: JUMP +.. opcode:: JUMP_NO_INTERRUPT + + Undirected relative jump instructions which are replaced by their + directed (forward/backward) counterparts by the assembler. + +.. opcode:: LOAD_METHOD + + Optimized unbound method lookup. Emitted as a ``LOAD_ATTR`` opcode + with a flag set in the arg. + .. _opcode_collections: @@ -1202,6 +1581,10 @@ Opcode collections These collections are provided for automatic introspection of bytecode instructions: + .. versionchanged:: 3.12 + The collections now contain pseudo instructions as well. These are + opcodes with values ``>= MIN_PSEUDO_OPCODE``. + .. data:: opname Sequence of operation names, indexable using the bytecode. @@ -1217,6 +1600,13 @@ instructions: Sequence of all compare operation names. +.. data:: hasarg + + Sequence of bytecodes that use their argument. + + .. versionadded:: 3.12 + + .. data:: hasconst Sequence of bytecodes that access a constant. @@ -1253,3 +1643,9 @@ instructions: .. data:: hascompare Sequence of bytecodes of Boolean operations. + +.. data:: hasexc + + Sequence of bytecodes that set an exception handler. + + .. versionadded:: 3.12 diff --git a/Doc/library/distribution.rst b/Doc/library/distribution.rst index 8d4befe41b3..bec1ca3cc39 100644 --- a/Doc/library/distribution.rst +++ b/Doc/library/distribution.rst @@ -9,7 +9,6 @@ with a local index server, or without any index server at all. .. toctree:: - distutils.rst ensurepip.rst venv.rst zipapp.rst diff --git a/Doc/library/distutils.rst b/Doc/library/distutils.rst deleted file mode 100644 index 31c4ae5b239..00000000000 --- a/Doc/library/distutils.rst +++ /dev/null @@ -1,49 +0,0 @@ -:mod:`distutils` --- Building and installing Python modules -=========================================================== - -.. module:: distutils - :synopsis: Support for building and installing Python modules into an - existing Python installation. - -.. sectionauthor:: Fred L. Drake, Jr. - --------------- - -:mod:`distutils` is deprecated with removal planned for Python 3.12. -See the :ref:`What's New ` entry for more information. - --------------- - -The :mod:`distutils` package provides support for building and installing -additional modules into a Python installation. The new modules may be either -100%-pure Python, or may be extension modules written in C, or may be -collections of Python packages which include modules coded in both Python and C. - -Most Python users will *not* want to use this module directly, but instead -use the cross-version tools maintained by the Python Packaging Authority. In -particular, -`setuptools `__ is an -enhanced alternative to :mod:`distutils` that provides: - -* support for declaring project dependencies -* additional mechanisms for configuring which files to include in source - releases (including plugins for integration with version control systems) -* the ability to declare project "entry points", which can be used as the - basis for application plugin systems -* the ability to automatically generate Windows command line executables at - installation time rather than needing to prebuild them -* consistent behaviour across all supported Python versions - -The recommended `pip `__ installer runs all -``setup.py`` scripts with ``setuptools``, even if the script itself only -imports ``distutils``. Refer to the -`Python Packaging User Guide `_ for more -information. - -For the benefits of packaging tool authors and users seeking a deeper -understanding of the details of the current packaging and distribution -system, the legacy :mod:`distutils` based user documentation and API -reference remain available: - -* :ref:`install-index` -* :ref:`distutils-index` diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index 0bbb640bea2..d6e4dca0860 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -288,10 +288,6 @@ strings are treated as if they were docstrings. In output, a key ``K`` in Any classes found are recursively searched similarly, to test docstrings in their contained methods and nested classes. -.. impl-detail:: - Prior to version 3.4, extension modules written in C were not fully - searched by doctest. - .. _doctest-finding-examples: @@ -355,6 +351,7 @@ The fine print: >>> def f(x): ... r'''Backslashes in a raw docstring: m\n''' + ... >>> print(f.__doc__) Backslashes in a raw docstring: m\n @@ -364,6 +361,7 @@ The fine print: >>> def f(x): ... '''Backslashes in a raw docstring: m\\n''' + ... >>> print(f.__doc__) Backslashes in a raw docstring: m\n @@ -567,41 +565,35 @@ doctest decides whether actual output matches an example's expected output: .. data:: IGNORE_EXCEPTION_DETAIL - When specified, an example that expects an exception passes if an exception of - the expected type is raised, even if the exception detail does not match. For - example, an example expecting ``ValueError: 42`` will pass if the actual - exception raised is ``ValueError: 3*14``, but will fail, e.g., if - :exc:`TypeError` is raised. + When specified, doctests expecting exceptions pass so long as an exception + of the expected type is raised, even if the details + (message and fully qualified exception name) don't match. - It will also ignore the module name used in Python 3 doctest reports. Hence - both of these variations will work with the flag specified, regardless of - whether the test is run under Python 2.7 or Python 3.2 (or later versions):: + For example, an example expecting ``ValueError: 42`` will pass if the actual + exception raised is ``ValueError: 3*14``, but will fail if, say, a + :exc:`TypeError` is raised instead. + It will also ignore any fully qualified name included before the + exception class, which can vary between implementations and versions + of Python and the code/libraries in use. + Hence, all three of these variations will work with the flag specified: - >>> raise CustomError('message') + .. code-block:: pycon + + >>> raise Exception('message') Traceback (most recent call last): - CustomError: message + Exception: message - >>> raise CustomError('message') + >>> raise Exception('message') Traceback (most recent call last): - my_module.CustomError: message + builtins.Exception: message + + >>> raise Exception('message') + Traceback (most recent call last): + __main__.Exception: message Note that :const:`ELLIPSIS` can also be used to ignore the details of the exception message, but such a test may still fail based - on whether or not the module details are printed as part of the - exception name. Using :const:`IGNORE_EXCEPTION_DETAIL` and the details - from Python 2.3 is also the only clear way to write a doctest that doesn't - care about the exception detail yet continues to pass under Python 2.3 or - earlier (those releases do not support :ref:`doctest directives - ` and ignore them as irrelevant comments). For example:: - - >>> (1, 2)[3] = 'moo' - Traceback (most recent call last): - File "", line 1, in - TypeError: object doesn't support item assignment - - passes under Python 2.3 and later Python versions with the flag specified, - even though the detail - changed in Python 2.4 to say "does not" instead of "doesn't". + on whether the module name is present or matches exactly. .. versionchanged:: 3.2 :const:`IGNORE_EXCEPTION_DETAIL` now also ignores any information relating @@ -706,10 +698,10 @@ special Python comments following an example's source code: .. productionlist:: doctest directive: "#" "doctest:" `directive_options` - directive_options: `directive_option` ("," `directive_option`)\* + directive_options: `directive_option` ("," `directive_option`)* directive_option: `on_or_off` `directive_option_name` - on_or_off: "+" \| "-" - directive_option_name: "DONT_ACCEPT_BLANKLINE" \| "NORMALIZE_WHITESPACE" \| ... + on_or_off: "+" | "-" + directive_option_name: "DONT_ACCEPT_BLANKLINE" | "NORMALIZE_WHITESPACE" | ... Whitespace is not allowed between the ``+`` or ``-`` and the directive option name. The directive option name can be any of the option flag names explained @@ -718,36 +710,51 @@ above. An example's doctest directives modify doctest's behavior for that single example. Use ``+`` to enable the named behavior, or ``-`` to disable it. -For example, this test passes:: +For example, this test passes: - >>> print(list(range(20))) # doctest: +NORMALIZE_WHITESPACE +.. doctest:: + :no-trim-doctest-flags: + + >>> print(list(range(20))) # doctest: +NORMALIZE_WHITESPACE [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] Without the directive it would fail, both because the actual output doesn't have two blanks before the single-digit list elements, and because the actual output is on a single line. This test also passes, and also requires a directive to do -so:: +so: - >>> print(list(range(20))) # doctest: +ELLIPSIS +.. doctest:: + :no-trim-doctest-flags: + + >>> print(list(range(20))) # doctest: +ELLIPSIS [0, 1, ..., 18, 19] Multiple directives can be used on a single physical line, separated by -commas:: +commas: - >>> print(list(range(20))) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE +.. doctest:: + :no-trim-doctest-flags: + + >>> print(list(range(20))) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE [0, 1, ..., 18, 19] If multiple directive comments are used for a single example, then they are -combined:: +combined: - >>> print(list(range(20))) # doctest: +ELLIPSIS - ... # doctest: +NORMALIZE_WHITESPACE +.. doctest:: + :no-trim-doctest-flags: + + >>> print(list(range(20))) # doctest: +ELLIPSIS + ... # doctest: +NORMALIZE_WHITESPACE [0, 1, ..., 18, 19] As the previous example shows, you can add ``...`` lines to your example containing only directives. This can be useful when an example is too long for -a directive to comfortably fit on the same line:: +a directive to comfortably fit on the same line: + +.. doctest:: + :no-trim-doctest-flags: >>> print(list(range(5)) + list(range(10, 20)) + list(range(30, 40))) ... # doctest: +ELLIPSIS @@ -785,25 +792,25 @@ instead. Another is to do :: >>> d ['Harry', 'Hermione'] -.. note:: - - Before Python 3.6, when printing a dict, Python did not guarantee that - the key-value pairs was printed in any particular order. - There are others, but you get the idea. -Another bad idea is to print things that embed an object address, like :: +Another bad idea is to print things that embed an object address, like - >>> id(1.0) # certain to fail some of the time +.. doctest:: + + >>> id(1.0) # certain to fail some of the time # doctest: +SKIP 7948648 >>> class C: pass - >>> C() # the default repr() for instances embeds an address - <__main__.C instance at 0x00AC18F0> + >>> C() # the default repr() for instances embeds an address # doctest: +SKIP + -The :const:`ELLIPSIS` directive gives a nice approach for the last example:: +The :const:`ELLIPSIS` directive gives a nice approach for the last example: - >>> C() #doctest: +ELLIPSIS - <__main__.C instance at 0x...> +.. doctest:: + :no-trim-doctest-flags: + + >>> C() # doctest: +ELLIPSIS + Floating-point numbers are also subject to small output variations across platforms, because Python defers to the platform C library for float formatting, @@ -1050,7 +1057,7 @@ from text files and modules with doctests: from a text file using :func:`DocFileSuite`. -.. function:: DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, setUp=None, tearDown=None, checker=None) +.. function:: DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, setUp=None, tearDown=None, optionflags=0, checker=None) Convert doctest tests for a module to a :class:`unittest.TestSuite`. diff --git a/Doc/library/email.charset.rst b/Doc/library/email.charset.rst index 38fda23bd82..adbe6c1c7d2 100644 --- a/Doc/library/email.charset.rst +++ b/Doc/library/email.charset.rst @@ -58,9 +58,9 @@ Import this class from the :mod:`email.charset` module. .. attribute:: header_encoding If the character set must be encoded before it can be used in an email - header, this attribute will be set to ``Charset.QP`` (for - quoted-printable), ``Charset.BASE64`` (for base64 encoding), or - ``Charset.SHORTEST`` for the shortest of QP or BASE64 encoding. Otherwise, + header, this attribute will be set to ``charset.QP`` (for + quoted-printable), ``charset.BASE64`` (for base64 encoding), or + ``charset.SHORTEST`` for the shortest of QP or BASE64 encoding. Otherwise, it will be ``None``. @@ -68,7 +68,7 @@ Import this class from the :mod:`email.charset` module. Same as *header_encoding*, but describes the encoding for the mail message's body, which indeed may be different than the header encoding. - ``Charset.SHORTEST`` is not allowed for *body_encoding*. + ``charset.SHORTEST`` is not allowed for *body_encoding*. .. attribute:: output_charset @@ -175,9 +175,9 @@ new entries to the global character set, alias, and codec registries: *charset* is the input character set, and must be the canonical name of a character set. - Optional *header_enc* and *body_enc* is either ``Charset.QP`` for - quoted-printable, ``Charset.BASE64`` for base64 encoding, - ``Charset.SHORTEST`` for the shortest of quoted-printable or base64 encoding, + Optional *header_enc* and *body_enc* is either ``charset.QP`` for + quoted-printable, ``charset.BASE64`` for base64 encoding, + ``charset.SHORTEST`` for the shortest of quoted-printable or base64 encoding, or ``None`` for no encoding. ``SHORTEST`` is only valid for *header_enc*. The default is ``None`` for no encoding. diff --git a/Doc/library/email.compat32-message.rst b/Doc/library/email.compat32-message.rst index c68e773b168..5bef155a4af 100644 --- a/Doc/library/email.compat32-message.rst +++ b/Doc/library/email.compat32-message.rst @@ -83,7 +83,7 @@ Here are the methods of the :class:`Message` class: Note that this method is provided as a convenience and may not always format the message the way you want. For example, by default it does not do the mangling of lines that begin with ``From`` that is - required by the unix mbox format. For more flexibility, instantiate a + required by the Unix mbox format. For more flexibility, instantiate a :class:`~email.generator.Generator` instance and use its :meth:`~email.generator.Generator.flatten` method directly. For example:: @@ -125,7 +125,7 @@ Here are the methods of the :class:`Message` class: Note that this method is provided as a convenience and may not always format the message the way you want. For example, by default it does not do the mangling of lines that begin with ``From`` that is - required by the unix mbox format. For more flexibility, instantiate a + required by the Unix mbox format. For more flexibility, instantiate a :class:`~email.generator.BytesGenerator` instance and use its :meth:`~email.generator.BytesGenerator.flatten` method directly. For example:: @@ -298,7 +298,7 @@ Here are the methods of the :class:`Message` class: In a model generated from bytes, any header values that (in contravention of the RFCs) contain non-ASCII bytes will, when retrieved through this interface, be represented as :class:`~email.header.Header` objects with - a charset of `unknown-8bit`. + a charset of ``unknown-8bit``. .. method:: __len__() diff --git a/Doc/library/email.errors.rst b/Doc/library/email.errors.rst index 7a77640571c..194a98696f4 100644 --- a/Doc/library/email.errors.rst +++ b/Doc/library/email.errors.rst @@ -114,4 +114,4 @@ All defect classes are subclassed from :class:`email.errors.MessageDefect`. a multiple of 4). The encoded block was kept as-is. * :class:`InvalidDateDefect` -- When decoding an invalid or unparsable date field. - The original value is kept as-is. \ No newline at end of file + The original value is kept as-is. diff --git a/Doc/library/email.generator.rst b/Doc/library/email.generator.rst index 2d9bae6a7ee..34ad7b7f200 100644 --- a/Doc/library/email.generator.rst +++ b/Doc/library/email.generator.rst @@ -55,7 +55,7 @@ To accommodate reproducible processing of SMIME-signed messages defaults to the value of the :attr:`~email.policy.Policy.mangle_from_` setting of the *policy* (which is ``True`` for the :data:`~email.policy.compat32` policy and ``False`` for all others). - *mangle_from_* is intended for use when messages are stored in unix mbox + *mangle_from_* is intended for use when messages are stored in Unix mbox format (see :mod:`mailbox` and `WHY THE CONTENT-LENGTH FORMAT IS BAD `_). @@ -156,7 +156,7 @@ to be using :class:`BytesGenerator`, and not :class:`Generator`. defaults to the value of the :attr:`~email.policy.Policy.mangle_from_` setting of the *policy* (which is ``True`` for the :data:`~email.policy.compat32` policy and ``False`` for all others). - *mangle_from_* is intended for use when messages are stored in unix mbox + *mangle_from_* is intended for use when messages are stored in Unix mbox format (see :mod:`mailbox` and `WHY THE CONTENT-LENGTH FORMAT IS BAD `_). diff --git a/Doc/library/email.header.rst b/Doc/library/email.header.rst index 07152c224f2..e093f138936 100644 --- a/Doc/library/email.header.rst +++ b/Doc/library/email.header.rst @@ -116,7 +116,7 @@ Here is the :class:`Header` class description: if *s* is a byte string. - .. method:: encode(splitchars=';, \\t', maxlinelen=None, linesep='\\n') + .. method:: encode(splitchars=';, \t', maxlinelen=None, linesep='\n') Encode a message header into an RFC-compliant format, possibly wrapping long lines and encapsulating non-ASCII parts in base64 or quoted-printable diff --git a/Doc/library/email.headerregistry.rst b/Doc/library/email.headerregistry.rst index 3e1d97a0326..00a954e0307 100644 --- a/Doc/library/email.headerregistry.rst +++ b/Doc/library/email.headerregistry.rst @@ -153,7 +153,7 @@ headers. specified as ``-0000`` (indicating it is in UTC but contains no information about the source timezone), then :attr:`.datetime` will be a naive :class:`~datetime.datetime`. If a specific timezone offset is - found (including `+0000`), then :attr:`.datetime` will contain an aware + found (including ``+0000``), then :attr:`.datetime` will contain an aware ``datetime`` that uses :class:`datetime.timezone` to record the timezone offset. @@ -206,7 +206,7 @@ headers. The ``decoded`` value of the header will have all encoded words decoded to unicode. :class:`~encodings.idna` encoded domain names are also decoded to - unicode. The ``decoded`` value is set by :attr:`~str.join`\ ing the + unicode. The ``decoded`` value is set by :ref:`joining ` the :class:`str` value of the elements of the ``groups`` attribute with ``', '``. diff --git a/Doc/library/email.mime.rst b/Doc/library/email.mime.rst index f37f6aa28de..d7c0d203d19 100644 --- a/Doc/library/email.mime.rst +++ b/Doc/library/email.mime.rst @@ -114,9 +114,9 @@ Here are the classes: A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the :class:`MIMEApplication` class is used to represent MIME message objects of - major type :mimetype:`application`. *_data* is a string containing the raw - byte data. Optional *_subtype* specifies the MIME subtype and defaults to - :mimetype:`octet-stream`. + major type :mimetype:`application`. *_data* contains the bytes for the raw + application data. Optional *_subtype* specifies the MIME subtype and defaults + to :mimetype:`octet-stream`. Optional *_encoder* is a callable (i.e. function) which will perform the actual encoding of the data for transport. This callable takes one argument, which is @@ -145,8 +145,8 @@ Here are the classes: A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the :class:`MIMEAudio` class is used to create MIME message objects of major type - :mimetype:`audio`. *_audiodata* is a string containing the raw audio data. If - this data can be decoded by the standard Python module :mod:`sndhdr`, then the + :mimetype:`audio`. *_audiodata* contains the bytes for the raw audio data. If + this data can be decoded as au, wav, aiff, or aifc, then the subtype will be automatically included in the :mailheader:`Content-Type` header. Otherwise you can explicitly specify the audio subtype via the *_subtype* argument. If the minor type could not be guessed and *_subtype* was not given, @@ -179,12 +179,13 @@ Here are the classes: A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the :class:`MIMEImage` class is used to create MIME message objects of major type - :mimetype:`image`. *_imagedata* is a string containing the raw image data. If - this data can be decoded by the standard Python module :mod:`imghdr`, then the - subtype will be automatically included in the :mailheader:`Content-Type` header. - Otherwise you can explicitly specify the image subtype via the *_subtype* - argument. If the minor type could not be guessed and *_subtype* was not given, - then :exc:`TypeError` is raised. + :mimetype:`image`. *_imagedata* contains the bytes for the raw image data. If + this data type can be detected (jpeg, png, gif, tiff, rgb, pbm, pgm, ppm, + rast, xbm, bmp, webp, and exr attempted), then the subtype will be + automatically included in the :mailheader:`Content-Type` header. Otherwise + you can explicitly specify the image subtype via the *_subtype* argument. + If the minor type could not be guessed and *_subtype* was not given, then + :exc:`TypeError` is raised. Optional *_encoder* is a callable (i.e. function) which will perform the actual encoding of the image data for transport. This callable takes one argument, diff --git a/Doc/library/email.policy.rst b/Doc/library/email.policy.rst index bf53b9520fc..2439dee676c 100644 --- a/Doc/library/email.policy.rst +++ b/Doc/library/email.policy.rst @@ -97,6 +97,7 @@ file on disk and pass it to the system ``sendmail`` program on a Unix system: >>> from subprocess import Popen, PIPE >>> with open('mymsg.txt', 'rb') as f: ... msg = message_from_binary_file(f, policy=policy.default) + ... >>> p = Popen(['sendmail', msg['To'].addresses[0]], stdin=PIPE) >>> g = BytesGenerator(p.stdin, policy=msg.policy.clone(linesep='\r\n')) >>> g.flatten(msg) diff --git a/Doc/library/ensurepip.rst b/Doc/library/ensurepip.rst index fa1b42cf484..d7f89cf9636 100644 --- a/Doc/library/ensurepip.rst +++ b/Doc/library/ensurepip.rst @@ -7,6 +7,8 @@ .. versionadded:: 3.4 +**Source code:** :source:`Lib/ensurepip` + -------------- The :mod:`ensurepip` package provides support for bootstrapping the ``pip`` @@ -36,6 +38,7 @@ when creating a virtual environment) or after explicitly uninstalling :pep:`453`: Explicit bootstrapping of pip in Python installations The original rationale and specification for this module. +.. include:: ../includes/wasm-notavail.rst Command line interface ---------------------- diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index 850b491680c..cfe4fbeb069 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -27,11 +27,12 @@ An enumeration: * is a set of symbolic names (members) bound to unique values -* can be iterated over to return its members in definition order +* can be iterated over to return its canonical (i.e. non-alias) members in + definition order * uses *call* syntax to return members by value * uses *index* syntax to return members by name -Enumerations are created either by using the :keyword:`class` syntax, or by +Enumerations are created either by using :keyword:`class` syntax, or by using function-call syntax:: >>> from enum import Enum @@ -45,17 +46,17 @@ using function-call syntax:: >>> # functional syntax >>> Color = Enum('Color', ['RED', 'GREEN', 'BLUE']) -Even though we can use the :keyword:`class` syntax to create Enums, Enums +Even though we can use :keyword:`class` syntax to create Enums, Enums are not normal Python classes. See :ref:`How are Enums different? ` for more details. .. note:: Nomenclature - - The class :class:`Color` is an *enumeration* (or *enum*) - - The attributes :attr:`Color.RED`, :attr:`Color.GREEN`, etc., are - *enumeration members* (or *enum members*) and are functionally constants. + - The class :class:`!Color` is an *enumeration* (or *enum*) + - The attributes :attr:`!Color.RED`, :attr:`!Color.GREEN`, etc., are + *enumeration members* (or *members*) and are functionally constants. - The enum members have *names* and *values* (the name of - :attr:`Color.RED` is ``RED``, the value of :attr:`Color.BLUE` is + :attr:`!Color.RED` is ``RED``, the value of :attr:`!Color.BLUE` is ``3``, etc.) --------------- @@ -92,6 +93,11 @@ Module Contents the bitwise operators without losing their :class:`IntFlag` membership. :class:`IntFlag` members are also subclasses of :class:`int`. (`Notes`_) + :class:`ReprEnum` + + Used by :class:`IntEnum`, :class:`StrEnum`, and :class:`IntFlag` + to keep the :class:`str() ` of the mixed-in type. + :class:`EnumCheck` An enumeration with the values ``CONTINUOUS``, ``NAMED_FLAGS``, and @@ -110,15 +116,10 @@ Module Contents :class:`StrEnum` defaults to the lower-cased version of the member name, while other Enums default to 1 and increase from there. - :func:`global_enum` - - :class:`Enum` class decorator to apply the appropriate global `__repr__`, - and export its members into the global name space. - - :func:`.property` + :func:`~enum.property` Allows :class:`Enum` members to have attributes without conflicting with - other members' names. + member names. :func:`unique` @@ -129,9 +130,28 @@ Module Contents Enum class decorator that checks user-selectable constraints on an enumeration. + :func:`member` + + Make ``obj`` a member. Can be used as a decorator. + + :func:`nonmember` + + Do not make ``obj`` a member. Can be used as a decorator. + + :func:`global_enum` + + Modify the :class:`str() ` and :func:`repr` of an enum + to show its members as belonging to the module instead of its class. + Should only be used if the enum members will be exported to the + module global namespace. + + :func:`show_flag_values` + + Return a list of all power-of-two integers contained in a flag. + .. versionadded:: 3.6 ``Flag``, ``IntFlag``, ``auto`` -.. versionadded:: 3.11 ``StrEnum``, ``EnumCheck``, ``FlagBoundary`` +.. versionadded:: 3.11 ``StrEnum``, ``EnumCheck``, ``ReprEnum``, ``FlagBoundary``, ``property``, ``member``, ``nonmember``, ``global_enum``, ``show_flag_values`` --------------- @@ -145,6 +165,11 @@ Data Types to subclass *EnumType* -- see :ref:`Subclassing EnumType ` for details. + *EnumType* is responsible for setting the correct :meth:`!__repr__`, + :meth:`!__str__`, :meth:`!__format__`, and :meth:`!__reduce__` methods on the + final *enum*, as well as creating the enum members, properly handling + duplicates, providing iteration over the enum class, etc. + .. method:: EnumType.__contains__(cls, member) Returns ``True`` if member belongs to the ``cls``:: @@ -165,28 +190,21 @@ Data Types names of the members in *cls*:: >>> dir(Color) - ['BLUE', 'GREEN', 'RED', '__class__', '__doc__', '__members__', '__module__'] - - .. method:: EnumType.__getattr__(cls, name) - - Returns the Enum member in *cls* matching *name*, or raises an :exc:`AttributeError`:: - - >>> Color.GREEN - Color.GREEN + ['BLUE', 'GREEN', 'RED', '__class__', '__contains__', '__doc__', '__getitem__', '__init_subclass__', '__iter__', '__len__', '__members__', '__module__', '__name__', '__qualname__'] .. method:: EnumType.__getitem__(cls, name) - Returns the Enum member in *cls* matching *name*, or raises an :exc:`KeyError`:: + Returns the Enum member in *cls* matching *name*, or raises a :exc:`KeyError`:: >>> Color['BLUE'] - Color.BLUE + .. method:: EnumType.__iter__(cls) Returns each member in *cls* in definition order:: >>> list(Color) - [Color.RED, Color.GREEN, Color.BLUE] + [, , ] .. method:: EnumType.__len__(cls) @@ -200,7 +218,7 @@ Data Types Returns each member in *cls* in reverse definition order:: >>> list(reversed(Color)) - [Color.BLUE, Color.GREEN, Color.RED] + [, , ] .. class:: Enum @@ -223,21 +241,21 @@ Data Types .. note:: Enum member values - Member values can be anything: :class:`int`, :class:`str`, etc.. If + Member values can be anything: :class:`int`, :class:`str`, etc. If the exact value is unimportant you may use :class:`auto` instances and an - appropriate value will be chosen for you. Care must be taken if you mix - :class:`auto` with other values. + appropriate value will be chosen for you. See :class:`auto` for the + details. .. attribute:: Enum._ignore_ ``_ignore_`` is only used during creation and is removed from the - enumeration once that is complete. + enumeration once creation is complete. ``_ignore_`` is a list of names that will not become members, and whose names will also be removed from the completed enumeration. See :ref:`TimePeriod ` for an example. - .. method:: Enum.__call__(cls, value, names=None, \*, module=None, qualname=None, type=None, start=1, boundary=None) + .. method:: Enum.__call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None) This method is called in two different ways: @@ -254,8 +272,8 @@ Data Types :module: The name of the module the new Enum is created in. :qualname: The actual location in the module where this Enum can be found. :type: A mix-in type for the new Enum. - :start: The first integer value for the Enum (used by :class:`auto`) - :boundary: How to handle out-of-range values from bit operations (:class:`Flag` only) + :start: The first integer value for the Enum (used by :class:`auto`). + :boundary: How to handle out-of-range values from bit operations (:class:`Flag` only). .. method:: Enum.__dir__(self) @@ -274,8 +292,9 @@ Data Types ... @classmethod ... def today(cls): ... print('today is %s' % cls(date.today().isoweekday()).name) + ... >>> dir(Weekday.SATURDAY) - ['__class__', '__doc__', '__module__', 'name', 'today', 'value'] + ['__class__', '__doc__', '__eq__', '__hash__', '__module__', 'name', 'today', 'value'] .. method:: Enum._generate_next_value_(name, start, count, last_values) @@ -291,11 +310,17 @@ Data Types >>> class PowersOfThree(Enum): ... @staticmethod ... def _generate_next_value_(name, start, count, last_values): - ... return (count + 1) * 3 + ... return 3 ** (count + 1) ... FIRST = auto() ... SECOND = auto() + ... >>> PowersOfThree.SECOND.value - 6 + 9 + + .. method:: Enum.__init_subclass__(cls, **kwds) + + A *classmethod* that is used to further configure subsequent subclasses. + By default, does nothing. .. method:: Enum._missing_(cls, value) @@ -313,45 +338,64 @@ Data Types ... if member.value == value: ... return member ... return None + ... >>> Build.DEBUG.value 'debug' >>> Build('deBUG') - Build.DEBUG + .. method:: Enum.__repr__(self) Returns the string used for *repr()* calls. By default, returns the - *Enum* name and the member name, but can be overridden:: + *Enum* name, member name, and value, but can be overridden:: - >>> class OldStyle(Enum): - ... RETRO = auto() - ... OLD_SCHOOl = auto() - ... YESTERYEAR = auto() + >>> class OtherStyle(Enum): + ... ALTERNATE = auto() + ... OTHER = auto() + ... SOMETHING_ELSE = auto() ... def __repr__(self): ... cls_name = self.__class__.__name__ - ... return f'<{cls_name}.{self.name}: {self.value}>' - >>> OldStyle.RETRO - + ... return f'{cls_name}.{self.name}' + ... + >>> OtherStyle.ALTERNATE, str(OtherStyle.ALTERNATE), f"{OtherStyle.ALTERNATE}" + (OtherStyle.ALTERNATE, 'OtherStyle.ALTERNATE', 'OtherStyle.ALTERNATE') .. method:: Enum.__str__(self) Returns the string used for *str()* calls. By default, returns the - member name, but can be overridden:: + *Enum* name and member name, but can be overridden:: - >>> class OldStyle(Enum): - ... RETRO = auto() - ... OLD_SCHOOl = auto() - ... YESTERYEAR = auto() + >>> class OtherStyle(Enum): + ... ALTERNATE = auto() + ... OTHER = auto() + ... SOMETHING_ELSE = auto() ... def __str__(self): - ... cls_name = self.__class__.__name__ - ... return f'{cls_name}.{self.name}' - >>> OldStyle.RETRO - OldStyle.RETRO + ... return f'{self.name}' + ... + >>> OtherStyle.ALTERNATE, str(OtherStyle.ALTERNATE), f"{OtherStyle.ALTERNATE}" + (, 'ALTERNATE', 'ALTERNATE') -.. note:: + .. method:: Enum.__format__(self) - Using :class:`auto` with :class:`Enum` results in integers of increasing value, - starting with ``1``. + Returns the string used for *format()* and *f-string* calls. By default, + returns :meth:`__str__` return value, but can be overridden:: + + >>> class OtherStyle(Enum): + ... ALTERNATE = auto() + ... OTHER = auto() + ... SOMETHING_ELSE = auto() + ... def __format__(self, spec): + ... return f'{self.name}' + ... + >>> OtherStyle.ALTERNATE, str(OtherStyle.ALTERNATE), f"{OtherStyle.ALTERNATE}" + (, 'OtherStyle.ALTERNATE', 'ALTERNATE') + + .. note:: + + Using :class:`auto` with :class:`Enum` results in integers of increasing value, + starting with ``1``. + + .. versionchanged:: 3.12 Added :ref:`enum-dataclass-support` .. class:: IntEnum @@ -365,8 +409,9 @@ Data Types ... ONE = 1 ... TWO = 2 ... THREE = 3 + ... >>> Numbers.THREE - Numbers.THREE + >>> Numbers.ONE + Numbers.TWO 3 >>> Numbers.THREE + 5 @@ -374,10 +419,14 @@ Data Types >>> Numbers.THREE == 3 True -.. note:: + .. note:: - Using :class:`auto` with :class:`IntEnum` results in integers of increasing value, - starting with ``1``. + Using :class:`auto` with :class:`IntEnum` results in integers of increasing + value, starting with ``1``. + + .. versionchanged:: 3.11 :meth:`~object.__str__` is now :meth:`!int.__str__` to + better support the *replacement of existing constants* use-case. + :meth:`~object.__format__` was already :meth:`!int.__format__` for that same reason. .. class:: StrEnum @@ -386,18 +435,25 @@ Data Types in most of the same places that a string can be used. The result of any string operation performed on or with a *StrEnum* member is not part of the enumeration. - .. note:: There are places in the stdlib that check for an exact :class:`str` - instead of a :class:`str` subclass (i.e. ``type(unknown) == str`` - instead of ``isinstance(str, unknown)``), and in those locations you - will need to use ``str(StrEnum.member)``. + .. note:: + There are places in the stdlib that check for an exact :class:`str` + instead of a :class:`str` subclass (i.e. ``type(unknown) == str`` + instead of ``isinstance(unknown, str)``), and in those locations you + will need to use ``str(StrEnum.member)``. -.. note:: + .. note:: - Using :class:`auto` with :class:`StrEnum` results in values of the member name, - lower-cased. + Using :class:`auto` with :class:`StrEnum` results in the lower-cased member + name as the value. -.. versionadded:: 3.11 + .. note:: + + :meth:`~object.__str__` is :meth:`!str.__str__` to better support the + *replacement of existing constants* use-case. :meth:`~object.__format__` is likewise + :meth:`!str.__format__` for that same reason. + + .. versionadded:: 3.11 .. class:: Flag @@ -414,6 +470,7 @@ Data Types ... RED = auto() ... GREEN = auto() ... BLUE = auto() + ... >>> purple = Color.RED | Color.BLUE >>> white = Color.RED | Color.GREEN | Color.BLUE >>> Color.GREEN in purple @@ -427,12 +484,16 @@ Data Types .. method:: __iter__(self): - Returns all contained members:: + Returns all contained non-alias members:: >>> list(Color.RED) - [Color.RED] + [] >>> list(purple) - [Color.RED, Color.BLUE] + [, ] + + .. versionchanged:: 3.11 + + Aliases are no longer returned during iteration. .. method:: __len__(self): @@ -460,42 +521,52 @@ Data Types Returns current flag binary or'ed with other:: >>> Color.RED | Color.GREEN - Color.RED|Color.GREEN + .. method:: __and__(self, other) Returns current flag binary and'ed with other:: >>> purple & white - Color.RED|Color.BLUE + >>> purple & Color.GREEN - 0x0 + .. method:: __xor__(self, other) Returns current flag binary xor'ed with other:: >>> purple ^ white - Color.GREEN + >>> purple ^ Color.GREEN - Color.RED|Color.GREEN|Color.BLUE + .. method:: __invert__(self): Returns all the flags in *type(self)* that are not in self:: >>> ~white - 0x0 + >>> ~purple - Color.GREEN + >>> ~Color.RED - Color.GREEN|Color.BLUE + -.. note:: + .. method:: _numeric_repr_ - Using :class:`auto` with :class:`Flag` results in integers that are powers - of two, starting with ``1``. + Function used to format any remaining unnamed numeric values. Default is + the value's repr; common choices are :func:`hex` and :func:`oct`. + .. note:: + + Using :class:`auto` with :class:`Flag` results in integers that are powers + of two, starting with ``1``. + + .. versionchanged:: 3.11 The *repr()* of zero-valued flags has changed. It + is now:: + + >>> Color(0) # doctest: +SKIP + .. class:: IntFlag @@ -507,10 +578,11 @@ Data Types ... RED = auto() ... GREEN = auto() ... BLUE = auto() + ... >>> Color.RED & 2 - 0x0 + >>> Color.RED | 2 - Color.RED|Color.GREEN + If any integer operation is performed with an *IntFlag* member, the result is not an *IntFlag*:: @@ -523,15 +595,45 @@ Data Types * the result is a valid *IntFlag*: an *IntFlag* is returned * the result is not a valid *IntFlag*: the result depends on the *FlagBoundary* setting -.. note:: + The *repr()* of unnamed zero-valued flags has changed. It is now: - Using :class:`auto` with :class:`IntFlag` results in integers that are powers - of two, starting with ``1``. + >>> Color(0) + + + .. note:: + + Using :class:`auto` with :class:`IntFlag` results in integers that are powers + of two, starting with ``1``. + + .. versionchanged:: 3.11 + + :meth:`~object.__str__` is now :meth:`!int.__str__` to better support the + *replacement of existing constants* use-case. :meth:`~object.__format__` was + already :meth:`!int.__format__` for that same reason. + + Inversion of an :class:`!IntFlag` now returns a positive value that is the + union of all flags not in the given flag, rather than a negative value. + This matches the existing :class:`Flag` behavior. + +.. class:: ReprEnum + + :class:`!ReprEnum` uses the :meth:`repr() ` of :class:`Enum`, + but the :class:`str() ` of the mixed-in data type: + + * :meth:`!int.__str__` for :class:`IntEnum` and :class:`IntFlag` + * :meth:`!str.__str__` for :class:`StrEnum` + + Inherit from :class:`!ReprEnum` to keep the :class:`str() ` / :func:`format` + of the mixed-in data type instead of using the + :class:`Enum`-default :meth:`str() `. + + + .. versionadded:: 3.11 .. class:: EnumCheck *EnumCheck* contains the options used by the :func:`verify` decorator to ensure - various constraints; failed constraints result in a :exc:`TypeError`. + various constraints; failed constraints result in a :exc:`ValueError`. .. attribute:: UNIQUE @@ -567,7 +669,7 @@ Data Types .. attribute:: NAMED_FLAGS Ensure that any flag groups/masks contain only named flags -- useful when - values are specified instead of being generated by :func:`auto` + values are specified instead of being generated by :func:`auto`:: >>> from enum import Flag, verify, NAMED_FLAGS >>> @verify(NAMED_FLAGS) @@ -581,11 +683,11 @@ Data Types ... ValueError: invalid Flag 'Color': aliases WHITE and NEON are missing combined values of 0x18 [use enum.show_flag_values(value) for details] -.. note:: + .. note:: - CONTINUOUS and NAMED_FLAGS are designed to work with integer-valued members. + CONTINUOUS and NAMED_FLAGS are designed to work with integer-valued members. -.. versionadded:: 3.11 + .. versionadded:: 3.11 .. class:: FlagBoundary @@ -602,10 +704,11 @@ Data Types ... RED = auto() ... GREEN = auto() ... BLUE = auto() + ... >>> StrictFlag(2**2 + 2**4) Traceback (most recent call last): ... - ValueError: StrictFlag: invalid value: 20 + ValueError: invalid value 20 given 0b0 10100 allowed 0b0 00111 @@ -619,8 +722,9 @@ Data Types ... RED = auto() ... GREEN = auto() ... BLUE = auto() + ... >>> ConformFlag(2**2 + 2**4) - ConformFlag.BLUE + .. attribute:: EJECT @@ -632,6 +736,7 @@ Data Types ... RED = auto() ... GREEN = auto() ... BLUE = auto() + ... >>> EjectFlag(2**2 + 2**4) 20 @@ -645,36 +750,86 @@ Data Types ... RED = auto() ... GREEN = auto() ... BLUE = auto() + ... >>> KeepFlag(2**2 + 2**4) - KeepFlag.BLUE|0x10 + .. versionadded:: 3.11 --------------- +Supported ``__dunder__`` names +"""""""""""""""""""""""""""""" + +:attr:`~EnumType.__members__` is a read-only ordered mapping of ``member_name``:``member`` +items. It is only available on the class. + +:meth:`~object.__new__`, if specified, must create and return the enum members; it is +also a very good idea to set the member's :attr:`!_value_` appropriately. Once +all the members are created it is no longer used. + + +Supported ``_sunder_`` names +"""""""""""""""""""""""""""" + +- ``_name_`` -- name of the member +- ``_value_`` -- value of the member; can be set / modified in ``__new__`` + +- ``_missing_`` -- a lookup function used when a value is not found; may be + overridden +- ``_ignore_`` -- a list of names, either as a :class:`list` or a :class:`str`, + that will not be transformed into members, and will be removed from the final + class +- ``_order_`` -- used in Python 2/3 code to ensure member order is consistent + (class attribute, removed during class creation) +- ``_generate_next_value_`` -- used to get an appropriate value for an enum + member; may be overridden + + .. note:: + + For standard :class:`Enum` classes the next value chosen is the last value seen + incremented by one. + + For :class:`Flag` classes the next value chosen will be the next highest + power-of-two, regardless of the last value seen. + +.. versionadded:: 3.6 ``_missing_``, ``_order_``, ``_generate_next_value_`` +.. versionadded:: 3.7 ``_ignore_`` + +--------------- + Utilities and Decorators ------------------------ .. class:: auto *auto* can be used in place of a value. If used, the *Enum* machinery will - call an *Enum*'s :meth:`_generate_next_value_` to get an appropriate value. + call an *Enum*'s :meth:`~Enum._generate_next_value_` to get an appropriate value. For *Enum* and *IntEnum* that appropriate value will be the last value plus one; for *Flag* and *IntFlag* it will be the first power-of-two greater - than the last value; for *StrEnum* it will be the lower-cased version of the - member's name. + than the highest value; for *StrEnum* it will be the lower-cased version of + the member's name. Care must be taken if mixing *auto()* with manually + specified values. + + *auto* instances are only resolved when at the top level of an assignment: + + * ``FIRST = auto()`` will work (auto() is replaced with ``1``); + * ``SECOND = auto(), -2`` will work (auto is replaced with ``2``, so ``2, -2`` is + used to create the ``SECOND`` enum member; + * ``THREE = [auto(), -3]`` will *not* work (``, -3`` is used to + create the ``THREE`` enum member) + + .. versionchanged:: 3.11.1 + + In prior versions, ``auto()`` had to be the only thing + on the assignment line to work properly. ``_generate_next_value_`` can be overridden to customize the values used by *auto*. -.. decorator:: global_enum - - A :keyword:`class` decorator specifically for enumerations. It replaces the - :meth:`__repr__` method with one that shows *module_name*.*member_name*. It - also injects the members, and their aliases, into the global namespace they - were defined in. - -.. versionadded:: 3.11 + .. note:: in 3.13 the default ``_generate_next_value_`` will always return + the highest member value incremented by 1, and will fail if any + member is an incompatible type. .. decorator:: property @@ -687,12 +842,12 @@ Utilities and Decorators *Enum* class, and *Enum* subclasses can define members with the names ``value`` and ``name``. -.. versionadded:: 3.11 + .. versionadded:: 3.11 .. decorator:: unique A :keyword:`class` decorator specifically for enumerations. It searches an - enumeration's :attr:`__members__`, gathering any aliases it finds; if any are + enumeration's :attr:`~EnumType.__members__`, gathering any aliases it finds; if any are found :exc:`ValueError` is raised with the details:: >>> from enum import Enum, unique @@ -713,7 +868,35 @@ Utilities and Decorators :class:`EnumCheck` are used to specify which constraints should be checked on the decorated enumeration. -.. versionadded:: 3.11 + .. versionadded:: 3.11 + +.. decorator:: member + + A decorator for use in enums: its target will become a member. + + .. versionadded:: 3.11 + +.. decorator:: nonmember + + A decorator for use in enums: its target will not become a member. + + .. versionadded:: 3.11 + +.. decorator:: global_enum + + A decorator to change the :class:`str() ` and :func:`repr` of an enum + to show its members as belonging to the module instead of its class. + Should only be used when the enum members are exported + to the module global namespace (see :class:`re.RegexFlag` for an example). + + + .. versionadded:: 3.11 + +.. function:: show_flag_values(value) + + Return a list of all power-of-two integers contained in a flag *value*. + + .. versionadded:: 3.11 --------------- @@ -722,17 +905,23 @@ Notes :class:`IntEnum`, :class:`StrEnum`, and :class:`IntFlag` - These three enum types are designed to be drop-in replacements for existing - integer- and string-based values; as such, they have extra limitations: + These three enum types are designed to be drop-in replacements for existing + integer- and string-based values; as such, they have extra limitations: - - ``format()`` will use the value of the enum member, unless ``__str__`` - has been overridden + - ``__str__`` uses the value and not the name of the enum member - - ``StrEnum.__str__`` uses the value and not the name of the enum member + - ``__format__``, because it uses ``__str__``, will also use the value of + the enum member instead of its name - If you do not need/want those limitations, you can create your own base - class by mixing in the ``int`` or ``str`` type yourself:: + If you do not need/want those limitations, you can either create your own + base class by mixing in the ``int`` or ``str`` type yourself:: - >>> from enum import Enum - >>> class MyIntEnum(int, Enum): - ... pass + >>> from enum import Enum + >>> class MyIntEnum(int, Enum): + ... pass + + or you can reassign the appropriate :meth:`str`, etc., in your enum:: + + >>> from enum import IntEnum + >>> class MyIntEnum(IntEnum): + ... __str__ = IntEnum.__str__ diff --git a/Doc/library/errno.rst b/Doc/library/errno.rst index 93bdb6ca9b8..5122c69697e 100644 --- a/Doc/library/errno.rst +++ b/Doc/library/errno.rst @@ -8,7 +8,7 @@ This module makes available standard ``errno`` system symbols. The value of each symbol is the corresponding integer value. The names and descriptions are -borrowed from :file:`linux/include/errno.h`, which should be pretty +borrowed from :file:`linux/include/errno.h`, which should be all-inclusive. @@ -27,25 +27,26 @@ defined by the module. The specific list of defined symbols is available as .. data:: EPERM - Operation not permitted + Operation not permitted. This error is mapped to the exception + :exc:`PermissionError`. .. data:: ENOENT - No such file or directory + No such file or directory. This error is mapped to the exception + :exc:`FileNotFoundError`. .. data:: ESRCH - No such process + No such process. This error is mapped to the exception + :exc:`ProcessLookupError`. .. data:: EINTR - Interrupted system call. - - .. seealso:: - This error is mapped to the exception :exc:`InterruptedError`. + Interrupted system call. This error is mapped to the exception + :exc:`InterruptedError`. .. data:: EIO @@ -75,12 +76,13 @@ defined by the module. The specific list of defined symbols is available as .. data:: ECHILD - No child processes + No child processes. This error is mapped to the exception + :exc:`ChildProcessError`. .. data:: EAGAIN - Try again + Try again. This error is mapped to the exception :exc:`BlockingIOError`. .. data:: ENOMEM @@ -90,7 +92,8 @@ defined by the module. The specific list of defined symbols is available as .. data:: EACCES - Permission denied + Permission denied. This error is mapped to the exception + :exc:`PermissionError`. .. data:: EFAULT @@ -110,7 +113,8 @@ defined by the module. The specific list of defined symbols is available as .. data:: EEXIST - File exists + File exists. This error is mapped to the exception + :exc:`FileExistsError`. .. data:: EXDEV @@ -125,12 +129,14 @@ defined by the module. The specific list of defined symbols is available as .. data:: ENOTDIR - Not a directory + Not a directory. This error is mapped to the exception + :exc:`NotADirectoryError`. .. data:: EISDIR - Is a directory + Is a directory. This error is mapped to the exception + :exc:`IsADirectoryError`. .. data:: EINVAL @@ -185,7 +191,8 @@ defined by the module. The specific list of defined symbols is available as .. data:: EPIPE - Broken pipe + Broken pipe. This error is mapped to the exception + :exc:`BrokenPipeError`. .. data:: EDOM @@ -230,7 +237,8 @@ defined by the module. The specific list of defined symbols is available as .. data:: EWOULDBLOCK - Operation would block + Operation would block. This error is mapped to the exception + :exc:`BlockingIOError`. .. data:: ENOMSG @@ -540,12 +548,14 @@ defined by the module. The specific list of defined symbols is available as .. data:: ECONNABORTED - Software caused connection abort + Software caused connection abort. This error is mapped to the + exception :exc:`ConnectionAbortedError`. .. data:: ECONNRESET - Connection reset by peer + Connection reset by peer. This error is mapped to the exception + :exc:`ConnectionResetError`. .. data:: ENOBUFS @@ -565,7 +575,8 @@ defined by the module. The specific list of defined symbols is available as .. data:: ESHUTDOWN - Cannot send after transport endpoint shutdown + Cannot send after transport endpoint shutdown. This error is mapped + to the exception :exc:`BrokenPipeError`. .. data:: ETOOMANYREFS @@ -575,12 +586,14 @@ defined by the module. The specific list of defined symbols is available as .. data:: ETIMEDOUT - Connection timed out + Connection timed out. This error is mapped to the exception + :exc:`TimeoutError`. .. data:: ECONNREFUSED - Connection refused + Connection refused. This error is mapped to the exception + :exc:`ConnectionRefusedError`. .. data:: EHOSTDOWN @@ -595,12 +608,14 @@ defined by the module. The specific list of defined symbols is available as .. data:: EALREADY - Operation already in progress + Operation already in progress. This error is mapped to the + exception :exc:`BlockingIOError`. .. data:: EINPROGRESS - Operation now in progress + Operation now in progress. This error is mapped to the exception + :exc:`BlockingIOError`. .. data:: ESTALE @@ -642,3 +657,12 @@ defined by the module. The specific list of defined symbols is available as Interface output queue is full .. versionadded:: 3.11 + +.. data:: ENOTCAPABLE + + Capabilities insufficient. This error is mapped to the exception + :exc:`PermissionError`. + + .. availability:: WASI, FreeBSD + + .. versionadded:: 3.11.1 diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index 8fa82a98a19..1217b817b4e 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -38,15 +38,14 @@ information on defining exceptions is available in the Python Tutorial under Exception context ----------------- -When raising (or re-raising) an exception in an :keyword:`except` or -:keyword:`finally` clause -:attr:`__context__` is automatically set to the last exception caught; if the -new exception is not handled the traceback that is eventually displayed will -include the originating exception(s) and the final exception. +When raising a new exception while another exception +is already being handled, the new exception's +:attr:`__context__` attribute is automatically set to the handled +exception. An exception may be handled when an :keyword:`except` or +:keyword:`finally` clause, or a :keyword:`with` statement, is used. -When raising a new exception (rather than using a bare ``raise`` to re-raise -the exception currently being handled), the implicit exception context can be -supplemented with an explicit cause by using :keyword:`from` with +This implicit exception context can be +supplemented with an explicit cause by using :keyword:`!from` with :keyword:`raise`:: raise new_exc from original_exc @@ -127,6 +126,21 @@ The following exceptions are used mostly as base classes for other exceptions. tb = sys.exc_info()[2] raise OtherException(...).with_traceback(tb) + .. method:: add_note(note) + + Add the string ``note`` to the exception's notes which appear in the standard + traceback after the exception string. A :exc:`TypeError` is raised if ``note`` + is not a string. + + .. versionadded:: 3.11 + + .. attribute:: __notes__ + + A list of the notes of this exception, which were added with :meth:`add_note`. + This attribute is created when :meth:`add_note` is called. + + .. versionadded:: 3.11 + .. exception:: Exception @@ -247,6 +261,15 @@ The following exceptions are the exceptions that are usually raised. accidentally caught by code that catches :exc:`Exception` and thus prevent the interpreter from exiting. + .. note:: + + Catching a :exc:`KeyboardInterrupt` requires special consideration. + Because it can be raised at unpredictable points, it may, in some + circumstances, leave the running program in an inconsistent state. It is + generally best to allow :exc:`KeyboardInterrupt` to end the program as + quickly as possible or avoid raising it entirely. (See + :ref:`handlers-and-exceptions`.) + .. exception:: MemoryError @@ -636,8 +659,8 @@ depending on the system error code. Raised when an operation would block on an object (e.g. socket) set for non-blocking operation. - Corresponds to :c:data:`errno` ``EAGAIN``, ``EALREADY``, - ``EWOULDBLOCK`` and ``EINPROGRESS``. + Corresponds to :c:data:`errno` :py:data:`~errno.EAGAIN`, :py:data:`~errno.EALREADY`, + :py:data:`~errno.EWOULDBLOCK` and :py:data:`~errno.EINPROGRESS`. In addition to those of :exc:`OSError`, :exc:`BlockingIOError` can have one more attribute: @@ -651,7 +674,7 @@ depending on the system error code. .. exception:: ChildProcessError Raised when an operation on a child process failed. - Corresponds to :c:data:`errno` ``ECHILD``. + Corresponds to :c:data:`errno` :py:data:`~errno.ECHILD`. .. exception:: ConnectionError @@ -665,35 +688,35 @@ depending on the system error code. A subclass of :exc:`ConnectionError`, raised when trying to write on a pipe while the other end has been closed, or trying to write on a socket which has been shutdown for writing. - Corresponds to :c:data:`errno` ``EPIPE`` and ``ESHUTDOWN``. + Corresponds to :c:data:`errno` :py:data:`~errno.EPIPE` and :py:data:`~errno.ESHUTDOWN`. .. exception:: ConnectionAbortedError A subclass of :exc:`ConnectionError`, raised when a connection attempt is aborted by the peer. - Corresponds to :c:data:`errno` ``ECONNABORTED``. + Corresponds to :c:data:`errno` :py:data:`~errno.ECONNABORTED`. .. exception:: ConnectionRefusedError A subclass of :exc:`ConnectionError`, raised when a connection attempt is refused by the peer. - Corresponds to :c:data:`errno` ``ECONNREFUSED``. + Corresponds to :c:data:`errno` :py:data:`~errno.ECONNREFUSED`. .. exception:: ConnectionResetError A subclass of :exc:`ConnectionError`, raised when a connection is reset by the peer. - Corresponds to :c:data:`errno` ``ECONNRESET``. + Corresponds to :c:data:`errno` :py:data:`~errno.ECONNRESET`. .. exception:: FileExistsError Raised when trying to create a file or directory which already exists. - Corresponds to :c:data:`errno` ``EEXIST``. + Corresponds to :c:data:`errno` :py:data:`~errno.EEXIST`. .. exception:: FileNotFoundError Raised when a file or directory is requested but doesn't exist. - Corresponds to :c:data:`errno` ``ENOENT``. + Corresponds to :c:data:`errno` :py:data:`~errno.ENOENT`. .. exception:: InterruptedError @@ -709,7 +732,7 @@ depending on the system error code. Raised when a file operation (such as :func:`os.remove`) is requested on a directory. - Corresponds to :c:data:`errno` ``EISDIR``. + Corresponds to :c:data:`errno` :py:data:`~errno.EISDIR`. .. exception:: NotADirectoryError @@ -717,23 +740,28 @@ depending on the system error code. something which is not a directory. On most POSIX platforms, it may also be raised if an operation attempts to open or traverse a non-directory file as if it were a directory. - Corresponds to :c:data:`errno` ``ENOTDIR``. + Corresponds to :c:data:`errno` :py:data:`~errno.ENOTDIR`. .. exception:: PermissionError Raised when trying to run an operation without the adequate access rights - for example filesystem permissions. - Corresponds to :c:data:`errno` ``EACCES`` and ``EPERM``. + Corresponds to :c:data:`errno` :py:data:`~errno.EACCES`, + :py:data:`~errno.EPERM`, and :py:data:`~errno.ENOTCAPABLE`. + + .. versionchanged:: 3.11.1 + WASI's :py:data:`~errno.ENOTCAPABLE` is now mapped to + :exc:`PermissionError`. .. exception:: ProcessLookupError Raised when a given process doesn't exist. - Corresponds to :c:data:`errno` ``ESRCH``. + Corresponds to :c:data:`errno` :py:data:`~errno.ESRCH`. .. exception:: TimeoutError Raised when a system function timed out at the system level. - Corresponds to :c:data:`errno` ``ETIMEDOUT``. + Corresponds to :c:data:`errno` :py:data:`~errno.ETIMEDOUT`. .. versionadded:: 3.3 All the above :exc:`OSError` subclasses were added. @@ -843,6 +871,127 @@ The following exceptions are used as warning categories; see the .. versionadded:: 3.2 +Exception groups +---------------- + +The following are used when it is necessary to raise multiple unrelated +exceptions. They are part of the exception hierarchy so they can be +handled with :keyword:`except` like all other exceptions. In addition, +they are recognised by :keyword:`except*`, which matches +their subgroups based on the types of the contained exceptions. + +.. exception:: ExceptionGroup(msg, excs) +.. exception:: BaseExceptionGroup(msg, excs) + + Both of these exception types wrap the exceptions in the sequence ``excs``. + The ``msg`` parameter must be a string. The difference between the two + classes is that :exc:`BaseExceptionGroup` extends :exc:`BaseException` and + it can wrap any exception, while :exc:`ExceptionGroup` extends :exc:`Exception` + and it can only wrap subclasses of :exc:`Exception`. This design is so that + ``except Exception`` catches an :exc:`ExceptionGroup` but not + :exc:`BaseExceptionGroup`. + + The :exc:`BaseExceptionGroup` constructor returns an :exc:`ExceptionGroup` + rather than a :exc:`BaseExceptionGroup` if all contained exceptions are + :exc:`Exception` instances, so it can be used to make the selection + automatic. The :exc:`ExceptionGroup` constructor, on the other hand, + raises a :exc:`TypeError` if any contained exception is not an + :exc:`Exception` subclass. + + .. attribute:: message + + The ``msg`` argument to the constructor. This is a read-only attribute. + + .. attribute:: exceptions + + A tuple of the exceptions in the ``excs`` sequence given to the + constructor. This is a read-only attribute. + + .. method:: subgroup(condition) + + Returns an exception group that contains only the exceptions from the + current group that match *condition*, or ``None`` if the result is empty. + + The condition can be either a function that accepts an exception and returns + true for those that should be in the subgroup, or it can be an exception type + or a tuple of exception types, which is used to check for a match using the + same check that is used in an ``except`` clause. + + The nesting structure of the current exception is preserved in the result, + as are the values of its :attr:`message`, :attr:`__traceback__`, + :attr:`__cause__`, :attr:`__context__` and :attr:`__notes__` fields. + Empty nested groups are omitted from the result. + + The condition is checked for all exceptions in the nested exception group, + including the top-level and any nested exception groups. If the condition is + true for such an exception group, it is included in the result in full. + + .. method:: split(condition) + + Like :meth:`subgroup`, but returns the pair ``(match, rest)`` where ``match`` + is ``subgroup(condition)`` and ``rest`` is the remaining non-matching + part. + + .. method:: derive(excs) + + Returns an exception group with the same :attr:`message`, but which + wraps the exceptions in ``excs``. + + This method is used by :meth:`subgroup` and :meth:`split`. A + subclass needs to override it in order to make :meth:`subgroup` + and :meth:`split` return instances of the subclass rather + than :exc:`ExceptionGroup`. + + :meth:`subgroup` and :meth:`split` copy the :attr:`__traceback__`, + :attr:`__cause__`, :attr:`__context__` and :attr:`__notes__` fields from + the original exception group to the one returned by :meth:`derive`, so + these fields do not need to be updated by :meth:`derive`. :: + + >>> class MyGroup(ExceptionGroup): + ... def derive(self, exc): + ... return MyGroup(self.message, exc) + ... + >>> e = MyGroup("eg", [ValueError(1), TypeError(2)]) + >>> e.add_note("a note") + >>> e.__context__ = Exception("context") + >>> e.__cause__ = Exception("cause") + >>> try: + ... raise e + ... except Exception as e: + ... exc = e + ... + >>> match, rest = exc.split(ValueError) + >>> exc, exc.__context__, exc.__cause__, exc.__notes__ + (MyGroup('eg', [ValueError(1), TypeError(2)]), Exception('context'), Exception('cause'), ['a note']) + >>> match, match.__context__, match.__cause__, match.__notes__ + (MyGroup('eg', [ValueError(1)]), Exception('context'), Exception('cause'), ['a note']) + >>> rest, rest.__context__, rest.__cause__, rest.__notes__ + (MyGroup('eg', [TypeError(2)]), Exception('context'), Exception('cause'), ['a note']) + >>> exc.__traceback__ is match.__traceback__ is rest.__traceback__ + True + + + Note that :exc:`BaseExceptionGroup` defines :meth:`__new__`, so + subclasses that need a different constructor signature need to + override that rather than :meth:`__init__`. For example, the following + defines an exception group subclass which accepts an exit_code and + and constructs the group's message from it. :: + + class Errors(ExceptionGroup): + def __new__(cls, errors, exit_code): + self = super().__new__(Errors, f"exit code: {exit_code}", errors) + self.exit_code = exit_code + return self + + def derive(self, excs): + return Errors(excs, self.exit_code) + + Like :exc:`ExceptionGroup`, any subclass of :exc:`BaseExceptionGroup` which + is also a subclass of :exc:`Exception` can only wrap instances of + :exc:`Exception`. + + .. versionadded:: 3.11 + Exception hierarchy ------------------- diff --git a/Doc/library/faulthandler.rst b/Doc/library/faulthandler.rst index be0912376bd..07a74899414 100644 --- a/Doc/library/faulthandler.rst +++ b/Doc/library/faulthandler.rst @@ -166,10 +166,10 @@ handler: .. code-block:: shell-session - $ python3 -c "import ctypes; ctypes.string_at(0)" + $ python -c "import ctypes; ctypes.string_at(0)" Segmentation fault - $ python3 -q -X faulthandler + $ python -q -X faulthandler >>> import ctypes >>> ctypes.string_at(0) Fatal Python error: Segmentation fault diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index 9d8021150c4..997c7ea571f 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -18,6 +18,8 @@ interface to the :c:func:`fcntl` and :c:func:`ioctl` Unix routines. For a complete description of these calls, see :manpage:`fcntl(2)` and :manpage:`ioctl(2)` Unix manual pages. +.. include:: ../includes/wasm-notavail.rst + All functions in this module take a file descriptor *fd* as their first argument. This can be an integer file descriptor, such as returned by ``sys.stdin.fileno()``, or an :class:`io.IOBase` object, such as ``sys.stdin`` @@ -37,13 +39,25 @@ descriptor. On macOS, the fcntl module exposes the ``F_GETPATH`` constant, which obtains the path of a file from a file descriptor. On Linux(>=3.15), the fcntl module exposes the ``F_OFD_GETLK``, ``F_OFD_SETLK`` - and ``F_OFD_SETLKW`` constants, which working with open file description locks. + and ``F_OFD_SETLKW`` constants, which are used when working with open file + description locks. .. versionchanged:: 3.10 On Linux >= 2.6.11, the fcntl module exposes the ``F_GETPIPE_SZ`` and ``F_SETPIPE_SZ`` constants, which allow to check and modify a pipe's size respectively. +.. versionchanged:: 3.11 + On FreeBSD, the fcntl module exposes the ``F_DUP2FD`` and ``F_DUP2FD_CLOEXEC`` + constants, which allow to duplicate a file descriptor, the latter setting + ``FD_CLOEXEC`` flag in addition. + +.. versionchanged:: 3.12 + On Linux >= 4.5, the :mod:`fcntl` module exposes the ``FICLONE`` and + ``FICLONERANGE`` constants, which allow to share some data of one file with + another file by reflinking on some filesystems (e.g., btrfs, OCFS2, and + XFS). This behavior is commonly referred to as "copy-on-write". + The module defines the following functions: diff --git a/Doc/library/fileformats.rst b/Doc/library/fileformats.rst index e9c2e1fbbdf..cab82b30ef4 100644 --- a/Doc/library/fileformats.rst +++ b/Doc/library/fileformats.rst @@ -12,6 +12,6 @@ that aren't markup languages and are not related to e-mail. csv.rst configparser.rst + tomllib.rst netrc.rst - xdrlib.rst plistlib.rst diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst index 2a2c1b3c2b9..4bc868759f2 100644 --- a/Doc/library/fileinput.rst +++ b/Doc/library/fileinput.rst @@ -224,5 +224,5 @@ The two following opening hooks are provided by this module: Added the optional *errors* parameter. .. deprecated:: 3.10 - This function is deprecated since :func:`input` and :class:`FileInput` + This function is deprecated since :func:`fileinput.input` and :class:`FileInput` now have *encoding* and *errors* parameters. diff --git a/Doc/library/fnmatch.rst b/Doc/library/fnmatch.rst index 9163da57c7b..46bf0fc2848 100644 --- a/Doc/library/fnmatch.rst +++ b/Doc/library/fnmatch.rst @@ -48,7 +48,7 @@ patterns. Also note that :func:`functools.lru_cache` with the *maxsize* of 32768 is used to cache the compiled regex patterns in the following functions: :func:`fnmatch`, -:func:`fnmatchcase`, :func:`filter`. +:func:`fnmatchcase`, :func:`.filter`. .. function:: fnmatch(filename, pattern) diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index c893f2d5389..06b0e038c89 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -98,6 +98,14 @@ another rational number, or from a string. :class:`Fraction` implements ``__int__`` now to satisfy ``typing.SupportsInt`` instance checks. + .. versionchanged:: 3.12 + Space is allowed around the slash for string inputs: ``Fraction('2 / 3')``. + + .. versionchanged:: 3.12 + :class:`Fraction` instances now support float-style formatting, with + presentation types ``"e"``, ``"E"``, ``"f"``, ``"F"``, ``"g"``, ``"G"`` + and ``"%""``. + .. attribute:: numerator Numerator of the Fraction in lowest term. @@ -114,10 +122,16 @@ another rational number, or from a string. .. versionadded:: 3.8 - .. method:: from_float(flt) + .. method:: is_integer() - This class method constructs a :class:`Fraction` representing the exact - value of *flt*, which must be a :class:`float`. Beware that + Return ``True`` if the Fraction is an integer. + + .. versionadded:: 3.12 + + .. classmethod:: from_float(flt) + + Alternative constructor which only accepts instances of + :class:`float` or :class:`numbers.Integral`. Beware that ``Fraction.from_float(0.3)`` is not the same value as ``Fraction(3, 10)``. .. note:: @@ -126,10 +140,10 @@ another rational number, or from a string. :class:`Fraction` instance directly from a :class:`float`. - .. method:: from_decimal(dec) + .. classmethod:: from_decimal(dec) - This class method constructs a :class:`Fraction` representing the exact - value of *dec*, which must be a :class:`decimal.Decimal` instance. + Alternative constructor which only accepts instances of + :class:`decimal.Decimal` or :class:`numbers.Integral`. .. note:: @@ -184,6 +198,29 @@ another rational number, or from a string. ``ndigits`` is negative), again rounding half toward even. This method can also be accessed through the :func:`round` function. + .. method:: __format__(format_spec, /) + + Provides support for float-style formatting of :class:`Fraction` + instances via the :meth:`str.format` method, the :func:`format` built-in + function, or :ref:`Formatted string literals `. The + presentation types ``"e"``, ``"E"``, ``"f"``, ``"F"``, ``"g"``, ``"G"`` + and ``"%"`` are supported. For these presentation types, formatting for a + :class:`Fraction` object ``x`` follows the rules outlined for + the :class:`float` type in the :ref:`formatspec` section. + + Here are some examples:: + + >>> from fractions import Fraction + >>> format(Fraction(1, 7), '.40g') + '0.1428571428571428571428571428571428571429' + >>> format(Fraction('1234567.855'), '_.2f') + '1_234_567.86' + >>> f"{Fraction(355, 113):*>20.6e}" + '********3.141593e+00' + >>> old_price, new_price = 499, 672 + >>> "{:.2%} price increase".format(Fraction(new_price, old_price) - 1) + '34.67% price increase' + .. seealso:: diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst index 2f94ac49928..47054812f9f 100644 --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -21,6 +21,8 @@ as mirroring other FTP servers. It is also used by the module The default encoding is UTF-8, following :rfc:`2640`. +.. include:: ../includes/wasm-notavail.rst + Here's a sample session using the :mod:`ftplib` module:: >>> from ftplib import FTP @@ -83,7 +85,8 @@ The module defines the following items: The *encoding* parameter was added, and the default was changed from Latin-1 to UTF-8 to follow :rfc:`2640`. -.. class:: FTP_TLS(host='', user='', passwd='', acct='', keyfile=None, certfile=None, context=None, timeout=None, source_address=None, *, encoding='utf-8') +.. class:: FTP_TLS(host='', user='', passwd='', acct='', *, context=None, + timeout=None, source_address=None, encoding='utf-8') A :class:`FTP` subclass which adds TLS support to FTP as described in :rfc:`4217`. @@ -94,10 +97,6 @@ The module defines the following items: options, certificates and private keys into a single (potentially long-lived) structure. Please read :ref:`ssl-security` for best practices. - *keyfile* and *certfile* are a legacy alternative to *context* -- they - can point to PEM-formatted private key and certificate chain files - (respectively) for the SSL connection. - .. versionadded:: 3.2 .. versionchanged:: 3.3 @@ -109,7 +108,6 @@ The module defines the following items: :data:`ssl.HAS_SNI`). .. deprecated:: 3.6 - *keyfile* and *certfile* are deprecated in favor of *context*. Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let :func:`ssl.create_default_context` select the system's trusted CA @@ -121,6 +119,9 @@ The module defines the following items: The *encoding* parameter was added, and the default was changed from Latin-1 to UTF-8 to follow :rfc:`2640`. + .. versionchanged:: 3.12 + The deprecated *keyfile* and *certfile* parameters have been removed. + Here's a sample session using the :class:`FTP_TLS` class:: >>> ftps = FTP_TLS('ftp.pureftpd.org') diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 0da2619685b..658d6768457 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -82,7 +82,8 @@ are always available. They are listed here in alphabetical order. return True -.. awaitablefunction:: anext(async_iterator[, default]) +.. awaitablefunction:: anext(async_iterator) + anext(async_iterator, default) When awaited, return the next item from the given :term:`asynchronous iterator`, or *default* if given and the iterator is exhausted. @@ -139,7 +140,7 @@ are always available. They are listed here in alphabetical order. See also :func:`format` for more information. -.. class:: bool([x]) +.. class:: bool(x=False) Return a Boolean value, i.e. one of ``True`` or ``False``. *x* is converted using the standard :ref:`truth testing procedure `. If *x* is false @@ -164,13 +165,17 @@ are always available. They are listed here in alphabetical order. :func:`sys.breakpointhook` can be set to some other function and :func:`breakpoint` will automatically call that, allowing you to drop into the debugger of choice. + If :func:`sys.breakpointhook` is not accessible, this function will + raise :exc:`RuntimeError`. .. audit-event:: builtins.breakpoint breakpointhook breakpoint .. versionadded:: 3.7 .. _func-bytearray: -.. class:: bytearray([source[, encoding[, errors]]]) +.. class:: bytearray(source=b'') + bytearray(source, encoding) + bytearray(source, encoding, errors) :noindex: Return a new array of bytes. The :class:`bytearray` class is a mutable @@ -200,7 +205,9 @@ are always available. They are listed here in alphabetical order. .. _func-bytes: -.. class:: bytes([source[, encoding[, errors]]]) +.. class:: bytes(source=b'') + bytes(source, encoding) + bytes(source, encoding, errors) :noindex: Return a new "bytes" object which is an immutable sequence of integers in @@ -248,7 +255,7 @@ are always available. They are listed here in alphabetical order. class C: @classmethod - def f(cls, arg1, arg2, ...): ... + def f(cls, arg1, arg2): ... The ``@classmethod`` form is a function :term:`decorator` -- see :ref:`function` for details. @@ -271,6 +278,11 @@ are always available. They are listed here in alphabetical order. ``__name__``, ``__qualname__``, ``__doc__`` and ``__annotations__``) and have a new ``__wrapped__`` attribute. + .. versionchanged:: 3.11 + Class methods can no longer wrap other :term:`descriptors ` such as + :func:`property`. + + .. function:: compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1) Compile the *source* into a code or AST object. Code objects can be executed @@ -351,7 +363,8 @@ are always available. They are listed here in alphabetical order. support for top-level ``await``, ``async for``, and ``async with``. -.. class:: complex([real[, imag]]) +.. class:: complex(real=0, imag=0) + complex(string) Return a complex number with the value *real* + *imag*\*1j or convert a string or number to a complex number. If the first parameter is a string, it will @@ -390,6 +403,7 @@ are always available. They are listed here in alphabetical order. string. The string must be the name of one of the object's attributes. The function deletes the named attribute, provided the object allows it. For example, ``delattr(x, 'foobar')`` is equivalent to ``del x.foobar``. + *name* need not be a Python identifier (see :func:`setattr`). .. _func-dict: @@ -405,7 +419,8 @@ are always available. They are listed here in alphabetical order. :class:`tuple` classes, as well as the :mod:`collections` module. -.. function:: dir([object]) +.. function:: dir() + dir(object) Without arguments, return the list of names in the current local scope. With an argument, attempt to return a list of valid attributes for that object. @@ -447,6 +462,7 @@ are always available. They are listed here in alphabetical order. >>> class Shape: ... def __dir__(self): ... return ['area', 'perimeter', 'location'] + ... >>> s = Shape() >>> dir(s) ['area', 'location', 'perimeter'] @@ -489,14 +505,15 @@ are always available. They are listed here in alphabetical order. Equivalent to:: - def enumerate(sequence, start=0): + def enumerate(iterable, start=0): n = start - for elem in sequence: + for elem in iterable: yield n, elem n += 1 +.. _func-eval: -.. function:: eval(expression[, globals[, locals]]) +.. function:: eval(expression, globals=None, locals=None) The arguments are a string and optional globals and locals. If provided, *globals* must be a dictionary. If provided, *locals* can be any mapping @@ -547,7 +564,7 @@ are always available. They are listed here in alphabetical order. .. index:: builtin: exec -.. function:: exec(object[, globals[, locals]]) +.. function:: exec(object, globals=None, locals=None, /, *, closure=None) This function supports dynamic execution of Python code. *object* must be either a string or a code object. If it is a string, the string is parsed as @@ -576,6 +593,11 @@ are always available. They are listed here in alphabetical order. builtins are available to the executed code by inserting your own ``__builtins__`` dictionary into *globals* before passing it to :func:`exec`. + The *closure* argument specifies a closure--a tuple of cellvars. + It's only valid when the *object* is a code object containing free variables. + The length of the tuple must exactly match the number of free variables + referenced by the code object. + .. audit-event:: exec code_object exec Raises an :ref:`auditing event ` ``exec`` with the code object @@ -594,6 +616,9 @@ are always available. They are listed here in alphabetical order. Pass an explicit *locals* dictionary if you need to see effects of the code on *locals* after function :func:`exec` returns. + .. versionchanged:: 3.11 + Added the *closure* parameter. + .. function:: filter(function, iterable) @@ -612,7 +637,7 @@ are always available. They are listed here in alphabetical order. elements of *iterable* for which *function* returns false. -.. class:: float([x]) +.. class:: float(x=0.0) .. index:: single: NaN @@ -625,20 +650,23 @@ are always available. They are listed here in alphabetical order. sign may be ``'+'`` or ``'-'``; a ``'+'`` sign has no effect on the value produced. The argument may also be a string representing a NaN (not-a-number), or positive or negative infinity. More precisely, the - input must conform to the following grammar after leading and trailing - whitespace characters are removed: + input must conform to the ``floatvalue`` production rule in the following + grammar, after leading and trailing whitespace characters are removed: .. productionlist:: float sign: "+" | "-" infinity: "Infinity" | "inf" nan: "nan" - numeric_value: `floatnumber` | `infinity` | `nan` - numeric_string: [`sign`] `numeric_value` + digitpart: `digit` (["_"] `digit`)* + number: [`digitpart`] "." `digitpart` | `digitpart` ["."] + exponent: ("e" | "E") ["+" | "-"] `digitpart` + floatnumber: number [`exponent`] + floatvalue: [`sign`] (`floatnumber` | `infinity` | `nan`) - Here ``floatnumber`` is the form of a Python floating-point literal, - described in :ref:`floating`. Case is not significant, so, for example, - "inf", "Inf", "INFINITY", and "iNfINity" are all acceptable spellings for - positive infinity. + Here ``digit`` is a Unicode decimal digit (character in the Unicode general + category ``Nd``). Case is not significant, so, for example, "inf", "Inf", + "INFINITY", and "iNfINity" are all acceptable spellings for positive + infinity. Otherwise, if the argument is an integer or a floating point number, a floating point number with the same value (within Python's floating point @@ -680,7 +708,7 @@ are always available. They are listed here in alphabetical order. single: __format__ single: string; format() (built-in function) -.. function:: format(value[, format_spec]) +.. function:: format(value, format_spec="") Convert a *value* to a "formatted" representation, as controlled by *format_spec*. The interpretation of *format_spec* will depend on the type @@ -703,7 +731,7 @@ are always available. They are listed here in alphabetical order. .. _func-frozenset: -.. class:: frozenset([iterable]) +.. class:: frozenset(iterable=set()) :noindex: Return a new :class:`frozenset` object, optionally with elements taken from @@ -715,13 +743,15 @@ are always available. They are listed here in alphabetical order. module. -.. function:: getattr(object, name[, default]) +.. function:: getattr(object, name) + getattr(object, name, default) Return the value of the named attribute of *object*. *name* must be a string. If the string is the name of one of the object's attributes, the result is the value of that attribute. For example, ``getattr(x, 'foobar')`` is equivalent to ``x.foobar``. If the named attribute does not exist, *default* is returned if provided, otherwise :exc:`AttributeError` is raised. + *name* need not be a Python identifier (see :func:`setattr`). .. note:: @@ -733,9 +763,9 @@ are always available. They are listed here in alphabetical order. .. function:: globals() - Return a dictionary representing the current global symbol table. This is always - the dictionary of the current module (inside a function or method, this is the - module where it is defined, not the module from which it is called). + Return the dictionary implementing the current module namespace. For code within + functions, this is set when the function is defined and remains the same + regardless of where the function is called. .. function:: hasattr(object, name) @@ -759,7 +789,8 @@ are always available. They are listed here in alphabetical order. truncates the return value based on the bit width of the host machine. See :meth:`__hash__` for details. -.. function:: help([object]) +.. function:: help() + help(request) Invoke the built-in help system. (This function is intended for interactive use.) If no argument is given, the interactive help system starts on the @@ -824,7 +855,8 @@ are always available. They are listed here in alphabetical order. .. audit-event:: builtins.id id id -.. function:: input([prompt]) +.. function:: input() + input(prompt) If the *prompt* argument is present, it is written to standard output without a trailing newline. The function then reads a line from input, converts it @@ -846,11 +878,11 @@ are always available. They are listed here in alphabetical order. .. audit-event:: builtins.input/result result input - Raises an auditing event ``builtins.input/result`` with the result after - successfully reading input. + Raises an :ref:`auditing event ` ``builtins.input/result`` + with the result after successfully reading input. -.. class:: int([x]) +.. class:: int(x=0) int(x, base=10) Return an integer object constructed from a number or string *x*, or return @@ -861,17 +893,21 @@ are always available. They are listed here in alphabetical order. For floating point numbers, this truncates towards zero. If *x* is not a number or if *base* is given, then *x* must be a string, - :class:`bytes`, or :class:`bytearray` instance representing an :ref:`integer - literal ` in radix *base*. Optionally, the literal can be - preceded by ``+`` or ``-`` (with no space in between) and surrounded by - whitespace. A base-n literal consists of the digits 0 to n-1, with ``a`` - to ``z`` (or ``A`` to ``Z``) having - values 10 to 35. The default *base* is 10. The allowed values are 0 and 2--36. - Base-2, -8, and -16 literals can be optionally prefixed with ``0b``/``0B``, - ``0o``/``0O``, or ``0x``/``0X``, as with integer literals in code. Base 0 - means to interpret exactly as a code literal, so that the actual base is 2, - 8, 10, or 16, and so that ``int('010', 0)`` is not legal, while - ``int('010')`` is, as well as ``int('010', 8)``. + :class:`bytes`, or :class:`bytearray` instance representing an integer + in radix *base*. Optionally, the string can be preceded by ``+`` or ``-`` + (with no space in between), have leading zeros, be surrounded by whitespace, + and have single underscores interspersed between digits. + + A base-n integer string contains digits, each representing a value from 0 to + n-1. The values 0--9 can be represented by any Unicode decimal digit. The + values 10--35 can be represented by ``a`` to ``z`` (or ``A`` to ``Z``). The + default *base* is 10. The allowed bases are 0 and 2--36. Base-2, -8, and -16 + strings can be optionally prefixed with ``0b``/``0B``, ``0o``/``0O``, or + ``0x``/``0X``, as with integer literals in code. For base 0, the string is + interpreted in a similar way to an :ref:`integer literal in code `, + in that the actual base is 2, 8, 10, or 16 as determined by the prefix. Base + 0 also disallows leading zeros: ``int('010', 0)`` is not legal, while + ``int('010')`` and ``int('010', 8)`` are. The integer type is described in :ref:`typesnumeric`. @@ -891,6 +927,16 @@ are always available. They are listed here in alphabetical order. .. versionchanged:: 3.8 Falls back to :meth:`__index__` if :meth:`__int__` is not defined. + .. versionchanged:: 3.11 + The delegation to :meth:`__trunc__` is deprecated. + + .. versionchanged:: 3.11 + :class:`int` string inputs and string representations can be limited to + help avoid denial of service attacks. A :exc:`ValueError` is raised when + the limit is exceeded while converting a string *x* to an :class:`int` or + when converting an :class:`int` into a string would exceed the limit. + See the :ref:`integer string conversion length limitation + ` documentation. .. function:: isinstance(object, classinfo) @@ -902,7 +948,8 @@ are always available. They are listed here in alphabetical order. tuples) or a :ref:`types-union` of multiple types, return ``True`` if *object* is an instance of any of the types. If *classinfo* is not a type or tuple of types and such tuples, - a :exc:`TypeError` exception is raised. + a :exc:`TypeError` exception is raised. :exc:`TypeError` may not be + raised for an invalid type if an earlier check succeeds. .. versionchanged:: 3.10 *classinfo* can be a :ref:`types-union`. @@ -913,7 +960,8 @@ are always available. They are listed here in alphabetical order. Return ``True`` if *class* is a subclass (direct, indirect, or :term:`virtual `) of *classinfo*. A class is considered a subclass of itself. *classinfo* may be a tuple of class - objects or a :ref:`types-union`, in which case return ``True`` if *class* is a + objects (or recursively, other such tuples) + or a :ref:`types-union`, in which case return ``True`` if *class* is a subclass of any entry in *classinfo*. In any other case, a :exc:`TypeError` exception is raised. @@ -921,7 +969,8 @@ are always available. They are listed here in alphabetical order. *classinfo* can be a :ref:`types-union`. -.. function:: iter(object[, sentinel]) +.. function:: iter(object) + iter(object, sentinel) Return an :term:`iterator` object. The first argument is interpreted very differently depending on the presence of the second argument. Without a @@ -961,7 +1010,8 @@ are always available. They are listed here in alphabetical order. .. _func-list: -.. class:: list([iterable]) +.. class:: list() + list(iterable) :noindex: Rather than being a function, :class:`list` is actually a mutable @@ -979,18 +1029,19 @@ are always available. They are listed here in alphabetical order. The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter. -.. function:: map(function, iterable, ...) +.. function:: map(function, iterable, *iterables) Return an iterator that applies *function* to every item of *iterable*, - yielding the results. If additional *iterable* arguments are passed, + yielding the results. If additional *iterables* arguments are passed, *function* must take that many arguments and is applied to the items from all iterables in parallel. With multiple iterables, the iterator stops when the shortest iterable is exhausted. For cases where the function inputs are already arranged into argument tuples, see :func:`itertools.starmap`\. -.. function:: max(iterable, *[, key, default]) - max(arg1, arg2, *args[, key]) +.. function:: max(iterable, *, key=None) + max(iterable, *, default, key=None) + max(arg1, arg2, *args, key=None) Return the largest item in an iterable or the largest of two or more arguments. @@ -1026,8 +1077,9 @@ are always available. They are listed here in alphabetical order. :ref:`typememoryview` for more information. -.. function:: min(iterable, *[, key, default]) - min(arg1, arg2, *args[, key]) +.. function:: min(iterable, *, key=None) + min(iterable, *, default, key=None) + min(arg1, arg2, *args, key=None) Return the smallest item in an iterable or the smallest of two or more arguments. @@ -1055,7 +1107,8 @@ are always available. They are listed here in alphabetical order. The *key* can be ``None``. -.. function:: next(iterator[, default]) +.. function:: next(iterator) + next(iterator, default) Retrieve the next item from the :term:`iterator` by calling its :meth:`~iterator.__next__` method. If *default* is given, it is returned @@ -1120,8 +1173,8 @@ are always available. They are listed here in alphabetical order. (which on *some* Unix systems, means that *all* writes append to the end of the file regardless of the current seek position). In text mode, if *encoding* is not specified the encoding used is platform-dependent: - ``locale.getpreferredencoding(False)`` is called to get the current locale - encoding. (For reading and writing raw bytes use binary mode and leave + :func:`locale.getencoding()` is called to get the current locale encoding. + (For reading and writing raw bytes use binary mode and leave *encoding* unspecified.) The available modes are: .. _filemodes: @@ -1162,7 +1215,11 @@ are always available. They are listed here in alphabetical order. *buffering* is an optional integer used to set the buffering policy. Pass 0 to switch buffering off (only allowed in binary mode), 1 to select line buffering (only usable in text mode), and an integer > 1 to indicate the size - in bytes of a fixed-size chunk buffer. When no *buffering* argument is + in bytes of a fixed-size chunk buffer. Note that specifying a buffer size this + way applies for binary buffered I/O, but ``TextIOWrapper`` (i.e., files opened + with ``mode='r+'``) would have another buffering. To disable buffering in + ``TextIOWrapper``, consider using the ``write_through`` flag for + :func:`io.TextIOWrapper.reconfigure`. When no *buffering* argument is given, the default buffering policy works as follows: * Binary files are buffered in fixed-size chunks; the size of the buffer is @@ -1176,10 +1233,9 @@ are always available. They are listed here in alphabetical order. *encoding* is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is platform - dependent (whatever :func:`locale.getpreferredencoding` returns), but any - :term:`text encoding` supported by Python - can be used. See the :mod:`codecs` module for - the list of supported encodings. + dependent (whatever :func:`locale.getencoding` returns), but any + :term:`text encoding` supported by Python can be used. + See the :mod:`codecs` module for the list of supported encodings. *errors* is an optional string that specifies how encoding and decoding errors are to be handled—this cannot be used in binary mode. @@ -1221,8 +1277,8 @@ are always available. They are listed here in alphabetical order. .. _open-newline-parameter: - *newline* controls how :term:`universal newlines` mode works (it only - applies to text mode). It can be ``None``, ``''``, ``'\n'``, ``'\r'``, and + *newline* determines how to parse newline characters from the stream. + It can be ``None``, ``''``, ``'\n'``, ``'\r'``, and ``'\r\n'``. It works as follows: * When reading input from the stream, if *newline* is ``None``, universal @@ -1331,7 +1387,7 @@ are always available. They are listed here in alphabetical order. returns ``8364``. This is the inverse of :func:`chr`. -.. function:: pow(base, exp[, mod]) +.. function:: pow(base, exp, mod=None) Return *base* to the power *exp*; if *mod* is present, return *base* to the power *exp*, modulo *mod* (computed more efficiently than @@ -1371,7 +1427,7 @@ are always available. They are listed here in alphabetical order. supported. -.. function:: print(*objects, sep=' ', end='\\n', file=sys.stdout, flush=False) +.. function:: print(*objects, sep=' ', end='\n', file=None, flush=False) Print *objects* to the text stream *file*, separated by *sep* and followed by *end*. *sep*, *end*, *file*, and *flush*, if present, must be given as keyword @@ -1475,7 +1531,7 @@ are always available. They are listed here in alphabetical order. .. _func-range: .. class:: range(stop) - range(start, stop[, step]) + range(start, stop, step=1) :noindex: Rather than being a function, :class:`range` is actually an immutable @@ -1491,6 +1547,8 @@ are always available. They are listed here in alphabetical order. of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a :meth:`__repr__` method. + If :func:`sys.displayhook` is not accessible, this function will raise + :exc:`RuntimeError`. .. function:: reversed(seq) @@ -1501,7 +1559,7 @@ are always available. They are listed here in alphabetical order. arguments starting at ``0``). -.. function:: round(number[, ndigits]) +.. function:: round(number, ndigits=None) Return *number* rounded to *ndigits* precision after the decimal point. If *ndigits* is omitted or is ``None``, it returns the @@ -1529,7 +1587,8 @@ are always available. They are listed here in alphabetical order. .. _func-set: -.. class:: set([iterable]) +.. class:: set() + set(iterable) :noindex: Return a new :class:`set` object, optionally with elements taken from @@ -1549,6 +1608,12 @@ are always available. They are listed here in alphabetical order. object allows it. For example, ``setattr(x, 'foobar', 123)`` is equivalent to ``x.foobar = 123``. + *name* need not be a Python identifier as defined in :ref:`identifiers` + unless the object chooses to enforce that, for example in a custom + :meth:`~object.__getattribute__` or via :attr:`~object.__slots__`. + An attribute whose name is not an identifier will not be accessible using + the dot notation, but is accessible through :func:`getattr` etc.. + .. note:: Since :ref:`private name mangling ` happens at @@ -1558,7 +1623,7 @@ are always available. They are listed here in alphabetical order. .. class:: slice(stop) - slice(start, stop[, step]) + slice(start, stop, step=1) Return a :term:`slice` object representing the set of indices specified by ``range(start, stop, step)``. The *start* and *step* arguments default to @@ -1571,7 +1636,7 @@ are always available. They are listed here in alphabetical order. :func:`itertools.islice` for an alternate version that returns an iterator. -.. function:: sorted(iterable, *, key=None, reverse=False) +.. function:: sorted(iterable, /, *, key=None, reverse=False) Return a new sorted list from the items in *iterable*. @@ -1675,21 +1740,26 @@ are always available. They are listed here in alphabetical order. .. versionchanged:: 3.8 The *start* parameter can be specified as a keyword argument. -.. class:: super([type[, object-or-type]]) + .. versionchanged:: 3.12 Summation of floats switched to an algorithm + that gives higher accuracy on most builds. + + +.. class:: super() + super(type, object_or_type=None) Return a proxy object that delegates method calls to a parent or sibling class of *type*. This is useful for accessing inherited methods that have been overridden in a class. - The *object-or-type* determines the :term:`method resolution order` + The *object_or_type* determines the :term:`method resolution order` to be searched. The search starts from the class right after the *type*. - For example, if :attr:`~class.__mro__` of *object-or-type* is + For example, if :attr:`~class.__mro__` of *object_or_type* is ``D -> B -> C -> A -> object`` and the value of *type* is ``B``, then :func:`super` searches ``C -> A -> object``. - The :attr:`~class.__mro__` attribute of the *object-or-type* lists the method + The :attr:`~class.__mro__` attribute of the *object_or_type* lists the method resolution search order used by both :func:`getattr` and :func:`super`. The attribute is dynamic and can change whenever the inheritance hierarchy is updated. @@ -1745,7 +1815,8 @@ are always available. They are listed here in alphabetical order. .. _func-tuple: -.. class:: tuple([iterable]) +.. class:: tuple() + tuple(iterable) :noindex: Rather than being a function, :class:`tuple` is actually an immutable @@ -1793,7 +1864,8 @@ are always available. They are listed here in alphabetical order. Subclasses of :class:`type` which don't override ``type.__new__`` may no longer use the one-argument form to get the type of an object. -.. function:: vars([object]) +.. function:: vars() + vars(object) Return the :attr:`~object.__dict__` attribute for a module, class, instance, or any other object with a :attr:`~object.__dict__` attribute. @@ -1855,14 +1927,24 @@ are always available. They are listed here in alphabetical order. >>> list(zip(('a', 'b', 'c'), (1, 2, 3), strict=True)) [('a', 1), ('b', 2), ('c', 3)] - Unlike the default behavior, it checks that the lengths of iterables are - identical, raising a :exc:`ValueError` if they aren't: + Unlike the default behavior, it raises a :exc:`ValueError` if one iterable + is exhausted before the others: - >>> list(zip(range(3), ['fee', 'fi', 'fo', 'fum'], strict=True)) + >>> for item in zip(range(3), ['fee', 'fi', 'fo', 'fum'], strict=True): # doctest: +SKIP + ... print(item) + ... + (0, 'fee') + (1, 'fi') + (2, 'fo') Traceback (most recent call last): ... ValueError: zip() argument 2 is longer than argument 1 + .. + This doctest is disabled because doctest does not support capturing + output and exceptions in the same code unit. + https://github.com/python/cpython/issues/65382 + Without the ``strict=True`` argument, any bug that results in iterables of different lengths will be silenced, possibly manifesting as a hard-to-find bug in another part of the program. diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index c78818bfab1..2f0a9bd8be8 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -49,6 +49,9 @@ The :mod:`functools` module defines the following functions: >>> factorial(12) # makes two new recursive calls, the other 10 are cached 479001600 + The cache is threadsafe so the wrapped function can be used in multiple + threads. + .. versionadded:: 3.9 @@ -119,7 +122,7 @@ The :mod:`functools` module defines the following functions: tool for programs being converted from Python 2 which supported the use of comparison functions. - A comparison function is any callable that accept two arguments, compares them, + A comparison function is any callable that accepts two arguments, compares them, and returns a negative number for less-than, zero for equality, or a positive number for greater-than. A key function is a callable that accepts one argument and returns another value to be used as the sort key. @@ -140,11 +143,14 @@ The :mod:`functools` module defines the following functions: *maxsize* most recent calls. It can save time when an expensive or I/O bound function is periodically called with the same arguments. + The cache is threadsafe so the wrapped function can be used in multiple + threads. + Since a dictionary is used to cache results, the positional and keyword arguments to the function must be hashable. Distinct argument patterns may be considered to be distinct calls with - separate cache entries. For example, `f(a=1, b=2)` and `f(b=2, a=1)` + separate cache entries. For example, ``f(a=1, b=2)`` and ``f(b=2, a=1)`` differ in their keyword argument order and may have two separate cache entries. @@ -191,6 +197,9 @@ The :mod:`functools` module defines the following functions: The cache keeps references to the arguments and return values until they age out of the cache or until the cache is cleared. + If a method is cached, the ``self`` instance argument is included in the + cache. See :ref:`faq-cache-method-calls` + An `LRU (least recently used) cache `_ works best when the most recent calls are the best predictors of upcoming @@ -208,7 +217,7 @@ The :mod:`functools` module defines the following functions: @lru_cache(maxsize=32) def get_pep(num): 'Retrieve text of a Python Enhancement Proposal' - resource = 'https://www.python.org/dev/peps/pep-%04d/' % num + resource = 'https://peps.python.org/pep-%04d/' % num try: with urllib.request.urlopen(resource) as s: return s.read() @@ -436,6 +445,23 @@ The :mod:`functools` module defines the following functions: ... for i, elem in enumerate(arg): ... print(i, elem) + :data:`types.UnionType` and :data:`typing.Union` can also be used:: + + >>> @fun.register + ... def _(arg: int | float, verbose=False): + ... if verbose: + ... print("Strength in numbers, eh?", end=" ") + ... print(arg) + ... + >>> from typing import Union + >>> @fun.register + ... def _(arg: Union[list, set], verbose=False): + ... if verbose: + ... print("Enumerate this:") + ... for i, elem in enumerate(arg): + ... print(i, elem) + ... + For code which doesn't use type annotations, the appropriate type argument can be passed explicitly to the decorator itself:: @@ -535,6 +561,10 @@ The :mod:`functools` module defines the following functions: .. versionchanged:: 3.7 The :func:`register` attribute now supports using type annotations. + .. versionchanged:: 3.11 + The :func:`register` attribute now supports :data:`types.UnionType` + and :data:`typing.Union` as type annotations. + .. class:: singledispatchmethod(func) diff --git a/Doc/library/getpass.rst b/Doc/library/getpass.rst index 82b11919a3d..d5bbe67fb30 100644 --- a/Doc/library/getpass.rst +++ b/Doc/library/getpass.rst @@ -12,8 +12,9 @@ -------------- -The :mod:`getpass` module provides two functions: +.. include:: ../includes/wasm-notavail.rst +The :mod:`getpass` module provides two functions: .. function:: getpass(prompt='Password: ', stream=None) diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index 62450195242..747f8703b75 100644 --- a/Doc/library/gettext.rst +++ b/Doc/library/gettext.rst @@ -445,7 +445,7 @@ There are a few tools to extract the strings meant for translation. The original GNU :program:`gettext` only supported C or C++ source code but its extended version :program:`xgettext` scans code written in a number of languages, including Python, to find strings marked as -translatable. `Babel `__ is a Python +translatable. `Babel `__ is a Python internationalization library that includes a :file:`pybabel` script to extract and compile message catalogs. François Pinard's program called :program:`xpot` does a similar job and is available as part of diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst index 215f60d328c..0e4cfe7ebed 100644 --- a/Doc/library/glob.rst +++ b/Doc/library/glob.rst @@ -23,8 +23,11 @@ according to the rules used by the Unix shell, although results are returned in arbitrary order. No tilde expansion is done, but ``*``, ``?``, and character ranges expressed with ``[]`` will be correctly matched. This is done by using the :func:`os.scandir` and :func:`fnmatch.fnmatch` functions in concert, and -not by actually invoking a subshell. Note that unlike :func:`fnmatch.fnmatch`, -:mod:`glob` treats filenames beginning with a dot (``.``) as special cases. +not by actually invoking a subshell. + +Note that files beginning with a dot (``.``) can only be matched by +patterns that also start with a dot, +unlike :func:`fnmatch.fnmatch` or :func:`pathlib.Path.glob`. (For tilde and shell variable expansion, use :func:`os.path.expanduser` and :func:`os.path.expandvars`.) @@ -36,16 +39,17 @@ For example, ``'[?]'`` matches the character ``'?'``. The :mod:`pathlib` module offers high-level path objects. -.. function:: glob(pathname, *, root_dir=None, dir_fd=None, recursive=False) +.. function:: glob(pathname, *, root_dir=None, dir_fd=None, recursive=False, \ + include_hidden=False) - Return a possibly-empty list of path names that match *pathname*, which must be + Return a possibly empty list of path names that match *pathname*, which must be a string containing a path specification. *pathname* can be either absolute (like :file:`/usr/src/Python-1.5/Makefile`) or relative (like :file:`../../Tools/\*/\*.gif`), and can contain shell-style wildcards. Broken symlinks are included in the results (as in the shell). Whether or not the results are sorted depends on the file system. If a file that satisfies conditions is removed or added during the call of this function, whether - a path name for that file be included is unspecified. + a path name for that file will be included is unspecified. If *root_dir* is not ``None``, it should be a :term:`path-like object` specifying the root directory for searching. It has the same effect on @@ -64,6 +68,8 @@ For example, ``'[?]'`` matches the character ``'?'``. pattern is followed by an :data:`os.sep` or :data:`os.altsep` then files will not match. + If *include_hidden* is true, "``**``" pattern will match hidden directories. + .. audit-event:: glob.glob pathname,recursive glob.glob .. audit-event:: glob.glob/2 pathname,recursive,root_dir,dir_fd glob.glob @@ -77,8 +83,12 @@ For example, ``'[?]'`` matches the character ``'?'``. .. versionchanged:: 3.10 Added the *root_dir* and *dir_fd* parameters. + .. versionchanged:: 3.11 + Added the *include_hidden* parameter. -.. function:: iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False) + +.. function:: iglob(pathname, *, root_dir=None, dir_fd=None, recursive=False, \ + include_hidden=False) Return an :term:`iterator` which yields the same values as :func:`glob` without actually storing them all simultaneously. @@ -92,6 +102,9 @@ For example, ``'[?]'`` matches the character ``'?'``. .. versionchanged:: 3.10 Added the *root_dir* and *dir_fd* parameters. + .. versionchanged:: 3.11 + Added the *include_hidden* parameter. + .. function:: escape(pathname) diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst index 74de3f95200..14af744e3ae 100644 --- a/Doc/library/grp.rst +++ b/Doc/library/grp.rst @@ -10,9 +10,11 @@ This module provides access to the Unix group database. It is available on all Unix versions. +.. include:: ../includes/wasm-notavail.rst + Group database entries are reported as a tuple-like object, whose attributes correspond to the members of the ``group`` structure (Attribute field below, see -````): +````): +-------+-----------+---------------------------------+ | Index | Attribute | Meaning | @@ -38,14 +40,13 @@ accessible via :func:`getgrnam` or :func:`getgrgid`.) It defines the following items: -.. function:: getgrgid(gid) +.. function:: getgrgid(id) Return the group database entry for the given numeric group ID. :exc:`KeyError` is raised if the entry asked for cannot be found. - .. deprecated:: 3.6 - Since Python 3.6 the support of non-integer arguments like floats or - strings in :func:`getgrgid` is deprecated. + .. versionchanged:: 3.10 + :exc:`TypeError` is raised for non-integer arguments like floats or strings. .. function:: getgrnam(name) diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst index 8cea2649ee6..1a2582d6a90 100644 --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -165,6 +165,10 @@ The module defines the following items: .. versionchanged:: 3.6 Accepts a :term:`path-like object`. + .. versionchanged:: 3.12 + Remove the ``filename`` attribute, use the :attr:`~GzipFile.name` + attribute instead. + .. deprecated:: 3.9 Opening :class:`GzipFile` for writing without specifying the *mode* argument is deprecated. diff --git a/Doc/library/hashlib-blake2-tree.png b/Doc/library/hashlib-blake2-tree.png index 73e849444ed..faef21b55f9 100644 Binary files a/Doc/library/hashlib-blake2-tree.png and b/Doc/library/hashlib-blake2-tree.png differ diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst index 0c3bd7b5ac2..f8d10c0c295 100644 --- a/Doc/library/hashlib.rst +++ b/Doc/library/hashlib.rst @@ -91,8 +91,8 @@ library that Python uses on your platform. On most platforms the Hashlib now uses SHA3 and SHAKE from OpenSSL 1.1.1 and newer. -For example, to obtain the digest of the byte string ``b'Nobody inspects the -spammish repetition'``:: +For example, to obtain the digest of the byte string ``b"Nobody inspects the +spammish repetition"``:: >>> import hashlib >>> m = hashlib.sha256() @@ -100,15 +100,13 @@ spammish repetition'``:: >>> m.update(b" the spammish repetition") >>> m.digest() b'\x03\x1e\xdd}Ae\x15\x93\xc5\xfe\\\x00o\xa5u+7\xfd\xdf\xf7\xbcN\x84:\xa6\xaf\x0c\x95\x0fK\x94\x06' - >>> m.digest_size - 32 - >>> m.block_size - 64 + >>> m.hexdigest() + '031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406' More condensed: - >>> hashlib.sha224(b"Nobody inspects the spammish repetition").hexdigest() - 'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2' + >>> hashlib.sha256(b"Nobody inspects the spammish repetition").hexdigest() + '031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406' .. function:: new(name[, data], *, usedforsecurity=True) @@ -120,10 +118,10 @@ More condensed: Using :func:`new` with an algorithm provided by OpenSSL: - >>> h = hashlib.new('sha512_256') + >>> h = hashlib.new('sha256') >>> h.update(b"Nobody inspects the spammish repetition") >>> h.hexdigest() - '19197dc4d03829df858011c6c87600f994a858103bbc19005f20987aa19a97e2' + '031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406' Hashlib provides the following constant attributes: @@ -228,6 +226,49 @@ by the SHAKE algorithm. exchange the value safely in email or other non-binary environments. +File hashing +------------ + +The hashlib module provides a helper function for efficient hashing of +a file or file-like object. + +.. function:: file_digest(fileobj, digest, /) + + Return a digest object that has been updated with contents of file object. + + *fileobj* must be a file-like object opened for reading in binary mode. + It accepts file objects from builtin :func:`open`, :class:`~io.BytesIO` + instances, SocketIO objects from :meth:`socket.socket.makefile`, and + similar. The function may bypass Python's I/O and use the file descriptor + from :meth:`~io.IOBase.fileno` directly. *fileobj* must be assumed to be + in an unknown state after this function returns or raises. It is up to + the caller to close *fileobj*. + + *digest* must either be a hash algorithm name as a *str*, a hash + constructor, or a callable that returns a hash object. + + Example: + + >>> import io, hashlib, hmac + >>> with open(hashlib.__file__, "rb") as f: + ... digest = hashlib.file_digest(f, "sha256") + ... + >>> digest.hexdigest() # doctest: +ELLIPSIS + '...' + + >>> buf = io.BytesIO(b"somedata") + >>> mac1 = hmac.HMAC(b"key", digestmod=hashlib.sha512) + >>> digest = hashlib.file_digest(buf, lambda: mac1) + + >>> digest is mac1 + True + >>> mac2 = hmac.HMAC(b"key", b"somedata", digestmod=hashlib.sha512) + >>> mac1.digest() == mac2.digest() + True + + .. versionadded:: 3.11 + + Key derivation -------------- @@ -249,30 +290,27 @@ include a `salt `_. a proper source, e.g. :func:`os.urandom`. The number of *iterations* should be chosen based on the hash algorithm and - computing power. As of 2013, at least 100,000 iterations of SHA-256 are - suggested. + computing power. As of 2022, hundreds of thousands of iterations of SHA-256 + are suggested. For rationale as to why and how to choose what is best for + your application, read *Appendix A.2.2* of NIST-SP-800-132_. The answers + on the `stackexchange pbkdf2 iterations question`_ explain in detail. *dklen* is the length of the derived key. If *dklen* is ``None`` then the digest size of the hash algorithm *hash_name* is used, e.g. 64 for SHA-512. - >>> import hashlib - >>> dk = hashlib.pbkdf2_hmac('sha256', b'password', b'salt', 100000) + >>> from hashlib import pbkdf2_hmac + >>> our_app_iters = 500_000 # Application specific, read above. + >>> dk = pbkdf2_hmac('sha256', b'password', b'bad salt' * 2, our_app_iters) >>> dk.hex() - '0394a2ede332c9a13eb82e9b24631604c31df978b4e2f0fbd2c549944f9d79a5' + '15530bba69924174860db778f2c6f8104d3aaf9d26241840c8c4a641c8d000a9' + + Function only available when Python is compiled with OpenSSL. .. versionadded:: 3.4 - .. note:: - - A fast implementation of *pbkdf2_hmac* is available with OpenSSL. The - Python implementation uses an inline version of :mod:`hmac`. It is about - three times slower and doesn't release the GIL. - - .. deprecated:: 3.10 - - Slow Python implementation of *pbkdf2_hmac* is deprecated. In the - future the function will only be available when Python is compiled - with OpenSSL. + .. versionchanged:: 3.12 + Function now only available when Python is built with OpenSSL. The slow + pure Python implementation has been removed. .. function:: scrypt(password, *, salt, n, r, p, maxmem=0, dklen=64) @@ -388,7 +426,7 @@ Constructor functions also accept the following tree hashing parameters: BLAKE2s, 0 in sequential mode). * *last_node*: boolean indicating whether the processed node is the last - one (`False` for sequential mode). + one (``False`` for sequential mode). .. figure:: hashlib-blake2-tree.png :alt: Explanation of tree mode parameters. @@ -459,6 +497,7 @@ update the hash: >>> h = blake2b() >>> for item in items: ... h.update(item) + ... >>> h.hexdigest() '6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183' @@ -624,7 +663,7 @@ function: hash function used in the protocol summarily stops this type of attack. (`The Skein Hash Function Family - `_, + `_, p. 21) BLAKE2 can be personalized by passing bytes to the *person* argument:: @@ -731,7 +770,8 @@ Domain Dedication 1.0 Universal: .. _SHA-3: https://en.wikipedia.org/wiki/NIST_hash_function_competition .. _ChaCha: https://cr.yp.to/chacha.html .. _pyblake2: https://pythonhosted.org/pyblake2/ - +.. _NIST-SP-800-132: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf +.. _stackexchange pbkdf2 iterations question: https://security.stackexchange.com/questions/3959/recommended-of-iterations-when-using-pbkdf2-sha256/ .. seealso:: @@ -754,3 +794,6 @@ Domain Dedication 1.0 Universal: https://www.ietf.org/rfc/rfc8018.txt PKCS #5: Password-Based Cryptography Specification Version 2.1 + + https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf + NIST Recommendation for Password-Based Key Derivation. diff --git a/Doc/library/hmac.rst b/Doc/library/hmac.rst index 6f1b59b57ce..b2ca0455d37 100644 --- a/Doc/library/hmac.rst +++ b/Doc/library/hmac.rst @@ -69,7 +69,7 @@ An HMAC object has the following methods: .. warning:: - When comparing the output of :meth:`digest` to an externally-supplied + When comparing the output of :meth:`digest` to an externally supplied digest during a verification routine, it is recommended to use the :func:`compare_digest` function instead of the ``==`` operator to reduce the vulnerability to timing attacks. @@ -83,7 +83,7 @@ An HMAC object has the following methods: .. warning:: - When comparing the output of :meth:`hexdigest` to an externally-supplied + When comparing the output of :meth:`hexdigest` to an externally supplied digest during a verification routine, it is recommended to use the :func:`compare_digest` function instead of the ``==`` operator to reduce the vulnerability to timing attacks. diff --git a/Doc/library/html.entities.rst b/Doc/library/html.entities.rst index 7d836fe7380..10529561a92 100644 --- a/Doc/library/html.entities.rst +++ b/Doc/library/html.entities.rst @@ -34,14 +34,14 @@ This module defines four dictionaries, :data:`html5`, .. data:: name2codepoint - A dictionary that maps HTML entity names to the Unicode code points. + A dictionary that maps HTML4 entity names to the Unicode code points. .. data:: codepoint2name - A dictionary that maps Unicode code points to HTML entity names. + A dictionary that maps Unicode code points to HTML4 entity names. .. rubric:: Footnotes -.. [#] See https://html.spec.whatwg.org/multipage/syntax.html#named-character-references +.. [#] See https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references diff --git a/Doc/library/html.parser.rst b/Doc/library/html.parser.rst index ac844a683bf..03aff25ce61 100644 --- a/Doc/library/html.parser.rst +++ b/Doc/library/html.parser.rst @@ -126,7 +126,7 @@ implementations do nothing (except for :meth:`~HTMLParser.handle_startendtag`): .. method:: HTMLParser.handle_starttag(tag, attrs) - This method is called to handle the start of a tag (e.g. ``
    ``). + This method is called to handle the start tag of an element (e.g. ``
    ``). The *tag* argument is the name of the tag converted to lower case. The *attrs* argument is a list of ``(name, value)`` pairs containing the attributes found diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst index e605f7b8b14..48582219695 100644 --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -14,13 +14,13 @@ -------------- -This module defines classes which implement the client side of the HTTP and +This module defines classes that implement the client side of the HTTP and HTTPS protocols. It is normally not used directly --- the module :mod:`urllib.request` uses it to handle URLs that use HTTP and HTTPS. .. seealso:: - The `Requests package `_ + The `Requests package `_ is recommended for a higher-level HTTP client interface. .. note:: @@ -28,6 +28,8 @@ HTTPS protocols. It is normally not used directly --- the module HTTPS support is only available if Python was compiled with SSL support (through the :mod:`ssl` module). +.. include:: ../includes/wasm-notavail.rst + The module provides the following classes: @@ -35,7 +37,7 @@ The module provides the following classes: blocksize=8192) An :class:`HTTPConnection` instance represents one transaction with an HTTP - server. It should be instantiated passing it a host and optional port + server. It should be instantiated by passing it a host and optional port number. If no port number is passed, the port is extracted from the host string if it has the form ``host:port``, else the default HTTP port (80) is used. If the optional *timeout* parameter is given, blocking @@ -59,16 +61,15 @@ The module provides the following classes: .. versionchanged:: 3.4 The *strict* parameter was removed. HTTP 0.9-style "Simple Responses" are - not longer supported. + no longer supported. .. versionchanged:: 3.7 *blocksize* parameter was added. -.. class:: HTTPSConnection(host, port=None, key_file=None, \ - cert_file=None[, timeout], \ - source_address=None, *, context=None, \ - check_hostname=None, blocksize=8192) +.. class:: HTTPSConnection(host, port=None, *[, timeout], \ + source_address=None, context=None, \ + blocksize=8192) A subclass of :class:`HTTPConnection` that uses SSL for communication with secure servers. Default port is ``443``. If *context* is specified, it @@ -94,6 +95,16 @@ The module provides the following classes: :func:`ssl._create_unverified_context` can be passed to the *context* parameter. + .. deprecated:: 3.6 + *key_file* and *cert_file* are deprecated in favor of *context*. + Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let + :func:`ssl.create_default_context` select the system's trusted CA + certificates for you. + + The *check_hostname* parameter is also deprecated; the + :attr:`ssl.SSLContext.check_hostname` attribute of *context* should + be used instead. + .. versionchanged:: 3.8 This class now enables TLS 1.3 :attr:`ssl.SSLContext.post_handshake_auth` for the default *context* or @@ -104,16 +115,9 @@ The module provides the following classes: ``http/1.1`` when no *context* is given. Custom *context* should set ALPN protocols with :meth:`~ssl.SSLContext.set_alpn_protocol`. - .. deprecated:: 3.6 - - *key_file* and *cert_file* are deprecated in favor of *context*. - Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let - :func:`ssl.create_default_context` select the system's trusted CA - certificates for you. - - The *check_hostname* parameter is also deprecated; the - :attr:`ssl.SSLContext.check_hostname` attribute of *context* should - be used instead. + .. versionchanged:: 3.12 + The deprecated *key_file*, *cert_file* and *check_hostname* parameters + have been removed. .. class:: HTTPResponse(sock, debuglevel=0, method=None, url=None) @@ -342,11 +346,11 @@ HTTPConnection Objects Set the host and the port for HTTP Connect Tunnelling. This allows running the connection through a proxy server. - The host and port arguments specify the endpoint of the tunneled connection + The *host* and *port* arguments specify the endpoint of the tunneled connection (i.e. the address included in the CONNECT request, *not* the address of the proxy server). - The headers argument should be a mapping of extra HTTP headers to send with + The *headers* argument should be a mapping of extra HTTP headers to send with the CONNECT request. For example, to tunnel through a HTTPS proxy server running locally on port @@ -472,7 +476,7 @@ statement. Return the value of the header *name*, or *default* if there is no header matching *name*. If there is more than one header with the name *name*, - return all of the values joined by ', '. If 'default' is any iterable other + return all of the values joined by ', '. If *default* is any iterable other than a single string, its elements are similarly returned joined by commas. .. method:: HTTPResponse.getheaders() @@ -576,7 +580,7 @@ Here is an example session that uses the ``HEAD`` method. Note that the >>> data == b'' True -Here is an example session that shows how to ``POST`` requests:: +Here is an example session that uses the ``POST`` method:: >>> import http.client, urllib.parse >>> params = urllib.parse.urlencode({'@number': 12524, '@type': 'issue', '@action': 'show'}) @@ -589,17 +593,16 @@ Here is an example session that shows how to ``POST`` requests:: 302 Found >>> data = response.read() >>> data - b'Redirecting to http://bugs.python.org/issue12524' + b'Redirecting to https://bugs.python.org/issue12524' >>> conn.close() -Client side ``HTTP PUT`` requests are very similar to ``POST`` requests. The -difference lies only the server side where HTTP server will allow resources to -be created via ``PUT`` request. It should be noted that custom HTTP methods +Client side HTTP ``PUT`` requests are very similar to ``POST`` requests. The +difference lies only on the server side where HTTP servers will allow resources to +be created via ``PUT`` requests. It should be noted that custom HTTP methods are also handled in :class:`urllib.request.Request` by setting the appropriate -method attribute. Here is an example session that shows how to send a ``PUT`` -request using http.client:: +method attribute. Here is an example session that uses the ``PUT`` method:: - >>> # This creates an HTTP message + >>> # This creates an HTTP request >>> # with the content of BODY as the enclosed representation >>> # for the resource http://localhost:8080/file ... diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst index 51a8c53152b..87ef156a0be 100644 --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -61,7 +61,7 @@ The following classes are provided: responsible for storing and retrieving cookies from a file or database. -.. class:: FileCookieJar(filename, delayload=None, policy=None) +.. class:: FileCookieJar(filename=None, delayload=None, policy=None) *policy* is an object implementing the :class:`CookiePolicy` interface. For the other arguments, see the documentation for the corresponding attributes. @@ -71,6 +71,8 @@ The following classes are provided: :meth:`load` or :meth:`revert` method is called. Subclasses of this class are documented in section :ref:`file-cookie-jar-classes`. + This should not be initialized directly – use its subclasses below instead. + .. versionchanged:: 3.8 The filename parameter supports a :term:`path-like object`. @@ -160,11 +162,10 @@ contained :class:`Cookie` objects. respectively), the :mailheader:`Cookie2` header is also added when appropriate. The *request* object (usually a :class:`urllib.request.Request` instance) - must support the methods :meth:`get_full_url`, :meth:`get_host`, - :meth:`get_type`, :meth:`unverifiable`, :meth:`has_header`, + must support the methods :meth:`get_full_url`, :meth:`has_header`, :meth:`get_header`, :meth:`header_items`, :meth:`add_unredirected_header` - and :attr:`origin_req_host` attribute as documented by - :mod:`urllib.request`. + and the attributes :attr:`host`, :attr:`!type`, :attr:`unverifiable` + and :attr:`origin_req_host` as documented by :mod:`urllib.request`. .. versionchanged:: 3.3 @@ -186,11 +187,11 @@ contained :class:`Cookie` objects. method, which returns an :class:`email.message.Message` instance. The *request* object (usually a :class:`urllib.request.Request` instance) - must support the methods :meth:`get_full_url`, :meth:`get_host`, - :meth:`unverifiable`, and :attr:`origin_req_host` attribute, as documented - by :mod:`urllib.request`. The request is used to set default values for - cookie-attributes as well as for checking that the cookie is allowed to be - set. + must support the method :meth:`get_full_url` and the attributes + :attr:`host`, :attr:`unverifiable` and :attr:`origin_req_host`, + as documented by :mod:`urllib.request`. The request is used to set + default values for cookie-attributes as well as for checking that the + cookie is allowed to be set. .. versionchanged:: 3.3 @@ -318,11 +319,11 @@ FileCookieJar subclasses and co-operation with web browsers The following :class:`CookieJar` subclasses are provided for reading and writing. -.. class:: MozillaCookieJar(filename, delayload=None, policy=None) +.. class:: MozillaCookieJar(filename=None, delayload=None, policy=None) A :class:`FileCookieJar` that can load from and save cookies to disk in the - Mozilla ``cookies.txt`` file format (which is also used by the Lynx and Netscape - browsers). + Mozilla ``cookies.txt`` file format (which is also used by curl and the Lynx + and Netscape browsers). .. note:: @@ -339,7 +340,7 @@ writing. Mozilla. -.. class:: LWPCookieJar(filename, delayload=None, policy=None) +.. class:: LWPCookieJar(filename=None, delayload=None, policy=None) A :class:`FileCookieJar` that can load from and save cookies to disk in format compatible with the libwww-perl library's ``Set-Cookie3`` file format. This is diff --git a/Doc/library/http.cookies.rst b/Doc/library/http.cookies.rst index 17792b20059..a2c1eb00d8b 100644 --- a/Doc/library/http.cookies.rst +++ b/Doc/library/http.cookies.rst @@ -93,7 +93,7 @@ Cookie Objects :meth:`value_decode` are inverses on the range of *value_decode*. -.. method:: BaseCookie.output(attrs=None, header='Set-Cookie:', sep='\\r\\n') +.. method:: BaseCookie.output(attrs=None, header='Set-Cookie:', sep='\r\n') Return a string representation suitable to be sent as HTTP headers. *attrs* and *header* are sent to each :class:`Morsel`'s :meth:`output` method. *sep* is used diff --git a/Doc/library/http.rst b/Doc/library/http.rst index 1569d504c7f..5e1912716e5 100644 --- a/Doc/library/http.rst +++ b/Doc/library/http.rst @@ -21,8 +21,8 @@ HyperText Transfer Protocol: * :mod:`http.cookies` has utilities for implementing state management with cookies * :mod:`http.cookiejar` provides persistence of cookies -:mod:`http` is also a module that defines a number of HTTP status codes and -associated messages through the :class:`http.HTTPStatus` enum: + +The :mod:`http` module also defines the following enums that help you work with http related code: .. class:: HTTPStatus @@ -53,8 +53,8 @@ HTTP status codes ----------------- Supported, -`IANA-registered `_ -status codes available in :class:`http.HTTPStatus` are: +`IANA-registered status codes `_ +available in :class:`http.HTTPStatus` are: ======= =================================== ================================================================== Code Enum Name Details @@ -136,3 +136,80 @@ equal to the constant name (i.e. ``http.HTTPStatus.OK`` is also available as .. versionadded:: 3.9 Added ``103 EARLY_HINTS``, ``418 IM_A_TEAPOT`` and ``425 TOO_EARLY`` status codes. + +HTTP status category +-------------------- + +.. versionadded:: 3.12 + +The enum values have several properties to indicate the HTTP status category: + +==================== ======================== =============================== +Property Indicates that Details +==================== ======================== =============================== +``is_informational`` ``100 <= status <= 199`` HTTP/1.1 :rfc:`7231`, Section 6 +``is_success`` ``200 <= status <= 299`` HTTP/1.1 :rfc:`7231`, Section 6 +``is_redirection`` ``300 <= status <= 399`` HTTP/1.1 :rfc:`7231`, Section 6 +``is_client_error`` ``400 <= status <= 499`` HTTP/1.1 :rfc:`7231`, Section 6 +``is_server_error`` ``500 <= status <= 599`` HTTP/1.1 :rfc:`7231`, Section 6 +==================== ======================== =============================== + + Usage:: + + >>> from http import HTTPStatus + >>> HTTPStatus.OK.is_success + True + >>> HTTPStatus.OK.is_client_error + False + +.. class:: HTTPMethod + + .. versionadded:: 3.11 + + A subclass of :class:`enum.StrEnum` that defines a set of HTTP methods and descriptions written in English. + + Usage:: + + >>> from http import HTTPMethod + >>> + >>> HTTPMethod.GET + + >>> HTTPMethod.GET == 'GET' + True + >>> HTTPMethod.GET.value + 'GET' + >>> HTTPMethod.GET.description + 'Retrieve the target.' + >>> list(HTTPMethod) + [, + , + , + , + , + , + , + , + ] + +.. _http-methods: + +HTTP methods +----------------- + +Supported, +`IANA-registered methods `_ +available in :class:`http.HTTPMethod` are: + +=========== =================================== ================================================================== +Method Enum Name Details +=========== =================================== ================================================================== +``GET`` ``GET`` HTTP/1.1 :rfc:`7231`, Section 4.3.1 +``HEAD`` ``HEAD`` HTTP/1.1 :rfc:`7231`, Section 4.3.2 +``POST`` ``POST`` HTTP/1.1 :rfc:`7231`, Section 4.3.3 +``PUT`` ``PUT`` HTTP/1.1 :rfc:`7231`, Section 4.3.4 +``DELETE`` ``DELETE`` HTTP/1.1 :rfc:`7231`, Section 4.3.5 +``CONNECT`` ``CONNECT`` HTTP/1.1 :rfc:`7231`, Section 4.3.6 +``OPTIONS`` ``OPTIONS`` HTTP/1.1 :rfc:`7231`, Section 4.3.7 +``TRACE`` ``TRACE`` HTTP/1.1 :rfc:`7231`, Section 4.3.8 +``PATCH`` ``PATCH`` HTTP/1.1 :rfc:`5789` +=========== =================================== ================================================================== diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst index c3cee079526..ae75e6dc5fd 100644 --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -20,7 +20,9 @@ This module defines classes for implementing HTTP servers. .. warning:: :mod:`http.server` is not recommended for production. It only implements - basic security checks. + :ref:`basic security checks `. + +.. include:: ../includes/wasm-notavail.rst One class, :class:`HTTPServer`, is a :class:`socketserver.TCPServer` subclass. It creates and listens at the HTTP socket, dispatching the requests to a @@ -157,7 +159,9 @@ provides three different variants: .. attribute:: protocol_version - This specifies the HTTP protocol version used in responses. If set to + Specifies the HTTP version to which the server is conformant. It is sent + in responses to let the client know the server's communication + capabilities for future requests. If set to ``'HTTP/1.1'``, the server will permit HTTP persistent connections; however, your server *must* then include an accurate ``Content-Length`` header (using :meth:`send_header`) in all of its responses to clients. @@ -193,7 +197,7 @@ provides three different variants: .. method:: handle_expect_100() - When a HTTP/1.1 compliant server receives an ``Expect: 100-continue`` + When an HTTP/1.1 conformant server receives an ``Expect: 100-continue`` request header it responds back with a ``100 Continue`` followed by ``200 OK`` headers. This method can be overridden to raise an error if the server does not @@ -388,8 +392,8 @@ provides three different variants: contents of the file are output. If the file's MIME type starts with ``text/`` the file is opened in text mode; otherwise binary mode is used. - For example usage, see the implementation of the :func:`test` function - invocation in the :mod:`http.server` module. + For example usage, see the implementation of the ``test`` function + in :source:`Lib/http/server.py`. .. versionchanged:: 3.7 Support of the ``'If-Modified-Since'`` header. @@ -409,20 +413,30 @@ the current directory:: print("serving at port", PORT) httpd.serve_forever() + +:class:`SimpleHTTPRequestHandler` can also be subclassed to enhance behavior, +such as using different index file names by overriding the class attribute +:attr:`index_pages`. + .. _http-server-cli: :mod:`http.server` can also be invoked directly using the :option:`-m` -switch of the interpreter with a ``port number`` argument. Similar to +switch of the interpreter. Similar to the previous example, this serves files relative to the current directory:: - python -m http.server 8000 + python -m http.server -By default, server binds itself to all interfaces. The option ``-b/--bind`` +The server listens to port 8000 by default. The default can be overridden +by passing the desired port number as an argument:: + + python -m http.server 9000 + +By default, the server binds itself to all interfaces. The option ``-b/--bind`` specifies a specific address to which it should bind. Both IPv4 and IPv6 addresses are supported. For example, the following command causes the server to bind to localhost only:: - python -m http.server 8000 --bind 127.0.0.1 + python -m http.server --bind 127.0.0.1 .. versionadded:: 3.4 ``--bind`` argument was introduced. @@ -430,14 +444,23 @@ to bind to localhost only:: .. versionadded:: 3.8 ``--bind`` argument enhanced to support IPv6 -By default, server uses the current directory. The option ``-d/--directory`` +By default, the server uses the current directory. The option ``-d/--directory`` specifies a directory to which it should serve the files. For example, the following command uses a specific directory:: python -m http.server --directory /tmp/ .. versionadded:: 3.7 - ``--directory`` specify alternate directory + ``--directory`` argument was introduced. + +By default, the server is conformant to HTTP/1.0. The option ``-p/--protocol`` +specifies the HTTP version to which the server is conformant. For example, the +following command runs an HTTP/1.1 conformant server:: + + python -m http.server --protocol HTTP/1.1 + +.. versionadded:: 3.11 + ``--protocol`` argument was introduced. .. class:: CGIHTTPRequestHandler(request, client_address, server) @@ -482,4 +505,24 @@ the following command uses a specific directory:: :class:`CGIHTTPRequestHandler` can be enabled in the command line by passing the ``--cgi`` option:: - python -m http.server --cgi 8000 + python -m http.server --cgi + +.. _http.server-security: + +Security Considerations +----------------------- + +.. index:: pair: http.server; security + +:class:`SimpleHTTPRequestHandler` will follow symbolic links when handling +requests, this makes it possible for files outside of the specified directory +to be served. + +Earlier versions of Python did not scrub control characters from the +log messages emitted to stderr from ``python -m http.server`` or the +default :class:`BaseHTTPRequestHandler` ``.log_message`` +implementation. This could allow remote clients connecting to your +server to send nefarious control codes to your terminal. + +.. versionadded:: 3.12 + Control characters are scrubbed in stderr logs. diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index d740973af91..3058bcead66 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -61,17 +61,17 @@ New File Open... Open an existing file with an Open dialog. -Recent Files - Open a list of recent files. Click one to open it. - Open Module... Open an existing module (searches sys.path). +Recent Files + Open a list of recent files. Click one to open it. + .. index:: - single: Class browser + single: Module browser single: Path browser -Class Browser +Module Browser Show functions, classes, and methods in the current Editor file in a tree structure. In the shell, open a module first. @@ -87,20 +87,25 @@ Save Save As... Save the current window with a Save As dialog. The file saved becomes the - new associated file for the window. + new associated file for the window. (If your file namager is set to hide + extensions, the current extension will be omitted in the file name box. + If the new filename has no '.', '.py' and '.txt' will be added for Python + and text files, except that on macOS Aqua,'.py' is added for all files.) Save Copy As... Save the current window to different file without changing the associated - file. + file. (See Save As note above about filename extensions.) Print Window Print the current window to the default printer. -Close - Close the current window (ask to save if unsaved). +Close Window + Close the current window (if an unsaved editor, ask to save; if an unsaved + Shell, ask to quit execution). Calling ``exit()`` or ``close()`` in the Shell + window also closes Shell. If this is the only window, also exit IDLE. -Exit - Close all windows and quit IDLE (ask to save unsaved windows). +Exit IDLE + Close all windows and quit IDLE (ask to save unsaved edit windows). Edit menu (Shell and Editor) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -112,6 +117,9 @@ Undo Redo Redo the last undone change to the current window. +Select All + Select the entire contents of the current window. + Cut Copy selection into the system-wide clipboard; then delete the selection. @@ -123,9 +131,6 @@ Paste The clipboard functions are also available in context menus. -Select All - Select the entire contents of the current window. - Find... Open a search dialog with many options @@ -154,12 +159,12 @@ Expand Word Expand a prefix you have typed to match a full word in the same window; repeat to get a different expansion. -Show call tip +Show Call Tip After an unclosed parenthesis for a function, open a small window with function parameter hints. See :ref:`Calltips ` in the Editing and navigation section below. -Show surrounding parens +Show Surrounding Parens Highlight the surrounding parenthesis. .. _format-menu: @@ -167,6 +172,11 @@ Show surrounding parens Format menu (Editor window only) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Format Paragraph + Reformat the current blank-line-delimited paragraph in comment block or + multiline string or selected line in a string. All lines in the + paragraph will be formatted to less than N columns, where N defaults to 72. + Indent Region Shift selected lines right by the indent width (default 4 spaces). @@ -193,12 +203,7 @@ New Indent Width Open a dialog to change indent width. The accepted default by the Python community is 4 spaces. -Format Paragraph - Reformat the current blank-line-delimited paragraph in comment block or - multiline string or selected line in a string. All lines in the - paragraph will be formatted to less than N columns, where N defaults to 72. - -Strip trailing whitespace +Strip Trailing Chitespace Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, including lines within multiline strings. Except for Shell windows, @@ -355,7 +360,7 @@ for more on Help menu choices. single: Clear Breakpoint single: breakpoints -Context Menus +Context menus ^^^^^^^^^^^^^^^^^^^^^^^^^^ Open a context menu by right-clicking in a window (Control-click on macOS). @@ -396,7 +401,7 @@ Squeeze .. _editing-and-navigation: -Editing and navigation +Editing and Navigation ---------------------- Editor windows @@ -469,6 +474,14 @@ are restricted to four spaces due to Tcl/Tk limitations. See also the indent/dedent region commands on the :ref:`Format menu `. +Search and Replace +^^^^^^^^^^^^^^^^^^ + +Any selection becomes a search target. However, only selections within +a line work because searches are only performed within lines with the +terminal newline removed. If ``[x] Regular expresion`` is checked, the +target is interpreted according to the Python re module. + .. _completions: Completions @@ -574,17 +587,29 @@ line to the top of the editor. The text and background colors for the context pane can be configured under the Highlights tab in the Configure IDLE dialog. -Python Shell window -^^^^^^^^^^^^^^^^^^^ +Shell window +^^^^^^^^^^^^ -With IDLE's Shell, one enters, edits, and recalls complete statements. -Most consoles and terminals only work with a single physical line at a time. +In IDLE's Shell, enter, edit, and recall complete statements. (Most +consoles and terminals only work with a single physical line at a time). + +Submit a single-line statement for execution by hitting :kbd:`Return` +with the cursor anywhere on the line. If a line is extended with +Backslash (:kbd:`\\`), the cursor must be on the last physical line. +Submit a multi-line compound statement by entering a blank line after +the statement. When one pastes code into Shell, it is not compiled and possibly executed -until one hits :kbd:`Return`. One may edit pasted code first. -If one pastes more that one statement into Shell, the result will be a +until one hits :kbd:`Return`, as specified above. +One may edit pasted code first. +If one pastes more than one statement into Shell, the result will be a :exc:`SyntaxError` when multiple statements are compiled as if they were one. +Lines containing ``RESTART`` mean that the user execution process has been +re-started. This occurs when the user execution process has crashed, +when one requests a restart on the Shell menu, or when one runs code +in an editor window. + The editing features described in previous subsections work when entering code interactively. IDLE's Shell window also responds to the following keys. @@ -601,7 +626,8 @@ code interactively. IDLE's Shell window also responds to the following keys. * :kbd:`Alt-n` retrieves next. On macOS use :kbd:`C-n`. - * :kbd:`Return` while on any previous command retrieves that command + * :kbd:`Return` while the cursor is on any previous command + retrieves that command Text colors ^^^^^^^^^^^ @@ -625,7 +651,7 @@ Highlighting tab. The marking of debugger breakpoint lines in the editor and text in popups and dialogs is not user-configurable. -Startup and code execution +Startup and Code Execution -------------------------- Upon startup with the ``-s`` option, IDLE will execute the file referenced by @@ -760,7 +786,9 @@ IDLE's standard stream replacements are not inherited by subprocesses created in the execution process, whether directly by user code or by modules such as multiprocessing. If such subprocess use ``input`` from sys.stdin or ``print`` or ``write`` to sys.stdout or sys.stderr, -IDLE should be started in a command line window. The secondary subprocess +IDLE should be started in a command line window. (On Windows, +use ``python`` or ``py`` rather than ``pythonw`` or ``pyw``.) +The secondary subprocess will then be attached to that window for input and output. If ``sys`` is reset by user code, such as with ``importlib.reload(sys)``, @@ -892,7 +920,7 @@ with the default subprocess if at all possible. .. deprecated:: 3.4 -Help and preferences +Help and Preferences -------------------- .. _help-sources: @@ -955,3 +983,23 @@ changed with the Extensions tab of the preferences dialog. See the beginning of config-extensions.def in the idlelib directory for further information. The only current default extension is zzdummy, an example also used for testing. + + +idlelib +------- + +.. module:: idlelib + :synopsis: Implementation package for the IDLE shell/editor. + +**Source code:** :source:`Lib/idlelib` + +-------------- + +The Lib/idlelib package implements the IDLE application. See the rest +of this page for how to use IDLE. + +The files in idlelib are described in idlelib/README.txt. Access it +either in idlelib or click Help => About IDLE on the IDLE menu. This +file also maps IDLE menu items to the code that implements the item. +Except for files listed under 'Startup', the idlelib code is 'private' in +sense that feature changes can be backported (see :pep:`434`). diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst index 65681ec0935..f1344ae9bb0 100644 --- a/Doc/library/imaplib.rst +++ b/Doc/library/imaplib.rst @@ -26,6 +26,8 @@ implement a large subset of the IMAP4rev1 client protocol as defined in :rfc:`2060`. It is backward compatible with IMAP4 (:rfc:`1730`) servers, but note that the ``STATUS`` command is not supported in IMAP4. +.. include:: ../includes/wasm-notavail.rst + Three classes are provided by the :mod:`imaplib` module, :class:`IMAP4` is the base class: @@ -82,8 +84,8 @@ Three exceptions are defined as attributes of the :class:`IMAP4` class: There's also a subclass for secure connections: -.. class:: IMAP4_SSL(host='', port=IMAP4_SSL_PORT, keyfile=None, \ - certfile=None, ssl_context=None, timeout=None) +.. class:: IMAP4_SSL(host='', port=IMAP4_SSL_PORT, *, ssl_context=None, \ + timeout=None) This is a subclass derived from :class:`IMAP4` that connects over an SSL encrypted socket (to use this class you need a socket module that was compiled @@ -94,12 +96,6 @@ There's also a subclass for secure connections: (potentially long-lived) structure. Please read :ref:`ssl-security` for best practices. - *keyfile* and *certfile* are a legacy alternative to *ssl_context* - they - can point to PEM-formatted private key and certificate chain files for - the SSL connection. Note that the *keyfile*/*certfile* parameters are - mutually exclusive with *ssl_context*, a :class:`ValueError` is raised - if *keyfile*/*certfile* is provided along with *ssl_context*. - The optional *timeout* parameter specifies a timeout in seconds for the connection attempt. If timeout is not given or is None, the global default socket timeout is used. @@ -122,6 +118,9 @@ There's also a subclass for secure connections: .. versionchanged:: 3.9 The optional *timeout* parameter was added. + .. versionchanged:: 3.12 + The deprecated *keyfile* and *certfile* parameters have been removed. + The second subclass allows for connections created by a child process: @@ -185,7 +184,7 @@ IMAP4 Objects ------------- All IMAP4rev1 commands are represented by methods of the same name, either -upper-case or lower-case. +uppercase or lowercase. All arguments to commands are converted to strings, except for ``AUTHENTICATE``, and the last argument to ``APPEND`` which is passed as an IMAP4 literal. If @@ -562,7 +561,7 @@ An :class:`IMAP4` instance has the following methods: ``search``, the searching *charset* argument is mandatory. There is also a ``uid thread`` command which corresponds to ``thread`` the way that ``uid search`` corresponds to ``search``. The ``thread`` command first searches the - mailbox for messages that match the given searching criteria using the charset + mailbox for messages that match the given searching criteria using the *charset* argument for the interpretation of strings in the searching criteria. It then returns the matching messages threaded according to the specified threading algorithm. diff --git a/Doc/library/imghdr.rst b/Doc/library/imghdr.rst index 3d7f6de7a1b..630fd7019f9 100644 --- a/Doc/library/imghdr.rst +++ b/Doc/library/imghdr.rst @@ -3,9 +3,14 @@ .. module:: imghdr :synopsis: Determine the type of image contained in a file or byte stream. + :deprecated: **Source code:** :source:`Lib/imghdr.py` +.. deprecated-removed:: 3.11 3.13 + The :mod:`imghdr` module is deprecated + (see :pep:`PEP 594 <594#imghdr>` for details and alternatives). + -------------- The :mod:`imghdr` module determines the type of image contained in a file or @@ -16,8 +21,8 @@ The :mod:`imghdr` module defines the following function: .. function:: what(file, h=None) - Tests the image data contained in the file named by *file*, and returns a - string describing the image type. If optional *h* is provided, the *file* + Test the image data contained in the file named *file* and return a + string describing the image type. If *h* is provided, the *file* argument is ignored and *h* is assumed to contain the byte stream to test. .. versionchanged:: 3.6 diff --git a/Doc/library/imp.rst b/Doc/library/imp.rst index 121a730e0c9..000793a7e66 100644 --- a/Doc/library/imp.rst +++ b/Doc/library/imp.rst @@ -7,7 +7,7 @@ **Source code:** :source:`Lib/imp.py` -.. deprecated:: 3.4 +.. deprecated-removed:: 3.4 3.12 The :mod:`imp` module is deprecated in favor of :mod:`importlib`. .. index:: statement: import diff --git a/Doc/library/importlib.metadata.rst b/Doc/library/importlib.metadata.rst index 99bcfeb2d1b..988d1a317f5 100644 --- a/Doc/library/importlib.metadata.rst +++ b/Doc/library/importlib.metadata.rst @@ -13,29 +13,61 @@ **Source code:** :source:`Lib/importlib/metadata/__init__.py` -``importlib.metadata`` is a library that provides for access to installed -package metadata. Built in part on Python's import system, this library +``importlib_metadata`` is a library that provides access to +the metadata of an installed `Distribution Package `_, +such as its entry points +or its top-level names (`Import Package `_\s, modules, if any). +Built in part on Python's import system, this library intends to replace similar functionality in the `entry point API`_ and `metadata API`_ of ``pkg_resources``. Along with -:mod:`importlib.resources` in Python 3.7 -and newer (backported as `importlib_resources`_ for older versions of -Python), this can eliminate the need to use the older and less efficient +:mod:`importlib.resources`, +this package can eliminate the need to use the older and less efficient ``pkg_resources`` package. -By "installed package" we generally mean a third-party package installed into -Python's ``site-packages`` directory via tools such as `pip -`_. Specifically, -it means a package with either a discoverable ``dist-info`` or ``egg-info`` -directory, and metadata defined by :pep:`566` or its older specifications. -By default, package metadata can live on the file system or in zip archives on +``importlib_metadata`` operates on third-party *distribution packages* +installed into Python's ``site-packages`` directory via tools such as +`pip `_. +Specifically, it works with distributions with discoverable +``dist-info`` or ``egg-info`` directories, +and metadata defined by the `Core metadata specifications `_. + +.. important:: + + These are *not* necessarily equivalent to or correspond 1:1 with + the top-level *import package* names + that can be imported inside Python code. + One *distribution package* can contain multiple *import packages* + (and single modules), + and one top-level *import package* + may map to multiple *distribution packages* + if it is a namespace package. + You can use :ref:`package_distributions() ` + to get a mapping between them. + +By default, distribution metadata can live on the file system +or in zip archives on :data:`sys.path`. Through an extension mechanism, the metadata can live almost anywhere. +.. seealso:: + + https://importlib-metadata.readthedocs.io/ + The documentation for ``importlib_metadata``, which supplies a + backport of ``importlib.metadata``. + This includes an `API reference + `__ + for this module's classes and functions, + as well as a `migration guide + `__ + for existing users of ``pkg_resources``. + + Overview ======== -Let's say you wanted to get the version string for a package you've installed +Let's say you wanted to get the version string for a +`Distribution Package `_ you've installed using ``pip``. We start by creating a virtual environment and installing something into it: @@ -43,7 +75,7 @@ something into it: $ python3 -m venv example $ source example/bin/activate - (example) $ pip install wheel + (example) $ python -m pip install wheel You can get the version string for ``wheel`` by running the following: @@ -54,9 +86,9 @@ You can get the version string for ``wheel`` by running the following: >>> version('wheel') # doctest: +SKIP '0.32.3' -You can also get the set of entry points keyed by group, such as +You can also get a collection of entry points selectable by properties of the EntryPoint (typically 'group' or 'name'), such as ``console_scripts``, ``distutils.commands`` and others. Each group contains a -sequence of :ref:`EntryPoint ` objects. +collection of :ref:`EntryPoint ` objects. You can get the :ref:`metadata for a distribution `:: @@ -91,7 +123,7 @@ Query all entry points:: >>> eps = entry_points() # doctest: +SKIP The ``entry_points()`` function returns an ``EntryPoints`` object, -a sequence of all ``EntryPoint`` objects with ``names`` and ``groups`` +a collection of all ``EntryPoint`` objects with ``names`` and ``groups`` attributes for convenience:: >>> sorted(eps.groups) # doctest: +SKIP @@ -136,7 +168,7 @@ Inspect the resolved entry point:: The ``group`` and ``name`` are arbitrary values defined by the package author and usually a client will wish to resolve all entry points for a particular group. Read `the setuptools docs -`_ +`_ for more information on entry points, their definition, and usage. *Compatibility Note* @@ -144,11 +176,10 @@ for more information on entry points, their definition, and usage. The "selectable" entry points were introduced in ``importlib_metadata`` 3.6 and Python 3.10. Prior to those changes, ``entry_points`` accepted no parameters and always returned a dictionary of entry points, keyed -by group. For compatibility, if no parameters are passed to entry_points, -a ``SelectableGroups`` object is returned, implementing that dict -interface. In the future, calling ``entry_points`` with no parameters -will return an ``EntryPoints`` object. Users should rely on the selection -interface to retrieve entry points by group. +by group. With ``importlib_metadata`` 5.0 and Python 3.12, +``entry_points`` always returns an ``EntryPoints`` object. See +`backports.entry_points_selectable `_ +for compatibility options. .. _metadata: @@ -156,7 +187,8 @@ interface to retrieve entry points by group. Distribution metadata --------------------- -Every distribution includes some metadata, which you can extract using the +Every `Distribution Package `_ includes some metadata, +which you can extract using the ``metadata()`` function:: >>> wheel_metadata = metadata('wheel') # doctest: +SKIP @@ -174,6 +206,13 @@ all the metadata in a JSON-compatible form per :PEP:`566`:: >>> wheel_metadata.json['requires_python'] '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*' +.. note:: + + The actual type of the object returned by ``metadata()`` is an + implementation detail and should be accessed only through the interface + described by the + `PackageMetadata protocol `_. + .. versionchanged:: 3.10 The ``Description`` is now included in the metadata when presented through the payload. Line continuation characters have been removed. @@ -187,7 +226,8 @@ all the metadata in a JSON-compatible form per :PEP:`566`:: Distribution versions --------------------- -The ``version()`` function is the quickest way to get a distribution's version +The ``version()`` function is the quickest way to get a +`Distribution Package `_'s version number, as a string:: >>> version('wheel') # doctest: +SKIP @@ -200,7 +240,8 @@ Distribution files ------------------ You can also get the full set of files contained within a distribution. The -``files()`` function takes a distribution package name and returns all of the +``files()`` function takes a `Distribution Package `_ name +and returns all of the files installed by this distribution. Each file object returned is a ``PackagePath``, a :class:`pathlib.PurePath` derived object with additional ``dist``, ``size``, and ``hash`` properties as indicated by the metadata. For example:: @@ -245,32 +286,39 @@ distribution is not known to have the metadata present. Distribution requirements ------------------------- -To get the full set of requirements for a distribution, use the ``requires()`` +To get the full set of requirements for a `Distribution Package `_, +use the ``requires()`` function:: >>> requires('wheel') # doctest: +SKIP ["pytest (>=3.0.0) ; extra == 'test'", "pytest-cov ; extra == 'test'"] -Package distributions ---------------------- +.. _package-distributions: +.. _import-distribution-package-mapping: -A convenience method to resolve the distribution or -distributions (in the case of a namespace package) for top-level -Python packages or modules:: +Mapping import to distribution packages +--------------------------------------- + +A convenience method to resolve the `Distribution Package `_ +name (or names, in the case of a namespace package) +that provide each importable top-level +Python module or `Import Package `_:: >>> packages_distributions() {'importlib_metadata': ['importlib-metadata'], 'yaml': ['PyYAML'], 'jaraco': ['jaraco.classes', 'jaraco.functools'], ...} .. versionadded:: 3.10 +.. _distributions: Distributions ============= While the above API is the most common and convenient usage, you can get all of that information from the ``Distribution`` class. A ``Distribution`` is an -abstract object that represents the metadata for a Python package. You can +abstract object that represents the metadata for +a Python `Distribution Package `_. You can get the ``Distribution`` instance:: >>> from importlib.metadata import distribution # doctest: +SKIP @@ -290,22 +338,36 @@ instance:: >>> dist.metadata['License'] # doctest: +SKIP 'MIT' -The full set of available metadata is not described here. See :pep:`566` -for additional details. +The full set of available metadata is not described here. +See the `Core metadata specifications `_ for additional details. + + +Distribution Discovery +====================== + +By default, this package provides built-in support for discovery of metadata +for file system and zip file `Distribution Package `_\s. +This metadata finder search defaults to ``sys.path``, but varies slightly in how it interprets those values from how other import machinery does. In particular: + +- ``importlib.metadata`` does not honor :class:`bytes` objects on ``sys.path``. +- ``importlib.metadata`` will incidentally honor :py:class:`pathlib.Path` objects on ``sys.path`` even though such values will be ignored for imports. Extending the search algorithm ============================== -Because package metadata is not available through :data:`sys.path` searches, or -package loaders directly, the metadata for a package is found through import +Because `Distribution Package `_ metadata +is not available through :data:`sys.path` searches, or +package loaders directly, +the metadata for a distribution is found through import system :ref:`finders `. To find a distribution package's metadata, ``importlib.metadata`` queries the list of :term:`meta path finders ` on :data:`sys.meta_path`. -The default ``PathFinder`` for Python includes a hook that calls into -``importlib.metadata.MetadataPathFinder`` for finding distributions -loaded from typical file-system-based paths. +By default ``importlib_metadata`` installs a finder for distribution packages +found on the file system. +This finder doesn't actually find any *distributions*, +but it can find their metadata. The abstract class :py:class:`importlib.abc.MetaPathFinder` defines the interface expected of finders by Python's import system. @@ -334,7 +396,3 @@ a custom finder, return instances of this derived ``Distribution`` in the .. _`entry point API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points .. _`metadata API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#metadata-api -.. _`importlib_resources`: https://importlib-resources.readthedocs.io/en/latest/index.html - - -.. rubric:: Footnotes diff --git a/Doc/library/importlib.resources.abc.rst b/Doc/library/importlib.resources.abc.rst new file mode 100644 index 00000000000..7747e89a833 --- /dev/null +++ b/Doc/library/importlib.resources.abc.rst @@ -0,0 +1,161 @@ +:mod:`importlib.resources.abc` -- Abstract base classes for resources +--------------------------------------------------------------------- + +.. module:: importlib.resources.abc + :synopsis: Abstract base classes for resources + +**Source code:** :source:`Lib/importlib/resources/abc.py` + +-------------- + +.. versionadded:: 3.11 + +.. class:: ResourceReader + + *Superseded by TraversableResources* + + An :term:`abstract base class` to provide the ability to read + *resources*. + + From the perspective of this ABC, a *resource* is a binary + artifact that is shipped within a package. Typically this is + something like a data file that lives next to the ``__init__.py`` + file of the package. The purpose of this class is to help abstract + out the accessing of such data files so that it does not matter if + the package and its data file(s) are stored in a e.g. zip file + versus on the file system. + + For any of methods of this class, a *resource* argument is + expected to be a :term:`path-like object` which represents + conceptually just a file name. This means that no subdirectory + paths should be included in the *resource* argument. This is + because the location of the package the reader is for, acts as the + "directory". Hence the metaphor for directories and file + names is packages and resources, respectively. This is also why + instances of this class are expected to directly correlate to + a specific package (instead of potentially representing multiple + packages or a module). + + Loaders that wish to support resource reading are expected to + provide a method called ``get_resource_reader(fullname)`` which + returns an object implementing this ABC's interface. If the module + specified by fullname is not a package, this method should return + :const:`None`. An object compatible with this ABC should only be + returned when the specified module is a package. + + .. versionadded:: 3.7 + + .. deprecated-removed:: 3.12 3.14 + Use :class:`importlib.resources.abc.TraversableResources` instead. + + .. abstractmethod:: open_resource(resource) + + Returns an opened, :term:`file-like object` for binary reading + of the *resource*. + + If the resource cannot be found, :exc:`FileNotFoundError` is + raised. + + .. abstractmethod:: resource_path(resource) + + Returns the file system path to the *resource*. + + If the resource does not concretely exist on the file system, + raise :exc:`FileNotFoundError`. + + .. abstractmethod:: is_resource(name) + + Returns ``True`` if the named *name* is considered a resource. + :exc:`FileNotFoundError` is raised if *name* does not exist. + + .. abstractmethod:: contents() + + Returns an :term:`iterable` of strings over the contents of + the package. Do note that it is not required that all names + returned by the iterator be actual resources, e.g. it is + acceptable to return names for which :meth:`is_resource` would + be false. + + Allowing non-resource names to be returned is to allow for + situations where how a package and its resources are stored + are known a priori and the non-resource names would be useful. + For instance, returning subdirectory names is allowed so that + when it is known that the package and resources are stored on + the file system then those subdirectory names can be used + directly. + + The abstract method returns an iterable of no items. + + +.. class:: Traversable + + An object with a subset of pathlib.Path methods suitable for + traversing directories and opening files. + + .. versionadded:: 3.9 + + .. deprecated-removed:: 3.12 3.14 + Use :class:`importlib.resources.abc.Traversable` instead. + + .. attribute:: name + + Abstract. The base name of this object without any parent references. + + .. abstractmethod:: iterdir() + + Yield Traversable objects in self. + + .. abstractmethod:: is_dir() + + Return True if self is a directory. + + .. abstractmethod:: is_file() + + Return True if self is a file. + + .. abstractmethod:: joinpath(child) + + Return Traversable child in self. + + .. abstractmethod:: __truediv__(child) + + Return Traversable child in self. + + .. abstractmethod:: open(mode='r', *args, **kwargs) + + *mode* may be 'r' or 'rb' to open as text or binary. Return a handle + suitable for reading (same as :attr:`pathlib.Path.open`). + + When opening as text, accepts encoding parameters such as those + accepted by :attr:`io.TextIOWrapper`. + + .. method:: read_bytes() + + Read contents of self as bytes. + + .. method:: read_text(encoding=None) + + Read contents of self as text. + + +.. class:: TraversableResources + + An abstract base class for resource readers capable of serving + the :meth:`importlib.resources.files` interface. Subclasses + :class:`importlib.resources.abc.ResourceReader` and provides + concrete implementations of the :class:`importlib.resources.abc.ResourceReader`'s + abstract methods. Therefore, any loader supplying + :class:`importlib.abc.TraversableResources` also supplies ResourceReader. + + Loaders that wish to support resource reading are expected to + implement this interface. + + .. versionadded:: 3.9 + + .. deprecated-removed:: 3.12 3.14 + Use :class:`importlib.resources.abc.TraversableResources` instead. + + .. abstractmethod:: files() + + Returns a :class:`importlib.resources.abc.Traversable` object for the loaded + package. diff --git a/Doc/library/importlib.resources.rst b/Doc/library/importlib.resources.rst new file mode 100644 index 00000000000..4c6aa59bf9f --- /dev/null +++ b/Doc/library/importlib.resources.rst @@ -0,0 +1,252 @@ +:mod:`importlib.resources` -- Resources +--------------------------------------- + +.. module:: importlib.resources + :synopsis: Package resource reading, opening, and access + +**Source code:** :source:`Lib/importlib/resources/__init__.py` + +-------------- + +.. versionadded:: 3.7 + +This module leverages Python's import system to provide access to *resources* +within *packages*. + +"Resources" are file-like resources associated with a module or package in +Python. The resources may be contained directly in a package, within a +subdirectory contained in that package, or adjacent to modules outside a +package. Resources may be text or binary. As a result, Python module sources +(.py) of a package and compilation artifacts (pycache) are technically +de-facto resources of that package. In practice, however, resources are +primarily those non-Python artifacts exposed specifically by the package +author. + +Resources can be opened or read in either binary or text mode. + +Resources are roughly akin to files inside directories, though it's important +to keep in mind that this is just a metaphor. Resources and packages **do +not** have to exist as physical files and directories on the file system: +for example, a package and its resources can be imported from a zip file using +:py:mod:`zipimport`. + +.. note:: + + This module provides functionality similar to `pkg_resources + `_ `Basic + Resource Access + `_ + without the performance overhead of that package. This makes reading + resources included in packages easier, with more stable and consistent + semantics. + + The standalone backport of this module provides more information + on `using importlib.resources + `_ and + `migrating from pkg_resources to importlib.resources + `_. + +:class:`Loaders ` that wish to support resource reading should implement a +``get_resource_reader(fullname)`` method as specified by +:class:`importlib.resources.abc.ResourceReader`. + +.. data:: Anchor + + Represents an anchor for resources, either a :class:`module object + ` or a module name as a string. Defined as + ``Union[str, ModuleType]``. + +.. function:: files(anchor: Optional[Anchor] = None) + + Returns a :class:`~importlib.resources.abc.Traversable` object + representing the resource container (think directory) and its resources + (think files). A Traversable may contain other containers (think + subdirectories). + + *anchor* is an optional :data:`Anchor`. If the anchor is a + package, resources are resolved from that package. If a module, + resources are resolved adjacent to that module (in the same package + or the package root). If the anchor is omitted, the caller's module + is used. + + .. versionadded:: 3.9 + + .. versionchanged:: 3.12 + "package" parameter was renamed to "anchor". "anchor" can now + be a non-package module and if omitted will default to the caller's + module. "package" is still accepted for compatibility but will raise + a DeprecationWarning. Consider passing the anchor positionally or + using ``importlib_resources >= 5.10`` for a compatible interface + on older Pythons. + +.. function:: as_file(traversable) + + Given a :class:`~importlib.resources.abc.Traversable` object representing + a file, typically from :func:`importlib.resources.files`, return + a context manager for use in a :keyword:`with` statement. + The context manager provides a :class:`pathlib.Path` object. + + Exiting the context manager cleans up any temporary file created when the + resource was extracted from e.g. a zip file. + + Use ``as_file`` when the Traversable methods + (``read_text``, etc) are insufficient and an actual file on + the file system is required. + + .. versionadded:: 3.9 + + +Deprecated functions +-------------------- + +An older, deprecated set of functions is still available, but is +scheduled for removal in a future version of Python. +The main drawback of these functions is that they do not support +directories: they assume all resources are located directly within a *package*. + +.. data:: Package + + Whenever a function accepts a ``Package`` argument, you can pass in + either a :class:`module object ` or a module name + as a string. You can only pass module objects whose + ``__spec__.submodule_search_locations`` is not ``None``. + + The ``Package`` type is defined as ``Union[str, ModuleType]``. + + .. deprecated:: 3.12 + + +.. data:: Resource + + For *resource* arguments of the functions below, you can pass in + the name of a resource as a string or + a :class:`path-like object `. + + The ``Resource`` type is defined as ``Union[str, os.PathLike]``. + + +.. function:: open_binary(package, resource) + + Open for binary reading the *resource* within *package*. + + *package* is either a name or a module object which conforms to the + ``Package`` requirements. *resource* is the name of the resource to open + within *package*; it may not contain path separators and it may not have + sub-resources (i.e. it cannot be a directory). This function returns a + ``typing.BinaryIO`` instance, a binary I/O stream open for reading. + + .. deprecated:: 3.11 + + Calls to this function can be replaced by:: + + files(package).joinpath(resource).open('rb') + + +.. function:: open_text(package, resource, encoding='utf-8', errors='strict') + + Open for text reading the *resource* within *package*. By default, the + resource is opened for reading as UTF-8. + + *package* is either a name or a module object which conforms to the + ``Package`` requirements. *resource* is the name of the resource to open + within *package*; it may not contain path separators and it may not have + sub-resources (i.e. it cannot be a directory). *encoding* and *errors* + have the same meaning as with built-in :func:`open`. + + This function returns a ``typing.TextIO`` instance, a text I/O stream open + for reading. + + .. deprecated:: 3.11 + + Calls to this function can be replaced by:: + + files(package).joinpath(resource).open('r', encoding=encoding) + + +.. function:: read_binary(package, resource) + + Read and return the contents of the *resource* within *package* as + ``bytes``. + + *package* is either a name or a module object which conforms to the + ``Package`` requirements. *resource* is the name of the resource to open + within *package*; it may not contain path separators and it may not have + sub-resources (i.e. it cannot be a directory). This function returns the + contents of the resource as :class:`bytes`. + + .. deprecated:: 3.11 + + Calls to this function can be replaced by:: + + files(package).joinpath(resource).read_bytes() + + +.. function:: read_text(package, resource, encoding='utf-8', errors='strict') + + Read and return the contents of *resource* within *package* as a ``str``. + By default, the contents are read as strict UTF-8. + + *package* is either a name or a module object which conforms to the + ``Package`` requirements. *resource* is the name of the resource to open + within *package*; it may not contain path separators and it may not have + sub-resources (i.e. it cannot be a directory). *encoding* and *errors* + have the same meaning as with built-in :func:`open`. This function + returns the contents of the resource as :class:`str`. + + .. deprecated:: 3.11 + + Calls to this function can be replaced by:: + + files(package).joinpath(resource).read_text(encoding=encoding) + + +.. function:: path(package, resource) + + Return the path to the *resource* as an actual file system path. This + function returns a context manager for use in a :keyword:`with` statement. + The context manager provides a :class:`pathlib.Path` object. + + Exiting the context manager cleans up any temporary file created when the + resource needs to be extracted from e.g. a zip file. + + *package* is either a name or a module object which conforms to the + ``Package`` requirements. *resource* is the name of the resource to open + within *package*; it may not contain path separators and it may not have + sub-resources (i.e. it cannot be a directory). + + .. deprecated:: 3.11 + + Calls to this function can be replaced using :func:`as_file`:: + + as_file(files(package).joinpath(resource)) + + +.. function:: is_resource(package, name) + + Return ``True`` if there is a resource named *name* in the package, + otherwise ``False``. + This function does not consider directories to be resources. + *package* is either a name or a module object which conforms to the + ``Package`` requirements. + + .. deprecated:: 3.11 + + Calls to this function can be replaced by:: + + files(package).joinpath(resource).is_file() + + +.. function:: contents(package) + + Return an iterable over the named items within the package. The iterable + returns :class:`str` resources (e.g. files) and non-resources + (e.g. directories). The iterable does not recurse into subdirectories. + + *package* is either a name or a module object which conforms to the + ``Package`` requirements. + + .. deprecated:: 3.11 + + Calls to this function can be replaced by:: + + (resource.name for resource in files(package).iterdir() if resource.is_file()) diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 6b71e64bcbf..3fc1531c0cd 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -13,10 +13,13 @@ -------------- + Introduction ------------ -The purpose of the :mod:`importlib` package is two-fold. One is to provide the +The purpose of the :mod:`importlib` package is three-fold. + +One is to provide the implementation of the :keyword:`import` statement (and thus, by extension, the :func:`__import__` function) in Python source code. This provides an implementation of :keyword:`!import` which is portable to any Python @@ -27,6 +30,14 @@ Two, the components to implement :keyword:`import` are exposed in this package, making it easier for users to create their own custom objects (known generically as an :term:`importer`) to participate in the import process. +Three, the package contains modules exposing additional functionality for +managing aspects of Python packages: + +* :mod:`importlib.metadata` presents access to metadata from third-party + distributions. +* :mod:`importlib.resources` provides routines for accessing non-code + "resources" from Python packages. + .. seealso:: :ref:`import` @@ -40,6 +51,9 @@ generically as an :term:`importer`) to participate in the import process. The :func:`.__import__` function The :keyword:`import` statement is syntactic sugar for this function. + :ref:`sys-path-init` + The initialization of :data:`sys.path`. + :pep:`235` Import on Case-Insensitive Platforms @@ -145,6 +159,10 @@ Functions .. versionadded:: 3.3 + .. versionchanged:: 3.10 + Namespace packages created/installed in a different :data:`sys.path` + location after the same namespace was already imported are noticed. + .. function:: reload(module) Reload a previously imported *module*. The argument must be a module object, @@ -230,8 +248,8 @@ ABC hierarchy:: object +-- Finder (deprecated) - | +-- MetaPathFinder - | +-- PathEntryFinder + +-- MetaPathFinder + +-- PathEntryFinder +-- Loader +-- ResourceLoader --------+ +-- InspectLoader | @@ -264,8 +282,7 @@ ABC hierarchy:: .. class:: MetaPathFinder - An abstract base class representing a :term:`meta path finder`. For - compatibility, this is a subclass of :class:`Finder`. + An abstract base class representing a :term:`meta path finder`. .. versionadded:: 3.3 @@ -384,7 +401,7 @@ ABC hierarchy:: Loaders that wish to support resource reading should implement a :meth:`get_resource_reader` method as specified by - :class:`importlib.abc.ResourceReader`. + :class:`importlib.resources.abc.ResourceReader`. .. versionchanged:: 3.7 Introduced the optional :meth:`get_resource_reader` method. @@ -397,8 +414,8 @@ ABC hierarchy:: .. versionadded:: 3.4 - .. versionchanged:: 3.5 - Starting in Python 3.6, this method will not be optional when + .. versionchanged:: 3.6 + This method is no longer optional when :meth:`exec_module` is defined. .. method:: exec_module(module) @@ -426,14 +443,14 @@ ABC hierarchy:: from the import. If the loader inserted a module and the load fails, it must be removed by the loader from :data:`sys.modules`; modules already in :data:`sys.modules` before the loader began execution should be left - alone (see :func:`importlib.util.module_for_loader`). + alone. The loader should set several attributes on the module (note that some of these attributes can change when a module is reloaded): - :attr:`__name__` - The module's fully-qualified name. + The module's fully qualified name. It is ``'__main__'`` for an executed module. - :attr:`__file__` @@ -454,7 +471,7 @@ ABC hierarchy:: as an indicator that the module is a package. - :attr:`__package__` - The fully-qualified name of the package the module is in (or the + The fully qualified name of the package the module is in (or the empty string for a top-level module). If the module is a package then this is the same as :attr:`__name__`. @@ -476,94 +493,6 @@ ABC hierarchy:: other responsibilities of :meth:`load_module` when :meth:`exec_module` is implemented. - .. method:: module_repr(module) - - A legacy method which when implemented calculates and returns the given - module's representation, as a string. The module type's default - :meth:`__repr__` will use the result of this method as appropriate. - - .. versionadded:: 3.3 - - .. versionchanged:: 3.4 - Made optional instead of an abstractmethod. - - .. deprecated:: 3.4 - The import machinery now takes care of this automatically. - - -.. class:: ResourceReader - - *Superseded by TraversableResources* - - An :term:`abstract base class` to provide the ability to read - *resources*. - - From the perspective of this ABC, a *resource* is a binary - artifact that is shipped within a package. Typically this is - something like a data file that lives next to the ``__init__.py`` - file of the package. The purpose of this class is to help abstract - out the accessing of such data files so that it does not matter if - the package and its data file(s) are stored in a e.g. zip file - versus on the file system. - - For any of methods of this class, a *resource* argument is - expected to be a :term:`path-like object` which represents - conceptually just a file name. This means that no subdirectory - paths should be included in the *resource* argument. This is - because the location of the package the reader is for, acts as the - "directory". Hence the metaphor for directories and file - names is packages and resources, respectively. This is also why - instances of this class are expected to directly correlate to - a specific package (instead of potentially representing multiple - packages or a module). - - Loaders that wish to support resource reading are expected to - provide a method called ``get_resource_reader(fullname)`` which - returns an object implementing this ABC's interface. If the module - specified by fullname is not a package, this method should return - :const:`None`. An object compatible with this ABC should only be - returned when the specified module is a package. - - .. versionadded:: 3.7 - - .. abstractmethod:: open_resource(resource) - - Returns an opened, :term:`file-like object` for binary reading - of the *resource*. - - If the resource cannot be found, :exc:`FileNotFoundError` is - raised. - - .. abstractmethod:: resource_path(resource) - - Returns the file system path to the *resource*. - - If the resource does not concretely exist on the file system, - raise :exc:`FileNotFoundError`. - - .. abstractmethod:: is_resource(name) - - Returns ``True`` if the named *name* is considered a resource. - :exc:`FileNotFoundError` is raised if *name* does not exist. - - .. abstractmethod:: contents() - - Returns an :term:`iterable` of strings over the contents of - the package. Do note that it is not required that all names - returned by the iterator be actual resources, e.g. it is - acceptable to return names for which :meth:`is_resource` would - be false. - - Allowing non-resource names to be returned is to allow for - situations where how a package and its resources are stored - are known a priori and the non-resource names would be useful. - For instance, returning subdirectory names is allowed so that - when it is known that the package and resources are stored on - the file system then those subdirectory names can be used - directly. - - The abstract method returns an iterable of no items. - .. class:: ResourceLoader @@ -573,7 +502,7 @@ ABC hierarchy:: .. deprecated:: 3.7 This ABC is deprecated in favour of supporting resource loading - through :class:`importlib.abc.ResourceReader`. + through :class:`importlib.resources.abc.ResourceReader`. .. abstractmethod:: get_data(path) @@ -810,244 +739,6 @@ ABC hierarchy:: itself does not end in ``__init__``. -.. class:: Traversable - - An object with a subset of pathlib.Path methods suitable for - traversing directories and opening files. - - .. versionadded:: 3.9 - - .. attribute:: name - - Abstract. The base name of this object without any parent references. - - .. abstractmethod:: iterdir() - - Yield Traversable objects in self. - - .. abstractmethod:: is_dir() - - Return True if self is a directory. - - .. abstractmethod:: is_file() - - Return True if self is a file. - - .. abstractmethod:: joinpath(child) - - Return Traversable child in self. - - .. abstractmethod:: __truediv__(child) - - Return Traversable child in self. - - .. abstractmethod:: open(mode='r', *args, **kwargs) - - *mode* may be 'r' or 'rb' to open as text or binary. Return a handle - suitable for reading (same as :attr:`pathlib.Path.open`). - - When opening as text, accepts encoding parameters such as those - accepted by :attr:`io.TextIOWrapper`. - - .. method:: read_bytes() - - Read contents of self as bytes. - - .. method:: read_text(encoding=None) - - Read contents of self as text. - - -.. class:: TraversableResources - - An abstract base class for resource readers capable of serving - the :meth:`importlib.resources.files` interface. Subclasses - :class:`importlib.abc.ResourceReader` and provides - concrete implementations of the :class:`importlib.abc.ResourceReader`'s - abstract methods. Therefore, any loader supplying - :class:`importlib.abc.TraversableReader` also supplies ResourceReader. - - Loaders that wish to support resource reading are expected to - implement this interface. - - .. versionadded:: 3.9 - - .. abstractmethod:: files() - - Returns a :class:`importlib.abc.Traversable` object for the loaded - package. - - -:mod:`importlib.resources` -- Resources ---------------------------------------- - -.. module:: importlib.resources - :synopsis: Package resource reading, opening, and access - -**Source code:** :source:`Lib/importlib/resources.py` - --------------- - -.. versionadded:: 3.7 - -This module leverages Python's import system to provide access to *resources* -within *packages*. If you can import a package, you can access resources -within that package. Resources can be opened or read, in either binary or -text mode. - -Resources are roughly akin to files inside directories, though it's important -to keep in mind that this is just a metaphor. Resources and packages **do -not** have to exist as physical files and directories on the file system. - -.. note:: - - This module provides functionality similar to `pkg_resources - `_ `Basic - Resource Access - `_ - without the performance overhead of that package. This makes reading - resources included in packages easier, with more stable and consistent - semantics. - - The standalone backport of this module provides more information - on `using importlib.resources - `_ and - `migrating from pkg_resources to importlib.resources - `_. - -Loaders that wish to support resource reading should implement a -``get_resource_reader(fullname)`` method as specified by -:class:`importlib.abc.ResourceReader`. - -The following types are defined. - -.. data:: Package - - The ``Package`` type is defined as ``Union[str, ModuleType]``. This means - that where the function describes accepting a ``Package``, you can pass in - either a string or a module. Module objects must have a resolvable - ``__spec__.submodule_search_locations`` that is not ``None``. - -.. data:: Resource - - This type describes the resource names passed into the various functions - in this package. This is defined as ``Union[str, os.PathLike]``. - - -The following functions are available. - - -.. function:: files(package) - - Returns an :class:`importlib.resources.abc.Traversable` object - representing the resource container for the package (think directory) - and its resources (think files). A Traversable may contain other - containers (think subdirectories). - - *package* is either a name or a module object which conforms to the - ``Package`` requirements. - - .. versionadded:: 3.9 - -.. function:: as_file(traversable) - - Given a :class:`importlib.resources.abc.Traversable` object representing - a file, typically from :func:`importlib.resources.files`, return - a context manager for use in a :keyword:`with` statement. - The context manager provides a :class:`pathlib.Path` object. - - Exiting the context manager cleans up any temporary file created when the - resource was extracted from e.g. a zip file. - - Use ``as_file`` when the Traversable methods - (``read_text``, etc) are insufficient and an actual file on - the file system is required. - - .. versionadded:: 3.9 - -.. function:: open_binary(package, resource) - - Open for binary reading the *resource* within *package*. - - *package* is either a name or a module object which conforms to the - ``Package`` requirements. *resource* is the name of the resource to open - within *package*; it may not contain path separators and it may not have - sub-resources (i.e. it cannot be a directory). This function returns a - ``typing.BinaryIO`` instance, a binary I/O stream open for reading. - - -.. function:: open_text(package, resource, encoding='utf-8', errors='strict') - - Open for text reading the *resource* within *package*. By default, the - resource is opened for reading as UTF-8. - - *package* is either a name or a module object which conforms to the - ``Package`` requirements. *resource* is the name of the resource to open - within *package*; it may not contain path separators and it may not have - sub-resources (i.e. it cannot be a directory). *encoding* and *errors* - have the same meaning as with built-in :func:`open`. - - This function returns a ``typing.TextIO`` instance, a text I/O stream open - for reading. - - -.. function:: read_binary(package, resource) - - Read and return the contents of the *resource* within *package* as - ``bytes``. - - *package* is either a name or a module object which conforms to the - ``Package`` requirements. *resource* is the name of the resource to open - within *package*; it may not contain path separators and it may not have - sub-resources (i.e. it cannot be a directory). This function returns the - contents of the resource as :class:`bytes`. - - -.. function:: read_text(package, resource, encoding='utf-8', errors='strict') - - Read and return the contents of *resource* within *package* as a ``str``. - By default, the contents are read as strict UTF-8. - - *package* is either a name or a module object which conforms to the - ``Package`` requirements. *resource* is the name of the resource to open - within *package*; it may not contain path separators and it may not have - sub-resources (i.e. it cannot be a directory). *encoding* and *errors* - have the same meaning as with built-in :func:`open`. This function - returns the contents of the resource as :class:`str`. - - -.. function:: path(package, resource) - - Return the path to the *resource* as an actual file system path. This - function returns a context manager for use in a :keyword:`with` statement. - The context manager provides a :class:`pathlib.Path` object. - - Exiting the context manager cleans up any temporary file created when the - resource needs to be extracted from e.g. a zip file. - - *package* is either a name or a module object which conforms to the - ``Package`` requirements. *resource* is the name of the resource to open - within *package*; it may not contain path separators and it may not have - sub-resources (i.e. it cannot be a directory). - - -.. function:: is_resource(package, name) - - Return ``True`` if there is a resource named *name* in the package, - otherwise ``False``. Remember that directories are *not* resources! - *package* is either a name or a module object which conforms to the - ``Package`` requirements. - - -.. function:: contents(package) - - Return an iterable over the named items within the package. The iterable - returns :class:`str` resources (e.g. files) and non-resources - (e.g. directories). The iterable does not recurse into subdirectories. - - *package* is either a name or a module object which conforms to the - ``Package`` requirements. - :mod:`importlib.machinery` -- Importers and path hooks ------------------------------------------------------ @@ -1437,7 +1128,7 @@ find and load modules. (:attr:`__name__`) - The module's fully-qualified name. + The module's fully qualified name. The :term:`finder` should always set this attribute to a non-empty string. .. attribute:: loader @@ -1486,7 +1177,7 @@ find and load modules. (:attr:`__package__`) - (Read-only) The fully-qualified name of the package the module is in (or the + (Read-only) The fully qualified name of the package the module is in (or the empty string for a top-level module). If the module is a package then this is the same as :attr:`name`. @@ -1635,67 +1326,6 @@ an :term:`importer`. .. versionadded:: 3.5 -.. decorator:: module_for_loader - - A :term:`decorator` for :meth:`importlib.abc.Loader.load_module` - to handle selecting the proper - module object to load with. The decorated method is expected to have a call - signature taking two positional arguments - (e.g. ``load_module(self, module)``) for which the second argument - will be the module **object** to be used by the loader. - Note that the decorator will not work on static methods because of the - assumption of two arguments. - - The decorated method will take in the **name** of the module to be loaded - as expected for a :term:`loader`. If the module is not found in - :data:`sys.modules` then a new one is constructed. Regardless of where the - module came from, :attr:`__loader__` set to **self** and :attr:`__package__` - is set based on what :meth:`importlib.abc.InspectLoader.is_package` returns - (if available). These attributes are set unconditionally to support - reloading. - - If an exception is raised by the decorated method and a module was added to - :data:`sys.modules`, then the module will be removed to prevent a partially - initialized module from being in left in :data:`sys.modules`. If the module - was already in :data:`sys.modules` then it is left alone. - - .. versionchanged:: 3.3 - :attr:`__loader__` and :attr:`__package__` are automatically set - (when possible). - - .. versionchanged:: 3.4 - Set :attr:`__name__`, :attr:`__loader__` :attr:`__package__` - unconditionally to support reloading. - - .. deprecated:: 3.4 - The import machinery now directly performs all the functionality - provided by this function. - -.. decorator:: set_loader - - A :term:`decorator` for :meth:`importlib.abc.Loader.load_module` - to set the :attr:`__loader__` - attribute on the returned module. If the attribute is already set the - decorator does nothing. It is assumed that the first positional argument to - the wrapped method (i.e. ``self``) is what :attr:`__loader__` should be set - to. - - .. versionchanged:: 3.4 - Set ``__loader__`` if set to ``None``, as if the attribute does not - exist. - - .. deprecated:: 3.4 - The import machinery takes care of this automatically. - -.. decorator:: set_package - - A :term:`decorator` for :meth:`importlib.abc.Loader.load_module` to set the - :attr:`__package__` attribute on the returned module. If :attr:`__package__` - is set and has a value other than ``None`` it will not be changed. - - .. deprecated:: 3.4 - The import machinery takes care of this automatically. - .. function:: spec_from_loader(name, loader, *, origin=None, is_package=None) A factory function for creating a :class:`~importlib.machinery.ModuleSpec` @@ -1788,6 +1418,9 @@ Checking if a module can be imported If you need to find out if a module can be imported without actually doing the import, then you should use :func:`importlib.util.find_spec`. + +Note that if ``name`` is a submodule (contains a dot), +:func:`importlib.util.find_spec` will import the parent module. :: import importlib.util @@ -1811,8 +1444,7 @@ import, then you should use :func:`importlib.util.find_spec`. Importing a source file directly '''''''''''''''''''''''''''''''' -To import a Python source file directly, use the following recipe -(Python 3.5 and newer only):: +To import a Python source file directly, use the following recipe:: import importlib.util import sys @@ -1893,9 +1525,7 @@ Import itself is implemented in Python code, making it possible to expose most of the import machinery through importlib. The following helps illustrate the various APIs that importlib exposes by providing an approximate implementation of -:func:`importlib.import_module` (Python 3.4 and newer for the importlib usage, -Python 3.6 and newer for other parts of the code). -:: +:func:`importlib.import_module`:: import importlib.util import sys diff --git a/Doc/library/index.rst b/Doc/library/index.rst index db8f0d9bdfb..d064b680f9a 100644 --- a/Doc/library/index.rst +++ b/Doc/library/index.rst @@ -27,8 +27,8 @@ as a collection of packages, so it may be necessary to use the packaging tools provided with the operating system to obtain some or all of the optional components. -In addition to the standard library, there is a growing collection of -several thousand components (from individual programs and modules to +In addition to the standard library, there is an active collection of +hundreds of thousands of components (from individual programs and modules to packages and entire application development frameworks), available from the `Python Package Index `_. @@ -74,5 +74,4 @@ the `Python Package Index `_. windows.rst unix.rst superseded.rst - undoc.rst security_warnings.rst diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 1074f977184..58b84a35a89 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -32,7 +32,7 @@ The :func:`getmembers` function retrieves the members of an object such as a class or module. The functions whose names begin with "is" are mainly provided as convenient choices for the second argument to :func:`getmembers`. They also help you determine when you can expect to find the following special -attributes: +attributes (see :ref:`import-mod-attrs` for module attributes): .. this function name is too big to fit in the ascii-art table below .. |coroutine-origin-link| replace:: :func:`sys.set_coroutine_origin_tracking_depth` @@ -40,11 +40,6 @@ attributes: +-----------+-------------------+---------------------------+ | Type | Attribute | Description | +===========+===================+===========================+ -| module | __doc__ | documentation string | -+-----------+-------------------+---------------------------+ -| | __file__ | filename (missing for | -| | | built-in modules) | -+-----------+-------------------+---------------------------+ | class | __doc__ | documentation string | +-----------+-------------------+---------------------------+ | | __name__ | name with which this | @@ -187,12 +182,13 @@ attributes: | | co_name | name with which this code | | | | object was defined | +-----------+-------------------+---------------------------+ -| | co_qualname | fully-qualified name with | +| | co_qualname | fully qualified name with | | | | which this code object | | | | was defined | +-----------+-------------------+---------------------------+ -| | co_names | tuple of names of local | -| | | variables | +| | co_names | tuple of names other | +| | | than arguments and | +| | | function locals | +-----------+-------------------+---------------------------+ | | co_nlocals | number of local variables | +-----------+-------------------+---------------------------+ @@ -275,6 +271,24 @@ attributes: listed in the metaclass' custom :meth:`__dir__`. +.. function:: getmembers_static(object[, predicate]) + + Return all the members of an object in a list of ``(name, value)`` + pairs sorted by name without triggering dynamic lookup via the descriptor + protocol, __getattr__ or __getattribute__. Optionally, only return members + that satisfy a given predicate. + + .. note:: + + :func:`getmembers_static` may not be able to retrieve all members + that getmembers can fetch (like dynamically created attributes) + and may find members that getmembers can't (like descriptors + that raise AttributeError). It can also return descriptor objects + instead of instance members in some cases. + + .. versionadded:: 3.11 + + .. function:: getmodulename(path) Return the name of the module named by the file *path*, without including the @@ -329,8 +343,10 @@ attributes: .. function:: iscoroutinefunction(object) - Return ``True`` if the object is a :term:`coroutine function` - (a function defined with an :keyword:`async def` syntax). + Return ``True`` if the object is a :term:`coroutine function` (a function + defined with an :keyword:`async def` syntax), a :func:`functools.partial` + wrapping a :term:`coroutine function`, or a sync function marked with + :func:`markcoroutinefunction`. .. versionadded:: 3.5 @@ -338,6 +354,25 @@ attributes: Functions wrapped in :func:`functools.partial` now return ``True`` if the wrapped function is a :term:`coroutine function`. + .. versionchanged:: 3.12 + Sync functions marked with :func:`markcoroutinefunction` now return + ``True``. + + +.. function:: markcoroutinefunction(func) + + Decorator to mark a callable as a :term:`coroutine function` if it would not + otherwise be detected by :func:`iscoroutinefunction`. + + This may be of use for sync functions that return a :term:`coroutine`, if + the function is passed to an API that requires :func:`iscoroutinefunction`. + + When possible, using an :keyword:`async def` function is preferred. Also + acceptable is calling the function and testing the return with + :func:`iscoroutine`. + + .. versionadded:: 3.12 + .. function:: iscoroutine(object) @@ -411,6 +446,16 @@ attributes: Return ``True`` if the object is a built-in function or a bound built-in method. +.. function:: ismethodwrapper(object) + + Return ``True`` if the type of object is a :class:`~types.MethodWrapperType`. + + These are instances of :class:`~types.MethodWrapperType`, such as :meth:`~object.__str__`, + :meth:`~object.__eq__` and :meth:`~object.__repr__`. + + .. versionadded:: 3.11 + + .. function:: isroutine(object) Return ``True`` if the object is a user-defined or built-in function or method. @@ -485,6 +530,7 @@ Retrieving source code If the documentation string for an object is not provided and the object is a class, a method, a property or a descriptor, retrieve the documentation string from the inheritance hierarchy. + Return ``None`` if the documentation string is invalid or missing. .. versionchanged:: 3.5 Documentation strings are now inherited if not overridden. @@ -508,12 +554,14 @@ Retrieving source code .. function:: getmodule(object) - Try to guess which module an object was defined in. + Try to guess which module an object was defined in. Return ``None`` + if the module cannot be determined. .. function:: getsourcefile(object) - Return the name of the Python source file in which an object was defined. This + Return the name of the Python source file in which an object was defined + or ``None`` if no way can be identified to get the source. This will fail with a :exc:`TypeError` if the object is a built-in module, class, or function. @@ -688,6 +736,7 @@ function. >>> def test(a, b): ... pass + ... >>> sig = signature(test) >>> new_sig = sig.replace(return_annotation="new return anno") >>> str(new_sig) @@ -1027,6 +1076,7 @@ Classes and functions >>> from inspect import getcallargs >>> def f(a, b=1, *pos, **named): ... pass + ... >>> getcallargs(f, 1, 2, 3) == {'a': 1, 'named': {}, 'b': 2, 'pos': (3,)} True >>> getcallargs(f, a=2, x=4) == {'a': 2, 'named': {'x': 4}, 'b': 1, 'pos': ()} @@ -1100,7 +1150,7 @@ Classes and functions doesn't have its own annotations dict, returns an empty dict. * All accesses to object members and dict values are done using ``getattr()`` and ``dict.get()`` for safety. - * Always, always, always returns a freshly-created dict. + * Always, always, always returns a freshly created dict. ``eval_str`` controls whether or not values of type ``str`` are replaced with the result of calling :func:`eval()` on those values: @@ -1136,16 +1186,90 @@ Classes and functions The interpreter stack --------------------- -When the following functions return "frame records," each record is a -:term:`named tuple` -``FrameInfo(frame, filename, lineno, function, code_context, index)``. -The tuple contains the frame object, the filename, the line number of the -current line, -the function name, a list of lines of context from the source code, and the -index of the current line within that list. +Some of the following functions return +:class:`FrameInfo` objects. For backwards compatibility these objects allow +tuple-like operations on all attributes except ``positions``. This behavior +is considered deprecated and may be removed in the future. + +.. class:: FrameInfo + + .. attribute:: frame + + The :ref:`frame object ` that the record corresponds to. + + .. attribute:: filename + + The file name associated with the code being executed by the frame this record + corresponds to. + + .. attribute:: lineno + + The line number of the current line associated with the code being + executed by the frame this record corresponds to. + + .. attribute:: function + + The function name that is being executed by the frame this record corresponds to. + + .. attribute:: code_context + + A list of lines of context from the source code that's being executed by the frame + this record corresponds to. + + .. attribute:: index + + The index of the current line being executed in the :attr:`code_context` list. + + .. attribute:: positions + + A :class:`dis.Positions` object containing the start line number, end line + number, start column offset, and end column offset associated with the + instruction being executed by the frame this record corresponds to. + + .. versionchanged:: 3.5 + Return a :term:`named tuple` instead of a :class:`tuple`. + + .. versionchanged:: 3.11 + :class:`!FrameInfo` is now a class instance + (that is backwards compatible with the previous :term:`named tuple`). + + +.. class:: Traceback + + .. attribute:: filename + + The file name associated with the code being executed by the frame this traceback + corresponds to. + + .. attribute:: lineno + + The line number of the current line associated with the code being + executed by the frame this traceback corresponds to. + + .. attribute:: function + + The function name that is being executed by the frame this traceback corresponds to. + + .. attribute:: code_context + + A list of lines of context from the source code that's being executed by the frame + this traceback corresponds to. + + .. attribute:: index + + The index of the current line being executed in the :attr:`code_context` list. + + .. attribute:: positions + + A :class:`dis.Positions` object containing the start line number, end + line number, start column offset, and end column offset associated with + the instruction being executed by the frame this traceback corresponds + to. + + .. versionchanged:: 3.11 + :class:`!Traceback` is now a class instance + (that is backwards compatible with the previous :term:`named tuple`). -.. versionchanged:: 3.5 - Return a named tuple instead of a tuple. .. note:: @@ -1180,35 +1304,41 @@ line. .. function:: getframeinfo(frame, context=1) - Get information about a frame or traceback object. A :term:`named tuple` - ``Traceback(filename, lineno, function, code_context, index)`` is returned. + Get information about a frame or traceback object. A :class:`Traceback` object + is returned. + .. versionchanged:: 3.11 + A :class:`Traceback` object is returned instead of a named tuple. .. function:: getouterframes(frame, context=1) - Get a list of frame records for a frame and all outer frames. These frames - represent the calls that lead to the creation of *frame*. The first entry in the - returned list represents *frame*; the last entry represents the outermost call - on *frame*'s stack. + Get a list of :class:`FrameInfo` objects for a frame and all outer frames. + These frames represent the calls that lead to the creation of *frame*. The + first entry in the returned list represents *frame*; the last entry + represents the outermost call on *frame*'s stack. .. versionchanged:: 3.5 A list of :term:`named tuples ` ``FrameInfo(frame, filename, lineno, function, code_context, index)`` is returned. + .. versionchanged:: 3.11 + A list of :class:`FrameInfo` objects is returned. .. function:: getinnerframes(traceback, context=1) - Get a list of frame records for a traceback's frame and all inner frames. These - frames represent calls made as a consequence of *frame*. The first entry in the - list represents *traceback*; the last entry represents where the exception was - raised. + Get a list of :class:`FrameInfo` objects for a traceback's frame and all + inner frames. These frames represent calls made as a consequence of *frame*. + The first entry in the list represents *traceback*; the last entry represents + where the exception was raised. .. versionchanged:: 3.5 A list of :term:`named tuples ` ``FrameInfo(frame, filename, lineno, function, code_context, index)`` is returned. + .. versionchanged:: 3.11 + A list of :class:`FrameInfo` objects is returned. .. function:: currentframe() @@ -1224,28 +1354,32 @@ line. .. function:: stack(context=1) - Return a list of frame records for the caller's stack. The first entry in the - returned list represents the caller; the last entry represents the outermost - call on the stack. + Return a list of :class:`FrameInfo` objects for the caller's stack. The + first entry in the returned list represents the caller; the last entry + represents the outermost call on the stack. .. versionchanged:: 3.5 A list of :term:`named tuples ` ``FrameInfo(frame, filename, lineno, function, code_context, index)`` is returned. + .. versionchanged:: 3.11 + A list of :class:`FrameInfo` objects is returned. .. function:: trace(context=1) - Return a list of frame records for the stack between the current frame and the - frame in which an exception currently being handled was raised in. The first - entry in the list represents the caller; the last entry represents where the - exception was raised. + Return a list of :class:`FrameInfo` objects for the stack between the current + frame and the frame in which an exception currently being handled was raised + in. The first entry in the list represents the caller; the last entry + represents where the exception was raised. .. versionchanged:: 3.5 A list of :term:`named tuples ` ``FrameInfo(frame, filename, lineno, function, code_context, index)`` is returned. + .. versionchanged:: 3.11 + A list of :class:`FrameInfo` objects is returned. Fetching attributes statically ------------------------------ diff --git a/Doc/library/internet.rst b/Doc/library/internet.rst index 65693c9b3b2..ff58dcf4d89 100644 --- a/Doc/library/internet.rst +++ b/Doc/library/internet.rst @@ -20,8 +20,6 @@ is currently supported on most popular platforms. Here is an overview: .. toctree:: webbrowser.rst - cgi.rst - cgitb.rst wsgiref.rst urllib.rst urllib.request.rst @@ -33,9 +31,7 @@ is currently supported on most popular platforms. Here is an overview: ftplib.rst poplib.rst imaplib.rst - nntplib.rst smtplib.rst - telnetlib.rst uuid.rst socketserver.rst http.server.rst diff --git a/Doc/library/intro.rst b/Doc/library/intro.rst index 5bb33b9c10c..5a4c9b8b16a 100644 --- a/Doc/library/intro.rst +++ b/Doc/library/intro.rst @@ -60,3 +60,62 @@ Notes on availability * If not separately noted, all functions that claim "Availability: Unix" are supported on macOS, which builds on a Unix core. +* If an availability note contains both a minimum Kernel version and a minimum + libc version, then both conditions must hold. For example a feature with note + *Availability: Linux >= 3.17 with glibc >= 2.27* requires both Linux 3.17 or + newer and glibc 2.27 or newer. + +.. _wasm-availability: + +WebAssembly platforms +--------------------- + +The `WebAssembly`_ platforms ``wasm32-emscripten`` (`Emscripten`_) and +``wasm32-wasi`` (`WASI`_) provide a subset of POSIX APIs. WebAssembly runtimes +and browsers are sandboxed and have limited access to the host and external +resources. Any Python standard library module that uses processes, threading, +networking, signals, or other forms of inter-process communication (IPC), is +either not available or may not work as on other Unix-like systems. File I/O, +file system, and Unix permission-related functions are restricted, too. +Emscripten does not permit blocking I/O. Other blocking operations like +:func:`~time.sleep` block the browser event loop. + +The properties and behavior of Python on WebAssembly platforms depend on the +`Emscripten`_-SDK or `WASI`_-SDK version, WASM runtimes (browser, NodeJS, +`wasmtime`_), and Python build time flags. WebAssembly, Emscripten, and WASI +are evolving standards; some features like networking may be +supported in the future. + +For Python in the browser, users should consider `Pyodide`_ or `PyScript`_. +PyScript is built on top of Pyodide, which itself is built on top of +CPython and Emscripten. Pyodide provides access to browsers' JavaScript and +DOM APIs as well as limited networking capabilities with JavaScript's +``XMLHttpRequest`` and ``Fetch`` APIs. + +* Process-related APIs are not available or always fail with an error. That + includes APIs that spawn new processes (:func:`~os.fork`, + :func:`~os.execve`), wait for processes (:func:`~os.waitpid`), send signals + (:func:`~os.kill`), or otherwise interact with processes. The + :mod:`subprocess` is importable but does not work. + +* The :mod:`socket` module is available, but is limited and behaves + differently from other platforms. On Emscripten, sockets are always + non-blocking and require additional JavaScript code and helpers on the + server to proxy TCP through WebSockets; see `Emscripten Networking`_ + for more information. WASI snapshot preview 1 only permits sockets from an + existing file descriptor. + +* Some functions are stubs that either don't do anything and always return + hardcoded values. + +* Functions related to file descriptors, file permissions, file ownership, and + links are limited and don't support some operations. For example, WASI does + not permit symlinks with absolute file names. + +.. _WebAssembly: https://webassembly.org/ +.. _Emscripten: https://emscripten.org/ +.. _Emscripten Networking: https://emscripten.org/docs/porting/networking.html +.. _WASI: https://wasi.dev/ +.. _wasmtime: https://wasmtime.dev/ +.. _Pyodide: https://pyodide.org/ +.. _PyScript: https://pyscript.net/ diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 0881015c7fa..c9249da1c3c 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -112,7 +112,7 @@ Text Encoding ------------- The default encoding of :class:`TextIOWrapper` and :func:`open` is -locale-specific (:func:`locale.getpreferredencoding(False) `). +locale-specific (:func:`locale.getencoding`). However, many developers forget to specify the encoding when opening text files encoded in UTF-8 (e.g. JSON, TOML, Markdown, etc...) since most Unix @@ -123,17 +123,19 @@ encoding is not UTF-8 for most Windows users. For example:: with open("README.md") as f: long_description = f.read() -Additionally, while there is no concrete plan as of yet, Python may change -the default text file encoding to UTF-8 in the future. - Accordingly, it is highly recommended that you specify the encoding explicitly when opening text files. If you want to use UTF-8, pass ``encoding="utf-8"``. To use the current locale encoding, -``encoding="locale"`` is supported in Python 3.10. +``encoding="locale"`` is supported since Python 3.10. -When you need to run existing code on Windows that attempts to opens -UTF-8 files using the default locale encoding, you can enable the UTF-8 -mode. See :ref:`UTF-8 mode on Windows `. +.. seealso:: + + :ref:`utf8-mode` + Python UTF-8 Mode can be used to change the default encoding to + UTF-8 from locale-specific encoding. + + :pep:`686` + Python 3.15 will make :ref:`utf8-mode` default. .. _io-encoding-warning: @@ -193,17 +195,18 @@ High-level Module Interface .. versionadded:: 3.8 -.. function:: text_encoding(encoding, stacklevel=2) +.. function:: text_encoding(encoding, stacklevel=2, /) This is a helper function for callables that use :func:`open` or :class:`TextIOWrapper` and have an ``encoding=None`` parameter. - This function returns *encoding* if it is not ``None`` and ``"locale"`` if - *encoding* is ``None``. + This function returns *encoding* if it is not ``None``. + Otherwise, it returns ``"locale"`` or ``"utf-8"`` depending on + :ref:`UTF-8 Mode `. This function emits an :class:`EncodingWarning` if :data:`sys.flags.warn_default_encoding ` is true and *encoding* - is None. *stacklevel* specifies where the warning is emitted. + is ``None``. *stacklevel* specifies where the warning is emitted. For example:: def read_text(path, encoding=None): @@ -218,6 +221,10 @@ High-level Module Interface .. versionadded:: 3.10 + .. versionchanged:: 3.11 + :func:`text_encoding` returns "utf-8" when UTF-8 mode is enabled and + *encoding* is ``None``. + .. exception:: BlockingIOError @@ -265,7 +272,7 @@ to provide an interface to files in the machine's file system. The :class:`BufferedIOBase` ABC extends :class:`IOBase`. It deals with buffering on a raw binary stream (:class:`RawIOBase`). Its subclasses, :class:`BufferedWriter`, :class:`BufferedReader`, and :class:`BufferedRWPair` -buffer raw binary streams that are readable, writable, and both readable and writable, +buffer raw binary streams that are writable, readable, and both readable and writable, respectively. :class:`BufferedRandom` provides a buffered interface to seekable streams. Another :class:`BufferedIOBase` subclass, :class:`BytesIO`, is a stream of in-memory bytes. @@ -306,8 +313,7 @@ I/O Base Classes .. class:: IOBase - The abstract base class for all I/O classes, acting on streams of bytes. - There is no public constructor. + The abstract base class for all I/O classes. This class provides empty abstract implementations for many methods that derived classes can override selectively; the default @@ -376,7 +382,7 @@ I/O Base Classes Return ``True`` if the stream can be read from. If ``False``, :meth:`read` will raise :exc:`OSError`. - .. method:: readline(size=-1) + .. method:: readline(size=-1, /) Read and return one line from the stream. If *size* is specified, at most *size* bytes will be read. @@ -385,7 +391,7 @@ I/O Base Classes the *newline* argument to :func:`open` can be used to select the line terminator(s) recognized. - .. method:: readlines(hint=-1) + .. method:: readlines(hint=-1, /) Read and return a list of lines from the stream. *hint* can be specified to control the number of lines read: no more lines will be read if the @@ -397,7 +403,7 @@ I/O Base Classes Note that it's already possible to iterate on file objects using ``for line in file: ...`` without calling ``file.readlines()``. - .. method:: seek(offset, whence=SEEK_SET) + .. method:: seek(offset, whence=SEEK_SET, /) Change the stream position to the given byte *offset*. *offset* is interpreted relative to the position indicated by *whence*. The default @@ -429,7 +435,7 @@ I/O Base Classes Return the current stream position. - .. method:: truncate(size=None) + .. method:: truncate(size=None, /) Resize the stream to the given *size* in bytes (or the current position if *size* is not specified). The current stream position isn't changed. @@ -446,7 +452,7 @@ I/O Base Classes Return ``True`` if the stream supports writing. If ``False``, :meth:`write` and :meth:`truncate` will raise :exc:`OSError`. - .. method:: writelines(lines) + .. method:: writelines(lines, /) Write a list of lines to the stream. Line separators are not added, so it is usual for each of the lines provided to have a line separator at the @@ -461,8 +467,7 @@ I/O Base Classes .. class:: RawIOBase - Base class for raw binary streams. It inherits :class:`IOBase`. There is no - public constructor. + Base class for raw binary streams. It inherits :class:`IOBase`. Raw binary streams typically provide low-level access to an underlying OS device or API, and do not try to encapsulate it in high-level primitives @@ -472,7 +477,7 @@ I/O Base Classes :class:`RawIOBase` provides these methods in addition to those from :class:`IOBase`: - .. method:: read(size=-1) + .. method:: read(size=-1, /) Read up to *size* bytes from the object and return them. As a convenience, if *size* is unspecified or -1, all bytes until EOF are returned. @@ -491,7 +496,7 @@ I/O Base Classes Read and return all the bytes from the stream until EOF, using multiple calls to the stream if necessary. - .. method:: readinto(b) + .. method:: readinto(b, /) Read bytes into a pre-allocated, writable :term:`bytes-like object` *b*, and return the @@ -499,7 +504,7 @@ I/O Base Classes If the object is in non-blocking mode and no bytes are available, ``None`` is returned. - .. method:: write(b) + .. method:: write(b, /) Write the given :term:`bytes-like object`, *b*, to the underlying raw stream, and return the number of @@ -515,7 +520,7 @@ I/O Base Classes .. class:: BufferedIOBase Base class for binary streams that support some kind of buffering. - It inherits :class:`IOBase`. There is no public constructor. + It inherits :class:`IOBase`. The main difference with :class:`RawIOBase` is that methods :meth:`read`, :meth:`readinto` and :meth:`write` will try (respectively) to read as much @@ -556,7 +561,7 @@ I/O Base Classes .. versionadded:: 3.1 - .. method:: read(size=-1) + .. method:: read(size=-1, /) Read and return up to *size* bytes. If the argument is omitted, ``None``, or negative, data is read and returned until EOF is reached. An empty @@ -571,7 +576,7 @@ I/O Base Classes A :exc:`BlockingIOError` is raised if the underlying raw stream is in non blocking-mode, and has no data available at the moment. - .. method:: read1([size]) + .. method:: read1(size=-1, /) Read and return up to *size* bytes, with at most one call to the underlying raw stream's :meth:`~RawIOBase.read` (or @@ -582,7 +587,7 @@ I/O Base Classes If *size* is ``-1`` (the default), an arbitrary number of bytes are returned (more than zero unless EOF is reached). - .. method:: readinto(b) + .. method:: readinto(b, /) Read bytes into a pre-allocated, writable :term:`bytes-like object` *b* and return the number of bytes read. @@ -594,7 +599,7 @@ I/O Base Classes A :exc:`BlockingIOError` is raised if the underlying raw stream is in non blocking-mode, and has no data available at the moment. - .. method:: readinto1(b) + .. method:: readinto1(b, /) Read bytes into a pre-allocated, writable :term:`bytes-like object` *b*, using at most one call to @@ -606,7 +611,7 @@ I/O Base Classes .. versionadded:: 3.5 - .. method:: write(b) + .. method:: write(b, /) Write the given :term:`bytes-like object`, *b*, and return the number of bytes written (always equal to the length of *b* in bytes, since if @@ -689,7 +694,7 @@ Buffered Streams Buffered I/O streams provide a higher-level interface to an I/O device than raw I/O does. -.. class:: BytesIO([initial_bytes]) +.. class:: BytesIO(initial_bytes=b'') A binary stream using an in-memory bytes buffer. It inherits :class:`BufferedIOBase`. The buffer is discarded when the @@ -724,14 +729,14 @@ than raw I/O does. Return :class:`bytes` containing the entire contents of the buffer. - .. method:: read1([size]) + .. method:: read1(size=-1, /) In :class:`BytesIO`, this is the same as :meth:`~BufferedIOBase.read`. .. versionchanged:: 3.7 The *size* argument is now optional. - .. method:: readinto1(b) + .. method:: readinto1(b, /) In :class:`BytesIO`, this is the same as :meth:`~BufferedIOBase.readinto`. @@ -754,18 +759,18 @@ than raw I/O does. :class:`BufferedReader` provides or overrides these methods in addition to those from :class:`BufferedIOBase` and :class:`IOBase`: - .. method:: peek([size]) + .. method:: peek(size=0, /) Return bytes from the stream without advancing the position. At most one single read on the raw stream is done to satisfy the call. The number of bytes returned may be less or more than requested. - .. method:: read([size]) + .. method:: read(size=-1, /) Read and return *size* bytes, or if *size* is not given or negative, until EOF or if the read call would block in non-blocking mode. - .. method:: read1([size]) + .. method:: read1(size=-1, /) Read and return up to *size* bytes with only one call on the raw stream. If at least one byte is buffered, only buffered bytes are returned. @@ -802,7 +807,7 @@ than raw I/O does. Force bytes held in the buffer into the raw stream. A :exc:`BlockingIOError` should be raised if the raw stream blocks. - .. method:: write(b) + .. method:: write(b, /) Write the :term:`bytes-like object`, *b*, and return the number of bytes written. When in non-blocking mode, a @@ -825,7 +830,7 @@ than raw I/O does. are guaranteed to be implemented. -.. class:: BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE) +.. class:: BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE, /) A buffered binary stream providing higher-level access to two non seekable :class:`RawIOBase` raw binary streams---one readable, the other writeable. @@ -852,8 +857,7 @@ Text I/O .. class:: TextIOBase Base class for text streams. This class provides a character and line based - interface to stream I/O. It inherits :class:`IOBase`. There is no public - constructor. + interface to stream I/O. It inherits :class:`IOBase`. :class:`TextIOBase` provides or overrides these data attributes and methods in addition to those from :class:`IOBase`: @@ -893,19 +897,19 @@ Text I/O .. versionadded:: 3.1 - .. method:: read(size=-1) + .. method:: read(size=-1, /) Read and return at most *size* characters from the stream as a single :class:`str`. If *size* is negative or ``None``, reads until EOF. - .. method:: readline(size=-1) + .. method:: readline(size=-1, /) Read until newline or EOF and return a single ``str``. If the stream is already at EOF, an empty string is returned. If *size* is specified, at most *size* characters will be read. - .. method:: seek(offset, whence=SEEK_SET) + .. method:: seek(offset, whence=SEEK_SET, /) Change the stream position to the given *offset*. Behaviour depends on the *whence* parameter. The default value for *whence* is @@ -932,7 +936,7 @@ Text I/O does not usually represent a number of bytes in the underlying binary storage. - .. method:: write(s) + .. method:: write(s, /) Write the string *s* to the stream and return the number of characters written. @@ -946,8 +950,7 @@ Text I/O :class:`TextIOBase`. *encoding* gives the name of the encoding that the stream will be decoded or - encoded with. It defaults to - :func:`locale.getpreferredencoding(False) `. + encoded with. It defaults to :func:`locale.getencoding()`. ``encoding="locale"`` can be used to specify the current locale's encoding explicitly. See :ref:`io-text-encoding` for more information. @@ -1018,8 +1021,8 @@ Text I/O .. versionadded:: 3.7 - .. method:: reconfigure(*[, encoding][, errors][, newline][, \ - line_buffering][, write_through]) + .. method:: reconfigure(*, encoding=None, errors=None, newline=None, \ + line_buffering=None, write_through=None) Reconfigure this text stream using new settings for *encoding*, *errors*, *newline*, *line_buffering* and *write_through*. @@ -1037,8 +1040,11 @@ Text I/O .. versionadded:: 3.7 + .. versionchanged:: 3.11 + The method supports ``encoding="locale"`` option. -.. class:: StringIO(initial_value='', newline='\\n') + +.. class:: StringIO(initial_value='', newline='\n') A text stream using an in-memory text buffer. It inherits :class:`TextIOBase`. @@ -1048,8 +1054,12 @@ Text I/O The initial value of the buffer can be set by providing *initial_value*. If newline translation is enabled, newlines will be encoded as if by - :meth:`~TextIOBase.write`. The stream is positioned at the start of - the buffer. + :meth:`~TextIOBase.write`. The stream is positioned at the start of the + buffer which emulates opening an existing file in a ``w+`` mode, making it + ready for an immediate write from the beginning or for a write that + would overwrite the initial value. To emulate opening a file in an ``a+`` + mode ready for appending, use ``f.seek(0, io.SEEK_END)`` to reposition the + stream at the end of the buffer. The *newline* argument works like that of :class:`TextIOWrapper`, except that when writing output to the stream, if *newline* is ``None``, diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 61d8b869711..8d83d92660d 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -10,6 +10,10 @@ .. testsetup:: from itertools import * + import collections + import math + import operator + import random -------------- @@ -29,7 +33,7 @@ by combining :func:`map` and :func:`count` to form ``map(f, count())``. These tools and their built-in counterparts also work well with the high-speed functions in the :mod:`operator` module. For example, the multiplication operator can be mapped across two vectors to form an efficient dot-product: -``sum(map(operator.mul, vector1, vector2))``. +``sum(starmap(operator.mul, zip(vec1, vec2, strict=True)))``. **Infinite iterators:** @@ -48,6 +52,7 @@ Iterator Arguments Results Iterator Arguments Results Example ============================ ============================ ================================================= ============================================================= :func:`accumulate` p [,func] p0, p0+p1, p0+p1+p2, ... ``accumulate([1,2,3,4,5]) --> 1 3 6 10 15`` +:func:`batched` p, n (p0, p1, ..., p_n-1), ... ``batched('ABCDEFG', n=3) --> ABC DEF G`` :func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... ``chain('ABC', 'DEF') --> A B C D E F`` :func:`chain.from_iterable` iterable p0, p1, ... plast, q0, q1, ... ``chain.from_iterable(['ABC', 'DEF']) --> A B C D E F`` :func:`compress` data, selectors (d[0] if s[0]), (d[1] if s[1]), ... ``compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F`` @@ -132,10 +137,9 @@ loops that truncate the stream. There are a number of uses for the *func* argument. It can be set to :func:`min` for a running minimum, :func:`max` for a running maximum, or :func:`operator.mul` for a running product. Amortization tables can be - built by accumulating interest and applying payments. First-order - `recurrence relations `_ - can be modeled by supplying the initial value in the iterable and using only - the accumulated total in *func* argument:: + built by accumulating interest and applying payments: + + .. doctest:: >>> data = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8] >>> list(accumulate(data, operator.mul)) # running product @@ -148,17 +152,6 @@ loops that truncate the stream. >>> list(accumulate(cashflows, lambda bal, pmt: bal*1.05 + pmt)) [1000, 960.0, 918.0, 873.9000000000001, 827.5950000000001] - # Chaotic recurrence relation https://en.wikipedia.org/wiki/Logistic_map - >>> logistic_map = lambda x, _: r * x * (1 - x) - >>> r = 3.8 - >>> x0 = 0.4 - >>> inputs = repeat(x0, 36) # only the initial value is used - >>> [format(x, '.2f') for x in accumulate(inputs, logistic_map)] - ['0.40', '0.91', '0.30', '0.81', '0.60', '0.92', '0.29', '0.79', '0.63', - '0.88', '0.39', '0.90', '0.33', '0.84', '0.52', '0.95', '0.18', '0.57', - '0.93', '0.25', '0.71', '0.79', '0.63', '0.88', '0.39', '0.91', '0.32', - '0.83', '0.54', '0.95', '0.20', '0.60', '0.91', '0.30', '0.80', '0.60'] - See :func:`functools.reduce` for a similar function that returns only the final accumulated value. @@ -170,6 +163,44 @@ loops that truncate the stream. .. versionchanged:: 3.8 Added the optional *initial* parameter. + +.. function:: batched(iterable, n) + + Batch data from the *iterable* into tuples of length *n*. The last + batch may be shorter than *n*. + + Loops over the input iterable and accumulates data into tuples up to + size *n*. The input is consumed lazily, just enough to fill a batch. + The result is yielded as soon as the batch is full or when the input + iterable is exhausted: + + .. doctest:: + + >>> flattened_data = ['roses', 'red', 'violets', 'blue', 'sugar', 'sweet'] + >>> unflattened = list(batched(flattened_data, 2)) + >>> unflattened + [('roses', 'red'), ('violets', 'blue'), ('sugar', 'sweet')] + + >>> for batch in batched('ABCDEFG', 3): + ... print(batch) + ... + ('A', 'B', 'C') + ('D', 'E', 'F') + ('G',) + + Roughly equivalent to:: + + def batched(iterable, n): + # batched('ABCDEFG', 3) --> ABC DEF G + if n < 1: + raise ValueError('n must be at least one') + it = iter(iterable) + while (batch := tuple(islice(it, n))): + yield batch + + .. versionadded:: 3.12 + + .. function:: chain(*iterables) Make an iterator that returns elements from the first iterable until it is @@ -202,10 +233,10 @@ loops that truncate the stream. The combination tuples are emitted in lexicographic ordering according to the order of the input *iterable*. So, if the input *iterable* is sorted, - the combination tuples will be produced in sorted order. + the output tuples will be produced in sorted order. Elements are treated as unique based on their position, not on their - value. So if the input elements are unique, there will be no repeat + value. So if the input elements are unique, there will be no repeated values in each combination. Roughly equivalent to:: @@ -251,7 +282,7 @@ loops that truncate the stream. The combination tuples are emitted in lexicographic ordering according to the order of the input *iterable*. So, if the input *iterable* is sorted, - the combination tuples will be produced in sorted order. + the output tuples will be produced in sorted order. Elements are treated as unique based on their position, not on their value. So if the input elements are unique, the generated combinations @@ -314,7 +345,7 @@ loops that truncate the stream. def count(start=0, step=1): # count(10) --> 10 11 12 13 14 ... - # count(2.5, 0.5) -> 2.5 3.0 3.5 ... + # count(2.5, 0.5) --> 2.5 3.0 3.5 ... n = start while True: yield n @@ -410,14 +441,17 @@ loops that truncate the stream. class groupby: # [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B # [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D + def __init__(self, iterable, key=None): if key is None: key = lambda x: x self.keyfunc = key self.it = iter(iterable) self.tgtkey = self.currkey = self.currvalue = object() + def __iter__(self): return self + def __next__(self): self.id = object() while self.currkey == self.tgtkey: @@ -425,6 +459,7 @@ loops that truncate the stream. self.currkey = self.keyfunc(self.currvalue) self.tgtkey = self.currkey return (self.currkey, self._grouper(self.tgtkey, self.id)) + def _grouper(self, tgtkey, id): while self.id is id and self.currkey == tgtkey: yield self.currvalue @@ -443,10 +478,17 @@ loops that truncate the stream. Afterward, elements are returned consecutively unless *step* is set higher than one which results in items being skipped. If *stop* is ``None``, then iteration continues until the iterator is exhausted, if at all; otherwise, it stops at the - specified position. Unlike regular slicing, :func:`islice` does not support - negative values for *start*, *stop*, or *step*. Can be used to extract related - fields from data where the internal structure has been flattened (for example, a - multi-line report may list a name field on every third line). Roughly equivalent to:: + specified position. + + If *start* is ``None``, then iteration starts at zero. If *step* is ``None``, + then the step defaults to one. + + Unlike regular slicing, :func:`islice` does not support negative values for + *start*, *stop*, or *step*. Can be used to extract related fields from + data where the internal structure has been flattened (for example, a + multi-line report may list a name field on every third line). + + Roughly equivalent to:: def islice(iterable, *args): # islice('ABCDEFG', 2) --> A B @@ -473,8 +515,6 @@ loops that truncate the stream. for i, element in zip(range(i + 1, stop), iterable): pass - If *start* is ``None``, then iteration starts at zero. If *step* is ``None``, - then the step defaults to one. .. function:: pairwise(iterable) @@ -503,13 +543,13 @@ loops that truncate the stream. of the *iterable* and all possible full-length permutations are generated. - The permutation tuples are emitted in lexicographic ordering according to + The permutation tuples are emitted in lexicographic order according to the order of the input *iterable*. So, if the input *iterable* is sorted, - the combination tuples will be produced in sorted order. + the output tuples will be produced in sorted order. Elements are treated as unique based on their position, not on their - value. So if the input elements are unique, there will be no repeat - values in each permutation. + value. So if the input elements are unique, there will be no repeated + values within a permutation. Roughly equivalent to:: @@ -589,9 +629,7 @@ loops that truncate the stream. .. function:: repeat(object[, times]) Make an iterator that returns *object* over and over again. Runs indefinitely - unless the *times* argument is specified. Used as argument to :func:`map` for - invariant parameters to the called function. Also used with :func:`zip` to - create an invariant part of a tuple record. + unless the *times* argument is specified. Roughly equivalent to:: @@ -605,7 +643,9 @@ loops that truncate the stream. yield object A common use for *repeat* is to supply a stream of constant values to *map* - or *zip*:: + or *zip*: + + .. doctest:: >>> list(map(pow, range(10), repeat(2))) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] @@ -614,9 +654,12 @@ loops that truncate the stream. Make an iterator that computes the function using arguments obtained from the iterable. Used instead of :func:`map` when argument parameters are already - grouped in tuples from a single iterable (the data has been "pre-zipped"). The - difference between :func:`map` and :func:`starmap` parallels the distinction - between ``function(a,b)`` and ``function(*c)``. Roughly equivalent to:: + grouped in tuples from a single iterable (when the data has been + "pre-zipped"). + + The difference between :func:`map` and :func:`starmap` parallels the + distinction between ``function(a,b)`` and ``function(*c)``. Roughly + equivalent to:: def starmap(function, iterable): # starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000 @@ -644,9 +687,7 @@ loops that truncate the stream. The following Python code helps explain what *tee* does (although the actual implementation is more complex and uses only a single underlying - :abbr:`FIFO (first-in, first-out)` queue). - - Roughly equivalent to:: + :abbr:`FIFO (first-in, first-out)` queue):: def tee(iterable, n=2): it = iter(iterable) @@ -663,12 +704,12 @@ loops that truncate the stream. yield mydeque.popleft() return tuple(gen(d) for d in deques) - Once :func:`tee` has made a split, the original *iterable* should not be + Once a :func:`tee` has been created, the original *iterable* should not be used anywhere else; otherwise, the *iterable* could get advanced without the tee objects being informed. ``tee`` iterators are not threadsafe. A :exc:`RuntimeError` may be - raised when using simultaneously iterators returned by the same :func:`tee` + raised when simultaneously using iterators returned by the same :func:`tee` call, even if the original *iterable* is threadsafe. This itertool may require significant auxiliary storage (depending on how @@ -717,14 +758,28 @@ Itertools Recipes This section shows recipes for creating an extended toolset using the existing itertools as building blocks. +The primary purpose of the itertools recipes is educational. The recipes show +various ways of thinking about individual tools — for example, that +``chain.from_iterable`` is related to the concept of flattening. The recipes +also give ideas about ways that the tools can be combined — for example, how +``compress()`` and ``range()`` can work together. The recipes also show patterns +for using itertools with the :mod:`operator` and :mod:`collections` modules as +well as with the built-in itertools such as ``map()``, ``filter()``, +``reversed()``, and ``enumerate()``. + +A secondary purpose of the recipes is to serve as an incubator. The +``accumulate()``, ``compress()``, and ``pairwise()`` itertools started out as +recipes. Currently, the ``iter_index()`` recipe is being tested to see +whether it proves its worth. + Substantially all of these recipes and many, many others can be installed from the `more-itertools project `_ found on the Python Package Index:: - pip install more-itertools + python -m pip install more-itertools -The extended tools offer the same high performance as the underlying toolset. -The superior memory performance is kept by processing elements one at a time +Many of the recipes offer the same high performance as the underlying toolset. +Superior memory performance is kept by processing elements one at a time rather than bringing the whole iterable into memory all at once. Code volume is kept small by linking the tools together in a functional style which helps eliminate temporary variables. High speed is retained by preferring @@ -733,13 +788,18 @@ which incur interpreter overhead. .. testcode:: + import collections + import math + import operator + import random + def take(n, iterable): "Return first n items of the iterable as a list" return list(islice(iterable, n)) def prepend(value, iterator): "Prepend a single value in front of an iterator" - # prepend(1, [2, 3, 4]) -> 1 2 3 4 + # prepend(1, [2, 3, 4]) --> 1 2 3 4 return chain([value], iterator) def tabulate(function, start=0): @@ -774,19 +834,25 @@ which incur interpreter overhead. "Count how many times the predicate is true" return sum(map(pred, iterable)) - def pad_none(iterable): - """Returns the sequence elements and then returns None indefinitely. - - Useful for emulating the behavior of the built-in map() function. - """ - return chain(iterable, repeat(None)) - def ncycles(iterable, n): "Returns the sequence elements n times" return chain.from_iterable(repeat(tuple(iterable), n)) - def dotproduct(vec1, vec2): - return sum(map(operator.mul, vec1, vec2)) + def sum_of_squares(it): + "Add up the squares of the input values." + # sum_of_squares([10, 20, 30]) -> 1400 + return math.sumprod(*tee(it)) + + def transpose(it): + "Swap the rows and columns of the input." + # transpose([(1, 2, 3), (11, 22, 33)]) --> (1, 11) (2, 22) (3, 33) + return zip(*it, strict=True) + + def matmul(m1, m2): + "Multiply two matrices." + # matmul([(7, 5), (3, 5)], [[2, 5], [7, 9]]) --> (49, 80), (41, 60) + n = len(m2[0]) + return batched(starmap(math.sumprod, product(m1, transpose(m2))), n) def convolve(signal, kernel): # See: https://betterexplained.com/articles/intuitive-convolution/ @@ -798,7 +864,65 @@ which incur interpreter overhead. window = collections.deque([0], maxlen=n) * n for x in chain(signal, repeat(0, n-1)): window.append(x) - yield sum(map(operator.mul, kernel, window)) + yield math.sumprod(kernel, window) + + def polynomial_from_roots(roots): + """Compute a polynomial's coefficients from its roots. + + (x - 5) (x + 4) (x - 3) expands to: x³ -4x² -17x + 60 + """ + # polynomial_from_roots([5, -4, 3]) --> [1, -4, -17, 60] + roots = list(map(operator.neg, roots)) + return [ + sum(map(math.prod, combinations(roots, k))) + for k in range(len(roots) + 1) + ] + + def iter_index(iterable, value, start=0): + "Return indices where a value occurs in a sequence or iterable." + # iter_index('AABCADEAF', 'A') --> 0 1 4 7 + try: + seq_index = iterable.index + except AttributeError: + # Slow path for general iterables + it = islice(iterable, start, None) + for i, element in enumerate(it, start): + if element is value or element == value: + yield i + else: + # Fast path for sequences + i = start - 1 + try: + while True: + yield (i := seq_index(value, i+1)) + except ValueError: + pass + + def sieve(n): + "Primes less than n" + # sieve(30) --> 2 3 5 7 11 13 17 19 23 29 + data = bytearray((0, 1)) * (n // 2) + data[:3] = 0, 0, 0 + limit = math.isqrt(n) + 1 + for p in compress(range(limit), data): + data[p*p : n : p+p] = bytes(len(range(p*p, n, p+p))) + data[2] = 1 + return iter_index(data, 1) if n > 2 else iter([]) + + def factor(n): + "Prime factors of n." + # factor(99) --> 3 3 11 + for prime in sieve(math.isqrt(n) + 1): + while True: + quotient, remainder = divmod(n, prime) + if remainder: + break + yield prime + n = quotient + if n == 1: + return + if n >= 2: + yield n def flatten(list_of_lists): "Flatten one level of nesting" @@ -813,20 +937,29 @@ which incur interpreter overhead. return starmap(func, repeat(args)) return starmap(func, repeat(args, times)) - def grouper(iterable, n, fillvalue=None): + def grouper(iterable, n, *, incomplete='fill', fillvalue=None): "Collect data into non-overlapping fixed-length chunks or blocks" - # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx + # grouper('ABCDEFG', 3, fillvalue='x') --> ABC DEF Gxx + # grouper('ABCDEFG', 3, incomplete='strict') --> ABC DEF ValueError + # grouper('ABCDEFG', 3, incomplete='ignore') --> ABC DEF args = [iter(iterable)] * n - return zip_longest(*args, fillvalue=fillvalue) + if incomplete == 'fill': + return zip_longest(*args, fillvalue=fillvalue) + if incomplete == 'strict': + return zip(*args, strict=True) + if incomplete == 'ignore': + return zip(*args) + else: + raise ValueError('Expected fill, strict, or ignore') def triplewise(iterable): "Return overlapping triplets from an iterable" - # triplewise('ABCDEFG') -> ABC BCD CDE DEF EFG + # triplewise('ABCDEFG') --> ABC BCD CDE DEF EFG for (a, _), (b, c) in pairwise(pairwise(iterable)): yield a, b, c def sliding_window(iterable, n): - # sliding_window('ABCDEFG', 4) -> ABCD BCDE CDEF DEFG + # sliding_window('ABCDEFG', 4) --> ABCD BCDE CDEF DEFG it = iter(iterable) window = collections.deque(islice(it, n), maxlen=n) if len(window) == n: @@ -884,6 +1017,12 @@ which incur interpreter overhead. yield from it return true_iterator(), remainder_iterator() + def subslices(seq): + "Return all contiguous non-empty subslices of a sequence" + # subslices('ABCD') --> A AB ABC ABCD B BC BCD C CD D + slices = starmap(slice, combinations(range(len(seq) + 1), 2)) + return map(operator.getitem, repeat(seq), slices) + def powerset(iterable): "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" s = list(iterable) @@ -892,24 +1031,30 @@ which incur interpreter overhead. def unique_everseen(iterable, key=None): "List unique elements, preserving order. Remember all elements ever seen." # unique_everseen('AAAABBBCCDAABBB') --> A B C D - # unique_everseen('ABBCcAD', str.lower) --> A B C D + # unique_everseen('ABBcCAD', str.lower) --> A B c D seen = set() - seen_add = seen.add if key is None: for element in filterfalse(seen.__contains__, iterable): - seen_add(element) + seen.add(element) yield element + # For order preserving deduplication, + # a faster but non-lazy solution is: + # yield from dict.fromkeys(iterable) else: for element in iterable: k = key(element) if k not in seen: - seen_add(k) + seen.add(k) yield element + # For use cases that allow the last matching element to be returned, + # a faster but non-lazy solution is: + # t1, t2 = tee(iterable) + # yield from dict(zip(map(key, t1), t2)).values() def unique_justseen(iterable, key=None): "List unique elements, preserving order. Remember only the element just seen." # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B - # unique_justseen('ABBCcAD', str.lower) --> A B C A D + # unique_justseen('ABBcCAD', str.lower) --> A B c A D return map(next, map(operator.itemgetter(1), groupby(iterable, key))) def iter_except(func, exception, first=None): @@ -948,41 +1093,11 @@ which incur interpreter overhead. # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x return next(filter(pred, iterable), default) - def random_product(*args, repeat=1): - "Random selection from itertools.product(*args, **kwds)" - pools = [tuple(pool) for pool in args] * repeat - return tuple(map(random.choice, pools)) - - def random_permutation(iterable, r=None): - "Random selection from itertools.permutations(iterable, r)" - pool = tuple(iterable) - r = len(pool) if r is None else r - return tuple(random.sample(pool, r)) - - def random_combination(iterable, r): - "Random selection from itertools.combinations(iterable, r)" - pool = tuple(iterable) - n = len(pool) - indices = sorted(random.sample(range(n), r)) - return tuple(pool[i] for i in indices) - - def random_combination_with_replacement(iterable, r): - "Random selection from itertools.combinations_with_replacement(iterable, r)" - pool = tuple(iterable) - n = len(pool) - indices = sorted(random.choices(range(n), k=r)) - return tuple(pool[i] for i in indices) - def nth_combination(iterable, r, index): "Equivalent to list(combinations(iterable, r))[index]" pool = tuple(iterable) n = len(pool) - if r < 0 or r > n: - raise ValueError - c = 1 - k = min(r, n-r) - for i in range(1, k+1): - c = c * (n - k + i) // i + c = math.comb(n, r) if index < 0: index += c if index < 0 or index >= c: @@ -995,3 +1110,332 @@ which incur interpreter overhead. c, n = c*(n-r)//n, n-1 result.append(pool[-1-n]) return tuple(result) + +.. doctest:: + :hide: + + These examples no longer appear in the docs but are guaranteed + to keep working. + + >>> amounts = [120.15, 764.05, 823.14] + >>> for checknum, amount in zip(count(1200), amounts): + ... print('Check %d is for $%.2f' % (checknum, amount)) + ... + Check 1200 is for $120.15 + Check 1201 is for $764.05 + Check 1202 is for $823.14 + + >>> import operator + >>> for cube in map(operator.pow, range(1,4), repeat(3)): + ... print(cube) + ... + 1 + 8 + 27 + + >>> reportlines = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele'] + >>> for name in islice(reportlines, 3, None, 2): + ... print(name.title()) + ... + Alex + Laura + Martin + Walter + Samuele + + >>> from operator import itemgetter + >>> d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3) + >>> di = sorted(sorted(d.items()), key=itemgetter(1)) + >>> for k, g in groupby(di, itemgetter(1)): + ... print(k, list(map(itemgetter(0), g))) + ... + 1 ['a', 'c', 'e'] + 2 ['b', 'd', 'f'] + 3 ['g'] + + # Find runs of consecutive numbers using groupby. The key to the solution + # is differencing with a range so that consecutive numbers all appear in + # same group. + >>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28] + >>> for k, g in groupby(enumerate(data), lambda t:t[0]-t[1]): + ... print(list(map(operator.itemgetter(1), g))) + ... + [1] + [4, 5, 6] + [10] + [15, 16, 17, 18] + [22] + [25, 26, 27, 28] + + Now, we test all of the itertool recipes + + >>> take(10, count()) + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + + >>> list(prepend(1, [2, 3, 4])) + [1, 2, 3, 4] + + >>> list(enumerate('abc')) + [(0, 'a'), (1, 'b'), (2, 'c')] + + >>> list(islice(tabulate(lambda x: 2*x), 4)) + [0, 2, 4, 6] + + >>> list(tail(3, 'ABCDEFG')) + ['E', 'F', 'G'] + + >>> it = iter(range(10)) + >>> consume(it, 3) + >>> next(it) + 3 + >>> consume(it) + >>> next(it, 'Done') + 'Done' + + >>> nth('abcde', 3) + 'd' + + >>> nth('abcde', 9) is None + True + + >>> [all_equal(s) for s in ('', 'A', 'AAAA', 'AAAB', 'AAABA')] + [True, True, True, False, False] + + >>> quantify(range(99), lambda x: x%2==0) + 50 + + >>> quantify([True, False, False, True, True]) + 3 + + >>> quantify(range(12), pred=lambda x: x%2==1) + 6 + + >>> a = [[1, 2, 3], [4, 5, 6]] + >>> list(flatten(a)) + [1, 2, 3, 4, 5, 6] + + >>> list(repeatfunc(pow, 5, 2, 3)) + [8, 8, 8, 8, 8] + + >>> take(5, map(int, repeatfunc(random.random))) + [0, 0, 0, 0, 0] + + >>> list(ncycles('abc', 3)) + ['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c'] + + >>> sum_of_squares([10, 20, 30]) + 1400 + + >>> list(transpose([(1, 2, 3), (11, 22, 33)])) + [(1, 11), (2, 22), (3, 33)] + + >>> list(matmul([(7, 5), (3, 5)], [[2, 5], [7, 9]])) + [(49, 80), (41, 60)] + >>> list(matmul([[2, 5], [7, 9], [3, 4]], [[7, 11, 5, 4, 9], [3, 5, 2, 6, 3]])) + [(29, 47, 20, 38, 33), (76, 122, 53, 82, 90), (33, 53, 23, 36, 39)] + + >>> data = [20, 40, 24, 32, 20, 28, 16] + >>> list(convolve(data, [0.25, 0.25, 0.25, 0.25])) + [5.0, 15.0, 21.0, 29.0, 29.0, 26.0, 24.0, 16.0, 11.0, 4.0] + >>> list(convolve(data, [1, -1])) + [20, 20, -16, 8, -12, 8, -12, -16] + >>> list(convolve(data, [1, -2, 1])) + [20, 0, -36, 24, -20, 20, -20, -4, 16] + + >>> polynomial_from_roots([5, -4, 3]) + [1, -4, -17, 60] + >>> factored = lambda x: (x - 5) * (x + 4) * (x - 3) + >>> expanded = lambda x: x**3 -4*x**2 -17*x + 60 + >>> all(factored(x) == expanded(x) for x in range(-10, 11)) + True + + >>> list(iter_index('AABCADEAF', 'A')) + [0, 1, 4, 7] + >>> list(iter_index('AABCADEAF', 'B')) + [2] + >>> list(iter_index('AABCADEAF', 'X')) + [] + >>> list(iter_index('', 'X')) + [] + >>> list(iter_index('AABCADEAF', 'A', 1)) + [1, 4, 7] + >>> list(iter_index(iter('AABCADEAF'), 'A', 1)) + [1, 4, 7] + >>> list(iter_index('AABCADEAF', 'A', 2)) + [4, 7] + >>> list(iter_index(iter('AABCADEAF'), 'A', 2)) + [4, 7] + >>> list(iter_index('AABCADEAF', 'A', 10)) + [] + >>> list(iter_index(iter('AABCADEAF'), 'A', 10)) + [] + + >>> list(sieve(30)) + [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] + >>> small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] + >>> all(list(sieve(n)) == [p for p in small_primes if p < n] for n in range(101)) + True + >>> len(list(sieve(100))) + 25 + >>> len(list(sieve(1_000))) + 168 + >>> len(list(sieve(10_000))) + 1229 + >>> len(list(sieve(100_000))) + 9592 + >>> len(list(sieve(1_000_000))) + 78498 + >>> carmichael = {561, 1105, 1729, 2465, 2821, 6601, 8911} # https://oeis.org/A002997 + >>> set(sieve(10_000)).isdisjoint(carmichael) + True + + >>> list(factor(0)) + [] + >>> list(factor(1)) + [] + >>> list(factor(2)) + [2] + >>> list(factor(3)) + [3] + >>> list(factor(4)) + [2, 2] + >>> list(factor(5)) + [5] + >>> list(factor(6)) + [2, 3] + >>> list(factor(7)) + [7] + >>> list(factor(8)) + [2, 2, 2] + >>> list(factor(9)) + [3, 3] + >>> list(factor(10)) + [2, 5] + >>> list(factor(128_884_753_939)) # large prime + [128884753939] + >>> list(factor(999953 * 999983)) # large semiprime + [999953, 999983] + >>> list(factor(6 ** 20)) == [2] * 20 + [3] * 20 # large power + True + >>> list(factor(909_909_090_909)) # large multiterm composite + [3, 3, 7, 13, 13, 751, 113797] + >>> math.prod([3, 3, 7, 13, 13, 751, 113797]) + 909909090909 + >>> all(math.prod(factor(n)) == n for n in range(1, 2_000)) + True + >>> all(set(factor(n)) <= set(sieve(n+1)) for n in range(2_000)) + True + >>> all(list(factor(n)) == sorted(factor(n)) for n in range(2_000)) + True + + >>> list(flatten([('a', 'b'), (), ('c', 'd', 'e'), ('f',), ('g', 'h', 'i')])) + ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'] + + >>> random.seed(85753098575309) + >>> list(repeatfunc(random.random, 3)) + [0.16370491282496968, 0.45889608687313455, 0.3747076837820118] + >>> list(repeatfunc(chr, 3, 65)) + ['A', 'A', 'A'] + >>> list(repeatfunc(pow, 3, 2, 5)) + [32, 32, 32] + + >>> list(grouper('abcdefg', 3, fillvalue='x')) + [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'x', 'x')] + + >>> it = grouper('abcdefg', 3, incomplete='strict') + >>> next(it) + ('a', 'b', 'c') + >>> next(it) + ('d', 'e', 'f') + >>> next(it) + Traceback (most recent call last): + ... + ValueError: zip() argument 2 is shorter than argument 1 + + >>> list(grouper('abcdefg', n=3, incomplete='ignore')) + [('a', 'b', 'c'), ('d', 'e', 'f')] + + >>> list(triplewise('ABCDEFG')) + [('A', 'B', 'C'), ('B', 'C', 'D'), ('C', 'D', 'E'), ('D', 'E', 'F'), ('E', 'F', 'G')] + + >>> list(sliding_window('ABCDEFG', 4)) + [('A', 'B', 'C', 'D'), ('B', 'C', 'D', 'E'), ('C', 'D', 'E', 'F'), ('D', 'E', 'F', 'G')] + + >>> list(roundrobin('abc', 'd', 'ef')) + ['a', 'd', 'e', 'b', 'f', 'c'] + + >>> def is_odd(x): + ... return x % 2 == 1 + + >>> evens, odds = partition(is_odd, range(10)) + >>> list(evens) + [0, 2, 4, 6, 8] + >>> list(odds) + [1, 3, 5, 7, 9] + + >>> it = iter('ABCdEfGhI') + >>> all_upper, remainder = before_and_after(str.isupper, it) + >>> ''.join(all_upper) + 'ABC' + >>> ''.join(remainder) + 'dEfGhI' + + >>> list(subslices('ABCD')) + ['A', 'AB', 'ABC', 'ABCD', 'B', 'BC', 'BCD', 'C', 'CD', 'D'] + + >>> list(powerset([1,2,3])) + [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)] + + >>> all(len(list(powerset(range(n)))) == 2**n for n in range(18)) + True + + >>> list(powerset('abcde')) == sorted(sorted(set(powerset('abcde'))), key=len) + True + + >>> list(unique_everseen('AAAABBBCCDAABBB')) + ['A', 'B', 'C', 'D'] + >>> list(unique_everseen('ABBCcAD', str.lower)) + ['A', 'B', 'C', 'D'] + >>> list(unique_everseen('ABBcCAD', str.lower)) + ['A', 'B', 'c', 'D'] + + >>> list(unique_justseen('AAAABBBCCDAABBB')) + ['A', 'B', 'C', 'D', 'A', 'B'] + >>> list(unique_justseen('ABBCcAD', str.lower)) + ['A', 'B', 'C', 'A', 'D'] + >>> list(unique_justseen('ABBcCAD', str.lower)) + ['A', 'B', 'c', 'A', 'D'] + + >>> d = dict(a=1, b=2, c=3) + >>> it = iter_except(d.popitem, KeyError) + >>> d['d'] = 4 + >>> next(it) + ('d', 4) + >>> next(it) + ('c', 3) + >>> next(it) + ('b', 2) + >>> d['e'] = 5 + >>> next(it) + ('e', 5) + >>> next(it) + ('a', 1) + >>> next(it, 'empty') + 'empty' + + >>> first_true('ABC0DEF1', '9', str.isdigit) + '0' + + >>> population = 'ABCDEFGH' + >>> for r in range(len(population) + 1): + ... seq = list(combinations(population, r)) + ... for i in range(len(seq)): + ... assert nth_combination(population, r, i) == seq[i] + ... for i in range(-len(seq), 0): + ... assert nth_combination(population, r, i) == seq[i] + + >>> iterable = 'abcde' + >>> r = 3 + >>> combos = list(combinations(iterable, r)) + >>> all(nth_combination(iterable, r, i) == comb for i, comb in enumerate(combos)) + True diff --git a/Doc/library/json.rst b/Doc/library/json.rst index 6fa89f578a2..00f585124a8 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -9,6 +9,11 @@ **Source code:** :source:`Lib/json/__init__.py` +.. testsetup:: * + + import json + from json import AttrDict + -------------- `JSON (JavaScript Object Notation) `_, specified by @@ -18,6 +23,11 @@ is a lightweight data interchange format inspired by `JavaScript `_ object literal syntax (although it is not a strict subset of JavaScript [#rfc-errata]_ ). +.. warning:: + Be cautious when parsing JSON data from untrusted sources. A malicious + JSON string may cause the decoder to consume considerable CPU and memory + resources. Limiting the size of data to be parsed is recommended. + :mod:`json` exposes an API familiar to users of the standard library :mod:`marshal` and :mod:`pickle` modules. @@ -115,7 +125,7 @@ See :ref:`json-commandline` for detailed documentation. .. note:: - JSON is a subset of `YAML `_ 1.2. The JSON produced by + JSON is a subset of `YAML `_ 1.2. The JSON produced by this module's default settings (in particular, the default *separators* value) is also a subset of YAML 1.0 and 1.1. This module can thus also be used as a YAML serializer. @@ -125,13 +135,6 @@ See :ref:`json-commandline` for detailed documentation. This module's encoders and decoders preserve input and output order by default. Order is only lost if the underlying containers are unordered. - Prior to Python 3.7, :class:`dict` was not guaranteed to be ordered, so - inputs and outputs were typically scrambled unless - :class:`collections.OrderedDict` was specifically requested. Starting - with Python 3.7, the regular :class:`dict` became order preserving, so - it is no longer necessary to specify :class:`collections.OrderedDict` for - JSON generation and parsing. - Basic Usage ----------- @@ -159,7 +162,7 @@ Basic Usage If *check_circular* is false (default: ``True``), then the circular reference check for container types will be skipped and a circular reference - will result in an :exc:`OverflowError` (or worse). + will result in a :exc:`RecursionError` (or worse). If *allow_nan* is false (default: ``True``), then it will be a :exc:`ValueError` to serialize out of range :class:`float` values (``nan``, @@ -233,7 +236,7 @@ Basic Usage *object_hook* is an optional function that will be called with the result of any object literal decoded (a :class:`dict`). The return value of *object_hook* will be used instead of the :class:`dict`. This feature can be used - to implement custom decoders (e.g. `JSON-RPC `_ + to implement custom decoders (e.g. `JSON-RPC `_ class hinting). *object_pairs_hook* is an optional function that will be called with the @@ -255,6 +258,12 @@ Basic Usage be used to use another datatype or parser for JSON integers (e.g. :class:`float`). + .. versionchanged:: 3.11 + The default *parse_int* of :func:`int` now limits the maximum length of + the integer string via the interpreter's :ref:`integer string + conversion length limitation ` to help avoid denial + of service attacks. + *parse_constant*, if specified, will be called with one of the following strings: ``'-Infinity'``, ``'Infinity'``, ``'NaN'``. This can be used to raise an exception if invalid JSON numbers @@ -333,7 +342,7 @@ Encoders and Decoders *object_hook*, if specified, will be called with the result of every JSON object decoded and its return value will be used in place of the given :class:`dict`. This can be used to provide custom deserializations (e.g. to - support `JSON-RPC `_ class hinting). + support `JSON-RPC `_ class hinting). *object_pairs_hook*, if specified will be called with the result of every JSON object decoded with an ordered list of pairs. The return value of @@ -432,7 +441,7 @@ Encoders and Decoders If *check_circular* is true (the default), then lists, dicts, and custom encoded objects will be checked for circular references during encoding to - prevent an infinite recursion (which would cause an :exc:`OverflowError`). + prevent an infinite recursion (which would cause a :exc:`RecursionError`). Otherwise, no such check takes place. If *allow_nan* is true (the default), then ``NaN``, ``Infinity``, and @@ -539,6 +548,44 @@ Exceptions .. versionadded:: 3.5 +.. class:: AttrDict(**kwargs) + AttrDict(mapping, **kwargs) + AttrDict(iterable, **kwargs) + + Subclass of :class:`dict` object that also supports attribute style dotted access. + + This class is intended for use with the :attr:`object_hook` in + :func:`json.load` and :func:`json.loads`:: + + .. doctest:: + + >>> json_string = '{"mercury": 88, "venus": 225, "earth": 365, "mars": 687}' + >>> orbital_period = json.loads(json_string, object_hook=AttrDict) + >>> orbital_period['earth'] # Dict style lookup + 365 + >>> orbital_period.earth # Attribute style lookup + 365 + >>> orbital_period.keys() # All dict methods are present + dict_keys(['mercury', 'venus', 'earth', 'mars']) + + Attribute style access only works for keys that are valid attribute + names. In contrast, dictionary style access works for all keys. For + example, ``d.two words`` contains a space and is not syntactically + valid Python, so ``d["two words"]`` should be used instead. + + If a key has the same name as a dictionary method, then a dictionary + lookup finds the key and an attribute lookup finds the method: + + .. doctest:: + + >>> d = AttrDict(items=50) + >>> d['items'] # Lookup the key + 50 + >>> d.items() # Call the method + dict_items([('items', 50)]) + + .. versionadded:: 3.12 + Standard Compliance and Interoperability ---------------------------------------- diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst index 60d0c59d017..f726f8397c9 100644 --- a/Doc/library/locale.rst +++ b/Doc/library/locale.rst @@ -147,12 +147,12 @@ The :mod:`locale` module defines the following exception and functions: | ``CHAR_MAX`` | Nothing is specified in this locale. | +--------------+-----------------------------------------+ - The function sets temporarily the ``LC_CTYPE`` locale to the ``LC_NUMERIC`` + The function temporarily sets the ``LC_CTYPE`` locale to the ``LC_NUMERIC`` locale or the ``LC_MONETARY`` locale if locales are different and numeric or monetary strings are non-ASCII. This temporary change affects other threads. .. versionchanged:: 3.7 - The function now sets temporarily the ``LC_CTYPE`` locale to the + The function now temporarily sets the ``LC_CTYPE`` locale to the ``LC_NUMERIC`` locale in some cases. @@ -227,16 +227,18 @@ The :mod:`locale` module defines the following exception and functions: Get a regular expression that can be used with the regex function to recognize a positive response to a yes/no question. - .. note:: - - The expression is in the syntax suitable for the :c:func:`regex` function - from the C library, which might differ from the syntax used in :mod:`re`. - .. data:: NOEXPR Get a regular expression that can be used with the regex(3) function to recognize a negative response to a yes/no question. + .. note:: + + The regular expressions for :const:`YESEXPR` and + :const:`NOEXPR` use syntax suitable for the + :c:func:`regex` function from the C library, which might + differ from the syntax used in :mod:`re`. + .. data:: CRNCYSTR Get the currency symbol, preceded by "-" if the symbol should appear before @@ -301,6 +303,8 @@ The :mod:`locale` module defines the following exception and functions: *language code* and *encoding* may be ``None`` if their values cannot be determined. + .. deprecated-removed:: 3.11 3.13 + .. function:: getlocale(category=LC_CTYPE) @@ -325,17 +329,37 @@ The :mod:`locale` module defines the following exception and functions: is not necessary or desired, *do_setlocale* should be set to ``False``. On Android or if the :ref:`Python UTF-8 Mode ` is enabled, always - return ``'UTF-8'``, the :term:`locale encoding` and the *do_setlocale* + return ``'utf-8'``, the :term:`locale encoding` and the *do_setlocale* argument are ignored. The :ref:`Python preinitialization ` configures the LC_CTYPE locale. See also the :term:`filesystem encoding and error handler`. .. versionchanged:: 3.7 - The function now always returns ``UTF-8`` on Android or if the + The function now always returns ``"utf-8"`` on Android or if the :ref:`Python UTF-8 Mode ` is enabled. +.. function:: getencoding() + + Get the current :term:`locale encoding`: + + * On Android and VxWorks, return ``"utf-8"``. + * On Unix, return the encoding of the current :data:`LC_CTYPE` locale. + Return ``"utf-8"`` if ``nl_langinfo(CODESET)`` returns an empty string: + for example, if the current LC_CTYPE locale is not supported. + * On Windows, return the ANSI code page. + + The :ref:`Python preinitialization ` configures the LC_CTYPE + locale. See also the :term:`filesystem encoding and error handler`. + + This function is similar to + :func:`getpreferredencoding(False) ` except this + function ignores the :ref:`Python UTF-8 Mode `. + + .. versionadded:: 3.11 + + .. function:: normalize(localename) Returns a normalized locale code for the given locale name. The returned locale @@ -353,6 +377,8 @@ The :mod:`locale` module defines the following exception and functions: The default setting is determined by calling :func:`getdefaultlocale`. *category* defaults to :const:`LC_ALL`. + .. deprecated-removed:: 3.11 3.13 + .. function:: strcoll(string1, string2) @@ -375,7 +401,7 @@ The :mod:`locale` module defines the following exception and functions: Formats a number *val* according to the current :const:`LC_NUMERIC` setting. The format follows the conventions of the ``%`` operator. For floating point - values, the decimal point is modified if appropriate. If *grouping* is true, + values, the decimal point is modified if appropriate. If *grouping* is ``True``, also takes the grouping into account. If *monetary* is true, the conversion uses monetary thousands separator and @@ -388,29 +414,19 @@ The :mod:`locale` module defines the following exception and functions: The *monetary* keyword parameter was added. -.. function:: format(format, val, grouping=False, monetary=False) - - Please note that this function works like :meth:`format_string` but will - only work for exactly one ``%char`` specifier. For example, ``'%f'`` and - ``'%.0f'`` are both valid specifiers, but ``'%f KiB'`` is not. - - For whole format strings, use :func:`format_string`. - - .. deprecated:: 3.7 - Use :meth:`format_string` instead. - - .. function:: currency(val, symbol=True, grouping=False, international=False) Formats a number *val* according to the current :const:`LC_MONETARY` settings. The returned string includes the currency symbol if *symbol* is true, which is - the default. If *grouping* is true (which is not the default), grouping is done - with the value. If *international* is true (which is not the default), the + the default. If *grouping* is ``True`` (which is not the default), grouping is done + with the value. If *international* is ``True`` (which is not the default), the international currency symbol is used. - Note that this function will not work with the 'C' locale, so you have to set a - locale via :func:`setlocale` first. + .. note:: + + This function will not work with the 'C' locale, so you have to set a + locale via :func:`setlocale` first. .. function:: str(float) @@ -435,10 +451,10 @@ The :mod:`locale` module defines the following exception and functions: .. versionadded:: 3.10 -.. function:: atof(string) +.. function:: atof(string, func=float) - Converts a string to a floating point number, following the :const:`LC_NUMERIC` - settings. + Converts a string to a number, following the :const:`LC_NUMERIC` settings, + by calling *func* on the result of calling :func:`delocalize` on *string*. .. function:: atoi(string) @@ -480,10 +496,13 @@ The :mod:`locale` module defines the following exception and functions: system, like those returned by :func:`os.strerror` might be affected by this category. + This value may not be available on operating systems not conforming to the + POSIX standard, most notably Windows. + .. data:: LC_NUMERIC - Locale category for formatting numbers. The functions :func:`.format`, + Locale category for formatting numbers. The functions :func:`format_string`, :func:`atoi`, :func:`atof` and :func:`.str` of the :mod:`locale` module are affected by that category. All other numeric formatting operations are not affected. @@ -545,7 +564,7 @@ document that your module is not compatible with non-\ ``C`` locale settings. The only way to perform numeric operations according to the locale is to use the special functions defined by this module: :func:`atof`, :func:`atoi`, -:func:`.format`, :func:`.str`. +:func:`format_string`, :func:`.str`. There is no way to perform case conversions and character classifications according to the locale. For (Unicode) text strings these are done according @@ -597,4 +616,3 @@ applications that link with additional C libraries which internally invoke :c:func:`gettext` or :c:func:`dcgettext`. For these applications, it may be necessary to bind the text domain, so that the libraries can properly locate their message catalogs. - diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst index 5a3e686802e..2daf2422ebd 100644 --- a/Doc/library/logging.config.rst +++ b/Doc/library/logging.config.rst @@ -191,6 +191,20 @@ in :mod:`logging` itself) and defining handlers which are declared either in :func:`listen`. +Security considerations +^^^^^^^^^^^^^^^^^^^^^^^ + +The logging configuration functionality tries to offer convenience, and in part this +is done by offering the ability to convert text in configuration files into Python +objects used in logging configuration - for example, as described in +:ref:`logging-config-dict-userdef`. However, these same mechanisms (importing +callables from user-defined modules and calling them with parameters from the +configuration) could be used to invoke any code you like, and for this reason you +should treat configuration files from untrusted sources with *extreme caution* and +satisfy yourself that nothing bad can happen if you load them, before actually loading +them. + + .. _logging-config-dictschema: Configuration dictionary schema @@ -274,6 +288,9 @@ otherwise, the context is used to determine what to instantiate. * ``filters`` (optional). A list of ids of the filters for this handler. + .. versionchanged:: 3.11 + ``filters`` can take filter instances in addition to ids. + All *other* keys are passed through as keyword arguments to the handler's constructor. For example, given the snippet: @@ -312,6 +329,9 @@ otherwise, the context is used to determine what to instantiate. * ``filters`` (optional). A list of ids of the filters for this logger. + .. versionchanged:: 3.11 + ``filters`` can take filter instances in addition to ids. + * ``handlers`` (optional). A list of ids of the handlers for this logger. @@ -505,11 +525,67 @@ returned by the call:: my.package.customFormatterFactory(bar='baz', spam=99.9, answer=42) +.. warning:: The values for keys such as ``bar``, ``spam`` and ``answer`` in + the above example should not be configuration dictionaries or references such + as ``cfg://foo`` or ``ext://bar``, because they will not be processed by the + configuration machinery, but passed to the callable as-is. + The key ``'()'`` has been used as the special key because it is not a valid keyword parameter name, and so will not clash with the names of the keyword arguments used in the call. The ``'()'`` also serves as a mnemonic that the corresponding value is a callable. + .. versionchanged:: 3.11 + The ``filters`` member of ``handlers`` and ``loggers`` can take + filter instances in addition to ids. + +You can also specify a special key ``'.'`` whose value is a dictionary is a +mapping of attribute names to values. If found, the specified attributes will +be set on the user-defined object before it is returned. Thus, with the +following configuration:: + + { + '()' : 'my.package.customFormatterFactory', + 'bar' : 'baz', + 'spam' : 99.9, + 'answer' : 42, + '.' { + 'foo': 'bar', + 'baz': 'bozz' + } + } + +the returned formatter will have attribute ``foo`` set to ``'bar'`` and +attribute ``baz`` set to ``'bozz'``. + +.. warning:: The values for attributes such as ``foo`` and ``baz`` in + the above example should not be configuration dictionaries or references such + as ``cfg://foo`` or ``ext://bar``, because they will not be processed by the + configuration machinery, but set as attribute values as-is. + + +.. _handler-config-dict-order: + +Handler configuration order +""""""""""""""""""""""""""" + +Handlers are configured in alphabetical order of their keys, and a configured +handler replaces the configuration dictionary in (a working copy of) the +``handlers`` dictionary in the schema. If you use a construct such as +``cfg://handlers.foo``, then initially ``handlers['foo']`` points to the +configuration dictionary for the handler named ``foo``, and later (once that +handler has been configured) it points to the configured handler instance. +Thus, ``cfg://handlers.foo`` could resolve to either a dictionary or a handler +instance. In general, it is wise to name handlers in a way such that dependent +handlers are configured _after_ any handlers they depend on; that allows +something like ``cfg://handlers.foo`` to be used in configuring a handler that +depends on handler ``foo``. If that dependent handler were named ``bar``, +problems would result, because the configuration of ``bar`` would be attempted +before that of ``foo``, and ``foo`` would not yet have been configured. +However, if the dependent handler were named ``foobar``, it would be configured +after ``foo``, with the result that ``cfg://handlers.foo`` would resolve to +configured handler ``foo``, and not its configuration dictionary. + .. _logging-config-dict-externalobj: @@ -637,6 +713,76 @@ it with :func:`staticmethod`. For example:: You don't need to wrap with :func:`staticmethod` if you're setting the import callable on a configurator *instance*. +.. _configure-queue: + +Configuring QueueHandler and QueueListener +"""""""""""""""""""""""""""""""""""""""""" + +If you want to configure a :class:`~logging.handlers.QueueHandler`, noting that this +is normally used in conjunction with a :class:`~logging.handlers.QueueListener`, you +can configure both together. After the configuration, the ``QueueListener`` instance +will be available as the :attr:`~logging.handlers.QueueHandler.listener` attribute of +the created handler, and that in turn will be available to you using +:func:`~logging.getHandlerByName` and passing the name you have used for the +``QueueHandler`` in your configuration. The dictionary schema for configuring the pair +is shown in the example YAML snippet below. + +.. code-block:: yaml + + handlers: + qhand: + class: logging.handlers.QueueHandler + queue: my.module.queue_factory + listener: my.package.CustomListener + handlers: + - hand_name_1 + - hand_name_2 + ... + +The ``queue`` and ``listener`` keys are optional. + +If the ``queue`` key is present, the corresponding value can be one of the following: + +* An actual instance of :class:`queue.Queue` or a subclass thereof. This is of course + only possible if you are constructing or modifying the configuration dictionary in + code. + +* A string that resolves to a callable which, when called with no arguments, returns + the :class:`queue.Queue` instance to use. That callable could be a + :class:`queue.Queue` subclass or a function which returns a suitable queue instance, + such as ``my.module.queue_factory()``. + +* A dict with a ``'()'`` key which is constructed in the usual way as discussed in + :ref:`logging-config-dict-userdef`. The result of this construction should be a + :class:`queue.Queue` instance. + +If the ``queue`` key is absent, a standard unbounded :class:`queue.Queue` instance is +created and used. + +If the ``listener`` key is present, the corresponding value can be one of the following: + +* A subclass of :class:`logging.handlers.QueueListener`. This is of course only + possible if you are constructing or modifying the configuration dictionary in + code. + +* A string which resolves to a class which is a subclass of ``QueueListener``, such as + ``'my.package.CustomListener'``. + +* A dict with a ``'()'`` key which is constructed in the usual way as discussed in + :ref:`logging-config-dict-userdef`. The result of this construction should be a + callable with the same signature as the ``QueueListener`` initializer. + +If the ``listener`` key is absent, :class:`logging.handlers.QueueListener` is used. + +The values under the ``handlers`` key are the names of other handlers in the +configuration (not shown in the above snippet) which will be passed to the queue +listener. + +Any custom queue handler and listener classes will need to be defined with the same +initialization signatures as :class:`~logging.handlers.QueueHandler` and +:class:`~logging.handlers.QueueListener`. + +.. versionadded:: 3.12 .. _logging-config-fileformat: @@ -692,7 +838,7 @@ root logger section is given below. The ``level`` entry can be one of ``DEBUG, INFO, WARNING, ERROR, CRITICAL`` or ``NOTSET``. For the root logger only, ``NOTSET`` means that all messages will be -logged. Level values are :func:`eval`\ uated in the context of the ``logging`` +logged. Level values are :ref:`evaluated ` in the context of the ``logging`` package's namespace. The ``handlers`` entry is a comma-separated list of handler names, which must @@ -739,13 +885,13 @@ handler. If blank, a default formatter (``logging._defaultFormatter``) is used. If a name is specified, it must appear in the ``[formatters]`` section and have a corresponding section in the configuration file. -The ``args`` entry, when :func:`eval`\ uated in the context of the ``logging`` +The ``args`` entry, when :ref:`evaluated ` in the context of the ``logging`` package's namespace, is the list of arguments to the constructor for the handler class. Refer to the constructors for the relevant handlers, or to the examples below, to see how typical entries are constructed. If not provided, it defaults to ``()``. -The optional ``kwargs`` entry, when :func:`eval`\ uated in the context of the +The optional ``kwargs`` entry, when :ref:`evaluated ` in the context of the ``logging`` package's namespace, is the keyword argument dict to the constructor for the handler class. If not provided, it defaults to ``{}``. @@ -809,7 +955,7 @@ Sections which specify formatter configuration are typified by the following. [formatter_form01] format=F1 %(asctime)s %(levelname)s %(message)s datefmt= - style='%' + style=% validate=True class=logging.Formatter diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index 56256900ac9..d4429d3d0a4 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -234,6 +234,19 @@ need to override. return the same output every time for a given input, otherwise the rollover behaviour may not work as expected. + It's also worth noting that care should be taken when using a namer to + preserve certain attributes in the filename which are used during rotation. + For example, :class:`RotatingFileHandler` expects to have a set of log files + whose names contain successive integers, so that rotation works as expected, + and :class:`TimedRotatingFileHandler` deletes old log files (based on the + ``backupCount`` parameter passed to the handler's initializer) by determining + the oldest files to delete. For this to happen, the filenames should be + sortable using the date/time portion of the filename, and a namer needs to + respect this. (If a namer is wanted that doesn't respect this scheme, it will + need to be used in a subclass of :class:`TimedRotatingFileHandler` which + overrides the :meth:`~TimedRotatingFileHandler.getFilesToDelete` method to + fit in with the custom naming scheme.) + .. versionadded:: 3.3 @@ -443,6 +456,10 @@ timed intervals. Outputs the record to the file, catering for rollover as described above. + .. method:: getFilesToDelete() + + Returns a list of filenames which should be deleted as part of rollover. These + are the absolute paths of the oldest backup log files written by the handler. .. _socket-handler: @@ -555,6 +572,13 @@ over UDP sockets. Returns a new instance of the :class:`DatagramHandler` class intended to communicate with a remote machine whose address is given by *host* and *port*. + .. note:: As UDP is not a streaming protocol, there is no persistent connection + between an instance of this handler and *host*. For this reason, when using a + network socket, a DNS lookup might have to be made each time an event is + logged, which can introduce some latency into the system. If this affects you, + you can do a lookup yourself and initialize this handler using the looked-up IP + address rather than the hostname. + .. versionchanged:: 3.4 If ``port`` is specified as ``None``, a Unix domain socket is created using the value in ``host`` - otherwise, a UDP socket is created. @@ -612,6 +636,12 @@ supports sending logging messages to a remote or local Unix syslog. application needs to run on several platforms). On Windows, you pretty much have to use the UDP option. + .. note:: On macOS 12.x (Monterey), Apple has changed the behaviour of their + syslog daemon - it no longer listens on a domain socket. Therefore, you cannot + expect :class:`SysLogHandler` to work on this system. + + See :gh:`91070` for more information. + .. versionchanged:: 3.2 *socktype* was added. @@ -620,6 +650,17 @@ supports sending logging messages to a remote or local Unix syslog. Closes the socket to the remote host. + .. method:: createSocket() + + Tries to create a socket and, if it's not a datagram socket, connect it + to the other end. This method is called during handler initialization, + but it's not regarded as an error if the other end isn't listening at + this point - the method will be called again when emitting an event, if + but it's not regarded as an error if the other end isn't listening yet + --- the method will be called again when emitting an event, + if there is no socket at that point. + + .. versionadded:: 3.11 .. method:: emit(record) @@ -1001,6 +1042,8 @@ possible, while any potentially slow operations (such as sending an email via have the task tracking API, which means that you can use :class:`~queue.SimpleQueue` instances for *queue*. + .. note:: If you are using :mod:`multiprocessing`, you should avoid using + :class:`~queue.SimpleQueue` and instead use :class:`multiprocessing.Queue`. .. method:: emit(record) @@ -1017,7 +1060,7 @@ possible, while any potentially slow operations (such as sending an email via method is enqueued. The base implementation formats the record to merge the message, - arguments, and exception information, if present. It also removes + arguments, exception and stack information, if present. It also removes unpickleable items from the record in-place. Specifically, it overwrites the record's :attr:`msg` and :attr:`message` attributes with the merged message (obtained by calling the handler's :meth:`format` method), and @@ -1028,13 +1071,33 @@ possible, while any potentially slow operations (such as sending an email via the record to a dict or JSON string, or send a modified copy of the record while leaving the original intact. + .. note:: The base implementation formats the message with arguments, sets + the ``message`` and ``msg`` attributes to the formatted message and + sets the ``args`` and ``exc_text`` attributes to ``None`` to allow + pickling and to prevent further attempts at formatting. This means + that a handler on the :class:`QueueListener` side won't have the + information to do custom formatting, e.g. of exceptions. You may wish + to subclass ``QueueHandler`` and override this method to e.g. avoid + setting ``exc_text`` to ``None``. Note that the ``message`` / ``msg`` + / ``args`` changes are related to ensuring the record is pickleable, + and you might or might not be able to avoid doing that depending on + whether your ``args`` are pickleable. (Note that you may have to + consider not only your own code but also code in any libraries that + you use.) + .. method:: enqueue(record) Enqueues the record on the queue using ``put_nowait()``; you may want to override this if you want to use blocking behaviour, or a timeout, or a customized queue implementation. + .. attribute:: listener + When created via configuration using :func:`~logging.config.dictConfig`, this + attribute will contain a :class:`QueueListener` instance for use with this + handler. Otherwise, it will be ``None``. + + .. versionadded:: 3.12 .. _queue-listener: @@ -1068,6 +1131,9 @@ possible, while any potentially slow operations (such as sending an email via task tracking API (though it's used if available), which means that you can use :class:`~queue.SimpleQueue` instances for *queue*. + .. note:: If you are using :mod:`multiprocessing`, you should avoid using + :class:`~queue.SimpleQueue` and instead use :class:`multiprocessing.Queue`. + If ``respect_handler_level`` is ``True``, a handler's level is respected (compared with the level for the message) when deciding whether to pass messages to that handler; otherwise, the behaviour is as in previous Python diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 3f3a8534f54..34e98fc2577 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -30,9 +30,17 @@ is that all Python modules can participate in logging, so your application log can include your own messages integrated with messages from third-party modules. +The simplest example: + +.. code-block:: none + + >>> import logging + >>> logging.warning('Watch out!') + WARNING:root:Watch out! + The module provides a lot of functionality and flexibility. If you are -unfamiliar with logging, the best way to get to grips with it is to see the -tutorials (see the links on the right). +unfamiliar with logging, the best way to get to grips with it is to view the +tutorials (**see the links above and on the right**). The basic classes defined by the module, together with their functions, are listed below. @@ -80,6 +88,15 @@ is the module's name in the Python package namespace. If this evaluates to false, logging messages are not passed to the handlers of ancestor loggers. + Spelling it out with an example: If the propagate attribute of the logger named + ``A.B.C`` evaluates to true, any event logged to ``A.B.C`` via a method call such as + ``logging.getLogger('A.B.C').error(...)`` will [subject to passing that logger's + level and filter settings] be passed in turn to any handlers attached to loggers + named ``A.B``, ``A`` and the root logger, after first being passed to any handlers + attached to ``A.B.C``. If any logger in the chain ``A.B.C``, ``A.B``, ``A`` has its + ``propagate`` attribute set to false, then that is the last logger whose handlers + are offered the event to handle, and propagation stops at that point. + The constructor sets this attribute to ``True``. .. note:: If you attach a handler to a logger *and* one or more of its @@ -153,6 +170,18 @@ is the module's name in the Python package namespace. .. versionadded:: 3.2 + .. method:: Logger.getChildren() + + Returns a set of loggers which are immediate children of this logger. So for + example ``logging.getLogger().getChildren()`` might return a set containing + loggers named ``foo`` and ``bar``, but a logger named ``foo.bar`` wouldn't be + included in the set. Likewise, ``logging.getLogger('foo').getChildren()`` might + return a set including a logger named ``foo.bar``, but it wouldn't include one + named ``foo.bar.baz``. + + .. versionadded:: 3.12 + + .. method:: Logger.debug(msg, *args, **kwargs) Logs a message with level :const:`DEBUG` on this logger. The *msg* is the @@ -216,7 +245,7 @@ is the module's name in the Python package namespace. 2006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection reset The keys in the dictionary passed in *extra* should not clash with the keys used - by the logging system. (See the :class:`Formatter` documentation for more + by the logging system. (See the section on :ref:`logrecord-attributes` for more information on which keys are used by the logging system.) If you choose to use these attributes in logged messages, you need to exercise @@ -233,6 +262,10 @@ is the module's name in the Python package namespace. above example). In such circumstances, it is likely that specialized :class:`Formatter`\ s would be used with particular :class:`Handler`\ s. + If no handler is attached to this logger (or any of its ancestors, + taking into account the relevant :attr:`Logger.propagate` attributes), + the message will be sent to the handler set on :attr:`lastResort`. + .. versionchanged:: 3.2 The *stack_info* parameter was added. @@ -501,6 +534,22 @@ subclasses. However, the :meth:`__init__` method in subclasses needs to call is intended to be implemented by subclasses and so raises a :exc:`NotImplementedError`. + .. warning:: This method is called after a handler-level lock is acquired, which + is released after this method returns. When you override this method, note + that you should be careful when calling anything that invokes other parts of + the logging API which might do locking, because that might result in a + deadlock. Specifically: + + * Logging configuration APIs acquire the module-level lock, and then + individual handler-level locks as those handlers are configured. + + * Many logging APIs lock the module-level lock. If such an API is called + from this method, it could cause a deadlock if a configuration call is + made on another thread, because that thread will try to acquire the + module-level lock *before* the handler-level lock, whereas this thread + tries to acquire the module-level lock *after* the handler-level lock + (because in this method, the handler-level lock has already been acquired). + For a list of handlers included as standard, see :mod:`logging.handlers`. .. _formatter-objects: @@ -510,55 +559,53 @@ Formatter Objects .. currentmodule:: logging -:class:`Formatter` objects have the following attributes and methods. They are -responsible for converting a :class:`LogRecord` to (usually) a string which can -be interpreted by either a human or an external system. The base -:class:`Formatter` allows a formatting string to be specified. If none is -supplied, the default value of ``'%(message)s'`` is used, which just includes -the message in the logging call. To have additional items of information in the -formatted output (such as a timestamp), keep reading. - -A Formatter can be initialized with a format string which makes use of knowledge -of the :class:`LogRecord` attributes - such as the default value mentioned above -making use of the fact that the user's message and arguments are pre-formatted -into a :class:`LogRecord`'s *message* attribute. This format string contains -standard Python %-style mapping keys. See section :ref:`old-string-formatting` -for more information on string formatting. - -The useful mapping keys in a :class:`LogRecord` are given in the section on -:ref:`logrecord-attributes`. - - .. class:: Formatter(fmt=None, datefmt=None, style='%', validate=True, *, defaults=None) - Returns a new instance of the :class:`Formatter` class. The instance is - initialized with a format string for the message as a whole, as well as a - format string for the date/time portion of a message. If no *fmt* is - specified, ``'%(message)s'`` is used. If no *datefmt* is specified, a format - is used which is described in the :meth:`formatTime` documentation. + Responsible for converting a :class:`LogRecord` to an output string + to be interpreted by a human or external system. - The *style* parameter can be one of '%', '{' or '$' and determines how - the format string will be merged with its data: using one of %-formatting, - :meth:`str.format` or :class:`string.Template`. This only applies to the - format string *fmt* (e.g. ``'%(message)s'`` or ``{message}``), not to the - actual log messages passed to ``Logger.debug`` etc; see - :ref:`formatting-styles` for more information on using {- and $-formatting - for log messages. + :param fmt: A format string in the given *style* for + the logged output as a whole. + The possible mapping keys are drawn from the :class:`LogRecord` object's + :ref:`logrecord-attributes`. + If not specified, ``'%(message)s'`` is used, + which is just the logged message. + :type fmt: str - The *defaults* parameter can be a dictionary with default values to use in - custom fields. For example: - ``logging.Formatter('%(ip)s %(message)s', defaults={"ip": None})`` + :param datefmt: A format string in the given *style* for + the date/time portion of the logged output. + If not specified, the default described in :meth:`formatTime` is used. + :type datefmt: str - .. versionchanged:: 3.2 - The *style* parameter was added. + :param style: Can be one of ``'%'``, ``'{'`` or ``'$'`` and determines + how the format string will be merged with its data: using one of + :ref:`old-string-formatting` (``%``), :meth:`str.format` (``{``) + or :class:`string.Template` (``$``). This only applies to + *fmt* and *datefmt* (e.g. ``'%(message)s'`` versus ``'{message}'``), + not to the actual log messages passed to the logging methods. + However, there are :ref:`other ways ` + to use ``{``- and ``$``-formatting for log messages. + :type style: str - .. versionchanged:: 3.8 - The *validate* parameter was added. Incorrect or mismatched style and fmt - will raise a ``ValueError``. - For example: ``logging.Formatter('%(asctime)s - %(message)s', style='{')``. + :param validate: If ``True`` (the default), incorrect or mismatched + *fmt* and *style* will raise a :exc:`ValueError`; for example, + ``logging.Formatter('%(asctime)s - %(message)s', style='{')``. + :type validate: bool + + :param defaults: A dictionary with default values to use in custom fields. + For example, + ``logging.Formatter('%(ip)s %(message)s', defaults={"ip": None})`` + :type defaults: dict[str, Any] + + .. versionadded:: 3.2 + The *style* parameter. + + .. versionadded:: 3.8 + The *validate* parameter. + + .. versionadded:: 3.10 + The *defaults* parameter. - .. versionchanged:: 3.10 - The *defaults* parameter was added. .. method:: format(record) @@ -631,6 +678,35 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on :func:`traceback.print_stack`, but with the last newline removed) as a string. This default implementation just returns the input value. +.. class:: BufferingFormatter(linefmt=None) + + A base formatter class suitable for subclassing when you want to format a + number of records. You can pass a :class:`Formatter` instance which you want + to use to format each line (that corresponds to a single record). If not + specified, the default formatter (which just outputs the event message) is + used as the line formatter. + + .. method:: formatHeader(records) + + Return a header for a list of *records*. The base implementation just + returns the empty string. You will need to override this method if you + want specific behaviour, e.g. to show the count of records, a title or a + separator line. + + .. method:: formatFooter(records) + + Return a footer for a list of *records*. The base implementation just + returns the empty string. You will need to override this method if you + want specific behaviour, e.g. to show the count of records or a separator + line. + + .. method:: format(records) + + Return formatted text for a list of *records*. The base implementation + just returns the empty string if there are no records; otherwise, it + returns the concatenation of the header, each record formatted with the + line formatter, and the footer. + .. _filter: Filter Objects @@ -653,9 +729,10 @@ empty string, all events are passed. .. method:: filter(record) - Is the specified record to be logged? Returns zero for no, nonzero for - yes. If deemed appropriate, the record may be modified in-place by this - method. + Is the specified record to be logged? Returns false for no, true for + yes. Filters can either modify log records in-place or return a completely + different record instance which will replace the original + log record in any future processing of the event. Note that filters attached to handlers are consulted before an event is emitted by the handler, whereas filters attached to loggers are consulted @@ -677,6 +754,12 @@ which has a ``filter`` method with the same semantics. parameter. The returned value should conform to that returned by :meth:`~Filter.filter`. +.. versionchanged:: 3.12 + You can now return a :class:`LogRecord` instance from filters to replace + the log record rather than modifying it in place. This allows filters attached to + a :class:`Handler` to modify the log record before it is emitted, without + having side effects on other handlers. + Although filters are used primarily to filter records based on more sophisticated criteria than levels, they get to see every record which is processed by the handler or logger they're attached to: this can be useful if @@ -686,6 +769,7 @@ the :class:`LogRecord` being processed. Obviously changing the LogRecord needs to be done with some care, but it does allow the injection of contextual information into logs (see :ref:`filters-contextual`). + .. _log-record: LogRecord Objects @@ -701,32 +785,54 @@ wire). Contains all the information pertinent to the event being logged. - The primary information is passed in :attr:`msg` and :attr:`args`, which - are combined using ``msg % args`` to create the :attr:`message` field of the - record. + The primary information is passed in *msg* and *args*, + which are combined using ``msg % args`` to create + the :attr:`!message` attribute of the record. + + :param name: The name of the logger used to log the event + represented by this :class:`!LogRecord`. + Note that the logger name in the :class:`!LogRecord` + will always have this value, + even though it may be emitted by a handler + attached to a different (ancestor) logger. + :type name: str + + :param level: The :ref:`numeric level ` of the logging event + (such as ``10`` for ``DEBUG``, ``20`` for ``INFO``, etc). + Note that this is converted to *two* attributes of the LogRecord: + :attr:`!levelno` for the numeric value + and :attr:`!levelname` for the corresponding level name. + :type level: int + + :param pathname: The full string path of the source file + where the logging call was made. + :type pathname: str + + :param lineno: The line number in the source file + where the logging call was made. + :type lineno: int + + :param msg: The event description message, + which can be a %-format string with placeholders for variable data. + :type msg: str + + :param args: Variable data to merge into the *msg* argument + to obtain the event description. + :type args: tuple | dict[str, typing.Any] - :param name: The name of the logger used to log the event represented by - this LogRecord. Note that this name will always have this - value, even though it may be emitted by a handler attached to - a different (ancestor) logger. - :param level: The numeric level of the logging event (one of DEBUG, INFO etc.) - Note that this is converted to *two* attributes of the LogRecord: - ``levelno`` for the numeric value and ``levelname`` for the - corresponding level name. - :param pathname: The full pathname of the source file where the logging call - was made. - :param lineno: The line number in the source file where the logging call was - made. - :param msg: The event description message, possibly a format string with - placeholders for variable data. - :param args: Variable data to merge into the *msg* argument to obtain the - event description. :param exc_info: An exception tuple with the current exception information, - or ``None`` if no exception information is available. - :param func: The name of the function or method from which the logging call - was invoked. - :param sinfo: A text string representing stack information from the base of - the stack in the current thread, up to the logging call. + as returned by :func:`sys.exc_info`, + or ``None`` if no exception information is available. + :type exc_info: tuple[type[BaseException], BaseException, types.TracebackType] | None + + :param func: The name of the function or method + from which the logging call was invoked. + :type func: str | None + + :param sinfo: A text string representing stack information + from the base of the stack in the current thread, + up to the logging call. + :type sinfo: str | None .. method:: getMessage() @@ -859,10 +965,14 @@ the options available to you. +----------------+-------------------------+-----------------------------------------------+ | threadName | ``%(threadName)s`` | Thread name (if available). | +----------------+-------------------------+-----------------------------------------------+ +| taskName | ``%(taskName)s`` | :class:`asyncio.Task` name (if available). | ++----------------+-------------------------+-----------------------------------------------+ .. versionchanged:: 3.1 *processName* was added. +.. versionchanged:: 3.12 + *taskName* was added. .. _logger-adapter: @@ -1029,6 +1139,10 @@ functions. above example). In such circumstances, it is likely that specialized :class:`Formatter`\ s would be used with particular :class:`Handler`\ s. + This function (as well as :func:`info`, :func:`warning`, :func:`error` and + :func:`critical`) will call :func:`basicConfig` if the root logger doesn't + have any handler attached. + .. versionchanged:: 3.2 The *stack_info* parameter was added. @@ -1071,16 +1185,6 @@ functions. Logs a message with level *level* on the root logger. The other arguments are interpreted as for :func:`debug`. - .. note:: The above module-level convenience functions, which delegate to the - root logger, call :func:`basicConfig` to ensure that at least one handler - is available. Because of this, they should *not* be used in threads, - in versions of Python earlier than 2.7.1 and 3.2, unless at least one - handler has been added to the root logger *before* the threads are - started. In earlier versions of Python, due to a thread safety shortcoming - in :func:`basicConfig`, this can (under rare circumstances) lead to - handlers being added multiple times to the root logger, which can in turn - lead to multiple messages for the same event. - .. function:: disable(level=CRITICAL) Provides an overriding level *level* for all loggers which takes precedence over @@ -1153,6 +1257,19 @@ functions. This undocumented behaviour was considered a mistake, and was removed in Python 3.4, but reinstated in 3.4.2 due to retain backward compatibility. +.. function:: getHandlerByName(name) + + Returns a handler with the specified *name*, or ``None`` if there is no handler + with that name. + + .. versionadded:: 3.12 + +.. function:: getHandlerNames() + + Returns an immutable set of all known handler names. + + .. versionadded:: 3.12 + .. function:: makeLogRecord(attrdict) Creates and returns a new :class:`LogRecord` instance whose attributes are diff --git a/Doc/library/lzma.rst b/Doc/library/lzma.rst index 21092645366..868d4dcfb6c 100644 --- a/Doc/library/lzma.rst +++ b/Doc/library/lzma.rst @@ -258,7 +258,7 @@ Compressing and decompressing data in memory will be set to ``True``. Attempting to decompress data after the end of stream is reached - raises an `EOFError`. Any data found after the end of the + raises an :exc:`EOFError`. Any data found after the end of the stream is ignored and saved in the :attr:`~.unused_data` attribute. .. versionchanged:: 3.5 diff --git a/Doc/library/mailbox.rst b/Doc/library/mailbox.rst index 94d95d10290..56908dedea1 100644 --- a/Doc/library/mailbox.rst +++ b/Doc/library/mailbox.rst @@ -426,7 +426,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. .. seealso:: - `maildir man page from Courier `_ + `maildir man page from Courier `_ A specification of the format. Describes a common extension for supporting folders. @@ -614,7 +614,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. .. seealso:: - `nmh - Message Handling System `_ + `nmh - Message Handling System `_ Home page of :program:`nmh`, an updated version of the original :program:`mh`. `MH & nmh: Email for Users & Programmers `_ @@ -1510,7 +1510,7 @@ The following exception classes are defined in the :mod:`mailbox` module: Raised when some mailbox-related condition beyond the control of the program causes it to be unable to proceed, such as when failing to acquire a lock that - another program already holds a lock, or when a uniquely-generated file name + another program already holds a lock, or when a uniquely generated file name already exists. diff --git a/Doc/library/mailcap.rst b/Doc/library/mailcap.rst index 7749b7dd45e..bfaedb46091 100644 --- a/Doc/library/mailcap.rst +++ b/Doc/library/mailcap.rst @@ -3,9 +3,15 @@ .. module:: mailcap :synopsis: Mailcap file handling. + :deprecated: **Source code:** :source:`Lib/mailcap.py` +.. deprecated-removed:: 3.11 3.13 + The :mod:`mailcap` module is deprecated + (see :pep:`PEP 594 <594#mailcap>` for details). + The :mod:`mimetypes` module provides an alternative. + -------------- Mailcap files are used to configure how MIME-aware applications such as mail @@ -54,6 +60,18 @@ standard. However, mailcap files are supported on most Unix systems. use) to determine whether or not the mailcap line applies. :func:`findmatch` will automatically check such conditions and skip the entry if the check fails. + .. versionchanged:: 3.11 + + To prevent security issues with shell metacharacters (symbols that have + special effects in a shell command line), ``findmatch`` will refuse + to inject ASCII characters other than alphanumerics and ``@+=:,./-_`` + into the returned command line. + + If a disallowed character appears in *filename*, ``findmatch`` will always + return ``(None, None)`` as if no entry was found. + If such a character appears elsewhere (a value in *plist* or in *MIMEtype*), + ``findmatch`` will ignore all mailcap entries which use that value. + A :mod:`warning ` will be raised in either case. .. function:: getcaps() diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 71186788a65..9da22b6ad05 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -32,8 +32,8 @@ Number-theoretic and representation functions .. function:: ceil(x) Return the ceiling of *x*, the smallest integer greater than or equal to *x*. - If *x* is not a float, delegates to ``x.__ceil__()``, which should return an - :class:`~numbers.Integral` value. + If *x* is not a float, delegates to :meth:`x.__ceil__ `, + which should return an :class:`~numbers.Integral` value. .. function:: comb(n, k) @@ -45,8 +45,8 @@ Number-theoretic and representation functions to zero when ``k > n``. Also called the binomial coefficient because it is equivalent - to the coefficient of k-th term in polynomial expansion of the - expression ``(1 + x) ** n``. + to the coefficient of k-th term in polynomial expansion of + ``(1 + x)â¿``. Raises :exc:`TypeError` if either of the arguments are not integers. Raises :exc:`ValueError` if either of the arguments are negative. @@ -66,9 +66,9 @@ Number-theoretic and representation functions Return the absolute value of *x*. -.. function:: factorial(x) +.. function:: factorial(n) - Return *x* factorial as an integer. Raises :exc:`ValueError` if *x* is not integral or + Return *n* factorial as an integer. Raises :exc:`ValueError` if *n* is not integral or is negative. .. deprecated:: 3.9 @@ -77,9 +77,9 @@ Number-theoretic and representation functions .. function:: floor(x) - Return the floor of *x*, the largest integer less than or equal to *x*. - If *x* is not a float, delegates to ``x.__floor__()``, which should return an - :class:`~numbers.Integral` value. + Return the floor of *x*, the largest integer less than or equal to *x*. If + *x* is not a float, delegates to :meth:`x.__floor__ `, which + should return an :class:`~numbers.Integral` value. .. function:: fmod(x, y) @@ -108,12 +108,7 @@ Number-theoretic and representation functions .. function:: fsum(iterable) Return an accurate floating point sum of values in the iterable. Avoids - loss of precision by tracking multiple intermediate partial sums:: - - >>> sum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1]) - 0.9999999999999999 - >>> fsum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1]) - 1.0 + loss of precision by tracking multiple intermediate partial sums. The algorithm's accuracy depends on IEEE-754 arithmetic guarantees and the typical case where the rounding mode is half-even. On some non-Windows @@ -296,11 +291,29 @@ Number-theoretic and representation functions .. versionadded:: 3.7 +.. function:: sumprod(p, q) + + Return the sum of products of values from two iterables *p* and *q*. + + Raises :exc:`ValueError` if the inputs do not have the same length. + + Roughly equivalent to:: + + sum(itertools.starmap(operator.mul, zip(p, q, strict=True))) + + For float and mixed int/float inputs, the intermediate products + and sums are computed with extended precision. + + .. versionadded:: 3.12 + + .. function:: trunc(x) - Return the :class:`~numbers.Real` value *x* truncated to an - :class:`~numbers.Integral` (usually an integer). Delegates to - :meth:`x.__trunc__() `. + Return *x* with the fractional part + removed, leaving the integer part. This rounds toward 0: ``trunc()`` is + equivalent to :func:`floor` for positive *x*, and equivalent to :func:`ceil` + for negative *x*. If *x* is not a float, delegates to :meth:`x.__trunc__ + `, which should return an :class:`~numbers.Integral` value. .. function:: ulp(x) @@ -356,13 +369,20 @@ Power and logarithmic functions or ``pow(math.e, x)``. +.. function:: exp2(x) + + Return *2* raised to the power *x*. + + .. versionadded:: 3.11 + + .. function:: expm1(x) Return *e* raised to the power *x*, minus 1. Here *e* is the base of natural logarithms. For small floats *x*, the subtraction in ``exp(x) - 1`` can result in a `significant loss of precision `_\; the :func:`expm1` - function provides a way to compute this quantity to full precision:: + function provides a way to compute this quantity to full precision: >>> from math import exp, expm1 >>> exp(1e-5) - 1 # gives result accurate to 11 places @@ -373,13 +393,12 @@ Power and logarithmic functions .. versionadded:: 3.2 -.. function:: log(x[, base]) +.. function:: log(x, base=None) - With one argument, return the natural logarithm of *x* (to base *e*). - - With two arguments, return the logarithm of *x* to the given *base*, - calculated as ``log(x)/log(base)``. + Return the logarithm of *x* to the given *base*. + If the *base* is not specified, returns the natural + logarithm (base *e*) of *x*. .. function:: log1p(x) @@ -525,7 +544,7 @@ Angular conversion Hyperbolic functions -------------------- -`Hyperbolic functions `_ +`Hyperbolic functions `_ are analogs of trigonometric functions that are based on hyperbolas instead of circles. @@ -569,7 +588,7 @@ Special functions The :func:`erf` function can be used to compute traditional statistical functions such as the `cumulative standard normal distribution - `_:: + `_:: def phi(x): 'Cumulative distribution function for the standard normal distribution' @@ -639,8 +658,26 @@ Constants .. data:: nan - A floating-point "not a number" (NaN) value. Equivalent to the output of - ``float('nan')``. + A floating-point "not a number" (NaN) value. Equivalent to the output of + ``float('nan')``. Due to the requirements of the `IEEE-754 standard + `_, ``math.nan`` and ``float('nan')`` are + not considered to equal to any other numeric value, including themselves. To check + whether a number is a NaN, use the :func:`isnan` function to test + for NaNs instead of ``is`` or ``==``. + Example: + + >>> import math + >>> math.nan == math.nan + False + >>> float('nan') == float('nan') + False + >>> math.isnan(math.nan) + True + >>> math.isnan(float('nan')) + True + + .. versionchanged:: 3.11 + It is now always available. .. versionadded:: 3.5 diff --git a/Doc/library/mm.rst b/Doc/library/mm.rst index c8f79c4de1c..cd06e9385a2 100644 --- a/Doc/library/mm.rst +++ b/Doc/library/mm.rst @@ -11,12 +11,5 @@ discretion of the installation. Here's an overview: .. toctree:: - audioop.rst - aifc.rst - sunau.rst wave.rst - chunk.rst colorsys.rst - imghdr.rst - sndhdr.rst - ossaudiodev.rst diff --git a/Doc/library/mmap.rst b/Doc/library/mmap.rst index c1ebd80abd9..c4f8781f2ac 100644 --- a/Doc/library/mmap.rst +++ b/Doc/library/mmap.rst @@ -6,6 +6,8 @@ -------------- +.. include:: ../includes/wasm-notavail.rst + Memory-mapped file objects behave like both :class:`bytearray` and like :term:`file objects `. You can use mmap objects in most places where :class:`bytearray` are expected; for example, you can use the :mod:`re` @@ -102,7 +104,7 @@ To map anonymous memory, -1 should be passed as the fileno along with the length To ensure validity of the created memory mapping the file specified by the descriptor *fileno* is internally automatically synchronized - with physical backing store on macOS and OpenVMS. + with the physical backing store on macOS. This example shows a simple way of using :class:`~mmap.mmap`:: @@ -367,8 +369,12 @@ MAP_* Constants MAP_ANON MAP_ANONYMOUS MAP_POPULATE + MAP_STACK These are the various flags that can be passed to :meth:`mmap.mmap`. Note that some options might not be present on some systems. .. versionchanged:: 3.10 Added MAP_POPULATE constant. + + .. versionadded:: 3.11 + Added MAP_STACK constant. diff --git a/Doc/library/modulefinder.rst b/Doc/library/modulefinder.rst index 7b39ce7d1aa..526f0ff868c 100644 --- a/Doc/library/modulefinder.rst +++ b/Doc/library/modulefinder.rst @@ -96,14 +96,14 @@ Sample output (may vary depending on the architecture):: Loaded modules: _types: copyreg: _inverted_registry,_slotnames,__all__ - sre_compile: isstring,_sre,_optimize_unicode + re._compiler: isstring,_sre,_optimize_unicode _sre: - sre_constants: REPEAT_ONE,makedict,AT_END_LINE + re._constants: REPEAT_ONE,makedict,AT_END_LINE sys: re: __module__,finditer,_expand itertools: __main__: re,itertools,baconhameggs - sre_parse: _PATTERNENDERS,SRE_FLAG_UNICODE + re._parser: _PATTERNENDERS,SRE_FLAG_UNICODE array: types: __module__,IntType,TypeType --------------------------------------------------- diff --git a/Doc/library/modules.rst b/Doc/library/modules.rst index 565ce0525c2..8c5936a4d8d 100644 --- a/Doc/library/modules.rst +++ b/Doc/library/modules.rst @@ -17,4 +17,7 @@ The full list of modules described in this chapter is: modulefinder.rst runpy.rst importlib.rst + importlib.resources.rst + importlib.resources.abc.rst importlib.metadata.rst + sys_path_init.rst diff --git a/Doc/library/msilib.rst b/Doc/library/msilib.rst index 22638852e31..fbe55db9372 100644 --- a/Doc/library/msilib.rst +++ b/Doc/library/msilib.rst @@ -4,6 +4,7 @@ .. module:: msilib :platform: Windows :synopsis: Creation of Microsoft Installer files, and CAB files. + :deprecated: .. moduleauthor:: Martin v. Löwis .. sectionauthor:: Martin v. Löwis @@ -12,6 +13,10 @@ .. index:: single: msi +.. deprecated-removed:: 3.11 3.13 + The :mod:`msilib` module is deprecated + (see :pep:`PEP 594 <594#msilib>` for details). + -------------- The :mod:`msilib` supports the creation of Microsoft Installer (``.msi``) files. diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 7a1a285255f..b5ceeb796f8 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -8,6 +8,8 @@ -------------- +.. include:: ../includes/wasm-notavail.rst + Introduction ------------ @@ -43,6 +45,16 @@ will print to standard output :: [1, 4, 9] +.. seealso:: + + :class:`concurrent.futures.ProcessPoolExecutor` offers a higher level interface + to push tasks to a background process without blocking execution of the + calling process. Compared to using the :class:`~multiprocessing.pool.Pool` + interface directly, the :mod:`concurrent.futures` API more readily allows + the submission of work to the underlying process pool to be separated from + waiting for the results. + + The :class:`Process` class ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -96,7 +108,7 @@ Depending on the platform, :mod:`multiprocessing` supports three ways to start a process. These *start methods* are *spawn* - The parent process starts a fresh python interpreter process. The + The parent process starts a fresh Python interpreter process. The child process will only inherit those resources necessary to run the process object's :meth:`~Process.run` method. In particular, unnecessary file descriptors and handles from the parent process @@ -132,8 +144,8 @@ to start a process. These *start methods* are subprocess. See :issue:`33725`. .. versionchanged:: 3.4 - *spawn* added on all unix platforms, and *forkserver* added for - some unix platforms. + *spawn* added on all Unix platforms, and *forkserver* added for + some Unix platforms. Child processes no longer inherit all of the parents inheritable handles on Windows. @@ -485,7 +497,9 @@ The :mod:`multiprocessing` package mostly replicates the API of the to ``True`` or ``False``. If ``None`` (the default), this flag will be inherited from the creating process. - By default, no arguments are passed to *target*. + By default, no arguments are passed to *target*. The *args* argument, + which defaults to ``()``, can be used to specify a list or tuple of the arguments + to pass to *target*. If a subclass overrides the constructor, it must make sure it invokes the base class constructor (:meth:`Process.__init__`) before doing anything else @@ -503,6 +517,19 @@ The :mod:`multiprocessing` package mostly replicates the API of the the target argument, if any, with sequential and keyword arguments taken from the *args* and *kwargs* arguments, respectively. + Using a list or tuple as the *args* argument passed to :class:`Process` + achieves the same effect. + + Example:: + + >>> from multiprocessing import Process + >>> p = Process(target=print, args=[1]) + >>> p.run() + 1 + >>> p = Process(target=print, args=(1,)) + >>> p.run() + 1 + .. method:: start() Start the process's activity. @@ -569,8 +596,15 @@ The :mod:`multiprocessing` package mostly replicates the API of the .. attribute:: exitcode The child's exit code. This will be ``None`` if the process has not yet - terminated. A negative value *-N* indicates that the child was terminated - by signal *N*. + terminated. + + If the child's :meth:`run` method returned normally, the exit code + will be 0. If it terminated via :func:`sys.exit` with an integer + argument *N*, the exit code will be *N*. + + If the child terminated due to an exception not caught within + :meth:`run`, the exit code will be 1. If it was terminated by + signal *N*, the exit code will be the negative value *-N*. .. attribute:: authkey @@ -640,7 +674,6 @@ The :mod:`multiprocessing` package mostly replicates the API of the Example usage of some of the methods of :class:`Process`: .. doctest:: - :options: +ELLIPSIS >>> import multiprocessing, time, signal >>> p = multiprocessing.Process(target=time.sleep, args=(1000,)) @@ -1040,9 +1073,9 @@ Miscellaneous .. versionadded:: 3.4 -.. function:: set_executable() +.. function:: set_executable(executable) - Sets the path of the Python interpreter to use when starting a child process. + Set the path of the Python interpreter to use when starting a child process. (By default :data:`sys.executable` is used). Embedders will probably need to do some thing like :: @@ -1053,10 +1086,17 @@ Miscellaneous .. versionchanged:: 3.4 Now supported on Unix when the ``'spawn'`` start method is used. -.. function:: set_start_method(method) + .. versionchanged:: 3.11 + Accepts a :term:`path-like object`. + +.. function:: set_start_method(method, force=False) Set the method which should be used to start child processes. - *method* can be ``'fork'``, ``'spawn'`` or ``'forkserver'``. + The *method* argument can be ``'fork'``, ``'spawn'`` or ``'forkserver'``. + Raises :exc:`RuntimeError` if the start method has already been set and *force* + is not ``True``. If *method* is ``None`` and *force* is ``True`` then the start + method is set to ``None``. If *method* is ``None`` and *force* is ``False`` + then the context is set to the default context. Note that this should be called at most once, and it should be protected inside the ``if __name__ == '__main__'`` clause of the @@ -1641,6 +1681,7 @@ different machines. A manager object controls a server process which manages proxies. .. function:: multiprocessing.Manager() + :module: Returns a started :class:`~multiprocessing.managers.SyncManager` object which can be used for sharing objects between processes. The returned manager @@ -1654,7 +1695,7 @@ Manager processes will be shutdown as soon as they are garbage collected or their parent process exits. The manager classes are defined in the :mod:`multiprocessing.managers` module: -.. class:: BaseManager([address[, authkey]]) +.. class:: BaseManager(address=None, authkey=None, serializer='pickle', ctx=None, *, shutdown_timeout=1.0) Create a BaseManager object. @@ -1669,6 +1710,20 @@ their parent process exits. The manager classes are defined in the *authkey* is ``None`` then ``current_process().authkey`` is used. Otherwise *authkey* is used and it must be a byte string. + *serializer* must be ``'pickle'`` (use :mod:`pickle` serialization) or + ``'xmlrpclib'`` (use :mod:`xmlrpc.client` serialization). + + *ctx* is a context object, or ``None`` (use the current context). See the + :func:`get_context` function. + + *shutdown_timeout* is a timeout in seconds used to wait until the process + used by the manager completes in the :meth:`shutdown` method. If the + shutdown times out, the process is terminated. If terminating the process + also times out, the process is killed. + + .. versionchanged:: 3.11 + Added the *shutdown_timeout* parameter. + .. method:: start([initializer[, initargs]]) Start a subprocess to start the manager. If *initializer* is not ``None`` @@ -2578,9 +2633,9 @@ Address Formats filesystem. * An ``'AF_PIPE'`` address is a string of the form - :samp:`r'\\\\.\\pipe\\{PipeName}'`. To use :func:`Client` to connect to a named + :samp:`r'\\\\\\.\\pipe\\\\{PipeName}'`. To use :func:`Client` to connect to a named pipe on a remote computer called *ServerName* one should use an address of the - form :samp:`r'\\\\{ServerName}\\pipe\\{PipeName}'` instead. + form :samp:`r'\\\\\\\\{ServerName}\\pipe\\\\{PipeName}'` instead. Note that any string beginning with two backslashes is assumed by default to be an ``'AF_PIPE'`` address rather than an ``'AF_UNIX'`` address. @@ -2903,6 +2958,8 @@ Global variables However, global variables which are just module level constants cause no problems. +.. _multiprocessing-safe-main-import: + Safe importing of main module Make sure that the main module can be safely imported by a new Python diff --git a/Doc/library/multiprocessing.shared_memory.rst b/Doc/library/multiprocessing.shared_memory.rst index 2ba42b7e579..76046b34610 100644 --- a/Doc/library/multiprocessing.shared_memory.rst +++ b/Doc/library/multiprocessing.shared_memory.rst @@ -1,5 +1,5 @@ -:mod:`multiprocessing.shared_memory` --- Provides shared memory for direct access across processes -=================================================================================================== +:mod:`multiprocessing.shared_memory` --- Shared memory for direct access across processes +========================================================================================= .. module:: multiprocessing.shared_memory :synopsis: Provides shared memory for direct access across processes. @@ -125,7 +125,7 @@ instances:: The following example demonstrates a practical use of the :class:`SharedMemory` -class with `NumPy arrays `_, accessing the +class with `NumPy arrays `_, accessing the same ``numpy.ndarray`` from two distinct Python shells: .. doctest:: diff --git a/Doc/library/netdata.rst b/Doc/library/netdata.rst index 16f43a69d68..1541e2a5444 100644 --- a/Doc/library/netdata.rst +++ b/Doc/library/netdata.rst @@ -13,10 +13,8 @@ on the internet. email.rst json.rst - mailcap.rst mailbox.rst mimetypes.rst base64.rst binascii.rst quopri.rst - uu.rst diff --git a/Doc/library/nis.rst b/Doc/library/nis.rst index 10c67cbb81b..3fa7916c37b 100644 --- a/Doc/library/nis.rst +++ b/Doc/library/nis.rst @@ -5,10 +5,15 @@ .. module:: nis :platform: Unix :synopsis: Interface to Sun's NIS (Yellow Pages) library. + :deprecated: .. moduleauthor:: Fred Gansevles .. sectionauthor:: Moshe Zadka +.. deprecated-removed:: 3.11 3.13 + The :mod:`nis` module is deprecated + (see :pep:`PEP 594 <594#nis>` for details). + -------------- The :mod:`nis` module gives a thin wrapper around the NIS library, useful for @@ -16,6 +21,8 @@ central administration of several hosts. Because NIS exists only on Unix systems, this module is only available for Unix. +.. include:: ../includes/wasm-notavail.rst + The :mod:`nis` module defines the following functions: diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst index e7ec9047e01..143e4e0c427 100644 --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -3,6 +3,7 @@ .. module:: nntplib :synopsis: NNTP protocol client (requires sockets). + :deprecated: **Source code:** :source:`Lib/nntplib.py` @@ -10,6 +11,26 @@ pair: NNTP; protocol single: Network News Transfer Protocol +.. deprecated:: 3.11 + The :mod:`nntplib` module is deprecated (see :pep:`594` for details). + +.. testsetup:: + + import warnings + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=DeprecationWarning) + import nntplib + +.. testcleanup:: + + try: + s.quit() + except NameError: + pass + import sys + # Force a warning if any other file imports nntplib + sys.modules.pop('nntplib') + -------------- This module defines the class :class:`NNTP` which implements the client side of @@ -17,6 +38,8 @@ the Network News Transfer Protocol. It can be used to implement a news reader or poster, or automated news processors. It is compatible with :rfc:`3977` as well as the older :rfc:`977` and :rfc:`2980`. +.. include:: ../includes/wasm-notavail.rst + Here are two small examples of how it can be used. To list some statistics about a newsgroup and print the subjects of the last 10 articles:: diff --git a/Doc/library/numbers.rst b/Doc/library/numbers.rst index b77845ed0de..b3dce151aee 100644 --- a/Doc/library/numbers.rst +++ b/Doc/library/numbers.rst @@ -58,11 +58,14 @@ The numeric tower .. class:: Rational - Subtypes :class:`Real` and adds - :attr:`~Rational.numerator` and :attr:`~Rational.denominator` properties, which - should be in lowest terms. With these, it provides a default for + Subtypes :class:`Real` and adds :attr:`~Rational.numerator` and + :attr:`~Rational.denominator` properties. It also provides a default for :func:`float`. + The :attr:`~Rational.numerator` and :attr:`~Rational.denominator` values + should be instances of :class:`Integral` and should be in lowest terms with + :attr:`~Rational.denominator` positive. + .. attribute:: numerator Abstract. @@ -202,9 +205,9 @@ forward and reverse instances of any given operator. For example, if isinstance(a, Rational): # Includes ints. return monomorphic_operator(a, b) - elif isinstance(a, numbers.Real): + elif isinstance(a, Real): return fallback_operator(float(a), float(b)) - elif isinstance(a, numbers.Complex): + elif isinstance(a, Complex): return fallback_operator(complex(a), complex(b)) else: return NotImplemented diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index b1094198f4c..3e29fed0175 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -131,7 +131,7 @@ option These option syntaxes are not supported by :mod:`optparse`, and they never will be. This is deliberate: the first three are non-standard on any environment, and the last only makes sense if you're exclusively targeting - VMS, MS-DOS, and/or Windows. + Windows or certain legacy platforms (e.g. VMS, MS-DOS). option argument an argument that follows an option, is closely associated with that option, @@ -404,7 +404,7 @@ Other actions Some other actions supported by :mod:`optparse` are: ``"store_const"`` - store a constant value + store a constant value, pre-set via :attr:`Option.const` ``"append"`` append this option's argument to a list @@ -529,7 +529,7 @@ help message: line-wrapping---\ :mod:`optparse` takes care of wrapping lines and making the help output look good. -* options that take a value indicate this fact in their automatically-generated +* options that take a value indicate this fact in their automatically generated help message, e.g. for the "mode" option:: -m MODE, --mode=MODE @@ -539,7 +539,7 @@ help message: :mod:`optparse` converts the destination variable name to uppercase and uses that for the meta-variable. Sometimes, that's not what you want---for example, the ``--filename`` option explicitly sets ``metavar="FILE"``, - resulting in this automatically-generated option description:: + resulting in this automatically generated option description:: -f FILE, --filename=FILE @@ -925,7 +925,7 @@ The canonical way to create an :class:`Option` instance is with the store this option's argument (default) ``"store_const"`` - store a constant value + store a constant value, pre-set via :attr:`Option.const` ``"store_true"`` store ``True`` @@ -937,7 +937,7 @@ The canonical way to create an :class:`Option` instance is with the append this option's argument to a list ``"append_const"`` - append a constant value to a list + append a constant value to a list, pre-set via :attr:`Option.const` ``"count"`` increment a counter by one @@ -1449,7 +1449,7 @@ intelligently and add conflicting options to it:: parser.add_option("-n", "--dry-run", ..., help="do no harm") parser.add_option("-n", "--noisy", ..., help="be noisy") -At this point, :mod:`optparse` detects that a previously-added option is already +At this point, :mod:`optparse` detects that a previously added option is already using the ``-n`` option string. Since ``conflict_handler`` is ``"resolve"``, it resolves the situation by removing ``-n`` from the earlier option's list of option strings. Now ``--dry-run`` is the only way for the user to activate @@ -1460,7 +1460,7 @@ that option. If the user asks for help, the help message will reflect that:: ... -n, --noisy be noisy -It's possible to whittle away the option strings for a previously-added option +It's possible to whittle away the option strings for a previously added option until there are none left, and the user has no way of invoking that option from the command-line. In that case, :mod:`optparse` removes that option completely, so it doesn't show up in help text or anywhere else. Carrying on with our diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index a66b3c5a3a9..786c2fd7f64 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -5,24 +5,18 @@ :synopsis: Operations on pathnames. **Source code:** :source:`Lib/posixpath.py` (for POSIX) and -:source:`Lib/ntpath.py` (for Windows NT). +:source:`Lib/ntpath.py` (for Windows). .. index:: single: path; operations -------------- -This module implements some useful functions on pathnames. To read or -write files see :func:`open`, and for accessing the filesystem see the -:mod:`os` module. The path parameters can be passed as either strings, -or bytes. Applications are encouraged to represent file names as -(Unicode) character strings. Unfortunately, some file names may not be -representable as strings on Unix, so applications that need to support -arbitrary file names on Unix should use bytes objects to represent -path names. Vice versa, using bytes objects cannot represent all file -names on Windows (in the standard ``mbcs`` encoding), hence Windows -applications should use string objects to access all files. +This module implements some useful functions on pathnames. To read or write +files see :func:`open`, and for accessing the filesystem see the :mod:`os` +module. The path parameters can be passed as strings, or bytes, or any object +implementing the :class:`os.PathLike` protocol. -Unlike a unix shell, Python does not do any *automatic* path expansions. +Unlike a Unix shell, Python does not do any *automatic* path expansions. Functions such as :func:`expanduser` and :func:`expandvars` can be invoked explicitly when an application desires shell-like path expansion. (See also the :mod:`glob` module.) @@ -38,7 +32,6 @@ the :mod:`glob` module.) their parameters. The result is an object of the same type, if a path or file name is returned. - .. note:: Since different operating systems have different path name conventions, there @@ -273,6 +266,15 @@ the :mod:`glob` module.) Accepts a :term:`path-like object`. +.. function:: isjunction(path) + + Return ``True`` if *path* refers to an :func:`existing ` directory + entry that is a junction. Always return ``False`` if junctions are not + supported on the current platform. + + .. versionadded:: 3.12 + + .. function:: islink(path) Return ``True`` if *path* refers to an :func:`existing ` directory @@ -304,17 +306,18 @@ the :mod:`glob` module.) .. function:: join(path, *paths) - Join one or more path components intelligently. The return value is the - concatenation of *path* and any members of *\*paths* with exactly one - directory separator following each non-empty part except the last, meaning - that the result will only end in a separator if the last part is empty. If - a component is an absolute path, all previous components are thrown away - and joining continues from the absolute path component. + Join one or more path segments intelligently. The return value is the + concatenation of *path* and all members of *\*paths*, with exactly one + directory separator following each non-empty part except the last. That is, + if the last part is empty, the result will end in a separator. If + a segment is an absolute path (which on Windows requires both a drive and a + root), then all previous segments are ignored and joining continues from the + absolute path segment. - On Windows, the drive letter is not reset when an absolute path component - (e.g., ``r'\foo'``) is encountered. If a component contains a drive - letter, all previous components are thrown away and the drive letter is - reset. Note that since there is a current directory for each drive, + On Windows, the drive is not reset when a rooted path segment (e.g., + ``r'\foo'``) is encountered. If a segment is on a different drive or is an + absolute path, all previous segments are ignored and the drive is reset. Note + that since there is a current directory for each drive, ``os.path.join("c:", "foo")`` represents a path relative to the current directory on drive :file:`C:` (:file:`c:foo`), not :file:`c:\\foo`. @@ -342,7 +345,7 @@ the :mod:`glob` module.) .. note:: On POSIX systems, in accordance with `IEEE Std 1003.1 2013 Edition; 4.13 - Pathname Resolution `_, + Pathname Resolution `_, if a pathname begins with exactly two slashes, the first component following the leading characters may be interpreted in an implementation-defined manner, although more than two leading characters shall be treated as a @@ -476,7 +479,7 @@ the :mod:`glob` module.) ("c:", "/dir") If the path contains a UNC path, drive will contain the host name - and share, up to but not including the fourth separator:: + and share:: >>> splitdrive("//host/computer/dir") ("//host/computer", "/dir") @@ -485,6 +488,39 @@ the :mod:`glob` module.) Accepts a :term:`path-like object`. +.. function:: splitroot(path) + + Split the pathname *path* into a 3-item tuple ``(drive, root, tail)`` where + *drive* is a device name or mount point, *root* is a string of separators + after the drive, and *tail* is everything after the root. Any of these + items may be the empty string. In all cases, ``drive + root + tail`` will + be the same as *path*. + + On POSIX systems, *drive* is always empty. The *root* may be empty (if *path* is + relative), a single forward slash (if *path* is absolute), or two forward slashes + (implementation-defined per `IEEE Std 1003.1-2017; 4.13 Pathname Resolution + `_.) + For example:: + + >>> splitroot('/home/sam') + ('', '/', 'home/sam') + >>> splitroot('//home/sam') + ('', '//', 'home/sam') + >>> splitroot('///home/sam') + ('', '/', '//home/sam') + + On Windows, *drive* may be empty, a drive-letter name, a UNC share, or a device + name. The *root* may be empty, a forward slash, or a backward slash. For + example:: + + >>> splitroot('C:/Users/Sam') + ('C:', '/', 'Users/Sam') + >>> splitroot('//Server/Share/Users/Sam') + ('//Server/Share', '/', 'Users/Sam') + + .. versionadded:: 3.12 + + .. function:: splitext(path) Split the pathname *path* into a pair ``(root, ext)`` such that ``root + ext == @@ -501,11 +537,16 @@ the :mod:`glob` module.) >>> splitext('foo.bar.exe') ('foo.bar', '.exe') + >>> splitext('/foo/bar.exe') + ('/foo/bar', '.exe') - Leading periods on the basename are ignored:: + Leading periods of the last component of the path are considered to + be part of the root:: >>> splitext('.cshrc') ('.cshrc', '') + >>> splitext('/foo/....jpg') + ('/foo/....jpg', '') .. versionchanged:: 3.6 Accepts a :term:`path-like object`. diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 8092397be65..fb091176767 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -34,6 +34,14 @@ Notes on the availability of these functions: * On VxWorks, os.popen, os.fork, os.execv and os.spawn*p* are not supported. +* On WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``, large + parts of the :mod:`os` module are not available or behave differently. API + related to processes (e.g. :func:`~os.fork`, :func:`~os.execve`), signals + (e.g. :func:`~os.kill`, :func:`~os.wait`), and resources + (e.g. :func:`~os.nice`) are not available. Others like :func:`~os.getuid` + and :func:`~os.getpid` are emulated or stubs. + + .. note:: All functions in this module raise :exc:`OSError` (or subclasses thereof) in @@ -105,15 +113,15 @@ of the UTF-8 encoding: * Use UTF-8 as the :term:`filesystem encoding `. -* :func:`sys.getfilesystemencoding()` returns ``'UTF-8'``. -* :func:`locale.getpreferredencoding()` returns ``'UTF-8'`` (the *do_setlocale* +* :func:`sys.getfilesystemencoding()` returns ``'utf-8'``. +* :func:`locale.getpreferredencoding()` returns ``'utf-8'`` (the *do_setlocale* argument has no effect). * :data:`sys.stdin`, :data:`sys.stdout`, and :data:`sys.stderr` all use UTF-8 as their text encoding, with the ``surrogateescape`` :ref:`error handler ` being enabled for :data:`sys.stdin` and :data:`sys.stdout` (:data:`sys.stderr` continues to use ``backslashreplace`` as it does in the default locale-aware mode) -* On Unix, :func:`os.device_encoding` returns ``'UTF-8'``. rather than the +* On Unix, :func:`os.device_encoding` returns ``'utf-8'`` rather than the device encoding. Note that the standard stream settings in UTF-8 mode can be overridden by @@ -151,6 +159,11 @@ can be read from :data:`sys.flags.utf8_mode `. See also the :ref:`UTF-8 mode on Windows ` and the :term:`filesystem encoding and error handler`. +.. seealso:: + + :pep:`686` + Python 3.15 will make :ref:`utf8-mode` default. + .. _os-procinfo: @@ -165,7 +178,7 @@ process and user. Return the filename corresponding to the controlling terminal of the process. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: environ @@ -177,8 +190,8 @@ process and user. This mapping is captured the first time the :mod:`os` module is imported, typically during Python startup as part of processing :file:`site.py`. Changes - to the environment made after this time are not reflected in ``os.environ``, - except for changes made by modifying ``os.environ`` directly. + to the environment made after this time are not reflected in :data:`os.environ`, + except for changes made by modifying :data:`os.environ` directly. This mapping may be used to modify the environment as well as query the environment. :func:`putenv` will be called automatically when the mapping @@ -190,8 +203,8 @@ process and user. .. note:: - Calling :func:`putenv` directly does not change ``os.environ``, so it's better - to modify ``os.environ``. + Calling :func:`putenv` directly does not change :data:`os.environ`, so it's better + to modify :data:`os.environ`. .. note:: @@ -201,7 +214,7 @@ process and user. You can delete items in this mapping to unset environment variables. :func:`unsetenv` will be called automatically when an item is deleted from - ``os.environ``, and when one of the :meth:`pop` or :meth:`clear` methods is + :data:`os.environ`, and when one of the :meth:`pop` or :meth:`clear` methods is called. .. versionchanged:: 3.9 @@ -291,25 +304,32 @@ process and user. .. function:: getenv(key, default=None) - Return the value of the environment variable *key* if it exists, or - *default* if it doesn't. *key*, *default* and the result are str. + Return the value of the environment variable *key* as a string if it exists, or + *default* if it doesn't. *key* is a string. Note that + since :func:`getenv` uses :data:`os.environ`, the mapping of :func:`getenv` is + similarly also captured on import, and the function may not reflect + future environment changes. On Unix, keys and values are decoded with :func:`sys.getfilesystemencoding` and ``'surrogateescape'`` error handler. Use :func:`os.getenvb` if you would like to use a different encoding. - .. availability:: most flavors of Unix, Windows. + .. availability:: Unix, Windows. .. function:: getenvb(key, default=None) - Return the value of the environment variable *key* if it exists, or - *default* if it doesn't. *key*, *default* and the result are bytes. + Return the value of the environment variable *key* as bytes if it exists, or + *default* if it doesn't. *key* must be bytes. Note that + since :func:`getenvb` uses :data:`os.environb`, the mapping of :func:`getenvb` is + similarly also captured on import, and the function may not reflect + future environment changes. + :func:`getenvb` is only available if :data:`supports_bytes_environ` is ``True``. - .. availability:: most flavors of Unix. + .. availability:: Unix. .. versionadded:: 3.2 @@ -330,7 +350,7 @@ process and user. Return the effective group id of the current process. This corresponds to the "set id" bit on the file being executed in the current process. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: geteuid() @@ -339,7 +359,7 @@ process and user. Return the current process's effective user id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: getgid() @@ -350,14 +370,18 @@ process and user. .. availability:: Unix. + The function is a stub on Emscripten and WASI, see + :ref:`wasm-availability` for more information. -.. function:: getgrouplist(user, group) + +.. function:: getgrouplist(user, group, /) Return list of group ids that *user* belongs to. If *group* is not in the list, it is included; typically, *group* is specified as the group ID - field from the password record for *user*. + field from the password record for *user*, because that group ID will + otherwise be potentially omitted. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -366,7 +390,7 @@ process and user. Return list of supplemental group ids associated with the current process. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. note:: @@ -394,7 +418,7 @@ process and user. falls back to ``pwd.getpwuid(os.getuid())[0]`` to get the login name of the current real user id. - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. function:: getpgid(pid) @@ -402,7 +426,7 @@ process and user. Return the process group id of the process with process id *pid*. If *pid* is 0, the process group id of the current process is returned. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: getpgrp() @@ -410,7 +434,7 @@ process and user. Return the id of the current process group. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: getpid() @@ -419,6 +443,8 @@ process and user. Return the current process id. + The function is a stub on Emscripten and WASI, see + :ref:`wasm-availability` for more information. .. function:: getppid() @@ -428,7 +454,7 @@ process and user. the id returned is the one of the init process (1), on Windows it is still the same id, which may be already reused by another process. - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. versionchanged:: 3.2 Added support for Windows. @@ -446,7 +472,7 @@ process and user. (respectively) the calling process, the process group of the calling process, or the real user ID of the calling process. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -457,7 +483,7 @@ process and user. Parameters for the :func:`getpriority` and :func:`setpriority` functions. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -467,7 +493,7 @@ process and user. Return a tuple (ruid, euid, suid) denoting the current process's real, effective, and saved user ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.2 @@ -477,7 +503,7 @@ process and user. Return a tuple (rgid, egid, sgid) denoting the current process's real, effective, and saved group ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.2 @@ -490,19 +516,22 @@ process and user. .. availability:: Unix. + The function is a stub on Emscripten and WASI, see + :ref:`wasm-availability` for more information. -.. function:: initgroups(username, gid) + +.. function:: initgroups(username, gid, /) Call the system initgroups() to initialize the group access list with all of the groups of which the specified username is a member, plus the specified group id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.2 -.. function:: putenv(key, value) +.. function:: putenv(key, value, /) .. index:: single: environment variables; setting @@ -510,10 +539,11 @@ process and user. changes to the environment affect subprocesses started with :func:`os.system`, :func:`popen` or :func:`fork` and :func:`execv`. - Assignments to items in ``os.environ`` are automatically translated into + Assignments to items in :data:`os.environ` are automatically translated into corresponding calls to :func:`putenv`; however, calls to :func:`putenv` - don't update ``os.environ``, so it is actually preferable to assign to items - of ``os.environ``. + don't update :data:`os.environ`, so it is actually preferable to assign to items + of :data:`os.environ`. This also applies to :func:`getenv` and :func:`getenvb`, which + respectively use :data:`os.environ` and :data:`os.environb` in their implementations. .. note:: @@ -526,55 +556,93 @@ process and user. The function is now always available. -.. function:: setegid(egid) +.. function:: setegid(egid, /) Set the current process's effective group id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. -.. function:: seteuid(euid) +.. function:: seteuid(euid, /) Set the current process's effective user id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. -.. function:: setgid(gid) +.. function:: setgid(gid, /) Set the current process' group id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. -.. function:: setgroups(groups) +.. function:: setgroups(groups, /) Set the list of supplemental group ids associated with the current process to *groups*. *groups* must be a sequence, and each element must be an integer identifying a group. This operation is typically available only to the superuser. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. note:: On macOS, the length of *groups* may not exceed the system-defined maximum number of effective group ids, typically 16. See the documentation for :func:`getgroups` for cases where it may not return the same group list set by calling setgroups(). +.. function:: setns(fd, nstype=0) + + Reassociate the current thread with a Linux namespace. + See the :manpage:`setns(2)` and :manpage:`namespaces(7)` man pages for more + details. + + If *fd* refers to a :file:`/proc/{pid}/ns/` link, ``setns()`` reassociates the + calling thread with the namespace associated with that link, + and *nstype* may be set to one of the + :ref:`CLONE_NEW* constants ` + to impose constraints on the operation + (``0`` means no constraints). + + Since Linux 5.8, *fd* may refer to a PID file descriptor obtained from + :func:`~os.pidfd_open`. In this case, ``setns()`` reassociates the calling thread + into one or more of the same namespaces as the thread referred to by *fd*. + This is subject to any constraints imposed by *nstype*, + which is a bit mask combining one or more of the + :ref:`CLONE_NEW* constants `, + e.g. ``setns(fd, os.CLONE_NEWUTS | os.CLONE_NEWPID)``. + The caller's memberships in unspecified namespaces are left unchanged. + + *fd* can be any object with a :meth:`~io.IOBase.fileno` method, or a raw file descriptor. + + This example reassociates the thread with the ``init`` process's network namespace:: + + fd = os.open("/proc/1/ns/net", os.O_RDONLY) + os.setns(fd, os.CLONE_NEWNET) + os.close(fd) + + .. availability:: Linux >= 3.0 with glibc >= 2.14. + + .. versionadded:: 3.12 + + .. seealso:: + + The :func:`~os.unshare` function. + .. function:: setpgrp() Call the system call :c:func:`setpgrp` or ``setpgrp(0, 0)`` depending on which version is implemented (if any). See the Unix manual for the semantics. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. -.. function:: setpgid(pid, pgrp) +.. function:: setpgid(pid, pgrp, /) Call the system call :c:func:`setpgid` to set the process group id of the process with id *pid* to the process group with id *pgrp*. See the Unix manual for the semantics. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: setpriority(which, who, priority) @@ -591,68 +659,68 @@ process and user. *priority* is a value in the range -20 to 19. The default priority is 0; lower priorities cause more favorable scheduling. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 -.. function:: setregid(rgid, egid) +.. function:: setregid(rgid, egid, /) Set the current process's real and effective group ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. -.. function:: setresgid(rgid, egid, sgid) +.. function:: setresgid(rgid, egid, sgid, /) Set the current process's real, effective, and saved group ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.2 -.. function:: setresuid(ruid, euid, suid) +.. function:: setresuid(ruid, euid, suid, /) Set the current process's real, effective, and saved user ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.2 -.. function:: setreuid(ruid, euid) +.. function:: setreuid(ruid, euid, /) Set the current process's real and effective user ids. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. -.. function:: getsid(pid) +.. function:: getsid(pid, /) Call the system call :c:func:`getsid`. See the Unix manual for the semantics. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: setsid() Call the system call :c:func:`setsid`. See the Unix manual for the semantics. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. -.. function:: setuid(uid) +.. function:: setuid(uid, /) .. index:: single: user; id, setting Set the current process's user id. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. placed in this section since it relates to errno.... a little weak -.. function:: strerror(code) +.. function:: strerror(code, /) Return the error message corresponding to the error code in *code*. On platforms where :c:func:`strerror` returns ``NULL`` when given an unknown @@ -667,10 +735,13 @@ process and user. .. versionadded:: 3.2 -.. function:: umask(mask) +.. function:: umask(mask, /) Set the current numeric umask and return the previous umask. + The function is a stub on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. function:: uname() @@ -697,14 +768,14 @@ process and user. :func:`socket.gethostname` or even ``socket.gethostbyaddr(socket.gethostname())``. - .. availability:: recent flavors of Unix. + .. availability:: Unix. .. versionchanged:: 3.3 Return type changed from a tuple to a tuple-like object with named attributes. -.. function:: unsetenv(key) +.. function:: unsetenv(key, /) .. index:: single: environment variables; deleting @@ -712,10 +783,10 @@ process and user. environment affect subprocesses started with :func:`os.system`, :func:`popen` or :func:`fork` and :func:`execv`. - Deletion of items in ``os.environ`` is automatically translated into a + Deletion of items in :data:`os.environ` is automatically translated into a corresponding call to :func:`unsetenv`; however, calls to :func:`unsetenv` - don't update ``os.environ``, so it is actually preferable to delete items of - ``os.environ``. + don't update :data:`os.environ`, so it is actually preferable to delete items of + :data:`os.environ`. .. audit-event:: os.unsetenv key os.unsetenv @@ -723,6 +794,49 @@ process and user. The function is now always available and is also available on Windows. +.. function:: unshare(flags) + + Disassociate parts of the process execution context, and move them into a + newly created namespace. + See the :manpage:`unshare(2)` + man page for more details. + The *flags* argument is a bit mask, combining zero or more of the + :ref:`CLONE_* constants `, + that specifies which parts of the execution context should be + unshared from their existing associations and moved to a new namespace. + If the *flags* argument is ``0``, no changes are made to the calling process's + execution context. + + .. availability:: Linux >= 2.6.16. + + .. versionadded:: 3.12 + + .. seealso:: + + The :func:`~os.setns` function. + +.. _os-unshare-clone-flags: + +Flags to the :func:`unshare` function, if the implementation supports them. +See :manpage:`unshare(2)` in the Linux manual +for their exact effect and availability. + +.. data:: CLONE_FILES + CLONE_FS + CLONE_NEWCGROUP + CLONE_NEWIPC + CLONE_NEWNET + CLONE_NEWNS + CLONE_NEWPID + CLONE_NEWTIME + CLONE_NEWUSER + CLONE_NEWUTS + CLONE_SIGHAND + CLONE_SYSVSEM + CLONE_THREAD + CLONE_VM + + .. _os-newstreams: File Object Creation @@ -772,7 +886,7 @@ as internal buffering of data. :func:`fdopen`, use its :meth:`~io.IOBase.close` method. -.. function:: closerange(fd_low, fd_high) +.. function:: closerange(fd_low, fd_high, /) Close all file descriptors from *fd_low* (inclusive) to *fd_high* (exclusive), ignoring errors. Equivalent to (but much faster than):: @@ -789,19 +903,33 @@ as internal buffering of data. Copy *count* bytes from file descriptor *src*, starting from offset *offset_src*, to file descriptor *dst*, starting from offset *offset_dst*. If *offset_src* is None, then *src* is read from the current position; - respectively for *offset_dst*. The files pointed by *src* and *dst* + respectively for *offset_dst*. + + In Linux kernel older than 5.3, the files pointed by *src* and *dst* must reside in the same filesystem, otherwise an :exc:`OSError` is raised with :attr:`~OSError.errno` set to :data:`errno.EXDEV`. This copy is done without the additional cost of transferring data from the kernel to user space and then back into the kernel. Additionally, - some filesystems could implement extra optimizations. The copy is done as if - both files are opened as binary. + some filesystems could implement extra optimizations, such as the use of + reflinks (i.e., two or more inodes that share pointers to the same + copy-on-write disk blocks; supported file systems include btrfs and XFS) + and server-side copy (in the case of NFS). + + The function copies bytes between two file descriptors. Text options, like + the encoding and the line ending, are ignored. The return value is the amount of bytes copied. This could be less than the amount requested. - .. availability:: Linux kernel >= 4.5 or glibc >= 2.27. + .. note:: + + On Linux, :func:`os.copy_file_range` should not be used for copying a + range of a pseudo file from a special filesystem like procfs and sysfs. + It will always copy no bytes and return 0 as if the file was empty + because of a known Linux kernel issue. + + .. availability:: Linux >= 4.5 with glibc >= 2.27. .. versionadded:: 3.8 @@ -818,7 +946,7 @@ as internal buffering of data. On Unix, the function now implements the Python UTF-8 Mode. -.. function:: dup(fd) +.. function:: dup(fd, /) Return a duplicate of file descriptor *fd*. The new file descriptor is :ref:`non-inheritable `. @@ -827,6 +955,8 @@ as internal buffering of data. 2: stderr), the new file descriptor is :ref:`inheritable `. + .. availability:: not WASI. + .. versionchanged:: 3.4 The new file descriptor is now non-inheritable. @@ -838,6 +968,8 @@ as internal buffering of data. ` by default or non-inheritable if *inheritable* is ``False``. + .. availability:: not WASI. + .. versionchanged:: 3.4 Add the optional *inheritable* parameter. @@ -855,6 +987,9 @@ as internal buffering of data. .. availability:: Unix. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. function:: fchown(fd, uid, gid) @@ -867,6 +1002,9 @@ as internal buffering of data. .. availability:: Unix. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. function:: fdatasync(fd) @@ -879,7 +1017,7 @@ as internal buffering of data. This function is not available on MacOS. -.. function:: fpathconf(fd, name) +.. function:: fpathconf(fd, name, /) Return system configuration information relevant to an open file. *name* specifies the configuration value to retrieve; it may be a string which is the @@ -911,7 +1049,7 @@ as internal buffering of data. The :func:`.stat` function. -.. function:: fstatvfs(fd) +.. function:: fstatvfs(fd, /) Return information about the filesystem containing the file associated with file descriptor *fd*, like :func:`statvfs`. As of Python 3.3, this is @@ -932,7 +1070,7 @@ as internal buffering of data. .. availability:: Unix, Windows. -.. function:: ftruncate(fd, length) +.. function:: ftruncate(fd, length, /) Truncate the file corresponding to file descriptor *fd*, so that it is at most *length* bytes in size. As of Python 3.3, this is equivalent to @@ -946,7 +1084,7 @@ as internal buffering of data. Added support for Windows -.. function:: get_blocking(fd) +.. function:: get_blocking(fd, /) Get the blocking mode of the file descriptor: ``False`` if the :data:`O_NONBLOCK` flag is set, ``True`` if the flag is cleared. @@ -955,16 +1093,19 @@ as internal buffering of data. .. availability:: Unix. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. versionadded:: 3.5 -.. function:: isatty(fd) +.. function:: isatty(fd, /) Return ``True`` if the file descriptor *fd* is open and connected to a tty(-like) device, else ``False``. -.. function:: lockf(fd, cmd, len) +.. function:: lockf(fd, cmd, len, /) Apply, test or remove a POSIX lock on an open file descriptor. *fd* is an open file descriptor. @@ -991,7 +1132,18 @@ as internal buffering of data. .. versionadded:: 3.3 -.. function:: lseek(fd, pos, how) +.. function:: login_tty(fd, /) + + Prepare the tty of which fd is a file descriptor for a new login session. + Make the calling process a session leader; make the tty the controlling tty, + the stdin, the stdout, and the stderr of the calling process; close fd. + + .. availability:: Unix, not Emscripten, not WASI. + + .. versionadded:: 3.11 + + +.. function:: lseek(fd, pos, how, /) Set the current position of file descriptor *fd* to position *pos*, modified by *how*: :const:`SEEK_SET` or ``0`` to set the position relative to the @@ -1130,7 +1282,7 @@ or `the MSDN `_ on Windo descriptors are :ref:`non-inheritable `. For a (slightly) more portable approach, use the :mod:`pty` module. - .. availability:: some flavors of Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionchanged:: 3.4 The new file descriptors are now non-inheritable. @@ -1148,7 +1300,7 @@ or `the MSDN `_ on Windo The new file descriptors are now non-inheritable. -.. function:: pipe2(flags) +.. function:: pipe2(flags, /) Create a pipe with *flags* set atomically. *flags* can be constructed by ORing together one or more of these values: @@ -1156,22 +1308,22 @@ or `the MSDN `_ on Windo Return a pair of file descriptors ``(r, w)`` usable for reading and writing, respectively. - .. availability:: some flavors of Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 -.. function:: posix_fallocate(fd, offset, len) +.. function:: posix_fallocate(fd, offset, len, /) Ensures that enough disk space is allocated for the file specified by *fd* starting from *offset* and continuing for *len* bytes. - .. availability:: Unix. + .. availability:: Unix, not Emscripten. .. versionadded:: 3.3 -.. function:: posix_fadvise(fd, offset, len, advice) +.. function:: posix_fadvise(fd, offset, len, advice, /) Announces an intention to access data in a specific pattern thus allowing the kernel to make optimizations. @@ -1201,7 +1353,7 @@ or `the MSDN `_ on Windo .. versionadded:: 3.3 -.. function:: pread(fd, n, offset) +.. function:: pread(fd, n, offset, /) Read at most *n* bytes from file descriptor *fd* at a position of *offset*, leaving the file offset unchanged. @@ -1214,7 +1366,7 @@ or `the MSDN `_ on Windo .. versionadded:: 3.3 -.. function:: preadv(fd, buffers, offset, flags=0) +.. function:: preadv(fd, buffers, offset, flags=0, /) Read from a file descriptor *fd* at a position of *offset* into mutable :term:`bytes-like objects ` *buffers*, leaving the file @@ -1235,9 +1387,9 @@ or `the MSDN `_ on Windo Combine the functionality of :func:`os.readv` and :func:`os.pread`. - .. availability:: Linux 2.6.30 and newer, FreeBSD 6.0 and newer, - OpenBSD 2.7 and newer, AIX 7.1 and newer. Using flags requires - Linux 4.6 or newer. + .. availability:: Linux >= 2.6.30, FreeBSD >= 6.0, OpenBSD >= 2.7, AIX >= 7.1. + + Using flags requires Linux >= 4.6. .. versionadded:: 3.7 @@ -1252,7 +1404,7 @@ or `the MSDN `_ on Windo If no bytes were read, it will return ``-1`` and set errno to :data:`errno.EAGAIN`. - .. availability:: Linux 4.14 and newer. + .. availability:: Linux >= 4.14. .. versionadded:: 3.7 @@ -1266,12 +1418,12 @@ or `the MSDN `_ on Windo Currently, on Linux, this feature is usable only on a file descriptor opened using the :data:`O_DIRECT` flag. - .. availability:: Linux 4.6 and newer. + .. availability:: Linux >= 4.6. .. versionadded:: 3.7 -.. function:: pwrite(fd, str, offset) +.. function:: pwrite(fd, str, offset, /) Write the bytestring in *str* to file descriptor *fd* at position of *offset*, leaving the file offset unchanged. @@ -1283,7 +1435,7 @@ or `the MSDN `_ on Windo .. versionadded:: 3.3 -.. function:: pwritev(fd, buffers, offset, flags=0) +.. function:: pwritev(fd, buffers, offset, flags=0, /) Write the *buffers* contents to file descriptor *fd* at a offset *offset*, leaving the file offset unchanged. *buffers* must be a sequence of @@ -1305,9 +1457,9 @@ or `the MSDN `_ on Windo Combine the functionality of :func:`os.writev` and :func:`os.pwrite`. - .. availability:: Linux 2.6.30 and newer, FreeBSD 6.0 and newer, - OpenBSD 2.7 and newer, AIX 7.1 and newer. Using flags requires - Linux 4.7 or newer. + .. availability:: Linux >= 2.6.30, FreeBSD >= 6.0, OpenBSD >= 2.7, AIX >= 7.1. + + Using flags requires Linux >= 4.6. .. versionadded:: 3.7 @@ -1317,7 +1469,7 @@ or `the MSDN `_ on Windo Provide a per-write equivalent of the :data:`O_DSYNC` :func:`os.open` flag. This flag effect applies only to the data range written by the system call. - .. availability:: Linux 4.7 and newer. + .. availability:: Linux >= 4.7. .. versionadded:: 3.7 @@ -1327,7 +1479,7 @@ or `the MSDN `_ on Windo Provide a per-write equivalent of the :data:`O_SYNC` :func:`os.open` flag. This flag effect applies only to the data range written by the system call. - .. availability:: Linux 4.7 and newer. + .. availability:: Linux >= 4.7. .. versionadded:: 3.7 @@ -1341,12 +1493,12 @@ or `the MSDN `_ on Windo appended to the end of the file. However, if the *offset* argument is ``-1``, the current file *offset* is updated. - .. availability:: Linux 4.16 and newer. + .. availability:: Linux >= 4.16. .. versionadded:: 3.10 -.. function:: read(fd, n) +.. function:: read(fd, n, /) Read at most *n* bytes from file descriptor *fd*. @@ -1393,7 +1545,7 @@ or `the MSDN `_ on Windo Cross-platform applications should not use *headers*, *trailers* and *flags* arguments. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. note:: @@ -1406,7 +1558,7 @@ or `the MSDN `_ on Windo Parameters *out* and *in* was renamed to *out_fd* and *in_fd*. -.. function:: set_blocking(fd, blocking) +.. function:: set_blocking(fd, blocking, /) Set the blocking mode of the specified file descriptor. Set the :data:`O_NONBLOCK` flag if blocking is ``False``, clear the flag otherwise. @@ -1415,6 +1567,9 @@ or `the MSDN `_ on Windo .. availability:: Unix. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. versionadded:: 3.5 @@ -1425,10 +1580,19 @@ or `the MSDN `_ on Windo Parameters to the :func:`sendfile` function, if the implementation supports them. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 +.. data:: SF_NOCACHE + + Parameter to the :func:`sendfile` function, if the implementation supports + it. The data won't be cached in the virtual memory and will be freed afterwards. + + .. availability:: Unix, not Emscripten, not WASI. + + .. versionadded:: 3.11 + .. function:: splice(src, dst, count, offset_src=None, offset_dst=None) @@ -1452,7 +1616,7 @@ or `the MSDN `_ on Windo make sense to block because there are no writers connected to the write end of the pipe. - .. availability:: Linux kernel >= 2.6.17 and glibc >= 2.5 + .. availability:: Linux >= 2.6.17 with glibc >= 2.5 .. versionadded:: 3.10 @@ -1463,7 +1627,7 @@ or `the MSDN `_ on Windo .. versionadded:: 3.10 -.. function:: readv(fd, buffers) +.. function:: readv(fd, buffers, /) Read from a file descriptor *fd* into a number of mutable :term:`bytes-like objects ` *buffers*. Transfer data into each buffer until @@ -1481,23 +1645,23 @@ or `the MSDN `_ on Windo .. versionadded:: 3.3 -.. function:: tcgetpgrp(fd) +.. function:: tcgetpgrp(fd, /) Return the process group associated with the terminal given by *fd* (an open file descriptor as returned by :func:`os.open`). - .. availability:: Unix. + .. availability:: Unix, not WASI. -.. function:: tcsetpgrp(fd, pg) +.. function:: tcsetpgrp(fd, pg, /) Set the process group associated with the terminal given by *fd* (an open file descriptor as returned by :func:`os.open`) to *pg*. - .. availability:: Unix. + .. availability:: Unix, not WASI. -.. function:: ttyname(fd) +.. function:: ttyname(fd, /) Return a string which specifies the terminal device associated with file descriptor *fd*. If *fd* is not associated with a terminal device, an @@ -1506,7 +1670,7 @@ or `the MSDN `_ on Windo .. availability:: Unix. -.. function:: write(fd, str) +.. function:: write(fd, str, /) Write the bytestring in *str* to file descriptor *fd*. @@ -1526,7 +1690,7 @@ or `the MSDN `_ on Windo :exc:`InterruptedError` exception (see :pep:`475` for the rationale). -.. function:: writev(fd, buffers) +.. function:: writev(fd, buffers, /) Write the contents of *buffers* to file descriptor *fd*. *buffers* must be a sequence of :term:`bytes-like objects `. Buffers are @@ -1550,7 +1714,7 @@ Querying the size of a terminal .. versionadded:: 3.3 -.. function:: get_terminal_size(fd=STDOUT_FILENO) +.. function:: get_terminal_size(fd=STDOUT_FILENO, /) Return the size of the terminal window as ``(columns, lines)``, tuple of type :class:`terminal_size`. @@ -1602,21 +1766,24 @@ Using the :mod:`subprocess` module, all file descriptors except standard streams are closed, and inheritable handles are only inherited if the *close_fds* parameter is ``False``. -.. function:: get_inheritable(fd) +On WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``, the file +descriptor cannot be modified. + +.. function:: get_inheritable(fd, /) Get the "inheritable" flag of the specified file descriptor (a boolean). -.. function:: set_inheritable(fd, inheritable) +.. function:: set_inheritable(fd, inheritable, /) Set the "inheritable" flag of the specified file descriptor. -.. function:: get_handle_inheritable(handle) +.. function:: get_handle_inheritable(handle, /) Get the "inheritable" flag of the specified handle (a boolean). .. availability:: Windows. -.. function:: set_handle_inheritable(handle, inheritable) +.. function:: set_handle_inheritable(handle, inheritable, /) Set the "inheritable" flag of the specified handle. @@ -1786,7 +1953,7 @@ features: .. audit-event:: os.chflags path,flags os.chflags - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 The *follow_symlinks* argument. @@ -1831,6 +1998,9 @@ features: read-only flag with it (via the ``stat.S_IWRITE`` and ``stat.S_IREAD`` constants or a corresponding integer value). All other bits are ignored. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. audit-event:: os.chmod path,mode,dir_fd os.chmod .. versionadded:: 3.3 @@ -1857,6 +2027,9 @@ features: .. availability:: Unix. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. versionadded:: 3.3 Added support for specifying *path* as an open file descriptor, and the *dir_fd* and *follow_symlinks* arguments. @@ -1869,7 +2042,7 @@ features: Change the root directory of the current process to *path*. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionchanged:: 3.6 Accepts a :term:`path-like object`. @@ -1909,7 +2082,7 @@ features: .. audit-event:: os.chflags path,flags os.lchflags - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionchanged:: 3.6 Accepts a :term:`path-like object`. @@ -2041,7 +2214,8 @@ features: Create a directory named *path* with numeric mode *mode*. - If the directory already exists, :exc:`FileExistsError` is raised. + If the directory already exists, :exc:`FileExistsError` is raised. If a parent + directory in the path does not exist, :exc:`FileNotFoundError` is raised. .. _mkdir_modebits: @@ -2077,11 +2251,11 @@ features: The *mode* parameter is passed to :func:`mkdir` for creating the leaf directory; see :ref:`the mkdir() description ` for how it - is interpreted. To set the file permission bits of any newly-created parent + is interpreted. To set the file permission bits of any newly created parent directories you can set the umask before invoking :func:`makedirs`. The file permission bits of existing parent directories are not changed. - If *exist_ok* is ``False`` (the default), an :exc:`FileExistsError` is + If *exist_ok* is ``False`` (the default), a :exc:`FileExistsError` is raised if the target directory already exists. .. note:: @@ -2108,7 +2282,7 @@ features: .. versionchanged:: 3.7 The *mode* argument no longer affects the file permission bits of - newly-created intermediate-level directories. + newly created intermediate-level directories. .. function:: mkfifo(path, mode=0o666, *, dir_fd=None) @@ -2125,7 +2299,7 @@ features: FIFO for reading, and the client opens it for writing. Note that :func:`mkfifo` doesn't open the FIFO --- it just creates the rendezvous point. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 The *dir_fd* argument. @@ -2147,7 +2321,7 @@ features: This function can also support :ref:`paths relative to directory descriptors `. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 The *dir_fd* argument. @@ -2156,19 +2330,19 @@ features: Accepts a :term:`path-like object`. -.. function:: major(device) +.. function:: major(device, /) Extract the device major number from a raw device number (usually the :attr:`st_dev` or :attr:`st_rdev` field from :c:type:`stat`). -.. function:: minor(device) +.. function:: minor(device, /) Extract the device minor number from a raw device number (usually the :attr:`st_dev` or :attr:`st_rdev` field from :c:type:`stat`). -.. function:: makedev(major, minor) +.. function:: makedev(major, minor, /) Compose a raw device number from the major and minor device numbers. @@ -2247,7 +2421,7 @@ features: .. function:: remove(path, *, dir_fd=None) Remove (delete) the file *path*. If *path* is a directory, an - :exc:`IsADirectoryError` is raised. Use :func:`rmdir` to remove directories. + :exc:`OSError` is raised. Use :func:`rmdir` to remove directories. If the file does not exist, a :exc:`FileNotFoundError` is raised. This function can support :ref:`paths relative to directory descriptors @@ -2293,12 +2467,14 @@ features: will fail with an :exc:`OSError` subclass in a number of cases: On Windows, if *dst* exists a :exc:`FileExistsError` is always raised. + The operation may fail if *src* and *dst* are on different filesystems. Use + :func:`shutil.move` to support moves to a different filesystem. On Unix, if *src* is a file and *dst* is a directory or vice-versa, an :exc:`IsADirectoryError` or a :exc:`NotADirectoryError` will be raised respectively. If both are directories and *dst* is empty, *dst* will be silently replaced. If *dst* is a non-empty directory, an :exc:`OSError` - is raised. If both are files, *dst* it will be replaced silently if the user + is raised. If both are files, *dst* will be replaced silently if the user has permission. The operation may fail on some Unix flavors if *src* and *dst* are on different filesystems. If successful, the renaming will be an atomic operation (this is a POSIX requirement). @@ -2337,7 +2513,7 @@ features: .. function:: replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None) - Rename the file or directory *src* to *dst*. If *dst* is a directory, + Rename the file or directory *src* to *dst*. If *dst* is a non-empty directory, :exc:`OSError` will be raised. If *dst* exists and is a file, it will be replaced silently if the user has permission. The operation may fail if *src* and *dst* are on different filesystems. If successful, @@ -2357,7 +2533,7 @@ features: .. function:: rmdir(path, *, dir_fd=None) Remove (delete) the directory *path*. If the directory does not exist or is - not empty, an :exc:`FileNotFoundError` or an :exc:`OSError` is raised + not empty, a :exc:`FileNotFoundError` or an :exc:`OSError` is raised respectively. In order to remove whole directory trees, :func:`shutil.rmtree` can be used. @@ -2430,9 +2606,9 @@ features: .. note:: On Unix-based systems, :func:`scandir` uses the system's - `opendir() `_ + `opendir() `_ and - `readdir() `_ + `readdir() `_ functions. On Windows, it uses the Win32 `FindFirstFileW `_ and @@ -2564,6 +2740,17 @@ features: This method can raise :exc:`OSError`, such as :exc:`PermissionError`, but :exc:`FileNotFoundError` is caught and not raised. + .. method:: is_junction() + + Return ``True`` if this entry is a junction (even if broken); + return ``False`` if the entry points to a regular directory, any kind + of file, a symlink, or if it doesn't exist anymore. + + The result is cached on the ``os.DirEntry`` object. Call + :func:`os.path.isjunction` to fetch up-to-date information. + + .. versionadded:: 3.12 + .. method:: stat(*, follow_symlinks=True) Return a :class:`stat_result` object for this entry. This method @@ -2586,8 +2773,8 @@ features: Note that there is a nice correspondence between several attributes and methods of ``os.DirEntry`` and of :class:`pathlib.Path`. In particular, the ``name`` attribute has the same - meaning, as do the ``is_dir()``, ``is_file()``, ``is_symlink()`` - and ``stat()`` methods. + meaning, as do the ``is_dir()``, ``is_file()``, ``is_symlink()``, + ``is_junction()``, and ``stat()`` methods. .. versionadded:: 3.5 @@ -3015,6 +3202,9 @@ features: .. availability:: Unix, Windows. + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + .. versionchanged:: 3.2 Added support for Windows 6.0 (Vista) symbolic links. @@ -3098,7 +3288,7 @@ features: system records access and modification times; see :func:`~os.stat`. The best way to preserve exact times is to use the *st_atime_ns* and *st_mtime_ns* fields from the :func:`os.stat` result object with the *ns* parameter to - `utime`. + :func:`utime`. This function can support :ref:`specifying a file descriptor `, :ref:`paths relative to directory descriptors ` and :ref:`not @@ -3126,7 +3316,8 @@ features: filenames)``. *dirpath* is a string, the path to the directory. *dirnames* is a list of the - names of the subdirectories in *dirpath* (excluding ``'.'`` and ``'..'``). + names of the subdirectories in *dirpath* (including symlinks to directories, + and excluding ``'.'`` and ``'..'``). *filenames* is a list of the names of the non-directory files in *dirpath*. Note that the names in the lists contain no path components. To get a full path (which begins with *top*) to a file or directory in *dirpath*, do @@ -3290,7 +3481,7 @@ features: the file descriptor, and as such multiple files can have the same name without any side effects. - .. availability:: Linux 3.17 or newer with glibc 2.27 or newer. + .. availability:: Linux >= 3.17 with glibc >= 2.27. .. versionadded:: 3.8 @@ -3315,8 +3506,9 @@ features: These flags can be passed to :func:`memfd_create`. - .. availability:: Linux 3.17 or newer with glibc 2.27 or newer. The - ``MFD_HUGE*`` flags are only available since Linux 4.14. + .. availability:: Linux >= 3.17 with glibc >= 2.27 + + The ``MFD_HUGE*`` flags are only available since Linux 4.14. .. versionadded:: 3.8 @@ -3368,7 +3560,7 @@ features: finally: os.close(fd) - .. availability:: Linux 2.6.27 or newer with glibc 2.8 or newer. + .. availability:: Linux >= 2.6.27 with glibc >= 2.8 .. versionadded:: 3.10 @@ -3377,7 +3569,7 @@ features: Read value from an :func:`eventfd` file descriptor and return a 64 bit unsigned int. The function does not verify that *fd* is an :func:`eventfd`. - .. availability:: See :func:`eventfd` + .. availability:: Linux >= 2.6.27 .. versionadded:: 3.10 @@ -3386,7 +3578,7 @@ features: Add value to an :func:`eventfd` file descriptor. *value* must be a 64 bit unsigned int. The function does not verify that *fd* is an :func:`eventfd`. - .. availability:: See :func:`eventfd` + .. availability:: Linux >= 2.6.27 .. versionadded:: 3.10 @@ -3394,7 +3586,7 @@ features: Set close-on-exec flag for new :func:`eventfd` file descriptor. - .. availability:: See :func:`eventfd` + .. availability:: Linux >= 2.6.27 .. versionadded:: 3.10 @@ -3403,7 +3595,7 @@ features: Set :const:`O_NONBLOCK` status flag for new :func:`eventfd` file descriptor. - .. availability:: See :func:`eventfd` + .. availability:: Linux >= 2.6.27 .. versionadded:: 3.10 @@ -3412,7 +3604,7 @@ features: Provide semaphore-like semantics for reads from a :func:`eventfd` file descriptor. On read the internal counter is decremented by one. - .. availability:: Linux 2.6.30 or newer with glibc 2.8 or newer. + .. availability:: Linux >= 2.6.30 .. versionadded:: 3.10 @@ -3545,8 +3737,8 @@ to be ignored. Add a path to the DLL search path. This search path is used when resolving dependencies for imported - extension modules (the module itself is resolved through sys.path), - and also by :mod:`ctypes`. + extension modules (the module itself is resolved through + :data:`sys.path`), and also by :mod:`ctypes`. Remove the directory by calling **close()** on the returned object or using it in a :keyword:`with` statement. @@ -3625,7 +3817,7 @@ to be ignored. .. audit-event:: os.exec path,args,env os.execl - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. versionadded:: 3.3 Added support for specifying *path* as an open file descriptor @@ -3668,49 +3860,49 @@ written in Python, such as a mail server's external command delivery program. Exit code that means the command was used incorrectly, such as when the wrong number of arguments are given. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_DATAERR Exit code that means the input data was incorrect. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_NOINPUT Exit code that means an input file did not exist or was not readable. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_NOUSER Exit code that means a specified user did not exist. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_NOHOST Exit code that means a specified host did not exist. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_UNAVAILABLE Exit code that means that a required service is unavailable. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_SOFTWARE Exit code that means an internal software error was detected. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_OSERR @@ -3718,7 +3910,7 @@ written in Python, such as a mail server's external command delivery program. Exit code that means an operating system error was detected, such as the inability to fork or create a pipe. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_OSFILE @@ -3726,21 +3918,21 @@ written in Python, such as a mail server's external command delivery program. Exit code that means some system file did not exist, could not be opened, or had some other kind of error. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_CANTCREAT Exit code that means a user specified output file could not be created. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_IOERR Exit code that means that an error occurred while doing I/O on some file. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_TEMPFAIL @@ -3749,7 +3941,7 @@ written in Python, such as a mail server's external command delivery program. that may not really be an error, such as a network connection that couldn't be made during a retryable operation. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_PROTOCOL @@ -3757,7 +3949,7 @@ written in Python, such as a mail server's external command delivery program. Exit code that means that a protocol exchange was illegal, invalid, or not understood. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_NOPERM @@ -3765,21 +3957,21 @@ written in Python, such as a mail server's external command delivery program. Exit code that means that there were insufficient permissions to perform the operation (but not intended for file system problems). - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_CONFIG Exit code that means that some kind of configuration error occurred. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. data:: EX_NOTFOUND Exit code that means something like "an entry was not found". - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: fork() @@ -3800,7 +3992,7 @@ written in Python, such as a mail server's external command delivery program. See :mod:`ssl` for applications that use the SSL module with fork(). - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: forkpty() @@ -3817,10 +4009,10 @@ written in Python, such as a mail server's external command delivery program. Calling ``forkpty()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). - .. availability:: some flavors of Unix. + .. availability:: Unix, not Emscripten, not WASI. -.. function:: kill(pid, sig) +.. function:: kill(pid, sig, /) .. index:: single: process; killing @@ -3841,11 +4033,13 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.kill pid,sig os.kill + .. availability:: Unix, Windows, not Emscripten, not WASI. + .. versionadded:: 3.2 Windows support. -.. function:: killpg(pgid, sig) +.. function:: killpg(pgid, sig, /) .. index:: single: process; killing @@ -3855,35 +4049,44 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.killpg pgid,sig os.killpg - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. -.. function:: nice(increment) +.. function:: nice(increment, /) Add *increment* to the process's "niceness". Return the new niceness. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: pidfd_open(pid, flags=0) - Return a file descriptor referring to the process *pid*. This descriptor can - be used to perform process management without races and signals. The *flags* - argument is provided for future extensions; no flag values are currently - defined. + Return a file descriptor referring to the process *pid* with *flags* set. + This descriptor can be used to perform process management without races + and signals. See the :manpage:`pidfd_open(2)` man page for more details. - .. availability:: Linux 5.3+ + .. availability:: Linux >= 5.3 .. versionadded:: 3.9 + .. data:: PIDFD_NONBLOCK -.. function:: plock(op) + This flag indicates that the file descriptor will be non-blocking. + If the process referred to by the file descriptor has not yet terminated, + then an attempt to wait on the file descriptor using :manpage:`waitid(2)` + will immediately return the error :data:`~errno.EAGAIN` rather than blocking. + + .. availability:: Linux >= 5.10 + .. versionadded:: 3.12 + + +.. function:: plock(op, /) Lock program segments into memory. The value of *op* (defined in ````) determines which segments are locked. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: popen(cmd, mode='r', buffering=-1) @@ -3891,7 +4094,8 @@ written in Python, such as a mail server's external command delivery program. Open a pipe to or from command *cmd*. The return value is an open file object connected to the pipe, which can be read or written depending on whether *mode* - is ``'r'`` (default) or ``'w'``. The *buffering* argument has the same meaning as + is ``'r'`` (default) or ``'w'``. + The *buffering* argument have the same meaning as the corresponding argument to the built-in :func:`open` function. The returned file object reads or writes text strings rather than bytes. @@ -3914,6 +4118,16 @@ written in Python, such as a mail server's external command delivery program. documentation for more powerful ways to manage and communicate with subprocesses. + .. availability:: not Emscripten, not WASI. + + .. note:: + The :ref:`Python UTF-8 Mode ` affects encodings used + for *cmd* and pipe contents. + + :func:`popen` is a simple wrapper around :class:`subprocess.Popen`. + Use :class:`subprocess.Popen` or :func:`subprocess.run` to + control options like encodings. + .. function:: posix_spawn(path, argv, env, *, file_actions=None, \ setpgroup=None, resetids=False, setsid=False, setsigmask=(), \ @@ -3975,7 +4189,7 @@ written in Python, such as a mail server's external command delivery program. library :c:data:`POSIX_SPAWN_RESETIDS` flag. If the *setsid* argument is ``True``, it will create a new session ID - for `posix_spawn`. *setsid* requires :c:data:`POSIX_SPAWN_SETSID` + for ``posix_spawn``. *setsid* requires :c:data:`POSIX_SPAWN_SETSID` or :c:data:`POSIX_SPAWN_SETSID_NP` flag. Otherwise, :exc:`NotImplementedError` is raised. @@ -3999,7 +4213,7 @@ written in Python, such as a mail server's external command delivery program. .. versionadded:: 3.8 - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: posix_spawnp(path, argv, env, *, file_actions=None, \ setpgroup=None, resetids=False, setsid=False, setsigmask=(), \ @@ -4015,7 +4229,9 @@ written in Python, such as a mail server's external command delivery program. .. versionadded:: 3.8 - .. availability:: See :func:`posix_spawn` documentation. + .. availability:: POSIX, not Emscripten, not WASI. + + See :func:`posix_spawn` documentation. .. function:: register_at_fork(*, before=None, after_in_parent=None, \ @@ -4046,7 +4262,7 @@ written in Python, such as a mail server's external command delivery program. There is no way to unregister a function. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.7 @@ -4115,7 +4331,9 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.spawn mode,path,args,env os.spawnl - .. availability:: Unix, Windows. :func:`spawnlp`, :func:`spawnlpe`, :func:`spawnvp` + .. availability:: Unix, Windows, not Emscripten, not WASI. + + :func:`spawnlp`, :func:`spawnlpe`, :func:`spawnvp` and :func:`spawnvpe` are not available on Windows. :func:`spawnle` and :func:`spawnve` are not thread-safe on Windows; we advise you to use the :mod:`subprocess` module instead. @@ -4162,13 +4380,13 @@ written in Python, such as a mail server's external command delivery program. Start a file with its associated application. - When *operation* is not specified or ``'open'``, this acts like double-clicking + When *operation* is not specified, this acts like double-clicking the file in Windows Explorer, or giving the file name as an argument to the :program:`start` command from the interactive command shell: the file is opened with whatever application (if any) its extension is associated. When another *operation* is given, it must be a "command verb" that specifies - what should be done with the file. Common verbs documented by Microsoft are + what should be done with the file. Common verbs documented by Microsoft are ``'open'``, ``'print'`` and ``'edit'`` (to be used on files) as well as ``'explore'`` and ``'find'`` (to be used on directories). @@ -4237,7 +4455,7 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.system command os.system - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. function:: times() @@ -4245,20 +4463,20 @@ written in Python, such as a mail server's external command delivery program. Returns the current global process times. The return value is an object with five attributes: - * :attr:`user` - user time - * :attr:`system` - system time - * :attr:`children_user` - user time of all child processes - * :attr:`children_system` - system time of all child processes - * :attr:`elapsed` - elapsed real time since a fixed point in the past + * :attr:`!user` - user time + * :attr:`!system` - system time + * :attr:`!children_user` - user time of all child processes + * :attr:`!children_system` - system time of all child processes + * :attr:`!elapsed` - elapsed real time since a fixed point in the past For backwards compatibility, this object also behaves like a five-tuple - containing :attr:`user`, :attr:`system`, :attr:`children_user`, - :attr:`children_system`, and :attr:`elapsed` in that order. + containing :attr:`!user`, :attr:`!system`, :attr:`!children_user`, + :attr:`!children_system`, and :attr:`!elapsed` in that order. See the Unix manual page - :manpage:`times(2)` and :manpage:`times(3)` manual page on Unix or `the GetProcessTimes MSDN + :manpage:`times(2)` and `times(3) `_ manual page on Unix or `the GetProcessTimes MSDN `_ - on Windows. On Windows, only :attr:`user` and :attr:`system` are known; the other attributes are zero. + on Windows. On Windows, only :attr:`!user` and :attr:`!system` are known; the other attributes are zero. .. availability:: Unix, Windows. @@ -4275,85 +4493,52 @@ written in Python, such as a mail server's external command delivery program. number is zero); the high bit of the low byte is set if a core file was produced. + If there are no children that could be waited for, :exc:`ChildProcessError` + is raised. + :func:`waitstatus_to_exitcode` can be used to convert the exit status into an exit code. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. seealso:: - :func:`waitpid` can be used to wait for the completion of a specific - child process and has more options. + The other :func:`!wait*` functions documented below can be used to wait for the + completion of a specific child process and have more options. + :func:`waitpid` is the only one also available on Windows. -.. function:: waitid(idtype, id, options) - Wait for the completion of one or more child processes. - *idtype* can be :data:`P_PID`, :data:`P_PGID`, :data:`P_ALL`, or - :data:`P_PIDFD` on Linux. - *id* specifies the pid to wait on. - *options* is constructed from the ORing of one or more of :data:`WEXITED`, - :data:`WSTOPPED` or :data:`WCONTINUED` and additionally may be ORed with - :data:`WNOHANG` or :data:`WNOWAIT`. The return value is an object - representing the data contained in the :c:type:`siginfo_t` structure, namely: - :attr:`si_pid`, :attr:`si_uid`, :attr:`si_signo`, :attr:`si_status`, - :attr:`si_code` or ``None`` if :data:`WNOHANG` is specified and there are no - children in a waitable state. +.. function:: waitid(idtype, id, options, /) - .. availability:: Unix. + Wait for the completion of a child process. - .. versionadded:: 3.3 + *idtype* can be :data:`P_PID`, :data:`P_PGID`, :data:`P_ALL`, or (on Linux) :data:`P_PIDFD`. + The interpretation of *id* depends on it; see their individual descriptions. -.. data:: P_PID - P_PGID - P_ALL + *options* is an OR combination of flags. At least one of :data:`WEXITED`, + :data:`WSTOPPED` or :data:`WCONTINUED` is required; + :data:`WNOHANG` and :data:`WNOWAIT` are additional optional flags. - These are the possible values for *idtype* in :func:`waitid`. They affect - how *id* is interpreted. + The return value is an object representing the data contained in the + :c:type:`!siginfo_t` structure with the following attributes: - .. availability:: Unix. + * :attr:`!si_pid` (process ID) + * :attr:`!si_uid` (real user ID of the child) + * :attr:`!si_signo` (always :data:`~signal.SIGCHLD`) + * :attr:`!si_status` (the exit status or signal number, depending on :attr:`!si_code`) + * :attr:`!si_code` (see :data:`CLD_EXITED` for possible values) - .. versionadded:: 3.3 + If :data:`WNOHANG` is specified and there are no matching children in the + requested state, ``None`` is returned. + Otherwise, if there are no matching children + that could be waited for, :exc:`ChildProcessError` is raised. -.. data:: P_PIDFD - - This is a Linux-specific *idtype* that indicates that *id* is a file - descriptor that refers to a process. - - .. availability:: Linux 5.4+ - - .. versionadded:: 3.9 - -.. data:: WEXITED - WSTOPPED - WNOWAIT - - Flags that can be used in *options* in :func:`waitid` that specify what - child signal to wait for. - - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. versionadded:: 3.3 -.. data:: CLD_EXITED - CLD_KILLED - CLD_DUMPED - CLD_TRAPPED - CLD_STOPPED - CLD_CONTINUED - - These are the possible values for :attr:`si_code` in the result returned by - :func:`waitid`. - - .. availability:: Unix. - - .. versionadded:: 3.3 - - .. versionchanged:: 3.9 - Added :data:`CLD_KILLED` and :data:`CLD_STOPPED` values. - - -.. function:: waitpid(pid, options) +.. function:: waitpid(pid, options, /) The details of this function differ on Unix and Windows. @@ -4369,8 +4554,11 @@ written in Python, such as a mail server's external command delivery program. ``-1``, status is requested for any process in the process group ``-pid`` (the absolute value of *pid*). - An :exc:`OSError` is raised with the value of errno when the syscall - returns -1. + *options* is an OR combination of flags. If it contains :data:`WNOHANG` and + there are no matching children in the requested state, ``(0, 0)`` is + returned. Otherwise, if there are no matching children that could be waited + for, :exc:`ChildProcessError` is raised. Other options that can be used are + :data:`WUNTRACED` and :data:`WCONTINUED`. On Windows: Wait for completion of a process given by process handle *pid*, and return a tuple containing *pid*, and its exit status shifted left by 8 bits @@ -4383,6 +4571,8 @@ written in Python, such as a mail server's external command delivery program. :func:`waitstatus_to_exitcode` can be used to convert the exit status into an exit code. + .. availability:: Unix, Windows, not Emscripten, not WASI. + .. versionchanged:: 3.5 If the system call is interrupted and the signal handler does not raise an exception, the function now retries the system call instead of raising an @@ -4394,28 +4584,133 @@ written in Python, such as a mail server's external command delivery program. Similar to :func:`waitpid`, except no process id argument is given and a 3-element tuple containing the child's process id, exit status indication, and resource usage information is returned. Refer to - :mod:`resource`.\ :func:`~resource.getrusage` for details on resource usage - information. The option argument is the same as that provided to - :func:`waitpid` and :func:`wait4`. + :func:`resource.getrusage` for details on resource usage information. The + *options* argument is the same as that provided to :func:`waitpid` and + :func:`wait4`. :func:`waitstatus_to_exitcode` can be used to convert the exit status into an exitcode. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: wait4(pid, options) Similar to :func:`waitpid`, except a 3-element tuple, containing the child's - process id, exit status indication, and resource usage information is returned. - Refer to :mod:`resource`.\ :func:`~resource.getrusage` for details on - resource usage information. The arguments to :func:`wait4` are the same - as those provided to :func:`waitpid`. + process id, exit status indication, and resource usage information is + returned. Refer to :func:`resource.getrusage` for details on resource usage + information. The arguments to :func:`wait4` are the same as those provided + to :func:`waitpid`. :func:`waitstatus_to_exitcode` can be used to convert the exit status into an exitcode. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. + + +.. data:: P_PID + P_PGID + P_ALL + P_PIDFD + + These are the possible values for *idtype* in :func:`waitid`. They affect + how *id* is interpreted: + + * :data:`!P_PID` - wait for the child whose PID is *id*. + * :data:`!P_PGID` - wait for any child whose progress group ID is *id*. + * :data:`!P_ALL` - wait for any child; *id* is ignored. + * :data:`!P_PIDFD` - wait for the child identified by the file descriptor + *id* (a process file descriptor created with :func:`pidfd_open`). + + .. availability:: Unix, not Emscripten, not WASI. + + .. note:: :data:`!P_PIDFD` is only available on Linux >= 5.4. + + .. versionadded:: 3.3 + .. versionadded:: 3.9 + The :data:`!P_PIDFD` constant. + + +.. data:: WCONTINUED + + This *options* flag for :func:`waitpid`, :func:`wait3`, :func:`wait4`, and + :func:`waitid` causes child processes to be reported if they have been + continued from a job control stop since they were last reported. + + .. availability:: Unix, not Emscripten, not WASI. + + +.. data:: WEXITED + + This *options* flag for :func:`waitid` causes child processes that have terminated to + be reported. + + The other ``wait*`` functions always report children that have terminated, + so this option is not available for them. + + .. availability:: Unix, not Emscripten, not WASI. + + .. versionadded:: 3.3 + + +.. data:: WSTOPPED + + This *options* flag for :func:`waitid` causes child processes that have been stopped + by the delivery of a signal to be reported. + + This option is not available for the other ``wait*`` functions. + + .. availability:: Unix, not Emscripten, not WASI. + + .. versionadded:: 3.3 + + +.. data:: WUNTRACED + + This *options* flag for :func:`waitpid`, :func:`wait3`, and :func:`wait4` causes + child processes to also be reported if they have been stopped but their + current state has not been reported since they were stopped. + + This option is not available for :func:`waitid`. + + .. availability:: Unix, not Emscripten, not WASI. + + +.. data:: WNOHANG + + This *options* flag causes :func:`waitpid`, :func:`wait3`, :func:`wait4`, and + :func:`waitid` to return right away if no child process status is available + immediately. + + .. availability:: Unix, not Emscripten, not WASI. + + +.. data:: WNOWAIT + + This *options* flag causes :func:`waitid` to leave the child in a waitable state, so that + a later :func:`!wait*` call can be used to retrieve the child status information again. + + This option is not available for the other ``wait*`` functions. + + .. availability:: Unix, not Emscripten, not WASI. + + +.. data:: CLD_EXITED + CLD_KILLED + CLD_DUMPED + CLD_TRAPPED + CLD_STOPPED + CLD_CONTINUED + + These are the possible values for :attr:`!si_code` in the result returned by + :func:`waitid`. + + .. availability:: Unix, not Emscripten, not WASI. + + .. versionadded:: 3.3 + + .. versionchanged:: 3.9 + Added :data:`CLD_KILLED` and :data:`CLD_STOPPED` values. .. function:: waitstatus_to_exitcode(status) @@ -4445,45 +4740,23 @@ written in Python, such as a mail server's external command delivery program. :func:`WIFEXITED`, :func:`WEXITSTATUS`, :func:`WIFSIGNALED`, :func:`WTERMSIG`, :func:`WIFSTOPPED`, :func:`WSTOPSIG` functions. + .. availability:: Unix, Windows, not Emscripten, not WASI. + .. versionadded:: 3.9 -.. data:: WNOHANG - - The option for :func:`waitpid` to return immediately if no child process status - is available immediately. The function returns ``(0, 0)`` in this case. - - .. availability:: Unix. - - -.. data:: WCONTINUED - - This option causes child processes to be reported if they have been continued - from a job control stop since their status was last reported. - - .. availability:: some Unix systems. - - -.. data:: WUNTRACED - - This option causes child processes to be reported if they have been stopped but - their current state has not been reported since they were stopped. - - .. availability:: Unix. - - The following functions take a process status code as returned by :func:`system`, :func:`wait`, or :func:`waitpid` as a parameter. They may be used to determine the disposition of a process. -.. function:: WCOREDUMP(status) +.. function:: WCOREDUMP(status, /) Return ``True`` if a core dump was generated for the process, otherwise return ``False``. This function should be employed only if :func:`WIFSIGNALED` is true. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WIFCONTINUED(status) @@ -4494,7 +4767,7 @@ used to determine the disposition of a process. See :data:`WCONTINUED` option. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WIFSTOPPED(status) @@ -4506,14 +4779,14 @@ used to determine the disposition of a process. done using :data:`WUNTRACED` option or when the process is being traced (see :manpage:`ptrace(2)`). - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WIFSIGNALED(status) Return ``True`` if the process was terminated by a signal, otherwise return ``False``. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WIFEXITED(status) @@ -4522,7 +4795,7 @@ used to determine the disposition of a process. by calling ``exit()`` or ``_exit()``, or by returning from ``main()``; otherwise return ``False``. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WEXITSTATUS(status) @@ -4531,7 +4804,7 @@ used to determine the disposition of a process. This function should be employed only if :func:`WIFEXITED` is true. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WSTOPSIG(status) @@ -4540,7 +4813,7 @@ used to determine the disposition of a process. This function should be employed only if :func:`WIFSTOPPED` is true. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. .. function:: WTERMSIG(status) @@ -4549,7 +4822,7 @@ used to determine the disposition of a process. This function should be employed only if :func:`WIFSIGNALED` is true. - .. availability:: Unix. + .. availability:: Unix, not Emscripten, not WASI. Interface to the scheduler @@ -4621,33 +4894,33 @@ operating system. scheduling policy constants above. -.. function:: sched_setscheduler(pid, policy, param) +.. function:: sched_setscheduler(pid, policy, param, /) Set the scheduling policy for the process with PID *pid*. A *pid* of 0 means the calling process. *policy* is one of the scheduling policy constants above. *param* is a :class:`sched_param` instance. -.. function:: sched_getscheduler(pid) +.. function:: sched_getscheduler(pid, /) Return the scheduling policy for the process with PID *pid*. A *pid* of 0 means the calling process. The result is one of the scheduling policy constants above. -.. function:: sched_setparam(pid, param) +.. function:: sched_setparam(pid, param, /) Set the scheduling parameters for the process with PID *pid*. A *pid* of 0 means the calling process. *param* is a :class:`sched_param` instance. -.. function:: sched_getparam(pid) +.. function:: sched_getparam(pid, /) Return the scheduling parameters as a :class:`sched_param` instance for the process with PID *pid*. A *pid* of 0 means the calling process. -.. function:: sched_rr_get_interval(pid) +.. function:: sched_rr_get_interval(pid, /) Return the round-robin quantum in seconds for the process with PID *pid*. A *pid* of 0 means the calling process. @@ -4658,14 +4931,14 @@ operating system. Voluntarily relinquish the CPU. -.. function:: sched_setaffinity(pid, mask) +.. function:: sched_setaffinity(pid, mask, /) Restrict the process with PID *pid* (or the current process if zero) to a set of CPUs. *mask* is an iterable of integers representing the set of CPUs to which the process should be restricted. -.. function:: sched_getaffinity(pid) +.. function:: sched_getaffinity(pid, /) Return the set of CPUs the process with PID *pid* (or the current process if zero) is restricted to. @@ -4677,7 +4950,7 @@ Miscellaneous System Information -------------------------------- -.. function:: confstr(name) +.. function:: confstr(name, /) Return string-valued system configuration values. *name* specifies the configuration value to retrieve; it may be a string which is the name of a @@ -4728,7 +5001,7 @@ Miscellaneous System Information .. availability:: Unix. -.. function:: sysconf(name) +.. function:: sysconf(name, /) Return integer-valued system configuration values. If the configuration value specified by *name* isn't defined, ``-1`` is returned. The comments regarding @@ -4746,6 +5019,9 @@ Miscellaneous System Information .. availability:: Unix. + .. versionchanged:: 3.11 + Add ``'SC_MINSIGSTKSZ'`` name. + The following data values are used to support path manipulation operations. These are defined for all platforms. @@ -4862,15 +5138,15 @@ Random numbers :py:data:`GRND_NONBLOCK`. See also the `Linux getrandom() manual page - `_. + `_. - .. availability:: Linux 3.17 and newer. + .. availability:: Linux >= 3.17. .. versionadded:: 3.6 -.. function:: urandom(size) +.. function:: urandom(size, /) - Return a string of *size* random bytes suitable for cryptographic use. + Return a bytestring of *size* random bytes suitable for cryptographic use. This function returns random bytes from an OS-specific randomness source. The returned data should be unpredictable enough for cryptographic applications, diff --git a/Doc/library/ossaudiodev.rst b/Doc/library/ossaudiodev.rst index a7d3dac363c..e14c1bf8d53 100644 --- a/Doc/library/ossaudiodev.rst +++ b/Doc/library/ossaudiodev.rst @@ -4,6 +4,11 @@ .. module:: ossaudiodev :platform: Linux, FreeBSD :synopsis: Access to OSS-compatible audio devices. + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + The :mod:`ossaudiodev` module is deprecated + (see :pep:`PEP 594 <594#ossaudiodev>` for details). -------------- diff --git a/Doc/library/pathlib-inheritance.svg b/Doc/library/pathlib-inheritance.svg index 49057f678fd..01f8684a2b2 100644 --- a/Doc/library/pathlib-inheritance.svg +++ b/Doc/library/pathlib-inheritance.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index b6507eb4d6f..f222745a2c5 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -118,26 +118,28 @@ we also call *flavours*: >>> PurePath() PurePosixPath('.') - When several absolute paths are given, the last is taken as an anchor - (mimicking :func:`os.path.join`'s behaviour):: + If a segment is an absolute path, all previous segments are ignored + (like :func:`os.path.join`):: >>> PurePath('/etc', '/usr', 'lib64') PurePosixPath('/usr/lib64') >>> PureWindowsPath('c:/Windows', 'd:bar') PureWindowsPath('d:bar') - However, in a Windows path, changing the local root doesn't discard the - previous drive setting:: + On Windows, the drive is not reset when a rooted relative path + segment (e.g., ``r'\foo'``) is encountered:: >>> PureWindowsPath('c:/Windows', '/Program Files') PureWindowsPath('c:/Program Files') Spurious slashes and single dots are collapsed, but double dots (``'..'``) - are not, since this would change the meaning of a path in the face of - symbolic links:: + and leading double slashes (``'//'``) are not, since this would change the + meaning of a path for various reasons (e.g. symbolic links, UNC paths):: >>> PurePath('foo//bar') PurePosixPath('foo/bar') + >>> PurePath('//foo/bar') + PurePosixPath('//foo/bar') >>> PurePath('foo/./bar') PurePosixPath('foo/bar') >>> PurePath('foo/../bar') @@ -166,13 +168,17 @@ we also call *flavours*: .. class:: PureWindowsPath(*pathsegments) A subclass of :class:`PurePath`, this path flavour represents Windows - filesystem paths:: + filesystem paths, including `UNC paths`_:: >>> PureWindowsPath('c:/Program Files/') PureWindowsPath('c:/Program Files') + >>> PureWindowsPath('//server/share/file') + PureWindowsPath('//server/share/file') *pathsegments* is specified similarly to :class:`PurePath`. + .. _unc paths: https://en.wikipedia.org/wiki/Path_(computing)#UNC + Regardless of the system you're running on, you can instantiate all of these classes, since they don't provide any operation that does system calls. @@ -206,7 +212,10 @@ Paths of a different flavour compare unequal and cannot be ordered:: Operators ^^^^^^^^^ -The slash operator helps create child paths, similarly to :func:`os.path.join`:: +The slash operator helps create child paths, like :func:`os.path.join`. +If the argument is an absolute path, the previous path is ignored. +On Windows, the drive is not reset when the argument is a rooted +relative path (e.g., ``r'\foo'``):: >>> p = PurePath('/etc') >>> p @@ -216,6 +225,10 @@ The slash operator helps create child paths, similarly to :func:`os.path.join`:: >>> q = PurePath('bin') >>> '/usr' / q PurePosixPath('/usr/bin') + >>> p / '/an_absolute_path' + PurePosixPath('/an_absolute_path') + >>> PureWindowsPath('c:/Windows', '/Program Files') + PureWindowsPath('c:/Program Files') A path object can be used anywhere an object implementing :class:`os.PathLike` is accepted:: @@ -253,7 +266,7 @@ Accessing individual parts To access the individual "parts" (components) of a path, use the following property: -.. data:: PurePath.parts +.. attribute:: PurePath.parts A tuple giving access to the path's various components:: @@ -277,7 +290,7 @@ Methods and properties Pure paths provide the following methods and properties: -.. data:: PurePath.drive +.. attribute:: PurePath.drive A string representing the drive letter or name, if any:: @@ -293,7 +306,7 @@ Pure paths provide the following methods and properties: >>> PureWindowsPath('//host/share/foo.txt').drive '\\\\host\\share' -.. data:: PurePath.root +.. attribute:: PurePath.root A string representing the (local or global) root, if any:: @@ -309,7 +322,27 @@ Pure paths provide the following methods and properties: >>> PureWindowsPath('//host/share').root '\\' -.. data:: PurePath.anchor + If the path starts with more than two successive slashes, + :class:`~pathlib.PurePosixPath` collapses them:: + + >>> PurePosixPath('//etc').root + '//' + >>> PurePosixPath('///etc').root + '/' + >>> PurePosixPath('////etc').root + '/' + + .. note:: + + This behavior conforms to *The Open Group Base Specifications Issue 6*, + paragraph `4.11 Pathname Resolution + `_: + + *"A pathname that begins with two successive slashes may be interpreted in + an implementation-defined manner, although more than two leading slashes + shall be treated as a single slash."* + +.. attribute:: PurePath.anchor The concatenation of the drive and root:: @@ -323,7 +356,7 @@ Pure paths provide the following methods and properties: '\\\\host\\share\\' -.. data:: PurePath.parents +.. attribute:: PurePath.parents An immutable sequence providing access to the logical ancestors of the path:: @@ -339,7 +372,7 @@ Pure paths provide the following methods and properties: .. versionchanged:: 3.10 The parents sequence now supports :term:`slices ` and negative index values. -.. data:: PurePath.parent +.. attribute:: PurePath.parent The logical parent of the path:: @@ -365,10 +398,10 @@ Pure paths provide the following methods and properties: If you want to walk an arbitrary filesystem path upwards, it is recommended to first call :meth:`Path.resolve` so as to resolve - symlinks and eliminate `".."` components. + symlinks and eliminate ``".."`` components. -.. data:: PurePath.name +.. attribute:: PurePath.name A string representing the final path component, excluding the drive and root, if any:: @@ -384,7 +417,7 @@ Pure paths provide the following methods and properties: '' -.. data:: PurePath.suffix +.. attribute:: PurePath.suffix The file extension of the final component, if any:: @@ -396,7 +429,7 @@ Pure paths provide the following methods and properties: '' -.. data:: PurePath.suffixes +.. attribute:: PurePath.suffixes A list of the path's file extensions:: @@ -408,7 +441,7 @@ Pure paths provide the following methods and properties: [] -.. data:: PurePath.stem +.. attribute:: PurePath.stem The final path component, without its suffix:: @@ -464,7 +497,7 @@ Pure paths provide the following methods and properties: True -.. method:: PurePath.is_relative_to(*other) +.. method:: PurePath.is_relative_to(other) Return whether or not this path is relative to the *other* path. @@ -476,6 +509,10 @@ Pure paths provide the following methods and properties: .. versionadded:: 3.9 + .. deprecated-removed:: 3.12 3.14 + + Passing additional arguments is deprecated; if supplied, they are joined + with *other*. .. method:: PurePath.is_reserved() @@ -538,10 +575,10 @@ Pure paths provide the following methods and properties: True -.. method:: PurePath.relative_to(*other) +.. method:: PurePath.relative_to(other, walk_up=False) Compute a version of this path relative to the path represented by - *other*. If it's impossible, ValueError is raised:: + *other*. If it's impossible, :exc:`ValueError` is raised:: >>> p = PurePosixPath('/etc/passwd') >>> p.relative_to('/') @@ -551,12 +588,38 @@ Pure paths provide the following methods and properties: >>> p.relative_to('/usr') Traceback (most recent call last): File "", line 1, in - File "pathlib.py", line 694, in relative_to - .format(str(self), str(formatted))) - ValueError: '/etc/passwd' is not in the subpath of '/usr' OR one path is relative and the other absolute. + File "pathlib.py", line 941, in relative_to + raise ValueError(error_message.format(str(self), str(formatted))) + ValueError: '/etc/passwd' is not in the subpath of '/usr' OR one path is relative and the other is absolute. - NOTE: This function is part of :class:`PurePath` and works with strings. It does not check or access the underlying file structure. + When *walk_up* is False (the default), the path must start with *other*. + When the argument is True, ``..`` entries may be added to form the + relative path. In all other cases, such as the paths referencing + different drives, :exc:`ValueError` is raised.:: + >>> p.relative_to('/usr', walk_up=True) + PurePosixPath('../etc/passwd') + >>> p.relative_to('foo', walk_up=True) + Traceback (most recent call last): + File "", line 1, in + File "pathlib.py", line 941, in relative_to + raise ValueError(error_message.format(str(self), str(formatted))) + ValueError: '/etc/passwd' is not on the same drive as 'foo' OR one path is relative and the other is absolute. + + .. warning:: + This function is part of :class:`PurePath` and works with strings. + It does not check or access the underlying file structure. + This can impact the *walk_up* option as it assumes that no symlinks + are present in the path; call :meth:`~Path.resolve` first if + necessary to resolve symlinks. + + .. versionadded:: 3.12 + The *walk_up* argument (old behavior is the same as ``walk_up=False``). + + .. deprecated-removed:: 3.12 3.14 + + Passing additional positional arguments is deprecated; if supplied, + they are joined with *other*. .. method:: PurePath.with_name(name) @@ -815,6 +878,9 @@ call fails (for example because the path doesn't exist). .. audit-event:: pathlib.Path.glob self,pattern pathlib.Path.glob + .. versionchanged:: 3.11 + Return only directories if *pattern* ends with a pathname components + separator (:data:`~os.sep` or :data:`~os.altsep`). .. method:: Path.group() @@ -840,6 +906,14 @@ call fails (for example because the path doesn't exist). other errors (such as permission errors) are propagated. +.. method:: Path.is_junction() + + Return ``True`` if the path points to a junction, and ``False`` for any other + type of file. Currently only Windows supports junctions. + + .. versionadded:: 3.12 + + .. method:: Path.is_mount() Return ``True`` if the path is a :dfn:`mount point`: a point in a @@ -847,10 +921,15 @@ call fails (for example because the path doesn't exist). function checks whether *path*'s parent, :file:`path/..`, is on a different device than *path*, or whether :file:`path/..` and *path* point to the same i-node on the same device --- this should detect mount points for all Unix - and POSIX variants. Not implemented on Windows. + and POSIX variants. On Windows, a mount point is considered to be a drive + letter root (e.g. ``c:\``), a UNC share (e.g. ``\\server\share``), or a + mounted filesystem directory. .. versionadded:: 3.7 + .. versionchanged:: 3.12 + Windows support was added. + .. method:: Path.is_symlink() @@ -914,9 +993,104 @@ call fails (for example because the path doesn't exist). The children are yielded in arbitrary order, and the special entries ``'.'`` and ``'..'`` are not included. If a file is removed from or added - to the directory after creating the iterator, whether an path object for + to the directory after creating the iterator, whether a path object for that file be included is unspecified. +.. method:: Path.walk(top_down=True, on_error=None, follow_symlinks=False) + + Generate the file names in a directory tree by walking the tree + either top-down or bottom-up. + + For each directory in the directory tree rooted at *self* (including + *self* but excluding '.' and '..'), the method yields a 3-tuple of + ``(dirpath, dirnames, filenames)``. + + *dirpath* is a :class:`Path` to the directory currently being walked, + *dirnames* is a list of strings for the names of subdirectories in *dirpath* + (excluding ``'.'`` and ``'..'``), and *filenames* is a list of strings for + the names of the non-directory files in *dirpath*. To get a full path + (which begins with *self*) to a file or directory in *dirpath*, do + ``dirpath / name``. Whether or not the lists are sorted is file + system-dependent. + + If the optional argument *top_down* is true (which is the default), the triple for a + directory is generated before the triples for any of its subdirectories + (directories are walked top-down). If *top_down* is false, the triple + for a directory is generated after the triples for all of its subdirectories + (directories are walked bottom-up). No matter the value of *top_down*, the + list of subdirectories is retrieved before the triples for the directory and + its subdirectories are walked. + + When *top_down* is true, the caller can modify the *dirnames* list in-place + (for example, using :keyword:`del` or slice assignment), and :meth:`Path.walk` + will only recurse into the subdirectories whose names remain in *dirnames*. + This can be used to prune the search, or to impose a specific order of visiting, + or even to inform :meth:`Path.walk` about directories the caller creates or + renames before it resumes :meth:`Path.walk` again. Modifying *dirnames* when + *top_down* is false has no effect on the behavior of :meth:`Path.walk()` since the + directories in *dirnames* have already been generated by the time *dirnames* + is yielded to the caller. + + By default, errors from :func:`os.scandir` are ignored. If the optional + argument *on_error* is specified, it should be a callable; it will be + called with one argument, an :exc:`OSError` instance. The callable can handle the + error to continue the walk or re-raise it to stop the walk. Note that the + filename is available as the ``filename`` attribute of the exception object. + + By default, :meth:`Path.walk` does not follow symbolic links, and instead adds them + to the *filenames* list. Set *follow_symlinks* to true to resolve symlinks + and place them in *dirnames* and *filenames* as appropriate for their targets, and + consequently visit directories pointed to by symlinks (where supported). + + .. note:: + + Be aware that setting *follow_symlinks* to true can lead to infinite + recursion if a link points to a parent directory of itself. :meth:`Path.walk` + does not keep track of the directories it has already visited. + + .. note:: + :meth:`Path.walk` assumes the directories it walks are not modified during + execution. For example, if a directory from *dirnames* has been replaced + with a symlink and *follow_symlinks* is false, :meth:`Path.walk` will + still try to descend into it. To prevent such behavior, remove directories + from *dirnames* as appropriate. + + .. note:: + + Unlike :func:`os.walk`, :meth:`Path.walk` lists symlinks to directories in + *filenames* if *follow_symlinks* is false. + + This example displays the number of bytes used by all files in each directory, + while ignoring ``__pycache__`` directories:: + + from pathlib import Path + for root, dirs, files in Path("cpython/Lib/concurrent").walk(on_error=print): + print( + root, + "consumes", + sum((root / file).stat().st_size for file in files), + "bytes in", + len(files), + "non-directory files" + ) + if '__pycache__' in dirs: + dirs.remove('__pycache__') + + This next example is a simple implementation of :func:`shutil.rmtree`. + Walking the tree bottom-up is essential as :func:`rmdir` doesn't allow + deleting a directory before it is empty:: + + # Delete everything reachable from the directory "top". + # CAUTION: This is dangerous! For example, if top == Path('/'), + # it could delete all of your files. + for root, dirs, files in top.walk(top_down=False): + for name in files: + (root / name).unlink() + for name in dirs: + (root / name).rmdir() + + .. versionadded:: 3.12 + .. method:: Path.lchmod(mode) Like :meth:`Path.chmod` but, if the path points to a symbolic link, the @@ -1018,8 +1192,9 @@ call fails (for example because the path doesn't exist). Rename this file or directory to the given *target*, and return a new Path instance pointing to *target*. On Unix, if *target* exists and is a file, - it will be replaced silently if the user has permission. *target* can be - either a string or another path object:: + it will be replaced silently if the user has permission. + On Windows, if *target* exists, :exc:`FileExistsError` will be raised. + *target* can be either a string or another path object:: >>> p = Path('foo') >>> p.open('w').write('some text') @@ -1034,6 +1209,8 @@ call fails (for example because the path doesn't exist). relative to the current working directory, *not* the directory of the Path object. + It is implemented in terms of :func:`os.rename` and gives the same guarantees. + .. versionchanged:: 3.8 Added return value, return the new Path instance. @@ -1042,7 +1219,7 @@ call fails (for example because the path doesn't exist). Rename this file or directory to the given *target*, and return a new Path instance pointing to *target*. If *target* points to an existing file or - directory, it will be unconditionally replaced. + empty directory, it will be unconditionally replaced. The target path may be absolute or relative. Relative paths are interpreted relative to the current working directory, *not* the directory of the Path @@ -1052,6 +1229,18 @@ call fails (for example because the path doesn't exist). Added return value, return the new Path instance. +.. method:: Path.absolute() + + Make the path absolute, without normalization or resolving symlinks. + Returns a new path object:: + + >>> p = Path('tests') + >>> p + PosixPath('tests') + >>> p.absolute() + PosixPath('/home/antoine/pathlib/tests') + + .. method:: Path.resolve(strict=False) Make the path absolute, resolving any symlinks. A new path object is @@ -1080,8 +1269,9 @@ call fails (for example because the path doesn't exist). .. method:: Path.rglob(pattern) - This is like calling :func:`Path.glob` with "``**/``" added in front of the - given relative *pattern*:: + Glob the given relative *pattern* recursively. This is like calling + :func:`Path.glob` with "``**/``" added in front of the *pattern*, where + *patterns* are the same as for :mod:`fnmatch`:: >>> sorted(Path().rglob("*.py")) [PosixPath('build/lib/pathlib.py'), @@ -1092,6 +1282,9 @@ call fails (for example because the path doesn't exist). .. audit-event:: pathlib.Path.rglob self,pattern pathlib.Path.rglob + .. versionchanged:: 3.11 + Return only directories if *pattern* ends with a pathname components + separator (:data:`~os.sep` or :data:`~os.altsep`). .. method:: Path.rmdir() @@ -1150,25 +1343,6 @@ call fails (for example because the path doesn't exist). .. versionadded:: 3.10 -.. method:: Path.link_to(target) - - Make *target* a hard link to this path. - - .. warning:: - - This function does not make this path a hard link to *target*, despite - the implication of the function and argument names. The argument order - (target, link) is the reverse of :func:`Path.symlink_to` and - :func:`Path.hardlink_to`, but matches that of :func:`os.link`. - - .. versionadded:: 3.8 - - .. deprecated:: 3.10 - - This method is deprecated in favor of :meth:`Path.hardlink_to`, as the - argument order of :meth:`Path.link_to` does not match that of - :meth:`Path.symlink_to`. - .. method:: Path.touch(mode=0o666, exist_ok=True) @@ -1239,13 +1413,14 @@ Below is a table mapping various :mod:`os` functions to their corresponding Not all pairs of functions/methods below are equivalent. Some of them, despite having some overlapping use-cases, have different semantics. They - include :func:`os.path.abspath` and :meth:`Path.resolve`, + include :func:`os.path.abspath` and :meth:`Path.absolute`, :func:`os.path.relpath` and :meth:`PurePath.relative_to`. ==================================== ============================== :mod:`os` and :mod:`os.path` :mod:`pathlib` ==================================== ============================== -:func:`os.path.abspath` :meth:`Path.resolve` [#]_ +:func:`os.path.abspath` :meth:`Path.absolute` [#]_ +:func:`os.path.realpath` :meth:`Path.resolve` :func:`os.chmod` :meth:`Path.chmod` :func:`os.mkdir` :meth:`Path.mkdir` :func:`os.makedirs` :meth:`Path.mkdir` @@ -1258,25 +1433,27 @@ Below is a table mapping various :mod:`os` functions to their corresponding :func:`os.path.expanduser` :meth:`Path.expanduser` and :meth:`Path.home` :func:`os.listdir` :meth:`Path.iterdir` +:func:`os.walk` :meth:`Path.walk` :func:`os.path.isdir` :meth:`Path.is_dir` :func:`os.path.isfile` :meth:`Path.is_file` :func:`os.path.islink` :meth:`Path.is_symlink` :func:`os.link` :meth:`Path.hardlink_to` :func:`os.symlink` :meth:`Path.symlink_to` :func:`os.readlink` :meth:`Path.readlink` -:func:`os.path.relpath` :meth:`Path.relative_to` [#]_ +:func:`os.path.relpath` :meth:`PurePath.relative_to` [#]_ :func:`os.stat` :meth:`Path.stat`, :meth:`Path.owner`, :meth:`Path.group` :func:`os.path.isabs` :meth:`PurePath.is_absolute` :func:`os.path.join` :func:`PurePath.joinpath` -:func:`os.path.basename` :data:`PurePath.name` -:func:`os.path.dirname` :data:`PurePath.parent` +:func:`os.path.basename` :attr:`PurePath.name` +:func:`os.path.dirname` :attr:`PurePath.parent` :func:`os.path.samefile` :meth:`Path.samefile` -:func:`os.path.splitext` :data:`PurePath.suffix` +:func:`os.path.splitext` :attr:`PurePath.stem` and + :attr:`PurePath.suffix` ==================================== ============================== .. rubric:: Footnotes -.. [#] :func:`os.path.abspath` does not resolve symbolic links while :meth:`Path.resolve` does. -.. [#] :meth:`Path.relative_to` requires ``self`` to be the subpath of the argument, but :func:`os.path.relpath` does not. +.. [#] :func:`os.path.abspath` normalizes the resulting path, which may change its meaning in the presence of symlinks, while :meth:`Path.absolute` does not. +.. [#] :meth:`PurePath.relative_to` requires ``self`` to be the subpath of the argument, but :func:`os.path.relpath` does not. diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index 6d1dba1bf2e..383c3adcf28 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -67,14 +67,13 @@ useful than quitting the debugger upon program's exit. before the first line of the module. -The typical usage to break into the debugger from a running program is to -insert :: +The typical usage to break into the debugger is to insert:: import pdb; pdb.set_trace() -at the location you want to break into the debugger. You can then step through -the code following this statement, and continue running without the debugger -using the :pdbcmd:`continue` command. +at the location you want to break into the debugger, and then run the program. +You can then step through the code following this statement, and continue +running without the debugger using the :pdbcmd:`continue` command. .. versionadded:: 3.7 The built-in :func:`breakpoint()`, when called with defaults, can be used @@ -234,7 +233,8 @@ Multiple commands may be entered on a single line, separated by ``;;``. (A single ``;`` is not used as it is the separator for multiple commands in a line that is passed to the Python parser.) No intelligence is applied to separating the commands; the input is split at the first ``;;`` pair, even if it is in the -middle of a quoted string. +middle of a quoted string. A workaround for strings with double semicolons +is to use implicit string concatenation ``';'';'`` or ``";"";"``. .. index:: pair: .pdbrc; file diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index be48561ed10..79476b04cd9 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -90,7 +90,7 @@ Comparison with ``json`` ^^^^^^^^^^^^^^^^^^^^^^^^ There are fundamental differences between the pickle protocols and -`JSON (JavaScript Object Notation) `_: +`JSON (JavaScript Object Notation) `_: * JSON is a text serialization format (it outputs unicode text, although most of the time it is then encoded to ``utf-8``), while pickle is @@ -147,7 +147,7 @@ to read the pickle produced. earlier versions of Python. * Protocol version 2 was introduced in Python 2.3. It provides much more - efficient pickling of :term:`new-style class`\es. Refer to :pep:`307` for + efficient pickling of :term:`new-style classes `. Refer to :pep:`307` for information about improvements brought by protocol 2. * Protocol version 3 was added in Python 3.0. It has explicit support for @@ -261,7 +261,7 @@ process more convenient: protocol argument is needed. Bytes past the pickled representation of the object are ignored. - Arguments *file*, *fix_imports*, *encoding*, *errors*, *strict* and *buffers* + Arguments *fix_imports*, *encoding*, *errors*, *strict* and *buffers* have the same meaning as in the :class:`Unpickler` constructor. .. versionchanged:: 3.8 @@ -368,7 +368,7 @@ The :mod:`pickle` module exports three classes, :class:`Pickler`, .. versionadded:: 3.3 - .. method:: reducer_override(self, obj) + .. method:: reducer_override(obj) Special reducer that can be defined in :class:`Pickler` subclasses. This method has priority over any reducer in the :attr:`dispatch_table`. It @@ -494,24 +494,21 @@ What can be pickled and unpickled? The following types can be pickled: -* ``None``, ``True``, and ``False`` +* ``None``, ``True``, and ``False``; -* integers, floating point numbers, complex numbers +* integers, floating-point numbers, complex numbers; -* strings, bytes, bytearrays +* strings, bytes, bytearrays; -* tuples, lists, sets, and dictionaries containing only picklable objects +* tuples, lists, sets, and dictionaries containing only picklable objects; -* functions defined at the top level of a module (using :keyword:`def`, not - :keyword:`lambda`) +* functions (built-in and user-defined) accessible from the top level of a + module (using :keyword:`def`, not :keyword:`lambda`); -* built-in functions defined at the top level of a module +* classes accessible from the top level of a module; -* classes that are defined at the top level of a module - -* instances of such classes whose :attr:`~object.__dict__` or the result of - calling :meth:`__getstate__` is picklable (see section :ref:`pickle-inst` for - details). +* instances of such classes whose the result of calling :meth:`__getstate__` + is picklable (see section :ref:`pickle-inst` for details). Attempts to pickle unpicklable objects will raise the :exc:`PicklingError` exception; when this happens, an unspecified number of bytes may have already @@ -520,14 +517,14 @@ structure may exceed the maximum recursion depth, a :exc:`RecursionError` will b raised in this case. You can carefully raise this limit with :func:`sys.setrecursionlimit`. -Note that functions (built-in and user-defined) are pickled by "fully qualified" -name reference, not by value. [#]_ This means that only the function name is -pickled, along with the name of the module the function is defined in. Neither +Note that functions (built-in and user-defined) are pickled by fully +:term:`qualified name`, not by value. [#]_ This means that only the function name is +pickled, along with the name of the containing module and classes. Neither the function's code, nor any of its function attributes are pickled. Thus the defining module must be importable in the unpickling environment, and the module must contain the named object, otherwise an exception will be raised. [#]_ -Similarly, classes are pickled by named reference, so the same restrictions in +Similarly, classes are pickled by fully qualified name, so the same restrictions in the unpickling environment apply. Note that none of the class's code or data is pickled, so in the following example the class attribute ``attr`` is not restored in the unpickling environment:: @@ -537,7 +534,7 @@ restored in the unpickling environment:: picklestring = pickle.dumps(Foo) -These restrictions are why picklable functions and classes must be defined in +These restrictions are why picklable functions and classes must be defined at the top level of a module. Similarly, when class instances are pickled, their class's code and data are not @@ -569,7 +566,7 @@ implementation of this behaviour:: def save(obj): return (obj.__class__, obj.__dict__) - def load(cls, attributes): + def restore(cls, attributes): obj = cls.__new__(cls) obj.__dict__.update(attributes) return obj @@ -611,11 +608,31 @@ methods: .. method:: object.__getstate__() - Classes can further influence how their instances are pickled; if the class - defines the method :meth:`__getstate__`, it is called and the returned object - is pickled as the contents for the instance, instead of the contents of the - instance's dictionary. If the :meth:`__getstate__` method is absent, the - instance's :attr:`~object.__dict__` is pickled as usual. + Classes can further influence how their instances are pickled by overriding + the method :meth:`__getstate__`. It is called and the returned object + is pickled as the contents for the instance, instead of a default state. + There are several cases: + + * For a class that has no instance :attr:`~object.__dict__` and no + :attr:`~object.__slots__`, the default state is ``None``. + + * For a class that has an instance :attr:`~object.__dict__` and no + :attr:`~object.__slots__`, the default state is ``self.__dict__``. + + * For a class that has an instance :attr:`~object.__dict__` and + :attr:`~object.__slots__`, the default state is a tuple consisting of two + dictionaries: ``self.__dict__``, and a dictionary mapping slot + names to slot values. Only slots that have a value are + included in the latter. + + * For a class that has :attr:`~object.__slots__` and no instance + :attr:`~object.__dict__`, the default state is a tuple whose first item + is ``None`` and whose second item is a dictionary mapping slot names + to slot values described in the previous bullet. + + .. versionchanged:: 3.11 + Added the default implementation of the ``__getstate__()`` method in the + :class:`object` class. .. method:: object.__setstate__(state) @@ -788,14 +805,15 @@ the code :: f = io.BytesIO() p = MyPickler(f) -does the same, but all instances of ``MyPickler`` will by default -share the same dispatch table. The equivalent code using the -:mod:`copyreg` module is :: +does the same but all instances of ``MyPickler`` will by default +share the private dispatch table. On the other hand, the code :: copyreg.pickle(SomeClass, reduce_SomeClass) f = io.BytesIO() p = pickle.Pickler(f) +modifies the global dispatch table shared by all users of the :mod:`copyreg` module. + .. _pickle-state: Handling Stateful Objects @@ -1098,7 +1116,7 @@ Here is an example of an unpickler allowing only few safe classes from the """Helper function analogous to pickle.loads().""" return RestrictedUnpickler(io.BytesIO(s)).load() -A sample usage of our unpickler working has intended:: +A sample usage of our unpickler working as intended:: >>> restricted_loads(pickle.dumps([1, 2, range(15)])) [1, 2, range(0, 15)] @@ -1142,7 +1160,7 @@ For the simplest code, use the :func:`dump` and :func:`load` functions. :: # An arbitrary collection of objects supported by pickle. data = { - 'a': [1, 2.0, 3, 4+6j], + 'a': [1, 2.0, 3+4j], 'b': ("character string", b"byte string"), 'c': {None, True, False} } @@ -1198,6 +1216,6 @@ The following example reads the resulting pickled data. :: operations. .. [#] The limitation on alphanumeric characters is due to the fact - the persistent IDs, in protocol 0, are delimited by the newline + that persistent IDs in protocol 0 are delimited by the newline character. Therefore if any kind of newline characters occurs in - persistent IDs, the resulting pickle will become unreadable. + persistent IDs, the resulting pickled data will become unreadable. diff --git a/Doc/library/pipes.rst b/Doc/library/pipes.rst index 57e27a6acf4..471ae0dbc97 100644 --- a/Doc/library/pipes.rst +++ b/Doc/library/pipes.rst @@ -4,11 +4,17 @@ .. module:: pipes :platform: Unix :synopsis: A Python interface to Unix shell pipelines. + :deprecated: .. sectionauthor:: Moshe Zadka **Source code:** :source:`Lib/pipes.py` +.. deprecated-removed:: 3.11 3.13 + The :mod:`pipes` module is deprecated + (see :pep:`PEP 594 <594#pipes>` for details). + Please use the :mod:`subprocess` module instead. + -------------- The :mod:`pipes` module defines a class to abstract the concept of a *pipeline* @@ -17,7 +23,7 @@ The :mod:`pipes` module defines a class to abstract the concept of a *pipeline* Because the module uses :program:`/bin/sh` command lines, a POSIX or compatible shell for :func:`os.system` and :func:`os.popen` is required. -.. availability:: Unix. Not available on VxWorks. +.. availability:: Unix, not VxWorks. The :mod:`pipes` module defines the following class: diff --git a/Doc/library/pkgutil.rst b/Doc/library/pkgutil.rst index 3b17b9a6219..788a02dcb89 100644 --- a/Doc/library/pkgutil.rst +++ b/Doc/library/pkgutil.rst @@ -26,7 +26,7 @@ support. __path__ = extend_path(__path__, __name__) This will add to the package's ``__path__`` all subdirectories of directories - on ``sys.path`` named after the package. This is useful if one wants to + on :data:`sys.path` named after the package. This is useful if one wants to distribute different parts of a single logical package as multiple directories. @@ -128,9 +128,9 @@ support. Yield :term:`finder` objects for the given module name. - If fullname contains a '.', the finders will be for the package + If fullname contains a ``'.'``, the finders will be for the package containing fullname, otherwise they will be all registered top level - finders (i.e. those on both sys.meta_path and sys.path_hooks). + finders (i.e. those on both :data:`sys.meta_path` and :data:`sys.path_hooks`). If the named module is in a package, that package is imported as a side effect of invoking this function. @@ -145,7 +145,7 @@ support. .. function:: iter_modules(path=None, prefix='') Yields :class:`ModuleInfo` for all submodules on *path*, or, if - *path* is ``None``, all top-level modules on ``sys.path``. + *path* is ``None``, all top-level modules on :data:`sys.path`. *path* should be either ``None`` or a list of paths to look for modules in. diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst index a0eece6c4d8..a0c9f63ab9f 100644 --- a/Doc/library/platform.rst +++ b/Doc/library/platform.rst @@ -53,7 +53,7 @@ Cross Platform .. function:: machine() - Returns the machine type, e.g. ``'i386'``. An empty string is returned if the + Returns the machine type, e.g. ``'AMD64'``. An empty string is returned if the value cannot be determined. @@ -139,7 +139,7 @@ Cross Platform .. function:: release() - Returns the system's release, e.g. ``'2.2.0'`` or ``'NT'`` An empty string is + Returns the system's release, e.g. ``'2.2.0'`` or ``'NT'``. An empty string is returned if the value cannot be determined. @@ -168,15 +168,19 @@ Cross Platform containing six attributes: :attr:`system`, :attr:`node`, :attr:`release`, :attr:`version`, :attr:`machine`, and :attr:`processor`. - Note that this adds a sixth attribute (:attr:`processor`) not present - in the :func:`os.uname` result. Also, the attribute names are different - for the first two attributes; :func:`os.uname` names them - :attr:`sysname` and :attr:`nodename`. + :attr:`processor` is resolved late, on demand. + + Note: the first two attribute names differ from the names presented by + :func:`os.uname`, where they are named :attr:`sysname` and + :attr:`nodename`. Entries which cannot be determined are set to ``''``. .. versionchanged:: 3.3 - Result changed from a tuple to a namedtuple. + Result changed from a tuple to a :func:`~collections.namedtuple`. + + .. versionchanged:: 3.9 + :attr:`processor` is resolved late instead of immediately. Java Platform @@ -201,7 +205,9 @@ Windows Platform Get additional version information from the Windows Registry and return a tuple ``(release, version, csd, ptype)`` referring to OS release, version number, - CSD level (service pack) and OS type (multi/single processor). + CSD level (service pack) and OS type (multi/single processor). Values which + cannot be determined are set to the defaults given as parameters (which all + default to an empty string). As a hint: *ptype* is ``'Uniprocessor Free'`` on single processor NT machines and ``'Multiprocessor Free'`` on multi processor machines. The *'Free'* refers @@ -211,9 +217,9 @@ Windows Platform .. function:: win32_edition() - Returns a string representing the current Windows edition. Possible - values include but are not limited to ``'Enterprise'``, ``'IoTUAP'``, - ``'ServerStandard'``, and ``'nanoserver'``. + Returns a string representing the current Windows edition, or ``None`` if the + value cannot be determined. Possible values include but are not limited to + ``'Enterprise'``, ``'IoTUAP'``, ``'ServerStandard'``, and ``'nanoserver'``. .. versionadded:: 3.8 diff --git a/Doc/library/poplib.rst b/Doc/library/poplib.rst index 27202a168e7..d8618ce9b60 100644 --- a/Doc/library/poplib.rst +++ b/Doc/library/poplib.rst @@ -28,6 +28,8 @@ quality of POP3 servers varies widely, and too many are quite poor. If your mailserver supports IMAP, you would be better off using the :class:`imaplib.IMAP4` class, as IMAP servers tend to be better implemented. +.. include:: ../includes/wasm-notavail.rst + The :mod:`poplib` module provides two classes: @@ -51,7 +53,7 @@ The :mod:`poplib` module provides two classes: If the *timeout* parameter is set to be zero, it will raise a :class:`ValueError` to prevent the creation of a non-blocking socket. -.. class:: POP3_SSL(host, port=POP3_SSL_PORT, keyfile=None, certfile=None, timeout=None, context=None) +.. class:: POP3_SSL(host, port=POP3_SSL_PORT, *, timeout=None, context=None) This is a subclass of :class:`POP3` that connects to the server over an SSL encrypted socket. If *port* is not specified, 995, the standard POP3-over-SSL @@ -61,10 +63,6 @@ The :mod:`poplib` module provides two classes: single (potentially long-lived) structure. Please read :ref:`ssl-security` for best practices. - *keyfile* and *certfile* are a legacy alternative to *context* - they can - point to PEM-formatted private key and certificate chain files, - respectively, for the SSL connection. - .. audit-event:: poplib.connect self,host,port poplib.POP3_SSL .. audit-event:: poplib.putline self,line poplib.POP3_SSL @@ -92,6 +90,9 @@ The :mod:`poplib` module provides two classes: If the *timeout* parameter is set to be zero, it will raise a :class:`ValueError` to prevent the creation of a non-blocking socket. + .. versionchanged:: 3.12 + The deprecated *keyfile* and *certfile* parameters have been removed. + One exception is defined as an attribute of the :mod:`poplib` module: @@ -121,7 +122,7 @@ POP3 Objects All POP3 commands are represented by methods of the same name, in lowercase; most return the response text sent by the server. -An :class:`POP3` instance has the following methods: +A :class:`POP3` instance has the following methods: .. method:: POP3.set_debuglevel(level) diff --git a/Doc/library/posix.rst b/Doc/library/posix.rst index ad417a17879..ec04b0dcfc1 100644 --- a/Doc/library/posix.rst +++ b/Doc/library/posix.rst @@ -37,14 +37,14 @@ Large File Support .. sectionauthor:: Steve Clift -Several operating systems (including AIX, HP-UX and Solaris) provide +Several operating systems (including AIX and Solaris) provide support for files that are larger than 2 GiB from a C programming model where -:c:type:`int` and :c:type:`long` are 32-bit values. This is typically accomplished +:c:expr:`int` and :c:expr:`long` are 32-bit values. This is typically accomplished by defining the relevant size and offset types as 64-bit values. Such files are sometimes referred to as :dfn:`large files`. Large file support is enabled in Python when the size of an :c:type:`off_t` is -larger than a :c:type:`long` and the :c:type:`long long` is at least as large +larger than a :c:expr:`long` and the :c:expr:`long long` is at least as large as an :c:type:`off_t`. It may be necessary to configure and compile Python with certain compiler flags to enable this mode. For example, with Solaris 2.6 and 2.7 you need to do diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst index 3da5aa9389b..4e29192311f 100644 --- a/Doc/library/pprint.rst +++ b/Doc/library/pprint.rst @@ -171,17 +171,21 @@ The :mod:`pprint` module defines one class: .. function:: isrecursive(object) - Determine if *object* requires a recursive representation. + Determine if *object* requires a recursive representation. This function is + subject to the same limitations as noted in :func:`saferepr` below and may raise an + :exc:`RecursionError` if it fails to detect a recursive object. One more support function is also defined: .. function:: saferepr(object) - Return a string representation of *object*, protected against recursive data - structures. If the representation of *object* exposes a recursive entry, the - recursive reference will be represented as ````. The representation is not otherwise formatted. + Return a string representation of *object*, protected against recursion in + some common data structures, namely instances of :class:`dict`, :class:`list` + and :class:`tuple` or subclasses whose ``__repr__`` has not been overridden. If the + representation of object exposes a recursive entry, the recursive reference + will be represented as ````. The + representation is not otherwise formatted. >>> pprint.saferepr(stuff) "[, 'spam', 'eggs', 'lumberjack', 'knights', 'ni']" diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index cf324a57e79..c2189e02656 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -66,22 +66,23 @@ your system.) The above action would run :func:`re.compile` and print profile results like the following:: - 197 function calls (192 primitive calls) in 0.002 seconds + 214 function calls (207 primitive calls) in 0.002 seconds - Ordered by: standard name + Ordered by: cumulative time ncalls tottime percall cumtime percall filename:lineno(function) + 1 0.000 0.000 0.002 0.002 {built-in method builtins.exec} 1 0.000 0.000 0.001 0.001 :1() - 1 0.000 0.000 0.001 0.001 re.py:212(compile) - 1 0.000 0.000 0.001 0.001 re.py:268(_compile) - 1 0.000 0.000 0.000 0.000 sre_compile.py:172(_compile_charset) - 1 0.000 0.000 0.000 0.000 sre_compile.py:201(_optimize_charset) - 4 0.000 0.000 0.000 0.000 sre_compile.py:25(_identityfunction) - 3/1 0.000 0.000 0.000 0.000 sre_compile.py:33(_compile) + 1 0.000 0.000 0.001 0.001 __init__.py:250(compile) + 1 0.000 0.000 0.001 0.001 __init__.py:289(_compile) + 1 0.000 0.000 0.000 0.000 _compiler.py:759(compile) + 1 0.000 0.000 0.000 0.000 _parser.py:937(parse) + 1 0.000 0.000 0.000 0.000 _compiler.py:598(_code) + 1 0.000 0.000 0.000 0.000 _parser.py:435(_parse_sub) -The first line indicates that 197 calls were monitored. Of those calls, 192 +The first line indicates that 214 calls were monitored. Of those calls, 207 were :dfn:`primitive`, meaning that the call was not induced via recursion. The -next line: ``Ordered by: standard name``, indicates that the text string in the +next line: ``Ordered by: cumulative name``, indicates that the text string in the far right column was used to sort the output. The column headings include: ncalls @@ -273,7 +274,7 @@ functions: with cProfile.Profile() as pr: # ... do something ... - pr.print_stats() + pr.print_stats() .. versionchanged:: 3.8 Added context manager support. diff --git a/Doc/library/pwd.rst b/Doc/library/pwd.rst index 03ebb02e4e5..98f3c45e29c 100644 --- a/Doc/library/pwd.rst +++ b/Doc/library/pwd.rst @@ -10,6 +10,8 @@ This module provides access to the Unix user account and password database. It is available on all Unix versions. +.. include:: ../includes/wasm-notavail.rst + Password database entries are reported as a tuple-like object, whose attributes correspond to the members of the ``passwd`` structure (Attribute field below, see ````): diff --git a/Doc/library/py_compile.rst b/Doc/library/py_compile.rst index 4fba4cba4d3..69b93a3bdfc 100644 --- a/Doc/library/py_compile.rst +++ b/Doc/library/py_compile.rst @@ -35,8 +35,9 @@ byte-code cache files in the directory containing the source code. in ``.pyc``. For example, if *file* is ``/foo/bar/baz.py`` *cfile* will default to ``/foo/bar/__pycache__/baz.cpython-32.pyc`` for Python 3.2. If *dfile* is - specified, it is used as the name of the source file in error messages - instead of *file*. If *doraise* is true, a :exc:`PyCompileError` is raised + specified, it is used instead of *file* as the name of the source file from + which source lines are obtained for display in exception tracebacks. + If *doraise* is true, a :exc:`PyCompileError` is raised when an error is encountered while compiling *file*. If *doraise* is false (the default), an error string is written to ``sys.stderr``, but no exception is raised. This function returns the path to byte-compiled file, i.e. diff --git a/Doc/library/pydoc.rst b/Doc/library/pydoc.rst index 94daf4a58f9..03e0915bf6d 100644 --- a/Doc/library/pydoc.rst +++ b/Doc/library/pydoc.rst @@ -33,7 +33,7 @@ as text on the console. The same text documentation can also be viewed from outside the Python interpreter by running :program:`pydoc` as a script at the operating system's command prompt. For example, running :: - pydoc sys + python -m pydoc sys at a shell prompt will display documentation on the :mod:`sys` module, in a style similar to the manual pages shown by the Unix :program:`man` command. The @@ -65,18 +65,18 @@ manner similar to the Unix :program:`man` command. The synopsis line of a module is the first line of its documentation string. You can also use :program:`pydoc` to start an HTTP server on the local machine -that will serve documentation to visiting web browsers. :program:`pydoc -p 1234` +that will serve documentation to visiting web browsers. :program:`python -m pydoc -p 1234` will start a HTTP server on port 1234, allowing you to browse the documentation at ``http://localhost:1234/`` in your preferred web browser. Specifying ``0`` as the port number will select an arbitrary unused port. -:program:`pydoc -n ` will start the server listening at the given +:program:`python -m pydoc -n ` will start the server listening at the given hostname. By default the hostname is 'localhost' but if you want the server to be reached from other machines, you may want to change the host name that the server responds to. During development this is especially useful if you want to run pydoc from within a container. -:program:`pydoc -b` will start the server and additionally open a web +:program:`python -m pydoc -b` will start the server and additionally open a web browser to a module index page. Each served page has a navigation bar at the top where you can *Get* help on an individual item, *Search* all modules with a keyword in their synopsis line, and go to the *Module index*, *Topics* and diff --git a/Doc/library/pyexpat.rst b/Doc/library/pyexpat.rst index 034e579315d..d6581e21b01 100644 --- a/Doc/library/pyexpat.rst +++ b/Doc/library/pyexpat.rst @@ -867,6 +867,40 @@ The ``errors`` module has the following attributes: .. data:: XML_ERROR_SUSPEND_PE +.. data:: XML_ERROR_RESERVED_PREFIX_XML + + An attempt was made to + undeclare reserved namespace prefix ``xml`` + or to bind it to another namespace URI. + + +.. data:: XML_ERROR_RESERVED_PREFIX_XMLNS + + An attempt was made to declare or undeclare reserved namespace prefix ``xmlns``. + + +.. data:: XML_ERROR_RESERVED_NAMESPACE_URI + + An attempt was made to bind the URI of one the reserved namespace + prefixes ``xml`` and ``xmlns`` to another namespace prefix. + + +.. data:: XML_ERROR_INVALID_ARGUMENT + + This should not be reported to Python applications. + + +.. data:: XML_ERROR_NO_BUFFER + + This should not be reported to Python applications. + + +.. data:: XML_ERROR_AMPLIFICATION_LIMIT_BREACH + + The limit on input amplification factor (from DTD and entities) + has been breached. + + .. rubric:: Footnotes .. [1] The encoding string included in XML output should conform to the diff --git a/Doc/library/queue.rst b/Doc/library/queue.rst index 0ec5900bef5..c67f15e953b 100644 --- a/Doc/library/queue.rst +++ b/Doc/library/queue.rst @@ -138,7 +138,7 @@ provide the public methods described below. .. method:: Queue.put_nowait(item) - Equivalent to ``put(item, False)``. + Equivalent to ``put(item, block=False)``. .. method:: Queue.get(block=True, timeout=None) @@ -190,7 +190,8 @@ fully processed by daemon consumer threads. Example of how to wait for enqueued tasks to be completed:: - import threading, queue + import threading + import queue q = queue.Queue() @@ -201,15 +202,14 @@ Example of how to wait for enqueued tasks to be completed:: print(f'Finished {item}') q.task_done() - # turn-on the worker thread + # Turn-on the worker thread. threading.Thread(target=worker, daemon=True).start() - # send thirty task requests to the worker + # Send thirty task requests to the worker. for item in range(30): q.put(item) - print('All task requests sent\n', end='') - # block until all tasks are done + # Block until all tasks are done. q.join() print('All work completed') @@ -249,7 +249,7 @@ SimpleQueue Objects .. method:: SimpleQueue.put_nowait(item) - Equivalent to ``put(item)``, provided for compatibility with + Equivalent to ``put(item, block=False)``, provided for compatibility with :meth:`Queue.put_nowait`. diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 36f232dc319..4522f5a8d26 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -21,8 +21,8 @@ lognormal, negative exponential, gamma, and beta distributions. For generating distributions of angles, the von Mises distribution is available. Almost all module functions depend on the basic function :func:`.random`, which -generates a random float uniformly in the semi-open range [0.0, 1.0). Python -uses the Mersenne Twister as the core generator. It produces 53-bit precision +generates a random float uniformly in the half-open range ``0.0 <= X < 1.0``. +Python uses the Mersenne Twister as the core generator. It produces 53-bit precision floats and has a period of 2\*\*19937-1. The underlying implementation in C is both fast and threadsafe. The Mersenne Twister is one of the most extensively tested random number generators in existence. However, being completely @@ -123,19 +123,23 @@ Functions for integers .. function:: randrange(stop) randrange(start, stop[, step]) - Return a randomly selected element from ``range(start, stop, step)``. This is - equivalent to ``choice(range(start, stop, step))``, but doesn't actually build a - range object. + Return a randomly selected element from ``range(start, stop, step)``. - The positional argument pattern matches that of :func:`range`. Keyword arguments - should not be used because the function may use them in unexpected ways. + This is roughly equivalent to ``choice(range(start, stop, step))`` but + supports arbitrarily large ranges and is optimized for common cases. + + The positional argument pattern matches the :func:`range` function. + + Keyword arguments should not be used because they can be interpreted + in unexpected ways. For example ``randrange(start=100)`` is interpreted + as ``randrange(0, 100, 1)``. .. versionchanged:: 3.2 :meth:`randrange` is more sophisticated about producing equally distributed values. Formerly it used a style like ``int(random()*n)`` which could produce slightly uneven distributions. - .. versionchanged:: 3.11 + .. versionchanged:: 3.12 Automatic conversion of non-integer types is no longer supported. Calls such as ``randrange(10.0)`` and ``randrange(Fraction(10, 1))`` now raise a :exc:`TypeError`. @@ -148,7 +152,7 @@ Functions for integers .. function:: getrandbits(k) Returns a non-negative Python integer with *k* random bits. This method - is supplied with the MersenneTwister generator and some other generators + is supplied with the Mersenne Twister generator and some other generators may also provide it as an optional part of the API. When available, :meth:`getrandbits` enables :meth:`randrange` to handle arbitrarily large ranges. @@ -252,7 +256,29 @@ Functions for sequences .. versionchanged:: 3.11 The *population* must be a sequence. Automatic conversion of sets - to lists is longer supported. + to lists is no longer supported. + +Discrete distributions +---------------------- + +The following function generates a discrete distribution. + +.. function:: binomialvariate(n=1, p=0.5) + + `Binomial distribution + `_. + Return the number of successes for *n* independent trials with the + probability of success in each trial being *p*: + + Mathematically equivalent to:: + + sum(random() < p for i in range(n)) + + The number of trials *n* should be a non-negative integer. + The probability of success *p* should be between ``0.0 <= p <= 1.0``. + The result is an integer in the range ``0 <= X <= n``. + + .. versionadded:: 3.12 .. _real-valued-distributions: @@ -268,7 +294,7 @@ be found in any statistics text. .. function:: random() - Return the next random floating point number in the range [0.0, 1.0). + Return the next random floating point number in the range ``0.0 <= X < 1.0`` .. function:: uniform(a, b) @@ -294,7 +320,7 @@ be found in any statistics text. ``beta > 0``. Returned values range between 0 and 1. -.. function:: expovariate(lambd) +.. function:: expovariate(lambd = 1.0) Exponential distribution. *lambd* is 1.0 divided by the desired mean. It should be nonzero. (The parameter would be called @@ -302,6 +328,9 @@ be found in any statistics text. range from 0 to positive infinity if *lambd* is positive, and from negative infinity to 0 if *lambd* is negative. + .. versionchanged:: 3.12 + Added the default value for ``lambd``. + .. function:: gammavariate(alpha, beta) @@ -315,7 +344,7 @@ be found in any statistics text. math.gamma(alpha) * beta ** alpha -.. function:: gauss(mu, sigma) +.. function:: gauss(mu=0.0, sigma=1.0) Normal distribution, also called the Gaussian distribution. *mu* is the mean, and *sigma* is the standard deviation. This is slightly faster than @@ -328,6 +357,9 @@ be found in any statistics text. number generator. 2) Put locks around all calls. 3) Use the slower, but thread-safe :func:`normalvariate` function instead. + .. versionchanged:: 3.11 + *mu* and *sigma* now have default arguments. + .. function:: lognormvariate(mu, sigma) @@ -337,10 +369,13 @@ be found in any statistics text. zero. -.. function:: normalvariate(mu, sigma) +.. function:: normalvariate(mu=0.0, sigma=1.0) Normal distribution. *mu* is the mean, and *sigma* is the standard deviation. + .. versionchanged:: 3.11 + *mu* and *sigma* now have default arguments. + .. function:: vonmisesvariate(mu, kappa) @@ -442,16 +477,13 @@ Simulations:: >>> # Deal 20 cards without replacement from a deck >>> # of 52 playing cards, and determine the proportion of cards >>> # with a ten-value: ten, jack, queen, or king. - >>> dealt = sample(['tens', 'low cards'], counts=[16, 36], k=20) - >>> dealt.count('tens') / 20 + >>> deal = sample(['tens', 'low cards'], counts=[16, 36], k=20) + >>> deal.count('tens') / 20 0.15 >>> # Estimate the probability of getting 5 or more heads from 7 spins >>> # of a biased coin that settles on heads 60% of the time. - >>> def trial(): - ... return choices('HT', cum_weights=(0.60, 1.00), k=7).count('H') >= 5 - ... - >>> sum(trial() for i in range(10_000)) / 10_000 + >>> sum(binomialvariate(n=7, p=0.6) >= 5 for i in range(10_000)) / 10_000 0.4169 >>> # Probability of the median of 5 samples being in middle two quartiles @@ -465,7 +497,7 @@ Example of `statistical bootstrapping `_ using resampling with replacement to estimate a confidence interval for the mean of a sample:: - # http://statistics.about.com/od/Applications/a/Example-Of-Bootstrapping.htm + # https://www.thoughtco.com/example-of-bootstrapping-3126155 from statistics import fmean as mean from random import choices @@ -537,15 +569,15 @@ Simulation of arrival times and service deliveries for a multiserver queue:: including simulation, sampling, shuffling, and cross-validation. `Economics Simulation - `_ + `_ a simulation of a marketplace by - `Peter Norvig `_ that shows effective + `Peter Norvig `_ that shows effective use of many of the tools and distributions provided by this module (gauss, uniform, sample, betavariate, choice, triangular, and randrange). `A Concrete Introduction to Probability (using Python) - `_ - a tutorial by `Peter Norvig `_ covering + `_ + a tutorial by `Peter Norvig `_ covering the basics of probability theory, how to write simulations, and how to perform data analysis using Python. @@ -553,6 +585,37 @@ Simulation of arrival times and service deliveries for a multiserver queue:: Recipes ------- +These recipes show how to efficiently make random selections +from the combinatoric iterators in the :mod:`itertools` module: + +.. testcode:: + import random + + def random_product(*args, repeat=1): + "Random selection from itertools.product(*args, **kwds)" + pools = [tuple(pool) for pool in args] * repeat + return tuple(map(random.choice, pools)) + + def random_permutation(iterable, r=None): + "Random selection from itertools.permutations(iterable, r)" + pool = tuple(iterable) + r = len(pool) if r is None else r + return tuple(random.sample(pool, r)) + + def random_combination(iterable, r): + "Random selection from itertools.combinations(iterable, r)" + pool = tuple(iterable) + n = len(pool) + indices = sorted(random.sample(range(n), r)) + return tuple(pool[i] for i in indices) + + def random_combination_with_replacement(iterable, r): + "Random selection from itertools.combinations_with_replacement(iterable, r)" + pool = tuple(iterable) + n = len(pool) + indices = sorted(random.choices(range(n), k=r)) + return tuple(pool[i] for i in indices) + The default :func:`.random` returns multiples of 2â»âµÂ³ in the range *0.0 ≤ x < 1.0*. All such numbers are evenly spaced and are exactly representable as Python floats. However, many other representable diff --git a/Doc/library/re.rst b/Doc/library/re.rst index b12ce4b9744..d0a16b95184 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -7,7 +7,7 @@ .. moduleauthor:: Fredrik Lundh .. sectionauthor:: Andrew M. Kuchling -**Source code:** :source:`Lib/re.py` +**Source code:** :source:`Lib/re/` -------------- @@ -29,7 +29,7 @@ a literal backslash, one might have to write ``'\\\\'`` as the pattern string, because the regular expression must be ``\\``, and each backslash must be expressed as ``\\`` inside a regular Python string literal. Also, please note that any invalid escape sequences in Python's -usage of the backslash in string literals now generate a :exc:`DeprecationWarning` +usage of the backslash in string literals now generate a :exc:`SyntaxWarning` and in the future this will become a :exc:`SyntaxError`. This behaviour will happen even if it is a valid escape sequence for a regular expression. @@ -87,7 +87,7 @@ Some characters, like ``'|'`` or ``'('``, are special. Special characters either stand for classes of ordinary characters, or affect how the regular expressions around them are interpreted. -Repetition qualifiers (``*``, ``+``, ``?``, ``{m,n}``, etc) cannot be +Repetition operators or quantifiers (``*``, ``+``, ``?``, ``{m,n}``, etc) cannot be directly nested. This avoids ambiguity with the non-greedy modifier suffix ``?``, and with other modifiers in other implementations. To apply a second repetition to an inner repetition, parentheses may be used. For example, @@ -146,14 +146,38 @@ The special characters are: single: ??; in regular expressions ``*?``, ``+?``, ``??`` - The ``'*'``, ``'+'``, and ``'?'`` qualifiers are all :dfn:`greedy`; they match + The ``'*'``, ``'+'``, and ``'?'`` quantifiers are all :dfn:`greedy`; they match as much text as possible. Sometimes this behaviour isn't desired; if the RE ``<.*>`` is matched against ``' b '``, it will match the entire - string, and not just ``''``. Adding ``?`` after the qualifier makes it + string, and not just ``''``. Adding ``?`` after the quantifier makes it perform the match in :dfn:`non-greedy` or :dfn:`minimal` fashion; as *few* characters as possible will be matched. Using the RE ``<.*?>`` will match only ``''``. +.. index:: + single: *+; in regular expressions + single: ++; in regular expressions + single: ?+; in regular expressions + +``*+``, ``++``, ``?+`` + Like the ``'*'``, ``'+'``, and ``'?'`` quantifiers, those where ``'+'`` is + appended also match as many times as possible. + However, unlike the true greedy quantifiers, these do not allow + back-tracking when the expression following it fails to match. + These are known as :dfn:`possessive` quantifiers. + For example, ``a*a`` will match ``'aaaa'`` because the ``a*`` will match + all 4 ``'a'``\ s, but, when the final ``'a'`` is encountered, the + expression is backtracked so that in the end the ``a*`` ends up matching + 3 ``'a'``\ s total, and the fourth ``'a'`` is matched by the final ``'a'``. + However, when ``a*+a`` is used to match ``'aaaa'``, the ``a*+`` will + match all 4 ``'a'``, but when the final ``'a'`` fails to find any more + characters to match, the expression cannot be backtracked and will thus + fail to match. + ``x*+``, ``x++`` and ``x?+`` are equivalent to ``(?>x*)``, ``(?>x+)`` + and ``(?>x?)`` correspondingly. + + .. versionadded:: 3.11 + .. index:: single: {} (curly brackets); in regular expressions @@ -174,10 +198,25 @@ The special characters are: ``{m,n}?`` Causes the resulting RE to match from *m* to *n* repetitions of the preceding RE, attempting to match as *few* repetitions as possible. This is the - non-greedy version of the previous qualifier. For example, on the + non-greedy version of the previous quantifier. For example, on the 6-character string ``'aaaaaa'``, ``a{3,5}`` will match 5 ``'a'`` characters, while ``a{3,5}?`` will only match 3 characters. +``{m,n}+`` + Causes the resulting RE to match from *m* to *n* repetitions of the + preceding RE, attempting to match as many repetitions as possible + *without* establishing any backtracking points. + This is the possessive version of the quantifier above. + For example, on the 6-character string ``'aaaaaa'``, ``a{3,5}+aa`` + attempt to match 5 ``'a'`` characters, then, requiring 2 more ``'a'``\ s, + will need more characters than available and thus fail, while + ``a{3,5}aa`` will match with ``a{3,5}`` capturing 5, then 4 ``'a'``\ s + by backtracking and then the final 2 ``'a'``\ s are matched by the final + ``aa`` in the pattern. + ``x{m,n}+`` is equivalent to ``(?>x{m,n})``. + + .. versionadded:: 3.11 + .. index:: single: \ (backslash); in regular expressions ``\`` @@ -299,6 +338,9 @@ The special characters are: :func:`re.compile` function. Flags should be used first in the expression string. + .. versionchanged:: 3.11 + This construction can only be used at the start of the expression. + .. index:: single: (?:; in regular expressions ``(?:...)`` @@ -333,13 +375,29 @@ The special characters are: .. versionchanged:: 3.7 The letters ``'a'``, ``'L'`` and ``'u'`` also can be used in a group. +``(?>...)`` + Attempts to match ``...`` as if it was a separate regular expression, and + if successful, continues to match the rest of the pattern following it. + If the subsequent pattern fails to match, the stack can only be unwound + to a point *before* the ``(?>...)`` because once exited, the expression, + known as an :dfn:`atomic group`, has thrown away all stack points within + itself. + Thus, ``(?>.*).`` would never match anything because first the ``.*`` + would match all characters possible, then, having nothing left to match, + the final ``.`` would fail to match. + Since there are no stack points saved in the Atomic Group, and there is + no stack point before it, the entire expression would thus fail to match. + + .. versionadded:: 3.11 + .. index:: single: (?P<; in regular expressions ``(?P...)`` Similar to regular parentheses, but the substring matched by the group is accessible via the symbolic group name *name*. Group names must be valid - Python identifiers, and each group name must be defined only once within a - regular expression. A symbolic group is also a numbered group, just as if + Python identifiers, and in :class:`bytes` patterns they can only contain + bytes in the ASCII range. Each group name must be defined only once within + a regular expression. A symbolic group is also a numbered group, just as if the group were not named. Named groups can be referenced in three contexts. If the pattern is @@ -360,6 +418,10 @@ The special characters are: | | * ``\1`` | +---------------------------------------+----------------------------------+ + .. versionchanged:: 3.12 + In :class:`bytes` patterns, group *name* can only contain bytes + in the ASCII range (``b'\x00'``-``b'\x7f'``). + .. index:: single: (?P=; in regular expressions ``(?P=name)`` @@ -421,6 +483,9 @@ The special characters are: some fixed length. Patterns which start with negative lookbehind assertions may match at the beginning of the string being searched. +.. _re-conditional-expression: +.. index:: single: (?(; in regular expressions + ``(?(id/name)yes-pattern|no-pattern)`` Will try to match with ``yes-pattern`` if the group with given *id* or *name* exists, and with ``no-pattern`` if it doesn't. ``no-pattern`` is @@ -429,6 +494,11 @@ The special characters are: will match with ``''`` as well as ``'user@host.com'``, but not with ``''``. + .. versionchanged:: 3.12 + Group *id* can only contain ASCII digits. + In :class:`bytes` patterns, group *name* can only contain bytes + in the ASCII range (``b'\x00'``-``b'\x7f'``). + The special sequences consist of ``'\'`` and a character from the list below. If the ordinary character is not an ASCII digit or an ASCII letter, then the @@ -523,10 +593,9 @@ character ``'$'``. ``\w`` For Unicode (str) patterns: - Matches Unicode word characters; this includes most characters - that can be part of a word in any language, as well as numbers and - the underscore. If the :const:`ASCII` flag is used, only - ``[a-zA-Z0-9_]`` is matched. + Matches Unicode word characters; this includes alphanumeric characters (as defined by :meth:`str.isalnum`) + as well as the underscore (``_``). + If the :const:`ASCII` flag is used, only ``[a-zA-Z0-9_]`` is matched. For 8-bit (bytes) patterns: Matches characters considered alphanumeric in the ASCII character set; @@ -602,41 +671,20 @@ functions are simplified versions of the full featured methods for compiled regular expressions. Most non-trivial applications always use the compiled form. + +Flags +^^^^^ + .. versionchanged:: 3.6 Flag constants are now instances of :class:`RegexFlag`, which is a subclass of :class:`enum.IntFlag`. -.. function:: compile(pattern, flags=0) - Compile a regular expression pattern into a :ref:`regular expression object - `, which can be used for matching using its - :func:`~Pattern.match`, :func:`~Pattern.search` and other methods, described - below. +.. class:: RegexFlag - The expression's behaviour can be modified by specifying a *flags* value. - Values can be any of the following variables, combined using bitwise OR (the - ``|`` operator). - - The sequence :: - - prog = re.compile(pattern) - result = prog.match(string) - - is equivalent to :: - - result = re.match(pattern, string) - - but using :func:`re.compile` and saving the resulting regular expression - object for reuse is more efficient when the expression will be used several - times in a single program. - - .. note:: - - The compiled versions of the most recent patterns passed to - :func:`re.compile` and the module-level matching functions are cached, so - programs that use only a few regular expressions at a time needn't worry - about compiling regular expressions. + An :class:`enum.IntFlag` class containing the regex options listed below. + .. versionadded:: 3.11 - added to ``__all__`` .. data:: A ASCII @@ -710,6 +758,17 @@ form. string and immediately before the newline (if any) at the end of the string. Corresponds to the inline flag ``(?m)``. +.. data:: NOFLAG + + Indicates no flag being applied, the value is ``0``. This flag may be used + as a default value for a function keyword argument or as a base value that + will be conditionally ORed with other flags. Example of use as a default + value:: + + def myfunc(text, flag=re.NOFLAG): + return re.match(text, flag) + + .. versionadded:: 3.11 .. data:: S DOTALL @@ -728,7 +787,8 @@ form. more readable by allowing you to visually separate logical sections of the pattern and add comments. Whitespace within the pattern is ignored, except when in a character class, or when preceded by an unescaped backslash, - or within tokens like ``*?``, ``(?:`` or ``(?P<...>``. + or within tokens like ``*?``, ``(?:`` or ``(?P<...>``. For example, ``(? :`` + and ``* ?`` are not allowed. When a line contains a ``#`` that is not in a character class and is not preceded by an unescaped backslash, all characters from the leftmost such ``#`` through the end of the line are ignored. @@ -744,6 +804,41 @@ form. Corresponds to the inline flag ``(?x)``. +Functions +^^^^^^^^^ + +.. function:: compile(pattern, flags=0) + + Compile a regular expression pattern into a :ref:`regular expression object + `, which can be used for matching using its + :func:`~Pattern.match`, :func:`~Pattern.search` and other methods, described + below. + + The expression's behaviour can be modified by specifying a *flags* value. + Values can be any of the following variables, combined using bitwise OR (the + ``|`` operator). + + The sequence :: + + prog = re.compile(pattern) + result = prog.match(string) + + is equivalent to :: + + result = re.match(pattern, string) + + but using :func:`re.compile` and saving the resulting regular expression + object for reuse is more efficient when the expression will be used several + times in a single program. + + .. note:: + + The compiled versions of the most recent patterns passed to + :func:`re.compile` and the module-level matching functions are cached, so + programs that use only a few regular expressions at a time needn't worry + about compiling regular expressions. + + .. function:: search(pattern, string, flags=0) Scan through *string* looking for the first location where the regular expression @@ -879,6 +974,7 @@ form. >>> def dashrepl(matchobj): ... if matchobj.group(0) == '-': return ' ' ... else: return '-' + ... >>> re.sub('-{1,2}', dashrepl, 'pro----gram-files') 'pro--gram files' >>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE) @@ -922,6 +1018,11 @@ form. Empty matches for the pattern are replaced when adjacent to a previous non-empty match. + .. versionchanged:: 3.12 + Group *id* can only contain ASCII digits. + In :class:`bytes` replacement strings, group *name* can only contain bytes + in the ASCII range (``b'\x00'``-``b'\x7f'``). + .. function:: subn(pattern, repl, string, count=0, flags=0) @@ -975,6 +1076,9 @@ form. Clear the regular expression cache. +Exceptions +^^^^^^^^^^ + .. exception:: error(msg, pattern=None, pos=None) Exception raised when a string passed to one of the functions here is not a @@ -1229,6 +1333,14 @@ Match objects support the following methods and attributes: >>> m[2] # The second parenthesized subgroup. 'Newton' + Named groups are supported as well:: + + >>> m = re.match(r"(?P\w+) (?P\w+)", "Isaac Newton") + >>> m['first_name'] + 'Isaac' + >>> m['last_name'] + 'Newton' + .. versionadded:: 3.6 @@ -1455,16 +1567,22 @@ search() vs. match() .. sectionauthor:: Fred L. Drake, Jr. -Python offers two different primitive operations based on regular expressions: -:func:`re.match` checks for a match only at the beginning of the string, while -:func:`re.search` checks for a match anywhere in the string (this is what Perl -does by default). +Python offers different primitive operations based on regular expressions: + ++ :func:`re.match` checks for a match only at the beginning of the string ++ :func:`re.search` checks for a match anywhere in the string + (this is what Perl does by default) ++ :func:`re.fullmatch` checks for entire string to be a match + For example:: >>> re.match("c", "abcdef") # No match >>> re.search("c", "abcdef") # Match + >>> re.fullmatch("p.*n", "python") # Match + + >>> re.fullmatch("r.*n", "python") # No match Regular expressions beginning with ``'^'`` can be used with :func:`search` to restrict the match at the beginning of the string:: @@ -1478,8 +1596,8 @@ Note however that in :const:`MULTILINE` mode :func:`match` only matches at the beginning of the string, whereas using :func:`search` with a regular expression beginning with ``'^'`` will match at the beginning of each line. :: - >>> re.match('X', 'A\nB\nX', re.MULTILINE) # No match - >>> re.search('^X', 'A\nB\nX', re.MULTILINE) # Match + >>> re.match("X", "A\nB\nX", re.MULTILINE) # No match + >>> re.search("^X", "A\nB\nX", re.MULTILINE) # Match @@ -1556,6 +1674,7 @@ in each word of a sentence except for the first and last characters:: ... inner_word = list(m.group(2)) ... random.shuffle(inner_word) ... return m.group(1) + "".join(inner_word) + m.group(3) + ... >>> text = "Professor Abdolmalek, please report your absences promptly." >>> re.sub(r"(\w)(\w+)(\w)", repl, text) 'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.' diff --git a/Doc/library/reprlib.rst b/Doc/library/reprlib.rst index 4b37c5ba60f..5ebb0a7780c 100644 --- a/Doc/library/reprlib.rst +++ b/Doc/library/reprlib.rst @@ -17,12 +17,31 @@ debugger and may be useful in other contexts as well. This module provides a class, an instance, and a function: -.. class:: Repr() +.. class:: Repr(*, maxlevel=6, maxtuple=6, maxlist=6, maxarray=5, maxdict=4, \ + maxset=6, maxfrozenset=6, maxdeque=6, maxstring=30, maxlong=40, \ + maxother=30, fillvalue="...", indent=None) Class which provides formatting services useful in implementing functions similar to the built-in :func:`repr`; size limits for different object types are added to avoid the generation of representations which are excessively long. + The keyword arguments of the constructor can be used as a shortcut to set the + attributes of the :class:`Repr` instance. Which means that the following + initialization:: + + aRepr = reprlib.Repr(maxlevel=3) + + Is equivalent to:: + + aRepr = reprlib.Repr() + aRepr.maxlevel = 3 + + See section `Repr Objects`_ for more information about :class:`Repr` + attributes. + + .. versionchanged:: 3.12 + Allow attributes to be set via keyword arguments. + .. data:: aRepr @@ -123,6 +142,66 @@ which format specific object types. similar manner as :attr:`maxstring`. The default is ``20``. +.. attribute:: Repr.indent + + If this attribute is set to ``None`` (the default), the output is formatted + with no line breaks or indentation, like the standard :func:`repr`. + For example: + + .. code-block:: pycon + + >>> example = [ + 1, 'spam', {'a': 2, 'b': 'spam eggs', 'c': {3: 4.5, 6: []}}, 'ham'] + >>> import reprlib + >>> aRepr = reprlib.Repr() + >>> print(aRepr.repr(example)) + [1, 'spam', {'a': 2, 'b': 'spam eggs', 'c': {3: 4.5, 6: []}}, 'ham'] + + If :attr:`~Repr.indent` is set to a string, each recursion level + is placed on its own line, indented by that string: + + .. code-block:: pycon + + >>> aRepr.indent = '-->' + >>> print(aRepr.repr(example)) + [ + -->1, + -->'spam', + -->{ + -->-->'a': 2, + -->-->'b': 'spam eggs', + -->-->'c': { + -->-->-->3: 4.5, + -->-->-->6: [], + -->-->}, + -->}, + -->'ham', + ] + + Setting :attr:`~Repr.indent` to a positive integer value behaves as if it + was set to a string with that number of spaces: + + .. code-block:: pycon + + >>> aRepr.indent = 4 + >>> print(aRepr.repr(example)) + [ + 1, + 'spam', + { + 'a': 2, + 'b': 'spam eggs', + 'c': { + 3: 4.5, + 6: [], + }, + }, + 'ham', + ] + + .. versionadded:: 3.12 + + .. method:: Repr.repr(obj) The equivalent to the built-in :func:`repr` that uses the formatting imposed by diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index 67e9b44fe48..e7bf45d7d56 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -13,6 +13,8 @@ This module provides basic mechanisms for measuring and controlling system resources utilized by a program. +.. include:: ../includes/wasm-notavail.rst + Symbolic constants are used to specify particular system resources and to request usage information about either the current process or its children. @@ -99,7 +101,7 @@ this module for those platforms. .. audit-event:: resource.prlimit pid,resource,limits resource.prlimit - .. availability:: Linux 2.6.36 or later with glibc 2.13 or later. + .. availability:: Linux >= 2.6.36 with glibc >= 2.13. .. versionadded:: 3.4 @@ -185,7 +187,7 @@ platform. The number of bytes that can be allocated for POSIX message queues. - .. availability:: Linux 2.6.8 or later. + .. availability:: Linux >= 2.6.8. .. versionadded:: 3.4 @@ -194,7 +196,7 @@ platform. The ceiling for the process's nice level (calculated as 20 - rlim_cur). - .. availability:: Linux 2.6.12 or later. + .. availability:: Linux >= 2.6.12. .. versionadded:: 3.4 @@ -203,7 +205,7 @@ platform. The ceiling of the real-time priority. - .. availability:: Linux 2.6.12 or later. + .. availability:: Linux >= 2.6.12. .. versionadded:: 3.4 @@ -213,7 +215,7 @@ platform. The time limit (in microseconds) on CPU time that a process can spend under real-time scheduling without making a blocking syscall. - .. availability:: Linux 2.6.25 or later. + .. availability:: Linux >= 2.6.25. .. versionadded:: 3.4 @@ -222,7 +224,7 @@ platform. The number of signals which the process may queue. - .. availability:: Linux 2.6.8 or later. + .. availability:: Linux >= 2.6.8. .. versionadded:: 3.4 @@ -232,7 +234,7 @@ platform. This limits the amount of network memory, and hence the amount of mbufs, that this user may hold at any time. - .. availability:: FreeBSD 9 or later. + .. availability:: FreeBSD. .. versionadded:: 3.4 @@ -245,7 +247,7 @@ platform. `tuning(7) `__ for a complete description of this sysctl. - .. availability:: FreeBSD 9 or later. + .. availability:: FreeBSD. .. versionadded:: 3.4 @@ -253,7 +255,7 @@ platform. The maximum number of pseudo-terminals created by this user id. - .. availability:: FreeBSD 9 or later. + .. availability:: FreeBSD. .. versionadded:: 3.4 @@ -261,7 +263,7 @@ platform. The maximum number of kqueues this user id is allowed to create. - .. availability:: FreeBSD 11 or later. + .. availability:: FreeBSD >= 11. .. versionadded:: 3.10 diff --git a/Doc/library/runpy.rst b/Doc/library/runpy.rst index af35e81a2d4..501f4ddf5a3 100644 --- a/Doc/library/runpy.rst +++ b/Doc/library/runpy.rst @@ -93,7 +93,12 @@ The :mod:`runpy` module provides two functions: run this way, as well as ensuring the real module name is always accessible as ``__spec__.name``. -.. function:: run_path(file_path, init_globals=None, run_name=None) + .. versionchanged:: 3.12 + The setting of ``__cached__``, ``__loader__``, and + ``__package__`` are deprecated. See + :class:`~importlib.machinery.ModuleSpec` for alternatives. + +.. function:: run_path(path_name, init_globals=None, run_name=None) .. index:: module: __main__ @@ -140,7 +145,7 @@ The :mod:`runpy` module provides two functions: A number of alterations are also made to the :mod:`sys` module. Firstly, ``sys.path`` may be altered as described above. ``sys.argv[0]`` is updated - with the value of ``file_path`` and ``sys.modules[__name__]`` is updated + with the value of ``path_name`` and ``sys.modules[__name__]`` is updated with a temporary module object for the module being executed. All modifications to items in :mod:`sys` are reverted before the function returns. @@ -163,6 +168,10 @@ The :mod:`runpy` module provides two functions: case where ``__main__`` is imported from a valid sys.path entry rather than being executed directly. + .. versionchanged:: 3.12 + The setting of ``__cached__``, ``__loader__``, and + ``__package__`` are deprecated. + .. seealso:: :pep:`338` -- Executing modules as scripts diff --git a/Doc/library/sched.rst b/Doc/library/sched.rst index a4ba2848f11..a051c65b97b 100644 --- a/Doc/library/sched.rst +++ b/Doc/library/sched.rst @@ -44,16 +44,22 @@ Example:: ... print(time.time()) ... s.enter(10, 1, print_time) ... s.enter(5, 2, print_time, argument=('positional',)) + ... # despite having higher priority, 'keyword' runs after 'positional' as enter() is relative ... s.enter(5, 1, print_time, kwargs={'a': 'keyword'}) + ... s.enterabs(1_650_000_000, 10, print_time, argument=("first enterabs",)) + ... s.enterabs(1_650_000_000, 5, print_time, argument=("second enterabs",)) ... s.run() ... print(time.time()) ... >>> print_some_times() - 930343690.257 - From print_time 930343695.274 positional - From print_time 930343695.275 keyword - From print_time 930343700.273 default - 930343700.276 + 1652342830.3640375 + From print_time 1652342830.3642538 second enterabs + From print_time 1652342830.3643398 first enterabs + From print_time 1652342835.3694863 positional + From print_time 1652342835.3696074 keyword + From print_time 1652342840.369612 default + 1652342840.3697174 + .. _scheduler-objects: diff --git a/Doc/library/secrets.rst b/Doc/library/secrets.rst index afa8e2d385f..4405dfc0535 100644 --- a/Doc/library/secrets.rst +++ b/Doc/library/secrets.rst @@ -44,7 +44,7 @@ randomness that your operating system provides. .. function:: choice(sequence) - Return a randomly-chosen element from a non-empty sequence. + Return a randomly chosen element from a non-empty sequence. .. function:: randbelow(n) @@ -128,8 +128,10 @@ Other functions .. function:: compare_digest(a, b) - Return ``True`` if strings *a* and *b* are equal, otherwise ``False``, - in such a way as to reduce the risk of + Return ``True`` if strings or + :term:`bytes-like objects ` + *a* and *b* are equal, otherwise ``False``, + using a "constant-time compare" to reduce the risk of `timing attacks `_. See :func:`hmac.compare_digest` for additional details. @@ -153,9 +155,9 @@ Generate an eight-character alphanumeric password: .. note:: Applications should not - `store passwords in a recoverable format `_, + `store passwords in a recoverable format `_, whether plain text or encrypted. They should be salted and hashed - using a cryptographically-strong one-way (irreversible) hash function. + using a cryptographically strong one-way (irreversible) hash function. Generate a ten-character alphanumeric password with at least one @@ -193,7 +195,7 @@ suitable for password recovery applications: .. testcode:: import secrets - url = 'https://mydomain.com/reset=' + secrets.token_urlsafe() + url = 'https://example.com/reset=' + secrets.token_urlsafe() diff --git a/Doc/library/security_warnings.rst b/Doc/library/security_warnings.rst index 26b015c0f8f..284f3658320 100644 --- a/Doc/library/security_warnings.rst +++ b/Doc/library/security_warnings.rst @@ -14,7 +14,7 @@ The following modules have specific security considerations: argument disabling known insecure and blocked algorithms ` * :mod:`http.server` is not suitable for production use, only implementing - basic security checks + basic security checks. See the :ref:`security considerations `. * :mod:`logging`: :ref:`Logging configuration uses eval() ` * :mod:`multiprocessing`: :ref:`Connection.recv() uses pickle @@ -32,3 +32,9 @@ The following modules have specific security considerations: * :mod:`xml`: :ref:`XML vulnerabilities ` * :mod:`zipfile`: :ref:`maliciously prepared .zip files can cause disk volume exhaustion ` + +The :option:`-I` command line option can be used to run Python in isolated +mode. When it cannot be used, the :option:`-P` option or the +:envvar:`PYTHONSAFEPATH` environment variable can be used to not prepend a +potentially unsafe path to :data:`sys.path` such as the current directory, the +script's directory or an empty string. diff --git a/Doc/library/select.rst b/Doc/library/select.rst index 46b5ff8b6d5..2890706bab7 100644 --- a/Doc/library/select.rst +++ b/Doc/library/select.rst @@ -22,6 +22,7 @@ it was last read. encouraged to use the :mod:`selectors` module instead, unless they want precise control over the OS-level primitives used. +.. include:: ../includes/wasm-notavail.rst The module defines the following: @@ -60,7 +61,7 @@ The module defines the following: events. *sizehint* informs epoll about the expected number of events to be - registered. It must be positive, or `-1` to use the default. It is only + registered. It must be positive, or ``-1`` to use the default. It is only used on older systems where :c:func:`epoll_create1` is not available; otherwise it has no effect (though its value is still checked). @@ -252,7 +253,7 @@ object. .. method:: devpoll.poll([timeout]) - Polls the set of registered file descriptors, and returns a possibly-empty list + Polls the set of registered file descriptors, and returns a possibly empty list containing ``(fd, event)`` 2-tuples for the descriptors that have events or errors to report. *fd* is the file descriptor, and *event* is a bitmask with bits set for the reported events for that descriptor --- :const:`POLLIN` for @@ -440,7 +441,7 @@ linearly scanned again. :c:func:`select` is O(highest file descriptor), while .. method:: poll.poll([timeout]) - Polls the set of registered file descriptors, and returns a possibly-empty list + Polls the set of registered file descriptors, and returns a possibly empty list containing ``(fd, event)`` 2-tuples for the descriptors that have events or errors to report. *fd* is the file descriptor, and *event* is a bitmask with bits set for the reported events for that descriptor --- :const:`POLLIN` for diff --git a/Doc/library/selectors.rst b/Doc/library/selectors.rst index 6d864a836de..0deb15cf4c5 100644 --- a/Doc/library/selectors.rst +++ b/Doc/library/selectors.rst @@ -38,6 +38,7 @@ users. :mod:`select` Low-level I/O multiplexing module. +.. include:: ../includes/wasm-notavail.rst Classes ------- diff --git a/Doc/library/shlex.rst b/Doc/library/shlex.rst index aab6a543792..0bad51833aa 100644 --- a/Doc/library/shlex.rst +++ b/Doc/library/shlex.rst @@ -36,9 +36,9 @@ The :mod:`shlex` module defines the following functions: instance, passing ``None`` for *s* will read the string to split from standard input. - .. deprecated:: 3.9 - Passing ``None`` for *s* will raise an exception in future Python - versions. + .. versionchanged:: 3.12 + Passing ``None`` for *s* argument now raises an exception, rather than + reading :data:`sys.stdin`. .. function:: join(split_command) diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 22d6dba9e1a..b33dbe21b1f 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -160,7 +160,8 @@ Directory and files operations Copies the file *src* to the file or directory *dst*. *src* and *dst* should be :term:`path-like objects ` or strings. If *dst* specifies a directory, the file will be copied into *dst* using the - base filename from *src*. Returns the path to the newly created file. + base filename from *src*. If *dst* specifies a file that already exists, + it will be replaced. Returns the path to the newly created file. If *follow_symlinks* is false, and *src* is a symbolic link, *dst* will be created as a symbolic link. If *follow_symlinks* @@ -193,7 +194,7 @@ Directory and files operations When *follow_symlinks* is false, and *src* is a symbolic link, :func:`copy2` attempts to copy all metadata from the - *src* symbolic link to the newly-created *dst* symbolic link. + *src* symbolic link to the newly created *dst* symbolic link. However, this functionality is not available on all platforms. On platforms where some or all of this functionality is unavailable, :func:`copy2` will preserve all the metadata @@ -230,9 +231,8 @@ Directory and files operations dirs_exist_ok=False) Recursively copy an entire directory tree rooted at *src* to a directory - named *dst* and return the destination directory. *dirs_exist_ok* dictates - whether to raise an exception in case *dst* or any missing parent directory - already exists. + named *dst* and return the destination directory. All intermediate + directories needed to contain *dst* will also be created by default. Permissions and times of directories are copied with :func:`copystat`, individual files are copied using :func:`~shutil.copy2`. @@ -263,8 +263,14 @@ Directory and files operations If *copy_function* is given, it must be a callable that will be used to copy each file. It will be called with the source path and the destination path -   as arguments. By default, :func:`~shutil.copy2` is used, but any function -   that supports the same signature (like :func:`~shutil.copy`) can be used. + as arguments. By default, :func:`~shutil.copy2` is used, but any function + that supports the same signature (like :func:`~shutil.copy`) can be used. + + If *dirs_exist_ok* is false (the default) and *dst* already exists, a + :exc:`FileExistsError` is raised. If *dirs_exist_ok* is true, the copying + operation will continue if it encounters existing directories, and files + within the *dst* tree will be overwritten by corresponding files from the + *src* tree. .. audit-event:: shutil.copytree src,dst shutil.copytree @@ -275,7 +281,7 @@ Directory and files operations .. versionchanged:: 3.2 Added the *copy_function* argument to be able to provide a custom copy function. - Added the *ignore_dangling_symlinks* argument to silent dangling symlinks + Added the *ignore_dangling_symlinks* argument to silence dangling symlinks errors when *symlinks* is false. .. versionchanged:: 3.8 @@ -286,7 +292,7 @@ Directory and files operations .. versionadded:: 3.8 The *dirs_exist_ok* parameter. -.. function:: rmtree(path, ignore_errors=False, onerror=None) +.. function:: rmtree(path, ignore_errors=False, onerror=None, *, dir_fd=None) .. index:: single: directory; deleting @@ -296,6 +302,9 @@ Directory and files operations handled by calling a handler specified by *onerror* or, if that is omitted, they raise an exception. + This function can support :ref:`paths relative to directory descriptors + `. + .. note:: On platforms that support the necessary fd-based functions a symlink @@ -315,7 +324,7 @@ Directory and files operations *excinfo*, will be the exception information returned by :func:`sys.exc_info`. Exceptions raised by *onerror* will not be caught. - .. audit-event:: shutil.rmtree path shutil.rmtree + .. audit-event:: shutil.rmtree path,dir_fd shutil.rmtree .. versionchanged:: 3.3 Added a symlink attack resistant version that is used automatically @@ -325,6 +334,9 @@ Directory and files operations On Windows, will no longer delete the contents of a directory junction before removing the junction. + .. versionchanged:: 3.11 + The *dir_fd* parameter. + .. attribute:: rmtree.avoids_symlink_attacks Indicates whether the current platform and implementation provides a @@ -470,42 +482,7 @@ file then shutil will silently fallback on using less efficient copytree example ~~~~~~~~~~~~~~~~ -This example is the implementation of the :func:`copytree` function, described -above, with the docstring omitted. It demonstrates many of the other functions -provided by this module. :: - - def copytree(src, dst, symlinks=False): - names = os.listdir(src) - os.makedirs(dst) - errors = [] - for name in names: - srcname = os.path.join(src, name) - dstname = os.path.join(dst, name) - try: - if symlinks and os.path.islink(srcname): - linkto = os.readlink(srcname) - os.symlink(linkto, dstname) - elif os.path.isdir(srcname): - copytree(srcname, dstname, symlinks) - else: - copy2(srcname, dstname) - # XXX What about devices, sockets etc.? - except OSError as why: - errors.append((srcname, dstname, str(why))) - # catch the Error from the recursive copytree so that we can - # continue with other files - except Error as err: - errors.extend(err.args[0]) - try: - copystat(src, dst) - except OSError as why: - # can't copy file access times on Windows - if why.winerror is None: - errors.extend((src, dst, str(why))) - if errors: - raise Error(errors) - -Another example that uses the :func:`ignore_patterns` helper:: +An example that uses the :func:`ignore_patterns` helper:: from shutil import copytree, ignore_patterns @@ -597,12 +574,19 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. .. note:: - This function is not thread-safe. + This function is not thread-safe when custom archivers registered + with :func:`register_archive_format` do not support the *root_dir* + argument. In this case it + temporarily changes the current working directory of the process + to *root_dir* to perform archiving. .. versionchanged:: 3.8 The modern pax (POSIX.1-2001) format is now used instead of the legacy GNU format for archives created with ``format="tar"``. + .. versionchanged:: 3.10.6 + This function is now made thread-safe during creation of standard + ``.zip`` and tar archives. .. function:: get_archive_formats() @@ -631,12 +615,21 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. Further arguments are passed as keyword arguments: *owner*, *group*, *dry_run* and *logger* (as passed in :func:`make_archive`). + If *function* has the custom attribute ``function.supports_root_dir`` set to ``True``, + the *root_dir* argument is passed as a keyword argument. + Otherwise the current working directory of the process is temporarily + changed to *root_dir* before calling *function*. + In this case :func:`make_archive` is not thread-safe. + If given, *extra_args* is a sequence of ``(name, value)`` pairs that will be used as extra keywords arguments when the archiver callable is used. *description* is used by :func:`get_archive_formats` which returns the list of archivers. Defaults to an empty string. + .. versionchanged:: 3.12 + Added support for functions supporting the *root_dir* argument. + .. function:: unregister_archive_format(name) @@ -659,10 +652,16 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. .. audit-event:: shutil.unpack_archive filename,extract_dir,format shutil.unpack_archive + .. warning:: + + Never extract archives from untrusted sources without prior inspection. + It is possible that files are created outside of the path specified in + the *extract_dir* argument, e.g. members that have absolute filenames + starting with "/" or filenames with two dots "..". + .. versionchanged:: 3.7 Accepts a :term:`path-like object` for *filename* and *extract_dir*. - .. function:: register_unpack_format(name, extensions, function[, extra_args[, description]]) Registers an unpack format. *name* is the name of the format and @@ -812,4 +811,4 @@ Querying the size of the output terminal http://www.manpagez.com/man/3/copyfile/ .. _`Other Environment Variables`: - http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003 + https://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003 diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 63821866a01..523d1ac5001 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -4,6 +4,8 @@ .. module:: signal :synopsis: Set handlers for asynchronous events. +**Source code:** :source:`Lib/signal.py` + -------------- This module provides mechanisms to use signal handlers in Python. @@ -24,6 +26,9 @@ explicitly reset (Python emulates the BSD style interface regardless of the underlying implementation), with the exception of the handler for :const:`SIGCHLD`, which follows the underlying implementation. +On WebAssembly platforms ``wasm32-emscripten`` and ``wasm32-wasi``, signals +are emulated and therefore behave differently. Several functions and signals +are not available on these platforms. Execution of Python signal handlers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -46,6 +51,9 @@ This has consequences: arbitrary amount of time, regardless of any signals received. The Python signal handlers will be called when the calculation finishes. +* If the handler raises an exception, it will be raised "out of thin air" in + the main thread. See the :ref:`note below ` for a + discussion. .. _signals-and-threads: @@ -92,8 +100,10 @@ The signal module defines three enums: :class:`enum.IntEnum` collection the constants :const:`SIG_BLOCK`, :const:`SIG_UNBLOCK` and :const:`SIG_SETMASK`. - Availability: Unix. See the man page :manpage:`sigprocmask(3)` and - :manpage:`pthread_sigmask(3)` for further information. + .. availability:: Unix. + + See the man page :manpage:`sigprocmask(2)` and + :manpage:`pthread_sigmask(3)` for further information. .. versionadded:: 3.5 @@ -197,6 +207,18 @@ The variables defined in the :mod:`signal` module are: Segmentation fault: invalid memory reference. +.. data:: SIGSTKFLT + + Stack fault on coprocessor. The Linux kernel does not raise this signal: it + can only be raised in user space. + + .. availability:: Linux. + + On architectures where the signal is available. See + the man page :manpage:`signal(7)` for further information. + + .. versionadded:: 3.11 + .. data:: SIGTERM Termination signal. @@ -253,6 +275,7 @@ The variables defined in the :mod:`signal` module are: .. data:: NSIG One more than the number of the highest signal number. + Use :func:`valid_signals` to get valid signal numbers. .. data:: ITIMER_REAL @@ -323,8 +346,9 @@ The :mod:`signal` module defines the following functions: delivered. If *time* is zero, no alarm is scheduled, and any scheduled alarm is canceled. If the return value is zero, no alarm is currently scheduled. - .. availability:: Unix. See the man page :manpage:`alarm(2)` for further - information. + .. availability:: Unix. + + See the man page :manpage:`alarm(2)` for further information. .. function:: getsignal(signalnum) @@ -340,9 +364,9 @@ The :mod:`signal` module defines the following functions: .. function:: strsignal(signalnum) - Return the system description of the signal *signalnum*, such as - "Interrupt", "Segmentation fault", etc. Returns :const:`None` if the signal - is not recognized. + Returns the description of signal *signalnum*, such as "Interrupt" + for :const:`SIGINT`. Returns :const:`None` if *signalnum* has no + description. Raises :exc:`ValueError` if *signalnum* is invalid. .. versionadded:: 3.8 @@ -361,8 +385,9 @@ The :mod:`signal` module defines the following functions: Cause the process to sleep until a signal is received; the appropriate handler will then be called. Returns nothing. - .. availability:: Unix. See the man page :manpage:`signal(2)` for further - information. + .. availability:: Unix. + + See the man page :manpage:`signal(2)` for further information. See also :func:`sigwait`, :func:`sigwaitinfo`, :func:`sigtimedwait` and :func:`sigpending`. @@ -384,7 +409,7 @@ The :mod:`signal` module defines the following functions: See the :manpage:`pidfd_send_signal(2)` man page for more information. - .. availability:: Linux 5.1+ + .. availability:: Linux >= 5.1 .. versionadded:: 3.9 @@ -407,8 +432,9 @@ The :mod:`signal` module defines the following functions: .. audit-event:: signal.pthread_kill thread_id,signalnum signal.pthread_kill - .. availability:: Unix. See the man page :manpage:`pthread_kill(3)` for further - information. + .. availability:: Unix. + + See the man page :manpage:`pthread_kill(3)` for further information. See also :func:`os.kill`. @@ -440,7 +466,9 @@ The :mod:`signal` module defines the following functions: :data:`SIGKILL` and :data:`SIGSTOP` cannot be blocked. - .. availability:: Unix. See the man page :manpage:`sigprocmask(2)` and + .. availability:: Unix. + + See the man page :manpage:`sigprocmask(2)` and :manpage:`pthread_sigmask(3)` for further information. See also :func:`pause`, :func:`sigpending` and :func:`sigwait`. @@ -528,8 +556,9 @@ The :mod:`signal` module defines the following functions: calls will be restarted when interrupted by signal *signalnum*, otherwise system calls will be interrupted. Returns nothing. - .. availability:: Unix. See the man page :manpage:`siginterrupt(3)` - for further information. + .. availability:: Unix. + + See the man page :manpage:`siginterrupt(3)` for further information. Note that installing a signal handler with :func:`signal` will reset the restart behaviour to interruptible by implicitly calling @@ -569,8 +598,9 @@ The :mod:`signal` module defines the following functions: thread (i.e., the signals which have been raised while blocked). Return the set of the pending signals. - .. availability:: Unix. See the man page :manpage:`sigpending(2)` for further - information. + .. availability:: Unix. + + See the man page :manpage:`sigpending(2)` for further information. See also :func:`pause`, :func:`pthread_sigmask` and :func:`sigwait`. @@ -583,8 +613,9 @@ The :mod:`signal` module defines the following functions: signals specified in the signal set *sigset*. The function accepts the signal (removes it from the pending list of signals), and returns the signal number. - .. availability:: Unix. See the man page :manpage:`sigwait(3)` for further - information. + .. availability:: Unix. + + See the man page :manpage:`sigwait(3)` for further information. See also :func:`pause`, :func:`pthread_sigmask`, :func:`sigpending`, :func:`sigwaitinfo` and :func:`sigtimedwait`. @@ -608,8 +639,9 @@ The :mod:`signal` module defines the following functions: :attr:`si_errno`, :attr:`si_pid`, :attr:`si_uid`, :attr:`si_status`, :attr:`si_band`. - .. availability:: Unix. See the man page :manpage:`sigwaitinfo(2)` for further - information. + .. availability:: Unix. + + See the man page :manpage:`sigwaitinfo(2)` for further information. See also :func:`pause`, :func:`sigwait` and :func:`sigtimedwait`. @@ -627,8 +659,9 @@ The :mod:`signal` module defines the following functions: specifying a timeout. If *timeout* is specified as :const:`0`, a poll is performed. Returns :const:`None` if a timeout occurs. - .. availability:: Unix. See the man page :manpage:`sigtimedwait(2)` for further - information. + .. availability:: Unix. + + See the man page :manpage:`sigtimedwait(2)` for further information. See also :func:`pause`, :func:`sigwait` and :func:`sigwaitinfo`. @@ -698,7 +731,75 @@ case, wrap your entry point to catch this exception as follows:: if __name__ == '__main__': main() -Do not set :const:`SIGPIPE`'s disposition to :const:`SIG_DFL` -in order to avoid :exc:`BrokenPipeError`. Doing that would cause -your program to exit unexpectedly also whenever any socket connection -is interrupted while your program is still writing to it. +Do not set :const:`SIGPIPE`'s disposition to :const:`SIG_DFL` in +order to avoid :exc:`BrokenPipeError`. Doing that would cause +your program to exit unexpectedly whenever any socket +connection is interrupted while your program is still writing to +it. + +.. _handlers-and-exceptions: + +Note on Signal Handlers and Exceptions +-------------------------------------- + +If a signal handler raises an exception, the exception will be propagated to +the main thread and may be raised after any :term:`bytecode` instruction. Most +notably, a :exc:`KeyboardInterrupt` may appear at any point during execution. +Most Python code, including the standard library, cannot be made robust against +this, and so a :exc:`KeyboardInterrupt` (or any other exception resulting from +a signal handler) may on rare occasions put the program in an unexpected state. + +To illustrate this issue, consider the following code:: + + class SpamContext: + def __init__(self): + self.lock = threading.Lock() + + def __enter__(self): + # If KeyboardInterrupt occurs here, everything is fine + self.lock.acquire() + # If KeyboardInterrupt occurs here, __exit__ will not be called + ... + # KeyboardInterrupt could occur just before the function returns + + def __exit__(self, exc_type, exc_val, exc_tb): + ... + self.lock.release() + +For many programs, especially those that merely want to exit on +:exc:`KeyboardInterrupt`, this is not a problem, but applications that are +complex or require high reliability should avoid raising exceptions from signal +handlers. They should also avoid catching :exc:`KeyboardInterrupt` as a means +of gracefully shutting down. Instead, they should install their own +:const:`SIGINT` handler. Below is an example of an HTTP server that avoids +:exc:`KeyboardInterrupt`:: + + import signal + import socket + from selectors import DefaultSelector, EVENT_READ + from http.server import HTTPServer, SimpleHTTPRequestHandler + + interrupt_read, interrupt_write = socket.socketpair() + + def handler(signum, frame): + print('Signal handler called with signal', signum) + interrupt_write.send(b'\0') + signal.signal(signal.SIGINT, handler) + + def serve_forever(httpd): + sel = DefaultSelector() + sel.register(interrupt_read, EVENT_READ) + sel.register(httpd, EVENT_READ) + + while True: + for key, _ in sel.select(): + if key.fileobj == interrupt_read: + interrupt_read.recv(1) + return + if key.fileobj == httpd: + httpd.handle_request() + + print("Serving on port 8000") + httpd = HTTPServer(('', 8000), SimpleHTTPRequestHandler) + serve_forever(httpd) + print("Shutdown...") diff --git a/Doc/library/site.rst b/Doc/library/site.rst index e2ad3c48f97..4a88013f1d6 100644 --- a/Doc/library/site.rst +++ b/Doc/library/site.rst @@ -250,8 +250,8 @@ command line: .. code-block:: shell-session - $ python3 -m site --user-site - /home/user/.local/lib/python3.3/site-packages + $ python -m site --user-site + /home/user/.local/lib/python3.11/site-packages If it is called without arguments, it will print the contents of :data:`sys.path` on the standard output, followed by the value of @@ -276,4 +276,6 @@ value greater than 2 if there is an error. .. seealso:: - :pep:`370` -- Per user site-packages directory + * :pep:`370` -- Per user site-packages directory + * :ref:`sys-path-init` -- The initialization of :data:`sys.path`. + diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst index aaab6b11d3b..2539c3d3883 100644 --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -19,6 +19,7 @@ to send mail to any internet machine with an SMTP or ESMTP listener daemon. For details of SMTP and ESMTP operation, consult :rfc:`821` (Simple Mail Transfer Protocol) and :rfc:`1869` (SMTP Service Extensions). +.. include:: ../includes/wasm-notavail.rst .. class:: SMTP(host='', port=0, local_hostname=None[, timeout], source_address=None) @@ -65,18 +66,17 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). Support for the :keyword:`with` statement was added. .. versionchanged:: 3.3 - source_address argument was added. + *source_address* argument was added. .. versionadded:: 3.5 The SMTPUTF8 extension (:rfc:`6531`) is now supported. .. versionchanged:: 3.9 If the *timeout* parameter is set to be zero, it will raise a - :class:`ValueError` to prevent the creation of a non-blocking socket + :class:`ValueError` to prevent the creation of a non-blocking socket. -.. class:: SMTP_SSL(host='', port=0, local_hostname=None, keyfile=None, \ - certfile=None [, timeout], context=None, \ - source_address=None) +.. class:: SMTP_SSL(host='', port=0, local_hostname=None, * [, timeout], \ + context=None, source_address=None) An :class:`SMTP_SSL` instance behaves exactly the same as instances of :class:`SMTP`. :class:`SMTP_SSL` should be used for situations where SSL is @@ -89,15 +89,11 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). aspects of the secure connection. Please read :ref:`ssl-security` for best practices. - *keyfile* and *certfile* are a legacy alternative to *context*, and can - point to a PEM formatted private key and certificate chain file for the - SSL connection. - .. versionchanged:: 3.3 *context* was added. .. versionchanged:: 3.3 - source_address argument was added. + The *source_address* argument was added. .. versionchanged:: 3.4 The class now supports hostname check with @@ -115,13 +111,16 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). If the *timeout* parameter is set to be zero, it will raise a :class:`ValueError` to prevent the creation of a non-blocking socket + .. versionchanged:: 3.12 + The deprecated *keyfile* and *certfile* parameters have been removed. + .. class:: LMTP(host='', port=LMTP_PORT, local_hostname=None, \ source_address=None[, timeout]) The LMTP protocol, which is very similar to ESMTP, is heavily based on the standard SMTP client. It's common to use Unix sockets for LMTP, so our :meth:`connect` method must support that as well as a regular host:port - server. The optional arguments local_hostname and source_address have the + server. The optional arguments *local_hostname* and *source_address* have the same meaning as they do in the :class:`SMTP` class. To specify a Unix socket, you must use an absolute path for *host*, starting with a '/'. @@ -359,7 +358,7 @@ An :class:`SMTP` instance has the following methods: be used as argument to the ``AUTH`` command; the valid values are those listed in the ``auth`` element of :attr:`esmtp_features`. - *authobject* must be a callable object taking an optional single argument: + *authobject* must be a callable object taking an optional single argument:: data = authobject(challenge=None) @@ -392,7 +391,7 @@ An :class:`SMTP` instance has the following methods: .. versionadded:: 3.5 -.. method:: SMTP.starttls(keyfile=None, certfile=None, context=None) +.. method:: SMTP.starttls(*, context=None) Put the SMTP connection in TLS (Transport Layer Security) mode. All SMTP commands that follow will be encrypted. You should then call :meth:`ehlo` @@ -415,6 +414,9 @@ An :class:`SMTP` instance has the following methods: :func:`ssl.create_default_context` select the system's trusted CA certificates for you. + .. versionchanged:: 3.12 + The deprecated *keyfile* and *certfile* parameters have been removed. + :exc:`SMTPHeloError` The server didn't reply properly to the ``HELO`` greeting. diff --git a/Doc/library/sndhdr.rst b/Doc/library/sndhdr.rst index 6bfa9a9fd21..fa9323e18dc 100644 --- a/Doc/library/sndhdr.rst +++ b/Doc/library/sndhdr.rst @@ -3,6 +3,7 @@ .. module:: sndhdr :synopsis: Determine type of a sound file. + :deprecated: .. sectionauthor:: Fred L. Drake, Jr. .. Based on comments in the module source file. @@ -13,6 +14,10 @@ single: A-LAW single: u-LAW +.. deprecated-removed:: 3.11 3.13 + The :mod:`sndhdr` module is deprecated + (see :pep:`PEP 594 <594#sndhdr>` for details and alternatives). + -------------- The :mod:`sndhdr` provides utility functions which attempt to determine the type @@ -49,3 +54,51 @@ be the sample size in bits or ``'A'`` for A-LAW or ``'U'`` for u-LAW. .. versionchanged:: 3.5 Result changed from a tuple to a namedtuple. +The following sound header types are recognized, as listed below with the return value +from :func:`whathdr`: and :func:`what`: + ++------------+------------------------------------+ +| Value | Sound header format | ++============+====================================+ +| ``'aifc'`` | Compressed Audio Interchange Files | ++------------+------------------------------------+ +| ``'aiff'`` | Audio Interchange Files | ++------------+------------------------------------+ +| ``'au'`` | Au Files | ++------------+------------------------------------+ +| ``'hcom'`` | HCOM Files | ++------------+------------------------------------+ +| ``'sndt'`` | Sndtool Sound Files | ++------------+------------------------------------+ +| ``'voc'`` | Creative Labs Audio Files | ++------------+------------------------------------+ +| ``'wav'`` | Waveform Audio File Format Files | ++------------+------------------------------------+ +| ``'8svx'`` | 8-Bit Sampled Voice Files | ++------------+------------------------------------+ +| ``'sb'`` | Signed Byte Audio Data Files | ++------------+------------------------------------+ +| ``'ub'`` | UB Files | ++------------+------------------------------------+ +| ``'ul'`` | uLAW Audio Files | ++------------+------------------------------------+ + +.. data:: tests + + A list of functions performing the individual tests. Each function takes two + arguments: the byte-stream and an open file-like object. When :func:`what` is + called with a byte-stream, the file-like object will be ``None``. + + The test function should return a string describing the image type if the test + succeeded, or ``None`` if it failed. + +Example: + +.. code-block:: pycon + + >>> import sndhdr + >>> imghdr.what('bass.wav') + 'wav' + >>> imghdr.whathdr('bass.wav') + 'wav' + diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst old mode 100755 new mode 100644 index d6edc057f5e..aec79da57f0 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -16,6 +16,9 @@ all modern Unix systems, Windows, MacOS, and probably additional platforms. Some behavior may be platform dependent, since calls are made to the operating system socket APIs. + +.. include:: ../includes/wasm-notavail.rst + .. index:: object: socket The Python interface is a straightforward transliteration of the Unix system @@ -125,7 +128,7 @@ created. Socket addresses are represented as follows: - A string or a tuple ``(id, unit)`` is used for the :const:`SYSPROTO_CONTROL` protocol of the :const:`PF_SYSTEM` family. The string is the name of a - kernel control using a dynamically-assigned ID. The tuple can be used if ID + kernel control using a dynamically assigned ID. The tuple can be used if ID and unit number of the kernel control are known or if a registered ID is used. @@ -165,7 +168,9 @@ created. Socket addresses are represented as follows: - *feat* and *mask* are unsigned 32bit integers. - .. availability:: Linux 2.6.38, some algorithm types require more recent Kernels. + .. availability:: Linux >= 2.6.38. + + Some algorithm types require more recent Kernels. .. versionadded:: 3.6 @@ -173,7 +178,9 @@ created. Socket addresses are represented as follows: their hosts. The sockets are represented as a ``(CID, port)`` tuple where the context ID or CID and port are integers. - .. availability:: Linux >= 4.8 QEMU >= 2.8 ESX >= 4.0 ESX Workstation >= 6.5. + .. availability:: Linux >= 3.9 + + See :manpage:`vsock(7)` .. versionadded:: 3.7 @@ -182,8 +189,11 @@ created. Socket addresses are represented as follows: ``(ifname, proto[, pkttype[, hatype[, addr]]])`` where: - *ifname* - String specifying the device name. - - *proto* - An in network-byte-order integer specifying the Ethernet - protocol number. + - *proto* - The Ethernet protocol number. + May be :data:`ETH_P_ALL` to capture all protocols, + one of the :ref:`ETHERTYPE_* constants ` + or any other Ethernet protocol number. + Value must be in network-byte-order. - *pkttype* - Optional integer specifying the packet type: - ``PACKET_HOST`` (the default) - Packet addressed to the local host. @@ -221,10 +231,33 @@ created. Socket addresses are represented as follows: ``socket(AF_INET, SOCK_DGRAM, IPPROTO_UDPLITE)`` for IPv4 or ``socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE)`` for IPv6. - .. availability:: Linux >= 2.6.20, FreeBSD >= 10.1-RELEASE + .. availability:: Linux >= 2.6.20, FreeBSD >= 10.1 .. versionadded:: 3.9 +- :const:`AF_HYPERV` is a Windows-only socket based interface for communicating + with Hyper-V hosts and guests. The address family is represented as a + ``(vm_id, service_id)`` tuple where the ``vm_id`` and ``service_id`` are + UUID strings. + + The ``vm_id`` is the virtual machine identifier or a set of known VMID values + if the target is not a specific virtual machine. Known VMID constants + defined on ``socket`` are: + + - ``HV_GUID_ZERO`` + - ``HV_GUID_BROADCAST`` + - ``HV_GUID_WILDCARD`` - Used to bind on itself and accept connections from + all partitions. + - ``HV_GUID_CHILDREN`` - Used to bind on itself and accept connection from + child partitions. + - ``HV_GUID_LOOPBACK`` - Used as a target to itself. + - ``HV_GUID_PARENT`` - When used as a bind accepts connection from the parent + partition. When used as an address target it will connect to the parent partition. + + The ``service_id`` is the service identifier of the registered service. + + .. versionadded:: 3.12 + If you use a hostname in the *host* portion of IPv4/v6 socket address, the program may show a nondeterministic behavior, as Python uses the first address returned from the DNS resolution. The socket address will be resolved @@ -233,9 +266,9 @@ resolution and/or the host configuration. For deterministic behavior use a numeric address in *host* portion. All errors raise exceptions. The normal exceptions for invalid argument types -and out-of-memory conditions can be raised; starting from Python 3.3, errors +and out-of-memory conditions can be raised. Errors related to socket or address semantics raise :exc:`OSError` or one of its -subclasses (they used to raise :exc:`socket.error`). +subclasses. Non-blocking mode is supported through :meth:`~socket.setblocking`. A generalization of this based on timeouts is supported through @@ -340,7 +373,7 @@ Constants .. seealso:: - `Secure File Descriptor Handling `_ + `Secure File Descriptor Handling `_ for a more thorough explanation. .. availability:: Linux >= 2.6.27. @@ -388,6 +421,23 @@ Constants Added ``TCP_KEEPALIVE``. On MacOS this constant can be used in the same way that ``TCP_KEEPIDLE`` is used on Linux. + .. versionchanged:: 3.11 + Added ``TCP_CONNECTION_INFO``. On MacOS this constant can be used in the + same way that ``TCP_INFO`` is used on Linux and BSD. + + .. versionchanged:: 3.12 + Added ``SO_RTABLE`` and ``SO_USER_COOKIE``. On OpenBSD + and FreeBSD respectively those constants can be used in the same way that + ``SO_MARK`` is used on Linux. Also added missing TCP socket options from + Linux: ``TCP_MD5SIG``, ``TCP_THIN_LINEAR_TIMEOUTS``, ``TCP_THIN_DUPACK``, + ``TCP_REPAIR``, ``TCP_REPAIR_QUEUE``, ``TCP_QUEUE_SEQ``, + ``TCP_REPAIR_OPTIONS``, ``TCP_TIMESTAMP``, ``TCP_CC_INFO``, + ``TCP_SAVE_SYN``, ``TCP_SAVED_SYN``, ``TCP_REPAIR_WINDOW``, + ``TCP_FASTOPEN_CONNECT``, ``TCP_ULP``, ``TCP_MD5SIG_EXT``, + ``TCP_FASTOPEN_KEY``, ``TCP_FASTOPEN_NO_COOKIE``, + ``TCP_ZEROCOPY_RECEIVE``, ``TCP_INQ``, ``TCP_TX_DELAY``. + Added ``IP_PKTINFO``. + .. data:: AF_CAN PF_CAN SOL_CAN_* @@ -396,10 +446,13 @@ Constants Many constants of these forms, documented in the Linux documentation, are also defined in the socket module. - .. availability:: Linux >= 2.6.25. + .. availability:: Linux >= 2.6.25, NetBSD >= 8. .. versionadded:: 3.3 + .. versionchanged:: 3.11 + NetBSD support was added. + .. data:: CAN_BCM CAN_BCM_* @@ -466,6 +519,19 @@ Constants .. availability:: Linux >= 2.2. +.. data:: ETH_P_ALL + + :data:`!ETH_P_ALL` can be used in the :class:`~socket.socket` + constructor as *proto* for the :const:`AF_PACKET` family in order to + capture every packet, regardless of protocol. + + For more information, see the :manpage:`packet(7)` manpage. + + .. availability:: Linux. + + .. versionadded:: 3.12 + + .. data:: AF_RDS PF_RDS SOL_RDS @@ -553,6 +619,65 @@ Constants .. availability:: Linux >= 4.7. +.. data:: SCM_CREDS2 + LOCAL_CREDS + LOCAL_CREDS_PERSISTENT + + LOCAL_CREDS and LOCAL_CREDS_PERSISTENT can be used + with SOCK_DGRAM, SOCK_STREAM sockets, equivalent to + Linux/DragonFlyBSD SO_PASSCRED, while LOCAL_CREDS + sends the credentials at first read, LOCAL_CREDS_PERSISTENT + sends for each read, SCM_CREDS2 must be then used for + the latter for the message type. + + .. versionadded:: 3.11 + + .. availability:: FreeBSD. + +.. data:: SO_INCOMING_CPU + + Constant to optimize CPU locality, to be used in conjunction with + :data:`SO_REUSEPORT`. + + .. versionadded:: 3.11 + + .. availability:: Linux >= 3.9 + +.. data:: AF_HYPERV + HV_PROTOCOL_RAW + HVSOCKET_CONNECT_TIMEOUT + HVSOCKET_CONNECT_TIMEOUT_MAX + HVSOCKET_CONNECTED_SUSPEND + HVSOCKET_ADDRESS_FLAG_PASSTHRU + HV_GUID_ZERO + HV_GUID_WILDCARD + HV_GUID_BROADCAST + HV_GUID_CHILDREN + HV_GUID_LOOPBACK + HV_GUID_LOOPBACK + + Constants for Windows Hyper-V sockets for host/guest communications. + + .. availability:: Windows. + + .. versionadded:: 3.12 + +.. _socket-ethernet-types: + +.. data:: ETHERTYPE_ARP + ETHERTYPE_IP + ETHERTYPE_IPV6 + ETHERTYPE_VLAN + + `IEEE 802.3 protocol number + `_. + constants. + + .. availability:: Linux, FreeBSD, macOS. + + .. versionadded:: 3.12 + + Functions ^^^^^^^^^ @@ -604,7 +729,7 @@ The following functions all create :ref:`socket objects `. When :const:`SOCK_NONBLOCK` or :const:`SOCK_CLOEXEC` bit flags are applied to *type* they are cleared, and :attr:`socket.type` will not reflect them. They are still passed - to the underlying system `socket()` call. Therefore, + to the underlying system ``socket()`` call. Therefore, :: @@ -642,7 +767,7 @@ The following functions all create :ref:`socket objects `. Windows support added. -.. function:: create_connection(address[, timeout[, source_address]]) +.. function:: create_connection(address, timeout=GLOBAL_DEFAULT, source_address=None, *, all_errors=False) Connect to a TCP service listening on the internet *address* (a 2-tuple ``(host, port)``), and return the socket object. This is a higher-level @@ -661,17 +786,26 @@ The following functions all create :ref:`socket objects `. socket to bind to as its source address before connecting. If host or port are '' or 0 respectively the OS default behavior will be used. + When a connection cannot be created, an exception is raised. By default, + it is the exception from the last address in the list. If *all_errors* + is ``True``, it is an :exc:`ExceptionGroup` containing the errors of all + attempts. + .. versionchanged:: 3.2 *source_address* was added. + .. versionchanged:: 3.11 + *all_errors* was added. + + .. function:: create_server(address, *, family=AF_INET, backlog=None, reuse_port=False, dualstack_ipv6=False) Convenience function which creates a TCP socket bound to *address* (a 2-tuple - ``(host, port)``) and return the socket object. + ``(host, port)``) and returns the socket object. *family* should be either :data:`AF_INET` or :data:`AF_INET6`. - *backlog* is the queue size passed to :meth:`socket.listen`; when ``0`` - a default reasonable value is chosen. + *backlog* is the queue size passed to :meth:`socket.listen`; if not specified + , a default reasonable value is chosen. *reuse_port* dictates whether to set the :data:`SO_REUSEPORT` socket option. If *dualstack_ipv6* is true and the platform supports it the socket will @@ -827,6 +961,8 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.gethostbyname hostname socket.gethostbyname + .. availability:: not WASI. + .. function:: gethostbyname_ex(hostname) @@ -841,6 +977,8 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.gethostbyname hostname socket.gethostbyname_ex + .. availability:: not WASI. + .. function:: gethostname() @@ -852,6 +990,8 @@ The :mod:`socket` module also offers various network-related services: Note: :func:`gethostname` doesn't always return the fully qualified domain name; use :func:`getfqdn` for that. + .. availability:: not WASI. + .. function:: gethostbyaddr(ip_address) @@ -865,11 +1005,13 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.gethostbyaddr ip_address socket.gethostbyaddr + .. availability:: not WASI. + .. function:: getnameinfo(sockaddr, flags) Translate a socket address *sockaddr* into a 2-tuple ``(host, port)``. Depending - on the settings of *flags*, the result can contain a fully-qualified domain name + on the settings of *flags*, the result can contain a fully qualified domain name or numeric address representation in *host*. Similarly, *port* can contain a string port name or a numeric port number. @@ -880,6 +1022,9 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.getnameinfo sockaddr socket.getnameinfo + .. availability:: not WASI. + + .. function:: getprotobyname(protocolname) Translate an internet protocol name (for example, ``'icmp'``) to a constant @@ -888,6 +1033,8 @@ The :mod:`socket` module also offers various network-related services: (:const:`SOCK_RAW`); for the normal socket modes, the correct protocol is chosen automatically if the protocol is omitted or zero. + .. availability:: not WASI. + .. function:: getservbyname(servicename[, protocolname]) @@ -897,6 +1044,8 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.getservbyname servicename,protocolname socket.getservbyname + .. availability:: not WASI. + .. function:: getservbyport(port[, protocolname]) @@ -906,6 +1055,8 @@ The :mod:`socket` module also offers various network-related services: .. audit-event:: socket.getservbyport port,protocolname socket.getservbyport + .. availability:: not WASI. + .. function:: ntohl(x) @@ -948,7 +1099,7 @@ The :mod:`socket` module also offers various network-related services: Convert an IPv4 address from dotted-quad string format (for example, '123.45.67.89') to 32-bit packed binary format, as a bytes object four characters in length. This is useful when conversing with a program that uses the standard C - library and needs objects of type :c:type:`struct in_addr`, which is the C type + library and needs objects of type :c:struct:`in_addr`, which is the C type for the 32-bit packed binary this function returns. :func:`inet_aton` also accepts strings with less than three dots; see the @@ -967,7 +1118,7 @@ The :mod:`socket` module also offers various network-related services: Convert a 32-bit packed IPv4 address (a :term:`bytes-like object` four bytes in length) to its standard dotted-quad string representation (for example, '123.45.67.89'). This is useful when conversing with a program that uses the - standard C library and needs objects of type :c:type:`struct in_addr`, which + standard C library and needs objects of type :c:struct:`in_addr`, which is the C type for the 32-bit packed binary data this function takes as an argument. @@ -984,8 +1135,8 @@ The :mod:`socket` module also offers various network-related services: Convert an IP address from its family-specific string format to a packed, binary format. :func:`inet_pton` is useful when a library or network protocol - calls for an object of type :c:type:`struct in_addr` (similar to - :func:`inet_aton`) or :c:type:`struct in6_addr`. + calls for an object of type :c:struct:`in_addr` (similar to + :func:`inet_aton`) or :c:struct:`in6_addr`. Supported values for *address_family* are currently :const:`AF_INET` and :const:`AF_INET6`. If the IP address string *ip_string* is invalid, @@ -993,7 +1144,7 @@ The :mod:`socket` module also offers various network-related services: both the value of *address_family* and the underlying implementation of :c:func:`inet_pton`. - .. availability:: Unix (maybe not all platforms), Windows. + .. availability:: Unix, Windows. .. versionchanged:: 3.4 Windows support added @@ -1005,15 +1156,15 @@ The :mod:`socket` module also offers various network-related services: bytes) to its standard, family-specific string representation (for example, ``'7.10.0.5'`` or ``'5aef:2b::8'``). :func:`inet_ntop` is useful when a library or network protocol returns an - object of type :c:type:`struct in_addr` (similar to :func:`inet_ntoa`) or - :c:type:`struct in6_addr`. + object of type :c:struct:`in_addr` (similar to :func:`inet_ntoa`) or + :c:struct:`in6_addr`. Supported values for *address_family* are currently :const:`AF_INET` and :const:`AF_INET6`. If the bytes object *packed_ip* is not the correct length for the specified address family, :exc:`ValueError` will be raised. :exc:`OSError` is raised for errors from the call to :func:`inet_ntop`. - .. availability:: Unix (maybe not all platforms), Windows. + .. availability:: Unix, Windows. .. versionchanged:: 3.4 Windows support added @@ -1039,7 +1190,9 @@ The :mod:`socket` module also offers various network-related services: buffer. Raises :exc:`OverflowError` if *length* is outside the permissible range of values. - .. availability:: most Unix platforms, possibly others. + .. availability:: Unix, not Emscripten, not WASI. + + Most Unix platforms. .. versionadded:: 3.3 @@ -1060,7 +1213,9 @@ The :mod:`socket` module also offers various network-related services: amount of ancillary data that can be received, since additional data may be able to fit into the padding area. - .. availability:: most Unix platforms, possibly others. + .. availability:: Unix, not Emscripten, not WASI. + + most Unix platforms. .. versionadded:: 3.3 @@ -1098,7 +1253,7 @@ The :mod:`socket` module also offers various network-related services: (index int, name string) tuples. :exc:`OSError` if the system call fails. - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -1125,7 +1280,7 @@ The :mod:`socket` module also offers various network-related services: interface name. :exc:`OSError` if no interface with the given name exists. - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -1142,7 +1297,7 @@ The :mod:`socket` module also offers various network-related services: interface index number. :exc:`OSError` if no interface with the given index exists. - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten, not WASI. .. versionadded:: 3.3 @@ -1159,7 +1314,10 @@ The :mod:`socket` module also offers various network-related services: The *fds* parameter is a sequence of file descriptors. Consult :meth:`sendmsg` for the documentation of these parameters. - .. availability:: Unix supporting :meth:`~socket.sendmsg` and :const:`SCM_RIGHTS` mechanism. + .. availability:: Unix, Windows, not Emscripten, not WASI. + + Unix platforms supporting :meth:`~socket.sendmsg` + and :const:`SCM_RIGHTS` mechanism. .. versionadded:: 3.9 @@ -1170,7 +1328,10 @@ The :mod:`socket` module also offers various network-related services: Return ``(msg, list(fds), flags, addr)``. Consult :meth:`recvmsg` for the documentation of these parameters. - .. availability:: Unix supporting :meth:`~socket.recvmsg` and :const:`SCM_RIGHTS` mechanism. + .. availability:: Unix, Windows, not Emscripten, not WASI. + + Unix platforms supporting :meth:`~socket.sendmsg` + and :const:`SCM_RIGHTS` mechanism. .. versionadded:: 3.9 @@ -1218,6 +1379,9 @@ to sockets. .. audit-event:: socket.bind self,address socket.socket.bind + .. availability:: not WASI. + + .. method:: socket.close() Mark the socket closed. The underlying system resource (e.g. a file @@ -1262,6 +1426,8 @@ to sockets. signal, the signal handler doesn't raise an exception and the socket is blocking or has a timeout (see the :pep:`475` for the rationale). + .. availability:: not WASI. + .. method:: socket.connect_ex(address) @@ -1274,6 +1440,8 @@ to sockets. .. audit-event:: socket.connect self,address socket.socket.connect_ex + .. availability:: not WASI. + .. method:: socket.detach() Put the socket object into closed state without actually closing the @@ -1292,6 +1460,8 @@ to sockets. .. versionchanged:: 3.4 The socket is now non-inheritable. + .. availability:: not WASI. + .. method:: socket.fileno() @@ -1337,6 +1507,8 @@ to sockets. contents of the buffer (see the optional built-in module :mod:`struct` for a way to decode C structures encoded as byte strings). + .. availability:: not WASI. + .. method:: socket.getblocking() @@ -1380,9 +1552,12 @@ to sockets. unaccepted connections that the system will allow before refusing new connections. If not specified, a default reasonable value is chosen. + .. availability:: not WASI. + .. versionchanged:: 3.5 The *backlog* parameter is now optional. + .. method:: socket.makefile(mode='r', buffering=None, *, encoding=None, \ errors=None, newline=None) @@ -1477,7 +1652,7 @@ to sockets. ancillary data, items of the form ``(socket.SOL_SOCKET, socket.SCM_RIGHTS, fds)``, where *fds* is a :class:`bytes` object representing the new file descriptors as a binary array of the - native C :c:type:`int` type. If :meth:`recvmsg` raises an + native C :c:expr:`int` type. If :meth:`recvmsg` raises an exception after the system call returns, it will first attempt to close any file descriptors received via this mechanism. @@ -1505,7 +1680,9 @@ to sockets. fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) return msg, list(fds) - .. availability:: most Unix platforms, possibly others. + .. availability:: Unix. + + Most Unix platforms. .. versionadded:: 3.3 @@ -1547,7 +1724,9 @@ to sockets. >>> [b1, b2, b3] [bytearray(b'Mary'), bytearray(b'01 had a 9'), bytearray(b'little lamb---')] - .. availability:: most Unix platforms, possibly others. + .. availability:: Unix. + + Most Unix platforms. .. versionadded:: 3.3 @@ -1653,7 +1832,9 @@ to sockets. def send_fds(sock, msg, fds): return sock.sendmsg([msg], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, array.array("i", fds))]) - .. availability:: most Unix platforms, possibly others. + .. availability:: Unix, not WASI. + + Most Unix platforms. .. audit-event:: socket.sendmsg self,address socket.socket.sendmsg @@ -1747,13 +1928,14 @@ to sockets. *optlen* argument is required. It's equivalent to call :c:func:`setsockopt` C function with ``optval=NULL`` and ``optlen=optlen``. - .. versionchanged:: 3.5 Writable :term:`bytes-like object` is now accepted. .. versionchanged:: 3.6 setsockopt(level, optname, None, optlen: int) form added. + .. availability:: not WASI. + .. method:: socket.shutdown(how) @@ -1762,6 +1944,8 @@ to sockets. are disallowed. If *how* is :const:`SHUT_RDWR`, further sends and receives are disallowed. + .. availability:: not WASI. + .. method:: socket.share(process_id) @@ -1988,10 +2172,10 @@ the interface:: # Include IP headers s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) - # receive all packages + # receive all packets s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) - # receive a package + # receive a packet print(s.recvfrom(65565)) # disabled promiscuous mode diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index 8aa72bd7332..ceb962e8600 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -10,6 +10,8 @@ The :mod:`socketserver` module simplifies the task of writing network servers. +.. include:: ../includes/wasm-notavail.rst + There are four basic concrete server classes: @@ -94,8 +96,7 @@ synchronous servers of four types:: Note that :class:`UnixDatagramServer` derives from :class:`UDPServer`, not from :class:`UnixStreamServer` --- the only difference between an IP and a Unix -stream server is the address family, which is simply repeated in both Unix -server classes. +server is the address family. .. class:: ForkingMixIn @@ -175,8 +176,7 @@ expensive or inappropriate for the service) is to maintain an explicit table of partially finished requests and to use :mod:`selectors` to decide which request to work on next (or whether to handle a new incoming request). This is particularly important for stream services where each client can potentially be -connected for a long time (if threads or subprocesses cannot be used). See -:mod:`asyncio` for another way to manage this. +connected for a long time (if threads or subprocesses cannot be used). .. XXX should data and methods be intermingled, or separate? how should the distinction between class and instance variables be drawn? @@ -430,11 +430,8 @@ Request Handler Objects The :attr:`self.rfile` and :attr:`self.wfile` attributes can be read or written, respectively, to get the request data or return data to the client. - - The :attr:`rfile` attributes of both classes support the - :class:`io.BufferedIOBase` readable interface, and - :attr:`DatagramRequestHandler.wfile` supports the - :class:`io.BufferedIOBase` writable interface. + The :attr:`!rfile` attributes support the :class:`io.BufferedIOBase` readable interface, + and :attr:`!wfile` attributes support the :class:`!io.BufferedIOBase` writable interface. .. versionchanged:: 3.6 :attr:`StreamRequestHandler.wfile` also supports the diff --git a/Doc/library/spwd.rst b/Doc/library/spwd.rst index c6cad2a3c32..d1693ea67f0 100644 --- a/Doc/library/spwd.rst +++ b/Doc/library/spwd.rst @@ -4,12 +4,19 @@ .. module:: spwd :platform: Unix :synopsis: The shadow password database (getspnam() and friends). + :deprecated: + +.. deprecated-removed:: 3.11 3.13 + The :mod:`spwd` module is deprecated + (see :pep:`PEP 594 <594#spwd>` for details and alternatives). -------------- This module provides access to the Unix shadow password database. It is available on various Unix versions. +.. include:: ../includes/wasm-notavail.rst + You must have enough privileges to access the shadow password database (this usually means you have to be root). diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 9fffe4da901..c0f0f133f4a 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -8,7 +8,17 @@ **Source code:** :source:`Lib/sqlite3/` --------------- +.. Make sure we always doctest the tutorial with an empty database. + +.. testsetup:: + + import sqlite3 + src = sqlite3.connect(":memory:", isolation_level=None) + dst = sqlite3.connect("tutorial.db", isolation_level=None) + src.backup(dst) + del src, dst + +.. _sqlite3-intro: SQLite is a C library that provides a lightweight disk-based database that doesn't require a separate server process and allows accessing the database @@ -17,88 +27,18 @@ SQLite for internal data storage. It's also possible to prototype an application using SQLite and then port the code to a larger database such as PostgreSQL or Oracle. -The sqlite3 module was written by Gerhard Häring. It provides a SQL interface +The :mod:`!sqlite3` module was written by Gerhard Häring. It provides an SQL interface compliant with the DB-API 2.0 specification described by :pep:`249`, and requires SQLite 3.7.15 or newer. -To use the module, start by creating a :class:`Connection` object that -represents the database. Here the data will be stored in the -:file:`example.db` file:: - - import sqlite3 - con = sqlite3.connect('example.db') - -The special path name ``:memory:`` can be provided to create a temporary -database in RAM. - -Once a :class:`Connection` has been established, create a :class:`Cursor` object -and call its :meth:`~Cursor.execute` method to perform SQL commands:: - - cur = con.cursor() - - # Create table - cur.execute('''CREATE TABLE stocks - (date text, trans text, symbol text, qty real, price real)''') - - # Insert a row of data - cur.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)") - - # Save (commit) the changes - con.commit() - - # We can also close the connection if we are done with it. - # Just be sure any changes have been committed or they will be lost. - con.close() - -The saved data is persistent: it can be reloaded in a subsequent session even -after restarting the Python interpreter:: - - import sqlite3 - con = sqlite3.connect('example.db') - cur = con.cursor() - -To retrieve data after executing a SELECT statement, either treat the cursor as -an :term:`iterator`, call the cursor's :meth:`~Cursor.fetchone` method to -retrieve a single matching row, or call :meth:`~Cursor.fetchall` to get a list -of the matching rows. - -This example uses the iterator form:: - - >>> for row in cur.execute('SELECT * FROM stocks ORDER BY price'): - print(row) - - ('2006-01-05', 'BUY', 'RHAT', 100, 35.14) - ('2006-03-28', 'BUY', 'IBM', 1000, 45.0) - ('2006-04-06', 'SELL', 'IBM', 500, 53.0) - ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0) - - -.. _sqlite3-placeholders: - -SQL operations usually need to use values from Python variables. However, -beware of using Python's string operations to assemble queries, as they -are vulnerable to SQL injection attacks (see the `xkcd webcomic -`_ for a humorous example of what can go wrong):: - - # Never do this -- insecure! - symbol = 'RHAT' - cur.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol) - -Instead, use the DB-API's parameter substitution. To insert a variable into a -query string, use a placeholder in the string, and substitute the actual values -into the query by providing them as a :class:`tuple` of values to the second -argument of the cursor's :meth:`~Cursor.execute` method. An SQL statement may -use one of two kinds of placeholders: question marks (qmark style) or named -placeholders (named style). For the qmark style, ``parameters`` must be a -:term:`sequence `. For the named style, it can be either a -:term:`sequence ` or :class:`dict` instance. The length of the -:term:`sequence ` must match the number of placeholders, or a -:exc:`ProgrammingError` is raised. If a :class:`dict` is given, it must contain -keys for all named parameters. Any extra items are ignored. Here's an example of -both styles: - -.. literalinclude:: ../includes/sqlite3/execute_1.py +This document includes four main sections: +* :ref:`sqlite3-tutorial` teaches how to use the :mod:`!sqlite3` module. +* :ref:`sqlite3-reference` describes the classes and functions this module + defines. +* :ref:`sqlite3-howtos` details how to handle specific tasks. +* :ref:`sqlite3-explanation` provides in-depth background on + transaction control. .. seealso:: @@ -113,11 +53,440 @@ both styles: PEP written by Marc-André Lemburg. +.. We use the following practises for SQL code: + - UPPERCASE for keywords + - snake_case for schema + - single quotes for string literals + - singular for table names + - if needed, use double quotes for table and column names + +.. _sqlite3-tutorial: + +Tutorial +-------- + +In this tutorial, you will create a database of Monty Python movies +using basic :mod:`!sqlite3` functionality. +It assumes a fundamental understanding of database concepts, +including `cursors`_ and `transactions`_. + +First, we need to create a new database and open +a database connection to allow :mod:`!sqlite3` to work with it. +Call :func:`sqlite3.connect` to to create a connection to +the database :file:`tutorial.db` in the current working directory, +implicitly creating it if it does not exist: + +.. testcode:: + + import sqlite3 + con = sqlite3.connect("tutorial.db") + +The returned :class:`Connection` object ``con`` +represents the connection to the on-disk database. + +In order to execute SQL statements and fetch results from SQL queries, +we will need to use a database cursor. +Call :meth:`con.cursor() ` to create the :class:`Cursor`: + +.. testcode:: + + cur = con.cursor() + +Now that we've got a database connection and a cursor, +we can create a database table ``movie`` with columns for title, +release year, and review score. +For simplicity, we can just use column names in the table declaration -- +thanks to the `flexible typing`_ feature of SQLite, +specifying the data types is optional. +Execute the ``CREATE TABLE`` statement +by calling :meth:`cur.execute(...) `: + +.. testcode:: + + cur.execute("CREATE TABLE movie(title, year, score)") + +.. Ideally, we'd use sqlite_schema instead of sqlite_master below, + but SQLite versions older than 3.33.0 do not recognise that variant. + +We can verify that the new table has been created by querying +the ``sqlite_master`` table built-in to SQLite, +which should now contain an entry for the ``movie`` table definition +(see `The Schema Table`_ for details). +Execute that query by calling :meth:`cur.execute(...) `, +assign the result to ``res``, +and call :meth:`res.fetchone() ` to fetch the resulting row: + +.. doctest:: + + >>> res = cur.execute("SELECT name FROM sqlite_master") + >>> res.fetchone() + ('movie',) + +We can see that the table has been created, +as the query returns a :class:`tuple` containing the table's name. +If we query ``sqlite_master`` for a non-existent table ``spam``, +:meth:`!res.fetchone()` will return ``None``: + +.. doctest:: + + >>> res = cur.execute("SELECT name FROM sqlite_master WHERE name='spam'") + >>> res.fetchone() is None + True + +Now, add two rows of data supplied as SQL literals +by executing an ``INSERT`` statement, +once again by calling :meth:`cur.execute(...) `: + +.. testcode:: + + cur.execute(""" + INSERT INTO movie VALUES + ('Monty Python and the Holy Grail', 1975, 8.2), + ('And Now for Something Completely Different', 1971, 7.5) + """) + +The ``INSERT`` statement implicitly opens a transaction, +which needs to be committed before changes are saved in the database +(see :ref:`sqlite3-controlling-transactions` for details). +Call :meth:`con.commit() ` on the connection object +to commit the transaction: + +.. testcode:: + + con.commit() + +We can verify that the data was inserted correctly +by executing a ``SELECT`` query. +Use the now-familiar :meth:`cur.execute(...) ` to +assign the result to ``res``, +and call :meth:`res.fetchall() ` to return all resulting rows: + +.. doctest:: + + >>> res = cur.execute("SELECT score FROM movie") + >>> res.fetchall() + [(8.2,), (7.5,)] + +The result is a :class:`list` of two :class:`!tuple`\s, one per row, +each containing that row's ``score`` value. + +Now, insert three more rows by calling +:meth:`cur.executemany(...) `: + +.. testcode:: + + data = [ + ("Monty Python Live at the Hollywood Bowl", 1982, 7.9), + ("Monty Python's The Meaning of Life", 1983, 7.5), + ("Monty Python's Life of Brian", 1979, 8.0), + ] + cur.executemany("INSERT INTO movie VALUES(?, ?, ?)", data) + con.commit() # Remember to commit the transaction after executing INSERT. + +Notice that ``?`` placeholders are used to bind ``data`` to the query. +Always use placeholders instead of :ref:`string formatting ` +to bind Python values to SQL statements, +to avoid `SQL injection attacks`_ +(see :ref:`sqlite3-placeholders` for more details). + +We can verify that the new rows were inserted +by executing a ``SELECT`` query, +this time iterating over the results of the query: + +.. doctest:: + + >>> for row in cur.execute("SELECT year, title FROM movie ORDER BY year"): + ... print(row) + (1971, 'And Now for Something Completely Different') + (1975, 'Monty Python and the Holy Grail') + (1979, "Monty Python's Life of Brian") + (1982, 'Monty Python Live at the Hollywood Bowl') + (1983, "Monty Python's The Meaning of Life") + +Each row is a two-item :class:`tuple` of ``(year, title)``, +matching the columns selected in the query. + +Finally, verify that the database has been written to disk +by calling :meth:`con.close() ` +to close the existing connection, opening a new one, +creating a new cursor, then querying the database: + +.. doctest:: + + >>> con.close() + >>> new_con = sqlite3.connect("tutorial.db") + >>> new_cur = new_con.cursor() + >>> res = new_cur.execute("SELECT title, year FROM movie ORDER BY score DESC") + >>> title, year = res.fetchone() + >>> print(f'The highest scoring Monty Python movie is {title!r}, released in {year}') + The highest scoring Monty Python movie is 'Monty Python and the Holy Grail', released in 1975 + +You've now created an SQLite database using the :mod:`!sqlite3` module, +inserted data and retrieved values from it in multiple ways. + +.. _SQL injection attacks: https://en.wikipedia.org/wiki/SQL_injection +.. _The Schema Table: https://www.sqlite.org/schematab.html +.. _cursors: https://en.wikipedia.org/wiki/Cursor_(databases) +.. _flexible typing: https://www.sqlite.org/flextypegood.html +.. _sqlite_master: https://www.sqlite.org/schematab.html +.. _transactions: https://en.wikipedia.org/wiki/Database_transaction + +.. seealso:: + + * :ref:`sqlite3-howtos` for further reading: + + * :ref:`sqlite3-placeholders` + * :ref:`sqlite3-adapters` + * :ref:`sqlite3-converters` + * :ref:`sqlite3-connection-context-manager` + * :ref:`sqlite3-howto-row-factory` + + * :ref:`sqlite3-explanation` for in-depth background on transaction control. + +.. _sqlite3-reference: + +Reference +--------- + +.. We keep the old sqlite3-module-contents ref to prevent breaking links. .. _sqlite3-module-contents: -Module functions and constants ------------------------------- +.. _sqlite3-module-functions: +Module functions +^^^^^^^^^^^^^^^^ + +.. function:: connect(database, timeout=5.0, detect_types=0, \ + isolation_level="DEFERRED", check_same_thread=True, \ + factory=sqlite3.Connection, cached_statements=128, \ + uri=False, \*, \ + autocommit=sqlite3.LEGACY_TRANSACTION_CONTROL) + + Open a connection to an SQLite database. + + :param database: + The path to the database file to be opened. + Pass ``":memory:"`` to open a connection to a database that is + in RAM instead of on disk. + :type database: :term:`path-like object` + + :param float timeout: + How many seconds the connection should wait before raising + an exception, if the database is locked by another connection. + If another connection opens a transaction to modify the database, + it will be locked until that transaction is committed. + Default five seconds. + + :param int detect_types: + Control whether and how data types not + :ref:`natively supported by SQLite ` + are looked up to be converted to Python types, + using the converters registered with :func:`register_converter`. + Set it to any combination (using ``|``, bitwise or) of + :const:`PARSE_DECLTYPES` and :const:`PARSE_COLNAMES` + to enable this. + Column names takes precedence over declared types if both flags are set. + Types cannot be detected for generated fields (for example ``max(data)``), + even when the *detect_types* parameter is set; :class:`str` will be + returned instead. + By default (``0``), type detection is disabled. + + :param isolation_level: + Control legacy transaction handling behaviour. + See :attr:`Connection.isolation_level` and + :ref:`sqlite3-transaction-control-isolation-level` for more information. + Can be ``"DEFERRED"`` (default), ``"EXCLUSIVE"`` or ``"IMMEDIATE"``; + or ``None`` to disable opening transactions implicitly. + Has no effect unless :attr:`Connection.autocommit` is set to + :data:`~sqlite3.LEGACY_TRANSACTION_CONTROL` (the default). + :type isolation_level: str | None + + :param bool check_same_thread: + If ``True`` (default), only the creating thread may use the connection. + If ``False``, the connection may be shared across multiple threads; + if so, write operations should be serialized by the user to avoid data + corruption. + + :param Connection factory: + A custom subclass of :class:`Connection` to create the connection with, + if not the default :class:`Connection` class. + + :param int cached_statements: + The number of statements that :mod:`!sqlite3` + should internally cache for this connection, to avoid parsing overhead. + By default, 128 statements. + + :param bool uri: + If set to ``True``, *database* is interpreted as a + :abbr:`URI (Uniform Resource Identifier)` with a file path + and an optional query string. + The scheme part *must* be ``"file:"``, + and the path can be relative or absolute. + The query string allows passing parameters to SQLite, + enabling various :ref:`sqlite3-uri-tricks`. + + :param autocommit: + Control :pep:`249` transaction handling behaviour. + See :attr:`Connection.autocommit` and + :ref:`sqlite3-transaction-control-autocommit` for more information. + *autocommit* currently defaults to + :data:`~sqlite3.LEGACY_TRANSACTION_CONTROL`. + The default will change to ``False`` in a future Python release. + :type autocommit: bool + + :rtype: Connection + + .. audit-event:: sqlite3.connect database sqlite3.connect + .. audit-event:: sqlite3.connect/handle connection_handle sqlite3.connect + + .. versionadded:: 3.4 + The *uri* parameter. + + .. versionchanged:: 3.7 + *database* can now also be a :term:`path-like object`, not only a string. + + .. versionadded:: 3.10 + The ``sqlite3.connect/handle`` auditing event. + + .. versionadded:: 3.12 + The *autocommit* parameter. + +.. function:: complete_statement(statement) + + Return ``True`` if the string *statement* appears to contain + one or more complete SQL statements. + No syntactic verification or parsing of any kind is performed, + other than checking that there are no unclosed string literals + and the statement is terminated by a semicolon. + + For example: + + .. doctest:: + + >>> sqlite3.complete_statement("SELECT foo FROM bar;") + True + >>> sqlite3.complete_statement("SELECT foo") + False + + This function may be useful during command-line input + to determine if the entered text seems to form a complete SQL statement, + or if additional input is needed before calling :meth:`~Cursor.execute`. + + See :func:`!runsource` in :source:`Lib/sqlite3/__main__.py` + for real-world use. + +.. function:: enable_callback_tracebacks(flag, /) + + Enable or disable callback tracebacks. + By default you will not get any tracebacks in user-defined functions, + aggregates, converters, authorizer callbacks etc. If you want to debug them, + you can call this function with *flag* set to ``True``. Afterwards, you + will get tracebacks from callbacks on :data:`sys.stderr`. Use ``False`` + to disable the feature again. + + Register an :func:`unraisable hook handler ` for an + improved debug experience: + + .. testsetup:: sqlite3.trace + + import sqlite3 + + .. doctest:: sqlite3.trace + + >>> sqlite3.enable_callback_tracebacks(True) + >>> con = sqlite3.connect(":memory:") + >>> def evil_trace(stmt): + ... 5/0 + ... + >>> con.set_trace_callback(evil_trace) + >>> def debug(unraisable): + ... print(f"{unraisable.exc_value!r} in callback {unraisable.object.__name__}") + ... print(f"Error message: {unraisable.err_msg}") + >>> import sys + >>> sys.unraisablehook = debug + >>> cur = con.execute("SELECT 1") + ZeroDivisionError('division by zero') in callback evil_trace + Error message: None + +.. function:: register_adapter(type, adapter, /) + + Register an *adapter* callable to adapt the Python type *type* into an + SQLite type. + The adapter is called with a Python object of type *type* as its sole + argument, and must return a value of a + :ref:`type that SQLite natively understands `. + +.. function:: register_converter(typename, converter, /) + + Register the *converter* callable to convert SQLite objects of type + *typename* into a Python object of a specific type. + The converter is invoked for all SQLite values of type *typename*; + it is passed a :class:`bytes` object and should return an object of the + desired Python type. + Consult the parameter *detect_types* of + :func:`connect` for information regarding how type detection works. + + Note: *typename* and the name of the type in your query are matched + case-insensitively. + + +.. _sqlite3-module-constants: + +Module constants +^^^^^^^^^^^^^^^^ + +.. data:: LEGACY_TRANSACTION_CONTROL + + Set :attr:`~Connection.autocommit` to this constant to select + old style (pre-Python 3.12) transaction control behaviour. + See :ref:`sqlite3-transaction-control-isolation-level` for more information. + +.. data:: PARSE_COLNAMES + + Pass this flag value to the *detect_types* parameter of + :func:`connect` to look up a converter function by + using the type name, parsed from the query column name, + as the converter dictionary key. + The type name must be wrapped in square brackets (``[]``). + + .. code-block:: sql + + SELECT p as "p [point]" FROM test; ! will look up converter "point" + + This flag may be combined with :const:`PARSE_DECLTYPES` using the ``|`` + (bitwise or) operator. + +.. data:: PARSE_DECLTYPES + + Pass this flag value to the *detect_types* parameter of + :func:`connect` to look up a converter function using + the declared types for each column. + The types are declared when the database table is created. + :mod:`!sqlite3` will look up a converter function using the first word of the + declared type as the converter dictionary key. + For example: + + .. code-block:: sql + + CREATE TABLE test( + i integer primary key, ! will look up a converter named "integer" + p point, ! will look up a converter named "point" + n number(10) ! will look up a converter named "number" + ) + + This flag may be combined with :const:`PARSE_COLNAMES` using the ``|`` + (bitwise or) operator. + +.. data:: SQLITE_OK + SQLITE_DENY + SQLITE_IGNORE + + Flags that should be returned by the *authorizer_callback* callable + passed to :meth:`Connection.set_authorizer`, to indicate whether: + + * Access is allowed (:const:`!SQLITE_OK`), + * The SQL statement should be aborted with an error (:const:`!SQLITE_DENY`) + * The column should be treated as a ``NULL`` value (:const:`!SQLITE_IGNORE`) .. data:: apilevel @@ -127,42 +496,26 @@ Module functions and constants .. data:: paramstyle String constant stating the type of parameter marker formatting expected by - the :mod:`sqlite3` module. Required by the DB-API. Hard-coded to + the :mod:`!sqlite3` module. Required by the DB-API. Hard-coded to ``"qmark"``. .. note:: - The :mod:`sqlite3` module supports both ``qmark`` and ``numeric`` DB-API - parameter styles, because that is what the underlying SQLite library - supports. However, the DB-API does not allow multiple values for - the ``paramstyle`` attribute. - -.. data:: version - - The version number of this module, as a string. This is not the version of - the SQLite library. - - -.. data:: version_info - - The version number of this module, as a tuple of integers. This is not the - version of the SQLite library. - + The ``named`` DB-API parameter style is also supported. .. data:: sqlite_version - The version number of the run-time SQLite library, as a string. - + Version number of the runtime SQLite library as a :class:`string `. .. data:: sqlite_version_info - The version number of the run-time SQLite library, as a tuple of integers. - + Version number of the runtime SQLite library as a :class:`tuple` of + :class:`integers `. .. data:: threadsafety Integer constant required by the DB-API 2.0, stating the level of thread - safety the :mod:`sqlite3` module supports. This attribute is set based on + safety the :mod:`!sqlite3` module supports. This attribute is set based on the default `threading mode `_ the underlying SQLite library is compiled with. The SQLite threading modes are: @@ -191,274 +544,360 @@ Module functions and constants | | | | connections and cursors | +------------------+-----------------+----------------------+-------------------------------+ - .. _threadsafety: https://www.python.org/dev/peps/pep-0249/#threadsafety + .. _threadsafety: https://peps.python.org/pep-0249/#threadsafety .. _SQLITE_THREADSAFE: https://sqlite.org/compile.html#threadsafe .. versionchanged:: 3.11 Set *threadsafety* dynamically instead of hard-coding it to ``1``. -.. data:: PARSE_DECLTYPES +.. data:: version - This constant is meant to be used with the *detect_types* parameter of the - :func:`connect` function. + Version number of this module as a :class:`string `. + This is not the version of the SQLite library. - Setting it makes the :mod:`sqlite3` module parse the declared type for each - column it returns. It will parse out the first word of the declared type, - i. e. for "integer primary key", it will parse out "integer", or for - "number(10)" it will parse out "number". Then for that column, it will look - into the converters dictionary and use the converter function registered for - that type there. + .. deprecated-removed:: 3.12 3.14 + This constant used to reflect the version number of the ``pysqlite`` + package, a third-party library which used to upstream changes to + :mod:`!sqlite3`. Today, it carries no meaning or practical value. +.. data:: version_info -.. data:: PARSE_COLNAMES + Version number of this module as a :class:`tuple` of :class:`integers `. + This is not the version of the SQLite library. - This constant is meant to be used with the *detect_types* parameter of the - :func:`connect` function. - - Setting this makes the SQLite interface parse the column name for each column it - returns. It will look for a string formed [mytype] in there, and then decide - that 'mytype' is the type of the column. It will try to find an entry of - 'mytype' in the converters dictionary and then use the converter function found - there to return the value. The column name found in :attr:`Cursor.description` - does not include the type, i. e. if you use something like - ``'as "Expiration date [datetime]"'`` in your SQL, then we will parse out - everything until the first ``'['`` for the column name and strip - the preceding space: the column name would simply be "Expiration date". - - -.. function:: connect(database[, timeout, detect_types, isolation_level, check_same_thread, factory, cached_statements, uri]) - - Opens a connection to the SQLite database file *database*. By default returns a - :class:`Connection` object, unless a custom *factory* is given. - - *database* is a :term:`path-like object` giving the pathname (absolute or - relative to the current working directory) of the database file to be opened. - You can use ``":memory:"`` to open a database connection to a database that - resides in RAM instead of on disk. - - When a database is accessed by multiple connections, and one of the processes - modifies the database, the SQLite database is locked until that transaction is - committed. The *timeout* parameter specifies how long the connection should wait - for the lock to go away until raising an exception. The default for the timeout - parameter is 5.0 (five seconds). - - For the *isolation_level* parameter, please see the - :attr:`~Connection.isolation_level` property of :class:`Connection` objects. - - SQLite natively supports only the types TEXT, INTEGER, REAL, BLOB and NULL. If - you want to use other types you must add support for them yourself. The - *detect_types* parameter and the using custom **converters** registered with the - module-level :func:`register_converter` function allow you to easily do that. - - *detect_types* defaults to 0 (i. e. off, no type detection), you can set it to - any combination of :const:`PARSE_DECLTYPES` and :const:`PARSE_COLNAMES` to turn - type detection on. Due to SQLite behaviour, types can't be detected for generated - fields (for example ``max(data)``), even when *detect_types* parameter is set. In - such case, the returned type is :class:`str`. - - By default, *check_same_thread* is :const:`True` and only the creating thread may - use the connection. If set :const:`False`, the returned connection may be shared - across multiple threads. When using multiple threads with the same connection - writing operations should be serialized by the user to avoid data corruption. - - By default, the :mod:`sqlite3` module uses its :class:`Connection` class for the - connect call. You can, however, subclass the :class:`Connection` class and make - :func:`connect` use your class instead by providing your class for the *factory* - parameter. - - Consult the section :ref:`sqlite3-types` of this manual for details. - - The :mod:`sqlite3` module internally uses a statement cache to avoid SQL parsing - overhead. If you want to explicitly set the number of statements that are cached - for the connection, you can set the *cached_statements* parameter. The currently - implemented default is to cache 128 statements. - - If *uri* is true, *database* is interpreted as a URI. This allows you - to specify options. For example, to open a database in read-only mode - you can use:: - - db = sqlite3.connect('file:path/to/database?mode=ro', uri=True) - - More information about this feature, including a list of recognized options, can - be found in the `SQLite URI documentation `_. - - .. audit-event:: sqlite3.connect database sqlite3.connect - .. audit-event:: sqlite3.connect/handle connection_handle sqlite3.connect - - .. versionchanged:: 3.4 - Added the *uri* parameter. - - .. versionchanged:: 3.7 - *database* can now also be a :term:`path-like object`, not only a string. - - .. versionchanged:: 3.10 - Added the ``sqlite3.connect/handle`` auditing event. - - -.. function:: register_converter(typename, callable) - - Registers a callable to convert a bytestring from the database into a custom - Python type. The callable will be invoked for all database values that are of - the type *typename*. Confer the parameter *detect_types* of the :func:`connect` - function for how the type detection works. Note that *typename* and the name of - the type in your query are matched in case-insensitive manner. - - -.. function:: register_adapter(type, callable) - - Registers a callable to convert the custom Python type *type* into one of - SQLite's supported types. The callable *callable* accepts as single parameter - the Python value, and must return a value of the following types: int, - float, str or bytes. - - -.. function:: complete_statement(sql) - - Returns :const:`True` if the string *sql* contains one or more complete SQL - statements terminated by semicolons. It does not verify that the SQL is - syntactically correct, only that there are no unclosed string literals and the - statement is terminated by a semicolon. - - This can be used to build a shell for SQLite, as in the following example: - - - .. literalinclude:: ../includes/sqlite3/complete_statement.py - - -.. function:: enable_callback_tracebacks(flag) - - By default you will not get any tracebacks in user-defined functions, - aggregates, converters, authorizer callbacks etc. If you want to debug them, - you can call this function with *flag* set to ``True``. Afterwards, you will - get tracebacks from callbacks on ``sys.stderr``. Use :const:`False` to - disable the feature again. + .. deprecated-removed:: 3.12 3.14 + This constant used to reflect the version number of the ``pysqlite`` + package, a third-party library which used to upstream changes to + :mod:`!sqlite3`. Today, it carries no meaning or practical value. .. _sqlite3-connection-objects: -Connection Objects ------------------- +Connection objects +^^^^^^^^^^^^^^^^^^ .. class:: Connection - A SQLite database connection has the following attributes and methods: + Each open SQLite database is represented by a ``Connection`` object, + which is created using :func:`sqlite3.connect`. + Their main purpose is creating :class:`Cursor` objects, + and :ref:`sqlite3-controlling-transactions`. - .. attribute:: isolation_level + .. seealso:: - Get or set the current default isolation level. :const:`None` for autocommit mode or - one of "DEFERRED", "IMMEDIATE" or "EXCLUSIVE". See section - :ref:`sqlite3-controlling-transactions` for a more detailed explanation. + * :ref:`sqlite3-connection-shortcuts` + * :ref:`sqlite3-connection-context-manager` - .. attribute:: in_transaction - - :const:`True` if a transaction is active (there are uncommitted changes), - :const:`False` otherwise. Read-only attribute. - - .. versionadded:: 3.2 + An SQLite database connection has the following attributes and methods: .. method:: cursor(factory=Cursor) + Create and return a :class:`Cursor` object. The cursor method accepts a single optional parameter *factory*. If supplied, this must be a callable returning an instance of :class:`Cursor` or its subclasses. + .. method:: blobopen(table, column, row, /, *, readonly=False, name="main") + + Open a :class:`Blob` handle to an existing + :abbr:`BLOB (Binary Large OBject)`. + + :param str table: + The name of the table where the blob is located. + + :param str column: + The name of the column where the blob is located. + + :param str row: + The name of the row where the blob is located. + + :param bool readonly: + Set to ``True`` if the blob should be opened without write + permissions. + Defaults to ``False``. + + :param str name: + The name of the database where the blob is located. + Defaults to ``"main"``. + + :raises OperationalError: + When trying to open a blob in a ``WITHOUT ROWID`` table. + + :rtype: Blob + + .. note:: + + The blob size cannot be changed using the :class:`Blob` class. + Use the SQL function ``zeroblob`` to create a blob with a fixed size. + + .. versionadded:: 3.11 + .. method:: commit() - This method commits the current transaction. If you don't call this method, - anything you did since the last call to ``commit()`` is not visible from - other database connections. If you wonder why you don't see the data you've - written to the database, please check you didn't forget to call this method. + Commit any pending transaction to the database. + If :attr:`autocommit` is ``True``, or there is no open transaction, + this method does nothing. + If :attr:`!autocommit` is ``False``, a new transaction is implicitly + opened if a pending transaction was committed by this method. .. method:: rollback() - This method rolls back any changes to the database since the last call to - :meth:`commit`. + Roll back to the start of any pending transaction. + If :attr:`autocommit` is ``True``, or there is no open transaction, + this method does nothing. + If :attr:`!autocommit` is ``False``, a new transaction is implicitly + opened if a pending transaction was rolled back by this method. .. method:: close() - This closes the database connection. Note that this does not automatically - call :meth:`commit`. If you just close your database connection without - calling :meth:`commit` first, your changes will be lost! + Close the database connection. + If :attr:`autocommit` is ``False``, + any pending transaction is implicitly rolled back. + If :attr:`!autocommit` is ``True`` or :data:`LEGACY_TRANSACTION_CONTROL`, + no implicit transaction control is executed. + Make sure to :meth:`commit` before closing + to avoid losing pending changes. - .. method:: execute(sql[, parameters]) + .. method:: execute(sql, parameters=(), /) - This is a nonstandard shortcut that creates a cursor object by calling - the :meth:`~Connection.cursor` method, calls the cursor's - :meth:`~Cursor.execute` method with the *parameters* given, and returns - the cursor. + Create a new :class:`Cursor` object and call + :meth:`~Cursor.execute` on it with the given *sql* and *parameters*. + Return the new cursor object. - .. method:: executemany(sql[, parameters]) + .. method:: executemany(sql, parameters, /) - This is a nonstandard shortcut that creates a cursor object by - calling the :meth:`~Connection.cursor` method, calls the cursor's - :meth:`~Cursor.executemany` method with the *parameters* given, and - returns the cursor. + Create a new :class:`Cursor` object and call + :meth:`~Cursor.executemany` on it with the given *sql* and *parameters*. + Return the new cursor object. - .. method:: executescript(sql_script) + .. method:: executescript(sql_script, /) - This is a nonstandard shortcut that creates a cursor object by - calling the :meth:`~Connection.cursor` method, calls the cursor's - :meth:`~Cursor.executescript` method with the given *sql_script*, and - returns the cursor. + Create a new :class:`Cursor` object and call + :meth:`~Cursor.executescript` on it with the given *sql_script*. + Return the new cursor object. - .. method:: create_function(name, num_params, func, *, deterministic=False) + .. method:: create_function(name, narg, func, *, deterministic=False) - Creates a user-defined function that you can later use from within SQL - statements under the function name *name*. *num_params* is the number of - parameters the function accepts (if *num_params* is -1, the function may - take any number of arguments), and *func* is a Python callable that is - called as the SQL function. If *deterministic* is true, the created function - is marked as `deterministic `_, which - allows SQLite to perform additional optimizations. This flag is supported by - SQLite 3.8.3 or higher, :exc:`NotSupportedError` will be raised if used - with older versions. + Create or remove a user-defined SQL function. - The function can return any of the types supported by SQLite: bytes, str, int, - float and ``None``. + :param str name: + The name of the SQL function. - .. versionchanged:: 3.8 - The *deterministic* parameter was added. + :param int narg: + The number of arguments the SQL function can accept. + If ``-1``, it may take any number of arguments. + + :param func: + A callable that is called when the SQL function is invoked. + The callable must return :ref:`a type natively supported by SQLite + `. + Set to ``None`` to remove an existing SQL function. + :type func: :term:`callback` | None + + :param bool deterministic: + If ``True``, the created SQL function is marked as + `deterministic `_, + which allows SQLite to perform additional optimizations. + + :raises NotSupportedError: + If *deterministic* is used with SQLite versions older than 3.8.3. + + .. versionadded:: 3.8 + The *deterministic* parameter. Example: - .. literalinclude:: ../includes/sqlite3/md5func.py + .. doctest:: + + >>> import hashlib + >>> def md5sum(t): + ... return hashlib.md5(t).hexdigest() + >>> con = sqlite3.connect(":memory:") + >>> con.create_function("md5", 1, md5sum) + >>> for row in con.execute("SELECT md5(?)", (b"foo",)): + ... print(row) + ('acbd18db4cc2f85cedef654fccc4a4d8',) - .. method:: create_aggregate(name, num_params, aggregate_class) + .. method:: create_aggregate(name, /, n_arg, aggregate_class) - Creates a user-defined aggregate function. + Create or remove a user-defined SQL aggregate function. - The aggregate class must implement a ``step`` method, which accepts the number - of parameters *num_params* (if *num_params* is -1, the function may take - any number of arguments), and a ``finalize`` method which will return the - final result of the aggregate. + :param str name: + The name of the SQL aggregate function. - The ``finalize`` method can return any of the types supported by SQLite: - bytes, str, int, float and ``None``. + :param int n_arg: + The number of arguments the SQL aggregate function can accept. + If ``-1``, it may take any number of arguments. + + :param aggregate_class: + A class must implement the following methods: + + * ``step()``: Add a row to the aggregate. + * ``finalize()``: Return the final result of the aggregate as + :ref:`a type natively supported by SQLite `. + + The number of arguments that the ``step()`` method must accept + is controlled by *n_arg*. + + Set to ``None`` to remove an existing SQL aggregate function. + :type aggregate_class: :term:`class` | None Example: - .. literalinclude:: ../includes/sqlite3/mysumaggr.py + .. testcode:: + class MySum: + def __init__(self): + self.count = 0 + + def step(self, value): + self.count += value + + def finalize(self): + return self.count + + con = sqlite3.connect(":memory:") + con.create_aggregate("mysum", 1, MySum) + cur = con.execute("CREATE TABLE test(i)") + cur.execute("INSERT INTO test(i) VALUES(1)") + cur.execute("INSERT INTO test(i) VALUES(2)") + cur.execute("SELECT mysum(i) FROM test") + print(cur.fetchone()[0]) + + con.close() + + .. testoutput:: + :hide: + + 3 + + + .. method:: create_window_function(name, num_params, aggregate_class, /) + + Create or remove a user-defined aggregate window function. + + :param str name: + The name of the SQL aggregate window function to create or remove. + + :param int num_params: + The number of arguments the SQL aggregate window function can accept. + If ``-1``, it may take any number of arguments. + + :param aggregate_class: + A class that must implement the following methods: + + * ``step()``: Add a row to the current window. + * ``value()``: Return the current value of the aggregate. + * ``inverse()``: Remove a row from the current window. + * ``finalize()``: Return the final result of the aggregate as + :ref:`a type natively supported by SQLite `. + + The number of arguments that the ``step()`` and ``value()`` methods + must accept is controlled by *num_params*. + + Set to ``None`` to remove an existing SQL aggregate window function. + + :raises NotSupportedError: + If used with a version of SQLite older than 3.25.0, + which does not support aggregate window functions. + + :type aggregate_class: :term:`class` | None + + .. versionadded:: 3.11 + + Example: + + .. testcode:: + + # Example taken from https://www.sqlite.org/windowfunctions.html#udfwinfunc + class WindowSumInt: + def __init__(self): + self.count = 0 + + def step(self, value): + """Add a row to the current window.""" + self.count += value + + def value(self): + """Return the current value of the aggregate.""" + return self.count + + def inverse(self, value): + """Remove a row from the current window.""" + self.count -= value + + def finalize(self): + """Return the final value of the aggregate. + + Any clean-up actions should be placed here. + """ + return self.count + + + con = sqlite3.connect(":memory:") + cur = con.execute("CREATE TABLE test(x, y)") + values = [ + ("a", 4), + ("b", 5), + ("c", 3), + ("d", 8), + ("e", 1), + ] + cur.executemany("INSERT INTO test VALUES(?, ?)", values) + con.create_window_function("sumint", 1, WindowSumInt) + cur.execute(""" + SELECT x, sumint(y) OVER ( + ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING + ) AS sum_y + FROM test ORDER BY x + """) + print(cur.fetchall()) + + .. testoutput:: + :hide: + + [('a', 9), ('b', 12), ('c', 16), ('d', 12), ('e', 9)] .. method:: create_collation(name, callable) - Creates a collation with the specified *name* and *callable*. The callable will - be passed two string arguments. It should return -1 if the first is ordered - lower than the second, 0 if they are ordered equal and 1 if the first is ordered - higher than the second. Note that this controls sorting (ORDER BY in SQL) so - your comparisons don't affect other SQL operations. + Create a collation named *name* using the collating function *callable*. + *callable* is passed two :class:`string ` arguments, + and it should return an :class:`integer `: - Note that the callable will get its parameters as Python bytestrings, which will - normally be encoded in UTF-8. + * ``1`` if the first is ordered higher than the second + * ``-1`` if the first is ordered lower than the second + * ``0`` if they are ordered equal - The following example shows a custom collation that sorts "the wrong way": + The following example shows a reverse sorting collation: - .. literalinclude:: ../includes/sqlite3/collation_reverse.py + .. testcode:: - To remove a collation, call ``create_collation`` with ``None`` as callable:: + def collate_reverse(string1, string2): + if string1 == string2: + return 0 + elif string1 < string2: + return 1 + else: + return -1 - con.create_collation("reverse", None) + con = sqlite3.connect(":memory:") + con.create_collation("reverse", collate_reverse) + + cur = con.execute("CREATE TABLE test(x)") + cur.executemany("INSERT INTO test(x) VALUES(?)", [("a",), ("b",)]) + cur.execute("SELECT x FROM test ORDER BY x COLLATE reverse") + for row in cur: + print(row) + con.close() + + .. testoutput:: + :hide: + + ('b',) + ('a',) + + Remove a collation function by setting *callable* to ``None``. .. versionchanged:: 3.11 The collation name can contain any Unicode character. Earlier, only @@ -467,66 +906,65 @@ Connection Objects .. method:: interrupt() - You can call this method from a different thread to abort any queries that might - be executing on the connection. The query will then abort and the caller will - get an exception. + Call this method from a different thread to abort any queries that might + be executing on the connection. + Aborted queries will raise an exception. .. method:: set_authorizer(authorizer_callback) - This routine registers a callback. The callback is invoked for each attempt to + Register callable *authorizer_callback* to be invoked for each attempt to access a column of a table in the database. The callback should return - :const:`SQLITE_OK` if access is allowed, :const:`SQLITE_DENY` if the entire SQL - statement should be aborted with an error and :const:`SQLITE_IGNORE` if the - column should be treated as a NULL value. These constants are available in the - :mod:`sqlite3` module. + one of :const:`SQLITE_OK`, :const:`SQLITE_DENY`, or :const:`SQLITE_IGNORE` + to signal how access to the column should be handled + by the underlying SQLite library. The first argument to the callback signifies what kind of operation is to be - authorized. The second and third argument will be arguments or :const:`None` + authorized. The second and third argument will be arguments or ``None`` depending on the first argument. The 4th argument is the name of the database ("main", "temp", etc.) if applicable. The 5th argument is the name of the inner-most trigger or view that is responsible for the access attempt or - :const:`None` if this access attempt is directly from input SQL code. + ``None`` if this access attempt is directly from input SQL code. Please consult the SQLite documentation about the possible values for the first argument and the meaning of the second and third argument depending on the first - one. All necessary constants are available in the :mod:`sqlite3` module. + one. All necessary constants are available in the :mod:`!sqlite3` module. - Passing :const:`None` as *authorizer_callback* will disable the authorizer. + Passing ``None`` as *authorizer_callback* will disable the authorizer. .. versionchanged:: 3.11 - Added support for disabling the authorizer using :const:`None`. + Added support for disabling the authorizer using ``None``. - .. method:: set_progress_handler(handler, n) + .. method:: set_progress_handler(progress_handler, n) - This routine registers a callback. The callback is invoked for every *n* + Register callable *progress_handler* to be invoked for every *n* instructions of the SQLite virtual machine. This is useful if you want to get called from SQLite during long-running operations, for example to update a GUI. If you want to clear any previously installed progress handler, call the - method with :const:`None` for *handler*. + method with ``None`` for *progress_handler*. Returning a non-zero value from the handler function will terminate the - currently executing query and cause it to raise an :exc:`OperationalError` + currently executing query and cause it to raise a :exc:`DatabaseError` exception. .. method:: set_trace_callback(trace_callback) - Registers *trace_callback* to be called for each SQL statement that is - actually executed by the SQLite backend. + Register callable *trace_callback* to be invoked for each SQL statement + that is actually executed by the SQLite backend. The only argument passed to the callback is the statement (as :class:`str`) that is being executed. The return value of the callback is ignored. Note that the backend does not only run statements passed to the :meth:`Cursor.execute` methods. Other sources include the :ref:`transaction management ` of the - sqlite3 module and the execution of triggers defined in the current + :mod:`!sqlite3` module and the execution of triggers defined in the current database. - Passing :const:`None` as *trace_callback* will disable the trace callback. + Passing ``None`` as *trace_callback* will disable the trace callback. .. note:: Exceptions raised in the trace callback are not propagated. As a @@ -537,94 +975,94 @@ Connection Objects .. versionadded:: 3.3 - .. method:: enable_load_extension(enabled) + .. method:: enable_load_extension(enabled, /) - This routine allows/disallows the SQLite engine to load SQLite extensions - from shared libraries. SQLite extensions can define new functions, + Enable the SQLite engine to load SQLite extensions from shared libraries + if *enabled* is ``True``; + else, disallow loading SQLite extensions. + SQLite extensions can define new functions, aggregates or whole new virtual table implementations. One well-known extension is the fulltext-search extension distributed with SQLite. - Loadable extensions are disabled by default. See [#f1]_. + .. note:: - .. audit-event:: sqlite3.enable_load_extension connection,enabled sqlite3.enable_load_extension + The :mod:`!sqlite3` module is not built with loadable extension support by + default, because some platforms (notably macOS) have SQLite + libraries which are compiled without this feature. + To get loadable extension support, + you must pass the :option:`--enable-loadable-sqlite-extensions` option + to :program:`configure`. + + .. audit-event:: sqlite3.enable_load_extension connection,enabled sqlite3.Connection.enable_load_extension .. versionadded:: 3.2 .. versionchanged:: 3.10 Added the ``sqlite3.enable_load_extension`` auditing event. - .. literalinclude:: ../includes/sqlite3/load_extension.py + .. testsetup:: sqlite3.loadext - .. method:: load_extension(path) + import sqlite3 + con = sqlite3.connect(":memory:") - This routine loads a SQLite extension from a shared library. You have to - enable extension loading with :meth:`enable_load_extension` before you can - use this routine. + .. testcode:: sqlite3.loadext + :skipif: True # not testable at the moment - Loadable extensions are disabled by default. See [#f1]_. + con.enable_load_extension(True) - .. audit-event:: sqlite3.load_extension connection,path sqlite3.load_extension + # Load the fulltext search extension + con.execute("select load_extension('./fts3.so')") + + # alternatively you can load the extension using an API call: + # con.load_extension("./fts3.so") + + # disable extension loading again + con.enable_load_extension(False) + + # example from SQLite wiki + con.execute("CREATE VIRTUAL TABLE recipe USING fts3(name, ingredients)") + con.executescript(""" + INSERT INTO recipe (name, ingredients) VALUES('broccoli stew', 'broccoli peppers cheese tomatoes'); + INSERT INTO recipe (name, ingredients) VALUES('pumpkin stew', 'pumpkin onions garlic celery'); + INSERT INTO recipe (name, ingredients) VALUES('broccoli pie', 'broccoli cheese onions flour'); + INSERT INTO recipe (name, ingredients) VALUES('pumpkin pie', 'pumpkin sugar flour butter'); + """) + for row in con.execute("SELECT rowid, name, ingredients FROM recipe WHERE name MATCH 'pie'"): + print(row) + + con.close() + + .. testoutput:: sqlite3.loadext + :hide: + + (2, 'broccoli pie', 'broccoli cheese onions flour') + (3, 'pumpkin pie', 'pumpkin sugar flour butter') + + .. method:: load_extension(path, /) + + Load an SQLite extension from a shared library located at *path*. + Enable extension loading with :meth:`enable_load_extension` before + calling this method. + + .. audit-event:: sqlite3.load_extension connection,path sqlite3.Connection.load_extension .. versionadded:: 3.2 .. versionchanged:: 3.10 Added the ``sqlite3.load_extension`` auditing event. - .. attribute:: row_factory + .. method:: iterdump - You can change this attribute to a callable that accepts the cursor and the - original row as a tuple and will return the real result row. This way, you can - implement more advanced ways of returning results, such as returning an object - that can also access columns by name. + Return an :term:`iterator` to dump the database as SQL source code. + Useful when saving an in-memory database for later restoration. + Similar to the ``.dump`` command in the :program:`sqlite3` shell. Example: - .. literalinclude:: ../includes/sqlite3/row_factory.py + .. testcode:: - If returning a tuple doesn't suffice and you want name-based access to - columns, you should consider setting :attr:`row_factory` to the - highly-optimized :class:`sqlite3.Row` type. :class:`Row` provides both - index-based and case-insensitive name-based access to columns with almost no - memory overhead. It will probably be better than your own custom - dictionary-based approach or even a db_row based solution. - - .. XXX what's a db_row-based solution? - - - .. attribute:: text_factory - - Using this attribute you can control what objects are returned for the ``TEXT`` - data type. By default, this attribute is set to :class:`str` and the - :mod:`sqlite3` module will return :class:`str` objects for ``TEXT``. - If you want to return :class:`bytes` instead, you can set it to :class:`bytes`. - - You can also set it to any other callable that accepts a single bytestring - parameter and returns the resulting object. - - See the following example code for illustration: - - .. literalinclude:: ../includes/sqlite3/text_factory.py - - - .. attribute:: total_changes - - Returns the total number of database rows that have been modified, inserted, or - deleted since the database connection was opened. - - - .. method:: iterdump - - Returns an iterator to dump the database in an SQL text format. Useful when - saving an in-memory database for later restoration. This function provides - the same capabilities as the :kbd:`.dump` command in the :program:`sqlite3` - shell. - - Example:: - - # Convert file existing_db.db to SQL dump file dump.sql - import sqlite3 - - con = sqlite3.connect('existing_db.db') + # Convert file example.db to SQL dump file dump.sql + con = sqlite3.connect('example.db') with open('dump.sql', 'w') as f: for line in con.iterdump(): f.write('%s\n' % line) @@ -633,93 +1071,340 @@ Connection Objects .. method:: backup(target, *, pages=-1, progress=None, name="main", sleep=0.250) - This method makes a backup of a SQLite database even while it's being accessed - by other clients, or concurrently by the same connection. The copy will be - written into the mandatory argument *target*, that must be another - :class:`Connection` instance. + Create a backup of an SQLite database. - By default, or when *pages* is either ``0`` or a negative integer, the entire - database is copied in a single step; otherwise the method performs a loop - copying up to *pages* pages at a time. + Works even if the database is being accessed by other clients + or concurrently by the same connection. - If *progress* is specified, it must either be ``None`` or a callable object that - will be executed at each iteration with three integer arguments, respectively - the *status* of the last iteration, the *remaining* number of pages still to be - copied and the *total* number of pages. + :param Connection target: + The database connection to save the backup to. - The *name* argument specifies the database name that will be copied: it must be - a string containing either ``"main"``, the default, to indicate the main - database, ``"temp"`` to indicate the temporary database or the name specified - after the ``AS`` keyword in an ``ATTACH DATABASE`` statement for an attached - database. + :param int pages: + The number of pages to copy at a time. + If equal to or less than ``0``, + the entire database is copied in a single step. + Defaults to ``-1``. - The *sleep* argument specifies the number of seconds to sleep by between - successive attempts to backup remaining pages, can be specified either as an - integer or a floating point value. + :param progress: + If set to a callable, it is invoked with three integer arguments for + every backup iteration: + the *status* of the last iteration, + the *remaining* number of pages still to be copied, + and the *total* number of pages. + Defaults to ``None``. + :type progress: :term:`callback` | None - Example 1, copy an existing database into another:: + :param str name: + The name of the database to back up. + Either ``"main"`` (the default) for the main database, + ``"temp"`` for the temporary database, + or the name of a custom database as attached using the + ``ATTACH DATABASE`` SQL statement. - import sqlite3 + :param float sleep: + The number of seconds to sleep between successive attempts + to back up remaining pages. + + Example 1, copy an existing database into another: + + .. testcode:: def progress(status, remaining, total): print(f'Copied {total-remaining} of {total} pages...') - con = sqlite3.connect('existing_db.db') - bck = sqlite3.connect('backup.db') - with bck: - con.backup(bck, pages=1, progress=progress) - bck.close() - con.close() + src = sqlite3.connect('example.db') + dst = sqlite3.connect('backup.db') + with dst: + src.backup(dst, pages=1, progress=progress) + dst.close() + src.close() - Example 2, copy an existing database into a transient copy:: + .. testoutput:: + :hide: - import sqlite3 + Copied 0 of 0 pages... - source = sqlite3.connect('existing_db.db') - dest = sqlite3.connect(':memory:') - source.backup(dest) + Example 2, copy an existing database into a transient copy: + + .. testcode:: + + src = sqlite3.connect('example.db') + dst = sqlite3.connect(':memory:') + src.backup(dst) .. versionadded:: 3.7 - .. method:: getlimit(category, /) - Get a connection run-time limit. *category* is the limit category to be - queried. + Get a connection runtime limit. - Example, query the maximum length of an SQL statement:: + :param int category: + The `SQLite limit category`_ to be queried. + + :rtype: int + + :raises ProgrammingError: + If *category* is not recognised by the underlying SQLite library. + + Example, query the maximum length of an SQL statement + for :class:`Connection` ``con`` (the default is 1000000000): + + .. testsetup:: sqlite3.limits import sqlite3 con = sqlite3.connect(":memory:") - lim = con.getlimit(sqlite3.SQLITE_LIMIT_SQL_LENGTH) - print(f"SQLITE_LIMIT_SQL_LENGTH={lim}") + con.setlimit(sqlite3.SQLITE_LIMIT_SQL_LENGTH, 1_000_000_000) + con.setlimit(sqlite3.SQLITE_LIMIT_ATTACHED, 10) + + .. doctest:: sqlite3.limits + + >>> con.getlimit(sqlite3.SQLITE_LIMIT_SQL_LENGTH) + 1000000000 .. versionadded:: 3.11 .. method:: setlimit(category, limit, /) - Set a connection run-time limit. *category* is the limit category to be - set. *limit* is the new limit. If the new limit is a negative number, the - limit is unchanged. - + Set a connection runtime limit. Attempts to increase a limit above its hard upper bound are silently truncated to the hard upper bound. Regardless of whether or not the limit was changed, the prior value of the limit is returned. - Example, limit the number of attached databases to 1:: + :param int category: + The `SQLite limit category`_ to be set. - import sqlite3 - con = sqlite3.connect(":memory:") - con.setlimit(sqlite3.SQLITE_LIMIT_ATTACHED, 1) + :param int limit: + The value of the new limit. + If negative, the current limit is unchanged. + + :rtype: int + + :raises ProgrammingError: + If *category* is not recognised by the underlying SQLite library. + + Example, limit the number of attached databases to 1 + for :class:`Connection` ``con`` (the default limit is 10): + + .. doctest:: sqlite3.limits + + >>> con.setlimit(sqlite3.SQLITE_LIMIT_ATTACHED, 1) + 10 + >>> con.getlimit(sqlite3.SQLITE_LIMIT_ATTACHED) + 1 + + .. versionadded:: 3.11 + + .. _SQLite limit category: https://www.sqlite.org/c3ref/c_limit_attached.html + + + .. method:: serialize(*, name="main") + + Serialize a database into a :class:`bytes` object. For an + ordinary on-disk database file, the serialization is just a copy of the + disk file. For an in-memory database or a "temp" database, the + serialization is the same sequence of bytes which would be written to + disk if that database were backed up to disk. + + :param str name: + The database name to be serialized. + Defaults to ``"main"``. + + :rtype: bytes + + .. note:: + + This method is only available if the underlying SQLite library has the + serialize API. .. versionadded:: 3.11 + .. method:: deserialize(data, /, *, name="main") + + Deserialize a :meth:`serialized ` database into a + :class:`Connection`. + This method causes the database connection to disconnect from database + *name*, and reopen *name* as an in-memory database based on the + serialization contained in *data*. + + :param bytes data: + A serialized database. + + :param str name: + The database name to deserialize into. + Defaults to ``"main"``. + + :raises OperationalError: + If the database connection is currently involved in a read + transaction or a backup operation. + + :raises DatabaseError: + If *data* does not contain a valid SQLite database. + + :raises OverflowError: + If :func:`len(data) ` is larger than ``2**63 - 1``. + + .. note:: + + This method is only available if the underlying SQLite library has the + deserialize API. + + .. versionadded:: 3.11 + + .. attribute:: autocommit + + This attribute controls :pep:`249`-compliant transaction behaviour. + :attr:`!autocommit` has three allowed values: + + * ``False``: Select :pep:`249`-compliant transaction behaviour, + implying that :mod:`!sqlite3` ensures a transaction is always open. + Use :meth:`commit` and :meth:`rollback` to close transactions. + + This is the recommended value of :attr:`!autocommit`. + + * ``True``: Use SQLite's `autocommit mode`_. + :meth:`commit` and :meth:`rollback` have no effect in this mode. + + * :data:`LEGACY_TRANSACTION_CONTROL`: + Pre-Python 3.12 (non-:pep:`249`-compliant) transaction control. + See :attr:`isolation_level` for more details. + + This is currently the default value of :attr:`!autocommit`. + + Changing :attr:`!autocommit` to ``False`` will open a new transaction, + and changing it to ``True`` will commit any pending transaction. + + See :ref:`sqlite3-transaction-control-autocommit` for more details. + + .. note:: + + The :attr:`isolation_level` attribute has no effect unless + :attr:`autocommit` is :data:`LEGACY_TRANSACTION_CONTROL`. + + .. versionadded:: 3.12 + + .. attribute:: in_transaction + + This read-only attribute corresponds to the low-level SQLite + `autocommit mode`_. + + ``True`` if a transaction is active (there are uncommitted changes), + ``False`` otherwise. + + .. versionadded:: 3.2 + + .. attribute:: isolation_level + + Controls the :ref:`legacy transaction handling mode + ` of :mod:`!sqlite3`. + If set to ``None``, transactions are never implicitly opened. + If set to one of ``"DEFERRED"``, ``"IMMEDIATE"``, or ``"EXCLUSIVE"``, + corresponding to the underlying `SQLite transaction behaviour`_, + :ref:`implicit transaction management + ` is performed. + + If not overridden by the *isolation_level* parameter of :func:`connect`, + the default is ``""``, which is an alias for ``"DEFERRED"``. + + .. note:: + + Using :attr:`autocommit` to control transaction handling is + recommended over using :attr:`!isolation_level`. + :attr:`!isolation_level` has no effect unless :attr:`autocommit` is + set to :data:`LEGACY_TRANSACTION_CONTROL` (the default). + + .. attribute:: row_factory + + The initial :attr:`~Cursor.row_factory` + for :class:`Cursor` objects created from this connection. + Assigning to this attribute does not affect the :attr:`!row_factory` + of existing cursors belonging to this connection, only new ones. + Is ``None`` by default, + meaning each row is returned as a :class:`tuple`. + + See :ref:`sqlite3-howto-row-factory` for more details. + + .. attribute:: text_factory + + A callable that accepts a :class:`bytes` parameter and returns a text + representation of it. + The callable is invoked for SQLite values with the ``TEXT`` data type. + By default, this attribute is set to :class:`str`. + If you want to return ``bytes`` instead, set *text_factory* to ``bytes``. + + Example: + + .. testcode:: + + con = sqlite3.connect(":memory:") + cur = con.cursor() + + AUSTRIA = "Österreich" + + # by default, rows are returned as str + cur.execute("SELECT ?", (AUSTRIA,)) + row = cur.fetchone() + assert row[0] == AUSTRIA + + # but we can make sqlite3 always return bytestrings ... + con.text_factory = bytes + cur.execute("SELECT ?", (AUSTRIA,)) + row = cur.fetchone() + assert type(row[0]) is bytes + # the bytestrings will be encoded in UTF-8, unless you stored garbage in the + # database ... + assert row[0] == AUSTRIA.encode("utf-8") + + # we can also implement a custom text_factory ... + # here we implement one that appends "foo" to all strings + con.text_factory = lambda x: x.decode("utf-8") + "foo" + cur.execute("SELECT ?", ("bar",)) + row = cur.fetchone() + assert row[0] == "barfoo" + + con.close() + + .. attribute:: total_changes + + Return the total number of database rows that have been modified, inserted, or + deleted since the database connection was opened. + + .. _sqlite3-cursor-objects: -Cursor Objects --------------- +Cursor objects +^^^^^^^^^^^^^^ + + A ``Cursor`` object represents a `database cursor`_ + which is used to execute SQL statements, + and manage the context of a fetch operation. + Cursors are created using :meth:`Connection.cursor`, + or by using any of the :ref:`connection shortcut methods + `. + + Cursor objects are :term:`iterators `, + meaning that if you :meth:`~Cursor.execute` a ``SELECT`` query, + you can simply iterate over the cursor to fetch the resulting rows: + + .. testsetup:: sqlite3.cursor + + import sqlite3 + con = sqlite3.connect(":memory:", isolation_level=None) + cur = con.execute("CREATE TABLE data(t)") + cur.execute("INSERT INTO data VALUES(1)") + + .. testcode:: sqlite3.cursor + + for row in cur.execute("SELECT t FROM data"): + print(row) + + .. testoutput:: sqlite3.cursor + :hide: + + (1,) + + .. _database cursor: https://en.wikipedia.org/wiki/Cursor_(databases) .. class:: Cursor @@ -728,61 +1413,89 @@ Cursor Objects .. index:: single: ? (question mark); in SQL statements .. index:: single: : (colon); in SQL statements - .. method:: execute(sql[, parameters]) + .. method:: execute(sql, parameters=(), /) - Executes an SQL statement. Values may be bound to the statement using - :ref:`placeholders `. + Execute SQL statement *sql*. + Bind values to the statement using :ref:`placeholders + ` that map to the :term:`sequence` or :class:`dict` + *parameters*. :meth:`execute` will only execute a single SQL statement. If you try to execute - more than one statement with it, it will raise a :exc:`.Warning`. Use + more than one statement with it, it will raise a :exc:`ProgrammingError`. Use :meth:`executescript` if you want to execute multiple SQL statements with one call. + If :attr:`~Connection.autocommit` is + :data:`LEGACY_TRANSACTION_CONTROL`, + :attr:`~Connection.isolation_level` is not ``None``, + *sql* is an ``INSERT``, ``UPDATE``, ``DELETE``, or ``REPLACE`` statement, + and there is no open transaction, + a transaction is implicitly opened before executing *sql*. - .. method:: executemany(sql, seq_of_parameters) - Executes a :ref:`parameterized ` SQL command + .. method:: executemany(sql, parameters, /) + + Execute :ref:`parameterized ` SQL statement *sql* against all parameter sequences or mappings found in the sequence - *seq_of_parameters*. The :mod:`sqlite3` module also allows using an + *parameters*. It is also possible to use an :term:`iterator` yielding parameters instead of a sequence. - - .. literalinclude:: ../includes/sqlite3/executemany_1.py - - Here's a shorter example using a :term:`generator`: - - .. literalinclude:: ../includes/sqlite3/executemany_2.py - - - .. method:: executescript(sql_script) - - This is a nonstandard convenience method for executing multiple SQL statements - at once. It issues a ``COMMIT`` statement first, then executes the SQL script it - gets as a parameter. This method disregards :attr:`isolation_level`; any - transaction control must be added to *sql_script*. - - *sql_script* can be an instance of :class:`str`. + Uses the same implicit transaction handling as :meth:`~Cursor.execute`. Example: - .. literalinclude:: ../includes/sqlite3/executescript.py + .. testcode:: sqlite3.cursor + + rows = [ + ("row1",), + ("row2",), + ] + # cur is an sqlite3.Cursor object + cur.executemany("INSERT INTO data VALUES(?)", rows) + + .. method:: executescript(sql_script, /) + + Execute the SQL statements in *sql_script*. + If the :attr:`~Connection.autocommit` is + :data:`LEGACY_TRANSACTION_CONTROL` + and there is a pending transaction, + an implicit ``COMMIT`` statement is executed first. + No other implicit transaction control is performed; + any transaction control must be added to *sql_script*. + + *sql_script* must be a :class:`string `. + + Example: + + .. testcode:: sqlite3.cursor + + # cur is an sqlite3.Cursor object + cur.executescript(""" + BEGIN; + CREATE TABLE person(firstname, lastname, age); + CREATE TABLE book(title, author, published); + CREATE TABLE publisher(name, address); + COMMIT; + """) .. method:: fetchone() - Fetches the next row of a query result set, returning a single sequence, - or :const:`None` when no more data is available. + If :attr:`~Cursor.row_factory` is ``None``, + return the next row query result set as a :class:`tuple`. + Else, pass it to the row factory and return its result. + Return ``None`` if no more data is available. .. method:: fetchmany(size=cursor.arraysize) - Fetches the next set of rows of a query result, returning a list. An empty - list is returned when no more rows are available. + Return the next set of rows of a query result as a :class:`list`. + Return an empty list if no more rows are available. The number of rows to fetch per call is specified by the *size* parameter. - If it is not given, the cursor's arraysize determines the number of rows - to be fetched. The method should try to fetch as many rows as indicated by - the size parameter. If this is not possible due to the specified number of - rows not being available, fewer rows may be returned. + If *size* is not given, :attr:`arraysize` determines the number of rows + to be fetched. + If fewer than *size* rows are available, + as many rows as are available are returned. Note there are performance considerations involved with the *size* parameter. For optimal performance, it is usually best to use the arraysize attribute. @@ -791,9 +1504,10 @@ Cursor Objects .. method:: fetchall() - Fetches all (remaining) rows of a query result, returning a list. Note that - the cursor's arraysize attribute can affect the performance of this operation. - An empty list is returned when no rows are available. + Return all (remaining) rows of a query result as a :class:`list`. + Return an empty list if no rows are available. + Note that the :attr:`arraysize` attribute can affect the performance of + this operation. .. method:: close() @@ -802,147 +1516,222 @@ Cursor Objects The cursor will be unusable from this point forward; a :exc:`ProgrammingError` exception will be raised if any operation is attempted with the cursor. - .. method:: setinputsizes(sizes) + .. method:: setinputsizes(sizes, /) - Required by the DB-API. Is a no-op in :mod:`sqlite3`. + Required by the DB-API. Does nothing in :mod:`!sqlite3`. - .. method:: setoutputsize(size [, column]) + .. method:: setoutputsize(size, column=None, /) - Required by the DB-API. Is a no-op in :mod:`sqlite3`. - - .. attribute:: rowcount - - Although the :class:`Cursor` class of the :mod:`sqlite3` module implements this - attribute, the database engine's own support for the determination of "rows - affected"/"rows selected" is quirky. - - For :meth:`executemany` statements, the number of modifications are summed up - into :attr:`rowcount`. - - As required by the Python DB API Spec, the :attr:`rowcount` attribute "is -1 in - case no ``executeXX()`` has been performed on the cursor or the rowcount of the - last operation is not determinable by the interface". This includes ``SELECT`` - statements because we cannot determine the number of rows a query produced - until all rows were fetched. - - .. attribute:: lastrowid - - This read-only attribute provides the rowid of the last modified row. It is - only set if you issued an ``INSERT`` or a ``REPLACE`` statement using the - :meth:`execute` method. For operations other than ``INSERT`` or - ``REPLACE`` or when :meth:`executemany` is called, :attr:`lastrowid` is - set to :const:`None`. - - If the ``INSERT`` or ``REPLACE`` statement failed to insert the previous - successful rowid is returned. - - .. versionchanged:: 3.6 - Added support for the ``REPLACE`` statement. + Required by the DB-API. Does nothing in :mod:`!sqlite3`. .. attribute:: arraysize Read/write attribute that controls the number of rows returned by :meth:`fetchmany`. The default value is 1 which means a single row would be fetched per call. - .. attribute:: description - - This read-only attribute provides the column names of the last query. To - remain compatible with the Python DB API, it returns a 7-tuple for each - column where the last six items of each tuple are :const:`None`. - - It is set for ``SELECT`` statements without any matching rows as well. - .. attribute:: connection - This read-only attribute provides the SQLite database :class:`Connection` - used by the :class:`Cursor` object. A :class:`Cursor` object created by + Read-only attribute that provides the SQLite database :class:`Connection` + belonging to the cursor. A :class:`Cursor` object created by calling :meth:`con.cursor() ` will have a - :attr:`connection` attribute that refers to *con*:: + :attr:`connection` attribute that refers to *con*: + + .. doctest:: >>> con = sqlite3.connect(":memory:") >>> cur = con.cursor() >>> cur.connection == con True + .. attribute:: description + + Read-only attribute that provides the column names of the last query. To + remain compatible with the Python DB API, it returns a 7-tuple for each + column where the last six items of each tuple are ``None``. + + It is set for ``SELECT`` statements without any matching rows as well. + + .. attribute:: lastrowid + + Read-only attribute that provides the row id of the last inserted row. It + is only updated after successful ``INSERT`` or ``REPLACE`` statements + using the :meth:`execute` method. For other statements, after + :meth:`executemany` or :meth:`executescript`, or if the insertion failed, + the value of ``lastrowid`` is left unchanged. The initial value of + ``lastrowid`` is ``None``. + + .. note:: + Inserts into ``WITHOUT ROWID`` tables are not recorded. + + .. versionchanged:: 3.6 + Added support for the ``REPLACE`` statement. + + .. attribute:: rowcount + + Read-only attribute that provides the number of modified rows for + ``INSERT``, ``UPDATE``, ``DELETE``, and ``REPLACE`` statements; + is ``-1`` for other statements, + including :abbr:`CTE (Common Table Expression)` queries. + It is only updated by the :meth:`execute` and :meth:`executemany` methods. + + .. attribute:: row_factory + + Control how a row fetched from this :class:`!Cursor` is represented. + If ``None``, a row is represented as a :class:`tuple`. + Can be set to the included :class:`sqlite3.Row`; + or a :term:`callable` that accepts two arguments, + a :class:`Cursor` object and the :class:`!tuple` of row values, + and returns a custom object representing an SQLite row. + + Defaults to what :attr:`Connection.row_factory` was set to + when the :class:`!Cursor` was created. + Assigning to this attribute does not affect + :attr:`Connection.row_factory` of the parent connection. + + See :ref:`sqlite3-howto-row-factory` for more details. + + +.. The sqlite3.Row example used to be a how-to. It has now been incorporated + into the Row reference. We keep the anchor here in order not to break + existing links. + +.. _sqlite3-columns-by-name: .. _sqlite3-row-objects: -Row Objects ------------ +Row objects +^^^^^^^^^^^ .. class:: Row - A :class:`Row` instance serves as a highly optimized + A :class:`!Row` instance serves as a highly optimized :attr:`~Connection.row_factory` for :class:`Connection` objects. - It tries to mimic a tuple in most of its features. + It supports iteration, equality testing, :func:`len`, + and :term:`mapping` access by column name and index. - It supports mapping access by column name and index, iteration, - representation, equality testing and :func:`len`. + Two :class:`!Row` objects compare equal + if they have identical column names and values. - If two :class:`Row` objects have exactly the same columns and their - members are equal, they compare equal. + See :ref:`sqlite3-howto-row-factory` for more details. .. method:: keys - This method returns a list of column names. Immediately after a query, + Return a :class:`list` of column names as :class:`strings `. + Immediately after a query, it is the first member of each tuple in :attr:`Cursor.description`. .. versionchanged:: 3.5 Added support of slicing. -Let's assume we initialize a table as in the example given above:: - con = sqlite3.connect(":memory:") - cur = con.cursor() - cur.execute('''create table stocks - (date text, trans text, symbol text, - qty real, price real)''') - cur.execute("""insert into stocks - values ('2006-01-05','BUY','RHAT',100,35.14)""") - con.commit() - cur.close() +.. _sqlite3-blob-objects: -Now we plug :class:`Row` in:: +Blob objects +^^^^^^^^^^^^ - >>> con.row_factory = sqlite3.Row - >>> cur = con.cursor() - >>> cur.execute('select * from stocks') - - >>> r = cur.fetchone() - >>> type(r) - - >>> tuple(r) - ('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14) - >>> len(r) - 5 - >>> r[2] - 'RHAT' - >>> r.keys() - ['date', 'trans', 'symbol', 'qty', 'price'] - >>> r['qty'] - 100.0 - >>> for member in r: - ... print(member) - ... - 2006-01-05 - BUY - RHAT - 100.0 - 35.14 +.. versionadded:: 3.11 + +.. class:: Blob + + A :class:`Blob` instance is a :term:`file-like object` + that can read and write data in an SQLite :abbr:`BLOB (Binary Large OBject)`. + Call :func:`len(blob) ` to get the size (number of bytes) of the blob. + Use indices and :term:`slices ` for direct access to the blob data. + + Use the :class:`Blob` as a :term:`context manager` to ensure that the blob + handle is closed after use. + + .. testcode:: + + con = sqlite3.connect(":memory:") + con.execute("CREATE TABLE test(blob_col blob)") + con.execute("INSERT INTO test(blob_col) VALUES(zeroblob(13))") + + # Write to our blob, using two write operations: + with con.blobopen("test", "blob_col", 1) as blob: + blob.write(b"hello, ") + blob.write(b"world.") + # Modify the first and last bytes of our blob + blob[0] = ord("H") + blob[-1] = ord("!") + + # Read the contents of our blob + with con.blobopen("test", "blob_col", 1) as blob: + greeting = blob.read() + + print(greeting) # outputs "b'Hello, world!'" + + .. testoutput:: + :hide: + + b'Hello, world!' + + .. method:: close() + + Close the blob. + + The blob will be unusable from this point onward. An + :class:`~sqlite3.Error` (or subclass) exception will be raised if any + further operation is attempted with the blob. + + .. method:: read(length=-1, /) + + Read *length* bytes of data from the blob at the current offset position. + If the end of the blob is reached, the data up to + :abbr:`EOF (End of File)` will be returned. When *length* is not + specified, or is negative, :meth:`~Blob.read` will read until the end of + the blob. + + .. method:: write(data, /) + + Write *data* to the blob at the current offset. This function cannot + change the blob length. Writing beyond the end of the blob will raise + :exc:`ValueError`. + + .. method:: tell() + + Return the current access position of the blob. + + .. method:: seek(offset, origin=os.SEEK_SET, /) + + Set the current access position of the blob to *offset*. The *origin* + argument defaults to :data:`os.SEEK_SET` (absolute blob positioning). + Other values for *origin* are :data:`os.SEEK_CUR` (seek relative to the + current position) and :data:`os.SEEK_END` (seek relative to the blob’s + end). + + +PrepareProtocol objects +^^^^^^^^^^^^^^^^^^^^^^^ + +.. class:: PrepareProtocol + + The PrepareProtocol type's single purpose is to act as a :pep:`246` style + adaption protocol for objects that can :ref:`adapt themselves + ` to :ref:`native SQLite types `. .. _sqlite3-exceptions: Exceptions ----------- +^^^^^^^^^^ + +The exception hierarchy is defined by the DB-API 2.0 (:pep:`249`). .. exception:: Warning - A subclass of :exc:`Exception`. + This exception is not currently raised by the :mod:`!sqlite3` module, + but may be raised by applications using :mod:`!sqlite3`, + for example if a user-defined function truncates data while inserting. + ``Warning`` is a subclass of :exc:`Exception`. .. exception:: Error - The base class of the other exceptions in this module. It is a subclass - of :exc:`Exception`. + The base class of the other exceptions in this module. + Use this to catch all errors with one single :keyword:`except` statement. + ``Error`` is a subclass of :exc:`Exception`. + + If the exception originated from within the SQLite library, + the following two attributes are added to the exception: .. attribute:: sqlite_errorcode @@ -958,44 +1747,66 @@ Exceptions .. versionadded:: 3.11 +.. exception:: InterfaceError + + Exception raised for misuse of the low-level SQLite C API. + In other words, if this exception is raised, it probably indicates a bug in the + :mod:`!sqlite3` module. + ``InterfaceError`` is a subclass of :exc:`Error`. + .. exception:: DatabaseError Exception raised for errors that are related to the database. + This serves as the base exception for several types of database errors. + It is only raised implicitly through the specialised subclasses. + ``DatabaseError`` is a subclass of :exc:`Error`. + +.. exception:: DataError + + Exception raised for errors caused by problems with the processed data, + like numeric values out of range, and strings which are too long. + ``DataError`` is a subclass of :exc:`DatabaseError`. + +.. exception:: OperationalError + + Exception raised for errors that are related to the database's operation, + and not necessarily under the control of the programmer. + For example, the database path is not found, + or a transaction could not be processed. + ``OperationalError`` is a subclass of :exc:`DatabaseError`. .. exception:: IntegrityError Exception raised when the relational integrity of the database is affected, e.g. a foreign key check fails. It is a subclass of :exc:`DatabaseError`. +.. exception:: InternalError + + Exception raised when SQLite encounters an internal error. + If this is raised, it may indicate that there is a problem with the runtime + SQLite library. + ``InternalError`` is a subclass of :exc:`DatabaseError`. + .. exception:: ProgrammingError - Exception raised for programming errors, e.g. table not found or already - exists, syntax error in the SQL statement, wrong number of parameters - specified, etc. It is a subclass of :exc:`DatabaseError`. - -.. exception:: OperationalError - - Exception raised for errors that are related to the database's operation - and not necessarily under the control of the programmer, e.g. an unexpected - disconnect occurs, the data source name is not found, a transaction could - not be processed, etc. It is a subclass of :exc:`DatabaseError`. + Exception raised for :mod:`!sqlite3` API programming errors, + for example supplying the wrong number of bindings to a query, + or trying to operate on a closed :class:`Connection`. + ``ProgrammingError`` is a subclass of :exc:`DatabaseError`. .. exception:: NotSupportedError - Exception raised in case a method or database API was used which is not - supported by the database, e.g. calling the :meth:`~Connection.rollback` - method on a connection that does not support transaction or has - transactions turned off. It is a subclass of :exc:`DatabaseError`. + Exception raised in case a method or database API is not supported by the + underlying SQLite library. For example, setting *deterministic* to + ``True`` in :meth:`~Connection.create_function`, if the underlying SQLite library + does not support deterministic functions. + ``NotSupportedError`` is a subclass of :exc:`DatabaseError`. .. _sqlite3-types: SQLite and Python types ------------------------ - - -Introduction -^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^ SQLite natively supports the following types: ``NULL``, ``INTEGER``, ``REAL``, ``TEXT``, ``BLOB``. @@ -1005,7 +1816,7 @@ The following Python types can thus be sent to SQLite without any problem: +-------------------------------+-------------+ | Python type | SQLite type | +===============================+=============+ -| :const:`None` | ``NULL`` | +| ``None`` | ``NULL`` | +-------------------------------+-------------+ | :class:`int` | ``INTEGER`` | +-------------------------------+-------------+ @@ -1022,7 +1833,7 @@ This is how SQLite types are converted to Python types by default: +-------------+----------------------------------------------+ | SQLite type | Python type | +=============+==============================================+ -| ``NULL`` | :const:`None` | +| ``NULL`` | ``None`` | +-------------+----------------------------------------------+ | ``INTEGER`` | :class:`int` | +-------------+----------------------------------------------+ @@ -1034,120 +1845,35 @@ This is how SQLite types are converted to Python types by default: | ``BLOB`` | :class:`bytes` | +-------------+----------------------------------------------+ -The type system of the :mod:`sqlite3` module is extensible in two ways: you can -store additional Python types in a SQLite database via object adaptation, and -you can let the :mod:`sqlite3` module convert SQLite types to different Python -types via converters. +The type system of the :mod:`!sqlite3` module is extensible in two ways: you can +store additional Python types in an SQLite database via +:ref:`object adapters `, +and you can let the :mod:`!sqlite3` module convert SQLite types to +Python types via :ref:`converters `. -Using adapters to store additional Python types in SQLite databases -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. _sqlite3-default-converters: -As described before, SQLite supports only a limited set of types natively. To -use other Python types with SQLite, you must **adapt** them to one of the -sqlite3 module's supported types for SQLite: one of NoneType, int, float, -str, bytes. - -There are two ways to enable the :mod:`sqlite3` module to adapt a custom Python -type to one of the supported ones. - - -Letting your object adapt itself -"""""""""""""""""""""""""""""""" - -This is a good approach if you write the class yourself. Let's suppose you have -a class like this:: - - class Point: - def __init__(self, x, y): - self.x, self.y = x, y - -Now you want to store the point in a single SQLite column. First you'll have to -choose one of the supported types to be used for representing the point. -Let's just use str and separate the coordinates using a semicolon. Then you need -to give your class a method ``__conform__(self, protocol)`` which must return -the converted value. The parameter *protocol* will be :class:`PrepareProtocol`. - -.. literalinclude:: ../includes/sqlite3/adapter_point_1.py - - -Registering an adapter callable -""""""""""""""""""""""""""""""" - -The other possibility is to create a function that converts the type to the -string representation and register the function with :meth:`register_adapter`. - -.. literalinclude:: ../includes/sqlite3/adapter_point_2.py - -The :mod:`sqlite3` module has two default adapters for Python's built-in -:class:`datetime.date` and :class:`datetime.datetime` types. Now let's suppose -we want to store :class:`datetime.datetime` objects not in ISO representation, -but as a Unix timestamp. - -.. literalinclude:: ../includes/sqlite3/adapter_datetime.py - - -Converting SQLite values to custom Python types -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Writing an adapter lets you send custom Python types to SQLite. But to make it -really useful we need to make the Python to SQLite to Python roundtrip work. - -Enter converters. - -Let's go back to the :class:`Point` class. We stored the x and y coordinates -separated via semicolons as strings in SQLite. - -First, we'll define a converter function that accepts the string as a parameter -and constructs a :class:`Point` object from it. +Default adapters and converters (deprecated) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. note:: - Converter functions **always** get called with a :class:`bytes` object, no - matter under which data type you sent the value to SQLite. + The default adapters and converters are deprecated as of Python 3.12. + Instead, use the :ref:`sqlite3-adapter-converter-recipes` + and tailor them to your needs. -:: +The deprecated default adapters and converters consist of: - def convert_point(s): - x, y = map(float, s.split(b";")) - return Point(x, y) - -Now you need to make the :mod:`sqlite3` module know that what you select from -the database is actually a point. There are two ways of doing this: - -* Implicitly via the declared type - -* Explicitly via the column name - -Both ways are described in section :ref:`sqlite3-module-contents`, in the entries -for the constants :const:`PARSE_DECLTYPES` and :const:`PARSE_COLNAMES`. - -The following example illustrates both approaches. - -.. literalinclude:: ../includes/sqlite3/converter_point.py - - -Default adapters and converters -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -There are default adapters for the date and datetime types in the datetime -module. They will be sent as ISO dates/ISO timestamps to SQLite. - -The default converters are registered under the name "date" for -:class:`datetime.date` and under the name "timestamp" for -:class:`datetime.datetime`. - -This way, you can use date/timestamps from Python without any additional -fiddling in most cases. The format of the adapters is also compatible with the -experimental SQLite date/time functions. - -The following example demonstrates this. - -.. literalinclude:: ../includes/sqlite3/pysqlite_datetime.py - -If a timestamp stored in SQLite has a fractional part longer than 6 -numbers, its value will be truncated to microsecond precision by the -timestamp converter. +* An adapter for :class:`datetime.date` objects to :class:`strings ` in + `ISO 8601`_ format. +* An adapter for :class:`datetime.datetime` objects to strings in + ISO 8601 format. +* A converter for :ref:`declared ` "date" types to + :class:`datetime.date` objects. +* A converter for declared "timestamp" types to + :class:`datetime.datetime` objects. + Fractional parts will be truncated to 6 digits (microsecond precision). .. note:: @@ -1156,89 +1882,677 @@ timestamp converter. offsets in timestamps, either leave converters disabled, or register an offset-aware converter with :func:`register_converter`. -.. _sqlite3-controlling-transactions: +.. deprecated:: 3.12 -Controlling Transactions ------------------------- - -The underlying ``sqlite3`` library operates in ``autocommit`` mode by default, -but the Python :mod:`sqlite3` module by default does not. - -``autocommit`` mode means that statements that modify the database take effect -immediately. A ``BEGIN`` or ``SAVEPOINT`` statement disables ``autocommit`` -mode, and a ``COMMIT``, a ``ROLLBACK``, or a ``RELEASE`` that ends the -outermost transaction, turns ``autocommit`` mode back on. - -The Python :mod:`sqlite3` module by default issues a ``BEGIN`` statement -implicitly before a Data Modification Language (DML) statement (i.e. -``INSERT``/``UPDATE``/``DELETE``/``REPLACE``). - -You can control which kind of ``BEGIN`` statements :mod:`sqlite3` implicitly -executes via the *isolation_level* parameter to the :func:`connect` -call, or via the :attr:`isolation_level` property of connections. -If you specify no *isolation_level*, a plain ``BEGIN`` is used, which is -equivalent to specifying ``DEFERRED``. Other possible values are ``IMMEDIATE`` -and ``EXCLUSIVE``. - -You can disable the :mod:`sqlite3` module's implicit transaction management by -setting :attr:`isolation_level` to ``None``. This will leave the underlying -``sqlite3`` library operating in ``autocommit`` mode. You can then completely -control the transaction state by explicitly issuing ``BEGIN``, ``ROLLBACK``, -``SAVEPOINT``, and ``RELEASE`` statements in your code. - -Note that :meth:`~Cursor.executescript` disregards -:attr:`isolation_level`; any transaction control must be added explicitly. - -.. versionchanged:: 3.6 - :mod:`sqlite3` used to implicitly commit an open transaction before DDL - statements. This is no longer the case. +.. _ISO 8601: https://en.wikipedia.org/wiki/ISO_8601 -Using :mod:`sqlite3` efficiently --------------------------------- +.. _sqlite3-cli: - -Using shortcut methods +Command-line interface ^^^^^^^^^^^^^^^^^^^^^^ -Using the nonstandard :meth:`execute`, :meth:`executemany` and -:meth:`executescript` methods of the :class:`Connection` object, your code can +The :mod:`!sqlite3` module can be invoked as a script, +using the interpreter's :option:`-m` switch, +in order to provide a simple SQLite shell. +The argument signature is as follows:: + + python -m sqlite3 [-h] [-v] [filename] [sql] + +Type ``.quit`` or CTRL-D to exit the shell. + +.. program:: python -m sqlite3 [-h] [-v] [filename] [sql] + +.. option:: -h, --help + + Print CLI help. + +.. option:: -v, --version + + Print underlying SQLite library version. + +.. versionadded:: 3.12 + + +.. _sqlite3-howtos: + +How-to guides +------------- + +.. _sqlite3-placeholders: + +How to use placeholders to bind values in SQL queries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +SQL operations usually need to use values from Python variables. However, +beware of using Python's string operations to assemble queries, as they +are vulnerable to `SQL injection attacks`_. For example, an attacker can simply +close the single quote and inject ``OR TRUE`` to select all rows:: + + >>> # Never do this -- insecure! + >>> symbol = input() + ' OR TRUE; -- + >>> sql = "SELECT * FROM stocks WHERE symbol = '%s'" % symbol + >>> print(sql) + SELECT * FROM stocks WHERE symbol = '' OR TRUE; --' + >>> cur.execute(sql) + +Instead, use the DB-API's parameter substitution. To insert a variable into a +query string, use a placeholder in the string, and substitute the actual values +into the query by providing them as a :class:`tuple` of values to the second +argument of the cursor's :meth:`~Cursor.execute` method. + +An SQL statement may use one of two kinds of placeholders: +question marks (qmark style) or named placeholders (named style). +For the qmark style, *parameters* must be a +:term:`sequence` whose length must match the number of placeholders, +or a :exc:`ProgrammingError` is raised. +For the named style, *parameters* should be +an instance of a :class:`dict` (or a subclass), +which must contain keys for all named parameters; +any extra items are ignored. +Here's an example of both styles: + +.. testcode:: + + con = sqlite3.connect(":memory:") + cur = con.execute("CREATE TABLE lang(name, first_appeared)") + + # This is the named style used with executemany(): + data = ( + {"name": "C", "year": 1972}, + {"name": "Fortran", "year": 1957}, + {"name": "Python", "year": 1991}, + {"name": "Go", "year": 2009}, + ) + cur.executemany("INSERT INTO lang VALUES(:name, :year)", data) + + # This is the qmark style used in a SELECT query: + params = (1972,) + cur.execute("SELECT * FROM lang WHERE first_appeared = ?", params) + print(cur.fetchall()) + +.. testoutput:: + :hide: + + [('C', 1972)] + +.. note:: + + :pep:`249` numeric placeholders are *not* supported. + If used, they will be interpreted as named placeholders. + + +.. _sqlite3-adapters: + +How to adapt custom Python types to SQLite values +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +SQLite supports only a limited set of data types natively. +To store custom Python types in SQLite databases, *adapt* them to one of the +:ref:`Python types SQLite natively understands `. + +There are two ways to adapt Python objects to SQLite types: +letting your object adapt itself, or using an *adapter callable*. +The latter will take precedence above the former. +For a library that exports a custom type, +it may make sense to enable that type to adapt itself. +As an application developer, it may make more sense to take direct control by +registering custom adapter functions. + + +.. _sqlite3-conform: + +How to write adaptable objects +"""""""""""""""""""""""""""""" + +Suppose we have a :class:`!Point` class that represents a pair of coordinates, +``x`` and ``y``, in a Cartesian coordinate system. +The coordinate pair will be stored as a text string in the database, +using a semicolon to separate the coordinates. +This can be implemented by adding a ``__conform__(self, protocol)`` +method which returns the adapted value. +The object passed to *protocol* will be of type :class:`PrepareProtocol`. + +.. testcode:: + + class Point: + def __init__(self, x, y): + self.x, self.y = x, y + + def __conform__(self, protocol): + if protocol is sqlite3.PrepareProtocol: + return f"{self.x};{self.y}" + + con = sqlite3.connect(":memory:") + cur = con.cursor() + + cur.execute("SELECT ?", (Point(4.0, -3.2),)) + print(cur.fetchone()[0]) + +.. testoutput:: + :hide: + + 4.0;-3.2 + + +How to register adapter callables +""""""""""""""""""""""""""""""""" + +The other possibility is to create a function that converts the Python object +to an SQLite-compatible type. +This function can then be registered using :func:`register_adapter`. + +.. testcode:: + + class Point: + def __init__(self, x, y): + self.x, self.y = x, y + + def adapt_point(point): + return f"{point.x};{point.y}" + + sqlite3.register_adapter(Point, adapt_point) + + con = sqlite3.connect(":memory:") + cur = con.cursor() + + cur.execute("SELECT ?", (Point(1.0, 2.5),)) + print(cur.fetchone()[0]) + +.. testoutput:: + :hide: + + 1.0;2.5 + + +.. _sqlite3-converters: + +How to convert SQLite values to custom Python types +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Writing an adapter lets you convert *from* custom Python types *to* SQLite +values. +To be able to convert *from* SQLite values *to* custom Python types, +we use *converters*. + +Let's go back to the :class:`!Point` class. We stored the x and y coordinates +separated via semicolons as strings in SQLite. + +First, we'll define a converter function that accepts the string as a parameter +and constructs a :class:`!Point` object from it. + +.. note:: + + Converter functions are **always** passed a :class:`bytes` object, + no matter the underlying SQLite data type. + +.. testcode:: + + def convert_point(s): + x, y = map(float, s.split(b";")) + return Point(x, y) + +We now need to tell :mod:`!sqlite3` when it should convert a given SQLite value. +This is done when connecting to a database, using the *detect_types* parameter +of :func:`connect`. There are three options: + +* Implicit: set *detect_types* to :const:`PARSE_DECLTYPES` +* Explicit: set *detect_types* to :const:`PARSE_COLNAMES` +* Both: set *detect_types* to + ``sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES``. + Column names take precedence over declared types. + +The following example illustrates the implicit and explicit approaches: + +.. testcode:: + + class Point: + def __init__(self, x, y): + self.x, self.y = x, y + + def __repr__(self): + return f"Point({self.x}, {self.y})" + + def adapt_point(point): + return f"{point.x};{point.y}" + + def convert_point(s): + x, y = list(map(float, s.split(b";"))) + return Point(x, y) + + # Register the adapter and converter + sqlite3.register_adapter(Point, adapt_point) + sqlite3.register_converter("point", convert_point) + + # 1) Parse using declared types + p = Point(4.0, -3.2) + con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES) + cur = con.execute("CREATE TABLE test(p point)") + + cur.execute("INSERT INTO test(p) VALUES(?)", (p,)) + cur.execute("SELECT p FROM test") + print("with declared types:", cur.fetchone()[0]) + cur.close() + con.close() + + # 2) Parse using column names + con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES) + cur = con.execute("CREATE TABLE test(p)") + + cur.execute("INSERT INTO test(p) VALUES(?)", (p,)) + cur.execute('SELECT p AS "p [point]" FROM test') + print("with column names:", cur.fetchone()[0]) + +.. testoutput:: + :hide: + + with declared types: Point(4.0, -3.2) + with column names: Point(4.0, -3.2) + + +.. _sqlite3-adapter-converter-recipes: + +Adapter and converter recipes +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This section shows recipes for common adapters and converters. + +.. testcode:: + + import datetime + import sqlite3 + + def adapt_date_iso(val): + """Adapt datetime.date to ISO 8601 date.""" + return val.isoformat() + + def adapt_datetime_iso(val): + """Adapt datetime.datetime to timezone-naive ISO 8601 date.""" + return val.isoformat() + + def adapt_datetime_epoch(val): + """Adapt datetime.datetime to Unix timestamp.""" + return int(val.timestamp()) + + sqlite3.register_adapter(datetime.date, adapt_date_iso) + sqlite3.register_adapter(datetime.datetime, adapt_datetime_iso) + sqlite3.register_adapter(datetime.datetime, adapt_datetime_epoch) + + def convert_date(val): + """Convert ISO 8601 date to datetime.date object.""" + return datetime.date.fromisoformat(val.decode()) + + def convert_datetime(val): + """Convert ISO 8601 datetime to datetime.datetime object.""" + return datetime.datetime.fromisoformat(val.decode()) + + def convert_timestamp(val): + """Convert Unix epoch timestamp to datetime.datetime object.""" + return datetime.datetime.fromtimestamp(int(val)) + + sqlite3.register_converter("date", convert_date) + sqlite3.register_converter("datetime", convert_datetime) + sqlite3.register_converter("timestamp", convert_timestamp) + +.. testcode:: + :hide: + + dt = datetime.datetime(2019, 5, 18, 15, 17, 8, 123456) + + assert adapt_date_iso(dt.date()) == "2019-05-18" + assert convert_date(b"2019-05-18") == dt.date() + + assert adapt_datetime_iso(dt) == "2019-05-18T15:17:08.123456" + assert convert_datetime(b"2019-05-18T15:17:08.123456") == dt + + # Using current time as fromtimestamp() returns local date/time. + # Dropping microseconds as adapt_datetime_epoch truncates fractional second part. + now = datetime.datetime.now().replace(microsecond=0) + current_timestamp = int(now.timestamp()) + + assert adapt_datetime_epoch(now) == current_timestamp + assert convert_timestamp(str(current_timestamp).encode()) == now + + +.. _sqlite3-connection-shortcuts: + +How to use connection shortcut methods +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Using the :meth:`~Connection.execute`, +:meth:`~Connection.executemany`, and :meth:`~Connection.executescript` +methods of the :class:`Connection` class, your code can be written more concisely because you don't have to create the (often superfluous) :class:`Cursor` objects explicitly. Instead, the :class:`Cursor` objects are created implicitly and these shortcut methods return the cursor objects. This way, you can execute a ``SELECT`` statement and iterate over it directly using only a single call on the :class:`Connection` object. -.. literalinclude:: ../includes/sqlite3/shortcut_methods.py +.. testcode:: + + # Create and fill the table. + con = sqlite3.connect(":memory:") + con.execute("CREATE TABLE lang(name, first_appeared)") + data = [ + ("C++", 1985), + ("Objective-C", 1984), + ] + con.executemany("INSERT INTO lang(name, first_appeared) VALUES(?, ?)", data) + + # Print the table contents + for row in con.execute("SELECT name, first_appeared FROM lang"): + print(row) + + print("I just deleted", con.execute("DELETE FROM lang").rowcount, "rows") + + # close() is not a shortcut method and it's not called automatically; + # the connection object should be closed manually + con.close() + +.. testoutput:: + :hide: + + ('C++', 1985) + ('Objective-C', 1984) + I just deleted 2 rows -Accessing columns by name instead of by index -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. _sqlite3-connection-context-manager: -One useful feature of the :mod:`sqlite3` module is the built-in -:class:`sqlite3.Row` class designed to be used as a row factory. - -Rows wrapped with this class can be accessed both by index (like tuples) and -case-insensitively by name: - -.. literalinclude:: ../includes/sqlite3/rowclass.py - - -Using the connection as a context manager +How to use the connection context manager ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Connection objects can be used as context managers -that automatically commit or rollback transactions. In the event of an -exception, the transaction is rolled back; otherwise, the transaction is -committed: +A :class:`Connection` object can be used as a context manager that +automatically commits or rolls back open transactions when leaving the body of +the context manager. +If the body of the :keyword:`with` statement finishes without exceptions, +the transaction is committed. +If this commit fails, +or if the body of the ``with`` statement raises an uncaught exception, +the transaction is rolled back. +If :attr:`~Connection.autocommit` is ``False``, +a new transaction is implicitly opened after committing or rolling back. -.. literalinclude:: ../includes/sqlite3/ctx_manager.py +If there is no open transaction upon leaving the body of the ``with`` statement, +or if :attr:`~Connection.autocommit` is ``True``, +the context manager does nothing. + +.. note:: + + The context manager neither implicitly opens a new transaction + nor closes the connection. + +.. testcode:: + + con = sqlite3.connect(":memory:") + con.execute("CREATE TABLE lang(id INTEGER PRIMARY KEY, name VARCHAR UNIQUE)") + + # Successful, con.commit() is called automatically afterwards + with con: + con.execute("INSERT INTO lang(name) VALUES(?)", ("Python",)) + + # con.rollback() is called after the with block finishes with an exception, + # the exception is still raised and must be caught + try: + with con: + con.execute("INSERT INTO lang(name) VALUES(?)", ("Python",)) + except sqlite3.IntegrityError: + print("couldn't add Python twice") + + # Connection object used as context manager only commits or rollbacks transactions, + # so the connection object should be closed manually + con.close() + +.. testoutput:: + :hide: + + couldn't add Python twice -.. rubric:: Footnotes +.. _sqlite3-uri-tricks: -.. [#f1] The sqlite3 module is not built with loadable extension support by - default, because some platforms (notably macOS) have SQLite - libraries which are compiled without this feature. To get loadable - extension support, you must pass the - :option:`--enable-loadable-sqlite-extensions` option to configure. +How to work with SQLite URIs +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Some useful URI tricks include: + +* Open a database in read-only mode: + +.. doctest:: + + >>> con = sqlite3.connect("file:tutorial.db?mode=ro", uri=True) + >>> con.execute("CREATE TABLE readonly(data)") + Traceback (most recent call last): + OperationalError: attempt to write a readonly database + +* Do not implicitly create a new database file if it does not already exist; + will raise :exc:`~sqlite3.OperationalError` if unable to create a new file: + +.. doctest:: + + >>> con = sqlite3.connect("file:nosuchdb.db?mode=rw", uri=True) + Traceback (most recent call last): + OperationalError: unable to open database file + + +* Create a shared named in-memory database: + +.. testcode:: + + db = "file:mem1?mode=memory&cache=shared" + con1 = sqlite3.connect(db, uri=True) + con2 = sqlite3.connect(db, uri=True) + with con1: + con1.execute("CREATE TABLE shared(data)") + con1.execute("INSERT INTO shared VALUES(28)") + res = con2.execute("SELECT data FROM shared") + assert res.fetchone() == (28,) + + +More information about this feature, including a list of parameters, +can be found in the `SQLite URI documentation`_. + +.. _SQLite URI documentation: https://www.sqlite.org/uri.html + + +.. _sqlite3-howto-row-factory: + +How to create and use row factories +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default, :mod:`!sqlite3` represents each row as a :class:`tuple`. +If a :class:`!tuple` does not suit your needs, +you can use the :class:`sqlite3.Row` class +or a custom :attr:`~Cursor.row_factory`. + +While :attr:`!row_factory` exists as an attribute both on the +:class:`Cursor` and the :class:`Connection`, +it is recommended to set :class:`Connection.row_factory`, +so all cursors created from the connection will use the same row factory. + +:class:`!Row` provides indexed and case-insensitive named access to columns, +with minimal memory overhead and performance impact over a :class:`!tuple`. +To use :class:`!Row` as a row factory, +assign it to the :attr:`!row_factory` attribute: + +.. doctest:: + + >>> con = sqlite3.connect(":memory:") + >>> con.row_factory = sqlite3.Row + +Queries now return :class:`!Row` objects: + +.. doctest:: + + >>> res = con.execute("SELECT 'Earth' AS name, 6378 AS radius") + >>> row = res.fetchone() + >>> row.keys() + ['name', 'radius'] + >>> row[0] # Access by index. + 'Earth' + >>> row["name"] # Access by name. + 'Earth' + >>> row["RADIUS"] # Column names are case-insensitive. + 6378 + +You can create a custom :attr:`~Cursor.row_factory` +that returns each row as a :class:`dict`, with column names mapped to values: + +.. testcode:: + + def dict_factory(cursor, row): + fields = [column[0] for column in cursor.description] + return {key: value for key, value in zip(fields, row)} + +Using it, queries now return a :class:`!dict` instead of a :class:`!tuple`: + +.. doctest:: + + >>> con = sqlite3.connect(":memory:") + >>> con.row_factory = dict_factory + >>> for row in con.execute("SELECT 1 AS a, 2 AS b"): + ... print(row) + {'a': 1, 'b': 2} + +The following row factory returns a :term:`named tuple`: + +.. testcode:: + + from collections import namedtuple + + def namedtuple_factory(cursor, row): + fields = [column[0] for column in cursor.description] + cls = namedtuple("Row", fields) + return cls._make(row) + +:func:`!namedtuple_factory` can be used as follows: + +.. doctest:: + + >>> con = sqlite3.connect(":memory:") + >>> con.row_factory = namedtuple_factory + >>> cur = con.execute("SELECT 1 AS a, 2 AS b") + >>> row = cur.fetchone() + >>> row + Row(a=1, b=2) + >>> row[0] # Indexed access. + 1 + >>> row.b # Attribute access. + 2 + +With some adjustments, the above recipe can be adapted to use a +:class:`~dataclasses.dataclass`, or any other custom class, +instead of a :class:`~collections.namedtuple`. + + +.. _sqlite3-explanation: + +Explanation +----------- + +.. _sqlite3-transaction-control: +.. _sqlite3-controlling-transactions: + +Transaction control +^^^^^^^^^^^^^^^^^^^ + +:mod:`!sqlite3` offers multiple methods of controlling whether, +when and how database transactions are opened and closed. +:ref:`sqlite3-transaction-control-autocommit` is recommended, +while :ref:`sqlite3-transaction-control-isolation-level` +retains the pre-Python 3.12 behaviour. + +.. _sqlite3-transaction-control-autocommit: + +Transaction control via the ``autocommit`` attribute +"""""""""""""""""""""""""""""""""""""""""""""""""""" + +The recommended way of controlling transaction behaviour is through +the :attr:`Connection.autocommit` attribute, +which should preferably be set using the *autocommit* parameter +of :func:`connect`. + +It is suggested to set *autocommit* to ``False``, +which implies :pep:`249`-compliant transaction control. +This means: + +* :mod:`!sqlite3` ensures that a transaction is always open, + so :func:`connect`, :meth:`Connection.commit`, and :meth:`Connection.rollback` + will implicitly open a new transaction + (immediately after closing the pending one, for the latter two). + :mod:`!sqlite3` uses ``BEGIN DEFERRED`` statements when opening transactions. +* Transactions should be committed explicitly using :meth:`!commit`. +* Transactions should be rolled back explicitly using :meth:`!rollback`. +* An implicit rollback is performed if the database is + :meth:`~Connection.close`-ed with pending changes. + +Set *autocommit* to ``True`` to enable SQLite's `autocommit mode`_. +In this mode, :meth:`Connection.commit` and :meth:`Connection.rollback` +have no effect. +Note that SQLite's autocommit mode is distinct from +the :pep:`249`-compliant :attr:`Connection.autocommit` attribute; +use :attr:`Connection.in_transaction` to query +the low-level SQLite autocommit mode. + +Set *autocommit* to :data:`LEGACY_TRANSACTION_CONTROL` +to leave transaction control behaviour to the +:attr:`Connection.isolation_level` attribute. +See :ref:`sqlite3-transaction-control-isolation-level` for more information. + + +.. _sqlite3-transaction-control-isolation-level: + +Transaction control via the ``isolation_level`` attribute +""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +.. note:: + + The recommended way of controlling transactions is via the + :attr:`~Connection.autocommit` attribute. + See :ref:`sqlite3-transaction-control-autocommit`. + +If :attr:`Connection.autocommit` is set to +:data:`LEGACY_TRANSACTION_CONTROL` (the default), +transaction behaviour is controlled using +the :attr:`Connection.isolation_level` attribute. +Otherwise, :attr:`!isolation_level` has no effect. + +If the connection attribute :attr:`~Connection.isolation_level` +is not ``None``, +new transactions are implicitly opened before +:meth:`~Cursor.execute` and :meth:`~Cursor.executemany` executes +``INSERT``, ``UPDATE``, ``DELETE``, or ``REPLACE`` statements; +for other statements, no implicit transaction handling is performed. +Use the :meth:`~Connection.commit` and :meth:`~Connection.rollback` methods +to respectively commit and roll back pending transactions. +You can choose the underlying `SQLite transaction behaviour`_ — +that is, whether and what type of ``BEGIN`` statements :mod:`!sqlite3` +implicitly executes – +via the :attr:`~Connection.isolation_level` attribute. + +If :attr:`~Connection.isolation_level` is set to ``None``, +no transactions are implicitly opened at all. +This leaves the underlying SQLite library in `autocommit mode`_, +but also allows the user to perform their own transaction handling +using explicit SQL statements. +The underlying SQLite library autocommit mode can be queried using the +:attr:`~Connection.in_transaction` attribute. + +The :meth:`~Cursor.executescript` method implicitly commits +any pending transaction before execution of the given SQL script, +regardless of the value of :attr:`~Connection.isolation_level`. + +.. versionchanged:: 3.6 + :mod:`!sqlite3` used to implicitly commit an open transaction before DDL + statements. This is no longer the case. + +.. versionchanged:: 3.12 + The recommended way of controlling transactions is now via the + :attr:`~Connection.autocommit` attribute. + +.. _autocommit mode: + https://www.sqlite.org/lang_transaction.html#implicit_versus_explicit_transactions + +.. _SQLite transaction behaviour: + https://www.sqlite.org/lang_transaction.html#deferred_immediate_and_exclusive_transactions diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index eb33d7e1778..30f2a0765cc 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -33,6 +33,7 @@ probably additional platforms, as long as OpenSSL is installed on that platform. may lead to a false sense of security, as the default settings of the ssl module are not necessarily appropriate for your application. +.. include:: ../includes/wasm-notavail.rst This section documents the objects and functions in the ``ssl`` module; for more general information about TLS, SSL, and certificates, the reader is referred to @@ -73,13 +74,10 @@ Functions, Constants, and Exceptions Socket creation ^^^^^^^^^^^^^^^ -Since Python 3.2 and 2.7.9, it is recommended to use the -:meth:`SSLContext.wrap_socket` of an :class:`SSLContext` instance to wrap -sockets as :class:`SSLSocket` objects. The helper functions +Instances of :class:`SSLSocket` must be created using the +:meth:`SSLContext.wrap_socket` method. The helper function :func:`create_default_context` returns a new context with secure default -settings. The old :func:`wrap_socket` function is deprecated since it is -both inefficient and has no support for server name indication (SNI) and -hostname matching. +settings. Client socket example with default context and IPv4/IPv6 dual stack:: @@ -311,27 +309,6 @@ Random generation .. versionadded:: 3.3 -.. function:: RAND_pseudo_bytes(num) - - Return (bytes, is_cryptographic): bytes are *num* pseudo-random bytes, - is_cryptographic is ``True`` if the bytes generated are cryptographically - strong. Raises an :class:`SSLError` if the operation is not supported by the - current RAND method. - - Generated pseudo-random byte sequences will be unique if they are of - sufficient length, but are not necessarily unpredictable. They can be used - for non-cryptographic purposes and for certain purposes in cryptographic - protocols, but usually not for key generation etc. - - For almost all applications :func:`os.urandom` is preferable. - - .. versionadded:: 3.3 - - .. deprecated:: 3.6 - - OpenSSL has deprecated :func:`ssl.RAND_pseudo_bytes`, use - :func:`ssl.RAND_bytes` instead. - .. function:: RAND_status() Return ``True`` if the SSL pseudo-random number generator has been seeded @@ -356,49 +333,6 @@ Certificate handling import ssl -.. function:: match_hostname(cert, hostname) - - Verify that *cert* (in decoded format as returned by - :meth:`SSLSocket.getpeercert`) matches the given *hostname*. The rules - applied are those for checking the identity of HTTPS servers as outlined - in :rfc:`2818`, :rfc:`5280` and :rfc:`6125`. In addition to HTTPS, this - function should be suitable for checking the identity of servers in - various SSL-based protocols such as FTPS, IMAPS, POPS and others. - - :exc:`CertificateError` is raised on failure. On success, the function - returns nothing:: - - >>> cert = {'subject': ((('commonName', 'example.com'),),)} - >>> ssl.match_hostname(cert, "example.com") - >>> ssl.match_hostname(cert, "example.org") - Traceback (most recent call last): - File "", line 1, in - File "/home/py3k/Lib/ssl.py", line 130, in match_hostname - ssl.CertificateError: hostname 'example.org' doesn't match 'example.com' - - .. versionadded:: 3.2 - - .. versionchanged:: 3.3.3 - The function now follows :rfc:`6125`, section 6.4.3 and does neither - match multiple wildcards (e.g. ``*.*.com`` or ``*a*.example.org``) nor - a wildcard inside an internationalized domain names (IDN) fragment. - IDN A-labels such as ``www*.xn--pthon-kva.org`` are still supported, - but ``x*.python.org`` no longer matches ``xn--tda.python.org``. - - .. versionchanged:: 3.5 - Matching of IP addresses, when present in the subjectAltName field - of the certificate, is now supported. - - .. versionchanged:: 3.7 - The function is no longer used to TLS connections. Hostname matching - is now performed by OpenSSL. - - Allow wildcard when it is the leftmost and the only character - in that segment. Partial wildcards like ``www*.example.com`` are no - longer supported. - - .. deprecated:: 3.7 - .. function:: cert_time_to_seconds(cert_time) Return the time in seconds since the Epoch, given the ``cert_time`` @@ -432,10 +366,10 @@ Certificate handling Given the address ``addr`` of an SSL-protected server, as a (*hostname*, *port-number*) pair, fetches the server's certificate, and returns it as a PEM-encoded string. If ``ssl_version`` is specified, uses that version of - the SSL protocol to attempt to connect to the server. If ``ca_certs`` is + the SSL protocol to attempt to connect to the server. If *ca_certs* is specified, it should be a file containing a list of root certificates, the - same format as used for the same parameter in - :meth:`SSLContext.wrap_socket`. The call will attempt to validate the + same format as used for the *cafile* parameter in + :meth:`SSLContext.load_verify_locations`. The call will attempt to validate the server certificate against that set of root certificates, and will fail if the validation attempt fails. A timeout can be specified with the ``timeout`` parameter. @@ -474,9 +408,6 @@ Certificate handling * :attr:`openssl_capath_env` - OpenSSL's environment key that points to a capath, * :attr:`openssl_capath` - hard coded path to a capath directory - .. availability:: LibreSSL ignores the environment vars - :attr:`openssl_cafile_env` and :attr:`openssl_capath_env`. - .. versionadded:: 3.4 .. function:: enum_certificates(store_name) @@ -517,33 +448,6 @@ Certificate handling .. versionadded:: 3.4 -.. function:: wrap_socket(sock, keyfile=None, certfile=None, \ - server_side=False, cert_reqs=CERT_NONE, ssl_version=PROTOCOL_TLS, \ - ca_certs=None, do_handshake_on_connect=True, \ - suppress_ragged_eofs=True, ciphers=None) - - Takes an instance ``sock`` of :class:`socket.socket`, and returns an instance - of :class:`ssl.SSLSocket`, a subtype of :class:`socket.socket`, which wraps - the underlying socket in an SSL context. ``sock`` must be a - :data:`~socket.SOCK_STREAM` socket; other socket types are unsupported. - - Internally, function creates a :class:`SSLContext` with protocol - *ssl_version* and :attr:`SSLContext.options` set to *cert_reqs*. If - parameters *keyfile*, *certfile*, *ca_certs* or *ciphers* are set, then - the values are passed to :meth:`SSLContext.load_cert_chain`, - :meth:`SSLContext.load_verify_locations`, and - :meth:`SSLContext.set_ciphers`. - - The arguments *server_side*, *do_handshake_on_connect*, and - *suppress_ragged_eofs* have the same meaning as - :meth:`SSLContext.wrap_socket`. - - .. deprecated:: 3.7 - - Since Python 3.2 and 2.7.9, it is recommended to use the - :meth:`SSLContext.wrap_socket` instead of :func:`wrap_socket`. The - top-level function is limited and creates an insecure client socket - without server name indication or hostname matching. Constants ^^^^^^^^^ @@ -554,8 +458,8 @@ Constants .. data:: CERT_NONE - Possible value for :attr:`SSLContext.verify_mode`, or the ``cert_reqs`` - parameter to :func:`wrap_socket`. Except for :const:`PROTOCOL_TLS_CLIENT`, + Possible value for :attr:`SSLContext.verify_mode`. + Except for :const:`PROTOCOL_TLS_CLIENT`, it is the default mode. With client-side sockets, just about any cert is accepted. Validation errors, such as untrusted or expired cert, are ignored and do not abort the TLS/SSL handshake. @@ -567,8 +471,8 @@ Constants .. data:: CERT_OPTIONAL - Possible value for :attr:`SSLContext.verify_mode`, or the ``cert_reqs`` - parameter to :func:`wrap_socket`. In client mode, :const:`CERT_OPTIONAL` + Possible value for :attr:`SSLContext.verify_mode`. + In client mode, :const:`CERT_OPTIONAL` has the same meaning as :const:`CERT_REQUIRED`. It is recommended to use :const:`CERT_REQUIRED` for client-side sockets instead. @@ -579,13 +483,12 @@ Constants the TLS handshake. Use of this setting requires a valid set of CA certificates to - be passed, either to :meth:`SSLContext.load_verify_locations` or as a - value of the ``ca_certs`` parameter to :func:`wrap_socket`. + be passed to :meth:`SSLContext.load_verify_locations`. .. data:: CERT_REQUIRED - Possible value for :attr:`SSLContext.verify_mode`, or the ``cert_reqs`` - parameter to :func:`wrap_socket`. In this mode, certificates are + Possible value for :attr:`SSLContext.verify_mode`. + In this mode, certificates are required from the other side of the socket connection; an :class:`SSLError` will be raised if no certificate is provided, or if its validation fails. This mode is **not** sufficient to verify a certificate in client mode as @@ -599,8 +502,7 @@ Constants the client must provide a valid and trusted certificate. Use of this setting requires a valid set of CA certificates to - be passed, either to :meth:`SSLContext.load_verify_locations` or as a - value of the ``ca_certs`` parameter to :func:`wrap_socket`. + be passed to :meth:`SSLContext.load_verify_locations`. .. class:: VerifyMode @@ -709,27 +611,12 @@ Constants Use :data:`PROTOCOL_TLS` instead. -.. data:: PROTOCOL_SSLv2 - - Selects SSL version 2 as the channel encryption protocol. - - This protocol is not available if OpenSSL is compiled with the - ``OPENSSL_NO_SSL2`` flag. - - .. warning:: - - SSL version 2 is insecure. Its use is highly discouraged. - - .. deprecated:: 3.6 - - OpenSSL has removed support for SSLv2. - .. data:: PROTOCOL_SSLv3 Selects SSL version 3 as the channel encryption protocol. - This protocol is not be available if OpenSSL is compiled with the - ``OPENSSL_NO_SSLv3`` flag. + This protocol is not available if OpenSSL is compiled with the + ``no-ssl3`` option. .. warning:: @@ -920,6 +807,29 @@ Constants .. versionadded:: 3.10 +.. data:: OP_ENABLE_KTLS + + Enable the use of the kernel TLS. To benefit from the feature, OpenSSL must + have been compiled with support for it, and the negotiated cipher suites and + extensions must be supported by it (a list of supported ones may vary by + platform and kernel version). + + Note that with enabled kernel TLS some cryptographic operations are + performed by the kernel directly and not via any available OpenSSL + Providers. This might be undesirable if, for example, the application + requires all cryptographic operations to be performed by the FIPS provider. + + This option is only available with OpenSSL 3.0.0 and later. + + .. versionadded:: 3.12 + +.. data:: OP_LEGACY_SERVER_CONNECT + + Allow legacy insecure renegotiation between OpenSSL and unpatched servers + only. + + .. versionadded:: 3.12 + .. data:: HAS_ALPN Whether the OpenSSL library has built-in support for the *Application-Layer @@ -1144,7 +1054,7 @@ SSL Sockets .. versionchanged:: 3.5 The :meth:`shutdown` does not reset the socket timeout each time bytes - are received or sent. The socket timeout is now to maximum total duration + are received or sent. The socket timeout is now the maximum total duration of the shutdown. .. deprecated:: 3.6 @@ -1177,8 +1087,8 @@ SSL sockets also have the following additional methods and attributes: cause write operations. .. versionchanged:: 3.5 - The socket timeout is no more reset each time bytes are received or sent. - The socket timeout is now to maximum total duration to read up to *len* + The socket timeout is no longer reset each time bytes are received or sent. + The socket timeout is now the maximum total duration to read up to *len* bytes. .. deprecated:: 3.6 @@ -1196,8 +1106,8 @@ SSL sockets also have the following additional methods and attributes: also cause read operations. .. versionchanged:: 3.5 - The socket timeout is no more reset each time bytes are received or sent. - The socket timeout is now to maximum total duration to write *buf*. + The socket timeout is no longer reset each time bytes are received or sent. + The socket timeout is now the maximum total duration to write *buf*. .. deprecated:: 3.6 Use :meth:`~SSLSocket.send` instead of :meth:`~SSLSocket.write`. @@ -1224,14 +1134,14 @@ SSL sockets also have the following additional methods and attributes: :attr:`~SSLSocket.context` is true. .. versionchanged:: 3.5 - The socket timeout is no more reset each time bytes are received or sent. - The socket timeout is now to maximum total duration of the handshake. + The socket timeout is no longer reset each time bytes are received or sent. + The socket timeout is now the maximum total duration of the handshake. .. versionchanged:: 3.7 Hostname or IP address is matched by OpenSSL during handshake. The function :func:`match_hostname` is no longer used. In case OpenSSL refuses a hostname or IP address, the handshake is aborted early and - a TLS alert message is send to the peer. + a TLS alert message is sent to the peer. .. method:: SSLSocket.getpeercert(binary_form=False) @@ -1272,11 +1182,6 @@ SSL sockets also have the following additional methods and attributes: 'subjectAltName': (('DNS', '*.eff.org'), ('DNS', 'eff.org')), 'version': 3} - .. note:: - - To validate a certificate for a particular service, you can use the - :func:`match_hostname` function. - If the ``binary_form`` parameter is :const:`True`, and a certificate was provided, this method returns the DER-encoded form of the entire certificate as a sequence of bytes, or :const:`None` if the peer did not provide a @@ -1291,6 +1196,8 @@ SSL sockets also have the following additional methods and attributes: :const:`None` if you used :const:`CERT_NONE` (rather than :const:`CERT_OPTIONAL` or :const:`CERT_REQUIRED`). + See also :attr:`SSLContext.check_hostname`. + .. versionchanged:: 3.2 The returned dictionary includes additional items such as ``issuer`` and ``notBefore``. @@ -1397,7 +1304,7 @@ SSL sockets also have the following additional methods and attributes: .. method:: SSLSocket.version() Return the actual SSL protocol version negotiated by the connection - as a string, or ``None`` is no secure connection is established. + as a string, or ``None`` if no secure connection is established. As of this writing, possible return values include ``"SSLv2"``, ``"SSLv3"``, ``"TLSv1"``, ``"TLSv1.1"`` and ``"TLSv1.2"``. Recent OpenSSL versions may define more return values. @@ -1411,10 +1318,7 @@ SSL sockets also have the following additional methods and attributes: .. attribute:: SSLSocket.context - The :class:`SSLContext` object this SSL socket is tied to. If the SSL - socket was created using the deprecated :func:`wrap_socket` function - (rather than :meth:`SSLContext.wrap_socket`), this is a custom context - object created for this SSL socket. + The :class:`SSLContext` object this SSL socket is tied to. .. versionadded:: 3.2 @@ -1505,11 +1409,10 @@ to speed up repeated connections from the same clients. The context is created with secure default values. The options :data:`OP_NO_COMPRESSION`, :data:`OP_CIPHER_SERVER_PREFERENCE`, :data:`OP_SINGLE_DH_USE`, :data:`OP_SINGLE_ECDH_USE`, - :data:`OP_NO_SSLv2` (except for :data:`PROTOCOL_SSLv2`), + :data:`OP_NO_SSLv2`, and :data:`OP_NO_SSLv3` (except for :data:`PROTOCOL_SSLv3`) are set by default. The initial cipher suite list contains only ``HIGH`` - ciphers, no ``NULL`` ciphers and no ``MD5`` ciphers (except for - :data:`PROTOCOL_SSLv2`). + ciphers, no ``NULL`` ciphers and no ``MD5`` ciphers. .. deprecated:: 3.10 @@ -1548,7 +1451,7 @@ to speed up repeated connections from the same clients. string must be the path to a single file in PEM format containing the certificate as well as any number of CA certificates needed to establish the certificate's authenticity. The *keyfile* string, if present, must - point to a file containing the private key in. Otherwise the private + point to a file containing the private key. Otherwise the private key will be taken from *certfile* as well. See the discussion of :ref:`ssl-certificates` for more information on how the certificate is stored in the *certfile*. @@ -1753,10 +1656,10 @@ to speed up repeated connections from the same clients. Due to the early negotiation phase of the TLS connection, only limited methods and attributes are usable like :meth:`SSLSocket.selected_alpn_protocol` and :attr:`SSLSocket.context`. - :meth:`SSLSocket.getpeercert`, :meth:`SSLSocket.getpeercert`, - :meth:`SSLSocket.cipher` and :meth:`SSLSocket.compress` methods require that + The :meth:`SSLSocket.getpeercert`, + :meth:`SSLSocket.cipher` and :meth:`SSLSocket.compression` methods require that the TLS connection has progressed beyond the TLS Client Hello and therefore - will not contain return meaningful values nor can they be called safely. + will not return meaningful values nor can they be called safely. The *sni_callback* function must return ``None`` to allow the TLS negotiation to continue. If a TLS failure is required, a constant @@ -1910,7 +1813,7 @@ to speed up repeated connections from the same clients. .. method:: SSLContext.session_stats() Get statistics about the SSL sessions created or managed by this context. - A dictionary is returned which maps the names of each `piece of information `_ to their + A dictionary is returned which maps the names of each `piece of information `_ to their numeric values. For example, here is the total number of hits and misses in the session cache since the context was created:: @@ -2070,7 +1973,7 @@ to speed up repeated connections from the same clients. :attr:`SSLContext.verify_flags` returns :class:`VerifyFlags` flags: >>> ssl.create_default_context().verify_flags # doctest: +SKIP - ssl.VERIFY_X509_TRUSTED_FIRST + .. attribute:: SSLContext.verify_mode @@ -2081,8 +1984,8 @@ to speed up repeated connections from the same clients. .. versionchanged:: 3.6 :attr:`SSLContext.verify_mode` returns :class:`VerifyMode` enum: - >>> ssl.create_default_context().verify_mode - ssl.CERT_REQUIRED + >>> ssl.create_default_context().verify_mode # doctest: +SKIP + .. index:: single: certificates @@ -2171,7 +2074,7 @@ Combined key and certificate Often the private key is stored in the same file as the certificate; in this case, only the ``certfile`` parameter to :meth:`SSLContext.load_cert_chain` -and :func:`wrap_socket` needs to be passed. If the private key is stored +needs to be passed. If the private key is stored with the certificate, it should come before the first certificate in the certificate chain:: @@ -2357,7 +2260,7 @@ waiting for clients to connect:: context.load_cert_chain(certfile="mycertfile", keyfile="mykeyfile") bindsocket = socket.socket() - bindsocket.bind(('myaddr.mydomain.com', 10023)) + bindsocket.bind(('myaddr.example.com', 10023)) bindsocket.listen(5) When a client connects, you'll call :meth:`accept` on the socket to get the @@ -2660,10 +2563,9 @@ Therefore, when in client mode, it is highly recommended to use :const:`CERT_REQUIRED`. However, it is in itself not sufficient; you also have to check that the server certificate, which can be obtained by calling :meth:`SSLSocket.getpeercert`, matches the desired service. For many -protocols and applications, the service can be identified by the hostname; -in this case, the :func:`match_hostname` function can be used. This common -check is automatically performed when :attr:`SSLContext.check_hostname` is -enabled. +protocols and applications, the service can be identified by the hostname. +This common check is automatically performed when +:attr:`SSLContext.check_hostname` is enabled. .. versionchanged:: 3.7 Hostname matchings is now performed by OpenSSL. Python no longer uses @@ -2704,7 +2606,7 @@ enabled when negotiating a SSL session is possible through the :meth:`SSLContext.set_ciphers` method. Starting from Python 3.2.3, the ssl module disables certain weak ciphers by default, but you may want to further restrict the cipher choice. Be sure to read OpenSSL's documentation -about the `cipher list format `_. +about the `cipher list format `_. If you want to check which ciphers are enabled by a given cipher list, use :meth:`SSLContext.get_ciphers` or the ``openssl ciphers`` command on your system. @@ -2717,8 +2619,8 @@ for example the :mod:`multiprocessing` or :mod:`concurrent.futures` modules), be aware that OpenSSL's internal random number generator does not properly handle forked processes. Applications must change the PRNG state of the parent process if they use any SSL feature with :func:`os.fork`. Any -successful call of :func:`~ssl.RAND_add`, :func:`~ssl.RAND_bytes` or -:func:`~ssl.RAND_pseudo_bytes` is sufficient. +successful call of :func:`~ssl.RAND_add` or :func:`~ssl.RAND_bytes` is +sufficient. .. _ssl-tlsv1_3: diff --git a/Doc/library/stat.rst b/Doc/library/stat.rst index 98219eaee97..083dc5e3bcf 100644 --- a/Doc/library/stat.rst +++ b/Doc/library/stat.rst @@ -109,7 +109,7 @@ Example:: for f in os.listdir(top): pathname = os.path.join(top, f) - mode = os.stat(pathname).st_mode + mode = os.lstat(pathname).st_mode if S_ISDIR(mode): # It's a directory, recurse into it walktree(pathname, callback) diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index 8638abfb697..f934b0e0319 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -35,6 +35,35 @@ and implementation-dependent. If your input data consists of mixed types, you may be able to use :func:`map` to ensure a consistent result, for example: ``map(float, input_data)``. +Some datasets use ``NaN`` (not a number) values to represent missing data. +Since NaNs have unusual comparison semantics, they cause surprising or +undefined behaviors in the statistics functions that sort data or that count +occurrences. The functions affected are ``median()``, ``median_low()``, +``median_high()``, ``median_grouped()``, ``mode()``, ``multimode()``, and +``quantiles()``. The ``NaN`` values should be stripped before calling these +functions:: + + >>> from statistics import median + >>> from math import isnan + >>> from itertools import filterfalse + + >>> data = [20.7, float('NaN'),19.2, 18.3, float('NaN'), 14.4] + >>> sorted(data) # This has surprising behavior + [20.7, nan, 14.4, 18.3, 19.2, nan] + >>> median(data) # This result is unexpected + 16.35 + + >>> sum(map(isnan, data)) # Number of missing values + 2 + >>> clean = list(filterfalse(isnan, data)) # Strip NaN values + >>> clean + [20.7, 19.2, 18.3, 14.4] + >>> sorted(clean) # Sorting now works as expected + [14.4, 18.3, 19.2, 20.7] + >>> median(clean) # This result is now well defined + 18.75 + + Averages and measures of central location ----------------------------------------- @@ -75,7 +104,7 @@ These functions calculate statistics regarding relations between two inputs. ========================= ===================================================== :func:`covariance` Sample covariance for two variables. -:func:`correlation` Pearson's correlation coefficient for two variables. +:func:`correlation` Pearson and Spearman's correlation coefficients. :func:`linear_regression` Slope and intercept for simple linear regression. ========================= ===================================================== @@ -116,10 +145,11 @@ However, for reading convenience, most of the examples show sorted sequences. .. note:: - The mean is strongly affected by outliers and is not a robust estimator - for central location: the mean is not necessarily a typical example of - the data points. For more robust measures of central location, see - :func:`median` and :func:`mode`. + The mean is strongly affected by `outliers + `_ and is not necessarily a + typical example of the data points. For a more robust, although less + efficient, measure of `central tendency + `_, see :func:`median`. The sample mean gives an unbiased estimate of the true population mean, so that when taken on average over all the possible samples, @@ -618,31 +648,57 @@ However, for reading convenience, most of the examples show sorted sequences. .. versionadded:: 3.10 -.. function:: correlation(x, y, /) +.. function:: correlation(x, y, /, *, method='linear') Return the `Pearson's correlation coefficient `_ for two inputs. Pearson's correlation coefficient *r* takes values - between -1 and +1. It measures the strength and direction of the linear - relationship, where +1 means very strong, positive linear relationship, - -1 very strong, negative linear relationship, and 0 no linear relationship. + between -1 and +1. It measures the strength and direction of a linear + relationship. + + If *method* is "ranked", computes `Spearman's rank correlation coefficient + `_ + for two inputs. The data is replaced by ranks. Ties are averaged so that + equal values receive the same rank. The resulting coefficient measures the + strength of a monotonic relationship. + + Spearman's correlation coefficient is appropriate for ordinal data or for + continuous data that doesn't meet the linear proportion requirement for + Pearson's correlation coefficient. Both inputs must be of the same length (no less than two), and need not to be constant, otherwise :exc:`StatisticsError` is raised. - Examples: + Example with `Kepler's laws of planetary motion + `_: .. doctest:: - >>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] - >>> y = [9, 8, 7, 6, 5, 4, 3, 2, 1] - >>> correlation(x, x) + >>> # Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, and Neptune + >>> orbital_period = [88, 225, 365, 687, 4331, 10_756, 30_687, 60_190] # days + >>> dist_from_sun = [58, 108, 150, 228, 778, 1_400, 2_900, 4_500] # million km + + >>> # Show that a perfect monotonic relationship exists + >>> correlation(orbital_period, dist_from_sun, method='ranked') + 1.0 + + >>> # Observe that a linear relationship is imperfect + >>> round(correlation(orbital_period, dist_from_sun), 4) + 0.9882 + + >>> # Demonstrate Kepler's third law: There is a linear correlation + >>> # between the square of the orbital period and the cube of the + >>> # distance from the sun. + >>> period_squared = [p * p for p in orbital_period] + >>> dist_cubed = [d * d * d for d in dist_from_sun] + >>> round(correlation(period_squared, dist_cubed), 4) 1.0 - >>> correlation(x, y) - -1.0 .. versionadded:: 3.10 + .. versionchanged:: 3.12 + Added support for Spearman's rank correlation coefficient. + .. function:: linear_regression(x, y, /, *, proportional=False) Return the slope and intercept of `simple linear regression @@ -783,7 +839,7 @@ of applications in statistics. The relative likelihood is computed as the probability of a sample occurring in a narrow range divided by the width of the range (hence the word "density"). Since the likelihood is relative to other points, - its value can be greater than `1.0`. + its value can be greater than ``1.0``. .. method:: NormalDist.cdf(x) @@ -797,7 +853,7 @@ of applications in statistics. Compute the inverse cumulative distribution function, also known as the `quantile function `_ or the `percent-point - `_ + `_ function. Mathematically, it is written ``x : P(X <= x) = p``. Finds the value *x* of the random variable *X* such that the @@ -908,7 +964,7 @@ Carlo simulation `_: [1.4591308524824727, 1.8035946855390597, 2.175091447274739] Normal distributions can be used to approximate `Binomial -distributions `_ +distributions `_ when the sample size is large and when the probability of a successful trial is near 50%. @@ -940,13 +996,14 @@ probability that the Python room will stay within its capacity limits? >>> seed(8675309) >>> def trial(): ... return choices(('Python', 'Ruby'), (p, q), k=n).count('Python') + ... >>> mean(trial() <= k for i in range(10_000)) 0.8398 Normal distributions commonly arise in machine learning problems. Wikipedia has a `nice example of a Naive Bayesian Classifier -`_. +`_. The challenge is to predict a person's gender from measurements of normally distributed features including height, weight, and foot size. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index de77507458a..0ef03035a57 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -178,13 +178,14 @@ operators are only defined where they make sense; for example, they raise a single: __ge__() (instance method) Non-identical instances of a class normally compare as non-equal unless the -class defines the :meth:`__eq__` method. +class defines the :meth:`~object.__eq__` method. Instances of a class cannot be ordered with respect to other instances of the same class, or other types of object, unless the class defines enough of the -methods :meth:`__lt__`, :meth:`__le__`, :meth:`__gt__`, and :meth:`__ge__` (in -general, :meth:`__lt__` and :meth:`__eq__` are sufficient, if you want the -conventional meanings of the comparison operators). +methods :meth:`~object.__lt__`, :meth:`~object.__le__`, :meth:`~object.__gt__`, and +:meth:`~object.__ge__` (in general, :meth:`~object.__lt__` and +:meth:`~object.__eq__` are sufficient, if you want the conventional meanings of the +comparison operators). The behavior of the :keyword:`is` and :keyword:`is not` operators cannot be customized; also they can be applied to any two objects and never raise an @@ -214,7 +215,7 @@ Numeric Types --- :class:`int`, :class:`float`, :class:`complex` There are three distinct numeric types: :dfn:`integers`, :dfn:`floating point numbers`, and :dfn:`complex numbers`. In addition, Booleans are a subtype of integers. Integers have unlimited precision. Floating point -numbers are usually implemented using :c:type:`double` in C; information +numbers are usually implemented using :c:expr:`double` in C; information about the precision and internal representation of floating point numbers for the machine on which your program is running is available in :data:`sys.float_info`. Complex numbers have a real and imaginary @@ -352,7 +353,7 @@ Notes: The numeric literals accepted include the digits ``0`` to ``9`` or any Unicode equivalent (code points with the ``Nd`` property). - See https://www.unicode.org/Public/14.0.0/ucd/extracted/DerivedNumericType.txt + See `the Unicode Standard `_ for a complete list of code points with the ``Nd`` property. @@ -608,6 +609,12 @@ class`. In addition, it provides a few more methods: .. versionadded:: 3.8 +.. method:: int.is_integer() + + Returns ``True``. Exists for duck type compatibility with :meth:`float.is_integer`. + + .. versionadded:: 3.12 + Additional Methods on Float --------------------------- @@ -698,7 +705,7 @@ Hashing of numeric types ------------------------ For numbers ``x`` and ``y``, possibly of different types, it's a requirement -that ``hash(x) == hash(y)`` whenever ``x == y`` (see the :meth:`__hash__` +that ``hash(x) == hash(y)`` whenever ``x == y`` (see the :meth:`~object.__hash__` method documentation for more details). For ease of implementation and efficiency across a variety of numeric types (including :class:`int`, :class:`float`, :class:`decimal.Decimal` and :class:`fractions.Fraction`) @@ -958,6 +965,16 @@ This means that to compare equal, every element must compare equal and the two sequences must be of the same type and have the same length. (For full details see :ref:`comparisons` in the language reference.) +.. index:: + single: loop; over mutable sequence + single: mutable sequence; loop over + +Forward and reversed iterators over mutable sequences access values using an +index. That index will continue to march forward (or backward) even if the +underlying sequence is mutated. The iterator terminates only when an +:exc:`IndexError` or a :exc:`StopIteration` is encountered (or when the index +drops below zero). + Notes: (1) @@ -1334,7 +1351,7 @@ loops. range(start, stop[, step]) The arguments to the range constructor must be integers (either built-in - :class:`int` or any object that implements the ``__index__`` special + :class:`int` or any object that implements the :meth:`~object.__index__` special method). If the *step* argument is omitted, it defaults to ``1``. If the *start* argument is omitted, it defaults to ``0``. If *step* is zero, :exc:`ValueError` is raised. @@ -1442,7 +1459,7 @@ objects that compare equal might have different :attr:`~range.start`, .. seealso:: - * The `linspace recipe `_ + * The `linspace recipe `_ shows how to implement a lazy version of range suitable for floating point applications. @@ -1462,7 +1479,7 @@ Strings are immutable written in a variety of ways: * Single quotes: ``'allows embedded "double" quotes'`` -* Double quotes: ``"allows embedded 'single' quotes"``. +* Double quotes: ``"allows embedded 'single' quotes"`` * Triple quoted: ``'''Three single quotes'''``, ``"""Three double quotes"""`` Triple quoted strings may span multiple lines - all associated whitespace will @@ -1506,11 +1523,12 @@ multiple fragments. depends on whether *encoding* or *errors* is given, as follows. If neither *encoding* nor *errors* is given, ``str(object)`` returns - :meth:`object.__str__() `, which is the "informal" or nicely + :meth:`type(object).__str__(object) `, + which is the "informal" or nicely printable string representation of *object*. For string objects, this is the string itself. If *object* does not have a :meth:`~object.__str__` method, then :func:`str` falls back to returning - :meth:`repr(object) `. + :func:`repr(object) `. .. index:: single: buffer protocol; str (built-in class) @@ -1585,8 +1603,9 @@ expression support in the :mod:`re` module). lowercase, :meth:`lower` would do nothing to ``'ß'``; :meth:`casefold` converts it to ``"ss"``. - The casefolding algorithm is described in section 3.13 of the Unicode - Standard. + The casefolding algorithm is + `described in section 3.13 of the Unicode Standard + `__. .. versionadded:: 3.3 @@ -1605,28 +1624,34 @@ expression support in the :mod:`re` module). range [*start*, *end*]. Optional arguments *start* and *end* are interpreted as in slice notation. + If *sub* is empty, returns the number of empty strings between characters + which is the length of the string plus one. + .. method:: str.encode(encoding="utf-8", errors="strict") - Return an encoded version of the string as a bytes object. Default encoding - is ``'utf-8'``. *errors* may be given to set a different error handling scheme. - The default for *errors* is ``'strict'``, meaning that encoding errors raise - a :exc:`UnicodeError`. Other possible - values are ``'ignore'``, ``'replace'``, ``'xmlcharrefreplace'``, - ``'backslashreplace'`` and any other name registered via - :func:`codecs.register_error`, see section :ref:`error-handlers`. For a - list of possible encodings, see section :ref:`standard-encodings`. + Return the string encoded to :class:`bytes`. - By default, the *errors* argument is not checked for best performances, but - only used at the first encoding error. Enable the :ref:`Python Development - Mode `, or use a :ref:`debug build ` to check - *errors*. + *encoding* defaults to ``'utf-8'``; + see :ref:`standard-encodings` for possible values. + + *errors* controls how encoding errors are handled. + If ``'strict'`` (the default), a :exc:`UnicodeError` exception is raised. + Other possible values are ``'ignore'``, + ``'replace'``, ``'xmlcharrefreplace'``, ``'backslashreplace'`` and any + other name registered via :func:`codecs.register_error`. + See :ref:`error-handlers` for details. + + For performance reasons, the value of *errors* is not checked for validity + unless an encoding error actually occurs, + :ref:`devmode` is enabled + or a :ref:`debug build ` is used. .. versionchanged:: 3.1 - Support for keyword arguments added. + Added support for keyword arguments. .. versionchanged:: 3.9 - The *errors* is now checked in development mode and + The value of the *errors* argument is now checked in :ref:`devmode` and in :ref:`debug mode `. @@ -1742,7 +1767,8 @@ expression support in the :mod:`re` module). one character, ``False`` otherwise. Alphabetic characters are those characters defined in the Unicode character database as "Letter", i.e., those with general category property being one of "Lm", "Lt", "Lu", "Ll", or "Lo". Note that this is different - from the "Alphabetic" property defined in the Unicode Standard. + from the `Alphabetic property defined in the Unicode Standard + `_. .. method:: str.isascii() @@ -1779,7 +1805,7 @@ expression support in the :mod:`re` module). Return ``True`` if the string is a valid identifier according to the language definition, section :ref:`identifiers`. - Call :func:`keyword.iskeyword` to test whether string ``s`` is a reserved + :func:`keyword.iskeyword` can be used to test whether string ``s`` is a reserved identifier, such as :keyword:`def` and :keyword:`class`. Example: @@ -1788,9 +1814,9 @@ expression support in the :mod:`re` module). >>> from keyword import iskeyword >>> 'hello'.isidentifier(), iskeyword('hello') - True, False + (True, False) >>> 'def'.isidentifier(), iskeyword('def') - True, True + (True, True) .. method:: str.islower() @@ -1854,6 +1880,8 @@ expression support in the :mod:`re` module). +.. _meth-str-join: + .. method:: str.join(iterable) Return a string which is the concatenation of the strings in *iterable*. @@ -1874,8 +1902,9 @@ expression support in the :mod:`re` module). Return a copy of the string with all the cased characters [4]_ converted to lowercase. - The lowercasing algorithm used is described in section 3.13 of the Unicode - Standard. + The lowercasing algorithm used is + `described in section 3.13 of the Unicode Standard + `__. .. method:: str.lstrip([chars]) @@ -2057,7 +2086,7 @@ expression support in the :mod:`re` module). .. index:: single: universal newlines; str.splitlines method -.. method:: str.splitlines([keepends]) +.. method:: str.splitlines(keepends=False) Return a list of the lines in the string, breaking at line boundaries. Line breaks are not included in the resulting list unless *keepends* is given and @@ -2177,7 +2206,11 @@ expression support in the :mod:`re` module). >>> "they're bill's friends from the UK".title() "They'Re Bill'S Friends From The Uk" - A workaround for apostrophes can be constructed using regular expressions:: + The :func:`string.capwords` function does not have this problem, as it + splits words on spaces only. + + Alternatively, a workaround for apostrophes can be constructed using regular + expressions:: >>> import re >>> def titlecase(s): @@ -2215,8 +2248,9 @@ expression support in the :mod:`re` module). character(s) is not "Lu" (Letter, uppercase), but e.g. "Lt" (Letter, titlecase). - The uppercasing algorithm used is described in section 3.13 of the Unicode - Standard. + The uppercasing algorithm used is + `described in section 3.13 of the Unicode Standard + `__. .. method:: str.zfill(width) @@ -2470,7 +2504,7 @@ data and are closely related to string objects in a variety of other ways. literals, except that a ``b`` prefix is added: * Single quotes: ``b'still allows embedded "double" quotes'`` - * Double quotes: ``b"still allows embedded 'single' quotes"``. + * Double quotes: ``b"still allows embedded 'single' quotes"`` * Triple quoted: ``b'''3 single quotes'''``, ``b"""3 double quotes"""`` Only ASCII characters are permitted in bytes literals (regardless of the @@ -2530,9 +2564,10 @@ data and are closely related to string objects in a variety of other ways. If you want to make the hex string easier to read, you can specify a single character separator *sep* parameter to include in the output. - By default between each byte. A second optional *bytes_per_sep* - parameter controls the spacing. Positive values calculate the - separator position from the right, negative values from the left. + By default, this separator will be included between each byte. + A second optional *bytes_per_sep* parameter controls the spacing. + Positive values calculate the separator position from the right, + negative values from the left. >>> value = b'\xf0\xf1\xf2' >>> value.hex('-') @@ -2557,16 +2592,6 @@ The representation of bytes objects uses the literal format (``b'...'``) since it is often more useful than e.g. ``bytes([46, 46, 46])``. You can always convert a bytes object into a list of integers using ``list(b)``. -.. note:: - For Python 2.x users: In the Python 2.x series, a variety of implicit - conversions between 8-bit strings (the closest thing 2.x offers to a - built-in binary data type) and Unicode strings were permitted. This was a - backwards compatibility workaround to account for the fact that Python - originally only supported 8-bit text, and Unicode text was a later - addition. In Python 3.x, those implicit conversions are gone - conversions - between 8-bit binary data and Unicode text must be explicit, and bytes and - string objects will always compare unequal. - .. _typebytearray: @@ -2689,6 +2714,9 @@ arbitrary binary data. The subsequence to search for may be any :term:`bytes-like object` or an integer in the range 0 to 255. + If *sub* is empty, returns the number of empty slices between characters + which is the length of the bytes object plus one. + .. versionchanged:: 3.3 Also accept an integer in the range 0 to 255 as the subsequence. @@ -2740,29 +2768,32 @@ arbitrary binary data. .. method:: bytes.decode(encoding="utf-8", errors="strict") bytearray.decode(encoding="utf-8", errors="strict") - Return a string decoded from the given bytes. Default encoding is - ``'utf-8'``. *errors* may be given to set a different - error handling scheme. The default for *errors* is ``'strict'``, meaning - that encoding errors raise a :exc:`UnicodeError`. Other possible values are - ``'ignore'``, ``'replace'`` and any other name registered via - :func:`codecs.register_error`, see section :ref:`error-handlers`. For a - list of possible encodings, see section :ref:`standard-encodings`. + Return the bytes decoded to a :class:`str`. - By default, the *errors* argument is not checked for best performances, but - only used at the first decoding error. Enable the :ref:`Python Development - Mode `, or use a :ref:`debug build ` to check *errors*. + *encoding* defaults to ``'utf-8'``; + see :ref:`standard-encodings` for possible values. + + *errors* controls how decoding errors are handled. + If ``'strict'`` (the default), a :exc:`UnicodeError` exception is raised. + Other possible values are ``'ignore'``, ``'replace'``, + and any other name registered via :func:`codecs.register_error`. + See :ref:`error-handlers` for details. + + For performance reasons, the value of *errors* is not checked for validity + unless a decoding error actually occurs, + :ref:`devmode` is enabled or a :ref:`debug build ` is used. .. note:: Passing the *encoding* argument to :class:`str` allows decoding any :term:`bytes-like object` directly, without needing to make a temporary - bytes or bytearray object. + :class:`!bytes` or :class:`!bytearray` object. .. versionchanged:: 3.1 Added support for keyword arguments. .. versionchanged:: 3.9 - The *errors* is now checked in development mode and + The value of the *errors* argument is now checked in :ref:`devmode` and in :ref:`debug mode `. @@ -3606,7 +3637,7 @@ The conversion types are: | | be used for Python2/3 code bases. | | +------------+-----------------------------------------------------+-------+ | ``'a'`` | Bytes (converts any Python object using | \(5) | -| | ``repr(obj).encode('ascii','backslashreplace)``). | | +| | ``repr(obj).encode('ascii', 'backslashreplace')``). | | +------------+-----------------------------------------------------+-------+ | ``'r'`` | ``'r'`` is an alias for ``'a'`` and should only | \(7) | | | be used for Python2/3 code bases. | | @@ -4361,19 +4392,13 @@ type, the :dfn:`dictionary`. (For other containers see the built-in A dictionary's keys are *almost* arbitrary values. Values that are not :term:`hashable`, that is, values containing lists, dictionaries or other mutable types (that are compared by value rather than by object identity) may -not be used as keys. Numeric types used for keys obey the normal rules for -numeric comparison: if two numbers compare equal (such as ``1`` and ``1.0``) -then they can be used interchangeably to index the same dictionary entry. (Note -however, that since computers store floating-point numbers as approximations it -is usually unwise to use them as dictionary keys.) +not be used as keys. +Values that compare equal (such as ``1``, ``1.0``, and ``True``) +can be used interchangeably to index the same dictionary entry. -Dictionaries can be created by placing a comma-separated list of ``key: value`` -pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: -'jack', 4127: 'sjoerd'}``, or by the :class:`dict` constructor. - -.. class:: dict(**kwarg) - dict(mapping, **kwarg) - dict(iterable, **kwarg) +.. class:: dict(**kwargs) + dict(mapping, **kwargs) + dict(iterable, **kwargs) Return a new dictionary initialized from an optional positional argument and a possibly empty set of keyword arguments. @@ -4446,6 +4471,7 @@ pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: >>> class Counter(dict): ... def __missing__(self, key): ... return 0 + ... >>> c = Counter() >>> c['red'] 0 @@ -4689,7 +4715,9 @@ values are hashable, so that ``(key, value)`` pairs are unique and hashable, then the items view is also set-like. (Values views are not treated as set-like since the entries are generally not unique.) For set-like views, all of the operations defined for the abstract base class :class:`collections.abc.Set` are -available (for example, ``==``, ``<``, or ``^``). +available (for example, ``==``, ``<``, or ``^``). While using set operators, +set-like views accept any iterable as the other operand, unlike sets which only +accept sets as the input. An example of dictionary view usage:: @@ -4701,6 +4729,7 @@ An example of dictionary view usage:: >>> n = 0 >>> for val in values: ... n += val + ... >>> print(n) 504 @@ -4721,10 +4750,12 @@ An example of dictionary view usage:: {'bacon'} >>> keys ^ {'sausage', 'juice'} {'juice', 'sausage', 'bacon', 'spam'} + >>> keys | ['juice', 'juice', 'juice'] + {'juice', 'sausage', 'bacon', 'spam', 'eggs'} >>> # get back a read-only proxy for the original dictionary >>> values.mapping - mappingproxy({'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}) + mappingproxy({'bacon': 1, 'spam': 500}) >>> values.mapping['spam'] 500 @@ -4793,9 +4824,9 @@ their implementation of the context management protocol. See the Python's :term:`generator`\s and the :class:`contextlib.contextmanager` decorator provide a convenient way to implement these protocols. If a generator function is decorated with the :class:`contextlib.contextmanager` decorator, it will return a -context manager implementing the necessary :meth:`__enter__` and -:meth:`__exit__` methods, rather than the iterator produced by an undecorated -generator function. +context manager implementing the necessary :meth:`~contextmanager.__enter__` and +:meth:`~contextmanager.__exit__` methods, rather than the iterator produced by an +undecorated generator function. Note that there is no specific slot for any of these methods in the type structure for Python objects in the Python/C API. Extension types wanting to @@ -4823,33 +4854,54 @@ Generic Alias Type object: GenericAlias pair: Generic; Alias -``GenericAlias`` objects are created by subscripting a class (usually a -container), such as ``list[int]``. They are intended primarily for +``GenericAlias`` objects are generally created by +:ref:`subscripting ` a class. They are most often used with +:ref:`container classes `, such as :class:`list` or +:class:`dict`. For example, ``list[int]`` is a ``GenericAlias`` object created +by subscripting the ``list`` class with the argument :class:`int`. +``GenericAlias`` objects are intended primarily for use with :term:`type annotations `. -Usually, the :ref:`subscription ` of container objects calls the -method :meth:`__getitem__` of the object. However, the subscription of some -containers' classes may call the classmethod :meth:`__class_getitem__` of the -class instead. The classmethod :meth:`__class_getitem__` should return a -``GenericAlias`` object. - .. note:: - If the :meth:`__getitem__` of the class' metaclass is present, it will take - precedence over the :meth:`__class_getitem__` defined in the class (see - :pep:`560` for more details). -The ``GenericAlias`` object acts as a proxy for :term:`generic types -`, implementing *parameterized generics* - a specific instance -of a generic which provides the types for container elements. + It is generally only possible to subscript a class if the class implements + the special method :meth:`~object.__class_getitem__`. -The user-exposed type for the ``GenericAlias`` object can be accessed from -:class:`types.GenericAlias` and used for :func:`isinstance` checks. It can -also be used to create ``GenericAlias`` objects directly. +A ``GenericAlias`` object acts as a proxy for a :term:`generic type`, +implementing *parameterized generics*. + +For a container class, the +argument(s) supplied to a :ref:`subscription ` of the class may +indicate the type(s) of the elements an object contains. For example, +``set[bytes]`` can be used in type annotations to signify a :class:`set` in +which all the elements are of type :class:`bytes`. + +For a class which defines :meth:`~object.__class_getitem__` but is not a +container, the argument(s) supplied to a subscription of the class will often +indicate the return type(s) of one or more methods defined on an object. For +example, :mod:`regular expressions ` can be used on both the :class:`str` data +type and the :class:`bytes` data type: + +* If ``x = re.search('foo', 'foo')``, ``x`` will be a + :ref:`re.Match ` object where the return values of + ``x.group(0)`` and ``x[0]`` will both be of type :class:`str`. We can + represent this kind of object in type annotations with the ``GenericAlias`` + ``re.Match[str]``. + +* If ``y = re.search(b'bar', b'bar')``, (note the ``b`` for :class:`bytes`), + ``y`` will also be an instance of ``re.Match``, but the return + values of ``y.group(0)`` and ``y[0]`` will both be of type + :class:`bytes`. In type annotations, we would represent this + variety of :ref:`re.Match ` objects with ``re.Match[bytes]``. + +``GenericAlias`` objects are instances of the class +:class:`types.GenericAlias`, which can also be used to create ``GenericAlias`` +objects directly. .. describe:: T[X, Y, ...] - Creates a ``GenericAlias`` representing a type ``T`` containing elements - of types *X*, *Y*, and more depending on the ``T`` used. + Creates a ``GenericAlias`` representing a type ``T`` parameterized by types + *X*, *Y*, and more depending on the ``T`` used. For example, a function expecting a :class:`list` containing :class:`float` elements:: @@ -4874,7 +4926,7 @@ The builtin functions :func:`isinstance` and :func:`issubclass` do not accept The Python runtime does not enforce :term:`type annotations `. This extends to generic types and their type parameters. When creating -an object from a ``GenericAlias``, container elements are not checked +a container object from a ``GenericAlias``, the elements in the container are not checked against their type. For example, the following code is discouraged, but will run without errors:: @@ -4901,8 +4953,8 @@ Calling :func:`repr` or :func:`str` on a generic shows the parameterized type:: >>> str(list[int]) 'list[int]' -The :meth:`__getitem__` method of generics will raise an exception to disallow -mistakes like ``dict[str][str]``:: +The :meth:`~object.__getitem__` method of generic containers will raise an +exception to disallow mistakes like ``dict[str][str]``:: >>> dict[str][str] Traceback (most recent call last): @@ -4911,7 +4963,7 @@ mistakes like ``dict[str][str]``:: However, such expressions are valid when :ref:`type variables ` are used. The index must have as many elements as there are type variable items -in the ``GenericAlias`` object's :attr:`__args__ `. :: +in the ``GenericAlias`` object's :attr:`~genericalias.__args__`. :: >>> from typing import TypeVar >>> Y = TypeVar('Y') @@ -4919,10 +4971,11 @@ in the ``GenericAlias`` object's :attr:`__args__ `. :: dict[str, int] -Standard Generic Collections -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Standard Generic Classes +^^^^^^^^^^^^^^^^^^^^^^^^ -These standard library collections support parameterized generics. +The following standard library classes support parameterized generics. This +list is non-exhaustive. * :class:`tuple` * :class:`list` @@ -4960,12 +5013,29 @@ These standard library collections support parameterized generics. * :class:`collections.abc.ValuesView` * :class:`contextlib.AbstractContextManager` * :class:`contextlib.AbstractAsyncContextManager` +* :class:`dataclasses.Field` +* :class:`functools.cached_property` +* :class:`functools.partialmethod` +* :class:`os.PathLike` +* :class:`queue.LifoQueue` +* :class:`queue.Queue` +* :class:`queue.PriorityQueue` +* :class:`queue.SimpleQueue` * :ref:`re.Pattern ` * :ref:`re.Match ` +* :class:`shelve.BsdDbShelf` +* :class:`shelve.DbfilenameShelf` +* :class:`shelve.Shelf` +* :class:`types.MappingProxyType` +* :class:`weakref.WeakKeyDictionary` +* :class:`weakref.WeakMethod` +* :class:`weakref.WeakSet` +* :class:`weakref.WeakValueDictionary` -Special Attributes of Generic Alias -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Special Attributes of ``GenericAlias`` objects +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ All parameterized generics implement special read-only attributes. @@ -4980,8 +5050,8 @@ All parameterized generics implement special read-only attributes. .. attribute:: genericalias.__args__ This attribute is a :class:`tuple` (possibly of length 1) of generic - types passed to the original :meth:`__class_getitem__` - of the generic container:: + types passed to the original :meth:`~object.__class_getitem__` of the + generic class:: >>> dict[str, list[int]].__args__ (, list[int]) @@ -5004,11 +5074,28 @@ All parameterized generics implement special read-only attributes. have correct ``__parameters__`` after substitution because :class:`typing.ParamSpec` is intended primarily for static type checking. + +.. attribute:: genericalias.__unpacked__ + + A boolean that is true if the alias has been unpacked using the + ``*`` operator (see :data:`~typing.TypeVarTuple`). + + .. versionadded:: 3.11 + + .. seealso:: - * :pep:`585` -- "Type Hinting Generics In Standard Collections" - * :meth:`__class_getitem__` -- Used to implement parameterized generics. - * :ref:`generics` -- Generics in the :mod:`typing` module. + :pep:`484` - Type Hints + Introducing Python's framework for type annotations. + + :pep:`585` - Type Hinting Generics In Standard Collections + Introducing the ability to natively parameterize standard-library + classes, provided they implement the special class method + :meth:`~object.__class_getitem__`. + + :ref:`Generics`, :ref:`user-defined generics ` and :class:`typing.Generic` + Documentation on how to implement generic classes that can be + parameterized at runtime and understood by static type-checkers. .. versionadded:: 3.9 @@ -5395,6 +5482,165 @@ types, where they are relevant. Some of these are not reported by the [] +.. _int_max_str_digits: + +Integer string conversion length limitation +=========================================== + +CPython has a global limit for converting between :class:`int` and :class:`str` +to mitigate denial of service attacks. This limit *only* applies to decimal or +other non-power-of-two number bases. Hexadecimal, octal, and binary conversions +are unlimited. The limit can be configured. + +The :class:`int` type in CPython is an arbitrary length number stored in binary +form (commonly known as a "bignum"). There exists no algorithm that can convert +a string to a binary integer or a binary integer to a string in linear time, +*unless* the base is a power of 2. Even the best known algorithms for base 10 +have sub-quadratic complexity. Converting a large value such as ``int('1' * +500_000)`` can take over a second on a fast CPU. + +Limiting conversion size offers a practical way to avoid `CVE-2020-10735 +`_. + +The limit is applied to the number of digit characters in the input or output +string when a non-linear conversion algorithm would be involved. Underscores +and the sign are not counted towards the limit. + +When an operation would exceed the limit, a :exc:`ValueError` is raised: + +.. doctest:: + + >>> import sys + >>> sys.set_int_max_str_digits(4300) # Illustrative, this is the default. + >>> _ = int('2' * 5432) + Traceback (most recent call last): + ... + ValueError: Exceeds the limit (4300 digits) for integer string conversion: value has 5432 digits; use sys.set_int_max_str_digits() to increase the limit. + >>> i = int('2' * 4300) + >>> len(str(i)) + 4300 + >>> i_squared = i*i + >>> len(str(i_squared)) + Traceback (most recent call last): + ... + ValueError: Exceeds the limit (4300 digits) for integer string conversion: value has 8599 digits; use sys.set_int_max_str_digits() to increase the limit. + >>> len(hex(i_squared)) + 7144 + >>> assert int(hex(i_squared), base=16) == i*i # Hexadecimal is unlimited. + +The default limit is 4300 digits as provided in +:data:`sys.int_info.default_max_str_digits `. +The lowest limit that can be configured is 640 digits as provided in +:data:`sys.int_info.str_digits_check_threshold `. + +Verification: + +.. doctest:: + + >>> import sys + >>> assert sys.int_info.default_max_str_digits == 4300, sys.int_info + >>> assert sys.int_info.str_digits_check_threshold == 640, sys.int_info + >>> msg = int('578966293710682886880994035146873798396722250538762761564' + ... '9252925514383915483333812743580549779436104706260696366600' + ... '571186405732').to_bytes(53, 'big') + ... + +.. versionadded:: 3.11 + +Affected APIs +------------- + +The limitation only applies to potentially slow conversions between :class:`int` +and :class:`str` or :class:`bytes`: + +* ``int(string)`` with default base 10. +* ``int(string, base)`` for all bases that are not a power of 2. +* ``str(integer)``. +* ``repr(integer)``. +* any other string conversion to base 10, for example ``f"{integer}"``, + ``"{}".format(integer)``, or ``b"%d" % integer``. + +The limitations do not apply to functions with a linear algorithm: + +* ``int(string, base)`` with base 2, 4, 8, 16, or 32. +* :func:`int.from_bytes` and :func:`int.to_bytes`. +* :func:`hex`, :func:`oct`, :func:`bin`. +* :ref:`formatspec` for hex, octal, and binary numbers. +* :class:`str` to :class:`float`. +* :class:`str` to :class:`decimal.Decimal`. + +Configuring the limit +--------------------- + +Before Python starts up you can use an environment variable or an interpreter +command line flag to configure the limit: + +* :envvar:`PYTHONINTMAXSTRDIGITS`, e.g. + ``PYTHONINTMAXSTRDIGITS=640 python3`` to set the limit to 640 or + ``PYTHONINTMAXSTRDIGITS=0 python3`` to disable the limitation. +* :option:`-X int_max_str_digits <-X>`, e.g. + ``python3 -X int_max_str_digits=640`` +* :data:`sys.flags.int_max_str_digits` contains the value of + :envvar:`PYTHONINTMAXSTRDIGITS` or :option:`-X int_max_str_digits <-X>`. + If both the env var and the ``-X`` option are set, the ``-X`` option takes + precedence. A value of *-1* indicates that both were unset, thus a value of + :data:`sys.int_info.default_max_str_digits` was used during initialization. + +From code, you can inspect the current limit and set a new one using these +:mod:`sys` APIs: + +* :func:`sys.get_int_max_str_digits` and :func:`sys.set_int_max_str_digits` are + a getter and setter for the interpreter-wide limit. Subinterpreters have + their own limit. + +Information about the default and minimum can be found in :attr:`sys.int_info`: + +* :data:`sys.int_info.default_max_str_digits ` is the compiled-in + default limit. +* :data:`sys.int_info.str_digits_check_threshold ` is the lowest + accepted value for the limit (other than 0 which disables it). + +.. versionadded:: 3.11 + +.. caution:: + + Setting a low limit *can* lead to problems. While rare, code exists that + contains integer constants in decimal in their source that exceed the + minimum threshold. A consequence of setting the limit is that Python source + code containing decimal integer literals longer than the limit will + encounter an error during parsing, usually at startup time or import time or + even at installation time - anytime an up to date ``.pyc`` does not already + exist for the code. A workaround for source that contains such large + constants is to convert them to ``0x`` hexadecimal form as it has no limit. + + Test your application thoroughly if you use a low limit. Ensure your tests + run with the limit set early via the environment or flag so that it applies + during startup and even during any installation step that may invoke Python + to precompile ``.py`` sources to ``.pyc`` files. + +Recommended configuration +------------------------- + +The default :data:`sys.int_info.default_max_str_digits` is expected to be +reasonable for most applications. If your application requires a different +limit, set it from your main entry point using Python version agnostic code as +these APIs were added in security patch releases in versions before 3.12. + +Example:: + + >>> import sys + >>> if hasattr(sys, "set_int_max_str_digits"): + ... upper_bound = 68000 + ... lower_bound = 4004 + ... current_limit = sys.get_int_max_str_digits() + ... if current_limit == 0 or current_limit > upper_bound: + ... sys.set_int_max_str_digits(upper_bound) + ... elif current_limit < lower_bound: + ... sys.set_int_max_str_digits(lower_bound) + +If you need to disable it entirely, set it to ``0``. + + .. rubric:: Footnotes .. [1] Additional information on these special methods may be found in the Python diff --git a/Doc/library/string.rst b/Doc/library/string.rst index b27782f8d8e..3b96813e683 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -8,6 +8,7 @@ -------------- + .. seealso:: :ref:`textseq` @@ -309,7 +310,7 @@ non-empty format specification typically modifies the result. The general form of a *standard format specifier* is: .. productionlist:: format-spec - format_spec: [[`fill`]`align`][`sign`][#][0][`width`][`grouping_option`][.`precision`][`type`] + format_spec: [[`fill`]`align`][`sign`][z][#][0][`width`][`grouping_option`][.`precision`][`type`] fill: align: "<" | ">" | "=" | "^" sign: "+" | "-" | " " @@ -380,6 +381,15 @@ following: +---------+----------------------------------------------------------+ +.. index:: single: z; in string formatting + +The ``'z'`` option coerces negative zero floating-point values to positive +zero after rounding to the format precision. This option is only valid for +floating-point presentation types. + +.. versionchanged:: 3.11 + Added the ``'z'`` option (see also :pep:`682`). + .. index:: single: # (hash); in string formatting The ``'#'`` option causes the "alternate form" to be used for the @@ -428,12 +438,13 @@ character of ``'0'`` with an *alignment* type of ``'='``. Preceding the *width* field by ``'0'`` no longer affects the default alignment for strings. -The *precision* is a decimal number indicating how many digits should be -displayed after the decimal point for a floating point value formatted with -``'f'`` and ``'F'``, or before and after the decimal point for a floating point -value formatted with ``'g'`` or ``'G'``. For non-number types the field +The *precision* is a decimal integer indicating how many digits should be +displayed after the decimal point for presentation types +``'f'`` and ``'F'``, or before and after the decimal point for presentation +types ``'g'`` or ``'G'``. For string presentation types the field indicates the maximum field size - in other words, how many characters will be -used from the field content. The *precision* is not allowed for integer values. +used from the field content. The *precision* is not allowed for integer +presentation types. Finally, the *type* determines how the data should be presented. @@ -728,7 +739,7 @@ internationalization (i18n) since in that context, the simpler syntax and functionality makes it easier to translate than other built-in string formatting facilities in Python. As an example of a library built on template strings for i18n, see the -`flufl.i18n `_ package. +`flufl.i18n `_ package. .. index:: single: $ (dollar); in template strings @@ -783,6 +794,22 @@ these rules. The methods of :class:`Template` are: templates containing dangling delimiters, unmatched braces, or placeholders that are not valid Python identifiers. + + .. method:: is_valid() + + Returns false if the template has invalid placeholders that will cause + :meth:`substitute` to raise :exc:`ValueError`. + + .. versionadded:: 3.11 + + + .. method:: get_identifiers() + + Returns a list of the valid identifiers in the template, in the order + they first appear, ignoring any invalid identifiers. + + .. versionadded:: 3.11 + :class:`Template` instances also provide one public data attribute: .. attribute:: template @@ -869,6 +896,9 @@ rule: * *invalid* -- This group matches any other delimiter pattern (usually a single delimiter), and it should appear last in the regular expression. +The methods on this class will raise :exc:`ValueError` if the pattern matches +the template without one of these named groups matching. + Helper functions ---------------- diff --git a/Doc/library/struct.rst b/Doc/library/struct.rst index eccba20fb8f..69d95f27cb6 100644 --- a/Doc/library/struct.rst +++ b/Doc/library/struct.rst @@ -12,21 +12,25 @@ -------------- -This module performs conversions between Python values and C structs represented -as Python :class:`bytes` objects. This can be used in handling binary data -stored in files or from network connections, among other sources. It uses -:ref:`struct-format-strings` as compact descriptions of the layout of the C -structs and the intended conversion to/from Python values. +This module converts between Python values and C structs represented +as Python :class:`bytes` objects. Compact :ref:`format strings ` +describe the intended conversions to/from Python values. +The module's functions and objects can be used for two largely +distinct applications, data exchange with external sources (files or +network connections), or data transfer between the Python application +and the C layer. .. note:: - By default, the result of packing a given C struct includes pad bytes in - order to maintain proper alignment for the C types involved; similarly, - alignment is taken into account when unpacking. This behavior is chosen so - that the bytes of a packed struct correspond exactly to the layout in memory - of the corresponding C struct. To handle platform-independent data formats - or omit implicit pad bytes, use ``standard`` size and alignment instead of - ``native`` size and alignment: see :ref:`struct-alignment` for details. + When no prefix character is given, native mode is the default. It + packs or unpacks data based on the platform and compiler on which + the Python interpreter was built. + The result of packing a given C struct includes pad bytes which + maintain proper alignment for the C types involved; similarly, + alignment is taken into account when unpacking. In contrast, when + communicating data between external sources, the programmer is + responsible for defining byte ordering and padding between elements. + See :ref:`struct-alignment` for details. Several :mod:`struct` functions (and methods of :class:`Struct`) take a *buffer* argument. This refers to objects that implement the :ref:`bufferobjects` and @@ -82,7 +86,7 @@ The module defines the following exception and functions: Iteratively unpack from the buffer *buffer* according to the format string *format*. This function returns an iterator which will read - equally-sized chunks from the buffer until all its contents have been + equally sized chunks from the buffer until all its contents have been consumed. The buffer's size in bytes must be a multiple of the size required by the format, as reflected by :func:`calcsize`. @@ -102,10 +106,13 @@ The module defines the following exception and functions: Format Strings -------------- -Format strings are the mechanism used to specify the expected layout when -packing and unpacking data. They are built up from :ref:`format-characters`, -which specify the type of data being packed/unpacked. In addition, there are -special characters for controlling the :ref:`struct-alignment`. +Format strings describe the data layout when +packing and unpacking data. They are built up from :ref:`format characters`, +which specify the type of data being packed/unpacked. In addition, +special characters control the :ref:`byte order, size and alignment`. +Each format string consists of an optional prefix character which +describes the overall properties of the data and one or more format +characters which describe the actual data values and padding. .. _struct-alignment: @@ -116,6 +123,11 @@ Byte Order, Size, and Alignment By default, C types are represented in the machine's native format and byte order, and properly aligned by skipping pad bytes if necessary (according to the rules used by the C compiler). +This behavior is chosen so +that the bytes of a packed struct correspond exactly to the memory layout +of the corresponding C struct. +Whether to use native byte ordering +and padding or standard formats depends on the application. .. index:: single: @ (at); in struct format strings @@ -144,11 +156,10 @@ following table: If the first character is not one of these, ``'@'`` is assumed. -Native byte order is big-endian or little-endian, depending on the host -system. For example, Intel x86 and AMD64 (x86-64) are little-endian; -Motorola 68000 and PowerPC G5 are big-endian; ARM and Intel Itanium feature -switchable endianness (bi-endian). Use ``sys.byteorder`` to check the -endianness of your system. +Native byte order is big-endian or little-endian, depending on the +host system. For example, Intel x86, AMD64 (x86-64), and Apple M1 are +little-endian; IBM z and many legacy architectures are big-endian. +Use :data:`sys.byteorder` to check the endianness of your system. Native size and alignment are determined using the C compiler's ``sizeof`` expression. This is always combined with native byte order. @@ -193,48 +204,48 @@ platform-dependent. +--------+--------------------------+--------------------+----------------+------------+ | Format | C Type | Python type | Standard size | Notes | +========+==========================+====================+================+============+ -| ``x`` | pad byte | no value | | | +| ``x`` | pad byte | no value | | \(7) | +--------+--------------------------+--------------------+----------------+------------+ -| ``c`` | :c:type:`char` | bytes of length 1 | 1 | | +| ``c`` | :c:expr:`char` | bytes of length 1 | 1 | | +--------+--------------------------+--------------------+----------------+------------+ -| ``b`` | :c:type:`signed char` | integer | 1 | \(1), \(2) | +| ``b`` | :c:expr:`signed char` | integer | 1 | \(1), \(2) | +--------+--------------------------+--------------------+----------------+------------+ -| ``B`` | :c:type:`unsigned char` | integer | 1 | \(2) | +| ``B`` | :c:expr:`unsigned char` | integer | 1 | \(2) | +--------+--------------------------+--------------------+----------------+------------+ -| ``?`` | :c:type:`_Bool` | bool | 1 | \(1) | +| ``?`` | :c:expr:`_Bool` | bool | 1 | \(1) | +--------+--------------------------+--------------------+----------------+------------+ -| ``h`` | :c:type:`short` | integer | 2 | \(2) | +| ``h`` | :c:expr:`short` | integer | 2 | \(2) | +--------+--------------------------+--------------------+----------------+------------+ -| ``H`` | :c:type:`unsigned short` | integer | 2 | \(2) | +| ``H`` | :c:expr:`unsigned short` | integer | 2 | \(2) | +--------+--------------------------+--------------------+----------------+------------+ -| ``i`` | :c:type:`int` | integer | 4 | \(2) | +| ``i`` | :c:expr:`int` | integer | 4 | \(2) | +--------+--------------------------+--------------------+----------------+------------+ -| ``I`` | :c:type:`unsigned int` | integer | 4 | \(2) | +| ``I`` | :c:expr:`unsigned int` | integer | 4 | \(2) | +--------+--------------------------+--------------------+----------------+------------+ -| ``l`` | :c:type:`long` | integer | 4 | \(2) | +| ``l`` | :c:expr:`long` | integer | 4 | \(2) | +--------+--------------------------+--------------------+----------------+------------+ -| ``L`` | :c:type:`unsigned long` | integer | 4 | \(2) | +| ``L`` | :c:expr:`unsigned long` | integer | 4 | \(2) | +--------+--------------------------+--------------------+----------------+------------+ -| ``q`` | :c:type:`long long` | integer | 8 | \(2) | +| ``q`` | :c:expr:`long long` | integer | 8 | \(2) | +--------+--------------------------+--------------------+----------------+------------+ -| ``Q`` | :c:type:`unsigned long | integer | 8 | \(2) | +| ``Q`` | :c:expr:`unsigned long | integer | 8 | \(2) | | | long` | | | | +--------+--------------------------+--------------------+----------------+------------+ -| ``n`` | :c:type:`ssize_t` | integer | | \(3) | +| ``n`` | :c:expr:`ssize_t` | integer | | \(3) | +--------+--------------------------+--------------------+----------------+------------+ -| ``N`` | :c:type:`size_t` | integer | | \(3) | +| ``N`` | :c:expr:`size_t` | integer | | \(3) | +--------+--------------------------+--------------------+----------------+------------+ | ``e`` | \(6) | float | 2 | \(4) | +--------+--------------------------+--------------------+----------------+------------+ -| ``f`` | :c:type:`float` | float | 4 | \(4) | +| ``f`` | :c:expr:`float` | float | 4 | \(4) | +--------+--------------------------+--------------------+----------------+------------+ -| ``d`` | :c:type:`double` | float | 8 | \(4) | +| ``d`` | :c:expr:`double` | float | 8 | \(4) | +--------+--------------------------+--------------------+----------------+------------+ -| ``s`` | :c:type:`char[]` | bytes | | | +| ``s`` | :c:expr:`char[]` | bytes | | \(9) | +--------+--------------------------+--------------------+----------------+------------+ -| ``p`` | :c:type:`char[]` | bytes | | | +| ``p`` | :c:expr:`char[]` | bytes | | \(8) | +--------+--------------------------+--------------------+----------------+------------+ -| ``P`` | :c:type:`void \*` | integer | | \(5) | +| ``P`` | :c:expr:`void \*` | integer | | \(5) | +--------+--------------------------+--------------------+----------------+------------+ .. versionchanged:: 3.3 @@ -249,8 +260,8 @@ Notes: (1) .. index:: single: ? (question mark); in struct format strings - The ``'?'`` conversion code corresponds to the :c:type:`_Bool` type defined by - C99. If this type is not available, it is simulated using a :c:type:`char`. In + The ``'?'`` conversion code corresponds to the :c:expr:`_Bool` type defined by + C99. If this type is not available, it is simulated using a :c:expr:`char`. In standard mode, it is always represented by one byte. (2) @@ -290,6 +301,34 @@ Notes: operations. See the Wikipedia page on the `half-precision floating-point format `_ for more information. +(7) + When packing, ``'x'`` inserts one NUL byte. + +(8) + The ``'p'`` format character encodes a "Pascal string", meaning a short + variable-length string stored in a *fixed number of bytes*, given by the count. + The first byte stored is the length of the string, or 255, whichever is + smaller. The bytes of the string follow. If the string passed in to + :func:`pack` is too long (longer than the count minus 1), only the leading + ``count-1`` bytes of the string are stored. If the string is shorter than + ``count-1``, it is padded with null bytes so that exactly count bytes in all + are used. Note that for :func:`unpack`, the ``'p'`` format character consumes + ``count`` bytes, but that the string returned can never contain more than 255 + bytes. + +(9) + For the ``'s'`` format character, the count is interpreted as the length of the + bytes, not a repeat count like for the other format characters; for example, + ``'10s'`` means a single 10-byte string mapping to or from a single + Python byte string, while ``'10c'`` means 10 + separate one byte character elements (e.g., ``cccccccccc``) mapping + to or from ten different Python byte objects. (See :ref:`struct-examples` + for a concrete demonstration of the difference.) + If a count is not given, it defaults to 1. For packing, the string is + truncated or padded with null bytes as appropriate to make it fit. For + unpacking, the resulting bytes object always has exactly the specified number + of bytes. As a special case, ``'0s'`` means a single, empty string (while + ``'0c'`` means 0 characters). A format character may be preceded by an integral repeat count. For example, the format string ``'4h'`` means exactly the same as ``'hhhh'``. @@ -297,15 +336,6 @@ the format string ``'4h'`` means exactly the same as ``'hhhh'``. Whitespace characters between formats are ignored; a count and its format must not contain whitespace though. -For the ``'s'`` format character, the count is interpreted as the length of the -bytes, not a repeat count like for the other format characters; for example, -``'10s'`` means a single 10-byte string, while ``'10c'`` means 10 characters. -If a count is not given, it defaults to 1. For packing, the string is -truncated or padded with null bytes as appropriate to make it fit. For -unpacking, the resulting bytes object always has exactly the specified number -of bytes. As a special case, ``'0s'`` means a single, empty string (while -``'0c'`` means 0 characters). - When packing a value ``x`` using one of the integer formats (``'b'``, ``'B'``, ``'h'``, ``'H'``, ``'i'``, ``'I'``, ``'l'``, ``'L'``, ``'q'``, ``'Q'``), if ``x`` is outside the valid range for that format @@ -315,17 +345,6 @@ then :exc:`struct.error` is raised. Previously, some of the integer formats wrapped out-of-range values and raised :exc:`DeprecationWarning` instead of :exc:`struct.error`. -The ``'p'`` format character encodes a "Pascal string", meaning a short -variable-length string stored in a *fixed number of bytes*, given by the count. -The first byte stored is the length of the string, or 255, whichever is -smaller. The bytes of the string follow. If the string passed in to -:func:`pack` is too long (longer than the count minus 1), only the leading -``count-1`` bytes of the string are stored. If the string is shorter than -``count-1``, it is padded with null bytes so that exactly count bytes in all -are used. Note that for :func:`unpack`, the ``'p'`` format character consumes -``count`` bytes, but that the string returned can never contain more than 255 -bytes. - .. index:: single: ? (question mark); in struct format strings For the ``'?'`` format character, the return value is either :const:`True` or @@ -341,18 +360,36 @@ Examples ^^^^^^^^ .. note:: - All examples assume a native byte order, size, and alignment with a - big-endian machine. + Native byte order examples (designated by the ``'@'`` format prefix or + lack of any prefix character) may not match what the reader's + machine produces as + that depends on the platform and compiler. -A basic example of packing/unpacking three integers:: +Pack and unpack integers of three different sizes, using big endian +ordering:: - >>> from struct import * - >>> pack('hhl', 1, 2, 3) - b'\x00\x01\x00\x02\x00\x00\x00\x03' - >>> unpack('hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03') - (1, 2, 3) - >>> calcsize('hhl') - 8 + >>> from struct import * + >>> pack(">bhl", 1, 2, 3) + b'\x01\x00\x02\x00\x00\x00\x03' + >>> unpack('>bhl', b'\x01\x00\x02\x00\x00\x00\x03' + (1, 2, 3) + >>> calcsize('>bhl') + 7 + +Attempt to pack an integer which is too large for the defined field:: + + >>> pack(">h", 99999) + Traceback (most recent call last): + File "", line 1, in + struct.error: 'h' format requires -32768 <= number <= 32767 + +Demonstrate the difference between ``'s'`` and ``'c'`` format +characters:: + + >>> pack("@ccc", b'1', b'2', b'3') + b'123' + >>> pack("@3s", b'123') + b'123' Unpacked fields can be named by assigning them to variables or by wrapping the result in a named tuple:: @@ -365,35 +402,132 @@ the result in a named tuple:: >>> Student._make(unpack('<10sHHb', record)) Student(name=b'raymond ', serialnum=4658, school=264, gradelevel=8) -The ordering of format characters may have an impact on size since the padding -needed to satisfy alignment requirements is different:: +The ordering of format characters may have an impact on size in native +mode since padding is implicit. In standard mode, the user is +responsible for inserting any desired padding. +Note in +the first ``pack`` call below that three NUL bytes were added after the +packed ``'#'`` to align the following integer on a four-byte boundary. +In this example, the output was produced on a little endian machine:: - >>> pack('ci', b'*', 0x12131415) - b'*\x00\x00\x00\x12\x13\x14\x15' - >>> pack('ic', 0x12131415, b'*') - b'\x12\x13\x14\x15*' - >>> calcsize('ci') + >>> pack('@ci', b'#', 0x12131415) + b'#\x00\x00\x00\x15\x14\x13\x12' + >>> pack('@ic', 0x12131415, b'#') + b'\x15\x14\x13\x12#' + >>> calcsize('@ci') 8 - >>> calcsize('ic') + >>> calcsize('@ic') 5 -The following format ``'llh0l'`` specifies two pad bytes at the end, assuming -longs are aligned on 4-byte boundaries:: +The following format ``'llh0l'`` results in two pad bytes being added +at the end, assuming the platform's longs are aligned on 4-byte boundaries:: - >>> pack('llh0l', 1, 2, 3) + >>> pack('@llh0l', 1, 2, 3) b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00' -This only works when native size and alignment are in effect; standard size and -alignment does not enforce any alignment. - .. seealso:: Module :mod:`array` Packed binary storage of homogeneous data. - Module :mod:`xdrlib` - Packing and unpacking of XDR data. + Module :mod:`json` + JSON encoder and decoder. + + Module :mod:`pickle` + Python object serialization. + + +.. _applications: + +Applications +------------ + +Two main applications for the :mod:`struct` module exist, data +interchange between Python and C code within an application or another +application compiled using the same compiler (:ref:`native formats`), and +data interchange between applications using agreed upon data layout +(:ref:`standard formats`). Generally speaking, the format strings +constructed for these two domains are distinct. + + +.. _struct-native-formats: + +Native Formats +^^^^^^^^^^^^^^ + +When constructing format strings which mimic native layouts, the +compiler and machine architecture determine byte ordering and padding. +In such cases, the ``@`` format character should be used to specify +native byte ordering and data sizes. Internal pad bytes are normally inserted +automatically. It is possible that a zero-repeat format code will be +needed at the end of a format string to round up to the correct +byte boundary for proper alignment of consecutive chunks of data. + +Consider these two simple examples (on a 64-bit, little-endian +machine):: + + >>> calcsize('@lhl') + 24 + >>> calcsize('@llh') + 18 + +Data is not padded to an 8-byte boundary at the end of the second +format string without the use of extra padding. A zero-repeat format +code solves that problem:: + + >>> calcsize('@llh0l') + 24 + +The ``'x'`` format code can be used to specify the repeat, but for +native formats it is better to use a zero-repeat format like ``'0l'``. + +By default, native byte ordering and alignment is used, but it is +better to be explicit and use the ``'@'`` prefix character. + + +.. _struct-standard-formats: + +Standard Formats +^^^^^^^^^^^^^^^^ + +When exchanging data beyond your process such as networking or storage, +be precise. Specify the exact byte order, size, and alignment. Do +not assume they match the native order of a particular machine. +For example, network byte order is big-endian, while many popular CPUs +are little-endian. By defining this explicitly, the user need not +care about the specifics of the platform their code is running on. +The first character should typically be ``<`` or ``>`` +(or ``!``). Padding is the responsibility of the programmer. The +zero-repeat format character won't work. Instead, the user must +explicitly add ``'x'`` pad bytes where needed. Revisiting the +examples from the previous section, we have:: + + >>> calcsize('>> pack('>> calcsize('@llh') + 18 + >>> pack('@llh', 1, 2, 3) == pack('>> calcsize('>> calcsize('@llh0l') + 24 + >>> pack('@llh0l', 1, 2, 3) == pack('>> calcsize('>> calcsize('@llh0l') + 12 + >>> pack('@llh0l', 1, 2, 3) == pack('>> subprocess.getstatusoutput('/bin/kill $$') (-15, '') - .. availability:: POSIX & Windows. + .. availability:: Unix, Windows. .. versionchanged:: 3.3.4 Windows support was added. @@ -1473,8 +1490,10 @@ handling consistency are valid for these functions. as it did in Python 3.3.3 and earlier. exitcode has the same value as :attr:`~Popen.returncode`. + .. versionadded:: 3.11 + Added *encoding* and *errors* arguments. -.. function:: getoutput(cmd) +.. function:: getoutput(cmd, *, encoding=None, errors=None) Return output (stdout and stderr) of executing *cmd* in a shell. @@ -1484,11 +1503,14 @@ handling consistency are valid for these functions. >>> subprocess.getoutput('ls /bin/ls') '/bin/ls' - .. availability:: POSIX & Windows. + .. availability:: Unix, Windows. .. versionchanged:: 3.3.4 Windows support added + .. versionadded:: 3.11 + Added *encoding* and *errors* arguments. + Notes ----- @@ -1527,3 +1549,43 @@ runtime): :mod:`shlex` Module which provides function to parse and escape command lines. + + +.. _disable_vfork: +.. _disable_posix_spawn: + +Disabling use of ``vfork()`` or ``posix_spawn()`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +On Linux, :mod:`subprocess` defaults to using the ``vfork()`` system call +internally when it is safe to do so rather than ``fork()``. This greatly +improves performance. + +If you ever encounter a presumed highly unusual situation where you need to +prevent ``vfork()`` from being used by Python, you can set the +:attr:`subprocess._USE_VFORK` attribute to a false value. + +:: + + subprocess._USE_VFORK = False # See CPython issue gh-NNNNNN. + +Setting this has no impact on use of ``posix_spawn()`` which could use +``vfork()`` internally within its libc implementation. There is a similar +:attr:`subprocess._USE_POSIX_SPAWN` attribute if you need to prevent use of +that. + +:: + + subprocess._USE_POSIX_SPAWN = False # See CPython issue gh-NNNNNN. + +It is safe to set these to false on any Python version. They will have no +effect on older versions when unsupported. Do not assume the attributes are +available to read. Despite their names, a true value does not indicate that the +corresponding function will be used, only that that it may be. + +Please file issues any time you have to use these private knobs with a way to +reproduce the issue you were seeing. Link to that issue from a comment in your +code. + +.. versionadded:: 3.8 ``_USE_POSIX_SPAWN`` +.. versionadded:: 3.11 ``_USE_VFORK`` diff --git a/Doc/library/sunau.rst b/Doc/library/sunau.rst index aad6f93b6bf..c7a38d96ade 100644 --- a/Doc/library/sunau.rst +++ b/Doc/library/sunau.rst @@ -3,11 +3,16 @@ .. module:: sunau :synopsis: Provide an interface to the Sun AU sound format. + :deprecated: .. sectionauthor:: Moshe Zadka **Source code:** :source:`Lib/sunau.py` +.. deprecated-removed:: 3.11 3.13 + The :mod:`sunau` module is deprecated + (see :pep:`PEP 594 <594#sunau>` for details). + -------------- The :mod:`sunau` module provides a convenient interface to the Sun AU sound diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst index 50a5983236e..8786e227be9 100644 --- a/Doc/library/superseded.rst +++ b/Doc/library/superseded.rst @@ -10,5 +10,24 @@ backwards compatibility. They have been superseded by other modules. .. toctree:: - optparse.rst + aifc.rst + audioop.rst + cgi.rst + cgitb.rst + chunk.rst + crypt.rst + imghdr.rst imp.rst + mailcap.rst + msilib.rst + nis.rst + nntplib.rst + optparse.rst + ossaudiodev.rst + pipes.rst + sndhdr.rst + spwd.rst + sunau.rst + telnetlib.rst + uu.rst + xdrlib.rst diff --git a/Doc/library/symtable.rst b/Doc/library/symtable.rst index 0264f891cc8..65ff5bfe7ab 100644 --- a/Doc/library/symtable.rst +++ b/Doc/library/symtable.rst @@ -69,7 +69,8 @@ Examining Symbol Tables .. method:: get_identifiers() - Return a list of names of symbols in this table. + Return a view object containing the names of symbols in the table. + See the :ref:`documentation of view objects `. .. method:: lookup(name) diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 175fc091652..605e2c9a671 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -35,6 +35,15 @@ always available. can then log the event, raise an exception to abort the operation, or terminate the process entirely. + Note that audit hooks are primarily for collecting information about internal + or otherwise unobservable actions, whether by Python or libraries written in + Python. They are not suitable for implementing a "sandbox". In particular, + malicious code can trivially disable or bypass hooks added using this + function. At a minimum, any security-sensitive hooks must be added using the + C API :c:func:`PySys_AddAuditHook` before initialising the runtime, and any + modules allowing arbitrary memory modification (such as :mod:`ctypes`) should + be completely removed or closely monitored. + .. audit-event:: sys.addaudithook "" sys.addaudithook Calling :func:`sys.addaudithook` will itself raise an auditing event @@ -250,7 +259,7 @@ always available. Print low-level information to stderr about the state of CPython's memory allocator. - If Python is `built in debug mode ` (:option:`configure + If Python is :ref:`built in debug mode ` (:option:`configure --with-pydebug option <--with-pydebug>`), it also performs some expensive internal consistency checks. @@ -314,13 +323,42 @@ always available. yourself to control bytecode file generation. +.. data:: _emscripten_info + + A :term:`named tuple` holding information about the environment on the + *wasm32-emscripten* platform. The named tuple is provisional and may change + in the future. + + .. tabularcolumns:: |l|L| + + +-----------------------------+----------------------------------------------+ + | Attribute | Explanation | + +=============================+==============================================+ + | :const:`emscripten_version` | Emscripten version as tuple of ints | + | | (major, minor, micro), e.g. ``(3, 1, 8)``. | + +-----------------------------+----------------------------------------------+ + | :const:`runtime` | Runtime string, e.g. browser user agent, | + | | ``'Node.js v14.18.2'``, or ``'UNKNOWN'``. | + +-----------------------------+----------------------------------------------+ + | :const:`pthreads` | ``True`` if Python is compiled with | + | | Emscripten pthreads support. | + +-----------------------------+----------------------------------------------+ + | :const:`shared_memory` | ``True`` if Python is compiled with shared | + | | memory support. | + +-----------------------------+----------------------------------------------+ + + .. availability:: Emscripten. + + .. versionadded:: 3.11 + + .. data:: pycache_prefix If this is set (not ``None``), Python will write bytecode-cache ``.pyc`` files to (and read them from) a parallel directory tree rooted at this directory, rather than from ``__pycache__`` directories in the source code tree. Any ``__pycache__`` directories in the source code tree will be ignored - and new `.pyc` files written within the pycache prefix. Thus if you use + and new ``.pyc`` files written within the pycache prefix. Thus if you use :mod:`compileall` as a pre-build step, you must ensure you run it with the same pycache prefix (if any) that you will use at runtime. @@ -378,27 +416,40 @@ always available. .. versionadded:: 3.8 __unraisablehook__ + +.. function:: exception() + + This function, when called while an exception handler is executing (such as + an ``except`` or ``except*`` clause), returns the exception instance that + was caught by this handler. When exception handlers are nested within one + another, only the exception handled by the innermost handler is accessible. + + If no exception handler is executing, this function returns ``None``. + + .. versionadded:: 3.11 + + .. function:: exc_info() - This function returns a tuple of three values that give information about the - exception that is currently being handled. The information returned is specific - both to the current thread and to the current stack frame. If the current stack - frame is not handling an exception, the information is taken from the calling - stack frame, or its caller, and so on until a stack frame is found that is - handling an exception. Here, "handling an exception" is defined as "executing - an except clause." For any stack frame, only information about the exception - being currently handled is accessible. + This function returns the old-style representation of the handled + exception. If an exception ``e`` is currently handled (so + :func:`exception` would return ``e``), :func:`exc_info` returns the + tuple ``(type(e), e, e.__traceback__)``. + That is, a tuple containing the type of the exception (a subclass of + :exc:`BaseException`), the exception itself, and a :ref:`traceback + object ` which typically encapsulates the call + stack at the point where the exception last occurred. .. index:: object: traceback - If no exception is being handled anywhere on the stack, a tuple containing - three ``None`` values is returned. Otherwise, the values returned are - ``(type, value, traceback)``. Their meaning is: *type* gets the type of the - exception being handled (a subclass of :exc:`BaseException`); *value* gets - the exception instance (an instance of the exception type); *traceback* gets - a :ref:`traceback object ` which encapsulates the call - stack at the point where the exception originally occurred. + If no exception is being handled anywhere on the stack, this function + return a tuple containing three ``None`` values. + .. versionchanged:: 3.11 + The ``type`` and ``traceback`` fields are now derived from the ``value`` + (the exception instance), so when an exception is modified while it is + being handled, the changes are reflected in the results of subsequent + calls to :func:`exc_info`. .. data:: exec_prefix @@ -429,10 +480,7 @@ always available. .. function:: exit([arg]) - Exit from Python. This is implemented by raising the :exc:`SystemExit` - exception, so cleanup actions specified by finally clauses of :keyword:`try` - statements are honored, and it is possible to intercept the exit attempt at - an outer level. + Raise a :exc:`SystemExit` exception, signaling an intention to exit the interpreter. The optional argument *arg* can be an integer giving the exit status (defaulting to zero), or another type of object. If it is an integer, zero @@ -449,7 +497,8 @@ always available. Since :func:`exit` ultimately "only" raises an exception, it will only exit the process when called from the main thread, and the exception is not - intercepted. + intercepted. Cleanup actions specified by finally clauses of :keyword:`try` statements + are honored, and it is possible to intercept the exit attempt at an outer level. .. versionchanged:: 3.6 If an error occurs in the cleanup after the Python interpreter @@ -462,9 +511,9 @@ always available. The :term:`named tuple` *flags* exposes the status of command line flags. The attributes are read only. - ============================= ================================================================ + ============================= ============================================================================================================== attribute flag - ============================= ================================================================ + ============================= ============================================================================================================== :const:`debug` :option:`-d` :const:`inspect` :option:`-i` :const:`interactive` :option:`-i` @@ -480,7 +529,9 @@ always available. :const:`hash_randomization` :option:`-R` :const:`dev_mode` :option:`-X dev <-X>` (:ref:`Python Development Mode `) :const:`utf8_mode` :option:`-X utf8 <-X>` - ============================= ================================================================ + :const:`safe_path` :option:`-P` + :const:`int_max_str_digits` :option:`-X int_max_str_digits <-X>` (:ref:`integer string conversion length limitation `) + ============================= ============================================================================================================== .. versionchanged:: 3.2 Added ``quiet`` attribute for the new :option:`-q` flag. @@ -499,6 +550,12 @@ always available. Mode ` and the ``utf8_mode`` attribute for the new :option:`-X` ``utf8`` flag. + .. versionchanged:: 3.11 + Added the ``safe_path`` attribute for :option:`-P` option. + + .. versionchanged:: 3.11 + Added the ``int_max_str_digits`` attribute. + .. data:: float_info @@ -547,12 +604,18 @@ always available. +---------------------+----------------+--------------------------------------------------+ | :const:`radix` | FLT_RADIX | radix of exponent representation | +---------------------+----------------+--------------------------------------------------+ - | :const:`rounds` | FLT_ROUNDS | integer constant representing the rounding mode | - | | | used for arithmetic operations. This reflects | - | | | the value of the system FLT_ROUNDS macro at | - | | | interpreter startup time. See section 5.2.4.2.2 | - | | | of the C99 standard for an explanation of the | - | | | possible values and their meanings. | + | :const:`rounds` | FLT_ROUNDS | integer representing the rounding mode for | + | | | floating-point arithmetic. This reflects the | + | | | value of the system FLT_ROUNDS macro at | + | | | interpreter startup time: | + | | | ``-1`` indeterminable, | + | | | ``0`` toward zero, | + | | | ``1`` to nearest, | + | | | ``2`` toward positive infinity, | + | | | ``3`` toward negative infinity | + | | | | + | | | All other values for FLT_ROUNDS characterize | + | | | implementation-defined rounding behavior. | +---------------------+----------------+--------------------------------------------------+ The attribute :attr:`sys.float_info.dig` needs further explanation. If @@ -679,6 +742,13 @@ always available. .. versionadded:: 3.6 +.. function:: get_int_max_str_digits() + + Returns the current value for the :ref:`integer string conversion length + limitation `. See also :func:`set_int_max_str_digits`. + + .. versionadded:: 3.11 + .. function:: getrefcount(object) Return the reference count of the *object*. The count returned is generally one @@ -730,7 +800,23 @@ always available. that is deeper than the call stack, :exc:`ValueError` is raised. The default for *depth* is zero, returning the frame at the top of the call stack. - .. audit-event:: sys._getframe "" sys._getframe + .. audit-event:: sys._getframe frame sys._getframe + + .. impl-detail:: + + This function should be used for internal and specialized purposes only. + It is not guaranteed to exist in all implementations of Python. + + +.. function:: _getframemodulename([depth]) + + Return the name of a module from the call stack. If optional integer *depth* + is given, return the module that many calls below the top of the stack. If + that is deeper than the call stack, or if the module is unidentifiable, + ``None`` is returned. The default for *depth* is zero, returning the + module at the top of the call stack. + + .. audit-event:: sys._getframemodulename depth sys._getframemodulename .. impl-detail:: @@ -819,7 +905,7 @@ always available. .. function:: get_asyncgen_hooks() Returns an *asyncgen_hooks* object, which is similar to a - :class:`~collections.namedtuple` of the form `(firstiter, finalizer)`, + :class:`~collections.namedtuple` of the form ``(firstiter, finalizer)``, where *firstiter* and *finalizer* are expected to be either ``None`` or functions which take an :term:`asynchronous generator iterator` as an argument, and are used to schedule finalization of an asynchronous @@ -952,19 +1038,31 @@ always available. .. tabularcolumns:: |l|L| - +-------------------------+----------------------------------------------+ - | Attribute | Explanation | - +=========================+==============================================+ - | :const:`bits_per_digit` | number of bits held in each digit. Python | - | | integers are stored internally in base | - | | ``2**int_info.bits_per_digit`` | - +-------------------------+----------------------------------------------+ - | :const:`sizeof_digit` | size in bytes of the C type used to | - | | represent a digit | - +-------------------------+----------------------------------------------+ + +----------------------------------------+-----------------------------------------------+ + | Attribute | Explanation | + +========================================+===============================================+ + | :const:`bits_per_digit` | number of bits held in each digit. Python | + | | integers are stored internally in base | + | | ``2**int_info.bits_per_digit`` | + +----------------------------------------+-----------------------------------------------+ + | :const:`sizeof_digit` | size in bytes of the C type used to | + | | represent a digit | + +----------------------------------------+-----------------------------------------------+ + | :const:`default_max_str_digits` | default value for | + | | :func:`sys.get_int_max_str_digits` when it | + | | is not otherwise explicitly configured. | + +----------------------------------------+-----------------------------------------------+ + | :const:`str_digits_check_threshold` | minimum non-zero value for | + | | :func:`sys.set_int_max_str_digits`, | + | | :envvar:`PYTHONINTMAXSTRDIGITS`, or | + | | :option:`-X int_max_str_digits <-X>`. | + +----------------------------------------+-----------------------------------------------+ .. versionadded:: 3.1 + .. versionchanged:: 3.11 + Added ``default_max_str_digits`` and ``str_digits_check_threshold``. + .. data:: __interactivehook__ @@ -1043,7 +1141,8 @@ always available. A list of :term:`meta path finder` objects that have their :meth:`~importlib.abc.MetaPathFinder.find_spec` methods called to see if one - of the objects can find the module to be imported. The + of the objects can find the module to be imported. By default, it holds entries + that implement Python's default import semantics. The :meth:`~importlib.abc.MetaPathFinder.find_spec` method is called with at least the absolute name of the module being imported. If the module to be imported is contained in a package, then the parent package's :attr:`__path__` @@ -1098,23 +1197,28 @@ always available. the environment variable :envvar:`PYTHONPATH`, plus an installation-dependent default. - As initialized upon program startup, the first item of this list, ``path[0]``, - is the directory containing the script that was used to invoke the Python - interpreter. If the script directory is not available (e.g. if the interpreter - is invoked interactively or if the script is read from standard input), - ``path[0]`` is the empty string, which directs Python to search modules in the - current directory first. Notice that the script directory is inserted *before* - the entries inserted as a result of :envvar:`PYTHONPATH`. + By default, as initialized upon program startup, a potentially unsafe path + is prepended to :data:`sys.path` (*before* the entries inserted as a result + of :envvar:`PYTHONPATH`): + + * ``python -m module`` command line: prepend the current working + directory. + * ``python script.py`` command line: prepend the script's directory. + If it's a symbolic link, resolve symbolic links. + * ``python -c code`` and ``python`` (REPL) command lines: prepend an empty + string, which means the current working directory. + + To not prepend this potentially unsafe path, use the :option:`-P` command + line option or the :envvar:`PYTHONSAFEPATH` environment variable. A program is free to modify this list for its own purposes. Only strings - and bytes should be added to :data:`sys.path`; all other data types are + should be added to :data:`sys.path`; all other data types are ignored during import. .. seealso:: - Module :mod:`site` This describes how to use .pth files to extend - :data:`sys.path`. - + * Module :mod:`site` This describes how to use .pth files to + extend :data:`sys.path`. .. data:: path_hooks @@ -1164,7 +1268,9 @@ always available. System ``platform`` value ================ =========================== AIX ``'aix'`` + Emscripten ``'emscripten'`` Linux ``'linux'`` + WASI ``'wasi'`` Windows ``'win32'`` Windows/Cygwin ``'cygwin'`` macOS ``'darwin'`` @@ -1256,6 +1362,14 @@ always available. .. availability:: Unix. +.. function:: set_int_max_str_digits(maxdigits) + + Set the :ref:`integer string conversion length limitation + ` used by this interpreter. See also + :func:`get_int_max_str_digits`. + + .. versionadded:: 3.11 + .. function:: setprofile(profilefunc) .. index:: @@ -1472,6 +1586,38 @@ always available. This function has been added on a provisional basis (see :pep:`411` for details.) Use it only for debugging purposes. +.. function:: activate_stack_trampoline(backend, /) + + Activate the stack profiler trampoline *backend*. + The only supported backend is ``"perf"``. + + .. availability:: Linux. + + .. versionadded:: 3.12 + + .. seealso:: + + * :ref:`perf_profiling` + * https://perf.wiki.kernel.org + +.. function:: deactivate_stack_trampoline() + + Deactivate the current stack profiler trampoline backend. + + If no stack profiler is activated, this function has no effect. + + .. availability:: Linux. + + .. versionadded:: 3.12 + +.. function:: is_stack_trampoline_active() + + Return ``True`` if a stack profiler trampoline is active. + + .. availability:: Linux. + + .. versionadded:: 3.12 + .. function:: _enablelegacywindowsfsencoding() Changes the :term:`filesystem encoding and error handler` to 'mbcs' and @@ -1606,6 +1752,8 @@ always available. | | | | | * ``'nt'``: Windows threads | | | * ``'pthread'``: POSIX threads | + | | * ``'pthread-stubs'``: stub POSIX threads | + | | (on WebAssembly platforms without threading support) | | | * ``'solaris'``: Solaris threads | +------------------+---------------------------------------------------------+ | :const:`lock` | Name of the lock implementation: | @@ -1711,7 +1859,7 @@ always available. The version number used to form registry keys on Windows platforms. This is stored as string resource 1000 in the Python DLL. The value is normally the - first three characters of :const:`version`. It is provided in the :mod:`sys` + major and minor versions of the running Python interpreter. It is provided in the :mod:`sys` module for informational purposes; modifying this value has no effect on the registry keys used by Python. @@ -1726,13 +1874,13 @@ always available. .. code-block:: shell-session - $ ./python -Xpycache_prefix=some_path -Xdev + $ ./python -Xa=b -Xc Python 3.2a3+ (py3k, Oct 16 2010, 20:14:50) [GCC 4.4.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> sys._xoptions - {'pycache_prefix': 'some_path', 'dev': True} + {'a': 'b', 'c': True} .. impl-detail:: @@ -1745,4 +1893,4 @@ always available. .. rubric:: Citations -.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf\ . +.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf\ . diff --git a/Doc/library/sys_path_init.rst b/Doc/library/sys_path_init.rst new file mode 100644 index 00000000000..72c1387344c --- /dev/null +++ b/Doc/library/sys_path_init.rst @@ -0,0 +1,108 @@ +.. _sys-path-init: + +The initialization of the :data:`sys.path` module search path +============================================================= + +A module search path is initialized when Python starts. This module search path +may be accessed at :data:`sys.path`. + +The first entry in the module search path is the directory that contains the +input script, if there is one. Otherwise, the first entry is the current +directory, which is the case when executing the interactive shell, a :option:`-c` +command, or :option:`-m` module. + +The :envvar:`PYTHONPATH` environment variable is often used to add directories +to the search path. If this environment variable is found then the contents are +added to the module search path. + +.. note:: + + :envvar:`PYTHONPATH` will affect all installed Python versions/environments. + Be wary of setting this in your shell profile or global environment variables. + The :mod:`site` module offers more nuanced techniques as mentioned below. + +The next items added are the directories containing standard Python modules as +well as any :term:`extension module`\s that these modules depend on. Extension +modules are ``.pyd`` files on Windows and ``.so`` files on other platforms. The +directory with the platform-independent Python modules is called ``prefix``. +The directory with the extension modules is called ``exec_prefix``. + +The :envvar:`PYTHONHOME` environment variable may be used to set the ``prefix`` +and ``exec_prefix`` locations. Otherwise these directories are found by using +the Python executable as a starting point and then looking for various 'landmark' +files and directories. Note that any symbolic links are followed so the real +Python executable location is used as the search starting point. The Python +executable location is called ``home``. + +Once ``home`` is determined, the ``prefix`` directory is found by first looking +for :file:`python{majorversion}{minorversion}.zip` (``python311.zip``). On Windows +the zip archive is searched for in ``home`` and on Unix the archive is expected +to be in :file:`lib`. Note that the expected zip archive location is added to the +module search path even if the archive does not exist. If no archive was found, +Python on Windows will continue the search for ``prefix`` by looking for :file:`Lib\\os.py`. +Python on Unix will look for :file:`lib/python{majorversion}.{minorversion}/os.py` +(``lib/python3.11/os.py``). On Windows ``prefix`` and ``exec_prefix`` are the same, +however on other platforms :file:`lib/python{majorversion}.{minorversion}/lib-dynload` +(``lib/python3.11/lib-dynload``) is searched for and used as an anchor for +``exec_prefix``. On some platforms :file:`lib` may be :file:`lib64` or another value, +see :data:`sys.platlibdir` and :envvar:`PYTHONPLATLIBDIR`. + +Once found, ``prefix`` and ``exec_prefix`` are available at :data:`sys.prefix` and +:data:`sys.exec_prefix` respectively. + +Finally, the :mod:`site` module is processed and :file:`site-packages` directories +are added to the module search path. A common way to customize the search path is +to create :mod:`sitecustomize` or :mod:`usercustomize` modules as described in +the :mod:`site` module documentation. + +.. note:: + + Certain command line options may further affect path calculations. + See :option:`-E`, :option:`-I`, :option:`-s` and :option:`-S` for further details. + +Virtual environments +-------------------- + +If Python is run in a virtual environment (as described at :ref:`tut-venv`) +then ``prefix`` and ``exec_prefix`` are specific to the virtual environment. + +If a ``pyvenv.cfg`` file is found alongside the main executable, or in the +directory one level above the executable, the following variations apply: + +* If ``home`` is an absolute path and :envvar:`PYTHONHOME` is not set, this + path is used instead of the path to the main executable when deducing ``prefix`` + and ``exec_prefix``. + +_pth files +---------- + +To completely override :data:`sys.path` create a ``._pth`` file with the same +name as the shared library or executable (``python._pth`` or ``python311._pth``). +The shared library path is always known on Windows, however it may not be +available on other platforms. In the ``._pth`` file specify one line for each path +to add to :data:`sys.path`. The file based on the shared library name overrides +the one based on the executable, which allows paths to be restricted for any +program loading the runtime if desired. + +When the file exists, all registry and environment variables are ignored, +isolated mode is enabled, and :mod:`site` is not imported unless one line in the +file specifies ``import site``. Blank paths and lines starting with ``#`` are +ignored. Each path may be absolute or relative to the location of the file. +Import statements other than to ``site`` are not permitted, and arbitrary code +cannot be specified. + +Note that ``.pth`` files (without leading underscore) will be processed normally +by the :mod:`site` module when ``import site`` has been specified. + +Embedded Python +--------------- + +If Python is embedded within another application :c:func:`Py_InitializeFromConfig` and +the :c:type:`PyConfig` structure can be used to initialize Python. The path specific +details are described at :ref:`init-path-config`. Alternatively the older :c:func:`Py_SetPath` +can be used to bypass the initialization of the module search path. + +.. seealso:: + + * :ref:`windows_finding_modules` for detailed Windows notes. + * :ref:`using-on-unix` for Unix details. diff --git a/Doc/library/sysconfig.rst b/Doc/library/sysconfig.rst index 7ef3b248967..839c2c015b4 100644 --- a/Doc/library/sysconfig.rst +++ b/Doc/library/sysconfig.rst @@ -25,7 +25,7 @@ Configuration variables A Python distribution contains a :file:`Makefile` and a :file:`pyconfig.h` header file that are necessary to build both the Python binary itself and -third-party C extensions compiled using :mod:`distutils`. +third-party C extensions compiled using ``setuptools``. :mod:`sysconfig` puts all variables found in these files in a dictionary that can be accessed using :func:`get_config_vars` or :func:`get_config_var`. @@ -73,7 +73,7 @@ Every new component that is installed using :mod:`distutils` or a Distutils-based system will follow the same scheme to copy its file in the right places. -Python currently supports six schemes: +Python currently supports nine schemes: - *posix_prefix*: scheme for POSIX platforms like Linux or macOS. This is the default scheme used when Python or a component is installed. @@ -83,8 +83,14 @@ Python currently supports six schemes: - *posix_user*: scheme for POSIX platforms used when a component is installed through Distutils and the *user* option is used. This scheme defines paths located under the user home directory. +- *posix_venv*: scheme for :mod:`Python virtual environments ` on POSIX + platforms; by default it is the same as *posix_prefix* . - *nt*: scheme for NT platforms like Windows. - *nt_user*: scheme for NT platforms, when the *user* option is used. +- *nt_venv*: scheme for :mod:`Python virtual environments ` on NT + platforms; by default it is the same as *nt* . +- *venv*: a scheme with values from ether *posix_venv* or *nt_venv* depending + on the platform Python runs on - *osx_framework_user*: scheme for macOS, when the *user* option is used. Each scheme is itself composed of a series of paths and each path has a unique @@ -96,8 +102,10 @@ identifier. Python currently uses eight paths: platform-specific. - *platlib*: directory for site-specific, platform-specific files. - *purelib*: directory for site-specific, non-platform-specific files. -- *include*: directory for non-platform-specific header files. -- *platinclude*: directory for platform-specific header files. +- *include*: directory for non-platform-specific header files for + the Python C-API. +- *platinclude*: directory for platform-specific header files for + the Python C-API. - *scripts*: directory for script files. - *data*: directory for data files. @@ -113,10 +121,13 @@ identifier. Python currently uses eight paths: Return the default scheme name for the current platform. - .. versionchanged:: 3.10 + .. versionadded:: 3.10 This function was previously named ``_get_default_scheme()`` and considered an implementation detail. + .. versionchanged:: 3.11 + When Python runs from a virtual environment, + the *venv* scheme is returned. .. function:: get_preferred_scheme(key) @@ -130,6 +141,10 @@ identifier. Python currently uses eight paths: .. versionadded:: 3.10 + .. versionchanged:: 3.11 + When Python runs from a virtual environment and ``key="prefix"``, + the *venv* scheme is returned. + .. function:: _get_preferred_schemes() diff --git a/Doc/library/syslog.rst b/Doc/library/syslog.rst index d264a3340c9..f29ef03267b 100644 --- a/Doc/library/syslog.rst +++ b/Doc/library/syslog.rst @@ -15,6 +15,8 @@ This module wraps the system ``syslog`` family of routines. A pure Python library that can speak to a syslog server is available in the :mod:`logging.handlers` module as :class:`SysLogHandler`. +.. include:: ../includes/wasm-notavail.rst + The module defines the following functions: @@ -29,10 +31,22 @@ The module defines the following functions: value given in the :func:`openlog` call is used. If :func:`openlog` has not been called prior to the call to :func:`syslog`, - ``openlog()`` will be called with no arguments. + :func:`openlog` will be called with no arguments. .. audit-event:: syslog.syslog priority,message syslog.syslog + .. versionchanged:: 3.2 + In previous versions, :func:`openlog` would not be called automatically if + it wasn't called prior to the call to :func:`syslog`, deferring to the syslog + implementation to call ``openlog()``. + + .. versionchanged:: 3.12 + This function is restricted in subinterpreters. + (Only code that runs in multiple interpreters is affected and + the restriction is not relevant for most users.) + :func:`openlog` must be called in the main interpreter before :func:`syslog` may be used + in a subinterpreter. Otherwise it will raise :exc:`RuntimeError`. + .. function:: openlog([ident[, logoption[, facility]]]) @@ -51,8 +65,14 @@ The module defines the following functions: .. versionchanged:: 3.2 In previous versions, keyword arguments were not allowed, and *ident* was - required. The default for *ident* was dependent on the system libraries, - and often was ``python`` instead of the name of the Python program file. + required. + + .. versionchanged:: 3.12 + This function is restricted in subinterpreters. + (Only code that runs in multiple interpreters is affected and + the restriction is not relevant for most users.) + This may only be called in the main interpreter. + It will raise :exc:`RuntimeError` if called in a subinterpreter. .. function:: closelog() @@ -66,6 +86,13 @@ The module defines the following functions: .. audit-event:: syslog.closelog "" syslog.closelog + .. versionchanged:: 3.12 + This function is restricted in subinterpreters. + (Only code that runs in multiple interpreters is affected and + the restriction is not relevant for most users.) + This may only be called in the main interpreter. + It will raise :exc:`RuntimeError` if called in a subinterpreter. + .. function:: setlogmask(maskpri) diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index 6afb8397b78..6e8baba04fb 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -63,19 +63,19 @@ Some facts and figures: +------------------+---------------------------------------------+ | ``'x'`` or | Create a tarfile exclusively without | | ``'x:'`` | compression. | - | | Raise an :exc:`FileExistsError` exception | + | | Raise a :exc:`FileExistsError` exception | | | if it already exists. | +------------------+---------------------------------------------+ | ``'x:gz'`` | Create a tarfile with gzip compression. | - | | Raise an :exc:`FileExistsError` exception | + | | Raise a :exc:`FileExistsError` exception | | | if it already exists. | +------------------+---------------------------------------------+ | ``'x:bz2'`` | Create a tarfile with bzip2 compression. | - | | Raise an :exc:`FileExistsError` exception | + | | Raise a :exc:`FileExistsError` exception | | | if it already exists. | +------------------+---------------------------------------------+ | ``'x:xz'`` | Create a tarfile with lzma compression. | - | | Raise an :exc:`FileExistsError` exception | + | | Raise a :exc:`FileExistsError` exception | | | if it already exists. | +------------------+---------------------------------------------+ | ``'a' or 'a:'`` | Open for appending with no compression. The | @@ -98,8 +98,8 @@ Some facts and figures: If *fileobj* is specified, it is used as an alternative to a :term:`file object` opened in binary mode for *name*. It is supposed to be at position 0. - For modes ``'w:gz'``, ``'r:gz'``, ``'w:bz2'``, ``'r:bz2'``, ``'x:gz'``, - ``'x:bz2'``, :func:`tarfile.open` accepts the keyword argument + For modes ``'w:gz'``, ``'x:gz'``, ``'w|gz'``, ``'w:bz2'``, ``'x:bz2'``, + ``'w|bz2'``, :func:`tarfile.open` accepts the keyword argument *compresslevel* (default ``9``) to specify the compression level of the file. For modes ``'w:xz'`` and ``'x:xz'``, :func:`tarfile.open` accepts the @@ -152,6 +152,9 @@ Some facts and figures: .. versionchanged:: 3.6 The *name* parameter accepts a :term:`path-like object`. + .. versionchanged:: 3.12 + The *compresslevel* keyword argument also works for streams. + .. class:: TarFile :noindex: @@ -836,7 +839,7 @@ There are three tar formats that can be created with the :mod:`tarfile` module: files and stores pathnames in a portable way. Modern tar implementations, including GNU tar, bsdtar/libarchive and star, fully support extended *pax* features; some old or unmaintained libraries may not, but should treat - *pax* archives as if they were in the universally-supported *ustar* format. + *pax* archives as if they were in the universally supported *ustar* format. It is the current default format for new archives. It extends the existing *ustar* format with extra headers for information diff --git a/Doc/library/telnetlib.rst b/Doc/library/telnetlib.rst index 48a9aea50dd..5a993dc42a5 100644 --- a/Doc/library/telnetlib.rst +++ b/Doc/library/telnetlib.rst @@ -3,6 +3,7 @@ .. module:: telnetlib :synopsis: Telnet client class. + :deprecated: .. sectionauthor:: Skip Montanaro @@ -10,6 +11,10 @@ .. index:: single: protocol; Telnet +.. deprecated-removed:: 3.11 3.13 + The :mod:`telnetlib` module is deprecated + (see :pep:`PEP 594 <594#telnetlib>` for details and alternatives). + -------------- The :mod:`telnetlib` module provides a :class:`Telnet` class that implements the @@ -25,6 +30,7 @@ SE (Subnegotiation End), NOP (No Operation), DM (Data Mark), BRK (Break), IP (Interrupt process), AO (Abort output), AYT (Are You There), EC (Erase Character), EL (Erase Line), GA (Go Ahead), SB (Subnegotiation Begin). +.. include:: ../includes/wasm-notavail.rst .. class:: Telnet(host=None, port=0[, timeout]) diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index 3e904d04642..b6d4f5dd05b 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -62,6 +62,9 @@ The module defines the following user-callable items: The :py:data:`os.O_TMPFILE` flag is used if it is available and works (Linux-specific, requires Linux kernel 3.11 or later). + On platforms that are neither Posix nor Cygwin, TemporaryFile is an alias + for NamedTemporaryFile. + .. audit-event:: tempfile.mkstemp fullpath tempfile.TemporaryFile .. versionchanged:: 3.5 @@ -72,20 +75,61 @@ The module defines the following user-callable items: Added *errors* parameter. -.. function:: NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True, *, errors=None) +.. function:: NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True, *, errors=None, delete_on_close=True) - This function operates exactly as :func:`TemporaryFile` does, except that - the file is guaranteed to have a visible name in the file system (on - Unix, the directory entry is not unlinked). That name can be retrieved - from the :attr:`name` attribute of the returned - file-like object. Whether the name can be - used to open the file a second time, while the named temporary file is - still open, varies across platforms (it can be so used on Unix; it cannot - on Windows NT or later). If *delete* is true (the default), the file is - deleted as soon as it is closed. - The returned object is always a file-like object whose :attr:`!file` - attribute is the underlying true file object. This file-like object can - be used in a :keyword:`with` statement, just like a normal file. + This function operates exactly as :func:`TemporaryFile` does, except the + following differences: + + * This function returns a file that is guaranteed to have a visible name in + the file system. + * To manage the named file, it extends the parameters of + :func:`TemporaryFile` with *delete* and *delete_on_close* parameters that + determine whether and how the named file should be automatically deleted. + + The returned object is always a :term:`file-like object` whose :attr:`!file` + attribute is the underlying true file object. This :term:`file-like object` + can be used in a :keyword:`with` statement, just like a normal file. The + name of the temporary file can be retrieved from the :attr:`name` attribute + of the returned file-like object. On Unix, unlike with the + :func:`TemporaryFile`, the directory entry does not get unlinked immediately + after the file creation. + + If *delete* is true (the default) and *delete_on_close* is true (the + default), the file is deleted as soon as it is closed. If *delete* is true + and *delete_on_close* is false, the file is deleted on context manager exit + only, or else when the :term:`file-like object` is finalized. Deletion is not + always guaranteed in this case (see :meth:`object.__del__`). If *delete* is + false, the value of *delete_on_close* is ignored. + + Therefore to use the name of the temporary file to reopen the file after + closing it, either make sure not to delete the file upon closure (set the + *delete* parameter to be false) or, in case the temporary file is created in + a :keyword:`with` statement, set the *delete_on_close* parameter to be false. + The latter approach is recommended as it provides assistance in automatic + cleaning of the temporary file upon the context manager exit. + + Opening the temporary file again by its name while it is still open works as + follows: + + * On POSIX the file can always be opened again. + * On Windows, make sure that at least one of the following conditions are + fulfilled: + + * *delete* is false + * additional open shares delete access (e.g. by calling :func:`os.open` + with the flag ``O_TEMPORARY``) + * *delete* is true but *delete_on_close* is false. Note, that in this + case the additional opens that do not share delete access (e.g. + created via builtin :func:`open`) must be closed before exiting the + context manager, else the :func:`os.unlink` call on context manager + exit will fail with a :exc:`PermissionError`. + + On Windows, if *delete_on_close* is false, and the file is created in a + directory for which the user lacks delete access, then the :func:`os.unlink` + call on exit of the context manager will fail with a :exc:`PermissionError`. + This cannot happen when *delete_on_close* is true because delete access is + requested by the open, which fails immediately if the requested access is not + granted. On POSIX (only), a process that is terminated abruptly with SIGKILL cannot automatically delete any NamedTemporaryFiles it created. @@ -95,10 +139,13 @@ The module defines the following user-callable items: .. versionchanged:: 3.8 Added *errors* parameter. + .. versionchanged:: 3.12 + Added *delete_on_close* parameter. -.. function:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None) - This function operates exactly as :func:`TemporaryFile` does, except that +.. class:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None) + + This class operates exactly as :func:`TemporaryFile` does, except that data is spooled in memory until the file size exceeds *max_size*, or until the file's :func:`fileno` method is called, at which point the contents are written to disk and operation proceeds as with @@ -120,10 +167,15 @@ The module defines the following user-callable items: .. versionchanged:: 3.8 Added *errors* parameter. + .. versionchanged:: 3.11 + Fully implements the :class:`io.BufferedIOBase` and + :class:`io.TextIOBase` abstract base classes (depending on whether binary + or text *mode* was specified). -.. function:: TemporaryDirectory(suffix=None, prefix=None, dir=None, ignore_cleanup_errors=False) - This function securely creates a temporary directory using the same rules as :func:`mkdtemp`. +.. class:: TemporaryDirectory(suffix=None, prefix=None, dir=None, ignore_cleanup_errors=False) + + This class securely creates a temporary directory using the same rules as :func:`mkdtemp`. The resulting object can be used as a context manager (see :ref:`tempfile-examples`). On completion of the context or destruction of the temporary directory object, the newly created temporary directory @@ -338,6 +390,19 @@ Here are some examples of typical usage of the :mod:`tempfile` module:: >>> # file is now closed and removed + # create a temporary file using a context manager + # close the file, use the name to open the file again + >>> with tempfile.TemporaryFile(delete_on_close=False) as fp: + ... fp.write(b'Hello world!') + ... fp.close() + # the file is closed, but not removed + # open the file again by using its name + ... with open(fp.name) as f + ... f.read() + b'Hello world!' + >>> + # file is now removed + # create a temporary directory using the context manager >>> with tempfile.TemporaryDirectory() as tmpdirname: ... print('created temporary directory', tmpdirname) diff --git a/Doc/library/termios.rst b/Doc/library/termios.rst index 3b0cb60f874..fb1ff567d49 100644 --- a/Doc/library/termios.rst +++ b/Doc/library/termios.rst @@ -85,11 +85,11 @@ The module defines the following functions: .. function:: tcsetwinsize(fd, winsize) - Set the tty window size for file descriptor *fd* from *winsize*, which is - a two-item tuple ``(ws_row, ws_col)`` like the one returned by - :func:`tcgetwinsize`. Requires at least one of the pairs - (:const:`termios.TIOCGWINSZ`, :const:`termios.TIOCSWINSZ`); - (:const:`termios.TIOCGSIZE`, :const:`termios.TIOCSSIZE`) to be defined. + Set the tty window size for file descriptor *fd* from *winsize*, which is + a two-item tuple ``(ws_row, ws_col)`` like the one returned by + :func:`tcgetwinsize`. Requires at least one of the pairs + (:const:`termios.TIOCGWINSZ`, :const:`termios.TIOCSWINSZ`); + (:const:`termios.TIOCGSIZE`, :const:`termios.TIOCSSIZE`) to be defined. .. versionadded:: 3.11 diff --git a/Doc/library/test.rst b/Doc/library/test.rst index 699db14596f..8199a27d7d9 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -319,6 +319,15 @@ The :mod:`test.support` module defines the following constants: to make writes blocking. +.. data:: Py_DEBUG + + True if Python is built with the :c:macro:`Py_DEBUG` macro defined: if + Python is :ref:`built in debug mode ` + (:option:`./configure --with-pydebug <--with-pydebug>`). + + .. versionadded:: 3.12 + + .. data:: SOCK_MAX_SIZE A constant that is likely larger than the underlying OS socket buffer size, @@ -359,13 +368,19 @@ The :mod:`test.support` module defines the following constants: .. data:: MISSING_C_DOCSTRINGS - Return ``True`` if running on CPython, not on Windows, and configuration - not set with ``WITH_DOC_STRINGS``. + Set to ``True`` if Python is built without docstrings (the + :c:macro:`WITH_DOC_STRINGS` macro is not defined). + See the :option:`configure --without-doc-strings <--without-doc-strings>` option. + + See also the :data:`HAVE_DOCSTRINGS` variable. .. data:: HAVE_DOCSTRINGS - Check for presence of docstrings. + Set to ``True`` if function docstrings are available. + See the :option:`python -OO <-O>` option, which strips docstrings of functions implemented in Python. + + See also the :data:`MISSING_C_DOCSTRINGS` variable. .. data:: TEST_HTTP_URL @@ -398,6 +413,51 @@ The :mod:`test.support` module defines the following constants: The :mod:`test.support` module defines the following functions: +.. function:: busy_retry(timeout, err_msg=None, /, *, error=True) + + Run the loop body until ``break`` stops the loop. + + After *timeout* seconds, raise an :exc:`AssertionError` if *error* is true, + or just stop the loop if *error* is false. + + Example:: + + for _ in support.busy_retry(support.SHORT_TIMEOUT): + if check(): + break + + Example of error=False usage:: + + for _ in support.busy_retry(support.SHORT_TIMEOUT, error=False): + if check(): + break + else: + raise RuntimeError('my custom error') + +.. function:: sleeping_retry(timeout, err_msg=None, /, *, init_delay=0.010, max_delay=1.0, error=True) + + Wait strategy that applies exponential backoff. + + Run the loop body until ``break`` stops the loop. Sleep at each loop + iteration, but not at the first iteration. The sleep delay is doubled at + each iteration (up to *max_delay* seconds). + + See :func:`busy_retry` documentation for the parameters usage. + + Example raising an exception after SHORT_TIMEOUT seconds:: + + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if check(): + break + + Example of error=False usage:: + + for _ in support.sleeping_retry(support.SHORT_TIMEOUT, error=False): + if check(): + break + else: + raise RuntimeError('my custom error') + .. function:: is_resource_enabled(resource) Return ``True`` if *resource* is enabled and available. The list of @@ -423,11 +483,6 @@ The :mod:`test.support` module defines the following functions: Used when tests are executed by :mod:`test.regrtest`. -.. function:: system_must_validate_cert(f) - - Raise :exc:`unittest.SkipTest` on TLS certification validation failures. - - .. function:: sortdict(dict) Return a repr of *dict* with keys sorted. @@ -445,12 +500,12 @@ The :mod:`test.support` module defines the following functions: .. function:: match_test(test) - Match *test* to patterns set in :func:`set_match_tests`. + Determine whether *test* matches the patterns set in :func:`set_match_tests`. -.. function:: set_match_tests(patterns) +.. function:: set_match_tests(accept_patterns=None, ignore_patterns=None) - Define match test with regular expression *patterns*. + Define match patterns on test filenames and test method names for filtering tests. .. function:: run_unittest(*classes) @@ -490,7 +545,9 @@ The :mod:`test.support` module defines the following functions: .. function:: check_impl_detail(**guards) Use this check to guard CPython's implementation-specific tests or to - run them only on the implementations guarded by the arguments:: + run them only on the implementations guarded by the arguments. This + function returns ``True`` or ``False`` depending on the host platform. + Example usage:: check_impl_detail() # Only on CPython (default). check_impl_detail(jython=True) # Only on Jython. @@ -509,7 +566,7 @@ The :mod:`test.support` module defines the following functions: time the regrtest began. -.. function:: get_original_stdout +.. function:: get_original_stdout() Return the original stdout set by :func:`record_original_stdout` or ``sys.stdout`` if it's not set. @@ -554,7 +611,7 @@ The :mod:`test.support` module defines the following functions: .. function:: disable_faulthandler() - A context manager that replaces ``sys.stderr`` with ``sys.__stderr__``. + A context manager that temporary disables :mod:`faulthandler`. .. function:: gc_collect() @@ -567,8 +624,8 @@ The :mod:`test.support` module defines the following functions: .. function:: disable_gc() - A context manager that disables the garbage collector upon entry and - reenables it upon exit. + A context manager that disables the garbage collector on entry. On + exit, the garbage collector is restored to its prior state. .. function:: swap_attr(obj, attr, new_val) @@ -642,14 +699,14 @@ The :mod:`test.support` module defines the following functions: .. function:: calcobjsize(fmt) - Return :func:`struct.calcsize` for ``nP{fmt}0n`` or, if ``gettotalrefcount`` - exists, ``2PnP{fmt}0P``. + Return the size of the :c:type:`PyObject` whose structure members are + defined by *fmt*. The returned value includes the size of the Python object header and alignment. .. function:: calcvobjsize(fmt) - Return :func:`struct.calcsize` for ``nPn{fmt}0n`` or, if ``gettotalrefcount`` - exists, ``2PnPn{fmt}0P``. + Return the size of the :c:type:`PyVarObject` whose structure members are + defined by *fmt*. The returned value includes the size of the Python object header and alignment. .. function:: checksizeof(test, o, size) @@ -665,6 +722,11 @@ The :mod:`test.support` module defines the following functions: have an associated comment identifying the relevant tracker issue. +.. function:: system_must_validate_cert(f) + + A decorator that skips the decorated test on TLS certification validation failures. + + .. decorator:: run_with_locale(catstr, *locales) A decorator for running a function in a different locale, correctly @@ -682,19 +744,19 @@ The :mod:`test.support` module defines the following functions: .. decorator:: requires_freebsd_version(*min_version) Decorator for the minimum version when running test on FreeBSD. If the - FreeBSD version is less than the minimum, raise :exc:`unittest.SkipTest`. + FreeBSD version is less than the minimum, the test is skipped. .. decorator:: requires_linux_version(*min_version) Decorator for the minimum version when running test on Linux. If the - Linux version is less than the minimum, raise :exc:`unittest.SkipTest`. + Linux version is less than the minimum, the test is skipped. .. decorator:: requires_mac_version(*min_version) Decorator for the minimum version when running test on macOS. If the - macOS version is less than the minimum, raise :exc:`unittest.SkipTest`. + macOS version is less than the minimum, the test is skipped. .. decorator:: requires_IEEE_754 @@ -732,7 +794,13 @@ The :mod:`test.support` module defines the following functions: Decorator for only running the test if :data:`HAVE_DOCSTRINGS`. -.. decorator:: cpython_only(test) +.. decorator:: requires_limited_api + + Decorator for only running the test if :ref:`Limited C API ` + is available. + + +.. decorator:: cpython_only Decorator for tests only applicable to CPython. @@ -743,12 +811,12 @@ The :mod:`test.support` module defines the following functions: returns ``False``, then uses *msg* as the reason for skipping the test. -.. decorator:: no_tracing(func) +.. decorator:: no_tracing Decorator to temporarily turn off tracing for the duration of the test. -.. decorator:: refcount_test(test) +.. decorator:: refcount_test Decorator for tests which involve reference counting. The decorator does not run the test if it is not run by CPython. Any trace function is unset @@ -771,10 +839,9 @@ The :mod:`test.support` module defines the following functions: means the test doesn't support dummy runs when ``-M`` is not specified. -.. decorator:: bigaddrspacetest(f) +.. decorator:: bigaddrspacetest - Decorator for tests that fill the address space. *f* is the function to - wrap. + Decorator for tests that fill the address space. .. function:: check_syntax_error(testcase, statement, errtext='', *, lineno=None, offset=None) @@ -876,7 +943,7 @@ The :mod:`test.support` module defines the following functions: .. function:: check_free_after_iterating(test, iter, cls, args=()) - Assert that *iter* is deallocated after iterating. + Assert instances of *cls* are deallocated after iterating. .. function:: missing_compiler_executable(cmd_names=[]) @@ -944,6 +1011,16 @@ The :mod:`test.support` module defines the following functions: .. versionadded:: 3.10 +.. function:: adjust_int_max_str_digits(max_digits) + + This function returns a context manager that will change the global + :func:`sys.set_int_max_str_digits` setting for the duration of the + context to allow execution of test code that needs a different limit + on the number of digits when converting between an integer and string. + + .. versionadded:: 3.11 + + The :mod:`test.support` module defines the following classes: @@ -967,6 +1044,16 @@ The :mod:`test.support` module defines the following classes: Class to save and restore signal handlers registered by the Python signal handler. + .. method:: save(self) + + Save the signal handlers to a dictionary mapping signal numbers to the + current signal handler. + + .. method:: restore(self) + + Set the signal numbers from the :meth:`save` dictionary to the saved + handler. + .. class:: Matcher() @@ -980,13 +1067,6 @@ The :mod:`test.support` module defines the following classes: Try to match a single stored value (*dv*) with a supplied value (*v*). -.. class:: BasicTestRunner() - - .. method:: run(test) - - Run *test* and return the result. - - :mod:`test.support.socket_helper` --- Utilities for socket tests ================================================================ @@ -1048,7 +1128,7 @@ The :mod:`test.support.socket_helper` module provides support for socket tests. .. function:: bind_unix_socket(sock, addr) - Bind a unix socket, raising :exc:`unittest.SkipTest` if + Bind a Unix socket, raising :exc:`unittest.SkipTest` if :exc:`PermissionError` is raised. @@ -1110,11 +1190,11 @@ script execution tests. variables *env_vars* succeeds (``rc == 0``) and return a ``(return code, stdout, stderr)`` tuple. - If the ``__cleanenv`` keyword is set, *env_vars* is used as a fresh + If the *__cleanenv* keyword-only parameter is set, *env_vars* is used as a fresh environment. Python is started in isolated mode (command line option ``-I``), - except if the ``__isolated`` keyword is set to ``False``. + except if the *__isolated* keyword-only parameter is set to ``False``. .. versionchanged:: 3.9 The function no longer strips whitespaces from *stderr*. @@ -1225,15 +1305,17 @@ The :mod:`test.support.threading_helper` module provides support for threading t is still alive after *timeout* seconds. -.. decorator:: reap_threads(func) +.. decorator:: reap_threads Decorator to ensure the threads are cleaned up even if the test fails. .. function:: start_threads(threads, unlock=None) - Context manager to start *threads*. It attempts to join the threads upon - exit. + Context manager to start *threads*, which is a sequence of threads. + *unlock* is a function called after the threads are started, even if an + exception was raised; an example would be :meth:`threading.Event.set`. + ``start_threads`` will attempt to join the started threads upon exit. .. function:: threading_cleanup(*original_values) @@ -1315,7 +1397,10 @@ The :mod:`test.support.os_helper` module provides support for os tests. .. data:: TESTFN_NONASCII - Set to a filename containing the :data:`FS_NONASCII` character. + Set to a filename containing the :data:`FS_NONASCII` character, if it exists. + This guarantees that if the filename exists, it can be encoded and decoded + with the default filesystem encoding. This allows tests that require a + non-ASCII filename to be easily skipped on platforms where they can't work. .. data:: TESTFN_UNENCODABLE @@ -1413,13 +1498,16 @@ The :mod:`test.support.os_helper` module provides support for os tests. .. function:: rmdir(filename) Call :func:`os.rmdir` on *filename*. On Windows platforms, this is - wrapped with a wait loop that checks for the existence of the file. + wrapped with a wait loop that checks for the existence of the file, + which is needed due to antivirus programs that can hold files open and prevent + deletion. .. function:: rmtree(path) Call :func:`shutil.rmtree` on *path* or call :func:`os.lstat` and - :func:`os.rmdir` to remove a path and its contents. On Windows platforms, + :func:`os.rmdir` to remove a path and its contents. As with :func:`rmdir`, + on Windows platforms this is wrapped with a wait loop that checks for the existence of the files. @@ -1466,7 +1554,8 @@ The :mod:`test.support.os_helper` module provides support for os tests. .. function:: unlink(filename) - Call :func:`os.unlink` on *filename*. On Windows platforms, this is + Call :func:`os.unlink` on *filename*. As with :func:`rmdir`, + on Windows platforms, this is wrapped with a wait loop that checks for the existence of the file. @@ -1523,7 +1612,7 @@ The :mod:`test.support.import_helper` module provides support for import tests. .. versionadded:: 3.1 -.. function:: import_module(name, deprecated=False, *, required_on()) +.. function:: import_module(name, deprecated=False, *, required_on=()) This function imports and returns the named module. Unlike a normal import, this function raises :exc:`unittest.SkipTest` if the module @@ -1565,7 +1654,7 @@ The :mod:`test.support.import_helper` module provides support for import tests. A context manager to force import to return a new module reference. This is useful for testing module-level behaviors, such as the emission of a - DeprecationWarning on import. Example usage:: + :exc:`DeprecationWarning` on import. Example usage:: with CleanImport('foo'): importlib.import_module('foo') # New reference. @@ -1573,7 +1662,7 @@ The :mod:`test.support.import_helper` module provides support for import tests. .. class:: DirsOnSysPath(*paths) - A context manager to temporarily add directories to sys.path. + A context manager to temporarily add directories to :data:`sys.path`. This makes a copy of :data:`sys.path`, appends any directories given as positional arguments, then reverts :data:`sys.path` to the copied diff --git a/Doc/library/textwrap.rst b/Doc/library/textwrap.rst index 7780e241769..1a9d5f98f78 100644 --- a/Doc/library/textwrap.rst +++ b/Doc/library/textwrap.rst @@ -21,7 +21,8 @@ functions should be good enough; otherwise, you should use an instance of subsequent_indent="", expand_tabs=True, \ replace_whitespace=True, fix_sentence_endings=False, \ break_long_words=True, drop_whitespace=True, \ - break_on_hyphens=True, tabsize=8, max_lines=None) + break_on_hyphens=True, tabsize=8, max_lines=None, \ + placeholder=' [...]') Wraps the single paragraph in *text* (a string) so every line is at most *width* characters long. Returns a list of output lines, without final @@ -39,7 +40,7 @@ functions should be good enough; otherwise, you should use an instance of replace_whitespace=True, fix_sentence_endings=False, \ break_long_words=True, drop_whitespace=True, \ break_on_hyphens=True, tabsize=8, \ - max_lines=None) + max_lines=None, placeholder=' [...]') Wraps the single paragraph in *text*, and returns a single string containing the wrapped paragraph. :func:`fill` is shorthand for :: diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 8c7664328a4..b352125551f 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -9,11 +9,23 @@ -------------- This module constructs higher-level threading interfaces on top of the lower -level :mod:`_thread` module. See also the :mod:`queue` module. +level :mod:`_thread` module. .. versionchanged:: 3.7 This module used to be optional, it is now always available. +.. seealso:: + + :class:`concurrent.futures.ThreadPoolExecutor` offers a higher level interface + to push tasks to a background thread without blocking execution of the + calling thread, while still being able to retrieve their results when needed. + + :mod:`queue` provides a thread-safe interface for exchanging data between + running threads. + + :mod:`asyncio` offers an alternative approach to achieving task level + concurrency without requiring the use of multiple operating system threads. + .. note:: In the Python 2.x series, this module contained ``camelCase`` names @@ -33,6 +45,7 @@ level :mod:`_thread` module. See also the :mod:`queue` module. However, threading is still an appropriate model if you want to run multiple I/O-bound tasks simultaneously. +.. include:: ../includes/wasm-notavail.rst This module defines the following functions: @@ -114,7 +127,7 @@ This module defines the following functions: Its value may be used to uniquely identify this particular thread system-wide (until the thread terminates, after which the value may be recycled by the OS). - .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX. + .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD. .. versionadded:: 3.8 @@ -145,6 +158,15 @@ This module defines the following functions: The *func* will be passed to :func:`sys.settrace` for each thread, before its :meth:`~Thread.run` method is called. +.. function:: settrace_all_threads(func) + + Set a trace function for all threads started from the :mod:`threading` module + and all Python threads that are currently executing. + + The *func* will be passed to :func:`sys.settrace` for each thread, before its + :meth:`~Thread.run` method is called. + + .. versionadded:: 3.12 .. function:: gettrace() @@ -165,6 +187,15 @@ This module defines the following functions: The *func* will be passed to :func:`sys.setprofile` for each thread, before its :meth:`~Thread.run` method is called. +.. function:: setprofile_all_threads(func) + + Set a profile function for all threads started from the :mod:`threading` module + and all Python threads that are currently executing. + + The *func* will be passed to :func:`sys.setprofile` for each thread, before its + :meth:`~Thread.run` method is called. + + .. versionadded:: 3.12 .. function:: getprofile() @@ -192,7 +223,9 @@ This module defines the following functions: information (4 KiB pages are common; using multiples of 4096 for the stack size is the suggested approach in the absence of more specific information). - .. availability:: Windows, systems with POSIX threads. + .. availability:: Windows, pthreads. + + Unix platforms with POSIX threads support. This module also defines the following constant: @@ -293,7 +326,7 @@ There is the possibility that "dummy thread objects" are created. These are thread objects corresponding to "alien threads", which are threads of control started outside the threading module, such as directly from C code. Dummy thread objects have limited functionality; they are always considered alive and -daemonic, and cannot be :meth:`~Thread.join`\ ed. They are never deleted, +daemonic, and cannot be :ref:`joined `. They are never deleted, since it is impossible to detect the termination of alien threads. @@ -314,7 +347,7 @@ since it is impossible to detect the termination of alien threads. or "Thread-*N* (target)" where "target" is ``target.__name__`` if the *target* argument is specified. - *args* is the argument tuple for the target invocation. Defaults to ``()``. + *args* is a list or tuple of arguments for the target invocation. Defaults to ``()``. *kwargs* is a dictionary of keyword arguments for the target invocation. Defaults to ``{}``. @@ -353,6 +386,21 @@ since it is impossible to detect the termination of alien threads. the *target* argument, if any, with positional and keyword arguments taken from the *args* and *kwargs* arguments, respectively. + Using list or tuple as the *args* argument which passed to the :class:`Thread` + could achieve the same effect. + + Example:: + + >>> from threading import Thread + >>> t = Thread(target=print, args=[1]) + >>> t.run() + 1 + >>> t = Thread(target=print, args=(1,)) + >>> t.run() + 1 + + .. _meth-thread-join: + .. method:: join(timeout=None) Wait until the thread terminates. This blocks the calling thread until @@ -370,7 +418,7 @@ since it is impossible to detect the termination of alien threads. When the *timeout* argument is not present or ``None``, the operation will block until the thread terminates. - A thread can be :meth:`~Thread.join`\ ed many times. + A thread can be joined many times. :meth:`~Thread.join` raises a :exc:`RuntimeError` if an attempt is made to join the current thread as that would cause a deadlock. It is also @@ -414,7 +462,7 @@ since it is impossible to detect the termination of alien threads. system-wide) from the time the thread is created until the thread has been terminated. - .. availability:: Requires :func:`get_native_id` function. + .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD. .. versionadded:: 3.8 @@ -428,8 +476,8 @@ since it is impossible to detect the termination of alien threads. .. attribute:: daemon - A boolean value indicating whether this thread is a daemon thread (True) - or not (False). This must be set before :meth:`~Thread.start` is called, + A boolean value indicating whether this thread is a daemon thread (``True``) + or not (``False``). This must be set before :meth:`~Thread.start` is called, otherwise :exc:`RuntimeError` is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to @@ -503,7 +551,7 @@ All methods are executed atomically. value, block for at most the number of seconds specified by *timeout* and as long as the lock cannot be acquired. A *timeout* argument of ``-1`` specifies an unbounded wait. It is forbidden to specify a *timeout* - when *blocking* is false. + when *blocking* is ``False``. The return value is ``True`` if the lock is acquired successfully, ``False`` if not (for example if the *timeout* expired). @@ -531,7 +579,7 @@ All methods are executed atomically. .. method:: locked() - Return true if the lock is acquired. + Return ``True`` if the lock is acquired. @@ -580,17 +628,17 @@ Reentrant locks also support the :ref:`context management protocol ` is unlocked, only one at a time will be able to grab ownership of the lock. There is no return value in this case. - When invoked with the *blocking* argument set to true, do the same thing as when + When invoked with the *blocking* argument set to ``True``, do the same thing as when called without arguments, and return ``True``. - When invoked with the *blocking* argument set to false, do not block. If a call + When invoked with the *blocking* argument set to ``False``, do not block. If a call without an argument would block, return ``False`` immediately; otherwise, do the same thing as when called without arguments, and return ``True``. When invoked with the floating-point *timeout* argument set to a positive value, block for at most the number of seconds specified by *timeout* and as long as the lock cannot be acquired. Return ``True`` if the lock has - been acquired, false if the timeout has elapsed. + been acquired, ``False`` if the timeout has elapsed. .. versionchanged:: 3.2 The *timeout* parameter is new. @@ -831,7 +879,7 @@ Semaphores also support the :ref:`context management protocol `. thread will be awoken by each call to :meth:`~Semaphore.release`. The order in which threads are awoken should not be relied on. - When invoked with *blocking* set to false, do not block. If a call + When invoked with *blocking* set to ``False``, do not block. If a call without an argument would block, return ``False`` immediately; otherwise, do the same thing as when called without arguments, and return ``True``. diff --git a/Doc/library/time.rst b/Doc/library/time.rst index 622f66719ce..9f23a6fc7d5 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -21,10 +21,8 @@ An explanation of some terminology and conventions is in order. .. index:: single: epoch -* The :dfn:`epoch` is the point where the time starts, and is platform - dependent. For Unix, the epoch is January 1, 1970, 00:00:00 (UTC). - To find out what the epoch is on a given platform, look at - ``time.gmtime(0)``. +* The :dfn:`epoch` is the point where the time starts, the return value of + ``time.gmtime(0)``. It is January 1, 1970, 00:00:00 (UTC) on all platforms. .. _leap seconds: https://en.wikipedia.org/wiki/Leap_second @@ -37,7 +35,7 @@ An explanation of some terminology and conventions is in order. .. index:: single: Year 2038 -* The functions in this module may not handle dates and times before the epoch or +* The functions in this module may not handle dates and times before the epoch_ or far in the future. The cut-off point in the future is determined by the C library; for 32-bit systems, it is typically in 2038. @@ -146,8 +144,10 @@ Functions Passing an invalid or expired *thread_id* may result in undefined behavior, such as segmentation fault. - .. availability:: Unix (see the man page for :manpage:`pthread_getcpuclockid(3)` for - further information). + .. availability:: Unix + + See the man page for :manpage:`pthread_getcpuclockid(3)` for + further information. .. versionadded:: 3.7 @@ -207,7 +207,7 @@ Functions .. function:: ctime([secs]) - Convert a time expressed in seconds since the epoch to a string of a form: + Convert a time expressed in seconds since the epoch_ to a string of a form: ``'Sun Jun 20 23:21:05 1993'`` representing local time. The day field is two characters long and is space padded if the day is a single digit, e.g.: ``'Wed Jun 9 04:26:40 1993'``. @@ -245,7 +245,7 @@ Functions .. function:: gmtime([secs]) - Convert a time expressed in seconds since the epoch to a :class:`struct_time` in + Convert a time expressed in seconds since the epoch_ to a :class:`struct_time` in UTC in which the dst flag is always zero. If *secs* is not provided or :const:`None`, the current time as returned by :func:`.time` is used. Fractions of a second are ignored. See above for a description of the @@ -259,6 +259,12 @@ Functions :const:`None`, the current time as returned by :func:`.time` is used. The dst flag is set to ``1`` when DST applies to the given time. + :func:`localtime` may raise :exc:`OverflowError`, if the timestamp is + outside the range of values supported by the platform C :c:func:`localtime` + or :c:func:`gmtime` functions, and :exc:`OSError` on :c:func:`localtime` or + :c:func:`gmtime` failure. It's common for this to be restricted to years + between 1970 and 2038. + .. function:: mktime(t) @@ -476,10 +482,10 @@ Functions | | negative time difference from UTC/GMT of the | | | | form +HHMM or -HHMM, where H represents decimal| | | | hour digits and M represents decimal minute | | - | | digits [-23:59, +23:59]. | | + | | digits [-23:59, +23:59]. [1]_ | | +-----------+------------------------------------------------+-------+ | ``%Z`` | Time zone name (no characters if no time zone | | - | | exists). | | + | | exists). Deprecated. [1]_ | | +-----------+------------------------------------------------+-------+ | ``%%`` | A literal ``'%'`` character. | | +-----------+------------------------------------------------+-------+ @@ -500,7 +506,7 @@ Functions calculations when the day of the week and the year are specified. Here is an example, a format for dates compatible with that specified in the - :rfc:`2822` Internet email standard. [#]_ :: + :rfc:`2822` Internet email standard. [1]_ :: >>> from time import gmtime, strftime >>> strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime()) @@ -601,14 +607,10 @@ Functions .. function:: time() -> float Return the time in seconds since the epoch_ as a floating point - number. The specific date of the epoch and the handling of - `leap seconds`_ is platform dependent. - On Windows and most Unix systems, the epoch is January 1, 1970, - 00:00:00 (UTC) and leap seconds are not counted towards the time - in seconds since the epoch. This is commonly referred to as - `Unix time `_. - To find out what the epoch is on a given platform, look at - ``gmtime(0)``. + number. The handling of `leap seconds`_ is platform dependent. + On Windows and most Unix systems, the leap seconds are not counted towards + the time in seconds since the epoch_. This is commonly referred to as `Unix + time `_. Note that even though the time is always returned as a floating point number, not all systems provide time with a better precision than 1 second. @@ -629,8 +631,8 @@ Functions .. function:: time_ns() -> int - Similar to :func:`~time.time` but returns time as an integer number of nanoseconds - since the epoch_. + Similar to :func:`~time.time` but returns time as an integer number of + nanoseconds since the epoch_. .. versionadded:: 3.7 @@ -651,8 +653,9 @@ Functions Use :func:`thread_time_ns` to avoid the precision loss caused by the :class:`float` type. - .. availability:: Windows, Linux, Unix systems supporting - ``CLOCK_THREAD_CPUTIME_ID``. + .. availability:: Linux, Unix, Windows. + + Unix systems supporting ``CLOCK_THREAD_CPUTIME_ID``. .. versionadded:: 3.7 @@ -770,7 +773,7 @@ These constants are used as parameters for :func:`clock_getres` and have discontinuities if the time is changed using ``settimeofday()`` or similar. - .. availability:: Linux 2.6.39 or later. + .. availability:: Linux >= 2.6.39. .. versionadded:: 3.7 @@ -801,7 +804,7 @@ These constants are used as parameters for :func:`clock_getres` and Similar to :data:`CLOCK_MONOTONIC`, but provides access to a raw hardware-based time that is not subject to NTP adjustments. - .. availability:: Linux 2.6.28 and newer, macOS 10.12 and newer. + .. availability:: Linux >= 2.6.28, macOS >= 10.12. .. versionadded:: 3.3 @@ -819,7 +822,7 @@ These constants are used as parameters for :func:`clock_getres` and High-resolution per-process timer from the CPU. - .. availability:: FreeBSD, NetBSD 7 or later, OpenBSD. + .. availability:: FreeBSD, NetBSD >= 7, OpenBSD. .. versionadded:: 3.7 @@ -849,7 +852,7 @@ These constants are used as parameters for :func:`clock_getres` and suspended, providing accurate uptime measurement, both absolute and interval. - .. availability:: FreeBSD, OpenBSD 5.5 or later. + .. availability:: FreeBSD, OpenBSD >= 5.5. .. versionadded:: 3.7 @@ -860,7 +863,7 @@ These constants are used as parameters for :func:`clock_getres` and point, unaffected by frequency or time adjustments and not incremented while the system is asleep. - .. availability:: macOS 10.12 and newer. + .. availability:: macOS >= 10.12. .. versionadded:: 3.8 @@ -928,10 +931,9 @@ Timezone Constants .. rubric:: Footnotes -.. [#] The use of ``%Z`` is now deprecated, but the ``%z`` escape that expands to the - preferred hour/minute offset is not supported by all ANSI C libraries. Also, a +.. [1] The use of ``%Z`` is now deprecated, but the ``%z`` escape that expands to the + preferred hour/minute offset is not supported by all ANSI C libraries. Also, a strict reading of the original 1982 :rfc:`822` standard calls for a two-digit - year (%y rather than %Y), but practice moved to 4-digit years long before the + year (``%y`` rather than ``%Y``), but practice moved to 4-digit years long before the year 2000. After that, :rfc:`822` became obsolete and the 4-digit year has been first recommended by :rfc:`1123` and then mandated by :rfc:`2822`. - diff --git a/Doc/library/timeit.rst b/Doc/library/timeit.rst index 7f1c41d4639..5437704cec3 100644 --- a/Doc/library/timeit.rst +++ b/Doc/library/timeit.rst @@ -27,11 +27,11 @@ can be used to compare three different expressions: .. code-block:: shell-session - $ python3 -m timeit '"-".join(str(n) for n in range(100))' + $ python -m timeit '"-".join(str(n) for n in range(100))' 10000 loops, best of 5: 30.2 usec per loop - $ python3 -m timeit '"-".join([str(n) for n in range(100)])' + $ python -m timeit '"-".join([str(n) for n in range(100)])' 10000 loops, best of 5: 27.5 usec per loop - $ python3 -m timeit '"-".join(map(str, range(100)))' + $ python -m timeit '"-".join(map(str, range(100)))' 10000 loops, best of 5: 23.2 usec per loop This can be achieved from the :ref:`python-interface` with:: @@ -282,6 +282,13 @@ It is possible to provide a setup statement that is executed only once at the be $ python -m timeit -s 'text = "sample string"; char = "g"' 'text.find(char)' 1000000 loops, best of 5: 0.342 usec per loop +In the output, there are three fields. The loop count, which tells you how many +times the statement body was run per timing loop repetition. The repetition +count ('best of 5') which tells you how many times the timing loop was +repeated, and finally the time the statement body took on average within the +best repetition of the timing loop. That is, the time the fastest repetition +took divided by the loop count. + :: >>> import timeit diff --git a/Doc/library/tk.rst b/Doc/library/tk.rst index 0cb8fda4e32..3dc2130539c 100644 --- a/Doc/library/tk.rst +++ b/Doc/library/tk.rst @@ -44,4 +44,4 @@ alternative `GUI frameworks and tools `_ + * `TkDocs `_ Extensive tutorial on creating user interfaces with Tkinter. Explains key concepts, and illustrates recommended approaches using the modern API. @@ -61,7 +61,7 @@ details that are unchanged. * `Python and Tkinter Programming `_ By Alan Moore. (ISBN 978-1788835886) - * `Programming Python `_ + * `Programming Python `_ By Mark Lutz; has excellent coverage of Tkinter. (ISBN 978-0596158101) * `Tcl and the Tk Toolkit (2nd edition) `_ @@ -90,7 +90,7 @@ Tcl (see `Threading model`_ for details). Tk - Tk is a `Tcl package `_ implemented in C + Tk is a `Tcl package `_ implemented in C that adds custom commands to create and manipulate GUI widgets. Each :class:`Tk` object embeds its own Tcl interpreter instance with Tk loaded into it. Tk's widgets are very customizable, though at the cost of a dated appearance. @@ -124,16 +124,72 @@ the modern themed widget set and API:: from tkinter import ttk -.. class:: Tk(screenName=None, baseName=None, className='Tk', useTk=1) +.. class:: Tk(screenName=None, baseName=None, className='Tk', useTk=True, sync=False, use=None) - The :class:`Tk` class is instantiated without arguments. This creates a toplevel - widget of Tk which usually is the main window of an application. Each instance - has its own associated Tcl interpreter. + Construct a toplevel Tk widget, which is usually the main window of an + application, and initialize a Tcl interpreter for this widget. Each + instance has its own associated Tcl interpreter. - .. FIXME: The following keyword arguments are currently recognized: + The :class:`Tk` class is typically instantiated using all default values. + However, the following keyword arguments are currently recognized: + + *screenName* + When given (as a string), sets the :envvar:`DISPLAY` environment + variable. (X11 only) + *baseName* + Name of the profile file. By default, *baseName* is derived from the + program name (``sys.argv[0]``). + *className* + Name of the widget class. Used as a profile file and also as the name + with which Tcl is invoked (*argv0* in *interp*). + *useTk* + If ``True``, initialize the Tk subsystem. The :func:`tkinter.Tcl() ` + function sets this to ``False``. + *sync* + If ``True``, execute all X server commands synchronously, so that errors + are reported immediately. Can be used for debugging. (X11 only) + *use* + Specifies the *id* of the window in which to embed the application, + instead of it being created as an independent toplevel window. *id* must + be specified in the same way as the value for the -use option for + toplevel widgets (that is, it has a form like that returned by + :meth:`winfo_id`). + + Note that on some platforms this will only work correctly if *id* refers + to a Tk frame or toplevel that has its -container option enabled. + + :class:`Tk` reads and interprets profile files, named + :file:`.{className}.tcl` and :file:`.{baseName}.tcl`, into the Tcl + interpreter and calls :func:`exec` on the contents of + :file:`.{className}.py` and :file:`.{baseName}.py`. The path for the + profile files is the :envvar:`HOME` environment variable or, if that + isn't defined, then :attr:`os.curdir`. + + .. attribute:: tk + + The Tk application object created by instantiating :class:`Tk`. This + provides access to the Tcl interpreter. Each widget that is attached + the same instance of :class:`Tk` has the same value for its :attr:`tk` + attribute. + + .. attribute:: master + + The widget object that contains this widget. For :class:`Tk`, the + *master* is :const:`None` because it is the main window. The terms + *master* and *parent* are similar and sometimes used interchangeably + as argument names; however, calling :meth:`winfo_parent` returns a + string of the widget name whereas :attr:`master` returns the object. + *parent*/*child* reflects the tree-like relationship while + *master*/*slave* reflects the container structure. + + .. attribute:: children + + The immediate descendants of this widget as a :class:`dict` with the + child widget names as the keys and the child instance objects as the + values. -.. function:: Tcl(screenName=None, baseName=None, className='Tk', useTk=0) +.. function:: Tcl(screenName=None, baseName=None, className='Tk', useTk=False) The :func:`Tcl` function is a factory function which creates an object much like that created by the :class:`Tk` class, except that it does not initialize the Tk @@ -756,8 +812,8 @@ callback color Colors can be given as the names of X colors in the rgb.txt file, or as strings - representing RGB values in 4 bit: ``"#RGB"``, 8 bit: ``"#RRGGBB"``, 12 bit" - ``"#RRRGGGBBB"``, or 16 bit ``"#RRRRGGGGBBBB"`` ranges, where R,G,B here + representing RGB values in 4 bit: ``"#RGB"``, 8 bit: ``"#RRGGBB"``, 12 bit: + ``"#RRRGGGBBB"``, or 16 bit: ``"#RRRRGGGGBBBB"`` ranges, where R,G,B here represent any legal hex digit. See page 160 of Ousterhout's book for details. cursor @@ -821,8 +877,9 @@ of the bind method is:: where: sequence - is a string that denotes the target kind of event. (See the bind man page and - page 201 of John Ousterhout's book for details). + is a string that denotes the target kind of event. (See the + :manpage:`bind(3tk)` man page, and page 201 of John Ousterhout's book, + :title-reference:`Tcl and the Tk Toolkit (2nd edition)`, for details). func is a Python function, taking one argument, to be invoked when the event occurs. @@ -931,7 +988,7 @@ wherever the image was used. .. seealso:: - The `Pillow `_ package adds support for + The `Pillow `_ package adds support for formats such as BMP, JPEG, TIFF, and WebP, among others. .. _tkinter-file-handlers: diff --git a/Doc/library/tkinter.tix.rst b/Doc/library/tkinter.tix.rst index 88b936c47a6..c86fcfa6a3f 100644 --- a/Doc/library/tkinter.tix.rst +++ b/Doc/library/tkinter.tix.rst @@ -33,17 +33,17 @@ special needs of your application and users. .. seealso:: - `Tix Homepage `_ + `Tix Homepage `_ The home page for :mod:`Tix`. This includes links to additional documentation and downloads. - `Tix Man Pages `_ + `Tix Man Pages `_ On-line version of the man pages and reference material. - `Tix Programming Guide `_ + `Tix Programming Guide `_ On-line version of the programmer's reference material. - `Tix Development Applications `_ + `Tix Development Applications `_ Tix applications for development of Tix and Tkinter programs. Tide applications work under Tk or Tkinter, and include :program:`TixInspect`, an inspector to remotely modify and debug Tix/Tk/Tkinter applications. @@ -80,7 +80,7 @@ the following:: Tix Widgets ----------- -`Tix `_ +`Tix `_ introduces over 40 widget classes to the :mod:`tkinter` repertoire. @@ -91,125 +91,125 @@ Basic Widgets .. class:: Balloon() A `Balloon - `_ that + `_ that pops up over a widget to provide help. When the user moves the cursor inside a widget to which a Balloon widget has been bound, a small pop-up window with a descriptive message will be shown on the screen. .. Python Demo of: -.. \ulink{Balloon}{http://tix.sourceforge.net/dist/current/demos/samples/Balloon.tcl} +.. \ulink{Balloon}{https://tix.sourceforge.net/dist/current/demos/samples/Balloon.tcl} .. class:: ButtonBox() The `ButtonBox - `_ + `_ widget creates a box of buttons, such as is commonly used for ``Ok Cancel``. .. Python Demo of: -.. \ulink{ButtonBox}{http://tix.sourceforge.net/dist/current/demos/samples/BtnBox.tcl} +.. \ulink{ButtonBox}{https://tix.sourceforge.net/dist/current/demos/samples/BtnBox.tcl} .. class:: ComboBox() The `ComboBox - `_ + `_ widget is similar to the combo box control in MS Windows. The user can select a choice by either typing in the entry subwidget or selecting from the listbox subwidget. .. Python Demo of: -.. \ulink{ComboBox}{http://tix.sourceforge.net/dist/current/demos/samples/ComboBox.tcl} +.. \ulink{ComboBox}{https://tix.sourceforge.net/dist/current/demos/samples/ComboBox.tcl} .. class:: Control() The `Control - `_ + `_ widget is also known as the :class:`SpinBox` widget. The user can adjust the value by pressing the two arrow buttons or by entering the value directly into the entry. The new value will be checked against the user-defined upper and lower limits. .. Python Demo of: -.. \ulink{Control}{http://tix.sourceforge.net/dist/current/demos/samples/Control.tcl} +.. \ulink{Control}{https://tix.sourceforge.net/dist/current/demos/samples/Control.tcl} .. class:: LabelEntry() The `LabelEntry - `_ + `_ widget packages an entry widget and a label into one mega widget. It can be used to simplify the creation of "entry-form" type of interface. .. Python Demo of: -.. \ulink{LabelEntry}{http://tix.sourceforge.net/dist/current/demos/samples/LabEntry.tcl} +.. \ulink{LabelEntry}{https://tix.sourceforge.net/dist/current/demos/samples/LabEntry.tcl} .. class:: LabelFrame() The `LabelFrame - `_ + `_ widget packages a frame widget and a label into one mega widget. To create widgets inside a LabelFrame widget, one creates the new widgets relative to the :attr:`frame` subwidget and manage them inside the :attr:`frame` subwidget. .. Python Demo of: -.. \ulink{LabelFrame}{http://tix.sourceforge.net/dist/current/demos/samples/LabFrame.tcl} +.. \ulink{LabelFrame}{https://tix.sourceforge.net/dist/current/demos/samples/LabFrame.tcl} .. class:: Meter() The `Meter - `_ widget + `_ widget can be used to show the progress of a background job which may take a long time to execute. .. Python Demo of: -.. \ulink{Meter}{http://tix.sourceforge.net/dist/current/demos/samples/Meter.tcl} +.. \ulink{Meter}{https://tix.sourceforge.net/dist/current/demos/samples/Meter.tcl} .. class:: OptionMenu() The `OptionMenu - `_ + `_ creates a menu button of options. .. Python Demo of: -.. \ulink{OptionMenu}{http://tix.sourceforge.net/dist/current/demos/samples/OptMenu.tcl} +.. \ulink{OptionMenu}{https://tix.sourceforge.net/dist/current/demos/samples/OptMenu.tcl} .. class:: PopupMenu() The `PopupMenu - `_ + `_ widget can be used as a replacement of the ``tk_popup`` command. The advantage of the :mod:`Tix` :class:`PopupMenu` widget is it requires less application code to manipulate. .. Python Demo of: -.. \ulink{PopupMenu}{http://tix.sourceforge.net/dist/current/demos/samples/PopMenu.tcl} +.. \ulink{PopupMenu}{https://tix.sourceforge.net/dist/current/demos/samples/PopMenu.tcl} .. class:: Select() The `Select - `_ widget + `_ widget is a container of button subwidgets. It can be used to provide radio-box or check-box style of selection options for the user. .. Python Demo of: -.. \ulink{Select}{http://tix.sourceforge.net/dist/current/demos/samples/Select.tcl} +.. \ulink{Select}{https://tix.sourceforge.net/dist/current/demos/samples/Select.tcl} .. class:: StdButtonBox() The `StdButtonBox - `_ + `_ widget is a group of standard buttons for Motif-like dialog boxes. .. Python Demo of: -.. \ulink{StdButtonBox}{http://tix.sourceforge.net/dist/current/demos/samples/StdBBox.tcl} +.. \ulink{StdButtonBox}{https://tix.sourceforge.net/dist/current/demos/samples/StdBBox.tcl} File Selectors @@ -219,37 +219,37 @@ File Selectors .. class:: DirList() The `DirList - `_ + `_ widget displays a list view of a directory, its previous directories and its sub-directories. The user can choose one of the directories displayed in the list or change to another directory. .. Python Demo of: -.. \ulink{DirList}{http://tix.sourceforge.net/dist/current/demos/samples/DirList.tcl} +.. \ulink{DirList}{https://tix.sourceforge.net/dist/current/demos/samples/DirList.tcl} .. class:: DirTree() The `DirTree - `_ + `_ widget displays a tree view of a directory, its previous directories and its sub-directories. The user can choose one of the directories displayed in the list or change to another directory. .. Python Demo of: -.. \ulink{DirTree}{http://tix.sourceforge.net/dist/current/demos/samples/DirTree.tcl} +.. \ulink{DirTree}{https://tix.sourceforge.net/dist/current/demos/samples/DirTree.tcl} .. class:: DirSelectDialog() The `DirSelectDialog - `_ + `_ widget presents the directories in the file system in a dialog window. The user can use this dialog window to navigate through the file system to select the desired directory. .. Python Demo of: -.. \ulink{DirSelectDialog}{http://tix.sourceforge.net/dist/current/demos/samples/DirDlg.tcl} +.. \ulink{DirSelectDialog}{https://tix.sourceforge.net/dist/current/demos/samples/DirDlg.tcl} .. class:: DirSelectBox() @@ -263,39 +263,39 @@ File Selectors .. class:: ExFileSelectBox() The `ExFileSelectBox - `_ + `_ widget is usually embedded in a tixExFileSelectDialog widget. It provides a convenient method for the user to select files. The style of the :class:`ExFileSelectBox` widget is very similar to the standard file dialog on MS Windows 3.1. .. Python Demo of: -.. \ulink{ExFileSelectDialog}{http://tix.sourceforge.net/dist/current/demos/samples/EFileDlg.tcl} +.. \ulink{ExFileSelectDialog}{https://tix.sourceforge.net/dist/current/demos/samples/EFileDlg.tcl} .. class:: FileSelectBox() The `FileSelectBox - `_ + `_ is similar to the standard Motif(TM) file-selection box. It is generally used for the user to choose a file. FileSelectBox stores the files mostly recently selected into a :class:`ComboBox` widget so that they can be quickly selected again. .. Python Demo of: -.. \ulink{FileSelectDialog}{http://tix.sourceforge.net/dist/current/demos/samples/FileDlg.tcl} +.. \ulink{FileSelectDialog}{https://tix.sourceforge.net/dist/current/demos/samples/FileDlg.tcl} .. class:: FileEntry() The `FileEntry - `_ + `_ widget can be used to input a filename. The user can type in the filename manually. Alternatively, the user can press the button widget that sits next to the entry, which will bring up a file selection dialog. .. Python Demo of: -.. \ulink{FileEntry}{http://tix.sourceforge.net/dist/current/demos/samples/FileEnt.tcl} +.. \ulink{FileEntry}{https://tix.sourceforge.net/dist/current/demos/samples/FileEnt.tcl} Hierarchical ListBox @@ -305,42 +305,42 @@ Hierarchical ListBox .. class:: HList() The `HList - `_ widget + `_ widget can be used to display any data that have a hierarchical structure, for example, file system directory trees. The list entries are indented and connected by branch lines according to their places in the hierarchy. .. Python Demo of: -.. \ulink{HList}{http://tix.sourceforge.net/dist/current/demos/samples/HList1.tcl} +.. \ulink{HList}{https://tix.sourceforge.net/dist/current/demos/samples/HList1.tcl} .. class:: CheckList() The `CheckList - `_ + `_ widget displays a list of items to be selected by the user. CheckList acts similarly to the Tk checkbutton or radiobutton widgets, except it is capable of handling many more items than checkbuttons or radiobuttons. .. Python Demo of: -.. \ulink{ CheckList}{http://tix.sourceforge.net/dist/current/demos/samples/ChkList.tcl} +.. \ulink{ CheckList}{https://tix.sourceforge.net/dist/current/demos/samples/ChkList.tcl} .. Python Demo of: -.. \ulink{ScrolledHList (1)}{http://tix.sourceforge.net/dist/current/demos/samples/SHList.tcl} +.. \ulink{ScrolledHList (1)}{https://tix.sourceforge.net/dist/current/demos/samples/SHList.tcl} .. Python Demo of: -.. \ulink{ScrolledHList (2)}{http://tix.sourceforge.net/dist/current/demos/samples/SHList2.tcl} +.. \ulink{ScrolledHList (2)}{https://tix.sourceforge.net/dist/current/demos/samples/SHList2.tcl} .. class:: Tree() The `Tree - `_ widget + `_ widget can be used to display hierarchical data in a tree form. The user can adjust the view of the tree by opening or closing parts of the tree. .. Python Demo of: -.. \ulink{Tree}{http://tix.sourceforge.net/dist/current/demos/samples/Tree.tcl} +.. \ulink{Tree}{https://tix.sourceforge.net/dist/current/demos/samples/Tree.tcl} .. Python Demo of: -.. \ulink{Tree (Dynamic)}{http://tix.sourceforge.net/dist/current/demos/samples/DynTree.tcl} +.. \ulink{Tree (Dynamic)}{https://tix.sourceforge.net/dist/current/demos/samples/DynTree.tcl} Tabular ListBox @@ -350,7 +350,7 @@ Tabular ListBox .. class:: TList() The `TList - `_ widget + `_ widget can be used to display data in a tabular format. The list entries of a :class:`TList` widget are similar to the entries in the Tk listbox widget. The main differences are (1) the :class:`TList` widget can display the list entries @@ -358,17 +358,17 @@ Tabular ListBox multiple colors and fonts for the list entries. .. Python Demo of: -.. \ulink{ScrolledTList (1)}{http://tix.sourceforge.net/dist/current/demos/samples/STList1.tcl} +.. \ulink{ScrolledTList (1)}{https://tix.sourceforge.net/dist/current/demos/samples/STList1.tcl} .. Python Demo of: -.. \ulink{ScrolledTList (2)}{http://tix.sourceforge.net/dist/current/demos/samples/STList2.tcl} +.. \ulink{ScrolledTList (2)}{https://tix.sourceforge.net/dist/current/demos/samples/STList2.tcl} .. Grid has yet to be added to Python .. \subsubsection{Grid Widget} .. Python Demo of: -.. \ulink{Simple Grid}{http://tix.sourceforge.net/dist/current/demos/samples/SGrid0.tcl} +.. \ulink{Simple Grid}{https://tix.sourceforge.net/dist/current/demos/samples/SGrid0.tcl} .. Python Demo of: -.. \ulink{ScrolledGrid}{http://tix.sourceforge.net/dist/current/demos/samples/SGrid1.tcl} +.. \ulink{ScrolledGrid}{https://tix.sourceforge.net/dist/current/demos/samples/SGrid1.tcl} .. Python Demo of: -.. \ulink{Editable Grid}{http://tix.sourceforge.net/dist/current/demos/samples/EditGrid.tcl} +.. \ulink{Editable Grid}{https://tix.sourceforge.net/dist/current/demos/samples/EditGrid.tcl} Manager Widgets @@ -378,19 +378,19 @@ Manager Widgets .. class:: PanedWindow() The `PanedWindow - `_ + `_ widget allows the user to interactively manipulate the sizes of several panes. The panes can be arranged either vertically or horizontally. The user changes the sizes of the panes by dragging the resize handle between two panes. .. Python Demo of: -.. \ulink{PanedWindow}{http://tix.sourceforge.net/dist/current/demos/samples/PanedWin.tcl} +.. \ulink{PanedWindow}{https://tix.sourceforge.net/dist/current/demos/samples/PanedWin.tcl} .. class:: ListNoteBook() The `ListNoteBook - `_ + `_ widget is very similar to the :class:`TixNoteBook` widget: it can be used to display many windows in a limited space using a notebook metaphor. The notebook is divided into a stack of pages (windows). At one time only one of these pages @@ -398,30 +398,30 @@ Manager Widgets the desired page in the :attr:`hlist` subwidget. .. Python Demo of: -.. \ulink{ListNoteBook}{http://tix.sourceforge.net/dist/current/demos/samples/ListNBK.tcl} +.. \ulink{ListNoteBook}{https://tix.sourceforge.net/dist/current/demos/samples/ListNBK.tcl} .. class:: NoteBook() The `NoteBook - `_ + `_ widget can be used to display many windows in a limited space using a notebook metaphor. The notebook is divided into a stack of pages. At one time only one of these pages can be shown. The user can navigate through these pages by choosing the visual "tabs" at the top of the NoteBook widget. .. Python Demo of: -.. \ulink{NoteBook}{http://tix.sourceforge.net/dist/current/demos/samples/NoteBook.tcl} +.. \ulink{NoteBook}{https://tix.sourceforge.net/dist/current/demos/samples/NoteBook.tcl} .. \subsubsection{Scrolled Widgets} .. Python Demo of: -.. \ulink{ScrolledListBox}{http://tix.sourceforge.net/dist/current/demos/samples/SListBox.tcl} +.. \ulink{ScrolledListBox}{https://tix.sourceforge.net/dist/current/demos/samples/SListBox.tcl} .. Python Demo of: -.. \ulink{ScrolledText}{http://tix.sourceforge.net/dist/current/demos/samples/SText.tcl} +.. \ulink{ScrolledText}{https://tix.sourceforge.net/dist/current/demos/samples/SText.tcl} .. Python Demo of: -.. \ulink{ScrolledWindow}{http://tix.sourceforge.net/dist/current/demos/samples/SWindow.tcl} +.. \ulink{ScrolledWindow}{https://tix.sourceforge.net/dist/current/demos/samples/SWindow.tcl} .. Python Demo of: -.. \ulink{Canvas Object View}{http://tix.sourceforge.net/dist/current/demos/samples/CObjView.tcl} +.. \ulink{Canvas Object View}{https://tix.sourceforge.net/dist/current/demos/samples/CObjView.tcl} Image Types @@ -429,17 +429,17 @@ Image Types The :mod:`tkinter.tix` module adds: -* `pixmap `_ +* `pixmap `_ capabilities to all :mod:`tkinter.tix` and :mod:`tkinter` widgets to create color images from XPM files. .. Python Demo of: - .. \ulink{XPM Image In Button}{http://tix.sourceforge.net/dist/current/demos/samples/Xpm.tcl} + .. \ulink{XPM Image In Button}{https://tix.sourceforge.net/dist/current/demos/samples/Xpm.tcl} .. Python Demo of: - .. \ulink{XPM Image In Menu}{http://tix.sourceforge.net/dist/current/demos/samples/Xpm1.tcl} + .. \ulink{XPM Image In Menu}{https://tix.sourceforge.net/dist/current/demos/samples/Xpm1.tcl} * `Compound - `_ image + `_ image types can be used to create images that consists of multiple horizontal lines; each line is composed of a series of items (texts, bitmaps, images or spaces) arranged from left to right. For example, a compound image can be used to @@ -447,13 +447,13 @@ The :mod:`tkinter.tix` module adds: widget. .. Python Demo of: - .. \ulink{Compound Image In Buttons}{http://tix.sourceforge.net/dist/current/demos/samples/CmpImg.tcl} + .. \ulink{Compound Image In Buttons}{https://tix.sourceforge.net/dist/current/demos/samples/CmpImg.tcl} .. Python Demo of: - .. \ulink{Compound Image In NoteBook}{http://tix.sourceforge.net/dist/current/demos/samples/CmpImg2.tcl} + .. \ulink{Compound Image In NoteBook}{https://tix.sourceforge.net/dist/current/demos/samples/CmpImg2.tcl} .. Python Demo of: - .. \ulink{Compound Image Notebook Color Tabs}{http://tix.sourceforge.net/dist/current/demos/samples/CmpImg4.tcl} + .. \ulink{Compound Image Notebook Color Tabs}{https://tix.sourceforge.net/dist/current/demos/samples/CmpImg4.tcl} .. Python Demo of: - .. \ulink{Compound Image Icons}{http://tix.sourceforge.net/dist/current/demos/samples/CmpImg3.tcl} + .. \ulink{Compound Image Icons}{https://tix.sourceforge.net/dist/current/demos/samples/CmpImg3.tcl} Miscellaneous Widgets @@ -463,7 +463,7 @@ Miscellaneous Widgets .. class:: InputOnly() The `InputOnly - `_ + `_ widgets are to accept inputs from the user, which can be done with the ``bind`` command (Unix only). @@ -477,7 +477,7 @@ In addition, :mod:`tkinter.tix` augments :mod:`tkinter` by providing: .. class:: Form() The `Form - `_ geometry + `_ geometry manager based on attachment rules for all Tk widgets. @@ -488,7 +488,7 @@ Tix Commands .. class:: tixCommand() The `tix commands - `_ provide + `_ provide access to miscellaneous elements of :mod:`Tix`'s internal state and the :mod:`Tix` application context. Most of the information manipulated by these methods pertains to the application as a whole, or to a screen or display, diff --git a/Doc/library/tkinter.ttk.rst b/Doc/library/tkinter.ttk.rst index 2db4c0f9143..4ff2b2159c3 100644 --- a/Doc/library/tkinter.ttk.rst +++ b/Doc/library/tkinter.ttk.rst @@ -13,9 +13,7 @@ -------------- The :mod:`tkinter.ttk` module provides access to the Tk themed widget set, -introduced in Tk 8.5. If Python has not been compiled against Tk 8.5, this -module can still be accessed if *Tile* has been installed. The former -method using Tk 8.5 provides additional benefits including anti-aliased font +introduced in Tk 8.5. It provides additional benefits including anti-aliased font rendering under X11 and window transparency (requiring a composition window manager on X11). @@ -58,7 +56,7 @@ for improved styling effects. .. seealso:: - `Converting existing applications to use Tile widgets `_ + `Converting existing applications to use Tile widgets `_ A monograph (using Tcl terminology) about differences typically encountered when moving applications to use the new widgets. @@ -288,7 +286,7 @@ methods :meth:`tkinter.Widget.cget` and :meth:`tkinter.Widget.configure`. Modify or inquire widget state. If *statespec* is specified, sets the widget state according to it and return a new *statespec* indicating which flags were changed. If *statespec* is not specified, returns - the currently-enabled state flags. + the currently enabled state flags. *statespec* will usually be a list or a tuple. @@ -467,7 +465,7 @@ Notebook Ttk Notebook widget manages a collection of windows and displays a single one at a time. Each child window is associated with a tab, which the user -may select to change the currently-displayed window. +may select to change the currently displayed window. Options @@ -545,7 +543,7 @@ of the following forms: * An integer between zero and the number of tabs * The name of a child window * A positional specification of the form "@x,y", which identifies the tab -* The literal string "current", which identifies the currently-selected tab +* The literal string "current", which identifies the currently selected tab * The literal string "end", which returns the number of tabs (only valid for :meth:`Notebook.index`) @@ -615,7 +613,7 @@ ttk.Notebook Selects the specified *tab_id*. The associated child window will be displayed, and the - previously-selected window (if different) is unmapped. If *tab_id* is + previously selected window (if different) is unmapped. If *tab_id* is omitted, returns the widget name of the currently selected pane. @@ -1274,7 +1272,7 @@ option. If you don't know the class name of a widget, use the method .. seealso:: - `Tcl'2004 conference presentation `_ + `Tcl'2004 conference presentation `_ This document explains how the theme engine works diff --git a/Doc/library/token-list.inc b/Doc/library/token-list.inc index 1a99f0518d1..2739d5bfc1d 100644 --- a/Doc/library/token-list.inc +++ b/Doc/library/token-list.inc @@ -1,4 +1,4 @@ -.. Auto-generated by Tools/scripts/generate_token.py +.. Auto-generated by Tools/build/generate_token.py .. data:: ENDMARKER .. data:: NAME diff --git a/Doc/library/tomllib.rst b/Doc/library/tomllib.rst new file mode 100644 index 00000000000..918576eb37e --- /dev/null +++ b/Doc/library/tomllib.rst @@ -0,0 +1,117 @@ +:mod:`tomllib` --- Parse TOML files +=================================== + +.. module:: tomllib + :synopsis: Parse TOML files. + +.. versionadded:: 3.11 + +.. moduleauthor:: Taneli Hukkinen +.. sectionauthor:: Taneli Hukkinen + +**Source code:** :source:`Lib/tomllib` + +-------------- + +This module provides an interface for parsing TOML (Tom's Obvious Minimal +Language, `https://toml.io `_). This module does not +support writing TOML. + +.. seealso:: + + The `Tomli-W package `__ + is a TOML writer that can be used in conjunction with this module, + providing a write API familiar to users of the standard library + :mod:`marshal` and :mod:`pickle` modules. + +.. seealso:: + + The `TOML Kit package `__ + is a style-preserving TOML library with both read and write capability. + It is a recommended replacement for this module for editing already + existing TOML files. + + +This module defines the following functions: + +.. function:: load(fp, /, *, parse_float=float) + + Read a TOML file. The first argument should be a readable and binary file object. + Return a :class:`dict`. Convert TOML types to Python using this + :ref:`conversion table `. + + *parse_float* will be called with the string of every TOML + float to be decoded. By default, this is equivalent to ``float(num_str)``. + This can be used to use another datatype or parser for TOML floats + (e.g. :class:`decimal.Decimal`). The callable must not return a + :class:`dict` or a :class:`list`, else a :exc:`ValueError` is raised. + + A :exc:`TOMLDecodeError` will be raised on an invalid TOML document. + + +.. function:: loads(s, /, *, parse_float=float) + + Load TOML from a :class:`str` object. Return a :class:`dict`. Convert TOML + types to Python using this :ref:`conversion table `. The + *parse_float* argument has the same meaning as in :func:`load`. + + A :exc:`TOMLDecodeError` will be raised on an invalid TOML document. + + +The following exceptions are available: + +.. exception:: TOMLDecodeError + + Subclass of :exc:`ValueError`. + + +Examples +-------- + +Parsing a TOML file:: + + import tomllib + + with open("pyproject.toml", "rb") as f: + data = tomllib.load(f) + +Parsing a TOML string:: + + import tomllib + + toml_str = """ + python-version = "3.11.0" + python-implementation = "CPython" + """ + + data = tomllib.loads(toml_str) + + +Conversion Table +---------------- + +.. _toml-to-py-table: + ++------------------+--------------------------------------------------------------------------------------+ +| TOML | Python | ++==================+======================================================================================+ +| table | dict | ++------------------+--------------------------------------------------------------------------------------+ +| string | str | ++------------------+--------------------------------------------------------------------------------------+ +| integer | int | ++------------------+--------------------------------------------------------------------------------------+ +| float | float (configurable with *parse_float*) | ++------------------+--------------------------------------------------------------------------------------+ +| boolean | bool | ++------------------+--------------------------------------------------------------------------------------+ +| offset date-time | datetime.datetime (``tzinfo`` attribute set to an instance of ``datetime.timezone``) | ++------------------+--------------------------------------------------------------------------------------+ +| local date-time | datetime.datetime (``tzinfo`` attribute set to ``None``) | ++------------------+--------------------------------------------------------------------------------------+ +| local date | datetime.date | ++------------------+--------------------------------------------------------------------------------------+ +| local time | datetime.time | ++------------------+--------------------------------------------------------------------------------------+ +| array | list | ++------------------+--------------------------------------------------------------------------------------+ diff --git a/Doc/library/traceback.rst b/Doc/library/traceback.rst index df4a38c9555..f8c1eabadac 100644 --- a/Doc/library/traceback.rst +++ b/Doc/library/traceback.rst @@ -236,6 +236,14 @@ capture data for later printing in a lightweight fashion. The ``__suppress_context__`` value from the original exception. + .. attribute:: __notes__ + + The ``__notes__`` value from the original exception, or ``None`` + if the exception does not have any notes. If it is not ``None`` + is it formatted in the traceback after the exception string. + + .. versionadded:: 3.11 + .. attribute:: stack A :class:`StackSummary` representing the traceback. @@ -333,6 +341,10 @@ capture data for later printing in a lightweight fashion. local variables in each :class:`FrameSummary` are captured as object representations. + .. versionchanged:: 3.12 + Exceptions raised from :func:`repr` on a local variable (when + *capture_locals* is ``True``) are no longer propagated to the caller. + .. classmethod:: from_list(a_list) Construct a :class:`StackSummary` object from a supplied list of @@ -417,9 +429,9 @@ exception and traceback: import sys, traceback def lumberjack(): - bright_side_of_death() + bright_side_of_life() - def bright_side_of_death(): + def bright_side_of_life(): return tuple()[0] try: @@ -429,9 +441,7 @@ exception and traceback: print("*** print_tb:") traceback.print_tb(exc_traceback, limit=1, file=sys.stdout) print("*** print_exception:") - # exc_type below is ignored on 3.5 and later - traceback.print_exception(exc_type, exc_value, exc_traceback, - limit=2, file=sys.stdout) + traceback.print_exception(exc_value, limit=2, file=sys.stdout) print("*** print_exc:") traceback.print_exc(limit=2, file=sys.stdout) print("*** format_exc, first and last line:") @@ -439,9 +449,7 @@ exception and traceback: print(formatted_lines[0]) print(formatted_lines[-1]) print("*** format_exception:") - # exc_type below is ignored on 3.5 and later - print(repr(traceback.format_exception(exc_type, exc_value, - exc_traceback))) + print(repr(traceback.format_exception(exc_value))) print("*** extract_tb:") print(repr(traceback.extract_tb(exc_traceback))) print("*** format_tb:") @@ -456,42 +464,37 @@ The output for the example would look similar to this: *** print_tb: File "", line 10, in lumberjack() - ^^^^^^^^^^^^ *** print_exception: Traceback (most recent call last): File "", line 10, in lumberjack() - ^^^^^^^^^^^^ File "", line 4, in lumberjack - bright_side_of_death() - ^^^^^^^^^^^^^^^^^^^^^^ + bright_side_of_life() IndexError: tuple index out of range *** print_exc: Traceback (most recent call last): File "", line 10, in lumberjack() - ^^^^^^^^^^^^ File "", line 4, in lumberjack - bright_side_of_death() - ^^^^^^^^^^^^^^^^^^^^^^ + bright_side_of_life() IndexError: tuple index out of range *** format_exc, first and last line: Traceback (most recent call last): IndexError: tuple index out of range *** format_exception: ['Traceback (most recent call last):\n', - ' File "", line 10, in \n lumberjack()\n ^^^^^^^^^^^^\n', - ' File "", line 4, in lumberjack\n bright_side_of_death()\n ^^^^^^^^^^^^^^^^^^^^^^\n', - ' File "", line 7, in bright_side_of_death\n return tuple()[0]\n ~~~~~~~^^^\n', + ' File "", line 10, in \n lumberjack()\n', + ' File "", line 4, in lumberjack\n bright_side_of_life()\n', + ' File "", line 7, in bright_side_of_life\n return tuple()[0]\n ~~~~~~~^^^\n', 'IndexError: tuple index out of range\n'] *** extract_tb: [, line 10 in >, , line 4 in lumberjack>, - , line 7 in bright_side_of_death>] + , line 7 in bright_side_of_life>] *** format_tb: - [' File "", line 10, in \n lumberjack()\n ^^^^^^^^^^^^\n', - ' File "", line 4, in lumberjack\n bright_side_of_death()\n ^^^^^^^^^^^^^^^^^^^^^^\n', - ' File "", line 7, in bright_side_of_death\n return tuple()[0]\n ~~~~~~~^^^\n'] + [' File "", line 10, in \n lumberjack()\n', + ' File "", line 4, in lumberjack\n bright_side_of_life()\n', + ' File "", line 7, in bright_side_of_life\n return tuple()[0]\n ~~~~~~~^^^\n'] *** tb_lineno: 10 diff --git a/Doc/library/turtle.rst b/Doc/library/turtle.rst index 17bf8829a9f..5add61c759e 100644 --- a/Doc/library/turtle.rst +++ b/Doc/library/turtle.rst @@ -1279,7 +1279,7 @@ Appearance (direction of movement). .. doctest:: - :skipif: _tkinter is None + :skipif: _tkinter is None or 'always; deprecated method' >>> turtle.reset() >>> turtle.shape("circle") diff --git a/Doc/library/types.rst b/Doc/library/types.rst index 2314b02c744..cce0ad960ed 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -239,7 +239,7 @@ Standard names are defined for the following types: The :term:`loader` which loaded the module. Defaults to ``None``. This attribute is to match :attr:`importlib.machinery.ModuleSpec.loader` - as stored in the attr:`__spec__` object. + as stored in the :attr:`__spec__` object. .. note:: A future version of Python may stop setting this attribute by default. @@ -264,7 +264,7 @@ Standard names are defined for the following types: :attr:`__name__` if the module is a package itself). Defaults to ``None``. This attribute is to match :attr:`importlib.machinery.ModuleSpec.parent` - as stored in the attr:`__spec__` object. + as stored in the :attr:`__spec__` object. .. note:: A future version of Python may stop setting this attribute by default. @@ -312,7 +312,7 @@ Standard names are defined for the following types: This type can now be subclassed. -.. data:: UnionType +.. class:: UnionType The type of :ref:`union type expressions`. @@ -417,6 +417,12 @@ Standard names are defined for the following types: .. versionadded:: 3.9 + .. describe:: hash(proxy) + + Return a hash of the underlying mapping. + + .. versionadded:: 3.12 + Additional Utility Classes and Functions ---------------------------------------- diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 735d477db43..356f919a189 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -32,6 +32,19 @@ In the function ``greeting``, the argument ``name`` is expected to be of type :class:`str` and the return type :class:`str`. Subtypes are accepted as arguments. +New features are frequently added to the ``typing`` module. +The `typing_extensions `_ package +provides backports of these new features to older versions of Python. + +For a summary of deprecated features and a deprecation timeline, please see +`Deprecation Timeline of Major Features`_. + +.. seealso:: + + The documentation at https://typing.readthedocs.io/ serves as useful reference + for type system features, useful typing related tools and typing best practices. + + .. _relevant-peps: Relevant PEPs @@ -66,8 +79,18 @@ annotations. These include: *Introducing* :class:`ParamSpec` and :data:`Concatenate` * :pep:`613`: Explicit Type Aliases *Introducing* :data:`TypeAlias` +* :pep:`646`: Variadic Generics + *Introducing* :data:`TypeVarTuple` * :pep:`647`: User-Defined Type Guards *Introducing* :data:`TypeGuard` +* :pep:`655`: Marking individual TypedDict items as required or potentially missing + *Introducing* :data:`Required` and :data:`NotRequired` +* :pep:`673`: Self type + *Introducing* :data:`Self` +* :pep:`675`: Arbitrary Literal String Type + *Introducing* :data:`LiteralString` +* :pep:`681`: Data Class Transforms + *Introducing* the :func:`@dataclass_transform` decorator .. _type-aliases: @@ -82,7 +105,7 @@ A type alias is defined by assigning the type to the alias. In this example, def scale(scalar: float, vector: Vector) -> Vector: return [scalar * num for num in vector] - # typechecks; a list of floats qualifies as a Vector. + # passes type checking; a list of floats qualifies as a Vector. new_vector = scale(2.0, [1.0, -4.2, 5.4]) Type aliases are useful for simplifying complex type signatures. For example:: @@ -111,7 +134,7 @@ Note that ``None`` as a type hint is a special case and is replaced by NewType ======= -Use the :class:`NewType` helper class to create distinct types:: +Use the :class:`NewType` helper to create distinct types:: from typing import NewType @@ -124,10 +147,10 @@ of the original type. This is useful in helping catch logical errors:: def get_user_name(user_id: UserId) -> str: ... - # typechecks + # passes type checking user_a = get_user_name(UserId(42351)) - # does not typecheck; an int is not a UserId + # fails type checking; an int is not a UserId user_b = get_user_name(-1) You may still perform all ``int`` operations on a variable of type ``UserId``, @@ -140,7 +163,7 @@ accidentally creating a ``UserId`` in an invalid way:: Note that these checks are enforced only by the static type checker. At runtime, the statement ``Derived = NewType('Derived', Base)`` will make ``Derived`` a -class that immediately returns whatever parameter you pass it. That means +callable that immediately returns whatever parameter you pass it. That means the expression ``Derived(some_value)`` does not create a new class or introduce much overhead beyond that of a regular function call. @@ -153,7 +176,7 @@ It is invalid to create a subtype of ``Derived``:: UserId = NewType('UserId', int) - # Fails at runtime and does not typecheck + # Fails at runtime and does not pass type checking class AdminUserId(UserId): pass However, it is possible to create a :class:`NewType` based on a 'derived' ``NewType``:: @@ -207,6 +230,10 @@ For example:: on_error: Callable[[int, Exception], None]) -> None: # Body + async def on_update(value: str) -> None: + # Body + callback: Callable[[str], Awaitable[None]] = on_update + It is possible to declare the return type of a callable without specifying the call signature by substituting a literal ellipsis for the list of arguments in the type hint: ``Callable[..., ReturnType]``. @@ -221,10 +248,10 @@ respectively. .. versionchanged:: 3.10 ``Callable`` now supports :class:`ParamSpec` and :data:`Concatenate`. - See :pep:`612` for more information. + See :pep:`612` for more details. .. seealso:: - The documentation for :class:`ParamSpec` and :class:`Concatenate` provide + The documentation for :class:`ParamSpec` and :class:`Concatenate` provides examples of usage in ``Callable``. .. _generics: @@ -243,7 +270,7 @@ subscription to denote expected types for container elements. def notify_by_email(employees: Sequence[Employee], overrides: Mapping[str, str]) -> None: ... -Generics can be parameterized by using a new factory available in typing +Generics can be parameterized by using a factory available in typing called :class:`TypeVar`. :: @@ -292,7 +319,7 @@ single type parameter ``T`` . This also makes ``T`` valid as a type within the class body. The :class:`Generic` base class defines :meth:`~object.__class_getitem__` so -that ``LoggedVar[t]`` is valid as a type:: +that ``LoggedVar[T]`` is valid as a type:: from collections.abc import Iterable @@ -300,16 +327,16 @@ that ``LoggedVar[t]`` is valid as a type:: for var in vars: var.set(0) -A generic type can have any number of type variables, and type variables may -be constrained:: +A generic type can have any number of type variables. All varieties of +:class:`TypeVar` are permissible as parameters for a generic type:: - from typing import TypeVar, Generic - ... + from typing import TypeVar, Generic, Sequence - T = TypeVar('T') + T = TypeVar('T', contravariant=True) + B = TypeVar('B', bound=Sequence[bytes], covariant=True) S = TypeVar('S', int, str) - class StrangePair(Generic[T, S]): + class WeirdTrio(Generic[T, B, S]): ... Each type variable argument to :class:`Generic` must be distinct. @@ -393,7 +420,7 @@ to this is that a list of types can be used to substitute a :class:`ParamSpec`:: Furthermore, a generic with only one parameter specification variable will accept parameter lists in the forms ``X[[Type1, Type2, ...]]`` and also ``X[Type1, Type2, ...]`` for aesthetic reasons. Internally, the latter is converted -to the former and are thus equivalent:: +to the former, so the following are equivalent:: >>> class X(Generic[P]): ... ... @@ -428,20 +455,20 @@ value of type :data:`Any` and assign it to any variable:: from typing import Any - a = None # type: Any - a = [] # OK - a = 2 # OK + a: Any = None + a = [] # OK + a = 2 # OK - s = '' # type: str - s = a # OK + s: str = '' + s = a # OK def foo(item: Any) -> int: - # Typechecks; 'item' could be any type, + # Passes type checking; 'item' could be any type, # and that type might have a 'bar' method item.bar() ... -Notice that no typechecking is performed when assigning a value of type +Notice that no type checking is performed when assigning a value of type :data:`Any` to a more precise type. For example, the static type checker did not report an error when assigning ``a`` to ``s`` even though ``s`` was declared to be of type :class:`str` and receives an :class:`int` value at @@ -473,20 +500,20 @@ reject almost all operations on it, and assigning it to a variable (or using it as a return value) of a more specialized type is a type error. For example:: def hash_a(item: object) -> int: - # Fails; an object does not have a 'magic' method. + # Fails type checking; an object does not have a 'magic' method. item.magic() ... def hash_b(item: Any) -> int: - # Typechecks + # Passes type checking item.magic() ... - # Typechecks, since ints and strs are subclasses of object + # Passes type checking, since ints and strs are subclasses of object hash_a(42) hash_a("foo") - # Typechecks, since Any is compatible with all types + # Passes type checking, since Any is compatible with all types hash_b(42) hash_b("foo") @@ -497,7 +524,7 @@ manner. Use :data:`Any` to indicate that a value is dynamically typed. Nominal vs structural subtyping =============================== -Initially :pep:`484` defined Python static type system as using +Initially :pep:`484` defined the Python static type system as using *nominal subtyping*. This means that a class ``A`` is allowed where a class ``B`` is expected if and only if ``A`` is a subclass of ``B``. @@ -572,6 +599,70 @@ These can be used as types in annotations and do not support ``[]``. * Every type is compatible with :data:`Any`. * :data:`Any` is compatible with every type. + .. versionchanged:: 3.11 + :data:`Any` can now be used as a base class. This can be useful for + avoiding type checker errors with classes that can duck type anywhere or + are highly dynamic. + +.. data:: LiteralString + + Special type that includes only literal strings. A string + literal is compatible with ``LiteralString``, as is another + ``LiteralString``, but an object typed as just ``str`` is not. + A string created by composing ``LiteralString``-typed objects + is also acceptable as a ``LiteralString``. + + Example:: + + def run_query(sql: LiteralString) -> ... + ... + + def caller(arbitrary_string: str, literal_string: LiteralString) -> None: + run_query("SELECT * FROM students") # ok + run_query(literal_string) # ok + run_query("SELECT * FROM " + literal_string) # ok + run_query(arbitrary_string) # type checker error + run_query( # type checker error + f"SELECT * FROM students WHERE name = {arbitrary_string}" + ) + + This is useful for sensitive APIs where arbitrary user-generated + strings could generate problems. For example, the two cases above + that generate type checker errors could be vulnerable to an SQL + injection attack. + + See :pep:`675` for more details. + + .. versionadded:: 3.11 + +.. data:: Never + + The `bottom type `_, + a type that has no members. + + This can be used to define a function that should never be + called, or a function that never returns:: + + from typing import Never + + def never_call_me(arg: Never) -> None: + pass + + def int_or_str(arg: int | str) -> None: + never_call_me(arg) # type checker error + match arg: + case int(): + print("It's an int") + case str(): + print("It's a str") + case _: + never_call_me(arg) # ok, arg is of type Never + + .. versionadded:: 3.11 + + On older Python versions, :data:`NoReturn` may be used to express the + same concept. ``Never`` was added to make the intended meaning more explicit. + .. data:: NoReturn Special type indicating that a function never returns. @@ -582,9 +673,60 @@ These can be used as types in annotations and do not support ``[]``. def stop() -> NoReturn: raise RuntimeError('no way') + ``NoReturn`` can also be used as a + `bottom type `_, a type that + has no values. Starting in Python 3.11, the :data:`Never` type should + be used for this concept instead. Type checkers should treat the two + equivalently. + .. versionadded:: 3.5.4 .. versionadded:: 3.6.2 +.. data:: Self + + Special type to represent the current enclosed class. + For example:: + + from typing import Self + + class Foo: + def return_self(self) -> Self: + ... + return self + + + This annotation is semantically equivalent to the following, + albeit in a more succinct fashion:: + + from typing import TypeVar + + Self = TypeVar("Self", bound="Foo") + + class Foo: + def return_self(self: Self) -> Self: + ... + return self + + In general if something currently follows the pattern of:: + + class Foo: + def return_self(self) -> "Foo": + ... + return self + + You should use :data:`Self` as calls to ``SubclassOfFoo.return_self`` would have + ``Foo`` as the return type and not ``SubclassOfFoo``. + + Other common use cases include: + + - :class:`classmethod`\s that are used as alternative constructors and return instances + of the ``cls`` parameter. + - Annotating an :meth:`~object.__enter__` method which returns self. + + See :pep:`673` for more details. + + .. versionadded:: 3.11 + .. data:: TypeAlias Special annotation for explicitly declaring a :ref:`type alias `. @@ -618,14 +760,14 @@ These can be used as types in annotations using ``[]``, each having a unique syn is equivalent to ``Tuple[Any, ...]``, and in turn to :class:`tuple`. .. deprecated:: 3.9 - :class:`builtins.tuple ` now supports ``[]``. See :pep:`585` and - :ref:`types-genericalias`. + :class:`builtins.tuple ` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. data:: Union Union type; ``Union[X, Y]`` is equivalent to ``X | Y`` and means either X or Y. - To define a union, use e.g. ``Union[int, str]`` or the shorthand ``int | str``. Details: + To define a union, use e.g. ``Union[int, str]`` or the shorthand ``int | str``. Using that shorthand is recommended. Details: * The arguments must be types and there must be at least one. @@ -707,12 +849,12 @@ These can be used as types in annotations using ``[]``, each having a unique syn respectively. .. deprecated:: 3.9 - :class:`collections.abc.Callable` now supports ``[]``. See :pep:`585` and - :ref:`types-genericalias`. + :class:`collections.abc.Callable` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. versionchanged:: 3.10 ``Callable`` now supports :class:`ParamSpec` and :data:`Concatenate`. - See :pep:`612` for more information. + See :pep:`612` for more details. .. seealso:: The documentation for :class:`ParamSpec` and :class:`Concatenate` provide @@ -725,7 +867,8 @@ These can be used as types in annotations using ``[]``, each having a unique syn callable. Usage is in the form ``Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable]``. ``Concatenate`` is currently only valid when used as the first argument to a :data:`Callable`. - The last parameter to ``Concatenate`` must be a :class:`ParamSpec`. + The last parameter to ``Concatenate`` must be a :class:`ParamSpec` or + ellipsis (``...``). For example, to annotate a decorator ``with_lock`` which provides a :class:`threading.Lock` to the decorated function, ``Concatenate`` can be @@ -737,7 +880,7 @@ These can be used as types in annotations using ``[]``, each having a unique syn from collections.abc import Callable from threading import Lock - from typing import Any, Concatenate, ParamSpec, TypeVar + from typing import Concatenate, ParamSpec, TypeVar P = ParamSpec('P') R = TypeVar('R') @@ -748,7 +891,6 @@ These can be used as types in annotations using ``[]``, each having a unique syn def with_lock(f: Callable[Concatenate[Lock, P], R]) -> Callable[P, R]: '''A type-safe decorator which provides a lock.''' - global my_lock def inner(*args: P.args, **kwargs: P.kwargs) -> R: # Provide the lock as the first argument. return f(my_lock, *args, **kwargs) @@ -815,8 +957,8 @@ These can be used as types in annotations using ``[]``, each having a unique syn .. versionadded:: 3.5.2 .. deprecated:: 3.9 - :class:`builtins.type ` now supports ``[]``. See :pep:`585` and - :ref:`types-genericalias`. + :class:`builtins.type ` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. data:: Literal @@ -891,6 +1033,17 @@ These can be used as types in annotations using ``[]``, each having a unique syn .. versionadded:: 3.8 +.. data:: Required + +.. data:: NotRequired + + Special typing constructs that mark individual keys of a :class:`TypedDict` + as either required or non-required respectively. + + See :class:`TypedDict` and :pep:`655` for more details. + + .. versionadded:: 3.11 + .. data:: Annotated A type, introduced in :pep:`593` (``Flexible function and variable @@ -904,7 +1057,7 @@ These can be used as types in annotations using ``[]``, each having a unique syn ``no_type_check`` functionality that currently exists in the ``typing`` module which completely disables typechecking annotations on a function or a class, the ``Annotated`` type allows for both static typechecking - of ``T`` (e.g., via mypy or Pyre, which can safely ignore ``x``) + of ``T`` (which can safely ignore ``x``) together with runtime access to ``x`` within a specific application. Ultimately, the responsibility of how to interpret the annotations (if @@ -1008,7 +1161,7 @@ These can be used as types in annotations using ``[]``, each having a unique syn 2. If the return value is ``True``, the type of its argument is the type inside ``TypeGuard``. - For example:: + For example:: def is_str_list(val: list[object]) -> TypeGuard[list[str]]: '''Determines whether all objects in the list are strings''' @@ -1038,8 +1191,7 @@ These can be used as types in annotations using ``[]``, each having a unique syn is not a subtype of the former, since ``list`` is invariant. The responsibility of writing type-safe type guards is left to the user. - ``TypeGuard`` also works with type variables. For more information, see - :pep:`647` (User-Defined Type Guards). + ``TypeGuard`` also works with type variables. See :pep:`647` for more details. .. versionadded:: 3.10 @@ -1080,7 +1232,8 @@ These are not used in annotations. They are building blocks for creating generic Usage:: T = TypeVar('T') # Can be anything - A = TypeVar('A', str, bytes) # Must be str or bytes + S = TypeVar('S', bound=str) # Can be any subtype of str + A = TypeVar('A', str, bytes) # Must be exactly str or bytes Type variables exist primarily for the benefit of static type checkers. They serve as the parameters for generic types as well @@ -1091,25 +1244,182 @@ These are not used in annotations. They are building blocks for creating generic """Return a list containing n references to x.""" return [x]*n - def longest(x: A, y: A) -> A: - """Return the longest of two strings.""" - return x if len(x) >= len(y) else y - The latter example's signature is essentially the overloading - of ``(str, str) -> str`` and ``(bytes, bytes) -> bytes``. Also note - that if the arguments are instances of some subclass of :class:`str`, - the return type is still plain :class:`str`. + def print_capitalized(x: S) -> S: + """Print x capitalized, and return x.""" + print(x.capitalize()) + return x + + + def concatenate(x: A, y: A) -> A: + """Add two strings or bytes objects together.""" + return x + y + + Note that type variables can be *bound*, *constrained*, or neither, but + cannot be both bound *and* constrained. + + Bound type variables and constrained type variables have different + semantics in several important ways. Using a *bound* type variable means + that the ``TypeVar`` will be solved using the most specific type possible:: + + x = print_capitalized('a string') + reveal_type(x) # revealed type is str + + class StringSubclass(str): + pass + + y = print_capitalized(StringSubclass('another string')) + reveal_type(y) # revealed type is StringSubclass + + z = print_capitalized(45) # error: int is not a subtype of str + + Type variables can be bound to concrete types, abstract types (ABCs or + protocols), and even unions of types:: + + U = TypeVar('U', bound=str|bytes) # Can be any subtype of the union str|bytes + V = TypeVar('V', bound=SupportsAbs) # Can be anything with an __abs__ method + + Using a *constrained* type variable, however, means that the ``TypeVar`` + can only ever be solved as being exactly one of the constraints given:: + + a = concatenate('one', 'two') + reveal_type(a) # revealed type is str + + b = concatenate(StringSubclass('one'), StringSubclass('two')) + reveal_type(b) # revealed type is str, despite StringSubclass being passed in + + c = concatenate('one', b'two') # error: type variable 'A' can be either str or bytes in a function call, but not both At runtime, ``isinstance(x, T)`` will raise :exc:`TypeError`. In general, :func:`isinstance` and :func:`issubclass` should not be used with types. Type variables may be marked covariant or contravariant by passing ``covariant=True`` or ``contravariant=True``. See :pep:`484` for more - details. By default type variables are invariant. Alternatively, - a type variable may specify an upper bound using ``bound=``. - This means that an actual type substituted (explicitly or implicitly) - for the type variable must be a subclass of the boundary type, - see :pep:`484`. + details. By default, type variables are invariant. + +.. class:: TypeVarTuple + + Type variable tuple. A specialized form of :class:`type variable ` + that enables *variadic* generics. + + A normal type variable enables parameterization with a single type. A type + variable tuple, in contrast, allows parameterization with an + *arbitrary* number of types by acting like an *arbitrary* number of type + variables wrapped in a tuple. For example:: + + T = TypeVar('T') + Ts = TypeVarTuple('Ts') + + def move_first_element_to_last(tup: tuple[T, *Ts]) -> tuple[*Ts, T]: + return (*tup[1:], tup[0]) + + # T is bound to int, Ts is bound to () + # Return value is (1,), which has type tuple[int] + move_first_element_to_last(tup=(1,)) + + # T is bound to int, Ts is bound to (str,) + # Return value is ('spam', 1), which has type tuple[str, int] + move_first_element_to_last(tup=(1, 'spam')) + + # T is bound to int, Ts is bound to (str, float) + # Return value is ('spam', 3.0, 1), which has type tuple[str, float, int] + move_first_element_to_last(tup=(1, 'spam', 3.0)) + + # This fails to type check (and fails at runtime) + # because tuple[()] is not compatible with tuple[T, *Ts] + # (at least one element is required) + move_first_element_to_last(tup=()) + + Note the use of the unpacking operator ``*`` in ``tuple[T, *Ts]``. + Conceptually, you can think of ``Ts`` as a tuple of type variables + ``(T1, T2, ...)``. ``tuple[T, *Ts]`` would then become + ``tuple[T, *(T1, T2, ...)]``, which is equivalent to + ``tuple[T, T1, T2, ...]``. (Note that in older versions of Python, you might + see this written using :data:`Unpack ` instead, as + ``Unpack[Ts]``.) + + Type variable tuples must *always* be unpacked. This helps distinguish type + variable tuples from normal type variables:: + + x: Ts # Not valid + x: tuple[Ts] # Not valid + x: tuple[*Ts] # The correct way to to do it + + Type variable tuples can be used in the same contexts as normal type + variables. For example, in class definitions, arguments, and return types:: + + Shape = TypeVarTuple('Shape') + class Array(Generic[*Shape]): + def __getitem__(self, key: tuple[*Shape]) -> float: ... + def __abs__(self) -> "Array[*Shape]": ... + def get_shape(self) -> tuple[*Shape]: ... + + Type variable tuples can be happily combined with normal type variables:: + + DType = TypeVar('DType') + + class Array(Generic[DType, *Shape]): # This is fine + pass + + class Array2(Generic[*Shape, DType]): # This would also be fine + pass + + float_array_1d: Array[float, Height] = Array() # Totally fine + int_array_2d: Array[int, Height, Width] = Array() # Yup, fine too + + However, note that at most one type variable tuple may appear in a single + list of type arguments or type parameters:: + + x: tuple[*Ts, *Ts] # Not valid + class Array(Generic[*Shape, *Shape]): # Not valid + pass + + Finally, an unpacked type variable tuple can be used as the type annotation + of ``*args``:: + + def call_soon( + callback: Callable[[*Ts], None], + *args: *Ts + ) -> None: + ... + callback(*args) + + In contrast to non-unpacked annotations of ``*args`` - e.g. ``*args: int``, + which would specify that *all* arguments are ``int`` - ``*args: *Ts`` + enables reference to the types of the *individual* arguments in ``*args``. + Here, this allows us to ensure the types of the ``*args`` passed + to ``call_soon`` match the types of the (positional) arguments of + ``callback``. + + See :pep:`646` for more details on type variable tuples. + + .. versionadded:: 3.11 + +.. data:: Unpack + + A typing operator that conceptually marks an object as having been + unpacked. For example, using the unpack operator ``*`` on a + :class:`type variable tuple ` is equivalent to using ``Unpack`` + to mark the type variable tuple as having been unpacked:: + + Ts = TypeVarTuple('Ts') + tup: tuple[*Ts] + # Effectively does: + tup: tuple[Unpack[Ts]] + + In fact, ``Unpack`` can be used interchangeably with ``*`` in the context + of types. You might see ``Unpack`` being used explicitly in older versions + of Python, where ``*`` couldn't be used in certain places:: + + # In older versions of Python, TypeVarTuple and Unpack + # are located in the `typing_extensions` backports package. + from typing_extensions import TypeVarTuple, Unpack + + Ts = TypeVarTuple('Ts') + tup: tuple[*Ts] # Syntax error on Python <= 3.10! + tup: tuple[Unpack[Ts]] # Semantically equivalent, and backwards-compatible + + .. versionadded:: 3.11 .. class:: ParamSpec(name, *, bound=None, covariant=False, contravariant=False) @@ -1155,11 +1465,11 @@ These are not used in annotations. They are building blocks for creating generic use a :class:`TypeVar` with bound ``Callable[..., Any]``. However this causes two problems: - 1. The type checker can't type check the ``inner`` function because - ``*args`` and ``**kwargs`` have to be typed :data:`Any`. - 2. :func:`~cast` may be required in the body of the ``add_logging`` - decorator when returning the ``inner`` function, or the static type - checker must be told to ignore the ``return inner``. + 1. The type checker can't type check the ``inner`` function because + ``*args`` and ``**kwargs`` have to be typed :data:`Any`. + 2. :func:`~cast` may be required in the body of the ``add_logging`` + decorator when returning the ``inner`` function, or the static type + checker must be told to ignore the ``return inner``. .. attribute:: args .. attribute:: kwargs @@ -1211,7 +1521,7 @@ These are not used in annotations. They are building blocks for creating generic .. data:: AnyStr - ``AnyStr`` is a type variable defined as + ``AnyStr`` is a :class:`constrained type variable ` defined as ``AnyStr = TypeVar('AnyStr', str, bytes)``. It is meant to be used for functions that may accept any kind of string @@ -1244,7 +1554,7 @@ These are not used in annotations. They are building blocks for creating generic func(C()) # Passes static type check - See :pep:`544` for details. Protocol classes decorated with + See :pep:`544` for more details. Protocol classes decorated with :func:`runtime_checkable` (described later) act as simple-minded runtime protocols that check only the presence of given attributes, ignoring their type signatures. @@ -1317,7 +1627,7 @@ These are not used in annotations. They are building blocks for declaring types. The resulting class has an extra attribute ``__annotations__`` giving a dict that maps the field names to the field types. (The field names are in the ``_fields`` attribute and the default values are in the - ``_field_defaults`` attribute both of which are part of the namedtuple + ``_field_defaults`` attribute, both of which are part of the :func:`~collections.namedtuple` API.) ``NamedTuple`` subclasses can also have docstrings and methods:: @@ -1330,6 +1640,12 @@ These are not used in annotations. They are building blocks for declaring types. def __repr__(self) -> str: return f'' + ``NamedTuple`` subclasses can be generic:: + + class Group(NamedTuple, Generic[T]): + key: T + group: list[T] + Backward-compatible usage:: Employee = NamedTuple('Employee', [('name', str), ('id', int)]) @@ -1348,6 +1664,9 @@ These are not used in annotations. They are building blocks for declaring types. Removed the ``_field_types`` attribute in favor of the more standard ``__annotations__`` attribute which has the same information. + .. versionchanged:: 3.11 + Added support for generic namedtuples. + .. class:: NewType(name, tp) A helper class to indicate a distinct type to a typechecker, @@ -1384,33 +1703,181 @@ These are not used in annotations. They are building blocks for declaring types. assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first') - The type info for introspection can be accessed via ``Point2D.__annotations__``, - ``Point2D.__total__``, ``Point2D.__required_keys__``, and - ``Point2D.__optional_keys__``. To allow using this feature with older versions of Python that do not support :pep:`526`, ``TypedDict`` supports two additional equivalent - syntactic forms:: + syntactic forms: + + * Using a literal :class:`dict` as the second argument:: - Point2D = TypedDict('Point2D', x=int, y=int, label=str) Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) + * Using keyword arguments:: + + Point2D = TypedDict('Point2D', x=int, y=int, label=str) + + .. deprecated-removed:: 3.11 3.13 + The keyword-argument syntax is deprecated in 3.11 and will be removed + in 3.13. It may also be unsupported by static type checkers. + + The functional syntax should also be used when any of the keys are not valid + :ref:`identifiers `, for example because they are keywords or contain hyphens. + Example:: + + # raises SyntaxError + class Point2D(TypedDict): + in: int # 'in' is a keyword + x-y: int # name with hyphens + + # OK, functional syntax + Point2D = TypedDict('Point2D', {'in': int, 'x-y': int}) + By default, all keys must be present in a ``TypedDict``. It is possible to - override this by specifying totality. - Usage:: + mark individual keys as non-required using :data:`NotRequired`:: + + class Point2D(TypedDict): + x: int + y: int + label: NotRequired[str] + + # Alternative syntax + Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': NotRequired[str]}) + + This means that a ``Point2D`` ``TypedDict`` can have the ``label`` + key omitted. + + It is also possible to mark all keys as non-required by default + by specifying a totality of ``False``:: class Point2D(TypedDict, total=False): x: int y: int + # Alternative syntax + Point2D = TypedDict('Point2D', {'x': int, 'y': int}, total=False) + This means that a ``Point2D`` ``TypedDict`` can have any of the keys omitted. A type checker is only expected to support a literal ``False`` or ``True`` as the value of the ``total`` argument. ``True`` is the default, and makes all items defined in the class body required. + Individual keys of a ``total=False`` ``TypedDict`` can be marked as + required using :data:`Required`:: + + class Point2D(TypedDict, total=False): + x: Required[int] + y: Required[int] + label: str + + # Alternative syntax + Point2D = TypedDict('Point2D', { + 'x': Required[int], + 'y': Required[int], + 'label': str + }, total=False) + + It is possible for a ``TypedDict`` type to inherit from one or more other ``TypedDict`` types + using the class-based syntax. + Usage:: + + class Point3D(Point2D): + z: int + + ``Point3D`` has three items: ``x``, ``y`` and ``z``. It is equivalent to this + definition:: + + class Point3D(TypedDict): + x: int + y: int + z: int + + A ``TypedDict`` cannot inherit from a non-\ ``TypedDict`` class, + except for :class:`Generic`. For example:: + + class X(TypedDict): + x: int + + class Y(TypedDict): + y: int + + class Z(object): pass # A non-TypedDict class + + class XY(X, Y): pass # OK + + class XZ(X, Z): pass # raises TypeError + + T = TypeVar('T') + class XT(X, Generic[T]): pass # raises TypeError + + A ``TypedDict`` can be generic:: + + class Group(TypedDict, Generic[T]): + key: T + group: list[T] + + A ``TypedDict`` can be introspected via annotations dicts + (see :ref:`annotations-howto` for more information on annotations best practices), + :attr:`__total__`, :attr:`__required_keys__`, and :attr:`__optional_keys__`. + + .. attribute:: __total__ + + ``Point2D.__total__`` gives the value of the ``total`` argument. + Example:: + + >>> from typing import TypedDict + >>> class Point2D(TypedDict): pass + >>> Point2D.__total__ + True + >>> class Point2D(TypedDict, total=False): pass + >>> Point2D.__total__ + False + >>> class Point3D(Point2D): pass + >>> Point3D.__total__ + True + + .. attribute:: __required_keys__ + + .. versionadded:: 3.9 + + .. attribute:: __optional_keys__ + + ``Point2D.__required_keys__`` and ``Point2D.__optional_keys__`` return + :class:`frozenset` objects containing required and non-required keys, respectively. + + Keys marked with :data:`Required` will always appear in ``__required_keys__`` + and keys marked with :data:`NotRequired` will always appear in ``__optional_keys__``. + + For backwards compatibility with Python 3.10 and below, + it is also possible to use inheritance to declare both required and + non-required keys in the same ``TypedDict`` . This is done by declaring a + ``TypedDict`` with one value for the ``total`` argument and then + inheriting from it in another ``TypedDict`` with a different value for + ``total``:: + + >>> class Point2D(TypedDict, total=False): + ... x: int + ... y: int + ... + >>> class Point3D(Point2D): + ... z: int + ... + >>> Point3D.__required_keys__ == frozenset({'z'}) + True + >>> Point3D.__optional_keys__ == frozenset({'x', 'y'}) + True + + .. versionadded:: 3.9 + See :pep:`589` for more examples and detailed rules of using ``TypedDict``. .. versionadded:: 3.8 + .. versionchanged:: 3.11 + Added support for marking individual keys as :data:`Required` or :data:`NotRequired`. + See :pep:`655`. + + .. versionchanged:: 3.11 + Added support for generic ``TypedDict``\ s. + Generic concrete collections ---------------------------- @@ -1429,8 +1896,8 @@ Corresponding to built-in types ... .. deprecated:: 3.9 - :class:`builtins.dict ` now supports ``[]``. See :pep:`585` and - :ref:`types-genericalias`. + :class:`builtins.dict ` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: List(list, MutableSequence[T]) @@ -1450,8 +1917,8 @@ Corresponding to built-in types return [item for item in vector if item > 0] .. deprecated:: 3.9 - :class:`builtins.list ` now supports ``[]``. See :pep:`585` and - :ref:`types-genericalias`. + :class:`builtins.list ` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: Set(set, MutableSet[T]) @@ -1460,16 +1927,17 @@ Corresponding to built-in types to use an abstract collection type such as :class:`AbstractSet`. .. deprecated:: 3.9 - :class:`builtins.set ` now supports ``[]``. See :pep:`585` and - :ref:`types-genericalias`. + :class:`builtins.set ` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: FrozenSet(frozenset, AbstractSet[T_co]) A generic version of :class:`builtins.frozenset `. .. deprecated:: 3.9 - :class:`builtins.frozenset ` now supports ``[]``. See - :pep:`585` and :ref:`types-genericalias`. + :class:`builtins.frozenset ` + now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. note:: :data:`Tuple` is a special form. @@ -1483,8 +1951,8 @@ Corresponding to types in :mod:`collections` .. versionadded:: 3.5.2 .. deprecated:: 3.9 - :class:`collections.defaultdict` now supports ``[]``. See :pep:`585` and - :ref:`types-genericalias`. + :class:`collections.defaultdict` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: OrderedDict(collections.OrderedDict, MutableMapping[KT, VT]) @@ -1493,8 +1961,8 @@ Corresponding to types in :mod:`collections` .. versionadded:: 3.7.2 .. deprecated:: 3.9 - :class:`collections.OrderedDict` now supports ``[]``. See :pep:`585` and - :ref:`types-genericalias`. + :class:`collections.OrderedDict` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: ChainMap(collections.ChainMap, MutableMapping[KT, VT]) @@ -1504,8 +1972,8 @@ Corresponding to types in :mod:`collections` .. versionadded:: 3.6.1 .. deprecated:: 3.9 - :class:`collections.ChainMap` now supports ``[]``. See :pep:`585` and - :ref:`types-genericalias`. + :class:`collections.ChainMap` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: Counter(collections.Counter, Dict[T, int]) @@ -1515,8 +1983,8 @@ Corresponding to types in :mod:`collections` .. versionadded:: 3.6.1 .. deprecated:: 3.9 - :class:`collections.Counter` now supports ``[]``. See :pep:`585` and - :ref:`types-genericalias`. + :class:`collections.Counter` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: Deque(deque, MutableSequence[T]) @@ -1526,8 +1994,8 @@ Corresponding to types in :mod:`collections` .. versionadded:: 3.6.1 .. deprecated:: 3.9 - :class:`collections.deque` now supports ``[]``. See :pep:`585` and - :ref:`types-genericalias`. + :class:`collections.deque` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. Other concrete types """""""""""""""""""" @@ -1541,7 +2009,7 @@ Other concrete types represent the types of I/O streams such as returned by :func:`open`. - .. deprecated-removed:: 3.8 3.12 + .. deprecated-removed:: 3.8 3.13 The ``typing.io`` namespace is deprecated and will be removed. These types should be directly imported from ``typing`` instead. @@ -1555,7 +2023,7 @@ Other concrete types ``Pattern[str]``, ``Pattern[bytes]``, ``Match[str]``, or ``Match[bytes]``. - .. deprecated-removed:: 3.8 3.12 + .. deprecated-removed:: 3.8 3.13 The ``typing.re`` namespace is deprecated and will be removed. These types should be directly imported from ``typing`` instead. @@ -1577,19 +2045,25 @@ Other concrete types .. versionadded:: 3.5.2 + .. deprecated:: 3.11 + Python 2 is no longer supported, and most type checkers also no longer + support type checking Python 2 code. Removal of the alias is not + currently planned, but users are encouraged to use + :class:`str` instead of ``Text`` wherever possible. + Abstract Base Classes --------------------- Corresponding to collections in :mod:`collections.abc` """""""""""""""""""""""""""""""""""""""""""""""""""""" -.. class:: AbstractSet(Sized, Collection[T_co]) +.. class:: AbstractSet(Collection[T_co]) A generic version of :class:`collections.abc.Set`. .. deprecated:: 3.9 - :class:`collections.abc.Set` now supports ``[]``. See :pep:`585` and - :ref:`types-genericalias`. + :class:`collections.abc.Set` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: ByteString(Sequence[int]) @@ -1602,8 +2076,8 @@ Corresponding to collections in :mod:`collections.abc` annotate arguments of any of the types mentioned above. .. deprecated:: 3.9 - :class:`collections.abc.ByteString` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.ByteString` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: Collection(Sized, Iterable[T_co], Container[T_co]) @@ -1612,34 +2086,34 @@ Corresponding to collections in :mod:`collections.abc` .. versionadded:: 3.6.0 .. deprecated:: 3.9 - :class:`collections.abc.Collection` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.Collection` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: Container(Generic[T_co]) A generic version of :class:`collections.abc.Container`. .. deprecated:: 3.9 - :class:`collections.abc.Container` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.Container` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. -.. class:: ItemsView(MappingView, Generic[KT_co, VT_co]) +.. class:: ItemsView(MappingView, AbstractSet[tuple[KT_co, VT_co]]) A generic version of :class:`collections.abc.ItemsView`. .. deprecated:: 3.9 - :class:`collections.abc.ItemsView` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.ItemsView` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. -.. class:: KeysView(MappingView[KT_co], AbstractSet[KT_co]) +.. class:: KeysView(MappingView, AbstractSet[KT_co]) A generic version of :class:`collections.abc.KeysView`. .. deprecated:: 3.9 - :class:`collections.abc.KeysView` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.KeysView` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. -.. class:: Mapping(Sized, Collection[KT], Generic[VT_co]) +.. class:: Mapping(Collection[KT], Generic[KT, VT_co]) A generic version of :class:`collections.abc.Mapping`. This type can be used as follows:: @@ -1648,56 +2122,58 @@ Corresponding to collections in :mod:`collections.abc` return word_list[word] .. deprecated:: 3.9 - :class:`collections.abc.Mapping` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.Mapping` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. -.. class:: MappingView(Sized, Iterable[T_co]) +.. class:: MappingView(Sized) A generic version of :class:`collections.abc.MappingView`. .. deprecated:: 3.9 - :class:`collections.abc.MappingView` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.MappingView` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: MutableMapping(Mapping[KT, VT]) A generic version of :class:`collections.abc.MutableMapping`. .. deprecated:: 3.9 - :class:`collections.abc.MutableMapping` now supports ``[]``. See - :pep:`585` and :ref:`types-genericalias`. + :class:`collections.abc.MutableMapping` + now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: MutableSequence(Sequence[T]) A generic version of :class:`collections.abc.MutableSequence`. .. deprecated:: 3.9 - :class:`collections.abc.MutableSequence` now supports ``[]``. See - :pep:`585` and :ref:`types-genericalias`. + :class:`collections.abc.MutableSequence` + now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: MutableSet(AbstractSet[T]) A generic version of :class:`collections.abc.MutableSet`. .. deprecated:: 3.9 - :class:`collections.abc.MutableSet` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.MutableSet` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: Sequence(Reversible[T_co], Collection[T_co]) A generic version of :class:`collections.abc.Sequence`. .. deprecated:: 3.9 - :class:`collections.abc.Sequence` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.Sequence` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. -.. class:: ValuesView(MappingView[VT_co]) +.. class:: ValuesView(MappingView, Collection[_VT_co]) A generic version of :class:`collections.abc.ValuesView`. .. deprecated:: 3.9 - :class:`collections.abc.ValuesView` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.ValuesView` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. Corresponding to other types in :mod:`collections.abc` """""""""""""""""""""""""""""""""""""""""""""""""""""" @@ -1707,16 +2183,16 @@ Corresponding to other types in :mod:`collections.abc` A generic version of :class:`collections.abc.Iterable`. .. deprecated:: 3.9 - :class:`collections.abc.Iterable` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.Iterable` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: Iterator(Iterable[T_co]) A generic version of :class:`collections.abc.Iterator`. .. deprecated:: 3.9 - :class:`collections.abc.Iterator` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.Iterator` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: Generator(Iterator[T_co], Generic[T_co, T_contra, V_co]) @@ -1750,24 +2226,30 @@ Corresponding to other types in :mod:`collections.abc` start += 1 .. deprecated:: 3.9 - :class:`collections.abc.Generator` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.Generator` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: Hashable - An alias to :class:`collections.abc.Hashable` + An alias to :class:`collections.abc.Hashable`. + + .. deprecated:: 3.12 + Use :class:`collections.abc.Hashable` directly instead. .. class:: Reversible(Iterable[T_co]) A generic version of :class:`collections.abc.Reversible`. .. deprecated:: 3.9 - :class:`collections.abc.Reversible` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.Reversible` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: Sized - An alias to :class:`collections.abc.Sized` + An alias to :class:`collections.abc.Sized`. + + .. deprecated:: 3.12 + Use :class:`collections.abc.Sized` directly instead. Asynchronous programming """""""""""""""""""""""" @@ -1779,17 +2261,16 @@ Asynchronous programming correspond to those of :class:`Generator`, for example:: from collections.abc import Coroutine - c = None # type: Coroutine[list[str], str, int] - ... - x = c.send('hi') # type: list[str] + c: Coroutine[list[str], str, int] # Some coroutine defined elsewhere + x = c.send('hi') # Inferred type of 'x' is list[str] async def bar() -> None: - x = await c # type: int + y = await c # Inferred type of 'y' is int .. versionadded:: 3.5.3 .. deprecated:: 3.9 - :class:`collections.abc.Coroutine` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.Coroutine` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: AsyncGenerator(AsyncIterator[T_co], Generic[T_co, T_contra]) @@ -1825,8 +2306,9 @@ Asynchronous programming .. versionadded:: 3.6.1 .. deprecated:: 3.9 - :class:`collections.abc.AsyncGenerator` now supports ``[]``. See - :pep:`585` and :ref:`types-genericalias`. + :class:`collections.abc.AsyncGenerator` + now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: AsyncIterable(Generic[T_co]) @@ -1835,8 +2317,8 @@ Asynchronous programming .. versionadded:: 3.5.2 .. deprecated:: 3.9 - :class:`collections.abc.AsyncIterable` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.AsyncIterable` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: AsyncIterator(AsyncIterable[T_co]) @@ -1845,8 +2327,8 @@ Asynchronous programming .. versionadded:: 3.5.2 .. deprecated:: 3.9 - :class:`collections.abc.AsyncIterator` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.AsyncIterator` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: Awaitable(Generic[T_co]) @@ -1855,8 +2337,8 @@ Asynchronous programming .. versionadded:: 3.5.2 .. deprecated:: 3.9 - :class:`collections.abc.Awaitable` now supports ``[]``. See :pep:`585` - and :ref:`types-genericalias`. + :class:`collections.abc.Awaitable` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. Context manager types @@ -1870,8 +2352,9 @@ Context manager types .. versionadded:: 3.6.0 .. deprecated:: 3.9 - :class:`contextlib.AbstractContextManager` now supports ``[]``. See - :pep:`585` and :ref:`types-genericalias`. + :class:`contextlib.AbstractContextManager` + now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. .. class:: AsyncContextManager(Generic[T_co]) @@ -1881,8 +2364,9 @@ Context manager types .. versionadded:: 3.6.2 .. deprecated:: 3.9 - :class:`contextlib.AbstractAsyncContextManager` now supports ``[]``. See - :pep:`585` and :ref:`types-genericalias`. + :class:`contextlib.AbstractAsyncContextManager` + now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. Protocols --------- @@ -1933,6 +2417,203 @@ Functions and decorators runtime we intentionally don't check anything (we want this to be as fast as possible). +.. function:: assert_type(val, typ, /) + + Ask a static type checker to confirm that *val* has an inferred type of *typ*. + + When the type checker encounters a call to ``assert_type()``, it + emits an error if the value is not of the specified type:: + + def greet(name: str) -> None: + assert_type(name, str) # OK, inferred type of `name` is `str` + assert_type(name, int) # type checker error + + At runtime this returns the first argument unchanged with no side effects. + + This function is useful for ensuring the type checker's understanding of a + script is in line with the developer's intentions:: + + def complex_function(arg: object): + # Do some complex type-narrowing logic, + # after which we hope the inferred type will be `int` + ... + # Test whether the type checker correctly understands our function + assert_type(arg, int) + + .. versionadded:: 3.11 + +.. function:: assert_never(arg, /) + + Ask a static type checker to confirm that a line of code is unreachable. + + Example:: + + def int_or_str(arg: int | str) -> None: + match arg: + case int(): + print("It's an int") + case str(): + print("It's a str") + case _ as unreachable: + assert_never(unreachable) + + Here, the annotations allow the type checker to infer that the + last case can never execute, because ``arg`` is either + an :class:`int` or a :class:`str`, and both options are covered by + earlier cases. + If a type checker finds that a call to ``assert_never()`` is + reachable, it will emit an error. For example, if the type annotation + for ``arg`` was instead ``int | str | float``, the type checker would + emit an error pointing out that ``unreachable`` is of type :class:`float`. + For a call to ``assert_never`` to pass type checking, the inferred type of + the argument passed in must be the bottom type, :data:`Never`, and nothing + else. + + At runtime, this throws an exception when called. + + .. seealso:: + `Unreachable Code and Exhaustiveness Checking + `__ has more + information about exhaustiveness checking with static typing. + + .. versionadded:: 3.11 + +.. function:: reveal_type(obj, /) + + Reveal the inferred static type of an expression. + + When a static type checker encounters a call to this function, + it emits a diagnostic with the type of the argument. For example:: + + x: int = 1 + reveal_type(x) # Revealed type is "builtins.int" + + This can be useful when you want to debug how your type checker + handles a particular piece of code. + + The function returns its argument unchanged, which allows using + it within an expression:: + + x = reveal_type(1) # Revealed type is "builtins.int" + + Most type checkers support ``reveal_type()`` anywhere, even if the + name is not imported from ``typing``. Importing the name from + ``typing`` allows your code to run without runtime errors and + communicates intent more clearly. + + At runtime, this function prints the runtime type of its argument to stderr + and returns it unchanged:: + + x = reveal_type(1) # prints "Runtime type is int" + print(x) # prints "1" + + .. versionadded:: 3.11 + +.. decorator:: dataclass_transform + + :data:`~typing.dataclass_transform` may be used to + decorate a class, metaclass, or a function that is itself a decorator. + The presence of ``@dataclass_transform()`` tells a static type checker that the + decorated object performs runtime "magic" that + transforms a class, giving it :func:`dataclasses.dataclass`-like behaviors. + + Example usage with a decorator function:: + + T = TypeVar("T") + + @dataclass_transform() + def create_model(cls: type[T]) -> type[T]: + ... + return cls + + @create_model + class CustomerModel: + id: int + name: str + + On a base class:: + + @dataclass_transform() + class ModelBase: ... + + class CustomerModel(ModelBase): + id: int + name: str + + On a metaclass:: + + @dataclass_transform() + class ModelMeta(type): ... + + class ModelBase(metaclass=ModelMeta): ... + + class CustomerModel(ModelBase): + id: int + name: str + + The ``CustomerModel`` classes defined above will + be treated by type checkers similarly to classes created with + :func:`@dataclasses.dataclass `. + For example, type checkers will assume these classes have + ``__init__`` methods that accept ``id`` and ``name``. + + The decorated class, metaclass, or function may accept the following bool + arguments which type checkers will assume have the same effect as they + would have on the + :func:`@dataclasses.dataclass` decorator: ``init``, + ``eq``, ``order``, ``unsafe_hash``, ``frozen``, ``match_args``, + ``kw_only``, and ``slots``. It must be possible for the value of these + arguments (``True`` or ``False``) to be statically evaluated. + + The arguments to the ``dataclass_transform`` decorator can be used to + customize the default behaviors of the decorated class, metaclass, or + function: + + * ``eq_default`` indicates whether the ``eq`` parameter is assumed to be + ``True`` or ``False`` if it is omitted by the caller. + * ``order_default`` indicates whether the ``order`` parameter is + assumed to be True or False if it is omitted by the caller. + * ``kw_only_default`` indicates whether the ``kw_only`` parameter is + assumed to be True or False if it is omitted by the caller. + * ``frozen_default`` indicates whether the ``frozen`` parameter is + assumed to be True or False if it is omitted by the caller. + + .. versionadded:: 3.12 + * ``field_specifiers`` specifies a static list of supported classes + or functions that describe fields, similar to ``dataclasses.field()``. + * Arbitrary other keyword arguments are accepted in order to allow for + possible future extensions. + + Type checkers recognize the following optional arguments on field + specifiers: + + * ``init`` indicates whether the field should be included in the + synthesized ``__init__`` method. If unspecified, ``init`` defaults to + ``True``. + * ``default`` provides the default value for the field. + * ``default_factory`` provides a runtime callback that returns the + default value for the field. If neither ``default`` nor + ``default_factory`` are specified, the field is assumed to have no + default value and must be provided a value when the class is + instantiated. + * ``factory`` is an alias for ``default_factory``. + * ``kw_only`` indicates whether the field should be marked as + keyword-only. If ``True``, the field will be keyword-only. If + ``False``, it will not be keyword-only. If unspecified, the value of + the ``kw_only`` parameter on the object decorated with + ``dataclass_transform`` will be used, or if that is unspecified, the + value of ``kw_only_default`` on ``dataclass_transform`` will be used. + * ``alias`` provides an alternative name for the field. This alternative + name is used in the synthesized ``__init__`` method. + + At runtime, this decorator records its arguments in the + ``__dataclass_transform__`` attribute on the decorated object. + It has no other runtime effect. + + See :pep:`681` for more details. + + .. versionadded:: 3.11 + .. decorator:: overload The ``@overload`` decorator allows describing functions and methods @@ -1959,7 +2640,36 @@ Functions and decorators def process(response): - See :pep:`484` for details and comparison with other typing semantics. + See :pep:`484` for more details and comparison with other typing semantics. + + .. versionchanged:: 3.11 + Overloaded functions can now be introspected at runtime using + :func:`get_overloads`. + + +.. function:: get_overloads(func) + + Return a sequence of :func:`@overload `-decorated definitions for + *func*. *func* is the function object for the implementation of the + overloaded function. For example, given the definition of ``process`` in + the documentation for :func:`@overload `, + ``get_overloads(process)`` will return a sequence of three function objects + for the three defined overloads. If called on a function with no overloads, + ``get_overloads()`` returns an empty sequence. + + ``get_overloads()`` can be used for introspecting an overloaded function at + runtime. + + .. versionadded:: 3.11 + + +.. function:: clear_overloads() + + Clear all registered overloads in the internal registry. This can be used + to reclaim the memory used by the registry. + + .. versionadded:: 3.11 + .. decorator:: final @@ -1973,7 +2683,7 @@ Functions and decorators ... class Sub(Base): def done(self) -> None: # Error reported by type checker - ... + ... @final class Leaf: @@ -1986,13 +2696,22 @@ Functions and decorators .. versionadded:: 3.8 + .. versionchanged:: 3.11 + The decorator will now set the ``__final__`` attribute to ``True`` + on the decorated object. Thus, a check like + ``if getattr(obj, "__final__", False)`` can be used at runtime + to determine whether an object ``obj`` has been marked as final. + If the decorated object does not support setting attributes, + the decorator returns the object unchanged without raising an exception. + + .. decorator:: no_type_check Decorator to indicate that annotations are not type hints. This works as class or function :term:`decorator`. With a class, it - applies recursively to all methods defined in that class (but not - to methods defined in its superclasses or subclasses). + applies recursively to all methods and classes defined in that class + (but not to methods defined in its superclasses or subclasses). This mutates the function(s) in place. @@ -2031,9 +2750,7 @@ Introspection helpers This is often the same as ``obj.__annotations__``. In addition, forward references encoded as string literals are handled by evaluating - them in ``globals`` and ``locals`` namespaces. If necessary, - ``Optional[t]`` is added for function and method annotations if a default - value equal to ``None`` is set. For a class ``C``, return + them in ``globals`` and ``locals`` namespaces. For a class ``C``, return a dictionary constructed by merging all the ``__annotations__`` along ``C.__mro__`` in reverse order. @@ -2060,6 +2777,11 @@ Introspection helpers .. versionchanged:: 3.9 Added ``include_extras`` parameter as part of :pep:`593`. + .. versionchanged:: 3.11 + Previously, ``Optional[t]`` was added for function and method annotations + if a default value equal to ``None`` was set. + Now the annotation is returned unchanged. + .. function:: get_args(tp) .. function:: get_origin(tp) @@ -2100,8 +2822,8 @@ Introspection helpers .. class:: ForwardRef A class used for internal typing representation of string forward references. - For example, ``list["SomeClass"]`` is implicitly transformed into - ``list[ForwardRef("SomeClass")]``. This class should not be instantiated by + For example, ``List["SomeClass"]`` is implicitly transformed into + ``List[ForwardRef("SomeClass")]``. This class should not be instantiated by a user, but may be used by introspection tools. .. note:: @@ -2132,10 +2854,32 @@ Constant .. note:: - If ``from __future__ import annotations`` is used in Python 3.7 or later, + If ``from __future__ import annotations`` is used, annotations are not evaluated at function definition time. - Instead, they are stored as strings in ``__annotations__``, - This makes it unnecessary to use quotes around the annotation. + Instead, they are stored as strings in ``__annotations__``. + This makes it unnecessary to use quotes around the annotation (see :pep:`563`). .. versionadded:: 3.5.2 + +Deprecation Timeline of Major Features +====================================== + +Certain features in ``typing`` are deprecated and may be removed in a future +version of Python. The following table summarizes major deprecations for your +convenience. This is subject to change, and not all deprecations are listed. + ++----------------------------------+---------------+-------------------+----------------+ +| Feature | Deprecated in | Projected removal | PEP/issue | ++==================================+===============+===================+================+ +| ``typing.io`` and ``typing.re`` | 3.8 | 3.13 | :issue:`38291` | +| submodules | | | | ++----------------------------------+---------------+-------------------+----------------+ +| ``typing`` versions of standard | 3.9 | Undecided | :pep:`585` | +| collections | | | | ++----------------------------------+---------------+-------------------+----------------+ +| ``typing.Text`` | 3.11 | Undecided | :gh:`92332` | ++----------------------------------+---------------+-------------------+----------------+ +| ``typing.Hashable`` and | 3.12 | Undecided | :gh:`94309` | +| ``typing.Sized`` | | | | ++----------------------------------+---------------+-------------------+----------------+ diff --git a/Doc/library/undoc.rst b/Doc/library/undoc.rst deleted file mode 100644 index 2444080d6b9..00000000000 --- a/Doc/library/undoc.rst +++ /dev/null @@ -1,26 +0,0 @@ -.. _undoc: - -******************** -Undocumented Modules -******************** - -Here's a quick listing of modules that are currently undocumented, but that -should be documented. Feel free to contribute documentation for them! (Send -via email to docs@python.org.) - -The idea and original contents for this chapter were taken from a posting by -Fredrik Lundh; the specific contents of this chapter have been substantially -revised. - - -Platform specific modules -========================= - -These modules are used to implement the :mod:`os.path` module, and are not -documented beyond this mention. There's little need to document these. - -:mod:`ntpath` - --- Implementation of :mod:`os.path` on Win32 and Win64 platforms. - -:mod:`posixpath` - --- Implementation of :mod:`os.path` on POSIX. diff --git a/Doc/library/unicodedata.rst b/Doc/library/unicodedata.rst index 6276f6382a0..3a094f9c64d 100644 --- a/Doc/library/unicodedata.rst +++ b/Doc/library/unicodedata.rst @@ -17,8 +17,8 @@ This module provides access to the Unicode Character Database (UCD) which defines character properties for all Unicode characters. The data contained in -this database is compiled from the `UCD version 14.0.0 -`_. +this database is compiled from the `UCD version 15.0.0 +`_. The module uses the same names and symbols as defined by Unicode Standard Annex #44, `"Unicode Character Database" @@ -175,6 +175,6 @@ Examples: .. rubric:: Footnotes -.. [#] https://www.unicode.org/Public/14.0.0/ucd/NameAliases.txt +.. [#] https://www.unicode.org/Public/15.0.0/ucd/NameAliases.txt -.. [#] https://www.unicode.org/Public/14.0.0/ucd/NamedSequences.txt +.. [#] https://www.unicode.org/Public/15.0.0/ucd/NamedSequences.txt diff --git a/Doc/library/unittest.mock-examples.rst b/Doc/library/unittest.mock-examples.rst index 24a18c68484..f9a207bad69 100644 --- a/Doc/library/unittest.mock-examples.rst +++ b/Doc/library/unittest.mock-examples.rst @@ -660,7 +660,7 @@ Applying the same patch to every test method If you want several patches in place for multiple test methods the obvious way is to apply the patch decorators to every method. This can feel like unnecessary -repetition. For Python 2.6 or more recent you can use :func:`patch` (in all its +repetition. Instead, you can use :func:`patch` (in all its various forms) as a class decorator. This applies the patches to all test methods on the class. A test method is identified by methods whose names start with ``test``:: @@ -1116,7 +1116,7 @@ on first use). That aside there is a way to use ``mock`` to affect the results of an import. Importing fetches an *object* from the :data:`sys.modules` dictionary. Note that it fetches an *object*, which need not be a module. Importing a module for the -first time results in a module object being put in `sys.modules`, so usually +first time results in a module object being put in ``sys.modules``, so usually when you import something you get a module back. This need not be the case however. diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 0856c3fbded..e009f303fef 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -1516,7 +1516,7 @@ attribute in a class) that does not exist will fail with :exc:`AttributeError`:: >>> test() Traceback (most recent call last): ... - AttributeError: does not have the attribute 'non_existing' + AttributeError: does not have the attribute 'non_existing_attribute' but adding ``create=True`` in the call to :func:`patch` will make the previous example work as expected:: @@ -1604,6 +1604,7 @@ decorator: >>> @patch.dict(foo, {'newkey': 'newvalue'}) ... def test(): ... assert foo == {'newkey': 'newvalue'} + ... >>> test() >>> assert foo == {} @@ -1944,7 +1945,7 @@ Both patch_ and patch.object_ correctly patch and restore descriptors: class methods, static methods and properties. You should patch these on the *class* rather than an instance. They also work with *some* objects that proxy attribute access, like the `django settings object -`_. +`_. MagicMock and magic method support @@ -2165,7 +2166,7 @@ Magic methods that are supported but not setup by default in ``MagicMock`` are: * ``__reversed__`` and ``__missing__`` * ``__reduce__``, ``__reduce_ex__``, ``__getinitargs__``, ``__getnewargs__``, ``__getstate__`` and ``__setstate__`` -* ``__getformat__`` and ``__setformat__`` +* ``__getformat__`` @@ -2381,7 +2382,7 @@ FILTER_DIR .. data:: FILTER_DIR :data:`FILTER_DIR` is a module level variable that controls the way mock objects -respond to :func:`dir` (only for Python 2.6 or more recent). The default is ``True``, +respond to :func:`dir`. The default is ``True``, which uses the filtering described below, to only show useful members. If you dislike this filtering, or need to switch it off for diagnostic purposes, then set ``mock.FILTER_DIR = False``. @@ -2550,7 +2551,7 @@ your assertion is gone: >>> mock = Mock(name='Thing', return_value=None) >>> mock(1, 2, 3) - >>> mock.assret_called_once_with(4, 5, 6) + >>> mock.assret_called_once_with(4, 5, 6) # Intentional typo! Your tests can pass silently and incorrectly because of the typo. @@ -2570,7 +2571,7 @@ attributes on the mock that exist on the real class: >>> from urllib import request >>> mock = Mock(spec=request.Request) - >>> mock.assret_called_with + >>> mock.assret_called_with # Intentional typo! Traceback (most recent call last): ... AttributeError: Mock object has no attribute 'assret_called_with' @@ -2582,7 +2583,7 @@ with any methods on the mock: >>> mock.has_data() - >>> mock.has_data.assret_called_with() + >>> mock.has_data.assret_called_with() # Intentional typo! Auto-speccing solves this problem. You can either pass ``autospec=True`` to :func:`patch` / :func:`patch.object` or use the :func:`create_autospec` function to create a @@ -2625,7 +2626,7 @@ any typos in our asserts will raise the correct error:: >>> req.add_header('spam', 'eggs') - >>> req.add_header.assret_called_with + >>> req.add_header.assret_called_with # Intentional typo! Traceback (most recent call last): ... AttributeError: Mock object has no attribute 'assret_called_with' diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index bf7a1e87928..1577149e976 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -72,8 +72,9 @@ test runner a GUI tool for test discovery and execution. This is intended largely for ease of use for those new to unit testing. For production environments it is recommended that tests be driven by a continuous integration system such as - `Buildbot `_, `Jenkins `_ - or `Travis-CI `_, or `AppVeyor `_. + `Buildbot `_, `Jenkins `_, + `GitHub Actions `_, or + `AppVeyor `_. .. _unittest-minimal-example: @@ -138,9 +139,9 @@ line, the above script produces an output that looks like this:: Passing the ``-v`` option to your test script will instruct :func:`unittest.main` to enable a higher level of verbosity, and produce the following output:: - test_isupper (__main__.TestStringMethods) ... ok - test_split (__main__.TestStringMethods) ... ok - test_upper (__main__.TestStringMethods) ... ok + test_isupper (__main__.TestStringMethods.test_isupper) ... ok + test_split (__main__.TestStringMethods.test_split) ... ok + test_upper (__main__.TestStringMethods.test_upper) ... ok ---------------------------------------------------------------------- Ran 3 tests in 0.001s @@ -265,8 +266,7 @@ Test Discovery Unittest supports simple test discovery. In order to be compatible with test discovery, all of the test files must be :ref:`modules ` or -:ref:`packages ` (including :term:`namespace packages -`) importable from the top-level directory of +:ref:`packages ` importable from the top-level directory of the project (this means that their filenames must be valid :ref:`identifiers `). @@ -339,6 +339,24 @@ the `load_tests protocol`_. directory too (e.g. ``python -m unittest discover -s root/namespace -t root``). +.. versionchanged:: 3.11 + Python 3.11 dropped the :term:`namespace packages ` + support. It has been broken since Python 3.7. Start directory and + subdirectories containing tests must be regular package that have + ``__init__.py`` file. + + Directories containing start directory still can be a namespace package. + In this case, you need to specify start directory as dotted package name, + and target directory explicitly. For example:: + + # proj/ <-- current directory + # namespace/ + # mypkg/ + # __init__.py + # test_mypkg.py + + python -m unittest discover -s namespace.mypkg -t . + .. _organizing-tests: @@ -547,10 +565,10 @@ Basic skipping looks like this:: This is the output of running the example above in verbose mode:: - test_format (__main__.MyTestCase) ... skipped 'not supported in this library version' - test_nothing (__main__.MyTestCase) ... skipped 'demonstrating skipping' - test_maybe_skipped (__main__.MyTestCase) ... skipped 'external resource not available' - test_windows_support (__main__.MyTestCase) ... skipped 'requires Windows' + test_format (__main__.MyTestCase.test_format) ... skipped 'not supported in this library version' + test_nothing (__main__.MyTestCase.test_nothing) ... skipped 'demonstrating skipping' + test_maybe_skipped (__main__.MyTestCase.test_maybe_skipped) ... skipped 'external resource not available' + test_windows_support (__main__.MyTestCase.test_windows_support) ... skipped 'requires Windows' ---------------------------------------------------------------------- Ran 4 tests in 0.005s @@ -643,27 +661,33 @@ For example, the following test:: will produce the following output:: ====================================================================== - FAIL: test_even (__main__.NumbersTest) (i=1) + FAIL: test_even (__main__.NumbersTest.test_even) (i=1) + Test that numbers between 0 and 5 are all even. ---------------------------------------------------------------------- Traceback (most recent call last): - File "subtests.py", line 32, in test_even + File "subtests.py", line 11, in test_even self.assertEqual(i % 2, 0) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ AssertionError: 1 != 0 ====================================================================== - FAIL: test_even (__main__.NumbersTest) (i=3) + FAIL: test_even (__main__.NumbersTest.test_even) (i=3) + Test that numbers between 0 and 5 are all even. ---------------------------------------------------------------------- Traceback (most recent call last): - File "subtests.py", line 32, in test_even + File "subtests.py", line 11, in test_even self.assertEqual(i % 2, 0) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ AssertionError: 1 != 0 ====================================================================== - FAIL: test_even (__main__.NumbersTest) (i=5) + FAIL: test_even (__main__.NumbersTest.test_even) (i=5) + Test that numbers between 0 and 5 are all even. ---------------------------------------------------------------------- Traceback (most recent call last): - File "subtests.py", line 32, in test_even + File "subtests.py", line 11, in test_even self.assertEqual(i % 2, 0) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ AssertionError: 1 != 0 Without using a subtest, execution would stop after the first failure, @@ -671,7 +695,7 @@ and the error would be less easy to diagnose because the value of ``i`` wouldn't be displayed:: ====================================================================== - FAIL: test_even (__main__.NumbersTest) + FAIL: test_even (__main__.NumbersTest.test_even) ---------------------------------------------------------------------- Traceback (most recent call last): File "subtests.py", line 32, in test_even @@ -1126,8 +1150,8 @@ Test cases Example:: with self.assertLogs('foo', level='INFO') as cm: - logging.getLogger('foo').info('first message') - logging.getLogger('foo.bar').error('second message') + logging.getLogger('foo').info('first message') + logging.getLogger('foo.bar').error('second message') self.assertEqual(cm.output, ['INFO:foo:first message', 'ERROR:foo.bar:second message']) @@ -1468,6 +1492,16 @@ Test cases .. versionadded:: 3.1 + .. method:: enterContext(cm) + + Enter the supplied :term:`context manager`. If successful, also + add its :meth:`~object.__exit__` method as a cleanup function by + :meth:`addCleanup` and return the result of the + :meth:`~object.__enter__` method. + + .. versionadded:: 3.11 + + .. method:: doCleanups() This method is called unconditionally after :meth:`tearDown`, or @@ -1483,6 +1517,7 @@ Test cases .. versionadded:: 3.1 + .. classmethod:: addClassCleanup(function, /, *args, **kwargs) Add a function to be called after :meth:`tearDownClass` to cleanup @@ -1497,6 +1532,16 @@ Test cases .. versionadded:: 3.8 + .. classmethod:: enterClassContext(cm) + + Enter the supplied :term:`context manager`. If successful, also + add its :meth:`~object.__exit__` method as a cleanup function by + :meth:`addClassCleanup` and return the result of the + :meth:`~object.__enter__` method. + + .. versionadded:: 3.11 + + .. classmethod:: doClassCleanups() This method is called unconditionally after :meth:`tearDownClass`, or @@ -1544,6 +1589,16 @@ Test cases This method accepts a coroutine that can be used as a cleanup function. + .. coroutinemethod:: enterAsyncContext(cm) + + Enter the supplied :term:`asynchronous context manager`. If successful, + also add its :meth:`~object.__aexit__` method as a cleanup function by + :meth:`addAsyncCleanup` and return the result of the + :meth:`~object.__aenter__` method. + + .. versionadded:: 3.11 + + .. method:: run(result=None) Sets up a new event loop to run the test, collecting the result into @@ -1705,7 +1760,7 @@ Loading and running tests A list of the non-fatal errors encountered while loading tests. Not reset by the loader at any point. Fatal errors are signalled by the relevant - a method raising an exception to the caller. Non-fatal errors are also + method raising an exception to the caller. Non-fatal errors are also indicated by a synthetic test that will raise the original error when run. @@ -1753,7 +1808,7 @@ Loading and running tests .. versionchanged:: 3.5 Support for a keyword-only argument *pattern* has been added. - .. versionchanged:: 3.11 + .. versionchanged:: 3.12 The undocumented and unofficial *use_load_tests* parameter has been removed. @@ -1857,6 +1912,10 @@ Loading and running tests whether their path matches *pattern*, because it is impossible for a package name to match the default pattern. + .. versionchanged:: 3.11 + *start_dir* can not be a :term:`namespace packages `. + It has been broken since Python 3.7 and Python 3.11 officially remove it. + The following attributes of a :class:`TestLoader` can be configured either by subclassing or assignment on an instance: @@ -1888,12 +1947,12 @@ Loading and running tests .. attribute:: testNamePatterns List of Unix shell-style wildcard test name patterns that test methods - have to match to be included in test suites (see ``-v`` option). + have to match to be included in test suites (see ``-k`` option). If this attribute is not ``None`` (the default), all test methods to be included in test suites must match one of the patterns in this list. Note that matches are always performed using :meth:`fnmatch.fnmatchcase`, - so unlike patterns passed to the ``-v`` option, simple substring patterns + so unlike patterns passed to the ``-k`` option, simple substring patterns will have to be converted using ``*`` wildcards. This affects all the :meth:`loadTestsFrom\*` methods. @@ -2396,13 +2455,23 @@ To add cleanup code that must be run even in the case of an exception, use .. versionadded:: 3.8 +.. classmethod:: enterModuleContext(cm) + + Enter the supplied :term:`context manager`. If successful, also + add its :meth:`~object.__exit__` method as a cleanup function by + :func:`addModuleCleanup` and return the result of the + :meth:`~object.__enter__` method. + + .. versionadded:: 3.11 + + .. function:: doModuleCleanups() This function is called unconditionally after :func:`tearDownModule`, or after :func:`setUpModule` if :func:`setUpModule` raises an exception. It is responsible for calling all the cleanup functions added by - :func:`addCleanupModule`. If you need cleanup functions to be called + :func:`addModuleCleanup`. If you need cleanup functions to be called *prior* to :func:`tearDownModule` then you can call :func:`doModuleCleanups` yourself. @@ -2411,6 +2480,7 @@ To add cleanup code that must be run even in the case of an exception, use .. versionadded:: 3.8 + Signal Handling --------------- diff --git a/Doc/library/unix.rst b/Doc/library/unix.rst index 04d4081f4a0..4553a104d15 100644 --- a/Doc/library/unix.rst +++ b/Doc/library/unix.rst @@ -13,14 +13,10 @@ of it. Here's an overview: posix.rst pwd.rst - spwd.rst grp.rst - crypt.rst termios.rst tty.rst pty.rst fcntl.rst - pipes.rst resource.rst - nis.rst syslog.rst diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index a060cc9ba7f..96b39651079 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -48,17 +48,29 @@ or on combining URL components into a URL string. result, except for a leading slash in the *path* component, which is retained if present. For example: + .. doctest:: + :options: +NORMALIZE_WHITESPACE + >>> from urllib.parse import urlparse - >>> o = urlparse('http://www.cwi.nl:80/%7Eguido/Python.html') - >>> o # doctest: +NORMALIZE_WHITESPACE - ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', - params='', query='', fragment='') + >>> urlparse("scheme://netloc/path;parameters?query#fragment") + ParseResult(scheme='scheme', netloc='netloc', path='/path;parameters', params='', + query='query', fragment='fragment') + >>> o = urlparse("http://docs.python.org:80/3/library/urllib.parse.html?" + ... "highlight=params#url-parsing") + >>> o + ParseResult(scheme='http', netloc='docs.python.org:80', + path='/3/library/urllib.parse.html', params='', + query='highlight=params', fragment='url-parsing') >>> o.scheme 'http' + >>> o.netloc + 'docs.python.org:80' + >>> o.hostname + 'docs.python.org' >>> o.port 80 - >>> o.geturl() - 'http://www.cwi.nl:80/%7Eguido/Python.html' + >>> o._replace(fragment="").geturl() + 'http://docs.python.org:80/3/library/urllib.parse.html?highlight=params' Following the syntax specifications in :rfc:`1808`, urlparse recognizes a netloc only if it is properly introduced by '//'. Otherwise the @@ -92,31 +104,31 @@ or on combining URL components into a URL string. The return value is a :term:`named tuple`, which means that its items can be accessed by index or as named attributes, which are: - +------------------+-------+--------------------------+----------------------+ - | Attribute | Index | Value | Value if not present | - +==================+=======+==========================+======================+ - | :attr:`scheme` | 0 | URL scheme specifier | *scheme* parameter | - +------------------+-------+--------------------------+----------------------+ - | :attr:`netloc` | 1 | Network location part | empty string | - +------------------+-------+--------------------------+----------------------+ - | :attr:`path` | 2 | Hierarchical path | empty string | - +------------------+-------+--------------------------+----------------------+ - | :attr:`params` | 3 | Parameters for last path | empty string | - | | | element | | - +------------------+-------+--------------------------+----------------------+ - | :attr:`query` | 4 | Query component | empty string | - +------------------+-------+--------------------------+----------------------+ - | :attr:`fragment` | 5 | Fragment identifier | empty string | - +------------------+-------+--------------------------+----------------------+ - | :attr:`username` | | User name | :const:`None` | - +------------------+-------+--------------------------+----------------------+ - | :attr:`password` | | Password | :const:`None` | - +------------------+-------+--------------------------+----------------------+ - | :attr:`hostname` | | Host name (lower case) | :const:`None` | - +------------------+-------+--------------------------+----------------------+ - | :attr:`port` | | Port number as integer, | :const:`None` | - | | | if present | | - +------------------+-------+--------------------------+----------------------+ + +------------------+-------+-------------------------+------------------------+ + | Attribute | Index | Value | Value if not present | + +==================+=======+=========================+========================+ + | :attr:`scheme` | 0 | URL scheme specifier | *scheme* parameter | + +------------------+-------+-------------------------+------------------------+ + | :attr:`netloc` | 1 | Network location part | empty string | + +------------------+-------+-------------------------+------------------------+ + | :attr:`path` | 2 | Hierarchical path | empty string | + +------------------+-------+-------------------------+------------------------+ + | :attr:`params` | 3 | Parameters for last | empty string | + | | | path element | | + +------------------+-------+-------------------------+------------------------+ + | :attr:`query` | 4 | Query component | empty string | + +------------------+-------+-------------------------+------------------------+ + | :attr:`fragment` | 5 | Fragment identifier | empty string | + +------------------+-------+-------------------------+------------------------+ + | :attr:`username` | | User name | :const:`None` | + +------------------+-------+-------------------------+------------------------+ + | :attr:`password` | | Password | :const:`None` | + +------------------+-------+-------------------------+------------------------+ + | :attr:`hostname` | | Host name (lower case) | :const:`None` | + +------------------+-------+-------------------------+------------------------+ + | :attr:`port` | | Port number as integer, | :const:`None` | + | | | if present | | + +------------------+-------+-------------------------+------------------------+ Reading the :attr:`port` attribute will raise a :exc:`ValueError` if an invalid port is specified in the URL. See section diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 88e93ba6b00..59e1f2da828 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -21,6 +21,7 @@ authentication, redirections, cookies and more. The `Requests package `_ is recommended for a higher-level HTTP client interface. +.. include:: ../includes/wasm-notavail.rst The :mod:`urllib.request` module defines the following functions: @@ -218,6 +219,7 @@ The following classes are provided: (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"``, while :mod:`urllib`'s default user agent string is ``"Python-urllib/2.6"`` (on Python 2.6). + All header keys are sent in camel case. An appropriate ``Content-Type`` header should be included if the *data* argument is present. If this header has not been provided and *data* @@ -546,7 +548,8 @@ request. name, and later calls will overwrite previous calls in case the *key* collides. Currently, this is no loss of HTTP functionality, since all headers which have meaning when used more than once have a (header-specific) way of gaining the - same functionality using only one header. + same functionality using only one header. Note that headers added using + this method are also added to redirected requests. .. method:: Request.add_unredirected_header(key, header) @@ -737,7 +740,7 @@ The following attribute and methods should only be used by classes derived from This method, if implemented, will be called by the parent :class:`OpenerDirector`. It should return a file-like object as described in - the return value of the :meth:`open` of :class:`OpenerDirector`, or ``None``. + the return value of the :meth:`~OpenerDirector.open` method of :class:`OpenerDirector`, or ``None``. It should raise :exc:`~urllib.error.URLError`, unless a truly exceptional thing happens (for example, :exc:`MemoryError` should not be mapped to :exc:`URLError`). @@ -1277,7 +1280,7 @@ involved. For example, the :envvar:`http_proxy` environment variable is read to obtain the HTTP proxy's URL. This example replaces the default :class:`ProxyHandler` with one that uses -programmatically-supplied proxy URLs, and adds proxy authorization support with +programmatically supplied proxy URLs, and adds proxy authorization support with :class:`ProxyBasicAuthHandler`. :: proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'}) diff --git a/Doc/library/uu.rst b/Doc/library/uu.rst index 0bc8021e1bd..83c4aec47bb 100644 --- a/Doc/library/uu.rst +++ b/Doc/library/uu.rst @@ -3,11 +3,17 @@ .. module:: uu :synopsis: Encode and decode files in uuencode format. + :deprecated: .. moduleauthor:: Lance Ellinghouse **Source code:** :source:`Lib/uu.py` +.. deprecated-removed:: 3.11 3.13 + The :mod:`uu` module is deprecated + (see :pep:`PEP 594 <594#uu-and-the-uu-encoding>` for details). + :mod:`base64` is a modern alternative. + -------------- This module encodes and decodes files in uuencode format, allowing arbitrary diff --git a/Doc/library/uuid.rst b/Doc/library/uuid.rst index 415e25bef6d..38b6434f467 100644 --- a/Doc/library/uuid.rst +++ b/Doc/library/uuid.rst @@ -118,7 +118,7 @@ which relays any information about the UUID's safety, using this enumeration: .. attribute:: UUID.hex - The UUID as a 32-character hexadecimal string. + The UUID as a 32-character lowercase hexadecimal string. .. attribute:: UUID.int @@ -211,7 +211,7 @@ The :mod:`uuid` module defines the following namespace identifiers for use with .. data:: NAMESPACE_DNS - When this namespace is specified, the *name* string is a fully-qualified domain + When this namespace is specified, the *name* string is a fully qualified domain name. @@ -261,6 +261,47 @@ of the :attr:`variant` attribute: internal format of UUIDs, and methods of generating UUIDs. +.. _uuid-cli: + +Command-Line Usage +------------------ + +.. versionadded:: 3.12 + +The :mod:`uuid` module can be executed as a script from the command line. + +.. code-block:: sh + + python -m uuid [-h] [-u {uuid1,uuid3,uuid4,uuid5}] [-n NAMESPACE] [-N NAME] + +The following options are accepted: + +.. program:: uuid + +.. cmdoption:: -h, --help + + Show the help message and exit. + +.. cmdoption:: -u + --uuid + + Specify the function name to use to generate the uuid. By default :func:`uuid4` + is used. + +.. cmdoption:: -n + --namespace + + The namespace is a ``UUID``, or ``@ns`` where ``ns`` is a well-known predefined UUID + addressed by namespace name. Such as ``@dns``, ``@url``, ``@oid``, and ``@x500``. + Only required for :func:`uuid3` / :func:`uuid5` functions. + +.. cmdoption:: -N + --name + + The name used as part of generating the uuid. Only required for + :func:`uuid3` / :func:`uuid5` functions. + + .. _uuid-example: Example @@ -301,3 +342,22 @@ Here are some examples of typical usage of the :mod:`uuid` module:: >>> uuid.UUID(bytes=x.bytes) UUID('00010203-0405-0607-0809-0a0b0c0d0e0f') + +.. _uuid-cli-example: + +Command-Line Example +-------------------- + +Here are some examples of typical usage of the :mod:`uuid` command line interface: + +.. code-block:: shell + + # generate a random uuid - by default uuid4() is used + $ python -m uuid + + # generate a uuid using uuid1() + $ python -m uuid -u uuid1 + + # generate a uuid using uuid5 + $ python -m uuid -u uuid5 -n @url -N example.com + diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index 092781b5ff1..2a41096de00 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -15,74 +15,119 @@ -------------- -The :mod:`venv` module provides support for creating lightweight "virtual -environments" with their own site directories, optionally isolated from system -site directories. Each virtual environment has its own Python binary (which -matches the version of the binary that was used to create this environment) and -can have its own independent set of installed Python packages in its site -directories. +.. _venv-def: +.. _venv-intro: -See :pep:`405` for more information about Python virtual environments. +The :mod:`!venv` module supports creating lightweight "virtual environments", +each with their own independent set of Python packages installed in +their :mod:`site` directories. +A virtual environment is created on top of an existing +Python installation, known as the virtual environment's "base" Python, and may +optionally be isolated from the packages in the base environment, +so only those explicitly installed in the virtual environment are available. + +When used from within a virtual environment, common installation tools such as +`pip`_ will install Python packages into a virtual environment +without needing to be told to do so explicitly. + +See :pep:`405` for more background on Python virtual environments. .. seealso:: `Python Packaging User Guide: Creating and using virtual environments `__ +.. include:: ../includes/wasm-notavail.rst Creating virtual environments ----------------------------- .. include:: /using/venv-create.inc +.. _venv-explanation: -.. _venv-def: +How venvs work +-------------- -.. note:: A virtual environment is a Python environment such that the Python - interpreter, libraries and scripts installed into it are isolated from those - installed in other virtual environments, and (by default) any libraries - installed in a "system" Python, i.e., one which is installed as part of your - operating system. +When a Python interpreter is running from a virtual environment, +:data:`sys.prefix` and :data:`sys.exec_prefix` +point to the directories of the virtual environment, +whereas :data:`sys.base_prefix` and :data:`sys.base_exec_prefix` +point to those of the base Python used to create the environment. +It is sufficient to check +``sys.prefix == sys.base_prefix`` to determine if the current interpreter is +running from a virtual environment. - A virtual environment is a directory tree which contains Python executable - files and other files which indicate that it is a virtual environment. +A virtual environment may be "activated" using a script in its binary directory +(``bin`` on POSIX; ``Scripts`` on Windows). +This will prepend that directory to your :envvar:`!PATH`, so that running +:program:`!python` will invoke the environment's Python interpreter +and you can run installed scripts without having to use their full path. +The invocation of the activation script is platform-specific +(:samp:`{}` must be replaced by the path to the directory +containing the virtual environment): - Common installation tools such as setuptools_ and pip_ work as - expected with virtual environments. In other words, when a virtual - environment is active, they install Python packages into the virtual - environment without needing to be told to do so explicitly. ++-------------+------------+--------------------------------------------------+ +| Platform | Shell | Command to activate virtual environment | ++=============+============+==================================================+ +| POSIX | bash/zsh | :samp:`$ source {}/bin/activate` | +| +------------+--------------------------------------------------+ +| | fish | :samp:`$ source {}/bin/activate.fish` | +| +------------+--------------------------------------------------+ +| | csh/tcsh | :samp:`$ source {}/bin/activate.csh` | +| +------------+--------------------------------------------------+ +| | PowerShell | :samp:`$ {}/bin/Activate.ps1` | ++-------------+------------+--------------------------------------------------+ +| Windows | cmd.exe | :samp:`C:\\> {}\\Scripts\\activate.bat` | +| +------------+--------------------------------------------------+ +| | PowerShell | :samp:`PS C:\\> {}\\Scripts\\Activate.ps1` | ++-------------+------------+--------------------------------------------------+ - When a virtual environment is active (i.e., the virtual environment's Python - interpreter is running), the attributes :attr:`sys.prefix` and - :attr:`sys.exec_prefix` point to the base directory of the virtual - environment, whereas :attr:`sys.base_prefix` and - :attr:`sys.base_exec_prefix` point to the non-virtual environment Python - installation which was used to create the virtual environment. If a virtual - environment is not active, then :attr:`sys.prefix` is the same as - :attr:`sys.base_prefix` and :attr:`sys.exec_prefix` is the same as - :attr:`sys.base_exec_prefix` (they all point to a non-virtual environment - Python installation). +.. versionadded:: 3.4 + :program:`!fish` and :program:`!csh` activation scripts. - When a virtual environment is active, any options that change the - installation path will be ignored from all :mod:`distutils` configuration - files to prevent projects being inadvertently installed outside of the - virtual environment. +.. versionadded:: 3.8 + PowerShell activation scripts installed under POSIX for PowerShell Core + support. - When working in a command shell, users can make a virtual environment active - by running an ``activate`` script in the virtual environment's executables - directory (the precise filename and command to use the file is - shell-dependent), which prepends the virtual environment's directory for - executables to the ``PATH`` environment variable for the running shell. There - should be no need in other circumstances to activate a virtual - environment; scripts installed into virtual environments have a "shebang" - line which points to the virtual environment's Python interpreter. This means - that the script will run with that interpreter regardless of the value of - ``PATH``. On Windows, "shebang" line processing is supported if you have the - Python Launcher for Windows installed (this was added to Python in 3.3 - see - :pep:`397` for more details). Thus, double-clicking an installed script in a - Windows Explorer window should run the script with the correct interpreter - without there needing to be any reference to its virtual environment in - ``PATH``. +You don't specifically *need* to activate a virtual environment, +as you can just specify the full path to that environment's +Python interpreter when invoking Python. +Furthermore, all scripts installed in the environment +should be runnable without activating it. + +In order to achieve this, scripts installed into virtual environments have +a "shebang" line which points to the environment's Python interpreter, +i.e. :samp:`#!/{}/bin/python`. +This means that the script will run with that interpreter regardless of the +value of :envvar:`!PATH`. On Windows, "shebang" line processing is supported if +you have the :ref:`launcher` installed. Thus, double-clicking an installed +script in a Windows Explorer window should run it with the correct interpreter +without the environment needing to be activated or on the :envvar:`!PATH`. + +When a virtual environment has been activated, the :envvar:`!VIRTUAL_ENV` +environment variable is set to the path of the environment. +Since explicitly activating a virtual environment is not required to use it, +:envvar:`!VIRTUAL_ENV` cannot be relied upon to determine +whether a virtual environment is being used. + +.. warning:: Because scripts installed in environments should not expect the + environment to be activated, their shebang lines contain the absolute paths + to their environment's interpreters. Because of this, environments are + inherently non-portable, in the general case. You should always have a + simple means of recreating an environment (for example, if you have a + requirements file ``requirements.txt``, you can invoke ``pip install -r + requirements.txt`` using the environment's ``pip`` to install all of the + packages needed by the environment). If for any reason you need to move the + environment to a new location, you should recreate it at the desired + location and delete the one at the old location. If you move an environment + because you moved a parent directory of it, you should recreate the + environment in its new location. Otherwise, software installed into the + environment may not work as expected. + +You can deactivate a virtual environment by typing ``deactivate`` in your shell. +The exact mechanism is platform-specific and is an internal implementation +detail (typically, a script or shell function will be used). .. _venv-api: @@ -177,6 +222,50 @@ creation according to their needs, the :class:`EnvBuilder` class. ``clear=True``, contents of the environment directory will be cleared and then all necessary subdirectories will be recreated. + The returned context object is a :class:`types.SimpleNamespace` with the + following attributes: + + * ``env_dir`` - The location of the virtual environment. Used for + ``__VENV_DIR__`` in activation scripts (see :meth:`install_scripts`). + + * ``env_name`` - The name of the virtual environment. Used for + ``__VENV_NAME__`` in activation scripts (see :meth:`install_scripts`). + + * ``prompt`` - The prompt to be used by the activation scripts. Used for + ``__VENV_PROMPT__`` in activation scripts (see :meth:`install_scripts`). + + * ``executable`` - The underlying Python executable used by the virtual + environment. This takes into account the case where a virtual environment + is created from another virtual environment. + + * ``inc_path`` - The include path for the virtual environment. + + * ``lib_path`` - The purelib path for the virtual environment. + + * ``bin_path`` - The script path for the virtual environment. + + * ``bin_name`` - The name of the script path relative to the virtual + environment location. Used for ``__VENV_BIN_NAME__`` in activation + scripts (see :meth:`install_scripts`). + + * ``env_exe`` - The name of the Python interpreter in the virtual + environment. Used for ``__VENV_PYTHON__`` in activation scripts + (see :meth:`install_scripts`). + + * ``env_exec_cmd`` - The name of the Python interpreter, taking into + account filesystem redirections. This can be used to run Python in + the virtual environment. + + + .. versionchanged:: 3.12 + The attribute ``lib_path`` was added to the context, and the context + object was documented. + + .. versionchanged:: 3.11 + The *venv* + :ref:`sysconfig installation scheme ` + is used to construct the paths of the created directories. + .. method:: create_configuration(context) Creates the ``pyvenv.cfg`` configuration file in the environment. @@ -408,76 +497,68 @@ subclass which installs setuptools and pip into a created virtual environment:: url = 'https://bootstrap.pypa.io/get-pip.py' self.install_script(context, 'pip', url) - def main(args=None): - compatible = True - if sys.version_info < (3, 3): - compatible = False - elif not hasattr(sys, 'base_prefix'): - compatible = False - if not compatible: - raise ValueError('This script is only for use with ' - 'Python 3.3 or later') - else: - import argparse - parser = argparse.ArgumentParser(prog=__name__, - description='Creates virtual Python ' - 'environments in one or ' - 'more target ' - 'directories.') - parser.add_argument('dirs', metavar='ENV_DIR', nargs='+', - help='A directory in which to create the ' - 'virtual environment.') - parser.add_argument('--no-setuptools', default=False, - action='store_true', dest='nodist', - help="Don't install setuptools or pip in the " - "virtual environment.") - parser.add_argument('--no-pip', default=False, - action='store_true', dest='nopip', - help="Don't install pip in the virtual " - "environment.") - parser.add_argument('--system-site-packages', default=False, - action='store_true', dest='system_site', - help='Give the virtual environment access to the ' - 'system site-packages dir.') - if os.name == 'nt': - use_symlinks = False - else: - use_symlinks = True - parser.add_argument('--symlinks', default=use_symlinks, - action='store_true', dest='symlinks', - help='Try to use symlinks rather than copies, ' - 'when symlinks are not the default for ' - 'the platform.') - parser.add_argument('--clear', default=False, action='store_true', - dest='clear', help='Delete the contents of the ' - 'virtual environment ' - 'directory if it already ' - 'exists, before virtual ' - 'environment creation.') - parser.add_argument('--upgrade', default=False, action='store_true', - dest='upgrade', help='Upgrade the virtual ' - 'environment directory to ' - 'use this version of ' - 'Python, assuming Python ' - 'has been upgraded ' - 'in-place.') - parser.add_argument('--verbose', default=False, action='store_true', - dest='verbose', help='Display the output ' - 'from the scripts which ' - 'install setuptools and pip.') - options = parser.parse_args(args) - if options.upgrade and options.clear: - raise ValueError('you cannot supply --upgrade and --clear together.') - builder = ExtendedEnvBuilder(system_site_packages=options.system_site, - clear=options.clear, - symlinks=options.symlinks, - upgrade=options.upgrade, - nodist=options.nodist, - nopip=options.nopip, - verbose=options.verbose) - for d in options.dirs: - builder.create(d) + def main(args=None): + import argparse + + parser = argparse.ArgumentParser(prog=__name__, + description='Creates virtual Python ' + 'environments in one or ' + 'more target ' + 'directories.') + parser.add_argument('dirs', metavar='ENV_DIR', nargs='+', + help='A directory in which to create the ' + 'virtual environment.') + parser.add_argument('--no-setuptools', default=False, + action='store_true', dest='nodist', + help="Don't install setuptools or pip in the " + "virtual environment.") + parser.add_argument('--no-pip', default=False, + action='store_true', dest='nopip', + help="Don't install pip in the virtual " + "environment.") + parser.add_argument('--system-site-packages', default=False, + action='store_true', dest='system_site', + help='Give the virtual environment access to the ' + 'system site-packages dir.') + if os.name == 'nt': + use_symlinks = False + else: + use_symlinks = True + parser.add_argument('--symlinks', default=use_symlinks, + action='store_true', dest='symlinks', + help='Try to use symlinks rather than copies, ' + 'when symlinks are not the default for ' + 'the platform.') + parser.add_argument('--clear', default=False, action='store_true', + dest='clear', help='Delete the contents of the ' + 'virtual environment ' + 'directory if it already ' + 'exists, before virtual ' + 'environment creation.') + parser.add_argument('--upgrade', default=False, action='store_true', + dest='upgrade', help='Upgrade the virtual ' + 'environment directory to ' + 'use this version of ' + 'Python, assuming Python ' + 'has been upgraded ' + 'in-place.') + parser.add_argument('--verbose', default=False, action='store_true', + dest='verbose', help='Display the output ' + 'from the scripts which ' + 'install setuptools and pip.') + options = parser.parse_args(args) + if options.upgrade and options.clear: + raise ValueError('you cannot supply --upgrade and --clear together.') + builder = ExtendedEnvBuilder(system_site_packages=options.system_site, + clear=options.clear, + symlinks=options.symlinks, + upgrade=options.upgrade, + nodist=options.nodist, + nopip=options.nopip, + verbose=options.verbose) + for d in options.dirs: + builder.create(d) if __name__ == '__main__': rc = 1 diff --git a/Doc/library/warnings.rst b/Doc/library/warnings.rst index fe11aabbcbd..884de08eab1 100644 --- a/Doc/library/warnings.rst +++ b/Doc/library/warnings.rst @@ -105,7 +105,7 @@ The following warnings category classes are currently defined: | | :class:`bytes` and :class:`bytearray`. | +----------------------------------+-----------------------------------------------+ | :exc:`ResourceWarning` | Base category for warnings related to | -| | resource usage. | +| | resource usage (ignored by default). | +----------------------------------+-----------------------------------------------+ .. versionchanged:: 3.7 @@ -154,14 +154,19 @@ the disposition of the match. Each entry is a tuple of the form (*action*, +---------------+----------------------------------------------+ * *message* is a string containing a regular expression that the start of - the warning message must match. The expression is compiled to always be - case-insensitive. + the warning message must match, case-insensitively. In :option:`-W` and + :envvar:`PYTHONWARNINGS`, *message* is a literal string that the start of the + warning message must contain (case-insensitively), ignoring any whitespace at + the start or end of *message*. * *category* is a class (a subclass of :exc:`Warning`) of which the warning category must be a subclass in order to match. -* *module* is a string containing a regular expression that the module name must - match. The expression is compiled to be case-sensitive. +* *module* is a string containing a regular expression that the start of the + fully qualified module name must match, case-sensitively. In :option:`-W` and + :envvar:`PYTHONWARNINGS`, *module* is a literal string that the + fully qualified module name must be equal to (case-sensitively), ignoring any + whitespace at the start or end of *module*. * *lineno* is an integer that the line number where the warning occurred must match, or ``0`` to match all line numbers. @@ -207,8 +212,7 @@ Some examples:: error::ResourceWarning # Treat ResourceWarning messages as errors default::DeprecationWarning # Show DeprecationWarning messages ignore,default:::mymodule # Only report warnings triggered by "mymodule" - error:::mymodule[.*] # Convert warnings to errors in "mymodule" - # and any subpackages of "mymodule" + error:::mymodule # Convert warnings to errors in "mymodule" .. _default-warning-filter: @@ -392,7 +396,7 @@ Available Functions ------------------- -.. function:: warn(message, category=None, stacklevel=1, source=None) +.. function:: warn(message, category=None, stacklevel=1, source=None, \*, skip_file_prefixes=None) Issue a warning, or maybe ignore it or raise an exception. The *category* argument, if given, must be a :ref:`warning category class `; it @@ -403,12 +407,39 @@ Available Functions :ref:`warnings filter `. The *stacklevel* argument can be used by wrapper functions written in Python, like this:: - def deprecation(message): + def deprecated_api(message): warnings.warn(message, DeprecationWarning, stacklevel=2) - This makes the warning refer to :func:`deprecation`'s caller, rather than to the - source of :func:`deprecation` itself (since the latter would defeat the purpose - of the warning message). + This makes the warning refer to ``deprecated_api``'s caller, rather than to + the source of ``deprecated_api`` itself (since the latter would defeat the + purpose of the warning message). + + The *skip_file_prefixes* keyword argument can be used to indicate which + stack frames are ignored when counting stack levels. This can be useful when + you want the warning to always appear at call sites outside of a package + when a constant *stacklevel* does not fit all call paths or is otherwise + challenging to maintain. If supplied, it must be a tuple of strings. When + prefixes are supplied, stacklevel is implicitly overridden to be ``max(2, + stacklevel)``. To cause a warning to be attributed to the caller from + outside of the current package you might write:: + + # example/lower.py + _warn_skips = (os.path.dirname(__file__),) + + def one_way(r_luxury_yacht=None, t_wobbler_mangrove=None): + if r_luxury_yacht: + warnings.warn("Please migrate to t_wobbler_mangrove=.", + skip_file_prefixes=_warn_skips) + + # example/higher.py + from . import lower + + def another_way(**kw): + lower.one_way(**kw) + + This makes the warning refer to both the ``example.lower.one_way()`` and + ``package.higher.another_way()`` call sites only from calling code living + outside of ``example`` package. *source*, if supplied, is the destroyed object which emitted a :exc:`ResourceWarning`. @@ -416,6 +447,9 @@ Available Functions .. versionchanged:: 3.6 Added *source* parameter. + .. versionchanged:: 3.12 + Added *skip_file_prefixes*. + .. function:: warn_explicit(message, category, filename, lineno, module=None, registry=None, module_globals=None, source=None) @@ -491,7 +525,7 @@ Available Functions Available Context Managers -------------------------- -.. class:: catch_warnings(*, record=False, module=None) +.. class:: catch_warnings(*, record=False, module=None, action=None, category=Warning, lineno=0, append=False) A context manager that copies and, upon exit, restores the warnings filter and the :func:`showwarning` function. @@ -507,6 +541,10 @@ Available Context Managers protected. This argument exists primarily for testing the :mod:`warnings` module itself. + If the *action* argument is not ``None``, the remaining arguments are + passed to :func:`simplefilter` as if it were called immediately on + entering the context. + .. note:: The :class:`catch_warnings` manager works by replacing and @@ -514,3 +552,7 @@ Available Context Managers :func:`showwarning` function and internal list of filter specifications. This means the context manager is modifying global state and therefore is not thread-safe. + + .. versionchanged:: 3.11 + + Added the *action*, *category*, *lineno*, and *append* parameters. diff --git a/Doc/library/wave.rst b/Doc/library/wave.rst index f63e0d3dce1..04a28d97d61 100644 --- a/Doc/library/wave.rst +++ b/Doc/library/wave.rst @@ -12,7 +12,12 @@ -------------- The :mod:`wave` module provides a convenient interface to the WAV sound format. -It does not support compression/decompression, but it does support mono/stereo. +Only PCM encoded wave files are supported. + +.. versionchanged:: 3.12 + + Support for ``WAVE_FORMAT_EXTENSIBLE`` headers was added, provided that the + extended format is ``KSDATAFORMAT_SUBTYPE_PCM``. The :mod:`wave` module defines the following function and exception: diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index 1102c634eda..1406b663c6a 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -1,3 +1,5 @@ +.. _mod-weakref: + :mod:`weakref` --- Weak references ================================== @@ -141,9 +143,12 @@ See :ref:`__slots__ documentation ` for details. ``ProxyType`` or ``CallableProxyType``, depending on whether *object* is callable. Proxy objects are not :term:`hashable` regardless of the referent; this avoids a number of problems related to their fundamentally mutable nature, and - prevent their use as dictionary keys. *callback* is the same as the parameter + prevents their use as dictionary keys. *callback* is the same as the parameter of the same name to the :func:`ref` function. + Accessing an attribute of the proxy object after the referent is + garbage collected raises :exc:`ReferenceError`. + .. versionchanged:: 3.8 Extended the operator support on proxy objects to include the matrix multiplication operators ``@`` and ``@=``. @@ -167,6 +172,30 @@ See :ref:`__slots__ documentation ` for details. application without adding attributes to those objects. This can be especially useful with objects that override attribute accesses. + Note that when a key with equal value to an existing key (but not equal identity) + is inserted into the dictionary, it replaces the value but does not replace the + existing key. Due to this, when the reference to the original key is deleted, it + also deletes the entry in the dictionary:: + + >>> class T(str): pass + ... + >>> k1, k2 = T(), T() + >>> d = weakref.WeakKeyDictionary() + >>> d[k1] = 1 # d = {k1: 1} + >>> d[k2] = 2 # d = {k1: 2} + >>> del k1 # d = {} + + A workaround would be to remove the key prior to reassignment:: + + >>> class T(str): pass + ... + >>> k1, k2 = T(), T() + >>> d = weakref.WeakKeyDictionary() + >>> d[k1] = 1 # d = {k1: 1} + >>> del d[k1] + >>> d[k2] = 2 # d = {k2: 2} + >>> del k1 # d = {k2: 2} + .. versionchanged:: 3.9 Added support for ``|`` and ``|=`` operators, specified in :pep:`584`. @@ -207,7 +236,7 @@ objects. discarded when no strong reference to it exists any more. -.. class:: WeakMethod(method) +.. class:: WeakMethod(method[, callback]) A custom :class:`ref` subclass which simulates a weak reference to a bound method (i.e., a method defined on a class and looked up on an instance). @@ -233,6 +262,8 @@ objects. >>> r() >>> + *callback* is the same as the parameter of the same name to the :func:`ref` function. + .. versionadded:: 3.4 .. class:: finalize(obj, func, /, *args, **kwargs) diff --git a/Doc/library/webbrowser.rst b/Doc/library/webbrowser.rst index 19b3c463bb8..734b6321e5a 100644 --- a/Doc/library/webbrowser.rst +++ b/Doc/library/webbrowser.rst @@ -41,6 +41,8 @@ naturally, mutually exclusive. Usage example:: python -m webbrowser -t "https://www.python.org" +.. include:: ../includes/wasm-notavail.rst + The following exception is defined: @@ -197,6 +199,11 @@ Browser controllers provide these methods which parallel three of the module-level convenience functions: +.. attribute:: name + + System-dependent name for the browser. + + .. method:: controller.open(url, new=0, autoraise=True) Display *url* using the browser handled by this controller. If *new* is 1, a new diff --git a/Doc/library/windows.rst b/Doc/library/windows.rst index b60d4e4ccf5..4d72ead12aa 100644 --- a/Doc/library/windows.rst +++ b/Doc/library/windows.rst @@ -9,7 +9,6 @@ This chapter describes modules that are only available on MS Windows platforms. .. toctree:: - msilib.rst msvcrt.rst winreg.rst winsound.rst diff --git a/Doc/library/winreg.rst b/Doc/library/winreg.rst index 487856a3ac6..4ab67181771 100644 --- a/Doc/library/winreg.rst +++ b/Doc/library/winreg.rst @@ -144,12 +144,6 @@ This module offers the following functions: Deletes the specified key. - .. note:: - The :func:`DeleteKeyEx` function is implemented with the RegDeleteKeyEx - Windows API function, which is specific to 64-bit versions of Windows. - See the `RegDeleteKeyEx documentation - `__. - *key* is an already open key, or one of the predefined :ref:`HKEY_* constants `. @@ -159,9 +153,10 @@ This module offers the following functions: *reserved* is a reserved integer, and must be zero. The default is zero. - *access* is an integer that specifies an access mask that describes the desired - security access for the key. Default is :const:`KEY_WOW64_64KEY`. See - :ref:`Access Rights ` for other allowed values. + *access* is an integer that specifies an access mask that describes the + desired security access for the key. Default is :const:`KEY_WOW64_64KEY`. + On 32-bit Windows, the WOW64 constants are ignored. + See :ref:`Access Rights ` for other allowed values. *This method can not delete keys with subkeys.* @@ -658,13 +653,12 @@ For more information, see `Accessing an Alternate Registry View .. data:: KEY_WOW64_64KEY Indicates that an application on 64-bit Windows should operate on - the 64-bit registry view. + the 64-bit registry view. On 32-bit Windows, this constant is ignored. .. data:: KEY_WOW64_32KEY Indicates that an application on 64-bit Windows should operate on - the 32-bit registry view. - + the 32-bit registry view. On 32-bit Windows, this constant is ignored. .. _value-types: diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index e924448b86d..75dea466335 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -7,6 +7,8 @@ .. moduleauthor:: Phillip J. Eby .. sectionauthor:: Phillip J. Eby +**Source code:** :source:`Lib/wsgiref` + -------------- The Web Server Gateway Interface (WSGI) is a standard interface between web @@ -23,6 +25,7 @@ an existing framework. be used to add WSGI support to a web server or framework. It provides utilities for manipulating WSGI environment variables and response headers, base classes for implementing WSGI servers, a demo HTTP server that serves WSGI applications, +types for static type checking, and a validation tool that checks WSGI servers and applications for conformance to the WSGI specification (:pep:`3333`). @@ -43,7 +46,9 @@ This module provides a variety of utility functions for working with WSGI environments. A WSGI environment is a dictionary containing HTTP request variables as described in :pep:`3333`. All of the functions taking an *environ* parameter expect a WSGI-compliant dictionary to be supplied; please see -:pep:`3333` for a detailed specification. +:pep:`3333` for a detailed specification and +:data:`~wsgiref.types.WSGIEnvironment` for a type alias that can be used +in type annotations. .. function:: guess_scheme(environ) @@ -150,7 +155,9 @@ also provides these miscellaneous utilities: .. class:: FileWrapper(filelike, blksize=8192) - A wrapper to convert a file-like object to an :term:`iterator`. The resulting objects + A concrete implementation of the :class:`wsgiref.types.FileWrapper` + protocol used to convert a file-like object to an :term:`iterator`. + The resulting objects are :term:`iterable`\ s. As the object is iterated over, the optional *blksize* parameter will be repeatedly passed to the *filelike* object's :meth:`read` method to obtain bytestrings to yield. When :meth:`read` @@ -328,7 +335,7 @@ request. (E.g., using the :func:`shift_path_info` function from .. method:: WSGIServer.get_app() - Returns the currently-set application callable. + Returns the currently set application callable. Normally, however, you do not need to use these additional methods, as :meth:`set_app` is normally called by :func:`make_server`, and the @@ -349,7 +356,8 @@ request. (E.g., using the :func:`shift_path_info` function from .. method:: WSGIRequestHandler.get_environ() - Returns a dictionary containing the WSGI environment for a request. The default + Return a :data:`~wsgiref.types.WSGIEnvironment` dictionary for a + request. The default implementation copies the contents of the :class:`WSGIServer` object's :attr:`base_environ` dictionary attribute and then adds various headers derived from the HTTP request. Each call to this method should return a new dictionary @@ -558,13 +566,15 @@ input, output, and error streams. .. method:: BaseHandler.get_stdin() - Return an input stream object suitable for use as the ``wsgi.input`` of the + Return an object compatible with :class:`~wsgiref.types.InputStream` + suitable for use as the ``wsgi.input`` of the request currently being processed. .. method:: BaseHandler.get_stderr() - Return an output stream object suitable for use as the ``wsgi.errors`` of the + Return an object compatible with :class:`~wsgiref.types.ErrorStream` + suitable for use as the ``wsgi.errors`` of the request currently being processed. @@ -634,7 +644,7 @@ input, output, and error streams. .. method:: BaseHandler.setup_environ() - Set the :attr:`environ` attribute to a fully-populated WSGI environment. The + Set the :attr:`environ` attribute to a fully populated WSGI environment. The default implementation uses all of the above methods and attributes, plus the :meth:`get_stdin`, :meth:`get_stderr`, and :meth:`add_cgi_vars` methods and the :attr:`wsgi_file_wrapper` attribute. It also inserts a ``SERVER_SOFTWARE`` key @@ -703,8 +713,9 @@ input, output, and error streams. .. attribute:: BaseHandler.wsgi_file_wrapper - A ``wsgi.file_wrapper`` factory, or ``None``. The default value of this - attribute is the :class:`wsgiref.util.FileWrapper` class. + A ``wsgi.file_wrapper`` factory, compatible with + :class:`wsgiref.types.FileWrapper`, or ``None``. The default value + of this attribute is the :class:`wsgiref.util.FileWrapper` class. .. method:: BaseHandler.sendfile() @@ -754,35 +765,126 @@ input, output, and error streams. .. versionadded:: 3.2 +:mod:`wsgiref.types` -- WSGI types for static type checking +----------------------------------------------------------- + +.. module:: wsgiref.types + :synopsis: WSGI types for static type checking + + +This module provides various types for static type checking as described +in :pep:`3333`. + +.. versionadded:: 3.11 + + +.. class:: StartResponse() + + A :class:`typing.Protocol` describing `start_response() + `_ + callables (:pep:`3333`). + +.. data:: WSGIEnvironment + + A type alias describing a WSGI environment dictionary. + +.. data:: WSGIApplication + + A type alias describing a WSGI application callable. + +.. class:: InputStream() + + A :class:`typing.Protocol` describing a `WSGI Input Stream + `_. + +.. class:: ErrorStream() + + A :class:`typing.Protocol` describing a `WSGI Error Stream + `_. + +.. class:: FileWrapper() + + A :class:`typing.Protocol` describing a `file wrapper + `_. + See :class:`wsgiref.util.FileWrapper` for a concrete implementation of this + protocol. + + Examples -------- This is a working "Hello World" WSGI application:: + """ + Every WSGI application must have an application object - a callable + object that accepts two arguments. For that purpose, we're going to + use a function (note that you're not limited to a function, you can + use a class for example). The first argument passed to the function + is a dictionary containing CGI-style environment variables and the + second variable is the callable object. + """ from wsgiref.simple_server import make_server - # Every WSGI application must have an application object - a callable - # object that accepts two arguments. For that purpose, we're going to - # use a function (note that you're not limited to a function, you can - # use a class for example). The first argument passed to the function - # is a dictionary containing CGI-style environment variables and the - # second variable is the callable object. + def hello_world_app(environ, start_response): - status = '200 OK' # HTTP Status - headers = [('Content-type', 'text/plain; charset=utf-8')] # HTTP Headers + status = "200 OK" # HTTP Status + headers = [("Content-type", "text/plain; charset=utf-8")] # HTTP Headers start_response(status, headers) # The returned object is going to be printed return [b"Hello World"] - with make_server('', 8000, hello_world_app) as httpd: + with make_server("", 8000, hello_world_app) as httpd: print("Serving on port 8000...") # Serve until process is killed httpd.serve_forever() -Example of a WSGI application serving the current directory, accept optional -directory and port number (default: 8000) on the command line: -.. literalinclude:: ../../Tools/scripts/serve.py +Example of a WSGI application serving the current directory, accept optional +directory and port number (default: 8000) on the command line:: + + """ + Small wsgiref based web server. Takes a path to serve from and an + optional port number (defaults to 8000), then tries to serve files. + MIME types are guessed from the file names, 404 errors are raised + if the file is not found. + """ + import mimetypes + import os + import sys + from wsgiref import simple_server, util + + + def app(environ, respond): + # Get the file name and MIME type + fn = os.path.join(path, environ["PATH_INFO"][1:]) + if "." not in fn.split(os.path.sep)[-1]: + fn = os.path.join(fn, "index.html") + mime_type = mimetypes.guess_type(fn)[0] + + # Return 200 OK if file exists, otherwise 404 Not Found + if os.path.exists(fn): + respond("200 OK", [("Content-Type", mime_type)]) + return util.FileWrapper(open(fn, "rb")) + else: + respond("404 Not Found", [("Content-Type", "text/plain")]) + return [b"not found"] + + + if __name__ == "__main__": + # Get the path and port from command-line arguments + path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() + port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000 + + # Make and start the server until control-c + httpd = simple_server.make_server("", port, app) + print(f"Serving {path} on port {port}, control-C to stop") + try: + httpd.serve_forever() + except KeyboardInterrupt: + print("Shutting down.") + httpd.server_close() + + diff --git a/Doc/library/xdrlib.rst b/Doc/library/xdrlib.rst index 42a03a46754..39e75573260 100644 --- a/Doc/library/xdrlib.rst +++ b/Doc/library/xdrlib.rst @@ -3,6 +3,7 @@ .. module:: xdrlib :synopsis: Encoders and decoders for the External Data Representation (XDR). + :deprecated: **Source code:** :source:`Lib/xdrlib.py` @@ -10,6 +11,10 @@ single: XDR single: External Data Representation +.. deprecated-removed:: 3.11 3.13 + The :mod:`xdrlib` module is deprecated + (see :pep:`PEP 594 <594#xdrlib>` for details). + -------------- The :mod:`xdrlib` module supports the External Data Representation Standard as diff --git a/Doc/library/xml.dom.minidom.rst b/Doc/library/xml.dom.minidom.rst index 20984b98b17..72a7a98c2ac 100644 --- a/Doc/library/xml.dom.minidom.rst +++ b/Doc/library/xml.dom.minidom.rst @@ -95,7 +95,7 @@ document: the one that holds all others. Here is an example program:: When you are finished with a DOM tree, you may optionally call the :meth:`unlink` method to encourage early cleanup of the now-unneeded objects. :meth:`unlink` is an :mod:`xml.dom.minidom`\ -specific -extension to the DOM API that renders the node and its descendants are +extension to the DOM API that renders the node and its descendants essentially useless. Otherwise, Python's garbage collector will eventually take care of the objects in the tree. @@ -148,8 +148,8 @@ module documentation. This section lists the differences between the API and Similarly, explicitly stating the *standalone* argument causes the standalone document declarations to be added to the prologue of the XML document. - If the value is set to `True`, `standalone="yes"` is added, - otherwise it is set to `"no"`. + If the value is set to ``True``, ``standalone="yes"`` is added, + otherwise it is set to ``"no"``. Not stating the argument will omit the declaration from the document. .. versionchanged:: 3.8 @@ -180,7 +180,7 @@ module documentation. This section lists the differences between the API and .. versionchanged:: 3.9 The *standalone* parameter was added. -.. method:: Node.toprettyxml(indent="\\t", newl="\\n", encoding=None, \ +.. method:: Node.toprettyxml(indent="\t", newl="\n", encoding=None, \ standalone=None) Return a pretty-printed version of the document. *indent* specifies the diff --git a/Doc/library/xml.dom.rst b/Doc/library/xml.dom.rst index 98454e18ff1..b387240a371 100644 --- a/Doc/library/xml.dom.rst +++ b/Doc/library/xml.dom.rst @@ -73,7 +73,7 @@ implementations are free to support the strict mapping from IDL). See section `Document Object Model (DOM) Level 1 Specification `_ The W3C recommendation for the DOM supported by :mod:`xml.dom.minidom`. - `Python Language Mapping Specification `_ + `Python Language Mapping Specification `_ This specifies the mapping from OMG IDL to Python. diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index e3932bc9e65..f9290f528e5 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -826,6 +826,7 @@ Functions ^^^^^^^^^ .. function:: xml.etree.ElementInclude.default_loader( href, parse, encoding=None) + :module: Default loader. This default loader reads an included resource from disk. *href* is a URL. *parse* is for parse mode either "xml" or "text". *encoding* @@ -837,6 +838,7 @@ Functions .. function:: xml.etree.ElementInclude.include( elem, loader=None, base_url=None, \ max_depth=6) + :module: This function expands XInclude directives. *elem* is the root element. *loader* is an optional resource loader. If omitted, it defaults to :func:`default_loader`. @@ -1043,9 +1045,9 @@ Element Objects :meth:`~object.__getitem__`, :meth:`~object.__setitem__`, :meth:`~object.__len__`. - Caution: Elements with no subelements will test as ``False``. This behavior - will change in future versions. Use specific ``len(elem)`` or ``elem is - None`` test instead. :: + Caution: Elements with no subelements will test as ``False``. Testing the + truth value of an Element is deprecated and will raise an exception in + Python 3.14. Use specific ``len(elem)`` or ``elem is None`` test instead.:: element = root.find('foo') @@ -1055,6 +1057,9 @@ Element Objects if element is None: print("element not found") + .. versionchanged:: 3.12 + Testing the truth value of an Element emits :exc:`DeprecationWarning`. + Prior to Python 3.8, the serialisation order of the XML attributes of elements was artificially made predictable by sorting the attributes by their name. Based on the now guaranteed ordering of dicts, this arbitrary @@ -1210,6 +1215,7 @@ Example of changing the attribute "target" of every link in first paragraph:: [, ] >>> for i in links: # Iterates through all found links ... i.attrib["target"] = "blank" + ... >>> tree.write("output.xhtml") .. _elementtree-qname-objects: diff --git a/Doc/library/xml.rst b/Doc/library/xml.rst index e3b35162961..20b0905bb10 100644 --- a/Doc/library/xml.rst +++ b/Doc/library/xml.rst @@ -95,7 +95,7 @@ quadratic blowup entity expansion entity expansion, too. Instead of nested entities it repeats one large entity with a couple of thousand chars over and over again. The attack isn't as efficient as the exponential case but it avoids triggering parser countermeasures - that forbid deeply-nested entities. + that forbid deeply nested entities. external entity expansion Entity declarations can contain more than just text for replacement. They can diff --git a/Doc/library/xml.sax.handler.rst b/Doc/library/xml.sax.handler.rst index 59d0d1b3b01..719ce5ab1bc 100644 --- a/Doc/library/xml.sax.handler.rst +++ b/Doc/library/xml.sax.handler.rst @@ -147,7 +147,7 @@ for the feature and property names. .. data:: property_xml_string | value: ``"http://xml.org/sax/properties/xml-string"`` - | data type: String + | data type: Bytes | description: The literal string of characters that was the source for the current event. | access: read-only diff --git a/Doc/library/xml.sax.utils.rst b/Doc/library/xml.sax.utils.rst index e46fefdf997..ab4606bcf9f 100644 --- a/Doc/library/xml.sax.utils.rst +++ b/Doc/library/xml.sax.utils.rst @@ -25,6 +25,11 @@ or as base classes. replaced with its corresponding value. The characters ``'&'``, ``'<'`` and ``'>'`` are always escaped, even if *entities* is provided. + .. note:: + + This function should only be used to escape characters that + can't be used directly in XML. Do not use this function as a general + string translation function. .. function:: unescape(data, entities={}) diff --git a/Doc/library/xmlrpc.client.rst b/Doc/library/xmlrpc.client.rst index 8d9db53ef1f..bd2c49a6eda 100644 --- a/Doc/library/xmlrpc.client.rst +++ b/Doc/library/xmlrpc.client.rst @@ -32,6 +32,8 @@ between conformable Python objects and XML on the wire. For HTTPS URIs, :mod:`xmlrpc.client` now performs all the necessary certificate and hostname checks by default. +.. include:: ../includes/wasm-notavail.rst + .. class:: ServerProxy(uri, transport=None, encoding=None, verbose=False, \ allow_none=False, use_datetime=False, \ use_builtin_types=False, *, headers=(), context=None) @@ -47,7 +49,7 @@ between conformable Python objects and XML on the wire. The following parameters govern the use of the returned proxy instance. If *allow_none* is true, the Python constant ``None`` will be translated into XML; the default behaviour is for ``None`` to raise a :exc:`TypeError`. This is - a commonly-used extension to the XML-RPC specification, but isn't supported by + a commonly used extension to the XML-RPC specification, but isn't supported by all clients and servers; see `http://ontosys.com/xml-rpc/extensions.php `_ for a description. @@ -58,7 +60,7 @@ between conformable Python objects and XML on the wire. may be passed to calls. The *headers* parameter is an optional sequence of HTTP headers to send with each request, expressed as a sequence of 2-tuples representing the header - name and value. (e.g. `[('Header-Name', 'value')]`). + name and value. (e.g. ``[('Header-Name', 'value')]``). The obsolete *use_datetime* flag is similar to *use_builtin_types* but it applies only to date/time values. @@ -154,16 +156,16 @@ between conformable Python objects and XML on the wire. Added support of unmarshalling additional types used by Apache XML-RPC implementation for numerics: ``i1``, ``i2``, ``i8``, ``biginteger``, ``float`` and ``bigdecimal``. - See http://ws.apache.org/xmlrpc/types.html for a description. + See https://ws.apache.org/xmlrpc/types.html for a description. .. seealso:: - `XML-RPC HOWTO `_ + `XML-RPC HOWTO `_ A good description of XML-RPC operation and client software in several languages. Contains pretty much everything an XML-RPC client developer needs to know. - `XML-RPC Introspection `_ + `XML-RPC Introspection `_ Describes the XML-RPC protocol extension for introspection. `XML-RPC Specification `_ diff --git a/Doc/library/xmlrpc.server.rst b/Doc/library/xmlrpc.server.rst index 7d561e2303f..016369d2b89 100644 --- a/Doc/library/xmlrpc.server.rst +++ b/Doc/library/xmlrpc.server.rst @@ -23,6 +23,7 @@ servers written in Python. Servers can either be free standing, using constructed data. If you need to parse untrusted or unauthenticated data see :ref:`xml-vulnerabilities`. +.. include:: ../includes/wasm-notavail.rst .. class:: SimpleXMLRPCServer(addr, requestHandler=SimpleXMLRPCRequestHandler,\ logRequests=True, allow_none=False, encoding=None,\ @@ -262,7 +263,7 @@ This ExampleService demo can be invoked from the command line:: The client that interacts with the above server is included in -`Lib/xmlrpc/client.py`:: +``Lib/xmlrpc/client.py``:: server = ServerProxy("http://localhost:8000") diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index 9d0d894c05b..1c516723f04 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -139,7 +139,8 @@ ZipFile Objects .. class:: ZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, \ - compresslevel=None, *, strict_timestamps=True) + compresslevel=None, *, strict_timestamps=True, \ + metadata_encoding=None) Open a ZIP file, where *file* can be a path to a file (a string), a file-like object or a :term:`path-like object`. @@ -183,6 +184,10 @@ ZipFile Objects Similar behavior occurs with files newer than 2107-12-31, the timestamp is also set to the limit. + When mode is ``'r'``, *metadata_encoding* may be set to the name of a codec, + which will be used to decode metadata such as the names of members and ZIP + comments. + If the file is created with mode ``'w'``, ``'x'`` or ``'a'`` and then :meth:`closed ` without adding any files to the archive, the appropriate ZIP structures for an empty archive will be written to the file. @@ -194,6 +199,19 @@ ZipFile Objects with ZipFile('spam.zip', 'w') as myzip: myzip.write('eggs.txt') + .. note:: + + *metadata_encoding* is an instance-wide setting for the ZipFile. + It is not currently possible to set this on a per-member basis. + + This attribute is a workaround for legacy implementations which produce + archives with names in the current locale encoding or code page (mostly + on Windows). According to the .ZIP standard, the encoding of metadata + may be specified to be either IBM code page (default) or UTF-8 by a flag + in the archive header. + That flag takes precedence over *metadata_encoding*, which is + a Python-specific extension. + .. versionadded:: 3.2 Added the ability to use :class:`ZipFile` as a context manager. @@ -220,6 +238,10 @@ ZipFile Objects .. versionadded:: 3.8 The *strict_timestamps* keyword-only argument + .. versionchanged:: 3.11 + Added support for specifying member name encoding for reading + metadata in the zipfile's directory and file headers. + .. method:: ZipFile.close() @@ -251,7 +273,8 @@ ZipFile Objects Access a member of the archive as a binary file-like object. *name* can be either the name of a file within the archive or a :class:`ZipInfo` object. The *mode* parameter, if included, must be ``'r'`` (the default) - or ``'w'``. *pwd* is the password used to decrypt encrypted ZIP files. + or ``'w'``. *pwd* is the password used to decrypt encrypted ZIP files as a + :class:`bytes` object. :meth:`~ZipFile.open` is also a context manager and therefore supports the :keyword:`with` statement:: @@ -289,7 +312,7 @@ ZipFile Objects compressed text files in :term:`universal newlines` mode. .. versionchanged:: 3.6 - :meth:`open` can now be used to write files into the archive with the + :meth:`ZipFile.open` can now be used to write files into the archive with the ``mode='w'`` option. .. versionchanged:: 3.6 @@ -303,7 +326,7 @@ ZipFile Objects must be its full name or a :class:`ZipInfo` object. Its file information is extracted as accurately as possible. *path* specifies a different directory to extract to. *member* can be a filename or a :class:`ZipInfo` object. - *pwd* is the password used for encrypted files. + *pwd* is the password used for encrypted files as a :class:`bytes` object. Returns the normalized path created (a directory or new file). @@ -330,7 +353,7 @@ ZipFile Objects Extract all members from the archive to the current working directory. *path* specifies a different directory to extract to. *members* is optional and must be a subset of the list returned by :meth:`namelist`. *pwd* is the password - used for encrypted files. + used for encrypted files as a :class:`bytes` object. .. warning:: @@ -355,16 +378,16 @@ ZipFile Objects .. method:: ZipFile.setpassword(pwd) - Set *pwd* as default password to extract encrypted files. + Set *pwd* (a :class:`bytes` object) as default password to extract encrypted files. .. method:: ZipFile.read(name, pwd=None) Return the bytes of the file *name* in the archive. *name* is the name of the file in the archive, or a :class:`ZipInfo` object. The archive must be open for - read or append. *pwd* is the password used for encrypted files and, if specified, - it will override the default password set with :meth:`setpassword`. Calling - :meth:`read` on a ZipFile that uses a compression method other than + read or append. *pwd* is the password used for encrypted files as a :class:`bytes` + object and, if specified, overrides the default password set with :meth:`setpassword`. + Calling :meth:`read` on a ZipFile that uses a compression method other than :const:`ZIP_STORED`, :const:`ZIP_DEFLATED`, :const:`ZIP_BZIP2` or :const:`ZIP_LZMA` will raise a :exc:`NotImplementedError`. An error will also be raised if the corresponding compression module is not available. @@ -395,6 +418,15 @@ ZipFile Objects given. The archive must be open with mode ``'w'``, ``'x'`` or ``'a'``. + .. note:: + + The ZIP file standard historically did not specify a metadata encoding, + but strongly recommended CP437 (the original IBM PC encoding) for + interoperability. Recent versions allow use of UTF-8 (only). In this + module, UTF-8 will automatically be used to write the member names if + they contain any non-ASCII characters. It is not possible to write + member names in any encoding other than ASCII or UTF-8. + .. note:: Archive names should be relative to the archive root, that is, they should not @@ -447,6 +479,17 @@ ZipFile Objects a closed ZipFile will raise a :exc:`ValueError`. Previously, a :exc:`RuntimeError` was raised. +.. method:: ZipFile.mkdir(zinfo_or_directory, mode=511) + + Create a directory inside the archive. If *zinfo_or_directory* is a string, + a directory is created inside the archive with the mode that is specified in + the *mode* argument. If, however, *zinfo_or_directory* is + a :class:`ZipInfo` instance then the *mode* argument is ignored. + + The archive must be opened with mode ``'w'``, ``'x'`` or ``'a'``. + + .. versionadded:: 3.11 + The following data attributes are also available: @@ -508,6 +551,12 @@ Path objects are traversable using the ``/`` operator or ``joinpath``. Added support for text and binary modes for open. Default mode is now text. + .. versionchanged:: 3.11.2 + The ``encoding`` parameter can be supplied as a positional argument + without causing a :exc:`TypeError`. As it could in 3.9. Code needing to + be compatible with unpatched 3.10 and 3.11 versions must pass all + :class:`io.TextIOWrapper` arguments, ``encoding`` included, as keywords. + .. method:: Path.iterdir() Enumerate the children of the current directory. @@ -553,6 +602,12 @@ Path objects are traversable using the ``/`` operator or ``joinpath``. :class:`io.TextIOWrapper` (except ``buffer``, which is implied by the context). + .. versionchanged:: 3.11.2 + The ``encoding`` parameter can be supplied as a positional argument + without causing a :exc:`TypeError`. As it could in 3.9. Code needing to + be compatible with unpatched 3.10 and 3.11 versions must pass all + :class:`io.TextIOWrapper` arguments, ``encoding`` included, as keywords. + .. method:: Path.read_bytes() Read the current file as bytes. @@ -630,6 +685,7 @@ The :class:`PyZipFile` constructor takes the same parameters as the >>> def notests(s): ... fn = os.path.basename(s) ... return (not (fn == 'test' or fn.startswith('test_'))) + ... >>> zf.writepy('myprog', filterfunc=notests) The :meth:`writepy` method makes archives with file names like @@ -868,6 +924,14 @@ Command-line options Test whether the zipfile is valid or not. +.. cmdoption:: --metadata-encoding + + Specify encoding of member names for :option:`-l`, :option:`-e` and + :option:`-t`. + + .. versionadded:: 3.11 + + Decompression pitfalls ---------------------- diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst index cd7030fed01..fe1adcae163 100644 --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -23,8 +23,8 @@ and a path within the archive can be specified to only import from a subdirectory. For example, the path :file:`example.zip/lib/` would only import from the :file:`lib/` subdirectory within the archive. -Any files may be present in the ZIP archive, but only files :file:`.py` and -:file:`.pyc` are available for import. ZIP import of dynamic modules +Any files may be present in the ZIP archive, but importers are only invoked for +:file:`.py` and :file:`.pyc` files. ZIP import of dynamic modules (:file:`.pyd`, :file:`.so`) is disallowed. Note that if an archive only contains :file:`.py` files, Python will not attempt to modify the archive by adding the corresponding :file:`.pyc` file, meaning that if a ZIP archive diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst index 793c90f3c4e..ac179722dee 100644 --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -42,10 +42,7 @@ The available exception and functions in this module are: for use as a general hash algorithm. .. versionchanged:: 3.0 - Always returns an unsigned value. - To generate the same numeric value across all Python versions and - platforms, use ``adler32(data) & 0xffffffff``. - + The result is always unsigned. .. function:: compress(data, /, level=-1, wbits=MAX_WBITS) @@ -137,10 +134,7 @@ The available exception and functions in this module are: for use as a general hash algorithm. .. versionchanged:: 3.0 - Always returns an unsigned value. - To generate the same numeric value across all Python versions and - platforms, use ``crc32(data) & 0xffffffff``. - + The result is always unsigned. .. function:: decompress(data, /, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE) @@ -271,7 +265,7 @@ Decompression objects support the following methods and attributes: A boolean indicating whether the end of the compressed data stream has been reached. - This makes it possible to distinguish between a properly-formed compressed + This makes it possible to distinguish between a properly formed compressed stream, and an incomplete or truncated one. .. versionadded:: 3.3 diff --git a/Doc/library/zoneinfo.rst b/Doc/library/zoneinfo.rst index 1b2ba2af2ae..d2e5619e7e4 100644 --- a/Doc/library/zoneinfo.rst +++ b/Doc/library/zoneinfo.rst @@ -9,6 +9,8 @@ .. moduleauthor:: Paul Ganssle .. sectionauthor:: Paul Ganssle +**Source code:** :source:`Lib/zoneinfo` + -------------- The :mod:`zoneinfo` module provides a concrete time zone implementation to @@ -27,6 +29,7 @@ first-party `tzdata`_ package available on PyPI. First-party package maintained by the CPython core developers to supply time zone data via PyPI. +.. include:: ../includes/wasm-notavail.rst Using ``ZoneInfo`` ------------------ diff --git a/Doc/license.rst b/Doc/license.rst index 1d086b6fdd3..005d048b6eb 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -100,7 +100,7 @@ PSF LICENSE AGREEMENT FOR PYTHON |release| analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python |release| alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of - copyright, i.e., "Copyright © 2001-2021 Python Software Foundation; All Rights + copyright, i.e., "Copyright © 2001-2023 Python Software Foundation; All Rights Reserved" are retained in Python |release| alone or in any derivative version prepared by Licensee. @@ -302,7 +302,8 @@ for third-party software incorporated in the Python distribution. Mersenne Twister ---------------- -The :mod:`_random` module includes code based on a download from +The :mod:`!_random` C extension underlying the :mod:`random` module +includes code based on a download from http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html. The following are the verbatim comments from the original code:: @@ -353,7 +354,7 @@ Sockets The :mod:`socket` module uses the functions, :func:`getaddrinfo`, and :func:`getnameinfo`, which are coded in separate source files from the WIDE -Project, http://www.wide.ad.jp/. :: +Project, https://www.wide.ad.jp/. :: Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. All rights reserved. @@ -383,6 +384,34 @@ Project, http://www.wide.ad.jp/. :: SUCH DAMAGE. +Asynchronous socket services +---------------------------- + +The :mod:`test.support.asynchat` and :mod:`test.support.asyncore` +modules contain the following notice:: + + Copyright 1996 by Sam Rushing + + All Rights Reserved + + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose and without fee is hereby + granted, provided that the above copyright notice appear in all + copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of Sam + Rushing not be used in advertising or publicity pertaining to + distribution of the software without specific, written prior + permission. + + SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR + CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Cookie management ----------------- @@ -599,9 +628,9 @@ strtod and dtoa The file :file:`Python/dtoa.c`, which supplies C functions dtoa and strtod for conversion of C doubles to and from strings, is derived from the file of the same name by David M. Gay, currently available -from http://www.netlib.org/fp/. The original file, as retrieved on -March 16, 2009, contains the following copyright and licensing -notice:: +from https://web.archive.org/web/20220517033456/http://www.netlib.org/fp/dtoa.c. +The original file, as retrieved on March 16, 2009, contains the following +copyright and licensing notice:: /**************************************************************** * @@ -792,7 +821,8 @@ sources unless the build is configured ``--with-system-expat``:: libffi ------ -The :mod:`_ctypes` extension is built using an included copy of the libffi +The :mod:`!_ctypes` C extension underlying the :mod:`ctypes` module +is built using an included copy of the libffi sources unless the build is configured ``--with-system-libffi``:: Copyright (c) 1996-2008 Red Hat, Inc and others. @@ -893,7 +923,8 @@ on the cfuhash project:: libmpdec -------- -The :mod:`_decimal` module is built using an included copy of the libmpdec +The :mod:`!_decimal` C extension underlying the :mod:`decimal` module +is built using an included copy of the libmpdec library unless the build is configured ``--with-system-libmpdec``:: Copyright (c) 2008-2020 Stefan Krah. All rights reserved. @@ -957,3 +988,31 @@ https://www.w3.org/TR/xml-c14n2-testcases/ and is distributed under the THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +Audioop +------- + +The audioop module uses the code base in g771.c file of the SoX project:: + + Programming the AdLib/Sound Blaster + FM Music Chips + Version 2.0 (24 Feb 1992) + Copyright (c) 1991, 1992 by Jeffrey S. Lee + jlee@smylex.uucp + Warranty and Copyright Policy + This document is provided on an "as-is" basis, and its author makes + no warranty or representation, express or implied, with respect to + its quality performance or fitness for a particular purpose. In no + event will the author of this document be liable for direct, indirect, + special, incidental, or consequential damages arising out of the use + or inability to use the information contained within. Use of this + document is at your own risk. + This file may be used and copied freely so long as the applicable + copyright notices are retained, and no modifications are made to the + text of the document. No money shall be charged for its distribution + beyond reasonable shipping, handling and duplication costs, nor shall + proprietary changes be made to this document so that it cannot be + distributed freely. This document may not be included in published + material or commercial packages without the written consent of its + author. diff --git a/Doc/make.bat b/Doc/make.bat index 7fde0636427..87d8359ef11 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -13,7 +13,7 @@ if not defined SPHINXBUILD ( %PYTHON% -c "import sphinx" > nul 2> nul if errorlevel 1 ( echo Installing sphinx with %PYTHON% - %PYTHON% -m pip install sphinx==2.2.0 + %PYTHON% -m pip install -r requirements.txt if errorlevel 1 exit /B ) set SPHINXBUILD=%PYTHON% -c "import sphinx.cmd.build, sys; sys.exit(sphinx.cmd.build.main())" @@ -30,12 +30,24 @@ if not defined BLURB ( %PYTHON% -c "import blurb" > nul 2> nul if errorlevel 1 ( echo Installing blurb with %PYTHON% + rem Should have been installed with Sphinx earlier %PYTHON% -m pip install blurb if errorlevel 1 exit /B ) set BLURB=%PYTHON% -m blurb ) +if not defined SPHINXLINT ( + %PYTHON% -c "import sphinxlint" > nul 2> nul + if errorlevel 1 ( + echo Installing sphinx-lint with %PYTHON% + rem Should have been installed with Sphinx earlier + %PYTHON% -m pip install sphinx-lint + if errorlevel 1 exit /B + ) + set SPHINXLINT=%PYTHON% -m sphinxlint +) + if "%1" NEQ "htmlhelp" goto :skiphhcsearch if exist "%HTMLHELP%" goto :skiphhcsearch @@ -97,9 +109,9 @@ echo.always available include: echo. echo. Provided by Sphinx: echo. html, htmlhelp, latex, text -echo. suspicious, linkcheck, changes, doctest +echo. linkcheck, changes, doctest echo. Provided by this script: -echo. clean, check, serve, htmlview +echo. clean, check, htmlview echo. echo.All arguments past the first one are passed through to sphinx-build as echo.filenames to build or are ignored. See README.rst in this directory or @@ -168,11 +180,14 @@ if EXIST "%BUILDDIR%\html\index.html" ( goto end :check -cmd /S /C "%PYTHON% tools\rstlint.py -i tools" +rem Check the docs and NEWS files with sphinx-lint. +rem Ignore the tools dir and check that the default role is not used. +cmd /S /C "%SPHINXLINT% -i tools --enable default-role" +cmd /S /C "%SPHINXLINT% --enable default-role ..\Misc\NEWS.d\next\ " goto end :serve -cmd /S /C "%PYTHON% ..\Tools\scripts\serve.py "%BUILDDIR%\html"" +echo.The serve target was removed, use htmlview instead (see bpo-36329) goto end :end diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index cf8ad1787b2..d5cb2899c23 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -154,17 +154,17 @@ The :keyword:`for` statement is used to iterate over the elements of a sequence (such as a string, tuple or list) or other iterable object: .. productionlist:: python-grammar - for_stmt: "for" `target_list` "in" `expression_list` ":" `suite` + for_stmt: "for" `target_list` "in" `starred_list` ":" `suite` : ["else" ":" `suite`] -The expression list is evaluated once; it should yield an iterable object. An -iterator is created for the result of the ``expression_list``. The suite is -then executed once for each item provided by the iterator, in the order returned -by the iterator. Each item in turn is assigned to the target list using the -standard rules for assignments (see :ref:`assignment`), and then the suite is -executed. When the items are exhausted (which is immediately when the sequence -is empty or an iterator raises a :exc:`StopIteration` exception), the suite in -the :keyword:`!else` clause, if present, is executed, and the loop terminates. +The ``starred_list`` expression is evaluated once; it should yield an +:term:`iterable` object. An :term:`iterator` is created for that iterable. +The first item provided +by the iterator is then assigned to the target list using the standard +rules for assignments (see :ref:`assignment`), and the suite is executed. This +repeats for each item provided by the iterator. When the iterator is exhausted, +the suite in the :keyword:`!else` clause, +if present, is executed, and the loop terminates. .. index:: statement: break @@ -192,35 +192,14 @@ those made in the suite of the for-loop:: Names in the target list are not deleted when the loop is finished, but if the sequence is empty, they will not have been assigned to at all by the loop. Hint: -the built-in function :func:`range` returns an iterator of integers suitable to -emulate the effect of Pascal's ``for i := a to b do``; e.g., ``list(range(3))`` -returns the list ``[0, 1, 2]``. +the built-in type :func:`range` represents immutable arithmetic sequences of integers. +For instance, iterating ``range(3)`` successively yields 0, 1, and then 2. -.. note:: - - .. index:: - single: loop; over mutable sequence - single: mutable sequence; loop over - - There is a subtlety when the sequence is being modified by the loop (this can - only occur for mutable sequences, e.g. lists). An internal counter is used - to keep track of which item is used next, and this is incremented on each - iteration. When this counter has reached the length of the sequence the loop - terminates. This means that if the suite deletes the current (or a previous) - item from the sequence, the next item will be skipped (since it gets the - index of the current item which has already been treated). Likewise, if the - suite inserts an item in the sequence before the current item, the current - item will be treated again the next time through the loop. This can lead to - nasty bugs that can be avoided by making a temporary copy using a slice of - the whole sequence, e.g., :: - - for x in a[:]: - if x < 0: a.remove(x) +.. versionchanged:: 3.11 + Starred elements are now allowed in the expression list. .. _try: -.. _except: -.. _finally: The :keyword:`!try` statement ============================= @@ -233,51 +212,72 @@ The :keyword:`!try` statement keyword: as single: : (colon); compound statement -The :keyword:`try` statement specifies exception handlers and/or cleanup code +The :keyword:`!try` statement specifies exception handlers and/or cleanup code for a group of statements: .. productionlist:: python-grammar - try_stmt: `try1_stmt` | `try2_stmt` + try_stmt: `try1_stmt` | `try2_stmt` | `try3_stmt` try1_stmt: "try" ":" `suite` : ("except" [`expression` ["as" `identifier`]] ":" `suite`)+ : ["else" ":" `suite`] : ["finally" ":" `suite`] try2_stmt: "try" ":" `suite` + : ("except" "*" `expression` ["as" `identifier`] ":" `suite`)+ + : ["else" ":" `suite`] + : ["finally" ":" `suite`] + try3_stmt: "try" ":" `suite` : "finally" ":" `suite` +Additional information on exceptions can be found in section :ref:`exceptions`, +and information on using the :keyword:`raise` statement to generate exceptions +may be found in section :ref:`raise`. -The :keyword:`except` clause(s) specify one or more exception handlers. When no + +.. _except: + +:keyword:`!except` clause +------------------------- + +The :keyword:`!except` clause(s) specify one or more exception handlers. When no exception occurs in the :keyword:`try` clause, no exception handler is executed. When an exception occurs in the :keyword:`!try` suite, a search for an exception -handler is started. This search inspects the except clauses in turn until one -is found that matches the exception. An expression-less except clause, if -present, must be last; it matches any exception. For an except clause with an -expression, that expression is evaluated, and the clause matches the exception +handler is started. This search inspects the :keyword:`!except` clauses in turn +until one is found that matches the exception. +An expression-less :keyword:`!except` clause, if present, must be last; +it matches any exception. +For an :keyword:`!except` clause with an expression, +that expression is evaluated, and the clause matches the exception if the resulting object is "compatible" with the exception. An object is -compatible with an exception if the object is the class or a base class of the exception -object, or a tuple containing an item that is the class or a base class of -the exception object. +compatible with an exception if the object is the class or a +:term:`non-virtual base class ` of the exception object, +or a tuple containing an item that is the class or a non-virtual base class +of the exception object. -If no except clause matches the exception, the search for an exception handler +If no :keyword:`!except` clause matches the exception, +the search for an exception handler continues in the surrounding code and on the invocation stack. [#]_ -If the evaluation of an expression in the header of an except clause raises an -exception, the original search for a handler is canceled and a search starts for +If the evaluation of an expression +in the header of an :keyword:`!except` clause raises an exception, +the original search for a handler is canceled and a search starts for the new exception in the surrounding code and on the call stack (it is treated as if the entire :keyword:`try` statement raised the exception). .. index:: single: as; except clause -When a matching except clause is found, the exception is assigned to the target -specified after the :keyword:`!as` keyword in that except clause, if present, and -the except clause's suite is executed. All except clauses must have an -executable block. When the end of this block is reached, execution continues -normally after the entire try statement. (This means that if two nested -handlers exist for the same exception, and the exception occurs in the try -clause of the inner handler, the outer handler will not handle the exception.) +When a matching :keyword:`!except` clause is found, +the exception is assigned to the target +specified after the :keyword:`!as` keyword in that :keyword:`!except` clause, +if present, and the :keyword:`!except` clause's suite is executed. +All :keyword:`!except` clauses must have an executable block. +When the end of this block is reached, execution continues +normally after the entire :keyword:`try` statement. +(This means that if two nested handlers exist for the same exception, +and the exception occurs in the :keyword:`!try` clause of the inner handler, +the outer handler will not handle the exception.) When an exception has been assigned using ``as target``, it is cleared at the -end of the except clause. This is as if :: +end of the :keyword:`!except` clause. This is as if :: except E as N: foo @@ -291,7 +291,8 @@ was translated to :: del N This means the exception must be assigned to a different name to be able to -refer to it after the except clause. Exceptions are cleared because with the +refer to it after the :keyword:`!except` clause. +Exceptions are cleared because with the traceback attached to them, they form a reference cycle with the stack frame, keeping all locals in that frame alive until the next garbage collection occurs. @@ -299,7 +300,8 @@ keeping all locals in that frame alive until the next garbage collection occurs. module: sys object: traceback -Before an except clause's suite is executed, details about the exception are +Before an :keyword:`!except` clause's suite is executed, +details about the exception are stored in the :mod:`sys` module and can be accessed via :func:`sys.exc_info`. :func:`sys.exc_info` returns a 3-tuple consisting of the exception class, the exception instance and a traceback object (see section :ref:`types`) identifying @@ -325,23 +327,94 @@ when leaving an exception handler:: >>> print(sys.exc_info()) (None, None, None) + +.. index:: + keyword: except_star + +.. _except_star: + +:keyword:`!except*` clause +-------------------------- + +The :keyword:`!except*` clause(s) are used for handling +:exc:`ExceptionGroup`\s. The exception type for matching is interpreted as in +the case of :keyword:`except`, but in the case of exception groups we can have +partial matches when the type matches some of the exceptions in the group. +This means that multiple :keyword:`!except*` clauses can execute, +each handling part of the exception group. +Each clause executes at most once and handles an exception group +of all matching exceptions. Each exception in the group is handled by at most +one :keyword:`!except*` clause, the first that matches it. :: + + >>> try: + ... raise ExceptionGroup("eg", + ... [ValueError(1), TypeError(2), OSError(3), OSError(4)]) + ... except* TypeError as e: + ... print(f'caught {type(e)} with nested {e.exceptions}') + ... except* OSError as e: + ... print(f'caught {type(e)} with nested {e.exceptions}') + ... + caught with nested (TypeError(2),) + caught with nested (OSError(3), OSError(4)) + + Exception Group Traceback (most recent call last): + | File "", line 2, in + | ExceptionGroup: eg + +-+---------------- 1 ---------------- + | ValueError: 1 + +------------------------------------ + + +Any remaining exceptions that were not handled by any :keyword:`!except*` +clause are re-raised at the end, combined into an exception group along with +all exceptions that were raised from within :keyword:`!except*` clauses. + +If the raised exception is not an exception group and its type matches +one of the :keyword:`!except*` clauses, it is caught and wrapped by an +exception group with an empty message string. :: + + >>> try: + ... raise BlockingIOError + ... except* BlockingIOError as e: + ... print(repr(e)) + ... + ExceptionGroup('', (BlockingIOError())) + +An :keyword:`!except*` clause must have a matching type, +and this type cannot be a subclass of :exc:`BaseExceptionGroup`. +It is not possible to mix :keyword:`except` and :keyword:`!except*` +in the same :keyword:`try`. +:keyword:`break`, :keyword:`continue` and :keyword:`return` +cannot appear in an :keyword:`!except*` clause. + + .. index:: keyword: else statement: return statement: break statement: continue +.. _except_else: + +:keyword:`!else` clause +----------------------- + The optional :keyword:`!else` clause is executed if the control flow leaves the :keyword:`try` suite, no exception was raised, and no :keyword:`return`, :keyword:`continue`, or :keyword:`break` statement was executed. Exceptions in the :keyword:`!else` clause are not handled by the preceding :keyword:`except` clauses. + .. index:: keyword: finally -If :keyword:`finally` is present, it specifies a 'cleanup' handler. The +.. _finally: + +:keyword:`!finally` clause +-------------------------- + +If :keyword:`!finally` is present, it specifies a 'cleanup' handler. The :keyword:`try` clause is executed, including any :keyword:`except` and -:keyword:`!else` clauses. If an exception occurs in any of the clauses and is +:keyword:`else` clauses. If an exception occurs in any of the clauses and is not handled, the exception is temporarily saved. The :keyword:`!finally` clause is executed. If there is a saved exception it is re-raised at the end of the :keyword:`!finally` clause. If the :keyword:`!finally` clause raises another @@ -359,7 +432,7 @@ or :keyword:`continue` statement, the saved exception is discarded:: 42 The exception information is not available to the program during execution of -the :keyword:`finally` clause. +the :keyword:`!finally` clause. .. index:: statement: return @@ -368,10 +441,10 @@ the :keyword:`finally` clause. When a :keyword:`return`, :keyword:`break` or :keyword:`continue` statement is executed in the :keyword:`try` suite of a :keyword:`!try`...\ :keyword:`!finally` -statement, the :keyword:`finally` clause is also executed 'on the way out.' +statement, the :keyword:`!finally` clause is also executed 'on the way out.' The return value of a function is determined by the last :keyword:`return` -statement executed. Since the :keyword:`finally` clause always executes, a +statement executed. Since the :keyword:`!finally` clause always executes, a :keyword:`!return` statement executed in the :keyword:`!finally` clause will always be the last one executed:: @@ -384,13 +457,9 @@ always be the last one executed:: >>> foo() 'finally' -Additional information on exceptions can be found in section :ref:`exceptions`, -and information on using the :keyword:`raise` statement to generate exceptions -may be found in section :ref:`raise`. - .. versionchanged:: 3.8 Prior to Python 3.8, a :keyword:`continue` statement was illegal in the - :keyword:`finally` clause due to a problem with the implementation. + :keyword:`!finally` clause due to a problem with the implementation. .. _with: @@ -436,7 +505,7 @@ The execution of the :keyword:`with` statement with one "item" proceeds as follo method returns without an error, then :meth:`__exit__` will always be called. Thus, if an error occurs during the assignment to the target list, it will be treated the same as an error occurring within the suite would - be. See step 6 below. + be. See step 7 below. #. The suite is executed. @@ -523,6 +592,7 @@ The :keyword:`!match` statement keyword: if keyword: as pair: match; case + single: as; match statement single: : (colon); compound statement .. versionadded:: 3.10 @@ -1094,7 +1164,7 @@ subject value: These classes accept a single positional argument, and the pattern there is matched against the whole object rather than an attribute. For example ``int(0|1)`` matches - the value ``0``, but not the values ``0.0`` or ``False``. + the value ``0``, but not the value ``0.0``. In simple terms ``CLS(P1, attr=P2)`` matches only if the following happens: @@ -1467,7 +1537,7 @@ Is semantically equivalent to:: else: SUITE2 -See also :meth:`__aiter__` and :meth:`__anext__` for details. +See also :meth:`~object.__aiter__` and :meth:`~object.__anext__` for details. It is a :exc:`SyntaxError` to use an ``async for`` statement outside the body of a coroutine function. @@ -1509,7 +1579,7 @@ is semantically equivalent to:: if not hit_except: await aexit(manager, None, None, None) -See also :meth:`__aenter__` and :meth:`__aexit__` for details. +See also :meth:`~object.__aenter__` and :meth:`~object.__aexit__` for details. It is a :exc:`SyntaxError` to use an ``async with`` statement outside the body of a coroutine function. diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index b14b2cb1ef5..1d2ddf3507a 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -188,7 +188,7 @@ Ellipsis representation in computers. The string representations of the numeric classes, computed by - :meth:`__repr__` and :meth:`__str__`, have the following + :meth:`~object.__repr__` and :meth:`~object.__str__`, have the following properties: * They are valid numeric literals which, when passed to their @@ -316,7 +316,7 @@ Sequences A string is a sequence of values that represent Unicode code points. All the code points in the range ``U+0000 - U+10FFFF`` can be - represented in a string. Python doesn't have a :c:type:`char` type; + represented in a string. Python doesn't have a :c:expr:`char` type; instead, every code point in the string is represented as a string object with length ``1``. The built-in function :func:`ord` converts a code point from its string form to an integer in the @@ -677,7 +677,8 @@ Callable types returns an :term:`asynchronous iterator` object which can be used in an :keyword:`async for` statement to execute the body of the function. - Calling the asynchronous iterator's :meth:`aiterator.__anext__` method + Calling the asynchronous iterator's + :meth:`aiterator.__anext__ ` method will return an :term:`awaitable` which when awaited will execute until it provides a value using the :keyword:`yield` expression. When the function executes an empty :keyword:`return` @@ -715,13 +716,13 @@ Callable types Classes Classes are callable. These objects normally act as factories for new instances of themselves, but variations are possible for class types that - override :meth:`__new__`. The arguments of the call are passed to - :meth:`__new__` and, in the typical case, to :meth:`__init__` to + override :meth:`~object.__new__`. The arguments of the call are passed to + :meth:`__new__` and, in the typical case, to :meth:`~object.__init__` to initialize the new instance. Class Instances Instances of arbitrary classes can be made callable by defining a - :meth:`__call__` method in their class. + :meth:`~object.__call__` method in their class. Modules @@ -880,14 +881,14 @@ Class instances section :ref:`descriptors` for another way in which attributes of a class retrieved via its instances may differ from the objects actually stored in the class's :attr:`~object.__dict__`. If no class attribute is found, and the - object's class has a :meth:`__getattr__` method, that is called to satisfy + object's class has a :meth:`~object.__getattr__` method, that is called to satisfy the lookup. .. index:: triple: class instance; attribute; assignment Attribute assignments and deletions update the instance's dictionary, never a - class's dictionary. If the class has a :meth:`__setattr__` or - :meth:`__delattr__` method, this is called instead of updating the instance + class's dictionary. If the class has a :meth:`~object.__setattr__` or + :meth:`~object.__delattr__` method, this is called instead of updating the instance dictionary directly. .. index:: @@ -1176,7 +1177,8 @@ Internal types Slice objects .. index:: builtin: slice - Slice objects are used to represent slices for :meth:`__getitem__` + Slice objects are used to represent slices for + :meth:`~object.__getitem__` methods. They are also created by the built-in :func:`slice` function. .. index:: @@ -1229,7 +1231,8 @@ A class can implement certain operations that are invoked by special syntax (such as arithmetic operations or subscripting and slicing) by defining methods with special names. This is Python's approach to :dfn:`operator overloading`, allowing classes to define their own behavior with respect to language -operators. For instance, if a class defines a method named :meth:`__getitem__`, +operators. For instance, if a class defines a method named +:meth:`~object.__getitem__`, and ``x`` is an instance of this class, then ``x[i]`` is roughly equivalent to ``type(x).__getitem__(x, i)``. Except where mentioned, attempts to execute an operation raise an exception when no appropriate method is defined (typically @@ -1237,9 +1240,9 @@ operation raise an exception when no appropriate method is defined (typically Setting a special method to ``None`` indicates that the corresponding operation is not available. For example, if a class sets -:meth:`__iter__` to ``None``, the class is not iterable, so calling +:meth:`~object.__iter__` to ``None``, the class is not iterable, so calling :func:`iter` on its instances will raise a :exc:`TypeError` (without -falling back to :meth:`__getitem__`). [#]_ +falling back to :meth:`~object.__getitem__`). [#]_ When implementing a class that emulates any built-in type, it is important that the emulation only be implemented to the degree that it makes sense for the @@ -1267,7 +1270,7 @@ Basic customization Typical implementations create a new instance of the class by invoking the superclass's :meth:`__new__` method using ``super().__new__(cls[, ...])`` - with appropriate arguments and then modifying the newly-created instance + with appropriate arguments and then modifying the newly created instance as necessary before returning it. If :meth:`__new__` is invoked during object construction and it returns an @@ -1498,7 +1501,7 @@ Basic customization Called by built-in function :func:`hash` and for operations on members of hashed collections including :class:`set`, :class:`frozenset`, and - :class:`dict`. :meth:`__hash__` should return an integer. The only required + :class:`dict`. The ``__hash__()`` method should return an integer. The only required property is that objects which compare equal have the same hash value; it is advised to mix together the hash values of the components of the object that also play a part in comparison of objects by packing them into a tuple and @@ -1557,7 +1560,7 @@ Basic customization predictable between repeated invocations of Python. This is intended to provide protection against a denial-of-service caused - by carefully-chosen inputs that exploit the worst case performance of a + by carefully chosen inputs that exploit the worst case performance of a dict insertion, O(n\ :sup:`2`) complexity. See http://www.ocert.org/advisories/ocert-2011-003.html for details. @@ -1789,7 +1792,8 @@ Invoking Descriptors In general, a descriptor is an object attribute with "binding behavior", one whose attribute access has been overridden by methods in the descriptor -protocol: :meth:`__get__`, :meth:`__set__`, and :meth:`__delete__`. If any of +protocol: :meth:`~object.__get__`, :meth:`~object.__set__`, and +:meth:`~object.__delete__`. If any of those methods are defined for an object, it is said to be a descriptor. The default behavior for attribute access is to get, set, or delete the @@ -1818,14 +1822,47 @@ Class Binding ``A.__dict__['x'].__get__(None, A)``. Super Binding - If ``a`` is an instance of :class:`super`, then the binding ``super(B, obj).m()`` - searches ``obj.__class__.__mro__`` for the base class ``A`` - immediately following ``B`` and then invokes the descriptor with the call: - ``A.__dict__['m'].__get__(obj, obj.__class__)``. + A dotted lookup such as ``super(A, a).x`` searches + ``a.__class__.__mro__`` for a base class ``B`` following ``A`` and then + returns ``B.__dict__['x'].__get__(a, A)``. If not a descriptor, ``x`` is + returned unchanged. + +.. testcode:: + :hide: + + class Desc: + def __get__(*args): + return args + + class B: + + x = Desc() + + class A(B): + + x = 999 + + def m(self): + 'Demonstrate these two descriptor invocations are equivalent' + result1 = super(A, self).x + result2 = B.__dict__['x'].__get__(self, A) + return result1 == result2 + +.. doctest:: + :hide: + + >>> a = A() + >>> a.__class__.__mro__.index(B) > a.__class__.__mro__.index(A) + True + >>> super(A, a).x == B.__dict__['x'].__get__(a, A) + True + >>> a.m() + True For instance bindings, the precedence of descriptor invocation depends on which descriptor methods are defined. A descriptor can define any combination -of :meth:`__get__`, :meth:`__set__` and :meth:`__delete__`. If it does not +of :meth:`~object.__get__`, :meth:`~object.__set__` and +:meth:`~object.__delete__`. If it does not define :meth:`__get__`, then accessing the attribute will return the descriptor object itself unless there is a value in the object's instance dictionary. If the descriptor defines :meth:`__set__` and/or :meth:`__delete__`, it is a data @@ -1836,7 +1873,8 @@ descriptors have just the :meth:`__get__` method. Data descriptors with instance dictionary. In contrast, non-data descriptors can be overridden by instances. -Python methods (including :func:`staticmethod` and :func:`classmethod`) are +Python methods (including those decorated with +:func:`@staticmethod ` and :func:`@classmethod `) are implemented as non-data descriptors. Accordingly, instances can redefine and override methods. This allows individual instances to acquire behaviors that differ from other instances of the same class. @@ -1851,46 +1889,52 @@ __slots__ ^^^^^^^^^ *__slots__* allow us to explicitly declare data members (like -properties) and deny the creation of *__dict__* and *__weakref__* +properties) and deny the creation of :attr:`~object.__dict__` and *__weakref__* (unless explicitly declared in *__slots__* or available in a parent.) -The space saved over using *__dict__* can be significant. +The space saved over using :attr:`~object.__dict__` can be significant. Attribute lookup speed can be significantly improved as well. .. data:: object.__slots__ This class variable can be assigned a string, iterable, or sequence of strings with variable names used by instances. *__slots__* reserves space - for the declared variables and prevents the automatic creation of *__dict__* + for the declared variables and prevents the automatic creation of + :attr:`~object.__dict__` and *__weakref__* for each instance. +.. _datamodel-note-slots: + Notes on using *__slots__* """""""""""""""""""""""""" -* When inheriting from a class without *__slots__*, the *__dict__* and +* When inheriting from a class without *__slots__*, the + :attr:`~object.__dict__` and *__weakref__* attribute of the instances will always be accessible. -* Without a *__dict__* variable, instances cannot be assigned new variables not +* Without a :attr:`~object.__dict__` variable, instances cannot be assigned new + variables not listed in the *__slots__* definition. Attempts to assign to an unlisted variable name raises :exc:`AttributeError`. If dynamic assignment of new variables is desired, then add ``'__dict__'`` to the sequence of strings in the *__slots__* declaration. * Without a *__weakref__* variable for each instance, classes defining - *__slots__* do not support weak references to its instances. If weak reference + *__slots__* do not support :mod:`weak references ` to its instances. + If weak reference support is needed, then add ``'__weakref__'`` to the sequence of strings in the *__slots__* declaration. -* *__slots__* are implemented at the class level by creating descriptors - (:ref:`descriptors`) for each variable name. As a result, class attributes +* *__slots__* are implemented at the class level by creating :ref:`descriptors ` + for each variable name. As a result, class attributes cannot be used to set default values for instance variables defined by *__slots__*; otherwise, the class attribute would overwrite the descriptor assignment. * The action of a *__slots__* declaration is not limited to the class where it is defined. *__slots__* declared in parents are available in - child classes. However, child subclasses will get a *__dict__* and + child classes. However, child subclasses will get a :attr:`~object.__dict__` and *__weakref__* unless they also define *__slots__* (which should only contain names of any *additional* slots). @@ -1902,18 +1946,24 @@ Notes on using *__slots__* * Nonempty *__slots__* does not work for classes derived from "variable-length" built-in types such as :class:`int`, :class:`bytes` and :class:`tuple`. -* Any non-string iterable may be assigned to *__slots__*. Mappings may also be - used; however, in the future, special meaning may be assigned to the values - corresponding to each key. +* Any non-string :term:`iterable` may be assigned to *__slots__*. -* *__class__* assignment works only if both classes have the same *__slots__*. +* If a :class:`dictionary ` is used to assign *__slots__*, the dictionary + keys will be used as the slot names. The values of the dictionary can be used + to provide per-attribute docstrings that will be recognised by + :func:`inspect.getdoc` and displayed in the output of :func:`help`. -* Multiple inheritance with multiple slotted parent classes can be used, +* :attr:`~instance.__class__` assignment works only if both classes have the + same *__slots__*. + +* :ref:`Multiple inheritance ` with multiple slotted parent + classes can be used, but only one parent is allowed to have attributes created by slots (the other bases must have empty slot layouts) - violations raise :exc:`TypeError`. -* If an iterator is used for *__slots__* then a descriptor is created for each +* If an :term:`iterator` is used for *__slots__* then a :term:`descriptor` is + created for each of the iterator's values. However, the *__slots__* attribute will be an empty iterator. @@ -1922,8 +1972,8 @@ Notes on using *__slots__* Customizing class creation -------------------------- -Whenever a class inherits from another class, *__init_subclass__* is -called on that class. This way, it is possible to write classes which +Whenever a class inherits from another class, :meth:`~object.__init_subclass__` is +called on the parent class. This way, it is possible to write classes which change the behavior of subclasses. This is closely related to class decorators, but where class decorators only affect the specific class they're applied to, ``__init_subclass__`` solely applies to future subclasses of the @@ -1963,7 +2013,7 @@ class defining the method. When a class is created, :meth:`type.__new__` scans the class variables -and makes callbacks to those with a :meth:`__set_name__` hook. +and makes callbacks to those with a :meth:`~object.__set_name__` hook. .. method:: object.__set_name__(self, owner, name) @@ -2075,7 +2125,8 @@ Once the appropriate metaclass has been identified, then the class namespace is prepared. If the metaclass has a ``__prepare__`` attribute, it is called as ``namespace = metaclass.__prepare__(name, bases, **kwds)`` (where the additional keyword arguments, if any, come from the class definition). The -``__prepare__`` method should be implemented as a :func:`classmethod`. The +``__prepare__`` method should be implemented as a +:func:`classmethod `. The namespace returned by ``__prepare__`` is passed in to ``__new__``, but when the final class object is created the namespace is copied into a new ``dict``. @@ -2285,7 +2336,7 @@ called:: from inspect import isclass def subscribe(obj, x): - """Return the result of the expression `obj[x]`""" + """Return the result of the expression 'obj[x]'""" class_of_obj = type(obj) @@ -2373,31 +2424,36 @@ Emulating container types ------------------------- The following methods can be defined to implement container objects. Containers -usually are sequences (such as lists or tuples) or mappings (like dictionaries), +usually are :term:`sequences ` (such as :class:`lists ` or +:class:`tuples `) or :term:`mappings ` (like +:class:`dictionaries `), but can represent other containers as well. The first set of methods is used either to emulate a sequence or to emulate a mapping; the difference is that for a sequence, the allowable keys should be the integers *k* for which ``0 <= k < -N`` where *N* is the length of the sequence, or slice objects, which define a +N`` where *N* is the length of the sequence, or :class:`slice` objects, which define a range of items. It is also recommended that mappings provide the methods :meth:`keys`, :meth:`values`, :meth:`items`, :meth:`get`, :meth:`clear`, :meth:`setdefault`, :meth:`pop`, :meth:`popitem`, :meth:`!copy`, and -:meth:`update` behaving similar to those for Python's standard dictionary +:meth:`update` behaving similar to those for Python's standard :class:`dictionary ` objects. The :mod:`collections.abc` module provides a :class:`~collections.abc.MutableMapping` -abstract base class to help create those methods from a base set of -:meth:`__getitem__`, :meth:`__setitem__`, :meth:`__delitem__`, and :meth:`keys`. +:term:`abstract base class` to help create those methods from a base set of +:meth:`~object.__getitem__`, :meth:`~object.__setitem__`, :meth:`~object.__delitem__`, and :meth:`keys`. Mutable sequences should provide methods :meth:`append`, :meth:`count`, :meth:`index`, :meth:`extend`, :meth:`insert`, :meth:`pop`, :meth:`remove`, -:meth:`reverse` and :meth:`sort`, like Python standard list objects. Finally, +:meth:`reverse` and :meth:`sort`, like Python standard :class:`list` +objects. Finally, sequence types should implement addition (meaning concatenation) and -multiplication (meaning repetition) by defining the methods :meth:`__add__`, -:meth:`__radd__`, :meth:`__iadd__`, :meth:`__mul__`, :meth:`__rmul__` and -:meth:`__imul__` described below; they should not define other numerical +multiplication (meaning repetition) by defining the methods +:meth:`~object.__add__`, :meth:`~object.__radd__`, :meth:`~object.__iadd__`, +:meth:`~object.__mul__`, :meth:`~object.__rmul__` and :meth:`~object.__imul__` +described below; they should not define other numerical operators. It is recommended that both mappings and sequences implement the -:meth:`__contains__` method to allow efficient use of the ``in`` operator; for +:meth:`~object.__contains__` method to allow efficient use of the ``in`` +operator; for mappings, ``in`` should search the mapping's keys; for sequences, it should search through the values. It is further recommended that both mappings and -sequences implement the :meth:`__iter__` method to allow efficient iteration +sequences implement the :meth:`~object.__iter__` method to allow efficient iteration through the container; for mappings, :meth:`__iter__` should iterate through the object's keys; for sequences, it should iterate through the values. @@ -2706,6 +2762,9 @@ left undefined. The built-in function :func:`int` falls back to :meth:`__trunc__` if neither :meth:`__int__` nor :meth:`__index__` is defined. + .. versionchanged:: 3.11 + The delegation of :func:`int` to :meth:`__trunc__` is deprecated. + .. _context-managers: @@ -2764,7 +2823,7 @@ Customizing positional arguments in class pattern matching When using a class name in a pattern, positional arguments in the pattern are not allowed by default, i.e. ``case MyClass(x, y)`` is typically invalid without special -support in ``MyClass``. To be able to use that kind of patterns, the class needs to +support in ``MyClass``. To be able to use that kind of pattern, the class needs to define a *__match_args__* attribute. .. data:: object.__match_args__ @@ -2810,7 +2869,8 @@ exception:: TypeError: object of type 'C' has no len() The rationale behind this behaviour lies with a number of special methods such -as :meth:`__hash__` and :meth:`__repr__` that are implemented by all objects, +as :meth:`~object.__hash__` and :meth:`~object.__repr__` that are implemented +by all objects, including type objects. If the implicit lookup of these methods used the conventional lookup process, they would fail when invoked on the type object itself:: @@ -2833,7 +2893,7 @@ the instance when looking up special methods:: In addition to bypassing any instance attributes in the interest of correctness, implicit special method lookup generally also bypasses the -:meth:`__getattribute__` method even of the object's metaclass:: +:meth:`~object.__getattribute__` method even of the object's metaclass:: >>> class Meta(type): ... def __getattribute__(*args): @@ -2857,7 +2917,7 @@ correctness, implicit special method lookup generally also bypasses the >>> len(c) # Implicit lookup 10 -Bypassing the :meth:`__getattribute__` machinery in this fashion +Bypassing the :meth:`~object.__getattribute__` machinery in this fashion provides significant scope for speed optimisations within the interpreter, at the cost of some flexibility in the handling of special methods (the special method *must* be set on the class @@ -2874,7 +2934,7 @@ Coroutines Awaitable Objects ----------------- -An :term:`awaitable` object generally implements an :meth:`__await__` method. +An :term:`awaitable` object generally implements an :meth:`~object.__await__` method. :term:`Coroutine objects ` returned from :keyword:`async def` functions are awaitable. @@ -2882,7 +2942,7 @@ are awaitable. The :term:`generator iterator` objects returned from generators decorated with :func:`types.coroutine` - are also awaitable, but they do not implement :meth:`__await__`. + are also awaitable, but they do not implement :meth:`~object.__await__`. .. method:: object.__await__(self) @@ -2890,6 +2950,14 @@ are awaitable. :term:`awaitable` objects. For instance, :class:`asyncio.Future` implements this method to be compatible with the :keyword:`await` expression. + .. note:: + + The language doesn't place any restriction on the type or value of the + objects yielded by the iterator returned by ``__await__``, as this is + specific to the implementation of the asynchronous execution framework + (e.g. :mod:`asyncio`) that will be managing the :term:`awaitable` object. + + .. versionadded:: 3.5 .. seealso:: :pep:`492` for additional information about awaitable objects. @@ -2901,7 +2969,7 @@ Coroutine Objects ----------------- :term:`Coroutine objects ` are :term:`awaitable` objects. -A coroutine's execution can be controlled by calling :meth:`__await__` and +A coroutine's execution can be controlled by calling :meth:`~object.__await__` and iterating over the result. When the coroutine has finished executing and returns, the iterator raises :exc:`StopIteration`, and the exception's :attr:`~StopIteration.value` attribute holds the return value. If the @@ -2920,23 +2988,29 @@ generators, coroutines do not directly support iteration. Starts or resumes execution of the coroutine. If *value* is ``None``, this is equivalent to advancing the iterator returned by - :meth:`__await__`. If *value* is not ``None``, this method delegates + :meth:`~object.__await__`. If *value* is not ``None``, this method delegates to the :meth:`~generator.send` method of the iterator that caused the coroutine to suspend. The result (return value, :exc:`StopIteration`, or other exception) is the same as when iterating over the :meth:`__await__` return value, described above. -.. method:: coroutine.throw(type[, value[, traceback]]) +.. method:: coroutine.throw(value) + coroutine.throw(type[, value[, traceback]]) Raises the specified exception in the coroutine. This method delegates to the :meth:`~generator.throw` method of the iterator that caused the coroutine to suspend, if it has such a method. Otherwise, the exception is raised at the suspension point. The result (return value, :exc:`StopIteration`, or other exception) is the same as - when iterating over the :meth:`__await__` return value, described + when iterating over the :meth:`~object.__await__` return value, described above. If the exception is not caught in the coroutine, it propagates back to the caller. + .. versionchanged:: 3.12 + + The second signature \(type\[, value\[, traceback\]\]\) is deprecated and + may be removed in a future version of Python. + .. method:: coroutine.close() Causes the coroutine to clean itself up and exit. If the coroutine @@ -2987,11 +3061,11 @@ An example of an asynchronous iterable object:: .. versionadded:: 3.5 .. versionchanged:: 3.7 - Prior to Python 3.7, ``__aiter__`` could return an *awaitable* + Prior to Python 3.7, :meth:`~object.__aiter__` could return an *awaitable* that would resolve to an :term:`asynchronous iterator `. - Starting with Python 3.7, ``__aiter__`` must return an + Starting with Python 3.7, :meth:`~object.__aiter__` must return an asynchronous iterator object. Returning anything else will result in a :exc:`TypeError` error. @@ -3034,8 +3108,9 @@ An example of an asynchronous context manager class:: controlled conditions. It generally isn't a good idea though, since it can lead to some very strange behaviour if it is handled incorrectly. -.. [#] The :meth:`__hash__`, :meth:`__iter__`, :meth:`__reversed__`, and - :meth:`__contains__` methods have special handling for this; others +.. [#] The :meth:`~object.__hash__`, :meth:`~object.__iter__`, + :meth:`~object.__reversed__`, and :meth:`~object.__contains__` methods have + special handling for this; others will still raise a :exc:`TypeError`, but may do so by relying on the behavior that ``None`` is not callable. @@ -3046,5 +3121,6 @@ An example of an asynchronous context manager class:: *blocking* such fallback. .. [#] For operands of the same type, it is assumed that if the non-reflected - method -- such as :meth:`__add__` -- fails then the overall operation is not + method -- such as :meth:`~object.__add__` -- fails then the overall + operation is not supported, which is why the reflected method is not called. diff --git a/Doc/reference/executionmodel.rst b/Doc/reference/executionmodel.rst index 5c85dd7052d..a264015cbf4 100644 --- a/Doc/reference/executionmodel.rst +++ b/Doc/reference/executionmodel.rst @@ -56,15 +56,25 @@ Binding of names .. index:: single: from; import statement -The following constructs bind names: formal parameters to functions, -:keyword:`import` statements, class and function definitions (these bind the -class or function name in the defining block), and targets that are identifiers -if occurring in an assignment, :keyword:`for` loop header, or after -:keyword:`!as` in a :keyword:`with` statement or :keyword:`except` clause. -The :keyword:`!import` statement -of the form ``from ... import *`` binds all names defined in the imported -module, except those beginning with an underscore. This form may only be used -at the module level. +The following constructs bind names: + +* formal parameters to functions, +* class definitions, +* function definitions, +* assignment expressions, +* :ref:`targets ` that are identifiers if occurring in + an assignment: + + + :keyword:`for` loop header, + + after :keyword:`!as` in a :keyword:`with` statement, :keyword:`except` + clause, :keyword:`except* ` clause, or in the as-pattern in structural pattern matching, + + in a capture pattern in structural pattern matching + +* :keyword:`import` statements. + +The :keyword:`!import` statement of the form ``from ... import *`` binds all +names defined in the imported module, except those beginning with an underscore. +This form may only be used at the module level. A target occurring in a :keyword:`del` statement is also considered bound for this purpose (though the actual semantics are to unbind the name). @@ -118,6 +128,8 @@ lead to errors when a name is used within a block before it is bound. This rule is subtle. Python lacks declarations and allows name binding operations to occur anywhere within a code block. The local variables of a code block can be determined by scanning the entire text of the block for name binding operations. +See :ref:`the FAQ entry on UnboundLocalError ` +for examples. If the :keyword:`global` statement occurs within a block, all uses of the names specified in the statement refer to the bindings of those names in the top-level @@ -249,8 +261,9 @@ a stack traceback, except when the exception is :exc:`SystemExit`. Exceptions are identified by class instances. The :keyword:`except` clause is selected depending on the class of the instance: it must reference the class of -the instance or a base class thereof. The instance can be received by the -handler and can carry additional information about the exceptional condition. +the instance or a :term:`non-virtual base class ` thereof. +The instance can be received by the handler and can carry additional information +about the exceptional condition. .. note:: diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 991f2d717a0..1e4a13fbd6a 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -154,7 +154,7 @@ tuple may or may not yield the same object). single: , (comma) Note that tuples are not formed by the parentheses, but rather by use of the -comma operator. The exception is the empty tuple, for which parentheses *are* +comma. The exception is the empty tuple, for which parentheses *are* required --- allowing unparenthesized "nothing" in expressions would cause ambiguities and allow common typos to pass uncaught. @@ -427,9 +427,9 @@ Yield expressions The yield expression is used when defining a :term:`generator` function or an :term:`asynchronous generator` function and thus can only be used in the body of a function definition. Using a yield -expression in a function's body causes that function to be a generator, +expression in a function's body causes that function to be a generator function, and using it in an :keyword:`async def` function's body causes that -coroutine function to be an asynchronous generator. For example:: +coroutine function to be an asynchronous generator function. For example:: def gen(): # defines a generator function yield 123 @@ -454,7 +454,9 @@ generator. That generator then controls the execution of the generator function. The execution starts when one of the generator's methods is called. At that time, the execution proceeds to the first yield expression, where it is suspended again, returning the value of :token:`~python-grammar:expression_list` -to the generator's caller. By suspended, we mean that all local state is +to the generator's caller, +or ``None`` if :token:`~python-grammar:expression_list` is omitted. +By suspended, we mean that all local state is retained, including the current bindings of local variables, the instruction pointer, the internal evaluation stack, and the state of any exception handling. When the execution is resumed by calling one of the generator's methods, the @@ -561,14 +563,32 @@ is already executing raises a :exc:`ValueError` exception. could receive the value. -.. method:: generator.throw(type[, value[, traceback]]) +.. method:: generator.throw(value) + generator.throw(type[, value[, traceback]]) - Raises an exception of type ``type`` at the point where the generator was paused, + Raises an exception at the point where the generator was paused, and returns the next value yielded by the generator function. If the generator exits without yielding another value, a :exc:`StopIteration` exception is raised. If the generator function does not catch the passed-in exception, or raises a different exception, then that exception propagates to the caller. + In typical use, this is called with a single exception instance similar to the + way the :keyword:`raise` keyword is used. + + For backwards compatibility, however, the second signature is + supported, following a convention from older versions of Python. + The *type* argument should be an exception class, and *value* + should be an exception instance. If the *value* is not provided, the + *type* constructor is called to get an instance. If *traceback* + is provided, it is set on the exception, otherwise any existing + :attr:`~BaseException.__traceback__` attribute stored in *value* may + be cleared. + + .. versionchanged:: 3.12 + + The second signature \(type\[, value\[, traceback\]\]\) is deprecated and + may be removed in a future version of Python. + .. index:: exception: GeneratorExit @@ -725,7 +745,8 @@ which are used to control the execution of a generator function. because there is no yield expression that could receive the value. -.. coroutinemethod:: agen.athrow(type[, value[, traceback]]) +.. coroutinemethod:: agen.athrow(value) + agen.athrow(type[, value[, traceback]]) Returns an awaitable that raises an exception of type ``type`` at the point where the asynchronous generator was paused, and returns the next value @@ -737,6 +758,11 @@ which are used to control the execution of a generator function. raises a different exception, then when the awaitable is run that exception propagates to the caller of the awaitable. + .. versionchanged:: 3.12 + + The second signature \(type\[, value\[, traceback\]\]\) is deprecated and + may be removed in a future version of Python. + .. index:: exception: GeneratorExit @@ -815,30 +841,44 @@ Subscriptions object: dictionary pair: sequence; item -Subscription of a sequence (string, tuple or list) or mapping (dictionary) -object usually selects an item from the collection: +The subscription of an instance of a :ref:`container class ` +will generally select an element from the container. The subscription of a +:term:`generic class ` will generally return a +:ref:`GenericAlias ` object. .. productionlist:: python-grammar subscription: `primary` "[" `expression_list` "]" -The primary must evaluate to an object that supports subscription (lists or -dictionaries for example). User-defined objects can support subscription by -defining a :meth:`__getitem__` method. +When an object is subscripted, the interpreter will evaluate the primary and +the expression list. -For built-in objects, there are two types of objects that support subscription: +The primary must evaluate to an object that supports subscription. An object +may support subscription through defining one or both of +:meth:`~object.__getitem__` and :meth:`~object.__class_getitem__`. When the +primary is subscripted, the evaluated result of the expression list will be +passed to one of these methods. For more details on when ``__class_getitem__`` +is called instead of ``__getitem__``, see :ref:`classgetitem-versus-getitem`. -If the primary is a mapping, the expression list must evaluate to an object -whose value is one of the keys of the mapping, and the subscription selects the -value in the mapping that corresponds to that key. (The expression list is a -tuple except if it has exactly one item.) +If the expression list contains at least one comma, it will evaluate to a +:class:`tuple` containing the items of the expression list. Otherwise, the +expression list will evaluate to the value of the list's sole member. -If the primary is a sequence, the expression list must evaluate to an integer -or a slice (as discussed in the following section). +For built-in objects, there are two types of objects that support subscription +via :meth:`~object.__getitem__`: + +1. Mappings. If the primary is a :term:`mapping`, the expression list must + evaluate to an object whose value is one of the keys of the mapping, and the + subscription selects the value in the mapping that corresponds to that key. + An example of a builtin mapping class is the :class:`dict` class. +2. Sequences. If the primary is a :term:`sequence`, the expression list must + evaluate to an :class:`int` or a :class:`slice` (as discussed in the + following section). Examples of builtin sequence classes include the + :class:`str`, :class:`list` and :class:`tuple` classes. The formal syntax makes no special provision for negative indices in -sequences; however, built-in sequences all provide a :meth:`__getitem__` +:term:`sequences `. However, built-in sequences all provide a :meth:`~object.__getitem__` method that interprets negative indices by adding the length of the sequence -to the index (so that ``x[-1]`` selects the last item of ``x``). The +to the index so that, for example, ``x[-1]`` selects the last item of ``x``. The resulting value must be a nonnegative integer less than the number of items in the sequence, and the subscription selects the item whose index is that value (counting from zero). Since the support for negative indices and slicing @@ -849,14 +889,10 @@ this method will need to explicitly add that support. single: character pair: string; item -A string's items are characters. A character is not a separate data type but a +A :class:`string ` is a special kind of sequence whose items are +*characters*. A character is not a separate data type but a string of exactly one character. -Subscription of certain :term:`classes ` or :term:`types ` -creates a :ref:`generic alias `. -In this case, user-defined classes can support subscription by providing a -:meth:`__class_getitem__` classmethod. - .. _slicings: @@ -1031,10 +1067,20 @@ used in the same call, so in practice this confusion does not often arise. If the syntax ``**expression`` appears in the function call, ``expression`` must evaluate to a :term:`mapping`, the contents of which are treated as -additional keyword arguments. If a keyword is already present -(as an explicit keyword argument, or from another unpacking), +additional keyword arguments. If a parameter matching a key has already been +given a value (by an explicit keyword argument, or from another unpacking), a :exc:`TypeError` exception is raised. +When ``**expression`` is used, each key in this mapping must be +a string. +Each value from the mapping is assigned to the first formal parameter +eligible for keyword assignment whose name is equal to the key. +A key need not be a Python identifier (e.g. ``"max-temp °F"`` is acceptable, +although it will not match any formal parameter that could be declared). +If there is no match to a formal parameter +the key-value pair is collected by the ``**`` parameter, if there is one, +or if there is not, a :exc:`TypeError` exception is raised. + Formal parameters using the syntax ``*identifier`` or ``**identifier`` cannot be used as positional argument slots or as keyword argument names. @@ -1518,7 +1564,7 @@ built-in types. true). * Mappings (instances of :class:`dict`) compare equal if and only if they have - equal `(key, value)` pairs. Equality comparison of the keys and values + equal ``(key, value)`` pairs. Equality comparison of the keys and values enforces reflexivity. Order comparisons (``<``, ``>``, ``<=``, and ``>=``) raise :exc:`TypeError`. @@ -1697,6 +1743,12 @@ returns a boolean value regardless of the type of its argument (for example, ``not 'foo'`` produces ``False`` rather than ``''``.) +.. index:: + single: := (colon equals) + single: assignment expression + single: walrus operator + single: named expression + Assignment expressions ====================== @@ -1722,6 +1774,13 @@ Or, when processing a file stream in chunks: while chunk := file.read(9000): process(chunk) +Assignment expressions must be surrounded by parentheses when used +as sub-expressions in slicing, conditional, lambda, +keyword-argument, and comprehension-if expressions +and in ``assert`` and ``with`` statements. +In all other places where they can be used, parentheses are not required, +including in ``if`` and ``while`` statements. + .. versionadded:: 3.8 See :pep:`572` for more details about assignment expressions. @@ -1856,7 +1915,7 @@ The following table summarizes the operator precedence in Python, from highest precedence (most binding) to lowest precedence (least binding). Operators in the same box have the same precedence. Unless the syntax is explicitly given, operators are binary. Operators in the same box group left to right (except for -exponentiation, which groups from right to left). +exponentiation and conditional expressions, which group from right to left). Note that comparisons, membership tests, and identity tests, all have the same precedence and have a left-to-right chaining feature as described in the @@ -1875,7 +1934,7 @@ precedence and have a left-to-right chaining feature as described in the | ``x[index]``, ``x[index:index]``, | Subscription, slicing, | | ``x(arguments...)``, ``x.attribute`` | call, attribute reference | +-----------------------------------------------+-------------------------------------+ -| :keyword:`await` ``x`` | Await expression | +| :keyword:`await x ` | Await expression | +-----------------------------------------------+-------------------------------------+ | ``**`` | Exponentiation [#]_ | +-----------------------------------------------+-------------------------------------+ @@ -1899,7 +1958,7 @@ precedence and have a left-to-right chaining feature as described in the | :keyword:`is`, :keyword:`is not`, ``<``, | tests and identity tests | | ``<=``, ``>``, ``>=``, ``!=``, ``==`` | | +-----------------------------------------------+-------------------------------------+ -| :keyword:`not` ``x`` | Boolean NOT | +| :keyword:`not x ` | Boolean NOT | +-----------------------------------------------+-------------------------------------+ | :keyword:`and` | Boolean AND | +-----------------------------------------------+-------------------------------------+ diff --git a/Doc/reference/grammar.rst b/Doc/reference/grammar.rst index 59b45005836..bc1db7b039c 100644 --- a/Doc/reference/grammar.rst +++ b/Doc/reference/grammar.rst @@ -12,7 +12,7 @@ and `PEG `_. In particular, ``&`` followed by a symbol, token or parenthesized group indicates a positive lookahead (i.e., is required to match but not consumed), while ``!`` indicates a negative lookahead (i.e., is -required _not_ to match). We use the ``|`` separator to mean PEG's +required *not* to match). We use the ``|`` separator to mean PEG's "ordered choice" (written as ``/`` in traditional PEG grammars). See :pep:`617` for more details on the grammar's syntax. diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index 69e2a947274..b22b5251f1d 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -84,9 +84,9 @@ considered a package. All modules have a name. Subpackage names are separated from their parent package name by a dot, akin to Python's standard attribute access syntax. Thus -you might have a module called :mod:`sys` and a package called :mod:`email`, -which in turn has a subpackage called :mod:`email.mime` and a module within -that subpackage called :mod:`email.mime.text`. +you might have a package called :mod:`email`, which in turn has a subpackage +called :mod:`email.mime` and a module within that subpackage called +:mod:`email.mime.text`. Regular packages @@ -358,7 +358,6 @@ of what happens during the loading portion of import:: sys.modules[spec.name] = module elif not hasattr(spec.loader, 'exec_module'): module = spec.loader.load_module(spec.name) - # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: @@ -490,21 +489,19 @@ submodule. Let's say you have the following directory structure:: spam/ __init__.py foo.py - bar.py -and ``spam/__init__.py`` has the following lines in it:: +and ``spam/__init__.py`` has the following line in it:: from .foo import Foo - from .bar import Bar -then executing the following puts a name binding to ``foo`` and ``bar`` in the +then executing the following puts name bindings for ``foo`` and ``Foo`` in the ``spam`` module:: >>> import spam >>> spam.foo - >>> spam.bar - + >>> spam.Foo + Given Python's familiar name binding rules this might seem surprising, but it's actually a fundamental feature of the import system. The invariant @@ -541,9 +538,13 @@ The import machinery fills in these attributes on each module object during loading, based on the module's spec, before the loader executes the module. +It is **strongly** recommended that you rely on :attr:`__spec__` and +its attributes instead of any of the other individual attributes +listed below. + .. attribute:: __name__ - The ``__name__`` attribute must be set to the fully-qualified name of + The ``__name__`` attribute must be set to the fully qualified name of the module. This name is used to uniquely identify the module in the import system. @@ -554,9 +555,17 @@ the module. for introspection, but can be used for additional loader-specific functionality, for example getting data associated with a loader. + It is **strongly** recommended that you rely on :attr:`__spec__` + instead instead of this attribute. + + .. versionchanged:: 3.12 + The value of ``__loader__`` is expected to be the same as + ``__spec__.loader``. The use of ``__loader__`` is deprecated and slated + for removal in Python 3.14. + .. attribute:: __package__ - The module's ``__package__`` attribute must be set. Its value must + The module's ``__package__`` attribute may be set. Its value must be a string, but it can be the same value as its ``__name__``. When the module is a package, its ``__package__`` value should be set to its ``__name__``. When the module is not a package, ``__package__`` @@ -565,13 +574,25 @@ the module. details. This attribute is used instead of ``__name__`` to calculate explicit - relative imports for main modules, as defined in :pep:`366`. It is - expected to have the same value as ``__spec__.parent``. + relative imports for main modules, as defined in :pep:`366`. + + It is **strongly** recommended that you rely on :attr:`__spec__` + instead instead of this attribute. .. versionchanged:: 3.6 The value of ``__package__`` is expected to be the same as ``__spec__.parent``. + .. versionchanged:: 3.10 + :exc:`ImportWarning` is raised if import falls back to + ``__package__`` instead of + :attr:`~importlib.machinery.ModuleSpec.parent`. + + .. versionchanged:: 3.12 + Raise :exc:`DeprecationWarning` instead of :exc:`ImportWarning` + when falling back to ``__package__``. + + .. attribute:: __spec__ The ``__spec__`` attribute must be set to the module spec that was @@ -580,7 +601,7 @@ the module. interpreter startup `. The one exception is ``__main__``, where ``__spec__`` is :ref:`set to None in some cases `. - When ``__package__`` is not defined, ``__spec__.parent`` is used as + When ``__spec__.parent`` is not set, ``__package__`` is used as a fallback. .. versionadded:: 3.4 @@ -612,18 +633,22 @@ the module. import system may opt to leave it unset if it has no semantic meaning (e.g. a module loaded from a database). - If ``__file__`` is set, it may also be appropriate to set the - ``__cached__`` attribute which is the path to any compiled version of + If ``__file__`` is set then the ``__cached__`` attribute might also + be set, which is the path to any compiled version of the code (e.g. byte-compiled file). The file does not need to exist to set this attribute; the path can simply point to where the compiled file would exist (see :pep:`3147`). - It is also appropriate to set ``__cached__`` when ``__file__`` is not + Note that ``__cached__`` may be set even if ``__file__`` is not set. However, that scenario is quite atypical. Ultimately, the - loader is what makes use of ``__file__`` and/or ``__cached__``. So + loader is what makes use of the module spec provided by the finder + (from which ``__file__`` and ``__cached__`` are derived). So if a loader can load from a cached module but otherwise does not load from a file, that atypical scenario may be appropriate. + It is **strongly** recommended that you rely on :attr:`__spec__` + instead instead of ``__cached__``. + .. _package-path-rules: module.__path__ @@ -677,22 +702,10 @@ Here are the exact rules used: * Otherwise, just use the module's ``__name__`` in the repr. -.. versionchanged:: 3.4 - Use of :meth:`loader.module_repr() ` - has been deprecated and the module spec is now used by the import - machinery to generate a module repr. - - For backward compatibility with Python 3.3, the module repr will be - generated by calling the loader's - :meth:`~importlib.abc.Loader.module_repr` method, if defined, before - trying either approach described above. However, the method is deprecated. - -.. versionchanged:: 3.10 - - Calling :meth:`~importlib.abc.Loader.module_repr` now occurs after trying to - use a module's ``__spec__`` attribute but before falling back on - ``__file__``. Use of :meth:`~importlib.abc.Loader.module_repr` is slated to - stop in Python 3.12. +.. versionchanged:: 3.12 + Use of :meth:`module_repr`, having been deprecated since Python 3.4, was + removed in Python 3.12 and is no longer called during the resolution of a + module's repr. .. _pyc-invalidation: @@ -801,10 +814,8 @@ environment variable and various other installation- and implementation-specific defaults. Entries in :data:`sys.path` can name directories on the file system, zip files, and potentially other "locations" (see the :mod:`site` module) that should be searched for modules, such as -URLs, or database queries. Only strings and bytes should be present on -:data:`sys.path`; all other data types are ignored. The encoding of bytes -entries is determined by the individual :term:`path entry finders `. +URLs, or database queries. Only strings should be present on +:data:`sys.path`; all other data types are ignored. The :term:`path based finder` is a :term:`meta path finder`, so the import machinery begins the :term:`import path` search by calling the path @@ -819,7 +830,7 @@ The path based finder iterates over every entry in the search path, and for each of these, looks for an appropriate :term:`path entry finder` (:class:`~importlib.abc.PathEntryFinder`) for the path entry. Because this can be an expensive operation (e.g. there may be -`stat()` call overheads for this search), the path based finder maintains +``stat()`` call overheads for this search), the path based finder maintains a cache mapping path entries to path entry finders. This cache is maintained in :data:`sys.path_importer_cache` (despite the name, this cache actually stores finder objects rather than being limited to :term:`importer` objects). @@ -1022,25 +1033,6 @@ and ``__main__.__spec__`` is set accordingly, they're still considered to populate the ``__main__`` namespace, and not during normal import. -Open issues -=========== - -XXX It would be really nice to have a diagram. - -XXX * (import_machinery.rst) how about a section devoted just to the -attributes of modules and packages, perhaps expanding upon or supplanting the -related entries in the data model reference page? - -XXX runpy, pkgutil, et al in the library manual should all get "See Also" -links at the top pointing to the new import system section. - -XXX Add more explanation regarding the different ways in which -``__main__`` is initialized? - -XXX Add more info on ``__main__`` quirks/pitfalls (i.e. copy from -:pep:`395`). - - References ========== diff --git a/Doc/reference/introduction.rst b/Doc/reference/introduction.rst index 72e874ee98e..914a11556c9 100644 --- a/Doc/reference/introduction.rst +++ b/Doc/reference/introduction.rst @@ -54,7 +54,7 @@ Jython Python implemented in Java. This implementation can be used as a scripting language for Java applications, or can be used to create applications using the Java class libraries. It is also often used to create tests for Java libraries. - More information can be found at `the Jython website `_. + More information can be found at `the Jython website `_. Python for .NET This implementation actually uses the CPython implementation, but is a managed @@ -66,7 +66,7 @@ IronPython An alternate Python for .NET. Unlike Python.NET, this is a complete Python implementation that generates IL, and compiles Python code directly to .NET assemblies. It was created by Jim Hugunin, the original creator of Jython. For - more information, see `the IronPython website `_. + more information, see `the IronPython website `_. PyPy An implementation of Python written completely in Python. It supports several @@ -74,7 +74,7 @@ PyPy and a Just in Time compiler. One of the goals of the project is to encourage experimentation with the language itself by making it easier to modify the interpreter (since it is written in Python). Additional information is - available on `the PyPy project's home page `_. + available on `the PyPy project's home page `_. Each of these implementations varies in some way from the language as documented in this manual, or introduces specific information beyond what's covered in the diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index b69d0fbdd41..8adb4b74082 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -101,12 +101,11 @@ addition, if the first bytes of the file are the UTF-8 byte-order mark (``b'\xef\xbb\xbf'``), the declared file encoding is UTF-8 (this is supported, among others, by Microsoft's :program:`notepad`). -If an encoding is declared, the encoding name must be recognized by Python. The +If an encoding is declared, the encoding name must be recognized by Python +(see :ref:`standard-encodings`). The encoding is used for all lexical analysis, including string literals, comments and identifiers. -.. XXX there should be a list of supported encodings. - .. _explicit-joining: @@ -316,7 +315,7 @@ The Unicode category codes mentioned above stand for: * *Nd* - decimal numbers * *Pc* - connector punctuations * *Other_ID_Start* - explicit list of characters in `PropList.txt - `_ to support backwards + `_ to support backwards compatibility * *Other_ID_Continue* - likewise @@ -324,8 +323,8 @@ All identifiers are converted into the normal form NFKC while parsing; compariso of identifiers is based on NFKC. A non-normative HTML file listing all valid identifier characters for Unicode -14.0.0 can be found at -https://www.unicode.org/Public/14.0.0/ucd/DerivedCoreProperties.txt +15.0.0 can be found at +https://www.unicode.org/Public/15.0.0/ucd/DerivedCoreProperties.txt .. _keywords: @@ -481,9 +480,11 @@ declaration is given in the source file; see section :ref:`encodings`. In plain English: Both types of literals can be enclosed in matching single quotes (``'``) or double quotes (``"``). They can also be enclosed in matching groups of three single or double quotes (these are generally referred to as -*triple-quoted strings*). The backslash (``\``) character is used to escape -characters that otherwise have a special meaning, such as newline, backslash -itself, or the quote character. +*triple-quoted strings*). The backslash (``\``) character is used to give special +meaning to otherwise ordinary characters like ``n``, which means 'newline' when +escaped (``\n``). It can also be used to escape characters that otherwise have a +special meaning, such as newline, backslash itself, or the quote character. +See :ref:`escape sequences ` below for examples. .. index:: single: b'; bytes literal @@ -542,6 +543,8 @@ retained), except that three unescaped quotes in a row terminate the literal. ( single: \u; escape sequence single: \U; escape sequence +.. _escape-sequences: + Unless an ``'r'`` or ``'R'`` prefix is present, escape sequences in string and bytes literals are interpreted according to rules similar to those used by Standard C. The recognized escape sequences are: @@ -549,7 +552,7 @@ Standard C. The recognized escape sequences are: +-----------------+---------------------------------+-------+ | Escape Sequence | Meaning | Notes | +=================+=================================+=======+ -| ``\newline`` | Backslash and newline ignored | | +| ``\``\ | Backslash and newline ignored | \(1) | +-----------------+---------------------------------+-------+ | ``\\`` | Backslash (``\``) | | +-----------------+---------------------------------+-------+ @@ -571,10 +574,10 @@ Standard C. The recognized escape sequences are: +-----------------+---------------------------------+-------+ | ``\v`` | ASCII Vertical Tab (VT) | | +-----------------+---------------------------------+-------+ -| ``\ooo`` | Character with octal value | (1,3) | +| ``\ooo`` | Character with octal value | (2,4) | | | *ooo* | | +-----------------+---------------------------------+-------+ -| ``\xhh`` | Character with hex value *hh* | (2,3) | +| ``\xhh`` | Character with hex value *hh* | (3,4) | +-----------------+---------------------------------+-------+ Escape sequences only recognized in string literals are: @@ -582,37 +585,57 @@ Escape sequences only recognized in string literals are: +-----------------+---------------------------------+-------+ | Escape Sequence | Meaning | Notes | +=================+=================================+=======+ -| ``\N{name}`` | Character named *name* in the | \(4) | +| ``\N{name}`` | Character named *name* in the | \(5) | | | Unicode database | | +-----------------+---------------------------------+-------+ -| ``\uxxxx`` | Character with 16-bit hex value | \(5) | +| ``\uxxxx`` | Character with 16-bit hex value | \(6) | | | *xxxx* | | +-----------------+---------------------------------+-------+ -| ``\Uxxxxxxxx`` | Character with 32-bit hex value | \(6) | +| ``\Uxxxxxxxx`` | Character with 32-bit hex value | \(7) | | | *xxxxxxxx* | | +-----------------+---------------------------------+-------+ Notes: (1) - As in Standard C, up to three octal digits are accepted. + A backslash can be added at the end of a line to ignore the newline:: + + >>> 'This string will not include \ + ... backslashes or newline characters.' + 'This string will not include backslashes or newline characters.' + + The same result can be achieved using :ref:`triple-quoted strings `, + or parentheses and :ref:`string literal concatenation `. + (2) - Unlike in Standard C, exactly two hex digits are required. + As in Standard C, up to three octal digits are accepted. + + .. versionchanged:: 3.11 + Octal escapes with value larger than ``0o377`` produce a + :exc:`DeprecationWarning`. + + .. versionchanged:: 3.12 + Octal escapes with value larger than ``0o377`` produce a + :exc:`SyntaxWarning`. In a future Python version they will be eventually + a :exc:`SyntaxError`. (3) + Unlike in Standard C, exactly two hex digits are required. + +(4) In a bytes literal, hexadecimal and octal escapes denote the byte with the given value. In a string literal, these escapes denote a Unicode character with the given value. -(4) +(5) .. versionchanged:: 3.3 Support for name aliases [#]_ has been added. -(5) +(6) Exactly four hex digits are required. -(6) +(7) Any Unicode character can be encoded this way. Exactly eight hex digits are required. @@ -627,9 +650,11 @@ escape sequences only recognized in string literals fall into the category of unrecognized escapes for bytes literals. .. versionchanged:: 3.6 - Unrecognized escape sequences produce a :exc:`DeprecationWarning`. In - a future Python version they will be a :exc:`SyntaxWarning` and - eventually a :exc:`SyntaxError`. + Unrecognized escape sequences produce a :exc:`DeprecationWarning`. + + .. versionchanged:: 3.12 + Unrecognized escape sequences produce a :exc:`SyntaxWarning`. In a future + Python version they will be eventually a :exc:`SyntaxError`. Even in a raw literal, quotes can be escaped with a backslash, but the backslash remains in the result; for example, ``r"\""`` is a valid string @@ -749,7 +774,7 @@ the final value of the whole string. Top-level format specifiers may include nested replacement fields. These nested fields may include their own conversion fields and :ref:`format specifiers -`, but may not include more deeply-nested replacement fields. The +`, but may not include more deeply nested replacement fields. The :ref:`format specifier mini-language ` is the same as that used by the :meth:`str.format` method. @@ -994,4 +1019,4 @@ occurrence outside string literals and comments is an unconditional error: .. rubric:: Footnotes -.. [#] https://www.unicode.org/Public/11.0.0/ucd/NameAliases.txt +.. [#] https://www.unicode.org/Public/15.0.0/ucd/NameAliases.txt diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index bb1209dfc33..c98ac81e415 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -124,9 +124,7 @@ square brackets, is recursively defined as follows. * If the target list is a single target with no trailing comma, optionally in parentheses, the object is assigned to that target. -* Else: The object must be an iterable with the same number of - items as there are targets in the target list, and the items are assigned, - from left to right, to the corresponding targets. +* Else: * If the target list contains one target prefixed with an asterisk, called a "starred" target: The object must be an iterable with at least as many items @@ -332,7 +330,7 @@ statement, of a variable or attribute annotation and an optional assignment stat annotated_assignment_stmt: `augtarget` ":" `expression` : ["=" (`starred_expression` | `yield_expression`)] -The difference from normal :ref:`assignment` is that only single target is allowed. +The difference from normal :ref:`assignment` is that only a single target is allowed. For simple names as assignment targets, if in class or module scope, the annotations are evaluated and stored in a special class or module @@ -367,8 +365,8 @@ target, then the interpreter evaluates the target except for the last IDEs. .. versionchanged:: 3.8 - Now annotated assignments allow same expressions in the right hand side as - the regular assignments. Previously, some expressions (like un-parenthesized + Now annotated assignments allow the same expressions in the right hand side as + regular assignments. Previously, some expressions (like un-parenthesized tuple expressions) caused a syntax error. @@ -563,10 +561,10 @@ The :keyword:`!raise` statement .. productionlist:: python-grammar raise_stmt: "raise" [`expression` ["from" `expression`]] -If no expressions are present, :keyword:`raise` re-raises the last exception -that was active in the current scope. If no exception is active in the current -scope, a :exc:`RuntimeError` exception is raised indicating that this is an -error. +If no expressions are present, :keyword:`raise` re-raises the +exception that is currently being handled, which is also known as the *active exception*. +If there isn't currently an active exception, a :exc:`RuntimeError` exception is raised +indicating that this is an error. Otherwise, :keyword:`raise` evaluates the first expression as the exception object. It must be either a subclass or an instance of :class:`BaseException`. @@ -581,8 +579,8 @@ The :dfn:`type` of the exception is the exception instance's class, the A traceback object is normally created automatically when an exception is raised and attached to it as the :attr:`__traceback__` attribute, which is writable. You can create an exception and set your own traceback in one step using the -:meth:`with_traceback` exception method (which returns the same exception -instance, with its traceback set to its argument), like so:: +:meth:`~BaseException.with_traceback` exception method (which returns the +same exception instance, with its traceback set to its argument), like so:: raise Exception("foo occurred").with_traceback(tracebackobj) @@ -614,8 +612,10 @@ exceptions will be printed:: File "", line 4, in RuntimeError: Something bad happened -A similar mechanism works implicitly if an exception is raised inside an -exception handler or a :keyword:`finally` clause: the previous exception is then +A similar mechanism works implicitly if a new exception is raised when +an exception is already being handled. An exception may be handled +when an :keyword:`except` or :keyword:`finally` clause, or a +:keyword:`with` statement, is used. The previous exception is then attached as the new exception's :attr:`__context__` attribute:: >>> try: @@ -655,6 +655,12 @@ and information about handling exceptions is in section :ref:`try`. The ``__suppress_context__`` attribute to suppress automatic display of the exception context. +.. versionchanged:: 3.11 + If the traceback of the active exception is modified in an :keyword:`except` + clause, a subsequent ``raise`` statement re-raises the exception with the + modified traceback. Previously, the exception was re-raised with the + traceback it had when it was caught. + .. _break: The :keyword:`!break` statement @@ -750,7 +756,7 @@ commas) the two steps are carried out separately for each clause, just as though the clauses had been separated out into individual import statements. -The details of the first step, finding and loading modules are described in +The details of the first step, finding and loading modules, are described in greater detail in the section on the :ref:`import system `, which also describes the various types of packages and modules that can be imported, as well as all the hooks that can be used to customize @@ -795,9 +801,9 @@ The :keyword:`from` form uses a slightly more complex process: Examples:: import foo # foo imported and bound locally - import foo.bar.baz # foo.bar.baz imported, foo bound locally - import foo.bar.baz as fbb # foo.bar.baz imported and bound as fbb - from foo.bar import baz # foo.bar.baz imported and bound as baz + import foo.bar.baz # foo, foo.bar, and foo.bar.baz imported, foo bound locally + import foo.bar.baz as fbb # foo, foo.bar, and foo.bar.baz imported, foo.bar.baz bound as fbb + from foo.bar import baz # foo, foo.bar, and foo.bar.baz imported, foo.bar.baz bound as baz from foo import attr # foo imported and foo.attr bound as attr .. index:: single: * (asterisk); import statement @@ -988,20 +994,12 @@ The :keyword:`!nonlocal` statement .. productionlist:: python-grammar nonlocal_stmt: "nonlocal" `identifier` ("," `identifier`)* -.. XXX add when implemented - : ["=" (`target_list` "=")+ starred_expression] - : | "nonlocal" identifier augop expression_list - The :keyword:`nonlocal` statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope excluding globals. This is important because the default behavior for binding is to search the local namespace first. The statement allows encapsulated code to rebind variables outside of the local scope besides the global (module) scope. -.. XXX not implemented - The :keyword:`nonlocal` statement may prepend an assignment or augmented - assignment, but not an expression. - Names listed in a :keyword:`nonlocal` statement, unlike those listed in a :keyword:`global` statement, must refer to pre-existing bindings in an enclosing scope (the scope in which a new binding should be created cannot diff --git a/Doc/requirements.txt b/Doc/requirements.txt index 785da2c3217..134f39d6d7b 100644 --- a/Doc/requirements.txt +++ b/Doc/requirements.txt @@ -3,10 +3,13 @@ # Sphinx version is pinned so that new versions that introduce new warnings # won't suddenly cause build failures. Updating the version is fine as long # as no warnings are raised by doing so. -sphinx==4.2.0 +sphinx==4.5.0 blurb +sphinx-lint==0.6.7 +sphinxext-opengraph>=0.7.1 + # The theme used by the documentation is stored separately, so we need # to install that as well. -python-docs-theme +python-docs-theme>=2022.1 diff --git a/Doc/runtime.txt b/Doc/runtime.txt deleted file mode 100644 index 548d71365f0..00000000000 --- a/Doc/runtime.txt +++ /dev/null @@ -1 +0,0 @@ -3.7 \ No newline at end of file diff --git a/Doc/tools/extensions/asdl_highlight.py b/Doc/tools/extensions/asdl_highlight.py index b1989e53957..42863a4b3bc 100644 --- a/Doc/tools/extensions/asdl_highlight.py +++ b/Doc/tools/extensions/asdl_highlight.py @@ -1,4 +1,3 @@ -import os import sys from pathlib import Path @@ -6,7 +5,7 @@ CPYTHON_ROOT = Path(__file__).resolve().parent.parent.parent.parent sys.path.append(str(CPYTHON_ROOT / "Parser")) from pygments.lexer import RegexLexer, bygroups, include, words -from pygments.token import (Comment, Generic, Keyword, Name, Operator, +from pygments.token import (Comment, Keyword, Name, Operator, Punctuation, Text) from asdl import builtin_types diff --git a/Doc/tools/extensions/c_annotations.py b/Doc/tools/extensions/c_annotations.py index 489f06613eb..9defb24a033 100644 --- a/Doc/tools/extensions/c_annotations.py +++ b/Doc/tools/extensions/c_annotations.py @@ -36,6 +36,7 @@ REST_ROLE_MAP = { 'type': 'type', 'macro': 'macro', 'type': 'type', + 'member': 'member', } @@ -100,6 +101,12 @@ class Annotations: # Stable ABI annotation. These have two forms: # Part of the [Stable ABI](link). # Part of the [Stable ABI](link) since version X.Y. + # For structs, there's some more info in the message: + # Part of the [Limited API](link) (as an opaque struct). + # Part of the [Stable ABI](link) (including all members). + # Part of the [Limited API](link) (Only some members are part + # of the stable ABI.). + # ... all of which can have "since version X.Y" appended. record = self.stable_abi_data.get(name) if record: if record['role'] != objtype: @@ -113,15 +120,27 @@ class Annotations: ref_node = addnodes.pending_xref( 'Stable ABI', refdomain="std", reftarget='stable', reftype='ref', refexplicit="False") - ref_node += nodes.Text('Stable ABI') + struct_abi_kind = record['struct_abi_kind'] + if struct_abi_kind in {'opaque', 'members'}: + ref_node += nodes.Text('Limited API') + else: + ref_node += nodes.Text('Stable ABI') emph_node += ref_node + if struct_abi_kind == 'opaque': + emph_node += nodes.Text(' (as an opaque struct)') + elif struct_abi_kind == 'full-abi': + emph_node += nodes.Text(' (including all members)') if record['ifdef_note']: emph_node += nodes.Text(' ' + record['ifdef_note']) if stable_added == '3.2': # Stable ABI was introduced in 3.2. - emph_node += nodes.Text('.') + pass else: - emph_node += nodes.Text(f' since version {stable_added}.') + emph_node += nodes.Text(f' since version {stable_added}') + emph_node += nodes.Text('.') + if struct_abi_kind == 'members': + emph_node += nodes.Text( + ' (Only some members are part of the stable ABI.)') node.insert(0, emph_node) # Return value annotation diff --git a/Doc/tools/extensions/escape4chm.py b/Doc/tools/extensions/escape4chm.py index e9999716251..89970975b90 100644 --- a/Doc/tools/extensions/escape4chm.py +++ b/Doc/tools/extensions/escape4chm.py @@ -5,6 +5,7 @@ effect on some MBCS Windows systems. https://bugs.python.org/issue32174 """ +import pathlib import re from html.entities import codepoint2name @@ -39,12 +40,12 @@ def fixup_keywords(app, exception): return getLogger(__name__).info('fixing HTML escapes in keywords file...') - outdir = app.builder.outdir + outdir = pathlib.Path(app.builder.outdir) outname = app.builder.config.htmlhelp_basename - with app.builder.open_file(outdir, outname + '.hhk', 'r') as f: + with open(outdir / (outname + '.hhk'), 'rb') as f: index = f.read() - with app.builder.open_file(outdir, outname + '.hhk', 'w') as f: - f.write(index.replace(''', ''')) + with open(outdir / (outname + '.hhk'), 'wb') as f: + f.write(index.replace(b''', b''')) def setup(app): # `html-page-context` event emitted when the HTML builder has diff --git a/Doc/tools/extensions/peg_highlight.py b/Doc/tools/extensions/peg_highlight.py index 42101be10ea..4bdc2ee1861 100644 --- a/Doc/tools/extensions/peg_highlight.py +++ b/Doc/tools/extensions/peg_highlight.py @@ -1,5 +1,5 @@ from pygments.lexer import RegexLexer, bygroups, include -from pygments.token import Comment, Generic, Keyword, Name, Operator, Punctuation, Text +from pygments.token import Comment, Keyword, Name, Operator, Punctuation, Text from sphinx.highlighting import lexers @@ -56,8 +56,8 @@ class PEGLexer(RegexLexer): (_name + _text_ws + r"(\[[\w\d_\*]+?\])" + _text_ws + "(=)", bygroups(None, None, None, None, None),), ], "invalids": [ - (r"^(\s+\|\s+invalid_\w+\s*\n)", bygroups(None)), - (r"^(\s+\|\s+incorrect_\w+\s*\n)", bygroups(None)), + (r"^(\s+\|\s+.*invalid_\w+.*\n)", bygroups(None)), + (r"^(\s+\|\s+.*incorrect_\w+.*\n)", bygroups(None)), (r"^(#.*invalid syntax.*(?:.|\n)*)", bygroups(None),), ], "root": [ diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index ff522c98d0f..db7bb3b4421 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -26,11 +26,10 @@ try: from sphinx.errors import NoUri except ImportError: from sphinx.environment import NoUri -from sphinx.locale import translators +from sphinx.locale import _ as sphinx_gettext from sphinx.util import status_iterator, logging from sphinx.util.nodes import split_explicit_title from sphinx.writers.text import TextWriter, TextTranslator -from sphinx.writers.latex import LaTeXTranslator try: from sphinx.domains.python import PyFunction, PyMethod @@ -38,12 +37,9 @@ except ImportError: from sphinx.domains.python import PyClassmember as PyMethod from sphinx.domains.python import PyModulelevel as PyFunction -# Support for checking for suspicious markup -import suspicious - - -ISSUE_URI = 'https://bugs.python.org/issue%s' +ISSUE_URI = 'https://bugs.python.org/issue?@action=redirect&bpo=%s' +GH_ISSUE_URI = 'https://github.com/python/cpython/issues/%s' SOURCE_URI = 'https://github.com/python/cpython/tree/main/%s' # monkey-patch reST parser to disable alphabetic and roman enumerated lists @@ -58,11 +54,33 @@ Body.enum.converters['loweralpha'] = \ def issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): issue = utils.unescape(text) + # sanity check: there are no bpo issues within these two values + if 47261 < int(issue) < 400000: + msg = inliner.reporter.error(f'The BPO ID {text!r} seems too high -- ' + 'use :gh:`...` for GitHub IDs', line=lineno) + prb = inliner.problematic(rawtext, rawtext, msg) + return [prb], [msg] text = 'bpo-' + issue refnode = nodes.reference(text, text, refuri=ISSUE_URI % issue) return [refnode], [] +# Support for marking up and linking to GitHub issues + +def gh_issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): + issue = utils.unescape(text) + # sanity check: all GitHub issues have ID >= 32426 + # even though some of them are also valid BPO IDs + if int(issue) < 32426: + msg = inliner.reporter.error(f'The GitHub ID {text!r} seems too low -- ' + 'use :issue:`...` for BPO IDs', line=lineno) + prb = inliner.problematic(rawtext, rawtext, msg) + return [prb], [msg] + text = 'gh-' + issue + refnode = nodes.reference(text, text, refuri=GH_ISSUE_URI % issue) + return [refnode], [] + + # Support for linking to Python source files easily def source_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): @@ -78,33 +96,24 @@ def source_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): class ImplementationDetail(Directive): has_content = True - required_arguments = 0 - optional_arguments = 1 final_argument_whitespace = True # This text is copied to templates/dummy.html label_text = 'CPython implementation detail:' def run(self): + self.assert_has_content() pnode = nodes.compound(classes=['impl-detail']) - label = translators['sphinx'].gettext(self.label_text) + label = sphinx_gettext(self.label_text) content = self.content add_text = nodes.strong(label, label) - if self.arguments: - n, m = self.state.inline_text(self.arguments[0], self.lineno) - pnode.append(nodes.paragraph('', '', *(n + m))) self.state.nested_parse(content, self.content_offset, pnode) - if pnode.children and isinstance(pnode[0], nodes.paragraph): - content = nodes.inline(pnode[0].rawsource, translatable=True) - content.source = pnode[0].source - content.line = pnode[0].line - content += pnode[0].children - pnode[0].replace_self(nodes.paragraph('', '', content, - translatable=False)) - pnode[0].insert(0, add_text) - pnode[0].insert(1, nodes.Text(' ')) - else: - pnode.insert(0, nodes.paragraph('', '', add_text)) + content = nodes.inline(pnode[0].rawsource, translatable=True) + content.source = pnode[0].source + content.line = pnode[0].line + content += pnode[0].children + pnode[0].replace_self(nodes.paragraph( + '', '', add_text, nodes.Text(' '), content, translatable=False)) return [pnode] @@ -112,11 +121,22 @@ class ImplementationDetail(Directive): class Availability(Directive): - has_content = False + has_content = True required_arguments = 1 optional_arguments = 0 final_argument_whitespace = True + # known platform, libc, and threading implementations + known_platforms = frozenset({ + "AIX", "Android", "BSD", "DragonFlyBSD", "Emscripten", "FreeBSD", + "Linux", "NetBSD", "OpenBSD", "POSIX", "Solaris", "Unix", "VxWorks", + "WASI", "Windows", "macOS", + # libc + "BSD libc", "glibc", "musl", + # POSIX platforms with pthreads + "pthreads", + }) + def run(self): availability_ref = ':ref:`Availability `: ' pnode = nodes.paragraph(availability_ref + self.arguments[0], @@ -125,8 +145,51 @@ class Availability(Directive): pnode.extend(n + m) n, m = self.state.inline_text(self.arguments[0], self.lineno) pnode.extend(n + m) + if self.content: + self.state.nested_parse(self.content, self.content_offset, pnode) + + self.parse_platforms() + return [pnode] + def parse_platforms(self): + """Parse platform information from arguments + + Arguments is a comma-separated string of platforms. A platform may + be prefixed with "not " to indicate that a feature is not available. + + Example:: + + .. availability:: Windows, Linux >= 4.2, not Emscripten, not WASI + + Arguments like "Linux >= 3.17 with glibc >= 2.27" are currently not + parsed into separate tokens. + """ + platforms = {} + for arg in self.arguments[0].rstrip(".").split(","): + arg = arg.strip() + platform, _, version = arg.partition(" >= ") + if platform.startswith("not "): + version = False + platform = platform[4:] + elif not version: + version = True + platforms[platform] = version + + unknown = set(platforms).difference(self.known_platforms) + if unknown: + cls = type(self) + logger = logging.getLogger(cls.__qualname__) + logger.warn( + f"Unknown platform(s) or syntax '{' '.join(sorted(unknown))}' " + f"in '.. availability:: {self.arguments[0]}', see " + f"{__file__}:{cls.__qualname__}.known_platforms for a set " + "known platforms." + ) + + return platforms + + # Support for documenting audit event @@ -189,7 +252,7 @@ class AuditEvent(Directive): else: args = [] - label = translators['sphinx'].gettext(self._label[min(2, len(args))]) + label = sphinx_gettext(self._label[min(2, len(args))]) text = label.format(name="``{}``".format(name), args=", ".join("``{}``".format(a) for a in args if a)) @@ -368,7 +431,7 @@ class DeprecatedRemoved(Directive): else: label = self._removed_label - label = translators['sphinx'].gettext(label) + label = sphinx_gettext(label) text = label.format(deprecated=self.arguments[0], removed=self.arguments[1]) if len(self.arguments) == 3: inodes, messages = self.state.inline_text(self.arguments[2], @@ -395,18 +458,14 @@ class DeprecatedRemoved(Directive): translatable=False) node.append(para) env = self.state.document.settings.env - # deprecated pre-Sphinx-2 method - if hasattr(env, 'note_versionchange'): - env.note_versionchange('deprecated', version[0], node, self.lineno) - # new method - else: - env.get_domain('changeset').note_changeset(node) + env.get_domain('changeset').note_changeset(node) return [node] + messages # Support for including Misc/NEWS -issue_re = re.compile('(?:[Ii]ssue #|bpo-)([0-9]+)') +issue_re = re.compile('(?:[Ii]ssue #|bpo-)([0-9]+)', re.I) +gh_issue_re = re.compile('(?:gh-issue-|gh-)([0-9]+)', re.I) whatsnew_re = re.compile(r"(?im)^what's new in (.*?)\??$") @@ -433,8 +492,9 @@ class MiscNews(Directive): text = 'The NEWS file is not available.' node = nodes.strong(text, text) return [node] - content = issue_re.sub(r'`bpo-\1 `__', - content) + content = issue_re.sub(r':issue:`\1`', content) + # Fallback handling for the GitHub issue + content = gh_issue_re.sub(r':gh:`\1`', content) content = whatsnew_re.sub(r'\1', content) # remove first 3 lines as they are the main heading lines = ['.. default-role:: obj', ''] + content.splitlines()[3:] @@ -614,6 +674,7 @@ def process_audit_events(app, doctree, fromdocname): def setup(app): app.add_role('issue', issue_role) + app.add_role('gh', gh_issue_role) app.add_role('source', source_role) app.add_directive('impl-detail', ImplementationDetail) app.add_directive('availability', Availability) @@ -621,7 +682,6 @@ def setup(app): app.add_directive('audit-event-table', AuditEventListDirective) app.add_directive('deprecated-removed', DeprecatedRemoved) app.add_builder(PydocTopicsBuilder) - app.add_builder(suspicious.CheckSuspiciousMarkupBuilder) app.add_object_type('opcode', 'opcode', '%s (opcode)', parse_opcode_signature) app.add_object_type('pdbcommand', 'pdbcmd', '%s (pdb command)', parse_pdb_command) app.add_object_type('2to3fixer', '2to3fixer', '%s (2to3 fixer)') diff --git a/Doc/tools/extensions/suspicious.py b/Doc/tools/extensions/suspicious.py deleted file mode 100644 index c3de4d79c83..00000000000 --- a/Doc/tools/extensions/suspicious.py +++ /dev/null @@ -1,278 +0,0 @@ -""" -Try to detect suspicious constructs, resembling markup -that has leaked into the final output. - -Suspicious lines are reported in a comma-separated-file, -``suspicious.csv``, located in the output directory. - -The file is utf-8 encoded, and each line contains four fields: - - * document name (normalized) - * line number in the source document - * problematic text - * complete line showing the problematic text in context - -It is common to find many false positives. To avoid reporting them -again and again, they may be added to the ``ignored.csv`` file -(located in the configuration directory). The file has the same -format as ``suspicious.csv`` with a few differences: - - - each line defines a rule; if the rule matches, the issue - is ignored. - - line number may be empty (that is, nothing between the - commas: ",,"). In this case, line numbers are ignored (the - rule matches anywhere in the file). - - the last field does not have to be a complete line; some - surrounding text (never more than a line) is enough for - context. - -Rules are processed sequentially. A rule matches when: - - * document names are the same - * problematic texts are the same - * line numbers are close to each other (5 lines up or down) - * the rule text is completely contained into the source line - -The simplest way to create the ignored.csv file is by copying -undesired entries from suspicious.csv (possibly trimming the last -field.) - -Copyright 2009 Gabriel A. Genellina - -""" - -import os -import re -import csv -import sys - -from docutils import nodes -from sphinx.builders import Builder -import sphinx.util - -detect_all = re.compile(r''' - ::(?=[^=])| # two :: (but NOT ::=) - :[a-zA-Z][a-zA-Z0-9]+| # :foo - `| # ` (seldom used by itself) - (?= (3, 0) - - -class Rule: - def __init__(self, docname, lineno, issue, line): - """A rule for ignoring issues""" - self.docname = docname # document to which this rule applies - self.lineno = lineno # line number in the original source; - # this rule matches only near that. - # None -> don't care - self.issue = issue # the markup fragment that triggered this rule - self.line = line # text of the container element (single line only) - self.used = False - - def __repr__(self): - return '{0.docname},,{0.issue},{0.line}'.format(self) - - - -class dialect(csv.excel): - """Our dialect: uses only linefeed as newline.""" - lineterminator = '\n' - - -class CheckSuspiciousMarkupBuilder(Builder): - """ - Checks for possibly invalid markup that may leak into the output. - """ - name = 'suspicious' - logger = sphinx.util.logging.getLogger("CheckSuspiciousMarkupBuilder") - - def init(self): - # create output file - self.log_file_name = os.path.join(self.outdir, 'suspicious.csv') - open(self.log_file_name, 'w').close() - # load database of previously ignored issues - self.load_rules(os.path.join(os.path.dirname(__file__), '..', - 'susp-ignored.csv')) - - def get_outdated_docs(self): - return self.env.found_docs - - def get_target_uri(self, docname, typ=None): - return '' - - def prepare_writing(self, docnames): - pass - - def write_doc(self, docname, doctree): - # set when any issue is encountered in this document - self.any_issue = False - self.docname = docname - visitor = SuspiciousVisitor(doctree, self) - doctree.walk(visitor) - - def finish(self): - unused_rules = [rule for rule in self.rules if not rule.used] - if unused_rules: - self.logger.warning( - 'Found %s/%s unused rules: %s' % ( - len(unused_rules), len(self.rules), - '\n'.join(repr(rule) for rule in unused_rules), - ) - ) - return - - def check_issue(self, line, lineno, issue): - if not self.is_ignored(line, lineno, issue): - self.report_issue(line, lineno, issue) - - def is_ignored(self, line, lineno, issue): - """Determine whether this issue should be ignored.""" - docname = self.docname - for rule in self.rules: - if rule.docname != docname: continue - if rule.issue != issue: continue - # Both lines must match *exactly*. This is rather strict, - # and probably should be improved. - # Doing fuzzy matches with levenshtein distance could work, - # but that means bringing other libraries... - # Ok, relax that requirement: just check if the rule fragment - # is contained in the document line - if rule.line not in line: continue - # Check both line numbers. If they're "near" - # this rule matches. (lineno=None means "don't care") - if (rule.lineno is not None) and \ - abs(rule.lineno - lineno) > 5: continue - # if it came this far, the rule matched - rule.used = True - return True - return False - - def report_issue(self, text, lineno, issue): - self.any_issue = True - self.write_log_entry(lineno, issue, text) - if py3: - self.logger.warning('[%s:%d] "%s" found in "%-.120s"' % - (self.docname, lineno, issue, text)) - else: - self.logger.warning( - '[%s:%d] "%s" found in "%-.120s"' % ( - self.docname.encode(sys.getdefaultencoding(),'replace'), - lineno, - issue.encode(sys.getdefaultencoding(),'replace'), - text.strip().encode(sys.getdefaultencoding(),'replace'))) - self.app.statuscode = 1 - - def write_log_entry(self, lineno, issue, text): - if py3: - f = open(self.log_file_name, 'a') - writer = csv.writer(f, dialect) - writer.writerow([self.docname, lineno, issue, text.strip()]) - f.close() - else: - f = open(self.log_file_name, 'ab') - writer = csv.writer(f, dialect) - writer.writerow([self.docname.encode('utf-8'), - lineno, - issue.encode('utf-8'), - text.strip().encode('utf-8')]) - f.close() - - def load_rules(self, filename): - """Load database of previously ignored issues. - - A csv file, with exactly the same format as suspicious.csv - Fields: document name (normalized), line number, issue, surrounding text - """ - self.logger.info("loading ignore rules... ", nonl=1) - self.rules = rules = [] - try: - if py3: - f = open(filename, 'r') - else: - f = open(filename, 'rb') - except IOError: - return - for i, row in enumerate(csv.reader(f)): - if len(row) != 4: - raise ValueError( - "wrong format in %s, line %d: %s" % (filename, i+1, row)) - docname, lineno, issue, text = row - if lineno: - lineno = int(lineno) - else: - lineno = None - if not py3: - docname = docname.decode('utf-8') - issue = issue.decode('utf-8') - text = text.decode('utf-8') - rule = Rule(docname, lineno, issue, text) - rules.append(rule) - f.close() - self.logger.info('done, %d rules loaded' % len(self.rules)) - - -def get_lineno(node): - """Obtain line number information for a node.""" - lineno = None - while lineno is None and node: - node = node.parent - lineno = node.line - return lineno - - -def extract_line(text, index): - """text may be a multiline string; extract - only the line containing the given character index. - - >>> extract_line("abc\ndefgh\ni", 6) - >>> 'defgh' - >>> for i in (0, 2, 3, 4, 10): - ... print extract_line("abc\ndefgh\ni", i) - abc - abc - abc - defgh - defgh - i - """ - p = text.rfind('\n', 0, index) + 1 - q = text.find('\n', index) - if q < 0: - q = len(text) - return text[p:q] - - -class SuspiciousVisitor(nodes.GenericNodeVisitor): - - lastlineno = 0 - - def __init__(self, document, builder): - nodes.GenericNodeVisitor.__init__(self, document) - self.builder = builder - - def default_visit(self, node): - if isinstance(node, (nodes.Text, nodes.image)): # direct text containers - text = node.astext() - # lineno seems to go backwards sometimes (?) - self.lastlineno = lineno = max(get_lineno(node) or 0, self.lastlineno) - seen = set() # don't report the same issue more than only once per line - for match in detect_all(text): - issue = match.group() - line = extract_line(text, match.start()) - if (issue, line) not in seen: - self.builder.check_issue(line, lineno, issue) - seen.add((issue, line)) - - unknown_visit = default_visit - - def visit_document(self, node): - self.lastlineno = 0 - - def visit_comment(self, node): - # ignore comments -- too much false positives. - # (although doing this could miss some errors; - # there were two sections "commented-out" by mistake - # in the Python docs that would not be caught) - raise nodes.SkipNode diff --git a/Doc/tools/rstlint.py b/Doc/tools/rstlint.py deleted file mode 100755 index 33cbaadfce9..00000000000 --- a/Doc/tools/rstlint.py +++ /dev/null @@ -1,403 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# Check for stylistic and formal issues in .rst and .py -# files included in the documentation. -# -# 01/2009, Georg Brandl - -# TODO: - wrong versions in versionadded/changed -# - wrong markup after versionchanged directive - -import os -import re -import sys -import getopt -from string import ascii_letters -from os.path import join, splitext, abspath, exists -from collections import defaultdict - -directives = [ - # standard docutils ones - 'admonition', 'attention', 'caution', 'class', 'compound', 'container', - 'contents', 'csv-table', 'danger', 'date', 'default-role', 'epigraph', - 'error', 'figure', 'footer', 'header', 'highlights', 'hint', 'image', - 'important', 'include', 'line-block', 'list-table', 'meta', 'note', - 'parsed-literal', 'pull-quote', 'raw', 'replace', - 'restructuredtext-test-directive', 'role', 'rubric', 'sectnum', 'sidebar', - 'table', 'target-notes', 'tip', 'title', 'topic', 'unicode', 'warning', - # Sphinx and Python docs custom ones - 'acks', 'attribute', 'autoattribute', 'autoclass', 'autodata', - 'autoexception', 'autofunction', 'automethod', 'automodule', - 'availability', 'centered', 'cfunction', 'class', 'classmethod', 'cmacro', - 'cmdoption', 'cmember', 'code-block', 'confval', 'cssclass', 'ctype', - 'currentmodule', 'cvar', 'data', 'decorator', 'decoratormethod', - 'deprecated-removed', 'deprecated(?!-removed)', 'describe', 'directive', - 'doctest', 'envvar', 'event', 'exception', 'function', 'glossary', - 'highlight', 'highlightlang', 'impl-detail', 'index', 'literalinclude', - 'method', 'miscnews', 'module', 'moduleauthor', 'opcode', 'pdbcommand', - 'productionlist', 'program', 'role', 'sectionauthor', 'seealso', - 'sourcecode', 'staticmethod', 'tabularcolumns', 'testcode', 'testoutput', - 'testsetup', 'toctree', 'todo', 'todolist', 'versionadded', - 'versionchanged' -] - -roles = [ - "(? 81: - # don't complain about tables, links and function signatures - if line.lstrip()[0] not in '+|' and \ - 'http://' not in line and \ - not line.lstrip().startswith(('.. function', - '.. method', - '.. cfunction')): - yield lno+1, "line too long" - - -@checker('.html', severity=2, falsepositives=True) -def check_leaked_markup(fn, lines): - """Check HTML files for leaked reST markup; this only works if - the HTML files have been built. - """ - for lno, line in enumerate(lines): - if leaked_markup_re.search(line): - yield lno+1, 'possibly leaked markup: %r' % line - - -def hide_literal_blocks(lines): - """Tool to remove literal blocks from given lines. - - It yields empty lines in place of blocks, so line numbers are - still meaningful. - """ - in_block = False - for line in lines: - if line.endswith("::\n"): - in_block = True - elif in_block: - if line == "\n" or line.startswith(" "): - line = "\n" - else: - in_block = False - yield line - - -def type_of_explicit_markup(line): - if re.match(fr'\.\. {all_directives}::', line): - return 'directive' - if re.match(r'\.\. \[[0-9]+\] ', line): - return 'footnote' - if re.match(r'\.\. \[[^\]]+\] ', line): - return 'citation' - if re.match(r'\.\. _.*[^_]: ', line): - return 'target' - if re.match(r'\.\. \|[^\|]*\| ', line): - return 'substitution_definition' - return 'comment' - - -def hide_comments(lines): - """Tool to remove comments from given lines. - - It yields empty lines in place of comments, so line numbers are - still meaningful. - """ - in_multiline_comment = False - for line in lines: - if line == "..\n": - in_multiline_comment = True - elif in_multiline_comment: - if line == "\n" or line.startswith(" "): - line = "\n" - else: - in_multiline_comment = False - if line.startswith(".. ") and type_of_explicit_markup(line) == 'comment': - line = "\n" - yield line - - - -@checker(".rst", severity=2) -def check_missing_surrogate_space_on_plural(fn, lines): - r"""Check for missing 'backslash-space' between a code sample a letter. - - Good: ``Point``\ s - Bad: ``Point``s - """ - in_code_sample = False - check_next_one = False - for lno, line in enumerate(hide_comments(hide_literal_blocks(lines))): - tokens = line.split("``") - for token_no, token in enumerate(tokens): - if check_next_one: - if token[0] in ascii_letters: - yield lno + 1, f"Missing backslash-space between code sample and {token!r}." - check_next_one = False - if token_no == len(tokens) - 1: - continue - if in_code_sample: - check_next_one = True - in_code_sample = not in_code_sample - -def main(argv): - usage = '''\ -Usage: %s [-v] [-f] [-s sev] [-i path]* [path] - -Options: -v verbose (print all checked file names) - -f enable checkers that yield many false positives - -s sev only show problems with severity >= sev - -i path ignore subdir or file path -''' % argv[0] - try: - gopts, args = getopt.getopt(argv[1:], 'vfs:i:') - except getopt.GetoptError: - print(usage) - return 2 - - verbose = False - severity = 1 - ignore = [] - falsepos = False - for opt, val in gopts: - if opt == '-v': - verbose = True - elif opt == '-f': - falsepos = True - elif opt == '-s': - severity = int(val) - elif opt == '-i': - ignore.append(abspath(val)) - - if len(args) == 0: - path = '.' - elif len(args) == 1: - path = args[0] - else: - print(usage) - return 2 - - if not exists(path): - print('Error: path %s does not exist' % path) - return 2 - - count = defaultdict(int) - - for root, dirs, files in os.walk(path): - # ignore subdirs in ignore list - if abspath(root) in ignore: - del dirs[:] - continue - - for fn in files: - fn = join(root, fn) - if fn[:2] == './': - fn = fn[2:] - - # ignore files in ignore list - if abspath(fn) in ignore: - continue - - ext = splitext(fn)[1] - checkerlist = checkers.get(ext, None) - if not checkerlist: - continue - - if verbose: - print('Checking %s...' % fn) - - try: - with open(fn, 'r', encoding='utf-8') as f: - lines = list(f) - except (IOError, OSError) as err: - print('%s: cannot open: %s' % (fn, err)) - count[4] += 1 - continue - - for checker in checkerlist: - if checker.falsepositives and not falsepos: - continue - csev = checker.severity - if csev >= severity: - for lno, msg in checker(fn, lines): - print('[%d] %s:%d: %s' % (csev, fn, lno, msg)) - count[csev] += 1 - if verbose: - print() - if not count: - if severity > 1: - print('No problems with severity >= %d found.' % severity) - else: - print('No problems found.') - else: - for severity in sorted(count): - number = count[severity] - print('%d problem%s with severity %d found.' % - (number, number > 1 and 's' or '', severity)) - return int(bool(count)) - - -if __name__ == '__main__': - sys.exit(main(sys.argv)) diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv deleted file mode 100644 index 280e9a63cdc..00000000000 --- a/Doc/tools/susp-ignored.csv +++ /dev/null @@ -1,383 +0,0 @@ -c-api/arg,,:ref,"PyArg_ParseTuple(args, ""O|O:ref"", &object, &callback)" -c-api/list,,:high,list[low:high] -c-api/sequence,,:i2,del o[i1:i2] -c-api/sequence,,:i2,o[i1:i2] -c-api/tuple,,:high,p[low:high] -c-api/unicode,,:end,str[start:end] -c-api/unicode,,:start,unicode[start:start+length] -distutils/examples,,`,This is the description of the ``foobar`` package. -distutils/setupscript,,::, -extending/embedding,,:numargs,"if(!PyArg_ParseTuple(args, "":numargs""))" -extending/extending,,:myfunction,"PyArg_ParseTuple(args, ""D:myfunction"", &c);" -extending/extending,,:set,"if (PyArg_ParseTuple(args, ""O:set_callback"", &temp)) {" -extending/newtypes,,:call,"if (!PyArg_ParseTuple(args, ""sss:call"", &arg1, &arg2, &arg3)) {" -faq/programming,,:chr,">=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr(" -faq/programming,,:reduce,"print((lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y," -faq/programming,,:reduce,"Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro," -faq/windows,,:d48eceb,"Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32" -howto/curses,,:black,"colors when it activates color mode. They are: 0:black, 1:red," -howto/curses,,:red,"colors when it activates color mode. They are: 0:black, 1:red," -howto/curses,,:green,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white. The" -howto/curses,,:yellow,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white. The" -howto/curses,,:blue,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white. The" -howto/curses,,:magenta,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white. The" -howto/curses,,:cyan,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white. The" -howto/curses,,:white,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white. The" -howto/descriptor,,:root,"INFO:root" -howto/descriptor,,:Updating,"root:Updating" -howto/descriptor,,:Accessing,"root:Accessing" -howto/instrumentation,,::,python$target:::function-entry -howto/instrumentation,,:function,python$target:::function-entry -howto/instrumentation,,::,python$target:::function-return -howto/instrumentation,,:function,python$target:::function-return -howto/instrumentation,,:call,156641360502280 function-entry:call_stack.py:start:23 -howto/instrumentation,,:start,156641360502280 function-entry:call_stack.py:start:23 -howto/instrumentation,,:function,156641360518804 function-entry: call_stack.py:function_1:1 -howto/instrumentation,,:function,156641360532797 function-entry: call_stack.py:function_3:9 -howto/instrumentation,,:function,156641360546807 function-return: call_stack.py:function_3:10 -howto/instrumentation,,:function,156641360563367 function-return: call_stack.py:function_1:2 -howto/instrumentation,,:function,156641360578365 function-entry: call_stack.py:function_2:5 -howto/instrumentation,,:function,156641360591757 function-entry: call_stack.py:function_1:1 -howto/instrumentation,,:function,156641360605556 function-entry: call_stack.py:function_3:9 -howto/instrumentation,,:function,156641360617482 function-return: call_stack.py:function_3:10 -howto/instrumentation,,:function,156641360629814 function-return: call_stack.py:function_1:2 -howto/instrumentation,,:function,156641360642285 function-return: call_stack.py:function_2:6 -howto/instrumentation,,:function,156641360656770 function-entry: call_stack.py:function_3:9 -howto/instrumentation,,:function,156641360669707 function-return: call_stack.py:function_3:10 -howto/instrumentation,,:function,156641360687853 function-entry: call_stack.py:function_4:13 -howto/instrumentation,,:function,156641360700719 function-return: call_stack.py:function_4:14 -howto/instrumentation,,:function,156641360719640 function-entry: call_stack.py:function_5:18 -howto/instrumentation,,:function,156641360732567 function-return: call_stack.py:function_5:21 -howto/instrumentation,,:call,156641360747370 function-return:call_stack.py:start:28 -howto/instrumentation,,:start,156641360747370 function-return:call_stack.py:start:28 -howto/ipaddress,,:DB8,>>> ipaddress.ip_address('2001:DB8::1') -howto/ipaddress,,::,>>> ipaddress.ip_address('2001:DB8::1') -howto/ipaddress,,:db8,IPv6Address('2001:db8::1') -howto/ipaddress,,::,IPv6Address('2001:db8::1') -howto/ipaddress,,::,IPv6Address('::1') -howto/ipaddress,,:db8,>>> ipaddress.ip_network('2001:db8::0/96') -howto/ipaddress,,::,>>> ipaddress.ip_network('2001:db8::0/96') -howto/ipaddress,,:db8,IPv6Network('2001:db8::/96') -howto/ipaddress,,::,IPv6Network('2001:db8::/96') -howto/ipaddress,,:db8,IPv6Network('2001:db8::/128') -howto/ipaddress,,::,IPv6Network('2001:db8::/128') -howto/ipaddress,,:db8,IPv6Interface('2001:db8::1/96') -howto/ipaddress,,::,IPv6Interface('2001:db8::1/96') -howto/ipaddress,,:db8,>>> addr6 = ipaddress.ip_address('2001:db8::1') -howto/ipaddress,,::,>>> addr6 = ipaddress.ip_address('2001:db8::1') -howto/ipaddress,,:db8,>>> host6 = ipaddress.ip_interface('2001:db8::1/96') -howto/ipaddress,,::,>>> host6 = ipaddress.ip_interface('2001:db8::1/96') -howto/ipaddress,,:db8,>>> net6 = ipaddress.ip_network('2001:db8::0/96') -howto/ipaddress,,::,>>> net6 = ipaddress.ip_network('2001:db8::0/96') -howto/ipaddress,,:ffff,IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff::') -howto/ipaddress,,::,IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff::') -howto/ipaddress,,::,IPv6Address('::ffff:ffff') -howto/ipaddress,,:ffff,IPv6Address('::ffff:ffff') -howto/ipaddress,,:db8,'2001:db8::/96' -howto/ipaddress,,::,'2001:db8::/96' -howto/ipaddress,,:db8,>>> ipaddress.ip_interface('2001:db8::1/96') -howto/ipaddress,,::,>>> ipaddress.ip_interface('2001:db8::1/96') -howto/ipaddress,,:db8,'2001:db8::1' -howto/ipaddress,,::,'2001:db8::1' -howto/ipaddress,,:db8,IPv6Address('2001:db8::ffff:ffff') -howto/ipaddress,,::,IPv6Address('2001:db8::ffff:ffff') -howto/ipaddress,,:ffff,IPv6Address('2001:db8::ffff:ffff') -howto/logging,,:And,"WARNING:And this, too" -howto/logging,,:And,"WARNING:root:And this, too" -howto/logging,,:And,"ERROR:root:And non-ASCII stuff, too, like " -howto/logging,,:Doing,INFO:root:Doing something -howto/logging,,:Finished,INFO:root:Finished -howto/logging,,:logger,severity:logger name:message -howto/logging,,:Look,WARNING:root:Look before you leap! -howto/logging,,:message,severity:logger name:message -howto/logging,,:root,DEBUG:root:This message should go to the log file -howto/logging,,:root,INFO:root:Doing something -howto/logging,,:root,INFO:root:Finished -howto/logging,,:root,INFO:root:So should this -howto/logging,,:root,"ERROR:root:And non-ASCII stuff, too, like " -howto/logging,,:root,INFO:root:Started -howto/logging,,:root,"WARNING:root:And this, too" -howto/logging,,:root,WARNING:root:Look before you leap! -howto/logging,,:root,WARNING:root:Watch out! -howto/logging,,:So,INFO:root:So should this -howto/logging,,:So,INFO:So should this -howto/logging,,:Started,INFO:root:Started -howto/logging,,:This,DEBUG:root:This message should go to the log file -howto/logging,,:This,DEBUG:This message should appear on the console -howto/logging,,:Watch,WARNING:root:Watch out! -howto/pyporting,,::,Programming Language :: Python :: 2 -howto/pyporting,,::,Programming Language :: Python :: 3 -howto/regex,,::, -howto/regex,,:foo,(?:foo) -howto/urllib2,,:password,"""joe:password@example.com""" -library/__main__,,`, -library/ast,,:upper,lower:upper -library/ast,,:step,lower:upper:step -library/audioop,,:ipos,"# factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)]," -library/configparser,,:home,my_dir: ${Common:home_dir}/twosheds -library/configparser,,:option,${section:option} -library/configparser,,:path,python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python} -library/configparser,,:Python,python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python} -library/configparser,,:system,path: ${Common:system_dir}/Library/Frameworks/ -library/datetime,,:MM, -library/datetime,,:SS, -library/decimal,,:optional,"trailneg:optional trailing minus indicator" -library/difflib,,:ahi,a[alo:ahi] -library/difflib,,:bhi,b[blo:bhi] -library/difflib,,:i1, -library/difflib,,:i2, -library/difflib,,:j2, -library/doctest,,`,``factorial`` from the ``example`` module: -library/doctest,,`,The ``example`` module -library/doctest,,`,Using ``factorial`` -library/exceptions,,:err,err.object[err.start:err.end] -library/functions,,:step,a[start:stop:step] -library/functions,,:stop,"a[start:stop, i]" -library/functions,,:stop,a[start:stop:step] -library/hashlib,,:LEAF,"h00 = blake2b(buf[0:LEAF_SIZE], fanout=FANOUT, depth=DEPTH," -library/http.client,,:port,host:port -library/http.cookies,,`,!#$%&'*+-.^_`|~: -library/imaplib,,:MM,"""DD-Mmm-YYYY HH:MM:SS" -library/imaplib,,:SS,"""DD-Mmm-YYYY HH:MM:SS" -library/inspect,,:int,">>> def foo(a, *, b:int, **kwargs):" -library/inspect,,:int,"'(a, *, b:int, **kwargs)'" -library/inspect,,:int,'b:int' -library/ipaddress,,:db8,>>> ipaddress.ip_address('2001:db8::') -library/ipaddress,,::,>>> ipaddress.ip_address('2001:db8::') -library/ipaddress,,:db8,IPv6Address('2001:db8::') -library/ipaddress,,::,IPv6Address('2001:db8::') -library/ipaddress,,:db8,>>> ipaddress.IPv6Address('2001:db8::1000') -library/ipaddress,,::,>>> ipaddress.IPv6Address('2001:db8::1000') -library/ipaddress,,:db8,'2001:db8::1000' -library/ipaddress,,::,'2001:db8::1000' -library/ipaddress,,:db8,">>> f'{ipaddress.IPv6Address(""2001:db8::1000""):s}'" -library/ipaddress,,::,">>> f'{ipaddress.IPv6Address(""2001:db8::1000""):s}'" -library/ipaddress,,::,IPv6Address('ff02::5678%1') -library/ipaddress,,::,fe80::1234 -library/ipaddress,,:db8,">>> ipaddress.ip_address(""2001:db8::1"").reverse_pointer" -library/ipaddress,,::,">>> ipaddress.ip_address(""2001:db8::1"").reverse_pointer" -library/ipaddress,,::,"""::abc:7:def""" -library/ipaddress,,:def,"""::abc:7:def""" -library/ipaddress,,::,::FFFF/96 -library/ipaddress,,::,2002::/16 -library/ipaddress,,::,2001::/32 -library/ipaddress,,::,>>> str(ipaddress.IPv6Address('::1')) -library/ipaddress,,::,'::1' -library/ipaddress,,:ff00,ffff:ff00:: -library/ipaddress,,:db00,2001:db00::0/24 -library/ipaddress,,::,2001:db00::0/24 -library/ipaddress,,:db00,2001:db00::0/ffff:ff00:: -library/ipaddress,,::,2001:db00::0/ffff:ff00:: -library/itertools,,:step,elements from seq[start:stop:step] -library/itertools,,::,kernel = tuple(kernel)[::-1] -library/itertools,,:stop,elements from seq[start:stop:step] -library/logging.handlers,,:port,host:port -library/mmap,,:i2,obj[i1:i2] -library/multiprocessing,,`,# Add more tasks using `put()` -library/multiprocessing,,:queue,">>> QueueManager.register('get_queue', callable=lambda:queue)" -library/multiprocessing,,`,# register the Foo class; make `f()` and `g()` accessible via proxy -library/multiprocessing,,`,# register the Foo class; make `g()` and `_h()` accessible via proxy -library/multiprocessing,,`,# register the generator function baz; use `GeneratorProxy` to make proxies -library/nntplib,,:bytes,:bytes -library/nntplib,,:lines,:lines -library/optparse,,:len,"del parser.rargs[:len(value)]" -library/os.path,,:foo,c:foo -library/pathlib,,:bar,">>> PureWindowsPath('c:/Windows', 'd:bar')" -library/pathlib,,:bar,PureWindowsPath('d:bar') -library/pathlib,,:Program,>>> PureWindowsPath('c:Program Files/').root -library/pathlib,,:Program,>>> PureWindowsPath('c:Program Files/').anchor -library/pdb,,:lineno,filename:lineno -library/pickle,,:memory,"conn = sqlite3.connect("":memory:"")" -library/posix,,`,"CFLAGS=""`getconf LFS_CFLAGS`"" OPT=""-g -O2 $CFLAGS""" -library/pprint,,::,"'Programming Language :: Python :: 2.6'," -library/pprint,,::,"'Programming Language :: Python :: 2.7'," -library/pprint,,::,"'classifiers': ['Development Status :: 3 - Alpha'," -library/pprint,,::,"'Intended Audience :: Developers'," -library/pprint,,::,"'License :: OSI Approved :: MIT License'," -library/pprint,,::,"'Programming Language :: Python :: 2'," -library/pprint,,::,"'Programming Language :: Python :: 3'," -library/pprint,,::,"'Programming Language :: Python :: 3.2'," -library/pprint,,::,"'Programming Language :: Python :: 3.3'," -library/pprint,,::,"'Programming Language :: Python :: 3.4'," -library/pprint,,::,"'Topic :: Software Development :: Build Tools']," -library/profile,,:lineno,filename:lineno(function) -library/pyexpat,,:elem1, -library/pyexpat,,:py,"xmlns:py = ""http://www.python.org/ns/"">" -library/random,,:len,new_diff = mean(combined[:len(drug)]) - mean(combined[len(drug):]) -library/readline,,:bind,"python:bind -v" -library/readline,,:bind,"python:bind ^I rl_complete" -library/smtplib,,:port,method must support that as well as a regular host:port -library/socket,,::,'5aef:2b::8' -library/socket,,:can,"return (can_id, can_dlc, data[:can_dlc])" -library/socket,,:len,fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) -library/sqlite3,,:year,"cur.execute(""select * from lang where first_appeared=:year"", {""year"": 1972})" -library/sqlite3,,:memory, -library/sqlite3,,:path,"db = sqlite3.connect('file:path/to/database?mode=ro', uri=True)" -library/ssl,,:My,"Organizational Unit Name (eg, section) []:My Group" -library/ssl,,:My,"Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Organization, Inc." -library/ssl,,:myserver,"Common Name (eg, YOUR name) []:myserver.mygroup.myorganization.com" -library/ssl,,:MyState,State or Province Name (full name) [Some-State]:MyState -library/ssl,,:ops,Email Address []:ops@myserver.mygroup.myorganization.com -library/ssl,,:Some,"Locality Name (eg, city) []:Some City" -library/ssl,,:US,Country Name (2 letter code) [AU]:US -library/stdtypes,,:end,s[start:end] -library/stdtypes,,::,>>> hash(v[::-2]) == hash(b'abcefg'[::-2]) -library/stdtypes,,:len,s[len(s):len(s)] -library/stdtypes,,::,>>> y = m[::2] -library/stdtypes,,::,>>> z = y[::-2] -library/string,,`,"!""#$%&'()*+,-./:;<=>?@[\]^_`{|}~" -library/tarfile,,:bz2, -library/tarfile,,:compression,filemode[:compression] -library/tarfile,,:gz, -library/tarfile,,:xz,'a:xz' -library/tarfile,,:xz,'r:xz' -library/tarfile,,:xz,'w:xz' -library/time,,:mm, -library/time,,:ss, -library/tracemalloc,,:limit,"for index, stat in enumerate(top_stats[:limit], 1):" -library/turtle,,::,Example:: -library/unittest,,:foo,"self.assertEqual(cm.output, ['INFO:foo:first message'," -library/unittest,,:first,"self.assertEqual(cm.output, ['INFO:foo:first message'," -library/unittest,,:foo,'ERROR:foo.bar:second message']) -library/unittest,,:second,'ERROR:foo.bar:second message']) -library/urllib.request,,:close,Connection:close -library/urllib.request,,:port,:port -library/urllib.request,,:lang,"xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en"" lang=""en"">\n\n\n" -library/urllib.request,,:password,"""joe:password@python.org""" -library/urllib.parse,,:scheme, -library/urllib.parse,,:scheme,URL:scheme://host/path -library/uuid,,:uuid,urn:uuid:12345678-1234-5678-1234-567812345678 -library/venv,,:param,":param nodist: If true, setuptools and pip are not installed into the" -library/venv,,:param,":param progress: If setuptools or pip are installed, the progress of the" -library/venv,,:param,":param nopip: If true, pip is not installed into the created" -library/venv,,:param,:param context: The information for the virtual environment -library/xmlrpc.client,,:nil,ex:nil -library/xmlrpc.client,,:pass,http://user:pass@host:port/path -library/xmlrpc.client,,:pass,user:pass -library/xmlrpc.client,,:port,http://user:pass@host:port/path -license,,`,"``Software''), to deal in the Software without restriction, including" -license,,`,"THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND," -license,,`,* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -license,,`,THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -license,,`,* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY -license,,`,THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND -license,,:zooko,mailto:zooko@zooko.com -reference/expressions,,:index,x[index:index] -reference/lexical_analysis,,`,$ ? ` -reference/lexical_analysis,,:fileencoding,# vim:fileencoding= -tutorial/datastructures,,:value,It is also possible to delete a key:value -tutorial/datastructures,,:value,key:value pairs within the braces adds initial key:value pairs -tutorial/stdlib2,,:config,"logging.warning('Warning:config file %s not found', 'server.conf')" -tutorial/stdlib2,,:config,WARNING:root:Warning:config file server.conf not found -tutorial/stdlib2,,:Critical,CRITICAL:root:Critical error -- shutting down -tutorial/stdlib2,,:Error,ERROR:root:Error occurred -tutorial/stdlib2,,:root,CRITICAL:root:Critical error -- shutting down -tutorial/stdlib2,,:root,ERROR:root:Error occurred -tutorial/stdlib2,,:root,WARNING:root:Warning:config file server.conf not found -tutorial/stdlib2,,:start,extra = data[start:start+extra_size] -tutorial/stdlib2,,:start,"fields = struct.unpack('>> urlparse.urlparse('http://[1080::8:800:200C:417A]/foo') -whatsnew/2.7,,:Sunday,'2009:4:Sunday' -whatsnew/2.7,,:Cookie,"export PYTHONWARNINGS=all,error:::Cookie:0" -whatsnew/2.7,,::,"export PYTHONWARNINGS=all,error:::Cookie:0" -whatsnew/3.2,,:affe,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]'," -whatsnew/3.2,,:affe,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/') -whatsnew/3.2,,:beef,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]'," -whatsnew/3.2,,:beef,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/') -whatsnew/3.2,,:cafe,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]'," -whatsnew/3.2,,:cafe,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/') -whatsnew/3.2,,:deaf,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]'," -whatsnew/3.2,,:deaf,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/') -whatsnew/3.2,,:directory,${buildout:directory}/downloads/dist -whatsnew/3.2,,::,"$ export PYTHONWARNINGS='ignore::RuntimeWarning::,once::UnicodeWarning::'" -whatsnew/3.2,,:feed,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]'," -whatsnew/3.2,,:feed,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/') -whatsnew/3.2,,:gz,">>> with tarfile.open(name='myarchive.tar.gz', mode='w:gz') as tf:" -whatsnew/3.2,,:location,zope9-location = ${zope9:location} -whatsnew/3.2,,:prefix,zope-conf = ${custom:prefix}/etc/zope.conf -library/re,,`,!#$%&'*+-.^_`|~: -library/re,,`,!\#\$%\&'\*\+\-\.\^_`\|\~: -library/tarfile,,:xz,'x:xz' -library/warnings,,:message,action:message:category:module:line -library/warnings,,:category,action:message:category:module:line -library/warnings,,:module,action:message:category:module:line -library/warnings,,:line,action:message:category:module:line -library/warnings,,::,error::ResourceWarning -library/warnings,,::,default::DeprecationWarning -library/warnings,,::,default:::mymodule -library/warnings,,:mymodule,default:::mymodule -library/warnings,,::,error:::mymodule -library/warnings,,:mymodule,error:::mymodule -library/warnings,,::,ignore::DeprecationWarning -library/warnings,,::,ignore::PendingDeprecationWarning -library/warnings,,::,ignore::ImportWarning -library/warnings,,::,ignore::ResourceWarning -library/xml.etree.elementtree,,:sometag,prefix:sometag -library/xml.etree.elementtree,,:fictional,"Lancelot -library/xml.etree.elementtree,,:character,Archie Leach -library/xml.etree.elementtree,,:character,Sir Robin -library/xml.etree.elementtree,,:character,Gunther -library/xml.etree.elementtree,,:character,Commander Clement -library/xml.etree.elementtree,,:actor,"for actor in root.findall('real_person:actor', ns):" -library/xml.etree.elementtree,,:name,"name = actor.find('real_person:name', ns)" -library/xml.etree.elementtree,,:character,"for char in actor.findall('role:character', ns):" -library/xml.etree.elementtree,,:xi, -library/xml.etree.elementtree,,:include, -library/xml.etree.elementtree,,:include, Copyright (c) . -library/zipapp,,:main,"$ python -m zipapp myapp -m ""myapp:main""" -library/zipapp,,:fn,"pkg.mod:fn" -library/zipapp,,:callable,"pkg.module:callable" -library/stdtypes,,::,>>> m[::2].tolist() -whatsnew/3.5,,:root,'WARNING:root:warning\n' -whatsnew/3.5,,:warning,'WARNING:root:warning\n' -whatsnew/3.5,,::,>>> addr6 = ipaddress.IPv6Address('::1') -whatsnew/3.5,,:root,ERROR:root:exception -whatsnew/3.5,,:exception,ERROR:root:exception -whatsnew/changelog,,`,'`' -whatsnew/changelog,,:end,str[start:end] -library/binascii,,`,'`' -library/uu,,`,'`' -whatsnew/3.7,,`,'`' -whatsnew/3.7,,::,error::BytesWarning -whatsnew/changelog,,::,error::BytesWarning -whatsnew/changelog,,::,default::BytesWarning -whatsnew/changelog,,::,default::DeprecationWarning -library/importlib.metadata,,:main,"EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts')" -library/importlib.metadata,,`,loading the metadata for packages for the indicated ``context``. -library/re,,`,"`" -using/configure,84,:db2,=db1:db2:... -library/typing,,`,# Type of ``val`` is narrowed to ``str`` -library/typing,,`,"# Else, type of ``val`` is narrowed to ``float``." -library/typing,,`,# Type of ``val`` is narrowed to ``list[str]``. -library/typing,,`,# Type of ``val`` remains as ``list[object]``. -library/tkinter,,::,ttk::frame .frm -padding 10 -library/tkinter,,::,"grid [ttk::label .frm.lbl -text ""Hello World!""] -column 0 -row 0" -library/tkinter,,::,"grid [ttk::button .frm.btn -text ""Quit"" -command ""destroy .""] -column 1 -row 0" -library/tkinter,,::,ttk::frame -library/tkinter,,::,ttk::button -library/tkinter,,::,ttk::widget -reference/datamodel,2285,`,"""""""Return the result of the expression `obj[x]`""""""" diff --git a/Doc/tools/templates/download.html b/Doc/tools/templates/download.html index 987c63a7f35..7920e0619f9 100644 --- a/Doc/tools/templates/download.html +++ b/Doc/tools/templates/download.html @@ -3,6 +3,10 @@ {% if daily is defined %} {% set dlbase = pathto('archives', 1) %} {% else %} + {# + The link below returns HTTP 404 until the first related alpha release. + This is expected; use daily documentation builds for CPython development. + #} {% set dlbase = 'https://docs.python.org/ftp/python/doc/' + release %} {% endif %} @@ -40,10 +44,6 @@ Python in one of various formats, follow one of links in this table.

    These archives contain all the content in the documentation.

    -

    HTML Help (.chm) files are made available in the "Windows" section -on the Python -download page.

    -

    Unpacking

    diff --git a/Doc/tools/templates/indexsidebar.html b/Doc/tools/templates/indexsidebar.html index f7bf6d8e491..5986204256f 100644 --- a/Doc/tools/templates/indexsidebar.html +++ b/Doc/tools/templates/indexsidebar.html @@ -10,7 +10,7 @@

    {% trans %}Other resources{% endtrans %}

    {%- endif %} + +{%- if is_deployment_preview %} +
    +
    + + Deploys by Netlify + +
    + {% trans %}This is a deploy preview created from a pull request. + For authoritative documentation, see the {% endtrans %} + {% trans %} the current stable release{% endtrans %}. +
    +{%- endif %} {% endblock %} {% block rootrellink %} diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 0d780e3ba89..116801177a3 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -119,12 +119,12 @@ directly accessible: * the innermost scope, which is searched first, contains the local names * the scopes of any enclosing functions, which are searched starting with the - nearest enclosing scope, contains non-local, but also non-global names + nearest enclosing scope, contain non-local, but also non-global names * the next-to-last scope contains the current module's global names * the outermost scope (searched last) is the namespace containing built-in names If a name is declared global, then all references and assignments go directly to -the middle scope containing the module's global names. To rebind variables +the next-to-last scope containing the module's global names. To rebind variables found outside of the innermost scope, the :keyword:`nonlocal` statement can be used; if not declared nonlocal, those variables are read-only (an attempt to write to such a variable will simply create a *new* local variable in the @@ -297,7 +297,7 @@ initial state. Therefore a class may define a special method named self.data = [] When a class defines an :meth:`__init__` method, class instantiation -automatically invokes :meth:`__init__` for the newly-created class instance. So +automatically invokes :meth:`__init__` for the newly created class instance. So in this example, a new, initialized instance can be obtained by:: x = MyClass() @@ -479,9 +479,9 @@ If the same attribute name occurs in both an instance and in a class, then attribute lookup prioritizes the instance:: >>> class Warehouse: - purpose = 'storage' - region = 'west' - + ... purpose = 'storage' + ... region = 'west' + ... >>> w1 = Warehouse() >>> print(w1.purpose, w1.region) storage west @@ -581,7 +581,8 @@ this:: . -The name :class:`BaseClassName` must be defined in a scope containing the +The name :class:`BaseClassName` must be defined in a +namespace accessible from the scope containing the derived class definition. In place of a base class name, other arbitrary expressions are also allowed. This can be useful, for example, when the base class is defined in another module:: @@ -737,18 +738,24 @@ Odds and Ends ============= Sometimes it is useful to have a data type similar to the Pascal "record" or C -"struct", bundling together a few named data items. An empty class definition -will do nicely:: +"struct", bundling together a few named data items. The idiomatic approach +is to use :mod:`dataclasses` for this purpose:: - class Employee: - pass + from dataclasses import dataclass - john = Employee() # Create an empty employee record + @dataclass + class Employee: + name: str + dept: str + salary: int - # Fill the fields of the record - john.name = 'John Doe' - john.dept = 'computer lab' - john.salary = 1000 +:: + + >>> john = Employee('john', 'computer lab', 1000) + >>> john.dept + 'computer lab' + >>> john.salary + 1000 A piece of Python code that expects a particular abstract data type can often be passed a class that emulates the methods of that data type instead. For @@ -797,7 +804,7 @@ using the :func:`next` built-in function; this example shows how it all works:: >>> s = 'abc' >>> it = iter(s) >>> it - + >>> next(it) 'a' >>> next(it) diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index a8197566026..52db51e84cd 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -250,11 +250,13 @@ at a more abstract level. The :keyword:`!pass` is silently ignored:: :keyword:`!match` Statements ============================ -A match statement takes an expression and compares its value to successive +A :keyword:`match` statement takes an expression and compares its value to successive patterns given as one or more case blocks. This is superficially similar to a switch statement in C, Java or JavaScript (and many -other languages), but it can also extract components (sequence elements or -object attributes) from the value into variables. +other languages), but it's more similar to pattern matching in +languages like Rust or Haskell. Only the first pattern that matches +gets executed and it can also extract components (sequence elements +or object attributes) from the value into variables. The simplest form compares a subject value against one or more literals:: @@ -395,9 +397,11 @@ Several other key features of this statement: from enum import Enum class Color(Enum): - RED = 0 - GREEN = 1 - BLUE = 2 + RED = 'red' + GREEN = 'green' + BLUE = 'blue' + + color = Color(input("Enter your choice of 'red', 'blue' or 'green': ")) match color: case Color.RED: @@ -836,8 +840,9 @@ will always bind to the first parameter. For example:: But using ``/`` (positional only arguments), it is possible since it allows ``name`` as a positional argument and ``'name'`` as a key in the keyword arguments:: - def foo(name, /, **kwds): - return 'name' in kwds + >>> def foo(name, /, **kwds): + ... return 'name' in kwds + ... >>> foo(1, **{'name': 2}) True @@ -882,7 +887,7 @@ zero or more normal arguments may occur. :: file.write(separator.join(args)) -Normally, these ``variadic`` arguments will be last in the list of formal +Normally, these *variadic* arguments will be last in the list of formal parameters, because they scoop up all remaining input arguments that are passed to the function. Any formal parameters which occur after the ``*args`` parameter are 'keyword-only' arguments, meaning that they can only be used as diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index e42b380db3d..c8e89d9b79b 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -106,7 +106,7 @@ An example that uses most of the list methods:: 0 >>> fruits.index('banana') 3 - >>> fruits.index('banana', 4) # Find next banana starting a position 4 + >>> fruits.index('banana', 4) # Find next banana starting at position 4 6 >>> fruits.reverse() >>> fruits @@ -122,7 +122,7 @@ An example that uses most of the list methods:: You might have noticed that methods like ``insert``, ``remove`` or ``sort`` that only modify the list have no return value printed -- they return the default -``None``. [1]_ This is a design principle for all mutable data structures in +``None``. [#]_ This is a design principle for all mutable data structures in Python. Another thing you might notice is that not all data can be sorted or @@ -268,10 +268,10 @@ it must be parenthesized. :: [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)] >>> # the tuple must be parenthesized, otherwise an error is raised >>> [x, x**2 for x in range(6)] - File "", line 1, in + File "", line 1 [x, x**2 for x in range(6)] - ^ - SyntaxError: invalid syntax + ^^^^^^^ + SyntaxError: did you forget parentheses around the comprehension target? >>> # flatten a list using a listcomp with two 'for' >>> vec = [[1,2,3], [4,5,6], [7,8,9]] >>> [num for elem in vec for num in elem] @@ -303,7 +303,7 @@ The following list comprehension will transpose rows and columns:: >>> [[row[i] for row in matrix] for i in range(4)] [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]] -As we saw in the previous section, the nested listcomp is evaluated in +As we saw in the previous section, the inner list comprehension is evaluated in the context of the :keyword:`for` that follows it, so this example is equivalent to:: @@ -659,10 +659,12 @@ More on Conditions The conditions used in ``while`` and ``if`` statements can contain any operators, not just comparisons. -The comparison operators ``in`` and ``not in`` check whether a value occurs -(does not occur) in a sequence. The operators ``is`` and ``is not`` compare -whether two objects are really the same object. All comparison operators have -the same priority, which is lower than that of all numerical operators. + +The comparison operators ``in`` and ``not in`` are membership tests that +determine whether a value is in (or not in) a container. The operators ``is`` +and ``is not`` compare whether two objects are really the same object. All +comparison operators have the same priority, which is lower than that of all +numerical operators. Comparisons can be chained. For example, ``a < b == c`` tests whether ``a`` is less than ``b`` and moreover ``b`` equals ``c``. @@ -729,5 +731,5 @@ interpreter will raise a :exc:`TypeError` exception. .. rubric:: Footnotes -.. [1] Other languages may return the mutated object, which allows method +.. [#] Other languages may return the mutated object, which allows method chaining, such as ``d->insert("a")->remove("b")->sort();``. diff --git a/Doc/tutorial/errors.rst b/Doc/tutorial/errors.rst index f2490d65db5..e09c829b8e9 100644 --- a/Doc/tutorial/errors.rst +++ b/Doc/tutorial/errors.rst @@ -147,10 +147,52 @@ For example, the following code will print B, C, D in that order:: Note that if the *except clauses* were reversed (with ``except B`` first), it would have printed B, B, B --- the first matching *except clause* is triggered. -All exceptions inherit from :exc:`BaseException`, and so it can be used to serve -as a wildcard. Use this with extreme caution, since it is easy to mask a real -programming error in this way! It can also be used to print an error message and -then re-raise the exception (allowing a caller to handle the exception as well):: +When an exception occurs, it may have associated values, also known as the +exception's *arguments*. The presence and types of the arguments depend on the +exception type. + +The *except clause* may specify a variable after the exception name. The +variable is bound to the exception instance which typically has an ``args`` +attribute that stores the arguments. For convenience, builtin exception +types define :meth:`__str__` to print all the arguments without explicitly +accessing ``.args``. :: + + >>> try: + ... raise Exception('spam', 'eggs') + ... except Exception as inst: + ... print(type(inst)) # the exception instance + ... print(inst.args) # arguments stored in .args + ... print(inst) # __str__ allows args to be printed directly, + ... # but may be overridden in exception subclasses + ... x, y = inst.args # unpack args + ... print('x =', x) + ... print('y =', y) + ... + + ('spam', 'eggs') + ('spam', 'eggs') + x = spam + y = eggs + +The exception's :meth:`__str__` output is printed as the last part ('detail') +of the message for unhandled exceptions. + +:exc:`BaseException` is the common base class of all exceptions. One of its +subclasses, :exc:`Exception`, is the base class of all the non-fatal exceptions. +Exceptions which are not subclasses of :exc:`Exception` are not typically +handled, because they are used to indicate that the program should terminate. +They include :exc:`SystemExit` which is raised by :meth:`sys.exit` and +:exc:`KeyboardInterrupt` which is raised when a user wishes to interrupt +the program. + +:exc:`Exception` can be used as a wildcard that catches (almost) everything. +However, it is good practice to be as specific as possible with the types +of exceptions that we intend to handle, and to allow any unexpected +exceptions to propagate on. + +The most common pattern for handling :exc:`Exception` is to print or log +the exception and then re-raise it (allowing a caller to handle the +exception as well):: import sys @@ -159,16 +201,13 @@ then re-raise the exception (allowing a caller to handle the exception as well): s = f.readline() i = int(s.strip()) except OSError as err: - print("OS error: {0}".format(err)) + print("OS error:", err) except ValueError: print("Could not convert data to an integer.") - except BaseException as err: + except Exception as err: print(f"Unexpected {err=}, {type(err)=}") raise -Alternatively the last except clause may omit the exception name(s), however the exception -value must then be retrieved from ``sys.exc_info()[1]``. - The :keyword:`try` ... :keyword:`except` statement has an optional *else clause*, which, when present, must follow all *except clauses*. It is useful for code that must be executed if the *try clause* does not raise an exception. @@ -188,39 +227,8 @@ the :keyword:`try` clause because it avoids accidentally catching an exception that wasn't raised by the code being protected by the :keyword:`!try` ... :keyword:`!except` statement. -When an exception occurs, it may have an associated value, also known as the -exception's *argument*. The presence and type of the argument depend on the -exception type. - -The *except clause* may specify a variable after the exception name. The -variable is bound to an exception instance with the arguments stored in -``instance.args``. For convenience, the exception instance defines -:meth:`__str__` so the arguments can be printed directly without having to -reference ``.args``. One may also instantiate an exception first before -raising it and add any attributes to it as desired. :: - - >>> try: - ... raise Exception('spam', 'eggs') - ... except Exception as inst: - ... print(type(inst)) # the exception instance - ... print(inst.args) # arguments stored in .args - ... print(inst) # __str__ allows args to be printed directly, - ... # but may be overridden in exception subclasses - ... x, y = inst.args # unpack args - ... print('x =', x) - ... print('y =', y) - ... - - ('spam', 'eggs') - ('spam', 'eggs') - x = spam - y = eggs - -If an exception has arguments, they are printed as the last part ('detail') of -the message for unhandled exceptions. - -Exception handlers don't just handle exceptions if they occur immediately in the -*try clause*, but also if they occur inside functions that are called (even +Exception handlers do not handle only exceptions that occur immediately in the +*try clause*, but also those that occur inside functions that are called (even indirectly) in the *try clause*. For example:: >>> def this_fails(): @@ -249,8 +257,9 @@ exception to occur. For example:: The sole argument to :keyword:`raise` indicates the exception to be raised. This must be either an exception instance or an exception class (a class that -derives from :class:`Exception`). If an exception class is passed, it will -be implicitly instantiated by calling its constructor with no arguments:: +derives from :class:`BaseException`, such as :exc:`Exception` or one of its +subclasses). If an exception class is passed, it will be implicitly +instantiated by calling its constructor with no arguments:: raise ValueError # shorthand for 'raise ValueError()' @@ -275,8 +284,27 @@ re-raise the exception:: Exception Chaining ================== -The :keyword:`raise` statement allows an optional :keyword:`from` which enables -chaining exceptions. For example:: +If an unhandled exception occurs inside an :keyword:`except` section, it will +have the exception being handled attached to it and included in the error +message:: + + >>> try: + ... open("database.sqlite") + ... except OSError: + ... raise RuntimeError("unable to handle error") + ... + Traceback (most recent call last): + File "", line 2, in + FileNotFoundError: [Errno 2] No such file or directory: 'database.sqlite' + + During handling of the above exception, another exception occurred: + + Traceback (most recent call last): + File "", line 4, in + RuntimeError: unable to handle error + +To indicate that an exception is a direct consequence of another, the +:keyword:`raise` statement allows an optional :keyword:`from` clause:: # exc must be exception instance or None. raise RuntimeError from exc @@ -302,9 +330,8 @@ This can be useful when you are transforming exceptions. For example:: File "", line 4, in RuntimeError: Failed to open database -Exception chaining happens automatically when an exception is raised inside an -:keyword:`except` or :keyword:`finally` section. This can be -disabled by using ``from None`` idiom: +It also allows disabling automatic exception chaining using the ``from None`` +idiom:: >>> try: ... open('database.sqlite') @@ -329,48 +356,13 @@ be derived from the :exc:`Exception` class, either directly or indirectly. Exception classes can be defined which do anything any other class can do, but are usually kept simple, often only offering a number of attributes that allow -information about the error to be extracted by handlers for the exception. When -creating a module that can raise several distinct errors, a common practice is -to create a base class for exceptions defined by that module, and subclass that -to create specific exception classes for different error conditions:: - - class Error(Exception): - """Base class for exceptions in this module.""" - pass - - class InputError(Error): - """Exception raised for errors in the input. - - Attributes: - expression -- input expression in which the error occurred - message -- explanation of the error - """ - - def __init__(self, expression, message): - self.expression = expression - self.message = message - - class TransitionError(Error): - """Raised when an operation attempts a state transition that's not - allowed. - - Attributes: - previous -- state at beginning of transition - next -- attempted new state - message -- explanation of why the specific transition is not allowed - """ - - def __init__(self, previous, next, message): - self.previous = previous - self.next = next - self.message = message +information about the error to be extracted by handlers for the exception. Most exceptions are defined with names that end in "Error", similar to the naming of the standard exceptions. Many standard modules define their own exceptions to report errors that may -occur in functions they define. More information on classes is presented in -chapter :ref:`tut-classes`. +occur in functions they define. .. _tut-cleanup: @@ -496,3 +488,156 @@ used in a way that ensures they are always cleaned up promptly and correctly. :: After the statement is executed, the file *f* is always closed, even if a problem was encountered while processing the lines. Objects which, like files, provide predefined clean-up actions will indicate this in their documentation. + + +.. _tut-exception-groups: + +Raising and Handling Multiple Unrelated Exceptions +================================================== + +There are situations where it is necessary to report several exceptions that +have occurred. This is often the case in concurrency frameworks, when several +tasks may have failed in parallel, but there are also other use cases where +it is desirable to continue execution and collect multiple errors rather than +raise the first exception. + +The builtin :exc:`ExceptionGroup` wraps a list of exception instances so +that they can be raised together. It is an exception itself, so it can be +caught like any other exception. :: + + >>> def f(): + ... excs = [OSError('error 1'), SystemError('error 2')] + ... raise ExceptionGroup('there were problems', excs) + ... + >>> f() + + Exception Group Traceback (most recent call last): + | File "", line 1, in + | File "", line 3, in f + | ExceptionGroup: there were problems + +-+---------------- 1 ---------------- + | OSError: error 1 + +---------------- 2 ---------------- + | SystemError: error 2 + +------------------------------------ + >>> try: + ... f() + ... except Exception as e: + ... print(f'caught {type(e)}: e') + ... + caught : e + >>> + +By using ``except*`` instead of ``except``, we can selectively +handle only the exceptions in the group that match a certain +type. In the following example, which shows a nested exception +group, each ``except*`` clause extracts from the group exceptions +of a certain type while letting all other exceptions propagate to +other clauses and eventually to be reraised. :: + + >>> def f(): + ... raise ExceptionGroup("group1", + ... [OSError(1), + ... SystemError(2), + ... ExceptionGroup("group2", + ... [OSError(3), RecursionError(4)])]) + ... + >>> try: + ... f() + ... except* OSError as e: + ... print("There were OSErrors") + ... except* SystemError as e: + ... print("There were SystemErrors") + ... + There were OSErrors + There were SystemErrors + + Exception Group Traceback (most recent call last): + | File "", line 2, in + | File "", line 2, in f + | ExceptionGroup: group1 + +-+---------------- 1 ---------------- + | ExceptionGroup: group2 + +-+---------------- 1 ---------------- + | RecursionError: 4 + +------------------------------------ + >>> + +Note that the exceptions nested in an exception group must be instances, +not types. This is because in practice the exceptions would typically +be ones that have already been raised and caught by the program, along +the following pattern:: + + >>> excs = [] + ... for test in tests: + ... try: + ... test.run() + ... except Exception as e: + ... excs.append(e) + ... + >>> if excs: + ... raise ExceptionGroup("Test Failures", excs) + ... + + +Enriching Exceptions with Notes +=============================== + +When an exception is created in order to be raised, it is usually initialized +with information that describes the error that has occurred. There are cases +where it is useful to add information after the exception was caught. For this +purpose, exceptions have a method ``add_note(note)`` that accepts a string and +adds it to the exception's notes list. The standard traceback rendering +includes all notes, in the order they were added, after the exception. :: + + >>> try: + ... raise TypeError('bad type') + ... except Exception as e: + ... e.add_note('Add some information') + ... e.add_note('Add some more information') + ... raise + ... + Traceback (most recent call last): + File "", line 2, in + TypeError: bad type + Add some information + Add some more information + >>> + +For example, when collecting exceptions into an exception group, we may want +to add context information for the individual errors. In the following each +exception in the group has a note indicating when this error has occurred. :: + + >>> def f(): + ... raise OSError('operation failed') + ... + >>> excs = [] + >>> for i in range(3): + ... try: + ... f() + ... except Exception as e: + ... e.add_note(f'Happened in Iteration {i+1}') + ... excs.append(e) + ... + >>> raise ExceptionGroup('We have some problems', excs) + + Exception Group Traceback (most recent call last): + | File "", line 1, in + | ExceptionGroup: We have some problems (3 sub-exceptions) + +-+---------------- 1 ---------------- + | Traceback (most recent call last): + | File "", line 3, in + | File "", line 2, in f + | OSError: operation failed + | Happened in Iteration 1 + +---------------- 2 ---------------- + | Traceback (most recent call last): + | File "", line 3, in + | File "", line 2, in f + | OSError: operation failed + | Happened in Iteration 2 + +---------------- 3 ---------------- + | Traceback (most recent call last): + | File "", line 3, in + | File "", line 2, in f + | OSError: operation failed + | Happened in Iteration 3 + +------------------------------------ + >>> diff --git a/Doc/tutorial/floatingpoint.rst b/Doc/tutorial/floatingpoint.rst index b98de6e56a0..cedade6e336 100644 --- a/Doc/tutorial/floatingpoint.rst +++ b/Doc/tutorial/floatingpoint.rst @@ -12,15 +12,9 @@ Floating Point Arithmetic: Issues and Limitations Floating-point numbers are represented in computer hardware as base 2 (binary) -fractions. For example, the decimal fraction :: - - 0.125 - -has value 1/10 + 2/100 + 5/1000, and in the same way the binary fraction :: - - 0.001 - -has value 0/2 + 0/4 + 1/8. These two fractions have identical values, the only +fractions. For example, the **decimal** fraction ``0.125`` +has value 1/10 + 2/100 + 5/1000, and in the same way the **binary** fraction ``0.001`` +has value 0/2 + 0/4 + 1/8. These two fractions have identical values, the only real difference being that the first is written in base 10 fractional notation, and the second in base 2. @@ -133,7 +127,7 @@ with inexact values become comparable to one another:: Binary floating-point arithmetic holds many surprises like this. The problem with "0.1" is explained in precise detail below, in the "Representation Error" -section. See `The Perils of Floating Point `_ +section. See `The Perils of Floating Point `_ for a more complete account of other common surprises. As that says near the end, "there are no easy answers." Still, don't be unduly @@ -198,7 +192,7 @@ added onto a running total. That can make a difference in overall accuracy so that the errors do not accumulate to the point where they affect the final total: - >>> sum([0.1] * 10) == 1.0 + >>> 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 == 1.0 False >>> math.fsum([0.1] * 10) == 1.0 True diff --git a/Doc/tutorial/inputoutput.rst b/Doc/tutorial/inputoutput.rst index 7f83c4d4612..3581b3727a5 100644 --- a/Doc/tutorial/inputoutput.rst +++ b/Doc/tutorial/inputoutput.rst @@ -133,7 +133,17 @@ applies :func:`repr`:: >>> print(f'My hovercraft is full of {animals!r}.') My hovercraft is full of 'eels'. -For a reference on these format specifications, see +The ``=`` specifier can be used to expand an expression to the text of the +expression, an equal sign, then the representation of the evaluated expression: + + >>> bugs = 'roaches' + >>> count = 13 + >>> area = 'living room' + >>> print(f'Debugging {bugs=} {count=} {area=}') + Debugging bugs='roaches' count=13 area='living room' + +See :ref:`self-documenting expressions ` for more information +on the ``=`` specifier. For a reference on these format specifications, see the reference guide for the :ref:`formatspec`. .. _tut-string-format: @@ -166,7 +176,7 @@ are referred to by using the name of the argument. :: Positional and keyword arguments can be arbitrarily combined:: >>> print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred', - other='Georg')) + ... other='Georg')) The story of Bill, Manfred, and Georg. If you have a really long format string that you don't want to split up, it @@ -179,7 +189,7 @@ square brackets ``'[]'`` to access the keys. :: ... 'Dcab: {0[Dcab]:d}'.format(table)) Jack: 4098; Sjoerd: 4127; Dcab: 8637678 -This could also be done by passing the table as keyword arguments with the '**' +This could also be done by passing the ``table`` dictionary as keyword arguments with the ``**`` notation. :: >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} @@ -189,7 +199,7 @@ notation. :: This is particularly useful in combination with the built-in function :func:`vars`, which returns a dictionary containing all local variables. -As an example, the following lines produce a tidily-aligned +As an example, the following lines produce a tidily aligned set of columns giving integers and their squares and cubes:: >>> for x in range(1, 11): @@ -279,11 +289,12 @@ Reading and Writing Files object: file :func:`open` returns a :term:`file object`, and is most commonly used with -two arguments: ``open(filename, mode)``. +two positional arguments and one keyword argument: +``open(filename, mode, encoding=None)`` :: - >>> f = open('workfile', 'w') + >>> f = open('workfile', 'w', encoding="utf-8") .. XXX str(f) is @@ -300,11 +311,14 @@ writing. The *mode* argument is optional; ``'r'`` will be assumed if it's omitted. Normally, files are opened in :dfn:`text mode`, that means, you read and write -strings from and to the file, which are encoded in a specific encoding. If -encoding is not specified, the default is platform dependent (see -:func:`open`). ``'b'`` appended to the mode opens the file in -:dfn:`binary mode`: now the data is read and written in the form of bytes -objects. This mode should be used for all files that don't contain text. +strings from and to the file, which are encoded in a specific *encoding*. +If *encoding* is not specified, the default is platform dependent +(see :func:`open`). +Because UTF-8 is the modern de-facto standard, ``encoding="utf-8"`` is +recommended unless you know that you need to use a different encoding. +Appending a ``'b'`` to the mode opens the file in :dfn:`binary mode`. +Binary mode data is read and written as :class:`bytes` objects. +You can not specify *encoding* when opening file in binary mode. In text mode, the default when reading is to convert platform-specific line endings (``\n`` on Unix, ``\r\n`` on Windows) to just ``\n``. When writing in @@ -320,7 +334,7 @@ after its suite finishes, even if an exception is raised at some point. Using :keyword:`!with` is also much shorter than writing equivalent :keyword:`try`\ -\ :keyword:`finally` blocks:: - >>> with open('workfile') as f: + >>> with open('workfile', encoding="utf-8") as f: ... read_data = f.read() >>> # We can check that the file has been automatically closed. @@ -464,7 +478,7 @@ becomes complicated. Rather than having users constantly writing and debugging code to save complicated data types to files, Python allows you to use the popular data interchange format called `JSON (JavaScript Object Notation) -`_. The standard module called :mod:`json` can take Python +`_. The standard module called :mod:`json` can take Python data hierarchies, and convert them to string representations; this process is called :dfn:`serializing`. Reconstructing the data from the string representation is called :dfn:`deserializing`. Between serializing and deserializing, the @@ -490,11 +504,15 @@ simply serializes the object to a :term:`text file`. So if ``f`` is a json.dump(x, f) -To decode the object again, if ``f`` is a :term:`text file` object which has -been opened for reading:: +To decode the object again, if ``f`` is a :term:`binary file` or +:term:`text file` object which has been opened for reading:: x = json.load(f) +.. note:: + JSON files must be encoded in UTF-8. Use ``encoding="utf-8"`` when opening + JSON file as a :term:`text file` for both of reading and writing. + This simple serialization technique can handle lists and dictionaries, but serializing arbitrary class instances in JSON requires a bit of extra effort. The reference for the :mod:`json` module contains an explanation of this. diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index d7f300d93b0..b71c61089e6 100644 --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -10,13 +10,13 @@ Using the Python Interpreter Invoking the Interpreter ======================== -The Python interpreter is usually installed as :file:`/usr/local/bin/python3.11` +The Python interpreter is usually installed as :file:`/usr/local/bin/python3.12` on those machines where it is available; putting :file:`/usr/local/bin` in your Unix shell's search path makes it possible to start it by typing the command: .. code-block:: text - python3.11 + python3.12 to the shell. [#]_ Since the choice of the directory where the interpreter lives is an installation option, other places are possible; check with your local @@ -24,7 +24,7 @@ Python guru or system administrator. (E.g., :file:`/usr/local/python` is a popular alternative location.) On Windows machines where you have installed Python from the :ref:`Microsoft Store -`, the :file:`python3.11` command will be available. If you have +`, the :file:`python3.12` command will be available. If you have the :ref:`py.exe launcher ` installed, you can use the :file:`py` command. See :ref:`setting-envvars` for other ways to launch Python. @@ -52,7 +52,7 @@ A second way of starting the interpreter is ``python -c command [arg] ...``, which executes the statement(s) in *command*, analogous to the shell's :option:`-c` option. Since Python statements often contain spaces or other characters that are special to the shell, it is usually advised to quote -*command* in its entirety with single quotes. +*command* in its entirety. Some Python modules are also useful as scripts. These can be invoked using ``python -m module [arg] ...``, which executes the source file for *module* as @@ -97,8 +97,8 @@ before printing the first prompt: .. code-block:: shell-session - $ python3.11 - Python 3.11 (default, April 4 2021, 09:25:04) + $ python3.12 + Python 3.12 (default, April 4 2022, 09:25:04) [GCC 10.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst index 33678f5a64b..ebc2e918753 100644 --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -70,8 +70,8 @@ the ones with a fractional part (e.g. ``5.0``, ``1.6``) have type :class:`float`. We will see more about numeric types later in the tutorial. Division (``/``) always returns a float. To do :term:`floor division` and -get an integer result (discarding any fractional result) you can use the ``//`` -operator; to calculate the remainder you can use ``%``:: +get an integer result you can use the ``//`` operator; to calculate +the remainder you can use ``%``:: >>> 17 / 3 # classic division returns a float 5.666666666666667 @@ -189,6 +189,11 @@ the first quote:: >>> print(r'C:\some\name') # note the r before the quote C:\some\name +There is one subtle aspect to raw strings: a raw string may not end in +an odd number of ``\`` characters; see +:ref:`the FAQ entry ` for more information +and workarounds. + String literals can span multiple lines. One way is using triple-quotes: ``"""..."""`` or ``'''...'''``. End of lines are automatically included in the string, but it's possible to prevent this by adding a ``\`` at @@ -234,12 +239,12 @@ This only works with two literals though, not with variables or expressions:: >>> prefix 'thon' # can't concatenate a variable and a string literal File "", line 1 prefix 'thon' - ^ + ^^^^^^ SyntaxError: invalid syntax >>> ('un' * 3) 'ium' File "", line 1 ('un' * 3) 'ium' - ^ + ^^^^^ SyntaxError: invalid syntax If you want to concatenate variables or a variable and a literal, use ``+``:: @@ -269,7 +274,7 @@ Indices may also be negative numbers, to start counting from the right:: Note that since -0 is the same as 0, negative indices start from -1. In addition to indexing, *slicing* is also supported. While indexing is used -to obtain individual characters, *slicing* allows you to obtain substring:: +to obtain individual characters, *slicing* allows you to obtain a substring:: >>> word[0:2] # characters from position 0 (included) to 2 (excluded) 'Py' diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst index f1d4957e37e..ad70d92994a 100644 --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -47,8 +47,9 @@ command:: >>> import fibo -This does not enter the names of the functions defined in ``fibo`` directly in -the current symbol table; it only enters the module name ``fibo`` there. Using +This does not add the names of the functions defined in ``fibo`` directly to +the current :term:`namespace` (see :ref:`tut-scopes` for more details); +it only adds the module name ``fibo`` there. Using the module name you can access the functions:: >>> fibo.fib(1000) @@ -75,8 +76,8 @@ These statements are intended to initialize the module. They are executed only the *first* time the module name is encountered in an import statement. [#]_ (They are also run if the file is executed as a script.) -Each module has its own private symbol table, which is used as the global symbol -table by all functions defined in the module. Thus, the author of a module can +Each module has its own private namespace, which is used as the global namespace +by all functions defined in the module. Thus, the author of a module can use global variables in the module without worrying about accidental clashes with a user's global variables. On the other hand, if you know what you are doing you can touch a module's global variables with the same notation used to @@ -84,18 +85,18 @@ refer to its functions, ``modname.itemname``. Modules can import other modules. It is customary but not required to place all :keyword:`import` statements at the beginning of a module (or script, for that -matter). The imported module names are placed in the importing module's global -symbol table. +matter). The imported module names, if placed at the top level of a module +(outside any functions or classes), are added to the module's global namespace. There is a variant of the :keyword:`import` statement that imports names from a -module directly into the importing module's symbol table. For example:: +module directly into the importing module's namespace. For example:: >>> from fibo import fib, fib2 >>> fib(500) 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 This does not introduce the module name from which the imports are taken in the -local symbol table (so in the example, ``fibo`` is not defined). +local namespace (so in the example, ``fibo`` is not defined). There is even a variant to import all names that a module defines:: @@ -183,7 +184,8 @@ The Module Search Path .. index:: triple: module; search; path When a module named :mod:`spam` is imported, the interpreter first searches for -a built-in module with that name. If not found, it then searches for a file +a built-in module with that name. These module names are listed in +:data:`sys.builtin_module_names`. If not found, it then searches for a file named :file:`spam.py` in a list of directories given by the variable :data:`sys.path`. :data:`sys.path` is initialized from these locations: @@ -194,6 +196,8 @@ named :file:`spam.py` in a list of directories given by the variable * The installation-dependent default (by convention including a ``site-packages`` directory, handled by the :mod:`site` module). +More details are at :ref:`sys-path-init`. + .. note:: On file systems which support symlinks, the directory containing the input script is calculated after the symlink is followed. In other words the @@ -209,6 +213,8 @@ directory. This is an error unless the replacement is intended. See section .. % Do we need stuff on zip files etc. ? DUBOIS +.. _tut-pycache: + "Compiled" Python files ----------------------- @@ -504,7 +510,7 @@ code:: __all__ = ["echo", "surround", "reverse"] This would mean that ``from sound.effects import *`` would import the three -named submodules of the :mod:`sound` package. +named submodules of the :mod:`sound.effects` package. If ``__all__`` is not defined, the statement ``from sound.effects import *`` does *not* import all submodules from the package :mod:`sound.effects` into the @@ -575,5 +581,5 @@ modules found in a package. .. rubric:: Footnotes .. [#] In fact function definitions are also 'statements' that are 'executed'; the - execution of a module-level function definition enters the function name in - the module's global symbol table. + execution of a module-level function definition adds the function name to + the module's global namespace. diff --git a/Doc/tutorial/stdlib.rst b/Doc/tutorial/stdlib.rst index bad750424c8..4f5ada90eb5 100644 --- a/Doc/tutorial/stdlib.rst +++ b/Doc/tutorial/stdlib.rst @@ -15,7 +15,7 @@ operating system:: >>> import os >>> os.getcwd() # Return the current working directory - 'C:\\Python311' + 'C:\\Python312' >>> os.chdir('/server/accesslogs') # Change current working directory >>> os.system('mkdir today') # Run the command mkdir in the system shell 0 @@ -65,11 +65,15 @@ Command Line Arguments Common utility scripts often need to process command line arguments. These arguments are stored in the :mod:`sys` module's *argv* attribute as a list. For -instance the following output results from running ``python demo.py one two -three`` at the command line:: +instance, let's take the following :file:`demo.py` file:: + + # File demo.py + import sys + print(sys.argv) + +Here is the output from running ``python demo.py one two three`` at the command +line:: - >>> import sys - >>> print(sys.argv) ['demo.py', 'one', 'two', 'three'] The :mod:`argparse` module provides a more sophisticated mechanism to process @@ -78,8 +82,9 @@ and an optional number of lines to be displayed:: import argparse - parser = argparse.ArgumentParser(prog = 'top', - description = 'Show top lines from each file') + parser = argparse.ArgumentParser( + prog='top', + description='Show top lines from each file') parser.add_argument('filenames', nargs='+') parser.add_argument('-l', '--lines', type=int, default=10) args = parser.parse_args() @@ -178,13 +183,13 @@ protocols. Two of the simplest are :mod:`urllib.request` for retrieving data from URLs and :mod:`smtplib` for sending mail:: >>> from urllib.request import urlopen - >>> with urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl') as response: + >>> with urlopen('http://worldtimeapi.org/api/timezone/etc/UTC.txt') as response: ... for line in response: - ... line = line.decode('utf-8') # Decoding the binary data to text. - ... if 'EST' in line or 'EDT' in line: # look for Eastern Time - ... print(line) - -
    Nov. 25, 09:43:32 PM EST + ... line = line.decode() # Convert bytes to a str + ... if line.startswith('datetime'): + ... print(line.rstrip()) # Remove trailing newline + ... + datetime: 2022-01-01T01:36:47.689215+00:00 >>> import smtplib >>> server = smtplib.SMTP('localhost') @@ -326,7 +331,7 @@ Python has a "batteries included" philosophy. This is best seen through the sophisticated and robust capabilities of its larger packages. For example: * The :mod:`xmlrpc.client` and :mod:`xmlrpc.server` modules make implementing - remote procedure calls into an almost trivial task. Despite the modules + remote procedure calls into an almost trivial task. Despite the modules' names, no direct knowledge or handling of XML is needed. * The :mod:`email` package is a library for managing email messages, including diff --git a/Doc/tutorial/stdlib2.rst b/Doc/tutorial/stdlib2.rst index 69ec0d4727c..0c101c1f207 100644 --- a/Doc/tutorial/stdlib2.rst +++ b/Doc/tutorial/stdlib2.rst @@ -59,7 +59,7 @@ formatting numbers with group separators:: 'English_United States.1252' >>> conv = locale.localeconv() # get a mapping of conventions >>> x = 1234567.8 - >>> locale.format("%d", x, grouping=True) + >>> locale.format_string("%d", x, grouping=True) '1,234,567' >>> locale.format_string("%s%.*f", (conv['currency_symbol'], ... conv['frac_digits'], x), grouping=True) @@ -108,6 +108,7 @@ placeholders such as the current date, image sequence number, or file format:: >>> photofiles = ['img_1074.jpg', 'img_1076.jpg', 'img_1077.jpg'] >>> class BatchRename(Template): ... delimiter = '%' + ... >>> fmt = input('Enter rename style (%d-date %n-seqnum %f-format): ') Enter rename style (%d-date %n-seqnum %f-format): Ashley_%n%f @@ -278,7 +279,7 @@ applications include caching objects that are expensive to create:: Traceback (most recent call last): File "", line 1, in d['primary'] # entry was automatically removed - File "C:/python311/lib/weakref.py", line 46, in __getitem__ + File "C:/python312/lib/weakref.py", line 46, in __getitem__ o = self.data[key]() KeyError: 'primary' diff --git a/Doc/tutorial/venv.rst b/Doc/tutorial/venv.rst index 58ad31972f6..1fdb370b33d 100644 --- a/Doc/tutorial/venv.rst +++ b/Doc/tutorial/venv.rst @@ -60,7 +60,7 @@ Once you've created a virtual environment, you may activate it. On Windows, run:: - tutorial-env\Scripts\activate.bat + tutorial-env\Scripts\activate On Unix or MacOS, run:: @@ -130,8 +130,8 @@ package name followed by ``==`` and the version number: If you re-run this command, ``pip`` will notice that the requested version is already installed and do nothing. You can supply a -different version number to get that version, or you can run ``pip -install --upgrade`` to upgrade the package to the latest version: +different version number to get that version, or you can run ``python +-m pip install --upgrade`` to upgrade the package to the latest version: .. code-block:: bash @@ -143,14 +143,14 @@ install --upgrade`` to upgrade the package to the latest version: Successfully uninstalled requests-2.6.0 Successfully installed requests-2.7.0 -``pip uninstall`` followed by one or more package names will remove the -packages from the virtual environment. +``python -m pip uninstall`` followed by one or more package names will +remove the packages from the virtual environment. -``pip show`` will display information about a particular package: +``python -m pip show`` will display information about a particular package: .. code-block:: bash - (tutorial-env) $ pip show requests + (tutorial-env) $ python -m pip show requests --- Metadata-Version: 2.0 Name: requests @@ -163,25 +163,25 @@ packages from the virtual environment. Location: /Users/akuchling/envs/tutorial-env/lib/python3.4/site-packages Requires: -``pip list`` will display all of the packages installed in the virtual -environment: +``python -m pip list`` will display all of the packages installed in +the virtual environment: .. code-block:: bash - (tutorial-env) $ pip list + (tutorial-env) $ python -m pip list novas (3.1.1.3) numpy (1.9.2) pip (7.0.3) requests (2.7.0) setuptools (16.0) -``pip freeze`` will produce a similar list of the installed packages, -but the output uses the format that ``pip install`` expects. +``python -m pip freeze`` will produce a similar list of the installed packages, +but the output uses the format that ``python -m pip install`` expects. A common convention is to put this list in a ``requirements.txt`` file: .. code-block:: bash - (tutorial-env) $ pip freeze > requirements.txt + (tutorial-env) $ python -m pip freeze > requirements.txt (tutorial-env) $ cat requirements.txt novas==3.1.1.3 numpy==1.9.2 diff --git a/Doc/tutorial/whatnow.rst b/Doc/tutorial/whatnow.rst index 18805da90e5..dbe2d7fc099 100644 --- a/Doc/tutorial/whatnow.rst +++ b/Doc/tutorial/whatnow.rst @@ -17,7 +17,7 @@ the set are: reference material about types, functions, and the modules in the standard library. The standard Python distribution includes a *lot* of additional code. There are modules to read Unix mailboxes, retrieve documents via HTTP, generate - random numbers, parse command-line options, write CGI programs, compress data, + random numbers, parse command-line options, compress data, and many other tasks. Skimming through the Library Reference will give you an idea of what's available. @@ -31,10 +31,7 @@ the set are: More Python resources: * https://www.python.org: The major Python web site. It contains code, - documentation, and pointers to Python-related pages around the web. This web - site is mirrored in various places around the world, such as Europe, Japan, and - Australia; a mirror may be faster than the main site, depending on your - geographical location. + documentation, and pointers to Python-related pages around the web. * https://docs.python.org: Fast access to Python's documentation. @@ -48,7 +45,7 @@ More Python resources: Particularly notable contributions are collected in a book also titled Python Cookbook (O'Reilly & Associates, ISBN 0-596-00797-3.) -* http://www.pyvideo.org collects links to Python-related videos from +* https://pyvideo.org collects links to Python-related videos from conferences and user-group meetings. * https://scipy.org: The Scientific Python project includes modules for fast diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index d341ea8bb43..2a4d070ec05 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -183,6 +183,8 @@ automatically enabled, if available on your platform (see Automatic enabling of tab-completion and history editing. +.. _using-on-generic-options: + Generic options ~~~~~~~~~~~~~~~ @@ -190,8 +192,28 @@ Generic options -h --help - Print a short description of all command line options. + Print a short description of all command line options and corresponding + environment variables and exit. +.. cmdoption:: --help-env + + Print a short description of Python-specific environment variables + and exit. + + .. versionadded:: 3.11 + +.. cmdoption:: --help-xoptions + + Print a description of implementation-specific :option:`-X` options + and exit. + + .. versionadded:: 3.11 + +.. cmdoption:: --help-all + + Print complete usage information and exit. + + .. versionadded:: 3.11 .. cmdoption:: -V --version @@ -212,6 +234,7 @@ Generic options .. versionadded:: 3.6 The ``-VV`` option. + .. _using-on-misc-options: Miscellaneous options @@ -248,8 +271,11 @@ Miscellaneous options .. cmdoption:: -d - Turn on parser debugging output (for expert only, depending on compilation - options). See also :envvar:`PYTHONDEBUG`. + Turn on parser debugging output (for expert only). + See also the :envvar:`PYTHONDEBUG` environment variable. + + This option requires a :ref:`debug build of Python `, otherwise + it's ignored. .. cmdoption:: -E @@ -257,6 +283,8 @@ Miscellaneous options Ignore all :envvar:`PYTHON*` environment variables, e.g. :envvar:`PYTHONPATH` and :envvar:`PYTHONHOME`, that might be set. + See also the :option:`-P` and :option:`-I` (isolated) options. + .. cmdoption:: -i @@ -271,7 +299,9 @@ Miscellaneous options .. cmdoption:: -I - Run Python in isolated mode. This also implies -E and -s. + Run Python in isolated mode. This also implies :option:`-E`, :option:`-P` + and :option:`-s` options. + In isolated mode :data:`sys.path` contains neither the script's directory nor the user's site-packages directory. All :envvar:`PYTHON*` environment variables are ignored, too. Further restrictions may be imposed to prevent @@ -301,6 +331,23 @@ Miscellaneous options Modify ``.pyc`` filenames according to :pep:`488`. +.. cmdoption:: -P + + Don't prepend a potentially unsafe path to :data:`sys.path`: + + * ``python -m module`` command line: Don't prepend the current working + directory. + * ``python script.py`` command line: Don't prepend the script's directory. + If it's a symbolic link, resolve symbolic links. + * ``python -c code`` and ``python`` (REPL) command lines: Don't prepend an + empty string, which means the current working directory. + + See also the :envvar:`PYTHONSAFEPATH` environment variable, and :option:`-E` + and :option:`-I` (isolated) options. + + .. versionadded:: 3.11 + + .. cmdoption:: -q Don't display the copyright and version messages even in interactive mode. @@ -321,7 +368,7 @@ Miscellaneous options between repeated invocations of Python. Hash randomization is intended to provide protection against a - denial-of-service caused by carefully-chosen inputs that exploit the worst + denial-of-service caused by carefully chosen inputs that exploit the worst case performance of a dict construction, O(n\ :sup:`2`) complexity. See http://www.ocert.org/advisories/ocert-2011-003.html for details. @@ -417,7 +464,7 @@ Miscellaneous options whether the actual warning category of the message is a subclass of the specified warning category. - The *module* field matches the (fully-qualified) module name; this match is + The *module* field matches the (fully qualified) module name; this match is case-sensitive. The *lineno* field matches the line number, where zero matches all line @@ -436,6 +483,7 @@ Miscellaneous options See :ref:`warning-filter` and :ref:`describing-warning-filters` for more details. + .. cmdoption:: -x Skip the first line of the source, allowing use of non-Unix forms of @@ -457,6 +505,9 @@ Miscellaneous options stored in a traceback of a trace. Use ``-X tracemalloc=NFRAME`` to start tracing with a traceback limit of *NFRAME* frames. See the :func:`tracemalloc.start` for more information. + * ``-X int_max_str_digits`` configures the :ref:`integer string conversion + length limitation `. See also + :envvar:`PYTHONINTMAXSTRDIGITS`. * ``-X importtime`` to show how long each import takes. It shows module name, cumulative time (including nested imports) and self time (excluding nested imports). Note that its output may be broken in multi-threaded @@ -487,6 +538,11 @@ Miscellaneous options development (running from the source tree) then the default is "off". Note that the "importlib_bootstrap" and "importlib_bootstrap_external" frozen modules are always used, even if this flag is set to "off". + * ``-X perf`` enables support for the Linux ``perf`` profiler. + When this option is provided, the ``perf`` profiler will be able to + report Python calls. This option is only available on some platforms and + will do nothing if is not supported on the current system. The default value + is "off". See also :envvar:`PYTHONPERFSUPPORT` and :ref:`perf_profiling`. It also allows passing arbitrary values and retrieving them through the :data:`sys._xoptions` dictionary. @@ -528,6 +584,12 @@ Miscellaneous options .. versionadded:: 3.11 The ``-X frozen_modules`` option. + .. versionadded:: 3.11 + The ``-X int_max_str_digits`` option. + + .. versionadded:: 3.12 + The ``-X perf`` option. + Options you shouldn't use ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -536,7 +598,7 @@ Options you shouldn't use Reserved for use by Jython_. -.. _Jython: http://www.jython.org/ +.. _Jython: https://www.jython.org/ .. _using-on-envvars: @@ -583,6 +645,14 @@ conflict. within a Python program as the variable :data:`sys.path`. +.. envvar:: PYTHONSAFEPATH + + If this is set to a non-empty string, don't prepend a potentially unsafe + path to :data:`sys.path`: see the :option:`-P` option for details. + + .. versionadded:: 3.11 + + .. envvar:: PYTHONPLATLIBDIR If this is set to a non-empty string, it overrides the :data:`sys.platlibdir` @@ -631,6 +701,9 @@ conflict. :option:`-d` option. If set to an integer, it is equivalent to specifying :option:`-d` multiple times. + This environment variable requires a :ref:`debug build of Python + `, otherwise it's ignored. + .. envvar:: PYTHONINSPECT @@ -695,6 +768,13 @@ conflict. .. versionadded:: 3.2.3 +.. envvar:: PYTHONINTMAXSTRDIGITS + + If this variable is set to an integer, it is used to configure the + interpreter's global :ref:`integer string conversion length limitation + `. + + .. versionadded:: 3.11 .. envvar:: PYTHONIOENCODING @@ -921,7 +1001,7 @@ conflict. order to force the interpreter to use ``ASCII`` instead of ``UTF-8`` for system interfaces. - .. availability:: \*nix. + .. availability:: Unix. .. versionadded:: 3.7 See :pep:`538` for more details. @@ -965,20 +1045,22 @@ conflict. .. versionadded:: 3.11 +.. envvar:: PYTHONPERFSUPPORT + + If this variable is set to a nonzero value, it enables support for + the Linux ``perf`` profiler so Python calls can be detected by it. + + If set to ``0``, disable Linux ``perf`` profiler support. + + See also the :option:`-X perf <-X>` command-line option + and :ref:`perf_profiling`. + + .. versionadded:: 3.12 Debug-mode variables ~~~~~~~~~~~~~~~~~~~~ -.. envvar:: PYTHONTHREADDEBUG - - If set, Python will print threading debug info into stdout. - - Need a :ref:`debug build of Python `. - - .. deprecated-removed:: 3.10 3.12 - - .. envvar:: PYTHONDUMPREFS If set, Python will dump objects and reference counts still alive after diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index f00766dfc4f..8fa8d250d53 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -2,6 +2,47 @@ Configure Python **************** +Build Requirements +================== + +Features required to build CPython: + +* A `C11 `_ compiler. `Optional C11 + features + `_ + are not required. + +* Support for `IEEE 754 `_ floating + point numbers and `floating point Not-a-Number (NaN) + `_. + +* Support for threads. + +* OpenSSL 1.1.1 or newer for the :mod:`ssl` and :mod:`hashlib` modules. + +* On Windows, Microsoft Visual Studio 2017 or later is required. + +.. versionchanged:: 3.11 + C11 compiler, IEEE 754 and NaN support are now required. + On Windows, Visual Studio 2017 or later is required. + +.. versionchanged:: 3.10 + OpenSSL 1.1.1 is now required. + +.. versionchanged:: 3.7 + Thread support and OpenSSL 1.0.2 are now required. + +.. versionchanged:: 3.6 + Selected C99 features are now required, like ```` and ``static + inline`` functions. + +.. versionchanged:: 3.5 + On Windows, Visual Studio 2015 or later is required. + +See also :pep:`7` "Style Guide for C Code" and :pep:`11` "CPython platform +support". + + .. _configure-options: Configure Options @@ -35,25 +76,24 @@ General Options Define the size in bits of Python :class:`int` digits: 15 or 30 bits. - By default, the number of bits is selected depending on ``sizeof(void*)``: - 30 bits if ``void*`` size is 64-bit or larger, 15 bits otherwise. + By default, the digit size is 30. Define the ``PYLONG_BITS_IN_DIGIT`` to ``15`` or ``30``. See :data:`sys.int_info.bits_per_digit `. -.. cmdoption:: --with-cxx-main -.. cmdoption:: --with-cxx-main=COMPILER - - Compile the Python ``main()`` function and link Python executable with C++ - compiler: ``$CXX``, or *COMPILER* if specified. - .. cmdoption:: --with-suffix=SUFFIX Set the Python executable suffix to *SUFFIX*. The default suffix is ``.exe`` on Windows and macOS (``python.exe`` - executable), and an empty string on other platforms (``python`` executable). + executable), ``.js`` on Emscripten node, ``.html`` on Emscripten browser, + ``.wasm`` on WASI, and an empty string on other platforms (``python`` + executable). + + .. versionchanged:: 3.11 + The default suffix on WASM platform is one of ``.js``, ``.html`` + or ``.wasm``. .. cmdoption:: --with-tzpath= @@ -76,7 +116,7 @@ General Options .. versionadded:: 3.9 -.. cmdoption:: --with-dbmliborder=db1:db2:... +.. cmdoption:: --with-dbmliborder= Override order to check db backends for the :mod:`dbm` module @@ -94,6 +134,12 @@ General Options See :envvar:`PYTHONCOERCECLOCALE` and the :pep:`538`. +.. cmdoption:: --without-freelists + + Disable all freelists except the empty tuple singleton. + + .. versionadded:: 3.11 + .. cmdoption:: --with-platlibdir=DIRNAME Python library directory name (default is ``lib``). @@ -127,6 +173,45 @@ General Options .. versionadded:: 3.11 +.. cmdoption:: --enable-pystats + + Turn on internal statistics gathering. + + The statistics will be dumped to a arbitrary (probably unique) file in + ``/tmp/py_stats/``, or ``C:\temp\py_stats\`` on Windows. If that directory + does not exist, results will be printed on stdout. + + Use ``Tools/scripts/summarize_stats.py`` to read the stats. + + .. versionadded:: 3.11 + +WebAssembly Options +------------------- + +.. cmdoption:: --with-emscripten-target=[browser|node] + + Set build flavor for ``wasm32-emscripten``. + + * ``browser`` (default): preload minimal stdlib, default MEMFS. + * ``node``: NODERAWFS and pthread support. + + .. versionadded:: 3.11 + +.. cmdoption:: --enable-wasm-dynamic-linking + + Turn on dynamic linking support for WASM. + + Dynamic linking enables ``dlopen``. File size of the executable + increases due to limited dead code elimination and additional features. + + .. versionadded:: 3.11 + +.. cmdoption:: --enable-wasm-pthreads + + Turn on pthreads support for WASM. + + .. versionadded:: 3.11 + Install Options --------------- @@ -154,7 +239,8 @@ Performance options ------------------- Configuring Python using ``--enable-optimizations --with-lto`` (PGO + LTO) is -recommended for best performance. +recommended for best performance. The experimental ``--enable-bolt`` flag can +also be used to improve performance. .. cmdoption:: --enable-optimizations @@ -194,6 +280,27 @@ recommended for best performance. .. versionadded:: 3.11 To use ThinLTO feature, use ``--with-lto=thin`` on Clang. + .. versionchanged:: 3.12 + Use ThinLTO as the default optimization policy on Clang if the compiler accepts the flag. + +.. cmdoption:: --enable-bolt + + Enable usage of the `BOLT post-link binary optimizer + `_ (disabled by + default). + + BOLT is part of the LLVM project but is not always included in their binary + distributions. This flag requires that ``llvm-bolt`` and ``merge-fdata`` + are available. + + BOLT is still a fairly new project so this flag should be considered + experimental for now. Because this tool operates on machine code its success + is dependent on a combination of the build environment + the other + optimization configure args + the CPU architecture, and not all combinations + are supported. + + .. versionadded:: 3.12 + .. cmdoption:: --with-computed-gotos Enable computed gotos in evaluation loop (enabled by default on supported @@ -235,8 +342,9 @@ Effects of a debug build: * Add ``d`` to :data:`sys.abiflags`. * Add :func:`sys.gettotalrefcount` function. * Add :option:`-X showrefcount <-X>` command line option. -* Add :envvar:`PYTHONTHREADDEBUG` environment variable. -* Add support for the ``__ltrace__`` variable: enable low-level tracing in the +* Add :option:`-d` command line option and :envvar:`PYTHONDEBUG` environment + variable to debug the parser. +* Add support for the ``__lltrace__`` variable: enable low-level tracing in the bytecode evaluation loop if the variable is defined. * Install :ref:`debug hooks on memory allocators ` to detect buffer overflow and other memory errors. @@ -251,6 +359,7 @@ Effects of a debug build: to detect usage of uninitialized objects. * Ensure that functions which can clear or replace the current exception are not called with an exception raised. + * Check that deallocator functions don't change the current exception. * The garbage collector (:func:`gc.collect` function) runs some basic checks on objects consistency. * The :c:macro:`Py_SAFE_DOWNCAST()` macro checks for integer underflow and @@ -362,11 +471,6 @@ Libraries options Build the :mod:`pyexpat` module using an installed ``expat`` library (default is no). -.. cmdoption:: --with-system-ffi - - Build the :mod:`_ctypes` extension module using an installed ``ffi`` - library, see the :mod:`ctypes` module (default is system-dependent). - .. cmdoption:: --with-system-libmpdec Build the ``_decimal`` extension module using an installed ``mpdec`` @@ -390,14 +494,6 @@ Libraries options .. versionadded:: 3.10 -.. cmdoption:: --with-tcltk-includes='-I...' - - Override search for Tcl and Tk include files. - -.. cmdoption:: --with-tcltk-libs='-L...' - - Override search for Tcl and Tk libraries. - .. cmdoption:: --with-libm=STRING Override ``libm`` math library to *STRING* (default is system-dependent). @@ -509,6 +605,48 @@ See ``Mac/README.rst``. :option:`--enable-framework` is set (default: ``Python``). +Cross Compiling Options +----------------------- + +Cross compiling, also known as cross building, can be used to build Python +for another CPU architecture or platform. Cross compiling requires a Python +interpreter for the build platform. The version of the build Python must match +the version of the cross compiled host Python. + +.. cmdoption:: --build=BUILD + + configure for building on BUILD, usually guessed by :program:`config.guess`. + +.. cmdoption:: --host=HOST + + cross-compile to build programs to run on HOST (target platform) + +.. cmdoption:: --with-build-python=path/to/python + + path to build ``python`` binary for cross compiling + + .. versionadded:: 3.11 + +.. cmdoption:: CONFIG_SITE=file + + An environment variable that points to a file with configure overrides. + + Example *config.site* file:: + + # config.site-aarch64 + ac_cv_buggy_getaddrinfo=no + ac_cv_file__dev_ptmx=yes + ac_cv_file__dev_ptc=no + + +Cross compiling example:: + + CONFIG_SITE=config.site-aarch64 ../configure \ + --build=x86_64-pc-linux-gnu \ + --host=aarch64-unknown-linux-gnu \ + --with-build-python=../x86_64/python + + Python Build System =================== @@ -520,7 +658,7 @@ Main files of the build system * :file:`pyconfig.h` (created by :file:`configure`); * :file:`Modules/Setup`: C extensions built by the Makefile using :file:`Module/makesetup` shell script; -* :file:`setup.py`: C extensions built using the :mod:`distutils` module. +* :file:`setup.py`: C extensions built using the ``setuptools`` package. Main build steps ---------------- @@ -642,22 +780,10 @@ Compiler flags Example: ``gcc -pthread``. -.. envvar:: MAINCC - - C compiler command used to build the ``main()`` function of programs like - ``python``. - - Variable set by the :option:`--with-cxx-main` option of the configure - script. - - Default: ``$(CC)``. - .. envvar:: CXX C++ compiler command. - Used if the :option:`--with-cxx-main` option is used. - Example: ``g++ -pthread``. .. envvar:: CFLAGS @@ -670,8 +796,26 @@ Compiler flags extensions. Use it when a compiler flag should *not* be part of the distutils :envvar:`CFLAGS` once Python is installed (:issue:`21121`). + In particular, :envvar:`CFLAGS` should not contain: + + * the compiler flag ``-I`` (for setting the search path for include files). + The ``-I`` flags are processed from left to right, and any flags in + :envvar:`CFLAGS` would take precedence over user- and package-supplied ``-I`` + flags. + + * hardening flags such as ``-Werror`` because distributions cannot control + whether packages installed by users conform to such heightened + standards. + .. versionadded:: 3.5 +.. envvar:: COMPILEALL_OPTS + + Options passed to the :mod:`compileall` command line when building PYC files + in ``make install``. Default: ``-j0``. + + .. versionadded:: 3.12 + .. envvar:: EXTRA_CFLAGS Extra C compiler flags. @@ -764,7 +908,7 @@ Linker flags Linker command used to build programs like ``python`` and ``_testembed``. - Default: ``$(PURIFY) $(MAINCC)``. + Default: ``$(PURIFY) $(CC)``. .. envvar:: CONFIGURE_LDFLAGS @@ -782,6 +926,13 @@ Linker flags :envvar:`CFLAGS_NODIST`. Use it when a linker flag should *not* be part of the distutils :envvar:`LDFLAGS` once Python is installed (:issue:`35257`). + In particular, :envvar:`LDFLAGS` should not contain: + + * the compiler flag ``-L`` (for setting the search path for libraries). + The ``-L`` flags are processed from left to right, and any flags in + :envvar:`LDFLAGS` would take precedence over user- and package-supplied ``-L`` + flags. + .. envvar:: CONFIGURE_LDFLAGS_NODIST Value of :envvar:`LDFLAGS_NODIST` variable passed to the ``./configure`` diff --git a/Doc/using/mac.rst b/Doc/using/mac.rst index 2f132a96bef..9ae0270eaee 100644 --- a/Doc/using/mac.rst +++ b/Doc/using/mac.rst @@ -17,15 +17,16 @@ the IDE and the Package Manager that are worth pointing out. Getting and Installing MacPython ================================ -macOS since version 10.8 comes with Python 2.7 pre-installed by Apple. If you wish, you -are invited to install the most recent version of Python 3 from the Python +macOS used to come with Python 2.7 pre-installed between versions +10.8 and `12.3 `_. +You are invited to install the most recent version of Python 3 from the Python website (https://www.python.org). A current "universal binary" build of Python, which runs natively on the Mac's new Intel and legacy PPC CPU's, is available there. What you get after installing is a number of things: -* A :file:`Python 3.9` folder in your :file:`Applications` folder. In here +* A :file:`Python 3.12` folder in your :file:`Applications` folder. In here you find IDLE, the development environment that is a standard part of official Python distributions; and PythonLauncher, which handles double-clicking Python scripts from the Finder. @@ -65,7 +66,7 @@ number of standard Unix command line editors, :program:`vim` and :program:`BBEdit` or :program:`TextWrangler` from Bare Bones Software (see http://www.barebones.com/products/bbedit/index.html) are good choices, as is :program:`TextMate` (see https://macromates.com/). Other editors include -:program:`Gvim` (http://macvim-dev.github.io/macvim/) and :program:`Aquamacs` +:program:`Gvim` (https://macvim-dev.github.io/macvim/) and :program:`Aquamacs` (http://aquamacs.org/). To run your script from the Terminal window you must make sure that @@ -160,7 +161,7 @@ Distributing Python Applications on the Mac The standard tool for deploying standalone Python applications on the Mac is :program:`py2app`. More information on installing and using py2app can be found -at http://undefined.org/python/#py2app. +at https://pypi.org/project/py2app/. Other Resources diff --git a/Doc/using/unix.rst b/Doc/using/unix.rst index 0a1834453a0..24c02c99f87 100644 --- a/Doc/using/unix.rst +++ b/Doc/using/unix.rst @@ -69,7 +69,7 @@ Building Python If you want to compile CPython yourself, first thing you should do is get the `source `_. You can download either the latest release's source or just grab a fresh `clone -`_. (If you want +`_. (If you want to contribute patches, you will need a clone.) The build process consists of the usual commands:: @@ -158,19 +158,19 @@ Custom OpenSSL .. code-block:: shell-session $ curl -O https://www.openssl.org/source/openssl-VERSION.tar.gz - $ tar xzf openssl-VERSION - $ pushd openssl-VERSION - $ ./config \ - --prefix=/usr/local/custom-openssl \ - --libdir=lib \ - --openssldir=/etc/ssl - $ make -j1 depend - $ make -j8 - $ make install_sw - $ popd + $ tar xzf openssl-VERSION + $ pushd openssl-VERSION + $ ./config \ + --prefix=/usr/local/custom-openssl \ + --libdir=lib \ + --openssldir=/etc/ssl + $ make -j1 depend + $ make -j8 + $ make install_sw + $ popd 3. Build Python with custom OpenSSL - (see the configure `--with-openssl` and `--with-openssl-rpath` options) + (see the configure ``--with-openssl`` and ``--with-openssl-rpath`` options) .. code-block:: shell-session diff --git a/Doc/using/venv-create.inc b/Doc/using/venv-create.inc index ddb36f94667..d535b254f05 100644 --- a/Doc/using/venv-create.inc +++ b/Doc/using/venv-create.inc @@ -16,8 +16,8 @@ re-used. .. deprecated:: 3.6 ``pyvenv`` was the recommended tool for creating virtual environments for - Python 3.3 and 3.4, and is `deprecated in Python 3.6 - `_. + Python 3.3 and 3.4, and is + :ref:`deprecated in Python 3.6 `. .. versionchanged:: 3.5 The use of ``venv`` is now recommended for creating virtual environments. @@ -26,7 +26,7 @@ re-used. On Windows, invoke the ``venv`` command as follows:: - c:\>c:\Python35\python -m venv c:\path\to\myenv + c:\>Python35\python -m venv c:\path\to\myenv Alternatively, if you configured the ``PATH`` and ``PATHEXT`` variables for your :ref:`Python installation `:: @@ -105,45 +105,3 @@ Multiple paths can be given to ``venv``, in which case an identical virtual environment will be created, according to the given options, at each provided path. -Once a virtual environment has been created, it can be "activated" using a -script in the virtual environment's binary directory. The invocation of the -script is platform-specific (`` must be replaced by the path of the -directory containing the virtual environment): - -+-------------+-----------------+-----------------------------------------+ -| Platform | Shell | Command to activate virtual environment | -+=============+=================+=========================================+ -| POSIX | bash/zsh | $ source /bin/activate | -+-------------+-----------------+-----------------------------------------+ -| | fish | $ source /bin/activate.fish | -+-------------+-----------------+-----------------------------------------+ -| | csh/tcsh | $ source /bin/activate.csh | -+-------------+-----------------+-----------------------------------------+ -| | PowerShell Core | $ /bin/Activate.ps1 | -+-------------+-----------------+-----------------------------------------+ -| Windows | cmd.exe | C:\\> \\Scripts\\activate.bat | -+-------------+-----------------+-----------------------------------------+ -| | PowerShell | PS C:\\> \\Scripts\\Activate.ps1 | -+-------------+-----------------+-----------------------------------------+ - -When a virtual environment is active, the :envvar:`VIRTUAL_ENV` environment -variable is set to the path of the virtual environment. This can be used to -check if one is running inside a virtual environment. - -You don't specifically *need* to activate an environment; activation just -prepends the virtual environment's binary directory to your path, so that -"python" invokes the virtual environment's Python interpreter and you can run -installed scripts without having to use their full path. However, all scripts -installed in a virtual environment should be runnable without activating it, -and run with the virtual environment's Python automatically. - -You can deactivate a virtual environment by typing "deactivate" in your shell. -The exact mechanism is platform-specific and is an internal implementation -detail (typically a script or shell function will be used). - -.. versionadded:: 3.4 - ``fish`` and ``csh`` activation scripts. - -.. versionadded:: 3.8 - PowerShell activation scripts installed under POSIX for PowerShell Core - support. diff --git a/Doc/using/win_installer.png b/Doc/using/win_installer.png index 9c18ff19cf5..03bf2d7b16c 100644 Binary files a/Doc/using/win_installer.png and b/Doc/using/win_installer.png differ diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 68ee09c565e..bd09666d5e0 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -34,7 +34,7 @@ developers using Python for any kind of project. :ref:`windows-store` is a simple installation of Python that is suitable for running scripts and packages, and using IDLE or other development environments. -It requires Windows 10, but can be safely installed without corrupting other +It requires Windows 10 and above, but can be safely installed without corrupting other programs. It also provides many convenient commands for launching Python and its tools. @@ -126,11 +126,24 @@ command line, allowing scripted installers to replicate an installation on many machines without user interaction. These options may also be set without suppressing the UI in order to change some of the defaults. -To completely hide the installer UI and install Python silently, pass the -``/quiet`` option. To skip past the user interaction but still display -progress and errors, pass the ``/passive`` option. The ``/uninstall`` -option may be passed to immediately begin removing Python - no prompt will be -displayed. +The following options (found by executing the installer with ``/?``) can be +passed into the installer: + ++---------------------+--------------------------------------------------------+ +| Name | Description | ++=====================+========================================================+ +| /passive | to display progress without requiring user interaction | ++---------------------+--------------------------------------------------------+ +| /quiet | to install/uninstall without displaying any UI | ++---------------------+--------------------------------------------------------+ +| /simple | to prevent user customization | ++---------------------+--------------------------------------------------------+ +| /uninstall | to remove Python (without confirmation) | ++---------------------+--------------------------------------------------------+ +| /layout [directory] | to pre-download all components | ++---------------------+--------------------------------------------------------+ +| /log [filename] | to specify log files location | ++---------------------+--------------------------------------------------------+ All other options are passed as ``name=value``, where the value is usually ``0`` to disable a feature, ``1`` to enable a feature, or a path. The full list @@ -150,11 +163,14 @@ of available options is shown below. | | | Python X.Y` | +---------------------------+--------------------------------------+--------------------------+ | DefaultJustForMeTargetDir | The default install directory for | :file:`%LocalAppData%\\\ | -| | just-for-me installs | Programs\\PythonXY` or | +| | just-for-me installs | Programs\\Python\\\ | +| | | PythonXY` or | | | | :file:`%LocalAppData%\\\ | -| | | Programs\\PythonXY-32` or| +| | | Programs\\Python\\\ | +| | | PythonXY-32` or | | | | :file:`%LocalAppData%\\\ | -| | | Programs\\PythonXY-64` | +| | | Programs\\Python\\\ | +| | | PythonXY-64` | +---------------------------+--------------------------------------+--------------------------+ | DefaultCustomTargetDir | The default custom install directory | (empty) | | | displayed in the UI | | @@ -165,9 +181,13 @@ of available options is shown below. | CompileAll | Compile all ``.py`` files to | 0 | | | ``.pyc``. | | +---------------------------+--------------------------------------+--------------------------+ -| PrependPath | Add install and Scripts directories | 0 | -| | to :envvar:`PATH` and ``.PY`` to | | -| | :envvar:`PATHEXT` | | +| PrependPath | Prepend install and Scripts | 0 | +| | directories to :envvar:`PATH` and | | +| | add ``.PY`` to :envvar:`PATHEXT` | | ++---------------------------+--------------------------------------+--------------------------+ +| AppendPath | Append install and Scripts | 0 | +| | directories to :envvar:`PATH` and | | +| | add ``.PY`` to :envvar:`PATHEXT` | | +---------------------------+--------------------------------------+--------------------------+ | Shortcuts | Create shortcuts for the interpreter,| 1 | | | documentation and IDLE if installed. | | @@ -177,22 +197,26 @@ of available options is shown below. | Include_debug | Install debug binaries | 0 | +---------------------------+--------------------------------------+--------------------------+ | Include_dev | Install developer headers and | 1 | -| | libraries | | +| | libraries. Omitting this may lead to | | +| | an unusable installation. | | +---------------------------+--------------------------------------+--------------------------+ | Include_exe | Install :file:`python.exe` and | 1 | -| | related files | | +| | related files. Omitting this may | | +| | lead to an unusable installation. | | +---------------------------+--------------------------------------+--------------------------+ | Include_launcher | Install :ref:`launcher`. | 1 | +---------------------------+--------------------------------------+--------------------------+ -| InstallLauncherAllUsers | Installs :ref:`launcher` for all | 1 | -| | users. | | +| InstallLauncherAllUsers | Installs the launcher for all | 1 | +| | users. Also requires | | +| | ``Include_launcher`` to be set to 1 | | +---------------------------+--------------------------------------+--------------------------+ | Include_lib | Install standard library and | 1 | -| | extension modules | | +| | extension modules. Omitting this may | | +| | lead to an unusable installation. | | +---------------------------+--------------------------------------+--------------------------+ | Include_pip | Install bundled pip and setuptools | 1 | +---------------------------+--------------------------------------+--------------------------+ -| Include_symbols | Install debugging symbols (`*`.pdb) | 0 | +| Include_symbols | Install debugging symbols (``*.pdb``)| 0 | +---------------------------+--------------------------------------+--------------------------+ | Include_tcltk | Install Tcl/Tk support and IDLE | 1 | +---------------------------+--------------------------------------+--------------------------+ @@ -331,14 +355,42 @@ Python in Start and right-click to select Uninstall. Uninstalling will remove all packages you installed directly into this Python installation, but will not remove any virtual environments -Known Issues +Known issues ------------ +Redirection of local data, registry, and temporary paths +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Because of restrictions on Microsoft Store apps, Python scripts may not have -full write access to shared locations such as ``TEMP`` and the registry. +full write access to shared locations such as :envvar:`TEMP` and the registry. Instead, it will write to a private copy. If your scripts must modify the shared locations, you will need to install the full installer. +At runtime, Python will use a private copy of well-known Windows folders and the registry. +For example, if the environment variable :envvar:`%APPDATA%` is :file:`c:\\Users\\\\AppData\\`, +then when writing to :file:`C:\\Users\\\\AppData\\Local` will write to +:file:`C:\\Users\\\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\\LocalCache\\Local\\`. + +When reading files, Windows will return the file from the private folder, or if that does not exist, the +real Windows directory. For example reading :file:`C:\\Windows\\System32` returns the contents of :file:`C:\\Windows\\System32` +plus the contents of :file:`C:\\Program Files\\WindowsApps\\package_name\\VFS\\SystemX86`. + +You can find the real path of any existing file using :func:`os.path.realpath`: + +.. code-block:: python + + >>> import os + >>> test_file = 'C:\\Users\\example\\AppData\\Local\\test.txt' + >>> os.path.realpath(test_file) + 'C:\\Users\\example\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\\LocalCache\\Local\\test.txt' + +When writing to the Windows Registry, the following behaviors exist: + +* Reading from ``HKLM\\Software`` is allowed and results are merged with the :file:`registry.dat` file in the package. +* Writing to ``HKLM\\Software`` is not allowed if the corresponding key/value exists, i.e. modifying existing keys. +* Writing to ``HKLM\\Software`` is allowed as long as a corresponding key/value does not exist in the package + and the user has the correct access permissions. + For more detail on the technical basis for these limitations, please consult Microsoft's documentation on packaged full-trust apps, currently available at `docs.microsoft.com/en-us/windows/msix/desktop/desktop-to-uwp-behind-the-scenes @@ -374,7 +426,9 @@ may be changed from ``.``, and the package will be installed into a subdirectory. By default, the subdirectory is named the same as the package, and without the ``-ExcludeVersion`` option this name will include the specific version installed. Inside the subdirectory is a ``tools`` directory that -contains the Python installation:: +contains the Python installation: + +.. code-block:: doscon # Without -ExcludeVersion > .\python.3.5.2\tools\python.exe -V @@ -421,7 +475,7 @@ dependants, such as Idle), pip and the Python documentation are not included. .. note:: The embedded distribution does not include the `Microsoft C Runtime - `_ and it is + `_ and it is the responsibility of the application installer to provide this. The runtime may have already been installed on a user's system previously or automatically via Windows Update, and can be detected by finding @@ -494,9 +548,11 @@ key features: Popular scientific modules (such as numpy, scipy and pandas) and the ``conda`` package manager. -`Canopy `_ - A "comprehensive Python analysis environment" with editors and other - development tools. +`Enthought Deployment Manager `_ + "The Next Generation Python Environment and Package Manager". + + Previously Enthought provided Canopy, but it `reached end of life in 2016 + `_. `WinPython `_ Windows-specific distribution with prebuilt scientific packages and @@ -555,27 +611,22 @@ System variables, you need non-restricted access to your machine Windows will concatenate User variables *after* System variables, which may cause unexpected results when modifying :envvar:`PATH`. - The :envvar:`PYTHONPATH` variable is used by all versions of Python 2 and - Python 3, so you should not permanently configure this variable unless it - only includes code that is compatible with all of your installed Python + The :envvar:`PYTHONPATH` variable is used by all versions of Python, + so you should not permanently configure it unless the listed paths + only include code that is compatible with all of your installed Python versions. .. seealso:: - https://www.microsoft.com/en-us/wdsi/help/folder-variables - Environment variables in Windows NT + https://docs.microsoft.com/en-us/windows/win32/procthread/environment-variables + Overview of environment variables on Windows - https://technet.microsoft.com/en-us/library/cc754250.aspx - The SET command, for temporarily modifying environment variables + https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/set_1 + The ``set`` command, for temporarily modifying environment variables - https://technet.microsoft.com/en-us/library/cc755104.aspx - The SETX command, for permanently modifying environment variables + https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/setx + The ``setx`` command, for permanently modifying environment variables - https://support.microsoft.com/en-us/help/310519/how-to-manage-environment-variables-in-windows-xp - How To Manage Environment Variables in Windows XP - - https://www.chem.gla.ac.uk/~louis/software/faq/q1.html - Setting Environment variables, Louis J. Farrugia .. _windows-path-mod: @@ -614,7 +665,7 @@ UTF-8 mode Windows still uses legacy encodings for the system encoding (the ANSI Code Page). Python uses it for the default encoding of text files (e.g. -:func:`locale.getpreferredencoding`). +:func:`locale.getencoding`). This may cause issues because UTF-8 is widely used on the internet and most Unix systems, including WSL (Windows Subsystem for Linux). @@ -673,9 +724,7 @@ From the command-line System-wide installations of Python 3.3 and later will put the launcher on your :envvar:`PATH`. The launcher is compatible with all available versions of Python, so it does not matter which version is installed. To check that the -launcher is available, execute the following command in Command Prompt: - -:: +launcher is available, execute the following command in Command Prompt:: py @@ -683,26 +732,20 @@ You should find that the latest version of Python you have installed is started - it can be exited as normal, and any additional command-line arguments specified will be sent directly to Python. -If you have multiple versions of Python installed (e.g., 2.7 and |version|) you -will have noticed that Python |version| was started - to launch Python 2.7, try -the command: +If you have multiple versions of Python installed (e.g., 3.7 and |version|) you +will have noticed that Python |version| was started - to launch Python 3.7, try +the command:: -:: + py -3.7 - py -2.7 - -If you want the latest version of Python 2.x you have installed, try the -command: - -:: +If you want the latest version of Python 2 you have installed, try the +command:: py -2 -You should find the latest version of Python 2.x starts. +You should find the latest version of Python 3.x starts. -If you see the following error, you do not have the launcher installed: - -:: +If you see the following error, you do not have the launcher installed:: 'py' is not recognized as an internal or external command, operable program or batch file. @@ -710,6 +753,12 @@ If you see the following error, you do not have the launcher installed: Per-user installations of Python do not add the launcher to :envvar:`PATH` unless the option was selected on installation. +The command:: + + py --list + +displays the currently installed version(s) of Python. + Virtual environments ^^^^^^^^^^^^^^^^^^^^ @@ -734,9 +783,7 @@ following contents import sys sys.stdout.write("hello from Python %s\n" % (sys.version,)) -From the directory in which hello.py lives, execute the command: - -:: +From the directory in which hello.py lives, execute the command:: py hello.py @@ -749,9 +796,9 @@ is printed. Now try changing the first line to be: Re-executing the command should now print the latest Python 3.x information. As with the above command-line examples, you can specify a more explicit -version qualifier. Assuming you have Python 2.6 installed, try changing the -first line to ``#! python2.6`` and you should find the 2.6 version -information printed. +version qualifier. Assuming you have Python 3.7 installed, try changing +the first line to ``#! python3.7`` and you should find the 3.7 +version information printed. Note that unlike interactive use, a bare "python" will use the latest version of Python 2.x that you have installed. This is for backward @@ -784,7 +831,7 @@ To allow shebang lines in Python scripts to be portable between Unix and Windows, this launcher supports a number of 'virtual' commands to specify which interpreter to use. The supported virtual commands are: -* ``/usr/bin/env python`` +* ``/usr/bin/env`` * ``/usr/bin/python`` * ``/usr/local/bin/python`` * ``python`` @@ -804,8 +851,8 @@ shebang lines starting with ``/usr``. Any of the above virtual commands can be suffixed with an explicit version (either just the major version, or the major and minor version). Furthermore the 32-bit version can be requested by adding "-32" after the -minor version. I.e. ``/usr/bin/python2.7-32`` will request usage of the -32-bit python 2.7. +minor version. I.e. ``/usr/bin/python3.7-32`` will request usage of the +32-bit python 3.7. .. versionadded:: 3.7 @@ -813,10 +860,43 @@ minor version. I.e. ``/usr/bin/python2.7-32`` will request usage of the by the "-64" suffix. Furthermore it is possible to specify a major and architecture without minor (i.e. ``/usr/bin/python3-64``). +.. versionchanged:: 3.11 + + The "-64" suffix is deprecated, and now implies "any architecture that is + not provably i386/32-bit". To request a specific environment, use the new + ``-V:`` argument with the complete tag. + The ``/usr/bin/env`` form of shebang line has one further special property. Before looking for installed Python interpreters, this form will search the -executable :envvar:`PATH` for a Python executable. This corresponds to the -behaviour of the Unix ``env`` program, which performs a :envvar:`PATH` search. +executable :envvar:`PATH` for a Python executable matching the name provided +as the first argument. This corresponds to the behaviour of the Unix ``env`` +program, which performs a :envvar:`PATH` search. +If an executable matching the first argument after the ``env`` command cannot +be found, but the argument starts with ``python``, it will be handled as +described for the other virtual commands. +The environment variable :envvar:`PYLAUNCHER_NO_SEARCH_PATH` may be set +(to any value) to skip this search of :envvar:`PATH`. + +Shebang lines that do not match any of these patterns are looked up in the +``[commands]`` section of the launcher's :ref:`.INI file `. +This may be used to handle certain commands in a way that makes sense for your +system. The name of the command must be a single argument (no spaces in the +shebang executable), and the value substituted is the full path to the +executable (additional arguments specified in the .INI will be quoted as part +of the filename). + +.. code-block:: ini + + [commands] + /bin/xpython=C:\Program Files\XPython\python.exe + +Any commands not found in the .INI file are treated as **Windows** executable +paths that are absolute or relative to the directory containing the script file. +This is a convenience for Windows-only scripts, such as those generated by an +installer, since the behavior is not compatible with Unix-style shells. +These paths may be quoted, and may include multiple arguments, after which the +path to the script and any additional arguments will be appended. + Arguments in shebang lines -------------------------- @@ -833,15 +913,16 @@ Then Python will be started with the ``-v`` option Customization ------------- +.. _launcher-ini: + Customization via INI files ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Two .ini files will be searched by the launcher - ``py.ini`` in the current -user's "application data" directory (i.e. the directory returned by calling the -Windows function ``SHGetFolderPath`` with ``CSIDL_LOCAL_APPDATA``) and ``py.ini`` in the -same directory as the launcher. The same .ini files are used for both the -'console' version of the launcher (i.e. py.exe) and for the 'windows' version -(i.e. pyw.exe). +user's application data directory (``%LOCALAPPDATA%`` or ``$env:LocalAppData``) +and ``py.ini`` in the same directory as the launcher. The same .ini files are +used for both the 'console' version of the launcher (i.e. py.exe) and for the +'windows' version (i.e. pyw.exe). Customization specified in the "application directory" will have precedence over the one next to the executable, so a user, who may not have write access to the @@ -891,19 +972,19 @@ Examples: ``python2`` will use the latest Python 2.x version installed and the command ``python3`` will use the latest Python 3.x installed. -* The commands ``python3.1`` and ``python2.7`` will not consult any +* The command ``python3.7`` will not consult any options at all as the versions are fully specified. * If ``PY_PYTHON=3``, the commands ``python`` and ``python3`` will both use the latest installed Python 3 version. -* If ``PY_PYTHON=3.1-32``, the command ``python`` will use the 32-bit - implementation of 3.1 whereas the command ``python3`` will use the latest +* If ``PY_PYTHON=3.7-32``, the command ``python`` will use the 32-bit + implementation of 3.7 whereas the command ``python3`` will use the latest installed Python (PY_PYTHON was not considered at all as a major version was specified.) -* If ``PY_PYTHON=3`` and ``PY_PYTHON3=3.1``, the commands - ``python`` and ``python3`` will both use specifically 3.1 +* If ``PY_PYTHON=3`` and ``PY_PYTHON3=3.7``, the commands + ``python`` and ``python3`` will both use specifically 3.7 In addition to environment variables, the same settings can be configured in the .INI file used by the launcher. The section in the INI file is @@ -914,60 +995,93 @@ an environment variable will override things specified in the INI file. For example: -* Setting ``PY_PYTHON=3.1`` is equivalent to the INI file containing: +* Setting ``PY_PYTHON=3.7`` is equivalent to the INI file containing: .. code-block:: ini [defaults] - python=3.1 + python=3.7 -* Setting ``PY_PYTHON=3`` and ``PY_PYTHON3=3.1`` is equivalent to the INI file +* Setting ``PY_PYTHON=3`` and ``PY_PYTHON3=3.7`` is equivalent to the INI file containing: .. code-block:: ini [defaults] python=3 - python3=3.1 + python3=3.7 Diagnostics ----------- -If an environment variable ``PYLAUNCH_DEBUG`` is set (to any value), the +If an environment variable :envvar:`PYLAUNCHER_DEBUG` is set (to any value), the launcher will print diagnostic information to stderr (i.e. to the console). While this information manages to be simultaneously verbose *and* terse, it should allow you to see what versions of Python were located, why a particular version was chosen and the exact command-line used to execute the -target Python. +target Python. It is primarily intended for testing and debugging. + +Dry Run +------- + +If an environment variable :envvar:`PYLAUNCHER_DRYRUN` is set (to any value), +the launcher will output the command it would have run, but will not actually +launch Python. This may be useful for tools that want to use the launcher to +detect and then launch Python directly. Note that the command written to +standard output is always encoded using UTF-8, and may not render correctly in +the console. + +Install on demand +----------------- + +If an environment variable :envvar:`PYLAUNCHER_ALLOW_INSTALL` is set (to any +value), and the requested Python version is not installed but is available on +the Microsoft Store, the launcher will attempt to install it. This may require +user interaction to complete, and you may need to run the command again. + +An additional :envvar:`PYLAUNCHER_ALWAYS_INSTALL` variable causes the launcher +to always try to install Python, even if it is detected. This is mainly intended +for testing (and should be used with :envvar:`PYLAUNCHER_DRYRUN`). + +Return codes +------------ + +The following exit codes may be returned by the Python launcher. Unfortunately, +there is no way to distinguish these from the exit code of Python itself. + +The names of codes are as used in the sources, and are only for reference. There +is no way to access or resolve them apart from reading this page. Entries are +listed in alphabetical order of names. + ++-------------------+-------+-----------------------------------------------+ +| Name | Value | Description | ++===================+=======+===============================================+ +| RC_BAD_VENV_CFG | 107 | A :file:`pyvenv.cfg` was found but is corrupt.| ++-------------------+-------+-----------------------------------------------+ +| RC_CREATE_PROCESS | 101 | Failed to launch Python. | ++-------------------+-------+-----------------------------------------------+ +| RC_INSTALLING | 111 | An install was started, but the command will | +| | | need to be re-run after it completes. | ++-------------------+-------+-----------------------------------------------+ +| RC_INTERNAL_ERROR | 109 | Unexpected error. Please report a bug. | ++-------------------+-------+-----------------------------------------------+ +| RC_NO_COMMANDLINE | 108 | Unable to obtain command line from the | +| | | operating system. | ++-------------------+-------+-----------------------------------------------+ +| RC_NO_PYTHON | 103 | Unable to locate the requested version. | ++-------------------+-------+-----------------------------------------------+ +| RC_NO_VENV_CFG | 106 | A :file:`pyvenv.cfg` was required but not | +| | | found. | ++-------------------+-------+-----------------------------------------------+ - -.. _finding_modules: +.. _windows_finding_modules: Finding modules =============== -Python usually stores its library (and thereby your site-packages folder) in the -installation directory. So, if you had installed Python to -:file:`C:\\Python\\`, the default library would reside in -:file:`C:\\Python\\Lib\\` and third-party modules should be stored in -:file:`C:\\Python\\Lib\\site-packages\\`. - -To completely override :data:`sys.path`, create a ``._pth`` file with the same -name as the DLL (``python37._pth``) or the executable (``python._pth``) and -specify one line for each path to add to :data:`sys.path`. The file based on the -DLL name overrides the one based on the executable, which allows paths to be -restricted for any program loading the runtime if desired. - -When the file exists, all registry and environment variables are ignored, -isolated mode is enabled, and :mod:`site` is not imported unless one line in the -file specifies ``import site``. Blank paths and lines starting with ``#`` are -ignored. Each path may be absolute or relative to the location of the file. -Import statements other than to ``site`` are not permitted, and arbitrary code -cannot be specified. - -Note that ``.pth`` files (without leading underscore) will be processed normally -by the :mod:`site` module when ``import site`` has been specified. +These notes supplement the description at :ref:`sys-path-init` with +detailed Windows notes. When no ``._pth`` file is found, this is how :data:`sys.path` is populated on Windows: @@ -1082,13 +1196,14 @@ is a collection of modules for advanced Windows-specific support. This includes utilities for: * `Component Object Model - `_ + `_ (COM) * Win32 API calls * Registry * Event log -* `Microsoft Foundation Classes `_ (MFC) - user interfaces +* `Microsoft Foundation Classes + `_ + (MFC) user interfaces `PythonWin `_ is a sample MFC application @@ -1099,30 +1214,17 @@ shipped with PyWin32. It is an embeddable IDE with a built-in debugger. `Win32 How Do I...? `_ by Tim Golden - `Python and COM `_ + `Python and COM `_ by David and Paul Boddie cx_Freeze --------- -`cx_Freeze `_ is a :mod:`distutils` -extension (see :ref:`extending-distutils`) which wraps Python scripts into -executable Windows programs (:file:`{*}.exe` files). When you have done this, -you can distribute your application without requiring your users to install -Python. - - -WConio ------- - -Since Python's advanced terminal handling layer, :mod:`curses`, is restricted to -Unix-like systems, there is a library exclusive to Windows as well: Windows -Console I/O for Python. - -`WConio `_ is a wrapper for -Turbo-C's :file:`CONIO.H`, used to create text user interfaces. - +`cx_Freeze `_ is a ``distutils`` +extension which wraps Python scripts into executable Windows programs +(:file:`{*}.exe` files). When you have done this, you can distribute your +application without requiring your users to install Python. Compiling Python on Windows @@ -1131,24 +1233,16 @@ Compiling Python on Windows If you want to compile CPython yourself, first thing you should do is get the `source `_. You can download either the latest release's source or just grab a fresh `checkout -`_. +`_. The source tree contains a build solution and project files for Microsoft -Visual Studio 2015, which is the compiler used to build the official Python +Visual Studio, which is the compiler used to build the official Python releases. These files are in the :file:`PCbuild` directory. Check :file:`PCbuild/readme.txt` for general information on the build process. - For extension modules, consult :ref:`building-on-windows`. -.. seealso:: - - `Python + Windows + distutils + SWIG + gcc MinGW `_ - or "Creating Python extensions in C/C++ with SWIG and compiling them with - MinGW gcc under Windows" or "Installing Python extension with distutils - and without Microsoft Visual C++" by Sébastien Sauvage, 2003 - Other Platforms =============== @@ -1157,12 +1251,12 @@ With ongoing development of Python, some platforms that used to be supported earlier are no longer supported (due to the lack of users or developers). Check :pep:`11` for details on all unsupported platforms. -* `Windows CE `_ is still supported. -* The `Cygwin `_ installer offers to install the Python - interpreter as well (cf. `Cygwin package source - `_, `Maintainer releases - `_) +* `Windows CE `_ is + `no longer supported `__ + since Python 3 (if it ever was). +* The `Cygwin `_ installer offers to install the + `Python interpreter `__ + as well See `Python for Windows `_ for detailed information about platforms with pre-compiled installers. diff --git a/Doc/whatsnew/2.0.rst b/Doc/whatsnew/2.0.rst index 0e1cf1fd0ce..4bcb2acae1e 100644 --- a/Doc/whatsnew/2.0.rst +++ b/Doc/whatsnew/2.0.rst @@ -21,7 +21,7 @@ Python's development never completely stops between releases, and a steady flow of bug fixes and improvements are always being submitted. A host of minor fixes, a few optimizations, additional docstrings, and better error messages went into 2.0; to list them all would be impossible, but they're certainly significant. -Consult the publicly-available CVS logs if you want to see the full list. This +Consult the publicly available CVS logs if you want to see the full list. This progress is due to the five developers working for PythonLabs are now getting paid to spend their days fixing bugs, and also due to the improved communication resulting from moving to SourceForge. @@ -130,7 +130,7 @@ Guidelines": Read the rest of :pep:`1` for the details of the PEP editorial process, style, and format. PEPs are kept in the Python CVS tree on SourceForge, though they're not part of the Python 2.0 distribution, and are also available in HTML form from -https://www.python.org/dev/peps/. As of September 2000, there are 25 PEPS, ranging +https://peps.python.org/. As of September 2000, there are 25 PEPS, ranging from :pep:`201`, "Lockstep Iteration", to PEP 225, "Elementwise/Objectwise Operators". @@ -572,7 +572,7 @@ Work has been done on porting Python to 64-bit Windows on the Itanium processor, mostly by Trent Mick of ActiveState. (Confusingly, ``sys.platform`` is still ``'win32'`` on Win64 because it seems that for ease of porting, MS Visual C++ treats code as 32 bit on Itanium.) PythonWin also supports Windows CE; see the -Python CE page at http://pythonce.sourceforge.net/ for more information. +Python CE page at https://pythonce.sourceforge.net/ for more information. Another new platform is Darwin/MacOS X; initial support for it is in Python 2.0. Dynamic loading works, if you specify "configure --with-dyld --with-suffix=.x". @@ -820,7 +820,7 @@ packages, which made administering a Python installation something of a chore. The SIG for distribution utilities, shepherded by Greg Ward, has created the Distutils, a system to make package installation much easier. They form the -:mod:`distutils` package, a new part of Python's standard library. In the best +``distutils`` package, a new part of Python's standard library. In the best case, installing a Python module from source will require the same steps: first you simply mean unpack the tarball or zip archive, and the run "``python setup.py install``". The platform will be automatically detected, the compiler diff --git a/Doc/whatsnew/2.1.rst b/Doc/whatsnew/2.1.rst index b690f90cf66..0136de58774 100644 --- a/Doc/whatsnew/2.1.rst +++ b/Doc/whatsnew/2.1.rst @@ -542,8 +542,11 @@ PEP 241: Metadata in Python Packages A common complaint from Python users is that there's no single catalog of all the Python modules in existence. T. Middleton's Vaults of Parnassus at -http://www.vex.net/parnassus/ are the largest catalog of Python modules, but -registering software at the Vaults is optional, and many people don't bother. +``www.vex.net/parnassus/`` (retired in February 2009, `available in the +Internet Archive Wayback Machine +`_) +was the largest catalog of Python modules, but +registering software at the Vaults is optional, and many people did not bother. As a first small step toward fixing the problem, Python software packaged using the Distutils :command:`sdist` command will include a file named diff --git a/Doc/whatsnew/2.2.rst b/Doc/whatsnew/2.2.rst index 9355c1badaa..0c3bfda1933 100644 --- a/Doc/whatsnew/2.2.rst +++ b/Doc/whatsnew/2.2.rst @@ -395,7 +395,7 @@ This section has just been a quick overview of the new features, giving enough of an explanation to start you programming, but many details have been simplified or ignored. Where should you go to get a more complete picture? -https://docs.python.org/dev/howto/descriptor.html is a lengthy tutorial introduction to +The :ref:`descriptorhowto` is a lengthy tutorial introduction to the descriptor features, written by Guido van Rossum. If my description has whetted your appetite, go read this tutorial next, because it goes into much more detail about the new features while still remaining quite easy to read. @@ -983,7 +983,7 @@ New and Improved Modules Jun-ichiro "itojun" Hagino.) * Two new format characters were added to the :mod:`struct` module for 64-bit - integers on platforms that support the C :c:type:`long long` type. ``q`` is for + integers on platforms that support the C :c:expr:`long long` type. ``q`` is for a signed 64-bit integer, and ``Q`` is for an unsigned one. The value is returned in Python's long integer type. (Contributed by Tim Peters.) @@ -1102,7 +1102,7 @@ code, none of the changes described here will affect you very much. * A different argument parsing function, :c:func:`PyArg_UnpackTuple`, has been added that's simpler and presumably faster. Instead of specifying a format string, the caller simply gives the minimum and maximum number of arguments - expected, and a set of pointers to :c:type:`PyObject\*` variables that will be + expected, and a set of pointers to :c:expr:`PyObject*` variables that will be filled in with argument values. * Two new flags :const:`METH_NOARGS` and :const:`METH_O` are available in method diff --git a/Doc/whatsnew/2.3.rst b/Doc/whatsnew/2.3.rst index cf5552064cf..c6e2003e92f 100644 --- a/Doc/whatsnew/2.3.rst +++ b/Doc/whatsnew/2.3.rst @@ -527,7 +527,7 @@ creates a :class:`LogRecord` instance that is sent to any number of different of filters, and each filter can cause the :class:`LogRecord` to be ignored or can modify the record before passing it along. When they're finally output, :class:`LogRecord` instances are converted to text by a :class:`Formatter` -class. All of these classes can be replaced by your own specially-written +class. All of these classes can be replaced by your own specially written classes. With all of these features the :mod:`logging` package should provide enough @@ -1082,7 +1082,7 @@ Here are all of the changes that Python 2.3 makes to the core Python language. hierarchy. Classic classes are unaffected by this change. Python 2.2 originally used a topological sort of a class's ancestors, but 2.3 now uses the C3 algorithm as described in the paper `"A Monotonic Superclass Linearization - for Dylan" `_. To + for Dylan" `_. To understand the motivation for this change, read Michele Simionato's article `"Python 2.3 Method Resolution Order" `_, or read the thread on python-dev starting with the message at @@ -1231,7 +1231,7 @@ complete list of changes, or look through the CVS logs for all the details. repeat an array. (Contributed by Jason Orendorff.) * The :mod:`bsddb` module has been replaced by version 4.1.6 of the `PyBSDDB - `_ package, providing a more complete interface + `_ package, providing a more complete interface to the transactional features of the BerkeleyDB library. The old version of the module has been renamed to :mod:`bsddb185` and is no @@ -1905,8 +1905,8 @@ Changes to Python's build process and to the C API include: "")`` instead, but this will be slower than using :const:`METH_NOARGS`. * :c:func:`PyArg_ParseTuple` accepts new format characters for various sizes of - unsigned integers: ``B`` for :c:type:`unsigned char`, ``H`` for :c:type:`unsigned - short int`, ``I`` for :c:type:`unsigned int`, and ``K`` for :c:type:`unsigned + unsigned integers: ``B`` for :c:expr:`unsigned char`, ``H`` for :c:expr:`unsigned + short int`, ``I`` for :c:expr:`unsigned int`, and ``K`` for :c:expr:`unsigned long long`. * A new function, ``PyObject_DelItemString(mapping, char *key)`` was added diff --git a/Doc/whatsnew/2.4.rst b/Doc/whatsnew/2.4.rst index 7e11c98399c..63e819876ce 100644 --- a/Doc/whatsnew/2.4.rst +++ b/Doc/whatsnew/2.4.rst @@ -120,7 +120,7 @@ having the entire data set in memory at one time. List comprehensions don't fit into this picture very well because they produce a Python list object containing all of the items. This unavoidably pulls all of the objects into memory, which can be a problem if your data set is very large. When trying to write a -functionally-styled program, it would be natural to write something like:: +functionally styled program, it would be natural to write something like:: links = [link for link in get_all_links() if not link.followed] for link in links: @@ -472,7 +472,7 @@ PEP 327: Decimal Data Type ========================== Python has always supported floating-point (FP) numbers, based on the underlying -C :c:type:`double` type, as a data type. However, while most programming +C :c:expr:`double` type, as a data type. However, while most programming languages provide a floating-point type, many people (even programmers) are unaware that floating-point numbers don't represent certain decimal fractions accurately. The new :class:`Decimal` type can represent these fractions @@ -501,7 +501,7 @@ mantissa is multiplied by 4 (2 to the power of the exponent 2); 1.25 \* 4 equals 5. Modern systems usually provide floating-point support that conforms to a -standard called IEEE 754. C's :c:type:`double` type is usually implemented as a +standard called IEEE 754. C's :c:expr:`double` type is usually implemented as a 64-bit IEEE 754 number, which uses 52 bits of space for the mantissa. This means that numbers can only be specified to 52 bits of precision. If you're trying to represent numbers whose expansion repeats endlessly, the expansion is @@ -750,10 +750,10 @@ The solution described in the PEP is to add three new functions to the Python API that perform ASCII-only conversions, ignoring the locale setting: * ``PyOS_ascii_strtod(str, ptr)`` and ``PyOS_ascii_atof(str, ptr)`` - both convert a string to a C :c:type:`double`. + both convert a string to a C :c:expr:`double`. * ``PyOS_ascii_formatd(buffer, buf_len, format, d)`` converts a - :c:type:`double` to an ASCII string. + :c:expr:`double` to an ASCII string. The code for these functions came from the GLib library (https://developer.gnome.org/glib/stable/), whose developers kindly @@ -918,7 +918,7 @@ Here are all of the changes that Python 2.4 makes to the core Python language. (Contributed by Raymond Hettinger.) -* Encountering a failure while importing a module no longer leaves a partially-initialized +* Encountering a failure while importing a module no longer leaves a partially initialized module object in ``sys.modules``. The incomplete module object left behind would fool further imports of the same module into succeeding, leading to confusing errors. (Fixed by Tim Peters.) @@ -1453,7 +1453,7 @@ Some of the changes to Python's build process and to the C API are: extension functions: :c:macro:`Py_RETURN_NONE`, :c:macro:`Py_RETURN_TRUE`, and :c:macro:`Py_RETURN_FALSE`. (Contributed by Brett Cannon.) -* Another new macro, :c:macro:`Py_CLEAR(obj)`, decreases the reference count of +* Another new macro, :c:macro:`Py_CLEAR`, decreases the reference count of *obj* and sets *obj* to the null pointer. (Contributed by Jim Fulton.) * A new function, ``PyTuple_Pack(N, obj1, obj2, ..., objN)``, constructs @@ -1464,7 +1464,7 @@ Some of the changes to Python's build process and to the C API are: lookups without masking exceptions raised during the look-up process. (Contributed by Raymond Hettinger.) -* The :c:macro:`Py_IS_NAN(X)` macro returns 1 if its float or double argument +* The :c:expr:`Py_IS_NAN(X)` macro returns 1 if its float or double argument *X* is a NaN. (Contributed by Tim Peters.) * C code can avoid unnecessary locking by using the new @@ -1541,7 +1541,7 @@ code: * The :mod:`tarfile` module now generates GNU-format tar files by default. * Encountering a failure while importing a module no longer leaves a - partially-initialized module object in ``sys.modules``. + partially initialized module object in ``sys.modules``. * :const:`None` is now a constant; code that binds a new value to the name ``None`` is now a syntax error. diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index 4e85abaea75..dcfaef6ed29 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -11,11 +11,11 @@ This article explains the new features in Python 2.5. The final release of Python 2.5 is scheduled for August 2006; :pep:`356` describes the planned -release schedule. +release schedule. Python 2.5 was released on September 19, 2006. The changes in Python 2.5 are an interesting mix of language and library improvements. The library enhancements will be more important to Python's user -community, I think, because several widely-useful packages were added. New +community, I think, because several widely useful packages were added. New modules include ElementTree for XML processing (:mod:`xml.etree`), the SQLite database module (:mod:`sqlite`), and the :mod:`ctypes` module for calling C functions. @@ -551,7 +551,7 @@ exhausted. https://en.wikipedia.org/wiki/Coroutine The Wikipedia entry for coroutines. - http://www.sidhe.org/~dan/blog/archives/000178.html + https://web.archive.org/web/20160321211320/http://www.sidhe.org/~dan/blog/archives/000178.html An explanation of coroutines from a Perl point of view, written by Dan Sugalski. .. ====================================================================== @@ -872,18 +872,18 @@ PEP 353: Using ssize_t as the index type ======================================== A wide-ranging change to Python's C API, using a new :c:type:`Py_ssize_t` type -definition instead of :c:type:`int`, will permit the interpreter to handle more +definition instead of :c:expr:`int`, will permit the interpreter to handle more data on 64-bit platforms. This change doesn't affect Python's capacity on 32-bit platforms. -Various pieces of the Python interpreter used C's :c:type:`int` type to store +Various pieces of the Python interpreter used C's :c:expr:`int` type to store sizes or counts; for example, the number of items in a list or tuple were stored -in an :c:type:`int`. The C compilers for most 64-bit platforms still define -:c:type:`int` as a 32-bit type, so that meant that lists could only hold up to +in an :c:expr:`int`. The C compilers for most 64-bit platforms still define +:c:expr:`int` as a 32-bit type, so that meant that lists could only hold up to ``2**31 - 1`` = 2147483647 items. (There are actually a few different programming models that 64-bit C compilers can use -- see -http://www.unix.org/version2/whatsnew/lp64_wp.html for a discussion -- but the -most commonly available model leaves :c:type:`int` as 32 bits.) +https://unix.org/version2/whatsnew/lp64_wp.html for a discussion -- but the +most commonly available model leaves :c:expr:`int` as 32 bits.) A limit of 2147483647 items doesn't really matter on a 32-bit platform because you'll run out of memory before hitting the length limit. Each list item @@ -895,7 +895,7 @@ It's possible to address that much memory on a 64-bit platform, however. The pointers for a list that size would only require 16 GiB of space, so it's not unreasonable that Python programmers might construct lists that large. Therefore, the Python interpreter had to be changed to use some type other than -:c:type:`int`, and this will be a 64-bit type on 64-bit platforms. The change +:c:expr:`int`, and this will be a 64-bit type on 64-bit platforms. The change will cause incompatibilities on 64-bit machines, so it was deemed worth making the transition now, while the number of 64-bit users is still relatively small. (In 5 or 10 years, we may *all* be on 64-bit machines, and the transition would @@ -909,7 +909,7 @@ may therefore need to have some variables changed to :c:type:`Py_ssize_t`. The :c:func:`PyArg_ParseTuple` and :c:func:`Py_BuildValue` functions have a new conversion code, ``n``, for :c:type:`Py_ssize_t`. :c:func:`PyArg_ParseTuple`'s -``s#`` and ``t#`` still output :c:type:`int` by default, but you can define the +``s#`` and ``t#`` still output :c:expr:`int` by default, but you can define the macro :c:macro:`PY_SSIZE_T_CLEAN` before including :file:`Python.h` to make them return :c:type:`Py_ssize_t`. @@ -1293,7 +1293,7 @@ complete list of changes, or look through the SVN logs for all the details. received several enhancements and a number of bugfixes. You can now set the maximum size in bytes of a field by calling the ``csv.field_size_limit(new_limit)`` function; omitting the *new_limit* - argument will return the currently-set limit. The :class:`reader` class now has + argument will return the currently set limit. The :class:`reader` class now has a :attr:`line_num` attribute that counts the number of physical lines read from the source; records can span multiple physical lines, so :attr:`line_num` is not the same as the number of records read. @@ -1695,7 +1695,7 @@ attributes of the :class:`CDLL` object. :: result = libc.printf("Line of output\n") Type constructors for the various C types are provided: :func:`c_int`, -:func:`c_float`, :func:`c_double`, :func:`c_char_p` (equivalent to :c:type:`char +:func:`c_float`, :func:`c_double`, :func:`c_char_p` (equivalent to :c:expr:`char \*`), and so forth. Unlike Python's types, the C versions are all mutable; you can assign to their :attr:`value` attribute to change the wrapped value. Python integers and strings will be automatically converted to the corresponding C @@ -1725,7 +1725,7 @@ attribute of the function object to change this:: ``ctypes.pythonapi`` object. This object does *not* release the global interpreter lock before calling a function, because the lock must be held when calling into the interpreter's code. There's a :class:`py_object()` type -constructor that will create a :c:type:`PyObject \*` pointer. A simple usage:: +constructor that will create a :c:expr:`PyObject *` pointer. A simple usage:: import ctypes @@ -1746,8 +1746,8 @@ modules, now that :mod:`ctypes` is included with core Python. .. seealso:: - http://starship.python.net/crew/theller/ctypes/ - The ctypes web page, with a tutorial, reference, and FAQ. + https://web.archive.org/web/20180410025338/http://starship.python.net/crew/theller/ctypes/ + The pre-stdlib ctypes web page, with a tutorial, reference, and FAQ. The documentation for the :mod:`ctypes` module. @@ -1767,7 +1767,7 @@ included. The rest of this section will provide a brief overview of using ElementTree. Full documentation for ElementTree is available at -http://effbot.org/zone/element-index.htm. +https://web.archive.org/web/20201124024954/http://effbot.org/zone/element-index.htm. ElementTree represents an XML document as a tree of element nodes. The text content of the document is stored as the :attr:`text` and :attr:`tail` @@ -1865,7 +1865,7 @@ read the package's official documentation for more details. .. seealso:: - http://effbot.org/zone/element-index.htm + https://web.archive.org/web/20201124024954/http://effbot.org/zone/element-index.htm Official documentation for ElementTree. .. ====================================================================== @@ -1930,7 +1930,7 @@ with the same digest state. The sqlite3 package ------------------- -The pysqlite module (http://www.pysqlite.org), a wrapper for the SQLite embedded +The pysqlite module (https://www.pysqlite.org), a wrapper for the SQLite embedded database, has been added to the standard library under the package name :mod:`sqlite3`. @@ -2019,7 +2019,7 @@ https://www.sqlite.org. .. seealso:: - http://www.pysqlite.org + https://www.pysqlite.org The pysqlite web page. https://www.sqlite.org @@ -2065,7 +2065,7 @@ up a server takes only a few lines of code:: .. seealso:: - http://www.wsgi.org + https://web.archive.org/web/20160331090247/http://wsgi.readthedocs.org/en/latest/ A central web site for WSGI-related resources. :pep:`333` - Python Web Server Gateway Interface v1.0 @@ -2093,7 +2093,7 @@ Changes to Python's build process and to the C API include: * The largest change to the C API came from :pep:`353`, which modifies the interpreter to use a :c:type:`Py_ssize_t` type definition instead of - :c:type:`int`. See the earlier section :ref:`pep-353` for a discussion of this + :c:expr:`int`. See the earlier section :ref:`pep-353` for a discussion of this change. * The design of the bytecode compiler has changed a great deal, no longer @@ -2264,15 +2264,15 @@ code: Setting :attr:`rpc_paths` to ``None`` or an empty tuple disables this path checking. -* C API: Many functions now use :c:type:`Py_ssize_t` instead of :c:type:`int` to +* C API: Many functions now use :c:type:`Py_ssize_t` instead of :c:expr:`int` to allow processing more data on 64-bit machines. Extension code may need to make the same change to avoid warnings and to support 64-bit machines. See the earlier section :ref:`pep-353` for a discussion of this change. * C API: The obmalloc changes mean that you must be careful to not mix usage - of the :c:func:`PyMem_\*` and :c:func:`PyObject_\*` families of functions. Memory - allocated with one family's :c:func:`\*_Malloc` must be freed with the - corresponding family's :c:func:`\*_Free` function. + of the ``PyMem_*`` and ``PyObject_*`` families of functions. Memory + allocated with one family's ``*_Malloc`` must be freed with the + corresponding family's ``*_Free`` function. .. ====================================================================== diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index b6174a19a17..34f2656f765 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -49,7 +49,7 @@ This saves the maintainer some effort going through the SVN logs when researching a change. -This article explains the new features in Python 2.6, released on October 1 +This article explains the new features in Python 2.6, released on October 1, 2008. The release schedule is described in :pep:`361`. The major theme of Python 2.6 is preparing the migration path to @@ -155,7 +155,7 @@ up different products and import some of the bugs and patches from SourceForge. Four different trackers were examined: `Jira `__, `Launchpad `__, -`Roundup `__, and +`Roundup `__, and `Trac `__. The committee eventually settled on Jira and Roundup as the two candidates. Jira is a commercial product that @@ -176,7 +176,7 @@ Hosting of the Python bug tracker is kindly provided by of Stellenbosch, South Africa. Martin von Löwis put a lot of effort into importing existing bugs and patches from SourceForge; his scripts for this import operation are at -http://svn.python.org/view/tracker/importer/ and may be useful to +``https://svn.python.org/view/tracker/importer/`` and may be useful to other projects wishing to move from SourceForge to Roundup. .. seealso:: @@ -184,13 +184,13 @@ other projects wishing to move from SourceForge to Roundup. https://bugs.python.org The Python bug tracker. - http://bugs.jython.org: + https://bugs.jython.org: The Jython bug tracker. - http://roundup.sourceforge.net/ + https://roundup.sourceforge.io/ Roundup downloads and documentation. - http://svn.python.org/view/tracker/importer/ + https://svn.python.org/view/tracker/importer/ Martin von Löwis's conversion scripts. New Documentation Format: reStructuredText Using Sphinx @@ -217,7 +217,7 @@ the time required to finish the job. During the 2.6 development cycle, Georg Brandl put a lot of effort into building a new toolchain for processing the documentation. The resulting package is called Sphinx, and is available from -http://sphinx-doc.org/. +https://www.sphinx-doc.org/. Sphinx concentrates on HTML output, producing attractively styled and modern HTML; printed output is still supported through conversion to @@ -235,10 +235,10 @@ have adopted Sphinx as their documentation tool. `Documenting Python `__ Describes how to write for Python's documentation. - `Sphinx `__ + `Sphinx `__ Documentation and code for the Sphinx toolchain. - `Docutils `__ + `Docutils `__ The underlying reStructuredText parser and toolset. @@ -523,7 +523,7 @@ PEP 370: Per-user ``site-packages`` Directory When you run Python, the module search path ``sys.path`` usually includes a directory whose path ends in ``"site-packages"``. This -directory is intended to hold locally-installed packages available to +directory is intended to hold locally installed packages available to all users using a machine or a particular site installation. Python 2.6 introduces a convention for user-specific site directories. @@ -717,13 +717,13 @@ This will produce the output:: PEP 3101: Advanced String Formatting ===================================================== -In Python 3.0, the `%` operator is supplemented by a more powerful string +In Python 3.0, the ``%`` operator is supplemented by a more powerful string formatting method, :meth:`format`. Support for the :meth:`str.format` method has been backported to Python 2.6. -In 2.6, both 8-bit and Unicode strings have a `.format()` method that +In 2.6, both 8-bit and Unicode strings have a ``.format()`` method that treats the string as a template and takes the arguments to be formatted. -The formatting template uses curly brackets (`{`, `}`) as special characters:: +The formatting template uses curly brackets (``{``, ``}``) as special characters:: >>> # Substitute positional argument 0 into the string. >>> "User ID: {0}".format("root") @@ -1433,7 +1433,7 @@ one, :func:`math.trunc`, that's been backported to Python 2.6. `Scheme's numerical tower `__, from the Guile manual. - `Scheme's number datatypes `__ from the R5RS Scheme specification. + `Scheme's number datatypes `__ from the R5RS Scheme specification. The :mod:`fractions` Module @@ -1926,7 +1926,7 @@ changes, or look through the Subversion logs for all the details. the left to six places. (Contributed by Skip Montanaro; :issue:`1158`.) * The :mod:`decimal` module was updated to version 1.66 of - `the General Decimal Specification `__. New features + `the General Decimal Specification `__. New features include some methods for some basic mathematical functions such as :meth:`exp` and :meth:`log10`:: @@ -2389,7 +2389,7 @@ changes, or look through the Subversion logs for all the details. has been updated from version 2.3.2 in Python 2.5 to version 2.4.1. -* The :mod:`struct` module now supports the C99 :c:type:`_Bool` type, +* The :mod:`struct` module now supports the C99 :c:expr:`_Bool` type, using the format character ``'?'``. (Contributed by David Remahl.) @@ -2460,7 +2460,7 @@ changes, or look through the Subversion logs for all the details. The function must take a filename and return true if the file should be excluded or false if it should be archived. The function is applied to both the name initially passed to :meth:`add` - and to the names of files in recursively-added directories. + and to the names of files in recursively added directories. (All changes contributed by Lars Gustäbel). @@ -2513,7 +2513,7 @@ changes, or look through the Subversion logs for all the details. (Contributed by Brett Cannon.) * The :mod:`textwrap` module can now preserve existing whitespace - at the beginnings and ends of the newly-created lines + at the beginnings and ends of the newly created lines by specifying ``drop_whitespace=False`` as an argument:: diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst index abb65222ddd..810a2cd2537 100644 --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -279,7 +279,7 @@ Comparing an :class:`~collections.OrderedDict` with a regular dictionary ignores the insertion order and just compares the keys and values. How does the :class:`~collections.OrderedDict` work? It maintains a -doubly-linked list of keys, appending new keys to the list as they're inserted. +doubly linked list of keys, appending new keys to the list as they're inserted. A secondary dictionary maps keys to their corresponding list node, so deletion doesn't have to traverse the entire linked list and therefore remains O(1). @@ -299,7 +299,7 @@ modules. constructor was extended with an *object_pairs_hook* parameter to allow :class:`OrderedDict` instances to be built by the decoder. Support was also added for third-party tools like - `PyYAML `_. + `PyYAML `_. .. seealso:: @@ -1048,7 +1048,7 @@ changes, or look through the Subversion logs for all the details. The new version features better Python 3.x compatibility, various bug fixes, and adds several new BerkeleyDB flags and methods. (Updated by Jesús Cea Avión; :issue:`8156`. The pybsddb - changelog can be read at http://hg.jcea.es/pybsddb/file/tip/ChangeLog.) + changelog can be read at https://hg.jcea.es/pybsddb/file/tip/ChangeLog.) * The :mod:`bz2` module's :class:`~bz2.BZ2File` now supports the context management protocol, so you can write ``with bz2.BZ2File(...) as f:``. @@ -1331,6 +1331,7 @@ changes, or look through the Subversion logs for all the details. >>> from inspect import getcallargs >>> def f(a, b=1, *pos, **named): ... pass + ... >>> getcallargs(f, 1, 2, 3) {'a': 1, 'b': 2, 'pos': (3,), 'named': {}} >>> getcallargs(f, a=2, x=4) @@ -1545,7 +1546,7 @@ changes, or look through the Subversion logs for all the details. *ciphers* argument that's a string listing the encryption algorithms to be allowed; the format of the string is described `in the OpenSSL documentation - `__. + `__. (Added by Antoine Pitrou; :issue:`8322`.) Another change makes the extension load all of OpenSSL's ciphers and @@ -1831,7 +1832,7 @@ packaged as the :mod:`unittest2` package, from https://pypi.org/project/unittest2. When used from the command line, the module can automatically discover -tests. It's not as fancy as `py.test `__ or +tests. It's not as fancy as `py.test `__ or `nose `__, but provides a simple way to run tests kept within a set of package directories. For example, the following command will search the :file:`test/` subdirectory for @@ -1968,7 +1969,7 @@ GvR worked on merging them into Python's version of :mod:`unittest`. * :meth:`~unittest.TestCase.assertAlmostEqual` and :meth:`~unittest.TestCase.assertNotAlmostEqual` test whether *first* and *second* are approximately equal. This method - can either round their difference to an optionally-specified number + can either round their difference to an optionally specified number of *places* (the default is 7) and compare it to zero, or require the difference to be smaller than a supplied *delta* value. @@ -2001,7 +2002,7 @@ module is imported or used. .. seealso:: - http://www.voidspace.org.uk/python/articles/unittest2.shtml + https://web.archive.org/web/20210619163128/http://www.voidspace.org.uk/python/articles/unittest2.shtml Describes the new features, how to use them, and the rationale for various design decisions. (By Michael Foord.) @@ -2089,7 +2090,7 @@ version 1.3. Some of the new features are: Fredrik Lundh develops ElementTree and produced the 1.3 version; you can read his article describing 1.3 at -http://effbot.org/zone/elementtree-13-intro.htm. +https://web.archive.org/web/20200703234532/http://effbot.org/zone/elementtree-13-intro.htm. Florent Xicluna updated the version included with Python, after discussions on python-dev and in :issue:`6472`.) @@ -2144,7 +2145,7 @@ Changes to Python's build process and to the C API include: * New functions: :c:func:`PyLong_AsLongAndOverflow` and :c:func:`PyLong_AsLongLongAndOverflow` approximates a Python long - integer as a C :c:type:`long` or :c:type:`long long`. + integer as a C :c:expr:`long` or :c:expr:`long long`. If the number is too large to fit into the output type, an *overflow* flag is set and returned to the caller. (Contributed by Case Van Horsen; :issue:`7528` and :issue:`7767`.) @@ -2202,7 +2203,7 @@ Changes to Python's build process and to the C API include: * New format codes: the :c:func:`PyFormat_FromString`, :c:func:`PyFormat_FromStringV`, and :c:func:`PyErr_Format` functions now accept ``%lld`` and ``%llu`` format codes for displaying - C's :c:type:`long long` types. + C's :c:expr:`long long` types. (Contributed by Mark Dickinson; :issue:`7228`.) * The complicated interaction between threads and process forking has @@ -2333,7 +2334,7 @@ Port-Specific Changes: Windows * The :mod:`_winreg` module for accessing the registry now implements the :func:`~_winreg.CreateKeyEx` and :func:`~_winreg.DeleteKeyEx` - functions, extended versions of previously-supported functions that + functions, extended versions of previously supported functions that take several extra arguments. The :func:`~_winreg.DisableReflectionKey`, :func:`~_winreg.EnableReflectionKey`, and :func:`~_winreg.QueryReflectionKey` were also tested and documented. @@ -2485,8 +2486,8 @@ In the standard library: * The ElementTree library, :mod:`xml.etree`, no longer escapes ampersands and angle brackets when outputting an XML processing - instruction (which looks like ``) - or comment (which looks like ``). + instruction (which looks like ````) + or comment (which looks like ````). (Patch by Neil Muller; :issue:`2746`.) * The :meth:`~StringIO.StringIO.readline` method of :class:`~StringIO.StringIO` objects now does @@ -2681,7 +2682,7 @@ these commands by default, as long as, when invoked, they provide clear and simple directions on how to install them on that platform (usually using the system package manager). -__ https://www.python.org/dev/peps/pep-0477/#disabling-ensurepip-by-downstream-distributors +__ https://peps.python.org/pep-0477/#disabling-ensurepip-by-downstream-distributors Documentation Changes @@ -2692,12 +2693,12 @@ As part of this change, the :ref:`installing-index` and completely redesigned as short getting started and FAQ documents. Most packaging documentation has now been moved out to the Python Packaging Authority maintained `Python Packaging User Guide -`__ and the documentation of the individual +`__ and the documentation of the individual projects. However, as this migration is currently still incomplete, the legacy versions of those guides remaining available as :ref:`install-index` -and :ref:`distutils-index`. +and :ref:`setuptools-index`. .. seealso:: diff --git a/Doc/whatsnew/3.0.rst b/Doc/whatsnew/3.0.rst index 880958d3edb..63b24748d8a 100644 --- a/Doc/whatsnew/3.0.rst +++ b/Doc/whatsnew/3.0.rst @@ -53,9 +53,9 @@ This article explains the new features in Python 3.0, compared to 2.6. Python 3.0, also known as "Python 3000" or "Py3K", is the first ever -*intentionally backwards incompatible* Python release. There are more -changes than in a typical release, and more that are important for all -Python users. Nevertheless, after digesting the changes, you'll find +*intentionally backwards incompatible* Python release. Python 3.0 was released on December 3, 2008. +There are more changes than in a typical release, and more that are important for all +Python users. Nevertheless, after digesting the changes, you'll find that Python really hasn't changed all that much -- by and large, we're mostly fixing well-known annoyances and warts, and removing a lot of old cruft. @@ -663,7 +663,7 @@ Some other changes to standard library modules, not covered by :data:`string.ascii_letters` etc. instead. (The reason for the removal is that :data:`string.letters` and friends had locale-specific behavior, which is a bad idea for such - attractively-named global "constants".) + attractively named global "constants".) * Renamed module :mod:`__builtin__` to :mod:`builtins` (removing the underscores, adding an 's'). The :data:`__builtins__` variable diff --git a/Doc/whatsnew/3.1.rst b/Doc/whatsnew/3.1.rst index f1e6d0c4f3d..fba8816bb24 100644 --- a/Doc/whatsnew/3.1.rst +++ b/Doc/whatsnew/3.1.rst @@ -47,6 +47,7 @@ when researching a change. This article explains the new features in Python 3.1, compared to 3.0. +Python 3.1 was released on June 27, 2009. PEP 372: Ordered Dictionaries @@ -71,7 +72,7 @@ order. The *_asdict()* method for :func:`collections.namedtuple` now returns an ordered dictionary with the values appearing in the same order as the underlying tuple indices. The :mod:`json` module is being built-out with an *object_pairs_hook* to allow OrderedDicts to be built by the decoder. -Support was also added for third-party tools like `PyYAML `_. +Support was also added for third-party tools like `PyYAML `_. .. seealso:: @@ -450,7 +451,7 @@ Major performance enhancements have been added: * The :mod:`json` module now has a C extension to substantially improve its performance. In addition, the API was modified so that json works only with :class:`str`, not with :class:`bytes`. That change makes the - module closely match the `JSON specification `_ + module closely match the `JSON specification `_ which is defined in terms of Unicode. (Contributed by Bob Ippolito and converted to Py3.1 by Antoine Pitrou diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index a30fd2d0c0c..f6a48ed2680 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -2,8 +2,6 @@ What's New In Python 3.10 **************************** -:Release: |release| -:Date: |today| :Editor: Pablo Galindo Salgado .. Rules for maintenance: @@ -47,7 +45,7 @@ when researching a change. This article explains the new features in Python 3.10, compared to 3.9. - +Python 3.10 was released on October 4, 2021. For full details, see the :ref:`changelog `. Summary -- Release highlights @@ -77,8 +75,9 @@ Interpreter improvements: New typing features: * :pep:`604`, Allow writing union types as X | Y -* :pep:`613`, Explicit Type Aliases * :pep:`612`, Parameter Specification Variables +* :pep:`613`, Explicit Type Aliases +* :pep:`647`, User-Defined Type Guards Important deprecations, removals or restrictions: @@ -230,7 +229,7 @@ have been incorporated. Some of the most notable ones are as follows: ^ SyntaxError: expected ':' - (Contributed by Pablo Galindo in :issue:`42997`) + (Contributed by Pablo Galindo in :issue:`42997`.) * Unparenthesised tuples in comprehensions targets: @@ -242,7 +241,7 @@ have been incorporated. Some of the most notable ones are as follows: ^ SyntaxError: did you forget parentheses around the comprehension target? - (Contributed by Pablo Galindo in :issue:`43017`) + (Contributed by Pablo Galindo in :issue:`43017`.) * Missing commas in collection literals and between expressions: @@ -257,7 +256,7 @@ have been incorporated. Some of the most notable ones are as follows: ^ SyntaxError: invalid syntax. Perhaps you forgot a comma? - (Contributed by Pablo Galindo in :issue:`43822`) + (Contributed by Pablo Galindo in :issue:`43822`.) * Multiple Exception types without parentheses: @@ -271,7 +270,7 @@ have been incorporated. Some of the most notable ones are as follows: ^ SyntaxError: multiple exception types must be parenthesized - (Contributed by Pablo Galindo in :issue:`43149`) + (Contributed by Pablo Galindo in :issue:`43149`.) * Missing ``:`` and values in dictionary literals: @@ -293,7 +292,7 @@ have been incorporated. Some of the most notable ones are as follows: ^ SyntaxError: ':' expected after dictionary key - (Contributed by Pablo Galindo in :issue:`43823`) + (Contributed by Pablo Galindo in :issue:`43823`.) * ``try`` blocks without ``except`` or ``finally`` blocks: @@ -307,7 +306,7 @@ have been incorporated. Some of the most notable ones are as follows: ^^^^^^^^^ SyntaxError: expected 'except' or 'finally' block - (Contributed by Pablo Galindo in :issue:`44305`) + (Contributed by Pablo Galindo in :issue:`44305`.) * Usage of ``=`` instead of ``==`` in comparisons: @@ -319,7 +318,7 @@ have been incorporated. Some of the most notable ones are as follows: ^ SyntaxError: cannot assign to attribute here. Maybe you meant '==' instead of '='? - (Contributed by Pablo Galindo in :issue:`43797`) + (Contributed by Pablo Galindo in :issue:`43797`.) * Usage of ``*`` in f-strings: @@ -331,7 +330,7 @@ have been incorporated. Some of the most notable ones are as follows: ^ SyntaxError: f-string: cannot use starred expression here - (Contributed by Pablo Galindo in :issue:`41064`) + (Contributed by Pablo Galindo in :issue:`41064`.) IndentationErrors ~~~~~~~~~~~~~~~~~ @@ -669,6 +668,7 @@ Several other key features: GREEN = 1 BLUE = 2 + color = Color.GREEN match color: case Color.RED: print("I see red!") @@ -704,6 +704,7 @@ are added to enable the warning. See :ref:`io-text-encoding` for more information. +.. _new-feat-related-type-hints: New Features Related to Type Hints ================================== @@ -1018,7 +1019,7 @@ You can specify keyword-only on a per-field basis: .. code-block:: python - from dataclasses import dataclass + from dataclasses import dataclass, field @dataclass class Birthday: @@ -1047,7 +1048,7 @@ keyword-only. This will probably be the most common usage: Here, ``z`` and ``t`` are keyword-only parameters, while ``x`` and ``y`` are not. -(Contributed by Eric V. Smith in :issue:`43532`) +(Contributed by Eric V. Smith in :issue:`43532`.) .. _distutils-deprecated: @@ -1147,10 +1148,18 @@ IDLE and idlelib ---------------- Make IDLE invoke :func:`sys.excepthook` (when started without '-n'). -User hooks were previously ignored. (Patch by Ken Hilton in +User hooks were previously ignored. (Contributed by Ken Hilton in :issue:`43008`.) -This change was backported to a 3.9 maintenance release. +Rearrange the settings dialog. Split the General tab into Windows +and Shell/Ed tabs. Move help sources, which extend the Help menu, to the +Extensions tab. Make space for new options and shorten the dialog. The +latter makes the dialog better fit small screens. (Contributed by Terry Jan +Reedy in :issue:`40468`.) Move the indent space setting from the Font tab to +the new Windows tab. (Contributed by Mark Roseman and Terry Jan Reedy in +:issue:`33962`.) + +The changes above were backported to a 3.9 maintenance release. Add a Shell sidebar. Move the primary prompt ('>>>') to the sidebar. Add secondary prompts ('...') to the sidebar. Left click and optional @@ -1163,17 +1172,22 @@ in :issue:`37903`.) Use spaces instead of tabs to indent interactive code. This makes interactive code entries 'look right'. Making this feasible was a -major motivation for adding the shell sidebar. Contributed by +major motivation for adding the shell sidebar. (Contributed by Terry Jan Reedy in :issue:`37892`.) -We expect to backport these shell changes to a future 3.9 maintenance -release. - Highlight the new :ref:`soft keywords ` :keyword:`match`, :keyword:`case `, and :keyword:`_ ` in pattern-matching statements. However, this highlighting is not perfect and will be incorrect in some rare cases, including some ``_``-s in -``case`` patterns. (Contributed by Tal Einat in bpo-44010.) +``case`` patterns. (Contributed by Tal Einat in :issue:`44010`.) + +New in 3.10 maintenance releases. + +Apply syntax highlighting to ``.pyi`` files. (Contributed by Alex +Waygood and Terry Jan Reedy in :issue:`45447`.) + +Include prompts when saving Shell with inputs and outputs. +(Contributed by Terry Jan Reedy in :gh:`95191`.) importlib.metadata ------------------ @@ -1212,6 +1226,12 @@ now call :func:`inspect.get_annotations` to retrieve annotations. This means also now un-stringize stringized annotations. (Contributed by Larry Hastings in :issue:`43817`.) +itertools +--------- + +Add :func:`itertools.pairwise()`. +(Contributed by Raymond Hettinger in :issue:`38200`.) + linecache --------- @@ -1249,11 +1269,11 @@ pathlib ------- Add slice support to :attr:`PurePath.parents `. -(Contributed by Joshua Cannon in :issue:`35498`) +(Contributed by Joshua Cannon in :issue:`35498`.) Add negative indexing support to :attr:`PurePath.parents `. -(Contributed by Yaroslav Pankovych in :issue:`21041`) +(Contributed by Yaroslav Pankovych in :issue:`21041`.) Add :meth:`Path.hardlink_to ` method that supersedes :meth:`~pathlib.Path.link_to`. The new method has the same argument @@ -1271,7 +1291,7 @@ platform Add :func:`platform.freedesktop_os_release()` to retrieve operation system identification from `freedesktop.org os-release `_ standard file. -(Contributed by Christian Heimes in :issue:`28468`) +(Contributed by Christian Heimes in :issue:`28468`.) pprint ------ @@ -1429,14 +1449,14 @@ of types readily interpretable by type checkers. typing ------ -For major changes, see `New Features Related to Type Hints`_. +For major changes, see :ref:`new-feat-related-type-hints`. The behavior of :class:`typing.Literal` was changed to conform with :pep:`586` and to match the behavior of static type checkers specified in the PEP. 1. ``Literal`` now de-duplicates parameters. 2. Equality comparisons between ``Literal`` objects are now order independent. -3. ``Literal`` comparisons now respects types. For example, +3. ``Literal`` comparisons now respect types. For example, ``Literal[0] == Literal[False]`` previously evaluated to ``True``. It is now ``False``. To support this change, the internally used type cache now supports differentiating types. @@ -1456,7 +1476,7 @@ and to match the behavior of static type checkers specified in the PEP. Add new function :func:`typing.is_typeddict` to introspect if an annotation is a :class:`typing.TypedDict`. -(Contributed by Patrick Reader in :issue:`41792`) +(Contributed by Patrick Reader in :issue:`41792`.) Subclasses of ``typing.Protocol`` which only have data variables declared will now raise a ``TypeError`` when checked with ``isinstance`` unless they @@ -1464,14 +1484,14 @@ are decorated with :func:`runtime_checkable`. Previously, these checks passed silently. Users should decorate their subclasses with the :func:`runtime_checkable` decorator if they want runtime protocols. -(Contributed by Yurii Karabas in :issue:`38908`) +(Contributed by Yurii Karabas in :issue:`38908`.) Importing from the ``typing.io`` and ``typing.re`` submodules will now emit :exc:`DeprecationWarning`. These submodules have been deprecated since Python 3.8 and will be removed in a future version of Python. Anything belonging to those submodules should be imported directly from :mod:`typing` instead. -(Contributed by Sebastian Rittau in :issue:`38291`) +(Contributed by Sebastian Rittau in :issue:`38291`.) unittest -------- @@ -1549,7 +1569,7 @@ Optimizations strings, and the function object lazily converts this into the annotations dict on demand. This optimization cuts the CPU time needed to define an annotated function by half. - (Contributed by Yurii Karabas and Inada Naoki in :issue:`42202`) + (Contributed by Yurii Karabas and Inada Naoki in :issue:`42202`.) * Substring search functions such as ``str1 in str2`` and ``str2.find(str1)`` now sometimes use Crochemore & Perrin's "Two-Way" string searching @@ -1558,16 +1578,16 @@ Optimizations * Add micro-optimizations to ``_PyType_Lookup()`` to improve type attribute cache lookup performance in the common case of cache hits. This makes the interpreter 1.04 times faster - on average. (Contributed by Dino Viehland in :issue:`43452`) + on average. (Contributed by Dino Viehland in :issue:`43452`.) * The following built-in functions now support the faster :pep:`590` vectorcall calling convention: :func:`map`, :func:`filter`, :func:`reversed`, :func:`bool` and :func:`float`. - (Contributed by Dong-hee Na and Jeroen Demeyer in :issue:`43575`, :issue:`43287`, :issue:`41922`, :issue:`41873` and :issue:`41870`) + (Contributed by Dong-hee Na and Jeroen Demeyer in :issue:`43575`, :issue:`43287`, :issue:`41922`, :issue:`41873` and :issue:`41870`.) * :class:`BZ2File` performance is improved by removing internal ``RLock``. This makes :class:`BZ2File` thread unsafe in the face of multiple simultaneous readers or writers, just like its equivalent classes in :mod:`gzip` and - :mod:`lzma` have always been. (Contributed by Inada Naoki in :issue:`43785`). + :mod:`lzma` have always been. (Contributed by Inada Naoki in :issue:`43785`.) .. _whatsnew310-deprecated: @@ -1583,7 +1603,7 @@ Deprecated :keyword:`for`, :keyword:`if`, :keyword:`in`, :keyword:`is` and :keyword:`or`. In future releases it will be changed to syntax warning, and finally to syntax error. - (Contributed by Serhiy Storchaka in :issue:`43833`). + (Contributed by Serhiy Storchaka in :issue:`43833`.) * Starting in this release, there will be a concerted effort to begin cleaning up old import semantics that were kept for Python 2.7 @@ -1646,13 +1666,12 @@ Deprecated :meth:`importlib.machinery.FrozenImporter.find_module`, :meth:`importlib.machinery.WindowsRegistryFinder.find_module`, :meth:`importlib.machinery.PathFinder.find_module`, - :meth:`importlib.abc.MetaPathFinder.find_module`), + :meth:`importlib.abc.MetaPathFinder.find_module` ), :meth:`importlib.abc.PathEntryFinder.find_module` ( - :meth:`importlib.machinery.FileFinder.find_module`, - ), and + :meth:`importlib.machinery.FileFinder.find_module` ), and :meth:`importlib.abc.PathEntryFinder.find_loader` ( - :meth:`importlib.machinery.FileFinder.find_loader` - ) now raise :exc:`DeprecationWarning` and are slated for removal in + :meth:`importlib.machinery.FileFinder.find_loader` ) + now raise :exc:`DeprecationWarning` and are slated for removal in Python 3.12 (previously they were documented as deprecated in Python 3.4). (Contributed by Brett Cannon in :issue:`42135`.) @@ -1690,19 +1709,6 @@ Deprecated scheduled for removal in Python 3.12. (Contributed by Erlend E. Aasland in :issue:`42264`.) -* :func:`asyncio.get_event_loop` now emits a deprecation warning if there is - no running event loop. In the future it will be an alias of - :func:`~asyncio.get_running_loop`. - :mod:`asyncio` functions which implicitly create a :class:`~asyncio.Future` - or :class:`~asyncio.Task` objects now emit - a deprecation warning if there is no running event loop and no explicit - *loop* argument is passed: :func:`~asyncio.ensure_future`, - :func:`~asyncio.wrap_future`, :func:`~asyncio.gather`, - :func:`~asyncio.shield`, :func:`~asyncio.as_completed` and constructors of - :class:`~asyncio.Future`, :class:`~asyncio.Task`, - :class:`~asyncio.StreamReader`, :class:`~asyncio.StreamReaderProtocol`. - (Contributed by Serhiy Storchaka in :issue:`39529`.) - * The undocumented built-in function ``sqlite3.enable_shared_cache`` is now deprecated, scheduled for removal in Python 3.12. Its use is strongly discouraged by the SQLite3 documentation. See `the SQLite3 docs @@ -1730,7 +1736,7 @@ Deprecated * ``threading.Thread.setDaemon`` => :attr:`threading.Thread.daemon` - (Contributed by Jelle Zijlstra in :issue:`21574`.) + (Contributed by Jelle Zijlstra in :gh:`87889`.) * :meth:`pathlib.Path.link_to` is deprecated and slated for removal in Python 3.12. Use :meth:`pathlib.Path.hardlink_to` instead. @@ -1772,7 +1778,7 @@ Deprecated :exc:`DeprecationWarning`. These submodules will be removed in a future version of Python. Anything belonging to these submodules should be imported directly from :mod:`typing` instead. - (Contributed by Sebastian Rittau in :issue:`38291`) + (Contributed by Sebastian Rittau in :issue:`38291`.) .. _whatsnew310-removed: @@ -1833,7 +1839,7 @@ Removed running in different threads. Note that the low-level API will still accept ``loop``. - See `Changes in the Python API`_ for examples of how to replace existing code. + See :ref:`changes-python-api` for examples of how to replace existing code. (Contributed by Yurii Karabas, Andrew Svetlov, Yury Selivanov and Kyle Stanley in :issue:`42392`.) @@ -1855,8 +1861,9 @@ Changes in the Python syntax syntax error. To get rid of the warning and make the code compatible with future releases just add a space between the numeric literal and the following keyword. - (Contributed by Serhiy Storchaka in :issue:`43833`). + (Contributed by Serhiy Storchaka in :issue:`43833`.) +.. _changes-python-api: Changes in the Python API ------------------------- @@ -1964,7 +1971,7 @@ CPython bytecode changes * The ``MAKE_FUNCTION`` instruction now accepts either a dict or a tuple of strings as the function's annotations. - (Contributed by Yurii Karabas and Inada Naoki in :issue:`42202`) + (Contributed by Yurii Karabas and Inada Naoki in :issue:`42202`.) Build Changes ============= @@ -1978,7 +1985,7 @@ Build Changes (Contributed by Victor Stinner in :issue:`36020`.) * :mod:`sqlite3` requires SQLite 3.7.15 or higher. (Contributed by Sergey Fedoseev - and Erlend E. Aasland :issue:`40744` and :issue:`40810`.) + and Erlend E. Aasland in :issue:`40744` and :issue:`40810`.) * The :mod:`atexit` module must now always be built as a built-in module. (Contributed by Victor Stinner in :issue:`42639`.) @@ -2008,8 +2015,8 @@ Build Changes * The ``configure`` script now uses the ``pkg-config`` utility, if available, to detect the location of Tcl/Tk headers and libraries. As before, those - locations can be explicitly specified with the :option:`--with-tcltk-includes` - and :option:`--with-tcltk-libs` configuration options. + locations can be explicitly specified with the ``--with-tcltk-includes`` + and ``--with-tcltk-libs`` configuration options. (Contributed by Manolis Stamatogiannakis in :issue:`42603`.) * Add :option:`--with-openssl-rpath` option to ``configure`` script. The option @@ -2131,8 +2138,7 @@ Porting to Python 3.10 * The ``PY_SSIZE_T_CLEAN`` macro must now be defined to use :c:func:`PyArg_ParseTuple` and :c:func:`Py_BuildValue` formats which use ``#``: ``es#``, ``et#``, ``s#``, ``u#``, ``y#``, ``z#``, ``U#`` and ``Z#``. - See :ref:`Parsing arguments and building values - ` and the :pep:`353`. + See :ref:`arg-parsing` and :pep:`353`. (Contributed by Victor Stinner in :issue:`40943`.) * Since :c:func:`Py_REFCNT()` is changed to the inline static function, @@ -2163,8 +2169,7 @@ Porting to Python 3.10 :c:func:`Py_GetProgramFullPath`, :c:func:`Py_GetPythonHome` and :c:func:`Py_GetProgramName` functions now return ``NULL`` if called before :c:func:`Py_Initialize` (before Python is initialized). Use the new - :ref:`Python Initialization Configuration API ` to get the - :ref:`Python Path Configuration. `. + :ref:`init-config` API to get the :ref:`init-path-config`. (Contributed by Victor Stinner in :issue:`42260`.) * :c:func:`PyList_SET_ITEM`, :c:func:`PyTuple_SET_ITEM` and @@ -2178,9 +2183,9 @@ Porting to Python 3.10 ``picklebufobject.h``, ``pyarena.h``, ``pyctype.h``, ``pydebug.h``, ``pyfpe.h``, and ``pytime.h`` have been moved to the ``Include/cpython`` directory. These files must not be included directly, as they are already - included in ``Python.h``: :ref:`Include Files `. If they have + included in ``Python.h``; see :ref:`api-includes`. If they have been included directly, consider including ``Python.h`` instead. - (Contributed by Nicholas Sim in :issue:`35134`) + (Contributed by Nicholas Sim in :issue:`35134`.) * Use the :c:data:`Py_TPFLAGS_IMMUTABLETYPE` type flag to create immutable type objects. Do not rely on :c:data:`Py_TPFLAGS_HEAPTYPE` to decide if a type @@ -2190,7 +2195,7 @@ Porting to Python 3.10 * The undocumented function ``Py_FrozenMain`` has been removed from the limited API. The function is mainly useful for custom builds of Python. - (Contributed by Petr Viktorin in :issue:`26241`) + (Contributed by Petr Viktorin in :issue:`26241`.) Deprecated ---------- diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 9751f894f9a..bffb8d03aa7 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -2,8 +2,7 @@ What's New In Python 3.11 **************************** -:Release: |release| -:Date: |today| +:Editor: Pablo Galindo Salgado .. Rules for maintenance: @@ -49,12 +48,8 @@ This article explains the new features in Python 3.11, compared to 3.10. For full details, see the :ref:`changelog `. -.. note:: - - Prerelease users should be aware that this document is currently in draft - form. It will be updated substantially as Python 3.11 moves towards release, - so it's worth checking back even after reading earlier versions. +.. _whatsnew311-summary: Summary -- Release highlights ============================= @@ -62,20 +57,63 @@ Summary -- Release highlights .. This section singles out the most important changes in Python 3.11. Brevity is key. +* Python 3.11 is between 10-60% faster than Python 3.10. + On average, we measured a 1.25x speedup on the standard benchmark suite. + See :ref:`whatsnew311-faster-cpython` for details. .. PEP-sized items next. +New syntax features: + +* :ref:`whatsnew311-pep654` + +New built-in features: + +* :ref:`whatsnew311-pep678` + +New standard library modules: + +* :pep:`680`: :mod:`tomllib` — + Support for parsing `TOML `_ in the Standard Library + +Interpreter improvements: + +* :ref:`whatsnew311-pep657` +* New :option:`-P` command line option and :envvar:`PYTHONSAFEPATH` environment + variable to :ref:`disable automatically prepending potentially unsafe paths + ` to :data:`sys.path` + +New typing features: + +* :ref:`whatsnew311-pep646` +* :ref:`whatsnew311-pep655` +* :ref:`whatsnew311-pep673` +* :ref:`whatsnew311-pep675` +* :ref:`whatsnew311-pep681` + +Important deprecations, removals and restrictions: + +* :pep:`594`: + :ref:`Many legacy standard library modules have been deprecated + ` and will be removed in Python 3.13 +* :pep:`624`: + :ref:`Py_UNICODE encoder APIs have been removed ` +* :pep:`670`: + :ref:`Macros converted to static inline functions ` + + +.. _whatsnew311-features: New Features ============ .. _whatsnew311-pep657: -Enhanced error locations in tracebacks --------------------------------------- +PEP 657: Fine-grained error locations in tracebacks +--------------------------------------------------- When printing tracebacks, the interpreter will now point to the exact expression -that caused the error instead of just the line. For example: +that caused the error, instead of just the line. For example: .. code-block:: python @@ -88,16 +126,15 @@ that caused the error instead of just the line. For example: ^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'x' -Previous versions of the interpreter would point to just the line making it +Previous versions of the interpreter would point to just the line, making it ambiguous which object was ``None``. These enhanced errors can also be helpful -when dealing with deeply nested dictionary objects and multiple function calls, +when dealing with deeply nested :class:`dict` objects and multiple function calls: .. code-block:: python Traceback (most recent call last): File "query.py", line 37, in magic_arithmetic('foo') - ^^^^^^^^^^^^^^^^^^^^^^^ File "query.py", line 18, in magic_arithmetic return add_counts(x) / 25 ^^^^^^^^^^^^^ @@ -109,7 +146,7 @@ when dealing with deeply nested dictionary objects and multiple function calls, ~~~~~~~~~~~~~~~~~~^^^^^ TypeError: 'NoneType' object is not subscriptable -as well as complex arithmetic expressions: +As well as complex arithmetic expressions: .. code-block:: python @@ -119,77 +156,579 @@ as well as complex arithmetic expressions: ~~~~~~^~~ ZeroDivisionError: division by zero +Additionally, the information used by the enhanced traceback feature +is made available via a general API, that can be used to correlate +:term:`bytecode` :ref:`instructions ` with source code location. +This information can be retrieved using: + +- The :meth:`codeobject.co_positions` method in Python. +- The :c:func:`PyCode_Addr2Location` function in the C API. + See :pep:`657` for more details. (Contributed by Pablo Galindo, Batuhan Taskaya and Ammar Askar in :issue:`43950`.) .. note:: - This feature requires storing column positions in code objects which may - result in a small increase of disk usage of compiled Python files or - interpreter memory usage. To avoid storing the extra information and/or - deactivate printing the extra traceback information, the - :option:`-X` ``no_debug_ranges`` command line flag or the :envvar:`PYTHONNODEBUGRANGES` - environment variable can be used. + This feature requires storing column positions in :ref:`codeobjects`, + which may result in a small increase in interpreter memory usage + and disk usage for compiled Python files. + To avoid storing the extra information + and deactivate printing the extra traceback information, + use the :option:`-X no_debug_ranges <-X>` command line option + or the :envvar:`PYTHONNODEBUGRANGES` environment variable. -Column information for code objects -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The information used by the enhanced traceback feature is made available as a -general API that can be used to correlate bytecode instructions with source -code. This information can be retrieved using: +.. _whatsnew311-pep654: -- The :meth:`codeobject.co_positions` method in Python. -- The :c:func:`PyCode_Addr2Location` function in the C-API. +PEP 654: Exception Groups and ``except*`` +----------------------------------------- -The :option:`-X` ``no_debug_ranges`` option and the environment variable -:envvar:`PYTHONNODEBUGRANGES` can be used to disable this feature. +:pep:`654` introduces language features that enable a program +to raise and handle multiple unrelated exceptions simultaneously. +The builtin types :exc:`ExceptionGroup` and :exc:`BaseExceptionGroup` +make it possible to group exceptions and raise them together, +and the new :keyword:`except* ` syntax generalizes +:keyword:`except` to match subgroups of exception groups. -See :pep:`657` for more details. (Contributed by Pablo Galindo, Batuhan Taskaya -and Ammar Askar in :issue:`43950`.) +See :pep:`654` for more details. +(Contributed by Irit Katriel in :issue:`45292`. PEP written by +Irit Katriel, Yury Selivanov and Guido van Rossum.) + + +.. _whatsnew311-pep678: + +PEP 678: Exceptions can be enriched with notes +---------------------------------------------- + +The :meth:`~BaseException.add_note` method is added to :exc:`BaseException`. +It can be used to enrich exceptions with context information +that is not available at the time when the exception is raised. +The added notes appear in the default traceback. + +See :pep:`678` for more details. + +(Contributed by Irit Katriel in :issue:`45607`. +PEP written by Zac Hatfield-Dodds.) + + +.. _whatsnew311-windows-launcher: + +Windows ``py.exe`` launcher improvements +---------------------------------------- + +The copy of the :ref:`launcher` included with Python 3.11 has been significantly +updated. It now supports company/tag syntax as defined in :pep:`514` using the +``-V:/`` argument instead of the limited ``-.``. +This allows launching distributions other than ``PythonCore``, +the one hosted on `python.org `_. + +When using ``-V:`` selectors, either company or tag can be omitted, but all +installs will be searched. For example, ``-V:OtherPython/`` will select the +"best" tag registered for ``OtherPython``, while ``-V:3.11`` or ``-V:/3.11`` +will select the "best" distribution with tag ``3.11``. + +When using the legacy ``-``, ``-.``, +``--`` or ``-.-`` arguments, +all existing behaviour should be preserved from past versions, +and only releases from ``PythonCore`` will be selected. +However, the ``-64`` suffix now implies "not 32-bit" (not necessarily x86-64), +as there are multiple supported 64-bit platforms. +32-bit runtimes are detected by checking the runtime's tag for a ``-32`` suffix. +All releases of Python since 3.5 have included this in their 32-bit builds. + + +.. _new-feat-related-type-hints-311: +.. _whatsnew311-typing-features: + +New Features Related to Type Hints +================================== + +This section covers major changes affecting :pep:`484` type hints and +the :mod:`typing` module. + + +.. _whatsnew311-pep646: + +PEP 646: Variadic generics +-------------------------- + +:pep:`484` previously introduced :data:`~typing.TypeVar`, enabling creation +of generics parameterised with a single type. :pep:`646` adds +:data:`~typing.TypeVarTuple`, enabling parameterisation +with an *arbitrary* number of types. In other words, +a :data:`~typing.TypeVarTuple` is a *variadic* type variable, +enabling *variadic* generics. + +This enables a wide variety of use cases. +In particular, it allows the type of array-like structures +in numerical computing libraries such as NumPy and TensorFlow to be +parameterised with the array *shape*. Static type checkers will now +be able to catch shape-related bugs in code that uses these libraries. + +See :pep:`646` for more details. + +(Contributed by Matthew Rahtz in :issue:`43224`, with contributions by +Serhiy Storchaka and Jelle Zijlstra. PEP written by Mark Mendoza, Matthew +Rahtz, Pradeep Kumar Srinivasan, and Vincent Siles.) + + +.. _whatsnew311-pep655: + +PEP 655: Marking individual ``TypedDict`` items as required or not-required +--------------------------------------------------------------------------- + +:data:`~typing.Required` and :data:`~typing.NotRequired` provide a +straightforward way to mark whether individual items in a +:class:`~typing.TypedDict` must be present. Previously, this was only possible +using inheritance. + +All fields are still required by default, +unless the *total* parameter is set to ``False``, +in which case all fields are still not-required by default. +For example, the following specifies a :class:`!TypedDict` +with one required and one not-required key:: + + class Movie(TypedDict): + title: str + year: NotRequired[int] + + m1: Movie = {"title": "Black Panther", "year": 2018} # OK + m2: Movie = {"title": "Star Wars"} # OK (year is not required) + m3: Movie = {"year": 2022} # ERROR (missing required field title) + +The following definition is equivalent:: + + class Movie(TypedDict, total=False): + title: Required[str] + year: int + +See :pep:`655` for more details. + +(Contributed by David Foster and Jelle Zijlstra in :issue:`47087`. PEP +written by David Foster.) + + +.. _whatsnew311-pep673: + +PEP 673: ``Self`` type +---------------------- + +The new :data:`~typing.Self` annotation provides a simple and intuitive +way to annotate methods that return an instance of their class. This +behaves the same as the :class:`~typing.TypeVar`-based approach +:pep:`specified in PEP 484 <484#annotating-instance-and-class-methods>`, +but is more concise and easier to follow. + +Common use cases include alternative constructors provided as +:func:`classmethod `\s, +and :meth:`~object.__enter__` methods that return ``self``:: + + class MyLock: + def __enter__(self) -> Self: + self.lock() + return self + + ... + + class MyInt: + @classmethod + def fromhex(cls, s: str) -> Self: + return cls(int(s, 16)) + + ... + +:data:`~typing.Self` can also be used to annotate method parameters +or attributes of the same type as their enclosing class. + +See :pep:`673` for more details. + +(Contributed by James Hilton-Balfe in :issue:`46534`. PEP written by +Pradeep Kumar Srinivasan and James Hilton-Balfe.) + + +.. _whatsnew311-pep675: + +PEP 675: Arbitrary literal string type +-------------------------------------- + +The new :data:`~typing.LiteralString` annotation may be used to indicate +that a function parameter can be of any literal string type. This allows +a function to accept arbitrary literal string types, as well as strings +created from other literal strings. Type checkers can then +enforce that sensitive functions, such as those that execute SQL +statements or shell commands, are called only with static arguments, +providing protection against injection attacks. + +For example, a SQL query function could be annotated as follows:: + + def run_query(sql: LiteralString) -> ... + ... + + def caller( + arbitrary_string: str, + query_string: LiteralString, + table_name: LiteralString, + ) -> None: + run_query("SELECT * FROM students") # ok + run_query(query_string) # ok + run_query("SELECT * FROM " + table_name) # ok + run_query(arbitrary_string) # type checker error + run_query( # type checker error + f"SELECT * FROM students WHERE name = {arbitrary_string}" + ) + +See :pep:`675` for more details. + +(Contributed by Jelle Zijlstra in :issue:`47088`. PEP written by Pradeep +Kumar Srinivasan and Graham Bleaney.) + + +.. _whatsnew311-pep681: + +PEP 681: Data class transforms +------------------------------ + +:data:`~typing.dataclass_transform` may be used to +decorate a class, metaclass, or a function that is itself a decorator. +The presence of ``@dataclass_transform()`` tells a static type checker that the +decorated object performs runtime "magic" that transforms a class, +giving it :func:`dataclass `-like behaviors. + +For example:: + + # The create_model decorator is defined by a library. + @typing.dataclass_transform() + def create_model(cls: Type[T]) -> Type[T]: + cls.__init__ = ... + cls.__eq__ = ... + cls.__ne__ = ... + return cls + + # The create_model decorator can now be used to create new model classes: + @create_model + class CustomerModel: + id: int + name: str + + c = CustomerModel(id=327, name="Eric Idle") + +See :pep:`681` for more details. + +(Contributed by Jelle Zijlstra in :gh:`91860`. PEP written by +Erik De Bonte and Eric Traut.) + + +.. _whatsnew311-pep563-deferred: + +PEP 563 may not be the future +----------------------------- + +:pep:`563` Postponed Evaluation of Annotations +(the ``from __future__ import annotations`` :ref:`future statement `) +that was originally planned for release in Python 3.10 +has been put on hold indefinitely. +See `this message from the Steering Council `__ +for more information. + + +.. _whatsnew311-other-lang-changes: Other Language Changes ====================== -* Asynchronous comprehensions are now allowed inside comprehensions in - asynchronous functions. Outer comprehensions implicitly become - asynchronous. (Contributed by Serhiy Storchaka in :issue:`33346`.) +* Starred unpacking expressions can now be used in :keyword:`for` statements. + (See :issue:`46725` for more details.) + +* Asynchronous :ref:`comprehensions ` are now allowed + inside comprehensions in :ref:`asynchronous functions `. + Outer comprehensions implicitly become asynchronous in this case. + (Contributed by Serhiy Storchaka in :issue:`33346`.) * A :exc:`TypeError` is now raised instead of an :exc:`AttributeError` in - :meth:`contextlib.ExitStack.enter_context` and - :meth:`contextlib.AsyncExitStack.enter_async_context` for objects which do not - support the :term:`context manager` or :term:`asynchronous context manager` - protocols correspondingly. - (Contributed by Serhiy Storchaka in :issue:`44471`.) + :keyword:`with` statements and :meth:`contextlib.ExitStack.enter_context` + for objects that do not support the :term:`context manager` protocol, + and in :keyword:`async with` statements and + :meth:`contextlib.AsyncExitStack.enter_async_context` + for objects not supporting the :term:`asynchronous context manager` protocol. + (Contributed by Serhiy Storchaka in :issue:`12022` and :issue:`44471`.) -* A :exc:`TypeError` is now raised instead of an :exc:`AttributeError` in - :keyword:`with` and :keyword:`async with` statements for objects which do not - support the :term:`context manager` or :term:`asynchronous context manager` - protocols correspondingly. - (Contributed by Serhiy Storchaka in :issue:`12022`.) +* Added :meth:`object.__getstate__`, which provides the default + implementation of the :meth:`!__getstate__` method. :mod:`copy`\ing + and :mod:`pickle`\ing instances of subclasses of builtin types + :class:`bytearray`, :class:`set`, :class:`frozenset`, + :class:`collections.OrderedDict`, :class:`collections.deque`, + :class:`weakref.WeakSet`, and :class:`datetime.tzinfo` now copies and + pickles instance attributes implemented as :term:`slots <__slots__>`. + (Contributed by Serhiy Storchaka in :issue:`26579`.) +.. _whatsnew311-pythonsafepath: + +* Added a :option:`-P` command line option + and a :envvar:`PYTHONSAFEPATH` environment variable, + which disable the automatic prepending to :data:`sys.path` + of the script's directory when running a script, + or the current directory when using :option:`-c` and :option:`-m`. + This ensures only stdlib and installed modules + are picked up by :keyword:`import`, + and avoids unintentionally or maliciously shadowing modules + with those in a local (and typically user-writable) directory. + (Contributed by Victor Stinner in :gh:`57684`.) + +* A ``"z"`` option was added to the :ref:`formatspec` that + coerces negative to positive zero after rounding to the format precision. + See :pep:`682` for more details. + (Contributed by John Belmonte in :gh:`90153`.) + +* Bytes are no longer accepted on :data:`sys.path`. Support broke sometime + between Python 3.2 and 3.6, with no one noticing until after Python 3.10.0 + was released. In addition, bringing back support would be problematic due to + interactions between :option:`-b` and :data:`sys.path_importer_cache` when + there is a mixture of :class:`str` and :class:`bytes` keys. + (Contributed by Thomas Grainger in :gh:`91181`.) + + +.. _whatsnew311-other-implementation-changes: Other CPython Implementation Changes ==================================== -* Special methods :meth:`complex.__complex__` and :meth:`bytes.__bytes__` are implemented to - support :class:`typing.SupportsComplex` and :class:`typing.SupportsBytes` protocols. +* The special methods :meth:`~object.__complex__` for :class:`complex` + and :meth:`~object.__bytes__` for :class:`bytes` are implemented to support + the :class:`typing.SupportsComplex` and :class:`typing.SupportsBytes` protocols. (Contributed by Mark Dickinson and Dong-hee Na in :issue:`24234`.) -* ``siphash13`` is added as a new internal hashing algorithms. It's has similar security - properties as ``siphash24`` but it is slightly faster for long inputs. ``str``, ``bytes``, - and some other types now use it as default algorithm for ``hash()``. :pep:`552` - hash-based pyc files now use ``siphash13``, too. +* ``siphash13`` is added as a new internal hashing algorithm. + It has similar security properties as ``siphash24``, + but it is slightly faster for long inputs. + :class:`str`, :class:`bytes`, and some other types + now use it as the default algorithm for :func:`hash`. + :pep:`552` :ref:`hash-based .pyc files ` + now use ``siphash13`` too. (Contributed by Inada Naoki in :issue:`29410`.) +* When an active exception is re-raised by a :keyword:`raise` statement with no parameters, + the traceback attached to this exception is now always ``sys.exc_info()[1].__traceback__``. + This means that changes made to the traceback in the current :keyword:`except` clause are + reflected in the re-raised exception. + (Contributed by Irit Katriel in :issue:`45711`.) + +* The interpreter state's representation of handled exceptions + (aka ``exc_info`` or ``_PyErr_StackItem``) + now only has the ``exc_value`` field; ``exc_type`` and ``exc_traceback`` + have been removed, as they can be derived from ``exc_value``. + (Contributed by Irit Katriel in :issue:`45711`.) + +* A new :ref:`command line option `, ``AppendPath``, + has been added for the Windows installer. + It behaves similarly to ``PrependPath``, + but appends the install and scripts directories instead of prepending them. + (Contributed by Bastian Neuburger in :issue:`44934`.) + +* The :c:member:`PyConfig.module_search_paths_set` field must now be set to ``1`` for + initialization to use :c:member:`PyConfig.module_search_paths` to initialize + :data:`sys.path`. Otherwise, initialization will recalculate the path and replace + any values added to ``module_search_paths``. + +* The output of the :option:`--help` option now fits in 50 lines/80 columns. + Information about :ref:`Python environment variables ` + and :option:`-X` options is now available using the respective + :option:`--help-env` and :option:`--help-xoptions` flags, + and with the new :option:`--help-all`. + (Contributed by Éric Araujo in :issue:`46142`.) + +* Converting between :class:`int` and :class:`str` in bases other than 2 + (binary), 4, 8 (octal), 16 (hexadecimal), or 32 such as base 10 (decimal) + now raises a :exc:`ValueError` if the number of digits in string form is + above a limit to avoid potential denial of service attacks due to the + algorithmic complexity. This is a mitigation for `CVE-2020-10735 + `_. + This limit can be configured or disabled by environment variable, command + line flag, or :mod:`sys` APIs. See the :ref:`integer string conversion + length limitation ` documentation. The default limit + is 4300 digits in string form. + + +.. _whatsnew311-new-modules: + New Modules =========== -* None yet. +* :mod:`tomllib`: For parsing `TOML `_. + See :pep:`680` for more details. + (Contributed by Taneli Hukkinen in :issue:`40059`.) +* :mod:`wsgiref.types`: + :pep:`WSGI <3333>`-specific types for static type checking. + (Contributed by Sebastian Rittau in :issue:`42012`.) + + +.. _whatsnew311-improved-modules: Improved Modules ================ +.. _whatsnew311-asyncio: + +asyncio +------- + +* Added the :class:`~asyncio.TaskGroup` class, + an :ref:`asynchronous context manager ` + holding a group of tasks that will wait for all of them upon exit. + For new code this is recommended over using + :func:`~asyncio.create_task` and :func:`~asyncio.gather` directly. + (Contributed by Yury Selivanov and others in :gh:`90908`.) + +* Added :func:`~asyncio.timeout`, an asynchronous context manager for + setting a timeout on asynchronous operations. For new code this is + recommended over using :func:`~asyncio.wait_for` directly. + (Contributed by Andrew Svetlov in :gh:`90927`.) + +* Added the :class:`~asyncio.Runner` class, which exposes the machinery + used by :func:`~asyncio.run`. + (Contributed by Andrew Svetlov in :gh:`91218`.) + +* Added the :class:`~asyncio.Barrier` class to the synchronization + primitives in the asyncio library, and the related + :exc:`~asyncio.BrokenBarrierError` exception. + (Contributed by Yves Duprat and Andrew Svetlov in :gh:`87518`.) + +* Added keyword argument *all_errors* to :meth:`asyncio.loop.create_connection` + so that multiple connection errors can be raised as an :exc:`ExceptionGroup`. + +* Added the :meth:`asyncio.StreamWriter.start_tls` method for + upgrading existing stream-based connections to TLS. + (Contributed by Ian Good in :issue:`34975`.) + +* Added raw datagram socket functions to the event loop: + :meth:`~asyncio.loop.sock_sendto`, + :meth:`~asyncio.loop.sock_recvfrom` and + :meth:`~asyncio.loop.sock_recvfrom_into`. + These have implementations in :class:`~asyncio.SelectorEventLoop` and + :class:`~asyncio.ProactorEventLoop`. + (Contributed by Alex Grönholm in :issue:`46805`.) + +* Added :meth:`~asyncio.Task.cancelling` and + :meth:`~asyncio.Task.uncancel` methods to :class:`~asyncio.Task`. + These are primarily intended for internal use, + notably by :class:`~asyncio.TaskGroup`. + + +.. _whatsnew311-contextlib: + +contextlib +---------- + +* Added non parallel-safe :func:`~contextlib.chdir` context manager to change + the current working directory and then restore it on exit. Simple wrapper + around :func:`~os.chdir`. (Contributed by Filipe Laíns in :issue:`25625`) + + +.. _whatsnew311-dataclasses: + +dataclasses +----------- + +* Change field default mutability check, allowing only defaults which are + :term:`hashable` instead of any object which is not an instance of + :class:`dict`, :class:`list` or :class:`set`. (Contributed by Eric V. Smith in + :issue:`44674`.) + + +.. _whatsnew311-datetime: + +datetime +-------- + +* Add :attr:`datetime.UTC`, a convenience alias for + :attr:`datetime.timezone.utc`. (Contributed by Kabir Kwatra in :gh:`91973`.) + +* :meth:`datetime.date.fromisoformat`, :meth:`datetime.time.fromisoformat` and + :meth:`datetime.datetime.fromisoformat` can now be used to parse most ISO 8601 + formats (barring only those that support fractional hours and minutes). + (Contributed by Paul Ganssle in :gh:`80010`.) + + +.. _whatsnew311-enum: + +enum +---- + +* Renamed :class:`!EnumMeta` to :class:`~enum.EnumType` + (:class:`!EnumMeta` kept as an alias). + +* Added :class:`~enum.StrEnum`, + with members that can be used as (and must be) strings. + +* Added :class:`~enum.ReprEnum`, + which only modifies the :meth:`~object.__repr__` of members + while returning their literal values (rather than names) + for :meth:`~object.__str__` and :meth:`~object.__format__` + (used by :func:`str`, :func:`format` and :term:`f-string`\s). + +* Changed :class:`~enum.IntEnum`, :class:`~enum.IntFlag` and :class:`~enum.StrEnum` + to now inherit from :class:`~enum.ReprEnum`, + so their :func:`str` output now matches :func:`format` + (both ``str(AnIntEnum.ONE)`` and ``format(AnIntEnum.ONE)`` return ``'1'``, + whereas before ``str(AnIntEnum.ONE)`` returned ``'AnIntEnum.ONE'``. + +* Changed :meth:`Enum.__format__() ` + (the default for :func:`format`, :meth:`str.format` and :term:`f-string`\s) + of enums with mixed-in types (e.g. :class:`int`, :class:`str`) + to also include the class name in the output, not just the member's key. + This matches the existing behavior of :meth:`enum.Enum.__str__`, + returning e.g. ``'AnEnum.MEMBER'`` for an enum ``AnEnum(str, Enum)`` + instead of just ``'MEMBER'``. + +* Added a new *boundary* class parameter to :class:`~enum.Flag` enums + and the :class:`~enum.FlagBoundary` enum with its options, + to control how to handle out-of-range flag values. + +* Added the :func:`~enum.verify` enum decorator + and the :class:`~enum.EnumCheck` enum with its options, + to check enum classes against several specific constraints. + +* Added the :func:`~enum.member` and :func:`~enum.nonmember` decorators, + to ensure the decorated object is/is not converted to an enum member. + +* Added the :func:`~enum.property` decorator, + which works like :func:`property` except for enums. + Use this instead of :func:`types.DynamicClassAttribute`. + +* Added the :func:`~enum.global_enum` enum decorator, + which adjusts :meth:`~object.__repr__` and :meth:`~object.__str__` + to show values as members of their module rather than the enum class. + For example, ``'re.ASCII'`` for the :data:`~re.ASCII` member + of :class:`re.RegexFlag` rather than ``'RegexFlag.ASCII'``. + +* Enhanced :class:`~enum.Flag` to support + :func:`len`, iteration and :keyword:`in`/:keyword:`not in` on its members. + For example, the following now works: + ``len(AFlag(3)) == 2 and list(AFlag(3)) == (AFlag.ONE, AFlag.TWO)`` + +* Changed :class:`~enum.Enum` and :class:`~enum.Flag` + so that members are now defined + before :meth:`~object.__init_subclass__` is called; + :func:`dir` now includes methods, etc., from mixed-in data types. + +* Changed :class:`~enum.Flag` + to only consider primary values (power of two) canonical + while composite values (``3``, ``6``, ``10``, etc.) are considered aliases; + inverted flags are coerced to their positive equivalent. + + +.. _whatsnew311-fcntl: + +fcntl +----- + +* On FreeBSD, the :data:`!F_DUP2FD` and :data:`!F_DUP2FD_CLOEXEC` flags respectively + are supported, the former equals to ``dup2`` usage while the latter set + the ``FD_CLOEXEC`` flag in addition. + + +.. _whatsnew311-fractions: + fractions --------- @@ -201,9 +740,137 @@ fractions (Contributed by Mark Dickinson in :issue:`44547`.) +.. _whatsnew311-functools: + +functools +--------- + +* :func:`functools.singledispatch` now supports :data:`types.UnionType` + and :data:`typing.Union` as annotations to the dispatch argument.:: + + >>> from functools import singledispatch + >>> @singledispatch + ... def fun(arg, verbose=False): + ... if verbose: + ... print("Let me just say,", end=" ") + ... print(arg) + ... + >>> @fun.register + ... def _(arg: int | float, verbose=False): + ... if verbose: + ... print("Strength in numbers, eh?", end=" ") + ... print(arg) + ... + >>> from typing import Union + >>> @fun.register + ... def _(arg: Union[list, set], verbose=False): + ... if verbose: + ... print("Enumerate this:") + ... for i, elem in enumerate(arg): + ... print(i, elem) + ... + + (Contributed by Yurii Karabas in :issue:`46014`.) + + +.. _whatsnew311-hashlib: + +hashlib +------- + +* :func:`hashlib.blake2b` and :func:`hashlib.blake2s` now prefer `libb2`_ + over Python's vendored copy. + (Contributed by Christian Heimes in :issue:`47095`.) + +* The internal ``_sha3`` module with SHA3 and SHAKE algorithms now uses + *tiny_sha3* instead of the *Keccak Code Package* to reduce code and binary + size. The :mod:`hashlib` module prefers optimized SHA3 and SHAKE + implementations from OpenSSL. The change affects only installations without + OpenSSL support. + (Contributed by Christian Heimes in :issue:`47098`.) + +* Add :func:`hashlib.file_digest`, a helper function for efficient hashing + of files or file-like objects. + (Contributed by Christian Heimes in :gh:`89313`.) + + +.. _whatsnew311-idle: + +IDLE and idlelib +---------------- + +* Apply syntax highlighting to ``.pyi`` files. (Contributed by Alex + Waygood and Terry Jan Reedy in :issue:`45447`.) + +* Include prompts when saving Shell with inputs and outputs. + (Contributed by Terry Jan Reedy in :gh:`95191`.) + + +.. _whatsnew311-inspect: + +inspect +------- + +* Add :func:`~inspect.getmembers_static` to return all members without + triggering dynamic lookup via the descriptor protocol. (Contributed by + Weipeng Hong in :issue:`30533`.) + +* Add :func:`~inspect.ismethodwrapper` + for checking if the type of an object is a :class:`~types.MethodWrapperType`. + (Contributed by Hakan Çelik in :issue:`29418`.) + +* Change the frame-related functions in the :mod:`inspect` module to return new + :class:`~inspect.FrameInfo` and :class:`~inspect.Traceback` class instances + (backwards compatible with the previous :term:`named tuple`-like interfaces) + that includes the extended :pep:`657` position information (end + line number, column and end column). The affected functions are: + + * :func:`inspect.getframeinfo` + * :func:`inspect.getouterframes` + * :func:`inspect.getinnerframes`, + * :func:`inspect.stack` + * :func:`inspect.trace` + + (Contributed by Pablo Galindo in :gh:`88116`.) + + +.. _whatsnew311-locale: + +locale +------ + +* Add :func:`locale.getencoding` to get the current locale encoding. It is similar to + ``locale.getpreferredencoding(False)`` but ignores the + :ref:`Python UTF-8 Mode `. + + +.. _whatsnew311-logging: + +logging +------- + +* Added :func:`~logging.getLevelNamesMapping` + to return a mapping from logging level names (e.g. ``'CRITICAL'``) + to the values of their corresponding :ref:`levels` (e.g. ``50``, by default). + (Contributed by Andrei Kulakovin in :gh:`88024`.) + +* Added a :meth:`~logging.handlers.SysLogHandler.createSocket` method + to :class:`~logging.handlers.SysLogHandler`, to match + :meth:`SocketHandler.createSocket() + `. + It is called automatically during handler initialization + and when emitting an event, if there is no active socket. + (Contributed by Kirill Pinchuk in :gh:`88457`.) + + +.. _whatsnew311-math: + math ---- +* Add :func:`math.exp2`: return 2 raised to the power of x. + (Contributed by Gideon Mitchell in :issue:`45917`.) + * Add :func:`math.cbrt`: return the cube root of x. (Contributed by Ajith Ramachandran in :issue:`44357`.) @@ -213,6 +880,11 @@ math ``inf``. Previously they raised :exc:`ValueError`. (Contributed by Mark Dickinson in :issue:`44339`.) +* The :data:`math.nan` value is now always available. + (Contributed by Victor Stinner in :issue:`46917`.) + + +.. _whatsnew311-operator: operator -------- @@ -222,6 +894,8 @@ operator (Contributed by Antony Lee in :issue:`44019`.) +.. _whatsnew311-os: + os -- @@ -230,6 +904,52 @@ os (Contributed by Dong-hee Na in :issue:`44611`.) +.. _whatsnew311-pathlib: + +pathlib +------- + +* :meth:`~pathlib.Path.glob` and :meth:`~pathlib.Path.rglob` return only + directories if *pattern* ends with a pathname components separator: + :data:`~os.sep` or :data:`~os.altsep`. + (Contributed by Eisuke Kawasima in :issue:`22276` and :issue:`33392`.) + + +.. _whatsnew311-re: + +re +-- + +* Atomic grouping (``(?>...)``) and possessive quantifiers (``*+``, ``++``, + ``?+``, ``{m,n}+``) are now supported in regular expressions. + (Contributed by Jeffrey C. Jacobs and Serhiy Storchaka in :issue:`433030`.) + + +.. _whatsnew311-shutil: + +shutil +------ + +* Add optional parameter *dir_fd* in :func:`shutil.rmtree`. + (Contributed by Serhiy Storchaka in :issue:`46245`.) + + +.. _whatsnew311-socket: + +socket +------ + +* Add CAN Socket support for NetBSD. + (Contributed by Thomas Klausner in :issue:`30512`.) + +* :meth:`~socket.create_connection` has an option to raise, in case of + failure to connect, an :exc:`ExceptionGroup` containing all errors + instead of only raising the last error. + (Contributed by Irit Katriel in :issue:`29980`.) + + +.. _whatsnew311-sqlite3: + sqlite3 ------- @@ -248,7 +968,6 @@ sqlite3 (Contributed by Aviv Palivoda, Daniel Shahaf, and Erlend E. Aasland in :issue:`16379` and :issue:`24139`.) - * Add :meth:`~sqlite3.Connection.setlimit` and :meth:`~sqlite3.Connection.getlimit` to :class:`sqlite3.Connection` for setting and getting SQLite limits by connection basis. @@ -258,6 +977,94 @@ sqlite3 threading mode the underlying SQLite library has been compiled with. (Contributed by Erlend E. Aasland in :issue:`45613`.) +* :mod:`sqlite3` C callbacks now use unraisable exceptions if callback + tracebacks are enabled. Users can now register an + :func:`unraisable hook handler ` to improve their debug + experience. + (Contributed by Erlend E. Aasland in :issue:`45828`.) + +* Fetch across rollback no longer raises :exc:`~sqlite3.InterfaceError`. + Instead we leave it to the SQLite library to handle these cases. + (Contributed by Erlend E. Aasland in :issue:`44092`.) + +* Add :meth:`~sqlite3.Connection.serialize` and + :meth:`~sqlite3.Connection.deserialize` to :class:`sqlite3.Connection` for + serializing and deserializing databases. + (Contributed by Erlend E. Aasland in :issue:`41930`.) + +* Add :meth:`~sqlite3.Connection.create_window_function` to + :class:`sqlite3.Connection` for creating aggregate window functions. + (Contributed by Erlend E. Aasland in :issue:`34916`.) + +* Add :meth:`~sqlite3.Connection.blobopen` to :class:`sqlite3.Connection`. + :class:`sqlite3.Blob` allows incremental I/O operations on blobs. + (Contributed by Aviv Palivoda and Erlend E. Aasland in :issue:`24905`.) + + +.. _whatsnew311-string: + +string +------ + +* Add :meth:`~string.Template.get_identifiers` + and :meth:`~string.Template.is_valid` to :class:`string.Template`, + which respectively return all valid placeholders, + and whether any invalid placeholders are present. + (Contributed by Ben Kehoe in :gh:`90465`.) + + +.. _whatsnew311-sys: + +sys +--- + +* :func:`sys.exc_info` now derives the ``type`` and ``traceback`` fields + from the ``value`` (the exception instance), so when an exception is + modified while it is being handled, the changes are reflected in + the results of subsequent calls to :func:`!exc_info`. + (Contributed by Irit Katriel in :issue:`45711`.) + +* Add :func:`sys.exception` which returns the active exception instance + (equivalent to ``sys.exc_info()[1]``). + (Contributed by Irit Katriel in :issue:`46328`.) + +* Add the :data:`sys.flags.safe_path ` flag. + (Contributed by Victor Stinner in :gh:`57684`.) + + +.. _whatsnew311-sysconfig: + +sysconfig +--------- + +* Three new :ref:`installation schemes ` + (*posix_venv*, *nt_venv* and *venv*) were added and are used when Python + creates new virtual environments or when it is running from a virtual + environment. + The first two schemes (*posix_venv* and *nt_venv*) are OS-specific + for non-Windows and Windows, the *venv* is essentially an alias to one of + them according to the OS Python runs on. + This is useful for downstream distributors who modify + :func:`sysconfig.get_preferred_scheme`. + Third party code that creates new virtual environments should use the new + *venv* installation scheme to determine the paths, as does :mod:`venv`. + (Contributed by Miro HronÄok in :issue:`45413`.) + + +.. _whatsnew311-tempfile: + +tempfile +-------- + +* :class:`~tempfile.SpooledTemporaryFile` objects now fully implement the methods + of :class:`io.BufferedIOBase` or :class:`io.TextIOBase` + (depending on file mode). + This lets them work correctly with APIs that expect file-like objects, + such as compression modules. + (Contributed by Carey Metcalfe in :gh:`70363`.) + + +.. _whatsnew311-threading: threading --------- @@ -270,6 +1077,8 @@ threading (Contributed by Victor Stinner in :issue:`41710`.) +.. _whatsnew311-time: + time ---- @@ -287,81 +1096,735 @@ time (Contributed by Benjamin SzÅ‘ke, Dong-hee Na, Eryk Sun and Victor Stinner in :issue:`21302` and :issue:`45429`.) +.. _whatsnew311-tkinter: + +tkinter +------- + +* Added method ``info_patchlevel()`` which returns the exact version of + the Tcl library as a named tuple similar to :data:`sys.version_info`. + (Contributed by Serhiy Storchaka in :gh:`91827`.) + + +.. _whatsnew311-traceback: + +traceback +--------- + +* Add :func:`traceback.StackSummary.format_frame_summary` to allow users + to override which frames appear in the traceback, and how they are + formatted. + (Contributed by Ammar Askar in :issue:`44569`.) + +* Add :func:`traceback.TracebackException.print`, which prints the + formatted :exc:`~traceback.TracebackException` instance to a file. + (Contributed by Irit Katriel in :issue:`33809`.) + + +.. _whatsnew311-typing: + +typing +------ + +For major changes, see :ref:`new-feat-related-type-hints-311`. + +* Add :func:`typing.assert_never` and :class:`typing.Never`. + :func:`typing.assert_never` is useful for asking a type checker to confirm + that a line of code is not reachable. At runtime, it raises an + :exc:`AssertionError`. + (Contributed by Jelle Zijlstra in :gh:`90633`.) + +* Add :func:`typing.reveal_type`. This is useful for asking a type checker + what type it has inferred for a given expression. At runtime it prints + the type of the received value. + (Contributed by Jelle Zijlstra in :gh:`90572`.) + +* Add :func:`typing.assert_type`. This is useful for asking a type checker + to confirm that the type it has inferred for a given expression matches + the given type. At runtime it simply returns the received value. + (Contributed by Jelle Zijlstra in :gh:`90638`.) + +* :data:`typing.TypedDict` types can now be generic. (Contributed by + Samodya Abeysiriwardane in :gh:`89026`.) + +* :class:`~typing.NamedTuple` types can now be generic. + (Contributed by Serhiy Storchaka in :issue:`43923`.) + +* Allow subclassing of :class:`typing.Any`. This is useful for avoiding + type checker errors related to highly dynamic class, such as mocks. + (Contributed by Shantanu Jain in :gh:`91154`.) + +* The :func:`typing.final` decorator now sets the ``__final__`` attributed on + the decorated object. + (Contributed by Jelle Zijlstra in :gh:`90500`.) + +* The :func:`typing.get_overloads` function can be used for introspecting + the overloads of a function. :func:`typing.clear_overloads` can be used + to clear all registered overloads of a function. + (Contributed by Jelle Zijlstra in :gh:`89263`.) + +* The :meth:`~object.__init__` method of :class:`~typing.Protocol` subclasses + is now preserved. (Contributed by Adrian Garcia Badarasco in :gh:`88970`.) + +* The representation of empty tuple types (``Tuple[()]``) is simplified. + This affects introspection, e.g. ``get_args(Tuple[()])`` now evaluates + to ``()`` instead of ``((),)``. + (Contributed by Serhiy Storchaka in :gh:`91137`.) + +* Loosen runtime requirements for type annotations by removing the callable + check in the private ``typing._type_check`` function. (Contributed by + Gregory Beauregard in :gh:`90802`.) + +* :func:`typing.get_type_hints` now supports evaluating strings as forward + references in :ref:`PEP 585 generic aliases `. + (Contributed by Niklas Rosenstein in :gh:`85542`.) + +* :func:`typing.get_type_hints` no longer adds :data:`~typing.Optional` + to parameters with ``None`` as a default. (Contributed by Nikita Sobolev + in :gh:`90353`.) + +* :func:`typing.get_type_hints` now supports evaluating bare stringified + :data:`~typing.ClassVar` annotations. (Contributed by Gregory Beauregard + in :gh:`90711`.) + +* :func:`typing.no_type_check` no longer modifies external classes and functions. + It also now correctly marks classmethods as not to be type checked. (Contributed + by Nikita Sobolev in :gh:`90729`.) + + +.. _whatsnew311-unicodedata: + unicodedata ----------- -* The Unicode database has been updated to version 14.0.0. (:issue:`45190`). +* The Unicode database has been updated to version 14.0.0. + (Contributed by Benjamin Peterson in :issue:`45190`). +.. _whatsnew311-unittest: + +unittest +-------- + +* Added methods :meth:`~unittest.TestCase.enterContext` and + :meth:`~unittest.TestCase.enterClassContext` of class + :class:`~unittest.TestCase`, method + :meth:`~unittest.IsolatedAsyncioTestCase.enterAsyncContext` of + class :class:`~unittest.IsolatedAsyncioTestCase` and function + :func:`unittest.enterModuleContext`. + (Contributed by Serhiy Storchaka in :issue:`45046`.) + + +.. _whatsnew311-venv: + +venv +---- + +* When new Python virtual environments are created, the *venv* + :ref:`sysconfig installation scheme ` is used + to determine the paths inside the environment. + When Python runs in a virtual environment, the same installation scheme + is the default. + That means that downstream distributors can change the default sysconfig install + scheme without changing behavior of virtual environments. + Third party code that also creates new virtual environments should do the same. + (Contributed by Miro HronÄok in :issue:`45413`.) + + +.. _whatsnew311-warnings: + +warnings +-------- + +* :func:`warnings.catch_warnings` now accepts arguments for :func:`warnings.simplefilter`, + providing a more concise way to locally ignore warnings or convert them to errors. + (Contributed by Zac Hatfield-Dodds in :issue:`47074`.) + + +.. _whatsnew311-zipfile: + +zipfile +------- + +* Added support for specifying member name encoding for reading metadata + in a :class:`~zipfile.ZipFile`'s directory and file headers. + (Contributed by Stephen J. Turnbull and Serhiy Storchaka in :issue:`28080`.) + +* Added :meth:`ZipFile.mkdir() ` + for creating new directories inside ZIP archives. + (Contributed by Sam Ezeh in :gh:`49083`.) + +* Added :attr:`~zipfile.Path.stem`, :attr:`~zipfile.Path.suffix` + and :attr:`~zipfile.Path.suffixes` to :class:`zipfile.Path`. + (Contributed by Miguel Brito in :gh:`88261`.) + + +.. _whatsnew311-optimizations: + Optimizations ============= -* Compiler now optimizes simple C-style formatting with literal format - containing only format codes ``%s``, ``%r`` and ``%a`` and makes it as - fast as corresponding f-string expression. +This section covers specific optimizations independent of the +:ref:`whatsnew311-faster-cpython` project, which is covered in its own section. + +* The compiler now optimizes simple + :ref:`printf-style % formatting ` on string literals + containing only the format codes ``%s``, ``%r`` and ``%a`` and makes it as + fast as a corresponding :term:`f-string` expression. (Contributed by Serhiy Storchaka in :issue:`28307`.) -* "Zero-cost" exceptions are implemented. The cost of ``try`` statements is - almost eliminated when no exception is raised. - (Contributed by Mark Shannon in :issue:`40222`.) +* Integer division (``//``) is better tuned for optimization by compilers. + It is now around 20% faster on x86-64 when dividing an :class:`int` + by a value smaller than ``2**30``. + (Contributed by Gregory P. Smith and Tim Peters in :gh:`90564`.) -* Method calls with keywords are now faster due to bytecode - changes which avoid creating bound method instances. Previously, this - optimization was applied only to method calls with purely positional - arguments. - (Contributed by Ken Jin and Mark Shannon in :issue:`26110`, based on ideas - implemented in PyPy.) +* :func:`sum` is now nearly 30% faster for integers smaller than ``2**30``. + (Contributed by Stefan Behnel in :gh:`68264`.) -* Pure ASCII strings are now normalized in constant time by :func:`unicodedata.normalize`. +* Resizing lists is streamlined for the common case, + speeding up :meth:`list.append` by ≈15% + and simple :term:`list comprehension`\s by up to 20-30% + (Contributed by Dennis Sweeney in :gh:`91165`.) + +* Dictionaries don't store hash values when all keys are Unicode objects, + decreasing :class:`dict` size. + For example, ``sys.getsizeof(dict.fromkeys("abcdefg"))`` + is reduced from 352 bytes to 272 bytes (23% smaller) on 64-bit platforms. + (Contributed by Inada Naoki in :issue:`46845`.) + +* Using :class:`asyncio.DatagramProtocol` is now orders of magnitude faster + when transferring large files over UDP, + with speeds over 100 times higher for a ≈60 MiB file. + (Contributed by msoxzw in :gh:`91487`.) + +* :mod:`math` functions :func:`~math.comb` and :func:`~math.perm` are now + ≈10 times faster for large arguments (with a larger speedup for larger *k*). + (Contributed by Serhiy Storchaka in :issue:`37295`.) + +* The :mod:`statistics` functions :func:`~statistics.mean`, + :func:`~statistics.variance` and :func:`~statistics.stdev` now consume + iterators in one pass rather than converting them to a :class:`list` first. + This is twice as fast and can save substantial memory. + (Contributed by Raymond Hettinger in :gh:`90415`.) + +* :func:`unicodedata.normalize` + now normalizes pure-ASCII strings in constant time. (Contributed by Dong-hee Na in :issue:`44987`.) +.. _whatsnew311-faster-cpython: + +Faster CPython +============== + +CPython 3.11 is on average `25% faster `_ +than CPython 3.10 when measured with the +`pyperformance `_ benchmark suite, +and compiled with GCC on Ubuntu Linux. Depending on your workload, the speedup +could be up to 10-60% faster. + +This project focuses on two major areas in Python: faster startup and faster +runtime. Other optimizations not under this project are listed in `Optimizations`_. + + +.. _whatsnew311-faster-startup: + +Faster Startup +-------------- + +.. _whatsnew311-faster-imports: + +Frozen imports / Static code objects +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Python caches bytecode in the :ref:`__pycache__` directory to +speed up module loading. + +Previously in 3.10, Python module execution looked like this: + +.. code-block:: text + + Read __pycache__ -> Unmarshal -> Heap allocated code object -> Evaluate + +In Python 3.11, the core modules essential for Python startup are "frozen". +This means that their code objects (and bytecode) are statically allocated +by the interpreter. This reduces the steps in module execution process to this: + +.. code-block:: text + + Statically allocated code object -> Evaluate + +Interpreter startup is now 10-15% faster in Python 3.11. This has a big +impact for short-running programs using Python. + +(Contributed by Eric Snow, Guido van Rossum and Kumar Aditya in numerous issues.) + + +.. _whatsnew311-faster-runtime: + +Faster Runtime +-------------- + +.. _whatsnew311-lazy-python-frames: + +Cheaper, lazy Python frames +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Python frames are created whenever Python calls a Python function. This frame +holds execution information. The following are new frame optimizations: + +- Streamlined the frame creation process. +- Avoided memory allocation by generously re-using frame space on the C stack. +- Streamlined the internal frame struct to contain only essential information. + Frames previously held extra debugging and memory management information. + +Old-style frame objects are now created only when requested by debuggers or +by Python introspection functions such as ``sys._getframe`` or +``inspect.currentframe``. For most user code, no frame objects are +created at all. As a result, nearly all Python functions calls have sped +up significantly. We measured a 3-7% speedup in pyperformance. + +(Contributed by Mark Shannon in :issue:`44590`.) + + +.. _inline-calls: +.. _whatsnew311-inline-calls: + +Inlined Python function calls +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +During a Python function call, Python will call an evaluating C function to +interpret that function's code. This effectively limits pure Python recursion to +what's safe for the C stack. + +In 3.11, when CPython detects Python code calling another Python function, +it sets up a new frame, and "jumps" to the new code inside the new frame. This +avoids calling the C interpreting function altogether. + +Most Python function calls now consume no C stack space. This speeds up +most of such calls. In simple recursive functions like fibonacci or +factorial, a 1.7x speedup was observed. This also means recursive functions +can recurse significantly deeper (if the user increases the recursion limit). +We measured a 1-3% improvement in pyperformance. + +(Contributed by Pablo Galindo and Mark Shannon in :issue:`45256`.) + + +.. _whatsnew311-pep659: + +PEP 659: Specializing Adaptive Interpreter +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:pep:`659` is one of the key parts of the faster CPython project. The general +idea is that while Python is a dynamic language, most code has regions where +objects and types rarely change. This concept is known as *type stability*. + +At runtime, Python will try to look for common patterns and type stability +in the executing code. Python will then replace the current operation with a +more specialized one. This specialized operation uses fast paths available only +to those use cases/types, which generally outperform their generic +counterparts. This also brings in another concept called *inline caching*, where +Python caches the results of expensive operations directly in the bytecode. + +The specializer will also combine certain common instruction pairs into one +superinstruction. This reduces the overhead during execution. + +Python will only specialize +when it sees code that is "hot" (executed multiple times). This prevents Python +from wasting time for run-once code. Python can also de-specialize when code is +too dynamic or when the use changes. Specialization is attempted periodically, +and specialization attempts are not too expensive. This allows specialization +to adapt to new circumstances. + +(PEP written by Mark Shannon, with ideas inspired by Stefan Brunthaler. +See :pep:`659` for more information. Implementation by Mark Shannon and Brandt +Bucher, with additional help from Irit Katriel and Dennis Sweeney.) + +.. + If I missed out anyone, please add them. + ++---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ +| Operation | Form | Specialization | Operation speedup | Contributor(s) | +| | | | (up to) | | ++===============+====================+=======================================================+===================+===================+ +| Binary | ``x+x; x*x; x-x;`` | Binary add, multiply and subtract for common types | 10% | Mark Shannon, | +| operations | | such as ``int``, ``float``, and ``str`` take custom | | Dong-hee Na, | +| | | fast paths for their underlying types. | | Brandt Bucher, | +| | | | | Dennis Sweeney | ++---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ +| Subscript | ``a[i]`` | Subscripting container types such as ``list``, | 10-25% | Irit Katriel, | +| | | ``tuple`` and ``dict`` directly index the underlying | | Mark Shannon | +| | | data structures. | | | +| | | | | | +| | | Subscripting custom ``__getitem__`` | | | +| | | is also inlined similar to :ref:`inline-calls`. | | | ++---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ +| Store | ``a[i] = z`` | Similar to subscripting specialization above. | 10-25% | Dennis Sweeney | +| subscript | | | | | ++---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ +| Calls | ``f(arg)`` | Calls to common builtin (C) functions and types such | 20% | Mark Shannon, | +| | ``C(arg)`` | as ``len`` and ``str`` directly call their underlying | | Ken Jin | +| | | C version. This avoids going through the internal | | | +| | | calling convention. | | | +| | | | | | ++---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ +| Load | ``print`` | The object's index in the globals/builtins namespace | [1]_ | Mark Shannon | +| global | ``len`` | is cached. Loading globals and builtins require | | | +| variable | | zero namespace lookups. | | | ++---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ +| Load | ``o.attr`` | Similar to loading global variables. The attribute's | [2]_ | Mark Shannon | +| attribute | | index inside the class/object's namespace is cached. | | | +| | | In most cases, attribute loading will require zero | | | +| | | namespace lookups. | | | ++---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ +| Load | ``o.meth()`` | The actual address of the method is cached. Method | 10-20% | Ken Jin, | +| methods for | | loading now has no namespace lookups -- even for | | Mark Shannon | +| call | | classes with long inheritance chains. | | | ++---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ +| Store | ``o.attr = z`` | Similar to load attribute optimization. | 2% | Mark Shannon | +| attribute | | | in pyperformance | | ++---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ +| Unpack | ``*seq`` | Specialized for common containers such as ``list`` | 8% | Brandt Bucher | +| Sequence | | and ``tuple``. Avoids internal calling convention. | | | ++---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ + +.. [1] A similar optimization already existed since Python 3.8. 3.11 + specializes for more forms and reduces some overhead. + +.. [2] A similar optimization already existed since Python 3.10. + 3.11 specializes for more forms. Furthermore, all attribute loads should + be sped up by :issue:`45947`. + + +.. _whatsnew311-faster-cpython-misc: + +Misc +---- + +* Objects now require less memory due to lazily created object namespaces. Their + namespace dictionaries now also share keys more freely. + (Contributed Mark Shannon in :issue:`45340` and :issue:`40116`.) + +* A more concise representation of exceptions in the interpreter reduced the + time required for catching an exception by about 10%. + (Contributed by Irit Katriel in :issue:`45711`.) + + +.. _whatsnew311-faster-cpython-faq: + +FAQ +--- + +| Q: How should I write my code to utilize these speedups? +| +| A: You don't have to change your code. Write Pythonic code that follows common + best practices. The Faster CPython project optimizes for common code + patterns we observe. +| +| +| Q: Will CPython 3.11 use more memory? +| +| A: Maybe not. We don't expect memory use to exceed 20% more than 3.10. + This is offset by memory optimizations for frame objects and object + dictionaries as mentioned above. +| +| +| Q: I don't see any speedups in my workload. Why? +| +| A: Certain code won't have noticeable benefits. If your code spends most of + its time on I/O operations, or already does most of its + computation in a C extension library like numpy, there won't be significant + speedup. This project currently benefits pure-Python workloads the most. +| +| Furthermore, the pyperformance figures are a geometric mean. Even within the + pyperformance benchmarks, certain benchmarks have slowed down slightly, while + others have sped up by nearly 2x! +| +| +| Q: Is there a JIT compiler? +| +| A: No. We're still exploring other optimizations. + + +.. _whatsnew311-faster-cpython-about: + +About +----- + +Faster CPython explores optimizations for :term:`CPython`. The main team is +funded by Microsoft to work on this full-time. Pablo Galindo Salgado is also +funded by Bloomberg LP to work on the project part-time. Finally, many +contributors are volunteers from the community. + + +.. _whatsnew311-bytecode-changes: + CPython bytecode changes ======================== -* Replaced all numeric ``BINARY_*`` and ``INPLACE_*`` instructions with a single - :opcode:`BINARY_OP` implementation. +The bytecode now contains inline cache entries, +which take the form of the newly-added :opcode:`CACHE` instructions. +Many opcodes expect to be followed by an exact number of caches, +and instruct the interpreter to skip over them at runtime. +Populated caches can look like arbitrary instructions, +so great care should be taken when reading or modifying +raw, adaptive bytecode containing quickened data. -* Added a new :opcode:`CALL_METHOD_KW` opcode. Calls a method in a similar - fashion as :opcode:`CALL_METHOD`, but also supports keyword arguments. Works - in tandem with :opcode:`LOAD_METHOD`. -* Removed ``COPY_DICT_WITHOUT_KEYS``. +.. _whatsnew311-added-opcodes: -* :opcode:`MATCH_CLASS` and :opcode:`MATCH_KEYS` no longer push an additional - boolean value indicating whether the match succeeded or failed. Instead, they - indicate failure with :const:`None` (where a tuple of extracted values would - otherwise be). +New opcodes +----------- -* Added :opcode:`COPY`, which pushes the *i*-th item to the top of the stack. - The item is not removed from its original location. +* :opcode:`ASYNC_GEN_WRAP`, :opcode:`RETURN_GENERATOR` and :opcode:`SEND`, + used in generators and co-routines. -* :opcode:`JUMP_IF_NOT_EXC_MATCH` no longer pops the active exception. +* :opcode:`COPY_FREE_VARS`, + which avoids needing special caller-side code for closures. +* :opcode:`JUMP_BACKWARD_NO_INTERRUPT`, + for use in certain loops where handling interrupts is undesirable. + +* :opcode:`MAKE_CELL`, to create :ref:`cell-objects`. + +* :opcode:`CHECK_EG_MATCH` and :opcode:`PREP_RERAISE_STAR`, + to handle the :ref:`new exception groups and except* ` + added in :pep:`654`. + +* :opcode:`PUSH_EXC_INFO`, for use in exception handlers. + +* :opcode:`RESUME`, a no-op, + for internal tracing, debugging and optimization checks. + + +.. _whatsnew311-replaced-opcodes: + +Replaced opcodes +---------------- + ++------------------------------------+-----------------------------------+-----------------------------------------+ +| Replaced Opcode(s) | New Opcode(s) | Notes | ++====================================+===================================+=========================================+ +| | :opcode:`!BINARY_*` | :opcode:`BINARY_OP` | Replaced all numeric binary/in-place | +| | :opcode:`!INPLACE_*` | | opcodes with a single opcode | ++------------------------------------+-----------------------------------+-----------------------------------------+ +| | :opcode:`!CALL_FUNCTION` | | :opcode:`CALL` | Decouples argument shifting for methods | +| | :opcode:`!CALL_FUNCTION_KW` | | :opcode:`KW_NAMES` | from handling of keyword arguments; | +| | :opcode:`!CALL_METHOD` | | :opcode:`PRECALL` | allows better specialization of calls | +| | | :opcode:`PUSH_NULL` | | ++------------------------------------+-----------------------------------+-----------------------------------------+ +| | :opcode:`!DUP_TOP` | | :opcode:`COPY` | Stack manipulation instructions | +| | :opcode:`!DUP_TOP_TWO` | | :opcode:`SWAP` | | +| | :opcode:`!ROT_TWO` | | | +| | :opcode:`!ROT_THREE` | | | +| | :opcode:`!ROT_FOUR` | | | +| | :opcode:`!ROT_N` | | | ++------------------------------------+-----------------------------------+-----------------------------------------+ +| | :opcode:`!JUMP_IF_NOT_EXC_MATCH` | | :opcode:`CHECK_EXC_MATCH` | Now performs check but doesn't jump | ++------------------------------------+-----------------------------------+-----------------------------------------+ +| | :opcode:`!JUMP_ABSOLUTE` | | :opcode:`JUMP_BACKWARD` | See [#bytecode-jump]_; | +| | :opcode:`!POP_JUMP_IF_FALSE` | | :opcode:`POP_JUMP_BACKWARD_IF_* | ``TRUE``, ``FALSE``, | +| | :opcode:`!POP_JUMP_IF_TRUE` | ` | ``NONE`` and ``NOT_NONE`` variants | +| | | :opcode:`POP_JUMP_FORWARD_IF_* | for each direction | +| | ` | | ++------------------------------------+-----------------------------------+-----------------------------------------+ +| | :opcode:`!SETUP_WITH` | :opcode:`BEFORE_WITH` | :keyword:`with` block setup | +| | :opcode:`!SETUP_ASYNC_WITH` | | | ++------------------------------------+-----------------------------------+-----------------------------------------+ + +.. [#bytecode-jump] All jump opcodes are now relative, including the + existing :opcode:`JUMP_IF_TRUE_OR_POP` and :opcode:`JUMP_IF_FALSE_OR_POP`. + The argument is now an offset from the current instruction + rather than an absolute location. + + +.. _whatsnew311-changed-opcodes: +.. _whatsnew311-removed-opcodes: +.. _whatsnew311-changed-removed-opcodes: + +Changed/removed opcodes +----------------------- + +* Changed :opcode:`MATCH_CLASS` and :opcode:`MATCH_KEYS` + to no longer push an additional boolean value to indicate success/failure. + Instead, ``None`` is pushed on failure + in place of the tuple of extracted values. + +* Changed opcodes that work with exceptions to reflect them + now being represented as one item on the stack instead of three + (see :gh:`89874`). + +* Removed :opcode:`!COPY_DICT_WITHOUT_KEYS`, :opcode:`!GEN_START`, + :opcode:`!POP_BLOCK`, :opcode:`!SETUP_FINALLY` and :opcode:`!YIELD_FROM`. + + +.. _whatsnew311-deprecated: +.. _whatsnew311-python-api-deprecated: Deprecated ========== -* The :mod:`lib2to3` package and ``2to3`` tool are now deprecated and may not - be able to parse Python 3.10 or newer. See the :pep:`617` (New PEG parser for - CPython). (Contributed by Victor Stinner in :issue:`40360`.) +This section lists Python APIs that have been deprecated in Python 3.11. -* :class:`webbrowser.MacOSX` is deprecated and will be removed in Python 3.13. - It is untested and undocumented and also not used by webbrowser itself. +Deprecated C APIs are :ref:`listed separately `. + + +.. _whatsnew311-deprecated-language: +.. _whatsnew311-deprecated-builtins: + +Language/Builtins +----------------- + +* Chaining :class:`classmethod` descriptors (introduced in :issue:`19072`) + is now deprecated. It can no longer be used to wrap other descriptors + such as :class:`property`. The core design of this feature was flawed + and caused a number of downstream problems. To "pass-through" a + :class:`classmethod`, consider using the :attr:`!__wrapped__` attribute + that was added in Python 3.10. + (Contributed by Raymond Hettinger in :gh:`89519`.) + +* Octal escapes in string and bytes literals with values larger than ``0o377`` + (255 in decimal) now produce a :exc:`DeprecationWarning`. + In a future Python version, they will raise a :exc:`SyntaxWarning` and + eventually a :exc:`SyntaxError`. + (Contributed by Serhiy Storchaka in :gh:`81548`.) + +* The delegation of :func:`int` to :meth:`~object.__trunc__` is now deprecated. + Calling ``int(a)`` when ``type(a)`` implements :meth:`!__trunc__` but not + :meth:`~object.__int__` or :meth:`~object.__index__` now raises + a :exc:`DeprecationWarning`. + (Contributed by Zackery Spytz in :issue:`44977`.) + + +.. _whatsnew311-deprecated-modules: + +Modules +------- + +.. _whatsnew311-pep594: + +* :pep:`594` led to the deprecations of the following modules + slated for removal in Python 3.13: + + +---------------------+---------------------+---------------------+---------------------+---------------------+ + | :mod:`aifc` | :mod:`chunk` | :mod:`msilib` | :mod:`pipes` | :mod:`telnetlib` | + +---------------------+---------------------+---------------------+---------------------+---------------------+ + | :mod:`audioop` | :mod:`crypt` | :mod:`nis` | :mod:`sndhdr` | :mod:`uu` | + +---------------------+---------------------+---------------------+---------------------+---------------------+ + | :mod:`cgi` | :mod:`imghdr` | :mod:`nntplib` | :mod:`spwd` | :mod:`xdrlib` | + +---------------------+---------------------+---------------------+---------------------+---------------------+ + | :mod:`cgitb` | :mod:`mailcap` | :mod:`ossaudiodev` | :mod:`sunau` | | + +---------------------+---------------------+---------------------+---------------------+---------------------+ + + (Contributed by Brett Cannon in :issue:`47061` and Victor Stinner in + :gh:`68966`.) + +* The :mod:`asynchat`, :mod:`asyncore` and :mod:`smtpd` modules have been + deprecated since at least Python 3.6. Their documentation and deprecation + warnings have now been updated to note they will be removed in Python 3.12. + (Contributed by Hugo van Kemenade in :issue:`47022`.) + +* The :mod:`lib2to3` package and :ref:`2to3 <2to3-reference>` tool + are now deprecated and may not be able to parse Python 3.10 or newer. + See :pep:`617`, introducing the new PEG parser, for details. + (Contributed by Victor Stinner in :issue:`40360`.) + +* Undocumented modules :mod:`!sre_compile`, :mod:`!sre_constants` + and :mod:`!sre_parse` are now deprecated. + (Contributed by Serhiy Storchaka in :issue:`47152`.) + + +.. _whatsnew311-deprecated-stdlib: + +Standard Library +---------------- + +* The following have been deprecated in :mod:`configparser` since Python 3.2. + Their deprecation warnings have now been updated to note they will be removed + in Python 3.12: + + * the :class:`!configparser.SafeConfigParser` class + * the :attr:`!configparser.ParsingError.filename` property + * the :meth:`configparser.RawConfigParser.readfp` method + + (Contributed by Hugo van Kemenade in :issue:`45173`.) + +* :class:`!configparser.LegacyInterpolation` has been deprecated in the docstring + since Python 3.2, and is not listed in the :mod:`configparser` documentation. + It now emits a :exc:`DeprecationWarning` and will be removed + in Python 3.13. Use :class:`configparser.BasicInterpolation` or + :class:`configparser.ExtendedInterpolation` instead. + (Contributed by Hugo van Kemenade in :issue:`46607`.) + +* The older set of :mod:`importlib.resources` functions were deprecated + in favor of the replacements added in Python 3.9 + and will be removed in a future Python version, + due to not supporting resources located within package subdirectories: + + * :func:`importlib.resources.contents` + * :func:`importlib.resources.is_resource` + * :func:`importlib.resources.open_binary` + * :func:`importlib.resources.open_text` + * :func:`importlib.resources.read_binary` + * :func:`importlib.resources.read_text` + * :func:`importlib.resources.path` + +* The :func:`locale.getdefaultlocale` function is deprecated and will be + removed in Python 3.13. Use :func:`locale.setlocale`, + :func:`locale.getpreferredencoding(False) ` and + :func:`locale.getlocale` functions instead. + (Contributed by Victor Stinner in :gh:`90817`.) + +* The :func:`locale.resetlocale` function is deprecated and will be + removed in Python 3.13. Use ``locale.setlocale(locale.LC_ALL, "")`` instead. + (Contributed by Victor Stinner in :gh:`90817`.) + +* Stricter rules will now be applied for numerical group references + and group names in :ref:`regular expressions `. + Only sequences of ASCII digits will now be accepted as a numerical reference, + and the group name in :class:`bytes` patterns and replacement strings + can only contain ASCII letters, digits and underscores. + For now, a deprecation warning is raised for syntax violating these rules. + (Contributed by Serhiy Storchaka in :gh:`91760`.) + +* In the :mod:`re` module, the :func:`!re.template` function + and the corresponding :data:`!re.TEMPLATE` and :data:`!re.T` flags + are deprecated, as they were undocumented and lacked an obvious purpose. + They will be removed in Python 3.13. + (Contributed by Serhiy Storchaka and Miro HronÄok in :gh:`92728`.) + +* :func:`turtle.settiltangle` has been deprecated since Python 3.1; + it now emits a deprecation warning and will be removed in Python 3.13. Use + :func:`turtle.tiltangle` instead (it was earlier incorrectly marked + as deprecated, and its docstring is now corrected). + (Contributed by Hugo van Kemenade in :issue:`45837`.) + +* :class:`typing.Text`, which exists solely to provide compatibility support + between Python 2 and Python 3 code, is now deprecated. Its removal is + currently unplanned, but users are encouraged to use :class:`str` instead + wherever possible. + (Contributed by Alex Waygood in :gh:`92332`.) + +* The keyword argument syntax for constructing :data:`typing.TypedDict` types + is now deprecated. Support will be removed in Python 3.13. (Contributed by + Jingchen Ye in :gh:`90224`.) + +* :class:`!webbrowser.MacOSX` is deprecated and will be removed in Python 3.13. + It is untested, undocumented, and not used by :mod:`webbrowser` itself. (Contributed by Dong-hee Na in :issue:`42255`.) * The behavior of returning a value from a :class:`~unittest.TestCase` and :class:`~unittest.IsolatedAsyncioTestCase` test methods (other than the - default ``None`` value), is now deprecated. + default ``None`` value) is now deprecated. -* Deprecated the following :mod:`unittest` functions, scheduled for removal in - Python 3.13: +* Deprecated the following not-formally-documented :mod:`unittest` functions, + scheduled for removal in Python 3.13: - * :func:`unittest.findTestCases` - * :func:`unittest.makeSuite` - * :func:`unittest.getTestCaseNames` + * :func:`!unittest.findTestCases` + * :func:`!unittest.makeSuite` + * :func:`!unittest.getTestCaseNames` - Use :class:`~unittest.TestLoader` method instead: + Use :class:`~unittest.TestLoader` methods instead: * :meth:`unittest.TestLoader.loadTestsFromModule` * :meth:`unittest.TestLoader.loadTestsFromTestCase` @@ -369,32 +1832,90 @@ Deprecated (Contributed by Erlend E. Aasland in :issue:`5846`.) -* The :meth:`turtle.RawTurtle.settiltangle` is deprecated since Python 3.1, - it now emits a deprecation warning and will be removed in Python 3.13. Use - :meth:`turtle.RawTurtle.tiltangle` instead (it was earlier incorrectly marked - as deprecated, its docstring is now corrected). - (Contributed by Hugo van Kemenade in :issue:`45837`.) + +.. _whatsnew311-pending-removal: +.. _whatsnew311-python-api-pending-removal: + +Pending Removal in Python 3.12 +============================== + +The following Python APIs have been deprecated in earlier Python releases, +and will be removed in Python 3.12. + +C APIs pending removal are +:ref:`listed separately `. + +* The :mod:`asynchat` module +* The :mod:`asyncore` module +* The :ref:`entire distutils package ` +* The :mod:`imp` module +* The :class:`typing.io ` namespace +* The :class:`typing.re ` namespace +* :func:`!cgi.log` +* :func:`importlib.find_loader` +* :meth:`importlib.abc.Loader.module_repr` +* :meth:`importlib.abc.MetaPathFinder.find_module` +* :meth:`importlib.abc.PathEntryFinder.find_loader` +* :meth:`importlib.abc.PathEntryFinder.find_module` +* :meth:`!importlib.machinery.BuiltinImporter.find_module` +* :meth:`!importlib.machinery.BuiltinLoader.module_repr` +* :meth:`!importlib.machinery.FileFinder.find_loader` +* :meth:`!importlib.machinery.FileFinder.find_module` +* :meth:`!importlib.machinery.FrozenImporter.find_module` +* :meth:`!importlib.machinery.FrozenLoader.module_repr` +* :meth:`importlib.machinery.PathFinder.find_module` +* :meth:`!importlib.machinery.WindowsRegistryFinder.find_module` +* :func:`importlib.util.module_for_loader` +* :func:`!importlib.util.set_loader_wrapper` +* :func:`!importlib.util.set_package_wrapper` +* :class:`pkgutil.ImpImporter` +* :class:`pkgutil.ImpLoader` +* :meth:`pathlib.Path.link_to` +* :func:`!sqlite3.enable_shared_cache` +* :func:`!sqlite3.OptimizedUnicode` +* :envvar:`PYTHONTHREADDEBUG` environment variable +* The following deprecated aliases in :mod:`unittest`: + + ============================ =============================== =============== + Deprecated alias Method Name Deprecated in + ============================ =============================== =============== + ``failUnless`` :meth:`.assertTrue` 3.1 + ``failIf`` :meth:`.assertFalse` 3.1 + ``failUnlessEqual`` :meth:`.assertEqual` 3.1 + ``failIfEqual`` :meth:`.assertNotEqual` 3.1 + ``failUnlessAlmostEqual`` :meth:`.assertAlmostEqual` 3.1 + ``failIfAlmostEqual`` :meth:`.assertNotAlmostEqual` 3.1 + ``failUnlessRaises`` :meth:`.assertRaises` 3.1 + ``assert_`` :meth:`.assertTrue` 3.2 + ``assertEquals`` :meth:`.assertEqual` 3.2 + ``assertNotEquals`` :meth:`.assertNotEqual` 3.2 + ``assertAlmostEquals`` :meth:`.assertAlmostEqual` 3.2 + ``assertNotAlmostEquals`` :meth:`.assertNotAlmostEqual` 3.2 + ``assertRegexpMatches`` :meth:`.assertRegex` 3.2 + ``assertRaisesRegexp`` :meth:`.assertRaisesRegex` 3.2 + ``assertNotRegexpMatches`` :meth:`.assertNotRegex` 3.5 + ============================ =============================== =============== + +.. _whatsnew311-removed: +.. _whatsnew311-python-api-removed: Removed ======= -* :class:`smtpd.MailmanProxy` is now removed as it is unusable without - an external module, ``mailman``. (Contributed by Dong-hee Na in :issue:`35800`.) +This section lists Python APIs that have been removed in Python 3.11. -* The ``binhex`` module, deprecated in Python 3.9, is now removed. - The following :mod:`binascii` functions, deprecated in Python 3.9, are now - also removed: +Removed C APIs are :ref:`listed separately `. - * ``a2b_hqx()``, ``b2a_hqx()``; - * ``rlecode_hqx()``, ``rledecode_hqx()``. +* Removed the :func:`!@asyncio.coroutine` :term:`decorator` + enabling legacy generator-based coroutines to be compatible with + :keyword:`async` / :keyword:`await` code. + The function has been deprecated since Python 3.8 and the removal was + initially scheduled for Python 3.10. Use :keyword:`async def` instead. + (Contributed by Illia Volochii in :issue:`43216`.) - The :func:`binascii.crc_hqx` function remains available. - - (Contributed by Victor Stinner in :issue:`45085`.) - -* The distutils ``bdist_msi`` command, deprecated in Python 3.9, is now removed. - Use ``bdist_wheel`` (wheel packages) instead. - (Contributed by Hugo van Kemenade in :issue:`45124`.) +* Removed :class:`!asyncio.coroutines.CoroWrapper` used for wrapping legacy + generator-based coroutine objects in the debug mode. + (Contributed by Illia Volochii in :issue:`43216`.) * Due to significant security concerns, the *reuse_address* parameter of :meth:`asyncio.loop.create_datagram_endpoint`, disabled in Python 3.9, is @@ -402,162 +1923,252 @@ Removed ``SO_REUSEADDR`` in UDP. (Contributed by Hugo van Kemenade in :issue:`45129`.) -* Removed :meth:`__getitem__` methods of +* Removed the :mod:`!binhex` module, deprecated in Python 3.9. + Also removed the related, similarly-deprecated :mod:`binascii` functions: + + * :func:`!binascii.a2b_hqx` + * :func:`!binascii.b2a_hqx` + * :func:`!binascii.rlecode_hqx` + * :func:`!binascii.rldecode_hqx` + + The :func:`binascii.crc_hqx` function remains available. + + (Contributed by Victor Stinner in :issue:`45085`.) + +* Removed the :mod:`distutils` ``bdist_msi`` command deprecated in Python 3.9. + Use ``bdist_wheel`` (wheel packages) instead. + (Contributed by Hugo van Kemenade in :issue:`45124`.) + +* Removed the :meth:`~object.__getitem__` methods of :class:`xml.dom.pulldom.DOMEventStream`, :class:`wsgiref.util.FileWrapper` and :class:`fileinput.FileInput`, deprecated since Python 3.9. (Contributed by Hugo van Kemenade in :issue:`45132`.) -* Removed many old deprecated :mod:`unittest` features: - - - :class:`~unittest.TestCase` method aliases ``failUnlessEqual``, - ``failIfEqual``, ``failUnless``, ``failIf``, ``failUnlessRaises``, - ``failUnlessAlmostEqual``, ``failIfAlmostEqual`` (deprecated in Python 3.1), - ``assertEquals``, ``assertNotEquals``, ``assert_``, ``assertAlmostEquals``, - ``assertNotAlmostEquals``, ``assertRegexpMatches``, ``assertRaisesRegexp`` - (deprecated in Python 3.2), and ``assertNotRegexpMatches`` (deprecated in - Python 3.5). - - - Undocumented and broken :class:`~unittest.TestCase` method - ``assertDictContainsSubset`` (deprecated in Python 3.2). - - - Undocumented :meth:` - TestLoader.loadTestsFromModule` parameter *use_load_tests* (deprecated - and ignored since Python 3.2). - - - An alias of the :class:`~unittest.TextTestResult` class: - ``_TextTestResult`` (deprecated in Python 3.2). - - (Contributed by Serhiy Storchaka in :issue:`45162`.) - -* The following deprecated functions and methods are removed in the :mod:`gettext` - module: :func:`~gettext.lgettext`, :func:`~gettext.ldgettext`, - :func:`~gettext.lngettext` and :func:`~gettext.ldngettext`. - - Function :func:`~gettext.bind_textdomain_codeset`, methods - :meth:`~gettext.NullTranslations.output_charset` and - :meth:`~gettext.NullTranslations.set_output_charset`, and the *codeset* - parameter of functions :func:`~gettext.translation` and - :func:`~gettext.install` are also removed, since they are only used for - the ``l*gettext()`` functions. +* Removed the deprecated :mod:`gettext` functions + :func:`!lgettext`, :func:`!ldgettext`, + :func:`!lngettext` and :func:`!ldngettext`. + Also removed the :func:`!bind_textdomain_codeset` function, + the :meth:`!NullTranslations.output_charset` and + :meth:`!NullTranslations.set_output_charset` methods, + and the *codeset* parameter of :func:`!translation` and :func:`!install`, + since they are only used for the :func:`!l*gettext` functions. (Contributed by Dong-hee Na and Serhiy Storchaka in :issue:`44235`.) -* Removed from the :mod:`configparser` module: - the :class:`SafeConfigParser` class, - the :attr:`filename` property of the :class:`ParsingError` class, - the :meth:`readfp` method of the :class:`ConfigParser` class, - deprecated since Python 3.2. - (Contributed by Hugo van Kemenade in :issue:`45173`.) - -* The :func:`@asyncio.coroutine ` :term:`decorator` enabling - legacy generator-based coroutines to be compatible with async/await code. - The function has been deprecated since Python 3.8 and the removal was - initially scheduled for Python 3.10. Use :keyword:`async def` instead. - (Contributed by Illia Volochii in :issue:`43216`.) - -* :class:`asyncio.coroutines.CoroWrapper` used for wrapping legacy - generator-based coroutine objects in the debug mode. - (Contributed by Illia Volochii in :issue:`43216`.) - -* Removed the deprecated ``split()`` method of :class:`_tkinter.TkappType`. - (Contributed by Erlend E. Aasland in :issue:`38371`.) - * Removed from the :mod:`inspect` module: - * the ``getargspec`` function, deprecated since Python 3.0; + * The :func:`!getargspec` function, deprecated since Python 3.0; use :func:`inspect.signature` or :func:`inspect.getfullargspec` instead. - * the ``formatargspec`` function, deprecated since Python 3.5; - use the :func:`inspect.signature` function and :class:`Signature` object - directly. + * The :func:`!formatargspec` function, deprecated since Python 3.5; + use the :func:`inspect.signature` function + or the :class:`inspect.Signature` object directly. - * the undocumented ``Signature.from_callable`` and ``Signature.from_function`` - functions, deprecated since Python 3.5; use the - :meth:`Signature.from_callable() ` method - instead. + * The undocumented :meth:`!Signature.from_builtin` + and :meth:`!Signature.from_function` methods, deprecated since Python 3.5; + use the :meth:`Signature.from_callable() ` + method instead. (Contributed by Hugo van Kemenade in :issue:`45320`.) -* Remove the ``asyncore`` and ``asynchat`` modules, deprecated in Python 3.6: - use the :mod:`asyncio` module instead. - (Contributed by Victor Stinner in :issue:`28533`.) +* Removed the :meth:`~object.__class_getitem__` method + from :class:`pathlib.PurePath`, + because it was not used and added by mistake in previous versions. + (Contributed by Nikita Sobolev in :issue:`46483`.) -* Remove the ``smtpd`` module, deprecated in Python 3.6: the `aiosmtpd - `__ module can be used instead, it is based - on asyncio. - (Contributed by Victor Stinner in :issue:`28533`.) +* Removed the :class:`!MailmanProxy` class in the :mod:`smtpd` module, + as it is unusable without the external :mod:`!mailman` package. + (Contributed by Dong-hee Na in :issue:`35800`.) +* Removed the deprecated :meth:`!split` method of :class:`!_tkinter.TkappType`. + (Contributed by Erlend E. Aasland in :issue:`38371`.) + +* Removed namespace package support from :mod:`unittest` discovery. + It was introduced in Python 3.4 but has been broken since Python 3.7. + (Contributed by Inada Naoki in :issue:`23882`.) + +* Removed the undocumented private :meth:`!float.__set_format__()` method, + previously known as :meth:`!float.__setformat__()` in Python 3.7. + Its docstring said: "You probably don't want to use this function. + It exists mainly to be used in Python's test suite." + (Contributed by Victor Stinner in :issue:`46852`.) + +* The :option:`!--experimental-isolated-subinterpreters` configure flag + (and corresponding :c:macro:`!EXPERIMENTAL_ISOLATED_SUBINTERPRETERS` macro) + have been removed. + +* `Pynche `_ + --- The Pythonically Natural Color and Hue Editor --- has been moved out + of ``Tools/scripts`` and is `being developed independently + `_ from the Python source tree. + + +.. _whatsnew311-porting: +.. _whatsnew311-python-api-porting: Porting to Python 3.11 ====================== This section lists previously described changes and other bugfixes -that may require changes to your code. +in the Python API that may require changes to your Python code. - -Changes in the Python API -------------------------- - -* Prohibited passing non-:class:`concurrent.futures.ThreadPoolExecutor` - executors to :meth:`loop.set_default_executor` following a deprecation in - Python 3.8. - (Contributed by Illia Volochii in :issue:`43234`.) +Porting notes for the C API are +:ref:`listed separately `. * :func:`open`, :func:`io.open`, :func:`codecs.open` and :class:`fileinput.FileInput` no longer accept ``'U'`` ("universal newline") - in the file mode. This flag was deprecated since Python 3.3. In Python 3, the - "universal newline" is used by default when a file is open in text mode. The - :ref:`newline parameter ` of :func:`open` controls - how universal newlines works. + in the file mode. In Python 3, "universal newline" mode is used by default + whenever a file is opened in text mode, + and the ``'U'`` flag has been deprecated since Python 3.3. + The :ref:`newline parameter ` + to these functions controls how universal newlines work. (Contributed by Victor Stinner in :issue:`37330`.) +* :class:`ast.AST` node positions are now validated when provided to + :func:`compile` and other related functions. If invalid positions are detected, + a :exc:`ValueError` will be raised. (Contributed by Pablo Galindo in :gh:`93351`) + +* Prohibited passing non-:class:`concurrent.futures.ThreadPoolExecutor` + executors to :meth:`asyncio.loop.set_default_executor` + following a deprecation in Python 3.8. + (Contributed by Illia Volochii in :issue:`43234`.) + +* :mod:`calendar`: The :class:`calendar.LocaleTextCalendar` and + :class:`calendar.LocaleHTMLCalendar` classes now use + :func:`locale.getlocale`, instead of using :func:`locale.getdefaultlocale`, + if no locale is specified. + (Contributed by Victor Stinner in :issue:`46659`.) + * The :mod:`pdb` module now reads the :file:`.pdbrc` configuration file with - the ``'utf-8'`` encoding. + the ``'UTF-8'`` encoding. (Contributed by Srinivas Reddy Thatiparthy (à°¶à±à°°à±€à°¨à°¿à°µà°¾à°¸à± రెడà±à°¡à°¿ తాటిపరà±à°¤à°¿) in :issue:`41137`.) -* When sorting using tuples as keys, the order of the result may differ - from earlier releases if the tuple elements don't define a total - ordering (see :ref:`expressions-value-comparisons` for - information on total ordering). It's generally true that the result - of sorting simply isn't well-defined in the absence of a total ordering - on list elements. +* The *population* parameter of :func:`random.sample` must be a sequence, + and automatic conversion of :class:`set`\s to :class:`list`\s + is no longer supported. Also, if the sample size + is larger than the population size, a :exc:`ValueError` is raised. + (Contributed by Raymond Hettinger in :issue:`40465`.) +* The *random* optional parameter of :func:`random.shuffle` was removed. + It was previously an arbitrary random function to use for the shuffle; + now, :func:`random.random` (its previous default) will always be used. + +* In :mod:`re` :ref:`re-syntax`, global inline flags (e.g. ``(?i)``) + can now only be used at the start of regular expressions. + Using them elsewhere has been deprecated since Python 3.6. + (Contributed by Serhiy Storchaka in :issue:`47066`.) + +* In the :mod:`re` module, several long-standing bugs where fixed that, + in rare cases, could cause capture groups to get the wrong result. + Therefore, this could change the captured output in these cases. + (Contributed by Ma Lin in :issue:`35859`.) + + +.. _whatsnew311-build-changes: Build Changes ============= -* CPython can now be built with the ThinLTO option via ``--with-lto=thin``. - (Contributed by Dong-hee Na and Brett Holman in :issue:`44340`.) +* CPython now has :pep:`11` :pep:`Tier 3 support <11#tier-3>` for + cross compiling to the `WebAssembly `_ platforms + `Emscripten `_ + (``wasm32-unknown-emscripten``, i.e. Python in the browser) + and `WebAssembly System Interface (WASI) `_ + (``wasm32-unknown-wasi``). + The effort is inspired by previous work like `Pyodide `_. + These platforms provide a limited subset of POSIX APIs; Python standard + libraries features and modules related to networking, processes, threading, + signals, mmap, and users/groups are not available or don't work. + (Emscripten contributed by Christian Heimes and Ethan Smith in :gh:`84461` + and WASI contributed by Christian Heimes in :gh:`90473`; + platforms promoted in :gh:`95085`) + +* Building Python now requires: + + * A `C11 `_ compiler. + `Optional C11 features + `_ + are not required. + (Contributed by Victor Stinner in :issue:`46656`.) + + * Support for `IEEE 754 `_ + floating point numbers. + (Contributed by Victor Stinner in :issue:`46917`.) + + * Support for `floating point Not-a-Number (NaN) + `_, + as the :c:macro:`!Py_NO_NAN` macro has been removed. + (Contributed by Victor Stinner in :issue:`46656`.) + + * A `C99 `_ + ```` header file providing the + :c:func:`!copysign`, :c:func:`!hypot`, :c:func:`!isfinite`, + :c:func:`!isinf`, :c:func:`!isnan`, and :c:func:`!round` functions + (contributed by Victor Stinner in :issue:`45440`); + and a :c:data:`!NAN` constant or the :c:func:`!__builtin_nan` function + (Contributed by Victor Stinner in :issue:`46640`). + +* The :mod:`tkinter` package now requires `Tcl/Tk `_ + version 8.5.12 or newer. + (Contributed by Serhiy Storchaka in :issue:`46996`.) + +* Build dependencies, compiler flags, and linker flags for most stdlib + extension modules are now detected by :program:`configure`. libffi, libnsl, + libsqlite3, zlib, bzip2, liblzma, libcrypt, Tcl/Tk, and uuid flags + are detected by `pkg-config + `_ (when available). + :mod:`tkinter` now requires a pkg-config command + to detect development settings for `Tcl/Tk`_ headers and libraries. + (Contributed by Christian Heimes and Erlend Egeberg Aasland in + :issue:`45847`, :issue:`45747`, and :issue:`45763`.) * libpython is no longer linked against libcrypt. (Contributed by Mike Gilbert in :issue:`45433`.) -* Building Python now requires a C99 ```` header file providing - the following functions: ``copysign()``, ``hypot()``, ``isfinite()``, - ``isinf()``, ``isnan()``, ``round()``. - (Contributed by Victor Stinner in :issue:`45440`.) +* CPython can now be built with the + `ThinLTO `_ option + via passing ``thin`` to :option:`--with-lto`, i.e. ``--with-lto=thin``. + (Contributed by Dong-hee Na and Brett Holman in :issue:`44340`.) * Freelists for object structs can now be disabled. A new :program:`configure` - option :option:`!--without-freelists` can be used to disable all freelists + option :option:`--without-freelists` can be used to disable all freelists except empty tuple singleton. - (Contributed by Christian Heimes in :issue:`45522`) + (Contributed by Christian Heimes in :issue:`45522`.) * ``Modules/Setup`` and ``Modules/makesetup`` have been improved and tied up. Extension modules can now be built through ``makesetup``. All except some - test modules can be linked statically into main binary or library. + test modules can be linked statically into a main binary or library. (Contributed by Brett Cannon and Christian Heimes in :issue:`45548`, :issue:`45570`, :issue:`45571`, and :issue:`43974`.) -* The build dependencies for :mod:`zlib`, :mod:`bz2`, and :mod:`lzma` are now - detected by :program:`configure`. - (Contributed by Christian Heimes in :issue:`45763`.) + .. note:: + Use the environment variables :envvar:`!TCLTK_CFLAGS` and + :envvar:`!TCLTK_LIBS` to manually specify the location of Tcl/Tk headers + and libraries. The :program:`configure` options + :option:`!--with-tcltk-includes` and :option:`!--with-tcltk-libs` + have been removed. -* Build dependencies for :mod:`dbm` are now detected by :program:`configure`. - ``libdb`` 3.x and 4.x are no longer supported. - (Contributed by Christian Heimes in :issue:`45747`.) + On RHEL 7 and CentOS 7 the development packages do not provide ``tcl.pc`` + and ``tk.pc``; use ``TCLTK_LIBS="-ltk8.5 -ltkstub8.5 -ltcl8.5"``. + The directory ``Misc/rhel7`` contains ``.pc`` files and instructions + on how to build Python with RHEL 7's and CentOS 7's Tcl/Tk and OpenSSL. + +* CPython will now use 30-bit digits by default for the Python :class:`int` + implementation. Previously, the default was to use 30-bit digits on platforms + with ``SIZEOF_VOID_P >= 8``, and 15-bit digits otherwise. It's still possible + to explicitly request use of 15-bit digits via either the + :option:`--enable-big-digits` option to the configure script + or (for Windows) the ``PYLONG_BITS_IN_DIGIT`` variable in ``PC/pyconfig.h``, + but this option may be removed at some point in the future. + (Contributed by Mark Dickinson in :issue:`45569`.) + + +.. _whatsnew311-c-api: C API Changes ============= +.. _whatsnew311-c-api-new-features: + New Features ------------ @@ -572,9 +2183,108 @@ New Features suspend and resume tracing and profiling. (Contributed by Victor Stinner in :issue:`43760`.) +* Added the :c:data:`Py_Version` constant which bears the same value as + :c:macro:`PY_VERSION_HEX`. + (Contributed by Gabriele N. Tornetta in :issue:`43931`.) + +* :c:type:`Py_buffer` and APIs are now part of the limited API and the stable + ABI: + + * :c:func:`PyObject_CheckBuffer` + * :c:func:`PyObject_GetBuffer` + * :c:func:`PyBuffer_GetPointer` + * :c:func:`PyBuffer_SizeFromFormat` + * :c:func:`PyBuffer_ToContiguous` + * :c:func:`PyBuffer_FromContiguous` + * :c:func:`PyBuffer_CopyData` + * :c:func:`PyBuffer_IsContiguous` + * :c:func:`PyBuffer_FillContiguousStrides` + * :c:func:`PyBuffer_FillInfo` + * :c:func:`PyBuffer_Release` + * :c:func:`PyMemoryView_FromBuffer` + * :c:member:`~PyBufferProcs.bf_getbuffer` and + :c:member:`~PyBufferProcs.bf_releasebuffer` type slots + + (Contributed by Christian Heimes in :issue:`45459`.) + +* Added the :c:data:`PyType_GetModuleByDef` function, used to get the module + in which a method was defined, in cases where this information is not + available directly (via :c:type:`PyCMethod`). + (Contributed by Petr Viktorin in :issue:`46613`.) + +* Add new functions to pack and unpack C double (serialize and deserialize): + :c:func:`PyFloat_Pack2`, :c:func:`PyFloat_Pack4`, :c:func:`PyFloat_Pack8`, + :c:func:`PyFloat_Unpack2`, :c:func:`PyFloat_Unpack4` and + :c:func:`PyFloat_Unpack8`. + (Contributed by Victor Stinner in :issue:`46906`.) + +* Add new functions to get frame object attributes: + :c:func:`PyFrame_GetBuiltins`, :c:func:`PyFrame_GetGenerator`, + :c:func:`PyFrame_GetGlobals`, :c:func:`PyFrame_GetLasti`. + +* Added two new functions to get and set the active exception instance: + :c:func:`PyErr_GetHandledException` and :c:func:`PyErr_SetHandledException`. + These are alternatives to :c:func:`PyErr_SetExcInfo()` and + :c:func:`PyErr_GetExcInfo()` which work with the legacy 3-tuple + representation of exceptions. + (Contributed by Irit Katriel in :issue:`46343`.) + +* Added the :c:member:`PyConfig.safe_path` member. + (Contributed by Victor Stinner in :gh:`57684`.) + + +.. _whatsnew311-c-api-porting: + Porting to Python 3.11 ---------------------- +.. _whatsnew311-pep670: + +* Some macros have been converted to static inline functions to avoid + `macro pitfalls `_. + The change should be mostly transparent to users, + as the replacement functions will cast their arguments to the expected types + to avoid compiler warnings due to static type checks. + However, when the limited C API is set to >=3.11, + these casts are not done, + and callers will need to cast arguments to their expected types. + See :pep:`670` for more details. + (Contributed by Victor Stinner and Erlend E. Aasland in :gh:`89653`.) + +* :c:func:`PyErr_SetExcInfo()` no longer uses the ``type`` and ``traceback`` + arguments, the interpreter now derives those values from the exception + instance (the ``value`` argument). The function still steals references + of all three arguments. + (Contributed by Irit Katriel in :issue:`45711`.) + +* :c:func:`PyErr_GetExcInfo()` now derives the ``type`` and ``traceback`` + fields of the result from the exception instance (the ``value`` field). + (Contributed by Irit Katriel in :issue:`45711`.) + +* :c:struct:`_frozen` has a new ``is_package`` field to indicate whether + or not the frozen module is a package. Previously, a negative value + in the ``size`` field was the indicator. Now only non-negative values + be used for ``size``. + (Contributed by Kumar Aditya in :issue:`46608`.) + +* :c:func:`_PyFrameEvalFunction` now takes ``_PyInterpreterFrame*`` + as its second parameter, instead of ``PyFrameObject*``. + See :pep:`523` for more details of how to use this function pointer type. + +* :c:func:`PyCode_New` and :c:func:`PyCode_NewWithPosOnlyArgs` now take + an additional ``exception_table`` argument. + Using these functions should be avoided, if at all possible. + To get a custom code object: create a code object using the compiler, + then get a modified version with the ``replace`` method. + +* :c:type:`PyCodeObject` no longer has the ``co_code``, ``co_varnames``, + ``co_cellvars`` and ``co_freevars`` fields. Instead, use + :c:func:`PyCode_GetCode`, :c:func:`PyCode_GetVarnames`, + :c:func:`PyCode_GetCellvars` and :c:func:`PyCode_GetFreevars` respectively + to access them via the C API. + (Contributed by Brandt Bucher in :issue:`46841` and Ken Jin in :gh:`92154` + and :gh:`94936`.) + * The old trashcan macros (``Py_TRASHCAN_SAFE_BEGIN``/``Py_TRASHCAN_SAFE_END``) are now deprecated. They should be replaced by the new macros ``Py_TRASHCAN_BEGIN`` and ``Py_TRASHCAN_END``. @@ -608,7 +2318,7 @@ Porting to Python 3.11 can define the following macros and use them throughout the code (credit: these were copied from the ``mypy`` codebase):: - #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 8 + #if PY_VERSION_HEX >= 0x03080000 # define CPy_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_BEGIN(op, dealloc) # define CPy_TRASHCAN_END(op) Py_TRASHCAN_END #else @@ -660,7 +2370,7 @@ Porting to Python 3.11 explicitly include the header files after ``#include ``. (Contributed by Victor Stinner in :issue:`45434`.) -* The non-limited API files ``cellobject.h``, ``classobject.h``, ``context.h``, +* The non-limited API files ``cellobject.h``, ``classobject.h``, ``code.h``, ``context.h``, ``funcobject.h``, ``genobject.h`` and ``longintrepr.h`` have been moved to the ``Include/cpython`` directory. Moreover, the ``eval.h`` header file was removed. These files must not be included directly, as they are already @@ -668,6 +2378,165 @@ Porting to Python 3.11 been included directly, consider including ``Python.h`` instead. (Contributed by Victor Stinner in :issue:`35134`.) +* The :c:func:`PyUnicode_CHECK_INTERNED` macro has been excluded from the + limited C API. It was never usable there, because it used internal structures + which are not available in the limited C API. + (Contributed by Victor Stinner in :issue:`46007`.) + +* The following frame functions and type are now directly available with + ``#include ``, it's no longer needed to add + ``#include ``: + + * :c:func:`PyFrame_Check` + * :c:func:`PyFrame_GetBack` + * :c:func:`PyFrame_GetBuiltins` + * :c:func:`PyFrame_GetGenerator` + * :c:func:`PyFrame_GetGlobals` + * :c:func:`PyFrame_GetLasti` + * :c:func:`PyFrame_GetLocals` + * :c:type:`PyFrame_Type` + + (Contributed by Victor Stinner in :gh:`93937`.) + +.. _pyframeobject-3.11-hiding: + +* The :c:type:`PyFrameObject` structure members have been removed from the + public C API. + + While the documentation notes that the :c:type:`PyFrameObject` fields are + subject to change at any time, they have been stable for a long time and were + used in several popular extensions. + + In Python 3.11, the frame struct was reorganized to allow performance + optimizations. Some fields were removed entirely, as they were details of the + old implementation. + + :c:type:`PyFrameObject` fields: + + * ``f_back``: use :c:func:`PyFrame_GetBack`. + * ``f_blockstack``: removed. + * ``f_builtins``: use :c:func:`PyFrame_GetBuiltins`. + * ``f_code``: use :c:func:`PyFrame_GetCode`. + * ``f_gen``: use :c:func:`PyFrame_GetGenerator`. + * ``f_globals``: use :c:func:`PyFrame_GetGlobals`. + * ``f_iblock``: removed. + * ``f_lasti``: use :c:func:`PyFrame_GetLasti`. + Code using ``f_lasti`` with ``PyCode_Addr2Line()`` should use + :c:func:`PyFrame_GetLineNumber` instead; it may be faster. + * ``f_lineno``: use :c:func:`PyFrame_GetLineNumber` + * ``f_locals``: use :c:func:`PyFrame_GetLocals`. + * ``f_stackdepth``: removed. + * ``f_state``: no public API (renamed to ``f_frame.f_state``). + * ``f_trace``: no public API. + * ``f_trace_lines``: use ``PyObject_GetAttrString((PyObject*)frame, "f_trace_lines")``. + * ``f_trace_opcodes``: use ``PyObject_GetAttrString((PyObject*)frame, "f_trace_opcodes")``. + * ``f_localsplus``: no public API (renamed to ``f_frame.localsplus``). + * ``f_valuestack``: removed. + + The Python frame object is now created lazily. A side effect is that the + ``f_back`` member must not be accessed directly, since its value is now also + computed lazily. The :c:func:`PyFrame_GetBack` function must be called + instead. + + Debuggers that accessed the ``f_locals`` directly *must* call + :c:func:`PyFrame_GetLocals` instead. They no longer need to call + :c:func:`PyFrame_FastToLocalsWithError` or :c:func:`PyFrame_LocalsToFast`, + in fact they should not call those functions. The necessary updating of the + frame is now managed by the virtual machine. + + Code defining ``PyFrame_GetCode()`` on Python 3.8 and older:: + + #if PY_VERSION_HEX < 0x030900B1 + static inline PyCodeObject* PyFrame_GetCode(PyFrameObject *frame) + { + Py_INCREF(frame->f_code); + return frame->f_code; + } + #endif + + Code defining ``PyFrame_GetBack()`` on Python 3.8 and older:: + + #if PY_VERSION_HEX < 0x030900B1 + static inline PyFrameObject* PyFrame_GetBack(PyFrameObject *frame) + { + Py_XINCREF(frame->f_back); + return frame->f_back; + } + #endif + + Or use the `pythoncapi_compat project + `__ to get these two + functions on older Python versions. + +* Changes of the :c:type:`PyThreadState` structure members: + + * ``frame``: removed, use :c:func:`PyThreadState_GetFrame` (function added + to Python 3.9 by :issue:`40429`). + Warning: the function returns a :term:`strong reference`, need to call + :c:func:`Py_XDECREF`. + * ``tracing``: changed, use :c:func:`PyThreadState_EnterTracing` + and :c:func:`PyThreadState_LeaveTracing` + (functions added to Python 3.11 by :issue:`43760`). + * ``recursion_depth``: removed, + use ``(tstate->recursion_limit - tstate->recursion_remaining)`` instead. + * ``stackcheck_counter``: removed. + + Code defining ``PyThreadState_GetFrame()`` on Python 3.8 and older:: + + #if PY_VERSION_HEX < 0x030900B1 + static inline PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate) + { + Py_XINCREF(tstate->frame); + return tstate->frame; + } + #endif + + Code defining ``PyThreadState_EnterTracing()`` and + ``PyThreadState_LeaveTracing()`` on Python 3.10 and older:: + + #if PY_VERSION_HEX < 0x030B00A2 + static inline void PyThreadState_EnterTracing(PyThreadState *tstate) + { + tstate->tracing++; + #if PY_VERSION_HEX >= 0x030A00A1 + tstate->cframe->use_tracing = 0; + #else + tstate->use_tracing = 0; + #endif + } + + static inline void PyThreadState_LeaveTracing(PyThreadState *tstate) + { + int use_tracing = (tstate->c_tracefunc != NULL || tstate->c_profilefunc != NULL); + tstate->tracing--; + #if PY_VERSION_HEX >= 0x030A00A1 + tstate->cframe->use_tracing = use_tracing; + #else + tstate->use_tracing = use_tracing; + #endif + } + #endif + + Or use `the pythoncapi_compat project + `__ to get these functions + on old Python functions. + +* Distributors are encouraged to build Python with the optimized Blake2 + library `libb2`_. + +* The :c:member:`PyConfig.module_search_paths_set` field must now be set to 1 for + initialization to use :c:member:`PyConfig.module_search_paths` to initialize + :data:`sys.path`. Otherwise, initialization will recalculate the path and replace + any values added to ``module_search_paths``. + +* :c:func:`PyConfig_Read` no longer calculates the initial search path, and will not + fill any values into :c:member:`PyConfig.module_search_paths`. To calculate default + paths and then modify them, finish initialization and use :c:func:`PySys_GetObject` + to retrieve :data:`sys.path` as a Python list object and modify it directly. + + +.. _whatsnew311-c-api-deprecated: + Deprecated ---------- @@ -677,6 +2546,9 @@ Deprecated * :c:func:`PySys_AddWarnOption` * :c:func:`PySys_AddXOption` * :c:func:`PySys_HasWarnOptions` + * :c:func:`PySys_SetArgvEx` + * :c:func:`PySys_SetArgv` + * :c:func:`PySys_SetPath` * :c:func:`Py_SetPath` * :c:func:`Py_SetProgramName` * :c:func:`Py_SetPythonHome` @@ -685,7 +2557,39 @@ Deprecated Use the new :c:type:`PyConfig` API of the :ref:`Python Initialization Configuration ` instead (:pep:`587`). - (Contributed by Victor Stinner in :issue:`44113`.) + (Contributed by Victor Stinner in :gh:`88279`.) + +* Deprecate the ``ob_shash`` member of the :c:type:`PyBytesObject`. Use :c:func:`PyObject_Hash` instead. + (Contributed by Inada Naoki in :issue:`46864`.) + + +.. _whatsnew311-c-api-pending-removal: + +Pending Removal in Python 3.12 +------------------------------ + +The following C APIs have been deprecated in earlier Python releases, +and will be removed in Python 3.12. + +* :c:func:`PyUnicode_AS_DATA` +* :c:func:`PyUnicode_AS_UNICODE` +* :c:func:`PyUnicode_AsUnicodeAndSize` +* :c:func:`PyUnicode_AsUnicode` +* :c:func:`PyUnicode_FromUnicode` +* :c:func:`PyUnicode_GET_DATA_SIZE` +* :c:func:`PyUnicode_GET_SIZE` +* :c:func:`PyUnicode_GetSize` +* :c:func:`PyUnicode_IS_COMPACT` +* :c:func:`PyUnicode_IS_READY` +* :c:func:`PyUnicode_READY` +* :c:func:`Py_UNICODE_WSTR_LENGTH` +* :c:func:`_PyUnicode_AsUnicode` +* :c:macro:`PyUnicode_WCHAR_KIND` +* :c:type:`PyUnicodeObject` +* :c:func:`PyUnicode_InternImmortal()` + + +.. _whatsnew311-c-api-removed: Removed ------- @@ -734,3 +2638,42 @@ Removed worked since the :c:type:`PyWeakReference` structure is opaque in the limited C API. (Contributed by Victor Stinner in :issue:`35134`.) + +* Remove the ``PyHeapType_GET_MEMBERS()`` macro. It was exposed in the + public C API by mistake, it must only be used by Python internally. + Use the ``PyTypeObject.tp_members`` member instead. + (Contributed by Victor Stinner in :issue:`40170`.) + +* Remove the ``HAVE_PY_SET_53BIT_PRECISION`` macro (moved to the internal C + API). + (Contributed by Victor Stinner in :issue:`45412`.) + +.. _whatsnew311-pep624: + +* Remove the :c:type:`Py_UNICODE` encoder APIs, + as they have been deprecated since Python 3.3, + are little used + and are inefficient relative to the recommended alternatives. + + The removed functions are: + + * :func:`!PyUnicode_Encode` + * :func:`!PyUnicode_EncodeASCII` + * :func:`!PyUnicode_EncodeLatin1` + * :func:`!PyUnicode_EncodeUTF7` + * :func:`!PyUnicode_EncodeUTF8` + * :func:`!PyUnicode_EncodeUTF16` + * :func:`!PyUnicode_EncodeUTF32` + * :func:`!PyUnicode_EncodeUnicodeEscape` + * :func:`!PyUnicode_EncodeRawUnicodeEscape` + * :func:`!PyUnicode_EncodeCharmap` + * :func:`!PyUnicode_TranslateCharmap` + * :func:`!PyUnicode_EncodeDecimal` + * :func:`!PyUnicode_TransformDecimalToASCII` + + See :pep:`624` for details and + :pep:`migration guidance <624#alternative-apis>`. + (Contributed by Inada Naoki in :issue:`44029`.) + + +.. _libb2: https://www.blake2.net/ diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst new file mode 100644 index 00000000000..a071159b800 --- /dev/null +++ b/Doc/whatsnew/3.12.rst @@ -0,0 +1,1000 @@ + +**************************** + What's New In Python 3.12 +**************************** + +:Release: |release| +:Date: |today| + +.. Rules for maintenance: + + * Anyone can add text to this document. Do not spend very much time + on the wording of your changes, because your text will probably + get rewritten to some degree. + + * The maintainer will go through Misc/NEWS periodically and add + changes; it's therefore more important to add your changes to + Misc/NEWS than to this file. + + * This is not a complete list of every single change; completeness + is the purpose of Misc/NEWS. Some changes I consider too small + or esoteric to include. If such a change is added to the text, + I'll just remove it. (This is another reason you shouldn't spend + too much time on writing your addition.) + + * If you want to draw your new text to the attention of the + maintainer, add 'XXX' to the beginning of the paragraph or + section. + + * It's OK to just add a fragmentary note about a change. For + example: "XXX Describe the transmogrify() function added to the + socket module." The maintainer will research the change and + write the necessary text. + + * You can comment out your additions if you like, but it's not + necessary (especially when a final release is some months away). + + * Credit the author of a patch or bugfix. Just the name is + sufficient; the e-mail address isn't necessary. + + * It's helpful to add the issue number as a comment: + + XXX Describe the transmogrify() function added to the socket + module. + (Contributed by P.Y. Developer in :gh:`12345`.) + + This saves the maintainer the effort of going through the VCS log when + researching a change. + +This article explains the new features in Python 3.12, compared to 3.11. + +For full details, see the :ref:`changelog `. + +.. note:: + + Prerelease users should be aware that this document is currently in draft + form. It will be updated substantially as Python 3.12 moves towards release, + so it's worth checking back even after reading earlier versions. + + +Summary -- Release highlights +============================= + +.. This section singles out the most important changes in Python 3.12. + Brevity is key. + + +.. PEP-sized items next. + +Important deprecations, removals or restrictions: + +* :pep:`623`, Remove wstr from Unicode + +* :pep:`632`, Remove the ``distutils`` package. + +Improved Error Messages +======================= + +* Modules from the standard library are now potentially suggested as part of + the error messages displayed by the interpreter when a :exc:`NameError` is + raised to the top level. Contributed by Pablo Galindo in :gh:`98254`. + + >>> sys.version_info + Traceback (most recent call last): + File "", line 1, in + NameError: name 'sys' is not defined. Did you forget to import 'sys'? + +* Improve the error suggestion for :exc:`NameError` exceptions for instances. + Now if a :exc:`NameError` is raised in a method and the instance has an + attribute that's exactly equal to the name in the exception, the suggestion + will include ``self.`` instead of the closest match in the method + scope. Contributed by Pablo Galindo in :gh:`99139`. + + >>> class A: + ... def __init__(self): + ... self.blech = 1 + ... + ... def foo(self): + ... somethin = blech + + >>> A().foo() + Traceback (most recent call last): + File "", line 1 + somethin = blech + ^^^^^ + NameError: name 'blech' is not defined. Did you mean: 'self.blech'? + + +* Improve the :exc:`SyntaxError` error message when the user types ``import x + from y`` instead of ``from y import x``. Contributed by Pablo Galindo in :gh:`98931`. + + >>> import a.y.z from b.y.z + Traceback (most recent call last): + File "", line 1 + import a.y.z from b.y.z + ^^^^^^^^^^^^^^^^^^^^^^^ + SyntaxError: Did you mean to use 'from ... import ...' instead? + +* :exc:`ImportError` exceptions raised from failed ``from import + `` statements now include suggestions for the value of ```` based on the + available names in ````. Contributed by Pablo Galindo in :gh:`91058`. + + >>> from collections import chainmap + Traceback (most recent call last): + File "", line 1, in + ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'? + + +New Features +============ + +* Add :ref:`perf_profiling` through the new + environment variable :envvar:`PYTHONPERFSUPPORT`, + the new command-line option :option:`-X perf <-X>`, + as well as the new :func:`sys.activate_stack_trampoline`, + :func:`sys.deactivate_stack_trampoline`, + and :func:`sys.is_stack_trampoline_active` APIs. + (Design by Pablo Galindo. Contributed by Pablo Galindo and Christian Heimes + with contributions from Gregory P. Smith [Google] and Mark Shannon + in :gh:`96123`.) + + +Other Language Changes +====================== + +* :class:`types.MappingProxyType` instances are now hashable if the underlying + mapping is hashable. + (Contributed by Serhiy Storchaka in :gh:`87995`.) + +* :class:`memoryview` now supports the half-float type (the "e" format code). + (Contributed by Dong-hee Na and Antoine Pitrou in :gh:`90751`.) + +* The parser now raises :exc:`SyntaxError` when parsing source code containing + null bytes. (Contributed by Pablo Galindo in :gh:`96670`.) + +* :func:`ast.parse` now raises :exc:`SyntaxError` instead of :exc:`ValueError` + when parsing source code containing null bytes. (Contributed by Pablo Galindo + in :gh:`96670`.) + +* The Garbage Collector now runs only on the eval breaker mechanism of the + Python bytecode evaluation loop instead of object allocations. The GC can + also run when :c:func:`PyErr_CheckSignals` is called so C extensions that + need to run for a long time without executing any Python code also have a + chance to execute the GC periodically. (Contributed by Pablo Galindo in + :gh:`97922`.) + +* A backslash-character pair that is not a valid escape sequence now generates + a :exc:`SyntaxWarning`, instead of :exc:`DeprecationWarning`. + For example, ``re.compile("\d+\.\d+")`` now emits a :exc:`SyntaxWarning` + (``"\d"`` is an invalid escape sequence), use raw strings for regular + expression: ``re.compile(r"\d+\.\d+")``. + In a future Python version, :exc:`SyntaxError` will eventually be raised, + instead of :exc:`SyntaxWarning`. + (Contributed by Victor Stinner in :gh:`98401`.) + +* Octal escapes with value larger than ``0o377`` (ex: ``"\477"``), deprecated + in Python 3.11, now produce a :exc:`SyntaxWarning`, instead of + :exc:`DeprecationWarning`. + In a future Python version they will be eventually a :exc:`SyntaxError`. + (Contributed by Victor Stinner in :gh:`98401`.) + +* All builtin and extension callables expecting boolean parameters now accept + arguments of any type instead of just :class:`bool` and :class:`int`. + (Contributed by Serhiy Storchaka in :gh:`60203`.) + +* Variables used in the target part of comprehensions that are not stored to + can now be used in assignment expressions (``:=``). + For example, in ``[(b := 1) for a, b.prop in some_iter]``, the assignment to + ``b`` is now allowed. Note that assigning to variables stored to in the target + part of comprehensions (like ``a``) is still disallowed, as per :pep:`572`. + (Contributed by Nikita Sobolev in :gh:`100581`.) + + +New Modules +=========== + +* None yet. + + +Improved Modules +================ + +array +----- + +* The :class:`array.array` class now supports subscripting, making it a + :term:`generic type`. (Contributed by Jelle Zijlstra in :gh:`98658`.) + +asyncio +------- + +* On Linux, :mod:`asyncio` uses :class:`~asyncio.PidfdChildWatcher` by default + if :func:`os.pidfd_open` is available and functional instead of + :class:`~asyncio.ThreadedChildWatcher`. + (Contributed by Kumar Aditya in :gh:`98024`.) + +* The child watcher classes :class:`~asyncio.MultiLoopChildWatcher`, + :class:`~asyncio.FastChildWatcher`, :class:`~asyncio.AbstractChildWatcher` + and :class:`~asyncio.SafeChildWatcher` are deprecated and + will be removed in Python 3.14. It is recommended to not manually + configure a child watcher as the event loop now uses the best available + child watcher for each platform (:class:`~asyncio.PidfdChildWatcher` + if supported and :class:`~asyncio.ThreadedChildWatcher` otherwise). + (Contributed by Kumar Aditya in :gh:`94597`.) + +* :func:`asyncio.set_child_watcher`, :func:`asyncio.get_child_watcher`, + :meth:`asyncio.AbstractEventLoopPolicy.set_child_watcher` and + :meth:`asyncio.AbstractEventLoopPolicy.get_child_watcher` are deprecated + and will be removed in Python 3.14. + (Contributed by Kumar Aditya in :gh:`94597`.) + +* Add *loop_factory* parameter to :func:`asyncio.run` to allow specifying + a custom event loop factory. + (Contributed by Kumar Aditya in :gh:`99388`.) + +* Add C implementation of :func:`asyncio.current_task` for 4x-6x speedup. + (Contributed by Itamar Ostricher and Pranav Thulasiram Bhat in :gh:`100344`.) + +inspect +------- + +* Add :func:`inspect.markcoroutinefunction` to mark sync functions that return + a :term:`coroutine` for use with :func:`iscoroutinefunction`. + (Contributed Carlton Gibson in :gh:`99247`.) + +pathlib +------- + +* Add :meth:`~pathlib.Path.walk` for walking the directory trees and generating + all file or directory names within them, similar to :func:`os.walk`. + (Contributed by Stanislav Zmiev in :gh:`90385`.) + +* Add *walk_up* optional parameter to :meth:`pathlib.PurePath.relative_to` + to allow the insertion of ``..`` entries in the result; this behavior is + more consistent with :func:`os.path.relpath`. + (Contributed by Domenico Ragusa in :issue:`40358`.) + +* Add :meth:`pathlib.Path.is_junction` as a proxy to :func:`os.path.isjunction`. + (Contributed by Charles Machalow in :gh:`99547`.) + + +dis +--- + +* Pseudo instruction opcodes (which are used by the compiler but + do not appear in executable bytecode) are now exposed in the + :mod:`dis` module. + :data:`~dis.HAVE_ARGUMENT` is still relevant to real opcodes, + but it is not useful for pseudo instructions. Use the new + :data:`~dis.hasarg` collection instead. + (Contributed by Irit Katriel in :gh:`94216`.) + +fractions +--------- + +* Objects of type :class:`fractions.Fraction` now support float-style + formatting. (Contributed by Mark Dickinson in :gh:`100161`.) + +math +---- + +* Added :func:`math.sumprod` for computing a sum of products. + (Contributed by Raymond Hettinger in :gh:`100485`.) + +os +-- + +* Add :data:`os.PIDFD_NONBLOCK` to open a file descriptor + for a process with :func:`os.pidfd_open` in non-blocking mode. + (Contributed by Kumar Aditya in :gh:`93312`.) + +* :class:`os.DirEntry` now includes an :meth:`os.DirEntry.is_junction` + method to check if the entry is a junction. + (Contributed by Charles Machalow in :gh:`99547`.) + +os.path +------- + +* Add :func:`os.path.isjunction` to check if a given path is a junction. + (Contributed by Charles Machalow in :gh:`99547`.) + +* Add :func:`os.path.splitroot` to split a path into a triad + ``(drive, root, tail)``. (Contributed by Barney Gale in :gh:`101000`.) + +shutil +------ + +* :func:`shutil.make_archive` now passes the *root_dir* argument to custom + archivers which support it. + In this case it no longer temporarily changes the current working directory + of the process to *root_dir* to perform archiving. + (Contributed by Serhiy Storchaka in :gh:`74696`.) + + +sqlite3 +------- + +* Add a :ref:`command-line interface `. + (Contributed by Erlend E. Aasland in :gh:`77617`.) + +* Add the :attr:`~sqlite3.Connection.autocommit` attribute + to :class:`~sqlite3.Connection` + and the *autocommit* parameter to :func:`~sqlite3.connect` + to control :pep:`249`-compliant + :ref:`transaction handling `. + (Contributed by Erlend E. Aasland in :gh:`83638`.) + +threading +--------- + +* Add :func:`threading.settrace_all_threads` and + :func:`threading.setprofile_all_threads` that allow to set tracing and + profiling functions in all running threads in addition to the calling one. + (Contributed by Pablo Galindo in :gh:`93503`.) + +unicodedata +----------- + +* The Unicode database has been updated to version 15.0.0. (Contributed by + Benjamin Peterson in :gh:`96734`). + +uuid +---- + +* Add a :ref:`command-line interface `. + (Contributed by Adam Chhina in :gh:`88597`.) + +tempfile +-------- + +The :class:`tempfile.NamedTemporaryFile` function has a new optional parameter +*delete_on_close* (Contributed by Evgeny Zorin in :gh:`58451`.) + +sys +--- + +* Add :func:`sys.activate_stack_trampoline` and + :func:`sys.deactivate_stack_trampoline` for activating and deactivating + stack profiler trampolines, + and :func:`sys.is_stack_trampoline_active` for querying if stack profiler + trampolines are active. + (Contributed by Pablo Galindo and Christian Heimes + with contributions from Gregory P. Smith [Google] and Mark Shannon + in :gh:`96123`.) + + +Optimizations +============= + +* Removed ``wstr`` and ``wstr_length`` members from Unicode objects. + It reduces object size by 8 or 16 bytes on 64bit platform. (:pep:`623`) + (Contributed by Inada Naoki in :gh:`92536`.) + +* Added experimental support for using the BOLT binary optimizer in the build + process, which improves performance by 1-5%. + (Contributed by Kevin Modzelewski in :gh:`90536`.) + +* Speed up the regular expression substitution (functions :func:`re.sub` and + :func:`re.subn` and corresponding :class:`re.Pattern` methods) for + replacement strings containing group references by 2--3 times. + (Contributed by Serhiy Storchaka in :gh:`91524`.) + + +CPython bytecode changes +======================== + +* Removed the :opcode:`LOAD_METHOD` instruction. It has been merged into + :opcode:`LOAD_ATTR`. :opcode:`LOAD_ATTR` will now behave like the old + :opcode:`LOAD_METHOD` instruction if the low bit of its oparg is set. + (Contributed by Ken Jin in :gh:`93429`.) + + +Demos and Tools +=============== + +* Remove the ``Tools/demo/`` directory which contained old demo scripts. A copy + can be found in the `old-demos project + `_. + (Contributed by Victor Stinner in :gh:`97681`.) + +* Remove outdated example scripts of the ``Tools/scripts/`` directory. + A copy can be found in the `old-demos project + `_. + (Contributed by Victor Stinner in :gh:`97669`.) + + +Deprecated +========== + +* :class:`typing.Hashable` and :class:`typing.Sized` aliases for :class:`collections.abc.Hashable` + and :class:`collections.abc.Sized`. (:gh:`94309`.) + +* The :mod:`sqlite3` :ref:`default adapters and converters + ` are now deprecated. + Instead, use the :ref:`sqlite3-adapter-converter-recipes` + and tailor them to your needs. + (Contributed by Erlend E. Aasland in :gh:`90016`.) + +* The 3-arg signatures (type, value, traceback) of :meth:`~coroutine.throw`, + :meth:`~generator.throw` and :meth:`~agen.athrow` are deprecated and + may be removed in a future version of Python. Use the single-arg versions + of these functions instead. (Contributed by Ofey Chan in :gh:`89874`.) + +* :exc:`DeprecationWarning` is now raised when ``__package__`` on a + module differs from ``__spec__.parent`` (previously it was + :exc:`ImportWarning`). + (Contributed by Brett Cannon in :gh:`65961`.) + +* The :meth:`~asyncio.DefaultEventLoopPolicy.get_event_loop` method of the + default event loop policy now emits a :exc:`DeprecationWarning` if there + is no current event loop set and it decides to create one. + (Contributed by Serhiy Storchaka and Guido van Rossum in :gh:`100160`.) + +* The :mod:`xml.etree.ElementTree` module now emits :exc:`DeprecationWarning` + when testing the truth value of an :class:`xml.etree.ElementTree.Element`. + Before, the Python implementation emitted :exc:`FutureWarning`, and the C + implementation emitted nothing. + +* In accordance with :pep:`699`, the ``ma_version_tag`` field in :c:type:`PyDictObject` + is deprecated for extension modules. Accessing this field will generate a compiler + warning at compile time. This field will be removed in Python 3.14. + (Contributed by Ramvikrams and Kumar Aditya in :gh:`101193`. PEP by Ken Jin.) + + +Pending Removal in Python 3.13 +------------------------------ + +The following modules and APIs have been deprecated in earlier Python releases, +and will be removed in Python 3.13. + +Modules (see :pep:`594`): + +* :mod:`aifc` +* :mod:`audioop` +* :mod:`cgi` +* :mod:`cgitb` +* :mod:`chunk` +* :mod:`crypt` +* :mod:`imghdr` +* :mod:`mailcap` +* :mod:`msilib` +* :mod:`nis` +* :mod:`nntplib` +* :mod:`ossaudiodev` +* :mod:`pipes` +* :mod:`sndhdr` +* :mod:`spwd` +* :mod:`sunau` +* :mod:`telnetlib` +* :mod:`uu` +* :mod:`xdrlib` + +APIs: + +* :class:`configparser.LegacyInterpolation` (:gh:`90765`) +* :func:`locale.getdefaultlocale` (:gh:`90817`) +* :meth:`turtle.RawTurtle.settiltangle` (:gh:`50096`) +* :func:`unittest.findTestCases` (:gh:`50096`) +* :func:`unittest.makeSuite` (:gh:`50096`) +* :func:`unittest.getTestCaseNames` (:gh:`50096`) +* :class:`webbrowser.MacOSX` (:gh:`86421`) + +Pending Removal in Python 3.14 +============================== + +* Deprecated the following :mod:`importlib.abc` classes, scheduled for removal in + Python 3.14: + + * :class:`importlib.abc.ResourceReader` + * :class:`importlib.abc.Traversable` + * :class:`importlib.abc.TraversableResources` + + Use :mod:`importlib.resources.abc` classes instead: + + * :class:`importlib.resources.abc.Traversable` + * :class:`importlib.resources.abc.TraversableResources` + + (Contributed by Jason R. Coombs and Hugo van Kemenade in :gh:`93963`.) + +* Creating :c:data:`immutable types ` with mutable + bases using the C API. + +* ``__package__`` and ``__cached__`` will cease to be set or taken + into consideration by the import system (:gh:`97879`). + +* Testing the truth value of an :class:`xml.etree.ElementTree.Element` + is deprecated and will raise an exception in Python 3.14. + + +Pending Removal in Future Versions +---------------------------------- + +The following APIs were deprecated in earlier Python versions and will be removed, +although there is currently no date scheduled for their removal. + +* :class:`typing.Text` (:gh:`92332`) + +* Currently Python accepts numeric literals immediately followed by keywords, + for example ``0in x``, ``1or x``, ``0if 1else 2``. It allows confusing + and ambiguous expressions like ``[0x1for x in y]`` (which can be + interpreted as ``[0x1 for x in y]`` or ``[0x1f or x in y]``). + A syntax warning is raised if the numeric literal is + immediately followed by one of keywords :keyword:`and`, :keyword:`else`, + :keyword:`for`, :keyword:`if`, :keyword:`in`, :keyword:`is` and :keyword:`or`. + In a future release it will be changed to a syntax error. (:gh:`87999`) + + +Removed +======= + +* Remove the ``distutils`` package. It was deprecated in Python 3.10 by + :pep:`632` "Deprecate distutils module". For projects still using + ``distutils`` and cannot be updated to something else, the ``setuptools`` + project can be installed: it still provides ``distutils``. + (Contributed by Victor Stinner in :gh:`92584`.) + +* Removed many old deprecated :mod:`unittest` features: + + - A number of :class:`~unittest.TestCase` method aliases: + + ============================ =============================== =============== + Deprecated alias Method Name Deprecated in + ============================ =============================== =============== + ``failUnless`` :meth:`.assertTrue` 3.1 + ``failIf`` :meth:`.assertFalse` 3.1 + ``failUnlessEqual`` :meth:`.assertEqual` 3.1 + ``failIfEqual`` :meth:`.assertNotEqual` 3.1 + ``failUnlessAlmostEqual`` :meth:`.assertAlmostEqual` 3.1 + ``failIfAlmostEqual`` :meth:`.assertNotAlmostEqual` 3.1 + ``failUnlessRaises`` :meth:`.assertRaises` 3.1 + ``assert_`` :meth:`.assertTrue` 3.2 + ``assertEquals`` :meth:`.assertEqual` 3.2 + ``assertNotEquals`` :meth:`.assertNotEqual` 3.2 + ``assertAlmostEquals`` :meth:`.assertAlmostEqual` 3.2 + ``assertNotAlmostEquals`` :meth:`.assertNotAlmostEqual` 3.2 + ``assertRegexpMatches`` :meth:`.assertRegex` 3.2 + ``assertRaisesRegexp`` :meth:`.assertRaisesRegex` 3.2 + ``assertNotRegexpMatches`` :meth:`.assertNotRegex` 3.5 + ============================ =============================== =============== + + You can use https://github.com/isidentical/teyit to automatically modernise + your unit tests. + + - Undocumented and broken :class:`~unittest.TestCase` method + ``assertDictContainsSubset`` (deprecated in Python 3.2). + + - Undocumented :meth:`TestLoader.loadTestsFromModule + ` parameter *use_load_tests* + (deprecated and ignored since Python 3.2). + + - An alias of the :class:`~unittest.TextTestResult` class: + ``_TextTestResult`` (deprecated in Python 3.2). + + (Contributed by Serhiy Storchaka in :issue:`45162`.) + +* Several names deprecated in the :mod:`configparser` way back in 3.2 have + been removed per :gh:`89336`: + + * :class:`configparser.ParsingError` no longer has a ``filename`` attribute + or argument. Use the ``source`` attribute and argument instead. + * :mod:`configparser` no longer has a ``SafeConfigParser`` class. Use the + shorter :class:`~configparser.ConfigParser` name instead. + * :class:`configparser.ConfigParser` no longer has a ``readfp`` method. + Use :meth:`~configparser.ConfigParser.read_file` instead. + +* The following undocumented :mod:`sqlite3` features, deprecated in Python + 3.10, are now removed: + + * ``sqlite3.enable_shared_cache()`` + * ``sqlite3.OptimizedUnicode`` + + If a shared cache must be used, open the database in URI mode using the + ``cache=shared`` query parameter. + + The ``sqlite3.OptimizedUnicode`` text factory has been an alias for + :class:`str` since Python 3.3. Code that previously set the text factory to + ``OptimizedUnicode`` can either use ``str`` explicitly, or rely on the + default value which is also ``str``. + + (Contributed by Erlend E. Aasland in :gh:`92548`.) + +* ``smtpd`` has been removed according to the schedule in :pep:`594`, + having been deprecated in Python 3.4.7 and 3.5.4. + Use aiosmtpd_ PyPI module or any other + :mod:`asyncio`-based server instead. + (Contributed by Oleg Iarygin in :gh:`93243`.) + +.. _aiosmtpd: https://pypi.org/project/aiosmtpd/ + +* ``asynchat`` and ``asyncore`` have been removed + according to the schedule in :pep:`594`, + having been deprecated in Python 3.6. + Use :mod:`asyncio` instead. + (Contributed by Nikita Sobolev in :gh:`96580`.) + +* Remove ``io.OpenWrapper`` and ``_pyio.OpenWrapper``, deprecated in Python + 3.10: just use :func:`open` instead. The :func:`open` (:func:`io.open`) + function is a built-in function. Since Python 3.10, :func:`_pyio.open` is + also a static method. + (Contributed by Victor Stinner in :gh:`94169`.) + +* Remove the :func:`ssl.RAND_pseudo_bytes` function, deprecated in Python 3.6: + use :func:`os.urandom` or :func:`ssl.RAND_bytes` instead. + (Contributed by Victor Stinner in :gh:`94199`.) + +* :mod:`gzip`: Remove the ``filename`` attribute of :class:`gzip.GzipFile`, + deprecated since Python 2.6, use the :attr:`~gzip.GzipFile.name` attribute + instead. In write mode, the ``filename`` attribute added ``'.gz'`` file + extension if it was not present. + (Contributed by Victor Stinner in :gh:`94196`.) + +* Remove the :func:`ssl.match_hostname` function. The + :func:`ssl.match_hostname` was deprecated in Python 3.7. OpenSSL performs + hostname matching since Python 3.7, Python no longer uses the + :func:`ssl.match_hostname` function. + (Contributed by Victor Stinner in :gh:`94199`.) + +* Remove the :func:`locale.format` function, deprecated in Python 3.7: + use :func:`locale.format_string` instead. + (Contributed by Victor Stinner in :gh:`94226`.) + +* :mod:`hashlib`: Remove the pure Python implementation of + :func:`hashlib.pbkdf2_hmac()`, deprecated in Python 3.10. Python 3.10 and + newer requires OpenSSL 1.1.1 (:pep:`644`): this OpenSSL version provides + a C implementation of :func:`~hashlib.pbkdf2_hmac()` which is faster. + (Contributed by Victor Stinner in :gh:`94199`.) + +* :mod:`xml.etree`: Remove the ``ElementTree.Element.copy()`` method of the + pure Python implementation, deprecated in Python 3.10, use the + :func:`copy.copy` function instead. The C implementation of :mod:`xml.etree` + has no ``copy()`` method, only a ``__copy__()`` method. + (Contributed by Victor Stinner in :gh:`94383`.) + +* :mod:`zipimport`: Remove ``find_loader()`` and ``find_module()`` methods, + deprecated in Python 3.10: use the ``find_spec()`` method instead. See + :pep:`451` for the rationale. + (Contributed by Victor Stinner in :gh:`94379`.) + +* Remove the :func:`ssl.wrap_socket` function, deprecated in Python 3.7: + instead, create a :class:`ssl.SSLContext` object and call its + :class:`ssl.SSLContext.wrap_socket` method. Any package that still uses + :func:`ssl.wrap_socket` is broken and insecure. The function neither sends a + SNI TLS extension nor validates server hostname. Code is subject to `CWE-295 + `_: Improper Certificate + Validation. + (Contributed by Victor Stinner in :gh:`94199`.) + +* Many previously deprecated cleanups in :mod:`importlib` have now been + completed: + + * References to, and support for ``module_repr()`` has been eradicated. + + +* ``importlib.util.set_package`` has been removed. + (Contributed by Brett Cannon in :gh:`65961`.) + +* Removed the ``suspicious`` rule from the documentation Makefile, and + removed ``Doc/tools/rstlint.py``, both in favor of `sphinx-lint + `_. + (Contributed by Julien Palard in :gh:`98179`.) + +* Remove the *keyfile* and *certfile* parameters from the + :mod:`ftplib`, :mod:`imaplib`, :mod:`poplib` and :mod:`smtplib` modules, + and the *key_file*, *cert_file* and *check_hostname* parameters from the + :mod:`http.client` module, + all deprecated since Python 3.6. Use the *context* parameter + (*ssl_context* in :mod:`imaplib`) instead. + (Contributed by Victor Stinner in :gh:`94172`.) + +* :mod:`ftplib`: Remove the ``FTP_TLS.ssl_version`` class attribute: use the + *context* parameter instead. + (Contributed by Victor Stinner in :gh:`94172`.) + + +Porting to Python 3.12 +====================== + +This section lists previously described changes and other bugfixes +that may require changes to your code. + +Changes in the Python API +------------------------- + +* More strict rules are now applied for numerical group references and + group names in regular expressions. + Only sequence of ASCII digits is now accepted as a numerical reference. + The group name in bytes patterns and replacement strings can now only + contain ASCII letters and digits and underscore. + (Contributed by Serhiy Storchaka in :gh:`91760`.) + +* Removed ``randrange()`` functionality deprecated since Python 3.10. Formerly, + ``randrange(10.0)`` losslessly converted to ``randrange(10)``. Now, it raises a + :exc:`TypeError`. Also, the exception raised for non-integral values such as + ``randrange(10.5)`` or ``randrange('10')`` has been changed from :exc:`ValueError` to + :exc:`TypeError`. This also prevents bugs where ``randrange(1e25)`` would silently + select from a larger range than ``randrange(10**25)``. + (Originally suggested by Serhiy Storchaka :gh:`86388`.) + +* :class:`argparse.ArgumentParser` changed encoding and error handler + for reading arguments from file (e.g. ``fromfile_prefix_chars`` option) + from default text encoding (e.g. :func:`locale.getpreferredencoding(False) `) + to :term:`filesystem encoding and error handler`. + Argument files should be encoded in UTF-8 instead of ANSI Codepage on Windows. + +* Removed the ``asyncore``-based ``smtpd`` module deprecated in Python 3.4.7 + and 3.5.4. A recommended replacement is the + :mod:`asyncio`-based aiosmtpd_ PyPI module. + +* :func:`shlex.split`: Passing ``None`` for *s* argument now raises an + exception, rather than reading :data:`sys.stdin`. The feature was deprecated + in Python 3.9. + (Contributed by Victor Stinner in :gh:`94352`.) + +* The :mod:`os` module no longer accepts bytes-like paths, like + :class:`bytearray` and :class:`memoryview` types: only the exact + :class:`bytes` type is accepted for bytes strings. + (Contributed by Victor Stinner in :gh:`98393`.) + +* :func:`syslog.openlog` and :func:`syslog.closelog` now fail if used in subinterpreters. + :func:`syslog.syslog` may still be used in subinterpreters, + but now only if :func:`syslog.openlog` has already been called in the main interpreter. + These new restrictions do not apply to the main interpreter, + so only a very small set of users might be affected. + This change helps with interpreter isolation. Furthermore, :mod:`syslog` is a wrapper + around process-global resources, which are best managed from the main interpreter. + (Contributed by Dong-hee Na in :gh:`99127`.) + + +Build Changes +============= + +* Python no longer uses ``setup.py`` to build shared C extension modules. + Build parameters like headers and libraries are detected in ``configure`` + script. Extensions are built by ``Makefile``. Most extensions use + ``pkg-config`` and fall back to manual detection. + (Contributed by Christian Heimes in :gh:`93939`.) + +* ``va_start()`` with two parameters, like ``va_start(args, format),`` + is now required to build Python. + ``va_start()`` is no longer called with a single parameter. + (Contributed by Kumar Aditya in :gh:`93207`.) + +* CPython now uses the ThinLTO option as the default link time optimization policy + if the Clang compiler accepts the flag. + (Contributed by Dong-hee Na in :gh:`89536`.) + +* Add ``COMPILEALL_OPTS`` variable in Makefile to override :mod:`compileall` + options (default: ``-j0``) in ``make install``. Also merged the 3 + ``compileall`` commands into a single command to build .pyc files for all + optimization levels (0, 1, 2) at once. + (Contributed by Victor Stinner in :gh:`99289`.) + + +C API Changes +============= + +New Features +------------ + +* Added the new limited C API function :c:func:`PyType_FromMetaclass`, + which generalizes the existing :c:func:`PyType_FromModuleAndSpec` using + an additional metaclass argument. + (Contributed by Wenzel Jakob in :gh:`93012`.) + +* API for creating objects that can be called using + :ref:`the vectorcall protocol ` was added to the + :ref:`Limited API `: + + * :const:`Py_TPFLAGS_HAVE_VECTORCALL` + * :c:func:`PyVectorcall_NARGS` + * :c:func:`PyVectorcall_Call` + * :c:type:`vectorcallfunc` + + 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 makes vectorcall safe to use with mutable types (i.e. heap types + without the :const:`immutable ` flag). + Mutable types that do not override :c:member:`~PyTypeObject.tp_call` now + inherit the ``Py_TPFLAGS_HAVE_VECTORCALL`` flag. + (Contributed by Petr Viktorin in :gh:`93274`.) + + The :const:`Py_TPFLAGS_MANAGED_DICT` and :const:`Py_TPFLAGS_MANAGED_WEAKREF` + flags have been added. This allows extensions classes to support object + ``__dict__`` and weakrefs with less bookkeeping, + using less memory and with faster access. + +* API for performing calls using + :ref:`the vectorcall protocol ` was added to the + :ref:`Limited API `: + + * :c:func:`PyObject_Vectorcall` + * :c:func:`PyObject_VectorcallMethod` + * :const:`PY_VECTORCALL_ARGUMENTS_OFFSET` + + This means that both the incoming and outgoing ends of the vector call + protocol are now available in the :ref:`Limited API `. (Contributed + by Wenzel Jakob in :gh:`98586`.) + +* Added two new public functions, + :c:func:`PyEval_SetProfileAllThreads` and + :c:func:`PyEval_SetTraceAllThreads`, that allow to set tracing and profiling + functions in all running threads in addition to the calling one. (Contributed + by Pablo Galindo in :gh:`93503`.) + +* Added new function :c:func:`PyFunction_SetVectorcall` to the C API + which sets the vectorcall field of a given :c:type:`PyFunctionObject`. + (Contributed by Andrew Frost in :gh:`92257`.) + +* The C API now permits registering callbacks via :c:func:`PyDict_AddWatcher`, + :c:func:`PyDict_AddWatch` and related APIs to be called whenever a dictionary + is modified. This is intended for use by optimizing interpreters, JIT + compilers, or debuggers. + (Contributed by Carl Meyer in :gh:`91052`.) + +* Added :c:func:`PyType_AddWatcher` and :c:func:`PyType_Watch` API to register + callbacks to receive notification on changes to a type. + (Contributed by Carl Meyer in :gh:`91051`.) + +* Added :c:func:`PyCode_AddWatcher` and :c:func:`PyCode_ClearWatcher` + APIs to register callbacks to receive notification on creation and + destruction of code objects. + (Contributed by Itamar Ostricher in :gh:`91054`.) + +* Add :c:func:`PyFrame_GetVar` and :c:func:`PyFrame_GetVarString` functions to + get a frame variable by its name. + (Contributed by Victor Stinner in :gh:`91248`.) + +Porting to Python 3.12 +---------------------- + +* Legacy Unicode APIs based on ``Py_UNICODE*`` representation has been removed. + Please migrate to APIs based on UTF-8 or ``wchar_t*``. + +* Argument parsing functions like :c:func:`PyArg_ParseTuple` doesn't support + ``Py_UNICODE*`` based format (e.g. ``u``, ``Z``) anymore. Please migrate + to other formats for Unicode like ``s``, ``z``, ``es``, and ``U``. + +* ``tp_weaklist`` for all static builtin types is always ``NULL``. + This is an internal-only field on ``PyTypeObject`` + but we're pointing out the change in case someone happens to be + accessing the field directly anyway. To avoid breakage, consider + using the existing public C-API instead, or, if necessary, the + (internal-only) ``_PyObject_GET_WEAKREFS_LISTPTR()`` macro. + +* This internal-only :c:member:`PyTypeObject.tp_subclasses` may now not be + a valid object pointer. Its type was changed to :c:expr:`void *` to + reflect this. We mention this in case someone happens to be accessing the + internal-only field directly. + + To get a list of subclasses, call the Python method + :py:meth:`~class.__subclasses__` (using :c:func:`PyObject_CallMethod`, + for example). + +* An unrecognized format character in :c:func:`PyUnicode_FromFormat` and + :c:func:`PyUnicode_FromFormatV` now sets a :exc:`SystemError`. + In previous versions it caused all the rest of the format string to be + copied as-is to the result string, and any extra arguments discarded. + (Contributed by Serhiy Storchaka in :gh:`95781`.) + +* Fixed wrong sign placement in :c:func:`PyUnicode_FromFormat` and + :c:func:`PyUnicode_FromFormatV`. + (Contributed by Philip Georgi in :gh:`95504`.) + +* Extension classes wanting to add a ``__dict__`` or weak reference slot + should use :const:`Py_TPFLAGS_MANAGED_DICT` and + :const:`Py_TPFLAGS_MANAGED_WEAKREF` instead of ``tp_dictoffset`` and + ``tp_weaklistoffset``, respectively. + The use of ``tp_dictoffset`` and ``tp_weaklistoffset`` is still + supported, but does not fully support multiple inheritance + (:gh:`95589`), and performance may be worse. + Classes declaring :const:`Py_TPFLAGS_MANAGED_DICT` should call + :c:func:`_PyObject_VisitManagedDict` and :c:func:`_PyObject_ClearManagedDict` + to traverse and clear their instance's dictionaries. + To clear weakrefs, call :c:func:`PyObject_ClearWeakRefs`, as before. + +* The :c:func:`PyUnicode_FSDecoder` function no longer accepts bytes-like + paths, like :class:`bytearray` and :class:`memoryview` types: only the exact + :class:`bytes` type is accepted for bytes strings. + (Contributed by Victor Stinner in :gh:`98393`.) + +* The :c:macro:`Py_CLEAR`, :c:macro:`Py_SETREF` and :c:macro:`Py_XSETREF` + macros now only evaluate their arguments once. If an argument has side + effects, these side effects are no longer duplicated. + (Contributed by Victor Stinner in :gh:`98724`.) + +Deprecated +---------- + +* Deprecate global configuration variable: + + * :c:var:`Py_DebugFlag`: use :c:member:`PyConfig.parser_debug` + * :c:var:`Py_VerboseFlag`: use :c:member:`PyConfig.verbose` + * :c:var:`Py_QuietFlag`: use :c:member:`PyConfig.quiet` + * :c:var:`Py_InteractiveFlag`: use :c:member:`PyConfig.interactive` + * :c:var:`Py_InspectFlag`: use :c:member:`PyConfig.inspect` + * :c:var:`Py_OptimizeFlag`: use :c:member:`PyConfig.optimization_level` + * :c:var:`Py_NoSiteFlag`: use :c:member:`PyConfig.site_import` + * :c:var:`Py_BytesWarningFlag`: use :c:member:`PyConfig.bytes_warning` + * :c:var:`Py_FrozenFlag`: use :c:member:`PyConfig.pathconfig_warnings` + * :c:var:`Py_IgnoreEnvironmentFlag`: use :c:member:`PyConfig.use_environment` + * :c:var:`Py_DontWriteBytecodeFlag`: use :c:member:`PyConfig.write_bytecode` + * :c:var:`Py_NoUserSiteDirectory`: use :c:member:`PyConfig.user_site_directory` + * :c:var:`Py_UnbufferedStdioFlag`: use :c:member:`PyConfig.buffered_stdio` + * :c:var:`Py_HashRandomizationFlag`: use :c:member:`PyConfig.use_hash_seed` + and :c:member:`PyConfig.hash_seed` + * :c:var:`Py_IsolatedFlag`: use :c:member:`PyConfig.isolated` + * :c:var:`Py_LegacyWindowsFSEncodingFlag`: use :c:member:`PyConfig.legacy_windows_fs_encoding` + * :c:var:`Py_LegacyWindowsStdioFlag`: use :c:member:`PyConfig.legacy_windows_stdio` + * :c:var:`Py_FileSystemDefaultEncoding`: use :c:member:`PyConfig.filesystem_encoding` + * :c:var:`Py_FileSystemDefaultEncodeErrors`: use :c:member:`PyConfig.filesystem_errors` + * :c:var:`Py_UTF8Mode`: use :c:member:`PyPreConfig.utf8_mode` (see :c:func:`Py_PreInitialize`) + + The :c:func:`Py_InitializeFromConfig` API should be used with + :c:type:`PyConfig` instead. + (Contributed by Victor Stinner in :gh:`77782`.) + +* Creating :c:data:`immutable types ` with mutable + bases is deprecated and will be disabled in Python 3.14. + +* The ``structmember.h`` header is deprecated, though it continues to be + available and there are no plans to remove it. + + Its contents are now available just by including ``Python.h``, + with a ``Py`` prefix added if it was missing: + + - :c:struct:`PyMemberDef`, :c:func:`PyMember_GetOne` and + :c:func:`PyMember_SetOne` + - Type macros like :c:macro:`Py_T_INT`, :c:macro:`Py_T_DOUBLE`, etc. + (previously ``T_INT``, ``T_DOUBLE``, etc.) + - The flags :c:macro:`Py_READONLY` (previously ``READONLY``) and + :c:macro:`Py_AUDIT_READ` (previously all uppercase) + + Several items are not exposed from ``Python.h``: + + - :c:macro:`T_OBJECT` (use :c:macro:`Py_T_OBJECT_EX`) + - :c:macro:`T_NONE` (previously undocumented, and pretty quirky) + - The macro ``WRITE_RESTRICTED`` which does nothing. + - The macros ``RESTRICTED`` and ``READ_RESTRICTED``, equivalents of + :c:macro:`Py_AUDIT_READ`. + - In some configurations, ```` is not included from ``Python.h``. + It should be included manually when using ``offsetof()``. + + The deprecated header continues to provide its original + contents under the original names. + Your old code can stay unchanged, unless the extra include and non-namespaced + macros bother you greatly. + + (Contributed in :gh:`47146` by Petr Viktorin, based on + earlier work by Alexander Belopolsky and Matthias Braun.) + + +Removed +------- + +* Remove the ``token.h`` header file. There was never any public tokenizer C + API. The ``token.h`` header file was only designed to be used by Python + internals. + (Contributed by Victor Stinner in :gh:`92651`.) + +* Legacy Unicode APIs have been removed. See :pep:`623` for detail. + + * :c:macro:`PyUnicode_WCHAR_KIND` + * :c:func:`PyUnicode_AS_UNICODE` + * :c:func:`PyUnicode_AsUnicode` + * :c:func:`PyUnicode_AsUnicodeAndSize` + * :c:func:`PyUnicode_AS_DATA` + * :c:func:`PyUnicode_FromUnicode` + * :c:func:`PyUnicode_GET_SIZE` + * :c:func:`PyUnicode_GetSize` + * :c:func:`PyUnicode_GET_DATA_SIZE` + +* Remove the ``PyUnicode_InternImmortal()`` function and the + ``SSTATE_INTERNED_IMMORTAL`` macro. + (Contributed by Victor Stinner in :gh:`85858`.) + +* Remove ``Jython`` compatibility hacks from several stdlib modules and tests. + (Contributed by Nikita Sobolev in :gh:`99482`.) + +* Remove ``_use_broken_old_ctypes_structure_semantics_`` flag + from :mod:`ctypes` module. + (Contributed by Nikita Sobolev in :gh:`99285`.) diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index 09ec58eca5b..1b1455b72b9 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -48,10 +48,11 @@ This saves the maintainer the effort of going through the SVN log when researching a change. -This article explains the new features in Python 3.2 as compared to 3.1. It +This article explains the new features in Python 3.2 as compared to 3.1. +Python 3.2 was released on February 20, 2011. It focuses on a few highlights and gives a few examples. For full details, see the `Misc/NEWS -`_ +`__ file. .. seealso:: @@ -321,7 +322,7 @@ aspects that are visible to the programmer: * The tag that is unique to each interpreter is accessible from the :mod:`imp` module: - >>> import imp + >>> import imp # doctest: +SKIP >>> imp.get_tag() # doctest: +SKIP 'cpython-32' @@ -329,7 +330,7 @@ aspects that are visible to the programmer: be smarter. It is no longer sufficient to simply strip the "c" from a ".pyc" filename. Instead, use the new functions in the :mod:`imp` module: - >>> imp.source_from_cache('c:/py32/lib/__pycache__/collections.cpython-32.pyc') + >>> imp.source_from_cache('c:/py32/lib/__pycache__/collections.cpython-32.pyc') # doctest: +SKIP 'c:/py32/lib/collections.py' >>> imp.cache_from_source('c:/py32/lib/collections.py') # doctest: +SKIP 'c:/py32/lib/__pycache__/collections.cpython-32.pyc' @@ -467,6 +468,7 @@ Some smaller changes made to the core Python language are: >>> class LowerCasedDict(dict): ... def __getitem__(self, key): ... return dict.__getitem__(self, key.lower()) + ... >>> lcd = LowerCasedDict(part='widgets', quantity=10) >>> 'There are {QUANTITY} {Part} in stock'.format_map(lcd) 'There are 10 widgets in stock' @@ -474,6 +476,7 @@ Some smaller changes made to the core Python language are: >>> class PlaceholderDict(dict): ... def __missing__(self, key): ... return '<{}>'.format(key) + ... >>> 'Hello {name}, welcome to {location}'.format_map(PlaceholderDict()) 'Hello , welcome to ' @@ -744,7 +747,8 @@ Two methods have been deprecated: * :meth:`xml.etree.ElementTree.getiterator` use ``Element.iter`` instead. For details of the update, see `Introducing ElementTree -`_ on Fredrik Lundh's website. +`_ +on Fredrik Lundh's website. (Contributed by Florent Xicluna and Fredrik Lundh, :issue:`6472`.) @@ -971,7 +975,7 @@ sites do not finish before midnight, the barrier times-out and the ballots are sealed and deposited in a queue for later handling. See `Barrier Synchronization Patterns -`_ +`_ for more examples of how barriers can be used in parallel computing. Also, there is a simple but thorough explanation of barriers in `The Little Book of Semaphores `_, *section 3.6*. @@ -1645,7 +1649,7 @@ for secure (encrypted, authenticated) internet connections: * The :func:`ssl.wrap_socket` constructor function now takes a *ciphers* argument. The *ciphers* string lists the allowed encryption algorithms using the format described in the `OpenSSL documentation - `__. + `__. * When linked against recent versions of OpenSSL, the :mod:`ssl` module now supports the Server Name Indication extension to the TLS protocol, allowing @@ -1744,7 +1748,7 @@ names. instead of module names for running specific tests (:issue:`10620`). The new test discovery can find tests within packages, locating any test importable from the top-level directory. The top-level directory can be specified with - the `-t` option, a pattern for matching files with ``-p``, and a directory to + the ``-t`` option, a pattern for matching files with ``-p``, and a directory to start discovery with ``-s``: .. code-block:: shell-session @@ -1855,7 +1859,7 @@ asyncore :class:`asyncore.dispatcher` now provides a :meth:`~asyncore.dispatcher.handle_accepted()` method -returning a `(sock, addr)` pair which is called when a connection has actually +returning a ``(sock, addr)`` pair which is called when a connection has actually been established with a new remote endpoint. This is supposed to be used as a replacement for old :meth:`~asyncore.dispatcher.handle_accept()` and avoids the user to call :meth:`~asyncore.dispatcher.accept()` directly. @@ -1884,6 +1888,7 @@ inspect >>> from inspect import getgeneratorstate >>> def gen(): ... yield 'demo' + ... >>> g = gen() >>> getgeneratorstate(g) 'GEN_CREATED' @@ -2054,7 +2059,7 @@ information: such as "3.2". It also provides access to the paths and variables corresponding to one of -seven named schemes used by :mod:`distutils`. Those include *posix_prefix*, +seven named schemes used by ``distutils``. Those include *posix_prefix*, *posix_home*, *posix_user*, *nt*, *nt_user*, *os2*, *os2_home*: * :func:`~sysconfig.get_paths` makes a dictionary containing installation paths @@ -2416,7 +2421,7 @@ Unicode ======= Python has been updated to `Unicode 6.0.0 -`_. The update to the standard adds +`_. The update to the standard adds over 2,000 new characters including `emoji `_ symbols which are important for mobile phones. @@ -2424,7 +2429,7 @@ In addition, the updated standard has altered the character properties for two Kannada characters (U+0CF1, U+0CF2) and one New Tai Lue numeric character (U+19DA), making the former eligible for use in identifiers while disqualifying the latter. For more information, see `Unicode Character Database Changes -`_. +`_. Codecs @@ -2504,7 +2509,7 @@ IDLE Code Repository =============== -In addition to the existing Subversion code repository at http://svn.python.org +In addition to the existing Subversion code repository at https://svn.python.org there is now a `Mercurial `_ repository at https://hg.python.org/\ . @@ -2590,10 +2595,12 @@ Changes to Python's build process and to the C API include: longer used and it had never been documented (:issue:`8837`). There were a number of other small changes to the C-API. See the -:source:`Misc/NEWS` file for a complete list. +`Misc/NEWS `__ +file for a complete list. Also, there were a number of updates to the Mac OS X build, see -:source:`Mac/BuildScript/README.txt` for details. For users running a 32/64-bit +`Mac/BuildScript/README.txt `_ +for details. For users running a 32/64-bit build, there is a known problem with the default Tcl/Tk on Mac OS X 10.6. Accordingly, we recommend installing an updated alternative such as `ActiveState Tcl/Tk 8.5.9 `_\. diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index 361e6db07c3..9e8d42469b0 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -101,7 +101,7 @@ PEP 405: Virtual Environments Virtual environments help create separate Python setups while sharing a system-wide base install, for ease of maintenance. Virtual environments -have their own set of private site packages (i.e. locally-installed +have their own set of private site packages (i.e. locally installed libraries), and are optionally segregated from the system-wide site packages. Their concept and implementation are inspired by the popular ``virtualenv`` third-party package, but benefit from tighter integration @@ -560,6 +560,7 @@ Example with (non-bound) methods:: >>> class C: ... def meth(self): ... pass + ... >>> C.meth.__name__ 'meth' >>> C.meth.__qualname__ @@ -898,7 +899,7 @@ an IP address associated with a specific IP subnet). lzma ---- -The newly-added :mod:`lzma` module provides data compression and decompression +The newly added :mod:`lzma` module provides data compression and decompression using the LZMA algorithm, including support for the ``.xz`` and ``.lzma`` file formats. @@ -932,7 +933,7 @@ it can now be used as a class decorator (:issue:`10868`). array ----- -The :mod:`array` module supports the :c:type:`long long` type using ``q`` and +The :mod:`array` module supports the :c:expr:`long long` type using ``q`` and ``Q`` type codes. (Contributed by Oren Tirosh and Hirokazu Yamamoto in :issue:`1172711`.) @@ -1096,7 +1097,7 @@ decimal C-module and libmpdec written by Stefan Krah. The new C version of the decimal module integrates the high speed libmpdec -library for arbitrary precision correctly-rounded decimal floating point +library for arbitrary precision correctly rounded decimal floating point arithmetic. libmpdec conforms to IBM's General Decimal Arithmetic Specification. Performance gains range from 10x for database applications to 100x for @@ -1106,7 +1107,7 @@ the precision is user configurable, the exact figures may vary. For example, in integer bignum arithmetic the differences can be significantly higher. The following table is meant as an illustration. Benchmarks are available -at http://www.bytereef.org/mpdecimal/quickstart.html. +at https://www.bytereef.org/mpdecimal/quickstart.html. +---------+-------------+--------------+-------------+ | | decimal.py | _decimal | speedup | @@ -1158,8 +1159,8 @@ API changes in order to obtain a rounded or inexact value. -* The power function in decimal.py is always correctly-rounded. In the - C version, it is defined in terms of the correctly-rounded +* The power function in decimal.py is always correctly rounded. In the + C version, it is defined in terms of the correctly rounded :meth:`~decimal.Decimal.exp` and :meth:`~decimal.Decimal.ln` functions, but the final result is only "almost always correctly rounded". @@ -1898,7 +1899,7 @@ socket family on OS X. (Contributed by Michael Goderbauer in :issue:`13777`.) * New function :func:`~socket.sethostname` allows the hostname to be set - on unix systems if the calling process has sufficient privileges. + on Unix systems if the calling process has sufficient privileges. (Contributed by Ross Lagerwall in :issue:`10866`.) @@ -2137,7 +2138,7 @@ zlib ---- New attribute :attr:`zlib.Decompress.eof` makes it possible to distinguish -between a properly-formed compressed stream and an incomplete or truncated one. +between a properly formed compressed stream and an incomplete or truncated one. (Contributed by Nadeem Vawda in :issue:`12646`.) New attribute :attr:`zlib.ZLIB_RUNTIME_VERSION` reports the version string of @@ -2267,7 +2268,7 @@ The :c:type:`Py_UNICODE` has been deprecated by :pep:`393` and will be removed in Python 4. All functions using this type are deprecated: Unicode functions and methods using :c:type:`Py_UNICODE` and -:c:type:`Py_UNICODE*` types: +:c:expr:`Py_UNICODE*` types: * :c:macro:`PyUnicode_FromUnicode`: use :c:func:`PyUnicode_FromWideChar` or :c:func:`PyUnicode_FromKindAndData` @@ -2389,10 +2390,10 @@ Porting Python code :attr:`sys.path_importer_cache` where it represents the use of implicit finders, but semantically it should not change anything. -* :class:`importlib.abc.Finder` no longer specifies a `find_module()` abstract +* :class:`importlib.abc.Finder` no longer specifies a ``find_module()`` abstract method that must be implemented. If you were relying on subclasses to implement that method, make sure to check for the method's existence first. - You will probably want to check for `find_loader()` first, though, in the + You will probably want to check for ``find_loader()`` first, though, in the case of working with :term:`path entry finders `. * :mod:`pkgutil` has been converted to use :mod:`importlib` internally. This diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst index 0405f2ba193..b7bb505a818 100644 --- a/Doc/whatsnew/3.4.rst +++ b/Doc/whatsnew/3.4.rst @@ -220,7 +220,7 @@ these commands by default, as long as, when invoked, they provide clear and simple directions on how to install them on that platform (usually using the system package manager). -__ https://www.python.org/dev/peps/pep-0453/#recommendations-for-downstream-distributors +__ https://peps.python.org/pep-0453/#recommendations-for-downstream-distributors .. note:: @@ -247,7 +247,7 @@ projects. However, as this migration is currently still incomplete, the legacy versions of those guides remaining available as :ref:`install-index` -and :ref:`distutils-index`. +and :ref:`setuptools-index`. .. seealso:: @@ -409,7 +409,7 @@ Some smaller changes made to the core Python language are: evaluating has no elements. (Contributed by Julian Berman in :issue:`18111`.) -* Module objects are now :mod:`weakref`'able. +* Module objects are now :ref:`weakly referenceable `. * Module ``__file__`` attributes (and related values) should now always contain absolute paths by default, with the sole exception of @@ -1113,8 +1113,8 @@ with additional speedups by Antoine Pitrou in :issue:`19219`.) mmap ---- -mmap objects can now be :mod:`weakref`\ ed. (Contributed by Valerie Lambert in -:issue:`4885`.) +mmap objects are now :ref:`weakly referenceable `. +(Contributed by Valerie Lambert in :issue:`4885`.) multiprocessing @@ -1659,7 +1659,7 @@ The :class:`~unittest.TestCase` class has a new method, :keyword:`with` block becomes a "sub-test". This context manager allows a test method to dynamically generate subtests by, say, calling the ``subTest`` context manager inside a loop. A single test method can thereby produce an -indefinite number of separately-identified and separately-counted tests, all of +indefinite number of separately identified and separately counted tests, all of which will run even if one or more of them fail. For example:: class NumbersTest(unittest.TestCase): @@ -1963,7 +1963,7 @@ Other Improvements `_ will build python, run the test suite, and generate an HTML coverage report for the C codebase using ``gcov`` and `lcov - `_. + `_. * The ``-R`` option to the :ref:`python regression test suite ` now also checks for memory allocation leaks, using @@ -2056,7 +2056,7 @@ Significant Optimizations ``malloc`` in ``obmalloc``. Artificial benchmarks show about a 3% memory savings. -* :func:`os.urandom` now uses a lazily-opened persistent file descriptor +* :func:`os.urandom` now uses a lazily opened persistent file descriptor so as to avoid using many file descriptors when run in parallel from multiple threads. (Contributed by Antoine Pitrou in :issue:`18756`.) diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst index 1defee4090f..f872579ef54 100644 --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -1079,7 +1079,7 @@ Both the ``build`` and ``build_ext`` commands now accept a ``-j`` option to enable parallel building of extension modules. (Contributed by Antoine Pitrou in :issue:`5309`.) -The :mod:`distutils` module now supports ``xz`` compression, and can be +The ``distutils`` module now supports ``xz`` compression, and can be enabled by passing ``xztar`` as an argument to ``bdist --format``. (Contributed by Serhiy Storchaka in :issue:`16314`.) @@ -1253,7 +1253,7 @@ imghdr ------ The :func:`~imghdr.what` function now recognizes the -`OpenEXR `_ format +`OpenEXR `_ format (contributed by Martin Vignali and Claudiu Popa in :issue:`20295`), and the `WebP `_ format (contributed by Fabrice Aneche and Claudiu Popa in :issue:`20197`.) @@ -1977,7 +1977,7 @@ unicodedata ----------- The :mod:`unicodedata` module now uses data from `Unicode 8.0.0 -`_. +`_. unittest @@ -2469,11 +2469,11 @@ Changes in the Python API ``opt-`` tag in ``.pyc`` file names. The :func:`importlib.util.cache_from_source` has gained an *optimization* parameter to help control the ``opt-`` tag. Because of this, the - *debug_override* parameter of the function is now deprecated. `.pyo` files + *debug_override* parameter of the function is now deprecated. ``.pyo`` files are also no longer supported as a file argument to the Python interpreter and thus serve no purpose when distributed on their own (i.e. sourceless code distribution). Due to the fact that the magic number for bytecode has changed - in Python 3.5, all old `.pyo` files from previous versions of Python are + in Python 3.5, all old ``.pyo`` files from previous versions of Python are invalid regardless of this PEP. * The :mod:`socket` module now exports the :data:`~socket.CAN_RAW_FD_FRAMES` diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst index d7884ea30d7..e4294c88b58 100644 --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -162,10 +162,10 @@ Windows improvements: * A ``._pth`` file can be added to force isolated mode and fully specify all search paths to avoid registry and environment lookup. See - :ref:`the documentation ` for more information. + :ref:`the documentation ` for more information. * A ``python36.zip`` file now works as a landmark to infer - :envvar:`PYTHONHOME`. See :ref:`the documentation ` for + :envvar:`PYTHONHOME`. See :ref:`the documentation ` for more information. @@ -960,8 +960,8 @@ contextlib The :class:`contextlib.AbstractContextManager` class has been added to provide an abstract base class for context managers. It provides a -sensible default implementation for `__enter__()` which returns -``self`` and leaves `__exit__()` an abstract method. A matching +sensible default implementation for ``__enter__()`` which returns +``self`` and leaves ``__exit__()`` an abstract method. A matching class has been added to the :mod:`typing` module as :class:`typing.ContextManager`. (Contributed by Brett Cannon in :issue:`25609`.) @@ -1012,7 +1012,7 @@ distutils --------- The ``default_format`` attribute has been removed from -:class:`distutils.command.sdist.sdist` and the ``formats`` +``distutils.command.sdist.sdist`` and the ``formats`` attribute defaults to ``['gztar']``. Although not anticipated, any code relying on the presence of ``default_format`` may need to be adapted. See :issue:`27819` for more details. @@ -1388,7 +1388,7 @@ are treated as punctuation. site ---- -When specifying paths to add to :attr:`sys.path` in a `.pth` file, +When specifying paths to add to :attr:`sys.path` in a ``.pth`` file, you may now specify file paths on top of directories (e.g. zip files). (Contributed by Wolfgang Langner in :issue:`26587`). @@ -1422,7 +1422,7 @@ The socket module now supports the address family Victor Stinner.) New Linux constants ``TCP_USER_TIMEOUT`` and ``TCP_CONGESTION`` were added. -(Contributed by Omar Sandoval, issue:`26273`). +(Contributed by Omar Sandoval, :issue:`26273`). socketserver @@ -1644,7 +1644,7 @@ unicodedata ----------- The :mod:`unicodedata` module now uses data from `Unicode 9.0.0 -`_. +`_. (Contributed by Benjamin Peterson.) @@ -1986,7 +1986,7 @@ distutils ~~~~~~~~~ The undocumented ``extra_path`` argument to the -:class:`~distutils.Distribution` constructor is now considered deprecated +``distutils.Distribution`` constructor is now considered deprecated and will raise a warning if set. Support for this parameter will be removed in a future Python release. See :issue:`27919` for details. @@ -2052,6 +2052,8 @@ tkinter The :mod:`tkinter.tix` module is now deprecated. :mod:`tkinter` users should use :mod:`tkinter.ttk` instead. +.. _whatsnew36-venv: + venv ~~~~ @@ -2117,7 +2119,8 @@ API and Feature Removals platform specific ``Lib/plat-*/`` directories, but were chronically out of date, inconsistently available across platforms, and unmaintained. The script that created these modules is still available in the source - distribution at :source:`Tools/scripts/h2py.py`. + distribution at `Tools/scripts/h2py.py + `_. * The deprecated ``asynchat.fifo`` class has been removed. @@ -2242,7 +2245,7 @@ Changes in the Python API accepting additional keyword arguments will need to adjust their calls to :meth:`type.__new__` (whether direct or via :class:`super`) accordingly. -* In :class:`distutils.command.sdist.sdist`, the ``default_format`` +* In ``distutils.command.sdist.sdist``, the ``default_format`` attribute has been removed and is no longer honored. Instead, the gzipped tarfile format is the default on all platforms and no platform-specific selection is made. diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 1199535c84d..df3b636cb9e 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -290,21 +290,21 @@ PEP 539: New C API for Thread-Local Storage While Python provides a C API for thread-local storage support; the existing :ref:`Thread Local Storage (TLS) API ` has used -:c:type:`int` to represent TLS keys across all platforms. This has not -generally been a problem for officially-support platforms, but that is neither +:c:expr:`int` to represent TLS keys across all platforms. This has not +generally been a problem for officially support platforms, but that is neither POSIX-compliant, nor portable in any practical sense. :pep:`539` changes this by providing a new :ref:`Thread Specific Storage (TSS) API ` to CPython which supersedes use of the existing TLS API within the CPython interpreter, while deprecating the existing -API. The TSS API uses a new type :c:type:`Py_tss_t` instead of :c:type:`int` +API. The TSS API uses a new type :c:type:`Py_tss_t` instead of :c:expr:`int` to represent TSS keys--an opaque type the definition of which may depend on the underlying TLS implementation. Therefore, this will allow to build CPython on platforms where the native TLS key is defined in a way that cannot be safely -cast to :c:type:`int`. +cast to :c:expr:`int`. Note that on platforms where the native TLS key is defined in a way that cannot -be safely cast to :c:type:`int`, all functions of the existing TLS API will be +be safely cast to :c:expr:`int`, all functions of the existing TLS API will be no-op and immediately return failure. This indicates clearly that the old API is not supported on platforms where it cannot be used reliably, and that no effort will be made to add such support. @@ -353,7 +353,7 @@ module: The new functions return the number of nanoseconds as an integer value. -`Measurements `_ +`Measurements `_ show that on Linux and Windows the resolution of :func:`time.time_ns` is approximately 3 times better than that of :func:`time.time`. @@ -538,7 +538,7 @@ Other Language Changes * The new :option:`-X` ``importtime`` option or the :envvar:`PYTHONPROFILEIMPORTTIME` environment variable can be used to show the timing of each module import. - (Contributed by Victor Stinner in :issue:`31415`.) + (Contributed by Inada Naoki in :issue:`31415`.) New Modules @@ -611,7 +611,7 @@ Contributed by Barry Warsaw and Brett Cannon in :issue:`32248`. .. seealso:: - `importlib_resources `_ + `importlib_resources `_ -- a PyPI backport for earlier Python versions. @@ -1175,7 +1175,7 @@ of :func:`os.writev` and :func:`os.pwrite`). (Contributed by Pablo Galindo in :issue:`31368`.) The mode argument of :func:`os.makedirs` no longer affects the file -permission bits of newly-created intermediate-level directories. +permission bits of newly created intermediate-level directories. (Contributed by Serhiy Storchaka in :issue:`19930`.) :func:`os.dup2` now returns the new file descriptor. Previously, ``None`` @@ -1507,7 +1507,7 @@ unicodedata ----------- The internal :mod:`unicodedata` database has been upgraded to use `Unicode 11 -`_. (Contributed by Benjamin +`_. (Contributed by Benjamin Peterson.) @@ -1708,12 +1708,12 @@ Contributed by Paul Ganssle in :issue:`10381`. The type of results of :c:func:`PyThread_start_new_thread` and :c:func:`PyThread_get_thread_ident`, and the *id* parameter of -:c:func:`PyThreadState_SetAsyncExc` changed from :c:type:`long` to -:c:type:`unsigned long`. +:c:func:`PyThreadState_SetAsyncExc` changed from :c:expr:`long` to +:c:expr:`unsigned long`. (Contributed by Serhiy Storchaka in :issue:`6532`.) :c:func:`PyUnicode_AsWideCharString` now raises a :exc:`ValueError` if the -second argument is ``NULL`` and the :c:type:`wchar_t*` string contains null +second argument is ``NULL`` and the :c:expr:`wchar_t*` string contains null characters. (Contributed by Serhiy Storchaka in :issue:`30708`.) Changes to the startup sequence and the management of dynamic memory @@ -1906,7 +1906,7 @@ Other CPython Implementation Changes variables were defined. Previously, the order was undefined. (Contributed by Raymond Hettinger in :issue:`32690`.) -* The :mod:`distutils` ``upload`` command no longer tries to change CR +* The ``distutils`` ``upload`` command no longer tries to change CR end-of-line characters to CRLF. This fixes a corruption issue with sdists that ended with a byte equivalent to CR. (Contributed by Bo Bayles in :issue:`32304`.) @@ -2120,7 +2120,8 @@ Platform Support Removals of other LTS Linux releases (e.g. RHEL/CentOS 7.5, SLES 12-SP3), use OpenSSL 1.0.2 or later, and remain supported in the default build configuration. - CPython's own :source:`CI configuration file <.travis.yml>` provides an + CPython's own `CI configuration file + `_ provides an example of using the SSL :source:`compatibility testing infrastructure ` in CPython's test suite to build and link against OpenSSL 1.1.0 rather than an @@ -2180,7 +2181,7 @@ The following features and APIs have been removed from Python 3.7: :func:`ssl.wrap_socket` or :class:`ssl.SSLContext`. (Contributed by Christian Heimes in :issue:`32951`.) -* The unused :mod:`distutils` ``install_misc`` command has been removed. +* The unused ``distutils`` ``install_misc`` command has been removed. (Contributed by Eric N. Vander Weele in :issue:`29218`.) @@ -2295,7 +2296,7 @@ Changes in the Python API (Contributed by Serhiy Storchaka in :issue:`29192`.) * The *mode* argument of :func:`os.makedirs` no longer affects the file - permission bits of newly-created intermediate-level directories. + permission bits of newly created intermediate-level directories. To set their file permission bits you can set the umask before invoking ``makedirs()``. (Contributed by Serhiy Storchaka in :issue:`19930`.) @@ -2474,7 +2475,7 @@ Windows-only Changes The file used to override :data:`sys.path` is now called ``._pth`` instead of ``'sys.path'``. -See :ref:`finding_modules` for more information. +See :ref:`windows_finding_modules` for more information. (Contributed by Steve Dower in :issue:`28137`.) @@ -2496,7 +2497,7 @@ number of other issues). Some known details affected: * :c:func:`PySys_AddWarnOptionUnicode` is not currently usable by embedding applications due to the requirement to create a Unicode object prior to - calling `Py_Initialize`. Use :c:func:`PySys_AddWarnOption` instead. + calling ``Py_Initialize``. Use :c:func:`PySys_AddWarnOption` instead. * warnings filters added by an embedding application with :c:func:`PySys_AddWarnOption` should now more consistently take precedence diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 7c293a50189..37a6cf24e54 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -45,6 +45,7 @@ :Editor: Raymond Hettinger This article explains the new features in Python 3.8, compared to 3.7. +Python 3.8 was released on October 14, 2019. For full details, see the :ref:`changelog `. .. testsetup:: @@ -121,8 +122,8 @@ Positional-only parameters There is a new function parameter syntax ``/`` to indicate that some function parameters must be specified positionally and cannot be used as keyword arguments. This is the same notation shown by ``help()`` for C -functions annotated with Larry Hastings' `Argument Clinic -`_ tool. +functions annotated with Larry Hastings' +:ref:`Argument Clinic ` tool. In the following example, parameters *a* and *b* are positional-only, while *c* or *d* can be positional or keyword, and *e* or *f* are @@ -249,6 +250,7 @@ Android and Cygwin, whose cases are handled by the script); this change is backward incompatible on purpose. (Contributed by Victor Stinner in :issue:`36721`.) +.. _bpo-36817-whatsnew: f-strings support ``=`` for self-documenting expressions and debugging ---------------------------------------------------------------------- @@ -1087,6 +1089,9 @@ contain characters unrepresentable at the OS level. Added :meth:`pathlib.Path.link_to()` which creates a hard link pointing to a path. (Contributed by Joannah Nanjekye in :issue:`26978`) +Note that ``link_to`` was deprecated in 3.10 and removed in 3.12 in +favor of a ``hardlink_to`` method added in 3.10 which matches the +semantics of the existing ``symlink_to`` method. pickle @@ -1346,7 +1351,7 @@ unicodedata ----------- The :mod:`unicodedata` module has been upgraded to use the `Unicode 12.1.0 -`_ release. +`_ release. New function :func:`~unicodedata.is_normalized` can be used to verify a string is in a specific normal form, often much faster than by actually normalizing @@ -1490,7 +1495,7 @@ Optimizations first introduced in Python 3.4. It offers better performance and smaller size compared to Protocol 3 available since Python 3.0. -* Removed one ``Py_ssize_t`` member from ``PyGC_Head``. All GC tracked +* Removed one :c:type:`Py_ssize_t` member from ``PyGC_Head``. All GC tracked objects (e.g. tuple, list, dict) size is reduced 4 or 8 bytes. (Contributed by Inada Naoki in :issue:`33597`.) @@ -2004,11 +2009,13 @@ Changes in the Python API ``replace()`` method of :class:`types.CodeType` can be used to make the code future-proof. +* The parameter ``digestmod`` for :func:`hmac.new` no longer uses the MD5 digest + by default. Changes in the C API -------------------- -* The :c:type:`PyCompilerFlags` structure got a new *cf_feature_version* +* The :c:struct:`PyCompilerFlags` structure got a new *cf_feature_version* field. It should be initialized to ``PY_MINOR_VERSION``. The field is ignored by default, and is used if and only if ``PyCF_ONLY_AST`` flag is set in *cf_flags*. diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 0d514084d6c..e974ee3a3f7 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -2,8 +2,6 @@ What's New In Python 3.9 **************************** -:Release: |release| -:Date: |today| :Editor: Åukasz Langa .. Rules for maintenance: @@ -45,7 +43,7 @@ when researching a change. This article explains the new features in Python 3.9, compared to 3.8. -Python 3.9 was released on October 5th, 2020. +Python 3.9 was released on October 5, 2020. For full details, see the :ref:`changelog `. @@ -484,8 +482,25 @@ Najera in :issue:`38944`.) Added keywords to module name completion list. (Contributed by Terry J. Reedy in :issue:`37765`.) +New in 3.9 maintenance releases + +Make IDLE invoke :func:`sys.excepthook` (when started without '-n'). +User hooks were previously ignored. (Contributed by Ken Hilton in +:issue:`43008`.) + The changes above have been backported to 3.8 maintenance releases. +Rearrange the settings dialog. Split the General tab into Windows +and Shell/Ed tabs. Move help sources, which extend the Help menu, to the +Extensions tab. Make space for new options and shorten the dialog. The +latter makes the dialog better fit small screens. (Contributed by Terry Jan +Reedy in :issue:`40468`.) Move the indent space setting from the Font tab to +the new Windows tab. (Contributed by Mark Roseman and Terry Jan Reedy in +:issue:`33962`.) + +Apply syntax highlighting to ``.pyi`` files. (Contributed by Alex +Waygood and Terry Jan Reedy in :issue:`45447`.) + imaplib ------- @@ -756,7 +771,7 @@ Optimizations Stinner in :issue:`38061`.) * :c:func:`PyLong_FromDouble` is now up to 1.87x faster for values that - fit into :c:type:`long`. + fit into :c:expr:`long`. (Contributed by Sergey Fedoseev in :issue:`37986`.) * A number of Python builtins (:class:`range`, :class:`tuple`, :class:`set`, @@ -1232,7 +1247,7 @@ Build Changes of macOS. If a macOS SDK is explicitly configured, by using :option:`--enable-universalsdk` or ``-isysroot``, only the SDK itself is searched. The default behavior can still be overridden with - :option:`--with-tcltk-includes` and :option:`--with-tcltk-libs`. + ``--with-tcltk-includes`` and ``--with-tcltk-libs``. (Contributed by Ned Deily in :issue:`34956`.) * Python can now be built for Windows 10 ARM64. diff --git a/Doc/whatsnew/index.rst b/Doc/whatsnew/index.rst index c787cdb0f71..bfee225791e 100644 --- a/Doc/whatsnew/index.rst +++ b/Doc/whatsnew/index.rst @@ -11,6 +11,7 @@ anyone wishing to stay up-to-date after a new release. .. toctree:: :maxdepth: 2 + 3.12.rst 3.11.rst 3.10.rst 3.9.rst diff --git a/Grammar/python.gram b/Grammar/python.gram index 60fbc400cf2..2498251293e 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -194,7 +194,10 @@ yield_stmt[stmt_ty]: y=yield_expr { _PyAST_Expr(y, EXTRA) } assert_stmt[stmt_ty]: 'assert' a=expression b=[',' z=expression { z }] { _PyAST_Assert(a, b, EXTRA) } -import_stmt[stmt_ty]: import_name | import_from +import_stmt[stmt_ty]: + | invalid_import + | import_name + | import_from # Import statements # ----------------- @@ -249,7 +252,7 @@ class_def[stmt_ty]: class_def_raw[stmt_ty]: | invalid_class_def_raw - | 'class' a=NAME b=['(' z=[arguments] ')' { z }] &&':' c=block { + | 'class' a=NAME b=['(' z=[arguments] ')' { z }] ':' c=block { _PyAST_ClassDef(a->v.Name.id, (b) ? ((expr_ty) b)->v.Call.args : NULL, (b) ? ((expr_ty) b)->v.Call.keywords : NULL, @@ -287,9 +290,9 @@ params[arguments_ty]: parameters[arguments_ty]: | a=slash_no_default b[asdl_arg_seq*]=param_no_default* c=param_with_default* d=[star_etc] { - _PyPegen_make_arguments(p, a, NULL, b, c, d) } + CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _PyPegen_make_arguments(p, a, NULL, b, c, d)) } | a=slash_with_default b=param_with_default* c=[star_etc] { - _PyPegen_make_arguments(p, NULL, a, NULL, b, c) } + CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _PyPegen_make_arguments(p, NULL, a, NULL, b, c)) } | a[asdl_arg_seq*]=param_no_default+ b=param_with_default* c=[star_etc] { _PyPegen_make_arguments(p, NULL, NULL, a, b, c) } | a=param_with_default+ b=[star_etc] { _PyPegen_make_arguments(p, NULL, NULL, NULL, a, b)} @@ -306,14 +309,18 @@ slash_with_default[SlashWithDefault*]: | a=param_no_default* b=param_with_default+ '/' &')' { _PyPegen_slash_with_default(p, (asdl_arg_seq *)a, b) } star_etc[StarEtc*]: + | invalid_star_etc | '*' a=param_no_default b=param_maybe_default* c=[kwds] { _PyPegen_star_etc(p, a, b, c) } + | '*' a=param_no_default_star_annotation b=param_maybe_default* c=[kwds] { + _PyPegen_star_etc(p, a, b, c) } | '*' ',' b=param_maybe_default+ c=[kwds] { _PyPegen_star_etc(p, NULL, b, c) } | a=kwds { _PyPegen_star_etc(p, NULL, NULL, a) } - | invalid_star_etc -kwds[arg_ty]: '**' a=param_no_default { a } +kwds[arg_ty]: + | invalid_kwds + | '**' a=param_no_default { a } # One parameter. This *includes* a following comma and type comment. # @@ -331,6 +338,9 @@ kwds[arg_ty]: '**' a=param_no_default { a } param_no_default[arg_ty]: | a=param ',' tc=TYPE_COMMENT? { _PyPegen_add_type_comment_to_arg(p, a, tc) } | a=param tc=TYPE_COMMENT? &')' { _PyPegen_add_type_comment_to_arg(p, a, tc) } +param_no_default_star_annotation[arg_ty]: + | a=param_star_annotation ',' tc=TYPE_COMMENT? { _PyPegen_add_type_comment_to_arg(p, a, tc) } + | a=param_star_annotation tc=TYPE_COMMENT? &')' { _PyPegen_add_type_comment_to_arg(p, a, tc) } param_with_default[NameDefaultPair*]: | a=param c=default ',' tc=TYPE_COMMENT? { _PyPegen_name_default_pair(p, a, c, tc) } | a=param c=default tc=TYPE_COMMENT? &')' { _PyPegen_name_default_pair(p, a, c, tc) } @@ -338,8 +348,10 @@ param_maybe_default[NameDefaultPair*]: | a=param c=default? ',' tc=TYPE_COMMENT? { _PyPegen_name_default_pair(p, a, c, tc) } | a=param c=default? tc=TYPE_COMMENT? &')' { _PyPegen_name_default_pair(p, a, c, tc) } param[arg_ty]: a=NAME b=annotation? { _PyAST_arg(a->v.Name.id, b, NULL, EXTRA) } +param_star_annotation[arg_ty]: a=NAME b=star_annotation { _PyAST_arg(a->v.Name.id, b, NULL, EXTRA) } annotation[expr_ty]: ':' a=expression { a } -default[expr_ty]: '=' a=expression { a } +star_annotation[expr_ty]: ':' a=star_expression { a } +default[expr_ty]: '=' a=expression { a } | invalid_default # If statement # ------------ @@ -370,9 +382,9 @@ while_stmt[stmt_ty]: for_stmt[stmt_ty]: | invalid_for_stmt - | 'for' t=star_targets 'in' ~ ex=star_expressions &&':' tc=[TYPE_COMMENT] b=block el=[else_block] { + | 'for' t=star_targets 'in' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] { _PyAST_For(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA) } - | ASYNC 'for' t=star_targets 'in' ~ ex=star_expressions &&':' tc=[TYPE_COMMENT] b=block el=[else_block] { + | ASYNC 'for' t=star_targets 'in' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] { CHECK_VERSION(stmt_ty, 5, "Async for loops are", _PyAST_AsyncFor(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA)) } | invalid_for_target @@ -382,7 +394,7 @@ for_stmt[stmt_ty]: with_stmt[stmt_ty]: | invalid_with_stmt_indent | 'with' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' b=block { - _PyAST_With(a, b, NULL, EXTRA) } + CHECK_VERSION(stmt_ty, 9, "Parenthesized context managers are", _PyAST_With(a, b, NULL, EXTRA)) } | 'with' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block { _PyAST_With(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) } | ASYNC 'with' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' b=block { @@ -403,6 +415,10 @@ try_stmt[stmt_ty]: | invalid_try_stmt | 'try' &&':' b=block f=finally_block { _PyAST_Try(b, NULL, NULL, f, EXTRA) } | 'try' &&':' b=block ex[asdl_excepthandler_seq*]=except_block+ el=[else_block] f=[finally_block] { _PyAST_Try(b, ex, el, f, EXTRA) } + | 'try' &&':' b=block ex[asdl_excepthandler_seq*]=except_star_block+ el=[else_block] f=[finally_block] { + CHECK_VERSION(stmt_ty, 11, "Exception groups are", + _PyAST_TryStar(b, ex, el, f, EXTRA)) } + # Except statement # ---------------- @@ -413,6 +429,11 @@ except_block[excepthandler_ty]: _PyAST_ExceptHandler(e, (t) ? ((expr_ty) t)->v.Name.id : NULL, b, EXTRA) } | 'except' ':' b=block { _PyAST_ExceptHandler(NULL, NULL, b, EXTRA) } | invalid_except_stmt +except_star_block[excepthandler_ty]: + | invalid_except_star_stmt_indent + | 'except' '*' e=expression t=['as' z=NAME { z }] ':' b=block { + _PyAST_ExceptHandler(e, (t) ? ((expr_ty) t)->v.Name.id : NULL, b, EXTRA) } + | invalid_except_stmt finally_block[asdl_stmt_seq*]: | invalid_finally_stmt | 'finally' &&':' a=block { a } @@ -455,7 +476,7 @@ or_pattern[pattern_ty]: | patterns[asdl_pattern_seq*]='|'.closed_pattern+ { asdl_seq_LEN(patterns) == 1 ? asdl_seq_GET(patterns, 0) : _PyAST_MatchOr(patterns, EXTRA) } -closed_pattern[pattern_ty]: +closed_pattern[pattern_ty] (memo): | literal_pattern | capture_pattern | wildcard_pattern @@ -542,7 +563,7 @@ maybe_star_pattern[pattern_ty]: | star_pattern | pattern -star_pattern[pattern_ty]: +star_pattern[pattern_ty] (memo): | '*' target=pattern_capture_target { _PyAST_MatchStar(target->v.Name.id, EXTRA) } | '*' wildcard_pattern { @@ -644,7 +665,9 @@ star_named_expression[expr_ty]: | named_expression assignment_expression[expr_ty]: - | a=NAME ':=' ~ b=expression { _PyAST_NamedExpr(CHECK(expr_ty, _PyPegen_set_expr_context(p, a, Store)), b, EXTRA) } + | a=NAME ':=' ~ b=expression { + CHECK_VERSION(expr_ty, 8, "Assignment expressions are", + _PyAST_NamedExpr(CHECK(expr_ty, _PyPegen_set_expr_context(p, a, Store)), b, EXTRA)) } named_expression[expr_ty]: | assignment_expression @@ -669,8 +692,8 @@ inversion[expr_ty] (memo): | 'not' a=inversion { _PyAST_UnaryOp(Not, a, EXTRA) } | comparison -# Comparisons operators -# --------------------- +# Comparison operators +# -------------------- comparison[expr_ty]: | a=bitwise_or b=compare_op_bitwise_or_pair+ { @@ -705,7 +728,7 @@ in_bitwise_or[CmpopExprPair*]: 'in' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, I isnot_bitwise_or[CmpopExprPair*]: 'is' 'not' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, IsNot, a) } is_bitwise_or[CmpopExprPair*]: 'is' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, Is, a) } -# Logical operators +# Bitwise operators # ----------------- bitwise_or[expr_ty]: @@ -773,7 +796,7 @@ primary[expr_ty]: slices[expr_ty]: | a=slice !',' { a } - | a[asdl_expr_seq*]=','.slice+ [','] { _PyAST_Tuple(a, Load, EXTRA) } + | a[asdl_expr_seq*]=','.(slice | starred_expression)+ [','] { _PyAST_Tuple(a, Load, EXTRA) } slice[expr_ty]: | a=[expression] ':' b=[expression] c=[':' d=[expression] { d }] { _PyAST_Slice(a, b, c, EXTRA) } @@ -812,9 +835,9 @@ lambda_params[arguments_ty]: # lambda_parameters[arguments_ty]: | a=lambda_slash_no_default b[asdl_arg_seq*]=lambda_param_no_default* c=lambda_param_with_default* d=[lambda_star_etc] { - _PyPegen_make_arguments(p, a, NULL, b, c, d) } + CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _PyPegen_make_arguments(p, a, NULL, b, c, d)) } | a=lambda_slash_with_default b=lambda_param_with_default* c=[lambda_star_etc] { - _PyPegen_make_arguments(p, NULL, a, NULL, b, c) } + CHECK_VERSION(arguments_ty, 8, "Positional-only parameters are", _PyPegen_make_arguments(p, NULL, a, NULL, b, c)) } | a[asdl_arg_seq*]=lambda_param_no_default+ b=lambda_param_with_default* c=[lambda_star_etc] { _PyPegen_make_arguments(p, NULL, NULL, a, b, c) } | a=lambda_param_with_default+ b=[lambda_star_etc] { _PyPegen_make_arguments(p, NULL, NULL, NULL, a, b)} @@ -829,14 +852,16 @@ lambda_slash_with_default[SlashWithDefault*]: | a=lambda_param_no_default* b=lambda_param_with_default+ '/' &':' { _PyPegen_slash_with_default(p, (asdl_arg_seq *)a, b) } lambda_star_etc[StarEtc*]: + | invalid_lambda_star_etc | '*' a=lambda_param_no_default b=lambda_param_maybe_default* c=[lambda_kwds] { _PyPegen_star_etc(p, a, b, c) } | '*' ',' b=lambda_param_maybe_default+ c=[lambda_kwds] { _PyPegen_star_etc(p, NULL, b, c) } | a=lambda_kwds { _PyPegen_star_etc(p, NULL, NULL, a) } - | invalid_lambda_star_etc -lambda_kwds[arg_ty]: '**' a=lambda_param_no_default { a } +lambda_kwds[arg_ty]: + | invalid_lambda_kwds + | '**' a=lambda_param_no_default { a } lambda_param_no_default[arg_ty]: | a=lambda_param ',' { a } @@ -932,6 +957,7 @@ kwargs[asdl_seq*]: | ','.kwarg_or_double_starred+ starred_expression[expr_ty]: + | invalid_starred_expression | '*' a=expression { _PyAST_Starred(a, Load, EXTRA) } kwarg_or_starred[KeywordOrStarred*]: @@ -1055,12 +1081,14 @@ func_type_comment[Token*]: invalid_arguments: | a=args ',' '*' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "iterable argument unpacking follows keyword argument unpacking") } | a=expression b=for_if_clauses ',' [args | expression for_if_clauses] { - RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, PyPegen_last_item(b, comprehension_ty)->target, "Generator expression must be parenthesized") } + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, _PyPegen_get_last_comprehension_item(PyPegen_last_item(b, comprehension_ty)), "Generator expression must be parenthesized") } | a=NAME b='=' expression for_if_clauses { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Maybe you meant '==' or ':=' instead of '='?")} + | (args ',')? a=NAME b='=' &(',' | ')') { + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "expected argument value expression")} | a=args b=for_if_clauses { _PyPegen_nonparen_genexp_in_call(p, a, b) } | args ',' a=expression b=for_if_clauses { - RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, asdl_seq_GET(b, b->size-1)->target, "Generator expression must be parenthesized") } + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, _PyPegen_get_last_comprehension_item(PyPegen_last_item(b, comprehension_ty)), "Generator expression must be parenthesized") } | a=args ',' args { _PyPegen_arguments_parsing_error(p, a) } invalid_kwarg: | a[Token*]=('True'|'False'|'None') b='=' { @@ -1070,7 +1098,10 @@ invalid_kwarg: | !(NAME '=') a=expression b='=' { RAISE_SYNTAX_ERROR_KNOWN_RANGE( a, b, "expression cannot contain assignment, perhaps you meant \"==\"?") } + | a='**' expression '=' b=expression { + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "cannot assign to keyword argument unpacking") } +# IMPORTANT: Note that the "_without_invalid" suffix causes the rule to not call invalid rules under it expression_without_invalid[expr_ty]: | a=disjunction 'if' b=disjunction 'else' c=expression { _PyAST_IfExp(b, a, c, EXTRA) } | disjunction @@ -1084,17 +1115,18 @@ invalid_expression: # !(NAME STRING) is not matched so we don't show this error with some invalid string prefixes like: kf"dsfsdf" # Soft keywords need to also be ignored because they can be parsed as NAME NAME | !(NAME STRING | SOFT_KEYWORD) a=disjunction b=expression_without_invalid { - _PyPegen_check_legacy_stmt(p, a) ? NULL : RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Perhaps you forgot a comma?") } + _PyPegen_check_legacy_stmt(p, a) ? NULL : p->tokens[p->mark-1]->level == 0 ? NULL : + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Perhaps you forgot a comma?") } | a=disjunction 'if' b=disjunction !('else'|':') { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "expected 'else' after 'if' expression") } -invalid_named_expression: +invalid_named_expression(memo): | a=expression ':=' expression { RAISE_SYNTAX_ERROR_KNOWN_LOCATION( a, "cannot use assignment expressions with %s", _PyPegen_get_expr_name(a)) } | a=NAME '=' b=bitwise_or !('='|':=') { - p->in_raw_rule ? NULL : RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Maybe you meant '==' or ':=' instead of '='?") } + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Maybe you meant '==' or ':=' instead of '='?") } | !(list|tuple|genexp|'True'|'None'|'False') a=bitwise_or b='=' bitwise_or !('='|':=') { - p->in_raw_rule ? NULL : RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot assign to %s here. Maybe you meant '==' instead of '='?", + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot assign to %s here. Maybe you meant '==' instead of '='?", _PyPegen_get_expr_name(a)) } invalid_assignment: @@ -1138,26 +1170,58 @@ invalid_dict_comprehension: | '{' a='**' bitwise_or for_if_clauses '}' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "dict unpacking cannot be used in dict comprehension") } invalid_parameters: - | param_no_default* invalid_parameters_helper a=param_no_default { - RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "non-default argument follows default argument") } + | a="/" ',' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "at least one argument must precede /") } + | (slash_no_default | slash_with_default) param_maybe_default* a='/' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "/ may appear only once") } + | slash_no_default? param_no_default* invalid_parameters_helper a=param_no_default { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "parameter without a default follows parameter with a default") } | param_no_default* a='(' param_no_default+ ','? b=')' { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "Function parameters cannot be parenthesized") } + | (slash_no_default | slash_with_default)? param_maybe_default* '*' (',' | param_no_default) param_maybe_default* a='/' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "/ must be ahead of *") } + | param_maybe_default+ '/' a='*' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "expected comma between / and *") } +invalid_default: + | a='=' &(')'|',') { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "expected default value expression") } +invalid_star_etc: + | a='*' (')' | ',' (')' | '**')) { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "named arguments must follow bare *") } + | '*' ',' TYPE_COMMENT { RAISE_SYNTAX_ERROR("bare * has associated type comment") } + | '*' param a='=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "var-positional argument cannot have default value") } + | '*' (param_no_default | ',') param_maybe_default* a='*' (param_no_default | ',') { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "* argument may appear only once") } +invalid_kwds: + | '**' param a='=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "var-keyword argument cannot have default value") } + | '**' param ',' a=param { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "arguments cannot follow var-keyword argument") } + | '**' param ',' a[Token*]=('*'|'**'|'/') { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "arguments cannot follow var-keyword argument") } invalid_parameters_helper: # This is only there to avoid type errors | a=slash_with_default { _PyPegen_singleton_seq(p, a) } | param_with_default+ invalid_lambda_parameters: - | lambda_param_no_default* invalid_lambda_parameters_helper a=lambda_param_no_default { - RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "non-default argument follows default argument") } + | a="/" ',' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "at least one argument must precede /") } + | (lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* a='/' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "/ may appear only once") } + | lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper a=lambda_param_no_default { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "parameter without a default follows parameter with a default") } | lambda_param_no_default* a='(' ','.lambda_param+ ','? b=')' { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "Lambda expression parameters cannot be parenthesized") } + | (lambda_slash_no_default | lambda_slash_with_default)? lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* a='/' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "/ must be ahead of *") } + | lambda_param_maybe_default+ '/' a='*' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "expected comma between / and *") } invalid_lambda_parameters_helper: | a=lambda_slash_with_default { _PyPegen_singleton_seq(p, a) } | lambda_param_with_default+ -invalid_star_etc: - | a='*' (')' | ',' (')' | '**')) { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "named arguments must follow bare *") } - | '*' ',' TYPE_COMMENT { RAISE_SYNTAX_ERROR("bare * has associated type comment") } invalid_lambda_star_etc: | '*' (':' | ',' (':' | '**')) { RAISE_SYNTAX_ERROR("named arguments must follow bare *") } + | '*' lambda_param a='=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "var-positional argument cannot have default value") } + | '*' (lambda_param_no_default | ',') lambda_param_maybe_default* a='*' (lambda_param_no_default | ',') { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "* argument may appear only once") } +invalid_lambda_kwds: + | '**' lambda_param a='=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "var-keyword argument cannot have default value") } + | '**' lambda_param ',' a=lambda_param { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "arguments cannot follow var-keyword argument") } + | '**' lambda_param ',' a[Token*]=('*'|'**'|'/') { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "arguments cannot follow var-keyword argument") } invalid_double_type_comments: | TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT { RAISE_SYNTAX_ERROR("Cannot have two type comments on def") } @@ -1174,13 +1238,17 @@ invalid_group: RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use starred expression here") } | '(' a='**' expression ')' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use double starred expression here") } +invalid_import: + | a='import' dotted_name 'from' dotted_name { + RAISE_SYNTAX_ERROR_STARTING_FROM(a, "Did you mean to use 'from ... import ...' instead?") } + invalid_import_from_targets: | import_from_as_names ',' NEWLINE { RAISE_SYNTAX_ERROR("trailing comma not allowed without surrounding parentheses") } invalid_with_stmt: - | [ASYNC] 'with' ','.(expression ['as' star_target])+ &&':' - | [ASYNC] 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':' + | [ASYNC] 'with' ','.(expression ['as' star_target])+ NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } + | [ASYNC] 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } invalid_with_stmt_indent: | [ASYNC] a='with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'with' statement on line %d", a->lineno) } @@ -1191,24 +1259,32 @@ invalid_try_stmt: | a='try' ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'try' statement on line %d", a->lineno) } | 'try' ':' block !('except' | 'finally') { RAISE_SYNTAX_ERROR("expected 'except' or 'finally' block") } + | 'try' ':' block* except_block+ a='except' b='*' expression ['as' NAME] ':' { + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "cannot have both 'except' and 'except*' on the same 'try'") } + | 'try' ':' block* except_star_block+ a='except' [expression ['as' NAME]] ':' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot have both 'except' and 'except*' on the same 'try'") } invalid_except_stmt: - | 'except' a=expression ',' expressions ['as' NAME ] ':' { + | 'except' '*'? a=expression ',' expressions ['as' NAME ] ':' { RAISE_SYNTAX_ERROR_STARTING_FROM(a, "multiple exception types must be parenthesized") } - | a='except' expression ['as' NAME ] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } + | a='except' '*'? expression ['as' NAME ] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } | a='except' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } + | a='except' '*' (NEWLINE | ':') { RAISE_SYNTAX_ERROR("expected one or more exception types") } invalid_finally_stmt: | a='finally' ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'finally' statement on line %d", a->lineno) } invalid_except_stmt_indent: | a='except' expression ['as' NAME ] ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'except' statement on line %d", a->lineno) } - | a='except' ':' NEWLINE !INDENT { RAISE_SYNTAX_ERROR("expected an indented block after except statement on line %d", a->lineno) } + | a='except' ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'except' statement on line %d", a->lineno) } +invalid_except_star_stmt_indent: + | a='except' '*' expression ['as' NAME ] ':' NEWLINE !INDENT { + RAISE_INDENTATION_ERROR("expected an indented block after 'except*' statement on line %d", a->lineno) } invalid_match_stmt: - | "match" subject_expr !':' { CHECK_VERSION(void*, 10, "Pattern matching is", RAISE_SYNTAX_ERROR("expected ':'") ) } + | "match" subject_expr NEWLINE { CHECK_VERSION(void*, 10, "Pattern matching is", RAISE_SYNTAX_ERROR("expected ':'") ) } | a="match" subject=subject_expr ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'match' statement on line %d", a->lineno) } invalid_case_block: - | "case" patterns guard? !':' { RAISE_SYNTAX_ERROR("expected ':'") } + | "case" patterns guard? NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } | a="case" patterns guard? ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'case' statement on line %d", a->lineno) } invalid_as_pattern: @@ -1237,13 +1313,15 @@ invalid_while_stmt: | a='while' named_expression ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'while' statement on line %d", a->lineno) } invalid_for_stmt: + | [ASYNC] 'for' star_targets 'in' star_expressions NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } | [ASYNC] a='for' star_targets 'in' star_expressions ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'for' statement on line %d", a->lineno) } invalid_def_raw: | [ASYNC] a='def' NAME '(' [params] ')' ['->' expression] ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after function definition on line %d", a->lineno) } invalid_class_def_raw: - | a='class' NAME ['('[arguments] ')'] ':' NEWLINE !INDENT { + | 'class' NAME ['(' [arguments] ')'] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") } + | a='class' NAME ['(' [arguments] ')'] ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after class definition on line %d", a->lineno) } invalid_double_starred_kvpairs: @@ -1254,4 +1332,6 @@ invalid_kvpair: | a=expression !(':') { RAISE_ERROR_KNOWN_LOCATION(p, PyExc_SyntaxError, a->lineno, a->end_col_offset - 1, a->end_lineno, -1, "':' expected after dictionary key") } | expression ':' a='*' bitwise_or { RAISE_SYNTAX_ERROR_STARTING_FROM(a, "cannot use a starred expression in a dictionary value") } - | expression a=':' {RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "expression expected after dictionary key and ':'") } + | expression a=':' &('}'|',') {RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "expression expected after dictionary key and ':'") } +invalid_starred_expression: + | a='*' expression '=' b=expression { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "cannot assign to iterable argument unpacking") } diff --git a/Include/Python.h b/Include/Python.h index 6e3303ac9a3..52a7aac6ba6 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -39,6 +39,8 @@ #include "pymacro.h" #include "pymath.h" #include "pymem.h" +#include "pytypedefs.h" +#include "pybuffer.h" #include "object.h" #include "objimpl.h" #include "typeslots.h" @@ -66,12 +68,13 @@ #include "cpython/classobject.h" #include "fileobject.h" #include "pycapsule.h" -#include "code.h" +#include "cpython/code.h" #include "pyframe.h" #include "traceback.h" #include "sliceobject.h" #include "cpython/cellobject.h" #include "iterobject.h" +#include "cpython/initconfig.h" #include "pystate.h" #include "cpython/genobject.h" #include "descrobject.h" @@ -83,7 +86,6 @@ #include "cpython/pytime.h" #include "codecs.h" #include "pyerrors.h" -#include "cpython/initconfig.h" #include "pythread.h" #include "cpython/context.h" #include "modsupport.h" diff --git a/Include/abstract.h b/Include/abstract.h index 9e06fbbb749..064b0300b51 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -14,9 +14,9 @@ extern "C" { Print an object 'o' on file 'fp'. Returns -1 on error. The flags argument is used to enable certain printing options. The only option currently - supported is Py_Print_RAW. - - (What should be said about Py_Print_RAW?). */ + supported is Py_PRINT_RAW. By default (flags=0), PyObject_Print() formats + the object by calling PyObject_Repr(). If flags equals to Py_PRINT_RAW, it + formats the object by calling PyObject_Str(). */ /* Implemented elsewhere: @@ -88,7 +88,7 @@ extern "C" { -1 on failure. This is the equivalent of the Python statement: del o.attr_name. */ -#define PyObject_DelAttrString(O,A) PyObject_SetAttrString((O),(A), NULL) +#define PyObject_DelAttrString(O, A) PyObject_SetAttrString((O), (A), NULL) /* Implemented as a macro: @@ -98,7 +98,7 @@ extern "C" { Delete attribute named attr_name, for object o. Returns -1 on failure. This is the equivalent of the Python statement: del o.attr_name. */ -#define PyObject_DelAttr(O,A) PyObject_SetAttr((O),(A), NULL) +#define PyObject_DelAttr(O, A) PyObject_SetAttr((O), (A), NULL) /* Implemented elsewhere: @@ -228,6 +228,32 @@ PyAPI_FUNC(PyObject *) PyObject_CallMethodObjArgs( PyObject *name, ...); +/* Given a vectorcall nargsf argument, return the actual number of arguments. + * (For use outside the limited API, this is re-defined as a static inline + * function in cpython/abstract.h) + */ +PyAPI_FUNC(Py_ssize_t) PyVectorcall_NARGS(size_t nargsf); + +/* Call "callable" (which must support vectorcall) with positional arguments + "tuple" and keyword arguments "dict". "dict" may also be NULL */ +PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030C0000 +#define PY_VECTORCALL_ARGUMENTS_OFFSET \ + (_Py_STATIC_CAST(size_t, 1) << (8 * sizeof(size_t) - 1)) + +/* Perform a PEP 590-style vector call on 'callable' */ +PyAPI_FUNC(PyObject *) PyObject_Vectorcall( + PyObject *callable, + PyObject *const *args, + size_t nargsf, + PyObject *kwnames); + +/* Call the method 'name' on args[0] with arguments in args[1..nargsf-1]. */ +PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod( + PyObject *name, PyObject *const *args, + size_t nargsf, PyObject *kwnames); +#endif /* Implemented elsewhere: @@ -722,7 +748,7 @@ PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m); /* Return the 'i'-th element of the sequence 'o', assuming that o was returned by PySequence_Fast, and that i is within bounds. */ #define PySequence_Fast_GET_ITEM(o, i)\ - (PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i)) + (PyList_Check(o) ? PyList_GET_ITEM((o), (i)) : PyTuple_GET_ITEM((o), (i))) /* Return a pointer to the underlying item array for an object returned by PySequence_Fast */ @@ -802,7 +828,7 @@ PyAPI_FUNC(Py_ssize_t) PyMapping_Length(PyObject *o); failure. This is equivalent to the Python statement: del o[key]. */ -#define PyMapping_DelItemString(O,K) PyObject_DelItemString((O),(K)) +#define PyMapping_DelItemString(O, K) PyObject_DelItemString((O), (K)) /* Implemented as a macro: @@ -812,7 +838,7 @@ PyAPI_FUNC(Py_ssize_t) PyMapping_Length(PyObject *o); Returns -1 on failure. This is equivalent to the Python statement: del o[key]. */ -#define PyMapping_DelItem(O,K) PyObject_DelItem((O),(K)) +#define PyMapping_DelItem(O, K) PyObject_DelItem((O), (K)) /* On success, return 1 if the mapping object 'o' has the key 'key', and 0 otherwise. diff --git a/Include/boolobject.h b/Include/boolobject.h index cda6f89a99e..ca21fbfad8e 100644 --- a/Include/boolobject.h +++ b/Include/boolobject.h @@ -9,18 +9,18 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyBool_Type; -#define PyBool_Check(x) Py_IS_TYPE(x, &PyBool_Type) +#define PyBool_Check(x) Py_IS_TYPE((x), &PyBool_Type) /* Py_False and Py_True are the only two bools in existence. Don't forget to apply Py_INCREF() when returning either!!! */ /* Don't use these directly */ -PyAPI_DATA(struct _longobject) _Py_FalseStruct; -PyAPI_DATA(struct _longobject) _Py_TrueStruct; +PyAPI_DATA(PyLongObject) _Py_FalseStruct; +PyAPI_DATA(PyLongObject) _Py_TrueStruct; /* Use these macros */ -#define Py_False ((PyObject *) &_Py_FalseStruct) -#define Py_True ((PyObject *) &_Py_TrueStruct) +#define Py_False _PyObject_CAST(&_Py_FalseStruct) +#define Py_True _PyObject_CAST(&_Py_TrueStruct) // Test if an object is the True singleton, the same as "x is True" in Python. PyAPI_FUNC(int) Py_IsTrue(PyObject *x); diff --git a/Include/bytearrayobject.h b/Include/bytearrayobject.h index ae2bde1c303..3d53fdba643 100644 --- a/Include/bytearrayobject.h +++ b/Include/bytearrayobject.h @@ -21,8 +21,8 @@ PyAPI_DATA(PyTypeObject) PyByteArray_Type; PyAPI_DATA(PyTypeObject) PyByteArrayIter_Type; /* Type check macros */ -#define PyByteArray_Check(self) PyObject_TypeCheck(self, &PyByteArray_Type) -#define PyByteArray_CheckExact(self) Py_IS_TYPE(self, &PyByteArray_Type) +#define PyByteArray_Check(self) PyObject_TypeCheck((self), &PyByteArray_Type) +#define PyByteArray_CheckExact(self) Py_IS_TYPE((self), &PyByteArray_Type) /* Direct API functions */ PyAPI_FUNC(PyObject *) PyByteArray_FromObject(PyObject *); diff --git a/Include/bytesobject.h b/Include/bytesobject.h index 4c4dc40d705..ee448cd02bd 100644 --- a/Include/bytesobject.h +++ b/Include/bytesobject.h @@ -29,7 +29,7 @@ PyAPI_DATA(PyTypeObject) PyBytesIter_Type; #define PyBytes_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS) -#define PyBytes_CheckExact(op) Py_IS_TYPE(op, &PyBytes_Type) +#define PyBytes_CheckExact(op) Py_IS_TYPE((op), &PyBytes_Type) PyAPI_FUNC(PyObject *) PyBytes_FromStringAndSize(const char *, Py_ssize_t); PyAPI_FUNC(PyObject *) PyBytes_FromString(const char *); diff --git a/Include/ceval.h b/Include/ceval.h index 1b57f6ea20f..ad4d909d6f2 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -31,7 +31,7 @@ Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords( /* Deprecated since PyEval_CallObjectWithKeywords is deprecated */ #define PyEval_CallObject(callable, arg) \ - PyEval_CallObjectWithKeywords(callable, arg, (PyObject *)NULL) + PyEval_CallObjectWithKeywords((callable), (arg), _PyObject_CAST(_Py_NULL)) Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyEval_CallFunction( PyObject *callable, const char *format, ...); diff --git a/Include/code.h b/Include/code.h deleted file mode 100644 index 2dea3c26105..00000000000 --- a/Include/code.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Definitions for bytecode */ - -#ifndef Py_CODE_H -#define Py_CODE_H -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct PyCodeObject PyCodeObject; - -#ifndef Py_LIMITED_API -# define Py_CPYTHON_CODE_H -# include "cpython/code.h" -# undef Py_CPYTHON_CODE_H -#endif - -#ifdef __cplusplus -} -#endif -#endif /* !Py_CODE_H */ diff --git a/Include/complexobject.h b/Include/complexobject.h index 9221f9c51d6..ebe49a832f7 100644 --- a/Include/complexobject.h +++ b/Include/complexobject.h @@ -6,61 +6,22 @@ extern "C" { #endif -#ifndef Py_LIMITED_API -typedef struct { - double real; - double imag; -} Py_complex; - -/* Operations on complex numbers from complexmodule.c */ - -PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex); -PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex); -PyAPI_FUNC(double) _Py_c_abs(Py_complex); -#endif - /* Complex object interface */ -/* -PyComplexObject represents a complex number with double-precision -real and imaginary parts. -*/ -#ifndef Py_LIMITED_API -typedef struct { - PyObject_HEAD - Py_complex cval; -} PyComplexObject; -#endif - PyAPI_DATA(PyTypeObject) PyComplex_Type; -#define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type) -#define PyComplex_CheckExact(op) Py_IS_TYPE(op, &PyComplex_Type) +#define PyComplex_Check(op) PyObject_TypeCheck((op), &PyComplex_Type) +#define PyComplex_CheckExact(op) Py_IS_TYPE((op), &PyComplex_Type) -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex); -#endif PyAPI_FUNC(PyObject *) PyComplex_FromDoubles(double real, double imag); PyAPI_FUNC(double) PyComplex_RealAsDouble(PyObject *op); PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op); -#ifndef Py_LIMITED_API -PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op); -#endif -/* Format the object based on the format_spec, as defined in PEP 3101 - (Advanced String Formatting). */ #ifndef Py_LIMITED_API -PyAPI_FUNC(int) _PyComplex_FormatAdvancedWriter( - _PyUnicodeWriter *writer, - PyObject *obj, - PyObject *format_spec, - Py_ssize_t start, - Py_ssize_t end); +# define Py_CPYTHON_COMPLEXOBJECT_H +# include "cpython/complexobject.h" +# undef Py_CPYTHON_COMPLEXOBJECT_H #endif #ifdef __cplusplus diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index 55a742c31fa..3b27aab2fc4 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -50,22 +50,18 @@ PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall( PyObject *const *args, Py_ssize_t nargs, PyObject *keywords); -#define PY_VECTORCALL_ARGUMENTS_OFFSET ((size_t)1 << (8 * sizeof(size_t) - 1)) - +// PyVectorcall_NARGS() is exported as a function for the stable ABI. +// Here (when we are not using the stable ABI), the name is overridden to +// call a static inline function for best performance. +#define PyVectorcall_NARGS(n) _PyVectorcall_NARGS(n) static inline Py_ssize_t -PyVectorcall_NARGS(size_t n) +_PyVectorcall_NARGS(size_t n) { return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET; } PyAPI_FUNC(vectorcallfunc) PyVectorcall_Function(PyObject *callable); -PyAPI_FUNC(PyObject *) PyObject_Vectorcall( - PyObject *callable, - PyObject *const *args, - size_t nargsf, - PyObject *kwnames); - // Backwards compatibility aliases for API that was provisional in Python 3.8 #define _PyObject_Vectorcall PyObject_Vectorcall #define _PyObject_VectorcallMethod PyObject_VectorcallMethod @@ -83,10 +79,6 @@ PyAPI_FUNC(PyObject *) PyObject_VectorcallDict( size_t nargsf, PyObject *kwargs); -/* Call "callable" (which must support vectorcall) with positional arguments - "tuple" and keyword arguments "dict". "dict" may also be NULL */ -PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict); - // Same as PyObject_Vectorcall(), except without keyword arguments PyAPI_FUNC(PyObject *) _PyObject_FastCall( PyObject *func, @@ -95,27 +87,26 @@ PyAPI_FUNC(PyObject *) _PyObject_FastCall( PyAPI_FUNC(PyObject *) PyObject_CallOneArg(PyObject *func, PyObject *arg); -PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod( - PyObject *name, PyObject *const *args, - size_t nargsf, PyObject *kwnames); - static inline PyObject * PyObject_CallMethodNoArgs(PyObject *self, PyObject *name) { - return PyObject_VectorcallMethod(name, &self, - 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; + return PyObject_VectorcallMethod(name, &self, nargsf, _Py_NULL); } static inline PyObject * PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg) { PyObject *args[2] = {self, arg}; - + size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET; assert(arg != NULL); - return PyObject_VectorcallMethod(name, args, - 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + return PyObject_VectorcallMethod(name, args, nargsf, _Py_NULL); } +PyAPI_FUNC(PyObject *) _PyObject_CallMethod(PyObject *obj, + PyObject *name, + const char *format, ...); + /* Like PyObject_CallMethod(), but expect a _Py_Identifier* as the method name. */ PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj, @@ -129,7 +120,7 @@ PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *obj, PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs( PyObject *obj, - struct _Py_Identifier *name, + _Py_Identifier *name, ...); static inline PyObject * @@ -139,7 +130,7 @@ _PyObject_VectorcallMethodId( { PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ if (!oname) { - return NULL; + return _Py_NULL; } return PyObject_VectorcallMethod(oname, args, nargsf, kwnames); } @@ -147,18 +138,17 @@ _PyObject_VectorcallMethodId( static inline PyObject * _PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name) { - return _PyObject_VectorcallMethodId(name, &self, - 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; + return _PyObject_VectorcallMethodId(name, &self, nargsf, _Py_NULL); } static inline PyObject * _PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg) { PyObject *args[2] = {self, arg}; - + size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET; assert(arg != NULL); - return _PyObject_VectorcallMethodId(name, args, - 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + return _PyObject_VectorcallMethodId(name, args, nargsf, _Py_NULL); } PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o); @@ -168,80 +158,12 @@ PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o); value. If one of the calls fails, this function returns -1. */ PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); -/* === New Buffer API ============================================ */ - -/* Return 1 if the getbuffer function is available, otherwise return 0. */ -PyAPI_FUNC(int) PyObject_CheckBuffer(PyObject *obj); - -/* This is a C-API version of the getbuffer function call. It checks - to make sure object has the required function pointer and issues the - call. - - Returns -1 and raises an error on failure and returns 0 on success. */ -PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, Py_buffer *view, - int flags); - -/* Get the memory area pointed to by the indices for the buffer given. - Note that view->ndim is the assumed size of indices. */ -PyAPI_FUNC(void *) PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices); - -/* Return the implied itemsize of the data-format area from a - struct-style description. */ -PyAPI_FUNC(Py_ssize_t) PyBuffer_SizeFromFormat(const char *format); - -/* Implementation in memoryobject.c */ -PyAPI_FUNC(int) PyBuffer_ToContiguous(void *buf, Py_buffer *view, - Py_ssize_t len, char order); - -PyAPI_FUNC(int) PyBuffer_FromContiguous(Py_buffer *view, void *buf, - Py_ssize_t len, char order); - -/* Copy len bytes of data from the contiguous chunk of memory - pointed to by buf into the buffer exported by obj. Return - 0 on success and return -1 and raise a PyBuffer_Error on - error (i.e. the object does not have a buffer interface or - it is not working). - - If fort is 'F', then if the object is multi-dimensional, - then the data will be copied into the array in - Fortran-style (first dimension varies the fastest). If - fort is 'C', then the data will be copied into the array - in C-style (last dimension varies the fastest). If fort - is 'A', then it does not matter and the copy will be made - in whatever way is more efficient. */ -PyAPI_FUNC(int) PyObject_CopyData(PyObject *dest, PyObject *src); - -/* Copy the data from the src buffer to the buffer of destination. */ -PyAPI_FUNC(int) PyBuffer_IsContiguous(const Py_buffer *view, char fort); - -/*Fill the strides array with byte-strides of a contiguous - (Fortran-style if fort is 'F' or C-style otherwise) - array of the given shape with the given number of bytes - per element. */ -PyAPI_FUNC(void) PyBuffer_FillContiguousStrides(int ndims, - Py_ssize_t *shape, - Py_ssize_t *strides, - int itemsize, - char fort); - -/* Fills in a buffer-info structure correctly for an exporter - that can only share a contiguous chunk of memory of - "unsigned bytes" of the given length. - - Returns 0 on success and -1 (with raising an error) on error. */ -PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf, - Py_ssize_t len, int readonly, - int flags); - -/* Releases a Py_buffer obtained from getbuffer ParseTuple's "s*". */ -PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view); - /* === Sequence protocol ================================================ */ /* Assume tp_as_sequence and sq_item exist and that 'i' does not need to be corrected for a negative index. */ #define PySequence_ITEM(o, i)\ - ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) ) + ( Py_TYPE(o)->tp_as_sequence->sq_item((o), (i)) ) #define PY_ITERSEARCH_COUNT 1 #define PY_ITERSEARCH_INDEX 2 diff --git a/Include/cpython/bytearrayobject.h b/Include/cpython/bytearrayobject.h index 569b0cd0369..9ba176eb2d3 100644 --- a/Include/cpython/bytearrayobject.h +++ b/Include/cpython/bytearrayobject.h @@ -11,10 +11,24 @@ typedef struct { Py_ssize_t ob_exports; /* How many buffer exports */ } PyByteArrayObject; -/* Macros, trading safety for speed */ -#define PyByteArray_AS_STRING(self) \ - (assert(PyByteArray_Check(self)), \ - Py_SIZE(self) ? ((PyByteArrayObject *)(self))->ob_start : _PyByteArray_empty_string) -#define PyByteArray_GET_SIZE(self) (assert(PyByteArray_Check(self)), Py_SIZE(self)) - PyAPI_DATA(char) _PyByteArray_empty_string[]; + +/* Macros and static inline functions, trading safety for speed */ +#define _PyByteArray_CAST(op) \ + (assert(PyByteArray_Check(op)), _Py_CAST(PyByteArrayObject*, op)) + +static inline char* PyByteArray_AS_STRING(PyObject *op) +{ + PyByteArrayObject *self = _PyByteArray_CAST(op); + if (Py_SIZE(self)) { + return self->ob_start; + } + return _PyByteArray_empty_string; +} +#define PyByteArray_AS_STRING(self) PyByteArray_AS_STRING(_PyObject_CAST(self)) + +static inline Py_ssize_t PyByteArray_GET_SIZE(PyObject *op) { + PyByteArrayObject *self = _PyByteArray_CAST(op); + return Py_SIZE(self); +} +#define PyByteArray_GET_SIZE(self) PyByteArray_GET_SIZE(_PyObject_CAST(self)) diff --git a/Include/cpython/bytesobject.h b/Include/cpython/bytesobject.h index 6b3f55224fc..e982031c107 100644 --- a/Include/cpython/bytesobject.h +++ b/Include/cpython/bytesobject.h @@ -4,7 +4,7 @@ typedef struct { PyObject_VAR_HEAD - Py_hash_t ob_shash; + Py_DEPRECATED(3.11) Py_hash_t ob_shash; char ob_sval[1]; /* Invariants: @@ -28,10 +28,21 @@ PyAPI_FUNC(PyObject*) _PyBytes_FromHex( PyAPI_FUNC(PyObject *) _PyBytes_DecodeEscape(const char *, Py_ssize_t, const char *, const char **); -/* Macro, trading safety for speed */ -#define PyBytes_AS_STRING(op) (assert(PyBytes_Check(op)), \ - (((PyBytesObject *)(op))->ob_sval)) -#define PyBytes_GET_SIZE(op) (assert(PyBytes_Check(op)),Py_SIZE(op)) +/* Macros and static inline functions, trading safety for speed */ +#define _PyBytes_CAST(op) \ + (assert(PyBytes_Check(op)), _Py_CAST(PyBytesObject*, op)) + +static inline char* PyBytes_AS_STRING(PyObject *op) +{ + return _PyBytes_CAST(op)->ob_sval; +} +#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op)) + +static inline Py_ssize_t PyBytes_GET_SIZE(PyObject *op) { + PyBytesObject *self = _PyBytes_CAST(op); + return Py_SIZE(self); +} +#define PyBytes_GET_SIZE(self) PyBytes_GET_SIZE(_PyObject_CAST(self)) /* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyBytesObject*, x must be an iterable object. */ diff --git a/Include/cpython/cellobject.h b/Include/cpython/cellobject.h index 8dc7b8f4cf6..47a6a491497 100644 --- a/Include/cpython/cellobject.h +++ b/Include/cpython/cellobject.h @@ -15,14 +15,27 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyCell_Type; -#define PyCell_Check(op) Py_IS_TYPE(op, &PyCell_Type) +#define PyCell_Check(op) Py_IS_TYPE((op), &PyCell_Type) PyAPI_FUNC(PyObject *) PyCell_New(PyObject *); PyAPI_FUNC(PyObject *) PyCell_Get(PyObject *); PyAPI_FUNC(int) PyCell_Set(PyObject *, PyObject *); -#define PyCell_GET(op) (((PyCellObject *)(op))->ob_ref) -#define PyCell_SET(op, v) ((void)(((PyCellObject *)(op))->ob_ref = v)) +static inline PyObject* PyCell_GET(PyObject *op) { + PyCellObject *cell; + assert(PyCell_Check(op)); + cell = _Py_CAST(PyCellObject*, op); + return cell->ob_ref; +} +#define PyCell_GET(op) PyCell_GET(_PyObject_CAST(op)) + +static inline void PyCell_SET(PyObject *op, PyObject *value) { + PyCellObject *cell; + assert(PyCell_Check(op)); + cell = _Py_CAST(PyCellObject*, op); + cell->ob_ref = value; +} +#define PyCell_SET(op, value) PyCell_SET(_PyObject_CAST(op), (value)) #ifdef __cplusplus } diff --git a/Include/cpython/ceval.h b/Include/cpython/ceval.h index caf64401307..74665c9fa10 100644 --- a/Include/cpython/ceval.h +++ b/Include/cpython/ceval.h @@ -2,26 +2,22 @@ # error "this header file must not be included directly" #endif -PyAPI_FUNC(PyObject *) _PyEval_CallTracing(PyObject *func, PyObject *args); - PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); +PyAPI_FUNC(void) PyEval_SetProfileAllThreads(Py_tracefunc, PyObject *); PyAPI_DATA(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); +PyAPI_FUNC(void) PyEval_SetTraceAllThreads(Py_tracefunc, PyObject *); PyAPI_FUNC(int) _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); -PyAPI_FUNC(int) _PyEval_GetCoroutineOriginTrackingDepth(void); -PyAPI_FUNC(int) _PyEval_SetAsyncGenFirstiter(PyObject *); -PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFirstiter(void); -PyAPI_FUNC(int) _PyEval_SetAsyncGenFinalizer(PyObject *); -PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFinalizer(void); /* Helper to look up a builtin object */ +PyAPI_FUNC(PyObject *) _PyEval_GetBuiltin(PyObject *); PyAPI_FUNC(PyObject *) _PyEval_GetBuiltinId(_Py_Identifier *); /* Look at the current frame's (if any) code's co_flags, and turn on the corresponding compiler flags in cf->cf_flags. Return 1 if any flag was set, else return 0. */ PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf); -PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(PyThreadState *tstate, struct _interpreter_frame *f, int exc); +PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(PyThreadState *tstate, struct _PyInterpreterFrame *f, int exc); PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds); PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void); diff --git a/Include/cpython/classobject.h b/Include/cpython/classobject.h index 80df8842eb4..d7c9ddd1336 100644 --- a/Include/cpython/classobject.h +++ b/Include/cpython/classobject.h @@ -19,19 +19,27 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyMethod_Type; -#define PyMethod_Check(op) Py_IS_TYPE(op, &PyMethod_Type) +#define PyMethod_Check(op) Py_IS_TYPE((op), &PyMethod_Type) PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *); PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *); -/* Macros for direct access to these values. Type checks are *not* - done, so use with care. */ -#define PyMethod_GET_FUNCTION(meth) \ - (((PyMethodObject *)meth) -> im_func) -#define PyMethod_GET_SELF(meth) \ - (((PyMethodObject *)meth) -> im_self) +#define _PyMethod_CAST(meth) \ + (assert(PyMethod_Check(meth)), _Py_CAST(PyMethodObject*, meth)) + +/* Static inline functions for direct access to these values. + Type checks are *not* done, so use with care. */ +static inline PyObject* PyMethod_GET_FUNCTION(PyObject *meth) { + return _PyMethod_CAST(meth)->im_func; +} +#define PyMethod_GET_FUNCTION(meth) PyMethod_GET_FUNCTION(_PyObject_CAST(meth)) + +static inline PyObject* PyMethod_GET_SELF(PyObject *meth) { + return _PyMethod_CAST(meth)->im_self; +} +#define PyMethod_GET_SELF(meth) PyMethod_GET_SELF(_PyObject_CAST(meth)) typedef struct { PyObject_HEAD @@ -40,15 +48,21 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyInstanceMethod_Type; -#define PyInstanceMethod_Check(op) Py_IS_TYPE(op, &PyInstanceMethod_Type) +#define PyInstanceMethod_Check(op) Py_IS_TYPE((op), &PyInstanceMethod_Type) PyAPI_FUNC(PyObject *) PyInstanceMethod_New(PyObject *); PyAPI_FUNC(PyObject *) PyInstanceMethod_Function(PyObject *); -/* Macros for direct access to these values. Type checks are *not* - done, so use with care. */ -#define PyInstanceMethod_GET_FUNCTION(meth) \ - (((PyInstanceMethodObject *)meth) -> func) +#define _PyInstanceMethod_CAST(meth) \ + (assert(PyInstanceMethod_Check(meth)), \ + _Py_CAST(PyInstanceMethodObject*, meth)) + +/* Static inline function for direct access to these values. + Type checks are *not* done, so use with care. */ +static inline PyObject* PyInstanceMethod_GET_FUNCTION(PyObject *meth) { + return _PyInstanceMethod_CAST(meth)->func; +} +#define PyInstanceMethod_GET_FUNCTION(meth) PyInstanceMethod_GET_FUNCTION(_PyObject_CAST(meth)) #ifdef __cplusplus } diff --git a/Include/cpython/code.h b/Include/cpython/code.h index b232f80367e..0cf49f06c87 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -1,113 +1,116 @@ -#ifndef Py_CPYTHON_CODE_H -# error "this header file must not be included directly" +/* Definitions for bytecode */ + +#ifndef Py_LIMITED_API +#ifndef Py_CODE_H +#define Py_CODE_H +#ifdef __cplusplus +extern "C" { #endif /* Each instruction in a code object is a fixed-width value, * currently 2 bytes: 1-byte opcode + 1-byte oparg. The EXTENDED_ARG * opcode allows for larger values but the current limit is 3 uses - * of EXTENDED_ARG (see Python/wordcode_helpers.h), for a maximum + * of EXTENDED_ARG (see Python/compile.c), for a maximum * 32-bit value. This aligns with the note in Python/compile.c * (compiler_addop_i_line) indicating that the max oparg value is * 2**32 - 1, rather than INT_MAX. */ -typedef uint16_t _Py_CODEUNIT; +typedef union { + uint16_t cache; + struct { + uint8_t opcode; + uint8_t oparg; + }; +} _Py_CODEUNIT; -#ifdef WORDS_BIGENDIAN -# define _Py_OPCODE(word) ((word) >> 8) -# define _Py_OPARG(word) ((word) & 255) -# define _Py_MAKECODEUNIT(opcode, oparg) (((opcode)<<8)|(oparg)) -#else -# define _Py_OPCODE(word) ((word) & 255) -# define _Py_OPARG(word) ((word) >> 8) -# define _Py_MAKECODEUNIT(opcode, oparg) ((opcode)|((oparg)<<8)) -#endif +#define _Py_OPCODE(word) ((word).opcode) +#define _Py_OPARG(word) ((word).oparg) +static inline void +_py_set_opcode(_Py_CODEUNIT *word, uint8_t opcode) +{ + word->opcode = opcode; +} + +#define _Py_SET_OPCODE(word, opcode) _py_set_opocde(&(word), opcode) + +typedef struct { + PyObject *_co_code; + PyObject *_co_varnames; + PyObject *_co_cellvars; + PyObject *_co_freevars; +} _PyCoCached; + +// To avoid repeating ourselves in deepfreeze.py, all PyCodeObject members are +// defined in this macro: +#define _PyCode_DEF(SIZE) { \ + PyObject_VAR_HEAD \ + \ + /* Note only the following fields are used in hash and/or comparisons \ + * \ + * - co_name \ + * - co_argcount \ + * - co_posonlyargcount \ + * - co_kwonlyargcount \ + * - co_nlocals \ + * - co_stacksize \ + * - co_flags \ + * - co_firstlineno \ + * - co_consts \ + * - co_names \ + * - co_localsplusnames \ + * This is done to preserve the name and line number for tracebacks \ + * and debuggers; otherwise, constant de-duplication would collapse \ + * identical functions/lambdas defined on different lines. \ + */ \ + \ + /* These fields are set with provided values on new code objects. */ \ + \ + /* The hottest fields (in the eval loop) are grouped here at the top. */ \ + PyObject *co_consts; /* list (constants used) */ \ + PyObject *co_names; /* list of strings (names used) */ \ + PyObject *co_exceptiontable; /* Byte string encoding exception handling \ + table */ \ + int co_flags; /* CO_..., see below */ \ + short _co_linearray_entry_size; /* Size of each entry in _co_linearray */ \ + \ + /* The rest are not so impactful on performance. */ \ + int co_argcount; /* #arguments, except *args */ \ + int co_posonlyargcount; /* #positional only arguments */ \ + int co_kwonlyargcount; /* #keyword only arguments */ \ + int co_stacksize; /* #entries needed for evaluation stack */ \ + int co_firstlineno; /* first source line number */ \ + \ + /* redundant values (derived from co_localsplusnames and \ + co_localspluskinds) */ \ + int co_nlocalsplus; /* number of local + cell + free variables */ \ + int co_framesize; /* Size of frame in words */ \ + int co_nlocals; /* number of local variables */ \ + int co_ncellvars; /* total number of cell variables */ \ + int co_nfreevars; /* number of free variables */ \ + uint32_t co_version; /* version number */ \ + \ + PyObject *co_localsplusnames; /* tuple mapping offsets to names */ \ + PyObject *co_localspluskinds; /* Bytes mapping to local kinds (one byte \ + per variable) */ \ + PyObject *co_filename; /* unicode (where it was loaded from) */ \ + PyObject *co_name; /* unicode (name, for reference) */ \ + PyObject *co_qualname; /* unicode (qualname, for reference) */ \ + PyObject *co_linetable; /* bytes object that holds location info */ \ + PyObject *co_weakreflist; /* to support weakrefs to code objects */ \ + _PyCoCached *_co_cached; /* cached co_* attributes */ \ + int _co_firsttraceable; /* index of first traceable instruction */ \ + char *_co_linearray; /* array of line offsets */ \ + /* Scratch space for extra data relating to the code object. \ + Type is a void* to keep the format private in codeobject.c to force \ + people to go through the proper APIs. */ \ + void *co_extra; \ + char co_code_adaptive[(SIZE)]; \ +} /* Bytecode object */ -struct PyCodeObject { - PyObject_HEAD - - /* Note only the following fields are used in hash and/or comparisons - * - * - co_name - * - co_argcount - * - co_posonlyargcount - * - co_kwonlyargcount - * - co_nlocals - * - co_stacksize - * - co_flags - * - co_firstlineno - * - co_code - * - co_consts - * - co_names - * - co_varnames - * - co_freevars - * - co_cellvars - * - * This is done to preserve the name and line number for tracebacks - * and debuggers; otherwise, constant de-duplication would collapse - * identical functions/lambdas defined on different lines. - */ - - /* These fields are set with provided values on new code objects. */ - - // The hottest fields (in the eval loop) are grouped here at the top. - PyObject *co_consts; /* list (constants used) */ - PyObject *co_names; /* list of strings (names used) */ - _Py_CODEUNIT *co_firstinstr; /* Pointer to first instruction, used for quickening. - Unlike the other "hot" fields, this one is - actually derived from co_code. */ - PyObject *co_exceptiontable; /* Byte string encoding exception handling table */ - int co_flags; /* CO_..., see below */ - int co_warmup; /* Warmup counter for quickening */ - - // The rest are not so impactful on performance. - int co_argcount; /* #arguments, except *args */ - int co_posonlyargcount; /* #positional only arguments */ - int co_kwonlyargcount; /* #keyword only arguments */ - int co_stacksize; /* #entries needed for evaluation stack */ - int co_firstlineno; /* first source line number */ - PyObject *co_code; /* instruction opcodes */ - PyObject *co_localsplusnames; /* tuple mapping offsets to names */ - PyObject *co_localspluskinds; /* Bytes mapping to local kinds (one byte per variable) */ - PyObject *co_filename; /* unicode (where it was loaded from) */ - PyObject *co_name; /* unicode (name, for reference) */ - PyObject *co_qualname; /* unicode (qualname, for reference) */ - PyObject *co_linetable; /* bytes (encoding addr<->lineno mapping) See - Objects/lnotab_notes.txt for details. */ - PyObject *co_endlinetable; /* bytes object that holds end lineno for - instructions separated across different - lines */ - PyObject *co_columntable; /* bytes object that holds start/end column - offset each instruction */ - - /* These fields are set with computed values on new code objects. */ - - // redundant values (derived from co_localsplusnames and co_localspluskinds) - int co_nlocalsplus; /* number of local + cell + free variables */ - int co_nlocals; /* number of local variables */ - int co_nplaincellvars; /* number of non-arg cell variables */ - int co_ncellvars; /* total number of cell variables */ - int co_nfreevars; /* number of free variables */ - // lazily-computed values - PyObject *co_varnames; /* tuple of strings (local variable names) */ - PyObject *co_cellvars; /* tuple of strings (cell variable names) */ - PyObject *co_freevars; /* tuple of strings (free variable names) */ - - /* The remaining fields are zeroed out on new code objects. */ - - PyObject *co_weakreflist; /* to support weakrefs to code objects */ - /* Scratch space for extra data relating to the code object. - Type is a void* to keep the format private in codeobject.c to force - people to go through the proper APIs. */ - void *co_extra; - /* Quickened instructions and cache, or NULL - This should be treated as opaque by all code except the specializer and - interpreter. */ - union _cache_or_instruction *co_quickened; - -}; +struct PyCodeObject _PyCode_DEF(1); /* Masks for co_flags above */ #define CO_OPTIMIZED 0x0001 @@ -146,21 +149,33 @@ struct PyCodeObject { PyAPI_DATA(PyTypeObject) PyCode_Type; -#define PyCode_Check(op) Py_IS_TYPE(op, &PyCode_Type) -#define PyCode_GetNumFree(op) ((op)->co_nfreevars) +#define PyCode_Check(op) Py_IS_TYPE((op), &PyCode_Type) + +static inline Py_ssize_t PyCode_GetNumFree(PyCodeObject *op) { + assert(PyCode_Check(op)); + return op->co_nfreevars; +} + +static inline int PyCode_GetFirstFree(PyCodeObject *op) { + assert(PyCode_Check(op)); + return op->co_nlocalsplus - op->co_nfreevars; +} + +#define _PyCode_CODE(CO) _Py_RVALUE((_Py_CODEUNIT *)(CO)->co_code_adaptive) +#define _PyCode_NBYTES(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT)) /* Public interface */ PyAPI_FUNC(PyCodeObject *) PyCode_New( int, int, int, int, int, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, int, PyObject *, - PyObject *, PyObject *, PyObject *); + PyObject *); PyAPI_FUNC(PyCodeObject *) PyCode_NewWithPosOnlyArgs( int, int, int, int, int, int, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, int, PyObject *, - PyObject *, PyObject *, PyObject *); + PyObject *); /* same as struct above */ /* Creates a new empty code object with the specified source location. */ @@ -174,18 +189,46 @@ PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int); PyAPI_FUNC(int) PyCode_Addr2Location(PyCodeObject *, int, int *, int *, int *, int *); -/* Return the ending source code line number from a bytecode index. */ -PyAPI_FUNC(int) _PyCode_Addr2EndLine(PyCodeObject *, int); -/* Return the starting source code column offset from a bytecode index. */ -PyAPI_FUNC(int) _PyCode_Addr2Offset(PyCodeObject *, int); -/* Return the ending source code column offset from a bytecode index. */ -PyAPI_FUNC(int) _PyCode_Addr2EndOffset(PyCodeObject *, int); +typedef enum PyCodeEvent { + PY_CODE_EVENT_CREATE, + PY_CODE_EVENT_DESTROY +} PyCodeEvent; + + +/* + * A callback that is invoked for different events in a code object's lifecycle. + * + * The callback is invoked with a borrowed reference to co, after it is + * created and before it is destroyed. + * + * If the callback returns with an exception set, it must return -1. Otherwise + * it should return 0. + */ +typedef int (*PyCode_WatchCallback)( + PyCodeEvent event, + PyCodeObject* co); + +/* + * Register a per-interpreter callback that will be invoked for code object + * lifecycle events. + * + * Returns a handle that may be passed to PyCode_ClearWatcher on success, + * or -1 and sets an error if no more handles are available. + */ +PyAPI_FUNC(int) PyCode_AddWatcher(PyCode_WatchCallback callback); + +/* + * Clear the watcher associated with the watcher_id handle. + * + * Returns 0 on success or -1 if no watcher exists for the provided id. + */ +PyAPI_FUNC(int) PyCode_ClearWatcher(int watcher_id); /* for internal use only */ struct _opaque { int computed_line; - const char *lo_next; - const char *limit; + const uint8_t *lo_next; + const uint8_t *limit; }; typedef struct _line_offsets { @@ -218,14 +261,31 @@ PyAPI_FUNC(int) _PyCode_GetExtra(PyObject *code, Py_ssize_t index, PyAPI_FUNC(int) _PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra); -/** API for initializing the line number tables. */ -int _PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds); -int _PyCode_InitEndAddressRange(PyCodeObject* co, PyCodeAddressRange* bounds); +/* Equivalent to getattr(code, 'co_code') in Python. + Returns a strong reference to a bytes object. */ +PyAPI_FUNC(PyObject *) PyCode_GetCode(PyCodeObject *code); +/* Equivalent to getattr(code, 'co_varnames') in Python. */ +PyAPI_FUNC(PyObject *) PyCode_GetVarnames(PyCodeObject *code); +/* Equivalent to getattr(code, 'co_cellvars') in Python. */ +PyAPI_FUNC(PyObject *) PyCode_GetCellvars(PyCodeObject *code); +/* Equivalent to getattr(code, 'co_freevars') in Python. */ +PyAPI_FUNC(PyObject *) PyCode_GetFreevars(PyCodeObject *code); -/** Out of process API for initializing the line number table. */ -void PyLineTable_InitAddressRange(const char *linetable, Py_ssize_t length, int firstlineno, PyCodeAddressRange *range); +typedef enum _PyCodeLocationInfoKind { + /* short forms are 0 to 9 */ + PY_CODE_LOCATION_INFO_SHORT0 = 0, + /* one lineforms are 10 to 12 */ + PY_CODE_LOCATION_INFO_ONE_LINE0 = 10, + PY_CODE_LOCATION_INFO_ONE_LINE1 = 11, + PY_CODE_LOCATION_INFO_ONE_LINE2 = 12, -/** API for traversing the line number table. */ -int PyLineTable_NextAddressRange(PyCodeAddressRange *range); -int PyLineTable_PreviousAddressRange(PyCodeAddressRange *range); + PY_CODE_LOCATION_INFO_NO_COLUMNS = 13, + PY_CODE_LOCATION_INFO_LONG = 14, + PY_CODE_LOCATION_INFO_NONE = 15 +} _PyCodeLocationInfoKind; +#ifdef __cplusplus +} +#endif +#endif // !Py_CODE_H +#endif // !Py_LIMITED_API diff --git a/Include/cpython/compile.h b/Include/cpython/compile.h index a202c0b0e65..f5a62a8ec6d 100644 --- a/Include/cpython/compile.h +++ b/Include/cpython/compile.h @@ -18,8 +18,10 @@ #define PyCF_IGNORE_COOKIE 0x0800 #define PyCF_TYPE_COMMENTS 0x1000 #define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000 +#define PyCF_ALLOW_INCOMPLETE_INPUT 0x4000 #define PyCF_COMPILE_MASK (PyCF_ONLY_AST | PyCF_ALLOW_TOP_LEVEL_AWAIT | \ - PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT) + PyCF_TYPE_COMMENTS | PyCF_DONT_IMPLY_DEDENT | \ + PyCF_ALLOW_INCOMPLETE_INPUT) typedef struct { int cf_flags; /* bitmask of CO_xxx flags relevant to future */ @@ -29,11 +31,26 @@ typedef struct { #define _PyCompilerFlags_INIT \ (PyCompilerFlags){.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION} +/* source location information */ +typedef struct { + int lineno; + int end_lineno; + int col_offset; + int end_col_offset; +} _PyCompilerSrcLocation; + +#define SRC_LOCATION_FROM_AST(n) \ + (_PyCompilerSrcLocation){ \ + .lineno = (n)->lineno, \ + .end_lineno = (n)->end_lineno, \ + .col_offset = (n)->col_offset, \ + .end_col_offset = (n)->end_col_offset } + /* Future feature support */ typedef struct { - int ff_features; /* flags set by future statements */ - int ff_lineno; /* line number of last future statement */ + int ff_features; /* flags set by future statements */ + _PyCompilerSrcLocation ff_location; /* location of last future statement */ } PyFutureFeatures; #define FUTURE_NESTED_SCOPES "nested_scopes" diff --git a/Include/cpython/complexobject.h b/Include/cpython/complexobject.h new file mode 100644 index 00000000000..b7d7283ae88 --- /dev/null +++ b/Include/cpython/complexobject.h @@ -0,0 +1,44 @@ +#ifndef Py_CPYTHON_COMPLEXOBJECT_H +# error "this header file must not be included directly" +#endif + +typedef struct { + double real; + double imag; +} Py_complex; + +/* Operations on complex numbers from complexmodule.c */ + +PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex); +PyAPI_FUNC(double) _Py_c_abs(Py_complex); + +/* Complex object interface */ + +/* +PyComplexObject represents a complex number with double-precision +real and imaginary parts. +*/ +typedef struct { + PyObject_HEAD + Py_complex cval; +} PyComplexObject; + +PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex); + +PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op); + +#ifdef Py_BUILD_CORE +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +extern int _PyComplex_FormatAdvancedWriter( + _PyUnicodeWriter *writer, + PyObject *obj, + PyObject *format_spec, + Py_ssize_t start, + Py_ssize_t end); +#endif // Py_BUILD_CORE diff --git a/Include/cpython/context.h b/Include/cpython/context.h index 4db079f7633..9879fc7192e 100644 --- a/Include/cpython/context.h +++ b/Include/cpython/context.h @@ -15,9 +15,9 @@ PyAPI_DATA(PyTypeObject) PyContextToken_Type; typedef struct _pycontexttokenobject PyContextToken; -#define PyContext_CheckExact(o) Py_IS_TYPE(o, &PyContext_Type) -#define PyContextVar_CheckExact(o) Py_IS_TYPE(o, &PyContextVar_Type) -#define PyContextToken_CheckExact(o) Py_IS_TYPE(o, &PyContextToken_Type) +#define PyContext_CheckExact(o) Py_IS_TYPE((o), &PyContext_Type) +#define PyContextVar_CheckExact(o) Py_IS_TYPE((o), &PyContextVar_Type) +#define PyContextToken_CheckExact(o) Py_IS_TYPE((o), &PyContextToken_Type) PyAPI_FUNC(PyObject *) PyContext_New(void); diff --git a/Include/cpython/descrobject.h b/Include/cpython/descrobject.h new file mode 100644 index 00000000000..e2ea1b9a2d3 --- /dev/null +++ b/Include/cpython/descrobject.h @@ -0,0 +1,64 @@ +#ifndef Py_CPYTHON_DESCROBJECT_H +# error "this header file must not be included directly" +#endif + +typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args, + void *wrapped); + +typedef PyObject *(*wrapperfunc_kwds)(PyObject *self, PyObject *args, + void *wrapped, PyObject *kwds); + +struct wrapperbase { + const char *name; + int offset; + void *function; + wrapperfunc wrapper; + const char *doc; + int flags; + PyObject *name_strobj; +}; + +/* Flags for above struct */ +#define PyWrapperFlag_KEYWORDS 1 /* wrapper function takes keyword args */ + +/* Various kinds of descriptor objects */ + +typedef struct { + PyObject_HEAD + PyTypeObject *d_type; + PyObject *d_name; + PyObject *d_qualname; +} PyDescrObject; + +#define PyDescr_COMMON PyDescrObject d_common + +#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type) +#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name) + +typedef struct { + PyDescr_COMMON; + PyMethodDef *d_method; + vectorcallfunc vectorcall; +} PyMethodDescrObject; + +typedef struct { + PyDescr_COMMON; + PyMemberDef *d_member; +} PyMemberDescrObject; + +typedef struct { + PyDescr_COMMON; + PyGetSetDef *d_getset; +} PyGetSetDescrObject; + +typedef struct { + PyDescr_COMMON; + struct wrapperbase *d_base; + void *d_wrapped; /* This can be any function pointer */ +} PyWrapperDescrObject; + +PyAPI_DATA(PyTypeObject) _PyMethodWrapper_Type; + +PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *, + struct wrapperbase *, void *); +PyAPI_FUNC(int) PyDescr_IsData(PyObject *); diff --git a/Include/cpython/dictobject.h b/Include/cpython/dictobject.h index e97969be4de..5001f356544 100644 --- a/Include/cpython/dictobject.h +++ b/Include/cpython/dictobject.h @@ -16,7 +16,11 @@ typedef struct { /* Dictionary version: globally unique, value change each time the dictionary is modified */ +#ifdef Py_BUILD_CORE uint64_t ma_version_tag; +#else + Py_DEPRECATED(3.12) uint64_t ma_version_tag; +#endif PyDictKeysObject *ma_keys; @@ -30,8 +34,9 @@ typedef struct { PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key, Py_hash_t hash); +PyAPI_FUNC(PyObject *) _PyDict_GetItemWithError(PyObject *dp, PyObject *key); PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp, - struct _Py_Identifier *key); + _Py_Identifier *key); PyAPI_FUNC(PyObject *) _PyDict_GetItemStringWithError(PyObject *, const char *); PyAPI_FUNC(PyObject *) PyDict_SetDefault( PyObject *mp, PyObject *key, PyObject *defaultobj); @@ -41,22 +46,25 @@ PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key, Py_hash_t hash); PyAPI_FUNC(int) _PyDict_DelItemIf(PyObject *mp, PyObject *key, int (*predicate)(PyObject *value)); -PyDictKeysObject *_PyDict_NewKeysForClass(void); PyAPI_FUNC(int) _PyDict_Next( PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash); /* Get the number of items of a dictionary. */ -#define PyDict_GET_SIZE(mp) (assert(PyDict_Check(mp)),((PyDictObject *)mp)->ma_used) +static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) { + PyDictObject *mp; + assert(PyDict_Check(op)); + mp = _Py_CAST(PyDictObject*, op); + return mp->ma_used; +} +#define PyDict_GET_SIZE(op) PyDict_GET_SIZE(_PyObject_CAST(op)) + PyAPI_FUNC(int) _PyDict_Contains_KnownHash(PyObject *, PyObject *, Py_hash_t); -PyAPI_FUNC(int) _PyDict_ContainsId(PyObject *, struct _Py_Identifier *); +PyAPI_FUNC(int) _PyDict_ContainsId(PyObject *, _Py_Identifier *); PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused); PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp); PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp); -Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys); PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *); PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *, PyObject *, PyObject *); -PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObject *); -PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *); #define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL) /* Like PyDict_Merge, but override can be 0, 1 or 2. If override is 0, @@ -65,15 +73,11 @@ PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *); argument is raised. */ PyAPI_FUNC(int) _PyDict_MergeEx(PyObject *mp, PyObject *other, int override); -PyAPI_FUNC(int) _PyDict_SetItemId(PyObject *dp, struct _Py_Identifier *key, PyObject *item); +PyAPI_FUNC(int) _PyDict_SetItemId(PyObject *dp, _Py_Identifier *key, PyObject *item); -PyAPI_FUNC(int) _PyDict_DelItemId(PyObject *mp, struct _Py_Identifier *key); +PyAPI_FUNC(int) _PyDict_DelItemId(PyObject *mp, _Py_Identifier *key); PyAPI_FUNC(void) _PyDict_DebugMallocStats(FILE *out); -int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value); -PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *); -Py_ssize_t _PyDict_GetItemHint(PyDictObject *, PyObject *, Py_ssize_t, PyObject **); - /* _PyDictView */ typedef struct { @@ -84,8 +88,26 @@ typedef struct { PyAPI_FUNC(PyObject *) _PyDictView_New(PyObject *, PyTypeObject *); PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other); -/* Gets a version number unique to the current state of the keys of dict, if possible. - * Returns the version number, or zero if it was not possible to get a version number. */ -uint32_t _PyDictKeys_GetVersionForCurrentState(PyDictKeysObject *dictkeys); +/* Dictionary watchers */ -Py_ssize_t _PyDictKeys_StringLookup(PyDictKeysObject* dictkeys, PyObject *key); +typedef enum { + PyDict_EVENT_ADDED, + PyDict_EVENT_MODIFIED, + PyDict_EVENT_DELETED, + PyDict_EVENT_CLONED, + PyDict_EVENT_CLEARED, + PyDict_EVENT_DEALLOCATED, +} PyDict_WatchEvent; + +// Callback to be invoked when a watched dict is cleared, dealloced, or modified. +// In clear/dealloc case, key and new_value will be NULL. Otherwise, new_value will be the +// new value for key, NULL if key is being deleted. +typedef int(*PyDict_WatchCallback)(PyDict_WatchEvent event, PyObject* dict, PyObject* key, PyObject* new_value); + +// Register/unregister a dict-watcher callback +PyAPI_FUNC(int) PyDict_AddWatcher(PyDict_WatchCallback callback); +PyAPI_FUNC(int) PyDict_ClearWatcher(int watcher_id); + +// Mark given dictionary as "watched" (callback will be called if it is modified) +PyAPI_FUNC(int) PyDict_Watch(int watcher_id, PyObject* dict); +PyAPI_FUNC(int) PyDict_Unwatch(int watcher_id, PyObject* dict); diff --git a/Include/cpython/fileobject.h b/Include/cpython/fileobject.h index cff2243d625..b70ec318986 100644 --- a/Include/cpython/fileobject.h +++ b/Include/cpython/fileobject.h @@ -3,6 +3,7 @@ #endif PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); +PyAPI_FUNC(char *) _Py_UniversalNewlineFgetsWithSize(char *, int, FILE*, PyObject *, size_t*); /* The std printer acts as a preliminary sys.stderr until the new io infrastructure is in place. */ diff --git a/Include/cpython/fileutils.h b/Include/cpython/fileutils.h index ccf37e9468d..b386ad107bd 100644 --- a/Include/cpython/fileutils.h +++ b/Include/cpython/fileutils.h @@ -2,171 +2,7 @@ # error "this header file must not be included directly" #endif -typedef enum { - _Py_ERROR_UNKNOWN=0, - _Py_ERROR_STRICT, - _Py_ERROR_SURROGATEESCAPE, - _Py_ERROR_REPLACE, - _Py_ERROR_IGNORE, - _Py_ERROR_BACKSLASHREPLACE, - _Py_ERROR_SURROGATEPASS, - _Py_ERROR_XMLCHARREFREPLACE, - _Py_ERROR_OTHER -} _Py_error_handler; - -PyAPI_FUNC(_Py_error_handler) _Py_GetErrorHandler(const char *errors); - -PyAPI_FUNC(int) _Py_DecodeLocaleEx( - const char *arg, - wchar_t **wstr, - size_t *wlen, - const char **reason, - int current_locale, - _Py_error_handler errors); - -PyAPI_FUNC(int) _Py_EncodeLocaleEx( - const wchar_t *text, - char **str, - size_t *error_pos, - const char **reason, - int current_locale, - _Py_error_handler errors); - -PyAPI_FUNC(char*) _Py_EncodeLocaleRaw( - const wchar_t *text, - size_t *error_pos); - -PyAPI_FUNC(PyObject *) _Py_device_encoding(int); - -#if defined(MS_WINDOWS) || defined(__APPLE__) - /* On Windows, the count parameter of read() is an int (bpo-9015, bpo-9611). - On macOS 10.13, read() and write() with more than INT_MAX bytes - fail with EINVAL (bpo-24658). */ -# define _PY_READ_MAX INT_MAX -# define _PY_WRITE_MAX INT_MAX -#else - /* write() should truncate the input to PY_SSIZE_T_MAX bytes, - but it's safer to do it ourself to have a portable behaviour */ -# define _PY_READ_MAX PY_SSIZE_T_MAX -# define _PY_WRITE_MAX PY_SSIZE_T_MAX -#endif - -#ifdef MS_WINDOWS -struct _Py_stat_struct { - unsigned long st_dev; - uint64_t st_ino; - unsigned short st_mode; - int st_nlink; - int st_uid; - int st_gid; - unsigned long st_rdev; - __int64 st_size; - time_t st_atime; - int st_atime_nsec; - time_t st_mtime; - int st_mtime_nsec; - time_t st_ctime; - int st_ctime_nsec; - unsigned long st_file_attributes; - unsigned long st_reparse_tag; -}; -#else -# define _Py_stat_struct stat -#endif - -PyAPI_FUNC(int) _Py_fstat( - int fd, - struct _Py_stat_struct *status); - -PyAPI_FUNC(int) _Py_fstat_noraise( - int fd, - struct _Py_stat_struct *status); - -PyAPI_FUNC(int) _Py_stat( - PyObject *path, - struct stat *status); - -PyAPI_FUNC(int) _Py_open( - const char *pathname, - int flags); - -PyAPI_FUNC(int) _Py_open_noraise( - const char *pathname, - int flags); - -PyAPI_FUNC(FILE *) _Py_wfopen( - const wchar_t *path, - const wchar_t *mode); - +// Used by _testcapi which must not use the internal C API PyAPI_FUNC(FILE*) _Py_fopen_obj( PyObject *path, const char *mode); - -PyAPI_FUNC(Py_ssize_t) _Py_read( - int fd, - void *buf, - size_t count); - -PyAPI_FUNC(Py_ssize_t) _Py_write( - int fd, - const void *buf, - size_t count); - -PyAPI_FUNC(Py_ssize_t) _Py_write_noraise( - int fd, - const void *buf, - size_t count); - -#ifdef HAVE_READLINK -PyAPI_FUNC(int) _Py_wreadlink( - const wchar_t *path, - wchar_t *buf, - /* Number of characters of 'buf' buffer - including the trailing NUL character */ - size_t buflen); -#endif - -#ifdef HAVE_REALPATH -PyAPI_FUNC(wchar_t*) _Py_wrealpath( - const wchar_t *path, - wchar_t *resolved_path, - /* Number of characters of 'resolved_path' buffer - including the trailing NUL character */ - size_t resolved_path_len); -#endif - -#ifndef MS_WINDOWS -PyAPI_FUNC(int) _Py_isabs(const wchar_t *path); -#endif - -PyAPI_FUNC(int) _Py_abspath(const wchar_t *path, wchar_t **abspath_p); - -PyAPI_FUNC(wchar_t*) _Py_wgetcwd( - wchar_t *buf, - /* Number of characters of 'buf' buffer - including the trailing NUL character */ - size_t buflen); - -PyAPI_FUNC(int) _Py_get_inheritable(int fd); - -PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable, - int *atomic_flag_works); - -PyAPI_FUNC(int) _Py_set_inheritable_async_safe(int fd, int inheritable, - int *atomic_flag_works); - -PyAPI_FUNC(int) _Py_dup(int fd); - -#ifndef MS_WINDOWS -PyAPI_FUNC(int) _Py_get_blocking(int fd); - -PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking); -#else /* MS_WINDOWS */ -PyAPI_FUNC(void*) _Py_get_osfhandle_noraise(int fd); - -PyAPI_FUNC(void*) _Py_get_osfhandle(int fd); - -PyAPI_FUNC(int) _Py_open_osfhandle_noraise(void *handle, int flags); - -PyAPI_FUNC(int) _Py_open_osfhandle(void *handle, int flags); -#endif /* MS_WINDOWS */ diff --git a/Include/cpython/floatobject.h b/Include/cpython/floatobject.h index fffd4686902..127093098bf 100644 --- a/Include/cpython/floatobject.h +++ b/Include/cpython/floatobject.h @@ -7,6 +7,21 @@ typedef struct { double ob_fval; } PyFloatObject; -// Macro version of PyFloat_AsDouble() trading safety for speed. +#define _PyFloat_CAST(op) \ + (assert(PyFloat_Check(op)), _Py_CAST(PyFloatObject*, op)) + +// Static inline version of PyFloat_AsDouble() trading safety for speed. // It doesn't check if op is a double object. -#define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval) +static inline double PyFloat_AS_DOUBLE(PyObject *op) { + return _PyFloat_CAST(op)->ob_fval; +} +#define PyFloat_AS_DOUBLE(op) PyFloat_AS_DOUBLE(_PyObject_CAST(op)) + + +PyAPI_FUNC(int) PyFloat_Pack2(double x, char *p, int le); +PyAPI_FUNC(int) PyFloat_Pack4(double x, char *p, int le); +PyAPI_FUNC(int) PyFloat_Pack8(double x, char *p, int le); + +PyAPI_FUNC(double) PyFloat_Unpack2(const char *p, int le); +PyAPI_FUNC(double) PyFloat_Unpack4(const char *p, int le); +PyAPI_FUNC(double) PyFloat_Unpack8(const char *p, int le); diff --git a/Include/cpython/frameobject.h b/Include/cpython/frameobject.h index e4cfac518bb..4e19535c656 100644 --- a/Include/cpython/frameobject.h +++ b/Include/cpython/frameobject.h @@ -4,40 +4,26 @@ # error "this header file must not be included directly" #endif -struct _frame { - PyObject_HEAD - struct _frame *f_back; /* previous frame, or NULL */ - struct _interpreter_frame *f_frame; /* points to the frame data */ - PyObject *f_trace; /* Trace function */ - int f_lineno; /* Current line number. Only valid if non-zero */ - char f_trace_lines; /* Emit per-line trace events? */ - char f_trace_opcodes; /* Emit per-opcode trace events? */ - char f_own_locals_memory; /* This frame owns the memory for the locals */ -}; - /* Standard object interface */ -PyAPI_DATA(PyTypeObject) PyFrame_Type; - -#define PyFrame_Check(op) Py_IS_TYPE(op, &PyFrame_Type) - PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *, PyObject *, PyObject *); -/* only internal use */ -PyFrameObject* -_PyFrame_New_NoTrack(struct _interpreter_frame *, int); - - /* The rest of the interface is specific for frame objects */ /* Conversions between "fast locals" and locals in dictionary */ PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int); +/* -- Caveat emptor -- + * The concept of entry frames is an implementation detail of the CPython + * interpreter. This API is considered unstable and is provided for the + * convenience of debuggers, profilers and state-inspecting tools. Notice that + * this API can be changed in future minor versions if the underlying frame + * mechanism change or the concept of an 'entry frame' or its semantics becomes + * obsolete or outdated. */ + +PyAPI_FUNC(int) _PyFrame_IsEntryFrame(PyFrameObject *frame); + PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f); PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *); - -PyAPI_FUNC(void) _PyFrame_DebugMallocStats(FILE *out); - -PyAPI_FUNC(PyFrameObject *) PyFrame_GetBack(PyFrameObject *frame); diff --git a/Include/cpython/funcobject.h b/Include/cpython/funcobject.h index 60b702218a1..5979febc2e3 100644 --- a/Include/cpython/funcobject.h +++ b/Include/cpython/funcobject.h @@ -48,7 +48,8 @@ typedef struct { * defaults * kwdefaults (only if the object changes, not the contents of the dict) * code - * annotations */ + * annotations + * vectorcall function pointer */ uint32_t func_version; /* Invariant: @@ -60,7 +61,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyFunction_Type; -#define PyFunction_Check(op) Py_IS_TYPE(op, &PyFunction_Type) +#define PyFunction_Check(op) Py_IS_TYPE((op), &PyFunction_Type) PyAPI_FUNC(PyObject *) PyFunction_New(PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyFunction_NewWithQualName(PyObject *, PyObject *, PyObject *); @@ -69,6 +70,7 @@ PyAPI_FUNC(PyObject *) PyFunction_GetGlobals(PyObject *); PyAPI_FUNC(PyObject *) PyFunction_GetModule(PyObject *); PyAPI_FUNC(PyObject *) PyFunction_GetDefaults(PyObject *); PyAPI_FUNC(int) PyFunction_SetDefaults(PyObject *, PyObject *); +PyAPI_FUNC(void) PyFunction_SetVectorcall(PyFunctionObject *, vectorcallfunc); PyAPI_FUNC(PyObject *) PyFunction_GetKwDefaults(PyObject *); PyAPI_FUNC(int) PyFunction_SetKwDefaults(PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyFunction_GetClosure(PyObject *); @@ -82,27 +84,45 @@ PyAPI_FUNC(PyObject *) _PyFunction_Vectorcall( size_t nargsf, PyObject *kwnames); -uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func); +#define _PyFunction_CAST(func) \ + (assert(PyFunction_Check(func)), _Py_CAST(PyFunctionObject*, func)) -/* Macros for direct access to these values. Type checks are *not* - done, so use with care. */ -#define PyFunction_GET_CODE(func) \ - (((PyFunctionObject *)func) -> func_code) -#define PyFunction_GET_GLOBALS(func) \ - (((PyFunctionObject *)func) -> func_globals) -#define PyFunction_GET_MODULE(func) \ - (((PyFunctionObject *)func) -> func_module) -#define PyFunction_GET_DEFAULTS(func) \ - (((PyFunctionObject *)func) -> func_defaults) -#define PyFunction_GET_KW_DEFAULTS(func) \ - (((PyFunctionObject *)func) -> func_kwdefaults) -#define PyFunction_GET_CLOSURE(func) \ - (((PyFunctionObject *)func) -> func_closure) -#define PyFunction_GET_ANNOTATIONS(func) \ - (((PyFunctionObject *)func) -> func_annotations) +/* Static inline functions for direct access to these values. + Type checks are *not* done, so use with care. */ +static inline PyObject* PyFunction_GET_CODE(PyObject *func) { + return _PyFunction_CAST(func)->func_code; +} +#define PyFunction_GET_CODE(func) PyFunction_GET_CODE(_PyObject_CAST(func)) -#define PyFunction_AS_FRAME_CONSTRUCTOR(func) \ - ((PyFrameConstructor *)&((PyFunctionObject *)(func))->func_globals) +static inline PyObject* PyFunction_GET_GLOBALS(PyObject *func) { + return _PyFunction_CAST(func)->func_globals; +} +#define PyFunction_GET_GLOBALS(func) PyFunction_GET_GLOBALS(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_MODULE(PyObject *func) { + return _PyFunction_CAST(func)->func_module; +} +#define PyFunction_GET_MODULE(func) PyFunction_GET_MODULE(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_DEFAULTS(PyObject *func) { + return _PyFunction_CAST(func)->func_defaults; +} +#define PyFunction_GET_DEFAULTS(func) PyFunction_GET_DEFAULTS(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_KW_DEFAULTS(PyObject *func) { + return _PyFunction_CAST(func)->func_kwdefaults; +} +#define PyFunction_GET_KW_DEFAULTS(func) PyFunction_GET_KW_DEFAULTS(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_CLOSURE(PyObject *func) { + return _PyFunction_CAST(func)->func_closure; +} +#define PyFunction_GET_CLOSURE(func) PyFunction_GET_CLOSURE(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_ANNOTATIONS(PyObject *func) { + return _PyFunction_CAST(func)->func_annotations; +} +#define PyFunction_GET_ANNOTATIONS(func) PyFunction_GET_ANNOTATIONS(_PyObject_CAST(func)) /* The classmethod and staticmethod types lives here, too */ PyAPI_DATA(PyTypeObject) PyClassMethod_Type; @@ -111,6 +131,55 @@ PyAPI_DATA(PyTypeObject) PyStaticMethod_Type; PyAPI_FUNC(PyObject *) PyClassMethod_New(PyObject *); PyAPI_FUNC(PyObject *) PyStaticMethod_New(PyObject *); +#define FOREACH_FUNC_EVENT(V) \ + V(CREATE) \ + V(DESTROY) \ + V(MODIFY_CODE) \ + V(MODIFY_DEFAULTS) \ + V(MODIFY_KWDEFAULTS) + +typedef enum { + #define DEF_EVENT(EVENT) PyFunction_EVENT_##EVENT, + FOREACH_FUNC_EVENT(DEF_EVENT) + #undef DEF_EVENT +} PyFunction_WatchEvent; + +/* + * A callback that is invoked for different events in a function's lifecycle. + * + * The callback is invoked with a borrowed reference to func, after it is + * created and before it is modified or destroyed. The callback should not + * modify func. + * + * When a function's code object, defaults, or kwdefaults are modified the + * callback will be invoked with the respective event and new_value will + * contain a borrowed reference to the new value that is about to be stored in + * the function. Otherwise the third argument is NULL. + * + * If the callback returns with an exception set, it must return -1. Otherwise + * it should return 0. + */ +typedef int (*PyFunction_WatchCallback)( + PyFunction_WatchEvent event, + PyFunctionObject *func, + PyObject *new_value); + +/* + * Register a per-interpreter callback that will be invoked for function lifecycle + * events. + * + * Returns a handle that may be passed to PyFunction_ClearWatcher on success, + * or -1 and sets an error if no more handles are available. + */ +PyAPI_FUNC(int) PyFunction_AddWatcher(PyFunction_WatchCallback callback); + +/* + * Clear the watcher associated with the watcher_id handle. + * + * Returns 0 on success or -1 if no watcher exists for the supplied id. + */ +PyAPI_FUNC(int) PyFunction_ClearWatcher(int watcher_id); + #ifdef __cplusplus } #endif diff --git a/Include/cpython/genobject.h b/Include/cpython/genobject.h index 8f87cf5fff7..6127ba7babb 100644 --- a/Include/cpython/genobject.h +++ b/Include/cpython/genobject.h @@ -13,8 +13,6 @@ extern "C" { and coroutine objects. */ #define _PyGenObject_HEAD(prefix) \ PyObject_HEAD \ - /* Note: gi_frame can be NULL if the generator is "finished" */ \ - struct _interpreter_frame *prefix##_xframe; \ /* The code object backing the generator */ \ PyCodeObject *prefix##_code; \ /* List of weak reference. */ \ @@ -23,7 +21,14 @@ extern "C" { PyObject *prefix##_name; \ /* Qualified name of the generator. */ \ PyObject *prefix##_qualname; \ - _PyErr_StackItem prefix##_exc_state; + _PyErr_StackItem prefix##_exc_state; \ + PyObject *prefix##_origin_or_finalizer; \ + char prefix##_hooks_inited; \ + char prefix##_closed; \ + char prefix##_running_async; \ + /* The frame */ \ + int8_t prefix##_frame_state; \ + PyObject *prefix##_iframe[1]; typedef struct { /* The gi_ prefix is intended to remind of generator-iterator. */ @@ -32,15 +37,14 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyGen_Type; -#define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type) -#define PyGen_CheckExact(op) Py_IS_TYPE(op, &PyGen_Type) +#define PyGen_Check(op) PyObject_TypeCheck((op), &PyGen_Type) +#define PyGen_CheckExact(op) Py_IS_TYPE((op), &PyGen_Type) PyAPI_FUNC(PyObject *) PyGen_New(PyFrameObject *); PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(PyFrameObject *, PyObject *name, PyObject *qualname); PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *); PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **); -PyObject *_PyGen_yf(PyGenObject *); PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self); @@ -48,14 +52,12 @@ PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self); typedef struct { _PyGenObject_HEAD(cr) - PyObject *cr_origin; } PyCoroObject; PyAPI_DATA(PyTypeObject) PyCoro_Type; PyAPI_DATA(PyTypeObject) _PyCoroWrapper_Type; -#define PyCoro_CheckExact(op) Py_IS_TYPE(op, &PyCoro_Type) -PyObject *_PyCoro_GetAwaitableIter(PyObject *o); +#define PyCoro_CheckExact(op) Py_IS_TYPE((op), &PyCoro_Type) PyAPI_FUNC(PyObject *) PyCoro_New(PyFrameObject *, PyObject *name, PyObject *qualname); @@ -64,18 +66,6 @@ PyAPI_FUNC(PyObject *) PyCoro_New(PyFrameObject *, typedef struct { _PyGenObject_HEAD(ag) - PyObject *ag_finalizer; - - /* Flag is set to 1 when hooks set up by sys.set_asyncgen_hooks - were called on the generator, to avoid calling them more - than once. */ - int ag_hooks_inited; - - /* Flag is set to 1 when aclose() is called for the first time, or - when a StopAsyncIteration exception is raised. */ - int ag_closed; - - int ag_running_async; } PyAsyncGenObject; PyAPI_DATA(PyTypeObject) PyAsyncGen_Type; @@ -86,9 +76,7 @@ PyAPI_DATA(PyTypeObject) _PyAsyncGenAThrow_Type; PyAPI_FUNC(PyObject *) PyAsyncGen_New(PyFrameObject *, PyObject *name, PyObject *qualname); -#define PyAsyncGen_CheckExact(op) Py_IS_TYPE(op, &PyAsyncGen_Type) - -PyObject *_PyAsyncGenValueWrapperNew(PyObject *); +#define PyAsyncGen_CheckExact(op) Py_IS_TYPE((op), &PyAsyncGen_Type) #undef _PyGenObject_HEAD diff --git a/Include/cpython/import.h b/Include/cpython/import.h index 5ec637e7ab3..a58801b47f1 100644 --- a/Include/cpython/import.h +++ b/Include/cpython/import.h @@ -6,7 +6,7 @@ PyMODINIT_FUNC PyInit__imp(void); PyAPI_FUNC(int) _PyImport_IsInitialized(PyInterpreterState *); -PyAPI_FUNC(PyObject *) _PyImport_GetModuleId(struct _Py_Identifier *name); +PyAPI_FUNC(PyObject *) _PyImport_GetModuleId(_Py_Identifier *name); PyAPI_FUNC(int) _PyImport_SetModule(PyObject *name, PyObject *module); PyAPI_FUNC(int) _PyImport_SetModuleString(const char *name, PyObject* module); @@ -25,6 +25,7 @@ struct _inittab { const char *name; /* ASCII encoded string */ PyObject* (*initfunc)(void); }; +// This is not used after Py_Initialize() is called. PyAPI_DATA(struct _inittab *) PyImport_Inittab; PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab); @@ -32,6 +33,7 @@ struct _frozen { const char *name; /* ASCII encoded string */ const unsigned char *code; int size; + int is_package; PyObject *(*get_code)(void); }; @@ -39,3 +41,6 @@ struct _frozen { collection of frozen modules: */ PyAPI_DATA(const struct _frozen *) PyImport_FrozenModules; + +PyAPI_DATA(PyObject *) _PyImport_GetModuleAttr(PyObject *, PyObject *); +PyAPI_DATA(PyObject *) _PyImport_GetModuleAttrString(const char *, const char *); diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index 05641001bcd..6ce42b4c095 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -1,6 +1,9 @@ #ifndef Py_PYCORECONFIG_H #define Py_PYCORECONFIG_H #ifndef Py_LIMITED_API +#ifdef __cplusplus +extern "C" { +#endif /* --- PyStatus ----------------------------------------------- */ @@ -139,8 +142,9 @@ typedef struct PyConfig { unsigned long hash_seed; int faulthandler; int tracemalloc; + int perf_profiling; int import_time; - int no_debug_ranges; + int code_debug_ranges; int show_ref_count; int dump_refs; wchar_t *dump_refs_file; @@ -173,6 +177,8 @@ typedef struct PyConfig { #endif wchar_t *check_hash_pycs_mode; int use_frozen_modules; + int safe_path; + int int_max_str_digits; /* --- Path configuration inputs ------------ */ int pathconfig_warnings; @@ -207,9 +213,8 @@ typedef struct PyConfig { // If equal to 0, stop Python initialization before the "main" phase. int _init_main; - // If non-zero, disallow threads, subprocesses, and fork. - // Default: 0. - int _isolated_interpreter; + // If non-zero, we believe we're running from a source tree. + int _is_python_build; } PyConfig; PyAPI_FUNC(void) PyConfig_InitPythonConfig(PyConfig *config); @@ -236,6 +241,31 @@ PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config, Py_ssize_t length, wchar_t **items); +/* --- PyInterpreterConfig ------------------------------------ */ + +typedef struct { + int allow_fork; + int allow_exec; + int allow_threads; + int allow_daemon_threads; +} _PyInterpreterConfig; + +#define _PyInterpreterConfig_INIT \ + { \ + .allow_fork = 0, \ + .allow_exec = 0, \ + .allow_threads = 1, \ + .allow_daemon_threads = 0, \ + } + +#define _PyInterpreterConfig_LEGACY_INIT \ + { \ + .allow_fork = 1, \ + .allow_exec = 1, \ + .allow_threads = 1, \ + .allow_daemon_threads = 1, \ + } + /* --- Helper functions --------------------------------------- */ /* Get the original command line arguments, before Python modified them. @@ -243,5 +273,8 @@ PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config, See also PyConfig.orig_argv. */ PyAPI_FUNC(void) Py_GetArgcArgv(int *argc, wchar_t ***argv); +#ifdef __cplusplus +} +#endif #endif /* !Py_LIMITED_API */ #endif /* !Py_PYCORECONFIG_H */ diff --git a/Include/cpython/listobject.h b/Include/cpython/listobject.h index e3239152c49..8fa82122d8d 100644 --- a/Include/cpython/listobject.h +++ b/Include/cpython/listobject.h @@ -24,11 +24,24 @@ typedef struct { PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *); PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out); -/* Macro, trading safety for speed */ - /* Cast argument to PyListObject* type. */ -#define _PyList_CAST(op) (assert(PyList_Check(op)), (PyListObject *)(op)) +#define _PyList_CAST(op) \ + (assert(PyList_Check(op)), _Py_CAST(PyListObject*, (op))) -#define PyList_GET_ITEM(op, i) (_PyList_CAST(op)->ob_item[i]) -#define PyList_SET_ITEM(op, i, v) ((void)(_PyList_CAST(op)->ob_item[i] = (v))) -#define PyList_GET_SIZE(op) Py_SIZE(_PyList_CAST(op)) +// Macros and static inline functions, trading safety for speed + +static inline Py_ssize_t PyList_GET_SIZE(PyObject *op) { + PyListObject *list = _PyList_CAST(op); + return Py_SIZE(list); +} +#define PyList_GET_SIZE(op) PyList_GET_SIZE(_PyObject_CAST(op)) + +#define PyList_GET_ITEM(op, index) (_PyList_CAST(op)->ob_item[(index)]) + +static inline void +PyList_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) { + PyListObject *list = _PyList_CAST(op); + list->ob_item[index] = value; +} +#define PyList_SET_ITEM(op, index, value) \ + PyList_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value)) diff --git a/Include/cpython/longintrepr.h b/Include/cpython/longintrepr.h index ff4155f9656..6d52427508b 100644 --- a/Include/cpython/longintrepr.h +++ b/Include/cpython/longintrepr.h @@ -21,8 +21,6 @@ extern "C" { PyLong_SHIFT. The majority of the code doesn't care about the precise value of PyLong_SHIFT, but there are some notable exceptions: - - long_pow() requires that PyLong_SHIFT be divisible by 5 - - PyLong_{As,From}ByteArray require that PyLong_SHIFT be at least 8 - long_hash() requires that PyLong_SHIFT is *strictly* less than the number @@ -63,10 +61,6 @@ typedef long stwodigits; /* signed variant of twodigits */ #define PyLong_BASE ((digit)1 << PyLong_SHIFT) #define PyLong_MASK ((digit)(PyLong_BASE - 1)) -#if PyLong_SHIFT % 5 != 0 -#error "longobject.c requires that PyLong_SHIFT be divisible by 5" -#endif - /* Long integer representation. The absolute value of a number is equal to SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i) @@ -77,6 +71,9 @@ typedef long stwodigits; /* signed variant of twodigits */ 0 <= ob_digit[i] <= MASK. The allocation function takes care of allocating extra memory so that ob_digit[0] ... ob_digit[abs(ob_size)-1] are actually available. + We always allocate memory for at least one digit, so accessing ob_digit[0] + is always safe. However, in the case ob_size == 0, the contents of + ob_digit[0] may be undefined. CAUTION: Generic code manipulating subtypes of PyVarObject has to aware that ints abuse ob_size's sign bit. diff --git a/Include/cpython/memoryobject.h b/Include/cpython/memoryobject.h new file mode 100644 index 00000000000..deab3cc89f7 --- /dev/null +++ b/Include/cpython/memoryobject.h @@ -0,0 +1,51 @@ +#ifndef Py_CPYTHON_MEMORYOBJECT_H +# error "this header file must not be included directly" +#endif + +PyAPI_DATA(PyTypeObject) _PyManagedBuffer_Type; + +/* The structs are declared here so that macros can work, but they shouldn't + be considered public. Don't access their fields directly, use the macros + and functions instead! */ +#define _Py_MANAGED_BUFFER_RELEASED 0x001 /* access to exporter blocked */ +#define _Py_MANAGED_BUFFER_FREE_FORMAT 0x002 /* free format */ + +typedef struct { + PyObject_HEAD + int flags; /* state flags */ + Py_ssize_t exports; /* number of direct memoryview exports */ + Py_buffer master; /* snapshot buffer obtained from the original exporter */ +} _PyManagedBufferObject; + + +/* memoryview state flags */ +#define _Py_MEMORYVIEW_RELEASED 0x001 /* access to master buffer blocked */ +#define _Py_MEMORYVIEW_C 0x002 /* C-contiguous layout */ +#define _Py_MEMORYVIEW_FORTRAN 0x004 /* Fortran contiguous layout */ +#define _Py_MEMORYVIEW_SCALAR 0x008 /* scalar: ndim = 0 */ +#define _Py_MEMORYVIEW_PIL 0x010 /* PIL-style layout */ + +typedef struct { + PyObject_VAR_HEAD + _PyManagedBufferObject *mbuf; /* managed buffer */ + Py_hash_t hash; /* hash value for read-only views */ + int flags; /* state flags */ + Py_ssize_t exports; /* number of buffer re-exports */ + Py_buffer view; /* private copy of the exporter's view */ + PyObject *weakreflist; + Py_ssize_t ob_array[1]; /* shape, strides, suboffsets */ +} PyMemoryViewObject; + +#define _PyMemoryView_CAST(op) _Py_CAST(PyMemoryViewObject*, op) + +/* Get a pointer to the memoryview's private copy of the exporter's buffer. */ +static inline Py_buffer* PyMemoryView_GET_BUFFER(PyObject *op) { + return (&_PyMemoryView_CAST(op)->view); +} +#define PyMemoryView_GET_BUFFER(op) PyMemoryView_GET_BUFFER(_PyObject_CAST(op)) + +/* Get a pointer to the exporting object (this may be NULL!). */ +static inline PyObject* PyMemoryView_GET_BASE(PyObject *op) { + return _PyMemoryView_CAST(op)->view.obj; +} +#define PyMemoryView_GET_BASE(op) PyMemoryView_GET_BASE(_PyObject_CAST(op)) diff --git a/Include/cpython/methodobject.h b/Include/cpython/methodobject.h index 7ecbfe3b5e2..d541e154948 100644 --- a/Include/cpython/methodobject.h +++ b/Include/cpython/methodobject.h @@ -2,23 +2,7 @@ # error "this header file must not be included directly" #endif -PyAPI_DATA(PyTypeObject) PyCMethod_Type; - -#define PyCMethod_CheckExact(op) Py_IS_TYPE(op, &PyCMethod_Type) -#define PyCMethod_Check(op) PyObject_TypeCheck(op, &PyCMethod_Type) - -/* Macros for direct access to these values. Type checks are *not* - done, so use with care. */ -#define PyCFunction_GET_FUNCTION(func) \ - (((PyCFunctionObject *)func) -> m_ml -> ml_meth) -#define PyCFunction_GET_SELF(func) \ - (((PyCFunctionObject *)func) -> m_ml -> ml_flags & METH_STATIC ? \ - NULL : ((PyCFunctionObject *)func) -> m_self) -#define PyCFunction_GET_FLAGS(func) \ - (((PyCFunctionObject *)func) -> m_ml -> ml_flags) -#define PyCFunction_GET_CLASS(func) \ - (((PyCFunctionObject *)func) -> m_ml -> ml_flags & METH_METHOD ? \ - ((PyCMethodObject *)func) -> mm_class : NULL) +// PyCFunctionObject structure typedef struct { PyObject_HEAD @@ -29,7 +13,54 @@ typedef struct { vectorcallfunc vectorcall; } PyCFunctionObject; +#define _PyCFunctionObject_CAST(func) \ + (assert(PyCFunction_Check(func)), \ + _Py_CAST(PyCFunctionObject*, (func))) + + +// PyCMethodObject structure + typedef struct { PyCFunctionObject func; PyTypeObject *mm_class; /* Class that defines this method */ } PyCMethodObject; + +#define _PyCMethodObject_CAST(func) \ + (assert(PyCMethod_Check(func)), \ + _Py_CAST(PyCMethodObject*, (func))) + +PyAPI_DATA(PyTypeObject) PyCMethod_Type; + +#define PyCMethod_CheckExact(op) Py_IS_TYPE((op), &PyCMethod_Type) +#define PyCMethod_Check(op) PyObject_TypeCheck((op), &PyCMethod_Type) + + +/* Static inline functions for direct access to these values. + Type checks are *not* done, so use with care. */ +static inline PyCFunction PyCFunction_GET_FUNCTION(PyObject *func) { + return _PyCFunctionObject_CAST(func)->m_ml->ml_meth; +} +#define PyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(_PyObject_CAST(func)) + +static inline PyObject* PyCFunction_GET_SELF(PyObject *func_obj) { + PyCFunctionObject *func = _PyCFunctionObject_CAST(func_obj); + if (func->m_ml->ml_flags & METH_STATIC) { + return _Py_NULL; + } + return func->m_self; +} +#define PyCFunction_GET_SELF(func) PyCFunction_GET_SELF(_PyObject_CAST(func)) + +static inline int PyCFunction_GET_FLAGS(PyObject *func) { + return _PyCFunctionObject_CAST(func)->m_ml->ml_flags; +} +#define PyCFunction_GET_FLAGS(func) PyCFunction_GET_FLAGS(_PyObject_CAST(func)) + +static inline PyTypeObject* PyCFunction_GET_CLASS(PyObject *func_obj) { + PyCFunctionObject *func = _PyCFunctionObject_CAST(func_obj); + if (func->m_ml->ml_flags & METH_METHOD) { + return _PyCMethodObject_CAST(func)->mm_class; + } + return _Py_NULL; +} +#define PyCFunction_GET_CLASS(func) PyCFunction_GET_CLASS(_PyObject_CAST(func)) diff --git a/Include/cpython/modsupport.h b/Include/cpython/modsupport.h new file mode 100644 index 00000000000..88f34fe7513 --- /dev/null +++ b/Include/cpython/modsupport.h @@ -0,0 +1,108 @@ +#ifndef Py_CPYTHON_MODSUPPORT_H +# error "this header file must not be included directly" +#endif + +/* If PY_SSIZE_T_CLEAN is defined, each functions treats #-specifier + to mean Py_ssize_t */ +#ifdef PY_SSIZE_T_CLEAN +#define _Py_VaBuildStack _Py_VaBuildStack_SizeT +#else +PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list); +PyAPI_FUNC(PyObject **) _Py_VaBuildStack_SizeT( + PyObject **small_stack, + Py_ssize_t small_stack_len, + const char *format, + va_list va, + Py_ssize_t *p_nargs); +#endif + +PyAPI_FUNC(int) _PyArg_UnpackStack( + PyObject *const *args, + Py_ssize_t nargs, + const char *name, + Py_ssize_t min, + Py_ssize_t max, + ...); + +PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kwargs); +PyAPI_FUNC(int) _PyArg_NoKwnames(const char *funcname, PyObject *kwnames); +PyAPI_FUNC(int) _PyArg_NoPositional(const char *funcname, PyObject *args); +#define _PyArg_NoKeywords(funcname, kwargs) \ + ((kwargs) == NULL || _PyArg_NoKeywords((funcname), (kwargs))) +#define _PyArg_NoKwnames(funcname, kwnames) \ + ((kwnames) == NULL || _PyArg_NoKwnames((funcname), (kwnames))) +#define _PyArg_NoPositional(funcname, args) \ + ((args) == NULL || _PyArg_NoPositional((funcname), (args))) + +#define _Py_ANY_VARARGS(n) ((n) == PY_SSIZE_T_MAX) + +PyAPI_FUNC(void) _PyArg_BadArgument(const char *, const char *, const char *, PyObject *); +PyAPI_FUNC(int) _PyArg_CheckPositional(const char *, Py_ssize_t, + Py_ssize_t, Py_ssize_t); +#define _PyArg_CheckPositional(funcname, nargs, min, max) \ + ((!_Py_ANY_VARARGS(max) && (min) <= (nargs) && (nargs) <= (max)) \ + || _PyArg_CheckPositional((funcname), (nargs), (min), (max))) + +PyAPI_FUNC(PyObject **) _Py_VaBuildStack( + PyObject **small_stack, + Py_ssize_t small_stack_len, + const char *format, + va_list va, + Py_ssize_t *p_nargs); + +typedef struct _PyArg_Parser { + int initialized; + const char *format; + const char * const *keywords; + const char *fname; + const char *custom_msg; + int pos; /* number of positional-only arguments */ + int min; /* minimal number of arguments */ + int max; /* maximal number of positional arguments */ + PyObject *kwtuple; /* tuple of keyword parameter names */ + struct _PyArg_Parser *next; +} _PyArg_Parser; + +#ifdef PY_SSIZE_T_CLEAN +#define _PyArg_ParseTupleAndKeywordsFast _PyArg_ParseTupleAndKeywordsFast_SizeT +#define _PyArg_ParseStack _PyArg_ParseStack_SizeT +#define _PyArg_ParseStackAndKeywords _PyArg_ParseStackAndKeywords_SizeT +#define _PyArg_VaParseTupleAndKeywordsFast _PyArg_VaParseTupleAndKeywordsFast_SizeT +#endif + +PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *, + struct _PyArg_Parser *, ...); +PyAPI_FUNC(int) _PyArg_ParseStack( + PyObject *const *args, + Py_ssize_t nargs, + const char *format, + ...); +PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords( + PyObject *const *args, + Py_ssize_t nargs, + PyObject *kwnames, + struct _PyArg_Parser *, + ...); +PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *, + struct _PyArg_Parser *, va_list); +PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywords( + PyObject *const *args, Py_ssize_t nargs, + PyObject *kwargs, PyObject *kwnames, + struct _PyArg_Parser *parser, + int minpos, int maxpos, int minkw, + PyObject **buf); + +PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywordsWithVararg( + PyObject *const *args, Py_ssize_t nargs, + PyObject *kwargs, PyObject *kwnames, + struct _PyArg_Parser *parser, + int minpos, int maxpos, int minkw, + int vararg, PyObject **buf); + +#define _PyArg_UnpackKeywords(args, nargs, kwargs, kwnames, parser, minpos, maxpos, minkw, buf) \ + (((minkw) == 0 && (kwargs) == NULL && (kwnames) == NULL && \ + (minpos) <= (nargs) && (nargs) <= (maxpos) && (args) != NULL) ? (args) : \ + _PyArg_UnpackKeywords((args), (nargs), (kwargs), (kwnames), (parser), \ + (minpos), (maxpos), (minkw), (buf))) + +PyAPI_FUNC(PyObject *) _PyModule_CreateInitialized(PyModuleDef*, int apiver); diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 3a8a256e3b9..3f26f2487d7 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -41,65 +41,15 @@ typedef struct _Py_Identifier { Py_ssize_t index; } _Py_Identifier; -#define _Py_static_string_init(value) { .string = value, .index = -1 } +#ifndef Py_BUILD_CORE +// For now we are keeping _Py_IDENTIFIER for continued use +// in non-builtin extensions (and naughty PyPI modules). + +#define _Py_static_string_init(value) { .string = (value), .index = -1 } #define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value) #define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname) -/* buffer interface */ -typedef struct bufferinfo { - void *buf; - PyObject *obj; /* owned reference */ - Py_ssize_t len; - Py_ssize_t itemsize; /* This is Py_ssize_t so it can be - pointed to by strides in simple case.*/ - int readonly; - int ndim; - char *format; - Py_ssize_t *shape; - Py_ssize_t *strides; - Py_ssize_t *suboffsets; - void *internal; -} Py_buffer; - -typedef int (*getbufferproc)(PyObject *, Py_buffer *, int); -typedef void (*releasebufferproc)(PyObject *, Py_buffer *); - -typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, - size_t nargsf, PyObject *kwnames); - -/* Maximum number of dimensions */ -#define PyBUF_MAX_NDIM 64 - -/* Flags for getting buffers */ -#define PyBUF_SIMPLE 0 -#define PyBUF_WRITABLE 0x0001 -/* we used to include an E, backwards compatible alias */ -#define PyBUF_WRITEABLE PyBUF_WRITABLE -#define PyBUF_FORMAT 0x0004 -#define PyBUF_ND 0x0008 -#define PyBUF_STRIDES (0x0010 | PyBUF_ND) -#define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES) -#define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES) -#define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES) -#define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES) - -#define PyBUF_CONTIG (PyBUF_ND | PyBUF_WRITABLE) -#define PyBUF_CONTIG_RO (PyBUF_ND) - -#define PyBUF_STRIDED (PyBUF_STRIDES | PyBUF_WRITABLE) -#define PyBUF_STRIDED_RO (PyBUF_STRIDES) - -#define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT) -#define PyBUF_RECORDS_RO (PyBUF_STRIDES | PyBUF_FORMAT) - -#define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT) -#define PyBUF_FULL_RO (PyBUF_INDIRECT | PyBUF_FORMAT) - - -#define PyBUF_READ 0x100 -#define PyBUF_WRITE 0x200 -/* End buffer interface */ - +#endif /* !Py_BUILD_CORE */ typedef struct { /* Number implementations must check *both* @@ -244,11 +194,11 @@ struct _typeobject { iternextfunc tp_iternext; /* Attribute descriptor and subclassing stuff */ - struct PyMethodDef *tp_methods; - struct PyMemberDef *tp_members; - struct PyGetSetDef *tp_getset; + PyMethodDef *tp_methods; + PyMemberDef *tp_members; + PyGetSetDef *tp_getset; // Strong reference on a heap type, borrowed reference on a static type - struct _typeobject *tp_base; + PyTypeObject *tp_base; PyObject *tp_dict; descrgetfunc tp_descr_get; descrsetfunc tp_descr_set; @@ -260,9 +210,9 @@ struct _typeobject { inquiry tp_is_gc; /* For PyObject_IS_GC */ PyObject *tp_bases; PyObject *tp_mro; /* method resolution order */ - PyObject *tp_cache; - PyObject *tp_subclasses; - PyObject *tp_weaklist; + PyObject *tp_cache; /* no longer used */ + void *tp_subclasses; /* for static builtin types this is an index */ + PyObject *tp_weaklist; /* not used for static builtin types */ destructor tp_del; /* Type attribute cache version tag. Added in version 2.6 */ @@ -270,7 +220,16 @@ struct _typeobject { destructor tp_finalize; vectorcallfunc tp_vectorcall; - Py_ssize_t tp_inline_values_offset; + + /* bitset of which type-watchers care about this type */ + char tp_watched; +}; + +/* This struct is used by the specializer + * It should should be treated as an opaque blob + * by code other than the specializer and interpreter. */ +struct _specialization_cache { + PyObject *getitem; }; /* The *real* layout of a type object when allocated on the heap */ @@ -291,32 +250,32 @@ typedef struct _heaptypeobject { struct _dictkeysobject *ht_cached_keys; PyObject *ht_module; char *_ht_tpname; // Storage for "tp_name"; see PyType_FromModuleAndSpec + struct _specialization_cache _spec_cache; // For use by the specializer. /* here are optional user slots, followed by the members. */ } PyHeapTypeObject; -/* access macro to the members which are floating "behind" the object */ -#define PyHeapType_GET_MEMBERS(etype) \ - ((PyMemberDef *)(((char *)etype) + Py_TYPE(etype)->tp_basicsize)) - PyAPI_FUNC(const char *) _PyType_Name(PyTypeObject *); PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *); PyAPI_FUNC(PyObject *) _PyType_LookupId(PyTypeObject *, _Py_Identifier *); -PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, _Py_Identifier *); +PyAPI_FUNC(PyObject *) _PyObject_LookupSpecialId(PyObject *, _Py_Identifier *); +#ifndef Py_BUILD_CORE +// Backward compatibility for 3rd-party extensions +// that may be using the old name. +#define _PyObject_LookupSpecial _PyObject_LookupSpecialId +#endif PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *); PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *); PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *); -struct PyModuleDef; -PyAPI_FUNC(PyObject *) _PyType_GetModuleByDef(PyTypeObject *, struct PyModuleDef *); +PyAPI_FUNC(PyObject *) PyType_GetModuleByDef(PyTypeObject *, PyModuleDef *); -struct _Py_Identifier; PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); PyAPI_FUNC(void) _Py_BreakPoint(void); PyAPI_FUNC(void) _PyObject_Dump(PyObject *); PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *); PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *); -PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, struct _Py_Identifier *); -PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, struct _Py_Identifier *, PyObject *); +PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, _Py_Identifier *); +PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, _Py_Identifier *, PyObject *); /* Replacements of PyObject_GetAttr() and _PyObject_GetAttrId() which don't raise AttributeError. @@ -327,7 +286,7 @@ PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, struct _Py_Identifier *, PyObjec is raised. */ PyAPI_FUNC(int) _PyObject_LookupAttr(PyObject *, PyObject *, PyObject **); -PyAPI_FUNC(int) _PyObject_LookupAttrId(PyObject *, struct _Py_Identifier *, PyObject **); +PyAPI_FUNC(int) _PyObject_LookupAttrId(PyObject *, _Py_Identifier *, PyObject **); PyAPI_FUNC(int) _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); @@ -346,38 +305,69 @@ _PyObject_GenericSetAttrWithDict(PyObject *, PyObject *, PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *); -/* Safely decref `op` and set `op` to `op2`. +/* Safely decref `dst` and set `dst` to `src`. * * As in case of Py_CLEAR "the obvious" code can be deadly: * - * Py_DECREF(op); - * op = op2; + * Py_DECREF(dst); + * dst = src; * * The safe way is: * - * Py_SETREF(op, op2); + * Py_SETREF(dst, src); * - * That arranges to set `op` to `op2` _before_ decref'ing, so that any code - * triggered as a side-effect of `op` getting torn down no longer believes - * `op` points to a valid object. + * That arranges to set `dst` to `src` _before_ decref'ing, so that any code + * triggered as a side-effect of `dst` getting torn down no longer believes + * `dst` points to a valid object. * - * Py_XSETREF is a variant of Py_SETREF that uses Py_XDECREF instead of - * Py_DECREF. + * Temporary variables are used to only evalutate macro arguments once and so + * avoid the duplication of side effects. _Py_TYPEOF() or memcpy() is used to + * avoid a miscompilation caused by type punning. See Py_CLEAR() comment for + * implementation details about type punning. + * + * The memcpy() implementation does not emit a compiler warning if 'src' has + * not the same type than 'src': any pointer type is accepted for 'src'. */ - -#define Py_SETREF(op, op2) \ - do { \ - PyObject *_py_tmp = _PyObject_CAST(op); \ - (op) = (op2); \ - Py_DECREF(_py_tmp); \ +#ifdef _Py_TYPEOF +#define Py_SETREF(dst, src) \ + do { \ + _Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \ + _Py_TYPEOF(dst) _tmp_old_dst = (*_tmp_dst_ptr); \ + *_tmp_dst_ptr = (src); \ + Py_DECREF(_tmp_old_dst); \ } while (0) - -#define Py_XSETREF(op, op2) \ - do { \ - PyObject *_py_tmp = _PyObject_CAST(op); \ - (op) = (op2); \ - Py_XDECREF(_py_tmp); \ +#else +#define Py_SETREF(dst, src) \ + do { \ + PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \ + PyObject *_tmp_old_dst = (*_tmp_dst_ptr); \ + PyObject *_tmp_src = _PyObject_CAST(src); \ + memcpy(_tmp_dst_ptr, &_tmp_src, sizeof(PyObject*)); \ + Py_DECREF(_tmp_old_dst); \ } while (0) +#endif + +/* Py_XSETREF() is a variant of Py_SETREF() that uses Py_XDECREF() instead of + * Py_DECREF(). + */ +#ifdef _Py_TYPEOF +#define Py_XSETREF(dst, src) \ + do { \ + _Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \ + _Py_TYPEOF(dst) _tmp_old_dst = (*_tmp_dst_ptr); \ + *_tmp_dst_ptr = (src); \ + Py_XDECREF(_tmp_old_dst); \ + } while (0) +#else +#define Py_XSETREF(dst, src) \ + do { \ + PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \ + PyObject *_tmp_old_dst = (*_tmp_dst_ptr); \ + PyObject *_tmp_src = _PyObject_CAST(src); \ + memcpy(_tmp_dst_ptr, &_tmp_src, sizeof(PyObject*)); \ + Py_XDECREF(_tmp_old_dst); \ + } while (0) +#endif PyAPI_DATA(PyTypeObject) _PyNone_Type; @@ -422,9 +412,9 @@ _PyObject_DebugTypeStats(FILE *out); #endif #define _PyObject_ASSERT_WITH_MSG(obj, expr, msg) \ - _PyObject_ASSERT_FROM(obj, expr, msg, __FILE__, __LINE__, __func__) + _PyObject_ASSERT_FROM((obj), expr, (msg), __FILE__, __LINE__, __func__) #define _PyObject_ASSERT(obj, expr) \ - _PyObject_ASSERT_WITH_MSG(obj, expr, NULL) + _PyObject_ASSERT_WITH_MSG((obj), expr, NULL) #define _PyObject_ASSERT_FAILED_MSG(obj, msg) \ _PyObject_AssertFailed((obj), NULL, (msg), __FILE__, __LINE__, __func__) @@ -505,12 +495,9 @@ partially-deallocated object. To check this, the tp_dealloc function must be passed as second argument to Py_TRASHCAN_BEGIN(). */ -/* Forward declarations for PyThreadState */ -struct _ts; - /* Python 3.9 private API, invoked by the macros below. */ -PyAPI_FUNC(int) _PyTrash_begin(struct _ts *tstate, PyObject *op); -PyAPI_FUNC(void) _PyTrash_end(struct _ts *tstate); +PyAPI_FUNC(int) _PyTrash_begin(PyThreadState *tstate, PyObject *op); +PyAPI_FUNC(void) _PyTrash_end(PyThreadState *tstate); /* Python 3.10 private API, invoked by the Py_TRASHCAN_BEGIN(). */ PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, destructor dealloc); @@ -520,7 +507,7 @@ PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, destructor dealloc); /* If "cond" is false, then _tstate remains NULL and the deallocator \ * is run normally without involving the trashcan */ \ if (cond) { \ - _tstate = PyThreadState_Get(); \ + _tstate = _PyThreadState_UncheckedGet(); \ if (_PyTrash_begin(_tstate, _PyObject_CAST(op))) { \ break; \ } \ @@ -533,8 +520,8 @@ PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, destructor dealloc); } while (0); #define Py_TRASHCAN_BEGIN(op, dealloc) \ - Py_TRASHCAN_BEGIN_CONDITION(op, \ - _PyTrash_cond(_PyObject_CAST(op), (destructor)dealloc)) + Py_TRASHCAN_BEGIN_CONDITION((op), \ + _PyTrash_cond(_PyObject_CAST(op), (destructor)(dealloc))) /* The following two macros, Py_TRASHCAN_SAFE_BEGIN and * Py_TRASHCAN_SAFE_END, are deprecated since version 3.11 and @@ -545,7 +532,19 @@ Py_DEPRECATED(3.11) typedef int UsingDeprecatedTrashcanMacro; #define Py_TRASHCAN_SAFE_BEGIN(op) \ do { \ UsingDeprecatedTrashcanMacro cond=1; \ - Py_TRASHCAN_BEGIN_CONDITION(op, cond); + Py_TRASHCAN_BEGIN_CONDITION((op), cond); #define Py_TRASHCAN_SAFE_END(op) \ Py_TRASHCAN_END; \ } while(0); + + +PyAPI_FUNC(int) _PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg); +PyAPI_FUNC(void) _PyObject_ClearManagedDict(PyObject *obj); + +#define TYPE_MAX_WATCHERS 8 + +typedef int(*PyType_WatchCallback)(PyTypeObject *); +PyAPI_FUNC(int) PyType_AddWatcher(PyType_WatchCallback callback); +PyAPI_FUNC(int) PyType_ClearWatcher(int watcher_id); +PyAPI_FUNC(int) PyType_Watch(int watcher_id, PyObject *type); +PyAPI_FUNC(int) PyType_Unwatch(int watcher_id, PyObject *type); diff --git a/Include/cpython/objimpl.h b/Include/cpython/objimpl.h index d83700e2a46..0b038d31080 100644 --- a/Include/cpython/objimpl.h +++ b/Include/cpython/objimpl.h @@ -2,7 +2,9 @@ # error "this header file must not be included directly" #endif -#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) +static inline size_t _PyObject_SIZE(PyTypeObject *type) { + return _Py_STATIC_CAST(size_t, type->tp_basicsize); +} /* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a vrbl-size object with nitems items, exclusive of gc overhead (if any). The @@ -18,10 +20,11 @@ # error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2" #endif -#define _PyObject_VAR_SIZE(typeobj, nitems) \ - _Py_SIZE_ROUND_UP((typeobj)->tp_basicsize + \ - (nitems)*(typeobj)->tp_itemsize, \ - SIZEOF_VOID_P) +static inline size_t _PyObject_VAR_SIZE(PyTypeObject *type, Py_ssize_t nitems) { + size_t size = _Py_STATIC_CAST(size_t, type->tp_basicsize); + size += _Py_STATIC_CAST(size_t, nitems) * _Py_STATIC_CAST(size_t, type->tp_itemsize); + return _Py_SIZE_ROUND_UP(size, SIZEOF_VOID_P); +} /* This example code implements an object constructor with a custom @@ -52,14 +55,6 @@ the 1st step is performed automatically for you, so in a C++ class constructor you would start directly with PyObject_Init/InitVar. */ -/* This function returns the number of allocated memory blocks, regardless of size */ -PyAPI_FUNC(Py_ssize_t) _Py_GetAllocatedBlocks(void); - -/* Macros */ -#ifdef WITH_PYMALLOC -PyAPI_FUNC(int) _PyObject_DebugMallocStats(FILE *out); -#endif - typedef struct { /* user context passed as the first argument to the 2 functions */ @@ -90,11 +85,8 @@ PyAPI_FUNC(int) PyObject_IS_GC(PyObject *obj); # define _PyGC_FINALIZED(o) PyObject_GC_IsFinalized(o) #endif -PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t size); -PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size); - -/* Test if a type supports weak references */ -#define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0) +// Test if a type supports weak references +PyAPI_FUNC(int) PyType_SUPPORTS_WEAKREFS(PyTypeObject *type); PyAPI_FUNC(PyObject **) PyObject_GET_WEAKREFS_LISTPTR(PyObject *op); diff --git a/Include/cpython/odictobject.h b/Include/cpython/odictobject.h index e070413017d..3822d554868 100644 --- a/Include/cpython/odictobject.h +++ b/Include/cpython/odictobject.h @@ -18,8 +18,8 @@ PyAPI_DATA(PyTypeObject) PyODictKeys_Type; PyAPI_DATA(PyTypeObject) PyODictItems_Type; PyAPI_DATA(PyTypeObject) PyODictValues_Type; -#define PyODict_Check(op) PyObject_TypeCheck(op, &PyODict_Type) -#define PyODict_CheckExact(op) Py_IS_TYPE(op, &PyODict_Type) +#define PyODict_Check(op) PyObject_TypeCheck((op), &PyODict_Type) +#define PyODict_CheckExact(op) Py_IS_TYPE((op), &PyODict_Type) #define PyODict_SIZE(op) PyDict_GET_SIZE((op)) PyAPI_FUNC(PyObject *) PyODict_New(void); @@ -27,13 +27,13 @@ PyAPI_FUNC(int) PyODict_SetItem(PyObject *od, PyObject *key, PyObject *item); PyAPI_FUNC(int) PyODict_DelItem(PyObject *od, PyObject *key); /* wrappers around PyDict* functions */ -#define PyODict_GetItem(od, key) PyDict_GetItem(_PyObject_CAST(od), key) +#define PyODict_GetItem(od, key) PyDict_GetItem(_PyObject_CAST(od), (key)) #define PyODict_GetItemWithError(od, key) \ - PyDict_GetItemWithError(_PyObject_CAST(od), key) -#define PyODict_Contains(od, key) PyDict_Contains(_PyObject_CAST(od), key) + PyDict_GetItemWithError(_PyObject_CAST(od), (key)) +#define PyODict_Contains(od, key) PyDict_Contains(_PyObject_CAST(od), (key)) #define PyODict_Size(od) PyDict_Size(_PyObject_CAST(od)) #define PyODict_GetItemString(od, key) \ - PyDict_GetItemString(_PyObject_CAST(od), key) + PyDict_GetItemString(_PyObject_CAST(od), (key)) #endif diff --git a/Include/cpython/picklebufobject.h b/Include/cpython/picklebufobject.h index 0df2561dcea..f3cbaeef919 100644 --- a/Include/cpython/picklebufobject.h +++ b/Include/cpython/picklebufobject.h @@ -12,7 +12,7 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyPickleBuffer_Type; -#define PyPickleBuffer_Check(op) Py_IS_TYPE(op, &PyPickleBuffer_Type) +#define PyPickleBuffer_Check(op) Py_IS_TYPE((op), &PyPickleBuffer_Type) /* Create a PickleBuffer redirecting to the given buffer-enabled object */ PyAPI_FUNC(PyObject *) PyPickleBuffer_FromObject(PyObject *); diff --git a/Include/cpython/pthread_stubs.h b/Include/cpython/pthread_stubs.h new file mode 100644 index 00000000000..d95ee03d830 --- /dev/null +++ b/Include/cpython/pthread_stubs.h @@ -0,0 +1,88 @@ +#ifndef Py_CPYTHON_PTRHEAD_STUBS_H +#define Py_CPYTHON_PTRHEAD_STUBS_H + +#if !defined(HAVE_PTHREAD_STUBS) +# error "this header file requires stubbed pthreads." +#endif + +#ifndef _POSIX_THREADS +# define _POSIX_THREADS 1 +#endif + +/* Minimal pthread stubs for CPython. + * + * The stubs implement the minimum pthread API for CPython. + * - pthread_create() fails. + * - pthread_exit() calls exit(0). + * - pthread_key_*() functions implement minimal TSS without destructor. + * - all other functions do nothing and return 0. + */ + +#ifdef __wasi__ +// WASI's bits/alltypes.h provides type definitions when __NEED_ is set. +// The header file can be included multiple times. +# define __NEED_pthread_cond_t 1 +# define __NEED_pthread_condattr_t 1 +# define __NEED_pthread_mutex_t 1 +# define __NEED_pthread_mutexattr_t 1 +# define __NEED_pthread_key_t 1 +# define __NEED_pthread_t 1 +# define __NEED_pthread_attr_t 1 +# include +#else +typedef struct { void *__x; } pthread_cond_t; +typedef struct { unsigned __attr; } pthread_condattr_t; +typedef struct { void *__x; } pthread_mutex_t; +typedef struct { unsigned __attr; } pthread_mutexattr_t; +typedef unsigned pthread_key_t; +typedef unsigned pthread_t; +typedef struct { unsigned __attr; } pthread_attr_t; +#endif + +// mutex +PyAPI_FUNC(int) pthread_mutex_init(pthread_mutex_t *restrict mutex, + const pthread_mutexattr_t *restrict attr); +PyAPI_FUNC(int) pthread_mutex_destroy(pthread_mutex_t *mutex); +PyAPI_FUNC(int) pthread_mutex_trylock(pthread_mutex_t *mutex); +PyAPI_FUNC(int) pthread_mutex_lock(pthread_mutex_t *mutex); +PyAPI_FUNC(int) pthread_mutex_unlock(pthread_mutex_t *mutex); + +// condition +PyAPI_FUNC(int) pthread_cond_init(pthread_cond_t *restrict cond, + const pthread_condattr_t *restrict attr); +PyAPI_FUNC(int) pthread_cond_destroy(pthread_cond_t *cond); +PyAPI_FUNC(int) pthread_cond_wait(pthread_cond_t *restrict cond, + pthread_mutex_t *restrict mutex); +PyAPI_FUNC(int) pthread_cond_timedwait(pthread_cond_t *restrict cond, + pthread_mutex_t *restrict mutex, + const struct timespec *restrict abstime); +PyAPI_FUNC(int) pthread_cond_signal(pthread_cond_t *cond); +PyAPI_FUNC(int) pthread_condattr_init(pthread_condattr_t *attr); +PyAPI_FUNC(int) pthread_condattr_setclock( + pthread_condattr_t *attr, clockid_t clock_id); + +// pthread +PyAPI_FUNC(int) pthread_create(pthread_t *restrict thread, + const pthread_attr_t *restrict attr, + void *(*start_routine)(void *), + void *restrict arg); +PyAPI_FUNC(int) pthread_detach(pthread_t thread); +PyAPI_FUNC(pthread_t) pthread_self(void); +PyAPI_FUNC(int) pthread_exit(void *retval) __attribute__ ((__noreturn__)); +PyAPI_FUNC(int) pthread_attr_init(pthread_attr_t *attr); +PyAPI_FUNC(int) pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); +PyAPI_FUNC(int) pthread_attr_destroy(pthread_attr_t *attr); + + +// pthread_key +#ifndef PTHREAD_KEYS_MAX +# define PTHREAD_KEYS_MAX 128 +#endif + +PyAPI_FUNC(int) pthread_key_create(pthread_key_t *key, + void (*destr_function)(void *)); +PyAPI_FUNC(int) pthread_key_delete(pthread_key_t key); +PyAPI_FUNC(void *) pthread_getspecific(pthread_key_t key); +PyAPI_FUNC(int) pthread_setspecific(pthread_key_t key, const void *value); + +#endif // Py_CPYTHON_PTRHEAD_STUBS_H diff --git a/Include/cpython/pydebug.h b/Include/cpython/pydebug.h index cab799f0b38..f6ebd99ed7e 100644 --- a/Include/cpython/pydebug.h +++ b/Include/cpython/pydebug.h @@ -5,31 +5,31 @@ extern "C" { #endif -PyAPI_DATA(int) Py_DebugFlag; -PyAPI_DATA(int) Py_VerboseFlag; -PyAPI_DATA(int) Py_QuietFlag; -PyAPI_DATA(int) Py_InteractiveFlag; -PyAPI_DATA(int) Py_InspectFlag; -PyAPI_DATA(int) Py_OptimizeFlag; -PyAPI_DATA(int) Py_NoSiteFlag; -PyAPI_DATA(int) Py_BytesWarningFlag; -PyAPI_DATA(int) Py_FrozenFlag; -PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; -PyAPI_DATA(int) Py_DontWriteBytecodeFlag; -PyAPI_DATA(int) Py_NoUserSiteDirectory; -PyAPI_DATA(int) Py_UnbufferedStdioFlag; -PyAPI_DATA(int) Py_HashRandomizationFlag; -PyAPI_DATA(int) Py_IsolatedFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_DebugFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_VerboseFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_QuietFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_InteractiveFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_InspectFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_OptimizeFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_NoSiteFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_BytesWarningFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_FrozenFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_DontWriteBytecodeFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_NoUserSiteDirectory; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_UnbufferedStdioFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_HashRandomizationFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_IsolatedFlag; #ifdef MS_WINDOWS -PyAPI_DATA(int) Py_LegacyWindowsFSEncodingFlag; -PyAPI_DATA(int) Py_LegacyWindowsStdioFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_LegacyWindowsFSEncodingFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_LegacyWindowsStdioFlag; #endif /* this is a wrapper around getenv() that pays attention to Py_IgnoreEnvironmentFlag. It should be used for getting variables like PYTHONPATH and PYTHONHOME from the environment */ -PyAPI_DATA(char*) Py_GETENV(const char *name); +PyAPI_FUNC(char*) Py_GETENV(const char *name); #ifdef __cplusplus } diff --git a/Include/cpython/pyerrors.h b/Include/cpython/pyerrors.h index a07018abae0..14134166779 100644 --- a/Include/cpython/pyerrors.h +++ b/Include/cpython/pyerrors.h @@ -6,7 +6,7 @@ /* PyException_HEAD defines the initial segment of every exception class. */ #define PyException_HEAD PyObject_HEAD PyObject *dict;\ - PyObject *args; PyObject *traceback;\ + PyObject *args; PyObject *notes; PyObject *traceback;\ PyObject *context; PyObject *cause;\ char suppress_context; @@ -37,6 +37,7 @@ typedef struct { PyObject *msg; PyObject *name; PyObject *path; + PyObject *name_from; } PyImportErrorObject; typedef struct { @@ -91,6 +92,8 @@ typedef PyOSErrorObject PyWindowsErrorObject; PyAPI_FUNC(void) _PyErr_SetKeyError(PyObject *); PyAPI_FUNC(_PyErr_StackItem*) _PyErr_GetTopmostException(PyThreadState *tstate); +PyAPI_FUNC(PyObject*) _PyErr_GetHandledException(PyThreadState *); +PyAPI_FUNC(void) _PyErr_SetHandledException(PyThreadState *, PyObject *); PyAPI_FUNC(void) _PyErr_GetExcInfo(PyThreadState *, PyObject **, PyObject **, PyObject **); /* Context manipulation (PEP 3134) */ @@ -174,4 +177,11 @@ PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFormat( const char *format, ...); -#define Py_FatalError(message) _Py_FatalErrorFunc(__func__, message) +extern PyObject *_PyErr_SetImportErrorWithNameFrom( + PyObject *, + PyObject *, + PyObject *, + PyObject *); + + +#define Py_FatalError(message) _Py_FatalErrorFunc(__func__, (message)) diff --git a/Include/cpython/pyframe.h b/Include/cpython/pyframe.h new file mode 100644 index 00000000000..6ec292718af --- /dev/null +++ b/Include/cpython/pyframe.h @@ -0,0 +1,18 @@ +#ifndef Py_CPYTHON_PYFRAME_H +# error "this header file must not be included directly" +#endif + +PyAPI_DATA(PyTypeObject) PyFrame_Type; + +#define PyFrame_Check(op) Py_IS_TYPE((op), &PyFrame_Type) + +PyAPI_FUNC(PyFrameObject *) PyFrame_GetBack(PyFrameObject *frame); +PyAPI_FUNC(PyObject *) PyFrame_GetLocals(PyFrameObject *frame); + +PyAPI_FUNC(PyObject *) PyFrame_GetGlobals(PyFrameObject *frame); +PyAPI_FUNC(PyObject *) PyFrame_GetBuiltins(PyFrameObject *frame); + +PyAPI_FUNC(PyObject *) PyFrame_GetGenerator(PyFrameObject *frame); +PyAPI_FUNC(int) PyFrame_GetLasti(PyFrameObject *frame); +PyAPI_FUNC(PyObject*) PyFrame_GetVar(PyFrameObject *frame, PyObject *name); +PyAPI_FUNC(PyObject*) PyFrame_GetVarString(PyFrameObject *frame, const char *name); diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h index bb5b07ef590..e1f83acbffc 100644 --- a/Include/cpython/pylifecycle.h +++ b/Include/cpython/pylifecycle.h @@ -62,4 +62,5 @@ PyAPI_FUNC(int) _Py_CoerceLegacyLocale(int warn); PyAPI_FUNC(int) _Py_LegacyLocaleDetected(int warn); PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category); -PyAPI_FUNC(PyThreadState *) _Py_NewInterpreter(int isolated_subinterpreter); +PyAPI_FUNC(PyThreadState *) _Py_NewInterpreterFromConfig( + const _PyInterpreterConfig *); diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 9ac0a298baa..3c1e70de3e4 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -2,13 +2,40 @@ # error "this header file must not be included directly" #endif -#include "cpython/initconfig.h" + +/* +Runtime Feature Flags + +Each flag indicate whether or not a specific runtime feature +is available in a given context. For example, forking the process +might not be allowed in the current interpreter (i.e. os.fork() would fail). +*/ + +/* Set if threads are allowed. */ +#define Py_RTFLAGS_THREADS (1UL << 10) + +/* Set if daemon threads are allowed. */ +#define Py_RTFLAGS_DAEMON_THREADS (1UL << 11) + +/* Set if os.fork() is allowed. */ +#define Py_RTFLAGS_FORK (1UL << 15) + +/* Set if os.exec*() is allowed. */ +#define Py_RTFLAGS_EXEC (1UL << 16) + + +PyAPI_FUNC(int) _PyInterpreterState_HasFeature(PyInterpreterState *interp, + unsigned long feature); + + +/* private interpreter helpers */ PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *); PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int); PyAPI_FUNC(PyObject *) _PyInterpreterState_GetMainModule(PyInterpreterState *); + /* State unique per thread */ /* Py_tracefunc return -1 when raising an exception, or 0 for success. */ @@ -34,7 +61,9 @@ typedef struct { PyCodeAddressRange bounds; // Only valid if code != NULL. } PyTraceInfo; -typedef struct _cframe { +// Internal structure: you should not use it directly, but use public functions +// like PyThreadState_EnterTracing() and PyThreadState_LeaveTracing(). +typedef struct _PyCFrame { /* This struct will be threaded through the C stack * allowing fast access to per-thread state that needs * to be accessed quickly by the interpreter, but can @@ -45,20 +74,27 @@ typedef struct _cframe { * discipline and make sure that instances of this struct cannot * accessed outside of their lifetime. */ - int use_tracing; + uint8_t use_tracing; // 0 or 255 (or'ed into opcode, hence 8-bit type) /* Pointer to the currently executing frame (it can be NULL) */ - struct _interpreter_frame *current_frame; - struct _cframe *previous; -} CFrame; + struct _PyInterpreterFrame *current_frame; + struct _PyCFrame *previous; +} _PyCFrame; typedef struct _err_stackitem { - /* This struct represents an entry on the exception stack, which is a - * per-coroutine state. (Coroutine in the computer science sense, - * including the thread and generators). - * This ensures that the exception state is not impacted by "yields" - * from an except handler. + /* This struct represents a single execution context where we might + * be currently handling an exception. It is a per-coroutine state + * (coroutine in the computer science sense, including the thread + * and generators). + * + * This is used as an entry on the exception stack, where each + * entry indicates if it is currently handling an exception. + * This ensures that the exception state is not impacted + * by "yields" from an except handler. The thread + * always has an entry (the bottom-most one). */ - PyObject *exc_type, *exc_value, *exc_traceback; + + /* The exception currently being handled in this context, if any. */ + PyObject *exc_value; struct _err_stackitem *previous_item; @@ -71,26 +107,35 @@ typedef struct _stack_chunk { PyObject * data[1]; /* Variable sized */ } _PyStackChunk; -// The PyThreadState typedef is in Include/pystate.h. +struct _py_trashcan { + int delete_nesting; + PyObject *delete_later; +}; + struct _ts { /* See Python/ceval.c for comments explaining most fields */ - struct _ts *prev; - struct _ts *next; + PyThreadState *prev; + PyThreadState *next; PyInterpreterState *interp; - int recursion_remaining; - int recursion_limit; + int _status; + + int py_recursion_remaining; + int py_recursion_limit; + + int c_recursion_remaining; int recursion_headroom; /* Allow 50 more calls to handle any errors. */ /* 'tracing' keeps track of the execution depth when tracing/profiling. This is to prevent the actual trace/profile code from being recorded in the trace/profile. */ int tracing; + int tracing_what; /* The event currently being traced, if any. */ - /* Pointer to current CFrame in the C stack frame of the currently, + /* Pointer to current _PyCFrame in the C stack frame of the currently, * or most recently, executing _PyEval_EvalFrameDefault. */ - CFrame *cframe; + _PyCFrame *cframe; Py_tracefunc c_profilefunc; Py_tracefunc c_tracefunc; @@ -102,13 +147,9 @@ struct _ts { PyObject *curexc_value; PyObject *curexc_traceback; - /* The exception currently being handled, if no coroutines/generators - * are present. Always last element on the stack referred to be exc_info. - */ - _PyErr_StackItem exc_state; - - /* Pointer to the top of the stack of the exceptions currently - * being handled */ + /* Pointer to the top of the exception stack for the exceptions + * we may be currently handling. (See _PyErr_StackItem above.) + * This is never NULL. */ _PyErr_StackItem *exc_info; PyObject *dict; /* Stores per-thread state */ @@ -124,8 +165,7 @@ struct _ts { */ unsigned long native_thread_id; - int trash_delete_nesting; - PyObject *trash_delete_later; + struct _py_trashcan trash; /* Called when a thread state is deleted normally, but not when it * is destroyed after fork(). @@ -164,7 +204,6 @@ struct _ts { /* Unique thread state id. */ uint64_t id; - CFrame root_cframe; PyTraceInfo trace_info; _PyStackChunk *datastack_chunk; @@ -172,8 +211,37 @@ struct _ts { PyObject **datastack_limit; /* XXX signal handlers should also be here */ + /* The following fields are here to avoid allocation during init. + The data is exposed through PyThreadState pointer fields. + These fields should not be accessed directly outside of init. + This is indicated by an underscore prefix on the field names. + + All other PyInterpreterState pointer fields are populated when + needed and default to NULL. + */ + // Note some fields do not have a leading underscore for backward + // compatibility. See https://bugs.python.org/issue45953#msg412046. + + /* The thread's exception stack entry. (Always the last entry.) */ + _PyErr_StackItem exc_state; + + /* The bottom-most frame on the stack. */ + _PyCFrame root_cframe; }; +/* WASI has limited call stack. Python's recursion limit depends on code + layout, optimization, and WASI runtime. Wasmtime can handle about 700 + recursions, sometimes less. 500 is a more conservative limit. */ +#ifndef C_RECURSION_LIMIT +# ifdef __wasi__ +# define C_RECURSION_LIMIT 500 +# else +# define C_RECURSION_LIMIT 800 +# endif +#endif + +/* other API */ + // Alias for backward compatibility with Python 3.8 #define _PyInterpreterState_Get PyInterpreterState_Get @@ -230,7 +298,7 @@ PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void); /* Frame evaluation API */ -typedef PyObject* (*_PyFrameEvalFunction)(PyThreadState *tstate, struct _interpreter_frame *, int); +typedef PyObject* (*_PyFrameEvalFunction)(PyThreadState *tstate, struct _PyInterpreterFrame *, int); PyAPI_FUNC(_PyFrameEvalFunction) _PyInterpreterState_GetEvalFrameFunc( PyInterpreterState *interp); @@ -248,7 +316,10 @@ PyAPI_FUNC(const PyConfig*) _PyInterpreterState_GetConfig(PyInterpreterState *in for example. Python must be preinitialized to call this method. - The caller must hold the GIL. */ + The caller must hold the GIL. + + Once done with the configuration, PyConfig_Clear() must be called to clear + it. */ PyAPI_FUNC(int) _PyInterpreterState_GetConfigCopy( struct PyConfig *config); @@ -277,12 +348,15 @@ PyAPI_FUNC(const PyConfig*) _Py_GetConfig(void); /* cross-interpreter data */ -struct _xid; - // _PyCrossInterpreterData is similar to Py_buffer as an effectively // opaque struct that holds data outside the object machinery. This // is necessary to pass safely between interpreters in the same process. -typedef struct _xid { +typedef struct _xid _PyCrossInterpreterData; + +typedef PyObject *(*xid_newobjectfunc)(_PyCrossInterpreterData *); +typedef void (*xid_freefunc)(void *); + +struct _xid { // data is the cross-interpreter-safe derivation of a Python object // (see _PyObject_GetCrossInterpreterData). It will be NULL if the // new_object func (below) encodes the data. @@ -308,7 +382,7 @@ typedef struct _xid { // interpreter given the data. The resulting object (a new // reference) will be equivalent to the original object. This field // is required. - PyObject *(*new_object)(struct _xid *); + xid_newobjectfunc new_object; // free is called when the data is released. If it is NULL then // nothing will be done to free the data. For some types this is // okay (e.g. bytes) and for those types this field should be set @@ -318,18 +392,31 @@ typedef struct _xid { // leak. In that case, at the very least this field should be set // to PyMem_RawFree (the default if not explicitly set to NULL). // The call will happen with the original interpreter activated. - void (*free)(void *); -} _PyCrossInterpreterData; + xid_freefunc free; +}; + +PyAPI_FUNC(void) _PyCrossInterpreterData_Init( + _PyCrossInterpreterData *data, + PyInterpreterState *interp, void *shared, PyObject *obj, + xid_newobjectfunc new_object); +PyAPI_FUNC(int) _PyCrossInterpreterData_InitWithSize( + _PyCrossInterpreterData *, + PyInterpreterState *interp, const size_t, PyObject *, + xid_newobjectfunc); +PyAPI_FUNC(void) _PyCrossInterpreterData_Clear( + PyInterpreterState *, _PyCrossInterpreterData *); PyAPI_FUNC(int) _PyObject_GetCrossInterpreterData(PyObject *, _PyCrossInterpreterData *); PyAPI_FUNC(PyObject *) _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *); -PyAPI_FUNC(void) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *); +PyAPI_FUNC(int) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *); PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *); /* cross-interpreter data registry */ -typedef int (*crossinterpdatafunc)(PyObject *, struct _xid *); +typedef int (*crossinterpdatafunc)(PyThreadState *tstate, PyObject *, + _PyCrossInterpreterData *); PyAPI_FUNC(int) _PyCrossInterpreterData_RegisterClass(PyTypeObject *, crossinterpdatafunc); +PyAPI_FUNC(int) _PyCrossInterpreterData_UnregisterClass(PyTypeObject *); PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *); diff --git a/Include/cpython/pythonrun.h b/Include/cpython/pythonrun.h index 2e72d0820d3..fb617655374 100644 --- a/Include/cpython/pythonrun.h +++ b/Include/cpython/pythonrun.h @@ -66,8 +66,8 @@ PyAPI_FUNC(PyObject *) Py_CompileStringObject( PyCompilerFlags *flags, int optimize); -#define Py_CompileString(str, p, s) Py_CompileStringExFlags(str, p, s, NULL, -1) -#define Py_CompileStringFlags(str, p, s, f) Py_CompileStringExFlags(str, p, s, f, -1) +#define Py_CompileString(str, p, s) Py_CompileStringExFlags((str), (p), (s), NULL, -1) +#define Py_CompileStringFlags(str, p, s, f) Py_CompileStringExFlags((str), (p), (s), (f), -1) PyAPI_FUNC(const char *) _Py_SourceAsString( @@ -96,23 +96,23 @@ PyAPI_FUNC(PyObject *) PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyAPI_FUNC(PyObject *) PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, PyCompilerFlags *flags); /* Use macros for a bunch of old variants */ -#define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL) -#define PyRun_AnyFile(fp, name) PyRun_AnyFileExFlags(fp, name, 0, NULL) +#define PyRun_String(str, s, g, l) PyRun_StringFlags((str), (s), (g), (l), NULL) +#define PyRun_AnyFile(fp, name) PyRun_AnyFileExFlags((fp), (name), 0, NULL) #define PyRun_AnyFileEx(fp, name, closeit) \ - PyRun_AnyFileExFlags(fp, name, closeit, NULL) + PyRun_AnyFileExFlags((fp), (name), (closeit), NULL) #define PyRun_AnyFileFlags(fp, name, flags) \ - PyRun_AnyFileExFlags(fp, name, 0, flags) -#define PyRun_SimpleString(s) PyRun_SimpleStringFlags(s, NULL) -#define PyRun_SimpleFile(f, p) PyRun_SimpleFileExFlags(f, p, 0, NULL) -#define PyRun_SimpleFileEx(f, p, c) PyRun_SimpleFileExFlags(f, p, c, NULL) -#define PyRun_InteractiveOne(f, p) PyRun_InteractiveOneFlags(f, p, NULL) -#define PyRun_InteractiveLoop(f, p) PyRun_InteractiveLoopFlags(f, p, NULL) + PyRun_AnyFileExFlags((fp), (name), 0, (flags)) +#define PyRun_SimpleString(s) PyRun_SimpleStringFlags((s), NULL) +#define PyRun_SimpleFile(f, p) PyRun_SimpleFileExFlags((f), (p), 0, NULL) +#define PyRun_SimpleFileEx(f, p, c) PyRun_SimpleFileExFlags((f), (p), (c), NULL) +#define PyRun_InteractiveOne(f, p) PyRun_InteractiveOneFlags((f), (p), NULL) +#define PyRun_InteractiveLoop(f, p) PyRun_InteractiveLoopFlags((f), (p), NULL) #define PyRun_File(fp, p, s, g, l) \ - PyRun_FileExFlags(fp, p, s, g, l, 0, NULL) + PyRun_FileExFlags((fp), (p), (s), (g), (l), 0, NULL) #define PyRun_FileEx(fp, p, s, g, l, c) \ - PyRun_FileExFlags(fp, p, s, g, l, c, NULL) + PyRun_FileExFlags((fp), (p), (s), (g), (l), (c), NULL) #define PyRun_FileFlags(fp, p, s, g, l, flags) \ - PyRun_FileExFlags(fp, p, s, g, l, 0, flags) + PyRun_FileExFlags((fp), (p), (s), (g), (l), 0, (flags)) /* Stuff with no proper home (yet) */ diff --git a/Include/cpython/pythread.h b/Include/cpython/pythread.h new file mode 100644 index 00000000000..ce4ec8f65b1 --- /dev/null +++ b/Include/cpython/pythread.h @@ -0,0 +1,42 @@ +#ifndef Py_CPYTHON_PYTHREAD_H +# error "this header file must not be included directly" +#endif + +#define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1) + +#ifdef HAVE_FORK +/* Private function to reinitialize a lock at fork in the child process. + Reset the lock to the unlocked state. + Return 0 on success, return -1 on error. */ +PyAPI_FUNC(int) _PyThread_at_fork_reinit(PyThread_type_lock *lock); +#endif /* HAVE_FORK */ + +#ifdef HAVE_PTHREAD_H + /* Darwin needs pthread.h to know type name the pthread_key_t. */ +# include +# define NATIVE_TSS_KEY_T pthread_key_t +#elif defined(NT_THREADS) + /* In Windows, native TSS key type is DWORD, + but hardcode the unsigned long to avoid errors for include directive. + */ +# define NATIVE_TSS_KEY_T unsigned long +#elif defined(HAVE_PTHREAD_STUBS) +# include "cpython/pthread_stubs.h" +# define NATIVE_TSS_KEY_T pthread_key_t +#else +# error "Require native threads. See https://bugs.python.org/issue31370" +#endif + +/* When Py_LIMITED_API is not defined, the type layout of Py_tss_t is + exposed to allow static allocation in the API clients. Even in this case, + you must handle TSS keys through API functions due to compatibility. +*/ +struct _Py_tss_t { + int _is_initialized; + NATIVE_TSS_KEY_T _key; +}; + +#undef NATIVE_TSS_KEY_T + +/* When static allocation, you must initialize with Py_tss_NEEDS_INIT. */ +#define Py_tss_NEEDS_INIT {0} diff --git a/Include/cpython/pytime.h b/Include/cpython/pytime.h index 23d4f16a8fd..16d88d191e9 100644 --- a/Include/cpython/pytime.h +++ b/Include/cpython/pytime.h @@ -53,6 +53,10 @@ functions and constants extern "C" { #endif +#ifdef __clang__ +struct timeval; +#endif + /* _PyTime_t: Python timestamp with subsecond precision. It can be used to store a duration, and so indirectly a date (related to another date, like UNIX epoch). */ @@ -130,6 +134,10 @@ PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int seconds); /* Create a timestamp from a number of nanoseconds. */ PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(_PyTime_t ns); +/* Create a timestamp from a number of microseconds. + * Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. */ +PyAPI_FUNC(_PyTime_t) _PyTime_FromMicrosecondsClamp(_PyTime_t us); + /* Create a timestamp from nanoseconds (Python int). */ PyAPI_FUNC(int) _PyTime_FromNanosecondsObject(_PyTime_t *t, PyObject *obj); diff --git a/Include/cpython/setobject.h b/Include/cpython/setobject.h new file mode 100644 index 00000000000..20fd63eaae5 --- /dev/null +++ b/Include/cpython/setobject.h @@ -0,0 +1,72 @@ +#ifndef Py_CPYTHON_SETOBJECT_H +# error "this header file must not be included directly" +#endif + +/* There are three kinds of entries in the table: + +1. Unused: key == NULL and hash == 0 +2. Dummy: key == dummy and hash == -1 +3. Active: key != NULL and key != dummy and hash != -1 + +The hash field of Unused slots is always zero. + +The hash field of Dummy slots are set to -1 +meaning that dummy entries can be detected by +either entry->key==dummy or by entry->hash==-1. +*/ + +#define PySet_MINSIZE 8 + +typedef struct { + PyObject *key; + Py_hash_t hash; /* Cached hash code of the key */ +} setentry; + +/* The SetObject data structure is shared by set and frozenset objects. + +Invariant for sets: + - hash is -1 + +Invariants for frozensets: + - data is immutable. + - hash is the hash of the frozenset or -1 if not computed yet. + +*/ + +typedef struct { + PyObject_HEAD + + Py_ssize_t fill; /* Number active and dummy entries*/ + Py_ssize_t used; /* Number active entries */ + + /* The table contains mask + 1 slots, and that's a power of 2. + * We store the mask instead of the size because the mask is more + * frequently needed. + */ + Py_ssize_t mask; + + /* The table points to a fixed-size smalltable for small tables + * or to additional malloc'ed memory for bigger tables. + * The table pointer is never NULL which saves us from repeated + * runtime null-tests. + */ + setentry *table; + Py_hash_t hash; /* Only used by frozenset objects */ + Py_ssize_t finger; /* Search finger for pop() */ + + setentry smalltable[PySet_MINSIZE]; + PyObject *weakreflist; /* List of weak references */ +} PySetObject; + +#define _PySet_CAST(so) \ + (assert(PyAnySet_Check(so)), _Py_CAST(PySetObject*, so)) + +static inline Py_ssize_t PySet_GET_SIZE(PyObject *so) { + return _PySet_CAST(so)->used; +} +#define PySet_GET_SIZE(so) PySet_GET_SIZE(_PyObject_CAST(so)) + +PyAPI_DATA(PyObject *) _PySet_Dummy; + +PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash); +PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); diff --git a/Include/cpython/sysmodule.h b/Include/cpython/sysmodule.h index fc4c899b3fe..19d9dddc344 100644 --- a/Include/cpython/sysmodule.h +++ b/Include/cpython/sysmodule.h @@ -2,8 +2,8 @@ # error "this header file must not be included directly" #endif -PyAPI_FUNC(PyObject *) _PySys_GetObjectId(_Py_Identifier *key); -PyAPI_FUNC(int) _PySys_SetObjectId(_Py_Identifier *key, PyObject *); +PyAPI_FUNC(PyObject *) _PySys_GetAttr(PyThreadState *tstate, + PyObject *name); PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *); diff --git a/Include/cpython/traceback.h b/Include/cpython/traceback.h index d0dde335cfe..a4e087b2b4e 100644 --- a/Include/cpython/traceback.h +++ b/Include/cpython/traceback.h @@ -2,13 +2,15 @@ # error "this header file must not be included directly" #endif -typedef struct _traceback { +typedef struct _traceback PyTracebackObject; + +struct _traceback { PyObject_HEAD - struct _traceback *tb_next; + PyTracebackObject *tb_next; PyFrameObject *tb_frame; int tb_lasti; int tb_lineno; -} PyTracebackObject; +}; PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int, int *, PyObject **); PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int); diff --git a/Include/cpython/tupleobject.h b/Include/cpython/tupleobject.h index 7cada8848c4..f6a1f076e03 100644 --- a/Include/cpython/tupleobject.h +++ b/Include/cpython/tupleobject.h @@ -13,16 +13,27 @@ typedef struct { PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t); PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *); -/* Macros trading safety for speed */ - /* Cast argument to PyTupleObject* type. */ -#define _PyTuple_CAST(op) (assert(PyTuple_Check(op)), (PyTupleObject *)(op)) +#define _PyTuple_CAST(op) \ + (assert(PyTuple_Check(op)), _Py_CAST(PyTupleObject*, (op))) -#define PyTuple_GET_SIZE(op) Py_SIZE(_PyTuple_CAST(op)) +// Macros and static inline functions, trading safety for speed -#define PyTuple_GET_ITEM(op, i) (_PyTuple_CAST(op)->ob_item[i]) +static inline Py_ssize_t PyTuple_GET_SIZE(PyObject *op) { + PyTupleObject *tuple = _PyTuple_CAST(op); + return Py_SIZE(tuple); +} +#define PyTuple_GET_SIZE(op) PyTuple_GET_SIZE(_PyObject_CAST(op)) -/* Macro, *only* to be used to fill in brand new tuples */ -#define PyTuple_SET_ITEM(op, i, v) ((void)(_PyTuple_CAST(op)->ob_item[i] = v)) +#define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[(index)]) + +/* Function *only* to be used to fill in brand new tuples */ +static inline void +PyTuple_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) { + PyTupleObject *tuple = _PyTuple_CAST(op); + tuple->ob_item[index] = value; +} +#define PyTuple_SET_ITEM(op, index, value) \ + PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value)) PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out); diff --git a/Include/cpython/unicodeobject.h b/Include/cpython/unicodeobject.h index ab4aebf5e70..75a74ffa2f9 100644 --- a/Include/cpython/unicodeobject.h +++ b/Include/cpython/unicodeobject.h @@ -11,63 +11,43 @@ /* --- Internal Unicode Operations ---------------------------------------- */ -#ifndef USE_UNICODE_WCHAR_CACHE -# define USE_UNICODE_WCHAR_CACHE 1 -#endif /* USE_UNICODE_WCHAR_CACHE */ +// Static inline functions to work with surrogates +static inline int Py_UNICODE_IS_SURROGATE(Py_UCS4 ch) { + return (0xD800 <= ch && ch <= 0xDFFF); +} +static inline int Py_UNICODE_IS_HIGH_SURROGATE(Py_UCS4 ch) { + return (0xD800 <= ch && ch <= 0xDBFF); +} +static inline int Py_UNICODE_IS_LOW_SURROGATE(Py_UCS4 ch) { + return (0xDC00 <= ch && ch <= 0xDFFF); +} -/* Since splitting on whitespace is an important use case, and - whitespace in most situations is solely ASCII whitespace, we - optimize for the common case by using a quick look-up table - _Py_ascii_whitespace (see below) with an inlined check. +// Join two surrogate characters and return a single Py_UCS4 value. +static inline Py_UCS4 Py_UNICODE_JOIN_SURROGATES(Py_UCS4 high, Py_UCS4 low) { + assert(Py_UNICODE_IS_HIGH_SURROGATE(high)); + assert(Py_UNICODE_IS_LOW_SURROGATE(low)); + return 0x10000 + (((high & 0x03FF) << 10) | (low & 0x03FF)); +} - */ -#define Py_UNICODE_ISSPACE(ch) \ - ((Py_UCS4)(ch) < 128U ? _Py_ascii_whitespace[(ch)] : _PyUnicode_IsWhitespace(ch)) +// High surrogate = top 10 bits added to 0xD800. +// The character must be in the range [U+10000; U+10ffff]. +static inline Py_UCS4 Py_UNICODE_HIGH_SURROGATE(Py_UCS4 ch) { + assert(0x10000 <= ch && ch <= 0x10ffff); + return (0xD800 - (0x10000 >> 10) + (ch >> 10)); +} -#define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch) -#define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch) -#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) -#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) - -#define Py_UNICODE_TOLOWER(ch) _PyUnicode_ToLowercase(ch) -#define Py_UNICODE_TOUPPER(ch) _PyUnicode_ToUppercase(ch) -#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch) - -#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch) -#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch) -#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch) -#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch) - -#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch) -#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch) -#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch) - -#define Py_UNICODE_ISALPHA(ch) _PyUnicode_IsAlpha(ch) - -#define Py_UNICODE_ISALNUM(ch) \ - (Py_UNICODE_ISALPHA(ch) || \ - Py_UNICODE_ISDECIMAL(ch) || \ - Py_UNICODE_ISDIGIT(ch) || \ - Py_UNICODE_ISNUMERIC(ch)) - -/* macros to work with surrogates */ -#define Py_UNICODE_IS_SURROGATE(ch) (0xD800 <= (ch) && (ch) <= 0xDFFF) -#define Py_UNICODE_IS_HIGH_SURROGATE(ch) (0xD800 <= (ch) && (ch) <= 0xDBFF) -#define Py_UNICODE_IS_LOW_SURROGATE(ch) (0xDC00 <= (ch) && (ch) <= 0xDFFF) -/* Join two surrogate characters and return a single Py_UCS4 value. */ -#define Py_UNICODE_JOIN_SURROGATES(high, low) \ - (((((Py_UCS4)(high) & 0x03FF) << 10) | \ - ((Py_UCS4)(low) & 0x03FF)) + 0x10000) -/* high surrogate = top 10 bits added to D800 */ -#define Py_UNICODE_HIGH_SURROGATE(ch) (0xD800 - (0x10000 >> 10) + ((ch) >> 10)) -/* low surrogate = bottom 10 bits added to DC00 */ -#define Py_UNICODE_LOW_SURROGATE(ch) (0xDC00 + ((ch) & 0x3FF)) +// Low surrogate = bottom 10 bits added to 0xDC00. +// The character must be in the range [U+10000; U+10ffff]. +static inline Py_UCS4 Py_UNICODE_LOW_SURROGATE(Py_UCS4 ch) { + assert(0x10000 <= ch && ch <= 0x10ffff); + return (0xDC00 + (ch & 0x3FF)); +} /* --- Unicode Type ------------------------------------------------------- */ /* ASCII-only strings created through PyUnicode_New use the PyASCIIObject structure. state.ascii and state.compact are set, and the data - immediately follow the structure. utf8_length and wstr_length can be found + immediately follow the structure. utf8_length can be found in the length field; the utf8 pointer is equal to the data pointer. */ typedef struct { /* There are 4 forms of Unicode strings: @@ -79,8 +59,7 @@ typedef struct { * kind = PyUnicode_1BYTE_KIND * compact = 1 * ascii = 1 - * ready = 1 - * (length is the length of the utf8 and wstr strings) + * (length is the length of the utf8) * (data starts just after the structure) * (since ASCII is decoded from UTF-8, the utf8 string are the data) @@ -91,55 +70,27 @@ typedef struct { * kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or PyUnicode_4BYTE_KIND * compact = 1 - * ready = 1 * ascii = 0 * utf8 is not shared with data * utf8_length = 0 if utf8 is NULL - * wstr is shared with data and wstr_length=length - if kind=PyUnicode_2BYTE_KIND and sizeof(wchar_t)=2 - or if kind=PyUnicode_4BYTE_KIND and sizeof(wchar_t)=4 - * wstr_length = 0 if wstr is NULL * (data starts just after the structure) - - legacy string, not ready: - - * structure = PyUnicodeObject - * test: kind == PyUnicode_WCHAR_KIND - * length = 0 (use wstr_length) - * hash = -1 - * kind = PyUnicode_WCHAR_KIND - * compact = 0 - * ascii = 0 - * ready = 0 - * interned = SSTATE_NOT_INTERNED - * wstr is not NULL - * data.any is NULL - * utf8 is NULL - * utf8_length = 0 - - - legacy string, ready: + - legacy string: * structure = PyUnicodeObject structure - * test: !PyUnicode_IS_COMPACT(op) && kind != PyUnicode_WCHAR_KIND + * test: !PyUnicode_IS_COMPACT(op) * kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or PyUnicode_4BYTE_KIND * compact = 0 - * ready = 1 * data.any is not NULL * utf8 is shared and utf8_length = length with data.any if ascii = 1 * utf8_length = 0 if utf8 is NULL - * wstr is shared with data.any and wstr_length = length - if kind=PyUnicode_2BYTE_KIND and sizeof(wchar_t)=2 - or if kind=PyUnicode_4BYTE_KIND and sizeof(wchar_4)=4 - * wstr_length = 0 if wstr is NULL Compact strings use only one memory block (structure + characters), whereas legacy strings use one block for the structure and one block for characters. - Legacy strings are created by PyUnicode_FromUnicode() and - PyUnicode_FromStringAndSize(NULL, size) functions. They become ready - when PyUnicode_READY() is called. + Legacy strings are created by subclasses of Unicode. See also _PyUnicode_CheckConsistency(). */ @@ -147,22 +98,11 @@ typedef struct { Py_ssize_t length; /* Number of code points in the string */ Py_hash_t hash; /* Hash value; -1 if not set */ struct { - /* - SSTATE_NOT_INTERNED (0) - SSTATE_INTERNED_MORTAL (1) - SSTATE_INTERNED_IMMORTAL (2) - - If interned != SSTATE_NOT_INTERNED, the two references from the - dictionary to this object are *not* counted in ob_refcnt. - */ - unsigned int interned:2; + /* If interned is set, the two references from the + dictionary to this object are *not* counted in ob_refcnt. */ + unsigned int interned:1; /* Character size: - - PyUnicode_WCHAR_KIND (0): - - * character type = wchar_t (16 or 32 bits, depending on the - platform) - - PyUnicode_1BYTE_KIND (1): * character type = Py_UCS1 (8 bits, unsigned) @@ -193,16 +133,10 @@ typedef struct { and the kind is PyUnicode_1BYTE_KIND. If ascii is set and compact is set, use the PyASCIIObject structure. */ unsigned int ascii:1; - /* The ready flag indicates whether the object layout is initialized - completely. This means that this is either a compact object, or - the data pointer is filled out. The bit is redundant, and helps - to minimize the test in PyUnicode_IS_READY(). */ - unsigned int ready:1; /* Padding to ensure that PyUnicode_DATA() is always aligned to 4 bytes (see issue #19537 on m68k). */ - unsigned int :24; + unsigned int :26; } state; - wchar_t *wstr; /* wchar_t representation (null-terminated) */ } PyASCIIObject; /* Non-ASCII strings allocated through PyUnicode_New use the @@ -213,13 +147,9 @@ typedef struct { Py_ssize_t utf8_length; /* Number of bytes in utf8, excluding the * terminating \0. */ char *utf8; /* UTF-8 representation (null-terminated) */ - Py_ssize_t wstr_length; /* Number of code points in wstr, possible - * surrogates count as two code points. */ } PyCompactUnicodeObject; -/* Strings allocated through PyUnicode_FromUnicode(NULL, len) use the - PyUnicodeObject structure. The actual string data is initially in the wstr - block, and copied into the data block using _PyUnicode_Ready. */ +/* Object format for Unicode subclasses. */ typedef struct { PyCompactUnicodeObject _base; union { @@ -234,40 +164,16 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency( PyObject *op, int check_content); -/* Fast access macros */ -/* Returns the deprecated Py_UNICODE representation's size in code units - (this includes surrogate pairs as 2 units). - If the Py_UNICODE representation is not available, it will be computed - on request. Use PyUnicode_GET_LENGTH() for the length in code points. */ - -/* Py_DEPRECATED(3.3) */ -#define PyUnicode_GET_SIZE(op) \ - (assert(PyUnicode_Check(op)), \ - (((PyASCIIObject *)(op))->wstr) ? \ - PyUnicode_WSTR_LENGTH(op) : \ - ((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\ - assert(((PyASCIIObject *)(op))->wstr), \ - PyUnicode_WSTR_LENGTH(op))) - -/* Py_DEPRECATED(3.3) */ -#define PyUnicode_GET_DATA_SIZE(op) \ - (PyUnicode_GET_SIZE(op) * Py_UNICODE_SIZE) - -/* Alias for PyUnicode_AsUnicode(). This will create a wchar_t/Py_UNICODE - representation on demand. Using this macro is very inefficient now, - try to port your code to use the new PyUnicode_*BYTE_DATA() macros or - use PyUnicode_WRITE() and PyUnicode_READ(). */ - -/* Py_DEPRECATED(3.3) */ -#define PyUnicode_AS_UNICODE(op) \ +#define _PyASCIIObject_CAST(op) \ (assert(PyUnicode_Check(op)), \ - (((PyASCIIObject *)(op))->wstr) ? (((PyASCIIObject *)(op))->wstr) : \ - PyUnicode_AsUnicode(_PyObject_CAST(op))) - -/* Py_DEPRECATED(3.3) */ -#define PyUnicode_AS_DATA(op) \ - ((const char *)(PyUnicode_AS_UNICODE(op))) + _Py_CAST(PyASCIIObject*, (op))) +#define _PyCompactUnicodeObject_CAST(op) \ + (assert(PyUnicode_Check(op)), \ + _Py_CAST(PyCompactUnicodeObject*, (op))) +#define _PyUnicodeObject_CAST(op) \ + (assert(PyUnicode_Check(op)), \ + _Py_CAST(PyUnicodeObject*, (op))) /* --- Flexible String Representation Helper Macros (PEP 393) -------------- */ @@ -277,165 +183,190 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency( /* Interning state. */ #define SSTATE_NOT_INTERNED 0 #define SSTATE_INTERNED_MORTAL 1 -#define SSTATE_INTERNED_IMMORTAL 2 + +/* Use only if you know it's a string */ +static inline unsigned int PyUnicode_CHECK_INTERNED(PyObject *op) { + return _PyASCIIObject_CAST(op)->state.interned; +} +#define PyUnicode_CHECK_INTERNED(op) PyUnicode_CHECK_INTERNED(_PyObject_CAST(op)) + +/* For backward compatibility */ +static inline unsigned int PyUnicode_IS_READY(PyObject* Py_UNUSED(op)) { + return 1; +} +#define PyUnicode_IS_READY(op) PyUnicode_IS_READY(_PyObject_CAST(op)) /* Return true if the string contains only ASCII characters, or 0 if not. The string may be compact (PyUnicode_IS_COMPACT_ASCII) or not, but must be ready. */ -#define PyUnicode_IS_ASCII(op) \ - (assert(PyUnicode_Check(op)), \ - assert(PyUnicode_IS_READY(op)), \ - ((PyASCIIObject*)op)->state.ascii) +static inline unsigned int PyUnicode_IS_ASCII(PyObject *op) { + return _PyASCIIObject_CAST(op)->state.ascii; +} +#define PyUnicode_IS_ASCII(op) PyUnicode_IS_ASCII(_PyObject_CAST(op)) /* Return true if the string is compact or 0 if not. No type checks or Ready calls are performed. */ -#define PyUnicode_IS_COMPACT(op) \ - (((PyASCIIObject*)(op))->state.compact) +static inline unsigned int PyUnicode_IS_COMPACT(PyObject *op) { + return _PyASCIIObject_CAST(op)->state.compact; +} +#define PyUnicode_IS_COMPACT(op) PyUnicode_IS_COMPACT(_PyObject_CAST(op)) /* Return true if the string is a compact ASCII string (use PyASCIIObject structure), or 0 if not. No type checks or Ready calls are performed. */ -#define PyUnicode_IS_COMPACT_ASCII(op) \ - (((PyASCIIObject*)op)->state.ascii && PyUnicode_IS_COMPACT(op)) +static inline int PyUnicode_IS_COMPACT_ASCII(PyObject *op) { + return (_PyASCIIObject_CAST(op)->state.ascii && PyUnicode_IS_COMPACT(op)); +} +#define PyUnicode_IS_COMPACT_ASCII(op) PyUnicode_IS_COMPACT_ASCII(_PyObject_CAST(op)) enum PyUnicode_Kind { -/* String contains only wstr byte characters. This is only possible - when the string was created with a legacy API and _PyUnicode_Ready() - has not been called yet. */ - PyUnicode_WCHAR_KIND = 0, -/* Return values of the PyUnicode_KIND() macro: */ +/* Return values of the PyUnicode_KIND() function: */ PyUnicode_1BYTE_KIND = 1, PyUnicode_2BYTE_KIND = 2, PyUnicode_4BYTE_KIND = 4 }; +// PyUnicode_KIND(): Return one of the PyUnicode_*_KIND values defined above. +// +// gh-89653: Converting this macro to a static inline function would introduce +// new compiler warnings on "kind < PyUnicode_KIND(str)" (compare signed and +// unsigned numbers) where kind type is an int or on +// "unsigned int kind = PyUnicode_KIND(str)" (cast signed to unsigned). +#define PyUnicode_KIND(op) _Py_RVALUE(_PyASCIIObject_CAST(op)->state.kind) + +/* Return a void pointer to the raw unicode buffer. */ +static inline void* _PyUnicode_COMPACT_DATA(PyObject *op) { + if (PyUnicode_IS_ASCII(op)) { + return _Py_STATIC_CAST(void*, (_PyASCIIObject_CAST(op) + 1)); + } + return _Py_STATIC_CAST(void*, (_PyCompactUnicodeObject_CAST(op) + 1)); +} + +static inline void* _PyUnicode_NONCOMPACT_DATA(PyObject *op) { + void *data; + assert(!PyUnicode_IS_COMPACT(op)); + data = _PyUnicodeObject_CAST(op)->data.any; + assert(data != NULL); + return data; +} + +static inline void* PyUnicode_DATA(PyObject *op) { + if (PyUnicode_IS_COMPACT(op)) { + return _PyUnicode_COMPACT_DATA(op); + } + return _PyUnicode_NONCOMPACT_DATA(op); +} +#define PyUnicode_DATA(op) PyUnicode_DATA(_PyObject_CAST(op)) + /* Return pointers to the canonical representation cast to unsigned char, Py_UCS2, or Py_UCS4 for direct character access. No checks are performed, use PyUnicode_KIND() before to ensure these will work correctly. */ -#define PyUnicode_1BYTE_DATA(op) ((Py_UCS1*)PyUnicode_DATA(op)) -#define PyUnicode_2BYTE_DATA(op) ((Py_UCS2*)PyUnicode_DATA(op)) -#define PyUnicode_4BYTE_DATA(op) ((Py_UCS4*)PyUnicode_DATA(op)) +#define PyUnicode_1BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS1*, PyUnicode_DATA(op)) +#define PyUnicode_2BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS2*, PyUnicode_DATA(op)) +#define PyUnicode_4BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS4*, PyUnicode_DATA(op)) -/* Return one of the PyUnicode_*_KIND values defined above. */ -#define PyUnicode_KIND(op) \ - (assert(PyUnicode_Check(op)), \ - assert(PyUnicode_IS_READY(op)), \ - ((PyASCIIObject *)(op))->state.kind) +/* Returns the length of the unicode string. */ +static inline Py_ssize_t PyUnicode_GET_LENGTH(PyObject *op) { + return _PyASCIIObject_CAST(op)->length; +} +#define PyUnicode_GET_LENGTH(op) PyUnicode_GET_LENGTH(_PyObject_CAST(op)) -/* Return a void pointer to the raw unicode buffer. */ -#define _PyUnicode_COMPACT_DATA(op) \ - (PyUnicode_IS_ASCII(op) ? \ - ((void*)((PyASCIIObject*)(op) + 1)) : \ - ((void*)((PyCompactUnicodeObject*)(op) + 1))) - -#define _PyUnicode_NONCOMPACT_DATA(op) \ - (assert(((PyUnicodeObject*)(op))->data.any), \ - ((((PyUnicodeObject *)(op))->data.any))) - -#define PyUnicode_DATA(op) \ - (assert(PyUnicode_Check(op)), \ - PyUnicode_IS_COMPACT(op) ? _PyUnicode_COMPACT_DATA(op) : \ - _PyUnicode_NONCOMPACT_DATA(op)) - -/* In the access macros below, "kind" may be evaluated more than once. - All other macro parameters are evaluated exactly once, so it is safe - to put side effects into them (such as increasing the index). */ - -/* Write into the canonical representation, this macro does not do any sanity +/* Write into the canonical representation, this function does not do any sanity checks and is intended for usage in loops. The caller should cache the - kind and data pointers obtained from other macro calls. + kind and data pointers obtained from other function calls. index is the index in the string (starts at 0) and value is the new code point value which should be written to that location. */ +static inline void PyUnicode_WRITE(int kind, void *data, + Py_ssize_t index, Py_UCS4 value) +{ + assert(index >= 0); + if (kind == PyUnicode_1BYTE_KIND) { + assert(value <= 0xffU); + _Py_STATIC_CAST(Py_UCS1*, data)[index] = _Py_STATIC_CAST(Py_UCS1, value); + } + else if (kind == PyUnicode_2BYTE_KIND) { + assert(value <= 0xffffU); + _Py_STATIC_CAST(Py_UCS2*, data)[index] = _Py_STATIC_CAST(Py_UCS2, value); + } + else { + assert(kind == PyUnicode_4BYTE_KIND); + assert(value <= 0x10ffffU); + _Py_STATIC_CAST(Py_UCS4*, data)[index] = value; + } +} #define PyUnicode_WRITE(kind, data, index, value) \ - do { \ - switch ((kind)) { \ - case PyUnicode_1BYTE_KIND: { \ - ((Py_UCS1 *)(data))[(index)] = (Py_UCS1)(value); \ - break; \ - } \ - case PyUnicode_2BYTE_KIND: { \ - ((Py_UCS2 *)(data))[(index)] = (Py_UCS2)(value); \ - break; \ - } \ - default: { \ - assert((kind) == PyUnicode_4BYTE_KIND); \ - ((Py_UCS4 *)(data))[(index)] = (Py_UCS4)(value); \ - } \ - } \ - } while (0) + PyUnicode_WRITE(_Py_STATIC_CAST(int, kind), _Py_CAST(void*, data), \ + (index), _Py_STATIC_CAST(Py_UCS4, value)) /* Read a code point from the string's canonical representation. No checks or ready calls are performed. */ +static inline Py_UCS4 PyUnicode_READ(int kind, + const void *data, Py_ssize_t index) +{ + assert(index >= 0); + if (kind == PyUnicode_1BYTE_KIND) { + return _Py_STATIC_CAST(const Py_UCS1*, data)[index]; + } + if (kind == PyUnicode_2BYTE_KIND) { + return _Py_STATIC_CAST(const Py_UCS2*, data)[index]; + } + assert(kind == PyUnicode_4BYTE_KIND); + return _Py_STATIC_CAST(const Py_UCS4*, data)[index]; +} #define PyUnicode_READ(kind, data, index) \ - ((Py_UCS4) \ - ((kind) == PyUnicode_1BYTE_KIND ? \ - ((const Py_UCS1 *)(data))[(index)] : \ - ((kind) == PyUnicode_2BYTE_KIND ? \ - ((const Py_UCS2 *)(data))[(index)] : \ - ((const Py_UCS4 *)(data))[(index)] \ - ) \ - )) + PyUnicode_READ(_Py_STATIC_CAST(int, kind), \ + _Py_STATIC_CAST(const void*, data), \ + (index)) /* PyUnicode_READ_CHAR() is less efficient than PyUnicode_READ() because it calls PyUnicode_KIND() and might call it twice. For single reads, use PyUnicode_READ_CHAR, for multiple consecutive reads callers should cache kind and use PyUnicode_READ instead. */ +static inline Py_UCS4 PyUnicode_READ_CHAR(PyObject *unicode, Py_ssize_t index) +{ + int kind; + + assert(index >= 0); + // Tolerate reading the NUL character at str[len(str)] + assert(index <= PyUnicode_GET_LENGTH(unicode)); + + kind = PyUnicode_KIND(unicode); + if (kind == PyUnicode_1BYTE_KIND) { + return PyUnicode_1BYTE_DATA(unicode)[index]; + } + if (kind == PyUnicode_2BYTE_KIND) { + return PyUnicode_2BYTE_DATA(unicode)[index]; + } + assert(kind == PyUnicode_4BYTE_KIND); + return PyUnicode_4BYTE_DATA(unicode)[index]; +} #define PyUnicode_READ_CHAR(unicode, index) \ - (assert(PyUnicode_Check(unicode)), \ - assert(PyUnicode_IS_READY(unicode)), \ - (Py_UCS4) \ - (PyUnicode_KIND((unicode)) == PyUnicode_1BYTE_KIND ? \ - ((const Py_UCS1 *)(PyUnicode_DATA((unicode))))[(index)] : \ - (PyUnicode_KIND((unicode)) == PyUnicode_2BYTE_KIND ? \ - ((const Py_UCS2 *)(PyUnicode_DATA((unicode))))[(index)] : \ - ((const Py_UCS4 *)(PyUnicode_DATA((unicode))))[(index)] \ - ) \ - )) - -/* Returns the length of the unicode string. The caller has to make sure that - the string has it's canonical representation set before calling - this macro. Call PyUnicode_(FAST_)Ready to ensure that. */ -#define PyUnicode_GET_LENGTH(op) \ - (assert(PyUnicode_Check(op)), \ - assert(PyUnicode_IS_READY(op)), \ - ((PyASCIIObject *)(op))->length) - - -/* Fast check to determine whether an object is ready. Equivalent to - PyUnicode_IS_COMPACT(op) || ((PyUnicodeObject*)(op))->data.any */ - -#define PyUnicode_IS_READY(op) (((PyASCIIObject*)op)->state.ready) - -/* PyUnicode_READY() does less work than _PyUnicode_Ready() in the best - case. If the canonical representation is not yet set, it will still call - _PyUnicode_Ready(). - Returns 0 on success and -1 on errors. */ -#define PyUnicode_READY(op) \ - (assert(PyUnicode_Check(op)), \ - (PyUnicode_IS_READY(op) ? \ - 0 : _PyUnicode_Ready(_PyObject_CAST(op)))) + PyUnicode_READ_CHAR(_PyObject_CAST(unicode), (index)) /* Return a maximum character value which is suitable for creating another string based on op. This is always an approximation but more efficient than iterating over the string. */ -#define PyUnicode_MAX_CHAR_VALUE(op) \ - (assert(PyUnicode_IS_READY(op)), \ - (PyUnicode_IS_ASCII(op) ? \ - (0x7f) : \ - (PyUnicode_KIND(op) == PyUnicode_1BYTE_KIND ? \ - (0xffU) : \ - (PyUnicode_KIND(op) == PyUnicode_2BYTE_KIND ? \ - (0xffffU) : \ - (0x10ffffU))))) +static inline Py_UCS4 PyUnicode_MAX_CHAR_VALUE(PyObject *op) +{ + int kind; -Py_DEPRECATED(3.3) -static inline Py_ssize_t _PyUnicode_get_wstr_length(PyObject *op) { - return PyUnicode_IS_COMPACT_ASCII(op) ? - ((PyASCIIObject*)op)->length : - ((PyCompactUnicodeObject*)op)->wstr_length; + if (PyUnicode_IS_ASCII(op)) { + return 0x7fU; + } + + kind = PyUnicode_KIND(op); + if (kind == PyUnicode_1BYTE_KIND) { + return 0xffU; + } + if (kind == PyUnicode_2BYTE_KIND) { + return 0xffffU; + } + assert(kind == PyUnicode_4BYTE_KIND); + return 0x10ffffU; } -#define PyUnicode_WSTR_LENGTH(op) _PyUnicode_get_wstr_length((PyObject*)op) +#define PyUnicode_MAX_CHAR_VALUE(op) \ + PyUnicode_MAX_CHAR_VALUE(_PyObject_CAST(op)) /* === Public API ========================================================= */ @@ -449,16 +380,12 @@ PyAPI_FUNC(PyObject*) PyUnicode_New( Py_UCS4 maxchar /* maximum code point value in the string */ ); -/* Initializes the canonical string representation from the deprecated - wstr/Py_UNICODE representation. This function is used to convert Unicode - objects which were created using the old API to the new flexible format - introduced with PEP 393. - - Don't call this function directly, use the public PyUnicode_READY() macro - instead. */ -PyAPI_FUNC(int) _PyUnicode_Ready( - PyObject *unicode /* Unicode object */ - ); +/* For backward compatibility */ +static inline int PyUnicode_READY(PyObject* Py_UNUSED(op)) +{ + return 0; +} +#define PyUnicode_READY(op) PyUnicode_READY(_PyObject_CAST(op)) /* Get a copy of a Unicode string. */ PyAPI_FUNC(PyObject*) _PyUnicode_Copy( @@ -526,20 +453,6 @@ PyAPI_FUNC(void) _PyUnicode_FastFill( Py_UCS4 fill_char ); -/* Create a Unicode Object from the Py_UNICODE buffer u of the given - size. - - u may be NULL which causes the contents to be undefined. It is the - user's responsibility to fill in the needed data afterwards. Note - that modifying the Unicode object contents after construction is - only allowed if u was set to NULL. - - The buffer is copied into the new object. */ -Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_FromUnicode( - const Py_UNICODE *u, /* Unicode buffer */ - Py_ssize_t size /* size of buffer */ - ); - /* Create a new string from a buffer of Py_UCS1, Py_UCS2 or Py_UCS4 characters. Scan the string to find the maximum character. */ PyAPI_FUNC(PyObject*) PyUnicode_FromKindAndData( @@ -560,37 +473,12 @@ PyAPI_FUNC(Py_UCS4) _PyUnicode_FindMaxChar ( Py_ssize_t start, Py_ssize_t end); -/* Return a read-only pointer to the Unicode object's internal - Py_UNICODE buffer. - If the wchar_t/Py_UNICODE representation is not yet available, this - function will calculate it. */ -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode( - PyObject *unicode /* Unicode object */ - ); - -/* Similar to PyUnicode_AsUnicode(), but raises a ValueError if the string - contains null characters. */ -PyAPI_FUNC(const Py_UNICODE *) _PyUnicode_AsUnicode( - PyObject *unicode /* Unicode object */ - ); - -/* Return a read-only pointer to the Unicode object's internal - Py_UNICODE buffer and save the length at size. - If the wchar_t/Py_UNICODE representation is not yet available, this - function will calculate it. */ - -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicodeAndSize( - PyObject *unicode, /* Unicode object */ - Py_ssize_t *size /* location where to save the length */ - ); - - /* --- _PyUnicodeWriter API ----------------------------------------------- */ typedef struct { PyObject *buffer; void *data; - enum PyUnicode_Kind kind; + int kind; Py_UCS4 maxchar; Py_ssize_t size; Py_ssize_t pos; @@ -641,8 +529,7 @@ _PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer, Return 0 on success, raise an exception and return -1 on error. */ #define _PyUnicodeWriter_PrepareKind(WRITER, KIND) \ - (assert((KIND) != PyUnicode_WCHAR_KIND), \ - (KIND) <= (WRITER)->kind \ + ((KIND) <= (WRITER)->kind \ ? 0 \ : _PyUnicodeWriter_PrepareKindInternal((WRITER), (KIND))) @@ -650,7 +537,7 @@ _PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer, macro instead. */ PyAPI_FUNC(int) _PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer, - enum PyUnicode_Kind kind); + int kind); /* Append a Unicode character. Return 0 on success, raise an exception and return -1 on error. */ @@ -896,10 +783,6 @@ PyAPI_FUNC(Py_ssize_t) _PyUnicode_InsertThousandsGrouping( /* === Characters Type APIs =============================================== */ -/* Helper array used by Py_UNICODE_ISSPACE(). */ - -PyAPI_DATA(const unsigned char) _Py_ascii_whitespace[]; - /* These should not be used directly. Use the Py_UNICODE_IS* and Py_UNICODE_TO* macros instead. @@ -1007,6 +890,50 @@ PyAPI_FUNC(int) _PyUnicode_IsAlpha( Py_UCS4 ch /* Unicode character */ ); +// Helper array used by Py_UNICODE_ISSPACE(). +PyAPI_DATA(const unsigned char) _Py_ascii_whitespace[]; + +// Since splitting on whitespace is an important use case, and +// whitespace in most situations is solely ASCII whitespace, we +// optimize for the common case by using a quick look-up table +// _Py_ascii_whitespace (see below) with an inlined check. +static inline int Py_UNICODE_ISSPACE(Py_UCS4 ch) { + if (ch < 128) { + return _Py_ascii_whitespace[ch]; + } + return _PyUnicode_IsWhitespace(ch); +} + +#define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch) +#define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch) +#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) +#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) + +#define Py_UNICODE_TOLOWER(ch) _PyUnicode_ToLowercase(ch) +#define Py_UNICODE_TOUPPER(ch) _PyUnicode_ToUppercase(ch) +#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch) + +#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch) +#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch) +#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch) +#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch) + +#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch) +#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch) +#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch) + +#define Py_UNICODE_ISALPHA(ch) _PyUnicode_IsAlpha(ch) + +static inline int Py_UNICODE_ISALNUM(Py_UCS4 ch) { + return (Py_UNICODE_ISALPHA(ch) + || Py_UNICODE_ISDECIMAL(ch) + || Py_UNICODE_ISDIGIT(ch) + || Py_UNICODE_ISNUMERIC(ch)); +} + + +/* === Misc functions ===================================================== */ + PyAPI_FUNC(PyObject*) _PyUnicode_FormatLong(PyObject *, int, int, int); /* Return an interned Unicode object for an Identifier; may fail if there is no memory.*/ @@ -1016,6 +943,9 @@ PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*); and where the hash values are equal (i.e. a very probable match) */ PyAPI_FUNC(int) _PyUnicode_EQ(PyObject *, PyObject *); +/* Equality check. */ +PyAPI_FUNC(int) _PyUnicode_Equal(PyObject *, PyObject *); + PyAPI_FUNC(int) _PyUnicode_WideCharString_Converter(PyObject *, void *); PyAPI_FUNC(int) _PyUnicode_WideCharString_Opt_Converter(PyObject *, void *); diff --git a/Include/cpython/warnings.h b/Include/cpython/warnings.h index 2ef8e3ce943..4e3eb88e8ff 100644 --- a/Include/cpython/warnings.h +++ b/Include/cpython/warnings.h @@ -17,4 +17,4 @@ PyAPI_FUNC(int) PyErr_WarnExplicitFormat( const char *format, ...); // DEPRECATED: Use PyErr_WarnEx() instead. -#define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1) +#define PyErr_Warn(category, msg) PyErr_WarnEx((category), (msg), 1) diff --git a/Include/cpython/weakrefobject.h b/Include/cpython/weakrefobject.h index 9efcc412df9..fd79fdc2dcc 100644 --- a/Include/cpython/weakrefobject.h +++ b/Include/cpython/weakrefobject.h @@ -29,19 +29,28 @@ struct _PyWeakReference { */ PyWeakReference *wr_prev; PyWeakReference *wr_next; + vectorcallfunc vectorcall; }; PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head); PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self); -/* Explanation for the Py_REFCNT() check: when a weakref's target is part - of a long chain of deallocations which triggers the trashcan mechanism, - clearing the weakrefs can be delayed long after the target's refcount - has dropped to zero. In the meantime, code accessing the weakref will - be able to "see" the target object even though it is supposed to be - unreachable. See issue #16602. */ -#define PyWeakref_GET_OBJECT(ref) \ - (Py_REFCNT(((PyWeakReference *)(ref))->wr_object) > 0 \ - ? ((PyWeakReference *)(ref))->wr_object \ - : Py_None) +static inline PyObject* PyWeakref_GET_OBJECT(PyObject *ref_obj) { + PyWeakReference *ref; + PyObject *obj; + assert(PyWeakref_Check(ref_obj)); + ref = _Py_CAST(PyWeakReference*, ref_obj); + obj = ref->wr_object; + // Explanation for the Py_REFCNT() check: when a weakref's target is part + // of a long chain of deallocations which triggers the trashcan mechanism, + // clearing the weakrefs can be delayed long after the target's refcount + // has dropped to zero. In the meantime, code accessing the weakref will + // be able to "see" the target object even though it is supposed to be + // unreachable. See issue gh-60806. + if (Py_REFCNT(obj) > 0) { + return obj; + } + return Py_None; +} +#define PyWeakref_GET_OBJECT(ref) PyWeakref_GET_OBJECT(_PyObject_CAST(ref)) diff --git a/Include/datetime.h b/Include/datetime.h index bb565201a16..b78cc0e8e2e 100644 --- a/Include/datetime.h +++ b/Include/datetime.h @@ -119,39 +119,39 @@ typedef struct // o is a pointer to a time or a datetime object. #define _PyDateTime_HAS_TZINFO(o) (((_PyDateTime_BaseTZInfo *)(o))->hastzinfo) -#define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \ - ((PyDateTime_Date*)o)->data[1]) -#define PyDateTime_GET_MONTH(o) (((PyDateTime_Date*)o)->data[2]) -#define PyDateTime_GET_DAY(o) (((PyDateTime_Date*)o)->data[3]) +#define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)(o))->data[0] << 8) | \ + ((PyDateTime_Date*)(o))->data[1]) +#define PyDateTime_GET_MONTH(o) (((PyDateTime_Date*)(o))->data[2]) +#define PyDateTime_GET_DAY(o) (((PyDateTime_Date*)(o))->data[3]) -#define PyDateTime_DATE_GET_HOUR(o) (((PyDateTime_DateTime*)o)->data[4]) -#define PyDateTime_DATE_GET_MINUTE(o) (((PyDateTime_DateTime*)o)->data[5]) -#define PyDateTime_DATE_GET_SECOND(o) (((PyDateTime_DateTime*)o)->data[6]) +#define PyDateTime_DATE_GET_HOUR(o) (((PyDateTime_DateTime*)(o))->data[4]) +#define PyDateTime_DATE_GET_MINUTE(o) (((PyDateTime_DateTime*)(o))->data[5]) +#define PyDateTime_DATE_GET_SECOND(o) (((PyDateTime_DateTime*)(o))->data[6]) #define PyDateTime_DATE_GET_MICROSECOND(o) \ - ((((PyDateTime_DateTime*)o)->data[7] << 16) | \ - (((PyDateTime_DateTime*)o)->data[8] << 8) | \ - ((PyDateTime_DateTime*)o)->data[9]) -#define PyDateTime_DATE_GET_FOLD(o) (((PyDateTime_DateTime*)o)->fold) -#define PyDateTime_DATE_GET_TZINFO(o) (_PyDateTime_HAS_TZINFO(o) ? \ + ((((PyDateTime_DateTime*)(o))->data[7] << 16) | \ + (((PyDateTime_DateTime*)(o))->data[8] << 8) | \ + ((PyDateTime_DateTime*)(o))->data[9]) +#define PyDateTime_DATE_GET_FOLD(o) (((PyDateTime_DateTime*)(o))->fold) +#define PyDateTime_DATE_GET_TZINFO(o) (_PyDateTime_HAS_TZINFO((o)) ? \ ((PyDateTime_DateTime *)(o))->tzinfo : Py_None) /* Apply for time instances. */ -#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0]) -#define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)o)->data[1]) -#define PyDateTime_TIME_GET_SECOND(o) (((PyDateTime_Time*)o)->data[2]) +#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)(o))->data[0]) +#define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)(o))->data[1]) +#define PyDateTime_TIME_GET_SECOND(o) (((PyDateTime_Time*)(o))->data[2]) #define PyDateTime_TIME_GET_MICROSECOND(o) \ - ((((PyDateTime_Time*)o)->data[3] << 16) | \ - (((PyDateTime_Time*)o)->data[4] << 8) | \ - ((PyDateTime_Time*)o)->data[5]) -#define PyDateTime_TIME_GET_FOLD(o) (((PyDateTime_Time*)o)->fold) + ((((PyDateTime_Time*)(o))->data[3] << 16) | \ + (((PyDateTime_Time*)(o))->data[4] << 8) | \ + ((PyDateTime_Time*)(o))->data[5]) +#define PyDateTime_TIME_GET_FOLD(o) (((PyDateTime_Time*)(o))->fold) #define PyDateTime_TIME_GET_TZINFO(o) (_PyDateTime_HAS_TZINFO(o) ? \ ((PyDateTime_Time *)(o))->tzinfo : Py_None) /* Apply for time delta instances */ -#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days) -#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds) +#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)(o))->days) +#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)(o))->seconds) #define PyDateTime_DELTA_GET_MICROSECONDS(o) \ - (((PyDateTime_Delta*)o)->microseconds) + (((PyDateTime_Delta*)(o))->microseconds) /* Define structure for C API. */ @@ -203,60 +203,60 @@ static PyDateTime_CAPI *PyDateTimeAPI = NULL; #define PyDateTime_TimeZone_UTC PyDateTimeAPI->TimeZone_UTC /* Macros for type checking when not building the Python core. */ -#define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType) -#define PyDate_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DateType) +#define PyDate_Check(op) PyObject_TypeCheck((op), PyDateTimeAPI->DateType) +#define PyDate_CheckExact(op) Py_IS_TYPE((op), PyDateTimeAPI->DateType) -#define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType) -#define PyDateTime_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DateTimeType) +#define PyDateTime_Check(op) PyObject_TypeCheck((op), PyDateTimeAPI->DateTimeType) +#define PyDateTime_CheckExact(op) Py_IS_TYPE((op), PyDateTimeAPI->DateTimeType) -#define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType) -#define PyTime_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->TimeType) +#define PyTime_Check(op) PyObject_TypeCheck((op), PyDateTimeAPI->TimeType) +#define PyTime_CheckExact(op) Py_IS_TYPE((op), PyDateTimeAPI->TimeType) -#define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType) -#define PyDelta_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DeltaType) +#define PyDelta_Check(op) PyObject_TypeCheck((op), PyDateTimeAPI->DeltaType) +#define PyDelta_CheckExact(op) Py_IS_TYPE((op), PyDateTimeAPI->DeltaType) -#define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType) -#define PyTZInfo_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->TZInfoType) +#define PyTZInfo_Check(op) PyObject_TypeCheck((op), PyDateTimeAPI->TZInfoType) +#define PyTZInfo_CheckExact(op) Py_IS_TYPE((op), PyDateTimeAPI->TZInfoType) /* Macros for accessing constructors in a simplified fashion. */ #define PyDate_FromDate(year, month, day) \ - PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType) + PyDateTimeAPI->Date_FromDate((year), (month), (day), PyDateTimeAPI->DateType) #define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \ - PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, \ - min, sec, usec, Py_None, PyDateTimeAPI->DateTimeType) + PyDateTimeAPI->DateTime_FromDateAndTime((year), (month), (day), (hour), \ + (min), (sec), (usec), Py_None, PyDateTimeAPI->DateTimeType) #define PyDateTime_FromDateAndTimeAndFold(year, month, day, hour, min, sec, usec, fold) \ - PyDateTimeAPI->DateTime_FromDateAndTimeAndFold(year, month, day, hour, \ - min, sec, usec, Py_None, fold, PyDateTimeAPI->DateTimeType) + PyDateTimeAPI->DateTime_FromDateAndTimeAndFold((year), (month), (day), (hour), \ + (min), (sec), (usec), Py_None, (fold), PyDateTimeAPI->DateTimeType) #define PyTime_FromTime(hour, minute, second, usecond) \ - PyDateTimeAPI->Time_FromTime(hour, minute, second, usecond, \ + PyDateTimeAPI->Time_FromTime((hour), (minute), (second), (usecond), \ Py_None, PyDateTimeAPI->TimeType) #define PyTime_FromTimeAndFold(hour, minute, second, usecond, fold) \ - PyDateTimeAPI->Time_FromTimeAndFold(hour, minute, second, usecond, \ - Py_None, fold, PyDateTimeAPI->TimeType) + PyDateTimeAPI->Time_FromTimeAndFold((hour), (minute), (second), (usecond), \ + Py_None, (fold), PyDateTimeAPI->TimeType) #define PyDelta_FromDSU(days, seconds, useconds) \ - PyDateTimeAPI->Delta_FromDelta(days, seconds, useconds, 1, \ + PyDateTimeAPI->Delta_FromDelta((days), (seconds), (useconds), 1, \ PyDateTimeAPI->DeltaType) #define PyTimeZone_FromOffset(offset) \ - PyDateTimeAPI->TimeZone_FromTimeZone(offset, NULL) + PyDateTimeAPI->TimeZone_FromTimeZone((offset), NULL) #define PyTimeZone_FromOffsetAndName(offset, name) \ - PyDateTimeAPI->TimeZone_FromTimeZone(offset, name) + PyDateTimeAPI->TimeZone_FromTimeZone((offset), (name)) /* Macros supporting the DB API. */ #define PyDateTime_FromTimestamp(args) \ PyDateTimeAPI->DateTime_FromTimestamp( \ - (PyObject*) (PyDateTimeAPI->DateTimeType), args, NULL) + (PyObject*) (PyDateTimeAPI->DateTimeType), (args), NULL) #define PyDate_FromTimestamp(args) \ PyDateTimeAPI->Date_FromTimestamp( \ - (PyObject*) (PyDateTimeAPI->DateType), args) + (PyObject*) (PyDateTimeAPI->DateType), (args)) #endif /* !defined(_PY_DATETIME_IMPL) */ diff --git a/Include/descrobject.h b/Include/descrobject.h index 703bc8fd6df..0a420b865df 100644 --- a/Include/descrobject.h +++ b/Include/descrobject.h @@ -8,101 +8,92 @@ extern "C" { typedef PyObject *(*getter)(PyObject *, void *); typedef int (*setter)(PyObject *, PyObject *, void *); -typedef struct PyGetSetDef { +struct PyGetSetDef { const char *name; getter get; setter set; const char *doc; void *closure; -} PyGetSetDef; - -#ifndef Py_LIMITED_API -typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args, - void *wrapped); - -typedef PyObject *(*wrapperfunc_kwds)(PyObject *self, PyObject *args, - void *wrapped, PyObject *kwds); - -struct wrapperbase { - const char *name; - int offset; - void *function; - wrapperfunc wrapper; - const char *doc; - int flags; - PyObject *name_strobj; }; -/* Flags for above struct */ -#define PyWrapperFlag_KEYWORDS 1 /* wrapper function takes keyword args */ - -/* Various kinds of descriptor objects */ - -typedef struct { - PyObject_HEAD - PyTypeObject *d_type; - PyObject *d_name; - PyObject *d_qualname; -} PyDescrObject; - -#define PyDescr_COMMON PyDescrObject d_common - -#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type) -#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name) - -typedef struct { - PyDescr_COMMON; - PyMethodDef *d_method; - vectorcallfunc vectorcall; -} PyMethodDescrObject; - -typedef struct { - PyDescr_COMMON; - struct PyMemberDef *d_member; -} PyMemberDescrObject; - -typedef struct { - PyDescr_COMMON; - PyGetSetDef *d_getset; -} PyGetSetDescrObject; - -typedef struct { - PyDescr_COMMON; - struct wrapperbase *d_base; - void *d_wrapped; /* This can be any function pointer */ -} PyWrapperDescrObject; -#endif /* Py_LIMITED_API */ - PyAPI_DATA(PyTypeObject) PyClassMethodDescr_Type; PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type; PyAPI_DATA(PyTypeObject) PyMemberDescr_Type; PyAPI_DATA(PyTypeObject) PyMethodDescr_Type; PyAPI_DATA(PyTypeObject) PyWrapperDescr_Type; PyAPI_DATA(PyTypeObject) PyDictProxy_Type; -#ifndef Py_LIMITED_API -PyAPI_DATA(PyTypeObject) _PyMethodWrapper_Type; -#endif /* Py_LIMITED_API */ +PyAPI_DATA(PyTypeObject) PyProperty_Type; PyAPI_FUNC(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *); PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *); -struct PyMemberDef; /* forward declaration for following prototype */ -PyAPI_FUNC(PyObject *) PyDescr_NewMember(PyTypeObject *, - struct PyMemberDef *); -PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *, - struct PyGetSetDef *); -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *, - struct wrapperbase *, void *); -PyAPI_FUNC(int) PyDescr_IsData(PyObject *); -#endif +PyAPI_FUNC(PyObject *) PyDescr_NewMember(PyTypeObject *, PyMemberDef *); +PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *, PyGetSetDef *); PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *); PyAPI_FUNC(PyObject *) PyWrapper_New(PyObject *, PyObject *); -PyAPI_DATA(PyTypeObject) PyProperty_Type; +/* An array of PyMemberDef structures defines the name, type and offset + of selected members of a C structure. These can be read by + PyMember_GetOne() and set by PyMember_SetOne() (except if their READONLY + flag is set). The array must be terminated with an entry whose name + pointer is NULL. */ +struct PyMemberDef { + const char *name; + int type; + Py_ssize_t offset; + int flags; + const char *doc; +}; + +// These constants used to be in structmember.h, not prefixed by Py_. +// (structmember.h now has aliases to the new names.) + +/* Types */ +#define Py_T_SHORT 0 +#define Py_T_INT 1 +#define Py_T_LONG 2 +#define Py_T_FLOAT 3 +#define Py_T_DOUBLE 4 +#define Py_T_STRING 5 +#define _Py_T_OBJECT 6 // Deprecated, use Py_T_OBJECT_EX instead +/* the ordering here is weird for binary compatibility */ +#define Py_T_CHAR 7 /* 1-character string */ +#define Py_T_BYTE 8 /* 8-bit signed int */ +/* unsigned variants: */ +#define Py_T_UBYTE 9 +#define Py_T_USHORT 10 +#define Py_T_UINT 11 +#define Py_T_ULONG 12 + +/* Added by Jack: strings contained in the structure */ +#define Py_T_STRING_INPLACE 13 + +/* Added by Lillo: bools contained in the structure (assumed char) */ +#define Py_T_BOOL 14 + +#define Py_T_OBJECT_EX 16 +#define Py_T_LONGLONG 17 +#define Py_T_ULONGLONG 18 + +#define Py_T_PYSSIZET 19 /* Py_ssize_t */ +#define _Py_T_NONE 20 // Deprecated. Value is always None. + +/* Flags */ +#define Py_READONLY 1 +#define Py_AUDIT_READ 2 // Added in 3.10, harmless no-op before that +#define _Py_WRITE_RESTRICTED 4 // Deprecated, no-op. Do not reuse the value. + +PyAPI_FUNC(PyObject *) PyMember_GetOne(const char *, PyMemberDef *); +PyAPI_FUNC(int) PyMember_SetOne(char *, PyMemberDef *, PyObject *); + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_DESCROBJECT_H +# include "cpython/descrobject.h" +# undef Py_CPYTHON_DESCROBJECT_H +#endif + #ifdef __cplusplus } #endif #endif /* !Py_DESCROBJECT_H */ - diff --git a/Include/dictobject.h b/Include/dictobject.h index a6233d8ae25..e7fcb44d0cf 100644 --- a/Include/dictobject.h +++ b/Include/dictobject.h @@ -16,7 +16,7 @@ PyAPI_DATA(PyTypeObject) PyDict_Type; #define PyDict_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS) -#define PyDict_CheckExact(op) Py_IS_TYPE(op, &PyDict_Type) +#define PyDict_CheckExact(op) Py_IS_TYPE((op), &PyDict_Type) PyAPI_FUNC(PyObject *) PyDict_New(void); PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key); @@ -67,9 +67,9 @@ PyAPI_DATA(PyTypeObject) PyDictKeys_Type; PyAPI_DATA(PyTypeObject) PyDictValues_Type; PyAPI_DATA(PyTypeObject) PyDictItems_Type; -#define PyDictKeys_Check(op) PyObject_TypeCheck(op, &PyDictKeys_Type) -#define PyDictValues_Check(op) PyObject_TypeCheck(op, &PyDictValues_Type) -#define PyDictItems_Check(op) PyObject_TypeCheck(op, &PyDictItems_Type) +#define PyDictKeys_Check(op) PyObject_TypeCheck((op), &PyDictKeys_Type) +#define PyDictValues_Check(op) PyObject_TypeCheck((op), &PyDictValues_Type) +#define PyDictItems_Check(op) PyObject_TypeCheck((op), &PyDictItems_Type) /* This excludes Values, since they are not sets. */ # define PyDictViewSet_Check(op) \ (PyDictKeys_Check(op) || PyDictItems_Check(op)) diff --git a/Include/dynamic_annotations.h b/Include/dynamic_annotations.h index 0bd1a833c2e..4d4def9bf89 100644 --- a/Include/dynamic_annotations.h +++ b/Include/dynamic_annotations.h @@ -44,7 +44,7 @@ Actual implementation of these macros may differ depending on the dynamic analysis tool being used. - See http://code.google.com/p/data-race-test/ for more information. + See https://code.google.com/p/data-race-test/ for more information. This file supports the following dynamic analysis tools: - None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero). @@ -140,7 +140,7 @@ of the mutex's critical sections individually using the annotations above. This annotation makes sense only for hybrid race detectors. For pure happens-before detectors this is a no-op. For more details see - http://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */ + https://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */ #define _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \ AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu) diff --git a/Include/errcode.h b/Include/errcode.h index 2e07fc2c963..54ae929bf25 100644 --- a/Include/errcode.h +++ b/Include/errcode.h @@ -26,6 +26,8 @@ extern "C" { #define E_TOODEEP 20 /* Too many indentation levels */ #define E_DEDENT 21 /* No matching outer block for dedent */ #define E_DECODE 22 /* Error in decoding into Unicode */ +#define E_EOFS 23 /* EOF in triple-quoted string */ +#define E_EOLS 24 /* EOL in single-quoted string */ #define E_LINECONT 25 /* Unexpected characters after a line continuation */ #define E_BADSINGLE 27 /* Ill-formed single statement input */ #define E_INTERACT_STOP 28 /* Interactive mode stopped tokenization */ diff --git a/Include/exports.h b/Include/exports.h index fc1a5c5ead6..59373c39ff7 100644 --- a/Include/exports.h +++ b/Include/exports.h @@ -2,9 +2,15 @@ #define Py_EXPORTS_H #if defined(_WIN32) || defined(__CYGWIN__) - #define Py_IMPORTED_SYMBOL __declspec(dllimport) - #define Py_EXPORTED_SYMBOL __declspec(dllexport) - #define Py_LOCAL_SYMBOL + #if defined(Py_ENABLE_SHARED) + #define Py_IMPORTED_SYMBOL __declspec(dllimport) + #define Py_EXPORTED_SYMBOL __declspec(dllexport) + #define Py_LOCAL_SYMBOL + #else + #define Py_IMPORTED_SYMBOL + #define Py_EXPORTED_SYMBOL + #define Py_LOCAL_SYMBOL + #endif #else /* * If we only ever used gcc >= 5, we could use __has_attribute(visibility) diff --git a/Include/fileobject.h b/Include/fileobject.h index 4c983e7b5da..02bd7c915a2 100644 --- a/Include/fileobject.h +++ b/Include/fileobject.h @@ -19,14 +19,14 @@ PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *); /* The default encoding used by the platform file system APIs If non-NULL, this is different than the default encoding for strings */ -PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding; +Py_DEPRECATED(3.12) PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding; #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 -PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors; +Py_DEPRECATED(3.12) PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors; #endif PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding; #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 -PyAPI_DATA(int) Py_UTF8Mode; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_UTF8Mode; #endif /* A routine to check if a file descriptor can be select()-ed. */ diff --git a/Include/floatobject.h b/Include/floatobject.h index 3b6ca478eae..999441ac536 100644 --- a/Include/floatobject.h +++ b/Include/floatobject.h @@ -14,11 +14,9 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyFloat_Type; #define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type) -#define PyFloat_CheckExact(op) Py_IS_TYPE(op, &PyFloat_Type) +#define PyFloat_CheckExact(op) Py_IS_TYPE((op), &PyFloat_Type) -#ifdef Py_NAN -# define Py_RETURN_NAN return PyFloat_FromDouble(Py_NAN) -#endif +#define Py_RETURN_NAN return PyFloat_FromDouble(Py_NAN) #define Py_RETURN_INF(sign) \ do { \ diff --git a/Include/import.h b/Include/import.h index a87677bb10c..5d5f3425b8e 100644 --- a/Include/import.h +++ b/Include/import.h @@ -67,7 +67,7 @@ PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevelObject( #endif #define PyImport_ImportModuleEx(n, g, l, f) \ - PyImport_ImportModuleLevel(n, g, l, f, 0) + PyImport_ImportModuleLevel((n), (g), (l), (f), 0) PyAPI_FUNC(PyObject *) PyImport_GetImporter(PyObject *path); PyAPI_FUNC(PyObject *) PyImport_Import(PyObject *name); diff --git a/Include/internal/pycore_accu.h b/Include/internal/pycore_accu.h deleted file mode 100644 index d346222e4dd..00000000000 --- a/Include/internal/pycore_accu.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef Py_LIMITED_API -#ifndef Py_INTERNAL_ACCU_H -#define Py_INTERNAL_ACCU_H -#ifdef __cplusplus -extern "C" { -#endif - -/*** This is a private API for use by the interpreter and the stdlib. - *** Its definition may be changed or removed at any moment. - ***/ - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -/* - * A two-level accumulator of unicode objects that avoids both the overhead - * of keeping a huge number of small separate objects, and the quadratic - * behaviour of using a naive repeated concatenation scheme. - */ - -#undef small /* defined by some Windows headers */ - -typedef struct { - PyObject *large; /* A list of previously accumulated large strings */ - PyObject *small; /* Pending small strings */ -} _PyAccu; - -PyAPI_FUNC(int) _PyAccu_Init(_PyAccu *acc); -PyAPI_FUNC(int) _PyAccu_Accumulate(_PyAccu *acc, PyObject *unicode); -PyAPI_FUNC(PyObject *) _PyAccu_FinishAsList(_PyAccu *acc); -PyAPI_FUNC(PyObject *) _PyAccu_Finish(_PyAccu *acc); -PyAPI_FUNC(void) _PyAccu_Destroy(_PyAccu *acc); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_ACCU_H */ -#endif /* !Py_LIMITED_API */ diff --git a/Include/internal/pycore_asdl.h b/Include/internal/pycore_asdl.h index 2929e030872..afeada88d13 100644 --- a/Include/internal/pycore_asdl.h +++ b/Include/internal/pycore_asdl.h @@ -78,9 +78,9 @@ asdl_ ## NAME ## _seq *_Py_asdl_ ## NAME ## _seq_new(Py_ssize_t size, PyArena *a return seq; \ } -#define asdl_seq_GET_UNTYPED(S, I) (S)->elements[(I)] -#define asdl_seq_GET(S, I) (S)->typed_elements[(I)] -#define asdl_seq_LEN(S) ((S) == NULL ? 0 : (S)->size) +#define asdl_seq_GET_UNTYPED(S, I) _Py_RVALUE((S)->elements[(I)]) +#define asdl_seq_GET(S, I) _Py_RVALUE((S)->typed_elements[(I)]) +#define asdl_seq_LEN(S) _Py_RVALUE(((S) == NULL ? 0 : (S)->size)) #ifdef Py_DEBUG # define asdl_seq_SET(S, I, V) \ @@ -91,7 +91,7 @@ asdl_ ## NAME ## _seq *_Py_asdl_ ## NAME ## _seq_new(Py_ssize_t size, PyArena *a (S)->typed_elements[_asdl_i] = (V); \ } while (0) #else -# define asdl_seq_SET(S, I, V) ((void)((S)->typed_elements[I] = (V))) +# define asdl_seq_SET(S, I, V) _Py_RVALUE((S)->typed_elements[(I)] = (V)) #endif #ifdef Py_DEBUG @@ -103,7 +103,7 @@ asdl_ ## NAME ## _seq *_Py_asdl_ ## NAME ## _seq_new(Py_ssize_t size, PyArena *a (S)->elements[_asdl_i] = (V); \ } while (0) #else -# define asdl_seq_SET_UNTYPED(S, I, V) ((void)((S)->elements[I] = (V))) +# define asdl_seq_SET_UNTYPED(S, I, V) _Py_RVALUE((S)->elements[(I)] = (V)) #endif #ifdef __cplusplus diff --git a/Include/internal/pycore_ast.h b/Include/internal/pycore_ast.h index ebb6a90087b..36277efe9c5 100644 --- a/Include/internal/pycore_ast.h +++ b/Include/internal/pycore_ast.h @@ -179,9 +179,9 @@ enum _stmt_kind {FunctionDef_kind=1, AsyncFunctionDef_kind=2, ClassDef_kind=3, AugAssign_kind=7, AnnAssign_kind=8, For_kind=9, AsyncFor_kind=10, While_kind=11, If_kind=12, With_kind=13, AsyncWith_kind=14, Match_kind=15, Raise_kind=16, Try_kind=17, - Assert_kind=18, Import_kind=19, ImportFrom_kind=20, - Global_kind=21, Nonlocal_kind=22, Expr_kind=23, Pass_kind=24, - Break_kind=25, Continue_kind=26}; + TryStar_kind=18, Assert_kind=19, Import_kind=20, + ImportFrom_kind=21, Global_kind=22, Nonlocal_kind=23, + Expr_kind=24, Pass_kind=25, Break_kind=26, Continue_kind=27}; struct _stmt { enum _stmt_kind kind; union { @@ -295,6 +295,13 @@ struct _stmt { asdl_stmt_seq *finalbody; } Try; + struct { + asdl_stmt_seq *body; + asdl_excepthandler_seq *handlers; + asdl_stmt_seq *orelse; + asdl_stmt_seq *finalbody; + } TryStar; + struct { expr_ty test; expr_ty msg; @@ -688,6 +695,10 @@ stmt_ty _PyAST_Try(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); +stmt_ty _PyAST_TryStar(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, + asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int + lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); stmt_ty _PyAST_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); stmt_ty _PyAST_Import(asdl_alias_seq * names, int lineno, int col_offset, int diff --git a/Include/internal/pycore_ast_state.h b/Include/internal/pycore_ast_state.h index 882cd09c006..f15b4905eed 100644 --- a/Include/internal/pycore_ast_state.h +++ b/Include/internal/pycore_ast_state.h @@ -12,6 +12,8 @@ extern "C" { struct ast_state { int initialized; + int recursion_depth; + int recursion_limit; PyObject *AST_type; PyObject *Add_singleton; PyObject *Add_type; @@ -132,6 +134,7 @@ struct ast_state { PyObject *Sub_singleton; PyObject *Sub_type; PyObject *Subscript_type; + PyObject *TryStar_type; PyObject *Try_type; PyObject *Tuple_type; PyObject *TypeIgnore_type; diff --git a/Include/internal/pycore_atomic.h b/Include/internal/pycore_atomic.h index 3d42e54464c..425d69f868b 100644 --- a/Include/internal/pycore_atomic.h +++ b/Include/internal/pycore_atomic.h @@ -236,7 +236,7 @@ _Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order) in hardware they will fall back to a full memory barrier as well. This might affect performance but likely only in some very specific and - hard to meassure scenario. + hard to measure scenario. */ #if defined(_M_IX86) || defined(_M_X64) typedef enum _Py_memory_order { diff --git a/Include/internal/pycore_bitutils.h b/Include/internal/pycore_bitutils.h index e4aa7a3d0d0..e6bf61ef425 100644 --- a/Include/internal/pycore_bitutils.h +++ b/Include/internal/pycore_bitutils.h @@ -115,8 +115,6 @@ _Py_popcount32(uint32_t x) const uint32_t M2 = 0x33333333; // Binary: 0000 1111 0000 1111 ... const uint32_t M4 = 0x0F0F0F0F; - // 256**4 + 256**3 + 256**2 + 256**1 - const uint32_t SUM = 0x01010101; // Put count of each 2 bits into those 2 bits x = x - ((x >> 1) & M1); @@ -124,8 +122,20 @@ _Py_popcount32(uint32_t x) x = (x & M2) + ((x >> 2) & M2); // Put count of each 8 bits into those 8 bits x = (x + (x >> 4)) & M4; - // Sum of the 4 byte counts - return (uint32_t)((uint64_t)x * (uint64_t)SUM) >> 24; + // Sum of the 4 byte counts. + // Take care when considering changes to the next line. Portability and + // correctness are delicate here, thanks to C's "integer promotions" (C99 + // §6.3.1.1p2). On machines where the `int` type has width greater than 32 + // bits, `x` will be promoted to an `int`, and following C's "usual + // arithmetic conversions" (C99 §6.3.1.8), the multiplication will be + // performed as a multiplication of two `unsigned int` operands. In this + // case it's critical that we cast back to `uint32_t` in order to keep only + // the least significant 32 bits. On machines where the `int` type has + // width no greater than 32, the multiplication is of two 32-bit unsigned + // integer types, and the (uint32_t) cast is a no-op. In both cases, we + // avoid the risk of undefined behaviour due to overflow of a + // multiplication of signed integer types. + return (uint32_t)(x * 0x01010101U) >> 24; #endif } diff --git a/Include/internal/pycore_bytesobject.h b/Include/internal/pycore_bytesobject.h new file mode 100644 index 00000000000..9173a4f105f --- /dev/null +++ b/Include/internal/pycore_bytesobject.h @@ -0,0 +1,52 @@ +#ifndef Py_INTERNAL_BYTESOBJECT_H +#define Py_INTERNAL_BYTESOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +/* runtime lifecycle */ + +extern PyStatus _PyBytes_InitTypes(PyInterpreterState *); + + +/* Substring Search. + + Returns the index of the first occurrence of + a substring ("needle") in a larger text ("haystack"). + If the needle is not found, return -1. + If the needle is found, add offset to the index. +*/ + +PyAPI_FUNC(Py_ssize_t) +_PyBytes_Find(const char *haystack, Py_ssize_t len_haystack, + const char *needle, Py_ssize_t len_needle, + Py_ssize_t offset); + +/* Same as above, but search right-to-left */ +PyAPI_FUNC(Py_ssize_t) +_PyBytes_ReverseFind(const char *haystack, Py_ssize_t len_haystack, + const char *needle, Py_ssize_t len_needle, + Py_ssize_t offset); + + +/** Helper function to implement the repeat and inplace repeat methods on a buffer + * + * len_dest is assumed to be an integer multiple of len_src. + * If src equals dest, then assume the operation is inplace. + * + * This method repeately doubles the number of bytes copied to reduce + * the number of invocations of memcpy. + */ +PyAPI_FUNC(void) +_PyBytes_Repeat(char* dest, Py_ssize_t len_dest, + const char* src, Py_ssize_t len_src); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_BYTESOBJECT_H */ diff --git a/Include/internal/pycore_call.h b/Include/internal/pycore_call.h index f2cfd2fd53e..55378e3dfeb 100644 --- a/Include/internal/pycore_call.h +++ b/Include/internal/pycore_call.h @@ -30,6 +30,9 @@ PyAPI_FUNC(PyObject *) _PyObject_Call( PyObject *args, PyObject *kwargs); +extern PyObject * _PyObject_CallMethodFormat( + PyThreadState *tstate, PyObject *callable, const char *format, ...); + // Static inline variant of public PyVectorcall_Function(). static inline vectorcallfunc @@ -100,6 +103,7 @@ _PyObject_CallNoArgsTstate(PyThreadState *tstate, PyObject *func) { // Private static inline function variant of public PyObject_CallNoArgs() static inline PyObject * _PyObject_CallNoArgs(PyObject *func) { + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); PyThreadState *tstate = _PyThreadState_GET(); return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); } @@ -108,6 +112,7 @@ _PyObject_CallNoArgs(PyObject *func) { static inline PyObject * _PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const *args, Py_ssize_t nargs) { + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL); } diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index c2251b04be6..deda070a6de 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -12,12 +12,17 @@ extern "C" { struct pyruntimestate; struct _ceval_runtime_state; +#ifndef Py_DEFAULT_RECURSION_LIMIT +# define Py_DEFAULT_RECURSION_LIMIT 1000 +#endif + #include "pycore_interp.h" // PyInterpreterState.eval_frame #include "pycore_pystate.h" // _PyThreadState_GET() + extern void _Py_FinishPendingCalls(PyThreadState *tstate); extern void _PyEval_InitRuntimeState(struct _ceval_runtime_state *); -extern int _PyEval_InitState(struct _ceval_state *ceval); +extern void _PyEval_InitState(struct _ceval_state *, PyThread_type_lock); extern void _PyEval_FiniState(struct _ceval_state *ceval); PyAPI_FUNC(void) _PyEval_SignalReceived(PyInterpreterState *interp); PyAPI_FUNC(int) _PyEval_AddPendingCall( @@ -28,39 +33,70 @@ PyAPI_FUNC(void) _PyEval_SignalAsyncExc(PyInterpreterState *interp); #ifdef HAVE_FORK extern PyStatus _PyEval_ReInitThreads(PyThreadState *tstate); #endif -PyAPI_FUNC(void) _PyEval_SetCoroutineOriginTrackingDepth( - PyThreadState *tstate, - int new_depth); -void _PyEval_Fini(void); +// Used by sys.call_tracing() +extern PyObject* _PyEval_CallTracing(PyObject *func, PyObject *args); + +// Used by sys.get_asyncgen_hooks() +extern PyObject* _PyEval_GetAsyncGenFirstiter(void); +extern PyObject* _PyEval_GetAsyncGenFinalizer(void); + +// Used by sys.set_asyncgen_hooks() +extern int _PyEval_SetAsyncGenFirstiter(PyObject *); +extern int _PyEval_SetAsyncGenFinalizer(PyObject *); + +// Used by sys.get_coroutine_origin_tracking_depth() +// and sys.set_coroutine_origin_tracking_depth() +extern int _PyEval_GetCoroutineOriginTrackingDepth(void); +extern int _PyEval_SetCoroutineOriginTrackingDepth(int depth); + +extern void _PyEval_Fini(void); extern PyObject* _PyEval_GetBuiltins(PyThreadState *tstate); -extern PyObject *_PyEval_BuiltinsFromGlobals( +extern PyObject* _PyEval_BuiltinsFromGlobals( PyThreadState *tstate, PyObject *globals); +// Trampoline API + +typedef struct { + // Callback to initialize the trampoline state + void* (*init_state)(void); + // Callback to register every trampoline being created + void (*write_state)(void* state, const void *code_addr, + unsigned int code_size, PyCodeObject* code); + // Callback to free the trampoline state + int (*free_state)(void* state); +} _PyPerf_Callbacks; + +extern int _PyPerfTrampoline_SetCallbacks(_PyPerf_Callbacks *); +extern void _PyPerfTrampoline_GetCallbacks(_PyPerf_Callbacks *); +extern int _PyPerfTrampoline_Init(int activate); +extern int _PyPerfTrampoline_Fini(void); +extern int _PyIsPerfTrampolineActive(void); +extern PyStatus _PyPerfTrampoline_AfterFork_Child(void); +#ifdef PY_HAVE_PERF_TRAMPOLINE +extern _PyPerf_Callbacks _Py_perfmap_callbacks; +#endif static inline PyObject* -_PyEval_EvalFrame(PyThreadState *tstate, struct _interpreter_frame *frame, int throwflag) +_PyEval_EvalFrame(PyThreadState *tstate, struct _PyInterpreterFrame *frame, int throwflag) { + EVAL_CALL_STAT_INC(EVAL_CALL_TOTAL); if (tstate->interp->eval_frame == NULL) { return _PyEval_EvalFrameDefault(tstate, frame, throwflag); } return tstate->interp->eval_frame(tstate, frame, throwflag); } -extern PyObject * +extern PyObject* _PyEval_Vector(PyThreadState *tstate, - PyFrameConstructor *desc, PyObject *locals, + PyFunctionObject *func, PyObject *locals, PyObject* const* args, size_t argcount, PyObject *kwnames); -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS -extern int _PyEval_ThreadsInitialized(PyInterpreterState *interp); -#else extern int _PyEval_ThreadsInitialized(struct pyruntimestate *runtime); -#endif extern PyStatus _PyEval_InitGIL(PyThreadState *tstate); extern void _PyEval_FiniGIL(PyInterpreterState *interp); @@ -73,14 +109,14 @@ extern void _PyEval_DeactivateOpCache(void); #ifdef USE_STACKCHECK /* With USE_STACKCHECK macro defined, trigger stack checks in - _Py_CheckRecursiveCall() on every 64th call to Py_EnterRecursiveCall. */ + _Py_CheckRecursiveCall() on every 64th call to _Py_EnterRecursiveCall. */ static inline int _Py_MakeRecCheck(PyThreadState *tstate) { - return (tstate->recursion_remaining-- <= 0 - || (tstate->recursion_remaining & 63) == 0); + return (tstate->c_recursion_remaining-- <= 0 + || (tstate->c_recursion_remaining & 63) == 0); } #else static inline int _Py_MakeRecCheck(PyThreadState *tstate) { - return tstate->recursion_remaining-- <= 0; + return tstate->c_recursion_remaining-- <= 0; } #endif @@ -88,32 +124,35 @@ PyAPI_FUNC(int) _Py_CheckRecursiveCall( PyThreadState *tstate, const char *where); -static inline int _Py_EnterRecursiveCall(PyThreadState *tstate, - const char *where) { +int _Py_CheckRecursiveCallPy( + PyThreadState *tstate); + +static inline int _Py_EnterRecursiveCallTstate(PyThreadState *tstate, + const char *where) { return (_Py_MakeRecCheck(tstate) && _Py_CheckRecursiveCall(tstate, where)); } -static inline int _Py_EnterRecursiveCall_inline(const char *where) { +static inline int _Py_EnterRecursiveCall(const char *where) { PyThreadState *tstate = _PyThreadState_GET(); - return _Py_EnterRecursiveCall(tstate, where); + return _Py_EnterRecursiveCallTstate(tstate, where); } -#define Py_EnterRecursiveCall(where) _Py_EnterRecursiveCall_inline(where) - -static inline void _Py_LeaveRecursiveCall(PyThreadState *tstate) { - tstate->recursion_remaining++; +static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { + tstate->c_recursion_remaining++; } -static inline void _Py_LeaveRecursiveCall_inline(void) { +static inline void _Py_LeaveRecursiveCall(void) { PyThreadState *tstate = _PyThreadState_GET(); - _Py_LeaveRecursiveCall(tstate); + _Py_LeaveRecursiveCallTstate(tstate); } -#define Py_LeaveRecursiveCall() _Py_LeaveRecursiveCall_inline() +extern struct _PyInterpreterFrame* _PyEval_GetFrame(void); + +extern PyObject* _Py_MakeCoro(PyFunctionObject *func); + +extern int _Py_HandlePending(PyThreadState *tstate); -struct _interpreter_frame *_PyEval_GetFrame(void); -PyObject *_Py_MakeCoro(PyFrameConstructor *, struct _interpreter_frame *); #ifdef __cplusplus } diff --git a/Include/internal/pycore_ceval_state.h b/Include/internal/pycore_ceval_state.h new file mode 100644 index 00000000000..9ba42eb03b2 --- /dev/null +++ b/Include/internal/pycore_ceval_state.h @@ -0,0 +1,100 @@ +#ifndef Py_INTERNAL_CEVAL_STATE_H +#define Py_INTERNAL_CEVAL_STATE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +#include "pycore_atomic.h" /* _Py_atomic_address */ +#include "pycore_gil.h" // struct _gil_runtime_state + + +typedef enum { + PERF_STATUS_FAILED = -1, // Perf trampoline is in an invalid state + PERF_STATUS_NO_INIT = 0, // Perf trampoline is not initialized + PERF_STATUS_OK = 1, // Perf trampoline is ready to be executed +} perf_status_t; + + +#ifdef PY_HAVE_PERF_TRAMPOLINE +struct code_arena_st; + +struct trampoline_api_st { + void* (*init_state)(void); + void (*write_state)(void* state, const void *code_addr, + unsigned int code_size, PyCodeObject* code); + int (*free_state)(void* state); + void *state; +}; +#endif + +struct _ceval_runtime_state { + struct { +#ifdef PY_HAVE_PERF_TRAMPOLINE + perf_status_t status; + Py_ssize_t extra_code_index; + struct code_arena_st *code_arena; + struct trampoline_api_st trampoline_api; + FILE *map_file; +#else + int _not_used; +#endif + } perf; + /* Request for checking signals. It is shared by all interpreters (see + bpo-40513). Any thread of any interpreter can receive a signal, but only + the main thread of the main interpreter can handle signals: see + _Py_ThreadCanHandleSignals(). */ + _Py_atomic_int signals_pending; + struct _gil_runtime_state gil; +}; + +#ifdef PY_HAVE_PERF_TRAMPOLINE +# define _PyEval_RUNTIME_PERF_INIT \ + { \ + .status = PERF_STATUS_NO_INIT, \ + .extra_code_index = -1, \ + } +#else +# define _PyEval_RUNTIME_PERF_INIT {0} +#endif + + +struct _pending_calls { + int busy; + PyThread_type_lock lock; + /* Request for running pending calls. */ + _Py_atomic_int calls_to_do; + /* Request for looking at the `async_exc` field of the current + thread state. + Guarded by the GIL. */ + int async_exc; +#define NPENDINGCALLS 32 + struct { + int (*func)(void *); + void *arg; + } calls[NPENDINGCALLS]; + int first; + int last; +}; + +struct _ceval_state { + int recursion_limit; + /* This single variable consolidates all requests to break out of + the fast path in the eval loop. */ + _Py_atomic_int eval_breaker; + /* Request for dropping the GIL */ + _Py_atomic_int gil_drop_request; + /* The GC is ready to be executed */ + _Py_atomic_int gc_scheduled; + struct _pending_calls pending; +}; + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_CEVAL_STATE_H */ diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index 194af46a3a2..a287250acc1 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -4,156 +4,101 @@ extern "C" { #endif +#define CODE_MAX_WATCHERS 8 + /* PEP 659 * Specialization and quickening structs and helper functions */ -typedef struct { - int32_t cache_count; - int32_t _; /* Force 8 byte size */ -} _PyEntryZero; + +// Inline caches. If you change the number of cache entries for an instruction, +// you must *also* update the number of cache entries in Lib/opcode.py and bump +// the magic number in Lib/importlib/_bootstrap_external.py! + +#define CACHE_ENTRIES(cache) (sizeof(cache)/sizeof(_Py_CODEUNIT)) typedef struct { - uint8_t original_oparg; - uint8_t counter; + uint16_t counter; uint16_t index; - uint32_t version; -} _PyAdaptiveEntry; + uint16_t module_keys_version[2]; + uint16_t builtin_keys_version; +} _PyLoadGlobalCache; +#define INLINE_CACHE_ENTRIES_LOAD_GLOBAL CACHE_ENTRIES(_PyLoadGlobalCache) typedef struct { - uint32_t tp_version; - uint32_t dk_version_or_hint; + uint16_t counter; +} _PyBinaryOpCache; + +#define INLINE_CACHE_ENTRIES_BINARY_OP CACHE_ENTRIES(_PyBinaryOpCache) + +typedef struct { + uint16_t counter; +} _PyUnpackSequenceCache; + +#define INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE \ + CACHE_ENTRIES(_PyUnpackSequenceCache) + +typedef struct { + uint16_t counter; +} _PyCompareOpCache; + +#define INLINE_CACHE_ENTRIES_COMPARE_OP CACHE_ENTRIES(_PyCompareOpCache) + +typedef struct { + uint16_t counter; + uint16_t type_version[2]; + uint16_t func_version; +} _PyBinarySubscrCache; + +#define INLINE_CACHE_ENTRIES_BINARY_SUBSCR CACHE_ENTRIES(_PyBinarySubscrCache) + +typedef struct { + uint16_t counter; + uint16_t version[2]; + uint16_t index; } _PyAttrCache; typedef struct { - uint32_t module_keys_version; - uint32_t builtin_keys_version; -} _PyLoadGlobalCache; + uint16_t counter; + uint16_t type_version[2]; + uint16_t keys_version[2]; + uint16_t descr[4]; +} _PyLoadMethodCache; + + +// MUST be the max(_PyAttrCache, _PyLoadMethodCache) +#define INLINE_CACHE_ENTRIES_LOAD_ATTR CACHE_ENTRIES(_PyLoadMethodCache) + +#define INLINE_CACHE_ENTRIES_STORE_ATTR CACHE_ENTRIES(_PyAttrCache) typedef struct { - /* Borrowed ref in LOAD_METHOD */ - PyObject *obj; -} _PyObjectCache; - -typedef struct { - uint32_t func_version; - uint16_t defaults_start; - uint16_t defaults_len; + uint16_t counter; + uint16_t func_version[2]; + uint16_t min_args; } _PyCallCache; -/* Add specialized versions of entries to this union. - * - * Do not break the invariant: sizeof(SpecializedCacheEntry) == 8 - * Preserving this invariant is necessary because: - - If any one form uses more space, then all must and on 64 bit machines - this is likely to double the memory consumption of caches - - The function for calculating the offset of caches assumes a 4:1 - cache:instruction size ratio. Changing that would need careful - analysis to choose a new function. - */ -typedef union { - _PyEntryZero zero; - _PyAdaptiveEntry adaptive; - _PyAttrCache attr; - _PyLoadGlobalCache load_global; - _PyObjectCache obj; - _PyCallCache call; -} SpecializedCacheEntry; +#define INLINE_CACHE_ENTRIES_CALL CACHE_ENTRIES(_PyCallCache) -#define INSTRUCTIONS_PER_ENTRY (sizeof(SpecializedCacheEntry)/sizeof(_Py_CODEUNIT)) +typedef struct { + uint16_t counter; +} _PyStoreSubscrCache; -/* Maximum size of code to quicken, in code units. */ -#define MAX_SIZE_TO_QUICKEN 5000 +#define INLINE_CACHE_ENTRIES_STORE_SUBSCR CACHE_ENTRIES(_PyStoreSubscrCache) -typedef union _cache_or_instruction { - _Py_CODEUNIT code[1]; - SpecializedCacheEntry entry; -} SpecializedCacheOrInstruction; +typedef struct { + uint16_t counter; +} _PyForIterCache; -/* Get pointer to the nth cache entry, from the first instruction and n. - * Cache entries are indexed backwards, with [count-1] first in memory, and [0] last. - * The zeroth entry immediately precedes the instructions. - */ -static inline SpecializedCacheEntry * -_GetSpecializedCacheEntry(const _Py_CODEUNIT *first_instr, Py_ssize_t n) -{ - SpecializedCacheOrInstruction *last_cache_plus_one = (SpecializedCacheOrInstruction *)first_instr; - assert(&last_cache_plus_one->code[0] == first_instr); - return &last_cache_plus_one[-1-n].entry; -} - -/* Following two functions form a pair. - * - * oparg_from_offset_and_index() is used to compute the oparg - * when quickening, so that offset_from_oparg_and_nexti() - * can be used at runtime to compute the offset. - * - * The relationship between the three values is currently - * offset == (index>>1) + oparg - * This relation is chosen based on the following observations: - * 1. typically 1 in 4 instructions need a cache - * 2. instructions that need a cache typically use 2 entries - * These observations imply: offset ≈ index/2 - * We use the oparg to fine tune the relation to avoid wasting space - * and allow consecutive instructions to use caches. - * - * If the number of cache entries < number of instructions/2 we will waste - * some small amoount of space. - * If the number of cache entries > (number of instructions/2) + 255, then - * some instructions will not be able to use a cache. - * In practice, we expect some small amount of wasted space in a shorter functions - * and only functions exceeding a 1000 lines or more not to have enugh cache space. - * - */ -static inline int -oparg_from_offset_and_nexti(int offset, int nexti) -{ - return offset-(nexti>>1); -} - -static inline int -offset_from_oparg_and_nexti(int oparg, int nexti) -{ - return (nexti>>1)+oparg; -} - -/* Get pointer to the cache entry associated with an instruction. - * nexti is the index of the instruction plus one. - * nexti is used as it corresponds to the instruction pointer in the interpreter. - * This doesn't check that an entry has been allocated for that instruction. */ -static inline SpecializedCacheEntry * -_GetSpecializedCacheEntryForInstruction(const _Py_CODEUNIT *first_instr, int nexti, int oparg) -{ - return _GetSpecializedCacheEntry( - first_instr, - offset_from_oparg_and_nexti(oparg, nexti) - ); -} - -#define QUICKENING_WARMUP_DELAY 8 - -/* We want to compare to zero for efficiency, so we offset values accordingly */ -#define QUICKENING_INITIAL_WARMUP_VALUE (-QUICKENING_WARMUP_DELAY) -#define QUICKENING_WARMUP_COLDEST 1 - -static inline void -PyCodeObject_IncrementWarmup(PyCodeObject * co) -{ - co->co_warmup++; -} - -/* Used by the interpreter to determine when a code object should be quickened */ -static inline int -PyCodeObject_IsWarmedUp(PyCodeObject * co) -{ - return (co->co_warmup == 0); -} - -int _Py_Quicken(PyCodeObject *code); - -extern Py_ssize_t _Py_QuickenedCount; +#define INLINE_CACHE_ENTRIES_FOR_ITER CACHE_ENTRIES(_PyForIterCache) +// Borrowed references to common callables: +struct callable_cache { + PyObject *isinstance; + PyObject *len; + PyObject *list_append; + PyObject *object__getattribute__; +}; /* "Locals plus" for a code object is the set of locals + cell vars + * free vars. This relates to variable names as well as offsets into @@ -210,8 +155,6 @@ struct _PyCodeConstructor { PyObject *code; int firstlineno; PyObject *linetable; - PyObject *endlinetable; - PyObject *columntable; /* used by the code */ PyObject *consts; @@ -250,69 +193,308 @@ PyAPI_FUNC(PyCodeObject *) _PyCode_New(struct _PyCodeConstructor *); /* Private API */ /* Getters for internal PyCodeObject data. */ -PyAPI_FUNC(PyObject *) _PyCode_GetVarnames(PyCodeObject *); -PyAPI_FUNC(PyObject *) _PyCode_GetCellvars(PyCodeObject *); -PyAPI_FUNC(PyObject *) _PyCode_GetFreevars(PyCodeObject *); +extern PyObject* _PyCode_GetVarnames(PyCodeObject *); +extern PyObject* _PyCode_GetCellvars(PyCodeObject *); +extern PyObject* _PyCode_GetFreevars(PyCodeObject *); +extern PyObject* _PyCode_GetCode(PyCodeObject *); -#define ADAPTIVE_CACHE_BACKOFF 64 +/** API for initializing the line number tables. */ +extern int _PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds); -static inline void -cache_backoff(_PyAdaptiveEntry *entry) { - entry->counter = ADAPTIVE_CACHE_BACKOFF; -} +/** Out of process API for initializing the location table. */ +extern void _PyLineTable_InitAddressRange( + const char *linetable, + Py_ssize_t length, + int firstlineno, + PyCodeAddressRange *range); + +/** API for traversing the line number table. */ +extern int _PyLineTable_NextAddressRange(PyCodeAddressRange *range); +extern int _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range); /* Specialization functions */ -int _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache); -int _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache); -int _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache); -int _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache); -int _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, _Py_CODEUNIT *instr, SpecializedCacheEntry *cache); -int _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *instr); -int _Py_Specialize_CallFunction(PyObject *callable, _Py_CODEUNIT *instr, int nargs, SpecializedCacheEntry *cache, PyObject *builtins); -void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, - SpecializedCacheEntry *cache); +extern void _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, + PyObject *name); +extern void _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, + PyObject *name); +extern void _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, + _Py_CODEUNIT *instr, PyObject *name); +extern void _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, + _Py_CODEUNIT *instr); +extern void _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, + _Py_CODEUNIT *instr); +extern void _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, + int nargs, PyObject *kwnames); +extern void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, + int oparg, PyObject **locals); +extern void _Py_Specialize_CompareAndBranch(PyObject *lhs, PyObject *rhs, + _Py_CODEUNIT *instr, int oparg); +extern void _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, + int oparg); +extern void _Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr, int oparg); -#define PRINT_SPECIALIZATION_STATS 0 -#define PRINT_SPECIALIZATION_STATS_DETAILED 0 -#define PRINT_SPECIALIZATION_STATS_TO_FILE 0 +/* Finalizer function for static codeobjects used in deepfreeze.py */ +extern void _PyStaticCode_Fini(PyCodeObject *co); +/* Function to intern strings of codeobjects and quicken the bytecode */ +extern int _PyStaticCode_Init(PyCodeObject *co); -#ifdef Py_DEBUG -#define COLLECT_SPECIALIZATION_STATS 1 -#define COLLECT_SPECIALIZATION_STATS_DETAILED 1 -#else -#define COLLECT_SPECIALIZATION_STATS PRINT_SPECIALIZATION_STATS -#define COLLECT_SPECIALIZATION_STATS_DETAILED PRINT_SPECIALIZATION_STATS_DETAILED -#endif +#ifdef Py_STATS -#define SPECIALIZATION_FAILURE_KINDS 20 -#if COLLECT_SPECIALIZATION_STATS - -typedef struct _stats { - uint64_t specialization_success; - uint64_t specialization_failure; - uint64_t hit; - uint64_t deferred; - uint64_t miss; - uint64_t deopt; - uint64_t unquickened; -#if COLLECT_SPECIALIZATION_STATS_DETAILED - uint64_t specialization_failure_kinds[SPECIALIZATION_FAILURE_KINDS]; -#endif -} SpecializationStats; - -extern SpecializationStats _specialization_stats[256]; -#define STAT_INC(opname, name) _specialization_stats[opname].name++ -#define STAT_DEC(opname, name) _specialization_stats[opname].name-- -void _Py_PrintSpecializationStats(void); +#define STAT_INC(opname, name) do { if (_py_stats) _py_stats->opcode_stats[opname].specialization.name++; } while (0) +#define STAT_DEC(opname, name) do { if (_py_stats) _py_stats->opcode_stats[opname].specialization.name--; } while (0) +#define OPCODE_EXE_INC(opname) do { if (_py_stats) _py_stats->opcode_stats[opname].execution_count++; } while (0) +#define CALL_STAT_INC(name) do { if (_py_stats) _py_stats->call_stats.name++; } while (0) +#define OBJECT_STAT_INC(name) do { if (_py_stats) _py_stats->object_stats.name++; } while (0) +#define OBJECT_STAT_INC_COND(name, cond) \ + do { if (_py_stats && cond) _py_stats->object_stats.name++; } while (0) +#define EVAL_CALL_STAT_INC(name) do { if (_py_stats) _py_stats->call_stats.eval_calls[name]++; } while (0) +#define EVAL_CALL_STAT_INC_IF_FUNCTION(name, callable) \ + do { if (_py_stats && PyFunction_Check(callable)) _py_stats->call_stats.eval_calls[name]++; } while (0) +// Used by the _opcode extension which is built as a shared library PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void); #else #define STAT_INC(opname, name) ((void)0) #define STAT_DEC(opname, name) ((void)0) -#endif +#define OPCODE_EXE_INC(opname) ((void)0) +#define CALL_STAT_INC(name) ((void)0) +#define OBJECT_STAT_INC(name) ((void)0) +#define OBJECT_STAT_INC_COND(name, cond) ((void)0) +#define EVAL_CALL_STAT_INC(name) ((void)0) +#define EVAL_CALL_STAT_INC_IF_FUNCTION(name, callable) ((void)0) +#endif // !Py_STATS + +// Utility functions for reading/writing 32/64-bit values in the inline caches. +// Great care should be taken to ensure that these functions remain correct and +// performant! They should compile to just "move" instructions on all supported +// compilers and platforms. + +// We use memcpy to let the C compiler handle unaligned accesses and endianness +// issues for us. It also seems to produce better code than manual copying for +// most compilers (see https://blog.regehr.org/archives/959 for more info). + +static inline void +write_u32(uint16_t *p, uint32_t val) +{ + memcpy(p, &val, sizeof(val)); +} + +static inline void +write_u64(uint16_t *p, uint64_t val) +{ + memcpy(p, &val, sizeof(val)); +} + +static inline void +write_obj(uint16_t *p, PyObject *val) +{ + memcpy(p, &val, sizeof(val)); +} + +static inline uint16_t +read_u16(uint16_t *p) +{ + return *p; +} + +static inline uint32_t +read_u32(uint16_t *p) +{ + uint32_t val; + memcpy(&val, p, sizeof(val)); + return val; +} + +static inline uint64_t +read_u64(uint16_t *p) +{ + uint64_t val; + memcpy(&val, p, sizeof(val)); + return val; +} + +static inline PyObject * +read_obj(uint16_t *p) +{ + PyObject *val; + memcpy(&val, p, sizeof(val)); + return val; +} + +/* See Objects/exception_handling_notes.txt for details. + */ +static inline unsigned char * +parse_varint(unsigned char *p, int *result) { + int val = p[0] & 63; + while (p[0] & 64) { + p++; + val = (val << 6) | (p[0] & 63); + } + *result = val; + return p+1; +} + +static inline int +write_varint(uint8_t *ptr, unsigned int val) +{ + int written = 1; + while (val >= 64) { + *ptr++ = 64 | (val & 63); + val >>= 6; + written++; + } + *ptr = val; + return written; +} + +static inline int +write_signed_varint(uint8_t *ptr, int val) +{ + if (val < 0) { + val = ((-val)<<1) | 1; + } + else { + val = val << 1; + } + return write_varint(ptr, val); +} + +static inline int +write_location_entry_start(uint8_t *ptr, int code, int length) +{ + assert((code & 15) == code); + *ptr = 128 | (code << 3) | (length - 1); + return 1; +} + + +/** Counters + * The first 16-bit value in each inline cache is a counter. + * When counting misses, the counter is treated as a simple unsigned value. + * + * When counting executions until the next specialization attempt, + * exponential backoff is used to reduce the number of specialization failures. + * The high 12 bits store the counter, the low 4 bits store the backoff exponent. + * On a specialization failure, the backoff exponent is incremented and the + * counter set to (2**backoff - 1). + * Backoff == 6 -> starting counter == 63, backoff == 10 -> starting counter == 1023. + */ + +/* With a 16-bit counter, we have 12 bits for the counter value, and 4 bits for the backoff */ +#define ADAPTIVE_BACKOFF_BITS 4 + +// A value of 1 means that we attempt to specialize the *second* time each +// instruction is executed. Executing twice is a much better indicator of +// "hotness" than executing once, but additional warmup delays only prevent +// specialization. Most types stabilize by the second execution, too: +#define ADAPTIVE_WARMUP_VALUE 1 +#define ADAPTIVE_WARMUP_BACKOFF 1 + +// A value of 52 means that we attempt to re-specialize after 53 misses (a prime +// number, useful for avoiding artifacts if every nth value is a different type +// or something). Setting the backoff to 0 means that the counter is reset to +// the same state as a warming-up instruction (value == 1, backoff == 1) after +// deoptimization. This isn't strictly necessary, but it is bit easier to reason +// about when thinking about the opcode transitions as a state machine: +#define ADAPTIVE_COOLDOWN_VALUE 52 +#define ADAPTIVE_COOLDOWN_BACKOFF 0 + +#define MAX_BACKOFF_VALUE (16 - ADAPTIVE_BACKOFF_BITS) + + +static inline uint16_t +adaptive_counter_bits(int value, int backoff) { + return (value << ADAPTIVE_BACKOFF_BITS) | + (backoff & ((1< MAX_BACKOFF_VALUE) { + backoff = MAX_BACKOFF_VALUE; + } + unsigned int value = (1 << backoff) - 1; + return adaptive_counter_bits(value, backoff); +} + + +/* Line array cache for tracing */ + +extern int _PyCode_CreateLineArray(PyCodeObject *co); + +static inline int +_PyCode_InitLineArray(PyCodeObject *co) +{ + if (co->_co_linearray) { + return 0; + } + return _PyCode_CreateLineArray(co); +} + +static inline int +_PyCode_LineNumberFromArray(PyCodeObject *co, int index) +{ + assert(co->_co_linearray != NULL); + assert(index >= 0); + assert(index < Py_SIZE(co)); + if (co->_co_linearray_entry_size == 2) { + return ((int16_t *)co->_co_linearray)[index]; + } + else { + assert(co->_co_linearray_entry_size == 4); + return ((int32_t *)co->_co_linearray)[index]; + } +} + +typedef struct _PyShimCodeDef { + const uint8_t *code; + int codelen; + int stacksize; + const char *cname; +} _PyShimCodeDef; + +extern PyCodeObject * +_Py_MakeShimCode(const _PyShimCodeDef *code); + +extern uint32_t _Py_next_func_version; + + +/* Comparison bit masks. */ + +/* Note this evaluates its arguments twice each */ +#define COMPARISON_BIT(x, y) (1 << (2 * ((x) >= (y)) + ((x) <= (y)))) + +/* + * The following bits are chosen so that the value of + * COMPARSION_BIT(left, right) + * masked by the values below will be non-zero if the + * comparison is true, and zero if it is false */ + +/* This is for values that are unordered, ie. NaN, not types that are unordered, e.g. sets */ +#define COMPARISON_UNORDERED 1 + +#define COMPARISON_LESS_THAN 2 +#define COMPARISON_GREATER_THAN 4 +#define COMPARISON_EQUALS 8 + +#define COMPARISON_NOT_EQUALS (COMPARISON_UNORDERED | COMPARISON_LESS_THAN | COMPARISON_GREATER_THAN) #ifdef __cplusplus diff --git a/Include/internal/pycore_compile.h b/Include/internal/pycore_compile.h index 06a6082cdda..967fe92a5bc 100644 --- a/Include/internal/pycore_compile.h +++ b/Include/internal/pycore_compile.h @@ -18,10 +18,11 @@ PyAPI_FUNC(PyCodeObject*) _PyAST_Compile( PyCompilerFlags *flags, int optimize, struct _arena *arena); -extern PyFutureFeatures* _PyFuture_FromAST( + +int _PyFuture_FromAST( struct _mod * mod, - PyObject *filename - ); + PyObject *filename, + PyFutureFeatures* futures); extern PyObject* _Py_Mangle(PyObject *p, PyObject *name); @@ -38,6 +39,18 @@ extern int _PyAST_Optimize( struct _arena *arena, _PyASTOptimizeState *state); +/* Access compiler internals for unit testing */ + +PyAPI_FUNC(PyObject*) _PyCompile_CodeGen( + PyObject *ast, + PyObject *filename, + PyCompilerFlags *flags, + int optimize); + +PyAPI_FUNC(PyObject*) _PyCompile_OptimizeCfg( + PyObject *instructions, + PyObject *consts); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_condvar.h b/Include/internal/pycore_condvar.h index edb7dc8193c..981c962bf7d 100644 --- a/Include/internal/pycore_condvar.h +++ b/Include/internal/pycore_condvar.h @@ -20,7 +20,9 @@ */ #define Py_HAVE_CONDVAR -#include +#ifdef HAVE_PTHREAD_H +# include +#endif #define PyMUTEX_T pthread_mutex_t #define PyCOND_T pthread_cond_t diff --git a/Include/internal/pycore_context.h b/Include/internal/pycore_context.h index a482dd42122..52dfe3ef233 100644 --- a/Include/internal/pycore_context.h +++ b/Include/internal/pycore_context.h @@ -7,6 +7,38 @@ #include "pycore_hamt.h" /* PyHamtObject */ + +extern PyTypeObject _PyContextTokenMissing_Type; + +/* runtime lifecycle */ + +PyStatus _PyContext_Init(PyInterpreterState *); +void _PyContext_Fini(PyInterpreterState *); + + +/* other API */ + +typedef struct { + PyObject_HEAD +} _PyContextTokenMissing; + +#ifndef WITH_FREELISTS +// without freelists +# define PyContext_MAXFREELIST 0 +#endif + +#ifndef PyContext_MAXFREELIST +# define PyContext_MAXFREELIST 255 +#endif + +struct _Py_context_state { +#if PyContext_MAXFREELIST > 0 + // List of free PyContext objects + PyContext *freelist; + int numfree; +#endif +}; + struct _pycontextobject { PyObject_HEAD PyContext *ctx_prev; @@ -36,7 +68,4 @@ struct _pycontexttokenobject { }; -int _PyContext_Init(void); -void _PyContext_Fini(PyInterpreterState *interp); - #endif /* !Py_INTERNAL_CONTEXT_H */ diff --git a/Include/internal/pycore_descrobject.h b/Include/internal/pycore_descrobject.h new file mode 100644 index 00000000000..76378569df9 --- /dev/null +++ b/Include/internal/pycore_descrobject.h @@ -0,0 +1,26 @@ +#ifndef Py_INTERNAL_DESCROBJECT_H +#define Py_INTERNAL_DESCROBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +typedef struct { + PyObject_HEAD + PyObject *prop_get; + PyObject *prop_set; + PyObject *prop_del; + PyObject *prop_doc; + PyObject *prop_name; + int getter_doc; +} propertyobject; + +typedef propertyobject _PyPropertyObject; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_DESCROBJECT_H */ diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index 2f0536801ec..c74a3437713 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -9,6 +9,16 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_dict_state.h" +#include "pycore_runtime.h" // _PyRuntime + + +/* runtime lifecycle */ + +extern void _PyDict_Fini(PyInterpreterState *interp); + + +/* other API */ typedef struct { /* Cached hash code of me_key. */ @@ -17,17 +27,39 @@ typedef struct { PyObject *me_value; /* This field is only meaningful for combined tables */ } PyDictKeyEntry; +typedef struct { + PyObject *me_key; /* The key must be Unicode and have hash. */ + PyObject *me_value; /* This field is only meaningful for combined tables */ +} PyDictUnicodeEntry; + +extern PyDictKeysObject *_PyDict_NewKeysForClass(void); +extern PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *); + +/* Gets a version number unique to the current state of the keys of dict, if possible. + * Returns the version number, or zero if it was not possible to get a version number. */ +extern uint32_t _PyDictKeys_GetVersionForCurrentState(PyDictKeysObject *dictkeys); + +extern size_t _PyDict_KeysSize(PyDictKeysObject *keys); + /* _Py_dict_lookup() returns index of entry which can be used like DK_ENTRIES(dk)[index]. * -1 when no entry found, -3 when compare raises error. */ -Py_ssize_t _Py_dict_lookup(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject **value_addr); +extern Py_ssize_t _Py_dict_lookup(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject **value_addr); + +extern Py_ssize_t _PyDict_LookupIndex(PyDictObject *, PyObject *); +extern Py_ssize_t _PyDictKeys_StringLookup(PyDictKeysObject* dictkeys, PyObject *key); +extern PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *); /* Consumes references to key and value */ -int _PyDict_SetItem_Take2(PyDictObject *op, PyObject *key, PyObject *value); +extern int _PyDict_SetItem_Take2(PyDictObject *op, PyObject *key, PyObject *value); +extern int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value); + +extern PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObject *); #define DKIX_EMPTY (-1) #define DKIX_DUMMY (-2) /* Used internally */ #define DKIX_ERROR (-3) +#define DKIX_KEY_CHANGED (-4) /* Used internally */ typedef enum { DICT_KEYS_GENERAL = 0, @@ -42,6 +74,9 @@ struct _dictkeysobject { /* Size of the hash table (dk_indices). It must be a power of 2. */ uint8_t dk_log2_size; + /* Size of the hash table (dk_indices) by bytes. */ + uint8_t dk_log2_index_bytes; + /* Kind of keys */ uint8_t dk_kind; @@ -69,41 +104,91 @@ struct _dictkeysobject { Dynamically sized, SIZEOF_VOID_P is minimum. */ char dk_indices[]; /* char is required to avoid strict aliasing. */ - /* "PyDictKeyEntry dk_entries[dk_usable];" array follows: + /* "PyDictKeyEntry or PyDictUnicodeEntry dk_entries[USABLE_FRACTION(DK_SIZE(dk))];" array follows: see the DK_ENTRIES() macro */ }; -/* This must be no more than 16, for the order vector to fit in 64 bits */ -#define SHARED_KEYS_MAX_SIZE 16 +/* This must be no more than 250, for the prefix size to fit in one byte. */ +#define SHARED_KEYS_MAX_SIZE 30 +#define NEXT_LOG2_SHARED_KEYS_MAX_SIZE 6 +/* Layout of dict values: + * + * The PyObject *values are preceded by an array of bytes holding + * the insertion order and size. + * [-1] = prefix size. [-2] = used size. size[-2-n...] = insertion order. + */ struct _dictvalues { - uint64_t mv_order; PyObject *values[1]; }; -#define DK_LOG_SIZE(dk) ((dk)->dk_log2_size) +#define DK_LOG_SIZE(dk) _Py_RVALUE((dk)->dk_log2_size) #if SIZEOF_VOID_P > 4 #define DK_SIZE(dk) (((int64_t)1)<dk_indices))[DK_SIZE(dk) * DK_IXSIZE(dk)])) -extern uint64_t _pydict_global_version; +static inline void* _DK_ENTRIES(PyDictKeysObject *dk) { + int8_t *indices = (int8_t*)(dk->dk_indices); + size_t index = (size_t)1 << dk->dk_log2_index_bytes; + return (&indices[index]); +} +static inline PyDictKeyEntry* DK_ENTRIES(PyDictKeysObject *dk) { + assert(dk->dk_kind == DICT_KEYS_GENERAL); + return (PyDictKeyEntry*)_DK_ENTRIES(dk); +} +static inline PyDictUnicodeEntry* DK_UNICODE_ENTRIES(PyDictKeysObject *dk) { + assert(dk->dk_kind != DICT_KEYS_GENERAL); + return (PyDictUnicodeEntry*)_DK_ENTRIES(dk); +} -#define DICT_NEXT_VERSION() (++_pydict_global_version) +#define DK_IS_UNICODE(dk) ((dk)->dk_kind != DICT_KEYS_GENERAL) -PyObject *_PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values); +#define DICT_VERSION_INCREMENT (1 << DICT_MAX_WATCHERS) +#define DICT_VERSION_MASK (DICT_VERSION_INCREMENT - 1) + +#define DICT_NEXT_VERSION() \ + (_PyRuntime.dict_state.global_version += DICT_VERSION_INCREMENT) + +void +_PyDict_SendEvent(int watcher_bits, + PyDict_WatchEvent event, + PyDictObject *mp, + PyObject *key, + PyObject *value); + +static inline uint64_t +_PyDict_NotifyEvent(PyDict_WatchEvent event, + PyDictObject *mp, + PyObject *key, + PyObject *value) +{ + int watcher_bits = mp->ma_version_tag & DICT_VERSION_MASK; + if (watcher_bits) { + _PyDict_SendEvent(watcher_bits, event, mp, key, value); + return DICT_NEXT_VERSION() | watcher_bits; + } + return DICT_NEXT_VERSION(); +} + +extern PyObject *_PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values); +extern PyObject *_PyDict_FromItems( + PyObject *const *keys, Py_ssize_t keys_offset, + PyObject *const *values, Py_ssize_t values_offset, + Py_ssize_t length); + +static inline void +_PyDictValues_AddToInsertionOrder(PyDictValues *values, Py_ssize_t ix) +{ + assert(ix < SHARED_KEYS_MAX_SIZE); + uint8_t *size_ptr = ((uint8_t *)values)-2; + int size = *size_ptr; + assert(size+2 < ((uint8_t *)values)[-1]); + size++; + size_ptr[-size] = (uint8_t)ix; + *size_ptr = size; +} #ifdef __cplusplus } diff --git a/Include/internal/pycore_dict_state.h b/Include/internal/pycore_dict_state.h new file mode 100644 index 00000000000..77375ea8beb --- /dev/null +++ b/Include/internal/pycore_dict_state.h @@ -0,0 +1,47 @@ +#ifndef Py_INTERNAL_DICT_STATE_H +#define Py_INTERNAL_DICT_STATE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +struct _Py_dict_runtime_state { + /*Global counter used to set ma_version_tag field of dictionary. + * It is incremented each time that a dictionary is created and each + * time that a dictionary is modified. */ + uint64_t global_version; + uint32_t next_keys_version; +}; + + +#ifndef WITH_FREELISTS +// without freelists +# define PyDict_MAXFREELIST 0 +#endif + +#ifndef PyDict_MAXFREELIST +# define PyDict_MAXFREELIST 80 +#endif + +#define DICT_MAX_WATCHERS 8 + +struct _Py_dict_state { +#if PyDict_MAXFREELIST > 0 + /* Dictionary reuse scheme to save calls to malloc and free */ + PyDictObject *free_list[PyDict_MAXFREELIST]; + PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST]; + int numfree; + int keys_numfree; +#endif + PyDict_WatchCallback watchers[DICT_MAX_WATCHERS]; +}; + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_DICT_STATE_H */ diff --git a/Include/internal/pycore_dtoa.h b/Include/internal/pycore_dtoa.h index 3faf8cf6b2e..67189cf0ade 100644 --- a/Include/internal/pycore_dtoa.h +++ b/Include/internal/pycore_dtoa.h @@ -1,4 +1,5 @@ -#ifndef PY_NO_SHORT_FLOAT_REPR +#ifndef Py_INTERNAL_DTOA_H +#define Py_INTERNAL_DTOA_H #ifdef __cplusplus extern "C" { #endif @@ -7,6 +8,54 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR + + +#if _PY_SHORT_FLOAT_REPR == 1 + +typedef uint32_t ULong; + +struct +Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; +}; + +#ifdef Py_USING_MEMORY_DEBUGGER + +struct _dtoa_runtime_state { + int _not_used; +}; +#define _dtoa_runtime_state_INIT {0} + +#else // !Py_USING_MEMORY_DEBUGGER + +/* The size of the Bigint freelist */ +#define Bigint_Kmax 7 + +#ifndef PRIVATE_MEM +#define PRIVATE_MEM 2304 +#endif +#define Bigint_PREALLOC_SIZE \ + ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) + +struct _dtoa_runtime_state { + /* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */ + // XXX This should be freed during runtime fini. + struct Bigint *p5s; + struct Bigint *freelist[Bigint_Kmax+1]; + double preallocated[Bigint_PREALLOC_SIZE]; + double *preallocated_next; +}; +#define _dtoa_runtime_state_INIT(runtime) \ + { \ + .preallocated_next = runtime.dtoa.preallocated, \ + } + +#endif // !Py_USING_MEMORY_DEBUGGER + + /* These functions are used by modules compiled as C extension like math: they must be exported. */ @@ -17,7 +66,9 @@ PyAPI_FUNC(void) _Py_dg_freedtoa(char *s); PyAPI_FUNC(double) _Py_dg_stdnan(int sign); PyAPI_FUNC(double) _Py_dg_infinity(int sign); +#endif // _PY_SHORT_FLOAT_REPR == 1 + #ifdef __cplusplus } #endif -#endif /* !PY_NO_SHORT_FLOAT_REPR */ +#endif /* !Py_INTERNAL_DTOA_H */ diff --git a/Include/internal/pycore_emscripten_signal.h b/Include/internal/pycore_emscripten_signal.h new file mode 100644 index 00000000000..8b3287d85da --- /dev/null +++ b/Include/internal/pycore_emscripten_signal.h @@ -0,0 +1,25 @@ +#ifndef Py_EMSCRIPTEN_SIGNAL_H +#define Py_EMSCRIPTEN_SIGNAL_H + +#if defined(__EMSCRIPTEN__) + +void +_Py_CheckEmscriptenSignals(void); + +void +_Py_CheckEmscriptenSignalsPeriodically(void); + +#define _Py_CHECK_EMSCRIPTEN_SIGNALS() _Py_CheckEmscriptenSignals() + +#define _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY() _Py_CheckEmscriptenSignalsPeriodically() + +extern int Py_EMSCRIPTEN_SIGNAL_HANDLING; + +#else + +#define _Py_CHECK_EMSCRIPTEN_SIGNALS() +#define _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY() + +#endif // defined(__EMSCRIPTEN__) + +#endif // ndef Py_EMSCRIPTEN_SIGNAL_H diff --git a/Include/internal/pycore_exceptions.h b/Include/internal/pycore_exceptions.h new file mode 100644 index 00000000000..4a9df709131 --- /dev/null +++ b/Include/internal/pycore_exceptions.h @@ -0,0 +1,37 @@ +#ifndef Py_INTERNAL_EXCEPTIONS_H +#define Py_INTERNAL_EXCEPTIONS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +/* runtime lifecycle */ + +extern PyStatus _PyExc_InitState(PyInterpreterState *); +extern PyStatus _PyExc_InitGlobalObjects(PyInterpreterState *); +extern int _PyExc_InitTypes(PyInterpreterState *); +extern void _PyExc_Fini(PyInterpreterState *); + + +/* other API */ + +struct _Py_exc_state { + // The dict mapping from errno codes to OSError subclasses + PyObject *errnomap; + PyBaseExceptionObject *memerrors_freelist; + int memerrors_numfree; + // The ExceptionGroup type + PyObject *PyExc_ExceptionGroup; +}; + +extern void _PyExc_ClearExceptionGroupType(PyInterpreterState *); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_EXCEPTIONS_H */ diff --git a/Include/internal/pycore_faulthandler.h b/Include/internal/pycore_faulthandler.h new file mode 100644 index 00000000000..e6aec7745a6 --- /dev/null +++ b/Include/internal/pycore_faulthandler.h @@ -0,0 +1,99 @@ +#ifndef Py_INTERNAL_FAULTHANDLER_H +#define Py_INTERNAL_FAULTHANDLER_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#ifdef HAVE_SIGACTION +# include +#endif + + +#ifndef MS_WINDOWS + /* register() is useless on Windows, because only SIGSEGV, SIGABRT and + SIGILL can be handled by the process, and these signals can only be used + with enable(), not using register() */ +# define FAULTHANDLER_USER +#endif + + +#ifdef HAVE_SIGACTION +/* Using an alternative stack requires sigaltstack() + and sigaction() SA_ONSTACK */ +# ifdef HAVE_SIGALTSTACK +# define FAULTHANDLER_USE_ALT_STACK +# endif +typedef struct sigaction _Py_sighandler_t; +#else +typedef PyOS_sighandler_t _Py_sighandler_t; +#endif // HAVE_SIGACTION + + +#ifdef FAULTHANDLER_USER +struct faulthandler_user_signal { + int enabled; + PyObject *file; + int fd; + int all_threads; + int chain; + _Py_sighandler_t previous; + PyInterpreterState *interp; +}; +#endif /* FAULTHANDLER_USER */ + + +struct _faulthandler_runtime_state { + struct { + int enabled; + PyObject *file; + int fd; + int all_threads; + PyInterpreterState *interp; +#ifdef MS_WINDOWS + void *exc_handler; +#endif + } fatal_error; + + struct { + PyObject *file; + int fd; + PY_TIMEOUT_T timeout_us; /* timeout in microseconds */ + int repeat; + PyInterpreterState *interp; + int exit; + char *header; + size_t header_len; + /* The main thread always holds this lock. It is only released when + faulthandler_thread() is interrupted before this thread exits, or at + Python exit. */ + PyThread_type_lock cancel_event; + /* released by child thread when joined */ + PyThread_type_lock running; + } thread; + +#ifdef FAULTHANDLER_USER + struct faulthandler_user_signal *user_signals; +#endif + +#ifdef FAULTHANDLER_USE_ALT_STACK + stack_t stack; + stack_t old_stack; +#endif +}; + +#define _faulthandler_runtime_state_INIT \ + { \ + .fatal_error = { \ + .fd = -1, \ + }, \ + } + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_FAULTHANDLER_H */ diff --git a/Include/internal/pycore_fileutils.h b/Include/internal/pycore_fileutils.h index d1caf9c2372..ac89c43d569 100644 --- a/Include/internal/pycore_fileutils.h +++ b/Include/internal/pycore_fileutils.h @@ -10,6 +10,170 @@ extern "C" { #include /* struct lconv */ + +struct _fileutils_state { + int force_ascii; +}; + +typedef enum { + _Py_ERROR_UNKNOWN=0, + _Py_ERROR_STRICT, + _Py_ERROR_SURROGATEESCAPE, + _Py_ERROR_REPLACE, + _Py_ERROR_IGNORE, + _Py_ERROR_BACKSLASHREPLACE, + _Py_ERROR_SURROGATEPASS, + _Py_ERROR_XMLCHARREFREPLACE, + _Py_ERROR_OTHER +} _Py_error_handler; + +PyAPI_FUNC(_Py_error_handler) _Py_GetErrorHandler(const char *errors); + +PyAPI_FUNC(int) _Py_DecodeLocaleEx( + const char *arg, + wchar_t **wstr, + size_t *wlen, + const char **reason, + int current_locale, + _Py_error_handler errors); + +PyAPI_FUNC(int) _Py_EncodeLocaleEx( + const wchar_t *text, + char **str, + size_t *error_pos, + const char **reason, + int current_locale, + _Py_error_handler errors); + +PyAPI_FUNC(char*) _Py_EncodeLocaleRaw( + const wchar_t *text, + size_t *error_pos); + +PyAPI_FUNC(PyObject *) _Py_device_encoding(int); + +#if defined(MS_WINDOWS) || defined(__APPLE__) + /* On Windows, the count parameter of read() is an int (bpo-9015, bpo-9611). + On macOS 10.13, read() and write() with more than INT_MAX bytes + fail with EINVAL (bpo-24658). */ +# define _PY_READ_MAX INT_MAX +# define _PY_WRITE_MAX INT_MAX +#else + /* write() should truncate the input to PY_SSIZE_T_MAX bytes, + but it's safer to do it ourself to have a portable behaviour */ +# define _PY_READ_MAX PY_SSIZE_T_MAX +# define _PY_WRITE_MAX PY_SSIZE_T_MAX +#endif + +#ifdef MS_WINDOWS +struct _Py_stat_struct { + unsigned long st_dev; + uint64_t st_ino; + unsigned short st_mode; + int st_nlink; + int st_uid; + int st_gid; + unsigned long st_rdev; + __int64 st_size; + time_t st_atime; + int st_atime_nsec; + time_t st_mtime; + int st_mtime_nsec; + time_t st_ctime; + int st_ctime_nsec; + unsigned long st_file_attributes; + unsigned long st_reparse_tag; +}; +#else +# define _Py_stat_struct stat +#endif + +PyAPI_FUNC(int) _Py_fstat( + int fd, + struct _Py_stat_struct *status); + +PyAPI_FUNC(int) _Py_fstat_noraise( + int fd, + struct _Py_stat_struct *status); + +PyAPI_FUNC(int) _Py_stat( + PyObject *path, + struct stat *status); + +PyAPI_FUNC(int) _Py_open( + const char *pathname, + int flags); + +PyAPI_FUNC(int) _Py_open_noraise( + const char *pathname, + int flags); + +PyAPI_FUNC(FILE *) _Py_wfopen( + const wchar_t *path, + const wchar_t *mode); + +PyAPI_FUNC(Py_ssize_t) _Py_read( + int fd, + void *buf, + size_t count); + +PyAPI_FUNC(Py_ssize_t) _Py_write( + int fd, + const void *buf, + size_t count); + +PyAPI_FUNC(Py_ssize_t) _Py_write_noraise( + int fd, + const void *buf, + size_t count); + +#ifdef HAVE_READLINK +PyAPI_FUNC(int) _Py_wreadlink( + const wchar_t *path, + wchar_t *buf, + /* Number of characters of 'buf' buffer + including the trailing NUL character */ + size_t buflen); +#endif + +#ifdef HAVE_REALPATH +PyAPI_FUNC(wchar_t*) _Py_wrealpath( + const wchar_t *path, + wchar_t *resolved_path, + /* Number of characters of 'resolved_path' buffer + including the trailing NUL character */ + size_t resolved_path_len); +#endif + +PyAPI_FUNC(wchar_t*) _Py_wgetcwd( + wchar_t *buf, + /* Number of characters of 'buf' buffer + including the trailing NUL character */ + size_t buflen); + +PyAPI_FUNC(int) _Py_get_inheritable(int fd); + +PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable, + int *atomic_flag_works); + +PyAPI_FUNC(int) _Py_set_inheritable_async_safe(int fd, int inheritable, + int *atomic_flag_works); + +PyAPI_FUNC(int) _Py_dup(int fd); + +#ifndef MS_WINDOWS +PyAPI_FUNC(int) _Py_get_blocking(int fd); + +PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking); +#else /* MS_WINDOWS */ +PyAPI_FUNC(void*) _Py_get_osfhandle_noraise(int fd); + +PyAPI_FUNC(void*) _Py_get_osfhandle(int fd); + +PyAPI_FUNC(int) _Py_open_osfhandle_noraise(void *handle, int flags); + +PyAPI_FUNC(int) _Py_open_osfhandle(void *handle, int flags); +#endif /* MS_WINDOWS */ + // This is used after getting NULL back from Py_DecodeLocale(). #define DECODE_LOCALE_ERR(NAME, LEN) \ ((LEN) == (size_t)-2) \ @@ -74,14 +238,18 @@ extern int _Py_EncodeNonUnicodeWchar_InPlace( Py_ssize_t size); #endif +extern int _Py_isabs(const wchar_t *path); +extern int _Py_abspath(const wchar_t *path, wchar_t **abspath_p); +#ifdef MS_WINDOWS +extern int _PyOS_getfullpathname(const wchar_t *path, wchar_t **abspath_p); +#endif extern wchar_t * _Py_join_relfile(const wchar_t *dirname, const wchar_t *relfile); extern int _Py_add_relfile(wchar_t *dirname, const wchar_t *relfile, size_t bufsize); extern size_t _Py_find_basename(const wchar_t *filename); -PyAPI_FUNC(int) _Py_normalize_path(const wchar_t *path, - wchar_t *buf, const size_t buf_len); +PyAPI_FUNC(wchar_t *) _Py_normpath(wchar_t *path, Py_ssize_t size); // Macros to protect CRT calls against instant termination when passed an diff --git a/Include/internal/pycore_floatobject.h b/Include/internal/pycore_floatobject.h index 18227c9e369..27c63bc87f3 100644 --- a/Include/internal/pycore_floatobject.h +++ b/Include/internal/pycore_floatobject.h @@ -8,53 +8,49 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -/* _PyFloat_{Pack,Unpack}{4,8} - * - * The struct and pickle (at least) modules need an efficient platform- - * independent way to store floating-point values as byte strings. - * The Pack routines produce a string from a C double, and the Unpack - * routines produce a C double from such a string. The suffix (4 or 8) - * specifies the number of bytes in the string. - * - * On platforms that appear to use (see _PyFloat_Init()) IEEE-754 formats - * these functions work by copying bits. On other platforms, the formats the - * 4- byte format is identical to the IEEE-754 single precision format, and - * the 8-byte format to the IEEE-754 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 string containing an IEEE - * INF or NaN will raise an exception. - * - * On non-IEEE platforms with more precision, or larger dynamic range, than - * 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). - */ -/* The pack routines write 2, 4 or 8 bytes, starting at p. le is a bool - * argument, true if you want the string in little-endian format (exponent - * last, at p+1, p+3 or p+7), false if you want big-endian format (exponent - * first, at p). - * Return value: 0 if all is OK, -1 if error (and an exception is - * set, most likely OverflowError). - * There are two problems on non-IEEE platforms: - * 1): What this does is undefined if x is a NaN or infinity. - * 2): -0.0 and +0.0 produce the same string. - */ -PyAPI_FUNC(int) _PyFloat_Pack2(double x, unsigned char *p, int le); -PyAPI_FUNC(int) _PyFloat_Pack4(double x, unsigned char *p, int le); -PyAPI_FUNC(int) _PyFloat_Pack8(double x, unsigned char *p, int le); +/* runtime lifecycle */ -/* The unpack routines read 2, 4 or 8 bytes, starting at p. le is a bool - * argument, true if the string is in little-endian format (exponent - * last, at p+1, p+3 or p+7), false if big-endian (exponent first, at p). - * Return value: The unpacked double. On error, this is -1.0 and - * PyErr_Occurred() is true (and an exception is set, most likely - * OverflowError). Note that on a non-IEEE platform this will refuse - * to unpack a string that represents a NaN or infinity. - */ -PyAPI_FUNC(double) _PyFloat_Unpack2(const unsigned char *p, int le); -PyAPI_FUNC(double) _PyFloat_Unpack4(const unsigned char *p, int le); -PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le); +extern void _PyFloat_InitState(PyInterpreterState *); +extern PyStatus _PyFloat_InitTypes(PyInterpreterState *); +extern void _PyFloat_Fini(PyInterpreterState *); +extern void _PyFloat_FiniType(PyInterpreterState *); + + +/* other API */ + +enum _py_float_format_type { + _py_float_format_unknown, + _py_float_format_ieee_big_endian, + _py_float_format_ieee_little_endian, +}; + +struct _Py_float_runtime_state { + enum _py_float_format_type float_format; + enum _py_float_format_type double_format; +}; + + +#ifndef WITH_FREELISTS +// without freelists +# define PyFloat_MAXFREELIST 0 +#endif + +#ifndef PyFloat_MAXFREELIST +# define PyFloat_MAXFREELIST 100 +#endif + +struct _Py_float_state { +#if PyFloat_MAXFREELIST > 0 + /* Special free list + free_list is a singly-linked list of available PyFloatObjects, + linked via abuse of their ob_type members. */ + int numfree; + PyFloatObject *free_list; +#endif +}; + +void _PyFloat_ExactDealloc(PyObject *op); PyAPI_FUNC(void) _PyFloat_DebugMallocStats(FILE* out); diff --git a/Include/internal/pycore_format.h b/Include/internal/pycore_format.h index 1b8d57539ca..1899609e77e 100644 --- a/Include/internal/pycore_format.h +++ b/Include/internal/pycore_format.h @@ -14,12 +14,14 @@ extern "C" { * F_BLANK ' ' * F_ALT '#' * F_ZERO '0' + * F_NO_NEG_0 'z' */ #define F_LJUST (1<<0) #define F_SIGN (1<<1) #define F_BLANK (1<<2) #define F_ALT (1<<3) #define F_ZERO (1<<4) +#define F_NO_NEG_0 (1<<5) #ifdef __cplusplus } diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h index b025ca0b8d7..f12b225ebfc 100644 --- a/Include/internal/pycore_frame.h +++ b/Include/internal/pycore_frame.h @@ -4,123 +4,196 @@ extern "C" { #endif -/* These values are chosen so that the inline functions below all - * compare f_state to zero. - */ -enum _framestate { +#include +#include +#include "pycore_code.h" // STATS + +/* See Objects/frame_layout.md for an explanation of the frame stack + * including explanation of the PyFrameObject and _PyInterpreterFrame + * structs. */ + + +struct _frame { + PyObject_HEAD + PyFrameObject *f_back; /* previous frame, or NULL */ + struct _PyInterpreterFrame *f_frame; /* points to the frame data */ + PyObject *f_trace; /* Trace function */ + int f_lineno; /* Current line number. Only valid if non-zero */ + char f_trace_lines; /* Emit per-line trace events? */ + char f_trace_opcodes; /* Emit per-opcode trace events? */ + char f_fast_as_locals; /* Have the fast locals of this frame been converted to a dict? */ + /* The frame data, if this frame object owns the frame */ + PyObject *_f_frame_data[1]; +}; + +extern PyFrameObject* _PyFrame_New_NoTrack(PyCodeObject *code); + + +/* other API */ + +typedef enum _framestate { FRAME_CREATED = -2, FRAME_SUSPENDED = -1, FRAME_EXECUTING = 0, - FRAME_RETURNED = 1, - FRAME_UNWINDING = 2, - FRAME_RAISED = 3, + FRAME_COMPLETED = 1, FRAME_CLEARED = 4 +} PyFrameState; + +enum _frameowner { + FRAME_OWNED_BY_THREAD = 0, + FRAME_OWNED_BY_GENERATOR = 1, + FRAME_OWNED_BY_FRAME_OBJECT = 2, + FRAME_OWNED_BY_CSTACK = 3, }; -typedef signed char PyFrameState; - -typedef struct _interpreter_frame { - PyObject *f_globals; - PyObject *f_builtins; - PyObject *f_locals; - PyCodeObject *f_code; - PyFrameObject *frame_obj; - /* Borrowed reference to a generator, or NULL */ - PyObject *generator; - struct _interpreter_frame *previous; - int f_lasti; /* Last instruction if called */ - int stacktop; /* Offset of TOS from localsplus */ - PyFrameState f_state; /* What state the frame is in */ - int depth; /* Depth of the frame in a ceval loop */ +typedef struct _PyInterpreterFrame { + /* "Specials" section */ + PyObject *f_funcobj; /* Strong reference. Only valid if not on C stack */ + PyObject *f_globals; /* Borrowed reference. Only valid if not on C stack */ + PyObject *f_builtins; /* Borrowed reference. Only valid if not on C stack */ + PyObject *f_locals; /* Strong reference, may be NULL. Only valid if not on C stack */ + PyCodeObject *f_code; /* Strong reference */ + PyFrameObject *frame_obj; /* Strong reference, may be NULL. Only valid if not on C stack */ + /* Linkage section */ + struct _PyInterpreterFrame *previous; + // NOTE: This is not necessarily the last instruction started in the given + // frame. Rather, it is the code unit *prior to* the *next* instruction. For + // example, it may be an inline CACHE entry, an instruction we just jumped + // over, or (in the case of a newly-created frame) a totally invalid value: + _Py_CODEUNIT *prev_instr; + int stacktop; /* Offset of TOS from localsplus */ + uint16_t yield_offset; + char owner; + /* Locals and stack */ PyObject *localsplus[1]; -} InterpreterFrame; +} _PyInterpreterFrame; -static inline int _PyFrame_IsRunnable(InterpreterFrame *f) { - return f->f_state < FRAME_EXECUTING; -} +#define _PyInterpreterFrame_LASTI(IF) \ + ((int)((IF)->prev_instr - _PyCode_CODE((IF)->f_code))) -static inline int _PyFrame_IsExecuting(InterpreterFrame *f) { - return f->f_state == FRAME_EXECUTING; -} - -static inline int _PyFrameHasCompleted(InterpreterFrame *f) { - return f->f_state > FRAME_EXECUTING; -} - -static inline PyObject **_PyFrame_Stackbase(InterpreterFrame *f) { +static inline PyObject **_PyFrame_Stackbase(_PyInterpreterFrame *f) { return f->localsplus + f->f_code->co_nlocalsplus; } -static inline PyObject *_PyFrame_StackPeek(InterpreterFrame *f) { +static inline PyObject *_PyFrame_StackPeek(_PyInterpreterFrame *f) { assert(f->stacktop > f->f_code->co_nlocalsplus); + assert(f->localsplus[f->stacktop-1] != NULL); return f->localsplus[f->stacktop-1]; } -static inline PyObject *_PyFrame_StackPop(InterpreterFrame *f) { +static inline PyObject *_PyFrame_StackPop(_PyInterpreterFrame *f) { assert(f->stacktop > f->f_code->co_nlocalsplus); f->stacktop--; return f->localsplus[f->stacktop]; } -static inline void _PyFrame_StackPush(InterpreterFrame *f, PyObject *value) { +static inline void _PyFrame_StackPush(_PyInterpreterFrame *f, PyObject *value) { f->localsplus[f->stacktop] = value; f->stacktop++; } -#define FRAME_SPECIALS_SIZE ((sizeof(InterpreterFrame)-1)/sizeof(PyObject *)) +#define FRAME_SPECIALS_SIZE ((int)((sizeof(_PyInterpreterFrame)-1)/sizeof(PyObject *))) -InterpreterFrame * -_PyInterpreterFrame_HeapAlloc(PyFrameConstructor *con, PyObject *locals); - -static inline void -_PyFrame_InitializeSpecials( - InterpreterFrame *frame, PyFrameConstructor *con, - PyObject *locals, int nlocalsplus) +static inline int +_PyFrame_NumSlotsForCodeObject(PyCodeObject *code) { - frame->f_code = (PyCodeObject *)Py_NewRef(con->fc_code); - frame->f_builtins = Py_NewRef(con->fc_builtins); - frame->f_globals = Py_NewRef(con->fc_globals); - frame->f_locals = Py_XNewRef(locals); - frame->stacktop = nlocalsplus; + /* This function needs to remain in sync with the calculation of + * co_framesize in Tools/build/deepfreeze.py */ + assert(code->co_framesize >= FRAME_SPECIALS_SIZE); + return code->co_framesize - FRAME_SPECIALS_SIZE; +} + +void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest); + +/* Consumes reference to func and locals. + Does not initialize frame->previous, which happens + when frame is linked into the frame stack. + */ +static inline void +_PyFrame_Initialize( + _PyInterpreterFrame *frame, PyFunctionObject *func, + PyObject *locals, PyCodeObject *code, int null_locals_from) +{ + frame->f_funcobj = (PyObject *)func; + frame->f_code = (PyCodeObject *)Py_NewRef(code); + frame->f_builtins = func->func_builtins; + frame->f_globals = func->func_globals; + frame->f_locals = locals; + frame->stacktop = code->co_nlocalsplus; frame->frame_obj = NULL; - frame->generator = NULL; - frame->f_lasti = -1; - frame->f_state = FRAME_CREATED; - frame->depth = 0; + frame->prev_instr = _PyCode_CODE(code) - 1; + frame->yield_offset = 0; + frame->owner = FRAME_OWNED_BY_THREAD; + + for (int i = null_locals_from; i < code->co_nlocalsplus; i++) { + frame->localsplus[i] = NULL; + } } /* Gets the pointer to the locals array * that precedes this frame. */ static inline PyObject** -_PyFrame_GetLocalsArray(InterpreterFrame *frame) +_PyFrame_GetLocalsArray(_PyInterpreterFrame *frame) { return frame->localsplus; } static inline PyObject** -_PyFrame_GetStackPointer(InterpreterFrame *frame) +_PyFrame_GetStackPointer(_PyInterpreterFrame *frame) { return frame->localsplus+frame->stacktop; } static inline void -_PyFrame_SetStackPointer(InterpreterFrame *frame, PyObject **stack_pointer) +_PyFrame_SetStackPointer(_PyInterpreterFrame *frame, PyObject **stack_pointer) { frame->stacktop = (int)(stack_pointer - frame->localsplus); } +/* Determine whether a frame is incomplete. + * A frame is incomplete if it is part way through + * creating cell objects or a generator or coroutine. + * + * Frames on the frame stack are incomplete until the + * first RESUME instruction. + * Frames owned by a generator are always complete. + */ +static inline bool +_PyFrame_IsIncomplete(_PyInterpreterFrame *frame) +{ + return frame->owner != FRAME_OWNED_BY_GENERATOR && + frame->prev_instr < _PyCode_CODE(frame->f_code) + frame->f_code->_co_firsttraceable; +} + +static inline _PyInterpreterFrame * +_PyFrame_GetFirstComplete(_PyInterpreterFrame *frame) +{ + while (frame && _PyFrame_IsIncomplete(frame)) { + frame = frame->previous; + } + return frame; +} + +static inline _PyInterpreterFrame * +_PyThreadState_GetFrame(PyThreadState *tstate) +{ + return _PyFrame_GetFirstComplete(tstate->cframe->current_frame); +} + /* For use by _PyFrame_GetFrameObject Do not call directly. */ PyFrameObject * -_PyFrame_MakeAndSetFrameObject(InterpreterFrame *frame); +_PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame); /* Gets the PyFrameObject for this frame, lazily * creating it if necessary. * Returns a borrowed referennce */ static inline PyFrameObject * -_PyFrame_GetFrameObject(InterpreterFrame *frame) +_PyFrame_GetFrameObject(_PyInterpreterFrame *frame) { + + assert(!_PyFrame_IsIncomplete(frame)); PyFrameObject *res = frame->frame_obj; if (res != NULL) { return res; @@ -129,7 +202,7 @@ _PyFrame_GetFrameObject(InterpreterFrame *frame) } /* Clears all references in the frame. - * If take is non-zero, then the InterpreterFrame frame + * If take is non-zero, then the _PyInterpreterFrame frame * may be transferred to the frame object it references * instead of being cleared. Either way * the caller no longer owns the references @@ -137,37 +210,59 @@ _PyFrame_GetFrameObject(InterpreterFrame *frame) * take should be set to 1 for heap allocated * frames like the ones in generators and coroutines. */ -int -_PyFrame_Clear(InterpreterFrame * frame, int take); +void +_PyFrame_Clear(_PyInterpreterFrame * frame); int -_PyFrame_Traverse(InterpreterFrame *frame, visitproc visit, void *arg); +_PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg); int -_PyFrame_FastToLocalsWithError(InterpreterFrame *frame); +_PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame); void -_PyFrame_LocalsToFast(InterpreterFrame *frame, int clear); +_PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear); -InterpreterFrame *_PyThreadState_PushFrame( - PyThreadState *tstate, PyFrameConstructor *con, PyObject *locals); - -extern InterpreterFrame * -_PyThreadState_BumpFramePointerSlow(PyThreadState *tstate, size_t size); - -static inline InterpreterFrame * -_PyThreadState_BumpFramePointer(PyThreadState *tstate, size_t size) +static inline bool +_PyThreadState_HasStackSpace(PyThreadState *tstate, int size) { - PyObject **base = tstate->datastack_top; - PyObject **top = base + size; - if (top < tstate->datastack_limit) { - tstate->datastack_top = top; - return (InterpreterFrame *)base; - } - return _PyThreadState_BumpFramePointerSlow(tstate, size); + assert( + (tstate->datastack_top == NULL && tstate->datastack_limit == NULL) + || + (tstate->datastack_top != NULL && tstate->datastack_limit != NULL) + ); + return tstate->datastack_top != NULL && + size < tstate->datastack_limit - tstate->datastack_top; } -void _PyThreadState_PopFrame(PyThreadState *tstate, InterpreterFrame *frame); +extern _PyInterpreterFrame * +_PyThreadState_PushFrame(PyThreadState *tstate, size_t size); + +void _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame); + +/* Pushes a frame without checking for space. + * Must be guarded by _PyThreadState_HasStackSpace() + * Consumes reference to func. */ +static inline _PyInterpreterFrame * +_PyFrame_PushUnchecked(PyThreadState *tstate, PyFunctionObject *func, int null_locals_from) +{ + CALL_STAT_INC(frames_pushed); + PyCodeObject *code = (PyCodeObject *)func->func_code; + _PyInterpreterFrame *new_frame = (_PyInterpreterFrame *)tstate->datastack_top; + tstate->datastack_top += code->co_framesize; + assert(tstate->datastack_top < tstate->datastack_limit); + _PyFrame_Initialize(new_frame, func, NULL, code, null_locals_from); + return new_frame; +} + +int _PyInterpreterFrame_GetLine(_PyInterpreterFrame *frame); + +static inline +PyGenObject *_PyFrame_GetGenerator(_PyInterpreterFrame *frame) +{ + assert(frame->owner == FRAME_OWNED_BY_GENERATOR); + size_t offset_in_gen = offsetof(PyGenObject, gi_iframe); + return (PyGenObject *)(((char *)frame) - offset_in_gen); +} #ifdef __cplusplus } diff --git a/Include/internal/pycore_function.h b/Include/internal/pycore_function.h new file mode 100644 index 00000000000..5cedb33d7e3 --- /dev/null +++ b/Include/internal/pycore_function.h @@ -0,0 +1,24 @@ +#ifndef Py_INTERNAL_FUNCTION_H +#define Py_INTERNAL_FUNCTION_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#define FUNC_MAX_WATCHERS 8 + +struct _py_func_runtime_state { + uint32_t next_version; +}; + +extern PyFunctionObject* _PyFunction_FromConstructor(PyFrameConstructor *constr); + +extern uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_FUNCTION_H */ diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h index 45e85b54c2e..b3abe2030a0 100644 --- a/Include/internal/pycore_gc.h +++ b/Include/internal/pycore_gc.h @@ -19,16 +19,29 @@ typedef struct { uintptr_t _gc_prev; } PyGC_Head; -#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1) +static inline PyGC_Head* _Py_AS_GC(PyObject *op) { + return (_Py_CAST(PyGC_Head*, op) - 1); +} +#define _PyGC_Head_UNUSED PyGC_Head /* True if the object is currently tracked by the GC. */ -#define _PyObject_GC_IS_TRACKED(o) (_Py_AS_GC(o)->_gc_next != 0) +static inline int _PyObject_GC_IS_TRACKED(PyObject *op) { + PyGC_Head *gc = _Py_AS_GC(op); + return (gc->_gc_next != 0); +} +#define _PyObject_GC_IS_TRACKED(op) _PyObject_GC_IS_TRACKED(_Py_CAST(PyObject*, op)) /* True if the object may be tracked by the GC in the future, or already is. This can be useful to implement some optimizations. */ -#define _PyObject_GC_MAY_BE_TRACKED(obj) \ - (PyObject_IS_GC(obj) && \ - (!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj))) +static inline int _PyObject_GC_MAY_BE_TRACKED(PyObject *obj) { + if (!PyObject_IS_GC(obj)) { + return 0; + } + if (PyTuple_CheckExact(obj)) { + return _PyObject_GC_IS_TRACKED(obj); + } + return 1; +} /* Bit flags for _gc_prev */ @@ -42,26 +55,40 @@ typedef struct { // Lowest bit of _gc_next is used for flags only in GC. // But it is always 0 for normal code. -#define _PyGCHead_NEXT(g) ((PyGC_Head*)(g)->_gc_next) -#define _PyGCHead_SET_NEXT(g, p) ((void)((g)->_gc_next = (uintptr_t)(p))) +static inline PyGC_Head* _PyGCHead_NEXT(PyGC_Head *gc) { + uintptr_t next = gc->_gc_next; + return _Py_CAST(PyGC_Head*, next); +} +static inline void _PyGCHead_SET_NEXT(PyGC_Head *gc, PyGC_Head *next) { + gc->_gc_next = _Py_CAST(uintptr_t, next); +} // Lowest two bits of _gc_prev is used for _PyGC_PREV_MASK_* flags. -#define _PyGCHead_PREV(g) ((PyGC_Head*)((g)->_gc_prev & _PyGC_PREV_MASK)) -#define _PyGCHead_SET_PREV(g, p) do { \ - assert(((uintptr_t)p & ~_PyGC_PREV_MASK) == 0); \ - (g)->_gc_prev = ((g)->_gc_prev & ~_PyGC_PREV_MASK) \ - | ((uintptr_t)(p)); \ - } while (0) +static inline PyGC_Head* _PyGCHead_PREV(PyGC_Head *gc) { + uintptr_t prev = (gc->_gc_prev & _PyGC_PREV_MASK); + return _Py_CAST(PyGC_Head*, prev); +} +static inline void _PyGCHead_SET_PREV(PyGC_Head *gc, PyGC_Head *prev) { + uintptr_t uprev = _Py_CAST(uintptr_t, prev); + assert((uprev & ~_PyGC_PREV_MASK) == 0); + gc->_gc_prev = ((gc->_gc_prev & ~_PyGC_PREV_MASK) | uprev); +} -#define _PyGCHead_FINALIZED(g) \ - (((g)->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0) -#define _PyGCHead_SET_FINALIZED(g) \ - ((void)((g)->_gc_prev |= _PyGC_PREV_MASK_FINALIZED)) +static inline int _PyGCHead_FINALIZED(PyGC_Head *gc) { + return ((gc->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0); +} +static inline void _PyGCHead_SET_FINALIZED(PyGC_Head *gc) { + gc->_gc_prev |= _PyGC_PREV_MASK_FINALIZED; +} -#define _PyGC_FINALIZED(o) \ - _PyGCHead_FINALIZED(_Py_AS_GC(o)) -#define _PyGC_SET_FINALIZED(o) \ - _PyGCHead_SET_FINALIZED(_Py_AS_GC(o)) +static inline int _PyGC_FINALIZED(PyObject *op) { + PyGC_Head *gc = _Py_AS_GC(op); + return _PyGCHead_FINALIZED(gc); +} +static inline void _PyGC_SET_FINALIZED(PyObject *op) { + PyGC_Head *gc = _Py_AS_GC(op); + _PyGCHead_SET_FINALIZED(gc); +} /* GC runtime state */ @@ -134,6 +161,7 @@ struct _gc_runtime_state { /* Current call-stack depth of tp_dealloc calls. */ int trash_delete_nesting; + /* Is automatic collection enabled? */ int enabled; int debug; /* linked lists of container objects */ @@ -161,19 +189,21 @@ struct _gc_runtime_state { Py_ssize_t long_lived_pending; }; + extern void _PyGC_InitState(struct _gc_runtime_state *); extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate); // Functions to clear types free lists -extern void _PyFrame_ClearFreeList(PyInterpreterState *interp); extern void _PyTuple_ClearFreeList(PyInterpreterState *interp); extern void _PyFloat_ClearFreeList(PyInterpreterState *interp); extern void _PyList_ClearFreeList(PyInterpreterState *interp); extern void _PyDict_ClearFreeList(PyInterpreterState *interp); extern void _PyAsyncGen_ClearFreeLists(PyInterpreterState *interp); extern void _PyContext_ClearFreeList(PyInterpreterState *interp); +extern void _Py_ScheduleGC(PyInterpreterState *interp); +extern void _Py_RunGC(PyThreadState *tstate); #ifdef __cplusplus } diff --git a/Include/internal/pycore_genobject.h b/Include/internal/pycore_genobject.h new file mode 100644 index 00000000000..dc60b4ca705 --- /dev/null +++ b/Include/internal/pycore_genobject.h @@ -0,0 +1,49 @@ +#ifndef Py_INTERNAL_GENOBJECT_H +#define Py_INTERNAL_GENOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +extern PyObject *_PyGen_yf(PyGenObject *); +extern PyObject *_PyCoro_GetAwaitableIter(PyObject *o); +extern PyObject *_PyAsyncGenValueWrapperNew(PyThreadState *state, PyObject *); + +/* runtime lifecycle */ + +extern void _PyAsyncGen_Fini(PyInterpreterState *); + + +/* other API */ + +#ifndef WITH_FREELISTS +// without freelists +# define _PyAsyncGen_MAXFREELIST 0 +#endif + +#ifndef _PyAsyncGen_MAXFREELIST +# define _PyAsyncGen_MAXFREELIST 80 +#endif + +struct _Py_async_gen_state { +#if _PyAsyncGen_MAXFREELIST > 0 + /* Freelists boost performance 6-10%; they also reduce memory + fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend + are short-living objects that are instantiated for every + __anext__() call. */ + struct _PyAsyncGenWrappedValue* value_freelist[_PyAsyncGen_MAXFREELIST]; + int value_numfree; + + struct PyAsyncGenASend* asend_freelist[_PyAsyncGen_MAXFREELIST]; + int asend_numfree; +#endif +}; + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_GENOBJECT_H */ diff --git a/Include/internal/pycore_global_objects.h b/Include/internal/pycore_global_objects.h new file mode 100644 index 00000000000..d0461fa7e82 --- /dev/null +++ b/Include/internal/pycore_global_objects.h @@ -0,0 +1,95 @@ +#ifndef Py_INTERNAL_GLOBAL_OBJECTS_H +#define Py_INTERNAL_GLOBAL_OBJECTS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_gc.h" // PyGC_Head +#include "pycore_global_strings.h" // struct _Py_global_strings +#include "pycore_hamt.h" // PyHamtNode_Bitmap +#include "pycore_context.h" // _PyContextTokenMissing +#include "pycore_typeobject.h" // pytype_slotdef + + +// These would be in pycore_long.h if it weren't for an include cycle. +#define _PY_NSMALLPOSINTS 257 +#define _PY_NSMALLNEGINTS 5 + + +// Only immutable objects should be considered runtime-global. +// All others must be per-interpreter. + +#define _Py_CACHED_OBJECT(NAME) \ + _PyRuntime.cached_objects.NAME + +struct _Py_cached_objects { + PyObject *str_replace_inf; + + PyObject *interned_strings; +}; + +#define _Py_GLOBAL_OBJECT(NAME) \ + _PyRuntime.static_objects.NAME +#define _Py_SINGLETON(NAME) \ + _Py_GLOBAL_OBJECT(singletons.NAME) + +struct _Py_static_objects { + struct { + /* Small integers are preallocated in this array so that they + * can be shared. + * The integers that are preallocated are those in the range + * -_PY_NSMALLNEGINTS (inclusive) to _PY_NSMALLPOSINTS (exclusive). + */ + PyLongObject small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS]; + + PyBytesObject bytes_empty; + struct { + PyBytesObject ob; + char eos; + } bytes_characters[256]; + + struct _Py_global_strings strings; + + _PyGC_Head_UNUSED _tuple_empty_gc_not_used; + PyTupleObject tuple_empty; + + _PyGC_Head_UNUSED _hamt_bitmap_node_empty_gc_not_used; + PyHamtNode_Bitmap hamt_bitmap_node_empty; + _PyContextTokenMissing context_token_missing; + } singletons; +}; + +#define _Py_INTERP_CACHED_OBJECT(interp, NAME) \ + (interp)->cached_objects.NAME + +struct _Py_interp_cached_objects { + int _not_set; + /* object.__reduce__ */ + PyObject *objreduce; + PyObject *type_slots_pname; + pytype_slotdef *type_slots_ptrs[MAX_EQUIV]; +}; + +#define _Py_INTERP_STATIC_OBJECT(interp, NAME) \ + (interp)->static_objects.NAME +#define _Py_INTERP_SINGLETON(interp, NAME) \ + _Py_INTERP_STATIC_OBJECT(interp, singletons.NAME) + +struct _Py_interp_static_objects { + struct { + int _not_used; + // hamt_empty is here instead of global because of its weakreflist. + _PyGC_Head_UNUSED _hamt_empty_gc_not_used; + PyHamtObject hamt_empty; + } singletons; +}; + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_GLOBAL_OBJECTS_H */ diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h new file mode 100644 index 00000000000..8c210111b58 --- /dev/null +++ b/Include/internal/pycore_global_objects_fini_generated.h @@ -0,0 +1,1500 @@ +#ifndef Py_INTERNAL_GLOBAL_OBJECTS_FINI_GENERATED_INIT_H +#define Py_INTERNAL_GLOBAL_OBJECTS_FINI_GENERATED_INIT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_object.h" // _PyObject_IMMORTAL_REFCNT + +#ifdef Py_DEBUG +static inline void +_PyStaticObject_CheckRefcnt(PyObject *obj) { + if (Py_REFCNT(obj) < _PyObject_IMMORTAL_REFCNT) { + _PyObject_ASSERT_FAILED_MSG(obj, + "immortal object has less refcnt than expected " + "_PyObject_IMMORTAL_REFCNT"); + } +} +#endif + +/* The following is auto-generated by Tools/build/generate_global_objects.py. */ +#ifdef Py_DEBUG +static inline void +_PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { + /* generated runtime-global */ + // (see pycore_runtime_init_generated.h) + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -5]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -4]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -3]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -2]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -1]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 0]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 1]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 2]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 3]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 4]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 5]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 6]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 7]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 8]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 9]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 10]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 11]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 12]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 13]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 14]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 15]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 16]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 17]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 18]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 19]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 20]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 21]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 22]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 23]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 24]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 25]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 26]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 27]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 28]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 29]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 30]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 31]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 32]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 33]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 34]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 35]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 36]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 37]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 38]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 39]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 40]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 41]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 42]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 43]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 44]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 45]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 46]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 47]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 48]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 49]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 50]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 51]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 52]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 53]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 54]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 55]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 56]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 57]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 58]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 59]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 60]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 61]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 62]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 63]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 64]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 65]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 66]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 67]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 68]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 69]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 70]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 71]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 72]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 73]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 74]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 75]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 76]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 77]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 78]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 79]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 80]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 81]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 82]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 83]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 84]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 85]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 86]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 87]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 88]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 89]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 90]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 91]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 92]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 93]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 94]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 95]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 96]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 97]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 98]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 99]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 100]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 101]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 102]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 103]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 104]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 105]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 106]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 107]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 108]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 109]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 110]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 111]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 112]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 113]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 114]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 115]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 116]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 117]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 118]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 119]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 120]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 121]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 122]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 123]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 124]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 125]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 126]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 127]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 129]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 130]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 131]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 132]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 133]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 134]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 135]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 136]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 137]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 138]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 139]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 140]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 141]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 142]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 143]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 144]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 145]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 146]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 147]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 148]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 149]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 150]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 151]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 152]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 153]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 154]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 155]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 156]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 157]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 158]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 159]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 160]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 161]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 162]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 163]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 164]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 165]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 166]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 167]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 168]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 169]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 170]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 171]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 172]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 173]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 174]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 175]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 176]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 177]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 178]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 179]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 180]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 181]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 182]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 183]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 184]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 185]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 186]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 187]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 188]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 189]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 190]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 191]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 192]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 193]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 194]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 195]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 196]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 197]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 198]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 199]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 200]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 201]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 202]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 203]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 204]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 205]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 206]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 207]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 208]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 209]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 210]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 211]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 212]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 213]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 214]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 215]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 216]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 217]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 218]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 219]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 220]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 221]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 222]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 223]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 224]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 225]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 226]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 227]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 228]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 229]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 230]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 231]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 232]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 233]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 234]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 235]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 236]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 237]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 238]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 239]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 240]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 241]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 242]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 243]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 244]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 245]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 246]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 247]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 248]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 249]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 250]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 251]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 252]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 253]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 254]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 255]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 256]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[0]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[1]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[2]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[3]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[4]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[5]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[6]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[7]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[8]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[9]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[10]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[11]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[12]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[13]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[14]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[15]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[16]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[17]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[18]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[19]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[20]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[21]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[22]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[23]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[24]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[25]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[26]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[27]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[28]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[29]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[30]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[31]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[32]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[33]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[34]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[35]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[36]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[37]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[38]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[39]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[40]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[41]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[42]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[43]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[44]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[45]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[46]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[47]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[48]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[49]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[50]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[51]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[52]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[53]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[54]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[55]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[56]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[57]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[58]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[59]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[60]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[61]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[62]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[63]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[64]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[65]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[66]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[67]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[68]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[69]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[70]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[71]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[72]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[73]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[74]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[75]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[76]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[77]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[78]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[79]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[80]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[81]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[82]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[83]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[84]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[85]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[86]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[87]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[88]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[89]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[90]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[91]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[92]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[93]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[94]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[95]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[96]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[97]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[98]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[99]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[100]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[101]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[102]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[103]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[104]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[105]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[106]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[107]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[108]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[109]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[110]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[111]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[112]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[113]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[114]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[115]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[116]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[117]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[118]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[119]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[120]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[121]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[122]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[123]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[124]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[125]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[126]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[127]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[129]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[130]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[131]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[132]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[133]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[134]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[135]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[136]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[137]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[138]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[139]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[140]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[141]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[142]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[143]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[144]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[145]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[146]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[147]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[148]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[149]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[150]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[151]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[152]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[153]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[154]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[155]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[156]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[157]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[158]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[159]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[160]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[161]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[162]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[163]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[164]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[165]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[166]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[167]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[168]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[169]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[170]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[171]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[172]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[173]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[174]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[175]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[176]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[177]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[178]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[179]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[180]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[181]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[182]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[183]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[184]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[185]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[186]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[187]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[188]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[189]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[190]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[191]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[192]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[193]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[194]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[195]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[196]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[197]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[198]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[199]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[200]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[201]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[202]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[203]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[204]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[205]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[206]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[207]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[208]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[209]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[210]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[211]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[212]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[213]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[214]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[215]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[216]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[217]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[218]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[219]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[220]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[221]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[222]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[223]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[224]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[225]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[226]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[227]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[228]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[229]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[230]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[231]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[232]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[233]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[234]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[235]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[236]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[237]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[238]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[239]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[240]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[241]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[242]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[243]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[244]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[245]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[246]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[247]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[248]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[249]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[250]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[251]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[252]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[253]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[254]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[255]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_dictcomp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_genexpr)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_lambda)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_listcomp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_module)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_setcomp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_string)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_unknown)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(close_br)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(dbl_close_br)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(dbl_open_br)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(dbl_percent)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(dot)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(dot_locals)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(empty)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(json_decoder)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(list_err)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(newline)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(open_br)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(percent)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(shim_name)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(utf_8)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(CANCELLED)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(FINISHED)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(False)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(JSONDecodeError)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(PENDING)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(Py_Repr)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(TextIOWrapper)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(True)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(WarningMessage)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__IOBase_closed)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__abc_tpflags__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__abs__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__abstractmethods__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__add__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__aenter__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__aexit__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__aiter__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__all__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__and__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__anext__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__annotations__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__args__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__asyncio_running_event_loop__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__await__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__bases__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__bool__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__build_class__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__builtins__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__bytes__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__call__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__cantrace__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__class__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__class_getitem__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__classcell__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__complex__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__contains__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__copy__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ctypes_from_outparam__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__del__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__delattr__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__delete__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__delitem__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__dict__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__dictoffset__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__dir__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__divmod__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__doc__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__enter__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__eq__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__exit__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__file__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__float__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__floordiv__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__format__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__fspath__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ge__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__get__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__getattr__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__getattribute__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__getinitargs__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__getitem__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__getnewargs__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__getnewargs_ex__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__getstate__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__gt__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__hash__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__iadd__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__iand__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ifloordiv__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ilshift__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__imatmul__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__imod__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__import__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__imul__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__index__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__init__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__init_subclass__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__instancecheck__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__int__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__invert__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ior__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ipow__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__irshift__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__isabstractmethod__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__isub__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__iter__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__itruediv__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ixor__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__le__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__len__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__length_hint__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__lltrace__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__loader__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__lshift__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__lt__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__main__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__matmul__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__missing__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__mod__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__module__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__mro_entries__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__mul__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__name__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ne__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__neg__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__new__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__newobj__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__newobj_ex__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__next__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__notes__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__or__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__orig_class__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__origin__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__package__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__parameters__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__path__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__pos__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__pow__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__prepare__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__qualname__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__radd__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rand__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rdivmod__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__reduce__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__reduce_ex__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__repr__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__reversed__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rfloordiv__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rlshift__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rmatmul__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rmod__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rmul__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ror__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__round__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rpow__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rrshift__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rshift__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rsub__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rtruediv__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rxor__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__set__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__set_name__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__setattr__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__setitem__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__setstate__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__sizeof__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__slotnames__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__slots__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__spec__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__str__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__sub__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__subclasscheck__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__subclasshook__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__truediv__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__trunc__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__typing_is_unpacked_typevartuple__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__typing_prepare_subst__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__typing_subst__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__typing_unpacked_tuple_args__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__warningregistry__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__weaklistoffset__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__weakref__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__xor__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_abc_impl)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_abstract_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_active)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_annotation)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_anonymous_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_argtypes_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_as_parameter_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_asyncio_future_blocking)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_blksize)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_bootstrap)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_check_retval_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_dealloc_warn)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_feature_version)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_fields_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_finalizing)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_find_and_load)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_fix_up_module)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_flags_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_get_sourcefile)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_handle_fromlist)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_initializing)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_is_text_encoding)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_length_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_limbo)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_lock_unlock_module)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_loop)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_needs_com_addref_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_pack_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_restype_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_showwarnmsg)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_shutdown)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_slotnames)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_strptime_datetime)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_swappedbytes_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_type_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_uninitialized_submodules)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_warn_unawaited_coroutine)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_xoptions)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(a)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(abs_tol)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(access)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(add)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(add_done_callback)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(after_in_child)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(after_in_parent)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(aggregate_class)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(append)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(argdefs)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(arguments)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(argv)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(as_integer_ratio)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ast)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(attribute)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(authorizer_callback)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(autocommit)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(b)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(backtick)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(base)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(before)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(big)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(binary_form)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(block)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(buffer)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(buffer_callback)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(buffer_size)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(buffering)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(buffers)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(bufsize)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(builtins)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(byteorder)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(bytes)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(bytes_per_sep)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(c)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(c_call)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(c_exception)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(c_return)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cached_statements)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cadata)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cafile)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(call)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(call_exception_handler)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(call_soon)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cancel)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(capath)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(category)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cb_type)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(certfile)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(check_same_thread)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(clear)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(close)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(closed)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(closefd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(closure)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_argcount)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_cellvars)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_code)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_consts)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_exceptiontable)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_filename)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_firstlineno)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_flags)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_freevars)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_kwonlyargcount)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_linetable)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_name)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_names)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_nlocals)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_posonlyargcount)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_qualname)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_stacksize)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_varnames)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(code)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(command)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(comment_factory)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(consts)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(context)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cookie)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(copy)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(copyreg)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(coro)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(count)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cwd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(d)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(data)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(database)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(decode)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(decoder)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(default)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(defaultaction)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(delete)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(depth)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(detect_types)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(deterministic)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(device)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dict)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dictcomp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(difference_update)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(digest)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(digest_size)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(digestmod)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dir_fd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(discard)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dispatch_table)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(displayhook)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dklen)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(doc)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dont_inherit)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dst)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dst_dir_fd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(duration)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(e)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(effective_ids)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(element_factory)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(encode)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(encoding)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(end)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(end_lineno)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(end_offset)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(endpos)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(env)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(errors)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(event)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(eventmask)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc_type)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc_value)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(excepthook)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exception)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(extend)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(facility)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(factory)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(false)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(family)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fanout)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fd2)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fdel)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fget)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(file)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(file_actions)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(filename)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fileno)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(filepath)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fillvalue)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(filters)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(final)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(find_class)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fix_imports)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(flags)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(flush)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(follow_symlinks)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(format)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(frequency)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(from_param)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fromlist)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fromtimestamp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fromutc)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fset)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(func)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(future)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(generation)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(genexpr)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(get)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(get_debug)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(get_event_loop)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(get_loop)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(get_source)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(getattr)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(getstate)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(gid)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(globals)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(groupindex)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(groups)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(handle)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hash_name)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(header)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(headers)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hi)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hook)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(id)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ident)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ignore)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(imag)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(importlib)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(in_fd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(incoming)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(indexgroup)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(inf)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(inheritable)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(initial)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(initial_bytes)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(initial_value)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(initval)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(inner_size)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(input)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(insert_comments)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(insert_pis)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(instructions)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(intern)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(intersection)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(isatty)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(isinstance)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(isoformat)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(isolation_level)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(istext)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(item)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(items)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(iter)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(iterable)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(iterations)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(join)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(jump)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(keepends)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(key)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(keyfile)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(keys)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kind)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kw)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kw1)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kw2)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(lambda)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_node)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_traceback)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_type)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_value)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(latin1)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(leaf_size)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(len)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(length)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(level)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(limit)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(line)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(line_buffering)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(lineno)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(listcomp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(little)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(lo)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(locale)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(locals)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(logoption)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(loop)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mapping)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(match)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(max_length)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxdigits)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxevents)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxmem)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxsplit)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxvalue)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(memLevel)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(memlimit)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(message)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(metaclass)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(method)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mod)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mode)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(module)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(module_globals)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(modules)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mro)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(msg)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mycmp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(n)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(n_arg)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(n_fields)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(n_sequence_fields)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(n_unnamed_fields)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(name)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(name_from)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(namespace_separator)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(namespaces)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(narg)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ndigits)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(new_limit)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(newline)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(newlines)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(next)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(node_depth)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(node_offset)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ns)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(nstype)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(nt)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(null)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(number)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(obj)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(object)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(offset)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(offset_dst)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(offset_src)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(on_type_read)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(onceregistry)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(only_keys)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(oparg)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(opcode)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(open)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(opener)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(operation)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(optimize)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(options)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(order)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(out_fd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(outgoing)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(overlapped)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(owner)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(p)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pages)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(parent)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(password)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(path)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pattern)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(peek)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(persistent_id)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(persistent_load)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(person)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pi_factory)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pid)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(policy)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos1)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos2)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(posix)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(print_file_and_line)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(priority)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(progress)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(progress_handler)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(proto)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(protocol)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ps1)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ps2)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(query)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(quotetabs)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(r)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(raw)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(read)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(read1)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(readable)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(readall)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(readinto)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(readinto1)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(readline)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(readonly)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(real)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reducer_override)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(registry)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(rel_tol)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reload)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(repl)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(replace)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reserved)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reset)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(resetids)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(return)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reverse)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reversed)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(s)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(salt)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sched_priority)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(scheduler)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(seek)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(seekable)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(selectors)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(self)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(send)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sep)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sequence)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(server_hostname)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(server_side)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(session)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(setcomp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(setpgroup)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(setsid)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(setsigdef)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(setsigmask)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(setstate)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(shape)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(show_cmd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(signed)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(size)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sizehint)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(skip_file_prefixes)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sleep)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sock)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sort)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sound)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(source)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(source_traceback)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(src)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(src_dir_fd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(stacklevel)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(start)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(statement)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(status)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(stderr)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(stdin)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(stdout)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(step)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(store_name)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(strategy)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(strftime)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(strict)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(strict_mode)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(string)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sub_key)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(symmetric_difference_update)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tabsize)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tag)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(target)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(target_is_directory)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(task)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tb_frame)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tb_lasti)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tb_lineno)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tb_next)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tell)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(template)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(term)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(text)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(threading)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(throw)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timeout)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(times)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timetuple)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(top)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(trace_callback)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(traceback)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(trailers)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(translate)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(true)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(truncate)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(twice)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(txt)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(type)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tz)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tzname)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(uid)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(unlink)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(unraisablehook)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(uri)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(usedforsecurity)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(value)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(values)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(version)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(warnings)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(warnoptions)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(wbits)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(week)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(weekday)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(which)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(who)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(withdata)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(writable)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(write)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(write_through)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(x)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(year)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(zdict)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[0]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[1]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[2]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[3]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[4]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[5]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[6]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[7]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[8]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[9]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[10]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[11]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[12]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[13]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[14]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[15]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[16]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[17]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[18]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[19]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[20]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[21]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[22]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[23]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[24]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[25]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[26]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[27]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[28]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[29]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[30]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[31]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[32]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[33]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[34]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[35]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[36]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[37]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[38]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[39]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[40]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[41]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[42]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[43]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[44]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[45]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[46]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[47]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[48]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[49]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[50]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[51]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[52]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[53]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[54]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[55]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[56]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[57]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[58]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[59]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[60]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[61]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[62]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[63]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[64]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[65]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[66]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[67]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[68]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[69]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[70]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[71]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[72]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[73]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[74]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[75]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[76]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[77]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[78]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[79]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[80]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[81]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[82]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[83]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[84]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[85]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[86]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[87]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[88]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[89]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[90]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[91]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[92]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[93]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[94]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[95]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[96]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[97]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[98]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[99]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[100]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[101]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[102]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[103]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[104]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[105]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[106]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[107]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[108]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[109]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[110]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[111]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[112]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[113]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[114]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[115]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[116]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[117]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[118]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[119]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[120]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[121]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[122]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[123]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[124]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[125]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[126]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[127]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[128 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[129 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[130 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[131 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[132 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[133 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[134 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[135 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[136 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[137 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[138 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[139 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[140 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[141 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[142 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[143 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[144 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[145 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[146 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[147 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[148 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[149 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[150 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[151 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[152 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[153 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[154 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[155 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[156 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[157 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[158 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[159 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[160 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[161 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[162 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[163 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[164 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[165 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[166 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[167 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[168 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[169 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[170 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[171 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[172 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[173 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[174 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[175 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[176 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[177 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[178 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[179 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[180 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[181 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[182 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[183 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[184 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[185 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[186 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[187 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[188 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[189 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[190 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[191 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[192 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[193 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[194 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[195 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[196 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[197 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[198 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[199 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[200 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[201 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[202 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[203 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[204 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[205 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[206 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[207 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[208 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[209 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[210 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[211 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[212 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[213 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[214 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[215 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[216 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[217 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[218 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[219 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[220 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[221 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[222 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[223 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[224 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[225 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[226 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[227 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[228 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[229 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[230 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[231 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[232 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[233 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[234 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[235 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[236 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[237 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[238 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[239 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[240 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[241 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[242 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[243 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[244 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[245 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[246 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[247 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[248 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[249 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[250 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[251 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[252 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[253 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[254 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[255 - 128]); + /* non-generated */ + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_empty)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(tuple_empty)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(hamt_bitmap_node_empty)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_INTERP_SINGLETON(interp, hamt_empty)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(context_token_missing)); +} +#endif // Py_DEBUG +/* End auto-generated code */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_GLOBAL_OBJECTS_FINI_GENERATED_INIT_H */ diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h new file mode 100644 index 00000000000..6b1c8424424 --- /dev/null +++ b/Include/internal/pycore_global_strings.h @@ -0,0 +1,753 @@ +#ifndef Py_INTERNAL_GLOBAL_STRINGS_H +#define Py_INTERNAL_GLOBAL_STRINGS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +// The data structure & init here are inspired by Tools/build/deepfreeze.py. + +// All field names generated by ASCII_STR() have a common prefix, +// to help avoid collisions with keywords, macros, etc. + +#define STRUCT_FOR_ASCII_STR(LITERAL) \ + struct { \ + PyASCIIObject _ascii; \ + uint8_t _data[sizeof(LITERAL)]; \ + } +#define STRUCT_FOR_STR(NAME, LITERAL) \ + STRUCT_FOR_ASCII_STR(LITERAL) _py_ ## NAME; +#define STRUCT_FOR_ID(NAME) \ + STRUCT_FOR_ASCII_STR(#NAME) _py_ ## NAME; + +// XXX Order by frequency of use? + +/* The following is auto-generated by Tools/build/generate_global_objects.py. */ +struct _Py_global_strings { + struct { + STRUCT_FOR_STR(anon_dictcomp, "") + STRUCT_FOR_STR(anon_genexpr, "") + STRUCT_FOR_STR(anon_lambda, "") + STRUCT_FOR_STR(anon_listcomp, "") + STRUCT_FOR_STR(anon_module, "") + STRUCT_FOR_STR(anon_setcomp, "") + STRUCT_FOR_STR(anon_string, "") + STRUCT_FOR_STR(anon_unknown, "") + STRUCT_FOR_STR(close_br, "}") + STRUCT_FOR_STR(dbl_close_br, "}}") + STRUCT_FOR_STR(dbl_open_br, "{{") + STRUCT_FOR_STR(dbl_percent, "%%") + STRUCT_FOR_STR(dot, ".") + STRUCT_FOR_STR(dot_locals, ".") + STRUCT_FOR_STR(empty, "") + STRUCT_FOR_STR(json_decoder, "json.decoder") + STRUCT_FOR_STR(list_err, "list index out of range") + STRUCT_FOR_STR(newline, "\n") + STRUCT_FOR_STR(open_br, "{") + STRUCT_FOR_STR(percent, "%") + STRUCT_FOR_STR(shim_name, "") + STRUCT_FOR_STR(utf_8, "utf-8") + } literals; + + struct { + STRUCT_FOR_ID(CANCELLED) + STRUCT_FOR_ID(FINISHED) + STRUCT_FOR_ID(False) + STRUCT_FOR_ID(JSONDecodeError) + STRUCT_FOR_ID(PENDING) + STRUCT_FOR_ID(Py_Repr) + STRUCT_FOR_ID(TextIOWrapper) + STRUCT_FOR_ID(True) + STRUCT_FOR_ID(WarningMessage) + STRUCT_FOR_ID(_) + STRUCT_FOR_ID(__IOBase_closed) + STRUCT_FOR_ID(__abc_tpflags__) + STRUCT_FOR_ID(__abs__) + STRUCT_FOR_ID(__abstractmethods__) + STRUCT_FOR_ID(__add__) + STRUCT_FOR_ID(__aenter__) + STRUCT_FOR_ID(__aexit__) + STRUCT_FOR_ID(__aiter__) + STRUCT_FOR_ID(__all__) + STRUCT_FOR_ID(__and__) + STRUCT_FOR_ID(__anext__) + STRUCT_FOR_ID(__annotations__) + STRUCT_FOR_ID(__args__) + STRUCT_FOR_ID(__asyncio_running_event_loop__) + STRUCT_FOR_ID(__await__) + STRUCT_FOR_ID(__bases__) + STRUCT_FOR_ID(__bool__) + STRUCT_FOR_ID(__build_class__) + STRUCT_FOR_ID(__builtins__) + STRUCT_FOR_ID(__bytes__) + STRUCT_FOR_ID(__call__) + STRUCT_FOR_ID(__cantrace__) + STRUCT_FOR_ID(__class__) + STRUCT_FOR_ID(__class_getitem__) + STRUCT_FOR_ID(__classcell__) + STRUCT_FOR_ID(__complex__) + STRUCT_FOR_ID(__contains__) + STRUCT_FOR_ID(__copy__) + STRUCT_FOR_ID(__ctypes_from_outparam__) + STRUCT_FOR_ID(__del__) + STRUCT_FOR_ID(__delattr__) + STRUCT_FOR_ID(__delete__) + STRUCT_FOR_ID(__delitem__) + STRUCT_FOR_ID(__dict__) + STRUCT_FOR_ID(__dictoffset__) + STRUCT_FOR_ID(__dir__) + STRUCT_FOR_ID(__divmod__) + STRUCT_FOR_ID(__doc__) + STRUCT_FOR_ID(__enter__) + STRUCT_FOR_ID(__eq__) + STRUCT_FOR_ID(__exit__) + STRUCT_FOR_ID(__file__) + STRUCT_FOR_ID(__float__) + STRUCT_FOR_ID(__floordiv__) + STRUCT_FOR_ID(__format__) + STRUCT_FOR_ID(__fspath__) + STRUCT_FOR_ID(__ge__) + STRUCT_FOR_ID(__get__) + STRUCT_FOR_ID(__getattr__) + STRUCT_FOR_ID(__getattribute__) + STRUCT_FOR_ID(__getinitargs__) + STRUCT_FOR_ID(__getitem__) + STRUCT_FOR_ID(__getnewargs__) + STRUCT_FOR_ID(__getnewargs_ex__) + STRUCT_FOR_ID(__getstate__) + STRUCT_FOR_ID(__gt__) + STRUCT_FOR_ID(__hash__) + STRUCT_FOR_ID(__iadd__) + STRUCT_FOR_ID(__iand__) + STRUCT_FOR_ID(__ifloordiv__) + STRUCT_FOR_ID(__ilshift__) + STRUCT_FOR_ID(__imatmul__) + STRUCT_FOR_ID(__imod__) + STRUCT_FOR_ID(__import__) + STRUCT_FOR_ID(__imul__) + STRUCT_FOR_ID(__index__) + STRUCT_FOR_ID(__init__) + STRUCT_FOR_ID(__init_subclass__) + STRUCT_FOR_ID(__instancecheck__) + STRUCT_FOR_ID(__int__) + STRUCT_FOR_ID(__invert__) + STRUCT_FOR_ID(__ior__) + STRUCT_FOR_ID(__ipow__) + STRUCT_FOR_ID(__irshift__) + STRUCT_FOR_ID(__isabstractmethod__) + STRUCT_FOR_ID(__isub__) + STRUCT_FOR_ID(__iter__) + STRUCT_FOR_ID(__itruediv__) + STRUCT_FOR_ID(__ixor__) + STRUCT_FOR_ID(__le__) + STRUCT_FOR_ID(__len__) + STRUCT_FOR_ID(__length_hint__) + STRUCT_FOR_ID(__lltrace__) + STRUCT_FOR_ID(__loader__) + STRUCT_FOR_ID(__lshift__) + STRUCT_FOR_ID(__lt__) + STRUCT_FOR_ID(__main__) + STRUCT_FOR_ID(__matmul__) + STRUCT_FOR_ID(__missing__) + STRUCT_FOR_ID(__mod__) + STRUCT_FOR_ID(__module__) + STRUCT_FOR_ID(__mro_entries__) + STRUCT_FOR_ID(__mul__) + STRUCT_FOR_ID(__name__) + STRUCT_FOR_ID(__ne__) + STRUCT_FOR_ID(__neg__) + STRUCT_FOR_ID(__new__) + STRUCT_FOR_ID(__newobj__) + STRUCT_FOR_ID(__newobj_ex__) + STRUCT_FOR_ID(__next__) + STRUCT_FOR_ID(__notes__) + STRUCT_FOR_ID(__or__) + STRUCT_FOR_ID(__orig_class__) + STRUCT_FOR_ID(__origin__) + STRUCT_FOR_ID(__package__) + STRUCT_FOR_ID(__parameters__) + STRUCT_FOR_ID(__path__) + STRUCT_FOR_ID(__pos__) + STRUCT_FOR_ID(__pow__) + STRUCT_FOR_ID(__prepare__) + STRUCT_FOR_ID(__qualname__) + STRUCT_FOR_ID(__radd__) + STRUCT_FOR_ID(__rand__) + STRUCT_FOR_ID(__rdivmod__) + STRUCT_FOR_ID(__reduce__) + STRUCT_FOR_ID(__reduce_ex__) + STRUCT_FOR_ID(__repr__) + STRUCT_FOR_ID(__reversed__) + STRUCT_FOR_ID(__rfloordiv__) + STRUCT_FOR_ID(__rlshift__) + STRUCT_FOR_ID(__rmatmul__) + STRUCT_FOR_ID(__rmod__) + STRUCT_FOR_ID(__rmul__) + STRUCT_FOR_ID(__ror__) + STRUCT_FOR_ID(__round__) + STRUCT_FOR_ID(__rpow__) + STRUCT_FOR_ID(__rrshift__) + STRUCT_FOR_ID(__rshift__) + STRUCT_FOR_ID(__rsub__) + STRUCT_FOR_ID(__rtruediv__) + STRUCT_FOR_ID(__rxor__) + STRUCT_FOR_ID(__set__) + STRUCT_FOR_ID(__set_name__) + STRUCT_FOR_ID(__setattr__) + STRUCT_FOR_ID(__setitem__) + STRUCT_FOR_ID(__setstate__) + STRUCT_FOR_ID(__sizeof__) + STRUCT_FOR_ID(__slotnames__) + STRUCT_FOR_ID(__slots__) + STRUCT_FOR_ID(__spec__) + STRUCT_FOR_ID(__str__) + STRUCT_FOR_ID(__sub__) + STRUCT_FOR_ID(__subclasscheck__) + STRUCT_FOR_ID(__subclasshook__) + STRUCT_FOR_ID(__truediv__) + STRUCT_FOR_ID(__trunc__) + STRUCT_FOR_ID(__typing_is_unpacked_typevartuple__) + STRUCT_FOR_ID(__typing_prepare_subst__) + STRUCT_FOR_ID(__typing_subst__) + STRUCT_FOR_ID(__typing_unpacked_tuple_args__) + STRUCT_FOR_ID(__warningregistry__) + STRUCT_FOR_ID(__weaklistoffset__) + STRUCT_FOR_ID(__weakref__) + STRUCT_FOR_ID(__xor__) + STRUCT_FOR_ID(_abc_impl) + STRUCT_FOR_ID(_abstract_) + STRUCT_FOR_ID(_active) + STRUCT_FOR_ID(_annotation) + STRUCT_FOR_ID(_anonymous_) + STRUCT_FOR_ID(_argtypes_) + STRUCT_FOR_ID(_as_parameter_) + STRUCT_FOR_ID(_asyncio_future_blocking) + STRUCT_FOR_ID(_blksize) + STRUCT_FOR_ID(_bootstrap) + STRUCT_FOR_ID(_check_retval_) + STRUCT_FOR_ID(_dealloc_warn) + STRUCT_FOR_ID(_feature_version) + STRUCT_FOR_ID(_fields_) + STRUCT_FOR_ID(_finalizing) + STRUCT_FOR_ID(_find_and_load) + STRUCT_FOR_ID(_fix_up_module) + STRUCT_FOR_ID(_flags_) + STRUCT_FOR_ID(_get_sourcefile) + STRUCT_FOR_ID(_handle_fromlist) + STRUCT_FOR_ID(_initializing) + STRUCT_FOR_ID(_is_text_encoding) + STRUCT_FOR_ID(_length_) + STRUCT_FOR_ID(_limbo) + STRUCT_FOR_ID(_lock_unlock_module) + STRUCT_FOR_ID(_loop) + STRUCT_FOR_ID(_needs_com_addref_) + STRUCT_FOR_ID(_pack_) + STRUCT_FOR_ID(_restype_) + STRUCT_FOR_ID(_showwarnmsg) + STRUCT_FOR_ID(_shutdown) + STRUCT_FOR_ID(_slotnames) + STRUCT_FOR_ID(_strptime_datetime) + STRUCT_FOR_ID(_swappedbytes_) + STRUCT_FOR_ID(_type_) + STRUCT_FOR_ID(_uninitialized_submodules) + STRUCT_FOR_ID(_warn_unawaited_coroutine) + STRUCT_FOR_ID(_xoptions) + STRUCT_FOR_ID(a) + STRUCT_FOR_ID(abs_tol) + STRUCT_FOR_ID(access) + STRUCT_FOR_ID(add) + STRUCT_FOR_ID(add_done_callback) + STRUCT_FOR_ID(after_in_child) + STRUCT_FOR_ID(after_in_parent) + STRUCT_FOR_ID(aggregate_class) + STRUCT_FOR_ID(append) + STRUCT_FOR_ID(argdefs) + STRUCT_FOR_ID(arguments) + STRUCT_FOR_ID(argv) + STRUCT_FOR_ID(as_integer_ratio) + STRUCT_FOR_ID(ast) + STRUCT_FOR_ID(attribute) + STRUCT_FOR_ID(authorizer_callback) + STRUCT_FOR_ID(autocommit) + STRUCT_FOR_ID(b) + STRUCT_FOR_ID(backtick) + STRUCT_FOR_ID(base) + STRUCT_FOR_ID(before) + STRUCT_FOR_ID(big) + STRUCT_FOR_ID(binary_form) + STRUCT_FOR_ID(block) + STRUCT_FOR_ID(buffer) + STRUCT_FOR_ID(buffer_callback) + STRUCT_FOR_ID(buffer_size) + STRUCT_FOR_ID(buffering) + STRUCT_FOR_ID(buffers) + STRUCT_FOR_ID(bufsize) + STRUCT_FOR_ID(builtins) + STRUCT_FOR_ID(byteorder) + STRUCT_FOR_ID(bytes) + STRUCT_FOR_ID(bytes_per_sep) + STRUCT_FOR_ID(c) + STRUCT_FOR_ID(c_call) + STRUCT_FOR_ID(c_exception) + STRUCT_FOR_ID(c_return) + STRUCT_FOR_ID(cached_statements) + STRUCT_FOR_ID(cadata) + STRUCT_FOR_ID(cafile) + STRUCT_FOR_ID(call) + STRUCT_FOR_ID(call_exception_handler) + STRUCT_FOR_ID(call_soon) + STRUCT_FOR_ID(cancel) + STRUCT_FOR_ID(capath) + STRUCT_FOR_ID(category) + STRUCT_FOR_ID(cb_type) + STRUCT_FOR_ID(certfile) + STRUCT_FOR_ID(check_same_thread) + STRUCT_FOR_ID(clear) + STRUCT_FOR_ID(close) + STRUCT_FOR_ID(closed) + STRUCT_FOR_ID(closefd) + STRUCT_FOR_ID(closure) + STRUCT_FOR_ID(co_argcount) + STRUCT_FOR_ID(co_cellvars) + STRUCT_FOR_ID(co_code) + STRUCT_FOR_ID(co_consts) + STRUCT_FOR_ID(co_exceptiontable) + STRUCT_FOR_ID(co_filename) + STRUCT_FOR_ID(co_firstlineno) + STRUCT_FOR_ID(co_flags) + STRUCT_FOR_ID(co_freevars) + STRUCT_FOR_ID(co_kwonlyargcount) + STRUCT_FOR_ID(co_linetable) + STRUCT_FOR_ID(co_name) + STRUCT_FOR_ID(co_names) + STRUCT_FOR_ID(co_nlocals) + STRUCT_FOR_ID(co_posonlyargcount) + STRUCT_FOR_ID(co_qualname) + STRUCT_FOR_ID(co_stacksize) + STRUCT_FOR_ID(co_varnames) + STRUCT_FOR_ID(code) + STRUCT_FOR_ID(command) + STRUCT_FOR_ID(comment_factory) + STRUCT_FOR_ID(consts) + STRUCT_FOR_ID(context) + STRUCT_FOR_ID(cookie) + STRUCT_FOR_ID(copy) + STRUCT_FOR_ID(copyreg) + STRUCT_FOR_ID(coro) + STRUCT_FOR_ID(count) + STRUCT_FOR_ID(cwd) + STRUCT_FOR_ID(d) + STRUCT_FOR_ID(data) + STRUCT_FOR_ID(database) + STRUCT_FOR_ID(decode) + STRUCT_FOR_ID(decoder) + STRUCT_FOR_ID(default) + STRUCT_FOR_ID(defaultaction) + STRUCT_FOR_ID(delete) + STRUCT_FOR_ID(depth) + STRUCT_FOR_ID(detect_types) + STRUCT_FOR_ID(deterministic) + STRUCT_FOR_ID(device) + STRUCT_FOR_ID(dict) + STRUCT_FOR_ID(dictcomp) + STRUCT_FOR_ID(difference_update) + STRUCT_FOR_ID(digest) + STRUCT_FOR_ID(digest_size) + STRUCT_FOR_ID(digestmod) + STRUCT_FOR_ID(dir_fd) + STRUCT_FOR_ID(discard) + STRUCT_FOR_ID(dispatch_table) + STRUCT_FOR_ID(displayhook) + STRUCT_FOR_ID(dklen) + STRUCT_FOR_ID(doc) + STRUCT_FOR_ID(dont_inherit) + STRUCT_FOR_ID(dst) + STRUCT_FOR_ID(dst_dir_fd) + STRUCT_FOR_ID(duration) + STRUCT_FOR_ID(e) + STRUCT_FOR_ID(effective_ids) + STRUCT_FOR_ID(element_factory) + STRUCT_FOR_ID(encode) + STRUCT_FOR_ID(encoding) + STRUCT_FOR_ID(end) + STRUCT_FOR_ID(end_lineno) + STRUCT_FOR_ID(end_offset) + STRUCT_FOR_ID(endpos) + STRUCT_FOR_ID(env) + STRUCT_FOR_ID(errors) + STRUCT_FOR_ID(event) + STRUCT_FOR_ID(eventmask) + STRUCT_FOR_ID(exc_type) + STRUCT_FOR_ID(exc_value) + STRUCT_FOR_ID(excepthook) + STRUCT_FOR_ID(exception) + STRUCT_FOR_ID(exp) + STRUCT_FOR_ID(extend) + STRUCT_FOR_ID(facility) + STRUCT_FOR_ID(factory) + STRUCT_FOR_ID(false) + STRUCT_FOR_ID(family) + STRUCT_FOR_ID(fanout) + STRUCT_FOR_ID(fd) + STRUCT_FOR_ID(fd2) + STRUCT_FOR_ID(fdel) + STRUCT_FOR_ID(fget) + STRUCT_FOR_ID(file) + STRUCT_FOR_ID(file_actions) + STRUCT_FOR_ID(filename) + STRUCT_FOR_ID(fileno) + STRUCT_FOR_ID(filepath) + STRUCT_FOR_ID(fillvalue) + STRUCT_FOR_ID(filters) + STRUCT_FOR_ID(final) + STRUCT_FOR_ID(find_class) + STRUCT_FOR_ID(fix_imports) + STRUCT_FOR_ID(flags) + STRUCT_FOR_ID(flush) + STRUCT_FOR_ID(follow_symlinks) + STRUCT_FOR_ID(format) + STRUCT_FOR_ID(frequency) + STRUCT_FOR_ID(from_param) + STRUCT_FOR_ID(fromlist) + STRUCT_FOR_ID(fromtimestamp) + STRUCT_FOR_ID(fromutc) + STRUCT_FOR_ID(fset) + STRUCT_FOR_ID(func) + STRUCT_FOR_ID(future) + STRUCT_FOR_ID(generation) + STRUCT_FOR_ID(genexpr) + STRUCT_FOR_ID(get) + STRUCT_FOR_ID(get_debug) + STRUCT_FOR_ID(get_event_loop) + STRUCT_FOR_ID(get_loop) + STRUCT_FOR_ID(get_source) + STRUCT_FOR_ID(getattr) + STRUCT_FOR_ID(getstate) + STRUCT_FOR_ID(gid) + STRUCT_FOR_ID(globals) + STRUCT_FOR_ID(groupindex) + STRUCT_FOR_ID(groups) + STRUCT_FOR_ID(handle) + STRUCT_FOR_ID(hash_name) + STRUCT_FOR_ID(header) + STRUCT_FOR_ID(headers) + STRUCT_FOR_ID(hi) + STRUCT_FOR_ID(hook) + STRUCT_FOR_ID(id) + STRUCT_FOR_ID(ident) + STRUCT_FOR_ID(ignore) + STRUCT_FOR_ID(imag) + STRUCT_FOR_ID(importlib) + STRUCT_FOR_ID(in_fd) + STRUCT_FOR_ID(incoming) + STRUCT_FOR_ID(indexgroup) + STRUCT_FOR_ID(inf) + STRUCT_FOR_ID(inheritable) + STRUCT_FOR_ID(initial) + STRUCT_FOR_ID(initial_bytes) + STRUCT_FOR_ID(initial_value) + STRUCT_FOR_ID(initval) + STRUCT_FOR_ID(inner_size) + STRUCT_FOR_ID(input) + STRUCT_FOR_ID(insert_comments) + STRUCT_FOR_ID(insert_pis) + STRUCT_FOR_ID(instructions) + STRUCT_FOR_ID(intern) + STRUCT_FOR_ID(intersection) + STRUCT_FOR_ID(isatty) + STRUCT_FOR_ID(isinstance) + STRUCT_FOR_ID(isoformat) + STRUCT_FOR_ID(isolation_level) + STRUCT_FOR_ID(istext) + STRUCT_FOR_ID(item) + STRUCT_FOR_ID(items) + STRUCT_FOR_ID(iter) + STRUCT_FOR_ID(iterable) + STRUCT_FOR_ID(iterations) + STRUCT_FOR_ID(join) + STRUCT_FOR_ID(jump) + STRUCT_FOR_ID(keepends) + STRUCT_FOR_ID(key) + STRUCT_FOR_ID(keyfile) + STRUCT_FOR_ID(keys) + STRUCT_FOR_ID(kind) + STRUCT_FOR_ID(kw) + STRUCT_FOR_ID(kw1) + STRUCT_FOR_ID(kw2) + STRUCT_FOR_ID(lambda) + STRUCT_FOR_ID(last) + STRUCT_FOR_ID(last_node) + STRUCT_FOR_ID(last_traceback) + STRUCT_FOR_ID(last_type) + STRUCT_FOR_ID(last_value) + STRUCT_FOR_ID(latin1) + STRUCT_FOR_ID(leaf_size) + STRUCT_FOR_ID(len) + STRUCT_FOR_ID(length) + STRUCT_FOR_ID(level) + STRUCT_FOR_ID(limit) + STRUCT_FOR_ID(line) + STRUCT_FOR_ID(line_buffering) + STRUCT_FOR_ID(lineno) + STRUCT_FOR_ID(listcomp) + STRUCT_FOR_ID(little) + STRUCT_FOR_ID(lo) + STRUCT_FOR_ID(locale) + STRUCT_FOR_ID(locals) + STRUCT_FOR_ID(logoption) + STRUCT_FOR_ID(loop) + STRUCT_FOR_ID(mapping) + STRUCT_FOR_ID(match) + STRUCT_FOR_ID(max_length) + STRUCT_FOR_ID(maxdigits) + STRUCT_FOR_ID(maxevents) + STRUCT_FOR_ID(maxmem) + STRUCT_FOR_ID(maxsplit) + STRUCT_FOR_ID(maxvalue) + STRUCT_FOR_ID(memLevel) + STRUCT_FOR_ID(memlimit) + STRUCT_FOR_ID(message) + STRUCT_FOR_ID(metaclass) + STRUCT_FOR_ID(method) + STRUCT_FOR_ID(mod) + STRUCT_FOR_ID(mode) + STRUCT_FOR_ID(module) + STRUCT_FOR_ID(module_globals) + STRUCT_FOR_ID(modules) + STRUCT_FOR_ID(mro) + STRUCT_FOR_ID(msg) + STRUCT_FOR_ID(mycmp) + STRUCT_FOR_ID(n) + STRUCT_FOR_ID(n_arg) + STRUCT_FOR_ID(n_fields) + STRUCT_FOR_ID(n_sequence_fields) + STRUCT_FOR_ID(n_unnamed_fields) + STRUCT_FOR_ID(name) + STRUCT_FOR_ID(name_from) + STRUCT_FOR_ID(namespace_separator) + STRUCT_FOR_ID(namespaces) + STRUCT_FOR_ID(narg) + STRUCT_FOR_ID(ndigits) + STRUCT_FOR_ID(new_limit) + STRUCT_FOR_ID(newline) + STRUCT_FOR_ID(newlines) + STRUCT_FOR_ID(next) + STRUCT_FOR_ID(node_depth) + STRUCT_FOR_ID(node_offset) + STRUCT_FOR_ID(ns) + STRUCT_FOR_ID(nstype) + STRUCT_FOR_ID(nt) + STRUCT_FOR_ID(null) + STRUCT_FOR_ID(number) + STRUCT_FOR_ID(obj) + STRUCT_FOR_ID(object) + STRUCT_FOR_ID(offset) + STRUCT_FOR_ID(offset_dst) + STRUCT_FOR_ID(offset_src) + STRUCT_FOR_ID(on_type_read) + STRUCT_FOR_ID(onceregistry) + STRUCT_FOR_ID(only_keys) + STRUCT_FOR_ID(oparg) + STRUCT_FOR_ID(opcode) + STRUCT_FOR_ID(open) + STRUCT_FOR_ID(opener) + STRUCT_FOR_ID(operation) + STRUCT_FOR_ID(optimize) + STRUCT_FOR_ID(options) + STRUCT_FOR_ID(order) + STRUCT_FOR_ID(out_fd) + STRUCT_FOR_ID(outgoing) + STRUCT_FOR_ID(overlapped) + STRUCT_FOR_ID(owner) + STRUCT_FOR_ID(p) + STRUCT_FOR_ID(pages) + STRUCT_FOR_ID(parent) + STRUCT_FOR_ID(password) + STRUCT_FOR_ID(path) + STRUCT_FOR_ID(pattern) + STRUCT_FOR_ID(peek) + STRUCT_FOR_ID(persistent_id) + STRUCT_FOR_ID(persistent_load) + STRUCT_FOR_ID(person) + STRUCT_FOR_ID(pi_factory) + STRUCT_FOR_ID(pid) + STRUCT_FOR_ID(policy) + STRUCT_FOR_ID(pos) + STRUCT_FOR_ID(pos1) + STRUCT_FOR_ID(pos2) + STRUCT_FOR_ID(posix) + STRUCT_FOR_ID(print_file_and_line) + STRUCT_FOR_ID(priority) + STRUCT_FOR_ID(progress) + STRUCT_FOR_ID(progress_handler) + STRUCT_FOR_ID(proto) + STRUCT_FOR_ID(protocol) + STRUCT_FOR_ID(ps1) + STRUCT_FOR_ID(ps2) + STRUCT_FOR_ID(query) + STRUCT_FOR_ID(quotetabs) + STRUCT_FOR_ID(r) + STRUCT_FOR_ID(raw) + STRUCT_FOR_ID(read) + STRUCT_FOR_ID(read1) + STRUCT_FOR_ID(readable) + STRUCT_FOR_ID(readall) + STRUCT_FOR_ID(readinto) + STRUCT_FOR_ID(readinto1) + STRUCT_FOR_ID(readline) + STRUCT_FOR_ID(readonly) + STRUCT_FOR_ID(real) + STRUCT_FOR_ID(reducer_override) + STRUCT_FOR_ID(registry) + STRUCT_FOR_ID(rel_tol) + STRUCT_FOR_ID(reload) + STRUCT_FOR_ID(repl) + STRUCT_FOR_ID(replace) + STRUCT_FOR_ID(reserved) + STRUCT_FOR_ID(reset) + STRUCT_FOR_ID(resetids) + STRUCT_FOR_ID(return) + STRUCT_FOR_ID(reverse) + STRUCT_FOR_ID(reversed) + STRUCT_FOR_ID(s) + STRUCT_FOR_ID(salt) + STRUCT_FOR_ID(sched_priority) + STRUCT_FOR_ID(scheduler) + STRUCT_FOR_ID(seek) + STRUCT_FOR_ID(seekable) + STRUCT_FOR_ID(selectors) + STRUCT_FOR_ID(self) + STRUCT_FOR_ID(send) + STRUCT_FOR_ID(sep) + STRUCT_FOR_ID(sequence) + STRUCT_FOR_ID(server_hostname) + STRUCT_FOR_ID(server_side) + STRUCT_FOR_ID(session) + STRUCT_FOR_ID(setcomp) + STRUCT_FOR_ID(setpgroup) + STRUCT_FOR_ID(setsid) + STRUCT_FOR_ID(setsigdef) + STRUCT_FOR_ID(setsigmask) + STRUCT_FOR_ID(setstate) + STRUCT_FOR_ID(shape) + STRUCT_FOR_ID(show_cmd) + STRUCT_FOR_ID(signed) + STRUCT_FOR_ID(size) + STRUCT_FOR_ID(sizehint) + STRUCT_FOR_ID(skip_file_prefixes) + STRUCT_FOR_ID(sleep) + STRUCT_FOR_ID(sock) + STRUCT_FOR_ID(sort) + STRUCT_FOR_ID(sound) + STRUCT_FOR_ID(source) + STRUCT_FOR_ID(source_traceback) + STRUCT_FOR_ID(src) + STRUCT_FOR_ID(src_dir_fd) + STRUCT_FOR_ID(stacklevel) + STRUCT_FOR_ID(start) + STRUCT_FOR_ID(statement) + STRUCT_FOR_ID(status) + STRUCT_FOR_ID(stderr) + STRUCT_FOR_ID(stdin) + STRUCT_FOR_ID(stdout) + STRUCT_FOR_ID(step) + STRUCT_FOR_ID(store_name) + STRUCT_FOR_ID(strategy) + STRUCT_FOR_ID(strftime) + STRUCT_FOR_ID(strict) + STRUCT_FOR_ID(strict_mode) + STRUCT_FOR_ID(string) + STRUCT_FOR_ID(sub_key) + STRUCT_FOR_ID(symmetric_difference_update) + STRUCT_FOR_ID(tabsize) + STRUCT_FOR_ID(tag) + STRUCT_FOR_ID(target) + STRUCT_FOR_ID(target_is_directory) + STRUCT_FOR_ID(task) + STRUCT_FOR_ID(tb_frame) + STRUCT_FOR_ID(tb_lasti) + STRUCT_FOR_ID(tb_lineno) + STRUCT_FOR_ID(tb_next) + STRUCT_FOR_ID(tell) + STRUCT_FOR_ID(template) + STRUCT_FOR_ID(term) + STRUCT_FOR_ID(text) + STRUCT_FOR_ID(threading) + STRUCT_FOR_ID(throw) + STRUCT_FOR_ID(timeout) + STRUCT_FOR_ID(times) + STRUCT_FOR_ID(timetuple) + STRUCT_FOR_ID(top) + STRUCT_FOR_ID(trace_callback) + STRUCT_FOR_ID(traceback) + STRUCT_FOR_ID(trailers) + STRUCT_FOR_ID(translate) + STRUCT_FOR_ID(true) + STRUCT_FOR_ID(truncate) + STRUCT_FOR_ID(twice) + STRUCT_FOR_ID(txt) + STRUCT_FOR_ID(type) + STRUCT_FOR_ID(tz) + STRUCT_FOR_ID(tzname) + STRUCT_FOR_ID(uid) + STRUCT_FOR_ID(unlink) + STRUCT_FOR_ID(unraisablehook) + STRUCT_FOR_ID(uri) + STRUCT_FOR_ID(usedforsecurity) + STRUCT_FOR_ID(value) + STRUCT_FOR_ID(values) + STRUCT_FOR_ID(version) + STRUCT_FOR_ID(warnings) + STRUCT_FOR_ID(warnoptions) + STRUCT_FOR_ID(wbits) + STRUCT_FOR_ID(week) + STRUCT_FOR_ID(weekday) + STRUCT_FOR_ID(which) + STRUCT_FOR_ID(who) + STRUCT_FOR_ID(withdata) + STRUCT_FOR_ID(writable) + STRUCT_FOR_ID(write) + STRUCT_FOR_ID(write_through) + STRUCT_FOR_ID(x) + STRUCT_FOR_ID(year) + STRUCT_FOR_ID(zdict) + } identifiers; + struct { + PyASCIIObject _ascii; + uint8_t _data[2]; + } ascii[128]; + struct { + PyCompactUnicodeObject _latin1; + uint8_t _data[2]; + } latin1[128]; +}; +/* End auto-generated code */ + +#undef ID +#undef STR + + +#define _Py_ID(NAME) \ + (_Py_SINGLETON(strings.identifiers._py_ ## NAME._ascii.ob_base)) +#define _Py_STR(NAME) \ + (_Py_SINGLETON(strings.literals._py_ ## NAME._ascii.ob_base)) + +/* _Py_DECLARE_STR() should precede all uses of _Py_STR() in a function. + + This is true even if the same string has already been declared + elsewhere, even in the same file. Mismatched duplicates are detected + by Tools/scripts/generate-global-objects.py. + + Pairing _Py_DECLARE_STR() with every use of _Py_STR() makes sure the + string keeps working even if the declaration is removed somewhere + else. It also makes it clear what the actual string is at every + place it is being used. */ +#define _Py_DECLARE_STR(name, str) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_GLOBAL_STRINGS_H */ diff --git a/Include/internal/pycore_hamt.h b/Include/internal/pycore_hamt.h index aaf65590955..d8742c7cb63 100644 --- a/Include/internal/pycore_hamt.h +++ b/Include/internal/pycore_hamt.h @@ -5,10 +5,33 @@ # error "this header requires Py_BUILD_CORE define" #endif -#define _Py_HAMT_MAX_TREE_DEPTH 7 + +/* +HAMT tree is shaped by hashes of keys. Every group of 5 bits of a hash denotes +the exact position of the key in one level of the tree. Since we're using +32 bit hashes, we can have at most 7 such levels. Although if there are +two distinct keys with equal hashes, they will have to occupy the same +cell in the 7th level of the tree -- so we'd put them in a "collision" node. +Which brings the total possible tree depth to 8. Read more about the actual +layout of the HAMT tree in `hamt.c`. + +This constant is used to define a datastucture for storing iteration state. +*/ +#define _Py_HAMT_MAX_TREE_DEPTH 8 -#define PyHamt_Check(o) Py_IS_TYPE(o, &_PyHamt_Type) +extern PyTypeObject _PyHamt_Type; +extern PyTypeObject _PyHamt_ArrayNode_Type; +extern PyTypeObject _PyHamt_BitmapNode_Type; +extern PyTypeObject _PyHamt_CollisionNode_Type; +extern PyTypeObject _PyHamtKeys_Type; +extern PyTypeObject _PyHamtValues_Type; +extern PyTypeObject _PyHamtItems_Type; + + +/* other API */ + +#define PyHamt_Check(o) Py_IS_TYPE((o), &_PyHamt_Type) /* Abstract tree node. */ @@ -26,6 +49,13 @@ typedef struct { } PyHamtObject; +typedef struct { + PyObject_VAR_HEAD + uint32_t b_bitmap; + PyObject *b_array[1]; +} PyHamtNode_Bitmap; + + /* A struct to hold the state of depth-first traverse of the tree. HAMT is an immutable collection. Iterators will hold a strong reference @@ -61,15 +91,6 @@ typedef struct { } PyHamtIterator; -PyAPI_DATA(PyTypeObject) _PyHamt_Type; -PyAPI_DATA(PyTypeObject) _PyHamt_ArrayNode_Type; -PyAPI_DATA(PyTypeObject) _PyHamt_BitmapNode_Type; -PyAPI_DATA(PyTypeObject) _PyHamt_CollisionNode_Type; -PyAPI_DATA(PyTypeObject) _PyHamtKeys_Type; -PyAPI_DATA(PyTypeObject) _PyHamtValues_Type; -PyAPI_DATA(PyTypeObject) _PyHamtItems_Type; - - /* Create a new HAMT immutable mapping. */ PyHamtObject * _PyHamt_New(void); @@ -110,7 +131,4 @@ PyObject * _PyHamt_NewIterValues(PyHamtObject *o); /* Return a Items iterator over "o". */ PyObject * _PyHamt_NewIterItems(PyHamtObject *o); -int _PyHamt_Init(void); -void _PyHamt_Fini(void); - #endif /* !Py_INTERNAL_HAMT_H */ diff --git a/Include/internal/pycore_hashtable.h b/Include/internal/pycore_hashtable.h index 18757abc28c..6501ab14d27 100644 --- a/Include/internal/pycore_hashtable.h +++ b/Include/internal/pycore_hashtable.h @@ -18,9 +18,9 @@ typedef struct { _Py_slist_item_t *head; } _Py_slist_t; -#define _Py_SLIST_ITEM_NEXT(ITEM) (((_Py_slist_item_t *)ITEM)->next) +#define _Py_SLIST_ITEM_NEXT(ITEM) _Py_RVALUE(((_Py_slist_item_t *)(ITEM))->next) -#define _Py_SLIST_HEAD(SLIST) (((_Py_slist_t *)SLIST)->head) +#define _Py_SLIST_HEAD(SLIST) _Py_RVALUE(((_Py_slist_t *)(SLIST))->head) /* _Py_hashtable: table entry */ diff --git a/Include/internal/pycore_import.h b/Include/internal/pycore_import.h index aee1f66a3ea..9036dff6725 100644 --- a/Include/internal/pycore_import.h +++ b/Include/internal/pycore_import.h @@ -5,6 +5,38 @@ extern "C" { #endif + +struct _import_runtime_state { + /* The builtin modules (defined in config.c). */ + struct _inittab *inittab; + /* The most recent value assigned to a PyModuleDef.m_base.m_index. + This is incremented each time PyModuleDef_Init() is called, + which is just about every time an extension module is imported. + See PyInterpreterState.modules_by_index for more info. */ + Py_ssize_t last_module_index; + /* A dict mapping (filename, name) to PyModuleDef for modules. + Only legacy (single-phase init) extension modules are added + and only if they support multiple initialization (m_size >- 0) + or are imported in the main interpreter. + This is initialized lazily in _PyImport_FixupExtensionObject(). + Modules are added there and looked up in _imp.find_extension(). */ + PyObject *extensions; + /* The global import lock. */ + struct { + PyThread_type_lock mutex; + unsigned long thread; + int level; + } lock; + struct { + int import_level; + _PyTime_t accumulated; + int header; + } find_and_load; + /* Package context -- the full module name for package imports */ + const char * pkgcontext; +}; + + #ifdef HAVE_FORK extern PyStatus _PyImport_ReInitLock(void); #endif diff --git a/Include/internal/pycore_initconfig.h b/Include/internal/pycore_initconfig.h index 9014fcd41d8..69f88d7d1d4 100644 --- a/Include/internal/pycore_initconfig.h +++ b/Include/internal/pycore_initconfig.h @@ -36,13 +36,13 @@ struct pyruntimestate; ._type = _PyStatus_TYPE_EXIT, \ .exitcode = (EXITCODE)} #define _PyStatus_IS_ERROR(err) \ - (err._type == _PyStatus_TYPE_ERROR) + ((err)._type == _PyStatus_TYPE_ERROR) #define _PyStatus_IS_EXIT(err) \ - (err._type == _PyStatus_TYPE_EXIT) + ((err)._type == _PyStatus_TYPE_EXIT) #define _PyStatus_EXCEPTION(err) \ - (err._type != _PyStatus_TYPE_OK) + ((err)._type != _PyStatus_TYPE_OK) #define _PyStatus_UPDATE_FUNC(err) \ - do { err.func = _PyStatus_GET_FUNC(); } while (0) + do { (err).func = _PyStatus_GET_FUNC(); } while (0) PyObject* _PyErr_SetFromPyStatus(PyStatus status); @@ -166,6 +166,10 @@ extern PyStatus _PyConfig_SetPyArgv( PyAPI_FUNC(PyObject*) _PyConfig_AsDict(const PyConfig *config); PyAPI_FUNC(int) _PyConfig_FromDict(PyConfig *config, PyObject *dict); +extern void _Py_DumpPathConfig(PyThreadState *tstate); + +PyAPI_FUNC(PyObject*) _Py_Get_Getpath_CodeObject(void); + /* --- Function used for testing ---------------------------------- */ diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 18f21432008..0e3d46852f2 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -8,207 +8,26 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include + #include "pycore_atomic.h" // _Py_atomic_address #include "pycore_ast_state.h" // struct ast_state -#include "pycore_gil.h" // struct _gil_runtime_state +#include "pycore_ceval_state.h" // struct _ceval_state +#include "pycore_code.h" // struct callable_cache +#include "pycore_context.h" // struct _Py_context_state +#include "pycore_dict_state.h" // struct _Py_dict_state +#include "pycore_exceptions.h" // struct _Py_exc_state +#include "pycore_floatobject.h" // struct _Py_float_state +#include "pycore_function.h" // FUNC_MAX_WATCHERS +#include "pycore_genobject.h" // struct _Py_async_gen_state #include "pycore_gc.h" // struct _gc_runtime_state +#include "pycore_list.h" // struct _Py_list_state +#include "pycore_global_objects.h" // struct _Py_interp_static_objects +#include "pycore_tuple.h" // struct _Py_tuple_state +#include "pycore_typeobject.h" // struct type_cache +#include "pycore_unicodeobject.h" // struct _Py_unicode_state #include "pycore_warnings.h" // struct _warnings_runtime_state -struct _pending_calls { - PyThread_type_lock lock; - /* Request for running pending calls. */ - _Py_atomic_int calls_to_do; - /* Request for looking at the `async_exc` field of the current - thread state. - Guarded by the GIL. */ - int async_exc; -#define NPENDINGCALLS 32 - struct { - int (*func)(void *); - void *arg; - } calls[NPENDINGCALLS]; - int first; - int last; -}; - -struct _ceval_state { - int recursion_limit; - /* This single variable consolidates all requests to break out of - the fast path in the eval loop. */ - _Py_atomic_int eval_breaker; - /* Request for dropping the GIL */ - _Py_atomic_int gil_drop_request; - struct _pending_calls pending; -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - struct _gil_runtime_state gil; -#endif -}; - -/* fs_codec.encoding is initialized to NULL. - Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */ -struct _Py_unicode_fs_codec { - char *encoding; // Filesystem encoding (encoded to UTF-8) - int utf8; // encoding=="utf-8"? - char *errors; // Filesystem errors (encoded to UTF-8) - _Py_error_handler error_handler; -}; - -struct _Py_bytes_state { - PyObject *empty_string; - PyBytesObject *characters[256]; -}; - -struct _Py_unicode_ids { - Py_ssize_t size; - PyObject **array; -}; - -struct _Py_unicode_state { - // The empty Unicode object is a singleton to improve performance. - PyObject *empty_string; - /* Single character Unicode strings in the Latin-1 range are being - shared as well. */ - PyObject *latin1[256]; - struct _Py_unicode_fs_codec fs_codec; - - /* This dictionary holds all interned unicode strings. Note that references - to strings in this dictionary are *not* counted in the string's ob_refcnt. - When the interned string reaches a refcnt of 0 the string deallocation - function will delete the reference from this dictionary. - - Another way to look at this is that to say that the actual reference - count of a string is: s->ob_refcnt + (s->state ? 2 : 0) - */ - PyObject *interned; - - // Unicode identifiers (_Py_Identifier): see _PyUnicode_FromId() - struct _Py_unicode_ids ids; -}; - -#ifndef WITH_FREELISTS -// without freelists -# define PyFloat_MAXFREELIST 0 -// for tuples only store empty tuple singleton -# define PyTuple_MAXSAVESIZE 1 -# define PyTuple_MAXFREELIST 1 -# define PyList_MAXFREELIST 0 -# define PyDict_MAXFREELIST 0 -# define PyFrame_MAXFREELIST 0 -# define _PyAsyncGen_MAXFREELIST 0 -# define PyContext_MAXFREELIST 0 -#endif - -#ifndef PyFloat_MAXFREELIST -# define PyFloat_MAXFREELIST 100 -#endif - -struct _Py_float_state { -#if PyFloat_MAXFREELIST > 0 - /* Special free list - free_list is a singly-linked list of available PyFloatObjects, - linked via abuse of their ob_type members. */ - int numfree; - PyFloatObject *free_list; -#endif -}; - -/* Speed optimization to avoid frequent malloc/free of small tuples */ -#ifndef PyTuple_MAXSAVESIZE - // Largest tuple to save on free list -# define PyTuple_MAXSAVESIZE 20 -#endif -#ifndef PyTuple_MAXFREELIST - // Maximum number of tuples of each size to save -# define PyTuple_MAXFREELIST 2000 -#endif - -struct _Py_tuple_state { -#if PyTuple_MAXSAVESIZE > 0 - /* Entries 1 up to PyTuple_MAXSAVESIZE are free lists, - entry 0 is the empty tuple () of which at most one instance - will be allocated. */ - PyTupleObject *free_list[PyTuple_MAXSAVESIZE]; - int numfree[PyTuple_MAXSAVESIZE]; -#endif -}; - -/* Empty list reuse scheme to save calls to malloc and free */ -#ifndef PyList_MAXFREELIST -# define PyList_MAXFREELIST 80 -#endif - -struct _Py_list_state { -#if PyList_MAXFREELIST > 0 - PyListObject *free_list[PyList_MAXFREELIST]; - int numfree; -#endif -}; - -#ifndef PyDict_MAXFREELIST -# define PyDict_MAXFREELIST 80 -#endif - -struct _Py_dict_state { -#if PyDict_MAXFREELIST > 0 - /* Dictionary reuse scheme to save calls to malloc and free */ - PyDictObject *free_list[PyDict_MAXFREELIST]; - int numfree; - PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST]; - int keys_numfree; -#endif -}; - -#ifndef PyFrame_MAXFREELIST -# define PyFrame_MAXFREELIST 200 -#endif - -struct _Py_frame_state { -#if PyFrame_MAXFREELIST > 0 - PyFrameObject *free_list; - /* number of frames currently in free_list */ - int numfree; -#endif -}; - -#ifndef _PyAsyncGen_MAXFREELIST -# define _PyAsyncGen_MAXFREELIST 80 -#endif - -struct _Py_async_gen_state { -#if _PyAsyncGen_MAXFREELIST > 0 - /* Freelists boost performance 6-10%; they also reduce memory - fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend - are short-living objects that are instantiated for every - __anext__() call. */ - struct _PyAsyncGenWrappedValue* value_freelist[_PyAsyncGen_MAXFREELIST]; - int value_numfree; - - struct PyAsyncGenASend* asend_freelist[_PyAsyncGen_MAXFREELIST]; - int asend_numfree; -#endif -}; - -#ifndef PyContext_MAXFREELIST -# define PyContext_MAXFREELIST 255 -#endif - -struct _Py_context_state { -#if PyContext_MAXFREELIST > 0 - // List of free PyContext objects - PyContext *freelist; - int numfree; -#endif -}; - -struct _Py_exc_state { - // The dict mapping from errno codes to OSError subclasses - PyObject *errnomap; - PyBaseExceptionObject *memerrors_freelist; - int memerrors_numfree; - // The ExceptionGroup type - PyObject *PyExc_ExceptionGroup; -}; - // atexit state typedef struct { @@ -224,34 +43,34 @@ struct atexit_state { }; -// Type attribute lookup cache: speed up attribute and method lookups, -// see _PyType_Lookup(). -struct type_cache_entry { - unsigned int version; // initialized from type->tp_version_tag - PyObject *name; // reference to exactly a str or None - PyObject *value; // borrowed reference or NULL -}; - -#define MCACHE_SIZE_EXP 12 -#define MCACHE_STATS 0 - -struct type_cache { - struct type_cache_entry hashtable[1 << MCACHE_SIZE_EXP]; -#if MCACHE_STATS - size_t hits; - size_t misses; - size_t collisions; -#endif +struct _Py_long_state { + int max_str_digits; }; /* interpreter state */ -// The PyInterpreterState typedef is in Include/pystate.h. +/* PyInterpreterState holds the global state for one of the runtime's + interpreters. Typically the initial (main) interpreter is the only one. + + The PyInterpreterState typedef is in Include/pytypedefs.h. + */ struct _is { - struct _is *next; - struct _ts *tstate_head; + PyInterpreterState *next; + + struct pythreads { + uint64_t next_unique_id; + /* The linked list of threads, newest first. */ + PyThreadState *head; + /* Used in Modules/_threadmodule.c. */ + long count; + /* Support for runtime thread stack size tuning. + A value of 0 means using the platform's default stack size + or the size specified by the THREAD_STACK_SIZE macro. */ + /* Used in Python/thread.c. */ + size_t stacksize; + } threads; /* Reference to the _PyRuntime global variable. This field exists to not have to pass runtime in addition to tstate to a function. @@ -263,6 +82,11 @@ struct _is { int requires_idref; PyThread_type_lock id_mutex; + /* Has been initialized to a safe state. + + In order to be effective, this must be set to 0 during or right + after allocation. */ + int _initialized; int finalizing; struct _ceval_state ceval; @@ -270,6 +94,25 @@ struct _is { // sys.modules dictionary PyObject *modules; + /* This is the list of module objects for all legacy (single-phase init) + extension modules ever loaded in this process (i.e. imported + in this interpreter or in any other). Py_None stands in for + modules that haven't actually been imported in this interpreter. + + A module's index (PyModuleDef.m_base.m_index) is used to look up + the corresponding module object for this interpreter, if any. + (See PyState_FindModule().) When any extension module + is initialized during import, its moduledef gets initialized by + PyModuleDef_Init(), and the first time that happens for each + PyModuleDef, its index gets set to the current value of + a global counter (see _PyRuntimeState.imports.last_module_index). + The entry for that index in this interpreter remains unset until + the module is actually imported here. (Py_None is used as + a placeholder.) Note that multi-phase init modules always get + an index for which there will never be a module set. + + This is initialized lazily in _PyState_AddModule(), which is also + where modules get added. */ PyObject *modules_by_index; // Dictionary of the sys module PyObject *sysdict; @@ -281,14 +124,6 @@ struct _is { // (-1: "off", 1: "on", 0: no override) int override_frozen_modules; - /* Used in Modules/_threadmodule.c. */ - long num_threads; - /* Support for runtime thread stack size tuning. - A value of 0 means using the platform's default stack size - or the size specified by the THREAD_STACK_SIZE macro. */ - /* Used in Python/thread.c. */ - size_t pythread_stacksize; - PyObject *codec_search_path; PyObject *codec_search_cache; PyObject *codec_error_registry; @@ -298,6 +133,7 @@ struct _is { #ifdef HAVE_DLOPEN int dlopenflags; #endif + unsigned long feature_flags; PyObject *dict; /* Stores per-interpreter state */ @@ -306,6 +142,10 @@ struct _is { // Initialized to _PyEval_EvalFrameDefault(). _PyFrameEvalFunction eval_frame; + PyFunction_WatchCallback func_watchers[FUNC_MAX_WATCHERS]; + // One bit is set for each non-NULL entry in func_watchers + uint8_t active_func_watchers; + Py_ssize_t co_extra_user_count; freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS]; @@ -315,16 +155,18 @@ struct _is { PyObject *after_forkers_child; #endif - uint64_t tstate_next_unique_id; - struct _warnings_runtime_state warnings; struct atexit_state atexit; PyObject *audit_hooks; + PyType_WatchCallback type_watchers[TYPE_MAX_WATCHERS]; + PyCode_WatchCallback code_watchers[CODE_MAX_WATCHERS]; + // One bit is set for each non-NULL entry in code_watchers + uint8_t active_code_watchers; - struct _Py_bytes_state bytes; struct _Py_unicode_state unicode; struct _Py_float_state float_state; + struct _Py_long_state long_state; /* Using a cache is very effective since typically only a single slice is created and then deleted again. */ PySliceObject *slice_cache; @@ -332,15 +174,37 @@ struct _is { struct _Py_tuple_state tuple; struct _Py_list_state list; struct _Py_dict_state dict_state; - struct _Py_frame_state frame; struct _Py_async_gen_state async_gen; struct _Py_context_state context; struct _Py_exc_state exc_state; struct ast_state ast; - struct type_cache type_cache; + struct types_state types; + struct callable_cache callable_cache; + PyCodeObject *interpreter_trampoline; + + struct _Py_interp_cached_objects cached_objects; + struct _Py_interp_static_objects static_objects; + + /* The following fields are here to avoid allocation during init. + The data is exposed through PyInterpreterState pointer fields. + These fields should not be accessed directly outside of init. + + All other PyInterpreterState pointer fields are populated when + needed and default to NULL. + + For now there are some exceptions to that rule, which require + allocation during init. These will be addressed on a case-by-case + basis. Also see _PyRuntimeState regarding the various mutex fields. + */ + + /* the initial PyInterpreterState.threads.head */ + PyThreadState _initial_thread; }; + +/* other API */ + extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp); extern void _PyInterpreterState_Clear(PyThreadState *tstate); @@ -354,16 +218,17 @@ extern void _PyInterpreterState_Clear(PyThreadState *tstate); struct _xidregitem; struct _xidregitem { - PyTypeObject *cls; - crossinterpdatafunc getdata; + struct _xidregitem *prev; struct _xidregitem *next; + PyObject *cls; // weakref to a PyTypeObject + crossinterpdatafunc getdata; }; -PyAPI_FUNC(struct _is*) _PyInterpreterState_LookUpID(int64_t); +PyAPI_FUNC(PyInterpreterState*) _PyInterpreterState_LookUpID(int64_t); -PyAPI_FUNC(int) _PyInterpreterState_IDInitref(struct _is *); -PyAPI_FUNC(int) _PyInterpreterState_IDIncref(struct _is *); -PyAPI_FUNC(void) _PyInterpreterState_IDDecref(struct _is *); +PyAPI_FUNC(int) _PyInterpreterState_IDInitref(PyInterpreterState *); +PyAPI_FUNC(int) _PyInterpreterState_IDIncref(PyInterpreterState *); +PyAPI_FUNC(void) _PyInterpreterState_IDDecref(PyInterpreterState *); #ifdef __cplusplus } diff --git a/Include/internal/pycore_intrinsics.h b/Include/internal/pycore_intrinsics.h new file mode 100644 index 00000000000..1da618f2b4a --- /dev/null +++ b/Include/internal/pycore_intrinsics.h @@ -0,0 +1,13 @@ + +#define INTRINSIC_PRINT 1 +#define INTRINSIC_IMPORT_STAR 2 +#define INTRINSIC_STOPITERATION_ERROR 3 +#define INTRINSIC_ASYNC_GEN_WRAP 4 +#define INTRINSIC_UNARY_POSITIVE 5 +#define INTRINSIC_LIST_TO_TUPLE 6 + +#define MAX_INTRINSIC_1 6 + +typedef PyObject *(*instrinsic_func1)(PyThreadState* tstate, PyObject *value); + +extern instrinsic_func1 _PyIntrinsics_UnaryFunctions[]; diff --git a/Include/internal/pycore_list.h b/Include/internal/pycore_list.h index f18fb052c49..2fcbe12cd65 100644 --- a/Include/internal/pycore_list.h +++ b/Include/internal/pycore_list.h @@ -11,8 +11,71 @@ extern "C" { #include "listobject.h" // _PyList_CAST() -#define _PyList_ITEMS(op) (_PyList_CAST(op)->ob_item) +/* runtime lifecycle */ +extern void _PyList_Fini(PyInterpreterState *); + + +/* other API */ + +#ifndef WITH_FREELISTS +// without freelists +# define PyList_MAXFREELIST 0 +#endif + +/* Empty list reuse scheme to save calls to malloc and free */ +#ifndef PyList_MAXFREELIST +# define PyList_MAXFREELIST 80 +#endif + +struct _Py_list_state { +#if PyList_MAXFREELIST > 0 + PyListObject *free_list[PyList_MAXFREELIST]; + int numfree; +#endif +}; + +#define _PyList_ITEMS(op) _Py_RVALUE(_PyList_CAST(op)->ob_item) + +extern int +_PyList_AppendTakeRefListResize(PyListObject *self, PyObject *newitem); + +static inline int +_PyList_AppendTakeRef(PyListObject *self, PyObject *newitem) +{ + assert(self != NULL && newitem != NULL); + assert(PyList_Check(self)); + Py_ssize_t len = PyList_GET_SIZE(self); + Py_ssize_t allocated = self->allocated; + assert((size_t)len + 1 < PY_SSIZE_T_MAX); + if (allocated > len) { + PyList_SET_ITEM(self, len, newitem); + Py_SET_SIZE(self, len + 1); + return 0; + } + return _PyList_AppendTakeRefListResize(self, newitem); +} + +// Repeat the bytes of a buffer in place +static inline void +_Py_memory_repeat(char* dest, Py_ssize_t len_dest, Py_ssize_t len_src) +{ + assert(len_src > 0); + Py_ssize_t copied = len_src; + while (copied < len_dest) { + Py_ssize_t bytes_to_copy = Py_MIN(copied, len_dest - copied); + memcpy(dest + copied, dest, bytes_to_copy); + copied += bytes_to_copy; + } +} + +typedef struct { + PyObject_HEAD + Py_ssize_t it_index; + PyListObject *it_seq; /* Set to NULL when iterator is exhausted */ +} _PyListIterObject; + +extern PyObject *_PyList_FromArraySteal(PyObject *const *src, Py_ssize_t n); #ifdef __cplusplus } diff --git a/Include/internal/pycore_long.h b/Include/internal/pycore_long.h index b9f926996d8..8c1d017bb95 100644 --- a/Include/internal/pycore_long.h +++ b/Include/internal/pycore_long.h @@ -8,23 +8,82 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_interp.h" // PyInterpreterState.small_ints -#include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_global_objects.h" // _PY_NSMALLNEGINTS +#include "pycore_runtime.h" // _PyRuntime + +/* + * Default int base conversion size limitation: Denial of Service prevention. + * + * Chosen such that this isn't wildly slow on modern hardware and so that + * everyone's existing deployed numpy test suite passes before + * https://github.com/numpy/numpy/issues/22098 is widely available. + * + * $ python -m timeit -s 's = "1"*4300' 'int(s)' + * 2000 loops, best of 5: 125 usec per loop + * $ python -m timeit -s 's = "1"*4300; v = int(s)' 'str(v)' + * 1000 loops, best of 5: 311 usec per loop + * (zen2 cloud VM) + * + * 4300 decimal digits fits a ~14284 bit number. + */ +#define _PY_LONG_DEFAULT_MAX_STR_DIGITS 4300 +/* + * Threshold for max digits check. For performance reasons int() and + * int.__str__() don't checks values that are smaller than this + * threshold. Acts as a guaranteed minimum size limit for bignums that + * applications can expect from CPython. + * + * % python -m timeit -s 's = "1"*640; v = int(s)' 'str(int(s))' + * 20000 loops, best of 5: 12 usec per loop + * + * "640 digits should be enough for anyone." - gps + * fits a ~2126 bit decimal number. + */ +#define _PY_LONG_MAX_STR_DIGITS_THRESHOLD 640 + +#if ((_PY_LONG_DEFAULT_MAX_STR_DIGITS != 0) && \ + (_PY_LONG_DEFAULT_MAX_STR_DIGITS < _PY_LONG_MAX_STR_DIGITS_THRESHOLD)) +# error "_PY_LONG_DEFAULT_MAX_STR_DIGITS smaller than threshold." +#endif + + +/* runtime lifecycle */ + +extern PyStatus _PyLong_InitTypes(PyInterpreterState *); +extern void _PyLong_FiniTypes(PyInterpreterState *interp); + + +/* other API */ + +#define _PyLong_SMALL_INTS _Py_SINGLETON(small_ints) + +// _PyLong_GetZero() and _PyLong_GetOne() must always be available +// _PyLong_FromUnsignedChar must always be available +#if _PY_NSMALLPOSINTS < 257 +# error "_PY_NSMALLPOSINTS must be greater than or equal to 257" +#endif // Return a borrowed reference to the zero singleton. // The function cannot return NULL. static inline PyObject* _PyLong_GetZero(void) -{ return (PyObject *)&_PyRuntime.small_ints[_PY_NSMALLNEGINTS]; } +{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS]; } // Return a borrowed reference to the one singleton. // The function cannot return NULL. static inline PyObject* _PyLong_GetOne(void) -{ return (PyObject *)&_PyRuntime.small_ints[_PY_NSMALLNEGINTS+1]; } +{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+1]; } + +static inline PyObject* _PyLong_FromUnsignedChar(unsigned char i) +{ + return Py_NewRef((PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i]); +} PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right); PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right); PyObject *_PyLong_Subtract(PyLongObject *left, PyLongObject *right); +int _PyLong_AssignValue(PyObject **target, Py_ssize_t value); + /* Used by Python/mystrtoul.c, _PyBytes_FromHex(), _PyBytes_DecodeEscape(), etc. */ PyAPI_DATA(unsigned char) _PyLong_DigitValue[256]; @@ -51,6 +110,25 @@ PyAPI_FUNC(char*) _PyLong_FormatBytesWriter( int base, int alternate); +/* Return 1 if the argument is positive single digit int */ +static inline int +_PyLong_IsPositiveSingleDigit(PyObject* sub) { + /* For a positive single digit int, the value of Py_SIZE(sub) is 0 or 1. + + We perform a fast check using a single comparison by casting from int + to uint which casts negative numbers to large positive numbers. + For details see Section 14.2 "Bounds Checking" in the Agner Fog + optimization manual found at: + https://www.agner.org/optimize/optimizing_cpp.pdf + + The function is not affected by -fwrapv, -fno-wrapv and -ftrapv + compiler options of GCC and clang + */ + assert(PyLong_CheckExact(sub)); + Py_ssize_t signed_size = Py_SIZE(sub); + return ((size_t)signed_size) <= 1; +} + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_moduleobject.h b/Include/internal/pycore_moduleobject.h index e9978abd25b..76361b8dff1 100644 --- a/Include/internal/pycore_moduleobject.h +++ b/Include/internal/pycore_moduleobject.h @@ -11,7 +11,7 @@ extern "C" { typedef struct { PyObject_HEAD PyObject *md_dict; - struct PyModuleDef *md_def; + PyModuleDef *md_def; void *md_state; PyObject *md_weaklist; // for logging purposes after md_dict is cleared diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 3c126aaef11..8796dfe2f6b 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -8,9 +8,77 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() #include "pycore_interp.h" // PyInterpreterState.gc #include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_runtime.h" // _PyRuntime + +/* This value provides *effective* immortality, meaning the object should never + be deallocated (until runtime finalization). See PEP 683 for more details about + immortality, as well as a proposed mechanism for proper immortality. */ +#define _PyObject_IMMORTAL_REFCNT 999999999 + +#define _PyObject_IMMORTAL_INIT(type) \ + { \ + .ob_refcnt = _PyObject_IMMORTAL_REFCNT, \ + .ob_type = (type), \ + } +#define _PyVarObject_IMMORTAL_INIT(type, size) \ + { \ + .ob_base = _PyObject_IMMORTAL_INIT(type), \ + .ob_size = size, \ + } + +PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalRefcountErrorFunc( + const char *func, + const char *message); + +#define _Py_FatalRefcountError(message) \ + _Py_FatalRefcountErrorFunc(__func__, (message)) + +// Increment reference count by n +static inline void _Py_RefcntAdd(PyObject* op, Py_ssize_t n) +{ +#ifdef Py_REF_DEBUG + _Py_RefTotal += n; +#endif + op->ob_refcnt += n; +} +#define _Py_RefcntAdd(op, n) _Py_RefcntAdd(_PyObject_CAST(op), n) + +static inline void +_Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct) +{ + _Py_DECREF_STAT_INC(); +#ifdef Py_REF_DEBUG + _Py_RefTotal--; +#endif + if (--op->ob_refcnt != 0) { + assert(op->ob_refcnt > 0); + } + else { +#ifdef Py_TRACE_REFS + _Py_ForgetReference(op); +#endif + destruct(op); + } +} + +static inline void +_Py_DECREF_NO_DEALLOC(PyObject *op) +{ + _Py_DECREF_STAT_INC(); +#ifdef Py_REF_DEBUG + _Py_RefTotal--; +#endif + op->ob_refcnt--; +#ifdef Py_DEBUG + if (op->ob_refcnt <= 0) { + _Py_FatalRefcountError("Expected a positive remaining refcount"); + } +#endif +} PyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type); PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content); @@ -149,13 +217,52 @@ extern void _Py_PrintReferences(FILE *); extern void _Py_PrintReferenceAddresses(FILE *); #endif + +/* Return the *address* of the object's weaklist. The address may be + * dereferenced to get the current head of the weaklist. This is useful + * for iterating over the linked list of weakrefs, especially when the + * list is being modified externally (e.g. refs getting removed). + * + * The returned pointer should not be used to change the head of the list + * nor should it be used to add, remove, or swap any refs in the list. + * That is the sole responsibility of the code in weakrefobject.c. + */ static inline PyObject ** _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op) { + if (PyType_Check(op) && + ((PyTypeObject *)op)->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + static_builtin_state *state = _PyStaticType_GetState( + (PyTypeObject *)op); + return _PyStaticType_GET_WEAKREFS_LISTPTR(state); + } + // Essentially _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(): Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset; return (PyObject **)((char *)op + offset); } +/* This is a special case of _PyObject_GET_WEAKREFS_LISTPTR(). + * Only the most fundamental lookup path is used. + * Consequently, static types should not be used. + * + * For static builtin types the returned pointer will always point + * to a NULL tp_weaklist. This is fine for any deallocation cases, + * since static types are never deallocated and static builtin types + * are only finalized at the end of runtime finalization. + * + * If the weaklist for static types is actually needed then use + * _PyObject_GET_WEAKREFS_LISTPTR(). + */ +static inline PyWeakReference ** +_PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(PyObject *op) +{ + assert(!PyType_Check(op) || + ((PyTypeObject *)op)->tp_flags & Py_TPFLAGS_HEAPTYPE); + Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset; + return (PyWeakReference **)((char *)op + offset); +} + + // Fast inlined version of PyObject_IS_GC() static inline int _PyObject_IS_GC(PyObject *obj) @@ -168,6 +275,15 @@ _PyObject_IS_GC(PyObject *obj) // Fast inlined version of PyType_IS_GC() #define _PyType_IS_GC(t) _PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC) +static inline size_t +_PyType_PreHeaderSize(PyTypeObject *tp) +{ + return _PyType_IS_GC(tp) * sizeof(PyGC_Head) + + _PyType_HasFeature(tp, Py_TPFLAGS_PREHEADER) * 2 * sizeof(PyObject *); +} + +void _PyObject_GC_Link(PyObject *op); + // Usage: assert(_Py_CheckSlotResult(obj, "__getitem__", result != NULL)); extern int _Py_CheckSlotResult( PyObject *obj, @@ -178,6 +294,11 @@ extern int _Py_CheckSlotResult( // See also the Py_TPFLAGS_READY flag. #define _PyType_IsReady(type) ((type)->tp_dict != NULL) +// Test if a type supports weak references +static inline int _PyType_SUPPORTS_WEAKREFS(PyTypeObject *type) { + return (type->tp_weaklistoffset != 0); +} + extern PyObject* _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems); extern int _PyObject_InitializeDict(PyObject *obj); @@ -185,12 +306,87 @@ extern int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject *name, PyObject *value); PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject *name); -PyDictValues ** _PyObject_ValuesPointer(PyObject *); -PyObject ** _PyObject_DictPointer(PyObject *); -int _PyObject_VisitInstanceAttributes(PyObject *self, visitproc visit, void *arg); -void _PyObject_ClearInstanceAttributes(PyObject *self); -void _PyObject_FreeInstanceAttributes(PyObject *self); -int _PyObject_IsInstanceDictEmpty(PyObject *); + +typedef union { + PyObject *dict; + /* Use a char* to generate a warning if directly assigning a PyDictValues */ + char *values; +} PyDictOrValues; + +static inline PyDictOrValues * +_PyObject_DictOrValuesPointer(PyObject *obj) +{ + assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + return ((PyDictOrValues *)obj)-3; +} + +static inline int +_PyDictOrValues_IsValues(PyDictOrValues dorv) +{ + return ((uintptr_t)dorv.values) & 1; +} + +static inline PyDictValues * +_PyDictOrValues_GetValues(PyDictOrValues dorv) +{ + assert(_PyDictOrValues_IsValues(dorv)); + return (PyDictValues *)(dorv.values + 1); +} + +static inline PyObject * +_PyDictOrValues_GetDict(PyDictOrValues dorv) +{ + assert(!_PyDictOrValues_IsValues(dorv)); + return dorv.dict; +} + +static inline void +_PyDictOrValues_SetValues(PyDictOrValues *ptr, PyDictValues *values) +{ + ptr->values = ((char *)values) - 1; +} + +#define MANAGED_WEAKREF_OFFSET (((Py_ssize_t)sizeof(PyObject *))*-4) + +extern PyObject ** _PyObject_ComputedDictPointer(PyObject *); +extern void _PyObject_FreeInstanceAttributes(PyObject *obj); +extern int _PyObject_IsInstanceDictEmpty(PyObject *); +extern int _PyType_HasSubclasses(PyTypeObject *); +extern PyObject* _PyType_GetSubclasses(PyTypeObject *); + +// Access macro to the members which are floating "behind" the object +static inline PyMemberDef* _PyHeapType_GET_MEMBERS(PyHeapTypeObject *etype) { + return (PyMemberDef*)((char*)etype + Py_TYPE(etype)->tp_basicsize); +} + +PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, PyObject *); + +/* C function call trampolines to mitigate bad function pointer casts. + * + * Typical native ABIs ignore additional arguments or fill in missing + * values with 0/NULL in function pointer cast. Compilers do not show + * warnings when a function pointer is explicitly casted to an + * incompatible type. + * + * Bad fpcasts are an issue in WebAssembly. WASM's indirect_call has strict + * function signature checks. Argument count, types, and return type must + * match. + * + * Third party code unintentionally rely on problematic fpcasts. The call + * trampoline mitigates common occurrences of bad fpcasts on Emscripten. + */ +#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) +#define _PyCFunction_TrampolineCall(meth, self, args) \ + _PyCFunctionWithKeywords_TrampolineCall( \ + (*(PyCFunctionWithKeywords)(void(*)(void))(meth)), (self), (args), NULL) +extern PyObject* _PyCFunctionWithKeywords_TrampolineCall( + PyCFunctionWithKeywords meth, PyObject *, PyObject *, PyObject *); +#else +#define _PyCFunction_TrampolineCall(meth, self, args) \ + (meth)((self), (args)) +#define _PyCFunctionWithKeywords_TrampolineCall(meth, self, args, kw) \ + (meth)((self), (args), (kw)) +#endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE #ifdef __cplusplus } diff --git a/Include/internal/pycore_obmalloc.h b/Include/internal/pycore_obmalloc.h new file mode 100644 index 00000000000..a5c7f4528f9 --- /dev/null +++ b/Include/internal/pycore_obmalloc.h @@ -0,0 +1,690 @@ +#ifndef Py_INTERNAL_OBMALLOC_H +#define Py_INTERNAL_OBMALLOC_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +typedef unsigned int pymem_uint; /* assuming >= 16 bits */ + +#undef uint +#define uint pymem_uint + + +/* An object allocator for Python. + + Here is an introduction to the layers of the Python memory architecture, + showing where the object allocator is actually used (layer +2), It is + called for every object allocation and deallocation (PyObject_New/Del), + unless the object-specific allocators implement a proprietary allocation + scheme (ex.: ints use a simple free list). This is also the place where + the cyclic garbage collector operates selectively on container objects. + + + Object-specific allocators + _____ ______ ______ ________ + [ int ] [ dict ] [ list ] ... [ string ] Python core | ++3 | <----- Object-specific memory -----> | <-- Non-object memory --> | + _______________________________ | | + [ Python's object allocator ] | | ++2 | ####### Object memory ####### | <------ Internal buffers ------> | + ______________________________________________________________ | + [ Python's raw memory allocator (PyMem_ API) ] | ++1 | <----- Python memory (under PyMem manager's control) ------> | | + __________________________________________________________________ + [ Underlying general-purpose allocator (ex: C library malloc) ] + 0 | <------ Virtual memory allocated for the python process -------> | + + ========================================================================= + _______________________________________________________________________ + [ OS-specific Virtual Memory Manager (VMM) ] +-1 | <--- Kernel dynamic storage allocation & management (page-based) ---> | + __________________________________ __________________________________ + [ ] [ ] +-2 | <-- Physical memory: ROM/RAM --> | | <-- Secondary storage (swap) --> | + +*/ +/*==========================================================================*/ + +/* A fast, special-purpose memory allocator for small blocks, to be used + on top of a general-purpose malloc -- heavily based on previous art. */ + +/* Vladimir Marangozov -- August 2000 */ + +/* + * "Memory management is where the rubber meets the road -- if we do the wrong + * thing at any level, the results will not be good. And if we don't make the + * levels work well together, we are in serious trouble." (1) + * + * (1) Paul R. Wilson, Mark S. Johnstone, Michael Neely, and David Boles, + * "Dynamic Storage Allocation: A Survey and Critical Review", + * in Proc. 1995 Int'l. Workshop on Memory Management, September 1995. + */ + +/* #undef WITH_MEMORY_LIMITS */ /* disable mem limit checks */ + +/*==========================================================================*/ + +/* + * Allocation strategy abstract: + * + * For small requests, the allocator sub-allocates blocks of memory. + * Requests greater than SMALL_REQUEST_THRESHOLD bytes are routed to the + * system's allocator. + * + * Small requests are grouped in size classes spaced 8 bytes apart, due + * to the required valid alignment of the returned address. Requests of + * a particular size are serviced from memory pools of 4K (one VMM page). + * Pools are fragmented on demand and contain free lists of blocks of one + * particular size class. In other words, there is a fixed-size allocator + * for each size class. Free pools are shared by the different allocators + * thus minimizing the space reserved for a particular size class. + * + * This allocation strategy is a variant of what is known as "simple + * segregated storage based on array of free lists". The main drawback of + * simple segregated storage is that we might end up with lot of reserved + * memory for the different free lists, which degenerate in time. To avoid + * this, we partition each free list in pools and we share dynamically the + * reserved space between all free lists. This technique is quite efficient + * for memory intensive programs which allocate mainly small-sized blocks. + * + * For small requests we have the following table: + * + * Request in bytes Size of allocated block Size class idx + * ---------------------------------------------------------------- + * 1-8 8 0 + * 9-16 16 1 + * 17-24 24 2 + * 25-32 32 3 + * 33-40 40 4 + * 41-48 48 5 + * 49-56 56 6 + * 57-64 64 7 + * 65-72 72 8 + * ... ... ... + * 497-504 504 62 + * 505-512 512 63 + * + * 0, SMALL_REQUEST_THRESHOLD + 1 and up: routed to the underlying + * allocator. + */ + +/*==========================================================================*/ + +/* + * -- Main tunable settings section -- + */ + +/* + * Alignment of addresses returned to the user. 8-bytes alignment works + * on most current architectures (with 32-bit or 64-bit address buses). + * The alignment value is also used for grouping small requests in size + * classes spaced ALIGNMENT bytes apart. + * + * You shouldn't change this unless you know what you are doing. + */ + +#if SIZEOF_VOID_P > 4 +#define ALIGNMENT 16 /* must be 2^N */ +#define ALIGNMENT_SHIFT 4 +#else +#define ALIGNMENT 8 /* must be 2^N */ +#define ALIGNMENT_SHIFT 3 +#endif + +/* Return the number of bytes in size class I, as a uint. */ +#define INDEX2SIZE(I) (((pymem_uint)(I) + 1) << ALIGNMENT_SHIFT) + +/* + * Max size threshold below which malloc requests are considered to be + * small enough in order to use preallocated memory pools. You can tune + * this value according to your application behaviour and memory needs. + * + * Note: a size threshold of 512 guarantees that newly created dictionaries + * will be allocated from preallocated memory pools on 64-bit. + * + * The following invariants must hold: + * 1) ALIGNMENT <= SMALL_REQUEST_THRESHOLD <= 512 + * 2) SMALL_REQUEST_THRESHOLD is evenly divisible by ALIGNMENT + * + * Although not required, for better performance and space efficiency, + * it is recommended that SMALL_REQUEST_THRESHOLD is set to a power of 2. + */ +#define SMALL_REQUEST_THRESHOLD 512 +#define NB_SMALL_SIZE_CLASSES (SMALL_REQUEST_THRESHOLD / ALIGNMENT) + +/* + * The system's VMM page size can be obtained on most unices with a + * getpagesize() call or deduced from various header files. To make + * things simpler, we assume that it is 4K, which is OK for most systems. + * It is probably better if this is the native page size, but it doesn't + * have to be. In theory, if SYSTEM_PAGE_SIZE is larger than the native page + * size, then `POOL_ADDR(p)->arenaindex' could rarely cause a segmentation + * violation fault. 4K is apparently OK for all the platforms that python + * currently targets. + */ +#define SYSTEM_PAGE_SIZE (4 * 1024) + +/* + * Maximum amount of memory managed by the allocator for small requests. + */ +#ifdef WITH_MEMORY_LIMITS +#ifndef SMALL_MEMORY_LIMIT +#define SMALL_MEMORY_LIMIT (64 * 1024 * 1024) /* 64 MB -- more? */ +#endif +#endif + +#if !defined(WITH_PYMALLOC_RADIX_TREE) +/* Use radix-tree to track arena memory regions, for address_in_range(). + * Enable by default since it allows larger pool sizes. Can be disabled + * using -DWITH_PYMALLOC_RADIX_TREE=0 */ +#define WITH_PYMALLOC_RADIX_TREE 1 +#endif + +#if SIZEOF_VOID_P > 4 +/* on 64-bit platforms use larger pools and arenas if we can */ +#define USE_LARGE_ARENAS +#if WITH_PYMALLOC_RADIX_TREE +/* large pools only supported if radix-tree is enabled */ +#define USE_LARGE_POOLS +#endif +#endif + +/* + * The allocator sub-allocates blocks of memory (called arenas) aligned + * on a page boundary. This is a reserved virtual address space for the + * current process (obtained through a malloc()/mmap() call). In no way this + * means that the memory arenas will be used entirely. A malloc() is + * usually an address range reservation for bytes, unless all pages within + * this space are referenced subsequently. So malloc'ing big blocks and not + * using them does not mean "wasting memory". It's an addressable range + * wastage... + * + * Arenas are allocated with mmap() on systems supporting anonymous memory + * mappings to reduce heap fragmentation. + */ +#ifdef USE_LARGE_ARENAS +#define ARENA_BITS 20 /* 1 MiB */ +#else +#define ARENA_BITS 18 /* 256 KiB */ +#endif +#define ARENA_SIZE (1 << ARENA_BITS) +#define ARENA_SIZE_MASK (ARENA_SIZE - 1) + +#ifdef WITH_MEMORY_LIMITS +#define MAX_ARENAS (SMALL_MEMORY_LIMIT / ARENA_SIZE) +#endif + +/* + * Size of the pools used for small blocks. Must be a power of 2. + */ +#ifdef USE_LARGE_POOLS +#define POOL_BITS 14 /* 16 KiB */ +#else +#define POOL_BITS 12 /* 4 KiB */ +#endif +#define POOL_SIZE (1 << POOL_BITS) +#define POOL_SIZE_MASK (POOL_SIZE - 1) + +#if !WITH_PYMALLOC_RADIX_TREE +#if POOL_SIZE != SYSTEM_PAGE_SIZE +# error "pool size must be equal to system page size" +#endif +#endif + +#define MAX_POOLS_IN_ARENA (ARENA_SIZE / POOL_SIZE) +#if MAX_POOLS_IN_ARENA * POOL_SIZE != ARENA_SIZE +# error "arena size not an exact multiple of pool size" +#endif + +/* + * -- End of tunable settings section -- + */ + +/*==========================================================================*/ + +/* When you say memory, my mind reasons in terms of (pointers to) blocks */ +typedef uint8_t pymem_block; + +/* Pool for small blocks. */ +struct pool_header { + union { pymem_block *_padding; + uint count; } ref; /* number of allocated blocks */ + pymem_block *freeblock; /* pool's free list head */ + struct pool_header *nextpool; /* next pool of this size class */ + struct pool_header *prevpool; /* previous pool "" */ + uint arenaindex; /* index into arenas of base adr */ + uint szidx; /* block size class index */ + uint nextoffset; /* bytes to virgin block */ + uint maxnextoffset; /* largest valid nextoffset */ +}; + +typedef struct pool_header *poolp; + +/* Record keeping for arenas. */ +struct arena_object { + /* The address of the arena, as returned by malloc. Note that 0 + * will never be returned by a successful malloc, and is used + * here to mark an arena_object that doesn't correspond to an + * allocated arena. + */ + uintptr_t address; + + /* Pool-aligned pointer to the next pool to be carved off. */ + pymem_block* pool_address; + + /* The number of available pools in the arena: free pools + never- + * allocated pools. + */ + uint nfreepools; + + /* The total number of pools in the arena, whether or not available. */ + uint ntotalpools; + + /* Singly-linked list of available pools. */ + struct pool_header* freepools; + + /* Whenever this arena_object is not associated with an allocated + * arena, the nextarena member is used to link all unassociated + * arena_objects in the singly-linked `unused_arena_objects` list. + * The prevarena member is unused in this case. + * + * When this arena_object is associated with an allocated arena + * with at least one available pool, both members are used in the + * doubly-linked `usable_arenas` list, which is maintained in + * increasing order of `nfreepools` values. + * + * Else this arena_object is associated with an allocated arena + * all of whose pools are in use. `nextarena` and `prevarena` + * are both meaningless in this case. + */ + struct arena_object* nextarena; + struct arena_object* prevarena; +}; + +#define POOL_OVERHEAD _Py_SIZE_ROUND_UP(sizeof(struct pool_header), ALIGNMENT) + +#define DUMMY_SIZE_IDX 0xffff /* size class of newly cached pools */ + +/* Round pointer P down to the closest pool-aligned address <= P, as a poolp */ +#define POOL_ADDR(P) ((poolp)_Py_ALIGN_DOWN((P), POOL_SIZE)) + +/* Return total number of blocks in pool of size index I, as a uint. */ +#define NUMBLOCKS(I) ((pymem_uint)(POOL_SIZE - POOL_OVERHEAD) / INDEX2SIZE(I)) + +/*==========================================================================*/ + +/* + * Pool table -- headed, circular, doubly-linked lists of partially used pools. + +This is involved. For an index i, usedpools[i+i] is the header for a list of +all partially used pools holding small blocks with "size class idx" i. So +usedpools[0] corresponds to blocks of size 8, usedpools[2] to blocks of size +16, and so on: index 2*i <-> blocks of size (i+1)<freeblock points to +the start of a singly-linked list of free blocks within the pool. When a +block is freed, it's inserted at the front of its pool's freeblock list. Note +that the available blocks in a pool are *not* linked all together when a pool +is initialized. Instead only "the first two" (lowest addresses) blocks are +set up, returning the first such block, and setting pool->freeblock to a +one-block list holding the second such block. This is consistent with that +pymalloc strives at all levels (arena, pool, and block) never to touch a piece +of memory until it's actually needed. + +So long as a pool is in the used state, we're certain there *is* a block +available for allocating, and pool->freeblock is not NULL. If pool->freeblock +points to the end of the free list before we've carved the entire pool into +blocks, that means we simply haven't yet gotten to one of the higher-address +blocks. The offset from the pool_header to the start of "the next" virgin +block is stored in the pool_header nextoffset member, and the largest value +of nextoffset that makes sense is stored in the maxnextoffset member when a +pool is initialized. All the blocks in a pool have been passed out at least +once when and only when nextoffset > maxnextoffset. + + +Major obscurity: While the usedpools vector is declared to have poolp +entries, it doesn't really. It really contains two pointers per (conceptual) +poolp entry, the nextpool and prevpool members of a pool_header. The +excruciating initialization code below fools C so that + + usedpool[i+i] + +"acts like" a genuine poolp, but only so long as you only reference its +nextpool and prevpool members. The "- 2*sizeof(pymem_block *)" gibberish is +compensating for that a pool_header's nextpool and prevpool members +immediately follow a pool_header's first two members: + + union { pymem_block *_padding; + uint count; } ref; + pymem_block *freeblock; + +each of which consume sizeof(pymem_block *) bytes. So what usedpools[i+i] really +contains is a fudged-up pointer p such that *if* C believes it's a poolp +pointer, then p->nextpool and p->prevpool are both p (meaning that the headed +circular list is empty). + +It's unclear why the usedpools setup is so convoluted. It could be to +minimize the amount of cache required to hold this heavily-referenced table +(which only *needs* the two interpool pointer members of a pool_header). OTOH, +referencing code has to remember to "double the index" and doing so isn't +free, usedpools[0] isn't a strictly legal pointer, and we're crucially relying +on that C doesn't insert any padding anywhere in a pool_header at or before +the prevpool member. +**************************************************************************** */ + +#define OBMALLOC_USED_POOLS_SIZE (2 * ((NB_SMALL_SIZE_CLASSES + 7) / 8) * 8) + +struct _obmalloc_pools { + poolp used[OBMALLOC_USED_POOLS_SIZE]; +}; + + +/*========================================================================== +Arena management. + +`arenas` is a vector of arena_objects. It contains maxarenas entries, some of +which may not be currently used (== they're arena_objects that aren't +currently associated with an allocated arena). Note that arenas proper are +separately malloc'ed. + +Prior to Python 2.5, arenas were never free()'ed. Starting with Python 2.5, +we do try to free() arenas, and use some mild heuristic strategies to increase +the likelihood that arenas eventually can be freed. + +unused_arena_objects + + This is a singly-linked list of the arena_objects that are currently not + being used (no arena is associated with them). Objects are taken off the + head of the list in new_arena(), and are pushed on the head of the list in + PyObject_Free() when the arena is empty. Key invariant: an arena_object + is on this list if and only if its .address member is 0. + +usable_arenas + + This is a doubly-linked list of the arena_objects associated with arenas + that have pools available. These pools are either waiting to be reused, + or have not been used before. The list is sorted to have the most- + allocated arenas first (ascending order based on the nfreepools member). + This means that the next allocation will come from a heavily used arena, + which gives the nearly empty arenas a chance to be returned to the system. + In my unscientific tests this dramatically improved the number of arenas + that could be freed. + +Note that an arena_object associated with an arena all of whose pools are +currently in use isn't on either list. + +Changed in Python 3.8: keeping usable_arenas sorted by number of free pools +used to be done by one-at-a-time linear search when an arena's number of +free pools changed. That could, overall, consume time quadratic in the +number of arenas. That didn't really matter when there were only a few +hundred arenas (typical!), but could be a timing disaster when there were +hundreds of thousands. See bpo-37029. + +Now we have a vector of "search fingers" to eliminate the need to search: +nfp2lasta[nfp] returns the last ("rightmost") arena in usable_arenas +with nfp free pools. This is NULL if and only if there is no arena with +nfp free pools in usable_arenas. +*/ + +/* How many arena_objects do we initially allocate? + * 16 = can allocate 16 arenas = 16 * ARENA_SIZE = 4MB before growing the + * `arenas` vector. + */ +#define INITIAL_ARENA_OBJECTS 16 + +struct _obmalloc_mgmt { + /* Array of objects used to track chunks of memory (arenas). */ + struct arena_object* arenas; + /* Number of slots currently allocated in the `arenas` vector. */ + uint maxarenas; + + /* The head of the singly-linked, NULL-terminated list of available + * arena_objects. + */ + struct arena_object* unused_arena_objects; + + /* The head of the doubly-linked, NULL-terminated at each end, list of + * arena_objects associated with arenas that have pools available. + */ + struct arena_object* usable_arenas; + + /* nfp2lasta[nfp] is the last arena in usable_arenas with nfp free pools */ + struct arena_object* nfp2lasta[MAX_POOLS_IN_ARENA + 1]; + + /* Number of arenas allocated that haven't been free()'d. */ + size_t narenas_currently_allocated; + + /* Total number of times malloc() called to allocate an arena. */ + size_t ntimes_arena_allocated; + /* High water mark (max value ever seen) for narenas_currently_allocated. */ + size_t narenas_highwater; + + Py_ssize_t raw_allocated_blocks; +}; + + +#if WITH_PYMALLOC_RADIX_TREE +/*==========================================================================*/ +/* radix tree for tracking arena usage. If enabled, used to implement + address_in_range(). + + memory address bit allocation for keys + + 64-bit pointers, IGNORE_BITS=0 and 2^20 arena size: + 15 -> MAP_TOP_BITS + 15 -> MAP_MID_BITS + 14 -> MAP_BOT_BITS + 20 -> ideal aligned arena + ---- + 64 + + 64-bit pointers, IGNORE_BITS=16, and 2^20 arena size: + 16 -> IGNORE_BITS + 10 -> MAP_TOP_BITS + 10 -> MAP_MID_BITS + 8 -> MAP_BOT_BITS + 20 -> ideal aligned arena + ---- + 64 + + 32-bit pointers and 2^18 arena size: + 14 -> MAP_BOT_BITS + 18 -> ideal aligned arena + ---- + 32 + +*/ + +#if SIZEOF_VOID_P == 8 + +/* number of bits in a pointer */ +#define POINTER_BITS 64 + +/* High bits of memory addresses that will be ignored when indexing into the + * radix tree. Setting this to zero is the safe default. For most 64-bit + * machines, setting this to 16 would be safe. The kernel would not give + * user-space virtual memory addresses that have significant information in + * those high bits. The main advantage to setting IGNORE_BITS > 0 is that less + * virtual memory will be used for the top and middle radix tree arrays. Those + * arrays are allocated in the BSS segment and so will typically consume real + * memory only if actually accessed. + */ +#define IGNORE_BITS 0 + +/* use the top and mid layers of the radix tree */ +#define USE_INTERIOR_NODES + +#elif SIZEOF_VOID_P == 4 + +#define POINTER_BITS 32 +#define IGNORE_BITS 0 + +#else + + /* Currently this code works for 64-bit or 32-bit pointers only. */ +#error "obmalloc radix tree requires 64-bit or 32-bit pointers." + +#endif /* SIZEOF_VOID_P */ + +/* arena_coverage_t members require this to be true */ +#if ARENA_BITS >= 32 +# error "arena size must be < 2^32" +#endif + +/* the lower bits of the address that are not ignored */ +#define ADDRESS_BITS (POINTER_BITS - IGNORE_BITS) + +#ifdef USE_INTERIOR_NODES +/* number of bits used for MAP_TOP and MAP_MID nodes */ +#define INTERIOR_BITS ((ADDRESS_BITS - ARENA_BITS + 2) / 3) +#else +#define INTERIOR_BITS 0 +#endif + +#define MAP_TOP_BITS INTERIOR_BITS +#define MAP_TOP_LENGTH (1 << MAP_TOP_BITS) +#define MAP_TOP_MASK (MAP_TOP_LENGTH - 1) + +#define MAP_MID_BITS INTERIOR_BITS +#define MAP_MID_LENGTH (1 << MAP_MID_BITS) +#define MAP_MID_MASK (MAP_MID_LENGTH - 1) + +#define MAP_BOT_BITS (ADDRESS_BITS - ARENA_BITS - 2*INTERIOR_BITS) +#define MAP_BOT_LENGTH (1 << MAP_BOT_BITS) +#define MAP_BOT_MASK (MAP_BOT_LENGTH - 1) + +#define MAP_BOT_SHIFT ARENA_BITS +#define MAP_MID_SHIFT (MAP_BOT_BITS + MAP_BOT_SHIFT) +#define MAP_TOP_SHIFT (MAP_MID_BITS + MAP_MID_SHIFT) + +#define AS_UINT(p) ((uintptr_t)(p)) +#define MAP_BOT_INDEX(p) ((AS_UINT(p) >> MAP_BOT_SHIFT) & MAP_BOT_MASK) +#define MAP_MID_INDEX(p) ((AS_UINT(p) >> MAP_MID_SHIFT) & MAP_MID_MASK) +#define MAP_TOP_INDEX(p) ((AS_UINT(p) >> MAP_TOP_SHIFT) & MAP_TOP_MASK) + +#if IGNORE_BITS > 0 +/* Return the ignored part of the pointer address. Those bits should be same + * for all valid pointers if IGNORE_BITS is set correctly. + */ +#define HIGH_BITS(p) (AS_UINT(p) >> ADDRESS_BITS) +#else +#define HIGH_BITS(p) 0 +#endif + + +/* This is the leaf of the radix tree. See arena_map_mark_used() for the + * meaning of these members. */ +typedef struct { + int32_t tail_hi; + int32_t tail_lo; +} arena_coverage_t; + +typedef struct arena_map_bot { + /* The members tail_hi and tail_lo are accessed together. So, it + * better to have them as an array of structs, rather than two + * arrays. + */ + arena_coverage_t arenas[MAP_BOT_LENGTH]; +} arena_map_bot_t; + +#ifdef USE_INTERIOR_NODES +typedef struct arena_map_mid { + struct arena_map_bot *ptrs[MAP_MID_LENGTH]; +} arena_map_mid_t; + +typedef struct arena_map_top { + struct arena_map_mid *ptrs[MAP_TOP_LENGTH]; +} arena_map_top_t; +#endif + +struct _obmalloc_usage { + /* The root of radix tree. Note that by initializing like this, the memory + * should be in the BSS. The OS will only memory map pages as the MAP_MID + * nodes get used (OS pages are demand loaded as needed). + */ +#ifdef USE_INTERIOR_NODES + arena_map_top_t arena_map_root; + /* accounting for number of used interior nodes */ + int arena_map_mid_count; + int arena_map_bot_count; +#else + arena_map_bot_t arena_map_root; +#endif +}; + +#endif /* WITH_PYMALLOC_RADIX_TREE */ + + +struct _obmalloc_state { + int dump_debug_stats; + struct _obmalloc_pools pools; + struct _obmalloc_mgmt mgmt; + struct _obmalloc_usage usage; +}; + + +#undef uint + + +/* Allocate memory directly from the O/S virtual memory system, + * where supported. Otherwise fallback on malloc */ +void *_PyObject_VirtualAlloc(size_t size); +void _PyObject_VirtualFree(void *, size_t size); + + +/* This function returns the number of allocated memory blocks, regardless of size */ +PyAPI_FUNC(Py_ssize_t) _Py_GetAllocatedBlocks(void); + + +#ifdef WITH_PYMALLOC +// Export the symbol for the 3rd party guppy3 project +PyAPI_FUNC(int) _PyObject_DebugMallocStats(FILE *out); +#endif + + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_OBMALLOC_H diff --git a/Include/internal/pycore_obmalloc_init.h b/Include/internal/pycore_obmalloc_init.h new file mode 100644 index 00000000000..c9f197e72de --- /dev/null +++ b/Include/internal/pycore_obmalloc_init.h @@ -0,0 +1,69 @@ +#ifndef Py_INTERNAL_OBMALLOC_INIT_H +#define Py_INTERNAL_OBMALLOC_INIT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +/****************************************************/ +/* the default object allocator's state initializer */ + +#define PTA(pools, x) \ + ((poolp )((uint8_t *)&(pools.used[2*(x)]) - 2*sizeof(pymem_block *))) +#define PT(p, x) PTA(p, x), PTA(p, x) + +#define PT_8(p, start) \ + PT(p, start), \ + PT(p, start+1), \ + PT(p, start+2), \ + PT(p, start+3), \ + PT(p, start+4), \ + PT(p, start+5), \ + PT(p, start+6), \ + PT(p, start+7) + +#if NB_SMALL_SIZE_CLASSES <= 8 +# define _obmalloc_pools_INIT(p) \ + { PT_8(p, 0) } +#elif NB_SMALL_SIZE_CLASSES <= 16 +# define _obmalloc_pools_INIT(p) \ + { PT_8(p, 0), PT_8(p, 8) } +#elif NB_SMALL_SIZE_CLASSES <= 24 +# define _obmalloc_pools_INIT(p) \ + { PT_8(p, 0), PT_8(p, 8), PT_8(p, 16) } +#elif NB_SMALL_SIZE_CLASSES <= 32 +# define _obmalloc_pools_INIT(p) \ + { PT_8(p, 0), PT_8(p, 8), PT_8(p, 16), PT_8(p, 24) } +#elif NB_SMALL_SIZE_CLASSES <= 40 +# define _obmalloc_pools_INIT(p) \ + { PT_8(p, 0), PT_8(p, 8), PT_8(p, 16), PT_8(p, 24), PT_8(p, 32) } +#elif NB_SMALL_SIZE_CLASSES <= 48 +# define _obmalloc_pools_INIT(p) \ + { PT_8(p, 0), PT_8(p, 8), PT_8(p, 16), PT_8(p, 24), PT_8(p, 32), PT_8(p, 40) } +#elif NB_SMALL_SIZE_CLASSES <= 56 +# define _obmalloc_pools_INIT(p) \ + { PT_8(p, 0), PT_8(p, 8), PT_8(p, 16), PT_8(p, 24), PT_8(p, 32), PT_8(p, 40), PT_8(p, 48) } +#elif NB_SMALL_SIZE_CLASSES <= 64 +# define _obmalloc_pools_INIT(p) \ + { PT_8(p, 0), PT_8(p, 8), PT_8(p, 16), PT_8(p, 24), PT_8(p, 32), PT_8(p, 40), PT_8(p, 48), PT_8(p, 56) } +#else +# error "NB_SMALL_SIZE_CLASSES should be less than 64" +#endif + +#define _obmalloc_state_INIT(obmalloc) \ + { \ + .dump_debug_stats = -1, \ + .pools = { \ + .used = _obmalloc_pools_INIT(obmalloc.pools), \ + }, \ + } + + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_OBMALLOC_INIT_H diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h new file mode 100644 index 00000000000..05c0485b064 --- /dev/null +++ b/Include/internal/pycore_opcode.h @@ -0,0 +1,590 @@ +// Auto-generated by Tools/build/generate_opcode_h.py from Lib/opcode.py + +#ifndef Py_INTERNAL_OPCODE_H +#define Py_INTERNAL_OPCODE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "opcode.h" + +extern const uint8_t _PyOpcode_Caches[256]; + +extern const uint8_t _PyOpcode_Deopt[256]; + +#ifdef NEED_OPCODE_TABLES +static const uint32_t _PyOpcode_RelativeJump[9] = { + 0U, + 0U, + 536870912U, + 135118848U, + 4163U, + 0U, + 0U, + 0U, + 48U, +}; +static const uint32_t _PyOpcode_Jump[9] = { + 0U, + 0U, + 536870912U, + 135118848U, + 4163U, + 0U, + 0U, + 0U, + 48U, +}; + +const uint8_t _PyOpcode_Caches[256] = { + [BINARY_SUBSCR] = 4, + [STORE_SUBSCR] = 1, + [UNPACK_SEQUENCE] = 1, + [FOR_ITER] = 1, + [STORE_ATTR] = 4, + [LOAD_ATTR] = 9, + [COMPARE_OP] = 1, + [LOAD_GLOBAL] = 5, + [BINARY_OP] = 1, + [COMPARE_AND_BRANCH] = 1, + [CALL] = 4, +}; + +const uint8_t _PyOpcode_Deopt[256] = { + [BEFORE_ASYNC_WITH] = BEFORE_ASYNC_WITH, + [BEFORE_WITH] = BEFORE_WITH, + [BINARY_OP] = BINARY_OP, + [BINARY_OP_ADD_FLOAT] = BINARY_OP, + [BINARY_OP_ADD_INT] = BINARY_OP, + [BINARY_OP_ADD_UNICODE] = BINARY_OP, + [BINARY_OP_INPLACE_ADD_UNICODE] = BINARY_OP, + [BINARY_OP_MULTIPLY_FLOAT] = BINARY_OP, + [BINARY_OP_MULTIPLY_INT] = BINARY_OP, + [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP, + [BINARY_OP_SUBTRACT_INT] = BINARY_OP, + [BINARY_SLICE] = BINARY_SLICE, + [BINARY_SUBSCR] = BINARY_SUBSCR, + [BINARY_SUBSCR_DICT] = BINARY_SUBSCR, + [BINARY_SUBSCR_GETITEM] = BINARY_SUBSCR, + [BINARY_SUBSCR_LIST_INT] = BINARY_SUBSCR, + [BINARY_SUBSCR_TUPLE_INT] = BINARY_SUBSCR, + [BUILD_CONST_KEY_MAP] = BUILD_CONST_KEY_MAP, + [BUILD_LIST] = BUILD_LIST, + [BUILD_MAP] = BUILD_MAP, + [BUILD_SET] = BUILD_SET, + [BUILD_SLICE] = BUILD_SLICE, + [BUILD_STRING] = BUILD_STRING, + [BUILD_TUPLE] = BUILD_TUPLE, + [CACHE] = CACHE, + [CALL] = CALL, + [CALL_BOUND_METHOD_EXACT_ARGS] = CALL, + [CALL_BUILTIN_CLASS] = CALL, + [CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL, + [CALL_FUNCTION_EX] = CALL_FUNCTION_EX, + [CALL_INTRINSIC_1] = CALL_INTRINSIC_1, + [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = CALL, + [CALL_NO_KW_BUILTIN_FAST] = CALL, + [CALL_NO_KW_BUILTIN_O] = CALL, + [CALL_NO_KW_ISINSTANCE] = CALL, + [CALL_NO_KW_LEN] = CALL, + [CALL_NO_KW_LIST_APPEND] = CALL, + [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = CALL, + [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = CALL, + [CALL_NO_KW_METHOD_DESCRIPTOR_O] = CALL, + [CALL_NO_KW_STR_1] = CALL, + [CALL_NO_KW_TUPLE_1] = CALL, + [CALL_NO_KW_TYPE_1] = CALL, + [CALL_PY_EXACT_ARGS] = CALL, + [CALL_PY_WITH_DEFAULTS] = CALL, + [CHECK_EG_MATCH] = CHECK_EG_MATCH, + [CHECK_EXC_MATCH] = CHECK_EXC_MATCH, + [CLEANUP_THROW] = CLEANUP_THROW, + [COMPARE_AND_BRANCH] = COMPARE_AND_BRANCH, + [COMPARE_AND_BRANCH_FLOAT] = COMPARE_AND_BRANCH, + [COMPARE_AND_BRANCH_INT] = COMPARE_AND_BRANCH, + [COMPARE_AND_BRANCH_STR] = COMPARE_AND_BRANCH, + [COMPARE_OP] = COMPARE_OP, + [CONTAINS_OP] = CONTAINS_OP, + [COPY] = COPY, + [COPY_FREE_VARS] = COPY_FREE_VARS, + [DELETE_ATTR] = DELETE_ATTR, + [DELETE_DEREF] = DELETE_DEREF, + [DELETE_FAST] = DELETE_FAST, + [DELETE_GLOBAL] = DELETE_GLOBAL, + [DELETE_NAME] = DELETE_NAME, + [DELETE_SUBSCR] = DELETE_SUBSCR, + [DICT_MERGE] = DICT_MERGE, + [DICT_UPDATE] = DICT_UPDATE, + [END_ASYNC_FOR] = END_ASYNC_FOR, + [END_FOR] = END_FOR, + [EXTENDED_ARG] = EXTENDED_ARG, + [FORMAT_VALUE] = FORMAT_VALUE, + [FOR_ITER] = FOR_ITER, + [FOR_ITER_GEN] = FOR_ITER, + [FOR_ITER_LIST] = FOR_ITER, + [FOR_ITER_RANGE] = FOR_ITER, + [FOR_ITER_TUPLE] = FOR_ITER, + [GET_AITER] = GET_AITER, + [GET_ANEXT] = GET_ANEXT, + [GET_AWAITABLE] = GET_AWAITABLE, + [GET_ITER] = GET_ITER, + [GET_LEN] = GET_LEN, + [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER, + [IMPORT_FROM] = IMPORT_FROM, + [IMPORT_NAME] = IMPORT_NAME, + [INTERPRETER_EXIT] = INTERPRETER_EXIT, + [IS_OP] = IS_OP, + [JUMP_BACKWARD] = JUMP_BACKWARD, + [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT, + [JUMP_FORWARD] = JUMP_FORWARD, + [JUMP_IF_FALSE_OR_POP] = JUMP_IF_FALSE_OR_POP, + [JUMP_IF_TRUE_OR_POP] = JUMP_IF_TRUE_OR_POP, + [KW_NAMES] = KW_NAMES, + [LIST_APPEND] = LIST_APPEND, + [LIST_EXTEND] = LIST_EXTEND, + [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR, + [LOAD_ATTR] = LOAD_ATTR, + [LOAD_ATTR_CLASS] = LOAD_ATTR, + [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = LOAD_ATTR, + [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR, + [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR, + [LOAD_ATTR_MODULE] = LOAD_ATTR, + [LOAD_ATTR_PROPERTY] = LOAD_ATTR, + [LOAD_ATTR_SLOT] = LOAD_ATTR, + [LOAD_ATTR_WITH_HINT] = LOAD_ATTR, + [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS, + [LOAD_CLASSDEREF] = LOAD_CLASSDEREF, + [LOAD_CLOSURE] = LOAD_CLOSURE, + [LOAD_CONST] = LOAD_CONST, + [LOAD_CONST__LOAD_FAST] = LOAD_CONST, + [LOAD_DEREF] = LOAD_DEREF, + [LOAD_FAST] = LOAD_FAST, + [LOAD_FAST_CHECK] = LOAD_FAST_CHECK, + [LOAD_FAST__LOAD_CONST] = LOAD_FAST, + [LOAD_FAST__LOAD_FAST] = LOAD_FAST, + [LOAD_GLOBAL] = LOAD_GLOBAL, + [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL, + [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL, + [LOAD_NAME] = LOAD_NAME, + [MAKE_CELL] = MAKE_CELL, + [MAKE_FUNCTION] = MAKE_FUNCTION, + [MAP_ADD] = MAP_ADD, + [MATCH_CLASS] = MATCH_CLASS, + [MATCH_KEYS] = MATCH_KEYS, + [MATCH_MAPPING] = MATCH_MAPPING, + [MATCH_SEQUENCE] = MATCH_SEQUENCE, + [NOP] = NOP, + [POP_EXCEPT] = POP_EXCEPT, + [POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE, + [POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE, + [POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE, + [POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE, + [POP_TOP] = POP_TOP, + [PREP_RERAISE_STAR] = PREP_RERAISE_STAR, + [PUSH_EXC_INFO] = PUSH_EXC_INFO, + [PUSH_NULL] = PUSH_NULL, + [RAISE_VARARGS] = RAISE_VARARGS, + [RERAISE] = RERAISE, + [RESUME] = RESUME, + [RETURN_GENERATOR] = RETURN_GENERATOR, + [RETURN_VALUE] = RETURN_VALUE, + [SEND] = SEND, + [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS, + [SET_ADD] = SET_ADD, + [SET_UPDATE] = SET_UPDATE, + [STORE_ATTR] = STORE_ATTR, + [STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR, + [STORE_ATTR_SLOT] = STORE_ATTR, + [STORE_ATTR_WITH_HINT] = STORE_ATTR, + [STORE_DEREF] = STORE_DEREF, + [STORE_FAST] = STORE_FAST, + [STORE_FAST__LOAD_FAST] = STORE_FAST, + [STORE_FAST__STORE_FAST] = STORE_FAST, + [STORE_GLOBAL] = STORE_GLOBAL, + [STORE_NAME] = STORE_NAME, + [STORE_SLICE] = STORE_SLICE, + [STORE_SUBSCR] = STORE_SUBSCR, + [STORE_SUBSCR_DICT] = STORE_SUBSCR, + [STORE_SUBSCR_LIST_INT] = STORE_SUBSCR, + [SWAP] = SWAP, + [UNARY_INVERT] = UNARY_INVERT, + [UNARY_NEGATIVE] = UNARY_NEGATIVE, + [UNARY_NOT] = UNARY_NOT, + [UNPACK_EX] = UNPACK_EX, + [UNPACK_SEQUENCE] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_LIST] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_TUPLE] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE, + [WITH_EXCEPT_START] = WITH_EXCEPT_START, + [YIELD_VALUE] = YIELD_VALUE, +}; +#endif // NEED_OPCODE_TABLES + +#ifdef Py_DEBUG +static const char *const _PyOpcode_OpName[263] = { + [CACHE] = "CACHE", + [POP_TOP] = "POP_TOP", + [PUSH_NULL] = "PUSH_NULL", + [INTERPRETER_EXIT] = "INTERPRETER_EXIT", + [END_FOR] = "END_FOR", + [BINARY_OP_ADD_FLOAT] = "BINARY_OP_ADD_FLOAT", + [BINARY_OP_ADD_INT] = "BINARY_OP_ADD_INT", + [BINARY_OP_ADD_UNICODE] = "BINARY_OP_ADD_UNICODE", + [BINARY_OP_INPLACE_ADD_UNICODE] = "BINARY_OP_INPLACE_ADD_UNICODE", + [NOP] = "NOP", + [BINARY_OP_MULTIPLY_FLOAT] = "BINARY_OP_MULTIPLY_FLOAT", + [UNARY_NEGATIVE] = "UNARY_NEGATIVE", + [UNARY_NOT] = "UNARY_NOT", + [BINARY_OP_MULTIPLY_INT] = "BINARY_OP_MULTIPLY_INT", + [BINARY_OP_SUBTRACT_FLOAT] = "BINARY_OP_SUBTRACT_FLOAT", + [UNARY_INVERT] = "UNARY_INVERT", + [BINARY_OP_SUBTRACT_INT] = "BINARY_OP_SUBTRACT_INT", + [BINARY_SUBSCR_DICT] = "BINARY_SUBSCR_DICT", + [BINARY_SUBSCR_GETITEM] = "BINARY_SUBSCR_GETITEM", + [BINARY_SUBSCR_LIST_INT] = "BINARY_SUBSCR_LIST_INT", + [BINARY_SUBSCR_TUPLE_INT] = "BINARY_SUBSCR_TUPLE_INT", + [CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS", + [CALL_PY_WITH_DEFAULTS] = "CALL_PY_WITH_DEFAULTS", + [CALL_BOUND_METHOD_EXACT_ARGS] = "CALL_BOUND_METHOD_EXACT_ARGS", + [CALL_BUILTIN_CLASS] = "CALL_BUILTIN_CLASS", + [BINARY_SUBSCR] = "BINARY_SUBSCR", + [BINARY_SLICE] = "BINARY_SLICE", + [STORE_SLICE] = "STORE_SLICE", + [CALL_BUILTIN_FAST_WITH_KEYWORDS] = "CALL_BUILTIN_FAST_WITH_KEYWORDS", + [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS", + [GET_LEN] = "GET_LEN", + [MATCH_MAPPING] = "MATCH_MAPPING", + [MATCH_SEQUENCE] = "MATCH_SEQUENCE", + [MATCH_KEYS] = "MATCH_KEYS", + [CALL_NO_KW_BUILTIN_FAST] = "CALL_NO_KW_BUILTIN_FAST", + [PUSH_EXC_INFO] = "PUSH_EXC_INFO", + [CHECK_EXC_MATCH] = "CHECK_EXC_MATCH", + [CHECK_EG_MATCH] = "CHECK_EG_MATCH", + [CALL_NO_KW_BUILTIN_O] = "CALL_NO_KW_BUILTIN_O", + [CALL_NO_KW_ISINSTANCE] = "CALL_NO_KW_ISINSTANCE", + [CALL_NO_KW_LEN] = "CALL_NO_KW_LEN", + [CALL_NO_KW_LIST_APPEND] = "CALL_NO_KW_LIST_APPEND", + [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = "CALL_NO_KW_METHOD_DESCRIPTOR_FAST", + [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = "CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS", + [CALL_NO_KW_METHOD_DESCRIPTOR_O] = "CALL_NO_KW_METHOD_DESCRIPTOR_O", + [CALL_NO_KW_STR_1] = "CALL_NO_KW_STR_1", + [CALL_NO_KW_TUPLE_1] = "CALL_NO_KW_TUPLE_1", + [CALL_NO_KW_TYPE_1] = "CALL_NO_KW_TYPE_1", + [COMPARE_AND_BRANCH_FLOAT] = "COMPARE_AND_BRANCH_FLOAT", + [WITH_EXCEPT_START] = "WITH_EXCEPT_START", + [GET_AITER] = "GET_AITER", + [GET_ANEXT] = "GET_ANEXT", + [BEFORE_ASYNC_WITH] = "BEFORE_ASYNC_WITH", + [BEFORE_WITH] = "BEFORE_WITH", + [END_ASYNC_FOR] = "END_ASYNC_FOR", + [CLEANUP_THROW] = "CLEANUP_THROW", + [COMPARE_AND_BRANCH_INT] = "COMPARE_AND_BRANCH_INT", + [COMPARE_AND_BRANCH_STR] = "COMPARE_AND_BRANCH_STR", + [FOR_ITER_LIST] = "FOR_ITER_LIST", + [FOR_ITER_TUPLE] = "FOR_ITER_TUPLE", + [STORE_SUBSCR] = "STORE_SUBSCR", + [DELETE_SUBSCR] = "DELETE_SUBSCR", + [FOR_ITER_RANGE] = "FOR_ITER_RANGE", + [FOR_ITER_GEN] = "FOR_ITER_GEN", + [LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS", + [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN", + [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE", + [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE", + [GET_ITER] = "GET_ITER", + [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER", + [LOAD_ATTR_PROPERTY] = "LOAD_ATTR_PROPERTY", + [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS", + [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT", + [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT", + [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR", + [RETURN_GENERATOR] = "RETURN_GENERATOR", + [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT", + [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT", + [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES", + [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", + [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST", + [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST", + [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", + [RETURN_VALUE] = "RETURN_VALUE", + [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", + [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS", + [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE", + [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT", + [PREP_RERAISE_STAR] = "PREP_RERAISE_STAR", + [POP_EXCEPT] = "POP_EXCEPT", + [STORE_NAME] = "STORE_NAME", + [DELETE_NAME] = "DELETE_NAME", + [UNPACK_SEQUENCE] = "UNPACK_SEQUENCE", + [FOR_ITER] = "FOR_ITER", + [UNPACK_EX] = "UNPACK_EX", + [STORE_ATTR] = "STORE_ATTR", + [DELETE_ATTR] = "DELETE_ATTR", + [STORE_GLOBAL] = "STORE_GLOBAL", + [DELETE_GLOBAL] = "DELETE_GLOBAL", + [SWAP] = "SWAP", + [LOAD_CONST] = "LOAD_CONST", + [LOAD_NAME] = "LOAD_NAME", + [BUILD_TUPLE] = "BUILD_TUPLE", + [BUILD_LIST] = "BUILD_LIST", + [BUILD_SET] = "BUILD_SET", + [BUILD_MAP] = "BUILD_MAP", + [LOAD_ATTR] = "LOAD_ATTR", + [COMPARE_OP] = "COMPARE_OP", + [IMPORT_NAME] = "IMPORT_NAME", + [IMPORT_FROM] = "IMPORT_FROM", + [JUMP_FORWARD] = "JUMP_FORWARD", + [JUMP_IF_FALSE_OR_POP] = "JUMP_IF_FALSE_OR_POP", + [JUMP_IF_TRUE_OR_POP] = "JUMP_IF_TRUE_OR_POP", + [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT", + [POP_JUMP_IF_FALSE] = "POP_JUMP_IF_FALSE", + [POP_JUMP_IF_TRUE] = "POP_JUMP_IF_TRUE", + [LOAD_GLOBAL] = "LOAD_GLOBAL", + [IS_OP] = "IS_OP", + [CONTAINS_OP] = "CONTAINS_OP", + [RERAISE] = "RERAISE", + [COPY] = "COPY", + [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST", + [BINARY_OP] = "BINARY_OP", + [SEND] = "SEND", + [LOAD_FAST] = "LOAD_FAST", + [STORE_FAST] = "STORE_FAST", + [DELETE_FAST] = "DELETE_FAST", + [LOAD_FAST_CHECK] = "LOAD_FAST_CHECK", + [POP_JUMP_IF_NOT_NONE] = "POP_JUMP_IF_NOT_NONE", + [POP_JUMP_IF_NONE] = "POP_JUMP_IF_NONE", + [RAISE_VARARGS] = "RAISE_VARARGS", + [GET_AWAITABLE] = "GET_AWAITABLE", + [MAKE_FUNCTION] = "MAKE_FUNCTION", + [BUILD_SLICE] = "BUILD_SLICE", + [JUMP_BACKWARD_NO_INTERRUPT] = "JUMP_BACKWARD_NO_INTERRUPT", + [MAKE_CELL] = "MAKE_CELL", + [LOAD_CLOSURE] = "LOAD_CLOSURE", + [LOAD_DEREF] = "LOAD_DEREF", + [STORE_DEREF] = "STORE_DEREF", + [DELETE_DEREF] = "DELETE_DEREF", + [JUMP_BACKWARD] = "JUMP_BACKWARD", + [COMPARE_AND_BRANCH] = "COMPARE_AND_BRANCH", + [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", + [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST", + [EXTENDED_ARG] = "EXTENDED_ARG", + [LIST_APPEND] = "LIST_APPEND", + [SET_ADD] = "SET_ADD", + [MAP_ADD] = "MAP_ADD", + [LOAD_CLASSDEREF] = "LOAD_CLASSDEREF", + [COPY_FREE_VARS] = "COPY_FREE_VARS", + [YIELD_VALUE] = "YIELD_VALUE", + [RESUME] = "RESUME", + [MATCH_CLASS] = "MATCH_CLASS", + [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT", + [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT", + [FORMAT_VALUE] = "FORMAT_VALUE", + [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP", + [BUILD_STRING] = "BUILD_STRING", + [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST", + [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE", + [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE", + [161] = "<161>", + [LIST_EXTEND] = "LIST_EXTEND", + [SET_UPDATE] = "SET_UPDATE", + [DICT_MERGE] = "DICT_MERGE", + [DICT_UPDATE] = "DICT_UPDATE", + [166] = "<166>", + [167] = "<167>", + [168] = "<168>", + [169] = "<169>", + [170] = "<170>", + [CALL] = "CALL", + [KW_NAMES] = "KW_NAMES", + [CALL_INTRINSIC_1] = "CALL_INTRINSIC_1", + [174] = "<174>", + [175] = "<175>", + [176] = "<176>", + [177] = "<177>", + [178] = "<178>", + [179] = "<179>", + [180] = "<180>", + [181] = "<181>", + [182] = "<182>", + [183] = "<183>", + [184] = "<184>", + [185] = "<185>", + [186] = "<186>", + [187] = "<187>", + [188] = "<188>", + [189] = "<189>", + [190] = "<190>", + [191] = "<191>", + [192] = "<192>", + [193] = "<193>", + [194] = "<194>", + [195] = "<195>", + [196] = "<196>", + [197] = "<197>", + [198] = "<198>", + [199] = "<199>", + [200] = "<200>", + [201] = "<201>", + [202] = "<202>", + [203] = "<203>", + [204] = "<204>", + [205] = "<205>", + [206] = "<206>", + [207] = "<207>", + [208] = "<208>", + [209] = "<209>", + [210] = "<210>", + [211] = "<211>", + [212] = "<212>", + [213] = "<213>", + [214] = "<214>", + [215] = "<215>", + [216] = "<216>", + [217] = "<217>", + [218] = "<218>", + [219] = "<219>", + [220] = "<220>", + [221] = "<221>", + [222] = "<222>", + [223] = "<223>", + [224] = "<224>", + [225] = "<225>", + [226] = "<226>", + [227] = "<227>", + [228] = "<228>", + [229] = "<229>", + [230] = "<230>", + [231] = "<231>", + [232] = "<232>", + [233] = "<233>", + [234] = "<234>", + [235] = "<235>", + [236] = "<236>", + [237] = "<237>", + [238] = "<238>", + [239] = "<239>", + [240] = "<240>", + [241] = "<241>", + [242] = "<242>", + [243] = "<243>", + [244] = "<244>", + [245] = "<245>", + [246] = "<246>", + [247] = "<247>", + [248] = "<248>", + [249] = "<249>", + [250] = "<250>", + [251] = "<251>", + [252] = "<252>", + [253] = "<253>", + [254] = "<254>", + [DO_TRACING] = "DO_TRACING", + [SETUP_FINALLY] = "SETUP_FINALLY", + [SETUP_CLEANUP] = "SETUP_CLEANUP", + [SETUP_WITH] = "SETUP_WITH", + [POP_BLOCK] = "POP_BLOCK", + [JUMP] = "JUMP", + [JUMP_NO_INTERRUPT] = "JUMP_NO_INTERRUPT", + [LOAD_METHOD] = "LOAD_METHOD", +}; +#endif + +#define EXTRA_CASES \ + case 161: \ + case 166: \ + case 167: \ + case 168: \ + case 169: \ + case 170: \ + case 174: \ + case 175: \ + case 176: \ + case 177: \ + case 178: \ + case 179: \ + case 180: \ + case 181: \ + case 182: \ + case 183: \ + case 184: \ + case 185: \ + case 186: \ + case 187: \ + case 188: \ + case 189: \ + case 190: \ + case 191: \ + case 192: \ + case 193: \ + case 194: \ + case 195: \ + case 196: \ + case 197: \ + case 198: \ + case 199: \ + case 200: \ + case 201: \ + case 202: \ + case 203: \ + case 204: \ + case 205: \ + case 206: \ + case 207: \ + case 208: \ + case 209: \ + case 210: \ + case 211: \ + case 212: \ + case 213: \ + case 214: \ + case 215: \ + case 216: \ + case 217: \ + case 218: \ + case 219: \ + case 220: \ + case 221: \ + case 222: \ + case 223: \ + case 224: \ + case 225: \ + case 226: \ + case 227: \ + case 228: \ + case 229: \ + case 230: \ + case 231: \ + case 232: \ + case 233: \ + case 234: \ + case 235: \ + case 236: \ + case 237: \ + case 238: \ + case 239: \ + case 240: \ + case 241: \ + case 242: \ + case 243: \ + case 244: \ + case 245: \ + case 246: \ + case 247: \ + case 248: \ + case 249: \ + case 250: \ + case 251: \ + case 252: \ + case 253: \ + case 254: \ + ; + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_OPCODE_H diff --git a/Include/internal/pycore_parser.h b/Include/internal/pycore_parser.h index e2de24e2ca9..dd51b92801a 100644 --- a/Include/internal/pycore_parser.h +++ b/Include/internal/pycore_parser.h @@ -8,12 +8,46 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif + +#include "pycore_ast.h" // struct _expr +#include "pycore_global_strings.h" // _Py_DECLARE_STR() +#include "pycore_pyarena.h" // PyArena + + +#ifdef Py_DEBUG +#define _PYPEGEN_NSTATISTICS 2000 +#endif + +struct _parser_runtime_state { +#ifdef Py_DEBUG + long memo_statistics[_PYPEGEN_NSTATISTICS]; +#else + int _not_used; +#endif + struct _expr dummy_name; +}; + +_Py_DECLARE_STR(empty, "") +#define _parser_runtime_state_INIT \ + { \ + .dummy_name = { \ + .kind = Name_kind, \ + .v.Name.id = &_Py_STR(empty), \ + .v.Name.ctx = Load, \ + .lineno = 1, \ + .col_offset = 0, \ + .end_lineno = 1, \ + .end_col_offset = 0, \ + }, \ + } + extern struct _mod* _PyParser_ASTFromString( const char *str, PyObject* filename, int mode, PyCompilerFlags *flags, PyArena *arena); + extern struct _mod* _PyParser_ASTFromFile( FILE *fp, PyObject *filename_ob, @@ -25,6 +59,7 @@ extern struct _mod* _PyParser_ASTFromFile( int *errcode, PyArena *arena); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_pathconfig.h b/Include/internal/pycore_pathconfig.h index a258aab2397..b8deaa0c3eb 100644 --- a/Include/internal/pycore_pathconfig.h +++ b/Include/internal/pycore_pathconfig.h @@ -8,65 +8,15 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -typedef struct _PyPathConfig { - /* Full path to the Python program */ - wchar_t *program_full_path; - wchar_t *prefix; - wchar_t *exec_prefix; - wchar_t *stdlib_dir; - /* Set by Py_SetPath(), or computed by _PyConfig_InitPathConfig() */ - wchar_t *module_search_path; - /* Python program name */ - wchar_t *program_name; - /* Set by Py_SetPythonHome() or PYTHONHOME environment variable */ - wchar_t *home; -#ifdef MS_WINDOWS - /* isolated and site_import are used to set Py_IsolatedFlag and - Py_NoSiteFlag flags on Windows in read_pth_file(). These fields - are ignored when their value are equal to -1 (unset). */ - int isolated; - int site_import; - /* Set when a venv is detected */ - wchar_t *base_executable; -#endif -} _PyPathConfig; +PyAPI_FUNC(void) _PyPathConfig_ClearGlobal(void); +extern PyStatus _PyPathConfig_ReadGlobal(PyConfig *config); +extern PyStatus _PyPathConfig_UpdateGlobal(const PyConfig *config); +extern const wchar_t * _PyPathConfig_GetGlobalModuleSearchPath(void); -#ifdef MS_WINDOWS -# define _PyPathConfig_INIT \ - {.module_search_path = NULL, \ - .isolated = -1, \ - .site_import = -1} -#else -# define _PyPathConfig_INIT \ - {.module_search_path = NULL} -#endif -/* Note: _PyPathConfig_INIT sets other fields to 0/NULL */ - -PyAPI_DATA(_PyPathConfig) _Py_path_config; -#ifdef MS_WINDOWS -PyAPI_DATA(wchar_t*) _Py_dll_path; -#endif - -extern void _PyPathConfig_ClearGlobal(void); - -extern PyStatus _PyPathConfig_Calculate( - _PyPathConfig *pathconfig, - const PyConfig *config); extern int _PyPathConfig_ComputeSysPath0( const PyWideStringList *argv, PyObject **path0); -extern PyStatus _Py_FindEnvConfigValue( - FILE *env_file, - const wchar_t *key, - wchar_t **value_p); -#ifdef MS_WINDOWS -extern wchar_t* _Py_GetDLLPath(void); -#endif - -extern PyStatus _PyConfig_WritePathConfig(const PyConfig *config); -extern void _Py_DumpPathConfig(PyThreadState *tstate); -extern PyObject* _PyPathConfig_AsDict(void); #ifdef __cplusplus } diff --git a/Include/internal/pycore_pyerrors.h b/Include/internal/pycore_pyerrors.h index 0f4d41c7e0b..66f37942ef9 100644 --- a/Include/internal/pycore_pyerrors.h +++ b/Include/internal/pycore_pyerrors.h @@ -8,6 +8,15 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif + +/* runtime lifecycle */ + +extern PyStatus _PyErr_InitTypes(PyInterpreterState *); +extern void _PyErr_FiniTypes(PyInterpreterState *); + + +/* other API */ + static inline PyObject* _PyErr_Occurred(PyThreadState *tstate) { assert(tstate != NULL); @@ -16,18 +25,11 @@ static inline PyObject* _PyErr_Occurred(PyThreadState *tstate) static inline void _PyErr_ClearExcState(_PyErr_StackItem *exc_state) { - PyObject *t, *v, *tb; - t = exc_state->exc_type; - v = exc_state->exc_value; - tb = exc_state->exc_traceback; - exc_state->exc_type = NULL; - exc_state->exc_value = NULL; - exc_state->exc_traceback = NULL; - Py_XDECREF(t); - Py_XDECREF(v); - Py_XDECREF(tb); + Py_CLEAR(exc_state->exc_value); } +PyAPI_FUNC(PyObject*) _PyErr_StackItemToExcInfoTuple( + _PyErr_StackItem *err_info); PyAPI_FUNC(void) _PyErr_Fetch( PyThreadState *tstate, @@ -82,6 +84,14 @@ PyAPI_FUNC(PyObject *) _PyErr_FormatFromCauseTstate( const char *format, ...); +PyAPI_FUNC(PyObject *) _PyExc_CreateExceptionGroup( + const char *msg, + PyObject *excs); + +PyAPI_FUNC(PyObject *) _PyExc_PrepReraiseStar( + PyObject *orig, + PyObject *excs); + PyAPI_FUNC(int) _PyErr_CheckSignalsTstate(PyThreadState *tstate); PyAPI_FUNC(void) _Py_DumpExtensionModules(int fd, PyInterpreterState *interp); @@ -90,12 +100,6 @@ extern PyObject* _Py_Offer_Suggestions(PyObject* exception); PyAPI_FUNC(Py_ssize_t) _Py_UTF8_Edit_Cost(PyObject *str_a, PyObject *str_b, Py_ssize_t max_cost); -PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalRefcountErrorFunc( - const char *func, - const char *message); - -#define _Py_FatalRefcountError(message) _Py_FatalRefcountErrorFunc(__func__, message) - #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_pyhash.h b/Include/internal/pycore_pyhash.h index a229f8d8b7f..34dfa537712 100644 --- a/Include/internal/pycore_pyhash.h +++ b/Include/internal/pycore_pyhash.h @@ -5,6 +5,36 @@ # error "this header requires Py_BUILD_CORE define" #endif + +struct pyhash_runtime_state { + struct { +#ifndef MS_WINDOWS + int fd; + dev_t st_dev; + ino_t st_ino; +#else + // This is a placeholder so the struct isn't empty on Windows. + int _not_used; +#endif + } urandom_cache; +}; + +#ifndef MS_WINDOWS +# define _py_urandom_cache_INIT \ + { \ + .fd = -1, \ + } +#else +# define _py_urandom_cache_INIT {0} +#endif + +#define pyhash_state_INIT \ + { \ + .urandom_cache = _py_urandom_cache_INIT, \ + } + + uint64_t _Py_KeyedHash(uint64_t, const char *, Py_ssize_t); -#endif + +#endif // Py_INTERNAL_HASH_H diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 5e0f36ab2ae..2d431befd74 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -8,32 +8,12 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#ifdef HAVE_SIGNAL_H -#include -#endif - #include "pycore_runtime.h" // _PyRuntimeState -#ifndef NSIG -# if defined(_NSIG) -# define NSIG _NSIG /* For BSD/SysV */ -# elif defined(_SIGMAX) -# define NSIG (_SIGMAX + 1) /* For QNX */ -# elif defined(SIGMAX) -# define NSIG (SIGMAX + 1) /* For djgpp */ -# else -# define NSIG 64 /* Use a reasonable default value */ -# endif -#endif - /* Forward declarations */ struct _PyArgv; struct pyruntimestate; -/* True if the main interpreter thread exited due to an unhandled - * KeyboardInterrupt exception, suggesting the user pressed ^C. */ -PyAPI_DATA(int) _Py_UnhandledKeyboardInterrupt; - extern int _Py_SetFileSystemEncoding( const char *encoding, const char *errors); @@ -49,13 +29,8 @@ PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc); /* Various one-time initializers */ -extern PyStatus _PyUnicode_Init(PyInterpreterState *interp); -extern PyStatus _PyUnicode_InitTypes(void); -extern PyStatus _PyBytes_Init(PyInterpreterState *interp); -extern int _PyStructSequence_Init(void); -extern void _PyLong_Init(PyInterpreterState *interp); -extern int _PyLong_InitTypes(void); -extern PyStatus _PyTuple_Init(PyInterpreterState *interp); +extern void _Py_InitVersion(void); +extern PyStatus _PyImport_Init(void); extern PyStatus _PyFaulthandler_Init(int enable); extern int _PyTraceMalloc_Init(int enable); extern PyObject * _PyBuiltin_Init(PyInterpreterState *interp); @@ -65,52 +40,36 @@ extern PyStatus _PySys_Create( extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options); extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config); extern int _PySys_UpdateConfig(PyThreadState *tstate); -extern PyStatus _PyExc_Init(PyInterpreterState *interp); -extern PyStatus _PyErr_InitTypes(void); -extern PyStatus _PyBuiltins_AddExceptions(PyObject * bltinmod); -extern void _PyFloat_Init(void); -extern int _PyFloat_InitTypes(void); +extern void _PySys_Fini(PyInterpreterState *interp); +extern int _PyBuiltins_AddExceptions(PyObject * bltinmod); extern PyStatus _Py_HashRandomization_Init(const PyConfig *); -extern PyStatus _PyTypes_Init(void); -extern PyStatus _PyTypes_InitSlotDefs(void); +extern PyStatus _PyTime_Init(void); extern PyStatus _PyImportZip_Init(PyThreadState *tstate); extern PyStatus _PyGC_Init(PyInterpreterState *interp); extern PyStatus _PyAtExit_Init(PyInterpreterState *interp); - +extern int _Py_Deepfreeze_Init(void); /* Various internal finalizers */ -extern void _PyFrame_Fini(PyInterpreterState *interp); -extern void _PyDict_Fini(PyInterpreterState *interp); -extern void _PyTuple_Fini(PyInterpreterState *interp); -extern void _PyList_Fini(PyInterpreterState *interp); -extern void _PyBytes_Fini(PyInterpreterState *interp); -extern void _PyFloat_Fini(PyInterpreterState *interp); -extern void _PySlice_Fini(PyInterpreterState *interp); -extern void _PyAsyncGen_Fini(PyInterpreterState *interp); - extern int _PySignal_Init(int install_signal_handlers); extern void _PySignal_Fini(void); -extern void _PyExc_ClearExceptionGroupType(PyInterpreterState *interp); -extern void _PyExc_Fini(PyInterpreterState *interp); extern void _PyImport_Fini(void); extern void _PyImport_Fini2(void); extern void _PyGC_Fini(PyInterpreterState *interp); -extern void _PyType_Fini(PyInterpreterState *interp); extern void _Py_HashRandomization_Fini(void); -extern void _PyUnicode_Fini(PyInterpreterState *interp); -extern void _PyUnicode_ClearInterned(PyInterpreterState *interp); -extern void _PyLong_Fini(PyInterpreterState *interp); extern void _PyFaulthandler_Fini(void); extern void _PyHash_Fini(void); extern void _PyTraceMalloc_Fini(void); extern void _PyWarnings_Fini(PyInterpreterState *interp); extern void _PyAST_Fini(PyInterpreterState *interp); extern void _PyAtExit_Fini(PyInterpreterState *interp); +extern void _PyThread_FiniType(PyInterpreterState *interp); +extern void _Py_Deepfreeze_Fini(void); +extern void _PyArg_Fini(void); -extern PyStatus _PyGILState_Init(_PyRuntimeState *runtime); +extern PyStatus _PyGILState_Init(PyInterpreterState *interp); extern PyStatus _PyGILState_SetTstate(PyThreadState *tstate); extern void _PyGILState_Fini(PyInterpreterState *interp); diff --git a/Include/internal/pycore_pymath.h b/Include/internal/pycore_pymath.h index 395b71452e4..5f3afe4df68 100644 --- a/Include/internal/pycore_pymath.h +++ b/Include/internal/pycore_pymath.h @@ -8,15 +8,6 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -// Extra declarations -#if !defined(_MSC_VER) && !defined(__STDC__) -extern double fmod (double, double); -extern double frexp (double, int *); -extern double ldexp (double, int); -extern double modf (double, double *); -extern double pow(double, double); -#endif // !defined(_MSC_VER) && !defined(__STDC__) - /* _Py_ADJUST_ERANGE1(x) * _Py_ADJUST_ERANGE2(x, y) @@ -65,17 +56,13 @@ static inline void _Py_ADJUST_ERANGE2(double x, double y) } } -// Return whether integral type *type* is signed or not. -#define _Py_IntegralTypeSigned(type) \ - ((type)(-1) < 0) - // Return the maximum value of integral type *type*. #define _Py_IntegralTypeMax(type) \ - ((_Py_IntegralTypeSigned(type)) ? (((((type)1 << (sizeof(type)*CHAR_BIT - 2)) - 1) << 1) + 1) : ~(type)0) + (_Py_IS_TYPE_SIGNED(type) ? (((((type)1 << (sizeof(type)*CHAR_BIT - 2)) - 1) << 1) + 1) : ~(type)0) // Return the minimum value of integral type *type*. #define _Py_IntegralTypeMin(type) \ - ((_Py_IntegralTypeSigned(type)) ? -_Py_IntegralTypeMax(type) - 1 : 0) + (_Py_IS_TYPE_SIGNED(type) ? -_Py_IntegralTypeMax(type) - 1 : 0) // Check whether *v* is in the range of integral type *type*. This is most // useful if *v* is floating-point, since demoting a floating-point *v* to an @@ -85,19 +72,34 @@ static inline void _Py_ADJUST_ERANGE2(double x, double y) (_Py_IntegralTypeMin(type) <= v && v <= _Py_IntegralTypeMax(type)) -//--- Implementation of the HAVE_PY_SET_53BIT_PRECISION macro ------------- -//--- defined in pyport.h ------------------------------------------------- +//--- HAVE_PY_SET_53BIT_PRECISION macro ------------------------------------ // -// Give appropriate definitions for the following three macros: +// The functions _Py_dg_strtod() and _Py_dg_dtoa() in Python/dtoa.c (which are +// required to support the short float repr introduced in Python 3.1) require +// that the floating-point unit that's being used for arithmetic operations on +// C doubles is set to use 53-bit precision. It also requires that the FPU +// rounding mode is round-half-to-even, but that's less often an issue. // -// _Py_SET_53BIT_PRECISION_HEADER : any variable declarations needed to -// use the two macros below. -// _Py_SET_53BIT_PRECISION_START : store original FPU settings, and -// set FPU to 53-bit precision/round-half-to-even -// _Py_SET_53BIT_PRECISION_END : restore original FPU settings +// If your FPU isn't already set to 53-bit precision/round-half-to-even, and +// you want to make use of _Py_dg_strtod() and _Py_dg_dtoa(), then you should: +// +// #define HAVE_PY_SET_53BIT_PRECISION 1 +// +// and also give appropriate definitions for the following three macros: +// +// * _Py_SET_53BIT_PRECISION_HEADER: any variable declarations needed to +// use the two macros below. +// * _Py_SET_53BIT_PRECISION_START: store original FPU settings, and +// set FPU to 53-bit precision/round-half-to-even +// * _Py_SET_53BIT_PRECISION_END: restore original FPU settings +// +// The macros are designed to be used within a single C function: see +// Python/pystrtod.c for an example of their use. + // Get and set x87 control word for gcc/x86 #ifdef HAVE_GCC_ASM_FOR_X87 +#define HAVE_PY_SET_53BIT_PRECISION 1 // Functions defined in Python/pymath.c extern unsigned short _Py_get_387controlword(void); @@ -124,6 +126,7 @@ extern void _Py_set_387controlword(unsigned short); // Get and set x87 control word for VisualStudio/x86. // x87 is not supported in 64-bit or ARM. #if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM) +#define HAVE_PY_SET_53BIT_PRECISION 1 #include // __control87_2() @@ -150,7 +153,10 @@ extern void _Py_set_387controlword(unsigned short); } while (0) #endif + +// MC68881 #ifdef HAVE_GCC_ASM_FOR_MC68881 +#define HAVE_PY_SET_53BIT_PRECISION 1 #define _Py_SET_53BIT_PRECISION_HEADER \ unsigned int old_fpcr, new_fpcr #define _Py_SET_53BIT_PRECISION_START \ @@ -178,6 +184,36 @@ extern void _Py_set_387controlword(unsigned short); #endif +//--- _PY_SHORT_FLOAT_REPR macro ------------------------------------------- + +// If we can't guarantee 53-bit precision, don't use the code +// in Python/dtoa.c, but fall back to standard code. This +// means that repr of a float will be long (17 significant digits). +// +// Realistically, there are two things that could go wrong: +// +// (1) doubles aren't IEEE 754 doubles, or +// (2) we're on x86 with the rounding precision set to 64-bits +// (extended precision), and we don't know how to change +// the rounding precision. +#if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \ + !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \ + !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) +# define _PY_SHORT_FLOAT_REPR 0 +#endif + +// Double rounding is symptomatic of use of extended precision on x86. +// If we're seeing double rounding, and we don't have any mechanism available +// for changing the FPU rounding precision, then don't use Python/dtoa.c. +#if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION) +# define _PY_SHORT_FLOAT_REPR 0 +#endif + +#ifndef _PY_SHORT_FLOAT_REPR +# define _PY_SHORT_FLOAT_REPR 1 +#endif + + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h index d70deee710e..4cc953d8d77 100644 --- a/Include/internal/pycore_pymem.h +++ b/Include/internal/pycore_pymem.h @@ -11,6 +11,27 @@ extern "C" { #include "pymem.h" // PyMemAllocatorName +typedef struct { + /* We tag each block with an API ID in order to tag API violations */ + char api_id; + PyMemAllocatorEx alloc; +} debug_alloc_api_t; + +struct _pymem_allocators { + struct { + PyMemAllocatorEx raw; + PyMemAllocatorEx mem; + PyMemAllocatorEx obj; + } standard; + struct { + debug_alloc_api_t raw; + debug_alloc_api_t mem; + debug_alloc_api_t obj; + } debug; + PyObjectArenaAllocator obj_arena; +}; + + /* Set the memory allocator of the specified domain to the default. Save the old allocator into *old_alloc if it's non-NULL. Return on success, or return -1 if the domain is unknown. */ @@ -69,36 +90,6 @@ PyAPI_FUNC(int) _PyMem_GetAllocatorName( PYMEM_ALLOCATOR_NOT_SET does nothing. */ PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator); -struct _PyTraceMalloc_Config { - /* Module initialized? - Variable protected by the GIL */ - enum { - TRACEMALLOC_NOT_INITIALIZED, - TRACEMALLOC_INITIALIZED, - TRACEMALLOC_FINALIZED - } initialized; - - /* Is tracemalloc tracing memory allocations? - Variable protected by the GIL */ - int tracing; - - /* limit of the number of frames in a traceback, 1 by default. - Variable protected by the GIL. */ - int max_nframe; -}; - -#define _PyTraceMalloc_Config_INIT \ - {.initialized = TRACEMALLOC_NOT_INITIALIZED, \ - .tracing = 0, \ - .max_nframe = 1} - -PyAPI_DATA(struct _PyTraceMalloc_Config) _Py_tracemalloc_config; - -/* Allocate memory directly from the O/S virtual memory system, - * where supported. Otherwise fallback on malloc */ -void *_PyObject_VirtualAlloc(size_t size); -void _PyObject_VirtualFree(void *, size_t size); - #ifdef __cplusplus } diff --git a/Include/internal/pycore_pymem_init.h b/Include/internal/pycore_pymem_init.h new file mode 100644 index 00000000000..78232738cb0 --- /dev/null +++ b/Include/internal/pycore_pymem_init.h @@ -0,0 +1,85 @@ +#ifndef Py_INTERNAL_PYMEM_INIT_H +#define Py_INTERNAL_PYMEM_INIT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_pymem.h" + + +/********************************/ +/* the allocators' initializers */ + +extern void * _PyMem_RawMalloc(void *, size_t); +extern void * _PyMem_RawCalloc(void *, size_t, size_t); +extern void * _PyMem_RawRealloc(void *, void *, size_t); +extern void _PyMem_RawFree(void *, void *); +#define PYRAW_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree} + +#ifdef WITH_PYMALLOC +extern void* _PyObject_Malloc(void *, size_t); +extern void* _PyObject_Calloc(void *, size_t, size_t); +extern void _PyObject_Free(void *, void *); +extern void* _PyObject_Realloc(void *, void *, size_t); +# define PYOBJ_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free} +#else +# define PYOBJ_ALLOC PYRAW_ALLOC +#endif // WITH_PYMALLOC + +#define PYMEM_ALLOC PYOBJ_ALLOC + +extern void* _PyMem_DebugRawMalloc(void *, size_t); +extern void* _PyMem_DebugRawCalloc(void *, size_t, size_t); +extern void* _PyMem_DebugRawRealloc(void *, void *, size_t); +extern void _PyMem_DebugRawFree(void *, void *); + +extern void* _PyMem_DebugMalloc(void *, size_t); +extern void* _PyMem_DebugCalloc(void *, size_t, size_t); +extern void* _PyMem_DebugRealloc(void *, void *, size_t); +extern void _PyMem_DebugFree(void *, void *); + +#define PYDBGRAW_ALLOC(runtime) \ + {&(runtime).allocators.debug.raw, _PyMem_DebugRawMalloc, _PyMem_DebugRawCalloc, _PyMem_DebugRawRealloc, _PyMem_DebugRawFree} +#define PYDBGMEM_ALLOC(runtime) \ + {&(runtime).allocators.debug.mem, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} +#define PYDBGOBJ_ALLOC(runtime) \ + {&(runtime).allocators.debug.obj, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} + +extern void * _PyMem_ArenaAlloc(void *, size_t); +extern void _PyMem_ArenaFree(void *, void *, size_t); + +#ifdef Py_DEBUG +# define _pymem_allocators_standard_INIT(runtime) \ + { \ + PYDBGRAW_ALLOC(runtime), \ + PYDBGMEM_ALLOC(runtime), \ + PYDBGOBJ_ALLOC(runtime), \ + } +#else +# define _pymem_allocators_standard_INIT(runtime) \ + { \ + PYRAW_ALLOC, \ + PYMEM_ALLOC, \ + PYOBJ_ALLOC, \ + } +#endif + +#define _pymem_allocators_debug_INIT \ + { \ + {'r', PYRAW_ALLOC}, \ + {'m', PYMEM_ALLOC}, \ + {'o', PYOBJ_ALLOC}, \ + } + +# define _pymem_allocators_obj_arena_INIT \ + { NULL, _PyMem_ArenaAlloc, _PyMem_ArenaFree } + + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_PYMEM_INIT_H diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 9a570b08bc5..0e46693c1f1 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -21,19 +21,23 @@ _Py_IsMainThread(void) } +static inline PyInterpreterState * +_PyInterpreterState_Main(void) +{ + return _PyRuntime.interpreters.main; +} + static inline int _Py_IsMainInterpreter(PyInterpreterState *interp) { - /* Use directly _PyRuntime rather than tstate->interp->runtime, since - this function is used in performance critical code path (ceval) */ - return (interp == _PyRuntime.interpreters.main); + return (interp == _PyInterpreterState_Main()); } static inline const PyConfig * _Py_GetMainConfig(void) { - PyInterpreterState *interp = _PyRuntime.interpreters.main; + PyInterpreterState *interp = _PyInterpreterState_Main(); if (interp == NULL) { return NULL; } @@ -45,7 +49,7 @@ _Py_GetMainConfig(void) static inline int _Py_ThreadCanHandleSignals(PyInterpreterState *interp) { - return (_Py_IsMainThread() && interp == _PyRuntime.interpreters.main); + return (_Py_IsMainThread() && _Py_IsMainInterpreter(interp)); } @@ -60,23 +64,15 @@ _Py_ThreadCanHandlePendingCalls(void) /* Variable and macro for in-line access to current thread and interpreter state */ -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS -PyAPI_FUNC(PyThreadState*) _PyThreadState_GetTSS(void); -#endif - static inline PyThreadState* _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime) { -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - return _PyThreadState_GetTSS(); -#else - return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->gilstate.tstate_current); -#endif + return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->tstate_current); } /* Get the current Python thread state. - Efficient macro reading directly the 'gilstate.tstate_current' atomic + Efficient macro reading directly the 'tstate_current' atomic variable. The macro is unsafe: it does not check for error and it can return NULL. @@ -86,26 +82,23 @@ _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime) static inline PyThreadState* _PyThreadState_GET(void) { -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - return _PyThreadState_GetTSS(); -#else return _PyRuntimeState_GetThreadState(&_PyRuntime); -#endif } -PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalError_TstateNULL(const char *func); - static inline void _Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate) { if (tstate == NULL) { - _Py_FatalError_TstateNULL(func); + _Py_FatalErrorFunc(func, + "the function must be called with the GIL held, " + "after Python initialization and before Python finalization, " + "but the GIL is released (the current Python thread state is NULL)"); } } // Call Py_FatalError() if tstate is NULL #define _Py_EnsureTstateNotNULL(tstate) \ - _Py_EnsureFuncTstateNotNULL(__func__, tstate) + _Py_EnsureFuncTstateNotNULL(__func__, (tstate)) /* Get the current interpreter state. @@ -127,38 +120,47 @@ static inline PyInterpreterState* _PyInterpreterState_GET(void) { // PyThreadState functions +PyAPI_FUNC(void) _PyThreadState_Bind(PyThreadState *tstate); +// We keep this around exclusively for stable ABI compatibility. PyAPI_FUNC(void) _PyThreadState_Init( PyThreadState *tstate); PyAPI_FUNC(void) _PyThreadState_DeleteExcept( _PyRuntimeState *runtime, PyThreadState *tstate); -static inline void -_PyThreadState_PauseTracing(PyThreadState *tstate) -{ - tstate->cframe->use_tracing = 0; -} static inline void -_PyThreadState_ResumeTracing(PyThreadState *tstate) +_PyThreadState_UpdateTracingState(PyThreadState *tstate) { - int use_tracing = (tstate->c_tracefunc != NULL - || tstate->c_profilefunc != NULL); + bool use_tracing = + (tstate->tracing == 0) && + (tstate->c_tracefunc != NULL || tstate->c_profilefunc != NULL); tstate->cframe->use_tracing = (use_tracing ? 255 : 0); } +/* PyThreadState status */ + +#define PyThreadState_UNINITIALIZED 0 +/* Has been initialized to a safe state. + + In order to be effective, this must be set to 0 during or right + after allocation. */ +#define PyThreadState_INITIALIZED 1 +#define PyThreadState_BOUND 2 +#define PyThreadState_UNBOUND 3 + + /* Other */ PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap( - struct _gilstate_runtime_state *gilstate, + _PyRuntimeState *runtime, PyThreadState *newts); PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime); #ifdef HAVE_FORK extern PyStatus _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime); -extern PyStatus _PyGILState_Reinit(_PyRuntimeState *runtime); extern void _PySignal_AfterFork(void); #endif @@ -166,11 +168,17 @@ extern void _PySignal_AfterFork(void); PyAPI_FUNC(int) _PyState_AddModule( PyThreadState *tstate, PyObject* module, - struct PyModuleDef* def); + PyModuleDef* def); PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate); +#define HEAD_LOCK(runtime) \ + PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK) +#define HEAD_UNLOCK(runtime) \ + PyThread_release_lock((runtime)->interpreters.mutex) + + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_pythread.h b/Include/internal/pycore_pythread.h new file mode 100644 index 00000000000..f53921494c1 --- /dev/null +++ b/Include/internal/pycore_pythread.h @@ -0,0 +1,81 @@ +#ifndef Py_INTERNAL_PYTHREAD_H +#define Py_INTERNAL_PYTHREAD_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +#ifndef _POSIX_THREADS +/* This means pthreads are not implemented in libc headers, hence the macro + not present in unistd.h. But they still can be implemented as an external + library (e.g. gnu pth in pthread emulation) */ +# ifdef HAVE_PTHREAD_H +# include /* _POSIX_THREADS */ +# endif +# ifndef _POSIX_THREADS +/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then + enough of the Posix threads package is implemented to support python + threads. + + This is valid for HP-UX 11.23 running on an ia64 system. If needed, add + a check of __ia64 to verify that we're running on an ia64 system instead + of a pa-risc system. +*/ +# ifdef __hpux +# ifdef _SC_THREADS +# define _POSIX_THREADS +# endif +# endif +# endif /* _POSIX_THREADS */ +#endif /* _POSIX_THREADS */ + +#if defined(_POSIX_THREADS) || defined(HAVE_PTHREAD_STUBS) +# define _USE_PTHREADS +#endif + +#if defined(_USE_PTHREADS) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) +// monotonic is supported statically. It doesn't mean it works on runtime. +# define CONDATTR_MONOTONIC +#endif + + +#if defined(HAVE_PTHREAD_STUBS) +// pthread_key +struct py_stub_tls_entry { + bool in_use; + void *value; +}; +#endif + +struct _pythread_runtime_state { + int initialized; + +#ifdef _USE_PTHREADS + // This matches when thread_pthread.h is used. + struct { + /* NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported. */ + pthread_condattr_t *ptr; +# ifdef CONDATTR_MONOTONIC + /* The value to which condattr_monotonic is set. */ + pthread_condattr_t val; +# endif + } _condattr_monotonic; + +#endif // USE_PTHREADS + +#if defined(HAVE_PTHREAD_STUBS) + struct { + struct py_stub_tls_entry tls_entries[PTHREAD_KEYS_MAX]; + } stubs; +#endif +}; + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_PYTHREAD_H */ diff --git a/Include/internal/pycore_range.h b/Include/internal/pycore_range.h new file mode 100644 index 00000000000..bf045ec4fd8 --- /dev/null +++ b/Include/internal/pycore_range.h @@ -0,0 +1,21 @@ +#ifndef Py_INTERNAL_RANGE_H +#define Py_INTERNAL_RANGE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +typedef struct { + PyObject_HEAD + long start; + long step; + long len; +} _PyRangeIterObject; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_RANGE_H */ diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h index 9df833c2701..9ef27079157 100644 --- a/Include/internal/pycore_runtime.h +++ b/Include/internal/pycore_runtime.h @@ -8,45 +8,44 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_atomic.h" /* _Py_atomic_address */ -#include "pycore_gil.h" // struct _gil_runtime_state +#include "pycore_atomic.h" /* _Py_atomic_address */ +#include "pycore_ceval_state.h" // struct _ceval_runtime_state +#include "pycore_dict_state.h" // struct _Py_dict_runtime_state +#include "pycore_dtoa.h" // struct _dtoa_runtime_state +#include "pycore_floatobject.h" // struct _Py_float_runtime_state +#include "pycore_faulthandler.h" // struct _faulthandler_runtime_state +#include "pycore_function.h" // struct _func_runtime_state +#include "pycore_global_objects.h" // struct _Py_global_objects +#include "pycore_import.h" // struct _import_runtime_state +#include "pycore_interp.h" // PyInterpreterState +#include "pycore_parser.h" // struct _parser_runtime_state +#include "pycore_pymem.h" // struct _pymem_allocators +#include "pycore_pyhash.h" // struct pyhash_runtime_state +#include "pycore_pythread.h" // struct _pythread_runtime_state +#include "pycore_obmalloc.h" // struct obmalloc_state +#include "pycore_signal.h" // struct _signals_runtime_state +#include "pycore_time.h" // struct _time_runtime_state +#include "pycore_tracemalloc.h" // struct _tracemalloc_runtime_state +#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids -#define _PY_NSMALLPOSINTS 257 -#define _PY_NSMALLNEGINTS 5 - -// _PyLong_GetZero() and _PyLong_GetOne() must always be available -#if _PY_NSMALLPOSINTS < 2 -# error "_PY_NSMALLPOSINTS must be greater than 1" -#endif +struct _getargs_runtime_state { + PyThread_type_lock mutex; + struct _PyArg_Parser *static_parsers; +}; /* ceval state */ -struct _ceval_runtime_state { - /* Request for checking signals. It is shared by all interpreters (see - bpo-40513). Any thread of any interpreter can receive a signal, but only - the main thread of the main interpreter can handle signals: see - _Py_ThreadCanHandleSignals(). */ - _Py_atomic_int signals_pending; -#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - struct _gil_runtime_state gil; -#endif -}; - /* GIL state */ struct _gilstate_runtime_state { /* bpo-26558: Flag to disable PyGILState_Check(). If set to non-zero, PyGILState_Check() always return 1. */ int check_enabled; - /* Assuming the current thread holds the GIL, this is the - PyThreadState for the current thread. */ - _Py_atomic_address tstate_current; /* The single PyInterpreterState used by this process' GILState implementation */ /* TODO: Given interp_main, it may be possible to kill this ref */ PyInterpreterState *autoInterpreterState; - Py_tss_t autoTSSkey; }; /* Runtime audit hook state */ @@ -57,16 +56,18 @@ typedef struct _Py_AuditHookEntry { void *userData; } _Py_AuditHookEntry; -struct _Py_unicode_runtime_ids { - PyThread_type_lock lock; - // next_index value must be preserved when Py_Initialize()/Py_Finalize() - // is called multiple times: see _PyUnicode_FromId() implementation. - Py_ssize_t next_index; -}; - /* Full Python runtime state */ +/* _PyRuntimeState holds the global state for the CPython runtime. + That data is exposed in the internal API as a static variable (_PyRuntime). + */ typedef struct pyruntimestate { + /* Has been initialized to a safe state. + + In order to be effective, this must be set to 0 during or right + after allocation. */ + int _initialized; + /* Is running Py_PreInitialize()? */ int preinitializing; @@ -86,12 +87,23 @@ typedef struct pyruntimestate { to access it, don't access it directly. */ _Py_atomic_address _finalizing; + struct _pymem_allocators allocators; + struct _obmalloc_state obmalloc; + struct pyhash_runtime_state pyhash_state; + struct _time_runtime_state time; + struct _pythread_runtime_state threads; + struct _signals_runtime_state signals; + struct pyinterpreters { PyThread_type_lock mutex; + /* The linked list of interpreters, newest first. */ PyInterpreterState *head; + /* The runtime's initial interpreter, which has a special role + in the operation of the runtime. It is also often the only + interpreter. */ PyInterpreterState *main; - /* _next_interp_id is an auto-numbered sequence of small - integers. It gets initialized in _PyInterpreterState_Init(), + /* next_id is an auto-numbered sequence of small + integers. It gets initialized in _PyInterpreterState_Enable(), which is called in Py_Initialize(), and used in PyInterpreterState_New(). A negative interpreter ID indicates an error occurred. The main interpreter will @@ -108,19 +120,31 @@ typedef struct pyruntimestate { unsigned long main_thread; - /* Small integers are preallocated in this array so that they - * can be shared. - * The integers that are preallocated are those in the range - *-_PY_NSMALLNEGINTS (inclusive) to _PY_NSMALLPOSINTS (not inclusive). - */ - PyLongObject small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS]; + /* Assuming the current thread holds the GIL, this is the + PyThreadState for the current thread. */ + _Py_atomic_address tstate_current; + /* Used for the thread state bound to the current thread. */ + Py_tss_t autoTSSkey; + + /* Used instead of PyThreadState.trash when there is not current tstate. */ + Py_tss_t trashTSSkey; + + PyWideStringList orig_argv; + + struct _parser_runtime_state parser; #define NEXITFUNCS 32 void (*exitfuncs[NEXITFUNCS])(void); int nexitfuncs; + struct _import_runtime_state imports; struct _ceval_runtime_state ceval; struct _gilstate_runtime_state gilstate; + struct _getargs_runtime_state getargs; + struct _dtoa_runtime_state dtoa; + struct _fileutils_state fileutils; + struct _faulthandler_runtime_state faulthandler; + struct _tracemalloc_runtime_state tracemalloc; PyPreConfig preconfig; @@ -130,15 +154,42 @@ typedef struct pyruntimestate { void *open_code_userdata; _Py_AuditHookEntry *audit_hook_head; - struct _Py_unicode_runtime_ids unicode_ids; + struct _Py_float_runtime_state float_state; + struct _Py_unicode_runtime_state unicode_state; + struct _Py_dict_runtime_state dict_state; + struct _py_func_runtime_state func_state; - // XXX Consolidate globals found via the check-c-globals script. + struct { + /* Used to set PyTypeObject.tp_version_tag */ + // bpo-42745: next_version_tag remains shared by all interpreters + // because of static types. + unsigned int next_version_tag; + } types; + + /* All the objects that are shared by the runtime's interpreters. */ + struct _Py_cached_objects cached_objects; + struct _Py_static_objects static_objects; + + /* The following fields are here to avoid allocation during init. + The data is exposed through _PyRuntimeState pointer fields. + These fields should not be accessed directly outside of init. + + All other _PyRuntimeState pointer fields are populated when + needed and default to NULL. + + For now there are some exceptions to that rule, which require + allocation during init. These will be addressed on a case-by-case + basis. Most notably, we don't pre-allocated the several mutex + (PyThread_type_lock) fields, because on Windows we only ever get + a pointer type. + */ + + /* PyInterpreterState.interpreters.main */ + PyInterpreterState _main_interpreter; } _PyRuntimeState; -#define _PyRuntimeState_INIT \ - {.preinitialized = 0, .core_initialized = 0, .initialized = 0} -/* Note: _PyRuntimeState_INIT sets other fields to 0/NULL */ +/* other API */ PyAPI_DATA(_PyRuntimeState) _PyRuntime; diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h new file mode 100644 index 00000000000..f10dccc0158 --- /dev/null +++ b/Include/internal/pycore_runtime_init.h @@ -0,0 +1,203 @@ +#ifndef Py_INTERNAL_RUNTIME_INIT_H +#define Py_INTERNAL_RUNTIME_INIT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_object.h" +#include "pycore_parser.h" +#include "pycore_pymem_init.h" +#include "pycore_obmalloc_init.h" + + +/* The static initializers defined here should only be used + in the runtime init code (in pystate.c and pylifecycle.c). */ + + +#define _PyRuntimeState_INIT(runtime) \ + { \ + .allocators = { \ + _pymem_allocators_standard_INIT(runtime), \ + _pymem_allocators_debug_INIT, \ + _pymem_allocators_obj_arena_INIT, \ + }, \ + .obmalloc = _obmalloc_state_INIT(runtime.obmalloc), \ + .pyhash_state = pyhash_state_INIT, \ + .signals = _signals_RUNTIME_INIT, \ + .interpreters = { \ + /* This prevents interpreters from getting created \ + until _PyInterpreterState_Enable() is called. */ \ + .next_id = -1, \ + }, \ + /* A TSS key must be initialized with Py_tss_NEEDS_INIT \ + in accordance with the specification. */ \ + .autoTSSkey = Py_tss_NEEDS_INIT, \ + .parser = _parser_runtime_state_INIT, \ + .imports = { \ + .lock = { \ + .mutex = NULL, \ + .thread = PYTHREAD_INVALID_THREAD_ID, \ + .level = 0, \ + }, \ + .find_and_load = { \ + .header = 1, \ + }, \ + }, \ + .ceval = { \ + .perf = _PyEval_RUNTIME_PERF_INIT, \ + }, \ + .gilstate = { \ + .check_enabled = 1, \ + }, \ + .dtoa = _dtoa_runtime_state_INIT(runtime), \ + .fileutils = { \ + .force_ascii = -1, \ + }, \ + .faulthandler = _faulthandler_runtime_state_INIT, \ + .tracemalloc = _tracemalloc_runtime_state_INIT, \ + .float_state = { \ + .float_format = _py_float_format_unknown, \ + .double_format = _py_float_format_unknown, \ + }, \ + .dict_state = { \ + .next_keys_version = 2, \ + }, \ + .func_state = { \ + .next_version = 1, \ + }, \ + .types = { \ + .next_version_tag = 1, \ + }, \ + .static_objects = { \ + .singletons = { \ + .small_ints = _Py_small_ints_INIT, \ + .bytes_empty = _PyBytes_SIMPLE_INIT(0, 0), \ + .bytes_characters = _Py_bytes_characters_INIT, \ + .strings = { \ + .literals = _Py_str_literals_INIT, \ + .identifiers = _Py_str_identifiers_INIT, \ + .ascii = _Py_str_ascii_INIT, \ + .latin1 = _Py_str_latin1_INIT, \ + }, \ + .tuple_empty = { \ + .ob_base = _PyVarObject_IMMORTAL_INIT(&PyTuple_Type, 0) \ + }, \ + .hamt_bitmap_node_empty = { \ + .ob_base = _PyVarObject_IMMORTAL_INIT(&_PyHamt_BitmapNode_Type, 0) \ + }, \ + .context_token_missing = { \ + .ob_base = _PyObject_IMMORTAL_INIT(&_PyContextTokenMissing_Type), \ + }, \ + }, \ + }, \ + ._main_interpreter = _PyInterpreterState_INIT, \ + } + +#ifdef HAVE_DLOPEN +# include +# if HAVE_DECL_RTLD_NOW +# define _Py_DLOPEN_FLAGS RTLD_NOW +# else +# define _Py_DLOPEN_FLAGS RTLD_LAZY +# endif +# define DLOPENFLAGS_INIT .dlopenflags = _Py_DLOPEN_FLAGS, +#else +# define _Py_DLOPEN_FLAGS 0 +# define DLOPENFLAGS_INIT +#endif + +#define _PyInterpreterState_INIT \ + { \ + .id_refcount = -1, \ + DLOPENFLAGS_INIT \ + .ceval = { \ + .recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \ + }, \ + .gc = { \ + .enabled = 1, \ + .generations = { \ + /* .head is set in _PyGC_InitState(). */ \ + { .threshold = 700, }, \ + { .threshold = 10, }, \ + { .threshold = 10, }, \ + }, \ + }, \ + .static_objects = { \ + .singletons = { \ + ._not_used = 1, \ + .hamt_empty = { \ + .ob_base = _PyObject_IMMORTAL_INIT(&_PyHamt_Type), \ + .h_root = (PyHamtNode*)&_Py_SINGLETON(hamt_bitmap_node_empty), \ + }, \ + }, \ + }, \ + ._initial_thread = _PyThreadState_INIT, \ + } + +#define _PyThreadState_INIT \ + { \ + .py_recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \ + .context_ver = 1, \ + } + + +// global objects + +#define _PyLong_DIGIT_INIT(val) \ + { \ + _PyVarObject_IMMORTAL_INIT(&PyLong_Type, \ + ((val) == 0 ? 0 : ((val) > 0 ? 1 : -1))), \ + .ob_digit = { ((val) >= 0 ? (val) : -(val)) }, \ + } + +#define _PyBytes_SIMPLE_INIT(CH, LEN) \ + { \ + _PyVarObject_IMMORTAL_INIT(&PyBytes_Type, (LEN)), \ + .ob_shash = -1, \ + .ob_sval = { (CH) }, \ + } +#define _PyBytes_CHAR_INIT(CH) \ + { \ + _PyBytes_SIMPLE_INIT((CH), 1) \ + } + +#define _PyUnicode_ASCII_BASE_INIT(LITERAL, ASCII) \ + { \ + .ob_base = _PyObject_IMMORTAL_INIT(&PyUnicode_Type), \ + .length = sizeof(LITERAL) - 1, \ + .hash = -1, \ + .state = { \ + .kind = 1, \ + .compact = 1, \ + .ascii = (ASCII), \ + }, \ + } +#define _PyASCIIObject_INIT(LITERAL) \ + { \ + ._ascii = _PyUnicode_ASCII_BASE_INIT((LITERAL), 1), \ + ._data = (LITERAL) \ + } +#define INIT_STR(NAME, LITERAL) \ + ._py_ ## NAME = _PyASCIIObject_INIT(LITERAL) +#define INIT_ID(NAME) \ + ._py_ ## NAME = _PyASCIIObject_INIT(#NAME) +#define _PyUnicode_LATIN1_INIT(LITERAL, UTF8) \ + { \ + ._latin1 = { \ + ._base = _PyUnicode_ASCII_BASE_INIT((LITERAL), 0), \ + .utf8 = (UTF8), \ + .utf8_length = sizeof(UTF8) - 1, \ + }, \ + ._data = (LITERAL), \ + } + +#include "pycore_runtime_init_generated.h" + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_RUNTIME_INIT_H */ diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h new file mode 100644 index 00000000000..fcb613083ff --- /dev/null +++ b/Include/internal/pycore_runtime_init_generated.h @@ -0,0 +1,1491 @@ +#ifndef Py_INTERNAL_RUNTIME_INIT_GENERATED_H +#define Py_INTERNAL_RUNTIME_INIT_GENERATED_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +/* The following is auto-generated by Tools/build/generate_global_objects.py. */ +#define _Py_small_ints_INIT { \ + _PyLong_DIGIT_INIT(-5), \ + _PyLong_DIGIT_INIT(-4), \ + _PyLong_DIGIT_INIT(-3), \ + _PyLong_DIGIT_INIT(-2), \ + _PyLong_DIGIT_INIT(-1), \ + _PyLong_DIGIT_INIT(0), \ + _PyLong_DIGIT_INIT(1), \ + _PyLong_DIGIT_INIT(2), \ + _PyLong_DIGIT_INIT(3), \ + _PyLong_DIGIT_INIT(4), \ + _PyLong_DIGIT_INIT(5), \ + _PyLong_DIGIT_INIT(6), \ + _PyLong_DIGIT_INIT(7), \ + _PyLong_DIGIT_INIT(8), \ + _PyLong_DIGIT_INIT(9), \ + _PyLong_DIGIT_INIT(10), \ + _PyLong_DIGIT_INIT(11), \ + _PyLong_DIGIT_INIT(12), \ + _PyLong_DIGIT_INIT(13), \ + _PyLong_DIGIT_INIT(14), \ + _PyLong_DIGIT_INIT(15), \ + _PyLong_DIGIT_INIT(16), \ + _PyLong_DIGIT_INIT(17), \ + _PyLong_DIGIT_INIT(18), \ + _PyLong_DIGIT_INIT(19), \ + _PyLong_DIGIT_INIT(20), \ + _PyLong_DIGIT_INIT(21), \ + _PyLong_DIGIT_INIT(22), \ + _PyLong_DIGIT_INIT(23), \ + _PyLong_DIGIT_INIT(24), \ + _PyLong_DIGIT_INIT(25), \ + _PyLong_DIGIT_INIT(26), \ + _PyLong_DIGIT_INIT(27), \ + _PyLong_DIGIT_INIT(28), \ + _PyLong_DIGIT_INIT(29), \ + _PyLong_DIGIT_INIT(30), \ + _PyLong_DIGIT_INIT(31), \ + _PyLong_DIGIT_INIT(32), \ + _PyLong_DIGIT_INIT(33), \ + _PyLong_DIGIT_INIT(34), \ + _PyLong_DIGIT_INIT(35), \ + _PyLong_DIGIT_INIT(36), \ + _PyLong_DIGIT_INIT(37), \ + _PyLong_DIGIT_INIT(38), \ + _PyLong_DIGIT_INIT(39), \ + _PyLong_DIGIT_INIT(40), \ + _PyLong_DIGIT_INIT(41), \ + _PyLong_DIGIT_INIT(42), \ + _PyLong_DIGIT_INIT(43), \ + _PyLong_DIGIT_INIT(44), \ + _PyLong_DIGIT_INIT(45), \ + _PyLong_DIGIT_INIT(46), \ + _PyLong_DIGIT_INIT(47), \ + _PyLong_DIGIT_INIT(48), \ + _PyLong_DIGIT_INIT(49), \ + _PyLong_DIGIT_INIT(50), \ + _PyLong_DIGIT_INIT(51), \ + _PyLong_DIGIT_INIT(52), \ + _PyLong_DIGIT_INIT(53), \ + _PyLong_DIGIT_INIT(54), \ + _PyLong_DIGIT_INIT(55), \ + _PyLong_DIGIT_INIT(56), \ + _PyLong_DIGIT_INIT(57), \ + _PyLong_DIGIT_INIT(58), \ + _PyLong_DIGIT_INIT(59), \ + _PyLong_DIGIT_INIT(60), \ + _PyLong_DIGIT_INIT(61), \ + _PyLong_DIGIT_INIT(62), \ + _PyLong_DIGIT_INIT(63), \ + _PyLong_DIGIT_INIT(64), \ + _PyLong_DIGIT_INIT(65), \ + _PyLong_DIGIT_INIT(66), \ + _PyLong_DIGIT_INIT(67), \ + _PyLong_DIGIT_INIT(68), \ + _PyLong_DIGIT_INIT(69), \ + _PyLong_DIGIT_INIT(70), \ + _PyLong_DIGIT_INIT(71), \ + _PyLong_DIGIT_INIT(72), \ + _PyLong_DIGIT_INIT(73), \ + _PyLong_DIGIT_INIT(74), \ + _PyLong_DIGIT_INIT(75), \ + _PyLong_DIGIT_INIT(76), \ + _PyLong_DIGIT_INIT(77), \ + _PyLong_DIGIT_INIT(78), \ + _PyLong_DIGIT_INIT(79), \ + _PyLong_DIGIT_INIT(80), \ + _PyLong_DIGIT_INIT(81), \ + _PyLong_DIGIT_INIT(82), \ + _PyLong_DIGIT_INIT(83), \ + _PyLong_DIGIT_INIT(84), \ + _PyLong_DIGIT_INIT(85), \ + _PyLong_DIGIT_INIT(86), \ + _PyLong_DIGIT_INIT(87), \ + _PyLong_DIGIT_INIT(88), \ + _PyLong_DIGIT_INIT(89), \ + _PyLong_DIGIT_INIT(90), \ + _PyLong_DIGIT_INIT(91), \ + _PyLong_DIGIT_INIT(92), \ + _PyLong_DIGIT_INIT(93), \ + _PyLong_DIGIT_INIT(94), \ + _PyLong_DIGIT_INIT(95), \ + _PyLong_DIGIT_INIT(96), \ + _PyLong_DIGIT_INIT(97), \ + _PyLong_DIGIT_INIT(98), \ + _PyLong_DIGIT_INIT(99), \ + _PyLong_DIGIT_INIT(100), \ + _PyLong_DIGIT_INIT(101), \ + _PyLong_DIGIT_INIT(102), \ + _PyLong_DIGIT_INIT(103), \ + _PyLong_DIGIT_INIT(104), \ + _PyLong_DIGIT_INIT(105), \ + _PyLong_DIGIT_INIT(106), \ + _PyLong_DIGIT_INIT(107), \ + _PyLong_DIGIT_INIT(108), \ + _PyLong_DIGIT_INIT(109), \ + _PyLong_DIGIT_INIT(110), \ + _PyLong_DIGIT_INIT(111), \ + _PyLong_DIGIT_INIT(112), \ + _PyLong_DIGIT_INIT(113), \ + _PyLong_DIGIT_INIT(114), \ + _PyLong_DIGIT_INIT(115), \ + _PyLong_DIGIT_INIT(116), \ + _PyLong_DIGIT_INIT(117), \ + _PyLong_DIGIT_INIT(118), \ + _PyLong_DIGIT_INIT(119), \ + _PyLong_DIGIT_INIT(120), \ + _PyLong_DIGIT_INIT(121), \ + _PyLong_DIGIT_INIT(122), \ + _PyLong_DIGIT_INIT(123), \ + _PyLong_DIGIT_INIT(124), \ + _PyLong_DIGIT_INIT(125), \ + _PyLong_DIGIT_INIT(126), \ + _PyLong_DIGIT_INIT(127), \ + _PyLong_DIGIT_INIT(128), \ + _PyLong_DIGIT_INIT(129), \ + _PyLong_DIGIT_INIT(130), \ + _PyLong_DIGIT_INIT(131), \ + _PyLong_DIGIT_INIT(132), \ + _PyLong_DIGIT_INIT(133), \ + _PyLong_DIGIT_INIT(134), \ + _PyLong_DIGIT_INIT(135), \ + _PyLong_DIGIT_INIT(136), \ + _PyLong_DIGIT_INIT(137), \ + _PyLong_DIGIT_INIT(138), \ + _PyLong_DIGIT_INIT(139), \ + _PyLong_DIGIT_INIT(140), \ + _PyLong_DIGIT_INIT(141), \ + _PyLong_DIGIT_INIT(142), \ + _PyLong_DIGIT_INIT(143), \ + _PyLong_DIGIT_INIT(144), \ + _PyLong_DIGIT_INIT(145), \ + _PyLong_DIGIT_INIT(146), \ + _PyLong_DIGIT_INIT(147), \ + _PyLong_DIGIT_INIT(148), \ + _PyLong_DIGIT_INIT(149), \ + _PyLong_DIGIT_INIT(150), \ + _PyLong_DIGIT_INIT(151), \ + _PyLong_DIGIT_INIT(152), \ + _PyLong_DIGIT_INIT(153), \ + _PyLong_DIGIT_INIT(154), \ + _PyLong_DIGIT_INIT(155), \ + _PyLong_DIGIT_INIT(156), \ + _PyLong_DIGIT_INIT(157), \ + _PyLong_DIGIT_INIT(158), \ + _PyLong_DIGIT_INIT(159), \ + _PyLong_DIGIT_INIT(160), \ + _PyLong_DIGIT_INIT(161), \ + _PyLong_DIGIT_INIT(162), \ + _PyLong_DIGIT_INIT(163), \ + _PyLong_DIGIT_INIT(164), \ + _PyLong_DIGIT_INIT(165), \ + _PyLong_DIGIT_INIT(166), \ + _PyLong_DIGIT_INIT(167), \ + _PyLong_DIGIT_INIT(168), \ + _PyLong_DIGIT_INIT(169), \ + _PyLong_DIGIT_INIT(170), \ + _PyLong_DIGIT_INIT(171), \ + _PyLong_DIGIT_INIT(172), \ + _PyLong_DIGIT_INIT(173), \ + _PyLong_DIGIT_INIT(174), \ + _PyLong_DIGIT_INIT(175), \ + _PyLong_DIGIT_INIT(176), \ + _PyLong_DIGIT_INIT(177), \ + _PyLong_DIGIT_INIT(178), \ + _PyLong_DIGIT_INIT(179), \ + _PyLong_DIGIT_INIT(180), \ + _PyLong_DIGIT_INIT(181), \ + _PyLong_DIGIT_INIT(182), \ + _PyLong_DIGIT_INIT(183), \ + _PyLong_DIGIT_INIT(184), \ + _PyLong_DIGIT_INIT(185), \ + _PyLong_DIGIT_INIT(186), \ + _PyLong_DIGIT_INIT(187), \ + _PyLong_DIGIT_INIT(188), \ + _PyLong_DIGIT_INIT(189), \ + _PyLong_DIGIT_INIT(190), \ + _PyLong_DIGIT_INIT(191), \ + _PyLong_DIGIT_INIT(192), \ + _PyLong_DIGIT_INIT(193), \ + _PyLong_DIGIT_INIT(194), \ + _PyLong_DIGIT_INIT(195), \ + _PyLong_DIGIT_INIT(196), \ + _PyLong_DIGIT_INIT(197), \ + _PyLong_DIGIT_INIT(198), \ + _PyLong_DIGIT_INIT(199), \ + _PyLong_DIGIT_INIT(200), \ + _PyLong_DIGIT_INIT(201), \ + _PyLong_DIGIT_INIT(202), \ + _PyLong_DIGIT_INIT(203), \ + _PyLong_DIGIT_INIT(204), \ + _PyLong_DIGIT_INIT(205), \ + _PyLong_DIGIT_INIT(206), \ + _PyLong_DIGIT_INIT(207), \ + _PyLong_DIGIT_INIT(208), \ + _PyLong_DIGIT_INIT(209), \ + _PyLong_DIGIT_INIT(210), \ + _PyLong_DIGIT_INIT(211), \ + _PyLong_DIGIT_INIT(212), \ + _PyLong_DIGIT_INIT(213), \ + _PyLong_DIGIT_INIT(214), \ + _PyLong_DIGIT_INIT(215), \ + _PyLong_DIGIT_INIT(216), \ + _PyLong_DIGIT_INIT(217), \ + _PyLong_DIGIT_INIT(218), \ + _PyLong_DIGIT_INIT(219), \ + _PyLong_DIGIT_INIT(220), \ + _PyLong_DIGIT_INIT(221), \ + _PyLong_DIGIT_INIT(222), \ + _PyLong_DIGIT_INIT(223), \ + _PyLong_DIGIT_INIT(224), \ + _PyLong_DIGIT_INIT(225), \ + _PyLong_DIGIT_INIT(226), \ + _PyLong_DIGIT_INIT(227), \ + _PyLong_DIGIT_INIT(228), \ + _PyLong_DIGIT_INIT(229), \ + _PyLong_DIGIT_INIT(230), \ + _PyLong_DIGIT_INIT(231), \ + _PyLong_DIGIT_INIT(232), \ + _PyLong_DIGIT_INIT(233), \ + _PyLong_DIGIT_INIT(234), \ + _PyLong_DIGIT_INIT(235), \ + _PyLong_DIGIT_INIT(236), \ + _PyLong_DIGIT_INIT(237), \ + _PyLong_DIGIT_INIT(238), \ + _PyLong_DIGIT_INIT(239), \ + _PyLong_DIGIT_INIT(240), \ + _PyLong_DIGIT_INIT(241), \ + _PyLong_DIGIT_INIT(242), \ + _PyLong_DIGIT_INIT(243), \ + _PyLong_DIGIT_INIT(244), \ + _PyLong_DIGIT_INIT(245), \ + _PyLong_DIGIT_INIT(246), \ + _PyLong_DIGIT_INIT(247), \ + _PyLong_DIGIT_INIT(248), \ + _PyLong_DIGIT_INIT(249), \ + _PyLong_DIGIT_INIT(250), \ + _PyLong_DIGIT_INIT(251), \ + _PyLong_DIGIT_INIT(252), \ + _PyLong_DIGIT_INIT(253), \ + _PyLong_DIGIT_INIT(254), \ + _PyLong_DIGIT_INIT(255), \ + _PyLong_DIGIT_INIT(256), \ +} + +#define _Py_bytes_characters_INIT { \ + _PyBytes_CHAR_INIT(0), \ + _PyBytes_CHAR_INIT(1), \ + _PyBytes_CHAR_INIT(2), \ + _PyBytes_CHAR_INIT(3), \ + _PyBytes_CHAR_INIT(4), \ + _PyBytes_CHAR_INIT(5), \ + _PyBytes_CHAR_INIT(6), \ + _PyBytes_CHAR_INIT(7), \ + _PyBytes_CHAR_INIT(8), \ + _PyBytes_CHAR_INIT(9), \ + _PyBytes_CHAR_INIT(10), \ + _PyBytes_CHAR_INIT(11), \ + _PyBytes_CHAR_INIT(12), \ + _PyBytes_CHAR_INIT(13), \ + _PyBytes_CHAR_INIT(14), \ + _PyBytes_CHAR_INIT(15), \ + _PyBytes_CHAR_INIT(16), \ + _PyBytes_CHAR_INIT(17), \ + _PyBytes_CHAR_INIT(18), \ + _PyBytes_CHAR_INIT(19), \ + _PyBytes_CHAR_INIT(20), \ + _PyBytes_CHAR_INIT(21), \ + _PyBytes_CHAR_INIT(22), \ + _PyBytes_CHAR_INIT(23), \ + _PyBytes_CHAR_INIT(24), \ + _PyBytes_CHAR_INIT(25), \ + _PyBytes_CHAR_INIT(26), \ + _PyBytes_CHAR_INIT(27), \ + _PyBytes_CHAR_INIT(28), \ + _PyBytes_CHAR_INIT(29), \ + _PyBytes_CHAR_INIT(30), \ + _PyBytes_CHAR_INIT(31), \ + _PyBytes_CHAR_INIT(32), \ + _PyBytes_CHAR_INIT(33), \ + _PyBytes_CHAR_INIT(34), \ + _PyBytes_CHAR_INIT(35), \ + _PyBytes_CHAR_INIT(36), \ + _PyBytes_CHAR_INIT(37), \ + _PyBytes_CHAR_INIT(38), \ + _PyBytes_CHAR_INIT(39), \ + _PyBytes_CHAR_INIT(40), \ + _PyBytes_CHAR_INIT(41), \ + _PyBytes_CHAR_INIT(42), \ + _PyBytes_CHAR_INIT(43), \ + _PyBytes_CHAR_INIT(44), \ + _PyBytes_CHAR_INIT(45), \ + _PyBytes_CHAR_INIT(46), \ + _PyBytes_CHAR_INIT(47), \ + _PyBytes_CHAR_INIT(48), \ + _PyBytes_CHAR_INIT(49), \ + _PyBytes_CHAR_INIT(50), \ + _PyBytes_CHAR_INIT(51), \ + _PyBytes_CHAR_INIT(52), \ + _PyBytes_CHAR_INIT(53), \ + _PyBytes_CHAR_INIT(54), \ + _PyBytes_CHAR_INIT(55), \ + _PyBytes_CHAR_INIT(56), \ + _PyBytes_CHAR_INIT(57), \ + _PyBytes_CHAR_INIT(58), \ + _PyBytes_CHAR_INIT(59), \ + _PyBytes_CHAR_INIT(60), \ + _PyBytes_CHAR_INIT(61), \ + _PyBytes_CHAR_INIT(62), \ + _PyBytes_CHAR_INIT(63), \ + _PyBytes_CHAR_INIT(64), \ + _PyBytes_CHAR_INIT(65), \ + _PyBytes_CHAR_INIT(66), \ + _PyBytes_CHAR_INIT(67), \ + _PyBytes_CHAR_INIT(68), \ + _PyBytes_CHAR_INIT(69), \ + _PyBytes_CHAR_INIT(70), \ + _PyBytes_CHAR_INIT(71), \ + _PyBytes_CHAR_INIT(72), \ + _PyBytes_CHAR_INIT(73), \ + _PyBytes_CHAR_INIT(74), \ + _PyBytes_CHAR_INIT(75), \ + _PyBytes_CHAR_INIT(76), \ + _PyBytes_CHAR_INIT(77), \ + _PyBytes_CHAR_INIT(78), \ + _PyBytes_CHAR_INIT(79), \ + _PyBytes_CHAR_INIT(80), \ + _PyBytes_CHAR_INIT(81), \ + _PyBytes_CHAR_INIT(82), \ + _PyBytes_CHAR_INIT(83), \ + _PyBytes_CHAR_INIT(84), \ + _PyBytes_CHAR_INIT(85), \ + _PyBytes_CHAR_INIT(86), \ + _PyBytes_CHAR_INIT(87), \ + _PyBytes_CHAR_INIT(88), \ + _PyBytes_CHAR_INIT(89), \ + _PyBytes_CHAR_INIT(90), \ + _PyBytes_CHAR_INIT(91), \ + _PyBytes_CHAR_INIT(92), \ + _PyBytes_CHAR_INIT(93), \ + _PyBytes_CHAR_INIT(94), \ + _PyBytes_CHAR_INIT(95), \ + _PyBytes_CHAR_INIT(96), \ + _PyBytes_CHAR_INIT(97), \ + _PyBytes_CHAR_INIT(98), \ + _PyBytes_CHAR_INIT(99), \ + _PyBytes_CHAR_INIT(100), \ + _PyBytes_CHAR_INIT(101), \ + _PyBytes_CHAR_INIT(102), \ + _PyBytes_CHAR_INIT(103), \ + _PyBytes_CHAR_INIT(104), \ + _PyBytes_CHAR_INIT(105), \ + _PyBytes_CHAR_INIT(106), \ + _PyBytes_CHAR_INIT(107), \ + _PyBytes_CHAR_INIT(108), \ + _PyBytes_CHAR_INIT(109), \ + _PyBytes_CHAR_INIT(110), \ + _PyBytes_CHAR_INIT(111), \ + _PyBytes_CHAR_INIT(112), \ + _PyBytes_CHAR_INIT(113), \ + _PyBytes_CHAR_INIT(114), \ + _PyBytes_CHAR_INIT(115), \ + _PyBytes_CHAR_INIT(116), \ + _PyBytes_CHAR_INIT(117), \ + _PyBytes_CHAR_INIT(118), \ + _PyBytes_CHAR_INIT(119), \ + _PyBytes_CHAR_INIT(120), \ + _PyBytes_CHAR_INIT(121), \ + _PyBytes_CHAR_INIT(122), \ + _PyBytes_CHAR_INIT(123), \ + _PyBytes_CHAR_INIT(124), \ + _PyBytes_CHAR_INIT(125), \ + _PyBytes_CHAR_INIT(126), \ + _PyBytes_CHAR_INIT(127), \ + _PyBytes_CHAR_INIT(128), \ + _PyBytes_CHAR_INIT(129), \ + _PyBytes_CHAR_INIT(130), \ + _PyBytes_CHAR_INIT(131), \ + _PyBytes_CHAR_INIT(132), \ + _PyBytes_CHAR_INIT(133), \ + _PyBytes_CHAR_INIT(134), \ + _PyBytes_CHAR_INIT(135), \ + _PyBytes_CHAR_INIT(136), \ + _PyBytes_CHAR_INIT(137), \ + _PyBytes_CHAR_INIT(138), \ + _PyBytes_CHAR_INIT(139), \ + _PyBytes_CHAR_INIT(140), \ + _PyBytes_CHAR_INIT(141), \ + _PyBytes_CHAR_INIT(142), \ + _PyBytes_CHAR_INIT(143), \ + _PyBytes_CHAR_INIT(144), \ + _PyBytes_CHAR_INIT(145), \ + _PyBytes_CHAR_INIT(146), \ + _PyBytes_CHAR_INIT(147), \ + _PyBytes_CHAR_INIT(148), \ + _PyBytes_CHAR_INIT(149), \ + _PyBytes_CHAR_INIT(150), \ + _PyBytes_CHAR_INIT(151), \ + _PyBytes_CHAR_INIT(152), \ + _PyBytes_CHAR_INIT(153), \ + _PyBytes_CHAR_INIT(154), \ + _PyBytes_CHAR_INIT(155), \ + _PyBytes_CHAR_INIT(156), \ + _PyBytes_CHAR_INIT(157), \ + _PyBytes_CHAR_INIT(158), \ + _PyBytes_CHAR_INIT(159), \ + _PyBytes_CHAR_INIT(160), \ + _PyBytes_CHAR_INIT(161), \ + _PyBytes_CHAR_INIT(162), \ + _PyBytes_CHAR_INIT(163), \ + _PyBytes_CHAR_INIT(164), \ + _PyBytes_CHAR_INIT(165), \ + _PyBytes_CHAR_INIT(166), \ + _PyBytes_CHAR_INIT(167), \ + _PyBytes_CHAR_INIT(168), \ + _PyBytes_CHAR_INIT(169), \ + _PyBytes_CHAR_INIT(170), \ + _PyBytes_CHAR_INIT(171), \ + _PyBytes_CHAR_INIT(172), \ + _PyBytes_CHAR_INIT(173), \ + _PyBytes_CHAR_INIT(174), \ + _PyBytes_CHAR_INIT(175), \ + _PyBytes_CHAR_INIT(176), \ + _PyBytes_CHAR_INIT(177), \ + _PyBytes_CHAR_INIT(178), \ + _PyBytes_CHAR_INIT(179), \ + _PyBytes_CHAR_INIT(180), \ + _PyBytes_CHAR_INIT(181), \ + _PyBytes_CHAR_INIT(182), \ + _PyBytes_CHAR_INIT(183), \ + _PyBytes_CHAR_INIT(184), \ + _PyBytes_CHAR_INIT(185), \ + _PyBytes_CHAR_INIT(186), \ + _PyBytes_CHAR_INIT(187), \ + _PyBytes_CHAR_INIT(188), \ + _PyBytes_CHAR_INIT(189), \ + _PyBytes_CHAR_INIT(190), \ + _PyBytes_CHAR_INIT(191), \ + _PyBytes_CHAR_INIT(192), \ + _PyBytes_CHAR_INIT(193), \ + _PyBytes_CHAR_INIT(194), \ + _PyBytes_CHAR_INIT(195), \ + _PyBytes_CHAR_INIT(196), \ + _PyBytes_CHAR_INIT(197), \ + _PyBytes_CHAR_INIT(198), \ + _PyBytes_CHAR_INIT(199), \ + _PyBytes_CHAR_INIT(200), \ + _PyBytes_CHAR_INIT(201), \ + _PyBytes_CHAR_INIT(202), \ + _PyBytes_CHAR_INIT(203), \ + _PyBytes_CHAR_INIT(204), \ + _PyBytes_CHAR_INIT(205), \ + _PyBytes_CHAR_INIT(206), \ + _PyBytes_CHAR_INIT(207), \ + _PyBytes_CHAR_INIT(208), \ + _PyBytes_CHAR_INIT(209), \ + _PyBytes_CHAR_INIT(210), \ + _PyBytes_CHAR_INIT(211), \ + _PyBytes_CHAR_INIT(212), \ + _PyBytes_CHAR_INIT(213), \ + _PyBytes_CHAR_INIT(214), \ + _PyBytes_CHAR_INIT(215), \ + _PyBytes_CHAR_INIT(216), \ + _PyBytes_CHAR_INIT(217), \ + _PyBytes_CHAR_INIT(218), \ + _PyBytes_CHAR_INIT(219), \ + _PyBytes_CHAR_INIT(220), \ + _PyBytes_CHAR_INIT(221), \ + _PyBytes_CHAR_INIT(222), \ + _PyBytes_CHAR_INIT(223), \ + _PyBytes_CHAR_INIT(224), \ + _PyBytes_CHAR_INIT(225), \ + _PyBytes_CHAR_INIT(226), \ + _PyBytes_CHAR_INIT(227), \ + _PyBytes_CHAR_INIT(228), \ + _PyBytes_CHAR_INIT(229), \ + _PyBytes_CHAR_INIT(230), \ + _PyBytes_CHAR_INIT(231), \ + _PyBytes_CHAR_INIT(232), \ + _PyBytes_CHAR_INIT(233), \ + _PyBytes_CHAR_INIT(234), \ + _PyBytes_CHAR_INIT(235), \ + _PyBytes_CHAR_INIT(236), \ + _PyBytes_CHAR_INIT(237), \ + _PyBytes_CHAR_INIT(238), \ + _PyBytes_CHAR_INIT(239), \ + _PyBytes_CHAR_INIT(240), \ + _PyBytes_CHAR_INIT(241), \ + _PyBytes_CHAR_INIT(242), \ + _PyBytes_CHAR_INIT(243), \ + _PyBytes_CHAR_INIT(244), \ + _PyBytes_CHAR_INIT(245), \ + _PyBytes_CHAR_INIT(246), \ + _PyBytes_CHAR_INIT(247), \ + _PyBytes_CHAR_INIT(248), \ + _PyBytes_CHAR_INIT(249), \ + _PyBytes_CHAR_INIT(250), \ + _PyBytes_CHAR_INIT(251), \ + _PyBytes_CHAR_INIT(252), \ + _PyBytes_CHAR_INIT(253), \ + _PyBytes_CHAR_INIT(254), \ + _PyBytes_CHAR_INIT(255), \ +} + +#define _Py_str_literals_INIT { \ + INIT_STR(anon_dictcomp, ""), \ + INIT_STR(anon_genexpr, ""), \ + INIT_STR(anon_lambda, ""), \ + INIT_STR(anon_listcomp, ""), \ + INIT_STR(anon_module, ""), \ + INIT_STR(anon_setcomp, ""), \ + INIT_STR(anon_string, ""), \ + INIT_STR(anon_unknown, ""), \ + INIT_STR(close_br, "}"), \ + INIT_STR(dbl_close_br, "}}"), \ + INIT_STR(dbl_open_br, "{{"), \ + INIT_STR(dbl_percent, "%%"), \ + INIT_STR(dot, "."), \ + INIT_STR(dot_locals, "."), \ + INIT_STR(empty, ""), \ + INIT_STR(json_decoder, "json.decoder"), \ + INIT_STR(list_err, "list index out of range"), \ + INIT_STR(newline, "\n"), \ + INIT_STR(open_br, "{"), \ + INIT_STR(percent, "%"), \ + INIT_STR(shim_name, ""), \ + INIT_STR(utf_8, "utf-8"), \ +} + +#define _Py_str_identifiers_INIT { \ + INIT_ID(CANCELLED), \ + INIT_ID(FINISHED), \ + INIT_ID(False), \ + INIT_ID(JSONDecodeError), \ + INIT_ID(PENDING), \ + INIT_ID(Py_Repr), \ + INIT_ID(TextIOWrapper), \ + INIT_ID(True), \ + INIT_ID(WarningMessage), \ + INIT_ID(_), \ + INIT_ID(__IOBase_closed), \ + INIT_ID(__abc_tpflags__), \ + INIT_ID(__abs__), \ + INIT_ID(__abstractmethods__), \ + INIT_ID(__add__), \ + INIT_ID(__aenter__), \ + INIT_ID(__aexit__), \ + INIT_ID(__aiter__), \ + INIT_ID(__all__), \ + INIT_ID(__and__), \ + INIT_ID(__anext__), \ + INIT_ID(__annotations__), \ + INIT_ID(__args__), \ + INIT_ID(__asyncio_running_event_loop__), \ + INIT_ID(__await__), \ + INIT_ID(__bases__), \ + INIT_ID(__bool__), \ + INIT_ID(__build_class__), \ + INIT_ID(__builtins__), \ + INIT_ID(__bytes__), \ + INIT_ID(__call__), \ + INIT_ID(__cantrace__), \ + INIT_ID(__class__), \ + INIT_ID(__class_getitem__), \ + INIT_ID(__classcell__), \ + INIT_ID(__complex__), \ + INIT_ID(__contains__), \ + INIT_ID(__copy__), \ + INIT_ID(__ctypes_from_outparam__), \ + INIT_ID(__del__), \ + INIT_ID(__delattr__), \ + INIT_ID(__delete__), \ + INIT_ID(__delitem__), \ + INIT_ID(__dict__), \ + INIT_ID(__dictoffset__), \ + INIT_ID(__dir__), \ + INIT_ID(__divmod__), \ + INIT_ID(__doc__), \ + INIT_ID(__enter__), \ + INIT_ID(__eq__), \ + INIT_ID(__exit__), \ + INIT_ID(__file__), \ + INIT_ID(__float__), \ + INIT_ID(__floordiv__), \ + INIT_ID(__format__), \ + INIT_ID(__fspath__), \ + INIT_ID(__ge__), \ + INIT_ID(__get__), \ + INIT_ID(__getattr__), \ + INIT_ID(__getattribute__), \ + INIT_ID(__getinitargs__), \ + INIT_ID(__getitem__), \ + INIT_ID(__getnewargs__), \ + INIT_ID(__getnewargs_ex__), \ + INIT_ID(__getstate__), \ + INIT_ID(__gt__), \ + INIT_ID(__hash__), \ + INIT_ID(__iadd__), \ + INIT_ID(__iand__), \ + INIT_ID(__ifloordiv__), \ + INIT_ID(__ilshift__), \ + INIT_ID(__imatmul__), \ + INIT_ID(__imod__), \ + INIT_ID(__import__), \ + INIT_ID(__imul__), \ + INIT_ID(__index__), \ + INIT_ID(__init__), \ + INIT_ID(__init_subclass__), \ + INIT_ID(__instancecheck__), \ + INIT_ID(__int__), \ + INIT_ID(__invert__), \ + INIT_ID(__ior__), \ + INIT_ID(__ipow__), \ + INIT_ID(__irshift__), \ + INIT_ID(__isabstractmethod__), \ + INIT_ID(__isub__), \ + INIT_ID(__iter__), \ + INIT_ID(__itruediv__), \ + INIT_ID(__ixor__), \ + INIT_ID(__le__), \ + INIT_ID(__len__), \ + INIT_ID(__length_hint__), \ + INIT_ID(__lltrace__), \ + INIT_ID(__loader__), \ + INIT_ID(__lshift__), \ + INIT_ID(__lt__), \ + INIT_ID(__main__), \ + INIT_ID(__matmul__), \ + INIT_ID(__missing__), \ + INIT_ID(__mod__), \ + INIT_ID(__module__), \ + INIT_ID(__mro_entries__), \ + INIT_ID(__mul__), \ + INIT_ID(__name__), \ + INIT_ID(__ne__), \ + INIT_ID(__neg__), \ + INIT_ID(__new__), \ + INIT_ID(__newobj__), \ + INIT_ID(__newobj_ex__), \ + INIT_ID(__next__), \ + INIT_ID(__notes__), \ + INIT_ID(__or__), \ + INIT_ID(__orig_class__), \ + INIT_ID(__origin__), \ + INIT_ID(__package__), \ + INIT_ID(__parameters__), \ + INIT_ID(__path__), \ + INIT_ID(__pos__), \ + INIT_ID(__pow__), \ + INIT_ID(__prepare__), \ + INIT_ID(__qualname__), \ + INIT_ID(__radd__), \ + INIT_ID(__rand__), \ + INIT_ID(__rdivmod__), \ + INIT_ID(__reduce__), \ + INIT_ID(__reduce_ex__), \ + INIT_ID(__repr__), \ + INIT_ID(__reversed__), \ + INIT_ID(__rfloordiv__), \ + INIT_ID(__rlshift__), \ + INIT_ID(__rmatmul__), \ + INIT_ID(__rmod__), \ + INIT_ID(__rmul__), \ + INIT_ID(__ror__), \ + INIT_ID(__round__), \ + INIT_ID(__rpow__), \ + INIT_ID(__rrshift__), \ + INIT_ID(__rshift__), \ + INIT_ID(__rsub__), \ + INIT_ID(__rtruediv__), \ + INIT_ID(__rxor__), \ + INIT_ID(__set__), \ + INIT_ID(__set_name__), \ + INIT_ID(__setattr__), \ + INIT_ID(__setitem__), \ + INIT_ID(__setstate__), \ + INIT_ID(__sizeof__), \ + INIT_ID(__slotnames__), \ + INIT_ID(__slots__), \ + INIT_ID(__spec__), \ + INIT_ID(__str__), \ + INIT_ID(__sub__), \ + INIT_ID(__subclasscheck__), \ + INIT_ID(__subclasshook__), \ + INIT_ID(__truediv__), \ + INIT_ID(__trunc__), \ + INIT_ID(__typing_is_unpacked_typevartuple__), \ + INIT_ID(__typing_prepare_subst__), \ + INIT_ID(__typing_subst__), \ + INIT_ID(__typing_unpacked_tuple_args__), \ + INIT_ID(__warningregistry__), \ + INIT_ID(__weaklistoffset__), \ + INIT_ID(__weakref__), \ + INIT_ID(__xor__), \ + INIT_ID(_abc_impl), \ + INIT_ID(_abstract_), \ + INIT_ID(_active), \ + INIT_ID(_annotation), \ + INIT_ID(_anonymous_), \ + INIT_ID(_argtypes_), \ + INIT_ID(_as_parameter_), \ + INIT_ID(_asyncio_future_blocking), \ + INIT_ID(_blksize), \ + INIT_ID(_bootstrap), \ + INIT_ID(_check_retval_), \ + INIT_ID(_dealloc_warn), \ + INIT_ID(_feature_version), \ + INIT_ID(_fields_), \ + INIT_ID(_finalizing), \ + INIT_ID(_find_and_load), \ + INIT_ID(_fix_up_module), \ + INIT_ID(_flags_), \ + INIT_ID(_get_sourcefile), \ + INIT_ID(_handle_fromlist), \ + INIT_ID(_initializing), \ + INIT_ID(_is_text_encoding), \ + INIT_ID(_length_), \ + INIT_ID(_limbo), \ + INIT_ID(_lock_unlock_module), \ + INIT_ID(_loop), \ + INIT_ID(_needs_com_addref_), \ + INIT_ID(_pack_), \ + INIT_ID(_restype_), \ + INIT_ID(_showwarnmsg), \ + INIT_ID(_shutdown), \ + INIT_ID(_slotnames), \ + INIT_ID(_strptime_datetime), \ + INIT_ID(_swappedbytes_), \ + INIT_ID(_type_), \ + INIT_ID(_uninitialized_submodules), \ + INIT_ID(_warn_unawaited_coroutine), \ + INIT_ID(_xoptions), \ + INIT_ID(a), \ + INIT_ID(abs_tol), \ + INIT_ID(access), \ + INIT_ID(add), \ + INIT_ID(add_done_callback), \ + INIT_ID(after_in_child), \ + INIT_ID(after_in_parent), \ + INIT_ID(aggregate_class), \ + INIT_ID(append), \ + INIT_ID(argdefs), \ + INIT_ID(arguments), \ + INIT_ID(argv), \ + INIT_ID(as_integer_ratio), \ + INIT_ID(ast), \ + INIT_ID(attribute), \ + INIT_ID(authorizer_callback), \ + INIT_ID(autocommit), \ + INIT_ID(b), \ + INIT_ID(backtick), \ + INIT_ID(base), \ + INIT_ID(before), \ + INIT_ID(big), \ + INIT_ID(binary_form), \ + INIT_ID(block), \ + INIT_ID(buffer), \ + INIT_ID(buffer_callback), \ + INIT_ID(buffer_size), \ + INIT_ID(buffering), \ + INIT_ID(buffers), \ + INIT_ID(bufsize), \ + INIT_ID(builtins), \ + INIT_ID(byteorder), \ + INIT_ID(bytes), \ + INIT_ID(bytes_per_sep), \ + INIT_ID(c), \ + INIT_ID(c_call), \ + INIT_ID(c_exception), \ + INIT_ID(c_return), \ + INIT_ID(cached_statements), \ + INIT_ID(cadata), \ + INIT_ID(cafile), \ + INIT_ID(call), \ + INIT_ID(call_exception_handler), \ + INIT_ID(call_soon), \ + INIT_ID(cancel), \ + INIT_ID(capath), \ + INIT_ID(category), \ + INIT_ID(cb_type), \ + INIT_ID(certfile), \ + INIT_ID(check_same_thread), \ + INIT_ID(clear), \ + INIT_ID(close), \ + INIT_ID(closed), \ + INIT_ID(closefd), \ + INIT_ID(closure), \ + INIT_ID(co_argcount), \ + INIT_ID(co_cellvars), \ + INIT_ID(co_code), \ + INIT_ID(co_consts), \ + INIT_ID(co_exceptiontable), \ + INIT_ID(co_filename), \ + INIT_ID(co_firstlineno), \ + INIT_ID(co_flags), \ + INIT_ID(co_freevars), \ + INIT_ID(co_kwonlyargcount), \ + INIT_ID(co_linetable), \ + INIT_ID(co_name), \ + INIT_ID(co_names), \ + INIT_ID(co_nlocals), \ + INIT_ID(co_posonlyargcount), \ + INIT_ID(co_qualname), \ + INIT_ID(co_stacksize), \ + INIT_ID(co_varnames), \ + INIT_ID(code), \ + INIT_ID(command), \ + INIT_ID(comment_factory), \ + INIT_ID(consts), \ + INIT_ID(context), \ + INIT_ID(cookie), \ + INIT_ID(copy), \ + INIT_ID(copyreg), \ + INIT_ID(coro), \ + INIT_ID(count), \ + INIT_ID(cwd), \ + INIT_ID(d), \ + INIT_ID(data), \ + INIT_ID(database), \ + INIT_ID(decode), \ + INIT_ID(decoder), \ + INIT_ID(default), \ + INIT_ID(defaultaction), \ + INIT_ID(delete), \ + INIT_ID(depth), \ + INIT_ID(detect_types), \ + INIT_ID(deterministic), \ + INIT_ID(device), \ + INIT_ID(dict), \ + INIT_ID(dictcomp), \ + INIT_ID(difference_update), \ + INIT_ID(digest), \ + INIT_ID(digest_size), \ + INIT_ID(digestmod), \ + INIT_ID(dir_fd), \ + INIT_ID(discard), \ + INIT_ID(dispatch_table), \ + INIT_ID(displayhook), \ + INIT_ID(dklen), \ + INIT_ID(doc), \ + INIT_ID(dont_inherit), \ + INIT_ID(dst), \ + INIT_ID(dst_dir_fd), \ + INIT_ID(duration), \ + INIT_ID(e), \ + INIT_ID(effective_ids), \ + INIT_ID(element_factory), \ + INIT_ID(encode), \ + INIT_ID(encoding), \ + INIT_ID(end), \ + INIT_ID(end_lineno), \ + INIT_ID(end_offset), \ + INIT_ID(endpos), \ + INIT_ID(env), \ + INIT_ID(errors), \ + INIT_ID(event), \ + INIT_ID(eventmask), \ + INIT_ID(exc_type), \ + INIT_ID(exc_value), \ + INIT_ID(excepthook), \ + INIT_ID(exception), \ + INIT_ID(exp), \ + INIT_ID(extend), \ + INIT_ID(facility), \ + INIT_ID(factory), \ + INIT_ID(false), \ + INIT_ID(family), \ + INIT_ID(fanout), \ + INIT_ID(fd), \ + INIT_ID(fd2), \ + INIT_ID(fdel), \ + INIT_ID(fget), \ + INIT_ID(file), \ + INIT_ID(file_actions), \ + INIT_ID(filename), \ + INIT_ID(fileno), \ + INIT_ID(filepath), \ + INIT_ID(fillvalue), \ + INIT_ID(filters), \ + INIT_ID(final), \ + INIT_ID(find_class), \ + INIT_ID(fix_imports), \ + INIT_ID(flags), \ + INIT_ID(flush), \ + INIT_ID(follow_symlinks), \ + INIT_ID(format), \ + INIT_ID(frequency), \ + INIT_ID(from_param), \ + INIT_ID(fromlist), \ + INIT_ID(fromtimestamp), \ + INIT_ID(fromutc), \ + INIT_ID(fset), \ + INIT_ID(func), \ + INIT_ID(future), \ + INIT_ID(generation), \ + INIT_ID(genexpr), \ + INIT_ID(get), \ + INIT_ID(get_debug), \ + INIT_ID(get_event_loop), \ + INIT_ID(get_loop), \ + INIT_ID(get_source), \ + INIT_ID(getattr), \ + INIT_ID(getstate), \ + INIT_ID(gid), \ + INIT_ID(globals), \ + INIT_ID(groupindex), \ + INIT_ID(groups), \ + INIT_ID(handle), \ + INIT_ID(hash_name), \ + INIT_ID(header), \ + INIT_ID(headers), \ + INIT_ID(hi), \ + INIT_ID(hook), \ + INIT_ID(id), \ + INIT_ID(ident), \ + INIT_ID(ignore), \ + INIT_ID(imag), \ + INIT_ID(importlib), \ + INIT_ID(in_fd), \ + INIT_ID(incoming), \ + INIT_ID(indexgroup), \ + INIT_ID(inf), \ + INIT_ID(inheritable), \ + INIT_ID(initial), \ + INIT_ID(initial_bytes), \ + INIT_ID(initial_value), \ + INIT_ID(initval), \ + INIT_ID(inner_size), \ + INIT_ID(input), \ + INIT_ID(insert_comments), \ + INIT_ID(insert_pis), \ + INIT_ID(instructions), \ + INIT_ID(intern), \ + INIT_ID(intersection), \ + INIT_ID(isatty), \ + INIT_ID(isinstance), \ + INIT_ID(isoformat), \ + INIT_ID(isolation_level), \ + INIT_ID(istext), \ + INIT_ID(item), \ + INIT_ID(items), \ + INIT_ID(iter), \ + INIT_ID(iterable), \ + INIT_ID(iterations), \ + INIT_ID(join), \ + INIT_ID(jump), \ + INIT_ID(keepends), \ + INIT_ID(key), \ + INIT_ID(keyfile), \ + INIT_ID(keys), \ + INIT_ID(kind), \ + INIT_ID(kw), \ + INIT_ID(kw1), \ + INIT_ID(kw2), \ + INIT_ID(lambda), \ + INIT_ID(last), \ + INIT_ID(last_node), \ + INIT_ID(last_traceback), \ + INIT_ID(last_type), \ + INIT_ID(last_value), \ + INIT_ID(latin1), \ + INIT_ID(leaf_size), \ + INIT_ID(len), \ + INIT_ID(length), \ + INIT_ID(level), \ + INIT_ID(limit), \ + INIT_ID(line), \ + INIT_ID(line_buffering), \ + INIT_ID(lineno), \ + INIT_ID(listcomp), \ + INIT_ID(little), \ + INIT_ID(lo), \ + INIT_ID(locale), \ + INIT_ID(locals), \ + INIT_ID(logoption), \ + INIT_ID(loop), \ + INIT_ID(mapping), \ + INIT_ID(match), \ + INIT_ID(max_length), \ + INIT_ID(maxdigits), \ + INIT_ID(maxevents), \ + INIT_ID(maxmem), \ + INIT_ID(maxsplit), \ + INIT_ID(maxvalue), \ + INIT_ID(memLevel), \ + INIT_ID(memlimit), \ + INIT_ID(message), \ + INIT_ID(metaclass), \ + INIT_ID(method), \ + INIT_ID(mod), \ + INIT_ID(mode), \ + INIT_ID(module), \ + INIT_ID(module_globals), \ + INIT_ID(modules), \ + INIT_ID(mro), \ + INIT_ID(msg), \ + INIT_ID(mycmp), \ + INIT_ID(n), \ + INIT_ID(n_arg), \ + INIT_ID(n_fields), \ + INIT_ID(n_sequence_fields), \ + INIT_ID(n_unnamed_fields), \ + INIT_ID(name), \ + INIT_ID(name_from), \ + INIT_ID(namespace_separator), \ + INIT_ID(namespaces), \ + INIT_ID(narg), \ + INIT_ID(ndigits), \ + INIT_ID(new_limit), \ + INIT_ID(newline), \ + INIT_ID(newlines), \ + INIT_ID(next), \ + INIT_ID(node_depth), \ + INIT_ID(node_offset), \ + INIT_ID(ns), \ + INIT_ID(nstype), \ + INIT_ID(nt), \ + INIT_ID(null), \ + INIT_ID(number), \ + INIT_ID(obj), \ + INIT_ID(object), \ + INIT_ID(offset), \ + INIT_ID(offset_dst), \ + INIT_ID(offset_src), \ + INIT_ID(on_type_read), \ + INIT_ID(onceregistry), \ + INIT_ID(only_keys), \ + INIT_ID(oparg), \ + INIT_ID(opcode), \ + INIT_ID(open), \ + INIT_ID(opener), \ + INIT_ID(operation), \ + INIT_ID(optimize), \ + INIT_ID(options), \ + INIT_ID(order), \ + INIT_ID(out_fd), \ + INIT_ID(outgoing), \ + INIT_ID(overlapped), \ + INIT_ID(owner), \ + INIT_ID(p), \ + INIT_ID(pages), \ + INIT_ID(parent), \ + INIT_ID(password), \ + INIT_ID(path), \ + INIT_ID(pattern), \ + INIT_ID(peek), \ + INIT_ID(persistent_id), \ + INIT_ID(persistent_load), \ + INIT_ID(person), \ + INIT_ID(pi_factory), \ + INIT_ID(pid), \ + INIT_ID(policy), \ + INIT_ID(pos), \ + INIT_ID(pos1), \ + INIT_ID(pos2), \ + INIT_ID(posix), \ + INIT_ID(print_file_and_line), \ + INIT_ID(priority), \ + INIT_ID(progress), \ + INIT_ID(progress_handler), \ + INIT_ID(proto), \ + INIT_ID(protocol), \ + INIT_ID(ps1), \ + INIT_ID(ps2), \ + INIT_ID(query), \ + INIT_ID(quotetabs), \ + INIT_ID(r), \ + INIT_ID(raw), \ + INIT_ID(read), \ + INIT_ID(read1), \ + INIT_ID(readable), \ + INIT_ID(readall), \ + INIT_ID(readinto), \ + INIT_ID(readinto1), \ + INIT_ID(readline), \ + INIT_ID(readonly), \ + INIT_ID(real), \ + INIT_ID(reducer_override), \ + INIT_ID(registry), \ + INIT_ID(rel_tol), \ + INIT_ID(reload), \ + INIT_ID(repl), \ + INIT_ID(replace), \ + INIT_ID(reserved), \ + INIT_ID(reset), \ + INIT_ID(resetids), \ + INIT_ID(return), \ + INIT_ID(reverse), \ + INIT_ID(reversed), \ + INIT_ID(s), \ + INIT_ID(salt), \ + INIT_ID(sched_priority), \ + INIT_ID(scheduler), \ + INIT_ID(seek), \ + INIT_ID(seekable), \ + INIT_ID(selectors), \ + INIT_ID(self), \ + INIT_ID(send), \ + INIT_ID(sep), \ + INIT_ID(sequence), \ + INIT_ID(server_hostname), \ + INIT_ID(server_side), \ + INIT_ID(session), \ + INIT_ID(setcomp), \ + INIT_ID(setpgroup), \ + INIT_ID(setsid), \ + INIT_ID(setsigdef), \ + INIT_ID(setsigmask), \ + INIT_ID(setstate), \ + INIT_ID(shape), \ + INIT_ID(show_cmd), \ + INIT_ID(signed), \ + INIT_ID(size), \ + INIT_ID(sizehint), \ + INIT_ID(skip_file_prefixes), \ + INIT_ID(sleep), \ + INIT_ID(sock), \ + INIT_ID(sort), \ + INIT_ID(sound), \ + INIT_ID(source), \ + INIT_ID(source_traceback), \ + INIT_ID(src), \ + INIT_ID(src_dir_fd), \ + INIT_ID(stacklevel), \ + INIT_ID(start), \ + INIT_ID(statement), \ + INIT_ID(status), \ + INIT_ID(stderr), \ + INIT_ID(stdin), \ + INIT_ID(stdout), \ + INIT_ID(step), \ + INIT_ID(store_name), \ + INIT_ID(strategy), \ + INIT_ID(strftime), \ + INIT_ID(strict), \ + INIT_ID(strict_mode), \ + INIT_ID(string), \ + INIT_ID(sub_key), \ + INIT_ID(symmetric_difference_update), \ + INIT_ID(tabsize), \ + INIT_ID(tag), \ + INIT_ID(target), \ + INIT_ID(target_is_directory), \ + INIT_ID(task), \ + INIT_ID(tb_frame), \ + INIT_ID(tb_lasti), \ + INIT_ID(tb_lineno), \ + INIT_ID(tb_next), \ + INIT_ID(tell), \ + INIT_ID(template), \ + INIT_ID(term), \ + INIT_ID(text), \ + INIT_ID(threading), \ + INIT_ID(throw), \ + INIT_ID(timeout), \ + INIT_ID(times), \ + INIT_ID(timetuple), \ + INIT_ID(top), \ + INIT_ID(trace_callback), \ + INIT_ID(traceback), \ + INIT_ID(trailers), \ + INIT_ID(translate), \ + INIT_ID(true), \ + INIT_ID(truncate), \ + INIT_ID(twice), \ + INIT_ID(txt), \ + INIT_ID(type), \ + INIT_ID(tz), \ + INIT_ID(tzname), \ + INIT_ID(uid), \ + INIT_ID(unlink), \ + INIT_ID(unraisablehook), \ + INIT_ID(uri), \ + INIT_ID(usedforsecurity), \ + INIT_ID(value), \ + INIT_ID(values), \ + INIT_ID(version), \ + INIT_ID(warnings), \ + INIT_ID(warnoptions), \ + INIT_ID(wbits), \ + INIT_ID(week), \ + INIT_ID(weekday), \ + INIT_ID(which), \ + INIT_ID(who), \ + INIT_ID(withdata), \ + INIT_ID(writable), \ + INIT_ID(write), \ + INIT_ID(write_through), \ + INIT_ID(x), \ + INIT_ID(year), \ + INIT_ID(zdict), \ +} + +#define _Py_str_ascii_INIT { \ + _PyASCIIObject_INIT("\x00"), \ + _PyASCIIObject_INIT("\x01"), \ + _PyASCIIObject_INIT("\x02"), \ + _PyASCIIObject_INIT("\x03"), \ + _PyASCIIObject_INIT("\x04"), \ + _PyASCIIObject_INIT("\x05"), \ + _PyASCIIObject_INIT("\x06"), \ + _PyASCIIObject_INIT("\x07"), \ + _PyASCIIObject_INIT("\x08"), \ + _PyASCIIObject_INIT("\x09"), \ + _PyASCIIObject_INIT("\x0a"), \ + _PyASCIIObject_INIT("\x0b"), \ + _PyASCIIObject_INIT("\x0c"), \ + _PyASCIIObject_INIT("\x0d"), \ + _PyASCIIObject_INIT("\x0e"), \ + _PyASCIIObject_INIT("\x0f"), \ + _PyASCIIObject_INIT("\x10"), \ + _PyASCIIObject_INIT("\x11"), \ + _PyASCIIObject_INIT("\x12"), \ + _PyASCIIObject_INIT("\x13"), \ + _PyASCIIObject_INIT("\x14"), \ + _PyASCIIObject_INIT("\x15"), \ + _PyASCIIObject_INIT("\x16"), \ + _PyASCIIObject_INIT("\x17"), \ + _PyASCIIObject_INIT("\x18"), \ + _PyASCIIObject_INIT("\x19"), \ + _PyASCIIObject_INIT("\x1a"), \ + _PyASCIIObject_INIT("\x1b"), \ + _PyASCIIObject_INIT("\x1c"), \ + _PyASCIIObject_INIT("\x1d"), \ + _PyASCIIObject_INIT("\x1e"), \ + _PyASCIIObject_INIT("\x1f"), \ + _PyASCIIObject_INIT("\x20"), \ + _PyASCIIObject_INIT("\x21"), \ + _PyASCIIObject_INIT("\x22"), \ + _PyASCIIObject_INIT("\x23"), \ + _PyASCIIObject_INIT("\x24"), \ + _PyASCIIObject_INIT("\x25"), \ + _PyASCIIObject_INIT("\x26"), \ + _PyASCIIObject_INIT("\x27"), \ + _PyASCIIObject_INIT("\x28"), \ + _PyASCIIObject_INIT("\x29"), \ + _PyASCIIObject_INIT("\x2a"), \ + _PyASCIIObject_INIT("\x2b"), \ + _PyASCIIObject_INIT("\x2c"), \ + _PyASCIIObject_INIT("\x2d"), \ + _PyASCIIObject_INIT("\x2e"), \ + _PyASCIIObject_INIT("\x2f"), \ + _PyASCIIObject_INIT("\x30"), \ + _PyASCIIObject_INIT("\x31"), \ + _PyASCIIObject_INIT("\x32"), \ + _PyASCIIObject_INIT("\x33"), \ + _PyASCIIObject_INIT("\x34"), \ + _PyASCIIObject_INIT("\x35"), \ + _PyASCIIObject_INIT("\x36"), \ + _PyASCIIObject_INIT("\x37"), \ + _PyASCIIObject_INIT("\x38"), \ + _PyASCIIObject_INIT("\x39"), \ + _PyASCIIObject_INIT("\x3a"), \ + _PyASCIIObject_INIT("\x3b"), \ + _PyASCIIObject_INIT("\x3c"), \ + _PyASCIIObject_INIT("\x3d"), \ + _PyASCIIObject_INIT("\x3e"), \ + _PyASCIIObject_INIT("\x3f"), \ + _PyASCIIObject_INIT("\x40"), \ + _PyASCIIObject_INIT("\x41"), \ + _PyASCIIObject_INIT("\x42"), \ + _PyASCIIObject_INIT("\x43"), \ + _PyASCIIObject_INIT("\x44"), \ + _PyASCIIObject_INIT("\x45"), \ + _PyASCIIObject_INIT("\x46"), \ + _PyASCIIObject_INIT("\x47"), \ + _PyASCIIObject_INIT("\x48"), \ + _PyASCIIObject_INIT("\x49"), \ + _PyASCIIObject_INIT("\x4a"), \ + _PyASCIIObject_INIT("\x4b"), \ + _PyASCIIObject_INIT("\x4c"), \ + _PyASCIIObject_INIT("\x4d"), \ + _PyASCIIObject_INIT("\x4e"), \ + _PyASCIIObject_INIT("\x4f"), \ + _PyASCIIObject_INIT("\x50"), \ + _PyASCIIObject_INIT("\x51"), \ + _PyASCIIObject_INIT("\x52"), \ + _PyASCIIObject_INIT("\x53"), \ + _PyASCIIObject_INIT("\x54"), \ + _PyASCIIObject_INIT("\x55"), \ + _PyASCIIObject_INIT("\x56"), \ + _PyASCIIObject_INIT("\x57"), \ + _PyASCIIObject_INIT("\x58"), \ + _PyASCIIObject_INIT("\x59"), \ + _PyASCIIObject_INIT("\x5a"), \ + _PyASCIIObject_INIT("\x5b"), \ + _PyASCIIObject_INIT("\x5c"), \ + _PyASCIIObject_INIT("\x5d"), \ + _PyASCIIObject_INIT("\x5e"), \ + _PyASCIIObject_INIT("\x5f"), \ + _PyASCIIObject_INIT("\x60"), \ + _PyASCIIObject_INIT("\x61"), \ + _PyASCIIObject_INIT("\x62"), \ + _PyASCIIObject_INIT("\x63"), \ + _PyASCIIObject_INIT("\x64"), \ + _PyASCIIObject_INIT("\x65"), \ + _PyASCIIObject_INIT("\x66"), \ + _PyASCIIObject_INIT("\x67"), \ + _PyASCIIObject_INIT("\x68"), \ + _PyASCIIObject_INIT("\x69"), \ + _PyASCIIObject_INIT("\x6a"), \ + _PyASCIIObject_INIT("\x6b"), \ + _PyASCIIObject_INIT("\x6c"), \ + _PyASCIIObject_INIT("\x6d"), \ + _PyASCIIObject_INIT("\x6e"), \ + _PyASCIIObject_INIT("\x6f"), \ + _PyASCIIObject_INIT("\x70"), \ + _PyASCIIObject_INIT("\x71"), \ + _PyASCIIObject_INIT("\x72"), \ + _PyASCIIObject_INIT("\x73"), \ + _PyASCIIObject_INIT("\x74"), \ + _PyASCIIObject_INIT("\x75"), \ + _PyASCIIObject_INIT("\x76"), \ + _PyASCIIObject_INIT("\x77"), \ + _PyASCIIObject_INIT("\x78"), \ + _PyASCIIObject_INIT("\x79"), \ + _PyASCIIObject_INIT("\x7a"), \ + _PyASCIIObject_INIT("\x7b"), \ + _PyASCIIObject_INIT("\x7c"), \ + _PyASCIIObject_INIT("\x7d"), \ + _PyASCIIObject_INIT("\x7e"), \ + _PyASCIIObject_INIT("\x7f"), \ +} + +#define _Py_str_latin1_INIT { \ + _PyUnicode_LATIN1_INIT("\x80", "\xc2\x80"), \ + _PyUnicode_LATIN1_INIT("\x81", "\xc2\x81"), \ + _PyUnicode_LATIN1_INIT("\x82", "\xc2\x82"), \ + _PyUnicode_LATIN1_INIT("\x83", "\xc2\x83"), \ + _PyUnicode_LATIN1_INIT("\x84", "\xc2\x84"), \ + _PyUnicode_LATIN1_INIT("\x85", "\xc2\x85"), \ + _PyUnicode_LATIN1_INIT("\x86", "\xc2\x86"), \ + _PyUnicode_LATIN1_INIT("\x87", "\xc2\x87"), \ + _PyUnicode_LATIN1_INIT("\x88", "\xc2\x88"), \ + _PyUnicode_LATIN1_INIT("\x89", "\xc2\x89"), \ + _PyUnicode_LATIN1_INIT("\x8a", "\xc2\x8a"), \ + _PyUnicode_LATIN1_INIT("\x8b", "\xc2\x8b"), \ + _PyUnicode_LATIN1_INIT("\x8c", "\xc2\x8c"), \ + _PyUnicode_LATIN1_INIT("\x8d", "\xc2\x8d"), \ + _PyUnicode_LATIN1_INIT("\x8e", "\xc2\x8e"), \ + _PyUnicode_LATIN1_INIT("\x8f", "\xc2\x8f"), \ + _PyUnicode_LATIN1_INIT("\x90", "\xc2\x90"), \ + _PyUnicode_LATIN1_INIT("\x91", "\xc2\x91"), \ + _PyUnicode_LATIN1_INIT("\x92", "\xc2\x92"), \ + _PyUnicode_LATIN1_INIT("\x93", "\xc2\x93"), \ + _PyUnicode_LATIN1_INIT("\x94", "\xc2\x94"), \ + _PyUnicode_LATIN1_INIT("\x95", "\xc2\x95"), \ + _PyUnicode_LATIN1_INIT("\x96", "\xc2\x96"), \ + _PyUnicode_LATIN1_INIT("\x97", "\xc2\x97"), \ + _PyUnicode_LATIN1_INIT("\x98", "\xc2\x98"), \ + _PyUnicode_LATIN1_INIT("\x99", "\xc2\x99"), \ + _PyUnicode_LATIN1_INIT("\x9a", "\xc2\x9a"), \ + _PyUnicode_LATIN1_INIT("\x9b", "\xc2\x9b"), \ + _PyUnicode_LATIN1_INIT("\x9c", "\xc2\x9c"), \ + _PyUnicode_LATIN1_INIT("\x9d", "\xc2\x9d"), \ + _PyUnicode_LATIN1_INIT("\x9e", "\xc2\x9e"), \ + _PyUnicode_LATIN1_INIT("\x9f", "\xc2\x9f"), \ + _PyUnicode_LATIN1_INIT("\xa0", "\xc2\xa0"), \ + _PyUnicode_LATIN1_INIT("\xa1", "\xc2\xa1"), \ + _PyUnicode_LATIN1_INIT("\xa2", "\xc2\xa2"), \ + _PyUnicode_LATIN1_INIT("\xa3", "\xc2\xa3"), \ + _PyUnicode_LATIN1_INIT("\xa4", "\xc2\xa4"), \ + _PyUnicode_LATIN1_INIT("\xa5", "\xc2\xa5"), \ + _PyUnicode_LATIN1_INIT("\xa6", "\xc2\xa6"), \ + _PyUnicode_LATIN1_INIT("\xa7", "\xc2\xa7"), \ + _PyUnicode_LATIN1_INIT("\xa8", "\xc2\xa8"), \ + _PyUnicode_LATIN1_INIT("\xa9", "\xc2\xa9"), \ + _PyUnicode_LATIN1_INIT("\xaa", "\xc2\xaa"), \ + _PyUnicode_LATIN1_INIT("\xab", "\xc2\xab"), \ + _PyUnicode_LATIN1_INIT("\xac", "\xc2\xac"), \ + _PyUnicode_LATIN1_INIT("\xad", "\xc2\xad"), \ + _PyUnicode_LATIN1_INIT("\xae", "\xc2\xae"), \ + _PyUnicode_LATIN1_INIT("\xaf", "\xc2\xaf"), \ + _PyUnicode_LATIN1_INIT("\xb0", "\xc2\xb0"), \ + _PyUnicode_LATIN1_INIT("\xb1", "\xc2\xb1"), \ + _PyUnicode_LATIN1_INIT("\xb2", "\xc2\xb2"), \ + _PyUnicode_LATIN1_INIT("\xb3", "\xc2\xb3"), \ + _PyUnicode_LATIN1_INIT("\xb4", "\xc2\xb4"), \ + _PyUnicode_LATIN1_INIT("\xb5", "\xc2\xb5"), \ + _PyUnicode_LATIN1_INIT("\xb6", "\xc2\xb6"), \ + _PyUnicode_LATIN1_INIT("\xb7", "\xc2\xb7"), \ + _PyUnicode_LATIN1_INIT("\xb8", "\xc2\xb8"), \ + _PyUnicode_LATIN1_INIT("\xb9", "\xc2\xb9"), \ + _PyUnicode_LATIN1_INIT("\xba", "\xc2\xba"), \ + _PyUnicode_LATIN1_INIT("\xbb", "\xc2\xbb"), \ + _PyUnicode_LATIN1_INIT("\xbc", "\xc2\xbc"), \ + _PyUnicode_LATIN1_INIT("\xbd", "\xc2\xbd"), \ + _PyUnicode_LATIN1_INIT("\xbe", "\xc2\xbe"), \ + _PyUnicode_LATIN1_INIT("\xbf", "\xc2\xbf"), \ + _PyUnicode_LATIN1_INIT("\xc0", "\xc3\x80"), \ + _PyUnicode_LATIN1_INIT("\xc1", "\xc3\x81"), \ + _PyUnicode_LATIN1_INIT("\xc2", "\xc3\x82"), \ + _PyUnicode_LATIN1_INIT("\xc3", "\xc3\x83"), \ + _PyUnicode_LATIN1_INIT("\xc4", "\xc3\x84"), \ + _PyUnicode_LATIN1_INIT("\xc5", "\xc3\x85"), \ + _PyUnicode_LATIN1_INIT("\xc6", "\xc3\x86"), \ + _PyUnicode_LATIN1_INIT("\xc7", "\xc3\x87"), \ + _PyUnicode_LATIN1_INIT("\xc8", "\xc3\x88"), \ + _PyUnicode_LATIN1_INIT("\xc9", "\xc3\x89"), \ + _PyUnicode_LATIN1_INIT("\xca", "\xc3\x8a"), \ + _PyUnicode_LATIN1_INIT("\xcb", "\xc3\x8b"), \ + _PyUnicode_LATIN1_INIT("\xcc", "\xc3\x8c"), \ + _PyUnicode_LATIN1_INIT("\xcd", "\xc3\x8d"), \ + _PyUnicode_LATIN1_INIT("\xce", "\xc3\x8e"), \ + _PyUnicode_LATIN1_INIT("\xcf", "\xc3\x8f"), \ + _PyUnicode_LATIN1_INIT("\xd0", "\xc3\x90"), \ + _PyUnicode_LATIN1_INIT("\xd1", "\xc3\x91"), \ + _PyUnicode_LATIN1_INIT("\xd2", "\xc3\x92"), \ + _PyUnicode_LATIN1_INIT("\xd3", "\xc3\x93"), \ + _PyUnicode_LATIN1_INIT("\xd4", "\xc3\x94"), \ + _PyUnicode_LATIN1_INIT("\xd5", "\xc3\x95"), \ + _PyUnicode_LATIN1_INIT("\xd6", "\xc3\x96"), \ + _PyUnicode_LATIN1_INIT("\xd7", "\xc3\x97"), \ + _PyUnicode_LATIN1_INIT("\xd8", "\xc3\x98"), \ + _PyUnicode_LATIN1_INIT("\xd9", "\xc3\x99"), \ + _PyUnicode_LATIN1_INIT("\xda", "\xc3\x9a"), \ + _PyUnicode_LATIN1_INIT("\xdb", "\xc3\x9b"), \ + _PyUnicode_LATIN1_INIT("\xdc", "\xc3\x9c"), \ + _PyUnicode_LATIN1_INIT("\xdd", "\xc3\x9d"), \ + _PyUnicode_LATIN1_INIT("\xde", "\xc3\x9e"), \ + _PyUnicode_LATIN1_INIT("\xdf", "\xc3\x9f"), \ + _PyUnicode_LATIN1_INIT("\xe0", "\xc3\xa0"), \ + _PyUnicode_LATIN1_INIT("\xe1", "\xc3\xa1"), \ + _PyUnicode_LATIN1_INIT("\xe2", "\xc3\xa2"), \ + _PyUnicode_LATIN1_INIT("\xe3", "\xc3\xa3"), \ + _PyUnicode_LATIN1_INIT("\xe4", "\xc3\xa4"), \ + _PyUnicode_LATIN1_INIT("\xe5", "\xc3\xa5"), \ + _PyUnicode_LATIN1_INIT("\xe6", "\xc3\xa6"), \ + _PyUnicode_LATIN1_INIT("\xe7", "\xc3\xa7"), \ + _PyUnicode_LATIN1_INIT("\xe8", "\xc3\xa8"), \ + _PyUnicode_LATIN1_INIT("\xe9", "\xc3\xa9"), \ + _PyUnicode_LATIN1_INIT("\xea", "\xc3\xaa"), \ + _PyUnicode_LATIN1_INIT("\xeb", "\xc3\xab"), \ + _PyUnicode_LATIN1_INIT("\xec", "\xc3\xac"), \ + _PyUnicode_LATIN1_INIT("\xed", "\xc3\xad"), \ + _PyUnicode_LATIN1_INIT("\xee", "\xc3\xae"), \ + _PyUnicode_LATIN1_INIT("\xef", "\xc3\xaf"), \ + _PyUnicode_LATIN1_INIT("\xf0", "\xc3\xb0"), \ + _PyUnicode_LATIN1_INIT("\xf1", "\xc3\xb1"), \ + _PyUnicode_LATIN1_INIT("\xf2", "\xc3\xb2"), \ + _PyUnicode_LATIN1_INIT("\xf3", "\xc3\xb3"), \ + _PyUnicode_LATIN1_INIT("\xf4", "\xc3\xb4"), \ + _PyUnicode_LATIN1_INIT("\xf5", "\xc3\xb5"), \ + _PyUnicode_LATIN1_INIT("\xf6", "\xc3\xb6"), \ + _PyUnicode_LATIN1_INIT("\xf7", "\xc3\xb7"), \ + _PyUnicode_LATIN1_INIT("\xf8", "\xc3\xb8"), \ + _PyUnicode_LATIN1_INIT("\xf9", "\xc3\xb9"), \ + _PyUnicode_LATIN1_INIT("\xfa", "\xc3\xba"), \ + _PyUnicode_LATIN1_INIT("\xfb", "\xc3\xbb"), \ + _PyUnicode_LATIN1_INIT("\xfc", "\xc3\xbc"), \ + _PyUnicode_LATIN1_INIT("\xfd", "\xc3\xbd"), \ + _PyUnicode_LATIN1_INIT("\xfe", "\xc3\xbe"), \ + _PyUnicode_LATIN1_INIT("\xff", "\xc3\xbf"), \ +} +/* End auto-generated code */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_RUNTIME_INIT_GENERATED_H */ diff --git a/Include/internal/pycore_signal.h b/Include/internal/pycore_signal.h new file mode 100644 index 00000000000..ca3f69d09fc --- /dev/null +++ b/Include/internal/pycore_signal.h @@ -0,0 +1,98 @@ +// Define Py_NSIG constant for signal handling. + +#ifndef Py_INTERNAL_SIGNAL_H +#define Py_INTERNAL_SIGNAL_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_atomic.h" // _Py_atomic_address + +#include // NSIG + + +#ifdef _SIG_MAXSIG + // gh-91145: On FreeBSD, defines NSIG as 32: it doesn't include + // realtime signals: [SIGRTMIN,SIGRTMAX]. Use _SIG_MAXSIG instead. For + // example on x86-64 FreeBSD 13, SIGRTMAX is 126 and _SIG_MAXSIG is 128. +# define Py_NSIG _SIG_MAXSIG +#elif defined(NSIG) +# define Py_NSIG NSIG +#elif defined(_NSIG) +# define Py_NSIG _NSIG // BSD/SysV +#elif defined(_SIGMAX) +# define Py_NSIG (_SIGMAX + 1) // QNX +#elif defined(SIGMAX) +# define Py_NSIG (SIGMAX + 1) // djgpp +#else +# define Py_NSIG 64 // Use a reasonable default value +#endif + +#define INVALID_FD (-1) + +struct _signals_runtime_state { + volatile struct { + _Py_atomic_int tripped; + /* func is atomic to ensure that PyErr_SetInterrupt is async-signal-safe + * (even though it would probably be otherwise, anyway). + */ + _Py_atomic_address func; + } handlers[Py_NSIG]; + + volatile struct { +#ifdef MS_WINDOWS + /* This would be "SOCKET fd" if were always included. + It isn't so we must cast to SOCKET where appropriate. */ + volatile int fd; +#elif defined(__VXWORKS__) + int fd; +#else + sig_atomic_t fd; +#endif + + int warn_on_full_buffer; +#ifdef MS_WINDOWS + int use_send; +#endif + } wakeup; + + /* Speed up sigcheck() when none tripped */ + _Py_atomic_int is_tripped; + + /* These objects necessarily belong to the main interpreter. */ + PyObject *default_handler; + PyObject *ignore_handler; + +#ifdef MS_WINDOWS + /* This would be "HANDLE sigint_event" if were always included. + It isn't so we must cast to HANDLE everywhere "sigint_event" is used. */ + void *sigint_event; +#endif + + /* True if the main interpreter thread exited due to an unhandled + * KeyboardInterrupt exception, suggesting the user pressed ^C. */ + int unhandled_keyboard_interrupt; +}; + +#ifdef MS_WINDOWS +# define _signals_WAKEUP_INIT \ + {.fd = INVALID_FD, .warn_on_full_buffer = 1, .use_send = 0} +#else +# define _signals_WAKEUP_INIT \ + {.fd = INVALID_FD, .warn_on_full_buffer = 1} +#endif + +#define _signals_RUNTIME_INIT \ + { \ + .wakeup = _signals_WAKEUP_INIT, \ + } + + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_SIGNAL_H diff --git a/Include/internal/pycore_sliceobject.h b/Include/internal/pycore_sliceobject.h new file mode 100644 index 00000000000..98665c3859d --- /dev/null +++ b/Include/internal/pycore_sliceobject.h @@ -0,0 +1,22 @@ +#ifndef Py_INTERNAL_SLICEOBJECT_H +#define Py_INTERNAL_SLICEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +/* runtime lifecycle */ + +extern void _PySlice_Fini(PyInterpreterState *); + +extern PyObject * +_PyBuildSlice_ConsumeRefs(PyObject *start, PyObject *stop); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_SLICEOBJECT_H */ diff --git a/Include/internal/pycore_strhex.h b/Include/internal/pycore_strhex.h index 1633671da0f..f427b4d695b 100644 --- a/Include/internal/pycore_strhex.h +++ b/Include/internal/pycore_strhex.h @@ -22,12 +22,12 @@ PyAPI_FUNC(PyObject*) _Py_strhex_bytes( PyAPI_FUNC(PyObject*) _Py_strhex_with_sep( const char* argbuf, const Py_ssize_t arglen, - const PyObject* sep, + PyObject* sep, const int bytes_per_group); PyAPI_FUNC(PyObject*) _Py_strhex_bytes_with_sep( const char* argbuf, const Py_ssize_t arglen, - const PyObject* sep, + PyObject* sep, const int bytes_per_group); #ifdef __cplusplus diff --git a/Include/internal/pycore_structseq.h b/Include/internal/pycore_structseq.h index 84c8d477e0d..d10a921c55f 100644 --- a/Include/internal/pycore_structseq.h +++ b/Include/internal/pycore_structseq.h @@ -9,11 +9,25 @@ extern "C" { #endif -PyAPI_FUNC(int) _PyStructSequence_InitType( +/* other API */ + +PyAPI_FUNC(PyTypeObject *) _PyStructSequence_NewType( + PyStructSequence_Desc *desc, + unsigned long tp_flags); + +PyAPI_FUNC(int) _PyStructSequence_InitBuiltinWithFlags( PyTypeObject *type, PyStructSequence_Desc *desc, unsigned long tp_flags); +static inline int +_PyStructSequence_InitBuiltin(PyTypeObject *type, + PyStructSequence_Desc *desc) +{ + return _PyStructSequence_InitBuiltinWithFlags(type, desc, 0); +} + +extern void _PyStructSequence_FiniType(PyTypeObject *type); #ifdef __cplusplus } diff --git a/Include/internal/pycore_symtable.h b/Include/internal/pycore_symtable.h index 4c1b7d3519c..8532646ce7d 100644 --- a/Include/internal/pycore_symtable.h +++ b/Include/internal/pycore_symtable.h @@ -13,6 +13,13 @@ struct _mod; // Type defined in pycore_ast.h typedef enum _block_type { FunctionBlock, ClassBlock, ModuleBlock, AnnotationBlock } _Py_block_ty; +typedef enum _comprehension_type { + NoComprehension = 0, + ListComprehension = 1, + DictComprehension = 2, + SetComprehension = 3, + GeneratorExpression = 4 } _Py_comprehension_ty; + struct _symtable_entry; struct symtable { @@ -42,14 +49,14 @@ typedef struct _symtable_entry { PyObject *ste_varnames; /* list of function parameters */ PyObject *ste_children; /* list of child blocks */ PyObject *ste_directives;/* locations of global and nonlocal statements */ - _Py_block_ty ste_type; /* module, class, or function */ + _Py_block_ty ste_type; /* module, class, function or annotation */ int ste_nested; /* true if block is nested */ unsigned ste_free : 1; /* true if block has free variables */ unsigned ste_child_free : 1; /* true if a child block has free vars, including free refs to globals */ unsigned ste_generator : 1; /* true if namespace is a generator */ unsigned ste_coroutine : 1; /* true if namespace is a coroutine */ - unsigned ste_comprehension : 1; /* true if namespace is a list comprehension */ + _Py_comprehension_ty ste_comprehension; /* Kind of comprehension (if any) */ unsigned ste_varargs : 1; /* true if block has varargs */ unsigned ste_varkeywords : 1; /* true if block has varkeywords */ unsigned ste_returns_value : 1; /* true if namespace uses return with @@ -70,7 +77,7 @@ typedef struct _symtable_entry { extern PyTypeObject PySTEntry_Type; -#define PySTEntry_Check(op) Py_IS_TYPE(op, &PySTEntry_Type) +#define PySTEntry_Check(op) Py_IS_TYPE((op), &PySTEntry_Type) extern long _PyST_GetSymbol(PySTEntryObject *, PyObject *); extern int _PyST_GetScope(PySTEntryObject *, PyObject *); diff --git a/Include/internal/pycore_sysmodule.h b/Include/internal/pycore_sysmodule.h index 738a7746a03..10d092cdc30 100644 --- a/Include/internal/pycore_sysmodule.h +++ b/Include/internal/pycore_sysmodule.h @@ -18,6 +18,8 @@ PyAPI_FUNC(int) _PySys_Audit( PyAPI_FUNC() to not export the symbol. */ extern void _PySys_ClearAuditHooks(PyThreadState *tstate); +PyAPI_FUNC(int) _PySys_SetAttr(PyObject *, PyObject *); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_time.h b/Include/internal/pycore_time.h new file mode 100644 index 00000000000..949170c4493 --- /dev/null +++ b/Include/internal/pycore_time.h @@ -0,0 +1,25 @@ +#ifndef Py_INTERNAL_TIME_H +#define Py_INTERNAL_TIME_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +struct _time_runtime_state { +#ifdef HAVE_TIMES + int ticks_per_second_initialized; + long ticks_per_second; +#else + int _not_used; +#endif +}; + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_TIME_H */ diff --git a/Include/token.h b/Include/internal/pycore_token.h similarity index 85% rename from Include/token.h rename to Include/internal/pycore_token.h index eb1b9ea47b4..95459ab9f7d 100644 --- a/Include/token.h +++ b/Include/internal/pycore_token.h @@ -1,13 +1,16 @@ -/* Auto-generated by Tools/scripts/generate_token.py */ +/* Auto-generated by Tools/build/generate_token.py */ /* Token types */ -#ifndef Py_LIMITED_API -#ifndef Py_TOKEN_H -#define Py_TOKEN_H +#ifndef Py_INTERNAL_TOKEN_H +#define Py_INTERNAL_TOKEN_H #ifdef __cplusplus extern "C" { #endif +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + #undef TILDE /* Prevent clash of our definition with system macro. Ex AIX, ioctl.h */ #define ENDMARKER 0 @@ -85,13 +88,13 @@ extern "C" { (x) == DEDENT) +// Symbols exported for test_peg_generator PyAPI_DATA(const char * const) _PyParser_TokenNames[]; /* Token names */ -PyAPI_FUNC(int) PyToken_OneChar(int); -PyAPI_FUNC(int) PyToken_TwoChars(int, int); -PyAPI_FUNC(int) PyToken_ThreeChars(int, int, int); +PyAPI_FUNC(int) _PyToken_OneChar(int); +PyAPI_FUNC(int) _PyToken_TwoChars(int, int); +PyAPI_FUNC(int) _PyToken_ThreeChars(int, int, int); #ifdef __cplusplus } #endif -#endif /* !Py_TOKEN_H */ -#endif /* Py_LIMITED_API */ +#endif // !Py_INTERNAL_TOKEN_H diff --git a/Include/internal/pycore_traceback.h b/Include/internal/pycore_traceback.h index 84dbe27044f..c393b2c136f 100644 --- a/Include/internal/pycore_traceback.h +++ b/Include/internal/pycore_traceback.h @@ -8,9 +8,6 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -/* Forward declaration */ -struct _is; - /* Write the Python traceback into the file 'fd'. For example: Traceback (most recent call first): @@ -57,7 +54,7 @@ PyAPI_FUNC(void) _Py_DumpTraceback( PyAPI_FUNC(const char*) _Py_DumpTracebackThreads( int fd, - struct _is *interp, + PyInterpreterState *interp, PyThreadState *current_tstate); /* Write a Unicode object into the file descriptor fd. Encode the string to diff --git a/Include/internal/pycore_tracemalloc.h b/Include/internal/pycore_tracemalloc.h new file mode 100644 index 00000000000..d086adc61c3 --- /dev/null +++ b/Include/internal/pycore_tracemalloc.h @@ -0,0 +1,123 @@ +#ifndef Py_INTERNAL_TRACEMALLOC_H +#define Py_INTERNAL_TRACEMALLOC_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_hashtable.h" // _Py_hashtable_t + + +/* Trace memory blocks allocated by PyMem_RawMalloc() */ +#define TRACE_RAW_MALLOC + + +struct _PyTraceMalloc_Config { + /* Module initialized? + Variable protected by the GIL */ + enum { + TRACEMALLOC_NOT_INITIALIZED, + TRACEMALLOC_INITIALIZED, + TRACEMALLOC_FINALIZED + } initialized; + + /* Is tracemalloc tracing memory allocations? + Variable protected by the GIL */ + int tracing; + + /* limit of the number of frames in a traceback, 1 by default. + Variable protected by the GIL. */ + int max_nframe; +}; + + +/* Pack the frame_t structure to reduce the memory footprint on 64-bit + architectures: 12 bytes instead of 16. */ +#if defined(_MSC_VER) +#pragma pack(push, 4) +#endif + +struct +#ifdef __GNUC__ +__attribute__((packed)) +#endif +tracemalloc_frame { + /* filename cannot be NULL: "" is used if the Python frame + filename is NULL */ + PyObject *filename; + unsigned int lineno; +}; +#ifdef _MSC_VER +#pragma pack(pop) +#endif + +struct tracemalloc_traceback { + Py_uhash_t hash; + /* Number of frames stored */ + uint16_t nframe; + /* Total number of frames the traceback had */ + uint16_t total_nframe; + struct tracemalloc_frame frames[1]; +}; + + +struct _tracemalloc_runtime_state { + struct _PyTraceMalloc_Config config; + + /* Protected by the GIL */ + struct { + PyMemAllocatorEx mem; + PyMemAllocatorEx raw; + PyMemAllocatorEx obj; + } allocators; + +#if defined(TRACE_RAW_MALLOC) + PyThread_type_lock tables_lock; +#endif + /* Size in bytes of currently traced memory. + Protected by TABLES_LOCK(). */ + size_t traced_memory; + /* Peak size in bytes of traced memory. + Protected by TABLES_LOCK(). */ + size_t peak_traced_memory; + /* Hash table used as a set to intern filenames: + PyObject* => PyObject*. + Protected by the GIL */ + _Py_hashtable_t *filenames; + /* Buffer to store a new traceback in traceback_new(). + Protected by the GIL. */ + struct tracemalloc_traceback *traceback; + /* Hash table used as a set to intern tracebacks: + traceback_t* => traceback_t* + Protected by the GIL */ + _Py_hashtable_t *tracebacks; + /* pointer (void*) => trace (trace_t*). + Protected by TABLES_LOCK(). */ + _Py_hashtable_t *traces; + /* domain (unsigned int) => traces (_Py_hashtable_t). + Protected by TABLES_LOCK(). */ + _Py_hashtable_t *domains; + + struct tracemalloc_traceback empty_traceback; + + Py_tss_t reentrant_key; +}; + +#define _tracemalloc_runtime_state_INIT \ + { \ + .config = { \ + .initialized = TRACEMALLOC_NOT_INITIALIZED, \ + .tracing = 0, \ + .max_nframe = 1, \ + }, \ + .reentrant_key = Py_tss_NEEDS_INIT, \ + } + + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_TRACEMALLOC_H diff --git a/Include/internal/pycore_tuple.h b/Include/internal/pycore_tuple.h index 79c827fe880..edc70843b57 100644 --- a/Include/internal/pycore_tuple.h +++ b/Include/internal/pycore_tuple.h @@ -10,11 +10,70 @@ extern "C" { #include "tupleobject.h" /* _PyTuple_CAST() */ -#define _PyTuple_ITEMS(op) (_PyTuple_CAST(op)->ob_item) + +/* runtime lifecycle */ + +extern PyStatus _PyTuple_InitGlobalObjects(PyInterpreterState *); +extern PyStatus _PyTuple_InitTypes(PyInterpreterState *); +extern void _PyTuple_Fini(PyInterpreterState *); + + +/* other API */ + +// PyTuple_MAXSAVESIZE - largest tuple to save on free list +// PyTuple_MAXFREELIST - maximum number of tuples of each size to save + +#if defined(PyTuple_MAXSAVESIZE) && PyTuple_MAXSAVESIZE <= 0 + // A build indicated that tuple freelists should not be used. +# define PyTuple_NFREELISTS 0 +# undef PyTuple_MAXSAVESIZE +# undef PyTuple_MAXFREELIST + +#elif !defined(WITH_FREELISTS) +# define PyTuple_NFREELISTS 0 +# undef PyTuple_MAXSAVESIZE +# undef PyTuple_MAXFREELIST + +#else + // We are using a freelist for tuples. +# ifndef PyTuple_MAXSAVESIZE +# define PyTuple_MAXSAVESIZE 20 +# endif +# define PyTuple_NFREELISTS PyTuple_MAXSAVESIZE +# ifndef PyTuple_MAXFREELIST +# define PyTuple_MAXFREELIST 2000 +# endif +#endif + +struct _Py_tuple_state { +#if PyTuple_NFREELISTS > 0 + /* There is one freelist for each size from 1 to PyTuple_MAXSAVESIZE. + The empty tuple is handled separately. + + Each tuple stored in the array is the head of the linked list + (and the next available tuple) for that size. The actual tuple + object is used as the linked list node, with its first item + (ob_item[0]) pointing to the next node (i.e. the previous head). + Each linked list is initially NULL. */ + PyTupleObject *free_list[PyTuple_NFREELISTS]; + int numfree[PyTuple_NFREELISTS]; +#else + char _unused; // Empty structs are not allowed. +#endif +}; + +#define _PyTuple_ITEMS(op) _Py_RVALUE(_PyTuple_CAST(op)->ob_item) extern PyObject *_PyTuple_FromArray(PyObject *const *, Py_ssize_t); extern PyObject *_PyTuple_FromArraySteal(PyObject *const *, Py_ssize_t); + +typedef struct { + PyObject_HEAD + Py_ssize_t it_index; + PyTupleObject *it_seq; /* Set to NULL when iterator is exhausted */ +} _PyTupleIterObject; + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h new file mode 100644 index 00000000000..4d705740a9a --- /dev/null +++ b/Include/internal/pycore_typeobject.h @@ -0,0 +1,88 @@ +#ifndef Py_INTERNAL_TYPEOBJECT_H +#define Py_INTERNAL_TYPEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +/* runtime lifecycle */ + +extern PyStatus _PyTypes_InitTypes(PyInterpreterState *); +extern void _PyTypes_FiniTypes(PyInterpreterState *); +extern void _PyTypes_Fini(PyInterpreterState *); + + +/* other API */ + +/* Length of array of slotdef pointers used to store slots with the + same __name__. There should be at most MAX_EQUIV-1 slotdef entries with + the same __name__, for any __name__. Since that's a static property, it is + appropriate to declare fixed-size arrays for this. */ +#define MAX_EQUIV 10 + +typedef struct wrapperbase pytype_slotdef; + + +// Type attribute lookup cache: speed up attribute and method lookups, +// see _PyType_Lookup(). +struct type_cache_entry { + unsigned int version; // initialized from type->tp_version_tag + PyObject *name; // reference to exactly a str or None + PyObject *value; // borrowed reference or NULL +}; + +#define MCACHE_SIZE_EXP 12 + +struct type_cache { + struct type_cache_entry hashtable[1 << MCACHE_SIZE_EXP]; +}; + +/* For now we hard-code this to a value for which we are confident + all the static builtin types will fit (for all builds). */ +#define _Py_MAX_STATIC_BUILTIN_TYPES 200 + +typedef struct { + PyTypeObject *type; + PyObject *tp_subclasses; + /* We never clean up weakrefs for static builtin types since + they will effectively never get triggered. However, there + are also some diagnostic uses for the list of weakrefs, + so we still keep it. */ + PyObject *tp_weaklist; +} static_builtin_state; + +static inline PyObject ** +_PyStaticType_GET_WEAKREFS_LISTPTR(static_builtin_state *state) +{ + assert(state != NULL); + return &state->tp_weaklist; +} + +struct types_state { + struct type_cache type_cache; + size_t num_builtins_initialized; + static_builtin_state builtins[_Py_MAX_STATIC_BUILTIN_TYPES]; +}; + + +extern int _PyStaticType_InitBuiltin(PyTypeObject *type); +extern static_builtin_state * _PyStaticType_GetState(PyTypeObject *); +extern void _PyStaticType_ClearWeakRefs(PyTypeObject *type); +extern void _PyStaticType_Dealloc(PyTypeObject *type); + +PyObject * +_Py_type_getattro_impl(PyTypeObject *type, PyObject *name, int *suppress_missing_attribute); +PyObject * +_Py_type_getattro(PyTypeObject *type, PyObject *name); + +PyObject *_Py_slot_tp_getattro(PyObject *self, PyObject *name); +PyObject *_Py_slot_tp_getattr_hook(PyObject *self, PyObject *name); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_TYPEOBJECT_H */ diff --git a/Include/internal/pycore_unicodeobject.h b/Include/internal/pycore_unicodeobject.h new file mode 100644 index 00000000000..19faceebf1d --- /dev/null +++ b/Include/internal/pycore_unicodeobject.h @@ -0,0 +1,68 @@ +#ifndef Py_INTERNAL_UNICODEOBJECT_H +#define Py_INTERNAL_UNICODEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_fileutils.h" // _Py_error_handler +#include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI + +void _PyUnicode_ExactDealloc(PyObject *op); + +/* runtime lifecycle */ + +extern void _PyUnicode_InitState(PyInterpreterState *); +extern PyStatus _PyUnicode_InitGlobalObjects(PyInterpreterState *); +extern PyStatus _PyUnicode_InitTypes(PyInterpreterState *); +extern void _PyUnicode_Fini(PyInterpreterState *); +extern void _PyUnicode_FiniTypes(PyInterpreterState *); + +extern PyTypeObject _PyUnicodeASCIIIter_Type; + +/* other API */ + +struct _Py_unicode_runtime_ids { + PyThread_type_lock lock; + // next_index value must be preserved when Py_Initialize()/Py_Finalize() + // is called multiple times: see _PyUnicode_FromId() implementation. + Py_ssize_t next_index; +}; + +struct _Py_unicode_runtime_state { + struct _Py_unicode_runtime_ids ids; +}; + +/* fs_codec.encoding is initialized to NULL. + Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */ +struct _Py_unicode_fs_codec { + char *encoding; // Filesystem encoding (encoded to UTF-8) + int utf8; // encoding=="utf-8"? + char *errors; // Filesystem errors (encoded to UTF-8) + _Py_error_handler error_handler; +}; + +struct _Py_unicode_ids { + Py_ssize_t size; + PyObject **array; +}; + +struct _Py_unicode_state { + struct _Py_unicode_fs_codec fs_codec; + + _PyUnicode_Name_CAPI *ucnhash_capi; + + // Unicode identifiers (_Py_Identifier): see _PyUnicode_FromId() + struct _Py_unicode_ids ids; +}; + +extern void _PyUnicode_ClearInterned(PyInterpreterState *interp); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_UNICODEOBJECT_H */ diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h new file mode 100644 index 00000000000..301aee5210e --- /dev/null +++ b/Include/internal/pycore_unicodeobject_generated.h @@ -0,0 +1,1342 @@ +#ifndef Py_INTERNAL_UNICODEOBJECT_GENERATED_H +#define Py_INTERNAL_UNICODEOBJECT_GENERATED_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +/* The following is auto-generated by Tools/build/generate_global_objects.py. */ +static inline void +_PyUnicode_InitStaticStrings(void) { + PyObject *string; + string = &_Py_ID(CANCELLED); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(FINISHED); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(False); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(JSONDecodeError); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(PENDING); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(Py_Repr); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(TextIOWrapper); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(True); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(WarningMessage); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__IOBase_closed); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__abc_tpflags__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__abs__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__abstractmethods__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__add__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__aenter__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__aexit__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__aiter__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__all__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__and__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__anext__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__annotations__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__args__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__asyncio_running_event_loop__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__await__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__bases__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__bool__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__build_class__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__builtins__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__bytes__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__call__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__cantrace__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__class__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__class_getitem__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__classcell__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__complex__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__contains__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__copy__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__ctypes_from_outparam__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__del__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__delattr__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__delete__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__delitem__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__dict__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__dictoffset__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__dir__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__divmod__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__doc__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__enter__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__eq__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__exit__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__file__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__float__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__floordiv__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__format__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__fspath__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__ge__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__get__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__getattr__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__getattribute__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__getinitargs__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__getitem__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__getnewargs__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__getnewargs_ex__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__getstate__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__gt__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__hash__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__iadd__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__iand__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__ifloordiv__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__ilshift__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__imatmul__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__imod__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__import__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__imul__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__index__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__init__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__init_subclass__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__instancecheck__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__int__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__invert__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__ior__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__ipow__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__irshift__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__isabstractmethod__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__isub__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__iter__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__itruediv__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__ixor__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__le__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__len__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__length_hint__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__lltrace__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__loader__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__lshift__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__lt__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__main__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__matmul__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__missing__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__mod__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__module__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__mro_entries__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__mul__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__name__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__ne__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__neg__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__new__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__newobj__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__newobj_ex__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__next__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__notes__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__or__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__orig_class__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__origin__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__package__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__parameters__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__path__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__pos__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__pow__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__prepare__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__qualname__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__radd__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__rand__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__rdivmod__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__reduce__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__reduce_ex__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__repr__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__reversed__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__rfloordiv__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__rlshift__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__rmatmul__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__rmod__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__rmul__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__ror__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__round__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__rpow__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__rrshift__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__rshift__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__rsub__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__rtruediv__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__rxor__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__set__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__set_name__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__setattr__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__setitem__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__setstate__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__sizeof__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__slotnames__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__slots__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__spec__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__str__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__sub__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__subclasscheck__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__subclasshook__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__truediv__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__trunc__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__typing_is_unpacked_typevartuple__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__typing_prepare_subst__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__typing_subst__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__typing_unpacked_tuple_args__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__warningregistry__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__weaklistoffset__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__weakref__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(__xor__); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_abc_impl); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_abstract_); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_active); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_annotation); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_anonymous_); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_argtypes_); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_as_parameter_); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_asyncio_future_blocking); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_blksize); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_bootstrap); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_check_retval_); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_dealloc_warn); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_feature_version); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_fields_); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_finalizing); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_find_and_load); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_fix_up_module); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_flags_); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_get_sourcefile); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_handle_fromlist); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_initializing); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_is_text_encoding); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_length_); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_limbo); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_lock_unlock_module); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_loop); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_needs_com_addref_); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_pack_); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_restype_); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_showwarnmsg); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_shutdown); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_slotnames); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_strptime_datetime); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_swappedbytes_); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_type_); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_uninitialized_submodules); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_warn_unawaited_coroutine); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(_xoptions); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(a); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(abs_tol); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(access); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(add); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(add_done_callback); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(after_in_child); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(after_in_parent); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(aggregate_class); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(append); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(argdefs); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(arguments); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(argv); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(as_integer_ratio); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(ast); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(attribute); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(authorizer_callback); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(autocommit); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(b); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(backtick); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(base); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(before); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(big); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(binary_form); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(block); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(buffer); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(buffer_callback); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(buffer_size); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(buffering); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(buffers); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(bufsize); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(builtins); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(byteorder); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(bytes); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(bytes_per_sep); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(c); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(c_call); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(c_exception); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(c_return); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(cached_statements); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(cadata); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(cafile); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(call); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(call_exception_handler); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(call_soon); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(cancel); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(capath); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(category); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(cb_type); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(certfile); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(check_same_thread); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(clear); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(close); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(closed); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(closefd); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(closure); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_argcount); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_cellvars); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_code); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_consts); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_exceptiontable); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_filename); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_firstlineno); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_flags); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_freevars); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_kwonlyargcount); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_linetable); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_name); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_names); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_nlocals); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_posonlyargcount); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_qualname); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_stacksize); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(co_varnames); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(code); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(command); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(comment_factory); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(consts); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(context); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(cookie); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(copy); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(copyreg); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(coro); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(count); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(cwd); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(d); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(data); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(database); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(decode); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(decoder); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(default); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(defaultaction); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(delete); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(depth); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(detect_types); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(deterministic); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(device); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(dict); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(dictcomp); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(difference_update); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(digest); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(digest_size); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(digestmod); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(dir_fd); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(discard); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(dispatch_table); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(displayhook); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(dklen); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(doc); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(dont_inherit); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(dst); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(dst_dir_fd); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(duration); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(e); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(effective_ids); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(element_factory); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(encode); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(encoding); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(end); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(end_lineno); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(end_offset); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(endpos); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(env); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(errors); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(event); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(eventmask); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(exc_type); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(exc_value); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(excepthook); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(exception); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(exp); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(extend); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(facility); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(factory); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(false); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(family); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fanout); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fd); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fd2); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fdel); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fget); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(file); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(file_actions); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(filename); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fileno); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(filepath); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fillvalue); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(filters); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(final); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(find_class); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fix_imports); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(flags); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(flush); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(follow_symlinks); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(format); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(frequency); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(from_param); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fromlist); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fromtimestamp); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fromutc); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(fset); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(func); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(future); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(generation); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(genexpr); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(get); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(get_debug); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(get_event_loop); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(get_loop); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(get_source); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(getattr); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(getstate); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(gid); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(globals); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(groupindex); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(groups); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(handle); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(hash_name); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(header); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(headers); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(hi); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(hook); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(id); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(ident); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(ignore); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(imag); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(importlib); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(in_fd); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(incoming); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(indexgroup); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(inf); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(inheritable); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(initial); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(initial_bytes); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(initial_value); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(initval); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(inner_size); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(input); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(insert_comments); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(insert_pis); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(instructions); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(intern); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(intersection); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(isatty); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(isinstance); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(isoformat); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(isolation_level); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(istext); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(item); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(items); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(iter); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(iterable); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(iterations); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(join); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(jump); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(keepends); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(key); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(keyfile); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(keys); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(kind); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(kw); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(kw1); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(kw2); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(lambda); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(last); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(last_node); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(last_traceback); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(last_type); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(last_value); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(latin1); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(leaf_size); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(len); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(length); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(level); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(limit); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(line); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(line_buffering); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(lineno); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(listcomp); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(little); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(lo); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(locale); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(locals); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(logoption); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(loop); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(mapping); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(match); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(max_length); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(maxdigits); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(maxevents); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(maxmem); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(maxsplit); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(maxvalue); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(memLevel); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(memlimit); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(message); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(metaclass); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(method); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(mod); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(mode); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(module); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(module_globals); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(modules); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(mro); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(msg); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(mycmp); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(n); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(n_arg); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(n_fields); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(n_sequence_fields); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(n_unnamed_fields); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(name); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(name_from); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(namespace_separator); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(namespaces); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(narg); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(ndigits); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(new_limit); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(newline); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(newlines); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(next); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(node_depth); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(node_offset); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(ns); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(nstype); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(nt); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(null); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(number); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(obj); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(object); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(offset); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(offset_dst); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(offset_src); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(on_type_read); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(onceregistry); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(only_keys); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(oparg); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(opcode); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(open); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(opener); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(operation); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(optimize); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(options); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(order); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(out_fd); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(outgoing); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(overlapped); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(owner); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(p); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(pages); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(parent); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(password); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(path); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(pattern); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(peek); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(persistent_id); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(persistent_load); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(person); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(pi_factory); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(pid); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(policy); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(pos); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(pos1); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(pos2); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(posix); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(print_file_and_line); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(priority); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(progress); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(progress_handler); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(proto); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(protocol); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(ps1); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(ps2); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(query); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(quotetabs); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(r); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(raw); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(read); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(read1); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(readable); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(readall); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(readinto); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(readinto1); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(readline); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(readonly); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(real); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(reducer_override); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(registry); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(rel_tol); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(reload); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(repl); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(replace); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(reserved); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(reset); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(resetids); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(return); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(reverse); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(reversed); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(s); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(salt); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(sched_priority); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(scheduler); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(seek); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(seekable); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(selectors); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(self); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(send); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(sep); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(sequence); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(server_hostname); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(server_side); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(session); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(setcomp); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(setpgroup); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(setsid); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(setsigdef); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(setsigmask); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(setstate); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(shape); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(show_cmd); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(signed); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(size); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(sizehint); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(skip_file_prefixes); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(sleep); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(sock); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(sort); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(sound); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(source); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(source_traceback); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(src); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(src_dir_fd); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(stacklevel); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(start); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(statement); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(status); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(stderr); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(stdin); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(stdout); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(step); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(store_name); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(strategy); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(strftime); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(strict); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(strict_mode); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(string); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(sub_key); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(symmetric_difference_update); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tabsize); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tag); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(target); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(target_is_directory); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(task); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tb_frame); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tb_lasti); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tb_lineno); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tb_next); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tell); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(template); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(term); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(text); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(threading); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(throw); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(timeout); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(times); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(timetuple); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(top); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(trace_callback); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(traceback); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(trailers); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(translate); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(true); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(truncate); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(twice); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(txt); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(type); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tz); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(tzname); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(uid); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(unlink); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(unraisablehook); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(uri); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(usedforsecurity); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(value); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(values); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(version); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(warnings); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(warnoptions); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(wbits); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(week); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(weekday); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(which); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(who); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(withdata); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(writable); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(write); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(write_through); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(x); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(year); + PyUnicode_InternInPlace(&string); + string = &_Py_ID(zdict); + PyUnicode_InternInPlace(&string); +} +/* End auto-generated code */ +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_UNICODEOBJECT_GENERATED_H */ diff --git a/Include/internal/pycore_unionobject.h b/Include/internal/pycore_unionobject.h index 9962f576103..87264635b6e 100644 --- a/Include/internal/pycore_unionobject.h +++ b/Include/internal/pycore_unionobject.h @@ -9,12 +9,13 @@ extern "C" { #endif extern PyTypeObject _PyUnion_Type; -#define _PyUnion_Check(op) Py_IS_TYPE(op, &_PyUnion_Type) +#define _PyUnion_Check(op) Py_IS_TYPE((op), &_PyUnion_Type) extern PyObject *_Py_union_type_or(PyObject *, PyObject *); -#define _PyGenericAlias_Check(op) PyObject_TypeCheck(op, &Py_GenericAliasType) +#define _PyGenericAlias_Check(op) PyObject_TypeCheck((op), &Py_GenericAliasType) extern PyObject *_Py_subs_parameters(PyObject *, PyObject *, PyObject *, PyObject *); extern PyObject *_Py_make_parameters(PyObject *); +extern PyObject *_Py_union_args(PyObject *self); #ifdef __cplusplus } diff --git a/Include/iterobject.h b/Include/iterobject.h index 6454611aebe..fff30f7176f 100644 --- a/Include/iterobject.h +++ b/Include/iterobject.h @@ -11,12 +11,12 @@ PyAPI_DATA(PyTypeObject) PyCallIter_Type; extern PyTypeObject _PyAnextAwaitable_Type; #endif -#define PySeqIter_Check(op) Py_IS_TYPE(op, &PySeqIter_Type) +#define PySeqIter_Check(op) Py_IS_TYPE((op), &PySeqIter_Type) PyAPI_FUNC(PyObject *) PySeqIter_New(PyObject *); -#define PyCallIter_Check(op) Py_IS_TYPE(op, &PyCallIter_Type) +#define PyCallIter_Check(op) Py_IS_TYPE((op), &PyCallIter_Type) PyAPI_FUNC(PyObject *) PyCallIter_New(PyObject *, PyObject *); diff --git a/Include/listobject.h b/Include/listobject.h index eff42c188f1..6b7041ba0b0 100644 --- a/Include/listobject.h +++ b/Include/listobject.h @@ -23,7 +23,7 @@ PyAPI_DATA(PyTypeObject) PyListRevIter_Type; #define PyList_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) -#define PyList_CheckExact(op) Py_IS_TYPE(op, &PyList_Type) +#define PyList_CheckExact(op) Py_IS_TYPE((op), &PyList_Type) PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size); PyAPI_FUNC(Py_ssize_t) PyList_Size(PyObject *); diff --git a/Include/longobject.h b/Include/longobject.h index 7fe8f58cb3e..e559e238ae5 100644 --- a/Include/longobject.h +++ b/Include/longobject.h @@ -7,13 +7,11 @@ extern "C" { /* Long (arbitrary precision) integer object interface */ -typedef struct _longobject PyLongObject; /* Revealed in longintrepr.h */ - PyAPI_DATA(PyTypeObject) PyLong_Type; #define PyLong_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS) -#define PyLong_CheckExact(op) Py_IS_TYPE(op, &PyLong_Type) +#define PyLong_CheckExact(op) Py_IS_TYPE((op), &PyLong_Type) PyAPI_FUNC(PyObject *) PyLong_FromLong(long); PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLong(unsigned long); diff --git a/Include/memoryobject.h b/Include/memoryobject.h index 306028f4b22..2c9146aa2b5 100644 --- a/Include/memoryobject.h +++ b/Include/memoryobject.h @@ -6,64 +6,26 @@ extern "C" { #endif -#ifndef Py_LIMITED_API -PyAPI_DATA(PyTypeObject) _PyManagedBuffer_Type; -#endif PyAPI_DATA(PyTypeObject) PyMemoryView_Type; -#define PyMemoryView_Check(op) Py_IS_TYPE(op, &PyMemoryView_Type) - -#ifndef Py_LIMITED_API -/* Get a pointer to the memoryview's private copy of the exporter's buffer. */ -#define PyMemoryView_GET_BUFFER(op) (&((PyMemoryViewObject *)(op))->view) -/* Get a pointer to the exporting object (this may be NULL!). */ -#define PyMemoryView_GET_BASE(op) (((PyMemoryViewObject *)(op))->view.obj) -#endif +#define PyMemoryView_Check(op) Py_IS_TYPE((op), &PyMemoryView_Type) PyAPI_FUNC(PyObject *) PyMemoryView_FromObject(PyObject *base); #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject *) PyMemoryView_FromMemory(char *mem, Py_ssize_t size, int flags); #endif -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) PyMemoryView_FromBuffer(Py_buffer *info); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030b0000 +PyAPI_FUNC(PyObject *) PyMemoryView_FromBuffer(const Py_buffer *info); #endif PyAPI_FUNC(PyObject *) PyMemoryView_GetContiguous(PyObject *base, int buffertype, char order); - -/* The structs are declared here so that macros can work, but they shouldn't - be considered public. Don't access their fields directly, use the macros - and functions instead! */ #ifndef Py_LIMITED_API -#define _Py_MANAGED_BUFFER_RELEASED 0x001 /* access to exporter blocked */ -#define _Py_MANAGED_BUFFER_FREE_FORMAT 0x002 /* free format */ -typedef struct { - PyObject_HEAD - int flags; /* state flags */ - Py_ssize_t exports; /* number of direct memoryview exports */ - Py_buffer master; /* snapshot buffer obtained from the original exporter */ -} _PyManagedBufferObject; - - -/* memoryview state flags */ -#define _Py_MEMORYVIEW_RELEASED 0x001 /* access to master buffer blocked */ -#define _Py_MEMORYVIEW_C 0x002 /* C-contiguous layout */ -#define _Py_MEMORYVIEW_FORTRAN 0x004 /* Fortran contiguous layout */ -#define _Py_MEMORYVIEW_SCALAR 0x008 /* scalar: ndim = 0 */ -#define _Py_MEMORYVIEW_PIL 0x010 /* PIL-style layout */ - -typedef struct { - PyObject_VAR_HEAD - _PyManagedBufferObject *mbuf; /* managed buffer */ - Py_hash_t hash; /* hash value for read-only views */ - int flags; /* state flags */ - Py_ssize_t exports; /* number of buffer re-exports */ - Py_buffer view; /* private copy of the exporter's view */ - PyObject *weakreflist; - Py_ssize_t ob_array[1]; /* shape, strides, suboffsets */ -} PyMemoryViewObject; +# define Py_CPYTHON_MEMORYOBJECT_H +# include "cpython/memoryobject.h" +# undef Py_CPYTHON_MEMORYOBJECT_H #endif #ifdef __cplusplus diff --git a/Include/methodobject.h b/Include/methodobject.h index 1be5873a305..72af5ad933d 100644 --- a/Include/methodobject.h +++ b/Include/methodobject.h @@ -13,8 +13,8 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyCFunction_Type; -#define PyCFunction_CheckExact(op) Py_IS_TYPE(op, &PyCFunction_Type) -#define PyCFunction_Check(op) PyObject_TypeCheck(op, &PyCFunction_Type) +#define PyCFunction_CheckExact(op) Py_IS_TYPE((op), &PyCFunction_Type) +#define PyCFunction_Check(op) PyObject_TypeCheck((op), &PyCFunction_Type) typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); typedef PyObject *(*_PyCFunctionFast) (PyObject *, PyObject *const *, Py_ssize_t); @@ -26,6 +26,25 @@ typedef PyObject *(*_PyCFunctionFastWithKeywords) (PyObject *, typedef PyObject *(*PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *); +// Cast an function to the PyCFunction type to use it with PyMethodDef. +// +// This macro can be used to prevent compiler warnings if the first parameter +// uses a different pointer type than PyObject* (ex: METH_VARARGS and METH_O +// calling conventions). +// +// The macro can also be used for METH_FASTCALL and METH_VARARGS|METH_KEYWORDS +// calling conventions to avoid compiler warnings because the function has more +// than 2 parameters. The macro first casts the function to the +// "void func(void)" type to prevent compiler warnings. +// +// If a function is declared with the METH_NOARGS calling convention, it must +// have 2 parameters. Since the second parameter is unused, Py_UNUSED() can be +// used to prevent a compiler warning. If the function has a single parameter, +// it triggers an undefined behavior when Python calls it with 2 parameters +// (bpo-33012). +#define _PyCFunction_CAST(func) \ + _Py_CAST(PyCFunction, _Py_CAST(void(*)(void), (func))) + PyAPI_FUNC(PyCFunction) PyCFunction_GetFunction(PyObject *); PyAPI_FUNC(PyObject *) PyCFunction_GetSelf(PyObject *); PyAPI_FUNC(int) PyCFunction_GetFlags(PyObject *); @@ -39,7 +58,6 @@ struct PyMethodDef { describe the args expected by the C func */ const char *ml_doc; /* The __doc__ attribute, or NULL */ }; -typedef struct PyMethodDef PyMethodDef; /* PyCFunction_New is declared as a function for stable ABI (declaration is * needed for e.g. GCC with -fvisibility=hidden), but redefined as a macro diff --git a/Include/modsupport.h b/Include/modsupport.h index baf47f0038d..4e369bd56b4 100644 --- a/Include/modsupport.h +++ b/Include/modsupport.h @@ -19,19 +19,6 @@ extern "C" { #define PyArg_VaParseTupleAndKeywords _PyArg_VaParseTupleAndKeywords_SizeT #define Py_BuildValue _Py_BuildValue_SizeT #define Py_VaBuildValue _Py_VaBuildValue_SizeT -#ifndef Py_LIMITED_API -#define _Py_VaBuildStack _Py_VaBuildStack_SizeT -#endif -#else -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list); -PyAPI_FUNC(PyObject **) _Py_VaBuildStack_SizeT( - PyObject **small_stack, - Py_ssize_t small_stack_len, - const char *format, - va_list va, - Py_ssize_t *p_nargs); -#endif /* !Py_LIMITED_API */ #endif /* Due to a glitch in 3.2, the _SizeT versions weren't exported from the DLL. */ @@ -50,100 +37,7 @@ PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...); PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...); -#define ANY_VARARGS(n) (n == PY_SSIZE_T_MAX) -#ifndef Py_LIMITED_API -PyAPI_FUNC(int) _PyArg_UnpackStack( - PyObject *const *args, - Py_ssize_t nargs, - const char *name, - Py_ssize_t min, - Py_ssize_t max, - ...); - -PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kwargs); -PyAPI_FUNC(int) _PyArg_NoKwnames(const char *funcname, PyObject *kwnames); -PyAPI_FUNC(int) _PyArg_NoPositional(const char *funcname, PyObject *args); -#define _PyArg_NoKeywords(funcname, kwargs) \ - ((kwargs) == NULL || _PyArg_NoKeywords((funcname), (kwargs))) -#define _PyArg_NoKwnames(funcname, kwnames) \ - ((kwnames) == NULL || _PyArg_NoKwnames((funcname), (kwnames))) -#define _PyArg_NoPositional(funcname, args) \ - ((args) == NULL || _PyArg_NoPositional((funcname), (args))) - -PyAPI_FUNC(void) _PyArg_BadArgument(const char *, const char *, const char *, PyObject *); -PyAPI_FUNC(int) _PyArg_CheckPositional(const char *, Py_ssize_t, - Py_ssize_t, Py_ssize_t); -#define _PyArg_CheckPositional(funcname, nargs, min, max) \ - ((!ANY_VARARGS(max) && (min) <= (nargs) && (nargs) <= (max)) \ - || _PyArg_CheckPositional((funcname), (nargs), (min), (max))) - -#endif - PyAPI_FUNC(PyObject *) Py_VaBuildValue(const char *, va_list); -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject **) _Py_VaBuildStack( - PyObject **small_stack, - Py_ssize_t small_stack_len, - const char *format, - va_list va, - Py_ssize_t *p_nargs); -#endif - -#ifndef Py_LIMITED_API -typedef struct _PyArg_Parser { - const char *format; - const char * const *keywords; - const char *fname; - const char *custom_msg; - int pos; /* number of positional-only arguments */ - int min; /* minimal number of arguments */ - int max; /* maximal number of positional arguments */ - PyObject *kwtuple; /* tuple of keyword parameter names */ - struct _PyArg_Parser *next; -} _PyArg_Parser; -#ifdef PY_SSIZE_T_CLEAN -#define _PyArg_ParseTupleAndKeywordsFast _PyArg_ParseTupleAndKeywordsFast_SizeT -#define _PyArg_ParseStack _PyArg_ParseStack_SizeT -#define _PyArg_ParseStackAndKeywords _PyArg_ParseStackAndKeywords_SizeT -#define _PyArg_VaParseTupleAndKeywordsFast _PyArg_VaParseTupleAndKeywordsFast_SizeT -#endif -PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *, - struct _PyArg_Parser *, ...); -PyAPI_FUNC(int) _PyArg_ParseStack( - PyObject *const *args, - Py_ssize_t nargs, - const char *format, - ...); -PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords( - PyObject *const *args, - Py_ssize_t nargs, - PyObject *kwnames, - struct _PyArg_Parser *, - ...); -PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *, - struct _PyArg_Parser *, va_list); -PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywords( - PyObject *const *args, Py_ssize_t nargs, - PyObject *kwargs, PyObject *kwnames, - struct _PyArg_Parser *parser, - int minpos, int maxpos, int minkw, - PyObject **buf); - -PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywordsWithVararg( - PyObject *const *args, Py_ssize_t nargs, - PyObject *kwargs, PyObject *kwnames, - struct _PyArg_Parser *parser, - int minpos, int maxpos, int minkw, - int vararg, PyObject **buf); - -#define _PyArg_UnpackKeywords(args, nargs, kwargs, kwnames, parser, minpos, maxpos, minkw, buf) \ - (((minkw) == 0 && (kwargs) == NULL && (kwnames) == NULL && \ - (minpos) <= (nargs) && (nargs) <= (maxpos) && args != NULL) ? (args) : \ - _PyArg_UnpackKeywords((args), (nargs), (kwargs), (kwnames), (parser), \ - (minpos), (maxpos), (minkw), (buf))) - -void _PyArg_Fini(void); -#endif /* Py_LIMITED_API */ // Add an attribute with name 'name' and value 'obj' to the module 'mod. // On success, return 0 on success. @@ -156,12 +50,14 @@ PyAPI_FUNC(int) PyModule_AddObject(PyObject *mod, const char *, PyObject *value) PyAPI_FUNC(int) PyModule_AddIntConstant(PyObject *, const char *, long); PyAPI_FUNC(int) PyModule_AddStringConstant(PyObject *, const char *, const char *); + #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000 /* New in 3.9 */ PyAPI_FUNC(int) PyModule_AddType(PyObject *module, PyTypeObject *type); #endif /* Py_LIMITED_API */ -#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant(m, #c, c) -#define PyModule_AddStringMacro(m, c) PyModule_AddStringConstant(m, #c, c) + +#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c)) +#define PyModule_AddStringMacro(m, c) PyModule_AddStringConstant((m), #c, (c)) #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 /* New in 3.5 */ @@ -232,19 +128,14 @@ PyAPI_FUNC(int) PyModule_ExecDef(PyObject *module, PyModuleDef *def); #define PyModule_FromDefAndSpec2 PyModule_FromDefAndSpec2TraceRefs #endif -PyAPI_FUNC(PyObject *) PyModule_Create2(struct PyModuleDef*, - int apiver); -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PyModule_CreateInitialized(struct PyModuleDef*, - int apiver); -#endif +PyAPI_FUNC(PyObject *) PyModule_Create2(PyModuleDef*, int apiver); #ifdef Py_LIMITED_API #define PyModule_Create(module) \ - PyModule_Create2(module, PYTHON_ABI_VERSION) + PyModule_Create2((module), PYTHON_ABI_VERSION) #else #define PyModule_Create(module) \ - PyModule_Create2(module, PYTHON_API_VERSION) + PyModule_Create2((module), PYTHON_API_VERSION) #endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 @@ -255,15 +146,18 @@ PyAPI_FUNC(PyObject *) PyModule_FromDefAndSpec2(PyModuleDef *def, #ifdef Py_LIMITED_API #define PyModule_FromDefAndSpec(module, spec) \ - PyModule_FromDefAndSpec2(module, spec, PYTHON_ABI_VERSION) + PyModule_FromDefAndSpec2((module), (spec), PYTHON_ABI_VERSION) #else #define PyModule_FromDefAndSpec(module, spec) \ - PyModule_FromDefAndSpec2(module, spec, PYTHON_API_VERSION) + PyModule_FromDefAndSpec2((module), (spec), PYTHON_API_VERSION) #endif /* Py_LIMITED_API */ + #endif /* New in 3.5 */ #ifndef Py_LIMITED_API -PyAPI_DATA(const char *) _Py_PackageContext; +# define Py_CPYTHON_MODSUPPORT_H +# include "cpython/modsupport.h" +# undef Py_CPYTHON_MODSUPPORT_H #endif #ifdef __cplusplus diff --git a/Include/moduleobject.h b/Include/moduleobject.h index 49b116ca1c3..555564ec73b 100644 --- a/Include/moduleobject.h +++ b/Include/moduleobject.h @@ -9,8 +9,8 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyModule_Type; -#define PyModule_Check(op) PyObject_TypeCheck(op, &PyModule_Type) -#define PyModule_CheckExact(op) Py_IS_TYPE(op, &PyModule_Type) +#define PyModule_Check(op) PyObject_TypeCheck((op), &PyModule_Type) +#define PyModule_CheckExact(op) Py_IS_TYPE((op), &PyModule_Type) #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject *) PyModule_NewObject( @@ -32,36 +32,49 @@ PyAPI_FUNC(void) _PyModule_Clear(PyObject *); PyAPI_FUNC(void) _PyModule_ClearDict(PyObject *); PyAPI_FUNC(int) _PyModuleSpec_IsInitializing(PyObject *); #endif -PyAPI_FUNC(struct PyModuleDef*) PyModule_GetDef(PyObject*); +PyAPI_FUNC(PyModuleDef*) PyModule_GetDef(PyObject*); PyAPI_FUNC(void*) PyModule_GetState(PyObject*); #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 /* New in 3.5 */ -PyAPI_FUNC(PyObject *) PyModuleDef_Init(struct PyModuleDef*); +PyAPI_FUNC(PyObject *) PyModuleDef_Init(PyModuleDef*); PyAPI_DATA(PyTypeObject) PyModuleDef_Type; #endif typedef struct PyModuleDef_Base { PyObject_HEAD + /* The function used to re-initialize the module. + This is only set for legacy (single-phase init) extension modules + and only used for those that support multiple initializations + (m_size >= 0). + It is set by _PyImport_LoadDynamicModuleWithSpec() + and _imp.create_builtin(). */ PyObject* (*m_init)(void); + /* The module's index into its interpreter's modules_by_index cache. + This is set for all extension modules but only used for legacy ones. + (See PyInterpreterState.modules_by_index for more info.) + It is set by PyModuleDef_Init(). */ Py_ssize_t m_index; + /* A copy of the module's __dict__ after the first time it was loaded. + This is only set/used for legacy modules that do not support + multiple initializations. + It is set by _PyImport_FixupExtensionObject(). */ PyObject* m_copy; } PyModuleDef_Base; -#define PyModuleDef_HEAD_INIT { \ - PyObject_HEAD_INIT(NULL) \ - NULL, /* m_init */ \ - 0, /* m_index */ \ - NULL, /* m_copy */ \ +#define PyModuleDef_HEAD_INIT { \ + PyObject_HEAD_INIT(_Py_NULL) \ + _Py_NULL, /* m_init */ \ + 0, /* m_index */ \ + _Py_NULL, /* m_copy */ \ } -struct PyModuleDef_Slot; #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 /* New in 3.5 */ -typedef struct PyModuleDef_Slot{ +struct PyModuleDef_Slot { int slot; void *value; -} PyModuleDef_Slot; +}; #define Py_mod_create 1 #define Py_mod_exec 2 @@ -72,17 +85,17 @@ typedef struct PyModuleDef_Slot{ #endif /* New in 3.5 */ -typedef struct PyModuleDef{ +struct PyModuleDef { PyModuleDef_Base m_base; const char* m_name; const char* m_doc; Py_ssize_t m_size; PyMethodDef *m_methods; - struct PyModuleDef_Slot* m_slots; + PyModuleDef_Slot *m_slots; traverseproc m_traverse; inquiry m_clear; freefunc m_free; -} PyModuleDef; +}; // Internal C API diff --git a/Include/object.h b/Include/object.h index 33df303a44e..3774f126730 100644 --- a/Include/object.h +++ b/Include/object.h @@ -1,6 +1,5 @@ #ifndef Py_OBJECT_H #define Py_OBJECT_H - #ifdef __cplusplus extern "C" { #endif @@ -52,6 +51,8 @@ A standard interface exists for objects that contain an array of items whose size is determined when the object is allocated. */ +#include "pystats.h" + /* Py_DEBUG implies Py_REF_DEBUG. */ #if defined(Py_DEBUG) && !defined(Py_REF_DEBUG) # define Py_REF_DEBUG @@ -61,17 +62,13 @@ whose size is determined when the object is allocated. # error Py_LIMITED_API is incompatible with Py_TRACE_REFS #endif -/* PyTypeObject structure is defined in cpython/object.h. - In Py_LIMITED_API, PyTypeObject is an opaque structure. */ -typedef struct _typeobject PyTypeObject; - #ifdef Py_TRACE_REFS /* Define pointers to support a doubly-linked list of all live heap objects. */ #define _PyObject_HEAD_EXTRA \ - struct _object *_ob_next; \ - struct _object *_ob_prev; + PyObject *_ob_next; \ + PyObject *_ob_prev; -#define _PyObject_EXTRA_INIT 0, 0, +#define _PyObject_EXTRA_INIT _Py_NULL, _Py_NULL, #else # define _PyObject_HEAD_EXTRA @@ -83,10 +80,10 @@ typedef struct _typeobject PyTypeObject; #define PyObject_HEAD_INIT(type) \ { _PyObject_EXTRA_INIT \ - 1, type }, + 1, (type) }, #define PyVarObject_HEAD_INIT(type, size) \ - { PyObject_HEAD_INIT(type) size }, + { PyObject_HEAD_INIT(type) (size) }, /* PyObject_VAR_HEAD defines the initial segment of all variable-size * container objects. These end with a declaration of an array with 1 @@ -102,15 +99,14 @@ typedef struct _typeobject PyTypeObject; * by hand. Similarly every pointer to a variable-size Python object can, * in addition, be cast to PyVarObject*. */ -typedef struct _object { +struct _object { _PyObject_HEAD_EXTRA Py_ssize_t ob_refcnt; PyTypeObject *ob_type; -} PyObject; +}; /* Cast argument to PyObject* type. */ -#define _PyObject_CAST(op) ((PyObject*)(op)) -#define _PyObject_CAST_CONST(op) ((const PyObject*)(op)) +#define _PyObject_CAST(op) _Py_CAST(PyObject*, (op)) typedef struct { PyObject ob_base; @@ -118,8 +114,7 @@ typedef struct { } PyVarObject; /* Cast argument to PyVarObject* type. */ -#define _PyVarObject_CAST(op) ((PyVarObject*)(op)) -#define _PyVarObject_CAST_CONST(op) ((const PyVarObject*)(op)) +#define _PyVarObject_CAST(op) _Py_CAST(PyVarObject*, (op)) // Test if the 'x' object is the 'y' object, the same as "x is y" in Python. @@ -127,49 +122,62 @@ PyAPI_FUNC(int) Py_Is(PyObject *x, PyObject *y); #define Py_Is(x, y) ((x) == (y)) -static inline Py_ssize_t _Py_REFCNT(const PyObject *ob) { +static inline Py_ssize_t Py_REFCNT(PyObject *ob) { return ob->ob_refcnt; } -#define Py_REFCNT(ob) _Py_REFCNT(_PyObject_CAST_CONST(ob)) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 +# define Py_REFCNT(ob) Py_REFCNT(_PyObject_CAST(ob)) +#endif // bpo-39573: The Py_SET_TYPE() function must be used to set an object type. -static inline PyTypeObject* _Py_TYPE(const PyObject *ob) { +static inline PyTypeObject* Py_TYPE(PyObject *ob) { return ob->ob_type; } -#define Py_TYPE(ob) _Py_TYPE(_PyObject_CAST_CONST(ob)) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 +# define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob)) +#endif // bpo-39573: The Py_SET_SIZE() function must be used to set an object size. -static inline Py_ssize_t _Py_SIZE(const PyVarObject *ob) { - return ob->ob_size; +static inline Py_ssize_t Py_SIZE(PyObject *ob) { + PyVarObject *var_ob = _PyVarObject_CAST(ob); + return var_ob->ob_size; } -#define Py_SIZE(ob) _Py_SIZE(_PyVarObject_CAST_CONST(ob)) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 +# define Py_SIZE(ob) Py_SIZE(_PyObject_CAST(ob)) +#endif -static inline int _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) { - // bpo-44378: Don't use Py_TYPE() since Py_TYPE() requires a non-const - // object. - return ob->ob_type == type; +static inline int Py_IS_TYPE(PyObject *ob, PyTypeObject *type) { + return Py_TYPE(ob) == type; } -#define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST_CONST(ob), type) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 +# define Py_IS_TYPE(ob, type) Py_IS_TYPE(_PyObject_CAST(ob), (type)) +#endif -static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) { +static inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) { ob->ob_refcnt = refcnt; } -#define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 +# define Py_SET_REFCNT(ob, refcnt) Py_SET_REFCNT(_PyObject_CAST(ob), (refcnt)) +#endif -static inline void _Py_SET_TYPE(PyObject *ob, PyTypeObject *type) { +static inline void Py_SET_TYPE(PyObject *ob, PyTypeObject *type) { ob->ob_type = type; } -#define Py_SET_TYPE(ob, type) _Py_SET_TYPE(_PyObject_CAST(ob), type) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 +# define Py_SET_TYPE(ob, type) Py_SET_TYPE(_PyObject_CAST(ob), type) +#endif -static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) { +static inline void Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) { ob->ob_size = size; } -#define Py_SET_SIZE(ob, size) _Py_SET_SIZE(_PyVarObject_CAST(ob), size) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 +# define Py_SET_SIZE(ob, size) Py_SET_SIZE(_PyVarObject_CAST(ob), (size)) +#endif /* @@ -220,6 +228,11 @@ typedef int (*initproc)(PyObject *, PyObject *, PyObject *); typedef PyObject *(*newfunc)(PyTypeObject *, PyObject *, PyObject *); typedef PyObject *(*allocfunc)(PyTypeObject *, Py_ssize_t); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030c0000 // 3.12 +typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames); +#endif + typedef struct{ int slot; /* slot id, see below */ void *pfunc; /* function pointer */ @@ -242,21 +255,26 @@ PyAPI_FUNC(void*) PyType_GetSlot(PyTypeObject*, int); #endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000 PyAPI_FUNC(PyObject*) PyType_FromModuleAndSpec(PyObject *, PyType_Spec *, PyObject *); -PyAPI_FUNC(PyObject *) PyType_GetModule(struct _typeobject *); -PyAPI_FUNC(void *) PyType_GetModuleState(struct _typeobject *); +PyAPI_FUNC(PyObject *) PyType_GetModule(PyTypeObject *); +PyAPI_FUNC(void *) PyType_GetModuleState(PyTypeObject *); #endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030B0000 PyAPI_FUNC(PyObject *) PyType_GetName(PyTypeObject *); PyAPI_FUNC(PyObject *) PyType_GetQualName(PyTypeObject *); #endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030C0000 +PyAPI_FUNC(PyObject *) PyType_FromMetaclass(PyTypeObject*, PyObject*, PyType_Spec*, PyObject*); +#endif /* Generic type check */ PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *); -static inline int _PyObject_TypeCheck(PyObject *ob, PyTypeObject *type) { +static inline int PyObject_TypeCheck(PyObject *ob, PyTypeObject *type) { return Py_IS_TYPE(ob, type) || PyType_IsSubtype(Py_TYPE(ob), type); } -#define PyObject_TypeCheck(ob, type) _PyObject_TypeCheck(_PyObject_CAST(ob), type) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 +# define PyObject_TypeCheck(ob, type) PyObject_TypeCheck(_PyObject_CAST(ob), (type)) +#endif PyAPI_DATA(PyTypeObject) PyType_Type; /* built-in 'type' */ PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */ @@ -304,6 +322,11 @@ PyAPI_FUNC(void) PyObject_ClearWeakRefs(PyObject *); */ PyAPI_FUNC(PyObject *) PyObject_Dir(PyObject *); +/* Pickle support. */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyObject_GetState(PyObject *); +#endif + /* Helpers for printing recursive container types */ PyAPI_FUNC(int) Py_ReprEnter(PyObject *); @@ -334,6 +357,21 @@ given type object has a specified feature. #ifndef Py_LIMITED_API +/* Track types initialized using _PyStaticType_InitBuiltin(). */ +#define _Py_TPFLAGS_STATIC_BUILTIN (1 << 1) + +/* Placement of weakref pointers are managed by the VM, not by the type. + * The VM will automatically set tp_weaklistoffset. + */ +#define Py_TPFLAGS_MANAGED_WEAKREF (1 << 3) + +/* Placement of dict (and values) pointers are managed by the VM, not by the type. + * The VM will automatically set tp_dictoffset. + */ +#define Py_TPFLAGS_MANAGED_DICT (1 << 4) + +#define Py_TPFLAGS_PREHEADER (Py_TPFLAGS_MANAGED_WEAKREF | Py_TPFLAGS_MANAGED_DICT) + /* Set if instances of the type object are treated as sequences for pattern matching */ #define Py_TPFLAGS_SEQUENCE (1 << 5) /* Set if instances of the type object are treated as mappings for pattern matching */ @@ -354,11 +392,13 @@ given type object has a specified feature. #define Py_TPFLAGS_BASETYPE (1UL << 10) /* Set if the type implements the vectorcall protocol (PEP 590) */ -#ifndef Py_LIMITED_API +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030C0000 #define Py_TPFLAGS_HAVE_VECTORCALL (1UL << 11) +#ifndef Py_LIMITED_API // Backwards compatibility alias for API that was provisional in Python 3.8 #define _Py_TPFLAGS_HAVE_VECTORCALL Py_TPFLAGS_HAVE_VECTORCALL #endif +#endif /* Set if the type is 'ready' -- fully initialized */ #define Py_TPFLAGS_READY (1UL << 12) @@ -469,12 +509,13 @@ PyAPI_FUNC(void) Py_DecRef(PyObject *); PyAPI_FUNC(void) _Py_IncRef(PyObject *); PyAPI_FUNC(void) _Py_DecRef(PyObject *); -static inline void _Py_INCREF(PyObject *op) +static inline void Py_INCREF(PyObject *op) { #if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000 // Stable ABI for Python 3.10 built in debug mode. _Py_IncRef(op); #else + _Py_INCREF_STAT_INC(); // Non-limited C API and limited C API for Python 3.9 and older access // directly PyObject.ob_refcnt. #ifdef Py_REF_DEBUG @@ -483,39 +524,44 @@ static inline void _Py_INCREF(PyObject *op) op->ob_refcnt++; #endif } -#define Py_INCREF(op) _Py_INCREF(_PyObject_CAST(op)) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 +# define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op)) +#endif -static inline void _Py_DECREF( -#if defined(Py_REF_DEBUG) && !(defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000) - const char *filename, int lineno, -#endif - PyObject *op) -{ #if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000 - // Stable ABI for Python 3.10 built in debug mode. +// Stable ABI for limited C API version 3.10 of Python debug build +static inline void Py_DECREF(PyObject *op) { _Py_DecRef(op); -#else - // Non-limited C API and limited C API for Python 3.9 and older access - // directly PyObject.ob_refcnt. -#ifdef Py_REF_DEBUG +} +#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op)) + +#elif defined(Py_REF_DEBUG) +static inline void Py_DECREF(const char *filename, int lineno, PyObject *op) +{ + _Py_DECREF_STAT_INC(); _Py_RefTotal--; -#endif if (--op->ob_refcnt != 0) { -#ifdef Py_REF_DEBUG if (op->ob_refcnt < 0) { _Py_NegativeRefcount(filename, lineno, op); } -#endif } else { _Py_Dealloc(op); } -#endif } -#if defined(Py_REF_DEBUG) && !(defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000) -# define Py_DECREF(op) _Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op)) +#define Py_DECREF(op) Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op)) + #else -# define Py_DECREF(op) _Py_DECREF(_PyObject_CAST(op)) +static inline void Py_DECREF(PyObject *op) +{ + _Py_DECREF_STAT_INC(); + // Non-limited C API and limited C API for Python 3.9 and older access + // directly PyObject.ob_refcnt. + if (--op->ob_refcnt == 0) { + _Py_Dealloc(op); + } +} +#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op)) #endif @@ -552,34 +598,65 @@ static inline void _Py_DECREF( * one of those can't cause problems -- but in part that relies on that * Python integers aren't currently weakly referencable. Best practice is * to use Py_CLEAR() even if you can't think of a reason for why you need to. + * + * gh-98724: Use a temporary variable to only evaluate the macro argument once, + * to avoid the duplication of side effects if the argument has side effects. + * + * gh-99701: If the PyObject* type is used with casting arguments to PyObject*, + * the code can be miscompiled with strict aliasing because of type punning. + * With strict aliasing, a compiler considers that two pointers of different + * types cannot read or write the same memory which enables optimization + * opportunities. + * + * If available, use _Py_TYPEOF() to use the 'op' type for temporary variables, + * and so avoid type punning. Otherwise, use memcpy() which causes type erasure + * and so prevents the compiler to reuse an old cached 'op' value after + * Py_CLEAR(). */ -#define Py_CLEAR(op) \ - do { \ - PyObject *_py_tmp = _PyObject_CAST(op); \ - if (_py_tmp != NULL) { \ - (op) = NULL; \ - Py_DECREF(_py_tmp); \ - } \ +#ifdef _Py_TYPEOF +#define Py_CLEAR(op) \ + do { \ + _Py_TYPEOF(op)* _tmp_op_ptr = &(op); \ + _Py_TYPEOF(op) _tmp_old_op = (*_tmp_op_ptr); \ + if (_tmp_old_op != NULL) { \ + *_tmp_op_ptr = _Py_NULL; \ + Py_DECREF(_tmp_old_op); \ + } \ } while (0) +#else +#define Py_CLEAR(op) \ + do { \ + PyObject **_tmp_op_ptr = _Py_CAST(PyObject**, &(op)); \ + PyObject *_tmp_old_op = (*_tmp_op_ptr); \ + if (_tmp_old_op != NULL) { \ + PyObject *_null_ptr = _Py_NULL; \ + memcpy(_tmp_op_ptr, &_null_ptr, sizeof(PyObject*)); \ + Py_DECREF(_tmp_old_op); \ + } \ + } while (0) +#endif + /* Function to use in case the object pointer can be NULL: */ -static inline void _Py_XINCREF(PyObject *op) +static inline void Py_XINCREF(PyObject *op) { - if (op != NULL) { + if (op != _Py_NULL) { Py_INCREF(op); } } +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 +# define Py_XINCREF(op) Py_XINCREF(_PyObject_CAST(op)) +#endif -#define Py_XINCREF(op) _Py_XINCREF(_PyObject_CAST(op)) - -static inline void _Py_XDECREF(PyObject *op) +static inline void Py_XDECREF(PyObject *op) { - if (op != NULL) { + if (op != _Py_NULL) { Py_DECREF(op); } } - -#define Py_XDECREF(op) _Py_XDECREF(_PyObject_CAST(op)) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 +# define Py_XDECREF(op) Py_XDECREF(_PyObject_CAST(op)) +#endif // Create a new strong reference to an object: // increment the reference count of the object and return the object. @@ -603,8 +680,13 @@ static inline PyObject* _Py_XNewRef(PyObject *obj) // Py_NewRef() and Py_XNewRef() are exported as functions for the stable ABI. // Names overridden with macros by static inline functions for best // performances. -#define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj)) -#define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj)) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 +# define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj)) +# define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj)) +#else +# define Py_NewRef(obj) _Py_NewRef(obj) +# define Py_XNewRef(obj) _Py_XNewRef(obj) +#endif /* @@ -742,19 +824,26 @@ PyType_HasFeature(PyTypeObject *type, unsigned long feature) return ((flags & feature) != 0); } -#define PyType_FastSubclass(type, flag) PyType_HasFeature(type, flag) +#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag)) -static inline int _PyType_Check(PyObject *op) { +static inline int PyType_Check(PyObject *op) { return PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS); } -#define PyType_Check(op) _PyType_Check(_PyObject_CAST(op)) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 +# define PyType_Check(op) PyType_Check(_PyObject_CAST(op)) +#endif -static inline int _PyType_CheckExact(PyObject *op) { +#define _PyType_CAST(op) \ + (assert(PyType_Check(op)), _Py_CAST(PyTypeObject*, (op))) + +static inline int PyType_CheckExact(PyObject *op) { return Py_IS_TYPE(op, &PyType_Type); } -#define PyType_CheckExact(op) _PyType_CheckExact(_PyObject_CAST(op)) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 +# define PyType_CheckExact(op) PyType_CheckExact(_PyObject_CAST(op)) +#endif #ifdef __cplusplus } #endif -#endif /* !Py_OBJECT_H */ +#endif // !Py_OBJECT_H diff --git a/Include/objimpl.h b/Include/objimpl.h index 9b98c112ac2..dde8df34835 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -135,14 +135,14 @@ PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t); // Alias to PyObject_New(). In Python 3.8, PyObject_NEW() called directly // PyObject_MALLOC() with _PyObject_SIZE(). -#define PyObject_NEW(type, typeobj) PyObject_New(type, typeobj) +#define PyObject_NEW(type, typeobj) PyObject_New(type, (typeobj)) #define PyObject_NewVar(type, typeobj, n) \ ( (type *) _PyObject_NewVar((typeobj), (n)) ) // Alias to PyObject_NewVar(). In Python 3.8, PyObject_NEW_VAR() called // directly PyObject_MALLOC() with _PyObject_VAR_SIZE(). -#define PyObject_NEW_VAR(type, typeobj, n) PyObject_NewVar(type, typeobj, n) +#define PyObject_NEW_VAR(type, typeobj, n) PyObject_NewVar(type, (typeobj), (n)) /* @@ -182,9 +182,9 @@ PyAPI_FUNC(void) PyObject_GC_UnTrack(void *); PyAPI_FUNC(void) PyObject_GC_Del(void *); #define PyObject_GC_New(type, typeobj) \ - ( (type *) _PyObject_GC_New(typeobj) ) + _Py_CAST(type*, _PyObject_GC_New(typeobj)) #define PyObject_GC_NewVar(type, typeobj, n) \ - ( (type *) _PyObject_GC_NewVar((typeobj), (n)) ) + _Py_CAST(type*, _PyObject_GC_NewVar((typeobj), (n))) PyAPI_FUNC(int) PyObject_GC_IsTracked(PyObject *); PyAPI_FUNC(int) PyObject_GC_IsFinalized(PyObject *); diff --git a/Include/opcode.h b/Include/opcode.h index 3ec89bd4c0b..827f9931beb 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -1,4 +1,5 @@ -/* Auto-generated by Tools/scripts/generate_opcode_h.py from Lib/opcode.py */ +// Auto-generated by Tools/build/generate_opcode_h.py from Lib/opcode.py + #ifndef Py_OPCODE_H #define Py_OPCODE_H #ifdef __cplusplus @@ -7,216 +8,228 @@ extern "C" { /* Instruction opcodes for compiled code */ -#define POP_TOP 1 -#define ROT_TWO 2 -#define ROT_THREE 3 -#define DUP_TOP 4 -#define DUP_TOP_TWO 5 -#define ROT_FOUR 6 -#define NOP 9 -#define UNARY_POSITIVE 10 -#define UNARY_NEGATIVE 11 -#define UNARY_NOT 12 -#define UNARY_INVERT 15 -#define BINARY_SUBSCR 25 -#define GET_LEN 30 -#define MATCH_MAPPING 31 -#define MATCH_SEQUENCE 32 -#define MATCH_KEYS 33 -#define PUSH_EXC_INFO 35 -#define POP_EXCEPT_AND_RERAISE 37 -#define WITH_EXCEPT_START 49 -#define GET_AITER 50 -#define GET_ANEXT 51 -#define BEFORE_ASYNC_WITH 52 -#define BEFORE_WITH 53 -#define END_ASYNC_FOR 54 -#define STORE_SUBSCR 60 -#define DELETE_SUBSCR 61 -#define GET_ITER 68 -#define GET_YIELD_FROM_ITER 69 -#define PRINT_EXPR 70 -#define LOAD_BUILD_CLASS 71 -#define YIELD_FROM 72 -#define GET_AWAITABLE 73 -#define LOAD_ASSERTION_ERROR 74 -#define LIST_TO_TUPLE 82 -#define RETURN_VALUE 83 -#define IMPORT_STAR 84 -#define SETUP_ANNOTATIONS 85 -#define YIELD_VALUE 86 -#define POP_EXCEPT 89 -#define HAVE_ARGUMENT 90 -#define STORE_NAME 90 -#define DELETE_NAME 91 -#define UNPACK_SEQUENCE 92 -#define FOR_ITER 93 -#define UNPACK_EX 94 -#define STORE_ATTR 95 -#define DELETE_ATTR 96 -#define STORE_GLOBAL 97 -#define DELETE_GLOBAL 98 -#define ROT_N 99 -#define LOAD_CONST 100 -#define LOAD_NAME 101 -#define BUILD_TUPLE 102 -#define BUILD_LIST 103 -#define BUILD_SET 104 -#define BUILD_MAP 105 -#define LOAD_ATTR 106 -#define COMPARE_OP 107 -#define IMPORT_NAME 108 -#define IMPORT_FROM 109 -#define JUMP_FORWARD 110 -#define JUMP_IF_FALSE_OR_POP 111 -#define JUMP_IF_TRUE_OR_POP 112 -#define JUMP_ABSOLUTE 113 -#define POP_JUMP_IF_FALSE 114 -#define POP_JUMP_IF_TRUE 115 -#define LOAD_GLOBAL 116 -#define IS_OP 117 -#define CONTAINS_OP 118 -#define RERAISE 119 -#define COPY 120 -#define JUMP_IF_NOT_EXC_MATCH 121 -#define BINARY_OP 122 -#define LOAD_FAST 124 -#define STORE_FAST 125 -#define DELETE_FAST 126 -#define GEN_START 129 -#define RAISE_VARARGS 130 -#define CALL_FUNCTION 131 -#define MAKE_FUNCTION 132 -#define BUILD_SLICE 133 -#define MAKE_CELL 135 -#define LOAD_CLOSURE 136 -#define LOAD_DEREF 137 -#define STORE_DEREF 138 -#define DELETE_DEREF 139 -#define CALL_FUNCTION_KW 141 -#define CALL_FUNCTION_EX 142 -#define EXTENDED_ARG 144 -#define LIST_APPEND 145 -#define SET_ADD 146 -#define MAP_ADD 147 -#define LOAD_CLASSDEREF 148 -#define MATCH_CLASS 152 -#define FORMAT_VALUE 155 -#define BUILD_CONST_KEY_MAP 156 -#define BUILD_STRING 157 -#define LOAD_METHOD 160 -#define CALL_METHOD 161 -#define LIST_EXTEND 162 -#define SET_UPDATE 163 -#define DICT_MERGE 164 -#define DICT_UPDATE 165 -#define CALL_METHOD_KW 166 -#define BINARY_OP_ADAPTIVE 7 -#define BINARY_OP_ADD_INT 8 -#define BINARY_OP_ADD_FLOAT 13 -#define BINARY_OP_ADD_UNICODE 14 -#define BINARY_OP_INPLACE_ADD_UNICODE 16 -#define BINARY_OP_MULTIPLY_INT 17 -#define BINARY_OP_MULTIPLY_FLOAT 18 -#define BINARY_OP_SUBTRACT_INT 19 -#define BINARY_OP_SUBTRACT_FLOAT 20 -#define BINARY_SUBSCR_ADAPTIVE 21 -#define BINARY_SUBSCR_GETITEM 22 -#define BINARY_SUBSCR_LIST_INT 23 -#define BINARY_SUBSCR_TUPLE_INT 24 -#define BINARY_SUBSCR_DICT 26 -#define STORE_SUBSCR_ADAPTIVE 27 -#define STORE_SUBSCR_LIST_INT 28 -#define STORE_SUBSCR_DICT 29 -#define CALL_FUNCTION_ADAPTIVE 34 -#define CALL_FUNCTION_BUILTIN_O 36 -#define CALL_FUNCTION_BUILTIN_FAST 38 -#define CALL_FUNCTION_LEN 39 -#define CALL_FUNCTION_ISINSTANCE 40 -#define CALL_FUNCTION_PY_SIMPLE 41 -#define JUMP_ABSOLUTE_QUICK 42 -#define LOAD_ATTR_ADAPTIVE 43 -#define LOAD_ATTR_INSTANCE_VALUE 44 -#define LOAD_ATTR_WITH_HINT 45 -#define LOAD_ATTR_SLOT 46 -#define LOAD_ATTR_MODULE 47 -#define LOAD_GLOBAL_ADAPTIVE 48 -#define LOAD_GLOBAL_MODULE 55 -#define LOAD_GLOBAL_BUILTIN 56 -#define LOAD_METHOD_ADAPTIVE 57 -#define LOAD_METHOD_CACHED 58 -#define LOAD_METHOD_CLASS 59 -#define LOAD_METHOD_MODULE 62 -#define LOAD_METHOD_NO_DICT 63 -#define STORE_ATTR_ADAPTIVE 64 -#define STORE_ATTR_INSTANCE_VALUE 65 -#define STORE_ATTR_SLOT 66 -#define STORE_ATTR_WITH_HINT 67 -#define LOAD_FAST__LOAD_FAST 75 -#define STORE_FAST__LOAD_FAST 76 -#define LOAD_FAST__LOAD_CONST 77 -#define LOAD_CONST__LOAD_FAST 78 -#define STORE_FAST__STORE_FAST 79 -#define DO_TRACING 255 -#ifdef NEED_OPCODE_JUMP_TABLES -static uint32_t _PyOpcode_RelativeJump[8] = { - 0U, - 0U, - 536870912U, - 16384U, - 0U, - 0U, - 0U, - 0U, -}; -static uint32_t _PyOpcode_Jump[8] = { - 0U, - 0U, - 536870912U, - 34586624U, - 0U, - 0U, - 0U, - 0U, -}; -#endif /* OPCODE_TABLES */ +#define CACHE 0 +#define POP_TOP 1 +#define PUSH_NULL 2 +#define INTERPRETER_EXIT 3 +#define END_FOR 4 +#define NOP 9 +#define UNARY_NEGATIVE 11 +#define UNARY_NOT 12 +#define UNARY_INVERT 15 +#define BINARY_SUBSCR 25 +#define BINARY_SLICE 26 +#define STORE_SLICE 27 +#define GET_LEN 30 +#define MATCH_MAPPING 31 +#define MATCH_SEQUENCE 32 +#define MATCH_KEYS 33 +#define PUSH_EXC_INFO 35 +#define CHECK_EXC_MATCH 36 +#define CHECK_EG_MATCH 37 +#define WITH_EXCEPT_START 49 +#define GET_AITER 50 +#define GET_ANEXT 51 +#define BEFORE_ASYNC_WITH 52 +#define BEFORE_WITH 53 +#define END_ASYNC_FOR 54 +#define CLEANUP_THROW 55 +#define STORE_SUBSCR 60 +#define DELETE_SUBSCR 61 +#define GET_ITER 68 +#define GET_YIELD_FROM_ITER 69 +#define LOAD_BUILD_CLASS 71 +#define LOAD_ASSERTION_ERROR 74 +#define RETURN_GENERATOR 75 +#define RETURN_VALUE 83 +#define SETUP_ANNOTATIONS 85 +#define PREP_RERAISE_STAR 88 +#define POP_EXCEPT 89 +#define HAVE_ARGUMENT 90 +#define STORE_NAME 90 +#define DELETE_NAME 91 +#define UNPACK_SEQUENCE 92 +#define FOR_ITER 93 +#define UNPACK_EX 94 +#define STORE_ATTR 95 +#define DELETE_ATTR 96 +#define STORE_GLOBAL 97 +#define DELETE_GLOBAL 98 +#define SWAP 99 +#define LOAD_CONST 100 +#define LOAD_NAME 101 +#define BUILD_TUPLE 102 +#define BUILD_LIST 103 +#define BUILD_SET 104 +#define BUILD_MAP 105 +#define LOAD_ATTR 106 +#define COMPARE_OP 107 +#define IMPORT_NAME 108 +#define IMPORT_FROM 109 +#define JUMP_FORWARD 110 +#define JUMP_IF_FALSE_OR_POP 111 +#define JUMP_IF_TRUE_OR_POP 112 +#define POP_JUMP_IF_FALSE 114 +#define POP_JUMP_IF_TRUE 115 +#define LOAD_GLOBAL 116 +#define IS_OP 117 +#define CONTAINS_OP 118 +#define RERAISE 119 +#define COPY 120 +#define BINARY_OP 122 +#define SEND 123 +#define LOAD_FAST 124 +#define STORE_FAST 125 +#define DELETE_FAST 126 +#define LOAD_FAST_CHECK 127 +#define POP_JUMP_IF_NOT_NONE 128 +#define POP_JUMP_IF_NONE 129 +#define RAISE_VARARGS 130 +#define GET_AWAITABLE 131 +#define MAKE_FUNCTION 132 +#define BUILD_SLICE 133 +#define JUMP_BACKWARD_NO_INTERRUPT 134 +#define MAKE_CELL 135 +#define LOAD_CLOSURE 136 +#define LOAD_DEREF 137 +#define STORE_DEREF 138 +#define DELETE_DEREF 139 +#define JUMP_BACKWARD 140 +#define COMPARE_AND_BRANCH 141 +#define CALL_FUNCTION_EX 142 +#define EXTENDED_ARG 144 +#define LIST_APPEND 145 +#define SET_ADD 146 +#define MAP_ADD 147 +#define LOAD_CLASSDEREF 148 +#define COPY_FREE_VARS 149 +#define YIELD_VALUE 150 +#define RESUME 151 +#define MATCH_CLASS 152 +#define FORMAT_VALUE 155 +#define BUILD_CONST_KEY_MAP 156 +#define BUILD_STRING 157 +#define LIST_EXTEND 162 +#define SET_UPDATE 163 +#define DICT_MERGE 164 +#define DICT_UPDATE 165 +#define CALL 171 +#define KW_NAMES 172 +#define CALL_INTRINSIC_1 173 +#define MIN_PSEUDO_OPCODE 256 +#define SETUP_FINALLY 256 +#define SETUP_CLEANUP 257 +#define SETUP_WITH 258 +#define POP_BLOCK 259 +#define JUMP 260 +#define JUMP_NO_INTERRUPT 261 +#define LOAD_METHOD 262 +#define MAX_PSEUDO_OPCODE 262 +#define BINARY_OP_ADD_FLOAT 5 +#define BINARY_OP_ADD_INT 6 +#define BINARY_OP_ADD_UNICODE 7 +#define BINARY_OP_INPLACE_ADD_UNICODE 8 +#define BINARY_OP_MULTIPLY_FLOAT 10 +#define BINARY_OP_MULTIPLY_INT 13 +#define BINARY_OP_SUBTRACT_FLOAT 14 +#define BINARY_OP_SUBTRACT_INT 16 +#define BINARY_SUBSCR_DICT 17 +#define BINARY_SUBSCR_GETITEM 18 +#define BINARY_SUBSCR_LIST_INT 19 +#define BINARY_SUBSCR_TUPLE_INT 20 +#define CALL_PY_EXACT_ARGS 21 +#define CALL_PY_WITH_DEFAULTS 22 +#define CALL_BOUND_METHOD_EXACT_ARGS 23 +#define CALL_BUILTIN_CLASS 24 +#define CALL_BUILTIN_FAST_WITH_KEYWORDS 28 +#define CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 29 +#define CALL_NO_KW_BUILTIN_FAST 34 +#define CALL_NO_KW_BUILTIN_O 38 +#define CALL_NO_KW_ISINSTANCE 39 +#define CALL_NO_KW_LEN 40 +#define CALL_NO_KW_LIST_APPEND 41 +#define CALL_NO_KW_METHOD_DESCRIPTOR_FAST 42 +#define CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 43 +#define CALL_NO_KW_METHOD_DESCRIPTOR_O 44 +#define CALL_NO_KW_STR_1 45 +#define CALL_NO_KW_TUPLE_1 46 +#define CALL_NO_KW_TYPE_1 47 +#define COMPARE_AND_BRANCH_FLOAT 48 +#define COMPARE_AND_BRANCH_INT 56 +#define COMPARE_AND_BRANCH_STR 57 +#define FOR_ITER_LIST 58 +#define FOR_ITER_TUPLE 59 +#define FOR_ITER_RANGE 62 +#define FOR_ITER_GEN 63 +#define LOAD_ATTR_CLASS 64 +#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 65 +#define LOAD_ATTR_INSTANCE_VALUE 66 +#define LOAD_ATTR_MODULE 67 +#define LOAD_ATTR_PROPERTY 70 +#define LOAD_ATTR_SLOT 72 +#define LOAD_ATTR_WITH_HINT 73 +#define LOAD_ATTR_METHOD_LAZY_DICT 76 +#define LOAD_ATTR_METHOD_NO_DICT 77 +#define LOAD_ATTR_METHOD_WITH_VALUES 78 +#define LOAD_CONST__LOAD_FAST 79 +#define LOAD_FAST__LOAD_CONST 80 +#define LOAD_FAST__LOAD_FAST 81 +#define LOAD_GLOBAL_BUILTIN 82 +#define LOAD_GLOBAL_MODULE 84 +#define STORE_ATTR_INSTANCE_VALUE 86 +#define STORE_ATTR_SLOT 87 +#define STORE_ATTR_WITH_HINT 113 +#define STORE_FAST__LOAD_FAST 121 +#define STORE_FAST__STORE_FAST 143 +#define STORE_SUBSCR_DICT 153 +#define STORE_SUBSCR_LIST_INT 154 +#define UNPACK_SEQUENCE_LIST 158 +#define UNPACK_SEQUENCE_TUPLE 159 +#define UNPACK_SEQUENCE_TWO_TUPLE 160 +#define DO_TRACING 255 -#define HAS_CONST(op) (false\ - || ((op) == 100) \ +#define HAS_ARG(op) ((((op) >= HAVE_ARGUMENT) && (!IS_PSEUDO_OPCODE(op)))\ + || ((op) == JUMP) \ + || ((op) == JUMP_NO_INTERRUPT) \ + || ((op) == LOAD_METHOD) \ ) -#define NB_ADD 0 -#define NB_AND 1 -#define NB_FLOOR_DIVIDE 2 -#define NB_LSHIFT 3 -#define NB_MATRIX_MULTIPLY 4 -#define NB_MULTIPLY 5 -#define NB_REMAINDER 6 -#define NB_OR 7 -#define NB_POWER 8 -#define NB_RSHIFT 9 -#define NB_SUBTRACT 10 -#define NB_TRUE_DIVIDE 11 -#define NB_XOR 12 -#define NB_INPLACE_ADD 13 -#define NB_INPLACE_AND 14 -#define NB_INPLACE_FLOOR_DIVIDE 15 -#define NB_INPLACE_LSHIFT 16 -#define NB_INPLACE_MATRIX_MULTIPLY 17 -#define NB_INPLACE_MULTIPLY 18 -#define NB_INPLACE_REMAINDER 19 -#define NB_INPLACE_OR 20 -#define NB_INPLACE_POWER 21 -#define NB_INPLACE_RSHIFT 22 -#define NB_INPLACE_SUBTRACT 23 -#define NB_INPLACE_TRUE_DIVIDE 24 -#define NB_INPLACE_XOR 25 +#define HAS_CONST(op) (false\ + || ((op) == LOAD_CONST) \ + || ((op) == KW_NAMES) \ + ) -#define HAS_ARG(op) ((op) >= HAVE_ARGUMENT) +#define NB_ADD 0 +#define NB_AND 1 +#define NB_FLOOR_DIVIDE 2 +#define NB_LSHIFT 3 +#define NB_MATRIX_MULTIPLY 4 +#define NB_MULTIPLY 5 +#define NB_REMAINDER 6 +#define NB_OR 7 +#define NB_POWER 8 +#define NB_RSHIFT 9 +#define NB_SUBTRACT 10 +#define NB_TRUE_DIVIDE 11 +#define NB_XOR 12 +#define NB_INPLACE_ADD 13 +#define NB_INPLACE_AND 14 +#define NB_INPLACE_FLOOR_DIVIDE 15 +#define NB_INPLACE_LSHIFT 16 +#define NB_INPLACE_MATRIX_MULTIPLY 17 +#define NB_INPLACE_MULTIPLY 18 +#define NB_INPLACE_REMAINDER 19 +#define NB_INPLACE_OR 20 +#define NB_INPLACE_POWER 21 +#define NB_INPLACE_RSHIFT 22 +#define NB_INPLACE_SUBTRACT 23 +#define NB_INPLACE_TRUE_DIVIDE 24 +#define NB_INPLACE_XOR 25 -/* Reserve some bytecodes for internal use in the compiler. - * The value of 240 is arbitrary. */ -#define IS_ARTIFICIAL(op) ((op) > 240) +/* Defined in Lib/opcode.py */ +#define ENABLE_SPECIALIZATION 1 + +#define IS_PSEUDO_OPCODE(op) (((op) >= MIN_PSEUDO_OPCODE) && ((op) <= MAX_PSEUDO_OPCODE)) #ifdef __cplusplus } diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 45543931ffb..3a3e40c2e09 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -17,13 +17,13 @@ /* Version parsed out into numeric values */ /*--start constants--*/ #define PY_MAJOR_VERSION 3 -#define PY_MINOR_VERSION 11 +#define PY_MINOR_VERSION 12 #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA -#define PY_RELEASE_SERIAL 2 +#define PY_RELEASE_SERIAL 4 /* Version as a string */ -#define PY_VERSION "3.11.0a2+" +#define PY_VERSION "3.12.0a4+" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Include/py_curses.h b/Include/py_curses.h index b70252d9d76..e46b08e9cc4 100644 --- a/Include/py_curses.h +++ b/Include/py_curses.h @@ -64,7 +64,7 @@ typedef struct { char *encoding; } PyCursesWindowObject; -#define PyCursesWindow_Check(v) Py_IS_TYPE(v, &PyCursesWindow_Type) +#define PyCursesWindow_Check(v) Py_IS_TYPE((v), &PyCursesWindow_Type) #define PyCurses_CAPSULE_NAME "_curses._C_API" @@ -77,7 +77,7 @@ typedef struct { static void **PyCurses_API; -#define PyCursesWindow_Type (*(PyTypeObject *) PyCurses_API[0]) +#define PyCursesWindow_Type (*_PyType_CAST(PyCurses_API[0])) #define PyCursesSetupTermCalled {if (! ((int (*)(void))PyCurses_API[1]) () ) return NULL;} #define PyCursesInitialised {if (! ((int (*)(void))PyCurses_API[2]) () ) return NULL;} #define PyCursesInitialisedColor {if (! ((int (*)(void))PyCurses_API[3]) () ) return NULL;} diff --git a/Include/pybuffer.h b/Include/pybuffer.h new file mode 100644 index 00000000000..bbac60972f5 --- /dev/null +++ b/Include/pybuffer.h @@ -0,0 +1,145 @@ +/* Public Py_buffer API */ + +#ifndef Py_BUFFER_H +#define Py_BUFFER_H +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030b0000 + +/* === New Buffer API ============================================ + * Limited API and stable ABI since Python 3.11 + * + * Py_buffer struct layout and size is now part of the stable abi3. The + * struct layout and size must not be changed in any way, as it would + * break the ABI. + * + */ + +typedef struct { + void *buf; + PyObject *obj; /* owned reference */ + Py_ssize_t len; + Py_ssize_t itemsize; /* This is Py_ssize_t so it can be + pointed to by strides in simple case.*/ + int readonly; + int ndim; + char *format; + Py_ssize_t *shape; + Py_ssize_t *strides; + Py_ssize_t *suboffsets; + void *internal; +} Py_buffer; + +typedef int (*getbufferproc)(PyObject *, Py_buffer *, int); +typedef void (*releasebufferproc)(PyObject *, Py_buffer *); + +/* Return 1 if the getbuffer function is available, otherwise return 0. */ +PyAPI_FUNC(int) PyObject_CheckBuffer(PyObject *obj); + +/* This is a C-API version of the getbuffer function call. It checks + to make sure object has the required function pointer and issues the + call. + + Returns -1 and raises an error on failure and returns 0 on success. */ +PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, Py_buffer *view, + int flags); + +/* Get the memory area pointed to by the indices for the buffer given. + Note that view->ndim is the assumed size of indices. */ +PyAPI_FUNC(void *) PyBuffer_GetPointer(const Py_buffer *view, const Py_ssize_t *indices); + +/* Return the implied itemsize of the data-format area from a + struct-style description. */ +PyAPI_FUNC(Py_ssize_t) PyBuffer_SizeFromFormat(const char *format); + +/* Implementation in memoryobject.c */ +PyAPI_FUNC(int) PyBuffer_ToContiguous(void *buf, const Py_buffer *view, + Py_ssize_t len, char order); + +PyAPI_FUNC(int) PyBuffer_FromContiguous(const Py_buffer *view, const void *buf, + Py_ssize_t len, char order); + +/* Copy len bytes of data from the contiguous chunk of memory + pointed to by buf into the buffer exported by obj. Return + 0 on success and return -1 and raise a PyBuffer_Error on + error (i.e. the object does not have a buffer interface or + it is not working). + + If fort is 'F', then if the object is multi-dimensional, + then the data will be copied into the array in + Fortran-style (first dimension varies the fastest). If + fort is 'C', then the data will be copied into the array + in C-style (last dimension varies the fastest). If fort + is 'A', then it does not matter and the copy will be made + in whatever way is more efficient. */ +PyAPI_FUNC(int) PyObject_CopyData(PyObject *dest, PyObject *src); + +/* Copy the data from the src buffer to the buffer of destination. */ +PyAPI_FUNC(int) PyBuffer_IsContiguous(const Py_buffer *view, char fort); + +/*Fill the strides array with byte-strides of a contiguous + (Fortran-style if fort is 'F' or C-style otherwise) + array of the given shape with the given number of bytes + per element. */ +PyAPI_FUNC(void) PyBuffer_FillContiguousStrides(int ndims, + Py_ssize_t *shape, + Py_ssize_t *strides, + int itemsize, + char fort); + +/* Fills in a buffer-info structure correctly for an exporter + that can only share a contiguous chunk of memory of + "unsigned bytes" of the given length. + + Returns 0 on success and -1 (with raising an error) on error. */ +PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf, + Py_ssize_t len, int readonly, + int flags); + +/* Releases a Py_buffer obtained from getbuffer ParseTuple's "s*". */ +PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view); + +/* Maximum number of dimensions */ +#define PyBUF_MAX_NDIM 64 + +/* Flags for getting buffers */ +#define PyBUF_SIMPLE 0 +#define PyBUF_WRITABLE 0x0001 + +#ifndef Py_LIMITED_API +/* we used to include an E, backwards compatible alias */ +#define PyBUF_WRITEABLE PyBUF_WRITABLE +#endif + +#define PyBUF_FORMAT 0x0004 +#define PyBUF_ND 0x0008 +#define PyBUF_STRIDES (0x0010 | PyBUF_ND) +#define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES) +#define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES) +#define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES) +#define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES) + +#define PyBUF_CONTIG (PyBUF_ND | PyBUF_WRITABLE) +#define PyBUF_CONTIG_RO (PyBUF_ND) + +#define PyBUF_STRIDED (PyBUF_STRIDES | PyBUF_WRITABLE) +#define PyBUF_STRIDED_RO (PyBUF_STRIDES) + +#define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT) +#define PyBUF_RECORDS_RO (PyBUF_STRIDES | PyBUF_FORMAT) + +#define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT) +#define PyBUF_FULL_RO (PyBUF_INDIRECT | PyBUF_FORMAT) + + +#define PyBUF_READ 0x100 +#define PyBUF_WRITE 0x200 + +#endif /* !Py_LIMITED_API || Py_LIMITED_API >= 3.11 */ + +#ifdef __cplusplus +} +#endif +#endif /* Py_BUFFER_H */ diff --git a/Include/pycapsule.h b/Include/pycapsule.h index fb5d503fea7..929a9a68525 100644 --- a/Include/pycapsule.h +++ b/Include/pycapsule.h @@ -22,7 +22,7 @@ PyAPI_DATA(PyTypeObject) PyCapsule_Type; typedef void (*PyCapsule_Destructor)(PyObject *); -#define PyCapsule_CheckExact(op) Py_IS_TYPE(op, &PyCapsule_Type) +#define PyCapsule_CheckExact(op) Py_IS_TYPE((op), &PyCapsule_Type) PyAPI_FUNC(PyObject *) PyCapsule_New( diff --git a/Include/pydtrace.h b/Include/pydtrace.h index 75f8e7f7097..e197d366945 100644 --- a/Include/pydtrace.h +++ b/Include/pydtrace.h @@ -12,7 +12,7 @@ extern "C" { /* pydtrace_probes.h, on systems with DTrace, is auto-generated to include `PyDTrace_{PROBE}` and `PyDTrace_{PROBE}_ENABLED()` macros for every probe - defined in pydtrace_provider.d. + defined in pydtrace.d. Calling these functions must be guarded by a `PyDTrace_{PROBE}_ENABLED()` check to minimize performance impact when probing is off. For example: diff --git a/Include/pyerrors.h b/Include/pyerrors.h index 77d791427d4..d5ac6af5b32 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -18,6 +18,10 @@ PyAPI_FUNC(PyObject *) PyErr_Occurred(void); PyAPI_FUNC(void) PyErr_Clear(void); PyAPI_FUNC(void) PyErr_Fetch(PyObject **, PyObject **, PyObject **); PyAPI_FUNC(void) PyErr_Restore(PyObject *, PyObject *, PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030b0000 +PyAPI_FUNC(PyObject*) PyErr_GetHandledException(void); +PyAPI_FUNC(void) PyErr_SetHandledException(PyObject *); +#endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(void) PyErr_GetExcInfo(PyObject **, PyObject **, PyObject **); PyAPI_FUNC(void) PyErr_SetExcInfo(PyObject *, PyObject *, PyObject *); @@ -58,10 +62,10 @@ PyAPI_FUNC(void) PyException_SetContext(PyObject *, PyObject *); PyAPI_FUNC(const char *) PyExceptionClass_Name(PyObject *); -#define PyExceptionInstance_Class(x) ((PyObject*)Py_TYPE(x)) +#define PyExceptionInstance_Class(x) _PyObject_CAST(Py_TYPE(x)) #define _PyBaseExceptionGroup_Check(x) \ - PyObject_TypeCheck(x, (PyTypeObject *)PyExc_BaseExceptionGroup) + PyObject_TypeCheck((x), (PyTypeObject *)PyExc_BaseExceptionGroup) /* Predefined exceptions */ diff --git a/Include/pyframe.h b/Include/pyframe.h index 3816224201c..13d52312ea9 100644 --- a/Include/pyframe.h +++ b/Include/pyframe.h @@ -9,13 +9,17 @@ extern "C" { #endif -typedef struct _frame PyFrameObject; - /* Return the line of code the frame is currently executing. */ PyAPI_FUNC(int) PyFrame_GetLineNumber(PyFrameObject *); PyAPI_FUNC(PyCodeObject *) PyFrame_GetCode(PyFrameObject *frame); +#ifndef Py_LIMITED_API +# define Py_CPYTHON_PYFRAME_H +# include "cpython/pyframe.h" +# undef Py_CPYTHON_PYFRAME_H +#endif + #ifdef __cplusplus } #endif diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h index 4aecda235ab..e4c3b09c963 100644 --- a/Include/pylifecycle.h +++ b/Include/pylifecycle.h @@ -62,6 +62,10 @@ typedef void (*PyOS_sighandler_t)(int); PyAPI_FUNC(PyOS_sighandler_t) PyOS_getsig(int); PyAPI_FUNC(PyOS_sighandler_t) PyOS_setsig(int, PyOS_sighandler_t); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030B0000 +PyAPI_DATA(const unsigned long) Py_Version; +#endif + #ifndef Py_LIMITED_API # define Py_CPYTHON_PYLIFECYCLE_H # include "cpython/pylifecycle.h" diff --git a/Include/pymacconfig.h b/Include/pymacconfig.h index 9dde11bd58e..00459a03b98 100644 --- a/Include/pymacconfig.h +++ b/Include/pymacconfig.h @@ -84,18 +84,6 @@ # define HAVE_GCC_ASM_FOR_X87 #endif - /* - * The definition in pyconfig.h is only valid on the OS release - * where configure ran on and not necessarily for all systems where - * the executable can be used on. - * - * Specifically: OSX 10.4 has limited supported for '%zd', while - * 10.5 has full support for '%zd'. A binary built on 10.5 won't - * work properly on 10.4 unless we suppress the definition - * of PY_FORMAT_SIZE_T - */ -#undef PY_FORMAT_SIZE_T - #endif /* defined(_APPLE__) */ diff --git a/Include/pymacro.h b/Include/pymacro.h index 202b936d964..e37cda44c5e 100644 --- a/Include/pymacro.h +++ b/Include/pymacro.h @@ -1,6 +1,25 @@ #ifndef Py_PYMACRO_H #define Py_PYMACRO_H +// gh-91782: On FreeBSD 12, if the _POSIX_C_SOURCE and _XOPEN_SOURCE macros are +// defined, disables C11 support and does not define +// the static_assert() macro. Define the static_assert() macro in Python until +// suports C11: +// https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=255290 +#if defined(__FreeBSD__) && !defined(static_assert) +# define static_assert _Static_assert +#endif + +// static_assert is defined in glibc from version 2.16. Before it requires +// compiler support (gcc >= 4.6) and is called _Static_assert. +// In C++ 11 static_assert is a keyword, redefining is undefined behaviour. +#if (defined(__GLIBC__) \ + && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 16)) \ + && !(defined(__cplusplus) && __cplusplus >= 201103L) \ + && !defined(static_assert)) +# define static_assert _Static_assert +#endif + /* Minimum value between x and y */ #define Py_MIN(x, y) (((x) > (y)) ? (y) : (x)) @@ -129,4 +148,13 @@ Py_FatalError("Unreachable C code path reached") #endif +// Prevent using an expression as a l-value. +// For example, "int x; _Py_RVALUE(x) = 1;" fails with a compiler error. +#define _Py_RVALUE(EXPR) ((void)0, (EXPR)) + +// Return non-zero if the type is signed, return zero if it's unsigned. +// Use "<= 0" rather than "< 0" to prevent the compiler warning: +// "comparison of unsigned expression in '< 0' is always false". +#define _Py_IS_TYPE_SIGNED(type) ((type)(-1) <= 0) + #endif /* Py_PYMACRO_H */ diff --git a/Include/pymath.h b/Include/pymath.h index 57310fc097e..772b67e4977 100644 --- a/Include/pymath.h +++ b/Include/pymath.h @@ -50,30 +50,16 @@ # define Py_HUGE_VAL HUGE_VAL #endif -/* Py_NAN - * A value that evaluates to a NaN. On IEEE 754 platforms INF*0 or - * INF/INF works. Define Py_NO_NAN in pyconfig.h if your platform - * doesn't support NaNs. - */ -#if !defined(Py_NAN) && !defined(Py_NO_NAN) -# if !defined(__INTEL_COMPILER) -# define Py_NAN (Py_HUGE_VAL * 0.) -# else /* __INTEL_COMPILER */ -# if defined(ICC_NAN_STRICT) - #pragma float_control(push) - #pragma float_control(precise, on) - #pragma float_control(except, on) - Py_NO_INLINE static double __icc_nan() - { - return sqrt(-1.0); - } - #pragma float_control (pop) -# define Py_NAN __icc_nan() -# else /* ICC_NAN_RELAXED as default for Intel Compiler */ - static const union { unsigned char buf[8]; double __icc_nan; } __nan_store = {0,0,0,0,0,0,0xf8,0x7f}; -# define Py_NAN (__nan_store.__icc_nan) -# endif /* ICC_NAN_STRICT */ -# endif /* __INTEL_COMPILER */ +// Py_NAN: Value that evaluates to a quiet Not-a-Number (NaN). +#if !defined(Py_NAN) +# if _Py__has_builtin(__builtin_nan) + // Built-in implementation of the ISO C99 function nan(): quiet NaN. +# define Py_NAN (__builtin_nan("")) +#else + // Use C99 NAN constant: quiet Not-A-Number. + // NAN is a float, Py_NAN is a double: cast to double. +# define Py_NAN ((double)NAN) +# endif #endif #endif /* Py_PYMATH_H */ diff --git a/Include/pymem.h b/Include/pymem.h index c15ad10dfcf..e882645757b 100644 --- a/Include/pymem.h +++ b/Include/pymem.h @@ -82,13 +82,13 @@ PyAPI_FUNC(void) PyMem_Free(void *ptr); // Deprecated aliases only kept for backward compatibility. // PyMem_Del and PyMem_DEL are defined with no parameter to be able to use // them as function pointers (ex: dealloc = PyMem_Del). -#define PyMem_MALLOC(n) PyMem_Malloc(n) -#define PyMem_NEW(type, n) PyMem_New(type, n) -#define PyMem_REALLOC(p, n) PyMem_Realloc(p, n) -#define PyMem_RESIZE(p, type, n) PyMem_Resize(p, type, n) -#define PyMem_FREE(p) PyMem_Free(p) -#define PyMem_Del PyMem_Free -#define PyMem_DEL PyMem_Free +#define PyMem_MALLOC(n) PyMem_Malloc((n)) +#define PyMem_NEW(type, n) PyMem_New(type, (n)) +#define PyMem_REALLOC(p, n) PyMem_Realloc((p), (n)) +#define PyMem_RESIZE(p, type, n) PyMem_Resize((p), type, (n)) +#define PyMem_FREE(p) PyMem_Free((p)) +#define PyMem_Del(p) PyMem_Free((p)) +#define PyMem_DEL(p) PyMem_Free((p)) #ifndef Py_LIMITED_API diff --git a/Include/pyport.h b/Include/pyport.h index 953f75c970d..b1b2a747796 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -14,6 +14,25 @@ #endif +// Macro to use C++ static_cast<> in the Python C API. +#ifdef __cplusplus +# define _Py_STATIC_CAST(type, expr) static_cast(expr) +#else +# define _Py_STATIC_CAST(type, expr) ((type)(expr)) +#endif +// Macro to use the more powerful/dangerous C-style cast even in C++. +#define _Py_CAST(type, expr) ((type)(expr)) + +// Static inline functions should use _Py_NULL rather than using directly NULL +// to prevent C++ compiler warnings. On C++11 and newer, _Py_NULL is defined as +// nullptr. +#if defined(__cplusplus) && __cplusplus >= 201103 +# define _Py_NULL nullptr +#else +# define _Py_NULL NULL +#endif + + /* Defines to build Python and its standard library: * * - Py_BUILD_CORE: Build Python core. Give access to Python internals, but @@ -85,16 +104,12 @@ Used in: Py_SAFE_DOWNCAST #define PY_INT32_T int32_t #define PY_INT64_T int64_t -/* If PYLONG_BITS_IN_DIGIT is not defined then we'll use 30-bit digits if all - the necessary integer types are available, and we're on a 64-bit platform - (as determined by SIZEOF_VOID_P); otherwise we use 15-bit digits. */ - +/* PYLONG_BITS_IN_DIGIT describes the number of bits per "digit" (limb) in the + * PyLongObject implementation (longintrepr.h). It's currently either 30 or 15, + * defaulting to 30. The 15-bit digit option may be removed in the future. + */ #ifndef PYLONG_BITS_IN_DIGIT -#if SIZEOF_VOID_P >= 8 #define PYLONG_BITS_IN_DIGIT 30 -#else -#define PYLONG_BITS_IN_DIGIT 15 -#endif #endif /* uintptr_t is the C9X name for an unsigned integral type such that a @@ -108,17 +123,23 @@ typedef intptr_t Py_intptr_t; /* Py_ssize_t is 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 Py_ssize_t. */ #ifdef HAVE_PY_SSIZE_T #elif HAVE_SSIZE_T typedef ssize_t Py_ssize_t; +# define PY_SSIZE_T_MAX SSIZE_MAX #elif SIZEOF_VOID_P == SIZEOF_SIZE_T typedef Py_intptr_t Py_ssize_t; +# define PY_SSIZE_T_MAX INTPTR_MAX #else # error "Python needs a typedef for Py_ssize_t in pyport.h." #endif +/* Smallest negative value of type Py_ssize_t. */ +#define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1) + /* Py_hash_t is the same size as a pointer. */ #define SIZEOF_PY_HASH_T SIZEOF_SIZE_T typedef Py_ssize_t Py_hash_t; @@ -132,37 +153,10 @@ typedef Py_ssize_t Py_ssize_clean_t; /* Largest possible value of size_t. */ #define PY_SIZE_MAX SIZE_MAX -/* Largest positive value of type Py_ssize_t. */ -#define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t)-1)>>1)) -/* Smallest negative value of type Py_ssize_t. */ -#define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1) - -/* Macro kept for backward compatibility: use "z" in new code. +/* Macro kept for backward compatibility: use directly "z" in new code. * - * PY_FORMAT_SIZE_T is a platform-specific modifier for use in a printf - * format to convert an argument with the width of a size_t or Py_ssize_t. - * C99 introduced "z" for this purpose, but old MSVCs had not supported it. - * Since MSVC supports "z" since (at least) 2015, we can just use "z" - * for new code. - * - * These "high level" Python format functions interpret "z" correctly on - * all platforms (Python interprets the format string itself, and does whatever - * the platform C requires to convert a size_t/Py_ssize_t argument): - * - * PyBytes_FromFormat - * PyErr_Format - * PyBytes_FromFormatV - * PyUnicode_FromFormatV - * - * Lower-level uses require that you interpolate the correct format modifier - * yourself (e.g., calling printf, fprintf, sprintf, PyOS_snprintf); for - * example, - * - * Py_ssize_t index; - * fprintf(stderr, "index %" PY_FORMAT_SIZE_T "d sucks\n", index); - * - * That will expand to %zd or to something else correct for a Py_ssize_t on - * the platform. + * PY_FORMAT_SIZE_T is a modifier for use in a printf format to convert an + * argument with the width of a size_t or Py_ssize_t: "z" (C99). */ #ifndef PY_FORMAT_SIZE_T # define PY_FORMAT_SIZE_T "z" @@ -174,23 +168,12 @@ typedef Py_ssize_t Py_ssize_clean_t; * Py_LOCAL_INLINE does the same thing, and also explicitly requests inlining, * for platforms that support that. * - * If PY_LOCAL_AGGRESSIVE is defined before python.h is included, more - * "aggressive" inlining/optimization is enabled for the entire module. This - * may lead to code bloat, and may slow things down for those reasons. It may - * also lead to errors, if the code relies on pointer aliasing. Use with - * care. - * * NOTE: You can only use this for functions that are entirely local to a * module; functions that are exported via method tables, callbacks, etc, * should keep using static. */ #if defined(_MSC_VER) -# if defined(PY_LOCAL_AGGRESSIVE) - /* enable more aggressive optimization for MSVC */ - /* active in both release and debug builds - see bpo-43271 */ -# pragma optimize("gt", on) -#endif /* ignore warnings if the compiler decides not to inline a function */ # pragma warning(disable: 4710) /* fastest possible local call under MSVC */ @@ -310,65 +293,11 @@ extern "C" { * VALUE may be evaluated more than once. */ #ifdef Py_DEBUG -#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) \ - (assert((WIDE)(NARROW)(VALUE) == (VALUE)), (NARROW)(VALUE)) +# define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) \ + (assert(_Py_STATIC_CAST(WIDE, _Py_STATIC_CAST(NARROW, (VALUE))) == (VALUE)), \ + _Py_STATIC_CAST(NARROW, (VALUE))) #else -#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) (NARROW)(VALUE) -#endif - -/* The functions _Py_dg_strtod and _Py_dg_dtoa in Python/dtoa.c (which are - * required to support the short float repr introduced in Python 3.1) require - * that the floating-point unit that's being used for arithmetic operations - * on C doubles is set to use 53-bit precision. It also requires that the - * FPU rounding mode is round-half-to-even, but that's less often an issue. - * - * If your FPU isn't already set to 53-bit precision/round-half-to-even, and - * you want to make use of _Py_dg_strtod and _Py_dg_dtoa, then you should - * - * #define HAVE_PY_SET_53BIT_PRECISION 1 - * - * The macros are designed to be used within a single C function: see - * Python/pystrtod.c for an example of their use. - */ - -// HAVE_PY_SET_53BIT_PRECISION macro must be kept in sync with pycore_pymath.h -#ifdef HAVE_GCC_ASM_FOR_X87 - // Get and set x87 control word for gcc/x86 -# define HAVE_PY_SET_53BIT_PRECISION 1 -#endif -#if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM) - // Get and set x87 control word for VisualStudio/x86. - // x87 not supported in 64-bit or ARM. -# define HAVE_PY_SET_53BIT_PRECISION 1 -#endif -#ifdef HAVE_GCC_ASM_FOR_MC68881 -# define HAVE_PY_SET_53BIT_PRECISION 1 -#endif - - -/* If we can't guarantee 53-bit precision, don't use the code - in Python/dtoa.c, but fall back to standard code. This - means that repr of a float will be long (17 sig digits). - - Realistically, there are two things that could go wrong: - - (1) doubles aren't IEEE 754 doubles, or - (2) we're on x86 with the rounding precision set to 64-bits - (extended precision), and we don't know how to change - the rounding precision. - */ - -#if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \ - !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \ - !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) -# define PY_NO_SHORT_FLOAT_REPR -#endif - -/* double rounding is symptomatic of use of extended precision on x86. If - we're seeing double rounding, and we don't have any mechanism available for - changing the FPU rounding precision, then don't use Python/dtoa.c. */ -#if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION) -# define PY_NO_SHORT_FLOAT_REPR +# define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) _Py_STATIC_CAST(NARROW, (VALUE)) #endif @@ -769,6 +698,15 @@ extern char * _getpty(int *, int, mode_t, int); # define _Py__has_builtin(x) 0 #endif +// _Py_TYPEOF(expr) gets the type of an expression. +// +// Example: _Py_TYPEOF(x) x_copy = (x); +// +// The macro is only defined if GCC or clang compiler is used. +#if defined(__GNUC__) || defined(__clang__) +# define _Py_TYPEOF(expr) __typeof__(expr) +#endif + /* A convenient way for code to know if sanitizers are enabled. */ #if defined(__has_feature) diff --git a/Include/pystate.h b/Include/pystate.h index b6ee0ede81d..e6b4de979c8 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -11,16 +11,6 @@ extern "C" { removed (with effort). */ #define MAX_CO_EXTRA_USERS 255 -/* Forward declarations for PyFrameObject, PyThreadState - and PyInterpreterState */ -struct _ts; -struct _is; - -/* struct _ts is defined in cpython/pystate.h */ -typedef struct _ts PyThreadState; -/* struct _is is defined in internal/pycore_interp.h */ -typedef struct _is PyInterpreterState; - PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void); PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *); PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *); @@ -50,10 +40,10 @@ PyAPI_FUNC(int64_t) PyInterpreterState_GetID(PyInterpreterState *); /* State unique per thread */ /* New in 3.3 */ -PyAPI_FUNC(int) PyState_AddModule(PyObject*, struct PyModuleDef*); -PyAPI_FUNC(int) PyState_RemoveModule(struct PyModuleDef*); +PyAPI_FUNC(int) PyState_AddModule(PyObject*, PyModuleDef*); +PyAPI_FUNC(int) PyState_RemoveModule(PyModuleDef*); #endif -PyAPI_FUNC(PyObject*) PyState_FindModule(struct PyModuleDef*); +PyAPI_FUNC(PyObject*) PyState_FindModule(PyModuleDef*); PyAPI_FUNC(PyThreadState *) PyThreadState_New(PyInterpreterState *); PyAPI_FUNC(void) PyThreadState_Clear(PyThreadState *); diff --git a/Include/pystats.h b/Include/pystats.h new file mode 100644 index 00000000000..25ed4bddc72 --- /dev/null +++ b/Include/pystats.h @@ -0,0 +1,112 @@ + + +#ifndef Py_PYSTATS_H +#define Py_PYSTATS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef Py_STATS + +#define SPECIALIZATION_FAILURE_KINDS 36 + +/* Stats for determining who is calling PyEval_EvalFrame */ +#define EVAL_CALL_TOTAL 0 +#define EVAL_CALL_VECTOR 1 +#define EVAL_CALL_GENERATOR 2 +#define EVAL_CALL_LEGACY 3 +#define EVAL_CALL_FUNCTION_VECTORCALL 4 +#define EVAL_CALL_BUILD_CLASS 5 +#define EVAL_CALL_SLOT 6 +#define EVAL_CALL_FUNCTION_EX 7 +#define EVAL_CALL_API 8 +#define EVAL_CALL_METHOD 9 + +#define EVAL_CALL_KINDS 10 + +typedef struct _specialization_stats { + uint64_t success; + uint64_t failure; + uint64_t hit; + uint64_t deferred; + uint64_t miss; + uint64_t deopt; + uint64_t failure_kinds[SPECIALIZATION_FAILURE_KINDS]; +} SpecializationStats; + +typedef struct _opcode_stats { + SpecializationStats specialization; + uint64_t execution_count; + uint64_t pair_count[256]; +} OpcodeStats; + +typedef struct _call_stats { + uint64_t inlined_py_calls; + uint64_t pyeval_calls; + uint64_t frames_pushed; + uint64_t frame_objects_created; + uint64_t eval_calls[EVAL_CALL_KINDS]; +} CallStats; + +typedef struct _object_stats { + uint64_t increfs; + uint64_t decrefs; + uint64_t interpreter_increfs; + uint64_t interpreter_decrefs; + uint64_t allocations; + uint64_t allocations512; + uint64_t allocations4k; + uint64_t allocations_big; + uint64_t frees; + uint64_t to_freelist; + uint64_t from_freelist; + uint64_t new_values; + uint64_t dict_materialized_on_request; + uint64_t dict_materialized_new_key; + uint64_t dict_materialized_too_big; + uint64_t dict_materialized_str_subclass; + uint64_t type_cache_hits; + uint64_t type_cache_misses; + uint64_t type_cache_dunder_hits; + uint64_t type_cache_dunder_misses; + uint64_t type_cache_collisions; +} ObjectStats; + +# + +typedef struct _stats { + OpcodeStats opcode_stats[256]; + CallStats call_stats; + ObjectStats object_stats; +} PyStats; + + +PyAPI_DATA(PyStats) _py_stats_struct; +PyAPI_DATA(PyStats *) _py_stats; + +extern void _Py_StatsClear(void); +extern void _Py_PrintSpecializationStats(int to_file); + +#ifdef _PY_INTERPRETER + +#define _Py_INCREF_STAT_INC() do { if (_py_stats) _py_stats->object_stats.interpreter_increfs++; } while (0) +#define _Py_DECREF_STAT_INC() do { if (_py_stats) _py_stats->object_stats.interpreter_decrefs++; } while (0) + +#else + +#define _Py_INCREF_STAT_INC() do { if (_py_stats) _py_stats->object_stats.increfs++; } while (0) +#define _Py_DECREF_STAT_INC() do { if (_py_stats) _py_stats->object_stats.decrefs++; } while (0) + +#endif + +#else + +#define _Py_INCREF_STAT_INC() ((void)0) +#define _Py_DECREF_STAT_INC() ((void)0) + +#endif // !Py_STATS + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYSTATs_H */ diff --git a/Include/pystrtod.h b/Include/pystrtod.h index c1e84de6fe5..fa056d17b63 100644 --- a/Include/pystrtod.h +++ b/Include/pystrtod.h @@ -32,6 +32,7 @@ PyAPI_FUNC(double) _Py_parse_inf_or_nan(const char *p, char **endptr); #define Py_DTSF_ADD_DOT_0 0x02 /* if the result is an integer add ".0" */ #define Py_DTSF_ALT 0x04 /* "alternate" formatting. it's format_code specific */ +#define Py_DTSF_NO_NEG_0 0x08 /* negative zero result is coerced to 0 */ /* PyOS_double_to_string's "type", if non-NULL, will be set to one of: */ #define Py_DTST_FINITE 0 diff --git a/Include/pythonrun.h b/Include/pythonrun.h index 02715775581..1b208b734ab 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -24,6 +24,7 @@ PyAPI_DATA(int) (*PyOS_InputHook)(void); #if defined(WIN32) && !defined(MS_WIN64) && !defined(_M_ARM) && defined(_MSC_VER) && _MSC_VER >= 1300 /* Enable stack checking under Microsoft C */ +// When changing the platforms, ensure PyOS_CheckStack() docs are still correct #define USE_STACKCHECK #endif diff --git a/Include/pythread.h b/Include/pythread.h index 1a6092c4ad0..63714437c49 100644 --- a/Include/pythread.h +++ b/Include/pythread.h @@ -1,4 +1,3 @@ - #ifndef Py_PYTHREAD_H #define Py_PYTHREAD_H @@ -16,16 +15,14 @@ typedef enum PyLockStatus { PY_LOCK_INTR } PyLockStatus; -#ifndef Py_LIMITED_API -#define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1) -#endif - PyAPI_FUNC(void) PyThread_init_thread(void); PyAPI_FUNC(unsigned long) PyThread_start_new_thread(void (*)(void *), void *); PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void); -#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(_WIN32) || defined(_AIX) +#if (defined(__APPLE__) || defined(__linux__) || defined(_WIN32) \ + || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ + || defined(__DragonFly__) || defined(_AIX)) #define PY_HAVE_THREAD_NATIVE_ID PyAPI_FUNC(unsigned long) PyThread_get_thread_native_id(void); #endif @@ -36,15 +33,6 @@ PyAPI_FUNC(int) PyThread_acquire_lock(PyThread_type_lock, int); #define WAIT_LOCK 1 #define NOWAIT_LOCK 0 -#ifndef Py_LIMITED_API -#ifdef HAVE_FORK -/* Private function to reinitialize a lock at fork in the child process. - Reset the lock to the unlocked state. - Return 0 on success, return -1 on error. */ -PyAPI_FUNC(int) _PyThread_at_fork_reinit(PyThread_type_lock *lock); -#endif /* HAVE_FORK */ -#endif /* !Py_LIMITED_API */ - /* PY_TIMEOUT_T is the integral type used to specify timeouts when waiting on a lock (see PyThread_acquire_lock_timed() below). PY_TIMEOUT_MAX is the highest usable value (in microseconds) of that @@ -124,35 +112,6 @@ Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyThread_ReInitTLS(void); typedef struct _Py_tss_t Py_tss_t; /* opaque */ -#ifndef Py_LIMITED_API -#if defined(_POSIX_THREADS) - /* Darwin needs pthread.h to know type name the pthread_key_t. */ -# include -# define NATIVE_TSS_KEY_T pthread_key_t -#elif defined(NT_THREADS) - /* In Windows, native TSS key type is DWORD, - but hardcode the unsigned long to avoid errors for include directive. - */ -# define NATIVE_TSS_KEY_T unsigned long -#else -# error "Require native threads. See https://bugs.python.org/issue31370" -#endif - -/* When Py_LIMITED_API is not defined, the type layout of Py_tss_t is - exposed to allow static allocation in the API clients. Even in this case, - you must handle TSS keys through API functions due to compatibility. -*/ -struct _Py_tss_t { - int _is_initialized; - NATIVE_TSS_KEY_T _key; -}; - -#undef NATIVE_TSS_KEY_T - -/* When static allocation, you must initialize with Py_tss_NEEDS_INIT. */ -#define Py_tss_NEEDS_INIT {0} -#endif /* !Py_LIMITED_API */ - PyAPI_FUNC(Py_tss_t *) PyThread_tss_alloc(void); PyAPI_FUNC(void) PyThread_tss_free(Py_tss_t *key); @@ -164,8 +123,13 @@ PyAPI_FUNC(int) PyThread_tss_set(Py_tss_t *key, void *value); PyAPI_FUNC(void *) PyThread_tss_get(Py_tss_t *key); #endif /* New in 3.7 */ +#ifndef Py_LIMITED_API +# define Py_CPYTHON_PYTHREAD_H +# include "cpython/pythread.h" +# undef Py_CPYTHON_PYTHREAD_H +#endif + #ifdef __cplusplus } #endif - #endif /* !Py_PYTHREAD_H */ diff --git a/Include/pytypedefs.h b/Include/pytypedefs.h new file mode 100644 index 00000000000..e78ed56a3b6 --- /dev/null +++ b/Include/pytypedefs.h @@ -0,0 +1,30 @@ +// Forward declarations of types of the Python C API. +// Declare them at the same place since redefining typedef is a C11 feature. +// Only use a forward declaration if there is an interdependency between two +// header files. + +#ifndef Py_PYTYPEDEFS_H +#define Py_PYTYPEDEFS_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct PyModuleDef PyModuleDef; +typedef struct PyModuleDef_Slot PyModuleDef_Slot; +typedef struct PyMethodDef PyMethodDef; +typedef struct PyGetSetDef PyGetSetDef; +typedef struct PyMemberDef PyMemberDef; + +typedef struct _object PyObject; +typedef struct _longobject PyLongObject; +typedef struct _typeobject PyTypeObject; +typedef struct PyCodeObject PyCodeObject; +typedef struct _frame PyFrameObject; + +typedef struct _ts PyThreadState; +typedef struct _is PyInterpreterState; + +#ifdef __cplusplus +} +#endif +#endif // !Py_PYTYPEDEFS_H diff --git a/Include/rangeobject.h b/Include/rangeobject.h index d6af8473f9e..d46ce7cd41b 100644 --- a/Include/rangeobject.h +++ b/Include/rangeobject.h @@ -19,7 +19,7 @@ PyAPI_DATA(PyTypeObject) PyRange_Type; PyAPI_DATA(PyTypeObject) PyRangeIter_Type; PyAPI_DATA(PyTypeObject) PyLongRangeIter_Type; -#define PyRange_Check(op) Py_IS_TYPE(op, &PyRange_Type) +#define PyRange_Check(op) Py_IS_TYPE((op), &PyRange_Type) #ifdef __cplusplus } diff --git a/Include/setobject.h b/Include/setobject.h index 62516be5ab2..62c9e6b13f8 100644 --- a/Include/setobject.h +++ b/Include/setobject.h @@ -6,73 +6,6 @@ extern "C" { #endif -#ifndef Py_LIMITED_API - -/* There are three kinds of entries in the table: - -1. Unused: key == NULL and hash == 0 -2. Dummy: key == dummy and hash == -1 -3. Active: key != NULL and key != dummy and hash != -1 - -The hash field of Unused slots is always zero. - -The hash field of Dummy slots are set to -1 -meaning that dummy entries can be detected by -either entry->key==dummy or by entry->hash==-1. -*/ - -#define PySet_MINSIZE 8 - -typedef struct { - PyObject *key; - Py_hash_t hash; /* Cached hash code of the key */ -} setentry; - -/* The SetObject data structure is shared by set and frozenset objects. - -Invariant for sets: - - hash is -1 - -Invariants for frozensets: - - data is immutable. - - hash is the hash of the frozenset or -1 if not computed yet. - -*/ - -typedef struct { - PyObject_HEAD - - Py_ssize_t fill; /* Number active and dummy entries*/ - Py_ssize_t used; /* Number active entries */ - - /* The table contains mask + 1 slots, and that's a power of 2. - * We store the mask instead of the size because the mask is more - * frequently needed. - */ - Py_ssize_t mask; - - /* The table points to a fixed-size smalltable for small tables - * or to additional malloc'ed memory for bigger tables. - * The table pointer is never NULL which saves us from repeated - * runtime null-tests. - */ - setentry *table; - Py_hash_t hash; /* Only used by frozenset objects */ - Py_ssize_t finger; /* Search finger for pop() */ - - setentry smalltable[PySet_MINSIZE]; - PyObject *weakreflist; /* List of weak references */ -} PySetObject; - -#define PySet_GET_SIZE(so) (assert(PyAnySet_Check(so)),(((PySetObject *)(so))->used)) - -PyAPI_DATA(PyObject *) _PySet_Dummy; - -PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash); -PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); - -#endif /* Section excluded by Py_LIMITED_API */ - PyAPI_DATA(PyTypeObject) PySet_Type; PyAPI_DATA(PyTypeObject) PyFrozenSet_Type; PyAPI_DATA(PyTypeObject) PySetIter_Type; @@ -87,23 +20,29 @@ PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key); PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set); PyAPI_FUNC(Py_ssize_t) PySet_Size(PyObject *anyset); -#define PyFrozenSet_CheckExact(ob) Py_IS_TYPE(ob, &PyFrozenSet_Type) +#define PyFrozenSet_CheckExact(ob) Py_IS_TYPE((ob), &PyFrozenSet_Type) #define PyFrozenSet_Check(ob) \ - (Py_IS_TYPE(ob, &PyFrozenSet_Type) || \ + (Py_IS_TYPE((ob), &PyFrozenSet_Type) || \ PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) #define PyAnySet_CheckExact(ob) \ - (Py_IS_TYPE(ob, &PySet_Type) || Py_IS_TYPE(ob, &PyFrozenSet_Type)) + (Py_IS_TYPE((ob), &PySet_Type) || Py_IS_TYPE((ob), &PyFrozenSet_Type)) #define PyAnySet_Check(ob) \ - (Py_IS_TYPE(ob, &PySet_Type) || Py_IS_TYPE(ob, &PyFrozenSet_Type) || \ + (Py_IS_TYPE((ob), &PySet_Type) || Py_IS_TYPE((ob), &PyFrozenSet_Type) || \ PyType_IsSubtype(Py_TYPE(ob), &PySet_Type) || \ PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) #define PySet_CheckExact(op) Py_IS_TYPE(op, &PySet_Type) #define PySet_Check(ob) \ - (Py_IS_TYPE(ob, &PySet_Type) || \ + (Py_IS_TYPE((ob), &PySet_Type) || \ PyType_IsSubtype(Py_TYPE(ob), &PySet_Type)) +#ifndef Py_LIMITED_API +# define Py_CPYTHON_SETOBJECT_H +# include "cpython/setobject.h" +# undef Py_CPYTHON_SETOBJECT_H +#endif + #ifdef __cplusplus } #endif diff --git a/Include/sliceobject.h b/Include/sliceobject.h index 2c889508b4b..c13863f27c2 100644 --- a/Include/sliceobject.h +++ b/Include/sliceobject.h @@ -28,7 +28,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PySlice_Type; PyAPI_DATA(PyTypeObject) PyEllipsis_Type; -#define PySlice_Check(op) Py_IS_TYPE(op, &PySlice_Type) +#define PySlice_Check(op) Py_IS_TYPE((op), &PySlice_Type) PyAPI_FUNC(PyObject *) PySlice_New(PyObject* start, PyObject* stop, PyObject* step); diff --git a/Include/structmember.h b/Include/structmember.h index 93b7aff8091..f6e8fd82989 100644 --- a/Include/structmember.h +++ b/Include/structmember.h @@ -5,69 +5,50 @@ extern "C" { #endif -/* Interface to map C struct members to Python object attributes */ +/* Interface to map C struct members to Python object attributes + * + * This header is deprecated: new code should not use stuff from here. + * New definitions are in descrobject.h. + * + * However, there's nothing wrong with old code continuing to use it, + * and there's not much mainenance overhead in maintaining a few aliases. + * So, don't be too eager to convert old code. + * + * It uses names not prefixed with Py_. + * It is also *not* included from Python.h and must be included individually. + */ -#include /* For offsetof */ - -/* An array of PyMemberDef structures defines the name, type and offset - of selected members of a C structure. These can be read by - PyMember_GetOne() and set by PyMember_SetOne() (except if their READONLY - flag is set). The array must be terminated with an entry whose name - pointer is NULL. */ - -typedef struct PyMemberDef { - const char *name; - int type; - Py_ssize_t offset; - int flags; - const char *doc; -} PyMemberDef; +#include /* For offsetof (not always provided by Python.h) */ /* Types */ -#define T_SHORT 0 -#define T_INT 1 -#define T_LONG 2 -#define T_FLOAT 3 -#define T_DOUBLE 4 -#define T_STRING 5 -#define T_OBJECT 6 -/* XXX the ordering here is weird for binary compatibility */ -#define T_CHAR 7 /* 1-character string */ -#define T_BYTE 8 /* 8-bit signed int */ -/* unsigned variants: */ -#define T_UBYTE 9 -#define T_USHORT 10 -#define T_UINT 11 -#define T_ULONG 12 - -/* Added by Jack: strings contained in the structure */ -#define T_STRING_INPLACE 13 - -/* Added by Lillo: bools contained in the structure (assumed char) */ -#define T_BOOL 14 - -#define T_OBJECT_EX 16 /* Like T_OBJECT, but raises AttributeError - when the value is NULL, instead of - converting to None. */ -#define T_LONGLONG 17 -#define T_ULONGLONG 18 - -#define T_PYSSIZET 19 /* Py_ssize_t */ -#define T_NONE 20 /* Value is always None */ - +#define T_SHORT Py_T_SHORT +#define T_INT Py_T_INT +#define T_LONG Py_T_LONG +#define T_FLOAT Py_T_FLOAT +#define T_DOUBLE Py_T_DOUBLE +#define T_STRING Py_T_STRING +#define T_OBJECT _Py_T_OBJECT +#define T_CHAR Py_T_CHAR +#define T_BYTE Py_T_BYTE +#define T_UBYTE Py_T_UBYTE +#define T_USHORT Py_T_USHORT +#define T_UINT Py_T_UINT +#define T_ULONG Py_T_ULONG +#define T_STRING_INPLACE Py_T_STRING_INPLACE +#define T_BOOL Py_T_BOOL +#define T_OBJECT_EX Py_T_OBJECT_EX +#define T_LONGLONG Py_T_LONGLONG +#define T_ULONGLONG Py_T_ULONGLONG +#define T_PYSSIZET Py_T_PYSSIZET +#define T_NONE _Py_T_NONE /* Flags */ -#define READONLY 1 -#define READ_RESTRICTED 2 -#define PY_WRITE_RESTRICTED 4 +#define READONLY Py_READONLY +#define PY_AUDIT_READ Py_AUDIT_READ +#define READ_RESTRICTED Py_AUDIT_READ +#define PY_WRITE_RESTRICTED _Py_WRITE_RESTRICTED #define RESTRICTED (READ_RESTRICTED | PY_WRITE_RESTRICTED) -#define PY_AUDIT_READ READ_RESTRICTED - -/* Current API, use this */ -PyAPI_FUNC(PyObject *) PyMember_GetOne(const char *, struct PyMemberDef *); -PyAPI_FUNC(int) PyMember_SetOne(char *, struct PyMemberDef *, PyObject *); - #ifdef __cplusplus } diff --git a/Include/structseq.h b/Include/structseq.h index e89265a67c3..96871155611 100644 --- a/Include/structseq.h +++ b/Include/structseq.h @@ -15,7 +15,7 @@ typedef struct PyStructSequence_Field { typedef struct PyStructSequence_Desc { const char *name; const char *doc; - struct PyStructSequence_Field *fields; + PyStructSequence_Field *fields; int n_in_sequence; } PyStructSequence_Desc; @@ -35,9 +35,9 @@ PyAPI_FUNC(PyObject *) PyStructSequence_New(PyTypeObject* type); typedef PyTupleObject PyStructSequence; /* Macro, *only* to be used to fill in brand new objects */ -#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM(op, i, v) +#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v)) -#define PyStructSequence_GET_ITEM(op, i) PyTuple_GET_ITEM(op, i) +#define PyStructSequence_GET_ITEM(op, i) PyTuple_GET_ITEM((op), (i)) #endif PyAPI_FUNC(void) PyStructSequence_SetItem(PyObject*, Py_ssize_t, PyObject*); diff --git a/Include/sysmodule.h b/Include/sysmodule.h index 3463c622309..b5087119b1c 100644 --- a/Include/sysmodule.h +++ b/Include/sysmodule.h @@ -10,9 +10,9 @@ extern "C" { PyAPI_FUNC(PyObject *) PySys_GetObject(const char *); PyAPI_FUNC(int) PySys_SetObject(const char *, PyObject *); -PyAPI_FUNC(void) PySys_SetArgv(int, wchar_t **); -PyAPI_FUNC(void) PySys_SetArgvEx(int, wchar_t **, int); -PyAPI_FUNC(void) PySys_SetPath(const wchar_t *); +Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetArgv(int, wchar_t **); +Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetArgvEx(int, wchar_t **, int); +Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetPath(const wchar_t *); PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...) Py_GCC_ATTRIBUTE((format(printf, 1, 2))); diff --git a/Include/traceback.h b/Include/traceback.h index 2dfa2ada4f2..2b40cc9fc32 100644 --- a/Include/traceback.h +++ b/Include/traceback.h @@ -11,7 +11,7 @@ PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *); /* Reveal traceback type so we can typecheck traceback objects */ PyAPI_DATA(PyTypeObject) PyTraceBack_Type; -#define PyTraceBack_Check(v) Py_IS_TYPE(v, &PyTraceBack_Type) +#define PyTraceBack_Check(v) Py_IS_TYPE((v), &PyTraceBack_Type) #ifndef Py_LIMITED_API diff --git a/Include/tupleobject.h b/Include/tupleobject.h index dc68e3fc5c6..1f9ab54be65 100644 --- a/Include/tupleobject.h +++ b/Include/tupleobject.h @@ -25,7 +25,7 @@ PyAPI_DATA(PyTypeObject) PyTupleIter_Type; #define PyTuple_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS) -#define PyTuple_CheckExact(op) Py_IS_TYPE(op, &PyTuple_Type) +#define PyTuple_CheckExact(op) Py_IS_TYPE((op), &PyTuple_Type) PyAPI_FUNC(PyObject *) PyTuple_New(Py_ssize_t size); PyAPI_FUNC(Py_ssize_t) PyTuple_Size(PyObject *); diff --git a/Include/typeslots.h b/Include/typeslots.h index 5800d0158bc..506b05580de 100644 --- a/Include/typeslots.h +++ b/Include/typeslots.h @@ -1,12 +1,6 @@ /* Do not renumber the file; these numbers are part of the stable ABI. */ -#if defined(Py_LIMITED_API) -/* Disabled, see #10181 */ -#undef Py_bf_getbuffer -#undef Py_bf_releasebuffer -#else #define Py_bf_getbuffer 1 #define Py_bf_releasebuffer 2 -#endif #define Py_mp_ass_subscript 3 #define Py_mp_length 4 #define Py_mp_subscript 5 diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index abce967caff..74474f5bb8f 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -112,8 +112,8 @@ PyAPI_DATA(PyTypeObject) PyUnicode_Type; PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type; #define PyUnicode_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) -#define PyUnicode_CheckExact(op) Py_IS_TYPE(op, &PyUnicode_Type) + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) +#define PyUnicode_CheckExact(op) Py_IS_TYPE((op), &PyUnicode_Type) /* --- Constants ---------------------------------------------------------- */ @@ -171,13 +171,6 @@ PyAPI_FUNC(Py_ssize_t) PyUnicode_GetLength( ); #endif -/* Get the number of Py_UNICODE units in the - string representation. */ - -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_ssize_t) PyUnicode_GetSize( - PyObject *unicode /* Unicode object */ - ); - #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 /* Read a character from the string. */ @@ -198,9 +191,7 @@ PyAPI_FUNC(int) PyUnicode_WriteChar( ); #endif -/* Resize a Unicode object. The length is the number of characters, except - if the kind of the string is PyUnicode_WCHAR_KIND: in this case, the length - is the number of Py_UNICODE characters. +/* Resize a Unicode object. The length is the number of codepoints. *unicode is modified to point to the new (resized) object and 0 returned on success. @@ -265,14 +256,6 @@ PyAPI_FUNC(PyObject *) PyUnicode_InternFromString( const char *u /* UTF-8 encoded string */ ); -// PyUnicode_InternImmortal() is deprecated since Python 3.10 -// and will be removed in Python 3.12. Use PyUnicode_InternInPlace() instead. -Py_DEPRECATED(3.10) PyAPI_FUNC(void) PyUnicode_InternImmortal(PyObject **); - -/* Use only if you know it's a string */ -#define PyUnicode_CHECK_INTERNED(op) \ - (((PyASCIIObject *)(op))->state.interned) - /* --- wchar_t support for platforms which support it --------------------- */ #ifdef HAVE_WCHAR_H @@ -772,38 +755,22 @@ PyAPI_FUNC(int) PyUnicode_FSConverter(PyObject*, void*); PyAPI_FUNC(int) PyUnicode_FSDecoder(PyObject*, void*); -/* Decode a null-terminated string using Py_FileSystemDefaultEncoding - and the "surrogateescape" error handler. - - If Py_FileSystemDefaultEncoding is not set, fall back to the locale - encoding. - - Use PyUnicode_DecodeFSDefaultAndSize() if the string length is known. -*/ +/* Decode a null-terminated string from the Python filesystem encoding + and error handler. + If the string length is known, use PyUnicode_DecodeFSDefaultAndSize(). */ PyAPI_FUNC(PyObject*) PyUnicode_DecodeFSDefault( const char *s /* encoded string */ ); -/* Decode a string using Py_FileSystemDefaultEncoding - and the "surrogateescape" error handler. - - If Py_FileSystemDefaultEncoding is not set, fall back to the locale - encoding. -*/ - +/* Decode a string from the Python filesystem encoding and error handler. */ PyAPI_FUNC(PyObject*) PyUnicode_DecodeFSDefaultAndSize( const char *s, /* encoded string */ Py_ssize_t size /* size */ ); -/* Encode a Unicode object to Py_FileSystemDefaultEncoding with the - "surrogateescape" error handler, and return bytes. - - If Py_FileSystemDefaultEncoding is not set, fall back to the locale - encoding. -*/ - +/* Encode a Unicode object to the Python filesystem encoding and error handler. + Return bytes. */ PyAPI_FUNC(PyObject*) PyUnicode_EncodeFSDefault( PyObject *unicode ); diff --git a/Include/weakrefobject.h b/Include/weakrefobject.h index f071e9c759a..8e1fa1b9286 100644 --- a/Include/weakrefobject.h +++ b/Include/weakrefobject.h @@ -12,12 +12,12 @@ PyAPI_DATA(PyTypeObject) _PyWeakref_RefType; PyAPI_DATA(PyTypeObject) _PyWeakref_ProxyType; PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType; -#define PyWeakref_CheckRef(op) PyObject_TypeCheck(op, &_PyWeakref_RefType) +#define PyWeakref_CheckRef(op) PyObject_TypeCheck((op), &_PyWeakref_RefType) #define PyWeakref_CheckRefExact(op) \ - Py_IS_TYPE(op, &_PyWeakref_RefType) + Py_IS_TYPE((op), &_PyWeakref_RefType) #define PyWeakref_CheckProxy(op) \ - (Py_IS_TYPE(op, &_PyWeakref_ProxyType) || \ - Py_IS_TYPE(op, &_PyWeakref_CallableProxyType)) + (Py_IS_TYPE((op), &_PyWeakref_ProxyType) \ + || Py_IS_TYPE((op), &_PyWeakref_CallableProxyType)) #define PyWeakref_Check(op) \ (PyWeakref_CheckRef(op) || PyWeakref_CheckProxy(op)) diff --git a/LICENSE b/LICENSE index 55cb8d37e52..f26bcf4d2de 100644 --- a/LICENSE +++ b/LICENSE @@ -2,12 +2,12 @@ A. HISTORY OF THE SOFTWARE ========================== Python was created in the early 1990s by Guido van Rossum at Stichting -Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands +Mathematisch Centrum (CWI, see https://www.cwi.nl) in the Netherlands as a successor of a language called ABC. Guido remains Python's principal author, although it includes many contributions from others. In 1995, Guido continued his work on Python at the Corporation for -National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) +National Research Initiatives (CNRI, see https://www.cnri.reston.va.us) in Reston, Virginia where he released several versions of the software. @@ -19,7 +19,7 @@ https://www.python.org/psf/) was formed, a non-profit organization created specifically to own Python-related Intellectual Property. Zope Corporation was a sponsoring member of the PSF. -All Python releases are Open Source (see http://www.opensource.org for +All Python releases are Open Source (see https://opensource.org for the Open Source Definition). Historically, most, but not all, Python releases have also been GPL-compatible; the table below summarizes the various releases. @@ -84,7 +84,7 @@ analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Python Software Foundation; +2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee. diff --git a/Lib/__future__.py b/Lib/__future__.py index 97dc90c6e46..39720a5e412 100644 --- a/Lib/__future__.py +++ b/Lib/__future__.py @@ -33,7 +33,7 @@ in releases at or after that, modules no longer need to use the feature in question, but may continue to use such imports. MandatoryRelease may also be None, meaning that a planned feature got -dropped. +dropped or that the release version is undetermined. Instances of class _Feature have two corresponding methods, .getOptionalRelease() and .getMandatoryRelease(). @@ -96,7 +96,7 @@ class _Feature: """Return release in which this feature will become mandatory. This is a 5-tuple, of the same form as sys.version_info, or, if - the feature was dropped, is None. + the feature was dropped, or the release date is undetermined, is None. """ return self.mandatory @@ -143,5 +143,5 @@ generator_stop = _Feature((3, 5, 0, "beta", 1), CO_FUTURE_GENERATOR_STOP) annotations = _Feature((3, 7, 0, "beta", 1), - (3, 11, 0, "alpha", 0), + None, CO_FUTURE_ANNOTATIONS) diff --git a/Lib/__hello__.py b/Lib/__hello__.py index d37bd2766ac..c09d6a4f523 100644 --- a/Lib/__hello__.py +++ b/Lib/__hello__.py @@ -1,5 +1,14 @@ initialized = True +class TestFrozenUtf8_1: + """\u00b6""" + +class TestFrozenUtf8_2: + """\u03c0""" + +class TestFrozenUtf8_4: + """\U0001f600""" + def main(): print("Hello world!") diff --git a/Lib/_aix_support.py b/Lib/_aix_support.py index 1d8482ff382..18533e769b7 100644 --- a/Lib/_aix_support.py +++ b/Lib/_aix_support.py @@ -1,15 +1,9 @@ """Shared AIX support functions.""" +import subprocess import sys import sysconfig -try: - import subprocess -except ImportError: # pragma: no cover - # _aix_support is used in distutils by setup.py to build C extensions, - # before subprocess dependencies like _posixsubprocess are available. - import _bootsubprocess as subprocess - def _aix_tag(vrtl, bd): # type: (List[int], int) -> str diff --git a/Lib/_bootsubprocess.py b/Lib/_bootsubprocess.py deleted file mode 100644 index 014782f616c..00000000000 --- a/Lib/_bootsubprocess.py +++ /dev/null @@ -1,97 +0,0 @@ -""" -Basic subprocess implementation for POSIX which only uses os functions. Only -implement features required by setup.py to build C extension modules when -subprocess is unavailable. setup.py is not used on Windows. -""" -import os - - -# distutils.spawn used by distutils.command.build_ext -# calls subprocess.Popen().wait() -class Popen: - def __init__(self, cmd, env=None): - self._cmd = cmd - self._env = env - self.returncode = None - - def wait(self): - pid = os.fork() - if pid == 0: - # Child process - try: - if self._env is not None: - os.execve(self._cmd[0], self._cmd, self._env) - else: - os.execv(self._cmd[0], self._cmd) - finally: - os._exit(1) - else: - # Parent process - _, status = os.waitpid(pid, 0) - self.returncode = os.waitstatus_to_exitcode(status) - - return self.returncode - - -def _check_cmd(cmd): - # Use regex [a-zA-Z0-9./-]+: reject empty string, space, etc. - safe_chars = [] - for first, last in (("a", "z"), ("A", "Z"), ("0", "9")): - for ch in range(ord(first), ord(last) + 1): - safe_chars.append(chr(ch)) - safe_chars.append("./-") - safe_chars = ''.join(safe_chars) - - if isinstance(cmd, (tuple, list)): - check_strs = cmd - elif isinstance(cmd, str): - check_strs = [cmd] - else: - return False - - for arg in check_strs: - if not isinstance(arg, str): - return False - if not arg: - # reject empty string - return False - for ch in arg: - if ch not in safe_chars: - return False - - return True - - -# _aix_support used by distutil.util calls subprocess.check_output() -def check_output(cmd, **kwargs): - if kwargs: - raise NotImplementedError(repr(kwargs)) - - if not _check_cmd(cmd): - raise ValueError(f"unsupported command: {cmd!r}") - - tmp_filename = "check_output.tmp" - if not isinstance(cmd, str): - cmd = " ".join(cmd) - cmd = f"{cmd} >{tmp_filename}" - - try: - # system() spawns a shell - status = os.system(cmd) - exitcode = os.waitstatus_to_exitcode(status) - if exitcode: - raise ValueError(f"Command {cmd!r} returned non-zero " - f"exit status {exitcode!r}") - - try: - with open(tmp_filename, "rb") as fp: - stdout = fp.read() - except FileNotFoundError: - stdout = b'' - finally: - try: - os.unlink(tmp_filename) - except OSError: - pass - - return stdout diff --git a/Lib/_collections_abc.py b/Lib/_collections_abc.py index 87a9cd2d46d..c62233b81a5 100644 --- a/Lib/_collections_abc.py +++ b/Lib/_collections_abc.py @@ -6,6 +6,32 @@ Unit tests are in test_collections. """ +############ Maintenance notes ######################################### +# +# ABCs are different from other standard library modules in that they +# specify compliance tests. In general, once an ABC has been published, +# new methods (either abstract or concrete) cannot be added. +# +# Though classes that inherit from an ABC would automatically receive a +# new mixin method, registered classes would become non-compliant and +# violate the contract promised by ``isinstance(someobj, SomeABC)``. +# +# Though irritating, the correct procedure for adding new abstract or +# mixin methods is to create a new ABC as a subclass of the previous +# ABC. For example, union(), intersection(), and difference() cannot +# be added to Set but could go into a new ABC that extends Set. +# +# Because they are so hard to change, new ABCs should have their APIs +# carefully thought through prior to publication. +# +# Since ABCMeta only checks for the presence of methods, it is possible +# to alter the signature of a method by adding optional arguments +# or changing parameters names. This is still a bit dubious but at +# least it won't cause isinstance() to return an incorrect result. +# +# +####################################################################### + from abc import ABCMeta, abstractmethod import sys @@ -430,25 +456,13 @@ class _CallableGenericAlias(GenericAlias): raise TypeError( "Callable must be used as Callable[[arg, ...], result].") t_args, t_result = args - if isinstance(t_args, list): + if isinstance(t_args, (tuple, list)): args = (*t_args, t_result) elif not _is_param_expr(t_args): raise TypeError(f"Expected a list of types, an ellipsis, " f"ParamSpec, or Concatenate. Got {t_args}") return super().__new__(cls, origin, args) - @property - def __parameters__(self): - params = [] - for arg in self.__args__: - # Looks like a genericalias - if hasattr(arg, "__parameters__") and isinstance(arg.__parameters__, tuple): - params.extend(arg.__parameters__) - else: - if _is_typevarlike(arg): - params.append(arg) - return tuple(dict.fromkeys(params)) - def __repr__(self): if len(self.__args__) == 2 and _is_param_expr(self.__args__[0]): return super().__repr__() @@ -468,54 +482,24 @@ class _CallableGenericAlias(GenericAlias): # code is copied from typing's _GenericAlias and the builtin # types.GenericAlias. - # A special case in PEP 612 where if X = Callable[P, int], - # then X[int, str] == X[[int, str]]. - param_len = len(self.__parameters__) - if param_len == 0: - raise TypeError(f'{self} is not a generic class') if not isinstance(item, tuple): item = (item,) - if (param_len == 1 and _is_param_expr(self.__parameters__[0]) + # A special case in PEP 612 where if X = Callable[P, int], + # then X[int, str] == X[[int, str]]. + if (len(self.__parameters__) == 1 + and _is_param_expr(self.__parameters__[0]) and item and not _is_param_expr(item[0])): - item = (list(item),) - item_len = len(item) - if item_len != param_len: - raise TypeError(f'Too {"many" if item_len > param_len else "few"}' - f' arguments for {self};' - f' actual {item_len}, expected {param_len}') - subst = dict(zip(self.__parameters__, item)) - new_args = [] - for arg in self.__args__: - if _is_typevarlike(arg): - if _is_param_expr(arg): - arg = subst[arg] - if not _is_param_expr(arg): - raise TypeError(f"Expected a list of types, an ellipsis, " - f"ParamSpec, or Concatenate. Got {arg}") - else: - arg = subst[arg] - # Looks like a GenericAlias - elif hasattr(arg, '__parameters__') and isinstance(arg.__parameters__, tuple): - subparams = arg.__parameters__ - if subparams: - subargs = tuple(subst[x] for x in subparams) - arg = arg[subargs] - new_args.append(arg) + item = (item,) + + new_args = super().__getitem__(item).__args__ # args[0] occurs due to things like Z[[int, str, bool]] from PEP 612 - if not isinstance(new_args[0], list): + if not isinstance(new_args[0], (tuple, list)): t_result = new_args[-1] t_args = new_args[:-1] new_args = (t_args, t_result) return _CallableGenericAlias(Callable, tuple(new_args)) - -def _is_typevarlike(arg): - obj = type(arg) - # looks like a TypeVar/ParamSpec - return (obj.__module__ == 'typing' - and obj.__name__ in {'ParamSpec', 'TypeVar'}) - def _is_param_expr(obj): """Checks if obj matches either a list of types, ``...``, ``ParamSpec`` or ``_ConcatenateGenericAlias`` from typing.py @@ -868,7 +852,7 @@ class KeysView(MappingView, Set): __slots__ = () @classmethod - def _from_iterable(self, it): + def _from_iterable(cls, it): return set(it) def __contains__(self, key): @@ -886,7 +870,7 @@ class ItemsView(MappingView, Set): __slots__ = () @classmethod - def _from_iterable(self, it): + def _from_iterable(cls, it): return set(it) def __contains__(self, item): @@ -1064,10 +1048,10 @@ class Sequence(Reversible, Collection): while stop is None or i < stop: try: v = self[i] - if v is value or v == value: - return i except IndexError: break + if v is value or v == value: + return i i += 1 raise ValueError diff --git a/Lib/_compat_pickle.py b/Lib/_compat_pickle.py index f68496ae639..65a94b6b1bd 100644 --- a/Lib/_compat_pickle.py +++ b/Lib/_compat_pickle.py @@ -249,3 +249,4 @@ PYTHON3_IMPORTERROR_EXCEPTIONS = ( for excname in PYTHON3_IMPORTERROR_EXCEPTIONS: REVERSE_NAME_MAPPING[('builtins', excname)] = ('exceptions', 'ImportError') +del excname diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py index f6d9ddf42e4..2692f2fcba4 100644 --- a/Lib/_pydecimal.py +++ b/Lib/_pydecimal.py @@ -159,7 +159,7 @@ import sys try: from collections import namedtuple as _namedtuple - DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent') + DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent', module='decimal') except ImportError: DecimalTuple = lambda *args: args @@ -441,6 +441,10 @@ import contextvars _current_context_var = contextvars.ContextVar('decimal_context') +_context_attributes = frozenset( + ['prec', 'Emin', 'Emax', 'capitals', 'clamp', 'rounding', 'flags', 'traps'] +) + def getcontext(): """Returns this thread's context. @@ -464,7 +468,7 @@ def setcontext(context): del contextvars # Don't contaminate the namespace -def localcontext(ctx=None): +def localcontext(ctx=None, **kwargs): """Return a context manager for a copy of the supplied context Uses a copy of the current context if no context is specified @@ -500,8 +504,14 @@ def localcontext(ctx=None): >>> print(getcontext().prec) 28 """ - if ctx is None: ctx = getcontext() - return _ContextManager(ctx) + if ctx is None: + ctx = getcontext() + ctx_manager = _ContextManager(ctx) + for key, value in kwargs.items(): + if key not in _context_attributes: + raise TypeError(f"'{key}' is an invalid keyword argument for this function") + setattr(ctx_manager.new_context, key, value) + return ctx_manager ##### Decimal class ####################################################### @@ -3795,6 +3805,10 @@ class Decimal(object): # represented in fixed point; rescale them to 0e0. if not self and self._exp > 0 and spec['type'] in 'fF%': self = self._rescale(0, rounding) + if not self and spec['no_neg_0'] and self._sign: + adjusted_sign = 0 + else: + adjusted_sign = self._sign # figure out placement of the decimal point leftdigits = self._exp + len(self._int) @@ -3825,7 +3839,7 @@ class Decimal(object): # done with the decimal-specific stuff; hand over the rest # of the formatting to the _format_number function - return _format_number(self._sign, intpart, fracpart, exp, spec) + return _format_number(adjusted_sign, intpart, fracpart, exp, spec) def _dec_from_triple(sign, coefficient, exponent, special=False): """Create a decimal instance directly, without any validation, @@ -6143,7 +6157,7 @@ _exact_half = re.compile('50*$').match # # A format specifier for Decimal looks like: # -# [[fill]align][sign][#][0][minimumwidth][,][.precision][type] +# [[fill]align][sign][z][#][0][minimumwidth][,][.precision][type] _parse_format_specifier_regex = re.compile(r"""\A (?: @@ -6151,6 +6165,7 @@ _parse_format_specifier_regex = re.compile(r"""\A (?P[<>=^]) )? (?P[-+ ])? +(?Pz)? (?P\#)? (?P0)? (?P(?!0)\d+)? diff --git a/Lib/_pyio.py b/Lib/_pyio.py index d7119742b9d..7f247ff47c9 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -44,8 +44,9 @@ def text_encoding(encoding, stacklevel=2): """ A helper function to choose the text encoding. - When encoding is not None, just return it. - Otherwise, return the default text encoding (i.e. "locale"). + When encoding is not None, this function returns it. + Otherwise, this function returns the default text encoding + (i.e. "locale" or "utf-8" depends on UTF-8 mode). This function emits an EncodingWarning if *encoding* is None and sys.flags.warn_default_encoding is true. @@ -55,7 +56,10 @@ def text_encoding(encoding, stacklevel=2): However, please consider using encoding="utf-8" for new APIs. """ if encoding is None: - encoding = "locale" + if sys.flags.utf8_mode: + encoding = "utf-8" + else: + encoding = "locale" if sys.flags.warn_default_encoding: import warnings warnings.warn("'encoding' argument not specified.", @@ -299,22 +303,6 @@ except AttributeError: open_code = _open_code_with_warning -def __getattr__(name): - if name == "OpenWrapper": - # bpo-43680: Until Python 3.9, _pyio.open was not a static method and - # builtins.open was set to OpenWrapper to not become a bound method - # when set to a class variable. _io.open is a built-in function whereas - # _pyio.open is a Python function. In Python 3.10, _pyio.open() is now - # a static method, and builtins.open() is now io.open(). - import warnings - warnings.warn('OpenWrapper is deprecated, use open instead', - DeprecationWarning, stacklevel=2) - global OpenWrapper - OpenWrapper = open - return OpenWrapper - raise AttributeError(name) - - # In normal operation, both `UnsupportedOperation`s should be bound to the # same object. try: @@ -326,8 +314,7 @@ except AttributeError: class IOBase(metaclass=abc.ABCMeta): - """The abstract base class for all I/O classes, acting on streams of - bytes. There is no public constructor. + """The abstract base class for all I/O classes. This class provides dummy implementations for many methods that derived classes can override selectively; the default implementations @@ -651,10 +638,7 @@ class RawIOBase(IOBase): def readall(self): """Read until EOF, using multiple read() call.""" res = bytearray() - while True: - data = self.read(DEFAULT_BUFFER_SIZE) - if not data: - break + while data := self.read(DEFAULT_BUFFER_SIZE): res += data if res: return bytes(res) @@ -1142,6 +1126,7 @@ class BufferedReader(_BufferedIOMixin): do at most one raw read to satisfy it. We never return more than self.buffer_size. """ + self._checkClosed("peek of closed file") with self._read_lock: return self._peek_unlocked(size) @@ -1160,6 +1145,7 @@ class BufferedReader(_BufferedIOMixin): """Reads up to size bytes, with at most one read() system call.""" # Returns up to size bytes. If at least one byte is buffered, we # only return buffered bytes. Otherwise, we do one raw read. + self._checkClosed("read of closed file") if size < 0: size = self.buffer_size if size == 0: @@ -1177,6 +1163,8 @@ class BufferedReader(_BufferedIOMixin): def _readinto(self, buf, read1): """Read data into *buf* with at most one system call.""" + self._checkClosed("readinto of closed file") + # Need to create a memoryview object of type 'b', otherwise # we may not be able to assign bytes to it, and slicing it # would create a new object. @@ -1226,6 +1214,7 @@ class BufferedReader(_BufferedIOMixin): def seek(self, pos, whence=0): if whence not in valid_seek_flags: raise ValueError("invalid whence value") + self._checkClosed("seek of closed file") with self._read_lock: if whence == 1: pos -= len(self._read_buf) - self._read_pos @@ -1833,7 +1822,7 @@ class TextIOBase(IOBase): """Base class for text I/O. This class provides a character and line based interface to stream - I/O. There is no public constructor. + I/O. """ def read(self, size=-1): @@ -1985,7 +1974,7 @@ class TextIOWrapper(TextIOBase): r"""Character and line based layer over a BufferedIOBase object, buffer. encoding gives the name of the encoding that the stream will be - decoded or encoded with. It defaults to locale.getpreferredencoding(False). + decoded or encoded with. It defaults to locale.getencoding(). errors determines the strictness of encoding and decoding (see the codecs.register) and defaults to "strict". @@ -2019,19 +2008,7 @@ class TextIOWrapper(TextIOBase): encoding = text_encoding(encoding) if encoding == "locale": - try: - encoding = os.device_encoding(buffer.fileno()) or "locale" - except (AttributeError, UnsupportedOperation): - pass - - if encoding == "locale": - try: - import locale - except ImportError: - # Importing locale may fail if Python is being built - encoding = "utf-8" - else: - encoding = locale.getpreferredencoding(False) + encoding = self._get_locale_encoding() if not isinstance(encoding, str): raise ValueError("invalid encoding: %r" % encoding) @@ -2164,6 +2141,8 @@ class TextIOWrapper(TextIOBase): else: if not isinstance(encoding, str): raise TypeError("invalid encoding: %r" % encoding) + if encoding == "locale": + encoding = self._get_locale_encoding() if newline is Ellipsis: newline = self._readnl @@ -2268,6 +2247,15 @@ class TextIOWrapper(TextIOBase): self._decoded_chars_used += len(chars) return chars + def _get_locale_encoding(self): + try: + import locale + except ImportError: + # Importing locale may fail if Python is being built + return "utf-8" + else: + return locale.getencoding() + def _rewind_decoded_chars(self, n): """Rewind the _decoded_chars buffer.""" if self._decoded_chars_used < n: diff --git a/Lib/_pylong.py b/Lib/_pylong.py new file mode 100644 index 00000000000..d14c1d93836 --- /dev/null +++ b/Lib/_pylong.py @@ -0,0 +1,286 @@ +"""Python implementations of some algorithms for use by longobject.c. +The goal is to provide asymptotically faster algorithms that can be +used for operations on integers with many digits. In those cases, the +performance overhead of the Python implementation is not significant +since the asymptotic behavior is what dominates runtime. Functions +provided by this module should be considered private and not part of any +public API. + +Note: for ease of maintainability, please prefer clear code and avoid +"micro-optimizations". This module will only be imported and used for +integers with a huge number of digits. Saving a few microseconds with +tricky or non-obvious code is not worth it. For people looking for +maximum performance, they should use something like gmpy2.""" + +import sys +import re +import decimal + + +def int_to_decimal(n): + """Asymptotically fast conversion of an 'int' to Decimal.""" + + # Function due to Tim Peters. See GH issue #90716 for details. + # https://github.com/python/cpython/issues/90716 + # + # The implementation in longobject.c of base conversion algorithms + # between power-of-2 and non-power-of-2 bases are quadratic time. + # This function implements a divide-and-conquer algorithm that is + # faster for large numbers. Builds an equal decimal.Decimal in a + # "clever" recursive way. If we want a string representation, we + # apply str to _that_. + + D = decimal.Decimal + D2 = D(2) + + BITLIM = 128 + + mem = {} + + def w2pow(w): + """Return D(2)**w and store the result. Also possibly save some + intermediate results. In context, these are likely to be reused + across various levels of the conversion to Decimal.""" + if (result := mem.get(w)) is None: + if w <= BITLIM: + result = D2**w + elif w - 1 in mem: + result = (t := mem[w - 1]) + t + else: + w2 = w >> 1 + # If w happens to be odd, w-w2 is one larger then w2 + # now. Recurse on the smaller first (w2), so that it's + # in the cache and the larger (w-w2) can be handled by + # the cheaper `w-1 in mem` branch instead. + result = w2pow(w2) * w2pow(w - w2) + mem[w] = result + return result + + def inner(n, w): + if w <= BITLIM: + return D(n) + w2 = w >> 1 + hi = n >> w2 + lo = n - (hi << w2) + return inner(lo, w2) + inner(hi, w - w2) * w2pow(w2) + + with decimal.localcontext() as ctx: + ctx.prec = decimal.MAX_PREC + ctx.Emax = decimal.MAX_EMAX + ctx.Emin = decimal.MIN_EMIN + ctx.traps[decimal.Inexact] = 1 + + if n < 0: + negate = True + n = -n + else: + negate = False + result = inner(n, n.bit_length()) + if negate: + result = -result + return result + + +def int_to_decimal_string(n): + """Asymptotically fast conversion of an 'int' to a decimal string.""" + return str(int_to_decimal(n)) + + +def _str_to_int_inner(s): + """Asymptotically fast conversion of a 'str' to an 'int'.""" + + # Function due to Bjorn Martinsson. See GH issue #90716 for details. + # https://github.com/python/cpython/issues/90716 + # + # The implementation in longobject.c of base conversion algorithms + # between power-of-2 and non-power-of-2 bases are quadratic time. + # This function implements a divide-and-conquer algorithm making use + # of Python's built in big int multiplication. Since Python uses the + # Karatsuba algorithm for multiplication, the time complexity + # of this function is O(len(s)**1.58). + + DIGLIM = 2048 + + mem = {} + + def w5pow(w): + """Return 5**w and store the result. + Also possibly save some intermediate results. In context, these + are likely to be reused across various levels of the conversion + to 'int'. + """ + if (result := mem.get(w)) is None: + if w <= DIGLIM: + result = 5**w + elif w - 1 in mem: + result = mem[w - 1] * 5 + else: + w2 = w >> 1 + # If w happens to be odd, w-w2 is one larger then w2 + # now. Recurse on the smaller first (w2), so that it's + # in the cache and the larger (w-w2) can be handled by + # the cheaper `w-1 in mem` branch instead. + result = w5pow(w2) * w5pow(w - w2) + mem[w] = result + return result + + def inner(a, b): + if b - a <= DIGLIM: + return int(s[a:b]) + mid = (a + b + 1) >> 1 + return inner(mid, b) + ((inner(a, mid) * w5pow(b - mid)) << (b - mid)) + + return inner(0, len(s)) + + +def int_from_string(s): + """Asymptotically fast version of PyLong_FromString(), conversion + of a string of decimal digits into an 'int'.""" + # PyLong_FromString() has already removed leading +/-, checked for invalid + # use of underscore characters, checked that string consists of only digits + # and underscores, and stripped leading whitespace. The input can still + # contain underscores and have trailing whitespace. + s = s.rstrip().replace('_', '') + return _str_to_int_inner(s) + + +def str_to_int(s): + """Asymptotically fast version of decimal string to 'int' conversion.""" + # FIXME: this doesn't support the full syntax that int() supports. + m = re.match(r'\s*([+-]?)([0-9_]+)\s*', s) + if not m: + raise ValueError('invalid literal for int() with base 10') + v = int_from_string(m.group(2)) + if m.group(1) == '-': + v = -v + return v + + +# Fast integer division, based on code from Mark Dickinson, fast_div.py +# GH-47701. Additional refinements and optimizations by Bjorn Martinsson. The +# algorithm is due to Burnikel and Ziegler, in their paper "Fast Recursive +# Division". + +_DIV_LIMIT = 4000 + + +def _div2n1n(a, b, n): + """Divide a 2n-bit nonnegative integer a by an n-bit positive integer + b, using a recursive divide-and-conquer algorithm. + + Inputs: + n is a positive integer + b is a positive integer with exactly n bits + a is a nonnegative integer such that a < 2**n * b + + Output: + (q, r) such that a = b*q+r and 0 <= r < b. + + """ + if a.bit_length() - n <= _DIV_LIMIT: + return divmod(a, b) + pad = n & 1 + if pad: + a <<= 1 + b <<= 1 + n += 1 + half_n = n >> 1 + mask = (1 << half_n) - 1 + b1, b2 = b >> half_n, b & mask + q1, r = _div3n2n(a >> n, (a >> half_n) & mask, b, b1, b2, half_n) + q2, r = _div3n2n(r, a & mask, b, b1, b2, half_n) + if pad: + r >>= 1 + return q1 << half_n | q2, r + + +def _div3n2n(a12, a3, b, b1, b2, n): + """Helper function for _div2n1n; not intended to be called directly.""" + if a12 >> n == b1: + q, r = (1 << n) - 1, a12 - (b1 << n) + b1 + else: + q, r = _div2n1n(a12, b1, n) + r = (r << n | a3) - q * b2 + while r < 0: + q -= 1 + r += b + return q, r + + +def _int2digits(a, n): + """Decompose non-negative int a into base 2**n + + Input: + a is a non-negative integer + + Output: + List of the digits of a in base 2**n in little-endian order, + meaning the most significant digit is last. The most + significant digit is guaranteed to be non-zero. + If a is 0 then the output is an empty list. + + """ + a_digits = [0] * ((a.bit_length() + n - 1) // n) + + def inner(x, L, R): + if L + 1 == R: + a_digits[L] = x + return + mid = (L + R) >> 1 + shift = (mid - L) * n + upper = x >> shift + lower = x ^ (upper << shift) + inner(lower, L, mid) + inner(upper, mid, R) + + if a: + inner(a, 0, len(a_digits)) + return a_digits + + +def _digits2int(digits, n): + """Combine base-2**n digits into an int. This function is the + inverse of `_int2digits`. For more details, see _int2digits. + """ + + def inner(L, R): + if L + 1 == R: + return digits[L] + mid = (L + R) >> 1 + shift = (mid - L) * n + return (inner(mid, R) << shift) + inner(L, mid) + + return inner(0, len(digits)) if digits else 0 + + +def _divmod_pos(a, b): + """Divide a non-negative integer a by a positive integer b, giving + quotient and remainder.""" + # Use grade-school algorithm in base 2**n, n = nbits(b) + n = b.bit_length() + a_digits = _int2digits(a, n) + + r = 0 + q_digits = [] + for a_digit in reversed(a_digits): + q_digit, r = _div2n1n((r << n) + a_digit, b, n) + q_digits.append(q_digit) + q_digits.reverse() + q = _digits2int(q_digits, n) + return q, r + + +def int_divmod(a, b): + """Asymptotically fast replacement for divmod, for 'int'. + Its time complexity is O(n**1.58), where n = #bits(a) + #bits(b). + """ + if b == 0: + raise ZeroDivisionError + elif b < 0: + q, r = int_divmod(-a, -b) + return q, -r + elif a < 0: + q, r = int_divmod(~a, b) + return ~q, b + ~r + else: + return _divmod_pos(a, b) diff --git a/Lib/_weakrefset.py b/Lib/_weakrefset.py index 2a27684324d..489eec714e0 100644 --- a/Lib/_weakrefset.py +++ b/Lib/_weakrefset.py @@ -80,8 +80,7 @@ class WeakSet: return wr in self.data def __reduce__(self): - return (self.__class__, (list(self),), - getattr(self, '__dict__', None)) + return self.__class__, (list(self),), self.__getstate__() def add(self, item): if self._pending_removals: diff --git a/Lib/abc.py b/Lib/abc.py index 3c552cebb42..42048ddb855 100644 --- a/Lib/abc.py +++ b/Lib/abc.py @@ -102,7 +102,7 @@ else: implementations defined by the registering ABC be callable (not even via super()). """ - def __new__(mcls, name, bases, namespace, **kwargs): + def __new__(mcls, name, bases, namespace, /, **kwargs): cls = super().__new__(mcls, name, bases, namespace, **kwargs) _abc_init(cls) return cls diff --git a/Lib/aifc.py b/Lib/aifc.py index d50f258e1ac..5254987e22b 100644 --- a/Lib/aifc.py +++ b/Lib/aifc.py @@ -140,6 +140,10 @@ import warnings __all__ = ["Error", "open"] + +warnings._deprecated(__name__, remove=(3, 13)) + + class Error(Exception): pass @@ -251,7 +255,9 @@ def _write_float(f, x): _write_ulong(f, himant) _write_ulong(f, lomant) -from chunk import Chunk +with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + from chunk import Chunk from collections import namedtuple _aifc_params = namedtuple('_aifc_params', @@ -447,15 +453,21 @@ class Aifc_read: # def _alaw2lin(self, data): - import audioop + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=DeprecationWarning) + import audioop return audioop.alaw2lin(data, 2) def _ulaw2lin(self, data): - import audioop + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=DeprecationWarning) + import audioop return audioop.ulaw2lin(data, 2) def _adpcm2lin(self, data): - import audioop + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=DeprecationWarning) + import audioop if not hasattr(self, '_adpcmstate'): # first time self._adpcmstate = None @@ -463,7 +475,9 @@ class Aifc_read: return data def _sowt2lin(self, data): - import audioop + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=DeprecationWarning) + import audioop return audioop.byteswap(data, 2) def _read_comm_chunk(self, chunk): @@ -770,22 +784,30 @@ class Aifc_write: # def _lin2alaw(self, data): - import audioop + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=DeprecationWarning) + import audioop return audioop.lin2alaw(data, 2) def _lin2ulaw(self, data): - import audioop + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=DeprecationWarning) + import audioop return audioop.lin2ulaw(data, 2) def _lin2adpcm(self, data): - import audioop + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=DeprecationWarning) + import audioop if not hasattr(self, '_adpcmstate'): self._adpcmstate = None data, self._adpcmstate = audioop.lin2adpcm(data, 2, self._adpcmstate) return data def _lin2sowt(self, data): - import audioop + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=DeprecationWarning) + import audioop return audioop.byteswap(data, 2) def _ensure_header_written(self, datasize): diff --git a/Lib/argparse.py b/Lib/argparse.py index b44fa4f0f65..240625ff010 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -89,6 +89,8 @@ import os as _os import re as _re import sys as _sys +import warnings + from gettext import gettext as _, ngettext SUPPRESS = '==SUPPRESS==' @@ -151,6 +153,7 @@ def _copy_items(items): # Formatting Help # =============== + class HelpFormatter(object): """Formatter for generating usage messages and argument help strings. @@ -392,6 +395,9 @@ class HelpFormatter(object): group_actions = set() inserts = {} for group in groups: + if not group._group_actions: + raise ValueError(f'empty group {group}') + try: start = actions.index(group._group_actions[0]) except ValueError: @@ -690,8 +696,19 @@ class ArgumentDefaultsHelpFormatter(HelpFormatter): """ def _get_help_string(self, action): + """ + Add the default value to the option help message. + + ArgumentDefaultsHelpFormatter and BooleanOptionalAction when it isn't + already present. This code will do that, detecting cornercases to + prevent duplicates or cases where it wouldn't make sense to the end + user. + """ help = action.help - if '%(default)' not in action.help: + if help is None: + help = '' + + if '%(default)' not in help: if action.default is not SUPPRESS: defaulting_nargs = [OPTIONAL, ZERO_OR_MORE] if action.option_strings or action.nargs in defaulting_nargs: @@ -699,6 +716,7 @@ class ArgumentDefaultsHelpFormatter(HelpFormatter): return help + class MetavarTypeHelpFormatter(HelpFormatter): """Help message formatter which uses the argument 'type' as the default metavar value (instead of the argument 'dest') @@ -714,7 +732,6 @@ class MetavarTypeHelpFormatter(HelpFormatter): return action.type.__name__ - # ===================== # Options and Arguments # ===================== @@ -723,7 +740,7 @@ def _get_action_name(argument): if argument is None: return None elif argument.option_strings: - return '/'.join(argument.option_strings) + return '/'.join(argument.option_strings) elif argument.metavar not in (None, SUPPRESS): return argument.metavar elif argument.dest not in (None, SUPPRESS): @@ -749,7 +766,7 @@ class ArgumentError(Exception): if self.argument_name is None: format = '%(message)s' else: - format = 'argument %(argument_name)s: %(message)s' + format = _('argument %(argument_name)s: %(message)s') return format % dict(message=self.message, argument_name=self.argument_name) @@ -845,6 +862,7 @@ class Action(_AttributeHolder): 'default', 'type', 'choices', + 'required', 'help', 'metavar', ] @@ -876,9 +894,6 @@ class BooleanOptionalAction(Action): option_string = '--no-' + option_string[2:] _option_strings.append(option_string) - if help is not None and default is not None: - help += " (default: %(default)s)" - super().__init__( option_strings=_option_strings, dest=dest, @@ -890,6 +905,7 @@ class BooleanOptionalAction(Action): help=help, metavar=metavar) + def __call__(self, parser, namespace, values, option_string=None): if option_string in self.option_strings: setattr(namespace, self.dest, not option_string.startswith('--no-')) @@ -1165,6 +1181,13 @@ class _SubParsersAction(Action): aliases = kwargs.pop('aliases', ()) + if name in self._name_parser_map: + raise ArgumentError(self, _('conflicting subparser: %s') % name) + for alias in aliases: + if alias in self._name_parser_map: + raise ArgumentError( + self, _('conflicting subparser alias: %s') % alias) + # create a pseudo-action to hold the choice help if 'help' in kwargs: help = kwargs.pop('help') @@ -1254,9 +1277,9 @@ class FileType(object): # the special argument "-" means sys.std{in,out} if string == '-': if 'r' in self._mode: - return _sys.stdin - elif 'w' in self._mode: - return _sys.stdout + return _sys.stdin.buffer if 'b' in self._mode else _sys.stdin + elif any(c in self._mode for c in 'wax'): + return _sys.stdout.buffer if 'b' in self._mode else _sys.stdout else: msg = _('argument "-" with mode %r') % self._mode raise ValueError(msg) @@ -1645,6 +1668,14 @@ class _ArgumentGroup(_ActionsContainer): super(_ArgumentGroup, self)._remove_action(action) self._group_actions.remove(action) + def add_argument_group(self, *args, **kwargs): + warnings.warn( + "Nesting argument groups is deprecated.", + category=DeprecationWarning, + stacklevel=2 + ) + return super().add_argument_group(*args, **kwargs) + class _MutuallyExclusiveGroup(_ArgumentGroup): @@ -1665,12 +1696,21 @@ class _MutuallyExclusiveGroup(_ArgumentGroup): self._container._remove_action(action) self._group_actions.remove(action) + def add_mutually_exclusive_group(self, *args, **kwargs): + warnings.warn( + "Nesting mutually exclusive groups is deprecated.", + category=DeprecationWarning, + stacklevel=2 + ) + return super().add_mutually_exclusive_group(*args, **kwargs) + class ArgumentParser(_AttributeHolder, _ActionsContainer): """Object for parsing command line strings into Python objects. Keyword Arguments: - - prog -- The name of the program (default: sys.argv[0]) + - prog -- The name of the program (default: + ``os.path.basename(sys.argv[0])``) - usage -- A usage message (default: auto-generated from arguments) - description -- A description of what the program does - epilog -- Text following the argument descriptions @@ -1853,8 +1893,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): if self.exit_on_error: try: namespace, args = self._parse_known_args(args, namespace) - except ArgumentError: - err = _sys.exc_info()[1] + except ArgumentError as err: self.error(str(err)) else: namespace, args = self._parse_known_args(args, namespace) @@ -1958,7 +1997,11 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): # arguments, try to parse more single-dash options out # of the tail of the option string chars = self.prefix_chars - if arg_count == 0 and option_string[1] not in chars: + if ( + arg_count == 0 + and option_string[1] not in chars + and explicit_arg != '' + ): action_tuples.append((action, [], option_string)) char = option_string[0] option_string = char + explicit_arg[0] @@ -2122,15 +2165,16 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): # replace arguments referencing files with the file content else: try: - with open(arg_string[1:]) as args_file: + with open(arg_string[1:], + encoding=_sys.getfilesystemencoding(), + errors=_sys.getfilesystemencodeerrors()) as args_file: arg_strings = [] for arg_line in args_file.read().splitlines(): for arg in self.convert_arg_line_to_args(arg_line): arg_strings.append(arg) arg_strings = self._read_args_from_files(arg_strings) new_arg_strings.extend(arg_strings) - except OSError: - err = _sys.exc_info()[1] + except OSError as err: self.error(str(err)) # return the modified argument list @@ -2437,9 +2481,11 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): not action.option_strings): if action.default is not None: value = action.default + self._check_value(action, value) else: + # since arg_strings is always [] at this point + # there is no need to use self._check_value(action, value) value = arg_strings - self._check_value(action, value) # single argument or optional argument produces a single value elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]: @@ -2480,9 +2526,8 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): result = type_func(arg_string) # ArgumentTypeErrors indicate errors - except ArgumentTypeError: - name = getattr(action.type, '__name__', repr(action.type)) - msg = str(_sys.exc_info()[1]) + except ArgumentTypeError as err: + msg = str(err) raise ArgumentError(action, msg) # TypeErrors or ValueErrors also indicate errors diff --git a/Lib/ast.py b/Lib/ast.py index 400d7c45146..2cbc80a9835 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -40,12 +40,13 @@ def parse(source, filename='', mode='exec', *, flags = PyCF_ONLY_AST if type_comments: flags |= PyCF_TYPE_COMMENTS - if isinstance(feature_version, tuple): - major, minor = feature_version # Should be a 2-tuple. - assert major == 3 - feature_version = minor - elif feature_version is None: + if feature_version is None: feature_version = -1 + elif isinstance(feature_version, tuple): + major, minor = feature_version # Should be a 2-tuple. + if major != 3: + raise ValueError(f"Unsupported major version: {major}") + feature_version = minor # Else it should be an int giving the minor version for 3.x. return compile(source, filename, mode, flags, _feature_version=feature_version) @@ -53,10 +54,12 @@ def parse(source, filename='', mode='exec', *, def literal_eval(node_or_string): """ - Safely evaluate an expression node or a string containing a Python + Evaluate an expression node or a string containing only a Python expression. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, and None. + + Caution: A complex expression can overflow the C stack and cause a crash. """ if isinstance(node_or_string, str): node_or_string = parse(node_or_string.lstrip(" \t"), mode='eval') @@ -234,6 +237,12 @@ def increment_lineno(node, n=1): location in a file. """ for child in walk(node): + # TypeIgnore is a special case where lineno is not an attribute + # but rather a field of the node itself. + if isinstance(child, TypeIgnore): + child.lineno = getattr(child, 'lineno', 0) + n + continue + if 'lineno' in child._attributes: child.lineno = getattr(child, 'lineno', 0) + n if ( @@ -683,6 +692,7 @@ class _Unparser(NodeVisitor): self._type_ignores = {} self._indent = 0 self._avoid_backslashes = _avoid_backslashes + self._in_try_star = False def interleave(self, inter, f, seq): """Call f on each item in seq, calling inter() in between.""" @@ -851,7 +861,7 @@ class _Unparser(NodeVisitor): def visit_ImportFrom(self, node): self.fill("from ") - self.write("." * node.level) + self.write("." * (node.level or 0)) if node.module: self.write(node.module) self.write(" import ") @@ -953,7 +963,7 @@ class _Unparser(NodeVisitor): self.write(" from ") self.traverse(node.cause) - def visit_Try(self, node): + def do_visit_try(self, node): self.fill("try") with self.block(): self.traverse(node.body) @@ -968,8 +978,24 @@ class _Unparser(NodeVisitor): with self.block(): self.traverse(node.finalbody) + def visit_Try(self, node): + prev_in_try_star = self._in_try_star + try: + self._in_try_star = False + self.do_visit_try(node) + finally: + self._in_try_star = prev_in_try_star + + def visit_TryStar(self, node): + prev_in_try_star = self._in_try_star + try: + self._in_try_star = True + self.do_visit_try(node) + finally: + self._in_try_star = prev_in_try_star + def visit_ExceptHandler(self, node): - self.fill("except") + self.fill("except*" if self._in_try_star else "except") if node.type: self.write(" ") self.traverse(node.type) @@ -1318,7 +1344,11 @@ class _Unparser(NodeVisitor): ) def visit_Tuple(self, node): - with self.require_parens(_Precedence.TUPLE, node): + with self.delimit_if( + "(", + ")", + len(node.elts) == 0 or self.get_precedence(node) > _Precedence.TUPLE + ): self.items_view(self.traverse, node.elts) unop = {"Invert": "~", "Not": "not", "UAdd": "+", "USub": "-"} @@ -1459,20 +1489,17 @@ class _Unparser(NodeVisitor): self.traverse(e) def visit_Subscript(self, node): - def is_simple_tuple(slice_value): - # when unparsing a non-empty tuple, the parentheses can be safely - # omitted if there aren't any elements that explicitly requires - # parentheses (such as starred expressions). + def is_non_empty_tuple(slice_value): return ( isinstance(slice_value, Tuple) and slice_value.elts - and not any(isinstance(elt, Starred) for elt in slice_value.elts) ) self.set_precedence(_Precedence.ATOM, node.value) self.traverse(node.value) with self.delimit("[", "]"): - if is_simple_tuple(node.slice): + if is_non_empty_tuple(node.slice): + # parentheses can be omitted if the tuple isn't empty self.items_view(self.traverse, node.slice.elts) else: self.traverse(node.slice) diff --git a/Lib/asyncio/__init__.py b/Lib/asyncio/__init__.py index 200b14c2a3f..fed16ec7c67 100644 --- a/Lib/asyncio/__init__.py +++ b/Lib/asyncio/__init__.py @@ -17,6 +17,8 @@ from .queues import * from .streams import * from .subprocess import * from .tasks import * +from .taskgroups import * +from .timeouts import * from .threads import * from .transports import * @@ -33,6 +35,7 @@ __all__ = (base_events.__all__ + subprocess.__all__ + tasks.__all__ + threads.__all__ + + timeouts.__all__ + transports.__all__) if sys.platform == 'win32': # pragma: no cover diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 054d7b45ec2..32d7e1c481e 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -49,7 +49,7 @@ from . import trsock from .log import logger -__all__ = 'BaseEventLoop', +__all__ = 'BaseEventLoop','Server', # Minimum number of _scheduled timer handles before cleanup of @@ -198,6 +198,11 @@ else: pass +def _check_ssl_socket(sock): + if ssl is not None and isinstance(sock, ssl.SSLSocket): + raise TypeError("Socket cannot be of type SSLSocket") + + class _SendfileFallbackProtocol(protocols.Protocol): def __init__(self, transp): if not isinstance(transp, transports._FlowControlMixin): @@ -269,7 +274,7 @@ class _SendfileFallbackProtocol(protocols.Protocol): class Server(events.AbstractServer): def __init__(self, loop, sockets, protocol_factory, ssl_context, backlog, - ssl_handshake_timeout): + ssl_handshake_timeout, ssl_shutdown_timeout=None): self._loop = loop self._sockets = sockets self._active_count = 0 @@ -278,6 +283,7 @@ class Server(events.AbstractServer): self._backlog = backlog self._ssl_context = ssl_context self._ssl_handshake_timeout = ssl_handshake_timeout + self._ssl_shutdown_timeout = ssl_shutdown_timeout self._serving = False self._serving_forever_fut = None @@ -309,7 +315,8 @@ class Server(events.AbstractServer): sock.listen(self._backlog) self._loop._start_serving( self._protocol_factory, sock, self._ssl_context, - self, self._backlog, self._ssl_handshake_timeout) + self, self._backlog, self._ssl_handshake_timeout, + self._ssl_shutdown_timeout) def get_loop(self): return self._loop @@ -370,7 +377,7 @@ class Server(events.AbstractServer): self._serving_forever_fut = None async def wait_closed(self): - if self._sockets is None or self._waiters is None: + if self._waiters is None or self._active_count == 0: return waiter = self._loop.create_future() self._waiters.append(waiter) @@ -419,18 +426,23 @@ class BaseEventLoop(events.AbstractEventLoop): """Create a Future object attached to the loop.""" return futures.Future(loop=self) - def create_task(self, coro, *, name=None): + def create_task(self, coro, *, name=None, context=None): """Schedule a coroutine object. Return a task object. """ self._check_closed() if self._task_factory is None: - task = tasks.Task(coro, loop=self, name=name) + task = tasks.Task(coro, loop=self, name=name, context=context) if task._source_traceback: del task._source_traceback[-1] else: - task = self._task_factory(self, coro) + if context is None: + # Use legacy API if context is not needed + task = self._task_factory(self, coro) + else: + task = self._task_factory(self, coro, context=context) + tasks._set_task_name(task, name) return task @@ -463,6 +475,7 @@ class BaseEventLoop(events.AbstractEventLoop): *, server_side=False, server_hostname=None, extra=None, server=None, ssl_handshake_timeout=None, + ssl_shutdown_timeout=None, call_connection_made=True): """Create SSL transport.""" raise NotImplementedError @@ -548,8 +561,13 @@ class BaseEventLoop(events.AbstractEventLoop): 'asyncgen': agen }) - async def shutdown_default_executor(self): - """Schedule the shutdown of the default executor.""" + async def shutdown_default_executor(self, timeout=None): + """Schedule the shutdown of the default executor. + + The timeout parameter specifies the amount of time the executor will + be given to finish joining. The default value is None, which means + that the executor will be given an unlimited amount of time. + """ self._executor_shutdown_called = True if self._default_executor is None: return @@ -559,14 +577,22 @@ class BaseEventLoop(events.AbstractEventLoop): try: await future finally: - thread.join() + thread.join(timeout) + + if thread.is_alive(): + warnings.warn("The executor did not finishing joining " + f"its threads within {timeout} seconds.", + RuntimeWarning, stacklevel=2) + self._default_executor.shutdown(wait=False) def _do_shutdown(self, future): try: self._default_executor.shutdown(wait=True) - self.call_soon_threadsafe(future.set_result, None) + if not self.is_closed(): + self.call_soon_threadsafe(future.set_result, None) except Exception as ex: - self.call_soon_threadsafe(future.set_exception, ex) + if not self.is_closed(): + self.call_soon_threadsafe(future.set_exception, ex) def _check_running(self): if self.is_running(): @@ -580,12 +606,13 @@ class BaseEventLoop(events.AbstractEventLoop): self._check_closed() self._check_running() self._set_coroutine_origin_tracking(self._debug) - self._thread_id = threading.get_ident() old_agen_hooks = sys.get_asyncgen_hooks() - sys.set_asyncgen_hooks(firstiter=self._asyncgen_firstiter_hook, - finalizer=self._asyncgen_finalizer_hook) try: + self._thread_id = threading.get_ident() + sys.set_asyncgen_hooks(firstiter=self._asyncgen_firstiter_hook, + finalizer=self._asyncgen_finalizer_hook) + events._set_running_loop(self) while True: self._run_once() @@ -706,6 +733,8 @@ class BaseEventLoop(events.AbstractEventLoop): Any positional arguments after the callback will be passed to the callback when it is called. """ + if delay is None: + raise TypeError('delay must not be None') timer = self.call_at(self.time() + delay, callback, *args, context=context) if timer._source_traceback: @@ -717,6 +746,8 @@ class BaseEventLoop(events.AbstractEventLoop): Absolute time corresponds to the event loop's time() method. """ + if when is None: + raise TypeError("when cannot be None") self._check_closed() if self._debug: self._check_thread() @@ -855,6 +886,7 @@ class BaseEventLoop(events.AbstractEventLoop): *, fallback=True): if self._debug and sock.gettimeout() != 0: raise ValueError("the socket must be non-blocking") + _check_ssl_socket(sock) self._check_sendfile_params(sock, file, offset, count) try: return await self._sock_sendfile_native(sock, file, @@ -870,7 +902,7 @@ class BaseEventLoop(events.AbstractEventLoop): # non-mmap files even if sendfile is supported by OS raise exceptions.SendfileNotAvailableError( f"syscall sendfile is not available for socket {sock!r} " - "and file {file!r} combination") + f"and file {file!r} combination") async def _sock_sendfile_fallback(self, sock, file, offset, count): if offset: @@ -929,7 +961,10 @@ class BaseEventLoop(events.AbstractEventLoop): sock = socket.socket(family=family, type=type_, proto=proto) sock.setblocking(False) if local_addr_infos is not None: - for _, _, _, _, laddr in local_addr_infos: + for lfamily, _, _, _, laddr in local_addr_infos: + # skip local addresses of different family + if lfamily != family: + continue try: sock.bind(laddr) break @@ -942,7 +977,10 @@ class BaseEventLoop(events.AbstractEventLoop): exc = OSError(exc.errno, msg) my_exceptions.append(exc) else: # all bind attempts failed - raise my_exceptions.pop() + if my_exceptions: + raise my_exceptions.pop() + else: + raise OSError(f"no matching local address with {family=} found") await self.sock_connect(sock, address) return sock except OSError as exc: @@ -954,6 +992,8 @@ class BaseEventLoop(events.AbstractEventLoop): if sock is not None: sock.close() raise + finally: + exceptions = my_exceptions = None async def create_connection( self, protocol_factory, host=None, port=None, @@ -961,7 +1001,9 @@ class BaseEventLoop(events.AbstractEventLoop): proto=0, flags=0, sock=None, local_addr=None, server_hostname=None, ssl_handshake_timeout=None, - happy_eyeballs_delay=None, interleave=None): + ssl_shutdown_timeout=None, + happy_eyeballs_delay=None, interleave=None, + all_errors=False): """Connect to a TCP server. Create a streaming transport connection to a given internet host and @@ -996,6 +1038,13 @@ class BaseEventLoop(events.AbstractEventLoop): raise ValueError( 'ssl_handshake_timeout is only meaningful with ssl') + if ssl_shutdown_timeout is not None and not ssl: + raise ValueError( + 'ssl_shutdown_timeout is only meaningful with ssl') + + if sock is not None: + _check_ssl_socket(sock) + if happy_eyeballs_delay is not None and interleave is None: # If using happy eyeballs, default to interleave addresses by family interleave = 1 @@ -1043,17 +1092,22 @@ class BaseEventLoop(events.AbstractEventLoop): if sock is None: exceptions = [exc for sub in exceptions for exc in sub] - if len(exceptions) == 1: - raise exceptions[0] - else: - # If they all have the same str(), raise one. - model = str(exceptions[0]) - if all(str(exc) == model for exc in exceptions): + try: + if all_errors: + raise ExceptionGroup("create_connection failed", exceptions) + if len(exceptions) == 1: raise exceptions[0] - # Raise a combined exception so the user can see all - # the various error messages. - raise OSError('Multiple exceptions: {}'.format( - ', '.join(str(exc) for exc in exceptions))) + else: + # If they all have the same str(), raise one. + model = str(exceptions[0]) + if all(str(exc) == model for exc in exceptions): + raise exceptions[0] + # Raise a combined exception so the user can see all + # the various error messages. + raise OSError('Multiple exceptions: {}'.format( + ', '.join(str(exc) for exc in exceptions))) + finally: + exceptions = None else: if sock is None: @@ -1071,7 +1125,8 @@ class BaseEventLoop(events.AbstractEventLoop): transport, protocol = await self._create_connection_transport( sock, protocol_factory, ssl, server_hostname, - ssl_handshake_timeout=ssl_handshake_timeout) + ssl_handshake_timeout=ssl_handshake_timeout, + ssl_shutdown_timeout=ssl_shutdown_timeout) if self._debug: # Get the socket from the transport because SSL transport closes # the old socket and creates a new SSL socket @@ -1083,7 +1138,8 @@ class BaseEventLoop(events.AbstractEventLoop): async def _create_connection_transport( self, sock, protocol_factory, ssl, server_hostname, server_side=False, - ssl_handshake_timeout=None): + ssl_handshake_timeout=None, + ssl_shutdown_timeout=None): sock.setblocking(False) @@ -1094,7 +1150,8 @@ class BaseEventLoop(events.AbstractEventLoop): transport = self._make_ssl_transport( sock, protocol, sslcontext, waiter, server_side=server_side, server_hostname=server_hostname, - ssl_handshake_timeout=ssl_handshake_timeout) + ssl_handshake_timeout=ssl_handshake_timeout, + ssl_shutdown_timeout=ssl_shutdown_timeout) else: transport = self._make_socket_transport(sock, protocol, waiter) @@ -1185,7 +1242,8 @@ class BaseEventLoop(events.AbstractEventLoop): async def start_tls(self, transport, protocol, sslcontext, *, server_side=False, server_hostname=None, - ssl_handshake_timeout=None): + ssl_handshake_timeout=None, + ssl_shutdown_timeout=None): """Upgrade transport to TLS. Return a new transport that *protocol* should start using @@ -1208,6 +1266,7 @@ class BaseEventLoop(events.AbstractEventLoop): self, protocol, sslcontext, waiter, server_side, server_hostname, ssl_handshake_timeout=ssl_handshake_timeout, + ssl_shutdown_timeout=ssl_shutdown_timeout, call_connection_made=False) # Pause early so that "ssl_protocol.data_received()" doesn't @@ -1281,8 +1340,8 @@ class BaseEventLoop(events.AbstractEventLoop): addr_infos = {} # Using order preserving dict for idx, addr in ((0, local_addr), (1, remote_addr)): if addr is not None: - assert isinstance(addr, tuple) and len(addr) == 2, ( - '2-tuple is expected') + if not (isinstance(addr, tuple) and len(addr) == 2): + raise TypeError('2-tuple is expected') infos = await self._ensure_resolved( addr, family=family, type=socket.SOCK_DGRAM, @@ -1390,8 +1449,10 @@ class BaseEventLoop(events.AbstractEventLoop): sock=None, backlog=100, ssl=None, + reuse_address=None, reuse_port=None, ssl_handshake_timeout=None, + ssl_shutdown_timeout=None, start_serving=True): """Create a TCP server. @@ -1415,11 +1476,20 @@ class BaseEventLoop(events.AbstractEventLoop): raise ValueError( 'ssl_handshake_timeout is only meaningful with ssl') + if ssl_shutdown_timeout is not None and ssl is None: + raise ValueError( + 'ssl_shutdown_timeout is only meaningful with ssl') + + if sock is not None: + _check_ssl_socket(sock) + if host is not None or port is not None: if sock is not None: raise ValueError( 'host/port and sock can not be specified at the same time') + if reuse_address is None: + reuse_address = os.name == "posix" and sys.platform != "cygwin" sockets = [] if host == '': hosts = [None] @@ -1449,6 +1519,9 @@ class BaseEventLoop(events.AbstractEventLoop): af, socktype, proto, exc_info=True) continue sockets.append(sock) + if reuse_address: + sock.setsockopt( + socket.SOL_SOCKET, socket.SO_REUSEADDR, True) if reuse_port: _set_reuseport(sock) # Disable IPv4/IPv6 dual stack support (enabled by @@ -1482,7 +1555,8 @@ class BaseEventLoop(events.AbstractEventLoop): sock.setblocking(False) server = Server(self, sockets, protocol_factory, - ssl, backlog, ssl_handshake_timeout) + ssl, backlog, ssl_handshake_timeout, + ssl_shutdown_timeout) if start_serving: server._start_serving() # Skip one loop iteration so that all 'loop.add_reader' @@ -1496,7 +1570,8 @@ class BaseEventLoop(events.AbstractEventLoop): async def connect_accepted_socket( self, protocol_factory, sock, *, ssl=None, - ssl_handshake_timeout=None): + ssl_handshake_timeout=None, + ssl_shutdown_timeout=None): if sock.type != socket.SOCK_STREAM: raise ValueError(f'A Stream Socket was expected, got {sock!r}') @@ -1504,9 +1579,17 @@ class BaseEventLoop(events.AbstractEventLoop): raise ValueError( 'ssl_handshake_timeout is only meaningful with ssl') + if ssl_shutdown_timeout is not None and not ssl: + raise ValueError( + 'ssl_shutdown_timeout is only meaningful with ssl') + + if sock is not None: + _check_ssl_socket(sock) + transport, protocol = await self._create_connection_transport( sock, protocol_factory, ssl, '', server_side=True, - ssl_handshake_timeout=ssl_handshake_timeout) + ssl_handshake_timeout=ssl_handshake_timeout, + ssl_shutdown_timeout=ssl_shutdown_timeout) if self._debug: # Get the socket from the transport because SSL transport closes # the old socket and creates a new SSL socket @@ -1736,7 +1819,22 @@ class BaseEventLoop(events.AbstractEventLoop): exc_info=True) else: try: - self._exception_handler(self, context) + ctx = None + thing = context.get("task") + if thing is None: + # Even though Futures don't have a context, + # Task is a subclass of Future, + # and sometimes the 'future' key holds a Task. + thing = context.get("future") + if thing is None: + # Handles also have a context. + thing = context.get("handle") + if thing is not None and hasattr(thing, "get_context"): + ctx = thing.get_context() + if ctx is not None and hasattr(ctx, "run"): + ctx.run(self._exception_handler, self, context) + else: + self._exception_handler(self, context) except (SystemExit, KeyboardInterrupt): raise except BaseException as exc: @@ -1759,12 +1857,9 @@ class BaseEventLoop(events.AbstractEventLoop): exc_info=True) def _add_callback(self, handle): - """Add a Handle to _scheduled (TimerHandle) or _ready.""" - assert isinstance(handle, events.Handle), 'A Handle is required here' - if handle._cancelled: - return - assert not isinstance(handle, events.TimerHandle) - self._ready.append(handle) + """Add a Handle to _ready.""" + if not handle._cancelled: + self._ready.append(handle) def _add_callback_signalsafe(self, handle): """Like _add_callback() but called from a signal handler.""" @@ -1817,6 +1912,8 @@ class BaseEventLoop(events.AbstractEventLoop): event_list = self._selector.select(timeout) self._process_events(event_list) + # Needed to break cycles when an exception occurs. + event_list = None # Handle 'later' callbacks that are ready. end_time = self.time() + self._clock_resolution diff --git a/Lib/asyncio/base_futures.py b/Lib/asyncio/base_futures.py index 2c01ac98e10..7987963bd99 100644 --- a/Lib/asyncio/base_futures.py +++ b/Lib/asyncio/base_futures.py @@ -1,7 +1,6 @@ __all__ = () import reprlib -from _thread import get_ident from . import format_helpers @@ -42,16 +41,6 @@ def _format_callbacks(cb): return f'cb=[{cb}]' -# bpo-42183: _repr_running is needed for repr protection -# when a Future or Task result contains itself directly or indirectly. -# The logic is borrowed from @reprlib.recursive_repr decorator. -# Unfortunately, the direct decorator usage is impossible because of -# AttributeError: '_asyncio.Task' object has no attribute '__module__' error. -# -# After fixing this thing we can return to the decorator based approach. -_repr_running = set() - - def _future_repr_info(future): # (Future) -> str """helper function for Future.__repr__""" @@ -60,17 +49,9 @@ def _future_repr_info(future): if future._exception is not None: info.append(f'exception={future._exception!r}') else: - key = id(future), get_ident() - if key in _repr_running: - result = '...' - else: - _repr_running.add(key) - try: - # use reprlib to limit the length of the output, especially - # for very long strings - result = reprlib.repr(future._result) - finally: - _repr_running.discard(key) + # use reprlib to limit the length of the output, especially + # for very long strings + result = reprlib.repr(future._result) info.append(f'result={result}') if future._callbacks: info.append(_format_callbacks(future._callbacks)) @@ -78,3 +59,9 @@ def _future_repr_info(future): frame = future._source_traceback[-1] info.append(f'created at {frame[0]}:{frame[1]}') return info + + +@reprlib.recursive_repr() +def _future_repr(future): + info = ' '.join(_future_repr_info(future)) + return f'<{future.__class__.__name__} {info}>' diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py index 14d50519228..4c9b0dd5653 100644 --- a/Lib/asyncio/base_subprocess.py +++ b/Lib/asyncio/base_subprocess.py @@ -215,13 +215,8 @@ class BaseSubprocessTransport(transports.SubprocessTransport): # object. On Python 3.6, it is required to avoid a ResourceWarning. self._proc.returncode = returncode self._call(self._protocol.process_exited) - self._try_finish() - # wake up futures waiting for wait() - for waiter in self._exit_waiters: - if not waiter.cancelled(): - waiter.set_result(returncode) - self._exit_waiters = None + self._try_finish() async def _wait(self): """Wait until the process exit and return the process return code. @@ -247,6 +242,11 @@ class BaseSubprocessTransport(transports.SubprocessTransport): try: self._protocol.connection_lost(exc) finally: + # wake up futures waiting for wait() + for waiter in self._exit_waiters: + if not waiter.cancelled(): + waiter.set_result(self._returncode) + self._exit_waiters = None self._loop = None self._proc = None self._protocol = None diff --git a/Lib/asyncio/base_tasks.py b/Lib/asyncio/base_tasks.py index 09bb171a2ce..26298e638cb 100644 --- a/Lib/asyncio/base_tasks.py +++ b/Lib/asyncio/base_tasks.py @@ -1,4 +1,5 @@ import linecache +import reprlib import traceback from . import base_futures @@ -8,7 +9,7 @@ from . import coroutines def _task_repr_info(task): info = base_futures._future_repr_info(task) - if task._must_cancel: + if task.cancelling() and not task.done(): # replace status info[0] = 'cancelling' @@ -22,6 +23,12 @@ def _task_repr_info(task): return info +@reprlib.recursive_repr() +def _task_repr(task): + info = ' '.join(_task_repr_info(task)) + return f'<{task.__class__.__name__} {info}>' + + def _task_get_stack(task, limit): frames = [] if hasattr(task._coro, 'cr_frame'): diff --git a/Lib/asyncio/constants.py b/Lib/asyncio/constants.py index 33feed60e55..f0ce0433a7a 100644 --- a/Lib/asyncio/constants.py +++ b/Lib/asyncio/constants.py @@ -15,10 +15,20 @@ DEBUG_STACK_DEPTH = 10 # The default timeout matches that of Nginx. SSL_HANDSHAKE_TIMEOUT = 60.0 +# Number of seconds to wait for SSL shutdown to complete +# The default timeout mimics lingering_time +SSL_SHUTDOWN_TIMEOUT = 30.0 + # Used in sendfile fallback code. We use fallback for platforms # that don't support sendfile, or for TLS connections. SENDFILE_FALLBACK_READBUFFER_SIZE = 1024 * 256 +FLOW_CONTROL_HIGH_WATER_SSL_READ = 256 # KiB +FLOW_CONTROL_HIGH_WATER_SSL_WRITE = 512 # KiB + +# Default timeout for joining the threads in the threadpool +THREAD_JOIN_TIMEOUT = 300 + # The enum should be here to break circular dependencies between # base_events and sslproto class _SendfileMode(enum.Enum): diff --git a/Lib/asyncio/coroutines.py b/Lib/asyncio/coroutines.py index 0e4b489f30f..7fda0e449d5 100644 --- a/Lib/asyncio/coroutines.py +++ b/Lib/asyncio/coroutines.py @@ -4,7 +4,6 @@ import collections.abc import inspect import os import sys -import traceback import types diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index 7abaaca2d2b..ce44942186b 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -13,6 +13,7 @@ __all__ = ( import contextvars import os +import signal import socket import subprocess import sys @@ -61,6 +62,9 @@ class Handle: info = self._repr_info() return '<{}>'.format(' '.join(info)) + def get_context(self): + return self._context + def cancel(self): if not self._cancelled: self._cancelled = True @@ -101,7 +105,6 @@ class TimerHandle(Handle): __slots__ = ['_scheduled', '_when'] def __init__(self, when, callback, args, loop, context=None): - assert when is not None super().__init__(callback, args, loop, context) if self._source_traceback: del self._source_traceback[-1] @@ -258,13 +261,13 @@ class AbstractEventLoop: """Notification that a TimerHandle has been cancelled.""" raise NotImplementedError - def call_soon(self, callback, *args): - return self.call_later(0, callback, *args) + def call_soon(self, callback, *args, context=None): + return self.call_later(0, callback, *args, context=context) - def call_later(self, delay, callback, *args): + def call_later(self, delay, callback, *args, context=None): raise NotImplementedError - def call_at(self, when, callback, *args): + def call_at(self, when, callback, *args, context=None): raise NotImplementedError def time(self): @@ -275,12 +278,12 @@ class AbstractEventLoop: # Method scheduling a coroutine object: create a task. - def create_task(self, coro, *, name=None): + def create_task(self, coro, *, name=None, context=None): raise NotImplementedError # Methods for interacting with threads. - def call_soon_threadsafe(self, callback, *args): + def call_soon_threadsafe(self, callback, *args, context=None): raise NotImplementedError def run_in_executor(self, executor, func, *args): @@ -304,6 +307,7 @@ class AbstractEventLoop: flags=0, sock=None, local_addr=None, server_hostname=None, ssl_handshake_timeout=None, + ssl_shutdown_timeout=None, happy_eyeballs_delay=None, interleave=None): raise NotImplementedError @@ -313,6 +317,7 @@ class AbstractEventLoop: flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None, ssl_handshake_timeout=None, + ssl_shutdown_timeout=None, start_serving=True): """A coroutine which creates a TCP server bound to host and port. @@ -353,6 +358,10 @@ class AbstractEventLoop: will wait for completion of the SSL handshake before aborting the connection. Default is 60s. + ssl_shutdown_timeout is the time in seconds that an SSL server + will wait for completion of the SSL shutdown procedure + before aborting the connection. Default is 30s. + start_serving set to True (default) causes the created server to start accepting connections immediately. When set to False, the user should await Server.start_serving() or Server.serve_forever() @@ -371,7 +380,8 @@ class AbstractEventLoop: async def start_tls(self, transport, protocol, sslcontext, *, server_side=False, server_hostname=None, - ssl_handshake_timeout=None): + ssl_handshake_timeout=None, + ssl_shutdown_timeout=None): """Upgrade a transport to TLS. Return a new transport that *protocol* should start using @@ -383,13 +393,15 @@ class AbstractEventLoop: self, protocol_factory, path=None, *, ssl=None, sock=None, server_hostname=None, - ssl_handshake_timeout=None): + ssl_handshake_timeout=None, + ssl_shutdown_timeout=None): raise NotImplementedError async def create_unix_server( self, protocol_factory, path=None, *, sock=None, backlog=100, ssl=None, ssl_handshake_timeout=None, + ssl_shutdown_timeout=None, start_serving=True): """A coroutine which creates a UNIX Domain Socket server. @@ -411,6 +423,9 @@ class AbstractEventLoop: ssl_handshake_timeout is the time in seconds that an SSL server will wait for the SSL handshake to complete (defaults to 60s). + ssl_shutdown_timeout is the time in seconds that an SSL server + will wait for the SSL shutdown to finish (defaults to 30s). + start_serving set to True (default) causes the created server to start accepting connections immediately. When set to False, the user should await Server.start_serving() or Server.serve_forever() @@ -421,7 +436,8 @@ class AbstractEventLoop: async def connect_accepted_socket( self, protocol_factory, sock, *, ssl=None, - ssl_handshake_timeout=None): + ssl_handshake_timeout=None, + ssl_shutdown_timeout=None): """Handle an accepted connection. This is used by servers that accept connections outside of @@ -534,9 +550,18 @@ class AbstractEventLoop: async def sock_recv_into(self, sock, buf): raise NotImplementedError + async def sock_recvfrom(self, sock, bufsize): + raise NotImplementedError + + async def sock_recvfrom_into(self, sock, buf, nbytes=0): + raise NotImplementedError + async def sock_sendall(self, sock, data): raise NotImplementedError + async def sock_sendto(self, sock, data, address): + raise NotImplementedError + async def sock_connect(self, sock, address): raise NotImplementedError @@ -650,6 +675,23 @@ class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy): if (self._local._loop is None and not self._local._set_called and threading.current_thread() is threading.main_thread()): + stacklevel = 2 + try: + f = sys._getframe(1) + except AttributeError: + pass + else: + # Move up the call stack so that the warning is attached + # to the line outside asyncio itself. + while f: + module = f.f_globals.get('__name__') + if not (module == 'asyncio' or module.startswith('asyncio.')): + break + f = f.f_back + stacklevel += 1 + import warnings + warnings.warn('There is no current event loop', + DeprecationWarning, stacklevel=stacklevel) self.set_event_loop(self.new_event_loop()) if self._local._loop is None: @@ -661,7 +703,8 @@ class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy): def set_event_loop(self, loop): """Set the event loop.""" self._local._set_called = True - assert loop is None or isinstance(loop, AbstractEventLoop) + if loop is not None and not isinstance(loop, AbstractEventLoop): + raise TypeError(f"loop must be an instance of AbstractEventLoop or None, not '{type(loop).__name__}'") self._local._loop = loop def new_event_loop(self): @@ -745,7 +788,8 @@ def set_event_loop_policy(policy): If policy is None, the default policy is restored.""" global _event_loop_policy - assert policy is None or isinstance(policy, AbstractEventLoopPolicy) + if policy is not None and not isinstance(policy, AbstractEventLoopPolicy): + raise TypeError(f"policy must be an instance of AbstractEventLoopPolicy or None, not '{type(policy).__name__}'") _event_loop_policy = policy @@ -759,16 +803,9 @@ def get_event_loop(): the result of `get_event_loop_policy().get_event_loop()` call. """ # NOTE: this function is implemented in C (see _asynciomodule.c) - return _py__get_event_loop() - - -def _get_event_loop(stacklevel=3): current_loop = _get_running_loop() if current_loop is not None: return current_loop - import warnings - warnings.warn('There is no current event loop', - DeprecationWarning, stacklevel=stacklevel) return get_event_loop_policy().get_event_loop() @@ -798,7 +835,6 @@ _py__get_running_loop = _get_running_loop _py__set_running_loop = _set_running_loop _py_get_running_loop = get_running_loop _py_get_event_loop = get_event_loop -_py__get_event_loop = _get_event_loop try: @@ -806,7 +842,7 @@ try: # functions in asyncio. Pure Python implementation is # about 4 times slower than C-accelerated. from _asyncio import (_get_running_loop, _set_running_loop, - get_running_loop, get_event_loop, _get_event_loop) + get_running_loop, get_event_loop) except ImportError: pass else: @@ -815,4 +851,14 @@ else: _c__set_running_loop = _set_running_loop _c_get_running_loop = get_running_loop _c_get_event_loop = get_event_loop - _c__get_event_loop = _get_event_loop + + +if hasattr(os, 'fork'): + def on_fork(): + # Reset the loop and wakeupfd in the forked child process. + if _event_loop_policy is not None: + _event_loop_policy._local = BaseDefaultEventLoopPolicy._Local() + _set_running_loop(None) + signal.set_wakeup_fd(-1) + + os.register_at_fork(after_in_child=on_fork) diff --git a/Lib/asyncio/exceptions.py b/Lib/asyncio/exceptions.py index f07e4486577..5ece595aad6 100644 --- a/Lib/asyncio/exceptions.py +++ b/Lib/asyncio/exceptions.py @@ -1,7 +1,8 @@ """asyncio exceptions.""" -__all__ = ('CancelledError', 'InvalidStateError', 'TimeoutError', +__all__ = ('BrokenBarrierError', + 'CancelledError', 'InvalidStateError', 'TimeoutError', 'IncompleteReadError', 'LimitOverrunError', 'SendfileNotAvailableError') @@ -10,8 +11,7 @@ class CancelledError(BaseException): """The Future or Task was cancelled.""" -class TimeoutError(Exception): - """The operation exceeded the given deadline.""" +TimeoutError = TimeoutError # make local alias for the standard exception class InvalidStateError(Exception): @@ -56,3 +56,7 @@ class LimitOverrunError(Exception): def __reduce__(self): return type(self), (self.args[0], self.consumed) + + +class BrokenBarrierError(RuntimeError): + """Barrier is broken by barrier.abort() call.""" diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index 10f8f0554e4..97fc4e3fcb6 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -8,6 +8,7 @@ import concurrent.futures import contextvars import logging import sys +from types import GenericAlias from . import base_futures from . import events @@ -76,7 +77,7 @@ class Future: the default event loop. """ if loop is None: - self._loop = events._get_event_loop() + self._loop = events.get_event_loop() else: self._loop = loop self._callbacks = [] @@ -84,11 +85,8 @@ class Future: self._source_traceback = format_helpers.extract_stack( sys._getframe(1)) - _repr_info = base_futures._future_repr_info - def __repr__(self): - return '<{} {}>'.format(self.__class__.__name__, - ' '.join(self._repr_info())) + return base_futures._future_repr(self) def __del__(self): if not self.__log_traceback: @@ -106,8 +104,7 @@ class Future: context['source_traceback'] = self._source_traceback self._loop.call_exception_handler(context) - def __class_getitem__(cls, type): - return cls + __class_getitem__ = classmethod(GenericAlias) @property def _log_traceback(self): @@ -132,6 +129,11 @@ class Future: This should only be called once when handling a cancellation since it erases the saved context exception value. """ + if self._cancelled_exc is not None: + exc = self._cancelled_exc + self._cancelled_exc = None + return exc + if self._cancel_message is None: exc = exceptions.CancelledError() else: @@ -198,7 +200,7 @@ class Future: raise exceptions.InvalidStateError('Result is not ready.') self.__log_traceback = False if self._exception is not None: - raise self._exception + raise self._exception.with_traceback(self._exception_tb) return self._result def exception(self): @@ -274,6 +276,7 @@ class Future: raise TypeError("StopIteration interacts badly with generators " "and cannot be raised into a Future") self._exception = exception + self._exception_tb = exception.__traceback__ self._state = _FINISHED self.__schedule_callbacks() self.__log_traceback = True @@ -395,6 +398,8 @@ def _chain_future(source, destination): if dest_loop is None or dest_loop is source_loop: _set_state(destination, source) else: + if dest_loop.is_closed(): + return dest_loop.call_soon_threadsafe(_set_state, destination, source) destination.add_done_callback(_call_check_cancel) @@ -408,7 +413,7 @@ def wrap_future(future, *, loop=None): assert isinstance(future, concurrent.futures.Future), \ f'concurrent.futures.Future is expected, got {future!r}' if loop is None: - loop = events._get_event_loop() + loop = events.get_event_loop() new_future = loop.create_future() _chain_future(future, new_future) return new_future diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py index 4fef64e3921..ce5d8d5bfb2 100644 --- a/Lib/asyncio/locks.py +++ b/Lib/asyncio/locks.py @@ -1,13 +1,14 @@ """Synchronization primitives.""" -__all__ = ('Lock', 'Event', 'Condition', 'Semaphore', 'BoundedSemaphore') +__all__ = ('Lock', 'Event', 'Condition', 'Semaphore', + 'BoundedSemaphore', 'Barrier') import collections +import enum from . import exceptions from . import mixins - class _ContextManagerMixin: async def __aenter__(self): await self.acquire() @@ -73,8 +74,7 @@ class Lock(_ContextManagerMixin, mixins._LoopBoundMixin): """ - def __init__(self, *, loop=mixins._marker): - super().__init__(loop=loop) + def __init__(self): self._waiters = None self._locked = False @@ -163,8 +163,7 @@ class Event(mixins._LoopBoundMixin): false. """ - def __init__(self, *, loop=mixins._marker): - super().__init__(loop=loop) + def __init__(self): self._waiters = collections.deque() self._value = False @@ -226,8 +225,7 @@ class Condition(_ContextManagerMixin, mixins._LoopBoundMixin): A new Lock object is created and used as the underlying lock. """ - def __init__(self, lock=None, *, loop=mixins._marker): - super().__init__(loop=loop) + def __init__(self, lock=None): if lock is None: lock = Lock() @@ -344,12 +342,11 @@ class Semaphore(_ContextManagerMixin, mixins._LoopBoundMixin): ValueError is raised. """ - def __init__(self, value=1, *, loop=mixins._marker): - super().__init__(loop=loop) + def __init__(self, value=1): if value < 0: raise ValueError("Semaphore initial value must be >= 0") + self._waiters = None self._value = value - self._waiters = collections.deque() def __repr__(self): res = super().__repr__() @@ -358,16 +355,10 @@ class Semaphore(_ContextManagerMixin, mixins._LoopBoundMixin): extra = f'{extra}, waiters:{len(self._waiters)}' return f'<{res[1:-1]} [{extra}]>' - def _wake_up_next(self): - while self._waiters: - waiter = self._waiters.popleft() - if not waiter.done(): - waiter.set_result(None) - return - def locked(self): - """Returns True if semaphore can not be acquired immediately.""" - return self._value == 0 + """Returns True if semaphore cannot be acquired immediately.""" + return self._value == 0 or ( + any(not w.cancelled() for w in (self._waiters or ()))) async def acquire(self): """Acquire a semaphore. @@ -378,28 +369,53 @@ class Semaphore(_ContextManagerMixin, mixins._LoopBoundMixin): called release() to make it larger than 0, and then return True. """ - while self._value <= 0: - fut = self._get_loop().create_future() - self._waiters.append(fut) + if not self.locked(): + self._value -= 1 + return True + + if self._waiters is None: + self._waiters = collections.deque() + fut = self._get_loop().create_future() + self._waiters.append(fut) + + # Finally block should be called before the CancelledError + # handling as we don't want CancelledError to call + # _wake_up_first() and attempt to wake up itself. + try: try: await fut - except: - # See the similar code in Queue.get. - fut.cancel() - if self._value > 0 and not fut.cancelled(): - self._wake_up_next() - raise - self._value -= 1 + finally: + self._waiters.remove(fut) + except exceptions.CancelledError: + if not fut.cancelled(): + self._value += 1 + self._wake_up_next() + raise + + if self._value > 0: + self._wake_up_next() return True def release(self): """Release a semaphore, incrementing the internal counter by one. + When it was zero on entry and another coroutine is waiting for it to become larger than zero again, wake up that coroutine. """ self._value += 1 self._wake_up_next() + def _wake_up_next(self): + """Wake up the first waiter that isn't done.""" + if not self._waiters: + return + + for fut in self._waiters: + if not fut.done(): + self._value -= 1 + fut.set_result(True) + return + class BoundedSemaphore(Semaphore): """A bounded semaphore implementation. @@ -408,11 +424,163 @@ class BoundedSemaphore(Semaphore): above the initial value. """ - def __init__(self, value=1, *, loop=mixins._marker): + def __init__(self, value=1): self._bound_value = value - super().__init__(value, loop=loop) + super().__init__(value) def release(self): if self._value >= self._bound_value: raise ValueError('BoundedSemaphore released too many times') super().release() + + + +class _BarrierState(enum.Enum): + FILLING = 'filling' + DRAINING = 'draining' + RESETTING = 'resetting' + BROKEN = 'broken' + + +class Barrier(mixins._LoopBoundMixin): + """Asyncio equivalent to threading.Barrier + + Implements a Barrier primitive. + Useful for synchronizing a fixed number of tasks at known synchronization + points. Tasks block on 'wait()' and are simultaneously awoken once they + have all made their call. + """ + + def __init__(self, parties): + """Create a barrier, initialised to 'parties' tasks.""" + if parties < 1: + raise ValueError('parties must be > 0') + + self._cond = Condition() # notify all tasks when state changes + + self._parties = parties + self._state = _BarrierState.FILLING + self._count = 0 # count tasks in Barrier + + def __repr__(self): + res = super().__repr__() + extra = f'{self._state.value}' + if not self.broken: + extra += f', waiters:{self.n_waiting}/{self.parties}' + return f'<{res[1:-1]} [{extra}]>' + + async def __aenter__(self): + # wait for the barrier reaches the parties number + # when start draining release and return index of waited task + return await self.wait() + + async def __aexit__(self, *args): + pass + + async def wait(self): + """Wait for the barrier. + + When the specified number of tasks have started waiting, they are all + simultaneously awoken. + Returns an unique and individual index number from 0 to 'parties-1'. + """ + async with self._cond: + await self._block() # Block while the barrier drains or resets. + try: + index = self._count + self._count += 1 + if index + 1 == self._parties: + # We release the barrier + await self._release() + else: + await self._wait() + return index + finally: + self._count -= 1 + # Wake up any tasks waiting for barrier to drain. + self._exit() + + async def _block(self): + # Block until the barrier is ready for us, + # or raise an exception if it is broken. + # + # It is draining or resetting, wait until done + # unless a CancelledError occurs + await self._cond.wait_for( + lambda: self._state not in ( + _BarrierState.DRAINING, _BarrierState.RESETTING + ) + ) + + # see if the barrier is in a broken state + if self._state is _BarrierState.BROKEN: + raise exceptions.BrokenBarrierError("Barrier aborted") + + async def _release(self): + # Release the tasks waiting in the barrier. + + # Enter draining state. + # Next waiting tasks will be blocked until the end of draining. + self._state = _BarrierState.DRAINING + self._cond.notify_all() + + async def _wait(self): + # Wait in the barrier until we are released. Raise an exception + # if the barrier is reset or broken. + + # wait for end of filling + # unless a CancelledError occurs + await self._cond.wait_for(lambda: self._state is not _BarrierState.FILLING) + + if self._state in (_BarrierState.BROKEN, _BarrierState.RESETTING): + raise exceptions.BrokenBarrierError("Abort or reset of barrier") + + def _exit(self): + # If we are the last tasks to exit the barrier, signal any tasks + # waiting for the barrier to drain. + if self._count == 0: + if self._state in (_BarrierState.RESETTING, _BarrierState.DRAINING): + self._state = _BarrierState.FILLING + self._cond.notify_all() + + async def reset(self): + """Reset the barrier to the initial state. + + Any tasks currently waiting will get the BrokenBarrier exception + raised. + """ + async with self._cond: + if self._count > 0: + if self._state is not _BarrierState.RESETTING: + #reset the barrier, waking up tasks + self._state = _BarrierState.RESETTING + else: + self._state = _BarrierState.FILLING + self._cond.notify_all() + + async def abort(self): + """Place the barrier into a 'broken' state. + + Useful in case of error. Any currently waiting tasks and tasks + attempting to 'wait()' will have BrokenBarrierError raised. + """ + async with self._cond: + self._state = _BarrierState.BROKEN + self._cond.notify_all() + + @property + def parties(self): + """Return the number of tasks required to trip the barrier.""" + return self._parties + + @property + def n_waiting(self): + """Return the number of tasks currently waiting at the barrier.""" + if self._state is _BarrierState.FILLING: + return self._count + return 0 + + @property + def broken(self): + """Return True if the barrier is in a broken state.""" + return self._state is _BarrierState.BROKEN diff --git a/Lib/asyncio/mixins.py b/Lib/asyncio/mixins.py index 650df05ccc9..c6bf97329e9 100644 --- a/Lib/asyncio/mixins.py +++ b/Lib/asyncio/mixins.py @@ -5,20 +5,10 @@ from . import events _global_lock = threading.Lock() -# Used as a sentinel for loop parameter -_marker = object() - class _LoopBoundMixin: _loop = None - def __init__(self, *, loop=_marker): - if loop is not _marker: - raise TypeError( - f'As of 3.10, the *loop* parameter was removed from ' - f'{type(self).__name__}() since it is no longer necessary' - ) - def _get_loop(self): loop = events._get_running_loop() diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 1d9e2fe2ca7..1e2a730cf36 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -60,6 +60,7 @@ class _ProactorBasePipeTransport(transports._FlowControlMixin, self._pending_write = 0 self._conn_lost = 0 self._closing = False # Set when close() called. + self._called_connection_lost = False self._eof_written = False if self._server is not None: self._server._attach() @@ -113,7 +114,7 @@ class _ProactorBasePipeTransport(transports._FlowControlMixin, def __del__(self, _warn=warnings.warn): if self._sock is not None: _warn(f"unclosed transport {self!r}", ResourceWarning, source=self) - self.close() + self._sock.close() def _fatal_error(self, exc, message='Fatal error on pipe transport'): try: @@ -136,7 +137,7 @@ class _ProactorBasePipeTransport(transports._FlowControlMixin, self._empty_waiter.set_result(None) else: self._empty_waiter.set_exception(exc) - if self._closing: + if self._closing and self._called_connection_lost: return self._closing = True self._conn_lost += 1 @@ -151,6 +152,8 @@ class _ProactorBasePipeTransport(transports._FlowControlMixin, self._loop.call_soon(self._call_connection_lost, exc) def _call_connection_lost(self, exc): + if self._called_connection_lost: + return try: self._protocol.connection_lost(exc) finally: @@ -158,7 +161,7 @@ class _ProactorBasePipeTransport(transports._FlowControlMixin, # end then it may fail with ERROR_NETNAME_DELETED if we # just close our end. First calling shutdown() seems to # cure it, but maybe using DisconnectEx() would be better. - if hasattr(self._sock, 'shutdown'): + if hasattr(self._sock, 'shutdown') and self._sock.fileno() != -1: self._sock.shutdown(socket.SHUT_RDWR) self._sock.close() self._sock = None @@ -166,6 +169,7 @@ class _ProactorBasePipeTransport(transports._FlowControlMixin, if server is not None: server._detach() self._server = None + self._called_connection_lost = True def get_write_buffer_size(self): size = self._pending_write @@ -284,7 +288,8 @@ class _ProactorReadPipeTransport(_ProactorBasePipeTransport, # we got end-of-file so no need to reschedule a new read return - data = self._data[:length] + # It's a new slice so make it immutable so protocols upstream don't have problems + data = bytes(memoryview(self._data)[:length]) else: # the future will be replaced by next proactor.recv call fut.cancel() @@ -452,12 +457,14 @@ class _ProactorWritePipeTransport(_ProactorBaseWritePipeTransport): self.close() -class _ProactorDatagramTransport(_ProactorBasePipeTransport): +class _ProactorDatagramTransport(_ProactorBasePipeTransport, + transports.DatagramTransport): max_size = 256 * 1024 def __init__(self, loop, sock, protocol, address=None, waiter=None, extra=None): self._address = address self._empty_waiter = None + self._buffer_size = 0 # We don't need to call _protocol.connection_made() since our base # constructor does it for us. super().__init__(loop, sock, protocol, waiter=waiter, extra=extra) @@ -470,7 +477,7 @@ class _ProactorDatagramTransport(_ProactorBasePipeTransport): _set_socket_extra(self, sock) def get_write_buffer_size(self): - return sum(len(data) for data, _ in self._buffer) + return self._buffer_size def abort(self): self._force_close(None) @@ -495,6 +502,7 @@ class _ProactorDatagramTransport(_ProactorBasePipeTransport): # Ensure that what we buffer is immutable. self._buffer.append((bytes(data), addr)) + self._buffer_size += len(data) if self._write_fut is None: # No current write operations are active, kick one off @@ -521,6 +529,7 @@ class _ProactorDatagramTransport(_ProactorBasePipeTransport): return data, addr = self._buffer.popleft() + self._buffer_size -= len(data) if self._address is not None: self._write_fut = self._loop._proactor.send(self._sock, data) @@ -642,11 +651,13 @@ class BaseProactorEventLoop(base_events.BaseEventLoop): self, rawsock, protocol, sslcontext, waiter=None, *, server_side=False, server_hostname=None, extra=None, server=None, - ssl_handshake_timeout=None): + ssl_handshake_timeout=None, + ssl_shutdown_timeout=None): ssl_protocol = sslproto.SSLProtocol( self, protocol, sslcontext, waiter, server_side, server_hostname, - ssl_handshake_timeout=ssl_handshake_timeout) + ssl_handshake_timeout=ssl_handshake_timeout, + ssl_shutdown_timeout=ssl_shutdown_timeout) _ProactorSocketTransport(self, rawsock, ssl_protocol, extra=extra, server=server) return ssl_protocol._app_transport @@ -697,9 +708,21 @@ class BaseProactorEventLoop(base_events.BaseEventLoop): async def sock_recv_into(self, sock, buf): return await self._proactor.recv_into(sock, buf) + async def sock_recvfrom(self, sock, bufsize): + return await self._proactor.recvfrom(sock, bufsize) + + async def sock_recvfrom_into(self, sock, buf, nbytes=0): + if not nbytes: + nbytes = len(buf) + + return await self._proactor.recvfrom_into(sock, buf, nbytes) + async def sock_sendall(self, sock, data): return await self._proactor.send(sock, data) + async def sock_sendto(self, sock, data, address): + return await self._proactor.sendto(sock, data, 0, address) + async def sock_connect(self, sock, address): return await self._proactor.connect(sock, address) @@ -812,7 +835,8 @@ class BaseProactorEventLoop(base_events.BaseEventLoop): def _start_serving(self, protocol_factory, sock, sslcontext=None, server=None, backlog=100, - ssl_handshake_timeout=None): + ssl_handshake_timeout=None, + ssl_shutdown_timeout=None): def loop(f=None): try: @@ -826,7 +850,8 @@ class BaseProactorEventLoop(base_events.BaseEventLoop): self._make_ssl_transport( conn, protocol, sslcontext, server_side=True, extra={'peername': addr}, server=server, - ssl_handshake_timeout=ssl_handshake_timeout) + ssl_handshake_timeout=ssl_handshake_timeout, + ssl_shutdown_timeout=ssl_shutdown_timeout) else: self._make_socket_transport( conn, protocol, diff --git a/Lib/asyncio/protocols.py b/Lib/asyncio/protocols.py index 69fa43e8b65..09987b164c6 100644 --- a/Lib/asyncio/protocols.py +++ b/Lib/asyncio/protocols.py @@ -109,10 +109,6 @@ class Protocol(BaseProtocol): class BufferedProtocol(BaseProtocol): """Interface for stream protocol with manual buffer control. - Important: this has been added to asyncio in Python 3.7 - *on a provisional basis*! Consider it as an experimental API that - might be changed or removed in Python 3.8. - Event methods, such as `create_server` and `create_connection`, accept factories that return protocols that implement this interface. diff --git a/Lib/asyncio/queues.py b/Lib/asyncio/queues.py index a87ec8b2158..a9656a6df56 100644 --- a/Lib/asyncio/queues.py +++ b/Lib/asyncio/queues.py @@ -2,6 +2,7 @@ __all__ = ('Queue', 'PriorityQueue', 'LifoQueue', 'QueueFull', 'QueueEmpty') import collections import heapq +from types import GenericAlias from . import locks from . import mixins @@ -29,8 +30,7 @@ class Queue(mixins._LoopBoundMixin): interrupted between calling qsize() and doing an operation on the Queue. """ - def __init__(self, maxsize=0, *, loop=mixins._marker): - super().__init__(loop=loop) + def __init__(self, maxsize=0): self._maxsize = maxsize # Futures. @@ -69,8 +69,7 @@ class Queue(mixins._LoopBoundMixin): def __str__(self): return f'<{type(self).__name__} {self._format()}>' - def __class_getitem__(cls, type): - return cls + __class_getitem__ = classmethod(GenericAlias) def _format(self): result = f'maxsize={self._maxsize!r}' diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index 9a5e9a48479..1b89236599a 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -1,16 +1,168 @@ -__all__ = 'run', +__all__ = ('Runner', 'run') +import contextvars +import enum +import functools +import threading +import signal from . import coroutines from . import events +from . import exceptions from . import tasks +from . import constants + +class _State(enum.Enum): + CREATED = "created" + INITIALIZED = "initialized" + CLOSED = "closed" -def run(main, *, debug=None): +class Runner: + """A context manager that controls event loop life cycle. + + The context manager always creates a new event loop, + allows to run async functions inside it, + and properly finalizes the loop at the context manager exit. + + If debug is True, the event loop will be run in debug mode. + If loop_factory is passed, it is used for new event loop creation. + + asyncio.run(main(), debug=True) + + is a shortcut for + + with asyncio.Runner(debug=True) as runner: + runner.run(main()) + + The run() method can be called multiple times within the runner's context. + + This can be useful for interactive console (e.g. IPython), + unittest runners, console tools, -- everywhere when async code + is called from existing sync framework and where the preferred single + asyncio.run() call doesn't work. + + """ + + # Note: the class is final, it is not intended for inheritance. + + def __init__(self, *, debug=None, loop_factory=None): + self._state = _State.CREATED + self._debug = debug + self._loop_factory = loop_factory + self._loop = None + self._context = None + self._interrupt_count = 0 + self._set_event_loop = False + + def __enter__(self): + self._lazy_init() + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + + def close(self): + """Shutdown and close event loop.""" + if self._state is not _State.INITIALIZED: + return + try: + loop = self._loop + _cancel_all_tasks(loop) + loop.run_until_complete(loop.shutdown_asyncgens()) + loop.run_until_complete( + loop.shutdown_default_executor(constants.THREAD_JOIN_TIMEOUT)) + finally: + if self._set_event_loop: + events.set_event_loop(None) + loop.close() + self._loop = None + self._state = _State.CLOSED + + def get_loop(self): + """Return embedded event loop.""" + self._lazy_init() + return self._loop + + def run(self, coro, *, context=None): + """Run a coroutine inside the embedded event loop.""" + if not coroutines.iscoroutine(coro): + raise ValueError("a coroutine was expected, got {!r}".format(coro)) + + if events._get_running_loop() is not None: + # fail fast with short traceback + raise RuntimeError( + "Runner.run() cannot be called from a running event loop") + + self._lazy_init() + + if context is None: + context = self._context + task = self._loop.create_task(coro, context=context) + + if (threading.current_thread() is threading.main_thread() + and signal.getsignal(signal.SIGINT) is signal.default_int_handler + ): + sigint_handler = functools.partial(self._on_sigint, main_task=task) + try: + signal.signal(signal.SIGINT, sigint_handler) + except ValueError: + # `signal.signal` may throw if `threading.main_thread` does + # not support signals (e.g. embedded interpreter with signals + # not registered - see gh-91880) + sigint_handler = None + else: + sigint_handler = None + + self._interrupt_count = 0 + try: + return self._loop.run_until_complete(task) + except exceptions.CancelledError: + if self._interrupt_count > 0: + uncancel = getattr(task, "uncancel", None) + if uncancel is not None and uncancel() == 0: + raise KeyboardInterrupt() + raise # CancelledError + finally: + if (sigint_handler is not None + and signal.getsignal(signal.SIGINT) is sigint_handler + ): + signal.signal(signal.SIGINT, signal.default_int_handler) + + def _lazy_init(self): + if self._state is _State.CLOSED: + raise RuntimeError("Runner is closed") + if self._state is _State.INITIALIZED: + return + if self._loop_factory is None: + self._loop = events.new_event_loop() + if not self._set_event_loop: + # Call set_event_loop only once to avoid calling + # attach_loop multiple times on child watchers + events.set_event_loop(self._loop) + self._set_event_loop = True + else: + self._loop = self._loop_factory() + if self._debug is not None: + self._loop.set_debug(self._debug) + self._context = contextvars.copy_context() + self._state = _State.INITIALIZED + + def _on_sigint(self, signum, frame, main_task): + self._interrupt_count += 1 + if self._interrupt_count == 1 and not main_task.done(): + main_task.cancel() + # wakeup loop if it is blocked by select() with long timeout + self._loop.call_soon_threadsafe(lambda: None) + return + raise KeyboardInterrupt() + + +def run(main, *, debug=None, loop_factory=None): """Execute the coroutine and return the result. This function runs the passed coroutine, taking care of - managing the asyncio event loop and finalizing asynchronous - generators. + managing the asyncio event loop, finalizing asynchronous + generators and closing the default executor. This function cannot be called when another asyncio event loop is running in the same thread. @@ -21,6 +173,10 @@ def run(main, *, debug=None): It should be used as a main entry point for asyncio programs, and should ideally only be called once. + The executor is given a timeout duration of 5 minutes to shutdown. + If the executor hasn't finished within that duration, a warning is + emitted and the executor is closed. + Example: async def main(): @@ -30,26 +186,12 @@ def run(main, *, debug=None): asyncio.run(main()) """ if events._get_running_loop() is not None: + # fail fast with short traceback raise RuntimeError( "asyncio.run() cannot be called from a running event loop") - if not coroutines.iscoroutine(main): - raise ValueError("a coroutine was expected, got {!r}".format(main)) - - loop = events.new_event_loop() - try: - events.set_event_loop(loop) - if debug is not None: - loop.set_debug(debug) - return loop.run_until_complete(main) - finally: - try: - _cancel_all_tasks(loop) - loop.run_until_complete(loop.shutdown_asyncgens()) - loop.run_until_complete(loop.shutdown_default_executor()) - finally: - events.set_event_loop(None) - loop.close() + with Runner(debug=debug, loop_factory=loop_factory) as runner: + return runner.run(main) def _cancel_all_tasks(loop): diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 59cb6b1babe..de5076a9621 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -9,6 +9,8 @@ __all__ = 'BaseSelectorEventLoop', import collections import errno import functools +import itertools +import os import selectors import socket import warnings @@ -28,6 +30,14 @@ from . import transports from . import trsock from .log import logger +_HAS_SENDMSG = hasattr(socket.socket, 'sendmsg') + +if _HAS_SENDMSG: + try: + SC_IOV_MAX = os.sysconf('SC_IOV_MAX') + except OSError: + # Fallback to send + _HAS_SENDMSG = False def _test_selector_event(selector, fd, event): # Test if the selector is monitoring 'event' events @@ -40,11 +50,6 @@ def _test_selector_event(selector, fd, event): return bool(key.events & event) -def _check_ssl_socket(sock): - if ssl is not None and isinstance(sock, ssl.SSLSocket): - raise TypeError("Socket cannot be of type SSLSocket") - - class BaseSelectorEventLoop(base_events.BaseEventLoop): """Selector event loop. @@ -63,6 +68,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): def _make_socket_transport(self, sock, protocol, waiter=None, *, extra=None, server=None): + self._ensure_fd_no_transport(sock) return _SelectorSocketTransport(self, sock, protocol, waiter, extra, server) @@ -70,17 +76,23 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): self, rawsock, protocol, sslcontext, waiter=None, *, server_side=False, server_hostname=None, extra=None, server=None, - ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT): + ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT, + ssl_shutdown_timeout=constants.SSL_SHUTDOWN_TIMEOUT, + ): + self._ensure_fd_no_transport(rawsock) ssl_protocol = sslproto.SSLProtocol( - self, protocol, sslcontext, waiter, - server_side, server_hostname, - ssl_handshake_timeout=ssl_handshake_timeout) + self, protocol, sslcontext, waiter, + server_side, server_hostname, + ssl_handshake_timeout=ssl_handshake_timeout, + ssl_shutdown_timeout=ssl_shutdown_timeout + ) _SelectorSocketTransport(self, rawsock, ssl_protocol, extra=extra, server=server) return ssl_protocol._app_transport def _make_datagram_transport(self, sock, protocol, address=None, waiter=None, extra=None): + self._ensure_fd_no_transport(sock) return _SelectorDatagramTransport(self, sock, protocol, address, waiter, extra) @@ -146,15 +158,17 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): def _start_serving(self, protocol_factory, sock, sslcontext=None, server=None, backlog=100, - ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT): + ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT, + ssl_shutdown_timeout=constants.SSL_SHUTDOWN_TIMEOUT): self._add_reader(sock.fileno(), self._accept_connection, protocol_factory, sock, sslcontext, server, backlog, - ssl_handshake_timeout) + ssl_handshake_timeout, ssl_shutdown_timeout) def _accept_connection( self, protocol_factory, sock, sslcontext=None, server=None, backlog=100, - ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT): + ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT, + ssl_shutdown_timeout=constants.SSL_SHUTDOWN_TIMEOUT): # This method is only called once for each event loop tick where the # listening socket has triggered an EVENT_READ. There may be multiple # connections waiting for an .accept() so it is called in a loop. @@ -185,20 +199,22 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): self.call_later(constants.ACCEPT_RETRY_DELAY, self._start_serving, protocol_factory, sock, sslcontext, server, - backlog, ssl_handshake_timeout) + backlog, ssl_handshake_timeout, + ssl_shutdown_timeout) else: raise # The event loop will catch, log and ignore it. else: extra = {'peername': addr} accept = self._accept_connection2( protocol_factory, conn, extra, sslcontext, server, - ssl_handshake_timeout) + ssl_handshake_timeout, ssl_shutdown_timeout) self.create_task(accept) async def _accept_connection2( self, protocol_factory, conn, extra, sslcontext=None, server=None, - ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT): + ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT, + ssl_shutdown_timeout=constants.SSL_SHUTDOWN_TIMEOUT): protocol = None transport = None try: @@ -208,7 +224,8 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): transport = self._make_ssl_transport( conn, protocol, sslcontext, waiter=waiter, server_side=True, extra=extra, server=server, - ssl_handshake_timeout=ssl_handshake_timeout) + ssl_handshake_timeout=ssl_handshake_timeout, + ssl_shutdown_timeout=ssl_shutdown_timeout) else: transport = self._make_socket_transport( conn, protocol, waiter=waiter, extra=extra, @@ -357,7 +374,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): The maximum amount of data to be received at once is specified by nbytes. """ - _check_ssl_socket(sock) + base_events._check_ssl_socket(sock) if self._debug and sock.gettimeout() != 0: raise ValueError("the socket must be non-blocking") try: @@ -398,7 +415,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): The received data is written into *buf* (a writable buffer). The return value is the number of bytes written. """ - _check_ssl_socket(sock) + base_events._check_ssl_socket(sock) if self._debug and sock.gettimeout() != 0: raise ValueError("the socket must be non-blocking") try: @@ -430,6 +447,88 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): else: fut.set_result(nbytes) + async def sock_recvfrom(self, sock, bufsize): + """Receive a datagram from a datagram socket. + + The return value is a tuple of (bytes, address) representing the + datagram received and the address it came from. + The maximum amount of data to be received at once is specified by + nbytes. + """ + base_events._check_ssl_socket(sock) + if self._debug and sock.gettimeout() != 0: + raise ValueError("the socket must be non-blocking") + try: + return sock.recvfrom(bufsize) + except (BlockingIOError, InterruptedError): + pass + fut = self.create_future() + fd = sock.fileno() + self._ensure_fd_no_transport(fd) + handle = self._add_reader(fd, self._sock_recvfrom, fut, sock, bufsize) + fut.add_done_callback( + functools.partial(self._sock_read_done, fd, handle=handle)) + return await fut + + def _sock_recvfrom(self, fut, sock, bufsize): + # _sock_recvfrom() can add itself as an I/O callback if the operation + # can't be done immediately. Don't use it directly, call + # sock_recvfrom(). + if fut.done(): + return + try: + result = sock.recvfrom(bufsize) + except (BlockingIOError, InterruptedError): + return # try again next time + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: + fut.set_exception(exc) + else: + fut.set_result(result) + + async def sock_recvfrom_into(self, sock, buf, nbytes=0): + """Receive data from the socket. + + The received data is written into *buf* (a writable buffer). + The return value is a tuple of (number of bytes written, address). + """ + base_events._check_ssl_socket(sock) + if self._debug and sock.gettimeout() != 0: + raise ValueError("the socket must be non-blocking") + if not nbytes: + nbytes = len(buf) + + try: + return sock.recvfrom_into(buf, nbytes) + except (BlockingIOError, InterruptedError): + pass + fut = self.create_future() + fd = sock.fileno() + self._ensure_fd_no_transport(fd) + handle = self._add_reader(fd, self._sock_recvfrom_into, fut, sock, buf, + nbytes) + fut.add_done_callback( + functools.partial(self._sock_read_done, fd, handle=handle)) + return await fut + + def _sock_recvfrom_into(self, fut, sock, buf, bufsize): + # _sock_recv_into() can add itself as an I/O callback if the operation + # can't be done immediately. Don't use it directly, call + # sock_recv_into(). + if fut.done(): + return + try: + result = sock.recvfrom_into(buf, bufsize) + except (BlockingIOError, InterruptedError): + return # try again next time + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: + fut.set_exception(exc) + else: + fut.set_result(result) + async def sock_sendall(self, sock, data): """Send data to the socket. @@ -439,7 +538,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): raised, and there is no way to determine how much data, if any, was successfully processed by the receiving end of the connection. """ - _check_ssl_socket(sock) + base_events._check_ssl_socket(sock) if self._debug and sock.gettimeout() != 0: raise ValueError("the socket must be non-blocking") try: @@ -483,23 +582,72 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): else: pos[0] = start + async def sock_sendto(self, sock, data, address): + """Send data to the socket. + + The socket must be connected to a remote socket. This method continues + to send data from data until either all data has been sent or an + error occurs. None is returned on success. On error, an exception is + raised, and there is no way to determine how much data, if any, was + successfully processed by the receiving end of the connection. + """ + base_events._check_ssl_socket(sock) + if self._debug and sock.gettimeout() != 0: + raise ValueError("the socket must be non-blocking") + try: + return sock.sendto(data, address) + except (BlockingIOError, InterruptedError): + pass + + fut = self.create_future() + fd = sock.fileno() + self._ensure_fd_no_transport(fd) + # use a trick with a list in closure to store a mutable state + handle = self._add_writer(fd, self._sock_sendto, fut, sock, data, + address) + fut.add_done_callback( + functools.partial(self._sock_write_done, fd, handle=handle)) + return await fut + + def _sock_sendto(self, fut, sock, data, address): + if fut.done(): + # Future cancellation can be scheduled on previous loop iteration + return + try: + n = sock.sendto(data, 0, address) + except (BlockingIOError, InterruptedError): + return + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: + fut.set_exception(exc) + else: + fut.set_result(n) + async def sock_connect(self, sock, address): """Connect to a remote socket at address. This method is a coroutine. """ - _check_ssl_socket(sock) + base_events._check_ssl_socket(sock) if self._debug and sock.gettimeout() != 0: raise ValueError("the socket must be non-blocking") - if not hasattr(socket, 'AF_UNIX') or sock.family != socket.AF_UNIX: + if sock.family == socket.AF_INET or ( + base_events._HAS_IPv6 and sock.family == socket.AF_INET6): resolved = await self._ensure_resolved( - address, family=sock.family, proto=sock.proto, loop=self) + address, family=sock.family, type=sock.type, proto=sock.proto, + loop=self, + ) _, _, _, _, address = resolved[0] fut = self.create_future() self._sock_connect(fut, sock, address) - return await fut + try: + return await fut + finally: + # Needed to break cycles when an exception occurs. + fut = None def _sock_connect(self, fut, sock, address): fd = sock.fileno() @@ -521,6 +669,8 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): fut.set_exception(exc) else: fut.set_result(None) + finally: + fut = None def _sock_write_done(self, fd, fut, handle=None): if handle is None or not handle.cancelled(): @@ -544,6 +694,8 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): fut.set_exception(exc) else: fut.set_result(None) + finally: + fut = None async def sock_accept(self, sock): """Accept a connection. @@ -553,7 +705,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection. """ - _check_ssl_socket(sock) + base_events._check_ssl_socket(sock) if self._debug and sock.gettimeout() != 0: raise ValueError("the socket must be non-blocking") fut = self.create_future() @@ -615,8 +767,6 @@ class _SelectorTransport(transports._FlowControlMixin, max_size = 256 * 1024 # Buffer size passed to recv(). - _buffer_factory = bytearray # Constructs initial value for self._buffer. - # Attribute used in the destructor: it must be set even if the constructor # is not called (see _SelectorSslTransport which may start by raising an # exception) @@ -641,7 +791,7 @@ class _SelectorTransport(transports._FlowControlMixin, self.set_protocol(protocol) self._server = server - self._buffer = self._buffer_factory() + self._buffer = collections.deque() self._conn_lost = 0 # Set when call to connection_lost scheduled. self._closing = False # Set when close() called. if self._server is not None: @@ -745,7 +895,7 @@ class _SelectorTransport(transports._FlowControlMixin, self._server = None def get_write_buffer_size(self): - return len(self._buffer) + return sum(map(len, self._buffer)) def _add_reader(self, fd, callback, *args): if self._closing: @@ -767,7 +917,10 @@ class _SelectorSocketTransport(_SelectorTransport): self._eof = False self._paused = False self._empty_waiter = None - + if _HAS_SENDMSG: + self._write_ready = self._write_sendmsg + else: + self._write_ready = self._write_send # Disable the Nagle algorithm -- small writes will be # sent without waiting for the TCP ACK. This generally # decreases the latency (in some cases significantly.) @@ -924,23 +1077,68 @@ class _SelectorSocketTransport(_SelectorTransport): self._fatal_error(exc, 'Fatal write error on socket transport') return else: - data = data[n:] + data = memoryview(data)[n:] if not data: return # Not all was written; register write handler. self._loop._add_writer(self._sock_fd, self._write_ready) # Add it to the buffer. - self._buffer.extend(data) + self._buffer.append(data) self._maybe_pause_protocol() - def _write_ready(self): - assert self._buffer, 'Data should not be empty' + def _get_sendmsg_buffer(self): + return itertools.islice(self._buffer, SC_IOV_MAX) + def _write_sendmsg(self): + assert self._buffer, 'Data should not be empty' if self._conn_lost: return try: - n = self._sock.send(self._buffer) + nbytes = self._sock.sendmsg(self._get_sendmsg_buffer()) + self._adjust_leftover_buffer(nbytes) + except (BlockingIOError, InterruptedError): + pass + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: + self._loop._remove_writer(self._sock_fd) + self._buffer.clear() + self._fatal_error(exc, 'Fatal write error on socket transport') + if self._empty_waiter is not None: + self._empty_waiter.set_exception(exc) + else: + self._maybe_resume_protocol() # May append to buffer. + if not self._buffer: + self._loop._remove_writer(self._sock_fd) + if self._empty_waiter is not None: + self._empty_waiter.set_result(None) + if self._closing: + self._call_connection_lost(None) + elif self._eof: + self._sock.shutdown(socket.SHUT_WR) + + def _adjust_leftover_buffer(self, nbytes: int) -> None: + buffer = self._buffer + while nbytes: + b = buffer.popleft() + b_len = len(b) + if b_len <= nbytes: + nbytes -= b_len + else: + buffer.appendleft(b[nbytes:]) + break + + def _write_send(self): + assert self._buffer, 'Data should not be empty' + if self._conn_lost: + return + try: + buffer = self._buffer.popleft() + n = self._sock.send(buffer) + if n != len(buffer): + # Not all data was written + self._buffer.appendleft(buffer[n:]) except (BlockingIOError, InterruptedError): pass except (SystemExit, KeyboardInterrupt): @@ -952,8 +1150,6 @@ class _SelectorSocketTransport(_SelectorTransport): if self._empty_waiter is not None: self._empty_waiter.set_exception(exc) else: - if n: - del self._buffer[:n] self._maybe_resume_protocol() # May append to buffer. if not self._buffer: self._loop._remove_writer(self._sock_fd) @@ -971,6 +1167,16 @@ class _SelectorSocketTransport(_SelectorTransport): if not self._buffer: self._sock.shutdown(socket.SHUT_WR) + def writelines(self, list_of_data): + if self._eof: + raise RuntimeError('Cannot call writelines() after write_eof()') + if self._empty_waiter is not None: + raise RuntimeError('unable to writelines; sendfile is in progress') + if not list_of_data: + return + self._buffer.extend([memoryview(data) for data in list_of_data]) + self._write_ready() + def can_write_eof(self): return True @@ -991,8 +1197,12 @@ class _SelectorSocketTransport(_SelectorTransport): def _reset_empty_waiter(self): self._empty_waiter = None + def close(self): + self._read_ready_cb = None + super().close() -class _SelectorDatagramTransport(_SelectorTransport): + +class _SelectorDatagramTransport(_SelectorTransport, transports.DatagramTransport): _buffer_factory = collections.deque @@ -1000,6 +1210,7 @@ class _SelectorDatagramTransport(_SelectorTransport): waiter=None, extra=None): super().__init__(loop, sock, protocol, extra) self._address = address + self._buffer_size = 0 self._loop.call_soon(self._protocol.connection_made, self) # only start reading when connection_made() has been called self._loop.call_soon(self._add_reader, @@ -1010,7 +1221,7 @@ class _SelectorDatagramTransport(_SelectorTransport): waiter, None) def get_write_buffer_size(self): - return sum(len(data) for data, _ in self._buffer) + return self._buffer_size def _read_ready(self): if self._conn_lost: @@ -1069,11 +1280,13 @@ class _SelectorDatagramTransport(_SelectorTransport): # Ensure that what we buffer is immutable. self._buffer.append((bytes(data), addr)) + self._buffer_size += len(data) self._maybe_pause_protocol() def _sendto_ready(self): while self._buffer: data, addr = self._buffer.popleft() + self._buffer_size -= len(data) try: if self._extra['peername']: self._sock.send(data) @@ -1081,6 +1294,7 @@ class _SelectorDatagramTransport(_SelectorTransport): self._sock.sendto(data, addr) except (BlockingIOError, InterruptedError): self._buffer.appendleft((data, addr)) # Try again later. + self._buffer_size += len(data) break except OSError as exc: self._protocol.error_received(exc) diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index cad25b26539..bbf9cad6bc7 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -1,4 +1,5 @@ import collections +import enum import warnings try: import ssl @@ -6,10 +7,38 @@ except ImportError: # pragma: no cover ssl = None from . import constants +from . import exceptions from . import protocols from . import transports from .log import logger +if ssl is not None: + SSLAgainErrors = (ssl.SSLWantReadError, ssl.SSLSyscallError) + + +class SSLProtocolState(enum.Enum): + UNWRAPPED = "UNWRAPPED" + DO_HANDSHAKE = "DO_HANDSHAKE" + WRAPPED = "WRAPPED" + FLUSHING = "FLUSHING" + SHUTDOWN = "SHUTDOWN" + + +class AppProtocolState(enum.Enum): + # This tracks the state of app protocol (https://git.io/fj59P): + # + # INIT -cm-> CON_MADE [-dr*->] [-er-> EOF?] -cl-> CON_LOST + # + # * cm: connection_made() + # * dr: data_received() + # * er: eof_received() + # * cl: connection_lost() + + STATE_INIT = "STATE_INIT" + STATE_CON_MADE = "STATE_CON_MADE" + STATE_EOF = "STATE_EOF" + STATE_CON_LOST = "STATE_CON_LOST" + def _create_transport_context(server_side, server_hostname): if server_side: @@ -25,269 +54,35 @@ def _create_transport_context(server_side, server_hostname): return sslcontext -# States of an _SSLPipe. -_UNWRAPPED = "UNWRAPPED" -_DO_HANDSHAKE = "DO_HANDSHAKE" -_WRAPPED = "WRAPPED" -_SHUTDOWN = "SHUTDOWN" +def add_flowcontrol_defaults(high, low, kb): + if high is None: + if low is None: + hi = kb * 1024 + else: + lo = low + hi = 4 * lo + else: + hi = high + if low is None: + lo = hi // 4 + else: + lo = low + if not hi >= lo >= 0: + raise ValueError('high (%r) must be >= low (%r) must be >= 0' % + (hi, lo)) -class _SSLPipe(object): - """An SSL "Pipe". - - An SSL pipe allows you to communicate with an SSL/TLS protocol instance - through memory buffers. It can be used to implement a security layer for an - existing connection where you don't have access to the connection's file - descriptor, or for some reason you don't want to use it. - - An SSL pipe can be in "wrapped" and "unwrapped" mode. In unwrapped mode, - data is passed through untransformed. In wrapped mode, application level - data is encrypted to SSL record level data and vice versa. The SSL record - level is the lowest level in the SSL protocol suite and is what travels - as-is over the wire. - - An SslPipe initially is in "unwrapped" mode. To start SSL, call - do_handshake(). To shutdown SSL again, call unwrap(). - """ - - max_size = 256 * 1024 # Buffer size passed to read() - - def __init__(self, context, server_side, server_hostname=None): - """ - The *context* argument specifies the ssl.SSLContext to use. - - The *server_side* argument indicates whether this is a server side or - client side transport. - - The optional *server_hostname* argument can be used to specify the - hostname you are connecting to. You may only specify this parameter if - the _ssl module supports Server Name Indication (SNI). - """ - self._context = context - self._server_side = server_side - self._server_hostname = server_hostname - self._state = _UNWRAPPED - self._incoming = ssl.MemoryBIO() - self._outgoing = ssl.MemoryBIO() - self._sslobj = None - self._need_ssldata = False - self._handshake_cb = None - self._shutdown_cb = None - - @property - def context(self): - """The SSL context passed to the constructor.""" - return self._context - - @property - def ssl_object(self): - """The internal ssl.SSLObject instance. - - Return None if the pipe is not wrapped. - """ - return self._sslobj - - @property - def need_ssldata(self): - """Whether more record level data is needed to complete a handshake - that is currently in progress.""" - return self._need_ssldata - - @property - def wrapped(self): - """ - Whether a security layer is currently in effect. - - Return False during handshake. - """ - return self._state == _WRAPPED - - def do_handshake(self, callback=None): - """Start the SSL handshake. - - Return a list of ssldata. A ssldata element is a list of buffers - - The optional *callback* argument can be used to install a callback that - will be called when the handshake is complete. The callback will be - called with None if successful, else an exception instance. - """ - if self._state != _UNWRAPPED: - raise RuntimeError('handshake in progress or completed') - self._sslobj = self._context.wrap_bio( - self._incoming, self._outgoing, - server_side=self._server_side, - server_hostname=self._server_hostname) - self._state = _DO_HANDSHAKE - self._handshake_cb = callback - ssldata, appdata = self.feed_ssldata(b'', only_handshake=True) - assert len(appdata) == 0 - return ssldata - - def shutdown(self, callback=None): - """Start the SSL shutdown sequence. - - Return a list of ssldata. A ssldata element is a list of buffers - - The optional *callback* argument can be used to install a callback that - will be called when the shutdown is complete. The callback will be - called without arguments. - """ - if self._state == _UNWRAPPED: - raise RuntimeError('no security layer present') - if self._state == _SHUTDOWN: - raise RuntimeError('shutdown in progress') - assert self._state in (_WRAPPED, _DO_HANDSHAKE) - self._state = _SHUTDOWN - self._shutdown_cb = callback - ssldata, appdata = self.feed_ssldata(b'') - assert appdata == [] or appdata == [b''] - return ssldata - - def feed_eof(self): - """Send a potentially "ragged" EOF. - - This method will raise an SSL_ERROR_EOF exception if the EOF is - unexpected. - """ - self._incoming.write_eof() - ssldata, appdata = self.feed_ssldata(b'') - assert appdata == [] or appdata == [b''] - - def feed_ssldata(self, data, only_handshake=False): - """Feed SSL record level data into the pipe. - - The data must be a bytes instance. It is OK to send an empty bytes - instance. This can be used to get ssldata for a handshake initiated by - this endpoint. - - Return a (ssldata, appdata) tuple. The ssldata element is a list of - buffers containing SSL data that needs to be sent to the remote SSL. - - The appdata element is a list of buffers containing plaintext data that - needs to be forwarded to the application. The appdata list may contain - an empty buffer indicating an SSL "close_notify" alert. This alert must - be acknowledged by calling shutdown(). - """ - if self._state == _UNWRAPPED: - # If unwrapped, pass plaintext data straight through. - if data: - appdata = [data] - else: - appdata = [] - return ([], appdata) - - self._need_ssldata = False - if data: - self._incoming.write(data) - - ssldata = [] - appdata = [] - try: - if self._state == _DO_HANDSHAKE: - # Call do_handshake() until it doesn't raise anymore. - self._sslobj.do_handshake() - self._state = _WRAPPED - if self._handshake_cb: - self._handshake_cb(None) - if only_handshake: - return (ssldata, appdata) - # Handshake done: execute the wrapped block - - if self._state == _WRAPPED: - # Main state: read data from SSL until close_notify - while True: - chunk = self._sslobj.read(self.max_size) - appdata.append(chunk) - if not chunk: # close_notify - break - - elif self._state == _SHUTDOWN: - # Call shutdown() until it doesn't raise anymore. - self._sslobj.unwrap() - self._sslobj = None - self._state = _UNWRAPPED - if self._shutdown_cb: - self._shutdown_cb() - - elif self._state == _UNWRAPPED: - # Drain possible plaintext data after close_notify. - appdata.append(self._incoming.read()) - except (ssl.SSLError, ssl.CertificateError) as exc: - exc_errno = getattr(exc, 'errno', None) - if exc_errno not in ( - ssl.SSL_ERROR_WANT_READ, ssl.SSL_ERROR_WANT_WRITE, - ssl.SSL_ERROR_SYSCALL): - if self._state == _DO_HANDSHAKE and self._handshake_cb: - self._handshake_cb(exc) - raise - self._need_ssldata = (exc_errno == ssl.SSL_ERROR_WANT_READ) - - # Check for record level data that needs to be sent back. - # Happens for the initial handshake and renegotiations. - if self._outgoing.pending: - ssldata.append(self._outgoing.read()) - return (ssldata, appdata) - - def feed_appdata(self, data, offset=0): - """Feed plaintext data into the pipe. - - Return an (ssldata, offset) tuple. The ssldata element is a list of - buffers containing record level data that needs to be sent to the - remote SSL instance. The offset is the number of plaintext bytes that - were processed, which may be less than the length of data. - - NOTE: In case of short writes, this call MUST be retried with the SAME - buffer passed into the *data* argument (i.e. the id() must be the - same). This is an OpenSSL requirement. A further particularity is that - a short write will always have offset == 0, because the _ssl module - does not enable partial writes. And even though the offset is zero, - there will still be encrypted data in ssldata. - """ - assert 0 <= offset <= len(data) - if self._state == _UNWRAPPED: - # pass through data in unwrapped mode - if offset < len(data): - ssldata = [data[offset:]] - else: - ssldata = [] - return (ssldata, len(data)) - - ssldata = [] - view = memoryview(data) - while True: - self._need_ssldata = False - try: - if offset < len(view): - offset += self._sslobj.write(view[offset:]) - except ssl.SSLError as exc: - # It is not allowed to call write() after unwrap() until the - # close_notify is acknowledged. We return the condition to the - # caller as a short write. - exc_errno = getattr(exc, 'errno', None) - if exc.reason == 'PROTOCOL_IS_SHUTDOWN': - exc_errno = exc.errno = ssl.SSL_ERROR_WANT_READ - if exc_errno not in (ssl.SSL_ERROR_WANT_READ, - ssl.SSL_ERROR_WANT_WRITE, - ssl.SSL_ERROR_SYSCALL): - raise - self._need_ssldata = (exc_errno == ssl.SSL_ERROR_WANT_READ) - - # See if there's any record level data back for us. - if self._outgoing.pending: - ssldata.append(self._outgoing.read()) - if offset == len(view) or self._need_ssldata: - break - return (ssldata, offset) + return hi, lo class _SSLProtocolTransport(transports._FlowControlMixin, transports.Transport): + _start_tls_compatible = True _sendfile_compatible = constants._SendfileMode.FALLBACK def __init__(self, loop, ssl_protocol): self._loop = loop - # SSLProtocol instance self._ssl_protocol = ssl_protocol self._closed = False @@ -312,19 +107,21 @@ class _SSLProtocolTransport(transports._FlowControlMixin, protocol's connection_lost() method will (eventually) called with None as its argument. """ - self._closed = True - self._ssl_protocol._start_shutdown() - - def __del__(self, _warn=warnings.warn): if not self._closed: - _warn(f"unclosed transport {self!r}", ResourceWarning, source=self) - self.close() + self._closed = True + self._ssl_protocol._start_shutdown() + else: + self._ssl_protocol = None + + def __del__(self, _warnings=warnings): + if not self._closed: + self._closed = True + _warnings.warn( + "unclosed transport ", ResourceWarning) def is_reading(self): - tr = self._ssl_protocol._transport - if tr is None: - raise RuntimeError('SSL transport has not been initialized yet') - return tr.is_reading() + return not self._ssl_protocol._app_reading_paused def pause_reading(self): """Pause the receiving end. @@ -332,7 +129,7 @@ class _SSLProtocolTransport(transports._FlowControlMixin, No data will be passed to the protocol's data_received() method until resume_reading() is called. """ - self._ssl_protocol._transport.pause_reading() + self._ssl_protocol._pause_reading() def resume_reading(self): """Resume the receiving end. @@ -340,7 +137,7 @@ class _SSLProtocolTransport(transports._FlowControlMixin, Data received will once again be passed to the protocol's data_received() method. """ - self._ssl_protocol._transport.resume_reading() + self._ssl_protocol._resume_reading() def set_write_buffer_limits(self, high=None, low=None): """Set the high- and low-water limits for write flow control. @@ -361,16 +158,51 @@ class _SSLProtocolTransport(transports._FlowControlMixin, reduces opportunities for doing I/O and computation concurrently. """ - self._ssl_protocol._transport.set_write_buffer_limits(high, low) + self._ssl_protocol._set_write_buffer_limits(high, low) + self._ssl_protocol._control_app_writing() + + def get_write_buffer_limits(self): + return (self._ssl_protocol._outgoing_low_water, + self._ssl_protocol._outgoing_high_water) def get_write_buffer_size(self): - """Return the current size of the write buffer.""" - return self._ssl_protocol._transport.get_write_buffer_size() + """Return the current size of the write buffers.""" + return self._ssl_protocol._get_write_buffer_size() + + def set_read_buffer_limits(self, high=None, low=None): + """Set the high- and low-water limits for read flow control. + + These two values control when to call the upstream transport's + pause_reading() and resume_reading() methods. If specified, + the low-water limit must be less than or equal to the + high-water limit. Neither value can be negative. + + The defaults are implementation-specific. If only the + high-water limit is given, the low-water limit defaults to an + implementation-specific value less than or equal to the + high-water limit. Setting high to zero forces low to zero as + well, and causes pause_reading() to be called whenever the + buffer becomes non-empty. Setting low to zero causes + resume_reading() to be called only once the buffer is empty. + Use of zero for either limit is generally sub-optimal as it + reduces opportunities for doing I/O and computation + concurrently. + """ + self._ssl_protocol._set_read_buffer_limits(high, low) + self._ssl_protocol._control_ssl_reading() + + def get_read_buffer_limits(self): + return (self._ssl_protocol._incoming_low_water, + self._ssl_protocol._incoming_high_water) + + def get_read_buffer_size(self): + """Return the current size of the read buffer.""" + return self._ssl_protocol._get_read_buffer_size() @property def _protocol_paused(self): # Required for sendfile fallback pause_writing/resume_writing logic - return self._ssl_protocol._transport._protocol_paused + return self._ssl_protocol._app_writing_paused def write(self, data): """Write some data bytes to the transport. @@ -383,7 +215,22 @@ class _SSLProtocolTransport(transports._FlowControlMixin, f"got {type(data).__name__}") if not data: return - self._ssl_protocol._write_appdata(data) + self._ssl_protocol._write_appdata((data,)) + + def writelines(self, list_of_data): + """Write a list (or any iterable) of data bytes to the transport. + + The default implementation concatenates the arguments and + calls write() on the result. + """ + self._ssl_protocol._write_appdata(list_of_data) + + def write_eof(self): + """Close the write end after flushing buffered data. + + This raises :exc:`NotImplementedError` right now. + """ + raise NotImplementedError def can_write_eof(self): """Return True if this transport supports write_eof(), False if not.""" @@ -396,23 +243,36 @@ class _SSLProtocolTransport(transports._FlowControlMixin, The protocol's connection_lost() method will (eventually) be called with None as its argument. """ - self._ssl_protocol._abort() self._closed = True + self._ssl_protocol._abort() + + def _force_close(self, exc): + self._closed = True + self._ssl_protocol._abort(exc) + + def _test__append_write_backlog(self, data): + # for test only + self._ssl_protocol._write_backlog.append(data) + self._ssl_protocol._write_buffer_size += len(data) -class SSLProtocol(protocols.Protocol): - """SSL protocol. +class SSLProtocol(protocols.BufferedProtocol): + max_size = 256 * 1024 # Buffer size passed to read() - Implementation of SSL on top of a socket using incoming and outgoing - buffers which are ssl.MemoryBIO objects. - """ + _handshake_start_time = None + _handshake_timeout_handle = None + _shutdown_timeout_handle = None def __init__(self, loop, app_protocol, sslcontext, waiter, server_side=False, server_hostname=None, call_connection_made=True, - ssl_handshake_timeout=None): + ssl_handshake_timeout=None, + ssl_shutdown_timeout=None): if ssl is None: - raise RuntimeError('stdlib ssl module not available') + raise RuntimeError("stdlib ssl module not available") + + self._ssl_buffer = bytearray(self.max_size) + self._ssl_buffer_view = memoryview(self._ssl_buffer) if ssl_handshake_timeout is None: ssl_handshake_timeout = constants.SSL_HANDSHAKE_TIMEOUT @@ -420,6 +280,12 @@ class SSLProtocol(protocols.Protocol): raise ValueError( f"ssl_handshake_timeout should be a positive number, " f"got {ssl_handshake_timeout}") + if ssl_shutdown_timeout is None: + ssl_shutdown_timeout = constants.SSL_SHUTDOWN_TIMEOUT + elif ssl_shutdown_timeout <= 0: + raise ValueError( + f"ssl_shutdown_timeout should be a positive number, " + f"got {ssl_shutdown_timeout}") if not sslcontext: sslcontext = _create_transport_context( @@ -442,21 +308,54 @@ class SSLProtocol(protocols.Protocol): self._waiter = waiter self._loop = loop self._set_app_protocol(app_protocol) - self._app_transport = _SSLProtocolTransport(self._loop, self) - # _SSLPipe instance (None until the connection is made) - self._sslpipe = None - self._session_established = False - self._in_handshake = False - self._in_shutdown = False + self._app_transport = None + self._app_transport_created = False # transport, ex: SelectorSocketTransport self._transport = None - self._call_connection_made = call_connection_made self._ssl_handshake_timeout = ssl_handshake_timeout + self._ssl_shutdown_timeout = ssl_shutdown_timeout + # SSL and state machine + self._incoming = ssl.MemoryBIO() + self._outgoing = ssl.MemoryBIO() + self._state = SSLProtocolState.UNWRAPPED + self._conn_lost = 0 # Set when connection_lost called + if call_connection_made: + self._app_state = AppProtocolState.STATE_INIT + else: + self._app_state = AppProtocolState.STATE_CON_MADE + self._sslobj = self._sslcontext.wrap_bio( + self._incoming, self._outgoing, + server_side=self._server_side, + server_hostname=self._server_hostname) + + # Flow Control + + self._ssl_writing_paused = False + + self._app_reading_paused = False + + self._ssl_reading_paused = False + self._incoming_high_water = 0 + self._incoming_low_water = 0 + self._set_read_buffer_limits() + self._eof_received = False + + self._app_writing_paused = False + self._outgoing_high_water = 0 + self._outgoing_low_water = 0 + self._set_write_buffer_limits() + self._get_app_transport() def _set_app_protocol(self, app_protocol): self._app_protocol = app_protocol - self._app_protocol_is_buffer = \ - isinstance(app_protocol, protocols.BufferedProtocol) + # Make fast hasattr check first + if (hasattr(app_protocol, 'get_buffer') and + isinstance(app_protocol, protocols.BufferedProtocol)): + self._app_protocol_get_buffer = app_protocol.get_buffer + self._app_protocol_buffer_updated = app_protocol.buffer_updated + self._app_protocol_is_buffer = True + else: + self._app_protocol_is_buffer = False def _wakeup_waiter(self, exc=None): if self._waiter is None: @@ -468,15 +367,20 @@ class SSLProtocol(protocols.Protocol): self._waiter.set_result(None) self._waiter = None + def _get_app_transport(self): + if self._app_transport is None: + if self._app_transport_created: + raise RuntimeError('Creating _SSLProtocolTransport twice') + self._app_transport = _SSLProtocolTransport(self._loop, self) + self._app_transport_created = True + return self._app_transport + def connection_made(self, transport): """Called when the low-level connection is made. Start the SSL handshake. """ self._transport = transport - self._sslpipe = _SSLPipe(self._sslcontext, - self._server_side, - self._server_hostname) self._start_handshake() def connection_lost(self, exc): @@ -486,72 +390,58 @@ class SSLProtocol(protocols.Protocol): meaning a regular EOF is received or the connection was aborted or closed). """ - if self._session_established: - self._session_established = False - self._loop.call_soon(self._app_protocol.connection_lost, exc) - else: - # Most likely an exception occurred while in SSL handshake. - # Just mark the app transport as closed so that its __del__ - # doesn't complain. - if self._app_transport is not None: - self._app_transport._closed = True + self._write_backlog.clear() + self._outgoing.read() + self._conn_lost += 1 + + # Just mark the app transport as closed so that its __dealloc__ + # doesn't complain. + if self._app_transport is not None: + self._app_transport._closed = True + + if self._state != SSLProtocolState.DO_HANDSHAKE: + if ( + self._app_state == AppProtocolState.STATE_CON_MADE or + self._app_state == AppProtocolState.STATE_EOF + ): + self._app_state = AppProtocolState.STATE_CON_LOST + self._loop.call_soon(self._app_protocol.connection_lost, exc) + self._set_state(SSLProtocolState.UNWRAPPED) self._transport = None self._app_transport = None - if getattr(self, '_handshake_timeout_handle', None): - self._handshake_timeout_handle.cancel() - self._wakeup_waiter(exc) self._app_protocol = None - self._sslpipe = None + self._wakeup_waiter(exc) - def pause_writing(self): - """Called when the low-level transport's buffer goes over - the high-water mark. - """ - self._app_protocol.pause_writing() + if self._shutdown_timeout_handle: + self._shutdown_timeout_handle.cancel() + self._shutdown_timeout_handle = None + if self._handshake_timeout_handle: + self._handshake_timeout_handle.cancel() + self._handshake_timeout_handle = None - def resume_writing(self): - """Called when the low-level transport's buffer drains below - the low-water mark. - """ - self._app_protocol.resume_writing() + def get_buffer(self, n): + want = n + if want <= 0 or want > self.max_size: + want = self.max_size + if len(self._ssl_buffer) < want: + self._ssl_buffer = bytearray(want) + self._ssl_buffer_view = memoryview(self._ssl_buffer) + return self._ssl_buffer_view - def data_received(self, data): - """Called when some SSL data is received. + def buffer_updated(self, nbytes): + self._incoming.write(self._ssl_buffer_view[:nbytes]) - The argument is a bytes object. - """ - if self._sslpipe is None: - # transport closing, sslpipe is destroyed - return + if self._state == SSLProtocolState.DO_HANDSHAKE: + self._do_handshake() - try: - ssldata, appdata = self._sslpipe.feed_ssldata(data) - except (SystemExit, KeyboardInterrupt): - raise - except BaseException as e: - self._fatal_error(e, 'SSL error in data received') - return + elif self._state == SSLProtocolState.WRAPPED: + self._do_read() - for chunk in ssldata: - self._transport.write(chunk) + elif self._state == SSLProtocolState.FLUSHING: + self._do_flush() - for chunk in appdata: - if chunk: - try: - if self._app_protocol_is_buffer: - protocols._feed_data_to_buffered_proto( - self._app_protocol, chunk) - else: - self._app_protocol.data_received(chunk) - except (SystemExit, KeyboardInterrupt): - raise - except BaseException as ex: - self._fatal_error( - ex, 'application protocol failed to receive SSL data') - return - else: - self._start_shutdown() - break + elif self._state == SSLProtocolState.SHUTDOWN: + self._do_shutdown() def eof_received(self): """Called when the other end of the low-level stream @@ -561,19 +451,32 @@ class SSLProtocol(protocols.Protocol): will close itself. If it returns a true value, closing the transport is up to the protocol. """ + self._eof_received = True try: if self._loop.get_debug(): logger.debug("%r received EOF", self) - self._wakeup_waiter(ConnectionResetError) + if self._state == SSLProtocolState.DO_HANDSHAKE: + self._on_handshake_complete(ConnectionResetError) - if not self._in_handshake: - keep_open = self._app_protocol.eof_received() - if keep_open: - logger.warning('returning true from eof_received() ' - 'has no effect when using ssl') - finally: + elif self._state == SSLProtocolState.WRAPPED: + self._set_state(SSLProtocolState.FLUSHING) + if self._app_reading_paused: + return True + else: + self._do_flush() + + elif self._state == SSLProtocolState.FLUSHING: + self._do_write() + self._set_state(SSLProtocolState.SHUTDOWN) + self._do_shutdown() + + elif self._state == SSLProtocolState.SHUTDOWN: + self._do_shutdown() + + except Exception: self._transport.close() + raise def _get_extra_info(self, name, default=None): if name in self._extra: @@ -583,19 +486,45 @@ class SSLProtocol(protocols.Protocol): else: return default - def _start_shutdown(self): - if self._in_shutdown: - return - if self._in_handshake: - self._abort() - else: - self._in_shutdown = True - self._write_appdata(b'') + def _set_state(self, new_state): + allowed = False - def _write_appdata(self, data): - self._write_backlog.append((data, 0)) - self._write_buffer_size += len(data) - self._process_write_backlog() + if new_state == SSLProtocolState.UNWRAPPED: + allowed = True + + elif ( + self._state == SSLProtocolState.UNWRAPPED and + new_state == SSLProtocolState.DO_HANDSHAKE + ): + allowed = True + + elif ( + self._state == SSLProtocolState.DO_HANDSHAKE and + new_state == SSLProtocolState.WRAPPED + ): + allowed = True + + elif ( + self._state == SSLProtocolState.WRAPPED and + new_state == SSLProtocolState.FLUSHING + ): + allowed = True + + elif ( + self._state == SSLProtocolState.FLUSHING and + new_state == SSLProtocolState.SHUTDOWN + ): + allowed = True + + if allowed: + self._state = new_state + + else: + raise RuntimeError( + 'cannot switch state from {} to {}'.format( + self._state, new_state)) + + # Handshake flow def _start_handshake(self): if self._loop.get_debug(): @@ -603,17 +532,18 @@ class SSLProtocol(protocols.Protocol): self._handshake_start_time = self._loop.time() else: self._handshake_start_time = None - self._in_handshake = True - # (b'', 1) is a special value in _process_write_backlog() to do - # the SSL handshake - self._write_backlog.append((b'', 1)) + + self._set_state(SSLProtocolState.DO_HANDSHAKE) + + # start handshake timeout count down self._handshake_timeout_handle = \ self._loop.call_later(self._ssl_handshake_timeout, - self._check_handshake_timeout) - self._process_write_backlog() + lambda: self._check_handshake_timeout()) + + self._do_handshake() def _check_handshake_timeout(self): - if self._in_handshake is True: + if self._state == SSLProtocolState.DO_HANDSHAKE: msg = ( f"SSL handshake is taking longer than " f"{self._ssl_handshake_timeout} seconds: " @@ -621,24 +551,37 @@ class SSLProtocol(protocols.Protocol): ) self._fatal_error(ConnectionAbortedError(msg)) - def _on_handshake_complete(self, handshake_exc): - self._in_handshake = False - self._handshake_timeout_handle.cancel() - - sslobj = self._sslpipe.ssl_object + def _do_handshake(self): try: - if handshake_exc is not None: + self._sslobj.do_handshake() + except SSLAgainErrors: + self._process_outgoing() + except ssl.SSLError as exc: + self._on_handshake_complete(exc) + else: + self._on_handshake_complete(None) + + def _on_handshake_complete(self, handshake_exc): + if self._handshake_timeout_handle is not None: + self._handshake_timeout_handle.cancel() + self._handshake_timeout_handle = None + + sslobj = self._sslobj + try: + if handshake_exc is None: + self._set_state(SSLProtocolState.WRAPPED) + else: raise handshake_exc peercert = sslobj.getpeercert() - except (SystemExit, KeyboardInterrupt): - raise - except BaseException as exc: + except Exception as exc: + self._set_state(SSLProtocolState.UNWRAPPED) if isinstance(exc, ssl.CertificateError): msg = 'SSL handshake failed on verifying the certificate' else: msg = 'SSL handshake failed' self._fatal_error(exc, msg) + self._wakeup_waiter(exc) return if self._loop.get_debug(): @@ -649,85 +592,330 @@ class SSLProtocol(protocols.Protocol): self._extra.update(peercert=peercert, cipher=sslobj.cipher(), compression=sslobj.compression(), - ssl_object=sslobj, - ) - if self._call_connection_made: - self._app_protocol.connection_made(self._app_transport) + ssl_object=sslobj) + if self._app_state == AppProtocolState.STATE_INIT: + self._app_state = AppProtocolState.STATE_CON_MADE + self._app_protocol.connection_made(self._get_app_transport()) self._wakeup_waiter() - self._session_established = True - # In case transport.write() was already called. Don't call - # immediately _process_write_backlog(), but schedule it: - # _on_handshake_complete() can be called indirectly from - # _process_write_backlog(), and _process_write_backlog() is not - # reentrant. - self._loop.call_soon(self._process_write_backlog) + self._do_read() - def _process_write_backlog(self): - # Try to make progress on the write backlog. - if self._transport is None or self._sslpipe is None: + # Shutdown flow + + def _start_shutdown(self): + if ( + self._state in ( + SSLProtocolState.FLUSHING, + SSLProtocolState.SHUTDOWN, + SSLProtocolState.UNWRAPPED + ) + ): + return + if self._app_transport is not None: + self._app_transport._closed = True + if self._state == SSLProtocolState.DO_HANDSHAKE: + self._abort() + else: + self._set_state(SSLProtocolState.FLUSHING) + self._shutdown_timeout_handle = self._loop.call_later( + self._ssl_shutdown_timeout, + lambda: self._check_shutdown_timeout() + ) + self._do_flush() + + def _check_shutdown_timeout(self): + if ( + self._state in ( + SSLProtocolState.FLUSHING, + SSLProtocolState.SHUTDOWN + ) + ): + self._transport._force_close( + exceptions.TimeoutError('SSL shutdown timed out')) + + def _do_flush(self): + self._do_read() + self._set_state(SSLProtocolState.SHUTDOWN) + self._do_shutdown() + + def _do_shutdown(self): + try: + if not self._eof_received: + self._sslobj.unwrap() + except SSLAgainErrors: + self._process_outgoing() + except ssl.SSLError as exc: + self._on_shutdown_complete(exc) + else: + self._process_outgoing() + self._call_eof_received() + self._on_shutdown_complete(None) + + def _on_shutdown_complete(self, shutdown_exc): + if self._shutdown_timeout_handle is not None: + self._shutdown_timeout_handle.cancel() + self._shutdown_timeout_handle = None + + if shutdown_exc: + self._fatal_error(shutdown_exc) + else: + self._loop.call_soon(self._transport.close) + + def _abort(self): + self._set_state(SSLProtocolState.UNWRAPPED) + if self._transport is not None: + self._transport.abort() + + # Outgoing flow + + def _write_appdata(self, list_of_data): + if ( + self._state in ( + SSLProtocolState.FLUSHING, + SSLProtocolState.SHUTDOWN, + SSLProtocolState.UNWRAPPED + ) + ): + if self._conn_lost >= constants.LOG_THRESHOLD_FOR_CONNLOST_WRITES: + logger.warning('SSL connection is closed') + self._conn_lost += 1 return + for data in list_of_data: + self._write_backlog.append(data) + self._write_buffer_size += len(data) + try: - for i in range(len(self._write_backlog)): - data, offset = self._write_backlog[0] - if data: - ssldata, offset = self._sslpipe.feed_appdata(data, offset) - elif offset: - ssldata = self._sslpipe.do_handshake( - self._on_handshake_complete) - offset = 1 + if self._state == SSLProtocolState.WRAPPED: + self._do_write() + + except Exception as ex: + self._fatal_error(ex, 'Fatal error on SSL protocol') + + def _do_write(self): + try: + while self._write_backlog: + data = self._write_backlog[0] + count = self._sslobj.write(data) + data_len = len(data) + if count < data_len: + self._write_backlog[0] = data[count:] + self._write_buffer_size -= count else: - ssldata = self._sslpipe.shutdown(self._finalize) - offset = 1 + del self._write_backlog[0] + self._write_buffer_size -= data_len + except SSLAgainErrors: + pass + self._process_outgoing() - for chunk in ssldata: - self._transport.write(chunk) + def _process_outgoing(self): + if not self._ssl_writing_paused: + data = self._outgoing.read() + if len(data): + self._transport.write(data) + self._control_app_writing() - if offset < len(data): - self._write_backlog[0] = (data, offset) - # A short write means that a write is blocked on a read - # We need to enable reading if it is paused! - assert self._sslpipe.need_ssldata - if self._transport._paused: - self._transport.resume_reading() + # Incoming flow + + def _do_read(self): + if ( + self._state not in ( + SSLProtocolState.WRAPPED, + SSLProtocolState.FLUSHING, + ) + ): + return + try: + if not self._app_reading_paused: + if self._app_protocol_is_buffer: + self._do_read__buffered() + else: + self._do_read__copied() + if self._write_backlog: + self._do_write() + else: + self._process_outgoing() + self._control_ssl_reading() + except Exception as ex: + self._fatal_error(ex, 'Fatal error on SSL protocol') + + def _do_read__buffered(self): + offset = 0 + count = 1 + + buf = self._app_protocol_get_buffer(self._get_read_buffer_size()) + wants = len(buf) + + try: + count = self._sslobj.read(wants, buf) + + if count > 0: + offset = count + while offset < wants: + count = self._sslobj.read(wants - offset, buf[offset:]) + if count > 0: + offset += count + else: + break + else: + self._loop.call_soon(lambda: self._do_read()) + except SSLAgainErrors: + pass + if offset > 0: + self._app_protocol_buffer_updated(offset) + if not count: + # close_notify + self._call_eof_received() + self._start_shutdown() + + def _do_read__copied(self): + chunk = b'1' + zero = True + one = False + + try: + while True: + chunk = self._sslobj.read(self.max_size) + if not chunk: break + if zero: + zero = False + one = True + first = chunk + elif one: + one = False + data = [first, chunk] + else: + data.append(chunk) + except SSLAgainErrors: + pass + if one: + self._app_protocol.data_received(first) + elif not zero: + self._app_protocol.data_received(b''.join(data)) + if not chunk: + # close_notify + self._call_eof_received() + self._start_shutdown() - # An entire chunk from the backlog was processed. We can - # delete it and reduce the outstanding buffer size. - del self._write_backlog[0] - self._write_buffer_size -= len(data) - except (SystemExit, KeyboardInterrupt): + def _call_eof_received(self): + try: + if self._app_state == AppProtocolState.STATE_CON_MADE: + self._app_state = AppProtocolState.STATE_EOF + keep_open = self._app_protocol.eof_received() + if keep_open: + logger.warning('returning true from eof_received() ' + 'has no effect when using ssl') + except (KeyboardInterrupt, SystemExit): raise - except BaseException as exc: - if self._in_handshake: - # Exceptions will be re-raised in _on_handshake_complete. - self._on_handshake_complete(exc) - else: - self._fatal_error(exc, 'Fatal error on SSL transport') + except BaseException as ex: + self._fatal_error(ex, 'Error calling eof_received()') + + # Flow control for writes from APP socket + + def _control_app_writing(self): + size = self._get_write_buffer_size() + if size >= self._outgoing_high_water and not self._app_writing_paused: + self._app_writing_paused = True + try: + self._app_protocol.pause_writing() + except (KeyboardInterrupt, SystemExit): + raise + except BaseException as exc: + self._loop.call_exception_handler({ + 'message': 'protocol.pause_writing() failed', + 'exception': exc, + 'transport': self._app_transport, + 'protocol': self, + }) + elif size <= self._outgoing_low_water and self._app_writing_paused: + self._app_writing_paused = False + try: + self._app_protocol.resume_writing() + except (KeyboardInterrupt, SystemExit): + raise + except BaseException as exc: + self._loop.call_exception_handler({ + 'message': 'protocol.resume_writing() failed', + 'exception': exc, + 'transport': self._app_transport, + 'protocol': self, + }) + + def _get_write_buffer_size(self): + return self._outgoing.pending + self._write_buffer_size + + def _set_write_buffer_limits(self, high=None, low=None): + high, low = add_flowcontrol_defaults( + high, low, constants.FLOW_CONTROL_HIGH_WATER_SSL_WRITE) + self._outgoing_high_water = high + self._outgoing_low_water = low + + # Flow control for reads to APP socket + + def _pause_reading(self): + self._app_reading_paused = True + + def _resume_reading(self): + if self._app_reading_paused: + self._app_reading_paused = False + + def resume(): + if self._state == SSLProtocolState.WRAPPED: + self._do_read() + elif self._state == SSLProtocolState.FLUSHING: + self._do_flush() + elif self._state == SSLProtocolState.SHUTDOWN: + self._do_shutdown() + self._loop.call_soon(resume) + + # Flow control for reads from SSL socket + + def _control_ssl_reading(self): + size = self._get_read_buffer_size() + if size >= self._incoming_high_water and not self._ssl_reading_paused: + self._ssl_reading_paused = True + self._transport.pause_reading() + elif size <= self._incoming_low_water and self._ssl_reading_paused: + self._ssl_reading_paused = False + self._transport.resume_reading() + + def _set_read_buffer_limits(self, high=None, low=None): + high, low = add_flowcontrol_defaults( + high, low, constants.FLOW_CONTROL_HIGH_WATER_SSL_READ) + self._incoming_high_water = high + self._incoming_low_water = low + + def _get_read_buffer_size(self): + return self._incoming.pending + + # Flow control for writes to SSL socket + + def pause_writing(self): + """Called when the low-level transport's buffer goes over + the high-water mark. + """ + assert not self._ssl_writing_paused + self._ssl_writing_paused = True + + def resume_writing(self): + """Called when the low-level transport's buffer drains below + the low-water mark. + """ + assert self._ssl_writing_paused + self._ssl_writing_paused = False + self._process_outgoing() def _fatal_error(self, exc, message='Fatal error on transport'): + if self._transport: + self._transport._force_close(exc) + if isinstance(exc, OSError): if self._loop.get_debug(): logger.debug("%r: %s", self, message, exc_info=True) - else: + elif not isinstance(exc, exceptions.CancelledError): self._loop.call_exception_handler({ 'message': message, 'exception': exc, 'transport': self._transport, 'protocol': self, }) - if self._transport: - self._transport._force_close(exc) - - def _finalize(self): - self._sslpipe = None - - if self._transport is not None: - self._transport.close() - - def _abort(self): - try: - if self._transport is not None: - self._transport.abort() - finally: - self._finalize() diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index 080d8a62cde..0f9098b4195 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -2,9 +2,9 @@ __all__ = ( 'StreamReader', 'StreamWriter', 'StreamReaderProtocol', 'open_connection', 'start_server') +import collections import socket import sys -import warnings import weakref if hasattr(socket, 'AF_UNIX'): @@ -125,11 +125,11 @@ class FlowControlMixin(protocols.Protocol): def __init__(self, loop=None): if loop is None: - self._loop = events._get_event_loop(stacklevel=4) + self._loop = events.get_event_loop() else: self._loop = loop self._paused = False - self._drain_waiter = None + self._drain_waiters = collections.deque() self._connection_lost = False def pause_writing(self): @@ -144,38 +144,34 @@ class FlowControlMixin(protocols.Protocol): if self._loop.get_debug(): logger.debug("%r resumes writing", self) - waiter = self._drain_waiter - if waiter is not None: - self._drain_waiter = None + for waiter in self._drain_waiters: if not waiter.done(): waiter.set_result(None) def connection_lost(self, exc): self._connection_lost = True - # Wake up the writer if currently paused. + # Wake up the writer(s) if currently paused. if not self._paused: return - waiter = self._drain_waiter - if waiter is None: - return - self._drain_waiter = None - if waiter.done(): - return - if exc is None: - waiter.set_result(None) - else: - waiter.set_exception(exc) + + for waiter in self._drain_waiters: + if not waiter.done(): + if exc is None: + waiter.set_result(None) + else: + waiter.set_exception(exc) async def _drain_helper(self): if self._connection_lost: raise ConnectionResetError('Connection lost') if not self._paused: return - waiter = self._drain_waiter - assert waiter is None or waiter.cancelled() waiter = self._loop.create_future() - self._drain_waiter = waiter - await waiter + self._drain_waiters.append(waiter) + try: + await waiter + finally: + self._drain_waiters.remove(waiter) def _get_close_waiter(self, stream): raise NotImplementedError @@ -206,6 +202,7 @@ class StreamReaderProtocol(FlowControlMixin, protocols.Protocol): self._strong_reader = stream_reader self._reject_connection = False self._stream_writer = None + self._task = None self._transport = None self._client_connected_cb = client_connected_cb self._over_ssl = False @@ -217,6 +214,13 @@ class StreamReaderProtocol(FlowControlMixin, protocols.Protocol): return None return self._stream_reader_wr() + def _replace_writer(self, writer): + loop = self._loop + transport = writer.transport + self._stream_writer = writer + self._transport = transport + self._over_ssl = transport.get_extra_info('sslcontext') is not None + def connection_made(self, transport): if self._reject_connection: context = { @@ -241,7 +245,7 @@ class StreamReaderProtocol(FlowControlMixin, protocols.Protocol): res = self._client_connected_cb(reader, self._stream_writer) if coroutines.iscoroutine(res): - self._loop.create_task(res) + self._task = self._loop.create_task(res) self._strong_reader = None def connection_lost(self, exc): @@ -259,6 +263,7 @@ class StreamReaderProtocol(FlowControlMixin, protocols.Protocol): super().connection_lost(exc) self._stream_reader_wr = None self._stream_writer = None + self._task = None self._transport = None def data_received(self, data): @@ -371,6 +376,20 @@ class StreamWriter: await sleep(0) await self._protocol._drain_helper() + async def start_tls(self, sslcontext, *, + server_hostname=None, + ssl_handshake_timeout=None): + """Upgrade an existing stream-based connection to TLS.""" + server_side = self._protocol._client_connected_cb is not None + protocol = self._protocol + await self.drain() + new_transport = await self._loop.start_tls( # type: ignore + self._transport, protocol, sslcontext, + server_side=server_side, server_hostname=server_hostname, + ssl_handshake_timeout=ssl_handshake_timeout) + self._transport = new_transport + protocol._replace_writer(self) + class StreamReader: @@ -385,7 +404,7 @@ class StreamReader: self._limit = limit if loop is None: - self._loop = events._get_event_loop() + self._loop = events.get_event_loop() else: self._loop = loop self._buffer = bytearray() @@ -669,7 +688,7 @@ class StreamReader: await self._wait_for_data('read') # This will work right even if buffer is less than n bytes - data = bytes(self._buffer[:n]) + data = bytes(memoryview(self._buffer)[:n]) del self._buffer[:n] self._maybe_resume_transport() @@ -711,7 +730,7 @@ class StreamReader: data = bytes(self._buffer) self._buffer.clear() else: - data = bytes(self._buffer[:n]) + data = bytes(memoryview(self._buffer)[:n]) del self._buffer[:n] self._maybe_resume_transport() return data diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py new file mode 100644 index 00000000000..911419e1769 --- /dev/null +++ b/Lib/asyncio/taskgroups.py @@ -0,0 +1,218 @@ +# Adapted with permission from the EdgeDB project; +# license: PSFL. + + +__all__ = ["TaskGroup"] + +from . import events +from . import exceptions +from . import tasks + + +class TaskGroup: + + def __init__(self): + self._entered = False + self._exiting = False + self._aborting = False + self._loop = None + self._parent_task = None + self._parent_cancel_requested = False + self._tasks = set() + self._errors = [] + self._base_error = None + self._on_completed_fut = None + + def __repr__(self): + info = [''] + if self._tasks: + info.append(f'tasks={len(self._tasks)}') + if self._errors: + info.append(f'errors={len(self._errors)}') + if self._aborting: + info.append('cancelling') + elif self._entered: + info.append('entered') + + info_str = ' '.join(info) + return f'' + + async def __aenter__(self): + if self._entered: + raise RuntimeError( + f"TaskGroup {self!r} has been already entered") + self._entered = True + + if self._loop is None: + self._loop = events.get_running_loop() + + self._parent_task = tasks.current_task(self._loop) + if self._parent_task is None: + raise RuntimeError( + f'TaskGroup {self!r} cannot determine the parent task') + + return self + + async def __aexit__(self, et, exc, tb): + self._exiting = True + + if (exc is not None and + self._is_base_error(exc) and + self._base_error is None): + self._base_error = exc + + propagate_cancellation_error = \ + exc if et is exceptions.CancelledError else None + if self._parent_cancel_requested: + # If this flag is set we *must* call uncancel(). + if self._parent_task.uncancel() == 0: + # If there are no pending cancellations left, + # don't propagate CancelledError. + propagate_cancellation_error = None + + if et is not None: + if not self._aborting: + # Our parent task is being cancelled: + # + # async with TaskGroup() as g: + # g.create_task(...) + # await ... # <- CancelledError + # + # or there's an exception in "async with": + # + # async with TaskGroup() as g: + # g.create_task(...) + # 1 / 0 + # + self._abort() + + # We use while-loop here because "self._on_completed_fut" + # can be cancelled multiple times if our parent task + # is being cancelled repeatedly (or even once, when + # our own cancellation is already in progress) + while self._tasks: + if self._on_completed_fut is None: + self._on_completed_fut = self._loop.create_future() + + try: + await self._on_completed_fut + except exceptions.CancelledError as ex: + if not self._aborting: + # Our parent task is being cancelled: + # + # async def wrapper(): + # async with TaskGroup() as g: + # g.create_task(foo) + # + # "wrapper" is being cancelled while "foo" is + # still running. + propagate_cancellation_error = ex + self._abort() + + self._on_completed_fut = None + + assert not self._tasks + + if self._base_error is not None: + raise self._base_error + + # Propagate CancelledError if there is one, except if there + # are other errors -- those have priority. + if propagate_cancellation_error and not self._errors: + raise propagate_cancellation_error + + if et is not None and et is not exceptions.CancelledError: + self._errors.append(exc) + + if self._errors: + # Exceptions are heavy objects that can have object + # cycles (bad for GC); let's not keep a reference to + # a bunch of them. + try: + me = BaseExceptionGroup('unhandled errors in a TaskGroup', self._errors) + raise me from None + finally: + self._errors = None + + def create_task(self, coro, *, name=None, context=None): + if not self._entered: + raise RuntimeError(f"TaskGroup {self!r} has not been entered") + if self._exiting and not self._tasks: + raise RuntimeError(f"TaskGroup {self!r} is finished") + if self._aborting: + raise RuntimeError(f"TaskGroup {self!r} is shutting down") + if context is None: + task = self._loop.create_task(coro) + else: + task = self._loop.create_task(coro, context=context) + tasks._set_task_name(task, name) + task.add_done_callback(self._on_task_done) + self._tasks.add(task) + return task + + # Since Python 3.8 Tasks propagate all exceptions correctly, + # except for KeyboardInterrupt and SystemExit which are + # still considered special. + + def _is_base_error(self, exc: BaseException) -> bool: + assert isinstance(exc, BaseException) + return isinstance(exc, (SystemExit, KeyboardInterrupt)) + + def _abort(self): + self._aborting = True + + for t in self._tasks: + if not t.done(): + t.cancel() + + def _on_task_done(self, task): + self._tasks.discard(task) + + if self._on_completed_fut is not None and not self._tasks: + if not self._on_completed_fut.done(): + self._on_completed_fut.set_result(True) + + if task.cancelled(): + return + + exc = task.exception() + if exc is None: + return + + self._errors.append(exc) + if self._is_base_error(exc) and self._base_error is None: + self._base_error = exc + + if self._parent_task.done(): + # Not sure if this case is possible, but we want to handle + # it anyways. + self._loop.call_exception_handler({ + 'message': f'Task {task!r} has errored out but its parent ' + f'task {self._parent_task} is already completed', + 'exception': exc, + 'task': task, + }) + return + + if not self._aborting and not self._parent_cancel_requested: + # If parent task *is not* being cancelled, it means that we want + # to manually cancel it to abort whatever is being run right now + # in the TaskGroup. But we want to mark parent task as + # "not cancelled" later in __aexit__. Example situation that + # we need to handle: + # + # async def foo(): + # try: + # async with TaskGroup() as g: + # g.create_task(crash_soon()) + # await something # <- this needs to be canceled + # # by the TaskGroup, e.g. + # # foo() needs to be cancelled + # except Exception: + # # Ignore any exceptions raised in the TaskGroup + # pass + # await something_else # this line has to be called + # # after TaskGroup is finished. + self._abort() + self._parent_cancel_requested = True + self._parent_task.cancel() diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 9a9d0d6e3cc..e78719de216 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -17,6 +17,7 @@ import itertools import types import warnings import weakref +from types import GenericAlias from . import base_tasks from . import coroutines @@ -66,7 +67,10 @@ def _set_task_name(task, name): try: set_name = task.set_name except AttributeError: - pass + warnings.warn("Task.set_name() was added in Python 3.8, " + "the method support will be mandatory for third-party " + "task implementations since 3.13.", + DeprecationWarning, stacklevel=3) else: set_name(name) @@ -89,7 +93,7 @@ class Task(futures._PyFuture): # Inherit Python Task implementation # status is still pending _log_destroy_pending = True - def __init__(self, coro, *, loop=None, name=None): + def __init__(self, coro, *, loop=None, name=None, context=None): super().__init__(loop=loop) if self._source_traceback: del self._source_traceback[-1] @@ -104,10 +108,14 @@ class Task(futures._PyFuture): # Inherit Python Task implementation else: self._name = str(name) + self._num_cancels_requested = 0 self._must_cancel = False self._fut_waiter = None self._coro = coro - self._context = contextvars.copy_context() + if context is None: + self._context = contextvars.copy_context() + else: + self._context = context self._loop.call_soon(self.__step, context=self._context) _register_task(self) @@ -123,15 +131,17 @@ class Task(futures._PyFuture): # Inherit Python Task implementation self._loop.call_exception_handler(context) super().__del__() - def __class_getitem__(cls, type): - return cls + __class_getitem__ = classmethod(GenericAlias) - def _repr_info(self): - return base_tasks._task_repr_info(self) + def __repr__(self): + return base_tasks._task_repr(self) def get_coro(self): return self._coro + def get_context(self): + return self._context + def get_name(self): return self._name @@ -197,10 +207,18 @@ class Task(futures._PyFuture): # Inherit Python Task implementation task will be marked as cancelled when the wrapped coroutine terminates with a CancelledError exception (even if cancel() was not called). + + This also increases the task's count of cancellation requests. """ self._log_traceback = False if self.done(): return False + self._num_cancels_requested += 1 + # These two lines are controversial. See discussion starting at + # https://github.com/python/cpython/pull/31394#issuecomment-1053545331 + # Also remember that this is duplicated in _asynciomodule.c. + # if self._num_cancels_requested > 1: + # return False if self._fut_waiter is not None: if self._fut_waiter.cancel(msg=msg): # Leave self._fut_waiter; it may be a Task that @@ -212,6 +230,26 @@ class Task(futures._PyFuture): # Inherit Python Task implementation self._cancel_message = msg return True + def cancelling(self): + """Return the count of the task's cancellation requests. + + This count is incremented when .cancel() is called + and may be decremented using .uncancel(). + """ + return self._num_cancels_requested + + def uncancel(self): + """Decrement the task's count of cancellation requests. + + This should be called by the party that called `cancel()` on the task + beforehand. + + Returns the remaining number of cancellation requests. + """ + if self._num_cancels_requested > 0: + self._num_cancels_requested -= 1 + return self._num_cancels_requested + def __step(self, exc=None): if self.done(): raise exceptions.InvalidStateError( @@ -328,13 +366,18 @@ else: Task = _CTask = _asyncio.Task -def create_task(coro, *, name=None): +def create_task(coro, *, name=None, context=None): """Schedule the execution of a coroutine object in a spawn task. Return a Task object. """ loop = events.get_running_loop() - task = loop.create_task(coro) + if context is None: + # Use legacy API if context is not needed + task = loop.create_task(coro) + else: + task = loop.create_task(coro, context=context) + _set_task_name(task, name) return task @@ -347,7 +390,7 @@ ALL_COMPLETED = concurrent.futures.ALL_COMPLETED async def wait(fs, *, timeout=None, return_when=ALL_COMPLETED): - """Wait for the Futures and coroutines given by fs to complete. + """Wait for the Futures or Tasks given by fs to complete. The fs iterable must not be empty. @@ -365,22 +408,16 @@ async def wait(fs, *, timeout=None, return_when=ALL_COMPLETED): if futures.isfuture(fs) or coroutines.iscoroutine(fs): raise TypeError(f"expect a list of futures, not {type(fs).__name__}") if not fs: - raise ValueError('Set of coroutines/Futures is empty.') + raise ValueError('Set of Tasks/Futures is empty.') if return_when not in (FIRST_COMPLETED, FIRST_EXCEPTION, ALL_COMPLETED): raise ValueError(f'Invalid return_when value: {return_when}') - loop = events.get_running_loop() - fs = set(fs) if any(coroutines.iscoroutine(f) for f in fs): - warnings.warn("The explicit passing of coroutine objects to " - "asyncio.wait() is deprecated since Python 3.8, and " - "scheduled for removal in Python 3.11.", - DeprecationWarning, stacklevel=2) - - fs = {ensure_future(f, loop=loop) for f in fs} + raise TypeError("Passing coroutines is forbidden, use tasks explicitly.") + loop = events.get_running_loop() return await _wait(fs, timeout, return_when, loop) @@ -415,11 +452,9 @@ async def wait_for(fut, timeout): await _cancel_and_wait(fut, loop=loop) try: - fut.result() + return fut.result() except exceptions.CancelledError as exc: raise exceptions.TimeoutError() from exc - else: - raise exceptions.TimeoutError() waiter = loop.create_future() timeout_handle = loop.call_later(timeout, _release_waiter, waiter) @@ -455,11 +490,9 @@ async def wait_for(fut, timeout): # exception, we should re-raise it # See https://bugs.python.org/issue40607 try: - fut.result() + return fut.result() except exceptions.CancelledError as exc: raise exceptions.TimeoutError() from exc - else: - raise exceptions.TimeoutError() finally: timeout_handle.cancel() @@ -549,7 +582,7 @@ def as_completed(fs, *, timeout=None): from .queues import Queue # Import here to avoid circular import problem. done = Queue() - loop = events._get_event_loop() + loop = events.get_event_loop() todo = {ensure_future(f, loop=loop) for f in set(fs)} timeout_handle = None @@ -625,17 +658,23 @@ def _ensure_future(coro_or_future, *, loop=None): raise ValueError('The future belongs to a different loop than ' 'the one specified as the loop argument') return coro_or_future - + called_wrap_awaitable = False if not coroutines.iscoroutine(coro_or_future): if inspect.isawaitable(coro_or_future): coro_or_future = _wrap_awaitable(coro_or_future) + called_wrap_awaitable = True else: raise TypeError('An asyncio.Future, a coroutine or an awaitable ' 'is required') if loop is None: - loop = events._get_event_loop(stacklevel=4) - return loop.create_task(coro_or_future) + loop = events.get_event_loop() + try: + return loop.create_task(coro_or_future) + except RuntimeError: + if not called_wrap_awaitable: + coro_or_future.close() + raise @types.coroutine @@ -710,7 +749,7 @@ def gather(*coros_or_futures, return_exceptions=False): gather won't cancel any other awaitables. """ if not coros_or_futures: - loop = events._get_event_loop() + loop = events.get_event_loop() outer = loop.create_future() outer.set_result([]) return outer @@ -719,7 +758,7 @@ def gather(*coros_or_futures, return_exceptions=False): nonlocal nfinished nfinished += 1 - if outer.done(): + if outer is None or outer.done(): if not fut.cancelled(): # Mark exception retrieved. fut.exception() @@ -775,6 +814,7 @@ def gather(*coros_or_futures, return_exceptions=False): nfuts = 0 nfinished = 0 loop = None + outer = None # bpo-46672 for arg in coros_or_futures: if arg not in arg_to_fut: fut = _ensure_future(arg, loop=loop) @@ -806,7 +846,8 @@ def shield(arg): The statement - res = await shield(something()) + task = asyncio.create_task(something()) + res = await shield(task) is exactly equivalent to the statement @@ -822,10 +863,16 @@ def shield(arg): If you want to completely ignore cancellation (not recommended) you can combine shield() with a try/except clause, as follows: + task = asyncio.create_task(something()) try: - res = await shield(something()) + res = await shield(task) except CancelledError: res = None + + Save a reference to tasks passed to this function, to avoid + a task disappearing mid-execution. The event loop only keeps + weak references to tasks. A task that isn't referenced elsewhere + may get garbage collected at any time, even before it's done. """ inner = _ensure_future(arg) if inner.done(): @@ -917,6 +964,7 @@ def _unregister_task(task): _all_tasks.discard(task) +_py_current_task = current_task _py_register_task = _register_task _py_unregister_task = _unregister_task _py_enter_task = _enter_task @@ -926,10 +974,12 @@ _py_leave_task = _leave_task try: from _asyncio import (_register_task, _unregister_task, _enter_task, _leave_task, - _all_tasks, _current_tasks) + _all_tasks, _current_tasks, + current_task) except ImportError: pass else: + _c_current_task = current_task _c_register_task = _register_task _c_unregister_task = _unregister_task _c_enter_task = _enter_task diff --git a/Lib/asyncio/timeouts.py b/Lib/asyncio/timeouts.py new file mode 100644 index 00000000000..94d25535fbc --- /dev/null +++ b/Lib/asyncio/timeouts.py @@ -0,0 +1,151 @@ +import enum + +from types import TracebackType +from typing import final, Optional, Type + +from . import events +from . import exceptions +from . import tasks + + +__all__ = ( + "Timeout", + "timeout", + "timeout_at", +) + + +class _State(enum.Enum): + CREATED = "created" + ENTERED = "active" + EXPIRING = "expiring" + EXPIRED = "expired" + EXITED = "finished" + + +@final +class Timeout: + + def __init__(self, when: Optional[float]) -> None: + self._state = _State.CREATED + + self._timeout_handler: Optional[events.TimerHandle] = None + self._task: Optional[tasks.Task] = None + self._when = when + + def when(self) -> Optional[float]: + return self._when + + def reschedule(self, when: Optional[float]) -> None: + assert self._state is not _State.CREATED + if self._state is not _State.ENTERED: + raise RuntimeError( + f"Cannot change state of {self._state.value} Timeout", + ) + + self._when = when + + if self._timeout_handler is not None: + self._timeout_handler.cancel() + + if when is None: + self._timeout_handler = None + else: + loop = events.get_running_loop() + if when <= loop.time(): + self._timeout_handler = loop.call_soon(self._on_timeout) + else: + self._timeout_handler = loop.call_at(when, self._on_timeout) + + def expired(self) -> bool: + """Is timeout expired during execution?""" + return self._state in (_State.EXPIRING, _State.EXPIRED) + + def __repr__(self) -> str: + info = [''] + if self._state is _State.ENTERED: + when = round(self._when, 3) if self._when is not None else None + info.append(f"when={when}") + info_str = ' '.join(info) + return f"" + + async def __aenter__(self) -> "Timeout": + self._state = _State.ENTERED + self._task = tasks.current_task() + if self._task is None: + raise RuntimeError("Timeout should be used inside a task") + self.reschedule(self._when) + return self + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> Optional[bool]: + assert self._state in (_State.ENTERED, _State.EXPIRING) + + if self._timeout_handler is not None: + self._timeout_handler.cancel() + self._timeout_handler = None + + if self._state is _State.EXPIRING: + self._state = _State.EXPIRED + + if self._task.uncancel() == 0 and exc_type is exceptions.CancelledError: + # Since there are no outstanding cancel requests, we're + # handling this. + raise TimeoutError + elif self._state is _State.ENTERED: + self._state = _State.EXITED + + return None + + def _on_timeout(self) -> None: + assert self._state is _State.ENTERED + self._task.cancel() + self._state = _State.EXPIRING + # drop the reference early + self._timeout_handler = None + + +def timeout(delay: Optional[float]) -> Timeout: + """Timeout async context manager. + + Useful in cases when you want to apply timeout logic around block + of code or in cases when asyncio.wait_for is not suitable. For example: + + >>> async with asyncio.timeout(10): # 10 seconds timeout + ... await long_running_task() + + + delay - value in seconds or None to disable timeout logic + + long_running_task() is interrupted by raising asyncio.CancelledError, + the top-most affected timeout() context manager converts CancelledError + into TimeoutError. + """ + loop = events.get_running_loop() + return Timeout(loop.time() + delay if delay is not None else None) + + +def timeout_at(when: Optional[float]) -> Timeout: + """Schedule the timeout at absolute time. + + Like timeout() but argument gives absolute time in the same clock system + as loop.time(). + + Please note: it is not POSIX time but a time with + undefined starting base, e.g. the time of the system power on. + + >>> async with asyncio.timeout_at(loop.time() + 10): + ... await long_running_task() + + + when - a deadline when timeout occurs or None to disable timeout logic + + long_running_task() is interrupted by raising asyncio.CancelledError, + the top-most affected timeout() context manager converts CancelledError + into TimeoutError. + """ + return Timeout(when) diff --git a/Lib/asyncio/transports.py b/Lib/asyncio/transports.py index 45e155c94ca..30fd41d49af 100644 --- a/Lib/asyncio/transports.py +++ b/Lib/asyncio/transports.py @@ -99,6 +99,12 @@ class WriteTransport(BaseTransport): """Return the current size of the write buffer.""" raise NotImplementedError + def get_write_buffer_limits(self): + """Get the high and low watermarks for write flow control. + Return a tuple (low, high) where low and high are + positive number of bytes.""" + raise NotImplementedError + def write(self, data): """Write some data bytes to the transport. diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index c88b818de62..b21e0394141 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -195,22 +195,25 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop): async def _make_subprocess_transport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, extra=None, **kwargs): - with events.get_child_watcher() as watcher: + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + watcher = events.get_child_watcher() + + with watcher: if not watcher.is_active(): # Check early. # Raising exception before process creation # prevents subprocess execution if the watcher # is not ready to handle it. raise RuntimeError("asyncio.get_child_watcher() is not activated, " - "subprocess support is not installed.") + "subprocess support is not installed.") waiter = self.create_future() transp = _UnixSubprocessTransport(self, protocol, args, shell, - stdin, stdout, stderr, bufsize, - waiter=waiter, extra=extra, - **kwargs) - + stdin, stdout, stderr, bufsize, + waiter=waiter, extra=extra, + **kwargs) watcher.add_child_handler(transp.get_pid(), - self._child_watcher_callback, transp) + self._child_watcher_callback, transp) try: await waiter except (SystemExit, KeyboardInterrupt): @@ -223,13 +226,15 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop): return transp def _child_watcher_callback(self, pid, returncode, transp): - self.call_soon_threadsafe(transp._process_exited, returncode) + # Skip one iteration for callbacks to be executed + self.call_soon_threadsafe(self.call_soon, transp._process_exited, returncode) async def create_unix_connection( self, protocol_factory, path=None, *, ssl=None, sock=None, server_hostname=None, - ssl_handshake_timeout=None): + ssl_handshake_timeout=None, + ssl_shutdown_timeout=None): assert server_hostname is None or isinstance(server_hostname, str) if ssl: if server_hostname is None: @@ -241,6 +246,9 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop): if ssl_handshake_timeout is not None: raise ValueError( 'ssl_handshake_timeout is only meaningful with ssl') + if ssl_shutdown_timeout is not None: + raise ValueError( + 'ssl_shutdown_timeout is only meaningful with ssl') if path is not None: if sock is not None: @@ -267,13 +275,15 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop): transport, protocol = await self._create_connection_transport( sock, protocol_factory, ssl, server_hostname, - ssl_handshake_timeout=ssl_handshake_timeout) + ssl_handshake_timeout=ssl_handshake_timeout, + ssl_shutdown_timeout=ssl_shutdown_timeout) return transport, protocol async def create_unix_server( self, protocol_factory, path=None, *, sock=None, backlog=100, ssl=None, ssl_handshake_timeout=None, + ssl_shutdown_timeout=None, start_serving=True): if isinstance(ssl, bool): raise TypeError('ssl argument must be an SSLContext or None') @@ -282,6 +292,10 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop): raise ValueError( 'ssl_handshake_timeout is only meaningful with ssl') + if ssl_shutdown_timeout is not None and not ssl: + raise ValueError( + 'ssl_shutdown_timeout is only meaningful with ssl') + if path is not None: if sock is not None: raise ValueError( @@ -328,7 +342,8 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop): sock.setblocking(False) server = base_events.Server(self, [sock], protocol_factory, - ssl, backlog, ssl_handshake_timeout) + ssl, backlog, ssl_handshake_timeout, + ssl_shutdown_timeout) if start_serving: server._start_serving() # Skip one loop iteration so that all 'loop.add_reader' @@ -788,12 +803,11 @@ class _UnixSubprocessTransport(base_subprocess.BaseSubprocessTransport): def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs): stdin_w = None - if stdin == subprocess.PIPE: - # Use a socket pair for stdin, since not all platforms + if stdin == subprocess.PIPE and sys.platform.startswith('aix'): + # Use a socket pair for stdin on AIX, since it does not # support selecting read events on the write end of a # socket (which we use in order to detect closing of the - # other end). Notably this is needed on AIX, and works - # just fine on other platforms. + # other end). stdin, stdin_w = socket.socketpair() try: self._proc = subprocess.Popen( @@ -832,6 +846,13 @@ class AbstractChildWatcher: waitpid(-1), there should be only one active object per process. """ + def __init_subclass__(cls) -> None: + if cls.__module__ != __name__: + warnings._deprecated("AbstractChildWatcher", + "{name!r} is deprecated as of Python 3.12 and will be " + "removed in Python {remove}.", + remove=(3, 14)) + def add_child_handler(self, pid, callback, *args): """Register a new child handler. @@ -900,10 +921,6 @@ class PidfdChildWatcher(AbstractChildWatcher): recent (5.3+) kernels. """ - def __init__(self): - self._loop = None - self._callbacks = {} - def __enter__(self): return self @@ -911,35 +928,22 @@ class PidfdChildWatcher(AbstractChildWatcher): pass def is_active(self): - return self._loop is not None and self._loop.is_running() + return True def close(self): - self.attach_loop(None) + pass def attach_loop(self, loop): - if self._loop is not None and loop is None and self._callbacks: - warnings.warn( - 'A loop is being detached ' - 'from a child watcher with pending handlers', - RuntimeWarning) - for pidfd, _, _ in self._callbacks.values(): - self._loop._remove_reader(pidfd) - os.close(pidfd) - self._callbacks.clear() - self._loop = loop + pass def add_child_handler(self, pid, callback, *args): - existing = self._callbacks.get(pid) - if existing is not None: - self._callbacks[pid] = existing[0], callback, args - else: - pidfd = os.pidfd_open(pid) - self._loop._add_reader(pidfd, self._do_wait, pid) - self._callbacks[pid] = pidfd, callback, args + loop = events.get_running_loop() + pidfd = os.pidfd_open(pid) + loop._add_reader(pidfd, self._do_wait, pid, pidfd, callback, args) - def _do_wait(self, pid): - pidfd, callback, args = self._callbacks.pop(pid) - self._loop._remove_reader(pidfd) + def _do_wait(self, pid, pidfd, callback, args): + loop = events.get_running_loop() + loop._remove_reader(pidfd) try: _, status = os.waitpid(pid, 0) except ChildProcessError: @@ -957,12 +961,9 @@ class PidfdChildWatcher(AbstractChildWatcher): callback(pid, returncode, *args) def remove_child_handler(self, pid): - try: - pidfd, _, _ = self._callbacks.pop(pid) - except KeyError: - return False - self._loop._remove_reader(pidfd) - os.close(pidfd) + # asyncio never calls remove_child_handler() !!! + # The method is no-op but is implemented because + # abstract base classes require it. return True @@ -1030,6 +1031,13 @@ class SafeChildWatcher(BaseChildWatcher): big number of children (O(n) each time SIGCHLD is raised) """ + def __init__(self): + super().__init__() + warnings._deprecated("SafeChildWatcher", + "{name!r} is deprecated as of Python 3.12 and will be " + "removed in Python {remove}.", + remove=(3, 14)) + def close(self): self._callbacks.clear() super().close() @@ -1108,6 +1116,10 @@ class FastChildWatcher(BaseChildWatcher): self._lock = threading.Lock() self._zombies = {} self._forks = 0 + warnings._deprecated("FastChildWatcher", + "{name!r} is deprecated as of Python 3.12 and will be " + "removed in Python {remove}.", + remove=(3, 14)) def close(self): self._callbacks.clear() @@ -1220,6 +1232,10 @@ class MultiLoopChildWatcher(AbstractChildWatcher): def __init__(self): self._callbacks = {} self._saved_sighandler = None + warnings._deprecated("MultiLoopChildWatcher", + "{name!r} is deprecated as of Python 3.12 and will be " + "removed in Python {remove}.", + remove=(3, 14)) def is_active(self): return self._saved_sighandler is not None @@ -1411,6 +1427,17 @@ class ThreadedChildWatcher(AbstractChildWatcher): self._threads.pop(expected_pid) +def can_use_pidfd(): + if not hasattr(os, 'pidfd_open'): + return False + try: + pid = os.getpid() + os.close(os.pidfd_open(pid, 0)) + except OSError: + # blocked by security policy like SECCOMP + return False + return True + class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy): """UNIX event loop policy with a watcher for child processes.""" @@ -1423,7 +1450,10 @@ class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy): def _init_watcher(self): with events._lock: if self._watcher is None: # pragma: no branch - self._watcher = ThreadedChildWatcher() + if can_use_pidfd(): + self._watcher = PidfdChildWatcher() + else: + self._watcher = ThreadedChildWatcher() if threading.current_thread() is threading.main_thread(): self._watcher.attach_loop(self._local._loop) @@ -1449,6 +1479,9 @@ class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy): if self._watcher is None: self._init_watcher() + warnings._deprecated("get_child_watcher", + "{name!r} is deprecated as of Python 3.12 and will be " + "removed in Python {remove}.", remove=(3, 14)) return self._watcher def set_child_watcher(self, watcher): @@ -1460,6 +1493,9 @@ class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy): self._watcher.close() self._watcher = watcher + warnings._deprecated("set_child_watcher", + "{name!r} is deprecated as of Python 3.12 and will be " + "removed in Python {remove}.", remove=(3, 14)) SelectorEventLoop = _UnixSelectorEventLoop diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py index 5e7cd795895..c9a5fb841cb 100644 --- a/Lib/asyncio/windows_events.py +++ b/Lib/asyncio/windows_events.py @@ -1,5 +1,10 @@ """Selector and proactor event loops for Windows.""" +import sys + +if sys.platform != 'win32': # pragma: no cover + raise ImportError('win32 only') + import _overlapped import _winapi import errno @@ -28,8 +33,8 @@ __all__ = ( ) -NULL = 0 -INFINITE = 0xffffffff +NULL = _winapi.NULL +INFINITE = _winapi.INFINITE ERROR_CONNECTION_REFUSED = 1225 ERROR_CONNECTION_ABORTED = 1236 @@ -361,6 +366,10 @@ class ProactorEventLoop(proactor_events.BaseProactorEventLoop): return f = self._proactor.accept_pipe(pipe) + except BrokenPipeError: + if pipe and pipe.fileno() != -1: + pipe.close() + self.call_soon(loop_accept_pipe) except OSError as exc: if pipe and pipe.fileno() != -1: self.call_exception_handler({ @@ -372,6 +381,7 @@ class ProactorEventLoop(proactor_events.BaseProactorEventLoop): elif self._debug: logger.warning("Accept pipe failed on pipe %r", pipe, exc_info=True) + self.call_soon(loop_accept_pipe) except exceptions.CancelledError: if pipe: pipe.close() @@ -405,7 +415,7 @@ class ProactorEventLoop(proactor_events.BaseProactorEventLoop): class IocpProactor: """Proactor implementation using IOCP.""" - def __init__(self, concurrency=0xffffffff): + def __init__(self, concurrency=INFINITE): self._loop = None self._results = [] self._iocp = _overlapped.CreateIoCompletionPort( @@ -434,13 +444,28 @@ class IocpProactor: self._poll(timeout) tmp = self._results self._results = [] - return tmp + try: + return tmp + finally: + # Needed to break cycles when an exception occurs. + tmp = None def _result(self, value): fut = self._loop.create_future() fut.set_result(value) return fut + @staticmethod + def finish_socket_func(trans, key, ov): + try: + return ov.getresult() + except OSError as exc: + if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED, + _overlapped.ERROR_OPERATION_ABORTED): + raise ConnectionResetError(*exc.args) + else: + raise + def recv(self, conn, nbytes, flags=0): self._register_with_iocp(conn) ov = _overlapped.Overlapped(NULL) @@ -452,17 +477,7 @@ class IocpProactor: except BrokenPipeError: return self._result(b'') - def finish_recv(trans, key, ov): - try: - return ov.getresult() - except OSError as exc: - if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED, - _overlapped.ERROR_OPERATION_ABORTED): - raise ConnectionResetError(*exc.args) - else: - raise - - return self._register(ov, conn, finish_recv) + return self._register(ov, conn, self.finish_socket_func) def recv_into(self, conn, buf, flags=0): self._register_with_iocp(conn) @@ -475,17 +490,7 @@ class IocpProactor: except BrokenPipeError: return self._result(0) - def finish_recv(trans, key, ov): - try: - return ov.getresult() - except OSError as exc: - if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED, - _overlapped.ERROR_OPERATION_ABORTED): - raise ConnectionResetError(*exc.args) - else: - raise - - return self._register(ov, conn, finish_recv) + return self._register(ov, conn, self.finish_socket_func) def recvfrom(self, conn, nbytes, flags=0): self._register_with_iocp(conn) @@ -495,6 +500,16 @@ class IocpProactor: except BrokenPipeError: return self._result((b'', None)) + return self._register(ov, conn, self.finish_socket_func) + + def recvfrom_into(self, conn, buf, flags=0): + self._register_with_iocp(conn) + ov = _overlapped.Overlapped(NULL) + try: + ov.WSARecvFromInto(conn.fileno(), buf, flags) + except BrokenPipeError: + return self._result((0, None)) + def finish_recv(trans, key, ov): try: return ov.getresult() @@ -513,17 +528,7 @@ class IocpProactor: ov.WSASendTo(conn.fileno(), buf, flags, addr) - def finish_send(trans, key, ov): - try: - return ov.getresult() - except OSError as exc: - if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED, - _overlapped.ERROR_OPERATION_ABORTED): - raise ConnectionResetError(*exc.args) - else: - raise - - return self._register(ov, conn, finish_send) + return self._register(ov, conn, self.finish_socket_func) def send(self, conn, buf, flags=0): self._register_with_iocp(conn) @@ -533,17 +538,7 @@ class IocpProactor: else: ov.WriteFile(conn.fileno(), buf) - def finish_send(trans, key, ov): - try: - return ov.getresult() - except OSError as exc: - if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED, - _overlapped.ERROR_OPERATION_ABORTED): - raise ConnectionResetError(*exc.args) - else: - raise - - return self._register(ov, conn, finish_send) + return self._register(ov, conn, self.finish_socket_func) def accept(self, listener): self._register_with_iocp(listener) @@ -614,16 +609,7 @@ class IocpProactor: offset_low, offset_high, count, 0, 0) - def finish_sendfile(trans, key, ov): - try: - return ov.getresult() - except OSError as exc: - if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED, - _overlapped.ERROR_OPERATION_ABORTED): - raise ConnectionResetError(*exc.args) - else: - raise - return self._register(ov, sock, finish_sendfile) + return self._register(ov, sock, self.finish_socket_func) def accept_pipe(self, pipe): self._register_with_iocp(pipe) @@ -816,6 +802,8 @@ class IocpProactor: else: f.set_result(value) self._results.append(f) + finally: + f = None # Remove unregistered futures for ov in self._unregistered: @@ -834,7 +822,7 @@ class IocpProactor: return # Cancel remaining registered operations. - for address, (fut, ov, obj, callback) in list(self._cache.items()): + for fut, ov, obj, callback in list(self._cache.values()): if fut.cancelled(): # Nothing to do with cancelled futures pass diff --git a/Lib/base64.py b/Lib/base64.py index 7e9c2a2ca47..95dc7b00860 100755 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -508,14 +508,8 @@ MAXBINSIZE = (MAXLINESIZE//4)*3 def encode(input, output): """Encode a file; input and output are binary files.""" - while True: - s = input.read(MAXBINSIZE) - if not s: - break - while len(s) < MAXBINSIZE: - ns = input.read(MAXBINSIZE-len(s)) - if not ns: - break + while s := input.read(MAXBINSIZE): + while len(s) < MAXBINSIZE and (ns := input.read(MAXBINSIZE-len(s))): s += ns line = binascii.b2a_base64(s) output.write(line) @@ -523,10 +517,7 @@ def encode(input, output): def decode(input, output): """Decode a file; input and output are binary files.""" - while True: - line = input.readline() - if not line: - break + while line := input.readline(): s = binascii.a2b_base64(line) output.write(s) @@ -567,11 +558,10 @@ def decodebytes(s): def main(): """Small main program""" import sys, getopt - usage = """usage: %s [-h|-d|-e|-u|-t] [file|-] + usage = f"""usage: {sys.argv[0]} [-h|-d|-e|-u|-t] [file|-] -h: print this help message and exit -d, -u: decode - -e: encode (default) - -t: encode and decode string 'Aladdin:open sesame'"""%sys.argv[0] + -e: encode (default)""" try: opts, args = getopt.getopt(sys.argv[1:], 'hdeut') except getopt.error as msg: @@ -584,7 +574,6 @@ def main(): if o == '-e': func = encode if o == '-d': func = decode if o == '-u': func = decode - if o == '-t': test(); return if o == '-h': print(usage); return if args and args[0] != '-': with open(args[0], 'rb') as f: @@ -593,15 +582,5 @@ def main(): func(sys.stdin.buffer, sys.stdout.buffer) -def test(): - s0 = b"Aladdin:open sesame" - print(repr(s0)) - s1 = encodebytes(s0) - print(repr(s1)) - s2 = decodebytes(s1) - print(repr(s2)) - assert s0 == s2 - - if __name__ == '__main__': main() diff --git a/Lib/bdb.py b/Lib/bdb.py index 75d61135763..81fbb8514ac 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -805,15 +805,18 @@ def checkfuncname(b, frame): return True -# Determines if there is an effective (active) breakpoint at this -# line of code. Returns breakpoint number or 0 if none def effective(file, line, frame): - """Determine which breakpoint for this file:line is to be acted upon. + """Return (active breakpoint, delete temporary flag) or (None, None) as + breakpoint to act upon. - Called only if we know there is a breakpoint at this location. Return - the breakpoint that was triggered and a boolean that indicates if it is - ok to delete a temporary breakpoint. Return (None, None) if there is no - matching breakpoint. + The "active breakpoint" is the first entry in bplist[line, file] (which + must exist) that is enabled, for which checkfuncname is True, and that + has neither a False condition nor a positive ignore count. The flag, + meaning that a temporary breakpoint should be deleted, is False only + when the condiion cannot be evaluated (in which case, ignore count is + ignored). + + If no such entry exists, then (None, None) is returned. """ possibles = Breakpoint.bplist[file, line] for b in possibles: diff --git a/Lib/cProfile.py b/Lib/cProfile.py index 22a7d0aade8..f7000a8bfa0 100755 --- a/Lib/cProfile.py +++ b/Lib/cProfile.py @@ -7,6 +7,7 @@ __all__ = ["run", "runctx", "Profile"] import _lsprof +import importlib.machinery import profile as _pyprofile # ____________________________________________________________ @@ -140,7 +141,7 @@ def main(): help="Save stats to ", default=None) parser.add_option('-s', '--sort', dest="sort", help="Sort order when printing to stdout, based on pstats.Stats class", - default=-1, + default=2, choices=sorted(pstats.Stats.sort_arg_dict_default)) parser.add_option('-m', dest="module", action="store_true", help="Profile a library module", default=False) @@ -169,9 +170,12 @@ def main(): sys.path.insert(0, os.path.dirname(progname)) with open(progname, 'rb') as fp: code = compile(fp.read(), progname, 'exec') + spec = importlib.machinery.ModuleSpec(name='__main__', loader=None, + origin=progname) globs = { - '__file__': progname, - '__name__': '__main__', + '__spec__': spec, + '__file__': spec.origin, + '__name__': spec.name, '__package__': None, '__cached__': None, } diff --git a/Lib/calendar.py b/Lib/calendar.py index 663bb946b0d..657396439c9 100644 --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -15,7 +15,9 @@ __all__ = ["IllegalMonthError", "IllegalWeekdayError", "setfirstweekday", "monthcalendar", "prmonth", "month", "prcal", "calendar", "timegm", "month_name", "month_abbr", "day_name", "day_abbr", "Calendar", "TextCalendar", "HTMLCalendar", "LocaleTextCalendar", - "LocaleHTMLCalendar", "weekheader"] + "LocaleHTMLCalendar", "weekheader", + "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", + "SATURDAY", "SUNDAY"] # Exception raised for bad input (with string parameter for details) error = ValueError @@ -546,15 +548,28 @@ class HTMLCalendar(Calendar): class different_locale: def __init__(self, locale): self.locale = locale + self.oldlocale = None def __enter__(self): - self.oldlocale = _locale.getlocale(_locale.LC_TIME) + self.oldlocale = _locale.setlocale(_locale.LC_TIME, None) _locale.setlocale(_locale.LC_TIME, self.locale) def __exit__(self, *args): + if self.oldlocale is None: + return _locale.setlocale(_locale.LC_TIME, self.oldlocale) +def _get_default_locale(): + locale = _locale.setlocale(_locale.LC_TIME, None) + if locale == "C": + with different_locale(""): + # The LC_TIME locale does not seem to be configured: + # get the user preferred locale. + locale = _locale.setlocale(_locale.LC_TIME, None) + return locale + + class LocaleTextCalendar(TextCalendar): """ This class can be passed a locale name in the constructor and will return @@ -564,7 +579,7 @@ class LocaleTextCalendar(TextCalendar): def __init__(self, firstweekday=0, locale=None): TextCalendar.__init__(self, firstweekday) if locale is None: - locale = _locale.getdefaultlocale() + locale = _get_default_locale() self.locale = locale def formatweekday(self, day, width): @@ -584,7 +599,7 @@ class LocaleHTMLCalendar(HTMLCalendar): def __init__(self, firstweekday=0, locale=None): HTMLCalendar.__init__(self, firstweekday) if locale is None: - locale = _locale.getdefaultlocale() + locale = _get_default_locale() self.locale = locale def formatweekday(self, day): diff --git a/Lib/cgi.py b/Lib/cgi.py index 6cb8cf28bd6..8787567be7c 100755 --- a/Lib/cgi.py +++ b/Lib/cgi.py @@ -13,6 +13,11 @@ This module defines a number of utilities for use by CGI scripts written in Python. + +The global variable maxlen can be set to an integer indicating the maximum size +of a POST request. POST requests larger than this size will result in a +ValueError being raised during parsing. The default value of this variable is 0, +meaning the request size is unlimited. """ # History @@ -48,6 +53,9 @@ __all__ = ["MiniFieldStorage", "FieldStorage", "parse", "parse_multipart", "print_form", "print_directory", "print_arguments", "print_environ_usage"] + +warnings._deprecated(__name__, remove=(3,13)) + # Logging support # =============== diff --git a/Lib/cgitb.py b/Lib/cgitb.py index ec156843099..f6b97f25c59 100644 --- a/Lib/cgitb.py +++ b/Lib/cgitb.py @@ -31,8 +31,12 @@ import tempfile import time import tokenize import traceback +import warnings from html import escape as html_escape +warnings._deprecated(__name__, remove=(3, 13)) + + def reset(): """Return a string that resets the CGI and browser to a known state.""" return ''' A B C D # unique_everseen('ABBCcAD', str.lower) --> A B C D - seen = set() + seen: Set[Union[_T, _U]] = set() seen_add = seen.add if key is None: for element in filterfalse(seen.__contains__, iterable): diff --git a/Lib/importlib/_legacy.py b/Lib/importlib/resources/_legacy.py similarity index 63% rename from Lib/importlib/_legacy.py rename to Lib/importlib/resources/_legacy.py index 2ddec5f90a3..b1ea8105dad 100644 --- a/Lib/importlib/_legacy.py +++ b/Lib/importlib/resources/_legacy.py @@ -1,25 +1,57 @@ +import functools import os import pathlib import types +import warnings -from typing import Union, Iterable, ContextManager, BinaryIO, TextIO +from typing import Union, Iterable, ContextManager, BinaryIO, TextIO, Any from . import _common Package = Union[types.ModuleType, str] -Resource = Union[str, os.PathLike] +Resource = str +def deprecated(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + warnings.warn( + f"{func.__name__} is deprecated. Use files() instead. " + "Refer to https://importlib-resources.readthedocs.io" + "/en/latest/using.html#migrating-from-legacy for migration advice.", + DeprecationWarning, + stacklevel=2, + ) + return func(*args, **kwargs) + + return wrapper + + +def normalize_path(path: Any) -> str: + """Normalize a path by ensuring it is a string. + + If the resulting string contains path separators, an exception is raised. + """ + str_path = str(path) + parent, file_name = os.path.split(str_path) + if parent: + raise ValueError(f'{path!r} must be only a file name') + return file_name + + +@deprecated def open_binary(package: Package, resource: Resource) -> BinaryIO: """Return a file-like object opened for binary reading of the resource.""" - return (_common.files(package) / _common.normalize_path(resource)).open('rb') + return (_common.files(package) / normalize_path(resource)).open('rb') +@deprecated def read_binary(package: Package, resource: Resource) -> bytes: """Return the binary contents of the resource.""" - return (_common.files(package) / _common.normalize_path(resource)).read_bytes() + return (_common.files(package) / normalize_path(resource)).read_bytes() +@deprecated def open_text( package: Package, resource: Resource, @@ -27,11 +59,12 @@ def open_text( errors: str = 'strict', ) -> TextIO: """Return a file-like object opened for text reading of the resource.""" - return (_common.files(package) / _common.normalize_path(resource)).open( + return (_common.files(package) / normalize_path(resource)).open( 'r', encoding=encoding, errors=errors ) +@deprecated def read_text( package: Package, resource: Resource, @@ -47,6 +80,7 @@ def read_text( return fp.read() +@deprecated def contents(package: Package) -> Iterable[str]: """Return an iterable of entries in `package`. @@ -57,18 +91,20 @@ def contents(package: Package) -> Iterable[str]: return [path.name for path in _common.files(package).iterdir()] +@deprecated def is_resource(package: Package, name: str) -> bool: """True if `name` is a resource inside `package`. Directories are *not* resources. """ - resource = _common.normalize_path(name) + resource = normalize_path(name) return any( traversable.name == resource and traversable.is_file() for traversable in _common.files(package).iterdir() ) +@deprecated def path( package: Package, resource: Resource, @@ -81,4 +117,4 @@ def path( raised if the file was deleted prior to the context manager exiting). """ - return _common.as_file(_common.files(package) / _common.normalize_path(resource)) + return _common.as_file(_common.files(package) / normalize_path(resource)) diff --git a/Lib/importlib/resources/abc.py b/Lib/importlib/resources/abc.py new file mode 100644 index 00000000000..6750a7aaf14 --- /dev/null +++ b/Lib/importlib/resources/abc.py @@ -0,0 +1,173 @@ +import abc +import io +import itertools +import os +import pathlib +from typing import Any, BinaryIO, Iterable, Iterator, NoReturn, Text, Optional +from typing import runtime_checkable, Protocol +from typing import Union + + +StrPath = Union[str, os.PathLike[str]] + +__all__ = ["ResourceReader", "Traversable", "TraversableResources"] + + +class ResourceReader(metaclass=abc.ABCMeta): + """Abstract base class for loaders to provide resource reading support.""" + + @abc.abstractmethod + def open_resource(self, resource: Text) -> BinaryIO: + """Return an opened, file-like object for binary reading. + + The 'resource' argument is expected to represent only a file name. + If the resource cannot be found, FileNotFoundError is raised. + """ + # This deliberately raises FileNotFoundError instead of + # NotImplementedError so that if this method is accidentally called, + # it'll still do the right thing. + raise FileNotFoundError + + @abc.abstractmethod + def resource_path(self, resource: Text) -> Text: + """Return the file system path to the specified resource. + + The 'resource' argument is expected to represent only a file name. + If the resource does not exist on the file system, raise + FileNotFoundError. + """ + # This deliberately raises FileNotFoundError instead of + # NotImplementedError so that if this method is accidentally called, + # it'll still do the right thing. + raise FileNotFoundError + + @abc.abstractmethod + def is_resource(self, path: Text) -> bool: + """Return True if the named 'path' is a resource. + + Files are resources, directories are not. + """ + raise FileNotFoundError + + @abc.abstractmethod + def contents(self) -> Iterable[str]: + """Return an iterable of entries in `package`.""" + raise FileNotFoundError + + +class TraversalError(Exception): + pass + + +@runtime_checkable +class Traversable(Protocol): + """ + An object with a subset of pathlib.Path methods suitable for + traversing directories and opening files. + + Any exceptions that occur when accessing the backing resource + may propagate unaltered. + """ + + @abc.abstractmethod + def iterdir(self) -> Iterator["Traversable"]: + """ + Yield Traversable objects in self + """ + + def read_bytes(self) -> bytes: + """ + Read contents of self as bytes + """ + with self.open('rb') as strm: + return strm.read() + + def read_text(self, encoding: Optional[str] = None) -> str: + """ + Read contents of self as text + """ + with self.open(encoding=encoding) as strm: + return strm.read() + + @abc.abstractmethod + def is_dir(self) -> bool: + """ + Return True if self is a directory + """ + + @abc.abstractmethod + def is_file(self) -> bool: + """ + Return True if self is a file + """ + + def joinpath(self, *descendants: StrPath) -> "Traversable": + """ + Return Traversable resolved with any descendants applied. + + Each descendant should be a path segment relative to self + and each may contain multiple levels separated by + ``posixpath.sep`` (``/``). + """ + if not descendants: + return self + names = itertools.chain.from_iterable( + path.parts for path in map(pathlib.PurePosixPath, descendants) + ) + target = next(names) + matches = ( + traversable for traversable in self.iterdir() if traversable.name == target + ) + try: + match = next(matches) + except StopIteration: + raise TraversalError( + "Target not found during traversal.", target, list(names) + ) + return match.joinpath(*names) + + def __truediv__(self, child: StrPath) -> "Traversable": + """ + Return Traversable child in self + """ + return self.joinpath(child) + + @abc.abstractmethod + def open(self, mode='r', *args, **kwargs): + """ + mode may be 'r' or 'rb' to open as text or binary. Return a handle + suitable for reading (same as pathlib.Path.open). + + When opening as text, accepts encoding parameters such as those + accepted by io.TextIOWrapper. + """ + + @property + @abc.abstractmethod + def name(self) -> str: + """ + The base name of this object without any parent references. + """ + + +class TraversableResources(ResourceReader): + """ + The required interface for providing traversable + resources. + """ + + @abc.abstractmethod + def files(self) -> "Traversable": + """Return a Traversable object for the loaded package.""" + + def open_resource(self, resource: StrPath) -> io.BufferedReader: + return self.files().joinpath(resource).open('rb') + + def resource_path(self, resource: Any) -> NoReturn: + raise FileNotFoundError(resource) + + def is_resource(self, path: StrPath) -> bool: + return self.files().joinpath(path).is_file() + + def contents(self) -> Iterator[str]: + return (item.name for item in self.files().iterdir()) diff --git a/Lib/importlib/resources/readers.py b/Lib/importlib/resources/readers.py new file mode 100644 index 00000000000..80cb320dd8b --- /dev/null +++ b/Lib/importlib/resources/readers.py @@ -0,0 +1,120 @@ +import collections +import operator +import pathlib +import zipfile + +from . import abc + +from ._itertools import unique_everseen + + +def remove_duplicates(items): + return iter(collections.OrderedDict.fromkeys(items)) + + +class FileReader(abc.TraversableResources): + def __init__(self, loader): + self.path = pathlib.Path(loader.path).parent + + def resource_path(self, resource): + """ + Return the file system path to prevent + `resources.path()` from creating a temporary + copy. + """ + return str(self.path.joinpath(resource)) + + def files(self): + return self.path + + +class ZipReader(abc.TraversableResources): + def __init__(self, loader, module): + _, _, name = module.rpartition('.') + self.prefix = loader.prefix.replace('\\', '/') + name + '/' + self.archive = loader.archive + + def open_resource(self, resource): + try: + return super().open_resource(resource) + except KeyError as exc: + raise FileNotFoundError(exc.args[0]) + + def is_resource(self, path): + # workaround for `zipfile.Path.is_file` returning true + # for non-existent paths. + target = self.files().joinpath(path) + return target.is_file() and target.exists() + + def files(self): + return zipfile.Path(self.archive, self.prefix) + + +class MultiplexedPath(abc.Traversable): + """ + Given a series of Traversable objects, implement a merged + version of the interface across all objects. Useful for + namespace packages which may be multihomed at a single + name. + """ + + def __init__(self, *paths): + self._paths = list(map(pathlib.Path, remove_duplicates(paths))) + if not self._paths: + message = 'MultiplexedPath must contain at least one path' + raise FileNotFoundError(message) + if not all(path.is_dir() for path in self._paths): + raise NotADirectoryError('MultiplexedPath only supports directories') + + def iterdir(self): + files = (file for path in self._paths for file in path.iterdir()) + return unique_everseen(files, key=operator.attrgetter('name')) + + def read_bytes(self): + raise FileNotFoundError(f'{self} is not a file') + + def read_text(self, *args, **kwargs): + raise FileNotFoundError(f'{self} is not a file') + + def is_dir(self): + return True + + def is_file(self): + return False + + def joinpath(self, *descendants): + try: + return super().joinpath(*descendants) + except abc.TraversalError: + # One of the paths did not resolve (a directory does not exist). + # Just return something that will not exist. + return self._paths[0].joinpath(*descendants) + + def open(self, *args, **kwargs): + raise FileNotFoundError(f'{self} is not a file') + + @property + def name(self): + return self._paths[0].name + + def __repr__(self): + paths = ', '.join(f"'{path}'" for path in self._paths) + return f'MultiplexedPath({paths})' + + +class NamespaceReader(abc.TraversableResources): + def __init__(self, namespace_path): + if 'NamespacePath' not in str(namespace_path): + raise ValueError('Invalid path') + self.path = MultiplexedPath(*list(namespace_path)) + + def resource_path(self, resource): + """ + Return the file system path to prevent + `resources.path()` from creating a temporary + copy. + """ + return str(self.path.joinpath(resource)) + + def files(self): + return self.path diff --git a/Lib/importlib/resources/simple.py b/Lib/importlib/resources/simple.py new file mode 100644 index 00000000000..7770c922c84 --- /dev/null +++ b/Lib/importlib/resources/simple.py @@ -0,0 +1,106 @@ +""" +Interface adapters for low-level readers. +""" + +import abc +import io +import itertools +from typing import BinaryIO, List + +from .abc import Traversable, TraversableResources + + +class SimpleReader(abc.ABC): + """ + The minimum, low-level interface required from a resource + provider. + """ + + @property + @abc.abstractmethod + def package(self) -> str: + """ + The name of the package for which this reader loads resources. + """ + + @abc.abstractmethod + def children(self) -> List['SimpleReader']: + """ + Obtain an iterable of SimpleReader for available + child containers (e.g. directories). + """ + + @abc.abstractmethod + def resources(self) -> List[str]: + """ + Obtain available named resources for this virtual package. + """ + + @abc.abstractmethod + def open_binary(self, resource: str) -> BinaryIO: + """ + Obtain a File-like for a named resource. + """ + + @property + def name(self): + return self.package.split('.')[-1] + + +class ResourceContainer(Traversable): + """ + Traversable container for a package's resources via its reader. + """ + + def __init__(self, reader: SimpleReader): + self.reader = reader + + def is_dir(self): + return True + + def is_file(self): + return False + + def iterdir(self): + files = (ResourceHandle(self, name) for name in self.reader.resources) + dirs = map(ResourceContainer, self.reader.children()) + return itertools.chain(files, dirs) + + def open(self, *args, **kwargs): + raise IsADirectoryError() + + +class ResourceHandle(Traversable): + """ + Handle to a named resource in a ResourceReader. + """ + + def __init__(self, parent: ResourceContainer, name: str): + self.parent = parent + self.name = name # type: ignore + + def is_file(self): + return True + + def is_dir(self): + return False + + def open(self, mode='r', *args, **kwargs): + stream = self.parent.reader.open_binary(self.name) + if 'b' not in mode: + stream = io.TextIOWrapper(*args, **kwargs) + return stream + + def joinpath(self, name): + raise RuntimeError("Cannot traverse into a resource") + + +class TraversableReader(TraversableResources, SimpleReader): + """ + A TraversableResources based on SimpleReader. Resource providers + may derive from this class to provide the TraversableResources + interface by supplying the SimpleReader interface. + """ + + def files(self): + return ResourceContainer(self) diff --git a/Lib/importlib/simple.py b/Lib/importlib/simple.py index da073cbdb11..845bb903647 100644 --- a/Lib/importlib/simple.py +++ b/Lib/importlib/simple.py @@ -1,116 +1,14 @@ """ -Interface adapters for low-level readers. +Compatibility shim for .resources.simple as found on Python 3.10. + +Consumers that can rely on Python 3.11 should use the other +module directly. """ -import abc -import io -import itertools -from typing import BinaryIO, List +from .resources.simple import ( + SimpleReader, ResourceHandle, ResourceContainer, TraversableReader, +) -from .abc import Traversable, TraversableResources - - -class SimpleReader(abc.ABC): - """ - The minimum, low-level interface required from a resource - provider. - """ - - @abc.abstractproperty - def package(self): - # type: () -> str - """ - The name of the package for which this reader loads resources. - """ - - @abc.abstractmethod - def children(self): - # type: () -> List['SimpleReader'] - """ - Obtain an iterable of SimpleReader for available - child containers (e.g. directories). - """ - - @abc.abstractmethod - def resources(self): - # type: () -> List[str] - """ - Obtain available named resources for this virtual package. - """ - - @abc.abstractmethod - def open_binary(self, resource): - # type: (str) -> BinaryIO - """ - Obtain a File-like for a named resource. - """ - - @property - def name(self): - return self.package.split('.')[-1] - - -class ResourceHandle(Traversable): - """ - Handle to a named resource in a ResourceReader. - """ - - def __init__(self, parent, name): - # type: (ResourceContainer, str) -> None - self.parent = parent - self.name = name # type: ignore - - def is_file(self): - return True - - def is_dir(self): - return False - - def open(self, mode='r', *args, **kwargs): - stream = self.parent.reader.open_binary(self.name) - if 'b' not in mode: - stream = io.TextIOWrapper(*args, **kwargs) - return stream - - def joinpath(self, name): - raise RuntimeError("Cannot traverse into a resource") - - -class ResourceContainer(Traversable): - """ - Traversable container for a package's resources via its reader. - """ - - def __init__(self, reader): - # type: (SimpleReader) -> None - self.reader = reader - - def is_dir(self): - return True - - def is_file(self): - return False - - def iterdir(self): - files = (ResourceHandle(self, name) for name in self.reader.resources) - dirs = map(ResourceContainer, self.reader.children()) - return itertools.chain(files, dirs) - - def open(self, *args, **kwargs): - raise IsADirectoryError() - - def joinpath(self, name): - return next( - traversable for traversable in self.iterdir() if traversable.name == name - ) - - -class TraversableReader(TraversableResources, SimpleReader): - """ - A TraversableResources based on SimpleReader. Resource providers - may derive from this class to provide the TraversableResources - interface by supplying the SimpleReader interface. - """ - - def files(self): - return ResourceContainer(self) +__all__ = [ + 'SimpleReader', 'ResourceHandle', 'ResourceContainer', 'TraversableReader', +] diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py index 8623c89840c..5294578cc26 100644 --- a/Lib/importlib/util.py +++ b/Lib/importlib/util.py @@ -11,12 +11,9 @@ from ._bootstrap_external import decode_source from ._bootstrap_external import source_from_cache from ._bootstrap_external import spec_from_file_location -from contextlib import contextmanager import _imp -import functools import sys import types -import warnings def source_hash(source_bytes): @@ -63,10 +60,10 @@ def _find_spec_from_path(name, path=None): try: spec = module.__spec__ except AttributeError: - raise ValueError('{}.__spec__ is not set'.format(name)) from None + raise ValueError(f'{name}.__spec__ is not set') from None else: if spec is None: - raise ValueError('{}.__spec__ is None'.format(name)) + raise ValueError(f'{name}.__spec__ is None') return spec @@ -108,117 +105,13 @@ def find_spec(name, package=None): try: spec = module.__spec__ except AttributeError: - raise ValueError('{}.__spec__ is not set'.format(name)) from None + raise ValueError(f'{name}.__spec__ is not set') from None else: if spec is None: - raise ValueError('{}.__spec__ is None'.format(name)) + raise ValueError(f'{name}.__spec__ is None') return spec -@contextmanager -def _module_to_load(name): - is_reload = name in sys.modules - - module = sys.modules.get(name) - if not is_reload: - # This must be done before open() is called as the 'io' module - # implicitly imports 'locale' and would otherwise trigger an - # infinite loop. - module = type(sys)(name) - # This must be done before putting the module in sys.modules - # (otherwise an optimization shortcut in import.c becomes wrong) - module.__initializing__ = True - sys.modules[name] = module - try: - yield module - except Exception: - if not is_reload: - try: - del sys.modules[name] - except KeyError: - pass - finally: - module.__initializing__ = False - - -def set_package(fxn): - """Set __package__ on the returned module. - - This function is deprecated. - - """ - @functools.wraps(fxn) - def set_package_wrapper(*args, **kwargs): - warnings.warn('The import system now takes care of this automatically; ' - 'this decorator is slated for removal in Python 3.12', - DeprecationWarning, stacklevel=2) - module = fxn(*args, **kwargs) - if getattr(module, '__package__', None) is None: - module.__package__ = module.__name__ - if not hasattr(module, '__path__'): - module.__package__ = module.__package__.rpartition('.')[0] - return module - return set_package_wrapper - - -def set_loader(fxn): - """Set __loader__ on the returned module. - - This function is deprecated. - - """ - @functools.wraps(fxn) - def set_loader_wrapper(self, *args, **kwargs): - warnings.warn('The import system now takes care of this automatically; ' - 'this decorator is slated for removal in Python 3.12', - DeprecationWarning, stacklevel=2) - module = fxn(self, *args, **kwargs) - if getattr(module, '__loader__', None) is None: - module.__loader__ = self - return module - return set_loader_wrapper - - -def module_for_loader(fxn): - """Decorator to handle selecting the proper module for loaders. - - The decorated function is passed the module to use instead of the module - name. The module passed in to the function is either from sys.modules if - it already exists or is a new module. If the module is new, then __name__ - is set the first argument to the method, __loader__ is set to self, and - __package__ is set accordingly (if self.is_package() is defined) will be set - before it is passed to the decorated function (if self.is_package() does - not work for the module it will be set post-load). - - If an exception is raised and the decorator created the module it is - subsequently removed from sys.modules. - - The decorator assumes that the decorated function takes the module name as - the second argument. - - """ - warnings.warn('The import system now takes care of this automatically; ' - 'this decorator is slated for removal in Python 3.12', - DeprecationWarning, stacklevel=2) - @functools.wraps(fxn) - def module_for_loader_wrapper(self, fullname, *args, **kwargs): - with _module_to_load(fullname) as module: - module.__loader__ = self - try: - is_package = self.is_package(fullname) - except (ImportError, AttributeError): - pass - else: - if is_package: - module.__package__ = fullname - else: - module.__package__ = fullname.rpartition('.')[0] - # If __package__ was not set above, __import__() will do it later. - return fxn(self, module, *args, **kwargs) - - return module_for_loader_wrapper - - class _LazyModule(types.ModuleType): """A subclass of the module type which triggers loading upon attribute access.""" diff --git a/Lib/inspect.py b/Lib/inspect.py index dd891112570..8bb3a375735 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -33,6 +33,107 @@ Here are some of the useful functions provided by this module: __author__ = ('Ka-Ping Yee ', 'Yury Selivanov ') +__all__ = [ + "ArgInfo", + "Arguments", + "Attribute", + "BlockFinder", + "BoundArguments", + "CORO_CLOSED", + "CORO_CREATED", + "CORO_RUNNING", + "CORO_SUSPENDED", + "CO_ASYNC_GENERATOR", + "CO_COROUTINE", + "CO_GENERATOR", + "CO_ITERABLE_COROUTINE", + "CO_NESTED", + "CO_NEWLOCALS", + "CO_NOFREE", + "CO_OPTIMIZED", + "CO_VARARGS", + "CO_VARKEYWORDS", + "ClassFoundException", + "ClosureVars", + "EndOfBlock", + "FrameInfo", + "FullArgSpec", + "GEN_CLOSED", + "GEN_CREATED", + "GEN_RUNNING", + "GEN_SUSPENDED", + "Parameter", + "Signature", + "TPFLAGS_IS_ABSTRACT", + "Traceback", + "classify_class_attrs", + "cleandoc", + "currentframe", + "findsource", + "formatannotation", + "formatannotationrelativeto", + "formatargvalues", + "get_annotations", + "getabsfile", + "getargs", + "getargvalues", + "getattr_static", + "getblock", + "getcallargs", + "getclasstree", + "getclosurevars", + "getcomments", + "getcoroutinelocals", + "getcoroutinestate", + "getdoc", + "getfile", + "getframeinfo", + "getfullargspec", + "getgeneratorlocals", + "getgeneratorstate", + "getinnerframes", + "getlineno", + "getmembers", + "getmembers_static", + "getmodule", + "getmodulename", + "getmro", + "getouterframes", + "getsource", + "getsourcefile", + "getsourcelines", + "indentsize", + "isabstract", + "isasyncgen", + "isasyncgenfunction", + "isawaitable", + "isbuiltin", + "isclass", + "iscode", + "iscoroutine", + "iscoroutinefunction", + "isdatadescriptor", + "isframe", + "isfunction", + "isgenerator", + "isgeneratorfunction", + "isgetsetdescriptor", + "ismemberdescriptor", + "ismethod", + "ismethoddescriptor", + "ismethodwrapper", + "ismodule", + "isroutine", + "istraceback", + "markcoroutinefunction", + "signature", + "stack", + "trace", + "unwrap", + "walktree", +] + + import abc import ast import dis @@ -49,6 +150,7 @@ import token import types import functools import builtins +from keyword import iskeyword from operator import attrgetter from collections import namedtuple, OrderedDict @@ -57,6 +159,7 @@ from collections import namedtuple, OrderedDict mod_dict = globals() for k, v in dis.COMPILER_FLAG_NAMES.items(): mod_dict["CO_" + v] = k +del k, v, mod_dict # See Include/object.h TPFLAGS_IS_ABSTRACT = 1 << 20 @@ -179,30 +282,15 @@ def get_annotations(obj, *, globals=None, locals=None, eval_str=False): # ----------------------------------------------------------- type-checking def ismodule(object): - """Return true if the object is a module. - - Module objects provide these attributes: - __cached__ pathname to byte compiled file - __doc__ documentation string - __file__ filename (missing for built-in modules)""" + """Return true if the object is a module.""" return isinstance(object, types.ModuleType) def isclass(object): - """Return true if the object is a class. - - Class objects provide these attributes: - __doc__ documentation string - __module__ name of module in which this class was defined""" + """Return true if the object is a class.""" return isinstance(object, type) def ismethod(object): - """Return true if the object is an instance method. - - Instance method objects provide these attributes: - __doc__ documentation string - __name__ name with which this method was defined - __func__ function object containing implementation of method - __self__ instance to which this method is bound""" + """Return true if the object is an instance method.""" return isinstance(object, types.MethodType) def ismethoddescriptor(object): @@ -293,7 +381,7 @@ def _has_code_flag(f, flag): while ismethod(f): f = f.__func__ f = functools._unwrap_partial(f) - if not isfunction(f): + if not (isfunction(f) or _signature_is_functionlike(f)): return False return bool(f.__code__.co_flags & flag) @@ -304,12 +392,31 @@ def isgeneratorfunction(obj): See help(isfunction) for a list of attributes.""" return _has_code_flag(obj, CO_GENERATOR) +# A marker for markcoroutinefunction and iscoroutinefunction. +_is_coroutine_marker = object() + +def _has_coroutine_mark(f): + while ismethod(f): + f = f.__func__ + f = functools._unwrap_partial(f) + return getattr(f, "_is_coroutine_marker", None) is _is_coroutine_marker + +def markcoroutinefunction(func): + """ + Decorator to ensure callable is recognised as a coroutine function. + """ + if hasattr(func, '__func__'): + func = func.__func__ + func._is_coroutine_marker = _is_coroutine_marker + return func + def iscoroutinefunction(obj): """Return true if the object is a coroutine function. - Coroutine functions are defined with "async def" syntax. + Coroutine functions are normally defined with "async def" syntax, but may + be marked via markcoroutinefunction. """ - return _has_code_flag(obj, CO_COROUTINE) + return _has_code_flag(obj, CO_COROUTINE) or _has_coroutine_mark(obj) def isasyncgenfunction(obj): """Return true if the object is an asynchronous generator function. @@ -409,12 +516,17 @@ def isbuiltin(object): __self__ instance to which a method is bound, or None""" return isinstance(object, types.BuiltinFunctionType) +def ismethodwrapper(object): + """Return true if the object is a method wrapper.""" + return isinstance(object, types.MethodWrapperType) + def isroutine(object): """Return true if the object is any kind of function or method.""" return (isbuiltin(object) or isfunction(object) or ismethod(object) - or ismethoddescriptor(object)) + or ismethoddescriptor(object) + or ismethodwrapper(object)) def isabstract(object): """Return true if the object is an abstract base class (ABC).""" @@ -440,32 +552,30 @@ def isabstract(object): return True return False -def getmembers(object, predicate=None): - """Return all members of an object as (name, value) pairs sorted by name. - Optionally, only return members that satisfy a given predicate.""" - if isclass(object): - mro = (object,) + getmro(object) - else: - mro = () +def _getmembers(object, predicate, getter): results = [] processed = set() names = dir(object) - # :dd any DynamicClassAttributes to the list of names if object is a class; - # this may result in duplicate entries if, for example, a virtual - # attribute with the same name as a DynamicClassAttribute exists - try: - for base in object.__bases__: - for k, v in base.__dict__.items(): - if isinstance(v, types.DynamicClassAttribute): - names.append(k) - except AttributeError: - pass + if isclass(object): + mro = getmro(object) + # add any DynamicClassAttributes to the list of names if object is a class; + # this may result in duplicate entries if, for example, a virtual + # attribute with the same name as a DynamicClassAttribute exists + try: + for base in object.__bases__: + for k, v in base.__dict__.items(): + if isinstance(v, types.DynamicClassAttribute): + names.append(k) + except AttributeError: + pass + else: + mro = () for key in names: # First try to get the value via getattr. Some descriptors don't # like calling their __get__ (see bug #1785), so fall back to # looking in the __dict__. try: - value = getattr(object, key) + value = getter(object, key) # handle the duplicate key if key in processed: raise AttributeError @@ -484,6 +594,25 @@ def getmembers(object, predicate=None): results.sort(key=lambda pair: pair[0]) return results +def getmembers(object, predicate=None): + """Return all members of an object as (name, value) pairs sorted by name. + Optionally, only return members that satisfy a given predicate.""" + return _getmembers(object, predicate, getattr) + +def getmembers_static(object, predicate=None): + """Return all members of an object as (name, value) pairs sorted by name + without triggering dynamic lookup via the descriptor protocol, + __getattr__ or __getattribute__. Optionally, only return members that + satisfy a given predicate. + + Note: this function may not be able to retrieve all members + that getmembers can fetch (like dynamically created attributes) + and may find members that getmembers can't (like descriptors + that raise AttributeError). It can also return descriptor objects + instead of instance members in some cases. + """ + return _getmembers(object, predicate, getattr_static) + Attribute = namedtuple('Attribute', 'name kind defining_class object') def classify_class_attrs(cls): @@ -547,7 +676,7 @@ def classify_class_attrs(cls): if name == '__dict__': raise Exception("__dict__ is special, don't want the proxy") get_obj = getattr(cls, name) - except Exception as exc: + except Exception: pass else: homecls = getattr(get_obj, "__objclass__", homecls) @@ -822,6 +951,9 @@ def getsourcefile(object): elif any(filename.endswith(s) for s in importlib.machinery.EXTENSION_SUFFIXES): return None + # return a filename found in the linecache even if it doesn't exist on disk + if filename in linecache.cache: + return filename if os.path.exists(filename): return filename # only return a non-existent filename if the module has a PEP 302 loader @@ -830,9 +962,6 @@ def getsourcefile(object): return filename elif getattr(getattr(module, "__spec__", None), "loader", None) is not None: return filename - # or it is in the linecache - elif filename in linecache.cache: - return filename def getabsfile(object, _filename=None): """Return an absolute path to the source or compiled file for an object. @@ -1051,7 +1180,6 @@ class BlockFinder: self.started = False self.passline = False self.indecorator = False - self.decoratorhasargs = False self.last = 1 self.body_col0 = None @@ -1066,13 +1194,6 @@ class BlockFinder: self.islambda = True self.started = True self.passline = True # skip to the end of the line - elif token == "(": - if self.indecorator: - self.decoratorhasargs = True - elif token == ")": - if self.indecorator: - self.indecorator = False - self.decoratorhasargs = False elif type == tokenize.NEWLINE: self.passline = False # stop skipping when a NEWLINE is seen self.last = srowcol[0] @@ -1080,7 +1201,7 @@ class BlockFinder: raise EndOfBlock # hitting a NEWLINE when in a decorator without args # ends the decorator - if self.indecorator and not self.decoratorhasargs: + if self.indecorator: self.indecorator = False elif self.passline: pass @@ -1201,7 +1322,6 @@ def getargs(co): nkwargs = co.co_kwonlyargcount args = list(names[:nargs]) kwonlyargs = list(names[nargs:nargs+nkwargs]) - step = 0 nargs += nkwargs varargs = None @@ -1324,7 +1444,10 @@ def getargvalues(frame): def formatannotation(annotation, base_module=None): if getattr(annotation, '__module__', None) == 'typing': - return repr(annotation).replace('typing.', '') + def repl(match): + text = match.group() + return text.removeprefix('typing.') + return re.sub(r'[\w\.]+', repl, repr(annotation)) if isinstance(annotation, types.GenericAlias): return str(annotation) if isinstance(annotation, type): @@ -1515,7 +1638,30 @@ def getclosurevars(func): # -------------------------------------------------- stack frame extraction -Traceback = namedtuple('Traceback', 'filename lineno function code_context index') +_Traceback = namedtuple('_Traceback', 'filename lineno function code_context index') + +class Traceback(_Traceback): + def __new__(cls, filename, lineno, function, code_context, index, *, positions=None): + instance = super().__new__(cls, filename, lineno, function, code_context, index) + instance.positions = positions + return instance + + def __repr__(self): + return ('Traceback(filename={!r}, lineno={!r}, function={!r}, ' + 'code_context={!r}, index={!r}, positions={!r})'.format( + self.filename, self.lineno, self.function, self.code_context, + self.index, self.positions)) + +def _get_code_position_from_tb(tb): + code, instruction_index = tb.tb_frame.f_code, tb.tb_lasti + return _get_code_position(code, instruction_index) + +def _get_code_position(code, instruction_index): + if instruction_index < 0: + return (None, None, None, None) + positions_gen = code.co_positions() + # The nth entry in code.co_positions() corresponds to instruction (2*n)th since Python 3.10+ + return next(itertools.islice(positions_gen, instruction_index // 2, None)) def getframeinfo(frame, context=1): """Get information about a frame or traceback object. @@ -1526,10 +1672,20 @@ def getframeinfo(frame, context=1): The optional second argument specifies the number of lines of context to return, which are centered around the current line.""" if istraceback(frame): + positions = _get_code_position_from_tb(frame) lineno = frame.tb_lineno frame = frame.tb_frame else: lineno = frame.f_lineno + positions = _get_code_position(frame.f_code, frame.f_lasti) + + if positions[0] is None: + frame, *positions = (frame, lineno, *positions[1:]) + else: + frame, *positions = (frame, *positions) + + lineno = positions[0] + if not isframe(frame): raise TypeError('{!r} is not a frame or traceback object'.format(frame)) @@ -1547,14 +1703,26 @@ def getframeinfo(frame, context=1): else: lines = index = None - return Traceback(filename, lineno, frame.f_code.co_name, lines, index) + return Traceback(filename, lineno, frame.f_code.co_name, lines, + index, positions=dis.Positions(*positions)) def getlineno(frame): """Get the line number from a frame object, allowing for optimization.""" # FrameType.f_lineno is now a descriptor that grovels co_lnotab return frame.f_lineno -FrameInfo = namedtuple('FrameInfo', ('frame',) + Traceback._fields) +_FrameInfo = namedtuple('_FrameInfo', ('frame',) + Traceback._fields) +class FrameInfo(_FrameInfo): + def __new__(cls, frame, filename, lineno, function, code_context, index, *, positions=None): + instance = super().__new__(cls, frame, filename, lineno, function, code_context, index) + instance.positions = positions + return instance + + def __repr__(self): + return ('FrameInfo(frame={!r}, filename={!r}, lineno={!r}, function={!r}, ' + 'code_context={!r}, index={!r}, positions={!r})'.format( + self.frame, self.filename, self.lineno, self.function, + self.code_context, self.index, self.positions)) def getouterframes(frame, context=1): """Get a list of records for a frame and all higher (calling) frames. @@ -1563,8 +1731,9 @@ def getouterframes(frame, context=1): name, a list of lines of context, and index within the context.""" framelist = [] while frame: - frameinfo = (frame,) + getframeinfo(frame, context) - framelist.append(FrameInfo(*frameinfo)) + traceback_info = getframeinfo(frame, context) + frameinfo = (frame,) + traceback_info + framelist.append(FrameInfo(*frameinfo, positions=traceback_info.positions)) frame = frame.f_back return framelist @@ -1575,8 +1744,9 @@ def getinnerframes(tb, context=1): name, a list of lines of context, and index within the context.""" framelist = [] while tb: - frameinfo = (tb.tb_frame,) + getframeinfo(tb, context) - framelist.append(FrameInfo(*frameinfo)) + traceback_info = getframeinfo(tb, context) + frameinfo = (tb.tb_frame,) + traceback_info + framelist.append(FrameInfo(*frameinfo, positions=traceback_info.positions)) tb = tb.tb_next return framelist @@ -1703,11 +1873,11 @@ def getgeneratorstate(generator): """ if generator.gi_running: return GEN_RUNNING + if generator.gi_suspended: + return GEN_SUSPENDED if generator.gi_frame is None: return GEN_CLOSED - if generator.gi_frame.f_lasti == -1: - return GEN_CREATED - return GEN_SUSPENDED + return GEN_CREATED def getgeneratorlocals(generator): @@ -1745,11 +1915,11 @@ def getcoroutinestate(coroutine): """ if coroutine.cr_running: return CORO_RUNNING + if coroutine.cr_suspended: + return CORO_SUSPENDED if coroutine.cr_frame is None: return CORO_CLOSED - if coroutine.cr_frame.f_lasti == -1: - return CORO_CREATED - return CORO_SUSPENDED + return CORO_CREATED def getcoroutinelocals(coroutine): @@ -1770,13 +1940,9 @@ def getcoroutinelocals(coroutine): ############################################################################### -_WrapperDescriptor = type(type.__call__) -_MethodWrapper = type(all.__call__) -_ClassMethodWrapper = type(int.__dict__['from_bytes']) - -_NonUserDefinedCallables = (_WrapperDescriptor, - _MethodWrapper, - _ClassMethodWrapper, +_NonUserDefinedCallables = (types.WrapperDescriptorType, + types.MethodWrapperType, + types.ClassMethodDescriptorType, types.BuiltinFunctionType) @@ -1954,7 +2120,7 @@ def _signature_strip_non_python_syntax(signature): self_parameter = None last_positional_only = None - lines = [l.encode('ascii') for l in signature.split('\n')] + lines = [l.encode('ascii') for l in signature.split('\n') if l] generator = iter(lines).__next__ token_stream = tokenize.tokenize(generator) @@ -2030,7 +2196,6 @@ def _signature_fromstr(cls, obj, s, skip_bound_arg=True): parameters = [] empty = Parameter.empty - invalid = object() module = None module_dict = {} @@ -2054,11 +2219,11 @@ def _signature_fromstr(cls, obj, s, skip_bound_arg=True): try: value = eval(s, sys_module_dict) except NameError: - raise RuntimeError() + raise ValueError if isinstance(value, (str, int, float, bytes, bool, type(None))): return ast.Constant(value) - raise RuntimeError() + raise ValueError class RewriteSymbolics(ast.NodeTransformer): def visit_Attribute(self, node): @@ -2068,7 +2233,7 @@ def _signature_fromstr(cls, obj, s, skip_bound_arg=True): a.append(n.attr) n = n.value if not isinstance(n, ast.Name): - raise RuntimeError() + raise ValueError a.append(n.id) value = ".".join(reversed(a)) return wrap_value(value) @@ -2078,19 +2243,29 @@ def _signature_fromstr(cls, obj, s, skip_bound_arg=True): raise ValueError() return wrap_value(node.id) + def visit_BinOp(self, node): + # Support constant folding of a couple simple binary operations + # commonly used to define default values in text signatures + left = self.visit(node.left) + right = self.visit(node.right) + if not isinstance(left, ast.Constant) or not isinstance(right, ast.Constant): + raise ValueError + if isinstance(node.op, ast.Add): + return ast.Constant(left.value + right.value) + elif isinstance(node.op, ast.Sub): + return ast.Constant(left.value - right.value) + elif isinstance(node.op, ast.BitOr): + return ast.Constant(left.value | right.value) + raise ValueError + def p(name_node, default_node, default=empty): name = parse_name(name_node) - if name is invalid: - return None if default_node and default_node is not _empty: try: default_node = RewriteSymbolics().visit(default_node) - o = ast.literal_eval(default_node) + default = ast.literal_eval(default_node) except ValueError: - o = invalid - if o is invalid: - return None - default = o if o is not invalid else default + raise ValueError("{!r} builtin has invalid signature".format(obj)) from None parameters.append(Parameter(name, kind, default=default, annotation=empty)) # non-keyword-only parameters @@ -2287,7 +2462,10 @@ def _signature_from_callable(obj, *, # Was this function wrapped by a decorator? if follow_wrapper_chains: - obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__"))) + # Unwrap until we find an explicit signature or a MethodType (which will be + # handled explicitly below). + obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__") + or isinstance(f, types.MethodType))) if isinstance(obj, types.MethodType): # If the unwrapped object is a *method*, we might want to # skip its first parameter (self). @@ -2300,10 +2478,18 @@ def _signature_from_callable(obj, *, pass else: if sig is not None: + # since __text_signature__ is not writable on classes, __signature__ + # may contain text (or be a callable that returns text); + # if so, convert it + o_sig = sig + if not isinstance(sig, (Signature, str)) and callable(sig): + sig = sig() + if isinstance(sig, str): + sig = _signature_fromstr(sigcls, obj, sig) if not isinstance(sig, Signature): raise TypeError( 'unexpected object {!r} in __signature__ ' - 'attribute'.format(sig)) + 'attribute'.format(o_sig)) return sig try: @@ -2395,9 +2581,9 @@ def _signature_from_callable(obj, *, pass else: if text_sig: - # If 'obj' class has a __text_signature__ attribute: + # If 'base' class has a __text_signature__ attribute: # return a signature based on it - return _signature_fromstr(sigcls, obj, text_sig) + return _signature_fromstr(sigcls, base, text_sig) # No '__text_signature__' was found for the 'obj' class. # Last option is to check if its '__init__' is @@ -2416,7 +2602,7 @@ def _signature_from_callable(obj, *, elif not isinstance(obj, _NonUserDefinedCallables): # An object with __call__ # We also check that the 'obj' is not an instance of - # _WrapperDescriptor or _MethodWrapper to avoid + # types.WrapperDescriptorType or types.MethodWrapperType to avoid # infinite recursion (and even potential segfault) call = _signature_get_user_defined_method(type(obj), '__call__') if call is not None: @@ -2451,15 +2637,21 @@ class _empty: class _ParameterKind(enum.IntEnum): - POSITIONAL_ONLY = 0 - POSITIONAL_OR_KEYWORD = 1 - VAR_POSITIONAL = 2 - KEYWORD_ONLY = 3 - VAR_KEYWORD = 4 + POSITIONAL_ONLY = 'positional-only' + POSITIONAL_OR_KEYWORD = 'positional or keyword' + VAR_POSITIONAL = 'variadic positional' + KEYWORD_ONLY = 'keyword-only' + VAR_KEYWORD = 'variadic keyword' - @property - def description(self): - return _PARAM_NAME_MAPPING[self] + def __new__(cls, description): + value = len(cls.__members__) + member = int.__new__(cls, value) + member._value_ = value + member.description = description + return member + + def __str__(self): + return self.name _POSITIONAL_ONLY = _ParameterKind.POSITIONAL_ONLY _POSITIONAL_OR_KEYWORD = _ParameterKind.POSITIONAL_OR_KEYWORD @@ -2467,14 +2659,6 @@ _VAR_POSITIONAL = _ParameterKind.VAR_POSITIONAL _KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY _VAR_KEYWORD = _ParameterKind.VAR_KEYWORD -_PARAM_NAME_MAPPING = { - _POSITIONAL_ONLY: 'positional-only', - _POSITIONAL_OR_KEYWORD: 'positional or keyword', - _VAR_POSITIONAL: 'variadic positional', - _KEYWORD_ONLY: 'keyword-only', - _VAR_KEYWORD: 'variadic keyword' -} - class Parameter: """Represents a parameter in a function signature. @@ -2543,7 +2727,10 @@ class Parameter: self._kind = _POSITIONAL_ONLY name = 'implicit{}'.format(name[1:]) - if not name.isidentifier(): + # It's possible for C functions to have a positional-only parameter + # where the name is a keyword, so for compatibility we'll allow it. + is_keyword = iskeyword(name) and self._kind is not _POSITIONAL_ONLY + if is_keyword or not name.isidentifier(): raise ValueError('{!r} is not a valid parameter name'.format(name)) self._name = name @@ -2946,8 +3133,12 @@ class Signature: parameters_ex = (param,) break else: - msg = 'missing a required argument: {arg!r}' - msg = msg.format(arg=param.name) + if param.kind == _KEYWORD_ONLY: + argtype = ' keyword-only' + else: + argtype = '' + msg = 'missing a required{argtype} argument: {arg!r}' + msg = msg.format(arg=param.name, argtype=argtype) raise TypeError(msg) from None else: # We have a positional argument to process diff --git a/Lib/io.py b/Lib/io.py index 2a6140c3dd5..50ce97436ac 100644 --- a/Lib/io.py +++ b/Lib/io.py @@ -57,22 +57,6 @@ from _io import (DEFAULT_BUFFER_SIZE, BlockingIOError, UnsupportedOperation, IncrementalNewlineDecoder, text_encoding, TextIOWrapper) -def __getattr__(name): - if name == "OpenWrapper": - # bpo-43680: Until Python 3.9, _pyio.open was not a static method and - # builtins.open was set to OpenWrapper to not become a bound method - # when set to a class variable. _io.open is a built-in function whereas - # _pyio.open is a Python function. In Python 3.10, _pyio.open() is now - # a static method, and builtins.open() is now io.open(). - import warnings - warnings.warn('OpenWrapper is deprecated, use open instead', - DeprecationWarning, stacklevel=2) - global OpenWrapper - OpenWrapper = open - return OpenWrapper - raise AttributeError(name) - - # Pretend this exception was created here. UnsupportedOperation.__module__ = "io" diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index e601f6f476e..1cb71d8032e 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -51,8 +51,7 @@ def ip_address(address): except (AddressValueError, NetmaskValueError): pass - raise ValueError('%r does not appear to be an IPv4 or IPv6 address' % - address) + raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 address') def ip_network(address, strict=True): @@ -81,8 +80,7 @@ def ip_network(address, strict=True): except (AddressValueError, NetmaskValueError): pass - raise ValueError('%r does not appear to be an IPv4 or IPv6 network' % - address) + raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 network') def ip_interface(address): @@ -116,8 +114,7 @@ def ip_interface(address): except (AddressValueError, NetmaskValueError): pass - raise ValueError('%r does not appear to be an IPv4 or IPv6 interface' % - address) + raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 interface') def v4_int_to_packed(address): @@ -160,7 +157,7 @@ def _split_optional_netmask(address): """Helper to split the netmask and raise AddressValueError if needed""" addr = str(address).split('/') if len(addr) > 2: - raise AddressValueError("Only one '/' permitted in %r" % address) + raise AddressValueError(f"Only one '/' permitted in {address!r}") return addr @@ -1080,15 +1077,16 @@ class _BaseNetwork(_IPAddressBase): @property def is_private(self): - """Test if this address is allocated for private networks. + """Test if this network belongs to a private range. Returns: - A boolean, True if the address is reserved per + A boolean, True if the network is reserved per iana-ipv4-special-registry or iana-ipv6-special-registry. """ - return (self.network_address.is_private and - self.broadcast_address.is_private) + return any(self.network_address in priv_network and + self.broadcast_address in priv_network + for priv_network in self._constants._private_networks) @property def is_global(self): @@ -1125,6 +1123,15 @@ class _BaseNetwork(_IPAddressBase): return (self.network_address.is_loopback and self.broadcast_address.is_loopback) + +class _BaseConstants: + + _private_networks = [] + + +_BaseNetwork._constants = _BaseConstants + + class _BaseV4: """Base IPv4 object. @@ -1304,7 +1311,7 @@ class IPv4Address(_BaseV4, _BaseAddress): # which converts into a formatted IP string. addr_str = str(address) if '/' in addr_str: - raise AddressValueError("Unexpected '/' in %r" % address) + raise AddressValueError(f"Unexpected '/' in {address!r}") self._ip = self._ip_int_from_string(addr_str) @property @@ -1564,6 +1571,7 @@ class _IPv4Constants: IPv4Address._constants = _IPv4Constants +IPv4Network._constants = _IPv4Constants class _BaseV6: @@ -1913,7 +1921,7 @@ class IPv6Address(_BaseV6, _BaseAddress): # which converts into a formatted IP string. addr_str = str(address) if '/' in addr_str: - raise AddressValueError("Unexpected '/' in %r" % address) + raise AddressValueError(f"Unexpected '/' in {address!r}") addr_str, self._scope_id = self._split_scope_id(addr_str) self._ip = self._ip_int_from_string(addr_str) @@ -2288,3 +2296,4 @@ class _IPv6Constants: IPv6Address._constants = _IPv6Constants +IPv6Network._constants = _IPv6Constants diff --git a/Lib/json/__init__.py b/Lib/json/__init__.py index 2c52bdeba67..256e76a0a67 100644 --- a/Lib/json/__init__.py +++ b/Lib/json/__init__.py @@ -1,4 +1,4 @@ -r"""JSON (JavaScript Object Notation) is a subset of +r"""JSON (JavaScript Object Notation) is a subset of JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data interchange format. @@ -97,7 +97,7 @@ Using json.tool from the shell to validate and pretty-print:: """ __version__ = '2.0.9' __all__ = [ - 'dump', 'dumps', 'load', 'loads', + 'dump', 'dumps', 'load', 'loads', 'AttrDict', 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder', ] @@ -133,7 +133,7 @@ def dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will - result in an ``OverflowError`` (or worse). + result in an ``RecursionError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) @@ -195,7 +195,7 @@ def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will - result in an ``OverflowError`` (or worse). + result in an ``RecursionError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in @@ -357,3 +357,53 @@ def loads(s, *, cls=None, object_hook=None, parse_float=None, if parse_constant is not None: kw['parse_constant'] = parse_constant return cls(**kw).decode(s) + +class AttrDict(dict): + """Dict like object that supports attribute style dotted access. + + This class is intended for use with the *object_hook* in json.loads(): + + >>> from json import loads, AttrDict + >>> json_string = '{"mercury": 88, "venus": 225, "earth": 365, "mars": 687}' + >>> orbital_period = loads(json_string, object_hook=AttrDict) + >>> orbital_period['earth'] # Dict style lookup + 365 + >>> orbital_period.earth # Attribute style lookup + 365 + >>> orbital_period.keys() # All dict methods are present + dict_keys(['mercury', 'venus', 'earth', 'mars']) + + Attribute style access only works for keys that are valid attribute names. + In contrast, dictionary style access works for all keys. + For example, ``d.two words`` contains a space and is not syntactically + valid Python, so ``d["two words"]`` should be used instead. + + If a key has the same name as dictionary method, then a dictionary + lookup finds the key and an attribute lookup finds the method: + + >>> d = AttrDict(items=50) + >>> d['items'] # Lookup the key + 50 + >>> d.items() # Call the method + dict_items([('items', 50)]) + + """ + __slots__ = () + + def __getattr__(self, attr): + try: + return self[attr] + except KeyError: + raise AttributeError(attr) from None + + def __setattr__(self, attr, value): + self[attr] = value + + def __delattr__(self, attr): + try: + del self[attr] + except KeyError: + raise AttributeError(attr) from None + + def __dir__(self): + return list(self) + dir(type(self)) diff --git a/Lib/json/decoder.py b/Lib/json/decoder.py index d7d824454e1..c5d9ae2d0d5 100644 --- a/Lib/json/decoder.py +++ b/Lib/json/decoder.py @@ -252,7 +252,7 @@ def JSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): class JSONDecoder(object): - """Simple JSON decoder + """Simple JSON decoder Performs the following translations in decoding by default: diff --git a/Lib/json/encoder.py b/Lib/json/encoder.py index c8c78b9c237..45f54774188 100644 --- a/Lib/json/encoder.py +++ b/Lib/json/encoder.py @@ -30,6 +30,7 @@ ESCAPE_DCT = { for i in range(0x20): ESCAPE_DCT.setdefault(chr(i), '\\u{0:04x}'.format(i)) #ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,)) +del i INFINITY = float('inf') @@ -71,7 +72,7 @@ encode_basestring_ascii = ( c_encode_basestring_ascii or py_encode_basestring_ascii) class JSONEncoder(object): - """Extensible JSON encoder for Python data structures. + """Extensible JSON encoder for Python data structures. Supports the following objects and types by default: @@ -116,7 +117,7 @@ class JSONEncoder(object): If check_circular is true, then lists, dicts, and custom encoded objects will be checked for circular references during encoding to - prevent an infinite recursion (which would cause an OverflowError). + prevent an infinite recursion (which would cause an RecursionError). Otherwise, no such check takes place. If allow_nan is true, then NaN, Infinity, and -Infinity will be diff --git a/Lib/lib2to3/pgen2/grammar.py b/Lib/lib2to3/pgen2/grammar.py index 6a4d575ac2c..5d550aeb65e 100644 --- a/Lib/lib2to3/pgen2/grammar.py +++ b/Lib/lib2to3/pgen2/grammar.py @@ -186,3 +186,4 @@ for line in opmap_raw.splitlines(): if line: op, name = line.split() opmap[op] = getattr(token, name) +del line, op, name diff --git a/Lib/lib2to3/pgen2/token.py b/Lib/lib2to3/pgen2/token.py index 5f6612f5b30..2a55138e482 100755 --- a/Lib/lib2to3/pgen2/token.py +++ b/Lib/lib2to3/pgen2/token.py @@ -72,7 +72,7 @@ NT_OFFSET = 256 tok_name = {} for _name, _value in list(globals().items()): - if type(_value) is type(0): + if isinstance(_value, int): tok_name[_value] = _name diff --git a/Lib/lib2to3/pytree.py b/Lib/lib2to3/pytree.py index 2a6ef2ef524..729023df028 100644 --- a/Lib/lib2to3/pytree.py +++ b/Lib/lib2to3/pytree.py @@ -720,8 +720,8 @@ class WildcardPattern(BasePattern): r[self.name] = nodes[:count] yield count, r except RuntimeError: - # We fall back to the iterative pattern matching scheme if the recursive - # scheme hits the recursion limit. + # Fall back to the iterative pattern matching scheme if the + # recursive scheme hits the recursion limit (RecursionError). for count, r in self._iterative_matches(nodes): if self.name: r[self.name] = nodes[:count] diff --git a/Lib/lib2to3/tests/test_all_fixers.py b/Lib/lib2to3/tests/test_all_fixers.py deleted file mode 100644 index c0507cf3fbc..00000000000 --- a/Lib/lib2to3/tests/test_all_fixers.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Tests that run all fixer modules over an input stream. - -This has been broken out into its own test module because of its -running time. -""" -# Author: Collin Winter - -# Python imports -import unittest -import test.support - -# Local imports -from . import support - - -@test.support.requires_resource('cpu') -class Test_all(support.TestCase): - - def setUp(self): - self.refactor = support.get_refactorer() - - def test_all_project_files(self): - for filepath in support.all_project_files(): - self.refactor.refactor_file(filepath) - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/linecache.py b/Lib/linecache.py index 23191d6501d..97644a8e379 100644 --- a/Lib/linecache.py +++ b/Lib/linecache.py @@ -135,7 +135,7 @@ def updatecache(filename, module_globals=None): try: with tokenize.open(fullname) as fp: lines = fp.readlines() - except OSError: + except (OSError, UnicodeDecodeError, SyntaxError): return [] if lines and not lines[-1].endswith('\n'): lines[-1] += '\n' diff --git a/Lib/locale.py b/Lib/locale.py index 6d4f5192992..c2c7a04b280 100644 --- a/Lib/locale.py +++ b/Lib/locale.py @@ -26,9 +26,9 @@ import functools # trying the import. So __all__ is also fiddled at the end of the file. __all__ = ["getlocale", "getdefaultlocale", "getpreferredencoding", "Error", "setlocale", "resetlocale", "localeconv", "strcoll", "strxfrm", - "str", "atof", "atoi", "format", "format_string", "currency", + "str", "atof", "atoi", "format_string", "currency", "normalize", "LC_CTYPE", "LC_COLLATE", "LC_TIME", "LC_MONETARY", - "LC_NUMERIC", "LC_ALL", "CHAR_MAX"] + "LC_NUMERIC", "LC_ALL", "CHAR_MAX", "getencoding"] def _strcoll(a,b): """ strcoll(string,string) -> int. @@ -247,21 +247,6 @@ def format_string(f, val, grouping=False, monetary=False): return new_f % val -def format(percent, value, grouping=False, monetary=False, *additional): - """Deprecated, use format_string instead.""" - import warnings - warnings.warn( - "This method will be removed in a future version of Python. " - "Use 'locale.format_string()' instead.", - DeprecationWarning, stacklevel=2 - ) - - match = _percent_re.match(percent) - if not match or len(match.group())!= len(percent): - raise ValueError(("format() must be given exactly one %%char " - "format specifier, %s not valid") % repr(percent)) - return _format(percent, value, grouping, monetary, *additional) - def currency(val, symbol=True, grouping=False, international=False): """Formats val according to the currency settings in the current locale.""" @@ -555,6 +540,12 @@ def getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')): """ + import warnings + warnings.warn( + "Use setlocale(), getencoding() and getlocale() instead", + DeprecationWarning, stacklevel=2 + ) + try: # check if it's supported by the _locale module import _locale @@ -627,23 +618,31 @@ def resetlocale(category=LC_ALL): getdefaultlocale(). category defaults to LC_ALL. """ - _setlocale(category, _build_localename(getdefaultlocale())) + import warnings + warnings.warn( + 'Use locale.setlocale(locale.LC_ALL, "") instead', + DeprecationWarning, stacklevel=2 + ) + + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=DeprecationWarning) + loc = getdefaultlocale() + + _setlocale(category, _build_localename(loc)) try: - from _locale import _get_locale_encoding + from _locale import getencoding except ImportError: - def _get_locale_encoding(): + def getencoding(): if hasattr(sys, 'getandroidapilevel'): # On Android langinfo.h and CODESET are missing, and UTF-8 is # always used in mbstowcs() and wcstombs(). - return 'UTF-8' - if sys.flags.utf8_mode: - return 'UTF-8' + return 'utf-8' encoding = getdefaultlocale()[1] if encoding is None: - # LANG not set, default conservatively to ASCII - encoding = 'ascii' + # LANG not set, default to UTF-8 + encoding = 'utf-8' return encoding try: @@ -651,17 +650,30 @@ try: except NameError: def getpreferredencoding(do_setlocale=True): """Return the charset that the user is likely using.""" - return _get_locale_encoding() + if sys.flags.warn_default_encoding: + import warnings + warnings.warn( + "UTF-8 Mode affects locale.getpreferredencoding(). Consider locale.getencoding() instead.", + EncodingWarning, 2) + if sys.flags.utf8_mode: + return 'utf-8' + return getencoding() else: # On Unix, if CODESET is available, use that. def getpreferredencoding(do_setlocale=True): """Return the charset that the user is likely using, according to the system configuration.""" + + if sys.flags.warn_default_encoding: + import warnings + warnings.warn( + "UTF-8 Mode affects locale.getpreferredencoding(). Consider locale.getencoding() instead.", + EncodingWarning, 2) if sys.flags.utf8_mode: - return 'UTF-8' + return 'utf-8' if not do_setlocale: - return _get_locale_encoding() + return getencoding() old_loc = setlocale(LC_CTYPE) try: @@ -669,7 +681,7 @@ else: setlocale(LC_CTYPE, "") except Error: pass - return _get_locale_encoding() + return getencoding() finally: setlocale(LC_CTYPE, old_loc) @@ -746,6 +758,7 @@ locale_encoding_alias = { for k, v in sorted(locale_encoding_alias.items()): k = k.replace('_', '') locale_encoding_alias.setdefault(k, v) +del k, v # # The locale_alias table maps lowercase alias names to C locale names diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index e49e0d02a80..9241d73d0fd 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2001-2019 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2022 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -18,13 +18,14 @@ Logging package for Python. Based on PEP 282 and comments thereto in comp.lang.python. -Copyright (C) 2001-2019 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2022 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ import sys, os, time, io, re, traceback, warnings, weakref, collections.abc +from types import GenericAlias from string import Template from string import Formatter as StrFormatter @@ -37,7 +38,8 @@ __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'shutdown', 'warn', 'warning', 'getLogRecordFactory', 'setLogRecordFactory', - 'lastResort', 'raiseExceptions', 'getLevelNamesMapping'] + 'lastResort', 'raiseExceptions', 'getLevelNamesMapping', + 'getHandlerByName', 'getHandlerNames'] import threading @@ -63,20 +65,25 @@ _startTime = time.time() raiseExceptions = True # -# If you don't want threading information in the log, set this to zero +# If you don't want threading information in the log, set this to False # logThreads = True # -# If you don't want multiprocessing information in the log, set this to zero +# If you don't want multiprocessing information in the log, set this to False # logMultiprocessing = True # -# If you don't want process information in the log, set this to zero +# If you don't want process information in the log, set this to False # logProcesses = True +# +# If you don't want asyncio task information in the log, set this to False +# +logAsyncioTasks = True + #--------------------------------------------------------------------------- # Level related stuff #--------------------------------------------------------------------------- @@ -159,8 +166,8 @@ def addLevelName(level, levelName): finally: _releaseLock() -if hasattr(sys, '_getframe'): - currentframe = lambda: sys._getframe(3) +if hasattr(sys, "_getframe"): + currentframe = lambda: sys._getframe(1) else: #pragma: no cover def currentframe(): """Return the frame object for the caller's stack frame.""" @@ -184,13 +191,18 @@ else: #pragma: no cover _srcfile = os.path.normcase(addLevelName.__code__.co_filename) # _srcfile is only used in conjunction with sys._getframe(). -# To provide compatibility with older versions of Python, set _srcfile -# to None if _getframe() is not available; this value will prevent -# findCaller() from being called. You can also do this if you want to avoid -# the overhead of fetching caller information, even when _getframe() is -# available. -#if not hasattr(sys, '_getframe'): -# _srcfile = None +# Setting _srcfile to None will prevent findCaller() from being called. This +# way, you can avoid the overhead of fetching caller information. + +# The following is based on warnings._is_internal_frame. It makes sure that +# frames of the import mechanism are skipped when logging at module level and +# using a stacklevel value greater than one. +def _is_internal_frame(frame): + """Signal whether the frame is a CPython or logging module internal.""" + filename = os.path.normcase(frame.f_code.co_filename) + return filename == _srcfile or ( + "importlib" in filename and "_bootstrap" in filename + ) def _checkLevel(level): @@ -328,7 +340,7 @@ class LogRecord(object): self.lineno = lineno self.funcName = func self.created = ct - self.msecs = (ct - int(ct)) * 1000 + self.msecs = int((ct - int(ct)) * 1000) + 0.0 # see gh-89047 self.relativeCreated = (self.created - _startTime) * 1000 if logThreads: self.thread = threading.get_ident() @@ -355,6 +367,15 @@ class LogRecord(object): else: self.process = None + self.taskName = None + if logAsyncioTasks: + asyncio = sys.modules.get('asyncio') + if asyncio: + try: + self.taskName = asyncio.current_task().get_name() + except Exception: + pass + def __repr__(self): return ''%(self.name, self.levelno, self.pathname, self.lineno, self.msg) @@ -490,7 +511,7 @@ class StringTemplateStyle(PercentStyle): def usesTime(self): fmt = self._fmt - return fmt.find('$asctime') >= 0 or fmt.find(self.asctime_format) >= 0 + return fmt.find('$asctime') >= 0 or fmt.find(self.asctime_search) >= 0 def validate(self): pattern = Template.pattern @@ -560,6 +581,7 @@ class Formatter(object): (typically at application startup time) %(thread)d Thread ID (if available) %(threadName)s Thread name (if available) + %(taskName)s Task name (if available) %(process)d Process ID (if available) %(message)s The result of record.getMessage(), computed just as the record is emitted @@ -811,23 +833,36 @@ class Filterer(object): Determine if a record is loggable by consulting all the filters. The default is to allow the record to be logged; any filter can veto - this and the record is then dropped. Returns a zero value if a record - is to be dropped, else non-zero. + this by returning a false value. + If a filter attached to a handler returns a log record instance, + then that instance is used in place of the original log record in + any further processing of the event by that handler. + If a filter returns any other true value, the original log record + is used in any further processing of the event by that handler. + + If none of the filters return false values, this method returns + a log record. + If any of the filters return a false value, this method returns + a false value. .. versionchanged:: 3.2 Allow filters to be just callables. + + .. versionchanged:: 3.12 + Allow filters to return a LogRecord instead of + modifying it in place. """ - rv = True for f in self.filters: if hasattr(f, 'filter'): result = f.filter(record) else: result = f(record) # assume callable - will raise if not if not result: - rv = False - break - return rv + return False + if isinstance(result, LogRecord): + record = result + return record #--------------------------------------------------------------------------- # Handler classes and functions @@ -864,6 +899,23 @@ def _addHandlerRef(handler): finally: _releaseLock() + +def getHandlerByName(name): + """ + Get a handler with the specified *name*, or None if there isn't one with + that name. + """ + return _handlers.get(name) + + +def getHandlerNames(): + """ + Return all known handler names as an immutable set. + """ + result = set(_handlers.keys()) + return frozenset(result) + + class Handler(Filterer): """ Handler instances dispatch logging events to specific destinations. @@ -962,10 +1014,14 @@ class Handler(Filterer): Emission depends on filters which may have been added to the handler. Wrap the actual emission of the record with acquisition/release of - the I/O thread lock. Returns whether the filter passed the record for - emission. + the I/O thread lock. + + Returns an instance of the log record that was emitted + if it passed all filters, otherwise a false value is returned. """ rv = self.filter(record) + if isinstance(rv, LogRecord): + record = rv if rv: self.acquire() try: @@ -1140,6 +1196,8 @@ class StreamHandler(Handler): name += ' ' return '<%s %s(%s)>' % (self.__class__.__name__, name, level) + __class_getitem__ = classmethod(GenericAlias) + class FileHandler(StreamHandler): """ @@ -1475,7 +1533,7 @@ class Logger(Filterer): To pass exception information, use the keyword argument exc_info with a true value, e.g. - logger.info("Houston, we have a %s", "interesting problem", exc_info=1) + logger.info("Houston, we have a %s", "notable problem", exc_info=1) """ if self.isEnabledFor(INFO): self._log(INFO, msg, args, **kwargs) @@ -1558,33 +1616,31 @@ class Logger(Filterer): f = currentframe() #On some versions of IronPython, currentframe() returns None if #IronPython isn't run with -X:Frames. - if f is not None: - f = f.f_back - orig_f = f - while f and stacklevel > 1: - f = f.f_back - stacklevel -= 1 - if not f: - f = orig_f - rv = "(unknown file)", 0, "(unknown function)", None - while hasattr(f, "f_code"): - co = f.f_code - filename = os.path.normcase(co.co_filename) - if filename == _srcfile: - f = f.f_back - continue - sinfo = None - if stack_info: - sio = io.StringIO() - sio.write('Stack (most recent call last):\n') + if f is None: + return "(unknown file)", 0, "(unknown function)", None + while stacklevel > 0: + next_f = f.f_back + if next_f is None: + ## We've got options here. + ## If we want to use the last (deepest) frame: + break + ## If we want to mimic the warnings module: + #return ("sys", 1, "(unknown function)", None) + ## If we want to be pedantic: + #raise ValueError("call stack is not deep enough") + f = next_f + if not _is_internal_frame(f): + stacklevel -= 1 + co = f.f_code + sinfo = None + if stack_info: + with io.StringIO() as sio: + sio.write("Stack (most recent call last):\n") traceback.print_stack(f, file=sio) sinfo = sio.getvalue() if sinfo[-1] == '\n': sinfo = sinfo[:-1] - sio.close() - rv = (co.co_filename, f.f_lineno, co.co_name, sinfo) - break - return rv + return co.co_filename, f.f_lineno, co.co_name, sinfo def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None): @@ -1634,8 +1690,14 @@ class Logger(Filterer): This method is used for unpickled records received from a socket, as well as those created locally. Logger-level filtering is applied. """ - if (not self.disabled) and self.filter(record): - self.callHandlers(record) + if self.disabled: + return + maybe_record = self.filter(record) + if not maybe_record: + return + if isinstance(maybe_record, LogRecord): + record = maybe_record + self.callHandlers(record) def addHandler(self, hdlr): """ @@ -1766,13 +1828,30 @@ class Logger(Filterer): suffix = '.'.join((self.name, suffix)) return self.manager.getLogger(suffix) + def getChildren(self): + + def _hierlevel(logger): + if logger is logger.manager.root: + return 0 + return 1 + logger.name.count('.') + + d = self.manager.loggerDict + _acquireLock() + try: + # exclude PlaceHolders - the last check is to ensure that lower-level + # descendants aren't returned - if there are placeholders, a logger's + # parent field might point to a grandparent or ancestor thereof. + return set(item for item in d.values() + if isinstance(item, Logger) and item.parent is self and + _hierlevel(item) == 1 + _hierlevel(item.parent)) + finally: + _releaseLock() + def __repr__(self): level = getLevelName(self.getEffectiveLevel()) return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level) def __reduce__(self): - # In general, only the root logger will not be accessible via its name. - # However, the root logger's class has its own __reduce__ method. if getLogger(self.name) is not self: import pickle raise pickle.PicklingError('logger cannot be pickled') @@ -1936,6 +2015,8 @@ class LoggerAdapter(object): level = getLevelName(logger.getEffectiveLevel()) return '<%s %s (%s)>' % (self.__class__.__name__, logger.name, level) + __class_getitem__ = classmethod(GenericAlias) + root = RootLogger(WARNING) Logger.root = root Logger.manager = Manager(Logger.root) @@ -2183,7 +2264,11 @@ def shutdown(handlerList=_handlerList): if h: try: h.acquire() - h.flush() + # MemoryHandlers might not want to be flushed on close, + # but circular imports prevent us scoping this to just + # those handlers. hence the default to True. + if getattr(h, 'flushOnClose', True): + h.flush() h.close() except (OSError, ValueError): # Ignore errors which might be caused @@ -2246,7 +2331,9 @@ def _showwarning(message, category, filename, lineno, file=None, line=None): logger = getLogger("py.warnings") if not logger.handlers: logger.addHandler(NullHandler()) - logger.warning("%s", s) + # bpo-46557: Log str(s) as msg instead of logger.warning("%s", s) + # since some log aggregation tools group logs by the msg arg + logger.warning(str(s)) def captureWarnings(capture): """ diff --git a/Lib/logging/config.py b/Lib/logging/config.py index 3bc63b78621..7cd16c643e9 100644 --- a/Lib/logging/config.py +++ b/Lib/logging/config.py @@ -1,4 +1,4 @@ -# Copyright 2001-2019 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2022 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -19,18 +19,19 @@ Configuration functions for the logging package for Python. The core package is based on PEP 282 and comments thereto in comp.lang.python, and influenced by Apache's log4j system. -Copyright (C) 2001-2019 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2022 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ import errno +import functools import io import logging import logging.handlers +import queue import re import struct -import sys import threading import traceback @@ -392,11 +393,9 @@ class BaseConfigurator(object): self.importer(used) found = getattr(found, frag) return found - except ImportError: - e, tb = sys.exc_info()[1:] + except ImportError as e: v = ValueError('Cannot resolve %r: %s' % (s, e)) - v.__cause__, v.__traceback__ = e, tb - raise v + raise v from e def ext_convert(self, value): """Default converter for the ext:// protocol.""" @@ -566,7 +565,7 @@ class DictConfigurator(BaseConfigurator): handler.name = name handlers[name] = handler except Exception as e: - if 'target not configured yet' in str(e.__cause__): + if ' not configured yet' in str(e.__cause__): deferred.append(name) else: raise ValueError('Unable to configure handler ' @@ -697,10 +696,29 @@ class DictConfigurator(BaseConfigurator): """Add filters to a filterer from a list of names.""" for f in filters: try: - filterer.addFilter(self.config['filters'][f]) + if callable(f) or callable(getattr(f, 'filter', None)): + filter_ = f + else: + filter_ = self.config['filters'][f] + filterer.addFilter(filter_) except Exception as e: raise ValueError('Unable to add filter %r' % f) from e + def _configure_queue_handler(self, klass, **kwargs): + if 'queue' in kwargs: + q = kwargs['queue'] + else: + q = queue.Queue() # unbounded + rhl = kwargs.get('respect_handler_level', False) + if 'listener' in kwargs: + lklass = kwargs['listener'] + else: + lklass = logging.handlers.QueueListener + listener = lklass(q, *kwargs['handlers'], respect_handler_level=rhl) + handler = klass(q) + handler.listener = listener + return handler + def configure_handler(self, config): """Configure a handler from a dictionary.""" config_copy = dict(config) # for restoring in case of error @@ -720,26 +738,83 @@ class DictConfigurator(BaseConfigurator): factory = c else: cname = config.pop('class') - klass = self.resolve(cname) - #Special case for handler which refers to another handler + if callable(cname): + klass = cname + else: + klass = self.resolve(cname) if issubclass(klass, logging.handlers.MemoryHandler) and\ 'target' in config: + # Special case for handler which refers to another handler try: - th = self.config['handlers'][config['target']] + tn = config['target'] + th = self.config['handlers'][tn] if not isinstance(th, logging.Handler): config.update(config_copy) # restore for deferred cfg raise TypeError('target not configured yet') config['target'] = th except Exception as e: - raise ValueError('Unable to set target handler ' - '%r' % config['target']) from e + raise ValueError('Unable to set target handler %r' % tn) from e + elif issubclass(klass, logging.handlers.QueueHandler): + # Another special case for handler which refers to other handlers + if 'handlers' not in config: + raise ValueError('No handlers specified for a QueueHandler') + if 'queue' in config: + qspec = config['queue'] + if not isinstance(qspec, queue.Queue): + if isinstance(qspec, str): + q = self.resolve(qspec) + if not callable(q): + raise TypeError('Invalid queue specifier %r' % qspec) + q = q() + elif isinstance(qspec, dict): + if '()' not in qspec: + raise TypeError('Invalid queue specifier %r' % qspec) + q = self.configure_custom(dict(qspec)) + else: + raise TypeError('Invalid queue specifier %r' % qspec) + config['queue'] = q + if 'listener' in config: + lspec = config['listener'] + if isinstance(lspec, type): + if not issubclass(lspec, logging.handlers.QueueListener): + raise TypeError('Invalid listener specifier %r' % lspec) + else: + if isinstance(lspec, str): + listener = self.resolve(lspec) + if isinstance(listener, type) and\ + not issubclass(listener, logging.handlers.QueueListener): + raise TypeError('Invalid listener specifier %r' % lspec) + elif isinstance(lspec, dict): + if '()' not in lspec: + raise TypeError('Invalid listener specifier %r' % lspec) + listener = self.configure_custom(dict(lspec)) + else: + raise TypeError('Invalid listener specifier %r' % lspec) + if not callable(listener): + raise TypeError('Invalid listener specifier %r' % lspec) + config['listener'] = listener + hlist = [] + try: + for hn in config['handlers']: + h = self.config['handlers'][hn] + if not isinstance(h, logging.Handler): + config.update(config_copy) # restore for deferred cfg + raise TypeError('Required handler %r ' + 'is not configured yet' % hn) + hlist.append(h) + except Exception as e: + raise ValueError('Unable to set required handler %r' % hn) from e + config['handlers'] = hlist elif issubclass(klass, logging.handlers.SMTPHandler) and\ 'mailhost' in config: config['mailhost'] = self.as_tuple(config['mailhost']) elif issubclass(klass, logging.handlers.SysLogHandler) and\ 'address' in config: config['address'] = self.as_tuple(config['address']) - factory = klass + if issubclass(klass, logging.handlers.QueueHandler): + factory = functools.partial(self._configure_queue_handler, klass) + else: + factory = klass props = config.pop('.', None) kwargs = {k: config[k] for k in config if valid_ident(k)} try: @@ -794,6 +869,7 @@ class DictConfigurator(BaseConfigurator): """Configure a non-root logger from a dictionary.""" logger = logging.getLogger(name) self.common_logger_config(logger, config, incremental) + logger.disabled = False propagate = config.get('propagate', None) if propagate is not None: logger.propagate = propagate diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index d42c48de5f0..9847104446e 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -1,4 +1,4 @@ -# Copyright 2001-2016 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2021 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -18,7 +18,7 @@ Additional handlers for the logging package for Python. The core package is based on PEP 282 and comments thereto in comp.lang.python. -Copyright (C) 2001-2016 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2021 Vinay Sajip. All Rights Reserved. To use, simply 'import logging.handlers' and log away! """ @@ -348,11 +348,15 @@ class TimedRotatingFileHandler(BaseRotatingHandler): record is not used, as we are just comparing times, but it is needed so the method signatures are the same """ - # See bpo-45401: Never rollover anything other than regular files - if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename): - return False t = int(time.time()) if t >= self.rolloverAt: + # See #89564: Never rollover anything other than regular files + if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename): + # The file is not a regular file, so do not rollover, but do + # set the next rollover time to avoid repeated checks. + self.rolloverAt = self.computeRollover(t) + return False + return True return False @@ -366,9 +370,22 @@ class TimedRotatingFileHandler(BaseRotatingHandler): fileNames = os.listdir(dirName) result = [] # See bpo-44753: Don't use the extension when computing the prefix. - prefix = os.path.splitext(baseName)[0] + "." + n, e = os.path.splitext(baseName) + prefix = n + '.' plen = len(prefix) for fileName in fileNames: + if self.namer is None: + # Our files will always start with baseName + if not fileName.startswith(baseName): + continue + else: + # Our files could be just about anything after custom naming, but + # likely candidates are of the form + # foo.log.DATETIME_SUFFIX or foo.DATETIME_SUFFIX.log + if (not fileName.startswith(baseName) and fileName.endswith(e) and + len(fileName) > (plen + 1) and not fileName[plen+1].isdigit()): + continue + if fileName[:plen] == prefix: suffix = fileName[plen:] # See bpo-45628: The date/time suffix could be anywhere in the @@ -874,6 +891,13 @@ class SysLogHandler(logging.Handler): raise def createSocket(self): + """ + Try to create a socket and, if it's not a datagram socket, connect it + to the other end. This method is called during handler initialization, + but it's not regarded as an error if the other end isn't listening yet + --- the method will be called again when emitting an event, + if there is no socket at that point. + """ address = self.address socktype = self.socktype @@ -881,7 +905,7 @@ class SysLogHandler(logging.Handler): self.unixsocket = True # Syslog server may be unavailable during handler initialisation. # C's openlog() function also ignores connection errors. - # Moreover, we ignore these errors while logging, so it not worse + # Moreover, we ignore these errors while logging, so it's not worse # to ignore it also here. try: self._connect_unixsocket(address) @@ -1094,7 +1118,16 @@ class NTEventLogHandler(logging.Handler): dllname = os.path.join(dllname[0], r'win32service.pyd') self.dllname = dllname self.logtype = logtype - self._welu.AddSourceToRegistry(appname, dllname, logtype) + # Administrative privileges are required to add a source to the registry. + # This may not be available for a user that just wants to add to an + # existing source - handle this specific case. + try: + self._welu.AddSourceToRegistry(appname, dllname, logtype) + except Exception as e: + # This will probably be a pywintypes.error. Only raise if it's not + # an "access denied" error, else let it pass + if getattr(e, 'winerror', None) != 5: # not access denied + raise self.deftype = win32evtlog.EVENTLOG_ERROR_TYPE self.typemap = { logging.DEBUG : win32evtlog.EVENTLOG_INFORMATION_TYPE, @@ -1411,6 +1444,7 @@ class QueueHandler(logging.Handler): """ logging.Handler.__init__(self) self.queue = queue + self.listener = None # will be set to listener if configured via dictConfig() def enqueue(self, record): """ @@ -1442,7 +1476,7 @@ class QueueHandler(logging.Handler): # (if there's exception data), and also returns the formatted # message. We can then use this to replace the original # msg + args, as these might be unpickleable. We also zap the - # exc_info and exc_text attributes, as they are no longer + # exc_info, exc_text and stack_info attributes, as they are no longer # needed and, if not None, will typically not be pickleable. msg = self.format(record) # bpo-35726: make copy of record to avoid affecting other handlers in the chain. @@ -1452,6 +1486,7 @@ class QueueHandler(logging.Handler): record.args = None record.exc_info = None record.exc_text = None + record.stack_info = None return record def emit(self, record): diff --git a/Lib/mailbox.py b/Lib/mailbox.py index 70da07ed2e9..59834a2b3b5 100644 --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -1956,10 +1956,7 @@ class _ProxyFile: def __iter__(self): """Iterate over lines.""" - while True: - line = self.readline() - if not line: - return + while line := self.readline(): yield line def tell(self): diff --git a/Lib/mailcap.py b/Lib/mailcap.py index ae416a8e9fb..2f4656e854b 100644 --- a/Lib/mailcap.py +++ b/Lib/mailcap.py @@ -2,10 +2,17 @@ import os import warnings +import re __all__ = ["getcaps","findmatch"] +_DEPRECATION_MSG = ('The {name} module is deprecated and will be removed in ' + 'Python {remove}. See the mimetypes module for an ' + 'alternative.') +warnings._deprecated(__name__, _DEPRECATION_MSG, remove=(3, 13)) + + def lineno_sort_key(entry): # Sort in ascending order, with unspecified entries at the end if 'lineno' in entry: @@ -13,6 +20,11 @@ def lineno_sort_key(entry): else: return 1, 0 +_find_unsafe = re.compile(r'[^\xa1-\U0010FFFF\w@+=:,./-]').search + +class UnsafeMailcapInput(Warning): + """Warning raised when refusing unsafe input""" + # Part 1: top-level interface. @@ -78,9 +90,7 @@ def _readmailcapfile(fp, lineno): the viewing command is stored with the key "view". """ caps = {} - while 1: - line = fp.readline() - if not line: break + while line := fp.readline(): # Ignore comments and blank lines if line[0] == '#' or line.strip() == '': continue @@ -165,15 +175,22 @@ def findmatch(caps, MIMEtype, key='view', filename="/dev/null", plist=[]): entry to use. """ + if _find_unsafe(filename): + msg = "Refusing to use mailcap with filename %r. Use a safe temporary filename." % (filename,) + warnings.warn(msg, UnsafeMailcapInput) + return None, None entries = lookup(caps, MIMEtype, key) # XXX This code should somehow check for the needsterminal flag. for e in entries: if 'test' in e: test = subst(e['test'], filename, plist) + if test is None: + continue if test and os.system(test) != 0: continue command = subst(e[key], MIMEtype, filename, plist) - return command, e + if command is not None: + return command, e return None, None def lookup(caps, MIMEtype, key=None): @@ -206,6 +223,10 @@ def subst(field, MIMEtype, filename, plist=[]): elif c == 's': res = res + filename elif c == 't': + if _find_unsafe(MIMEtype): + msg = "Refusing to substitute MIME type %r into a shell command." % (MIMEtype,) + warnings.warn(msg, UnsafeMailcapInput) + return None res = res + MIMEtype elif c == '{': start = i @@ -213,7 +234,12 @@ def subst(field, MIMEtype, filename, plist=[]): i = i+1 name = field[start:i] i = i+1 - res = res + findparam(name, plist) + param = findparam(name, plist) + if _find_unsafe(param): + msg = "Refusing to substitute parameter %r (%s) into a shell command" % (param, name) + warnings.warn(msg, UnsafeMailcapInput) + return None + res = res + param # XXX To do: # %n == number of parts if type is multipart/* # %F == list of alternating type and filename for parts diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 4750408173e..37228de4828 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -141,25 +141,23 @@ class MimeTypes: type = 'text/plain' return type, None # never compressed, so encoding is None base, ext = posixpath.splitext(url) - while ext in self.suffix_map: - base, ext = posixpath.splitext(base + self.suffix_map[ext]) + while (ext_lower := ext.lower()) in self.suffix_map: + base, ext = posixpath.splitext(base + self.suffix_map[ext_lower]) + # encodings_map is case sensitive if ext in self.encodings_map: encoding = self.encodings_map[ext] base, ext = posixpath.splitext(base) else: encoding = None + ext = ext.lower() types_map = self.types_map[True] if ext in types_map: return types_map[ext], encoding - elif ext.lower() in types_map: - return types_map[ext.lower()], encoding elif strict: return None, encoding types_map = self.types_map[False] if ext in types_map: return types_map[ext], encoding - elif ext.lower() in types_map: - return types_map[ext.lower()], encoding else: return None, encoding @@ -219,10 +217,7 @@ class MimeTypes: list of standard types, else to the list of non-standard types. """ - while 1: - line = fp.readline() - if not line: - break + while line := fp.readline(): words = line.split() for i in range(len(words)): if words[i][0] == '#': @@ -429,8 +424,8 @@ def _default_mime_types(): # Make sure the entry with the preferred file extension for a particular mime type # appears before any others of the same mimetype. types_map = _types_map_default = { - '.js' : 'application/javascript', - '.mjs' : 'application/javascript', + '.js' : 'text/javascript', + '.mjs' : 'text/javascript', '.json' : 'application/json', '.webmanifest': 'application/manifest+json', '.doc' : 'application/msword', @@ -519,6 +514,7 @@ def _default_mime_types(): '.aiff' : 'audio/x-aiff', '.ra' : 'audio/x-pn-realaudio', '.wav' : 'audio/x-wav', + '.avif' : 'image/avif', '.bmp' : 'image/bmp', '.gif' : 'image/gif', '.ief' : 'image/ief', @@ -591,6 +587,7 @@ def _default_mime_types(): '.pict': 'image/pict', '.pct' : 'image/pict', '.pic' : 'image/pict', + '.webp': 'image/webp', '.xul' : 'text/xul', } diff --git a/Lib/msilib/__init__.py b/Lib/msilib/__init__.py index 0e85aa28967..565bf631abd 100644 --- a/Lib/msilib/__init__.py +++ b/Lib/msilib/__init__.py @@ -6,6 +6,9 @@ import os import re import string import sys +import warnings + +warnings._deprecated(__name__, remove=(3, 13)) AMD64 = "AMD64" in sys.version # Keep msilib.Win64 around to preserve backwards compatibility. diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py index 1cca66d5661..1a8822b9db0 100644 --- a/Lib/multiprocessing/connection.py +++ b/Lib/multiprocessing/connection.py @@ -73,11 +73,6 @@ def arbitrary_address(family): if family == 'AF_INET': return ('localhost', 0) elif family == 'AF_UNIX': - # Prefer abstract sockets if possible to avoid problems with the address - # size. When coding portable applications, some implementations have - # sun_path as short as 92 bytes in the sockaddr_un struct. - if util.abstract_sockets_supported: - return f"\0listener-{os.getpid()}-{next(_mmap_counter)}" return tempfile.mktemp(prefix='listener-', dir=util.get_temp_dir()) elif family == 'AF_PIPE': return tempfile.mktemp(prefix=r'\\.\pipe\pyc-%d-%d-' % @@ -188,10 +183,9 @@ class _ConnectionBase: self._check_closed() self._check_writable() m = memoryview(buf) - # HACK for byte-indexing of non-bytewise buffers (e.g. array.array) if m.itemsize > 1: - m = memoryview(bytes(m)) - n = len(m) + m = m.cast('B') + n = m.nbytes if offset < 0: raise ValueError("offset is negative") if n < offset: @@ -734,6 +728,74 @@ CHALLENGE = b'#CHALLENGE#' WELCOME = b'#WELCOME#' FAILURE = b'#FAILURE#' +# multiprocessing.connection Authentication Handshake Protocol Description +# (as documented for reference after reading the existing code) +# ============================================================================= +# +# On Windows: native pipes with "overlapped IO" are used to send the bytes, +# instead of the length prefix SIZE scheme described below. (ie: the OS deals +# with message sizes for us) +# +# Protocol error behaviors: +# +# On POSIX, any failure to receive the length prefix into SIZE, for SIZE greater +# than the requested maxsize to receive, or receiving fewer than SIZE bytes +# results in the connection being closed and auth to fail. +# +# On Windows, receiving too few bytes is never a low level _recv_bytes read +# error, receiving too many will trigger an error only if receive maxsize +# value was larger than 128 OR the if the data arrived in smaller pieces. +# +# Serving side Client side +# ------------------------------ --------------------------------------- +# 0. Open a connection on the pipe. +# 1. Accept connection. +# 2. New random 20 bytes -> MESSAGE +# 3. send 4 byte length (net order) +# prefix followed by: +# b'#CHALLENGE#' + MESSAGE +# 4. Receive 4 bytes, parse as network byte +# order integer. If it is -1, receive an +# additional 8 bytes, parse that as network +# byte order. The result is the length of +# the data that follows -> SIZE. +# 5. Receive min(SIZE, 256) bytes -> M1 +# 6. Assert that M1 starts with: +# b'#CHALLENGE#' +# 7. Strip that prefix from M1 into -> M2 +# 8. Compute HMAC-MD5 of AUTHKEY, M2 -> C_DIGEST +# 9. Send 4 byte length prefix (net order) +# followed by C_DIGEST bytes. +# 10. Compute HMAC-MD5 of AUTHKEY, +# MESSAGE into -> M_DIGEST. +# 11. Receive 4 or 4+8 byte length +# prefix (#4 dance) -> SIZE. +# 12. Receive min(SIZE, 256) -> C_D. +# 13. Compare M_DIGEST == C_D: +# 14a: Match? Send length prefix & +# b'#WELCOME#' +# <- RETURN +# 14b: Mismatch? Send len prefix & +# b'#FAILURE#' +# <- CLOSE & AuthenticationError +# 15. Receive 4 or 4+8 byte length prefix (net +# order) again as in #4 into -> SIZE. +# 16. Receive min(SIZE, 256) bytes -> M3. +# 17. Compare M3 == b'#WELCOME#': +# 17a. Match? <- RETURN +# 17b. Mismatch? <- CLOSE & AuthenticationError +# +# If this RETURNed, the connection remains open: it has been authenticated. +# +# Length prefixes are used consistently even though every step so far has +# always been a singular specific fixed length. This may help us evolve +# the protocol in the future without breaking backwards compatibility. +# +# Similarly the initial challenge message from the serving side has always +# been 20 bytes, but clients can accept a 100+ so using the length of the +# opening challenge message as an indicator of protocol version may work. + + def deliver_challenge(connection, authkey): import hmac if not isinstance(authkey, bytes): diff --git a/Lib/multiprocessing/context.py b/Lib/multiprocessing/context.py index 8d0525d5d62..b1960ea296f 100644 --- a/Lib/multiprocessing/context.py +++ b/Lib/multiprocessing/context.py @@ -223,6 +223,10 @@ class Process(process.BaseProcess): def _Popen(process_obj): return _default_context.get_context().Process._Popen(process_obj) + @staticmethod + def _after_fork(): + return _default_context.get_context().Process._after_fork() + class DefaultContext(BaseContext): Process = Process @@ -283,6 +287,11 @@ if sys.platform != 'win32': from .popen_spawn_posix import Popen return Popen(process_obj) + @staticmethod + def _after_fork(): + # process is spawned, nothing to do + pass + class ForkServerProcess(process.BaseProcess): _start_method = 'forkserver' @staticmethod @@ -326,6 +335,11 @@ else: from .popen_spawn_win32 import Popen return Popen(process_obj) + @staticmethod + def _after_fork(): + # process is spawned, nothing to do + pass + class SpawnContext(BaseContext): _name = 'spawn' Process = SpawnProcess diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index cf637c6cbbe..b6534939b4d 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -49,11 +49,11 @@ def reduce_array(a): reduction.register(array.array, reduce_array) view_types = [type(getattr({}, name)()) for name in ('items','keys','values')] -if view_types[0] is not list: # only needed in Py3.0 - def rebuild_as_list(obj): - return list, (list(obj),) - for view_type in view_types: - reduction.register(view_type, rebuild_as_list) +def rebuild_as_list(obj): + return list, (list(obj),) +for view_type in view_types: + reduction.register(view_type, rebuild_as_list) +del view_type, view_types # # Type for identifying shared objects @@ -433,7 +433,6 @@ class Server(object): self.id_to_refcount[ident] = 1 self.id_to_obj[ident] = \ self.id_to_local_proxy_obj[ident] - obj, exposed, gettypeid = self.id_to_obj[ident] util.debug('Server re-enabled tracking & INCREF %r', ident) else: raise ke @@ -497,7 +496,7 @@ class BaseManager(object): _Server = Server def __init__(self, address=None, authkey=None, serializer='pickle', - ctx=None): + ctx=None, *, shutdown_timeout=1.0): if authkey is None: authkey = process.current_process().authkey self._address = address # XXX not final address if eg ('', 0) @@ -507,6 +506,7 @@ class BaseManager(object): self._serializer = serializer self._Listener, self._Client = listener_client[serializer] self._ctx = ctx or get_context() + self._shutdown_timeout = shutdown_timeout def get_server(self): ''' @@ -570,8 +570,8 @@ class BaseManager(object): self._state.value = State.STARTED self.shutdown = util.Finalize( self, type(self)._finalize_manager, - args=(self._process, self._address, self._authkey, - self._state, self._Client), + args=(self._process, self._address, self._authkey, self._state, + self._Client, self._shutdown_timeout), exitpriority=0 ) @@ -656,7 +656,8 @@ class BaseManager(object): self.shutdown() @staticmethod - def _finalize_manager(process, address, authkey, state, _Client): + def _finalize_manager(process, address, authkey, state, _Client, + shutdown_timeout): ''' Shutdown the manager process; will be registered as a finalizer ''' @@ -671,15 +672,17 @@ class BaseManager(object): except Exception: pass - process.join(timeout=1.0) + process.join(timeout=shutdown_timeout) if process.is_alive(): util.info('manager still alive') if hasattr(process, 'terminate'): util.info('trying to `terminate()` manager process') process.terminate() - process.join(timeout=0.1) + process.join(timeout=shutdown_timeout) if process.is_alive(): util.info('manager still alive after terminate') + process.kill() + process.join() state.value = State.SHUTDOWN try: diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py index bbe05a550c3..4f5d88cb975 100644 --- a/Lib/multiprocessing/pool.py +++ b/Lib/multiprocessing/pool.py @@ -203,6 +203,9 @@ class Pool(object): processes = os.cpu_count() or 1 if processes < 1: raise ValueError("Number of processes must be at least 1") + if maxtasksperchild is not None: + if not isinstance(maxtasksperchild, int) or maxtasksperchild <= 0: + raise ValueError("maxtasksperchild must be a positive int or None") if initializer is not None and not callable(initializer): raise TypeError('initializer must be a callable') @@ -693,7 +696,7 @@ class Pool(object): if (not result_handler.is_alive()) and (len(cache) != 0): raise AssertionError( - "Cannot have cache with result_hander not alive") + "Cannot have cache with result_handler not alive") result_handler._state = TERMINATE change_notifier.put(None) diff --git a/Lib/multiprocessing/popen_spawn_win32.py b/Lib/multiprocessing/popen_spawn_win32.py index 9c4098d0fa4..4d60ffc030b 100644 --- a/Lib/multiprocessing/popen_spawn_win32.py +++ b/Lib/multiprocessing/popen_spawn_win32.py @@ -54,19 +54,20 @@ class Popen(object): wfd = msvcrt.open_osfhandle(whandle, 0) cmd = spawn.get_command_line(parent_pid=os.getpid(), pipe_handle=rhandle) - cmd = ' '.join('"%s"' % x for x in cmd) python_exe = spawn.get_executable() # bpo-35797: When running in a venv, we bypass the redirect # executor and launch our base Python. if WINENV and _path_eq(python_exe, sys.executable): - python_exe = sys._base_executable + cmd[0] = python_exe = sys._base_executable env = os.environ.copy() env["__PYVENV_LAUNCHER__"] = sys.executable else: env = None + cmd = ' '.join('"%s"' % x for x in cmd) + with open(wfd, 'wb', closefd=True) as to_child: # start process try: diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py index 0b2e0b45b23..c03c859baa7 100644 --- a/Lib/multiprocessing/process.py +++ b/Lib/multiprocessing/process.py @@ -304,8 +304,7 @@ class BaseProcess(object): if threading._HAVE_THREAD_NATIVE_ID: threading.main_thread()._set_native_id() try: - util._finalizer_registry.clear() - util._run_after_forkers() + self._after_fork() finally: # delay finalization of the old process object until after # _run_after_forkers() is executed @@ -336,6 +335,13 @@ class BaseProcess(object): return exitcode + @staticmethod + def _after_fork(): + from . import util + util._finalizer_registry.clear() + util._run_after_forkers() + + # # We subclass bytes to avoid accidental transmission of auth keys over network # @@ -427,6 +433,7 @@ _exitcode_to_name = {} for name, signum in list(signal.__dict__.items()): if name[:3]=='SIG' and '_' not in name: _exitcode_to_name[-signum] = f'-{name}' +del name, signum # For debug and leak testing _dangling = WeakSet() diff --git a/Lib/multiprocessing/queues.py b/Lib/multiprocessing/queues.py index a2901814876..daf9ee94a19 100644 --- a/Lib/multiprocessing/queues.py +++ b/Lib/multiprocessing/queues.py @@ -139,13 +139,10 @@ class Queue(object): def close(self): self._closed = True - try: - self._reader.close() - finally: - close = self._close - if close: - self._close = None - close() + close = self._close + if close: + self._close = None + close() def join_thread(self): debug('Queue.join_thread()') @@ -169,8 +166,9 @@ class Queue(object): self._thread = threading.Thread( target=Queue._feed, args=(self._buffer, self._notempty, self._send_bytes, - self._wlock, self._writer.close, self._ignore_epipe, - self._on_queue_feeder_error, self._sem), + self._wlock, self._reader.close, self._writer.close, + self._ignore_epipe, self._on_queue_feeder_error, + self._sem), name='QueueFeederThread' ) self._thread.daemon = True @@ -211,8 +209,8 @@ class Queue(object): notempty.notify() @staticmethod - def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe, - onerror, queue_sem): + def _feed(buffer, notempty, send_bytes, writelock, reader_close, + writer_close, ignore_epipe, onerror, queue_sem): debug('starting thread to feed data to pipe') nacquire = notempty.acquire nrelease = notempty.release @@ -238,7 +236,8 @@ class Queue(object): obj = bpopleft() if obj is sentinel: debug('feeder thread got sentinel -- exiting') - close() + reader_close() + writer_close() return # serialize the data before acquiring the lock @@ -281,6 +280,8 @@ class Queue(object): import traceback traceback.print_exc() + __class_getitem__ = classmethod(types.GenericAlias) + _sentinel = object() diff --git a/Lib/multiprocessing/resource_tracker.py b/Lib/multiprocessing/resource_tracker.py index cc42dbdda05..ea369507297 100644 --- a/Lib/multiprocessing/resource_tracker.py +++ b/Lib/multiprocessing/resource_tracker.py @@ -161,10 +161,10 @@ class ResourceTracker(object): def _send(self, cmd, name, rtype): self.ensure_running() msg = '{0}:{1}:{2}\n'.format(cmd, name, rtype).encode('ascii') - if len(name) > 512: + if len(msg) > 512: # posix guarantees that writes to a pipe of less than PIPE_BUF # bytes are atomic, and that PIPE_BUF >= 512 - raise ValueError('name too long') + raise ValueError('msg too long') nbytes = os.write(self._fd, msg) assert nbytes == len(msg), "nbytes {0:n} but len(msg) {1:n}".format( nbytes, len(msg)) diff --git a/Lib/multiprocessing/shared_memory.py b/Lib/multiprocessing/shared_memory.py index 122b3fcebf3..9a1e5aa17b8 100644 --- a/Lib/multiprocessing/shared_memory.py +++ b/Lib/multiprocessing/shared_memory.py @@ -23,6 +23,7 @@ else: import _posixshmem _USE_POSIX = True +from . import resource_tracker _O_CREX = os.O_CREAT | os.O_EXCL @@ -116,8 +117,7 @@ class SharedMemory: self.unlink() raise - from .resource_tracker import register - register(self._name, "shared_memory") + resource_tracker.register(self._name, "shared_memory") else: @@ -173,7 +173,10 @@ class SharedMemory: ) finally: _winapi.CloseHandle(h_map) - size = _winapi.VirtualQuerySize(p_buf) + try: + size = _winapi.VirtualQuerySize(p_buf) + finally: + _winapi.UnmapViewOfFile(p_buf) self._mmap = mmap.mmap(-1, size, tagname=name) self._size = size @@ -237,9 +240,8 @@ class SharedMemory: called once (and only once) across all processes which have access to the shared memory block.""" if _USE_POSIX and self._name: - from .resource_tracker import unregister _posixshmem.shm_unlink(self._name) - unregister(self._name, "shared_memory") + resource_tracker.unregister(self._name, "shared_memory") _encoding = "utf8" diff --git a/Lib/multiprocessing/spawn.py b/Lib/multiprocessing/spawn.py index 7cc129e2610..09f8a229d7c 100644 --- a/Lib/multiprocessing/spawn.py +++ b/Lib/multiprocessing/spawn.py @@ -33,18 +33,21 @@ else: WINEXE = getattr(sys, 'frozen', False) WINSERVICE = sys.executable.lower().endswith("pythonservice.exe") -if WINSERVICE: - _python_exe = os.path.join(sys.exec_prefix, 'python.exe') -else: - _python_exe = sys.executable - def set_executable(exe): global _python_exe - _python_exe = exe + if sys.platform == 'win32': + _python_exe = os.fsdecode(exe) + else: + _python_exe = os.fsencode(exe) def get_executable(): return _python_exe +if WINSERVICE: + set_executable(os.path.join(sys.exec_prefix, 'python.exe')) +else: + set_executable(sys.executable) + # # # @@ -86,7 +89,8 @@ def get_command_line(**kwds): prog = 'from multiprocessing.spawn import spawn_main; spawn_main(%s)' prog %= ', '.join('%s=%r' % item for item in kwds.items()) opts = util._args_from_interpreter_flags() - return [_python_exe] + opts + ['-c', prog, '--multiprocessing-fork'] + exe = get_executable() + return [exe] + opts + ['-c', prog, '--multiprocessing-fork'] def spawn_main(pipe_handle, parent_pid=None, tracker_fd=None): diff --git a/Lib/multiprocessing/synchronize.py b/Lib/multiprocessing/synchronize.py index d0be48f1fd7..42624b54360 100644 --- a/Lib/multiprocessing/synchronize.py +++ b/Lib/multiprocessing/synchronize.py @@ -353,6 +353,9 @@ class Event(object): return True return False + def __repr__(self) -> str: + set_status = 'set' if self.is_set() else 'unset' + return f"<{type(self).__qualname__} at {id(self):#x} {set_status}>" # # Barrier # diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py index a4683339820..6ee0d33e88a 100644 --- a/Lib/multiprocessing/util.py +++ b/Lib/multiprocessing/util.py @@ -120,7 +120,7 @@ def is_abstract_socket_namespace(address): return address[0] == 0 elif isinstance(address, str): return address[0] == "\0" - raise TypeError('address type of {address!r} unrecognized') + raise TypeError(f'address type of {address!r} unrecognized') abstract_sockets_supported = _platform_supports_abstract_sockets() @@ -446,13 +446,15 @@ def _flush_std_streams(): def spawnv_passfds(path, args, passfds): import _posixsubprocess + import subprocess passfds = tuple(sorted(map(int, passfds))) errpipe_read, errpipe_write = os.pipe() try: return _posixsubprocess.fork_exec( - args, [os.fsencode(path)], True, passfds, None, None, + args, [path], True, passfds, None, None, -1, -1, -1, -1, -1, -1, errpipe_read, errpipe_write, - False, False, None, None, None, -1, None) + False, False, -1, None, None, None, -1, None, + subprocess._USE_VFORK) finally: os.close(errpipe_read) os.close(errpipe_write) diff --git a/Lib/netrc.py b/Lib/netrc.py index c1358aac6ae..b285fd8e357 100644 --- a/Lib/netrc.py +++ b/Lib/netrc.py @@ -2,7 +2,7 @@ # Module and documentation by Eric S. Raymond, 21 Dec 1998 -import os, shlex, stat +import os, stat __all__ = ["netrc", "NetrcParseError"] diff --git a/Lib/nntplib.py b/Lib/nntplib.py index f6e746e7c95..dddea059982 100644 --- a/Lib/nntplib.py +++ b/Lib/nntplib.py @@ -68,6 +68,7 @@ import socket import collections import datetime import sys +import warnings try: import ssl @@ -85,6 +86,8 @@ __all__ = ["NNTP", "decode_header", ] +warnings._deprecated(__name__, remove=(3, 13)) + # maximal line length when calling readline(). This is to prevent # reading arbitrary length lines. RFC 3977 limits NNTP line length to # 512 characters, including CRLF. We have selected 2048 just to be on diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 527c7ae1938..f9ee8e02a57 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -23,13 +23,14 @@ import stat import genericpath from genericpath import * -__all__ = ["normcase","isabs","join","splitdrive","split","splitext", + +__all__ = ["normcase","isabs","join","splitdrive","splitroot","split","splitext", "basename","dirname","commonprefix","getsize","getmtime", "getatime","getctime", "islink","exists","lexists","isdir","isfile", "ismount", "expanduser","expandvars","normpath","abspath", "curdir","pardir","sep","pathsep","defpath","altsep", "extsep","devnull","realpath","supports_unicode_filenames","relpath", - "samefile", "sameopenfile", "samestat", "commonpath"] + "samefile", "sameopenfile", "samestat", "commonpath", "isjunction"] def _get_bothseps(path): if isinstance(path, bytes): @@ -41,14 +42,39 @@ def _get_bothseps(path): # Other normalizations (such as optimizing '../' away) are not done # (this is done by normpath). -def normcase(s): - """Normalize case of pathname. +try: + from _winapi import ( + LCMapStringEx as _LCMapStringEx, + LOCALE_NAME_INVARIANT as _LOCALE_NAME_INVARIANT, + LCMAP_LOWERCASE as _LCMAP_LOWERCASE) - Makes all characters lowercase and all slashes into backslashes.""" - s = os.fspath(s) - if isinstance(s, bytes): - return s.replace(b'/', b'\\').lower() - else: + def normcase(s): + """Normalize case of pathname. + + Makes all characters lowercase and all slashes into backslashes. + """ + s = os.fspath(s) + if not s: + return s + if isinstance(s, bytes): + encoding = sys.getfilesystemencoding() + s = s.decode(encoding, 'surrogateescape').replace('/', '\\') + s = _LCMapStringEx(_LOCALE_NAME_INVARIANT, + _LCMAP_LOWERCASE, s) + return s.encode(encoding, 'surrogateescape') + else: + return _LCMapStringEx(_LOCALE_NAME_INVARIANT, + _LCMAP_LOWERCASE, + s.replace('/', '\\')) +except ImportError: + def normcase(s): + """Normalize case of pathname. + + Makes all characters lowercase and all slashes into backslashes. + """ + s = os.fspath(s) + if isinstance(s, bytes): + return os.fsencode(os.fsdecode(s).replace('/', '\\').lower()) return s.replace('/', '\\').lower() @@ -61,16 +87,20 @@ def normcase(s): def isabs(s): """Test whether a path is absolute""" s = os.fspath(s) - # Paths beginning with \\?\ are always absolute, but do not - # necessarily contain a drive. if isinstance(s, bytes): - if s.replace(b'/', b'\\').startswith(b'\\\\?\\'): - return True + sep = b'\\' + altsep = b'/' + colon_sep = b':\\' else: - if s.replace('/', '\\').startswith('\\\\?\\'): - return True - s = splitdrive(s)[1] - return len(s) > 0 and s[0] in _get_bothseps(s) + sep = '\\' + altsep = '/' + colon_sep = ':\\' + s = s[:3].replace(altsep, sep) + # Absolute: UNC, device, and paths with a drive and root. + # LEGACY BUG: isabs("/x") should be false since the path has no drive. + if s.startswith(sep) or s.startswith(colon_sep, 1): + return True + return False # Join two (or more) paths. @@ -87,19 +117,21 @@ def join(path, *paths): try: if not paths: path[:0] + sep #23780: Ensure compatible data type even if p is null. - result_drive, result_path = splitdrive(path) + result_drive, result_root, result_path = splitroot(path) for p in map(os.fspath, paths): - p_drive, p_path = splitdrive(p) - if p_path and p_path[0] in seps: + p_drive, p_root, p_path = splitroot(p) + if p_root: # Second path is absolute if p_drive or not result_drive: result_drive = p_drive + result_root = p_root result_path = p_path continue elif p_drive and p_drive != result_drive: if p_drive.lower() != result_drive.lower(): # Different drives => ignore the first path entirely result_drive = p_drive + result_root = p_root result_path = p_path continue # Same drive in different case @@ -109,10 +141,10 @@ def join(path, *paths): result_path = result_path + sep result_path = result_path + p_path ## add separator between UNC and non-absolute path - if (result_path and result_path[0] not in seps and + if (result_path and not result_root and result_drive and result_drive[-1:] != colon): return result_drive + sep + result_path - return result_drive + result_path + return result_drive + result_root + result_path except (TypeError, AttributeError, BytesWarning): genericpath._check_arg_types('join', path, *paths) raise @@ -139,37 +171,61 @@ def splitdrive(p): Paths cannot contain both a drive letter and a UNC path. + """ + drive, root, tail = splitroot(p) + return drive, root + tail + + +def splitroot(p): + """Split a pathname into drive, root and tail. The drive is defined + exactly as in splitdrive(). On Windows, the root may be a single path + separator or an empty string. The tail contains anything after the root. + For example: + + splitroot('//server/share/') == ('//server/share', '/', '') + splitroot('C:/Users/Barney') == ('C:', '/', 'Users/Barney') + splitroot('C:///spam///ham') == ('C:', '/', '//spam///ham') + splitroot('Windows/notepad') == ('', '', 'Windows/notepad') """ p = os.fspath(p) - if len(p) >= 2: - if isinstance(p, bytes): - sep = b'\\' - altsep = b'/' - colon = b':' - else: - sep = '\\' - altsep = '/' - colon = ':' - normp = p.replace(altsep, sep) - if (normp[0:2] == sep*2) and (normp[2:3] != sep): - # is a UNC path: - # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path - # \\machine\mountpoint\directory\etc\... - # directory ^^^^^^^^^^^^^^^ - index = normp.find(sep, 2) + if isinstance(p, bytes): + sep = b'\\' + altsep = b'/' + colon = b':' + unc_prefix = b'\\\\?\\UNC\\' + empty = b'' + else: + sep = '\\' + altsep = '/' + colon = ':' + unc_prefix = '\\\\?\\UNC\\' + empty = '' + normp = p.replace(altsep, sep) + if normp[:1] == sep: + if normp[1:2] == sep: + # UNC drives, e.g. \\server\share or \\?\UNC\server\share + # Device drives, e.g. \\.\device or \\?\device + start = 8 if normp[:8].upper() == unc_prefix else 2 + index = normp.find(sep, start) if index == -1: - return p[:0], p + return p, empty, empty index2 = normp.find(sep, index + 1) - # a UNC path can't have two slashes in a row - # (after the initial two) - if index2 == index + 1: - return p[:0], p if index2 == -1: - index2 = len(p) - return p[:index2], p[index2:] - if normp[1:2] == colon: - return p[:2], p[2:] - return p[:0], p + return p, empty, empty + return p[:index2], p[index2:index2 + 1], p[index2 + 1:] + else: + # Relative path with root, e.g. \Windows + return empty, p[:1], p[1:] + elif normp[1:2] == colon: + if normp[2:3] == sep: + # Absolute drive-letter path, e.g. X:\Windows + return p[:2], p[2:3], p[3:] + else: + # Relative path with drive, e.g. X:Windows + return p[:2], empty, p[2:] + else: + # Relative path, e.g. Windows + return empty, empty, p # Split a path in head (everything up to the last '/') and tail (the @@ -184,15 +240,13 @@ def split(p): Either part may be empty.""" p = os.fspath(p) seps = _get_bothseps(p) - d, p = splitdrive(p) + d, r, p = splitroot(p) # set i to index beyond p's last slash i = len(p) while i and p[i-1] not in seps: i -= 1 head, tail = p[:i], p[i:] # now tail has no slashes - # remove trailing slashes from head, unless it's all slashes - head = head.rstrip(seps) or head - return d + head, tail + return d + r + head.rstrip(seps), tail # Split a path in root and extension. @@ -235,6 +289,24 @@ def islink(path): return False return stat.S_ISLNK(st.st_mode) + +# Is a path a junction? + +if hasattr(os.stat_result, 'st_reparse_tag'): + def isjunction(path): + """Test whether a path is a junction""" + try: + st = os.lstat(path) + except (OSError, ValueError, AttributeError): + return False + return bool(st.st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT) +else: + def isjunction(path): + """Test whether a path is a junction""" + os.fspath(path) + return False + + # Being true for dangling symbolic links is also useful. def lexists(path): @@ -265,14 +337,16 @@ def ismount(path): path = os.fspath(path) seps = _get_bothseps(path) path = abspath(path) - root, rest = splitdrive(path) - if root and root[0] in seps: - return (not rest) or (rest in seps) - if rest in seps: + drive, root, rest = splitroot(path) + if drive and drive[0] in seps: + return not rest + if root and not rest: return True if _getvolumepathname: - return path.rstrip(seps) == _getvolumepathname(path).rstrip(seps) + x = path.rstrip(seps) + y =_getvolumepathname(path).rstrip(seps) + return x.casefold() == y.casefold() else: return False @@ -459,56 +533,54 @@ def expandvars(path): # Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B. # Previously, this function also truncated pathnames to 8+3 format, # but as this module is called "ntpath", that's obviously wrong! +try: + from nt import _path_normpath -def normpath(path): - """Normalize path, eliminating double slashes, etc.""" - path = os.fspath(path) - if isinstance(path, bytes): - sep = b'\\' - altsep = b'/' - curdir = b'.' - pardir = b'..' - special_prefixes = (b'\\\\.\\', b'\\\\?\\') - else: - sep = '\\' - altsep = '/' - curdir = '.' - pardir = '..' - special_prefixes = ('\\\\.\\', '\\\\?\\') - if path.startswith(special_prefixes): - # in the case of paths with these prefixes: - # \\.\ -> device names - # \\?\ -> literal paths - # do not do any normalization, but return the path - # unchanged apart from the call to os.fspath() - return path - path = path.replace(altsep, sep) - prefix, path = splitdrive(path) - - # collapse initial backslashes - if path.startswith(sep): - prefix += sep - path = path.lstrip(sep) - - comps = path.split(sep) - i = 0 - while i < len(comps): - if not comps[i] or comps[i] == curdir: - del comps[i] - elif comps[i] == pardir: - if i > 0 and comps[i-1] != pardir: - del comps[i-1:i+1] - i -= 1 - elif i == 0 and prefix.endswith(sep): +except ImportError: + def normpath(path): + """Normalize path, eliminating double slashes, etc.""" + path = os.fspath(path) + if isinstance(path, bytes): + sep = b'\\' + altsep = b'/' + curdir = b'.' + pardir = b'..' + else: + sep = '\\' + altsep = '/' + curdir = '.' + pardir = '..' + path = path.replace(altsep, sep) + drive, root, path = splitroot(path) + prefix = drive + root + comps = path.split(sep) + i = 0 + while i < len(comps): + if not comps[i] or comps[i] == curdir: del comps[i] + elif comps[i] == pardir: + if i > 0 and comps[i-1] != pardir: + del comps[i-1:i+1] + i -= 1 + elif i == 0 and root: + del comps[i] + else: + i += 1 else: i += 1 - else: - i += 1 - # If the path is now empty, substitute '.' - if not prefix and not comps: - comps.append(curdir) - return prefix + sep.join(comps) + # If the path is now empty, substitute '.' + if not prefix and not comps: + comps.append(curdir) + return prefix + sep.join(comps) + +else: + def normpath(path): + """Normalize path, eliminating double slashes, etc.""" + path = os.fspath(path) + if isinstance(path, bytes): + return os.fsencode(_path_normpath(os.fsdecode(path))) or b"." + return _path_normpath(path) or "." + def _abspath_fallback(path): """Return the absolute version of a path as a fallback function in case @@ -537,7 +609,7 @@ else: # use native Windows method on Windows def abspath(path): """Return the absolute version of a path.""" try: - return normpath(_getfullpathname(path)) + return _getfullpathname(normpath(path)) except (OSError, ValueError): return _abspath_fallback(path) @@ -599,12 +671,15 @@ else: # 21: ERROR_NOT_READY (implies drive with no media) # 32: ERROR_SHARING_VIOLATION (probably an NTFS paging file) # 50: ERROR_NOT_SUPPORTED + # 53: ERROR_BAD_NETPATH + # 65: ERROR_NETWORK_ACCESS_DENIED # 67: ERROR_BAD_NET_NAME (implies remote server unavailable) # 87: ERROR_INVALID_PARAMETER # 123: ERROR_INVALID_NAME + # 161: ERROR_BAD_PATHNAME # 1920: ERROR_CANT_ACCESS_FILE # 1921: ERROR_CANT_RESOLVE_FILENAME (implies unfollowable symlink) - allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 67, 87, 123, 1920, 1921 + allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 53, 65, 67, 87, 123, 161, 1920, 1921 # Non-strict algorithm is to find as much of the target directory # as we can and join the rest. @@ -686,9 +761,8 @@ else: return path -# Win9x family and earlier have no Unicode filename support. -supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and - sys.getwindowsversion()[3] >= 2) +# All supported version have Unicode filename support. +supports_unicode_filenames = True def relpath(path, start=None): """Return a relative version of a path""" @@ -712,8 +786,8 @@ def relpath(path, start=None): try: start_abs = abspath(normpath(start)) path_abs = abspath(normpath(path)) - start_drive, start_rest = splitdrive(start_abs) - path_drive, path_rest = splitdrive(path_abs) + start_drive, _, start_rest = splitroot(start_abs) + path_drive, _, path_rest = splitroot(path_abs) if normcase(start_drive) != normcase(path_drive): raise ValueError("path is on mount %r, start on mount %r" % ( path_drive, start_drive)) @@ -763,21 +837,19 @@ def commonpath(paths): curdir = '.' try: - drivesplits = [splitdrive(p.replace(altsep, sep).lower()) for p in paths] - split_paths = [p.split(sep) for d, p in drivesplits] + drivesplits = [splitroot(p.replace(altsep, sep).lower()) for p in paths] + split_paths = [p.split(sep) for d, r, p in drivesplits] - try: - isabs, = set(p[:1] == sep for d, p in drivesplits) - except ValueError: - raise ValueError("Can't mix absolute and relative paths") from None + if len({r for d, r, p in drivesplits}) != 1: + raise ValueError("Can't mix absolute and relative paths") # Check that all drive letters or UNC paths match. The check is made only # now otherwise type errors for mixing strings and bytes would not be # caught. - if len(set(d for d, p in drivesplits)) != 1: + if len({d for d, r, p in drivesplits}) != 1: raise ValueError("Paths don't have the same drive") - drive, path = splitdrive(paths[0].replace(altsep, sep)) + drive, root, path = splitroot(paths[0].replace(altsep, sep)) common = path.split(sep) common = [c for c in common if c and c != curdir] @@ -791,8 +863,7 @@ def commonpath(paths): else: common = common[:len(s1)] - prefix = drive + sep if isabs else drive - return prefix + sep.join(common) + return drive + root + sep.join(common) except (TypeError, AttributeError): genericpath._check_arg_types('commonpath', *paths) raise diff --git a/Lib/numbers.py b/Lib/numbers.py index 5b98e642083..a2913e32cfa 100644 --- a/Lib/numbers.py +++ b/Lib/numbers.py @@ -5,6 +5,31 @@ TODO: Fill out more detailed documentation on the operators.""" +############ Maintenance notes ######################################### +# +# ABCs are different from other standard library modules in that they +# specify compliance tests. In general, once an ABC has been published, +# new methods (either abstract or concrete) cannot be added. +# +# Though classes that inherit from an ABC would automatically receive a +# new mixin method, registered classes would become non-compliant and +# violate the contract promised by ``isinstance(someobj, SomeABC)``. +# +# Though irritating, the correct procedure for adding new abstract or +# mixin methods is to create a new ABC as a subclass of the previous +# ABC. +# +# Because they are so hard to change, new ABCs should have their APIs +# carefully thought through prior to publication. +# +# Since ABCMeta only checks for the presence of methods, it is possible +# to alter the signature of a method by adding optional arguments +# or changing parameter names. This is still a bit dubious but at +# least it won't cause isinstance() to return an incorrect result. +# +# +####################################################################### + from abc import ABCMeta, abstractmethod __all__ = ["Number", "Complex", "Real", "Rational", "Integral"] @@ -118,7 +143,7 @@ class Complex(Number): @abstractmethod def __pow__(self, exponent): - """self**exponent; should promote to float or complex when necessary.""" + """self ** exponent; should promote to float or complex when necessary.""" raise NotImplementedError @abstractmethod @@ -167,7 +192,7 @@ class Real(Complex): """trunc(self): Truncates self to an Integral. Returns an Integral i such that: - * i>0 iff self>0; + * i > 0 iff self > 0; * abs(i) <= abs(self); * for any Integral j satisfying the first two conditions, abs(i) >= abs(j) [i.e. i has "maximal" abs among those]. @@ -203,7 +228,7 @@ class Real(Complex): return (self // other, self % other) def __rdivmod__(self, other): - """divmod(other, self): The pair (self // other, self % other). + """divmod(other, self): The pair (other // self, other % self). Sometimes this can be computed faster than the pair of operations. @@ -288,7 +313,7 @@ class Rational(Real): so that ratios of huge integers convert without overflowing. """ - return self.numerator / self.denominator + return int(self.numerator) / int(self.denominator) class Integral(Rational): diff --git a/Lib/opcode.py b/Lib/opcode.py index 3603bb422b1..c317e23beae 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -4,9 +4,9 @@ opcode module - potentially shared between dis and other modules which operate on bytecodes (e.g. peephole optimizers). """ -__all__ = ["cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs", - "haslocal", "hascompare", "hasfree", "opname", "opmap", - "HAVE_ARGUMENT", "EXTENDED_ARG", "hasnargs"] +__all__ = ["cmp_op", "hasarg", "hasconst", "hasname", "hasjrel", "hasjabs", + "haslocal", "hascompare", "hasfree", "hasexc", "opname", "opmap", + "HAVE_ARGUMENT", "EXTENDED_ARG"] # It's a chicken-and-egg I'm afraid: # We're imported before _opcode's made. @@ -23,6 +23,7 @@ except ImportError: cmp_op = ('<', '<=', '==', '!=', '>', '>=') +hasarg = [] hasconst = [] hasname = [] hasjrel = [] @@ -30,13 +31,24 @@ hasjabs = [] haslocal = [] hascompare = [] hasfree = [] -hasnargs = [] # unused +hasexc = [] + + +ENABLE_SPECIALIZATION = True + +def is_pseudo(op): + return op >= MIN_PSEUDO_OPCODE and op <= MAX_PSEUDO_OPCODE + +oplists = [hasarg, hasconst, hasname, hasjrel, hasjabs, + haslocal, hascompare, hasfree, hasexc] opmap = {} -opname = ['<%r>' % (op,) for op in range(256)] + +## pseudo opcodes (used in the compiler) mapped to the values +## they can become in the actual code. +_pseudo_ops = {} def def_op(name, op): - opname[op] = name opmap[name] = op def name_op(name, op): @@ -51,24 +63,37 @@ def jabs_op(name, op): def_op(name, op) hasjabs.append(op) +def pseudo_op(name, op, real_ops): + def_op(name, op) + _pseudo_ops[name] = real_ops + # add the pseudo opcode to the lists its targets are in + for oplist in oplists: + res = [opmap[rop] in oplist for rop in real_ops] + if any(res): + assert all(res) + oplist.append(op) + + # Instruction opcodes for compiled code # Blank lines correspond to available opcodes +def_op('CACHE', 0) def_op('POP_TOP', 1) -def_op('ROT_TWO', 2) -def_op('ROT_THREE', 3) -def_op('DUP_TOP', 4) -def_op('DUP_TOP_TWO', 5) -def_op('ROT_FOUR', 6) +def_op('PUSH_NULL', 2) +def_op('INTERPRETER_EXIT', 3) + +def_op('END_FOR', 4) def_op('NOP', 9) -def_op('UNARY_POSITIVE', 10) + def_op('UNARY_NEGATIVE', 11) def_op('UNARY_NOT', 12) def_op('UNARY_INVERT', 15) def_op('BINARY_SUBSCR', 25) +def_op('BINARY_SLICE', 26) +def_op('STORE_SLICE', 27) def_op('GET_LEN', 30) def_op('MATCH_MAPPING', 31) @@ -76,8 +101,8 @@ def_op('MATCH_SEQUENCE', 32) def_op('MATCH_KEYS', 33) def_op('PUSH_EXC_INFO', 35) - -def_op('POP_EXCEPT_AND_RERAISE', 37) +def_op('CHECK_EXC_MATCH', 36) +def_op('CHECK_EG_MATCH', 37) def_op('WITH_EXCEPT_START', 49) def_op('GET_AITER', 50) @@ -85,27 +110,27 @@ def_op('GET_ANEXT', 51) def_op('BEFORE_ASYNC_WITH', 52) def_op('BEFORE_WITH', 53) def_op('END_ASYNC_FOR', 54) +def_op('CLEANUP_THROW', 55) def_op('STORE_SUBSCR', 60) def_op('DELETE_SUBSCR', 61) def_op('GET_ITER', 68) def_op('GET_YIELD_FROM_ITER', 69) -def_op('PRINT_EXPR', 70) + def_op('LOAD_BUILD_CLASS', 71) -def_op('YIELD_FROM', 72) -def_op('GET_AWAITABLE', 73) + def_op('LOAD_ASSERTION_ERROR', 74) +def_op('RETURN_GENERATOR', 75) -def_op('LIST_TO_TUPLE', 82) def_op('RETURN_VALUE', 83) -def_op('IMPORT_STAR', 84) -def_op('SETUP_ANNOTATIONS', 85) -def_op('YIELD_VALUE', 86) +def_op('SETUP_ANNOTATIONS', 85) + +def_op('PREP_RERAISE_STAR', 88) def_op('POP_EXCEPT', 89) -HAVE_ARGUMENT = 90 # Opcodes from here have an argument: +HAVE_ARGUMENT = 90 # real opcodes from here have an argument: name_op('STORE_NAME', 90) # Index in name list name_op('DELETE_NAME', 91) # "" @@ -116,7 +141,7 @@ name_op('STORE_ATTR', 95) # Index in name list name_op('DELETE_ATTR', 96) # "" name_op('STORE_GLOBAL', 97) # "" name_op('DELETE_GLOBAL', 98) # "" -def_op('ROT_N', 99) +def_op('SWAP', 99) def_op('LOAD_CONST', 100) # Index in const list hasconst.append(100) name_op('LOAD_NAME', 101) # Index in name list @@ -129,33 +154,33 @@ def_op('COMPARE_OP', 107) # Comparison operator hascompare.append(107) name_op('IMPORT_NAME', 108) # Index in name list name_op('IMPORT_FROM', 109) # Index in name list -jrel_op('JUMP_FORWARD', 110) # Number of bytes to skip -jabs_op('JUMP_IF_FALSE_OR_POP', 111) # Target byte offset from beginning of code -jabs_op('JUMP_IF_TRUE_OR_POP', 112) # "" -jabs_op('JUMP_ABSOLUTE', 113) # "" -jabs_op('POP_JUMP_IF_FALSE', 114) # "" -jabs_op('POP_JUMP_IF_TRUE', 115) # "" +jrel_op('JUMP_FORWARD', 110) # Number of words to skip +jrel_op('JUMP_IF_FALSE_OR_POP', 111) # Number of words to skip +jrel_op('JUMP_IF_TRUE_OR_POP', 112) # "" +jrel_op('POP_JUMP_IF_FALSE', 114) +jrel_op('POP_JUMP_IF_TRUE', 115) name_op('LOAD_GLOBAL', 116) # Index in name list def_op('IS_OP', 117) def_op('CONTAINS_OP', 118) def_op('RERAISE', 119) def_op('COPY', 120) -jabs_op('JUMP_IF_NOT_EXC_MATCH', 121) def_op('BINARY_OP', 122) - -def_op('LOAD_FAST', 124) # Local variable number +jrel_op('SEND', 123) # Number of bytes to skip +def_op('LOAD_FAST', 124) # Local variable number, no null check haslocal.append(124) def_op('STORE_FAST', 125) # Local variable number haslocal.append(125) def_op('DELETE_FAST', 126) # Local variable number haslocal.append(126) - -def_op('GEN_START', 129) # Kind of generator/coroutine +def_op('LOAD_FAST_CHECK', 127) # Local variable number +haslocal.append(127) +jrel_op('POP_JUMP_IF_NOT_NONE', 128) +jrel_op('POP_JUMP_IF_NONE', 129) def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3) -def_op('CALL_FUNCTION', 131) # #args +def_op('GET_AWAITABLE', 131) def_op('MAKE_FUNCTION', 132) # Flags def_op('BUILD_SLICE', 133) # Number of items - +jrel_op('JUMP_BACKWARD_NO_INTERRUPT', 134) # Number of words to skip (backwards) def_op('MAKE_CELL', 135) hasfree.append(135) def_op('LOAD_CLOSURE', 136) @@ -166,8 +191,10 @@ def_op('STORE_DEREF', 138) hasfree.append(138) def_op('DELETE_DEREF', 139) hasfree.append(139) +jrel_op('JUMP_BACKWARD', 140) # Number of words to skip (backwards) +def_op('COMPARE_AND_BRANCH', 141) # Comparison and jump +hascompare.append(141) -def_op('CALL_FUNCTION_KW', 141) # #args + #kwargs def_op('CALL_FUNCTION_EX', 142) # Flags def_op('EXTENDED_ARG', 144) @@ -177,22 +204,50 @@ def_op('SET_ADD', 146) def_op('MAP_ADD', 147) def_op('LOAD_CLASSDEREF', 148) hasfree.append(148) - +def_op('COPY_FREE_VARS', 149) +def_op('YIELD_VALUE', 150) +def_op('RESUME', 151) # This must be kept in sync with deepfreeze.py def_op('MATCH_CLASS', 152) def_op('FORMAT_VALUE', 155) def_op('BUILD_CONST_KEY_MAP', 156) def_op('BUILD_STRING', 157) -name_op('LOAD_METHOD', 160) -def_op('CALL_METHOD', 161) def_op('LIST_EXTEND', 162) def_op('SET_UPDATE', 163) def_op('DICT_MERGE', 164) def_op('DICT_UPDATE', 165) -def_op('CALL_METHOD_KW', 166) -del def_op, name_op, jrel_op, jabs_op +def_op('CALL', 171) +def_op('KW_NAMES', 172) +hasconst.append(172) +def_op('CALL_INTRINSIC_1', 173) + +hasarg.extend([op for op in opmap.values() if op >= HAVE_ARGUMENT]) + +MIN_PSEUDO_OPCODE = 256 + +pseudo_op('SETUP_FINALLY', 256, ['NOP']) +hasexc.append(256) +pseudo_op('SETUP_CLEANUP', 257, ['NOP']) +hasexc.append(257) +pseudo_op('SETUP_WITH', 258, ['NOP']) +hasexc.append(258) +pseudo_op('POP_BLOCK', 259, ['NOP']) + +pseudo_op('JUMP', 260, ['JUMP_FORWARD', 'JUMP_BACKWARD']) +pseudo_op('JUMP_NO_INTERRUPT', 261, ['JUMP_FORWARD', 'JUMP_BACKWARD_NO_INTERRUPT']) + +pseudo_op('LOAD_METHOD', 262, ['LOAD_ATTR']) + +MAX_PSEUDO_OPCODE = MIN_PSEUDO_OPCODE + len(_pseudo_ops) - 1 + +del def_op, name_op, jrel_op, jabs_op, pseudo_op + +opname = ['<%r>' % (op,) for op in range(MAX_PSEUDO_OPCODE + 1)] +for op, i in opmap.items(): + opname[i] = op + _nb_ops = [ ("NB_ADD", "+"), @@ -223,61 +278,157 @@ _nb_ops = [ ("NB_INPLACE_XOR", "^="), ] +_specializations = { + "BINARY_OP": [ + "BINARY_OP_ADD_FLOAT", + "BINARY_OP_ADD_INT", + "BINARY_OP_ADD_UNICODE", + "BINARY_OP_INPLACE_ADD_UNICODE", + "BINARY_OP_MULTIPLY_FLOAT", + "BINARY_OP_MULTIPLY_INT", + "BINARY_OP_SUBTRACT_FLOAT", + "BINARY_OP_SUBTRACT_INT", + ], + "BINARY_SUBSCR": [ + "BINARY_SUBSCR_DICT", + "BINARY_SUBSCR_GETITEM", + "BINARY_SUBSCR_LIST_INT", + "BINARY_SUBSCR_TUPLE_INT", + ], + "CALL": [ + "CALL_PY_EXACT_ARGS", + "CALL_PY_WITH_DEFAULTS", + "CALL_BOUND_METHOD_EXACT_ARGS", + "CALL_BUILTIN_CLASS", + "CALL_BUILTIN_FAST_WITH_KEYWORDS", + "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS", + "CALL_NO_KW_BUILTIN_FAST", + "CALL_NO_KW_BUILTIN_O", + "CALL_NO_KW_ISINSTANCE", + "CALL_NO_KW_LEN", + "CALL_NO_KW_LIST_APPEND", + "CALL_NO_KW_METHOD_DESCRIPTOR_FAST", + "CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS", + "CALL_NO_KW_METHOD_DESCRIPTOR_O", + "CALL_NO_KW_STR_1", + "CALL_NO_KW_TUPLE_1", + "CALL_NO_KW_TYPE_1", + ], + "COMPARE_AND_BRANCH": [ + "COMPARE_AND_BRANCH_FLOAT", + "COMPARE_AND_BRANCH_INT", + "COMPARE_AND_BRANCH_STR", + ], + "FOR_ITER": [ + "FOR_ITER_LIST", + "FOR_ITER_TUPLE", + "FOR_ITER_RANGE", + "FOR_ITER_GEN", + ], + "LOAD_ATTR": [ + # These potentially push [NULL, bound method] onto the stack. + "LOAD_ATTR_CLASS", + "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN", + "LOAD_ATTR_INSTANCE_VALUE", + "LOAD_ATTR_MODULE", + "LOAD_ATTR_PROPERTY", + "LOAD_ATTR_SLOT", + "LOAD_ATTR_WITH_HINT", + # These will always push [unbound method, self] onto the stack. + "LOAD_ATTR_METHOD_LAZY_DICT", + "LOAD_ATTR_METHOD_NO_DICT", + "LOAD_ATTR_METHOD_WITH_VALUES", + ], + "LOAD_CONST": [ + "LOAD_CONST__LOAD_FAST", + ], + "LOAD_FAST": [ + "LOAD_FAST__LOAD_CONST", + "LOAD_FAST__LOAD_FAST", + ], + "LOAD_GLOBAL": [ + "LOAD_GLOBAL_BUILTIN", + "LOAD_GLOBAL_MODULE", + ], + "STORE_ATTR": [ + "STORE_ATTR_INSTANCE_VALUE", + "STORE_ATTR_SLOT", + "STORE_ATTR_WITH_HINT", + ], + "STORE_FAST": [ + "STORE_FAST__LOAD_FAST", + "STORE_FAST__STORE_FAST", + ], + "STORE_SUBSCR": [ + "STORE_SUBSCR_DICT", + "STORE_SUBSCR_LIST_INT", + ], + "UNPACK_SEQUENCE": [ + "UNPACK_SEQUENCE_LIST", + "UNPACK_SEQUENCE_TUPLE", + "UNPACK_SEQUENCE_TWO_TUPLE", + ], +} _specialized_instructions = [ - "BINARY_OP_ADAPTIVE", - "BINARY_OP_ADD_INT", - "BINARY_OP_ADD_FLOAT", - "BINARY_OP_ADD_UNICODE", - "BINARY_OP_INPLACE_ADD_UNICODE", - "BINARY_OP_MULTIPLY_INT", - "BINARY_OP_MULTIPLY_FLOAT", - "BINARY_OP_SUBTRACT_INT", - "BINARY_OP_SUBTRACT_FLOAT", - "BINARY_SUBSCR_ADAPTIVE", - "BINARY_SUBSCR_GETITEM", - "BINARY_SUBSCR_LIST_INT", - "BINARY_SUBSCR_TUPLE_INT", - "BINARY_SUBSCR_DICT", - "STORE_SUBSCR_ADAPTIVE", - "STORE_SUBSCR_LIST_INT", - "STORE_SUBSCR_DICT", - "CALL_FUNCTION_ADAPTIVE", - "CALL_FUNCTION_BUILTIN_O", - "CALL_FUNCTION_BUILTIN_FAST", - "CALL_FUNCTION_LEN", - "CALL_FUNCTION_ISINSTANCE", - "CALL_FUNCTION_PY_SIMPLE", - "JUMP_ABSOLUTE_QUICK", - "LOAD_ATTR_ADAPTIVE", - "LOAD_ATTR_INSTANCE_VALUE", - "LOAD_ATTR_WITH_HINT", - "LOAD_ATTR_SLOT", - "LOAD_ATTR_MODULE", - "LOAD_GLOBAL_ADAPTIVE", - "LOAD_GLOBAL_MODULE", - "LOAD_GLOBAL_BUILTIN", - "LOAD_METHOD_ADAPTIVE", - "LOAD_METHOD_CACHED", - "LOAD_METHOD_CLASS", - "LOAD_METHOD_MODULE", - "LOAD_METHOD_NO_DICT", - "STORE_ATTR_ADAPTIVE", - "STORE_ATTR_INSTANCE_VALUE", - "STORE_ATTR_SLOT", - "STORE_ATTR_WITH_HINT", - # Super instructions - "LOAD_FAST__LOAD_FAST", - "STORE_FAST__LOAD_FAST", - "LOAD_FAST__LOAD_CONST", - "LOAD_CONST__LOAD_FAST", - "STORE_FAST__STORE_FAST", + opcode for family in _specializations.values() for opcode in family ] _specialization_stats = [ - "specialization_success", - "specialization_failure", + "success", + "failure", "hit", "deferred", "miss", "deopt", - "unquickened", +] + +_cache_format = { + "LOAD_GLOBAL": { + "counter": 1, + "index": 1, + "module_keys_version": 2, + "builtin_keys_version": 1, + }, + "BINARY_OP": { + "counter": 1, + }, + "UNPACK_SEQUENCE": { + "counter": 1, + }, + "COMPARE_OP": { + "counter": 1, + }, + "COMPARE_AND_BRANCH": { + "counter": 1, + }, + "BINARY_SUBSCR": { + "counter": 1, + "type_version": 2, + "func_version": 1, + }, + "FOR_ITER": { + "counter": 1, + }, + "LOAD_ATTR": { + "counter": 1, + "version": 2, + "keys_version": 2, + "descr": 4, + }, + "STORE_ATTR": { + "counter": 1, + "version": 2, + "index": 1, + }, + "CALL": { + "counter": 1, + "func_version": 2, + "min_args": 1, + }, + "STORE_SUBSCR": { + "counter": 1, + }, +} + +_inline_cache_entries = [ + sum(_cache_format.get(opname[opcode], {}).values()) for opcode in range(256) ] diff --git a/Lib/os.py b/Lib/os.py index ab7ef3c1779..598c9e50230 100644 --- a/Lib/os.py +++ b/Lib/os.py @@ -288,7 +288,8 @@ def walk(top, topdown=True, onerror=None, followlinks=False): dirpath, dirnames, filenames dirpath is a string, the path to the directory. dirnames is a list of - the names of the subdirectories in dirpath (excluding '.' and '..'). + the names of the subdirectories in dirpath (including symlinks to directories, + and excluding '.' and '..'). filenames is a list of the names of the non-directory files in dirpath. Note that the names in the lists are just names, with no path components. To get a full path (which begins with top) to a file or directory in @@ -331,97 +332,103 @@ def walk(top, topdown=True, onerror=None, followlinks=False): import os from os.path import join, getsize for root, dirs, files in os.walk('python/Lib/email'): - print(root, "consumes", end="") - print(sum(getsize(join(root, name)) for name in files), end="") + print(root, "consumes ") + print(sum(getsize(join(root, name)) for name in files), end=" ") print("bytes in", len(files), "non-directory files") if 'CVS' in dirs: dirs.remove('CVS') # don't visit CVS directories """ sys.audit("os.walk", top, topdown, onerror, followlinks) - return _walk(fspath(top), topdown, onerror, followlinks) -def _walk(top, topdown, onerror, followlinks): - dirs = [] - nondirs = [] - walk_dirs = [] + stack = [fspath(top)] + islink, join = path.islink, path.join + while stack: + top = stack.pop() + if isinstance(top, tuple): + yield top + continue - # We may not have read permission for top, in which case we can't - # get a list of the files the directory contains. os.walk - # always suppressed the exception then, rather than blow up for a - # minor reason when (say) a thousand readable directories are still - # left to visit. That logic is copied here. - try: - # Note that scandir is global in this module due - # to earlier import-*. - scandir_it = scandir(top) - except OSError as error: - if onerror is not None: - onerror(error) - return + dirs = [] + nondirs = [] + walk_dirs = [] - with scandir_it: - while True: - try: + # We may not have read permission for top, in which case we can't + # get a list of the files the directory contains. + # We suppress the exception here, rather than blow up for a + # minor reason when (say) a thousand readable directories are still + # left to visit. + try: + scandir_it = scandir(top) + except OSError as error: + if onerror is not None: + onerror(error) + continue + + cont = False + with scandir_it: + while True: try: - entry = next(scandir_it) - except StopIteration: - break - except OSError as error: - if onerror is not None: - onerror(error) - return - - try: - is_dir = entry.is_dir() - except OSError: - # If is_dir() raises an OSError, consider that the entry is not - # a directory, same behaviour than os.path.isdir(). - is_dir = False - - if is_dir: - dirs.append(entry.name) - else: - nondirs.append(entry.name) - - if not topdown and is_dir: - # Bottom-up: recurse into sub-directory, but exclude symlinks to - # directories if followlinks is False - if followlinks: - walk_into = True - else: try: - is_symlink = entry.is_symlink() - except OSError: - # If is_symlink() raises an OSError, consider that the - # entry is not a symbolic link, same behaviour than - # os.path.islink(). - is_symlink = False - walk_into = not is_symlink + entry = next(scandir_it) + except StopIteration: + break + except OSError as error: + if onerror is not None: + onerror(error) + cont = True + break - if walk_into: - walk_dirs.append(entry.path) + try: + is_dir = entry.is_dir() + except OSError: + # If is_dir() raises an OSError, consider the entry not to + # be a directory, same behaviour as os.path.isdir(). + is_dir = False - # Yield before recursion if going top down - if topdown: - yield top, dirs, nondirs + if is_dir: + dirs.append(entry.name) + else: + nondirs.append(entry.name) - # Recurse into sub-directories - islink, join = path.islink, path.join - for dirname in dirs: - new_path = join(top, dirname) - # Issue #23605: os.path.islink() is used instead of caching - # entry.is_symlink() result during the loop on os.scandir() because - # the caller can replace the directory entry during the "yield" - # above. - if followlinks or not islink(new_path): - yield from _walk(new_path, topdown, onerror, followlinks) - else: - # Recurse into sub-directories - for new_path in walk_dirs: - yield from _walk(new_path, topdown, onerror, followlinks) - # Yield after recursion if going bottom up - yield top, dirs, nondirs + if not topdown and is_dir: + # Bottom-up: traverse into sub-directory, but exclude + # symlinks to directories if followlinks is False + if followlinks: + walk_into = True + else: + try: + is_symlink = entry.is_symlink() + except OSError: + # If is_symlink() raises an OSError, consider the + # entry not to be a symbolic link, same behaviour + # as os.path.islink(). + is_symlink = False + walk_into = not is_symlink + + if walk_into: + walk_dirs.append(entry.path) + if cont: + continue + + if topdown: + # Yield before sub-directory traversal if going top down + yield top, dirs, nondirs + # Traverse into sub-directories + for dirname in reversed(dirs): + new_path = join(top, dirname) + # bpo-23605: os.path.islink() is used instead of caching + # entry.is_symlink() result during the loop on os.scandir() because + # the caller can replace the directory entry during the "yield" + # above. + if followlinks or not islink(new_path): + stack.append(new_path) + else: + # Yield after sub-directory traversal if going bottom up + stack.append((top, dirs, nondirs)) + # Traverse into sub-directories + for new_path in reversed(walk_dirs): + stack.append(new_path) __all__.append("walk") @@ -981,7 +988,7 @@ if sys.platform != 'vxworks': raise ValueError("invalid mode %r" % mode) if buffering == 0 or buffering is None: raise ValueError("popen() does not support unbuffered streams") - import subprocess, io + import subprocess if mode == "r": proc = subprocess.Popen(cmd, shell=True, text=True, diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 621fba0e75c..17659bcd3e2 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -1,3 +1,10 @@ +"""Object-oriented filesystem paths. + +This module provides classes to represent abstract paths and concrete +paths with operations that have semantics appropriate for different +operating systems. +""" + import fnmatch import functools import io @@ -8,7 +15,7 @@ import re import sys import warnings from _collections_abc import Sequence -from errno import EINVAL, ENOENT, ENOTDIR, EBADF, ELOOP +from errno import ENOENT, ENOTDIR, EBADF, ELOOP from operator import attrgetter from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO from urllib.parse import quote_from_bytes as urlquote_from_bytes @@ -23,12 +30,20 @@ __all__ = [ # Internals # +# Reference for Windows paths can be found at +# https://learn.microsoft.com/en-gb/windows/win32/fileio/naming-a-file . +_WIN_RESERVED_NAMES = frozenset( + {'CON', 'PRN', 'AUX', 'NUL', 'CONIN$', 'CONOUT$'} | + {f'COM{c}' for c in '123456789\xb9\xb2\xb3'} | + {f'LPT{c}' for c in '123456789\xb9\xb2\xb3'} +) + _WINERROR_NOT_READY = 21 # drive exists but is not accessible _WINERROR_INVALID_NAME = 123 # fix for bpo-35306 _WINERROR_CANT_RESOLVE_FILENAME = 1921 # broken symlink pointing to itself # EBADF - guard against macOS `stat` throwing EBADF -_IGNORED_ERROS = (ENOENT, ENOTDIR, EBADF, ELOOP) +_IGNORED_ERRNOS = (ENOENT, ENOTDIR, EBADF, ELOOP) _IGNORED_WINERRORS = ( _WINERROR_NOT_READY, @@ -36,7 +51,7 @@ _IGNORED_WINERRORS = ( _WINERROR_CANT_RESOLVE_FILENAME) def _ignore_error(exception): - return (getattr(exception, 'errno', None) in _IGNORED_ERROS or + return (getattr(exception, 'errno', None) in _IGNORED_ERRNOS or getattr(exception, 'winerror', None) in _IGNORED_WINERRORS) @@ -45,329 +60,16 @@ def _is_wildcard_pattern(pat): # be looked up directly as a file. return "*" in pat or "?" in pat or "[" in pat - -class _Flavour(object): - """A flavour implements a particular (platform-specific) set of path - semantics.""" - - def __init__(self): - self.join = self.sep.join - - def parse_parts(self, parts): - parsed = [] - sep = self.sep - altsep = self.altsep - drv = root = '' - it = reversed(parts) - for part in it: - if not part: - continue - if altsep: - part = part.replace(altsep, sep) - drv, root, rel = self.splitroot(part) - if sep in rel: - for x in reversed(rel.split(sep)): - if x and x != '.': - parsed.append(sys.intern(x)) - else: - if rel and rel != '.': - parsed.append(sys.intern(rel)) - if drv or root: - if not drv: - # If no drive is present, try to find one in the previous - # parts. This makes the result of parsing e.g. - # ("C:", "/", "a") reasonably intuitive. - for part in it: - if not part: - continue - if altsep: - part = part.replace(altsep, sep) - drv = self.splitroot(part)[0] - if drv: - break - break - if drv or root: - parsed.append(drv + root) - parsed.reverse() - return drv, root, parsed - - def join_parsed_parts(self, drv, root, parts, drv2, root2, parts2): - """ - Join the two paths represented by the respective - (drive, root, parts) tuples. Return a new (drive, root, parts) tuple. - """ - if root2: - if not drv2 and drv: - return drv, root2, [drv + root2] + parts2[1:] - elif drv2: - if drv2 == drv or self.casefold(drv2) == self.casefold(drv): - # Same drive => second path is relative to the first - return drv, root, parts + parts2[1:] - else: - # Second path is non-anchored (common case) - return drv, root, parts + parts2 - return drv2, root2, parts2 - - -class _WindowsFlavour(_Flavour): - # Reference for Windows paths can be found at - # http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx - - sep = '\\' - altsep = '/' - has_drv = True - pathmod = ntpath - - is_supported = (os.name == 'nt') - - drive_letters = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') - ext_namespace_prefix = '\\\\?\\' - - reserved_names = ( - {'CON', 'PRN', 'AUX', 'NUL', 'CONIN$', 'CONOUT$'} | - {'COM%s' % c for c in '123456789\xb9\xb2\xb3'} | - {'LPT%s' % c for c in '123456789\xb9\xb2\xb3'} - ) - - # Interesting findings about extended paths: - # * '\\?\c:\a' is an extended path, which bypasses normal Windows API - # path processing. Thus relative paths are not resolved and slash is not - # translated to backslash. It has the native NT path limit of 32767 - # characters, but a bit less after resolving device symbolic links, - # such as '\??\C:' => '\Device\HarddiskVolume2'. - # * '\\?\c:/a' looks for a device named 'C:/a' because slash is a - # regular name character in the object namespace. - # * '\\?\c:\foo/bar' is invalid because '/' is illegal in NT filesystems. - # The only path separator at the filesystem level is backslash. - # * '//?/c:\a' and '//?/c:/a' are effectively equivalent to '\\.\c:\a' and - # thus limited to MAX_PATH. - # * Prior to Windows 8, ANSI API bytes paths are limited to MAX_PATH, - # even with the '\\?\' prefix. - - def splitroot(self, part, sep=sep): - first = part[0:1] - second = part[1:2] - if (second == sep and first == sep): - # XXX extended paths should also disable the collapsing of "." - # components (according to MSDN docs). - prefix, part = self._split_extended_path(part) - first = part[0:1] - second = part[1:2] - else: - prefix = '' - third = part[2:3] - if (second == sep and first == sep and third != sep): - # is a UNC path: - # vvvvvvvvvvvvvvvvvvvvv root - # \\machine\mountpoint\directory\etc\... - # directory ^^^^^^^^^^^^^^ - index = part.find(sep, 2) - if index != -1: - index2 = part.find(sep, index + 1) - # a UNC path can't have two slashes in a row - # (after the initial two) - if index2 != index + 1: - if index2 == -1: - index2 = len(part) - if prefix: - return prefix + part[1:index2], sep, part[index2+1:] - else: - return part[:index2], sep, part[index2+1:] - drv = root = '' - if second == ':' and first in self.drive_letters: - drv = part[:2] - part = part[2:] - first = third - if first == sep: - root = first - part = part.lstrip(sep) - return prefix + drv, root, part - - def casefold(self, s): - return s.lower() - - def casefold_parts(self, parts): - return [p.lower() for p in parts] - - def compile_pattern(self, pattern): - return re.compile(fnmatch.translate(pattern), re.IGNORECASE).fullmatch - - def _split_extended_path(self, s, ext_prefix=ext_namespace_prefix): - prefix = '' - if s.startswith(ext_prefix): - prefix = s[:4] - s = s[4:] - if s.startswith('UNC\\'): - prefix += s[:3] - s = '\\' + s[3:] - return prefix, s - - def is_reserved(self, parts): - # NOTE: the rules for reserved names seem somewhat complicated - # (e.g. r"..\NUL" is reserved but not r"foo\NUL" if "foo" does not - # exist). We err on the side of caution and return True for paths - # which are not considered reserved by Windows. - if not parts: - return False - if parts[0].startswith('\\\\'): - # UNC paths are never reserved - return False - name = parts[-1].partition('.')[0].partition(':')[0].rstrip(' ') - return name.upper() in self.reserved_names - - def make_uri(self, path): - # Under Windows, file URIs use the UTF-8 encoding. - drive = path.drive - if len(drive) == 2 and drive[1] == ':': - # It's a path on a local drive => 'file:///c:/a/b' - rest = path.as_posix()[2:].lstrip('/') - return 'file:///%s/%s' % ( - drive, urlquote_from_bytes(rest.encode('utf-8'))) - else: - # It's a path on a network drive => 'file://host/share/a/b' - return 'file:' + urlquote_from_bytes(path.as_posix().encode('utf-8')) - - -class _PosixFlavour(_Flavour): - sep = '/' - altsep = '' - has_drv = False - pathmod = posixpath - - is_supported = (os.name != 'nt') - - def splitroot(self, part, sep=sep): - if part and part[0] == sep: - stripped_part = part.lstrip(sep) - # According to POSIX path resolution: - # http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_11 - # "A pathname that begins with two successive slashes may be - # interpreted in an implementation-defined manner, although more - # than two leading slashes shall be treated as a single slash". - if len(part) - len(stripped_part) == 2: - return '', sep * 2, stripped_part - else: - return '', sep, stripped_part - else: - return '', '', part - - def casefold(self, s): - return s - - def casefold_parts(self, parts): - return parts - - def compile_pattern(self, pattern): - return re.compile(fnmatch.translate(pattern)).fullmatch - - def is_reserved(self, parts): - return False - - def make_uri(self, path): - # We represent the path using the local filesystem encoding, - # for portability to other applications. - bpath = bytes(path) - return 'file://' + urlquote_from_bytes(bpath) - - -_windows_flavour = _WindowsFlavour() -_posix_flavour = _PosixFlavour() - - -class _Accessor: - """An accessor implements a particular (system-specific or not) way of - accessing paths on the filesystem.""" - - -class _NormalAccessor(_Accessor): - - stat = os.stat - - open = io.open - - listdir = os.listdir - - scandir = os.scandir - - chmod = os.chmod - - mkdir = os.mkdir - - unlink = os.unlink - - if hasattr(os, "link"): - link = os.link - else: - def link(self, src, dst): - raise NotImplementedError("os.link() not available on this system") - - rmdir = os.rmdir - - rename = os.rename - - replace = os.replace - - if hasattr(os, "symlink"): - symlink = os.symlink - else: - def symlink(self, src, dst, target_is_directory=False): - raise NotImplementedError("os.symlink() not available on this system") - - def touch(self, path, mode=0o666, exist_ok=True): - if exist_ok: - # First try to bump modification time - # Implementation note: GNU touch uses the UTIME_NOW option of - # the utimensat() / futimens() functions. - try: - os.utime(path, None) - except OSError: - # Avoid exception chaining - pass - else: - return - flags = os.O_CREAT | os.O_WRONLY - if not exist_ok: - flags |= os.O_EXCL - fd = os.open(path, flags, mode) - os.close(fd) - - if hasattr(os, "readlink"): - readlink = os.readlink - else: - def readlink(self, path): - raise NotImplementedError("os.readlink() not available on this system") - - def owner(self, path): - try: - import pwd - return pwd.getpwuid(self.stat(path).st_uid).pw_name - except ImportError: - raise NotImplementedError("Path.owner() is unsupported on this system") - - def group(self, path): - try: - import grp - return grp.getgrgid(self.stat(path).st_gid).gr_name - except ImportError: - raise NotImplementedError("Path.group() is unsupported on this system") - - getcwd = os.getcwd - - expanduser = staticmethod(os.path.expanduser) - - realpath = staticmethod(os.path.realpath) - - -_normal_accessor = _NormalAccessor() - - # # Globbing helpers # +@functools.lru_cache() def _make_selector(pattern_parts, flavour): pat = pattern_parts[0] child_parts = pattern_parts[1:] + if not pat: + return _TerminatingSelector() if pat == '**': cls = _RecursiveWildcardSelector elif '**' in pat: @@ -378,9 +80,6 @@ def _make_selector(pattern_parts, flavour): cls = _PreciseSelector return cls(pat, child_parts, flavour) -if hasattr(functools, "lru_cache"): - _make_selector = functools.lru_cache()(_make_selector) - class _Selector: """A selector matches a specific glob pattern part against the children @@ -401,15 +100,16 @@ class _Selector: path_cls = type(parent_path) is_dir = path_cls.is_dir exists = path_cls.exists - scandir = parent_path._accessor.scandir + scandir = path_cls._scandir + normcase = path_cls._flavour.normcase if not is_dir(parent_path): return iter([]) - return self._select_from(parent_path, is_dir, exists, scandir) + return self._select_from(parent_path, is_dir, exists, scandir, normcase) class _TerminatingSelector: - def _select_from(self, parent_path, is_dir, exists, scandir): + def _select_from(self, parent_path, is_dir, exists, scandir, normcase): yield parent_path @@ -419,11 +119,11 @@ class _PreciseSelector(_Selector): self.name = name _Selector.__init__(self, child_parts, flavour) - def _select_from(self, parent_path, is_dir, exists, scandir): + def _select_from(self, parent_path, is_dir, exists, scandir, normcase): try: path = parent_path._make_child_relpath(self.name) if (is_dir if self.dironly else exists)(path): - for p in self.successor._select_from(path, is_dir, exists, scandir): + for p in self.successor._select_from(path, is_dir, exists, scandir, normcase): yield p except PermissionError: return @@ -432,11 +132,13 @@ class _PreciseSelector(_Selector): class _WildcardSelector(_Selector): def __init__(self, pat, child_parts, flavour): - self.match = flavour.compile_pattern(pat) + self.match = re.compile(fnmatch.translate(flavour.normcase(pat))).fullmatch _Selector.__init__(self, child_parts, flavour) - def _select_from(self, parent_path, is_dir, exists, scandir): + def _select_from(self, parent_path, is_dir, exists, scandir, normcase): try: + # We must close the scandir() object before proceeding to + # avoid exhausting file descriptors when globbing deep trees. with scandir(parent_path) as scandir_it: entries = list(scandir_it) for entry in entries: @@ -452,9 +154,9 @@ class _WildcardSelector(_Selector): raise continue name = entry.name - if self.match(name): + if self.match(normcase(name)): path = parent_path._make_child_relpath(name) - for p in self.successor._select_from(path, is_dir, exists, scandir): + for p in self.successor._select_from(path, is_dir, exists, scandir, normcase): yield p except PermissionError: return @@ -468,6 +170,8 @@ class _RecursiveWildcardSelector(_Selector): def _iterate_directories(self, parent_path, is_dir, scandir): yield parent_path try: + # We must close the scandir() object before proceeding to + # avoid exhausting file descriptors when globbing deep trees. with scandir(parent_path) as scandir_it: entries = list(scandir_it) for entry in entries: @@ -484,13 +188,13 @@ class _RecursiveWildcardSelector(_Selector): except PermissionError: return - def _select_from(self, parent_path, is_dir, exists, scandir): + def _select_from(self, parent_path, is_dir, exists, scandir, normcase): try: yielded = set() try: successor_select = self.successor._select_from for starting_point in self._iterate_directories(parent_path, is_dir, scandir): - for p in successor_select(starting_point, is_dir, exists, scandir): + for p in successor_select(starting_point, is_dir, exists, scandir, normcase): if p not in yielded: yield p yielded.add(p) @@ -528,6 +232,8 @@ class _PathParents(Sequence): if idx >= len(self) or idx < -len(self): raise IndexError(idx) + if idx < 0: + idx += len(self) return self._pathcls._from_parsed_parts(self._drv, self._root, self._parts[:-idx - 1]) @@ -546,8 +252,9 @@ class PurePath(object): """ __slots__ = ( '_drv', '_root', '_parts', - '_str', '_hash', '_pparts', '_cached_cparts', + '_str', '_hash', '_parts_tuple', '_parts_normcase_cached', ) + _flavour = os.path def __new__(cls, *args): """Construct a PurePath from one or several strings and or existing @@ -564,6 +271,23 @@ class PurePath(object): # when pickling related paths. return (self.__class__, tuple(self._parts)) + @classmethod + def _parse_parts(cls, parts): + if not parts: + return '', '', [] + sep = cls._flavour.sep + altsep = cls._flavour.altsep + path = cls._flavour.join(*parts) + if altsep: + path = path.replace(altsep, sep) + drv, root, rel = cls._flavour.splitroot(path) + if drv.startswith(sep): + # pathlib assumes that UNC paths always have a root. + root = sep + unfiltered_parsed = [drv + root] + rel.split(sep) + parsed = [sys.intern(x) for x in unfiltered_parsed if x and x != '.'] + return drv, root, parsed + @classmethod def _parse_args(cls, args): # This is useful when you don't want to create an instance, just @@ -582,7 +306,7 @@ class PurePath(object): "argument should be a str object or an os.PathLike " "object returning str, not %r" % type(a)) - return cls._flavour.parse_parts(parts) + return cls._parse_parts(parts) @classmethod def _from_parts(cls, args): @@ -606,15 +330,9 @@ class PurePath(object): @classmethod def _format_parsed_parts(cls, drv, root, parts): if drv or root: - return drv + root + cls._flavour.join(parts[1:]) + return drv + root + cls._flavour.sep.join(parts[1:]) else: - return cls._flavour.join(parts) - - def _make_child(self, args): - drv, root, parts = self._parse_args(args) - drv, root, parts = self._flavour.join_parsed_parts( - self._drv, self._root, self._parts, drv, root, parts) - return self._from_parsed_parts(drv, root, parts) + return cls._flavour.sep.join(parts) def __str__(self): """Return the string representation of the path, suitable for @@ -647,51 +365,62 @@ class PurePath(object): """Return the path as a 'file' URI.""" if not self.is_absolute(): raise ValueError("relative path can't be expressed as a file URI") - return self._flavour.make_uri(self) + + drive = self._drv + if len(drive) == 2 and drive[1] == ':': + # It's a path on a local drive => 'file:///c:/a/b' + prefix = 'file:///' + drive + path = self.as_posix()[2:] + elif drive: + # It's a path on a network drive => 'file://host/share/a/b' + prefix = 'file:' + path = self.as_posix() + else: + # It's a posix path => 'file:///etc/hosts' + prefix = 'file://' + path = str(self) + return prefix + urlquote_from_bytes(os.fsencode(path)) @property - def _cparts(self): - # Cached casefolded parts, for hashing and comparison + def _parts_normcase(self): + # Cached parts with normalized case, for hashing and comparison. try: - return self._cached_cparts + return self._parts_normcase_cached except AttributeError: - self._cached_cparts = self._flavour.casefold_parts(self._parts) - return self._cached_cparts + self._parts_normcase_cached = [self._flavour.normcase(p) for p in self._parts] + return self._parts_normcase_cached def __eq__(self, other): if not isinstance(other, PurePath): return NotImplemented - return self._cparts == other._cparts and self._flavour is other._flavour + return self._parts_normcase == other._parts_normcase and self._flavour is other._flavour def __hash__(self): try: return self._hash except AttributeError: - self._hash = hash(tuple(self._cparts)) + self._hash = hash(tuple(self._parts_normcase)) return self._hash def __lt__(self, other): if not isinstance(other, PurePath) or self._flavour is not other._flavour: return NotImplemented - return self._cparts < other._cparts + return self._parts_normcase < other._parts_normcase def __le__(self, other): if not isinstance(other, PurePath) or self._flavour is not other._flavour: return NotImplemented - return self._cparts <= other._cparts + return self._parts_normcase <= other._parts_normcase def __gt__(self, other): if not isinstance(other, PurePath) or self._flavour is not other._flavour: return NotImplemented - return self._cparts > other._cparts + return self._parts_normcase > other._parts_normcase def __ge__(self, other): if not isinstance(other, PurePath) or self._flavour is not other._flavour: return NotImplemented - return self._cparts >= other._cparts - - def __class_getitem__(cls, type): - return cls + return self._parts_normcase >= other._parts_normcase drive = property(attrgetter('_drv'), doc="""The drive prefix (letter or UNC path), if any.""") @@ -754,9 +483,9 @@ class PurePath(object): """Return a new path with the file name changed.""" if not self.name: raise ValueError("%r has an empty name" % (self,)) - drv, root, parts = self._flavour.parse_parts((name,)) - if (not name or name[-1] in [self._flavour.sep, self._flavour.altsep] - or drv or root or len(parts) != 1): + f = self._flavour + drv, root, tail = f.splitroot(name) + if drv or root or not tail or f.sep in tail or (f.altsep and f.altsep in tail): raise ValueError("Invalid name %r" % (name)) return self._from_parsed_parts(self._drv, self._root, self._parts[:-1] + [name]) @@ -786,47 +515,43 @@ class PurePath(object): return self._from_parsed_parts(self._drv, self._root, self._parts[:-1] + [name]) - def relative_to(self, *other): + def relative_to(self, other, /, *_deprecated, walk_up=False): """Return the relative path to another path identified by the passed arguments. If the operation is not possible (because this is not - a subpath of the other path), raise ValueError. - """ - # For the purpose of this method, drive and root are considered - # separate parts, i.e.: - # Path('c:/').relative_to('c:') gives Path('/') - # Path('c:/').relative_to('/') raise ValueError - if not other: - raise TypeError("need at least one argument") - parts = self._parts - drv = self._drv - root = self._root - if root: - abs_parts = [drv, root] + parts[1:] - else: - abs_parts = parts - to_drv, to_root, to_parts = self._parse_args(other) - if to_root: - to_abs_parts = [to_drv, to_root] + to_parts[1:] - else: - to_abs_parts = to_parts - n = len(to_abs_parts) - cf = self._flavour.casefold_parts - if (root or drv) if n == 0 else cf(abs_parts[:n]) != cf(to_abs_parts): - formatted = self._format_parsed_parts(to_drv, to_root, to_parts) - raise ValueError("{!r} is not in the subpath of {!r}" - " OR one path is relative and the other is absolute." - .format(str(self), str(formatted))) - return self._from_parsed_parts('', root if n == 1 else '', - abs_parts[n:]) + related to the other path), raise ValueError. - def is_relative_to(self, *other): + The *walk_up* parameter controls whether `..` may be used to resolve + the path. + """ + if _deprecated: + msg = ("support for supplying more than one positional argument " + "to pathlib.PurePath.relative_to() is deprecated and " + "scheduled for removal in Python {remove}") + warnings._deprecated("pathlib.PurePath.relative_to(*args)", msg, + remove=(3, 14)) + path_cls = type(self) + other = path_cls(other, *_deprecated) + for step, path in enumerate([other] + list(other.parents)): + if self.is_relative_to(path): + break + else: + raise ValueError(f"{str(self)!r} and {str(other)!r} have different anchors") + if step and not walk_up: + raise ValueError(f"{str(self)!r} is not in the subpath of {str(other)!r}") + parts = ('..',) * step + self.parts[len(path.parts):] + return path_cls(*parts) + + def is_relative_to(self, other, /, *_deprecated): """Return True if the path is relative to another path or False. """ - try: - self.relative_to(*other) - return True - except ValueError: - return False + if _deprecated: + msg = ("support for supplying more than one argument to " + "pathlib.PurePath.is_relative_to() is deprecated and " + "scheduled for removal in Python {remove}") + warnings._deprecated("pathlib.PurePath.is_relative_to(*args)", + msg, remove=(3, 14)) + other = type(self)(other, *_deprecated) + return other == self or other in self.parents @property def parts(self): @@ -835,10 +560,10 @@ class PurePath(object): # We cache the tuple to avoid building a new one each time .parts # is accessed. XXX is this necessary? try: - return self._pparts + return self._parts_tuple except AttributeError: - self._pparts = tuple(self._parts) - return self._pparts + self._parts_tuple = tuple(self._parts) + return self._parts_tuple def joinpath(self, *args): """Combine this path with one or several arguments, and return a @@ -846,11 +571,26 @@ class PurePath(object): paths) or a totally different path (if one of the arguments is anchored). """ - return self._make_child(args) + drv1, root1, parts1 = self._drv, self._root, self._parts + drv2, root2, parts2 = self._parse_args(args) + if root2: + if not drv2 and drv1: + return self._from_parsed_parts(drv1, root2, [drv1 + root2] + parts2[1:]) + else: + return self._from_parsed_parts(drv2, root2, parts2) + elif drv2: + if drv2 == drv1 or self._flavour.normcase(drv2) == self._flavour.normcase(drv1): + # Same drive => second path is relative to the first. + return self._from_parsed_parts(drv1, root1, parts1 + parts2[1:]) + else: + return self._from_parsed_parts(drv2, root2, parts2) + else: + # Second path is non-anchored (common case). + return self._from_parsed_parts(drv1, root1, parts1 + parts2) def __truediv__(self, key): try: - return self._make_child((key,)) + return self.joinpath(key) except TypeError: return NotImplemented @@ -878,29 +618,40 @@ class PurePath(object): def is_absolute(self): """True if the path is absolute (has both a root and, if applicable, a drive).""" - if not self._root: - return False - return not self._flavour.has_drv or bool(self._drv) + # ntpath.isabs() is defective - see GH-44626 . + if self._flavour is ntpath: + return bool(self._drv and self._root) + return self._flavour.isabs(self) def is_reserved(self): """Return True if the path contains one of the special names reserved by the system, if any.""" - return self._flavour.is_reserved(self._parts) + if self._flavour is posixpath or not self._parts: + return False + + # NOTE: the rules for reserved names seem somewhat complicated + # (e.g. r"..\NUL" is reserved but not r"foo\NUL" if "foo" does not + # exist). We err on the side of caution and return True for paths + # which are not considered reserved by Windows. + if self._parts[0].startswith('\\\\'): + # UNC paths are never reserved. + return False + name = self._parts[-1].partition('.')[0].partition(':')[0].rstrip(' ') + return name.upper() in _WIN_RESERVED_NAMES def match(self, path_pattern): """ Return True if this path matches the given pattern. """ - cf = self._flavour.casefold - path_pattern = cf(path_pattern) - drv, root, pat_parts = self._flavour.parse_parts((path_pattern,)) + path_pattern = self._flavour.normcase(path_pattern) + drv, root, pat_parts = self._parse_parts((path_pattern,)) if not pat_parts: raise ValueError("empty pattern") - if drv and drv != cf(self._drv): + elif drv and drv != self._flavour.normcase(self._drv): return False - if root and root != cf(self._root): + elif root and root != self._root: return False - parts = self._cparts + parts = self._parts_normcase if drv or root: if len(pat_parts) != len(parts): return False @@ -923,7 +674,7 @@ class PurePosixPath(PurePath): On a POSIX system, instantiating a PurePath should return this object. However, you can also instantiate it directly on any system. """ - _flavour = _posix_flavour + _flavour = posixpath __slots__ = () @@ -933,7 +684,7 @@ class PureWindowsPath(PurePath): On a Windows system, instantiating a PurePath should return this object. However, you can also instantiate it directly on any system. """ - _flavour = _windows_flavour + _flavour = ntpath __slots__ = () @@ -949,14 +700,17 @@ class Path(PurePath): object. You can also instantiate a PosixPath or WindowsPath directly, but cannot instantiate a WindowsPath on a POSIX system or vice versa. """ - _accessor = _normal_accessor __slots__ = () def __new__(cls, *args, **kwargs): + if kwargs: + msg = ("support for supplying keyword arguments to pathlib.PurePath " + "is deprecated and scheduled for removal in Python {remove}") + warnings._deprecated("pathlib.PurePath(**kwargs)", msg, remove=(3, 14)) if cls is Path: cls = WindowsPath if os.name == 'nt' else PosixPath self = cls._from_parts(args) - if not self._flavour.is_supported: + if self._flavour is not os.path: raise NotImplementedError("cannot instantiate %r on your system" % (cls.__name__,)) return self @@ -968,27 +722,32 @@ class Path(PurePath): return self._from_parsed_parts(self._drv, self._root, parts) def __enter__(self): + # In previous versions of pathlib, __exit__() marked this path as + # closed; subsequent attempts to perform I/O would raise an IOError. + # This functionality was never documented, and had the effect of + # making Path objects mutable, contrary to PEP 428. + # In Python 3.9 __exit__() was made a no-op. + # In Python 3.11 __enter__() began emitting DeprecationWarning. + # In Python 3.13 __enter__() and __exit__() should be removed. + warnings.warn("pathlib.Path.__enter__() is deprecated and scheduled " + "for removal in Python 3.13; Path objects as a context " + "manager is a no-op", + DeprecationWarning, stacklevel=2) return self def __exit__(self, t, v, tb): - # https://bugs.python.org/issue39682 - # In previous versions of pathlib, this method marked this path as - # closed; subsequent attempts to perform I/O would raise an IOError. - # This functionality was never documented, and had the effect of - # making Path objects mutable, contrary to PEP 428. In Python 3.9 the - # _closed attribute was removed, and this method made a no-op. - # This method and __enter__()/__exit__() should be deprecated and - # removed in the future. pass # Public API @classmethod def cwd(cls): - """Return a new path pointing to the current working directory - (as returned by os.getcwd()). - """ - return cls(cls._accessor.getcwd()) + """Return a new path pointing to the current working directory.""" + # We call 'absolute()' rather than using 'os.getcwd()' directly to + # enable users to replace the implementation of 'absolute()' in a + # subclass and benefit from the new behaviour here. This works because + # os.path.abspath('.') == os.getcwd(). + return cls().absolute() @classmethod def home(cls): @@ -1005,19 +764,24 @@ class Path(PurePath): try: other_st = other_path.stat() except AttributeError: - other_st = self._accessor.stat(other_path) - return os.path.samestat(st, other_st) + other_st = self.__class__(other_path).stat() + return self._flavour.samestat(st, other_st) def iterdir(self): - """Iterate over the files in this directory. Does not yield any - result for the special paths '.' and '..'. + """Yield path objects of the directory contents. + + The children are yielded in arbitrary order, and the + special entries '.' and '..' are not included. """ - for name in self._accessor.listdir(self): - if name in {'.', '..'}: - # Yielding a path object for these makes little sense - continue + for name in os.listdir(self): yield self._make_child_relpath(name) + def _scandir(self): + # bpo-24132: a future version of pathlib will support subclassing of + # pathlib.Path to customize how the filesystem is accessed. This + # includes scandir(), which is used to implement glob(). + return os.scandir(self) + def glob(self, pattern): """Iterate over this subtree and yield all existing files (of any kind, including directories) matching the given relative pattern. @@ -1025,9 +789,11 @@ class Path(PurePath): sys.audit("pathlib.Path.glob", self, pattern) if not pattern: raise ValueError("Unacceptable pattern: {!r}".format(pattern)) - drv, root, pattern_parts = self._flavour.parse_parts((pattern,)) + drv, root, pattern_parts = self._parse_parts((pattern,)) if drv or root: raise NotImplementedError("Non-relative patterns are unsupported") + if pattern[-1] in (self._flavour.sep, self._flavour.altsep): + pattern_parts.append('') selector = _make_selector(tuple(pattern_parts), self._flavour) for p in selector.select_from(self): yield p @@ -1038,32 +804,29 @@ class Path(PurePath): this subtree. """ sys.audit("pathlib.Path.rglob", self, pattern) - drv, root, pattern_parts = self._flavour.parse_parts((pattern,)) + drv, root, pattern_parts = self._parse_parts((pattern,)) if drv or root: raise NotImplementedError("Non-relative patterns are unsupported") + if pattern and pattern[-1] in (self._flavour.sep, self._flavour.altsep): + pattern_parts.append('') selector = _make_selector(("**",) + tuple(pattern_parts), self._flavour) for p in selector.select_from(self): yield p def absolute(self): - """Return an absolute version of this path. This function works - even if the path doesn't point to anything. + """Return an absolute version of this path by prepending the current + working directory. No normalization or symlink resolution is performed. - No normalization is done, i.e. all '.' and '..' will be kept along. Use resolve() to get the canonical path to a file. """ - # XXX untested yet! if self.is_absolute(): return self - # FIXME this must defer to the specific flavour (and, under Windows, - # use nt._getfullpathname()) - return self._from_parts([self._accessor.getcwd()] + self._parts) + return self._from_parts([os.getcwd()] + self._parts) def resolve(self, strict=False): """ Make the path absolute, resolving all symlinks on the way and also - normalizing it (for example turning slashes into backslashes under - Windows). + normalizing it. """ def check_eloop(e): @@ -1072,7 +835,7 @@ class Path(PurePath): raise RuntimeError("Symlink loop from %r" % e.filename) try: - s = self._accessor.realpath(self, strict=strict) + s = self._flavour.realpath(self, strict=strict) except OSError as e: check_eloop(e) raise @@ -1092,19 +855,28 @@ class Path(PurePath): Return the result of the stat() system call on this path, like os.stat() does. """ - return self._accessor.stat(self, follow_symlinks=follow_symlinks) + return os.stat(self, follow_symlinks=follow_symlinks) def owner(self): """ Return the login name of the file owner. """ - return self._accessor.owner(self) + try: + import pwd + return pwd.getpwuid(self.stat().st_uid).pw_name + except ImportError: + raise NotImplementedError("Path.owner() is unsupported on this system") def group(self): """ Return the group name of the file gid. """ - return self._accessor.group(self) + + try: + import grp + return grp.getgrgid(self.stat().st_gid).gr_name + except ImportError: + raise NotImplementedError("Path.group() is unsupported on this system") def open(self, mode='r', buffering=-1, encoding=None, errors=None, newline=None): @@ -1114,8 +886,7 @@ class Path(PurePath): """ if "b" not in mode: encoding = io.text_encoding(encoding) - return self._accessor.open(self, mode, buffering, encoding, errors, - newline) + return io.open(self, mode, buffering, encoding, errors, newline) def read_bytes(self): """ @@ -1156,21 +927,38 @@ class Path(PurePath): """ Return the path to which the symbolic link points. """ - path = self._accessor.readlink(self) - return self._from_parts((path,)) + if not hasattr(os, "readlink"): + raise NotImplementedError("os.readlink() not available on this system") + return self._from_parts((os.readlink(self),)) def touch(self, mode=0o666, exist_ok=True): """ Create this file with the given access mode, if it doesn't exist. """ - self._accessor.touch(self, mode, exist_ok) + + if exist_ok: + # First try to bump modification time + # Implementation note: GNU touch uses the UTIME_NOW option of + # the utimensat() / futimens() functions. + try: + os.utime(self, None) + except OSError: + # Avoid exception chaining + pass + else: + return + flags = os.O_CREAT | os.O_WRONLY + if not exist_ok: + flags |= os.O_EXCL + fd = os.open(self, flags, mode) + os.close(fd) def mkdir(self, mode=0o777, parents=False, exist_ok=False): """ Create a new directory at this given path. """ try: - self._accessor.mkdir(self, mode) + os.mkdir(self, mode) except FileNotFoundError: if not parents or self.parent == self: raise @@ -1186,7 +974,7 @@ class Path(PurePath): """ Change the permissions of the path, like os.chmod(). """ - self._accessor.chmod(self, mode, follow_symlinks=follow_symlinks) + os.chmod(self, mode, follow_symlinks=follow_symlinks) def lchmod(self, mode): """ @@ -1201,7 +989,7 @@ class Path(PurePath): If the path is a directory, use rmdir() instead. """ try: - self._accessor.unlink(self) + os.unlink(self) except FileNotFoundError: if not missing_ok: raise @@ -1210,7 +998,7 @@ class Path(PurePath): """ Remove this directory. The directory must be empty. """ - self._accessor.rmdir(self) + os.rmdir(self) def lstat(self): """ @@ -1229,7 +1017,7 @@ class Path(PurePath): Returns the new Path instance pointing to the target path. """ - self._accessor.rename(self, target) + os.rename(self, target) return self.__class__(target) def replace(self, target): @@ -1242,7 +1030,7 @@ class Path(PurePath): Returns the new Path instance pointing to the target path. """ - self._accessor.replace(self, target) + os.replace(self, target) return self.__class__(target) def symlink_to(self, target, target_is_directory=False): @@ -1250,7 +1038,9 @@ class Path(PurePath): Make this path a symlink pointing to the target path. Note the order of arguments (link, target) is the reverse of os.symlink. """ - self._accessor.symlink(target, self, target_is_directory) + if not hasattr(os, "symlink"): + raise NotImplementedError("os.symlink() not available on this system") + os.symlink(target, self, target_is_directory) def hardlink_to(self, target): """ @@ -1258,25 +1048,10 @@ class Path(PurePath): Note the order of arguments (self, target) is the reverse of os.link's. """ - self._accessor.link(target, self) + if not hasattr(os, "link"): + raise NotImplementedError("os.link() not available on this system") + os.link(target, self) - def link_to(self, target): - """ - Make the target path a hard link pointing to this path. - - Note this function does not make this path a hard link to *target*, - despite the implication of the function and argument names. The order - of arguments (target, link) is the reverse of Path.symlink_to, but - matches that of os.link. - - Deprecated since Python 3.10 and scheduled for removal in Python 3.12. - Use `hardlink_to()` instead. - """ - warnings.warn("pathlib.Path.link_to() is deprecated and is scheduled " - "for removal in Python 3.12. " - "Use pathlib.Path.hardlink_to() instead.", - DeprecationWarning, stacklevel=2) - self._accessor.link(self, target) # Convenience functions for querying the stat results @@ -1330,23 +1105,9 @@ class Path(PurePath): def is_mount(self): """ - Check if this path is a POSIX mount point + Check if this path is a mount point """ - # Need to exist and be a dir - if not self.exists() or not self.is_dir(): - return False - - try: - parent_dev = self.parent.stat().st_dev - except OSError: - return False - - dev = self.stat().st_dev - if dev != parent_dev: - return True - ino = self.stat().st_ino - parent_ino = self.parent.stat().st_ino - return ino == parent_ino + return self._flavour.ismount(self) def is_symlink(self): """ @@ -1363,6 +1124,12 @@ class Path(PurePath): # Non-encodable path return False + def is_junction(self): + """ + Whether this path is a junction. + """ + return self._flavour.isjunction(self) + def is_block_device(self): """ Whether this path is a block device. @@ -1433,13 +1200,56 @@ class Path(PurePath): """ if (not (self._drv or self._root) and self._parts and self._parts[0][:1] == '~'): - homedir = self._accessor.expanduser(self._parts[0]) + homedir = self._flavour.expanduser(self._parts[0]) if homedir[:1] == "~": raise RuntimeError("Could not determine home directory.") return self._from_parts([homedir] + self._parts[1:]) return self + def walk(self, top_down=True, on_error=None, follow_symlinks=False): + """Walk the directory tree from this directory, similar to os.walk().""" + sys.audit("pathlib.Path.walk", self, on_error, follow_symlinks) + return self._walk(top_down, on_error, follow_symlinks) + + def _walk(self, top_down, on_error, follow_symlinks): + # We may not have read permission for self, in which case we can't + # get a list of the files the directory contains. os.walk + # always suppressed the exception then, rather than blow up for a + # minor reason when (say) a thousand readable directories are still + # left to visit. That logic is copied here. + try: + scandir_it = self._scandir() + except OSError as error: + if on_error is not None: + on_error(error) + return + + with scandir_it: + dirnames = [] + filenames = [] + for entry in scandir_it: + try: + is_dir = entry.is_dir(follow_symlinks=follow_symlinks) + except OSError: + # Carried over from os.path.isdir(). + is_dir = False + + if is_dir: + dirnames.append(entry.name) + else: + filenames.append(entry.name) + + if top_down: + yield self, dirnames, filenames + + for dirname in dirnames: + dirpath = self._make_child_relpath(dirname) + yield from dirpath._walk(top_down, on_error, follow_symlinks) + + if not top_down: + yield self, dirnames, filenames + class PosixPath(Path, PurePosixPath): """Path subclass for non-Windows systems. @@ -1454,6 +1264,3 @@ class WindowsPath(Path, PureWindowsPath): On a Windows system, instantiating a Path should return this object. """ __slots__ = () - - def is_mount(self): - raise NotImplementedError("Path.is_mount() is unsupported on this system") diff --git a/Lib/pdb.py b/Lib/pdb.py index d7110074538..78d0ce537f1 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -131,7 +131,7 @@ class _rstr(str): return self -class ScriptTarget(str): +class _ScriptTarget(str): def __new__(cls, val): # Mutate self to be the "real path". res = super().__new__(cls, os.path.realpath(val)) @@ -167,7 +167,7 @@ class ScriptTarget(str): return f"exec(compile({fp.read()!r}, {self!r}, 'exec'))" -class ModuleTarget(str): +class _ModuleTarget(str): def check(self): try: self._details @@ -1332,6 +1332,12 @@ class Pdb(bdb.Bdb, cmd.Cmd): if last is None: last = first + 10 filename = self.curframe.f_code.co_filename + # gh-93696: stdlib frozen modules provide a useful __file__ + # this workaround can be removed with the closure of gh-89815 + if filename.startswith("= 1 only diff --git a/Lib/pipes.py b/Lib/pipes.py index 8cc74b0f1f7..61d63b48d3e 100644 --- a/Lib/pipes.py +++ b/Lib/pipes.py @@ -60,10 +60,13 @@ To create a new template object initialized to a given one: import re import os import tempfile +import warnings # we import the quote function rather than the module for backward compat # (quote used to be an undocumented but used function in pipes) from shlex import quote +warnings._deprecated(__name__, remove=(3, 13)) + __all__ = ["Template"] # Conversion step kinds diff --git a/Lib/platform.py b/Lib/platform.py index 9e9b42238fb..2dfaf76252d 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -186,6 +186,10 @@ def libc_ver(executable=None, lib='', version='', chunksize=16384): executable = sys.executable + if not executable: + # sys.executable is not set. + return lib, version + V = _comparable_version # We use os.path.realpath() # here to work around problems with Cygwin not being @@ -281,6 +285,7 @@ def _syscmd_ver(system='', release='', version='', stdin=subprocess.DEVNULL, stderr=subprocess.DEVNULL, text=True, + encoding="locale", shell=True) except (OSError, subprocess.CalledProcessError) as why: #print('Command %s failed: %s' % (cmd, why)) @@ -305,34 +310,52 @@ def _syscmd_ver(system='', release='', version='', version = _norm_version(version) return system, release, version -_WIN32_CLIENT_RELEASES = { - (5, 0): "2000", - (5, 1): "XP", - # Strictly, 5.2 client is XP 64-bit, but platform.py historically - # has always called it 2003 Server - (5, 2): "2003Server", - (5, None): "post2003", +try: + import _wmi +except ImportError: + def _wmi_query(*keys): + raise OSError("not supported") +else: + def _wmi_query(table, *keys): + table = { + "OS": "Win32_OperatingSystem", + "CPU": "Win32_Processor", + }[table] + data = _wmi.exec_query("SELECT {} FROM {}".format( + ",".join(keys), + table, + )).split("\0") + split_data = (i.partition("=") for i in data) + dict_data = {i[0]: i[2] for i in split_data} + return (dict_data[k] for k in keys) - (6, 0): "Vista", - (6, 1): "7", - (6, 2): "8", - (6, 3): "8.1", - (6, None): "post8.1", - (10, 0): "10", - (10, None): "post10", -} +_WIN32_CLIENT_RELEASES = [ + ((10, 1, 0), "post11"), + ((10, 0, 22000), "11"), + ((6, 4, 0), "10"), + ((6, 3, 0), "8.1"), + ((6, 2, 0), "8"), + ((6, 1, 0), "7"), + ((6, 0, 0), "Vista"), + ((5, 2, 3790), "XP64"), + ((5, 2, 0), "XPMedia"), + ((5, 1, 0), "XP"), + ((5, 0, 0), "2000"), +] -# Server release name lookup will default to client names if necessary -_WIN32_SERVER_RELEASES = { - (5, 2): "2003Server", - - (6, 0): "2008Server", - (6, 1): "2008ServerR2", - (6, 2): "2012Server", - (6, 3): "2012ServerR2", - (6, None): "post2012ServerR2", -} +_WIN32_SERVER_RELEASES = [ + ((10, 1, 0), "post2022Server"), + ((10, 0, 20348), "2022Server"), + ((10, 0, 17763), "2019Server"), + ((6, 4, 0), "2016Server"), + ((6, 3, 0), "2012ServerR2"), + ((6, 2, 0), "2012Server"), + ((6, 1, 0), "2008ServerR2"), + ((6, 0, 0), "2008Server"), + ((5, 2, 0), "2003Server"), + ((5, 0, 0), "2000Server"), +] def win32_is_iot(): return win32_edition() in ('IoTUAP', 'NanoServer', 'WindowsCoreHeadless', 'IoTEdgeOS') @@ -355,22 +378,40 @@ def win32_edition(): return None -def win32_ver(release='', version='', csd='', ptype=''): +def _win32_ver(version, csd, ptype): + # Try using WMI first, as this is the canonical source of data + try: + (version, product_type, ptype, spmajor, spminor) = _wmi_query( + 'OS', + 'Version', + 'ProductType', + 'BuildType', + 'ServicePackMajorVersion', + 'ServicePackMinorVersion', + ) + is_client = (int(product_type) == 1) + if spminor and spminor != '0': + csd = f'SP{spmajor}.{spminor}' + else: + csd = f'SP{spmajor}' + return version, csd, ptype, is_client + except OSError: + pass + + # Fall back to a combination of sys.getwindowsversion and "ver" try: from sys import getwindowsversion except ImportError: - return release, version, csd, ptype + return version, csd, ptype, True winver = getwindowsversion() + is_client = (getattr(winver, 'product_type', 1) == 1) try: - major, minor, build = map(int, _syscmd_ver()[2].split('.')) + version = _syscmd_ver()[2] + major, minor, build = map(int, version.split('.')) except ValueError: major, minor, build = winver.platform_version or winver[:3] - version = '{0}.{1}.{2}'.format(major, minor, build) - - release = (_WIN32_CLIENT_RELEASES.get((major, minor)) or - _WIN32_CLIENT_RELEASES.get((major, None)) or - release) + version = '{0}.{1}.{2}'.format(major, minor, build) # getwindowsversion() reflect the compatibility mode Python is # running under, and so the service pack value is only going to be @@ -382,12 +423,6 @@ def win32_ver(release='', version='', csd='', ptype=''): if csd[:13] == 'Service Pack ': csd = 'SP' + csd[13:] - # VER_NT_SERVER = 3 - if getattr(winver, 'product_type', None) == 3: - release = (_WIN32_SERVER_RELEASES.get((major, minor)) or - _WIN32_SERVER_RELEASES.get((major, None)) or - release) - try: try: import winreg @@ -403,6 +438,18 @@ def win32_ver(release='', version='', csd='', ptype=''): except OSError: pass + return version, csd, ptype, is_client + +def win32_ver(release='', version='', csd='', ptype=''): + is_client = False + + version, csd, ptype, is_client = _win32_ver(version, csd, ptype) + + if version: + intversion = tuple(map(int, version.split('.'))) + releases = _WIN32_CLIENT_RELEASES if is_client else _WIN32_SERVER_RELEASES + release = next((r for v, r in releases if v <= intversion), release) + return release, version, csd, ptype @@ -557,7 +604,7 @@ def _platform(*args): platform = platform.replace('unknown', '') # Fold '--'s and remove trailing '-' - while 1: + while True: cleaned = platform.replace('--', '-') if cleaned == platform: break @@ -607,7 +654,10 @@ def _syscmd_file(target, default=''): # XXX Others too ? return default - import subprocess + try: + import subprocess + except ImportError: + return default target = _follow_symlinks(target) # "file" output is locale dependent: force the usage of the C locale # to get deterministic behavior. @@ -718,6 +768,21 @@ def _get_machine_win32(): # http://www.geocities.com/rick_lively/MANUALS/ENV/MSWIN/PROCESSI.HTM # WOW64 processes mask the native architecture + try: + [arch, *_] = _wmi_query('CPU', 'Architecture') + except OSError: + pass + else: + try: + arch = ['x86', 'MIPS', 'Alpha', 'PowerPC', None, + 'ARM', 'ia64', None, None, + 'AMD64', None, None, 'ARM64', + ][int(arch)] + except (ValueError, IndexError): + pass + else: + if arch: + return arch return ( os.environ.get('PROCESSOR_ARCHITEW6432', '') or os.environ.get('PROCESSOR_ARCHITECTURE', '') @@ -731,7 +796,12 @@ class _Processor: return func() or '' def get_win32(): - return os.environ.get('PROCESSOR_IDENTIFIER', _get_machine_win32()) + try: + manufacturer, caption = _wmi_query('CPU', 'Manufacturer', 'Caption') + except OSError: + return os.environ.get('PROCESSOR_IDENTIFIER', _get_machine_win32()) + else: + return f'{caption}, {manufacturer}' def get_OpenVMS(): try: @@ -746,12 +816,16 @@ class _Processor: """ Fall back to `uname -p` """ - import subprocess + try: + import subprocess + except ImportError: + return None try: return subprocess.check_output( ['uname', '-p'], stderr=subprocess.DEVNULL, text=True, + encoding="utf8", ).strip() except (OSError, subprocess.CalledProcessError): pass @@ -775,6 +849,8 @@ class uname_result( except when needed. """ + _fields = ('system', 'node', 'release', 'version', 'machine', 'processor') + @functools.cached_property def processor(self): return _unknown_as_blank(_Processor.get()) @@ -788,7 +864,7 @@ class uname_result( @classmethod def _make(cls, iterable): # override factory to affect length check - num_fields = len(cls._fields) + num_fields = len(cls._fields) - 1 result = cls.__new__(cls, *iterable) if len(result) != num_fields + 1: msg = f'Expected {num_fields} arguments, got {len(result)}' @@ -802,7 +878,7 @@ class uname_result( return len(tuple(iter(self))) def __reduce__(self): - return uname_result, tuple(self)[:len(self._fields)] + return uname_result, tuple(self)[:len(self._fields) - 1] _uname_cache = None @@ -1216,7 +1292,7 @@ def platform(aliased=0, terse=0): else: platform = _platform(system, release, version, csd) - elif system in ('Linux',): + elif system == 'Linux': # check for libc vs. glibc libcname, libcversion = libc_ver() platform = _platform(system, release, machine, processor, diff --git a/Lib/plistlib.py b/Lib/plistlib.py index 3ab71edc320..30f3f673ada 100644 --- a/Lib/plistlib.py +++ b/Lib/plistlib.py @@ -61,7 +61,8 @@ import struct from xml.parsers.expat import ParserCreate -PlistFormat = enum.global_enum(enum.Enum('PlistFormat', 'FMT_XML FMT_BINARY', module=__name__)) +PlistFormat = enum.Enum('PlistFormat', 'FMT_XML FMT_BINARY', module=__name__) +globals().update(PlistFormat.__members__) class UID: @@ -151,7 +152,7 @@ def _date_to_string(d): def _escape(text): m = _controlCharPat.search(text) if m is not None: - raise ValueError("strings can't contains control characters; " + raise ValueError("strings can't contain control characters; " "use bytes instead") text = text.replace("\r\n", "\n") # convert DOS line endings text = text.replace("\r", "\n") # convert Mac line endings @@ -198,7 +199,7 @@ class _PlistParser: def add_object(self, value): if self.current_key is not None: - if not isinstance(self.stack[-1], type({})): + if not isinstance(self.stack[-1], dict): raise ValueError("unexpected element at line %d" % self.parser.CurrentLineNumber) self.stack[-1][self.current_key] = value @@ -207,7 +208,7 @@ class _PlistParser: # this is the root object self.root = value else: - if not isinstance(self.stack[-1], type([])): + if not isinstance(self.stack[-1], list): raise ValueError("unexpected element at line %d" % self.parser.CurrentLineNumber) self.stack[-1].append(value) @@ -231,7 +232,7 @@ class _PlistParser: self.stack.pop() def end_key(self): - if self.current_key or not isinstance(self.stack[-1], type({})): + if self.current_key or not isinstance(self.stack[-1], dict): raise ValueError("unexpected key at line %d" % self.parser.CurrentLineNumber) self.current_key = self.get_data() diff --git a/Lib/poplib.py b/Lib/poplib.py index 0f8587317c2..9a5ef03c983 100644 --- a/Lib/poplib.py +++ b/Lib/poplib.py @@ -419,35 +419,19 @@ if HAVE_SSL: class POP3_SSL(POP3): """POP3 client class over SSL connection - Instantiate with: POP3_SSL(hostname, port=995, keyfile=None, certfile=None, - context=None) + Instantiate with: POP3_SSL(hostname, port=995, context=None) hostname - the hostname of the pop3 over ssl server port - port number - keyfile - PEM formatted file that contains your private key - certfile - PEM formatted certificate chain file context - a ssl.SSLContext See the methods of the parent class POP3 for more documentation. """ - def __init__(self, host, port=POP3_SSL_PORT, keyfile=None, certfile=None, - timeout=socket._GLOBAL_DEFAULT_TIMEOUT, context=None): - if context is not None and keyfile is not None: - raise ValueError("context and keyfile arguments are mutually " - "exclusive") - if context is not None and certfile is not None: - raise ValueError("context and certfile arguments are mutually " - "exclusive") - if keyfile is not None or certfile is not None: - import warnings - warnings.warn("keyfile and certfile are deprecated, use a " - "custom context instead", DeprecationWarning, 2) - self.keyfile = keyfile - self.certfile = certfile + def __init__(self, host, port=POP3_SSL_PORT, + *, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, context=None): if context is None: - context = ssl._create_stdlib_context(certfile=certfile, - keyfile=keyfile) + context = ssl._create_stdlib_context() self.context = context POP3.__init__(self, host, port, timeout) @@ -457,7 +441,7 @@ if HAVE_SSL: server_hostname=self.host) return sock - def stls(self, keyfile=None, certfile=None, context=None): + def stls(self, context=None): """The method unconditionally raises an exception since the STLS command doesn't make any sense on an already established SSL/TLS session. diff --git a/Lib/posixpath.py b/Lib/posixpath.py index 195374613a7..32b5d6e105d 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -28,14 +28,14 @@ import stat import genericpath from genericpath import * -__all__ = ["normcase","isabs","join","splitdrive","split","splitext", +__all__ = ["normcase","isabs","join","splitdrive","splitroot","split","splitext", "basename","dirname","commonprefix","getsize","getmtime", "getatime","getctime","islink","exists","lexists","isdir","isfile", "ismount", "expanduser","expandvars","normpath","abspath", "samefile","sameopenfile","samestat", "curdir","pardir","sep","pathsep","defpath","altsep","extsep", "devnull","realpath","supports_unicode_filenames","relpath", - "commonpath"] + "commonpath", "isjunction"] def _get_sep(path): @@ -135,6 +135,35 @@ def splitdrive(p): return p[:0], p +def splitroot(p): + """Split a pathname into drive, root and tail. On Posix, drive is always + empty; the root may be empty, a single slash, or two slashes. The tail + contains anything after the root. For example: + + splitroot('foo/bar') == ('', '', 'foo/bar') + splitroot('/foo/bar') == ('', '/', 'foo/bar') + splitroot('//foo/bar') == ('', '//', 'foo/bar') + splitroot('///foo/bar') == ('', '/', '//foo/bar') + """ + p = os.fspath(p) + if isinstance(p, bytes): + sep = b'/' + empty = b'' + else: + sep = '/' + empty = '' + if p[:1] != sep: + # Relative path, e.g.: 'foo' + return empty, empty, p + elif p[1:2] != sep or p[2:3] == sep: + # Absolute path, e.g.: '/foo', '///foo', '////foo', etc. + return empty, sep, p[1:] + else: + # Precisely two leading slashes, e.g.: '//foo'. Implementation defined per POSIX, see + # https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13 + return empty, p[:2], p[2:] + + # Return the tail (basename) part of a path, same as split(path)[1]. def basename(p): @@ -169,6 +198,16 @@ def islink(path): return False return stat.S_ISLNK(st.st_mode) + +# Is a path a junction? + +def isjunction(path): + """Test whether a path is a junction + Junctions are not a part of posix semantics""" + os.fspath(path) + return False + + # Being true for dangling symbolic links is also useful. def lexists(path): @@ -195,6 +234,7 @@ def ismount(path): if stat.S_ISLNK(s1.st_mode): return False + path = os.fspath(path) if isinstance(path, bytes): parent = join(path, b'..') else: @@ -241,7 +281,11 @@ def expanduser(path): i = len(path) if i == 1: if 'HOME' not in os.environ: - import pwd + try: + import pwd + except ImportError: + # pwd module unavailable, return path unchanged + return path try: userhome = pwd.getpwuid(os.getuid()).pw_dir except KeyError: @@ -251,7 +295,11 @@ def expanduser(path): else: userhome = os.environ['HOME'] else: - import pwd + try: + import pwd + except ImportError: + # pwd module unavailable, return path unchanged + return path name = path[1:i] if isinstance(name, bytes): name = str(name, 'ASCII') @@ -334,43 +382,47 @@ def expandvars(path): # It should be understood that this may change the meaning of the path # if it contains symbolic links! -def normpath(path): - """Normalize path, eliminating double slashes, etc.""" - path = os.fspath(path) - if isinstance(path, bytes): - sep = b'/' - empty = b'' - dot = b'.' - dotdot = b'..' - else: - sep = '/' - empty = '' - dot = '.' - dotdot = '..' - if path == empty: - return dot - initial_slashes = path.startswith(sep) - # POSIX allows one or two initial slashes, but treats three or more - # as single slash. - # (see http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13) - if (initial_slashes and - path.startswith(sep*2) and not path.startswith(sep*3)): - initial_slashes = 2 - comps = path.split(sep) - new_comps = [] - for comp in comps: - if comp in (empty, dot): - continue - if (comp != dotdot or (not initial_slashes and not new_comps) or - (new_comps and new_comps[-1] == dotdot)): - new_comps.append(comp) - elif new_comps: - new_comps.pop() - comps = new_comps - path = sep.join(comps) - if initial_slashes: - path = sep*initial_slashes + path - return path or dot +try: + from posix import _path_normpath + +except ImportError: + def normpath(path): + """Normalize path, eliminating double slashes, etc.""" + path = os.fspath(path) + if isinstance(path, bytes): + sep = b'/' + empty = b'' + dot = b'.' + dotdot = b'..' + else: + sep = '/' + empty = '' + dot = '.' + dotdot = '..' + if path == empty: + return dot + _, initial_slashes, path = splitroot(path) + comps = path.split(sep) + new_comps = [] + for comp in comps: + if comp in (empty, dot): + continue + if (comp != dotdot or (not initial_slashes and not new_comps) or + (new_comps and new_comps[-1] == dotdot)): + new_comps.append(comp) + elif new_comps: + new_comps.pop() + comps = new_comps + path = initial_slashes + sep.join(comps) + return path or dot + +else: + def normpath(path): + """Normalize path, eliminating double slashes, etc.""" + path = os.fspath(path) + if isinstance(path, bytes): + return os.fsencode(_path_normpath(os.fsdecode(path))) or b"." + return _path_normpath(path) or "." def abspath(path): diff --git a/Lib/pprint.py b/Lib/pprint.py index 575688d8eb6..34ed12637e2 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -637,19 +637,6 @@ def _recursion(object): % (type(object).__name__, id(object))) -def _perfcheck(object=None): - import time - if object is None: - object = [("string", (1, 2), [3, 4], {5: 6, 7: 8})] * 100000 - p = PrettyPrinter() - t1 = time.perf_counter() - p._safe_repr(object, {}, None, 0, True) - t2 = time.perf_counter() - p.pformat(object) - t3 = time.perf_counter() - print("_safe_repr:", t2 - t1) - print("pformat:", t3 - t2) - def _wrap_bytes_repr(object, width, allowance): current = b'' last = len(object) // 4 * 4 @@ -666,6 +653,3 @@ def _wrap_bytes_repr(object, width, allowance): current = candidate if current: yield repr(current) - -if __name__ == "__main__": - _perfcheck() diff --git a/Lib/profile.py b/Lib/profile.py index d8599fb4eeb..453e56285c5 100755 --- a/Lib/profile.py +++ b/Lib/profile.py @@ -24,6 +24,7 @@ # governing permissions and limitations under the License. +import importlib.machinery import sys import time import marshal @@ -589,9 +590,12 @@ def main(): sys.path.insert(0, os.path.dirname(progname)) with open(progname, 'rb') as fp: code = compile(fp.read(), progname, 'exec') + spec = importlib.machinery.ModuleSpec(name='__main__', loader=None, + origin=progname) globs = { - '__file__': progname, - '__name__': '__main__', + '__spec__': spec, + '__file__': spec.origin, + '__name__': spec.name, '__package__': None, '__cached__': None, } diff --git a/Lib/pstats.py b/Lib/pstats.py index 8e0743f2e5f..51bcca84188 100644 --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -57,7 +57,7 @@ class SortKey: @dataclass(unsafe_hash=True) class FunctionProfile: - ncalls: int + ncalls: str tottime: float percall_tottime: float cumtime: float @@ -223,8 +223,6 @@ class Stats: for word, tup in self.sort_arg_dict_default.items(): fragment = word while fragment: - if not fragment: - break if fragment in dict: bad_list[fragment] = 0 break diff --git a/Lib/pty.py b/Lib/pty.py index 8d8ce40df54..03073f07c92 100644 --- a/Lib/pty.py +++ b/Lib/pty.py @@ -162,7 +162,7 @@ def _copy(master_fd, master_read=_read, stdin_read=_read): def spawn(argv, master_read=_read, stdin_read=_read): """Create a spawned process.""" - if type(argv) == type(''): + if isinstance(argv, str): argv = (argv,) sys.audit('pty.spawn', argv) diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 3a2ff218f83..0a693f45230 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -54,6 +54,7 @@ Richard Chamberlain, for the first implementation of textdoc. # the current directory is changed with os.chdir(), an incorrect # path will be displayed. +import __future__ import builtins import importlib._bootstrap import importlib._bootstrap_external @@ -270,6 +271,8 @@ def _split_list(s, predicate): no.append(x) return yes, no +_future_feature_names = set(__future__.all_feature_names) + def visiblename(name, all=None, obj=None): """Decide whether to show documentation on a variable.""" # Certain special names are redundant or internal. @@ -284,6 +287,10 @@ def visiblename(name, all=None, obj=None): # Namedtuples have public fields and methods with a single leading underscore if name.startswith('_') and hasattr(obj, '_fields'): return True + # Ignore __future__ imports. + if obj is not __future__ and name in _future_feature_names: + if isinstance(getattr(obj, name, None), __future__._Feature): + return False if all is not None: # only document that which the programmer exported in __all__ return name in all @@ -679,9 +686,7 @@ class HTMLDoc(Doc): r'RFC[- ]?(\d+)|' r'PEP[- ]?(\d+)|' r'(self\.)?(\w+))') - while True: - match = pattern.search(text, here) - if not match: break + while match := pattern.search(text, here): start, end = match.span() results.append(escape(text[here:start])) @@ -690,10 +695,10 @@ class HTMLDoc(Doc): url = escape(all).replace('"', '"') results.append('%s' % (url, url)) elif rfc: - url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc) + url = 'https://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc) results.append('%s' % (url, escape(all))) elif pep: - url = 'https://www.python.org/dev/peps/pep-%04d/' % int(pep) + url = 'https://peps.python.org/pep-%04d/' % int(pep) results.append('%s' % (url, escape(all))) elif selfdot: # Create a link for methods like 'self.method(...)' @@ -716,7 +721,7 @@ class HTMLDoc(Doc): """Produce HTML for a class tree as given by inspect.getclasstree().""" result = '' for entry in tree: - if type(entry) is type(()): + if isinstance(entry, tuple): c, bases = entry result = result + '
    ' result = result + self.classlink(c, modname) @@ -726,7 +731,7 @@ class HTMLDoc(Doc): parents.append(self.classlink(base, modname)) result = result + '(' + ', '.join(parents) + ')' result = result + '\n
    ' - elif type(entry) is type([]): + elif isinstance(entry, list): result = result + '
    \n%s
    \n' % self.formattree( entry, modname, c) return '
    \n%s
    \n' % result @@ -1164,8 +1169,7 @@ class TextDoc(Doc): def indent(self, text, prefix=' '): """Indent text by prepending a given prefix to each line.""" if not text: return '' - lines = [prefix + line for line in text.split('\n')] - if lines: lines[-1] = lines[-1].rstrip() + lines = [(prefix + line).rstrip() for line in text.split('\n')] return '\n'.join(lines) def section(self, title, contents): @@ -1179,14 +1183,14 @@ class TextDoc(Doc): """Render in text a class tree as returned by inspect.getclasstree().""" result = '' for entry in tree: - if type(entry) is type(()): + if isinstance(entry, tuple): c, bases = entry result = result + prefix + classname(c, modname) if bases and bases != (parent,): parents = (classname(c, modname) for c in bases) result = result + '(%s)' % ', '.join(parents) result = result + '\n' - elif type(entry) is type([]): + elif isinstance(entry, list): result = result + self.formattree( entry, modname, c, prefix + ' ') return result @@ -1556,6 +1560,8 @@ def getpager(): return plainpager if not sys.stdin.isatty() or not sys.stdout.isatty(): return plainpager + if sys.platform == "emscripten": + return plainpager use_pager = os.environ.get('MANPAGER') or os.environ.get('PAGER') if use_pager: if sys.platform == 'win32': # pipes completely broken in Windows @@ -1878,6 +1884,7 @@ class Helper: if topic not in topics: topics = topics + ' ' + topic symbols[symbol] = topics + del topic, symbols_, symbol, topics topics = { 'TYPES': ('types', 'STRINGS UNICODE NUMBERS SEQUENCES MAPPINGS ' @@ -1988,7 +1995,10 @@ class Helper: _GoInteractive = object() def __call__(self, request=_GoInteractive): if request is not self._GoInteractive: - self.help(request) + try: + self.help(request) + except ImportError as e: + self.output.write(f'{e}\n') else: self.intro() self.interact() @@ -2030,7 +2040,7 @@ has the same effect as typing a particular string at the help> prompt. return self.input.readline() def help(self, request): - if type(request) is type(''): + if isinstance(request, str): request = request.strip() if request == 'keywords': self.listkeywords() elif request == 'symbols': self.listsymbols() @@ -2115,7 +2125,7 @@ module "pydoc_data.topics" could not be found. if not target: self.output.write('no documentation found for %s\n' % repr(topic)) return - if type(target) is type(''): + if isinstance(target, str): return self.showtopic(target, more_xrefs) label, xrefs = target diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 78555cddca7..11b75037e78 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Fri Nov 5 19:03:45 2021 +# Autogenerated by Sphinx on Tue Jan 10 13:08:32 2023 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -93,11 +93,7 @@ topics = {'assert': 'The "assert" statement\n' ' optionally in parentheses, the object is assigned to that ' 'target.\n' '\n' - '* Else: The object must be an iterable with the same number of ' - 'items\n' - ' as there are targets in the target list, and the items are ' - 'assigned,\n' - ' from left to right, to the corresponding targets.\n' + '* Else:\n' '\n' ' * If the target list contains one target prefixed with an ' 'asterisk,\n' @@ -362,7 +358,7 @@ topics = {'assert': 'The "assert" statement\n' 'yield_expression)]\n' '\n' 'The difference from normal Assignment statements is that only ' - 'single\n' + 'a single\n' 'target is allowed.\n' '\n' 'For simple names as assignment targets, if in class or module ' @@ -412,12 +408,13 @@ topics = {'assert': 'The "assert" statement\n' 'analysis\n' ' tools and IDEs.\n' '\n' - 'Changed in version 3.8: Now annotated assignments allow same\n' - 'expressions in the right hand side as the regular ' - 'assignments.\n' - 'Previously, some expressions (like un-parenthesized tuple ' - 'expressions)\n' - 'caused a syntax error.\n', + 'Changed in version 3.8: Now annotated assignments allow the ' + 'same\n' + 'expressions in the right hand side as regular assignments. ' + 'Previously,\n' + 'some expressions (like un-parenthesized tuple expressions) ' + 'caused a\n' + 'syntax error.\n', 'async': 'Coroutines\n' '**********\n' '\n' @@ -1003,14 +1000,12 @@ topics = {'assert': 'The "assert" statement\n' ' "A.__dict__[\'x\'].__get__(None, A)".\n' '\n' 'Super Binding\n' - ' If "a" is an instance of "super", then the binding ' - '"super(B,\n' - ' obj).m()" searches "obj.__class__.__mro__" for the ' - 'base class "A"\n' - ' immediately preceding "B" and then invokes the ' - 'descriptor with the\n' - ' call: "A.__dict__[\'m\'].__get__(obj, ' - 'obj.__class__)".\n' + ' A dotted lookup such as "super(A, a).x" searches\n' + ' "a.__class__.__mro__" for a base class "B" following ' + '"A" and then\n' + ' returns "B.__dict__[\'x\'].__get__(a, A)". If not a ' + 'descriptor, "x"\n' + ' is returned unchanged.\n' '\n' 'For instance bindings, the precedence of descriptor ' 'invocation depends\n' @@ -1038,14 +1033,15 @@ topics = {'assert': 'The "assert" statement\n' 'can be\n' 'overridden by instances.\n' '\n' - 'Python methods (including "staticmethod()" and ' - '"classmethod()") are\n' - 'implemented as non-data descriptors. Accordingly, ' - 'instances can\n' - 'redefine and override methods. This allows individual ' - 'instances to\n' - 'acquire behaviors that differ from other instances of ' - 'the same class.\n' + 'Python methods (including those decorated with ' + '"@staticmethod" and\n' + '"@classmethod") are implemented as non-data ' + 'descriptors. Accordingly,\n' + 'instances can redefine and override methods. This ' + 'allows individual\n' + 'instances to acquire behaviors that differ from other ' + 'instances of the\n' + 'same class.\n' '\n' 'The "property()" function is implemented as a data ' 'descriptor.\n' @@ -1058,12 +1054,12 @@ topics = {'assert': 'The "assert" statement\n' '\n' '*__slots__* allow us to explicitly declare data members ' '(like\n' - 'properties) and deny the creation of *__dict__* and ' + 'properties) and deny the creation of "__dict__" and ' '*__weakref__*\n' '(unless explicitly declared in *__slots__* or available ' 'in a parent.)\n' '\n' - 'The space saved over using *__dict__* can be ' + 'The space saved over using "__dict__" can be ' 'significant. Attribute\n' 'lookup speed can be significantly improved as well.\n' '\n' @@ -1075,7 +1071,7 @@ topics = {'assert': 'The "assert" statement\n' '*__slots__*\n' ' reserves space for the declared variables and ' 'prevents the\n' - ' automatic creation of *__dict__* and *__weakref__* ' + ' automatic creation of "__dict__" and *__weakref__* ' 'for each\n' ' instance.\n' '\n' @@ -1084,11 +1080,11 @@ topics = {'assert': 'The "assert" statement\n' '--------------------------\n' '\n' '* When inheriting from a class without *__slots__*, the ' - '*__dict__* and\n' + '"__dict__" and\n' ' *__weakref__* attribute of the instances will always ' 'be accessible.\n' '\n' - '* Without a *__dict__* variable, instances cannot be ' + '* Without a "__dict__" variable, instances cannot be ' 'assigned new\n' ' variables not listed in the *__slots__* definition. ' 'Attempts to\n' @@ -1102,28 +1098,28 @@ topics = {'assert': 'The "assert" statement\n' '\n' '* Without a *__weakref__* variable for each instance, ' 'classes defining\n' - ' *__slots__* do not support weak references to its ' - 'instances. If weak\n' - ' reference support is needed, then add ' + ' *__slots__* do not support "weak references" to its ' + 'instances. If\n' + ' weak reference support is needed, then add ' '"\'__weakref__\'" to the\n' ' sequence of strings in the *__slots__* declaration.\n' '\n' '* *__slots__* are implemented at the class level by ' 'creating\n' - ' descriptors (Implementing Descriptors) for each ' - 'variable name. As a\n' - ' result, class attributes cannot be used to set default ' - 'values for\n' - ' instance variables defined by *__slots__*; otherwise, ' - 'the class\n' - ' attribute would overwrite the descriptor assignment.\n' + ' descriptors for each variable name. As a result, ' + 'class attributes\n' + ' cannot be used to set default values for instance ' + 'variables defined\n' + ' by *__slots__*; otherwise, the class attribute would ' + 'overwrite the\n' + ' descriptor assignment.\n' '\n' '* The action of a *__slots__* declaration is not limited ' 'to the class\n' ' where it is defined. *__slots__* declared in parents ' 'are available\n' ' in child classes. However, child subclasses will get a ' - '*__dict__*\n' + '"__dict__"\n' ' and *__weakref__* unless they also define *__slots__* ' '(which should\n' ' only contain names of any *additional* slots).\n' @@ -1143,13 +1139,19 @@ topics = {'assert': 'The "assert" statement\n' ' “variable-length†built-in types such as "int", ' '"bytes" and "tuple".\n' '\n' - '* Any non-string iterable may be assigned to ' - '*__slots__*. Mappings may\n' - ' also be used; however, in the future, special meaning ' - 'may be\n' - ' assigned to the values corresponding to each key.\n' + '* Any non-string *iterable* may be assigned to ' + '*__slots__*.\n' '\n' - '* *__class__* assignment works only if both classes have ' + '* If a "dictionary" is used to assign *__slots__*, the ' + 'dictionary keys\n' + ' will be used as the slot names. The values of the ' + 'dictionary can be\n' + ' used to provide per-attribute docstrings that will be ' + 'recognised by\n' + ' "inspect.getdoc()" and displayed in the output of ' + '"help()".\n' + '\n' + '* "__class__" assignment works only if both classes have ' 'the same\n' ' *__slots__*.\n' '\n' @@ -1161,10 +1163,10 @@ topics = {'assert': 'The "assert" statement\n' 'violations\n' ' raise "TypeError".\n' '\n' - '* If an iterator is used for *__slots__* then a ' - 'descriptor is created\n' - ' for each of the iterator’s values. However, the ' - '*__slots__*\n' + '* If an *iterator* is used for *__slots__* then a ' + '*descriptor* is\n' + ' created for each of the iterator’s values. However, ' + 'the *__slots__*\n' ' attribute will be an empty iterator.\n', 'attribute-references': 'Attribute references\n' '********************\n' @@ -1581,25 +1583,24 @@ topics = {'assert': 'The "assert" statement\n' 'parameter name, the first slot is used, and so on). If the slot ' 'is\n' 'already filled, a "TypeError" exception is raised. Otherwise, the\n' - 'value of the argument is placed in the slot, filling it (even if ' - 'the\n' - 'expression is "None", it fills the slot). When all arguments have\n' - 'been processed, the slots that are still unfilled are filled with ' - 'the\n' - 'corresponding default value from the function definition. ' - '(Default\n' - 'values are calculated, once, when the function is defined; thus, a\n' - 'mutable object such as a list or dictionary used as default value ' - 'will\n' - 'be shared by all calls that don’t specify an argument value for ' - 'the\n' - 'corresponding slot; this should usually be avoided.) If there are ' - 'any\n' - 'unfilled slots for which no default value is specified, a ' - '"TypeError"\n' - 'exception is raised. Otherwise, the list of filled slots is used ' - 'as\n' - 'the argument list for the call.\n' + 'argument is placed in the slot, filling it (even if the expression ' + 'is\n' + '"None", it fills the slot). When all arguments have been ' + 'processed,\n' + 'the slots that are still unfilled are filled with the ' + 'corresponding\n' + 'default value from the function definition. (Default values are\n' + 'calculated, once, when the function is defined; thus, a mutable ' + 'object\n' + 'such as a list or dictionary used as default value will be shared ' + 'by\n' + 'all calls that don’t specify an argument value for the ' + 'corresponding\n' + 'slot; this should usually be avoided.) If there are any unfilled\n' + 'slots for which no default value is specified, a "TypeError" ' + 'exception\n' + 'is raised. Otherwise, the list of filled slots is used as the\n' + 'argument list for the call.\n' '\n' '**CPython implementation detail:** An implementation may provide\n' 'built-in functions whose positional parameters do not have names, ' @@ -1666,15 +1667,31 @@ topics = {'assert': 'The "assert" statement\n' 'syntax\n' 'to be used in the same call, so in practice this confusion does ' 'not\n' - 'arise.\n' + 'often arise.\n' '\n' 'If the syntax "**expression" appears in the function call,\n' '"expression" must evaluate to a *mapping*, the contents of which ' 'are\n' - 'treated as additional keyword arguments. If a keyword is already\n' - 'present (as an explicit keyword argument, or from another ' - 'unpacking),\n' - 'a "TypeError" exception is raised.\n' + 'treated as additional keyword arguments. If a parameter matching a ' + 'key\n' + 'has already been given a value (by an explicit keyword argument, ' + 'or\n' + 'from another unpacking), a "TypeError" exception is raised.\n' + '\n' + 'When "**expression" is used, each key in this mapping must be a\n' + 'string. Each value from the mapping is assigned to the first ' + 'formal\n' + 'parameter eligible for keyword assignment whose name is equal to ' + 'the\n' + 'key. A key need not be a Python identifier (e.g. ""max-temp °F"" ' + 'is\n' + 'acceptable, although it will not match any formal parameter that ' + 'could\n' + 'be declared). If there is no match to a formal parameter the ' + 'key-value\n' + 'pair is collected by the "**" parameter, if there is one, or if ' + 'there\n' + 'is not, a "TypeError" exception is raised.\n' '\n' 'Formal parameters using the syntax "*identifier" or "**identifier"\n' 'cannot be used as positional argument slots or as keyword argument\n' @@ -2022,7 +2039,7 @@ topics = {'assert': 'The "assert" statement\n' '\n' '* Mappings (instances of "dict") compare equal if and only if ' 'they\n' - ' have equal *(key, value)* pairs. Equality comparison of the ' + ' have equal "(key, value)" pairs. Equality comparison of the ' 'keys and\n' ' values enforces reflexivity.\n' '\n' @@ -2321,27 +2338,21 @@ topics = {'assert': 'The "assert" statement\n' 'sequence\n' '(such as a string, tuple or list) or other iterable object:\n' '\n' - ' for_stmt ::= "for" target_list "in" expression_list ":" ' - 'suite\n' + ' for_stmt ::= "for" target_list "in" starred_list ":" suite\n' ' ["else" ":" suite]\n' '\n' - 'The expression list is evaluated once; it should yield an ' - 'iterable\n' - 'object. An iterator is created for the result of the\n' - '"expression_list". The suite is then executed once for each ' + 'The "starred_list" expression is evaluated once; it should yield ' + 'an\n' + '*iterable* object. An *iterator* is created for that iterable. ' + 'The\n' + 'first item provided by the iterator is then assigned to the ' + 'target\n' + 'list using the standard rules for assignments (see Assignment\n' + 'statements), and the suite is executed. This repeats for each ' 'item\n' - 'provided by the iterator, in the order returned by the ' - 'iterator. Each\n' - 'item in turn is assigned to the target list using the standard ' - 'rules\n' - 'for assignments (see Assignment statements), and then the suite ' - 'is\n' - 'executed. When the items are exhausted (which is immediately ' - 'when the\n' - 'sequence is empty or an iterator raises a "StopIteration" ' - 'exception),\n' - 'the suite in the "else" clause, if present, is executed, and the ' - 'loop\n' + 'provided by the iterator. When the iterator is exhausted, the ' + 'suite\n' + 'in the "else" clause, if present, is executed, and the loop\n' 'terminates.\n' '\n' 'A "break" statement executed in the first suite terminates the ' @@ -2371,39 +2382,14 @@ topics = {'assert': 'The "assert" statement\n' 'finished,\n' 'but if the sequence is empty, they will not have been assigned ' 'to at\n' - 'all by the loop. Hint: the built-in function "range()" returns ' - 'an\n' - 'iterator of integers suitable to emulate the effect of Pascal’s ' - '"for i\n' - ':= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, ' - '2]".\n' + 'all by the loop. Hint: the built-in type "range()" represents\n' + 'immutable arithmetic sequences of integers. For instance, ' + 'iterating\n' + '"range(3)" successively yields 0, 1, and then 2.\n' '\n' - 'Note:\n' - '\n' - ' There is a subtlety when the sequence is being modified by the ' - 'loop\n' - ' (this can only occur for mutable sequences, e.g. lists). An\n' - ' internal counter is used to keep track of which item is used ' - 'next,\n' - ' and this is incremented on each iteration. When this counter ' - 'has\n' - ' reached the length of the sequence the loop terminates. This ' - 'means\n' - ' that if the suite deletes the current (or a previous) item ' - 'from the\n' - ' sequence, the next item will be skipped (since it gets the ' - 'index of\n' - ' the current item which has already been treated). Likewise, ' - 'if the\n' - ' suite inserts an item in the sequence before the current item, ' + 'Changed in version 3.11: Starred elements are now allowed in ' 'the\n' - ' current item will be treated again the next time through the ' - 'loop.\n' - ' This can lead to nasty bugs that can be avoided by making a\n' - ' temporary copy using a slice of the whole sequence, e.g.,\n' - '\n' - ' for x in a[:]:\n' - ' if x < 0: a.remove(x)\n' + 'expression list.\n' '\n' '\n' 'The "try" statement\n' @@ -2413,44 +2399,57 @@ topics = {'assert': 'The "assert" statement\n' 'code\n' 'for a group of statements:\n' '\n' - ' try_stmt ::= try1_stmt | try2_stmt\n' + ' try_stmt ::= try1_stmt | try2_stmt | try3_stmt\n' ' try1_stmt ::= "try" ":" suite\n' ' ("except" [expression ["as" identifier]] ":" ' 'suite)+\n' ' ["else" ":" suite]\n' ' ["finally" ":" suite]\n' ' try2_stmt ::= "try" ":" suite\n' + ' ("except" "*" expression ["as" identifier] ":" ' + 'suite)+\n' + ' ["else" ":" suite]\n' + ' ["finally" ":" suite]\n' + ' try3_stmt ::= "try" ":" suite\n' ' "finally" ":" suite\n' '\n' + 'Additional information on exceptions can be found in section\n' + 'Exceptions, and information on using the "raise" statement to ' + 'generate\n' + 'exceptions may be found in section The raise statement.\n' + '\n' + '\n' + '"except" clause\n' + '---------------\n' + '\n' 'The "except" clause(s) specify one or more exception handlers. ' 'When no\n' 'exception occurs in the "try" clause, no exception handler is\n' 'executed. When an exception occurs in the "try" suite, a search ' 'for an\n' - 'exception handler is started. This search inspects the except ' - 'clauses\n' - 'in turn until one is found that matches the exception. An ' - 'expression-\n' - 'less except clause, if present, must be last; it matches any\n' - 'exception. For an except clause with an expression, that ' - 'expression\n' - 'is evaluated, and the clause matches the exception if the ' - 'resulting\n' - 'object is “compatible†with the exception. An object is ' - 'compatible\n' - 'with an exception if the object is the class or a base class of ' + 'exception handler is started. This search inspects the "except"\n' + 'clauses in turn until one is found that matches the exception. ' + 'An\n' + 'expression-less "except" clause, if present, must be last; it ' + 'matches\n' + 'any exception. For an "except" clause with an expression, that\n' + 'expression is evaluated, and the clause matches the exception if ' 'the\n' - 'exception object, or a tuple containing an item that is the ' - 'class or a\n' - 'base class of the exception object.\n' - '\n' - 'If no except clause matches the exception, the search for an ' + 'resulting object is “compatible†with the exception. An object ' + 'is\n' + 'compatible with an exception if the object is the class or a ' + '*non-\n' + 'virtual base class* of the exception object, or a tuple ' + 'containing an\n' + 'item that is the class or a non-virtual base class of the ' 'exception\n' - 'handler continues in the surrounding code and on the invocation ' - 'stack.\n' - '[1]\n' + 'object.\n' '\n' - 'If the evaluation of an expression in the header of an except ' + 'If no "except" clause matches the exception, the search for an\n' + 'exception handler continues in the surrounding code and on the\n' + 'invocation stack. [1]\n' + '\n' + 'If the evaluation of an expression in the header of an "except" ' 'clause\n' 'raises an exception, the original search for a handler is ' 'canceled and\n' @@ -2460,24 +2459,24 @@ topics = {'assert': 'The "assert" statement\n' 'raised\n' 'the exception).\n' '\n' - 'When a matching except clause is found, the exception is ' + 'When a matching "except" clause is found, the exception is ' 'assigned to\n' - 'the target specified after the "as" keyword in that except ' - 'clause, if\n' - 'present, and the except clause’s suite is executed. All except\n' - 'clauses must have an executable block. When the end of this ' + 'the target specified after the "as" keyword in that "except" ' + 'clause,\n' + 'if present, and the "except" clause’s suite is executed. All ' + '"except"\n' + 'clauses must have an executable block. When the end of this ' 'block is\n' - 'reached, execution continues normally after the entire try ' - 'statement.\n' - '(This means that if two nested handlers exist for the same ' - 'exception,\n' - 'and the exception occurs in the try clause of the inner handler, ' - 'the\n' - 'outer handler will not handle the exception.)\n' + 'reached, execution continues normally after the entire "try"\n' + 'statement. (This means that if two nested handlers exist for the ' + 'same\n' + 'exception, and the exception occurs in the "try" clause of the ' + 'inner\n' + 'handler, the outer handler will not handle the exception.)\n' '\n' 'When an exception has been assigned using "as target", it is ' 'cleared\n' - 'at the end of the except clause. This is as if\n' + 'at the end of the "except" clause. This is as if\n' '\n' ' except E as N:\n' ' foo\n' @@ -2492,7 +2491,7 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'This means the exception must be assigned to a different name to ' 'be\n' - 'able to refer to it after the except clause. Exceptions are ' + 'able to refer to it after the "except" clause. Exceptions are ' 'cleared\n' 'because with the traceback attached to them, they form a ' 'reference\n' @@ -2500,7 +2499,8 @@ topics = {'assert': 'The "assert" statement\n' 'alive\n' 'until the next garbage collection occurs.\n' '\n' - 'Before an except clause’s suite is executed, details about the\n' + 'Before an "except" clause’s suite is executed, details about ' + 'the\n' 'exception are stored in the "sys" module and can be accessed ' 'via\n' '"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting ' @@ -2536,6 +2536,80 @@ topics = {'assert': 'The "assert" statement\n' ' >>> print(sys.exc_info())\n' ' (None, None, None)\n' '\n' + '\n' + '"except*" clause\n' + '----------------\n' + '\n' + 'The "except*" clause(s) are used for handling "ExceptionGroup"s. ' + 'The\n' + 'exception type for matching is interpreted as in the case of ' + '"except",\n' + 'but in the case of exception groups we can have partial matches ' + 'when\n' + 'the type matches some of the exceptions in the group. This means ' + 'that\n' + 'multiple "except*" clauses can execute, each handling part of ' + 'the\n' + 'exception group. Each clause executes at most once and handles ' + 'an\n' + 'exception group of all matching exceptions. Each exception in ' + 'the\n' + 'group is handled by at most one "except*" clause, the first ' + 'that\n' + 'matches it.\n' + '\n' + ' >>> try:\n' + ' ... raise ExceptionGroup("eg",\n' + ' ... [ValueError(1), TypeError(2), OSError(3), ' + 'OSError(4)])\n' + ' ... except* TypeError as e:\n' + " ... print(f'caught {type(e)} with nested " + "{e.exceptions}')\n" + ' ... except* OSError as e:\n' + " ... print(f'caught {type(e)} with nested " + "{e.exceptions}')\n" + ' ...\n' + " caught with nested (TypeError(2),)\n" + " caught with nested (OSError(3), " + 'OSError(4))\n' + ' + Exception Group Traceback (most recent call last):\n' + ' | File "", line 2, in \n' + ' | ExceptionGroup: eg\n' + ' +-+---------------- 1 ----------------\n' + ' | ValueError: 1\n' + ' +------------------------------------\n' + '\n' + 'Any remaining exceptions that were not handled by any "except*" ' + 'clause\n' + 'are re-raised at the end, combined into an exception group along ' + 'with\n' + 'all exceptions that were raised from within "except*" clauses.\n' + '\n' + 'If the raised exception is not an exception group and its type ' + 'matches\n' + 'one of the "except*" clauses, it is caught and wrapped by an ' + 'exception\n' + 'group with an empty message string.\n' + '\n' + ' >>> try:\n' + ' ... raise BlockingIOError\n' + ' ... except* BlockingIOError as e:\n' + ' ... print(repr(e))\n' + ' ...\n' + " ExceptionGroup('', (BlockingIOError()))\n" + '\n' + 'An "except*" clause must have a matching type, and this type ' + 'cannot be\n' + 'a subclass of "BaseExceptionGroup". It is not possible to mix ' + '"except"\n' + 'and "except*" in the same "try". "break", "continue" and ' + '"return"\n' + 'cannot appear in an "except*" clause.\n' + '\n' + '\n' + '"else" clause\n' + '-------------\n' + '\n' 'The optional "else" clause is executed if the control flow ' 'leaves the\n' '"try" suite, no exception was raised, and no "return", ' @@ -2544,6 +2618,10 @@ topics = {'assert': 'The "assert" statement\n' 'are\n' 'not handled by the preceding "except" clauses.\n' '\n' + '\n' + '"finally" clause\n' + '----------------\n' + '\n' 'If "finally" is present, it specifies a ‘cleanup’ handler. The ' '"try"\n' 'clause is executed, including any "except" and "else" clauses. ' @@ -2597,11 +2675,6 @@ topics = {'assert': 'The "assert" statement\n' ' >>> foo()\n' " 'finally'\n" '\n' - 'Additional information on exceptions can be found in section\n' - 'Exceptions, and information on using the "raise" statement to ' - 'generate\n' - 'exceptions may be found in section The raise statement.\n' - '\n' 'Changed in version 3.8: Prior to Python 3.8, a "continue" ' 'statement\n' 'was illegal in the "finally" clause due to a problem with the\n' @@ -2651,7 +2724,7 @@ topics = {'assert': 'The "assert" statement\n' 'the\n' ' target list, it will be treated the same as an error ' 'occurring\n' - ' within the suite would be. See step 6 below.\n' + ' within the suite would be. See step 7 below.\n' '\n' '6. The suite is executed.\n' '\n' @@ -3453,8 +3526,8 @@ topics = {'assert': 'The "assert" statement\n' ' there is matched against the whole object rather than an ' 'attribute.\n' ' For example "int(0|1)" matches the value "0", but not the ' - 'values\n' - ' "0.0" or "False".\n' + 'value\n' + ' "0.0".\n' '\n' 'In simple terms "CLS(P1, attr=P2)" matches only if the ' 'following\n' @@ -4115,7 +4188,7 @@ topics = {'assert': 'The "assert" statement\n' ' invoking the superclass’s "__new__()" method using\n' ' "super().__new__(cls[, ...])" with appropriate arguments ' 'and then\n' - ' modifying the newly-created instance as necessary before ' + ' modifying the newly created instance as necessary before ' 'returning\n' ' it.\n' '\n' @@ -4419,15 +4492,17 @@ topics = {'assert': 'The "assert" statement\n' 'on members\n' ' of hashed collections including "set", "frozenset", and ' '"dict".\n' - ' "__hash__()" should return an integer. The only required ' - 'property\n' - ' is that objects which compare equal have the same hash ' - 'value; it is\n' - ' advised to mix together the hash values of the ' - 'components of the\n' - ' object that also play a part in comparison of objects by ' - 'packing\n' - ' them into a tuple and hashing the tuple. Example:\n' + ' The "__hash__()" method should return an integer. The ' + 'only required\n' + ' property is that objects which compare equal have the ' + 'same hash\n' + ' value; it is advised to mix together the hash values of ' + 'the\n' + ' components of the object that also play a part in ' + 'comparison of\n' + ' objects by packing them into a tuple and hashing the ' + 'tuple.\n' + ' Example:\n' '\n' ' def __hash__(self):\n' ' return hash((self.name, self.nick, self.color))\n' @@ -4516,7 +4591,7 @@ topics = {'assert': 'The "assert" statement\n' 'Python.This is\n' ' intended to provide protection against a ' 'denial-of-service caused\n' - ' by carefully-chosen inputs that exploit the worst ' + ' by carefully chosen inputs that exploit the worst ' 'case\n' ' performance of a dict insertion, O(n^2) complexity. ' 'See\n' @@ -4622,17 +4697,16 @@ topics = {'assert': 'The "assert" statement\n' 'debugger will pause execution just before the first line of the\n' 'module.\n' '\n' - 'The typical usage to break into the debugger from a running ' - 'program is\n' - 'to insert\n' + 'The typical usage to break into the debugger is to insert:\n' '\n' ' import pdb; pdb.set_trace()\n' '\n' - 'at the location you want to break into the debugger. You can ' - 'then\n' - 'step through the code following this statement, and continue ' - 'running\n' - 'without the debugger using the "continue" command.\n' + 'at the location you want to break into the debugger, and then ' + 'run the\n' + 'program. You can then step through the code following this ' + 'statement,\n' + 'and continue running without the debugger using the "continue"\n' + 'command.\n' '\n' 'New in version 3.7: The built-in "breakpoint()", when called ' 'with\n' @@ -4831,7 +4905,10 @@ topics = {'assert': 'The "assert" statement\n' 'is\n' 'applied to separating the commands; the input is split at the ' 'first\n' - '";;" pair, even if it is in the middle of a quoted string.\n' + '";;" pair, even if it is in the middle of a quoted string. A\n' + 'workaround for strings with double semicolons is to use ' + 'implicit\n' + 'string concatenation "\';\'\';\'" or "";"";"".\n' '\n' 'If a file ".pdbrc" exists in the user’s home directory or in ' 'the\n' @@ -5417,11 +5494,11 @@ topics = {'assert': 'The "assert" statement\n' 'clause is\n' 'selected depending on the class of the instance: it must ' 'reference the\n' - 'class of the instance or a base class thereof. The instance ' - 'can be\n' - 'received by the handler and can carry additional information ' - 'about the\n' - 'exceptional condition.\n' + 'class of the instance or a *non-virtual base class* thereof. ' + 'The\n' + 'instance can be received by the handler and can carry ' + 'additional\n' + 'information about the exceptional condition.\n' '\n' 'Note:\n' '\n' @@ -5493,20 +5570,33 @@ topics = {'assert': 'The "assert" statement\n' 'binding\n' 'operations.\n' '\n' - 'The following constructs bind names: formal parameters to ' - 'functions,\n' - '"import" statements, class and function definitions (these bind ' - 'the\n' - 'class or function name in the defining block), and targets that ' - 'are\n' - 'identifiers if occurring in an assignment, "for" loop header, ' - 'or after\n' - '"as" in a "with" statement or "except" clause. The "import" ' - 'statement\n' - 'of the form "from ... import *" binds all names defined in the\n' - 'imported module, except those beginning with an underscore. ' - 'This form\n' - 'may only be used at the module level.\n' + 'The following constructs bind names:\n' + '\n' + '* formal parameters to functions,\n' + '\n' + '* class definitions,\n' + '\n' + '* function definitions,\n' + '\n' + '* assignment expressions,\n' + '\n' + '* targets that are identifiers if occurring in an assignment:\n' + '\n' + ' * "for" loop header,\n' + '\n' + ' * after "as" in a "with" statement, "except" clause, ' + '"except*"\n' + ' clause, or in the as-pattern in structural pattern ' + 'matching,\n' + '\n' + ' * in a capture pattern in structural pattern matching\n' + '\n' + '* "import" statements.\n' + '\n' + 'The "import" statement of the form "from ... import *" binds ' + 'all names\n' + 'defined in the imported module, except those beginning with an\n' + 'underscore. This form may only be used at the module level.\n' '\n' 'A target occurring in a "del" statement is also considered ' 'bound for\n' @@ -5576,7 +5666,8 @@ topics = {'assert': 'The "assert" statement\n' 'be\n' 'determined by scanning the entire text of the block for name ' 'binding\n' - 'operations.\n' + 'operations. See the FAQ entry on UnboundLocalError for ' + 'examples.\n' '\n' 'If the "global" statement occurs within a block, all uses of ' 'the names\n' @@ -5744,11 +5835,11 @@ topics = {'assert': 'The "assert" statement\n' 'clause is\n' 'selected depending on the class of the instance: it must ' 'reference the\n' - 'class of the instance or a base class thereof. The instance ' - 'can be\n' - 'received by the handler and can carry additional information ' - 'about the\n' - 'exceptional condition.\n' + 'class of the instance or a *non-virtual base class* thereof. ' + 'The\n' + 'instance can be received by the handler and can carry ' + 'additional\n' + 'information about the exceptional condition.\n' '\n' 'Note:\n' '\n' @@ -5845,22 +5936,16 @@ topics = {'assert': 'The "assert" statement\n' 'sequence\n' '(such as a string, tuple or list) or other iterable object:\n' '\n' - ' for_stmt ::= "for" target_list "in" expression_list ":" suite\n' + ' for_stmt ::= "for" target_list "in" starred_list ":" suite\n' ' ["else" ":" suite]\n' '\n' - 'The expression list is evaluated once; it should yield an iterable\n' - 'object. An iterator is created for the result of the\n' - '"expression_list". The suite is then executed once for each item\n' - 'provided by the iterator, in the order returned by the iterator. ' - 'Each\n' - 'item in turn is assigned to the target list using the standard rules\n' - 'for assignments (see Assignment statements), and then the suite is\n' - 'executed. When the items are exhausted (which is immediately when ' - 'the\n' - 'sequence is empty or an iterator raises a "StopIteration" ' - 'exception),\n' - 'the suite in the "else" clause, if present, is executed, and the ' - 'loop\n' + 'The "starred_list" expression is evaluated once; it should yield an\n' + '*iterable* object. An *iterator* is created for that iterable. The\n' + 'first item provided by the iterator is then assigned to the target\n' + 'list using the standard rules for assignments (see Assignment\n' + 'statements), and the suite is executed. This repeats for each item\n' + 'provided by the iterator. When the iterator is exhausted, the suite\n' + 'in the "else" clause, if present, is executed, and the loop\n' 'terminates.\n' '\n' 'A "break" statement executed in the first suite terminates the loop\n' @@ -5884,33 +5969,12 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'Names in the target list are not deleted when the loop is finished,\n' 'but if the sequence is empty, they will not have been assigned to at\n' - 'all by the loop. Hint: the built-in function "range()" returns an\n' - 'iterator of integers suitable to emulate the effect of Pascal’s "for ' - 'i\n' - ':= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n' + 'all by the loop. Hint: the built-in type "range()" represents\n' + 'immutable arithmetic sequences of integers. For instance, iterating\n' + '"range(3)" successively yields 0, 1, and then 2.\n' '\n' - 'Note:\n' - '\n' - ' There is a subtlety when the sequence is being modified by the ' - 'loop\n' - ' (this can only occur for mutable sequences, e.g. lists). An\n' - ' internal counter is used to keep track of which item is used next,\n' - ' and this is incremented on each iteration. When this counter has\n' - ' reached the length of the sequence the loop terminates. This ' - 'means\n' - ' that if the suite deletes the current (or a previous) item from ' - 'the\n' - ' sequence, the next item will be skipped (since it gets the index ' - 'of\n' - ' the current item which has already been treated). Likewise, if ' - 'the\n' - ' suite inserts an item in the sequence before the current item, the\n' - ' current item will be treated again the next time through the loop.\n' - ' This can lead to nasty bugs that can be avoided by making a\n' - ' temporary copy using a slice of the whole sequence, e.g.,\n' - '\n' - ' for x in a[:]:\n' - ' if x < 0: a.remove(x)\n', + 'Changed in version 3.11: Starred elements are now allowed in the\n' + 'expression list.\n', 'formatstrings': 'Format String Syntax\n' '********************\n' '\n' @@ -6103,7 +6167,7 @@ topics = {'assert': 'The "assert" statement\n' 'The general form of a *standard format specifier* is:\n' '\n' ' format_spec ::= ' - '[[fill]align][sign][#][0][width][grouping_option][.precision][type]\n' + '[[fill]align][sign][z][#][0][width][grouping_option][.precision][type]\n' ' fill ::= \n' ' align ::= "<" | ">" | "=" | "^"\n' ' sign ::= "+" | "-" | " "\n' @@ -6205,6 +6269,16 @@ topics = {'assert': 'The "assert" statement\n' ' ' '+-----------+------------------------------------------------------------+\n' '\n' + 'The "\'z\'" option coerces negative zero floating-point ' + 'values to\n' + 'positive zero after rounding to the format precision. This ' + 'option is\n' + 'only valid for floating-point presentation types.\n' + '\n' + 'Changed in version 3.11: Added the "\'z\'" option (see also ' + '**PEP\n' + '682**).\n' + '\n' 'The "\'#\'" option causes the “alternate form†to be used ' 'for the\n' 'conversion. The alternate form is defined differently for ' @@ -6270,19 +6344,19 @@ topics = {'assert': 'The "assert" statement\n' '"\'0\'" no\n' 'longer affects the default alignment for strings.\n' '\n' - 'The *precision* is a decimal number indicating how many ' + 'The *precision* is a decimal integer indicating how many ' 'digits should\n' - 'be displayed after the decimal point for a floating point ' - 'value\n' - 'formatted with "\'f\'" and "\'F\'", or before and after the ' - 'decimal point\n' - 'for a floating point value formatted with "\'g\'" or ' - '"\'G\'". For non-\n' - 'number types the field indicates the maximum field size - ' - 'in other\n' - 'words, how many characters will be used from the field ' - 'content. The\n' - '*precision* is not allowed for integer values.\n' + 'be displayed after the decimal point for presentation types ' + '"\'f\'" and\n' + '"\'F\'", or before and after the decimal point for ' + 'presentation types\n' + '"\'g\'" or "\'G\'". For string presentation types the ' + 'field indicates the\n' + 'maximum field size - in other words, how many characters ' + 'will be used\n' + 'from the field content. The *precision* is not allowed for ' + 'integer\n' + 'presentation types.\n' '\n' 'Finally, the *type* determines how the data should be ' 'presented.\n' @@ -7074,8 +7148,8 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'A non-normative HTML file listing all valid identifier ' 'characters for\n' - 'Unicode 14.0.0 can be found at\n' - 'https://www.unicode.org/Public/14.0.0/ucd/DerivedCoreProperties.txt\n' + 'Unicode 15.0.0 can be found at\n' + 'https://www.unicode.org/Public/15.0.0/ucd/DerivedCoreProperties.txt\n' '\n' '\n' 'Keywords\n' @@ -7245,7 +7319,7 @@ topics = {'assert': 'The "assert" statement\n' 'the clauses had been separated out into individual import ' 'statements.\n' '\n' - 'The details of the first step, finding and loading modules are\n' + 'The details of the first step, finding and loading modules, are\n' 'described in greater detail in the section on the import system, ' 'which\n' 'also describes the various types of packages and modules that can ' @@ -7304,12 +7378,12 @@ topics = {'assert': 'The "assert" statement\n' 'Examples:\n' '\n' ' import foo # foo imported and bound locally\n' - ' import foo.bar.baz # foo.bar.baz imported, foo bound ' - 'locally\n' - ' import foo.bar.baz as fbb # foo.bar.baz imported and bound as ' - 'fbb\n' - ' from foo.bar import baz # foo.bar.baz imported and bound as ' - 'baz\n' + ' import foo.bar.baz # foo, foo.bar, and foo.bar.baz ' + 'imported, foo bound locally\n' + ' import foo.bar.baz as fbb # foo, foo.bar, and foo.bar.baz ' + 'imported, foo.bar.baz bound as fbb\n' + ' from foo.bar import baz # foo, foo.bar, and foo.bar.baz ' + 'imported, foo.bar.baz bound as baz\n' ' from foo import attr # foo imported and foo.attr bound as ' 'attr\n' '\n' @@ -7614,20 +7688,31 @@ topics = {'assert': 'The "assert" statement\n' '*Names* refer to objects. Names are introduced by name binding\n' 'operations.\n' '\n' - 'The following constructs bind names: formal parameters to ' - 'functions,\n' - '"import" statements, class and function definitions (these bind ' - 'the\n' - 'class or function name in the defining block), and targets that ' - 'are\n' - 'identifiers if occurring in an assignment, "for" loop header, or ' - 'after\n' - '"as" in a "with" statement or "except" clause. The "import" ' - 'statement\n' - 'of the form "from ... import *" binds all names defined in the\n' - 'imported module, except those beginning with an underscore. This ' - 'form\n' - 'may only be used at the module level.\n' + 'The following constructs bind names:\n' + '\n' + '* formal parameters to functions,\n' + '\n' + '* class definitions,\n' + '\n' + '* function definitions,\n' + '\n' + '* assignment expressions,\n' + '\n' + '* targets that are identifiers if occurring in an assignment:\n' + '\n' + ' * "for" loop header,\n' + '\n' + ' * after "as" in a "with" statement, "except" clause, "except*"\n' + ' clause, or in the as-pattern in structural pattern matching,\n' + '\n' + ' * in a capture pattern in structural pattern matching\n' + '\n' + '* "import" statements.\n' + '\n' + 'The "import" statement of the form "from ... import *" binds all ' + 'names\n' + 'defined in the imported module, except those beginning with an\n' + 'underscore. This form may only be used at the module level.\n' '\n' 'A target occurring in a "del" statement is also considered bound ' 'for\n' @@ -7694,7 +7779,7 @@ topics = {'assert': 'The "assert" statement\n' 'within a code block. The local variables of a code block can be\n' 'determined by scanning the entire text of the block for name ' 'binding\n' - 'operations.\n' + 'operations. See the FAQ entry on UnboundLocalError for examples.\n' '\n' 'If the "global" statement occurs within a block, all uses of the ' 'names\n' @@ -8046,7 +8131,11 @@ topics = {'assert': 'The "assert" statement\n' '\n' ' The built-in function "int()" falls back to ' '"__trunc__()" if\n' - ' neither "__int__()" nor "__index__()" is defined.\n', + ' neither "__int__()" nor "__index__()" is defined.\n' + '\n' + ' Changed in version 3.11: The delegation of "int()" to ' + '"__trunc__()"\n' + ' is deprecated.\n', 'objects': 'Objects, values and types\n' '*************************\n' '\n' @@ -8187,8 +8276,9 @@ topics = {'assert': 'The "assert" statement\n' 'the syntax is explicitly given, operators are binary. ' 'Operators in\n' 'the same box group left to right (except for ' - 'exponentiation, which\n' - 'groups from right to left).\n' + 'exponentiation and\n' + 'conditional expressions, which group from right to ' + 'left).\n' '\n' 'Note that comparisons, membership tests, and identity ' 'tests, all have\n' @@ -8212,7 +8302,7 @@ topics = {'assert': 'The "assert" statement\n' '| "x(arguments...)", "x.attribute" | ' 'attribute reference |\n' '+-------------------------------------------------+---------------------------------------+\n' - '| "await" "x" | ' + '| "await x" | ' 'Await expression |\n' '+-------------------------------------------------+---------------------------------------+\n' '| "**" | ' @@ -8248,7 +8338,7 @@ topics = {'assert': 'The "assert" statement\n' '| ">=", "!=", "==" | ' 'tests and identity tests |\n' '+-------------------------------------------------+---------------------------------------+\n' - '| "not" "x" | ' + '| "not x" | ' 'Boolean NOT |\n' '+-------------------------------------------------+---------------------------------------+\n' '| "and" | ' @@ -8409,12 +8499,12 @@ topics = {'assert': 'The "assert" statement\n' '\n' ' raise_stmt ::= "raise" [expression ["from" expression]]\n' '\n' - 'If no expressions are present, "raise" re-raises the last ' - 'exception\n' - 'that was active in the current scope. If no exception is active ' - 'in\n' - 'the current scope, a "RuntimeError" exception is raised indicating\n' - 'that this is an error.\n' + 'If no expressions are present, "raise" re-raises the exception that ' + 'is\n' + 'currently being handled, which is also known as the *active\n' + 'exception*. If there isn’t currently an active exception, a\n' + '"RuntimeError" exception is raised indicating that this is an ' + 'error.\n' '\n' 'Otherwise, "raise" evaluates the first expression as the exception\n' 'object. It must be either a subclass or an instance of\n' @@ -8469,11 +8559,14 @@ topics = {'assert': 'The "assert" statement\n' ' File "", line 4, in \n' ' RuntimeError: Something bad happened\n' '\n' - 'A similar mechanism works implicitly if an exception is raised ' - 'inside\n' - 'an exception handler or a "finally" clause: the previous exception ' - 'is\n' - 'then attached as the new exception’s "__context__" attribute:\n' + 'A similar mechanism works implicitly if a new exception is raised ' + 'when\n' + 'an exception is already being handled. An exception may be ' + 'handled\n' + 'when an "except" or "finally" clause, or a "with" statement, is ' + 'used.\n' + 'The previous exception is then attached as the new exception’s\n' + '"__context__" attribute:\n' '\n' ' >>> try:\n' ' ... print(1 / 0)\n' @@ -8514,7 +8607,14 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'New in version 3.3: The "__suppress_context__" attribute to ' 'suppress\n' - 'automatic display of the exception context.\n', + 'automatic display of the exception context.\n' + '\n' + 'Changed in version 3.11: If the traceback of the active exception ' + 'is\n' + 'modified in an "except" clause, a subsequent "raise" statement re-\n' + 'raises the exception with the modified traceback. Previously, the\n' + 'exception was re-raised with the traceback it had when it was ' + 'caught.\n', 'return': 'The "return" statement\n' '**********************\n' '\n' @@ -8555,61 +8655,62 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'The following methods can be defined to implement ' 'container objects.\n' - 'Containers usually are sequences (such as lists or tuples) ' - 'or mappings\n' - '(like dictionaries), but can represent other containers as ' - 'well. The\n' - 'first set of methods is used either to emulate a sequence ' - 'or to\n' - 'emulate a mapping; the difference is that for a sequence, ' - 'the\n' - 'allowable keys should be the integers *k* for which "0 <= ' - 'k < N" where\n' - '*N* is the length of the sequence, or slice objects, which ' - 'define a\n' - 'range of items. It is also recommended that mappings ' - 'provide the\n' - 'methods "keys()", "values()", "items()", "get()", ' - '"clear()",\n' - '"setdefault()", "pop()", "popitem()", "copy()", and ' - '"update()"\n' - 'behaving similar to those for Python’s standard dictionary ' + 'Containers usually are *sequences* (such as "lists" or ' + '"tuples") or\n' + '*mappings* (like "dictionaries"), but can represent other ' + 'containers\n' + 'as well. The first set of methods is used either to ' + 'emulate a\n' + 'sequence or to emulate a mapping; the difference is that ' + 'for a\n' + 'sequence, the allowable keys should be the integers *k* ' + 'for which "0\n' + '<= k < N" where *N* is the length of the sequence, or ' + '"slice" objects,\n' + 'which define a range of items. It is also recommended ' + 'that mappings\n' + 'provide the methods "keys()", "values()", "items()", ' + '"get()",\n' + '"clear()", "setdefault()", "pop()", "popitem()", "copy()", ' + 'and\n' + '"update()" behaving similar to those for Python’s ' + 'standard\n' + '"dictionary" objects. The "collections.abc" module ' + 'provides a\n' + '"MutableMapping" *abstract base class* to help create ' + 'those methods\n' + 'from a base set of "__getitem__()", "__setitem__()", ' + '"__delitem__()",\n' + 'and "keys()". Mutable sequences should provide methods ' + '"append()",\n' + '"count()", "index()", "extend()", "insert()", "pop()", ' + '"remove()",\n' + '"reverse()" and "sort()", like Python standard "list" ' 'objects.\n' - 'The "collections.abc" module provides a "MutableMapping" ' - 'abstract base\n' - 'class to help create those methods from a base set of ' - '"__getitem__()",\n' - '"__setitem__()", "__delitem__()", and "keys()". Mutable ' - 'sequences\n' - 'should provide methods "append()", "count()", "index()", ' - '"extend()",\n' - '"insert()", "pop()", "remove()", "reverse()" and "sort()", ' - 'like Python\n' - 'standard list objects. Finally, sequence types should ' - 'implement\n' - 'addition (meaning concatenation) and multiplication ' + 'Finally, sequence types should implement addition ' '(meaning\n' - 'repetition) by defining the methods "__add__()", ' - '"__radd__()",\n' - '"__iadd__()", "__mul__()", "__rmul__()" and "__imul__()" ' - 'described\n' - 'below; they should not define other numerical operators. ' + 'concatenation) and multiplication (meaning repetition) by ' + 'defining the\n' + 'methods "__add__()", "__radd__()", "__iadd__()", ' + '"__mul__()",\n' + '"__rmul__()" and "__imul__()" described below; they should ' + 'not define\n' + 'other numerical operators. It is recommended that both ' + 'mappings and\n' + 'sequences implement the "__contains__()" method to allow ' + 'efficient use\n' + 'of the "in" operator; for mappings, "in" should search the ' + 'mapping’s\n' + 'keys; for sequences, it should search through the values. ' 'It is\n' - 'recommended that both mappings and sequences implement ' + 'further recommended that both mappings and sequences ' + 'implement the\n' + '"__iter__()" method to allow efficient iteration through ' 'the\n' - '"__contains__()" method to allow efficient use of the "in" ' - 'operator;\n' - 'for mappings, "in" should search the mapping’s keys; for ' - 'sequences, it\n' - 'should search through the values. It is further ' - 'recommended that both\n' - 'mappings and sequences implement the "__iter__()" method ' - 'to allow\n' - 'efficient iteration through the container; for mappings, ' - '"__iter__()"\n' - 'should iterate through the object’s keys; for sequences, ' - 'it should\n' - 'iterate through the values.\n' + 'container; for mappings, "__iter__()" should iterate ' + 'through the\n' + 'object’s keys; for sequences, it should iterate through ' + 'the values.\n' '\n' 'object.__len__(self)\n' '\n' @@ -8668,22 +8769,24 @@ topics = {'assert': 'The "assert" statement\n' 'object.__getitem__(self, key)\n' '\n' ' Called to implement evaluation of "self[key]". For ' - 'sequence types,\n' - ' the accepted keys should be integers and slice ' - 'objects. Note that\n' - ' the special interpretation of negative indexes (if the ' - 'class wishes\n' - ' to emulate a sequence type) is up to the ' - '"__getitem__()" method. If\n' - ' *key* is of an inappropriate type, "TypeError" may be ' - 'raised; if of\n' - ' a value outside the set of indexes for the sequence ' - '(after any\n' - ' special interpretation of negative values), ' - '"IndexError" should be\n' - ' raised. For mapping types, if *key* is missing (not in ' + '*sequence*\n' + ' types, the accepted keys should be integers and slice ' + 'objects.\n' + ' Note that the special interpretation of negative ' + 'indexes (if the\n' + ' class wishes to emulate a *sequence* type) is up to ' 'the\n' - ' container), "KeyError" should be raised.\n' + ' "__getitem__()" method. If *key* is of an inappropriate ' + 'type,\n' + ' "TypeError" may be raised; if of a value outside the ' + 'set of indexes\n' + ' for the sequence (after any special interpretation of ' + 'negative\n' + ' values), "IndexError" should be raised. For *mapping* ' + 'types, if\n' + ' *key* is missing (not in the container), "KeyError" ' + 'should be\n' + ' raised.\n' '\n' ' Note:\n' '\n' @@ -8693,6 +8796,15 @@ topics = {'assert': 'The "assert" statement\n' 'of the\n' ' sequence.\n' '\n' + ' Note:\n' + '\n' + ' When subscripting a *class*, the special class ' + 'method\n' + ' "__class_getitem__()" may be called instead of ' + '"__getitem__()".\n' + ' See __class_getitem__ versus __getitem__ for more ' + 'details.\n' + '\n' 'object.__setitem__(self, key, value)\n' '\n' ' Called to implement assignment to "self[key]". Same ' @@ -8728,19 +8840,13 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'object.__iter__(self)\n' '\n' - ' This method is called when an iterator is required for ' - 'a container.\n' - ' This method should return a new iterator object that ' - 'can iterate\n' - ' over all the objects in the container. For mappings, ' - 'it should\n' - ' iterate over the keys of the container.\n' - '\n' - ' Iterator objects also need to implement this method; ' - 'they are\n' - ' required to return themselves. For more information on ' - 'iterator\n' - ' objects, see Iterator Types.\n' + ' This method is called when an *iterator* is required ' + 'for a\n' + ' container. This method should return a new iterator ' + 'object that can\n' + ' iterate over all the objects in the container. For ' + 'mappings, it\n' + ' should iterate over the keys of the container.\n' '\n' 'object.__reversed__(self)\n' '\n' @@ -8922,31 +9028,7 @@ topics = {'assert': 'The "assert" statement\n' ' still alive. The list is in definition order. Example:\n' '\n' ' >>> int.__subclasses__()\n' - " []\n" - '\n' - '-[ Footnotes ]-\n' - '\n' - '[1] Additional information on these special methods may be ' - 'found in\n' - ' the Python Reference Manual (Basic customization).\n' - '\n' - '[2] As a consequence, the list "[1, 2]" is considered equal ' - 'to "[1.0,\n' - ' 2.0]", and similarly for tuples.\n' - '\n' - '[3] They must have since the parser can’t tell the type of ' - 'the\n' - ' operands.\n' - '\n' - '[4] Cased characters are those with general category ' - 'property being\n' - ' one of “Lu†(Letter, uppercase), “Ll†(Letter, ' - 'lowercase), or “Ltâ€\n' - ' (Letter, titlecase).\n' - '\n' - '[5] To format only a tuple you should therefore provide a ' - 'singleton\n' - ' tuple whose only element is the tuple to be formatted.\n', + " []\n", 'specialnames': 'Special method names\n' '********************\n' '\n' @@ -9015,7 +9097,7 @@ topics = {'assert': 'The "assert" statement\n' ' invoking the superclass’s "__new__()" method using\n' ' "super().__new__(cls[, ...])" with appropriate arguments ' 'and then\n' - ' modifying the newly-created instance as necessary before ' + ' modifying the newly created instance as necessary before ' 'returning\n' ' it.\n' '\n' @@ -9319,15 +9401,17 @@ topics = {'assert': 'The "assert" statement\n' 'on members\n' ' of hashed collections including "set", "frozenset", and ' '"dict".\n' - ' "__hash__()" should return an integer. The only required ' - 'property\n' - ' is that objects which compare equal have the same hash ' - 'value; it is\n' - ' advised to mix together the hash values of the components ' - 'of the\n' - ' object that also play a part in comparison of objects by ' - 'packing\n' - ' them into a tuple and hashing the tuple. Example:\n' + ' The "__hash__()" method should return an integer. The ' + 'only required\n' + ' property is that objects which compare equal have the ' + 'same hash\n' + ' value; it is advised to mix together the hash values of ' + 'the\n' + ' components of the object that also play a part in ' + 'comparison of\n' + ' objects by packing them into a tuple and hashing the ' + 'tuple.\n' + ' Example:\n' '\n' ' def __hash__(self):\n' ' return hash((self.name, self.nick, self.color))\n' @@ -9414,7 +9498,7 @@ topics = {'assert': 'The "assert" statement\n' 'is\n' ' intended to provide protection against a ' 'denial-of-service caused\n' - ' by carefully-chosen inputs that exploit the worst case\n' + ' by carefully chosen inputs that exploit the worst case\n' ' performance of a dict insertion, O(n^2) complexity. ' 'See\n' ' http://www.ocert.org/advisories/ocert-2011-003.html ' @@ -9761,13 +9845,12 @@ topics = {'assert': 'The "assert" statement\n' ' "A.__dict__[\'x\'].__get__(None, A)".\n' '\n' 'Super Binding\n' - ' If "a" is an instance of "super", then the binding ' - '"super(B,\n' - ' obj).m()" searches "obj.__class__.__mro__" for the base ' - 'class "A"\n' - ' immediately preceding "B" and then invokes the descriptor ' - 'with the\n' - ' call: "A.__dict__[\'m\'].__get__(obj, obj.__class__)".\n' + ' A dotted lookup such as "super(A, a).x" searches\n' + ' "a.__class__.__mro__" for a base class "B" following "A" ' + 'and then\n' + ' returns "B.__dict__[\'x\'].__get__(a, A)". If not a ' + 'descriptor, "x"\n' + ' is returned unchanged.\n' '\n' 'For instance bindings, the precedence of descriptor ' 'invocation depends\n' @@ -9795,13 +9878,14 @@ topics = {'assert': 'The "assert" statement\n' 'be\n' 'overridden by instances.\n' '\n' - 'Python methods (including "staticmethod()" and ' - '"classmethod()") are\n' - 'implemented as non-data descriptors. Accordingly, instances ' - 'can\n' - 'redefine and override methods. This allows individual ' - 'instances to\n' - 'acquire behaviors that differ from other instances of the ' + 'Python methods (including those decorated with ' + '"@staticmethod" and\n' + '"@classmethod") are implemented as non-data descriptors. ' + 'Accordingly,\n' + 'instances can redefine and override methods. This allows ' + 'individual\n' + 'instances to acquire behaviors that differ from other ' + 'instances of the\n' 'same class.\n' '\n' 'The "property()" function is implemented as a data ' @@ -9815,12 +9899,12 @@ topics = {'assert': 'The "assert" statement\n' '\n' '*__slots__* allow us to explicitly declare data members ' '(like\n' - 'properties) and deny the creation of *__dict__* and ' + 'properties) and deny the creation of "__dict__" and ' '*__weakref__*\n' '(unless explicitly declared in *__slots__* or available in a ' 'parent.)\n' '\n' - 'The space saved over using *__dict__* can be significant. ' + 'The space saved over using "__dict__" can be significant. ' 'Attribute\n' 'lookup speed can be significantly improved as well.\n' '\n' @@ -9832,7 +9916,7 @@ topics = {'assert': 'The "assert" statement\n' '*__slots__*\n' ' reserves space for the declared variables and prevents ' 'the\n' - ' automatic creation of *__dict__* and *__weakref__* for ' + ' automatic creation of "__dict__" and *__weakref__* for ' 'each\n' ' instance.\n' '\n' @@ -9841,11 +9925,11 @@ topics = {'assert': 'The "assert" statement\n' '~~~~~~~~~~~~~~~~~~~~~~~~~~\n' '\n' '* When inheriting from a class without *__slots__*, the ' - '*__dict__* and\n' + '"__dict__" and\n' ' *__weakref__* attribute of the instances will always be ' 'accessible.\n' '\n' - '* Without a *__dict__* variable, instances cannot be ' + '* Without a "__dict__" variable, instances cannot be ' 'assigned new\n' ' variables not listed in the *__slots__* definition. ' 'Attempts to\n' @@ -9858,28 +9942,28 @@ topics = {'assert': 'The "assert" statement\n' '\n' '* Without a *__weakref__* variable for each instance, ' 'classes defining\n' - ' *__slots__* do not support weak references to its ' - 'instances. If weak\n' - ' reference support is needed, then add "\'__weakref__\'" to ' - 'the\n' + ' *__slots__* do not support "weak references" to its ' + 'instances. If\n' + ' weak reference support is needed, then add ' + '"\'__weakref__\'" to the\n' ' sequence of strings in the *__slots__* declaration.\n' '\n' '* *__slots__* are implemented at the class level by ' 'creating\n' - ' descriptors (Implementing Descriptors) for each variable ' - 'name. As a\n' - ' result, class attributes cannot be used to set default ' - 'values for\n' - ' instance variables defined by *__slots__*; otherwise, the ' - 'class\n' - ' attribute would overwrite the descriptor assignment.\n' + ' descriptors for each variable name. As a result, class ' + 'attributes\n' + ' cannot be used to set default values for instance ' + 'variables defined\n' + ' by *__slots__*; otherwise, the class attribute would ' + 'overwrite the\n' + ' descriptor assignment.\n' '\n' '* The action of a *__slots__* declaration is not limited to ' 'the class\n' ' where it is defined. *__slots__* declared in parents are ' 'available\n' ' in child classes. However, child subclasses will get a ' - '*__dict__*\n' + '"__dict__"\n' ' and *__weakref__* unless they also define *__slots__* ' '(which should\n' ' only contain names of any *additional* slots).\n' @@ -9899,13 +9983,18 @@ topics = {'assert': 'The "assert" statement\n' ' “variable-length†built-in types such as "int", "bytes" ' 'and "tuple".\n' '\n' - '* Any non-string iterable may be assigned to *__slots__*. ' - 'Mappings may\n' - ' also be used; however, in the future, special meaning may ' - 'be\n' - ' assigned to the values corresponding to each key.\n' + '* Any non-string *iterable* may be assigned to *__slots__*.\n' '\n' - '* *__class__* assignment works only if both classes have the ' + '* If a "dictionary" is used to assign *__slots__*, the ' + 'dictionary keys\n' + ' will be used as the slot names. The values of the ' + 'dictionary can be\n' + ' used to provide per-attribute docstrings that will be ' + 'recognised by\n' + ' "inspect.getdoc()" and displayed in the output of ' + '"help()".\n' + '\n' + '* "__class__" assignment works only if both classes have the ' 'same\n' ' *__slots__*.\n' '\n' @@ -9917,9 +10006,9 @@ topics = {'assert': 'The "assert" statement\n' 'violations\n' ' raise "TypeError".\n' '\n' - '* If an iterator is used for *__slots__* then a descriptor ' - 'is created\n' - ' for each of the iterator’s values. However, the ' + '* If an *iterator* is used for *__slots__* then a ' + '*descriptor* is\n' + ' created for each of the iterator’s values. However, the ' '*__slots__*\n' ' attribute will be an empty iterator.\n' '\n' @@ -9928,15 +10017,15 @@ topics = {'assert': 'The "assert" statement\n' '==========================\n' '\n' 'Whenever a class inherits from another class, ' - '*__init_subclass__* is\n' - 'called on that class. This way, it is possible to write ' - 'classes which\n' - 'change the behavior of subclasses. This is closely related ' - 'to class\n' - 'decorators, but where class decorators only affect the ' - 'specific class\n' - 'they’re applied to, "__init_subclass__" solely applies to ' - 'future\n' + '"__init_subclass__()" is\n' + 'called on the parent class. This way, it is possible to ' + 'write classes\n' + 'which change the behavior of subclasses. This is closely ' + 'related to\n' + 'class decorators, but where class decorators only affect the ' + 'specific\n' + 'class they’re applied to, "__init_subclass__" solely applies ' + 'to future\n' 'subclasses of the class defining the method.\n' '\n' 'classmethod object.__init_subclass__(cls)\n' @@ -10128,10 +10217,10 @@ topics = {'assert': 'The "assert" statement\n' 'come from\n' 'the class definition). The "__prepare__" method should be ' 'implemented\n' - 'as a "classmethod()". The namespace returned by ' - '"__prepare__" is\n' - 'passed in to "__new__", but when the final class object is ' - 'created the\n' + 'as a "classmethod". The namespace returned by "__prepare__" ' + 'is passed\n' + 'in to "__new__", but when the final class object is created ' + 'the\n' 'namespace is copied into a new "dict".\n' '\n' 'If the metaclass has no "__prepare__" attribute, then the ' @@ -10318,9 +10407,33 @@ topics = {'assert': 'The "assert" statement\n' 'Emulating generic types\n' '=======================\n' '\n' - 'One can implement the generic class syntax as specified by ' - '**PEP 484**\n' - '(for example "List[int]") by defining a special method:\n' + 'When using *type annotations*, it is often useful to ' + '*parameterize* a\n' + '*generic type* using Python’s square-brackets notation. For ' + 'example,\n' + 'the annotation "list[int]" might be used to signify a "list" ' + 'in which\n' + 'all the elements are of type "int".\n' + '\n' + 'See also:\n' + '\n' + ' **PEP 484** - Type Hints\n' + ' Introducing Python’s framework for type annotations\n' + '\n' + ' Generic Alias Types\n' + ' Documentation for objects representing parameterized ' + 'generic\n' + ' classes\n' + '\n' + ' Generics, user-defined generics and "typing.Generic"\n' + ' Documentation on how to implement generic classes that ' + 'can be\n' + ' parameterized at runtime and understood by static ' + 'type-checkers.\n' + '\n' + 'A class can *generally* only be parameterized if it defines ' + 'the\n' + 'special class method "__class_getitem__()".\n' '\n' 'classmethod object.__class_getitem__(cls, key)\n' '\n' @@ -10328,18 +10441,144 @@ topics = {'assert': 'The "assert" statement\n' 'generic class\n' ' by type arguments found in *key*.\n' '\n' - 'This method is looked up on the class object itself, and ' - 'when defined\n' - 'in the class body, this method is implicitly a class ' - 'method. Note,\n' - 'this mechanism is primarily reserved for use with static ' - 'type hints,\n' - 'other usage is discouraged.\n' + ' When defined on a class, "__class_getitem__()" is ' + 'automatically a\n' + ' class method. As such, there is no need for it to be ' + 'decorated with\n' + ' "@classmethod" when it is defined.\n' + '\n' + '\n' + 'The purpose of *__class_getitem__*\n' + '----------------------------------\n' + '\n' + 'The purpose of "__class_getitem__()" is to allow runtime\n' + 'parameterization of standard-library generic classes in ' + 'order to more\n' + 'easily apply *type hints* to these classes.\n' + '\n' + 'To implement custom generic classes that can be ' + 'parameterized at\n' + 'runtime and understood by static type-checkers, users should ' + 'either\n' + 'inherit from a standard library class that already ' + 'implements\n' + '"__class_getitem__()", or inherit from "typing.Generic", ' + 'which has its\n' + 'own implementation of "__class_getitem__()".\n' + '\n' + 'Custom implementations of "__class_getitem__()" on classes ' + 'defined\n' + 'outside of the standard library may not be understood by ' + 'third-party\n' + 'type-checkers such as mypy. Using "__class_getitem__()" on ' + 'any class\n' + 'for purposes other than type hinting is discouraged.\n' + '\n' + '\n' + '*__class_getitem__* versus *__getitem__*\n' + '----------------------------------------\n' + '\n' + 'Usually, the subscription of an object using square brackets ' + 'will call\n' + 'the "__getitem__()" instance method defined on the object’s ' + 'class.\n' + 'However, if the object being subscribed is itself a class, ' + 'the class\n' + 'method "__class_getitem__()" may be called instead.\n' + '"__class_getitem__()" should return a GenericAlias object if ' + 'it is\n' + 'properly defined.\n' + '\n' + 'Presented with the *expression* "obj[x]", the Python ' + 'interpreter\n' + 'follows something like the following process to decide ' + 'whether\n' + '"__getitem__()" or "__class_getitem__()" should be called:\n' + '\n' + ' from inspect import isclass\n' + '\n' + ' def subscribe(obj, x):\n' + ' """Return the result of the expression \'obj[x]\'"""\n' + '\n' + ' class_of_obj = type(obj)\n' + '\n' + ' # If the class of obj defines __getitem__,\n' + ' # call class_of_obj.__getitem__(obj, x)\n' + " if hasattr(class_of_obj, '__getitem__'):\n" + ' return class_of_obj.__getitem__(obj, x)\n' + '\n' + ' # Else, if obj is a class and defines ' + '__class_getitem__,\n' + ' # call obj.__class_getitem__(x)\n' + ' elif isclass(obj) and hasattr(obj, ' + "'__class_getitem__'):\n" + ' return obj.__class_getitem__(x)\n' + '\n' + ' # Else, raise an exception\n' + ' else:\n' + ' raise TypeError(\n' + ' f"\'{class_of_obj.__name__}\' object is not ' + 'subscriptable"\n' + ' )\n' + '\n' + 'In Python, all classes are themselves instances of other ' + 'classes. The\n' + 'class of a class is known as that class’s *metaclass*, and ' + 'most\n' + 'classes have the "type" class as their metaclass. "type" ' + 'does not\n' + 'define "__getitem__()", meaning that expressions such as ' + '"list[int]",\n' + '"dict[str, float]" and "tuple[str, bytes]" all result in\n' + '"__class_getitem__()" being called:\n' + '\n' + ' >>> # list has class "type" as its metaclass, like most ' + 'classes:\n' + ' >>> type(list)\n' + " \n" + ' >>> type(dict) == type(list) == type(tuple) == type(str) ' + '== type(bytes)\n' + ' True\n' + ' >>> # "list[int]" calls "list.__class_getitem__(int)"\n' + ' >>> list[int]\n' + ' list[int]\n' + ' >>> # list.__class_getitem__ returns a GenericAlias ' + 'object:\n' + ' >>> type(list[int])\n' + " \n" + '\n' + 'However, if a class has a custom metaclass that defines\n' + '"__getitem__()", subscribing the class may result in ' + 'different\n' + 'behaviour. An example of this can be found in the "enum" ' + 'module:\n' + '\n' + ' >>> from enum import Enum\n' + ' >>> class Menu(Enum):\n' + ' ... """A breakfast menu"""\n' + " ... SPAM = 'spam'\n" + " ... BACON = 'bacon'\n" + ' ...\n' + ' >>> # Enum classes have a custom metaclass:\n' + ' >>> type(Menu)\n' + " \n" + ' >>> # EnumMeta defines __getitem__,\n' + ' >>> # so __class_getitem__ is not called,\n' + ' >>> # and the result is not a GenericAlias object:\n' + " >>> Menu['SPAM']\n" + " \n" + " >>> type(Menu['SPAM'])\n" + " \n" '\n' 'See also:\n' '\n' - ' **PEP 560** - Core support for typing module and generic ' + ' **PEP 560** - Core Support for typing module and generic ' 'types\n' + ' Introducing "__class_getitem__()", and outlining when ' + 'a\n' + ' subscription results in "__class_getitem__()" being ' + 'called\n' + ' instead of "__getitem__()"\n' '\n' '\n' 'Emulating callable objects\n' @@ -10358,60 +10597,60 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'The following methods can be defined to implement container ' 'objects.\n' - 'Containers usually are sequences (such as lists or tuples) ' - 'or mappings\n' - '(like dictionaries), but can represent other containers as ' - 'well. The\n' - 'first set of methods is used either to emulate a sequence or ' - 'to\n' - 'emulate a mapping; the difference is that for a sequence, ' - 'the\n' - 'allowable keys should be the integers *k* for which "0 <= k ' - '< N" where\n' - '*N* is the length of the sequence, or slice objects, which ' - 'define a\n' - 'range of items. It is also recommended that mappings ' - 'provide the\n' - 'methods "keys()", "values()", "items()", "get()", ' - '"clear()",\n' - '"setdefault()", "pop()", "popitem()", "copy()", and ' - '"update()"\n' - 'behaving similar to those for Python’s standard dictionary ' + 'Containers usually are *sequences* (such as "lists" or ' + '"tuples") or\n' + '*mappings* (like "dictionaries"), but can represent other ' + 'containers\n' + 'as well. The first set of methods is used either to emulate ' + 'a\n' + 'sequence or to emulate a mapping; the difference is that for ' + 'a\n' + 'sequence, the allowable keys should be the integers *k* for ' + 'which "0\n' + '<= k < N" where *N* is the length of the sequence, or ' + '"slice" objects,\n' + 'which define a range of items. It is also recommended that ' + 'mappings\n' + 'provide the methods "keys()", "values()", "items()", ' + '"get()",\n' + '"clear()", "setdefault()", "pop()", "popitem()", "copy()", ' + 'and\n' + '"update()" behaving similar to those for Python’s standard\n' + '"dictionary" objects. The "collections.abc" module provides ' + 'a\n' + '"MutableMapping" *abstract base class* to help create those ' + 'methods\n' + 'from a base set of "__getitem__()", "__setitem__()", ' + '"__delitem__()",\n' + 'and "keys()". Mutable sequences should provide methods ' + '"append()",\n' + '"count()", "index()", "extend()", "insert()", "pop()", ' + '"remove()",\n' + '"reverse()" and "sort()", like Python standard "list" ' 'objects.\n' - 'The "collections.abc" module provides a "MutableMapping" ' - 'abstract base\n' - 'class to help create those methods from a base set of ' - '"__getitem__()",\n' - '"__setitem__()", "__delitem__()", and "keys()". Mutable ' - 'sequences\n' - 'should provide methods "append()", "count()", "index()", ' - '"extend()",\n' - '"insert()", "pop()", "remove()", "reverse()" and "sort()", ' - 'like Python\n' - 'standard list objects. Finally, sequence types should ' - 'implement\n' - 'addition (meaning concatenation) and multiplication ' - '(meaning\n' - 'repetition) by defining the methods "__add__()", ' - '"__radd__()",\n' - '"__iadd__()", "__mul__()", "__rmul__()" and "__imul__()" ' - 'described\n' - 'below; they should not define other numerical operators. It ' - 'is\n' - 'recommended that both mappings and sequences implement the\n' - '"__contains__()" method to allow efficient use of the "in" ' - 'operator;\n' - 'for mappings, "in" should search the mapping’s keys; for ' - 'sequences, it\n' - 'should search through the values. It is further recommended ' - 'that both\n' - 'mappings and sequences implement the "__iter__()" method to ' - 'allow\n' - 'efficient iteration through the container; for mappings, ' - '"__iter__()"\n' - 'should iterate through the object’s keys; for sequences, it ' - 'should\n' - 'iterate through the values.\n' + 'Finally, sequence types should implement addition (meaning\n' + 'concatenation) and multiplication (meaning repetition) by ' + 'defining the\n' + 'methods "__add__()", "__radd__()", "__iadd__()", ' + '"__mul__()",\n' + '"__rmul__()" and "__imul__()" described below; they should ' + 'not define\n' + 'other numerical operators. It is recommended that both ' + 'mappings and\n' + 'sequences implement the "__contains__()" method to allow ' + 'efficient use\n' + 'of the "in" operator; for mappings, "in" should search the ' + 'mapping’s\n' + 'keys; for sequences, it should search through the values. ' + 'It is\n' + 'further recommended that both mappings and sequences ' + 'implement the\n' + '"__iter__()" method to allow efficient iteration through ' + 'the\n' + 'container; for mappings, "__iter__()" should iterate through ' + 'the\n' + 'object’s keys; for sequences, it should iterate through the ' + 'values.\n' '\n' 'object.__len__(self)\n' '\n' @@ -10469,22 +10708,23 @@ topics = {'assert': 'The "assert" statement\n' 'object.__getitem__(self, key)\n' '\n' ' Called to implement evaluation of "self[key]". For ' - 'sequence types,\n' - ' the accepted keys should be integers and slice objects. ' - 'Note that\n' - ' the special interpretation of negative indexes (if the ' - 'class wishes\n' - ' to emulate a sequence type) is up to the "__getitem__()" ' - 'method. If\n' - ' *key* is of an inappropriate type, "TypeError" may be ' - 'raised; if of\n' - ' a value outside the set of indexes for the sequence ' - '(after any\n' - ' special interpretation of negative values), "IndexError" ' + '*sequence*\n' + ' types, the accepted keys should be integers and slice ' + 'objects.\n' + ' Note that the special interpretation of negative indexes ' + '(if the\n' + ' class wishes to emulate a *sequence* type) is up to the\n' + ' "__getitem__()" method. If *key* is of an inappropriate ' + 'type,\n' + ' "TypeError" may be raised; if of a value outside the set ' + 'of indexes\n' + ' for the sequence (after any special interpretation of ' + 'negative\n' + ' values), "IndexError" should be raised. For *mapping* ' + 'types, if\n' + ' *key* is missing (not in the container), "KeyError" ' 'should be\n' - ' raised. For mapping types, if *key* is missing (not in ' - 'the\n' - ' container), "KeyError" should be raised.\n' + ' raised.\n' '\n' ' Note:\n' '\n' @@ -10494,6 +10734,14 @@ topics = {'assert': 'The "assert" statement\n' 'the\n' ' sequence.\n' '\n' + ' Note:\n' + '\n' + ' When subscripting a *class*, the special class method\n' + ' "__class_getitem__()" may be called instead of ' + '"__getitem__()".\n' + ' See __class_getitem__ versus __getitem__ for more ' + 'details.\n' + '\n' 'object.__setitem__(self, key, value)\n' '\n' ' Called to implement assignment to "self[key]". Same note ' @@ -10529,19 +10777,13 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'object.__iter__(self)\n' '\n' - ' This method is called when an iterator is required for a ' - 'container.\n' - ' This method should return a new iterator object that can ' - 'iterate\n' - ' over all the objects in the container. For mappings, it ' - 'should\n' - ' iterate over the keys of the container.\n' - '\n' - ' Iterator objects also need to implement this method; they ' - 'are\n' - ' required to return themselves. For more information on ' - 'iterator\n' - ' objects, see Iterator Types.\n' + ' This method is called when an *iterator* is required for ' + 'a\n' + ' container. This method should return a new iterator ' + 'object that can\n' + ' iterate over all the objects in the container. For ' + 'mappings, it\n' + ' should iterate over the keys of the container.\n' '\n' 'object.__reversed__(self)\n' '\n' @@ -10788,6 +11030,10 @@ topics = {'assert': 'The "assert" statement\n' 'if\n' ' neither "__int__()" nor "__index__()" is defined.\n' '\n' + ' Changed in version 3.11: The delegation of "int()" to ' + '"__trunc__()"\n' + ' is deprecated.\n' + '\n' '\n' 'With Statement Context Managers\n' '===============================\n' @@ -10861,8 +11107,9 @@ topics = {'assert': 'The "assert" statement\n' 'y)" is\n' 'typically invalid without special support in "MyClass". To ' 'be able to\n' - 'use that kind of patterns, the class needs to define a\n' - '*__match_args__* attribute.\n' + 'use that kind of pattern, the class needs to define a ' + '*__match_args__*\n' + 'attribute.\n' '\n' 'object.__match_args__\n' '\n' @@ -11067,37 +11314,41 @@ topics = {'assert': 'The "assert" statement\n' '*start* and\n' ' *end* are interpreted as in slice notation.\n' '\n' + ' If *sub* is empty, returns the number of empty strings ' + 'between\n' + ' characters which is the length of the string plus one.\n' + '\n' "str.encode(encoding='utf-8', errors='strict')\n" '\n' - ' Return an encoded version of the string as a bytes ' - 'object. Default\n' - ' encoding is "\'utf-8\'". *errors* may be given to set a ' - 'different\n' - ' error handling scheme. The default for *errors* is ' - '"\'strict\'",\n' - ' meaning that encoding errors raise a "UnicodeError". ' + ' Return the string encoded to "bytes".\n' + '\n' + ' *encoding* defaults to "\'utf-8\'"; see Standard ' + 'Encodings for\n' + ' possible values.\n' + '\n' + ' *errors* controls how encoding errors are handled. If ' + '"\'strict\'"\n' + ' (the default), a "UnicodeError" exception is raised. ' 'Other possible\n' ' values are "\'ignore\'", "\'replace\'", ' '"\'xmlcharrefreplace\'",\n' ' "\'backslashreplace\'" and any other name registered ' 'via\n' - ' "codecs.register_error()", see section Error Handlers. ' - 'For a list\n' - ' of possible encodings, see section Standard Encodings.\n' + ' "codecs.register_error()". See Error Handlers for ' + 'details.\n' '\n' - ' By default, the *errors* argument is not checked for ' - 'best\n' - ' performances, but only used at the first encoding ' - 'error. Enable the\n' - ' Python Development Mode, or use a debug build to check ' - '*errors*.\n' + ' For performance reasons, the value of *errors* is not ' + 'checked for\n' + ' validity unless an encoding error actually occurs, ' + 'Python\n' + ' Development Mode is enabled or a debug build is used.\n' '\n' - ' Changed in version 3.1: Support for keyword arguments ' - 'added.\n' + ' Changed in version 3.1: Added support for keyword ' + 'arguments.\n' '\n' - ' Changed in version 3.9: The *errors* is now checked in ' - 'development\n' - ' mode and in debug mode.\n' + ' Changed in version 3.9: The value of the *errors* ' + 'argument is now\n' + ' checked in Python Development Mode and in debug mode.\n' '\n' 'str.endswith(suffix[, start[, end]])\n' '\n' @@ -11258,7 +11509,7 @@ topics = {'assert': 'The "assert" statement\n' 'property\n' ' being one of “Lmâ€, “Ltâ€, “Luâ€, “Llâ€, or “Loâ€. Note ' 'that this is\n' - ' different from the “Alphabetic†property defined in the ' + ' different from the Alphabetic property defined in the ' 'Unicode\n' ' Standard.\n' '\n' @@ -11307,18 +11558,18 @@ topics = {'assert': 'The "assert" statement\n' 'according to the\n' ' language definition, section Identifiers and keywords.\n' '\n' - ' Call "keyword.iskeyword()" to test whether string "s" ' - 'is a reserved\n' - ' identifier, such as "def" and "class".\n' + ' "keyword.iskeyword()" can be used to test whether ' + 'string "s" is a\n' + ' reserved identifier, such as "def" and "class".\n' '\n' ' Example:\n' '\n' ' >>> from keyword import iskeyword\n' '\n' " >>> 'hello'.isidentifier(), iskeyword('hello')\n" - ' True, False\n' + ' (True, False)\n' " >>> 'def'.isidentifier(), iskeyword('def')\n" - ' True, True\n' + ' (True, True)\n' '\n' 'str.islower()\n' '\n' @@ -11669,7 +11920,7 @@ topics = {'assert': 'The "assert" statement\n' " >>> ' 1 2 3 '.split()\n" " ['1', '2', '3']\n" '\n' - 'str.splitlines([keepends])\n' + 'str.splitlines(keepends=False)\n' '\n' ' Return a list of the lines in the string, breaking at ' 'line\n' @@ -11841,9 +12092,13 @@ topics = {'assert': 'The "assert" statement\n' ' >>> "they\'re bill\'s friends from the UK".title()\n' ' "They\'Re Bill\'S Friends From The Uk"\n' '\n' - ' A workaround for apostrophes can be constructed using ' - 'regular\n' - ' expressions:\n' + ' The "string.capwords()" function does not have this ' + 'problem, as it\n' + ' splits words on spaces only.\n' + '\n' + ' Alternatively, a workaround for apostrophes can be ' + 'constructed\n' + ' using regular expressions:\n' '\n' ' >>> import re\n' ' >>> def titlecase(s):\n' @@ -11965,12 +12220,15 @@ topics = {'assert': 'The "assert" statement\n' 'single quotes ("\'") or double quotes ("""). They can also be ' 'enclosed\n' 'in matching groups of three single or double quotes (these are\n' - 'generally referred to as *triple-quoted strings*). The ' - 'backslash\n' - '("\\") character is used to escape characters that otherwise have ' - 'a\n' - 'special meaning, such as newline, backslash itself, or the quote\n' + 'generally referred to as *triple-quoted strings*). The backslash ' + '("\\")\n' + 'character is used to give special meaning to otherwise ordinary\n' + 'characters like "n", which means ‘newline’ when escaped ("\\n"). ' + 'It can\n' + 'also be used to escape characters that otherwise have a special\n' + 'meaning, such as newline, backslash itself, or the quote ' 'character.\n' + 'See escape sequences below for examples.\n' '\n' 'Bytes literals are always prefixed with "\'b\'" or "\'B\'"; they ' 'produce\n' @@ -12027,8 +12285,8 @@ topics = {'assert': 'The "assert" statement\n' '| Escape Sequence | Meaning | Notes ' '|\n' '|===================|===================================|=========|\n' - '| "\\newline" | Backslash and newline ignored ' - '| |\n' + '| "\\" | Backslash and newline ignored | ' + '(1) |\n' '+-------------------+-----------------------------------+---------+\n' '| "\\\\" | Backslash ("\\") ' '| |\n' @@ -12061,10 +12319,10 @@ topics = {'assert': 'The "assert" statement\n' '| |\n' '+-------------------+-----------------------------------+---------+\n' '| "\\ooo" | Character with octal value *ooo* | ' - '(1,3) |\n' + '(2,4) |\n' '+-------------------+-----------------------------------+---------+\n' '| "\\xhh" | Character with hex value *hh* | ' - '(2,3) |\n' + '(3,4) |\n' '+-------------------+-----------------------------------+---------+\n' '\n' 'Escape sequences only recognized in string literals are:\n' @@ -12074,39 +12332,59 @@ topics = {'assert': 'The "assert" statement\n' '|\n' '|===================|===================================|=========|\n' '| "\\N{name}" | Character named *name* in the | ' - '(4) |\n' + '(5) |\n' '| | Unicode database | ' '|\n' '+-------------------+-----------------------------------+---------+\n' '| "\\uxxxx" | Character with 16-bit hex value | ' - '(5) |\n' + '(6) |\n' '| | *xxxx* | ' '|\n' '+-------------------+-----------------------------------+---------+\n' '| "\\Uxxxxxxxx" | Character with 32-bit hex value | ' - '(6) |\n' + '(7) |\n' '| | *xxxxxxxx* | ' '|\n' '+-------------------+-----------------------------------+---------+\n' '\n' 'Notes:\n' '\n' - '1. As in Standard C, up to three octal digits are accepted.\n' + '1. A backslash can be added at the end of a line to ignore the\n' + ' newline:\n' '\n' - '2. Unlike in Standard C, exactly two hex digits are required.\n' + " >>> 'This string will not include \\\n" + " ... backslashes or newline characters.'\n" + " 'This string will not include backslashes or newline " + "characters.'\n" '\n' - '3. In a bytes literal, hexadecimal and octal escapes denote the ' + ' The same result can be achieved using triple-quoted strings, ' + 'or\n' + ' parentheses and string literal concatenation.\n' + '\n' + '2. As in Standard C, up to three octal digits are accepted.\n' + '\n' + ' Changed in version 3.11: Octal escapes with value larger than\n' + ' "0o377" produce a "DeprecationWarning".\n' + '\n' + ' Changed in version 3.12: Octal escapes with value larger than\n' + ' "0o377" produce a "SyntaxWarning". In a future Python version ' + 'they\n' + ' will be eventually a "SyntaxError".\n' + '\n' + '3. Unlike in Standard C, exactly two hex digits are required.\n' + '\n' + '4. In a bytes literal, hexadecimal and octal escapes denote the ' 'byte\n' ' with the given value. In a string literal, these escapes ' 'denote a\n' ' Unicode character with the given value.\n' '\n' - '4. Changed in version 3.3: Support for name aliases [1] has been\n' + '5. Changed in version 3.3: Support for name aliases [1] has been\n' ' added.\n' '\n' - '5. Exactly four hex digits are required.\n' + '6. Exactly four hex digits are required.\n' '\n' - '6. Any Unicode character can be encoded this way. Exactly eight ' + '7. Any Unicode character can be encoded this way. Exactly eight ' 'hex\n' ' digits are required.\n' '\n' @@ -12126,9 +12404,13 @@ topics = {'assert': 'The "assert" statement\n' '\n' ' Changed in version 3.6: Unrecognized escape sequences produce ' 'a\n' - ' "DeprecationWarning". In a future Python version they will be ' + ' "DeprecationWarning".\n' + '\n' + ' Changed in version 3.12: Unrecognized escape sequences produce ' 'a\n' - ' "SyntaxWarning" and eventually a "SyntaxError".\n' + ' "SyntaxWarning". In a future Python version they will be ' + 'eventually\n' + ' a "SyntaxError".\n' '\n' 'Even in a raw literal, quotes can be escaped with a backslash, ' 'but the\n' @@ -12150,67 +12432,86 @@ topics = {'assert': 'The "assert" statement\n' 'subscriptions': 'Subscriptions\n' '*************\n' '\n' - 'Subscription of a sequence (string, tuple or list) or ' - 'mapping\n' - '(dictionary) object usually selects an item from the ' - 'collection:\n' + 'The subscription of an instance of a container class will ' + 'generally\n' + 'select an element from the container. The subscription of a ' + '*generic\n' + 'class* will generally return a GenericAlias object.\n' '\n' ' subscription ::= primary "[" expression_list "]"\n' '\n' + 'When an object is subscripted, the interpreter will ' + 'evaluate the\n' + 'primary and the expression list.\n' + '\n' 'The primary must evaluate to an object that supports ' - 'subscription\n' - '(lists or dictionaries for example). User-defined objects ' - 'can support\n' - 'subscription by defining a "__getitem__()" method.\n' + 'subscription. An\n' + 'object may support subscription through defining one or ' + 'both of\n' + '"__getitem__()" and "__class_getitem__()". When the primary ' + 'is\n' + 'subscripted, the evaluated result of the expression list ' + 'will be\n' + 'passed to one of these methods. For more details on when\n' + '"__class_getitem__" is called instead of "__getitem__", ' + 'see\n' + '__class_getitem__ versus __getitem__.\n' + '\n' + 'If the expression list contains at least one comma, it will ' + 'evaluate\n' + 'to a "tuple" containing the items of the expression list. ' + 'Otherwise,\n' + 'the expression list will evaluate to the value of the ' + 'list’s sole\n' + 'member.\n' '\n' 'For built-in objects, there are two types of objects that ' 'support\n' - 'subscription:\n' + 'subscription via "__getitem__()":\n' '\n' - 'If the primary is a mapping, the expression list must ' - 'evaluate to an\n' - 'object whose value is one of the keys of the mapping, and ' + '1. Mappings. If the primary is a *mapping*, the expression ' + 'list must\n' + ' evaluate to an object whose value is one of the keys of ' 'the\n' - 'subscription selects the value in the mapping that ' - 'corresponds to that\n' - 'key. (The expression list is a tuple except if it has ' - 'exactly one\n' - 'item.)\n' + ' mapping, and the subscription selects the value in the ' + 'mapping that\n' + ' corresponds to that key. An example of a builtin mapping ' + 'class is\n' + ' the "dict" class.\n' '\n' - 'If the primary is a sequence, the expression list must ' - 'evaluate to an\n' - 'integer or a slice (as discussed in the following ' - 'section).\n' + '2. Sequences. If the primary is a *sequence*, the ' + 'expression list must\n' + ' evaluate to an "int" or a "slice" (as discussed in the ' + 'following\n' + ' section). Examples of builtin sequence classes include ' + 'the "str",\n' + ' "list" and "tuple" classes.\n' '\n' 'The formal syntax makes no special provision for negative ' 'indices in\n' - 'sequences; however, built-in sequences all provide a ' + '*sequences*. However, built-in sequences all provide a ' '"__getitem__()"\n' 'method that interprets negative indices by adding the ' 'length of the\n' - 'sequence to the index (so that "x[-1]" selects the last ' - 'item of "x").\n' - 'The resulting value must be a nonnegative integer less than ' - 'the number\n' - 'of items in the sequence, and the subscription selects the ' - 'item whose\n' - 'index is that value (counting from zero). Since the support ' - 'for\n' - 'negative indices and slicing occurs in the object’s ' - '"__getitem__()"\n' - 'method, subclasses overriding this method will need to ' - 'explicitly add\n' - 'that support.\n' + 'sequence to the index so that, for example, "x[-1]" selects ' + 'the last\n' + 'item of "x". The resulting value must be a nonnegative ' + 'integer less\n' + 'than the number of items in the sequence, and the ' + 'subscription selects\n' + 'the item whose index is that value (counting from zero). ' + 'Since the\n' + 'support for negative indices and slicing occurs in the ' + 'object’s\n' + '"__getitem__()" method, subclasses overriding this method ' + 'will need to\n' + 'explicitly add that support.\n' '\n' - 'A string’s items are characters. A character is not a ' - 'separate data\n' - 'type but a string of exactly one character.\n' - '\n' - 'Subscription of certain *classes* or *types* creates a ' - 'generic alias.\n' - 'In this case, user-defined classes can support subscription ' - 'by\n' - 'providing a "__class_getitem__()" classmethod.\n', + 'A "string" is a special kind of sequence whose items are ' + '*characters*.\n' + 'A character is not a separate data type but a string of ' + 'exactly one\n' + 'character.\n', 'truth': 'Truth Value Testing\n' '*******************\n' '\n' @@ -12244,40 +12545,53 @@ topics = {'assert': 'The "assert" statement\n' 'The "try" statement specifies exception handlers and/or cleanup code\n' 'for a group of statements:\n' '\n' - ' try_stmt ::= try1_stmt | try2_stmt\n' + ' try_stmt ::= try1_stmt | try2_stmt | try3_stmt\n' ' try1_stmt ::= "try" ":" suite\n' ' ("except" [expression ["as" identifier]] ":" ' 'suite)+\n' ' ["else" ":" suite]\n' ' ["finally" ":" suite]\n' ' try2_stmt ::= "try" ":" suite\n' + ' ("except" "*" expression ["as" identifier] ":" ' + 'suite)+\n' + ' ["else" ":" suite]\n' + ' ["finally" ":" suite]\n' + ' try3_stmt ::= "try" ":" suite\n' ' "finally" ":" suite\n' '\n' + 'Additional information on exceptions can be found in section\n' + 'Exceptions, and information on using the "raise" statement to ' + 'generate\n' + 'exceptions may be found in section The raise statement.\n' + '\n' + '\n' + '"except" clause\n' + '===============\n' + '\n' 'The "except" clause(s) specify one or more exception handlers. When ' 'no\n' 'exception occurs in the "try" clause, no exception handler is\n' 'executed. When an exception occurs in the "try" suite, a search for ' 'an\n' - 'exception handler is started. This search inspects the except ' - 'clauses\n' - 'in turn until one is found that matches the exception. An ' - 'expression-\n' - 'less except clause, if present, must be last; it matches any\n' - 'exception. For an except clause with an expression, that expression\n' - 'is evaluated, and the clause matches the exception if the resulting\n' - 'object is “compatible†with the exception. An object is compatible\n' - 'with an exception if the object is the class or a base class of the\n' - 'exception object, or a tuple containing an item that is the class or ' - 'a\n' - 'base class of the exception object.\n' + 'exception handler is started. This search inspects the "except"\n' + 'clauses in turn until one is found that matches the exception. An\n' + 'expression-less "except" clause, if present, must be last; it ' + 'matches\n' + 'any exception. For an "except" clause with an expression, that\n' + 'expression is evaluated, and the clause matches the exception if the\n' + 'resulting object is “compatible†with the exception. An object is\n' + 'compatible with an exception if the object is the class or a *non-\n' + 'virtual base class* of the exception object, or a tuple containing ' + 'an\n' + 'item that is the class or a non-virtual base class of the exception\n' + 'object.\n' '\n' - 'If no except clause matches the exception, the search for an ' - 'exception\n' - 'handler continues in the surrounding code and on the invocation ' - 'stack.\n' - '[1]\n' + 'If no "except" clause matches the exception, the search for an\n' + 'exception handler continues in the surrounding code and on the\n' + 'invocation stack. [1]\n' '\n' - 'If the evaluation of an expression in the header of an except clause\n' + 'If the evaluation of an expression in the header of an "except" ' + 'clause\n' 'raises an exception, the original search for a handler is canceled ' 'and\n' 'a search starts for the new exception in the surrounding code and on\n' @@ -12285,21 +12599,20 @@ topics = {'assert': 'The "assert" statement\n' 'raised\n' 'the exception).\n' '\n' - 'When a matching except clause is found, the exception is assigned to\n' - 'the target specified after the "as" keyword in that except clause, ' - 'if\n' - 'present, and the except clause’s suite is executed. All except\n' - 'clauses must have an executable block. When the end of this block ' - 'is\n' - 'reached, execution continues normally after the entire try ' - 'statement.\n' - '(This means that if two nested handlers exist for the same ' - 'exception,\n' - 'and the exception occurs in the try clause of the inner handler, the\n' - 'outer handler will not handle the exception.)\n' + 'When a matching "except" clause is found, the exception is assigned ' + 'to\n' + 'the target specified after the "as" keyword in that "except" clause,\n' + 'if present, and the "except" clause’s suite is executed. All ' + '"except"\n' + 'clauses must have an executable block. When the end of this block is\n' + 'reached, execution continues normally after the entire "try"\n' + 'statement. (This means that if two nested handlers exist for the ' + 'same\n' + 'exception, and the exception occurs in the "try" clause of the inner\n' + 'handler, the outer handler will not handle the exception.)\n' '\n' 'When an exception has been assigned using "as target", it is cleared\n' - 'at the end of the except clause. This is as if\n' + 'at the end of the "except" clause. This is as if\n' '\n' ' except E as N:\n' ' foo\n' @@ -12313,12 +12626,13 @@ topics = {'assert': 'The "assert" statement\n' ' del N\n' '\n' 'This means the exception must be assigned to a different name to be\n' - 'able to refer to it after the except clause. Exceptions are cleared\n' + 'able to refer to it after the "except" clause. Exceptions are ' + 'cleared\n' 'because with the traceback attached to them, they form a reference\n' 'cycle with the stack frame, keeping all locals in that frame alive\n' 'until the next garbage collection occurs.\n' '\n' - 'Before an except clause’s suite is executed, details about the\n' + 'Before an "except" clause’s suite is executed, details about the\n' 'exception are stored in the "sys" module and can be accessed via\n' '"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting of ' 'the\n' @@ -12350,6 +12664,71 @@ topics = {'assert': 'The "assert" statement\n' ' >>> print(sys.exc_info())\n' ' (None, None, None)\n' '\n' + '\n' + '"except*" clause\n' + '================\n' + '\n' + 'The "except*" clause(s) are used for handling "ExceptionGroup"s. The\n' + 'exception type for matching is interpreted as in the case of ' + '"except",\n' + 'but in the case of exception groups we can have partial matches when\n' + 'the type matches some of the exceptions in the group. This means ' + 'that\n' + 'multiple "except*" clauses can execute, each handling part of the\n' + 'exception group. Each clause executes at most once and handles an\n' + 'exception group of all matching exceptions. Each exception in the\n' + 'group is handled by at most one "except*" clause, the first that\n' + 'matches it.\n' + '\n' + ' >>> try:\n' + ' ... raise ExceptionGroup("eg",\n' + ' ... [ValueError(1), TypeError(2), OSError(3), ' + 'OSError(4)])\n' + ' ... except* TypeError as e:\n' + " ... print(f'caught {type(e)} with nested {e.exceptions}')\n" + ' ... except* OSError as e:\n' + " ... print(f'caught {type(e)} with nested {e.exceptions}')\n" + ' ...\n' + " caught with nested (TypeError(2),)\n" + " caught with nested (OSError(3), " + 'OSError(4))\n' + ' + Exception Group Traceback (most recent call last):\n' + ' | File "", line 2, in \n' + ' | ExceptionGroup: eg\n' + ' +-+---------------- 1 ----------------\n' + ' | ValueError: 1\n' + ' +------------------------------------\n' + '\n' + 'Any remaining exceptions that were not handled by any "except*" ' + 'clause\n' + 'are re-raised at the end, combined into an exception group along ' + 'with\n' + 'all exceptions that were raised from within "except*" clauses.\n' + '\n' + 'If the raised exception is not an exception group and its type ' + 'matches\n' + 'one of the "except*" clauses, it is caught and wrapped by an ' + 'exception\n' + 'group with an empty message string.\n' + '\n' + ' >>> try:\n' + ' ... raise BlockingIOError\n' + ' ... except* BlockingIOError as e:\n' + ' ... print(repr(e))\n' + ' ...\n' + " ExceptionGroup('', (BlockingIOError()))\n" + '\n' + 'An "except*" clause must have a matching type, and this type cannot ' + 'be\n' + 'a subclass of "BaseExceptionGroup". It is not possible to mix ' + '"except"\n' + 'and "except*" in the same "try". "break", "continue" and "return"\n' + 'cannot appear in an "except*" clause.\n' + '\n' + '\n' + '"else" clause\n' + '=============\n' + '\n' 'The optional "else" clause is executed if the control flow leaves ' 'the\n' '"try" suite, no exception was raised, and no "return", "continue", ' @@ -12357,6 +12736,10 @@ topics = {'assert': 'The "assert" statement\n' '"break" statement was executed. Exceptions in the "else" clause are\n' 'not handled by the preceding "except" clauses.\n' '\n' + '\n' + '"finally" clause\n' + '================\n' + '\n' 'If "finally" is present, it specifies a ‘cleanup’ handler. The ' '"try"\n' 'clause is executed, including any "except" and "else" clauses. If ' @@ -12404,11 +12787,6 @@ topics = {'assert': 'The "assert" statement\n' ' >>> foo()\n' " 'finally'\n" '\n' - 'Additional information on exceptions can be found in section\n' - 'Exceptions, and information on using the "raise" statement to ' - 'generate\n' - 'exceptions may be found in section The raise statement.\n' - '\n' 'Changed in version 3.8: Prior to Python 3.8, a "continue" statement\n' 'was illegal in the "finally" clause due to a problem with the\n' 'implementation.\n', @@ -12608,7 +12986,7 @@ topics = {'assert': 'The "assert" statement\n' ' points. All the code points in the range "U+0000 - ' 'U+10FFFF"\n' ' can be represented in a string. Python doesn’t have a ' - '*char*\n' + 'char\n' ' type; instead, every code point in the string is ' 'represented\n' ' as a string object with length "1". The built-in ' @@ -12995,20 +13373,18 @@ topics = {'assert': 'The "assert" statement\n' ' A function or method which uses the "yield" statement (see\n' ' section The yield statement) is called a *generator ' 'function*.\n' - ' Such a function, when called, always returns an iterator ' - 'object\n' - ' which can be used to execute the body of the function: ' - 'calling\n' - ' the iterator’s "iterator.__next__()" method will cause the\n' - ' function to execute until it provides a value using the ' - '"yield"\n' - ' statement. When the function executes a "return" statement ' - 'or\n' - ' falls off the end, a "StopIteration" exception is raised and ' - 'the\n' - ' iterator will have reached the end of the set of values to ' - 'be\n' - ' returned.\n' + ' Such a function, when called, always returns an *iterator*\n' + ' object which can be used to execute the body of the ' + 'function:\n' + ' calling the iterator’s "iterator.__next__()" method will ' + 'cause\n' + ' the function to execute until it provides a value using the\n' + ' "yield" statement. When the function executes a "return"\n' + ' statement or falls off the end, a "StopIteration" exception ' + 'is\n' + ' raised and the iterator will have reached the end of the set ' + 'of\n' + ' values to be returned.\n' '\n' ' Coroutine functions\n' ' A function or method which is defined using "async def" is\n' @@ -13024,18 +13400,18 @@ topics = {'assert': 'The "assert" statement\n' ' which uses the "yield" statement is called a *asynchronous\n' ' generator function*. Such a function, when called, returns ' 'an\n' - ' asynchronous iterator object which can be used in an "async ' - 'for"\n' - ' statement to execute the body of the function.\n' + ' *asynchronous iterator* object which can be used in an ' + '"async\n' + ' for" statement to execute the body of the function.\n' '\n' - ' Calling the asynchronous iterator’s "aiterator.__anext__()"\n' - ' method will return an *awaitable* which when awaited will\n' - ' execute until it provides a value using the "yield" ' - 'expression.\n' - ' When the function executes an empty "return" statement or ' - 'falls\n' - ' off the end, a "StopAsyncIteration" exception is raised and ' + ' Calling the asynchronous iterator’s "aiterator.__anext__" ' + 'method\n' + ' will return an *awaitable* which when awaited will execute ' + 'until\n' + ' it provides a value using the "yield" expression. When the\n' + ' function executes an empty "return" statement or falls off ' 'the\n' + ' end, a "StopAsyncIteration" exception is raised and the\n' ' asynchronous iterator will have reached the end of the set ' 'of\n' ' values to be yielded.\n' @@ -13608,29 +13984,15 @@ topics = {'assert': 'The "assert" statement\n' 'dictionaries or\n' 'other mutable types (that are compared by value rather than ' 'by object\n' - 'identity) may not be used as keys. Numeric types used for ' - 'keys obey\n' - 'the normal rules for numeric comparison: if two numbers ' - 'compare equal\n' - '(such as "1" and "1.0") then they can be used ' - 'interchangeably to index\n' - 'the same dictionary entry. (Note however, that since ' - 'computers store\n' - 'floating-point numbers as approximations it is usually ' - 'unwise to use\n' - 'them as dictionary keys.)\n' + 'identity) may not be used as keys. Values that compare equal ' + '(such as\n' + '"1", "1.0", and "True") can be used interchangeably to index ' + 'the same\n' + 'dictionary entry.\n' '\n' - 'Dictionaries can be created by placing a comma-separated ' - 'list of "key:\n' - 'value" pairs within braces, for example: "{\'jack\': 4098, ' - "'sjoerd':\n" - '4127}" or "{4098: \'jack\', 4127: \'sjoerd\'}", or by the ' - '"dict"\n' - 'constructor.\n' - '\n' - 'class dict(**kwarg)\n' - 'class dict(mapping, **kwarg)\n' - 'class dict(iterable, **kwarg)\n' + 'class dict(**kwargs)\n' + 'class dict(mapping, **kwargs)\n' + 'class dict(iterable, **kwargs)\n' '\n' ' Return a new dictionary initialized from an optional ' 'positional\n' @@ -13735,6 +14097,7 @@ topics = {'assert': 'The "assert" statement\n' ' >>> class Counter(dict):\n' ' ... def __missing__(self, key):\n' ' ... return 0\n' + ' ...\n' ' >>> c = Counter()\n' " >>> c['red']\n" ' 0\n' @@ -14044,7 +14407,11 @@ topics = {'assert': 'The "assert" statement\n' 'abstract\n' 'base class "collections.abc.Set" are available (for example, ' '"==",\n' - '"<", or "^").\n' + '"<", or "^"). While using set operators, set-like views ' + 'accept any\n' + 'iterable as the other operand, unlike sets which only accept ' + 'sets as\n' + 'the input.\n' '\n' 'An example of dictionary view usage:\n' '\n' @@ -14057,6 +14424,7 @@ topics = {'assert': 'The "assert" statement\n' ' >>> n = 0\n' ' >>> for val in values:\n' ' ... n += val\n' + ' ...\n' ' >>> print(n)\n' ' 504\n' '\n' @@ -14078,12 +14446,13 @@ topics = {'assert': 'The "assert" statement\n' " {'bacon'}\n" " >>> keys ^ {'sausage', 'juice'}\n" " {'juice', 'sausage', 'bacon', 'spam'}\n" + " >>> keys | ['juice', 'juice', 'juice']\n" + " {'juice', 'sausage', 'bacon', 'spam', 'eggs'}\n" '\n' ' >>> # get back a read-only proxy for the original ' 'dictionary\n' ' >>> values.mapping\n' - " mappingproxy({'eggs': 2, 'sausage': 1, 'bacon': 1, " - "'spam': 500})\n" + " mappingproxy({'bacon': 1, 'spam': 500})\n" " >>> values.mapping['spam']\n" ' 500\n', 'typesmethods': 'Methods\n' @@ -14280,6 +14649,14 @@ topics = {'assert': 'The "assert" statement\n' 'Comparisons in\n' 'the language reference.)\n' '\n' + 'Forward and reversed iterators over mutable sequences access ' + 'values\n' + 'using an index. That index will continue to march forward (or\n' + 'backward) even if the underlying sequence is mutated. The ' + 'iterator\n' + 'terminates only when an "IndexError" or a "StopIteration" is\n' + 'encountered (or when the index drops below zero).\n' + '\n' 'Notes:\n' '\n' '1. While the "in" and "not in" operations are used only for ' @@ -14751,7 +15128,8 @@ topics = {'assert': 'The "assert" statement\n' '\n' ' The arguments to the range constructor must be integers ' '(either\n' - ' built-in "int" or any object that implements the "__index__"\n' + ' built-in "int" or any object that implements the ' + '"__index__()"\n' ' special method). If the *step* argument is omitted, it ' 'defaults to\n' ' "1". If the *start* argument is omitted, it defaults to "0". ' @@ -15120,7 +15498,7 @@ topics = {'assert': 'The "assert" statement\n' ' returns without an error, then "__exit__()" will always be\n' ' called. Thus, if an error occurs during the assignment to the\n' ' target list, it will be treated the same as an error occurring\n' - ' within the suite would be. See step 6 below.\n' + ' within the suite would be. See step 7 below.\n' '\n' '6. The suite is executed.\n' '\n' diff --git a/Lib/queue.py b/Lib/queue.py index 10dbcbc18ec..55f50088460 100644 --- a/Lib/queue.py +++ b/Lib/queue.py @@ -298,7 +298,7 @@ class _PySimpleQueue: def put_nowait(self, item): '''Put an item into the queue without blocking. - This is exactly equivalent to `put(item)` and is only provided + This is exactly equivalent to `put(item, block=False)` and is only provided for compatibility with the Queue class. ''' return self.put(item, block=False) diff --git a/Lib/quopri.py b/Lib/quopri.py index 08899c5cb73..f36cf7b3951 100755 --- a/Lib/quopri.py +++ b/Lib/quopri.py @@ -67,10 +67,7 @@ def encode(input, output, quotetabs, header=False): output.write(s + lineEnd) prevline = None - while 1: - line = input.readline() - if not line: - break + while line := input.readline(): outline = [] # Strip off any readline induced trailing newline stripped = b'' @@ -126,9 +123,7 @@ def decode(input, output, header=False): return new = b'' - while 1: - line = input.readline() - if not line: break + while line := input.readline(): i, n = 0, len(line) if n > 0 and line[n-1:n] == b'\n': partial = 0; n = n-1 diff --git a/Lib/random.py b/Lib/random.py index 92a71e14c48..3c4291f6a65 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -24,6 +24,7 @@ negative exponential gamma beta + binomial pareto Weibull @@ -49,8 +50,9 @@ from warnings import warn as _warn from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin from math import tau as TWOPI, floor as _floor, isfinite as _isfinite +from math import lgamma as _lgamma, fabs as _fabs, log2 as _log2 from os import urandom as _urandom -from _collections_abc import Set as _Set, Sequence as _Sequence +from _collections_abc import Sequence as _Sequence from operator import index as _index from itertools import accumulate as _accumulate, repeat as _repeat from bisect import bisect as _bisect @@ -68,6 +70,7 @@ __all__ = [ "Random", "SystemRandom", "betavariate", + "binomialvariate", "choice", "choices", "expovariate", @@ -233,19 +236,17 @@ class Random(_random.Random): break def _randbelow_with_getrandbits(self, n): - "Return a random int in the range [0,n). Returns 0 if n==0." + "Return a random int in the range [0,n). Defined for n > 0." - if not n: - return 0 getrandbits = self.getrandbits - k = n.bit_length() # don't use (n-1) here because n can be 1 + k = n.bit_length() r = getrandbits(k) # 0 <= r < 2**k while r >= n: r = getrandbits(k) return r def _randbelow_without_getrandbits(self, n, maxsize=1< 0. The implementation does not use getrandbits, but only random. """ @@ -256,8 +257,6 @@ class Random(_random.Random): "enough bits to choose from a population range this large.\n" "To remove the range limitation, add a getrandbits() method.") return _floor(random() * n) - if n == 0: - return 0 rem = maxsize % n limit = (maxsize - rem) / maxsize # int(limit * maxsize) % n == 0 r = random() @@ -288,9 +287,8 @@ class Random(_random.Random): def randrange(self, start, stop=None, step=_ONE): """Choose a random item from range(stop) or range(start, stop[, step]). - Roughly equivalent to ``choice(range(start, stop, step))`` - but supports arbitrarily large ranges and is optimized - for common cases. + Roughly equivalent to ``choice(range(start, stop, step))`` but + supports arbitrarily large ranges and is optimized for common cases. """ @@ -301,7 +299,7 @@ class Random(_random.Random): # We don't check for "step != 1" because it hasn't been # type checked and converted to an integer yet. if step is not _ONE: - raise TypeError('Missing a non-None stop argument') + raise TypeError("Missing a non-None stop argument") if istart > 0: return self._randbelow(istart) raise ValueError("empty range for randrange()") @@ -314,7 +312,7 @@ class Random(_random.Random): if istep == 1: if width > 0: return istart + self._randbelow(width) - raise ValueError(f"empty range in randrange({start}, {stop}, {step})") + raise ValueError(f"empty range in randrange({start}, {stop})") # Non-unit step argument supplied. if istep > 0: @@ -338,7 +336,11 @@ class Random(_random.Random): def choice(self, seq): """Choose a random element from a non-empty sequence.""" - # raises IndexError if seq is empty + + # As an accommodation for NumPy, we don't use "if not seq" + # because bool(numpy.array()) raises a ValueError. + if not len(seq): + raise IndexError('Cannot choose from an empty sequence') return seq[self._randbelow(len(seq))] def shuffle(self, x): @@ -509,7 +511,7 @@ class Random(_random.Random): low, high = high, low return low + (high - low) * _sqrt(u * c) - def normalvariate(self, mu, sigma): + def normalvariate(self, mu=0.0, sigma=1.0): """Normal distribution. mu is the mean, and sigma is the standard deviation. @@ -530,7 +532,7 @@ class Random(_random.Random): break return mu + z * sigma - def gauss(self, mu, sigma): + def gauss(self, mu=0.0, sigma=1.0): """Gaussian distribution. mu is the mean, and sigma is the standard deviation. This is @@ -578,7 +580,7 @@ class Random(_random.Random): """ return _exp(self.normalvariate(mu, sigma)) - def expovariate(self, lambd): + def expovariate(self, lambd=1.0): """Exponential distribution. lambd is 1.0 divided by the desired mean. It should be @@ -729,6 +731,91 @@ class Random(_random.Random): return y / (y + self.gammavariate(beta, 1.0)) return 0.0 + + def binomialvariate(self, n=1, p=0.5): + """Binomial random variable. + + Gives the number of successes for *n* independent trials + with the probability of success in each trial being *p*: + + sum(random() < p for i in range(n)) + + Returns an integer in the range: 0 <= X <= n + + """ + # Error check inputs and handle edge cases + if n < 0: + raise ValueError("n must be non-negative") + if p <= 0.0 or p >= 1.0: + if p == 0.0: + return 0 + if p == 1.0: + return n + raise ValueError("p must be in the range 0.0 <= p <= 1.0") + + random = self.random + + # Fast path for a common case + if n == 1: + return _index(random() < p) + + # Exploit symmetry to establish: p <= 0.5 + if p > 0.5: + return n - self.binomialvariate(n, 1.0 - p) + + if n * p < 10.0: + # BG: Geometric method by Devroye with running time of O(np). + # https://dl.acm.org/doi/pdf/10.1145/42372.42381 + x = y = 0 + c = _log2(1.0 - p) + if not c: + return x + while True: + y += _floor(_log2(random()) / c) + 1 + if y > n: + return x + x += 1 + + # BTRS: Transformed rejection with squeeze method by Wolfgang Hörmann + # https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.47.8407&rep=rep1&type=pdf + assert n*p >= 10.0 and p <= 0.5 + setup_complete = False + + spq = _sqrt(n * p * (1.0 - p)) # Standard deviation of the distribution + b = 1.15 + 2.53 * spq + a = -0.0873 + 0.0248 * b + 0.01 * p + c = n * p + 0.5 + vr = 0.92 - 4.2 / b + + while True: + + u = random() + u -= 0.5 + us = 0.5 - _fabs(u) + k = _floor((2.0 * a / us + b) * u + c) + if k < 0 or k > n: + continue + + # The early-out "squeeze" test substantially reduces + # the number of acceptance condition evaluations. + v = random() + if us >= 0.07 and v <= vr: + return k + + # Acceptance-rejection test. + # Note, the original paper errorneously omits the call to log(v) + # when comparing to the log of the rescaled binomial distribution. + if not setup_complete: + alpha = (2.83 + 5.1 / b) * spq + lpq = _log(p / (1.0 - p)) + m = _floor((n + 1) * p) # Mode of the distribution + h = _lgamma(m + 1) + _lgamma(n - m + 1) + setup_complete = True # Only needs to be done once + v *= alpha / (a / (us * us) + b) + if _log(v) <= h - _lgamma(k + 1) - _lgamma(n - k + 1) + (k - m) * lpq: + return k + + def paretovariate(self, alpha): """Pareto distribution. alpha is the shape parameter.""" # Jain, pg. 495 @@ -762,7 +849,7 @@ class SystemRandom(Random): """ def random(self): - """Get the next random number in the range [0.0, 1.0).""" + """Get the next random number in the range 0.0 <= X < 1.0.""" return (int.from_bytes(_urandom(7)) >> 3) * RECIP_BPF def getrandbits(self, k): @@ -814,6 +901,7 @@ vonmisesvariate = _inst.vonmisesvariate gammavariate = _inst.gammavariate gauss = _inst.gauss betavariate = _inst.betavariate +binomialvariate = _inst.binomialvariate paretovariate = _inst.paretovariate weibullvariate = _inst.weibullvariate getstate = _inst.getstate @@ -838,15 +926,17 @@ def _test_generator(n, func, args): low = min(data) high = max(data) - print(f'{t1 - t0:.3f} sec, {n} times {func.__name__}') + print(f'{t1 - t0:.3f} sec, {n} times {func.__name__}{args!r}') print('avg %g, stddev %g, min %g, max %g\n' % (xbar, sigma, low, high)) -def _test(N=2000): +def _test(N=10_000): _test_generator(N, random, ()) _test_generator(N, normalvariate, (0.0, 1.0)) _test_generator(N, lognormvariate, (0.0, 1.0)) _test_generator(N, vonmisesvariate, (0.0, 1.0)) + _test_generator(N, binomialvariate, (15, 0.60)) + _test_generator(N, binomialvariate, (100, 0.75)) _test_generator(N, gammavariate, (0.01, 1.0)) _test_generator(N, gammavariate, (0.1, 1.0)) _test_generator(N, gammavariate, (0.1, 2.0)) diff --git a/Lib/re.py b/Lib/re/__init__.py similarity index 77% rename from Lib/re.py rename to Lib/re/__init__.py index ea41217ce08..4515650a721 100644 --- a/Lib/re.py +++ b/Lib/re/__init__.py @@ -122,13 +122,9 @@ This module also defines an exception 'error'. """ import enum -import sre_compile -import sre_parse +from . import _compiler, _parser import functools -try: - import _locale -except ImportError: - _locale = None +import _sre # public symbols @@ -137,7 +133,7 @@ __all__ = [ "findall", "finditer", "compile", "purge", "template", "escape", "error", "Pattern", "Match", "A", "I", "L", "M", "S", "X", "U", "ASCII", "IGNORECASE", "LOCALE", "MULTILINE", "DOTALL", "VERBOSE", - "UNICODE", + "UNICODE", "NOFLAG", "RegexFlag", ] __version__ = "2.2.1" @@ -145,19 +141,22 @@ __version__ = "2.2.1" @enum.global_enum @enum._simple_enum(enum.IntFlag, boundary=enum.KEEP) class RegexFlag: - ASCII = A = sre_compile.SRE_FLAG_ASCII # assume ascii "locale" - IGNORECASE = I = sre_compile.SRE_FLAG_IGNORECASE # ignore case - LOCALE = L = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale - UNICODE = U = sre_compile.SRE_FLAG_UNICODE # assume unicode "locale" - MULTILINE = M = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline - DOTALL = S = sre_compile.SRE_FLAG_DOTALL # make dot match newline - VERBOSE = X = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments + NOFLAG = 0 + ASCII = A = _compiler.SRE_FLAG_ASCII # assume ascii "locale" + IGNORECASE = I = _compiler.SRE_FLAG_IGNORECASE # ignore case + LOCALE = L = _compiler.SRE_FLAG_LOCALE # assume current 8-bit locale + UNICODE = U = _compiler.SRE_FLAG_UNICODE # assume unicode "locale" + MULTILINE = M = _compiler.SRE_FLAG_MULTILINE # make anchors look for newline + DOTALL = S = _compiler.SRE_FLAG_DOTALL # make dot match newline + VERBOSE = X = _compiler.SRE_FLAG_VERBOSE # ignore whitespace and comments # sre extensions (experimental, don't rely on these) - TEMPLATE = T = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking - DEBUG = sre_compile.SRE_FLAG_DEBUG # dump pattern after compilation + TEMPLATE = T = _compiler.SRE_FLAG_TEMPLATE # unknown purpose, deprecated + DEBUG = _compiler.SRE_FLAG_DEBUG # dump pattern after compilation + __str__ = object.__str__ + _numeric_repr_ = hex # sre exception -error = sre_compile.error +error = _compiler.error # -------------------------------------------------------------------- # public interface @@ -231,11 +230,20 @@ def compile(pattern, flags=0): def purge(): "Clear the regular expression caches" _cache.clear() - _compile_repl.cache_clear() + _cache2.clear() + _compile_template.cache_clear() def template(pattern, flags=0): - "Compile a template pattern, returning a Pattern object" - return _compile(pattern, flags|T) + "Compile a template pattern, returning a Pattern object, deprecated" + import warnings + warnings.warn("The re.template() function is deprecated " + "as it is an undocumented function " + "without an obvious purpose. " + "Use re.compile() instead.", + DeprecationWarning) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) # warn just once + return _compile(pattern, flags|T) # SPECIAL_CHARS # closing ')', '}' and ']' @@ -254,60 +262,76 @@ def escape(pattern): pattern = str(pattern, 'latin1') return pattern.translate(_special_chars_map).encode('latin1') -Pattern = type(sre_compile.compile('', 0)) -Match = type(sre_compile.compile('', 0).match('')) +Pattern = type(_compiler.compile('', 0)) +Match = type(_compiler.compile('', 0).match('')) # -------------------------------------------------------------------- # internals -_cache = {} # ordered! - +# Use the fact that dict keeps the insertion order. +# _cache2 uses the simple FIFO policy which has better latency. +# _cache uses the LRU policy which has better hit rate. +_cache = {} # LRU +_cache2 = {} # FIFO _MAXCACHE = 512 +_MAXCACHE2 = 256 +assert _MAXCACHE2 < _MAXCACHE + def _compile(pattern, flags): # internal: compile pattern if isinstance(flags, RegexFlag): flags = flags.value try: - return _cache[type(pattern), pattern, flags] + return _cache2[type(pattern), pattern, flags] except KeyError: pass - if isinstance(pattern, Pattern): - if flags: - raise ValueError( - "cannot process flags argument with a compiled pattern") - return pattern - if not sre_compile.isstring(pattern): - raise TypeError("first argument must be string or compiled pattern") - p = sre_compile.compile(pattern, flags) - if not (flags & DEBUG): + + key = (type(pattern), pattern, flags) + # Item in _cache should be moved to the end if found. + p = _cache.pop(key, None) + if p is None: + if isinstance(pattern, Pattern): + if flags: + raise ValueError( + "cannot process flags argument with a compiled pattern") + return pattern + if not _compiler.isstring(pattern): + raise TypeError("first argument must be string or compiled pattern") + if flags & T: + import warnings + warnings.warn("The re.TEMPLATE/re.T flag is deprecated " + "as it is an undocumented flag " + "without an obvious purpose. " + "Don't use it.", + DeprecationWarning) + p = _compiler.compile(pattern, flags) + if flags & DEBUG: + return p if len(_cache) >= _MAXCACHE: - # Drop the oldest item + # Drop the least recently used item. + # next(iter(_cache)) is known to have linear amortized time, + # but it is used here to avoid a dependency from using OrderedDict. + # For the small _MAXCACHE value it doesn't make much of a difference. try: del _cache[next(iter(_cache))] except (StopIteration, RuntimeError, KeyError): pass - _cache[type(pattern), pattern, flags] = p + # Append to the end. + _cache[key] = p + + if len(_cache2) >= _MAXCACHE2: + # Drop the oldest item. + try: + del _cache2[next(iter(_cache2))] + except (StopIteration, RuntimeError, KeyError): + pass + _cache2[key] = p return p @functools.lru_cache(_MAXCACHE) -def _compile_repl(repl, pattern): +def _compile_template(pattern, repl): # internal: compile replacement pattern - return sre_parse.parse_template(repl, pattern) - -def _expand(pattern, match, template): - # internal: Match.expand implementation hook - template = sre_parse.parse_template(template, pattern) - return sre_parse.expand_template(template, match) - -def _subx(pattern, template): - # internal: Pattern.sub/subn implementation helper - template = _compile_repl(template, pattern) - if not template[0] and len(template[1]) == 1: - # literal replacement - return template[1][0] - def filter(match, template=template): - return sre_parse.expand_template(template, match) - return filter + return _sre.template(pattern, _parser.parse_template(repl, pattern)) # register myself for pickling @@ -323,22 +347,22 @@ copyreg.pickle(Pattern, _pickle, _compile) class Scanner: def __init__(self, lexicon, flags=0): - from sre_constants import BRANCH, SUBPATTERN + from ._constants import BRANCH, SUBPATTERN if isinstance(flags, RegexFlag): flags = flags.value self.lexicon = lexicon # combine phrases into a compound pattern p = [] - s = sre_parse.State() + s = _parser.State() s.flags = flags for phrase, action in lexicon: gid = s.opengroup() - p.append(sre_parse.SubPattern(s, [ - (SUBPATTERN, (gid, 0, 0, sre_parse.parse(phrase, flags))), + p.append(_parser.SubPattern(s, [ + (SUBPATTERN, (gid, 0, 0, _parser.parse(phrase, flags))), ])) s.closegroup(gid, p[-1]) - p = sre_parse.SubPattern(s, [(BRANCH, (None, p))]) - self.scanner = sre_compile.compile(p) + p = _parser.SubPattern(s, [(BRANCH, (None, p))]) + self.scanner = _compiler.compile(p) def scan(self, string): result = [] append = result.append diff --git a/Lib/re/_casefix.py b/Lib/re/_casefix.py new file mode 100644 index 00000000000..06507d08bee --- /dev/null +++ b/Lib/re/_casefix.py @@ -0,0 +1,106 @@ +# Auto-generated by Tools/scripts/generate_re_casefix.py. + +# Maps the code of lowercased character to codes of different lowercased +# characters which have the same uppercase. +_EXTRA_CASES = { + # LATIN SMALL LETTER I: LATIN SMALL LETTER DOTLESS I + 0x0069: (0x0131,), # 'i': 'ı' + # LATIN SMALL LETTER S: LATIN SMALL LETTER LONG S + 0x0073: (0x017f,), # 's': 'Å¿' + # MICRO SIGN: GREEK SMALL LETTER MU + 0x00b5: (0x03bc,), # 'µ': 'μ' + # LATIN SMALL LETTER DOTLESS I: LATIN SMALL LETTER I + 0x0131: (0x0069,), # 'ı': 'i' + # LATIN SMALL LETTER LONG S: LATIN SMALL LETTER S + 0x017f: (0x0073,), # 'Å¿': 's' + # COMBINING GREEK YPOGEGRAMMENI: GREEK SMALL LETTER IOTA, GREEK PROSGEGRAMMENI + 0x0345: (0x03b9, 0x1fbe), # '\u0345': 'ιι' + # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS: GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA + 0x0390: (0x1fd3,), # 'Î': 'á¿“' + # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS: GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA + 0x03b0: (0x1fe3,), # 'ΰ': 'á¿£' + # GREEK SMALL LETTER BETA: GREEK BETA SYMBOL + 0x03b2: (0x03d0,), # 'β': 'Ï' + # GREEK SMALL LETTER EPSILON: GREEK LUNATE EPSILON SYMBOL + 0x03b5: (0x03f5,), # 'ε': 'ϵ' + # GREEK SMALL LETTER THETA: GREEK THETA SYMBOL + 0x03b8: (0x03d1,), # 'θ': 'Ï‘' + # GREEK SMALL LETTER IOTA: COMBINING GREEK YPOGEGRAMMENI, GREEK PROSGEGRAMMENI + 0x03b9: (0x0345, 0x1fbe), # 'ι': '\u0345á¾¾' + # GREEK SMALL LETTER KAPPA: GREEK KAPPA SYMBOL + 0x03ba: (0x03f0,), # 'κ': 'ϰ' + # GREEK SMALL LETTER MU: MICRO SIGN + 0x03bc: (0x00b5,), # 'μ': 'µ' + # GREEK SMALL LETTER PI: GREEK PI SYMBOL + 0x03c0: (0x03d6,), # 'Ï€': 'Ï–' + # GREEK SMALL LETTER RHO: GREEK RHO SYMBOL + 0x03c1: (0x03f1,), # 'Ï': 'ϱ' + # GREEK SMALL LETTER FINAL SIGMA: GREEK SMALL LETTER SIGMA + 0x03c2: (0x03c3,), # 'Ï‚': 'σ' + # GREEK SMALL LETTER SIGMA: GREEK SMALL LETTER FINAL SIGMA + 0x03c3: (0x03c2,), # 'σ': 'Ï‚' + # GREEK SMALL LETTER PHI: GREEK PHI SYMBOL + 0x03c6: (0x03d5,), # 'φ': 'Ï•' + # GREEK BETA SYMBOL: GREEK SMALL LETTER BETA + 0x03d0: (0x03b2,), # 'Ï': 'β' + # GREEK THETA SYMBOL: GREEK SMALL LETTER THETA + 0x03d1: (0x03b8,), # 'Ï‘': 'θ' + # GREEK PHI SYMBOL: GREEK SMALL LETTER PHI + 0x03d5: (0x03c6,), # 'Ï•': 'φ' + # GREEK PI SYMBOL: GREEK SMALL LETTER PI + 0x03d6: (0x03c0,), # 'Ï–': 'Ï€' + # GREEK KAPPA SYMBOL: GREEK SMALL LETTER KAPPA + 0x03f0: (0x03ba,), # 'ϰ': 'κ' + # GREEK RHO SYMBOL: GREEK SMALL LETTER RHO + 0x03f1: (0x03c1,), # 'ϱ': 'Ï' + # GREEK LUNATE EPSILON SYMBOL: GREEK SMALL LETTER EPSILON + 0x03f5: (0x03b5,), # 'ϵ': 'ε' + # CYRILLIC SMALL LETTER VE: CYRILLIC SMALL LETTER ROUNDED VE + 0x0432: (0x1c80,), # 'в': 'á²€' + # CYRILLIC SMALL LETTER DE: CYRILLIC SMALL LETTER LONG-LEGGED DE + 0x0434: (0x1c81,), # 'д': 'á²' + # CYRILLIC SMALL LETTER O: CYRILLIC SMALL LETTER NARROW O + 0x043e: (0x1c82,), # 'о': 'ᲂ' + # CYRILLIC SMALL LETTER ES: CYRILLIC SMALL LETTER WIDE ES + 0x0441: (0x1c83,), # 'Ñ': 'ᲃ' + # CYRILLIC SMALL LETTER TE: CYRILLIC SMALL LETTER TALL TE, CYRILLIC SMALL LETTER THREE-LEGGED TE + 0x0442: (0x1c84, 0x1c85), # 'Ñ‚': 'ᲄᲅ' + # CYRILLIC SMALL LETTER HARD SIGN: CYRILLIC SMALL LETTER TALL HARD SIGN + 0x044a: (0x1c86,), # 'ÑŠ': 'ᲆ' + # CYRILLIC SMALL LETTER YAT: CYRILLIC SMALL LETTER TALL YAT + 0x0463: (0x1c87,), # 'Ñ£': 'ᲇ' + # CYRILLIC SMALL LETTER ROUNDED VE: CYRILLIC SMALL LETTER VE + 0x1c80: (0x0432,), # 'á²€': 'в' + # CYRILLIC SMALL LETTER LONG-LEGGED DE: CYRILLIC SMALL LETTER DE + 0x1c81: (0x0434,), # 'á²': 'д' + # CYRILLIC SMALL LETTER NARROW O: CYRILLIC SMALL LETTER O + 0x1c82: (0x043e,), # 'ᲂ': 'о' + # CYRILLIC SMALL LETTER WIDE ES: CYRILLIC SMALL LETTER ES + 0x1c83: (0x0441,), # 'ᲃ': 'Ñ' + # CYRILLIC SMALL LETTER TALL TE: CYRILLIC SMALL LETTER TE, CYRILLIC SMALL LETTER THREE-LEGGED TE + 0x1c84: (0x0442, 0x1c85), # 'ᲄ': 'тᲅ' + # CYRILLIC SMALL LETTER THREE-LEGGED TE: CYRILLIC SMALL LETTER TE, CYRILLIC SMALL LETTER TALL TE + 0x1c85: (0x0442, 0x1c84), # 'á²…': 'тᲄ' + # CYRILLIC SMALL LETTER TALL HARD SIGN: CYRILLIC SMALL LETTER HARD SIGN + 0x1c86: (0x044a,), # 'ᲆ': 'ÑŠ' + # CYRILLIC SMALL LETTER TALL YAT: CYRILLIC SMALL LETTER YAT + 0x1c87: (0x0463,), # 'ᲇ': 'Ñ£' + # CYRILLIC SMALL LETTER UNBLENDED UK: CYRILLIC SMALL LETTER MONOGRAPH UK + 0x1c88: (0xa64b,), # 'ᲈ': 'ꙋ' + # LATIN SMALL LETTER S WITH DOT ABOVE: LATIN SMALL LETTER LONG S WITH DOT ABOVE + 0x1e61: (0x1e9b,), # 'ṡ': 'ẛ' + # LATIN SMALL LETTER LONG S WITH DOT ABOVE: LATIN SMALL LETTER S WITH DOT ABOVE + 0x1e9b: (0x1e61,), # 'ẛ': 'ṡ' + # GREEK PROSGEGRAMMENI: COMBINING GREEK YPOGEGRAMMENI, GREEK SMALL LETTER IOTA + 0x1fbe: (0x0345, 0x03b9), # 'á¾¾': '\u0345ι' + # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA: GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + 0x1fd3: (0x0390,), # 'á¿“': 'Î' + # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA: GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + 0x1fe3: (0x03b0,), # 'á¿£': 'ΰ' + # CYRILLIC SMALL LETTER MONOGRAPH UK: CYRILLIC SMALL LETTER UNBLENDED UK + 0xa64b: (0x1c88,), # 'ꙋ': 'ᲈ' + # LATIN SMALL LIGATURE LONG S T: LATIN SMALL LIGATURE ST + 0xfb05: (0xfb06,), # 'ſt': 'st' + # LATIN SMALL LIGATURE ST: LATIN SMALL LIGATURE LONG S T + 0xfb06: (0xfb05,), # 'st': 'ſt' +} diff --git a/Lib/re/_compiler.py b/Lib/re/_compiler.py new file mode 100644 index 00000000000..d8e0d2fdefd --- /dev/null +++ b/Lib/re/_compiler.py @@ -0,0 +1,763 @@ +# +# Secret Labs' Regular Expression Engine +# +# convert template to internal format +# +# Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. +# +# See the __init__.py file for information on usage and redistribution. +# + +"""Internal support module for sre""" + +import _sre +from . import _parser +from ._constants import * +from ._casefix import _EXTRA_CASES + +assert _sre.MAGIC == MAGIC, "SRE module mismatch" + +_LITERAL_CODES = {LITERAL, NOT_LITERAL} +_SUCCESS_CODES = {SUCCESS, FAILURE} +_ASSERT_CODES = {ASSERT, ASSERT_NOT} +_UNIT_CODES = _LITERAL_CODES | {ANY, IN} + +_REPEATING_CODES = { + MIN_REPEAT: (REPEAT, MIN_UNTIL, MIN_REPEAT_ONE), + MAX_REPEAT: (REPEAT, MAX_UNTIL, REPEAT_ONE), + POSSESSIVE_REPEAT: (POSSESSIVE_REPEAT, SUCCESS, POSSESSIVE_REPEAT_ONE), +} + +def _combine_flags(flags, add_flags, del_flags, + TYPE_FLAGS=_parser.TYPE_FLAGS): + if add_flags & TYPE_FLAGS: + flags &= ~TYPE_FLAGS + return (flags | add_flags) & ~del_flags + +def _compile(code, pattern, flags): + # internal: compile a (sub)pattern + emit = code.append + _len = len + LITERAL_CODES = _LITERAL_CODES + REPEATING_CODES = _REPEATING_CODES + SUCCESS_CODES = _SUCCESS_CODES + ASSERT_CODES = _ASSERT_CODES + iscased = None + tolower = None + fixes = None + if flags & SRE_FLAG_IGNORECASE and not flags & SRE_FLAG_LOCALE: + if flags & SRE_FLAG_UNICODE: + iscased = _sre.unicode_iscased + tolower = _sre.unicode_tolower + fixes = _EXTRA_CASES + else: + iscased = _sre.ascii_iscased + tolower = _sre.ascii_tolower + for op, av in pattern: + if op in LITERAL_CODES: + if not flags & SRE_FLAG_IGNORECASE: + emit(op) + emit(av) + elif flags & SRE_FLAG_LOCALE: + emit(OP_LOCALE_IGNORE[op]) + emit(av) + elif not iscased(av): + emit(op) + emit(av) + else: + lo = tolower(av) + if not fixes: # ascii + emit(OP_IGNORE[op]) + emit(lo) + elif lo not in fixes: + emit(OP_UNICODE_IGNORE[op]) + emit(lo) + else: + emit(IN_UNI_IGNORE) + skip = _len(code); emit(0) + if op is NOT_LITERAL: + emit(NEGATE) + for k in (lo,) + fixes[lo]: + emit(LITERAL) + emit(k) + emit(FAILURE) + code[skip] = _len(code) - skip + elif op is IN: + charset, hascased = _optimize_charset(av, iscased, tolower, fixes) + if flags & SRE_FLAG_IGNORECASE and flags & SRE_FLAG_LOCALE: + emit(IN_LOC_IGNORE) + elif not hascased: + emit(IN) + elif not fixes: # ascii + emit(IN_IGNORE) + else: + emit(IN_UNI_IGNORE) + skip = _len(code); emit(0) + _compile_charset(charset, flags, code) + code[skip] = _len(code) - skip + elif op is ANY: + if flags & SRE_FLAG_DOTALL: + emit(ANY_ALL) + else: + emit(ANY) + elif op in REPEATING_CODES: + if flags & SRE_FLAG_TEMPLATE: + raise error("internal: unsupported template operator %r" % (op,)) + if _simple(av[2]): + emit(REPEATING_CODES[op][2]) + skip = _len(code); emit(0) + emit(av[0]) + emit(av[1]) + _compile(code, av[2], flags) + emit(SUCCESS) + code[skip] = _len(code) - skip + else: + emit(REPEATING_CODES[op][0]) + skip = _len(code); emit(0) + emit(av[0]) + emit(av[1]) + _compile(code, av[2], flags) + code[skip] = _len(code) - skip + emit(REPEATING_CODES[op][1]) + elif op is SUBPATTERN: + group, add_flags, del_flags, p = av + if group: + emit(MARK) + emit((group-1)*2) + # _compile_info(code, p, _combine_flags(flags, add_flags, del_flags)) + _compile(code, p, _combine_flags(flags, add_flags, del_flags)) + if group: + emit(MARK) + emit((group-1)*2+1) + elif op is ATOMIC_GROUP: + # Atomic Groups are handled by starting with an Atomic + # Group op code, then putting in the atomic group pattern + # and finally a success op code to tell any repeat + # operations within the Atomic Group to stop eating and + # pop their stack if they reach it + emit(ATOMIC_GROUP) + skip = _len(code); emit(0) + _compile(code, av, flags) + emit(SUCCESS) + code[skip] = _len(code) - skip + elif op in SUCCESS_CODES: + emit(op) + elif op in ASSERT_CODES: + emit(op) + skip = _len(code); emit(0) + if av[0] >= 0: + emit(0) # look ahead + else: + lo, hi = av[1].getwidth() + if lo != hi: + raise error("look-behind requires fixed-width pattern") + emit(lo) # look behind + _compile(code, av[1], flags) + emit(SUCCESS) + code[skip] = _len(code) - skip + elif op is AT: + emit(op) + if flags & SRE_FLAG_MULTILINE: + av = AT_MULTILINE.get(av, av) + if flags & SRE_FLAG_LOCALE: + av = AT_LOCALE.get(av, av) + elif flags & SRE_FLAG_UNICODE: + av = AT_UNICODE.get(av, av) + emit(av) + elif op is BRANCH: + emit(op) + tail = [] + tailappend = tail.append + for av in av[1]: + skip = _len(code); emit(0) + # _compile_info(code, av, flags) + _compile(code, av, flags) + emit(JUMP) + tailappend(_len(code)); emit(0) + code[skip] = _len(code) - skip + emit(FAILURE) # end of branch + for tail in tail: + code[tail] = _len(code) - tail + elif op is CATEGORY: + emit(op) + if flags & SRE_FLAG_LOCALE: + av = CH_LOCALE[av] + elif flags & SRE_FLAG_UNICODE: + av = CH_UNICODE[av] + emit(av) + elif op is GROUPREF: + if not flags & SRE_FLAG_IGNORECASE: + emit(op) + elif flags & SRE_FLAG_LOCALE: + emit(GROUPREF_LOC_IGNORE) + elif not fixes: # ascii + emit(GROUPREF_IGNORE) + else: + emit(GROUPREF_UNI_IGNORE) + emit(av-1) + elif op is GROUPREF_EXISTS: + emit(op) + emit(av[0]-1) + skipyes = _len(code); emit(0) + _compile(code, av[1], flags) + if av[2]: + emit(JUMP) + skipno = _len(code); emit(0) + code[skipyes] = _len(code) - skipyes + 1 + _compile(code, av[2], flags) + code[skipno] = _len(code) - skipno + else: + code[skipyes] = _len(code) - skipyes + 1 + else: + raise error("internal: unsupported operand type %r" % (op,)) + +def _compile_charset(charset, flags, code): + # compile charset subprogram + emit = code.append + for op, av in charset: + emit(op) + if op is NEGATE: + pass + elif op is LITERAL: + emit(av) + elif op is RANGE or op is RANGE_UNI_IGNORE: + emit(av[0]) + emit(av[1]) + elif op is CHARSET: + code.extend(av) + elif op is BIGCHARSET: + code.extend(av) + elif op is CATEGORY: + if flags & SRE_FLAG_LOCALE: + emit(CH_LOCALE[av]) + elif flags & SRE_FLAG_UNICODE: + emit(CH_UNICODE[av]) + else: + emit(av) + else: + raise error("internal: unsupported set operator %r" % (op,)) + emit(FAILURE) + +def _optimize_charset(charset, iscased=None, fixup=None, fixes=None): + # internal: optimize character set + out = [] + tail = [] + charmap = bytearray(256) + hascased = False + for op, av in charset: + while True: + try: + if op is LITERAL: + if fixup: + lo = fixup(av) + charmap[lo] = 1 + if fixes and lo in fixes: + for k in fixes[lo]: + charmap[k] = 1 + if not hascased and iscased(av): + hascased = True + else: + charmap[av] = 1 + elif op is RANGE: + r = range(av[0], av[1]+1) + if fixup: + if fixes: + for i in map(fixup, r): + charmap[i] = 1 + if i in fixes: + for k in fixes[i]: + charmap[k] = 1 + else: + for i in map(fixup, r): + charmap[i] = 1 + if not hascased: + hascased = any(map(iscased, r)) + else: + for i in r: + charmap[i] = 1 + elif op is NEGATE: + out.append((op, av)) + else: + tail.append((op, av)) + except IndexError: + if len(charmap) == 256: + # character set contains non-UCS1 character codes + charmap += b'\0' * 0xff00 + continue + # Character set contains non-BMP character codes. + # For range, all BMP characters in the range are already + # proceeded. + if fixup: + hascased = True + # For now, IN_UNI_IGNORE+LITERAL and + # IN_UNI_IGNORE+RANGE_UNI_IGNORE work for all non-BMP + # characters, because two characters (at least one of + # which is not in the BMP) match case-insensitively + # if and only if: + # 1) c1.lower() == c2.lower() + # 2) c1.lower() == c2 or c1.lower().upper() == c2 + # Also, both c.lower() and c.lower().upper() are single + # characters for every non-BMP character. + if op is RANGE: + op = RANGE_UNI_IGNORE + tail.append((op, av)) + break + + # compress character map + runs = [] + q = 0 + while True: + p = charmap.find(1, q) + if p < 0: + break + if len(runs) >= 2: + runs = None + break + q = charmap.find(0, p) + if q < 0: + runs.append((p, len(charmap))) + break + runs.append((p, q)) + if runs is not None: + # use literal/range + for p, q in runs: + if q - p == 1: + out.append((LITERAL, p)) + else: + out.append((RANGE, (p, q - 1))) + out += tail + # if the case was changed or new representation is more compact + if hascased or len(out) < len(charset): + return out, hascased + # else original character set is good enough + return charset, hascased + + # use bitmap + if len(charmap) == 256: + data = _mk_bitmap(charmap) + out.append((CHARSET, data)) + out += tail + return out, hascased + + # To represent a big charset, first a bitmap of all characters in the + # set is constructed. Then, this bitmap is sliced into chunks of 256 + # characters, duplicate chunks are eliminated, and each chunk is + # given a number. In the compiled expression, the charset is + # represented by a 32-bit word sequence, consisting of one word for + # the number of different chunks, a sequence of 256 bytes (64 words) + # of chunk numbers indexed by their original chunk position, and a + # sequence of 256-bit chunks (8 words each). + + # Compression is normally good: in a typical charset, large ranges of + # Unicode will be either completely excluded (e.g. if only cyrillic + # letters are to be matched), or completely included (e.g. if large + # subranges of Kanji match). These ranges will be represented by + # chunks of all one-bits or all zero-bits. + + # Matching can be also done efficiently: the more significant byte of + # the Unicode character is an index into the chunk number, and the + # less significant byte is a bit index in the chunk (just like the + # CHARSET matching). + + charmap = bytes(charmap) # should be hashable + comps = {} + mapping = bytearray(256) + block = 0 + data = bytearray() + for i in range(0, 65536, 256): + chunk = charmap[i: i + 256] + if chunk in comps: + mapping[i // 256] = comps[chunk] + else: + mapping[i // 256] = comps[chunk] = block + block += 1 + data += chunk + data = _mk_bitmap(data) + data[0:0] = [block] + _bytes_to_codes(mapping) + out.append((BIGCHARSET, data)) + out += tail + return out, hascased + +_CODEBITS = _sre.CODESIZE * 8 +MAXCODE = (1 << _CODEBITS) - 1 +_BITS_TRANS = b'0' + b'1' * 255 +def _mk_bitmap(bits, _CODEBITS=_CODEBITS, _int=int): + s = bits.translate(_BITS_TRANS)[::-1] + return [_int(s[i - _CODEBITS: i], 2) + for i in range(len(s), 0, -_CODEBITS)] + +def _bytes_to_codes(b): + # Convert block indices to word array + a = memoryview(b).cast('I') + assert a.itemsize == _sre.CODESIZE + assert len(a) * a.itemsize == len(b) + return a.tolist() + +def _simple(p): + # check if this subpattern is a "simple" operator + if len(p) != 1: + return False + op, av = p[0] + if op is SUBPATTERN: + return av[0] is None and _simple(av[-1]) + return op in _UNIT_CODES + +def _generate_overlap_table(prefix): + """ + Generate an overlap table for the following prefix. + An overlap table is a table of the same size as the prefix which + informs about the potential self-overlap for each index in the prefix: + - if overlap[i] == 0, prefix[i:] can't overlap prefix[0:...] + - if overlap[i] == k with 0 < k <= i, prefix[i-k+1:i+1] overlaps with + prefix[0:k] + """ + table = [0] * len(prefix) + for i in range(1, len(prefix)): + idx = table[i - 1] + while prefix[i] != prefix[idx]: + if idx == 0: + table[i] = 0 + break + idx = table[idx - 1] + else: + table[i] = idx + 1 + return table + +def _get_iscased(flags): + if not flags & SRE_FLAG_IGNORECASE: + return None + elif flags & SRE_FLAG_UNICODE: + return _sre.unicode_iscased + else: + return _sre.ascii_iscased + +def _get_literal_prefix(pattern, flags): + # look for literal prefix + prefix = [] + prefixappend = prefix.append + prefix_skip = None + iscased = _get_iscased(flags) + for op, av in pattern.data: + if op is LITERAL: + if iscased and iscased(av): + break + prefixappend(av) + elif op is SUBPATTERN: + group, add_flags, del_flags, p = av + flags1 = _combine_flags(flags, add_flags, del_flags) + if flags1 & SRE_FLAG_IGNORECASE and flags1 & SRE_FLAG_LOCALE: + break + prefix1, prefix_skip1, got_all = _get_literal_prefix(p, flags1) + if prefix_skip is None: + if group is not None: + prefix_skip = len(prefix) + elif prefix_skip1 is not None: + prefix_skip = len(prefix) + prefix_skip1 + prefix.extend(prefix1) + if not got_all: + break + else: + break + else: + return prefix, prefix_skip, True + return prefix, prefix_skip, False + +def _get_charset_prefix(pattern, flags): + while True: + if not pattern.data: + return None + op, av = pattern.data[0] + if op is not SUBPATTERN: + break + group, add_flags, del_flags, pattern = av + flags = _combine_flags(flags, add_flags, del_flags) + if flags & SRE_FLAG_IGNORECASE and flags & SRE_FLAG_LOCALE: + return None + + iscased = _get_iscased(flags) + if op is LITERAL: + if iscased and iscased(av): + return None + return [(op, av)] + elif op is BRANCH: + charset = [] + charsetappend = charset.append + for p in av[1]: + if not p: + return None + op, av = p[0] + if op is LITERAL and not (iscased and iscased(av)): + charsetappend((op, av)) + else: + return None + return charset + elif op is IN: + charset = av + if iscased: + for op, av in charset: + if op is LITERAL: + if iscased(av): + return None + elif op is RANGE: + if av[1] > 0xffff: + return None + if any(map(iscased, range(av[0], av[1]+1))): + return None + return charset + return None + +def _compile_info(code, pattern, flags): + # internal: compile an info block. in the current version, + # this contains min/max pattern width, and an optional literal + # prefix or a character map + lo, hi = pattern.getwidth() + if hi > MAXCODE: + hi = MAXCODE + if lo == 0: + code.extend([INFO, 4, 0, lo, hi]) + return + # look for a literal prefix + prefix = [] + prefix_skip = 0 + charset = [] # not used + if not (flags & SRE_FLAG_IGNORECASE and flags & SRE_FLAG_LOCALE): + # look for literal prefix + prefix, prefix_skip, got_all = _get_literal_prefix(pattern, flags) + # if no prefix, look for charset prefix + if not prefix: + charset = _get_charset_prefix(pattern, flags) +## if prefix: +## print("*** PREFIX", prefix, prefix_skip) +## if charset: +## print("*** CHARSET", charset) + # add an info block + emit = code.append + emit(INFO) + skip = len(code); emit(0) + # literal flag + mask = 0 + if prefix: + mask = SRE_INFO_PREFIX + if prefix_skip is None and got_all: + mask = mask | SRE_INFO_LITERAL + elif charset: + mask = mask | SRE_INFO_CHARSET + emit(mask) + # pattern length + if lo < MAXCODE: + emit(lo) + else: + emit(MAXCODE) + prefix = prefix[:MAXCODE] + emit(min(hi, MAXCODE)) + # add literal prefix + if prefix: + emit(len(prefix)) # length + if prefix_skip is None: + prefix_skip = len(prefix) + emit(prefix_skip) # skip + code.extend(prefix) + # generate overlap table + code.extend(_generate_overlap_table(prefix)) + elif charset: + charset, hascased = _optimize_charset(charset) + assert not hascased + _compile_charset(charset, flags, code) + code[skip] = len(code) - skip + +def isstring(obj): + return isinstance(obj, (str, bytes)) + +def _code(p, flags): + + flags = p.state.flags | flags + code = [] + + # compile info block + _compile_info(code, p, flags) + + # compile the pattern + _compile(code, p.data, flags) + + code.append(SUCCESS) + + return code + +def _hex_code(code): + return '[%s]' % ', '.join('%#0*x' % (_sre.CODESIZE*2+2, x) for x in code) + +def dis(code): + import sys + + labels = set() + level = 0 + offset_width = len(str(len(code) - 1)) + + def dis_(start, end): + def print_(*args, to=None): + if to is not None: + labels.add(to) + args += ('(to %d)' % (to,),) + print('%*d%s ' % (offset_width, start, ':' if start in labels else '.'), + end=' '*(level-1)) + print(*args) + + def print_2(*args): + print(end=' '*(offset_width + 2*level)) + print(*args) + + nonlocal level + level += 1 + i = start + while i < end: + start = i + op = code[i] + i += 1 + op = OPCODES[op] + if op in (SUCCESS, FAILURE, ANY, ANY_ALL, + MAX_UNTIL, MIN_UNTIL, NEGATE): + print_(op) + elif op in (LITERAL, NOT_LITERAL, + LITERAL_IGNORE, NOT_LITERAL_IGNORE, + LITERAL_UNI_IGNORE, NOT_LITERAL_UNI_IGNORE, + LITERAL_LOC_IGNORE, NOT_LITERAL_LOC_IGNORE): + arg = code[i] + i += 1 + print_(op, '%#02x (%r)' % (arg, chr(arg))) + elif op is AT: + arg = code[i] + i += 1 + arg = str(ATCODES[arg]) + assert arg[:3] == 'AT_' + print_(op, arg[3:]) + elif op is CATEGORY: + arg = code[i] + i += 1 + arg = str(CHCODES[arg]) + assert arg[:9] == 'CATEGORY_' + print_(op, arg[9:]) + elif op in (IN, IN_IGNORE, IN_UNI_IGNORE, IN_LOC_IGNORE): + skip = code[i] + print_(op, skip, to=i+skip) + dis_(i+1, i+skip) + i += skip + elif op in (RANGE, RANGE_UNI_IGNORE): + lo, hi = code[i: i+2] + i += 2 + print_(op, '%#02x %#02x (%r-%r)' % (lo, hi, chr(lo), chr(hi))) + elif op is CHARSET: + print_(op, _hex_code(code[i: i + 256//_CODEBITS])) + i += 256//_CODEBITS + elif op is BIGCHARSET: + arg = code[i] + i += 1 + mapping = list(b''.join(x.to_bytes(_sre.CODESIZE, sys.byteorder) + for x in code[i: i + 256//_sre.CODESIZE])) + print_(op, arg, mapping) + i += 256//_sre.CODESIZE + level += 1 + for j in range(arg): + print_2(_hex_code(code[i: i + 256//_CODEBITS])) + i += 256//_CODEBITS + level -= 1 + elif op in (MARK, GROUPREF, GROUPREF_IGNORE, GROUPREF_UNI_IGNORE, + GROUPREF_LOC_IGNORE): + arg = code[i] + i += 1 + print_(op, arg) + elif op is JUMP: + skip = code[i] + print_(op, skip, to=i+skip) + i += 1 + elif op is BRANCH: + skip = code[i] + print_(op, skip, to=i+skip) + while skip: + dis_(i+1, i+skip) + i += skip + start = i + skip = code[i] + if skip: + print_('branch', skip, to=i+skip) + else: + print_(FAILURE) + i += 1 + elif op in (REPEAT, REPEAT_ONE, MIN_REPEAT_ONE, + POSSESSIVE_REPEAT, POSSESSIVE_REPEAT_ONE): + skip, min, max = code[i: i+3] + if max == MAXREPEAT: + max = 'MAXREPEAT' + print_(op, skip, min, max, to=i+skip) + dis_(i+3, i+skip) + i += skip + elif op is GROUPREF_EXISTS: + arg, skip = code[i: i+2] + print_(op, arg, skip, to=i+skip) + i += 2 + elif op in (ASSERT, ASSERT_NOT): + skip, arg = code[i: i+2] + print_(op, skip, arg, to=i+skip) + dis_(i+2, i+skip) + i += skip + elif op is ATOMIC_GROUP: + skip = code[i] + print_(op, skip, to=i+skip) + dis_(i+1, i+skip) + i += skip + elif op is INFO: + skip, flags, min, max = code[i: i+4] + if max == MAXREPEAT: + max = 'MAXREPEAT' + print_(op, skip, bin(flags), min, max, to=i+skip) + start = i+4 + if flags & SRE_INFO_PREFIX: + prefix_len, prefix_skip = code[i+4: i+6] + print_2(' prefix_skip', prefix_skip) + start = i + 6 + prefix = code[start: start+prefix_len] + print_2(' prefix', + '[%s]' % ', '.join('%#02x' % x for x in prefix), + '(%r)' % ''.join(map(chr, prefix))) + start += prefix_len + print_2(' overlap', code[start: start+prefix_len]) + start += prefix_len + if flags & SRE_INFO_CHARSET: + level += 1 + print_2('in') + dis_(start, i+skip) + level -= 1 + i += skip + else: + raise ValueError(op) + + level -= 1 + + dis_(0, len(code)) + + +def compile(p, flags=0): + # internal: convert pattern list to internal format + + if isstring(p): + pattern = p + p = _parser.parse(p, flags) + else: + pattern = None + + code = _code(p, flags) + + if flags & SRE_FLAG_DEBUG: + print() + dis(code) + + # map in either direction + groupindex = p.state.groupdict + indexgroup = [None] * p.state.groups + for k, i in groupindex.items(): + indexgroup[i] = k + + return _sre.compile( + pattern, flags | p.state.flags, code, + p.state.groups-1, + groupindex, tuple(indexgroup) + ) diff --git a/Lib/re/_constants.py b/Lib/re/_constants.py new file mode 100644 index 00000000000..d8718d36075 --- /dev/null +++ b/Lib/re/_constants.py @@ -0,0 +1,220 @@ +# +# Secret Labs' Regular Expression Engine +# +# various symbols used by the regular expression engine. +# run this script to update the _sre include files! +# +# Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. +# +# See the __init__.py file for information on usage and redistribution. +# + +"""Internal support module for sre""" + +# update when constants are added or removed + +MAGIC = 20221023 + +from _sre import MAXREPEAT, MAXGROUPS + +# SRE standard exception (access as sre.error) +# should this really be here? + +class error(Exception): + """Exception raised for invalid regular expressions. + + Attributes: + + msg: The unformatted error message + pattern: The regular expression pattern + pos: The index in the pattern where compilation failed (may be None) + lineno: The line corresponding to pos (may be None) + colno: The column corresponding to pos (may be None) + """ + + __module__ = 're' + + def __init__(self, msg, pattern=None, pos=None): + self.msg = msg + self.pattern = pattern + self.pos = pos + if pattern is not None and pos is not None: + msg = '%s at position %d' % (msg, pos) + if isinstance(pattern, str): + newline = '\n' + else: + newline = b'\n' + self.lineno = pattern.count(newline, 0, pos) + 1 + self.colno = pos - pattern.rfind(newline, 0, pos) + if newline in pattern: + msg = '%s (line %d, column %d)' % (msg, self.lineno, self.colno) + else: + self.lineno = self.colno = None + super().__init__(msg) + + +class _NamedIntConstant(int): + def __new__(cls, value, name): + self = super(_NamedIntConstant, cls).__new__(cls, value) + self.name = name + return self + + def __repr__(self): + return self.name + + __reduce__ = None + +MAXREPEAT = _NamedIntConstant(MAXREPEAT, 'MAXREPEAT') + +def _makecodes(*names): + items = [_NamedIntConstant(i, name) for i, name in enumerate(names)] + globals().update({item.name: item for item in items}) + return items + +# operators +OPCODES = _makecodes( + # failure=0 success=1 (just because it looks better that way :-) + 'FAILURE', 'SUCCESS', + + 'ANY', 'ANY_ALL', + 'ASSERT', 'ASSERT_NOT', + 'AT', + 'BRANCH', + 'CATEGORY', + 'CHARSET', 'BIGCHARSET', + 'GROUPREF', 'GROUPREF_EXISTS', + 'IN', + 'INFO', + 'JUMP', + 'LITERAL', + 'MARK', + 'MAX_UNTIL', + 'MIN_UNTIL', + 'NOT_LITERAL', + 'NEGATE', + 'RANGE', + 'REPEAT', + 'REPEAT_ONE', + 'SUBPATTERN', + 'MIN_REPEAT_ONE', + 'ATOMIC_GROUP', + 'POSSESSIVE_REPEAT', + 'POSSESSIVE_REPEAT_ONE', + + 'GROUPREF_IGNORE', + 'IN_IGNORE', + 'LITERAL_IGNORE', + 'NOT_LITERAL_IGNORE', + + 'GROUPREF_LOC_IGNORE', + 'IN_LOC_IGNORE', + 'LITERAL_LOC_IGNORE', + 'NOT_LITERAL_LOC_IGNORE', + + 'GROUPREF_UNI_IGNORE', + 'IN_UNI_IGNORE', + 'LITERAL_UNI_IGNORE', + 'NOT_LITERAL_UNI_IGNORE', + 'RANGE_UNI_IGNORE', + + # The following opcodes are only occurred in the parser output, + # but not in the compiled code. + 'MIN_REPEAT', 'MAX_REPEAT', +) +del OPCODES[-2:] # remove MIN_REPEAT and MAX_REPEAT + +# positions +ATCODES = _makecodes( + 'AT_BEGINNING', 'AT_BEGINNING_LINE', 'AT_BEGINNING_STRING', + 'AT_BOUNDARY', 'AT_NON_BOUNDARY', + 'AT_END', 'AT_END_LINE', 'AT_END_STRING', + + 'AT_LOC_BOUNDARY', 'AT_LOC_NON_BOUNDARY', + + 'AT_UNI_BOUNDARY', 'AT_UNI_NON_BOUNDARY', +) + +# categories +CHCODES = _makecodes( + 'CATEGORY_DIGIT', 'CATEGORY_NOT_DIGIT', + 'CATEGORY_SPACE', 'CATEGORY_NOT_SPACE', + 'CATEGORY_WORD', 'CATEGORY_NOT_WORD', + 'CATEGORY_LINEBREAK', 'CATEGORY_NOT_LINEBREAK', + + 'CATEGORY_LOC_WORD', 'CATEGORY_LOC_NOT_WORD', + + 'CATEGORY_UNI_DIGIT', 'CATEGORY_UNI_NOT_DIGIT', + 'CATEGORY_UNI_SPACE', 'CATEGORY_UNI_NOT_SPACE', + 'CATEGORY_UNI_WORD', 'CATEGORY_UNI_NOT_WORD', + 'CATEGORY_UNI_LINEBREAK', 'CATEGORY_UNI_NOT_LINEBREAK', +) + + +# replacement operations for "ignore case" mode +OP_IGNORE = { + LITERAL: LITERAL_IGNORE, + NOT_LITERAL: NOT_LITERAL_IGNORE, +} + +OP_LOCALE_IGNORE = { + LITERAL: LITERAL_LOC_IGNORE, + NOT_LITERAL: NOT_LITERAL_LOC_IGNORE, +} + +OP_UNICODE_IGNORE = { + LITERAL: LITERAL_UNI_IGNORE, + NOT_LITERAL: NOT_LITERAL_UNI_IGNORE, +} + +AT_MULTILINE = { + AT_BEGINNING: AT_BEGINNING_LINE, + AT_END: AT_END_LINE +} + +AT_LOCALE = { + AT_BOUNDARY: AT_LOC_BOUNDARY, + AT_NON_BOUNDARY: AT_LOC_NON_BOUNDARY +} + +AT_UNICODE = { + AT_BOUNDARY: AT_UNI_BOUNDARY, + AT_NON_BOUNDARY: AT_UNI_NON_BOUNDARY +} + +CH_LOCALE = { + CATEGORY_DIGIT: CATEGORY_DIGIT, + CATEGORY_NOT_DIGIT: CATEGORY_NOT_DIGIT, + CATEGORY_SPACE: CATEGORY_SPACE, + CATEGORY_NOT_SPACE: CATEGORY_NOT_SPACE, + CATEGORY_WORD: CATEGORY_LOC_WORD, + CATEGORY_NOT_WORD: CATEGORY_LOC_NOT_WORD, + CATEGORY_LINEBREAK: CATEGORY_LINEBREAK, + CATEGORY_NOT_LINEBREAK: CATEGORY_NOT_LINEBREAK +} + +CH_UNICODE = { + CATEGORY_DIGIT: CATEGORY_UNI_DIGIT, + CATEGORY_NOT_DIGIT: CATEGORY_UNI_NOT_DIGIT, + CATEGORY_SPACE: CATEGORY_UNI_SPACE, + CATEGORY_NOT_SPACE: CATEGORY_UNI_NOT_SPACE, + CATEGORY_WORD: CATEGORY_UNI_WORD, + CATEGORY_NOT_WORD: CATEGORY_UNI_NOT_WORD, + CATEGORY_LINEBREAK: CATEGORY_UNI_LINEBREAK, + CATEGORY_NOT_LINEBREAK: CATEGORY_UNI_NOT_LINEBREAK +} + +# flags +SRE_FLAG_TEMPLATE = 1 # template mode (unknown purpose, deprecated) +SRE_FLAG_IGNORECASE = 2 # case insensitive +SRE_FLAG_LOCALE = 4 # honour system locale +SRE_FLAG_MULTILINE = 8 # treat target as multiline string +SRE_FLAG_DOTALL = 16 # treat target as a single string +SRE_FLAG_UNICODE = 32 # use unicode "locale" +SRE_FLAG_VERBOSE = 64 # ignore whitespace and comments +SRE_FLAG_DEBUG = 128 # debugging +SRE_FLAG_ASCII = 256 # use ascii "locale" + +# flags for INFO primitive +SRE_INFO_PREFIX = 1 # has prefix +SRE_INFO_LITERAL = 2 # entire pattern is literal (given by prefix) +SRE_INFO_CHARSET = 4 # pattern starts with character from given set diff --git a/Lib/re/_parser.py b/Lib/re/_parser.py new file mode 100644 index 00000000000..5709acb6267 --- /dev/null +++ b/Lib/re/_parser.py @@ -0,0 +1,1071 @@ +# +# Secret Labs' Regular Expression Engine +# +# convert re-style regular expression to sre pattern +# +# Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. +# +# See the __init__.py file for information on usage and redistribution. +# + +"""Internal support module for sre""" + +# XXX: show string offset and offending character for all errors + +from ._constants import * + +SPECIAL_CHARS = ".\\[{()*+?^$|" +REPEAT_CHARS = "*+?{" + +DIGITS = frozenset("0123456789") + +OCTDIGITS = frozenset("01234567") +HEXDIGITS = frozenset("0123456789abcdefABCDEF") +ASCIILETTERS = frozenset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + +WHITESPACE = frozenset(" \t\n\r\v\f") + +_REPEATCODES = frozenset({MIN_REPEAT, MAX_REPEAT, POSSESSIVE_REPEAT}) +_UNITCODES = frozenset({ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY}) + +ESCAPES = { + r"\a": (LITERAL, ord("\a")), + r"\b": (LITERAL, ord("\b")), + r"\f": (LITERAL, ord("\f")), + r"\n": (LITERAL, ord("\n")), + r"\r": (LITERAL, ord("\r")), + r"\t": (LITERAL, ord("\t")), + r"\v": (LITERAL, ord("\v")), + r"\\": (LITERAL, ord("\\")) +} + +CATEGORIES = { + r"\A": (AT, AT_BEGINNING_STRING), # start of string + r"\b": (AT, AT_BOUNDARY), + r"\B": (AT, AT_NON_BOUNDARY), + r"\d": (IN, [(CATEGORY, CATEGORY_DIGIT)]), + r"\D": (IN, [(CATEGORY, CATEGORY_NOT_DIGIT)]), + r"\s": (IN, [(CATEGORY, CATEGORY_SPACE)]), + r"\S": (IN, [(CATEGORY, CATEGORY_NOT_SPACE)]), + r"\w": (IN, [(CATEGORY, CATEGORY_WORD)]), + r"\W": (IN, [(CATEGORY, CATEGORY_NOT_WORD)]), + r"\Z": (AT, AT_END_STRING), # end of string +} + +FLAGS = { + # standard flags + "i": SRE_FLAG_IGNORECASE, + "L": SRE_FLAG_LOCALE, + "m": SRE_FLAG_MULTILINE, + "s": SRE_FLAG_DOTALL, + "x": SRE_FLAG_VERBOSE, + # extensions + "a": SRE_FLAG_ASCII, + "t": SRE_FLAG_TEMPLATE, + "u": SRE_FLAG_UNICODE, +} + +TYPE_FLAGS = SRE_FLAG_ASCII | SRE_FLAG_LOCALE | SRE_FLAG_UNICODE +GLOBAL_FLAGS = SRE_FLAG_DEBUG | SRE_FLAG_TEMPLATE + +class State: + # keeps track of state for parsing + def __init__(self): + self.flags = 0 + self.groupdict = {} + self.groupwidths = [None] # group 0 + self.lookbehindgroups = None + self.grouprefpos = {} + @property + def groups(self): + return len(self.groupwidths) + def opengroup(self, name=None): + gid = self.groups + self.groupwidths.append(None) + if self.groups > MAXGROUPS: + raise error("too many groups") + if name is not None: + ogid = self.groupdict.get(name, None) + if ogid is not None: + raise error("redefinition of group name %r as group %d; " + "was group %d" % (name, gid, ogid)) + self.groupdict[name] = gid + return gid + def closegroup(self, gid, p): + self.groupwidths[gid] = p.getwidth() + def checkgroup(self, gid): + return gid < self.groups and self.groupwidths[gid] is not None + + def checklookbehindgroup(self, gid, source): + if self.lookbehindgroups is not None: + if not self.checkgroup(gid): + raise source.error('cannot refer to an open group') + if gid >= self.lookbehindgroups: + raise source.error('cannot refer to group defined in the same ' + 'lookbehind subpattern') + +class SubPattern: + # a subpattern, in intermediate form + def __init__(self, state, data=None): + self.state = state + if data is None: + data = [] + self.data = data + self.width = None + + def dump(self, level=0): + nl = True + seqtypes = (tuple, list) + for op, av in self.data: + print(level*" " + str(op), end='') + if op is IN: + # member sublanguage + print() + for op, a in av: + print((level+1)*" " + str(op), a) + elif op is BRANCH: + print() + for i, a in enumerate(av[1]): + if i: + print(level*" " + "OR") + a.dump(level+1) + elif op is GROUPREF_EXISTS: + condgroup, item_yes, item_no = av + print('', condgroup) + item_yes.dump(level+1) + if item_no: + print(level*" " + "ELSE") + item_no.dump(level+1) + elif isinstance(av, seqtypes): + nl = False + for a in av: + if isinstance(a, SubPattern): + if not nl: + print() + a.dump(level+1) + nl = True + else: + if not nl: + print(' ', end='') + print(a, end='') + nl = False + if not nl: + print() + else: + print('', av) + def __repr__(self): + return repr(self.data) + def __len__(self): + return len(self.data) + def __delitem__(self, index): + del self.data[index] + def __getitem__(self, index): + if isinstance(index, slice): + return SubPattern(self.state, self.data[index]) + return self.data[index] + def __setitem__(self, index, code): + self.data[index] = code + def insert(self, index, code): + self.data.insert(index, code) + def append(self, code): + self.data.append(code) + def getwidth(self): + # determine the width (min, max) for this subpattern + if self.width is not None: + return self.width + lo = hi = 0 + for op, av in self.data: + if op is BRANCH: + i = MAXREPEAT - 1 + j = 0 + for av in av[1]: + l, h = av.getwidth() + i = min(i, l) + j = max(j, h) + lo = lo + i + hi = hi + j + elif op is ATOMIC_GROUP: + i, j = av.getwidth() + lo = lo + i + hi = hi + j + elif op is SUBPATTERN: + i, j = av[-1].getwidth() + lo = lo + i + hi = hi + j + elif op in _REPEATCODES: + i, j = av[2].getwidth() + lo = lo + i * av[0] + hi = hi + j * av[1] + elif op in _UNITCODES: + lo = lo + 1 + hi = hi + 1 + elif op is GROUPREF: + i, j = self.state.groupwidths[av] + lo = lo + i + hi = hi + j + elif op is GROUPREF_EXISTS: + i, j = av[1].getwidth() + if av[2] is not None: + l, h = av[2].getwidth() + i = min(i, l) + j = max(j, h) + else: + i = 0 + lo = lo + i + hi = hi + j + elif op is SUCCESS: + break + self.width = min(lo, MAXREPEAT - 1), min(hi, MAXREPEAT) + return self.width + +class Tokenizer: + def __init__(self, string): + self.istext = isinstance(string, str) + self.string = string + if not self.istext: + string = str(string, 'latin1') + self.decoded_string = string + self.index = 0 + self.next = None + self.__next() + def __next(self): + index = self.index + try: + char = self.decoded_string[index] + except IndexError: + self.next = None + return + if char == "\\": + index += 1 + try: + char += self.decoded_string[index] + except IndexError: + raise error("bad escape (end of pattern)", + self.string, len(self.string) - 1) from None + self.index = index + 1 + self.next = char + def match(self, char): + if char == self.next: + self.__next() + return True + return False + def get(self): + this = self.next + self.__next() + return this + def getwhile(self, n, charset): + result = '' + for _ in range(n): + c = self.next + if c not in charset: + break + result += c + self.__next() + return result + def getuntil(self, terminator, name): + result = '' + while True: + c = self.next + self.__next() + if c is None: + if not result: + raise self.error("missing " + name) + raise self.error("missing %s, unterminated name" % terminator, + len(result)) + if c == terminator: + if not result: + raise self.error("missing " + name, 1) + break + result += c + return result + @property + def pos(self): + return self.index - len(self.next or '') + def tell(self): + return self.index - len(self.next or '') + def seek(self, index): + self.index = index + self.__next() + + def error(self, msg, offset=0): + if not self.istext: + msg = msg.encode('ascii', 'backslashreplace').decode('ascii') + return error(msg, self.string, self.tell() - offset) + + def checkgroupname(self, name, offset): + if not (self.istext or name.isascii()): + msg = "bad character in group name %a" % name + raise self.error(msg, len(name) + offset) + if not name.isidentifier(): + msg = "bad character in group name %r" % name + raise self.error(msg, len(name) + offset) + +def _class_escape(source, escape): + # handle escape code inside character class + code = ESCAPES.get(escape) + if code: + return code + code = CATEGORIES.get(escape) + if code and code[0] is IN: + return code + try: + c = escape[1:2] + if c == "x": + # hexadecimal escape (exactly two digits) + escape += source.getwhile(2, HEXDIGITS) + if len(escape) != 4: + raise source.error("incomplete escape %s" % escape, len(escape)) + return LITERAL, int(escape[2:], 16) + elif c == "u" and source.istext: + # unicode escape (exactly four digits) + escape += source.getwhile(4, HEXDIGITS) + if len(escape) != 6: + raise source.error("incomplete escape %s" % escape, len(escape)) + return LITERAL, int(escape[2:], 16) + elif c == "U" and source.istext: + # unicode escape (exactly eight digits) + escape += source.getwhile(8, HEXDIGITS) + if len(escape) != 10: + raise source.error("incomplete escape %s" % escape, len(escape)) + c = int(escape[2:], 16) + chr(c) # raise ValueError for invalid code + return LITERAL, c + elif c == "N" and source.istext: + import unicodedata + # named unicode escape e.g. \N{EM DASH} + if not source.match('{'): + raise source.error("missing {") + charname = source.getuntil('}', 'character name') + try: + c = ord(unicodedata.lookup(charname)) + except (KeyError, TypeError): + raise source.error("undefined character name %r" % charname, + len(charname) + len(r'\N{}')) from None + return LITERAL, c + elif c in OCTDIGITS: + # octal escape (up to three digits) + escape += source.getwhile(2, OCTDIGITS) + c = int(escape[1:], 8) + if c > 0o377: + raise source.error('octal escape value %s outside of ' + 'range 0-0o377' % escape, len(escape)) + return LITERAL, c + elif c in DIGITS: + raise ValueError + if len(escape) == 2: + if c in ASCIILETTERS: + raise source.error('bad escape %s' % escape, len(escape)) + return LITERAL, ord(escape[1]) + except ValueError: + pass + raise source.error("bad escape %s" % escape, len(escape)) + +def _escape(source, escape, state): + # handle escape code in expression + code = CATEGORIES.get(escape) + if code: + return code + code = ESCAPES.get(escape) + if code: + return code + try: + c = escape[1:2] + if c == "x": + # hexadecimal escape + escape += source.getwhile(2, HEXDIGITS) + if len(escape) != 4: + raise source.error("incomplete escape %s" % escape, len(escape)) + return LITERAL, int(escape[2:], 16) + elif c == "u" and source.istext: + # unicode escape (exactly four digits) + escape += source.getwhile(4, HEXDIGITS) + if len(escape) != 6: + raise source.error("incomplete escape %s" % escape, len(escape)) + return LITERAL, int(escape[2:], 16) + elif c == "U" and source.istext: + # unicode escape (exactly eight digits) + escape += source.getwhile(8, HEXDIGITS) + if len(escape) != 10: + raise source.error("incomplete escape %s" % escape, len(escape)) + c = int(escape[2:], 16) + chr(c) # raise ValueError for invalid code + return LITERAL, c + elif c == "N" and source.istext: + import unicodedata + # named unicode escape e.g. \N{EM DASH} + if not source.match('{'): + raise source.error("missing {") + charname = source.getuntil('}', 'character name') + try: + c = ord(unicodedata.lookup(charname)) + except (KeyError, TypeError): + raise source.error("undefined character name %r" % charname, + len(charname) + len(r'\N{}')) from None + return LITERAL, c + elif c == "0": + # octal escape + escape += source.getwhile(2, OCTDIGITS) + return LITERAL, int(escape[1:], 8) + elif c in DIGITS: + # octal escape *or* decimal group reference (sigh) + if source.next in DIGITS: + escape += source.get() + if (escape[1] in OCTDIGITS and escape[2] in OCTDIGITS and + source.next in OCTDIGITS): + # got three octal digits; this is an octal escape + escape += source.get() + c = int(escape[1:], 8) + if c > 0o377: + raise source.error('octal escape value %s outside of ' + 'range 0-0o377' % escape, + len(escape)) + return LITERAL, c + # not an octal escape, so this is a group reference + group = int(escape[1:]) + if group < state.groups: + if not state.checkgroup(group): + raise source.error("cannot refer to an open group", + len(escape)) + state.checklookbehindgroup(group, source) + return GROUPREF, group + raise source.error("invalid group reference %d" % group, len(escape) - 1) + if len(escape) == 2: + if c in ASCIILETTERS: + raise source.error("bad escape %s" % escape, len(escape)) + return LITERAL, ord(escape[1]) + except ValueError: + pass + raise source.error("bad escape %s" % escape, len(escape)) + +def _uniq(items): + return list(dict.fromkeys(items)) + +def _parse_sub(source, state, verbose, nested): + # parse an alternation: a|b|c + + items = [] + itemsappend = items.append + sourcematch = source.match + start = source.tell() + while True: + itemsappend(_parse(source, state, verbose, nested + 1, + not nested and not items)) + if not sourcematch("|"): + break + if not nested: + verbose = state.flags & SRE_FLAG_VERBOSE + + if len(items) == 1: + return items[0] + + subpattern = SubPattern(state) + + # check if all items share a common prefix + while True: + prefix = None + for item in items: + if not item: + break + if prefix is None: + prefix = item[0] + elif item[0] != prefix: + break + else: + # all subitems start with a common "prefix". + # move it out of the branch + for item in items: + del item[0] + subpattern.append(prefix) + continue # check next one + break + + # check if the branch can be replaced by a character set + set = [] + for item in items: + if len(item) != 1: + break + op, av = item[0] + if op is LITERAL: + set.append((op, av)) + elif op is IN and av[0][0] is not NEGATE: + set.extend(av) + else: + break + else: + # we can store this as a character set instead of a + # branch (the compiler may optimize this even more) + subpattern.append((IN, _uniq(set))) + return subpattern + + subpattern.append((BRANCH, (None, items))) + return subpattern + +def _parse(source, state, verbose, nested, first=False): + # parse a simple pattern + subpattern = SubPattern(state) + + # precompute constants into local variables + subpatternappend = subpattern.append + sourceget = source.get + sourcematch = source.match + _len = len + _ord = ord + + while True: + + this = source.next + if this is None: + break # end of pattern + if this in "|)": + break # end of subpattern + sourceget() + + if verbose: + # skip whitespace and comments + if this in WHITESPACE: + continue + if this == "#": + while True: + this = sourceget() + if this is None or this == "\n": + break + continue + + if this[0] == "\\": + code = _escape(source, this, state) + subpatternappend(code) + + elif this not in SPECIAL_CHARS: + subpatternappend((LITERAL, _ord(this))) + + elif this == "[": + here = source.tell() - 1 + # character set + set = [] + setappend = set.append +## if sourcematch(":"): +## pass # handle character classes + if source.next == '[': + import warnings + warnings.warn( + 'Possible nested set at position %d' % source.tell(), + FutureWarning, stacklevel=nested + 6 + ) + negate = sourcematch("^") + # check remaining characters + while True: + this = sourceget() + if this is None: + raise source.error("unterminated character set", + source.tell() - here) + if this == "]" and set: + break + elif this[0] == "\\": + code1 = _class_escape(source, this) + else: + if set and this in '-&~|' and source.next == this: + import warnings + warnings.warn( + 'Possible set %s at position %d' % ( + 'difference' if this == '-' else + 'intersection' if this == '&' else + 'symmetric difference' if this == '~' else + 'union', + source.tell() - 1), + FutureWarning, stacklevel=nested + 6 + ) + code1 = LITERAL, _ord(this) + if sourcematch("-"): + # potential range + that = sourceget() + if that is None: + raise source.error("unterminated character set", + source.tell() - here) + if that == "]": + if code1[0] is IN: + code1 = code1[1][0] + setappend(code1) + setappend((LITERAL, _ord("-"))) + break + if that[0] == "\\": + code2 = _class_escape(source, that) + else: + if that == '-': + import warnings + warnings.warn( + 'Possible set difference at position %d' % ( + source.tell() - 2), + FutureWarning, stacklevel=nested + 6 + ) + code2 = LITERAL, _ord(that) + if code1[0] != LITERAL or code2[0] != LITERAL: + msg = "bad character range %s-%s" % (this, that) + raise source.error(msg, len(this) + 1 + len(that)) + lo = code1[1] + hi = code2[1] + if hi < lo: + msg = "bad character range %s-%s" % (this, that) + raise source.error(msg, len(this) + 1 + len(that)) + setappend((RANGE, (lo, hi))) + else: + if code1[0] is IN: + code1 = code1[1][0] + setappend(code1) + + set = _uniq(set) + # XXX: should move set optimization to compiler! + if _len(set) == 1 and set[0][0] is LITERAL: + # optimization + if negate: + subpatternappend((NOT_LITERAL, set[0][1])) + else: + subpatternappend(set[0]) + else: + if negate: + set.insert(0, (NEGATE, None)) + # charmap optimization can't be added here because + # global flags still are not known + subpatternappend((IN, set)) + + elif this in REPEAT_CHARS: + # repeat previous item + here = source.tell() + if this == "?": + min, max = 0, 1 + elif this == "*": + min, max = 0, MAXREPEAT + + elif this == "+": + min, max = 1, MAXREPEAT + elif this == "{": + if source.next == "}": + subpatternappend((LITERAL, _ord(this))) + continue + + min, max = 0, MAXREPEAT + lo = hi = "" + while source.next in DIGITS: + lo += sourceget() + if sourcematch(","): + while source.next in DIGITS: + hi += sourceget() + else: + hi = lo + if not sourcematch("}"): + subpatternappend((LITERAL, _ord(this))) + source.seek(here) + continue + + if lo: + min = int(lo) + if min >= MAXREPEAT: + raise OverflowError("the repetition number is too large") + if hi: + max = int(hi) + if max >= MAXREPEAT: + raise OverflowError("the repetition number is too large") + if max < min: + raise source.error("min repeat greater than max repeat", + source.tell() - here) + else: + raise AssertionError("unsupported quantifier %r" % (char,)) + # figure out which item to repeat + if subpattern: + item = subpattern[-1:] + else: + item = None + if not item or item[0][0] is AT: + raise source.error("nothing to repeat", + source.tell() - here + len(this)) + if item[0][0] in _REPEATCODES: + raise source.error("multiple repeat", + source.tell() - here + len(this)) + if item[0][0] is SUBPATTERN: + group, add_flags, del_flags, p = item[0][1] + if group is None and not add_flags and not del_flags: + item = p + if sourcematch("?"): + # Non-Greedy Match + subpattern[-1] = (MIN_REPEAT, (min, max, item)) + elif sourcematch("+"): + # Possessive Match (Always Greedy) + subpattern[-1] = (POSSESSIVE_REPEAT, (min, max, item)) + else: + # Greedy Match + subpattern[-1] = (MAX_REPEAT, (min, max, item)) + + elif this == ".": + subpatternappend((ANY, None)) + + elif this == "(": + start = source.tell() - 1 + capture = True + atomic = False + name = None + add_flags = 0 + del_flags = 0 + if sourcematch("?"): + # options + char = sourceget() + if char is None: + raise source.error("unexpected end of pattern") + if char == "P": + # python extensions + if sourcematch("<"): + # named group: skip forward to end of name + name = source.getuntil(">", "group name") + source.checkgroupname(name, 1) + elif sourcematch("="): + # named backreference + name = source.getuntil(")", "group name") + source.checkgroupname(name, 1) + gid = state.groupdict.get(name) + if gid is None: + msg = "unknown group name %r" % name + raise source.error(msg, len(name) + 1) + if not state.checkgroup(gid): + raise source.error("cannot refer to an open group", + len(name) + 1) + state.checklookbehindgroup(gid, source) + subpatternappend((GROUPREF, gid)) + continue + + else: + char = sourceget() + if char is None: + raise source.error("unexpected end of pattern") + raise source.error("unknown extension ?P" + char, + len(char) + 2) + elif char == ":": + # non-capturing group + capture = False + elif char == "#": + # comment + while True: + if source.next is None: + raise source.error("missing ), unterminated comment", + source.tell() - start) + if sourceget() == ")": + break + continue + + elif char in "=!<": + # lookahead assertions + dir = 1 + if char == "<": + char = sourceget() + if char is None: + raise source.error("unexpected end of pattern") + if char not in "=!": + raise source.error("unknown extension ?<" + char, + len(char) + 2) + dir = -1 # lookbehind + lookbehindgroups = state.lookbehindgroups + if lookbehindgroups is None: + state.lookbehindgroups = state.groups + p = _parse_sub(source, state, verbose, nested + 1) + if dir < 0: + if lookbehindgroups is None: + state.lookbehindgroups = None + if not sourcematch(")"): + raise source.error("missing ), unterminated subpattern", + source.tell() - start) + if char == "=": + subpatternappend((ASSERT, (dir, p))) + else: + subpatternappend((ASSERT_NOT, (dir, p))) + continue + + elif char == "(": + # conditional backreference group + condname = source.getuntil(")", "group name") + if not (condname.isdecimal() and condname.isascii()): + source.checkgroupname(condname, 1) + condgroup = state.groupdict.get(condname) + if condgroup is None: + msg = "unknown group name %r" % condname + raise source.error(msg, len(condname) + 1) + else: + condgroup = int(condname) + if not condgroup: + raise source.error("bad group number", + len(condname) + 1) + if condgroup >= MAXGROUPS: + msg = "invalid group reference %d" % condgroup + raise source.error(msg, len(condname) + 1) + if condgroup not in state.grouprefpos: + state.grouprefpos[condgroup] = ( + source.tell() - len(condname) - 1 + ) + if not (condname.isdecimal() and condname.isascii()): + import warnings + warnings.warn( + "bad character in group name %s at position %d" % + (repr(condname) if source.istext else ascii(condname), + source.tell() - len(condname) - 1), + DeprecationWarning, stacklevel=nested + 6 + ) + state.checklookbehindgroup(condgroup, source) + item_yes = _parse(source, state, verbose, nested + 1) + if source.match("|"): + item_no = _parse(source, state, verbose, nested + 1) + if source.next == "|": + raise source.error("conditional backref with more than two branches") + else: + item_no = None + if not source.match(")"): + raise source.error("missing ), unterminated subpattern", + source.tell() - start) + subpatternappend((GROUPREF_EXISTS, (condgroup, item_yes, item_no))) + continue + + elif char == ">": + # non-capturing, atomic group + capture = False + atomic = True + elif char in FLAGS or char == "-": + # flags + flags = _parse_flags(source, state, char) + if flags is None: # global flags + if not first or subpattern: + raise source.error('global flags not at the start ' + 'of the expression', + source.tell() - start) + verbose = state.flags & SRE_FLAG_VERBOSE + continue + + add_flags, del_flags = flags + capture = False + else: + raise source.error("unknown extension ?" + char, + len(char) + 1) + + # parse group contents + if capture: + try: + group = state.opengroup(name) + except error as err: + raise source.error(err.msg, len(name) + 1) from None + else: + group = None + sub_verbose = ((verbose or (add_flags & SRE_FLAG_VERBOSE)) and + not (del_flags & SRE_FLAG_VERBOSE)) + p = _parse_sub(source, state, sub_verbose, nested + 1) + if not source.match(")"): + raise source.error("missing ), unterminated subpattern", + source.tell() - start) + if group is not None: + state.closegroup(group, p) + if atomic: + assert group is None + subpatternappend((ATOMIC_GROUP, p)) + else: + subpatternappend((SUBPATTERN, (group, add_flags, del_flags, p))) + + elif this == "^": + subpatternappend((AT, AT_BEGINNING)) + + elif this == "$": + subpatternappend((AT, AT_END)) + + else: + raise AssertionError("unsupported special character %r" % (char,)) + + # unpack non-capturing groups + for i in range(len(subpattern))[::-1]: + op, av = subpattern[i] + if op is SUBPATTERN: + group, add_flags, del_flags, p = av + if group is None and not add_flags and not del_flags: + subpattern[i: i+1] = p + + return subpattern + +def _parse_flags(source, state, char): + sourceget = source.get + add_flags = 0 + del_flags = 0 + if char != "-": + while True: + flag = FLAGS[char] + if source.istext: + if char == 'L': + msg = "bad inline flags: cannot use 'L' flag with a str pattern" + raise source.error(msg) + else: + if char == 'u': + msg = "bad inline flags: cannot use 'u' flag with a bytes pattern" + raise source.error(msg) + add_flags |= flag + if (flag & TYPE_FLAGS) and (add_flags & TYPE_FLAGS) != flag: + msg = "bad inline flags: flags 'a', 'u' and 'L' are incompatible" + raise source.error(msg) + char = sourceget() + if char is None: + raise source.error("missing -, : or )") + if char in ")-:": + break + if char not in FLAGS: + msg = "unknown flag" if char.isalpha() else "missing -, : or )" + raise source.error(msg, len(char)) + if char == ")": + state.flags |= add_flags + return None + if add_flags & GLOBAL_FLAGS: + raise source.error("bad inline flags: cannot turn on global flag", 1) + if char == "-": + char = sourceget() + if char is None: + raise source.error("missing flag") + if char not in FLAGS: + msg = "unknown flag" if char.isalpha() else "missing flag" + raise source.error(msg, len(char)) + while True: + flag = FLAGS[char] + if flag & TYPE_FLAGS: + msg = "bad inline flags: cannot turn off flags 'a', 'u' and 'L'" + raise source.error(msg) + del_flags |= flag + char = sourceget() + if char is None: + raise source.error("missing :") + if char == ":": + break + if char not in FLAGS: + msg = "unknown flag" if char.isalpha() else "missing :" + raise source.error(msg, len(char)) + assert char == ":" + if del_flags & GLOBAL_FLAGS: + raise source.error("bad inline flags: cannot turn off global flag", 1) + if add_flags & del_flags: + raise source.error("bad inline flags: flag turned on and off", 1) + return add_flags, del_flags + +def fix_flags(src, flags): + # Check and fix flags according to the type of pattern (str or bytes) + if isinstance(src, str): + if flags & SRE_FLAG_LOCALE: + raise ValueError("cannot use LOCALE flag with a str pattern") + if not flags & SRE_FLAG_ASCII: + flags |= SRE_FLAG_UNICODE + elif flags & SRE_FLAG_UNICODE: + raise ValueError("ASCII and UNICODE flags are incompatible") + else: + if flags & SRE_FLAG_UNICODE: + raise ValueError("cannot use UNICODE flag with a bytes pattern") + if flags & SRE_FLAG_LOCALE and flags & SRE_FLAG_ASCII: + raise ValueError("ASCII and LOCALE flags are incompatible") + return flags + +def parse(str, flags=0, state=None): + # parse 're' pattern into list of (opcode, argument) tuples + + source = Tokenizer(str) + + if state is None: + state = State() + state.flags = flags + state.str = str + + p = _parse_sub(source, state, flags & SRE_FLAG_VERBOSE, 0) + p.state.flags = fix_flags(str, p.state.flags) + + if source.next is not None: + assert source.next == ")" + raise source.error("unbalanced parenthesis") + + for g in p.state.grouprefpos: + if g >= p.state.groups: + msg = "invalid group reference %d" % g + raise error(msg, str, p.state.grouprefpos[g]) + + if flags & SRE_FLAG_DEBUG: + p.dump() + + return p + +def parse_template(source, pattern): + # parse 're' replacement string into list of literals and + # group references + s = Tokenizer(source) + sget = s.get + result = [] + literal = [] + lappend = literal.append + def addliteral(): + if s.istext: + result.append(''.join(literal)) + else: + # The tokenizer implicitly decodes bytes objects as latin-1, we must + # therefore re-encode the final representation. + result.append(''.join(literal).encode('latin-1')) + del literal[:] + def addgroup(index, pos): + if index > pattern.groups: + raise s.error("invalid group reference %d" % index, pos) + addliteral() + result.append(index) + groupindex = pattern.groupindex + while True: + this = sget() + if this is None: + break # end of replacement string + if this[0] == "\\": + # group + c = this[1] + if c == "g": + if not s.match("<"): + raise s.error("missing <") + name = s.getuntil(">", "group name") + if not (name.isdecimal() and name.isascii()): + s.checkgroupname(name, 1) + try: + index = groupindex[name] + except KeyError: + raise IndexError("unknown group name %r" % name) from None + else: + index = int(name) + if index >= MAXGROUPS: + raise s.error("invalid group reference %d" % index, + len(name) + 1) + if not (name.isdecimal() and name.isascii()): + import warnings + warnings.warn( + "bad character in group name %s at position %d" % + (repr(name) if s.istext else ascii(name), + s.tell() - len(name) - 1), + DeprecationWarning, stacklevel=5 + ) + addgroup(index, len(name) + 1) + elif c == "0": + if s.next in OCTDIGITS: + this += sget() + if s.next in OCTDIGITS: + this += sget() + lappend(chr(int(this[1:], 8) & 0xff)) + elif c in DIGITS: + isoctal = False + if s.next in DIGITS: + this += sget() + if (c in OCTDIGITS and this[2] in OCTDIGITS and + s.next in OCTDIGITS): + this += sget() + isoctal = True + c = int(this[1:], 8) + if c > 0o377: + raise s.error('octal escape value %s outside of ' + 'range 0-0o377' % this, len(this)) + lappend(chr(c)) + if not isoctal: + addgroup(int(this[1:]), len(this) - 1) + else: + try: + this = chr(ESCAPES[this][1]) + except KeyError: + if c in ASCIILETTERS: + raise s.error('bad escape %s' % this, len(this)) from None + lappend(this) + else: + lappend(this) + addliteral() + return result diff --git a/Lib/reprlib.py b/Lib/reprlib.py index f3518df105e..a92b3e3dbb6 100644 --- a/Lib/reprlib.py +++ b/Lib/reprlib.py @@ -35,19 +35,24 @@ def recursive_repr(fillvalue='...'): class Repr: - def __init__(self): - self.fillvalue = '...' - self.maxlevel = 6 - self.maxtuple = 6 - self.maxlist = 6 - self.maxarray = 5 - self.maxdict = 4 - self.maxset = 6 - self.maxfrozenset = 6 - self.maxdeque = 6 - self.maxstring = 30 - self.maxlong = 40 - self.maxother = 30 + def __init__( + self, *, maxlevel=6, maxtuple=6, maxlist=6, maxarray=5, maxdict=4, + maxset=6, maxfrozenset=6, maxdeque=6, maxstring=30, maxlong=40, + maxother=30, fillvalue='...', indent=None, + ): + self.maxlevel = maxlevel + self.maxtuple = maxtuple + self.maxlist = maxlist + self.maxarray = maxarray + self.maxdict = maxdict + self.maxset = maxset + self.maxfrozenset = maxfrozenset + self.maxdeque = maxdeque + self.maxstring = maxstring + self.maxlong = maxlong + self.maxother = maxother + self.fillvalue = fillvalue + self.indent = indent def repr(self, x): return self.repr1(x, self.maxlevel) @@ -62,6 +67,26 @@ class Repr: else: return self.repr_instance(x, level) + def _join(self, pieces, level): + if self.indent is None: + return ', '.join(pieces) + if not pieces: + return '' + indent = self.indent + if isinstance(indent, int): + if indent < 0: + raise ValueError( + f'Repr.indent cannot be negative int (was {indent!r})' + ) + indent *= ' ' + try: + sep = ',\n' + (self.maxlevel - level + 1) * indent + except TypeError as error: + raise TypeError( + f'Repr.indent must be a str, int or None, not {type(indent)}' + ) from error + return sep.join(('', *pieces, ''))[1:-len(indent) or None] + def _repr_iterable(self, x, level, left, right, maxiter, trail=''): n = len(x) if level <= 0 and n: @@ -72,8 +97,8 @@ class Repr: pieces = [repr1(elem, newlevel) for elem in islice(x, maxiter)] if n > maxiter: pieces.append(self.fillvalue) - s = ', '.join(pieces) - if n == 1 and trail: + s = self._join(pieces, level) + if n == 1 and trail and self.indent is None: right = trail + right return '%s%s%s' % (left, s, right) @@ -120,7 +145,7 @@ class Repr: pieces.append('%s: %s' % (keyrepr, valrepr)) if n > self.maxdict: pieces.append(self.fillvalue) - s = ', '.join(pieces) + s = self._join(pieces, level) return '{%s}' % (s,) def repr_str(self, x, level): diff --git a/Lib/rlcompleter.py b/Lib/rlcompleter.py index 98b7930b32f..206d6fb511c 100644 --- a/Lib/rlcompleter.py +++ b/Lib/rlcompleter.py @@ -32,6 +32,8 @@ Notes: import atexit import builtins import inspect +import keyword +import re import __main__ __all__ = ["Completer"] @@ -113,18 +115,17 @@ class Completer: defined in self.namespace that match. """ - import keyword matches = [] seen = {"__builtins__"} n = len(text) - for word in keyword.kwlist: + for word in keyword.kwlist + keyword.softkwlist: if word[:n] == text: seen.add(word) if word in {'finally', 'try'}: word = word + ':' elif word not in {'False', 'None', 'True', 'break', 'continue', 'pass', - 'else'}: + 'else', '_'}: word = word + ' ' matches.append(word) for nspace in [self.namespace, builtins.__dict__]: @@ -146,7 +147,6 @@ class Completer: with a __getattr__ hook is evaluated. """ - import re m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text) if not m: return [] diff --git a/Lib/runpy.py b/Lib/runpy.py index caba1214262..54fc136d407 100644 --- a/Lib/runpy.py +++ b/Lib/runpy.py @@ -14,18 +14,20 @@ import sys import importlib.machinery # importlib first so we can test #15386 via -m import importlib.util import io -import types import os __all__ = [ "run_module", "run_path", ] +# avoid 'import types' just for ModuleType +ModuleType = type(sys) + class _TempModule(object): """Temporarily replace a module in sys.modules with an empty namespace""" def __init__(self, mod_name): self.mod_name = mod_name - self.module = types.ModuleType(mod_name) + self.module = ModuleType(mod_name) self._saved_module = [] def __enter__(self): @@ -198,9 +200,24 @@ def _run_module_as_main(mod_name, alter_argv=True): def run_module(mod_name, init_globals=None, run_name=None, alter_sys=False): - """Execute a module's code without importing it + """Execute a module's code without importing it. - Returns the resulting top level namespace dictionary + mod_name -- an absolute module name or package name. + + Optional arguments: + init_globals -- dictionary used to pre-populate the module’s + globals dictionary before the code is executed. + + run_name -- if not None, this will be used for setting __name__; + otherwise, __name__ will be set to mod_name + '__main__' if the + named module is a package and to just mod_name otherwise. + + alter_sys -- if True, sys.argv[0] is updated with the value of + __file__ and sys.modules[__name__] is updated with a temporary + module object for the module being executed. Both are + restored to their original values before the function returns. + + Returns the resulting module globals dictionary. """ mod_name, mod_spec, code = _get_module_details(mod_name) if run_name is None: @@ -243,14 +260,19 @@ def _get_code_from_file(run_name, fname): return code, fname def run_path(path_name, init_globals=None, run_name=None): - """Execute code located at the specified filesystem location + """Execute code located at the specified filesystem location. - Returns the resulting top level namespace dictionary + path_name -- filesystem location of a Python script, zipfile, + or directory containing a top level __main__.py script. - The file path may refer directly to a Python script (i.e. - one that could be directly executed with execfile) or else - it may refer to a zipfile or directory containing a top - level __main__.py script. + Optional arguments: + init_globals -- dictionary used to pre-populate the module’s + globals dictionary before the code is executed. + + run_name -- if not None, this will be used to set __name__; + otherwise, '' will be used for __name__. + + Returns the resulting module globals dictionary. """ if run_name is None: run_name = "" diff --git a/Lib/secrets.py b/Lib/secrets.py index a546efbdd42..566a09b7311 100644 --- a/Lib/secrets.py +++ b/Lib/secrets.py @@ -2,7 +2,7 @@ managing secrets such as account authentication, tokens, and similar. See PEP 506 for more information. -https://www.python.org/dev/peps/pep-0506/ +https://peps.python.org/pep-0506/ """ @@ -13,7 +13,6 @@ __all__ = ['choice', 'randbelow', 'randbits', 'SystemRandom', import base64 -import binascii from hmac import compare_digest from random import SystemRandom @@ -56,7 +55,7 @@ def token_hex(nbytes=None): 'f9bf78b9a18ce6d46a0cd2b0b86df9da' """ - return binascii.hexlify(token_bytes(nbytes)).decode('ascii') + return token_bytes(nbytes).hex() def token_urlsafe(nbytes=None): """Return a random URL-safe text string, in Base64 encoding. diff --git a/Lib/selectors.py b/Lib/selectors.py index bb15a1cb1ba..af6a4f94b50 100644 --- a/Lib/selectors.py +++ b/Lib/selectors.py @@ -50,12 +50,11 @@ SelectorKey.__doc__ = """SelectorKey(fileobj, fd, events, data) Object used to associate a file object to its backing file descriptor, selected event mask, and attached data. """ -if sys.version_info >= (3, 5): - SelectorKey.fileobj.__doc__ = 'File object registered.' - SelectorKey.fd.__doc__ = 'Underlying file descriptor.' - SelectorKey.events.__doc__ = 'Events that must be waited for on this file object.' - SelectorKey.data.__doc__ = ('''Optional opaque data associated to this file object. - For example, this could be used to store a per-client session ID.''') +SelectorKey.fileobj.__doc__ = 'File object registered.' +SelectorKey.fd.__doc__ = 'Underlying file descriptor.' +SelectorKey.events.__doc__ = 'Events that must be waited for on this file object.' +SelectorKey.data.__doc__ = ('''Optional opaque data associated to this file object. +For example, this could be used to store a per-client session ID.''') class _SelectorMapping(Mapping): diff --git a/Lib/shlex.py b/Lib/shlex.py index 4801a6c1d47..f4821616b62 100644 --- a/Lib/shlex.py +++ b/Lib/shlex.py @@ -305,9 +305,7 @@ class shlex: def split(s, comments=False, posix=True): """Split the string *s* using shell-like syntax.""" if s is None: - import warnings - warnings.warn("Passing None for 's' to shlex.split() is deprecated.", - DeprecationWarning, stacklevel=2) + raise ValueError("s argument must not be None") lex = shlex(s, posix=posix) lex.whitespace_split = True if not comments: @@ -335,10 +333,7 @@ def quote(s): def _print_tokens(lexer): - while 1: - tt = lexer.get_token() - if not tt: - break + while tt := lexer.get_token(): print("Token: " + repr(tt)) if __name__ == '__main__': diff --git a/Lib/shutil.py b/Lib/shutil.py index 949e024853c..867925aa10c 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -182,7 +182,8 @@ def _copyfileobj_readinto(fsrc, fdst, length=COPY_BUFSIZE): break elif n < length: with mv[:n] as smv: - fdst.write(smv) + fdst_write(smv) + break else: fdst_write(mv) @@ -193,10 +194,7 @@ def copyfileobj(fsrc, fdst, length=0): # Localize variable access to minimize overhead. fsrc_read = fsrc.read fdst_write = fdst.write - while True: - buf = fsrc_read(length) - if not buf: - break + while buf := fsrc_read(length): fdst_write(buf) def _samefile(src, dst): @@ -489,12 +487,13 @@ def _copytree(entries, src, dst, symlinks, ignore, copy_function, # otherwise let the copy occur. copy2 will raise an error if srcentry.is_dir(): copytree(srcobj, dstname, symlinks, ignore, - copy_function, dirs_exist_ok=dirs_exist_ok) + copy_function, ignore_dangling_symlinks, + dirs_exist_ok) else: copy_function(srcobj, dstname) elif srcentry.is_dir(): copytree(srcobj, dstname, symlinks, ignore, copy_function, - dirs_exist_ok=dirs_exist_ok) + ignore_dangling_symlinks, dirs_exist_ok) else: # Will raise a SpecialFileError for unsupported file types copy_function(srcobj, dstname) @@ -518,9 +517,6 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False, dirs_exist_ok=False): """Recursively copy a directory tree and return the destination directory. - dirs_exist_ok dictates whether to raise an exception in case dst or any - missing parent directory already exists. - If exception(s) occur, an Error is raised with a list of reasons. If the optional symlinks flag is true, symbolic links in the @@ -551,6 +547,11 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, destination path as arguments. By default, copy2() is used, but any function that supports the same signature (like copy()) can be used. + If dirs_exist_ok is false (the default) and `dst` already exists, a + `FileExistsError` is raised. If `dirs_exist_ok` is true, the copying + operation will continue if it encounters existing directories, and files + within the `dst` tree will be overwritten by corresponding files from the + `src` tree. """ sys.audit("shutil.copytree", src, dst) with os.scandir(src) as itr: @@ -561,18 +562,6 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, dirs_exist_ok=dirs_exist_ok) if hasattr(os.stat_result, 'st_file_attributes'): - # Special handling for directory junctions to make them behave like - # symlinks for shutil.rmtree, since in general they do not appear as - # regular links. - def _rmtree_isdir(entry): - try: - st = entry.stat(follow_symlinks=False) - return (stat.S_ISDIR(st.st_mode) and not - (st.st_file_attributes & stat.FILE_ATTRIBUTE_REPARSE_POINT - and st.st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT)) - except OSError: - return False - def _rmtree_islink(path): try: st = os.lstat(path) @@ -582,12 +571,6 @@ if hasattr(os.stat_result, 'st_file_attributes'): except OSError: return False else: - def _rmtree_isdir(entry): - try: - return entry.is_dir(follow_symlinks=False) - except OSError: - return False - def _rmtree_islink(path): return os.path.islink(path) @@ -601,7 +584,12 @@ def _rmtree_unsafe(path, onerror): entries = [] for entry in entries: fullname = entry.path - if _rmtree_isdir(entry): + try: + is_dir = entry.is_dir(follow_symlinks=False) + except OSError: + is_dir = False + + if is_dir and not entry.is_junction(): try: if entry.is_symlink(): # This can only happen if someone replaces @@ -648,6 +636,7 @@ def _rmtree_safe_fd(topfd, path, onerror): if is_dir: try: dirfd = os.open(entry.name, os.O_RDONLY, dir_fd=topfd) + dirfd_closed = False except OSError: onerror(os.open, fullname, sys.exc_info()) else: @@ -655,6 +644,8 @@ def _rmtree_safe_fd(topfd, path, onerror): if os.path.samestat(orig_st, os.fstat(dirfd)): _rmtree_safe_fd(dirfd, fullname, onerror) try: + os.close(dirfd) + dirfd_closed = True os.rmdir(entry.name, dir_fd=topfd) except OSError: onerror(os.rmdir, fullname, sys.exc_info()) @@ -668,7 +659,8 @@ def _rmtree_safe_fd(topfd, path, onerror): except OSError: onerror(os.path.islink, fullname, sys.exc_info()) finally: - os.close(dirfd) + if not dirfd_closed: + os.close(dirfd) else: try: os.unlink(entry.name, dir_fd=topfd) @@ -680,9 +672,14 @@ _use_fd_functions = ({os.open, os.stat, os.unlink, os.rmdir} <= os.scandir in os.supports_fd and os.stat in os.supports_follow_symlinks) -def rmtree(path, ignore_errors=False, onerror=None): +def rmtree(path, ignore_errors=False, onerror=None, *, dir_fd=None): """Recursively delete a directory tree. + If dir_fd is not None, it should be a file descriptor open to a directory; + path will then be relative to that directory. + dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. + If ignore_errors is set, errors are ignored; otherwise, if onerror is set, it is called to handle the error with arguments (func, path, exc_info) where func is platform and implementation dependent; @@ -691,7 +688,7 @@ def rmtree(path, ignore_errors=False, onerror=None): is false and onerror is None, an exception is raised. """ - sys.audit("shutil.rmtree", path) + sys.audit("shutil.rmtree", path, dir_fd) if ignore_errors: def onerror(*args): pass @@ -705,12 +702,13 @@ def rmtree(path, ignore_errors=False, onerror=None): # Note: To guard against symlink races, we use the standard # lstat()/open()/fstat() trick. try: - orig_st = os.lstat(path) + orig_st = os.lstat(path, dir_fd=dir_fd) except Exception: onerror(os.lstat, path, sys.exc_info()) return try: - fd = os.open(path, os.O_RDONLY) + fd = os.open(path, os.O_RDONLY, dir_fd=dir_fd) + fd_closed = False except Exception: onerror(os.open, path, sys.exc_info()) return @@ -718,7 +716,9 @@ def rmtree(path, ignore_errors=False, onerror=None): if os.path.samestat(orig_st, os.fstat(fd)): _rmtree_safe_fd(fd, path, onerror) try: - os.rmdir(path) + os.close(fd) + fd_closed = True + os.rmdir(path, dir_fd=dir_fd) except OSError: onerror(os.rmdir, path, sys.exc_info()) else: @@ -728,8 +728,11 @@ def rmtree(path, ignore_errors=False, onerror=None): except OSError: onerror(os.path.islink, path, sys.exc_info()) finally: - os.close(fd) + if not fd_closed: + os.close(fd) else: + if dir_fd is not None: + raise NotImplementedError("dir_fd unavailable on this platform") try: if _rmtree_islink(path): # symlinks to directories are forbidden, see bug #1669 @@ -879,7 +882,7 @@ def _get_uid(name): return None def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, - owner=None, group=None, logger=None): + owner=None, group=None, logger=None, root_dir=None): """Create a (possibly compressed) tar file from all the files under 'base_dir'. @@ -936,14 +939,20 @@ def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, if not dry_run: tar = tarfile.open(archive_name, 'w|%s' % tar_compression) + arcname = base_dir + if root_dir is not None: + base_dir = os.path.join(root_dir, base_dir) try: - tar.add(base_dir, filter=_set_uid_gid) + tar.add(base_dir, arcname, filter=_set_uid_gid) finally: tar.close() + if root_dir is not None: + archive_name = os.path.abspath(archive_name) return archive_name -def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): +def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, + logger=None, owner=None, group=None, root_dir=None): """Create a zip file from all the files under 'base_dir'. The output zip file will be named 'base_name' + ".zip". Returns the @@ -967,28 +976,48 @@ def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): if not dry_run: with zipfile.ZipFile(zip_filename, "w", compression=zipfile.ZIP_DEFLATED) as zf: - path = os.path.normpath(base_dir) - if path != os.curdir: - zf.write(path, path) + arcname = os.path.normpath(base_dir) + if root_dir is not None: + base_dir = os.path.join(root_dir, base_dir) + base_dir = os.path.normpath(base_dir) + if arcname != os.curdir: + zf.write(base_dir, arcname) if logger is not None: - logger.info("adding '%s'", path) + logger.info("adding '%s'", base_dir) for dirpath, dirnames, filenames in os.walk(base_dir): + arcdirpath = dirpath + if root_dir is not None: + arcdirpath = os.path.relpath(arcdirpath, root_dir) + arcdirpath = os.path.normpath(arcdirpath) for name in sorted(dirnames): - path = os.path.normpath(os.path.join(dirpath, name)) - zf.write(path, path) + path = os.path.join(dirpath, name) + arcname = os.path.join(arcdirpath, name) + zf.write(path, arcname) if logger is not None: logger.info("adding '%s'", path) for name in filenames: - path = os.path.normpath(os.path.join(dirpath, name)) + path = os.path.join(dirpath, name) + path = os.path.normpath(path) if os.path.isfile(path): - zf.write(path, path) + arcname = os.path.join(arcdirpath, name) + zf.write(path, arcname) if logger is not None: logger.info("adding '%s'", path) + if root_dir is not None: + zip_filename = os.path.abspath(zip_filename) return zip_filename +_make_tarball.supports_root_dir = True +_make_zipfile.supports_root_dir = True + +# Maps the name of the archive format to a tuple containing: +# * the archiving function +# * extra keyword arguments +# * description _ARCHIVE_FORMATS = { - 'tar': (_make_tarball, [('compress', None)], "uncompressed tar file"), + 'tar': (_make_tarball, [('compress', None)], + "uncompressed tar file"), } if _ZLIB_SUPPORTED: @@ -1057,36 +1086,40 @@ def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, uses the current owner and group. """ sys.audit("shutil.make_archive", base_name, format, root_dir, base_dir) - save_cwd = os.getcwd() - if root_dir is not None: - if logger is not None: - logger.debug("changing into '%s'", root_dir) - base_name = os.path.abspath(base_name) - if not dry_run: - os.chdir(root_dir) - - if base_dir is None: - base_dir = os.curdir - - kwargs = {'dry_run': dry_run, 'logger': logger} - try: format_info = _ARCHIVE_FORMATS[format] except KeyError: raise ValueError("unknown archive format '%s'" % format) from None + kwargs = {'dry_run': dry_run, 'logger': logger, + 'owner': owner, 'group': group} + func = format_info[0] for arg, val in format_info[1]: kwargs[arg] = val - if format != 'zip': - kwargs['owner'] = owner - kwargs['group'] = group + if base_dir is None: + base_dir = os.curdir + + supports_root_dir = getattr(func, 'supports_root_dir', False) + save_cwd = None + if root_dir is not None: + if supports_root_dir: + # Support path-like base_name here for backwards-compatibility. + base_name = os.fspath(base_name) + kwargs['root_dir'] = root_dir + else: + save_cwd = os.getcwd() + if logger is not None: + logger.debug("changing into '%s'", root_dir) + base_name = os.path.abspath(base_name) + if not dry_run: + os.chdir(root_dir) try: filename = func(base_name, base_dir, **kwargs) finally: - if root_dir is not None: + if save_cwd is not None: if logger is not None: logger.debug("changing back to '%s'", save_cwd) os.chdir(save_cwd) @@ -1199,6 +1232,11 @@ def _unpack_tarfile(filename, extract_dir): finally: tarobj.close() +# Maps the name of the unpack format to a tuple containing: +# * extensions +# * the unpacking function +# * extra keyword arguments +# * description _UNPACK_FORMATS = { 'tar': (['.tar'], _unpack_tarfile, [], "uncompressed tar file"), 'zip': (['.zip'], _unpack_zipfile, [], "ZIP file"), diff --git a/Lib/signal.py b/Lib/signal.py index d4a6d6fe2ad..50b215b29d2 100644 --- a/Lib/signal.py +++ b/Lib/signal.py @@ -1,6 +1,5 @@ import _signal from _signal import * -from functools import wraps as _wraps from enum import IntEnum as _IntEnum _globals = globals() @@ -42,6 +41,16 @@ def _enum_to_int(value): return value +# Similar to functools.wraps(), but only assign __doc__. +# __module__ should be preserved, +# __name__ and __qualname__ are already fine, +# __annotations__ is not set. +def _wraps(wrapped): + def decorator(wrapper): + wrapper.__doc__ = wrapped.__doc__ + return wrapper + return decorator + @_wraps(_signal.signal) def signal(signalnum, handler): handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler)) @@ -59,7 +68,6 @@ if 'pthread_sigmask' in _globals: def pthread_sigmask(how, mask): sigs_set = _signal.pthread_sigmask(how, mask) return set(_int_to_enum(x, Signals) for x in sigs_set) - pthread_sigmask.__doc__ = _signal.pthread_sigmask.__doc__ if 'sigpending' in _globals: @@ -73,7 +81,6 @@ if 'sigwait' in _globals: def sigwait(sigset): retsig = _signal.sigwait(sigset) return _int_to_enum(retsig, Signals) - sigwait.__doc__ = _signal.sigwait if 'valid_signals' in _globals: diff --git a/Lib/site.py b/Lib/site.py index e129f3b4851..7faf1c6f6af 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -266,8 +266,8 @@ def _getuserbase(): if env_base: return env_base - # VxWorks has no home directories - if sys.platform == "vxworks": + # Emscripten, VxWorks, and WASI have no home directories + if sys.platform in {"emscripten", "vxworks", "wasi"}: return None def joinuser(*args): @@ -361,11 +361,11 @@ def getsitepackages(prefixes=None): continue seen.add(prefix) - libdirs = [sys.platlibdir] - if sys.platlibdir != "lib": - libdirs.append("lib") - if os.sep == '/': + libdirs = [sys.platlibdir] + if sys.platlibdir != "lib": + libdirs.append("lib") + for libdir in libdirs: path = os.path.join(prefix, libdir, "python%d.%d" % sys.version_info[:2], @@ -373,10 +373,7 @@ def getsitepackages(prefixes=None): sitepackages.append(path) else: sitepackages.append(prefix) - - for libdir in libdirs: - path = os.path.join(prefix, libdir, "site-packages") - sitepackages.append(path) + sitepackages.append(os.path.join(prefix, "Lib", "site-packages")) return sitepackages def addsitepackages(known_paths, prefixes=None): @@ -407,12 +404,7 @@ def setquit(): def setcopyright(): """Set 'copyright' and 'credits' in builtins""" builtins.copyright = _sitebuiltins._Printer("copyright", sys.copyright) - if sys.platform[:4] == 'java': - builtins.credits = _sitebuiltins._Printer( - "credits", - "Jython is maintained by the Jython developers (www.jython.org).") - else: - builtins.credits = _sitebuiltins._Printer("credits", """\ + builtins.credits = _sitebuiltins._Printer("credits", """\ Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands for supporting Python development. See www.python.org for more information.""") files, dirs = [], [] diff --git a/Lib/smtplib.py b/Lib/smtplib.py index 324a1c19f12..18c91746fd7 100755 --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -749,14 +749,14 @@ class SMTP: # We could not login successfully. Return result of last attempt. raise last_exception - def starttls(self, keyfile=None, certfile=None, context=None): + def starttls(self, *, context=None): """Puts the connection to the SMTP server into TLS mode. If there has been no previous EHLO or HELO command this session, this method tries ESMTP EHLO first. If the server supports TLS, this will encrypt the rest of the SMTP - session. If you provide the keyfile and certfile parameters, + session. If you provide the context parameter, the identity of the SMTP server and client can be checked. This, however, depends on whether the socket module really checks the certificates. @@ -774,19 +774,8 @@ class SMTP: if resp == 220: if not _have_ssl: raise RuntimeError("No SSL support included in this Python") - if context is not None and keyfile is not None: - raise ValueError("context and keyfile arguments are mutually " - "exclusive") - if context is not None and certfile is not None: - raise ValueError("context and certfile arguments are mutually " - "exclusive") - if keyfile is not None or certfile is not None: - import warnings - warnings.warn("keyfile and certfile are deprecated, use a " - "custom context instead", DeprecationWarning, 2) if context is None: - context = ssl._create_stdlib_context(certfile=certfile, - keyfile=keyfile) + context = ssl._create_stdlib_context() self.sock = context.wrap_socket(self.sock, server_hostname=self._host) self.file = None @@ -1017,35 +1006,18 @@ if _have_ssl: compiled with SSL support). If host is not specified, '' (the local host) is used. If port is omitted, the standard SMTP-over-SSL port (465) is used. local_hostname and source_address have the same meaning - as they do in the SMTP class. keyfile and certfile are also optional - - they can contain a PEM formatted private key and certificate chain file - for the SSL connection. context also optional, can contain a - SSLContext, and is an alternative to keyfile and certfile; If it is - specified both keyfile and certfile must be None. + as they do in the SMTP class. context also optional, can contain a + SSLContext. """ default_port = SMTP_SSL_PORT def __init__(self, host='', port=0, local_hostname=None, - keyfile=None, certfile=None, - timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + *, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None, context=None): - if context is not None and keyfile is not None: - raise ValueError("context and keyfile arguments are mutually " - "exclusive") - if context is not None and certfile is not None: - raise ValueError("context and certfile arguments are mutually " - "exclusive") - if keyfile is not None or certfile is not None: - import warnings - warnings.warn("keyfile and certfile are deprecated, use a " - "custom context instead", DeprecationWarning, 2) - self.keyfile = keyfile - self.certfile = certfile if context is None: - context = ssl._create_stdlib_context(certfile=certfile, - keyfile=keyfile) + context = ssl._create_stdlib_context() self.context = context SMTP.__init__(self, host, port, local_hostname, timeout, source_address) @@ -1127,10 +1099,7 @@ if __name__ == '__main__': toaddrs = prompt("To").split(',') print("Enter message, end with ^D:") msg = '' - while 1: - line = sys.stdin.readline() - if not line: - break + while line := sys.stdin.readline(): msg = msg + line print("Message length is %d" % len(msg)) diff --git a/Lib/sndhdr.py b/Lib/sndhdr.py index 96595c69744..45def9ad16d 100644 --- a/Lib/sndhdr.py +++ b/Lib/sndhdr.py @@ -27,6 +27,10 @@ option -r tells it to recurse down directories found inside explicitly given directories. """ +import warnings + +warnings._deprecated(__name__, remove=(3, 13)) + # The file structure is top-down except that the test program and its # subroutine come last. @@ -73,7 +77,10 @@ def whathdr(filename): tests = [] def test_aifc(h, f): - import aifc + """AIFC and AIFF files""" + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=DeprecationWarning) + import aifc if not h.startswith(b'FORM'): return None if h[8:12] == b'AIFC': @@ -94,6 +101,7 @@ tests.append(test_aifc) def test_au(h, f): + """AU and SND files""" if h.startswith(b'.snd'): func = get_long_be elif h[:4] in (b'\0ds.', b'dns.'): @@ -127,6 +135,7 @@ tests.append(test_au) def test_hcom(h, f): + """HCOM file""" if h[65:69] != b'FSSD' or h[128:132] != b'HCOM': return None divisor = get_long_be(h[144:148]) @@ -140,6 +149,7 @@ tests.append(test_hcom) def test_voc(h, f): + """VOC file""" if not h.startswith(b'Creative Voice File\032'): return None sbseek = get_short_le(h[20:22]) @@ -154,6 +164,7 @@ tests.append(test_voc) def test_wav(h, f): + """WAV file""" import wave # 'RIFF' 'WAVE' 'fmt ' if not h.startswith(b'RIFF') or h[8:12] != b'WAVE' or h[12:16] != b'fmt ': @@ -170,6 +181,7 @@ tests.append(test_wav) def test_8svx(h, f): + """8SVX file""" if not h.startswith(b'FORM') or h[8:12] != b'8SVX': return None # Should decode it to get #channels -- assume always 1 @@ -179,6 +191,7 @@ tests.append(test_8svx) def test_sndt(h, f): + """SNDT file""" if h.startswith(b'SOUND'): nsamples = get_long_le(h[8:12]) rate = get_short_le(h[20:22]) @@ -188,6 +201,7 @@ tests.append(test_sndt) def test_sndr(h, f): + """SNDR file""" if h.startswith(b'\0\0'): rate = get_short_le(h[2:4]) if 4000 <= rate <= 25000: diff --git a/Lib/socket.py b/Lib/socket.py old mode 100755 new mode 100644 index ef82c496cb8..3a4f94de9cc --- a/Lib/socket.py +++ b/Lib/socket.py @@ -28,6 +28,7 @@ socket.getdefaulttimeout() -- get the default timeout value socket.setdefaulttimeout() -- set the default timeout value create_connection() -- connects to an address, with an optional timeout and optional source address. +create_server() -- create a TCP socket and bind it to a specified address. [*] not available on all platforms! @@ -122,7 +123,7 @@ if sys.platform.lower().startswith("win"): errorTab[10014] = "A fault occurred on the network??" # WSAEFAULT errorTab[10022] = "An invalid operation was attempted." errorTab[10024] = "Too many open files." - errorTab[10035] = "The socket operation would block" + errorTab[10035] = "The socket operation would block." errorTab[10036] = "A blocking operation is already in progress." errorTab[10037] = "Operation already in progress." errorTab[10038] = "Socket operation on nonsocket." @@ -254,17 +255,18 @@ class socket(_socket.socket): self.type, self.proto) if not closed: + # getsockname and getpeername may not be available on WASI. try: laddr = self.getsockname() if laddr: s += ", laddr=%s" % str(laddr) - except error: + except (error, AttributeError): pass try: raddr = self.getpeername() if raddr: s += ", raddr=%s" % str(raddr) - except error: + except (error, AttributeError): pass s += '>' return s @@ -783,11 +785,11 @@ def getfqdn(name=''): First the hostname returned by gethostbyaddr() is checked, then possibly existing aliases. In case no FQDN is available and `name` - was given, it is returned unchanged. If `name` was empty or '0.0.0.0', + was given, it is returned unchanged. If `name` was empty, '0.0.0.0' or '::', hostname from gethostname() is returned. """ name = name.strip() - if not name or name == '0.0.0.0': + if not name or name in ('0.0.0.0', '::'): name = gethostname() try: hostname, aliases, ipaddrs = gethostbyaddr(name) @@ -806,7 +808,7 @@ def getfqdn(name=''): _GLOBAL_DEFAULT_TIMEOUT = object() def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT, - source_address=None): + source_address=None, *, all_errors=False): """Connect to *address* and return the socket object. Convenience function. Connect to *address* (a 2-tuple ``(host, @@ -816,11 +818,13 @@ def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT, global default timeout setting returned by :func:`getdefaulttimeout` is used. If *source_address* is set it must be a tuple of (host, port) for the socket to bind as a source address before making the connection. - A host of '' or port 0 tells the OS to use the default. + A host of '' or port 0 tells the OS to use the default. When a connection + cannot be created, raises the last error if *all_errors* is False, + and an ExceptionGroup of all errors if *all_errors* is True. """ host, port = address - err = None + exceptions = [] for res in getaddrinfo(host, port, 0, SOCK_STREAM): af, socktype, proto, canonname, sa = res sock = None @@ -832,20 +836,24 @@ def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT, sock.bind(source_address) sock.connect(sa) # Break explicitly a reference cycle - err = None + exceptions.clear() return sock - except error as _: - err = _ + except error as exc: + if not all_errors: + exceptions.clear() # raise only the last error + exceptions.append(exc) if sock is not None: sock.close() - if err is not None: + if len(exceptions): try: - raise err + if not all_errors: + raise exceptions[0] + raise ExceptionGroup("create_connection failed", exceptions) finally: # Break explicitly a reference cycle - err = None + exceptions.clear() else: raise error("getaddrinfo returns an empty list") diff --git a/Lib/socketserver.py b/Lib/socketserver.py index 0d9583d56a4..842d526b011 100644 --- a/Lib/socketserver.py +++ b/Lib/socketserver.py @@ -187,6 +187,7 @@ class BaseServer: - address_family - socket_type - allow_reuse_address + - allow_reuse_port Instance variables: @@ -291,8 +292,7 @@ class BaseServer: selector.register(self, selectors.EVENT_READ) while True: - ready = selector.select(timeout) - if ready: + if selector.select(timeout): return self._handle_request_noblock() else: if timeout is not None: @@ -425,6 +425,7 @@ class TCPServer(BaseServer): - socket_type - request_queue_size (only for stream sockets) - allow_reuse_address + - allow_reuse_port Instance variables: @@ -442,6 +443,8 @@ class TCPServer(BaseServer): allow_reuse_address = False + allow_reuse_port = False + def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): """Constructor. May be extended, do not override.""" BaseServer.__init__(self, server_address, RequestHandlerClass) @@ -461,8 +464,10 @@ class TCPServer(BaseServer): May be overridden. """ - if self.allow_reuse_address: + if self.allow_reuse_address and hasattr(socket, "SO_REUSEADDR"): self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + if self.allow_reuse_port and hasattr(socket, "SO_REUSEPORT"): + self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) self.socket.bind(self.server_address) self.server_address = self.socket.getsockname() @@ -519,6 +524,8 @@ class UDPServer(TCPServer): allow_reuse_address = False + allow_reuse_port = False + socket_type = socket.SOCK_DGRAM max_packet_size = 8192 diff --git a/Lib/sqlite3/__init__.py b/Lib/sqlite3/__init__.py index 0dedf186b1a..927267cf0b9 100644 --- a/Lib/sqlite3/__init__.py +++ b/Lib/sqlite3/__init__.py @@ -21,7 +21,7 @@ # 3. This notice may not be removed or altered from any source distribution. """ -The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compilant +The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compliant interface to the SQLite library, and requires SQLite 3.7.15 or newer. To use the module, start by creating a database Connection object: @@ -55,17 +55,16 @@ The sqlite3 module is written by Gerhard Häring . """ from sqlite3.dbapi2 import * +from sqlite3.dbapi2 import (_deprecated_names, + _deprecated_version_info, + _deprecated_version) -# bpo-42264: OptimizedUnicode was deprecated in Python 3.10. It's scheduled -# for removal in Python 3.12. def __getattr__(name): - if name == "OptimizedUnicode": - import warnings - msg = (""" - OptimizedUnicode is deprecated and will be removed in Python 3.12. - Since Python 3.3 it has simply been an alias for 'str'. - """) - warnings.warn(msg, DeprecationWarning, stacklevel=2) - return str - raise AttributeError(f"module 'sqlite3' has no attribute '{name}'") + if name in _deprecated_names: + from warnings import warn + + warn(f"{name} is deprecated and will be removed in Python 3.14", + DeprecationWarning, stacklevel=2) + return globals()[f"_deprecated_{name}"] + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/sqlite3/__main__.py b/Lib/sqlite3/__main__.py new file mode 100644 index 00000000000..f8a5cca24e5 --- /dev/null +++ b/Lib/sqlite3/__main__.py @@ -0,0 +1,120 @@ +"""A simple SQLite CLI for the sqlite3 module. + +Apart from using 'argparse' for the command-line interface, +this module implements the REPL as a thin wrapper around +the InteractiveConsole class from the 'code' stdlib module. +""" +import sqlite3 +import sys + +from argparse import ArgumentParser +from code import InteractiveConsole +from textwrap import dedent + + +def execute(c, sql, suppress_errors=True): + """Helper that wraps execution of SQL code. + + This is used both by the REPL and by direct execution from the CLI. + + 'c' may be a cursor or a connection. + 'sql' is the SQL string to execute. + """ + + try: + for row in c.execute(sql): + print(row) + except sqlite3.Error as e: + tp = type(e).__name__ + try: + print(f"{tp} ({e.sqlite_errorname}): {e}", file=sys.stderr) + except AttributeError: + print(f"{tp}: {e}", file=sys.stderr) + if not suppress_errors: + sys.exit(1) + + +class SqliteInteractiveConsole(InteractiveConsole): + """A simple SQLite REPL.""" + + def __init__(self, connection): + super().__init__() + self._con = connection + self._cur = connection.cursor() + + def runsource(self, source, filename="", symbol="single"): + """Override runsource, the core of the InteractiveConsole REPL. + + Return True if more input is needed; buffering is done automatically. + Return False is input is a complete statement ready for execution. + """ + match source: + case ".version": + print(f"{sqlite3.sqlite_version}") + case ".help": + print("Enter SQL code and press enter.") + case ".quit": + sys.exit(0) + case _: + if not sqlite3.complete_statement(source): + return True + execute(self._cur, source) + return False + + +def main(): + parser = ArgumentParser( + description="Python sqlite3 CLI", + prog="python -m sqlite3", + ) + parser.add_argument( + "filename", type=str, default=":memory:", nargs="?", + help=( + "SQLite database to open (defaults to ':memory:'). " + "A new database is created if the file does not previously exist." + ), + ) + parser.add_argument( + "sql", type=str, nargs="?", + help=( + "An SQL query to execute. " + "Any returned rows are printed to stdout." + ), + ) + parser.add_argument( + "-v", "--version", action="version", + version=f"SQLite version {sqlite3.sqlite_version}", + help="Print underlying SQLite library version", + ) + args = parser.parse_args() + + if args.filename == ":memory:": + db_name = "a transient in-memory database" + else: + db_name = repr(args.filename) + + # Prepare REPL banner and prompts. + banner = dedent(f""" + sqlite3 shell, running on SQLite version {sqlite3.sqlite_version} + Connected to {db_name} + + Each command will be run using execute() on the cursor. + Type ".help" for more information; type ".quit" or CTRL-D to quit. + """).strip() + sys.ps1 = "sqlite> " + sys.ps2 = " ... " + + con = sqlite3.connect(args.filename, isolation_level=None) + try: + if args.sql: + # SQL statement provided on the command-line; execute it directly. + execute(con, args.sql, suppress_errors=False) + else: + # No SQL provided; start the REPL. + console = SqliteInteractiveConsole(con) + console.interact(banner, exitmsg="") + finally: + con.close() + + +main() diff --git a/Lib/sqlite3/dbapi2.py b/Lib/sqlite3/dbapi2.py index 7cf4dd32d54..56fc0461e6c 100644 --- a/Lib/sqlite3/dbapi2.py +++ b/Lib/sqlite3/dbapi2.py @@ -25,6 +25,9 @@ import time import collections.abc from _sqlite3 import * +from _sqlite3 import _deprecated_version + +_deprecated_names = frozenset({"version", "version_info"}) paramstyle = "qmark" @@ -45,23 +48,32 @@ def TimeFromTicks(ticks): def TimestampFromTicks(ticks): return Timestamp(*time.localtime(ticks)[:6]) -version_info = tuple([int(x) for x in version.split(".")]) +_deprecated_version_info = tuple(map(int, _deprecated_version.split("."))) sqlite_version_info = tuple([int(x) for x in sqlite_version.split(".")]) Binary = memoryview collections.abc.Sequence.register(Row) def register_adapters_and_converters(): + from warnings import warn + + msg = ("The default {what} is deprecated as of Python 3.12; " + "see the sqlite3 documentation for suggested replacement recipes") + def adapt_date(val): + warn(msg.format(what="date adapter"), DeprecationWarning, stacklevel=2) return val.isoformat() def adapt_datetime(val): + warn(msg.format(what="datetime adapter"), DeprecationWarning, stacklevel=2) return val.isoformat(" ") def convert_date(val): + warn(msg.format(what="date converter"), DeprecationWarning, stacklevel=2) return datetime.date(*map(int, val.split(b"-"))) def convert_timestamp(val): + warn(msg.format(what="timestamp converter"), DeprecationWarning, stacklevel=2) datepart, timepart = val.split(b" ") year, month, day = map(int, datepart.split(b"-")) timepart_full = timepart.split(b".") @@ -82,20 +94,15 @@ def register_adapters_and_converters(): register_adapters_and_converters() -# bpo-24464: enable_shared_cache was deprecated in Python 3.10. It's -# scheduled for removal in Python 3.12. -def enable_shared_cache(enable): - from _sqlite3 import enable_shared_cache as _old_enable_shared_cache - import warnings - msg = ( - "enable_shared_cache is deprecated and will be removed in Python 3.12. " - "Shared cache is strongly discouraged by the SQLite 3 documentation. " - "If shared cache must be used, open the database in URI mode using" - "the cache=shared query parameter." - ) - warnings.warn(msg, DeprecationWarning, stacklevel=2) - return _old_enable_shared_cache(enable) - # Clean up namespace del(register_adapters_and_converters) + +def __getattr__(name): + if name in _deprecated_names: + from warnings import warn + + warn(f"{name} is deprecated and will be removed in Python 3.14", + DeprecationWarning, stacklevel=2) + return globals()[f"_deprecated_{name}"] + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/sqlite3/dump.py b/Lib/sqlite3/dump.py index de9c368be30..07b9da10b92 100644 --- a/Lib/sqlite3/dump.py +++ b/Lib/sqlite3/dump.py @@ -28,9 +28,16 @@ def _iterdump(connection): ORDER BY "name" """ schema_res = cu.execute(q) + sqlite_sequence = [] for table_name, type, sql in schema_res.fetchall(): if table_name == 'sqlite_sequence': - yield('DELETE FROM "sqlite_sequence";') + rows = cu.execute('SELECT * FROM "sqlite_sequence";').fetchall() + sqlite_sequence = ['DELETE FROM "sqlite_sequence"'] + sqlite_sequence += [ + f'INSERT INTO "sqlite_sequence" VALUES(\'{row[0]}\',{row[1]})' + for row in rows + ] + continue elif table_name == 'sqlite_stat1': yield('ANALYZE "sqlite_master";') elif table_name.startswith('sqlite_'): @@ -67,4 +74,9 @@ def _iterdump(connection): for name, type, sql in schema_res.fetchall(): yield('{0};'.format(sql)) + # gh-79009: Yield statements concerning the sqlite_sequence table at the + # end of the transaction. + for row in sqlite_sequence: + yield('{0};'.format(row)) + yield('COMMIT;') diff --git a/Lib/sre_compile.py b/Lib/sre_compile.py index c6398bfb83a..f9da61e6487 100644 --- a/Lib/sre_compile.py +++ b/Lib/sre_compile.py @@ -1,784 +1,7 @@ -# -# Secret Labs' Regular Expression Engine -# -# convert template to internal format -# -# Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. -# -# See the sre.py file for information on usage and redistribution. -# +import warnings +warnings.warn(f"module {__name__!r} is deprecated", + DeprecationWarning, + stacklevel=2) -"""Internal support module for sre""" - -import _sre -import sre_parse -from sre_constants import * - -assert _sre.MAGIC == MAGIC, "SRE module mismatch" - -_LITERAL_CODES = {LITERAL, NOT_LITERAL} -_REPEATING_CODES = {REPEAT, MIN_REPEAT, MAX_REPEAT} -_SUCCESS_CODES = {SUCCESS, FAILURE} -_ASSERT_CODES = {ASSERT, ASSERT_NOT} -_UNIT_CODES = _LITERAL_CODES | {ANY, IN} - -# Sets of lowercase characters which have the same uppercase. -_equivalences = ( - # LATIN SMALL LETTER I, LATIN SMALL LETTER DOTLESS I - (0x69, 0x131), # iı - # LATIN SMALL LETTER S, LATIN SMALL LETTER LONG S - (0x73, 0x17f), # sÅ¿ - # MICRO SIGN, GREEK SMALL LETTER MU - (0xb5, 0x3bc), # µμ - # COMBINING GREEK YPOGEGRAMMENI, GREEK SMALL LETTER IOTA, GREEK PROSGEGRAMMENI - (0x345, 0x3b9, 0x1fbe), # \u0345ιι - # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS, GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA - (0x390, 0x1fd3), # Îá¿“ - # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS, GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA - (0x3b0, 0x1fe3), # ΰΰ - # GREEK SMALL LETTER BETA, GREEK BETA SYMBOL - (0x3b2, 0x3d0), # Î²Ï - # GREEK SMALL LETTER EPSILON, GREEK LUNATE EPSILON SYMBOL - (0x3b5, 0x3f5), # εϵ - # GREEK SMALL LETTER THETA, GREEK THETA SYMBOL - (0x3b8, 0x3d1), # θϑ - # GREEK SMALL LETTER KAPPA, GREEK KAPPA SYMBOL - (0x3ba, 0x3f0), # κϰ - # GREEK SMALL LETTER PI, GREEK PI SYMBOL - (0x3c0, 0x3d6), # πϖ - # GREEK SMALL LETTER RHO, GREEK RHO SYMBOL - (0x3c1, 0x3f1), # Ïϱ - # GREEK SMALL LETTER FINAL SIGMA, GREEK SMALL LETTER SIGMA - (0x3c2, 0x3c3), # ςσ - # GREEK SMALL LETTER PHI, GREEK PHI SYMBOL - (0x3c6, 0x3d5), # φϕ - # LATIN SMALL LETTER S WITH DOT ABOVE, LATIN SMALL LETTER LONG S WITH DOT ABOVE - (0x1e61, 0x1e9b), # ṡẛ - # LATIN SMALL LIGATURE LONG S T, LATIN SMALL LIGATURE ST - (0xfb05, 0xfb06), # ſtst -) - -# Maps the lowercase code to lowercase codes which have the same uppercase. -_ignorecase_fixes = {i: tuple(j for j in t if i != j) - for t in _equivalences for i in t} - -def _combine_flags(flags, add_flags, del_flags, - TYPE_FLAGS=sre_parse.TYPE_FLAGS): - if add_flags & TYPE_FLAGS: - flags &= ~TYPE_FLAGS - return (flags | add_flags) & ~del_flags - -def _compile(code, pattern, flags): - # internal: compile a (sub)pattern - emit = code.append - _len = len - LITERAL_CODES = _LITERAL_CODES - REPEATING_CODES = _REPEATING_CODES - SUCCESS_CODES = _SUCCESS_CODES - ASSERT_CODES = _ASSERT_CODES - iscased = None - tolower = None - fixes = None - if flags & SRE_FLAG_IGNORECASE and not flags & SRE_FLAG_LOCALE: - if flags & SRE_FLAG_UNICODE: - iscased = _sre.unicode_iscased - tolower = _sre.unicode_tolower - fixes = _ignorecase_fixes - else: - iscased = _sre.ascii_iscased - tolower = _sre.ascii_tolower - for op, av in pattern: - if op in LITERAL_CODES: - if not flags & SRE_FLAG_IGNORECASE: - emit(op) - emit(av) - elif flags & SRE_FLAG_LOCALE: - emit(OP_LOCALE_IGNORE[op]) - emit(av) - elif not iscased(av): - emit(op) - emit(av) - else: - lo = tolower(av) - if not fixes: # ascii - emit(OP_IGNORE[op]) - emit(lo) - elif lo not in fixes: - emit(OP_UNICODE_IGNORE[op]) - emit(lo) - else: - emit(IN_UNI_IGNORE) - skip = _len(code); emit(0) - if op is NOT_LITERAL: - emit(NEGATE) - for k in (lo,) + fixes[lo]: - emit(LITERAL) - emit(k) - emit(FAILURE) - code[skip] = _len(code) - skip - elif op is IN: - charset, hascased = _optimize_charset(av, iscased, tolower, fixes) - if flags & SRE_FLAG_IGNORECASE and flags & SRE_FLAG_LOCALE: - emit(IN_LOC_IGNORE) - elif not hascased: - emit(IN) - elif not fixes: # ascii - emit(IN_IGNORE) - else: - emit(IN_UNI_IGNORE) - skip = _len(code); emit(0) - _compile_charset(charset, flags, code) - code[skip] = _len(code) - skip - elif op is ANY: - if flags & SRE_FLAG_DOTALL: - emit(ANY_ALL) - else: - emit(ANY) - elif op in REPEATING_CODES: - if flags & SRE_FLAG_TEMPLATE: - raise error("internal: unsupported template operator %r" % (op,)) - if _simple(av[2]): - if op is MAX_REPEAT: - emit(REPEAT_ONE) - else: - emit(MIN_REPEAT_ONE) - skip = _len(code); emit(0) - emit(av[0]) - emit(av[1]) - _compile(code, av[2], flags) - emit(SUCCESS) - code[skip] = _len(code) - skip - else: - emit(REPEAT) - skip = _len(code); emit(0) - emit(av[0]) - emit(av[1]) - _compile(code, av[2], flags) - code[skip] = _len(code) - skip - if op is MAX_REPEAT: - emit(MAX_UNTIL) - else: - emit(MIN_UNTIL) - elif op is SUBPATTERN: - group, add_flags, del_flags, p = av - if group: - emit(MARK) - emit((group-1)*2) - # _compile_info(code, p, _combine_flags(flags, add_flags, del_flags)) - _compile(code, p, _combine_flags(flags, add_flags, del_flags)) - if group: - emit(MARK) - emit((group-1)*2+1) - elif op in SUCCESS_CODES: - emit(op) - elif op in ASSERT_CODES: - emit(op) - skip = _len(code); emit(0) - if av[0] >= 0: - emit(0) # look ahead - else: - lo, hi = av[1].getwidth() - if lo != hi: - raise error("look-behind requires fixed-width pattern") - emit(lo) # look behind - _compile(code, av[1], flags) - emit(SUCCESS) - code[skip] = _len(code) - skip - elif op is CALL: - emit(op) - skip = _len(code); emit(0) - _compile(code, av, flags) - emit(SUCCESS) - code[skip] = _len(code) - skip - elif op is AT: - emit(op) - if flags & SRE_FLAG_MULTILINE: - av = AT_MULTILINE.get(av, av) - if flags & SRE_FLAG_LOCALE: - av = AT_LOCALE.get(av, av) - elif flags & SRE_FLAG_UNICODE: - av = AT_UNICODE.get(av, av) - emit(av) - elif op is BRANCH: - emit(op) - tail = [] - tailappend = tail.append - for av in av[1]: - skip = _len(code); emit(0) - # _compile_info(code, av, flags) - _compile(code, av, flags) - emit(JUMP) - tailappend(_len(code)); emit(0) - code[skip] = _len(code) - skip - emit(FAILURE) # end of branch - for tail in tail: - code[tail] = _len(code) - tail - elif op is CATEGORY: - emit(op) - if flags & SRE_FLAG_LOCALE: - av = CH_LOCALE[av] - elif flags & SRE_FLAG_UNICODE: - av = CH_UNICODE[av] - emit(av) - elif op is GROUPREF: - if not flags & SRE_FLAG_IGNORECASE: - emit(op) - elif flags & SRE_FLAG_LOCALE: - emit(GROUPREF_LOC_IGNORE) - elif not fixes: # ascii - emit(GROUPREF_IGNORE) - else: - emit(GROUPREF_UNI_IGNORE) - emit(av-1) - elif op is GROUPREF_EXISTS: - emit(op) - emit(av[0]-1) - skipyes = _len(code); emit(0) - _compile(code, av[1], flags) - if av[2]: - emit(JUMP) - skipno = _len(code); emit(0) - code[skipyes] = _len(code) - skipyes + 1 - _compile(code, av[2], flags) - code[skipno] = _len(code) - skipno - else: - code[skipyes] = _len(code) - skipyes + 1 - else: - raise error("internal: unsupported operand type %r" % (op,)) - -def _compile_charset(charset, flags, code): - # compile charset subprogram - emit = code.append - for op, av in charset: - emit(op) - if op is NEGATE: - pass - elif op is LITERAL: - emit(av) - elif op is RANGE or op is RANGE_UNI_IGNORE: - emit(av[0]) - emit(av[1]) - elif op is CHARSET: - code.extend(av) - elif op is BIGCHARSET: - code.extend(av) - elif op is CATEGORY: - if flags & SRE_FLAG_LOCALE: - emit(CH_LOCALE[av]) - elif flags & SRE_FLAG_UNICODE: - emit(CH_UNICODE[av]) - else: - emit(av) - else: - raise error("internal: unsupported set operator %r" % (op,)) - emit(FAILURE) - -def _optimize_charset(charset, iscased=None, fixup=None, fixes=None): - # internal: optimize character set - out = [] - tail = [] - charmap = bytearray(256) - hascased = False - for op, av in charset: - while True: - try: - if op is LITERAL: - if fixup: - lo = fixup(av) - charmap[lo] = 1 - if fixes and lo in fixes: - for k in fixes[lo]: - charmap[k] = 1 - if not hascased and iscased(av): - hascased = True - else: - charmap[av] = 1 - elif op is RANGE: - r = range(av[0], av[1]+1) - if fixup: - if fixes: - for i in map(fixup, r): - charmap[i] = 1 - if i in fixes: - for k in fixes[i]: - charmap[k] = 1 - else: - for i in map(fixup, r): - charmap[i] = 1 - if not hascased: - hascased = any(map(iscased, r)) - else: - for i in r: - charmap[i] = 1 - elif op is NEGATE: - out.append((op, av)) - else: - tail.append((op, av)) - except IndexError: - if len(charmap) == 256: - # character set contains non-UCS1 character codes - charmap += b'\0' * 0xff00 - continue - # Character set contains non-BMP character codes. - if fixup: - hascased = True - # There are only two ranges of cased non-BMP characters: - # 10400-1044F (Deseret) and 118A0-118DF (Warang Citi), - # and for both ranges RANGE_UNI_IGNORE works. - if op is RANGE: - op = RANGE_UNI_IGNORE - tail.append((op, av)) - break - - # compress character map - runs = [] - q = 0 - while True: - p = charmap.find(1, q) - if p < 0: - break - if len(runs) >= 2: - runs = None - break - q = charmap.find(0, p) - if q < 0: - runs.append((p, len(charmap))) - break - runs.append((p, q)) - if runs is not None: - # use literal/range - for p, q in runs: - if q - p == 1: - out.append((LITERAL, p)) - else: - out.append((RANGE, (p, q - 1))) - out += tail - # if the case was changed or new representation is more compact - if hascased or len(out) < len(charset): - return out, hascased - # else original character set is good enough - return charset, hascased - - # use bitmap - if len(charmap) == 256: - data = _mk_bitmap(charmap) - out.append((CHARSET, data)) - out += tail - return out, hascased - - # To represent a big charset, first a bitmap of all characters in the - # set is constructed. Then, this bitmap is sliced into chunks of 256 - # characters, duplicate chunks are eliminated, and each chunk is - # given a number. In the compiled expression, the charset is - # represented by a 32-bit word sequence, consisting of one word for - # the number of different chunks, a sequence of 256 bytes (64 words) - # of chunk numbers indexed by their original chunk position, and a - # sequence of 256-bit chunks (8 words each). - - # Compression is normally good: in a typical charset, large ranges of - # Unicode will be either completely excluded (e.g. if only cyrillic - # letters are to be matched), or completely included (e.g. if large - # subranges of Kanji match). These ranges will be represented by - # chunks of all one-bits or all zero-bits. - - # Matching can be also done efficiently: the more significant byte of - # the Unicode character is an index into the chunk number, and the - # less significant byte is a bit index in the chunk (just like the - # CHARSET matching). - - charmap = bytes(charmap) # should be hashable - comps = {} - mapping = bytearray(256) - block = 0 - data = bytearray() - for i in range(0, 65536, 256): - chunk = charmap[i: i + 256] - if chunk in comps: - mapping[i // 256] = comps[chunk] - else: - mapping[i // 256] = comps[chunk] = block - block += 1 - data += chunk - data = _mk_bitmap(data) - data[0:0] = [block] + _bytes_to_codes(mapping) - out.append((BIGCHARSET, data)) - out += tail - return out, hascased - -_CODEBITS = _sre.CODESIZE * 8 -MAXCODE = (1 << _CODEBITS) - 1 -_BITS_TRANS = b'0' + b'1' * 255 -def _mk_bitmap(bits, _CODEBITS=_CODEBITS, _int=int): - s = bits.translate(_BITS_TRANS)[::-1] - return [_int(s[i - _CODEBITS: i], 2) - for i in range(len(s), 0, -_CODEBITS)] - -def _bytes_to_codes(b): - # Convert block indices to word array - a = memoryview(b).cast('I') - assert a.itemsize == _sre.CODESIZE - assert len(a) * a.itemsize == len(b) - return a.tolist() - -def _simple(p): - # check if this subpattern is a "simple" operator - if len(p) != 1: - return False - op, av = p[0] - if op is SUBPATTERN: - return av[0] is None and _simple(av[-1]) - return op in _UNIT_CODES - -def _generate_overlap_table(prefix): - """ - Generate an overlap table for the following prefix. - An overlap table is a table of the same size as the prefix which - informs about the potential self-overlap for each index in the prefix: - - if overlap[i] == 0, prefix[i:] can't overlap prefix[0:...] - - if overlap[i] == k with 0 < k <= i, prefix[i-k+1:i+1] overlaps with - prefix[0:k] - """ - table = [0] * len(prefix) - for i in range(1, len(prefix)): - idx = table[i - 1] - while prefix[i] != prefix[idx]: - if idx == 0: - table[i] = 0 - break - idx = table[idx - 1] - else: - table[i] = idx + 1 - return table - -def _get_iscased(flags): - if not flags & SRE_FLAG_IGNORECASE: - return None - elif flags & SRE_FLAG_UNICODE: - return _sre.unicode_iscased - else: - return _sre.ascii_iscased - -def _get_literal_prefix(pattern, flags): - # look for literal prefix - prefix = [] - prefixappend = prefix.append - prefix_skip = None - iscased = _get_iscased(flags) - for op, av in pattern.data: - if op is LITERAL: - if iscased and iscased(av): - break - prefixappend(av) - elif op is SUBPATTERN: - group, add_flags, del_flags, p = av - flags1 = _combine_flags(flags, add_flags, del_flags) - if flags1 & SRE_FLAG_IGNORECASE and flags1 & SRE_FLAG_LOCALE: - break - prefix1, prefix_skip1, got_all = _get_literal_prefix(p, flags1) - if prefix_skip is None: - if group is not None: - prefix_skip = len(prefix) - elif prefix_skip1 is not None: - prefix_skip = len(prefix) + prefix_skip1 - prefix.extend(prefix1) - if not got_all: - break - else: - break - else: - return prefix, prefix_skip, True - return prefix, prefix_skip, False - -def _get_charset_prefix(pattern, flags): - while True: - if not pattern.data: - return None - op, av = pattern.data[0] - if op is not SUBPATTERN: - break - group, add_flags, del_flags, pattern = av - flags = _combine_flags(flags, add_flags, del_flags) - if flags & SRE_FLAG_IGNORECASE and flags & SRE_FLAG_LOCALE: - return None - - iscased = _get_iscased(flags) - if op is LITERAL: - if iscased and iscased(av): - return None - return [(op, av)] - elif op is BRANCH: - charset = [] - charsetappend = charset.append - for p in av[1]: - if not p: - return None - op, av = p[0] - if op is LITERAL and not (iscased and iscased(av)): - charsetappend((op, av)) - else: - return None - return charset - elif op is IN: - charset = av - if iscased: - for op, av in charset: - if op is LITERAL: - if iscased(av): - return None - elif op is RANGE: - if av[1] > 0xffff: - return None - if any(map(iscased, range(av[0], av[1]+1))): - return None - return charset - return None - -def _compile_info(code, pattern, flags): - # internal: compile an info block. in the current version, - # this contains min/max pattern width, and an optional literal - # prefix or a character map - lo, hi = pattern.getwidth() - if hi > MAXCODE: - hi = MAXCODE - if lo == 0: - code.extend([INFO, 4, 0, lo, hi]) - return - # look for a literal prefix - prefix = [] - prefix_skip = 0 - charset = [] # not used - if not (flags & SRE_FLAG_IGNORECASE and flags & SRE_FLAG_LOCALE): - # look for literal prefix - prefix, prefix_skip, got_all = _get_literal_prefix(pattern, flags) - # if no prefix, look for charset prefix - if not prefix: - charset = _get_charset_prefix(pattern, flags) -## if prefix: -## print("*** PREFIX", prefix, prefix_skip) -## if charset: -## print("*** CHARSET", charset) - # add an info block - emit = code.append - emit(INFO) - skip = len(code); emit(0) - # literal flag - mask = 0 - if prefix: - mask = SRE_INFO_PREFIX - if prefix_skip is None and got_all: - mask = mask | SRE_INFO_LITERAL - elif charset: - mask = mask | SRE_INFO_CHARSET - emit(mask) - # pattern length - if lo < MAXCODE: - emit(lo) - else: - emit(MAXCODE) - prefix = prefix[:MAXCODE] - emit(min(hi, MAXCODE)) - # add literal prefix - if prefix: - emit(len(prefix)) # length - if prefix_skip is None: - prefix_skip = len(prefix) - emit(prefix_skip) # skip - code.extend(prefix) - # generate overlap table - code.extend(_generate_overlap_table(prefix)) - elif charset: - charset, hascased = _optimize_charset(charset) - assert not hascased - _compile_charset(charset, flags, code) - code[skip] = len(code) - skip - -def isstring(obj): - return isinstance(obj, (str, bytes)) - -def _code(p, flags): - - flags = p.state.flags | flags - code = [] - - # compile info block - _compile_info(code, p, flags) - - # compile the pattern - _compile(code, p.data, flags) - - code.append(SUCCESS) - - return code - -def _hex_code(code): - return '[%s]' % ', '.join('%#0*x' % (_sre.CODESIZE*2+2, x) for x in code) - -def dis(code): - import sys - - labels = set() - level = 0 - offset_width = len(str(len(code) - 1)) - - def dis_(start, end): - def print_(*args, to=None): - if to is not None: - labels.add(to) - args += ('(to %d)' % (to,),) - print('%*d%s ' % (offset_width, start, ':' if start in labels else '.'), - end=' '*(level-1)) - print(*args) - - def print_2(*args): - print(end=' '*(offset_width + 2*level)) - print(*args) - - nonlocal level - level += 1 - i = start - while i < end: - start = i - op = code[i] - i += 1 - op = OPCODES[op] - if op in (SUCCESS, FAILURE, ANY, ANY_ALL, - MAX_UNTIL, MIN_UNTIL, NEGATE): - print_(op) - elif op in (LITERAL, NOT_LITERAL, - LITERAL_IGNORE, NOT_LITERAL_IGNORE, - LITERAL_UNI_IGNORE, NOT_LITERAL_UNI_IGNORE, - LITERAL_LOC_IGNORE, NOT_LITERAL_LOC_IGNORE): - arg = code[i] - i += 1 - print_(op, '%#02x (%r)' % (arg, chr(arg))) - elif op is AT: - arg = code[i] - i += 1 - arg = str(ATCODES[arg]) - assert arg[:3] == 'AT_' - print_(op, arg[3:]) - elif op is CATEGORY: - arg = code[i] - i += 1 - arg = str(CHCODES[arg]) - assert arg[:9] == 'CATEGORY_' - print_(op, arg[9:]) - elif op in (IN, IN_IGNORE, IN_UNI_IGNORE, IN_LOC_IGNORE): - skip = code[i] - print_(op, skip, to=i+skip) - dis_(i+1, i+skip) - i += skip - elif op in (RANGE, RANGE_UNI_IGNORE): - lo, hi = code[i: i+2] - i += 2 - print_(op, '%#02x %#02x (%r-%r)' % (lo, hi, chr(lo), chr(hi))) - elif op is CHARSET: - print_(op, _hex_code(code[i: i + 256//_CODEBITS])) - i += 256//_CODEBITS - elif op is BIGCHARSET: - arg = code[i] - i += 1 - mapping = list(b''.join(x.to_bytes(_sre.CODESIZE, sys.byteorder) - for x in code[i: i + 256//_sre.CODESIZE])) - print_(op, arg, mapping) - i += 256//_sre.CODESIZE - level += 1 - for j in range(arg): - print_2(_hex_code(code[i: i + 256//_CODEBITS])) - i += 256//_CODEBITS - level -= 1 - elif op in (MARK, GROUPREF, GROUPREF_IGNORE, GROUPREF_UNI_IGNORE, - GROUPREF_LOC_IGNORE): - arg = code[i] - i += 1 - print_(op, arg) - elif op is JUMP: - skip = code[i] - print_(op, skip, to=i+skip) - i += 1 - elif op is BRANCH: - skip = code[i] - print_(op, skip, to=i+skip) - while skip: - dis_(i+1, i+skip) - i += skip - start = i - skip = code[i] - if skip: - print_('branch', skip, to=i+skip) - else: - print_(FAILURE) - i += 1 - elif op in (REPEAT, REPEAT_ONE, MIN_REPEAT_ONE): - skip, min, max = code[i: i+3] - if max == MAXREPEAT: - max = 'MAXREPEAT' - print_(op, skip, min, max, to=i+skip) - dis_(i+3, i+skip) - i += skip - elif op is GROUPREF_EXISTS: - arg, skip = code[i: i+2] - print_(op, arg, skip, to=i+skip) - i += 2 - elif op in (ASSERT, ASSERT_NOT): - skip, arg = code[i: i+2] - print_(op, skip, arg, to=i+skip) - dis_(i+2, i+skip) - i += skip - elif op is INFO: - skip, flags, min, max = code[i: i+4] - if max == MAXREPEAT: - max = 'MAXREPEAT' - print_(op, skip, bin(flags), min, max, to=i+skip) - start = i+4 - if flags & SRE_INFO_PREFIX: - prefix_len, prefix_skip = code[i+4: i+6] - print_2(' prefix_skip', prefix_skip) - start = i + 6 - prefix = code[start: start+prefix_len] - print_2(' prefix', - '[%s]' % ', '.join('%#02x' % x for x in prefix), - '(%r)' % ''.join(map(chr, prefix))) - start += prefix_len - print_2(' overlap', code[start: start+prefix_len]) - start += prefix_len - if flags & SRE_INFO_CHARSET: - level += 1 - print_2('in') - dis_(start, i+skip) - level -= 1 - i += skip - else: - raise ValueError(op) - - level -= 1 - - dis_(0, len(code)) - - -def compile(p, flags=0): - # internal: convert pattern list to internal format - - if isstring(p): - pattern = p - p = sre_parse.parse(p, flags) - else: - pattern = None - - code = _code(p, flags) - - if flags & SRE_FLAG_DEBUG: - print() - dis(code) - - # map in either direction - groupindex = p.state.groupdict - indexgroup = [None] * p.state.groups - for k, i in groupindex.items(): - indexgroup[i] = k - - return _sre.compile( - pattern, flags | p.state.flags, code, - p.state.groups-1, - groupindex, tuple(indexgroup) - ) +from re import _compiler as _ +globals().update({k: v for k, v in vars(_).items() if k[:2] != '__'}) diff --git a/Lib/sre_constants.py b/Lib/sre_constants.py index 8e613cb3fa5..fa09d044292 100644 --- a/Lib/sre_constants.py +++ b/Lib/sre_constants.py @@ -1,259 +1,7 @@ -# -# Secret Labs' Regular Expression Engine -# -# various symbols used by the regular expression engine. -# run this script to update the _sre include files! -# -# Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. -# -# See the sre.py file for information on usage and redistribution. -# +import warnings +warnings.warn(f"module {__name__!r} is deprecated", + DeprecationWarning, + stacklevel=2) -"""Internal support module for sre""" - -# update when constants are added or removed - -MAGIC = 20171005 - -from _sre import MAXREPEAT, MAXGROUPS - -# SRE standard exception (access as sre.error) -# should this really be here? - -class error(Exception): - """Exception raised for invalid regular expressions. - - Attributes: - - msg: The unformatted error message - pattern: The regular expression pattern - pos: The index in the pattern where compilation failed (may be None) - lineno: The line corresponding to pos (may be None) - colno: The column corresponding to pos (may be None) - """ - - __module__ = 're' - - def __init__(self, msg, pattern=None, pos=None): - self.msg = msg - self.pattern = pattern - self.pos = pos - if pattern is not None and pos is not None: - msg = '%s at position %d' % (msg, pos) - if isinstance(pattern, str): - newline = '\n' - else: - newline = b'\n' - self.lineno = pattern.count(newline, 0, pos) + 1 - self.colno = pos - pattern.rfind(newline, 0, pos) - if newline in pattern: - msg = '%s (line %d, column %d)' % (msg, self.lineno, self.colno) - else: - self.lineno = self.colno = None - super().__init__(msg) - - -class _NamedIntConstant(int): - def __new__(cls, value, name): - self = super(_NamedIntConstant, cls).__new__(cls, value) - self.name = name - return self - - def __repr__(self): - return self.name - -MAXREPEAT = _NamedIntConstant(MAXREPEAT, 'MAXREPEAT') - -def _makecodes(names): - names = names.strip().split() - items = [_NamedIntConstant(i, name) for i, name in enumerate(names)] - globals().update({item.name: item for item in items}) - return items - -# operators -# failure=0 success=1 (just because it looks better that way :-) -OPCODES = _makecodes(""" - FAILURE SUCCESS - - ANY ANY_ALL - ASSERT ASSERT_NOT - AT - BRANCH - CALL - CATEGORY - CHARSET BIGCHARSET - GROUPREF GROUPREF_EXISTS - IN - INFO - JUMP - LITERAL - MARK - MAX_UNTIL - MIN_UNTIL - NOT_LITERAL - NEGATE - RANGE - REPEAT - REPEAT_ONE - SUBPATTERN - MIN_REPEAT_ONE - - GROUPREF_IGNORE - IN_IGNORE - LITERAL_IGNORE - NOT_LITERAL_IGNORE - - GROUPREF_LOC_IGNORE - IN_LOC_IGNORE - LITERAL_LOC_IGNORE - NOT_LITERAL_LOC_IGNORE - - GROUPREF_UNI_IGNORE - IN_UNI_IGNORE - LITERAL_UNI_IGNORE - NOT_LITERAL_UNI_IGNORE - RANGE_UNI_IGNORE - - MIN_REPEAT MAX_REPEAT -""") -del OPCODES[-2:] # remove MIN_REPEAT and MAX_REPEAT - -# positions -ATCODES = _makecodes(""" - AT_BEGINNING AT_BEGINNING_LINE AT_BEGINNING_STRING - AT_BOUNDARY AT_NON_BOUNDARY - AT_END AT_END_LINE AT_END_STRING - - AT_LOC_BOUNDARY AT_LOC_NON_BOUNDARY - - AT_UNI_BOUNDARY AT_UNI_NON_BOUNDARY -""") - -# categories -CHCODES = _makecodes(""" - CATEGORY_DIGIT CATEGORY_NOT_DIGIT - CATEGORY_SPACE CATEGORY_NOT_SPACE - CATEGORY_WORD CATEGORY_NOT_WORD - CATEGORY_LINEBREAK CATEGORY_NOT_LINEBREAK - - CATEGORY_LOC_WORD CATEGORY_LOC_NOT_WORD - - CATEGORY_UNI_DIGIT CATEGORY_UNI_NOT_DIGIT - CATEGORY_UNI_SPACE CATEGORY_UNI_NOT_SPACE - CATEGORY_UNI_WORD CATEGORY_UNI_NOT_WORD - CATEGORY_UNI_LINEBREAK CATEGORY_UNI_NOT_LINEBREAK -""") - - -# replacement operations for "ignore case" mode -OP_IGNORE = { - LITERAL: LITERAL_IGNORE, - NOT_LITERAL: NOT_LITERAL_IGNORE, -} - -OP_LOCALE_IGNORE = { - LITERAL: LITERAL_LOC_IGNORE, - NOT_LITERAL: NOT_LITERAL_LOC_IGNORE, -} - -OP_UNICODE_IGNORE = { - LITERAL: LITERAL_UNI_IGNORE, - NOT_LITERAL: NOT_LITERAL_UNI_IGNORE, -} - -AT_MULTILINE = { - AT_BEGINNING: AT_BEGINNING_LINE, - AT_END: AT_END_LINE -} - -AT_LOCALE = { - AT_BOUNDARY: AT_LOC_BOUNDARY, - AT_NON_BOUNDARY: AT_LOC_NON_BOUNDARY -} - -AT_UNICODE = { - AT_BOUNDARY: AT_UNI_BOUNDARY, - AT_NON_BOUNDARY: AT_UNI_NON_BOUNDARY -} - -CH_LOCALE = { - CATEGORY_DIGIT: CATEGORY_DIGIT, - CATEGORY_NOT_DIGIT: CATEGORY_NOT_DIGIT, - CATEGORY_SPACE: CATEGORY_SPACE, - CATEGORY_NOT_SPACE: CATEGORY_NOT_SPACE, - CATEGORY_WORD: CATEGORY_LOC_WORD, - CATEGORY_NOT_WORD: CATEGORY_LOC_NOT_WORD, - CATEGORY_LINEBREAK: CATEGORY_LINEBREAK, - CATEGORY_NOT_LINEBREAK: CATEGORY_NOT_LINEBREAK -} - -CH_UNICODE = { - CATEGORY_DIGIT: CATEGORY_UNI_DIGIT, - CATEGORY_NOT_DIGIT: CATEGORY_UNI_NOT_DIGIT, - CATEGORY_SPACE: CATEGORY_UNI_SPACE, - CATEGORY_NOT_SPACE: CATEGORY_UNI_NOT_SPACE, - CATEGORY_WORD: CATEGORY_UNI_WORD, - CATEGORY_NOT_WORD: CATEGORY_UNI_NOT_WORD, - CATEGORY_LINEBREAK: CATEGORY_UNI_LINEBREAK, - CATEGORY_NOT_LINEBREAK: CATEGORY_UNI_NOT_LINEBREAK -} - -# flags -SRE_FLAG_TEMPLATE = 1 # template mode (disable backtracking) -SRE_FLAG_IGNORECASE = 2 # case insensitive -SRE_FLAG_LOCALE = 4 # honour system locale -SRE_FLAG_MULTILINE = 8 # treat target as multiline string -SRE_FLAG_DOTALL = 16 # treat target as a single string -SRE_FLAG_UNICODE = 32 # use unicode "locale" -SRE_FLAG_VERBOSE = 64 # ignore whitespace and comments -SRE_FLAG_DEBUG = 128 # debugging -SRE_FLAG_ASCII = 256 # use ascii "locale" - -# flags for INFO primitive -SRE_INFO_PREFIX = 1 # has prefix -SRE_INFO_LITERAL = 2 # entire pattern is literal (given by prefix) -SRE_INFO_CHARSET = 4 # pattern starts with character from given set - -if __name__ == "__main__": - def dump(f, d, prefix): - items = sorted(d) - for item in items: - f.write("#define %s_%s %d\n" % (prefix, item, item)) - with open("sre_constants.h", "w") as f: - f.write("""\ -/* - * Secret Labs' Regular Expression Engine - * - * regular expression matching engine - * - * NOTE: This file is generated by sre_constants.py. If you need - * to change anything in here, edit sre_constants.py and run it. - * - * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. - * - * See the _sre.c file for information on usage and redistribution. - */ - -""") - - f.write("#define SRE_MAGIC %d\n" % MAGIC) - - dump(f, OPCODES, "SRE_OP") - dump(f, ATCODES, "SRE") - dump(f, CHCODES, "SRE") - - f.write("#define SRE_FLAG_TEMPLATE %d\n" % SRE_FLAG_TEMPLATE) - f.write("#define SRE_FLAG_IGNORECASE %d\n" % SRE_FLAG_IGNORECASE) - f.write("#define SRE_FLAG_LOCALE %d\n" % SRE_FLAG_LOCALE) - f.write("#define SRE_FLAG_MULTILINE %d\n" % SRE_FLAG_MULTILINE) - f.write("#define SRE_FLAG_DOTALL %d\n" % SRE_FLAG_DOTALL) - f.write("#define SRE_FLAG_UNICODE %d\n" % SRE_FLAG_UNICODE) - f.write("#define SRE_FLAG_VERBOSE %d\n" % SRE_FLAG_VERBOSE) - f.write("#define SRE_FLAG_DEBUG %d\n" % SRE_FLAG_DEBUG) - f.write("#define SRE_FLAG_ASCII %d\n" % SRE_FLAG_ASCII) - - f.write("#define SRE_INFO_PREFIX %d\n" % SRE_INFO_PREFIX) - f.write("#define SRE_INFO_LITERAL %d\n" % SRE_INFO_LITERAL) - f.write("#define SRE_INFO_CHARSET %d\n" % SRE_INFO_CHARSET) - - print("done") +from re import _constants as _ +globals().update({k: v for k, v in vars(_).items() if k[:2] != '__'}) diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index 83119168e63..25a3f557d44 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -1,1064 +1,7 @@ -# -# Secret Labs' Regular Expression Engine -# -# convert re-style regular expression to sre pattern -# -# Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. -# -# See the sre.py file for information on usage and redistribution. -# +import warnings +warnings.warn(f"module {__name__!r} is deprecated", + DeprecationWarning, + stacklevel=2) -"""Internal support module for sre""" - -# XXX: show string offset and offending character for all errors - -from sre_constants import * - -SPECIAL_CHARS = ".\\[{()*+?^$|" -REPEAT_CHARS = "*+?{" - -DIGITS = frozenset("0123456789") - -OCTDIGITS = frozenset("01234567") -HEXDIGITS = frozenset("0123456789abcdefABCDEF") -ASCIILETTERS = frozenset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") - -WHITESPACE = frozenset(" \t\n\r\v\f") - -_REPEATCODES = frozenset({MIN_REPEAT, MAX_REPEAT}) -_UNITCODES = frozenset({ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY}) - -ESCAPES = { - r"\a": (LITERAL, ord("\a")), - r"\b": (LITERAL, ord("\b")), - r"\f": (LITERAL, ord("\f")), - r"\n": (LITERAL, ord("\n")), - r"\r": (LITERAL, ord("\r")), - r"\t": (LITERAL, ord("\t")), - r"\v": (LITERAL, ord("\v")), - r"\\": (LITERAL, ord("\\")) -} - -CATEGORIES = { - r"\A": (AT, AT_BEGINNING_STRING), # start of string - r"\b": (AT, AT_BOUNDARY), - r"\B": (AT, AT_NON_BOUNDARY), - r"\d": (IN, [(CATEGORY, CATEGORY_DIGIT)]), - r"\D": (IN, [(CATEGORY, CATEGORY_NOT_DIGIT)]), - r"\s": (IN, [(CATEGORY, CATEGORY_SPACE)]), - r"\S": (IN, [(CATEGORY, CATEGORY_NOT_SPACE)]), - r"\w": (IN, [(CATEGORY, CATEGORY_WORD)]), - r"\W": (IN, [(CATEGORY, CATEGORY_NOT_WORD)]), - r"\Z": (AT, AT_END_STRING), # end of string -} - -FLAGS = { - # standard flags - "i": SRE_FLAG_IGNORECASE, - "L": SRE_FLAG_LOCALE, - "m": SRE_FLAG_MULTILINE, - "s": SRE_FLAG_DOTALL, - "x": SRE_FLAG_VERBOSE, - # extensions - "a": SRE_FLAG_ASCII, - "t": SRE_FLAG_TEMPLATE, - "u": SRE_FLAG_UNICODE, -} - -TYPE_FLAGS = SRE_FLAG_ASCII | SRE_FLAG_LOCALE | SRE_FLAG_UNICODE -GLOBAL_FLAGS = SRE_FLAG_DEBUG | SRE_FLAG_TEMPLATE - -class Verbose(Exception): - pass - -class State: - # keeps track of state for parsing - def __init__(self): - self.flags = 0 - self.groupdict = {} - self.groupwidths = [None] # group 0 - self.lookbehindgroups = None - @property - def groups(self): - return len(self.groupwidths) - def opengroup(self, name=None): - gid = self.groups - self.groupwidths.append(None) - if self.groups > MAXGROUPS: - raise error("too many groups") - if name is not None: - ogid = self.groupdict.get(name, None) - if ogid is not None: - raise error("redefinition of group name %r as group %d; " - "was group %d" % (name, gid, ogid)) - self.groupdict[name] = gid - return gid - def closegroup(self, gid, p): - self.groupwidths[gid] = p.getwidth() - def checkgroup(self, gid): - return gid < self.groups and self.groupwidths[gid] is not None - - def checklookbehindgroup(self, gid, source): - if self.lookbehindgroups is not None: - if not self.checkgroup(gid): - raise source.error('cannot refer to an open group') - if gid >= self.lookbehindgroups: - raise source.error('cannot refer to group defined in the same ' - 'lookbehind subpattern') - -class SubPattern: - # a subpattern, in intermediate form - def __init__(self, state, data=None): - self.state = state - if data is None: - data = [] - self.data = data - self.width = None - - def dump(self, level=0): - nl = True - seqtypes = (tuple, list) - for op, av in self.data: - print(level*" " + str(op), end='') - if op is IN: - # member sublanguage - print() - for op, a in av: - print((level+1)*" " + str(op), a) - elif op is BRANCH: - print() - for i, a in enumerate(av[1]): - if i: - print(level*" " + "OR") - a.dump(level+1) - elif op is GROUPREF_EXISTS: - condgroup, item_yes, item_no = av - print('', condgroup) - item_yes.dump(level+1) - if item_no: - print(level*" " + "ELSE") - item_no.dump(level+1) - elif isinstance(av, seqtypes): - nl = False - for a in av: - if isinstance(a, SubPattern): - if not nl: - print() - a.dump(level+1) - nl = True - else: - if not nl: - print(' ', end='') - print(a, end='') - nl = False - if not nl: - print() - else: - print('', av) - def __repr__(self): - return repr(self.data) - def __len__(self): - return len(self.data) - def __delitem__(self, index): - del self.data[index] - def __getitem__(self, index): - if isinstance(index, slice): - return SubPattern(self.state, self.data[index]) - return self.data[index] - def __setitem__(self, index, code): - self.data[index] = code - def insert(self, index, code): - self.data.insert(index, code) - def append(self, code): - self.data.append(code) - def getwidth(self): - # determine the width (min, max) for this subpattern - if self.width is not None: - return self.width - lo = hi = 0 - for op, av in self.data: - if op is BRANCH: - i = MAXREPEAT - 1 - j = 0 - for av in av[1]: - l, h = av.getwidth() - i = min(i, l) - j = max(j, h) - lo = lo + i - hi = hi + j - elif op is CALL: - i, j = av.getwidth() - lo = lo + i - hi = hi + j - elif op is SUBPATTERN: - i, j = av[-1].getwidth() - lo = lo + i - hi = hi + j - elif op in _REPEATCODES: - i, j = av[2].getwidth() - lo = lo + i * av[0] - hi = hi + j * av[1] - elif op in _UNITCODES: - lo = lo + 1 - hi = hi + 1 - elif op is GROUPREF: - i, j = self.state.groupwidths[av] - lo = lo + i - hi = hi + j - elif op is GROUPREF_EXISTS: - i, j = av[1].getwidth() - if av[2] is not None: - l, h = av[2].getwidth() - i = min(i, l) - j = max(j, h) - else: - i = 0 - lo = lo + i - hi = hi + j - elif op is SUCCESS: - break - self.width = min(lo, MAXREPEAT - 1), min(hi, MAXREPEAT) - return self.width - -class Tokenizer: - def __init__(self, string): - self.istext = isinstance(string, str) - self.string = string - if not self.istext: - string = str(string, 'latin1') - self.decoded_string = string - self.index = 0 - self.next = None - self.__next() - def __next(self): - index = self.index - try: - char = self.decoded_string[index] - except IndexError: - self.next = None - return - if char == "\\": - index += 1 - try: - char += self.decoded_string[index] - except IndexError: - raise error("bad escape (end of pattern)", - self.string, len(self.string) - 1) from None - self.index = index + 1 - self.next = char - def match(self, char): - if char == self.next: - self.__next() - return True - return False - def get(self): - this = self.next - self.__next() - return this - def getwhile(self, n, charset): - result = '' - for _ in range(n): - c = self.next - if c not in charset: - break - result += c - self.__next() - return result - def getuntil(self, terminator, name): - result = '' - while True: - c = self.next - self.__next() - if c is None: - if not result: - raise self.error("missing " + name) - raise self.error("missing %s, unterminated name" % terminator, - len(result)) - if c == terminator: - if not result: - raise self.error("missing " + name, 1) - break - result += c - return result - @property - def pos(self): - return self.index - len(self.next or '') - def tell(self): - return self.index - len(self.next or '') - def seek(self, index): - self.index = index - self.__next() - - def error(self, msg, offset=0): - return error(msg, self.string, self.tell() - offset) - -def _class_escape(source, escape): - # handle escape code inside character class - code = ESCAPES.get(escape) - if code: - return code - code = CATEGORIES.get(escape) - if code and code[0] is IN: - return code - try: - c = escape[1:2] - if c == "x": - # hexadecimal escape (exactly two digits) - escape += source.getwhile(2, HEXDIGITS) - if len(escape) != 4: - raise source.error("incomplete escape %s" % escape, len(escape)) - return LITERAL, int(escape[2:], 16) - elif c == "u" and source.istext: - # unicode escape (exactly four digits) - escape += source.getwhile(4, HEXDIGITS) - if len(escape) != 6: - raise source.error("incomplete escape %s" % escape, len(escape)) - return LITERAL, int(escape[2:], 16) - elif c == "U" and source.istext: - # unicode escape (exactly eight digits) - escape += source.getwhile(8, HEXDIGITS) - if len(escape) != 10: - raise source.error("incomplete escape %s" % escape, len(escape)) - c = int(escape[2:], 16) - chr(c) # raise ValueError for invalid code - return LITERAL, c - elif c == "N" and source.istext: - import unicodedata - # named unicode escape e.g. \N{EM DASH} - if not source.match('{'): - raise source.error("missing {") - charname = source.getuntil('}', 'character name') - try: - c = ord(unicodedata.lookup(charname)) - except KeyError: - raise source.error("undefined character name %r" % charname, - len(charname) + len(r'\N{}')) - return LITERAL, c - elif c in OCTDIGITS: - # octal escape (up to three digits) - escape += source.getwhile(2, OCTDIGITS) - c = int(escape[1:], 8) - if c > 0o377: - raise source.error('octal escape value %s outside of ' - 'range 0-0o377' % escape, len(escape)) - return LITERAL, c - elif c in DIGITS: - raise ValueError - if len(escape) == 2: - if c in ASCIILETTERS: - raise source.error('bad escape %s' % escape, len(escape)) - return LITERAL, ord(escape[1]) - except ValueError: - pass - raise source.error("bad escape %s" % escape, len(escape)) - -def _escape(source, escape, state): - # handle escape code in expression - code = CATEGORIES.get(escape) - if code: - return code - code = ESCAPES.get(escape) - if code: - return code - try: - c = escape[1:2] - if c == "x": - # hexadecimal escape - escape += source.getwhile(2, HEXDIGITS) - if len(escape) != 4: - raise source.error("incomplete escape %s" % escape, len(escape)) - return LITERAL, int(escape[2:], 16) - elif c == "u" and source.istext: - # unicode escape (exactly four digits) - escape += source.getwhile(4, HEXDIGITS) - if len(escape) != 6: - raise source.error("incomplete escape %s" % escape, len(escape)) - return LITERAL, int(escape[2:], 16) - elif c == "U" and source.istext: - # unicode escape (exactly eight digits) - escape += source.getwhile(8, HEXDIGITS) - if len(escape) != 10: - raise source.error("incomplete escape %s" % escape, len(escape)) - c = int(escape[2:], 16) - chr(c) # raise ValueError for invalid code - return LITERAL, c - elif c == "N" and source.istext: - import unicodedata - # named unicode escape e.g. \N{EM DASH} - if not source.match('{'): - raise source.error("missing {") - charname = source.getuntil('}', 'character name') - try: - c = ord(unicodedata.lookup(charname)) - except KeyError: - raise source.error("undefined character name %r" % charname, - len(charname) + len(r'\N{}')) - return LITERAL, c - elif c == "0": - # octal escape - escape += source.getwhile(2, OCTDIGITS) - return LITERAL, int(escape[1:], 8) - elif c in DIGITS: - # octal escape *or* decimal group reference (sigh) - if source.next in DIGITS: - escape += source.get() - if (escape[1] in OCTDIGITS and escape[2] in OCTDIGITS and - source.next in OCTDIGITS): - # got three octal digits; this is an octal escape - escape += source.get() - c = int(escape[1:], 8) - if c > 0o377: - raise source.error('octal escape value %s outside of ' - 'range 0-0o377' % escape, - len(escape)) - return LITERAL, c - # not an octal escape, so this is a group reference - group = int(escape[1:]) - if group < state.groups: - if not state.checkgroup(group): - raise source.error("cannot refer to an open group", - len(escape)) - state.checklookbehindgroup(group, source) - return GROUPREF, group - raise source.error("invalid group reference %d" % group, len(escape) - 1) - if len(escape) == 2: - if c in ASCIILETTERS: - raise source.error("bad escape %s" % escape, len(escape)) - return LITERAL, ord(escape[1]) - except ValueError: - pass - raise source.error("bad escape %s" % escape, len(escape)) - -def _uniq(items): - return list(dict.fromkeys(items)) - -def _parse_sub(source, state, verbose, nested): - # parse an alternation: a|b|c - - items = [] - itemsappend = items.append - sourcematch = source.match - start = source.tell() - while True: - itemsappend(_parse(source, state, verbose, nested + 1, - not nested and not items)) - if not sourcematch("|"): - break - - if len(items) == 1: - return items[0] - - subpattern = SubPattern(state) - - # check if all items share a common prefix - while True: - prefix = None - for item in items: - if not item: - break - if prefix is None: - prefix = item[0] - elif item[0] != prefix: - break - else: - # all subitems start with a common "prefix". - # move it out of the branch - for item in items: - del item[0] - subpattern.append(prefix) - continue # check next one - break - - # check if the branch can be replaced by a character set - set = [] - for item in items: - if len(item) != 1: - break - op, av = item[0] - if op is LITERAL: - set.append((op, av)) - elif op is IN and av[0][0] is not NEGATE: - set.extend(av) - else: - break - else: - # we can store this as a character set instead of a - # branch (the compiler may optimize this even more) - subpattern.append((IN, _uniq(set))) - return subpattern - - subpattern.append((BRANCH, (None, items))) - return subpattern - -def _parse(source, state, verbose, nested, first=False): - # parse a simple pattern - subpattern = SubPattern(state) - - # precompute constants into local variables - subpatternappend = subpattern.append - sourceget = source.get - sourcematch = source.match - _len = len - _ord = ord - - while True: - - this = source.next - if this is None: - break # end of pattern - if this in "|)": - break # end of subpattern - sourceget() - - if verbose: - # skip whitespace and comments - if this in WHITESPACE: - continue - if this == "#": - while True: - this = sourceget() - if this is None or this == "\n": - break - continue - - if this[0] == "\\": - code = _escape(source, this, state) - subpatternappend(code) - - elif this not in SPECIAL_CHARS: - subpatternappend((LITERAL, _ord(this))) - - elif this == "[": - here = source.tell() - 1 - # character set - set = [] - setappend = set.append -## if sourcematch(":"): -## pass # handle character classes - if source.next == '[': - import warnings - warnings.warn( - 'Possible nested set at position %d' % source.tell(), - FutureWarning, stacklevel=nested + 6 - ) - negate = sourcematch("^") - # check remaining characters - while True: - this = sourceget() - if this is None: - raise source.error("unterminated character set", - source.tell() - here) - if this == "]" and set: - break - elif this[0] == "\\": - code1 = _class_escape(source, this) - else: - if set and this in '-&~|' and source.next == this: - import warnings - warnings.warn( - 'Possible set %s at position %d' % ( - 'difference' if this == '-' else - 'intersection' if this == '&' else - 'symmetric difference' if this == '~' else - 'union', - source.tell() - 1), - FutureWarning, stacklevel=nested + 6 - ) - code1 = LITERAL, _ord(this) - if sourcematch("-"): - # potential range - that = sourceget() - if that is None: - raise source.error("unterminated character set", - source.tell() - here) - if that == "]": - if code1[0] is IN: - code1 = code1[1][0] - setappend(code1) - setappend((LITERAL, _ord("-"))) - break - if that[0] == "\\": - code2 = _class_escape(source, that) - else: - if that == '-': - import warnings - warnings.warn( - 'Possible set difference at position %d' % ( - source.tell() - 2), - FutureWarning, stacklevel=nested + 6 - ) - code2 = LITERAL, _ord(that) - if code1[0] != LITERAL or code2[0] != LITERAL: - msg = "bad character range %s-%s" % (this, that) - raise source.error(msg, len(this) + 1 + len(that)) - lo = code1[1] - hi = code2[1] - if hi < lo: - msg = "bad character range %s-%s" % (this, that) - raise source.error(msg, len(this) + 1 + len(that)) - setappend((RANGE, (lo, hi))) - else: - if code1[0] is IN: - code1 = code1[1][0] - setappend(code1) - - set = _uniq(set) - # XXX: should move set optimization to compiler! - if _len(set) == 1 and set[0][0] is LITERAL: - # optimization - if negate: - subpatternappend((NOT_LITERAL, set[0][1])) - else: - subpatternappend(set[0]) - else: - if negate: - set.insert(0, (NEGATE, None)) - # charmap optimization can't be added here because - # global flags still are not known - subpatternappend((IN, set)) - - elif this in REPEAT_CHARS: - # repeat previous item - here = source.tell() - if this == "?": - min, max = 0, 1 - elif this == "*": - min, max = 0, MAXREPEAT - - elif this == "+": - min, max = 1, MAXREPEAT - elif this == "{": - if source.next == "}": - subpatternappend((LITERAL, _ord(this))) - continue - - min, max = 0, MAXREPEAT - lo = hi = "" - while source.next in DIGITS: - lo += sourceget() - if sourcematch(","): - while source.next in DIGITS: - hi += sourceget() - else: - hi = lo - if not sourcematch("}"): - subpatternappend((LITERAL, _ord(this))) - source.seek(here) - continue - - if lo: - min = int(lo) - if min >= MAXREPEAT: - raise OverflowError("the repetition number is too large") - if hi: - max = int(hi) - if max >= MAXREPEAT: - raise OverflowError("the repetition number is too large") - if max < min: - raise source.error("min repeat greater than max repeat", - source.tell() - here) - else: - raise AssertionError("unsupported quantifier %r" % (char,)) - # figure out which item to repeat - if subpattern: - item = subpattern[-1:] - else: - item = None - if not item or item[0][0] is AT: - raise source.error("nothing to repeat", - source.tell() - here + len(this)) - if item[0][0] in _REPEATCODES: - raise source.error("multiple repeat", - source.tell() - here + len(this)) - if item[0][0] is SUBPATTERN: - group, add_flags, del_flags, p = item[0][1] - if group is None and not add_flags and not del_flags: - item = p - if sourcematch("?"): - subpattern[-1] = (MIN_REPEAT, (min, max, item)) - else: - subpattern[-1] = (MAX_REPEAT, (min, max, item)) - - elif this == ".": - subpatternappend((ANY, None)) - - elif this == "(": - start = source.tell() - 1 - group = True - name = None - add_flags = 0 - del_flags = 0 - if sourcematch("?"): - # options - char = sourceget() - if char is None: - raise source.error("unexpected end of pattern") - if char == "P": - # python extensions - if sourcematch("<"): - # named group: skip forward to end of name - name = source.getuntil(">", "group name") - if not name.isidentifier(): - msg = "bad character in group name %r" % name - raise source.error(msg, len(name) + 1) - elif sourcematch("="): - # named backreference - name = source.getuntil(")", "group name") - if not name.isidentifier(): - msg = "bad character in group name %r" % name - raise source.error(msg, len(name) + 1) - gid = state.groupdict.get(name) - if gid is None: - msg = "unknown group name %r" % name - raise source.error(msg, len(name) + 1) - if not state.checkgroup(gid): - raise source.error("cannot refer to an open group", - len(name) + 1) - state.checklookbehindgroup(gid, source) - subpatternappend((GROUPREF, gid)) - continue - - else: - char = sourceget() - if char is None: - raise source.error("unexpected end of pattern") - raise source.error("unknown extension ?P" + char, - len(char) + 2) - elif char == ":": - # non-capturing group - group = None - elif char == "#": - # comment - while True: - if source.next is None: - raise source.error("missing ), unterminated comment", - source.tell() - start) - if sourceget() == ")": - break - continue - - elif char in "=!<": - # lookahead assertions - dir = 1 - if char == "<": - char = sourceget() - if char is None: - raise source.error("unexpected end of pattern") - if char not in "=!": - raise source.error("unknown extension ?<" + char, - len(char) + 2) - dir = -1 # lookbehind - lookbehindgroups = state.lookbehindgroups - if lookbehindgroups is None: - state.lookbehindgroups = state.groups - p = _parse_sub(source, state, verbose, nested + 1) - if dir < 0: - if lookbehindgroups is None: - state.lookbehindgroups = None - if not sourcematch(")"): - raise source.error("missing ), unterminated subpattern", - source.tell() - start) - if char == "=": - subpatternappend((ASSERT, (dir, p))) - else: - subpatternappend((ASSERT_NOT, (dir, p))) - continue - - elif char == "(": - # conditional backreference group - condname = source.getuntil(")", "group name") - if condname.isidentifier(): - condgroup = state.groupdict.get(condname) - if condgroup is None: - msg = "unknown group name %r" % condname - raise source.error(msg, len(condname) + 1) - else: - try: - condgroup = int(condname) - if condgroup < 0: - raise ValueError - except ValueError: - msg = "bad character in group name %r" % condname - raise source.error(msg, len(condname) + 1) from None - if not condgroup: - raise source.error("bad group number", - len(condname) + 1) - if condgroup >= MAXGROUPS: - msg = "invalid group reference %d" % condgroup - raise source.error(msg, len(condname) + 1) - state.checklookbehindgroup(condgroup, source) - item_yes = _parse(source, state, verbose, nested + 1) - if source.match("|"): - item_no = _parse(source, state, verbose, nested + 1) - if source.next == "|": - raise source.error("conditional backref with more than two branches") - else: - item_no = None - if not source.match(")"): - raise source.error("missing ), unterminated subpattern", - source.tell() - start) - subpatternappend((GROUPREF_EXISTS, (condgroup, item_yes, item_no))) - continue - - elif char in FLAGS or char == "-": - # flags - flags = _parse_flags(source, state, char) - if flags is None: # global flags - if not first or subpattern: - import warnings - warnings.warn( - 'Flags not at the start of the expression %r%s' % ( - source.string[:20], # truncate long regexes - ' (truncated)' if len(source.string) > 20 else '', - ), - DeprecationWarning, stacklevel=nested + 6 - ) - if (state.flags & SRE_FLAG_VERBOSE) and not verbose: - raise Verbose - continue - - add_flags, del_flags = flags - group = None - else: - raise source.error("unknown extension ?" + char, - len(char) + 1) - - # parse group contents - if group is not None: - try: - group = state.opengroup(name) - except error as err: - raise source.error(err.msg, len(name) + 1) from None - sub_verbose = ((verbose or (add_flags & SRE_FLAG_VERBOSE)) and - not (del_flags & SRE_FLAG_VERBOSE)) - p = _parse_sub(source, state, sub_verbose, nested + 1) - if not source.match(")"): - raise source.error("missing ), unterminated subpattern", - source.tell() - start) - if group is not None: - state.closegroup(group, p) - subpatternappend((SUBPATTERN, (group, add_flags, del_flags, p))) - - elif this == "^": - subpatternappend((AT, AT_BEGINNING)) - - elif this == "$": - subpatternappend((AT, AT_END)) - - else: - raise AssertionError("unsupported special character %r" % (char,)) - - # unpack non-capturing groups - for i in range(len(subpattern))[::-1]: - op, av = subpattern[i] - if op is SUBPATTERN: - group, add_flags, del_flags, p = av - if group is None and not add_flags and not del_flags: - subpattern[i: i+1] = p - - return subpattern - -def _parse_flags(source, state, char): - sourceget = source.get - add_flags = 0 - del_flags = 0 - if char != "-": - while True: - flag = FLAGS[char] - if source.istext: - if char == 'L': - msg = "bad inline flags: cannot use 'L' flag with a str pattern" - raise source.error(msg) - else: - if char == 'u': - msg = "bad inline flags: cannot use 'u' flag with a bytes pattern" - raise source.error(msg) - add_flags |= flag - if (flag & TYPE_FLAGS) and (add_flags & TYPE_FLAGS) != flag: - msg = "bad inline flags: flags 'a', 'u' and 'L' are incompatible" - raise source.error(msg) - char = sourceget() - if char is None: - raise source.error("missing -, : or )") - if char in ")-:": - break - if char not in FLAGS: - msg = "unknown flag" if char.isalpha() else "missing -, : or )" - raise source.error(msg, len(char)) - if char == ")": - state.flags |= add_flags - return None - if add_flags & GLOBAL_FLAGS: - raise source.error("bad inline flags: cannot turn on global flag", 1) - if char == "-": - char = sourceget() - if char is None: - raise source.error("missing flag") - if char not in FLAGS: - msg = "unknown flag" if char.isalpha() else "missing flag" - raise source.error(msg, len(char)) - while True: - flag = FLAGS[char] - if flag & TYPE_FLAGS: - msg = "bad inline flags: cannot turn off flags 'a', 'u' and 'L'" - raise source.error(msg) - del_flags |= flag - char = sourceget() - if char is None: - raise source.error("missing :") - if char == ":": - break - if char not in FLAGS: - msg = "unknown flag" if char.isalpha() else "missing :" - raise source.error(msg, len(char)) - assert char == ":" - if del_flags & GLOBAL_FLAGS: - raise source.error("bad inline flags: cannot turn off global flag", 1) - if add_flags & del_flags: - raise source.error("bad inline flags: flag turned on and off", 1) - return add_flags, del_flags - -def fix_flags(src, flags): - # Check and fix flags according to the type of pattern (str or bytes) - if isinstance(src, str): - if flags & SRE_FLAG_LOCALE: - raise ValueError("cannot use LOCALE flag with a str pattern") - if not flags & SRE_FLAG_ASCII: - flags |= SRE_FLAG_UNICODE - elif flags & SRE_FLAG_UNICODE: - raise ValueError("ASCII and UNICODE flags are incompatible") - else: - if flags & SRE_FLAG_UNICODE: - raise ValueError("cannot use UNICODE flag with a bytes pattern") - if flags & SRE_FLAG_LOCALE and flags & SRE_FLAG_ASCII: - raise ValueError("ASCII and LOCALE flags are incompatible") - return flags - -def parse(str, flags=0, state=None): - # parse 're' pattern into list of (opcode, argument) tuples - - source = Tokenizer(str) - - if state is None: - state = State() - state.flags = flags - state.str = str - - try: - p = _parse_sub(source, state, flags & SRE_FLAG_VERBOSE, 0) - except Verbose: - # the VERBOSE flag was switched on inside the pattern. to be - # on the safe side, we'll parse the whole thing again... - state = State() - state.flags = flags | SRE_FLAG_VERBOSE - state.str = str - source.seek(0) - p = _parse_sub(source, state, True, 0) - - p.state.flags = fix_flags(str, p.state.flags) - - if source.next is not None: - assert source.next == ")" - raise source.error("unbalanced parenthesis") - - if flags & SRE_FLAG_DEBUG: - p.dump() - - return p - -def parse_template(source, state): - # parse 're' replacement string into list of literals and - # group references - s = Tokenizer(source) - sget = s.get - groups = [] - literals = [] - literal = [] - lappend = literal.append - def addgroup(index, pos): - if index > state.groups: - raise s.error("invalid group reference %d" % index, pos) - if literal: - literals.append(''.join(literal)) - del literal[:] - groups.append((len(literals), index)) - literals.append(None) - groupindex = state.groupindex - while True: - this = sget() - if this is None: - break # end of replacement string - if this[0] == "\\": - # group - c = this[1] - if c == "g": - name = "" - if not s.match("<"): - raise s.error("missing <") - name = s.getuntil(">", "group name") - if name.isidentifier(): - try: - index = groupindex[name] - except KeyError: - raise IndexError("unknown group name %r" % name) - else: - try: - index = int(name) - if index < 0: - raise ValueError - except ValueError: - raise s.error("bad character in group name %r" % name, - len(name) + 1) from None - if index >= MAXGROUPS: - raise s.error("invalid group reference %d" % index, - len(name) + 1) - addgroup(index, len(name) + 1) - elif c == "0": - if s.next in OCTDIGITS: - this += sget() - if s.next in OCTDIGITS: - this += sget() - lappend(chr(int(this[1:], 8) & 0xff)) - elif c in DIGITS: - isoctal = False - if s.next in DIGITS: - this += sget() - if (c in OCTDIGITS and this[2] in OCTDIGITS and - s.next in OCTDIGITS): - this += sget() - isoctal = True - c = int(this[1:], 8) - if c > 0o377: - raise s.error('octal escape value %s outside of ' - 'range 0-0o377' % this, len(this)) - lappend(chr(c)) - if not isoctal: - addgroup(int(this[1:]), len(this) - 1) - else: - try: - this = chr(ESCAPES[this][1]) - except KeyError: - if c in ASCIILETTERS: - raise s.error('bad escape %s' % this, len(this)) - lappend(this) - else: - lappend(this) - if literal: - literals.append(''.join(literal)) - if not isinstance(source, str): - # The tokenizer implicitly decodes bytes objects as latin-1, we must - # therefore re-encode the final representation. - literals = [None if s is None else s.encode('latin-1') for s in literals] - return groups, literals - -def expand_template(template, match): - g = match.group - empty = match.string[:0] - groups, literals = template - literals = literals[:] - try: - for index, group in groups: - literals[index] = g(group) or empty - except IndexError: - raise error("invalid group reference %d" % index) - return empty.join(literals) +from re import _parser as _ +globals().update({k: v for k, v in vars(_).items() if k[:2] != '__'}) diff --git a/Lib/ssl.py b/Lib/ssl.py index 207925166ef..1d587372644 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -18,9 +18,10 @@ Functions: seconds past the Epoch (the time values returned from time.time()) - fetch_server_certificate (HOST, PORT) -- fetch the certificate provided - by the server running on HOST at port PORT. No - validation of the certificate is performed. + get_server_certificate (addr, ssl_version, ca_certs, timeout) -- Retrieve the + certificate from the server at the specified + address and return it as a PEM-encoded string + Integer constants: @@ -105,7 +106,7 @@ from _ssl import ( SSLSyscallError, SSLEOFError, SSLCertVerificationError ) from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj -from _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes +from _ssl import RAND_status, RAND_add, RAND_bytes try: from _ssl import RAND_egd except ImportError: @@ -119,7 +120,6 @@ from _ssl import ( ) from _ssl import _DEFAULT_CIPHERS, _OPENSSL_API_VERSION - _IntEnum._convert_( '_SSLMethod', __name__, lambda name: name.startswith('PROTOCOL_') and name != 'PROTOCOL_SSLv23', @@ -373,68 +373,6 @@ def _ipaddress_match(cert_ipaddress, host_ip): return ip == host_ip -def match_hostname(cert, hostname): - """Verify that *cert* (in decoded format as returned by - SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 - rules are followed. - - The function matches IP addresses rather than dNSNames if hostname is a - valid ipaddress string. IPv4 addresses are supported on all platforms. - IPv6 addresses are supported on platforms with IPv6 support (AF_INET6 - and inet_pton). - - CertificateError is raised on failure. On success, the function - returns nothing. - """ - warnings.warn( - "ssl.match_hostname() is deprecated", - category=DeprecationWarning, - stacklevel=2 - ) - if not cert: - raise ValueError("empty or no certificate, match_hostname needs a " - "SSL socket or SSL context with either " - "CERT_OPTIONAL or CERT_REQUIRED") - try: - host_ip = _inet_paton(hostname) - except ValueError: - # Not an IP address (common case) - host_ip = None - dnsnames = [] - san = cert.get('subjectAltName', ()) - for key, value in san: - if key == 'DNS': - if host_ip is None and _dnsname_match(value, hostname): - return - dnsnames.append(value) - elif key == 'IP Address': - if host_ip is not None and _ipaddress_match(value, host_ip): - return - dnsnames.append(value) - if not dnsnames: - # The subject is only checked when there is no dNSName entry - # in subjectAltName - for sub in cert.get('subject', ()): - for key, value in sub: - # XXX according to RFC 2818, the most specific Common Name - # must be used. - if key == 'commonName': - if _dnsname_match(value, hostname): - return - dnsnames.append(value) - if len(dnsnames) > 1: - raise CertificateError("hostname %r " - "doesn't match either of %s" - % (hostname, ', '.join(map(repr, dnsnames)))) - elif len(dnsnames) == 1: - raise CertificateError("hostname %r " - "doesn't match %r" - % (hostname, dnsnames[0])) - else: - raise CertificateError("no appropriate commonName or " - "subjectAltName fields were found") - - DefaultVerifyPaths = namedtuple("DefaultVerifyPaths", "cafile capath openssl_cafile_env openssl_cafile openssl_capath_env " "openssl_capath") @@ -1419,36 +1357,6 @@ SSLContext.sslsocket_class = SSLSocket SSLContext.sslobject_class = SSLObject -def wrap_socket(sock, keyfile=None, certfile=None, - server_side=False, cert_reqs=CERT_NONE, - ssl_version=PROTOCOL_TLS, ca_certs=None, - do_handshake_on_connect=True, - suppress_ragged_eofs=True, - ciphers=None): - warnings.warn( - "ssl.wrap_socket() is deprecated, use SSLContext.wrap_socket()", - category=DeprecationWarning, - stacklevel=2 - ) - if server_side and not certfile: - raise ValueError("certfile must be specified for server-side " - "operations") - if keyfile and not certfile: - raise ValueError("certfile must be specified") - context = SSLContext(ssl_version) - context.verify_mode = cert_reqs - if ca_certs: - context.load_verify_locations(ca_certs) - if certfile: - context.load_cert_chain(certfile, keyfile) - if ciphers: - context.set_ciphers(ciphers) - return context.wrap_socket( - sock=sock, server_side=server_side, - do_handshake_on_connect=do_handshake_on_connect, - suppress_ragged_eofs=suppress_ragged_eofs - ) - # some utility functions def cert_time_to_seconds(cert_time): diff --git a/Lib/statistics.py b/Lib/statistics.py index 5c3f77df154..07d1fd5ba6e 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -130,14 +130,16 @@ __all__ = [ import math import numbers import random +import sys from fractions import Fraction from decimal import Decimal -from itertools import groupby, repeat +from itertools import count, groupby, repeat from bisect import bisect_left, bisect_right from math import hypot, sqrt, fabs, exp, erf, tau, log, fsum -from operator import itemgetter, mul -from collections import Counter, namedtuple +from functools import reduce +from operator import mul, itemgetter +from collections import Counter, namedtuple, defaultdict _SQRT2 = sqrt(2.0) @@ -182,11 +184,12 @@ def _sum(data): allowed. """ count = 0 + types = set() + types_add = types.add partials = {} partials_get = partials.get - T = int for typ, values in groupby(data, type): - T = _coerce(T, typ) # or raise TypeError + types_add(typ) for n, d in map(_exact_ratio, values): count += 1 partials[d] = partials_get(d, 0) + n @@ -198,9 +201,51 @@ def _sum(data): else: # Sum all the partial sums using builtin sum. total = sum(Fraction(n, d) for d, n in partials.items()) + T = reduce(_coerce, types, int) # or raise TypeError return (T, total, count) +def _ss(data, c=None): + """Return the exact mean and sum of square deviations of sequence data. + + Calculations are done in a single pass, allowing the input to be an iterator. + + If given *c* is used the mean; otherwise, it is calculated from the data. + Use the *c* argument with care, as it can lead to garbage results. + + """ + if c is not None: + T, ssd, count = _sum((d := x - c) * d for x in data) + return (T, ssd, c, count) + count = 0 + types = set() + types_add = types.add + sx_partials = defaultdict(int) + sxx_partials = defaultdict(int) + for typ, values in groupby(data, type): + types_add(typ) + for n, d in map(_exact_ratio, values): + count += 1 + sx_partials[d] += n + sxx_partials[d] += n * n + if not count: + ssd = c = Fraction(0) + elif None in sx_partials: + # The sum will be a NAN or INF. We can ignore all the finite + # partials, and just look at this special one. + ssd = c = sx_partials[None] + assert not _isfinite(ssd) + else: + sx = sum(Fraction(n, d) for d, n in sx_partials.items()) + sxx = sum(Fraction(n, d*d) for d, n in sxx_partials.items()) + # This formula has poor numeric properties for floats, + # but with fractions it is exact. + ssd = (count * sxx - sx * sx) / count + c = sx / count + T = reduce(_coerce, types, int) # or raise TypeError + return (T, ssd, c, count) + + def _isfinite(x): try: return x.is_finite() # Likely a Decimal. @@ -247,6 +292,28 @@ def _exact_ratio(x): x is expected to be an int, Fraction, Decimal or float. """ + + # XXX We should revisit whether using fractions to accumulate exact + # ratios is the right way to go. + + # The integer ratios for binary floats can have numerators or + # denominators with over 300 decimal digits. The problem is more + # acute with decimal floats where the default decimal context + # supports a huge range of exponents from Emin=-999999 to + # Emax=999999. When expanded with as_integer_ratio(), numbers like + # Decimal('3.14E+5000') and Decimal('3.14E-5000') have large + # numerators or denominators that will slow computation. + + # When the integer ratios are accumulated as fractions, the size + # grows to cover the full range from the smallest magnitude to the + # largest. For example, Fraction(3.14E+300) + Fraction(3.14E-300), + # has a 616 digit numerator. Likewise, + # Fraction(Decimal('3.14E+5000')) + Fraction(Decimal('3.14E-5000')) + # has 10,003 digit numerator. + + # This doesn't seem to have been problem in practice, but it is a + # potential pitfall. + try: return x.as_integer_ratio() except AttributeError: @@ -281,22 +348,6 @@ def _convert(value, T): raise -def _find_lteq(a, x): - 'Locate the leftmost value exactly equal to x' - i = bisect_left(a, x) - if i != len(a) and a[i] == x: - return i - raise ValueError - - -def _find_rteq(a, l, x): - 'Locate the rightmost value exactly equal to x' - i = bisect_right(a, x, lo=l) - if i != (len(a) + 1) and a[i - 1] == x: - return i - 1 - raise ValueError - - def _fail_neg(values, errmsg='negative value'): """Iterate over values, failing if any are less than zero.""" for x in values: @@ -305,6 +356,113 @@ def _fail_neg(values, errmsg='negative value'): yield x +def _rank(data, /, *, key=None, reverse=False, ties='average', start=1) -> list[float]: + """Rank order a dataset. The lowest value has rank 1. + + Ties are averaged so that equal values receive the same rank: + + >>> data = [31, 56, 31, 25, 75, 18] + >>> _rank(data) + [3.5, 5.0, 3.5, 2.0, 6.0, 1.0] + + The operation is idempotent: + + >>> _rank([3.5, 5.0, 3.5, 2.0, 6.0, 1.0]) + [3.5, 5.0, 3.5, 2.0, 6.0, 1.0] + + It is possible to rank the data in reverse order so that the + highest value has rank 1. Also, a key-function can extract + the field to be ranked: + + >>> goals = [('eagles', 45), ('bears', 48), ('lions', 44)] + >>> _rank(goals, key=itemgetter(1), reverse=True) + [2.0, 1.0, 3.0] + + Ranks are conventionally numbered starting from one; however, + setting *start* to zero allows the ranks to be used as array indices: + + >>> prize = ['Gold', 'Silver', 'Bronze', 'Certificate'] + >>> scores = [8.1, 7.3, 9.4, 8.3] + >>> [prize[int(i)] for i in _rank(scores, start=0, reverse=True)] + ['Bronze', 'Certificate', 'Gold', 'Silver'] + + """ + # If this function becomes public at some point, more thought + # needs to be given to the signature. A list of ints is + # plausible when ties is "min" or "max". When ties is "average", + # either list[float] or list[Fraction] is plausible. + + # Default handling of ties matches scipy.stats.mstats.spearmanr. + if ties != 'average': + raise ValueError(f'Unknown tie resolution method: {ties!r}') + if key is not None: + data = map(key, data) + val_pos = sorted(zip(data, count()), reverse=reverse) + i = start - 1 + result = [0] * len(val_pos) + for _, g in groupby(val_pos, key=itemgetter(0)): + group = list(g) + size = len(group) + rank = i + (size + 1) / 2 + for value, orig_pos in group: + result[orig_pos] = rank + i += size + return result + + +def _integer_sqrt_of_frac_rto(n: int, m: int) -> int: + """Square root of n/m, rounded to the nearest integer using round-to-odd.""" + # Reference: https://www.lri.fr/~melquion/doc/05-imacs17_1-expose.pdf + a = math.isqrt(n // m) + return a | (a*a*m != n) + + +# For 53 bit precision floats, the bit width used in +# _float_sqrt_of_frac() is 109. +_sqrt_bit_width: int = 2 * sys.float_info.mant_dig + 3 + + +def _float_sqrt_of_frac(n: int, m: int) -> float: + """Square root of n/m as a float, correctly rounded.""" + # See principle and proof sketch at: https://bugs.python.org/msg407078 + q = (n.bit_length() - m.bit_length() - _sqrt_bit_width) // 2 + if q >= 0: + numerator = _integer_sqrt_of_frac_rto(n, m << 2 * q) << q + denominator = 1 + else: + numerator = _integer_sqrt_of_frac_rto(n << -2 * q, m) + denominator = 1 << -q + return numerator / denominator # Convert to float + + +def _decimal_sqrt_of_frac(n: int, m: int) -> Decimal: + """Square root of n/m as a Decimal, correctly rounded.""" + # Premise: For decimal, computing (n/m).sqrt() can be off + # by 1 ulp from the correctly rounded result. + # Method: Check the result, moving up or down a step if needed. + if n <= 0: + if not n: + return Decimal('0.0') + n, m = -n, -m + + root = (Decimal(n) / Decimal(m)).sqrt() + nr, dr = root.as_integer_ratio() + + plus = root.next_plus() + np, dp = plus.as_integer_ratio() + # test: n / m > ((root + plus) / 2) ** 2 + if 4 * n * (dr*dp)**2 > m * (dr*np + dp*nr)**2: + return plus + + minus = root.next_minus() + nm, dm = minus.as_integer_ratio() + # test: n / m < ((root + minus) / 2) ** 2 + if 4 * n * (dr*dm)**2 < m * (dr*nm + dm*nr)**2: + return minus + + return root + + # === Measures of central tendency (averages) === def mean(data): @@ -323,13 +481,9 @@ def mean(data): If ``data`` is empty, StatisticsError will be raised. """ - if iter(data) is data: - data = list(data) - n = len(data) + T, total, n = _sum(data) if n < 1: raise StatisticsError('mean requires at least one data point') - T, total, count = _sum(data) - assert count == n return _convert(total / n, T) @@ -387,7 +541,7 @@ def geometric_mean(data): return exp(fmean(map(log, data))) except ValueError: raise StatisticsError('geometric mean requires a non-empty dataset ' - ' containing positive numbers') from None + 'containing positive numbers') from None def harmonic_mean(data, weights=None): @@ -511,58 +665,75 @@ def median_high(data): return data[n // 2] -def median_grouped(data, interval=1): - """Return the 50th percentile (median) of grouped continuous data. +def median_grouped(data, interval=1.0): + """Estimates the median for numeric data binned around the midpoints + of consecutive, fixed-width intervals. - >>> median_grouped([1, 2, 2, 3, 4, 4, 4, 4, 4, 5]) - 3.7 - >>> median_grouped([52, 52, 53, 54]) - 52.5 + The *data* can be any iterable of numeric data with each value being + exactly the midpoint of a bin. At least one value must be present. - This calculates the median as the 50th percentile, and should be - used when your data is continuous and grouped. In the above example, - the values 1, 2, 3, etc. actually represent the midpoint of classes - 0.5-1.5, 1.5-2.5, 2.5-3.5, etc. The middle value falls somewhere in - class 3.5-4.5, and interpolation is used to estimate it. + The *interval* is width of each bin. - Optional argument ``interval`` represents the class interval, and - defaults to 1. Changing the class interval naturally will change the - interpolated 50th percentile value: + For example, demographic information may have been summarized into + consecutive ten-year age groups with each group being represented + by the 5-year midpoints of the intervals: - >>> median_grouped([1, 3, 3, 5, 7], interval=1) - 3.25 - >>> median_grouped([1, 3, 3, 5, 7], interval=2) - 3.5 + >>> demographics = Counter({ + ... 25: 172, # 20 to 30 years old + ... 35: 484, # 30 to 40 years old + ... 45: 387, # 40 to 50 years old + ... 55: 22, # 50 to 60 years old + ... 65: 6, # 60 to 70 years old + ... }) + + The 50th percentile (median) is the 536th person out of the 1071 + member cohort. That person is in the 30 to 40 year old age group. + + The regular median() function would assume that everyone in the + tricenarian age group was exactly 35 years old. A more tenable + assumption is that the 484 members of that age group are evenly + distributed between 30 and 40. For that, we use median_grouped(). + + >>> data = list(demographics.elements()) + >>> median(data) + 35 + >>> round(median_grouped(data, interval=10), 1) + 37.5 + + The caller is responsible for making sure the data points are separated + by exact multiples of *interval*. This is essential for getting a + correct result. The function does not check this precondition. + + Inputs may be any numeric type that can be coerced to a float during + the interpolation step. - This function does not check whether the data points are at least - ``interval`` apart. """ data = sorted(data) n = len(data) - if n == 0: + if not n: raise StatisticsError("no median for empty data") - elif n == 1: - return data[0] - # Find the value at the midpoint. Remember this corresponds to the - # centre of the class interval. - x = data[n // 2] - for obj in (x, interval): - if isinstance(obj, (str, bytes)): - raise TypeError('expected number but got %r' % obj) - try: - L = x - interval / 2 # The lower limit of the median interval. - except TypeError: - # Mixed type. For now we just coerce to float. - L = float(x) - float(interval) / 2 - # Uses bisection search to search for x in data with log(n) time complexity - # Find the position of leftmost occurrence of x in data - l1 = _find_lteq(data, x) - # Find the position of rightmost occurrence of x in data[l1...len(data)] - # Assuming always l1 <= l2 - l2 = _find_rteq(data, l1, x) - cf = l1 - f = l2 - l1 + 1 + # Find the value at the midpoint. Remember this corresponds to the + # midpoint of the class interval. + x = data[n // 2] + + # Using O(log n) bisection, find where all the x values occur in the data. + # All x will lie within data[i:j]. + i = bisect_left(data, x) + j = bisect_right(data, x, lo=i) + + # Coerce to floats, raising a TypeError if not possible + try: + interval = float(interval) + x = float(x) + except ValueError: + raise TypeError(f'Value cannot be converted to a float') + + # Interpolate the median using the formula found at: + # https://www.cuemath.com/data/median-of-grouped-data/ + L = x - interval / 2.0 # Lower limit of the median interval + cf = i # Cumulative frequency of the preceding interval + f = j - i # Number of elements in the median internal return L + interval * (n / 2 - cf) / f @@ -700,41 +871,6 @@ def quantiles(data, *, n=4, method='exclusive'): # See http://mathworld.wolfram.com/Variance.html # http://mathworld.wolfram.com/SampleVariance.html -# http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance -# -# Under no circumstances use the so-called "computational formula for -# variance", as that is only suitable for hand calculations with a small -# amount of low-precision data. It has terrible numeric properties. -# -# See a comparison of three computational methods here: -# http://www.johndcook.com/blog/2008/09/26/comparing-three-methods-of-computing-standard-deviation/ - -def _ss(data, c=None): - """Return sum of square deviations of sequence data. - - If ``c`` is None, the mean is calculated in one pass, and the deviations - from the mean are calculated in a second pass. Otherwise, deviations are - calculated from ``c`` as given. Use the second case with care, as it can - lead to garbage results. - """ - if c is not None: - T, total, count = _sum((d := x - c) * d for x in data) - return (T, total) - T, total, count = _sum(data) - mean_n, mean_d = (total / count).as_integer_ratio() - partials = Counter() - for n, d in map(_exact_ratio, data): - diff_n = n * mean_d - d * mean_n - diff_d = d * mean_d - partials[diff_d * diff_d] += diff_n * diff_n - if None in partials: - # The sum will be a NAN or INF. We can ignore all the finite - # partials, and just look at this special one. - total = partials[None] - assert not _isfinite(total) - else: - total = sum(Fraction(n, d) for d, n in partials.items()) - return (T, total) def variance(data, xbar=None): @@ -775,12 +911,9 @@ def variance(data, xbar=None): Fraction(67, 108) """ - if iter(data) is data: - data = list(data) - n = len(data) + T, ss, c, n = _ss(data, xbar) if n < 2: raise StatisticsError('variance requires at least two data points') - T, ss = _ss(data, xbar) return _convert(ss / (n - 1), T) @@ -819,12 +952,9 @@ def pvariance(data, mu=None): Fraction(13, 72) """ - if iter(data) is data: - data = list(data) - n = len(data) + T, ss, c, n = _ss(data, mu) if n < 1: raise StatisticsError('pvariance requires at least one data point') - T, ss = _ss(data, mu) return _convert(ss / n, T) @@ -837,14 +967,13 @@ def stdev(data, xbar=None): 1.0810874155219827 """ - # Fixme: Despite the exact sum of squared deviations, some inaccuracy - # remain because there are two rounding steps. The first occurs in - # the _convert() step for variance(), the second occurs in math.sqrt(). - var = variance(data, xbar) - try: - return var.sqrt() - except AttributeError: - return math.sqrt(var) + T, ss, c, n = _ss(data, xbar) + if n < 2: + raise StatisticsError('stdev requires at least two data points') + mss = ss / (n - 1) + if issubclass(T, Decimal): + return _decimal_sqrt_of_frac(mss.numerator, mss.denominator) + return _float_sqrt_of_frac(mss.numerator, mss.denominator) def pstdev(data, mu=None): @@ -856,14 +985,26 @@ def pstdev(data, mu=None): 0.986893273527251 """ - # Fixme: Despite the exact sum of squared deviations, some inaccuracy - # remain because there are two rounding steps. The first occurs in - # the _convert() step for pvariance(), the second occurs in math.sqrt(). - var = pvariance(data, mu) + T, ss, c, n = _ss(data, mu) + if n < 1: + raise StatisticsError('pstdev requires at least one data point') + mss = ss / n + if issubclass(T, Decimal): + return _decimal_sqrt_of_frac(mss.numerator, mss.denominator) + return _float_sqrt_of_frac(mss.numerator, mss.denominator) + + +def _mean_stdev(data): + """In one pass, compute the mean and sample standard deviation as floats.""" + T, ss, xbar, n = _ss(data) + if n < 2: + raise StatisticsError('stdev requires at least two data points') + mss = ss / (n - 1) try: - return var.sqrt() + return float(xbar), _float_sqrt_of_frac(mss.numerator, mss.denominator) except AttributeError: - return math.sqrt(var) + # Handle Nans and Infs gracefully + return float(xbar), float(xbar) / float(ss) # === Statistics for relations between two inputs === @@ -901,14 +1042,12 @@ def covariance(x, y, /): return sxy / (n - 1) -def correlation(x, y, /): +def correlation(x, y, /, *, method='linear'): """Pearson's correlation coefficient Return the Pearson's correlation coefficient for two inputs. Pearson's - correlation coefficient *r* takes values between -1 and +1. It measures the - strength and direction of the linear relationship, where +1 means very - strong, positive linear relationship, -1 very strong, negative linear - relationship, and 0 no linear relationship. + correlation coefficient *r* takes values between -1 and +1. It measures + the strength and direction of a linear relationship. >>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> y = [9, 8, 7, 6, 5, 4, 3, 2, 1] @@ -917,12 +1056,26 @@ def correlation(x, y, /): >>> correlation(x, y) -1.0 + If *method* is "ranked", computes Spearman's rank correlation coefficient + for two inputs. The data is replaced by ranks. Ties are averaged + so that equal values receive the same rank. The resulting coefficient + measures the strength of a monotonic relationship. + + Spearman's rank correlation coefficient is appropriate for ordinal + data or for continuous data that doesn't meet the linear proportion + requirement for Pearson's correlation coefficient. """ n = len(x) if len(y) != n: raise StatisticsError('correlation requires that both inputs have same number of data points') if n < 2: raise StatisticsError('correlation requires at least two data points') + if method not in {'linear', 'ranked'}: + raise ValueError(f'Unknown method: {method!r}') + if method == 'ranked': + start = (n - 1) / -2 # Center rankings around zero + x = _rank(x, start=start) + y = _rank(y, start=start) xbar = fsum(x) / n ybar = fsum(y) / n sxy = fsum((xi - xbar) * (yi - ybar) for xi, yi in zip(x, y)) @@ -1100,16 +1253,13 @@ class NormalDist: @classmethod def from_samples(cls, data): "Make a normal distribution instance from sample data." - if not isinstance(data, (list, tuple)): - data = list(data) - xbar = fmean(data) - return cls(xbar, stdev(data, xbar)) + return cls(*_mean_stdev(data)) def samples(self, n, *, seed=None): "Generate *n* samples for a given mean and standard deviation." gauss = random.gauss if seed is None else random.Random(seed).gauss mu, sigma = self._mu, self._sigma - return [gauss(mu, sigma) for i in range(n)] + return [gauss(mu, sigma) for _ in repeat(None, n)] def pdf(self, x): "Probability density function. P(x <= X < x+dx) / dx" @@ -1137,8 +1287,6 @@ class NormalDist: """ if p <= 0.0 or p >= 1.0: raise StatisticsError('p must be in the range 0.0 < p < 1.0') - if self._sigma <= 0.0: - raise StatisticsError('cdf() not defined when sigma at or below zero') return _normal_dist_inv_cdf(p, self._mu, self._sigma) def quantiles(self, n=4): @@ -1298,3 +1446,9 @@ class NormalDist: def __repr__(self): return f'{type(self).__name__}(mu={self._mu!r}, sigma={self._sigma!r})' + + def __getstate__(self): + return self._mu, self._sigma + + def __setstate__(self, state): + self._mu, self._sigma = state diff --git a/Lib/string.py b/Lib/string.py index 261789cc10a..2eab6d4f595 100644 --- a/Lib/string.py +++ b/Lib/string.py @@ -141,6 +141,35 @@ class Template: self.pattern) return self.pattern.sub(convert, self.template) + def is_valid(self): + for mo in self.pattern.finditer(self.template): + if mo.group('invalid') is not None: + return False + if (mo.group('named') is None + and mo.group('braced') is None + and mo.group('escaped') is None): + # If all the groups are None, there must be + # another group we're not expecting + raise ValueError('Unrecognized named group in pattern', + self.pattern) + return True + + def get_identifiers(self): + ids = [] + for mo in self.pattern.finditer(self.template): + named = mo.group('named') or mo.group('braced') + if named is not None and named not in ids: + # add a named group only the first time it appears + ids.append(named) + elif (named is None + and mo.group('invalid') is None + and mo.group('escaped') is None): + # If all the groups are None, there must be + # another group we're not expecting + raise ValueError('Unrecognized named group in pattern', + self.pattern) + return ids + # Initialize Template.pattern. __init_subclass__() is automatically called # only for subclasses, not for the Template class itself. Template.__init_subclass__() diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 33f022f8fce..9cadd1bf8e6 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -43,6 +43,7 @@ getstatusoutput(...): Runs a command in the shell, waits for it to complete, import builtins import errno import io +import locale import os import time import signal @@ -65,16 +66,19 @@ __all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "getstatusoutput", # NOTE: We intentionally exclude list2cmdline as it is # considered an internal implementation detail. issue10838. +# use presence of msvcrt to detect Windows-like platforms (see bpo-8110) try: import msvcrt - import _winapi - _mswindows = True except ModuleNotFoundError: _mswindows = False - import _posixsubprocess - import select - import selectors else: + _mswindows = True + +# wasm32-emscripten and wasm32-wasi do not support processes +_can_fork_exec = sys.platform not in {"emscripten", "wasi"} + +if _mswindows: + import _winapi from _winapi import (CREATE_NEW_CONSOLE, CREATE_NEW_PROCESS_GROUP, STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE, SW_HIDE, @@ -95,6 +99,24 @@ else: "NORMAL_PRIORITY_CLASS", "REALTIME_PRIORITY_CLASS", "CREATE_NO_WINDOW", "DETACHED_PROCESS", "CREATE_DEFAULT_ERROR_MODE", "CREATE_BREAKAWAY_FROM_JOB"]) +else: + if _can_fork_exec: + from _posixsubprocess import fork_exec as _fork_exec + # used in methods that are called by __del__ + _waitpid = os.waitpid + _waitstatus_to_exitcode = os.waitstatus_to_exitcode + _WIFSTOPPED = os.WIFSTOPPED + _WSTOPSIG = os.WSTOPSIG + _WNOHANG = os.WNOHANG + else: + _fork_exec = None + _waitpid = None + _waitstatus_to_exitcode = None + _WIFSTOPPED = None + _WSTOPSIG = None + _WNOHANG = None + import select + import selectors # Exception classes used by this module. @@ -302,12 +324,14 @@ def _args_from_interpreter_flags(): args.append('-E') if sys.flags.no_user_site: args.append('-s') + if sys.flags.safe_path: + args.append('-P') # -W options warnopts = sys.warnoptions[:] - bytes_warning = sys.flags.bytes_warning xoptions = getattr(sys, '_xoptions', {}) - dev_mode = ('dev' in xoptions) + bytes_warning = sys.flags.bytes_warning + dev_mode = sys.flags.dev_mode if bytes_warning > 1: warnopts.remove("error::BytesWarning") @@ -334,6 +358,26 @@ def _args_from_interpreter_flags(): return args +def _text_encoding(): + # Return default text encoding and emit EncodingWarning if + # sys.flags.warn_default_encoding is true. + if sys.flags.warn_default_encoding: + f = sys._getframe() + filename = f.f_code.co_filename + stacklevel = 2 + while f := f.f_back: + if f.f_code.co_filename != filename: + break + stacklevel += 1 + warnings.warn("'encoding' argument not specified.", + EncodingWarning, stacklevel) + + if sys.flags.utf8_mode: + return "utf-8" + else: + return locale.getencoding() + + def call(*popenargs, timeout=None, **kwargs): """Run command with arguments. Wait for command to complete or timeout, then return the returncode attribute. @@ -412,7 +456,8 @@ def check_output(*popenargs, timeout=None, **kwargs): if 'input' in kwargs and kwargs['input'] is None: # Explicitly passing input=None was previously equivalent to passing an # empty string. That is maintained here for backwards compatibility. - if kwargs.get('universal_newlines') or kwargs.get('text'): + if kwargs.get('universal_newlines') or kwargs.get('text') or kwargs.get('encoding') \ + or kwargs.get('errors'): empty = '' else: empty = b'' @@ -464,7 +509,8 @@ def run(*popenargs, The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes - will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them. + will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them, + or pass capture_output=True to capture both. If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code @@ -600,7 +646,7 @@ def list2cmdline(seq): # Various tools for executing commands and looking at their output and status. # -def getstatusoutput(cmd): +def getstatusoutput(cmd, *, encoding=None, errors=None): """Return (exitcode, output) of executing cmd in a shell. Execute the string 'cmd' in a shell with 'check_output' and @@ -622,7 +668,8 @@ def getstatusoutput(cmd): (-15, '') """ try: - data = check_output(cmd, shell=True, text=True, stderr=STDOUT) + data = check_output(cmd, shell=True, text=True, stderr=STDOUT, + encoding=encoding, errors=errors) exitcode = 0 except CalledProcessError as ex: data = ex.output @@ -631,7 +678,7 @@ def getstatusoutput(cmd): data = data[:-1] return exitcode, data -def getoutput(cmd): +def getoutput(cmd, *, encoding=None, errors=None): """Return output (stdout or stderr) of executing cmd in a shell. Like getstatusoutput(), except the exit status is ignored and the return @@ -641,7 +688,8 @@ def getoutput(cmd): >>> subprocess.getoutput('ls /bin/ls') '/bin/ls' """ - return getstatusoutput(cmd)[1] + return getstatusoutput(cmd, encoding=encoding, errors=errors)[1] + def _use_posix_spawn(): @@ -692,7 +740,10 @@ def _use_posix_spawn(): return False +# These are primarily fail-safe knobs for negatives. A True value does not +# guarantee the given libc/syscall API will be used. _USE_POSIX_SPAWN = _use_posix_spawn() +_USE_VFORK = True class Popen: @@ -733,6 +784,8 @@ class Popen: start_new_session (POSIX only) + process_group (POSIX only) + group (POSIX only) extra_groups (POSIX only) @@ -758,8 +811,14 @@ class Popen: startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, user=None, group=None, extra_groups=None, - encoding=None, errors=None, text=None, umask=-1, pipesize=-1): + encoding=None, errors=None, text=None, umask=-1, pipesize=-1, + process_group=None): """Create new Popen instance.""" + if not _can_fork_exec: + raise OSError( + errno.ENOTSUP, f"{sys.platform} does not support processes." + ) + _cleanup() # Held while anything is calling waitpid before returncode has been # updated to prevent clobbering returncode if wait() or poll() are @@ -845,13 +904,8 @@ class Popen: errread = msvcrt.open_osfhandle(errread.Detach(), 0) self.text_mode = encoding or errors or text or universal_newlines - - # PEP 597: We suppress the EncodingWarning in subprocess module - # for now (at Python 3.10), because we focus on files for now. - # This will be changed to encoding = io.text_encoding(encoding) - # in the future. if self.text_mode and encoding is None: - self.encoding = encoding = "locale" + self.encoding = encoding = _text_encoding() # How long to resume waiting on a child after the first ^C. # There is no right value for this. The purpose is to be polite @@ -869,6 +923,9 @@ class Popen: else: line_buffering = False + if process_group is None: + process_group = -1 # The internal APIs are int-only + gid = None if group is not None: if not hasattr(os, 'setregid'): @@ -972,7 +1029,7 @@ class Popen: errread, errwrite, restore_signals, gid, gids, uid, umask, - start_new_session) + start_new_session, process_group) except: # Cleanup if the child failed starting. for f in filter(None, (self.stdin, self.stdout, self.stderr)): @@ -1356,7 +1413,7 @@ class Popen: unused_restore_signals, unused_gid, unused_gids, unused_uid, unused_umask, - unused_start_new_session): + unused_start_new_session, unused_process_group): """Execute program (MS Windows version)""" assert not pass_fds, "pass_fds not supported on Windows." @@ -1688,7 +1745,7 @@ class Popen: errread, errwrite, restore_signals, gid, gids, uid, umask, - start_new_session): + start_new_session, process_group): """Execute program (POSIX version)""" if isinstance(args, (str, bytes)): @@ -1724,6 +1781,7 @@ class Popen: and (c2pwrite == -1 or c2pwrite > 2) and (errwrite == -1 or errwrite > 2) and not start_new_session + and process_group == -1 and gid is None and gids is None and uid is None @@ -1773,7 +1831,7 @@ class Popen: for dir in os.get_exec_path(env)) fds_to_keep = set(pass_fds) fds_to_keep.add(errpipe_write) - self.pid = _posixsubprocess.fork_exec( + self.pid = _fork_exec( args, executable_list, close_fds, tuple(sorted(map(int, fds_to_keep))), cwd, env_list, @@ -1781,8 +1839,8 @@ class Popen: errread, errwrite, errpipe_read, errpipe_write, restore_signals, start_new_session, - gid, gids, uid, umask, - preexec_fn) + process_group, gid, gids, uid, umask, + preexec_fn, _USE_VFORK) self._child_created = True finally: # be sure the FD is closed no matter what @@ -1845,19 +1903,19 @@ class Popen: def _handle_exitstatus(self, sts, - waitstatus_to_exitcode=os.waitstatus_to_exitcode, - _WIFSTOPPED=os.WIFSTOPPED, - _WSTOPSIG=os.WSTOPSIG): + _waitstatus_to_exitcode=_waitstatus_to_exitcode, + _WIFSTOPPED=_WIFSTOPPED, + _WSTOPSIG=_WSTOPSIG): """All callers to this function MUST hold self._waitpid_lock.""" # This method is called (indirectly) by __del__, so it cannot # refer to anything outside of its local scope. if _WIFSTOPPED(sts): self.returncode = -_WSTOPSIG(sts) else: - self.returncode = waitstatus_to_exitcode(sts) + self.returncode = _waitstatus_to_exitcode(sts) - def _internal_poll(self, _deadstate=None, _waitpid=os.waitpid, - _WNOHANG=os.WNOHANG, _ECHILD=errno.ECHILD): + def _internal_poll(self, _deadstate=None, _waitpid=_waitpid, + _WNOHANG=_WNOHANG, _ECHILD=errno.ECHILD): """Check if child process has terminated. Returns returncode attribute. diff --git a/Lib/sunau.py b/Lib/sunau.py index 79750a9d23e..c6caab959ab 100644 --- a/Lib/sunau.py +++ b/Lib/sunau.py @@ -104,6 +104,9 @@ is destroyed. """ from collections import namedtuple +import warnings + +warnings._deprecated(__name__, remove=(3, 13)) _sunau_params = namedtuple('_sunau_params', @@ -157,7 +160,7 @@ def _write_u32(file, x): class Au_read: def __init__(self, f): - if type(f) == type(''): + if isinstance(f, str): import builtins f = builtins.open(f, 'rb') self._opened = True @@ -275,7 +278,9 @@ class Au_read: data = self._file.read(nframes * self._framesize) self._soundpos += len(data) // self._framesize if self._encoding == AUDIO_FILE_ENCODING_MULAW_8: - import audioop + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=DeprecationWarning) + import audioop data = audioop.ulaw2lin(data, self._sampwidth) return data return None # XXX--not implemented yet @@ -307,7 +312,7 @@ class Au_read: class Au_write: def __init__(self, f): - if type(f) == type(''): + if isinstance(f, str): import builtins f = builtins.open(f, 'wb') self._opened = True @@ -421,7 +426,9 @@ class Au_write: data = memoryview(data).cast('B') self._ensure_header_written() if self._comptype == 'ULAW': - import audioop + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=DeprecationWarning) + import audioop data = audioop.lin2ulaw(data, self._sampwidth) nframes = len(data) // self._framesize self._file.write(data) diff --git a/Lib/symtable.py b/Lib/symtable.py index 75ff0921f4c..5dd71ffc6b4 100644 --- a/Lib/symtable.py +++ b/Lib/symtable.py @@ -111,7 +111,7 @@ class SymbolTable: return bool(self._table.children) def get_identifiers(self): - """Return a list of names of symbols in the table. + """Return a view object containing the names of symbols in the table. """ return self._table.symbols.keys() diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py index daf9f000060..c61100a6da8 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -2,6 +2,7 @@ import os import sys +import threading from os.path import pardir, realpath __all__ = [ @@ -56,8 +57,53 @@ _INSTALL_SCHEMES = { 'scripts': '{base}/Scripts', 'data': '{base}', }, + # Downstream distributors can overwrite the default install scheme. + # This is done to support downstream modifications where distributors change + # the installation layout (eg. different site-packages directory). + # So, distributors will change the default scheme to one that correctly + # represents their layout. + # This presents an issue for projects/people that need to bootstrap virtual + # environments, like virtualenv. As distributors might now be customizing + # the default install scheme, there is no guarantee that the information + # returned by sysconfig.get_default_scheme/get_paths is correct for + # a virtual environment, the only guarantee we have is that it is correct + # for the *current* environment. When bootstrapping a virtual environment, + # we need to know its layout, so that we can place the files in the + # correct locations. + # The "*_venv" install scheme is a scheme to bootstrap virtual environments, + # essentially identical to the default posix_prefix/nt schemes. + # Downstream distributors who patch posix_prefix/nt scheme are encouraged to + # leave the following schemes unchanged + 'posix_venv': { + 'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}', + 'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}', + 'purelib': '{base}/lib/python{py_version_short}/site-packages', + 'platlib': '{platbase}/{platlibdir}/python{py_version_short}/site-packages', + 'include': + '{installed_base}/include/python{py_version_short}{abiflags}', + 'platinclude': + '{installed_platbase}/include/python{py_version_short}{abiflags}', + 'scripts': '{base}/bin', + 'data': '{base}', + }, + 'nt_venv': { + 'stdlib': '{installed_base}/Lib', + 'platstdlib': '{base}/Lib', + 'purelib': '{base}/Lib/site-packages', + 'platlib': '{base}/Lib/site-packages', + 'include': '{installed_base}/Include', + 'platinclude': '{installed_base}/Include', + 'scripts': '{base}/Scripts', + 'data': '{base}', + }, } +# For the OS-native venv scheme, we essentially provide an alias: +if os.name == 'nt': + _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['nt_venv'] +else: + _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['posix_venv'] + # NOTE: site.py has copy of this function. # Sync it when modify this function. @@ -66,8 +112,8 @@ def _getuserbase(): if env_base: return env_base - # VxWorks has no home directories - if sys.platform == "vxworks": + # Emscripten, VxWorks, and WASI have no home directories + if sys.platform in {"emscripten", "vxworks", "wasi"}: return None def joinuser(*args): @@ -127,7 +173,11 @@ _PREFIX = os.path.normpath(sys.prefix) _BASE_PREFIX = os.path.normpath(sys.base_prefix) _EXEC_PREFIX = os.path.normpath(sys.exec_prefix) _BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix) +# Mutex guarding initialization of _CONFIG_VARS. +_CONFIG_VARS_LOCK = threading.RLock() _CONFIG_VARS = None +# True iff _CONFIG_VARS has been fully initialized. +_CONFIG_VARS_INITIALIZED = False _USER_BASE = None # Regexes needed for parsing Makefile (and similar syntaxes, @@ -150,37 +200,38 @@ else: # unable to retrieve the real program name _PROJECT_BASE = _safe_realpath(os.getcwd()) -if (os.name == 'nt' and - _PROJECT_BASE.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))): - _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) +# In a virtual environment, `sys._home` gives us the target directory +# `_PROJECT_BASE` for the executable that created it when the virtual +# python is an actual executable ('venv --copies' or Windows). +_sys_home = getattr(sys, '_home', None) +if _sys_home: + _PROJECT_BASE = _sys_home + +if os.name == 'nt': + # In a source build, the executable is in a subdirectory of the root + # that we want (\PCbuild\). + # `_BASE_PREFIX` is used as the base installation is where the source + # will be. The realpath is needed to prevent mount point confusion + # that can occur with just string comparisons. + if _safe_realpath(_PROJECT_BASE).startswith( + _safe_realpath(f'{_BASE_PREFIX}\\PCbuild')): + _PROJECT_BASE = _BASE_PREFIX # set for cross builds if "_PYTHON_PROJECT_BASE" in os.environ: _PROJECT_BASE = _safe_realpath(os.environ["_PYTHON_PROJECT_BASE"]) -def _is_python_source_dir(d): +def is_python_build(check_home=None): + if check_home is not None: + import warnings + warnings.warn("check_home argument is deprecated and ignored.", + DeprecationWarning, stacklevel=2) for fn in ("Setup", "Setup.local"): - if os.path.isfile(os.path.join(d, "Modules", fn)): + if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): return True return False -_sys_home = getattr(sys, '_home', None) - -if os.name == 'nt': - def _fix_pcbuild(d): - if d and os.path.normcase(d).startswith( - os.path.normcase(os.path.join(_PREFIX, "PCbuild"))): - return _PREFIX - return d - _PROJECT_BASE = _fix_pcbuild(_PROJECT_BASE) - _sys_home = _fix_pcbuild(_sys_home) - -def is_python_build(check_home=False): - if check_home and _sys_home: - return _is_python_source_dir(_sys_home) - return _is_python_source_dir(_PROJECT_BASE) - -_PYTHON_BUILD = is_python_build(True) +_PYTHON_BUILD = is_python_build() if _PYTHON_BUILD: for scheme in ('posix_prefix', 'posix_home'): @@ -192,6 +243,7 @@ if _PYTHON_BUILD: scheme['headers'] = scheme['include'] scheme['include'] = '{srcdir}/Include' scheme['platinclude'] = '{projectbase}/.' + del scheme def _subst_vars(s, local_vars): @@ -216,6 +268,11 @@ def _expand_vars(scheme, vars): if vars is None: vars = {} _extend_dict(vars, get_config_vars()) + if os.name == 'nt': + # On Windows we want to substitute 'lib' for schemes rather + # than the native value (without modifying vars, in case it + # was passed in) + vars = vars | {'platlibdir': 'lib'} for key, value in _INSTALL_SCHEMES[scheme].items(): if os.name in ('posix', 'nt'): @@ -245,6 +302,8 @@ def _get_preferred_schemes(): def get_preferred_scheme(key): + if key == 'prefix' and sys.prefix != sys.base_prefix: + return 'venv' scheme = _get_preferred_schemes()[key] if scheme not in _INSTALL_SCHEMES: raise ValueError( @@ -389,7 +448,7 @@ def _parse_makefile(filename, vars=None, keep_unresolved=True): def get_makefile_filename(): """Return the path of the Makefile.""" if _PYTHON_BUILD: - return os.path.join(_sys_home or _PROJECT_BASE, "Makefile") + return os.path.join(_PROJECT_BASE, "Makefile") if hasattr(sys, 'abiflags'): config_dir_name = f'config-{_PY_VERSION_SHORT}{sys.abiflags}' else: @@ -485,7 +544,12 @@ def _init_non_posix(vars): vars['LIBDEST'] = get_path('stdlib') vars['BINLIBDEST'] = get_path('platstdlib') vars['INCLUDEPY'] = get_path('include') - vars['EXT_SUFFIX'] = _imp.extension_suffixes()[0] + try: + # GH-99201: _imp.extension_suffixes may be empty when + # HAVE_DYNAMIC_LOADING is not set. In this case, don't set EXT_SUFFIX. + vars['EXT_SUFFIX'] = _imp.extension_suffixes()[0] + except IndexError: + pass vars['EXE'] = '.exe' vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) @@ -534,9 +598,9 @@ def get_config_h_filename(): """Return the path of pyconfig.h.""" if _PYTHON_BUILD: if os.name == "nt": - inc_dir = os.path.join(_sys_home or _PROJECT_BASE, "PC") + inc_dir = os.path.join(_PROJECT_BASE, "PC") else: - inc_dir = _sys_home or _PROJECT_BASE + inc_dir = _PROJECT_BASE else: inc_dir = get_path('platinclude') return os.path.join(inc_dir, 'pyconfig.h') @@ -572,6 +636,71 @@ def get_path(name, scheme=get_default_scheme(), vars=None, expand=True): return get_paths(scheme, vars, expand)[name] +def _init_config_vars(): + global _CONFIG_VARS + _CONFIG_VARS = {} + # Normalized versions of prefix and exec_prefix are handy to have; + # in fact, these are the standard versions used most places in the + # Distutils. + _CONFIG_VARS['prefix'] = _PREFIX + _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX + _CONFIG_VARS['py_version'] = _PY_VERSION + _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT + _CONFIG_VARS['py_version_nodot'] = _PY_VERSION_SHORT_NO_DOT + _CONFIG_VARS['installed_base'] = _BASE_PREFIX + _CONFIG_VARS['base'] = _PREFIX + _CONFIG_VARS['installed_platbase'] = _BASE_EXEC_PREFIX + _CONFIG_VARS['platbase'] = _EXEC_PREFIX + _CONFIG_VARS['projectbase'] = _PROJECT_BASE + _CONFIG_VARS['platlibdir'] = sys.platlibdir + try: + _CONFIG_VARS['abiflags'] = sys.abiflags + except AttributeError: + # sys.abiflags may not be defined on all platforms. + _CONFIG_VARS['abiflags'] = '' + try: + _CONFIG_VARS['py_version_nodot_plat'] = sys.winver.replace('.', '') + except AttributeError: + _CONFIG_VARS['py_version_nodot_plat'] = '' + + if os.name == 'nt': + _init_non_posix(_CONFIG_VARS) + _CONFIG_VARS['VPATH'] = sys._vpath + if os.name == 'posix': + _init_posix(_CONFIG_VARS) + if _HAS_USER_BASE: + # Setting 'userbase' is done below the call to the + # init function to enable using 'get_config_var' in + # the init-function. + _CONFIG_VARS['userbase'] = _getuserbase() + + # Always convert srcdir to an absolute path + srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE) + if os.name == 'posix': + if _PYTHON_BUILD: + # If srcdir is a relative path (typically '.' or '..') + # then it should be interpreted relative to the directory + # containing Makefile. + base = os.path.dirname(get_makefile_filename()) + srcdir = os.path.join(base, srcdir) + else: + # srcdir is not meaningful since the installation is + # spread about the filesystem. We choose the + # directory containing the Makefile since we know it + # exists. + srcdir = os.path.dirname(get_makefile_filename()) + _CONFIG_VARS['srcdir'] = _safe_realpath(srcdir) + + # OS X platforms require special customization to handle + # multi-architecture, multi-os-version installers + if sys.platform == 'darwin': + import _osx_support + _osx_support.customize_config_vars(_CONFIG_VARS) + + global _CONFIG_VARS_INITIALIZED + _CONFIG_VARS_INITIALIZED = True + + def get_config_vars(*args): """With no arguments, return a dictionary of all configuration variables relevant for the current platform. @@ -582,69 +711,16 @@ def get_config_vars(*args): With arguments, return a list of values that result from looking up each argument in the configuration variable dictionary. """ - global _CONFIG_VARS - if _CONFIG_VARS is None: - _CONFIG_VARS = {} - # Normalized versions of prefix and exec_prefix are handy to have; - # in fact, these are the standard versions used most places in the - # Distutils. - _CONFIG_VARS['prefix'] = _PREFIX - _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX - _CONFIG_VARS['py_version'] = _PY_VERSION - _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT - _CONFIG_VARS['py_version_nodot'] = _PY_VERSION_SHORT_NO_DOT - _CONFIG_VARS['installed_base'] = _BASE_PREFIX - _CONFIG_VARS['base'] = _PREFIX - _CONFIG_VARS['installed_platbase'] = _BASE_EXEC_PREFIX - _CONFIG_VARS['platbase'] = _EXEC_PREFIX - _CONFIG_VARS['projectbase'] = _PROJECT_BASE - _CONFIG_VARS['platlibdir'] = sys.platlibdir - try: - _CONFIG_VARS['abiflags'] = sys.abiflags - except AttributeError: - # sys.abiflags may not be defined on all platforms. - _CONFIG_VARS['abiflags'] = '' - try: - _CONFIG_VARS['py_version_nodot_plat'] = sys.winver.replace('.', '') - except AttributeError: - _CONFIG_VARS['py_version_nodot_plat'] = '' - if os.name == 'nt': - _init_non_posix(_CONFIG_VARS) - if os.name == 'posix': - _init_posix(_CONFIG_VARS) - # For backward compatibility, see issue19555 - SO = _CONFIG_VARS.get('EXT_SUFFIX') - if SO is not None: - _CONFIG_VARS['SO'] = SO - if _HAS_USER_BASE: - # Setting 'userbase' is done below the call to the - # init function to enable using 'get_config_var' in - # the init-function. - _CONFIG_VARS['userbase'] = _getuserbase() - - # Always convert srcdir to an absolute path - srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE) - if os.name == 'posix': - if _PYTHON_BUILD: - # If srcdir is a relative path (typically '.' or '..') - # then it should be interpreted relative to the directory - # containing Makefile. - base = os.path.dirname(get_makefile_filename()) - srcdir = os.path.join(base, srcdir) - else: - # srcdir is not meaningful since the installation is - # spread about the filesystem. We choose the - # directory containing the Makefile since we know it - # exists. - srcdir = os.path.dirname(get_makefile_filename()) - _CONFIG_VARS['srcdir'] = _safe_realpath(srcdir) - - # OS X platforms require special customization to handle - # multi-architecture, multi-os-version installers - if sys.platform == 'darwin': - import _osx_support - _osx_support.customize_config_vars(_CONFIG_VARS) + # Avoid claiming the lock once initialization is complete. + if not _CONFIG_VARS_INITIALIZED: + with _CONFIG_VARS_LOCK: + # Test again with the lock held to avoid races. Note that + # we test _CONFIG_VARS here, not _CONFIG_VARS_INITIALIZED, + # to ensure that recursive calls to get_config_vars() + # don't re-enter init_config_vars(). + if _CONFIG_VARS is None: + _init_config_vars() if args: vals = [] @@ -661,9 +737,6 @@ def get_config_var(name): Equivalent to get_config_vars().get(name) """ - if name == 'SO': - import warnings - warnings.warn('SO is deprecated, use EXT_SUFFIX', DeprecationWarning, 2) return get_config_vars().get(name) diff --git a/Lib/tabnanny.py b/Lib/tabnanny.py index 7973f26f98b..a47f5a96b89 100755 --- a/Lib/tabnanny.py +++ b/Lib/tabnanny.py @@ -23,8 +23,6 @@ __version__ = "6" import os import sys import tokenize -if not hasattr(tokenize, 'NL'): - raise ValueError("tokenize.NL doesn't exist -- tokenize module too old") __all__ = ["check", "NannyNag", "process_tokens"] diff --git a/Lib/tarfile.py b/Lib/tarfile.py index c1ee1222e09..d686435d90a 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -57,13 +57,9 @@ except ImportError: grp = None # os.symlink on Windows prior to 6.0 raises NotImplementedError -symlink_exception = (AttributeError, NotImplementedError) -try: - # OSError (winerror=1314) will be raised if the caller does not hold the - # SeCreateSymbolicLinkPrivilege privilege - symlink_exception += (OSError,) -except NameError: - pass +# OSError (winerror=1314) will be raised if the caller does not hold the +# SeCreateSymbolicLinkPrivilege privilege +symlink_exception = (AttributeError, NotImplementedError, OSError) # from tarfile import * __all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError", "ReadError", @@ -336,7 +332,8 @@ class _Stream: _Stream is intended to be used only internally. """ - def __init__(self, name, mode, comptype, fileobj, bufsize): + def __init__(self, name, mode, comptype, fileobj, bufsize, + compresslevel): """Construct a _Stream object. """ self._extfileobj = True @@ -371,7 +368,7 @@ class _Stream: self._init_read_gz() self.exception = zlib.error else: - self._init_write_gz() + self._init_write_gz(compresslevel) elif comptype == "bz2": try: @@ -383,7 +380,7 @@ class _Stream: self.cmp = bz2.BZ2Decompressor() self.exception = OSError else: - self.cmp = bz2.BZ2Compressor() + self.cmp = bz2.BZ2Compressor(compresslevel) elif comptype == "xz": try: @@ -410,13 +407,14 @@ class _Stream: if hasattr(self, "closed") and not self.closed: self.close() - def _init_write_gz(self): + def _init_write_gz(self, compresslevel): """Initialize for writing with gzip compression. """ - self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED, - -self.zlib.MAX_WBITS, - self.zlib.DEF_MEM_LEVEL, - 0) + self.cmp = self.zlib.compressobj(compresslevel, + self.zlib.DEFLATED, + -self.zlib.MAX_WBITS, + self.zlib.DEF_MEM_LEVEL, + 0) timestamp = struct.pack(" self._max_size: self.rollover() - self._file.truncate(size) + return self._file.truncate(size) + + def writable(self): + return self._file.writable() def write(self, s): file = self._file @@ -782,6 +837,9 @@ class SpooledTemporaryFile: self._check(file) return rv + def detach(self): + return self._file.detach() + class TemporaryDirectory: """Create and return a temporary directory. This has the same diff --git a/Lib/test/_test_atexit.py b/Lib/test/_test_atexit.py index a3165853111..55d28083349 100644 --- a/Lib/test/_test_atexit.py +++ b/Lib/test/_test_atexit.py @@ -116,6 +116,21 @@ class GeneralTest(unittest.TestCase): atexit._run_exitfuncs() self.assertEqual(l, [5]) + def test_atexit_with_unregistered_function(self): + # See bpo-46025 for more info + def func(): + atexit.unregister(func) + 1/0 + atexit.register(func) + try: + with support.catch_unraisable_exception() as cm: + atexit._run_exitfuncs() + self.assertEqual(cm.unraisable.object, func) + self.assertEqual(cm.unraisable.exc_type, ZeroDivisionError) + self.assertEqual(type(cm.unraisable.exc_value), ZeroDivisionError) + finally: + atexit.unregister(func) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/_test_eintr.py b/Lib/test/_test_eintr.py index e43b59d064f..006581f7cc6 100644 --- a/Lib/test/_test_eintr.py +++ b/Lib/test/_test_eintr.py @@ -403,11 +403,9 @@ class SignalEINTRTest(EINTRBaseTest): old_mask = signal.pthread_sigmask(signal.SIG_BLOCK, [signum]) self.addCleanup(signal.pthread_sigmask, signal.SIG_UNBLOCK, [signum]) - t0 = time.monotonic() proc = self.subprocess(code) with kill_on_error(proc): wait_func(signum) - dt = time.monotonic() - t0 self.assertEqual(proc.wait(), 0) @@ -497,16 +495,18 @@ class FNTLEINTRTest(EINTRBaseTest): proc = self.subprocess(code) with kill_on_error(proc): with open(os_helper.TESTFN, 'wb') as f: - while True: # synchronize the subprocess - dt = time.monotonic() - start_time - if dt > 60.0: - raise Exception("failed to sync child in %.1f sec" % dt) + # synchronize the subprocess + start_time = time.monotonic() + for _ in support.sleeping_retry(support.LONG_TIMEOUT, error=False): try: lock_func(f, fcntl.LOCK_EX | fcntl.LOCK_NB) lock_func(f, fcntl.LOCK_UN) - time.sleep(0.01) except BlockingIOError: break + else: + dt = time.monotonic() - start_time + raise Exception("failed to sync child in %.1f sec" % dt) + # the child locked the file just a moment ago for 'sleep_time' seconds # that means that the lock below will block for 'sleep_time' minus some # potential context switch delay diff --git a/Lib/test/_test_embed_set_config.py b/Lib/test/_test_embed_set_config.py index 23c927e2646..0c016b5d75d 100644 --- a/Lib/test/_test_embed_set_config.py +++ b/Lib/test/_test_embed_set_config.py @@ -1,7 +1,7 @@ # bpo-42260: Test _PyInterpreterState_GetConfigCopy() # and _PyInterpreterState_SetConfig(). # -# Test run in a subinterpreter since set_config(get_config()) +# Test run in a subprocess since set_config(get_config()) # does reset sys attributes to their state of the Python startup # (before the site module is run). @@ -20,6 +20,7 @@ class SetConfigTests(unittest.TestCase): self.sys_copy = dict(sys.__dict__) def tearDown(self): + _testinternalcapi.reset_path_config() _testinternalcapi.set_config(self.old_config) sys.__dict__.clear() sys.__dict__.update(self.sys_copy) @@ -61,7 +62,7 @@ class SetConfigTests(unittest.TestCase): 'faulthandler', 'tracemalloc', 'import_time', - 'no_debug_ranges', + 'code_debug_ranges', 'show_ref_count', 'dump_refs', 'malloc_stats', @@ -83,7 +84,6 @@ class SetConfigTests(unittest.TestCase): 'skip_source_first_line', '_install_importlib', '_init_main', - '_isolated_interpreter', ] if MS_WINDOWS: options.append('legacy_windows_stdio') @@ -235,10 +235,11 @@ class SetConfigTests(unittest.TestCase): module_search_paths=['a', 'b', 'c']) self.assertEqual(sys.path, ['a', 'b', 'c']) - # Leave sys.path unchanged if module_search_paths_set=0 + # sys.path is reset if module_search_paths_set=0 self.set_config(module_search_paths_set=0, module_search_paths=['new_path']) - self.assertEqual(sys.path, ['a', 'b', 'c']) + self.assertNotEqual(sys.path, ['a', 'b', 'c']) + self.assertNotEqual(sys.path, ['new_path']) def test_argv(self): self.set_config(parse_argv=0, diff --git a/Lib/test/_test_embed_structseq.py b/Lib/test/_test_embed_structseq.py new file mode 100644 index 00000000000..868f9f83e8b --- /dev/null +++ b/Lib/test/_test_embed_structseq.py @@ -0,0 +1,55 @@ +import sys +import types +import unittest + + +# bpo-46417: Test that structseq types used by the sys module are still +# valid when Py_Finalize()/Py_Initialize() are called multiple times. +class TestStructSeq(unittest.TestCase): + # test PyTypeObject members + def check_structseq(self, obj_type): + # ob_refcnt + self.assertGreaterEqual(sys.getrefcount(obj_type), 1) + # tp_base + self.assertTrue(issubclass(obj_type, tuple)) + # tp_bases + self.assertEqual(obj_type.__bases__, (tuple,)) + # tp_dict + self.assertIsInstance(obj_type.__dict__, types.MappingProxyType) + # tp_mro + self.assertEqual(obj_type.__mro__, (obj_type, tuple, object)) + # tp_name + self.assertIsInstance(type.__name__, str) + # tp_subclasses + self.assertEqual(obj_type.__subclasses__(), []) + + def test_sys_attrs(self): + for attr_name in ( + 'flags', # FlagsType + 'float_info', # FloatInfoType + 'hash_info', # Hash_InfoType + 'int_info', # Int_InfoType + 'thread_info', # ThreadInfoType + 'version_info', # VersionInfoType + ): + with self.subTest(attr=attr_name): + attr = getattr(sys, attr_name) + self.check_structseq(type(attr)) + + def test_sys_funcs(self): + func_names = ['get_asyncgen_hooks'] # AsyncGenHooksType + if hasattr(sys, 'getwindowsversion'): + func_names.append('getwindowsversion') # WindowsVersionType + for func_name in func_names: + with self.subTest(func=func_name): + func = getattr(sys, func_name) + obj = func() + self.check_structseq(type(obj)) + + +try: + unittest.main() +except SystemExit as exc: + if exc.args[0] != 0: + raise +print("Tests passed") diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 3bc5b8f3d79..2fa75eb4d11 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -5,6 +5,7 @@ import unittest import unittest.mock import queue as pyqueue +import textwrap import time import io import itertools @@ -20,6 +21,7 @@ import logging import subprocess import struct import operator +import pathlib import pickle import weakref import warnings @@ -73,6 +75,12 @@ except ImportError: msvcrt = None +if support.check_sanitizer(address=True): + # bpo-45200: Skip multiprocessing tests if Python is built with ASAN to + # work around a libasan race condition: dead lock in pthread_create(). + raise unittest.SkipTest("libasan has a pthread_create() dead lock") + + def latin(s): return s.encode('latin') @@ -113,6 +121,11 @@ if CHECK_TIMINGS: else: TIMEOUT1, TIMEOUT2, TIMEOUT3 = 0.1, 0.1, 0.1 +# BaseManager.shutdown_timeout +SHUTDOWN_TIMEOUT = support.SHORT_TIMEOUT + +WAIT_ACTIVE_CHILDREN_TIMEOUT = 5.0 + HAVE_GETVALUE = not getattr(_multiprocessing, 'HAVE_BROKEN_SEM_GETVALUE', False) @@ -247,6 +260,45 @@ class _TestProcess(BaseTestCase): self.assertEqual(current.ident, os.getpid()) self.assertEqual(current.exitcode, None) + def test_set_executable(self): + if self.TYPE == 'threads': + self.skipTest(f'test not appropriate for {self.TYPE}') + paths = [ + sys.executable, # str + sys.executable.encode(), # bytes + pathlib.Path(sys.executable) # os.PathLike + ] + for path in paths: + self.set_executable(path) + p = self.Process() + p.start() + p.join() + self.assertEqual(p.exitcode, 0) + + def test_args_argument(self): + # bpo-45735: Using list or tuple as *args* in constructor could + # achieve the same effect. + args_cases = (1, "str", [1], (1,)) + args_types = (list, tuple) + + test_cases = itertools.product(args_cases, args_types) + + for args, args_type in test_cases: + with self.subTest(args=args, args_type=args_type): + q = self.Queue(1) + # pass a tuple or list as args + p = self.Process(target=self._test_args, args=args_type((q, args))) + p.daemon = True + p.start() + child_args = q.get() + self.assertEqual(child_args, args) + p.join() + close_queue(q) + + @classmethod + def _test_args(cls, q, arg): + q.put(arg) + def test_daemon_argument(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -1645,7 +1697,20 @@ class _TestEvent(BaseTestCase): self.assertEqual(wait(), True) p.join() -# + def test_repr(self) -> None: + event = self.Event() + if self.TYPE == 'processes': + self.assertRegex(repr(event), r"") + event.set() + self.assertRegex(repr(event), r"") + event.clear() + self.assertRegex(repr(event), r"") + elif self.TYPE == 'manager': + self.assertRegex(repr(event), r" 1: - time.sleep(t) - t *= 2 - dt = time.monotonic() - start_time - if dt >= 5.0: - test.support.environment_altered = True - support.print_warning(f"multiprocessing.Manager still has " - f"{multiprocessing.active_children()} " - f"active children after {dt} seconds") + for _ in support.sleeping_retry(timeout, error=False): + if len(multiprocessing.active_children()) <= 1: break + else: + dt = time.monotonic() - start_time + support.environment_altered = True + support.print_warning(f"multiprocessing.Manager still has " + f"{multiprocessing.active_children()} " + f"active children after {dt:.1f} seconds") def run_worker(self, worker, obj): self.proc = multiprocessing.Process(target=worker, args=(obj, )) @@ -5623,45 +5698,48 @@ class TestSyncManagerTypes(unittest.TestCase): @classmethod def _test_list(cls, obj): - assert obj[0] == 5 - assert obj.count(5) == 1 - assert obj.index(5) == 0 + case = unittest.TestCase() + case.assertEqual(obj[0], 5) + case.assertEqual(obj.count(5), 1) + case.assertEqual(obj.index(5), 0) obj.sort() obj.reverse() for x in obj: pass - assert len(obj) == 1 - assert obj.pop(0) == 5 + case.assertEqual(len(obj), 1) + case.assertEqual(obj.pop(0), 5) def test_list(self): o = self.manager.list() o.append(5) self.run_worker(self._test_list, o) - assert not o + self.assertIsNotNone(o) self.assertEqual(len(o), 0) @classmethod def _test_dict(cls, obj): - assert len(obj) == 1 - assert obj['foo'] == 5 - assert obj.get('foo') == 5 - assert list(obj.items()) == [('foo', 5)] - assert list(obj.keys()) == ['foo'] - assert list(obj.values()) == [5] - assert obj.copy() == {'foo': 5} - assert obj.popitem() == ('foo', 5) + case = unittest.TestCase() + case.assertEqual(len(obj), 1) + case.assertEqual(obj['foo'], 5) + case.assertEqual(obj.get('foo'), 5) + case.assertListEqual(list(obj.items()), [('foo', 5)]) + case.assertListEqual(list(obj.keys()), ['foo']) + case.assertListEqual(list(obj.values()), [5]) + case.assertDictEqual(obj.copy(), {'foo': 5}) + case.assertTupleEqual(obj.popitem(), ('foo', 5)) def test_dict(self): o = self.manager.dict() o['foo'] = 5 self.run_worker(self._test_dict, o) - assert not o + self.assertIsNotNone(o) self.assertEqual(len(o), 0) @classmethod def _test_value(cls, obj): - assert obj.value == 1 - assert obj.get() == 1 + case = unittest.TestCase() + case.assertEqual(obj.value, 1) + case.assertEqual(obj.get(), 1) obj.set(2) def test_value(self): @@ -5672,10 +5750,11 @@ class TestSyncManagerTypes(unittest.TestCase): @classmethod def _test_array(cls, obj): - assert obj[0] == 0 - assert obj[1] == 1 - assert len(obj) == 2 - assert list(obj) == [0, 1] + case = unittest.TestCase() + case.assertEqual(obj[0], 0) + case.assertEqual(obj[1], 1) + case.assertEqual(len(obj), 2) + case.assertListEqual(list(obj), [0, 1]) def test_array(self): o = self.manager.Array('i', [0, 1]) @@ -5683,8 +5762,9 @@ class TestSyncManagerTypes(unittest.TestCase): @classmethod def _test_namespace(cls, obj): - assert obj.x == 0 - assert obj.y == 1 + case = unittest.TestCase() + case.assertEqual(obj.x, 0) + case.assertEqual(obj.y, 1) def test_namespace(self): o = self.manager.Namespace() @@ -5693,6 +5773,35 @@ class TestSyncManagerTypes(unittest.TestCase): self.run_worker(self._test_namespace, o) +class TestNamedResource(unittest.TestCase): + def test_global_named_resource_spawn(self): + # + # gh-90549: Check that global named resources in main module + # will not leak by a subprocess, in spawn context. + # + testfn = os_helper.TESTFN + self.addCleanup(os_helper.unlink, testfn) + with open(testfn, 'w', encoding='utf-8') as f: + f.write(textwrap.dedent('''\ + import multiprocessing as mp + + ctx = mp.get_context('spawn') + + global_resource = ctx.Semaphore() + + def submain(): pass + + if __name__ == '__main__': + p = ctx.Process(target=submain) + p.start() + p.join() + ''')) + rc, out, err = test.support.script_helper.assert_python_ok(testfn) + # on error, err = 'UserWarning: resource_tracker: There appear to + # be 1 leaked semaphore objects to clean up at shutdown' + self.assertEqual(err, b'') + + class MiscTestCase(unittest.TestCase): def test__all__(self): # Just make sure names in not_exported are excluded @@ -5736,6 +5845,7 @@ class ProcessesMixin(BaseMixin): current_process = staticmethod(multiprocessing.current_process) parent_process = staticmethod(multiprocessing.parent_process) active_children = staticmethod(multiprocessing.active_children) + set_executable = staticmethod(multiprocessing.set_executable) Pool = staticmethod(multiprocessing.Pool) Pipe = staticmethod(multiprocessing.Pipe) Queue = staticmethod(multiprocessing.Queue) @@ -5785,18 +5895,17 @@ class ManagerMixin(BaseMixin): # only the manager process should be returned by active_children() # but this can take a bit on slow machines, so wait a few seconds # if there are other children too (see #17395) + timeout = WAIT_ACTIVE_CHILDREN_TIMEOUT start_time = time.monotonic() - t = 0.01 - while len(multiprocessing.active_children()) > 1: - time.sleep(t) - t *= 2 - dt = time.monotonic() - start_time - if dt >= 5.0: - test.support.environment_altered = True - support.print_warning(f"multiprocessing.Manager still has " - f"{multiprocessing.active_children()} " - f"active children after {dt} seconds") + for _ in support.sleeping_retry(timeout, error=False): + if len(multiprocessing.active_children()) <= 1: break + else: + dt = time.monotonic() - start_time + support.environment_altered = True + support.print_warning(f"multiprocessing.Manager still has " + f"{multiprocessing.active_children()} " + f"active children after {dt:.1f} seconds") gc.collect() # do garbage collection if cls.manager._number_of_objects() != 0: @@ -5923,3 +6032,15 @@ def install_tests_in_module_dict(remote_globs, start_method): remote_globs['setUpModule'] = setUpModule remote_globs['tearDownModule'] = tearDownModule + + +@unittest.skipIf(not hasattr(_multiprocessing, 'SemLock'), 'SemLock not available') +@unittest.skipIf(sys.platform != "linux", "Linux only") +class SemLockTests(unittest.TestCase): + + def test_semlock_subclass(self): + class SemLock(_multiprocessing.SemLock): + pass + name = f'test_semlock_subclass-{os.getpid()}' + s = SemLock(1, 0, 10, name, False) + _multiprocessing.sem_unlink(name) diff --git a/Lib/test/_test_venv_multiprocessing.py b/Lib/test/_test_venv_multiprocessing.py new file mode 100644 index 00000000000..af72e915ba5 --- /dev/null +++ b/Lib/test/_test_venv_multiprocessing.py @@ -0,0 +1,40 @@ +import multiprocessing +import random +import sys +import time + +def fill_queue(queue, code): + queue.put(code) + + +def drain_queue(queue, code): + if code != queue.get(): + sys.exit(1) + + +def test_func(): + code = random.randrange(0, 1000) + queue = multiprocessing.Queue() + fill_pool = multiprocessing.Process( + target=fill_queue, + args=(queue, code) + ) + drain_pool = multiprocessing.Process( + target=drain_queue, + args=(queue, code) + ) + drain_pool.start() + fill_pool.start() + fill_pool.join() + drain_pool.join() + + +def main(): + test_pool = multiprocessing.Process(target=test_func) + test_pool.start() + test_pool.join() + sys.exit(test_pool.exitcode) + + +if __name__ == "__main__": + main() diff --git a/Lib/test/_testcppext.cpp b/Lib/test/_testcppext.cpp new file mode 100644 index 00000000000..0e381a78c5c --- /dev/null +++ b/Lib/test/_testcppext.cpp @@ -0,0 +1,258 @@ +// gh-91321: Very basic C++ test extension to check that the Python C API is +// compatible with C++ and does not emit C++ compiler warnings. + +// Always enable assertions +#undef NDEBUG + +#include "Python.h" + +#if __cplusplus >= 201103 +# define NAME _testcpp11ext +#else +# define NAME _testcpp03ext +#endif + +#define _STR(NAME) #NAME +#define STR(NAME) _STR(NAME) + +PyDoc_STRVAR(_testcppext_add_doc, +"add(x, y)\n" +"\n" +"Return the sum of two integers: x + y."); + +static PyObject * +_testcppext_add(PyObject *Py_UNUSED(module), PyObject *args) +{ + long i, j; + if (!PyArg_ParseTuple(args, "ll:foo", &i, &j)) { + return _Py_NULL; + } + long res = i + j; + return PyLong_FromLong(res); +} + + +// Class to test operator casting an object to PyObject* +class StrongRef +{ +public: + StrongRef(PyObject *obj) : m_obj(obj) { + Py_INCREF(this->m_obj); + } + + ~StrongRef() { + Py_DECREF(this->m_obj); + } + + // Cast to PyObject*: get a borrowed reference + inline operator PyObject*() const { return this->m_obj; } + +private: + PyObject *m_obj; // Strong reference +}; + + +static PyObject * +test_api_casts(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) +{ + PyObject *obj = Py_BuildValue("(ii)", 1, 2); + if (obj == _Py_NULL) { + return _Py_NULL; + } + Py_ssize_t refcnt = Py_REFCNT(obj); + assert(refcnt >= 1); + + // gh-92138: For backward compatibility, functions of Python C API accepts + // "const PyObject*". Check that using it does not emit C++ compiler + // warnings. + const PyObject *const_obj = obj; + Py_INCREF(const_obj); + Py_DECREF(const_obj); + PyTypeObject *type = Py_TYPE(const_obj); + assert(Py_REFCNT(const_obj) == refcnt); + assert(type == &PyTuple_Type); + assert(PyTuple_GET_SIZE(const_obj) == 2); + PyObject *one = PyTuple_GET_ITEM(const_obj, 0); + assert(PyLong_AsLong(one) == 1); + + // gh-92898: StrongRef doesn't inherit from PyObject but has an operator to + // cast to PyObject*. + StrongRef strong_ref(obj); + assert(Py_TYPE(strong_ref) == &PyTuple_Type); + assert(Py_REFCNT(strong_ref) == (refcnt + 1)); + Py_INCREF(strong_ref); + Py_DECREF(strong_ref); + + // gh-93442: Pass 0 as NULL for PyObject* + Py_XINCREF(0); + Py_XDECREF(0); +#if _cplusplus >= 201103 + // Test nullptr passed as PyObject* + Py_XINCREF(nullptr); + Py_XDECREF(nullptr); +#endif + + Py_DECREF(obj); + Py_RETURN_NONE; +} + + +static PyObject * +test_unicode(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) +{ + PyObject *str = PyUnicode_FromString("abc"); + if (str == _Py_NULL) { + return _Py_NULL; + } + + assert(PyUnicode_Check(str)); + assert(PyUnicode_GET_LENGTH(str) == 3); + + // gh-92800: test PyUnicode_READ() + const void* data = PyUnicode_DATA(str); + assert(data != _Py_NULL); + int kind = PyUnicode_KIND(str); + assert(kind == PyUnicode_1BYTE_KIND); + assert(PyUnicode_READ(kind, data, 0) == 'a'); + + // gh-92800: test PyUnicode_READ() casts + const void* const_data = PyUnicode_DATA(str); + unsigned int ukind = static_cast(kind); + assert(PyUnicode_READ(ukind, const_data, 2) == 'c'); + + assert(PyUnicode_READ_CHAR(str, 1) == 'b'); + + Py_DECREF(str); + Py_RETURN_NONE; +} + +/* Test a `new`-allocated object with a virtual method. + * (https://github.com/python/cpython/issues/94731) */ + +class VirtualPyObject : public PyObject { +public: + VirtualPyObject(); + virtual ~VirtualPyObject() { + delete [] internal_data; + --instance_count; + } + virtual void set_internal_data() { + internal_data[0] = 1; + } + static void dealloc(PyObject* o) { + delete static_cast(o); + } + + // Number of "living" instances + static int instance_count; +private: + // buffer that can get corrupted + int* internal_data; +}; + +int VirtualPyObject::instance_count = 0; + +PyType_Slot VirtualPyObject_Slots[] = { + {Py_tp_free, (void*)VirtualPyObject::dealloc}, + {0, _Py_NULL}, +}; + +PyType_Spec VirtualPyObject_Spec = { + /* .name */ STR(NAME) ".VirtualPyObject", + /* .basicsize */ sizeof(VirtualPyObject), + /* .itemsize */ 0, + /* .flags */ Py_TPFLAGS_DEFAULT, + /* .slots */ VirtualPyObject_Slots, +}; + +VirtualPyObject::VirtualPyObject() { + // Create a temporary type (just so we don't need to store it) + PyObject *type = PyType_FromSpec(&VirtualPyObject_Spec); + // no good way to signal failure from a C++ constructor, so use assert + // for error handling + assert(type); + assert(PyObject_Init(this, (PyTypeObject *)type)); + Py_DECREF(type); + internal_data = new int[50]; + ++instance_count; +} + +static PyObject * +test_virtual_object(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) +{ + VirtualPyObject* obj = new VirtualPyObject(); + obj->set_internal_data(); + Py_DECREF(obj); + if (VirtualPyObject::instance_count != 0) { + return PyErr_Format( + PyExc_AssertionError, + "instance_count should be 0, got %d", + VirtualPyObject::instance_count); + } + Py_RETURN_NONE; +} + +static PyMethodDef _testcppext_methods[] = { + {"add", _testcppext_add, METH_VARARGS, _testcppext_add_doc}, + {"test_api_casts", test_api_casts, METH_NOARGS, _Py_NULL}, + {"test_unicode", test_unicode, METH_NOARGS, _Py_NULL}, + {"test_virtual_object", test_virtual_object, METH_NOARGS, _Py_NULL}, + // Note: _testcppext_exec currently runs all test functions directly. + // When adding a new one, add a call there. + + {_Py_NULL, _Py_NULL, 0, _Py_NULL} /* sentinel */ +}; + + +static int +_testcppext_exec(PyObject *module) +{ + if (PyModule_AddIntMacro(module, __cplusplus) < 0) { + return -1; + } + + PyObject *result; + + result = PyObject_CallMethod(module, "test_api_casts", ""); + if (!result) return -1; + Py_DECREF(result); + + result = PyObject_CallMethod(module, "test_unicode", ""); + if (!result) return -1; + Py_DECREF(result); + + result = PyObject_CallMethod(module, "test_virtual_object", ""); + if (!result) return -1; + Py_DECREF(result); + + return 0; +} + +static PyModuleDef_Slot _testcppext_slots[] = { + {Py_mod_exec, reinterpret_cast(_testcppext_exec)}, + {0, _Py_NULL} +}; + + +PyDoc_STRVAR(_testcppext_doc, "C++ test extension."); + +static struct PyModuleDef _testcppext_module = { + PyModuleDef_HEAD_INIT, // m_base + STR(NAME), // m_name + _testcppext_doc, // m_doc + 0, // m_size + _testcppext_methods, // m_methods + _testcppext_slots, // m_slots + _Py_NULL, // m_traverse + _Py_NULL, // m_clear + _Py_NULL, // m_free +}; + +#define _FUNC_NAME(NAME) PyInit_ ## NAME +#define FUNC_NAME(NAME) _FUNC_NAME(NAME) + +PyMODINIT_FUNC +FUNC_NAME(NAME)(void) +{ + return PyModuleDef_Init(&_testcppext_module); +} diff --git a/Lib/test/_typed_dict_helper.py b/Lib/test/_typed_dict_helper.py index d333db19318..9df0ede7d40 100644 --- a/Lib/test/_typed_dict_helper.py +++ b/Lib/test/_typed_dict_helper.py @@ -6,13 +6,25 @@ look something like this: class Bar(_typed_dict_helper.Foo, total=False): b: int + +In addition, it uses multiple levels of Annotated to test the interaction +between the __future__ import, Annotated, and Required. """ from __future__ import annotations -from typing import Optional, TypedDict +from typing import Annotated, Generic, Optional, Required, TypedDict, TypeVar + OptionalIntType = Optional[int] class Foo(TypedDict): a: OptionalIntType + +T = TypeVar("T") + +class FooGeneric(TypedDict, Generic[T]): + a: Optional[T] + +class VeryAnnotated(TypedDict, total=False): + a: Annotated[Annotated[Annotated[Required[int], "a"], "b"], "c"] diff --git a/Lib/test/ann_module7.py b/Lib/test/ann_module7.py new file mode 100644 index 00000000000..8f890cd2802 --- /dev/null +++ b/Lib/test/ann_module7.py @@ -0,0 +1,11 @@ +# Tests class have ``__text_signature__`` + +from __future__ import annotations + +DEFAULT_BUFFER_SIZE = 8192 + +class BufferedReader(object): + """BufferedReader(raw, buffer_size=DEFAULT_BUFFER_SIZE)\n--\n\n + Create a new buffered reader using the given readable raw IO object. + """ + pass diff --git a/Lib/test/ann_module8.py b/Lib/test/ann_module8.py new file mode 100644 index 00000000000..bd031481378 --- /dev/null +++ b/Lib/test/ann_module8.py @@ -0,0 +1,10 @@ +# Test `@no_type_check`, +# see https://bugs.python.org/issue46571 + +class NoTypeCheck_Outer: + class Inner: + x: int + + +def NoTypeCheck_function(arg: int) -> int: + ... diff --git a/Lib/test/audiodata/pluck-pcm24-ext.wav b/Lib/test/audiodata/pluck-pcm24-ext.wav new file mode 100644 index 00000000000..e4c2d133597 Binary files /dev/null and b/Lib/test/audiodata/pluck-pcm24-ext.wav differ diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py index ccec9fedc44..0edc9d9c472 100644 --- a/Lib/test/audit-tests.py +++ b/Lib/test/audit-tests.py @@ -408,6 +408,112 @@ def test_sqlite3(): raise RuntimeError("Expected sqlite3.load_extension to fail") +def test_sys_getframe(): + import sys + + def hook(event, args): + if event.startswith("sys."): + print(event, args[0].f_code.co_name) + + sys.addaudithook(hook) + sys._getframe() + + +def test_sys_getframemodulename(): + import sys + + def hook(event, args): + if event.startswith("sys."): + print(event, *args) + + sys.addaudithook(hook) + sys._getframemodulename() + + +def test_threading(): + import _thread + + def hook(event, args): + if event.startswith(("_thread.", "cpython.PyThreadState", "test.")): + print(event, args) + + sys.addaudithook(hook) + + lock = _thread.allocate_lock() + lock.acquire() + + class test_func: + def __repr__(self): return "" + def __call__(self): + sys.audit("test.test_func") + lock.release() + + i = _thread.start_new_thread(test_func(), ()) + lock.acquire() + + +def test_threading_abort(): + # Ensures that aborting PyThreadState_New raises the correct exception + import _thread + + class ThreadNewAbortError(Exception): + pass + + def hook(event, args): + if event == "cpython.PyThreadState_New": + raise ThreadNewAbortError() + + sys.addaudithook(hook) + + try: + _thread.start_new_thread(lambda: None, ()) + except ThreadNewAbortError: + # Other exceptions are raised and the test will fail + pass + + +def test_wmi_exec_query(): + import _wmi + + def hook(event, args): + if event.startswith("_wmi."): + print(event, args[0]) + + sys.addaudithook(hook) + _wmi.exec_query("SELECT * FROM Win32_OperatingSystem") + +def test_syslog(): + import syslog + + def hook(event, args): + if event.startswith("syslog."): + print(event, *args) + + sys.addaudithook(hook) + syslog.openlog('python') + syslog.syslog('test') + syslog.setlogmask(syslog.LOG_DEBUG) + syslog.closelog() + # implicit open + syslog.syslog('test2') + # open with default ident + syslog.openlog(logoption=syslog.LOG_NDELAY, facility=syslog.LOG_LOCAL0) + sys.argv = None + syslog.openlog() + syslog.closelog() + + +def test_not_in_gc(): + import gc + + hook = lambda *a: None + sys.addaudithook(hook) + + for o in gc.get_objects(): + if isinstance(o, list): + assert hook not in o + + if __name__ == "__main__": from test.support import suppress_msvcrt_asserts diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test index d2934b3f211..53e5df5ba87 100644 --- a/Lib/test/clinic.test +++ b/Lib/test/clinic.test @@ -21,7 +21,7 @@ PyDoc_STRVAR(test_object_converter__doc__, "\n"); #define TEST_OBJECT_CONVERTER_METHODDEF \ - {"test_object_converter", (PyCFunction)(void(*)(void))test_object_converter, METH_FASTCALL, test_object_converter__doc__}, + {"test_object_converter", _PyCFunction_CAST(test_object_converter), METH_FASTCALL, test_object_converter__doc__}, static PyObject * test_object_converter_impl(PyObject *module, PyObject *a, PyObject *b, @@ -58,7 +58,7 @@ exit: static PyObject * test_object_converter_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyUnicode_Object *d) -/*[clinic end generated code: output=a78312d933df9ea1 input=005e6a8a711a869b]*/ +/*[clinic end generated code: output=886f4f9b598726b6 input=005e6a8a711a869b]*/ /*[clinic input] @@ -97,7 +97,7 @@ PyDoc_STRVAR(test_objects_converter__doc__, "\n"); #define TEST_OBJECTS_CONVERTER_METHODDEF \ - {"test_objects_converter", (PyCFunction)(void(*)(void))test_objects_converter, METH_FASTCALL, test_objects_converter__doc__}, + {"test_objects_converter", _PyCFunction_CAST(test_objects_converter), METH_FASTCALL, test_objects_converter__doc__}, static PyObject * test_objects_converter_impl(PyObject *module, PyObject *a, PyObject *b); @@ -126,7 +126,7 @@ exit: static PyObject * test_objects_converter_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=0e461f38d3b2bd08 input=4cbb3d9edd2a36f3]*/ +/*[clinic end generated code: output=fc26328b79d46bb7 input=4cbb3d9edd2a36f3]*/ /*[clinic input] @@ -153,7 +153,7 @@ PyDoc_STRVAR(test_object_converter_subclass_of__doc__, "\n"); #define TEST_OBJECT_CONVERTER_SUBCLASS_OF_METHODDEF \ - {"test_object_converter_subclass_of", (PyCFunction)(void(*)(void))test_object_converter_subclass_of, METH_FASTCALL, test_object_converter_subclass_of__doc__}, + {"test_object_converter_subclass_of", _PyCFunction_CAST(test_object_converter_subclass_of), METH_FASTCALL, test_object_converter_subclass_of__doc__}, static PyObject * test_object_converter_subclass_of_impl(PyObject *module, PyObject *a, @@ -240,7 +240,7 @@ test_object_converter_subclass_of_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e, PyObject *f, PyObject *g, PyObject *h, PyObject *i, PyObject *j) -/*[clinic end generated code: output=dcf7772bf0c876dd input=31b06b772d5f983e]*/ +/*[clinic end generated code: output=e4b07c9a54479a40 input=31b06b772d5f983e]*/ /*[clinic input] @@ -385,7 +385,7 @@ PyDoc_STRVAR(test_bool_converter__doc__, "\n"); #define TEST_BOOL_CONVERTER_METHODDEF \ - {"test_bool_converter", (PyCFunction)(void(*)(void))test_bool_converter, METH_FASTCALL, test_bool_converter__doc__}, + {"test_bool_converter", _PyCFunction_CAST(test_bool_converter), METH_FASTCALL, test_bool_converter__doc__}, static PyObject * test_bool_converter_impl(PyObject *module, int a, int b, int c); @@ -431,7 +431,7 @@ exit: static PyObject * test_bool_converter_impl(PyObject *module, int a, int b, int c) -/*[clinic end generated code: output=b5ec6409d942e0f9 input=939854fa9f248c60]*/ +/*[clinic end generated code: output=27f0e653a70b9be3 input=939854fa9f248c60]*/ /*[clinic input] @@ -463,7 +463,7 @@ PyDoc_STRVAR(test_char_converter__doc__, "\n"); #define TEST_CHAR_CONVERTER_METHODDEF \ - {"test_char_converter", (PyCFunction)(void(*)(void))test_char_converter, METH_FASTCALL, test_char_converter__doc__}, + {"test_char_converter", _PyCFunction_CAST(test_char_converter), METH_FASTCALL, test_char_converter__doc__}, static PyObject * test_char_converter_impl(PyObject *module, char a, char b, char c, char d, @@ -685,7 +685,7 @@ static PyObject * test_char_converter_impl(PyObject *module, char a, char b, char c, char d, char e, char f, char g, char h, char i, char j, char k, char l, char m, char n) -/*[clinic end generated code: output=9d3aaf5d6857ec9e input=e42330417a44feac]*/ +/*[clinic end generated code: output=98589f02422fe6b1 input=e42330417a44feac]*/ /*[clinic input] @@ -704,7 +704,7 @@ PyDoc_STRVAR(test_unsigned_char_converter__doc__, "\n"); #define TEST_UNSIGNED_CHAR_CONVERTER_METHODDEF \ - {"test_unsigned_char_converter", (PyCFunction)(void(*)(void))test_unsigned_char_converter, METH_FASTCALL, test_unsigned_char_converter__doc__}, + {"test_unsigned_char_converter", _PyCFunction_CAST(test_unsigned_char_converter), METH_FASTCALL, test_unsigned_char_converter__doc__}, static PyObject * test_unsigned_char_converter_impl(PyObject *module, unsigned char a, @@ -787,7 +787,7 @@ exit: static PyObject * test_unsigned_char_converter_impl(PyObject *module, unsigned char a, unsigned char b, unsigned char c) -/*[clinic end generated code: output=c0a6ab3144481466 input=021414060993e289]*/ +/*[clinic end generated code: output=45920dbedc22eb55 input=021414060993e289]*/ /*[clinic input] @@ -804,7 +804,7 @@ PyDoc_STRVAR(test_short_converter__doc__, "\n"); #define TEST_SHORT_CONVERTER_METHODDEF \ - {"test_short_converter", (PyCFunction)(void(*)(void))test_short_converter, METH_FASTCALL, test_short_converter__doc__}, + {"test_short_converter", _PyCFunction_CAST(test_short_converter), METH_FASTCALL, test_short_converter__doc__}, static PyObject * test_short_converter_impl(PyObject *module, short a); @@ -849,7 +849,7 @@ exit: static PyObject * test_short_converter_impl(PyObject *module, short a) -/*[clinic end generated code: output=3ccda4bd08b6e4b4 input=6a8a7a509a498ff4]*/ +/*[clinic end generated code: output=a580945bd6963d45 input=6a8a7a509a498ff4]*/ /*[clinic input] @@ -868,7 +868,7 @@ PyDoc_STRVAR(test_unsigned_short_converter__doc__, "\n"); #define TEST_UNSIGNED_SHORT_CONVERTER_METHODDEF \ - {"test_unsigned_short_converter", (PyCFunction)(void(*)(void))test_unsigned_short_converter, METH_FASTCALL, test_unsigned_short_converter__doc__}, + {"test_unsigned_short_converter", _PyCFunction_CAST(test_unsigned_short_converter), METH_FASTCALL, test_unsigned_short_converter__doc__}, static PyObject * test_unsigned_short_converter_impl(PyObject *module, unsigned short a, @@ -914,7 +914,7 @@ exit: static PyObject * test_unsigned_short_converter_impl(PyObject *module, unsigned short a, unsigned short b, unsigned short c) -/*[clinic end generated code: output=576b5ce48424f351 input=cdfd8eff3d9176b4]*/ +/*[clinic end generated code: output=e6e990df729114fc input=cdfd8eff3d9176b4]*/ /*[clinic input] @@ -934,7 +934,7 @@ PyDoc_STRVAR(test_int_converter__doc__, "\n"); #define TEST_INT_CONVERTER_METHODDEF \ - {"test_int_converter", (PyCFunction)(void(*)(void))test_int_converter, METH_FASTCALL, test_int_converter__doc__}, + {"test_int_converter", _PyCFunction_CAST(test_int_converter), METH_FASTCALL, test_int_converter__doc__}, static PyObject * test_int_converter_impl(PyObject *module, int a, int b, int c, myenum d); @@ -996,7 +996,7 @@ exit: static PyObject * test_int_converter_impl(PyObject *module, int a, int b, int c, myenum d) -/*[clinic end generated code: output=8a1a7b02ebe9eeac input=d20541fc1ca0553e]*/ +/*[clinic end generated code: output=800993036e078c07 input=d20541fc1ca0553e]*/ /*[clinic input] @@ -1015,7 +1015,7 @@ PyDoc_STRVAR(test_unsigned_int_converter__doc__, "\n"); #define TEST_UNSIGNED_INT_CONVERTER_METHODDEF \ - {"test_unsigned_int_converter", (PyCFunction)(void(*)(void))test_unsigned_int_converter, METH_FASTCALL, test_unsigned_int_converter__doc__}, + {"test_unsigned_int_converter", _PyCFunction_CAST(test_unsigned_int_converter), METH_FASTCALL, test_unsigned_int_converter__doc__}, static PyObject * test_unsigned_int_converter_impl(PyObject *module, unsigned int a, @@ -1061,7 +1061,7 @@ exit: static PyObject * test_unsigned_int_converter_impl(PyObject *module, unsigned int a, unsigned int b, unsigned int c) -/*[clinic end generated code: output=4f53904bfa1a0250 input=5533534828b62fc0]*/ +/*[clinic end generated code: output=f9cdbe410ccc98a3 input=5533534828b62fc0]*/ /*[clinic input] @@ -1078,7 +1078,7 @@ PyDoc_STRVAR(test_long_converter__doc__, "\n"); #define TEST_LONG_CONVERTER_METHODDEF \ - {"test_long_converter", (PyCFunction)(void(*)(void))test_long_converter, METH_FASTCALL, test_long_converter__doc__}, + {"test_long_converter", _PyCFunction_CAST(test_long_converter), METH_FASTCALL, test_long_converter__doc__}, static PyObject * test_long_converter_impl(PyObject *module, long a); @@ -1108,7 +1108,7 @@ exit: static PyObject * test_long_converter_impl(PyObject *module, long a) -/*[clinic end generated code: output=e5e7883fddcf4218 input=d2179e3c9cdcde89]*/ +/*[clinic end generated code: output=02b3a83495c1d236 input=d2179e3c9cdcde89]*/ /*[clinic input] @@ -1127,7 +1127,7 @@ PyDoc_STRVAR(test_unsigned_long_converter__doc__, "\n"); #define TEST_UNSIGNED_LONG_CONVERTER_METHODDEF \ - {"test_unsigned_long_converter", (PyCFunction)(void(*)(void))test_unsigned_long_converter, METH_FASTCALL, test_unsigned_long_converter__doc__}, + {"test_unsigned_long_converter", _PyCFunction_CAST(test_unsigned_long_converter), METH_FASTCALL, test_unsigned_long_converter__doc__}, static PyObject * test_unsigned_long_converter_impl(PyObject *module, unsigned long a, @@ -1174,7 +1174,7 @@ exit: static PyObject * test_unsigned_long_converter_impl(PyObject *module, unsigned long a, unsigned long b, unsigned long c) -/*[clinic end generated code: output=87c6b29fa217026e input=f450d94cae1ef73b]*/ +/*[clinic end generated code: output=540bb0ba2894e1fe input=f450d94cae1ef73b]*/ /*[clinic input] @@ -1191,7 +1191,7 @@ PyDoc_STRVAR(test_long_long_converter__doc__, "\n"); #define TEST_LONG_LONG_CONVERTER_METHODDEF \ - {"test_long_long_converter", (PyCFunction)(void(*)(void))test_long_long_converter, METH_FASTCALL, test_long_long_converter__doc__}, + {"test_long_long_converter", _PyCFunction_CAST(test_long_long_converter), METH_FASTCALL, test_long_long_converter__doc__}, static PyObject * test_long_long_converter_impl(PyObject *module, long long a); @@ -1221,7 +1221,7 @@ exit: static PyObject * test_long_long_converter_impl(PyObject *module, long long a) -/*[clinic end generated code: output=0488ac9e8c1d77bb input=d5fc81577ff4dd02]*/ +/*[clinic end generated code: output=f9d4ed79ad2db857 input=d5fc81577ff4dd02]*/ /*[clinic input] @@ -1240,7 +1240,7 @@ PyDoc_STRVAR(test_unsigned_long_long_converter__doc__, "\n"); #define TEST_UNSIGNED_LONG_LONG_CONVERTER_METHODDEF \ - {"test_unsigned_long_long_converter", (PyCFunction)(void(*)(void))test_unsigned_long_long_converter, METH_FASTCALL, test_unsigned_long_long_converter__doc__}, + {"test_unsigned_long_long_converter", _PyCFunction_CAST(test_unsigned_long_long_converter), METH_FASTCALL, test_unsigned_long_long_converter__doc__}, static PyObject * test_unsigned_long_long_converter_impl(PyObject *module, @@ -1291,7 +1291,7 @@ test_unsigned_long_long_converter_impl(PyObject *module, unsigned long long a, unsigned long long b, unsigned long long c) -/*[clinic end generated code: output=aad2c7b43db2f190 input=a15115dc41866ff4]*/ +/*[clinic end generated code: output=3d69994f618b46bb input=a15115dc41866ff4]*/ /*[clinic input] @@ -1310,7 +1310,7 @@ PyDoc_STRVAR(test_Py_ssize_t_converter__doc__, "\n"); #define TEST_PY_SSIZE_T_CONVERTER_METHODDEF \ - {"test_Py_ssize_t_converter", (PyCFunction)(void(*)(void))test_Py_ssize_t_converter, METH_FASTCALL, test_Py_ssize_t_converter__doc__}, + {"test_Py_ssize_t_converter", _PyCFunction_CAST(test_Py_ssize_t_converter), METH_FASTCALL, test_Py_ssize_t_converter__doc__}, static PyObject * test_Py_ssize_t_converter_impl(PyObject *module, Py_ssize_t a, Py_ssize_t b, @@ -1373,7 +1373,7 @@ exit: static PyObject * test_Py_ssize_t_converter_impl(PyObject *module, Py_ssize_t a, Py_ssize_t b, Py_ssize_t c) -/*[clinic end generated code: output=3bf73f9fdfeab468 input=3855f184bb3f299d]*/ +/*[clinic end generated code: output=48214bc3d01f4dd7 input=3855f184bb3f299d]*/ /*[clinic input] @@ -1392,7 +1392,7 @@ PyDoc_STRVAR(test_slice_index_converter__doc__, "\n"); #define TEST_SLICE_INDEX_CONVERTER_METHODDEF \ - {"test_slice_index_converter", (PyCFunction)(void(*)(void))test_slice_index_converter, METH_FASTCALL, test_slice_index_converter__doc__}, + {"test_slice_index_converter", _PyCFunction_CAST(test_slice_index_converter), METH_FASTCALL, test_slice_index_converter__doc__}, static PyObject * test_slice_index_converter_impl(PyObject *module, Py_ssize_t a, Py_ssize_t b, @@ -1437,7 +1437,7 @@ exit: static PyObject * test_slice_index_converter_impl(PyObject *module, Py_ssize_t a, Py_ssize_t b, Py_ssize_t c) -/*[clinic end generated code: output=2148703cd3c6e941 input=edeadb0ee126f531]*/ +/*[clinic end generated code: output=67506ed999361212 input=edeadb0ee126f531]*/ /*[clinic input] @@ -1454,7 +1454,7 @@ PyDoc_STRVAR(test_size_t_converter__doc__, "\n"); #define TEST_SIZE_T_CONVERTER_METHODDEF \ - {"test_size_t_converter", (PyCFunction)(void(*)(void))test_size_t_converter, METH_FASTCALL, test_size_t_converter__doc__}, + {"test_size_t_converter", _PyCFunction_CAST(test_size_t_converter), METH_FASTCALL, test_size_t_converter__doc__}, static PyObject * test_size_t_converter_impl(PyObject *module, size_t a); @@ -1483,7 +1483,7 @@ exit: static PyObject * test_size_t_converter_impl(PyObject *module, size_t a) -/*[clinic end generated code: output=8a91a9ca8a92dabb input=52e93a0fed0f1fb3]*/ +/*[clinic end generated code: output=1653ecb5cbf775aa input=52e93a0fed0f1fb3]*/ /*[clinic input] @@ -1500,7 +1500,7 @@ PyDoc_STRVAR(test_float_converter__doc__, "\n"); #define TEST_FLOAT_CONVERTER_METHODDEF \ - {"test_float_converter", (PyCFunction)(void(*)(void))test_float_converter, METH_FASTCALL, test_float_converter__doc__}, + {"test_float_converter", _PyCFunction_CAST(test_float_converter), METH_FASTCALL, test_float_converter__doc__}, static PyObject * test_float_converter_impl(PyObject *module, float a); @@ -1536,7 +1536,7 @@ exit: static PyObject * test_float_converter_impl(PyObject *module, float a) -/*[clinic end generated code: output=6b9c7443d2601cea input=259c0d98eca35034]*/ +/*[clinic end generated code: output=36ad006990a8a91e input=259c0d98eca35034]*/ /*[clinic input] @@ -1553,7 +1553,7 @@ PyDoc_STRVAR(test_double_converter__doc__, "\n"); #define TEST_DOUBLE_CONVERTER_METHODDEF \ - {"test_double_converter", (PyCFunction)(void(*)(void))test_double_converter, METH_FASTCALL, test_double_converter__doc__}, + {"test_double_converter", _PyCFunction_CAST(test_double_converter), METH_FASTCALL, test_double_converter__doc__}, static PyObject * test_double_converter_impl(PyObject *module, double a); @@ -1589,7 +1589,7 @@ exit: static PyObject * test_double_converter_impl(PyObject *module, double a) -/*[clinic end generated code: output=5b7b9a0f0791b2cc input=c6a9945706a41c27]*/ +/*[clinic end generated code: output=7435925592bac795 input=c6a9945706a41c27]*/ /*[clinic input] @@ -1654,7 +1654,7 @@ PyDoc_STRVAR(test_str_converter__doc__, "\n"); #define TEST_STR_CONVERTER_METHODDEF \ - {"test_str_converter", (PyCFunction)(void(*)(void))test_str_converter, METH_FASTCALL, test_str_converter__doc__}, + {"test_str_converter", _PyCFunction_CAST(test_str_converter), METH_FASTCALL, test_str_converter__doc__}, static PyObject * test_str_converter_impl(PyObject *module, const char *a, const char *b, @@ -1695,7 +1695,7 @@ test_str_converter_impl(PyObject *module, const char *a, const char *b, const char *f, Py_ssize_t f_length, const char *g, Py_ssize_t g_length, const char *h, Py_ssize_t h_length) -/*[clinic end generated code: output=5def009caa2fd1ac input=8afe9da8185cd38c]*/ +/*[clinic end generated code: output=82cb06d5237ef062 input=8afe9da8185cd38c]*/ /*[clinic input] @@ -1716,7 +1716,7 @@ PyDoc_STRVAR(test_str_converter_encoding__doc__, "\n"); #define TEST_STR_CONVERTER_ENCODING_METHODDEF \ - {"test_str_converter_encoding", (PyCFunction)(void(*)(void))test_str_converter_encoding, METH_FASTCALL, test_str_converter_encoding__doc__}, + {"test_str_converter_encoding", _PyCFunction_CAST(test_str_converter_encoding), METH_FASTCALL, test_str_converter_encoding__doc__}, static PyObject * test_str_converter_encoding_impl(PyObject *module, char *a, char *b, char *c, @@ -1740,29 +1740,18 @@ test_str_converter_encoding(PyObject *module, PyObject *const *args, Py_ssize_t goto exit; } return_value = test_str_converter_encoding_impl(module, a, b, c, d, d_length, e, e_length); + /* Post parse cleanup for a */ + PyMem_FREE(a); + /* Post parse cleanup for b */ + PyMem_FREE(b); + /* Post parse cleanup for c */ + PyMem_FREE(c); + /* Post parse cleanup for d */ + PyMem_FREE(d); + /* Post parse cleanup for e */ + PyMem_FREE(e); exit: - /* Cleanup for a */ - if (a) { - PyMem_FREE(a); - } - /* Cleanup for b */ - if (b) { - PyMem_FREE(b); - } - /* Cleanup for c */ - if (c) { - PyMem_FREE(c); - } - /* Cleanup for d */ - if (d) { - PyMem_FREE(d); - } - /* Cleanup for e */ - if (e) { - PyMem_FREE(e); - } - return return_value; } @@ -1770,7 +1759,7 @@ static PyObject * test_str_converter_encoding_impl(PyObject *module, char *a, char *b, char *c, char *d, Py_ssize_t d_length, char *e, Py_ssize_t e_length) -/*[clinic end generated code: output=5cae635c092334cb input=eb4c38e1f898f402]*/ +/*[clinic end generated code: output=999c1deecfa15b0a input=eb4c38e1f898f402]*/ /*[clinic input] @@ -1791,7 +1780,7 @@ PyDoc_STRVAR(test_Py_UNICODE_converter__doc__, "\n"); #define TEST_PY_UNICODE_CONVERTER_METHODDEF \ - {"test_Py_UNICODE_converter", (PyCFunction)(void(*)(void))test_Py_UNICODE_converter, METH_FASTCALL, test_Py_UNICODE_converter__doc__}, + {"test_Py_UNICODE_converter", _PyCFunction_CAST(test_Py_UNICODE_converter), METH_FASTCALL, test_Py_UNICODE_converter__doc__}, static PyObject * test_Py_UNICODE_converter_impl(PyObject *module, const Py_UNICODE *a, @@ -1803,12 +1792,12 @@ static PyObject * test_Py_UNICODE_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - const Py_UNICODE *a; - const Py_UNICODE *b; - const Py_UNICODE *c; - const Py_UNICODE *d; + const Py_UNICODE *a = NULL; + const Py_UNICODE *b = NULL; + const Py_UNICODE *c = NULL; + const Py_UNICODE *d = NULL; Py_ssize_t d_length; - const Py_UNICODE *e; + const Py_UNICODE *e = NULL; Py_ssize_t e_length; if (!_PyArg_ParseStack(args, nargs, "O&O&O&u#Z#:test_Py_UNICODE_converter", @@ -1819,17 +1808,11 @@ test_Py_UNICODE_converter(PyObject *module, PyObject *const *args, Py_ssize_t na exit: /* Cleanup for a */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)a); - #endif /* USE_UNICODE_WCHAR_CACHE */ /* Cleanup for b */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)b); - #endif /* USE_UNICODE_WCHAR_CACHE */ /* Cleanup for c */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)c); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -1839,7 +1822,7 @@ test_Py_UNICODE_converter_impl(PyObject *module, const Py_UNICODE *a, const Py_UNICODE *b, const Py_UNICODE *c, const Py_UNICODE *d, Py_ssize_t d_length, const Py_UNICODE *e, Py_ssize_t e_length) -/*[clinic end generated code: output=65d6607da302afd0 input=064a3b68ad7f04b0]*/ +/*[clinic end generated code: output=9f34a249b3071fdd input=064a3b68ad7f04b0]*/ /*[clinic input] @@ -1860,7 +1843,7 @@ PyDoc_STRVAR(test_Py_buffer_converter__doc__, "\n"); #define TEST_PY_BUFFER_CONVERTER_METHODDEF \ - {"test_Py_buffer_converter", (PyCFunction)(void(*)(void))test_Py_buffer_converter, METH_FASTCALL, test_Py_buffer_converter__doc__}, + {"test_Py_buffer_converter", _PyCFunction_CAST(test_Py_buffer_converter), METH_FASTCALL, test_Py_buffer_converter__doc__}, static PyObject * test_Py_buffer_converter_impl(PyObject *module, Py_buffer *a, Py_buffer *b, @@ -1910,7 +1893,7 @@ exit: static PyObject * test_Py_buffer_converter_impl(PyObject *module, Py_buffer *a, Py_buffer *b, Py_buffer *c, Py_buffer *d, Py_buffer *e) -/*[clinic end generated code: output=5760c82faa2ed61f input=6a9da0f56f9525fd]*/ +/*[clinic end generated code: output=a153b71b4f45f952 input=6a9da0f56f9525fd]*/ /*[clinic input] @@ -1927,7 +1910,7 @@ PyDoc_STRVAR(test_keywords__doc__, "\n"); #define TEST_KEYWORDS_METHODDEF \ - {"test_keywords", (PyCFunction)(void(*)(void))test_keywords, METH_FASTCALL|METH_KEYWORDS, test_keywords__doc__}, + {"test_keywords", _PyCFunction_CAST(test_keywords), METH_FASTCALL|METH_KEYWORDS, test_keywords__doc__}, static PyObject * test_keywords_impl(PyObject *module, PyObject *a, PyObject *b); @@ -1936,8 +1919,31 @@ static PyObject * test_keywords(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keywords", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keywords", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *b; @@ -1956,7 +1962,7 @@ exit: static PyObject * test_keywords_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=4be6cf045ea8242e input=0d3484844749c05b]*/ +/*[clinic end generated code: output=73d46a9ae3320f96 input=0d3484844749c05b]*/ /*[clinic input] @@ -1974,7 +1980,7 @@ PyDoc_STRVAR(test_keywords_kwonly__doc__, "\n"); #define TEST_KEYWORDS_KWONLY_METHODDEF \ - {"test_keywords_kwonly", (PyCFunction)(void(*)(void))test_keywords_kwonly, METH_FASTCALL|METH_KEYWORDS, test_keywords_kwonly__doc__}, + {"test_keywords_kwonly", _PyCFunction_CAST(test_keywords_kwonly), METH_FASTCALL|METH_KEYWORDS, test_keywords_kwonly__doc__}, static PyObject * test_keywords_kwonly_impl(PyObject *module, PyObject *a, PyObject *b); @@ -1983,8 +1989,31 @@ static PyObject * test_keywords_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keywords_kwonly", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keywords_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *b; @@ -2003,7 +2032,7 @@ exit: static PyObject * test_keywords_kwonly_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=d63c4977a7a80713 input=384adc78bfa0bff7]*/ +/*[clinic end generated code: output=c9f02a41f425897d input=384adc78bfa0bff7]*/ /*[clinic input] @@ -2021,7 +2050,7 @@ PyDoc_STRVAR(test_keywords_opt__doc__, "\n"); #define TEST_KEYWORDS_OPT_METHODDEF \ - {"test_keywords_opt", (PyCFunction)(void(*)(void))test_keywords_opt, METH_FASTCALL|METH_KEYWORDS, test_keywords_opt__doc__}, + {"test_keywords_opt", _PyCFunction_CAST(test_keywords_opt), METH_FASTCALL|METH_KEYWORDS, test_keywords_opt__doc__}, static PyObject * test_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, @@ -2031,8 +2060,31 @@ static PyObject * test_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keywords_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keywords_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2064,7 +2116,7 @@ exit: static PyObject * test_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=e5e50d114d8fc10a input=eda7964f784f4607]*/ +/*[clinic end generated code: output=b35d4e66f7283e46 input=eda7964f784f4607]*/ /*[clinic input] @@ -2084,7 +2136,7 @@ PyDoc_STRVAR(test_keywords_opt_kwonly__doc__, "\n"); #define TEST_KEYWORDS_OPT_KWONLY_METHODDEF \ - {"test_keywords_opt_kwonly", (PyCFunction)(void(*)(void))test_keywords_opt_kwonly, METH_FASTCALL|METH_KEYWORDS, test_keywords_opt_kwonly__doc__}, + {"test_keywords_opt_kwonly", _PyCFunction_CAST(test_keywords_opt_kwonly), METH_FASTCALL|METH_KEYWORDS, test_keywords_opt_kwonly__doc__}, static PyObject * test_keywords_opt_kwonly_impl(PyObject *module, PyObject *a, PyObject *b, @@ -2094,8 +2146,31 @@ static PyObject * test_keywords_opt_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keywords_opt_kwonly", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keywords_opt_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2138,7 +2213,7 @@ exit: static PyObject * test_keywords_opt_kwonly_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=3f065cb8309b9317 input=209387a4815e5082]*/ +/*[clinic end generated code: output=ede7e6e65106bf2b input=209387a4815e5082]*/ /*[clinic input] @@ -2157,7 +2232,7 @@ PyDoc_STRVAR(test_keywords_kwonly_opt__doc__, "\n"); #define TEST_KEYWORDS_KWONLY_OPT_METHODDEF \ - {"test_keywords_kwonly_opt", (PyCFunction)(void(*)(void))test_keywords_kwonly_opt, METH_FASTCALL|METH_KEYWORDS, test_keywords_kwonly_opt__doc__}, + {"test_keywords_kwonly_opt", _PyCFunction_CAST(test_keywords_kwonly_opt), METH_FASTCALL|METH_KEYWORDS, test_keywords_kwonly_opt__doc__}, static PyObject * test_keywords_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, @@ -2167,8 +2242,31 @@ static PyObject * test_keywords_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keywords_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keywords_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2200,7 +2298,7 @@ exit: static PyObject * test_keywords_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=94edba5484e1681e input=18393cc64fa000f4]*/ +/*[clinic end generated code: output=36d4df939a4c3eef input=18393cc64fa000f4]*/ /*[clinic input] @@ -2218,7 +2316,7 @@ PyDoc_STRVAR(test_posonly_keywords__doc__, "\n"); #define TEST_POSONLY_KEYWORDS_METHODDEF \ - {"test_posonly_keywords", (PyCFunction)(void(*)(void))test_posonly_keywords, METH_FASTCALL|METH_KEYWORDS, test_posonly_keywords__doc__}, + {"test_posonly_keywords", _PyCFunction_CAST(test_posonly_keywords), METH_FASTCALL|METH_KEYWORDS, test_posonly_keywords__doc__}, static PyObject * test_posonly_keywords_impl(PyObject *module, PyObject *a, PyObject *b); @@ -2227,8 +2325,31 @@ static PyObject * test_posonly_keywords(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *b; @@ -2247,7 +2368,7 @@ exit: static PyObject * test_posonly_keywords_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=eca1507f0182ffb0 input=1767b0ebdf06060e]*/ +/*[clinic end generated code: output=4835f4b6cf386c28 input=1767b0ebdf06060e]*/ /*[clinic input] @@ -2266,7 +2387,7 @@ PyDoc_STRVAR(test_posonly_kwonly__doc__, "\n"); #define TEST_POSONLY_KWONLY_METHODDEF \ - {"test_posonly_kwonly", (PyCFunction)(void(*)(void))test_posonly_kwonly, METH_FASTCALL|METH_KEYWORDS, test_posonly_kwonly__doc__}, + {"test_posonly_kwonly", _PyCFunction_CAST(test_posonly_kwonly), METH_FASTCALL|METH_KEYWORDS, test_posonly_kwonly__doc__}, static PyObject * test_posonly_kwonly_impl(PyObject *module, PyObject *a, PyObject *c); @@ -2275,8 +2396,31 @@ static PyObject * test_posonly_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_kwonly", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *c; @@ -2295,7 +2439,7 @@ exit: static PyObject * test_posonly_kwonly_impl(PyObject *module, PyObject *a, PyObject *c) -/*[clinic end generated code: output=3e14655646b66e9a input=9042f2818f664839]*/ +/*[clinic end generated code: output=2570ea156a8d3cb5 input=9042f2818f664839]*/ /*[clinic input] @@ -2315,7 +2459,7 @@ PyDoc_STRVAR(test_posonly_keywords_kwonly__doc__, "\n"); #define TEST_POSONLY_KEYWORDS_KWONLY_METHODDEF \ - {"test_posonly_keywords_kwonly", (PyCFunction)(void(*)(void))test_posonly_keywords_kwonly, METH_FASTCALL|METH_KEYWORDS, test_posonly_keywords_kwonly__doc__}, + {"test_posonly_keywords_kwonly", _PyCFunction_CAST(test_posonly_keywords_kwonly), METH_FASTCALL|METH_KEYWORDS, test_posonly_keywords_kwonly__doc__}, static PyObject * test_posonly_keywords_kwonly_impl(PyObject *module, PyObject *a, PyObject *b, @@ -2325,8 +2469,31 @@ static PyObject * test_posonly_keywords_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_kwonly", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject *a; PyObject *b; @@ -2348,7 +2515,7 @@ exit: static PyObject * test_posonly_keywords_kwonly_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=de57172fc97a626e input=29546ebdca492fea]*/ +/*[clinic end generated code: output=aaa0e6b5ce02900d input=29546ebdca492fea]*/ /*[clinic input] @@ -2368,7 +2535,7 @@ PyDoc_STRVAR(test_posonly_keywords_opt__doc__, "\n"); #define TEST_POSONLY_KEYWORDS_OPT_METHODDEF \ - {"test_posonly_keywords_opt", (PyCFunction)(void(*)(void))test_posonly_keywords_opt, METH_FASTCALL|METH_KEYWORDS, test_posonly_keywords_opt__doc__}, + {"test_posonly_keywords_opt", _PyCFunction_CAST(test_posonly_keywords_opt), METH_FASTCALL|METH_KEYWORDS, test_posonly_keywords_opt__doc__}, static PyObject * test_posonly_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, @@ -2378,8 +2545,31 @@ static PyObject * test_posonly_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -2413,7 +2603,7 @@ exit: static PyObject * test_posonly_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=8bc6b44a25d4b716 input=cdf5a9625e554e9b]*/ +/*[clinic end generated code: output=1d9f2d8420d0a85f input=cdf5a9625e554e9b]*/ /*[clinic input] @@ -2432,7 +2622,7 @@ PyDoc_STRVAR(test_posonly_keywords_opt2__doc__, "\n"); #define TEST_POSONLY_KEYWORDS_OPT2_METHODDEF \ - {"test_posonly_keywords_opt2", (PyCFunction)(void(*)(void))test_posonly_keywords_opt2, METH_FASTCALL|METH_KEYWORDS, test_posonly_keywords_opt2__doc__}, + {"test_posonly_keywords_opt2", _PyCFunction_CAST(test_posonly_keywords_opt2), METH_FASTCALL|METH_KEYWORDS, test_posonly_keywords_opt2__doc__}, static PyObject * test_posonly_keywords_opt2_impl(PyObject *module, PyObject *a, PyObject *b, @@ -2442,8 +2632,31 @@ static PyObject * test_posonly_keywords_opt2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_opt2", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_opt2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2475,7 +2688,7 @@ exit: static PyObject * test_posonly_keywords_opt2_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=a870c45a6510ba91 input=1581299d21d16f14]*/ +/*[clinic end generated code: output=a83caa0505b296cf input=1581299d21d16f14]*/ /*[clinic input] @@ -2495,7 +2708,7 @@ PyDoc_STRVAR(test_posonly_opt_keywords_opt__doc__, "\n"); #define TEST_POSONLY_OPT_KEYWORDS_OPT_METHODDEF \ - {"test_posonly_opt_keywords_opt", (PyCFunction)(void(*)(void))test_posonly_opt_keywords_opt, METH_FASTCALL|METH_KEYWORDS, test_posonly_opt_keywords_opt__doc__}, + {"test_posonly_opt_keywords_opt", _PyCFunction_CAST(test_posonly_opt_keywords_opt), METH_FASTCALL|METH_KEYWORDS, test_posonly_opt_keywords_opt__doc__}, static PyObject * test_posonly_opt_keywords_opt_impl(PyObject *module, PyObject *a, @@ -2505,8 +2718,31 @@ static PyObject * test_posonly_opt_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_opt_keywords_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_opt_keywords_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2545,7 +2781,7 @@ exit: static PyObject * test_posonly_opt_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=9ae3d52e071d3b7f input=408798ec3d42949f]*/ +/*[clinic end generated code: output=0b24fba3dc04d26b input=408798ec3d42949f]*/ /*[clinic input] @@ -2566,7 +2802,7 @@ PyDoc_STRVAR(test_posonly_kwonly_opt__doc__, "\n"); #define TEST_POSONLY_KWONLY_OPT_METHODDEF \ - {"test_posonly_kwonly_opt", (PyCFunction)(void(*)(void))test_posonly_kwonly_opt, METH_FASTCALL|METH_KEYWORDS, test_posonly_kwonly_opt__doc__}, + {"test_posonly_kwonly_opt", _PyCFunction_CAST(test_posonly_kwonly_opt), METH_FASTCALL|METH_KEYWORDS, test_posonly_kwonly_opt__doc__}, static PyObject * test_posonly_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, @@ -2576,8 +2812,31 @@ static PyObject * test_posonly_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -2611,7 +2870,7 @@ exit: static PyObject * test_posonly_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=fb001f586ba68549 input=8d8e5643bbbc2309]*/ +/*[clinic end generated code: output=592b217bca2f7bcc input=8d8e5643bbbc2309]*/ /*[clinic input] @@ -2631,7 +2890,7 @@ PyDoc_STRVAR(test_posonly_kwonly_opt2__doc__, "\n"); #define TEST_POSONLY_KWONLY_OPT2_METHODDEF \ - {"test_posonly_kwonly_opt2", (PyCFunction)(void(*)(void))test_posonly_kwonly_opt2, METH_FASTCALL|METH_KEYWORDS, test_posonly_kwonly_opt2__doc__}, + {"test_posonly_kwonly_opt2", _PyCFunction_CAST(test_posonly_kwonly_opt2), METH_FASTCALL|METH_KEYWORDS, test_posonly_kwonly_opt2__doc__}, static PyObject * test_posonly_kwonly_opt2_impl(PyObject *module, PyObject *a, PyObject *b, @@ -2641,8 +2900,31 @@ static PyObject * test_posonly_kwonly_opt2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_kwonly_opt2", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_kwonly_opt2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2674,7 +2956,7 @@ exit: static PyObject * test_posonly_kwonly_opt2_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=51aae7cac77b458a input=f7e5eed94f75fff0]*/ +/*[clinic end generated code: output=b8b00420826bc11f input=f7e5eed94f75fff0]*/ /*[clinic input] @@ -2695,7 +2977,7 @@ PyDoc_STRVAR(test_posonly_opt_kwonly_opt__doc__, "\n"); #define TEST_POSONLY_OPT_KWONLY_OPT_METHODDEF \ - {"test_posonly_opt_kwonly_opt", (PyCFunction)(void(*)(void))test_posonly_opt_kwonly_opt, METH_FASTCALL|METH_KEYWORDS, test_posonly_opt_kwonly_opt__doc__}, + {"test_posonly_opt_kwonly_opt", _PyCFunction_CAST(test_posonly_opt_kwonly_opt), METH_FASTCALL|METH_KEYWORDS, test_posonly_opt_kwonly_opt__doc__}, static PyObject * test_posonly_opt_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, @@ -2705,8 +2987,31 @@ static PyObject * test_posonly_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_opt_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_opt_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2745,7 +3050,7 @@ exit: static PyObject * test_posonly_opt_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=68844c45143d1668 input=1e557dc979d120fd]*/ +/*[clinic end generated code: output=3b9ee879ebee285a input=1e557dc979d120fd]*/ /*[clinic input] @@ -2767,7 +3072,7 @@ PyDoc_STRVAR(test_posonly_keywords_kwonly_opt__doc__, "\n"); #define TEST_POSONLY_KEYWORDS_KWONLY_OPT_METHODDEF \ - {"test_posonly_keywords_kwonly_opt", (PyCFunction)(void(*)(void))test_posonly_keywords_kwonly_opt, METH_FASTCALL|METH_KEYWORDS, test_posonly_keywords_kwonly_opt__doc__}, + {"test_posonly_keywords_kwonly_opt", _PyCFunction_CAST(test_posonly_keywords_kwonly_opt), METH_FASTCALL|METH_KEYWORDS, test_posonly_keywords_kwonly_opt__doc__}, static PyObject * test_posonly_keywords_kwonly_opt_impl(PyObject *module, PyObject *a, @@ -2778,8 +3083,31 @@ static PyObject * test_posonly_keywords_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", "d", "e", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; PyObject *a; @@ -2816,7 +3144,7 @@ static PyObject * test_posonly_keywords_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e) -/*[clinic end generated code: output=996ff645551897ac input=c3884a4f956fdc89]*/ +/*[clinic end generated code: output=d380f84f81cc0e45 input=c3884a4f956fdc89]*/ /*[clinic input] @@ -2837,7 +3165,7 @@ PyDoc_STRVAR(test_posonly_keywords_kwonly_opt2__doc__, "\n"); #define TEST_POSONLY_KEYWORDS_KWONLY_OPT2_METHODDEF \ - {"test_posonly_keywords_kwonly_opt2", (PyCFunction)(void(*)(void))test_posonly_keywords_kwonly_opt2, METH_FASTCALL|METH_KEYWORDS, test_posonly_keywords_kwonly_opt2__doc__}, + {"test_posonly_keywords_kwonly_opt2", _PyCFunction_CAST(test_posonly_keywords_kwonly_opt2), METH_FASTCALL|METH_KEYWORDS, test_posonly_keywords_kwonly_opt2__doc__}, static PyObject * test_posonly_keywords_kwonly_opt2_impl(PyObject *module, PyObject *a, @@ -2847,8 +3175,31 @@ static PyObject * test_posonly_keywords_kwonly_opt2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_kwonly_opt2", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_kwonly_opt2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -2882,7 +3233,7 @@ exit: static PyObject * test_posonly_keywords_kwonly_opt2_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=e5a3e992fd4b28b3 input=68d01d7c0f6dafb0]*/ +/*[clinic end generated code: output=ee629e962cb06992 input=68d01d7c0f6dafb0]*/ /*[clinic input] @@ -2905,7 +3256,7 @@ PyDoc_STRVAR(test_posonly_keywords_opt_kwonly_opt__doc__, "\n"); #define TEST_POSONLY_KEYWORDS_OPT_KWONLY_OPT_METHODDEF \ - {"test_posonly_keywords_opt_kwonly_opt", (PyCFunction)(void(*)(void))test_posonly_keywords_opt_kwonly_opt, METH_FASTCALL|METH_KEYWORDS, test_posonly_keywords_opt_kwonly_opt__doc__}, + {"test_posonly_keywords_opt_kwonly_opt", _PyCFunction_CAST(test_posonly_keywords_opt_kwonly_opt), METH_FASTCALL|METH_KEYWORDS, test_posonly_keywords_opt_kwonly_opt__doc__}, static PyObject * test_posonly_keywords_opt_kwonly_opt_impl(PyObject *module, PyObject *a, @@ -2916,8 +3267,31 @@ static PyObject * test_posonly_keywords_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", "d", "e", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_opt_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_opt_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -2963,7 +3337,7 @@ static PyObject * test_posonly_keywords_opt_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e) -/*[clinic end generated code: output=ff9fb6c3d2cbbaa4 input=d0883d45876f186c]*/ +/*[clinic end generated code: output=a2721babb42ecfd1 input=d0883d45876f186c]*/ /*[clinic input] @@ -2986,7 +3360,7 @@ PyDoc_STRVAR(test_posonly_keywords_opt2_kwonly_opt__doc__, "\n"); #define TEST_POSONLY_KEYWORDS_OPT2_KWONLY_OPT_METHODDEF \ - {"test_posonly_keywords_opt2_kwonly_opt", (PyCFunction)(void(*)(void))test_posonly_keywords_opt2_kwonly_opt, METH_FASTCALL|METH_KEYWORDS, test_posonly_keywords_opt2_kwonly_opt__doc__}, + {"test_posonly_keywords_opt2_kwonly_opt", _PyCFunction_CAST(test_posonly_keywords_opt2_kwonly_opt), METH_FASTCALL|METH_KEYWORDS, test_posonly_keywords_opt2_kwonly_opt__doc__}, static PyObject * test_posonly_keywords_opt2_kwonly_opt_impl(PyObject *module, PyObject *a, @@ -2997,8 +3371,31 @@ static PyObject * test_posonly_keywords_opt2_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", "d", "e", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_opt2_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_opt2_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -3049,7 +3446,7 @@ static PyObject * test_posonly_keywords_opt2_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e) -/*[clinic end generated code: output=c809d7a84a2205e1 input=c95e2e1ec93035ad]*/ +/*[clinic end generated code: output=0626203eedb6e7e8 input=c95e2e1ec93035ad]*/ /*[clinic input] @@ -3073,7 +3470,7 @@ PyDoc_STRVAR(test_posonly_opt_keywords_opt_kwonly_opt__doc__, "\n"); #define TEST_POSONLY_OPT_KEYWORDS_OPT_KWONLY_OPT_METHODDEF \ - {"test_posonly_opt_keywords_opt_kwonly_opt", (PyCFunction)(void(*)(void))test_posonly_opt_keywords_opt_kwonly_opt, METH_FASTCALL|METH_KEYWORDS, test_posonly_opt_keywords_opt_kwonly_opt__doc__}, + {"test_posonly_opt_keywords_opt_kwonly_opt", _PyCFunction_CAST(test_posonly_opt_keywords_opt_kwonly_opt), METH_FASTCALL|METH_KEYWORDS, test_posonly_opt_keywords_opt_kwonly_opt__doc__}, static PyObject * test_posonly_opt_keywords_opt_kwonly_opt_impl(PyObject *module, PyObject *a, @@ -3085,8 +3482,31 @@ static PyObject * test_posonly_opt_keywords_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), &_Py_ID(f), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "c", "d", "e", "f", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_opt_keywords_opt_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_opt_keywords_opt_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -3145,7 +3565,7 @@ test_posonly_opt_keywords_opt_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e, PyObject *f) -/*[clinic end generated code: output=719e4f6c224402d4 input=9914857713c5bbf8]*/ +/*[clinic end generated code: output=07d8acc04558a5a0 input=9914857713c5bbf8]*/ /*[clinic input] test_keyword_only_parameter @@ -3162,7 +3582,7 @@ PyDoc_STRVAR(test_keyword_only_parameter__doc__, "\n"); #define TEST_KEYWORD_ONLY_PARAMETER_METHODDEF \ - {"test_keyword_only_parameter", (PyCFunction)(void(*)(void))test_keyword_only_parameter, METH_FASTCALL|METH_KEYWORDS, test_keyword_only_parameter__doc__}, + {"test_keyword_only_parameter", _PyCFunction_CAST(test_keyword_only_parameter), METH_FASTCALL|METH_KEYWORDS, test_keyword_only_parameter__doc__}, static PyObject * test_keyword_only_parameter_impl(PyObject *module, PyBytesObject *co_lnotab); @@ -3171,8 +3591,31 @@ static PyObject * test_keyword_only_parameter(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(co_lnotab), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"co_lnotab", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keyword_only_parameter", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keyword_only_parameter", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyBytesObject *co_lnotab = (PyBytesObject *)self->co_lnotab; @@ -3198,7 +3641,7 @@ exit: static PyObject * test_keyword_only_parameter_impl(PyObject *module, PyBytesObject *co_lnotab) -/*[clinic end generated code: output=f25914b402039493 input=303df5046c7e37a3]*/ +/*[clinic end generated code: output=b12fe2e515a62603 input=303df5046c7e37a3]*/ /*[clinic input] @@ -3321,7 +3764,7 @@ PyDoc_STRVAR(test_vararg_and_posonly__doc__, "\n"); #define TEST_VARARG_AND_POSONLY_METHODDEF \ - {"test_vararg_and_posonly", (PyCFunction)(void(*)(void))test_vararg_and_posonly, METH_FASTCALL, test_vararg_and_posonly__doc__}, + {"test_vararg_and_posonly", _PyCFunction_CAST(test_vararg_and_posonly), METH_FASTCALL, test_vararg_and_posonly__doc__}, static PyObject * test_vararg_and_posonly_impl(PyObject *module, PyObject *a, PyObject *args); @@ -3338,8 +3781,11 @@ test_vararg_and_posonly(PyObject *module, PyObject *const *args, Py_ssize_t narg } a = args[0]; __clinic_args = PyTuple_New(nargs - 1); + if (!__clinic_args) { + goto exit; + } for (Py_ssize_t i = 0; i < nargs - 1; ++i) { - PyTuple_SET_ITEM(__clinic_args, i, args[1 + i]); + PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[1 + i])); } return_value = test_vararg_and_posonly_impl(module, a, __clinic_args); @@ -3350,7 +3796,7 @@ exit: static PyObject * test_vararg_and_posonly_impl(PyObject *module, PyObject *a, PyObject *args) -/*[clinic end generated code: output=ada613d2d87c9341 input=08dc2bf7afbf1613]*/ +/*[clinic end generated code: output=79b75dc07decc8d6 input=08dc2bf7afbf1613]*/ /*[clinic input] test_vararg @@ -3367,7 +3813,7 @@ PyDoc_STRVAR(test_vararg__doc__, "\n"); #define TEST_VARARG_METHODDEF \ - {"test_vararg", (PyCFunction)(void(*)(void))test_vararg, METH_FASTCALL|METH_KEYWORDS, test_vararg__doc__}, + {"test_vararg", _PyCFunction_CAST(test_vararg), METH_FASTCALL|METH_KEYWORDS, test_vararg__doc__}, static PyObject * test_vararg_impl(PyObject *module, PyObject *a, PyObject *args); @@ -3376,10 +3822,32 @@ static PyObject * test_vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_vararg", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_vararg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; - Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; PyObject *__clinic_args = NULL; @@ -3398,7 +3866,7 @@ exit: static PyObject * test_vararg_impl(PyObject *module, PyObject *a, PyObject *args) -/*[clinic end generated code: output=f721025731c3bfe8 input=81d33815ad1bae6e]*/ +/*[clinic end generated code: output=880365c61ae205d7 input=81d33815ad1bae6e]*/ /*[clinic input] test_vararg_with_default @@ -3416,7 +3884,7 @@ PyDoc_STRVAR(test_vararg_with_default__doc__, "\n"); #define TEST_VARARG_WITH_DEFAULT_METHODDEF \ - {"test_vararg_with_default", (PyCFunction)(void(*)(void))test_vararg_with_default, METH_FASTCALL|METH_KEYWORDS, test_vararg_with_default__doc__}, + {"test_vararg_with_default", _PyCFunction_CAST(test_vararg_with_default), METH_FASTCALL|METH_KEYWORDS, test_vararg_with_default__doc__}, static PyObject * test_vararg_with_default_impl(PyObject *module, PyObject *a, PyObject *args, @@ -3426,10 +3894,33 @@ static PyObject * test_vararg_with_default(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_vararg_with_default", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_vararg_with_default", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; - Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; PyObject *__clinic_args = NULL; int b = 0; @@ -3458,7 +3949,7 @@ exit: static PyObject * test_vararg_with_default_impl(PyObject *module, PyObject *a, PyObject *args, int b) -/*[clinic end generated code: output=63b34d3241c52fda input=6e110b54acd9b22d]*/ +/*[clinic end generated code: output=291e9a5a09831128 input=6e110b54acd9b22d]*/ /*[clinic input] test_vararg_with_only_defaults @@ -3476,7 +3967,7 @@ PyDoc_STRVAR(test_vararg_with_only_defaults__doc__, "\n"); #define TEST_VARARG_WITH_ONLY_DEFAULTS_METHODDEF \ - {"test_vararg_with_only_defaults", (PyCFunction)(void(*)(void))test_vararg_with_only_defaults, METH_FASTCALL|METH_KEYWORDS, test_vararg_with_only_defaults__doc__}, + {"test_vararg_with_only_defaults", _PyCFunction_CAST(test_vararg_with_only_defaults), METH_FASTCALL|METH_KEYWORDS, test_vararg_with_only_defaults__doc__}, static PyObject * test_vararg_with_only_defaults_impl(PyObject *module, PyObject *args, int b, @@ -3486,8 +3977,31 @@ static PyObject * test_vararg_with_only_defaults(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_vararg_with_only_defaults", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_vararg_with_only_defaults", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *__clinic_args = NULL; @@ -3523,4 +4037,68 @@ exit: static PyObject * test_vararg_with_only_defaults_impl(PyObject *module, PyObject *args, int b, PyObject *c) -/*[clinic end generated code: output=dc29ce6ebc2ec10c input=fa56a709a035666e]*/ +/*[clinic end generated code: output=dd21b28f0db26a4b input=fa56a709a035666e]*/ + +/*[clinic input] +test_paramname_module + + module as mod: object +[clinic start generated code]*/ + +PyDoc_STRVAR(test_paramname_module__doc__, +"test_paramname_module($module, /, module)\n" +"--\n" +"\n"); + +#define TEST_PARAMNAME_MODULE_METHODDEF \ + {"test_paramname_module", _PyCFunction_CAST(test_paramname_module), METH_FASTCALL|METH_KEYWORDS, test_paramname_module__doc__}, + +static PyObject * +test_paramname_module_impl(PyObject *module, PyObject *mod); + +static PyObject * +test_paramname_module(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(module), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"module", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_paramname_module", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *mod; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + mod = args[0]; + return_value = test_paramname_module_impl(module, mod); + +exit: + return return_value; +} + +static PyObject * +test_paramname_module_impl(PyObject *module, PyObject *mod) +/*[clinic end generated code: output=4a2a849ecbcc8b53 input=afefe259667f13ba]*/ diff --git a/Lib/test/crashers/infinite_loop_re.py b/Lib/test/crashers/infinite_loop_re.py index 9aecc568d91..c84f28d601f 100644 --- a/Lib/test/crashers/infinite_loop_re.py +++ b/Lib/test/crashers/infinite_loop_re.py @@ -1,5 +1,5 @@ -# This was taken from http://python.org/sf/1541697 +# This was taken from https://bugs.python.org/issue1541697 # It's not technically a crasher. It may not even truly be infinite, # however, I haven't waited a long time to see the result. It takes # 100% of CPU while running this and should be fixed. diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 810478c7db2..6a1df174a1b 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1,6 +1,6 @@ """Test date/time type. -See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases +See https://www.zope.dev/Members/fdrake/DateTimeWiki/TestCases """ import io import itertools @@ -28,6 +28,7 @@ from datetime import timedelta from datetime import tzinfo from datetime import time from datetime import timezone +from datetime import UTC from datetime import date, datetime import time as _time @@ -66,6 +67,9 @@ class TestModule(unittest.TestCase): self.assertEqual(datetime.MINYEAR, 1) self.assertEqual(datetime.MAXYEAR, 9999) + def test_utc_alias(self): + self.assertIs(UTC, timezone.utc) + def test_all(self): """Test that __all__ only points to valid attributes.""" all_attrs = dir(datetime_module) @@ -81,7 +85,7 @@ class TestModule(unittest.TestCase): if not name.startswith('__') and not name.endswith('__')) allowed = set(['MAXYEAR', 'MINYEAR', 'date', 'datetime', 'datetime_CAPI', 'time', 'timedelta', 'timezone', - 'tzinfo', 'sys']) + 'tzinfo', 'UTC', 'sys']) self.assertEqual(names - allowed, set([])) def test_divide_and_round(self): @@ -139,8 +143,8 @@ class PicklableFixedOffset(FixedOffset): def __init__(self, offset=None, name=None, dstoffset=None): FixedOffset.__init__(self, offset, name, dstoffset) - def __getstate__(self): - return self.__dict__ +class PicklableFixedOffsetWithSlots(PicklableFixedOffset): + __slots__ = '_FixedOffset__offset', '_FixedOffset__name', 'spam' class _TZInfo(tzinfo): def utcoffset(self, datetime_module): @@ -202,6 +206,7 @@ class TestTZInfo(unittest.TestCase): offset = timedelta(minutes=-300) for otype, args in [ (PicklableFixedOffset, (offset, 'cookie')), + (PicklableFixedOffsetWithSlots, (offset, 'cookie')), (timezone, (offset,)), (timezone, (offset, "EST"))]: orig = otype(*args) @@ -217,6 +222,7 @@ class TestTZInfo(unittest.TestCase): self.assertIs(type(derived), otype) self.assertEqual(derived.utcoffset(None), offset) self.assertEqual(derived.tzname(None), oname) + self.assertFalse(hasattr(derived, 'spam')) def test_issue23600(self): DSTDIFF = DSTOFFSET = timedelta(hours=1) @@ -308,6 +314,7 @@ class TestTimeZone(unittest.TestCase): def test_tzname(self): self.assertEqual('UTC', timezone.utc.tzname(None)) + self.assertEqual('UTC', UTC.tzname(None)) self.assertEqual('UTC', timezone(ZERO).tzname(None)) self.assertEqual('UTC-05:00', timezone(-5 * HOUR).tzname(None)) self.assertEqual('UTC+09:30', timezone(9.5 * HOUR).tzname(None)) @@ -1456,8 +1463,8 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase): # test that unicode input is allowed (issue 2782) self.assertEqual(t.strftime("%m"), "03") - # A naive object replaces %z and %Z w/ empty strings. - self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''") + # A naive object replaces %z, %:z and %Z w/ empty strings. + self.assertEqual(t.strftime("'%z' '%:z' '%Z'"), "'' '' ''") #make sure that invalid format specifiers are handled correctly #self.assertRaises(ValueError, t.strftime, "%e") @@ -1482,6 +1489,9 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase): #check that this standard extension works t.strftime("%f") + # bpo-41260: The parameter was named "fmt" in the pure python impl. + t.strftime(format="%f") + def test_strftime_trailing_percent(self): # bpo-35066: Make sure trailing '%' doesn't cause datetime's strftime to # complain. Different libcs have different handling of trailing @@ -1521,7 +1531,7 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase): for fmt in ["m:%m d:%d y:%y", "m:%m d:%d y:%y H:%H M:%M S:%S", - "%z %Z", + "%z %:z %Z", ]: self.assertEqual(dt.__format__(fmt), dt.strftime(fmt)) self.assertEqual(a.__format__(fmt), dt.strftime(fmt)) @@ -1676,7 +1686,8 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase): # Year 42 returns '42', not padded self.assertEqual(d.strftime("%Y"), '%d' % y) # '0042' is obtained anyway - self.assertEqual(d.strftime("%4Y"), '%04d' % y) + if support.has_strftime_extensions: + self.assertEqual(d.strftime("%4Y"), '%04d' % y) def test_replace(self): cls = self.theclass @@ -1832,6 +1843,41 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase): self.assertEqual(dt, dt_rt) + def test_fromisoformat_date_examples(self): + examples = [ + ('00010101', self.theclass(1, 1, 1)), + ('20000101', self.theclass(2000, 1, 1)), + ('20250102', self.theclass(2025, 1, 2)), + ('99991231', self.theclass(9999, 12, 31)), + ('0001-01-01', self.theclass(1, 1, 1)), + ('2000-01-01', self.theclass(2000, 1, 1)), + ('2025-01-02', self.theclass(2025, 1, 2)), + ('9999-12-31', self.theclass(9999, 12, 31)), + ('2025W01', self.theclass(2024, 12, 30)), + ('2025-W01', self.theclass(2024, 12, 30)), + ('2025W014', self.theclass(2025, 1, 2)), + ('2025-W01-4', self.theclass(2025, 1, 2)), + ('2026W01', self.theclass(2025, 12, 29)), + ('2026-W01', self.theclass(2025, 12, 29)), + ('2026W013', self.theclass(2025, 12, 31)), + ('2026-W01-3', self.theclass(2025, 12, 31)), + ('2022W52', self.theclass(2022, 12, 26)), + ('2022-W52', self.theclass(2022, 12, 26)), + ('2022W527', self.theclass(2023, 1, 1)), + ('2022-W52-7', self.theclass(2023, 1, 1)), + ('2015W534', self.theclass(2015, 12, 31)), # Has week 53 + ('2015-W53-4', self.theclass(2015, 12, 31)), # Has week 53 + ('2015-W53-5', self.theclass(2016, 1, 1)), + ('2020W531', self.theclass(2020, 12, 28)), # Leap year + ('2020-W53-1', self.theclass(2020, 12, 28)), # Leap year + ('2020-W53-6', self.theclass(2021, 1, 2)), + ] + + for input_str, expected in examples: + with self.subTest(input_str=input_str): + actual = self.theclass.fromisoformat(input_str) + self.assertEqual(actual, expected) + def test_fromisoformat_subclass(self): class DateSubclass(self.theclass): pass @@ -1854,7 +1900,8 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase): '2009-12-0a', # Invalid character in day '2009-01-32', # Invalid day '2009-02-29', # Invalid leap day - '20090228', # Valid ISO8601 output not from isoformat() + '2019-W53-1', # No week 53 in 2019 + '2020-W54-1', # No week 54 '2009\ud80002\ud80028', # Separators are surrogate codepoints ] @@ -1864,8 +1911,6 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase): def test_fromisoformat_fails_typeerror(self): # Test that fromisoformat fails when passed the wrong type - import io - bad_types = [b'2009-03-01', None, io.StringIO('2009-03-01')] for bad_type in bad_types: with self.assertRaises(TypeError): @@ -2092,7 +2137,7 @@ class TestDateTime(TestDate): for fmt in ["m:%m d:%d y:%y", "m:%m d:%d y:%y H:%H M:%M S:%S", - "%z %Z", + "%z %:z %Z", ]: self.assertEqual(dt.__format__(fmt), dt.strftime(fmt)) self.assertEqual(a.__format__(fmt), dt.strftime(fmt)) @@ -2381,6 +2426,12 @@ class TestDateTime(TestDate): got = self.theclass.fromtimestamp(ts) self.verify_field_equality(expected, got) + def test_fromtimestamp_keyword_arg(self): + import time + + # gh-85432: The parameter was named "t" in the pure-Python impl. + self.theclass.fromtimestamp(timestamp=time.time()) + def test_utcfromtimestamp(self): import time @@ -2472,45 +2523,101 @@ class TestDateTime(TestDate): self.assertEqual(t.microsecond, 7812) def test_timestamp_limits(self): - # minimum timestamp + with self.subTest("minimum UTC"): + min_dt = self.theclass.min.replace(tzinfo=timezone.utc) + min_ts = min_dt.timestamp() + + # This test assumes that datetime.min == 0000-01-01T00:00:00.00 + # If that assumption changes, this value can change as well + self.assertEqual(min_ts, -62135596800) + + with self.subTest("maximum UTC"): + # Zero out microseconds to avoid rounding issues + max_dt = self.theclass.max.replace(tzinfo=timezone.utc, + microsecond=0) + max_ts = max_dt.timestamp() + + # This test assumes that datetime.max == 9999-12-31T23:59:59.999999 + # If that assumption changes, this value can change as well + self.assertEqual(max_ts, 253402300799.0) + + def test_fromtimestamp_limits(self): + try: + self.theclass.fromtimestamp(-2**32 - 1) + except (OSError, OverflowError): + self.skipTest("Test not valid on this platform") + + # XXX: Replace these with datetime.{min,max}.timestamp() when we solve + # the issue with gh-91012 + min_dt = self.theclass.min + timedelta(days=1) + min_ts = min_dt.timestamp() + + max_dt = self.theclass.max.replace(microsecond=0) + max_ts = ((self.theclass.max - timedelta(hours=23)).timestamp() + + timedelta(hours=22, minutes=59, seconds=59).total_seconds()) + + for (test_name, ts, expected) in [ + ("minimum", min_ts, min_dt), + ("maximum", max_ts, max_dt), + ]: + with self.subTest(test_name, ts=ts, expected=expected): + actual = self.theclass.fromtimestamp(ts) + + self.assertEqual(actual, expected) + + # Test error conditions + test_cases = [ + ("Too small by a little", min_ts - timedelta(days=1, hours=12).total_seconds()), + ("Too small by a lot", min_ts - timedelta(days=400).total_seconds()), + ("Too big by a little", max_ts + timedelta(days=1).total_seconds()), + ("Too big by a lot", max_ts + timedelta(days=400).total_seconds()), + ] + + for test_name, ts in test_cases: + with self.subTest(test_name, ts=ts): + with self.assertRaises((ValueError, OverflowError)): + # converting a Python int to C time_t can raise a + # OverflowError, especially on 32-bit platforms. + self.theclass.fromtimestamp(ts) + + def test_utcfromtimestamp_limits(self): + try: + self.theclass.utcfromtimestamp(-2**32 - 1) + except (OSError, OverflowError): + self.skipTest("Test not valid on this platform") + min_dt = self.theclass.min.replace(tzinfo=timezone.utc) min_ts = min_dt.timestamp() - try: - # date 0001-01-01 00:00:00+00:00: timestamp=-62135596800 - self.assertEqual(self.theclass.fromtimestamp(min_ts, tz=timezone.utc), - min_dt) - except (OverflowError, OSError) as exc: - # the date 0001-01-01 doesn't fit into 32-bit time_t, - # or platform doesn't support such very old date - self.skipTest(str(exc)) - # maximum timestamp: set seconds to zero to avoid rounding issues - max_dt = self.theclass.max.replace(tzinfo=timezone.utc, - second=0, microsecond=0) + max_dt = self.theclass.max.replace(microsecond=0, tzinfo=timezone.utc) max_ts = max_dt.timestamp() - # date 9999-12-31 23:59:00+00:00: timestamp 253402300740 - self.assertEqual(self.theclass.fromtimestamp(max_ts, tz=timezone.utc), - max_dt) - # number of seconds greater than 1 year: make sure that the new date - # is not valid in datetime.datetime limits - delta = 3600 * 24 * 400 + for (test_name, ts, expected) in [ + ("minimum", min_ts, min_dt.replace(tzinfo=None)), + ("maximum", max_ts, max_dt.replace(tzinfo=None)), + ]: + with self.subTest(test_name, ts=ts, expected=expected): + try: + actual = self.theclass.utcfromtimestamp(ts) + except (OSError, OverflowError) as exc: + self.skipTest(str(exc)) - # too small - ts = min_ts - delta - # converting a Python int to C time_t can raise a OverflowError, - # especially on 32-bit platforms. - with self.assertRaises((ValueError, OverflowError)): - self.theclass.fromtimestamp(ts) - with self.assertRaises((ValueError, OverflowError)): - self.theclass.utcfromtimestamp(ts) + self.assertEqual(actual, expected) - # too big - ts = max_dt.timestamp() + delta - with self.assertRaises((ValueError, OverflowError)): - self.theclass.fromtimestamp(ts) - with self.assertRaises((ValueError, OverflowError)): - self.theclass.utcfromtimestamp(ts) + # Test error conditions + test_cases = [ + ("Too small by a little", min_ts - 1), + ("Too small by a lot", min_ts - timedelta(days=400).total_seconds()), + ("Too big by a little", max_ts + 1), + ("Too big by a lot", max_ts + timedelta(days=400).total_seconds()), + ] + + for test_name, ts in test_cases: + with self.subTest(test_name, ts=ts): + with self.assertRaises((ValueError, OverflowError)): + # converting a Python int to C time_t can raise a + # OverflowError, especially on 32-bit platforms. + self.theclass.utcfromtimestamp(ts) def test_insane_fromtimestamp(self): # It's possible that some platform maps time_t to double, @@ -2679,6 +2786,7 @@ class TestDateTime(TestDate): tz = timezone(-timedelta(hours=2, seconds=s, microseconds=us)) t = t.replace(tzinfo=tz) self.assertEqual(t.strftime("%z"), "-0200" + z) + self.assertEqual(t.strftime("%:z"), "-02:00:" + z) # bpo-34482: Check that surrogates don't cause a crash. try: @@ -2997,6 +3105,140 @@ class TestDateTime(TestDate): dt_rt = self.theclass.fromisoformat(dtstr) self.assertEqual(dt, dt_rt) + def test_fromisoformat_datetime_examples(self): + UTC = timezone.utc + BST = timezone(timedelta(hours=1), 'BST') + EST = timezone(timedelta(hours=-5), 'EST') + EDT = timezone(timedelta(hours=-4), 'EDT') + examples = [ + ('2025-01-02', self.theclass(2025, 1, 2, 0, 0)), + ('2025-01-02T03', self.theclass(2025, 1, 2, 3, 0)), + ('2025-01-02T03:04', self.theclass(2025, 1, 2, 3, 4)), + ('2025-01-02T0304', self.theclass(2025, 1, 2, 3, 4)), + ('2025-01-02T03:04:05', self.theclass(2025, 1, 2, 3, 4, 5)), + ('2025-01-02T030405', self.theclass(2025, 1, 2, 3, 4, 5)), + ('2025-01-02T03:04:05.6', + self.theclass(2025, 1, 2, 3, 4, 5, 600000)), + ('2025-01-02T03:04:05,6', + self.theclass(2025, 1, 2, 3, 4, 5, 600000)), + ('2025-01-02T03:04:05.678', + self.theclass(2025, 1, 2, 3, 4, 5, 678000)), + ('2025-01-02T03:04:05.678901', + self.theclass(2025, 1, 2, 3, 4, 5, 678901)), + ('2025-01-02T03:04:05,678901', + self.theclass(2025, 1, 2, 3, 4, 5, 678901)), + ('2025-01-02T030405.678901', + self.theclass(2025, 1, 2, 3, 4, 5, 678901)), + ('2025-01-02T030405,678901', + self.theclass(2025, 1, 2, 3, 4, 5, 678901)), + ('2025-01-02T03:04:05.6789010', + self.theclass(2025, 1, 2, 3, 4, 5, 678901)), + ('2009-04-19T03:15:45.2345', + self.theclass(2009, 4, 19, 3, 15, 45, 234500)), + ('2009-04-19T03:15:45.1234567', + self.theclass(2009, 4, 19, 3, 15, 45, 123456)), + ('2025-01-02T03:04:05,678', + self.theclass(2025, 1, 2, 3, 4, 5, 678000)), + ('20250102', self.theclass(2025, 1, 2, 0, 0)), + ('20250102T03', self.theclass(2025, 1, 2, 3, 0)), + ('20250102T03:04', self.theclass(2025, 1, 2, 3, 4)), + ('20250102T03:04:05', self.theclass(2025, 1, 2, 3, 4, 5)), + ('20250102T030405', self.theclass(2025, 1, 2, 3, 4, 5)), + ('20250102T03:04:05.6', + self.theclass(2025, 1, 2, 3, 4, 5, 600000)), + ('20250102T03:04:05,6', + self.theclass(2025, 1, 2, 3, 4, 5, 600000)), + ('20250102T03:04:05.678', + self.theclass(2025, 1, 2, 3, 4, 5, 678000)), + ('20250102T03:04:05,678', + self.theclass(2025, 1, 2, 3, 4, 5, 678000)), + ('20250102T03:04:05.678901', + self.theclass(2025, 1, 2, 3, 4, 5, 678901)), + ('20250102T030405.678901', + self.theclass(2025, 1, 2, 3, 4, 5, 678901)), + ('20250102T030405,678901', + self.theclass(2025, 1, 2, 3, 4, 5, 678901)), + ('20250102T030405.6789010', + self.theclass(2025, 1, 2, 3, 4, 5, 678901)), + ('2022W01', self.theclass(2022, 1, 3)), + ('2022W52520', self.theclass(2022, 12, 26, 20, 0)), + ('2022W527520', self.theclass(2023, 1, 1, 20, 0)), + ('2026W01516', self.theclass(2025, 12, 29, 16, 0)), + ('2026W013516', self.theclass(2025, 12, 31, 16, 0)), + ('2025W01503', self.theclass(2024, 12, 30, 3, 0)), + ('2025W014503', self.theclass(2025, 1, 2, 3, 0)), + ('2025W01512', self.theclass(2024, 12, 30, 12, 0)), + ('2025W014512', self.theclass(2025, 1, 2, 12, 0)), + ('2025W014T121431', self.theclass(2025, 1, 2, 12, 14, 31)), + ('2026W013T162100', self.theclass(2025, 12, 31, 16, 21)), + ('2026W013 162100', self.theclass(2025, 12, 31, 16, 21)), + ('2022W527T202159', self.theclass(2023, 1, 1, 20, 21, 59)), + ('2022W527 202159', self.theclass(2023, 1, 1, 20, 21, 59)), + ('2025W014 121431', self.theclass(2025, 1, 2, 12, 14, 31)), + ('2025W014T030405', self.theclass(2025, 1, 2, 3, 4, 5)), + ('2025W014 030405', self.theclass(2025, 1, 2, 3, 4, 5)), + ('2020-W53-6T03:04:05', self.theclass(2021, 1, 2, 3, 4, 5)), + ('2020W537 03:04:05', self.theclass(2021, 1, 3, 3, 4, 5)), + ('2025-W01-4T03:04:05', self.theclass(2025, 1, 2, 3, 4, 5)), + ('2025-W01-4T03:04:05.678901', + self.theclass(2025, 1, 2, 3, 4, 5, 678901)), + ('2025-W01-4T12:14:31', self.theclass(2025, 1, 2, 12, 14, 31)), + ('2025-W01-4T12:14:31.012345', + self.theclass(2025, 1, 2, 12, 14, 31, 12345)), + ('2026-W01-3T16:21:00', self.theclass(2025, 12, 31, 16, 21)), + ('2026-W01-3T16:21:00.000000', self.theclass(2025, 12, 31, 16, 21)), + ('2022-W52-7T20:21:59', + self.theclass(2023, 1, 1, 20, 21, 59)), + ('2022-W52-7T20:21:59.999999', + self.theclass(2023, 1, 1, 20, 21, 59, 999999)), + ('2025-W01003+00', + self.theclass(2024, 12, 30, 3, 0, tzinfo=UTC)), + ('2025-01-02T03:04:05+00', + self.theclass(2025, 1, 2, 3, 4, 5, tzinfo=UTC)), + ('2025-01-02T03:04:05Z', + self.theclass(2025, 1, 2, 3, 4, 5, tzinfo=UTC)), + ('2025-01-02003:04:05,6+00:00:00.00', + self.theclass(2025, 1, 2, 3, 4, 5, 600000, tzinfo=UTC)), + ('2000-01-01T00+21', + self.theclass(2000, 1, 1, 0, 0, tzinfo=timezone(timedelta(hours=21)))), + ('2025-01-02T03:05:06+0300', + self.theclass(2025, 1, 2, 3, 5, 6, + tzinfo=timezone(timedelta(hours=3)))), + ('2025-01-02T03:05:06-0300', + self.theclass(2025, 1, 2, 3, 5, 6, + tzinfo=timezone(timedelta(hours=-3)))), + ('2025-01-02T03:04:05+0000', + self.theclass(2025, 1, 2, 3, 4, 5, tzinfo=UTC)), + ('2025-01-02T03:05:06+03', + self.theclass(2025, 1, 2, 3, 5, 6, + tzinfo=timezone(timedelta(hours=3)))), + ('2025-01-02T03:05:06-03', + self.theclass(2025, 1, 2, 3, 5, 6, + tzinfo=timezone(timedelta(hours=-3)))), + ('2020-01-01T03:05:07.123457-05:00', + self.theclass(2020, 1, 1, 3, 5, 7, 123457, tzinfo=EST)), + ('2020-01-01T03:05:07.123457-0500', + self.theclass(2020, 1, 1, 3, 5, 7, 123457, tzinfo=EST)), + ('2020-06-01T04:05:06.111111-04:00', + self.theclass(2020, 6, 1, 4, 5, 6, 111111, tzinfo=EDT)), + ('2020-06-01T04:05:06.111111-0400', + self.theclass(2020, 6, 1, 4, 5, 6, 111111, tzinfo=EDT)), + ('2021-10-31T01:30:00.000000+01:00', + self.theclass(2021, 10, 31, 1, 30, tzinfo=BST)), + ('2021-10-31T01:30:00.000000+0100', + self.theclass(2021, 10, 31, 1, 30, tzinfo=BST)), + ('2025-01-02T03:04:05,6+000000.00', + self.theclass(2025, 1, 2, 3, 4, 5, 600000, tzinfo=UTC)), + ('2025-01-02T03:04:05,678+00:00:10', + self.theclass(2025, 1, 2, 3, 4, 5, 678000, + tzinfo=timezone(timedelta(seconds=10)))), + ] + + for input_str, expected in examples: + with self.subTest(input_str=input_str): + actual = self.theclass.fromisoformat(input_str) + self.assertEqual(actual, expected) + def test_fromisoformat_fails_datetime(self): # Test that fromisoformat() fails on invalid values bad_strs = [ @@ -3010,8 +3252,6 @@ class TestDateTime(TestDate): '2009-04-19T03;15:45', # Bad first time separator '2009-04-19T03:15;45', # Bad second time separator '2009-04-19T03:15:4500:00', # Bad time zone separator - '2009-04-19T03:15:45.2345', # Too many digits for milliseconds - '2009-04-19T03:15:45.1234567', # Too many digits for microseconds '2009-04-19T03:15:45.123456+24:30', # Invalid time zone offset '2009-04-19T03:15:45.123456-24:30', # Invalid negative offset '2009-04-10ᛇᛇᛇᛇᛇ12:15', # Too many unicode separators @@ -3285,8 +3525,8 @@ class TestTime(HarmlessMixedComparison, unittest.TestCase): def test_strftime(self): t = self.theclass(1, 2, 3, 4) self.assertEqual(t.strftime('%H %M %S %f'), "01 02 03 000004") - # A naive object replaces %z and %Z with empty strings. - self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''") + # A naive object replaces %z, %:z and %Z with empty strings. + self.assertEqual(t.strftime("'%z' '%:z' '%Z'"), "'' '' ''") # bpo-34482: Check that surrogates don't cause a crash. try: @@ -3294,6 +3534,9 @@ class TestTime(HarmlessMixedComparison, unittest.TestCase): except UnicodeEncodeError: pass + # gh-85432: The parameter was named "fmt" in the pure-Python impl. + t.strftime(format="%f") + def test_format(self): t = self.theclass(1, 2, 3, 4) self.assertEqual(t.__format__(''), str(t)) @@ -3704,10 +3947,10 @@ class TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase): self.assertEqual(repr(t4), d + "(0, 0, 0, 40)") self.assertEqual(repr(t5), d + "(0, 0, 0, 40, tzinfo=utc)") - self.assertEqual(t1.strftime("%H:%M:%S %%Z=%Z %%z=%z"), - "07:47:00 %Z=EST %z=-0500") - self.assertEqual(t2.strftime("%H:%M:%S %Z %z"), "12:47:00 UTC +0000") - self.assertEqual(t3.strftime("%H:%M:%S %Z %z"), "13:47:00 MET +0100") + self.assertEqual(t1.strftime("%H:%M:%S %%Z=%Z %%z=%z %%:z=%:z"), + "07:47:00 %Z=EST %z=-0500 %:z=-05:00") + self.assertEqual(t2.strftime("%H:%M:%S %Z %z %:z"), "12:47:00 UTC +0000 +00:00") + self.assertEqual(t3.strftime("%H:%M:%S %Z %z %:z"), "13:47:00 MET +0100 +01:00") yuck = FixedOffset(-1439, "%z %Z %%z%%Z") t1 = time(23, 59, tzinfo=yuck) @@ -3956,6 +4199,76 @@ class TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase): t_rt = self.theclass.fromisoformat(tstr) self.assertEqual(t, t_rt) + def test_fromisoformat_fractions(self): + strs = [ + ('12:30:45.1', (12, 30, 45, 100000)), + ('12:30:45.12', (12, 30, 45, 120000)), + ('12:30:45.123', (12, 30, 45, 123000)), + ('12:30:45.1234', (12, 30, 45, 123400)), + ('12:30:45.12345', (12, 30, 45, 123450)), + ('12:30:45.123456', (12, 30, 45, 123456)), + ('12:30:45.1234567', (12, 30, 45, 123456)), + ('12:30:45.12345678', (12, 30, 45, 123456)), + ] + + for time_str, time_comps in strs: + expected = self.theclass(*time_comps) + actual = self.theclass.fromisoformat(time_str) + + self.assertEqual(actual, expected) + + def test_fromisoformat_time_examples(self): + examples = [ + ('0000', self.theclass(0, 0)), + ('00:00', self.theclass(0, 0)), + ('000000', self.theclass(0, 0)), + ('00:00:00', self.theclass(0, 0)), + ('000000.0', self.theclass(0, 0)), + ('00:00:00.0', self.theclass(0, 0)), + ('000000.000', self.theclass(0, 0)), + ('00:00:00.000', self.theclass(0, 0)), + ('000000.000000', self.theclass(0, 0)), + ('00:00:00.000000', self.theclass(0, 0)), + ('1200', self.theclass(12, 0)), + ('12:00', self.theclass(12, 0)), + ('120000', self.theclass(12, 0)), + ('12:00:00', self.theclass(12, 0)), + ('120000.0', self.theclass(12, 0)), + ('12:00:00.0', self.theclass(12, 0)), + ('120000.000', self.theclass(12, 0)), + ('12:00:00.000', self.theclass(12, 0)), + ('120000.000000', self.theclass(12, 0)), + ('12:00:00.000000', self.theclass(12, 0)), + ('2359', self.theclass(23, 59)), + ('23:59', self.theclass(23, 59)), + ('235959', self.theclass(23, 59, 59)), + ('23:59:59', self.theclass(23, 59, 59)), + ('235959.9', self.theclass(23, 59, 59, 900000)), + ('23:59:59.9', self.theclass(23, 59, 59, 900000)), + ('235959.999', self.theclass(23, 59, 59, 999000)), + ('23:59:59.999', self.theclass(23, 59, 59, 999000)), + ('235959.999999', self.theclass(23, 59, 59, 999999)), + ('23:59:59.999999', self.theclass(23, 59, 59, 999999)), + ('00:00:00Z', self.theclass(0, 0, tzinfo=timezone.utc)), + ('12:00:00+0000', self.theclass(12, 0, tzinfo=timezone.utc)), + ('12:00:00+00:00', self.theclass(12, 0, tzinfo=timezone.utc)), + ('00:00:00+05', + self.theclass(0, 0, tzinfo=timezone(timedelta(hours=5)))), + ('00:00:00+05:30', + self.theclass(0, 0, tzinfo=timezone(timedelta(hours=5, minutes=30)))), + ('12:00:00-05:00', + self.theclass(12, 0, tzinfo=timezone(timedelta(hours=-5)))), + ('12:00:00-0500', + self.theclass(12, 0, tzinfo=timezone(timedelta(hours=-5)))), + ('00:00:00,000-23:59:59.999999', + self.theclass(0, 0, tzinfo=timezone(-timedelta(hours=23, minutes=59, seconds=59, microseconds=999999)))), + ] + + for input_str, expected in examples: + with self.subTest(input_str=input_str): + actual = self.theclass.fromisoformat(input_str) + self.assertEqual(actual, expected) + def test_fromisoformat_fails(self): bad_strs = [ '', # Empty string @@ -3969,15 +4282,17 @@ class TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase): '1a:30:45.334034', # Invalid character in hours '12:a0:45.334034', # Invalid character in minutes '12:30:a5.334034', # Invalid character in seconds - '12:30:45.1234', # Too many digits for milliseconds - '12:30:45.1234567', # Too many digits for microseconds '12:30:45.123456+24:30', # Invalid time zone offset '12:30:45.123456-24:30', # Invalid negative offset '12:30:45', # Uses full-width unicode colons + '12:30:45.123456a', # Non-numeric data after 6 components + '12:30:45.123456789a', # Non-numeric data after 9 components '12:30:45․123456', # Uses \u2024 in place of decimal point '12:30:45a', # Extra at tend of basic time '12:30:45.123a', # Extra at end of millisecond time '12:30:45.123456a', # Extra at end of microsecond time + '12:30:45.123456-', # Extra at end of microsecond time + '12:30:45.123456+', # Extra at end of microsecond time '12:30:45.123456+12:00:30a', # Extra at end of full time ] @@ -3988,8 +4303,6 @@ class TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase): def test_fromisoformat_fails_typeerror(self): # Test the fromisoformat fails when passed the wrong type - import io - bad_types = [b'12:30:45', None, io.StringIO('12:30:45')] for bad_type in bad_types: @@ -5859,6 +6172,9 @@ class ZoneInfoTest(unittest.TestCase): ldt = tz.fromutc(udt.replace(tzinfo=tz)) self.assertEqual(ldt.fold, 0) + @unittest.skipUnless( + hasattr(time, "tzset"), "time module has no attribute tzset" + ) def test_system_transitions(self): if ('Riyadh8' in self.zonename or # From tzdata NEWS file: diff --git a/Lib/test/doctest_lineno.py b/Lib/test/doctest_lineno.py new file mode 100644 index 00000000000..729a68aceaa --- /dev/null +++ b/Lib/test/doctest_lineno.py @@ -0,0 +1,53 @@ +# This module is used in `test_doctest`. +# It must not have a docstring. + +def func_with_docstring(): + """Some unrelated info.""" + + +def func_without_docstring(): + pass + + +def func_with_doctest(): + """ + This function really contains a test case. + + >>> func_with_doctest.__name__ + 'func_with_doctest' + """ + return 3 + + +class ClassWithDocstring: + """Some unrelated class information.""" + + +class ClassWithoutDocstring: + pass + + +class ClassWithDoctest: + """This class really has a test case in it. + + >>> ClassWithDoctest.__name__ + 'ClassWithDoctest' + """ + + +class MethodWrapper: + def method_with_docstring(self): + """Method with a docstring.""" + + def method_without_docstring(self): + pass + + def method_with_doctest(self): + """ + This has a doctest! + >>> MethodWrapper.method_with_doctest.__name__ + 'method_with_doctest' + """ + +# https://github.com/python/cpython/issues/99433 +str_wrapper = object().__str__ diff --git a/Lib/test/exception_hierarchy.txt b/Lib/test/exception_hierarchy.txt index 5c0bfda3737..1eca123be0f 100644 --- a/Lib/test/exception_hierarchy.txt +++ b/Lib/test/exception_hierarchy.txt @@ -1,12 +1,9 @@ BaseException - ├── SystemExit - ├── KeyboardInterrupt - ├── GeneratorExit ├── BaseExceptionGroup + ├── GeneratorExit + ├── KeyboardInterrupt + ├── SystemExit └── Exception - ├── ExceptionGroup [BaseExceptionGroup] - ├── StopIteration - ├── StopAsyncIteration ├── ArithmeticError │ ├── FloatingPointError │ ├── OverflowError @@ -15,6 +12,7 @@ BaseException ├── AttributeError ├── BufferError ├── EOFError + ├── ExceptionGroup [BaseExceptionGroup] ├── ImportError │ └── ModuleNotFoundError ├── LookupError @@ -43,6 +41,8 @@ BaseException ├── RuntimeError │ ├── NotImplementedError │ └── RecursionError + ├── StopAsyncIteration + ├── StopIteration ├── SyntaxError │ └── IndentationError │ └── TabError @@ -54,14 +54,14 @@ BaseException │ ├── UnicodeEncodeError │ └── UnicodeTranslateError └── Warning + ├── BytesWarning ├── DeprecationWarning - ├── PendingDeprecationWarning - ├── RuntimeWarning - ├── SyntaxWarning - ├── UserWarning + ├── EncodingWarning ├── FutureWarning ├── ImportWarning + ├── PendingDeprecationWarning + ├── ResourceWarning + ├── RuntimeWarning + ├── SyntaxWarning ├── UnicodeWarning - ├── BytesWarning - ├── EncodingWarning - └── ResourceWarning + └── UserWarning diff --git a/Lib/test/fork_wait.py b/Lib/test/fork_wait.py index 4d3dbd8e83f..c26c7aaaeb4 100644 --- a/Lib/test/fork_wait.py +++ b/Lib/test/fork_wait.py @@ -13,6 +13,7 @@ import os, sys, time, unittest import threading from test import support from test.support import threading_helper +import warnings LONGSLEEP = 2 @@ -54,10 +55,8 @@ class ForkWait(unittest.TestCase): self.threads.append(thread) # busy-loop to wait for threads - deadline = time.monotonic() + support.SHORT_TIMEOUT - while len(self.alive) < NUM_THREADS: - time.sleep(0.1) - if deadline < time.monotonic(): + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if len(self.alive) >= NUM_THREADS: break a = sorted(self.alive.keys()) @@ -65,19 +64,17 @@ class ForkWait(unittest.TestCase): prefork_lives = self.alive.copy() - if sys.platform in ['unixware7']: - cpid = os.fork1() - else: - cpid = os.fork() - - if cpid == 0: - # Child - time.sleep(LONGSLEEP) - n = 0 - for key in self.alive: - if self.alive[key] != prefork_lives[key]: - n += 1 - os._exit(n) - else: - # Parent - self.wait_impl(cpid, exitcode=0) + # Ignore the warning about fork with threads. + with warnings.catch_warnings(category=DeprecationWarning, + action="ignore"): + if (cpid := os.fork()) == 0: + # Child + time.sleep(LONGSLEEP) + n = 0 + for key in self.alive: + if self.alive[key] != prefork_lives[key]: + n += 1 + os._exit(n) + else: + # Parent + self.wait_impl(cpid, exitcode=0) diff --git a/Lib/test/imghdrdata/python.gif b/Lib/test/imghdrdata/python.gif index 96fd9fef76b..efa0be3861d 100644 Binary files a/Lib/test/imghdrdata/python.gif and b/Lib/test/imghdrdata/python.gif differ diff --git a/Lib/test/inspect_fodder2.py b/Lib/test/inspect_fodder2.py index e7d4b53ebef..2dc49817087 100644 --- a/Lib/test/inspect_fodder2.py +++ b/Lib/test/inspect_fodder2.py @@ -259,3 +259,17 @@ def all_markers_with_args_and_kwargs(a, b, /, c, d, *args, e, f, **kwargs): #line 259 def all_markers_with_defaults(a, b=1, /, c=2, d=3, *, e=4, f=5): pass + +# line 263 +def deco_factory(**kwargs): + def deco(f): + @wraps(f) + def wrapper(*a, **kwd): + kwd.update(kwargs) + return f(*a, **kwd) + return wrapper + return deco + +@deco_factory(foo=(1 + 2), bar=lambda: 1) +def complex_decorated(foo=0, bar=lambda: 0): + return foo + bar() diff --git a/Lib/test/leakers/test_ctypes.py b/Lib/test/leakers/test_ctypes.py index 7d7e9ff3a11..ec09ac36996 100644 --- a/Lib/test/leakers/test_ctypes.py +++ b/Lib/test/leakers/test_ctypes.py @@ -1,5 +1,5 @@ -# Taken from Lib/ctypes/test/test_keeprefs.py, PointerToStructure.test(). +# Taken from Lib/test/test_ctypes/test_keeprefs.py, PointerToStructure.test(). from ctypes import Structure, c_int, POINTER import gc diff --git a/Lib/test/levenshtein_examples.json b/Lib/test/levenshtein_examples.json new file mode 100644 index 00000000000..a32672cfdba --- /dev/null +++ b/Lib/test/levenshtein_examples.json @@ -0,0 +1,50002 @@ +[ + [ + "", + "", + 0 + ], + [ + "", + "AabBbb", + 12 + ], + [ + "", + "AbaC", + 8 + ], + [ + "", + "B", + 2 + ], + [ + "", + "Ba", + 4 + ], + [ + "", + "CBaACCCa", + 16 + ], + [ + "", + "CCbBC", + 10 + ], + [ + "", + "CcbCbaaAB", + 18 + ], + [ + "", + "bAa", + 6 + ], + [ + "", + "bAaCABb", + 14 + ], + [ + "A", + "A", + 0 + ], + [ + "A", + "AA", + 2 + ], + [ + "A", + "AABCAabcC", + 16 + ], + [ + "A", + "AACB", + 6 + ], + [ + "A", + "AACC", + 6 + ], + [ + "A", + "ABAaBbc", + 12 + ], + [ + "A", + "ABCcC", + 8 + ], + [ + "A", + "ABa", + 4 + ], + [ + "A", + "ABbBabcaa", + 16 + ], + [ + "A", + "ABbbCBcA", + 14 + ], + [ + "A", + "ACCBcBbBb", + 16 + ], + [ + "A", + "ACa", + 4 + ], + [ + "A", + "ACb", + 4 + ], + [ + "A", + "ACcbbaAB", + 14 + ], + [ + "A", + "AaAaccAb", + 14 + ], + [ + "A", + "AaabbCC", + 12 + ], + [ + "A", + "AabB", + 6 + ], + [ + "A", + "AbBa", + 6 + ], + [ + "A", + "AbBaA", + 8 + ], + [ + "A", + "AbCBBCaC", + 14 + ], + [ + "A", + "AbCb", + 6 + ], + [ + "A", + "AbcB", + 6 + ], + [ + "A", + "B", + 2 + ], + [ + "A", + "BA", + 2 + ], + [ + "A", + "BABbCc", + 10 + ], + [ + "A", + "BABca", + 8 + ], + [ + "A", + "BB", + 4 + ], + [ + "A", + "BBaBBaa", + 13 + ], + [ + "A", + "BBbbaAA", + 12 + ], + [ + "A", + "BCCAAc", + 10 + ], + [ + "A", + "BCa", + 5 + ], + [ + "A", + "BCcaC", + 9 + ], + [ + "A", + "BCccaa", + 11 + ], + [ + "A", + "BaacCbC", + 13 + ], + [ + "A", + "BabCC", + 9 + ], + [ + "A", + "Bac", + 5 + ], + [ + "A", + "BbCbb", + 10 + ], + [ + "A", + "BbaBAC", + 10 + ], + [ + "A", + "Bbc", + 6 + ], + [ + "A", + "BcB", + 6 + ], + [ + "A", + "BcCAbCBA", + 14 + ], + [ + "A", + "BcaaCbCB", + 15 + ], + [ + "A", + "C", + 2 + ], + [ + "A", + "CA", + 2 + ], + [ + "A", + "CABAacB", + 12 + ], + [ + "A", + "CABBABBc", + 14 + ], + [ + "A", + "CAaaBc", + 10 + ], + [ + "A", + "CBAA", + 6 + ], + [ + "A", + "CBCcBaBAB", + 16 + ], + [ + "A", + "CBcbc", + 10 + ], + [ + "A", + "CC", + 4 + ], + [ + "A", + "CCA", + 4 + ], + [ + "A", + "CCB", + 6 + ], + [ + "A", + "CCBaACcC", + 14 + ], + [ + "A", + "CCBcAAacb", + 16 + ], + [ + "A", + "CaCCaA", + 10 + ], + [ + "A", + "CbAB", + 6 + ], + [ + "A", + "CbBaAACC", + 14 + ], + [ + "A", + "CbCCbB", + 12 + ], + [ + "A", + "CbacBb", + 11 + ], + [ + "A", + "CbbABc", + 10 + ], + [ + "A", + "CcC", + 6 + ], + [ + "A", + "CcCacAAAC", + 16 + ], + [ + "A", + "CccCbaCcb", + 17 + ], + [ + "A", + "a", + 1 + ], + [ + "A", + "aABABBa", + 12 + ], + [ + "A", + "aABBA", + 8 + ], + [ + "A", + "aABCaBCa", + 14 + ], + [ + "A", + "aACBabAC", + 14 + ], + [ + "A", + "aBCb", + 7 + ], + [ + "A", + "aBaB", + 7 + ], + [ + "A", + "aBbBb", + 9 + ], + [ + "A", + "aC", + 3 + ], + [ + "A", + "aCA", + 4 + ], + [ + "A", + "aaBBb", + 9 + ], + [ + "A", + "aaC", + 5 + ], + [ + "A", + "aaCb", + 7 + ], + [ + "A", + "aaCbABbb", + 14 + ], + [ + "A", + "aaCcbb", + 11 + ], + [ + "A", + "aaaaCcAB", + 14 + ], + [ + "A", + "aaabb", + 9 + ], + [ + "A", + "aaacCabCC", + 17 + ], + [ + "A", + "aacBccCAC", + 16 + ], + [ + "A", + "aacC", + 7 + ], + [ + "A", + "abCAb", + 8 + ], + [ + "A", + "abbBcaccc", + 17 + ], + [ + "A", + "acCAB", + 8 + ], + [ + "A", + "acacBcAA", + 14 + ], + [ + "A", + "b", + 2 + ], + [ + "A", + "bABACaB", + 12 + ], + [ + "A", + "bAbA", + 6 + ], + [ + "A", + "bAbaBc", + 10 + ], + [ + "A", + "bBAa", + 6 + ], + [ + "A", + "bBa", + 5 + ], + [ + "A", + "bBaCAab", + 12 + ], + [ + "A", + "bBaCaCBbB", + 17 + ], + [ + "A", + "bBbAbaBa", + 14 + ], + [ + "A", + "bBbacabAb", + 16 + ], + [ + "A", + "bCCbA", + 8 + ], + [ + "A", + "bCCbB", + 10 + ], + [ + "A", + "bCbbACc", + 12 + ], + [ + "A", + "bCbbc", + 10 + ], + [ + "A", + "baACBCB", + 12 + ], + [ + "A", + "babABb", + 10 + ], + [ + "A", + "bacB", + 7 + ], + [ + "A", + "bacacA", + 10 + ], + [ + "A", + "bb", + 4 + ], + [ + "A", + "bbCa", + 7 + ], + [ + "A", + "bbCbaa", + 11 + ], + [ + "A", + "bbbAcb", + 10 + ], + [ + "A", + "bc", + 4 + ], + [ + "A", + "bcAAcCAb", + 14 + ], + [ + "A", + "bcC", + 6 + ], + [ + "A", + "bcbbaab", + 13 + ], + [ + "A", + "c", + 2 + ], + [ + "A", + "cAB", + 4 + ], + [ + "A", + "cACAc", + 8 + ], + [ + "A", + "cAaBccaC", + 14 + ], + [ + "A", + "cAcAaCAc", + 14 + ], + [ + "A", + "cBAaC", + 8 + ], + [ + "A", + "cBAac", + 8 + ], + [ + "A", + "cBCAABbc", + 14 + ], + [ + "A", + "cBaCbab", + 13 + ], + [ + "A", + "cBacA", + 8 + ], + [ + "A", + "cBb", + 6 + ], + [ + "A", + "cC", + 4 + ], + [ + "A", + "cCBABaC", + 12 + ], + [ + "A", + "cCCCa", + 9 + ], + [ + "A", + "cCa", + 5 + ], + [ + "A", + "cCaAaCaCB", + 16 + ], + [ + "A", + "cCabbbCa", + 15 + ], + [ + "A", + "caacCacAb", + 16 + ], + [ + "A", + "cabbC", + 9 + ], + [ + "A", + "cb", + 4 + ], + [ + "A", + "cbC", + 6 + ], + [ + "A", + "cbCAaAaAB", + 16 + ], + [ + "A", + "cbbaaAbbB", + 16 + ], + [ + "A", + "cc", + 4 + ], + [ + "A", + "ccCcCBaB", + 15 + ], + [ + "A", + "ccabbC", + 11 + ], + [ + "AA", + "AA", + 0 + ], + [ + "AA", + "ACAA", + 4 + ], + [ + "AA", + "BAc", + 4 + ], + [ + "AA", + "BC", + 4 + ], + [ + "AA", + "BaccaAA", + 10 + ], + [ + "AA", + "Bba", + 5 + ], + [ + "AA", + "BbcbcccAB", + 16 + ], + [ + "AA", + "CAb", + 4 + ], + [ + "AA", + "Cc", + 4 + ], + [ + "AA", + "CcBACCa", + 11 + ], + [ + "AA", + "aCBa", + 6 + ], + [ + "AA", + "aaBA", + 5 + ], + [ + "AA", + "aaBac", + 8 + ], + [ + "AA", + "bAAabBA", + 10 + ], + [ + "AA", + "bABbacbb", + 13 + ], + [ + "AA", + "bBbBbc", + 12 + ], + [ + "AA", + "bC", + 4 + ], + [ + "AA", + "bCabb", + 9 + ], + [ + "AA", + "baAB", + 5 + ], + [ + "AA", + "bbBaBcCBB", + 17 + ], + [ + "AA", + "bbBbAaaB", + 13 + ], + [ + "AA", + "c", + 4 + ], + [ + "AA", + "cACaCbab", + 13 + ], + [ + "AA", + "cBbCbBcA", + 14 + ], + [ + "AA", + "cBba", + 7 + ], + [ + "AA", + "cCbBBCca", + 15 + ], + [ + "AA", + "cacaca", + 10 + ], + [ + "AA", + "ccbccAa", + 11 + ], + [ + "AAA", + "B", + 6 + ], + [ + "AAA", + "C", + 6 + ], + [ + "AAA", + "aBBbcAaBa", + 14 + ], + [ + "AAA", + "aacbbBbbc", + 16 + ], + [ + "AAA", + "abAb", + 5 + ], + [ + "AAA", + "cccaAbBcB", + 15 + ], + [ + "AAAAABA", + "CaBcAaa", + 10 + ], + [ + "AAABACbC", + "BBBC", + 11 + ], + [ + "AAABAbaaA", + "CBbbacb", + 12 + ], + [ + "AAABa", + "AA", + 6 + ], + [ + "AAABc", + "cbBabcaBA", + 14 + ], + [ + "AAAC", + "acBcCCcC", + 13 + ], + [ + "AAACAbAaa", + "BCc", + 16 + ], + [ + "AAACBACc", + "CaCabAc", + 10 + ], + [ + "AAACCbbcA", + "bc", + 14 + ], + [ + "AAACa", + "A", + 8 + ], + [ + "AAACbCaa", + "acABAAa", + 9 + ], + [ + "AAACbaaa", + "BBa", + 13 + ], + [ + "AAAa", + "bBaaCc", + 9 + ], + [ + "AAAaAB", + "BCB", + 10 + ], + [ + "AAAaAcC", + "CAbBcBBC", + 12 + ], + [ + "AAAaCAAb", + "aBbAbaaA", + 12 + ], + [ + "AAAaCaA", + "cBcABaAb", + 11 + ], + [ + "AAAaaaaA", + "ABBBcaA", + 10 + ], + [ + "AAAb", + "AcC", + 6 + ], + [ + "AAAb", + "B", + 7 + ], + [ + "AAAbAB", + "cCBaAbcc", + 11 + ], + [ + "AAAbBcbc", + "C", + 15 + ], + [ + "AAAbaAABb", + "cCcAaca", + 15 + ], + [ + "AAAbbaA", + "Cbcc", + 12 + ], + [ + "AAAbbc", + "ABcaCCbca", + 11 + ], + [ + "AAAbcAcBA", + "bBaACAC", + 13 + ], + [ + "AAAbcbCa", + "cabCCbCba", + 10 + ], + [ + "AAAcAcCC", + "cbBCAAB", + 13 + ], + [ + "AAAcBAbCB", + "cbbABC", + 12 + ], + [ + "AAB", + "CB", + 4 + ], + [ + "AAB", + "accAC", + 7 + ], + [ + "AAB", + "bCCbaBbAc", + 15 + ], + [ + "AAB", + "bbb", + 5 + ], + [ + "AAB", + "bcCBcC", + 10 + ], + [ + "AABA", + "AAc", + 4 + ], + [ + "AABA", + "cBCAbA", + 7 + ], + [ + "AABABCcCc", + "abAC", + 12 + ], + [ + "AABAaB", + "BAB", + 6 + ], + [ + "AABAbAa", + "BcaB", + 11 + ], + [ + "AABAcb", + "cca", + 10 + ], + [ + "AABBA", + "AbAaCBb", + 8 + ], + [ + "AABBAACcC", + "A", + 16 + ], + [ + "AABBBcb", + "B", + 12 + ], + [ + "AABBCaB", + "bAbBA", + 8 + ], + [ + "AABBCabC", + "BCC", + 10 + ], + [ + "AABBCcB", + "cABBBAACc", + 10 + ], + [ + "AABBabAA", + "A", + 14 + ], + [ + "AABBac", + "BACCCB", + 10 + ], + [ + "AABBc", + "CAaBaA", + 7 + ], + [ + "AABCb", + "CcaCab", + 8 + ], + [ + "AABCbccb", + "B", + 14 + ], + [ + "AABCcA", + "BabC", + 8 + ], + [ + "AABCcB", + "BAB", + 8 + ], + [ + "AABCca", + "AbBBC", + 7 + ], + [ + "AABCcbBB", + "Bab", + 12 + ], + [ + "AABa", + "ACCcBA", + 7 + ], + [ + "AABa", + "BCcbaAa", + 11 + ], + [ + "AABa", + "C", + 8 + ], + [ + "AABaAc", + "Ccaa", + 9 + ], + [ + "AABaC", + "aA", + 7 + ], + [ + "AABaCccb", + "AABaAAbc", + 8 + ], + [ + "AABabcc", + "ccaABC", + 11 + ], + [ + "AABacB", + "cCbaa", + 9 + ], + [ + "AABacBac", + "AcAa", + 10 + ], + [ + "AABaccb", + "CcbBbbc", + 12 + ], + [ + "AABbBa", + "bBAcbaaB", + 10 + ], + [ + "AABbCc", + "AccbaB", + 8 + ], + [ + "AABba", + "cBbAc", + 7 + ], + [ + "AABbaBa", + "BBaAbb", + 10 + ], + [ + "AABc", + "BccAAA", + 10 + ], + [ + "AABcABaaA", + "cbB", + 14 + ], + [ + "AABcAC", + "acabAC", + 7 + ], + [ + "AABcBbcb", + "baAACAbAB", + 11 + ], + [ + "AABcCB", + "ca", + 10 + ], + [ + "AABcaBC", + "AaAaab", + 8 + ], + [ + "AAC", + "CBabAaB", + 11 + ], + [ + "AAC", + "aBA", + 5 + ], + [ + "AAC", + "aCBCBbac", + 13 + ], + [ + "AAC", + "aCa", + 5 + ], + [ + "AAC", + "baaBAba", + 11 + ], + [ + "AAC", + "bbAbc", + 7 + ], + [ + "AACA", + "aaCB", + 4 + ], + [ + "AACA", + "ab", + 7 + ], + [ + "AACA", + "cc", + 7 + ], + [ + "AACAba", + "CBAAaAB", + 9 + ], + [ + "AACAba", + "b", + 10 + ], + [ + "AACAbbc", + "AbaCABCcB", + 8 + ], + [ + "AACBACbcB", + "b", + 16 + ], + [ + "AACBC", + "Abbc", + 6 + ], + [ + "AACBC", + "aaCcAb", + 8 + ], + [ + "AACBCA", + "A", + 10 + ], + [ + "AACBCcbaa", + "cbBca", + 12 + ], + [ + "AACBaB", + "AAcABBA", + 7 + ], + [ + "AACBc", + "aABCaACA", + 10 + ], + [ + "AACC", + "bB", + 8 + ], + [ + "AACCA", + "b", + 10 + ], + [ + "AACCAC", + "Ccab", + 8 + ], + [ + "AACCBBAac", + "abbabb", + 14 + ], + [ + "AACCCCbc", + "BBCCaB", + 11 + ], + [ + "AACCCc", + "bcCbaBACA", + 14 + ], + [ + "AACCaBcA", + "BaC", + 13 + ], + [ + "AACCaca", + "ccbaBBaB", + 13 + ], + [ + "AACCc", + "b", + 10 + ], + [ + "AACa", + "BAC", + 4 + ], + [ + "AACaAaBA", + "AbcbB", + 11 + ], + [ + "AACaac", + "C", + 10 + ], + [ + "AACacB", + "CcbCBaBb", + 11 + ], + [ + "AACb", + "AC", + 4 + ], + [ + "AACb", + "ac", + 6 + ], + [ + "AACbAC", + "BBCCBCa", + 10 + ], + [ + "AACbC", + "bb", + 8 + ], + [ + "AACbbcaa", + "bbaaBCBb", + 14 + ], + [ + "AACbc", + "AbcbbBcCB", + 11 + ], + [ + "AACbc", + "aCCB", + 6 + ], + [ + "AACbcAaAb", + "BABcaBBAA", + 12 + ], + [ + "AACbcb", + "cabBc", + 8 + ], + [ + "AACc", + "BbCC", + 5 + ], + [ + "AACc", + "bbb", + 8 + ], + [ + "AACcAABAC", + "CBAcBaABa", + 11 + ], + [ + "AACcAb", + "CBCbCACcb", + 11 + ], + [ + "AACcCAAc", + "AbAACbCC", + 11 + ], + [ + "AACcabbC", + "cAAccbAB", + 9 + ], + [ + "AACcbA", + "BCCCcaCc", + 12 + ], + [ + "AAa", + "ACCC", + 6 + ], + [ + "AAa", + "BcAC", + 6 + ], + [ + "AAa", + "CACcaAAAb", + 13 + ], + [ + "AAa", + "CAaCA", + 6 + ], + [ + "AAa", + "aCcBACb", + 11 + ], + [ + "AAa", + "abACAA", + 7 + ], + [ + "AAa", + "b", + 6 + ], + [ + "AAa", + "cAAaBA", + 6 + ], + [ + "AAa", + "cBaB", + 6 + ], + [ + "AAaA", + "ca", + 6 + ], + [ + "AAaACcb", + "ABCcb", + 6 + ], + [ + "AAaB", + "aCAC", + 6 + ], + [ + "AAaB", + "cbAb", + 6 + ], + [ + "AAaBA", + "bBAc", + 8 + ], + [ + "AAaBB", + "ABCCaCBb", + 9 + ], + [ + "AAaBa", + "AcB", + 6 + ], + [ + "AAaBaB", + "aCcb", + 9 + ], + [ + "AAaBacBaC", + "CacABc", + 12 + ], + [ + "AAaBbAb", + "cC", + 14 + ], + [ + "AAaBbcaa", + "caB", + 12 + ], + [ + "AAaC", + "aCbBcBCB", + 13 + ], + [ + "AAaCACAB", + "cBa", + 14 + ], + [ + "AAaCCaCaA", + "baACABCCA", + 10 + ], + [ + "AAaCCcbb", + "aa", + 13 + ], + [ + "AAaCaccb", + "AAA", + 11 + ], + [ + "AAaCbAAAc", + "babcbBccb", + 14 + ], + [ + "AAaCcB", + "aA", + 9 + ], + [ + "AAaa", + "Abcbb", + 8 + ], + [ + "AAaaA", + "ACaCAcaa", + 9 + ], + [ + "AAaaB", + "cAaaAB", + 4 + ], + [ + "AAaaBbaC", + "bbCaCBc", + 12 + ], + [ + "AAaaCBabC", + "bBb", + 14 + ], + [ + "AAaacacca", + "C", + 17 + ], + [ + "AAaaccbA", + "CB", + 14 + ], + [ + "AAabAbac", + "cbABacbbc", + 11 + ], + [ + "AAabBBaA", + "caCcAAB", + 13 + ], + [ + "AAabCA", + "CbACAA", + 9 + ], + [ + "AAabCbCA", + "ACb", + 10 + ], + [ + "AAabb", + "B", + 9 + ], + [ + "AAabc", + "cBc", + 7 + ], + [ + "AAacA", + "CBBcB", + 8 + ], + [ + "AAacA", + "Cc", + 8 + ], + [ + "AAacCBCBc", + "bAaacCc", + 9 + ], + [ + "AAacCaBa", + "a", + 14 + ], + [ + "AAacCbCCC", + "BaB", + 15 + ], + [ + "AAaccABAA", + "bBCb", + 16 + ], + [ + "AAb", + "AbB", + 3 + ], + [ + "AAb", + "B", + 5 + ], + [ + "AAb", + "aCBbBBa", + 11 + ], + [ + "AAb", + "bAAc", + 4 + ], + [ + "AAb", + "bABA", + 5 + ], + [ + "AAb", + "bBCbBbaCA", + 16 + ], + [ + "AAb", + "bbBBaB", + 10 + ], + [ + "AAb", + "bbCcAb", + 8 + ], + [ + "AAbA", + "Bbb", + 6 + ], + [ + "AAbAAaBCC", + "b", + 16 + ], + [ + "AAbABB", + "Ca", + 11 + ], + [ + "AAbAaBBcB", + "BABaCB", + 10 + ], + [ + "AAbBBb", + "a", + 11 + ], + [ + "AAbBCCb", + "bA", + 12 + ], + [ + "AAbBbBcC", + "C", + 14 + ], + [ + "AAbBbbBcc", + "aCA", + 16 + ], + [ + "AAbC", + "cBbBCBBb", + 12 + ], + [ + "AAbCbBcC", + "BaABcCaCc", + 11 + ], + [ + "AAbCcCbC", + "a", + 15 + ], + [ + "AAba", + "cBCabCC", + 11 + ], + [ + "AAba", + "cBcBCcaBc", + 15 + ], + [ + "AAbaCabC", + "Aa", + 12 + ], + [ + "AAbabb", + "cbBAca", + 10 + ], + [ + "AAbb", + "AcbaaAB", + 9 + ], + [ + "AAbb", + "bccb", + 6 + ], + [ + "AAbbAcAB", + "cbacaBBBA", + 14 + ], + [ + "AAbbBAaAC", + "bcbaabc", + 11 + ], + [ + "AAbbbB", + "bCa", + 10 + ], + [ + "AAbcBbA", + "aaccCbB", + 8 + ], + [ + "AAbcaBBBA", + "ABb", + 13 + ], + [ + "AAbcacaB", + "cAAAbBb", + 12 + ], + [ + "AAbcbacC", + "abbbAaCCa", + 10 + ], + [ + "AAc", + "ACAc", + 2 + ], + [ + "AAc", + "AbB", + 4 + ], + [ + "AAc", + "BAabA", + 7 + ], + [ + "AAc", + "aAbc", + 3 + ], + [ + "AAc", + "aaaaacAA", + 12 + ], + [ + "AAc", + "aab", + 4 + ], + [ + "AAc", + "c", + 4 + ], + [ + "AAcA", + "AAbAAA", + 6 + ], + [ + "AAcABCA", + "bBBAbab", + 11 + ], + [ + "AAcAC", + "cCAAa", + 8 + ], + [ + "AAcAac", + "cAcA", + 6 + ], + [ + "AAcAbBcB", + "AAAAB", + 8 + ], + [ + "AAcAccAb", + "Ccac", + 11 + ], + [ + "AAcBBBcCB", + "A", + 16 + ], + [ + "AAcBbA", + "Aa", + 9 + ], + [ + "AAcC", + "bCbcaCCa", + 12 + ], + [ + "AAcCabaB", + "cACAC", + 11 + ], + [ + "AAcaACCBA", + "abcBCca", + 11 + ], + [ + "AAcaCBAcB", + "cCaBCcC", + 11 + ], + [ + "AAcab", + "A", + 8 + ], + [ + "AAcab", + "AcaabCccc", + 12 + ], + [ + "AAcb", + "aCBCcCBcC", + 14 + ], + [ + "AAcbAccc", + "CcccbA", + 12 + ], + [ + "AAcbCCAcB", + "BbbCaACc", + 11 + ], + [ + "AAcbCca", + "a", + 12 + ], + [ + "AAcbc", + "caCcb", + 7 + ], + [ + "AAcc", + "CcaBbcC", + 10 + ], + [ + "AAccB", + "cCca", + 7 + ], + [ + "AAccb", + "aA", + 7 + ], + [ + "AAccccbAA", + "caAaa", + 14 + ], + [ + "AB", + "A", + 2 + ], + [ + "AB", + "AACca", + 8 + ], + [ + "AB", + "ABcAc", + 6 + ], + [ + "AB", + "ACCACCbC", + 13 + ], + [ + "AB", + "BAA", + 4 + ], + [ + "AB", + "BAbac", + 7 + ], + [ + "AB", + "BC", + 4 + ], + [ + "AB", + "BbaCAc", + 10 + ], + [ + "AB", + "Bbac", + 7 + ], + [ + "AB", + "BcA", + 6 + ], + [ + "AB", + "CAAacB", + 8 + ], + [ + "AB", + "CC", + 4 + ], + [ + "AB", + "CCaabBcb", + 13 + ], + [ + "AB", + "CCcB", + 6 + ], + [ + "AB", + "CbA", + 5 + ], + [ + "AB", + "aCAC", + 6 + ], + [ + "AB", + "bBA", + 4 + ], + [ + "AB", + "bCbB", + 6 + ], + [ + "AB", + "bCccbbb", + 13 + ], + [ + "AB", + "bbb", + 5 + ], + [ + "AB", + "bcAbAAA", + 11 + ], + [ + "AB", + "bcbC", + 7 + ], + [ + "AB", + "c", + 4 + ], + [ + "AB", + "cCabccbCB", + 15 + ], + [ + "AB", + "caCBB", + 7 + ], + [ + "AB", + "caaac", + 9 + ], + [ + "AB", + "cababCa", + 12 + ], + [ + "ABA", + "A", + 4 + ], + [ + "ABA", + "ACBcBa", + 7 + ], + [ + "ABA", + "AcAb", + 4 + ], + [ + "ABA", + "abbBaaC", + 10 + ], + [ + "ABA", + "c", + 6 + ], + [ + "ABA", + "caAaCCbc", + 13 + ], + [ + "ABAAB", + "cbB", + 7 + ], + [ + "ABAABacbC", + "Ba", + 14 + ], + [ + "ABAAaCAa", + "cABb", + 14 + ], + [ + "ABAAaaBb", + "BCACaB", + 8 + ], + [ + "ABAAabb", + "bAcABc", + 9 + ], + [ + "ABAAabbCC", + "cbcBc", + 15 + ], + [ + "ABAAbBCb", + "aCACb", + 9 + ], + [ + "ABAAc", + "AbCc", + 5 + ], + [ + "ABAAcC", + "A", + 10 + ], + [ + "ABABBCaBb", + "aAcBcc", + 12 + ], + [ + "ABABCAB", + "cbBBCaA", + 8 + ], + [ + "ABABaaCc", + "BBBBBAB", + 11 + ], + [ + "ABABbCCab", + "aAC", + 13 + ], + [ + "ABAC", + "abaAC", + 4 + ], + [ + "ABACAccCC", + "BBCBcbCAc", + 11 + ], + [ + "ABACCAACA", + "aAacA", + 11 + ], + [ + "ABACaa", + "BA", + 8 + ], + [ + "ABACb", + "b", + 8 + ], + [ + "ABACbaCcC", + "cCBBbCbC", + 12 + ], + [ + "ABAa", + "A", + 6 + ], + [ + "ABAaAbbc", + "ccaCBA", + 13 + ], + [ + "ABAaB", + "bb", + 8 + ], + [ + "ABAaCCAB", + "acba", + 12 + ], + [ + "ABAaaBCBB", + "BaCC", + 12 + ], + [ + "ABAacbAbA", + "ABAb", + 10 + ], + [ + "ABAb", + "AcA", + 4 + ], + [ + "ABAb", + "cCab", + 5 + ], + [ + "ABAbACCB", + "cBCB", + 10 + ], + [ + "ABAbBC", + "BBAacabC", + 9 + ], + [ + "ABAbCCb", + "BAA", + 10 + ], + [ + "ABAbaCBB", + "aaCbbbBB", + 9 + ], + [ + "ABAbaCcC", + "bac", + 10 + ], + [ + "ABAc", + "CBACCbBA", + 11 + ], + [ + "ABAcAcB", + "Ac", + 10 + ], + [ + "ABAca", + "aCcCaAbC", + 12 + ], + [ + "ABAcaBc", + "bCaabABAb", + 14 + ], + [ + "ABAcaac", + "BcA", + 9 + ], + [ + "ABAcabA", + "aa", + 11 + ], + [ + "ABAcb", + "cCa", + 9 + ], + [ + "ABB", + "acaccCcA", + 15 + ], + [ + "ABB", + "bAaAAC", + 10 + ], + [ + "ABB", + "bBbAA", + 7 + ], + [ + "ABB", + "bac", + 6 + ], + [ + "ABBAAaCc", + "CaCaCAaCc", + 9 + ], + [ + "ABBAAbb", + "acBbCba", + 9 + ], + [ + "ABBAAc", + "bBccabAcB", + 11 + ], + [ + "ABBAbbAA", + "abAaaa", + 10 + ], + [ + "ABBAcBaa", + "Ab", + 13 + ], + [ + "ABBAcbAc", + "abBccbA", + 6 + ], + [ + "ABBBAa", + "ccBbcBa", + 9 + ], + [ + "ABBBAbAcc", + "abCaCAbcc", + 10 + ], + [ + "ABBBB", + "cAaCBCbCb", + 12 + ], + [ + "ABBBCaB", + "BaAbBabBa", + 12 + ], + [ + "ABBCC", + "aBBbaBAab", + 13 + ], + [ + "ABBCCc", + "aAcAbB", + 11 + ], + [ + "ABBCCcab", + "AcBcbcbAc", + 10 + ], + [ + "ABBa", + "bA", + 6 + ], + [ + "ABBaACA", + "cbBcAB", + 9 + ], + [ + "ABBaACCcb", + "bbCCcCb", + 10 + ], + [ + "ABBaa", + "bcabCCC", + 12 + ], + [ + "ABBabAbAC", + "AbcbbAcCc", + 10 + ], + [ + "ABBaba", + "BCcbAaBCA", + 13 + ], + [ + "ABBacb", + "CAbcBAbBa", + 11 + ], + [ + "ABBb", + "Aabc", + 5 + ], + [ + "ABBb", + "aAcAb", + 6 + ], + [ + "ABBbBAbCA", + "CCBACAAb", + 14 + ], + [ + "ABBbCbb", + "bccbcAc", + 11 + ], + [ + "ABBbb", + "aAabbCbCC", + 11 + ], + [ + "ABBcBBC", + "bCaB", + 10 + ], + [ + "ABBcCCC", + "bABbaCCC", + 5 + ], + [ + "ABBcb", + "aCc", + 7 + ], + [ + "ABBcbcC", + "AACBbAC", + 8 + ], + [ + "ABBccBcAa", + "ABa", + 12 + ], + [ + "ABBccCBA", + "CCCACa", + 12 + ], + [ + "ABBccc", + "B", + 10 + ], + [ + "ABC", + "BAaACA", + 8 + ], + [ + "ABC", + "BCc", + 4 + ], + [ + "ABC", + "CAa", + 6 + ], + [ + "ABC", + "CBca", + 5 + ], + [ + "ABC", + "CbCbbCB", + 11 + ], + [ + "ABC", + "bacacB", + 10 + ], + [ + "ABC", + "c", + 5 + ], + [ + "ABCAB", + "bAaAc", + 8 + ], + [ + "ABCAC", + "BaCBaC", + 7 + ], + [ + "ABCAa", + "aABbb", + 8 + ], + [ + "ABCAbAacA", + "cbCAa", + 11 + ], + [ + "ABCBC", + "AB", + 6 + ], + [ + "ABCBa", + "CcAACBC", + 8 + ], + [ + "ABCBa", + "caBbccC", + 10 + ], + [ + "ABCCAa", + "A", + 10 + ], + [ + "ABCCC", + "CC", + 6 + ], + [ + "ABCCbcBc", + "AbCBcBB", + 6 + ], + [ + "ABCCcCBB", + "bbccAbBBc", + 11 + ], + [ + "ABCCccaB", + "aCcACCCa", + 10 + ], + [ + "ABCaBa", + "BBb", + 8 + ], + [ + "ABCaBa", + "bbAcAA", + 10 + ], + [ + "ABCaC", + "bcCcab", + 8 + ], + [ + "ABCaa", + "AbCcaAb", + 6 + ], + [ + "ABCab", + "b", + 8 + ], + [ + "ABCabB", + "AAc", + 9 + ], + [ + "ABCb", + "CBBBC", + 7 + ], + [ + "ABCb", + "aABCcBC", + 7 + ], + [ + "ABCbAA", + "Ba", + 9 + ], + [ + "ABCbBBbc", + "cabbbCbcB", + 11 + ], + [ + "ABCbC", + "cc", + 8 + ], + [ + "ABCbCaCCc", + "aABB", + 15 + ], + [ + "ABCbaaCbb", + "CBbBBABBB", + 12 + ], + [ + "ABCbaaac", + "aaCaCCCca", + 13 + ], + [ + "ABCbbA", + "BCaAa", + 7 + ], + [ + "ABCbcC", + "ccbBBa", + 11 + ], + [ + "ABCc", + "Aa", + 6 + ], + [ + "ABCcAabbB", + "cCCaBBc", + 11 + ], + [ + "ABCcBcbC", + "Bcbcc", + 8 + ], + [ + "ABCcb", + "CacBAb", + 9 + ], + [ + "ABCccaAcC", + "BaAcBbC", + 12 + ], + [ + "ABa", + "AaabCa", + 7 + ], + [ + "ABa", + "CaA", + 5 + ], + [ + "ABaABc", + "caC", + 9 + ], + [ + "ABaAC", + "Caca", + 8 + ], + [ + "ABaAb", + "bAaC", + 7 + ], + [ + "ABaB", + "c", + 8 + ], + [ + "ABaBa", + "aacCAc", + 10 + ], + [ + "ABaBb", + "acbaBCcb", + 8 + ], + [ + "ABaBccB", + "BacbBBBcb", + 11 + ], + [ + "ABaCAb", + "aba", + 8 + ], + [ + "ABaCCC", + "aCAaacbc", + 10 + ], + [ + "ABaCc", + "bB", + 8 + ], + [ + "ABaa", + "CCcCC", + 10 + ], + [ + "ABabAbb", + "BCAcB", + 9 + ], + [ + "ABabBC", + "acc", + 9 + ], + [ + "ABabBaAc", + "AbBCbaBBB", + 12 + ], + [ + "ABababAC", + "aabaaBAA", + 8 + ], + [ + "ABabb", + "bBb", + 6 + ], + [ + "ABabcBacC", + "aC", + 14 + ], + [ + "ABabcBcc", + "BAcB", + 9 + ], + [ + "ABacCac", + "bbaCBcbcB", + 11 + ], + [ + "ABacbAAab", + "bC", + 16 + ], + [ + "ABacbbaCC", + "CbCbcbBAA", + 13 + ], + [ + "ABb", + "AaAcB", + 7 + ], + [ + "ABb", + "B", + 4 + ], + [ + "ABb", + "BB", + 3 + ], + [ + "ABb", + "BBaCCAAA", + 14 + ], + [ + "ABb", + "bBBaA", + 7 + ], + [ + "ABb", + "baCaaBaa", + 13 + ], + [ + "ABbA", + "CaACAABa", + 12 + ], + [ + "ABbACAC", + "BAcBBaB", + 12 + ], + [ + "ABbACAaAa", + "Cca", + 14 + ], + [ + "ABbAaa", + "cbacaa", + 7 + ], + [ + "ABbAaaB", + "BBc", + 11 + ], + [ + "ABbAacbAC", + "bAbAaacaa", + 11 + ], + [ + "ABbAbA", + "aaAaB", + 9 + ], + [ + "ABbBAb", + "a", + 11 + ], + [ + "ABbBcCbcA", + "acaAacBAB", + 15 + ], + [ + "ABbCC", + "caACcc", + 9 + ], + [ + "ABbCaAbb", + "b", + 14 + ], + [ + "ABbCb", + "aABCBBca", + 10 + ], + [ + "ABbCbA", + "A", + 10 + ], + [ + "ABbCbA", + "AbCbB", + 4 + ], + [ + "ABbCbbBa", + "B", + 14 + ], + [ + "ABbCcB", + "AaCccab", + 8 + ], + [ + "ABbaACBCc", + "baBCbCbcB", + 11 + ], + [ + "ABbaabcCC", + "aaaacAAAA", + 15 + ], + [ + "ABbacAAA", + "CAAccb", + 13 + ], + [ + "ABbb", + "cAaC", + 8 + ], + [ + "ABbbA", + "BCcbb", + 8 + ], + [ + "ABbbC", + "ABBc", + 4 + ], + [ + "ABbbbB", + "BCabaCc", + 12 + ], + [ + "ABbc", + "bBcAAac", + 10 + ], + [ + "ABbcc", + "AbBABaaa", + 11 + ], + [ + "ABbccBA", + "cACaCcCC", + 11 + ], + [ + "ABc", + "a", + 5 + ], + [ + "ABc", + "aA", + 5 + ], + [ + "ABc", + "b", + 5 + ], + [ + "ABcA", + "CB", + 6 + ], + [ + "ABcAa", + "BcbAC", + 6 + ], + [ + "ABcAaB", + "ab", + 9 + ], + [ + "ABcAbAa", + "AcAABbb", + 9 + ], + [ + "ABcAc", + "c", + 8 + ], + [ + "ABcAcCAc", + "cAcBcCaC", + 8 + ], + [ + "ABcBBcCCB", + "BaAcBbC", + 12 + ], + [ + "ABcBbAb", + "aAbACcAca", + 13 + ], + [ + "ABcBcCCbB", + "cbAC", + 13 + ], + [ + "ABcC", + "Cabc", + 6 + ], + [ + "ABcC", + "c", + 6 + ], + [ + "ABcCAaCc", + "C", + 14 + ], + [ + "ABcCAbCba", + "CcBa", + 12 + ], + [ + "ABcCBb", + "CAb", + 8 + ], + [ + "ABcCCa", + "bCaca", + 7 + ], + [ + "ABcCCcBa", + "Cbc", + 12 + ], + [ + "ABcCbbBbC", + "b", + 16 + ], + [ + "ABcaBC", + "Bcc", + 7 + ], + [ + "ABcaBb", + "CB", + 9 + ], + [ + "ABcb", + "a", + 7 + ], + [ + "ABcbAcc", + "AbBa", + 9 + ], + [ + "ABcbBC", + "cCcAa", + 10 + ], + [ + "ABcbCacCb", + "ba", + 14 + ], + [ + "ABcc", + "bAAcbCa", + 9 + ], + [ + "ABccA", + "CA", + 7 + ], + [ + "ABcccb", + "CB", + 10 + ], + [ + "AC", + "A", + 2 + ], + [ + "AC", + "AAb", + 4 + ], + [ + "AC", + "AB", + 2 + ], + [ + "AC", + "ABBc", + 5 + ], + [ + "AC", + "ABaaaBc", + 11 + ], + [ + "AC", + "ACBaAbb", + 10 + ], + [ + "AC", + "AaBcBC", + 8 + ], + [ + "AC", + "AaCCCB", + 8 + ], + [ + "AC", + "AabB", + 6 + ], + [ + "AC", + "AacAaBc", + 11 + ], + [ + "AC", + "AbBCacbA", + 12 + ], + [ + "AC", + "AbbbcbACb", + 14 + ], + [ + "AC", + "B", + 4 + ], + [ + "AC", + "BBbA", + 8 + ], + [ + "AC", + "BCaa", + 6 + ], + [ + "AC", + "BbCaaA", + 10 + ], + [ + "AC", + "BcAab", + 8 + ], + [ + "AC", + "C", + 2 + ], + [ + "AC", + "CAcb", + 5 + ], + [ + "AC", + "Ca", + 4 + ], + [ + "AC", + "CabAB", + 8 + ], + [ + "AC", + "aABaABAB", + 14 + ], + [ + "AC", + "aAacbbcAC", + 14 + ], + [ + "AC", + "aBCaCBba", + 13 + ], + [ + "AC", + "aa", + 3 + ], + [ + "AC", + "aaaBBabAb", + 16 + ], + [ + "AC", + "baccAbcB", + 13 + ], + [ + "AC", + "c", + 3 + ], + [ + "AC", + "cACCaBA", + 10 + ], + [ + "AC", + "cCaaAacaA", + 15 + ], + [ + "AC", + "cbcbbcC", + 12 + ], + [ + "ACA", + "Aa", + 3 + ], + [ + "ACA", + "C", + 4 + ], + [ + "ACA", + "CbaaBc", + 11 + ], + [ + "ACA", + "aAABAAcb", + 12 + ], + [ + "ACA", + "cACCbaAaC", + 12 + ], + [ + "ACAA", + "AcaAAb", + 5 + ], + [ + "ACAABBaC", + "A", + 14 + ], + [ + "ACAABcA", + "bCBACacC", + 10 + ], + [ + "ACAAC", + "bB", + 10 + ], + [ + "ACAAC", + "cBaaCabaC", + 11 + ], + [ + "ACAAa", + "CAa", + 4 + ], + [ + "ACAAaCaA", + "AAacb", + 9 + ], + [ + "ACAAbcaAa", + "bba", + 14 + ], + [ + "ACABA", + "bAB", + 6 + ], + [ + "ACABA", + "c", + 9 + ], + [ + "ACABABA", + "CcC", + 12 + ], + [ + "ACABACaB", + "bcBAaAB", + 8 + ], + [ + "ACABbCaBc", + "cA", + 15 + ], + [ + "ACAC", + "aaBAA", + 7 + ], + [ + "ACACB", + "aaCcbaBC", + 11 + ], + [ + "ACACBB", + "cCb", + 8 + ], + [ + "ACACBbccA", + "BABbAc", + 10 + ], + [ + "ACACC", + "BaAA", + 8 + ], + [ + "ACACa", + "Bccc", + 8 + ], + [ + "ACACbB", + "aCaacAaC", + 11 + ], + [ + "ACACbab", + "cC", + 11 + ], + [ + "ACAaA", + "Aaabbc", + 9 + ], + [ + "ACAaB", + "caBBcB", + 9 + ], + [ + "ACAaBA", + "CAbCC", + 8 + ], + [ + "ACAaCBccb", + "c", + 16 + ], + [ + "ACAabbCAc", + "BB", + 16 + ], + [ + "ACAb", + "AaaCC", + 7 + ], + [ + "ACAbBCaCA", + "A", + 16 + ], + [ + "ACAbbaaBA", + "aacacABbc", + 15 + ], + [ + "ACAbcB", + "bcBCB", + 7 + ], + [ + "ACAc", + "CCbcaabA", + 12 + ], + [ + "ACAcBCc", + "AcaAbcb", + 8 + ], + [ + "ACAcaabA", + "CACbBC", + 10 + ], + [ + "ACB", + "ACbbaBb", + 8 + ], + [ + "ACB", + "aCbbc", + 6 + ], + [ + "ACB", + "baBacBAB", + 12 + ], + [ + "ACB", + "cabbCcBA", + 11 + ], + [ + "ACBA", + "CbCCCaCAc", + 14 + ], + [ + "ACBAC", + "CaABbbcBA", + 13 + ], + [ + "ACBACBB", + "cAABCbBC", + 9 + ], + [ + "ACBACCba", + "ACBCcCb", + 5 + ], + [ + "ACBAbCBc", + "bC", + 12 + ], + [ + "ACBAba", + "aAaCaC", + 10 + ], + [ + "ACBAcb", + "aCACc", + 6 + ], + [ + "ACBB", + "bAbb", + 6 + ], + [ + "ACBBAB", + "BbBCb", + 8 + ], + [ + "ACBBABBa", + "bbabA", + 11 + ], + [ + "ACBBBaA", + "bccbA", + 10 + ], + [ + "ACBBBaCA", + "bCCCB", + 12 + ], + [ + "ACBBcAccc", + "ab", + 16 + ], + [ + "ACBCCC", + "a", + 11 + ], + [ + "ACBCbaa", + "ACCAbCCb", + 10 + ], + [ + "ACBaA", + "BcBcBcA", + 9 + ], + [ + "ACBaBa", + "AaAa", + 6 + ], + [ + "ACBabaa", + "abcAbbb", + 10 + ], + [ + "ACBabbab", + "CAa", + 11 + ], + [ + "ACBac", + "BcbcCb", + 9 + ], + [ + "ACBb", + "bcCAca", + 10 + ], + [ + "ACBbCaaBB", + "Cc", + 15 + ], + [ + "ACBba", + "CcaAbbc", + 10 + ], + [ + "ACBbaAbAC", + "aCabbAC", + 7 + ], + [ + "ACBbcAcB", + "cb", + 13 + ], + [ + "ACBcAB", + "cb", + 9 + ], + [ + "ACBcaaAAb", + "ACBA", + 10 + ], + [ + "ACC", + "BcccCaAba", + 15 + ], + [ + "ACC", + "Ccb", + 5 + ], + [ + "ACC", + "aB", + 5 + ], + [ + "ACC", + "bBcABBbAC", + 14 + ], + [ + "ACC", + "cABA", + 6 + ], + [ + "ACC", + "caACC", + 4 + ], + [ + "ACCA", + "BaaBc", + 9 + ], + [ + "ACCA", + "BacAabAAa", + 14 + ], + [ + "ACCACABB", + "ABAAbBaBa", + 11 + ], + [ + "ACCAbB", + "CcbAacC", + 11 + ], + [ + "ACCAccAB", + "ACbCC", + 10 + ], + [ + "ACCBAAC", + "Ac", + 11 + ], + [ + "ACCBAaBC", + "a", + 14 + ], + [ + "ACCBB", + "BcCccabbA", + 13 + ], + [ + "ACCBBcac", + "CCB", + 10 + ], + [ + "ACCBCBC", + "AcaaCacba", + 11 + ], + [ + "ACCBac", + "aCACaCc", + 7 + ], + [ + "ACCBb", + "BaCac", + 8 + ], + [ + "ACCBbcbAC", + "AAaCaCBCC", + 12 + ], + [ + "ACCBcCBB", + "aBBABb", + 10 + ], + [ + "ACCBcaaCa", + "CBb", + 14 + ], + [ + "ACCBcc", + "bbAa", + 11 + ], + [ + "ACCCAaCcC", + "CBAc", + 12 + ], + [ + "ACCCBac", + "CcCBACBB", + 9 + ], + [ + "ACCCC", + "CACCACc", + 5 + ], + [ + "ACCCb", + "CbBaCcb", + 9 + ], + [ + "ACCCbaCAc", + "abACCC", + 11 + ], + [ + "ACCaAACa", + "C", + 14 + ], + [ + "ACCaACAa", + "a", + 14 + ], + [ + "ACCaB", + "A", + 8 + ], + [ + "ACCaCA", + "a", + 10 + ], + [ + "ACCaaAc", + "A", + 12 + ], + [ + "ACCac", + "a", + 8 + ], + [ + "ACCbA", + "aCCBa", + 3 + ], + [ + "ACCbB", + "BaAa", + 10 + ], + [ + "ACCbC", + "CcbaCC", + 7 + ], + [ + "ACCbCba", + "a", + 12 + ], + [ + "ACCbaBbb", + "aA", + 14 + ], + [ + "ACCbba", + "aaCBCbccB", + 11 + ], + [ + "ACCbbbC", + "BCbABAbaA", + 13 + ], + [ + "ACCbcBa", + "aCBaBcbC", + 9 + ], + [ + "ACCbcbccB", + "caAAbaCcb", + 13 + ], + [ + "ACCcAccCc", + "AccAb", + 11 + ], + [ + "ACCcBcB", + "AcBcAAca", + 9 + ], + [ + "ACCcC", + "a", + 9 + ], + [ + "ACCcaC", + "cCA", + 8 + ], + [ + "ACCcacC", + "BBaaAcAab", + 14 + ], + [ + "ACa", + "AcbCAbaB", + 10 + ], + [ + "ACa", + "Bca", + 3 + ], + [ + "ACa", + "ba", + 4 + ], + [ + "ACa", + "baAAaba", + 10 + ], + [ + "ACaA", + "A", + 6 + ], + [ + "ACaA", + "ABCAba", + 6 + ], + [ + "ACaA", + "acbCc", + 8 + ], + [ + "ACaA", + "cc", + 7 + ], + [ + "ACaAC", + "cABCBAc", + 7 + ], + [ + "ACaAcABa", + "cCAACC", + 10 + ], + [ + "ACaB", + "ABAbccB", + 9 + ], + [ + "ACaB", + "bAAAaAbAA", + 13 + ], + [ + "ACaBBBCB", + "AaAC", + 10 + ], + [ + "ACaBBaAa", + "AcaBcBbcB", + 9 + ], + [ + "ACaBCB", + "cc", + 10 + ], + [ + "ACaBCBb", + "b", + 12 + ], + [ + "ACaBacCc", + "bb", + 15 + ], + [ + "ACaBcb", + "BcCc", + 9 + ], + [ + "ACaCACc", + "c", + 12 + ], + [ + "ACaCBccBc", + "CcABCcBcb", + 9 + ], + [ + "ACaCCBA", + "AAcacC", + 8 + ], + [ + "ACaa", + "BAAc", + 7 + ], + [ + "ACaaBAbc", + "ACAccba", + 9 + ], + [ + "ACaabb", + "BCAb", + 7 + ], + [ + "ACaacBa", + "cBCBAc", + 11 + ], + [ + "ACabABBA", + "CAcCbB", + 10 + ], + [ + "ACabC", + "B", + 9 + ], + [ + "ACabac", + "BACcbCcbB", + 10 + ], + [ + "ACabbcA", + "aCacc", + 7 + ], + [ + "ACaccaa", + "AA", + 11 + ], + [ + "ACb", + "A", + 4 + ], + [ + "ACb", + "cBAab", + 6 + ], + [ + "ACb", + "ccbccbB", + 11 + ], + [ + "ACbA", + "AaBacA", + 7 + ], + [ + "ACbA", + "BaCCbA", + 5 + ], + [ + "ACbA", + "abACa", + 7 + ], + [ + "ACbACcbaB", + "ccc", + 14 + ], + [ + "ACbAbaCBC", + "acbaba", + 9 + ], + [ + "ACbB", + "aCACBAbb", + 9 + ], + [ + "ACbBA", + "CACB", + 6 + ], + [ + "ACbBCC", + "bcbCaAB", + 11 + ], + [ + "ACbBa", + "B", + 8 + ], + [ + "ACbBaCab", + "cbB", + 11 + ], + [ + "ACbCCbBb", + "aaca", + 14 + ], + [ + "ACbCaA", + "bAbC", + 8 + ], + [ + "ACbCb", + "c", + 9 + ], + [ + "ACbCc", + "ABc", + 5 + ], + [ + "ACbCcbA", + "accAAAaCc", + 15 + ], + [ + "ACba", + "acABAcbC", + 11 + ], + [ + "ACba", + "bCabba", + 6 + ], + [ + "ACbaAaA", + "BaaAbcC", + 12 + ], + [ + "ACbaAbB", + "AaBbbbb", + 8 + ], + [ + "ACbaAc", + "ABaBbCBcB", + 12 + ], + [ + "ACbaCAC", + "bBcaC", + 8 + ], + [ + "ACbaCaB", + "cbaA", + 8 + ], + [ + "ACbaaaB", + "CAcA", + 10 + ], + [ + "ACbabABB", + "BCBABBAc", + 11 + ], + [ + "ACbabcac", + "ABBA", + 11 + ], + [ + "ACbbBB", + "cAbbaC", + 8 + ], + [ + "ACbbBb", + "abAAbCab", + 10 + ], + [ + "ACbbCc", + "AccCbBAAB", + 11 + ], + [ + "ACbbca", + "cbABC", + 9 + ], + [ + "ACbbccB", + "b", + 12 + ], + [ + "ACbcBBc", + "CBacBbCbA", + 11 + ], + [ + "ACbcCba", + "abBBc", + 10 + ], + [ + "ACbcCccA", + "BBaA", + 13 + ], + [ + "ACc", + "AABbabcbb", + 14 + ], + [ + "ACc", + "ABbCcC", + 6 + ], + [ + "ACc", + "ABcBaB", + 8 + ], + [ + "ACc", + "a", + 5 + ], + [ + "ACc", + "b", + 6 + ], + [ + "ACc", + "baCBbbCbc", + 13 + ], + [ + "ACc", + "bcAcC", + 6 + ], + [ + "ACc", + "c", + 4 + ], + [ + "ACcA", + "CbcBBcbb", + 13 + ], + [ + "ACcA", + "aBBA", + 5 + ], + [ + "ACcAAb", + "ccAa", + 6 + ], + [ + "ACcABac", + "cA", + 10 + ], + [ + "ACcAc", + "baC", + 8 + ], + [ + "ACcBCBbbB", + "aA", + 17 + ], + [ + "ACcBa", + "ABBbBAbca", + 12 + ], + [ + "ACcBa", + "abbaca", + 9 + ], + [ + "ACcBba", + "baaAcAcA", + 12 + ], + [ + "ACcBbaa", + "CbCcCCBAC", + 12 + ], + [ + "ACcC", + "AcCABAC", + 8 + ], + [ + "ACcCACb", + "CABB", + 9 + ], + [ + "ACcCC", + "ccabBBC", + 11 + ], + [ + "ACcCa", + "Bcb", + 8 + ], + [ + "ACcCacAa", + "CbCba", + 10 + ], + [ + "ACcCc", + "bbBCC", + 7 + ], + [ + "ACca", + "cBBCBcbC", + 12 + ], + [ + "ACcaCAb", + "aaA", + 9 + ], + [ + "ACcaaAb", + "CaCAc", + 8 + ], + [ + "ACcabc", + "AAACb", + 8 + ], + [ + "ACcac", + "abBCBCc", + 9 + ], + [ + "ACcbB", + "caBaa", + 10 + ], + [ + "ACcbC", + "aCA", + 7 + ], + [ + "ACcbaBb", + "aCACCCAaA", + 12 + ], + [ + "ACcbbC", + "cacb", + 8 + ], + [ + "ACcbcCBB", + "A", + 14 + ], + [ + "ACcc", + "Cca", + 4 + ], + [ + "ACcca", + "accBbB", + 8 + ], + [ + "ACccabBC", + "Bb", + 14 + ], + [ + "ACccb", + "C", + 8 + ], + [ + "ACccbCccb", + "BbCacaA", + 14 + ], + [ + "ACccca", + "A", + 10 + ], + [ + "Aa", + "A", + 2 + ], + [ + "Aa", + "AAcac", + 6 + ], + [ + "Aa", + "ABBa", + 4 + ], + [ + "Aa", + "AbAabCcB", + 12 + ], + [ + "Aa", + "AbCCCCbcC", + 16 + ], + [ + "Aa", + "AbccAA", + 9 + ], + [ + "Aa", + "B", + 4 + ], + [ + "Aa", + "BA", + 3 + ], + [ + "Aa", + "BB", + 4 + ], + [ + "Aa", + "BBaccBAc", + 14 + ], + [ + "Aa", + "BCAaBb", + 8 + ], + [ + "Aa", + "BaBBAc", + 10 + ], + [ + "Aa", + "BaBcCaBc", + 13 + ], + [ + "Aa", + "BaCc", + 6 + ], + [ + "Aa", + "BabcCcAb", + 14 + ], + [ + "Aa", + "BbBB", + 8 + ], + [ + "Aa", + "C", + 4 + ], + [ + "Aa", + "CAabcaaAB", + 14 + ], + [ + "Aa", + "CAbbCbCB", + 14 + ], + [ + "Aa", + "CBBaBccb", + 14 + ], + [ + "Aa", + "CBCAccba", + 12 + ], + [ + "Aa", + "a", + 2 + ], + [ + "Aa", + "aAc", + 4 + ], + [ + "Aa", + "aacb", + 5 + ], + [ + "Aa", + "acAAacaB", + 12 + ], + [ + "Aa", + "acaA", + 5 + ], + [ + "Aa", + "acbc", + 7 + ], + [ + "Aa", + "b", + 4 + ], + [ + "Aa", + "bBA", + 5 + ], + [ + "Aa", + "bBABbc", + 10 + ], + [ + "Aa", + "baABcc", + 10 + ], + [ + "Aa", + "babbc", + 8 + ], + [ + "Aa", + "bbabBCac", + 13 + ], + [ + "Aa", + "cAAB", + 5 + ], + [ + "Aa", + "cC", + 4 + ], + [ + "Aa", + "caCAB", + 8 + ], + [ + "Aa", + "ccabB", + 8 + ], + [ + "AaA", + "Acbc", + 6 + ], + [ + "AaA", + "BBAcB", + 8 + ], + [ + "AaA", + "BaAbb", + 6 + ], + [ + "AaA", + "CAcBB", + 8 + ], + [ + "AaA", + "Cc", + 6 + ], + [ + "AaA", + "a", + 4 + ], + [ + "AaA", + "bAcaab", + 7 + ], + [ + "AaA", + "bCbCac", + 10 + ], + [ + "AaA", + "bCcaBAa", + 10 + ], + [ + "AaA", + "cAbaCAbB", + 10 + ], + [ + "AaAA", + "bcacBb", + 10 + ], + [ + "AaAABca", + "aACbAbaa", + 9 + ], + [ + "AaAAbA", + "CAbA", + 6 + ], + [ + "AaAAbBCcc", + "bbcAb", + 14 + ], + [ + "AaAAcbcbB", + "aAcCCBba", + 11 + ], + [ + "AaABbA", + "BBaACcACA", + 12 + ], + [ + "AaABc", + "cCcaBB", + 9 + ], + [ + "AaABcBAbb", + "BABAbaB", + 11 + ], + [ + "AaACCAb", + "C", + 12 + ], + [ + "AaACCaac", + "aabBbAbCA", + 13 + ], + [ + "AaACa", + "BBb", + 10 + ], + [ + "AaAaABB", + "CABcCCcCA", + 16 + ], + [ + "AaAaBbCc", + "B", + 14 + ], + [ + "AaAaa", + "cba", + 8 + ], + [ + "AaAabb", + "CACAA", + 9 + ], + [ + "AaAaccCB", + "bAaacBbaA", + 12 + ], + [ + "AaAb", + "cABAcb", + 6 + ], + [ + "AaAbAaAb", + "a", + 14 + ], + [ + "AaAbAbbB", + "aA", + 12 + ], + [ + "AaAbBba", + "CCBac", + 12 + ], + [ + "AaAbb", + "BbaB", + 8 + ], + [ + "AaAbbc", + "cAAcCC", + 8 + ], + [ + "AaAbc", + "a", + 8 + ], + [ + "AaAc", + "aAaCA", + 6 + ], + [ + "AaAcA", + "BCAAAba", + 8 + ], + [ + "AaAccaBbc", + "baAcAACaa", + 11 + ], + [ + "AaB", + "AbbAbb", + 8 + ], + [ + "AaB", + "Bca", + 6 + ], + [ + "AaB", + "bbaAb", + 7 + ], + [ + "AaB", + "bcABBBCc", + 12 + ], + [ + "AaB", + "caAb", + 5 + ], + [ + "AaBA", + "cBAB", + 6 + ], + [ + "AaBACC", + "BCAAbB", + 10 + ], + [ + "AaBACaBA", + "cAc", + 13 + ], + [ + "AaBAa", + "c", + 10 + ], + [ + "AaBAc", + "CcACba", + 10 + ], + [ + "AaBAcBcaa", + "cb", + 15 + ], + [ + "AaBBAC", + "ACAca", + 9 + ], + [ + "AaBBAcbcc", + "CbCcBb", + 14 + ], + [ + "AaBBbcA", + "A", + 12 + ], + [ + "AaBCcbCB", + "CCcAb", + 11 + ], + [ + "AaBa", + "abA", + 4 + ], + [ + "AaBa", + "bbbCabA", + 10 + ], + [ + "AaBaaaCBa", + "A", + 16 + ], + [ + "AaBabBCb", + "aBac", + 9 + ], + [ + "AaBbB", + "bBaa", + 8 + ], + [ + "AaBba", + "ab", + 6 + ], + [ + "AaBbba", + "caAbBAa", + 7 + ], + [ + "AaBbbaac", + "Cbcca", + 12 + ], + [ + "AaBbbbA", + "AabcBAa", + 7 + ], + [ + "AaBc", + "bAaaBaCCB", + 11 + ], + [ + "AaBcA", + "aCbCbB", + 9 + ], + [ + "AaBcAbBC", + "CBCACaBBA", + 12 + ], + [ + "AaBccbA", + "BBcaaccb", + 10 + ], + [ + "AaC", + "AACcabcAa", + 13 + ], + [ + "AaC", + "ABAaabA", + 10 + ], + [ + "AaC", + "Acc", + 3 + ], + [ + "AaC", + "aCCB", + 5 + ], + [ + "AaC", + "bbbbbbAA", + 15 + ], + [ + "AaCA", + "CCc", + 6 + ], + [ + "AaCAAAcac", + "ABB", + 16 + ], + [ + "AaCAAbaa", + "CCbABc", + 11 + ], + [ + "AaCACCa", + "BCcBACc", + 10 + ], + [ + "AaCACCbcc", + "CAacc", + 10 + ], + [ + "AaCAcAcB", + "bbA", + 14 + ], + [ + "AaCB", + "BbBC", + 8 + ], + [ + "AaCB", + "bCCbBAA", + 10 + ], + [ + "AaCBa", + "ACAbC", + 7 + ], + [ + "AaCBaC", + "Ba", + 8 + ], + [ + "AaCBaaAAC", + "CaBc", + 13 + ], + [ + "AaCBbBBa", + "CBbAcCBb", + 12 + ], + [ + "AaCCAAC", + "ACaBb", + 9 + ], + [ + "AaCCAbcBB", + "BCaab", + 13 + ], + [ + "AaCCCB", + "AaaAA", + 8 + ], + [ + "AaCCCBB", + "bB", + 11 + ], + [ + "AaCCcbB", + "BCcaCcB", + 9 + ], + [ + "AaCCcc", + "cbc", + 9 + ], + [ + "AaCaAAa", + "ccccBbcaC", + 15 + ], + [ + "AaCaCccb", + "aCB", + 11 + ], + [ + "AaCaaaA", + "a", + 12 + ], + [ + "AaCaac", + "CBabAA", + 10 + ], + [ + "AaCac", + "AbaBC", + 7 + ], + [ + "AaCbbbBaB", + "ccC", + 16 + ], + [ + "AaCbcCb", + "ccAAaB", + 12 + ], + [ + "AaCc", + "a", + 6 + ], + [ + "AaCcABAa", + "B", + 14 + ], + [ + "AaCcAbC", + "Bb", + 12 + ], + [ + "AaCcBBcc", + "cBb", + 11 + ], + [ + "AaCcaCBaA", + "ABca", + 12 + ], + [ + "AaCcab", + "bBcB", + 9 + ], + [ + "AaCcacA", + "BBBAcbC", + 13 + ], + [ + "AaCcbBbCa", + "BBBAaabCb", + 14 + ], + [ + "AaCcc", + "abcBAb", + 10 + ], + [ + "AaCccBBCb", + "cB", + 14 + ], + [ + "AaCccbC", + "baaaaAb", + 11 + ], + [ + "Aaa", + "BaAA", + 5 + ], + [ + "Aaa", + "CbabcBBB", + 14 + ], + [ + "Aaa", + "aAa", + 2 + ], + [ + "Aaa", + "aBB", + 5 + ], + [ + "Aaa", + "bAAbBaBcc", + 13 + ], + [ + "Aaa", + "ca", + 4 + ], + [ + "AaaA", + "aBabbB", + 9 + ], + [ + "AaaA", + "baCb", + 6 + ], + [ + "AaaAAC", + "a", + 10 + ], + [ + "AaaAAaC", + "b", + 14 + ], + [ + "AaaACAcbA", + "CBAcAC", + 12 + ], + [ + "AaaACa", + "BABcccC", + 11 + ], + [ + "AaaAbBAab", + "bacccCc", + 16 + ], + [ + "AaaAcBCB", + "Bbbb", + 14 + ], + [ + "AaaAcb", + "AcabAA", + 8 + ], + [ + "AaaB", + "aaCAC", + 6 + ], + [ + "AaaBABa", + "bBaC", + 11 + ], + [ + "AaaBCaCC", + "c", + 15 + ], + [ + "AaaBa", + "CBCBc", + 8 + ], + [ + "AaaC", + "aaAc", + 3 + ], + [ + "AaaC", + "b", + 8 + ], + [ + "AaaC", + "caaBCAABc", + 12 + ], + [ + "AaaCB", + "ABcbBCCA", + 12 + ], + [ + "AaaCcbcc", + "B", + 15 + ], + [ + "Aaaa", + "abCBCBa", + 11 + ], + [ + "AaaaA", + "CccAB", + 9 + ], + [ + "AaaaBcb", + "BCabBBBC", + 11 + ], + [ + "AaaaCCC", + "BBcaacaCB", + 11 + ], + [ + "AaaacbC", + "CcAcBACcb", + 13 + ], + [ + "AaabA", + "cB", + 9 + ], + [ + "AaabACBca", + "bAc", + 12 + ], + [ + "AaabCAC", + "bCaacCbB", + 10 + ], + [ + "Aaaba", + "BbccCaa", + 12 + ], + [ + "AaabaBba", + "aBaB", + 9 + ], + [ + "Aaababb", + "BcbBCcc", + 13 + ], + [ + "AaabcBb", + "abab", + 8 + ], + [ + "Aaac", + "BAbaab", + 6 + ], + [ + "AaacACBc", + "ACbbCaABA", + 12 + ], + [ + "AaaccCBcb", + "CBabaCACb", + 11 + ], + [ + "AaacccCc", + "c", + 14 + ], + [ + "Aab", + "BcBaaCBC", + 12 + ], + [ + "Aab", + "CBBaACcBA", + 15 + ], + [ + "Aab", + "a", + 4 + ], + [ + "AabA", + "acCbacA", + 9 + ], + [ + "AabAAcBBB", + "aa", + 15 + ], + [ + "AabAbBbcB", + "AcCcA", + 14 + ], + [ + "AabAccB", + "AcabBCb", + 8 + ], + [ + "AabBABc", + "AAabbCcCc", + 9 + ], + [ + "AabBCAaC", + "aBcCbc", + 10 + ], + [ + "AabBCC", + "A", + 10 + ], + [ + "AabBaBcBB", + "cbcc", + 14 + ], + [ + "AabBacAaa", + "aAc", + 13 + ], + [ + "AabBba", + "bcabb", + 8 + ], + [ + "AabBbc", + "CcAaA", + 12 + ], + [ + "AabBcBca", + "Ca", + 13 + ], + [ + "AabBcbc", + "ac", + 10 + ], + [ + "AabCbA", + "B", + 11 + ], + [ + "AabCbC", + "ccBbc", + 8 + ], + [ + "Aaba", + "BBaa", + 6 + ], + [ + "AabaACCC", + "aaBBcccCa", + 10 + ], + [ + "AabaCCccc", + "BaB", + 15 + ], + [ + "AabbA", + "AB", + 7 + ], + [ + "AabbABCBb", + "aBB", + 12 + ], + [ + "AabbB", + "AA", + 7 + ], + [ + "AabbB", + "bCCC", + 10 + ], + [ + "AabbbbbC", + "bBbBaB", + 10 + ], + [ + "AabbcCACc", + "AAa", + 14 + ], + [ + "Aabc", + "bBCbc", + 6 + ], + [ + "Aabc", + "bbA", + 6 + ], + [ + "AabcAAbCc", + "Aa", + 14 + ], + [ + "AabcBBb", + "bAbAcCBB", + 8 + ], + [ + "AabcBb", + "bb", + 8 + ], + [ + "AabcC", + "BbbBcbbC", + 10 + ], + [ + "AabcbCa", + "CB", + 12 + ], + [ + "Aac", + "Bccc", + 6 + ], + [ + "Aac", + "CBABCbaA", + 12 + ], + [ + "Aac", + "Cb", + 6 + ], + [ + "Aac", + "a", + 4 + ], + [ + "Aac", + "aBbCCaaa", + 13 + ], + [ + "Aac", + "baBAcA", + 8 + ], + [ + "Aac", + "c", + 4 + ], + [ + "Aac", + "caAABac", + 8 + ], + [ + "AacA", + "ACcBA", + 4 + ], + [ + "AacA", + "BaaAccBcA", + 11 + ], + [ + "AacAABbaa", + "a", + 16 + ], + [ + "AacABAB", + "CCc", + 12 + ], + [ + "AacAcbbC", + "cbCa", + 12 + ], + [ + "AacBBCc", + "BcBAA", + 10 + ], + [ + "AacBaA", + "AAa", + 7 + ], + [ + "AacBbaCBB", + "CcbC", + 12 + ], + [ + "AacBbcccc", + "CbACCaBab", + 18 + ], + [ + "AacC", + "BcBcAbb", + 12 + ], + [ + "AacCaBcaB", + "CAAb", + 13 + ], + [ + "AacCacC", + "CaABC", + 9 + ], + [ + "AacCcCcAC", + "CCBBabBA", + 16 + ], + [ + "AacCcc", + "Aab", + 8 + ], + [ + "AacaaCc", + "bAaA", + 10 + ], + [ + "AacacB", + "aaBBB", + 7 + ], + [ + "AacacBC", + "CBBcAcba", + 10 + ], + [ + "AacacBb", + "AAabbcaC", + 10 + ], + [ + "Aacb", + "c", + 6 + ], + [ + "AacbAAA", + "BbcBaCCCb", + 14 + ], + [ + "Aacbaa", + "aCBbbCaAc", + 12 + ], + [ + "Aacc", + "ACAA", + 6 + ], + [ + "Aacc", + "CBAcB", + 7 + ], + [ + "AaccAB", + "baAcAcbcc", + 11 + ], + [ + "AaccABc", + "bB", + 12 + ], + [ + "AaccAaAb", + "acb", + 10 + ], + [ + "AaccB", + "ac", + 6 + ], + [ + "AaccBcc", + "BC", + 11 + ], + [ + "AaccC", + "bAbacBAa", + 10 + ], + [ + "AaccaAc", + "Bc", + 12 + ], + [ + "AaccaBa", + "B", + 12 + ], + [ + "AaccaCcBb", + "bABCca", + 13 + ], + [ + "Aaccac", + "c", + 10 + ], + [ + "AacccAa", + "AC", + 11 + ], + [ + "AacccAcC", + "ab", + 14 + ], + [ + "AacccBBcC", + "Bb", + 15 + ], + [ + "Ab", + "A", + 2 + ], + [ + "Ab", + "AA", + 2 + ], + [ + "Ab", + "AaabCAAA", + 12 + ], + [ + "Ab", + "AbACAaCAA", + 14 + ], + [ + "Ab", + "AbCCAAACc", + 14 + ], + [ + "Ab", + "AbCbAa", + 8 + ], + [ + "Ab", + "Ac", + 2 + ], + [ + "Ab", + "AcaABbc", + 10 + ], + [ + "Ab", + "BAcCa", + 8 + ], + [ + "Ab", + "BBc", + 5 + ], + [ + "Ab", + "BbcAcCCaa", + 16 + ], + [ + "Ab", + "CABa", + 5 + ], + [ + "Ab", + "CAaB", + 5 + ], + [ + "Ab", + "CCBcAbbc", + 12 + ], + [ + "Ab", + "CaBc", + 6 + ], + [ + "Ab", + "CbBCAbaBc", + 14 + ], + [ + "Ab", + "aCAccA", + 10 + ], + [ + "Ab", + "aab", + 3 + ], + [ + "Ab", + "acaCBAa", + 12 + ], + [ + "Ab", + "bA", + 4 + ], + [ + "Ab", + "bCBc", + 7 + ], + [ + "Ab", + "c", + 4 + ], + [ + "Ab", + "cBBB", + 7 + ], + [ + "Ab", + "cC", + 4 + ], + [ + "Ab", + "cCAaBbbBC", + 14 + ], + [ + "Ab", + "cCaAcc", + 10 + ], + [ + "Ab", + "caA", + 5 + ], + [ + "Ab", + "caCacCcBC", + 16 + ], + [ + "Ab", + "cbcacAC", + 12 + ], + [ + "Ab", + "ccAbB", + 6 + ], + [ + "Ab", + "ccb", + 4 + ], + [ + "AbA", + "BCBAaC", + 9 + ], + [ + "AbA", + "BbBAaA", + 8 + ], + [ + "AbA", + "CcBa", + 6 + ], + [ + "AbA", + "aAC", + 5 + ], + [ + "AbA", + "b", + 4 + ], + [ + "AbA", + "caABB", + 7 + ], + [ + "AbA", + "ccc", + 6 + ], + [ + "AbAA", + "CBba", + 6 + ], + [ + "AbAAC", + "BAAC", + 3 + ], + [ + "AbAAC", + "bbab", + 7 + ], + [ + "AbAACaAb", + "C", + 14 + ], + [ + "AbAACbbBB", + "BCbaa", + 13 + ], + [ + "AbAAbC", + "caCaAAAbA", + 11 + ], + [ + "AbAAcbBa", + "BabBBCa", + 11 + ], + [ + "AbAB", + "Ab", + 4 + ], + [ + "AbAB", + "Bcb", + 6 + ], + [ + "AbAB", + "ac", + 7 + ], + [ + "AbABCa", + "cC", + 10 + ], + [ + "AbABa", + "BAaaCB", + 9 + ], + [ + "AbACABc", + "aBCACA", + 8 + ], + [ + "AbACBCA", + "aBB", + 10 + ], + [ + "AbACaa", + "AcAba", + 6 + ], + [ + "AbACbA", + "A", + 10 + ], + [ + "AbACbAA", + "aACA", + 7 + ], + [ + "AbACccccb", + "cCbbCBA", + 15 + ], + [ + "AbAaABB", + "BcaaA", + 9 + ], + [ + "AbAaAb", + "CB", + 11 + ], + [ + "AbAaC", + "AacbbACba", + 11 + ], + [ + "AbAaCAab", + "CabaacCaA", + 9 + ], + [ + "AbAaaa", + "AaC", + 8 + ], + [ + "AbAacaaac", + "abACABAc", + 8 + ], + [ + "AbAb", + "bbccBB", + 9 + ], + [ + "AbAbCba", + "BCbA", + 8 + ], + [ + "AbAbabac", + "bc", + 12 + ], + [ + "AbAbbBaab", + "bbabb", + 10 + ], + [ + "AbAc", + "BcbBCbC", + 11 + ], + [ + "AbAcACAa", + "cBcBBA", + 11 + ], + [ + "AbAcB", + "c", + 8 + ], + [ + "AbAcbCbca", + "AcBaaB", + 13 + ], + [ + "AbAccAbBc", + "aACcAACbA", + 11 + ], + [ + "AbAccBCa", + "BACCAaA", + 10 + ], + [ + "AbB", + "AABC", + 4 + ], + [ + "AbB", + "AbCbCCc", + 9 + ], + [ + "AbB", + "BcaAbAAAb", + 13 + ], + [ + "AbB", + "bBBA", + 5 + ], + [ + "AbB", + "cAaaaB", + 8 + ], + [ + "AbB", + "cbbABB", + 7 + ], + [ + "AbBAcCAC", + "CAAbcCC", + 9 + ], + [ + "AbBB", + "AAAAC", + 8 + ], + [ + "AbBBabc", + "Bcb", + 10 + ], + [ + "AbBBbCaA", + "AaCccAAA", + 11 + ], + [ + "AbBBcaAaa", + "bcbBbcCb", + 13 + ], + [ + "AbBCAacC", + "c", + 14 + ], + [ + "AbBCAcaa", + "aa", + 12 + ], + [ + "AbBCBbA", + "abbcBb", + 5 + ], + [ + "AbBaABC", + "AabAAbc", + 6 + ], + [ + "AbBaBB", + "AAaAca", + 9 + ], + [ + "AbBaCC", + "CAb", + 10 + ], + [ + "AbBaaAb", + "ACcBcca", + 11 + ], + [ + "AbBabBa", + "bccBAbb", + 10 + ], + [ + "AbBb", + "A", + 6 + ], + [ + "AbBb", + "BbaAB", + 7 + ], + [ + "AbBbA", + "babCBABbb", + 11 + ], + [ + "AbBbAABc", + "AbAa", + 9 + ], + [ + "AbBbCb", + "bcAACCcac", + 15 + ], + [ + "AbBbb", + "aCAC", + 9 + ], + [ + "AbBbbacbC", + "CcbccAb", + 14 + ], + [ + "AbBbcb", + "Ab", + 8 + ], + [ + "AbBbcbabC", + "Ba", + 14 + ], + [ + "AbBcBaaCc", + "BbcAB", + 13 + ], + [ + "AbBcaaCCA", + "aba", + 13 + ], + [ + "AbBcb", + "BAaAcb", + 6 + ], + [ + "AbBcc", + "AaccBc", + 6 + ], + [ + "AbBcccB", + "cB", + 10 + ], + [ + "AbC", + "BccBcC", + 9 + ], + [ + "AbC", + "C", + 4 + ], + [ + "AbCAA", + "CCcCcacBa", + 14 + ], + [ + "AbCABa", + "ACBC", + 6 + ], + [ + "AbCACa", + "BcaBacAA", + 12 + ], + [ + "AbCACcBbB", + "C", + 16 + ], + [ + "AbCAc", + "BbCbcBCAb", + 12 + ], + [ + "AbCB", + "Caa", + 8 + ], + [ + "AbCB", + "acbAc", + 7 + ], + [ + "AbCB", + "caaaba", + 10 + ], + [ + "AbCBbB", + "BacABACaB", + 13 + ], + [ + "AbCBbbC", + "cACb", + 10 + ], + [ + "AbCCcAbc", + "abB", + 12 + ], + [ + "AbCCca", + "C", + 10 + ], + [ + "AbCCcacba", + "aaAaabcb", + 13 + ], + [ + "AbCa", + "CcAaCAaA", + 10 + ], + [ + "AbCa", + "aBcccBBa", + 11 + ], + [ + "AbCaA", + "bBbAB", + 8 + ], + [ + "AbCaAAbab", + "BCbCcb", + 13 + ], + [ + "AbCaC", + "AbABC", + 4 + ], + [ + "AbCaabBCB", + "Cb", + 14 + ], + [ + "AbCabbc", + "BcCaB", + 9 + ], + [ + "AbCacAacb", + "aaAAAAC", + 12 + ], + [ + "AbCb", + "A", + 6 + ], + [ + "AbCb", + "BbaBcaCb", + 10 + ], + [ + "AbCbC", + "Cc", + 7 + ], + [ + "AbCbaB", + "aCac", + 7 + ], + [ + "AbCc", + "bAaCac", + 6 + ], + [ + "AbCcBBACC", + "cACC", + 10 + ], + [ + "AbCcbaBCA", + "cccCAbbCA", + 11 + ], + [ + "Aba", + "ACA", + 3 + ], + [ + "Aba", + "C", + 6 + ], + [ + "Aba", + "aB", + 4 + ], + [ + "Aba", + "bccccA", + 11 + ], + [ + "Aba", + "cabbcC", + 9 + ], + [ + "AbaAACBCb", + "CACabC", + 13 + ], + [ + "AbaAabca", + "CBCBCA", + 12 + ], + [ + "AbaAb", + "cb", + 8 + ], + [ + "AbaB", + "aCaB", + 3 + ], + [ + "AbaBAaCbC", + "cbbacCbA", + 10 + ], + [ + "AbaBAbaB", + "cbaC", + 12 + ], + [ + "AbaBBcbAA", + "bCaaC", + 14 + ], + [ + "AbaBCa", + "B", + 10 + ], + [ + "AbaBCbaB", + "acBcb", + 10 + ], + [ + "AbaBaca", + "acAAABBB", + 13 + ], + [ + "AbaBcCba", + "accBCABAB", + 12 + ], + [ + "AbaC", + "BAAb", + 7 + ], + [ + "AbaC", + "aA", + 6 + ], + [ + "AbaCb", + "B", + 9 + ], + [ + "AbaCbBc", + "ACBAaCAcA", + 11 + ], + [ + "Abaa", + "aAcBb", + 8 + ], + [ + "Abaa", + "cbbAaabCc", + 12 + ], + [ + "AbaaAbab", + "CCaaBc", + 11 + ], + [ + "AbaaAc", + "bAba", + 8 + ], + [ + "AbaaabCBb", + "aa", + 14 + ], + [ + "Abab", + "bbbBb", + 6 + ], + [ + "Abab", + "cab", + 4 + ], + [ + "AbabBBb", + "CaAAc", + 12 + ], + [ + "AbabCC", + "CACcAabA", + 12 + ], + [ + "AbabcCbb", + "AbcCcbB", + 7 + ], + [ + "AbacAa", + "bCAAabcCa", + 10 + ], + [ + "AbacB", + "CBaCBAcBa", + 11 + ], + [ + "AbacBCc", + "B", + 12 + ], + [ + "AbacBbBCC", + "bC", + 14 + ], + [ + "AbacaaCB", + "B", + 14 + ], + [ + "AbacaaaBC", + "AacAa", + 9 + ], + [ + "Abacb", + "AcccbAb", + 8 + ], + [ + "Abb", + "Aba", + 2 + ], + [ + "Abb", + "Ac", + 4 + ], + [ + "Abb", + "BCcba", + 8 + ], + [ + "AbbA", + "BCb", + 6 + ], + [ + "AbbABab", + "baacCBb", + 11 + ], + [ + "AbbACbab", + "ccAcA", + 12 + ], + [ + "AbbAcA", + "CabbA", + 7 + ], + [ + "AbbB", + "b", + 6 + ], + [ + "AbbBbCbAC", + "bCCaBA", + 13 + ], + [ + "AbbBbb", + "BBcAbaAbB", + 11 + ], + [ + "AbbBcaaBa", + "aAAAaCAba", + 13 + ], + [ + "AbbCACaB", + "CbBBAbcB", + 9 + ], + [ + "AbbCB", + "AAC", + 6 + ], + [ + "AbbCBbCA", + "aAa", + 14 + ], + [ + "AbbCCA", + "bBBcbaAcC", + 13 + ], + [ + "AbbCCaBCB", + "AabbCB", + 9 + ], + [ + "AbbCCcAAb", + "ABCbbBCC", + 13 + ], + [ + "AbbCaCCa", + "B", + 15 + ], + [ + "AbbCbBC", + "Cc", + 11 + ], + [ + "AbbCcA", + "BaaCcBac", + 11 + ], + [ + "AbbaBacBC", + "BaCaCBcC", + 10 + ], + [ + "Abbaa", + "aCbBbc", + 8 + ], + [ + "Abbb", + "bBab", + 5 + ], + [ + "Abbbba", + "BbbaA", + 6 + ], + [ + "AbbcBbA", + "cCbCcaC", + 11 + ], + [ + "Abc", + "CBAaABCCc", + 13 + ], + [ + "Abc", + "Cab", + 5 + ], + [ + "Abc", + "ba", + 4 + ], + [ + "Abc", + "cCBCa", + 8 + ], + [ + "AbcAAAa", + "CBcBBAabc", + 11 + ], + [ + "AbcABaa", + "cCcBCb", + 10 + ], + [ + "AbcAcA", + "B", + 11 + ], + [ + "AbcB", + "AbaCBBaA", + 9 + ], + [ + "AbcBAA", + "BAAb", + 8 + ], + [ + "AbcBBaBB", + "CCBACAA", + 13 + ], + [ + "AbcBCcAA", + "abbABCcCa", + 8 + ], + [ + "AbcCACAbB", + "aBcCb", + 10 + ], + [ + "AbcCAacab", + "a", + 16 + ], + [ + "AbcCa", + "cBAaab", + 9 + ], + [ + "AbcCbbc", + "ACccaBbAB", + 10 + ], + [ + "AbcaA", + "cac", + 6 + ], + [ + "AbcaBABac", + "aA", + 14 + ], + [ + "AbcaBbBcA", + "CBbA", + 11 + ], + [ + "AbcaCAAAB", + "ac", + 15 + ], + [ + "AbcacabA", + "ABbaAC", + 10 + ], + [ + "Abcb", + "AbCCcbb", + 6 + ], + [ + "AbcbA", + "b", + 8 + ], + [ + "AbcbABc", + "bCBCabbBb", + 12 + ], + [ + "AbcbB", + "A", + 8 + ], + [ + "AbcbbC", + "bABbBAa", + 10 + ], + [ + "Abcc", + "bAABaA", + 9 + ], + [ + "Abcc", + "cAABAAa", + 11 + ], + [ + "AbccB", + "cA", + 8 + ], + [ + "Abccc", + "bba", + 8 + ], + [ + "Ac", + "ACbAa", + 7 + ], + [ + "Ac", + "AbB", + 4 + ], + [ + "Ac", + "BCB", + 5 + ], + [ + "Ac", + "BCacCBaBb", + 15 + ], + [ + "Ac", + "BaaCB", + 8 + ], + [ + "Ac", + "BacBbABCa", + 15 + ], + [ + "Ac", + "Bacc", + 5 + ], + [ + "Ac", + "BbaBaACcC", + 14 + ], + [ + "Ac", + "BccaAa", + 10 + ], + [ + "Ac", + "CA", + 4 + ], + [ + "Ac", + "CABacA", + 8 + ], + [ + "Ac", + "CABbbCA", + 11 + ], + [ + "Ac", + "CAa", + 4 + ], + [ + "Ac", + "CBCaAcBaB", + 14 + ], + [ + "Ac", + "CCA", + 5 + ], + [ + "Ac", + "CCcbBBc", + 12 + ], + [ + "Ac", + "CbBBBBbBA", + 18 + ], + [ + "Ac", + "Cbba", + 8 + ], + [ + "Ac", + "aCaa", + 6 + ], + [ + "Ac", + "aCbca", + 7 + ], + [ + "Ac", + "aaBC", + 6 + ], + [ + "Ac", + "aaCAa", + 8 + ], + [ + "Ac", + "aaaA", + 7 + ], + [ + "Ac", + "aabca", + 7 + ], + [ + "Ac", + "abcAAaB", + 11 + ], + [ + "Ac", + "acaBBbaAC", + 15 + ], + [ + "Ac", + "bAaa", + 6 + ], + [ + "Ac", + "bCCCCC", + 11 + ], + [ + "Ac", + "baAcB", + 6 + ], + [ + "Ac", + "bc", + 2 + ], + [ + "Ac", + "cB", + 4 + ], + [ + "Ac", + "cBaaaAAAb", + 16 + ], + [ + "Ac", + "cC", + 3 + ], + [ + "Ac", + "cCAcbCA", + 10 + ], + [ + "Ac", + "cCcCAAA", + 12 + ], + [ + "Ac", + "cbAAcc", + 8 + ], + [ + "AcA", + "ABAACCbc", + 12 + ], + [ + "AcA", + "BBBb", + 8 + ], + [ + "AcA", + "CcabCab", + 11 + ], + [ + "AcA", + "acA", + 1 + ], + [ + "AcA", + "bAbCc", + 7 + ], + [ + "AcA", + "bccBB", + 8 + ], + [ + "AcA", + "cCCA", + 5 + ], + [ + "AcAAAb", + "Acba", + 7 + ], + [ + "AcAABAc", + "bCaa", + 11 + ], + [ + "AcAABBc", + "c", + 12 + ], + [ + "AcAACA", + "cCb", + 8 + ], + [ + "AcAACBb", + "AbaA", + 9 + ], + [ + "AcAAbb", + "abBbA", + 9 + ], + [ + "AcAAcBaB", + "caB", + 10 + ], + [ + "AcABCCba", + "Ca", + 12 + ], + [ + "AcABa", + "aAbBBCA", + 9 + ], + [ + "AcAC", + "c", + 6 + ], + [ + "AcACB", + "aBBCbBabC", + 13 + ], + [ + "AcACCBA", + "c", + 12 + ], + [ + "AcACCaACA", + "aCAAAcABC", + 12 + ], + [ + "AcACaA", + "Ac", + 8 + ], + [ + "AcACcC", + "bABBAcC", + 8 + ], + [ + "AcACccA", + "CaacccB", + 8 + ], + [ + "AcAa", + "b", + 8 + ], + [ + "AcAaaCBA", + "abB", + 12 + ], + [ + "AcAac", + "BBCCC", + 9 + ], + [ + "AcAb", + "cCBBcBCAc", + 14 + ], + [ + "AcAbA", + "cCbbBcb", + 11 + ], + [ + "AcAbBabb", + "BBCBa", + 12 + ], + [ + "AcAbBcABC", + "baCcCcb", + 15 + ], + [ + "AcAbCB", + "ccCCaC", + 10 + ], + [ + "AcAba", + "CcBcBcC", + 11 + ], + [ + "AcAbb", + "bAAbc", + 6 + ], + [ + "AcAcB", + "aAcBAbC", + 8 + ], + [ + "AcAcCB", + "bc", + 10 + ], + [ + "AcAcCCCbb", + "BAaBC", + 14 + ], + [ + "AcAcbacA", + "cb", + 12 + ], + [ + "AcB", + "AbCbCa", + 8 + ], + [ + "AcB", + "CCABca", + 8 + ], + [ + "AcB", + "aBA", + 5 + ], + [ + "AcB", + "b", + 5 + ], + [ + "AcB", + "bCB", + 3 + ], + [ + "AcB", + "cBBaB", + 8 + ], + [ + "AcB", + "caBcC", + 7 + ], + [ + "AcB", + "caCCCaA", + 12 + ], + [ + "AcBAAa", + "ac", + 9 + ], + [ + "AcBAbbAA", + "ACCB", + 12 + ], + [ + "AcBB", + "AAAccBcA", + 10 + ], + [ + "AcBB", + "BaccCCACc", + 15 + ], + [ + "AcBB", + "bBCA", + 8 + ], + [ + "AcBB", + "cCAaaBaBb", + 12 + ], + [ + "AcBBAC", + "AaCA", + 8 + ], + [ + "AcBBACA", + "aAA", + 9 + ], + [ + "AcBBACCaC", + "abBcCAC", + 8 + ], + [ + "AcBBaB", + "aC", + 10 + ], + [ + "AcBBbbaBc", + "CC", + 16 + ], + [ + "AcBBbcb", + "ABBAAc", + 8 + ], + [ + "AcBBcabc", + "a", + 14 + ], + [ + "AcBC", + "ACabcCbBB", + 12 + ], + [ + "AcBC", + "AacAcBCcA", + 10 + ], + [ + "AcBC", + "bCbcAbbA", + 13 + ], + [ + "AcBCAcb", + "AB", + 10 + ], + [ + "AcBCCaAbc", + "ca", + 14 + ], + [ + "AcBCCb", + "aCcCAccc", + 11 + ], + [ + "AcBCaccAA", + "cBAcc", + 9 + ], + [ + "AcBCb", + "aBbaBac", + 11 + ], + [ + "AcBCcbCb", + "AAABCa", + 11 + ], + [ + "AcBCcbbaB", + "bBbC", + 14 + ], + [ + "AcBa", + "BBbCBAA", + 10 + ], + [ + "AcBaCCbCa", + "bbBBb", + 14 + ], + [ + "AcBaCCc", + "aaCcca", + 8 + ], + [ + "AcBaacCb", + "BBbbCbcC", + 13 + ], + [ + "AcBbAb", + "BabcbBbc", + 11 + ], + [ + "AcBbAc", + "cbAbC", + 7 + ], + [ + "AcBbaac", + "bA", + 11 + ], + [ + "AcBbbbB", + "ACaa", + 11 + ], + [ + "AcBc", + "abAcbb", + 7 + ], + [ + "AcBcAcA", + "aaCBAaAAa", + 11 + ], + [ + "AcBcBBB", + "a", + 13 + ], + [ + "AcBcCba", + "BCb", + 8 + ], + [ + "AcBca", + "Ab", + 7 + ], + [ + "AcBcbbA", + "ABb", + 8 + ], + [ + "AcBcbbA", + "BB", + 11 + ], + [ + "AcBcbcA", + "B", + 12 + ], + [ + "AcBccbbbC", + "CbBAAbB", + 13 + ], + [ + "AcBcccC", + "b", + 13 + ], + [ + "AcC", + "ACAbc", + 6 + ], + [ + "AcC", + "bBBA", + 8 + ], + [ + "AcC", + "bbCBACbcA", + 14 + ], + [ + "AcC", + "c", + 4 + ], + [ + "AcC", + "cBBa", + 8 + ], + [ + "AcCACC", + "bbAcCCcc", + 8 + ], + [ + "AcCACaCA", + "CBcCCB", + 11 + ], + [ + "AcCAb", + "bCBAACBC", + 12 + ], + [ + "AcCAbA", + "Bac", + 11 + ], + [ + "AcCAbcaBb", + "Cb", + 14 + ], + [ + "AcCAcCCCA", + "AcCC", + 10 + ], + [ + "AcCBA", + "a", + 9 + ], + [ + "AcCBBaBb", + "AC", + 12 + ], + [ + "AcCBba", + "CaaBCAa", + 10 + ], + [ + "AcCCAA", + "BcA", + 8 + ], + [ + "AcCCBcc", + "bbBACCa", + 13 + ], + [ + "AcCCCbb", + "AcaAc", + 9 + ], + [ + "AcCCb", + "bb", + 8 + ], + [ + "AcCCba", + "BC", + 10 + ], + [ + "AcCCcBACB", + "cb", + 15 + ], + [ + "AcCCccCB", + "baaCaAaB", + 12 + ], + [ + "AcCa", + "AAaCcC", + 8 + ], + [ + "AcCaAcccA", + "AaaaBaCBB", + 13 + ], + [ + "AcCaBCACC", + "a", + 16 + ], + [ + "AcCaC", + "CAcC", + 6 + ], + [ + "AcCaa", + "Ccab", + 6 + ], + [ + "AcCabb", + "BbCBa", + 9 + ], + [ + "AcCb", + "A", + 6 + ], + [ + "AcCbA", + "BaCcaC", + 9 + ], + [ + "AcCbA", + "aA", + 7 + ], + [ + "AcCbBb", + "CCAcb", + 7 + ], + [ + "AcCba", + "cBBbCbCc", + 12 + ], + [ + "AcCbac", + "cCBa", + 5 + ], + [ + "AcCbbbc", + "BbBbABCBc", + 12 + ], + [ + "AcCbc", + "ABBaaAc", + 10 + ], + [ + "AcCc", + "BBBAA", + 10 + ], + [ + "AcCc", + "CABBBCaCb", + 13 + ], + [ + "AcCc", + "acCbACCcc", + 11 + ], + [ + "AcCcA", + "AbCbabBc", + 11 + ], + [ + "AcCcABb", + "cCBaAc", + 9 + ], + [ + "AcCcBB", + "AAaCAaA", + 10 + ], + [ + "AcCcabBCB", + "BcA", + 15 + ], + [ + "AcCcb", + "bC", + 8 + ], + [ + "AcCccABB", + "bbCbbCB", + 12 + ], + [ + "AcCccbBBb", + "ACABAa", + 12 + ], + [ + "Aca", + "BaAA", + 6 + ], + [ + "Aca", + "CCBCCB", + 11 + ], + [ + "Aca", + "cA", + 3 + ], + [ + "AcaAAA", + "CcbbaB", + 9 + ], + [ + "AcaABAaCb", + "CcCACC", + 12 + ], + [ + "AcaABCa", + "bacAcA", + 9 + ], + [ + "AcaAcBC", + "ccbAaa", + 10 + ], + [ + "AcaBACCb", + "ACacBaBAb", + 8 + ], + [ + "AcaBAabCb", + "ACACAbaCB", + 9 + ], + [ + "AcaBC", + "ABacC", + 4 + ], + [ + "AcaBCa", + "AbBC", + 6 + ], + [ + "AcaBacc", + "CBB", + 11 + ], + [ + "AcaBcba", + "AbAbCBcC", + 10 + ], + [ + "AcaC", + "Aca", + 2 + ], + [ + "AcaCB", + "C", + 8 + ], + [ + "AcaCBB", + "cbacccC", + 11 + ], + [ + "AcaCBb", + "CCcaBC", + 8 + ], + [ + "AcaCa", + "bCA", + 7 + ], + [ + "AcaCaC", + "BB", + 12 + ], + [ + "AcaCbcC", + "aBBCccaC", + 9 + ], + [ + "AcaCc", + "CaaCBBb", + 10 + ], + [ + "AcaCc", + "aBaCb", + 5 + ], + [ + "AcaCcAc", + "acA", + 8 + ], + [ + "Acaa", + "BACcCA", + 7 + ], + [ + "AcaaA", + "bacbCca", + 10 + ], + [ + "Acaaa", + "ACccca", + 6 + ], + [ + "AcaaaaaBA", + "b", + 17 + ], + [ + "AcaaabbAC", + "AACbc", + 12 + ], + [ + "AcaabBaAc", + "aCAbBBCaA", + 10 + ], + [ + "AcaacaAAB", + "CA", + 15 + ], + [ + "AcaacbaC", + "A", + 14 + ], + [ + "Acab", + "AB", + 5 + ], + [ + "AcabA", + "BCcca", + 8 + ], + [ + "AcabBAcB", + "B", + 14 + ], + [ + "AcabCaab", + "cCCaBB", + 9 + ], + [ + "AcabcC", + "AC", + 8 + ], + [ + "Acabca", + "cCCC", + 9 + ], + [ + "AcacaAbbb", + "abB", + 13 + ], + [ + "AcacaBC", + "bbaCB", + 9 + ], + [ + "AcacaCCCc", + "aBbbcACA", + 14 + ], + [ + "AcaccB", + "aaBc", + 7 + ], + [ + "Acb", + "BcbA", + 4 + ], + [ + "Acb", + "BccCaB", + 9 + ], + [ + "Acb", + "aC", + 4 + ], + [ + "Acb", + "bAccAa", + 8 + ], + [ + "Acb", + "ccAcbaB", + 8 + ], + [ + "AcbA", + "cA", + 4 + ], + [ + "AcbAAcaA", + "Cba", + 11 + ], + [ + "AcbAB", + "cbBbAa", + 8 + ], + [ + "AcbACBAaA", + "cc", + 15 + ], + [ + "AcbB", + "C", + 7 + ], + [ + "AcbBa", + "aAABbACcB", + 13 + ], + [ + "AcbBaCb", + "bCcacBbA", + 12 + ], + [ + "AcbBaba", + "CbbCBaB", + 9 + ], + [ + "AcbBb", + "abBbA", + 5 + ], + [ + "AcbC", + "bbCaA", + 8 + ], + [ + "AcbCAC", + "CcACABBb", + 10 + ], + [ + "AcbCAc", + "aaBCaAbAa", + 12 + ], + [ + "AcbCBcc", + "aA", + 13 + ], + [ + "AcbCaCb", + "ccAABC", + 10 + ], + [ + "AcbCcBCa", + "bbbcAcB", + 11 + ], + [ + "AcbCcbCa", + "CcaABBcCa", + 11 + ], + [ + "Acba", + "aACbbBcc", + 11 + ], + [ + "AcbaCAA", + "bAaBbaca", + 10 + ], + [ + "Acbab", + "acBc", + 6 + ], + [ + "AcbbAcCa", + "cCb", + 12 + ], + [ + "AcbbC", + "B", + 9 + ], + [ + "Acbbb", + "cCbCAACA", + 13 + ], + [ + "AcbbcAB", + "cca", + 9 + ], + [ + "Acbc", + "AbCaCB", + 8 + ], + [ + "Acbc", + "Bac", + 6 + ], + [ + "AcbcBB", + "ABBBB", + 5 + ], + [ + "AcbcBcA", + "AaaBaba", + 11 + ], + [ + "AcbcCbcbA", + "ac", + 15 + ], + [ + "Acc", + "BbBCABBb", + 14 + ], + [ + "Acc", + "aAbBbBca", + 12 + ], + [ + "Acc", + "aa", + 5 + ], + [ + "Acc", + "aaBcC", + 6 + ], + [ + "Acc", + "bCbAaCab", + 13 + ], + [ + "AccA", + "BCBA", + 5 + ], + [ + "AccA", + "aC", + 6 + ], + [ + "AccAB", + "Bcb", + 7 + ], + [ + "AccABcbBC", + "AAcBcAcc", + 9 + ], + [ + "AccACBbA", + "c", + 14 + ], + [ + "AccAbcC", + "cbbB", + 10 + ], + [ + "AccBbab", + "bcAaaaA", + 10 + ], + [ + "AccC", + "BBbca", + 8 + ], + [ + "AccCBBACa", + "b", + 17 + ], + [ + "AccCCCcaa", + "aabC", + 15 + ], + [ + "AccCcAA", + "CCbAaABCA", + 13 + ], + [ + "Acca", + "C", + 7 + ], + [ + "Acca", + "aB", + 7 + ], + [ + "AccaCABA", + "CBBBc", + 13 + ], + [ + "AccaaAbbC", + "BaAB", + 13 + ], + [ + "Accb", + "baBaaCaCa", + 15 + ], + [ + "Accbbbb", + "bA", + 12 + ], + [ + "Accbcc", + "aaAAcb", + 9 + ], + [ + "Accc", + "ABbAB", + 8 + ], + [ + "AcccAC", + "BAAbCacBb", + 13 + ], + [ + "AcccAbbB", + "BaBCa", + 14 + ], + [ + "AcccBAAbC", + "CCbCb", + 13 + ], + [ + "AcccCACac", + "BAbccaC", + 11 + ], + [ + "AcccCabab", + "bBAAaBaA", + 13 + ], + [ + "AcccCb", + "BACacbcC", + 9 + ], + [ + "AcccaCb", + "CBBCcaCB", + 8 + ], + [ + "Acccac", + "acCaAcaCb", + 9 + ], + [ + "B", + "A", + 2 + ], + [ + "B", + "AAABB", + 8 + ], + [ + "B", + "AAAcc", + 10 + ], + [ + "B", + "AABBcC", + 10 + ], + [ + "B", + "AABCBb", + 10 + ], + [ + "B", + "AAC", + 6 + ], + [ + "B", + "AACA", + 8 + ], + [ + "B", + "AACaaaa", + 14 + ], + [ + "B", + "AAcaBa", + 10 + ], + [ + "B", + "AAcacbab", + 15 + ], + [ + "B", + "ABBc", + 6 + ], + [ + "B", + "ABCBcBCB", + 14 + ], + [ + "B", + "ABaAba", + 10 + ], + [ + "B", + "ABaB", + 6 + ], + [ + "B", + "ABaBba", + 10 + ], + [ + "B", + "ABaaCcBa", + 14 + ], + [ + "B", + "ABc", + 4 + ], + [ + "B", + "ACB", + 4 + ], + [ + "B", + "ACCCCCBc", + 14 + ], + [ + "B", + "ACbbC", + 9 + ], + [ + "B", + "ACbbCA", + 11 + ], + [ + "B", + "AaA", + 6 + ], + [ + "B", + "AaACbbaaB", + 16 + ], + [ + "B", + "AaAaCCbaa", + 17 + ], + [ + "B", + "AaBaBcba", + 14 + ], + [ + "B", + "AabcAaa", + 13 + ], + [ + "B", + "AacCacAb", + 15 + ], + [ + "B", + "AaccbBacB", + 16 + ], + [ + "B", + "Ab", + 3 + ], + [ + "B", + "AbBc", + 6 + ], + [ + "B", + "AbaBCcaBa", + 16 + ], + [ + "B", + "Abc", + 5 + ], + [ + "B", + "AcA", + 6 + ], + [ + "B", + "AcBA", + 6 + ], + [ + "B", + "AcBaBbCc", + 14 + ], + [ + "B", + "AcCc", + 8 + ], + [ + "B", + "AcaC", + 8 + ], + [ + "B", + "AccBacc", + 12 + ], + [ + "B", + "B", + 0 + ], + [ + "B", + "BAA", + 4 + ], + [ + "B", + "BBAbCc", + 10 + ], + [ + "B", + "BBAccA", + 10 + ], + [ + "B", + "BBBCb", + 8 + ], + [ + "B", + "BBa", + 4 + ], + [ + "B", + "BBaAcacab", + 16 + ], + [ + "B", + "BBc", + 4 + ], + [ + "B", + "BC", + 2 + ], + [ + "B", + "BCC", + 4 + ], + [ + "B", + "BCCbaBA", + 12 + ], + [ + "B", + "BCbCb", + 8 + ], + [ + "B", + "BCcC", + 6 + ], + [ + "B", + "BCcCccC", + 12 + ], + [ + "B", + "BCcb", + 6 + ], + [ + "B", + "BCcc", + 6 + ], + [ + "B", + "Ba", + 2 + ], + [ + "B", + "BaBCAaCAa", + 16 + ], + [ + "B", + "Baca", + 6 + ], + [ + "B", + "BacbcaCaC", + 16 + ], + [ + "B", + "BbcCCbAbb", + 16 + ], + [ + "B", + "BcACbAAC", + 14 + ], + [ + "B", + "BcACbbbc", + 14 + ], + [ + "B", + "BcabCBbab", + 16 + ], + [ + "B", + "C", + 2 + ], + [ + "B", + "CAAb", + 7 + ], + [ + "B", + "CAAba", + 9 + ], + [ + "B", + "CACcA", + 10 + ], + [ + "B", + "CB", + 2 + ], + [ + "B", + "CBCcAcbb", + 14 + ], + [ + "B", + "CBc", + 4 + ], + [ + "B", + "CBcA", + 6 + ], + [ + "B", + "CBcCC", + 8 + ], + [ + "B", + "CCaaCaac", + 16 + ], + [ + "B", + "CCcBBCb", + 12 + ], + [ + "B", + "Ca", + 4 + ], + [ + "B", + "CaCC", + 8 + ], + [ + "B", + "Caa", + 6 + ], + [ + "B", + "Cab", + 5 + ], + [ + "B", + "Cacbc", + 9 + ], + [ + "B", + "Cb", + 3 + ], + [ + "B", + "Cbc", + 5 + ], + [ + "B", + "CbcaAaACC", + 17 + ], + [ + "B", + "CbccCbca", + 15 + ], + [ + "B", + "Cc", + 4 + ], + [ + "B", + "CcAacCAA", + 16 + ], + [ + "B", + "CcBb", + 6 + ], + [ + "B", + "CcbBb", + 8 + ], + [ + "B", + "Ccc", + 6 + ], + [ + "B", + "a", + 2 + ], + [ + "B", + "aAA", + 6 + ], + [ + "B", + "aAACAb", + 11 + ], + [ + "B", + "aABCB", + 8 + ], + [ + "B", + "aACaCCBbA", + 16 + ], + [ + "B", + "aB", + 2 + ], + [ + "B", + "aBBbc", + 8 + ], + [ + "B", + "aBabc", + 8 + ], + [ + "B", + "aBcbCA", + 10 + ], + [ + "B", + "aBccCCBC", + 14 + ], + [ + "B", + "aC", + 4 + ], + [ + "B", + "aCBBAAc", + 12 + ], + [ + "B", + "aCBcA", + 8 + ], + [ + "B", + "aCCaAabB", + 14 + ], + [ + "B", + "aCCcbbac", + 15 + ], + [ + "B", + "aCa", + 6 + ], + [ + "B", + "aCaBABACa", + 16 + ], + [ + "B", + "aCcbCA", + 11 + ], + [ + "B", + "aaBBac", + 10 + ], + [ + "B", + "aaBCC", + 8 + ], + [ + "B", + "aab", + 5 + ], + [ + "B", + "aabBcbBa", + 14 + ], + [ + "B", + "aacbAB", + 10 + ], + [ + "B", + "abA", + 5 + ], + [ + "B", + "abAAA", + 9 + ], + [ + "B", + "abBBCBBcb", + 16 + ], + [ + "B", + "abC", + 5 + ], + [ + "B", + "abCcacAC", + 15 + ], + [ + "B", + "ac", + 4 + ], + [ + "B", + "acAbAB", + 10 + ], + [ + "B", + "acBcBba", + 12 + ], + [ + "B", + "b", + 1 + ], + [ + "B", + "bA", + 3 + ], + [ + "B", + "bAAbcbb", + 13 + ], + [ + "B", + "bABAacc", + 12 + ], + [ + "B", + "bACA", + 7 + ], + [ + "B", + "bAaAbBbcb", + 16 + ], + [ + "B", + "bAc", + 5 + ], + [ + "B", + "bB", + 2 + ], + [ + "B", + "bC", + 3 + ], + [ + "B", + "bCAbccaCA", + 17 + ], + [ + "B", + "bCCA", + 7 + ], + [ + "B", + "bCabCB", + 10 + ], + [ + "B", + "bCabcCa", + 13 + ], + [ + "B", + "ba", + 3 + ], + [ + "B", + "baba", + 7 + ], + [ + "B", + "babaa", + 9 + ], + [ + "B", + "bb", + 3 + ], + [ + "B", + "bbc", + 5 + ], + [ + "B", + "bbcbCCCb", + 15 + ], + [ + "B", + "bc", + 3 + ], + [ + "B", + "bcCBCacb", + 14 + ], + [ + "B", + "bcaAcbbB", + 14 + ], + [ + "B", + "c", + 2 + ], + [ + "B", + "cABAAb", + 10 + ], + [ + "B", + "cAaaACc", + 14 + ], + [ + "B", + "cAcCA", + 10 + ], + [ + "B", + "cAccC", + 10 + ], + [ + "B", + "cB", + 2 + ], + [ + "B", + "cBBBa", + 8 + ], + [ + "B", + "cBaCCba", + 12 + ], + [ + "B", + "cBbbaAaBC", + 16 + ], + [ + "B", + "cBcCaA", + 10 + ], + [ + "B", + "cC", + 4 + ], + [ + "B", + "cCABB", + 8 + ], + [ + "B", + "cCBAacA", + 12 + ], + [ + "B", + "cCbBBAccB", + 16 + ], + [ + "B", + "cCbcaBaca", + 16 + ], + [ + "B", + "cCcBaC", + 10 + ], + [ + "B", + "cCcbcaCcc", + 17 + ], + [ + "B", + "cabBca", + 10 + ], + [ + "B", + "cabccaAAB", + 16 + ], + [ + "B", + "cb", + 3 + ], + [ + "B", + "cbAACcCCb", + 17 + ], + [ + "B", + "cbAC", + 7 + ], + [ + "B", + "cbBbCC", + 10 + ], + [ + "B", + "cbC", + 5 + ], + [ + "B", + "cbCaba", + 11 + ], + [ + "B", + "cbCbBBaa", + 14 + ], + [ + "B", + "cbaaAAA", + 13 + ], + [ + "B", + "cbaaCAb", + 13 + ], + [ + "B", + "cbbCaccA", + 15 + ], + [ + "B", + "cbbb", + 7 + ], + [ + "B", + "cbcCa", + 9 + ], + [ + "B", + "ccABaB", + 10 + ], + [ + "B", + "ccAc", + 8 + ], + [ + "B", + "ccCbCbc", + 13 + ], + [ + "B", + "ccabaC", + 11 + ], + [ + "B", + "ccb", + 5 + ], + [ + "BA", + "A", + 2 + ], + [ + "BA", + "ABaabAbAc", + 14 + ], + [ + "BA", + "B", + 2 + ], + [ + "BA", + "BBABbCAaB", + 14 + ], + [ + "BA", + "BBcaC", + 7 + ], + [ + "BA", + "BBcacAbcb", + 14 + ], + [ + "BA", + "BCbCbbcAB", + 14 + ], + [ + "BA", + "CACCAaac", + 14 + ], + [ + "BA", + "CAaaacb", + 12 + ], + [ + "BA", + "CBC", + 4 + ], + [ + "BA", + "aACbbcba", + 14 + ], + [ + "BA", + "ab", + 4 + ], + [ + "BA", + "abCAa", + 7 + ], + [ + "BA", + "b", + 3 + ], + [ + "BA", + "bABaAca", + 10 + ], + [ + "BA", + "baCCBbC", + 12 + ], + [ + "BA", + "bbBcB", + 8 + ], + [ + "BA", + "bbbCC", + 9 + ], + [ + "BA", + "bbbaBA", + 8 + ], + [ + "BA", + "bbbbCBb", + 12 + ], + [ + "BA", + "cBABaC", + 8 + ], + [ + "BA", + "cBBbbA", + 8 + ], + [ + "BA", + "cC", + 4 + ], + [ + "BA", + "ccB", + 6 + ], + [ + "BA", + "ccCa", + 7 + ], + [ + "BAA", + "A", + 4 + ], + [ + "BAA", + "abA", + 4 + ], + [ + "BAA", + "acCAc", + 8 + ], + [ + "BAA", + "bB", + 5 + ], + [ + "BAA", + "bbcACCCAB", + 13 + ], + [ + "BAA", + "bcBC", + 7 + ], + [ + "BAA", + "cBaCaBc", + 10 + ], + [ + "BAAA", + "B", + 6 + ], + [ + "BAAA", + "BBCacaC", + 10 + ], + [ + "BAAA", + "bBAc", + 5 + ], + [ + "BAAAAAA", + "CbcbAc", + 12 + ], + [ + "BAAAACb", + "cbcACabBc", + 13 + ], + [ + "BAAAC", + "cbCBcbCC", + 12 + ], + [ + "BAAAaCCAB", + "bcCB", + 12 + ], + [ + "BAAAabC", + "CCaaaAcc", + 11 + ], + [ + "BAAAbcBa", + "aCcAAAcc", + 12 + ], + [ + "BAABC", + "bccab", + 9 + ], + [ + "BAABaC", + "Cbb", + 11 + ], + [ + "BAABabAb", + "ACC", + 14 + ], + [ + "BAAC", + "bB", + 7 + ], + [ + "BAAC", + "ccaBab", + 10 + ], + [ + "BAAC", + "ccbC", + 6 + ], + [ + "BAACAA", + "a", + 11 + ], + [ + "BAACaC", + "Cac", + 7 + ], + [ + "BAAaA", + "a", + 8 + ], + [ + "BAAaACaC", + "bb", + 15 + ], + [ + "BAAaB", + "ccAcbA", + 9 + ], + [ + "BAAaa", + "b", + 9 + ], + [ + "BAAaa", + "cacCaBc", + 11 + ], + [ + "BAAaaac", + "c", + 12 + ], + [ + "BAAaabB", + "aaAAA", + 9 + ], + [ + "BAAaac", + "BCaCcCAB", + 12 + ], + [ + "BAAacA", + "ccBAcCAc", + 11 + ], + [ + "BAAb", + "AA", + 4 + ], + [ + "BAAbAC", + "BbAccCba", + 10 + ], + [ + "BAAbCbbC", + "CCCBBc", + 11 + ], + [ + "BAAbacbC", + "aBAabc", + 9 + ], + [ + "BAAbbACC", + "CCABb", + 11 + ], + [ + "BAAcCBa", + "ACcA", + 9 + ], + [ + "BAAcaBBCa", + "AccB", + 12 + ], + [ + "BAAcac", + "Bb", + 10 + ], + [ + "BAAcc", + "CACbabA", + 11 + ], + [ + "BAB", + "AcbBaaBa", + 11 + ], + [ + "BAB", + "BB", + 2 + ], + [ + "BAB", + "Caa", + 5 + ], + [ + "BAB", + "cc", + 6 + ], + [ + "BABA", + "abbccc", + 11 + ], + [ + "BABA", + "caCca", + 8 + ], + [ + "BABB", + "bBCCBcAcb", + 13 + ], + [ + "BABBAAc", + "caAaa", + 10 + ], + [ + "BABBbCA", + "bAca", + 9 + ], + [ + "BABBc", + "BCCcAcCC", + 11 + ], + [ + "BABCB", + "AB", + 6 + ], + [ + "BABCcBbA", + "CBb", + 10 + ], + [ + "BABa", + "abbbaccAa", + 14 + ], + [ + "BABabAB", + "b", + 12 + ], + [ + "BABacA", + "abcBA", + 8 + ], + [ + "BABb", + "cC", + 8 + ], + [ + "BABbC", + "BaA", + 7 + ], + [ + "BABbb", + "Ccc", + 10 + ], + [ + "BABc", + "aB", + 5 + ], + [ + "BABcACCaC", + "CbbBaCbaC", + 10 + ], + [ + "BABcBA", + "CA", + 9 + ], + [ + "BABcBCaBc", + "CBAaBCC", + 11 + ], + [ + "BABcBcBa", + "bCBACcc", + 11 + ], + [ + "BABcaBB", + "bAaabb", + 7 + ], + [ + "BABcb", + "CcCAaC", + 11 + ], + [ + "BABcbcaa", + "BbbCcAAab", + 11 + ], + [ + "BABccba", + "cCbbbA", + 10 + ], + [ + "BAC", + "BB", + 4 + ], + [ + "BAC", + "BBacAbC", + 8 + ], + [ + "BAC", + "BaacBaC", + 9 + ], + [ + "BAC", + "BbbBaB", + 9 + ], + [ + "BAC", + "CAAaa", + 8 + ], + [ + "BAC", + "CBBbBccbc", + 15 + ], + [ + "BAC", + "b", + 5 + ], + [ + "BAC", + "babAAcA", + 10 + ], + [ + "BACACcCcc", + "cbB", + 16 + ], + [ + "BACB", + "AaCABa", + 7 + ], + [ + "BACBAACba", + "BaA", + 13 + ], + [ + "BACBCAC", + "A", + 12 + ], + [ + "BACBaB", + "Bcbc", + 8 + ], + [ + "BACBbCbB", + "ACaAAaCb", + 12 + ], + [ + "BACC", + "ab", + 7 + ], + [ + "BACCBcbaa", + "ab", + 15 + ], + [ + "BACCCAaCA", + "bCCcBb", + 12 + ], + [ + "BACCbABA", + "AAAAcAB", + 10 + ], + [ + "BACCbAac", + "AcBCaacB", + 10 + ], + [ + "BACCc", + "BbAAcA", + 7 + ], + [ + "BACCc", + "aBbbBBCa", + 12 + ], + [ + "BACaC", + "CB", + 8 + ], + [ + "BACab", + "bCA", + 6 + ], + [ + "BACb", + "AcBC", + 6 + ], + [ + "BACbAbCbC", + "BbC", + 12 + ], + [ + "BACbbaaAc", + "ACabC", + 11 + ], + [ + "BACcBbcCb", + "AcbB", + 11 + ], + [ + "BACcbBbc", + "AC", + 12 + ], + [ + "BACccabb", + "bAcAAa", + 10 + ], + [ + "BACcccA", + "aacC", + 10 + ], + [ + "BAa", + "AC", + 4 + ], + [ + "BAa", + "AbCBcA", + 9 + ], + [ + "BAa", + "CabbAabb", + 11 + ], + [ + "BAa", + "cBaAa", + 4 + ], + [ + "BAaA", + "BCB", + 6 + ], + [ + "BAaABbB", + "ABabABcbC", + 9 + ], + [ + "BAaAbCc", + "acb", + 10 + ], + [ + "BAaAcCb", + "AbbC", + 10 + ], + [ + "BAaAcbB", + "Aa", + 10 + ], + [ + "BAaBBaAb", + "bBaBcaAAa", + 9 + ], + [ + "BAaBaB", + "A", + 10 + ], + [ + "BAaBbCc", + "cacBaAcaB", + 13 + ], + [ + "BAaBbabc", + "A", + 14 + ], + [ + "BAaBcCaaa", + "ab", + 15 + ], + [ + "BAaBcCb", + "aCAA", + 11 + ], + [ + "BAaCB", + "BBb", + 7 + ], + [ + "BAaCB", + "aABACA", + 7 + ], + [ + "BAaCaA", + "acB", + 9 + ], + [ + "BAaCabCCa", + "b", + 16 + ], + [ + "BAaCbAC", + "bA", + 10 + ], + [ + "BAaCbB", + "aCcbbAAA", + 13 + ], + [ + "BAaCcc", + "bc", + 9 + ], + [ + "BAaaACaA", + "Ccbcaa", + 12 + ], + [ + "BAaaCCb", + "bCBC", + 11 + ], + [ + "BAab", + "c", + 8 + ], + [ + "BAab", + "ccaba", + 6 + ], + [ + "BAabAbBB", + "ABaBaaBa", + 10 + ], + [ + "BAabCA", + "Cb", + 10 + ], + [ + "BAabCCA", + "CCbBcb", + 11 + ], + [ + "BAac", + "bBbcaca", + 8 + ], + [ + "BAacBb", + "cABAca", + 9 + ], + [ + "BAacbBbCb", + "bBAca", + 13 + ], + [ + "BAacbaBC", + "ABCbcaCAc", + 12 + ], + [ + "BAaccAba", + "BAbBbCA", + 11 + ], + [ + "BAb", + "Aa", + 4 + ], + [ + "BAb", + "AbaccbCbC", + 14 + ], + [ + "BAb", + "BaCa", + 5 + ], + [ + "BAb", + "CCaBA", + 8 + ], + [ + "BAb", + "CbCb", + 5 + ], + [ + "BAb", + "caAAC", + 8 + ], + [ + "BAb", + "ccCAAAABC", + 15 + ], + [ + "BAbABaBbC", + "CAAcAb", + 11 + ], + [ + "BAbACcA", + "aBaaCcc", + 8 + ], + [ + "BAbAa", + "ABbCbabac", + 11 + ], + [ + "BAbAa", + "c", + 10 + ], + [ + "BAbAc", + "cBc", + 7 + ], + [ + "BAbAcABa", + "ac", + 13 + ], + [ + "BAbAcbB", + "aCAcBB", + 6 + ], + [ + "BAbBA", + "BcaCBcaBa", + 11 + ], + [ + "BAbBAB", + "ABBCCb", + 8 + ], + [ + "BAbBBaB", + "abaA", + 9 + ], + [ + "BAbBCc", + "aaAcAcAAC", + 14 + ], + [ + "BAbBc", + "ABcAAABb", + 10 + ], + [ + "BAbCCbBC", + "bc", + 13 + ], + [ + "BAbCbBacB", + "acBca", + 12 + ], + [ + "BAbCc", + "BBbcBAab", + 11 + ], + [ + "BAbCcB", + "CbacAaaa", + 14 + ], + [ + "BAbCcBB", + "ccaBBcACC", + 14 + ], + [ + "BAba", + "Bc", + 6 + ], + [ + "BAbaBCAB", + "bbCbBa", + 11 + ], + [ + "BAbaBbBc", + "baAC", + 11 + ], + [ + "BAbaCc", + "C", + 10 + ], + [ + "BAbabca", + "cBabaCb", + 8 + ], + [ + "BAbacCaa", + "CCa", + 11 + ], + [ + "BAbb", + "baBaBaB", + 9 + ], + [ + "BAbbBAA", + "ACbcccc", + 12 + ], + [ + "BAbc", + "B", + 6 + ], + [ + "BAbc", + "bABCB", + 5 + ], + [ + "BAbc", + "bcBAb", + 6 + ], + [ + "BAbcAcA", + "ccA", + 8 + ], + [ + "BAbcaBab", + "CaACACbcB", + 13 + ], + [ + "BAbccAcB", + "BA", + 12 + ], + [ + "BAbccaBA", + "CCCcaa", + 10 + ], + [ + "BAc", + "AAAccAa", + 10 + ], + [ + "BAc", + "Bbc", + 2 + ], + [ + "BAc", + "ba", + 4 + ], + [ + "BAcA", + "Ac", + 4 + ], + [ + "BAcAA", + "acbCAA", + 7 + ], + [ + "BAcAACc", + "accA", + 9 + ], + [ + "BAcAAb", + "AbC", + 10 + ], + [ + "BAcAB", + "aAacCcbac", + 13 + ], + [ + "BAcACCb", + "cccBC", + 10 + ], + [ + "BAcACcBA", + "BCAbccA", + 7 + ], + [ + "BAcAcC", + "aAcBb", + 8 + ], + [ + "BAcBa", + "CCAbBCc", + 10 + ], + [ + "BAcBcba", + "aaa", + 11 + ], + [ + "BAcCBCbaA", + "bCb", + 13 + ], + [ + "BAcCC", + "ACCaC", + 5 + ], + [ + "BAcCCBAbA", + "b", + 16 + ], + [ + "BAcCaB", + "cCBBCaa", + 10 + ], + [ + "BAcCbC", + "CAB", + 9 + ], + [ + "BAcCbaC", + "CCBBaCabB", + 14 + ], + [ + "BAcCbc", + "Cb", + 8 + ], + [ + "BAcCcAACa", + "aacaCaA", + 11 + ], + [ + "BAcaBBBc", + "a", + 14 + ], + [ + "BAcaBc", + "CAbaa", + 8 + ], + [ + "BAcaC", + "cAcaCA", + 4 + ], + [ + "BAcaab", + "ACbA", + 8 + ], + [ + "BAcab", + "BaCbca", + 7 + ], + [ + "BAcbA", + "AbA", + 4 + ], + [ + "BAcbA", + "bACBCbbCA", + 10 + ], + [ + "BAcbAcCB", + "ac", + 13 + ], + [ + "BAcbBCC", + "bBaba", + 11 + ], + [ + "BAcbCC", + "c", + 10 + ], + [ + "BAcbCc", + "B", + 10 + ], + [ + "BAcbabcB", + "aAa", + 12 + ], + [ + "BAcbbba", + "Cb", + 11 + ], + [ + "BAcbcABbA", + "baABcBCa", + 10 + ], + [ + "BAccAAA", + "AaaC", + 10 + ], + [ + "BAccAAca", + "BBCbbCcab", + 11 + ], + [ + "BAccAbCB", + "Cba", + 13 + ], + [ + "BAccCAb", + "cCBcCcac", + 11 + ], + [ + "BAccCAbC", + "BCabCBA", + 11 + ], + [ + "BAccCCcA", + "CbbBaCB", + 14 + ], + [ + "BAccCcCB", + "bcCAB", + 9 + ], + [ + "BAcca", + "cBcCBBcbC", + 13 + ], + [ + "BAccaAaC", + "cbBcAaA", + 10 + ], + [ + "BAcccCbb", + "Bb", + 12 + ], + [ + "BB", + "A", + 4 + ], + [ + "BB", + "AACBAacBB", + 14 + ], + [ + "BB", + "ABaA", + 6 + ], + [ + "BB", + "ACbbCcc", + 12 + ], + [ + "BB", + "AbAABC", + 9 + ], + [ + "BB", + "AbbbBBa", + 10 + ], + [ + "BB", + "BC", + 2 + ], + [ + "BB", + "Ba", + 2 + ], + [ + "BB", + "BbcAaACB", + 12 + ], + [ + "BB", + "CAcaACbBb", + 15 + ], + [ + "BB", + "CBabcc", + 9 + ], + [ + "BB", + "CaCBb", + 7 + ], + [ + "BB", + "CaaAAaAAc", + 18 + ], + [ + "BB", + "Cab", + 5 + ], + [ + "BB", + "Cb", + 3 + ], + [ + "BB", + "CbAAC", + 9 + ], + [ + "BB", + "CbcbCcBc", + 13 + ], + [ + "BB", + "Ccccc", + 10 + ], + [ + "BB", + "a", + 4 + ], + [ + "BB", + "aAAbcc", + 11 + ], + [ + "BB", + "aACBABa", + 10 + ], + [ + "BB", + "aACbBCaac", + 15 + ], + [ + "BB", + "aAcCCb", + 11 + ], + [ + "BB", + "aCACcBC", + 12 + ], + [ + "BB", + "aCa", + 6 + ], + [ + "BB", + "aa", + 4 + ], + [ + "BB", + "bAABCCabC", + 15 + ], + [ + "BB", + "bABBCb", + 8 + ], + [ + "BB", + "bBacaAb", + 11 + ], + [ + "BB", + "bc", + 3 + ], + [ + "BB", + "cBBcCBaAa", + 14 + ], + [ + "BB", + "cCaAaBc", + 12 + ], + [ + "BB", + "cCb", + 5 + ], + [ + "BB", + "cCc", + 6 + ], + [ + "BB", + "caBcCA", + 10 + ], + [ + "BB", + "cac", + 6 + ], + [ + "BB", + "cbb", + 4 + ], + [ + "BB", + "ccaC", + 8 + ], + [ + "BBA", + "BB", + 2 + ], + [ + "BBA", + "BCCaaAb", + 10 + ], + [ + "BBA", + "Bb", + 3 + ], + [ + "BBA", + "Bba", + 2 + ], + [ + "BBA", + "CBbBab", + 7 + ], + [ + "BBA", + "aaBbAc", + 7 + ], + [ + "BBA", + "ab", + 5 + ], + [ + "BBA", + "bAAaBCbA", + 11 + ], + [ + "BBA", + "cbcBbC", + 9 + ], + [ + "BBAACb", + "BBaBbb", + 5 + ], + [ + "BBAAb", + "abaBbac", + 10 + ], + [ + "BBAAbbCc", + "a", + 15 + ], + [ + "BBAAcAb", + "cCBCaBCA", + 12 + ], + [ + "BBAAcbba", + "aCACbcCc", + 13 + ], + [ + "BBABA", + "bbccbbb", + 11 + ], + [ + "BBABACCCB", + "c", + 17 + ], + [ + "BBABBAca", + "aCCAAcCA", + 13 + ], + [ + "BBABBaBA", + "CaAaaa", + 11 + ], + [ + "BBABBaaBB", + "CccbccAc", + 16 + ], + [ + "BBABa", + "b", + 9 + ], + [ + "BBABcC", + "aCAA", + 10 + ], + [ + "BBABccb", + "C", + 13 + ], + [ + "BBAC", + "bBCAcBaC", + 9 + ], + [ + "BBACB", + "bAb", + 6 + ], + [ + "BBACC", + "CBccc", + 6 + ], + [ + "BBACC", + "aCBBBB", + 10 + ], + [ + "BBACaBC", + "C", + 12 + ], + [ + "BBACcCbBa", + "CCCcCC", + 12 + ], + [ + "BBAbA", + "AbCaCcB", + 12 + ], + [ + "BBAbCcacC", + "aBaacBcb", + 11 + ], + [ + "BBAba", + "BCbBcB", + 9 + ], + [ + "BBAbcB", + "BBc", + 6 + ], + [ + "BBAbcBBaA", + "bCcAB", + 13 + ], + [ + "BBAbcC", + "BacA", + 7 + ], + [ + "BBAcA", + "bBcaAacbb", + 11 + ], + [ + "BBAcC", + "cC", + 6 + ], + [ + "BBB", + "BaBbB", + 4 + ], + [ + "BBB", + "Bbcbc", + 6 + ], + [ + "BBB", + "CC", + 6 + ], + [ + "BBB", + "CCCAbc", + 11 + ], + [ + "BBB", + "CcbcBc", + 9 + ], + [ + "BBB", + "aaAbb", + 8 + ], + [ + "BBBAAA", + "AA", + 8 + ], + [ + "BBBAAAcB", + "BAcAcCCA", + 11 + ], + [ + "BBBACc", + "AaBCBb", + 10 + ], + [ + "BBBAbAaAB", + "aAcBABA", + 13 + ], + [ + "BBBAccBbC", + "ccbCbAb", + 14 + ], + [ + "BBBB", + "baABcbb", + 9 + ], + [ + "BBBBCCacA", + "bbCCc", + 10 + ], + [ + "BBBBcCA", + "bBAabcB", + 10 + ], + [ + "BBBBccCCC", + "C", + 16 + ], + [ + "BBBCABbb", + "cAAaAB", + 12 + ], + [ + "BBBCab", + "abBACbBc", + 10 + ], + [ + "BBBa", + "CCabbCcaB", + 14 + ], + [ + "BBBa", + "cAa", + 6 + ], + [ + "BBBaCA", + "AAbbaaACB", + 12 + ], + [ + "BBBaaBb", + "cBcaac", + 8 + ], + [ + "BBBab", + "bAa", + 7 + ], + [ + "BBBac", + "aaCcCBcAB", + 15 + ], + [ + "BBBb", + "B", + 6 + ], + [ + "BBBbCCb", + "BbBaCc", + 6 + ], + [ + "BBBba", + "BCaC", + 8 + ], + [ + "BBBbcBcCA", + "BbBB", + 11 + ], + [ + "BBBbccc", + "A", + 14 + ], + [ + "BBBc", + "cCAba", + 9 + ], + [ + "BBBcAB", + "AbCAAbc", + 10 + ], + [ + "BBBcBAa", + "AbBCCa", + 8 + ], + [ + "BBBcBabbB", + "aCC", + 16 + ], + [ + "BBBcbBA", + "AbACCCbCb", + 14 + ], + [ + "BBBcc", + "CCbbabCb", + 12 + ], + [ + "BBBccBaaB", + "BcCB", + 11 + ], + [ + "BBC", + "CaAAAaCbB", + 16 + ], + [ + "BBC", + "Cbcbcc", + 9 + ], + [ + "BBC", + "abBBacA", + 9 + ], + [ + "BBC", + "b", + 5 + ], + [ + "BBC", + "bCBAA", + 7 + ], + [ + "BBC", + "bcCaAbb", + 11 + ], + [ + "BBC", + "cba", + 5 + ], + [ + "BBCA", + "BAcCC", + 6 + ], + [ + "BBCAbbbc", + "BAa", + 12 + ], + [ + "BBCAcb", + "Ca", + 9 + ], + [ + "BBCBb", + "aac", + 9 + ], + [ + "BBCBbc", + "CaaBB", + 9 + ], + [ + "BBCBcaBb", + "ccCcCbBC", + 11 + ], + [ + "BBCBcb", + "CBcCBcacC", + 10 + ], + [ + "BBCC", + "C", + 6 + ], + [ + "BBCCBC", + "aCbbA", + 9 + ], + [ + "BBCCBab", + "cBCaaC", + 8 + ], + [ + "BBCCCbaCB", + "AAA", + 17 + ], + [ + "BBCCaBbB", + "BaBAcCbC", + 11 + ], + [ + "BBCCccBCB", + "bCaaCA", + 13 + ], + [ + "BBCa", + "aB", + 6 + ], + [ + "BBCaa", + "AccACcAAC", + 14 + ], + [ + "BBCabCCBB", + "BcAcCaCC", + 12 + ], + [ + "BBCbB", + "BBb", + 4 + ], + [ + "BBCbB", + "CB", + 6 + ], + [ + "BBCbB", + "caABAb", + 10 + ], + [ + "BBCbc", + "BAAbcaaBc", + 11 + ], + [ + "BBCc", + "BabAb", + 7 + ], + [ + "BBCc", + "cbabab", + 10 + ], + [ + "BBCcbACcB", + "Ab", + 15 + ], + [ + "BBCccCAba", + "aCcCCBAb", + 9 + ], + [ + "BBa", + "AcBcBAb", + 9 + ], + [ + "BBa", + "Ccb", + 6 + ], + [ + "BBa", + "aCCcbCAc", + 14 + ], + [ + "BBa", + "bBaCBa", + 6 + ], + [ + "BBa", + "cbAcBBaA", + 10 + ], + [ + "BBaA", + "bAAaBAAAB", + 12 + ], + [ + "BBaAAccbb", + "CABB", + 14 + ], + [ + "BBaACBaB", + "cbcC", + 13 + ], + [ + "BBaAab", + "BCB", + 9 + ], + [ + "BBaAcAAcb", + "cbCBBCAcb", + 11 + ], + [ + "BBaAcB", + "ACbAcb", + 7 + ], + [ + "BBaBbcB", + "C", + 13 + ], + [ + "BBaCB", + "cC", + 8 + ], + [ + "BBaCCA", + "ABAcc", + 7 + ], + [ + "BBaCccb", + "Cbcbb", + 9 + ], + [ + "BBaa", + "ba", + 5 + ], + [ + "BBaaCCBA", + "AbCbC", + 12 + ], + [ + "BBaaCca", + "aaBBcbAB", + 13 + ], + [ + "BBaaa", + "B", + 8 + ], + [ + "BBaab", + "bbAcbB", + 7 + ], + [ + "BBaabcA", + "BACBAC", + 10 + ], + [ + "BBaacbcaB", + "Abacab", + 10 + ], + [ + "BBaacc", + "C", + 11 + ], + [ + "BBabBa", + "BbBBcAACB", + 13 + ], + [ + "BBabcBab", + "abB", + 10 + ], + [ + "BBabcbb", + "BbbCbA", + 6 + ], + [ + "BBac", + "cBAB", + 5 + ], + [ + "BBacAcaAa", + "Bba", + 13 + ], + [ + "BBacCaBBa", + "aa", + 14 + ], + [ + "BBacCc", + "bcaBA", + 9 + ], + [ + "BBacaABc", + "Cbbaac", + 10 + ], + [ + "BBacb", + "AbbaCBCb", + 9 + ], + [ + "BBacb", + "abCACCBBA", + 14 + ], + [ + "BBb", + "BAcaAaca", + 14 + ], + [ + "BBb", + "BBa", + 2 + ], + [ + "BBb", + "CAcBCAAc", + 14 + ], + [ + "BBb", + "aBACcCCC", + 14 + ], + [ + "BBb", + "acbCc", + 8 + ], + [ + "BBbA", + "ca", + 7 + ], + [ + "BBbAACb", + "ACCbb", + 10 + ], + [ + "BBbABAaAB", + "cAbaCba", + 13 + ], + [ + "BBbABbac", + "cAB", + 12 + ], + [ + "BBbAabbCA", + "A", + 16 + ], + [ + "BBbAbcB", + "AcAAcbABa", + 12 + ], + [ + "BBbAcaAB", + "cBB", + 12 + ], + [ + "BBbAcc", + "bBAb", + 7 + ], + [ + "BBbB", + "ccABABc", + 10 + ], + [ + "BBbBB", + "a", + 10 + ], + [ + "BBbBBbba", + "aACbb", + 12 + ], + [ + "BBbBBcacc", + "AcAa", + 15 + ], + [ + "BBbBCbBc", + "BbABC", + 9 + ], + [ + "BBbBaa", + "bbBbbbaAb", + 9 + ], + [ + "BBbCCCCbc", + "ccaAB", + 15 + ], + [ + "BBbCCcbAc", + "bABcac", + 11 + ], + [ + "BBbCbcb", + "Ab", + 12 + ], + [ + "BBba", + "a", + 6 + ], + [ + "BBbaBc", + "ac", + 8 + ], + [ + "BBbab", + "AcAB", + 8 + ], + [ + "BBbabb", + "CCbAa", + 9 + ], + [ + "BBbabbab", + "bCBBbaA", + 9 + ], + [ + "BBbb", + "BA", + 6 + ], + [ + "BBbbACc", + "A", + 12 + ], + [ + "BBbbCCBB", + "AaCcBAAA", + 15 + ], + [ + "BBbcABBbC", + "AaC", + 14 + ], + [ + "BBbcB", + "ACbA", + 8 + ], + [ + "BBbcCac", + "cbb", + 11 + ], + [ + "BBbccCCBB", + "BbaBcb", + 12 + ], + [ + "BBc", + "ABCbAA", + 9 + ], + [ + "BBc", + "BbbABAACA", + 13 + ], + [ + "BBc", + "BcccAbBaC", + 13 + ], + [ + "BBc", + "aBaCccA", + 10 + ], + [ + "BBc", + "aC", + 5 + ], + [ + "BBc", + "aCacBbCCa", + 14 + ], + [ + "BBcAAA", + "Acbc", + 10 + ], + [ + "BBcAAac", + "acCcAbc", + 9 + ], + [ + "BBcABAA", + "BbBaABaC", + 7 + ], + [ + "BBcB", + "AAacBC", + 8 + ], + [ + "BBcB", + "aAaabB", + 10 + ], + [ + "BBcB", + "acb", + 5 + ], + [ + "BBcB", + "bAcAAbac", + 12 + ], + [ + "BBcBACa", + "CBACA", + 6 + ], + [ + "BBcBCB", + "c", + 10 + ], + [ + "BBcBbCBA", + "cBaaAca", + 12 + ], + [ + "BBcBbcA", + "bBbca", + 6 + ], + [ + "BBcC", + "AcAcAcCc", + 12 + ], + [ + "BBcCBCac", + "ababc", + 12 + ], + [ + "BBcCC", + "ccB", + 7 + ], + [ + "BBcCCabAA", + "BCC", + 12 + ], + [ + "BBcCCcab", + "bCcc", + 10 + ], + [ + "BBcCa", + "BBAA", + 5 + ], + [ + "BBcCcb", + "BCb", + 6 + ], + [ + "BBca", + "b", + 7 + ], + [ + "BBcaA", + "AaCCAbCCC", + 15 + ], + [ + "BBcaA", + "b", + 9 + ], + [ + "BBcaACbB", + "AbCb", + 11 + ], + [ + "BBcaC", + "CCccCCCC", + 12 + ], + [ + "BBcaa", + "aBaa", + 4 + ], + [ + "BBcaa", + "bAAAC", + 8 + ], + [ + "BBcaa", + "ccCCcABA", + 12 + ], + [ + "BBcaaCBB", + "BbCcbC", + 10 + ], + [ + "BBcab", + "aaBc", + 8 + ], + [ + "BBcbA", + "BcBabbA", + 6 + ], + [ + "BBcbaA", + "caBbCcaa", + 9 + ], + [ + "BBcbbaB", + "ccCbbAccB", + 10 + ], + [ + "BBcbbabC", + "BB", + 12 + ], + [ + "BBcc", + "AcbAAB", + 11 + ], + [ + "BBcc", + "CCcBccBbC", + 12 + ], + [ + "BBccAb", + "aCACbAC", + 11 + ], + [ + "BBccB", + "BcB", + 4 + ], + [ + "BBccc", + "BBAbCAcbB", + 11 + ], + [ + "BBcccCAAB", + "ABABBAca", + 14 + ], + [ + "BC", + "A", + 4 + ], + [ + "BC", + "AAcba", + 9 + ], + [ + "BC", + "AC", + 2 + ], + [ + "BC", + "ACBACCA", + 10 + ], + [ + "BC", + "AaA", + 6 + ], + [ + "BC", + "AaCABABAb", + 16 + ], + [ + "BC", + "Ac", + 3 + ], + [ + "BC", + "AcCCcc", + 10 + ], + [ + "BC", + "B", + 2 + ], + [ + "BC", + "BAbC", + 4 + ], + [ + "BC", + "BC", + 0 + ], + [ + "BC", + "BCCCC", + 6 + ], + [ + "BC", + "BbAaaBAbb", + 16 + ], + [ + "BC", + "BbB", + 4 + ], + [ + "BC", + "BcB", + 3 + ], + [ + "BC", + "C", + 2 + ], + [ + "BC", + "CA", + 4 + ], + [ + "BC", + "CaaaCAcaC", + 16 + ], + [ + "BC", + "CbCC", + 5 + ], + [ + "BC", + "CcC", + 4 + ], + [ + "BC", + "CcCCCab", + 12 + ], + [ + "BC", + "CcaAbbbcb", + 16 + ], + [ + "BC", + "CccAb", + 9 + ], + [ + "BC", + "aAA", + 6 + ], + [ + "BC", + "aAbbcbac", + 14 + ], + [ + "BC", + "aCbAaAbBB", + 16 + ], + [ + "BC", + "abbba", + 9 + ], + [ + "BC", + "acAACAC", + 12 + ], + [ + "BC", + "acbCA", + 7 + ], + [ + "BC", + "acccbAAB", + 15 + ], + [ + "BC", + "bAABa", + 8 + ], + [ + "BC", + "bBBAcBbCC", + 14 + ], + [ + "BC", + "bC", + 1 + ], + [ + "BC", + "bCaCaCaa", + 13 + ], + [ + "BC", + "bCbaCa", + 9 + ], + [ + "BC", + "bCbaaaAAC", + 15 + ], + [ + "BC", + "babCAbca", + 13 + ], + [ + "BC", + "babbBBaB", + 14 + ], + [ + "BC", + "bbCA", + 5 + ], + [ + "BC", + "c", + 3 + ], + [ + "BC", + "cAAB", + 8 + ], + [ + "BC", + "cABCBCAB", + 12 + ], + [ + "BC", + "cBaACA", + 8 + ], + [ + "BC", + "cBbaAcB", + 11 + ], + [ + "BC", + "cCCBb", + 8 + ], + [ + "BC", + "cb", + 4 + ], + [ + "BC", + "cbBBB", + 8 + ], + [ + "BC", + "cba", + 5 + ], + [ + "BC", + "cbaB", + 7 + ], + [ + "BC", + "cbaCbBAC", + 12 + ], + [ + "BC", + "cbbCabA", + 11 + ], + [ + "BC", + "ccAACb", + 10 + ], + [ + "BC", + "ccccbb", + 11 + ], + [ + "BCA", + "A", + 4 + ], + [ + "BCA", + "AbcCbCaA", + 11 + ], + [ + "BCA", + "abccbBCC", + 12 + ], + [ + "BCAABABCB", + "abBbBaB", + 11 + ], + [ + "BCAABc", + "bBACcBa", + 9 + ], + [ + "BCAAbBc", + "AaABC", + 8 + ], + [ + "BCAAbbbc", + "A", + 14 + ], + [ + "BCAAcbb", + "CAaCAcBbC", + 9 + ], + [ + "BCAAccAa", + "Aaaa", + 10 + ], + [ + "BCABBA", + "AbBba", + 8 + ], + [ + "BCABBBAa", + "bCAbBA", + 6 + ], + [ + "BCABa", + "b", + 9 + ], + [ + "BCABcB", + "bcAAbCb", + 7 + ], + [ + "BCABcCCc", + "CACcbBAc", + 10 + ], + [ + "BCABccC", + "B", + 12 + ], + [ + "BCABccaB", + "cAaCbBCc", + 13 + ], + [ + "BCAC", + "CAcCB", + 6 + ], + [ + "BCACBaACB", + "aaCaC", + 11 + ], + [ + "BCACBaba", + "BbAaAbc", + 9 + ], + [ + "BCACBb", + "aCbCA", + 8 + ], + [ + "BCACb", + "CAABCa", + 8 + ], + [ + "BCACcABBB", + "C", + 16 + ], + [ + "BCACcCAC", + "aBcAaaB", + 12 + ], + [ + "BCACcb", + "AC", + 8 + ], + [ + "BCAa", + "A", + 6 + ], + [ + "BCAa", + "Cc", + 6 + ], + [ + "BCAacBCB", + "CaCC", + 9 + ], + [ + "BCAbBAbAc", + "aBcbB", + 13 + ], + [ + "BCAbBaCB", + "caCba", + 11 + ], + [ + "BCAbCB", + "ccBcBCC", + 10 + ], + [ + "BCAbaCC", + "aB", + 12 + ], + [ + "BCAbbAcBA", + "A", + 16 + ], + [ + "BCAbbBA", + "BBAAAbac", + 10 + ], + [ + "BCAbc", + "Cb", + 6 + ], + [ + "BCAbcaBCC", + "ccBacBbA", + 13 + ], + [ + "BCAbccbb", + "bAcaCCbAB", + 12 + ], + [ + "BCAc", + "BaBb", + 6 + ], + [ + "BCAcC", + "Ccc", + 5 + ], + [ + "BCAcCabcc", + "CBC", + 14 + ], + [ + "BCAcabbBc", + "bcbC", + 12 + ], + [ + "BCB", + "caa", + 6 + ], + [ + "BCB", + "ccB", + 3 + ], + [ + "BCBA", + "B", + 6 + ], + [ + "BCBA", + "bAB", + 5 + ], + [ + "BCBAACcc", + "aBB", + 14 + ], + [ + "BCBACbAbA", + "ccABAa", + 11 + ], + [ + "BCBACbCb", + "cBA", + 11 + ], + [ + "BCBAaBcA", + "baC", + 12 + ], + [ + "BCBAabB", + "Bcb", + 9 + ], + [ + "BCBAb", + "CccbcCcBb", + 13 + ], + [ + "BCBAcbbC", + "AccaABA", + 13 + ], + [ + "BCBB", + "A", + 8 + ], + [ + "BCBBA", + "ACAC", + 8 + ], + [ + "BCBBACa", + "AbbAA", + 9 + ], + [ + "BCBBbCbC", + "Ccb", + 11 + ], + [ + "BCBBbab", + "cCAccAbb", + 11 + ], + [ + "BCBBcCa", + "BCCCBbA", + 9 + ], + [ + "BCBBcaCBA", + "CbBCCBacA", + 10 + ], + [ + "BCBBccB", + "B", + 12 + ], + [ + "BCBC", + "CbaBa", + 7 + ], + [ + "BCBC", + "cabAcCaCc", + 13 + ], + [ + "BCBCAaB", + "CAcb", + 9 + ], + [ + "BCBCBaAA", + "b", + 15 + ], + [ + "BCBCBbbc", + "CBBA", + 10 + ], + [ + "BCBCbbBC", + "CACcaACaB", + 14 + ], + [ + "BCBCc", + "aBAA", + 8 + ], + [ + "BCBaACb", + "aCB", + 9 + ], + [ + "BCBaAcb", + "AaC", + 11 + ], + [ + "BCBaC", + "BC", + 6 + ], + [ + "BCBaCCabc", + "aAcbC", + 12 + ], + [ + "BCBb", + "AaaBabaAa", + 14 + ], + [ + "BCBbAABB", + "A", + 14 + ], + [ + "BCBbBCaA", + "B", + 14 + ], + [ + "BCBbc", + "AbBba", + 6 + ], + [ + "BCBbcbBC", + "ca", + 14 + ], + [ + "BCBcB", + "bbC", + 7 + ], + [ + "BCBcaACa", + "bbCaabC", + 10 + ], + [ + "BCBcabB", + "aaBaaaAac", + 14 + ], + [ + "BCC", + "AabbC", + 7 + ], + [ + "BCC", + "AbbBBa", + 10 + ], + [ + "BCC", + "CCBcABb", + 11 + ], + [ + "BCCA", + "bcbbc", + 8 + ], + [ + "BCCA", + "cBBbacAc", + 11 + ], + [ + "BCCAAbbC", + "ccCB", + 12 + ], + [ + "BCCABc", + "c", + 10 + ], + [ + "BCCAaba", + "CAbB", + 8 + ], + [ + "BCCB", + "cBca", + 7 + ], + [ + "BCCBCC", + "ACCBaa", + 6 + ], + [ + "BCCBbcAAA", + "aaaCCB", + 16 + ], + [ + "BCCCAbA", + "CabCcbc", + 10 + ], + [ + "BCCCCAB", + "BC", + 10 + ], + [ + "BCCCCBAB", + "cABCcc", + 13 + ], + [ + "BCCCb", + "cCCAc", + 6 + ], + [ + "BCCaAcbB", + "Cabccaa", + 12 + ], + [ + "BCCaB", + "cAaAcAa", + 12 + ], + [ + "BCCaBABCc", + "a", + 16 + ], + [ + "BCCaCBCAA", + "cBbCaccaA", + 9 + ], + [ + "BCCac", + "CbC", + 7 + ], + [ + "BCCbAc", + "AcCAaBcCc", + 12 + ], + [ + "BCCbCbaB", + "caa", + 13 + ], + [ + "BCCbaBBbC", + "baBAB", + 11 + ], + [ + "BCCbb", + "aAAcc", + 10 + ], + [ + "BCCbbb", + "BCaB", + 7 + ], + [ + "BCCbc", + "BBaAbbBCC", + 13 + ], + [ + "BCCbc", + "caBaAbbC", + 11 + ], + [ + "BCCcaAccC", + "bacbC", + 11 + ], + [ + "BCCcbAcBa", + "CA", + 14 + ], + [ + "BCCcbaBc", + "CcCcCAba", + 9 + ], + [ + "BCCccbaC", + "C", + 14 + ], + [ + "BCa", + "CBbbAac", + 10 + ], + [ + "BCa", + "aAbCCb", + 9 + ], + [ + "BCa", + "bbcAB", + 7 + ], + [ + "BCa", + "c", + 5 + ], + [ + "BCaABBaAB", + "acCcBAC", + 13 + ], + [ + "BCaAa", + "AC", + 8 + ], + [ + "BCaAaCac", + "aaAB", + 11 + ], + [ + "BCaAba", + "a", + 10 + ], + [ + "BCaAcAbC", + "B", + 14 + ], + [ + "BCaBAC", + "bCAcCAaB", + 10 + ], + [ + "BCaBcCB", + "BaAA", + 10 + ], + [ + "BCaCAc", + "CBAaBc", + 8 + ], + [ + "BCaCCCcc", + "ccbaBCaC", + 12 + ], + [ + "BCaCbbbc", + "aaAAa", + 14 + ], + [ + "BCaa", + "bc", + 6 + ], + [ + "BCaaAbaB", + "ccCA", + 13 + ], + [ + "BCaaab", + "cAbBBa", + 11 + ], + [ + "BCaaabC", + "Bbbcb", + 10 + ], + [ + "BCaabcbA", + "BabcCAb", + 8 + ], + [ + "BCabaB", + "BaBAbcB", + 7 + ], + [ + "BCabacC", + "a", + 12 + ], + [ + "BCabbbABB", + "BBCcABb", + 10 + ], + [ + "BCabbcCCC", + "ABcCAcbc", + 13 + ], + [ + "BCabcaAAA", + "Baa", + 12 + ], + [ + "BCacBBAAB", + "aBC", + 14 + ], + [ + "BCacBBbB", + "CBCB", + 10 + ], + [ + "BCacCB", + "bB", + 9 + ], + [ + "BCacCba", + "BaBbaAAba", + 10 + ], + [ + "BCb", + "BBa", + 4 + ], + [ + "BCb", + "bBCCa", + 6 + ], + [ + "BCb", + "bCAAAAC", + 11 + ], + [ + "BCbA", + "Bccc", + 5 + ], + [ + "BCbAAC", + "aA", + 9 + ], + [ + "BCbAcbcCB", + "cbBcba", + 11 + ], + [ + "BCbBCacaC", + "AACB", + 16 + ], + [ + "BCbBa", + "cbbBC", + 6 + ], + [ + "BCbBaa", + "aCAAbACc", + 12 + ], + [ + "BCbBca", + "bBaB", + 8 + ], + [ + "BCbCA", + "cB", + 8 + ], + [ + "BCbCccA", + "aaABcCAB", + 11 + ], + [ + "BCbaAABaa", + "AA", + 14 + ], + [ + "BCbaBAb", + "cAAAcbbaA", + 15 + ], + [ + "BCbaCbBAc", + "CBCcabcAb", + 10 + ], + [ + "BCbaaCCaa", + "cCbac", + 11 + ], + [ + "BCbaabbBC", + "abcCBbB", + 11 + ], + [ + "BCbaccCC", + "bbBc", + 11 + ], + [ + "BCbbc", + "AcCbBaACc", + 11 + ], + [ + "BCbbcbbB", + "AbbCca", + 11 + ], + [ + "BCbc", + "cbcCCcBAA", + 13 + ], + [ + "BCbcBbaC", + "babCBCACb", + 9 + ], + [ + "BCbcaACBB", + "aab", + 14 + ], + [ + "BCbccccB", + "Ca", + 14 + ], + [ + "BCc", + "AAaCBcAbc", + 13 + ], + [ + "BCc", + "AcBbBbcba", + 14 + ], + [ + "BCc", + "CAcB", + 6 + ], + [ + "BCc", + "bABBC", + 7 + ], + [ + "BCcA", + "Aac", + 6 + ], + [ + "BCcA", + "bbbCc", + 7 + ], + [ + "BCcACaB", + "CBcbcaBAA", + 11 + ], + [ + "BCcACaCca", + "cca", + 12 + ], + [ + "BCcAcb", + "bbcacbb", + 6 + ], + [ + "BCcBBAccb", + "cBB", + 12 + ], + [ + "BCcBBacB", + "B", + 14 + ], + [ + "BCcBBc", + "ca", + 10 + ], + [ + "BCcBac", + "Cb", + 9 + ], + [ + "BCcBbBAb", + "BBcBBcA", + 7 + ], + [ + "BCcBbBCc", + "A", + 16 + ], + [ + "BCcBc", + "a", + 10 + ], + [ + "BCcCB", + "CABB", + 6 + ], + [ + "BCcCC", + "baB", + 9 + ], + [ + "BCcCcaaB", + "CAaa", + 10 + ], + [ + "BCca", + "aBcCcA", + 5 + ], + [ + "BCcaAc", + "aaAAA", + 9 + ], + [ + "BCcaBbAb", + "A", + 14 + ], + [ + "BCcab", + "CA", + 7 + ], + [ + "BCcacCbcc", + "CBcabaBCC", + 11 + ], + [ + "BCcb", + "CCbBACCcc", + 12 + ], + [ + "BCcb", + "Ca", + 6 + ], + [ + "BCcb", + "bC", + 5 + ], + [ + "BCcbAc", + "B", + 10 + ], + [ + "BCcbAcBAA", + "AacbBc", + 12 + ], + [ + "BCcbBac", + "Aaa", + 12 + ], + [ + "BCcbaC", + "cB", + 9 + ], + [ + "BCcbc", + "BBa", + 7 + ], + [ + "BCccAac", + "ABB", + 12 + ], + [ + "BCccBb", + "Cc", + 8 + ], + [ + "BCccCC", + "BBA", + 10 + ], + [ + "Ba", + "AAACAbbb", + 15 + ], + [ + "Ba", + "AAaBBbBaa", + 14 + ], + [ + "Ba", + "ABBaAabBa", + 14 + ], + [ + "Ba", + "AaccaB", + 10 + ], + [ + "Ba", + "AcABCBc", + 12 + ], + [ + "Ba", + "AcB", + 6 + ], + [ + "Ba", + "AcaAcb", + 10 + ], + [ + "Ba", + "B", + 2 + ], + [ + "Ba", + "BAcBc", + 7 + ], + [ + "Ba", + "Ba", + 0 + ], + [ + "Ba", + "BcAACc", + 9 + ], + [ + "Ba", + "BcCa", + 4 + ], + [ + "Ba", + "BcbBb", + 8 + ], + [ + "Ba", + "C", + 4 + ], + [ + "Ba", + "CABbaBcb", + 12 + ], + [ + "Ba", + "CBBAAB", + 9 + ], + [ + "Ba", + "CC", + 4 + ], + [ + "Ba", + "CCCcABBC", + 14 + ], + [ + "Ba", + "CbCbCa", + 9 + ], + [ + "Ba", + "Cc", + 4 + ], + [ + "Ba", + "a", + 2 + ], + [ + "Ba", + "aA", + 3 + ], + [ + "Ba", + "aB", + 4 + ], + [ + "Ba", + "aCB", + 6 + ], + [ + "Ba", + "aCbCa", + 7 + ], + [ + "Ba", + "acBbb", + 8 + ], + [ + "Ba", + "b", + 3 + ], + [ + "Ba", + "bcBCAbcCB", + 15 + ], + [ + "Ba", + "c", + 4 + ], + [ + "Ba", + "cAaAABbCB", + 16 + ], + [ + "Ba", + "cBBa", + 4 + ], + [ + "Ba", + "cbBaCAb", + 10 + ], + [ + "Ba", + "ccBcACA", + 11 + ], + [ + "Ba", + "ccC", + 6 + ], + [ + "BaA", + "CACaA", + 6 + ], + [ + "BaA", + "CBAbbaca", + 11 + ], + [ + "BaA", + "aaBB", + 6 + ], + [ + "BaA", + "bA", + 3 + ], + [ + "BaA", + "baACAbcA", + 11 + ], + [ + "BaA", + "cbc", + 6 + ], + [ + "BaA", + "ccBAAB", + 7 + ], + [ + "BaAAA", + "BB", + 8 + ], + [ + "BaAAa", + "ca", + 8 + ], + [ + "BaAAaCBaA", + "ACCC", + 14 + ], + [ + "BaAAcCA", + "abCCBA", + 9 + ], + [ + "BaAAcc", + "aaAAbac", + 6 + ], + [ + "BaAAccaCA", + "CcABcBCc", + 12 + ], + [ + "BaAB", + "BBAB", + 2 + ], + [ + "BaAB", + "ac", + 6 + ], + [ + "BaAB", + "bBB", + 5 + ], + [ + "BaABAACBA", + "bAb", + 14 + ], + [ + "BaABCaACb", + "bCbabAaBb", + 13 + ], + [ + "BaABa", + "abC", + 7 + ], + [ + "BaABcbab", + "cAaca", + 10 + ], + [ + "BaACAcCc", + "BC", + 12 + ], + [ + "BaACB", + "bcAa", + 7 + ], + [ + "BaACBAbAC", + "Bac", + 13 + ], + [ + "BaACaCbC", + "AACACCC", + 6 + ], + [ + "BaAa", + "BBCC", + 6 + ], + [ + "BaAa", + "BcbccbCC", + 14 + ], + [ + "BaAa", + "aAbB", + 6 + ], + [ + "BaAaAaAB", + "Ccab", + 13 + ], + [ + "BaAaaAAb", + "ABBCBAcB", + 13 + ], + [ + "BaAacA", + "bACCCb", + 9 + ], + [ + "BaAb", + "AbCBcCba", + 12 + ], + [ + "BaAbCBa", + "CCCcAb", + 13 + ], + [ + "BaAbab", + "aAbaBCc", + 7 + ], + [ + "BaAbcCCB", + "CBcA", + 13 + ], + [ + "BaAcAB", + "BabCCCaC", + 10 + ], + [ + "BaAcAa", + "abaCCCBAA", + 11 + ], + [ + "BaAcAbbC", + "ABaBBAC", + 10 + ], + [ + "BaAcB", + "CBAACbCa", + 9 + ], + [ + "BaAcCbb", + "Abb", + 8 + ], + [ + "BaAcCbca", + "BcCbCAAcB", + 12 + ], + [ + "BaAcbcb", + "c", + 12 + ], + [ + "BaB", + "CACAb", + 8 + ], + [ + "BaB", + "aCACaB", + 8 + ], + [ + "BaB", + "bc", + 5 + ], + [ + "BaB", + "cBBB", + 4 + ], + [ + "BaB", + "cCacaaB", + 10 + ], + [ + "BaBA", + "cABACbbA", + 10 + ], + [ + "BaBAA", + "bbAacbA", + 9 + ], + [ + "BaBAB", + "acAaABBA", + 11 + ], + [ + "BaBABabC", + "C", + 14 + ], + [ + "BaBACA", + "ACAcbbccb", + 15 + ], + [ + "BaBAc", + "BaBABaaC", + 7 + ], + [ + "BaBB", + "aBBCaA", + 8 + ], + [ + "BaBBaABA", + "AaabaABb", + 7 + ], + [ + "BaBBb", + "BC", + 8 + ], + [ + "BaBBc", + "C", + 9 + ], + [ + "BaBBcAaAc", + "C", + 17 + ], + [ + "BaBBcbcb", + "bbabb", + 10 + ], + [ + "BaBCAbab", + "A", + 14 + ], + [ + "BaBCBC", + "BA", + 9 + ], + [ + "BaBCaCac", + "cACc", + 10 + ], + [ + "BaBCc", + "cBcCbAab", + 13 + ], + [ + "BaBa", + "bBBABAabb", + 11 + ], + [ + "BaBa", + "bCAbaAbCb", + 13 + ], + [ + "BaBaBB", + "C", + 12 + ], + [ + "BaBb", + "CC", + 8 + ], + [ + "BaBb", + "bbAbCcbBc", + 13 + ], + [ + "BaBbABA", + "ababcCAc", + 11 + ], + [ + "BaBbBb", + "cCAAb", + 10 + ], + [ + "BaBbC", + "BBACac", + 8 + ], + [ + "BaBbabbCb", + "b", + 16 + ], + [ + "BaBc", + "CB", + 6 + ], + [ + "BaBcACac", + "AbCaBA", + 11 + ], + [ + "BaBcB", + "AaabaaBAa", + 13 + ], + [ + "BaBcBbbAa", + "BCACcab", + 13 + ], + [ + "BaBcCA", + "CbCACA", + 8 + ], + [ + "BaBcCA", + "bCa", + 8 + ], + [ + "BaBcaCCbB", + "BCC", + 12 + ], + [ + "BaBcacC", + "ACB", + 12 + ], + [ + "BaC", + "ABAbc", + 6 + ], + [ + "BaC", + "ABbb", + 6 + ], + [ + "BaC", + "ACa", + 5 + ], + [ + "BaC", + "Aaba", + 6 + ], + [ + "BaC", + "BACccaaBA", + 13 + ], + [ + "BaC", + "BC", + 2 + ], + [ + "BaC", + "Bccb", + 5 + ], + [ + "BaC", + "a", + 4 + ], + [ + "BaC", + "bCbbBcB", + 12 + ], + [ + "BaC", + "baBcbC", + 7 + ], + [ + "BaC", + "cBAabACAa", + 12 + ], + [ + "BaC", + "cBaBAaCc", + 10 + ], + [ + "BaCAA", + "cbbcBBbb", + 14 + ], + [ + "BaCAAbbB", + "BAcB", + 10 + ], + [ + "BaCAB", + "cC", + 8 + ], + [ + "BaCABCB", + "bB", + 11 + ], + [ + "BaCABccaB", + "CAacBCCA", + 12 + ], + [ + "BaCAaAc", + "bCa", + 9 + ], + [ + "BaCB", + "B", + 6 + ], + [ + "BaCBa", + "BbAbaBC", + 9 + ], + [ + "BaCBaCcCC", + "aCCAc", + 11 + ], + [ + "BaCBbCB", + "acB", + 9 + ], + [ + "BaCBc", + "ABCB", + 6 + ], + [ + "BaCBcBC", + "cc", + 11 + ], + [ + "BaCCAcAb", + "Bab", + 10 + ], + [ + "BaCCC", + "CcBCabAAa", + 14 + ], + [ + "BaCCCAcb", + "bbcAaA", + 12 + ], + [ + "BaCCCbb", + "bCCaaCb", + 9 + ], + [ + "BaCCbAA", + "acCBcBB", + 10 + ], + [ + "BaCCc", + "Ca", + 8 + ], + [ + "BaCCcCcc", + "baAbcaCc", + 8 + ], + [ + "BaCa", + "bbAba", + 6 + ], + [ + "BaCaAAaca", + "CCbCb", + 15 + ], + [ + "BaCaCCABa", + "bCaC", + 11 + ], + [ + "BaCb", + "bbaA", + 7 + ], + [ + "BaCb", + "cABC", + 7 + ], + [ + "BaCbAB", + "BAcbaAC", + 6 + ], + [ + "BaCbBA", + "bcAacBaa", + 10 + ], + [ + "BaCbBCaa", + "acBCAAcA", + 11 + ], + [ + "BaCbBcbB", + "bc", + 12 + ], + [ + "BaCbbbBaa", + "CcCAcCCC", + 16 + ], + [ + "BaCc", + "Bc", + 4 + ], + [ + "BaCc", + "CCBcbAAA", + 13 + ], + [ + "BaCcBbAb", + "BcaAaBa", + 11 + ], + [ + "BaCcCcab", + "abBAcBA", + 12 + ], + [ + "BaCcCcbAc", + "BacCAaaaA", + 11 + ], + [ + "BaCcaAabB", + "BBc", + 14 + ], + [ + "BaCcaBAa", + "AaCb", + 11 + ], + [ + "BaCccaaaA", + "cBacBCA", + 12 + ], + [ + "Baa", + "A", + 5 + ], + [ + "Baa", + "AcccabBa", + 12 + ], + [ + "Baa", + "BaaBCABcB", + 12 + ], + [ + "Baa", + "CAAa", + 5 + ], + [ + "Baa", + "CBBcBcC", + 12 + ], + [ + "Baa", + "CCABBacBb", + 14 + ], + [ + "Baa", + "CbABbAcbb", + 15 + ], + [ + "Baa", + "CbCaAbc", + 10 + ], + [ + "Baa", + "bBaBbabAc", + 12 + ], + [ + "Baa", + "bBccbbaAC", + 13 + ], + [ + "Baa", + "bcAbaAACA", + 14 + ], + [ + "BaaA", + "CaBBc", + 8 + ], + [ + "BaaA", + "baBabC", + 7 + ], + [ + "BaaABa", + "bCbcaa", + 9 + ], + [ + "BaaACcAAc", + "bccAaa", + 11 + ], + [ + "BaaAaCc", + "cB", + 13 + ], + [ + "BaaB", + "C", + 8 + ], + [ + "BaaB", + "cAa", + 5 + ], + [ + "BaaBAbAb", + "baccCC", + 13 + ], + [ + "BaaBBcA", + "ccC", + 12 + ], + [ + "BaaC", + "bCb", + 7 + ], + [ + "BaaC", + "cacAcCBcC", + 13 + ], + [ + "BaaCACAaB", + "cAaCabab", + 9 + ], + [ + "BaaCBCBBc", + "ac", + 14 + ], + [ + "BaaCbAC", + "AbCAbca", + 11 + ], + [ + "BaaCcCa", + "cBACb", + 11 + ], + [ + "BaaaBcCab", + "BaBbbbAaC", + 11 + ], + [ + "BaaaC", + "accb", + 8 + ], + [ + "Baaaa", + "B", + 8 + ], + [ + "Baaaa", + "CaA", + 7 + ], + [ + "BaaababB", + "bCAcBCB", + 11 + ], + [ + "BaaacbA", + "aBCba", + 8 + ], + [ + "Baab", + "cCAAcBa", + 11 + ], + [ + "Baab", + "ccaAACcAC", + 15 + ], + [ + "BaabA", + "b", + 8 + ], + [ + "BaabAA", + "A", + 10 + ], + [ + "BaabBAcC", + "aaBCaab", + 10 + ], + [ + "BaabBcc", + "cCCAaCbc", + 12 + ], + [ + "BaabCBCC", + "CcCaB", + 14 + ], + [ + "BaabCa", + "cAaAB", + 9 + ], + [ + "BaabCb", + "CA", + 10 + ], + [ + "Baabacaa", + "bAcbccB", + 10 + ], + [ + "Baabb", + "bBbAbbA", + 7 + ], + [ + "BaabbAaA", + "BBA", + 11 + ], + [ + "BaabcAb", + "aBaC", + 10 + ], + [ + "Baac", + "AaCacBCA", + 10 + ], + [ + "Baac", + "CcBaBAb", + 9 + ], + [ + "Baac", + "a", + 6 + ], + [ + "Baac", + "aaAB", + 5 + ], + [ + "Baac", + "cCcBC", + 9 + ], + [ + "Baac", + "ccCb", + 8 + ], + [ + "BaacCABbA", + "cA", + 14 + ], + [ + "Bab", + "BaCABaCa", + 11 + ], + [ + "Bab", + "C", + 6 + ], + [ + "Bab", + "a", + 4 + ], + [ + "Bab", + "acabAacac", + 14 + ], + [ + "Bab", + "bbCaccBaB", + 13 + ], + [ + "BabA", + "a", + 6 + ], + [ + "BabA", + "cbAc", + 6 + ], + [ + "BabAAccaB", + "abb", + 13 + ], + [ + "BabACA", + "b", + 10 + ], + [ + "BabAaC", + "baCCBcC", + 9 + ], + [ + "BabAb", + "Aa", + 8 + ], + [ + "BabAbACA", + "CBAaCaaa", + 12 + ], + [ + "BabAbCA", + "CccAab", + 12 + ], + [ + "BabBBAaCa", + "AcCAccAB", + 15 + ], + [ + "BabBa", + "ABbACcCcb", + 15 + ], + [ + "BabBcA", + "ACC", + 10 + ], + [ + "BabBcBcA", + "acbCABcB", + 10 + ], + [ + "BabC", + "aABb", + 6 + ], + [ + "BabCaBca", + "AA", + 14 + ], + [ + "Baba", + "BaBCbCBB", + 10 + ], + [ + "BabaBaAA", + "AaB", + 11 + ], + [ + "BabacAbAb", + "cCaA", + 14 + ], + [ + "Babb", + "CcAa", + 8 + ], + [ + "Babb", + "aaACcbc", + 10 + ], + [ + "BabbA", + "CaCb", + 6 + ], + [ + "BabbAaaBA", + "BbCcACC", + 13 + ], + [ + "BabbAccb", + "cacBB", + 11 + ], + [ + "BabbBcBA", + "cAabCbba", + 11 + ], + [ + "BabbCBb", + "aCCcBcB", + 10 + ], + [ + "BabbCCbCA", + "AbAcBa", + 12 + ], + [ + "BabbcBAAa", + "aCacA", + 12 + ], + [ + "BabcBAbcc", + "CabA", + 12 + ], + [ + "BabcCbCA", + "cbC", + 10 + ], + [ + "BabcaC", + "ABB", + 10 + ], + [ + "Babcac", + "bcccAbBC", + 11 + ], + [ + "Bac", + "BBcaBcC", + 8 + ], + [ + "Bac", + "CbcAbAbB", + 14 + ], + [ + "Bac", + "bacBAccb", + 11 + ], + [ + "Bac", + "bbACab", + 9 + ], + [ + "BacAa", + "bBCb", + 8 + ], + [ + "BacAaaCaB", + "ccaaAb", + 10 + ], + [ + "BacAb", + "aBBaBa", + 9 + ], + [ + "BacAbA", + "caAaBbCAb", + 11 + ], + [ + "BacBBa", + "AbBBAAA", + 10 + ], + [ + "BacBCAB", + "cCBaBCc", + 10 + ], + [ + "BacBab", + "CbBABcB", + 10 + ], + [ + "BacCAaBAB", + "ccAb", + 12 + ], + [ + "BacCBBCc", + "B", + 14 + ], + [ + "BacCCaA", + "bcaBA", + 9 + ], + [ + "BacCCcbB", + "cCbaaCBB", + 12 + ], + [ + "BacCa", + "cCBBB", + 10 + ], + [ + "BacCab", + "bA", + 10 + ], + [ + "BacCabcAc", + "CCbBC", + 12 + ], + [ + "BacCccBa", + "ABCBA", + 10 + ], + [ + "BacaB", + "bbac", + 7 + ], + [ + "BacaC", + "AAC", + 6 + ], + [ + "BacaCaBB", + "bB", + 13 + ], + [ + "BacaCbA", + "caBCAa", + 9 + ], + [ + "BacbB", + "CcaACc", + 10 + ], + [ + "BacbC", + "AAabcbbCB", + 10 + ], + [ + "BacbCbBca", + "cCcCC", + 13 + ], + [ + "BacbbCaAa", + "aCACaC", + 11 + ], + [ + "Bacc", + "b", + 7 + ], + [ + "BaccACa", + "B", + 12 + ], + [ + "BaccAaacb", + "A", + 16 + ], + [ + "BaccBcCBB", + "acb", + 13 + ], + [ + "BaccCB", + "BaC", + 6 + ], + [ + "Bacca", + "Ac", + 7 + ], + [ + "BaccaCC", + "CcbA", + 11 + ], + [ + "Baccb", + "aCc", + 5 + ], + [ + "Baccba", + "cbaaBcbc", + 9 + ], + [ + "Bb", + "AAABBB", + 9 + ], + [ + "Bb", + "AAccaCAaa", + 18 + ], + [ + "Bb", + "AaA", + 6 + ], + [ + "Bb", + "AaAAc", + 10 + ], + [ + "Bb", + "B", + 2 + ], + [ + "Bb", + "BACBbABA", + 12 + ], + [ + "Bb", + "BBaBb", + 6 + ], + [ + "Bb", + "BacCBA", + 9 + ], + [ + "Bb", + "BbCBCABAC", + 14 + ], + [ + "Bb", + "Bba", + 2 + ], + [ + "Bb", + "BcBAACA", + 11 + ], + [ + "Bb", + "CC", + 4 + ], + [ + "Bb", + "CcaaBa", + 10 + ], + [ + "Bb", + "a", + 4 + ], + [ + "Bb", + "aAbbb", + 7 + ], + [ + "Bb", + "aBa", + 4 + ], + [ + "Bb", + "aBbcCbAAC", + 14 + ], + [ + "Bb", + "aCCAB", + 9 + ], + [ + "Bb", + "aCccacCB", + 15 + ], + [ + "Bb", + "aacA", + 8 + ], + [ + "Bb", + "abBaBbAa", + 12 + ], + [ + "Bb", + "b", + 2 + ], + [ + "Bb", + "bAcCbc", + 9 + ], + [ + "Bb", + "bBaCBc", + 9 + ], + [ + "Bb", + "bBbBCccc", + 12 + ], + [ + "Bb", + "bCCc", + 7 + ], + [ + "Bb", + "bCaBcC", + 10 + ], + [ + "Bb", + "bCcbbc", + 9 + ], + [ + "Bb", + "baB", + 4 + ], + [ + "Bb", + "bc", + 3 + ], + [ + "Bb", + "bcCaacCC", + 15 + ], + [ + "Bb", + "bcaBccAcb", + 14 + ], + [ + "Bb", + "cab", + 4 + ], + [ + "Bb", + "cbAACCBb", + 12 + ], + [ + "Bb", + "cbabCcbb", + 13 + ], + [ + "Bb", + "cc", + 4 + ], + [ + "BbA", + "BCaAcABab", + 14 + ], + [ + "BbA", + "C", + 6 + ], + [ + "BbA", + "aacCbAc", + 10 + ], + [ + "BbA", + "cbCcbaAAA", + 13 + ], + [ + "BbAAaA", + "AbbBccC", + 11 + ], + [ + "BbAAaA", + "bBc", + 10 + ], + [ + "BbABB", + "BBAACAa", + 9 + ], + [ + "BbABBbAa", + "acaCCbbcB", + 14 + ], + [ + "BbABC", + "c", + 9 + ], + [ + "BbABa", + "accBbBcBb", + 12 + ], + [ + "BbABaacaA", + "b", + 16 + ], + [ + "BbAC", + "CaCCBcAa", + 12 + ], + [ + "BbAC", + "caAcaab", + 11 + ], + [ + "BbACAbcB", + "aaaAB", + 11 + ], + [ + "BbAa", + "ACcA", + 7 + ], + [ + "BbAa", + "cCA", + 6 + ], + [ + "BbAaAaaa", + "cBbbcCB", + 14 + ], + [ + "BbAaCab", + "cA", + 12 + ], + [ + "BbAaa", + "Bbbcacaa", + 7 + ], + [ + "BbAac", + "b", + 8 + ], + [ + "BbAb", + "CccCbabaC", + 13 + ], + [ + "BbAbC", + "CABA", + 7 + ], + [ + "BbAbC", + "ccA", + 8 + ], + [ + "BbAbCab", + "bcabABC", + 10 + ], + [ + "BbAbCcBab", + "CAaAbcbAC", + 12 + ], + [ + "BbAbCcaAC", + "ABbcCa", + 11 + ], + [ + "BbAbbcbb", + "B", + 14 + ], + [ + "BbAbc", + "aABB", + 7 + ], + [ + "BbAcaaaa", + "bBccaac", + 8 + ], + [ + "BbAcbca", + "acCCcbBCB", + 13 + ], + [ + "BbB", + "ACbcc", + 8 + ], + [ + "BbB", + "Acaca", + 10 + ], + [ + "BbB", + "bBcb", + 5 + ], + [ + "BbBA", + "CA", + 6 + ], + [ + "BbBABCcA", + "aaC", + 13 + ], + [ + "BbBAaBa", + "b", + 12 + ], + [ + "BbBAb", + "aaCCcb", + 10 + ], + [ + "BbBAbABAc", + "cBbbBCcB", + 12 + ], + [ + "BbBBCbca", + "cbBcCbC", + 7 + ], + [ + "BbBBa", + "cC", + 10 + ], + [ + "BbBBaBBba", + "bAC", + 15 + ], + [ + "BbBBabAb", + "cbB", + 12 + ], + [ + "BbBC", + "cbbbcaA", + 9 + ], + [ + "BbBCAbb", + "baCCbBbb", + 9 + ], + [ + "BbBCbAb", + "BbCcBbbac", + 9 + ], + [ + "BbBa", + "aCaaaA", + 10 + ], + [ + "BbBa", + "caCcb", + 10 + ], + [ + "BbBaC", + "BA", + 7 + ], + [ + "BbBaCbCcB", + "baAbCbaCc", + 11 + ], + [ + "BbBaaCBbc", + "bcAAAbC", + 11 + ], + [ + "BbBacBCca", + "c", + 16 + ], + [ + "BbBbA", + "BbaaA", + 4 + ], + [ + "BbBbBAb", + "CbcCbAaCc", + 13 + ], + [ + "BbBbBa", + "A", + 11 + ], + [ + "BbBbBbC", + "cBbacbBa", + 10 + ], + [ + "BbBbbbBAb", + "AabCcBa", + 13 + ], + [ + "BbBcBc", + "bcaaC", + 9 + ], + [ + "BbBcaAC", + "cB", + 12 + ], + [ + "BbBcabAa", + "BaBAaACc", + 10 + ], + [ + "BbBcbbC", + "bCBAabbaa", + 11 + ], + [ + "BbC", + "A", + 6 + ], + [ + "BbC", + "Cc", + 5 + ], + [ + "BbC", + "aAAAc", + 9 + ], + [ + "BbC", + "aAAbca", + 9 + ], + [ + "BbC", + "bAaBabC", + 8 + ], + [ + "BbC", + "bBCcCa", + 8 + ], + [ + "BbC", + "baCACBbc", + 11 + ], + [ + "BbC", + "bcBccBcBa", + 14 + ], + [ + "BbCAACcac", + "AcCbB", + 14 + ], + [ + "BbCAACcb", + "b", + 14 + ], + [ + "BbCAaCaC", + "BBc", + 12 + ], + [ + "BbCAbc", + "aaa", + 11 + ], + [ + "BbCAcCaCC", + "CCcB", + 13 + ], + [ + "BbCAcaab", + "BCbACaABc", + 9 + ], + [ + "BbCBCB", + "bAAccbCc", + 11 + ], + [ + "BbCBCbAc", + "CcACA", + 11 + ], + [ + "BbCCAAab", + "ccCCC", + 12 + ], + [ + "BbCCABABa", + "Acaab", + 14 + ], + [ + "BbCCBBb", + "aacCb", + 9 + ], + [ + "BbCCCBCC", + "BCA", + 12 + ], + [ + "BbCCa", + "aaaCAc", + 9 + ], + [ + "BbCCcCcCc", + "AaAAA", + 18 + ], + [ + "BbCCcbc", + "BaaBCc", + 9 + ], + [ + "BbCa", + "aCC", + 6 + ], + [ + "BbCaB", + "A", + 9 + ], + [ + "BbCaBAA", + "AbAABc", + 9 + ], + [ + "BbCaCbACB", + "AAA", + 15 + ], + [ + "BbCaCcC", + "aAAcA", + 11 + ], + [ + "BbCaCcaC", + "A", + 15 + ], + [ + "BbCbC", + "bAACAAcAC", + 13 + ], + [ + "BbCbCCb", + "AbBAA", + 11 + ], + [ + "BbCbaAB", + "C", + 12 + ], + [ + "BbCbaB", + "aAcC", + 11 + ], + [ + "BbCbaBB", + "Cabb", + 8 + ], + [ + "BbCbbBc", + "b", + 12 + ], + [ + "BbCbbb", + "cCcAcBAcA", + 16 + ], + [ + "BbCbcc", + "AAACbaaAa", + 14 + ], + [ + "BbCc", + "A", + 8 + ], + [ + "BbCc", + "aac", + 6 + ], + [ + "BbCcCACB", + "cB", + 12 + ], + [ + "BbCcaBBC", + "CB", + 12 + ], + [ + "BbCccBCB", + "cCcbBb", + 9 + ], + [ + "Bba", + "ABBBcACb", + 12 + ], + [ + "Bba", + "AbAcAbCcA", + 14 + ], + [ + "Bba", + "CaBCAaaaB", + 14 + ], + [ + "Bba", + "CacBBCBA", + 12 + ], + [ + "Bba", + "aBAcbCC", + 10 + ], + [ + "Bba", + "aCCcAaAc", + 14 + ], + [ + "Bba", + "abcA", + 5 + ], + [ + "Bba", + "bcCa", + 5 + ], + [ + "BbaAB", + "BbB", + 4 + ], + [ + "BbaABacc", + "bccbc", + 11 + ], + [ + "BbaAbBCAA", + "caAcCbc", + 12 + ], + [ + "BbaAcAb", + "bacACCbC", + 9 + ], + [ + "BbaB", + "aBbAaCb", + 7 + ], + [ + "BbaB", + "bBbBAbBC", + 9 + ], + [ + "BbaBCB", + "bcA", + 9 + ], + [ + "BbaBcbacc", + "CCBAC", + 14 + ], + [ + "BbaC", + "C", + 6 + ], + [ + "BbaCBC", + "C", + 10 + ], + [ + "BbaCCCb", + "Cca", + 11 + ], + [ + "BbaCa", + "AcCC", + 8 + ], + [ + "BbaCa", + "ccbA", + 9 + ], + [ + "BbaCcBba", + "ACb", + 11 + ], + [ + "BbaCcC", + "cbCCAAbcc", + 11 + ], + [ + "Bbaa", + "abbaAA", + 6 + ], + [ + "BbaaAbAA", + "Acc", + 14 + ], + [ + "BbaaBAb", + "CBbaCbaBB", + 9 + ], + [ + "BbaacA", + "ccAbCabAa", + 12 + ], + [ + "BbaacBcbC", + "cabbCaC", + 12 + ], + [ + "Bbab", + "BCBb", + 4 + ], + [ + "BbabA", + "Cbc", + 8 + ], + [ + "BbabBc", + "AcA", + 11 + ], + [ + "BbabC", + "ab", + 6 + ], + [ + "BbabCcBA", + "AabACBc", + 9 + ], + [ + "Bbaba", + "AAa", + 7 + ], + [ + "BbabbBb", + "b", + 12 + ], + [ + "Bbac", + "bbb", + 5 + ], + [ + "BbacB", + "CBcBB", + 7 + ], + [ + "BbacCc", + "Cb", + 10 + ], + [ + "Bbacaa", + "AaAaac", + 8 + ], + [ + "Bbb", + "ACCCCc", + 12 + ], + [ + "Bbb", + "BCABAa", + 9 + ], + [ + "Bbb", + "BabbbBcCA", + 12 + ], + [ + "Bbb", + "acaCCaa", + 14 + ], + [ + "Bbb", + "bAAcBa", + 10 + ], + [ + "Bbb", + "ccacA", + 10 + ], + [ + "BbbA", + "ACccA", + 8 + ], + [ + "BbbAAB", + "baBAb", + 7 + ], + [ + "BbbABccc", + "AbaABca", + 8 + ], + [ + "BbbAC", + "bcAaBBBca", + 14 + ], + [ + "BbbAaAba", + "a", + 14 + ], + [ + "BbbB", + "Bcc", + 6 + ], + [ + "BbbBCCA", + "cBBb", + 11 + ], + [ + "BbbBCba", + "BA", + 11 + ], + [ + "BbbBcaa", + "b", + 12 + ], + [ + "BbbCAaA", + "cbbBaBaCA", + 9 + ], + [ + "BbbCAb", + "AACC", + 10 + ], + [ + "BbbCAc", + "cbaB", + 9 + ], + [ + "BbbCBcac", + "bAbaBCba", + 10 + ], + [ + "BbbCCB", + "C", + 10 + ], + [ + "BbbCCBAc", + "cbbBcCCAC", + 8 + ], + [ + "Bbba", + "AAaAB", + 9 + ], + [ + "Bbba", + "abAc", + 6 + ], + [ + "BbbaAC", + "aBABcAAaB", + 12 + ], + [ + "BbbaC", + "AbBaaAaA", + 11 + ], + [ + "BbbaabCCA", + "CbcAb", + 13 + ], + [ + "BbbacCbb", + "AaccA", + 11 + ], + [ + "BbbbCAaA", + "cACCaCcAC", + 15 + ], + [ + "BbbbbAc", + "AbbcCb", + 10 + ], + [ + "BbbbcA", + "AaCcBabb", + 14 + ], + [ + "BbbbcbbA", + "bAA", + 12 + ], + [ + "Bbbc", + "CbccaAc", + 10 + ], + [ + "BbbcABb", + "bbbcc", + 7 + ], + [ + "BbbcB", + "bbacbbc", + 8 + ], + [ + "BbbcbAcbB", + "aCaCbaAc", + 13 + ], + [ + "Bbbcbcab", + "caCaAAbc", + 14 + ], + [ + "BbcA", + "CBaA", + 5 + ], + [ + "BbcA", + "CBcAB", + 5 + ], + [ + "BbcABcB", + "AcA", + 10 + ], + [ + "BbcACB", + "BaaCCBBC", + 10 + ], + [ + "BbcACCcB", + "bcbbaaBba", + 14 + ], + [ + "BbcAbCa", + "CbbaCba", + 9 + ], + [ + "BbcAcaB", + "Aca", + 8 + ], + [ + "BbcAccCab", + "abCCaA", + 11 + ], + [ + "BbcB", + "aACCccCaA", + 16 + ], + [ + "BbcBbB", + "baacAca", + 11 + ], + [ + "BbcBbbaC", + "Ab", + 14 + ], + [ + "BbcC", + "AccAcaBaC", + 14 + ], + [ + "BbcCB", + "bBca", + 6 + ], + [ + "BbcCBaB", + "AcCcaCbb", + 11 + ], + [ + "BbcCaab", + "cACaC", + 10 + ], + [ + "BbcaBbCCb", + "acBBcc", + 11 + ], + [ + "BbcaCcaa", + "AbcccaBB", + 9 + ], + [ + "BbcaaACb", + "A", + 14 + ], + [ + "BbcbACAa", + "a", + 14 + ], + [ + "BbcbBCCA", + "AcaCB", + 12 + ], + [ + "BbcbCcCCc", + "a", + 18 + ], + [ + "Bbcbaa", + "a", + 10 + ], + [ + "BbcbbbBab", + "aaBcBcCB", + 14 + ], + [ + "BbcbccB", + "bAACb", + 10 + ], + [ + "Bbcc", + "caAACBBb", + 15 + ], + [ + "BbccBcb", + "BCAbccb", + 8 + ], + [ + "BbccC", + "CaaAC", + 8 + ], + [ + "Bbcca", + "bBcb", + 6 + ], + [ + "BbccccCC", + "aAbcc", + 12 + ], + [ + "Bc", + "A", + 4 + ], + [ + "Bc", + "AB", + 4 + ], + [ + "Bc", + "ABAccAcC", + 12 + ], + [ + "Bc", + "ABBbBBbb", + 14 + ], + [ + "Bc", + "AaA", + 6 + ], + [ + "Bc", + "AaaBaCcCc", + 14 + ], + [ + "Bc", + "AabBBC", + 9 + ], + [ + "Bc", + "Aac", + 4 + ], + [ + "Bc", + "Aba", + 5 + ], + [ + "Bc", + "Abccbabbc", + 15 + ], + [ + "Bc", + "AcAbBC", + 9 + ], + [ + "Bc", + "B", + 2 + ], + [ + "Bc", + "BACaACBC", + 13 + ], + [ + "Bc", + "BBcBCbCB", + 12 + ], + [ + "Bc", + "BcBAAAaA", + 12 + ], + [ + "Bc", + "BcaaABCcc", + 14 + ], + [ + "Bc", + "C", + 3 + ], + [ + "Bc", + "CBCccCbaA", + 14 + ], + [ + "Bc", + "CCaBABaBA", + 16 + ], + [ + "Bc", + "CaBCBbBbc", + 14 + ], + [ + "Bc", + "CbaBCbb", + 11 + ], + [ + "Bc", + "a", + 4 + ], + [ + "Bc", + "aC", + 3 + ], + [ + "Bc", + "abAbBBcc", + 12 + ], + [ + "Bc", + "abaCAABA", + 14 + ], + [ + "Bc", + "abaabAbc", + 13 + ], + [ + "Bc", + "abcbBBB", + 11 + ], + [ + "Bc", + "ac", + 2 + ], + [ + "Bc", + "acCCcb", + 10 + ], + [ + "Bc", + "acCacaaAa", + 16 + ], + [ + "Bc", + "ba", + 3 + ], + [ + "Bc", + "cC", + 3 + ], + [ + "Bc", + "cb", + 4 + ], + [ + "Bc", + "cbACCabca", + 15 + ], + [ + "BcA", + "AC", + 5 + ], + [ + "BcA", + "BAaB", + 5 + ], + [ + "BcA", + "BBc", + 4 + ], + [ + "BcA", + "CBababB", + 11 + ], + [ + "BcA", + "CcB", + 4 + ], + [ + "BcA", + "CcCb", + 6 + ], + [ + "BcA", + "a", + 5 + ], + [ + "BcA", + "bAcab", + 6 + ], + [ + "BcA", + "bBAbb", + 7 + ], + [ + "BcA", + "bbbc", + 7 + ], + [ + "BcA", + "c", + 4 + ], + [ + "BcAABaB", + "bACcAc", + 10 + ], + [ + "BcAAaA", + "BcCAbaBb", + 8 + ], + [ + "BcAB", + "aBCCcACc", + 10 + ], + [ + "BcABAc", + "BaAa", + 7 + ], + [ + "BcABaAaA", + "aCCaCcb", + 13 + ], + [ + "BcABaa", + "CaaBBaa", + 7 + ], + [ + "BcAC", + "BCAbcbCAa", + 11 + ], + [ + "BcACAA", + "aCb", + 9 + ], + [ + "BcACB", + "bCcC", + 6 + ], + [ + "BcACBaBCa", + "BCcBAbACc", + 10 + ], + [ + "BcACC", + "aa", + 9 + ], + [ + "BcAa", + "Cb", + 7 + ], + [ + "BcAaA", + "CBBc", + 9 + ], + [ + "BcAaA", + "abBbBBcB", + 14 + ], + [ + "BcAaACA", + "cbCABAaCb", + 10 + ], + [ + "BcAaCCBB", + "cBbCaBbA", + 11 + ], + [ + "BcAaCbB", + "ACB", + 8 + ], + [ + "BcAaaaC", + "cC", + 10 + ], + [ + "BcAb", + "BB", + 5 + ], + [ + "BcAb", + "CC", + 7 + ], + [ + "BcAbAbCac", + "bab", + 13 + ], + [ + "BcAbB", + "B", + 8 + ], + [ + "BcAbabBA", + "acb", + 12 + ], + [ + "BcAbabBBB", + "BA", + 14 + ], + [ + "BcAbabC", + "BBbaCAB", + 10 + ], + [ + "BcAbbcC", + "AaAcbC", + 8 + ], + [ + "BcAbc", + "BAC", + 5 + ], + [ + "BcAbc", + "BbbcbBabB", + 11 + ], + [ + "BcAbcAAC", + "A", + 14 + ], + [ + "BcAc", + "bC", + 6 + ], + [ + "BcAcAaACb", + "aAbBBB", + 14 + ], + [ + "BcAcB", + "caaAbbccB", + 12 + ], + [ + "BcAcaccb", + "cbAbAb", + 11 + ], + [ + "BcAcba", + "aA", + 10 + ], + [ + "BcAcc", + "BCaCBcAcC", + 9 + ], + [ + "BcB", + "AcCCAC", + 10 + ], + [ + "BcB", + "BBAcaAaB", + 10 + ], + [ + "BcB", + "BabAcacCA", + 14 + ], + [ + "BcB", + "aaBcAb", + 7 + ], + [ + "BcB", + "abcC", + 5 + ], + [ + "BcB", + "bcBBCbab", + 11 + ], + [ + "BcB", + "cAAc", + 8 + ], + [ + "BcB", + "ca", + 4 + ], + [ + "BcB", + "caBaaAAb", + 13 + ], + [ + "BcBA", + "CAabC", + 9 + ], + [ + "BcBA", + "baaC", + 7 + ], + [ + "BcBAAc", + "cBBaaabBB", + 14 + ], + [ + "BcBAB", + "aCaAaBb", + 9 + ], + [ + "BcBABCB", + "aaB", + 11 + ], + [ + "BcBAccAc", + "c", + 14 + ], + [ + "BcBBBA", + "ACc", + 11 + ], + [ + "BcBBC", + "cCABb", + 7 + ], + [ + "BcBBbb", + "bbBAa", + 8 + ], + [ + "BcBBbcAaA", + "CA", + 15 + ], + [ + "BcBC", + "c", + 6 + ], + [ + "BcBCA", + "cAaCC", + 8 + ], + [ + "BcBCAAAcc", + "abc", + 15 + ], + [ + "BcBCBBC", + "BbC", + 9 + ], + [ + "BcBCbAc", + "cBBCaC", + 8 + ], + [ + "BcBCcbccc", + "BcBC", + 10 + ], + [ + "BcBCccAa", + "acb", + 13 + ], + [ + "BcBa", + "aCB", + 5 + ], + [ + "BcBaAcAAc", + "bccBBBcBc", + 11 + ], + [ + "BcBaC", + "acBbcABAa", + 11 + ], + [ + "BcBab", + "CbCACC", + 10 + ], + [ + "BcBb", + "acAABAA", + 10 + ], + [ + "BcBbA", + "Ccba", + 5 + ], + [ + "BcBbAbABB", + "a", + 17 + ], + [ + "BcBbbCAa", + "baACcBCcC", + 14 + ], + [ + "BcBbbCa", + "AcCBAa", + 9 + ], + [ + "BcBbc", + "CcABb", + 6 + ], + [ + "BcBc", + "cBBcc", + 6 + ], + [ + "BcBcAbbc", + "babC", + 11 + ], + [ + "BcBcBc", + "cAAc", + 8 + ], + [ + "BcC", + "ABabcbC", + 8 + ], + [ + "BcC", + "Ac", + 4 + ], + [ + "BcC", + "C", + 4 + ], + [ + "BcC", + "acbcaAaa", + 13 + ], + [ + "BcC", + "bAbB", + 7 + ], + [ + "BcCA", + "ccaBaaAac", + 14 + ], + [ + "BcCAABBB", + "BCabBB", + 6 + ], + [ + "BcCAaAC", + "acCaB", + 8 + ], + [ + "BcCAaBc", + "Bcab", + 7 + ], + [ + "BcCAbB", + "ACaccCB", + 10 + ], + [ + "BcCAbaACc", + "aCAAcCBC", + 12 + ], + [ + "BcCAbcbA", + "bccAbCC", + 7 + ], + [ + "BcCAcA", + "BbB", + 10 + ], + [ + "BcCBABA", + "accb", + 10 + ], + [ + "BcCBAaC", + "b", + 13 + ], + [ + "BcCBbabcc", + "cCb", + 12 + ], + [ + "BcCBc", + "ba", + 9 + ], + [ + "BcCBcaAcc", + "B", + 16 + ], + [ + "BcCBcaCbC", + "CA", + 15 + ], + [ + "BcCCAA", + "caaA", + 7 + ], + [ + "BcCCBaaa", + "AaaCBb", + 12 + ], + [ + "BcCCCAA", + "b", + 13 + ], + [ + "BcCCaaaA", + "BccaAabBa", + 9 + ], + [ + "BcCCbCac", + "AcAa", + 12 + ], + [ + "BcCa", + "AB", + 8 + ], + [ + "BcCa", + "cB", + 6 + ], + [ + "BcCaACC", + "cbACaA", + 9 + ], + [ + "BcCaACCc", + "aaaCb", + 11 + ], + [ + "BcCaBbCAC", + "AbaAc", + 12 + ], + [ + "BcCaBc", + "CCAAB", + 8 + ], + [ + "BcCaCacc", + "CaCbbbc", + 10 + ], + [ + "BcCaaC", + "AcC", + 8 + ], + [ + "BcCb", + "aBacB", + 6 + ], + [ + "BcCbAcCb", + "CAA", + 12 + ], + [ + "BcCbCCCa", + "CBCC", + 9 + ], + [ + "BcCbaBabc", + "abcbB", + 13 + ], + [ + "BcCbbb", + "ccBCb", + 6 + ], + [ + "BcCc", + "bBb", + 7 + ], + [ + "BcCcBBb", + "aCCC", + 10 + ], + [ + "BcCcBcAb", + "aacbBbC", + 13 + ], + [ + "BcCca", + "CCcCaaB", + 8 + ], + [ + "Bca", + "AcbCBab", + 10 + ], + [ + "Bca", + "Bb", + 4 + ], + [ + "Bca", + "Bcc", + 2 + ], + [ + "Bca", + "CAAbA", + 9 + ], + [ + "Bca", + "CcBc", + 6 + ], + [ + "Bca", + "aAAccCBB", + 14 + ], + [ + "Bca", + "aCbbBBcCb", + 14 + ], + [ + "Bca", + "ac", + 4 + ], + [ + "Bca", + "c", + 4 + ], + [ + "BcaAAbACa", + "cAaacBB", + 13 + ], + [ + "BcaAaC", + "B", + 10 + ], + [ + "BcaB", + "A", + 7 + ], + [ + "BcaB", + "ABC", + 7 + ], + [ + "BcaB", + "AcAacA", + 8 + ], + [ + "BcaB", + "CAba", + 7 + ], + [ + "BcaB", + "cc", + 6 + ], + [ + "BcaBACC", + "aabAcbb", + 10 + ], + [ + "BcaBACbA", + "cB", + 12 + ], + [ + "BcaBAc", + "CAcBaCC", + 10 + ], + [ + "BcaBb", + "bABA", + 6 + ], + [ + "BcaBcab", + "aAaA", + 10 + ], + [ + "BcaC", + "abbAb", + 8 + ], + [ + "BcaC", + "ba", + 5 + ], + [ + "BcaC", + "ccaCBCB", + 8 + ], + [ + "BcaCBAbA", + "BA", + 12 + ], + [ + "BcaCC", + "CAbBbB", + 12 + ], + [ + "BcaCCbb", + "bbb", + 9 + ], + [ + "BcaCc", + "AaCABAACA", + 13 + ], + [ + "Bcaa", + "C", + 7 + ], + [ + "Bcaa", + "CbBABaa", + 8 + ], + [ + "Bcaa", + "cbbBcc", + 10 + ], + [ + "BcaaAc", + "AcaCCb", + 8 + ], + [ + "BcaaBBa", + "bBBCAAb", + 12 + ], + [ + "BcaaBcB", + "cCBbbAAcA", + 13 + ], + [ + "Bcaaba", + "ACbcA", + 10 + ], + [ + "Bcaabc", + "Bba", + 8 + ], + [ + "BcaacbcC", + "CBBBbCCA", + 12 + ], + [ + "Bcab", + "AcABabB", + 8 + ], + [ + "Bcab", + "abA", + 6 + ], + [ + "BcabB", + "BcbCc", + 6 + ], + [ + "BcabBB", + "BbAbbbA", + 7 + ], + [ + "BcabCA", + "b", + 10 + ], + [ + "BcabCac", + "BbAAaca", + 9 + ], + [ + "Bcaba", + "aCcbA", + 6 + ], + [ + "BcabaABA", + "CAbB", + 10 + ], + [ + "Bcac", + "CcCAbaaa", + 12 + ], + [ + "Bcac", + "ccc", + 4 + ], + [ + "BcacAC", + "abBc", + 9 + ], + [ + "BcacAaca", + "acbAbc", + 10 + ], + [ + "BcacCB", + "cbabacC", + 9 + ], + [ + "BcacaBC", + "ACCac", + 9 + ], + [ + "BcacabbA", + "Bcb", + 10 + ], + [ + "Bcacc", + "b", + 9 + ], + [ + "Bcb", + "AaAcacaB", + 13 + ], + [ + "Bcb", + "Cc", + 4 + ], + [ + "Bcb", + "aBBC", + 6 + ], + [ + "BcbAACc", + "aBBcA", + 11 + ], + [ + "BcbAAb", + "ab", + 9 + ], + [ + "BcbAC", + "AcC", + 6 + ], + [ + "BcbAaaacc", + "cc", + 14 + ], + [ + "BcbB", + "BbcbBbBC", + 8 + ], + [ + "BcbB", + "aB", + 6 + ], + [ + "BcbBcB", + "bCbb", + 7 + ], + [ + "BcbCA", + "bCc", + 6 + ], + [ + "BcbCAAba", + "CCaa", + 10 + ], + [ + "BcbCBCA", + "BcBa", + 7 + ], + [ + "BcbCC", + "b", + 8 + ], + [ + "BcbCCcc", + "Abb", + 12 + ], + [ + "BcbCabC", + "A", + 13 + ], + [ + "BcbCcB", + "cbaccCa", + 9 + ], + [ + "Bcba", + "ACa", + 5 + ], + [ + "Bcbb", + "baaAa", + 9 + ], + [ + "BcbbA", + "BBb", + 5 + ], + [ + "BcbbC", + "ccaBAABCC", + 12 + ], + [ + "BcbcA", + "bcBcAAcB", + 8 + ], + [ + "BcbcB", + "Ccc", + 6 + ], + [ + "Bcc", + "Ab", + 6 + ], + [ + "Bcc", + "BCAbacBc", + 10 + ], + [ + "Bcc", + "aacb", + 6 + ], + [ + "Bcc", + "baAa", + 7 + ], + [ + "BccABAbcA", + "Aba", + 13 + ], + [ + "BccACA", + "aa", + 10 + ], + [ + "BccAcAbbC", + "caC", + 13 + ], + [ + "BccBA", + "BACCAC", + 7 + ], + [ + "BccBAAbb", + "aac", + 14 + ], + [ + "BccBCbAA", + "BBCCC", + 10 + ], + [ + "BccBaAaa", + "AACAbbbbB", + 16 + ], + [ + "BccBac", + "CCabACa", + 10 + ], + [ + "BccC", + "ac", + 6 + ], + [ + "BccC", + "bCA", + 6 + ], + [ + "BccCa", + "caaBBaaB", + 14 + ], + [ + "BccCab", + "Cbcbac", + 8 + ], + [ + "BccCacBC", + "BBbA", + 13 + ], + [ + "BccCcA", + "BcCBCAB", + 6 + ], + [ + "Bcca", + "AAb", + 8 + ], + [ + "BccaA", + "cCC", + 7 + ], + [ + "BccaA", + "ccc", + 6 + ], + [ + "BccaBbB", + "AA", + 13 + ], + [ + "Bccac", + "CcbaCCa", + 9 + ], + [ + "Bccb", + "AcbC", + 6 + ], + [ + "BccbB", + "bbccA", + 7 + ], + [ + "BccbBCAA", + "AA", + 12 + ], + [ + "BccbBaCbb", + "CbcBBCAA", + 11 + ], + [ + "BccbacAAc", + "CAac", + 12 + ], + [ + "BccbbACa", + "acCAbCAc", + 10 + ], + [ + "BcccAC", + "cccBbBaac", + 12 + ], + [ + "BcccBB", + "bABCc", + 10 + ], + [ + "BcccBBb", + "Cbacbaa", + 11 + ], + [ + "C", + "A", + 2 + ], + [ + "C", + "AAA", + 6 + ], + [ + "C", + "AAAb", + 8 + ], + [ + "C", + "AAB", + 6 + ], + [ + "C", + "AAacba", + 11 + ], + [ + "C", + "AAbb", + 8 + ], + [ + "C", + "ABA", + 6 + ], + [ + "C", + "ABAB", + 8 + ], + [ + "C", + "ABAcBAabA", + 17 + ], + [ + "C", + "ABCB", + 6 + ], + [ + "C", + "ABCbbbBAC", + 16 + ], + [ + "C", + "ABabc", + 9 + ], + [ + "C", + "ACCCcAcAa", + 16 + ], + [ + "C", + "ACc", + 4 + ], + [ + "C", + "ACcbaABc", + 14 + ], + [ + "C", + "AaAAa", + 10 + ], + [ + "C", + "AaAa", + 8 + ], + [ + "C", + "AaAbcaBb", + 15 + ], + [ + "C", + "AabbbC", + 10 + ], + [ + "C", + "AacCCABaB", + 16 + ], + [ + "C", + "AacaaaB", + 13 + ], + [ + "C", + "Ab", + 4 + ], + [ + "C", + "AbBbBACab", + 16 + ], + [ + "C", + "AbBcCcBAb", + 16 + ], + [ + "C", + "AbC", + 4 + ], + [ + "C", + "AbCCaCbc", + 14 + ], + [ + "C", + "Abb", + 6 + ], + [ + "C", + "AbbCcBb", + 12 + ], + [ + "C", + "Acbc", + 7 + ], + [ + "C", + "B", + 2 + ], + [ + "C", + "BAAbAbCa", + 14 + ], + [ + "C", + "BAAc", + 7 + ], + [ + "C", + "BACcBbAcB", + 16 + ], + [ + "C", + "BBBaAcB", + 13 + ], + [ + "C", + "BBacaaA", + 13 + ], + [ + "C", + "BC", + 2 + ], + [ + "C", + "BCCbA", + 8 + ], + [ + "C", + "BCba", + 6 + ], + [ + "C", + "Ba", + 4 + ], + [ + "C", + "BaA", + 6 + ], + [ + "C", + "BaBCCBcb", + 14 + ], + [ + "C", + "BaBcbbCBA", + 16 + ], + [ + "C", + "BaaC", + 6 + ], + [ + "C", + "BabbcCBa", + 14 + ], + [ + "C", + "BacccCB", + 12 + ], + [ + "C", + "BbABc", + 9 + ], + [ + "C", + "BbAaAAC", + 12 + ], + [ + "C", + "BbBBcc", + 11 + ], + [ + "C", + "BbCBCB", + 10 + ], + [ + "C", + "BbcCCbAC", + 14 + ], + [ + "C", + "BcB", + 5 + ], + [ + "C", + "BcBBBbAaa", + 17 + ], + [ + "C", + "BcCAcacAB", + 16 + ], + [ + "C", + "BcCB", + 6 + ], + [ + "C", + "BcacCaB", + 12 + ], + [ + "C", + "BccAaa", + 11 + ], + [ + "C", + "BccaAa", + 11 + ], + [ + "C", + "C", + 0 + ], + [ + "C", + "CA", + 2 + ], + [ + "C", + "CAAbCa", + 10 + ], + [ + "C", + "CABBB", + 8 + ], + [ + "C", + "CAaAa", + 8 + ], + [ + "C", + "CAbAABb", + 12 + ], + [ + "C", + "CBBCaABbB", + 16 + ], + [ + "C", + "CBaacB", + 10 + ], + [ + "C", + "CBc", + 4 + ], + [ + "C", + "CC", + 2 + ], + [ + "C", + "CCA", + 4 + ], + [ + "C", + "CCBbccA", + 12 + ], + [ + "C", + "CCc", + 4 + ], + [ + "C", + "CCcbbCBCc", + 16 + ], + [ + "C", + "CCcc", + 6 + ], + [ + "C", + "CCccCaCa", + 14 + ], + [ + "C", + "Ca", + 2 + ], + [ + "C", + "CaA", + 4 + ], + [ + "C", + "Caab", + 6 + ], + [ + "C", + "Cacaacba", + 14 + ], + [ + "C", + "Cb", + 2 + ], + [ + "C", + "CbaCBcAb", + 14 + ], + [ + "C", + "CbbBCbC", + 12 + ], + [ + "C", + "Cc", + 2 + ], + [ + "C", + "CcAcCA", + 10 + ], + [ + "C", + "CcBBCbBB", + 14 + ], + [ + "C", + "CcCBBbB", + 12 + ], + [ + "C", + "a", + 2 + ], + [ + "C", + "aA", + 4 + ], + [ + "C", + "aAABBb", + 12 + ], + [ + "C", + "aACBaca", + 12 + ], + [ + "C", + "aAaCB", + 8 + ], + [ + "C", + "aAaaBcaB", + 15 + ], + [ + "C", + "aAabb", + 10 + ], + [ + "C", + "aAccAABB", + 15 + ], + [ + "C", + "aBAaa", + 10 + ], + [ + "C", + "aBbab", + 10 + ], + [ + "C", + "aCBccCbBc", + 16 + ], + [ + "C", + "aCCBcbcBc", + 16 + ], + [ + "C", + "aCCC", + 6 + ], + [ + "C", + "aCcB", + 6 + ], + [ + "C", + "aCcccA", + 10 + ], + [ + "C", + "aa", + 4 + ], + [ + "C", + "aaBA", + 8 + ], + [ + "C", + "aaBAbA", + 12 + ], + [ + "C", + "aaBabBB", + 14 + ], + [ + "C", + "aaCAC", + 8 + ], + [ + "C", + "aaCBb", + 8 + ], + [ + "C", + "aaaBcBBc", + 15 + ], + [ + "C", + "aaab", + 8 + ], + [ + "C", + "aab", + 6 + ], + [ + "C", + "aacCCabb", + 14 + ], + [ + "C", + "abBbAcaCc", + 16 + ], + [ + "C", + "abbbAaaC", + 14 + ], + [ + "C", + "abcBBB", + 11 + ], + [ + "C", + "ac", + 3 + ], + [ + "C", + "b", + 2 + ], + [ + "C", + "bAAAccb", + 13 + ], + [ + "C", + "bAAaCBaCa", + 16 + ], + [ + "C", + "bAaABACCb", + 16 + ], + [ + "C", + "bAbAcCAc", + 14 + ], + [ + "C", + "bBABA", + 10 + ], + [ + "C", + "bBB", + 6 + ], + [ + "C", + "bBacA", + 9 + ], + [ + "C", + "bBcbbCabb", + 16 + ], + [ + "C", + "bC", + 2 + ], + [ + "C", + "bCcAcACba", + 16 + ], + [ + "C", + "ba", + 4 + ], + [ + "C", + "baAA", + 8 + ], + [ + "C", + "baAba", + 10 + ], + [ + "C", + "baCABab", + 12 + ], + [ + "C", + "baaA", + 8 + ], + [ + "C", + "baaB", + 8 + ], + [ + "C", + "baaCbCb", + 12 + ], + [ + "C", + "bbABBCA", + 12 + ], + [ + "C", + "bbABcCb", + 12 + ], + [ + "C", + "bbCab", + 8 + ], + [ + "C", + "bbacCaabC", + 16 + ], + [ + "C", + "bbbcaAb", + 13 + ], + [ + "C", + "bc", + 3 + ], + [ + "C", + "bcAca", + 9 + ], + [ + "C", + "bcBAABAAC", + 16 + ], + [ + "C", + "bcBcA", + 9 + ], + [ + "C", + "bcC", + 4 + ], + [ + "C", + "bcCAb", + 8 + ], + [ + "C", + "bcaAb", + 9 + ], + [ + "C", + "bcacBAC", + 12 + ], + [ + "C", + "bcb", + 5 + ], + [ + "C", + "bcbBba", + 11 + ], + [ + "C", + "bcbacaAA", + 15 + ], + [ + "C", + "bccC", + 6 + ], + [ + "C", + "bccccCA", + 12 + ], + [ + "C", + "c", + 1 + ], + [ + "C", + "cAc", + 5 + ], + [ + "C", + "cAcBCbCb", + 14 + ], + [ + "C", + "cAcaABCA", + 14 + ], + [ + "C", + "cBAA", + 7 + ], + [ + "C", + "cBBB", + 7 + ], + [ + "C", + "cBc", + 5 + ], + [ + "C", + "cBccbAA", + 13 + ], + [ + "C", + "cC", + 2 + ], + [ + "C", + "cCBAAB", + 10 + ], + [ + "C", + "cCaACAAC", + 14 + ], + [ + "C", + "cCbA", + 6 + ], + [ + "C", + "cCbbABa", + 12 + ], + [ + "C", + "cCcabCbBb", + 16 + ], + [ + "C", + "ca", + 3 + ], + [ + "C", + "caCACCCaB", + 16 + ], + [ + "C", + "cabCa", + 8 + ], + [ + "C", + "cacACaBB", + 14 + ], + [ + "C", + "cacBaACc", + 14 + ], + [ + "C", + "cbACabc", + 12 + ], + [ + "C", + "cbCCB", + 8 + ], + [ + "C", + "cbcC", + 6 + ], + [ + "C", + "cc", + 3 + ], + [ + "C", + "ccBAbBBC", + 14 + ], + [ + "C", + "ccBaC", + 8 + ], + [ + "C", + "ccaCbbCbb", + 16 + ], + [ + "C", + "ccabC", + 8 + ], + [ + "C", + "ccbBbCCc", + 14 + ], + [ + "CA", + "A", + 2 + ], + [ + "CA", + "AAa", + 4 + ], + [ + "CA", + "Aaacbb", + 11 + ], + [ + "CA", + "AcC", + 5 + ], + [ + "CA", + "BBaB", + 7 + ], + [ + "CA", + "BcAcbBC", + 11 + ], + [ + "CA", + "C", + 2 + ], + [ + "CA", + "CBCAa", + 6 + ], + [ + "CA", + "CacbbBaa", + 13 + ], + [ + "CA", + "CcBcBAB", + 10 + ], + [ + "CA", + "CcbCaBB", + 11 + ], + [ + "CA", + "a", + 3 + ], + [ + "CA", + "aAABAaC", + 12 + ], + [ + "CA", + "aABBa", + 8 + ], + [ + "CA", + "abbCC", + 8 + ], + [ + "CA", + "acbb", + 7 + ], + [ + "CA", + "bAbAAcbA", + 13 + ], + [ + "CA", + "bAcBcACC", + 13 + ], + [ + "CA", + "bCBaBBaB", + 13 + ], + [ + "CA", + "bbbB", + 8 + ], + [ + "CA", + "cAaaaA", + 9 + ], + [ + "CA", + "caCBCcaaA", + 14 + ], + [ + "CAA", + "CCbc", + 6 + ], + [ + "CAA", + "CbCcba", + 9 + ], + [ + "CAA", + "bb", + 6 + ], + [ + "CAA", + "c", + 5 + ], + [ + "CAA", + "cACAaa", + 7 + ], + [ + "CAA", + "cAaabbacA", + 13 + ], + [ + "CAAA", + "bb", + 8 + ], + [ + "CAAAAAcCB", + "bC", + 16 + ], + [ + "CAAAB", + "ba", + 9 + ], + [ + "CAAABaBAc", + "CaaC", + 12 + ], + [ + "CAAACa", + "AAcbAAc", + 9 + ], + [ + "CAAACaAC", + "aABBcbcBa", + 15 + ], + [ + "CAAAaBAa", + "BCBc", + 14 + ], + [ + "CAAAba", + "CacBaB", + 8 + ], + [ + "CAAAbb", + "cCaCb", + 8 + ], + [ + "CAAB", + "CbcCbBBA", + 12 + ], + [ + "CAABAAcBC", + "bccb", + 14 + ], + [ + "CAABAAcbB", + "ABBa", + 13 + ], + [ + "CAABCaaBa", + "aBCACcBca", + 12 + ], + [ + "CAABCcAAa", + "ccCB", + 15 + ], + [ + "CAABbaA", + "AbBaAac", + 10 + ], + [ + "CAAC", + "cacABc", + 7 + ], + [ + "CAACAAC", + "Ab", + 12 + ], + [ + "CAACAbca", + "Bb", + 14 + ], + [ + "CAACCAc", + "CAAB", + 8 + ], + [ + "CAACb", + "CA", + 6 + ], + [ + "CAAa", + "cBCC", + 7 + ], + [ + "CAAaBaAC", + "AaccBBB", + 13 + ], + [ + "CAAaaA", + "CaAaACca", + 7 + ], + [ + "CAAab", + "b", + 8 + ], + [ + "CAAabac", + "Accbbc", + 8 + ], + [ + "CAAbCbCcC", + "B", + 17 + ], + [ + "CAAbb", + "caC", + 8 + ], + [ + "CAAbbAbb", + "BC", + 15 + ], + [ + "CAAcBB", + "aCBCbAAb", + 13 + ], + [ + "CAAccAcC", + "abA", + 13 + ], + [ + "CAB", + "ABabCcc", + 12 + ], + [ + "CAB", + "ABccbC", + 10 + ], + [ + "CAB", + "CABba", + 4 + ], + [ + "CAB", + "CcbB", + 4 + ], + [ + "CAB", + "aababa", + 10 + ], + [ + "CAB", + "bC", + 6 + ], + [ + "CAB", + "cAbbABAac", + 13 + ], + [ + "CABA", + "CaabCCc", + 10 + ], + [ + "CABAAa", + "abC", + 10 + ], + [ + "CABACacA", + "cAbaaABC", + 10 + ], + [ + "CABACcA", + "B", + 12 + ], + [ + "CABAa", + "aac", + 8 + ], + [ + "CABAcBa", + "b", + 13 + ], + [ + "CABBAa", + "bbBcabcC", + 13 + ], + [ + "CABBBAa", + "B", + 12 + ], + [ + "CABBBCaa", + "ACb", + 12 + ], + [ + "CABBBb", + "cacaAACa", + 14 + ], + [ + "CABC", + "cCbacA", + 9 + ], + [ + "CABCAcaC", + "B", + 14 + ], + [ + "CABa", + "B", + 6 + ], + [ + "CABaCc", + "BCaaaAAcb", + 11 + ], + [ + "CABab", + "baB", + 6 + ], + [ + "CABacBA", + "BaACb", + 10 + ], + [ + "CABb", + "bCcBaCba", + 10 + ], + [ + "CABbABcBA", + "aBaAccabA", + 10 + ], + [ + "CABbbC", + "CbACCAcc", + 11 + ], + [ + "CABcAaAb", + "bb", + 13 + ], + [ + "CABcaa", + "C", + 10 + ], + [ + "CABcaa", + "aCaBABAab", + 10 + ], + [ + "CABcabCAa", + "AcbaBcCA", + 11 + ], + [ + "CABcbCAc", + "ABAcc", + 9 + ], + [ + "CABcbbA", + "BBbcA", + 8 + ], + [ + "CABcbcacA", + "cb", + 14 + ], + [ + "CAC", + "aCAAaABb", + 12 + ], + [ + "CAC", + "abCCACaBc", + 12 + ], + [ + "CAC", + "bbcbB", + 9 + ], + [ + "CAC", + "caBAa", + 7 + ], + [ + "CAC", + "ccBaBcb", + 11 + ], + [ + "CACAACccb", + "bc", + 16 + ], + [ + "CACABBA", + "cCACAcCcC", + 10 + ], + [ + "CACACAcBB", + "aBAACCc", + 12 + ], + [ + "CACAabc", + "cbAaBbbbB", + 13 + ], + [ + "CACAcaAC", + "ACcACc", + 8 + ], + [ + "CACAcbC", + "Cc", + 10 + ], + [ + "CACB", + "Cbc", + 5 + ], + [ + "CACBb", + "C", + 8 + ], + [ + "CACC", + "bCa", + 6 + ], + [ + "CACCAAB", + "bACabAC", + 8 + ], + [ + "CACCAb", + "abBBB", + 10 + ], + [ + "CACCCBA", + "cabaac", + 12 + ], + [ + "CACCc", + "ba", + 9 + ], + [ + "CACaAcc", + "acaBbCbb", + 13 + ], + [ + "CACaCBBc", + "a", + 14 + ], + [ + "CACaabcBb", + "aCabba", + 10 + ], + [ + "CACacaABb", + "b", + 16 + ], + [ + "CACb", + "ABbb", + 6 + ], + [ + "CACb", + "AabbaCa", + 11 + ], + [ + "CACbA", + "bCbbC", + 8 + ], + [ + "CACbaCB", + "caacaaC", + 9 + ], + [ + "CACbaaCa", + "bBacacB", + 12 + ], + [ + "CACbbBBc", + "Bc", + 12 + ], + [ + "CACbc", + "Cc", + 6 + ], + [ + "CACbcAcac", + "cCAcA", + 10 + ], + [ + "CACbcba", + "caABaCb", + 10 + ], + [ + "CACcBabCc", + "baAbbaBB", + 13 + ], + [ + "CACcCacC", + "ABcC", + 10 + ], + [ + "CACccCAC", + "B", + 16 + ], + [ + "CAa", + "Ab", + 4 + ], + [ + "CAa", + "CabcCc", + 9 + ], + [ + "CAa", + "aaCAbaBc", + 10 + ], + [ + "CAa", + "bABABaCA", + 12 + ], + [ + "CAa", + "bBAaB", + 6 + ], + [ + "CAa", + "bca", + 4 + ], + [ + "CAa", + "cbC", + 5 + ], + [ + "CAaAAaA", + "abAbbcbaC", + 14 + ], + [ + "CAaAAbaaB", + "CAcBB", + 11 + ], + [ + "CAaAcb", + "bBCBB", + 11 + ], + [ + "CAaBAA", + "AacAcBABB", + 11 + ], + [ + "CAaBB", + "Cc", + 8 + ], + [ + "CAaBBACa", + "CAaacBccC", + 9 + ], + [ + "CAaBC", + "b", + 9 + ], + [ + "CAaBbbaBA", + "BBB", + 13 + ], + [ + "CAaC", + "AaBCacAba", + 14 + ], + [ + "CAaC", + "BcccCbBb", + 13 + ], + [ + "CAaCBbcab", + "CbC", + 13 + ], + [ + "CAaCc", + "AA", + 7 + ], + [ + "CAaCcabB", + "cBABCb", + 11 + ], + [ + "CAaCccCc", + "A", + 14 + ], + [ + "CAaa", + "bcABBaAb", + 10 + ], + [ + "CAaa", + "cbabABAC", + 12 + ], + [ + "CAaaB", + "b", + 9 + ], + [ + "CAaabBcC", + "a", + 14 + ], + [ + "CAaabbCac", + "bAC", + 14 + ], + [ + "CAaabcaB", + "cabCacbaA", + 12 + ], + [ + "CAabABbAa", + "bcbaCa", + 13 + ], + [ + "CAabac", + "baaABbB", + 10 + ], + [ + "CAabb", + "b", + 8 + ], + [ + "CAabb", + "cACACBaBB", + 10 + ], + [ + "CAac", + "aaB", + 5 + ], + [ + "CAac", + "cccBB", + 9 + ], + [ + "CAacAB", + "a", + 10 + ], + [ + "CAaccC", + "cacbc", + 6 + ], + [ + "CAb", + "ACCCAcaA", + 12 + ], + [ + "CAb", + "Aca", + 6 + ], + [ + "CAb", + "BCcBBAA", + 10 + ], + [ + "CAb", + "C", + 4 + ], + [ + "CAb", + "CCAcbAB", + 8 + ], + [ + "CAb", + "CcCbCBC", + 10 + ], + [ + "CAb", + "acAc", + 5 + ], + [ + "CAb", + "bab", + 3 + ], + [ + "CAb", + "cA", + 3 + ], + [ + "CAbAAaAA", + "abc", + 13 + ], + [ + "CAbAc", + "ABBCCB", + 10 + ], + [ + "CAbB", + "acC", + 7 + ], + [ + "CAbBBBB", + "BCcaBbabB", + 10 + ], + [ + "CAbBCCBAC", + "baA", + 14 + ], + [ + "CAbBab", + "cbABcBc", + 10 + ], + [ + "CAbBc", + "bBcAcCA", + 11 + ], + [ + "CAbBc", + "bCAcbba", + 7 + ], + [ + "CAbC", + "AaAc", + 6 + ], + [ + "CAbC", + "cBAC", + 5 + ], + [ + "CAbCBaBb", + "cAbcBa", + 6 + ], + [ + "CAbCCC", + "c", + 11 + ], + [ + "CAbCabbA", + "BbAABACba", + 12 + ], + [ + "CAbCcc", + "babBA", + 9 + ], + [ + "CAba", + "abbB", + 6 + ], + [ + "CAbaAbBBC", + "CbBBAbB", + 9 + ], + [ + "CAbaAcCCC", + "AcbB", + 14 + ], + [ + "CAbaBb", + "A", + 10 + ], + [ + "CAbaa", + "cc", + 9 + ], + [ + "CAbacbba", + "cBCccabA", + 10 + ], + [ + "CAbbAA", + "BAAaCbC", + 12 + ], + [ + "CAbbAAcC", + "CBBACbBCB", + 12 + ], + [ + "CAbbBCcB", + "Abca", + 10 + ], + [ + "CAbbBbC", + "ABcaca", + 11 + ], + [ + "CAbbbAC", + "bcB", + 11 + ], + [ + "CAbbcCABA", + "CbB", + 12 + ], + [ + "CAbc", + "B", + 7 + ], + [ + "CAbcA", + "CAcaccACb", + 10 + ], + [ + "CAbcACCB", + "BB", + 13 + ], + [ + "CAbcBAa", + "bccBACB", + 10 + ], + [ + "CAbcCca", + "cAc", + 9 + ], + [ + "CAbcaBbca", + "ccaacBaaa", + 12 + ], + [ + "CAc", + "AAcacbcC", + 12 + ], + [ + "CAc", + "AbbAbbcc", + 12 + ], + [ + "CAc", + "BAB", + 4 + ], + [ + "CAc", + "ab", + 5 + ], + [ + "CAc", + "b", + 6 + ], + [ + "CAc", + "bbaaac", + 9 + ], + [ + "CAcAaCcaC", + "AAa", + 12 + ], + [ + "CAcAbaaA", + "ccBcBc", + 12 + ], + [ + "CAcAcC", + "BAbCb", + 9 + ], + [ + "CAcAca", + "CCbb", + 9 + ], + [ + "CAcAcbbAc", + "Cca", + 13 + ], + [ + "CAcB", + "cBcaaCcB", + 10 + ], + [ + "CAcBbCccb", + "BBAbAbAB", + 15 + ], + [ + "CAcBbbAaA", + "aACbbCbaa", + 9 + ], + [ + "CAcBbcbCa", + "bcBc", + 12 + ], + [ + "CAcBcBC", + "abCaCb", + 11 + ], + [ + "CAcC", + "CBcB", + 4 + ], + [ + "CAcCACCA", + "cAAa", + 10 + ], + [ + "CAcCaCBCC", + "aac", + 14 + ], + [ + "CAca", + "AaBACbAab", + 13 + ], + [ + "CAcaABcab", + "aCCbC", + 14 + ], + [ + "CAcaaa", + "bbccA", + 9 + ], + [ + "CAcaacBB", + "c", + 14 + ], + [ + "CAcb", + "B", + 7 + ], + [ + "CAcb", + "aBCBAb", + 8 + ], + [ + "CAcbBA", + "bBAaba", + 9 + ], + [ + "CAcbBB", + "CCcCBA", + 6 + ], + [ + "CAcbBacb", + "AbbbB", + 10 + ], + [ + "CAcbCCaaC", + "bccB", + 14 + ], + [ + "CAcbCbc", + "bAcCA", + 8 + ], + [ + "CAcbbabC", + "abAccCaac", + 11 + ], + [ + "CAcbcA", + "BBca", + 8 + ], + [ + "CAcbcB", + "Ab", + 8 + ], + [ + "CAcc", + "b", + 8 + ], + [ + "CAccAaAcc", + "bccbAB", + 12 + ], + [ + "CAccBaAC", + "abbAAaB", + 13 + ], + [ + "CAccBaaCc", + "BCAb", + 15 + ], + [ + "CAccBbA", + "bcBbBcBc", + 13 + ], + [ + "CAccac", + "aAc", + 8 + ], + [ + "CB", + "A", + 4 + ], + [ + "CB", + "ABac", + 6 + ], + [ + "CB", + "AC", + 4 + ], + [ + "CB", + "ACbbcbb", + 11 + ], + [ + "CB", + "ACcCCBAC", + 12 + ], + [ + "CB", + "AaAAcBc", + 11 + ], + [ + "CB", + "AaBCab", + 9 + ], + [ + "CB", + "BCc", + 4 + ], + [ + "CB", + "BaCaB", + 6 + ], + [ + "CB", + "BccbcabCB", + 14 + ], + [ + "CB", + "C", + 2 + ], + [ + "CB", + "CAAAb", + 7 + ], + [ + "CB", + "CCba", + 5 + ], + [ + "CB", + "CaAcA", + 8 + ], + [ + "CB", + "CcCaAccb", + 13 + ], + [ + "CB", + "a", + 4 + ], + [ + "CB", + "aAa", + 6 + ], + [ + "CB", + "aBCBaBbC", + 12 + ], + [ + "CB", + "aCbcAc", + 9 + ], + [ + "CB", + "ac", + 4 + ], + [ + "CB", + "bAa", + 6 + ], + [ + "CB", + "bBAAbcb", + 12 + ], + [ + "CB", + "bCB", + 2 + ], + [ + "CB", + "bCaCCcaCA", + 16 + ], + [ + "CB", + "ba", + 4 + ], + [ + "CB", + "baBCcCc", + 12 + ], + [ + "CB", + "bbcbCB", + 8 + ], + [ + "CB", + "bcaab", + 8 + ], + [ + "CB", + "c", + 3 + ], + [ + "CB", + "cACca", + 8 + ], + [ + "CB", + "cBCbAB", + 8 + ], + [ + "CB", + "cCB", + 2 + ], + [ + "CB", + "cbb", + 4 + ], + [ + "CB", + "cbbBbACCA", + 15 + ], + [ + "CBA", + "ba", + 4 + ], + [ + "CBA", + "cbcBb", + 7 + ], + [ + "CBAA", + "ABBaBcB", + 11 + ], + [ + "CBAA", + "Ba", + 5 + ], + [ + "CBAA", + "bcc", + 7 + ], + [ + "CBAABa", + "BAaBA", + 4 + ], + [ + "CBAAC", + "CBAac", + 2 + ], + [ + "CBAAa", + "cccbAb", + 9 + ], + [ + "CBAAaac", + "bcAAb", + 10 + ], + [ + "CBAAbCc", + "bbaABBB", + 9 + ], + [ + "CBAAbbBC", + "CbBAaAc", + 10 + ], + [ + "CBAAc", + "AAA", + 6 + ], + [ + "CBAAc", + "bCbBbAAaC", + 9 + ], + [ + "CBAB", + "A", + 6 + ], + [ + "CBABAbcBA", + "b", + 16 + ], + [ + "CBABAcBc", + "cAb", + 12 + ], + [ + "CBABCacb", + "aCCbbBABA", + 14 + ], + [ + "CBABaa", + "cBbcCcc", + 11 + ], + [ + "CBABbbCa", + "BbAaA", + 11 + ], + [ + "CBABbcCCC", + "cCAC", + 12 + ], + [ + "CBABc", + "cCc", + 7 + ], + [ + "CBABccBbc", + "caAaaACbb", + 13 + ], + [ + "CBACAA", + "CCc", + 8 + ], + [ + "CBACAcC", + "aCbbc", + 10 + ], + [ + "CBACa", + "BACaBBaB", + 10 + ], + [ + "CBACbcB", + "a", + 13 + ], + [ + "CBACc", + "baCCCA", + 9 + ], + [ + "CBACcAccA", + "aAb", + 15 + ], + [ + "CBAaAC", + "ccbC", + 9 + ], + [ + "CBAaBaC", + "bCccccCb", + 14 + ], + [ + "CBAaCB", + "acabB", + 8 + ], + [ + "CBAaCa", + "Cabb", + 8 + ], + [ + "CBAaCc", + "cBBBBBaC", + 11 + ], + [ + "CBAabb", + "bbCabaBa", + 10 + ], + [ + "CBAacCa", + "Bccbacb", + 11 + ], + [ + "CBAb", + "cCAcbc", + 7 + ], + [ + "CBAbCcaB", + "aC", + 13 + ], + [ + "CBAba", + "CbbabA", + 5 + ], + [ + "CBAbabb", + "BABa", + 7 + ], + [ + "CBAbba", + "ba", + 8 + ], + [ + "CBAcAAbcb", + "BBBBBbABA", + 15 + ], + [ + "CBAcC", + "acbabBA", + 11 + ], + [ + "CBAccB", + "cb", + 9 + ], + [ + "CBAccab", + "cbB", + 11 + ], + [ + "CBB", + "Aa", + 6 + ], + [ + "CBB", + "BbAaC", + 9 + ], + [ + "CBB", + "CB", + 2 + ], + [ + "CBB", + "CCA", + 4 + ], + [ + "CBB", + "CcbCb", + 6 + ], + [ + "CBB", + "baBB", + 4 + ], + [ + "CBB", + "cAcBBccA", + 11 + ], + [ + "CBB", + "cBccaB", + 7 + ], + [ + "CBBABB", + "BbBb", + 6 + ], + [ + "CBBABC", + "AABcaac", + 10 + ], + [ + "CBBAbACb", + "CCBCbAbcB", + 8 + ], + [ + "CBBBA", + "bB", + 7 + ], + [ + "CBBBBaAC", + "ca", + 13 + ], + [ + "CBBBBbbcC", + "BaAbCaB", + 14 + ], + [ + "CBBBb", + "bCbaBBAb", + 7 + ], + [ + "CBBBbCbcA", + "ABCCcABc", + 13 + ], + [ + "CBBC", + "ACaca", + 8 + ], + [ + "CBBC", + "cB", + 5 + ], + [ + "CBBCAAB", + "b", + 13 + ], + [ + "CBBCAb", + "CBA", + 6 + ], + [ + "CBBCCAB", + "AbCa", + 10 + ], + [ + "CBBCCa", + "c", + 11 + ], + [ + "CBBCabAa", + "Cca", + 11 + ], + [ + "CBBaCc", + "CbbA", + 7 + ], + [ + "CBBab", + "acBCcA", + 9 + ], + [ + "CBBabb", + "BBCcBb", + 7 + ], + [ + "CBBacBacB", + "caCCccBc", + 12 + ], + [ + "CBBbAb", + "Bbab", + 5 + ], + [ + "CBBba", + "bcCcb", + 9 + ], + [ + "CBBbaAcbc", + "ABcABaAAc", + 11 + ], + [ + "CBBbbbabc", + "baAaBC", + 12 + ], + [ + "CBBbcaaC", + "bABABABB", + 13 + ], + [ + "CBBc", + "abCABc", + 6 + ], + [ + "CBBcACB", + "abBbC", + 9 + ], + [ + "CBBcBcc", + "A", + 14 + ], + [ + "CBBcbA", + "ccbBAca", + 9 + ], + [ + "CBBcbaBc", + "C", + 14 + ], + [ + "CBBcbaC", + "bBcAAbaaC", + 9 + ], + [ + "CBBccBCCB", + "bacCC", + 11 + ], + [ + "CBBccc", + "aBabc", + 8 + ], + [ + "CBC", + "ACB", + 4 + ], + [ + "CBC", + "CAbCabB", + 9 + ], + [ + "CBC", + "aCaAaAC", + 10 + ], + [ + "CBCAA", + "C", + 8 + ], + [ + "CBCAABa", + "BBcCbBa", + 7 + ], + [ + "CBCAACB", + "bBBcAAB", + 7 + ], + [ + "CBCACAa", + "ABbA", + 10 + ], + [ + "CBCAaCA", + "BbaAbac", + 10 + ], + [ + "CBCAacCc", + "cCb", + 12 + ], + [ + "CBCB", + "aAAaA", + 10 + ], + [ + "CBCBBA", + "acc", + 11 + ], + [ + "CBCBBCAA", + "ABC", + 12 + ], + [ + "CBCBC", + "aBccbCB", + 8 + ], + [ + "CBCBCC", + "BAbc", + 8 + ], + [ + "CBCC", + "CbaaA", + 7 + ], + [ + "CBCCBC", + "aACAA", + 10 + ], + [ + "CBCCBCcCb", + "Ba", + 16 + ], + [ + "CBCCCB", + "cacbAbbaA", + 15 + ], + [ + "CBCCCbaB", + "cacAbc", + 12 + ], + [ + "CBCCacb", + "a", + 12 + ], + [ + "CBCCbcc", + "BbbBcbCBc", + 11 + ], + [ + "CBCCcCbA", + "CBaAa", + 11 + ], + [ + "CBCa", + "aaAbbabA", + 13 + ], + [ + "CBCa", + "b", + 7 + ], + [ + "CBCaA", + "ab", + 8 + ], + [ + "CBCaAaBaa", + "acBbAa", + 12 + ], + [ + "CBCaB", + "caa", + 7 + ], + [ + "CBCacBBBB", + "BcabACCb", + 12 + ], + [ + "CBCb", + "AabACCa", + 11 + ], + [ + "CBCb", + "aABc", + 7 + ], + [ + "CBCbBa", + "abaCaB", + 9 + ], + [ + "CBCbbc", + "CcBCBCcbA", + 9 + ], + [ + "CBCbccaA", + "AbCbbCba", + 9 + ], + [ + "CBCc", + "bbcCBBAcb", + 12 + ], + [ + "CBCcB", + "BAa", + 8 + ], + [ + "CBCcBbb", + "ccaCBbA", + 8 + ], + [ + "CBCcccacB", + "BA", + 15 + ], + [ + "CBa", + "ACaba", + 5 + ], + [ + "CBa", + "CAaB", + 4 + ], + [ + "CBa", + "CBBCccc", + 10 + ], + [ + "CBa", + "CacAccB", + 11 + ], + [ + "CBa", + "c", + 5 + ], + [ + "CBaAAa", + "caCcaBAA", + 9 + ], + [ + "CBaAC", + "CBb", + 6 + ], + [ + "CBaAbaaAA", + "CbbcC", + 13 + ], + [ + "CBaB", + "aabBAbbC", + 12 + ], + [ + "CBaBBAa", + "AaAcA", + 10 + ], + [ + "CBaBCABC", + "AAA", + 13 + ], + [ + "CBaBaCcB", + "cBaAbBAAa", + 12 + ], + [ + "CBaBaa", + "AAB", + 9 + ], + [ + "CBaCAbC", + "BbCaCC", + 7 + ], + [ + "CBaCBba", + "bcABB", + 10 + ], + [ + "CBaCCAB", + "cBcBAcA", + 10 + ], + [ + "CBaCabccB", + "Bba", + 14 + ], + [ + "CBaaA", + "AacbaC", + 10 + ], + [ + "CBaaAcac", + "aacbcbACc", + 13 + ], + [ + "CBaaB", + "CbaAcB", + 4 + ], + [ + "CBaaBc", + "Ba", + 8 + ], + [ + "CBaaCaCa", + "c", + 15 + ], + [ + "CBaaaBB", + "B", + 12 + ], + [ + "CBaab", + "BaabBcba", + 10 + ], + [ + "CBaab", + "bBB", + 7 + ], + [ + "CBaabAB", + "CBCC", + 10 + ], + [ + "CBaacACCC", + "a", + 16 + ], + [ + "CBab", + "CB", + 4 + ], + [ + "CBab", + "aBcc", + 6 + ], + [ + "CBabACCaA", + "A", + 16 + ], + [ + "CBabCbbaC", + "AcbAc", + 12 + ], + [ + "CBacA", + "acBCCaCB", + 10 + ], + [ + "CBacaCBCB", + "aB", + 14 + ], + [ + "CBacbacB", + "CaBa", + 9 + ], + [ + "CBb", + "Cbb", + 1 + ], + [ + "CBb", + "a", + 6 + ], + [ + "CBb", + "bBbcc", + 6 + ], + [ + "CBb", + "bCaaaA", + 10 + ], + [ + "CBbA", + "bAaCbBC", + 10 + ], + [ + "CBbAAa", + "aabB", + 10 + ], + [ + "CBbAB", + "A", + 8 + ], + [ + "CBbAB", + "bbb", + 6 + ], + [ + "CBbACca", + "CbCAcB", + 7 + ], + [ + "CBbACcbC", + "bCcbBAb", + 12 + ], + [ + "CBbBB", + "C", + 8 + ], + [ + "CBbBB", + "CBCBcCBa", + 8 + ], + [ + "CBbBBCaBB", + "AbAca", + 13 + ], + [ + "CBbCA", + "aca", + 8 + ], + [ + "CBbCCB", + "BAbC", + 8 + ], + [ + "CBbCCCa", + "Ca", + 10 + ], + [ + "CBbCCb", + "CACbBBb", + 8 + ], + [ + "CBbCbbBc", + "ABaA", + 14 + ], + [ + "CBbaAcAAc", + "ccAACB", + 12 + ], + [ + "CBbaAca", + "bB", + 12 + ], + [ + "CBbaB", + "B", + 8 + ], + [ + "CBbaBBCaC", + "baaCcA", + 12 + ], + [ + "CBbaC", + "c", + 9 + ], + [ + "CBbaCa", + "cbbcAa", + 6 + ], + [ + "CBbaCbB", + "AcCcACbA", + 10 + ], + [ + "CBbabC", + "abB", + 8 + ], + [ + "CBbb", + "C", + 6 + ], + [ + "CBbb", + "a", + 8 + ], + [ + "CBbbbaB", + "B", + 12 + ], + [ + "CBbc", + "BaAABc", + 9 + ], + [ + "CBbcBAAB", + "cAbCAA", + 8 + ], + [ + "CBbcbb", + "cBCaC", + 8 + ], + [ + "CBc", + "Bcab", + 6 + ], + [ + "CBc", + "CBAAacc", + 8 + ], + [ + "CBc", + "abaCa", + 8 + ], + [ + "CBc", + "cAabccaaA", + 14 + ], + [ + "CBcA", + "CCA", + 3 + ], + [ + "CBcAAaccC", + "abBcAbaBC", + 10 + ], + [ + "CBcAaCCCb", + "aB", + 15 + ], + [ + "CBcAbAA", + "BabCcAAc", + 11 + ], + [ + "CBcAcB", + "CbbAAA", + 7 + ], + [ + "CBcB", + "a", + 8 + ], + [ + "CBcB", + "bcCBCCcbb", + 11 + ], + [ + "CBcBA", + "cBbCb", + 7 + ], + [ + "CBcBBABcc", + "bbBcabA", + 13 + ], + [ + "CBcBC", + "cAbCAAbcA", + 13 + ], + [ + "CBcBaaACB", + "cCc", + 14 + ], + [ + "CBcBb", + "c", + 8 + ], + [ + "CBcC", + "bCBBbBa", + 10 + ], + [ + "CBcC", + "c", + 6 + ], + [ + "CBcCC", + "aB", + 8 + ], + [ + "CBca", + "cC", + 6 + ], + [ + "CBcaAa", + "A", + 10 + ], + [ + "CBcaAba", + "AaAAaaCaA", + 13 + ], + [ + "CBcaBCc", + "AcBcb", + 9 + ], + [ + "CBcabbbba", + "bCCBc", + 15 + ], + [ + "CBcacCbCC", + "bCAaab", + 13 + ], + [ + "CBcb", + "Acb", + 4 + ], + [ + "CBcb", + "CbcABCA", + 8 + ], + [ + "CBcb", + "cBAac", + 7 + ], + [ + "CBcbCbc", + "cBBaBc", + 7 + ], + [ + "CBcbCcaBc", + "BAACAaC", + 11 + ], + [ + "CBcba", + "abCA", + 7 + ], + [ + "CBcbab", + "ABBabBC", + 9 + ], + [ + "CBcbbaC", + "ABcCa", + 8 + ], + [ + "CBcbcAAA", + "aaAbb", + 14 + ], + [ + "CBcbcbC", + "c", + 12 + ], + [ + "CBccaC", + "CAAa", + 8 + ], + [ + "CBccaCaaa", + "ccbBabcBB", + 15 + ], + [ + "CBccac", + "aB", + 10 + ], + [ + "CBccbaAbb", + "bBaacaC", + 14 + ], + [ + "CBccbbc", + "ACaAaCB", + 13 + ], + [ + "CC", + "AA", + 4 + ], + [ + "CC", + "AAaacAc", + 12 + ], + [ + "CC", + "ACACbCABB", + 14 + ], + [ + "CC", + "ACBaCAb", + 10 + ], + [ + "CC", + "ACaaB", + 8 + ], + [ + "CC", + "ACcCAaabb", + 14 + ], + [ + "CC", + "AacCBBc", + 11 + ], + [ + "CC", + "BaAACABCC", + 14 + ], + [ + "CC", + "BaBcaCbb", + 13 + ], + [ + "CC", + "Bc", + 3 + ], + [ + "CC", + "CBC", + 2 + ], + [ + "CC", + "CCAAAbab", + 12 + ], + [ + "CC", + "CCc", + 2 + ], + [ + "CC", + "Cb", + 2 + ], + [ + "CC", + "CbbBb", + 8 + ], + [ + "CC", + "CcAc", + 5 + ], + [ + "CC", + "a", + 4 + ], + [ + "CC", + "aACcC", + 6 + ], + [ + "CC", + "aBC", + 4 + ], + [ + "CC", + "aBbc", + 7 + ], + [ + "CC", + "aa", + 4 + ], + [ + "CC", + "bA", + 4 + ], + [ + "CC", + "c", + 3 + ], + [ + "CC", + "cBBB", + 7 + ], + [ + "CC", + "cBcCbBcab", + 15 + ], + [ + "CC", + "cCabBBC", + 10 + ], + [ + "CC", + "cCbBB", + 7 + ], + [ + "CCA", + "A", + 4 + ], + [ + "CCA", + "BaaabCA", + 10 + ], + [ + "CCA", + "CBaCacAB", + 10 + ], + [ + "CCA", + "aba", + 5 + ], + [ + "CCA", + "bb", + 6 + ], + [ + "CCAA", + "ABBCA", + 8 + ], + [ + "CCAA", + "BcCbBA", + 7 + ], + [ + "CCAA", + "babAabAA", + 12 + ], + [ + "CCAA", + "cAcC", + 7 + ], + [ + "CCAABbAAc", + "CA", + 14 + ], + [ + "CCAABc", + "BacACaaB", + 11 + ], + [ + "CCAACAbaa", + "BA", + 16 + ], + [ + "CCAAaB", + "CaCCcCa", + 10 + ], + [ + "CCAAbabbc", + "cc", + 15 + ], + [ + "CCAAcCCcA", + "ABcACaBc", + 13 + ], + [ + "CCAAcb", + "C", + 10 + ], + [ + "CCAB", + "bbc", + 8 + ], + [ + "CCABAAB", + "BCABbccB", + 8 + ], + [ + "CCABBCcbB", + "CabB", + 11 + ], + [ + "CCABCCAaa", + "CBCc", + 11 + ], + [ + "CCABb", + "Bcc", + 9 + ], + [ + "CCABcCBAa", + "bbBa", + 13 + ], + [ + "CCABcaC", + "caCc", + 10 + ], + [ + "CCABcbBaC", + "cAAaAAaC", + 11 + ], + [ + "CCAC", + "aBAccBA", + 11 + ], + [ + "CCACb", + "BABcBc", + 10 + ], + [ + "CCACbACc", + "Aabbbac", + 11 + ], + [ + "CCACcaCB", + "ABbCACbB", + 11 + ], + [ + "CCAa", + "aACCbaaac", + 11 + ], + [ + "CCAb", + "ACCBba", + 6 + ], + [ + "CCAbBcABA", + "cAaCBc", + 12 + ], + [ + "CCAbBcb", + "baCB", + 10 + ], + [ + "CCAbCAb", + "BaCCaa", + 10 + ], + [ + "CCAbaC", + "BBbcaa", + 10 + ], + [ + "CCAbaCBa", + "bcccA", + 12 + ], + [ + "CCAcAB", + "ccAAbCa", + 9 + ], + [ + "CCAcACA", + "acBA", + 9 + ], + [ + "CCAcBAa", + "aCacBaBAA", + 8 + ], + [ + "CCAcC", + "BbcBbC", + 9 + ], + [ + "CCAcCB", + "cBcaBBBA", + 11 + ], + [ + "CCAcaC", + "CcaB", + 6 + ], + [ + "CCAcaaca", + "cC", + 13 + ], + [ + "CCAcacccc", + "cAcabcB", + 9 + ], + [ + "CCAcbCb", + "ACCa", + 9 + ], + [ + "CCAcbbCBc", + "CcAbBCa", + 8 + ], + [ + "CCB", + "ACbaAACcB", + 12 + ], + [ + "CCB", + "Cc", + 3 + ], + [ + "CCB", + "abaAB", + 8 + ], + [ + "CCB", + "baCac", + 8 + ], + [ + "CCBA", + "Aaaaa", + 9 + ], + [ + "CCBAA", + "a", + 9 + ], + [ + "CCBABcc", + "BCABb", + 8 + ], + [ + "CCBAC", + "bCCcaCAc", + 9 + ], + [ + "CCBAbAC", + "bCA", + 10 + ], + [ + "CCBAc", + "BC", + 7 + ], + [ + "CCBAcaacb", + "aCCAA", + 13 + ], + [ + "CCBBCBccb", + "BBAa", + 14 + ], + [ + "CCBBbB", + "CbcAACa", + 11 + ], + [ + "CCBBccC", + "c", + 12 + ], + [ + "CCBC", + "CBCaABac", + 9 + ], + [ + "CCBCAaAA", + "CaC", + 12 + ], + [ + "CCBCBCcc", + "bcCccbAbb", + 13 + ], + [ + "CCBCb", + "c", + 9 + ], + [ + "CCBaAaB", + "bACAC", + 11 + ], + [ + "CCBaAaB", + "cbcCBca", + 11 + ], + [ + "CCBaAcba", + "BaaaCAA", + 11 + ], + [ + "CCBaBbbBC", + "a", + 16 + ], + [ + "CCBaCcAa", + "ccBbACCb", + 10 + ], + [ + "CCBbAAAB", + "CCcaBabc", + 11 + ], + [ + "CCBbACc", + "bbbaacBb", + 12 + ], + [ + "CCBbB", + "cBBBACC", + 10 + ], + [ + "CCBbBC", + "bAcCCab", + 12 + ], + [ + "CCBbabCB", + "bCcaB", + 10 + ], + [ + "CCBbca", + "bc", + 8 + ], + [ + "CCBcB", + "ACbbCa", + 8 + ], + [ + "CCBca", + "BacCaaAA", + 12 + ], + [ + "CCBcbbC", + "cB", + 11 + ], + [ + "CCC", + "CcaB", + 5 + ], + [ + "CCC", + "baaaC", + 8 + ], + [ + "CCCAABC", + "CC", + 10 + ], + [ + "CCCAbbBCb", + "cBBaaBab", + 12 + ], + [ + "CCCAc", + "BaccCaB", + 9 + ], + [ + "CCCBAbcc", + "accAb", + 10 + ], + [ + "CCCBBcab", + "ACCA", + 11 + ], + [ + "CCCBCaAcC", + "aaCcAbAa", + 14 + ], + [ + "CCCBbbbC", + "aCb", + 12 + ], + [ + "CCCBcBBaa", + "aBACAbAA", + 14 + ], + [ + "CCCBccaB", + "ccBcc", + 8 + ], + [ + "CCCC", + "bBcAaAbaC", + 15 + ], + [ + "CCCCA", + "BBACa", + 7 + ], + [ + "CCCCA", + "bAcAbbC", + 13 + ], + [ + "CCCCA", + "cccAC", + 7 + ], + [ + "CCCCAbaa", + "CaBaccBB", + 14 + ], + [ + "CCCCBC", + "ABbBc", + 9 + ], + [ + "CCCCCa", + "BCACA", + 7 + ], + [ + "CCCCaBCA", + "Bacbcab", + 13 + ], + [ + "CCCCbaC", + "b", + 12 + ], + [ + "CCCCbbba", + "BAbcAbcBb", + 14 + ], + [ + "CCCCcA", + "bbCCbbc", + 10 + ], + [ + "CCCCcBAC", + "acACBcC", + 9 + ], + [ + "CCCa", + "bAb", + 8 + ], + [ + "CCCaABacb", + "bacBBcAA", + 14 + ], + [ + "CCCaCcA", + "bAcAC", + 10 + ], + [ + "CCCaCcbBA", + "bAbc", + 15 + ], + [ + "CCCaaCaBA", + "AbAbBCb", + 15 + ], + [ + "CCCabaaab", + "cAbca", + 12 + ], + [ + "CCCacacb", + "CAcCBcA", + 10 + ], + [ + "CCCb", + "C", + 6 + ], + [ + "CCCbBBB", + "A", + 14 + ], + [ + "CCCba", + "BbAcaC", + 10 + ], + [ + "CCCbbAA", + "a", + 13 + ], + [ + "CCCbbaA", + "cCB", + 10 + ], + [ + "CCCbbcc", + "BCA", + 12 + ], + [ + "CCCc", + "CBbBBaBBa", + 16 + ], + [ + "CCCcBBba", + "CcBbcAa", + 9 + ], + [ + "CCCcBaA", + "CCCBAAAcA", + 9 + ], + [ + "CCa", + "Ca", + 2 + ], + [ + "CCa", + "CbabbAAcA", + 14 + ], + [ + "CCa", + "bbbCBA", + 9 + ], + [ + "CCa", + "cCAcbAbCC", + 14 + ], + [ + "CCaA", + "c", + 7 + ], + [ + "CCaAA", + "BBACcB", + 11 + ], + [ + "CCaAAb", + "cBa", + 9 + ], + [ + "CCaABbBaA", + "CcACab", + 11 + ], + [ + "CCaAcb", + "ABbBCaCa", + 13 + ], + [ + "CCaBAcbAC", + "CBbc", + 11 + ], + [ + "CCaBBA", + "bAbBB", + 8 + ], + [ + "CCaCAAbA", + "AA", + 12 + ], + [ + "CCaCACBcb", + "caC", + 13 + ], + [ + "CCaCAaA", + "BCAaCaa", + 7 + ], + [ + "CCaCB", + "CAAA", + 7 + ], + [ + "CCaCBcAC", + "bcCa", + 12 + ], + [ + "CCaCCC", + "CACcBa", + 8 + ], + [ + "CCaCaCc", + "BcCba", + 11 + ], + [ + "CCaCaCcBA", + "a", + 16 + ], + [ + "CCaCabaAa", + "CcccAacAC", + 11 + ], + [ + "CCaCb", + "bAcaCbCAb", + 11 + ], + [ + "CCaCbaaaC", + "CaCBCBBc", + 10 + ], + [ + "CCaaBbbA", + "BAAc", + 14 + ], + [ + "CCaaCbCab", + "aBbB", + 13 + ], + [ + "CCaaaaccC", + "AABcca", + 12 + ], + [ + "CCaacBa", + "a", + 12 + ], + [ + "CCabA", + "acbCAAbb", + 10 + ], + [ + "CCabA", + "bbaacCA", + 10 + ], + [ + "CCabCAac", + "ABABA", + 12 + ], + [ + "CCabcCbc", + "BCbc", + 9 + ], + [ + "CCac", + "a", + 6 + ], + [ + "CCacAac", + "bbBbaC", + 11 + ], + [ + "CCacAbCcb", + "bCbBa", + 14 + ], + [ + "CCacBca", + "C", + 12 + ], + [ + "CCacCb", + "cBAC", + 8 + ], + [ + "CCacab", + "Aa", + 9 + ], + [ + "CCacbb", + "CAb", + 7 + ], + [ + "CCacbcB", + "Cca", + 9 + ], + [ + "CCb", + "BAbBAaB", + 12 + ], + [ + "CCb", + "CAAAbca", + 10 + ], + [ + "CCb", + "bAc", + 6 + ], + [ + "CCb", + "bcabBaB", + 11 + ], + [ + "CCb", + "cbCcaAaac", + 15 + ], + [ + "CCbA", + "AABAC", + 7 + ], + [ + "CCbA", + "BbBCabCaa", + 13 + ], + [ + "CCbAAa", + "BcABbC", + 11 + ], + [ + "CCbABCC", + "a", + 13 + ], + [ + "CCbACCBa", + "BbbaBbC", + 12 + ], + [ + "CCbAaaA", + "aB", + 12 + ], + [ + "CCbAbC", + "cAacBCa", + 10 + ], + [ + "CCbAbbBB", + "abcaA", + 13 + ], + [ + "CCbB", + "Aa", + 8 + ], + [ + "CCbB", + "cbaBCBBA", + 10 + ], + [ + "CCbBBB", + "CACCacCBc", + 12 + ], + [ + "CCbBCC", + "BbCAbcAA", + 12 + ], + [ + "CCbBbaBa", + "BcbccCAc", + 13 + ], + [ + "CCbCBCbB", + "cCbbB", + 7 + ], + [ + "CCbCbA", + "ABACcA", + 8 + ], + [ + "CCbCbcacC", + "bBC", + 13 + ], + [ + "CCba", + "aBaAcAaCC", + 15 + ], + [ + "CCba", + "caCAcc", + 9 + ], + [ + "CCba", + "cbaCcba", + 7 + ], + [ + "CCbaB", + "Ba", + 7 + ], + [ + "CCbaBB", + "CCaccA", + 8 + ], + [ + "CCbaCC", + "aBbcaa", + 10 + ], + [ + "CCbaaBcAB", + "a", + 16 + ], + [ + "CCbaba", + "ACbaBAAb", + 8 + ], + [ + "CCbb", + "aBbacACBa", + 14 + ], + [ + "CCbbACcA", + "CBabaAA", + 9 + ], + [ + "CCbbAabCa", + "cAABb", + 13 + ], + [ + "CCbbBabb", + "aBBcc", + 13 + ], + [ + "CCbbaBC", + "cBC", + 9 + ], + [ + "CCbbca", + "bAC", + 9 + ], + [ + "CCbbcaCBA", + "CCaAaBBAB", + 10 + ], + [ + "CCbcAac", + "a", + 12 + ], + [ + "CCbcBC", + "aabbAc", + 9 + ], + [ + "CCbcBca", + "B", + 12 + ], + [ + "CCbcCAc", + "Bb", + 12 + ], + [ + "CCbcb", + "cBaC", + 8 + ], + [ + "CCbcc", + "aBaccBcB", + 11 + ], + [ + "CCc", + "A", + 6 + ], + [ + "CCc", + "Ac", + 4 + ], + [ + "CCc", + "Bc", + 4 + ], + [ + "CCc", + "Cacbb", + 6 + ], + [ + "CCc", + "bCcbAbbAB", + 14 + ], + [ + "CCcAC", + "CABCA", + 7 + ], + [ + "CCcACBCC", + "B", + 14 + ], + [ + "CCcACc", + "cACCCA", + 8 + ], + [ + "CCcAaaba", + "CCCBcABca", + 9 + ], + [ + "CCcAc", + "abaaaCCc", + 13 + ], + [ + "CCcB", + "aCAaBc", + 8 + ], + [ + "CCcBAB", + "CacAbbcbB", + 11 + ], + [ + "CCcBAcC", + "bB", + 12 + ], + [ + "CCcBbAb", + "aBbC", + 10 + ], + [ + "CCcBcaB", + "cBbb", + 9 + ], + [ + "CCcCaaAC", + "CAAbccC", + 12 + ], + [ + "CCcCb", + "B", + 9 + ], + [ + "CCcCbacba", + "AAa", + 15 + ], + [ + "CCcCcABB", + "cAcBabacb", + 13 + ], + [ + "CCcCcccAB", + "BAaACCCAB", + 11 + ], + [ + "CCca", + "Acc", + 5 + ], + [ + "CCca", + "a", + 6 + ], + [ + "CCcaBCabB", + "cAabc", + 11 + ], + [ + "CCcaC", + "bbCACAA", + 10 + ], + [ + "CCcaCca", + "CabacBb", + 9 + ], + [ + "CCcaaBaB", + "ccaAabb", + 9 + ], + [ + "CCcaaabbc", + "BCaCC", + 13 + ], + [ + "CCcabA", + "bCCAAcaBC", + 9 + ], + [ + "CCcacbB", + "Babb", + 9 + ], + [ + "CCcb", + "C", + 6 + ], + [ + "CCcbB", + "abB", + 6 + ], + [ + "CCcbBBC", + "aAAaCCCc", + 14 + ], + [ + "CCcbC", + "ACcBBBBc", + 10 + ], + [ + "CCcbC", + "a", + 10 + ], + [ + "CCcbCACab", + "Accba", + 11 + ], + [ + "CCcbcaaaA", + "ccaaAbaaB", + 12 + ], + [ + "CCccAAB", + "CCaaa", + 8 + ], + [ + "CCccB", + "AACBAbC", + 11 + ], + [ + "CCcca", + "baAaCccaa", + 10 + ], + [ + "CCccaAA", + "b", + 14 + ], + [ + "CCccbb", + "babC", + 10 + ], + [ + "Ca", + "ABCCb", + 8 + ], + [ + "Ca", + "AaCcCBaab", + 14 + ], + [ + "Ca", + "Aac", + 4 + ], + [ + "Ca", + "BAAABca", + 11 + ], + [ + "Ca", + "BACaCCb", + 10 + ], + [ + "Ca", + "BAc", + 5 + ], + [ + "Ca", + "BBAA", + 7 + ], + [ + "Ca", + "BCB", + 4 + ], + [ + "Ca", + "BCBbBaAC", + 12 + ], + [ + "Ca", + "BaCCAcBAa", + 14 + ], + [ + "Ca", + "BabB", + 6 + ], + [ + "Ca", + "BababbBb", + 14 + ], + [ + "Ca", + "BbCB", + 6 + ], + [ + "Ca", + "Bbb", + 6 + ], + [ + "Ca", + "CAbc", + 5 + ], + [ + "Ca", + "CBAbac", + 8 + ], + [ + "Ca", + "CBB", + 4 + ], + [ + "Ca", + "CBaA", + 4 + ], + [ + "Ca", + "CCAB", + 5 + ], + [ + "Ca", + "CCaCBaaA", + 12 + ], + [ + "Ca", + "CCbaAA", + 8 + ], + [ + "Ca", + "CCbb", + 6 + ], + [ + "Ca", + "Cb", + 2 + ], + [ + "Ca", + "aACCba", + 8 + ], + [ + "Ca", + "aB", + 4 + ], + [ + "Ca", + "aBBA", + 7 + ], + [ + "Ca", + "aac", + 4 + ], + [ + "Ca", + "acBacBcAA", + 15 + ], + [ + "Ca", + "b", + 4 + ], + [ + "Ca", + "bAbBbbAa", + 14 + ], + [ + "Ca", + "bBCA", + 5 + ], + [ + "Ca", + "bbBAAAa", + 12 + ], + [ + "Ca", + "c", + 3 + ], + [ + "Ca", + "cCBCBbAAa", + 14 + ], + [ + "Ca", + "caBabaBc", + 13 + ], + [ + "Ca", + "ccCaCCC", + 10 + ], + [ + "CaA", + "BcBcAb", + 9 + ], + [ + "CaA", + "CCBBA", + 6 + ], + [ + "CaA", + "aBa", + 5 + ], + [ + "CaA", + "aBcbcb", + 11 + ], + [ + "CaA", + "bBcCBcbcc", + 16 + ], + [ + "CaA", + "bCABC", + 7 + ], + [ + "CaA", + "bCcBaAaA", + 10 + ], + [ + "CaA", + "c", + 5 + ], + [ + "CaAA", + "bacCbbA", + 10 + ], + [ + "CaAABbc", + "c", + 12 + ], + [ + "CaAAC", + "c", + 9 + ], + [ + "CaAACB", + "bB", + 10 + ], + [ + "CaAAa", + "AcCbA", + 9 + ], + [ + "CaAAbcCa", + "a", + 14 + ], + [ + "CaAB", + "BCaCaCB", + 7 + ], + [ + "CaAB", + "Ba", + 6 + ], + [ + "CaAB", + "bCb", + 7 + ], + [ + "CaABBc", + "b", + 11 + ], + [ + "CaABCBA", + "bBb", + 11 + ], + [ + "CaABa", + "B", + 8 + ], + [ + "CaABbACB", + "BA", + 12 + ], + [ + "CaABbC", + "AAacAc", + 9 + ], + [ + "CaAC", + "BBCbCcaaC", + 11 + ], + [ + "CaAC", + "aCAABab", + 9 + ], + [ + "CaAC", + "acCBbcbA", + 13 + ], + [ + "CaACB", + "B", + 8 + ], + [ + "CaACbacC", + "BAbabAAB", + 12 + ], + [ + "CaACbc", + "CBA", + 8 + ], + [ + "CaACcBACc", + "aAcc", + 10 + ], + [ + "CaAa", + "Bababa", + 7 + ], + [ + "CaAa", + "ccAC", + 5 + ], + [ + "CaAaAC", + "ACa", + 9 + ], + [ + "CaAaACCc", + "BaabbBCbC", + 12 + ], + [ + "CaAaBbB", + "cbAb", + 9 + ], + [ + "CaAaa", + "cAAACBa", + 7 + ], + [ + "CaAab", + "BBbcbaa", + 12 + ], + [ + "CaAabcABB", + "ACcBacC", + 14 + ], + [ + "CaAbC", + "bC", + 6 + ], + [ + "CaAbbBa", + "c", + 13 + ], + [ + "CaAc", + "Ac", + 4 + ], + [ + "CaAc", + "abB", + 6 + ], + [ + "CaAcCAb", + "cABCaAA", + 9 + ], + [ + "CaAcCa", + "bBabcCCC", + 10 + ], + [ + "CaAca", + "bcAcBAABA", + 13 + ], + [ + "CaAcb", + "aBbACB", + 8 + ], + [ + "CaAcc", + "ACc", + 5 + ], + [ + "CaB", + "B", + 4 + ], + [ + "CaB", + "C", + 4 + ], + [ + "CaB", + "acbCAcC", + 11 + ], + [ + "CaB", + "bbAaAaBB", + 12 + ], + [ + "CaB", + "cabbb", + 6 + ], + [ + "CaBA", + "cbcAB", + 7 + ], + [ + "CaBAAB", + "BBAC", + 8 + ], + [ + "CaBAAB", + "a", + 10 + ], + [ + "CaBAAaBB", + "AACB", + 10 + ], + [ + "CaBAbCb", + "baA", + 10 + ], + [ + "CaBAcBCcb", + "A", + 16 + ], + [ + "CaBAcc", + "AACCaA", + 11 + ], + [ + "CaBAcc", + "bAcBbA", + 11 + ], + [ + "CaBB", + "aCCBbcaba", + 13 + ], + [ + "CaBB", + "babABcb", + 9 + ], + [ + "CaBBBa", + "Cc", + 10 + ], + [ + "CaBBBbBB", + "CAAaC", + 13 + ], + [ + "CaBBCccC", + "bAac", + 13 + ], + [ + "CaBBaA", + "a", + 10 + ], + [ + "CaBBabBcc", + "b", + 16 + ], + [ + "CaBBcC", + "BA", + 10 + ], + [ + "CaBBccac", + "accCBA", + 11 + ], + [ + "CaBC", + "CaaacC", + 6 + ], + [ + "CaBCACabA", + "CbcABbc", + 10 + ], + [ + "CaBCBbC", + "ccbBbaC", + 8 + ], + [ + "CaBCCcaCc", + "CaC", + 12 + ], + [ + "CaBaaBcA", + "C", + 14 + ], + [ + "CaBacBc", + "c", + 12 + ], + [ + "CaBba", + "bbcCaAa", + 10 + ], + [ + "CaBbac", + "A", + 11 + ], + [ + "CaBcAc", + "CAAab", + 8 + ], + [ + "CaBcBAbB", + "BABCCca", + 12 + ], + [ + "CaBcaA", + "bcC", + 9 + ], + [ + "CaBccaAc", + "bBa", + 12 + ], + [ + "CaC", + "aC", + 2 + ], + [ + "CaCA", + "bcBA", + 6 + ], + [ + "CaCAAbCcB", + "aBCc", + 11 + ], + [ + "CaCABCcbA", + "bB", + 16 + ], + [ + "CaCACCaA", + "BCBBaaBCA", + 13 + ], + [ + "CaCAbBA", + "bCBb", + 10 + ], + [ + "CaCB", + "AB", + 5 + ], + [ + "CaCB", + "bAb", + 6 + ], + [ + "CaCBa", + "ACabCC", + 8 + ], + [ + "CaCBa", + "abBaa", + 6 + ], + [ + "CaCBaaC", + "bcACBa", + 8 + ], + [ + "CaCBbBBb", + "bab", + 12 + ], + [ + "CaCBc", + "cAC", + 6 + ], + [ + "CaCCbB", + "babA", + 8 + ], + [ + "CaCCbc", + "BAbcCcBB", + 11 + ], + [ + "CaCa", + "Aab", + 6 + ], + [ + "CaCa", + "CCccAab", + 9 + ], + [ + "CaCa", + "CcbcAAC", + 10 + ], + [ + "CaCa", + "abCCa", + 6 + ], + [ + "CaCaAB", + "aBb", + 9 + ], + [ + "CaCb", + "bCab", + 4 + ], + [ + "CaCbBcCCC", + "CaBBab", + 11 + ], + [ + "CaCbbCAcb", + "aABcAc", + 10 + ], + [ + "CaCbbaB", + "ABB", + 10 + ], + [ + "CaCc", + "A", + 7 + ], + [ + "CaCc", + "ccBbc", + 7 + ], + [ + "CaCcAAb", + "baCBCB", + 9 + ], + [ + "CaCcB", + "AA", + 9 + ], + [ + "CaCcBa", + "cAc", + 8 + ], + [ + "CaCcaa", + "CABabbB", + 11 + ], + [ + "CaCcbBA", + "CAbccCaa", + 9 + ], + [ + "Caa", + "Acc", + 6 + ], + [ + "Caa", + "BAcBcBCbb", + 16 + ], + [ + "Caa", + "abbAb", + 9 + ], + [ + "CaaABcBab", + "acACccaCa", + 12 + ], + [ + "CaaAaAa", + "bbaabAc", + 9 + ], + [ + "CaaAaAaba", + "aaCBc", + 13 + ], + [ + "CaaAbCcAb", + "bc", + 14 + ], + [ + "CaaBAab", + "CcC", + 12 + ], + [ + "CaaBcB", + "Caaa", + 6 + ], + [ + "CaaC", + "AAbBaC", + 7 + ], + [ + "CaaCA", + "A", + 8 + ], + [ + "CaaCbCB", + "c", + 13 + ], + [ + "Caaa", + "BBaBcA", + 9 + ], + [ + "CaaaCabaC", + "CAa", + 13 + ], + [ + "Caaab", + "a", + 8 + ], + [ + "CaaabAbc", + "ACc", + 12 + ], + [ + "CaaabCbB", + "ABcB", + 11 + ], + [ + "Caaabcc", + "babAaAC", + 10 + ], + [ + "Caaac", + "AAbbccabb", + 15 + ], + [ + "Caab", + "BacAc", + 7 + ], + [ + "CaacAaCb", + "AbccbacB", + 10 + ], + [ + "CaacCb", + "acbcCABBB", + 13 + ], + [ + "Caacaccbc", + "bCcbB", + 13 + ], + [ + "CaacccACC", + "baBCAaCA", + 12 + ], + [ + "Cab", + "AbBCbcBbc", + 14 + ], + [ + "Cab", + "AcC", + 6 + ], + [ + "Cab", + "BCA", + 5 + ], + [ + "Cab", + "BaB", + 3 + ], + [ + "Cab", + "c", + 5 + ], + [ + "CabA", + "b", + 6 + ], + [ + "CabAabA", + "cbCaBBb", + 10 + ], + [ + "CabAbcCB", + "acbCa", + 10 + ], + [ + "CabB", + "AACcCBcab", + 14 + ], + [ + "CabB", + "BabB", + 2 + ], + [ + "CabB", + "Ccba", + 4 + ], + [ + "CabBCa", + "AaCaab", + 10 + ], + [ + "CabBacbC", + "C", + 14 + ], + [ + "CabBbab", + "Bc", + 12 + ], + [ + "CabBbc", + "BbBCbcBca", + 12 + ], + [ + "CabBcC", + "AaAcCAC", + 9 + ], + [ + "CabCB", + "AaCBCab", + 8 + ], + [ + "CabCaAABb", + "BbaB", + 12 + ], + [ + "CabCb", + "BcCbacbb", + 10 + ], + [ + "Caba", + "AA", + 6 + ], + [ + "Caba", + "CBbBBbCC", + 12 + ], + [ + "CabaAAcbc", + "aA", + 14 + ], + [ + "CabaAaab", + "Bccb", + 13 + ], + [ + "CabaBCc", + "acBcBb", + 11 + ], + [ + "CabaCAC", + "bAaa", + 10 + ], + [ + "CababAAcB", + "a", + 16 + ], + [ + "Cabb", + "aBbABaA", + 11 + ], + [ + "CabbAAABB", + "ccA", + 15 + ], + [ + "CabbACc", + "ABCCca", + 10 + ], + [ + "CabbB", + "BabCaAC", + 10 + ], + [ + "CabbB", + "CbBbAccbc", + 12 + ], + [ + "CabbCaa", + "bbaBbcacC", + 10 + ], + [ + "CabbaAba", + "CABaCBAbA", + 9 + ], + [ + "CabbbAACB", + "Babac", + 12 + ], + [ + "CabcB", + "aBAbaA", + 9 + ], + [ + "CabcBaC", + "Cac", + 8 + ], + [ + "CabcaABb", + "cBBc", + 12 + ], + [ + "CabcaBcB", + "bAABcbCA", + 12 + ], + [ + "Cabcb", + "Ba", + 8 + ], + [ + "Cabccb", + "BBBA", + 11 + ], + [ + "Cac", + "A", + 5 + ], + [ + "Cac", + "BAcb", + 5 + ], + [ + "Cac", + "BCcCCac", + 8 + ], + [ + "Cac", + "Bc", + 4 + ], + [ + "Cac", + "CBaacCcCb", + 12 + ], + [ + "Cac", + "cC", + 4 + ], + [ + "Cac", + "cbACbC", + 9 + ], + [ + "CacA", + "BaBabBAA", + 12 + ], + [ + "CacA", + "CacbC", + 4 + ], + [ + "CacAb", + "acCAb", + 4 + ], + [ + "CacAcAa", + "ACbcC", + 10 + ], + [ + "CacAcBc", + "caABbAAAA", + 13 + ], + [ + "CacBBBC", + "B", + 12 + ], + [ + "CacBCa", + "CcbcBA", + 7 + ], + [ + "CacBaCbca", + "aaBaaaBc", + 11 + ], + [ + "CacBbbB", + "CaCbbaBbb", + 7 + ], + [ + "CacBc", + "bBbAC", + 9 + ], + [ + "CacC", + "AcC", + 3 + ], + [ + "CacCbaAcc", + "bCaAaCB", + 13 + ], + [ + "CacaAc", + "aAbC", + 8 + ], + [ + "Cacab", + "AaBCAa", + 8 + ], + [ + "Cacab", + "c", + 8 + ], + [ + "CacacC", + "AABCCAA", + 12 + ], + [ + "Cacb", + "ac", + 4 + ], + [ + "CacbB", + "BCbcBaa", + 9 + ], + [ + "CacbC", + "bBbCaBBB", + 11 + ], + [ + "CacbC", + "cCAAcCa", + 9 + ], + [ + "CacbCAccB", + "AAaBBcbBc", + 14 + ], + [ + "Cacc", + "AACc", + 4 + ], + [ + "CaccAC", + "BabBAaC", + 8 + ], + [ + "CaccBca", + "aCbb", + 10 + ], + [ + "CaccaAbbC", + "BBbC", + 13 + ], + [ + "CaccaCCa", + "cc", + 12 + ], + [ + "Cb", + "A", + 4 + ], + [ + "Cb", + "AACB", + 5 + ], + [ + "Cb", + "AACCbcBc", + 12 + ], + [ + "Cb", + "ABcAcaCcC", + 16 + ], + [ + "Cb", + "ACCBAaCaA", + 15 + ], + [ + "Cb", + "AaBCBCc", + 11 + ], + [ + "Cb", + "Aaa", + 6 + ], + [ + "Cb", + "AacabCcB", + 13 + ], + [ + "Cb", + "Ac", + 4 + ], + [ + "Cb", + "BABB", + 7 + ], + [ + "Cb", + "BBcAabC", + 11 + ], + [ + "Cb", + "Ba", + 4 + ], + [ + "Cb", + "BaaB", + 7 + ], + [ + "Cb", + "BbCaabCCC", + 14 + ], + [ + "Cb", + "CA", + 2 + ], + [ + "Cb", + "CCcBaAB", + 11 + ], + [ + "Cb", + "Cbb", + 2 + ], + [ + "Cb", + "CcBccBacC", + 15 + ], + [ + "Cb", + "aBcaCb", + 8 + ], + [ + "Cb", + "aCBCcAACA", + 15 + ], + [ + "Cb", + "aaAbc", + 8 + ], + [ + "Cb", + "aaCBBaB", + 11 + ], + [ + "Cb", + "aaaB", + 7 + ], + [ + "Cb", + "abBaC", + 8 + ], + [ + "Cb", + "abaaaCABA", + 15 + ], + [ + "Cb", + "acBbAAca", + 13 + ], + [ + "Cb", + "acbbabbCC", + 15 + ], + [ + "Cb", + "bcCCBA", + 9 + ], + [ + "Cb", + "c", + 3 + ], + [ + "Cb", + "cAbcbCA", + 11 + ], + [ + "Cb", + "cAcCbBA", + 10 + ], + [ + "Cb", + "cB", + 2 + ], + [ + "Cb", + "cBcB", + 6 + ], + [ + "Cb", + "caacb", + 7 + ], + [ + "Cb", + "cbCBBbacA", + 14 + ], + [ + "Cb", + "cbcbccA", + 11 + ], + [ + "CbA", + "AAC", + 6 + ], + [ + "CbA", + "BBCBaCC", + 10 + ], + [ + "CbA", + "BBcBB", + 8 + ], + [ + "CbA", + "baaA", + 6 + ], + [ + "CbA", + "c", + 5 + ], + [ + "CbA", + "caBAbA", + 7 + ], + [ + "CbAABaAC", + "A", + 14 + ], + [ + "CbAACACcC", + "ba", + 15 + ], + [ + "CbAACa", + "AaCaAccab", + 11 + ], + [ + "CbAAaAB", + "BCaBCcaaC", + 12 + ], + [ + "CbAAb", + "bacAabaAB", + 11 + ], + [ + "CbAAcAb", + "caC", + 11 + ], + [ + "CbAAcC", + "ABbcaCa", + 10 + ], + [ + "CbABACcaB", + "Babb", + 14 + ], + [ + "CbABC", + "b", + 8 + ], + [ + "CbABaBaAC", + "acaC", + 12 + ], + [ + "CbAC", + "A", + 6 + ], + [ + "CbAC", + "c", + 7 + ], + [ + "CbACaB", + "aBcA", + 9 + ], + [ + "CbACb", + "bcABcCC", + 10 + ], + [ + "CbACc", + "BbabcaBCA", + 13 + ], + [ + "CbACcABba", + "baABAcBc", + 12 + ], + [ + "CbAaAaaa", + "ACbBACbbc", + 13 + ], + [ + "CbAaabbC", + "A", + 14 + ], + [ + "CbAacB", + "c", + 10 + ], + [ + "CbAacBB", + "CacbBBbBA", + 12 + ], + [ + "CbAb", + "baBac", + 8 + ], + [ + "CbAbBaC", + "aCAaACb", + 11 + ], + [ + "CbAba", + "CbaA", + 4 + ], + [ + "CbAbb", + "Bc", + 9 + ], + [ + "CbAc", + "a", + 7 + ], + [ + "CbAcAC", + "bcbCB", + 8 + ], + [ + "CbAcB", + "aac", + 7 + ], + [ + "CbAcBCcaa", + "ccABcacAc", + 11 + ], + [ + "CbAcCb", + "AC", + 8 + ], + [ + "CbAcaAAA", + "accCbbACC", + 15 + ], + [ + "CbAcc", + "AABbcBBc", + 11 + ], + [ + "CbB", + "ABcCCBb", + 10 + ], + [ + "CbB", + "B", + 4 + ], + [ + "CbB", + "BB", + 3 + ], + [ + "CbB", + "BBb", + 4 + ], + [ + "CbB", + "ababacC", + 11 + ], + [ + "CbB", + "bAaaABc", + 12 + ], + [ + "CbB", + "cCb", + 4 + ], + [ + "CbBABACb", + "BCcBAA", + 10 + ], + [ + "CbBABBaA", + "BacaabAc", + 13 + ], + [ + "CbBAb", + "cB", + 7 + ], + [ + "CbBB", + "CcBCBCcAC", + 12 + ], + [ + "CbBBB", + "BCCcb", + 9 + ], + [ + "CbBBaC", + "ab", + 10 + ], + [ + "CbBBcCCBb", + "B", + 16 + ], + [ + "CbBCCbbB", + "cC", + 13 + ], + [ + "CbBa", + "a", + 6 + ], + [ + "CbBa", + "aAb", + 7 + ], + [ + "CbBabA", + "CcCB", + 9 + ], + [ + "CbBb", + "aBccCBA", + 11 + ], + [ + "CbBbC", + "CCCbbC", + 5 + ], + [ + "CbBbbba", + "BaCCABCcC", + 15 + ], + [ + "CbBbc", + "C", + 8 + ], + [ + "CbBc", + "aAaAAbBA", + 12 + ], + [ + "CbBcB", + "b", + 8 + ], + [ + "CbC", + "AcacbAB", + 11 + ], + [ + "CbC", + "BCAc", + 5 + ], + [ + "CbC", + "Bc", + 4 + ], + [ + "CbC", + "CbB", + 2 + ], + [ + "CbC", + "b", + 4 + ], + [ + "CbCAAbb", + "bAAaC", + 8 + ], + [ + "CbCABcaC", + "aCcAACB", + 12 + ], + [ + "CbCACA", + "baAac", + 8 + ], + [ + "CbCAa", + "cCbabBb", + 10 + ], + [ + "CbCB", + "BAcbcAba", + 11 + ], + [ + "CbCBBb", + "cAbACcA", + 11 + ], + [ + "CbCBC", + "cacCccCb", + 11 + ], + [ + "CbCBCAB", + "bBBcC", + 9 + ], + [ + "CbCBcCAaa", + "aAAaAa", + 14 + ], + [ + "CbCCCc", + "BcBCaba", + 10 + ], + [ + "CbCCbAccA", + "cCbBB", + 13 + ], + [ + "CbCCcCCaB", + "bcaaab", + 11 + ], + [ + "CbCa", + "cBBaCacA", + 10 + ], + [ + "CbCaAaB", + "acaa", + 9 + ], + [ + "CbCaB", + "ACbaa", + 6 + ], + [ + "CbCaB", + "AcbAa", + 7 + ], + [ + "CbCaBCb", + "bcA", + 10 + ], + [ + "CbCaa", + "ABCBCcAb", + 10 + ], + [ + "CbCaa", + "ba", + 6 + ], + [ + "CbCaaaC", + "bAcBcBaAa", + 12 + ], + [ + "CbCb", + "Bbc", + 5 + ], + [ + "CbCbaBa", + "AbacBbabc", + 10 + ], + [ + "CbCbcC", + "Ca", + 10 + ], + [ + "CbCc", + "ACC", + 5 + ], + [ + "CbCc", + "Cabbb", + 6 + ], + [ + "CbCcAaBaA", + "cbC", + 13 + ], + [ + "CbCcAcAc", + "AcBaCaAC", + 11 + ], + [ + "CbCcBAb", + "c", + 12 + ], + [ + "CbCcBC", + "CacBbCAc", + 10 + ], + [ + "CbCcBac", + "AAbAC", + 11 + ], + [ + "Cba", + "ABBBbaab", + 12 + ], + [ + "Cba", + "AcbAbB", + 8 + ], + [ + "Cba", + "C", + 4 + ], + [ + "Cba", + "CCCbbbC", + 10 + ], + [ + "Cba", + "CCaaAa", + 8 + ], + [ + "Cba", + "CcBCCAAAA", + 14 + ], + [ + "Cba", + "aABbaC", + 8 + ], + [ + "CbaA", + "CAbCBaB", + 8 + ], + [ + "CbaA", + "CBb", + 5 + ], + [ + "CbaABAC", + "aBCBCBc", + 12 + ], + [ + "CbaAaBCaB", + "AcCcB", + 12 + ], + [ + "CbaAcBb", + "C", + 12 + ], + [ + "CbaAcc", + "acaCaaccA", + 10 + ], + [ + "CbaBA", + "ab", + 7 + ], + [ + "CbaBBcBaB", + "bB", + 14 + ], + [ + "CbaBa", + "CBC", + 6 + ], + [ + "CbaBb", + "CCCbcB", + 8 + ], + [ + "CbaBba", + "BC", + 10 + ], + [ + "CbaBcAcbC", + "cc", + 14 + ], + [ + "CbaC", + "B", + 7 + ], + [ + "CbaCA", + "BAbaAacA", + 9 + ], + [ + "CbaCABBb", + "cAB", + 11 + ], + [ + "CbaCABcbA", + "BbaCbC", + 10 + ], + [ + "CbaCAaCc", + "a", + 14 + ], + [ + "CbaCAcCba", + "BCcaB", + 12 + ], + [ + "CbaCbCA", + "ccBBAcBc", + 12 + ], + [ + "CbaaA", + "BA", + 7 + ], + [ + "CbaaBA", + "AcccAAaac", + 14 + ], + [ + "CbabAACaC", + "cABaCcbB", + 13 + ], + [ + "CbabACa", + "A", + 12 + ], + [ + "CbabAac", + "aaaB", + 9 + ], + [ + "CbabAcC", + "cbb", + 9 + ], + [ + "CbabBBBcc", + "c", + 16 + ], + [ + "CbabBCCab", + "bB", + 14 + ], + [ + "CbabC", + "CacBB", + 7 + ], + [ + "CbabbBbb", + "BaAABCC", + 11 + ], + [ + "Cbabc", + "aACbC", + 7 + ], + [ + "CbabcB", + "CBcbAcb", + 6 + ], + [ + "CbacAab", + "c", + 12 + ], + [ + "CbacCAB", + "cCC", + 10 + ], + [ + "CbacCCb", + "caaC", + 9 + ], + [ + "CbacCaCAB", + "Cbbba", + 12 + ], + [ + "Cbacaca", + "BACAc", + 8 + ], + [ + "Cbb", + "Ababcb", + 8 + ], + [ + "Cbb", + "Bb", + 3 + ], + [ + "Cbb", + "CACbbBCb", + 10 + ], + [ + "Cbb", + "CBaABccaA", + 14 + ], + [ + "Cbb", + "abcb", + 4 + ], + [ + "Cbb", + "bACBBCCaa", + 14 + ], + [ + "Cbb", + "caCCACBaB", + 14 + ], + [ + "Cbb", + "cbAcABac", + 12 + ], + [ + "CbbA", + "cAACAA", + 9 + ], + [ + "CbbAACbC", + "ccaABC", + 9 + ], + [ + "CbbABCCA", + "CBCABCA", + 5 + ], + [ + "CbbAb", + "B", + 9 + ], + [ + "CbbAbbac", + "bCBbca", + 10 + ], + [ + "CbbAcaCbC", + "CAbBbcAc", + 11 + ], + [ + "CbbB", + "A", + 8 + ], + [ + "CbbB", + "C", + 6 + ], + [ + "CbbBA", + "BBCabAB", + 10 + ], + [ + "CbbBAbcA", + "CcCCAaBb", + 12 + ], + [ + "CbbBAcCba", + "BBbbCaBA", + 11 + ], + [ + "CbbBaBcB", + "cCabACB", + 10 + ], + [ + "CbbCCacBc", + "cbbAcacab", + 8 + ], + [ + "CbbaAacC", + "bcbcbbaBa", + 13 + ], + [ + "CbbaCBAb", + "aBCBBcC", + 13 + ], + [ + "CbbbBb", + "BA", + 10 + ], + [ + "CbbbaA", + "aacCccBbB", + 15 + ], + [ + "CbbbaACba", + "aCBba", + 12 + ], + [ + "Cbbbab", + "AABAbbc", + 11 + ], + [ + "Cbbc", + "bcaAb", + 9 + ], + [ + "Cbbc", + "cba", + 5 + ], + [ + "CbbcBcAc", + "BbC", + 12 + ], + [ + "CbbcCBacB", + "AaC", + 15 + ], + [ + "Cbbcbb", + "bBaBCBA", + 10 + ], + [ + "CbbcbcabC", + "AcBcBcba", + 10 + ], + [ + "Cbbcc", + "B", + 9 + ], + [ + "Cbbcc", + "CcbA", + 6 + ], + [ + "CbbccBAaB", + "cCA", + 13 + ], + [ + "Cbbccc", + "BcA", + 9 + ], + [ + "Cbc", + "A", + 6 + ], + [ + "Cbc", + "BAa", + 6 + ], + [ + "Cbc", + "BaabcacC", + 12 + ], + [ + "Cbc", + "CBbAc", + 4 + ], + [ + "Cbc", + "aCCbab", + 8 + ], + [ + "Cbc", + "baB", + 6 + ], + [ + "Cbc", + "bcB", + 4 + ], + [ + "Cbc", + "caACbaC", + 9 + ], + [ + "Cbc", + "cbabc", + 5 + ], + [ + "CbcAB", + "AabCABAb", + 9 + ], + [ + "CbcAaaBa", + "aACA", + 12 + ], + [ + "CbcB", + "CBcC", + 3 + ], + [ + "CbcBCbB", + "CAAacC", + 11 + ], + [ + "CbcBb", + "aaCACAAcC", + 15 + ], + [ + "CbcBcb", + "AabcC", + 9 + ], + [ + "CbcBcbC", + "aCa", + 13 + ], + [ + "CbcCAAc", + "aaBBbbc", + 12 + ], + [ + "CbcCAB", + "bbaCCcc", + 9 + ], + [ + "CbcCB", + "c", + 8 + ], + [ + "CbcCBB", + "aB", + 10 + ], + [ + "CbcCCa", + "BB", + 11 + ], + [ + "CbcCcA", + "aCaacCaAa", + 10 + ], + [ + "Cbca", + "cABAAaaA", + 12 + ], + [ + "CbcaC", + "bCcabCa", + 8 + ], + [ + "Cbcb", + "AA", + 8 + ], + [ + "Cbcb", + "AaCc", + 7 + ], + [ + "Cbcb", + "CbBAa", + 6 + ], + [ + "CbcbA", + "bccbACcC", + 10 + ], + [ + "CbcbB", + "aC", + 9 + ], + [ + "CbcbBCBC", + "cBB", + 10 + ], + [ + "CbcbC", + "a", + 10 + ], + [ + "Cbcbb", + "cccAB", + 6 + ], + [ + "Cbcbcbc", + "CbaccAcCC", + 9 + ], + [ + "Cbcc", + "BbAcAabc", + 10 + ], + [ + "Cbcc", + "bbBBA", + 8 + ], + [ + "CbccCAcBA", + "acCA", + 12 + ], + [ + "CbccaACc", + "AC", + 12 + ], + [ + "Cc", + "AAbABC", + 11 + ], + [ + "Cc", + "AAcbCAca", + 12 + ], + [ + "Cc", + "ABaC", + 7 + ], + [ + "Cc", + "AC", + 3 + ], + [ + "Cc", + "ACCcCa", + 8 + ], + [ + "Cc", + "AaCCC", + 7 + ], + [ + "Cc", + "BBCBCbbb", + 13 + ], + [ + "Cc", + "BbAbcC", + 10 + ], + [ + "Cc", + "Bc", + 2 + ], + [ + "Cc", + "Bccba", + 7 + ], + [ + "Cc", + "CABACbAcB", + 14 + ], + [ + "Cc", + "CAaCbCA", + 11 + ], + [ + "Cc", + "CCCCAaC", + 11 + ], + [ + "Cc", + "CCbCaAb", + 11 + ], + [ + "Cc", + "Ccb", + 2 + ], + [ + "Cc", + "a", + 4 + ], + [ + "Cc", + "aAABCBacb", + 14 + ], + [ + "Cc", + "aAAccbC", + 11 + ], + [ + "Cc", + "aBBCbc", + 8 + ], + [ + "Cc", + "aCAcaCca", + 12 + ], + [ + "Cc", + "bB", + 4 + ], + [ + "Cc", + "baABAABbC", + 17 + ], + [ + "Cc", + "bbacA", + 8 + ], + [ + "Cc", + "bc", + 2 + ], + [ + "Cc", + "c", + 2 + ], + [ + "Cc", + "cAaAAbc", + 11 + ], + [ + "Cc", + "cBbbBbcA", + 13 + ], + [ + "Cc", + "ca", + 3 + ], + [ + "Cc", + "ccAC", + 5 + ], + [ + "Cc", + "ccCb", + 5 + ], + [ + "CcA", + "BbcbaAB", + 10 + ], + [ + "CcA", + "aCA", + 3 + ], + [ + "CcA", + "bAAbca", + 9 + ], + [ + "CcA", + "bBccA", + 5 + ], + [ + "CcA", + "bCCBb", + 7 + ], + [ + "CcA", + "cBAbaC", + 9 + ], + [ + "CcAA", + "bcACbc", + 8 + ], + [ + "CcAAAAC", + "abCa", + 12 + ], + [ + "CcAAAB", + "bBAbaC", + 9 + ], + [ + "CcAAAcCb", + "cAcBcBBC", + 11 + ], + [ + "CcAABaC", + "BbC", + 10 + ], + [ + "CcAABbc", + "BCaAbab", + 9 + ], + [ + "CcAACB", + "b", + 11 + ], + [ + "CcAAaC", + "CAbaab", + 7 + ], + [ + "CcAB", + "BbcCBc", + 8 + ], + [ + "CcAB", + "accAaa", + 7 + ], + [ + "CcABACACb", + "abBBbCAA", + 12 + ], + [ + "CcABBccA", + "cc", + 12 + ], + [ + "CcABb", + "a", + 9 + ], + [ + "CcABbabBA", + "cCA", + 14 + ], + [ + "CcABcAaa", + "Ba", + 12 + ], + [ + "CcACAbc", + "AbBB", + 11 + ], + [ + "CcACbaCA", + "abbBaBbBa", + 16 + ], + [ + "CcACcCAa", + "AaB", + 13 + ], + [ + "CcAa", + "aAbBCCc", + 13 + ], + [ + "CcAa", + "ccBC", + 5 + ], + [ + "CcAaA", + "cbcC", + 8 + ], + [ + "CcAaB", + "babCBbCAC", + 15 + ], + [ + "CcAaCABA", + "cbaBaCCCb", + 12 + ], + [ + "CcAaCcbcB", + "aBbaCAAC", + 13 + ], + [ + "CcAac", + "Cabaac", + 5 + ], + [ + "CcAacBAaC", + "bCACB", + 12 + ], + [ + "CcAb", + "b", + 6 + ], + [ + "CcAbBcBaa", + "CBc", + 12 + ], + [ + "CcAbaaA", + "cCa", + 10 + ], + [ + "CcAbcaB", + "bcA", + 9 + ], + [ + "CcAc", + "AAaaABABA", + 16 + ], + [ + "CcAcAB", + "aabAabCcb", + 14 + ], + [ + "CcAcCcC", + "cACbbac", + 10 + ], + [ + "CcAcCcc", + "A", + 12 + ], + [ + "CcB", + "AbcBBCAac", + 14 + ], + [ + "CcB", + "Ac", + 4 + ], + [ + "CcB", + "Ccb", + 1 + ], + [ + "CcB", + "ba", + 6 + ], + [ + "CcB", + "cab", + 4 + ], + [ + "CcB", + "cbc", + 5 + ], + [ + "CcBABc", + "cAAC", + 7 + ], + [ + "CcBACb", + "ac", + 10 + ], + [ + "CcBAaAa", + "aCCcB", + 12 + ], + [ + "CcBB", + "bab", + 7 + ], + [ + "CcBBA", + "B", + 8 + ], + [ + "CcBBAb", + "aBCAAc", + 10 + ], + [ + "CcBBCAAC", + "A", + 14 + ], + [ + "CcBBbac", + "Bb", + 10 + ], + [ + "CcBCBaa", + "bbbbB", + 11 + ], + [ + "CcBCCaAbC", + "aAaCaCA", + 14 + ], + [ + "CcBCCbABb", + "BbBCbccaC", + 14 + ], + [ + "CcBCaacCB", + "CAbCcbA", + 11 + ], + [ + "CcBCc", + "C", + 8 + ], + [ + "CcBCc", + "cBcba", + 7 + ], + [ + "CcBCccbb", + "abaAAAa", + 15 + ], + [ + "CcBaBb", + "BAabCcBcB", + 12 + ], + [ + "CcBaa", + "abBac", + 6 + ], + [ + "CcBabaabc", + "bCB", + 15 + ], + [ + "CcBacBC", + "aa", + 12 + ], + [ + "CcBb", + "AAB", + 6 + ], + [ + "CcBb", + "BaAcbA", + 9 + ], + [ + "CcBbC", + "A", + 10 + ], + [ + "CcBbaCbb", + "abcBCCBab", + 11 + ], + [ + "CcBbbaB", + "baCb", + 11 + ], + [ + "CcBc", + "aBabCbbcB", + 13 + ], + [ + "CcBc", + "cabcACa", + 10 + ], + [ + "CcBcABAC", + "AAC", + 10 + ], + [ + "CcBcBCBaa", + "CBA", + 13 + ], + [ + "CcC", + "CBAacacBa", + 13 + ], + [ + "CcC", + "CBbcac", + 7 + ], + [ + "CcCAA", + "cB", + 8 + ], + [ + "CcCABC", + "ACA", + 8 + ], + [ + "CcCACCb", + "CbAbCccC", + 11 + ], + [ + "CcCAaCAaB", + "ABbAAaBb", + 12 + ], + [ + "CcCAbB", + "abb", + 8 + ], + [ + "CcCAbCBc", + "cbaCBaB", + 11 + ], + [ + "CcCB", + "ABbCBAc", + 10 + ], + [ + "CcCB", + "bcaabaccc", + 14 + ], + [ + "CcCB", + "cbBaC", + 8 + ], + [ + "CcCBA", + "CbAbcb", + 9 + ], + [ + "CcCBCcCA", + "BbCcaa", + 10 + ], + [ + "CcCBb", + "aBBC", + 8 + ], + [ + "CcCBc", + "BCBb", + 6 + ], + [ + "CcCC", + "b", + 8 + ], + [ + "CcCCAB", + "CCbB", + 6 + ], + [ + "CcCCBACCa", + "ABAABAAAb", + 14 + ], + [ + "CcCCacbB", + "aACA", + 13 + ], + [ + "CcCaA", + "baa", + 7 + ], + [ + "CcCaaaaA", + "bCbbACC", + 13 + ], + [ + "CcCacAB", + "BCCBacCcb", + 10 + ], + [ + "CcCacbC", + "ACBabB", + 9 + ], + [ + "CcCbB", + "BABCbb", + 7 + ], + [ + "CcCbCA", + "aBcA", + 8 + ], + [ + "CcCbCbBbc", + "ccabB", + 11 + ], + [ + "CcCba", + "BCb", + 6 + ], + [ + "CcCbaAbB", + "aBbcaCB", + 11 + ], + [ + "CcCbcaC", + "CcBbaCbCb", + 9 + ], + [ + "CcCc", + "cBAACa", + 9 + ], + [ + "CcCcAB", + "aCBbA", + 9 + ], + [ + "CcCcAc", + "baBacaB", + 11 + ], + [ + "CcCcBB", + "bcbBbcAbB", + 11 + ], + [ + "CcCcCCAb", + "BCBBaABab", + 13 + ], + [ + "CcCca", + "bCaBAB", + 10 + ], + [ + "CcCcaB", + "aAacCCb", + 10 + ], + [ + "CcCcbCb", + "BBBCBaCC", + 12 + ], + [ + "CcCcbCb", + "cC", + 10 + ], + [ + "CcCccCbbc", + "cabBaCB", + 14 + ], + [ + "Cca", + "AbbaBABCA", + 16 + ], + [ + "Cca", + "AcacBcc", + 10 + ], + [ + "Cca", + "a", + 4 + ], + [ + "Cca", + "b", + 6 + ], + [ + "Cca", + "bAbaCBB", + 12 + ], + [ + "CcaAB", + "B", + 8 + ], + [ + "CcaABA", + "a", + 10 + ], + [ + "CcaAC", + "BaCbAbaAa", + 12 + ], + [ + "CcaACB", + "BcBbAAA", + 10 + ], + [ + "CcaACCA", + "bCacCB", + 8 + ], + [ + "CcaAa", + "cCC", + 8 + ], + [ + "CcaAbCCC", + "AbCBCb", + 10 + ], + [ + "CcaAcb", + "bcBAa", + 8 + ], + [ + "CcaAcc", + "babAAAcbB", + 13 + ], + [ + "CcaB", + "BbaCbBbCB", + 14 + ], + [ + "CcaBA", + "ACCCABCBC", + 12 + ], + [ + "CcaBaBC", + "bacAbAab", + 11 + ], + [ + "CcaBaa", + "A", + 11 + ], + [ + "CcaBcBAB", + "Ac", + 13 + ], + [ + "CcaBcC", + "A", + 11 + ], + [ + "CcaCAaabB", + "CABCacccB", + 11 + ], + [ + "CcaCCAAA", + "BCAaCCcc", + 10 + ], + [ + "CcaCa", + "BAa", + 7 + ], + [ + "CcaCabAcb", + "BaaaBAC", + 10 + ], + [ + "CcaCacbba", + "bccAB", + 13 + ], + [ + "CcaCbbA", + "CcB", + 9 + ], + [ + "CcaCcBc", + "cbaCa", + 9 + ], + [ + "Ccaa", + "AabAcaC", + 10 + ], + [ + "CcaaA", + "aaCAA", + 7 + ], + [ + "CcaaAAbc", + "aABCaCacc", + 13 + ], + [ + "CcaaBC", + "abBCaC", + 10 + ], + [ + "Ccaaa", + "cc", + 7 + ], + [ + "CcaaaAB", + "bc", + 12 + ], + [ + "Ccaaaa", + "ABbbbb", + 12 + ], + [ + "Ccaaabccc", + "cA", + 15 + ], + [ + "CcaabbCCA", + "Bbc", + 14 + ], + [ + "Ccab", + "AC", + 7 + ], + [ + "Ccab", + "Cba", + 4 + ], + [ + "Ccab", + "abBAaBB", + 11 + ], + [ + "Ccab", + "abbBCaBb", + 11 + ], + [ + "CcabACcb", + "cCAaC", + 10 + ], + [ + "Ccac", + "cbCCA", + 8 + ], + [ + "CcacB", + "cCBbaCB", + 7 + ], + [ + "CcacBabBC", + "CaBBaB", + 8 + ], + [ + "CcacC", + "AbbacBa", + 10 + ], + [ + "CcacCABB", + "ba", + 14 + ], + [ + "CcacCaA", + "CaAC", + 8 + ], + [ + "CcacaBB", + "B", + 12 + ], + [ + "CcacbC", + "cCb", + 7 + ], + [ + "Ccb", + "AcbABaCC", + 12 + ], + [ + "Ccb", + "CAA", + 4 + ], + [ + "Ccb", + "CbAcC", + 6 + ], + [ + "Ccb", + "c", + 4 + ], + [ + "CcbA", + "BccAc", + 6 + ], + [ + "CcbA", + "aabCBb", + 10 + ], + [ + "CcbA", + "bABb", + 7 + ], + [ + "CcbAACA", + "bcc", + 11 + ], + [ + "CcbAACB", + "acBBAcac", + 10 + ], + [ + "CcbAAaA", + "ccBCaCa", + 8 + ], + [ + "CcbACBA", + "A", + 12 + ], + [ + "CcbACC", + "bbaC", + 7 + ], + [ + "CcbAaBcAA", + "bAcac", + 11 + ], + [ + "CcbAc", + "AcbbBBBa", + 12 + ], + [ + "CcbBAbCcC", + "AAb", + 14 + ], + [ + "CcbBaCC", + "ABcA", + 11 + ], + [ + "CcbBac", + "BCAAA", + 10 + ], + [ + "CcbBbBBA", + "AbB", + 12 + ], + [ + "CcbBbbbbb", + "bb", + 14 + ], + [ + "CcbBc", + "cBAcacB", + 11 + ], + [ + "CcbBcAC", + "BbCcAbcbB", + 11 + ], + [ + "CcbBcaA", + "bbcca", + 8 + ], + [ + "CcbBcc", + "bbcc", + 5 + ], + [ + "CcbCA", + "a", + 9 + ], + [ + "CcbCA", + "aabAA", + 6 + ], + [ + "CcbCbB", + "CACab", + 7 + ], + [ + "CcbCbCA", + "BcaCaCAb", + 8 + ], + [ + "CcbCc", + "AC", + 8 + ], + [ + "CcbCc", + "cBbbc", + 5 + ], + [ + "CcbCcC", + "c", + 10 + ], + [ + "CcbaccBCb", + "bbCBA", + 13 + ], + [ + "CcbbABb", + "CbCbacB", + 8 + ], + [ + "CcbbaAbbB", + "bc", + 16 + ], + [ + "Ccbbb", + "CBAcACB", + 9 + ], + [ + "CcbbbC", + "cBacabCb", + 11 + ], + [ + "CcbbbCbc", + "BbCAaBaB", + 15 + ], + [ + "CcbbcABBa", + "BcAcCcBCB", + 13 + ], + [ + "Ccbc", + "ABAaaBAb", + 15 + ], + [ + "Ccc", + "B", + 6 + ], + [ + "Ccc", + "BABa", + 8 + ], + [ + "Ccc", + "BcaBAc", + 8 + ], + [ + "Ccc", + "CBB", + 4 + ], + [ + "Ccc", + "CC", + 3 + ], + [ + "Ccc", + "aaaaCC", + 10 + ], + [ + "Ccc", + "ac", + 4 + ], + [ + "Ccc", + "bb", + 6 + ], + [ + "CccABA", + "AAbBcA", + 10 + ], + [ + "CccACCB", + "AcbaC", + 9 + ], + [ + "CccAaB", + "baCaBcCa", + 12 + ], + [ + "CccAb", + "aABBc", + 10 + ], + [ + "CccAcbbca", + "c", + 16 + ], + [ + "CccBBBcB", + "bBbbCa", + 11 + ], + [ + "CccBBbC", + "Bba", + 10 + ], + [ + "CccBa", + "B", + 8 + ], + [ + "CccBa", + "caBA", + 5 + ], + [ + "CccBaaAB", + "C", + 14 + ], + [ + "CccBbBCb", + "a", + 16 + ], + [ + "CccBbca", + "BacAbCBbC", + 12 + ], + [ + "CccCAa", + "CcBcBCCc", + 8 + ], + [ + "CccCCa", + "Ba", + 10 + ], + [ + "CccCa", + "aA", + 9 + ], + [ + "CccCb", + "baA", + 10 + ], + [ + "Ccca", + "A", + 7 + ], + [ + "CccaABbBb", + "aAcB", + 12 + ], + [ + "CccaBBCb", + "BBbaaCCC", + 12 + ], + [ + "Cccaa", + "BbbC", + 10 + ], + [ + "CccacCBb", + "ccBa", + 10 + ], + [ + "CccbABBbb", + "B", + 16 + ], + [ + "Cccbbc", + "CCcBcBa", + 7 + ], + [ + "Cccc", + "BaCbb", + 9 + ], + [ + "CcccAB", + "aCBAB", + 7 + ], + [ + "CcccAbbA", + "BCBcBc", + 12 + ], + [ + "CcccBacc", + "BCAcB", + 11 + ], + [ + "CcccBcCB", + "cCAb", + 12 + ], + [ + "a", + "AA", + 3 + ], + [ + "a", + "AABaCbca", + 14 + ], + [ + "a", + "AACaBBAC", + 14 + ], + [ + "a", + "ABCaa", + 8 + ], + [ + "a", + "ABaaBCCb", + 14 + ], + [ + "a", + "ABab", + 6 + ], + [ + "a", + "ABcB", + 7 + ], + [ + "a", + "ACbcCBCB", + 15 + ], + [ + "a", + "ACbcaA", + 10 + ], + [ + "a", + "AaAA", + 6 + ], + [ + "a", + "AaABacaAA", + 16 + ], + [ + "a", + "AaAbBca", + 12 + ], + [ + "a", + "AabBCaab", + 14 + ], + [ + "a", + "AabCbCb", + 12 + ], + [ + "a", + "AaccB", + 8 + ], + [ + "a", + "Ab", + 3 + ], + [ + "a", + "AbBBaB", + 10 + ], + [ + "a", + "AbCb", + 7 + ], + [ + "a", + "AbCc", + 7 + ], + [ + "a", + "AbbbBacAa", + 16 + ], + [ + "a", + "AbcCaCbac", + 16 + ], + [ + "a", + "AcABaA", + 10 + ], + [ + "a", + "AcACCA", + 11 + ], + [ + "a", + "AcCbc", + 9 + ], + [ + "a", + "AcaB", + 6 + ], + [ + "a", + "B", + 2 + ], + [ + "a", + "BA", + 3 + ], + [ + "a", + "BABAAcBBc", + 17 + ], + [ + "a", + "BABaBa", + 10 + ], + [ + "a", + "BAC", + 5 + ], + [ + "a", + "BAaAbAc", + 12 + ], + [ + "a", + "BAabccCBc", + 16 + ], + [ + "a", + "BAbaaa", + 10 + ], + [ + "a", + "BAbb", + 7 + ], + [ + "a", + "BBAcbBB", + 13 + ], + [ + "a", + "BBBaCab", + 12 + ], + [ + "a", + "BBC", + 6 + ], + [ + "a", + "BBaCbBAC", + 14 + ], + [ + "a", + "BBcca", + 8 + ], + [ + "a", + "BCA", + 5 + ], + [ + "a", + "BCBab", + 8 + ], + [ + "a", + "BaAAAcAbc", + 16 + ], + [ + "a", + "BaAcABBC", + 14 + ], + [ + "a", + "BaBcaC", + 10 + ], + [ + "a", + "BaC", + 4 + ], + [ + "a", + "BaabBAabb", + 16 + ], + [ + "a", + "BbCaCa", + 10 + ], + [ + "a", + "BbcACCA", + 13 + ], + [ + "a", + "Bbcba", + 8 + ], + [ + "a", + "BcAb", + 7 + ], + [ + "a", + "BcBABC", + 11 + ], + [ + "a", + "BcBaAacC", + 14 + ], + [ + "a", + "Bca", + 4 + ], + [ + "a", + "Bcabba", + 10 + ], + [ + "a", + "BccCbbAb", + 15 + ], + [ + "a", + "C", + 2 + ], + [ + "a", + "CA", + 3 + ], + [ + "a", + "CABAcBbc", + 15 + ], + [ + "a", + "CABCB", + 9 + ], + [ + "a", + "CAbC", + 7 + ], + [ + "a", + "CAba", + 6 + ], + [ + "a", + "CAcCAa", + 10 + ], + [ + "a", + "CAcc", + 7 + ], + [ + "a", + "CBA", + 5 + ], + [ + "a", + "CBABB", + 9 + ], + [ + "a", + "CBAa", + 6 + ], + [ + "a", + "CBBCcB", + 12 + ], + [ + "a", + "CBBcA", + 9 + ], + [ + "a", + "CBaCAC", + 10 + ], + [ + "a", + "CBbaCCbC", + 14 + ], + [ + "a", + "CCBc", + 8 + ], + [ + "a", + "CCcaC", + 8 + ], + [ + "a", + "Ca", + 2 + ], + [ + "a", + "CaAaC", + 8 + ], + [ + "a", + "CaBacbb", + 12 + ], + [ + "a", + "CaabacC", + 12 + ], + [ + "a", + "CbBc", + 8 + ], + [ + "a", + "CbbcAB", + 11 + ], + [ + "a", + "CcBBaaCc", + 14 + ], + [ + "a", + "CcBbabBAc", + 16 + ], + [ + "a", + "CcaACcB", + 12 + ], + [ + "a", + "Ccca", + 6 + ], + [ + "a", + "a", + 0 + ], + [ + "a", + "aA", + 2 + ], + [ + "a", + "aAACAbCC", + 14 + ], + [ + "a", + "aACABcAb", + 14 + ], + [ + "a", + "aAbaB", + 8 + ], + [ + "a", + "aBB", + 4 + ], + [ + "a", + "aBBCb", + 8 + ], + [ + "a", + "aBaCbb", + 10 + ], + [ + "a", + "aBb", + 4 + ], + [ + "a", + "aC", + 2 + ], + [ + "a", + "aCCCCcab", + 14 + ], + [ + "a", + "aCaBBABa", + 14 + ], + [ + "a", + "aCaC", + 6 + ], + [ + "a", + "aCb", + 4 + ], + [ + "a", + "aCcBaAa", + 12 + ], + [ + "a", + "aa", + 2 + ], + [ + "a", + "aaBbC", + 8 + ], + [ + "a", + "aaCA", + 6 + ], + [ + "a", + "ab", + 2 + ], + [ + "a", + "abACBBAcC", + 16 + ], + [ + "a", + "abBbBba", + 12 + ], + [ + "a", + "abCaAaCbC", + 16 + ], + [ + "a", + "aba", + 4 + ], + [ + "a", + "abcac", + 8 + ], + [ + "a", + "acAcBAbaB", + 16 + ], + [ + "a", + "acBcAA", + 10 + ], + [ + "a", + "accCCCc", + 12 + ], + [ + "a", + "b", + 2 + ], + [ + "a", + "bA", + 3 + ], + [ + "a", + "bAAaB", + 8 + ], + [ + "a", + "bABBa", + 8 + ], + [ + "a", + "bACca", + 8 + ], + [ + "a", + "bAbAccb", + 13 + ], + [ + "a", + "bAccbcaAB", + 16 + ], + [ + "a", + "bBAca", + 8 + ], + [ + "a", + "bBBC", + 8 + ], + [ + "a", + "bBBCaccC", + 14 + ], + [ + "a", + "bBCb", + 8 + ], + [ + "a", + "bBbC", + 8 + ], + [ + "a", + "bBbCABa", + 12 + ], + [ + "a", + "bC", + 4 + ], + [ + "a", + "bCBacAcC", + 14 + ], + [ + "a", + "bCC", + 6 + ], + [ + "a", + "bCCbaccA", + 14 + ], + [ + "a", + "bCbA", + 7 + ], + [ + "a", + "bCbBab", + 10 + ], + [ + "a", + "bCcaCbc", + 12 + ], + [ + "a", + "bCcaaCbB", + 14 + ], + [ + "a", + "ba", + 2 + ], + [ + "a", + "baa", + 4 + ], + [ + "a", + "baacacaba", + 16 + ], + [ + "a", + "babcA", + 8 + ], + [ + "a", + "babcCAA", + 12 + ], + [ + "a", + "bb", + 4 + ], + [ + "a", + "bbAc", + 7 + ], + [ + "a", + "bbB", + 6 + ], + [ + "a", + "bbBA", + 7 + ], + [ + "a", + "bbBBcaBc", + 14 + ], + [ + "a", + "bbBbAaAAc", + 16 + ], + [ + "a", + "bbCCaACb", + 14 + ], + [ + "a", + "bbCaca", + 10 + ], + [ + "a", + "bbaC", + 6 + ], + [ + "a", + "bbbAcAB", + 13 + ], + [ + "a", + "bbbBAABC", + 15 + ], + [ + "a", + "bbcCBcB", + 14 + ], + [ + "a", + "bcAca", + 8 + ], + [ + "a", + "bcAcacCB", + 14 + ], + [ + "a", + "bcaAcBAbC", + 16 + ], + [ + "a", + "bcb", + 6 + ], + [ + "a", + "bcc", + 6 + ], + [ + "a", + "c", + 2 + ], + [ + "a", + "cAC", + 5 + ], + [ + "a", + "cACBACca", + 14 + ], + [ + "a", + "cACaCa", + 10 + ], + [ + "a", + "cAa", + 4 + ], + [ + "a", + "cBAaa", + 8 + ], + [ + "a", + "cBbBbab", + 12 + ], + [ + "a", + "cC", + 4 + ], + [ + "a", + "cCBA", + 7 + ], + [ + "a", + "cCCa", + 6 + ], + [ + "a", + "cCCbaa", + 10 + ], + [ + "a", + "cCaCcb", + 10 + ], + [ + "a", + "cCacac", + 10 + ], + [ + "a", + "cCcBbCBAa", + 16 + ], + [ + "a", + "cabbcaBBc", + 16 + ], + [ + "a", + "cb", + 4 + ], + [ + "a", + "cbAcAab", + 12 + ], + [ + "a", + "cbAcCB", + 11 + ], + [ + "a", + "cbBaC", + 8 + ], + [ + "a", + "cbCcbC", + 12 + ], + [ + "a", + "cbaCbbBb", + 14 + ], + [ + "a", + "cbbAaCA", + 12 + ], + [ + "a", + "ccACCaBAa", + 16 + ], + [ + "a", + "ccACbaC", + 12 + ], + [ + "a", + "ccAbAC", + 11 + ], + [ + "a", + "ccAbbaBA", + 14 + ], + [ + "a", + "ccCBaCcB", + 14 + ], + [ + "a", + "ccac", + 6 + ], + [ + "aA", + "AAc", + 3 + ], + [ + "aA", + "ABcACbCcb", + 15 + ], + [ + "aA", + "ACcbCBA", + 11 + ], + [ + "aA", + "AacACCa", + 10 + ], + [ + "aA", + "B", + 4 + ], + [ + "aA", + "BabBBcCbC", + 16 + ], + [ + "aA", + "Babb", + 6 + ], + [ + "aA", + "BcAcB", + 8 + ], + [ + "aA", + "CAacB", + 8 + ], + [ + "aA", + "CBABBaAB", + 12 + ], + [ + "aA", + "CaBbbbA", + 10 + ], + [ + "aA", + "CcAabB", + 10 + ], + [ + "aA", + "CcaAb", + 6 + ], + [ + "aA", + "a", + 2 + ], + [ + "aA", + "aCAcAb", + 8 + ], + [ + "aA", + "aCBb", + 6 + ], + [ + "aA", + "aCacaAA", + 10 + ], + [ + "aA", + "aaACBacA", + 12 + ], + [ + "aA", + "aaC", + 3 + ], + [ + "aA", + "abbAaBC", + 10 + ], + [ + "aA", + "abbBBbc", + 12 + ], + [ + "aA", + "bAc", + 4 + ], + [ + "aA", + "bB", + 4 + ], + [ + "aA", + "bBCBC", + 10 + ], + [ + "aA", + "baCBAbCa", + 12 + ], + [ + "aA", + "cABBaA", + 8 + ], + [ + "aA", + "cBc", + 6 + ], + [ + "aA", + "cabbabbA", + 12 + ], + [ + "aA", + "ccbcB", + 10 + ], + [ + "aAA", + "aACbBCCb", + 12 + ], + [ + "aAA", + "ac", + 4 + ], + [ + "aAA", + "bAc", + 4 + ], + [ + "aAAA", + "AaAC", + 4 + ], + [ + "aAAAA", + "c", + 10 + ], + [ + "aAAAAC", + "CbaaCCBBa", + 14 + ], + [ + "aAAAAaAA", + "cbAabBb", + 13 + ], + [ + "aAAABb", + "BABBaB", + 9 + ], + [ + "aAAAC", + "bC", + 8 + ], + [ + "aAAAaAb", + "AAC", + 10 + ], + [ + "aAAAabBca", + "AB", + 14 + ], + [ + "aAAAcCbCB", + "CcBbABBB", + 15 + ], + [ + "aAAB", + "A", + 6 + ], + [ + "aAAB", + "bcabAb", + 7 + ], + [ + "aAAB", + "c", + 8 + ], + [ + "aAAB", + "cCAB", + 4 + ], + [ + "aAABCcCcC", + "CbBBCAB", + 14 + ], + [ + "aAABbBACb", + "aACb", + 10 + ], + [ + "aAACC", + "ccbbaBA", + 13 + ], + [ + "aAACaCa", + "ACbabAc", + 11 + ], + [ + "aAAaAAaa", + "ACBcbbcaA", + 14 + ], + [ + "aAAaaaB", + "BABbaaAbA", + 10 + ], + [ + "aAAabaAbA", + "bcCBbaBB", + 13 + ], + [ + "aAAacaaC", + "a", + 14 + ], + [ + "aAAb", + "aCAA", + 4 + ], + [ + "aAAbBbaA", + "BaaaAbb", + 11 + ], + [ + "aAAbCbCcC", + "cBC", + 14 + ], + [ + "aAAbbA", + "bcbbaBa", + 10 + ], + [ + "aAAc", + "AccBbB", + 10 + ], + [ + "aAAcA", + "BBBABa", + 9 + ], + [ + "aAAcA", + "bb", + 10 + ], + [ + "aAAcAA", + "aCAA", + 5 + ], + [ + "aAAcAa", + "CbCAa", + 7 + ], + [ + "aAAcAaa", + "bAAACb", + 8 + ], + [ + "aAAcB", + "AbcACA", + 8 + ], + [ + "aAAcBBba", + "BcaAcACb", + 11 + ], + [ + "aAAcCCbCB", + "C", + 16 + ], + [ + "aAAcCaCc", + "caACAaAa", + 10 + ], + [ + "aAAcCb", + "bbAbA", + 10 + ], + [ + "aAAcabaab", + "cAACAbb", + 8 + ], + [ + "aAAcbACab", + "bCcAaBbCC", + 15 + ], + [ + "aAAcc", + "aaAC", + 4 + ], + [ + "aAB", + "AAaAcCaa", + 12 + ], + [ + "aAB", + "AbCBB", + 7 + ], + [ + "aAB", + "AcaAB", + 4 + ], + [ + "aAB", + "CAbaA", + 7 + ], + [ + "aAB", + "CCBAcbaCC", + 15 + ], + [ + "aAB", + "aBcbbB", + 8 + ], + [ + "aAB", + "aCCcaBCC", + 11 + ], + [ + "aAB", + "bcbccABCA", + 14 + ], + [ + "aABA", + "cCac", + 8 + ], + [ + "aABAB", + "AaaBBcCA", + 11 + ], + [ + "aABACAa", + "CcBBbA", + 10 + ], + [ + "aABAaA", + "C", + 12 + ], + [ + "aABAb", + "BbBCC", + 8 + ], + [ + "aABAb", + "ca", + 9 + ], + [ + "aABAbab", + "a", + 12 + ], + [ + "aABAc", + "AabAabaB", + 10 + ], + [ + "aABAcCbbA", + "aB", + 14 + ], + [ + "aABB", + "CCAaaccbA", + 14 + ], + [ + "aABB", + "aCac", + 6 + ], + [ + "aABB", + "cb", + 7 + ], + [ + "aABBBBCc", + "cBAcbb", + 13 + ], + [ + "aABBBBa", + "CaBaCCBB", + 11 + ], + [ + "aABBCc", + "cc", + 9 + ], + [ + "aABBacCA", + "BBbacBc", + 9 + ], + [ + "aABBbA", + "aCBbC", + 6 + ], + [ + "aABBbaB", + "CbbBCbacb", + 10 + ], + [ + "aABCAa", + "bBbC", + 9 + ], + [ + "aABCB", + "cAB", + 6 + ], + [ + "aABCCcbB", + "CBbaCcbc", + 9 + ], + [ + "aABCaca", + "Bb", + 12 + ], + [ + "aABCbCba", + "CabccBaB", + 11 + ], + [ + "aABaBA", + "BC", + 10 + ], + [ + "aABaBbAAA", + "B", + 16 + ], + [ + "aABb", + "BC", + 6 + ], + [ + "aABbAa", + "bCbBcC", + 10 + ], + [ + "aABbBbCca", + "ABCCBAbAc", + 12 + ], + [ + "aABbaA", + "bcBC", + 10 + ], + [ + "aABbac", + "AbBbABAAb", + 12 + ], + [ + "aABbccca", + "BcaA", + 11 + ], + [ + "aABcACB", + "A", + 12 + ], + [ + "aABccB", + "A", + 10 + ], + [ + "aAC", + "BA", + 4 + ], + [ + "aAC", + "CAbbaab", + 11 + ], + [ + "aAC", + "CbC", + 4 + ], + [ + "aAC", + "b", + 6 + ], + [ + "aAC", + "bACCbC", + 8 + ], + [ + "aAC", + "bcaBacc", + 10 + ], + [ + "aACABAcCa", + "ccCB", + 13 + ], + [ + "aACBA", + "Aa", + 7 + ], + [ + "aACBACA", + "BaCBa", + 8 + ], + [ + "aACBBcBC", + "A", + 14 + ], + [ + "aACCA", + "Cb", + 8 + ], + [ + "aACCAAb", + "Bca", + 12 + ], + [ + "aACCBc", + "AcbAaCB", + 9 + ], + [ + "aACCa", + "ACccABA", + 10 + ], + [ + "aACCbAA", + "AAaa", + 9 + ], + [ + "aACCc", + "BBcc", + 7 + ], + [ + "aACCc", + "cbaBAC", + 10 + ], + [ + "aACaaA", + "bcACaCbA", + 8 + ], + [ + "aACacACa", + "aaBccaB", + 10 + ], + [ + "aACacCb", + "C", + 12 + ], + [ + "aACaccCAC", + "cC", + 14 + ], + [ + "aACbAC", + "AB", + 9 + ], + [ + "aACbBBcb", + "b", + 14 + ], + [ + "aACbbbaBC", + "aBBACCB", + 13 + ], + [ + "aACcaBb", + "ABabA", + 9 + ], + [ + "aACcbCa", + "b", + 12 + ], + [ + "aAa", + "BbBb", + 8 + ], + [ + "aAa", + "CBCBAabb", + 12 + ], + [ + "aAa", + "Cc", + 6 + ], + [ + "aAa", + "bCaaCBcAa", + 12 + ], + [ + "aAa", + "bc", + 6 + ], + [ + "aAaA", + "b", + 8 + ], + [ + "aAaAcc", + "B", + 12 + ], + [ + "aAaAccAb", + "BCAbabcAA", + 11 + ], + [ + "aAaBBCb", + "Cbbc", + 11 + ], + [ + "aAaBaBBBc", + "cAcCCCA", + 16 + ], + [ + "aAaBaBa", + "bBbBc", + 10 + ], + [ + "aAaCB", + "cCc", + 8 + ], + [ + "aAaCCCc", + "bbcBabaAA", + 16 + ], + [ + "aAaCaaAc", + "BCaA", + 10 + ], + [ + "aAaa", + "bb", + 8 + ], + [ + "aAaaAcCA", + "cBbcccB", + 13 + ], + [ + "aAaaBbbb", + "bCca", + 14 + ], + [ + "aAaaC", + "aCAC", + 5 + ], + [ + "aAaaCBa", + "aaCBCc", + 8 + ], + [ + "aAaaaA", + "aBACbaBAC", + 10 + ], + [ + "aAaabBcb", + "AcCAcBA", + 12 + ], + [ + "aAab", + "C", + 8 + ], + [ + "aAab", + "bCaB", + 5 + ], + [ + "aAab", + "bbaacCCB", + 12 + ], + [ + "aAabC", + "ccbBa", + 9 + ], + [ + "aAabCAc", + "aBCb", + 9 + ], + [ + "aAabCCBaa", + "bBC", + 14 + ], + [ + "aAabbbbB", + "CBAACBCCb", + 13 + ], + [ + "aAabbcCaA", + "A", + 16 + ], + [ + "aAac", + "cCBbCAaBB", + 14 + ], + [ + "aAacB", + "cAcbcBa", + 8 + ], + [ + "aAacBcCBa", + "cba", + 13 + ], + [ + "aAb", + "A", + 4 + ], + [ + "aAb", + "a", + 4 + ], + [ + "aAb", + "b", + 4 + ], + [ + "aAbA", + "bccaaaCAB", + 13 + ], + [ + "aAbABAA", + "bCBAcabBb", + 14 + ], + [ + "aAbAC", + "cACcCa", + 8 + ], + [ + "aAbACaBAA", + "CB", + 14 + ], + [ + "aAbAb", + "cBBabc", + 8 + ], + [ + "aAbAcCb", + "c", + 12 + ], + [ + "aAbBB", + "AC", + 8 + ], + [ + "aAbBaBcAA", + "C", + 17 + ], + [ + "aAbCAcbCC", + "BAAaA", + 14 + ], + [ + "aAbCBA", + "aCBaCABc", + 9 + ], + [ + "aAbCCACCb", + "AbcacbAb", + 11 + ], + [ + "aAbCCC", + "Aca", + 9 + ], + [ + "aAbCa", + "bABc", + 6 + ], + [ + "aAbCbCa", + "AabbBCbA", + 8 + ], + [ + "aAbCbbaba", + "CcBbccaB", + 14 + ], + [ + "aAbCc", + "cCa", + 8 + ], + [ + "aAba", + "BbcbcCBcC", + 16 + ], + [ + "aAbaBA", + "aBAAAA", + 7 + ], + [ + "aAbaBBba", + "Cb", + 14 + ], + [ + "aAbaCAA", + "cAB", + 11 + ], + [ + "aAbaaBA", + "bcCbaccBA", + 10 + ], + [ + "aAbb", + "bBBaACCBC", + 13 + ], + [ + "aAbbABabC", + "cbACbB", + 12 + ], + [ + "aAbbBab", + "caaA", + 11 + ], + [ + "aAbbCAA", + "BBbBcbA", + 8 + ], + [ + "aAbbCbCCa", + "AAB", + 14 + ], + [ + "aAbbCbcb", + "CBc", + 11 + ], + [ + "aAbbaB", + "a", + 10 + ], + [ + "aAbbacAb", + "BccBb", + 11 + ], + [ + "aAbbcbA", + "A", + 12 + ], + [ + "aAbcCaA", + "CCc", + 11 + ], + [ + "aAbcaABCA", + "BCAcbCab", + 13 + ], + [ + "aAbcaAa", + "CCababB", + 11 + ], + [ + "aAbcbbB", + "baba", + 10 + ], + [ + "aAc", + "aBbBCbac", + 11 + ], + [ + "aAc", + "abbAbaC", + 9 + ], + [ + "aAcA", + "A", + 6 + ], + [ + "aAcA", + "ACABBCB", + 10 + ], + [ + "aAcAAb", + "ACC", + 9 + ], + [ + "aAcAAbB", + "cAbbBaCBb", + 13 + ], + [ + "aAcAabacA", + "aCbBcA", + 9 + ], + [ + "aAcAacaba", + "caACb", + 11 + ], + [ + "aAcAbaCac", + "bBc", + 14 + ], + [ + "aAcAcAbaB", + "bcCCa", + 13 + ], + [ + "aAcB", + "aaaCC", + 6 + ], + [ + "aAcB", + "caC", + 6 + ], + [ + "aAcBACBB", + "a", + 14 + ], + [ + "aAcBC", + "aCca", + 6 + ], + [ + "aAcBbABB", + "AA", + 12 + ], + [ + "aAcBbAaBC", + "BbCbaCcaC", + 14 + ], + [ + "aAcCAaC", + "b", + 14 + ], + [ + "aAcCCcAc", + "baabCBAaA", + 12 + ], + [ + "aAcCccBB", + "AaAa", + 14 + ], + [ + "aAcaAaB", + "AcC", + 10 + ], + [ + "aAcaBaA", + "ACcaaA", + 5 + ], + [ + "aAcaaac", + "BaABaBaBA", + 10 + ], + [ + "aAcb", + "AABbA", + 5 + ], + [ + "aAcb", + "aABC", + 4 + ], + [ + "aAcbA", + "cbcAAC", + 8 + ], + [ + "aAcbBb", + "CbcccCBcC", + 14 + ], + [ + "aAcbBcca", + "A", + 14 + ], + [ + "aAcba", + "acBcBBBAc", + 12 + ], + [ + "aAcba", + "b", + 8 + ], + [ + "aAcc", + "CACC", + 4 + ], + [ + "aAccac", + "ACABCBBAC", + 12 + ], + [ + "aAccbCaba", + "BCBbBc", + 14 + ], + [ + "aB", + "A", + 3 + ], + [ + "aB", + "AA", + 3 + ], + [ + "aB", + "AB", + 1 + ], + [ + "aB", + "ABAb", + 5 + ], + [ + "aB", + "ACcb", + 6 + ], + [ + "aB", + "Aabaaa", + 9 + ], + [ + "aB", + "AccabABB", + 12 + ], + [ + "aB", + "B", + 2 + ], + [ + "aB", + "BBcbB", + 8 + ], + [ + "aB", + "BCc", + 6 + ], + [ + "aB", + "Bca", + 6 + ], + [ + "aB", + "C", + 4 + ], + [ + "aB", + "CAAaa", + 8 + ], + [ + "aB", + "CbccACC", + 13 + ], + [ + "aB", + "Cc", + 4 + ], + [ + "aB", + "CcAcCC", + 11 + ], + [ + "aB", + "aCbBBc", + 8 + ], + [ + "aB", + "aaAbCb", + 9 + ], + [ + "aB", + "aaaAb", + 7 + ], + [ + "aB", + "aabCACc", + 11 + ], + [ + "aB", + "abAC", + 5 + ], + [ + "aB", + "bB", + 2 + ], + [ + "aB", + "bBB", + 4 + ], + [ + "aB", + "bb", + 3 + ], + [ + "aB", + "bbbca", + 9 + ], + [ + "aB", + "bbc", + 5 + ], + [ + "aB", + "bc", + 4 + ], + [ + "aB", + "bcb", + 5 + ], + [ + "aB", + "cB", + 2 + ], + [ + "aB", + "cCC", + 6 + ], + [ + "aB", + "cc", + 4 + ], + [ + "aBA", + "BAaAaaCBc", + 14 + ], + [ + "aBAAA", + "CBCAbbcAA", + 10 + ], + [ + "aBAAB", + "BacBABcAc", + 10 + ], + [ + "aBAAaB", + "caAc", + 9 + ], + [ + "aBAAacaa", + "acabBBcBC", + 13 + ], + [ + "aBAAbCcB", + "BCB", + 10 + ], + [ + "aBAAcbCc", + "cBCBBcAAB", + 14 + ], + [ + "aBAB", + "aaCc", + 6 + ], + [ + "aBAB", + "bbaAbA", + 8 + ], + [ + "aBABa", + "bacAa", + 6 + ], + [ + "aBABaABc", + "AAaCCC", + 10 + ], + [ + "aBABcaABA", + "CBcbB", + 12 + ], + [ + "aBACC", + "a", + 8 + ], + [ + "aBACa", + "c", + 9 + ], + [ + "aBACba", + "C", + 10 + ], + [ + "aBACcAA", + "B", + 12 + ], + [ + "aBAa", + "aaB", + 5 + ], + [ + "aBAaC", + "cCACbbBb", + 14 + ], + [ + "aBAabaAB", + "cacCbb", + 13 + ], + [ + "aBAabba", + "AaBABbCBc", + 9 + ], + [ + "aBAacCbbb", + "aBaCaAc", + 10 + ], + [ + "aBAacc", + "aAaAAcABC", + 10 + ], + [ + "aBAb", + "aBBbAac", + 8 + ], + [ + "aBAbAC", + "aABAbCAc", + 5 + ], + [ + "aBAbaaab", + "CCbbAaba", + 11 + ], + [ + "aBAbbB", + "aCacbAB", + 7 + ], + [ + "aBAbbcbb", + "bcBAb", + 11 + ], + [ + "aBAcABbb", + "Ca", + 14 + ], + [ + "aBAcBa", + "CbBcCaa", + 9 + ], + [ + "aBAcBbC", + "aaAaBac", + 7 + ], + [ + "aBAca", + "AACACCcAa", + 11 + ], + [ + "aBAcabBA", + "BBACb", + 9 + ], + [ + "aBAcba", + "bBaaCcB", + 10 + ], + [ + "aBAccCaba", + "CAcabBBbC", + 14 + ], + [ + "aBAcca", + "ABAABbCa", + 8 + ], + [ + "aBB", + "AaAbaAaBb", + 13 + ], + [ + "aBB", + "AaCaB", + 6 + ], + [ + "aBB", + "Acbc", + 6 + ], + [ + "aBB", + "aC", + 4 + ], + [ + "aBB", + "aa", + 4 + ], + [ + "aBB", + "bbCAAaBBB", + 12 + ], + [ + "aBBA", + "BAAc", + 6 + ], + [ + "aBBABAaAA", + "AbCAcbAA", + 10 + ], + [ + "aBBABaaaa", + "bCC", + 17 + ], + [ + "aBBABca", + "bA", + 11 + ], + [ + "aBBACC", + "caaCB", + 9 + ], + [ + "aBBAc", + "aCAA", + 6 + ], + [ + "aBBB", + "AcBcBa", + 7 + ], + [ + "aBBBA", + "CcbaAB", + 9 + ], + [ + "aBBBABAB", + "BBA", + 10 + ], + [ + "aBBBACB", + "Aa", + 12 + ], + [ + "aBBBAaA", + "bB", + 11 + ], + [ + "aBBBB", + "AaBb", + 6 + ], + [ + "aBBBCCBbb", + "BCBca", + 12 + ], + [ + "aBBBaBaAa", + "cCCB", + 16 + ], + [ + "aBBC", + "AbabA", + 7 + ], + [ + "aBBC", + "CcbcBBCb", + 10 + ], + [ + "aBBC", + "cCbbBa", + 9 + ], + [ + "aBBCBac", + "AbacacaCC", + 12 + ], + [ + "aBBCBbab", + "bb", + 12 + ], + [ + "aBBCaCCAB", + "ccBAcA", + 12 + ], + [ + "aBBCbAb", + "cACACb", + 10 + ], + [ + "aBBCbB", + "aCabbA", + 8 + ], + [ + "aBBCcabCb", + "CCacAacc", + 14 + ], + [ + "aBBaB", + "BCaccaa", + 10 + ], + [ + "aBBaB", + "bACCbA", + 11 + ], + [ + "aBBaCCab", + "CBcAbcC", + 12 + ], + [ + "aBBaa", + "a", + 8 + ], + [ + "aBBabAb", + "bACbcAa", + 11 + ], + [ + "aBBac", + "BbAa", + 6 + ], + [ + "aBBacABac", + "CbCbc", + 13 + ], + [ + "aBBb", + "BCAaBa", + 9 + ], + [ + "aBBbA", + "aaa", + 7 + ], + [ + "aBBbB", + "bbBaba", + 7 + ], + [ + "aBBbba", + "bCCcacbB", + 14 + ], + [ + "aBBc", + "BccbaCCac", + 14 + ], + [ + "aBBcABB", + "BBcAbCBAB", + 8 + ], + [ + "aBBcBAab", + "CcCBBA", + 12 + ], + [ + "aBBcBBA", + "cC", + 12 + ], + [ + "aBBcBcb", + "BBBca", + 6 + ], + [ + "aBBcaB", + "AbBAa", + 6 + ], + [ + "aBBccB", + "abcac", + 7 + ], + [ + "aBBcca", + "bABb", + 10 + ], + [ + "aBBcccbCB", + "bCcab", + 12 + ], + [ + "aBC", + "AABCBaAAC", + 13 + ], + [ + "aBC", + "CcaCAB", + 10 + ], + [ + "aBC", + "aACCc", + 6 + ], + [ + "aBC", + "aaaCcCcB", + 12 + ], + [ + "aBC", + "bABBAa", + 9 + ], + [ + "aBC", + "bC", + 3 + ], + [ + "aBC", + "baCCa", + 6 + ], + [ + "aBC", + "bc", + 4 + ], + [ + "aBCA", + "AbbcbAb", + 9 + ], + [ + "aBCA", + "CBaAa", + 6 + ], + [ + "aBCAa", + "BbCCAbAAb", + 12 + ], + [ + "aBCAcBAa", + "BC", + 12 + ], + [ + "aBCAcBCAC", + "AABaCbBcA", + 12 + ], + [ + "aBCAccBCB", + "b", + 17 + ], + [ + "aBCBA", + "b", + 9 + ], + [ + "aBCBBCa", + "aCCAaa", + 8 + ], + [ + "aBCBC", + "bCccB", + 8 + ], + [ + "aBCBC", + "bbB", + 7 + ], + [ + "aBCBabb", + "a", + 12 + ], + [ + "aBCCcc", + "caAAc", + 10 + ], + [ + "aBCaB", + "cB", + 7 + ], + [ + "aBCaCa", + "aCA", + 7 + ], + [ + "aBCaCbC", + "BcaaBaABA", + 13 + ], + [ + "aBCab", + "cAacAcCaA", + 12 + ], + [ + "aBCababA", + "ccbABc", + 11 + ], + [ + "aBCac", + "CbCBbaAB", + 11 + ], + [ + "aBCb", + "acabaC", + 8 + ], + [ + "aBCbb", + "C", + 8 + ], + [ + "aBCbbB", + "bCcBb", + 7 + ], + [ + "aBCbcCBc", + "cBaCAc", + 10 + ], + [ + "aBCc", + "bABcbCa", + 9 + ], + [ + "aBCcAc", + "cCAaaAc", + 10 + ], + [ + "aBCcAcAC", + "BCcBaca", + 8 + ], + [ + "aBCcCBaa", + "b", + 15 + ], + [ + "aBCcCBbcC", + "ba", + 16 + ], + [ + "aBCcaBAaC", + "bBbcaCC", + 10 + ], + [ + "aBa", + "cBCbb", + 8 + ], + [ + "aBa", + "caB", + 4 + ], + [ + "aBaA", + "caBAC", + 5 + ], + [ + "aBaAaAcC", + "CAbBbbabc", + 13 + ], + [ + "aBaAcCBBA", + "AcAcc", + 12 + ], + [ + "aBaAcCC", + "Bc", + 10 + ], + [ + "aBaB", + "CBBbc", + 7 + ], + [ + "aBaB", + "bBAaA", + 6 + ], + [ + "aBaBC", + "CBbcaaBA", + 10 + ], + [ + "aBaBbA", + "CCabBBAaC", + 11 + ], + [ + "aBaBbCcc", + "aB", + 12 + ], + [ + "aBaBc", + "CcCAb", + 10 + ], + [ + "aBaC", + "A", + 7 + ], + [ + "aBaC", + "aa", + 4 + ], + [ + "aBaC", + "accAbAC", + 8 + ], + [ + "aBaCCAb", + "cbBC", + 11 + ], + [ + "aBaCaA", + "Aa", + 9 + ], + [ + "aBaCaC", + "CbaCccAc", + 9 + ], + [ + "aBaCaabAc", + "bCcACb", + 13 + ], + [ + "aBaCba", + "baB", + 8 + ], + [ + "aBaa", + "CBaBAABbB", + 12 + ], + [ + "aBaa", + "Cb", + 7 + ], + [ + "aBaaA", + "aAAaABCB", + 9 + ], + [ + "aBaabC", + "bCBbAabAC", + 9 + ], + [ + "aBaabCba", + "bCCaB", + 12 + ], + [ + "aBaabaB", + "AA", + 12 + ], + [ + "aBaacBbca", + "cCc", + 14 + ], + [ + "aBabACAA", + "acABb", + 12 + ], + [ + "aBabBcb", + "bAbA", + 10 + ], + [ + "aBabbaBbc", + "cbaccAb", + 12 + ], + [ + "aBac", + "c", + 6 + ], + [ + "aBacAAcA", + "aaCB", + 11 + ], + [ + "aBacBB", + "cb", + 9 + ], + [ + "aBacC", + "ACCCcAb", + 11 + ], + [ + "aBacCB", + "abccAac", + 9 + ], + [ + "aBaccCAa", + "aBcacaaCb", + 10 + ], + [ + "aBb", + "BCBAabbac", + 13 + ], + [ + "aBb", + "Ccb", + 4 + ], + [ + "aBb", + "aaac", + 6 + ], + [ + "aBb", + "bbcbbbAaC", + 15 + ], + [ + "aBb", + "cbCaBb", + 6 + ], + [ + "aBb", + "cbaB", + 6 + ], + [ + "aBbA", + "bbaaAbab", + 11 + ], + [ + "aBbACC", + "cCcccBCC", + 12 + ], + [ + "aBbAcCBCA", + "cCBab", + 12 + ], + [ + "aBbB", + "BacA", + 8 + ], + [ + "aBbB", + "aCcCb", + 7 + ], + [ + "aBbBA", + "aAcC", + 8 + ], + [ + "aBbBB", + "aBCc", + 6 + ], + [ + "aBbBCbBAa", + "Ac", + 16 + ], + [ + "aBbBa", + "bAa", + 6 + ], + [ + "aBbBbAbC", + "Abc", + 11 + ], + [ + "aBbBbaBA", + "AbbBCccC", + 10 + ], + [ + "aBbBbcBcb", + "abaBAAAAB", + 12 + ], + [ + "aBbC", + "bCbBAcBc", + 12 + ], + [ + "aBbCABBA", + "Caa", + 12 + ], + [ + "aBbCACaCb", + "A", + 16 + ], + [ + "aBbCBCaBC", + "aCcc", + 12 + ], + [ + "aBbCaa", + "cbAC", + 9 + ], + [ + "aBbCbbbBA", + "aA", + 14 + ], + [ + "aBbCbcCAb", + "BcAC", + 12 + ], + [ + "aBbCc", + "AcACCCba", + 12 + ], + [ + "aBba", + "BcAcCBB", + 12 + ], + [ + "aBbaAACBA", + "BacacbaC", + 12 + ], + [ + "aBbaAB", + "bbCc", + 9 + ], + [ + "aBbaBcC", + "c", + 12 + ], + [ + "aBbaCcbC", + "bbbbcab", + 10 + ], + [ + "aBbaaCcaA", + "bBABBAbCc", + 13 + ], + [ + "aBbabCc", + "CaCB", + 10 + ], + [ + "aBbb", + "Bb", + 4 + ], + [ + "aBbb", + "cccAbB", + 9 + ], + [ + "aBbbA", + "AAC", + 9 + ], + [ + "aBbbAB", + "C", + 12 + ], + [ + "aBbbCab", + "AaCBacaba", + 10 + ], + [ + "aBbbbBA", + "BcbbBBA", + 5 + ], + [ + "aBbcCBaCc", + "C", + 16 + ], + [ + "aBbcCba", + "BbAcaBac", + 9 + ], + [ + "aBc", + "A", + 5 + ], + [ + "aBc", + "Bac", + 4 + ], + [ + "aBc", + "bCCc", + 6 + ], + [ + "aBc", + "baC", + 5 + ], + [ + "aBcAA", + "ABc", + 5 + ], + [ + "aBcAABabC", + "cab", + 12 + ], + [ + "aBcAaAccc", + "BacacaA", + 12 + ], + [ + "aBcAabAA", + "aBcB", + 9 + ], + [ + "aBcAc", + "bCCbbCc", + 11 + ], + [ + "aBcB", + "c", + 6 + ], + [ + "aBcBBBA", + "BbBBaAAab", + 12 + ], + [ + "aBcBBCAbb", + "AAA", + 15 + ], + [ + "aBcBaa", + "bbB", + 9 + ], + [ + "aBcBbbCb", + "cAcBCca", + 11 + ], + [ + "aBcC", + "CCAAA", + 10 + ], + [ + "aBcCABCc", + "BCbbcC", + 9 + ], + [ + "aBcCBbAc", + "cAbABaAa", + 12 + ], + [ + "aBcCCbA", + "cbA", + 8 + ], + [ + "aBcCcbaAC", + "aBBbBaB", + 11 + ], + [ + "aBca", + "BacbCCcB", + 11 + ], + [ + "aBca", + "CBAcCcCA", + 11 + ], + [ + "aBcaCC", + "c", + 10 + ], + [ + "aBcaaBB", + "BAbBaACbc", + 12 + ], + [ + "aBcbABAAa", + "bCCc", + 16 + ], + [ + "aBcbCAb", + "abA", + 8 + ], + [ + "aBcba", + "cAbCC", + 9 + ], + [ + "aBccABa", + "baBbCAAB", + 9 + ], + [ + "aBccAbac", + "CAaaCbb", + 14 + ], + [ + "aBccacCBa", + "ccbc", + 12 + ], + [ + "aBcccC", + "CccbACAcc", + 12 + ], + [ + "aC", + "AABacca", + 11 + ], + [ + "aC", + "ABABACC", + 11 + ], + [ + "aC", + "AcaBa", + 8 + ], + [ + "aC", + "AcaCBcaCB", + 14 + ], + [ + "aC", + "BBbbBcA", + 13 + ], + [ + "aC", + "BCABB", + 8 + ], + [ + "aC", + "Ba", + 4 + ], + [ + "aC", + "BaACBc", + 8 + ], + [ + "aC", + "BacccCb", + 10 + ], + [ + "aC", + "BcACaaCa", + 12 + ], + [ + "aC", + "BcB", + 5 + ], + [ + "aC", + "CAAcA", + 8 + ], + [ + "aC", + "CBbB", + 8 + ], + [ + "aC", + "CCA", + 4 + ], + [ + "aC", + "CaAA", + 6 + ], + [ + "aC", + "a", + 2 + ], + [ + "aC", + "aACaBBaB", + 12 + ], + [ + "aC", + "abCBcb", + 8 + ], + [ + "aC", + "abcabC", + 8 + ], + [ + "aC", + "bA", + 4 + ], + [ + "aC", + "bABAabc", + 11 + ], + [ + "aC", + "bBAAbCAcB", + 15 + ], + [ + "aC", + "bBaaaA", + 10 + ], + [ + "aC", + "bCBA", + 6 + ], + [ + "aC", + "baaaCC", + 8 + ], + [ + "aC", + "babcC", + 6 + ], + [ + "aC", + "bbc", + 5 + ], + [ + "aC", + "caCbAcaCc", + 14 + ], + [ + "aC", + "cbCaCaB", + 10 + ], + [ + "aCA", + "BCcBBaBc", + 13 + ], + [ + "aCA", + "CAACacC", + 10 + ], + [ + "aCA", + "bAaaC", + 8 + ], + [ + "aCA", + "babAaaBaC", + 14 + ], + [ + "aCA", + "baccbBBC", + 13 + ], + [ + "aCA", + "cBCc", + 6 + ], + [ + "aCAAA", + "aB", + 8 + ], + [ + "aCAAAaAba", + "BAbB", + 14 + ], + [ + "aCAABBBBb", + "BBABB", + 11 + ], + [ + "aCAACBcA", + "aA", + 12 + ], + [ + "aCAAaaa", + "AcbacaACb", + 12 + ], + [ + "aCAAbCBbA", + "cBc", + 15 + ], + [ + "aCAAcbC", + "CAaAcCcCc", + 10 + ], + [ + "aCAB", + "AbabAb", + 7 + ], + [ + "aCAB", + "BA", + 6 + ], + [ + "aCAB", + "CBAC", + 6 + ], + [ + "aCABAcBac", + "CCBCcbCC", + 10 + ], + [ + "aCABBC", + "ABb", + 7 + ], + [ + "aCABaAaC", + "BCaaABcC", + 9 + ], + [ + "aCABaBca", + "c", + 14 + ], + [ + "aCABaa", + "C", + 10 + ], + [ + "aCACACAC", + "baAbACC", + 8 + ], + [ + "aCACBBC", + "aCACBaAac", + 7 + ], + [ + "aCACBaaA", + "acCcCB", + 10 + ], + [ + "aCACCca", + "aBA", + 10 + ], + [ + "aCACa", + "baBbABB", + 10 + ], + [ + "aCACcbaa", + "CbAbBCBb", + 14 + ], + [ + "aCAa", + "bBCCcc", + 10 + ], + [ + "aCAaCba", + "AabAc", + 9 + ], + [ + "aCAab", + "CCCcCCAA", + 13 + ], + [ + "aCAacCAAa", + "abAcBacA", + 10 + ], + [ + "aCAb", + "Aaac", + 6 + ], + [ + "aCAbCC", + "bca", + 9 + ], + [ + "aCAbCC", + "cCABABac", + 10 + ], + [ + "aCAbCaCca", + "cACA", + 12 + ], + [ + "aCAbaBab", + "BABbA", + 11 + ], + [ + "aCAbca", + "B", + 11 + ], + [ + "aCAcBbbC", + "acaAbACAB", + 12 + ], + [ + "aCAcaCB", + "CbC", + 10 + ], + [ + "aCAcacc", + "aA", + 10 + ], + [ + "aCAcbA", + "aa", + 9 + ], + [ + "aCAcbabB", + "Aabbca", + 12 + ], + [ + "aCAccCa", + "AaBca", + 8 + ], + [ + "aCB", + "A", + 5 + ], + [ + "aCB", + "aAaCbBcA", + 10 + ], + [ + "aCB", + "aBABAaccA", + 14 + ], + [ + "aCB", + "aBcAb", + 6 + ], + [ + "aCB", + "abCbBA", + 6 + ], + [ + "aCB", + "b", + 5 + ], + [ + "aCB", + "cCcaBbc", + 10 + ], + [ + "aCBA", + "BCcCccBA", + 10 + ], + [ + "aCBA", + "cCCbcA", + 7 + ], + [ + "aCBAabBa", + "aA", + 12 + ], + [ + "aCBAb", + "B", + 8 + ], + [ + "aCBAbb", + "c", + 11 + ], + [ + "aCBB", + "bAb", + 7 + ], + [ + "aCBBAAB", + "bcbCAAAbc", + 11 + ], + [ + "aCBBBAab", + "CBcBbBcb", + 9 + ], + [ + "aCBBCcC", + "aBaCAa", + 8 + ], + [ + "aCBBabca", + "bCaaC", + 11 + ], + [ + "aCBBbb", + "cb", + 9 + ], + [ + "aCBBcBBC", + "c", + 14 + ], + [ + "aCBCCa", + "AaaABcA", + 10 + ], + [ + "aCBCc", + "bacBbaaaA", + 13 + ], + [ + "aCBa", + "cAA", + 6 + ], + [ + "aCBaABA", + "ba", + 11 + ], + [ + "aCBaAC", + "a", + 10 + ], + [ + "aCBaacBc", + "cacacCBB", + 10 + ], + [ + "aCBb", + "Ba", + 6 + ], + [ + "aCBb", + "CaAc", + 8 + ], + [ + "aCBb", + "CaBb", + 4 + ], + [ + "aCBbABbA", + "CbBcaA", + 10 + ], + [ + "aCBbACC", + "cAaBBC", + 10 + ], + [ + "aCBbBAcBB", + "aabBbCcaB", + 9 + ], + [ + "aCBbBc", + "aBabCbbaC", + 10 + ], + [ + "aCBbcccA", + "cCA", + 11 + ], + [ + "aCBc", + "ABAAaC", + 10 + ], + [ + "aCBc", + "BCcc", + 4 + ], + [ + "aCBcB", + "bBCCAC", + 10 + ], + [ + "aCBcaC", + "A", + 11 + ], + [ + "aCC", + "AB", + 5 + ], + [ + "aCC", + "Ac", + 4 + ], + [ + "aCC", + "abABbCBc", + 11 + ], + [ + "aCC", + "cBAcBCcb", + 12 + ], + [ + "aCC", + "cCCcBaa", + 10 + ], + [ + "aCCAA", + "C", + 8 + ], + [ + "aCCAB", + "bbCB", + 6 + ], + [ + "aCCABabA", + "aCa", + 10 + ], + [ + "aCCAcCbA", + "cBbCc", + 13 + ], + [ + "aCCAccAA", + "CB", + 14 + ], + [ + "aCCBBB", + "cccacc", + 10 + ], + [ + "aCCBCcA", + "aAc", + 10 + ], + [ + "aCCBCcCC", + "acBCbA", + 9 + ], + [ + "aCCC", + "ACbCcBa", + 8 + ], + [ + "aCCCBAC", + "AB", + 11 + ], + [ + "aCCCBCBa", + "a", + 14 + ], + [ + "aCCCBaAAa", + "CcBb", + 13 + ], + [ + "aCCCCB", + "cCABAcbA", + 12 + ], + [ + "aCCCCbCc", + "B", + 15 + ], + [ + "aCCCCcCb", + "AAB", + 14 + ], + [ + "aCCCab", + "BAaBcaC", + 10 + ], + [ + "aCCCc", + "aBabBBaa", + 14 + ], + [ + "aCCaA", + "aAAbb", + 8 + ], + [ + "aCCaA", + "cAA", + 6 + ], + [ + "aCCaBCcb", + "BAcc", + 12 + ], + [ + "aCCaC", + "CcacABac", + 10 + ], + [ + "aCCbBBbCB", + "baAcABCC", + 13 + ], + [ + "aCCbbAC", + "BAcbcB", + 11 + ], + [ + "aCCbbbaaB", + "abbC", + 12 + ], + [ + "aCCc", + "bAa", + 8 + ], + [ + "aCCc", + "cbaB", + 8 + ], + [ + "aCCcABBCB", + "bbC", + 14 + ], + [ + "aCCcBBABA", + "bABaacb", + 15 + ], + [ + "aCCcBCCBc", + "a", + 16 + ], + [ + "aCCcbaa", + "B", + 13 + ], + [ + "aCCccBBa", + "baAB", + 14 + ], + [ + "aCa", + "B", + 6 + ], + [ + "aCa", + "BCcC", + 6 + ], + [ + "aCa", + "bbbbCBA", + 11 + ], + [ + "aCaAAACa", + "AcCAA", + 10 + ], + [ + "aCaAAb", + "BCBccaB", + 10 + ], + [ + "aCaABBc", + "aCAbcbB", + 8 + ], + [ + "aCaABbAb", + "aBc", + 12 + ], + [ + "aCaAb", + "aCc", + 6 + ], + [ + "aCaAcCBb", + "baCcbb", + 9 + ], + [ + "aCaAcaC", + "BBCcCcbc", + 11 + ], + [ + "aCaB", + "BacaaAcBA", + 11 + ], + [ + "aCaB", + "C", + 6 + ], + [ + "aCaBAC", + "ab", + 9 + ], + [ + "aCaBBa", + "B", + 10 + ], + [ + "aCaBCB", + "a", + 10 + ], + [ + "aCaBCCB", + "cAccc", + 10 + ], + [ + "aCaBa", + "aC", + 6 + ], + [ + "aCaBacB", + "AAbcaB", + 9 + ], + [ + "aCaC", + "BBcc", + 7 + ], + [ + "aCaC", + "CAAaCAB", + 9 + ], + [ + "aCaC", + "accBcAAbA", + 14 + ], + [ + "aCaCAAac", + "CcCAB", + 10 + ], + [ + "aCaCBaaBb", + "CC", + 14 + ], + [ + "aCaCacAba", + "cbaAbBB", + 13 + ], + [ + "aCaCccca", + "CbACAc", + 11 + ], + [ + "aCaa", + "BAbB", + 8 + ], + [ + "aCaaC", + "ABacC", + 5 + ], + [ + "aCaac", + "AcabAC", + 6 + ], + [ + "aCaacB", + "CA", + 9 + ], + [ + "aCaacacbC", + "b", + 16 + ], + [ + "aCab", + "AcccBcB", + 11 + ], + [ + "aCab", + "BaaacBbbA", + 12 + ], + [ + "aCabBacCB", + "AAc", + 14 + ], + [ + "aCabCBBB", + "CBBcBbBBB", + 10 + ], + [ + "aCabCbbb", + "CBCCCcA", + 12 + ], + [ + "aCabaA", + "bABbaB", + 8 + ], + [ + "aCabbbCA", + "Ba", + 14 + ], + [ + "aCabcb", + "bBBb", + 9 + ], + [ + "aCacA", + "BbAB", + 9 + ], + [ + "aCacCa", + "baABcBcAb", + 12 + ], + [ + "aCacCcAaC", + "CbAbBa", + 14 + ], + [ + "aCacbC", + "CcbABcb", + 10 + ], + [ + "aCb", + "AaBaAc", + 10 + ], + [ + "aCb", + "BB", + 5 + ], + [ + "aCb", + "a", + 4 + ], + [ + "aCb", + "cCbBC", + 6 + ], + [ + "aCbA", + "CcCccBc", + 11 + ], + [ + "aCbA", + "bBaC", + 8 + ], + [ + "aCbAa", + "AABbbcCAC", + 13 + ], + [ + "aCbBAA", + "BcCC", + 11 + ], + [ + "aCbBAB", + "bcCBb", + 8 + ], + [ + "aCbBB", + "B", + 8 + ], + [ + "aCbBCaB", + "aCcAcaAbB", + 9 + ], + [ + "aCbBb", + "CBbA", + 6 + ], + [ + "aCbCBB", + "CAaACaA", + 11 + ], + [ + "aCbCBc", + "ABaBAcAcC", + 13 + ], + [ + "aCbCcCBCB", + "CBbc", + 13 + ], + [ + "aCba", + "aCba", + 0 + ], + [ + "aCbaa", + "BacbBccb", + 11 + ], + [ + "aCbb", + "bBcCBAAcc", + 15 + ], + [ + "aCbbCCCB", + "AaAC", + 13 + ], + [ + "aCbbaBAa", + "BbB", + 11 + ], + [ + "aCbbc", + "BBCAb", + 8 + ], + [ + "aCbbcAcB", + "accCaaB", + 9 + ], + [ + "aCbca", + "AbAc", + 7 + ], + [ + "aCbcb", + "cBcacaa", + 11 + ], + [ + "aCbcc", + "cBCbBAbB", + 12 + ], + [ + "aCbcca", + "CBbCaaCC", + 11 + ], + [ + "aCbccb", + "cAAab", + 9 + ], + [ + "aCc", + "AaAbC", + 7 + ], + [ + "aCc", + "BCbb", + 6 + ], + [ + "aCc", + "CCABBCAa", + 13 + ], + [ + "aCc", + "aAB", + 4 + ], + [ + "aCc", + "bbAcb", + 8 + ], + [ + "aCc", + "bbCcccb", + 10 + ], + [ + "aCc", + "caCAC", + 5 + ], + [ + "aCcA", + "a", + 6 + ], + [ + "aCcA", + "aC", + 4 + ], + [ + "aCcA", + "aaAAaaCBa", + 13 + ], + [ + "aCcA", + "cABb", + 8 + ], + [ + "aCcAAA", + "AbaBACBC", + 13 + ], + [ + "aCcABAc", + "BC", + 11 + ], + [ + "aCcABCB", + "b", + 13 + ], + [ + "aCcACA", + "baCcaaAa", + 7 + ], + [ + "aCcAaAba", + "aCAca", + 8 + ], + [ + "aCcAbB", + "cBCAB", + 7 + ], + [ + "aCcB", + "CCbcBaBBb", + 12 + ], + [ + "aCcBbCAC", + "CACbBb", + 11 + ], + [ + "aCcCC", + "A", + 9 + ], + [ + "aCcCCa", + "CcCabCc", + 8 + ], + [ + "aCcCabC", + "BcACaABCC", + 10 + ], + [ + "aCcCcAaA", + "baaAacBAb", + 13 + ], + [ + "aCcCca", + "cBCbCCAcb", + 11 + ], + [ + "aCcaAABb", + "BCACAAb", + 8 + ], + [ + "aCcaCAA", + "AabCbBBAC", + 12 + ], + [ + "aCcacbabC", + "a", + 16 + ], + [ + "aCcbAb", + "CbbcbaCAB", + 11 + ], + [ + "aCcbB", + "aA", + 8 + ], + [ + "aCcbBbAcC", + "bBBc", + 11 + ], + [ + "aCcbaCbca", + "bcBCCcbC", + 12 + ], + [ + "aCcbb", + "ccAabbABa", + 13 + ], + [ + "aCcbbaccb", + "AaCaCaCC", + 12 + ], + [ + "aCcbcBBA", + "CaBccABCa", + 11 + ], + [ + "aCcbcb", + "AcaacBCc", + 10 + ], + [ + "aCcc", + "baCACCa", + 8 + ], + [ + "aCccAaBa", + "BAaBcB", + 12 + ], + [ + "aCccAb", + "bBbaAcCC", + 13 + ], + [ + "aCccBB", + "CCa", + 9 + ], + [ + "aCccaaABC", + "CcBac", + 11 + ], + [ + "aCcccAaba", + "ccBbaA", + 11 + ], + [ + "aa", + "AACcaACB", + 13 + ], + [ + "aa", + "AcBCa", + 7 + ], + [ + "aa", + "Bbaba", + 6 + ], + [ + "aa", + "Bbc", + 6 + ], + [ + "aa", + "BcaBA", + 7 + ], + [ + "aa", + "C", + 4 + ], + [ + "aa", + "CBcC", + 8 + ], + [ + "aa", + "CbB", + 6 + ], + [ + "aa", + "CbBC", + 8 + ], + [ + "aa", + "a", + 2 + ], + [ + "aa", + "aABACBBb", + 13 + ], + [ + "aa", + "aBC", + 4 + ], + [ + "aa", + "aBcaaCAC", + 12 + ], + [ + "aa", + "aCbbAaaCa", + 14 + ], + [ + "aa", + "aaAaA", + 6 + ], + [ + "aa", + "aaAbcb", + 8 + ], + [ + "aa", + "aabCb", + 6 + ], + [ + "aa", + "abCBc", + 8 + ], + [ + "aa", + "abCbAb", + 9 + ], + [ + "aa", + "acAAbAAB", + 13 + ], + [ + "aa", + "bAaB", + 5 + ], + [ + "aa", + "bB", + 4 + ], + [ + "aa", + "bBAaBCA", + 11 + ], + [ + "aa", + "bCaaBbCA", + 12 + ], + [ + "aa", + "baCCBCBB", + 14 + ], + [ + "aa", + "bbAabBcCc", + 15 + ], + [ + "aa", + "bbcAC", + 9 + ], + [ + "aa", + "cAaabc", + 8 + ], + [ + "aa", + "cB", + 4 + ], + [ + "aa", + "cBB", + 6 + ], + [ + "aa", + "cBcBAAbA", + 14 + ], + [ + "aa", + "cCAB", + 7 + ], + [ + "aa", + "cCB", + 6 + ], + [ + "aa", + "caccAcB", + 11 + ], + [ + "aa", + "cb", + 4 + ], + [ + "aa", + "cbbcCB", + 12 + ], + [ + "aaA", + "A", + 4 + ], + [ + "aaA", + "ACBACBC", + 11 + ], + [ + "aaA", + "bCCA", + 6 + ], + [ + "aaA", + "bcaaAB", + 6 + ], + [ + "aaAA", + "aab", + 4 + ], + [ + "aaAAaaAaB", + "BAA", + 14 + ], + [ + "aaAAbbAC", + "cCbBbCAab", + 14 + ], + [ + "aaAAcC", + "cabbCa", + 9 + ], + [ + "aaAB", + "cAa", + 6 + ], + [ + "aaAB", + "cCaBCcB", + 10 + ], + [ + "aaABAbAC", + "CCAB", + 12 + ], + [ + "aaABAbb", + "CC", + 14 + ], + [ + "aaABB", + "Ccb", + 9 + ], + [ + "aaABCC", + "acABACB", + 6 + ], + [ + "aaABCb", + "CABbAaa", + 12 + ], + [ + "aaABaaA", + "CaaaBBabc", + 9 + ], + [ + "aaABbbCbc", + "B", + 16 + ], + [ + "aaAC", + "Ac", + 5 + ], + [ + "aaAC", + "bccBBBb", + 14 + ], + [ + "aaACa", + "cbAAaCB", + 9 + ], + [ + "aaAaAcbBC", + "A", + 16 + ], + [ + "aaAaaaAb", + "bcBc", + 16 + ], + [ + "aaAabBCbc", + "B", + 16 + ], + [ + "aaAabCaAa", + "BbbbcA", + 13 + ], + [ + "aaAabbbaC", + "bbbCaAbC", + 14 + ], + [ + "aaAac", + "cBCCc", + 8 + ], + [ + "aaAbaBbBa", + "baaCCa", + 12 + ], + [ + "aaAbcbBa", + "BbBbaaC", + 12 + ], + [ + "aaAc", + "bbCBca", + 10 + ], + [ + "aaAccCbC", + "BBa", + 15 + ], + [ + "aaB", + "bAAa", + 6 + ], + [ + "aaB", + "cccCAcAaC", + 15 + ], + [ + "aaBA", + "ABccb", + 9 + ], + [ + "aaBA", + "aca", + 5 + ], + [ + "aaBABCc", + "Aaa", + 10 + ], + [ + "aaBABaCc", + "acBaac", + 7 + ], + [ + "aaBABbCAc", + "cCb", + 16 + ], + [ + "aaBB", + "BbbBbcAB", + 12 + ], + [ + "aaBB", + "bAaAaAB", + 8 + ], + [ + "aaBB", + "bBabBA", + 7 + ], + [ + "aaBBa", + "caaB", + 6 + ], + [ + "aaBC", + "BacaAB", + 8 + ], + [ + "aaBCAaaaB", + "aaACA", + 10 + ], + [ + "aaBCC", + "BAAaBb", + 9 + ], + [ + "aaBCCa", + "CA", + 9 + ], + [ + "aaBCCbAac", + "AcaaBacc", + 13 + ], + [ + "aaBa", + "BabbcC", + 9 + ], + [ + "aaBaAaCa", + "aBbcAcAb", + 11 + ], + [ + "aaBaC", + "bcCAbac", + 9 + ], + [ + "aaBaCc", + "BCAaCCb", + 9 + ], + [ + "aaBaa", + "AAb", + 7 + ], + [ + "aaBaa", + "ccba", + 7 + ], + [ + "aaBaaAcBA", + "aCcBCAc", + 12 + ], + [ + "aaBabACBC", + "CCCc", + 15 + ], + [ + "aaBabbBA", + "aAbB", + 9 + ], + [ + "aaBacaB", + "BCABCCCbc", + 13 + ], + [ + "aaBbAaBA", + "BAc", + 12 + ], + [ + "aaBbb", + "aA", + 7 + ], + [ + "aaBbcA", + "CBcb", + 8 + ], + [ + "aaBbcbb", + "C", + 13 + ], + [ + "aaBcBaBa", + "aaBaaaB", + 6 + ], + [ + "aaBccACb", + "bCCBccC", + 10 + ], + [ + "aaC", + "ABcAca", + 9 + ], + [ + "aaC", + "BAbaCaa", + 9 + ], + [ + "aaC", + "CaCbcCc", + 10 + ], + [ + "aaC", + "Cc", + 5 + ], + [ + "aaC", + "aCa", + 4 + ], + [ + "aaC", + "caBBCb", + 8 + ], + [ + "aaCA", + "B", + 8 + ], + [ + "aaCAA", + "BcbBC", + 10 + ], + [ + "aaCABbb", + "CCcbBAb", + 9 + ], + [ + "aaCACa", + "Bb", + 12 + ], + [ + "aaCAcbc", + "AaaAAa", + 9 + ], + [ + "aaCAccaAB", + "CcCABcA", + 10 + ], + [ + "aaCC", + "B", + 8 + ], + [ + "aaCCC", + "ABAcC", + 6 + ], + [ + "aaCCCc", + "cCAaaAbAb", + 14 + ], + [ + "aaCCa", + "CAA", + 7 + ], + [ + "aaCCbaCaB", + "cCCcCAccC", + 13 + ], + [ + "aaCCcbCA", + "acAcb", + 9 + ], + [ + "aaCa", + "aCBca", + 5 + ], + [ + "aaCa", + "cAAca", + 5 + ], + [ + "aaCaABa", + "ba", + 11 + ], + [ + "aaCaABbc", + "B", + 14 + ], + [ + "aaCaBaA", + "aBcAa", + 8 + ], + [ + "aaCaa", + "Ac", + 8 + ], + [ + "aaCacA", + "CbabcA", + 8 + ], + [ + "aaCacAAb", + "CcCAc", + 10 + ], + [ + "aaCacaBC", + "BBaCcA", + 11 + ], + [ + "aaCacaba", + "ACbc", + 11 + ], + [ + "aaCbAAB", + "ABc", + 12 + ], + [ + "aaCbabb", + "Bc", + 13 + ], + [ + "aaCbabc", + "C", + 12 + ], + [ + "aaCbbAAc", + "BaBa", + 12 + ], + [ + "aaCcAcc", + "aC", + 10 + ], + [ + "aaCcaBcB", + "ccAaAbaBC", + 12 + ], + [ + "aaCcaC", + "AAABCccC", + 8 + ], + [ + "aaCccbAaa", + "B", + 17 + ], + [ + "aaa", + "ABAbCbC", + 12 + ], + [ + "aaa", + "abABCcbA", + 12 + ], + [ + "aaa", + "abaC", + 4 + ], + [ + "aaa", + "baa", + 2 + ], + [ + "aaa", + "cCbC", + 8 + ], + [ + "aaaA", + "BaCacbbc", + 12 + ], + [ + "aaaA", + "aaaabAC", + 6 + ], + [ + "aaaAAb", + "abCC", + 10 + ], + [ + "aaaAAcb", + "cbABcb", + 8 + ], + [ + "aaaABb", + "BBCCbBaba", + 14 + ], + [ + "aaaACcA", + "aaa", + 8 + ], + [ + "aaaAac", + "CCAaC", + 7 + ], + [ + "aaaAb", + "ACc", + 9 + ], + [ + "aaaB", + "b", + 7 + ], + [ + "aaaBBB", + "CcACCaCB", + 13 + ], + [ + "aaaBCAbBc", + "baCaab", + 12 + ], + [ + "aaaBaBCAb", + "BaBccAb", + 9 + ], + [ + "aaaBbAC", + "baBCAc", + 7 + ], + [ + "aaaBbBA", + "a", + 12 + ], + [ + "aaaC", + "aca", + 4 + ], + [ + "aaaCAAcAA", + "cCacb", + 13 + ], + [ + "aaaCBacCc", + "aA", + 15 + ], + [ + "aaaCaBcCC", + "ACAbBb", + 13 + ], + [ + "aaaCaaC", + "C", + 12 + ], + [ + "aaaCaaCb", + "bC", + 14 + ], + [ + "aaaCb", + "bcBbaB", + 11 + ], + [ + "aaaCbC", + "AabAc", + 8 + ], + [ + "aaaCcB", + "A", + 11 + ], + [ + "aaaa", + "CacBC", + 8 + ], + [ + "aaaaB", + "aCBcbC", + 9 + ], + [ + "aaaaBBCc", + "aCcCcaab", + 14 + ], + [ + "aaaaBCc", + "bcbaB", + 10 + ], + [ + "aaaaC", + "CBb", + 10 + ], + [ + "aaabCBaAB", + "cbBccA", + 14 + ], + [ + "aaac", + "BAaB", + 5 + ], + [ + "aaacCCB", + "aaAaacA", + 8 + ], + [ + "aab", + "CcCcaACB", + 12 + ], + [ + "aab", + "ab", + 2 + ], + [ + "aab", + "b", + 4 + ], + [ + "aab", + "bBb", + 4 + ], + [ + "aab", + "ccbCc", + 8 + ], + [ + "aabAA", + "CBCcBcac", + 14 + ], + [ + "aabACB", + "AACA", + 7 + ], + [ + "aabACB", + "Ca", + 10 + ], + [ + "aabAacba", + "bCbcBC", + 11 + ], + [ + "aabAbBc", + "AbCaCcCB", + 13 + ], + [ + "aabBAA", + "CbaACAbAA", + 10 + ], + [ + "aabBBcB", + "CbACCCc", + 13 + ], + [ + "aabCAAc", + "CBaA", + 10 + ], + [ + "aabCAcB", + "BBCA", + 9 + ], + [ + "aabaCc", + "Acab", + 9 + ], + [ + "aabb", + "a", + 6 + ], + [ + "aabbA", + "bA", + 6 + ], + [ + "aabbCAA", + "AaAAAbbC", + 11 + ], + [ + "aabbacA", + "AbC", + 10 + ], + [ + "aabbcABba", + "AC", + 16 + ], + [ + "aabc", + "A", + 7 + ], + [ + "aabc", + "Baab", + 4 + ], + [ + "aabcA", + "cabBcCc", + 8 + ], + [ + "aabcBcB", + "Ab", + 11 + ], + [ + "aabcaAA", + "abccacA", + 6 + ], + [ + "aabcbBc", + "BaCaaaA", + 12 + ], + [ + "aabcbaaac", + "BbCbccCc", + 11 + ], + [ + "aac", + "BCC", + 5 + ], + [ + "aac", + "BbCaCBbBc", + 14 + ], + [ + "aac", + "C", + 5 + ], + [ + "aac", + "a", + 4 + ], + [ + "aacA", + "CABCabaa", + 12 + ], + [ + "aacAaCCA", + "CBCbB", + 13 + ], + [ + "aacAaCCAb", + "BBCAB", + 13 + ], + [ + "aacAcb", + "baAacaCAB", + 9 + ], + [ + "aacB", + "ABcCcBAca", + 13 + ], + [ + "aacB", + "CACAABc", + 10 + ], + [ + "aacB", + "c", + 6 + ], + [ + "aacBAabc", + "caCBa", + 9 + ], + [ + "aacBc", + "aBCaCbAc", + 8 + ], + [ + "aacC", + "Ba", + 6 + ], + [ + "aacC", + "Bc", + 6 + ], + [ + "aacC", + "CAbBAbCaA", + 14 + ], + [ + "aacCCb", + "ccBAc", + 10 + ], + [ + "aacCc", + "CaB", + 8 + ], + [ + "aacaA", + "Bbaa", + 7 + ], + [ + "aacaa", + "cCB", + 8 + ], + [ + "aacaaCbBc", + "BCab", + 13 + ], + [ + "aacabaBA", + "cbbA", + 9 + ], + [ + "aacac", + "ABBCabcc", + 10 + ], + [ + "aacacAaB", + "aAbbA", + 11 + ], + [ + "aacb", + "BCcAb", + 6 + ], + [ + "aacbAAC", + "BbabBAC", + 8 + ], + [ + "aacbAcA", + "acbccC", + 6 + ], + [ + "aacbCABAC", + "AAbaCAbbA", + 11 + ], + [ + "aacbb", + "BBAbAC", + 10 + ], + [ + "aacc", + "acACBAa", + 10 + ], + [ + "aaccAaABA", + "BAbBacAC", + 14 + ], + [ + "aacccAccB", + "BBCAb", + 14 + ], + [ + "ab", + "ABca", + 6 + ], + [ + "ab", + "ACA", + 5 + ], + [ + "ab", + "AaB", + 3 + ], + [ + "ab", + "B", + 3 + ], + [ + "ab", + "BAabAa", + 8 + ], + [ + "ab", + "BAacbb", + 8 + ], + [ + "ab", + "Ba", + 4 + ], + [ + "ab", + "BbaBBa", + 9 + ], + [ + "ab", + "CACABaC", + 12 + ], + [ + "ab", + "CCbaA", + 8 + ], + [ + "ab", + "CbBACbc", + 11 + ], + [ + "ab", + "CbcbcbB", + 12 + ], + [ + "ab", + "CcB", + 5 + ], + [ + "ab", + "CcacBC", + 9 + ], + [ + "ab", + "aBBAbbaB", + 12 + ], + [ + "ab", + "aBCbBCACa", + 14 + ], + [ + "ab", + "abAbbc", + 8 + ], + [ + "ab", + "abB", + 2 + ], + [ + "ab", + "bAbCcBAaA", + 15 + ], + [ + "ab", + "baBcBa", + 9 + ], + [ + "ab", + "bb", + 2 + ], + [ + "ab", + "c", + 4 + ], + [ + "ab", + "cAAabacc", + 12 + ], + [ + "ab", + "cABcCCb", + 11 + ], + [ + "ab", + "cCbbbCa", + 12 + ], + [ + "ab", + "cbcb", + 6 + ], + [ + "ab", + "ccb", + 4 + ], + [ + "ab", + "cccaaCAA", + 14 + ], + [ + "abA", + "AaacB", + 8 + ], + [ + "abA", + "BAB", + 5 + ], + [ + "abA", + "abca", + 3 + ], + [ + "abA", + "bAAcC", + 8 + ], + [ + "abA", + "bBbaa", + 7 + ], + [ + "abA", + "bbbAcabb", + 12 + ], + [ + "abA", + "cAbCCcbb", + 13 + ], + [ + "abA", + "cBaaC", + 8 + ], + [ + "abAAB", + "BAbACC", + 7 + ], + [ + "abAAcaCa", + "c", + 14 + ], + [ + "abAB", + "AaCBBbb", + 10 + ], + [ + "abABAA", + "aBABbaabA", + 8 + ], + [ + "abABcAaC", + "aCbAcb", + 10 + ], + [ + "abABcb", + "b", + 10 + ], + [ + "abAC", + "BAC", + 3 + ], + [ + "abACAC", + "CBCaaCcA", + 12 + ], + [ + "abACC", + "BbCbBb", + 10 + ], + [ + "abACCBBa", + "abb", + 11 + ], + [ + "abACCaABb", + "aAcbb", + 10 + ], + [ + "abACb", + "Ca", + 8 + ], + [ + "abACbBAaA", + "cAAcCaCaB", + 13 + ], + [ + "abACccA", + "bBaCBC", + 9 + ], + [ + "abAaAaCCC", + "cACCbAbCC", + 13 + ], + [ + "abAaBAAC", + "ABca", + 11 + ], + [ + "abAacCCaa", + "acbCAC", + 11 + ], + [ + "abAbAcCc", + "b", + 14 + ], + [ + "abAbbBC", + "CAbbBbBb", + 8 + ], + [ + "abAc", + "bC", + 5 + ], + [ + "abAcBBbBA", + "CabccbcaA", + 11 + ], + [ + "abAccAbba", + "caCACCC", + 14 + ], + [ + "abAccBA", + "ACAbbABaa", + 12 + ], + [ + "abAccCbBa", + "cbccBbBac", + 8 + ], + [ + "abB", + "BAAA", + 7 + ], + [ + "abB", + "BACbb", + 6 + ], + [ + "abB", + "BcaBabA", + 10 + ], + [ + "abB", + "a", + 4 + ], + [ + "abB", + "cbBaACaAB", + 14 + ], + [ + "abBA", + "AACBCAbA", + 11 + ], + [ + "abBAA", + "bA", + 6 + ], + [ + "abBAAcaA", + "AACCC", + 11 + ], + [ + "abBAAcbb", + "bCCcbb", + 8 + ], + [ + "abBAB", + "aa", + 7 + ], + [ + "abBABBA", + "BBCBccbaA", + 12 + ], + [ + "abBAaBa", + "bbaBCcbc", + 11 + ], + [ + "abBAaCacb", + "bbaca", + 10 + ], + [ + "abBAaCcc", + "ccCACB", + 12 + ], + [ + "abBAc", + "bB", + 6 + ], + [ + "abBAc", + "bBB", + 6 + ], + [ + "abBB", + "BbaBbCbb", + 10 + ], + [ + "abBBCc", + "b", + 10 + ], + [ + "abBBaAcBc", + "bbCaB", + 11 + ], + [ + "abBBaBbCc", + "Cac", + 14 + ], + [ + "abBBac", + "BAc", + 7 + ], + [ + "abBBb", + "A", + 9 + ], + [ + "abBBb", + "ACAAc", + 9 + ], + [ + "abBBbB", + "b", + 10 + ], + [ + "abBCACBBc", + "B", + 16 + ], + [ + "abBCBAB", + "cCA", + 10 + ], + [ + "abBCCb", + "AbaCcCcA", + 9 + ], + [ + "abBCCcc", + "BcBCCbCbb", + 11 + ], + [ + "abBCac", + "cCcbACcC", + 11 + ], + [ + "abBCcCbA", + "bC", + 12 + ], + [ + "abBa", + "cbabba", + 5 + ], + [ + "abBaA", + "CA", + 8 + ], + [ + "abBaAAc", + "BB", + 11 + ], + [ + "abBaBcabA", + "BBBAabAba", + 10 + ], + [ + "abBaCbB", + "CaCaacbC", + 9 + ], + [ + "abBabAb", + "Aacb", + 9 + ], + [ + "abBacbc", + "cAccCaaa", + 15 + ], + [ + "abBacca", + "bAACac", + 10 + ], + [ + "abBb", + "ABCaACb", + 10 + ], + [ + "abBb", + "BAABc", + 7 + ], + [ + "abBb", + "c", + 8 + ], + [ + "abBb", + "cAB", + 6 + ], + [ + "abBbBB", + "Aaccb", + 10 + ], + [ + "abBbC", + "aaccbac", + 9 + ], + [ + "abBbCBBa", + "C", + 14 + ], + [ + "abBbb", + "BBA", + 7 + ], + [ + "abBbba", + "CBbAAb", + 9 + ], + [ + "abBc", + "AABBCcBcc", + 12 + ], + [ + "abBc", + "bcbbCABca", + 12 + ], + [ + "abBcB", + "CbCaCca", + 10 + ], + [ + "abBcBBCA", + "BCCCacAac", + 15 + ], + [ + "abBcaBa", + "bcBCCc", + 11 + ], + [ + "abC", + "ACAbb", + 7 + ], + [ + "abC", + "Cc", + 5 + ], + [ + "abC", + "aAabBb", + 8 + ], + [ + "abC", + "b", + 4 + ], + [ + "abC", + "bccBAC", + 9 + ], + [ + "abC", + "bccabCBc", + 10 + ], + [ + "abC", + "cBA", + 5 + ], + [ + "abC", + "cCB", + 6 + ], + [ + "abCA", + "Acb", + 6 + ], + [ + "abCA", + "cc", + 7 + ], + [ + "abCAA", + "BAcbCCBc", + 11 + ], + [ + "abCAAcbCB", + "acCabB", + 9 + ], + [ + "abCAaA", + "AcbaAB", + 8 + ], + [ + "abCB", + "BABBbAABA", + 13 + ], + [ + "abCBB", + "Bb", + 7 + ], + [ + "abCBCB", + "baCaaa", + 10 + ], + [ + "abCC", + "CA", + 6 + ], + [ + "abCC", + "CCcCAcaA", + 13 + ], + [ + "abCCAacb", + "babaA", + 12 + ], + [ + "abCCBB", + "baB", + 8 + ], + [ + "abCCBBC", + "aAc", + 11 + ], + [ + "abCCCBaAC", + "CCBbCbBA", + 13 + ], + [ + "abCCaAca", + "bBCBCaC", + 10 + ], + [ + "abCCbBBaA", + "Ab", + 15 + ], + [ + "abCCc", + "BcbBabBc", + 12 + ], + [ + "abCCcAcBB", + "BaAAAaAB", + 13 + ], + [ + "abCa", + "ABA", + 5 + ], + [ + "abCaBC", + "bCCaCaA", + 10 + ], + [ + "abCaC", + "acc", + 6 + ], + [ + "abCaCAbB", + "aCaba", + 8 + ], + [ + "abCabA", + "ACba", + 6 + ], + [ + "abCabbccb", + "CcAcA", + 14 + ], + [ + "abCacaaC", + "aC", + 12 + ], + [ + "abCb", + "cBCBaA", + 8 + ], + [ + "abCbBCcAa", + "a", + 16 + ], + [ + "abCbaCC", + "CAabaabBB", + 14 + ], + [ + "abCbbba", + "CcbBCBAA", + 12 + ], + [ + "abCc", + "Ca", + 6 + ], + [ + "abCcAbbC", + "B", + 15 + ], + [ + "abCcCCC", + "BbAaca", + 11 + ], + [ + "abCcCc", + "ACacA", + 8 + ], + [ + "abCcaA", + "aca", + 6 + ], + [ + "abCcaABB", + "AbcBb", + 8 + ], + [ + "aba", + "CBb", + 5 + ], + [ + "aba", + "CBbbaAb", + 10 + ], + [ + "aba", + "aCccA", + 7 + ], + [ + "aba", + "acaB", + 4 + ], + [ + "aba", + "bcCCa", + 8 + ], + [ + "aba", + "cBB", + 5 + ], + [ + "abaAAA", + "cAbB", + 10 + ], + [ + "abaACCcC", + "abacCBA", + 7 + ], + [ + "abaAaccC", + "CCaacc", + 8 + ], + [ + "abaAbb", + "a", + 10 + ], + [ + "abaBCABc", + "aCcccB", + 11 + ], + [ + "abaBaCca", + "aAcAbaB", + 12 + ], + [ + "abaC", + "Bba", + 4 + ], + [ + "abaCACccC", + "BBBBB", + 17 + ], + [ + "abaCBABaB", + "abacbacc", + 9 + ], + [ + "abaCCbcA", + "AcBBc", + 11 + ], + [ + "abaCbB", + "cC", + 10 + ], + [ + "abaCbaCB", + "AAcC", + 11 + ], + [ + "abaCbaa", + "aCCaCCA", + 9 + ], + [ + "abaaACcB", + "cBBCBBAbC", + 16 + ], + [ + "abab", + "CcaCC", + 8 + ], + [ + "abab", + "aCAAaaaB", + 11 + ], + [ + "abab", + "acBbA", + 6 + ], + [ + "ababA", + "CBBC", + 8 + ], + [ + "ababACcC", + "BC", + 13 + ], + [ + "ababCBBbB", + "CbC", + 14 + ], + [ + "ababa", + "CABCcCcb", + 14 + ], + [ + "ababcCb", + "aCAbCc", + 7 + ], + [ + "abacA", + "ABb", + 8 + ], + [ + "abacABc", + "babCCAbb", + 8 + ], + [ + "abacAc", + "BacbCaaB", + 11 + ], + [ + "abacBBa", + "CbCAa", + 9 + ], + [ + "abacBbaCC", + "a", + 16 + ], + [ + "abacCb", + "b", + 10 + ], + [ + "abaca", + "cAB", + 9 + ], + [ + "abacaCbBc", + "bACcACB", + 10 + ], + [ + "abaccABb", + "cBcCc", + 12 + ], + [ + "abaccaAcA", + "B", + 17 + ], + [ + "abacccc", + "Cba", + 10 + ], + [ + "abb", + "B", + 5 + ], + [ + "abb", + "CbBBAc", + 9 + ], + [ + "abb", + "aC", + 4 + ], + [ + "abb", + "bbbcaca", + 10 + ], + [ + "abbAAABBb", + "CbCcB", + 14 + ], + [ + "abbAcB", + "BbaaBc", + 8 + ], + [ + "abbBBCcB", + "aaa", + 14 + ], + [ + "abbBbAbcc", + "c", + 16 + ], + [ + "abbBbbbcC", + "aBbBaB", + 10 + ], + [ + "abbCBA", + "aA", + 8 + ], + [ + "abbCBA", + "bb", + 8 + ], + [ + "abbCBabac", + "CBAB", + 12 + ], + [ + "abbCaBB", + "Ab", + 11 + ], + [ + "abbCaBC", + "aBcc", + 9 + ], + [ + "abbCbbBB", + "cbbaaca", + 12 + ], + [ + "abbCc", + "bC", + 6 + ], + [ + "abbaA", + "BabaAAaBb", + 11 + ], + [ + "abbaBaaBc", + "CAcBbc", + 13 + ], + [ + "abbaBbc", + "aABbAcc", + 8 + ], + [ + "abbaCcba", + "Cba", + 10 + ], + [ + "abbbA", + "ACAcc", + 9 + ], + [ + "abbbBAbAA", + "aCACcAbA", + 10 + ], + [ + "abbbCCCaC", + "acBCBABcC", + 13 + ], + [ + "abbbb", + "cCcbBcb", + 9 + ], + [ + "abbbc", + "C", + 9 + ], + [ + "abbbca", + "BBAcBbAB", + 12 + ], + [ + "abbcABB", + "ac", + 10 + ], + [ + "abbcB", + "ABbcCB", + 4 + ], + [ + "abbcBac", + "bACca", + 9 + ], + [ + "abbccAa", + "AcC", + 10 + ], + [ + "abbccb", + "cbCb", + 7 + ], + [ + "abc", + "AbC", + 2 + ], + [ + "abc", + "BAAb", + 7 + ], + [ + "abc", + "C", + 5 + ], + [ + "abc", + "aB", + 3 + ], + [ + "abcAA", + "CAAabC", + 11 + ], + [ + "abcAaaccb", + "cAcAAcbcA", + 11 + ], + [ + "abcAbB", + "AbcCacc", + 8 + ], + [ + "abcAcaB", + "acBcBb", + 7 + ], + [ + "abcAcbbb", + "CaABc", + 13 + ], + [ + "abcB", + "AaCcAbCa", + 11 + ], + [ + "abcB", + "bbab", + 5 + ], + [ + "abcBaBb", + "cBBa", + 8 + ], + [ + "abcBacc", + "ACBa", + 8 + ], + [ + "abcBb", + "BBbcccBB", + 9 + ], + [ + "abcBbBAb", + "cB", + 12 + ], + [ + "abcC", + "BCc", + 5 + ], + [ + "abcCAB", + "CbCcC", + 8 + ], + [ + "abcCBAc", + "ACCBaA", + 7 + ], + [ + "abcCaBcCB", + "AAba", + 15 + ], + [ + "abcCbBCA", + "Ba", + 13 + ], + [ + "abca", + "cbaccAA", + 9 + ], + [ + "abcaCB", + "CCaaAB", + 8 + ], + [ + "abcb", + "a", + 6 + ], + [ + "abcbbC", + "BBc", + 9 + ], + [ + "abcbbbcb", + "b", + 14 + ], + [ + "abccC", + "bbcBab", + 8 + ], + [ + "abccCBabC", + "AbABaaabc", + 10 + ], + [ + "abccCaB", + "Bbaa", + 10 + ], + [ + "abccCcAa", + "BCbb", + 13 + ], + [ + "abccaB", + "aCABaba", + 9 + ], + [ + "abccaC", + "ABbCB", + 9 + ], + [ + "abccaCcBB", + "AAB", + 14 + ], + [ + "abccbCC", + "BAc", + 11 + ], + [ + "ac", + "A", + 3 + ], + [ + "ac", + "AAaCcbBa", + 12 + ], + [ + "ac", + "AAcCbbCca", + 15 + ], + [ + "ac", + "ACAcCa", + 9 + ], + [ + "ac", + "ACCBbAcCc", + 15 + ], + [ + "ac", + "B", + 4 + ], + [ + "ac", + "BAab", + 6 + ], + [ + "ac", + "BCCBbccb", + 14 + ], + [ + "ac", + "BCc", + 4 + ], + [ + "ac", + "BaBbbAA", + 12 + ], + [ + "ac", + "BcCACbB", + 12 + ], + [ + "ac", + "CBA", + 6 + ], + [ + "ac", + "CccBcaB", + 12 + ], + [ + "ac", + "aB", + 2 + ], + [ + "ac", + "aBBCacBbC", + 14 + ], + [ + "ac", + "aC", + 1 + ], + [ + "ac", + "aCcCC", + 6 + ], + [ + "ac", + "aaCaCaca", + 12 + ], + [ + "ac", + "ab", + 2 + ], + [ + "ac", + "acacCAbBA", + 14 + ], + [ + "ac", + "bACaaCCCC", + 15 + ], + [ + "ac", + "bAbaCCcBC", + 14 + ], + [ + "ac", + "bCCaAaa", + 12 + ], + [ + "ac", + "cBAcc", + 7 + ], + [ + "acA", + "AaCCAaabc", + 13 + ], + [ + "acA", + "aABBBACc", + 12 + ], + [ + "acA", + "ac", + 2 + ], + [ + "acA", + "cBcBb", + 8 + ], + [ + "acAA", + "bc", + 6 + ], + [ + "acAAABBa", + "cbcC", + 13 + ], + [ + "acAACBA", + "BcbaCbbA", + 8 + ], + [ + "acAB", + "ccbAAAa", + 10 + ], + [ + "acABCCA", + "BCcABBAa", + 9 + ], + [ + "acABc", + "BBcABbCba", + 11 + ], + [ + "acAC", + "A", + 6 + ], + [ + "acACCB", + "AAcBCba", + 9 + ], + [ + "acAaaAcba", + "BabCcbCbb", + 15 + ], + [ + "acAaaaBc", + "BacCBc", + 10 + ], + [ + "acAabACa", + "acaCB", + 8 + ], + [ + "acAabBbA", + "cabCb", + 8 + ], + [ + "acAacCc", + "BBCC", + 11 + ], + [ + "acAb", + "cc", + 6 + ], + [ + "acAbabcBa", + "ABABcaB", + 11 + ], + [ + "acAc", + "ABa", + 6 + ], + [ + "acAc", + "CcBCaa", + 9 + ], + [ + "acAc", + "aBbCaB", + 8 + ], + [ + "acAcBCCa", + "BaB", + 13 + ], + [ + "acAcCAc", + "cAbab", + 9 + ], + [ + "acAcaC", + "B", + 12 + ], + [ + "acAcabB", + "baaacbB", + 7 + ], + [ + "acAcbcAC", + "ccaCbCcc", + 8 + ], + [ + "acB", + "ABcAcBAcb", + 13 + ], + [ + "acB", + "acb", + 1 + ], + [ + "acB", + "bCccA", + 8 + ], + [ + "acB", + "cbabb", + 7 + ], + [ + "acBA", + "BcAaBCBAA", + 11 + ], + [ + "acBAcc", + "AAabb", + 10 + ], + [ + "acBB", + "AaaAbB", + 7 + ], + [ + "acBB", + "cA", + 6 + ], + [ + "acBBAb", + "bCcAbBCAC", + 11 + ], + [ + "acBBAbacB", + "aaCBB", + 12 + ], + [ + "acBBBbAcb", + "BAa", + 14 + ], + [ + "acBBCC", + "ccAbcBbCb", + 10 + ], + [ + "acBBCc", + "bcCaAbAa", + 13 + ], + [ + "acBBbBa", + "Cba", + 9 + ], + [ + "acBBcCC", + "ABbb", + 10 + ], + [ + "acBCBcabA", + "caCbca", + 9 + ], + [ + "acBCCbab", + "ccA", + 12 + ], + [ + "acBCa", + "BabbAcb", + 10 + ], + [ + "acBa", + "AC", + 6 + ], + [ + "acBaA", + "ABBCC", + 7 + ], + [ + "acBaAacc", + "bbab", + 13 + ], + [ + "acBaBCab", + "ac", + 12 + ], + [ + "acBaBaC", + "bbccbac", + 10 + ], + [ + "acBacCbAc", + "bBBACbaAA", + 11 + ], + [ + "acBb", + "CA", + 7 + ], + [ + "acBb", + "bCBAAB", + 8 + ], + [ + "acBbAc", + "aaaBCA", + 8 + ], + [ + "acBbCca", + "acA", + 9 + ], + [ + "acBcCcaB", + "CC", + 13 + ], + [ + "acBcabcAC", + "Aac", + 13 + ], + [ + "acC", + "AABcbaC", + 9 + ], + [ + "acC", + "AcBAaC", + 7 + ], + [ + "acC", + "CabBabaBC", + 14 + ], + [ + "acC", + "b", + 6 + ], + [ + "acC", + "baBCBCbAC", + 13 + ], + [ + "acC", + "baaCBCBC", + 11 + ], + [ + "acCA", + "C", + 6 + ], + [ + "acCA", + "aabBCaaaC", + 13 + ], + [ + "acCAAaCB", + "ba", + 14 + ], + [ + "acCAB", + "BccCcCbB", + 10 + ], + [ + "acCAa", + "c", + 8 + ], + [ + "acCAabBcc", + "Bb", + 16 + ], + [ + "acCAb", + "abB", + 7 + ], + [ + "acCAcc", + "cccCCacCC", + 10 + ], + [ + "acCB", + "B", + 6 + ], + [ + "acCBAcb", + "acaBcA", + 6 + ], + [ + "acCBBA", + "caccBbabC", + 9 + ], + [ + "acCBBb", + "aCbc", + 7 + ], + [ + "acCBCbaBC", + "bCabBc", + 11 + ], + [ + "acCBaaAc", + "BAAABCA", + 13 + ], + [ + "acCC", + "BAB", + 8 + ], + [ + "acCCABBb", + "Bbcca", + 13 + ], + [ + "acCCCaAb", + "acCCbAcca", + 9 + ], + [ + "acCCab", + "aB", + 9 + ], + [ + "acCCbA", + "CCAbCbBA", + 9 + ], + [ + "acCCbBcc", + "aAAaA", + 14 + ], + [ + "acCCcaC", + "AcbBabcCb", + 13 + ], + [ + "acCCcab", + "ccab", + 6 + ], + [ + "acCa", + "aaAcAbBbB", + 14 + ], + [ + "acCaAA", + "BAbcAcbC", + 13 + ], + [ + "acCaABcbb", + "A", + 16 + ], + [ + "acCaC", + "abBACBCB", + 10 + ], + [ + "acCaCa", + "aBa", + 8 + ], + [ + "acCb", + "aACBa", + 5 + ], + [ + "acCbBBa", + "BbbACCccb", + 15 + ], + [ + "acCbCCCBb", + "B", + 16 + ], + [ + "acCbbBB", + "bcca", + 11 + ], + [ + "acCc", + "A", + 7 + ], + [ + "acCc", + "AABBa", + 9 + ], + [ + "acCcA", + "CBBcaBCCA", + 11 + ], + [ + "acCcAcB", + "b", + 13 + ], + [ + "acCcB", + "BBCCBA", + 7 + ], + [ + "acCcaAA", + "b", + 14 + ], + [ + "acCcacB", + "cbAccBcb", + 10 + ], + [ + "acCcc", + "AC", + 7 + ], + [ + "aca", + "ACAB", + 5 + ], + [ + "aca", + "AaAc", + 6 + ], + [ + "aca", + "cAAbacBCa", + 12 + ], + [ + "aca", + "cbCCabAaB", + 14 + ], + [ + "acaA", + "C", + 7 + ], + [ + "acaA", + "aCbcACABa", + 11 + ], + [ + "acaAAAbc", + "B", + 15 + ], + [ + "acaABAcA", + "Cacca", + 10 + ], + [ + "acaAcb", + "cbc", + 8 + ], + [ + "acaBA", + "baBCbCBBC", + 13 + ], + [ + "acaBcacBc", + "b", + 17 + ], + [ + "acaBccaC", + "C", + 14 + ], + [ + "acaC", + "bccCAccA", + 12 + ], + [ + "acaCAaBB", + "Bc", + 14 + ], + [ + "acaCBBB", + "A", + 13 + ], + [ + "acaCaA", + "BCB", + 10 + ], + [ + "acaCaC", + "c", + 10 + ], + [ + "acaCbC", + "acaabCaa", + 6 + ], + [ + "acaCcaAB", + "ABAaaaba", + 12 + ], + [ + "acaCcbcB", + "CcbACBBc", + 10 + ], + [ + "acaCcbcc", + "C", + 14 + ], + [ + "acaa", + "AabBa", + 6 + ], + [ + "acaaBAA", + "cBBbaAB", + 10 + ], + [ + "acaaCC", + "cAACA", + 6 + ], + [ + "acaaaCCA", + "AaC", + 11 + ], + [ + "acaacAbB", + "bCbb", + 12 + ], + [ + "acaaca", + "cBACccCa", + 11 + ], + [ + "acaacb", + "ccCbBca", + 10 + ], + [ + "acabCb", + "ccaCbA", + 6 + ], + [ + "acabaBCbB", + "cab", + 12 + ], + [ + "acabcA", + "AB", + 10 + ], + [ + "acacA", + "bcBACcaa", + 10 + ], + [ + "acacbA", + "A", + 10 + ], + [ + "acacbABa", + "bCbcBa", + 9 + ], + [ + "acacbBa", + "BAbA", + 10 + ], + [ + "acb", + "AabAbA", + 8 + ], + [ + "acb", + "BCCa", + 7 + ], + [ + "acb", + "cBCB", + 6 + ], + [ + "acbA", + "AcBCbCa", + 8 + ], + [ + "acbA", + "aAaBCAB", + 9 + ], + [ + "acbAA", + "bc", + 8 + ], + [ + "acbACbbA", + "a", + 14 + ], + [ + "acbAbacc", + "caAcB", + 10 + ], + [ + "acbB", + "aBAb", + 5 + ], + [ + "acbBBC", + "caB", + 8 + ], + [ + "acbBaAAb", + "bbBcABBaC", + 13 + ], + [ + "acbBaC", + "CaA", + 9 + ], + [ + "acbBc", + "abB", + 4 + ], + [ + "acbC", + "ABABaBbca", + 13 + ], + [ + "acbC", + "bbBbcaaA", + 13 + ], + [ + "acbCA", + "A", + 8 + ], + [ + "acbCA", + "cBb", + 7 + ], + [ + "acbCBb", + "acAbCCaBc", + 8 + ], + [ + "acbCaaAaB", + "CaCc", + 14 + ], + [ + "acbCabC", + "cBACbcBC", + 10 + ], + [ + "acbaBaA", + "BBcA", + 9 + ], + [ + "acbabAa", + "CaAbcbc", + 10 + ], + [ + "acbabbaB", + "c", + 14 + ], + [ + "acbb", + "AAa", + 7 + ], + [ + "acbb", + "AbCaBCcBA", + 13 + ], + [ + "acbb", + "BbAca", + 9 + ], + [ + "acbb", + "CBaCBcCbA", + 12 + ], + [ + "acbbA", + "AcCAAbc", + 9 + ], + [ + "acbbAbA", + "CCCaccab", + 13 + ], + [ + "acbbcABBB", + "BcCBbb", + 11 + ], + [ + "acbc", + "aBAbB", + 6 + ], + [ + "acbcAa", + "BaCC", + 10 + ], + [ + "acbcBbc", + "B", + 12 + ], + [ + "acbcCAC", + "ACaAab", + 11 + ], + [ + "acbcCab", + "BAb", + 10 + ], + [ + "acbcaacbc", + "CbccCCBcb", + 11 + ], + [ + "acbcbbcc", + "CcAbaCCbb", + 13 + ], + [ + "acbccACA", + "b", + 14 + ], + [ + "acbccBcB", + "CCcc", + 10 + ], + [ + "acbccCB", + "bbbaaCAAB", + 12 + ], + [ + "acc", + "C", + 5 + ], + [ + "acc", + "bAac", + 5 + ], + [ + "accA", + "CBBaA", + 8 + ], + [ + "accAA", + "C", + 9 + ], + [ + "accABbb", + "cBbAAbaC", + 12 + ], + [ + "accAac", + "CCcacb", + 7 + ], + [ + "accAb", + "bcbAbB", + 6 + ], + [ + "accAcbAa", + "B", + 15 + ], + [ + "accB", + "bBbAb", + 9 + ], + [ + "accBC", + "bCCCCab", + 10 + ], + [ + "accBbcCaa", + "aaCcaBACB", + 12 + ], + [ + "accC", + "CCcbBc", + 8 + ], + [ + "accC", + "aa", + 6 + ], + [ + "accCAcACa", + "AABbCCc", + 14 + ], + [ + "accCCaCB", + "aCBba", + 11 + ], + [ + "accCCcA", + "cBbA", + 10 + ], + [ + "accCaB", + "aBaB", + 6 + ], + [ + "accCbbC", + "cBBcaa", + 12 + ], + [ + "acca", + "BBCAcbaba", + 13 + ], + [ + "acca", + "BBcCC", + 7 + ], + [ + "accaACAAc", + "cbbCABA", + 12 + ], + [ + "accaaAcAb", + "ccB", + 13 + ], + [ + "accaaC", + "CbA", + 10 + ], + [ + "accab", + "AAaAcA", + 9 + ], + [ + "accabbcB", + "aa", + 12 + ], + [ + "accac", + "C", + 9 + ], + [ + "accb", + "CBCAcCaBB", + 13 + ], + [ + "accbAA", + "Ba", + 10 + ], + [ + "accbAa", + "Ca", + 9 + ], + [ + "accbBac", + "caC", + 9 + ], + [ + "accbCcBAc", + "cbA", + 12 + ], + [ + "accbaAc", + "ACAaCAAA", + 11 + ], + [ + "accbb", + "CCcC", + 7 + ], + [ + "acccAB", + "cb", + 9 + ], + [ + "acccC", + "baaaaB", + 10 + ], + [ + "acccaAaB", + "C", + 15 + ], + [ + "acccc", + "cAAC", + 7 + ], + [ + "b", + "A", + 2 + ], + [ + "b", + "AAbAaCb", + 12 + ], + [ + "b", + "ABBBC", + 9 + ], + [ + "b", + "ABbCCBC", + 12 + ], + [ + "b", + "ABc", + 5 + ], + [ + "b", + "ABcba", + 8 + ], + [ + "b", + "ACAAC", + 10 + ], + [ + "b", + "ACBbAcabc", + 16 + ], + [ + "b", + "ACBbCBcCC", + 16 + ], + [ + "b", + "ACCaA", + 10 + ], + [ + "b", + "Aa", + 4 + ], + [ + "b", + "AaAbBCA", + 12 + ], + [ + "b", + "Aac", + 6 + ], + [ + "b", + "AacaBc", + 11 + ], + [ + "b", + "AbaC", + 6 + ], + [ + "b", + "Abcba", + 8 + ], + [ + "b", + "Ac", + 4 + ], + [ + "b", + "AcCbB", + 8 + ], + [ + "b", + "AcCbBca", + 12 + ], + [ + "b", + "AcaaCaAa", + 16 + ], + [ + "b", + "B", + 1 + ], + [ + "b", + "BBA", + 5 + ], + [ + "b", + "BBaaabB", + 12 + ], + [ + "b", + "BBbaBcba", + 14 + ], + [ + "b", + "BCBaC", + 9 + ], + [ + "b", + "BCcAABb", + 12 + ], + [ + "b", + "Ba", + 3 + ], + [ + "b", + "BaC", + 5 + ], + [ + "b", + "BaCbBc", + 10 + ], + [ + "b", + "Bac", + 5 + ], + [ + "b", + "BacBAc", + 11 + ], + [ + "b", + "Bb", + 2 + ], + [ + "b", + "BbA", + 4 + ], + [ + "b", + "BbBacbb", + 12 + ], + [ + "b", + "BbacaCc", + 12 + ], + [ + "b", + "BbbcAcAab", + 16 + ], + [ + "b", + "Bc", + 3 + ], + [ + "b", + "BcBA", + 7 + ], + [ + "b", + "BcBCAAaCB", + 17 + ], + [ + "b", + "BcC", + 5 + ], + [ + "b", + "BcCa", + 7 + ], + [ + "b", + "C", + 2 + ], + [ + "b", + "CAB", + 5 + ], + [ + "b", + "CACCBca", + 13 + ], + [ + "b", + "CBABaBAB", + 15 + ], + [ + "b", + "CBCCa", + 9 + ], + [ + "b", + "CBCCcC", + 11 + ], + [ + "b", + "CBCcaBBAB", + 17 + ], + [ + "b", + "CBaBaaCbB", + 16 + ], + [ + "b", + "CBaabA", + 10 + ], + [ + "b", + "CCBABBcC", + 15 + ], + [ + "b", + "CCC", + 6 + ], + [ + "b", + "CCbCA", + 8 + ], + [ + "b", + "Ca", + 4 + ], + [ + "b", + "CaCBcA", + 11 + ], + [ + "b", + "Cabacc", + 10 + ], + [ + "b", + "CabccCBCB", + 16 + ], + [ + "b", + "CacAbAAac", + 16 + ], + [ + "b", + "CbA", + 4 + ], + [ + "b", + "CbcBbA", + 10 + ], + [ + "b", + "Cc", + 4 + ], + [ + "b", + "CcAABbA", + 12 + ], + [ + "b", + "CcabBB", + 10 + ], + [ + "b", + "CcacCcAcC", + 18 + ], + [ + "b", + "CcbCACB", + 12 + ], + [ + "b", + "Ccbc", + 6 + ], + [ + "b", + "a", + 2 + ], + [ + "b", + "aA", + 4 + ], + [ + "b", + "aABBCcC", + 13 + ], + [ + "b", + "aABccbaCc", + 16 + ], + [ + "b", + "aACCCCba", + 14 + ], + [ + "b", + "aACCa", + 10 + ], + [ + "b", + "aAaBA", + 9 + ], + [ + "b", + "aAacBab", + 12 + ], + [ + "b", + "aB", + 3 + ], + [ + "b", + "aBCAac", + 11 + ], + [ + "b", + "aBCBC", + 9 + ], + [ + "b", + "aBCbacab", + 14 + ], + [ + "b", + "aBaCa", + 9 + ], + [ + "b", + "aBc", + 5 + ], + [ + "b", + "aC", + 4 + ], + [ + "b", + "aCBA", + 7 + ], + [ + "b", + "aCCa", + 8 + ], + [ + "b", + "aa", + 4 + ], + [ + "b", + "aabCCBca", + 14 + ], + [ + "b", + "aabbAb", + 10 + ], + [ + "b", + "aabbcC", + 10 + ], + [ + "b", + "ab", + 2 + ], + [ + "b", + "abB", + 4 + ], + [ + "b", + "abBBcb", + 10 + ], + [ + "b", + "abCCBCA", + 12 + ], + [ + "b", + "abcACcaa", + 14 + ], + [ + "b", + "abcBccCa", + 14 + ], + [ + "b", + "abca", + 6 + ], + [ + "b", + "ac", + 4 + ], + [ + "b", + "acACCaAca", + 18 + ], + [ + "b", + "acC", + 6 + ], + [ + "b", + "aca", + 6 + ], + [ + "b", + "acaabCC", + 12 + ], + [ + "b", + "b", + 0 + ], + [ + "b", + "bACAbB", + 10 + ], + [ + "b", + "bBAccb", + 10 + ], + [ + "b", + "bBBC", + 6 + ], + [ + "b", + "bBbaAA", + 10 + ], + [ + "b", + "bC", + 2 + ], + [ + "b", + "bCA", + 4 + ], + [ + "b", + "bCBCAbaCA", + 16 + ], + [ + "b", + "bCCbA", + 8 + ], + [ + "b", + "bCaAC", + 8 + ], + [ + "b", + "bCaCAB", + 10 + ], + [ + "b", + "bCabBB", + 10 + ], + [ + "b", + "bCbBbcA", + 12 + ], + [ + "b", + "bCcbAb", + 10 + ], + [ + "b", + "baBACBaaB", + 16 + ], + [ + "b", + "baCCbBC", + 12 + ], + [ + "b", + "baabBABb", + 14 + ], + [ + "b", + "baabbaCBB", + 16 + ], + [ + "b", + "baaccc", + 10 + ], + [ + "b", + "babBAcb", + 12 + ], + [ + "b", + "bb", + 2 + ], + [ + "b", + "bcBACbaBb", + 16 + ], + [ + "b", + "bcCa", + 6 + ], + [ + "b", + "bcCcAcbc", + 14 + ], + [ + "b", + "c", + 2 + ], + [ + "b", + "cABCaB", + 11 + ], + [ + "b", + "cAC", + 6 + ], + [ + "b", + "cAbBbBcc", + 14 + ], + [ + "b", + "cAbaBABBc", + 16 + ], + [ + "b", + "cAbaCBAa", + 14 + ], + [ + "b", + "cBAAAcaA", + 15 + ], + [ + "b", + "cBBcbAabb", + 16 + ], + [ + "b", + "cBCCAcb", + 12 + ], + [ + "b", + "cBCCa", + 9 + ], + [ + "b", + "cBCaCAc", + 13 + ], + [ + "b", + "cBbaBbcB", + 14 + ], + [ + "b", + "cBbbBaAa", + 14 + ], + [ + "b", + "cCAACba", + 12 + ], + [ + "b", + "cCaccAaCb", + 16 + ], + [ + "b", + "cCcbA", + 8 + ], + [ + "b", + "caA", + 6 + ], + [ + "b", + "caAb", + 6 + ], + [ + "b", + "caAccaCbb", + 16 + ], + [ + "b", + "caB", + 5 + ], + [ + "b", + "cabBbcA", + 12 + ], + [ + "b", + "cacbbBAb", + 14 + ], + [ + "b", + "cb", + 2 + ], + [ + "b", + "cbAa", + 6 + ], + [ + "b", + "cbAaCa", + 10 + ], + [ + "b", + "cbcBAcCbA", + 16 + ], + [ + "b", + "ccCaacc", + 14 + ], + [ + "b", + "ccCbaaaa", + 14 + ], + [ + "b", + "ccaC", + 8 + ], + [ + "b", + "ccbbcb", + 10 + ], + [ + "bA", + "AAAcACAbA", + 14 + ], + [ + "bA", + "AAbB", + 6 + ], + [ + "bA", + "ABaC", + 6 + ], + [ + "bA", + "ACBbbA", + 8 + ], + [ + "bA", + "ACBbccB", + 12 + ], + [ + "bA", + "ACbbBB", + 10 + ], + [ + "bA", + "Accc", + 8 + ], + [ + "bA", + "BAcCabc", + 11 + ], + [ + "bA", + "BCCcccB", + 13 + ], + [ + "bA", + "BabcCBCaa", + 15 + ], + [ + "bA", + "BbCaCBca", + 13 + ], + [ + "bA", + "BbbcbCCB", + 14 + ], + [ + "bA", + "Bbca", + 5 + ], + [ + "bA", + "C", + 4 + ], + [ + "bA", + "CAbABbBC", + 12 + ], + [ + "bA", + "CB", + 4 + ], + [ + "bA", + "CBCBa", + 8 + ], + [ + "bA", + "CbAaAaB", + 10 + ], + [ + "bA", + "CbcAAc", + 8 + ], + [ + "bA", + "CcAAcbcBC", + 16 + ], + [ + "bA", + "aAc", + 4 + ], + [ + "bA", + "aBCCcAcb", + 13 + ], + [ + "bA", + "aCb", + 6 + ], + [ + "bA", + "aCcbbc", + 10 + ], + [ + "bA", + "bAbcaAA", + 10 + ], + [ + "bA", + "bAc", + 2 + ], + [ + "bA", + "ba", + 1 + ], + [ + "bA", + "bb", + 2 + ], + [ + "bA", + "cAcCABaAb", + 15 + ], + [ + "bA", + "cCAABbBb", + 14 + ], + [ + "bA", + "cCC", + 6 + ], + [ + "bA", + "cabc", + 6 + ], + [ + "bA", + "ccCbcC", + 10 + ], + [ + "bAA", + "AabBB", + 8 + ], + [ + "bAA", + "BBAAaBCbC", + 13 + ], + [ + "bAA", + "C", + 6 + ], + [ + "bAA", + "CBaBcBb", + 12 + ], + [ + "bAA", + "CCBAc", + 7 + ], + [ + "bAA", + "abBBBAA", + 8 + ], + [ + "bAA", + "baacAbb", + 9 + ], + [ + "bAA", + "bcbBccAb", + 12 + ], + [ + "bAAA", + "C", + 8 + ], + [ + "bAAA", + "bBAAC", + 4 + ], + [ + "bAAAA", + "c", + 10 + ], + [ + "bAAAAbaCa", + "abacbC", + 12 + ], + [ + "bAAACbbb", + "Aaa", + 12 + ], + [ + "bAAACccC", + "CC", + 12 + ], + [ + "bAAAacAc", + "caC", + 12 + ], + [ + "bAAAbABC", + "CBCbBa", + 12 + ], + [ + "bAAB", + "bC", + 6 + ], + [ + "bAABaCA", + "A", + 12 + ], + [ + "bAABb", + "CaBBB", + 6 + ], + [ + "bAABcbbB", + "CbACCB", + 11 + ], + [ + "bAAC", + "AabbbaBA", + 13 + ], + [ + "bAAC", + "Acb", + 6 + ], + [ + "bAAC", + "aaB", + 6 + ], + [ + "bAACcACbc", + "Aaa", + 14 + ], + [ + "bAAa", + "AaABbabC", + 11 + ], + [ + "bAAa", + "bCAbbaa", + 7 + ], + [ + "bAAaCba", + "bAca", + 7 + ], + [ + "bAAaaaa", + "BC", + 13 + ], + [ + "bAAbAab", + "CBcA", + 12 + ], + [ + "bAAbCa", + "C", + 10 + ], + [ + "bAAbb", + "A", + 8 + ], + [ + "bAAc", + "CCAbca", + 8 + ], + [ + "bAAc", + "cCBAba", + 9 + ], + [ + "bAAcA", + "bbc", + 6 + ], + [ + "bAAccABbb", + "aAc", + 13 + ], + [ + "bAAccaCC", + "A", + 14 + ], + [ + "bAB", + "ACBcB", + 7 + ], + [ + "bAB", + "CbAA", + 4 + ], + [ + "bAB", + "bbABC", + 4 + ], + [ + "bABAC", + "BCaabaCBC", + 12 + ], + [ + "bABACCCB", + "abB", + 12 + ], + [ + "bABAaB", + "cCCCBbc", + 13 + ], + [ + "bABAaCBBA", + "BAbA", + 11 + ], + [ + "bABAaba", + "A", + 12 + ], + [ + "bABAba", + "BBBAccBA", + 9 + ], + [ + "bABAbbCbB", + "bA", + 14 + ], + [ + "bABAcCCb", + "abCaB", + 11 + ], + [ + "bABBCCC", + "bbCbBc", + 10 + ], + [ + "bABBa", + "bA", + 6 + ], + [ + "bABBcAc", + "bAC", + 9 + ], + [ + "bABC", + "AbBca", + 7 + ], + [ + "bABCBcAc", + "cBCAA", + 10 + ], + [ + "bABCC", + "aBCa", + 5 + ], + [ + "bABCCbbbC", + "cABACBBa", + 10 + ], + [ + "bABCaBCa", + "CaBbB", + 10 + ], + [ + "bABCbaB", + "ACCaCBc", + 10 + ], + [ + "bABa", + "BA", + 5 + ], + [ + "bABa", + "BAB", + 3 + ], + [ + "bABaCBBAa", + "Aa", + 14 + ], + [ + "bABb", + "acA", + 7 + ], + [ + "bABb", + "ccCA", + 8 + ], + [ + "bABbAB", + "ABCBCACc", + 11 + ], + [ + "bABbAC", + "bcBaCcAb", + 10 + ], + [ + "bABbBCB", + "cb", + 12 + ], + [ + "bABbaB", + "cAcAbbCAb", + 11 + ], + [ + "bABbaBAA", + "C", + 16 + ], + [ + "bABbbABBB", + "cAcb", + 14 + ], + [ + "bABbbbC", + "a", + 13 + ], + [ + "bABbcCab", + "ccccaa", + 11 + ], + [ + "bAC", + "AcAbc", + 7 + ], + [ + "bAC", + "bCcbAabb", + 12 + ], + [ + "bACA", + "ACaAAAaC", + 12 + ], + [ + "bACA", + "CAc", + 5 + ], + [ + "bACA", + "c", + 7 + ], + [ + "bACACAAa", + "cbBbC", + 14 + ], + [ + "bACAb", + "Cbc", + 8 + ], + [ + "bACAcc", + "BacBcAB", + 9 + ], + [ + "bACB", + "cBccC", + 8 + ], + [ + "bACBAC", + "BCCABaC", + 6 + ], + [ + "bACBBaA", + "bBACB", + 8 + ], + [ + "bACBCbb", + "b", + 12 + ], + [ + "bACBa", + "BCC", + 7 + ], + [ + "bACBaAcAb", + "C", + 16 + ], + [ + "bACBabABB", + "aCA", + 13 + ], + [ + "bACBcB", + "accBbaCcC", + 13 + ], + [ + "bACCaCcBb", + "aBaBcb", + 11 + ], + [ + "bACaBC", + "bA", + 8 + ], + [ + "bACaCCBAB", + "aaBacb", + 13 + ], + [ + "bACaCcC", + "aBCac", + 8 + ], + [ + "bACab", + "aBcBcAB", + 10 + ], + [ + "bACac", + "Bc", + 7 + ], + [ + "bACac", + "cBAacCAcB", + 10 + ], + [ + "bACbAA", + "B", + 11 + ], + [ + "bACbBbc", + "CbcAcBcA", + 11 + ], + [ + "bACc", + "bcA", + 5 + ], + [ + "bACc", + "cCb", + 6 + ], + [ + "bACcABb", + "BaC", + 10 + ], + [ + "bACcCaaC", + "AAbAbb", + 13 + ], + [ + "bAa", + "AaaACbAcc", + 14 + ], + [ + "bAa", + "AcAabb", + 8 + ], + [ + "bAa", + "bCbBCABBA", + 13 + ], + [ + "bAaA", + "aACcbaB", + 10 + ], + [ + "bAaAA", + "BacbCbBaa", + 14 + ], + [ + "bAaAAAa", + "cabAbA", + 9 + ], + [ + "bAaABAAC", + "AB", + 12 + ], + [ + "bAaAcA", + "cbC", + 11 + ], + [ + "bAaB", + "B", + 6 + ], + [ + "bAaB", + "acCCbb", + 11 + ], + [ + "bAaBAA", + "a", + 10 + ], + [ + "bAaBAcac", + "AABcaa", + 7 + ], + [ + "bAaBC", + "CBcaaaBa", + 10 + ], + [ + "bAaBa", + "C", + 10 + ], + [ + "bAaBaCBAB", + "CCbCCC", + 15 + ], + [ + "bAaBb", + "bCAA", + 7 + ], + [ + "bAaBbBc", + "AC", + 11 + ], + [ + "bAaBbc", + "cbbcAaab", + 10 + ], + [ + "bAaBc", + "a", + 8 + ], + [ + "bAaBc", + "cbCCBBbcc", + 12 + ], + [ + "bAaC", + "ABA", + 6 + ], + [ + "bAaC", + "BAaACAB", + 7 + ], + [ + "bAaCCa", + "CbCBB", + 10 + ], + [ + "bAaCa", + "bCBaABcbB", + 13 + ], + [ + "bAaCab", + "caBC", + 9 + ], + [ + "bAaa", + "AAcCbAC", + 11 + ], + [ + "bAaa", + "bBAAb", + 5 + ], + [ + "bAaaA", + "AbA", + 6 + ], + [ + "bAaaB", + "CABBC", + 8 + ], + [ + "bAaaB", + "bABBaC", + 6 + ], + [ + "bAaabaAc", + "cBaa", + 12 + ], + [ + "bAab", + "CcC", + 8 + ], + [ + "bAab", + "bAc", + 4 + ], + [ + "bAabAbC", + "A", + 12 + ], + [ + "bAabBACA", + "cCca", + 14 + ], + [ + "bAabBBCb", + "CbaCbA", + 12 + ], + [ + "bAabCAB", + "aA", + 10 + ], + [ + "bAabb", + "AaacAAA", + 11 + ], + [ + "bAabbC", + "babAb", + 6 + ], + [ + "bAabcA", + "bA", + 8 + ], + [ + "bAabcbc", + "BaAabcAaa", + 9 + ], + [ + "bAabccAa", + "aCbaB", + 12 + ], + [ + "bAac", + "ccACbbAA", + 13 + ], + [ + "bAacA", + "BBaACC", + 8 + ], + [ + "bAacAb", + "bacccBCc", + 10 + ], + [ + "bAacAbBca", + "C", + 17 + ], + [ + "bAacC", + "bbaAb", + 6 + ], + [ + "bAaccCB", + "c", + 12 + ], + [ + "bAb", + "ABCCAACCA", + 15 + ], + [ + "bAb", + "CCBAA", + 7 + ], + [ + "bAbACaC", + "bABcCAb", + 6 + ], + [ + "bAbAaC", + "BAbbA", + 6 + ], + [ + "bAbAabcab", + "CAabcBa", + 10 + ], + [ + "bAbAbcA", + "CAABBca", + 8 + ], + [ + "bAbBC", + "AACcbCca", + 11 + ], + [ + "bAbBCbaB", + "acacab", + 11 + ], + [ + "bAbBaCBcb", + "BaA", + 14 + ], + [ + "bAbBbbBbb", + "cAaacAC", + 16 + ], + [ + "bAbCAABaB", + "ACcBAccB", + 11 + ], + [ + "bAbCbCcCA", + "aBB", + 15 + ], + [ + "bAbCcB", + "aCAbA", + 10 + ], + [ + "bAba", + "CaAAb", + 8 + ], + [ + "bAbaCC", + "Bba", + 7 + ], + [ + "bAbab", + "CbCAcBcB", + 10 + ], + [ + "bAbb", + "acAbCBb", + 8 + ], + [ + "bAbb", + "b", + 6 + ], + [ + "bAbb", + "bAaAcBBab", + 11 + ], + [ + "bAbbB", + "AaACcBacC", + 14 + ], + [ + "bAbbaa", + "cCBC", + 11 + ], + [ + "bAbbbbBc", + "cABcBBC", + 9 + ], + [ + "bAbbbc", + "aCA", + 11 + ], + [ + "bAbc", + "Accbacc", + 9 + ], + [ + "bAbcBB", + "A", + 10 + ], + [ + "bAbcCaA", + "bACaCAcbC", + 11 + ], + [ + "bAbcCab", + "ABC", + 9 + ], + [ + "bAbcCbAA", + "BcBb", + 11 + ], + [ + "bAbcbA", + "CBCBCac", + 11 + ], + [ + "bAc", + "aaC", + 4 + ], + [ + "bAcA", + "bb", + 6 + ], + [ + "bAcAABA", + "aAAbca", + 9 + ], + [ + "bAcAAbA", + "BABabc", + 8 + ], + [ + "bAcAAbb", + "aC", + 12 + ], + [ + "bAcAbc", + "CAAcaaBa", + 10 + ], + [ + "bAcAc", + "BaC", + 7 + ], + [ + "bAcB", + "bcBC", + 4 + ], + [ + "bAcB", + "bccaA", + 6 + ], + [ + "bAcBAaaCa", + "aABCccaBa", + 12 + ], + [ + "bAcBAbBcC", + "B", + 16 + ], + [ + "bAcBBBABa", + "caA", + 14 + ], + [ + "bAcBCCbac", + "accBBAB", + 12 + ], + [ + "bAcBabbC", + "ca", + 12 + ], + [ + "bAcBbAb", + "cbaBA", + 9 + ], + [ + "bAcBbaA", + "AaBaaA", + 6 + ], + [ + "bAcC", + "Acac", + 5 + ], + [ + "bAcC", + "bba", + 6 + ], + [ + "bAcCAa", + "C", + 10 + ], + [ + "bAcCaCc", + "abbCcb", + 11 + ], + [ + "bAcCb", + "Bbcacac", + 9 + ], + [ + "bAcCbACCB", + "aA", + 15 + ], + [ + "bAcCcACA", + "ABCAaBB", + 11 + ], + [ + "bAcaAbA", + "baCCbBca", + 10 + ], + [ + "bAcac", + "BBbAbCccA", + 11 + ], + [ + "bAcb", + "aa", + 7 + ], + [ + "bAcb", + "cAbbb", + 6 + ], + [ + "bAcbAbBAC", + "CbBc", + 12 + ], + [ + "bAcbBbcb", + "cCcBBCaa", + 11 + ], + [ + "bAcc", + "aCcABC", + 9 + ], + [ + "bAccA", + "ccBaaCA", + 9 + ], + [ + "bAccCabB", + "aABCAAaAA", + 13 + ], + [ + "bAccCbb", + "BaAAcB", + 10 + ], + [ + "bAcca", + "CBbcBBBba", + 13 + ], + [ + "bAccaACaa", + "CCcBCaA", + 10 + ], + [ + "bAccaCCA", + "aABAABBCb", + 13 + ], + [ + "bAcccAC", + "ABC", + 10 + ], + [ + "bAcccAbaA", + "CBcCAbcC", + 11 + ], + [ + "bAcccaB", + "BccACBBC", + 10 + ], + [ + "bB", + "ACaAbC", + 10 + ], + [ + "bB", + "BCbCb", + 7 + ], + [ + "bB", + "Baa", + 5 + ], + [ + "bB", + "BbbbBAb", + 10 + ], + [ + "bB", + "Bcba", + 6 + ], + [ + "bB", + "CAAcBb", + 10 + ], + [ + "bB", + "CbbC", + 5 + ], + [ + "bB", + "aACCab", + 11 + ], + [ + "bB", + "aBaccb", + 10 + ], + [ + "bB", + "aBbC", + 6 + ], + [ + "bB", + "aCACcaA", + 14 + ], + [ + "bB", + "aaAABaCCc", + 16 + ], + [ + "bB", + "ac", + 4 + ], + [ + "bB", + "acACccAac", + 18 + ], + [ + "bB", + "bAAacb", + 9 + ], + [ + "bB", + "bBCccbcC", + 12 + ], + [ + "bB", + "bBbbcb", + 8 + ], + [ + "bB", + "bCbBAAbCc", + 14 + ], + [ + "bB", + "ba", + 2 + ], + [ + "bB", + "baAbcC", + 9 + ], + [ + "bB", + "bcBbACaa", + 12 + ], + [ + "bB", + "c", + 4 + ], + [ + "bB", + "cBCcc", + 8 + ], + [ + "bB", + "cCBa", + 6 + ], + [ + "bB", + "caBc", + 6 + ], + [ + "bB", + "caCCACb", + 13 + ], + [ + "bBA", + "AB", + 4 + ], + [ + "bBA", + "B", + 4 + ], + [ + "bBA", + "abBCbccC", + 12 + ], + [ + "bBA", + "bCaaa", + 7 + ], + [ + "bBA", + "cBB", + 4 + ], + [ + "bBAA", + "cAb", + 6 + ], + [ + "bBAAba", + "C", + 12 + ], + [ + "bBAAcb", + "BCcBABB", + 10 + ], + [ + "bBAB", + "ccaa", + 7 + ], + [ + "bBABbBc", + "Bb", + 10 + ], + [ + "bBAC", + "aCBb", + 8 + ], + [ + "bBACA", + "bbcaBB", + 8 + ], + [ + "bBACBA", + "CA", + 8 + ], + [ + "bBACBABc", + "ca", + 14 + ], + [ + "bBACCbCB", + "B", + 14 + ], + [ + "bBACbaC", + "aabAbaCC", + 9 + ], + [ + "bBAa", + "CBBbBaa", + 7 + ], + [ + "bBAa", + "CabC", + 8 + ], + [ + "bBAa", + "cCcCCCA", + 13 + ], + [ + "bBAaBAcB", + "CbCaaAbAA", + 12 + ], + [ + "bBAaBcAaB", + "ACcb", + 13 + ], + [ + "bBAaC", + "acBaAcC", + 8 + ], + [ + "bBAaCB", + "bcBbCBBca", + 12 + ], + [ + "bBAaCc", + "Aca", + 9 + ], + [ + "bBAac", + "AcccCbBc", + 14 + ], + [ + "bBAacA", + "aBCbaAAA", + 10 + ], + [ + "bBAbCA", + "cBAaaCACb", + 10 + ], + [ + "bBAba", + "B", + 8 + ], + [ + "bBAbac", + "cBbAaccb", + 10 + ], + [ + "bBAc", + "Bc", + 4 + ], + [ + "bBAcAbca", + "baB", + 12 + ], + [ + "bBAcBA", + "aAa", + 9 + ], + [ + "bBAcC", + "abbBbCBc", + 10 + ], + [ + "bBAcC", + "c", + 8 + ], + [ + "bBAca", + "Ba", + 6 + ], + [ + "bBAca", + "b", + 8 + ], + [ + "bBAca", + "c", + 8 + ], + [ + "bBB", + "ABACC", + 8 + ], + [ + "bBB", + "AcaBacAc", + 14 + ], + [ + "bBB", + "BCCBCB", + 7 + ], + [ + "bBB", + "Cba", + 5 + ], + [ + "bBB", + "bACbcbAc", + 12 + ], + [ + "bBBABBb", + "Cbab", + 10 + ], + [ + "bBBAa", + "c", + 10 + ], + [ + "bBBBB", + "AacCA", + 10 + ], + [ + "bBBBBAa", + "AbbBAB", + 8 + ], + [ + "bBBBCb", + "B", + 10 + ], + [ + "bBBBabC", + "abBacCCBA", + 13 + ], + [ + "bBBBc", + "AB", + 8 + ], + [ + "bBBC", + "B", + 6 + ], + [ + "bBBC", + "abAbBBcab", + 11 + ], + [ + "bBBCABbB", + "caaCC", + 14 + ], + [ + "bBBCAbB", + "BcBCBCcBc", + 10 + ], + [ + "bBBa", + "abbCAA", + 8 + ], + [ + "bBBaB", + "cacCCbAA", + 14 + ], + [ + "bBBaC", + "Bcc", + 7 + ], + [ + "bBBaaBC", + "bcbcbBba", + 11 + ], + [ + "bBBaaBb", + "a", + 12 + ], + [ + "bBBaabc", + "caaBba", + 10 + ], + [ + "bBBabac", + "aaAA", + 11 + ], + [ + "bBBb", + "Accaab", + 10 + ], + [ + "bBBb", + "aAacAbca", + 14 + ], + [ + "bBBbAcBB", + "BBAbBAb", + 9 + ], + [ + "bBBbBbbbB", + "cc", + 18 + ], + [ + "bBBbCa", + "BcC", + 8 + ], + [ + "bBBbaB", + "caAaaC", + 10 + ], + [ + "bBBbaBbCa", + "a", + 16 + ], + [ + "bBBbacabB", + "Ba", + 14 + ], + [ + "bBBbcc", + "bcA", + 8 + ], + [ + "bBBc", + "ABBbACc", + 8 + ], + [ + "bBBc", + "BAAb", + 7 + ], + [ + "bBBcA", + "caB", + 8 + ], + [ + "bBBcaca", + "CBBBbABcb", + 10 + ], + [ + "bBC", + "AB", + 4 + ], + [ + "bBC", + "aaCaCAcBc", + 15 + ], + [ + "bBC", + "bcaBACB", + 8 + ], + [ + "bBC", + "cAB", + 6 + ], + [ + "bBC", + "cBaCcbca", + 12 + ], + [ + "bBCA", + "AAc", + 7 + ], + [ + "bBCA", + "bCCACBc", + 8 + ], + [ + "bBCA", + "babCCBAC", + 9 + ], + [ + "bBCA", + "cBaabcA", + 9 + ], + [ + "bBCAB", + "ACcBBBBab", + 13 + ], + [ + "bBCABBA", + "BCabbCAB", + 9 + ], + [ + "bBCAbAb", + "caAbA", + 8 + ], + [ + "bBCAbBba", + "CbbBbbC", + 10 + ], + [ + "bBCAcBcCA", + "B", + 16 + ], + [ + "bBCBa", + "cbAAB", + 8 + ], + [ + "bBCBaBCaa", + "bA", + 15 + ], + [ + "bBCBaC", + "aABCAca", + 10 + ], + [ + "bBCBabBC", + "cCAc", + 12 + ], + [ + "bBCC", + "baAbacaA", + 12 + ], + [ + "bBCCA", + "aa", + 9 + ], + [ + "bBCCCCABc", + "babacAA", + 13 + ], + [ + "bBCCCb", + "ACc", + 9 + ], + [ + "bBCCbAb", + "a", + 13 + ], + [ + "bBCaABB", + "CbACac", + 10 + ], + [ + "bBCaCCC", + "ABccBC", + 8 + ], + [ + "bBCaabcAA", + "CBABCC", + 13 + ], + [ + "bBCac", + "BA", + 7 + ], + [ + "bBCacbCA", + "BaCBcCBC", + 10 + ], + [ + "bBCb", + "bBcCA", + 4 + ], + [ + "bBCbAAaAC", + "CCbCCA", + 12 + ], + [ + "bBCbBa", + "AbBaACCB", + 10 + ], + [ + "bBCbb", + "aCcaC", + 9 + ], + [ + "bBCc", + "ccB", + 7 + ], + [ + "bBCcaAAa", + "caabAbC", + 13 + ], + [ + "bBa", + "Bba", + 2 + ], + [ + "bBa", + "b", + 4 + ], + [ + "bBa", + "bBcAca", + 6 + ], + [ + "bBa", + "bCA", + 3 + ], + [ + "bBa", + "cACaAbBa", + 10 + ], + [ + "bBa", + "ccBcbcAcc", + 15 + ], + [ + "bBaABCcC", + "ABA", + 12 + ], + [ + "bBaACBaB", + "BCBBABbb", + 10 + ], + [ + "bBaAaA", + "Bb", + 10 + ], + [ + "bBaAaBc", + "BAbcaACBc", + 8 + ], + [ + "bBaAaC", + "cCBACaaA", + 10 + ], + [ + "bBaAb", + "bACbbacAB", + 10 + ], + [ + "bBaBCAAaa", + "CACBAc", + 13 + ], + [ + "bBaBCCcA", + "bb", + 13 + ], + [ + "bBaBCaAaB", + "bCAbCbbB", + 10 + ], + [ + "bBaBCcBcB", + "cabcc", + 11 + ], + [ + "bBaBa", + "BC", + 8 + ], + [ + "bBaBbAbAB", + "aBAAbCCBA", + 12 + ], + [ + "bBaBbb", + "BaCAbbb", + 7 + ], + [ + "bBaC", + "BAaAcb", + 8 + ], + [ + "bBaCbcC", + "bA", + 11 + ], + [ + "bBaCcAA", + "cAbb", + 12 + ], + [ + "bBaaBb", + "Caa", + 8 + ], + [ + "bBaaBcBbb", + "cABAaA", + 15 + ], + [ + "bBaaCABa", + "bcbaBcbC", + 11 + ], + [ + "bBaaCa", + "bAAC", + 6 + ], + [ + "bBaabbbbc", + "cbA", + 16 + ], + [ + "bBaacaC", + "bccaBC", + 8 + ], + [ + "bBabAcBA", + "ccaAbA", + 9 + ], + [ + "bBabB", + "BabcBBB", + 8 + ], + [ + "bBabC", + "ABc", + 7 + ], + [ + "bBabaAC", + "ccaCb", + 12 + ], + [ + "bBac", + "AbaAcAaB", + 11 + ], + [ + "bBac", + "BBCc", + 3 + ], + [ + "bBacbBcb", + "bCbc", + 9 + ], + [ + "bBb", + "AA", + 6 + ], + [ + "bBb", + "AbCaacc", + 12 + ], + [ + "bBb", + "CaaCCCaA", + 16 + ], + [ + "bBb", + "Ccac", + 8 + ], + [ + "bBb", + "a", + 6 + ], + [ + "bBb", + "aCC", + 6 + ], + [ + "bBb", + "baAC", + 6 + ], + [ + "bBb", + "cBA", + 4 + ], + [ + "bBb", + "caBaCBa", + 11 + ], + [ + "bBbA", + "C", + 8 + ], + [ + "bBbA", + "CBcBAA", + 7 + ], + [ + "bBbA", + "caBBABaBa", + 13 + ], + [ + "bBbAAa", + "aabbb", + 10 + ], + [ + "bBbB", + "AcbAA", + 8 + ], + [ + "bBbB", + "a", + 8 + ], + [ + "bBbBBaBAc", + "c", + 16 + ], + [ + "bBbBBba", + "Bbc", + 10 + ], + [ + "bBbBb", + "B", + 8 + ], + [ + "bBbCA", + "abBBcBBbc", + 12 + ], + [ + "bBbCCca", + "aCaCBCB", + 11 + ], + [ + "bBba", + "aAA", + 7 + ], + [ + "bBba", + "abB", + 6 + ], + [ + "bBbaA", + "cBCBCcCCB", + 15 + ], + [ + "bBbaC", + "bc", + 7 + ], + [ + "bBbaCba", + "aBBccAaB", + 10 + ], + [ + "bBbabBAC", + "bCBa", + 11 + ], + [ + "bBbacbBCA", + "BA", + 14 + ], + [ + "bBbbCA", + "bACbBAa", + 8 + ], + [ + "bBbbbc", + "c", + 10 + ], + [ + "bBbcAAba", + "cC", + 14 + ], + [ + "bBbcBBCa", + "b", + 14 + ], + [ + "bBbcCC", + "aacCBb", + 10 + ], + [ + "bBbcCC", + "acabCCb", + 9 + ], + [ + "bBbcbA", + "BcBCabB", + 9 + ], + [ + "bBbcbA", + "cBaCcCbB", + 10 + ], + [ + "bBbcbBa", + "BbA", + 9 + ], + [ + "bBc", + "A", + 6 + ], + [ + "bBc", + "ACA", + 6 + ], + [ + "bBc", + "CC", + 5 + ], + [ + "bBc", + "bCbA", + 5 + ], + [ + "bBc", + "bbcA", + 3 + ], + [ + "bBcA", + "BaCba", + 7 + ], + [ + "bBcAACbB", + "bCba", + 10 + ], + [ + "bBcABCb", + "BAca", + 9 + ], + [ + "bBcAa", + "Ca", + 7 + ], + [ + "bBcAcBabB", + "ccaCAb", + 11 + ], + [ + "bBcAccBAc", + "cAc", + 12 + ], + [ + "bBcB", + "Ca", + 7 + ], + [ + "bBcBAbB", + "A", + 12 + ], + [ + "bBcBAca", + "BcbC", + 8 + ], + [ + "bBcBc", + "C", + 9 + ], + [ + "bBcCCbcb", + "CAAcacCaC", + 14 + ], + [ + "bBcCaAb", + "CbbbCa", + 9 + ], + [ + "bBcCbAAa", + "c", + 14 + ], + [ + "bBcaaaCAC", + "ACBbc", + 16 + ], + [ + "bBcb", + "bCCac", + 7 + ], + [ + "bBcba", + "bba", + 4 + ], + [ + "bBcbaB", + "BaCCbc", + 10 + ], + [ + "bBcbaBAbB", + "AAb", + 13 + ], + [ + "bBcbaBbAB", + "c", + 16 + ], + [ + "bBcc", + "CcBABA", + 10 + ], + [ + "bBcc", + "aAc", + 6 + ], + [ + "bBccACBbA", + "CaCCCB", + 12 + ], + [ + "bBccBc", + "Caac", + 9 + ], + [ + "bBccC", + "bAcc", + 4 + ], + [ + "bBccb", + "bccAbBbC", + 10 + ], + [ + "bBccb", + "caBAA", + 10 + ], + [ + "bBccbBbCb", + "AAAbbaBA", + 15 + ], + [ + "bBccbBccC", + "c", + 16 + ], + [ + "bBccbb", + "AaABa", + 11 + ], + [ + "bBcccB", + "bcCAca", + 7 + ], + [ + "bC", + "A", + 4 + ], + [ + "bC", + "ACBBaBa", + 12 + ], + [ + "bC", + "Abc", + 3 + ], + [ + "bC", + "BAAcb", + 8 + ], + [ + "bC", + "BAa", + 5 + ], + [ + "bC", + "BAcaBCAcc", + 15 + ], + [ + "bC", + "BCbcCA", + 8 + ], + [ + "bC", + "BacAcb", + 10 + ], + [ + "bC", + "CC", + 2 + ], + [ + "bC", + "CbBcAbcc", + 13 + ], + [ + "bC", + "aBaCA", + 7 + ], + [ + "bC", + "aCCbCABBB", + 14 + ], + [ + "bC", + "aaBBCAA", + 11 + ], + [ + "bC", + "aaCbaAcB", + 13 + ], + [ + "bC", + "acCcbcB", + 11 + ], + [ + "bC", + "b", + 2 + ], + [ + "bC", + "bBBBC", + 6 + ], + [ + "bC", + "bBb", + 4 + ], + [ + "bC", + "bC", + 0 + ], + [ + "bC", + "baAAcb", + 9 + ], + [ + "bC", + "bac", + 3 + ], + [ + "bC", + "bbBb", + 6 + ], + [ + "bC", + "c", + 3 + ], + [ + "bC", + "cABAac", + 10 + ], + [ + "bC", + "cABcACACa", + 15 + ], + [ + "bC", + "cAaCb", + 8 + ], + [ + "bC", + "cBbB", + 6 + ], + [ + "bC", + "cBcCbcc", + 11 + ], + [ + "bC", + "cBcCcAa", + 11 + ], + [ + "bC", + "cccCBcaba", + 16 + ], + [ + "bCA", + "BbCaCc", + 7 + ], + [ + "bCA", + "ac", + 5 + ], + [ + "bCA", + "bCB", + 2 + ], + [ + "bCA", + "ba", + 3 + ], + [ + "bCA", + "cbcbAc", + 7 + ], + [ + "bCAAA", + "Cc", + 8 + ], + [ + "bCAAA", + "cBabbA", + 9 + ], + [ + "bCAAABc", + "Aabab", + 11 + ], + [ + "bCAABaCbc", + "Cab", + 12 + ], + [ + "bCAABccA", + "AaacCBBcB", + 13 + ], + [ + "bCAAC", + "bBAaCcc", + 7 + ], + [ + "bCAACaCa", + "CcAACaC", + 5 + ], + [ + "bCAAaBbCA", + "CbaAcB", + 13 + ], + [ + "bCAB", + "bAAA", + 4 + ], + [ + "bCABB", + "bA", + 6 + ], + [ + "bCABBCAA", + "bBCbcCc", + 11 + ], + [ + "bCABBcB", + "bBbACbaBb", + 11 + ], + [ + "bCABa", + "AaAa", + 6 + ], + [ + "bCABaBAcc", + "CBbaCCba", + 13 + ], + [ + "bCAC", + "ABCcc", + 6 + ], + [ + "bCAC", + "caCa", + 6 + ], + [ + "bCAC", + "cbCcb", + 6 + ], + [ + "bCACBA", + "cbac", + 10 + ], + [ + "bCACBB", + "Bcb", + 9 + ], + [ + "bCACa", + "c", + 9 + ], + [ + "bCACaaC", + "Cacaaa", + 6 + ], + [ + "bCACaaa", + "cC", + 11 + ], + [ + "bCACb", + "B", + 9 + ], + [ + "bCACbA", + "Cb", + 8 + ], + [ + "bCAaCB", + "aCAbcCbB", + 8 + ], + [ + "bCAaCbac", + "a", + 14 + ], + [ + "bCAaccaCC", + "b", + 16 + ], + [ + "bCAbAAcA", + "bBBCAabAc", + 10 + ], + [ + "bCAbab", + "ca", + 9 + ], + [ + "bCAbb", + "CBAcBAcBB", + 12 + ], + [ + "bCAc", + "BaCAaaBa", + 11 + ], + [ + "bCAcBA", + "CBBcCCA", + 10 + ], + [ + "bCAcC", + "BbaccaCA", + 10 + ], + [ + "bCAcC", + "BcA", + 6 + ], + [ + "bCAcc", + "cbCAB", + 6 + ], + [ + "bCB", + "CCabaC", + 9 + ], + [ + "bCB", + "abaaAbbAC", + 15 + ], + [ + "bCB", + "bCAca", + 6 + ], + [ + "bCB", + "cBAB", + 5 + ], + [ + "bCBA", + "BccBbcAA", + 10 + ], + [ + "bCBAAa", + "c", + 11 + ], + [ + "bCBBBCbc", + "CAbbbB", + 10 + ], + [ + "bCBBBcB", + "BBaBCBbC", + 10 + ], + [ + "bCBBa", + "CccaaC", + 9 + ], + [ + "bCBBbCc", + "bBaAB", + 10 + ], + [ + "bCBC", + "AbaCcaCB", + 10 + ], + [ + "bCBC", + "CcbaCaA", + 10 + ], + [ + "bCBC", + "aCAbcbCC", + 10 + ], + [ + "bCBCAB", + "C", + 10 + ], + [ + "bCBCACBb", + "bBacBCaA", + 11 + ], + [ + "bCBCBcbc", + "bA", + 14 + ], + [ + "bCBCaAc", + "a", + 12 + ], + [ + "bCBCbC", + "A", + 12 + ], + [ + "bCBa", + "Ba", + 4 + ], + [ + "bCBaAb", + "CABCCcb", + 10 + ], + [ + "bCBaabC", + "ACb", + 10 + ], + [ + "bCBabCa", + "cAbaccCC", + 11 + ], + [ + "bCBacABab", + "ccAacAaCc", + 11 + ], + [ + "bCBacaAB", + "ACbABB", + 10 + ], + [ + "bCBb", + "aaAbAbbC", + 11 + ], + [ + "bCBb", + "cBabcA", + 9 + ], + [ + "bCBb", + "cBcccaA", + 12 + ], + [ + "bCBbAaAb", + "BabA", + 11 + ], + [ + "bCBbAac", + "CBcca", + 8 + ], + [ + "bCBbAcC", + "CBbBbb", + 8 + ], + [ + "bCBbC", + "CA", + 8 + ], + [ + "bCBbaCCA", + "BAAab", + 13 + ], + [ + "bCBbabb", + "BcCBA", + 10 + ], + [ + "bCBbbCb", + "ABcbAba", + 10 + ], + [ + "bCBc", + "bbBACc", + 6 + ], + [ + "bCBcB", + "bCAbccACb", + 10 + ], + [ + "bCBcBBc", + "b", + 12 + ], + [ + "bCBca", + "cAABaCCa", + 11 + ], + [ + "bCBcabA", + "CAcbbcBcB", + 14 + ], + [ + "bCBcba", + "ABAcbc", + 8 + ], + [ + "bCBcccbC", + "Cbbbc", + 10 + ], + [ + "bCC", + "A", + 6 + ], + [ + "bCC", + "ABBbCCC", + 8 + ], + [ + "bCC", + "AaC", + 4 + ], + [ + "bCC", + "BB", + 5 + ], + [ + "bCC", + "a", + 6 + ], + [ + "bCC", + "aCbBaaCB", + 12 + ], + [ + "bCC", + "b", + 4 + ], + [ + "bCC", + "bbBaCaCAc", + 12 + ], + [ + "bCC", + "cB", + 5 + ], + [ + "bCCAACA", + "bc", + 11 + ], + [ + "bCCAAbAa", + "aC", + 14 + ], + [ + "bCCACBb", + "BcAA", + 10 + ], + [ + "bCCAc", + "bcBCABabC", + 10 + ], + [ + "bCCBACAa", + "cCB", + 11 + ], + [ + "bCCBC", + "CbbbACC", + 10 + ], + [ + "bCCBaBa", + "BC", + 11 + ], + [ + "bCCBbBAA", + "ACBbbBc", + 9 + ], + [ + "bCCCABcb", + "BaBbbAb", + 12 + ], + [ + "bCCCa", + "aA", + 9 + ], + [ + "bCCCbccc", + "aCAA", + 14 + ], + [ + "bCCa", + "AabcB", + 9 + ], + [ + "bCCa", + "BccBa", + 5 + ], + [ + "bCCa", + "bCACAaBb", + 8 + ], + [ + "bCCaA", + "cbAbaAA", + 8 + ], + [ + "bCCaAbBB", + "CcC", + 13 + ], + [ + "bCCaBa", + "AcCabCAc", + 9 + ], + [ + "bCCaCc", + "abAcCA", + 9 + ], + [ + "bCCaa", + "cA", + 8 + ], + [ + "bCCaaCaa", + "cbcc", + 14 + ], + [ + "bCCab", + "B", + 9 + ], + [ + "bCCaccbbB", + "cC", + 15 + ], + [ + "bCCb", + "cBBaBB", + 10 + ], + [ + "bCCbA", + "bcBC", + 6 + ], + [ + "bCCbACBBB", + "CA", + 14 + ], + [ + "bCCbB", + "aaBcCbAA", + 10 + ], + [ + "bCCbCc", + "aACbC", + 6 + ], + [ + "bCCbcA", + "caACc", + 10 + ], + [ + "bCCcAcAB", + "aCAB", + 10 + ], + [ + "bCCcc", + "aACCcacB", + 8 + ], + [ + "bCCccC", + "aabAb", + 12 + ], + [ + "bCa", + "Cb", + 4 + ], + [ + "bCa", + "aBbb", + 7 + ], + [ + "bCa", + "bBACAbba", + 10 + ], + [ + "bCa", + "baba", + 4 + ], + [ + "bCa", + "cbacb", + 7 + ], + [ + "bCa", + "ccaCaCCc", + 12 + ], + [ + "bCaA", + "AABbbA", + 9 + ], + [ + "bCaA", + "CBc", + 6 + ], + [ + "bCaAC", + "ACaaABaCa", + 10 + ], + [ + "bCaBAc", + "bbbBcbcAc", + 10 + ], + [ + "bCaBBBA", + "caCcBBCcB", + 12 + ], + [ + "bCaBBC", + "cacbBC", + 6 + ], + [ + "bCaBbCAC", + "aaCAcCAbC", + 11 + ], + [ + "bCaCAabc", + "bBaB", + 11 + ], + [ + "bCaCAcaC", + "bcccaa", + 8 + ], + [ + "bCaCCC", + "cAbabbACA", + 14 + ], + [ + "bCaCcB", + "ABbbcCABC", + 12 + ], + [ + "bCaCcac", + "CBbCAA", + 10 + ], + [ + "bCaa", + "a", + 6 + ], + [ + "bCaa", + "aBC", + 7 + ], + [ + "bCaabBC", + "CCABcA", + 10 + ], + [ + "bCabAacbC", + "BAB", + 14 + ], + [ + "bCabCc", + "CA", + 9 + ], + [ + "bCabaAAB", + "A", + 14 + ], + [ + "bCabbAacb", + "Cba", + 12 + ], + [ + "bCabbC", + "CAacA", + 9 + ], + [ + "bCac", + "C", + 6 + ], + [ + "bCac", + "cC", + 6 + ], + [ + "bCacAbBa", + "a", + 14 + ], + [ + "bCacBA", + "abB", + 8 + ], + [ + "bCacCcB", + "aAabBBbC", + 13 + ], + [ + "bCaccBAa", + "CB", + 12 + ], + [ + "bCb", + "aCBc", + 5 + ], + [ + "bCb", + "ab", + 4 + ], + [ + "bCb", + "ccA", + 5 + ], + [ + "bCbA", + "ab", + 6 + ], + [ + "bCbAAAB", + "AccbcBaB", + 10 + ], + [ + "bCbAB", + "BcBB", + 5 + ], + [ + "bCbACcbc", + "b", + 14 + ], + [ + "bCbAa", + "acCBABB", + 9 + ], + [ + "bCbAbcBc", + "b", + 14 + ], + [ + "bCbB", + "b", + 6 + ], + [ + "bCbBabC", + "cbacBCaBc", + 10 + ], + [ + "bCbBacaA", + "aBAaBCaa", + 11 + ], + [ + "bCbBbbbC", + "a", + 16 + ], + [ + "bCbBbcAb", + "ba", + 13 + ], + [ + "bCbCAbB", + "CABBbb", + 9 + ], + [ + "bCbCCCAcb", + "a", + 17 + ], + [ + "bCbCbb", + "AAACCCB", + 11 + ], + [ + "bCbCccc", + "abbAbC", + 11 + ], + [ + "bCbaACBbb", + "bCCccaa", + 13 + ], + [ + "bCbaAc", + "BA", + 9 + ], + [ + "bCbaaBc", + "CbAAcaBc", + 7 + ], + [ + "bCbac", + "aAcBABbaA", + 13 + ], + [ + "bCbac", + "b", + 8 + ], + [ + "bCbacABa", + "cCaac", + 10 + ], + [ + "bCbb", + "bbCBabAC", + 9 + ], + [ + "bCbbb", + "AcBc", + 8 + ], + [ + "bCbbba", + "AaBbc", + 9 + ], + [ + "bCbc", + "ABb", + 6 + ], + [ + "bCbc", + "CCb", + 4 + ], + [ + "bCbcB", + "AbAab", + 9 + ], + [ + "bCbcCBA", + "BCbBacC", + 9 + ], + [ + "bCbcCC", + "BbbABA", + 9 + ], + [ + "bCbcCbAC", + "ccccC", + 10 + ], + [ + "bCbca", + "bcbBCBa", + 6 + ], + [ + "bCbcaAAAA", + "A", + 16 + ], + [ + "bCbcaca", + "bBBAcc", + 8 + ], + [ + "bCbcbbBbC", + "CaC", + 14 + ], + [ + "bCc", + "BabBBCb", + 10 + ], + [ + "bCc", + "CCBcAA", + 8 + ], + [ + "bCc", + "CCCcCBcC", + 12 + ], + [ + "bCc", + "aaAABCCaB", + 14 + ], + [ + "bCc", + "aabbbaaB", + 14 + ], + [ + "bCc", + "bccB", + 3 + ], + [ + "bCcABC", + "aAcBcCC", + 10 + ], + [ + "bCcACCBa", + "cac", + 12 + ], + [ + "bCcACCaC", + "AbcaC", + 9 + ], + [ + "bCcB", + "BBB", + 5 + ], + [ + "bCcBA", + "CcAbcCbaA", + 11 + ], + [ + "bCcBB", + "cBb", + 5 + ], + [ + "bCcC", + "ACBaB", + 8 + ], + [ + "bCcCb", + "ccbBac", + 10 + ], + [ + "bCcCcCCCB", + "BCAaAa", + 15 + ], + [ + "bCca", + "CCaaaBbc", + 12 + ], + [ + "bCcaA", + "cACB", + 9 + ], + [ + "bCcaBbac", + "bBa", + 10 + ], + [ + "bCcaCc", + "A", + 11 + ], + [ + "bCcaCcC", + "bcCB", + 8 + ], + [ + "bCcaaa", + "B", + 11 + ], + [ + "bCcaabCB", + "bbAbcaAA", + 13 + ], + [ + "bCcacBCA", + "aACBccC", + 11 + ], + [ + "bCcbAaBBc", + "c", + 16 + ], + [ + "bCcbCCbb", + "bBbacaC", + 11 + ], + [ + "bCcbbaCab", + "BC", + 15 + ], + [ + "bCcbbc", + "bBBCB", + 9 + ], + [ + "bCcbc", + "acBCAcc", + 9 + ], + [ + "bCcc", + "CAbacbA", + 10 + ], + [ + "bCccbbbc", + "bBABAaBAc", + 13 + ], + [ + "ba", + "ABbbC", + 8 + ], + [ + "ba", + "BA", + 2 + ], + [ + "ba", + "BAABBb", + 10 + ], + [ + "ba", + "BacAAbA", + 11 + ], + [ + "ba", + "BbAaaCACc", + 14 + ], + [ + "ba", + "BcCAAC", + 10 + ], + [ + "ba", + "Bcc", + 5 + ], + [ + "ba", + "CCccCCa", + 12 + ], + [ + "ba", + "CaAbAb", + 9 + ], + [ + "ba", + "Cba", + 2 + ], + [ + "ba", + "Cca", + 4 + ], + [ + "ba", + "Ccac", + 6 + ], + [ + "ba", + "a", + 2 + ], + [ + "ba", + "aBABA", + 8 + ], + [ + "ba", + "aBaABB", + 9 + ], + [ + "ba", + "aCcaCbAbB", + 15 + ], + [ + "ba", + "bBC", + 4 + ], + [ + "ba", + "bBCC", + 6 + ], + [ + "ba", + "baABc", + 6 + ], + [ + "ba", + "baCAbB", + 8 + ], + [ + "ba", + "cA", + 3 + ], + [ + "ba", + "cABA", + 6 + ], + [ + "ba", + "cBbCCaB", + 10 + ], + [ + "ba", + "cBc", + 5 + ], + [ + "ba", + "cCCBcC", + 11 + ], + [ + "ba", + "caBBCAca", + 13 + ], + [ + "ba", + "cbBbb", + 8 + ], + [ + "ba", + "ccb", + 6 + ], + [ + "baA", + "AbAAaCaa", + 11 + ], + [ + "baA", + "B", + 5 + ], + [ + "baA", + "BBB", + 5 + ], + [ + "baA", + "a", + 4 + ], + [ + "baA", + "aCaaB", + 7 + ], + [ + "baA", + "cAaBCBaCB", + 15 + ], + [ + "baA", + "cBBcccca", + 14 + ], + [ + "baA", + "ccABbC", + 10 + ], + [ + "baAA", + "BBAaCacBC", + 14 + ], + [ + "baAA", + "cbbbCcbac", + 15 + ], + [ + "baAAA", + "CCcC", + 10 + ], + [ + "baAAABbC", + "BcACCbBa", + 11 + ], + [ + "baAAAbAC", + "caBb", + 12 + ], + [ + "baAAa", + "cACaAB", + 8 + ], + [ + "baAAc", + "bC", + 7 + ], + [ + "baAAcCa", + "CCABACcBC", + 12 + ], + [ + "baABBcc", + "cbcaaABc", + 9 + ], + [ + "baABCaCA", + "CABCbCAC", + 8 + ], + [ + "baABaBaAA", + "CAabb", + 13 + ], + [ + "baABbAcC", + "BcCBCCC", + 10 + ], + [ + "baAC", + "bCbAbBCA", + 10 + ], + [ + "baACCCcaA", + "Cb", + 16 + ], + [ + "baACca", + "bBcB", + 8 + ], + [ + "baAa", + "AbAab", + 6 + ], + [ + "baAaCAcc", + "acAbB", + 11 + ], + [ + "baAbCAc", + "baAacAac", + 5 + ], + [ + "baAbaAaba", + "cBA", + 15 + ], + [ + "baAbabAb", + "CC", + 16 + ], + [ + "baAcABAC", + "aabCBbBcB", + 13 + ], + [ + "baAcB", + "bbcb", + 5 + ], + [ + "baAcCcaaa", + "ccAA", + 12 + ], + [ + "baAca", + "aaAcCc", + 6 + ], + [ + "baAcaA", + "C", + 11 + ], + [ + "baAcab", + "B", + 11 + ], + [ + "baAcc", + "AbacACCCb", + 10 + ], + [ + "baB", + "BbccbbBbC", + 14 + ], + [ + "baB", + "acbAB", + 5 + ], + [ + "baB", + "accCa", + 10 + ], + [ + "baB", + "cA", + 5 + ], + [ + "baB", + "ca", + 4 + ], + [ + "baB", + "ccBACC", + 10 + ], + [ + "baBA", + "aa", + 5 + ], + [ + "baBAC", + "aA", + 6 + ], + [ + "baBAbccc", + "BCBaC", + 11 + ], + [ + "baBB", + "bCCaAca", + 10 + ], + [ + "baBB", + "cacbb", + 6 + ], + [ + "baBBC", + "BbBAA", + 7 + ], + [ + "baBBCAAc", + "bBaabAccc", + 11 + ], + [ + "baBBCcBCa", + "ABbBca", + 9 + ], + [ + "baBBaa", + "BCABAa", + 6 + ], + [ + "baBBbAb", + "bACa", + 10 + ], + [ + "baBBbCbBC", + "cBABabC", + 11 + ], + [ + "baBBcaBcC", + "CCCb", + 16 + ], + [ + "baBBcb", + "BBCbCCb", + 9 + ], + [ + "baBCcbbA", + "BBacCC", + 11 + ], + [ + "baBa", + "aA", + 5 + ], + [ + "baBa", + "bBbcAAb", + 10 + ], + [ + "baBa", + "cCbbbcBC", + 12 + ], + [ + "baBaABBb", + "bBcB", + 10 + ], + [ + "baBaaC", + "A", + 11 + ], + [ + "baBaaC", + "bBbAcc", + 7 + ], + [ + "baBbC", + "ACAc", + 8 + ], + [ + "baBbcCbaC", + "C", + 16 + ], + [ + "baBc", + "BAAbCa", + 8 + ], + [ + "baBcAAC", + "aBAAbACa", + 8 + ], + [ + "baBcC", + "Abc", + 6 + ], + [ + "baBcCCBBA", + "bbacBaaaC", + 14 + ], + [ + "baBcCCBb", + "Bccacb", + 9 + ], + [ + "baBcaAc", + "bc", + 10 + ], + [ + "baBcbccA", + "bCCa", + 11 + ], + [ + "baBccBC", + "C", + 12 + ], + [ + "baBccccb", + "AAbbaBCb", + 11 + ], + [ + "baC", + "AABBAb", + 10 + ], + [ + "baC", + "AB", + 5 + ], + [ + "baC", + "BBa", + 5 + ], + [ + "baC", + "CAaCCcbb", + 12 + ], + [ + "baC", + "CC", + 4 + ], + [ + "baC", + "caBcB", + 7 + ], + [ + "baCA", + "Bc", + 6 + ], + [ + "baCACBCac", + "a", + 16 + ], + [ + "baCAaAaBa", + "bcBcCab", + 12 + ], + [ + "baCAbc", + "CCc", + 8 + ], + [ + "baCB", + "B", + 6 + ], + [ + "baCBACbBa", + "b", + 16 + ], + [ + "baCBC", + "CAAcaCaB", + 12 + ], + [ + "baCBbCB", + "abc", + 9 + ], + [ + "baCCCCBB", + "b", + 14 + ], + [ + "baCCCcC", + "bbcAcABac", + 13 + ], + [ + "baCCbAB", + "CbBAC", + 9 + ], + [ + "baCCc", + "BcACCa", + 6 + ], + [ + "baCCc", + "ab", + 8 + ], + [ + "baCa", + "BAabaACcC", + 12 + ], + [ + "baCa", + "CCAABc", + 11 + ], + [ + "baCaAAB", + "aCB", + 8 + ], + [ + "baCaCa", + "caC", + 7 + ], + [ + "baCaCcbAb", + "bCB", + 13 + ], + [ + "baCb", + "CAbA", + 7 + ], + [ + "baCbCAB", + "aCBccCcC", + 11 + ], + [ + "baCbCC", + "ACCbA", + 8 + ], + [ + "baCbbCb", + "bACAc", + 8 + ], + [ + "baCbc", + "aaAbAb", + 8 + ], + [ + "baCbcACBc", + "CACcBb", + 11 + ], + [ + "baCc", + "BbcaaB", + 8 + ], + [ + "baCcA", + "bbbBcB", + 8 + ], + [ + "baCcaaC", + "cCCA", + 10 + ], + [ + "baCcb", + "BaCacAa", + 7 + ], + [ + "baa", + "ACbBca", + 8 + ], + [ + "baa", + "BaC", + 3 + ], + [ + "baaABBcBb", + "ABcacAC", + 14 + ], + [ + "baaAC", + "aCAb", + 6 + ], + [ + "baaAaBB", + "ccABBac", + 12 + ], + [ + "baaAb", + "bAcBabC", + 8 + ], + [ + "baaAcA", + "B", + 11 + ], + [ + "baaBAA", + "CbabaCCAA", + 8 + ], + [ + "baaBAAabB", + "cCB", + 16 + ], + [ + "baaBBBb", + "aC", + 12 + ], + [ + "baaBabb", + "cAaB", + 9 + ], + [ + "baaBb", + "CBbaBAbC", + 9 + ], + [ + "baaBcaa", + "CcCCbb", + 13 + ], + [ + "baaCCcAB", + "cCA", + 11 + ], + [ + "baaCaac", + "aCAaCCbA", + 11 + ], + [ + "baaCbA", + "ccBAAcC", + 12 + ], + [ + "baaa", + "CaCbCb", + 10 + ], + [ + "baaa", + "bBbBAAC", + 10 + ], + [ + "baaaAc", + "CBBbBBB", + 13 + ], + [ + "baaaCA", + "aab", + 8 + ], + [ + "baaaaabB", + "BCbbccA", + 15 + ], + [ + "baaacac", + "ABa", + 11 + ], + [ + "baab", + "aABbABC", + 11 + ], + [ + "baabA", + "cACC", + 9 + ], + [ + "baabaBaab", + "aCcA", + 15 + ], + [ + "baac", + "ACBbca", + 10 + ], + [ + "baacACa", + "bccCB", + 8 + ], + [ + "baacBbA", + "AaaCCbaaA", + 9 + ], + [ + "baacCc", + "CACBAA", + 11 + ], + [ + "baacaCcb", + "BBbbbAaBA", + 16 + ], + [ + "baacabBAA", + "aaaaBaB", + 9 + ], + [ + "bab", + "Cc", + 6 + ], + [ + "bab", + "CcBC", + 7 + ], + [ + "bab", + "a", + 4 + ], + [ + "bab", + "aabbAaBca", + 13 + ], + [ + "babA", + "AB", + 6 + ], + [ + "babA", + "bCb", + 4 + ], + [ + "babA", + "cccABCc", + 12 + ], + [ + "babAAaBC", + "Cb", + 14 + ], + [ + "babAaAA", + "bc", + 12 + ], + [ + "babAaBA", + "BbcBAbC", + 10 + ], + [ + "babBBB", + "b", + 10 + ], + [ + "babBa", + "BB", + 7 + ], + [ + "babBbAbAC", + "CbabB", + 12 + ], + [ + "babC", + "BCB", + 6 + ], + [ + "babC", + "CABB", + 6 + ], + [ + "babCABaa", + "BbcCAab", + 9 + ], + [ + "babCB", + "bcCCaABBC", + 12 + ], + [ + "babCBb", + "AAcbb", + 7 + ], + [ + "babCCCc", + "cCAbbca", + 12 + ], + [ + "babCCa", + "c", + 11 + ], + [ + "babCabCab", + "caac", + 13 + ], + [ + "babCbcc", + "AaAAcA", + 10 + ], + [ + "baba", + "abBcbAc", + 9 + ], + [ + "babaBA", + "CbcBbBabB", + 11 + ], + [ + "babaC", + "CbAaAA", + 8 + ], + [ + "babaCBaa", + "BbCa", + 9 + ], + [ + "babaa", + "C", + 10 + ], + [ + "babaaCBCC", + "BbaaAc", + 10 + ], + [ + "babb", + "AcB", + 6 + ], + [ + "babbA", + "BabaAAaB", + 9 + ], + [ + "babbCaaCB", + "cCaAAaBc", + 15 + ], + [ + "babbCbC", + "AA", + 13 + ], + [ + "babbCc", + "acbACaB", + 10 + ], + [ + "babbbbA", + "acA", + 10 + ], + [ + "babbcccAA", + "bAA", + 12 + ], + [ + "babcacA", + "c", + 12 + ], + [ + "bac", + "CBC", + 5 + ], + [ + "bac", + "CcBc", + 6 + ], + [ + "bac", + "Ccbca", + 8 + ], + [ + "bac", + "aacAc", + 6 + ], + [ + "bac", + "ba", + 2 + ], + [ + "bacABcBc", + "ABccc", + 8 + ], + [ + "bacAbca", + "aBCACc", + 9 + ], + [ + "bacBCbBb", + "ccAbcABA", + 12 + ], + [ + "bacBCc", + "cBcBB", + 8 + ], + [ + "bacBaBc", + "AcbcAcA", + 10 + ], + [ + "bacC", + "bbAbaCAB", + 11 + ], + [ + "bacCACCA", + "b", + 14 + ], + [ + "bacCAa", + "b", + 10 + ], + [ + "bacCCCccC", + "CCBbcacA", + 13 + ], + [ + "bacCbaBcB", + "Cab", + 13 + ], + [ + "bacCcBC", + "aBcbcccB", + 10 + ], + [ + "bacaCC", + "BAaAbcAC", + 10 + ], + [ + "bacaCcA", + "BcBAc", + 9 + ], + [ + "bacabaAA", + "AAACCBaC", + 13 + ], + [ + "bacacBa", + "BCAAaAA", + 11 + ], + [ + "bacbABaB", + "bCABBAc", + 10 + ], + [ + "bacbCAbbb", + "BaA", + 13 + ], + [ + "bacc", + "aAcAA", + 7 + ], + [ + "baccAA", + "C", + 11 + ], + [ + "baccAa", + "abCCB", + 9 + ], + [ + "baccBAA", + "ccCCbcCC", + 13 + ], + [ + "baccBBc", + "CAb", + 12 + ], + [ + "baccBbBaa", + "AbcaCcbb", + 12 + ], + [ + "baccCaCA", + "CAccb", + 11 + ], + [ + "baccaBc", + "AccABCbCC", + 11 + ], + [ + "baccccCB", + "cC", + 12 + ], + [ + "bb", + "A", + 4 + ], + [ + "bb", + "AABcCbCB", + 13 + ], + [ + "bb", + "AC", + 4 + ], + [ + "bb", + "Aabc", + 6 + ], + [ + "bb", + "AbC", + 4 + ], + [ + "bb", + "AbCC", + 6 + ], + [ + "bb", + "AbCCbbB", + 10 + ], + [ + "bb", + "Acaa", + 8 + ], + [ + "bb", + "B", + 3 + ], + [ + "bb", + "BAbcaB", + 9 + ], + [ + "bb", + "BCAC", + 7 + ], + [ + "bb", + "Bbccc", + 7 + ], + [ + "bb", + "CC", + 4 + ], + [ + "bb", + "a", + 4 + ], + [ + "bb", + "aBcCcc", + 11 + ], + [ + "bb", + "aaBBCc", + 10 + ], + [ + "bb", + "acCc", + 8 + ], + [ + "bb", + "accBa", + 9 + ], + [ + "bb", + "bA", + 2 + ], + [ + "bb", + "bAc", + 4 + ], + [ + "bb", + "bCbAcbaC", + 12 + ], + [ + "bb", + "baAB", + 5 + ], + [ + "bb", + "cAbBAbC", + 10 + ], + [ + "bb", + "cB", + 3 + ], + [ + "bb", + "cBC", + 5 + ], + [ + "bb", + "cbAacCaca", + 16 + ], + [ + "bb", + "cbBbABC", + 10 + ], + [ + "bbA", + "ABC", + 5 + ], + [ + "bbA", + "BBCabAA", + 9 + ], + [ + "bbA", + "BcCC", + 7 + ], + [ + "bbA", + "CB", + 5 + ], + [ + "bbA", + "bBbaababa", + 13 + ], + [ + "bbA", + "cCabBCAc", + 11 + ], + [ + "bbAA", + "B", + 7 + ], + [ + "bbAA", + "CC", + 8 + ], + [ + "bbAAaBb", + "AcC", + 12 + ], + [ + "bbAAb", + "BBBaaACAb", + 10 + ], + [ + "bbAAc", + "bBaCb", + 6 + ], + [ + "bbAAcAca", + "CCbBaccCB", + 12 + ], + [ + "bbAAcBca", + "bcA", + 11 + ], + [ + "bbAAcbCb", + "bAabCBAAC", + 12 + ], + [ + "bbAB", + "AaABCCB", + 10 + ], + [ + "bbAB", + "AbabABcC", + 8 + ], + [ + "bbAB", + "cBb", + 6 + ], + [ + "bbABACAbC", + "Ccabbc", + 13 + ], + [ + "bbABBC", + "CaAA", + 10 + ], + [ + "bbABCBA", + "ACb", + 9 + ], + [ + "bbABCBCbc", + "b", + 16 + ], + [ + "bbABab", + "CAcaba", + 8 + ], + [ + "bbABc", + "Bac", + 6 + ], + [ + "bbABcBBc", + "Aa", + 14 + ], + [ + "bbABcb", + "c", + 10 + ], + [ + "bbACABB", + "acC", + 12 + ], + [ + "bbACCcCbb", + "CCcC", + 10 + ], + [ + "bbAa", + "CbCaC", + 6 + ], + [ + "bbAa", + "cBcBBC", + 10 + ], + [ + "bbAaC", + "bBcCcAB", + 10 + ], + [ + "bbAaCaBAB", + "aabBc", + 13 + ], + [ + "bbAabBcca", + "BbaabB", + 8 + ], + [ + "bbAaccbAb", + "aCbBAAc", + 14 + ], + [ + "bbAb", + "B", + 7 + ], + [ + "bbAb", + "baaCABAa", + 11 + ], + [ + "bbAb", + "caAABCaac", + 15 + ], + [ + "bbAbAcaCA", + "cacab", + 13 + ], + [ + "bbAbB", + "ccAaCc", + 10 + ], + [ + "bbAbBc", + "AbcAbaBa", + 8 + ], + [ + "bbAbC", + "BBa", + 7 + ], + [ + "bbAbC", + "BcAcaCaaa", + 13 + ], + [ + "bbAbcBA", + "cAbbcBC", + 8 + ], + [ + "bbAc", + "bB", + 5 + ], + [ + "bbAcBabb", + "b", + 14 + ], + [ + "bbAcCaAC", + "CccacCABB", + 12 + ], + [ + "bbAcaA", + "caCabBaAB", + 13 + ], + [ + "bbAcabA", + "bBcbCb", + 9 + ], + [ + "bbB", + "Ac", + 6 + ], + [ + "bbB", + "aCbba", + 6 + ], + [ + "bbB", + "cAcbbBb", + 8 + ], + [ + "bbBA", + "B", + 6 + ], + [ + "bbBACc", + "AcCCBa", + 12 + ], + [ + "bbBAab", + "caAaBCbCb", + 14 + ], + [ + "bbBAbaa", + "aa", + 10 + ], + [ + "bbBBA", + "A", + 8 + ], + [ + "bbBBaaC", + "aCB", + 12 + ], + [ + "bbBBbc", + "ab", + 10 + ], + [ + "bbBCCCAbA", + "aAcCBBc", + 14 + ], + [ + "bbBCCaa", + "AACaAbAA", + 14 + ], + [ + "bbBCaaAC", + "bBAc", + 9 + ], + [ + "bbBCcbcbc", + "BBBaCcbBc", + 7 + ], + [ + "bbBa", + "BBcbc", + 7 + ], + [ + "bbBa", + "Cc", + 8 + ], + [ + "bbBaAcBaC", + "Bcc", + 13 + ], + [ + "bbBaCacbC", + "BAAaBcCa", + 13 + ], + [ + "bbBbA", + "Bbca", + 6 + ], + [ + "bbBbB", + "bBCaCbABa", + 11 + ], + [ + "bbBbBc", + "ABbBbc", + 5 + ], + [ + "bbBbCcBa", + "ba", + 12 + ], + [ + "bbBbaaaBB", + "C", + 18 + ], + [ + "bbBbabc", + "ABACBBacC", + 11 + ], + [ + "bbBbbcCA", + "AaabaCabb", + 15 + ], + [ + "bbBbc", + "Bab", + 7 + ], + [ + "bbBc", + "AaCcBCbCb", + 15 + ], + [ + "bbBcBCA", + "acaba", + 11 + ], + [ + "bbBcCc", + "BAc", + 8 + ], + [ + "bbBcab", + "cAabaC", + 10 + ], + [ + "bbBcbAba", + "b", + 14 + ], + [ + "bbBccBaCB", + "AcbAaCc", + 12 + ], + [ + "bbC", + "A", + 6 + ], + [ + "bbC", + "AAccbCBAA", + 14 + ], + [ + "bbC", + "BCAC", + 5 + ], + [ + "bbC", + "BacBCA", + 8 + ], + [ + "bbC", + "acBbCB", + 7 + ], + [ + "bbCAAb", + "aBAAcAc", + 9 + ], + [ + "bbCABbc", + "aCa", + 11 + ], + [ + "bbCACA", + "cBc", + 10 + ], + [ + "bbCAaBb", + "babcacCA", + 10 + ], + [ + "bbCAaa", + "cBaBbCa", + 11 + ], + [ + "bbCBCca", + "bC", + 10 + ], + [ + "bbCBacAB", + "aC", + 13 + ], + [ + "bbCBcBBcb", + "bCCCaa", + 13 + ], + [ + "bbCC", + "cAbBccA", + 9 + ], + [ + "bbCCAA", + "b", + 10 + ], + [ + "bbCCCBc", + "CCBAcbab", + 14 + ], + [ + "bbCCaccaA", + "ba", + 14 + ], + [ + "bbCCbBA", + "A", + 12 + ], + [ + "bbCCcABa", + "CBBbC", + 13 + ], + [ + "bbCCcCc", + "BbaabbaCc", + 11 + ], + [ + "bbCa", + "BC", + 5 + ], + [ + "bbCa", + "abBbA", + 6 + ], + [ + "bbCaAB", + "CCACcabAC", + 12 + ], + [ + "bbCaBabbC", + "CaBABbacC", + 10 + ], + [ + "bbCaaC", + "BbaBCcbCA", + 11 + ], + [ + "bbCaaCA", + "BcBBB", + 12 + ], + [ + "bbCabA", + "BaBBA", + 8 + ], + [ + "bbCabcAA", + "bc", + 12 + ], + [ + "bbCbAaBaA", + "CbAaAAc", + 9 + ], + [ + "bbCbCB", + "AaBB", + 9 + ], + [ + "bbCbaACb", + "Abbc", + 11 + ], + [ + "bbCbcaBA", + "AB", + 13 + ], + [ + "bbCc", + "aBaC", + 6 + ], + [ + "bbCcAA", + "ccaBAabBA", + 14 + ], + [ + "bbCcBaA", + "aAbCCabAb", + 11 + ], + [ + "bbCcaABc", + "a", + 14 + ], + [ + "bbCcc", + "BBAAA", + 8 + ], + [ + "bbCccBCCa", + "cacaCc", + 12 + ], + [ + "bba", + "ABBcccabc", + 14 + ], + [ + "bba", + "Bb", + 3 + ], + [ + "bba", + "C", + 6 + ], + [ + "bba", + "CBACA", + 8 + ], + [ + "bba", + "aCCAABCcb", + 17 + ], + [ + "bba", + "bbba", + 2 + ], + [ + "bbaA", + "CaCcCbb", + 14 + ], + [ + "bbaACCB", + "bAcAccABC", + 10 + ], + [ + "bbaAaaacc", + "CbaACB", + 11 + ], + [ + "bbaAcBA", + "cBbcaa", + 10 + ], + [ + "bbaB", + "Acc", + 8 + ], + [ + "bbaBAccC", + "cBBAb", + 11 + ], + [ + "bbaBBCc", + "C", + 12 + ], + [ + "bbaBCaAb", + "cCbA", + 12 + ], + [ + "bbaBaAc", + "cABCaA", + 9 + ], + [ + "bbaBbCbCb", + "aBccbBC", + 11 + ], + [ + "bbaBbaAbC", + "acaccca", + 15 + ], + [ + "bbaBc", + "bAbbCc", + 6 + ], + [ + "bbaCbCB", + "CCCA", + 10 + ], + [ + "bbaCbbC", + "c", + 13 + ], + [ + "bbaCc", + "CbCaBAaC", + 11 + ], + [ + "bbaCcBccb", + "C", + 16 + ], + [ + "bbab", + "ACB", + 7 + ], + [ + "bbab", + "CbbCbCbcC", + 12 + ], + [ + "bbabAbca", + "cBbbAB", + 10 + ], + [ + "bbabBcc", + "CAa", + 12 + ], + [ + "bbabC", + "abBAaAba", + 9 + ], + [ + "bbabC", + "cBb", + 7 + ], + [ + "bbabc", + "AAccbABAc", + 12 + ], + [ + "bbacC", + "aabaacA", + 8 + ], + [ + "bbacacb", + "acbCBaAcC", + 12 + ], + [ + "bbacccaa", + "AbBABACaa", + 9 + ], + [ + "bbb", + "ABC", + 5 + ], + [ + "bbb", + "C", + 6 + ], + [ + "bbb", + "aCBc", + 7 + ], + [ + "bbbA", + "bccbbcCCB", + 12 + ], + [ + "bbbABA", + "a", + 11 + ], + [ + "bbbACCCa", + "CBbcC", + 10 + ], + [ + "bbbAaBB", + "B", + 12 + ], + [ + "bbbAaCac", + "cCc", + 12 + ], + [ + "bbbAcbcC", + "aBBACacb", + 9 + ], + [ + "bbbB", + "ABAc", + 7 + ], + [ + "bbbB", + "AbABcABAB", + 12 + ], + [ + "bbbB", + "BB", + 5 + ], + [ + "bbbB", + "aC", + 8 + ], + [ + "bbbB", + "cCCcBcbCb", + 14 + ], + [ + "bbbBBBBCb", + "BcaBa", + 14 + ], + [ + "bbbBbA", + "bbA", + 6 + ], + [ + "bbbBbCBcB", + "bbcBcCC", + 9 + ], + [ + "bbbCa", + "CCB", + 8 + ], + [ + "bbbCccAA", + "bBAa", + 10 + ], + [ + "bbbaABaac", + "abaCbCB", + 13 + ], + [ + "bbbaAa", + "b", + 10 + ], + [ + "bbbaB", + "AC", + 9 + ], + [ + "bbbaa", + "CBBccC", + 10 + ], + [ + "bbbaaBba", + "Baa", + 11 + ], + [ + "bbbaacbb", + "cBbaC", + 10 + ], + [ + "bbbacBbBc", + "bcbcbCCC", + 10 + ], + [ + "bbbb", + "AbaACaC", + 12 + ], + [ + "bbbbbAB", + "aaAaCb", + 13 + ], + [ + "bbbbc", + "BBbC", + 5 + ], + [ + "bbbcAB", + "aBAbBBa", + 11 + ], + [ + "bbbcAcCAC", + "AaBbcCCcb", + 12 + ], + [ + "bbbcB", + "bcCc", + 6 + ], + [ + "bbbcBa", + "CAAccB", + 10 + ], + [ + "bbbcCB", + "aAbBABa", + 10 + ], + [ + "bbbca", + "cBbcabCC", + 9 + ], + [ + "bbbcbBAbc", + "AAacbcc", + 12 + ], + [ + "bbbcbcbc", + "Cbbaac", + 10 + ], + [ + "bbc", + "ACBaABaCC", + 15 + ], + [ + "bbc", + "BcCBaBcCc", + 14 + ], + [ + "bbc", + "CcB", + 6 + ], + [ + "bbc", + "bCCcBAac", + 11 + ], + [ + "bbc", + "c", + 4 + ], + [ + "bbcA", + "AAC", + 7 + ], + [ + "bbcACCca", + "bAABA", + 11 + ], + [ + "bbcAbBa", + "CaaA", + 11 + ], + [ + "bbcAbca", + "CCCCc", + 11 + ], + [ + "bbcAcbBab", + "CBacCca", + 12 + ], + [ + "bbcB", + "BaAbbccBb", + 10 + ], + [ + "bbcBAa", + "baaacc", + 10 + ], + [ + "bbcBCa", + "CaBabc", + 11 + ], + [ + "bbcCA", + "CAb", + 8 + ], + [ + "bbcCBACB", + "bcBBCaBc", + 10 + ], + [ + "bbcCBbAA", + "CcAc", + 12 + ], + [ + "bbcCC", + "BcbCc", + 6 + ], + [ + "bbcCCcB", + "b", + 12 + ], + [ + "bbca", + "AbbcaAcCa", + 10 + ], + [ + "bbca", + "acaBbbB", + 11 + ], + [ + "bbcaACCab", + "aACBab", + 8 + ], + [ + "bbcaAb", + "b", + 10 + ], + [ + "bbcaCab", + "B", + 13 + ], + [ + "bbcaaBCA", + "BCaaC", + 8 + ], + [ + "bbcaacCC", + "bCCcBACB", + 11 + ], + [ + "bbcab", + "bABaa", + 6 + ], + [ + "bbcabAB", + "BcC", + 11 + ], + [ + "bbcb", + "abAA", + 6 + ], + [ + "bbcbB", + "bCbAab", + 7 + ], + [ + "bbcbBccAa", + "bA", + 14 + ], + [ + "bbcbCcAB", + "cacaCCaBA", + 10 + ], + [ + "bbcc", + "B", + 7 + ], + [ + "bbcc", + "CcBBaABa", + 14 + ], + [ + "bbccAcBCB", + "CbacCAaB", + 11 + ], + [ + "bbccC", + "bac", + 6 + ], + [ + "bbccCa", + "baacc", + 7 + ], + [ + "bbccCcA", + "CbbbC", + 10 + ], + [ + "bbccaca", + "bb", + 10 + ], + [ + "bbccb", + "ABCA", + 8 + ], + [ + "bbccbB", + "Cbccbcb", + 5 + ], + [ + "bbccbBB", + "cbCB", + 8 + ], + [ + "bc", + "ACcCb", + 8 + ], + [ + "bc", + "Aa", + 4 + ], + [ + "bc", + "Ac", + 2 + ], + [ + "bc", + "BBAA", + 7 + ], + [ + "bc", + "BcA", + 3 + ], + [ + "bc", + "BcbBaCaCB", + 15 + ], + [ + "bc", + "CACcCBc", + 11 + ], + [ + "bc", + "CBBaAccB", + 13 + ], + [ + "bc", + "CaBa", + 7 + ], + [ + "bc", + "CcCaaABa", + 14 + ], + [ + "bc", + "a", + 4 + ], + [ + "bc", + "aAA", + 6 + ], + [ + "bc", + "aACBcB", + 9 + ], + [ + "bc", + "aBacc", + 7 + ], + [ + "bc", + "aBbAa", + 8 + ], + [ + "bc", + "acb", + 4 + ], + [ + "bc", + "b", + 2 + ], + [ + "bc", + "bA", + 2 + ], + [ + "bc", + "bBCcbA", + 8 + ], + [ + "bc", + "c", + 2 + ], + [ + "bc", + "cBb", + 5 + ], + [ + "bc", + "caaabc", + 8 + ], + [ + "bc", + "ccAB", + 6 + ], + [ + "bcA", + "ABbA", + 5 + ], + [ + "bcA", + "BBB", + 5 + ], + [ + "bcA", + "aabaAAB", + 10 + ], + [ + "bcA", + "acacbc", + 9 + ], + [ + "bcA", + "cbaACAB", + 9 + ], + [ + "bcAA", + "BaCc", + 7 + ], + [ + "bcAABAab", + "CB", + 13 + ], + [ + "bcAABbbBa", + "ABcccc", + 14 + ], + [ + "bcAABcb", + "c", + 12 + ], + [ + "bcAAbc", + "B", + 11 + ], + [ + "bcAB", + "a", + 7 + ], + [ + "bcAB", + "bcB", + 2 + ], + [ + "bcABAABcB", + "Cc", + 15 + ], + [ + "bcABAbBC", + "c", + 14 + ], + [ + "bcABAcB", + "bcCBCAbCa", + 9 + ], + [ + "bcAC", + "AAaC", + 5 + ], + [ + "bcACABab", + "c", + 14 + ], + [ + "bcACBbBaC", + "baaAbBbB", + 10 + ], + [ + "bcACa", + "bbaAcCBB", + 10 + ], + [ + "bcACbCa", + "aaaBBAbC", + 13 + ], + [ + "bcAa", + "BC", + 6 + ], + [ + "bcAa", + "b", + 6 + ], + [ + "bcAaAabA", + "abBB", + 13 + ], + [ + "bcAaBABA", + "CABac", + 10 + ], + [ + "bcAaBAaC", + "AaC", + 10 + ], + [ + "bcAaBCc", + "ca", + 10 + ], + [ + "bcAaaC", + "cbA", + 9 + ], + [ + "bcAabc", + "BAABb", + 7 + ], + [ + "bcAb", + "BcbbbA", + 7 + ], + [ + "bcAbAAAAb", + "abCBaAABc", + 11 + ], + [ + "bcAbACaB", + "cCaCAC", + 10 + ], + [ + "bcAbacAbc", + "BccaBBCbb", + 12 + ], + [ + "bcAc", + "BCBcaBCaB", + 13 + ], + [ + "bcAca", + "A", + 8 + ], + [ + "bcAcba", + "CcAc", + 6 + ], + [ + "bcAcbccB", + "Abbac", + 10 + ], + [ + "bcAccA", + "bbabbAcC", + 11 + ], + [ + "bcAccab", + "CCACcbcC", + 10 + ], + [ + "bcB", + "AaCbCccbb", + 13 + ], + [ + "bcB", + "BaAACbA", + 11 + ], + [ + "bcB", + "CAAABA", + 10 + ], + [ + "bcB", + "aaAaBccC", + 13 + ], + [ + "bcB", + "bAAAACCA", + 13 + ], + [ + "bcB", + "cAbcb", + 5 + ], + [ + "bcBA", + "bBBAb", + 4 + ], + [ + "bcBAAc", + "BccA", + 7 + ], + [ + "bcBACabcB", + "abBA", + 14 + ], + [ + "bcBAab", + "baaaBbcc", + 11 + ], + [ + "bcBAcAC", + "aCCC", + 10 + ], + [ + "bcBBC", + "c", + 8 + ], + [ + "bcBBCbAbA", + "bcCCb", + 10 + ], + [ + "bcBBaA", + "ABCBb", + 9 + ], + [ + "bcBBabABb", + "BcbaBBBCa", + 11 + ], + [ + "bcBBbB", + "bbbCC", + 8 + ], + [ + "bcBCAaaaB", + "CC", + 15 + ], + [ + "bcBCBC", + "aCB", + 8 + ], + [ + "bcBCCAB", + "ABCbc", + 10 + ], + [ + "bcBCCB", + "cAb", + 9 + ], + [ + "bcBCCcbA", + "c", + 14 + ], + [ + "bcBCa", + "CBccAbA", + 10 + ], + [ + "bcBa", + "abaBbcaba", + 11 + ], + [ + "bcBaBB", + "CB", + 9 + ], + [ + "bcBaCc", + "aaCBa", + 9 + ], + [ + "bcBaa", + "BcBB", + 5 + ], + [ + "bcBabcbc", + "accAbcB", + 8 + ], + [ + "bcBac", + "BB", + 7 + ], + [ + "bcBbAB", + "aCAbA", + 7 + ], + [ + "bcBbACCB", + "BAbcCc", + 10 + ], + [ + "bcBbACCac", + "CB", + 15 + ], + [ + "bcBbBCB", + "BcCbb", + 8 + ], + [ + "bcBbbAcac", + "ACbccac", + 9 + ], + [ + "bcBbc", + "caC", + 7 + ], + [ + "bcBc", + "A", + 8 + ], + [ + "bcBcaa", + "BbbCAaBB", + 10 + ], + [ + "bcBccBCBA", + "ABaCCAba", + 13 + ], + [ + "bcBccbcC", + "aC", + 14 + ], + [ + "bcC", + "ACabb", + 9 + ], + [ + "bcC", + "Ac", + 4 + ], + [ + "bcC", + "CACac", + 8 + ], + [ + "bcC", + "CAaCbCbb", + 13 + ], + [ + "bcC", + "CacBAbbac", + 15 + ], + [ + "bcC", + "a", + 6 + ], + [ + "bcC", + "abBBcB", + 8 + ], + [ + "bcC", + "acaAAaCbb", + 14 + ], + [ + "bcC", + "bBCaBBC", + 9 + ], + [ + "bcC", + "bbbCCABb", + 11 + ], + [ + "bcC", + "cBBBBCac", + 13 + ], + [ + "bcC", + "cCAAb", + 8 + ], + [ + "bcC", + "ccBcB", + 7 + ], + [ + "bcCAAA", + "CCCBbBAC", + 11 + ], + [ + "bcCAaA", + "AbCabC", + 9 + ], + [ + "bcCAb", + "CbBccBC", + 9 + ], + [ + "bcCAcAa", + "cB", + 12 + ], + [ + "bcCAcbC", + "AcAAbc", + 7 + ], + [ + "bcCB", + "a", + 8 + ], + [ + "bcCBAB", + "AaBAcB", + 8 + ], + [ + "bcCBBcb", + "CaCbaa", + 11 + ], + [ + "bcCBC", + "cb", + 7 + ], + [ + "bcCBaCAAc", + "aBb", + 16 + ], + [ + "bcCBaCb", + "aaaacC", + 11 + ], + [ + "bcCCAbB", + "BBcCAcA", + 8 + ], + [ + "bcCCa", + "BACbBaAcC", + 13 + ], + [ + "bcCCaa", + "cBcC", + 9 + ], + [ + "bcCCcbA", + "AAaAcCCA", + 12 + ], + [ + "bcCa", + "bCCC", + 3 + ], + [ + "bcCaaAB", + "cAAc", + 9 + ], + [ + "bcCaacC", + "BbcaccCCB", + 10 + ], + [ + "bcCab", + "BcCABbCAC", + 10 + ], + [ + "bcCacAA", + "CcbB", + 10 + ], + [ + "bcCacCaa", + "ABc", + 14 + ], + [ + "bcCacba", + "Bc", + 11 + ], + [ + "bcCb", + "aCbcBbCc", + 10 + ], + [ + "bcCbB", + "bAbCc", + 8 + ], + [ + "bcCbBCbaB", + "BC", + 14 + ], + [ + "bcCbaa", + "BbAACBAaC", + 10 + ], + [ + "bcCbbc", + "baAA", + 10 + ], + [ + "bcCc", + "AAA", + 8 + ], + [ + "bcCcBB", + "BaAccBC", + 8 + ], + [ + "bcCcaCCca", + "AaCc", + 12 + ], + [ + "bcCcbAAc", + "Ca", + 13 + ], + [ + "bca", + "AB", + 6 + ], + [ + "bca", + "AcaaBC", + 8 + ], + [ + "bca", + "CACBbcC", + 10 + ], + [ + "bca", + "bccb", + 4 + ], + [ + "bcaA", + "aBaCBBAa", + 12 + ], + [ + "bcaAAbCbC", + "CCcAA", + 13 + ], + [ + "bcaABAa", + "Ac", + 12 + ], + [ + "bcaACb", + "bAbCaCB", + 8 + ], + [ + "bcaAa", + "BbCcc", + 9 + ], + [ + "bcaAaaAC", + "acaaABc", + 8 + ], + [ + "bcaAba", + "BabBAaccb", + 14 + ], + [ + "bcaB", + "bCBCBAA", + 9 + ], + [ + "bcaBBAC", + "Cb", + 12 + ], + [ + "bcaCA", + "ACA", + 5 + ], + [ + "bcaCA", + "aB", + 8 + ], + [ + "bcaCAABcB", + "bBAbCcbc", + 12 + ], + [ + "bcaCB", + "AbaACbaC", + 10 + ], + [ + "bcaCBa", + "BaAbAB", + 9 + ], + [ + "bcaCa", + "cCbccbA", + 9 + ], + [ + "bcaCbBA", + "bcBabAb", + 8 + ], + [ + "bcaCbCbaA", + "bbCBb", + 11 + ], + [ + "bcaCcB", + "cAab", + 8 + ], + [ + "bcaa", + "CC", + 7 + ], + [ + "bcaa", + "aaBA", + 7 + ], + [ + "bcaaA", + "BAAacaAba", + 11 + ], + [ + "bcaaABBA", + "baa", + 10 + ], + [ + "bcaaAcbC", + "aBACAcaab", + 13 + ], + [ + "bcaaBaAb", + "b", + 14 + ], + [ + "bcaacb", + "acCb", + 7 + ], + [ + "bcab", + "a", + 6 + ], + [ + "bcab", + "cCAabCBCb", + 13 + ], + [ + "bcabAA", + "BAAcca", + 9 + ], + [ + "bcabC", + "Aac", + 7 + ], + [ + "bcabb", + "aAaA", + 8 + ], + [ + "bcac", + "CCAAbCbC", + 12 + ], + [ + "bcb", + "A", + 6 + ], + [ + "bcb", + "aBabCcB", + 9 + ], + [ + "bcb", + "abACACc", + 11 + ], + [ + "bcbA", + "AcbAcbCaB", + 11 + ], + [ + "bcbAAA", + "a", + 11 + ], + [ + "bcbAAAB", + "a", + 13 + ], + [ + "bcbACB", + "CBbcbCca", + 9 + ], + [ + "bcbACCA", + "AabaACAcB", + 11 + ], + [ + "bcbACCC", + "c", + 12 + ], + [ + "bcbAbCbB", + "caA", + 12 + ], + [ + "bcbAc", + "BACCccbCb", + 13 + ], + [ + "bcbBA", + "baaaa", + 7 + ], + [ + "bcbBAABCa", + "cBAcaa", + 10 + ], + [ + "bcbCAaAC", + "bB", + 13 + ], + [ + "bcbCAc", + "caccbaABC", + 11 + ], + [ + "bcbCB", + "c", + 8 + ], + [ + "bcbCcCa", + "CCCbACb", + 11 + ], + [ + "bcbaAACb", + "aBAcA", + 11 + ], + [ + "bcbaBBB", + "AA", + 13 + ], + [ + "bcbaccb", + "ACACCB", + 9 + ], + [ + "bcbb", + "cBcACA", + 9 + ], + [ + "bcbb", + "cCCBaaA", + 12 + ], + [ + "bcbbABC", + "CAAaa", + 11 + ], + [ + "bcbbB", + "ABB", + 7 + ], + [ + "bcbbBc", + "cCc", + 8 + ], + [ + "bcbbCBabA", + "cCccbccBA", + 12 + ], + [ + "bcbc", + "AAA", + 8 + ], + [ + "bcbc", + "Ca", + 7 + ], + [ + "bcbcAC", + "bBAaaacb", + 12 + ], + [ + "bcc", + "C", + 5 + ], + [ + "bcc", + "CaACa", + 9 + ], + [ + "bcc", + "bACb", + 5 + ], + [ + "bcc", + "bbcCcAa", + 8 + ], + [ + "bccA", + "C", + 7 + ], + [ + "bccA", + "aAb", + 8 + ], + [ + "bccA", + "ab", + 8 + ], + [ + "bccABAba", + "acacC", + 13 + ], + [ + "bccAC", + "BbbBcA", + 8 + ], + [ + "bccAbaA", + "aAc", + 12 + ], + [ + "bccAbcbcb", + "CbbcbbA", + 11 + ], + [ + "bccB", + "BcacaCB", + 7 + ], + [ + "bccB", + "cAcb", + 5 + ], + [ + "bccBABc", + "bAacbb", + 10 + ], + [ + "bccBBB", + "aAbbbbC", + 11 + ], + [ + "bccBBCbBa", + "bbbaabCbB", + 11 + ], + [ + "bccBBc", + "cCcbac", + 6 + ], + [ + "bccBBccA", + "bB", + 12 + ], + [ + "bccBCCAC", + "bABBCAabC", + 9 + ], + [ + "bccBCCBc", + "ACBaa", + 13 + ], + [ + "bccBa", + "CAcbB", + 7 + ], + [ + "bccBbA", + "aBCcBBBC", + 9 + ], + [ + "bccCA", + "BaBAAba", + 11 + ], + [ + "bccCAbbB", + "ccC", + 10 + ], + [ + "bccCBab", + "c", + 12 + ], + [ + "bccCCAaBB", + "bBa", + 14 + ], + [ + "bccCaBCC", + "Bb", + 14 + ], + [ + "bcca", + "AaAaabA", + 12 + ], + [ + "bccaCBb", + "bAbcabA", + 9 + ], + [ + "bccaCCC", + "CCBCBbAAA", + 16 + ], + [ + "bccaa", + "C", + 9 + ], + [ + "bccaab", + "cAcc", + 9 + ], + [ + "bccbAbab", + "b", + 14 + ], + [ + "bccbBCcCA", + "B", + 16 + ], + [ + "bccbBb", + "ccba", + 6 + ], + [ + "bccbC", + "bBC", + 5 + ], + [ + "bccbbCC", + "bBccA", + 9 + ], + [ + "bccbbbCB", + "BbcABC", + 10 + ], + [ + "bccbccAc", + "bBC", + 12 + ], + [ + "bccc", + "ACcca", + 5 + ], + [ + "bcccAA", + "bCBAbca", + 10 + ], + [ + "bcccAaBca", + "BaC", + 14 + ], + [ + "bcccBBCaA", + "bcAcaCcb", + 10 + ], + [ + "bcccC", + "aAAaa", + 10 + ], + [ + "bcccCCCbc", + "Bac", + 15 + ], + [ + "c", + "A", + 2 + ], + [ + "c", + "AA", + 4 + ], + [ + "c", + "AABacBC", + 12 + ], + [ + "c", + "AAbBBaBB", + 16 + ], + [ + "c", + "AB", + 4 + ], + [ + "c", + "ABA", + 6 + ], + [ + "c", + "ABBaCCBBB", + 17 + ], + [ + "c", + "ABBbBBCBA", + 17 + ], + [ + "c", + "ABbCb", + 9 + ], + [ + "c", + "ABbaaba", + 14 + ], + [ + "c", + "AC", + 3 + ], + [ + "c", + "ACABa", + 9 + ], + [ + "c", + "ACCB", + 7 + ], + [ + "c", + "ACCcbCCbC", + 16 + ], + [ + "c", + "ACbBBC", + 11 + ], + [ + "c", + "Aa", + 4 + ], + [ + "c", + "AaABA", + 10 + ], + [ + "c", + "Aaa", + 6 + ], + [ + "c", + "AaaaBbBC", + 15 + ], + [ + "c", + "AaabCAb", + 13 + ], + [ + "c", + "Ab", + 4 + ], + [ + "c", + "AbaCAAA", + 13 + ], + [ + "c", + "AcCACaAA", + 14 + ], + [ + "c", + "AcCCBAcaB", + 16 + ], + [ + "c", + "Acb", + 4 + ], + [ + "c", + "AcccbCacB", + 16 + ], + [ + "c", + "B", + 2 + ], + [ + "c", + "BA", + 4 + ], + [ + "c", + "BAAAAbB", + 14 + ], + [ + "c", + "BACA", + 7 + ], + [ + "c", + "BACbAC", + 11 + ], + [ + "c", + "BAbBbAc", + 12 + ], + [ + "c", + "BAbb", + 8 + ], + [ + "c", + "BAcBb", + 8 + ], + [ + "c", + "BB", + 4 + ], + [ + "c", + "BBAACAb", + 13 + ], + [ + "c", + "BBABBC", + 11 + ], + [ + "c", + "BBBcBccc", + 14 + ], + [ + "c", + "BBbbc", + 8 + ], + [ + "c", + "BBbcbbac", + 14 + ], + [ + "c", + "BBcBc", + 8 + ], + [ + "c", + "BC", + 3 + ], + [ + "c", + "BCA", + 5 + ], + [ + "c", + "BCAAcBC", + 12 + ], + [ + "c", + "BCAbCb", + 11 + ], + [ + "c", + "BCBc", + 6 + ], + [ + "c", + "BCa", + 5 + ], + [ + "c", + "BCcbaB", + 10 + ], + [ + "c", + "Ba", + 4 + ], + [ + "c", + "BaAaaA", + 12 + ], + [ + "c", + "BaBacca", + 12 + ], + [ + "c", + "BaCCBaCAC", + 17 + ], + [ + "c", + "BaaBcAcBb", + 16 + ], + [ + "c", + "BaaccC", + 10 + ], + [ + "c", + "BabCcAAcA", + 16 + ], + [ + "c", + "BbABABaBC", + 17 + ], + [ + "c", + "BbCa", + 7 + ], + [ + "c", + "BbaAacbb", + 14 + ], + [ + "c", + "BbaCAAcBa", + 16 + ], + [ + "c", + "BbcBb", + 8 + ], + [ + "c", + "Bbcc", + 6 + ], + [ + "c", + "Bc", + 2 + ], + [ + "c", + "BcBa", + 6 + ], + [ + "c", + "Bcb", + 4 + ], + [ + "c", + "Bcccb", + 8 + ], + [ + "c", + "C", + 1 + ], + [ + "c", + "CB", + 3 + ], + [ + "c", + "CBABBC", + 11 + ], + [ + "c", + "CBAcCA", + 10 + ], + [ + "c", + "CBBAbbA", + 13 + ], + [ + "c", + "CBCBb", + 9 + ], + [ + "c", + "CBCaBa", + 11 + ], + [ + "c", + "CBb", + 5 + ], + [ + "c", + "CCCBaaCB", + 15 + ], + [ + "c", + "CCCCCC", + 11 + ], + [ + "c", + "Ca", + 3 + ], + [ + "c", + "CaAb", + 7 + ], + [ + "c", + "CaCa", + 7 + ], + [ + "c", + "Cab", + 5 + ], + [ + "c", + "CabC", + 7 + ], + [ + "c", + "CbAC", + 7 + ], + [ + "c", + "CbabCAaAc", + 16 + ], + [ + "c", + "CcAABA", + 10 + ], + [ + "c", + "CccaaAa", + 12 + ], + [ + "c", + "a", + 2 + ], + [ + "c", + "aAAa", + 8 + ], + [ + "c", + "aAAc", + 6 + ], + [ + "c", + "aACbcB", + 10 + ], + [ + "c", + "aAbACcCA", + 14 + ], + [ + "c", + "aAbab", + 10 + ], + [ + "c", + "aB", + 4 + ], + [ + "c", + "aBAC", + 7 + ], + [ + "c", + "aBBbbc", + 10 + ], + [ + "c", + "aBaaA", + 10 + ], + [ + "c", + "aBb", + 6 + ], + [ + "c", + "aBcABcCCb", + 16 + ], + [ + "c", + "aBcBBCBbc", + 16 + ], + [ + "c", + "aCa", + 5 + ], + [ + "c", + "aa", + 4 + ], + [ + "c", + "aaCBCbC", + 13 + ], + [ + "c", + "aabcBAAcc", + 16 + ], + [ + "c", + "aabcBcA", + 12 + ], + [ + "c", + "aacABB", + 10 + ], + [ + "c", + "aacb", + 6 + ], + [ + "c", + "aaccAca", + 12 + ], + [ + "c", + "ab", + 4 + ], + [ + "c", + "abAa", + 8 + ], + [ + "c", + "abCAcC", + 10 + ], + [ + "c", + "abCCAB", + 11 + ], + [ + "c", + "abCc", + 6 + ], + [ + "c", + "ac", + 2 + ], + [ + "c", + "accbaBBAB", + 16 + ], + [ + "c", + "b", + 2 + ], + [ + "c", + "bAAccBAa", + 14 + ], + [ + "c", + "bAaBAbcCc", + 16 + ], + [ + "c", + "bAcacAbb", + 14 + ], + [ + "c", + "bBAaCa", + 11 + ], + [ + "c", + "bBAcaCaca", + 16 + ], + [ + "c", + "bBBCbaB", + 13 + ], + [ + "c", + "bBBa", + 8 + ], + [ + "c", + "bBab", + 8 + ], + [ + "c", + "bBcCbcABC", + 16 + ], + [ + "c", + "bBcCca", + 10 + ], + [ + "c", + "bCBC", + 7 + ], + [ + "c", + "bCC", + 5 + ], + [ + "c", + "bCCAbcBBa", + 16 + ], + [ + "c", + "bCCa", + 7 + ], + [ + "c", + "bCabaBC", + 13 + ], + [ + "c", + "bCc", + 4 + ], + [ + "c", + "bCcA", + 6 + ], + [ + "c", + "baaAB", + 10 + ], + [ + "c", + "baaABBC", + 13 + ], + [ + "c", + "baaAccba", + 14 + ], + [ + "c", + "bbBbbBBa", + 16 + ], + [ + "c", + "bbCccAAC", + 14 + ], + [ + "c", + "bc", + 2 + ], + [ + "c", + "bcAbC", + 8 + ], + [ + "c", + "bcBAcAcB", + 14 + ], + [ + "c", + "bcbBbCcb", + 14 + ], + [ + "c", + "bccAAa", + 10 + ], + [ + "c", + "c", + 0 + ], + [ + "c", + "cAABBb", + 10 + ], + [ + "c", + "cAACa", + 8 + ], + [ + "c", + "cABc", + 6 + ], + [ + "c", + "cAaCBc", + 10 + ], + [ + "c", + "cAacbCCA", + 14 + ], + [ + "c", + "cBCCAbA", + 12 + ], + [ + "c", + "cBacAc", + 10 + ], + [ + "c", + "cBcCBb", + 10 + ], + [ + "c", + "cCAB", + 6 + ], + [ + "c", + "cCCbbBBcA", + 16 + ], + [ + "c", + "cCcaBbcba", + 16 + ], + [ + "c", + "ca", + 2 + ], + [ + "c", + "caC", + 4 + ], + [ + "c", + "caa", + 4 + ], + [ + "c", + "cabA", + 6 + ], + [ + "c", + "cb", + 2 + ], + [ + "c", + "cbCaBBab", + 14 + ], + [ + "c", + "cbCbAa", + 10 + ], + [ + "c", + "cbbBbCcC", + 14 + ], + [ + "c", + "cbcaAAC", + 12 + ], + [ + "c", + "cc", + 2 + ], + [ + "c", + "ccB", + 4 + ], + [ + "c", + "ccCBaBAC", + 14 + ], + [ + "c", + "ccc", + 4 + ], + [ + "cA", + "A", + 2 + ], + [ + "cA", + "AAbaCB", + 10 + ], + [ + "cA", + "AC", + 4 + ], + [ + "cA", + "Ac", + 4 + ], + [ + "cA", + "Acc", + 4 + ], + [ + "cA", + "BABCB", + 8 + ], + [ + "cA", + "BBc", + 6 + ], + [ + "cA", + "BaaBCbA", + 11 + ], + [ + "cA", + "Bbb", + 6 + ], + [ + "cA", + "BbbAAccB", + 14 + ], + [ + "cA", + "Bc", + 4 + ], + [ + "cA", + "C", + 3 + ], + [ + "cA", + "CAaCAABb", + 13 + ], + [ + "cA", + "CAaacAcc", + 12 + ], + [ + "cA", + "CbaAccc", + 11 + ], + [ + "cA", + "Cbbb", + 7 + ], + [ + "cA", + "CcC", + 4 + ], + [ + "cA", + "aB", + 4 + ], + [ + "cA", + "aC", + 4 + ], + [ + "cA", + "ab", + 4 + ], + [ + "cA", + "abAAcc", + 10 + ], + [ + "cA", + "abC", + 6 + ], + [ + "cA", + "bBCAbCa", + 11 + ], + [ + "cA", + "bCbbBCAC", + 13 + ], + [ + "cA", + "bCcCBcCA", + 12 + ], + [ + "cA", + "bcaCcbC", + 11 + ], + [ + "cA", + "cABaBCb", + 10 + ], + [ + "cA", + "cBaAB", + 6 + ], + [ + "cA", + "cCBababA", + 12 + ], + [ + "cA", + "ccCBbBab", + 13 + ], + [ + "cA", + "cca", + 3 + ], + [ + "cAA", + "AaaCaBcCb", + 16 + ], + [ + "cAA", + "AbBC", + 8 + ], + [ + "cAA", + "a", + 5 + ], + [ + "cAA", + "cb", + 4 + ], + [ + "cAAA", + "cBaC", + 5 + ], + [ + "cAAAA", + "bcA", + 8 + ], + [ + "cAAAC", + "aBAaCcCca", + 13 + ], + [ + "cAAAacbCB", + "BBaACbA", + 12 + ], + [ + "cAAAbabc", + "BCAacBCBc", + 10 + ], + [ + "cAAAbbc", + "AAbb", + 6 + ], + [ + "cAAAcB", + "bbAB", + 8 + ], + [ + "cAAB", + "ABCaCbCbC", + 15 + ], + [ + "cAAB", + "Aab", + 4 + ], + [ + "cAABaBAa", + "bAaBaBA", + 5 + ], + [ + "cAAC", + "CAB", + 5 + ], + [ + "cAACA", + "CaABCCbAb", + 10 + ], + [ + "cAACAC", + "BC", + 10 + ], + [ + "cAACaCc", + "AcabA", + 9 + ], + [ + "cAACb", + "BCAcca", + 8 + ], + [ + "cAACbABCc", + "CCbAB", + 9 + ], + [ + "cAACbb", + "aAaC", + 7 + ], + [ + "cAACcAA", + "bAaCcacb", + 8 + ], + [ + "cAAa", + "caABcbBAB", + 12 + ], + [ + "cAAaB", + "BBaAb", + 7 + ], + [ + "cAAaBAAA", + "aCb", + 14 + ], + [ + "cAAaCbCc", + "CC", + 12 + ], + [ + "cAAaba", + "bcb", + 10 + ], + [ + "cAAabcCCA", + "aAa", + 13 + ], + [ + "cAAbB", + "AAcaBaa", + 10 + ], + [ + "cAAbBA", + "caCcABAB", + 9 + ], + [ + "cAAbBBaCa", + "CabcB", + 12 + ], + [ + "cAAbC", + "BAbbb", + 6 + ], + [ + "cAAba", + "CCBAabaAB", + 10 + ], + [ + "cAAc", + "bCcCCB", + 10 + ], + [ + "cAAcABCcb", + "BCBB", + 13 + ], + [ + "cAAcB", + "ca", + 7 + ], + [ + "cAAcCCAc", + "Cb", + 14 + ], + [ + "cAAcaabB", + "A", + 14 + ], + [ + "cAAccaaB", + "BBbbAcBc", + 15 + ], + [ + "cAB", + "B", + 4 + ], + [ + "cAB", + "BCAAacb", + 10 + ], + [ + "cAB", + "CaCbCca", + 11 + ], + [ + "cAB", + "CbacbCcbB", + 14 + ], + [ + "cAB", + "b", + 5 + ], + [ + "cAB", + "baabbCA", + 12 + ], + [ + "cAB", + "cbbaBbCb", + 11 + ], + [ + "cAB", + "cccBBCBC", + 12 + ], + [ + "cAB", + "cccCCCCb", + 13 + ], + [ + "cABA", + "CA", + 5 + ], + [ + "cABAABc", + "acabCCb", + 11 + ], + [ + "cABABAACA", + "cBaBCcaa", + 10 + ], + [ + "cABAa", + "c", + 8 + ], + [ + "cABAcaBb", + "BCBaBCBc", + 11 + ], + [ + "cABBAaCac", + "aAacACCcc", + 10 + ], + [ + "cABBCaBbc", + "bBAaBcACC", + 13 + ], + [ + "cABBc", + "B", + 8 + ], + [ + "cABBcacb", + "bBcCcCAA", + 13 + ], + [ + "cABC", + "B", + 6 + ], + [ + "cABCAB", + "bAcb", + 8 + ], + [ + "cABCAc", + "cBCBa", + 6 + ], + [ + "cABCAca", + "ABaCCCbcc", + 12 + ], + [ + "cABCBbbCA", + "ABBccc", + 11 + ], + [ + "cABCa", + "CaA", + 7 + ], + [ + "cABaA", + "aAAbaBb", + 9 + ], + [ + "cABaAaA", + "BAB", + 10 + ], + [ + "cABaBAC", + "acCa", + 12 + ], + [ + "cABaCAbbA", + "A", + 16 + ], + [ + "cABac", + "BaCc", + 6 + ], + [ + "cABbACA", + "BbccCBCBc", + 15 + ], + [ + "cABba", + "AAC", + 8 + ], + [ + "cABc", + "AaccB", + 7 + ], + [ + "cABcABc", + "cAcBBca", + 6 + ], + [ + "cABcBcb", + "cbBCa", + 8 + ], + [ + "cABcb", + "Cac", + 6 + ], + [ + "cABcba", + "BAab", + 8 + ], + [ + "cAC", + "BCaCAbaCa", + 13 + ], + [ + "cAC", + "C", + 4 + ], + [ + "cAC", + "CABbA", + 7 + ], + [ + "cAC", + "CAcABbA", + 10 + ], + [ + "cAC", + "bAa", + 4 + ], + [ + "cAC", + "cBBac", + 6 + ], + [ + "cACAACCbc", + "CAcABb", + 10 + ], + [ + "cACABcACC", + "CAc", + 12 + ], + [ + "cACACbC", + "BbCcAa", + 11 + ], + [ + "cACAabC", + "BbcbBcAAa", + 14 + ], + [ + "cACBCaC", + "C", + 12 + ], + [ + "cACBCcCBb", + "bBaaBaCbC", + 14 + ], + [ + "cACBaaB", + "bccBcBaB", + 9 + ], + [ + "cACCBBcb", + "Ba", + 14 + ], + [ + "cACCaa", + "aBcCaab", + 7 + ], + [ + "cACCc", + "ccAa", + 7 + ], + [ + "cACa", + "aBBcB", + 9 + ], + [ + "cACa", + "cAbCCA", + 5 + ], + [ + "cACaB", + "cAbbaBB", + 6 + ], + [ + "cACac", + "cBCBbbbB", + 12 + ], + [ + "cACbCBB", + "bBbAC", + 12 + ], + [ + "cACbaCc", + "AacCACBaB", + 11 + ], + [ + "cACbaba", + "acAACBcCC", + 11 + ], + [ + "cACbbC", + "Cba", + 8 + ], + [ + "cACbbb", + "ccacBccbA", + 11 + ], + [ + "cACbcb", + "b", + 10 + ], + [ + "cACc", + "Cc", + 4 + ], + [ + "cACc", + "bAba", + 6 + ], + [ + "cACcA", + "Caccc", + 5 + ], + [ + "cACcAcc", + "bbB", + 14 + ], + [ + "cACca", + "acabb", + 9 + ], + [ + "cACcaA", + "bB", + 12 + ], + [ + "cACccAacA", + "bcCBabCc", + 14 + ], + [ + "cAa", + "BacbCAbcA", + 13 + ], + [ + "cAa", + "Bbcb", + 8 + ], + [ + "cAa", + "C", + 5 + ], + [ + "cAa", + "aCBcCAcc", + 12 + ], + [ + "cAa", + "aCacc", + 8 + ], + [ + "cAa", + "caBcA", + 6 + ], + [ + "cAa", + "cacAbaAb", + 10 + ], + [ + "cAa", + "ccccAcaBC", + 12 + ], + [ + "cAaA", + "CbbaAaba", + 10 + ], + [ + "cAaAA", + "CaCbcbab", + 13 + ], + [ + "cAaAA", + "acAc", + 7 + ], + [ + "cAaAABAcb", + "bAba", + 14 + ], + [ + "cAaACBaa", + "cbBabcaac", + 11 + ], + [ + "cAaACc", + "ccbBB", + 10 + ], + [ + "cAaAaaB", + "CBCbBccBa", + 15 + ], + [ + "cAaAc", + "ABCACcb", + 10 + ], + [ + "cAaB", + "C", + 7 + ], + [ + "cAaB", + "aBaBA", + 6 + ], + [ + "cAaBCBbAA", + "aAc", + 14 + ], + [ + "cAaBaA", + "a", + 10 + ], + [ + "cAaC", + "BcbAbbCb", + 10 + ], + [ + "cAaC", + "CbB", + 7 + ], + [ + "cAaCAc", + "ac", + 8 + ], + [ + "cAaCaAc", + "bBBBbaC", + 12 + ], + [ + "cAaCaC", + "ABBa", + 8 + ], + [ + "cAaCc", + "c", + 8 + ], + [ + "cAaaAAA", + "BBCAa", + 11 + ], + [ + "cAaaaBCA", + "AcABc", + 10 + ], + [ + "cAaaacAB", + "aAbCB", + 10 + ], + [ + "cAaaacaa", + "ABB", + 14 + ], + [ + "cAaacB", + "AaCBbACB", + 10 + ], + [ + "cAaaca", + "bAbbc", + 8 + ], + [ + "cAabACa", + "bcaabaaAb", + 9 + ], + [ + "cAabCA", + "CbACAAcb", + 11 + ], + [ + "cAaba", + "a", + 8 + ], + [ + "cAabcacaa", + "aA", + 15 + ], + [ + "cAacAaBBC", + "bBaBAbcaC", + 12 + ], + [ + "cAaca", + "AcacAA", + 7 + ], + [ + "cAaca", + "BcCcBBBA", + 13 + ], + [ + "cAacc", + "BBCaCA", + 9 + ], + [ + "cAacc", + "a", + 8 + ], + [ + "cAacccAb", + "ccbbBACA", + 13 + ], + [ + "cAb", + "B", + 5 + ], + [ + "cAb", + "BAbABAC", + 10 + ], + [ + "cAb", + "BBAAc", + 8 + ], + [ + "cAb", + "CBABCa", + 8 + ], + [ + "cAb", + "CbBBaA", + 10 + ], + [ + "cAb", + "caBACCa", + 10 + ], + [ + "cAbA", + "Cacc", + 6 + ], + [ + "cAbA", + "aAAACA", + 8 + ], + [ + "cAbABbab", + "aCA", + 13 + ], + [ + "cAbAC", + "BAAc", + 5 + ], + [ + "cAbACB", + "bAcCC", + 8 + ], + [ + "cAbACcCaa", + "cBa", + 13 + ], + [ + "cAbAb", + "acBC", + 9 + ], + [ + "cAbAbA", + "bACaC", + 9 + ], + [ + "cAbAbAAAa", + "A", + 16 + ], + [ + "cAbBB", + "AbaaC", + 8 + ], + [ + "cAbBaAAAA", + "BabaaBAa", + 9 + ], + [ + "cAbBaB", + "AcB", + 8 + ], + [ + "cAbaBbBC", + "a", + 14 + ], + [ + "cAbab", + "Ba", + 7 + ], + [ + "cAbabb", + "bC", + 10 + ], + [ + "cAbbB", + "aBBcaAA", + 13 + ], + [ + "cAbbBCAcB", + "aabbaC", + 11 + ], + [ + "cAbbBaca", + "CbCAcBaC", + 12 + ], + [ + "cAbbBbcC", + "CB", + 13 + ], + [ + "cAbbb", + "cCbaBAAAc", + 13 + ], + [ + "cAbcAcBA", + "AcA", + 10 + ], + [ + "cAbcaCccC", + "ABbAbbcB", + 12 + ], + [ + "cAbcbB", + "AAABaac", + 11 + ], + [ + "cAbccBCBc", + "AAACAcbAc", + 12 + ], + [ + "cAc", + "AbBCcaBB", + 13 + ], + [ + "cAc", + "BCCcCaBac", + 13 + ], + [ + "cAc", + "CB", + 5 + ], + [ + "cAc", + "bBb", + 6 + ], + [ + "cAc", + "bCaCaCb", + 11 + ], + [ + "cAc", + "bcb", + 6 + ], + [ + "cAc", + "cAAcaa", + 6 + ], + [ + "cAcA", + "CaaB", + 6 + ], + [ + "cAcAA", + "cbAcBbB", + 8 + ], + [ + "cAcABAAc", + "aABaBBc", + 9 + ], + [ + "cAcACcBb", + "cacbCccC", + 7 + ], + [ + "cAcAb", + "aBbAA", + 8 + ], + [ + "cAcAcAcCc", + "caaAAcbc", + 7 + ], + [ + "cAcAcCB", + "ccbcbBbC", + 10 + ], + [ + "cAcBBaBCb", + "C", + 16 + ], + [ + "cAcBCb", + "abCbAAB", + 11 + ], + [ + "cAcBCcBba", + "A", + 16 + ], + [ + "cAcBbA", + "aBabBACbB", + 13 + ], + [ + "cAcBbB", + "ABBcacBBA", + 10 + ], + [ + "cAcCAB", + "CBBbc", + 11 + ], + [ + "cAcCBCa", + "CCA", + 9 + ], + [ + "cAcCBcBBa", + "CacACBBBB", + 8 + ], + [ + "cAcCCBCBA", + "ccCcbcbc", + 8 + ], + [ + "cAcCbCcAB", + "caC", + 13 + ], + [ + "cAcCcbaaA", + "CcBaa", + 9 + ], + [ + "cAca", + "BAcbCbC", + 10 + ], + [ + "cAcaAa", + "caAAaab", + 7 + ], + [ + "cAcaBAAC", + "BBB", + 14 + ], + [ + "cAcaaa", + "BaBaBC", + 9 + ], + [ + "cAcaaca", + "aaCBA", + 10 + ], + [ + "cAcabCbCB", + "BacBcbABb", + 11 + ], + [ + "cAcabaB", + "Cc", + 11 + ], + [ + "cAcac", + "acbA", + 7 + ], + [ + "cAcbABCBB", + "aABc", + 12 + ], + [ + "cAcbBCBac", + "bCbAAacB", + 13 + ], + [ + "cAcbbccAc", + "AABAaBbCb", + 16 + ], + [ + "cAcc", + "aCa", + 6 + ], + [ + "cAcc", + "bCAAcaCC", + 10 + ], + [ + "cAcc", + "cc", + 4 + ], + [ + "cAccCB", + "aAABca", + 9 + ], + [ + "cAccaBCAb", + "BBcBCCAbb", + 12 + ], + [ + "cAccaaABa", + "bCAcB", + 13 + ], + [ + "cAcccAA", + "bCAb", + 11 + ], + [ + "cAcccaCaA", + "abaB", + 14 + ], + [ + "cAcccacab", + "BbCCbaB", + 13 + ], + [ + "cB", + "AbAB", + 6 + ], + [ + "cB", + "AbBbCA", + 10 + ], + [ + "cB", + "B", + 2 + ], + [ + "cB", + "BACbBc", + 9 + ], + [ + "cB", + "BAcB", + 4 + ], + [ + "cB", + "BBaBaaccC", + 16 + ], + [ + "cB", + "BcAaA", + 8 + ], + [ + "cB", + "C", + 3 + ], + [ + "cB", + "CAA", + 5 + ], + [ + "cB", + "CAAA", + 7 + ], + [ + "cB", + "CAacabCCC", + 15 + ], + [ + "cB", + "CBBB", + 5 + ], + [ + "cB", + "CCBCABaaA", + 15 + ], + [ + "cB", + "Cc", + 3 + ], + [ + "cB", + "CcBAc", + 6 + ], + [ + "cB", + "a", + 4 + ], + [ + "cB", + "aACCba", + 10 + ], + [ + "cB", + "aacbcC", + 9 + ], + [ + "cB", + "acaaAABB", + 12 + ], + [ + "cB", + "b", + 3 + ], + [ + "cB", + "ba", + 4 + ], + [ + "cB", + "baacB", + 6 + ], + [ + "cB", + "bc", + 4 + ], + [ + "cB", + "cABAbCBc", + 12 + ], + [ + "cB", + "cCAB", + 4 + ], + [ + "cB", + "caAAbbBC", + 12 + ], + [ + "cB", + "caBAAa", + 8 + ], + [ + "cBA", + "Ac", + 6 + ], + [ + "cBA", + "CB", + 3 + ], + [ + "cBA", + "a", + 5 + ], + [ + "cBA", + "ac", + 6 + ], + [ + "cBA", + "b", + 5 + ], + [ + "cBA", + "bbaBac", + 9 + ], + [ + "cBA", + "cAaabbab", + 12 + ], + [ + "cBAA", + "AAB", + 6 + ], + [ + "cBAA", + "aCabbA", + 8 + ], + [ + "cBAAB", + "CCa", + 8 + ], + [ + "cBAABa", + "bA", + 9 + ], + [ + "cBAABccc", + "caBcbAAa", + 13 + ], + [ + "cBAAbCcC", + "Bcc", + 11 + ], + [ + "cBAAcAbAC", + "bBaacb", + 10 + ], + [ + "cBAB", + "cBBcaCCb", + 10 + ], + [ + "cBABaBCc", + "BAABc", + 7 + ], + [ + "cBABaac", + "baCbbb", + 12 + ], + [ + "cBABbBAaA", + "c", + 16 + ], + [ + "cBABba", + "AaAccABac", + 12 + ], + [ + "cBABca", + "aBcB", + 7 + ], + [ + "cBACBAAcA", + "BBCbCCBb", + 13 + ], + [ + "cBACa", + "cbaabBBcA", + 12 + ], + [ + "cBACc", + "cBbBaCb", + 7 + ], + [ + "cBACcBBC", + "AbaaBbcC", + 11 + ], + [ + "cBACcbCaa", + "ab", + 15 + ], + [ + "cBAa", + "cCCBaAc", + 8 + ], + [ + "cBAaBcaB", + "b", + 15 + ], + [ + "cBAacbBa", + "aaBb", + 11 + ], + [ + "cBAbCaBA", + "ccaB", + 9 + ], + [ + "cBAba", + "B", + 8 + ], + [ + "cBAbaa", + "CaccCBA", + 12 + ], + [ + "cBAbb", + "ca", + 7 + ], + [ + "cBAbbCaCc", + "aaCA", + 13 + ], + [ + "cBAbca", + "aaACbA", + 9 + ], + [ + "cBAc", + "BA", + 4 + ], + [ + "cBAc", + "aCCcbbbcC", + 13 + ], + [ + "cBAcAb", + "BCabCbcc", + 13 + ], + [ + "cBAcAbaa", + "AAC", + 12 + ], + [ + "cBAcBBc", + "cCcaaa", + 10 + ], + [ + "cBAcCCb", + "cCcAc", + 9 + ], + [ + "cBAcb", + "CaAAACba", + 10 + ], + [ + "cBB", + "BacacBcCA", + 14 + ], + [ + "cBB", + "Bc", + 4 + ], + [ + "cBB", + "bAACA", + 10 + ], + [ + "cBB", + "bCbBBC", + 7 + ], + [ + "cBBA", + "AcAAcABa", + 11 + ], + [ + "cBBA", + "Cca", + 6 + ], + [ + "cBBABC", + "bCcbaAB", + 9 + ], + [ + "cBBABC", + "cCCcBcBc", + 9 + ], + [ + "cBBAac", + "CbbbcB", + 9 + ], + [ + "cBBBABBA", + "AAAbAAAB", + 13 + ], + [ + "cBBBCA", + "caacccAbA", + 13 + ], + [ + "cBBBCacAB", + "Accab", + 13 + ], + [ + "cBBBcbA", + "cB", + 10 + ], + [ + "cBBC", + "acaC", + 6 + ], + [ + "cBBCBaCbA", + "CBcBaAc", + 10 + ], + [ + "cBBCCAca", + "ABCcCa", + 8 + ], + [ + "cBBCb", + "cBBbaaC", + 8 + ], + [ + "cBBCbB", + "aCbBaCaB", + 8 + ], + [ + "cBBaBaAac", + "C", + 17 + ], + [ + "cBBaaCbBb", + "baCCBa", + 11 + ], + [ + "cBBabaAc", + "b", + 14 + ], + [ + "cBBac", + "ba", + 7 + ], + [ + "cBBacC", + "aBcCAC", + 8 + ], + [ + "cBBbAaabA", + "aaA", + 12 + ], + [ + "cBBbB", + "BCcAACb", + 11 + ], + [ + "cBBbBaBcA", + "bbCCCc", + 13 + ], + [ + "cBBbCbc", + "ACccCBaCB", + 13 + ], + [ + "cBBbbaBcb", + "Cc", + 15 + ], + [ + "cBBbbbb", + "acBbaBca", + 10 + ], + [ + "cBBbbcAC", + "bCaBbbcbB", + 9 + ], + [ + "cBBbbcacb", + "BcCcaaBA", + 13 + ], + [ + "cBBbca", + "BbA", + 7 + ], + [ + "cBBcAccA", + "AcbbAC", + 11 + ], + [ + "cBBcBb", + "BaCb", + 7 + ], + [ + "cBBcaBcB", + "Aa", + 14 + ], + [ + "cBBcbC", + "bcCBacb", + 8 + ], + [ + "cBC", + "cACacBc", + 9 + ], + [ + "cBC", + "cCa", + 4 + ], + [ + "cBCA", + "C", + 6 + ], + [ + "cBCACaCaC", + "ccBBBCaac", + 9 + ], + [ + "cBCAaac", + "cB", + 10 + ], + [ + "cBCAacA", + "aaAcA", + 8 + ], + [ + "cBCAcCccC", + "cbB", + 15 + ], + [ + "cBCAcbC", + "CcAbCbbaA", + 13 + ], + [ + "cBCB", + "bbabCAAbB", + 13 + ], + [ + "cBCBCbCa", + "bcCAaCCa", + 10 + ], + [ + "cBCBacA", + "AcbBaA", + 7 + ], + [ + "cBCBbCBa", + "c", + 14 + ], + [ + "cBCCABcC", + "Baa", + 13 + ], + [ + "cBCCB", + "a", + 10 + ], + [ + "cBCCBcaBa", + "AcAAba", + 13 + ], + [ + "cBCCC", + "A", + 10 + ], + [ + "cBCCcBc", + "ccaBCB", + 9 + ], + [ + "cBCaB", + "BBbAA", + 7 + ], + [ + "cBCab", + "aaABbC", + 10 + ], + [ + "cBCacA", + "abcbAbAa", + 11 + ], + [ + "cBCb", + "aCbCc", + 6 + ], + [ + "cBCb", + "b", + 6 + ], + [ + "cBCb", + "cAA", + 6 + ], + [ + "cBCbCAc", + "ACacAB", + 9 + ], + [ + "cBCbCca", + "aaB", + 13 + ], + [ + "cBCbabA", + "bbBbABB", + 9 + ], + [ + "cBCbbBBbc", + "aCaBBbbb", + 10 + ], + [ + "cBCbcCC", + "ACBbBBc", + 10 + ], + [ + "cBCc", + "AcaCBCb", + 8 + ], + [ + "cBCcAbcac", + "aBcac", + 10 + ], + [ + "cBCcbccaa", + "bBbCaBB", + 13 + ], + [ + "cBa", + "b", + 5 + ], + [ + "cBa", + "bAAaA", + 8 + ], + [ + "cBaAA", + "baaCbca", + 11 + ], + [ + "cBaAAB", + "BcbB", + 8 + ], + [ + "cBaAACacA", + "bBa", + 14 + ], + [ + "cBaABacb", + "ACb", + 11 + ], + [ + "cBaB", + "BabB", + 4 + ], + [ + "cBaB", + "CBBBC", + 5 + ], + [ + "cBaBBAB", + "B", + 12 + ], + [ + "cBaBBCc", + "BacCACa", + 10 + ], + [ + "cBaBaABBB", + "bcc", + 17 + ], + [ + "cBaBbCBC", + "cAAB", + 11 + ], + [ + "cBaBc", + "bbC", + 7 + ], + [ + "cBaC", + "BacB", + 5 + ], + [ + "cBaC", + "bA", + 6 + ], + [ + "cBaCA", + "CAcabbb", + 11 + ], + [ + "cBaCAbCC", + "B", + 14 + ], + [ + "cBaCAccbc", + "bbccAcCBB", + 10 + ], + [ + "cBaCCC", + "ab", + 10 + ], + [ + "cBaCaBC", + "Cb", + 11 + ], + [ + "cBaCab", + "BC", + 8 + ], + [ + "cBaa", + "BAab", + 5 + ], + [ + "cBaaA", + "Bb", + 8 + ], + [ + "cBaaCabBb", + "aCACcCbbb", + 11 + ], + [ + "cBaaaBBac", + "bcaAbBcC", + 10 + ], + [ + "cBaab", + "acAacAbCc", + 11 + ], + [ + "cBab", + "ACCAB", + 7 + ], + [ + "cBabB", + "C", + 9 + ], + [ + "cBabBCaca", + "C", + 16 + ], + [ + "cBabBcab", + "CbcAAAa", + 12 + ], + [ + "cBabCaA", + "aaAbAaac", + 10 + ], + [ + "cBabbBCBb", + "C", + 16 + ], + [ + "cBac", + "A", + 7 + ], + [ + "cBacCAB", + "B", + 12 + ], + [ + "cBacabC", + "aAAaB", + 10 + ], + [ + "cBacac", + "c", + 10 + ], + [ + "cBb", + "BbbA", + 5 + ], + [ + "cBb", + "CAbcC", + 7 + ], + [ + "cBb", + "acAB", + 5 + ], + [ + "cBbACBB", + "bCCCAbbC", + 12 + ], + [ + "cBbACC", + "ACa", + 8 + ], + [ + "cBbAcabB", + "aA", + 14 + ], + [ + "cBbC", + "abAabbbc", + 12 + ], + [ + "cBbCAACc", + "bBB", + 13 + ], + [ + "cBbCAB", + "cbCb", + 5 + ], + [ + "cBbCAa", + "cacaBBAb", + 11 + ], + [ + "cBbCAaA", + "AB", + 12 + ], + [ + "cBbCAb", + "bC", + 8 + ], + [ + "cBbCBAAA", + "AbBbc", + 12 + ], + [ + "cBbCCC", + "BCba", + 8 + ], + [ + "cBbCc", + "ccaCBA", + 8 + ], + [ + "cBbCccaC", + "bA", + 13 + ], + [ + "cBba", + "cb", + 4 + ], + [ + "cBbaACaa", + "cC", + 12 + ], + [ + "cBbaCbc", + "ccaaca", + 9 + ], + [ + "cBbaaac", + "b", + 12 + ], + [ + "cBbaab", + "BbbBcC", + 9 + ], + [ + "cBbaccBA", + "c", + 14 + ], + [ + "cBbb", + "CCcCaa", + 10 + ], + [ + "cBbb", + "abCb", + 5 + ], + [ + "cBbbA", + "A", + 8 + ], + [ + "cBbbA", + "B", + 8 + ], + [ + "cBbbBAAb", + "AAaa", + 13 + ], + [ + "cBbbBBacb", + "cCaCCcAac", + 14 + ], + [ + "cBbbBCaa", + "AaBc", + 13 + ], + [ + "cBbbCa", + "CB", + 9 + ], + [ + "cBbbcBB", + "bAACBBb", + 10 + ], + [ + "cBbcBaCBC", + "abA", + 15 + ], + [ + "cBbcCAC", + "b", + 12 + ], + [ + "cBbcCb", + "caBBbb", + 7 + ], + [ + "cBbcaBAAc", + "bB", + 14 + ], + [ + "cBbcbAAb", + "aba", + 13 + ], + [ + "cBbcbcBB", + "AccaA", + 12 + ], + [ + "cBbccCcc", + "aaCBabcBB", + 15 + ], + [ + "cBbccb", + "caaABcBb", + 9 + ], + [ + "cBc", + "BCaAAAbB", + 14 + ], + [ + "cBc", + "CAAC", + 6 + ], + [ + "cBc", + "aAc", + 4 + ], + [ + "cBc", + "aBaAAc", + 8 + ], + [ + "cBc", + "aabbAc", + 9 + ], + [ + "cBc", + "aac", + 4 + ], + [ + "cBc", + "c", + 4 + ], + [ + "cBcA", + "bC", + 6 + ], + [ + "cBcAAbbcb", + "BAbb", + 10 + ], + [ + "cBcACAA", + "a", + 13 + ], + [ + "cBcACb", + "Bc", + 8 + ], + [ + "cBcAaACbc", + "abbB", + 14 + ], + [ + "cBcBaaC", + "AbC", + 11 + ], + [ + "cBcBbCC", + "aBbCaba", + 11 + ], + [ + "cBcBbCbbA", + "cBa", + 13 + ], + [ + "cBcBbb", + "Acb", + 8 + ], + [ + "cBcCaaAcb", + "baccACCCc", + 13 + ], + [ + "cBcCbcCa", + "aCa", + 12 + ], + [ + "cBcCccaAa", + "BCaCCabbA", + 12 + ], + [ + "cBcaAaC", + "bACBCAB", + 12 + ], + [ + "cBcaAbBCb", + "baCbbaa", + 12 + ], + [ + "cBcaAbc", + "aa", + 11 + ], + [ + "cBcaAcaaA", + "CACbcC", + 14 + ], + [ + "cBcaBcBc", + "aBbBCACc", + 11 + ], + [ + "cBcaCcCA", + "Bcc", + 10 + ], + [ + "cBcabC", + "bAAAabb", + 10 + ], + [ + "cBcbACbBB", + "ACBc", + 12 + ], + [ + "cBcbBAbAC", + "A", + 16 + ], + [ + "cBcbC", + "AAbBcCa", + 10 + ], + [ + "cBcbcaCb", + "cCbcCB", + 6 + ], + [ + "cBcc", + "bAcAcaaba", + 14 + ], + [ + "cBcc", + "cacc", + 2 + ], + [ + "cBccaAac", + "aab", + 12 + ], + [ + "cBccaBCB", + "Caa", + 13 + ], + [ + "cBccacbCA", + "bBCBAca", + 11 + ], + [ + "cBccbc", + "CAbA", + 9 + ], + [ + "cBcccCAC", + "BA", + 12 + ], + [ + "cC", + "A", + 4 + ], + [ + "cC", + "ABCCCa", + 9 + ], + [ + "cC", + "AbAacCAc", + 12 + ], + [ + "cC", + "AccAAABc", + 13 + ], + [ + "cC", + "BBAabcC", + 10 + ], + [ + "cC", + "BBc", + 5 + ], + [ + "cC", + "BBcaACaA", + 12 + ], + [ + "cC", + "BCABBCAaC", + 15 + ], + [ + "cC", + "BaAbcaBc", + 13 + ], + [ + "cC", + "BaBaccb", + 11 + ], + [ + "cC", + "CBA", + 5 + ], + [ + "cC", + "CacCac", + 8 + ], + [ + "cC", + "CcACcacbB", + 14 + ], + [ + "cC", + "CcBbb", + 8 + ], + [ + "cC", + "aACbbCAB", + 13 + ], + [ + "cC", + "aBABCBbc", + 14 + ], + [ + "cC", + "aCCcAAca", + 13 + ], + [ + "cC", + "aaBaBbAA", + 16 + ], + [ + "cC", + "acAb", + 6 + ], + [ + "cC", + "b", + 4 + ], + [ + "cC", + "bA", + 4 + ], + [ + "cC", + "bACBaA", + 10 + ], + [ + "cC", + "bacAcbc", + 11 + ], + [ + "cC", + "bcaCBaB", + 10 + ], + [ + "cC", + "c", + 2 + ], + [ + "cC", + "cA", + 2 + ], + [ + "cC", + "cABAc", + 7 + ], + [ + "cC", + "cAbc", + 5 + ], + [ + "cC", + "cBA", + 4 + ], + [ + "cC", + "cBCAccaCb", + 14 + ], + [ + "cC", + "cabcBCB", + 10 + ], + [ + "cC", + "cccaBa", + 9 + ], + [ + "cCA", + "c", + 4 + ], + [ + "cCAABb", + "ACbaBC", + 7 + ], + [ + "cCAACb", + "bbC", + 10 + ], + [ + "cCAAacBb", + "a", + 14 + ], + [ + "cCAAc", + "ABbCcbBb", + 14 + ], + [ + "cCAAc", + "AC", + 7 + ], + [ + "cCAB", + "AAaCAABab", + 12 + ], + [ + "cCABbAb", + "Ab", + 10 + ], + [ + "cCABbaBaA", + "aacC", + 15 + ], + [ + "cCAC", + "bCbbbbAC", + 10 + ], + [ + "cCACAb", + "AbC", + 10 + ], + [ + "cCACCc", + "cccbAabc", + 9 + ], + [ + "cCACc", + "BbAcaB", + 9 + ], + [ + "cCAa", + "CBA", + 5 + ], + [ + "cCAaabBbA", + "bCCCcacb", + 13 + ], + [ + "cCAac", + "BBA", + 8 + ], + [ + "cCAacBCc", + "CCBBaA", + 11 + ], + [ + "cCAacCCbA", + "bCACCa", + 9 + ], + [ + "cCAbA", + "aBBcaccbA", + 11 + ], + [ + "cCAbABC", + "bbACCaACB", + 13 + ], + [ + "cCAbACcc", + "AbBAccbb", + 11 + ], + [ + "cCAbCacAA", + "BcABBAC", + 12 + ], + [ + "cCAbbaA", + "CcACabA", + 8 + ], + [ + "cCAbcA", + "BABABC", + 10 + ], + [ + "cCAcAcbaB", + "BccBaCC", + 13 + ], + [ + "cCAcCAB", + "bcccCbbab", + 11 + ], + [ + "cCAcaabBA", + "bBcbCCBa", + 13 + ], + [ + "cCAcbBBa", + "AaBca", + 10 + ], + [ + "cCAcbcB", + "c", + 12 + ], + [ + "cCB", + "BBCAbba", + 11 + ], + [ + "cCB", + "BCcab", + 7 + ], + [ + "cCB", + "CC", + 3 + ], + [ + "cCB", + "CbBa", + 5 + ], + [ + "cCB", + "a", + 6 + ], + [ + "cCB", + "aC", + 4 + ], + [ + "cCBA", + "abcA", + 6 + ], + [ + "cCBACb", + "abBccaC", + 11 + ], + [ + "cCBAbCCa", + "a", + 14 + ], + [ + "cCBAbaC", + "aAbaAa", + 10 + ], + [ + "cCBAcCB", + "CbaCB", + 6 + ], + [ + "cCBBAb", + "cBcaC", + 7 + ], + [ + "cCBBBc", + "Cc", + 8 + ], + [ + "cCBBaa", + "CBC", + 8 + ], + [ + "cCBCBAc", + "ABCBCBbCB", + 9 + ], + [ + "cCBCa", + "AcacaBCAc", + 10 + ], + [ + "cCBCbB", + "Cc", + 9 + ], + [ + "cCBCcbB", + "cCBaAaBc", + 8 + ], + [ + "cCBaAac", + "C", + 12 + ], + [ + "cCBaCc", + "CcbBBbB", + 10 + ], + [ + "cCBac", + "bb", + 9 + ], + [ + "cCBbAC", + "abAbC", + 8 + ], + [ + "cCBbAaabb", + "BCc", + 16 + ], + [ + "cCBbAcCAC", + "acBCCbA", + 12 + ], + [ + "cCBbAccB", + "abA", + 12 + ], + [ + "cCBbbB", + "bbaaCCBbB", + 11 + ], + [ + "cCBc", + "ABbacCc", + 10 + ], + [ + "cCBc", + "cAcBb", + 5 + ], + [ + "cCBcABc", + "ac", + 11 + ], + [ + "cCBcACBa", + "cACcB", + 10 + ], + [ + "cCBcACCa", + "BACAAaa", + 11 + ], + [ + "cCBca", + "cbCacC", + 6 + ], + [ + "cCBcb", + "BCbAABAba", + 12 + ], + [ + "cCBcbCaCb", + "cbBCa", + 10 + ], + [ + "cCC", + "BbacaAb", + 12 + ], + [ + "cCC", + "CB", + 4 + ], + [ + "cCC", + "accaCCCcb", + 12 + ], + [ + "cCC", + "bAbcCcbcb", + 13 + ], + [ + "cCC", + "bB", + 6 + ], + [ + "cCC", + "bCBbABBCc", + 14 + ], + [ + "cCC", + "baAAb", + 10 + ], + [ + "cCC", + "cABBc", + 7 + ], + [ + "cCC", + "cCCbaac", + 8 + ], + [ + "cCCAbbbaa", + "BccccA", + 15 + ], + [ + "cCCAc", + "ccAbbb", + 9 + ], + [ + "cCCBBaBC", + "bcaA", + 13 + ], + [ + "cCCBCAaA", + "baB", + 13 + ], + [ + "cCCBc", + "bAccaAcB", + 11 + ], + [ + "cCCCC", + "cBC", + 6 + ], + [ + "cCCCaA", + "cCbB", + 8 + ], + [ + "cCCCaac", + "BCAcCb", + 11 + ], + [ + "cCCCbA", + "CcBBBBb", + 11 + ], + [ + "cCCCbb", + "ABccCcA", + 10 + ], + [ + "cCCCbbbAa", + "cA", + 14 + ], + [ + "cCCa", + "AccBc", + 7 + ], + [ + "cCCaA", + "BcACCA", + 6 + ], + [ + "cCCaAAAC", + "aBbcC", + 12 + ], + [ + "cCCaCB", + "CaaAcbCAB", + 12 + ], + [ + "cCCaccA", + "bc", + 12 + ], + [ + "cCCaccAC", + "abAACcCa", + 12 + ], + [ + "cCCb", + "C", + 6 + ], + [ + "cCCb", + "cAcBa", + 6 + ], + [ + "cCCbBCBab", + "CCcaca", + 11 + ], + [ + "cCCbb", + "BCBbbcA", + 8 + ], + [ + "cCCbc", + "bCCC", + 5 + ], + [ + "cCCbcbabA", + "aaCCc", + 14 + ], + [ + "cCCcABBB", + "aBBbABcb", + 11 + ], + [ + "cCCcCCcAa", + "bBCab", + 15 + ], + [ + "cCCcaaC", + "aBC", + 10 + ], + [ + "cCa", + "BacAaCAcA", + 13 + ], + [ + "cCa", + "C", + 4 + ], + [ + "cCa", + "CAACAAaC", + 11 + ], + [ + "cCa", + "aBBcbc", + 10 + ], + [ + "cCa", + "aCBab", + 6 + ], + [ + "cCa", + "aaCCAAAb", + 12 + ], + [ + "cCa", + "bBAcCcB", + 10 + ], + [ + "cCa", + "cBBcaCB", + 9 + ], + [ + "cCaA", + "CCaca", + 4 + ], + [ + "cCaA", + "cBcccC", + 9 + ], + [ + "cCaAAACA", + "cBBbacc", + 12 + ], + [ + "cCaAAacCc", + "cbCaBcA", + 12 + ], + [ + "cCaABCAAA", + "A", + 16 + ], + [ + "cCaAb", + "aBaAB", + 5 + ], + [ + "cCaAbAABA", + "CCabcAAbb", + 8 + ], + [ + "cCaAc", + "ABAbbBBB", + 15 + ], + [ + "cCaAcACaa", + "caaBcBc", + 11 + ], + [ + "cCaAcCBca", + "ABcc", + 12 + ], + [ + "cCaAcbA", + "aBCBcCCba", + 12 + ], + [ + "cCaB", + "ABABAbBBc", + 15 + ], + [ + "cCaBBaAb", + "aA", + 12 + ], + [ + "cCaBBaCAC", + "bC", + 15 + ], + [ + "cCaBBba", + "aa", + 10 + ], + [ + "cCaBCbb", + "BcaCB", + 8 + ], + [ + "cCaBb", + "Ac", + 9 + ], + [ + "cCaC", + "AC", + 5 + ], + [ + "cCaCA", + "BBBbbCAC", + 12 + ], + [ + "cCaCBBBCb", + "B", + 16 + ], + [ + "cCaCCB", + "BcBac", + 9 + ], + [ + "cCaCaB", + "AbcA", + 10 + ], + [ + "cCaCaaaA", + "abcCcc", + 14 + ], + [ + "cCaCc", + "aA", + 8 + ], + [ + "cCaa", + "CcCbcbA", + 9 + ], + [ + "cCaaBCb", + "A", + 13 + ], + [ + "cCaab", + "a", + 8 + ], + [ + "cCabB", + "AbbA", + 8 + ], + [ + "cCabB", + "AcaaACCb", + 11 + ], + [ + "cCabC", + "aBcB", + 8 + ], + [ + "cCabaBC", + "aB", + 10 + ], + [ + "cCabc", + "cabcccAB", + 10 + ], + [ + "cCabcBa", + "abccAaAB", + 12 + ], + [ + "cCac", + "AacBAaA", + 10 + ], + [ + "cCacacaa", + "CACbAbcC", + 13 + ], + [ + "cCacba", + "aAbAbBAc", + 13 + ], + [ + "cCb", + "AccbcbcB", + 11 + ], + [ + "cCb", + "BaC", + 6 + ], + [ + "cCb", + "BabCcAA", + 12 + ], + [ + "cCb", + "aCaBbBbC", + 12 + ], + [ + "cCb", + "accCcBAbA", + 12 + ], + [ + "cCb", + "cC", + 2 + ], + [ + "cCbAB", + "bcaac", + 8 + ], + [ + "cCbAB", + "cca", + 6 + ], + [ + "cCbAc", + "baB", + 7 + ], + [ + "cCbAcaB", + "AaBB", + 10 + ], + [ + "cCbBAc", + "bbBBBCa", + 10 + ], + [ + "cCbBBAbC", + "BCa", + 13 + ], + [ + "cCbBa", + "AAcCCaAB", + 11 + ], + [ + "cCbBacc", + "aBAbCAc", + 11 + ], + [ + "cCbBb", + "aacaBa", + 9 + ], + [ + "cCbBb", + "baAAacaCA", + 17 + ], + [ + "cCbBbc", + "acaAbC", + 8 + ], + [ + "cCbC", + "B", + 7 + ], + [ + "cCbC", + "CcBaA", + 7 + ], + [ + "cCbC", + "aC", + 6 + ], + [ + "cCbCCbCaA", + "acBBbCcC", + 12 + ], + [ + "cCbCaCBa", + "aBBAAbaA", + 13 + ], + [ + "cCbCac", + "CBAB", + 8 + ], + [ + "cCbCcaCc", + "cAbbAab", + 10 + ], + [ + "cCbCcbcbA", + "cbb", + 12 + ], + [ + "cCbaACaB", + "AB", + 12 + ], + [ + "cCbaAcaa", + "BCcCcb", + 12 + ], + [ + "cCbaB", + "aCCbc", + 7 + ], + [ + "cCbbAaaba", + "CccBCA", + 14 + ], + [ + "cCbbAbBC", + "acaAcBC", + 9 + ], + [ + "cCbbBC", + "bca", + 10 + ], + [ + "cCbbCB", + "AaBb", + 9 + ], + [ + "cCbbCBc", + "aBBAbba", + 12 + ], + [ + "cCbbCaA", + "A", + 12 + ], + [ + "cCbbabAC", + "B", + 15 + ], + [ + "cCbbccCb", + "bAcCc", + 10 + ], + [ + "cCbcABAa", + "ABaACa", + 11 + ], + [ + "cCbcB", + "bBBcbbA", + 10 + ], + [ + "cCbcbc", + "Aa", + 12 + ], + [ + "cCbccbB", + "abaaBc", + 11 + ], + [ + "cCbccbbaC", + "aCBAcBB", + 11 + ], + [ + "cCc", + "ABcAcB", + 8 + ], + [ + "cCc", + "BbaaC", + 9 + ], + [ + "cCc", + "CAbAabcAc", + 14 + ], + [ + "cCc", + "CccC", + 4 + ], + [ + "cCcA", + "CBaCbc", + 9 + ], + [ + "cCcAAC", + "cCbaCa", + 7 + ], + [ + "cCcAAbbcB", + "A", + 16 + ], + [ + "cCcAB", + "BCCa", + 6 + ], + [ + "cCcACAaCB", + "cccb", + 12 + ], + [ + "cCcAbbBbc", + "CBbaAb", + 12 + ], + [ + "cCcAcAa", + "c", + 12 + ], + [ + "cCcBC", + "CBBAbBAcC", + 13 + ], + [ + "cCcBCcbcb", + "C", + 16 + ], + [ + "cCcC", + "aAcbBCb", + 10 + ], + [ + "cCcCAb", + "bAaCcaCCB", + 11 + ], + [ + "cCcCaCaCB", + "AC", + 15 + ], + [ + "cCcCcB", + "b", + 11 + ], + [ + "cCcaAbCC", + "cAAaCC", + 7 + ], + [ + "cCcaBA", + "C", + 10 + ], + [ + "cCcaBBB", + "BCaCCcB", + 10 + ], + [ + "cCcaC", + "CCAcbCcCc", + 11 + ], + [ + "cCcaCa", + "AAcb", + 10 + ], + [ + "cCcaabba", + "A", + 15 + ], + [ + "cCcabc", + "bc", + 8 + ], + [ + "cCcb", + "BBaAbbaAb", + 16 + ], + [ + "cCcbAbcb", + "AcCbcAAA", + 12 + ], + [ + "cCcbBCCBC", + "cC", + 14 + ], + [ + "cCcbCCB", + "BAbABC", + 12 + ], + [ + "cCcbCaaC", + "cbbcccbca", + 12 + ], + [ + "cCcbaCca", + "baBCABcC", + 13 + ], + [ + "cCcbaba", + "cCBBA", + 7 + ], + [ + "cCcc", + "a", + 8 + ], + [ + "cCccBaa", + "CBcBA", + 7 + ], + [ + "cCccCaCbA", + "caABbAcB", + 13 + ], + [ + "cCccaA", + "abb", + 12 + ], + [ + "cCccbA", + "BBabb", + 10 + ], + [ + "cCccbB", + "abAcB", + 8 + ], + [ + "cCcccAAb", + "aa", + 14 + ], + [ + "cCcccC", + "CBcBaAAc", + 12 + ], + [ + "cCcccCA", + "bcCACb", + 9 + ], + [ + "ca", + "AC", + 4 + ], + [ + "ca", + "ACA", + 4 + ], + [ + "ca", + "ACACb", + 8 + ], + [ + "ca", + "ACa", + 3 + ], + [ + "ca", + "Aaaa", + 6 + ], + [ + "ca", + "BAacabbab", + 14 + ], + [ + "ca", + "BB", + 4 + ], + [ + "ca", + "BBcaAbBcb", + 14 + ], + [ + "ca", + "BacCBC", + 10 + ], + [ + "ca", + "BbA", + 5 + ], + [ + "ca", + "BbBbBC", + 12 + ], + [ + "ca", + "BbCACC", + 10 + ], + [ + "ca", + "Bcbc", + 6 + ], + [ + "ca", + "BccA", + 5 + ], + [ + "ca", + "C", + 3 + ], + [ + "ca", + "CA", + 2 + ], + [ + "ca", + "CAC", + 4 + ], + [ + "ca", + "CCcbBaaab", + 14 + ], + [ + "ca", + "CbCaAaB", + 11 + ], + [ + "ca", + "a", + 2 + ], + [ + "ca", + "aBAA", + 7 + ], + [ + "ca", + "aC", + 4 + ], + [ + "ca", + "aaAbcACCc", + 15 + ], + [ + "ca", + "acccCcBc", + 14 + ], + [ + "ca", + "bAAaCCAc", + 14 + ], + [ + "ca", + "bBcAABbbB", + 15 + ], + [ + "ca", + "bbb", + 6 + ], + [ + "ca", + "cBC", + 4 + ], + [ + "ca", + "cCbba", + 6 + ], + [ + "ca", + "ccBBaba", + 10 + ], + [ + "caA", + "B", + 6 + ], + [ + "caA", + "CcCcAA", + 7 + ], + [ + "caA", + "aCAbCCCA", + 12 + ], + [ + "caA", + "aCcCbbAAC", + 13 + ], + [ + "caA", + "bBbac", + 8 + ], + [ + "caA", + "bCACCACC", + 12 + ], + [ + "caA", + "bbaA", + 4 + ], + [ + "caA", + "bbbBA", + 8 + ], + [ + "caA", + "cbAacAbbc", + 12 + ], + [ + "caAA", + "bAbaa", + 7 + ], + [ + "caAAAB", + "ab", + 9 + ], + [ + "caAAAcaA", + "CacaAcA", + 6 + ], + [ + "caAACbc", + "CBBCABbbb", + 13 + ], + [ + "caAB", + "A", + 6 + ], + [ + "caAB", + "BCAcbbB", + 10 + ], + [ + "caAB", + "CAaAab", + 6 + ], + [ + "caABabc", + "ACbbCCC", + 12 + ], + [ + "caABb", + "AaCaBC", + 7 + ], + [ + "caAC", + "CbCcB", + 8 + ], + [ + "caAC", + "bBBBCCBA", + 14 + ], + [ + "caACABAA", + "aa", + 13 + ], + [ + "caACBa", + "BbbBcAc", + 13 + ], + [ + "caACCBAaa", + "bbAcA", + 13 + ], + [ + "caACCac", + "a", + 12 + ], + [ + "caAa", + "abBcaB", + 10 + ], + [ + "caAa", + "acaCcBc", + 10 + ], + [ + "caAaBaBc", + "bcbCa", + 14 + ], + [ + "caAaa", + "ac", + 8 + ], + [ + "caAaaaaa", + "ccc", + 14 + ], + [ + "caAac", + "ACcACAbc", + 9 + ], + [ + "caAbAAcBb", + "c", + 16 + ], + [ + "caAbAcACB", + "CBCCaAaaB", + 13 + ], + [ + "caAbBBAbC", + "bacC", + 13 + ], + [ + "caAbBCb", + "bbaaaCc", + 11 + ], + [ + "caAbbBa", + "bAC", + 12 + ], + [ + "caAbbb", + "bbCACabaC", + 13 + ], + [ + "caAc", + "baCBB", + 8 + ], + [ + "caAcCc", + "ACc", + 6 + ], + [ + "caAcbbaCB", + "cbcBc", + 12 + ], + [ + "caAcc", + "BBbabc", + 9 + ], + [ + "caAcccaAb", + "Acab", + 10 + ], + [ + "caB", + "CbAcacAa", + 12 + ], + [ + "caB", + "ccBA", + 4 + ], + [ + "caBAA", + "aCbc", + 8 + ], + [ + "caBABbbC", + "CB", + 13 + ], + [ + "caBAabAcC", + "aCA", + 14 + ], + [ + "caBAbAAc", + "bcCBBa", + 12 + ], + [ + "caBAbaAb", + "ba", + 12 + ], + [ + "caBAcB", + "BaaaBA", + 9 + ], + [ + "caBBA", + "Bc", + 8 + ], + [ + "caBBA", + "CacB", + 5 + ], + [ + "caBBaBAB", + "acAbaa", + 11 + ], + [ + "caBBbaaA", + "bB", + 13 + ], + [ + "caBC", + "CBaaBaAa", + 11 + ], + [ + "caBCBaBC", + "aABaB", + 8 + ], + [ + "caBCac", + "b", + 11 + ], + [ + "caBCc", + "CBCabB", + 9 + ], + [ + "caBa", + "CaBabAC", + 7 + ], + [ + "caBa", + "CcbccA", + 9 + ], + [ + "caBaB", + "BcA", + 8 + ], + [ + "caBaCAb", + "AacCAA", + 8 + ], + [ + "caBaCc", + "cCCA", + 8 + ], + [ + "caBb", + "AaCbCAAa", + 12 + ], + [ + "caBb", + "BCBC", + 6 + ], + [ + "caBb", + "b", + 6 + ], + [ + "caBbCaa", + "caCCbb", + 8 + ], + [ + "caBbCbbBB", + "aBCBCabca", + 11 + ], + [ + "caBbCcBC", + "cccBaB", + 11 + ], + [ + "caBbac", + "bac", + 6 + ], + [ + "caBbbB", + "BcBBA", + 9 + ], + [ + "caBbbcBa", + "b", + 14 + ], + [ + "caBc", + "bA", + 7 + ], + [ + "caBc", + "bBA", + 6 + ], + [ + "caBc", + "cc", + 4 + ], + [ + "caBcAA", + "ccacac", + 7 + ], + [ + "caBcacCb", + "bBc", + 12 + ], + [ + "caC", + "BCbb", + 7 + ], + [ + "caC", + "BbBcA", + 9 + ], + [ + "caC", + "babCacB", + 10 + ], + [ + "caC", + "bb", + 6 + ], + [ + "caC", + "cCbAaa", + 8 + ], + [ + "caCAB", + "CBA", + 7 + ], + [ + "caCAC", + "AcaaCaacc", + 10 + ], + [ + "caCAb", + "BaC", + 6 + ], + [ + "caCAccca", + "bACc", + 11 + ], + [ + "caCBA", + "aBBBBcA", + 10 + ], + [ + "caCBC", + "BcBBabA", + 11 + ], + [ + "caCBC", + "ac", + 7 + ], + [ + "caCBba", + "cBA", + 7 + ], + [ + "caCBbaBB", + "a", + 14 + ], + [ + "caCBbc", + "A", + 11 + ], + [ + "caCC", + "CaBC", + 3 + ], + [ + "caCCAa", + "Baabb", + 10 + ], + [ + "caCCAcaa", + "aC", + 12 + ], + [ + "caCCC", + "bCBaAAbC", + 11 + ], + [ + "caCCaa", + "acabCacA", + 7 + ], + [ + "caCCbCc", + "aCBcC", + 7 + ], + [ + "caCCcc", + "cbaCAacc", + 6 + ], + [ + "caCaBB", + "ccbBaBA", + 8 + ], + [ + "caCaBbcAA", + "baCcAB", + 10 + ], + [ + "caCaCAaaC", + "ABB", + 16 + ], + [ + "caCabcBa", + "CAcCABcc", + 10 + ], + [ + "caCb", + "BcAcABAB", + 11 + ], + [ + "caCb", + "bAbBCb", + 7 + ], + [ + "caCbAAcb", + "aaBbAB", + 9 + ], + [ + "caCbCBBb", + "A", + 15 + ], + [ + "caCbbC", + "cCcc", + 7 + ], + [ + "caCbbcbC", + "CBAAbCC", + 10 + ], + [ + "caCbc", + "B", + 9 + ], + [ + "caCcCaaB", + "AacCbcca", + 11 + ], + [ + "caa", + "CCAcAcaab", + 12 + ], + [ + "caa", + "b", + 6 + ], + [ + "caa", + "bAB", + 5 + ], + [ + "caa", + "bacAa", + 5 + ], + [ + "caaA", + "BaCbcC", + 10 + ], + [ + "caaAABaac", + "AC", + 15 + ], + [ + "caaACA", + "cB", + 10 + ], + [ + "caaAa", + "CaBaAbcB", + 9 + ], + [ + "caaAa", + "bbC", + 10 + ], + [ + "caaAbbc", + "Aa", + 11 + ], + [ + "caaB", + "bAc", + 7 + ], + [ + "caaB", + "cB", + 4 + ], + [ + "caaBA", + "C", + 9 + ], + [ + "caaBAabC", + "BACB", + 11 + ], + [ + "caaBCC", + "Ab", + 10 + ], + [ + "caaBCc", + "CCb", + 9 + ], + [ + "caaCCAa", + "bCccbA", + 11 + ], + [ + "caaCaBcBb", + "aCabaa", + 11 + ], + [ + "caaCbaB", + "CCc", + 11 + ], + [ + "caaCc", + "b", + 10 + ], + [ + "caaCcc", + "cbA", + 9 + ], + [ + "caaa", + "AcCc", + 8 + ], + [ + "caaa", + "bCabaCaa", + 9 + ], + [ + "caaaCb", + "AabC", + 7 + ], + [ + "caaaaC", + "CaaBCCaC", + 7 + ], + [ + "caaab", + "BCC", + 10 + ], + [ + "caaac", + "AaBbACcBa", + 13 + ], + [ + "caab", + "C", + 7 + ], + [ + "caabACbb", + "bb", + 12 + ], + [ + "caabB", + "AbaCbac", + 10 + ], + [ + "caabaABA", + "cbacccaA", + 10 + ], + [ + "caabcbcBB", + "abaAAaC", + 14 + ], + [ + "caac", + "ABb", + 7 + ], + [ + "caacAABaB", + "CbBcbaB", + 10 + ], + [ + "caacaccC", + "BAaccaBA", + 11 + ], + [ + "caacbaAc", + "Abccbc", + 10 + ], + [ + "cab", + "CB", + 4 + ], + [ + "cab", + "a", + 4 + ], + [ + "cab", + "abCCb", + 7 + ], + [ + "cab", + "bAaaBBA", + 11 + ], + [ + "cab", + "bBbCABC", + 11 + ], + [ + "cabAA", + "c", + 8 + ], + [ + "cabACCCCb", + "b", + 16 + ], + [ + "cabACc", + "bBBAb", + 9 + ], + [ + "cabBAaaB", + "BbCCBaBc", + 12 + ], + [ + "cabBC", + "A", + 9 + ], + [ + "cabBCa", + "C", + 10 + ], + [ + "cabBCcBbA", + "BbCbAAaAb", + 16 + ], + [ + "cabBaA", + "cCa", + 8 + ], + [ + "cabC", + "BBCabBCa", + 9 + ], + [ + "cabC", + "BCBb", + 7 + ], + [ + "cabC", + "Baccb", + 7 + ], + [ + "cabCCAcC", + "cCcA", + 9 + ], + [ + "cabCCaBca", + "BCbBc", + 11 + ], + [ + "cabCaba", + "a", + 12 + ], + [ + "cabCb", + "cB", + 7 + ], + [ + "cabCcbB", + "BBbAcBaac", + 13 + ], + [ + "cabaBBb", + "AbC", + 11 + ], + [ + "cabaa", + "ccBCAbAB", + 10 + ], + [ + "cababBBaB", + "AcBCAC", + 14 + ], + [ + "cabac", + "BCa", + 8 + ], + [ + "cabb", + "CACcCcac", + 14 + ], + [ + "cabb", + "a", + 6 + ], + [ + "cabbBBA", + "CCab", + 11 + ], + [ + "cabbBc", + "aCccAAcc", + 12 + ], + [ + "cabbbACA", + "bcaCC", + 11 + ], + [ + "cabc", + "BCBcBca", + 10 + ], + [ + "cabc", + "CaaBBAABA", + 14 + ], + [ + "cabcBCc", + "BABAC", + 10 + ], + [ + "cabca", + "aAaC", + 8 + ], + [ + "cac", + "BBbaabba", + 14 + ], + [ + "cac", + "bb", + 6 + ], + [ + "cac", + "bcBa", + 6 + ], + [ + "cac", + "cBaaBa", + 8 + ], + [ + "cacABBaB", + "BaBAabBbA", + 11 + ], + [ + "cacAaA", + "bc", + 10 + ], + [ + "cacAaaaBb", + "Aba", + 14 + ], + [ + "cacAbbcCB", + "AcCcAaBC", + 11 + ], + [ + "cacAc", + "cAcaAB", + 5 + ], + [ + "cacB", + "BCcbAAcbB", + 11 + ], + [ + "cacB", + "c", + 6 + ], + [ + "cacBAA", + "BbbCCab", + 12 + ], + [ + "cacBAc", + "bbaBB", + 10 + ], + [ + "cacBaAa", + "aBBBCbbbA", + 15 + ], + [ + "cacBab", + "AC", + 10 + ], + [ + "cacCCaB", + "ABCc", + 10 + ], + [ + "caca", + "bCbbAa", + 9 + ], + [ + "cacaAbAAA", + "bc", + 16 + ], + [ + "cacaAcc", + "bc", + 12 + ], + [ + "cacaBc", + "BaabCbbB", + 12 + ], + [ + "cacaaBc", + "caAacCAAa", + 11 + ], + [ + "cacaabBCa", + "AACaccAc", + 13 + ], + [ + "cacacBAbC", + "C", + 16 + ], + [ + "cacaca", + "aB", + 10 + ], + [ + "cacbAAaCa", + "b", + 16 + ], + [ + "cacbB", + "AbBaCB", + 9 + ], + [ + "cacbCcbcB", + "cc", + 14 + ], + [ + "cacbc", + "BbAACAAC", + 13 + ], + [ + "cacc", + "CAccbBacC", + 11 + ], + [ + "caccA", + "ccc", + 4 + ], + [ + "caccbc", + "ab", + 8 + ], + [ + "cb", + "AAaBCAa", + 13 + ], + [ + "cb", + "AAaC", + 8 + ], + [ + "cb", + "ABAcbc", + 8 + ], + [ + "cb", + "ABccA", + 8 + ], + [ + "cb", + "ACABcb", + 8 + ], + [ + "cb", + "Aa", + 4 + ], + [ + "cb", + "AbBAaB", + 10 + ], + [ + "cb", + "BCcbbACB", + 12 + ], + [ + "cb", + "BabCaAAB", + 14 + ], + [ + "cb", + "BbBCACCBb", + 15 + ], + [ + "cb", + "C", + 3 + ], + [ + "cb", + "CAAbCCB", + 11 + ], + [ + "cb", + "CABBCa", + 10 + ], + [ + "cb", + "CCACAAB", + 12 + ], + [ + "cb", + "aBcA", + 6 + ], + [ + "cb", + "aCBAaabaa", + 15 + ], + [ + "cb", + "aCBaacAac", + 16 + ], + [ + "cb", + "aCC", + 5 + ], + [ + "cb", + "aaBcCC", + 10 + ], + [ + "cb", + "acBAC", + 7 + ], + [ + "cb", + "bCBcaCbA", + 12 + ], + [ + "cb", + "bcCCC", + 8 + ], + [ + "cb", + "cBCaBCC", + 11 + ], + [ + "cb", + "cCabBBabA", + 14 + ], + [ + "cb", + "cb", + 0 + ], + [ + "cb", + "cccCa", + 8 + ], + [ + "cbA", + "AaAaB", + 8 + ], + [ + "cbA", + "AcACCa", + 9 + ], + [ + "cbA", + "BbCBABAA", + 12 + ], + [ + "cbA", + "aBcCCAAca", + 14 + ], + [ + "cbA", + "aaab", + 7 + ], + [ + "cbAA", + "BAbBc", + 8 + ], + [ + "cbAAaBcc", + "cABABCbb", + 10 + ], + [ + "cbAAcB", + "a", + 11 + ], + [ + "cbAAcC", + "cacC", + 5 + ], + [ + "cbAB", + "CAABa", + 5 + ], + [ + "cbABBb", + "acBA", + 9 + ], + [ + "cbABc", + "cbcAaCb", + 7 + ], + [ + "cbAC", + "C", + 6 + ], + [ + "cbACAbc", + "aABCAbA", + 8 + ], + [ + "cbACcAC", + "bbcAcbB", + 10 + ], + [ + "cbACcBBC", + "cABbcbbaB", + 12 + ], + [ + "cbACcb", + "cabbaAC", + 10 + ], + [ + "cbAaB", + "babCC", + 9 + ], + [ + "cbAaBc", + "Acc", + 8 + ], + [ + "cbAaBcCA", + "C", + 14 + ], + [ + "cbAaCBbB", + "A", + 14 + ], + [ + "cbAabcC", + "BBBCAc", + 11 + ], + [ + "cbAbAaBbc", + "bC", + 15 + ], + [ + "cbAbBBAA", + "bcaBbAc", + 9 + ], + [ + "cbAbCBA", + "acABcaC", + 10 + ], + [ + "cbAbCBBB", + "AAaaa", + 14 + ], + [ + "cbAbCaA", + "cbAcBB", + 7 + ], + [ + "cbAbaCc", + "BACabcaa", + 11 + ], + [ + "cbAbcCA", + "ccC", + 8 + ], + [ + "cbAbcaB", + "cc", + 10 + ], + [ + "cbAbcbAbB", + "AccBbbcA", + 13 + ], + [ + "cbAbcbb", + "caCaAB", + 10 + ], + [ + "cbAc", + "BABcCB", + 9 + ], + [ + "cbAc", + "bacb", + 5 + ], + [ + "cbAcCBb", + "ABac", + 10 + ], + [ + "cbAcbcccB", + "CCC", + 15 + ], + [ + "cbB", + "Aaa", + 6 + ], + [ + "cbB", + "CbC", + 3 + ], + [ + "cbB", + "caCaB", + 6 + ], + [ + "cbBA", + "BcBBccBA", + 9 + ], + [ + "cbBA", + "aCcbB", + 6 + ], + [ + "cbBAAc", + "bcABA", + 8 + ], + [ + "cbBAB", + "AbcBc", + 8 + ], + [ + "cbBABc", + "Cbba", + 7 + ], + [ + "cbBACACa", + "aA", + 13 + ], + [ + "cbBACBccA", + "Ca", + 15 + ], + [ + "cbBAba", + "AcAca", + 8 + ], + [ + "cbBAbb", + "CbaaC", + 8 + ], + [ + "cbBB", + "cAb", + 5 + ], + [ + "cbBB", + "cAba", + 5 + ], + [ + "cbBBbB", + "BBBBcaA", + 9 + ], + [ + "cbBBbca", + "cACABCb", + 10 + ], + [ + "cbBBcACBb", + "AACbBbbb", + 13 + ], + [ + "cbBCCaA", + "AccCcBc", + 11 + ], + [ + "cbBCacA", + "cB", + 10 + ], + [ + "cbBCb", + "CAAbBA", + 9 + ], + [ + "cbBa", + "aaCC", + 8 + ], + [ + "cbBa", + "cBaB", + 4 + ], + [ + "cbBa", + "cccB", + 6 + ], + [ + "cbBaBcAc", + "Aab", + 13 + ], + [ + "cbBaCAC", + "CCcCCc", + 10 + ], + [ + "cbBac", + "c", + 8 + ], + [ + "cbBacA", + "bCaaaBaa", + 12 + ], + [ + "cbBb", + "AABA", + 6 + ], + [ + "cbBb", + "CCaa", + 7 + ], + [ + "cbBbAbB", + "cC", + 12 + ], + [ + "cbBbCACCC", + "Ccc", + 14 + ], + [ + "cbBba", + "ccb", + 6 + ], + [ + "cbBbbb", + "BccCbaAAB", + 13 + ], + [ + "cbBc", + "A", + 8 + ], + [ + "cbBcCAa", + "acab", + 11 + ], + [ + "cbBcCCbAA", + "caAbaCaBc", + 14 + ], + [ + "cbBcaCB", + "bA", + 11 + ], + [ + "cbBcbaccC", + "CaAACBAAA", + 16 + ], + [ + "cbBcbc", + "ABBBAAc", + 9 + ], + [ + "cbBcc", + "CACaBC", + 10 + ], + [ + "cbC", + "AcABa", + 7 + ], + [ + "cbC", + "bCCBBa", + 10 + ], + [ + "cbCAbaAa", + "ccBCaC", + 11 + ], + [ + "cbCB", + "AABCCaaA", + 13 + ], + [ + "cbCBABAAb", + "a", + 17 + ], + [ + "cbCBAcacb", + "CAa", + 12 + ], + [ + "cbCBC", + "cbcaCaaba", + 11 + ], + [ + "cbCBccbcc", + "BcCbA", + 11 + ], + [ + "cbCC", + "B", + 7 + ], + [ + "cbCCBBCB", + "baBaCbC", + 11 + ], + [ + "cbCCBccBb", + "BaAaC", + 16 + ], + [ + "cbCCC", + "AACACB", + 8 + ], + [ + "cbCCbABBB", + "CcaABC", + 11 + ], + [ + "cbCCbBac", + "CAaA", + 12 + ], + [ + "cbCa", + "CBA", + 5 + ], + [ + "cbCa", + "bbcacb", + 7 + ], + [ + "cbCaB", + "cbBaCb", + 5 + ], + [ + "cbCbAaCCa", + "ACAAb", + 13 + ], + [ + "cbCbaC", + "BACcBC", + 8 + ], + [ + "cbCbaCcaC", + "AaaaBC", + 14 + ], + [ + "cbCbb", + "A", + 10 + ], + [ + "cbCbbCAAc", + "caccc", + 12 + ], + [ + "cbCbcC", + "B", + 11 + ], + [ + "cbCcAAcA", + "AcaAaCcCa", + 13 + ], + [ + "cbCcCAc", + "babCC", + 9 + ], + [ + "cbCcCB", + "BCABA", + 9 + ], + [ + "cbCcCbA", + "cB", + 11 + ], + [ + "cbCcb", + "AacBB", + 8 + ], + [ + "cbCcbca", + "BCB", + 10 + ], + [ + "cbCccca", + "AAA", + 13 + ], + [ + "cba", + "A", + 5 + ], + [ + "cba", + "b", + 4 + ], + [ + "cba", + "bBCaaCc", + 11 + ], + [ + "cba", + "cAAbc", + 6 + ], + [ + "cba", + "caABABbab", + 12 + ], + [ + "cba", + "ccAB", + 5 + ], + [ + "cbaAa", + "cBbbcB", + 8 + ], + [ + "cbaAc", + "cAAc", + 3 + ], + [ + "cbaBACBAc", + "a", + 16 + ], + [ + "cbaBCAAC", + "BAAcCc", + 12 + ], + [ + "cbaBCbbcC", + "BcAaabac", + 12 + ], + [ + "cbaBbCa", + "BBACcA", + 10 + ], + [ + "cbaC", + "BBCaACabc", + 13 + ], + [ + "cbaC", + "aaA", + 6 + ], + [ + "cbaCABA", + "BbAaBccBC", + 11 + ], + [ + "cbaCCA", + "cbCABA", + 6 + ], + [ + "cbaCCCa", + "a", + 12 + ], + [ + "cbaCacac", + "AcBBbAA", + 13 + ], + [ + "cbaCcaA", + "C", + 12 + ], + [ + "cbaa", + "aaBcCBcBa", + 13 + ], + [ + "cbaaA", + "cBaa", + 3 + ], + [ + "cbaabCcC", + "bB", + 13 + ], + [ + "cbabAA", + "Bc", + 11 + ], + [ + "cbabBbc", + "AbcacAC", + 11 + ], + [ + "cbabC", + "CBbaAa", + 7 + ], + [ + "cbabbC", + "aCacAcBAC", + 13 + ], + [ + "cbac", + "cCbBcACa", + 10 + ], + [ + "cbacAAAA", + "BcAbcAbc", + 12 + ], + [ + "cbacAAacc", + "ab", + 16 + ], + [ + "cbacAC", + "BaaABAbC", + 10 + ], + [ + "cbacACa", + "AcBbcBaC", + 10 + ], + [ + "cbacB", + "CaBAa", + 9 + ], + [ + "cbacCCab", + "Acbc", + 12 + ], + [ + "cbacCabBB", + "CCcc", + 14 + ], + [ + "cbb", + "BBbB", + 5 + ], + [ + "cbb", + "CcAaAC", + 10 + ], + [ + "cbb", + "bBcABAcCC", + 15 + ], + [ + "cbb", + "cbccAbA", + 8 + ], + [ + "cbbABaCBa", + "Ca", + 14 + ], + [ + "cbbAa", + "aBBcAa", + 6 + ], + [ + "cbbAaC", + "cbc", + 7 + ], + [ + "cbbAbB", + "BABaBA", + 9 + ], + [ + "cbbAbaaB", + "CCababBa", + 10 + ], + [ + "cbbBAC", + "AacCcb", + 12 + ], + [ + "cbbBbA", + "AbCAACc", + 12 + ], + [ + "cbbBbb", + "b", + 10 + ], + [ + "cbbBbbbCA", + "bBB", + 13 + ], + [ + "cbbBcBbBb", + "BaABc", + 14 + ], + [ + "cbbBcC", + "C", + 10 + ], + [ + "cbbCAaB", + "A", + 12 + ], + [ + "cbbCbC", + "cBaCCABb", + 10 + ], + [ + "cbbCcbA", + "baCBaBab", + 12 + ], + [ + "cbbaCA", + "aCAbbbCcA", + 9 + ], + [ + "cbbaCb", + "ABaCaB", + 8 + ], + [ + "cbbaaC", + "BcAAbAba", + 11 + ], + [ + "cbbabc", + "BaAaacCAc", + 14 + ], + [ + "cbbacB", + "b", + 10 + ], + [ + "cbbb", + "CC", + 7 + ], + [ + "cbbb", + "bBcCaCAC", + 14 + ], + [ + "cbbbB", + "abacb", + 7 + ], + [ + "cbbbBBcb", + "cA", + 14 + ], + [ + "cbbbaBbC", + "CbAABAC", + 8 + ], + [ + "cbbbc", + "c", + 8 + ], + [ + "cbbc", + "aCBAcAc", + 10 + ], + [ + "cbbc", + "abBBCAB", + 10 + ], + [ + "cbbcBC", + "BAB", + 9 + ], + [ + "cbbcBcCCb", + "bc", + 14 + ], + [ + "cbc", + "AACAAbCCB", + 14 + ], + [ + "cbc", + "BcbaA", + 6 + ], + [ + "cbc", + "CbBbACB", + 10 + ], + [ + "cbc", + "b", + 4 + ], + [ + "cbc", + "cBCcBaC", + 9 + ], + [ + "cbcA", + "ABBAcC", + 9 + ], + [ + "cbcAA", + "c", + 8 + ], + [ + "cbcACAabb", + "bccBcbAaA", + 13 + ], + [ + "cbcAaAAb", + "BBccBbCA", + 13 + ], + [ + "cbcAb", + "CCCbbbcba", + 13 + ], + [ + "cbcB", + "Aba", + 6 + ], + [ + "cbcB", + "bCaaaAba", + 14 + ], + [ + "cbcBacB", + "acbB", + 9 + ], + [ + "cbcBbb", + "cBa", + 8 + ], + [ + "cbcBcc", + "bbCcA", + 7 + ], + [ + "cbcC", + "aABacCCC", + 11 + ], + [ + "cbcCA", + "bBAaba", + 10 + ], + [ + "cbcCBcbc", + "acBa", + 12 + ], + [ + "cbcCcBa", + "CbbACa", + 8 + ], + [ + "cbcaB", + "bCaAAc", + 9 + ], + [ + "cbcabBAac", + "bcBCbCBb", + 13 + ], + [ + "cbcb", + "bba", + 6 + ], + [ + "cbcbCCA", + "AaaCCabcc", + 15 + ], + [ + "cbcbaCBb", + "BccCAb", + 9 + ], + [ + "cbcbbC", + "BAaa", + 11 + ], + [ + "cbcbcaCC", + "BaBbbB", + 14 + ], + [ + "cbcccaCc", + "acAAAa", + 13 + ], + [ + "cc", + "AAAbBbC", + 13 + ], + [ + "cc", + "ABBaccbbB", + 14 + ], + [ + "cc", + "ABa", + 6 + ], + [ + "cc", + "ABaA", + 8 + ], + [ + "cc", + "BAbbAab", + 14 + ], + [ + "cc", + "BAbc", + 6 + ], + [ + "cc", + "BBacCb", + 9 + ], + [ + "cc", + "BCbaB", + 9 + ], + [ + "cc", + "BaBcBAAc", + 12 + ], + [ + "cc", + "BaC", + 5 + ], + [ + "cc", + "Bbca", + 6 + ], + [ + "cc", + "CAbbcb", + 9 + ], + [ + "cc", + "CCAcCb", + 9 + ], + [ + "cc", + "Ccb", + 3 + ], + [ + "cc", + "aAaBCaA", + 13 + ], + [ + "cc", + "aB", + 4 + ], + [ + "cc", + "aBA", + 6 + ], + [ + "cc", + "acCcCabA", + 12 + ], + [ + "cc", + "b", + 4 + ], + [ + "cc", + "bACABABA", + 15 + ], + [ + "cc", + "baCaAAAc", + 13 + ], + [ + "cc", + "bacAbacB", + 12 + ], + [ + "cc", + "bcbA", + 6 + ], + [ + "cc", + "cABcAA", + 8 + ], + [ + "cc", + "cACac", + 6 + ], + [ + "cc", + "cAbba", + 8 + ], + [ + "cc", + "cB", + 2 + ], + [ + "cc", + "cCac", + 4 + ], + [ + "cc", + "cCbbAcaA", + 12 + ], + [ + "cc", + "cb", + 2 + ], + [ + "cc", + "ccBc", + 4 + ], + [ + "cc", + "ccCab", + 6 + ], + [ + "ccA", + "AcCccAcc", + 10 + ], + [ + "ccA", + "CBAaC", + 7 + ], + [ + "ccA", + "b", + 6 + ], + [ + "ccAABB", + "ccCBBbC", + 7 + ], + [ + "ccAAb", + "BaABC", + 8 + ], + [ + "ccAAbaA", + "BaA", + 9 + ], + [ + "ccAAbbbaB", + "AABBCc", + 12 + ], + [ + "ccAB", + "BcA", + 4 + ], + [ + "ccABA", + "BcBBcbBA", + 8 + ], + [ + "ccABBAA", + "bCCac", + 12 + ], + [ + "ccABcAA", + "AABBaBaA", + 11 + ], + [ + "ccAC", + "CAACBCaCA", + 13 + ], + [ + "ccAC", + "bA", + 6 + ], + [ + "ccACAAcb", + "AbabCa", + 12 + ], + [ + "ccACABbAc", + "BCbAb", + 12 + ], + [ + "ccACB", + "CBbabcAC", + 11 + ], + [ + "ccACBAaBa", + "ca", + 14 + ], + [ + "ccACBca", + "Cb", + 11 + ], + [ + "ccACC", + "CcaAba", + 7 + ], + [ + "ccACC", + "aCc", + 6 + ], + [ + "ccACaABcb", + "CBBCCABCc", + 10 + ], + [ + "ccACaBbAC", + "cBaAaB", + 11 + ], + [ + "ccACcAAB", + "AbCbaCAbb", + 13 + ], + [ + "ccACcbb", + "abCcBCb", + 9 + ], + [ + "ccAa", + "bca", + 4 + ], + [ + "ccAa", + "c", + 6 + ], + [ + "ccAaACB", + "BCabaaA", + 11 + ], + [ + "ccAaAbccA", + "AAbAAb", + 12 + ], + [ + "ccAaC", + "bAaaACAB", + 11 + ], + [ + "ccAcAC", + "c", + 10 + ], + [ + "ccAcAb", + "AbABBCbBA", + 14 + ], + [ + "ccAcb", + "bcAb", + 4 + ], + [ + "ccAcccc", + "ccCca", + 7 + ], + [ + "ccB", + "B", + 4 + ], + [ + "ccB", + "CcBAB", + 5 + ], + [ + "ccB", + "aAa", + 6 + ], + [ + "ccB", + "b", + 5 + ], + [ + "ccB", + "cAaAbaa", + 11 + ], + [ + "ccB", + "cBbCACaAB", + 13 + ], + [ + "ccBA", + "B", + 6 + ], + [ + "ccBA", + "CAac", + 7 + ], + [ + "ccBACbca", + "Abb", + 12 + ], + [ + "ccBAc", + "baaaCaaB", + 14 + ], + [ + "ccBB", + "BcC", + 6 + ], + [ + "ccBBA", + "BbACCaA", + 11 + ], + [ + "ccBBbAa", + "b", + 12 + ], + [ + "ccBBbb", + "cBbBb", + 4 + ], + [ + "ccBBbcC", + "CAbacA", + 10 + ], + [ + "ccBC", + "AaBAA", + 8 + ], + [ + "ccBC", + "Baba", + 7 + ], + [ + "ccBC", + "b", + 7 + ], + [ + "ccBC", + "cbba", + 5 + ], + [ + "ccBCAaBc", + "bBCCCAA", + 12 + ], + [ + "ccBCAbC", + "abC", + 9 + ], + [ + "ccBCBBcac", + "BCabBA", + 12 + ], + [ + "ccBCC", + "AbbC", + 7 + ], + [ + "ccBCCCa", + "BaCaB", + 10 + ], + [ + "ccBCCaBcB", + "AcC", + 14 + ], + [ + "ccBCCc", + "aBb", + 10 + ], + [ + "ccBCbBcC", + "ca", + 14 + ], + [ + "ccBCcCaA", + "bcbBAcaBA", + 10 + ], + [ + "ccBa", + "ACCaABcCa", + 12 + ], + [ + "ccBaC", + "AC", + 7 + ], + [ + "ccBaaAa", + "Cc", + 11 + ], + [ + "ccBab", + "BACC", + 9 + ], + [ + "ccBabcaBA", + "CBbc", + 11 + ], + [ + "ccBacCAbB", + "cCCcA", + 11 + ], + [ + "ccBbAABB", + "ccb", + 10 + ], + [ + "ccBbAaB", + "Cc", + 11 + ], + [ + "ccBbaCAb", + "Bcc", + 13 + ], + [ + "ccBbab", + "cCbBc", + 7 + ], + [ + "ccBbbbcB", + "Aacaaa", + 16 + ], + [ + "ccBcb", + "bbcACCb", + 9 + ], + [ + "ccC", + "Ab", + 6 + ], + [ + "ccC", + "CBcCaAbAc", + 13 + ], + [ + "ccC", + "aaCB", + 6 + ], + [ + "ccC", + "bBBAA", + 10 + ], + [ + "ccCAA", + "aCC", + 7 + ], + [ + "ccCAcCB", + "baAAbBac", + 14 + ], + [ + "ccCBAa", + "AABbcA", + 10 + ], + [ + "ccCBCc", + "caBcB", + 7 + ], + [ + "ccCBbC", + "BbbA", + 9 + ], + [ + "ccCC", + "A", + 8 + ], + [ + "ccCC", + "CCaBcACBC", + 11 + ], + [ + "ccCC", + "aab", + 8 + ], + [ + "ccCCAaa", + "B", + 14 + ], + [ + "ccCCBAaaC", + "Bb", + 16 + ], + [ + "ccCCBbCaA", + "AcACCaB", + 10 + ], + [ + "ccCCCaaCb", + "BaAbBB", + 16 + ], + [ + "ccCCacA", + "ACAAa", + 10 + ], + [ + "ccCa", + "acbBa", + 6 + ], + [ + "ccCaa", + "aCBCa", + 7 + ], + [ + "ccCab", + "CCAb", + 4 + ], + [ + "ccCbBB", + "AAcabCa", + 10 + ], + [ + "ccCba", + "aacAbCBb", + 11 + ], + [ + "ccCbbCBA", + "AaCBcAb", + 12 + ], + [ + "ccCbc", + "aCbBCcb", + 10 + ], + [ + "ccCbcCcA", + "aAA", + 14 + ], + [ + "ccCbcaaAC", + "abB", + 16 + ], + [ + "ccCcAbCA", + "AB", + 13 + ], + [ + "ccCcAccA", + "CCABcCCbc", + 13 + ], + [ + "ccCcBaA", + "caC", + 10 + ], + [ + "ccCcBbc", + "aaacAca", + 12 + ], + [ + "ccCcBcC", + "CBCCCBAA", + 9 + ], + [ + "ccCcabcb", + "baAb", + 12 + ], + [ + "ccCccbABc", + "b", + 16 + ], + [ + "cca", + "ABc", + 6 + ], + [ + "cca", + "aa", + 4 + ], + [ + "cca", + "bACA", + 6 + ], + [ + "ccaA", + "AcBa", + 5 + ], + [ + "ccaA", + "Ca", + 5 + ], + [ + "ccaABaccb", + "AAaaCBb", + 10 + ], + [ + "ccaACAC", + "BAc", + 11 + ], + [ + "ccaAba", + "Ccb", + 7 + ], + [ + "ccaAc", + "B", + 10 + ], + [ + "ccaAcCB", + "ccBB", + 8 + ], + [ + "ccaB", + "BbcB", + 6 + ], + [ + "ccaBC", + "CbbbB", + 8 + ], + [ + "ccaCA", + "ABBbb", + 10 + ], + [ + "ccaCAB", + "cCbcb", + 7 + ], + [ + "ccaCAcAB", + "acbb", + 11 + ], + [ + "ccaCAcBb", + "ccCbb", + 7 + ], + [ + "ccaCCCcCC", + "AACAc", + 13 + ], + [ + "ccaCaABb", + "bA", + 14 + ], + [ + "ccaCc", + "babb", + 8 + ], + [ + "ccaCcAAaB", + "BcAAaB", + 8 + ], + [ + "ccaCcB", + "B", + 10 + ], + [ + "ccaaBCB", + "AAA", + 12 + ], + [ + "ccaaaa", + "Aa", + 9 + ], + [ + "ccaab", + "acbbC", + 8 + ], + [ + "ccaac", + "BCBBb", + 9 + ], + [ + "ccab", + "C", + 7 + ], + [ + "ccab", + "aabBBcABa", + 14 + ], + [ + "ccabaB", + "CACba", + 7 + ], + [ + "ccabaCa", + "ccAac", + 6 + ], + [ + "ccababcA", + "abc", + 10 + ], + [ + "ccacAbBBB", + "Cb", + 15 + ], + [ + "ccacb", + "cbCA", + 7 + ], + [ + "ccb", + "A", + 6 + ], + [ + "ccb", + "Aa", + 6 + ], + [ + "ccb", + "Aca", + 4 + ], + [ + "ccb", + "acBAcb", + 6 + ], + [ + "ccb", + "acBccbAcA", + 12 + ], + [ + "ccbA", + "ba", + 5 + ], + [ + "ccbAAA", + "BAaca", + 9 + ], + [ + "ccbAACAc", + "CaaCBcBAa", + 14 + ], + [ + "ccbABAA", + "BBaccbb", + 13 + ], + [ + "ccbACa", + "cabACc", + 4 + ], + [ + "ccbAaCA", + "cCccaCCA", + 7 + ], + [ + "ccbAb", + "bbbCaACa", + 12 + ], + [ + "ccbAbA", + "cbcaBb", + 8 + ], + [ + "ccbAbBB", + "cBcbA", + 8 + ], + [ + "ccbAcC", + "AbBCcaacB", + 12 + ], + [ + "ccbBbcb", + "bCbCAC", + 10 + ], + [ + "ccbC", + "ACccBAc", + 8 + ], + [ + "ccbC", + "CB", + 6 + ], + [ + "ccbC", + "aCAA", + 7 + ], + [ + "ccbCC", + "AcCcCcb", + 8 + ], + [ + "ccbCa", + "bcBBcb", + 8 + ], + [ + "ccbCaACca", + "BBcaA", + 12 + ], + [ + "ccbCbbB", + "b", + 12 + ], + [ + "ccba", + "CAbbBc", + 9 + ], + [ + "ccba", + "Caa", + 5 + ], + [ + "ccba", + "bA", + 5 + ], + [ + "ccba", + "cbc", + 4 + ], + [ + "ccbabbC", + "AB", + 12 + ], + [ + "ccbbBbAb", + "CBc", + 13 + ], + [ + "ccbbabB", + "bCcaCa", + 11 + ], + [ + "ccbbcB", + "ACbcaaA", + 11 + ], + [ + "ccbbccCAC", + "CcccBcBC", + 10 + ], + [ + "ccbcABBCb", + "aAcAacC", + 12 + ], + [ + "ccbcAbBbc", + "a", + 17 + ], + [ + "ccbcB", + "CBaCAAcBc", + 12 + ], + [ + "ccbcBBAbB", + "cBccCc", + 13 + ], + [ + "ccbcCaab", + "cCaAAB", + 10 + ], + [ + "ccbcCbcB", + "CCCa", + 12 + ], + [ + "ccbcba", + "CA", + 10 + ], + [ + "ccc", + "AcBcbBcb", + 10 + ], + [ + "ccc", + "BbcCbB", + 9 + ], + [ + "ccc", + "CACABCbb", + 13 + ], + [ + "ccc", + "ac", + 4 + ], + [ + "ccc", + "baAABCbcc", + 13 + ], + [ + "ccc", + "c", + 4 + ], + [ + "ccc", + "cabACBAbB", + 15 + ], + [ + "cccA", + "cbBAbbB", + 10 + ], + [ + "cccAAA", + "AcB", + 10 + ], + [ + "cccAABCcA", + "ba", + 16 + ], + [ + "cccAC", + "ABCaa", + 8 + ], + [ + "cccAaccc", + "bcCC", + 12 + ], + [ + "cccAbC", + "cBbCAb", + 7 + ], + [ + "cccB", + "bACBcb", + 8 + ], + [ + "cccB", + "c", + 6 + ], + [ + "cccBAA", + "cbB", + 8 + ], + [ + "cccBAbb", + "bCCacb", + 9 + ], + [ + "cccBBAC", + "bbbcB", + 12 + ], + [ + "cccBBCc", + "CAaaAb", + 13 + ], + [ + "cccC", + "ACbB", + 7 + ], + [ + "cccC", + "bbbA", + 8 + ], + [ + "cccCabBA", + "AaBc", + 12 + ], + [ + "cccCbbcc", + "CcC", + 11 + ], + [ + "cccCccaC", + "b", + 16 + ], + [ + "ccca", + "cCcCAa", + 5 + ], + [ + "cccaAb", + "Abb", + 9 + ], + [ + "cccaCbA", + "cBcCBBbaA", + 9 + ], + [ + "cccaaa", + "BaABcbcca", + 14 + ], + [ + "cccacB", + "abBB", + 10 + ], + [ + "cccb", + "AABc", + 8 + ], + [ + "cccb", + "CbBAAbA", + 11 + ], + [ + "cccbABcc", + "a", + 15 + ], + [ + "cccbB", + "bcCAcaaba", + 11 + ], + [ + "cccbaBC", + "cbACAac", + 10 + ], + [ + "cccbabBb", + "ACc", + 13 + ], + [ + "cccbbA", + "bbcAc", + 10 + ], + [ + "cccbcaCC", + "AbCACBcCb", + 13 + ], + [ + "cccbcaaaC", + "baCcCc", + 14 + ], + [ + "ccccBa", + "abcbaaCbA", + 13 + ], + [ + "ccccCBcCA", + "Cbbab", + 15 + ], + [ + "ccccCCc", + "aabB", + 14 + ], + [ + "ccccaCA", + "Cb", + 12 + ], + [ + "cccccb", + "a", + 12 + ], + [ + "ccccccAcc", + "AB", + 16 + ] +] \ No newline at end of file diff --git a/Lib/test/libregrtest/cmdline.py b/Lib/test/libregrtest/cmdline.py index 11fa0f940bb..ebe57920d91 100644 --- a/Lib/test/libregrtest/cmdline.py +++ b/Lib/test/libregrtest/cmdline.py @@ -1,5 +1,6 @@ import argparse import os +import shlex import sys from test.support import os_helper @@ -206,6 +207,8 @@ def _create_parser(): group.add_argument('-S', '--start', metavar='START', help='the name of the test at which to start.' + more_details) + group.add_argument('-p', '--python', metavar='PYTHON', + help='Command to run Python test subprocesses with.') group = parser.add_argument_group('Verbosity') group.add_argument('-v', '--verbose', action='count', @@ -370,6 +373,11 @@ def _parse_args(args, **kwargs): parser.error("-s and -f don't go together!") if ns.use_mp is not None and ns.trace: parser.error("-T and -j don't go together!") + if ns.python is not None: + if ns.use_mp is None: + parser.error("-p requires -j!") + # The "executable" may be two or more parts, e.g. "node python.js" + ns.python = shlex.split(ns.python) if ns.failfast and not (ns.verbose or ns.verbose3): parser.error("-G/--failfast needs either -v or -W") if ns.pgo and (ns.verbose or ns.verbose2 or ns.verbose3): diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index fc3c2b96920..19ccf2db5e7 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -17,9 +17,11 @@ from test.libregrtest.runtest import ( ChildError, DidNotRun) from test.libregrtest.setup import setup_tests from test.libregrtest.pgo import setup_pgo_tests -from test.libregrtest.utils import removepy, count, format_duration, printlist +from test.libregrtest.utils import (removepy, count, format_duration, + printlist, get_build_info) from test import support from test.support import os_helper +from test.support import threading_helper # bpo-38203: Maximum delay in seconds to exit Python (call Py_Finalize()). @@ -27,6 +29,11 @@ from test.support import os_helper # Must be smaller than buildbot "1200 seconds without output" limit. EXIT_TIMEOUT = 120.0 +EXITCODE_BAD_TEST = 2 +EXITCODE_INTERRUPTED = 130 +EXITCODE_ENV_CHANGED = 3 +EXITCODE_NO_TESTS_RAN = 4 + class Regrtest: """Execute a test suite. @@ -305,13 +312,22 @@ class Regrtest: printlist(self.skipped, file=sys.stderr) def rerun_failed_tests(self): + self.log() + + if self.ns.python: + # Temp patch for https://github.com/python/cpython/issues/94052 + self.log( + "Re-running failed tests is not supported with --python " + "host runner option." + ) + return + self.ns.verbose = True self.ns.failfast = False self.ns.verbose3 = False self.first_result = self.get_tests_result() - self.log() self.log("Re-running failed tests in verbose mode") rerun_list = list(self.need_rerun) self.need_rerun.clear() @@ -476,13 +492,17 @@ class Regrtest: print("==", platform.python_implementation(), *sys.version.split()) print("==", platform.platform(aliased=True), "%s-endian" % sys.byteorder) + print("== Python build:", ' '.join(get_build_info())) print("== cwd:", os.getcwd()) cpu_count = os.cpu_count() if cpu_count: print("== CPU count:", cpu_count) print("== encodings: locale=%s, FS=%s" - % (locale.getpreferredencoding(False), - sys.getfilesystemencoding())) + % (locale.getencoding(), sys.getfilesystemencoding())) + + def no_tests_run(self): + return not any((self.good, self.bad, self.skipped, self.interrupted, + self.environment_changed)) def get_tests_result(self): result = [] @@ -490,9 +510,8 @@ class Regrtest: result.append("FAILURE") elif self.ns.fail_env_changed and self.environment_changed: result.append("ENV CHANGED") - elif not any((self.good, self.bad, self.skipped, self.interrupted, - self.environment_changed)): - result.append("NO TEST RUN") + elif self.no_tests_run(): + result.append("NO TESTS RAN") if self.interrupted: result.append("INTERRUPTED") @@ -533,7 +552,24 @@ class Regrtest: if self.ns.use_mp: from test.libregrtest.runtest_mp import run_tests_multiprocess - run_tests_multiprocess(self) + # If we're on windows and this is the parent runner (not a worker), + # track the load average. + if sys.platform == 'win32' and self.worker_test_name is None: + from test.libregrtest.win_utils import WindowsLoadTracker + + try: + self.win_load_tracker = WindowsLoadTracker() + except PermissionError as error: + # Standard accounts may not have access to the performance + # counters. + print(f'Failed to create WindowsLoadTracker: {error}') + + try: + run_tests_multiprocess(self) + finally: + if self.win_load_tracker is not None: + self.win_load_tracker.close() + self.win_load_tracker = None else: self.run_tests_sequential() @@ -583,6 +619,16 @@ class Regrtest: for s in ET.tostringlist(root): f.write(s) + def fix_umask(self): + if support.is_emscripten: + # Emscripten has default umask 0o777, which breaks some tests. + # see https://github.com/emscripten-core/emscripten/issues/17269 + old_mask = os.umask(0) + if old_mask == 0o777: + os.umask(0o027) + else: + os.umask(old_mask) + def set_temp_dir(self): if self.ns.tempdir: self.tmp_dir = self.ns.tempdir @@ -611,11 +657,16 @@ class Regrtest: # Define a writable temp dir that will be used as cwd while running # the tests. The name of the dir includes the pid to allow parallel # testing (see the -j option). - pid = os.getpid() - if self.worker_test_name is not None: - test_cwd = 'test_python_worker_{}'.format(pid) + # Emscripten and WASI have stubbed getpid(), Emscripten has only + # milisecond clock resolution. Use randint() instead. + if sys.platform in {"emscripten", "wasi"}: + nounce = random.randint(0, 1_000_000) else: - test_cwd = 'test_python_{}'.format(pid) + nounce = os.getpid() + if self.worker_test_name is not None: + test_cwd = 'test_python_worker_{}'.format(nounce) + else: + test_cwd = 'test_python_{}'.format(nounce) test_cwd += os_helper.FS_NONASCII test_cwd = os.path.join(self.tmp_dir, test_cwd) return test_cwd @@ -638,6 +689,8 @@ class Regrtest: self.set_temp_dir() + self.fix_umask() + if self.ns.cleanup: self.cleanup() sys.exit(0) @@ -659,7 +712,8 @@ class Regrtest: except SystemExit as exc: # bpo-38203: Python can hang at exit in Py_Finalize(), especially # on threading._shutdown() call: put a timeout - faulthandler.dump_traceback_later(EXIT_TIMEOUT, exit=True) + if threading_helper.can_start_thread: + faulthandler.dump_traceback_later(EXIT_TIMEOUT, exit=True) sys.exit(exc.code) @@ -695,39 +749,24 @@ class Regrtest: self.list_cases() sys.exit(0) - # If we're on windows and this is the parent runner (not a worker), - # track the load average. - if sys.platform == 'win32' and self.worker_test_name is None: - from test.libregrtest.win_utils import WindowsLoadTracker + self.run_tests() + self.display_result() - try: - self.win_load_tracker = WindowsLoadTracker() - except FileNotFoundError as error: - # Windows IoT Core and Windows Nano Server do not provide - # typeperf.exe for x64, x86 or ARM - print(f'Failed to create WindowsLoadTracker: {error}') - - try: - self.run_tests() - self.display_result() - - if self.ns.verbose2 and self.bad: - self.rerun_failed_tests() - finally: - if self.win_load_tracker is not None: - self.win_load_tracker.close() - self.win_load_tracker = None + if self.ns.verbose2 and self.bad: + self.rerun_failed_tests() self.finalize() self.save_xml_result() if self.bad: - sys.exit(2) + sys.exit(EXITCODE_BAD_TEST) if self.interrupted: - sys.exit(130) + sys.exit(EXITCODE_INTERRUPTED) if self.ns.fail_env_changed and self.environment_changed: - sys.exit(3) + sys.exit(EXITCODE_ENV_CHANGED) + if self.no_tests_run(): + sys.exit(EXITCODE_NO_TESTS_RAN) sys.exit(0) diff --git a/Lib/test/libregrtest/refleak.py b/Lib/test/libregrtest/refleak.py index 1069e2da008..4298fa806e1 100644 --- a/Lib/test/libregrtest/refleak.py +++ b/Lib/test/libregrtest/refleak.py @@ -73,7 +73,6 @@ def dash_R(ns, test_name, test_func): fd_deltas = [0] * repcount getallocatedblocks = sys.getallocatedblocks gettotalrefcount = sys.gettotalrefcount - _getquickenedcount = sys._getquickenedcount fd_count = os_helper.fd_count # initialize variables to make pyflakes quiet rc_before = alloc_before = fd_before = 0 @@ -93,7 +92,7 @@ def dash_R(ns, test_name, test_func): support.gc_collect() # Read memory statistics immediately after the garbage collection - alloc_after = getallocatedblocks() - _getquickenedcount() + alloc_after = getallocatedblocks() rc_after = gettotalrefcount() fd_after = fd_count() @@ -142,7 +141,7 @@ def dash_R(ns, test_name, test_func): msg = '%s leaked %s %s, sum=%s' % ( test_name, deltas, item_name, sum(deltas)) print(msg, file=sys.stderr, flush=True) - with open(fname, "a") as refrep: + with open(fname, "a", encoding="utf-8") as refrep: print(msg, file=refrep) refrep.flush() failed = True diff --git a/Lib/test/libregrtest/runtest.py b/Lib/test/libregrtest/runtest.py index 83c5f249841..e9bb72a7d77 100644 --- a/Lib/test/libregrtest/runtest.py +++ b/Lib/test/libregrtest/runtest.py @@ -11,6 +11,7 @@ import unittest from test import support from test.support import os_helper +from test.support import threading_helper from test.libregrtest.cmdline import Namespace from test.libregrtest.save_env import saved_test_environment from test.libregrtest.utils import clear_caches, format_duration, print_warning @@ -79,6 +80,11 @@ class EnvChanged(Failed): def __str__(self) -> str: return f"{self.name} failed (env changed)" + # Convert Passed to EnvChanged + @staticmethod + def from_passed(other): + return EnvChanged(other.name, other.duration_sec, other.xml_data) + class RefLeak(Failed): def __str__(self) -> str: @@ -179,7 +185,9 @@ def _runtest(ns: Namespace, test_name: str) -> TestResult: output_on_failure = ns.verbose3 - use_timeout = (ns.timeout is not None) + use_timeout = ( + ns.timeout is not None and threading_helper.can_start_thread + ) if use_timeout: faulthandler.dump_traceback_later(ns.timeout, exit=True) diff --git a/Lib/test/libregrtest/runtest_mp.py b/Lib/test/libregrtest/runtest_mp.py index f02f56e98bc..a12fcb46e0f 100644 --- a/Lib/test/libregrtest/runtest_mp.py +++ b/Lib/test/libregrtest/runtest_mp.py @@ -1,14 +1,15 @@ import faulthandler import json -import os +import os.path import queue import signal import subprocess import sys +import tempfile import threading import time import traceback -from typing import NamedTuple, NoReturn, Literal, Any +from typing import NamedTuple, NoReturn, Literal, Any, TextIO from test import support from test.support import os_helper @@ -16,10 +17,14 @@ from test.support import os_helper from test.libregrtest.cmdline import Namespace from test.libregrtest.main import Regrtest from test.libregrtest.runtest import ( - runtest, is_failed, TestResult, Interrupted, Timeout, ChildError, PROGRESS_MIN_TIME) + runtest, is_failed, TestResult, Interrupted, Timeout, ChildError, + PROGRESS_MIN_TIME, Passed, EnvChanged) from test.libregrtest.setup import setup_tests from test.libregrtest.utils import format_duration, print_warning +if sys.platform == 'win32': + import locale + # Display the running tests if nothing happened last N seconds PROGRESS_UPDATE = 30.0 # seconds @@ -51,31 +56,40 @@ def parse_worker_args(worker_args) -> tuple[Namespace, str]: return (ns, test_name) -def run_test_in_subprocess(testname: str, ns: Namespace) -> subprocess.Popen: +def run_test_in_subprocess(testname: str, ns: Namespace, tmp_dir: str, stdout_fh: TextIO) -> subprocess.Popen: ns_dict = vars(ns) worker_args = (ns_dict, testname) worker_args = json.dumps(worker_args) - - cmd = [sys.executable, *support.args_from_interpreter_flags(), + if ns.python is not None: + executable = ns.python + else: + executable = [sys.executable] + cmd = [*executable, *support.args_from_interpreter_flags(), '-u', # Unbuffered stdout and stderr '-m', 'test.regrtest', '--worker-args', worker_args] + env = dict(os.environ) + if tmp_dir is not None: + env['TMPDIR'] = tmp_dir + env['TEMP'] = tmp_dir + env['TMP'] = tmp_dir + # Running the child from the same working directory as regrtest's original # invocation ensures that TEMPDIR for the child is the same when # sysconfig.is_python_build() is true. See issue 15300. - kw = {} + kw = dict( + env=env, + stdout=stdout_fh, + # bpo-45410: Write stderr into stdout to keep messages order + stderr=stdout_fh, + text=True, + close_fds=(os.name != 'nt'), + cwd=os_helper.SAVEDCWD, + ) if USE_PROCESS_GROUP: kw['start_new_session'] = True - return subprocess.Popen(cmd, - stdout=subprocess.PIPE, - # bpo-45410: Write stderr into stdout to keep - # messages order - stderr=subprocess.STDOUT, - universal_newlines=True, - close_fds=(os.name != 'nt'), - cwd=os_helper.SAVEDCWD, - **kw) + return subprocess.Popen(cmd, **kw) def run_tests_worker(ns: Namespace, test_name: str) -> NoReturn: @@ -201,12 +215,12 @@ class TestWorkerProcess(threading.Thread): test_result.duration_sec = time.monotonic() - self.start_time return MultiprocessResult(test_result, stdout, err_msg) - def _run_process(self, test_name: str) -> tuple[int, str, str]: + def _run_process(self, test_name: str, tmp_dir: str, stdout_fh: TextIO) -> int: self.start_time = time.monotonic() self.current_test_name = test_name try: - popen = run_test_in_subprocess(test_name, self.ns) + popen = run_test_in_subprocess(test_name, self.ns, tmp_dir, stdout_fh) self._killed = False self._popen = popen @@ -223,10 +237,10 @@ class TestWorkerProcess(threading.Thread): raise ExitThread try: - # bpo-45410: stderr is written into stdout - stdout, _ = popen.communicate(timeout=self.timeout) - retcode = popen.returncode + # gh-94026: stdout+stderr are written to tempfile + retcode = popen.wait(timeout=self.timeout) assert retcode is not None + return retcode except subprocess.TimeoutExpired: if self._stopped: # kill() has been called: communicate() fails on reading @@ -241,17 +255,12 @@ class TestWorkerProcess(threading.Thread): # bpo-38207: Don't attempt to call communicate() again: on it # can hang until all child processes using stdout # pipes completes. - stdout = '' except OSError: if self._stopped: # kill() has been called: communicate() fails # on reading closed stdout raise ExitThread raise - else: - stdout = stdout.strip() - - return (retcode, stdout) except: self._kill() raise @@ -261,7 +270,35 @@ class TestWorkerProcess(threading.Thread): self.current_test_name = None def _runtest(self, test_name: str) -> MultiprocessResult: - retcode, stdout = self._run_process(test_name) + if sys.platform == 'win32': + # gh-95027: When stdout is not a TTY, Python uses the ANSI code + # page for the sys.stdout encoding. If the main process runs in a + # terminal, sys.stdout uses WindowsConsoleIO with UTF-8 encoding. + encoding = locale.getencoding() + else: + encoding = sys.stdout.encoding + # gh-94026: Write stdout+stderr to a tempfile as workaround for + # non-blocking pipes on Emscripten with NodeJS. + with tempfile.TemporaryFile('w+', encoding=encoding) as stdout_fh: + # gh-93353: Check for leaked temporary files in the parent process, + # since the deletion of temporary files can happen late during + # Python finalization: too late for libregrtest. + if not support.is_wasi: + # Don't check for leaked temporary files and directories if Python is + # run on WASI. WASI don't pass environment variables like TMPDIR to + # worker processes. + tmp_dir = tempfile.mkdtemp(prefix="test_python_") + tmp_dir = os.path.abspath(tmp_dir) + try: + retcode = self._run_process(test_name, tmp_dir, stdout_fh) + finally: + tmp_files = os.listdir(tmp_dir) + os_helper.rmtree(tmp_dir) + else: + retcode = self._run_process(test_name, None, stdout_fh) + tmp_files = () + stdout_fh.seek(0) + stdout = stdout_fh.read().strip() if retcode is None: return self.mp_result_error(Timeout(test_name), stdout) @@ -284,6 +321,14 @@ class TestWorkerProcess(threading.Thread): if err_msg is not None: return self.mp_result_error(ChildError(test_name), stdout, err_msg) + if tmp_files: + msg = (f'\n\n' + f'Warning -- {test_name} leaked temporary files ' + f'({len(tmp_files)}): {", ".join(sorted(tmp_files))}') + stdout += msg + if isinstance(result, Passed): + result = EnvChanged.from_passed(result) + return MultiprocessResult(result, stdout, err_msg) def run(self) -> None: @@ -308,9 +353,6 @@ class TestWorkerProcess(threading.Thread): def _wait_completed(self) -> None: popen = self._popen - # stdout must be closed to ensure that communicate() does not hang - popen.stdout.close() - try: popen.wait(JOIN_TIMEOUT) except (subprocess.TimeoutExpired, OSError) as exc: @@ -392,16 +434,12 @@ class MultiprocessTestRunner: worker.wait_stopped(start_time) def _get_result(self) -> QueueOutput | None: - if not any(worker.is_alive() for worker in self.workers): - # all worker threads are done: consume pending results - try: - return self.output.get(timeout=0) - except queue.Empty: - return None - use_faulthandler = (self.ns.timeout is not None) timeout = PROGRESS_UPDATE - while True: + + # bpo-46205: check the status of workers every iteration to avoid + # waiting forever on an empty queue. + while any(worker.is_alive() for worker in self.workers): if use_faulthandler: faulthandler.dump_traceback_later(MAIN_PROCESS_TIMEOUT, exit=True) @@ -417,6 +455,12 @@ class MultiprocessTestRunner: if running and not self.ns.pgo: self.log('running: %s' % ', '.join(running)) + # all worker threads are done: consume pending results + try: + return self.output.get(timeout=0) + except queue.Empty: + return None + def display_result(self, mp_result: MultiprocessResult) -> None: result = mp_result.result diff --git a/Lib/test/libregrtest/save_env.py b/Lib/test/libregrtest/save_env.py index 17dda99b645..cc5870ab2b8 100644 --- a/Lib/test/libregrtest/save_env.py +++ b/Lib/test/libregrtest/save_env.py @@ -52,7 +52,7 @@ class saved_test_environment: resources = ('sys.argv', 'cwd', 'sys.stdin', 'sys.stdout', 'sys.stderr', 'os.environ', 'sys.path', 'sys.path_hooks', '__import__', - 'warnings.filters', + 'warnings.filters', 'asyncore.socket_map', 'logging._handlers', 'logging._handlerList', 'sys.gettrace', 'sys.warnoptions', # multiprocessing.process._cleanup() may release ref @@ -160,6 +160,16 @@ class saved_test_environment: warnings.filters = saved_filters[1] warnings.filters[:] = saved_filters[2] + def get_asyncore_socket_map(self): + asyncore = sys.modules.get('test.support.asyncore') + # XXX Making a copy keeps objects alive until __exit__ gets called. + return asyncore and asyncore.socket_map.copy() or {} + def restore_asyncore_socket_map(self, saved_map): + asyncore = sys.modules.get('test.support.asyncore') + if asyncore is not None: + asyncore.close_all(ignore_all=True) + asyncore.socket_map.update(saved_map) + def get_shutil_archive_formats(self): shutil = self.try_get_module('shutil') # we could call get_archives_formats() but that only returns the diff --git a/Lib/test/libregrtest/setup.py b/Lib/test/libregrtest/setup.py index 4ffd15478f6..b76bece7ca0 100644 --- a/Lib/test/libregrtest/setup.py +++ b/Lib/test/libregrtest/setup.py @@ -5,6 +5,7 @@ import signal import sys import unittest from test import support +from test.support.os_helper import TESTFN_UNDECODABLE, FS_NONASCII try: import gc except ImportError: @@ -104,10 +105,10 @@ def setup_tests(ns): # Ensure there's a non-ASCII character in env vars at all times to force # tests consider this case. See BPO-44647 for details. - os.environ.setdefault( - UNICODE_GUARD_ENV, - "\N{SMILING FACE WITH SUNGLASSES}", - ) + if TESTFN_UNDECODABLE and os.supports_bytes_environ: + os.environb.setdefault(UNICODE_GUARD_ENV.encode(), TESTFN_UNDECODABLE) + elif FS_NONASCII: + os.environ.setdefault(UNICODE_GUARD_ENV, FS_NONASCII) def replace_stdout(): @@ -140,7 +141,7 @@ def _adjust_resource_limits(): """Adjust the system resource limits (ulimit) if needed.""" try: import resource - from resource import RLIMIT_NOFILE, RLIM_INFINITY + from resource import RLIMIT_NOFILE except ImportError: return fd_limit, max_fds = resource.getrlimit(RLIMIT_NOFILE) @@ -156,4 +157,3 @@ def _adjust_resource_limits(): except (ValueError, OSError) as err: print(f"Unable to raise RLIMIT_NOFILE from {fd_limit} to " f"{new_fd_limit}: {err}.") - diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py index 8578a028c78..fb13fa0e243 100644 --- a/Lib/test/libregrtest/utils.py +++ b/Lib/test/libregrtest/utils.py @@ -1,6 +1,7 @@ import math import os.path import sys +import sysconfig import textwrap from test import support @@ -124,15 +125,6 @@ def clear_caches(): if stream is not None: stream.flush() - # Clear assorted module caches. - # Don't worry about resetting the cache if the module is not loaded - try: - distutils_dir_util = sys.modules['distutils.dir_util'] - except KeyError: - pass - else: - distutils_dir_util._path_created.clear() - try: re = sys.modules['re'] except KeyError: @@ -210,3 +202,94 @@ def clear_caches(): else: for f in typing._cleanups: f() + + try: + fractions = sys.modules['fractions'] + except KeyError: + pass + else: + fractions._hash_algorithm.cache_clear() + + +def get_build_info(): + # Get most important configure and build options as a list of strings. + # Example: ['debug', 'ASAN+MSAN'] or ['release', 'LTO+PGO']. + + config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' + cflags = sysconfig.get_config_var('PY_CFLAGS') or '' + cflags_nodist = sysconfig.get_config_var('PY_CFLAGS_NODIST') or '' + ldflags_nodist = sysconfig.get_config_var('PY_LDFLAGS_NODIST') or '' + + build = [] + if hasattr(sys, 'gettotalrefcount'): + # --with-pydebug + build.append('debug') + + if '-DNDEBUG' in (cflags + cflags_nodist): + build.append('without_assert') + else: + build.append('release') + + if '--with-assertions' in config_args: + build.append('with_assert') + elif '-DNDEBUG' not in (cflags + cflags_nodist): + build.append('with_assert') + + # --enable-framework=name + framework = sysconfig.get_config_var('PYTHONFRAMEWORK') + if framework: + build.append(f'framework={framework}') + + # --enable-shared + shared = int(sysconfig.get_config_var('PY_ENABLE_SHARED') or '0') + if shared: + build.append('shared') + + # --with-lto + optimizations = [] + if '-flto=thin' in ldflags_nodist: + optimizations.append('ThinLTO') + elif '-flto' in ldflags_nodist: + optimizations.append('LTO') + + # --enable-optimizations + pgo_options = ( + # GCC + '-fprofile-use', + # clang: -fprofile-instr-use=code.profclangd + '-fprofile-instr-use', + # ICC + "-prof-use", + ) + if any(option in cflags_nodist for option in pgo_options): + optimizations.append('PGO') + if optimizations: + build.append('+'.join(optimizations)) + + # --with-address-sanitizer + sanitizers = [] + if support.check_sanitizer(address=True): + sanitizers.append("ASAN") + # --with-memory-sanitizer + if support.check_sanitizer(memory=True): + sanitizers.append("MSAN") + # --with-undefined-behavior-sanitizer + if support.check_sanitizer(ub=True): + sanitizers.append("UBSAN") + if sanitizers: + build.append('+'.join(sanitizers)) + + # --with-trace-refs + if hasattr(sys, 'getobjects'): + build.append("TraceRefs") + # --enable-pystats + if hasattr(sys, '_stats_on'): + build.append("pystats") + # --with-valgrind + if sysconfig.get_config_var('WITH_VALGRIND'): + build.append("valgrind") + # --with-dtrace + if sysconfig.get_config_var('WITH_DTRACE'): + build.append("dtrace") + + return build diff --git a/Lib/test/libregrtest/win_utils.py b/Lib/test/libregrtest/win_utils.py index a1cc2201147..5736cdfd3c7 100644 --- a/Lib/test/libregrtest/win_utils.py +++ b/Lib/test/libregrtest/win_utils.py @@ -1,16 +1,11 @@ +import _overlapped +import _thread import _winapi import math -import msvcrt -import os -import subprocess -import uuid +import struct import winreg -from test.support import os_helper -from test.libregrtest.utils import print_warning -# Max size of asynchronous reads -BUFSIZE = 8192 # Seconds per measurement SAMPLING_INTERVAL = 1 # Exponential damping factor to compute exponentially weighted moving average @@ -19,174 +14,111 @@ LOAD_FACTOR_1 = 1 / math.exp(SAMPLING_INTERVAL / 60) # Initialize the load using the arithmetic mean of the first NVALUE values # of the Processor Queue Length NVALUE = 5 -# Windows registry subkey of HKEY_LOCAL_MACHINE where the counter names -# of typeperf are registered -COUNTER_REGISTRY_KEY = (r"SOFTWARE\Microsoft\Windows NT\CurrentVersion" - r"\Perflib\CurrentLanguage") class WindowsLoadTracker(): """ - This class asynchronously interacts with the `typeperf` command to read - the system load on Windows. Multiprocessing and threads can't be used - here because they interfere with the test suite's cases for those - modules. + This class asynchronously reads the performance counters to calculate + the system load on Windows. A "raw" thread is used here to prevent + interference with the test suite's cases for the threading module. """ def __init__(self): + # Pre-flight test for access to the performance data; + # `PermissionError` will be raised if not allowed + winreg.QueryInfoKey(winreg.HKEY_PERFORMANCE_DATA) + self._values = [] self._load = None - self._buffer = '' - self._popen = None - self.start() + self._running = _overlapped.CreateEvent(None, True, False, None) + self._stopped = _overlapped.CreateEvent(None, True, False, None) - def start(self): - # Create a named pipe which allows for asynchronous IO in Windows - pipe_name = r'\\.\pipe\typeperf_output_' + str(uuid.uuid4()) + _thread.start_new_thread(self._update_load, (), {}) - open_mode = _winapi.PIPE_ACCESS_INBOUND - open_mode |= _winapi.FILE_FLAG_FIRST_PIPE_INSTANCE - open_mode |= _winapi.FILE_FLAG_OVERLAPPED + def _update_load(self, + # localize module access to prevent shutdown errors + _wait=_winapi.WaitForSingleObject, + _signal=_overlapped.SetEvent): + # run until signaled to stop + while _wait(self._running, 1000): + self._calculate_load() + # notify stopped + _signal(self._stopped) - # This is the read end of the pipe, where we will be grabbing output - self.pipe = _winapi.CreateNamedPipe( - pipe_name, open_mode, _winapi.PIPE_WAIT, - 1, BUFSIZE, BUFSIZE, _winapi.NMPWAIT_WAIT_FOREVER, _winapi.NULL - ) - # The write end of the pipe which is passed to the created process - pipe_write_end = _winapi.CreateFile( - pipe_name, _winapi.GENERIC_WRITE, 0, _winapi.NULL, - _winapi.OPEN_EXISTING, 0, _winapi.NULL - ) - # Open up the handle as a python file object so we can pass it to - # subprocess - command_stdout = msvcrt.open_osfhandle(pipe_write_end, 0) - - # Connect to the read end of the pipe in overlap/async mode - overlap = _winapi.ConnectNamedPipe(self.pipe, overlapped=True) - overlap.GetOverlappedResult(True) - - # Spawn off the load monitor - counter_name = self._get_counter_name() - command = ['typeperf', counter_name, '-si', str(SAMPLING_INTERVAL)] - self._popen = subprocess.Popen(' '.join(command), - stdout=command_stdout, - cwd=os_helper.SAVEDCWD) - - # Close our copy of the write end of the pipe - os.close(command_stdout) - - def _get_counter_name(self): - # accessing the registry to get the counter localization name - with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, COUNTER_REGISTRY_KEY) as perfkey: - counters = winreg.QueryValueEx(perfkey, 'Counter')[0] - - # Convert [key1, value1, key2, value2, ...] list - # to {key1: value1, key2: value2, ...} dict - counters = iter(counters) - counters_dict = dict(zip(counters, counters)) - - # System counter has key '2' and Processor Queue Length has key '44' - system = counters_dict['2'] - process_queue_length = counters_dict['44'] - return f'"\\{system}\\{process_queue_length}"' - - def close(self, kill=True): - if self._popen is None: + def _calculate_load(self, + # localize module access to prevent shutdown errors + _query=winreg.QueryValueEx, + _hkey=winreg.HKEY_PERFORMANCE_DATA, + _unpack=struct.unpack_from): + # get the 'System' object + data, _ = _query(_hkey, '2') + # PERF_DATA_BLOCK { + # WCHAR Signature[4] 8 + + # DWOWD LittleEndian 4 + + # DWORD Version 4 + + # DWORD Revision 4 + + # DWORD TotalByteLength 4 + + # DWORD HeaderLength = 24 byte offset + # ... + # } + obj_start, = _unpack('L', data, 24) + # PERF_OBJECT_TYPE { + # DWORD TotalByteLength + # DWORD DefinitionLength + # DWORD HeaderLength + # ... + # } + data_start, defn_start = _unpack('4xLL', data, obj_start) + data_base = obj_start + data_start + defn_base = obj_start + defn_start + # find the 'Processor Queue Length' counter (index=44) + while defn_base < data_base: + # PERF_COUNTER_DEFINITION { + # DWORD ByteLength + # DWORD CounterNameTitleIndex + # ... [7 DWORDs/28 bytes] + # DWORD CounterOffset + # } + size, idx, offset = _unpack('LL28xL', data, defn_base) + defn_base += size + if idx == 44: + counter_offset = data_base + offset + # the counter is known to be PERF_COUNTER_RAWCOUNT (DWORD) + processor_queue_length, = _unpack('L', data, counter_offset) + break + else: return - self._load = None - - if kill: - self._popen.kill() - self._popen.wait() - self._popen = None - - def __del__(self): - self.close() - - def _parse_line(self, line): - # typeperf outputs in a CSV format like this: - # "07/19/2018 01:32:26.605","3.000000" - # (date, process queue length) - tokens = line.split(',') - if len(tokens) != 2: - raise ValueError - - value = tokens[1] - if not value.startswith('"') or not value.endswith('"'): - raise ValueError - value = value[1:-1] - return float(value) - - def _read_lines(self): - overlapped, _ = _winapi.ReadFile(self.pipe, BUFSIZE, True) - bytes_read, res = overlapped.GetOverlappedResult(False) - if res != 0: - return () - - output = overlapped.getbuffer() - output = output.decode('oem', 'replace') - output = self._buffer + output - lines = output.splitlines(True) - - # bpo-36670: typeperf only writes a newline *before* writing a value, - # not after. Sometimes, the written line in incomplete (ex: only - # timestamp, without the process queue length). Only pass the last line - # to the parser if it's a valid value, otherwise store it in - # self._buffer. - try: - self._parse_line(lines[-1]) - except ValueError: - self._buffer = lines.pop(-1) + # We use an exponentially weighted moving average, imitating the + # load calculation on Unix systems. + # https://en.wikipedia.org/wiki/Load_(computing)#Unix-style_load_calculation + # https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average + if self._load is not None: + self._load = (self._load * LOAD_FACTOR_1 + + processor_queue_length * (1.0 - LOAD_FACTOR_1)) + elif len(self._values) < NVALUE: + self._values.append(processor_queue_length) else: - self._buffer = '' + self._load = sum(self._values) / len(self._values) - return lines + def close(self, kill=True): + self.__del__() + return + + def __del__(self, + # localize module access to prevent shutdown errors + _wait=_winapi.WaitForSingleObject, + _close=_winapi.CloseHandle, + _signal=_overlapped.SetEvent): + if self._running is not None: + # tell the update thread to quit + _signal(self._running) + # wait for the update thread to signal done + _wait(self._stopped, -1) + # cleanup events + _close(self._running) + _close(self._stopped) + self._running = self._stopped = None def getloadavg(self): - if self._popen is None: - return None - - returncode = self._popen.poll() - if returncode is not None: - self.close(kill=False) - return None - - try: - lines = self._read_lines() - except BrokenPipeError: - self.close() - return None - - for line in lines: - line = line.rstrip() - - # Ignore the initial header: - # "(PDH-CSV 4.0)","\\\\WIN\\System\\Processor Queue Length" - if 'PDH-CSV' in line: - continue - - # Ignore blank lines - if not line: - continue - - try: - processor_queue_length = self._parse_line(line) - except ValueError: - print_warning("Failed to parse typeperf output: %a" % line) - continue - - # We use an exponentially weighted moving average, imitating the - # load calculation on Unix systems. - # https://en.wikipedia.org/wiki/Load_(computing)#Unix-style_load_calculation - # https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average - if self._load is not None: - self._load = (self._load * LOAD_FACTOR_1 - + processor_queue_length * (1.0 - LOAD_FACTOR_1)) - elif len(self._values) < NVALUE: - self._values.append(processor_queue_length) - else: - self._load = sum(self._values) / len(self._values) - return self._load diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py index f7eea88c54a..fe3ee80b8d4 100644 --- a/Lib/test/list_tests.py +++ b/Lib/test/list_tests.py @@ -3,10 +3,9 @@ Tests common to list and UserList.UserList """ import sys -import os from functools import cmp_to_key -from test import support, seq_tests +from test import seq_tests from test.support import ALWAYS_EQ, NEVER_EQ diff --git a/Lib/test/lock_tests.py b/Lib/test/lock_tests.py index d82629368df..a4f52cb20ad 100644 --- a/Lib/test/lock_tests.py +++ b/Lib/test/lock_tests.py @@ -2,7 +2,6 @@ Various tests for synchronization primitives. """ -import os import gc import sys import time @@ -15,7 +14,7 @@ from test import support from test.support import threading_helper -requires_fork = unittest.skipUnless(hasattr(os, 'fork'), +requires_fork = unittest.skipUnless(support.has_fork_support, "platform doesn't support fork " "(no _at_fork_reinit method)") diff --git a/Lib/test/make_ssl_certs.py b/Lib/test/make_ssl_certs.py index c62896f861d..94a35a64ab1 100644 --- a/Lib/test/make_ssl_certs.py +++ b/Lib/test/make_ssl_certs.py @@ -307,6 +307,6 @@ if __name__ == '__main__': f.write(cert) unmake_ca() - print("update Lib/test/test_ssl.py and Lib/test/test_asyncio/util.py") + print("update Lib/test/test_ssl.py and Lib/test/test_asyncio/utils.py") print_cert('keycert.pem') print_cert('keycert3.pem') diff --git a/Lib/test/mock_socket.py b/Lib/test/mock_socket.py index 9788d58b4c7..b85b955d7f6 100644 --- a/Lib/test/mock_socket.py +++ b/Lib/test/mock_socket.py @@ -33,7 +33,7 @@ class MockFile: class MockSocket: - """Mock socket object used by smtplib tests. + """Mock socket object used by the smtplib tests. """ def __init__(self, family=None): global _reply_data diff --git a/Lib/test/mod_generics_cache.py b/Lib/test/mod_generics_cache.py index 6d35c58396d..9d8b56cf03c 100644 --- a/Lib/test/mod_generics_cache.py +++ b/Lib/test/mod_generics_cache.py @@ -1,53 +1,21 @@ """Module for testing the behavior of generics across different modules.""" -import sys -from textwrap import dedent from typing import TypeVar, Generic, Optional +default_a: Optional['A'] = None +default_b: Optional['B'] = None -if sys.version_info[:2] >= (3, 6): - exec(dedent(""" - default_a: Optional['A'] = None - default_b: Optional['B'] = None - - T = TypeVar('T') +T = TypeVar('T') +class A(Generic[T]): + some_b: 'B' + + +class B(Generic[T]): class A(Generic[T]): - some_b: 'B' + pass - - class B(Generic[T]): - class A(Generic[T]): - pass - - my_inner_a1: 'B.A' - my_inner_a2: A - my_outer_a: 'A' # unless somebody calls get_type_hints with localns=B.__dict__ - """)) -else: # This should stay in sync with the syntax above. - __annotations__ = dict( - default_a=Optional['A'], - default_b=Optional['B'], - ) - default_a = None - default_b = None - - T = TypeVar('T') - - - class A(Generic[T]): - __annotations__ = dict( - some_b='B' - ) - - - class B(Generic[T]): - class A(Generic[T]): - pass - - __annotations__ = dict( - my_inner_a1='B.A', - my_inner_a2=A, - my_outer_a='A' # unless somebody calls get_type_hints with localns=B.__dict__ - ) + my_inner_a1: 'B.A' + my_inner_a2: A + my_outer_a: 'A' # unless somebody calls get_type_hints with localns=B.__dict__ diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index f13d42f6648..6e87370c206 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -1,3 +1,4 @@ +import builtins import collections import copyreg import dbm @@ -11,6 +12,7 @@ import shutil import struct import sys import threading +import types import unittest import weakref from textwrap import dedent @@ -1380,6 +1382,7 @@ class AbstractUnpickleTests: self.check_unpickling_error(self.truncated_errors, p) @threading_helper.reap_threads + @threading_helper.requires_working_threading() def test_unpickle_module_race(self): # https://bugs.python.org/issue34572 locker_module = dedent(""" @@ -1979,6 +1982,33 @@ class AbstractPickleTests: u = self.loads(s) self.assertIs(type(singleton), u) + def test_builtin_types(self): + for t in builtins.__dict__.values(): + if isinstance(t, type) and not issubclass(t, BaseException): + for proto in protocols: + s = self.dumps(t, proto) + self.assertIs(self.loads(s), t) + + def test_builtin_exceptions(self): + for t in builtins.__dict__.values(): + if isinstance(t, type) and issubclass(t, BaseException): + for proto in protocols: + s = self.dumps(t, proto) + u = self.loads(s) + if proto <= 2 and issubclass(t, OSError) and t is not BlockingIOError: + self.assertIs(u, OSError) + elif proto <= 2 and issubclass(t, ImportError): + self.assertIs(u, ImportError) + else: + self.assertIs(u, t) + + def test_builtin_functions(self): + for t in builtins.__dict__.values(): + if isinstance(t, types.BuiltinFunctionType): + for proto in protocols: + s = self.dumps(t, proto) + self.assertIs(self.loads(s), t) + # Tests for protocol 2 def test_proto(self): @@ -2382,9 +2412,11 @@ class AbstractPickleTests: def test_bad_getattr(self): # Issue #3514: crash when there is an infinite loop in __getattr__ x = BadGetattr() - for proto in protocols: + for proto in range(2): with support.infinite_recursion(): self.assertRaises(RuntimeError, self.dumps, x, proto) + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + s = self.dumps(x, proto) def test_reduce_bad_iterator(self): # Issue4176: crash when 4th and 5th items of __reduce__() @@ -2773,6 +2805,15 @@ class AbstractPickleTests: unpickled = self.loads(self.dumps(method, proto)) self.assertEqual(method(obj), unpickled(obj)) + descriptors = ( + PyMethodsTest.__dict__['cheese'], # static method descriptor + PyMethodsTest.__dict__['wine'], # class method descriptor + ) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + for descr in descriptors: + with self.subTest(proto=proto, descr=descr): + self.assertRaises(TypeError, self.dumps, descr, proto) + def test_c_methods(self): global Subclass class Subclass(tuple): @@ -2808,6 +2849,15 @@ class AbstractPickleTests: unpickled = self.loads(self.dumps(method, proto)) self.assertEqual(method(*args), unpickled(*args)) + descriptors = ( + bytearray.__dict__['maketrans'], # built-in static method descriptor + dict.__dict__['fromkeys'], # built-in class method descriptor + ) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + for descr in descriptors: + with self.subTest(proto=proto, descr=descr): + self.assertRaises(TypeError, self.dumps, descr, proto) + def test_compat_pickle(self): tests = [ (range(1, 7), '__builtin__', 'xrange'), @@ -3032,6 +3082,67 @@ class AbstractPickleTests: # 2-D, non-contiguous check_array(arr[::2]) + def test_evil_class_mutating_dict(self): + # https://github.com/python/cpython/issues/92930 + from random import getrandbits + + global Bad + class Bad: + def __eq__(self, other): + return ENABLED + def __hash__(self): + return 42 + def __reduce__(self): + if getrandbits(6) == 0: + collection.clear() + return (Bad, ()) + + for proto in protocols: + for _ in range(20): + ENABLED = False + collection = {Bad(): Bad() for _ in range(20)} + for bad in collection: + bad.bad = bad + bad.collection = collection + ENABLED = True + try: + data = self.dumps(collection, proto) + self.loads(data) + except RuntimeError as e: + expected = "changed size during iteration" + self.assertIn(expected, str(e)) + + def test_evil_pickler_mutating_collection(self): + # https://github.com/python/cpython/issues/92930 + if not hasattr(self, "pickler"): + raise self.skipTest(f"{type(self)} has no associated pickler type") + + global Clearer + class Clearer: + pass + + def check(collection): + class EvilPickler(self.pickler): + def persistent_id(self, obj): + if isinstance(obj, Clearer): + collection.clear() + return None + pickler = EvilPickler(io.BytesIO(), proto) + try: + pickler.dump(collection) + except RuntimeError as e: + expected = "changed size during iteration" + self.assertIn(expected, str(e)) + + for proto in protocols: + check([Clearer()]) + check([Clearer(), Clearer()]) + check({Clearer()}) + check({Clearer(), Clearer()}) + check({Clearer(): 1}) + check({Clearer(): 1, Clearer(): 2}) + check({1: Clearer(), 2: Clearer()}) + class BigmemPickleTests: diff --git a/Lib/test/pydoc_mod.py b/Lib/test/pydoc_mod.py index 9c1fff5c2f2..80c287fb10c 100644 --- a/Lib/test/pydoc_mod.py +++ b/Lib/test/pydoc_mod.py @@ -1,5 +1,10 @@ """This is a test module for test_pydoc""" +from __future__ import print_function + +import types +import typing + __author__ = "Benjamin Peterson" __credits__ = "Nobody" __version__ = "1.2.3.4" @@ -24,6 +29,8 @@ class C(object): def is_it_true(self): """ Return self.get_answer() """ return self.get_answer() + def __class_getitem__(self, item): + return types.GenericAlias(self, item) def doc_func(): """ @@ -35,3 +42,10 @@ def doc_func(): def nodoc_func(): pass + + +list_alias1 = typing.List[int] +list_alias2 = list[int] +c_alias = C[int] +type_union1 = typing.Union[int, str] +type_union2 = int | str diff --git a/Lib/test/pydocfodder.py b/Lib/test/pydocfodder.py index 2530320a222..d0750e5a43c 100644 --- a/Lib/test/pydocfodder.py +++ b/Lib/test/pydocfodder.py @@ -2,85 +2,7 @@ import types -class A_classic: - "A classic class." - def A_method(self): - "Method defined in A." - def AB_method(self): - "Method defined in A and B." - def AC_method(self): - "Method defined in A and C." - def AD_method(self): - "Method defined in A and D." - def ABC_method(self): - "Method defined in A, B and C." - def ABD_method(self): - "Method defined in A, B and D." - def ACD_method(self): - "Method defined in A, C and D." - def ABCD_method(self): - "Method defined in A, B, C and D." - - -class B_classic(A_classic): - "A classic class, derived from A_classic." - def AB_method(self): - "Method defined in A and B." - def ABC_method(self): - "Method defined in A, B and C." - def ABD_method(self): - "Method defined in A, B and D." - def ABCD_method(self): - "Method defined in A, B, C and D." - def B_method(self): - "Method defined in B." - def BC_method(self): - "Method defined in B and C." - def BD_method(self): - "Method defined in B and D." - def BCD_method(self): - "Method defined in B, C and D." - -class C_classic(A_classic): - "A classic class, derived from A_classic." - def AC_method(self): - "Method defined in A and C." - def ABC_method(self): - "Method defined in A, B and C." - def ACD_method(self): - "Method defined in A, C and D." - def ABCD_method(self): - "Method defined in A, B, C and D." - def BC_method(self): - "Method defined in B and C." - def BCD_method(self): - "Method defined in B, C and D." - def C_method(self): - "Method defined in C." - def CD_method(self): - "Method defined in C and D." - -class D_classic(B_classic, C_classic): - "A classic class, derived from B_classic and C_classic." - def AD_method(self): - "Method defined in A and D." - def ABD_method(self): - "Method defined in A, B and D." - def ACD_method(self): - "Method defined in A, C and D." - def ABCD_method(self): - "Method defined in A, B, C and D." - def BD_method(self): - "Method defined in B and D." - def BCD_method(self): - "Method defined in B, C and D." - def CD_method(self): - "Method defined in C and D." - def D_method(self): - "Method defined in D." - - -class A_new(object): +class A_new: "A new-style class." def A_method(self): diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 39ee9e1d769..adc211b3e21 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -6,9 +6,13 @@ import errno import re import sys import traceback +import unittest import warnings +MS_WINDOWS = (sys.platform == 'win32') + + def normalize_text(text): if text is None: return None @@ -78,6 +82,7 @@ def call_func(info_add, name, mod, func_name, *, formatter=None): def collect_sys(info_add): attributes = ( + '_emscripten_info', '_framework', 'abiflags', 'api_version', @@ -125,13 +130,21 @@ def collect_sys(info_add): encoding = '%s/%s' % (encoding, errors) info_add('sys.%s.encoding' % name, encoding) - # Were we compiled --with-pydebug or with #define Py_DEBUG? + # Were we compiled --with-pydebug? Py_DEBUG = hasattr(sys, 'gettotalrefcount') if Py_DEBUG: text = 'Yes (sys.gettotalrefcount() present)' else: text = 'No (sys.gettotalrefcount() missing)' - info_add('Py_DEBUG', text) + info_add('build.Py_DEBUG', text) + + # Were we compiled --with-trace-refs? + Py_TRACE_REFS = hasattr(sys, 'getobjects') + if Py_TRACE_REFS: + text = 'Yes (sys.getobjects() present)' + else: + text = 'No (sys.getobjects() missing)' + info_add('build.Py_TRACE_REFS', text) def collect_platform(info_add): @@ -154,7 +167,7 @@ def collect_platform(info_add): def collect_locale(info_add): import locale - info_add('locale.encoding', locale.getpreferredencoding(False)) + info_add('locale.getencoding', locale.getencoding()) def collect_builtins(info_add): @@ -434,6 +447,15 @@ def collect_time(info_add): info_add('time.get_clock_info(%s)' % clock, clock_info) +def collect_curses(info_add): + try: + import curses + except ImportError: + return + + copy_attr(info_add, 'curses.ncurses_version', curses, 'ncurses_version') + + def collect_datetime(info_add): try: import datetime @@ -444,6 +466,11 @@ def collect_datetime(info_add): def collect_sysconfig(info_add): + # On Windows, sysconfig is not reliable to get macros used + # to build Python + if MS_WINDOWS: + return + import sysconfig for name in ( @@ -477,6 +504,28 @@ def collect_sysconfig(info_add): value = normalize_text(value) info_add('sysconfig[%s]' % name, value) + PY_CFLAGS = sysconfig.get_config_var('PY_CFLAGS') + NDEBUG = (PY_CFLAGS and '-DNDEBUG' in PY_CFLAGS) + if NDEBUG: + text = 'ignore assertions (macro defined)' + else: + text= 'build assertions (macro not defined)' + info_add('build.NDEBUG',text) + + for name in ( + 'WITH_DOC_STRINGS', + 'WITH_DTRACE', + 'WITH_FREELISTS', + 'WITH_PYMALLOC', + 'WITH_VALGRIND', + ): + value = sysconfig.get_config_var(name) + if value: + text = 'Yes' + else: + text = 'No' + info_add(f'build.{name}', text) + def collect_ssl(info_add): import os @@ -532,10 +581,19 @@ def collect_ssl(info_add): def collect_socket(info_add): - import socket + try: + import socket + except ImportError: + return - hostname = socket.gethostname() - info_add('socket.hostname', hostname) + try: + hostname = socket.gethostname() + except (OSError, AttributeError): + # WASI SDK 16.0 does not have gethostname(2). + if sys.platform != "wasi": + raise + else: + info_add('socket.hostname', hostname) def collect_sqlite(info_add): @@ -544,7 +602,7 @@ def collect_sqlite(info_add): except ImportError: return - attributes = ('version', 'sqlite_version') + attributes = ('sqlite_version',) copy_attributes(info_add, sqlite3, 'sqlite3.%s', attributes) @@ -585,7 +643,6 @@ def collect_testcapi(info_add): return call_func(info_add, 'pymem.allocator', _testcapi, 'pymem_getallocatorsname') - copy_attr(info_add, 'pymem.with_pymalloc', _testcapi, 'WITH_PYMALLOC') def collect_resource(info_add): @@ -606,7 +663,7 @@ def collect_resource(info_add): def collect_test_socket(info_add): try: from test import test_socket - except ImportError: + except (ImportError, unittest.SkipTest): return # all check attributes like HAVE_SOCKET_CAN @@ -627,6 +684,13 @@ def collect_test_support(info_add): call_func(info_add, 'test_support._is_gui_available', support, '_is_gui_available') call_func(info_add, 'test_support.python_is_optimized', support, 'python_is_optimized') + info_add('test_support.check_sanitizer(address=True)', + support.check_sanitizer(address=True)) + info_add('test_support.check_sanitizer(memory=True)', + support.check_sanitizer(memory=True)) + info_add('test_support.check_sanitizer(ub=True)', + support.check_sanitizer(ub=True)) + def collect_cc(info_add): import subprocess @@ -720,6 +784,48 @@ def collect_windows(info_add): except (ImportError, AttributeError): pass + import subprocess + try: + # When wmic.exe output is redirected to a pipe, + # it uses the OEM code page + proc = subprocess.Popen(["wmic", "os", "get", "Caption,Version", "/value"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + encoding="oem", + text=True) + output, stderr = proc.communicate() + if proc.returncode: + output = "" + except OSError: + pass + else: + for line in output.splitlines(): + line = line.strip() + if line.startswith('Caption='): + line = line.removeprefix('Caption=').strip() + if line: + info_add('windows.version_caption', line) + elif line.startswith('Version='): + line = line.removeprefix('Version=').strip() + if line: + info_add('windows.version', line) + + try: + proc = subprocess.Popen(["ver"], shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True) + output = proc.communicate()[0] + if proc.returncode: + output = "" + except OSError: + return + else: + output = output.strip() + line = output.splitlines()[0] + if line: + info_add('windows.ver', line) + def collect_fips(info_add): try: @@ -752,6 +858,7 @@ def collect_info(info): collect_builtins, collect_cc, + collect_curses, collect_datetime, collect_decimal, collect_expat, diff --git a/Lib/test/setup_testcppext.py b/Lib/test/setup_testcppext.py new file mode 100644 index 00000000000..c6b68104d13 --- /dev/null +++ b/Lib/test/setup_testcppext.py @@ -0,0 +1,48 @@ +# gh-91321: Build a basic C++ test extension to check that the Python C API is +# compatible with C++ and does not emit C++ compiler warnings. +import sys +from test import support + +from setuptools import setup, Extension + + +MS_WINDOWS = (sys.platform == 'win32') + + +SOURCE = support.findfile('_testcppext.cpp') +if not MS_WINDOWS: + # C++ compiler flags for GCC and clang + CPPFLAGS = [ + # gh-91321: The purpose of _testcppext extension is to check that building + # a C++ extension using the Python C API does not emit C++ compiler + # warnings + '-Werror', + ] +else: + # Don't pass any compiler flag to MSVC + CPPFLAGS = [] + + +def main(): + cppflags = list(CPPFLAGS) + if '-std=c++03' in sys.argv: + sys.argv.remove('-std=c++03') + std = 'c++03' + name = '_testcpp03ext' + else: + # Python currently targets C++11 + std = 'c++11' + name = '_testcpp11ext' + + cppflags = [*CPPFLAGS, f'-std={std}'] + + cpp_ext = Extension( + name, + sources=[SOURCE], + language='c++', + extra_compile_args=cppflags) + setup(name='internal' + name, version='0.0', ext_modules=[cpp_ext]) + + +if __name__ == "__main__": + main() diff --git a/Lib/test/signalinterproctester.py b/Lib/test/signalinterproctester.py index bc60b747f71..cdcd92a8baa 100644 --- a/Lib/test/signalinterproctester.py +++ b/Lib/test/signalinterproctester.py @@ -28,16 +28,15 @@ class InterProcessSignalTests(unittest.TestCase): # (if set) child.wait() - timeout = support.SHORT_TIMEOUT - deadline = time.monotonic() + timeout - - while time.monotonic() < deadline: + start_time = time.monotonic() + for _ in support.busy_retry(support.SHORT_TIMEOUT, error=False): if self.got_signals[signame]: return signal.pause() - - self.fail('signal %s not received after %s seconds' - % (signame, timeout)) + else: + dt = time.monotonic() - start_time + self.fail('signal %s not received after %.1f seconds' + % (signame, dt)) def subprocess_send_signal(self, pid, signame): code = 'import os, signal; os.kill(%s, signal.%s)' % (pid, signame) diff --git a/Lib/test/support/_smtpd.py b/Lib/test/smtpd.py similarity index 84% rename from Lib/test/support/_smtpd.py rename to Lib/test/smtpd.py index 0e37d08f2be..6052232ec2b 100755 --- a/Lib/test/support/_smtpd.py +++ b/Lib/test/smtpd.py @@ -77,17 +77,14 @@ import getopt import time import socket import collections +from test.support import asyncore, asynchat from warnings import warn from email._header_value_parser import get_addr_spec, get_angle_addr -from test.support import _asyncore as asyncore -from test.support import _asynchat as asynchat - __all__ = [ "SMTPChannel", "SMTPServer", "DebuggingServer", "PureProxy", ] - program = sys.argv[0] __version__ = 'Python SMTP proxy version 0.3' @@ -179,6 +176,128 @@ class SMTPChannel(asynchat.async_chat): self.received_lines = [] + # properties for backwards-compatibility + @property + def __server(self): + warn("Access to __server attribute on SMTPChannel is deprecated, " + "use 'smtp_server' instead", DeprecationWarning, 2) + return self.smtp_server + @__server.setter + def __server(self, value): + warn("Setting __server attribute on SMTPChannel is deprecated, " + "set 'smtp_server' instead", DeprecationWarning, 2) + self.smtp_server = value + + @property + def __line(self): + warn("Access to __line attribute on SMTPChannel is deprecated, " + "use 'received_lines' instead", DeprecationWarning, 2) + return self.received_lines + @__line.setter + def __line(self, value): + warn("Setting __line attribute on SMTPChannel is deprecated, " + "set 'received_lines' instead", DeprecationWarning, 2) + self.received_lines = value + + @property + def __state(self): + warn("Access to __state attribute on SMTPChannel is deprecated, " + "use 'smtp_state' instead", DeprecationWarning, 2) + return self.smtp_state + @__state.setter + def __state(self, value): + warn("Setting __state attribute on SMTPChannel is deprecated, " + "set 'smtp_state' instead", DeprecationWarning, 2) + self.smtp_state = value + + @property + def __greeting(self): + warn("Access to __greeting attribute on SMTPChannel is deprecated, " + "use 'seen_greeting' instead", DeprecationWarning, 2) + return self.seen_greeting + @__greeting.setter + def __greeting(self, value): + warn("Setting __greeting attribute on SMTPChannel is deprecated, " + "set 'seen_greeting' instead", DeprecationWarning, 2) + self.seen_greeting = value + + @property + def __mailfrom(self): + warn("Access to __mailfrom attribute on SMTPChannel is deprecated, " + "use 'mailfrom' instead", DeprecationWarning, 2) + return self.mailfrom + @__mailfrom.setter + def __mailfrom(self, value): + warn("Setting __mailfrom attribute on SMTPChannel is deprecated, " + "set 'mailfrom' instead", DeprecationWarning, 2) + self.mailfrom = value + + @property + def __rcpttos(self): + warn("Access to __rcpttos attribute on SMTPChannel is deprecated, " + "use 'rcpttos' instead", DeprecationWarning, 2) + return self.rcpttos + @__rcpttos.setter + def __rcpttos(self, value): + warn("Setting __rcpttos attribute on SMTPChannel is deprecated, " + "set 'rcpttos' instead", DeprecationWarning, 2) + self.rcpttos = value + + @property + def __data(self): + warn("Access to __data attribute on SMTPChannel is deprecated, " + "use 'received_data' instead", DeprecationWarning, 2) + return self.received_data + @__data.setter + def __data(self, value): + warn("Setting __data attribute on SMTPChannel is deprecated, " + "set 'received_data' instead", DeprecationWarning, 2) + self.received_data = value + + @property + def __fqdn(self): + warn("Access to __fqdn attribute on SMTPChannel is deprecated, " + "use 'fqdn' instead", DeprecationWarning, 2) + return self.fqdn + @__fqdn.setter + def __fqdn(self, value): + warn("Setting __fqdn attribute on SMTPChannel is deprecated, " + "set 'fqdn' instead", DeprecationWarning, 2) + self.fqdn = value + + @property + def __peer(self): + warn("Access to __peer attribute on SMTPChannel is deprecated, " + "use 'peer' instead", DeprecationWarning, 2) + return self.peer + @__peer.setter + def __peer(self, value): + warn("Setting __peer attribute on SMTPChannel is deprecated, " + "set 'peer' instead", DeprecationWarning, 2) + self.peer = value + + @property + def __conn(self): + warn("Access to __conn attribute on SMTPChannel is deprecated, " + "use 'conn' instead", DeprecationWarning, 2) + return self.conn + @__conn.setter + def __conn(self, value): + warn("Setting __conn attribute on SMTPChannel is deprecated, " + "set 'conn' instead", DeprecationWarning, 2) + self.conn = value + + @property + def __addr(self): + warn("Access to __addr attribute on SMTPChannel is deprecated, " + "use 'addr' instead", DeprecationWarning, 2) + return self.addr + @__addr.setter + def __addr(self, value): + warn("Setting __addr attribute on SMTPChannel is deprecated, " + "set 'addr' instead", DeprecationWarning, 2) + self.addr = value + # Overrides base class for convenience. def push(self, msg): asynchat.async_chat.push(self, bytes( diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py index 0d4c7ecf4a0..709cac7a27a 100644 --- a/Lib/test/string_tests.py +++ b/Lib/test/string_tests.py @@ -341,6 +341,42 @@ class BaseTest: self.checkequal(reference_find(p, text), text, 'find', p) + def test_find_many_lengths(self): + haystack_repeats = [a * 10**e for e in range(6) for a in (1,2,5)] + haystacks = [(n, self.fixtype("abcab"*n + "da")) for n in haystack_repeats] + + needle_repeats = [a * 10**e for e in range(6) for a in (1, 3)] + needles = [(m, self.fixtype("abcab"*m + "da")) for m in needle_repeats] + + for n, haystack1 in haystacks: + haystack2 = haystack1[:-1] + for m, needle in needles: + answer1 = 5 * (n - m) if m <= n else -1 + self.assertEqual(haystack1.find(needle), answer1, msg=(n,m)) + self.assertEqual(haystack2.find(needle), -1, msg=(n,m)) + + def test_adaptive_find(self): + # This would be very slow for the naive algorithm, + # but str.find() should be O(n + m). + for N in 1000, 10_000, 100_000, 1_000_000: + A, B = 'a' * N, 'b' * N + haystack = A + A + B + A + A + needle = A + B + B + A + self.checkequal(-1, haystack, 'find', needle) + self.checkequal(0, haystack, 'count', needle) + self.checkequal(len(haystack), haystack + needle, 'find', needle) + self.checkequal(1, haystack + needle, 'count', needle) + + def test_find_with_memory(self): + # Test the "Skip with memory" path in the two-way algorithm. + for N in 1000, 3000, 10_000, 30_000: + needle = 'ab' * N + haystack = ('ab'*(N-1) + 'b') * 2 + self.checkequal(-1, haystack, 'find', needle) + self.checkequal(0, haystack, 'count', needle) + self.checkequal(len(haystack), haystack + needle, 'find', needle) + self.checkequal(1, haystack + needle, 'count', needle) + def test_find_shift_table_overflow(self): """When the table of 8-bit shifts overflows.""" N = 2**8 + 100 @@ -469,6 +505,11 @@ class BaseTest: self.checkraises(ValueError, 'hello', 'split', '', 0) def test_rsplit(self): + # without arg + self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'rsplit') + self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'rsplit') + self.checkequal([], '', 'rsplit') + # by a char self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|') self.checkequal(['a|b|c', 'd'], 'a|b|c|d', 'rsplit', '|', 1) @@ -522,6 +563,9 @@ class BaseTest: # with keyword args self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'rsplit', sep='|') + self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'rsplit', sep=None) + self.checkequal(['a b c', 'd'], + 'a b c d', 'rsplit', sep=None, maxsplit=1) self.checkequal(['a|b|c', 'd'], 'a|b|c|d', 'rsplit', '|', maxsplit=1) self.checkequal(['a|b|c', 'd'], @@ -715,6 +759,18 @@ class BaseTest: self.checkraises(TypeError, 'hello', 'replace', 42, 'h') self.checkraises(TypeError, 'hello', 'replace', 'h', 42) + def test_replace_uses_two_way_maxcount(self): + # Test that maxcount works in _two_way_count in fastsearch.h + A, B = "A"*1000, "B"*1000 + AABAA = A + A + B + A + A + ABBA = A + B + B + A + self.checkequal(AABAA + ABBA, + AABAA + ABBA, 'replace', ABBA, "ccc", 0) + self.checkequal(AABAA + "ccc", + AABAA + ABBA, 'replace', ABBA, "ccc", 1) + self.checkequal(AABAA + "ccc", + AABAA + ABBA, 'replace', ABBA, "ccc", 2) + @unittest.skipIf(sys.maxsize > (1 << 32) or struct.calcsize('P') != 4, 'only applies to 32-bit platforms') def test_replace_overflow(self): diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 6d84a8bea42..4a22ccdd4db 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -5,6 +5,8 @@ if __name__ != 'test.support': import contextlib import functools +import getpass +import opcode import os import re import stat @@ -35,16 +37,20 @@ __all__ = [ "is_resource_enabled", "requires", "requires_freebsd_version", "requires_linux_version", "requires_mac_ver", "check_syntax_error", - "BasicTestRunner", "run_unittest", "run_doctest", + "run_unittest", "run_doctest", "requires_gzip", "requires_bz2", "requires_lzma", "bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute", "requires_IEEE_754", "requires_zlib", + "has_fork_support", "requires_fork", + "has_subprocess_support", "requires_subprocess", + "has_socket_support", "requires_working_socket", "anticipate_failure", "load_package_tests", "detect_api_mismatch", "check__all__", "skip_if_buggy_ucrt_strfptime", - "check_disallow_instantiation", + "check_disallow_instantiation", "check_sanitizer", "skip_if_sanitizer", + "requires_limited_api", "requires_specialization", # sys - "is_jython", "is_android", "check_impl_detail", "unix_shell", - "setswitchinterval", + "is_jython", "is_android", "is_emscripten", "is_wasi", + "check_impl_detail", "unix_shell", "setswitchinterval", # network "open_urlresource", # processes @@ -55,6 +61,7 @@ __all__ = [ "run_with_tz", "PGO", "missing_compiler_executable", "ALWAYS_EQ", "NEVER_EQ", "LARGEST", "SMALLEST", "LOOPBACK_TIMEOUT", "INTERNET_TIMEOUT", "SHORT_TIMEOUT", "LONG_TIMEOUT", + "Py_DEBUG", "EXCEEDS_RECURSION_LIMIT", ] @@ -195,6 +202,11 @@ def get_original_stdout(): def _force_run(path, func, *args): try: return func(*args) + except FileNotFoundError as err: + # chmod() won't fix a missing file. + if verbose >= 2: + print('%s: %s' % (err.__class__.__name__, err)) + raise except OSError as err: if verbose >= 2: print('%s: %s' % (err.__class__.__name__, err)) @@ -295,6 +307,8 @@ def requires(resource, msg=None): if msg is None: msg = "Use of the %r resource not enabled" % resource raise ResourceDenied(msg) + if resource in {"network", "urlfetch"} and not has_socket_support: + raise ResourceDenied("No socket support") if resource == 'gui' and not _is_gui_available(): raise ResourceDenied(_is_gui_available.reason) @@ -376,12 +390,47 @@ def skip_if_buildbot(reason=None): """Decorator raising SkipTest if running on a buildbot.""" if not reason: reason = 'not suitable for buildbots' - if sys.platform == 'win32': - isbuildbot = os.environ.get('USERNAME') == 'Buildbot' - else: - isbuildbot = os.environ.get('USER') == 'buildbot' + try: + isbuildbot = getpass.getuser().lower() == 'buildbot' + except (KeyError, EnvironmentError) as err: + warnings.warn(f'getpass.getuser() failed {err}.', RuntimeWarning) + isbuildbot = False return unittest.skipIf(isbuildbot, reason) +def check_sanitizer(*, address=False, memory=False, ub=False): + """Returns True if Python is compiled with sanitizer support""" + if not (address or memory or ub): + raise ValueError('At least one of address, memory, or ub must be True') + + + _cflags = sysconfig.get_config_var('CFLAGS') or '' + _config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' + memory_sanitizer = ( + '-fsanitize=memory' in _cflags or + '--with-memory-sanitizer' in _config_args + ) + address_sanitizer = ( + '-fsanitize=address' in _cflags or + '--with-memory-sanitizer' in _config_args + ) + ub_sanitizer = ( + '-fsanitize=undefined' in _cflags or + '--with-undefined-behavior-sanitizer' in _config_args + ) + return ( + (memory and memory_sanitizer) or + (address and address_sanitizer) or + (ub and ub_sanitizer) + ) + + +def skip_if_sanitizer(reason=None, *, address=False, memory=False, ub=False): + """Decorator raising SkipTest if running with a sanitizer active.""" + if not reason: + reason = 'not working with sanitizers active' + skip = check_sanitizer(address=address, memory=memory, ub=ub) + return unittest.skipIf(skip, reason) + def system_must_validate_cert(f): """Skip the test on TLS certificate validation failures.""" @@ -449,7 +498,7 @@ def has_no_debug_ranges(): except ImportError: raise unittest.SkipTest("_testinternalcapi required") config = _testinternalcapi.get_config() - return bool(config['no_debug_ranges']) + return not bool(config['code_debug_ranges']) def requires_debug_ranges(reason='requires co_positions / debug_ranges'): return unittest.skipIf(has_no_debug_ranges(), reason) @@ -457,6 +506,7 @@ def requires_debug_ranges(reason='requires co_positions / debug_ranges'): requires_legacy_unicode_capi = unittest.skipUnless(unicode_legacy_string, 'requires legacy Unicode C API') +# Is not actually used in tests, but is kept for compatibility. is_jython = sys.platform.startswith('java') is_android = hasattr(sys, 'getandroidapilevel') @@ -466,6 +516,46 @@ if sys.platform not in ('win32', 'vxworks'): else: unix_shell = None +# wasm32-emscripten and -wasi are POSIX-like but do not +# have subprocess or fork support. +is_emscripten = sys.platform == "emscripten" +is_wasi = sys.platform == "wasi" + +has_fork_support = hasattr(os, "fork") and not is_emscripten and not is_wasi + +def requires_fork(): + return unittest.skipUnless(has_fork_support, "requires working os.fork()") + +has_subprocess_support = not is_emscripten and not is_wasi + +def requires_subprocess(): + """Used for subprocess, os.spawn calls, fd inheritance""" + return unittest.skipUnless(has_subprocess_support, "requires subprocess support") + +# Emscripten's socket emulation and WASI sockets have limitations. +has_socket_support = not is_emscripten and not is_wasi + +def requires_working_socket(*, module=False): + """Skip tests or modules that require working sockets + + Can be used as a function/class decorator or to skip an entire module. + """ + msg = "requires socket support" + if module: + if not has_socket_support: + raise unittest.SkipTest(msg) + else: + return unittest.skipUnless(has_socket_support, msg) + +# Does strftime() support glibc extension like '%4Y'? +has_strftime_extensions = False +if sys.platform != "win32": + # bpo-47037: Windows debug builds crash with "Debug Assertion Failed" + try: + has_strftime_extensions = time.strftime("%4Y") != "%4Y" + except ValueError: + pass + # Define the URL of a dedicated HTTP server for the network tests. # The URL must use clear-text HTTP: no redirection to encrypted HTTPS. TEST_HTTP_URL = "http://www.pythontest.net" @@ -492,7 +582,8 @@ def darwin_malloc_err_warning(test_name): msg = ' NOTICE ' detail = (f'{test_name} may generate "malloc can\'t allocate region"\n' 'warnings on macOS systems. This behavior is known. Do not\n' - 'report a bug unless tests are also failing. See bpo-40928.') + 'report a bug unless tests are also failing.\n' + 'See https://github.com/python/cpython/issues/85100') padding, _ = shutil.get_terminal_size() print(msg.center(padding, '-')) @@ -648,8 +739,6 @@ def gc_collect(): """ import gc gc.collect() - if is_jython: - time.sleep(0.1) gc.collect() gc.collect() @@ -714,29 +803,29 @@ def check_sizeof(test, o, size): @contextlib.contextmanager def run_with_locale(catstr, *locales): + try: + import locale + category = getattr(locale, catstr) + orig_locale = locale.setlocale(category) + except AttributeError: + # if the test author gives us an invalid category string + raise + except: + # cannot retrieve original locale, so do nothing + locale = orig_locale = None + else: + for loc in locales: try: - import locale - category = getattr(locale, catstr) - orig_locale = locale.setlocale(category) - except AttributeError: - # if the test author gives us an invalid category string - raise + locale.setlocale(category, loc) + break except: - # cannot retrieve original locale, so do nothing - locale = orig_locale = None - else: - for loc in locales: - try: - locale.setlocale(category, loc) - break - except: - pass + pass - try: - yield - finally: - if locale and orig_locale: - locale.setlocale(category, orig_locale) + try: + yield + finally: + if locale and orig_locale: + locale.setlocale(category, orig_locale) #======================================================================= # Decorator for running a function in a specific timezone, correctly @@ -904,12 +993,6 @@ def bigaddrspacetest(f): #======================================================================= # unittest integration. -class BasicTestRunner: - def run(self, test): - result = unittest.TestResult() - test(result) - return result - def _id(obj): return obj @@ -988,6 +1071,18 @@ def refcount_test(test): return no_tracing(cpython_only(test)) +def requires_limited_api(test): + try: + import _testcapi + except ImportError: + return unittest.skip('needs _testcapi module')(test) + return unittest.skipUnless( + _testcapi.LIMITED_API_AVAILABLE, 'needs Limited API support')(test) + +def requires_specialization(test): + return unittest.skipUnless( + opcode.ENABLE_SPECIALIZATION, "requires specialization")(test) + def _filter_suite(suite, pred): """Recursively filter test cases in a suite based on a predicate.""" newtests = [] @@ -1223,6 +1318,8 @@ def reap_children(): # Need os.waitpid(-1, os.WNOHANG): Windows is not supported if not (hasattr(os, 'waitpid') and hasattr(os, 'WNOHANG')): return + elif not has_subprocess_support: + return # Reap all our dead child processes so we don't leave zombies around. # These hog resources and might be causing some of the buildbots to die. @@ -1364,7 +1461,7 @@ def skip_if_buggy_ucrt_strfptime(test): global _buggy_ucrt if _buggy_ucrt is None: if(sys.platform == 'win32' and - locale.getdefaultlocale()[1] == 'cp65001' and + locale.getencoding() == 'cp65001' and time.localtime().tm_zone == ''): _buggy_ucrt = True else: @@ -1385,9 +1482,6 @@ class PythonSymlink: self._platform_specific() - def _platform_specific(self): - pass - if sys.platform == "win32": def _platform_specific(self): import glob @@ -1413,8 +1507,11 @@ class PythonSymlink: self._env = {k.upper(): os.getenv(k) for k in os.environ} self._env["PYTHONHOME"] = os.path.dirname(self.real) - if sysconfig.is_python_build(True): + if sysconfig.is_python_build(): self._env["PYTHONPATH"] = STDLIB_DIR + else: + def _platform_specific(self): + pass def __enter__(self): os.symlink(self.real, self.link) @@ -1685,11 +1782,37 @@ def patch(test_instance, object_to_patch, attr_name, new_value): setattr(object_to_patch, attr_name, new_value) +@contextlib.contextmanager +def patch_list(orig): + """Like unittest.mock.patch.dict, but for lists.""" + try: + saved = orig[:] + yield + finally: + orig[:] = saved + + def run_in_subinterp(code): """ Run code in a subinterpreter. Raise unittest.SkipTest if the tracemalloc module is enabled. """ + _check_tracemalloc() + import _testcapi + return _testcapi.run_in_subinterp(code) + + +def run_in_subinterp_with_config(code, **config): + """ + Run code in a subinterpreter. Raise unittest.SkipTest if the tracemalloc + module is enabled. + """ + _check_tracemalloc() + import _testcapi + return _testcapi.run_in_subinterp_with_config(code, **config) + + +def _check_tracemalloc(): # Issue #10915, #15751: PyGILState_*() functions don't work with # sub-interpreters, the tracemalloc module uses these functions internally try: @@ -1701,8 +1824,6 @@ def run_in_subinterp(code): raise unittest.SkipTest("run_in_subinterp() cannot be used " "if tracemalloc module is tracing " "memory allocations") - import _testcapi - return _testcapi.run_in_subinterp(code) def check_free_after_iterating(test, iter, cls, args=()): @@ -1980,7 +2101,7 @@ def wait_process(pid, *, exitcode, timeout=None): Raise an AssertionError if the process exit code is not equal to exitcode. - If the process runs longer than timeout seconds (SHORT_TIMEOUT by default), + If the process runs longer than timeout seconds (LONG_TIMEOUT by default), kill the process (if signal.SIGKILL is available) and raise an AssertionError. The timeout feature is not available on Windows. """ @@ -1988,32 +2109,27 @@ def wait_process(pid, *, exitcode, timeout=None): import signal if timeout is None: - timeout = SHORT_TIMEOUT - t0 = time.monotonic() - sleep = 0.001 - max_sleep = 0.1 - while True: + timeout = LONG_TIMEOUT + + start_time = time.monotonic() + for _ in sleeping_retry(timeout, error=False): pid2, status = os.waitpid(pid, os.WNOHANG) if pid2 != 0: break - # process is still running + # rety: the process is still running + else: + try: + os.kill(pid, signal.SIGKILL) + os.waitpid(pid, 0) + except OSError: + # Ignore errors like ChildProcessError or PermissionError + pass - dt = time.monotonic() - t0 - if dt > SHORT_TIMEOUT: - try: - os.kill(pid, signal.SIGKILL) - os.waitpid(pid, 0) - except OSError: - # Ignore errors like ChildProcessError or PermissionError - pass - - raise AssertionError(f"process {pid} is still running " - f"after {dt:.1f} seconds") - - sleep = min(sleep * 2, max_sleep) - time.sleep(sleep) + dt = time.monotonic() - start_time + raise AssertionError(f"process {pid} is still running " + f"after {dt:.1f} seconds") else: - # Windows implementation + # Windows implementation: don't support timeout :-( pid2, status = os.waitpid(pid, 0) exitcode2 = os.waitstatus_to_exitcode(status) @@ -2066,19 +2182,23 @@ def check_disallow_instantiation(testcase, tp, *args, **kwds): testcase.assertRaisesRegex(TypeError, msg, tp, *args, **kwds) @contextlib.contextmanager +def set_recursion_limit(limit): + """Temporarily change the recursion limit.""" + original_limit = sys.getrecursionlimit() + try: + sys.setrecursionlimit(limit) + yield + finally: + sys.setrecursionlimit(original_limit) + def infinite_recursion(max_depth=75): """Set a lower limit for tests that interact with infinite recursions (e.g test_ast.ASTHelpers_Test.test_recursion_direct) since on some debug windows builds, due to not enough functions being inlined the stack size might not handle the default recursion limit (1000). See bpo-11105 for details.""" + return set_recursion_limit(max_depth) - original_depth = sys.getrecursionlimit() - try: - sys.setrecursionlimit(max_depth) - yield - finally: - sys.setrecursionlimit(original_depth) def ignore_deprecations_from(module: str, *, like: str) -> object: token = object() @@ -2108,3 +2228,152 @@ def clear_ignored_deprecations(*tokens: object) -> None: if warnings.filters != new_filters: warnings.filters[:] = new_filters warnings._filters_mutated() + + +# Skip a test if venv with pip is known to not work. +def requires_venv_with_pip(): + # ensurepip requires zlib to open ZIP archives (.whl binary wheel packages) + try: + import zlib + except ImportError: + return unittest.skipIf(True, "venv: ensurepip requires zlib") + + # bpo-26610: pip/pep425tags.py requires ctypes. + # gh-92820: setuptools/windows_support.py uses ctypes (setuptools 58.1). + try: + import ctypes + except ImportError: + ctypes = None + return unittest.skipUnless(ctypes, 'venv: pip requires ctypes') + + +# True if Python is built with the Py_DEBUG macro defined: if +# Python is built in debug mode (./configure --with-pydebug). +Py_DEBUG = hasattr(sys, 'gettotalrefcount') + + +def late_deletion(obj): + """ + Keep a Python alive as long as possible. + + Create a reference cycle and store the cycle in an object deleted late in + Python finalization. Try to keep the object alive until the very last + garbage collection. + + The function keeps a strong reference by design. It should be called in a + subprocess to not mark a test as "leaking a reference". + """ + + # Late CPython finalization: + # - finalize_interp_clear() + # - _PyInterpreterState_Clear(): Clear PyInterpreterState members + # (ex: codec_search_path, before_forkers) + # - clear os.register_at_fork() callbacks + # - clear codecs.register() callbacks + + ref_cycle = [obj] + ref_cycle.append(ref_cycle) + + # Store a reference in PyInterpreterState.codec_search_path + import codecs + def search_func(encoding): + return None + search_func.reference = ref_cycle + codecs.register(search_func) + + if hasattr(os, 'register_at_fork'): + # Store a reference in PyInterpreterState.before_forkers + def atfork_func(): + pass + atfork_func.reference = ref_cycle + os.register_at_fork(before=atfork_func) + + +def busy_retry(timeout, err_msg=None, /, *, error=True): + """ + Run the loop body until "break" stops the loop. + + After *timeout* seconds, raise an AssertionError if *error* is true, + or just stop if *error is false. + + Example: + + for _ in support.busy_retry(support.SHORT_TIMEOUT): + if check(): + break + + Example of error=False usage: + + for _ in support.busy_retry(support.SHORT_TIMEOUT, error=False): + if check(): + break + else: + raise RuntimeError('my custom error') + + """ + if timeout <= 0: + raise ValueError("timeout must be greater than zero") + + start_time = time.monotonic() + deadline = start_time + timeout + + while True: + yield + + if time.monotonic() >= deadline: + break + + if error: + dt = time.monotonic() - start_time + msg = f"timeout ({dt:.1f} seconds)" + if err_msg: + msg = f"{msg}: {err_msg}" + raise AssertionError(msg) + + +def sleeping_retry(timeout, err_msg=None, /, + *, init_delay=0.010, max_delay=1.0, error=True): + """ + Wait strategy that applies exponential backoff. + + Run the loop body until "break" stops the loop. Sleep at each loop + iteration, but not at the first iteration. The sleep delay is doubled at + each iteration (up to *max_delay* seconds). + + See busy_retry() documentation for the parameters usage. + + Example raising an exception after SHORT_TIMEOUT seconds: + + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if check(): + break + + Example of error=False usage: + + for _ in support.sleeping_retry(support.SHORT_TIMEOUT, error=False): + if check(): + break + else: + raise RuntimeError('my custom error') + """ + + delay = init_delay + for _ in busy_retry(timeout, err_msg, error=error): + yield + + time.sleep(delay) + delay = min(delay * 2, max_delay) + + +@contextlib.contextmanager +def adjust_int_max_str_digits(max_digits): + """Temporarily change the integer string conversion length limit.""" + current = sys.get_int_max_str_digits() + try: + sys.set_int_max_str_digits(max_digits) + yield + finally: + sys.set_int_max_str_digits(current) + +#For recursion tests, easily exceeds default recursion limit +EXCEEDS_RECURSION_LIMIT = 5000 diff --git a/Lib/test/support/ast_helper.py b/Lib/test/support/ast_helper.py new file mode 100644 index 00000000000..8a0415b6aae --- /dev/null +++ b/Lib/test/support/ast_helper.py @@ -0,0 +1,43 @@ +import ast + +class ASTTestMixin: + """Test mixing to have basic assertions for AST nodes.""" + + def assertASTEqual(self, ast1, ast2): + # Ensure the comparisons start at an AST node + self.assertIsInstance(ast1, ast.AST) + self.assertIsInstance(ast2, ast.AST) + + # An AST comparison routine modeled after ast.dump(), but + # instead of string building, it traverses the two trees + # in lock-step. + def traverse_compare(a, b, missing=object()): + if type(a) is not type(b): + self.fail(f"{type(a)!r} is not {type(b)!r}") + if isinstance(a, ast.AST): + for field in a._fields: + value1 = getattr(a, field, missing) + value2 = getattr(b, field, missing) + # Singletons are equal by definition, so further + # testing can be skipped. + if value1 is not value2: + traverse_compare(value1, value2) + elif isinstance(a, list): + try: + for node1, node2 in zip(a, b, strict=True): + traverse_compare(node1, node2) + except ValueError: + # Attempt a "pretty" error ala assertSequenceEqual() + len1 = len(a) + len2 = len(b) + if len1 > len2: + what = "First" + diff = len1 - len2 + else: + what = "Second" + diff = len2 - len1 + msg = f"{what} list contains {diff} additional elements." + raise self.failureException(msg) from None + elif a != b: + self.fail(f"{a!r} != {b!r}") + traverse_compare(ast1, ast2) diff --git a/Lib/test/support/_asynchat.py b/Lib/test/support/asynchat.py similarity index 97% rename from Lib/test/support/_asynchat.py rename to Lib/test/support/asynchat.py index 941cc1d22e6..38c47a1fda6 100644 --- a/Lib/test/support/_asynchat.py +++ b/Lib/test/support/asynchat.py @@ -1,3 +1,8 @@ +# TODO: This module was deprecated and removed from CPython 3.12 +# Now it is a test-only helper. Any attempts to rewrite exising tests that +# are using this module and remove it completely are appreciated! +# See: https://github.com/python/cpython/issues/72719 + # -*- Mode: Python; tab-width: 4 -*- # Id: asynchat.py,v 2.26 2000/09/07 22:29:26 rushing Exp # Author: Sam Rushing @@ -45,9 +50,11 @@ command will be accumulated (using your own 'collect_incoming_data' method) up to the terminator, and then control will be returned to you - by calling your self.found_terminator() method. """ -from test.support import _asyncore as asyncore + from collections import deque +from test.support import asyncore + class async_chat(asyncore.dispatcher): """This is an abstract class. You must derive from this class, and add diff --git a/Lib/test/support/_asyncore.py b/Lib/test/support/asyncore.py similarity index 98% rename from Lib/test/support/_asyncore.py rename to Lib/test/support/asyncore.py index 7863efaea66..401fa60bcf3 100644 --- a/Lib/test/support/_asyncore.py +++ b/Lib/test/support/asyncore.py @@ -1,3 +1,8 @@ +# TODO: This module was deprecated and removed from CPython 3.12 +# Now it is a test-only helper. Any attempts to rewrite exising tests that +# are using this module and remove it completely are appreciated! +# See: https://github.com/python/cpython/issues/72719 + # -*- Mode: Python -*- # Id: asyncore.py,v 2.51 2000/09/07 22:29:26 rushing Exp # Author: Sam Rushing diff --git a/Lib/test/support/bytecode_helper.py b/Lib/test/support/bytecode_helper.py index 471d4a68f91..65ae7a227ba 100644 --- a/Lib/test/support/bytecode_helper.py +++ b/Lib/test/support/bytecode_helper.py @@ -3,6 +3,7 @@ import unittest import dis import io +from _testinternalcapi import compiler_codegen, optimize_cfg _UNSPECIFIED = object() @@ -16,6 +17,7 @@ class BytecodeTestCase(unittest.TestCase): def assertInBytecode(self, x, opname, argval=_UNSPECIFIED): """Returns instr if opname is found, otherwise throws AssertionError""" + self.assertIn(opname, dis.opmap) for instr in dis.get_instructions(x): if instr.opname == opname: if argval is _UNSPECIFIED or instr.argval == argval: @@ -30,6 +32,7 @@ class BytecodeTestCase(unittest.TestCase): def assertNotInBytecode(self, x, opname, argval=_UNSPECIFIED): """Throws AssertionError if opname is found""" + self.assertIn(opname, dis.opmap) for instr in dis.get_instructions(x): if instr.opname == opname: disassembly = self.get_disassembly_as_string(x) @@ -40,3 +43,106 @@ class BytecodeTestCase(unittest.TestCase): msg = '(%s,%r) occurs in bytecode:\n%s' msg = msg % (opname, argval, disassembly) self.fail(msg) + +class CompilationStepTestCase(unittest.TestCase): + + HAS_ARG = set(dis.hasarg) + HAS_TARGET = set(dis.hasjrel + dis.hasjabs + dis.hasexc) + HAS_ARG_OR_TARGET = HAS_ARG.union(HAS_TARGET) + + def setUp(self): + self.last_label = 0 + + def Label(self): + self.last_label += 1 + return self.last_label + + def assertInstructionsMatch(self, actual_, expected_): + # get two lists where each entry is a label or + # an instruction tuple. Compare them, while mapping + # each actual label to a corresponding expected label + # based on their locations. + + self.assertIsInstance(actual_, list) + self.assertIsInstance(expected_, list) + + actual = self.normalize_insts(actual_) + expected = self.normalize_insts(expected_) + self.assertEqual(len(actual), len(expected)) + + # compare instructions + for act, exp in zip(actual, expected): + if isinstance(act, int): + self.assertEqual(exp, act) + continue + self.assertIsInstance(exp, tuple) + self.assertIsInstance(act, tuple) + # crop comparison to the provided expected values + if len(act) > len(exp): + act = act[:len(exp)] + self.assertEqual(exp, act) + + def normalize_insts(self, insts): + """ Map labels to instruction index. + Remove labels which are not used as jump targets. + Map opcodes to opnames. + """ + labels_map = {} + targets = set() + idx = 1 + for item in insts: + assert isinstance(item, (int, tuple)) + if isinstance(item, tuple): + opcode, oparg, *_ = item + if dis.opmap.get(opcode, opcode) in self.HAS_TARGET: + targets.add(oparg) + idx += 1 + elif isinstance(item, int): + assert item not in labels_map, "label reused" + labels_map[item] = idx + + res = [] + for item in insts: + if isinstance(item, int) and item in targets: + if not res or labels_map[item] != res[-1]: + res.append(labels_map[item]) + elif isinstance(item, tuple): + opcode, oparg, *loc = item + opcode = dis.opmap.get(opcode, opcode) + if opcode in self.HAS_TARGET: + arg = labels_map[oparg] + else: + arg = oparg if opcode in self.HAS_TARGET else None + opcode = dis.opname[opcode] + res.append((opcode, arg, *loc)) + return res + + +class CodegenTestCase(CompilationStepTestCase): + + def generate_code(self, ast): + insts = compiler_codegen(ast, "my_file.py", 0) + return insts + + +class CfgOptimizationTestCase(CompilationStepTestCase): + + def complete_insts_info(self, insts): + # fill in omitted fields in location, and oparg 0 for ops with no arg. + instructions = [] + for item in insts: + if isinstance(item, int): + instructions.append(item) + else: + assert isinstance(item, tuple) + inst = list(reversed(item)) + opcode = dis.opmap[inst.pop()] + oparg = inst.pop() if opcode in self.HAS_ARG_OR_TARGET else 0 + loc = inst + [-1] * (4 - len(inst)) + instructions.append((opcode, oparg, *loc)) + return instructions + + def get_optimized(self, insts, consts): + insts = self.complete_insts_info(insts) + insts = optimize_cfg(insts, consts) + return insts, consts diff --git a/Lib/test/support/import_helper.py b/Lib/test/support/import_helper.py index 9bce2989524..63a8a7952db 100644 --- a/Lib/test/support/import_helper.py +++ b/Lib/test/support/import_helper.py @@ -3,6 +3,7 @@ import _imp import importlib import importlib.util import os +import shutil import sys import unittest import warnings @@ -59,7 +60,7 @@ def make_legacy_pyc(source): pyc_file = importlib.util.cache_from_source(source) up_one = os.path.dirname(os.path.abspath(source)) legacy_pyc = os.path.join(up_one, source + 'c') - os.rename(pyc_file, legacy_pyc) + shutil.move(pyc_file, legacy_pyc) return legacy_pyc @@ -245,3 +246,11 @@ def modules_cleanup(oldmodules): # do currently). Implicitly imported *real* modules should be left alone # (see issue 10556). sys.modules.update(oldmodules) + + +def mock_register_at_fork(func): + # bpo-30599: Mock os.register_at_fork() when importing the random module, + # since this function doesn't allow to unregister callbacks and would leak + # memory. + from unittest import mock + return mock.patch('os.register_at_fork', create=True)(func) diff --git a/Lib/test/support/os_helper.py b/Lib/test/support/os_helper.py index ce01417ed07..2d4356a1191 100644 --- a/Lib/test/support/os_helper.py +++ b/Lib/test/support/os_helper.py @@ -11,11 +11,7 @@ import warnings # Filename used for testing -if os.name == 'java': - # Jython disallows @ in module names - TESTFN_ASCII = '$test' -else: - TESTFN_ASCII = '@test' +TESTFN_ASCII = '@test' # Disambiguate TESTFN for parallel testing, while letting it remain a valid # module name. @@ -49,8 +45,8 @@ if os.name == 'nt': 'encoding (%s). Unicode filename tests may not be effective' % (TESTFN_UNENCODABLE, sys.getfilesystemencoding())) TESTFN_UNENCODABLE = None -# Mac OS X denies unencodable filenames (invalid utf-8) -elif sys.platform != 'darwin': +# macOS and Emscripten deny unencodable filenames (invalid utf-8) +elif sys.platform not in {'darwin', 'emscripten', 'wasi'}: try: # ascii and utf-8 cannot encode the byte 0xff b'\xff'.decode(sys.getfilesystemencoding()) @@ -141,6 +137,11 @@ for name in ( try: name.decode(sys.getfilesystemencoding()) except UnicodeDecodeError: + try: + name.decode(sys.getfilesystemencoding(), + sys.getfilesystemencodeerrors()) + except UnicodeDecodeError: + continue TESTFN_UNDECODABLE = os.fsencode(TESTFN_ASCII) + name break @@ -171,9 +172,13 @@ def can_symlink(): global _can_symlink if _can_symlink is not None: return _can_symlink - symlink_path = TESTFN + "can_symlink" + # WASI / wasmtime prevents symlinks with absolute paths, see man + # openat2(2) RESOLVE_BENEATH. Almost all symlink tests use absolute + # paths. Skip symlink tests on WASI for now. + src = os.path.abspath(TESTFN) + symlink_path = src + "can_symlink" try: - os.symlink(TESTFN, symlink_path) + os.symlink(src, symlink_path) can = True except (OSError, NotImplementedError, AttributeError): can = False @@ -233,6 +238,84 @@ def skip_unless_xattr(test): return test if ok else unittest.skip(msg)(test) +_can_chmod = None + +def can_chmod(): + global _can_chmod + if _can_chmod is not None: + return _can_chmod + if not hasattr(os, "chown"): + _can_chmod = False + return _can_chmod + try: + with open(TESTFN, "wb") as f: + try: + os.chmod(TESTFN, 0o777) + mode1 = os.stat(TESTFN).st_mode + os.chmod(TESTFN, 0o666) + mode2 = os.stat(TESTFN).st_mode + except OSError as e: + can = False + else: + can = stat.S_IMODE(mode1) != stat.S_IMODE(mode2) + finally: + unlink(TESTFN) + _can_chmod = can + return can + + +def skip_unless_working_chmod(test): + """Skip tests that require working os.chmod() + + WASI SDK 15.0 cannot change file mode bits. + """ + ok = can_chmod() + msg = "requires working os.chmod()" + return test if ok else unittest.skip(msg)(test) + + +# Check whether the current effective user has the capability to override +# DAC (discretionary access control). Typically user root is able to +# bypass file read, write, and execute permission checks. The capability +# is independent of the effective user. See capabilities(7). +_can_dac_override = None + +def can_dac_override(): + global _can_dac_override + + if not can_chmod(): + _can_dac_override = False + if _can_dac_override is not None: + return _can_dac_override + + try: + with open(TESTFN, "wb") as f: + os.chmod(TESTFN, 0o400) + try: + with open(TESTFN, "wb"): + pass + except OSError: + _can_dac_override = False + else: + _can_dac_override = True + finally: + unlink(TESTFN) + + return _can_dac_override + + +def skip_if_dac_override(test): + ok = not can_dac_override() + msg = "incompatible with CAP_DAC_OVERRIDE" + return test if ok else unittest.skip(msg)(test) + + +def skip_unless_dac_override(test): + ok = can_dac_override() + msg = "requires CAP_DAC_OVERRIDE" + return test if ok else unittest.skip(msg)(test) + + def unlink(filename): try: _unlink(filename) @@ -455,6 +538,20 @@ def create_empty_file(filename): os.close(fd) +@contextlib.contextmanager +def open_dir_fd(path): + """Open a file descriptor to a directory.""" + assert os.path.isdir(path) + flags = os.O_RDONLY + if hasattr(os, "O_DIRECTORY"): + flags |= os.O_DIRECTORY + dir_fd = os.open(path, flags) + try: + yield dir_fd + finally: + os.close(dir_fd) + + def fs_is_case_insensitive(directory): """Detects if the file system for the specified directory is case-insensitive.""" @@ -471,7 +568,7 @@ def fs_is_case_insensitive(directory): class FakePath: - """Simple implementing of the path protocol. + """Simple implementation of the path protocol. """ def __init__(self, path): self.path = path @@ -491,7 +588,7 @@ class FakePath: def fd_count(): """Count the number of open file descriptors. """ - if sys.platform.startswith(('linux', 'freebsd')): + if sys.platform.startswith(('linux', 'freebsd', 'emscripten')): try: names = os.listdir("/proc/self/fd") # Subtract one because listdir() internally opens a file @@ -557,6 +654,11 @@ if hasattr(os, "umask"): yield finally: os.umask(oldmask) +else: + @contextlib.contextmanager + def temp_umask(umask): + """no-op on platforms without umask()""" + yield class EnvironmentVarGuard(collections.abc.MutableMapping): diff --git a/Lib/test/support/script_helper.py b/Lib/test/support/script_helper.py index 6d699c8486c..c2b43f4060e 100644 --- a/Lib/test/support/script_helper.py +++ b/Lib/test/support/script_helper.py @@ -42,6 +42,10 @@ def interpreter_requires_environment(): if 'PYTHONHOME' in os.environ: __cached_interp_requires_environment = True return True + # cannot run subprocess, assume we don't need it + if not support.has_subprocess_support: + __cached_interp_requires_environment = False + return False # Try running an interpreter with -E to see if it works or not. try: @@ -87,6 +91,7 @@ class _PythonRunResult(collections.namedtuple("_PythonRunResult", # Executing the interpreter in a subprocess +@support.requires_subprocess() def run_python_until_end(*args, **env_vars): env_required = interpreter_requires_environment() cwd = env_vars.pop('__cwd', None) @@ -139,6 +144,7 @@ def run_python_until_end(*args, **env_vars): return _PythonRunResult(rc, out, err), cmd_line +@support.requires_subprocess() def _assert_python(expected_success, /, *args, **env_vars): res, cmd_line = run_python_until_end(*args, **env_vars) if (res.rc and expected_success) or (not res.rc and not expected_success): @@ -171,6 +177,7 @@ def assert_python_failure(*args, **env_vars): return _assert_python(False, *args, **env_vars) +@support.requires_subprocess() def spawn_python(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw): """Run a Python subprocess with the given arguments. @@ -273,6 +280,7 @@ def make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, return zip_name, os.path.join(zip_name, script_name_in_zip) +@support.requires_subprocess() def run_test_script(script): # use -u to try to get the full output if the test hangs or crash if support.verbose: diff --git a/Lib/test/support/socket_helper.py b/Lib/test/support/socket_helper.py index b51677383eb..d2960c9e333 100644 --- a/Lib/test/support/socket_helper.py +++ b/Lib/test/support/socket_helper.py @@ -1,16 +1,21 @@ import contextlib import errno +import os.path import socket -import unittest import sys +import tempfile +import unittest from .. import support - +from . import warnings_helper HOST = "localhost" HOSTv4 = "127.0.0.1" HOSTv6 = "::1" +# WASI SDK 15.0 does not provide gethostname, stub raises OSError ENOTSUP. +has_gethostname = not support.is_wasi + def find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM): """Returns an unused port that should be suitable for binding. This is @@ -190,7 +195,7 @@ _NOT_SET = object() def transient_internet(resource_name, *, timeout=_NOT_SET, errnos=()): """Return a context manager that raises ResourceDenied when various issues with the internet connection manifest themselves as exceptions.""" - import nntplib + nntplib = warnings_helper.import_deprecated("nntplib") import urllib.error if timeout is _NOT_SET: timeout = support.INTERNET_TIMEOUT @@ -256,7 +261,7 @@ def transient_internet(resource_name, *, timeout=_NOT_SET, errnos=()): err = a[0] # The error can also be wrapped as args[1]: # except socket.error as msg: - # raise OSError('socket error', msg).with_traceback(sys.exc_info()[2]) + # raise OSError('socket error', msg) from msg elif len(a) >= 2 and isinstance(a[1], OSError): err = a[1] else: @@ -267,3 +272,14 @@ def transient_internet(resource_name, *, timeout=_NOT_SET, errnos=()): # __cause__ or __context__? finally: socket.setdefaulttimeout(old_timeout) + + +def create_unix_domain_name(): + """ + Create a UNIX domain name: socket.bind() argument of a AF_UNIX socket. + + Return a path relative to the current directory to get a short path + (around 27 ASCII characters). + """ + return tempfile.mktemp(prefix="test_python_", suffix='.sock', + dir=os.path.curdir) diff --git a/Lib/test/support/threading_helper.py b/Lib/test/support/threading_helper.py index 92a64e8354a..b9973c8bf5c 100644 --- a/Lib/test/support/threading_helper.py +++ b/Lib/test/support/threading_helper.py @@ -4,6 +4,7 @@ import functools import sys import threading import time +import unittest from test import support @@ -87,19 +88,17 @@ def wait_threads_exit(timeout=None): yield finally: start_time = time.monotonic() - deadline = start_time + timeout - while True: + for _ in support.sleeping_retry(timeout, error=False): + support.gc_collect() count = _thread._count() if count <= old_count: break - if time.monotonic() > deadline: - dt = time.monotonic() - start_time - msg = (f"wait_threads() failed to cleanup {count - old_count} " - f"threads after {dt:.1f} seconds " - f"(count: {count}, old count: {old_count})") - raise AssertionError(msg) - time.sleep(0.010) - support.gc_collect() + else: + dt = time.monotonic() - start_time + msg = (f"wait_threads() failed to cleanup {count - old_count} " + f"threads after {dt:.1f} seconds " + f"(count: {count}, old count: {old_count})") + raise AssertionError(msg) def join_thread(thread, timeout=None): @@ -207,3 +206,37 @@ class catch_threading_exception: del self.exc_value del self.exc_traceback del self.thread + + +def _can_start_thread() -> bool: + """Detect whether Python can start new threads. + + Some WebAssembly platforms do not provide a working pthread + implementation. Thread support is stubbed and any attempt + to create a new thread fails. + + - wasm32-wasi does not have threading. + - wasm32-emscripten can be compiled with or without pthread + support (-s USE_PTHREADS / __EMSCRIPTEN_PTHREADS__). + """ + if sys.platform == "emscripten": + return sys._emscripten_info.pthreads + elif sys.platform == "wasi": + return False + else: + # assume all other platforms have working thread support. + return True + +can_start_thread = _can_start_thread() + +def requires_working_threading(*, module=False): + """Skip tests or modules that require working threading. + + Can be used as a function/class decorator or to skip an entire module. + """ + msg = "requires threading support" + if module: + if not can_start_thread: + raise unittest.SkipTest(msg) + else: + return unittest.skipUnless(can_start_thread, msg) diff --git a/Lib/test/support/warnings_helper.py b/Lib/test/support/warnings_helper.py index a024fbe5bea..28e96f88b24 100644 --- a/Lib/test/support/warnings_helper.py +++ b/Lib/test/support/warnings_helper.py @@ -1,10 +1,18 @@ import contextlib import functools +import importlib import re import sys import warnings +def import_deprecated(name): + """Import *name* while suppressing DeprecationWarning.""" + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=DeprecationWarning) + return importlib.import_module(name) + + def check_syntax_warning(testcase, statement, errtext='', *, lineno=1, offset=None): # Test also that a warning is emitted only once. diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index 15f42d2d114..ecf73b3ad1b 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -3,6 +3,19 @@ from test import support from test.support import warnings_helper import os import sys +import types + +try: + import _multiprocessing +except ModuleNotFoundError: + _multiprocessing = None + + +if support.check_sanitizer(address=True, memory=True): + # bpo-46633: test___all__ is skipped because importing some modules + # directly can trigger known problems with ASAN (like tk or crypt). + raise unittest.SkipTest("workaround ASAN build issues on loading tests " + "like tk or crypt") class NoAll(RuntimeError): @@ -14,9 +27,21 @@ class FailedImport(RuntimeError): class AllTest(unittest.TestCase): + def setUp(self): + # concurrent.futures uses a __getattr__ hook. Its __all__ triggers + # import of a submodule, which fails when _multiprocessing is not + # available. + if _multiprocessing is None: + sys.modules["_multiprocessing"] = types.ModuleType("_multiprocessing") + + def tearDown(self): + if _multiprocessing is None: + sys.modules.pop("_multiprocessing") + def check_all(self, modname): names = {} with warnings_helper.check_warnings( + (f".*{modname}", DeprecationWarning), (".* (module|package)", DeprecationWarning), (".* (module|package)", PendingDeprecationWarning), ("", ResourceWarning), @@ -75,10 +100,9 @@ class AllTest(unittest.TestCase): '__future__', ]) - if not sys.platform.startswith('java'): - # In case _socket fails to build, make this test fail more gracefully - # than an AttributeError somewhere deep in CGIHTTPServer. - import _socket + # In case _socket fails to build, make this test fail more gracefully + # than an AttributeError somewhere deep in CGIHTTPServer. + import _socket ignored = [] failed_imports = [] diff --git a/Lib/test/test__locale.py b/Lib/test/test__locale.py index 59a00bad7d9..0947464bb8c 100644 --- a/Lib/test/test__locale.py +++ b/Lib/test/test__locale.py @@ -9,6 +9,8 @@ import sys import unittest from platform import uname +from test import support + if uname().system == "Darwin": maj, min, mic = [int(part) for part in uname().release.split(".")] if (maj, min, mic) < (8, 0, 0): @@ -41,7 +43,7 @@ def setUpModule(): locale.setlocale(locale.LC_ALL, loc) except Error: continue - encoding = locale.getpreferredencoding(False) + encoding = locale.getencoding() try: localeconv() except Exception as err: @@ -106,6 +108,10 @@ class _LocaleTests(unittest.TestCase): return True @unittest.skipUnless(nl_langinfo, "nl_langinfo is not available") + @unittest.skipIf( + support.is_emscripten or support.is_wasi, + "musl libc issue on Emscripten, bpo-46390" + ) def test_lc_numeric_nl_langinfo(self): # Test nl_langinfo against known values tested = False @@ -122,6 +128,10 @@ class _LocaleTests(unittest.TestCase): if not tested: self.skipTest('no suitable locales') + @unittest.skipIf( + support.is_emscripten or support.is_wasi, + "musl libc issue on Emscripten, bpo-46390" + ) def test_lc_numeric_localeconv(self): # Test localeconv against known values tested = False diff --git a/Lib/test/test__opcode.py b/Lib/test/test__opcode.py index 6bbab539903..db831069c7a 100644 --- a/Lib/test/test__opcode.py +++ b/Lib/test/test__opcode.py @@ -11,7 +11,6 @@ class OpcodeTests(unittest.TestCase): def test_stack_effect(self): self.assertEqual(stack_effect(dis.opmap['POP_TOP']), -1) - self.assertEqual(stack_effect(dis.opmap['DUP_TOP_TWO']), 2) self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 0), -1) self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 1), -1) self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 3), -2) @@ -19,9 +18,10 @@ class OpcodeTests(unittest.TestCase): self.assertRaises(ValueError, stack_effect, dis.opmap['BUILD_SLICE']) self.assertRaises(ValueError, stack_effect, dis.opmap['POP_TOP'], 0) # All defined opcodes - for name, code in dis.opmap.items(): + has_arg = dis.hasarg + for name, code in filter(lambda item: item[0] not in dis.deoptmap, dis.opmap.items()): with self.subTest(opname=name): - if code < dis.HAVE_ARGUMENT: + if code not in has_arg: stack_effect(code) self.assertRaises(ValueError, stack_effect, code, 0) else: @@ -40,17 +40,19 @@ class OpcodeTests(unittest.TestCase): self.assertEqual(stack_effect(JUMP_IF_TRUE_OR_POP, 0, jump=False), -1) FOR_ITER = dis.opmap['FOR_ITER'] self.assertEqual(stack_effect(FOR_ITER, 0), 1) - self.assertEqual(stack_effect(FOR_ITER, 0, jump=True), -1) + self.assertEqual(stack_effect(FOR_ITER, 0, jump=True), 1) self.assertEqual(stack_effect(FOR_ITER, 0, jump=False), 1) JUMP_FORWARD = dis.opmap['JUMP_FORWARD'] self.assertEqual(stack_effect(JUMP_FORWARD, 0), 0) self.assertEqual(stack_effect(JUMP_FORWARD, 0, jump=True), 0) self.assertEqual(stack_effect(JUMP_FORWARD, 0, jump=False), 0) # All defined opcodes + has_arg = dis.hasarg + has_exc = dis.hasexc has_jump = dis.hasjabs + dis.hasjrel - for name, code in dis.opmap.items(): + for name, code in filter(lambda item: item[0] not in dis.deoptmap, dis.opmap.items()): with self.subTest(opname=name): - if code < dis.HAVE_ARGUMENT: + if code not in has_arg: common = stack_effect(code) jump = stack_effect(code, jump=True) nojump = stack_effect(code, jump=False) @@ -58,7 +60,7 @@ class OpcodeTests(unittest.TestCase): common = stack_effect(code, 0) jump = stack_effect(code, 0, jump=True) nojump = stack_effect(code, 0, jump=False) - if code in has_jump: + if code in has_jump or code in has_exc: self.assertEqual(common, max(jump, nojump)) else: self.assertEqual(jump, common) @@ -70,9 +72,10 @@ class SpecializationStatsTests(unittest.TestCase): stat_names = opcode._specialization_stats specialized_opcodes = [ - op[:-len("_ADAPTIVE")].lower() for - op in opcode._specialized_instructions - if op.endswith("_ADAPTIVE")] + op.lower() + for op in opcode._specializations + if opcode._inline_cache_entries[opcode.opmap[op]] + ] self.assertIn('load_attr', specialized_opcodes) self.assertIn('binary_subscr', specialized_opcodes) @@ -82,13 +85,13 @@ class SpecializationStatsTests(unittest.TestCase): self.assertCountEqual(stats.keys(), specialized_opcodes) self.assertCountEqual( stats['load_attr'].keys(), - stat_names + ['specialization_failure_kinds']) + stat_names + ['failure_kinds']) for sn in stat_names: self.assertIsInstance(stats['load_attr'][sn], int) self.assertIsInstance( - stats['load_attr']['specialization_failure_kinds'], + stats['load_attr']['failure_kinds'], tuple) - for v in stats['load_attr']['specialization_failure_kinds']: + for v in stats['load_attr']['failure_kinds']: self.assertIsInstance(v, int) diff --git a/Lib/test/test__osx_support.py b/Lib/test/test__osx_support.py index 907ae27d529..4a14cb35213 100644 --- a/Lib/test/test__osx_support.py +++ b/Lib/test/test__osx_support.py @@ -19,8 +19,7 @@ class Test_OSXSupport(unittest.TestCase): self.maxDiff = None self.prog_name = 'bogus_program_xxxx' self.temp_path_dir = os.path.abspath(os.getcwd()) - self.env = os_helper.EnvironmentVarGuard() - self.addCleanup(self.env.__exit__) + self.env = self.enterContext(os_helper.EnvironmentVarGuard()) for cv in ('CFLAGS', 'LDFLAGS', 'CPPFLAGS', 'BASECFLAGS', 'BLDSHARED', 'LDSHARED', 'CC', 'CXX', 'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS', diff --git a/Lib/test/test__xxsubinterpreters.py b/Lib/test/test__xxsubinterpreters.py index 177a8a64a43..18900bb9f71 100644 --- a/Lib/test/test__xxsubinterpreters.py +++ b/Lib/test/test__xxsubinterpreters.py @@ -45,12 +45,11 @@ def _wait_for_interp_to_run(interp, timeout=None): # run subinterpreter eariler than the main thread in multiprocess. if timeout is None: timeout = support.SHORT_TIMEOUT - start_time = time.monotonic() - deadline = start_time + timeout - while not interpreters.is_running(interp): - if time.monotonic() > deadline: - raise RuntimeError('interp is not running') - time.sleep(0.010) + for _ in support.sleeping_retry(timeout, error=False): + if interpreters.is_running(interp): + break + else: + raise RuntimeError('interp is not running') @contextlib.contextmanager @@ -296,8 +295,8 @@ def clean_up_channels(): class TestBase(unittest.TestCase): def tearDown(self): - clean_up_interpreters() clean_up_channels() + clean_up_interpreters() ################################## @@ -387,7 +386,6 @@ class ShareableTypeTests(unittest.TestCase): self._assert_values([ b'spam', 9999, - self.cid, ]) def test_bytes(self): @@ -413,6 +411,15 @@ class ShareableTypeTests(unittest.TestCase): interpreters.channel_send(self.cid, i) +class ModuleTests(TestBase): + + def test_import_in_interpreter(self): + _run_output( + interpreters.create(), + 'import _xxsubinterpreters as _interpreters', + ) + + ################################## # interpreter tests @@ -802,7 +809,7 @@ class RunStringTests(TestBase): self.assertEqual(out, 'it worked!') def test_create_thread(self): - subinterp = interpreters.create(isolated=False) + subinterp = interpreters.create() script, file = _captured_script(""" import threading def f(): @@ -818,7 +825,62 @@ class RunStringTests(TestBase): self.assertEqual(out, 'it worked!') - @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()") + def test_create_daemon_thread(self): + with self.subTest('isolated'): + expected = 'spam spam spam spam spam' + subinterp = interpreters.create(isolated=True) + script, file = _captured_script(f""" + import threading + def f(): + print('it worked!', end='') + + try: + t = threading.Thread(target=f, daemon=True) + t.start() + t.join() + except RuntimeError: + print('{expected}', end='') + """) + with file: + interpreters.run_string(subinterp, script) + out = file.read() + + self.assertEqual(out, expected) + + with self.subTest('not isolated'): + subinterp = interpreters.create(isolated=False) + script, file = _captured_script(""" + import threading + def f(): + print('it worked!', end='') + + t = threading.Thread(target=f, daemon=True) + t.start() + t.join() + """) + with file: + interpreters.run_string(subinterp, script) + out = file.read() + + self.assertEqual(out, 'it worked!') + + def test_os_exec(self): + expected = 'spam spam spam spam spam' + subinterp = interpreters.create() + script, file = _captured_script(f""" + import os, sys + try: + os.execl(sys.executable) + except RuntimeError: + print('{expected}', end='') + """) + with file: + interpreters.run_string(subinterp, script) + out = file.read() + + self.assertEqual(out, expected) + + @support.requires_fork() def test_fork(self): import tempfile with tempfile.NamedTemporaryFile('w+', encoding="utf-8") as file: @@ -1159,6 +1221,18 @@ class ChannelIDTests(TestBase): self.assertFalse(cid1 != cid2) self.assertTrue(cid1 != cid3) + def test_shareable(self): + chan = interpreters.channel_create() + + obj = interpreters.channel_create() + interpreters.channel_send(chan, obj) + got = interpreters.channel_recv(chan) + + self.assertEqual(got, obj) + self.assertIs(type(got), type(obj)) + # XXX Check the following in the channel tests? + #self.assertIsNot(got, obj) + class ChannelTests(TestBase): @@ -1491,6 +1565,19 @@ class ChannelTests(TestBase): self.assertEqual(obj5, b'eggs') self.assertIs(obj6, default) + def test_recv_sending_interp_destroyed(self): + cid = interpreters.channel_create() + interp = interpreters.create() + interpreters.run_string(interp, dedent(f""" + import _xxsubinterpreters as _interpreters + _interpreters.channel_send({cid}, b'spam') + """)) + interpreters.destroy(interp) + + with self.assertRaisesRegex(RuntimeError, + 'unrecognized interpreter ID'): + interpreters.channel_recv(cid) + def test_run_string_arg_unresolved(self): cid = interpreters.channel_create() interp = interpreters.create() diff --git a/Lib/test/test_abc.py b/Lib/test/test_abc.py index c1d750dba83..86f31a9acb4 100644 --- a/Lib/test/test_abc.py +++ b/Lib/test/test_abc.py @@ -154,7 +154,7 @@ def test_factory(abc_ABCMeta, abc_get_cache_token): @abc.abstractmethod def method_one(self): pass - msg = r"class C with abstract method method_one" + msg = r"class C without an implementation for abstract method 'method_one'" self.assertRaisesRegex(TypeError, msg, C) def test_object_new_with_many_abstractmethods(self): @@ -165,7 +165,7 @@ def test_factory(abc_ABCMeta, abc_get_cache_token): @abc.abstractmethod def method_two(self): pass - msg = r"class C with abstract methods method_one, method_two" + msg = r"class C without an implementation for abstract methods 'method_one', 'method_two'" self.assertRaisesRegex(TypeError, msg, C) def test_abstractmethod_integration(self): @@ -535,7 +535,7 @@ def test_factory(abc_ABCMeta, abc_get_cache_token): A.foo = updated_foo abc.update_abstractmethods(A) self.assertEqual(A.__abstractmethods__, {'foo', 'bar'}) - msg = "class A with abstract methods bar, foo" + msg = "class A without an implementation for abstract methods 'bar', 'foo'" self.assertRaisesRegex(TypeError, msg, A) def test_update_implementation(self): @@ -547,7 +547,7 @@ def test_factory(abc_ABCMeta, abc_get_cache_token): class B(A): pass - msg = "class B with abstract method foo" + msg = "class B without an implementation for abstract method 'foo'" self.assertRaisesRegex(TypeError, msg, B) self.assertEqual(B.__abstractmethods__, {'foo'}) @@ -605,7 +605,7 @@ def test_factory(abc_ABCMeta, abc_get_cache_token): abc.update_abstractmethods(B) - msg = "class B with abstract method foo" + msg = "class B without an implementation for abstract method 'foo'" self.assertRaisesRegex(TypeError, msg, B) def test_update_layered_implementation(self): @@ -627,7 +627,7 @@ def test_factory(abc_ABCMeta, abc_get_cache_token): abc.update_abstractmethods(C) - msg = "class C with abstract method foo" + msg = "class C without an implementation for abstract method 'foo'" self.assertRaisesRegex(TypeError, msg, C) def test_update_multi_inheritance(self): @@ -668,6 +668,19 @@ def test_factory(abc_ABCMeta, abc_get_cache_token): class Receiver(ReceivesClassKwargs, abc_ABC, x=1, y=2, z=3): pass self.assertEqual(saved_kwargs, dict(x=1, y=2, z=3)) + + def test_positional_only_and_kwonlyargs_with_init_subclass(self): + saved_kwargs = {} + + class A: + def __init_subclass__(cls, **kwargs): + super().__init_subclass__() + saved_kwargs.update(kwargs) + + class B(A, metaclass=abc_ABCMeta, name="test"): + pass + self.assertEqual(saved_kwargs, dict(name="test")) + return TestLegacyAPI, TestABC, TestABCWithInitSubclass TestLegacyAPI_Py, TestABC_Py, TestABCWithInitSubclass_Py = test_factory(abc.ABCMeta, diff --git a/Lib/test/test_aifc.py b/Lib/test/test_aifc.py index fb6da4136f4..d3863d4915d 100644 --- a/Lib/test/test_aifc.py +++ b/Lib/test/test_aifc.py @@ -1,14 +1,17 @@ from test.support import findfile from test.support.os_helper import TESTFN, unlink -from test.support.warnings_helper import check_no_resource_warning +from test.support.warnings_helper import check_no_resource_warning, import_deprecated import unittest from unittest import mock from test import audiotests -from audioop import byteswap import io import sys import struct -import aifc + + +aifc = import_deprecated("aifc") +audioop = import_deprecated("audioop") + class AifcTest(audiotests.AudioWriteTests, audiotests.AudioTestsWithSourceFile): @@ -121,7 +124,7 @@ class AifcULAWTest(AifcTest, unittest.TestCase): E5040CBC 617C0A3C 08BC0A3C 2C7C0B3C 517C0E3C 8A8410FC B6840EBC 457C0A3C \ """) if sys.byteorder != 'big': - frames = byteswap(frames, 2) + frames = audioop.byteswap(frames, 2) class AifcALAWTest(AifcTest, unittest.TestCase): @@ -142,7 +145,7 @@ class AifcALAWTest(AifcTest, unittest.TestCase): E4800CC0 62000A40 08C00A40 2B000B40 52000E40 8A001180 B6000EC0 46000A40 \ """) if sys.byteorder != 'big': - frames = byteswap(frames, 2) + frames = audioop.byteswap(frames, 2) class AifcMiscTest(unittest.TestCase): diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index f3edde3de8e..cabb2f83769 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -1,6 +1,8 @@ # Author: Steven J. Bethard . import inspect +import io +import operator import os import shutil import stat @@ -9,13 +11,29 @@ import textwrap import tempfile import unittest import argparse - -from io import StringIO +import warnings from test.support import os_helper from unittest import mock -class StdIOBuffer(StringIO): - pass + + +class StdIOBuffer(io.TextIOWrapper): + '''Replacement for writable io.StringIO that behaves more like real file + + Unlike StringIO, provides a buffer attribute that holds the underlying + binary data, allowing it to replace sys.stdout/sys.stderr in more + contexts. + ''' + + def __init__(self, initial_value='', newline='\n'): + initial_value = initial_value.encode('utf-8') + super().__init__(io.BufferedWriter(io.BytesIO(initial_value)), + 'utf-8', newline=newline) + + def getvalue(self): + self.flush() + return self.buffer.raw.getvalue().decode('utf-8') + class TestCase(unittest.TestCase): @@ -23,11 +41,11 @@ class TestCase(unittest.TestCase): # The tests assume that line wrapping occurs at 80 columns, but this # behaviour can be overridden by setting the COLUMNS environment # variable. To ensure that this width is used, set COLUMNS to 80. - env = os_helper.EnvironmentVarGuard() + env = self.enterContext(os_helper.EnvironmentVarGuard()) env['COLUMNS'] = '80' - self.addCleanup(env.__exit__) +@os_helper.skip_unless_working_chmod class TempDirMixin(object): def setUp(self): @@ -42,11 +60,14 @@ class TempDirMixin(object): os.chmod(os.path.join(self.temp_dir, name), stat.S_IWRITE) shutil.rmtree(self.temp_dir, True) - def create_readonly_file(self, filename): + def create_writable_file(self, filename): file_path = os.path.join(self.temp_dir, filename) with open(file_path, 'w', encoding="utf-8") as file: file.write(filename) - os.chmod(file_path, stat.S_IREAD) + return file_path + + def create_readonly_file(self, filename): + os.chmod(self.create_writable_file(filename), stat.S_IREAD) class Sig(object): @@ -96,13 +117,18 @@ def stderr_to_parser_error(parse_args, *args, **kwargs): try: result = parse_args(*args, **kwargs) for key in list(vars(result)): - if getattr(result, key) is sys.stdout: + attr = getattr(result, key) + if attr is sys.stdout: setattr(result, key, old_stdout) - if getattr(result, key) is sys.stderr: + elif attr is sys.stdout.buffer: + setattr(result, key, getattr(old_stdout, 'buffer', BIN_STDOUT_SENTINEL)) + elif attr is sys.stderr: setattr(result, key, old_stderr) + elif attr is sys.stderr.buffer: + setattr(result, key, getattr(old_stderr, 'buffer', BIN_STDERR_SENTINEL)) return result - except SystemExit: - code = sys.exc_info()[1].code + except SystemExit as e: + code = e.code stdout = sys.stdout.getvalue() stderr = sys.stderr.getvalue() raise ArgumentParserError( @@ -270,7 +296,7 @@ class TestOptionalsSingleDashCombined(ParserTestCase): Sig('-z'), ] failures = ['a', '--foo', '-xa', '-x --foo', '-x -z', '-z -x', - '-yx', '-yz a', '-yyyx', '-yyyza', '-xyza'] + '-yx', '-yz a', '-yyyx', '-yyyza', '-xyza', '-x='] successes = [ ('', NS(x=False, yyy=None, z=None)), ('-x', NS(x=True, yyy=None, z=None)), @@ -1479,14 +1505,15 @@ class TestArgumentsFromFile(TempDirMixin, ParserTestCase): def setUp(self): super(TestArgumentsFromFile, self).setUp() file_texts = [ - ('hello', 'hello world!\n'), - ('recursive', '-a\n' - 'A\n' - '@hello'), - ('invalid', '@no-such-path\n'), + ('hello', os.fsencode(self.hello) + b'\n'), + ('recursive', b'-a\n' + b'A\n' + b'@hello'), + ('invalid', b'@no-such-path\n'), + ('undecodable', self.undecodable + b'\n'), ] for path, text in file_texts: - with open(path, 'w', encoding="utf-8") as file: + with open(path, 'wb') as file: file.write(text) parser_signature = Sig(fromfile_prefix_chars='@') @@ -1496,15 +1523,25 @@ class TestArgumentsFromFile(TempDirMixin, ParserTestCase): Sig('y', nargs='+'), ] failures = ['', '-b', 'X', '@invalid', '@missing'] + hello = 'hello world!' + os_helper.FS_NONASCII successes = [ ('X Y', NS(a=None, x='X', y=['Y'])), ('X -a A Y Z', NS(a='A', x='X', y=['Y', 'Z'])), - ('@hello X', NS(a=None, x='hello world!', y=['X'])), - ('X @hello', NS(a=None, x='X', y=['hello world!'])), - ('-a B @recursive Y Z', NS(a='A', x='hello world!', y=['Y', 'Z'])), - ('X @recursive Z -a B', NS(a='B', x='X', y=['hello world!', 'Z'])), + ('@hello X', NS(a=None, x=hello, y=['X'])), + ('X @hello', NS(a=None, x='X', y=[hello])), + ('-a B @recursive Y Z', NS(a='A', x=hello, y=['Y', 'Z'])), + ('X @recursive Z -a B', NS(a='B', x='X', y=[hello, 'Z'])), (["-a", "", "X", "Y"], NS(a='', x='X', y=['Y'])), ] + if os_helper.TESTFN_UNDECODABLE: + undecodable = os_helper.TESTFN_UNDECODABLE.lstrip(b'@') + decoded_undecodable = os.fsdecode(undecodable) + successes += [ + ('@undecodable X', NS(a=None, x=decoded_undecodable, y=['X'])), + ('X @undecodable', NS(a=None, x='X', y=[decoded_undecodable])), + ] + else: + undecodable = b'' class TestArgumentsFromFileConverter(TempDirMixin, ParserTestCase): @@ -1513,10 +1550,10 @@ class TestArgumentsFromFileConverter(TempDirMixin, ParserTestCase): def setUp(self): super(TestArgumentsFromFileConverter, self).setUp() file_texts = [ - ('hello', 'hello world!\n'), + ('hello', b'hello world!\n'), ] for path, text in file_texts: - with open(path, 'w', encoding="utf-8") as file: + with open(path, 'wb') as file: file.write(text) class FromFileConverterArgumentParser(ErrorRaisingArgumentParser): @@ -1564,16 +1601,40 @@ class TestFileTypeRepr(TestCase): type = argparse.FileType('r', 1, errors='replace') self.assertEqual("FileType('r', 1, errors='replace')", repr(type)) + +BIN_STDOUT_SENTINEL = object() +BIN_STDERR_SENTINEL = object() + + class StdStreamComparer: def __init__(self, attr): - self.attr = attr + # We try to use the actual stdXXX.buffer attribute as our + # marker, but but under some test environments, + # sys.stdout/err are replaced by io.StringIO which won't have .buffer, + # so we use a sentinel simply to show that the tests do the right thing + # for any buffer supporting object + self.getattr = operator.attrgetter(attr) + if attr == 'stdout.buffer': + self.backupattr = BIN_STDOUT_SENTINEL + elif attr == 'stderr.buffer': + self.backupattr = BIN_STDERR_SENTINEL + else: + self.backupattr = object() # Not equal to anything def __eq__(self, other): - return other == getattr(sys, self.attr) + try: + return other == self.getattr(sys) + except AttributeError: + return other == self.backupattr + eq_stdin = StdStreamComparer('stdin') eq_stdout = StdStreamComparer('stdout') eq_stderr = StdStreamComparer('stderr') +eq_bstdin = StdStreamComparer('stdin.buffer') +eq_bstdout = StdStreamComparer('stdout.buffer') +eq_bstderr = StdStreamComparer('stderr.buffer') + class RFile(object): seen = {} @@ -1652,7 +1713,7 @@ class TestFileTypeRB(TempDirMixin, ParserTestCase): ('foo', NS(x=None, spam=RFile('foo'))), ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))), ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))), - ('-x - -', NS(x=eq_stdin, spam=eq_stdin)), + ('-x - -', NS(x=eq_bstdin, spam=eq_bstdin)), ] @@ -1673,14 +1734,14 @@ class WFile(object): return self.name == other.name -@unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, - "non-root user required") +@os_helper.skip_if_dac_override class TestFileTypeW(TempDirMixin, ParserTestCase): """Test the FileType option/argument type for writing files""" def setUp(self): - super(TestFileTypeW, self).setUp() + super().setUp() self.create_readonly_file('readonly') + self.create_writable_file('writable') argument_signatures = [ Sig('-x', type=argparse.FileType('w')), @@ -1689,13 +1750,36 @@ class TestFileTypeW(TempDirMixin, ParserTestCase): failures = ['-x', '', 'readonly'] successes = [ ('foo', NS(x=None, spam=WFile('foo'))), + ('writable', NS(x=None, spam=WFile('writable'))), ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))), ('-x - -', NS(x=eq_stdout, spam=eq_stdout)), ] +@os_helper.skip_if_dac_override +class TestFileTypeX(TempDirMixin, ParserTestCase): + """Test the FileType option/argument type for writing new files only""" + + def setUp(self): + super().setUp() + self.create_readonly_file('readonly') + self.create_writable_file('writable') + + argument_signatures = [ + Sig('-x', type=argparse.FileType('x')), + Sig('spam', type=argparse.FileType('x')), + ] + failures = ['-x', '', 'readonly', 'writable'] + successes = [ + ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), + ('-x - -', NS(x=eq_stdout, spam=eq_stdout)), + ] + + +@os_helper.skip_if_dac_override class TestFileTypeWB(TempDirMixin, ParserTestCase): + """Test the FileType option/argument type for writing binary files""" argument_signatures = [ Sig('-x', type=argparse.FileType('wb')), @@ -1706,7 +1790,21 @@ class TestFileTypeWB(TempDirMixin, ParserTestCase): ('foo', NS(x=None, spam=WFile('foo'))), ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))), - ('-x - -', NS(x=eq_stdout, spam=eq_stdout)), + ('-x - -', NS(x=eq_bstdout, spam=eq_bstdout)), + ] + + +@os_helper.skip_if_dac_override +class TestFileTypeXB(TestFileTypeX): + "Test the FileType option/argument type for writing new binary files only" + + argument_signatures = [ + Sig('-x', type=argparse.FileType('xb')), + Sig('spam', type=argparse.FileType('xb')), + ] + successes = [ + ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), + ('-x - -', NS(x=eq_bstdout, spam=eq_bstdout)), ] @@ -1849,8 +1947,7 @@ class TestActionUserDefined(ParserTestCase): raise AssertionError('value: %s' % value) assert expected_ns == namespace, ('expected %s, got %s' % (expected_ns, namespace)) - except AssertionError: - e = sys.exc_info()[1] + except AssertionError as e: raise ArgumentParserError('opt_action failed: %s' % e) setattr(namespace, 'spam', value) @@ -1875,8 +1972,7 @@ class TestActionUserDefined(ParserTestCase): raise AssertionError('value: %s' % value) assert expected_ns == namespace, ('expected %s, got %s' % (expected_ns, namespace)) - except AssertionError: - e = sys.exc_info()[1] + except AssertionError as e: raise ArgumentParserError('arg_action failed: %s' % e) setattr(namespace, 'badger', value) @@ -2177,8 +2273,7 @@ class TestAddSubparsers(TestCase): main description positional arguments: - foo - + foo \n options: -h, --help show this help message and exit ''')) @@ -2194,8 +2289,7 @@ class TestAddSubparsers(TestCase): main description positional arguments: - {} - + {} \n options: -h, --help show this help message and exit ''')) @@ -2601,6 +2695,13 @@ class TestMutuallyExclusiveGroupErrors(TestCase): ''' self.assertEqual(parser.format_help(), textwrap.dedent(expected)) + def test_empty_group(self): + # See issue 26952 + parser = argparse.ArgumentParser() + group = parser.add_mutually_exclusive_group() + with self.assertRaises(ValueError): + parser.parse_args(['-h']) + class MEMixin(object): def test_failures_when_not_required(self): @@ -2966,15 +3067,24 @@ class TestMutuallyExclusiveOptionalsAndPositionalsMixed(MEMixin, TestCase): class TestMutuallyExclusiveNested(MEMixin, TestCase): + # Nesting mutually exclusive groups is an undocumented feature + # that came about by accident through inheritance and has been + # the source of many bugs. It is deprecated and this test should + # eventually be removed along with it. + def get_parser(self, required): parser = ErrorRaisingArgumentParser(prog='PROG') group = parser.add_mutually_exclusive_group(required=required) group.add_argument('-a') group.add_argument('-b') - group2 = group.add_mutually_exclusive_group(required=required) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + group2 = group.add_mutually_exclusive_group(required=required) group2.add_argument('-c') group2.add_argument('-d') - group3 = group2.add_mutually_exclusive_group(required=required) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + group3 = group2.add_mutually_exclusive_group(required=required) group3.add_argument('-e') group3.add_argument('-f') return parser @@ -3246,6 +3356,7 @@ class TestHelpFormattingMetaclass(type): def _test(self, tester, parser_text): expected_text = getattr(tester, self.func_suffix) expected_text = textwrap.dedent(expected_text) + tester.maxDiff = None tester.assertEqual(expected_text, parser_text) def test_format(self, tester): @@ -3325,9 +3436,8 @@ class TestShortColumns(HelpTestCase): but we don't want any exceptions thrown in such cases. Only ugly representation. ''' def setUp(self): - env = os_helper.EnvironmentVarGuard() + env = self.enterContext(os_helper.EnvironmentVarGuard()) env.set("COLUMNS", '15') - self.addCleanup(env.__exit__) parser_signature = TestHelpBiggerOptionals.parser_signature argument_signatures = TestHelpBiggerOptionals.argument_signatures @@ -3611,6 +3721,8 @@ class TestHelpUsage(HelpTestCase): Sig('--bar', help='Whether to bar', default=True, action=argparse.BooleanOptionalAction), Sig('-f', '--foobar', '--barfoo', action=argparse.BooleanOptionalAction), + Sig('--bazz', action=argparse.BooleanOptionalAction, + default=argparse.SUPPRESS, help='Bazz!'), ] argument_group_signatures = [ (Sig('group'), [ @@ -3623,8 +3735,8 @@ class TestHelpUsage(HelpTestCase): usage = '''\ usage: PROG [-h] [-w W [W ...]] [-x [X ...]] [--foo | --no-foo] [--bar | --no-bar] - [-f | --foobar | --no-foobar | --barfoo | --no-barfoo] [-y [Y]] - [-z Z Z Z] + [-f | --foobar | --no-foobar | --barfoo | --no-barfoo] + [--bazz | --no-bazz] [-y [Y]] [-z Z Z Z] a b b [c] [d ...] e [e ...] ''' help = usage + '''\ @@ -3639,8 +3751,9 @@ class TestHelpUsage(HelpTestCase): -w W [W ...] w -x [X ...] x --foo, --no-foo Whether to foo - --bar, --no-bar Whether to bar (default: True) + --bar, --no-bar Whether to bar -f, --foobar, --no-foobar, --barfoo, --no-barfoo + --bazz, --no-bazz Bazz! group: -y [Y] y @@ -4318,6 +4431,8 @@ class TestHelpArgumentDefaults(HelpTestCase): Sig('--bar', action='store_true', help='bar help'), Sig('--taz', action=argparse.BooleanOptionalAction, help='Whether to taz it', default=True), + Sig('--corge', action=argparse.BooleanOptionalAction, + help='Whether to corge it', default=argparse.SUPPRESS), Sig('--quux', help="Set the quux", default=42), Sig('spam', help='spam help'), Sig('badger', nargs='?', default='wooden', help='badger help'), @@ -4327,8 +4442,8 @@ class TestHelpArgumentDefaults(HelpTestCase): [Sig('--baz', type=int, default=42, help='baz help')]), ] usage = '''\ - usage: PROG [-h] [--foo FOO] [--bar] [--taz | --no-taz] [--quux QUUX] - [--baz BAZ] + usage: PROG [-h] [--foo FOO] [--bar] [--taz | --no-taz] [--corge | --no-corge] + [--quux QUUX] [--baz BAZ] spam [badger] ''' help = usage + '''\ @@ -4336,20 +4451,21 @@ class TestHelpArgumentDefaults(HelpTestCase): description positional arguments: - spam spam help - badger badger help (default: wooden) + spam spam help + badger badger help (default: wooden) options: - -h, --help show this help message and exit - --foo FOO foo help - oh and by the way, None - --bar bar help (default: False) - --taz, --no-taz Whether to taz it (default: True) - --quux QUUX Set the quux (default: 42) + -h, --help show this help message and exit + --foo FOO foo help - oh and by the way, None + --bar bar help (default: False) + --taz, --no-taz Whether to taz it (default: True) + --corge, --no-corge Whether to corge it + --quux QUUX Set the quux (default: 42) title: description - --baz BAZ baz help (default: 42) + --baz BAZ baz help (default: 42) ''' version = '' @@ -4699,6 +4815,19 @@ class TestConflictHandling(TestCase): --spam NEW_SPAM ''')) + def test_subparser_conflict(self): + parser = argparse.ArgumentParser() + sp = parser.add_subparsers() + sp.add_parser('fullname', aliases=['alias']) + self.assertRaises(argparse.ArgumentError, + sp.add_parser, 'fullname') + self.assertRaises(argparse.ArgumentError, + sp.add_parser, 'alias') + self.assertRaises(argparse.ArgumentError, + sp.add_parser, 'other', aliases=['fullname']) + self.assertRaises(argparse.ArgumentError, + sp.add_parser, 'other', aliases=['alias']) + # ============================= # Help and Version option tests @@ -4795,12 +4924,13 @@ class TestStrings(TestCase): nargs='+', default=42, choices=[1, 2, 3], + required=False, help='HELP', metavar='METAVAR') string = ( "Action(option_strings=['--foo', '-a', '-b'], dest='b', " "nargs='+', const=None, default=42, type='int', " - "choices=[1, 2, 3], help='HELP', metavar='METAVAR')") + "choices=[1, 2, 3], required=False, help='HELP', metavar='METAVAR')") self.assertStringEqual(option, string) def test_argument(self): @@ -4811,12 +4941,13 @@ class TestStrings(TestCase): nargs='?', default=2.5, choices=[0.5, 1.5, 2.5], + required=True, help='H HH H', metavar='MV MV MV') string = ( "Action(option_strings=[], dest='x', nargs='?', " "const=None, default=2.5, type=%r, choices=[0.5, 1.5, 2.5], " - "help='H HH H', metavar='MV MV MV')" % float) + "required=True, help='H HH H', metavar='MV MV MV')" % float) self.assertStringEqual(argument, string) def test_namespace(self): @@ -5099,6 +5230,13 @@ class TestParseKnownArgs(TestCase): self.assertEqual(NS(v=3, spam=True, badger="B"), args) self.assertEqual(["C", "--foo", "4"], extras) + def test_zero_or_more_optional(self): + parser = argparse.ArgumentParser() + parser.add_argument('x', nargs='*', choices=('x', 'y')) + args = parser.parse_args([]) + self.assertEqual(NS(x=[]), args) + + # =========================== # parse_intermixed_args tests # =========================== diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index e630677f796..c728d2b55e4 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -11,9 +11,10 @@ import weakref from textwrap import dedent from test import support +from test.support.ast_helper import ASTTestMixin def to_tuple(t): - if t is None or isinstance(t, (str, int, complex)): + if t is None or isinstance(t, (str, int, complex)) or t is Ellipsis: return t elif isinstance(t, list): return [to_tuple(e) for e in t] @@ -46,10 +47,20 @@ exec_tests = [ "def f(a=0): pass", # FunctionDef with varargs "def f(*args): pass", + # FunctionDef with varargs as TypeVarTuple + "def f(*args: *Ts): pass", + # FunctionDef with varargs as unpacked Tuple + "def f(*args: *tuple[int, ...]): pass", + # FunctionDef with varargs as unpacked Tuple *and* TypeVarTuple + "def f(*args: *tuple[int, *Ts]): pass", # FunctionDef with kwargs "def f(**kwargs): pass", # FunctionDef with all kind of args and docstring "def f(a, b=1, c=None, d=[], e={}, *args, f=42, **kwargs): 'doc for f()'", + # FunctionDef with type annotation on return involving unpacking + "def f() -> tuple[*Ts]: pass", + "def f() -> tuple[int, *Ts]: pass", + "def f() -> tuple[int, *tuple[int, ...]]: pass", # ClassDef "class C:pass", # ClassDef with docstring @@ -65,6 +76,10 @@ exec_tests = [ "a,b = c", "(a,b) = c", "[a,b] = c", + # AnnAssign with unpacked types + "x: tuple[*Ts]", + "x: tuple[int, *Ts]", + "x: tuple[int, *tuple[str, ...]]", # AugAssign "v += 1", # For @@ -86,6 +101,8 @@ exec_tests = [ "try:\n pass\nexcept Exception:\n pass", # TryFinally "try:\n pass\nfinally:\n pass", + # TryStarExcept + "try:\n pass\nexcept* Exception:\n pass", # Assert "assert v", # Import @@ -320,6 +337,41 @@ class AST_Tests(unittest.TestCase): tree = ast.parse(snippet) compile(tree, '', 'exec') + def test_invalid_position_information(self): + invalid_linenos = [ + (10, 1), (-10, -11), (10, -11), (-5, -2), (-5, 1) + ] + + for lineno, end_lineno in invalid_linenos: + with self.subTest(f"Check invalid linenos {lineno}:{end_lineno}"): + snippet = "a = 1" + tree = ast.parse(snippet) + tree.body[0].lineno = lineno + tree.body[0].end_lineno = end_lineno + with self.assertRaises(ValueError): + compile(tree, '', 'exec') + + invalid_col_offsets = [ + (10, 1), (-10, -11), (10, -11), (-5, -2), (-5, 1) + ] + for col_offset, end_col_offset in invalid_col_offsets: + with self.subTest(f"Check invalid col_offset {col_offset}:{end_col_offset}"): + snippet = "a = 1" + tree = ast.parse(snippet) + tree.body[0].col_offset = col_offset + tree.body[0].end_col_offset = end_col_offset + with self.assertRaises(ValueError): + compile(tree, '', 'exec') + + def test_compilation_of_ast_nodes_with_default_end_position_values(self): + tree = ast.Module(body=[ + ast.Import(names=[ast.alias(name='builtins', lineno=1, col_offset=0)], lineno=1, col_offset=0), + ast.Import(names=[ast.alias(name='traceback', lineno=0, col_offset=0)], lineno=0, col_offset=1) + ], type_ignores=[]) + + # Check that compilation doesn't crash. Note: this may crash explicitly only on debug mode. + compile(tree, "", "exec") + def test_slice(self): slc = ast.parse("x[::]").body[0].value.slice self.assertIsNone(slc.upper) @@ -588,18 +640,11 @@ class AST_Tests(unittest.TestCase): def test_pickling(self): import pickle - mods = [pickle] - try: - import cPickle - mods.append(cPickle) - except ImportError: - pass - protocols = [0, 1, 2] - for mod in mods: - for protocol in protocols: - for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests): - ast2 = mod.loads(mod.dumps(ast, protocol)) - self.assertEqual(to_tuple(ast2), to_tuple(ast)) + + for protocol in range(pickle.HIGHEST_PROTOCOL + 1): + for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests): + ast2 = pickle.loads(pickle.dumps(ast, protocol)) + self.assertEqual(to_tuple(ast2), to_tuple(ast)) def test_invalid_sum(self): pos = dict(lineno=2, col_offset=3) @@ -687,11 +732,54 @@ class AST_Tests(unittest.TestCase): expressions[0] = f"expr = {ast.expr.__subclasses__()[0].__doc__}" self.assertCountEqual(ast.expr.__doc__.split("\n"), expressions) - def test_issue40614_feature_version(self): + def test_positional_only_feature_version(self): + ast.parse('def foo(x, /): ...', feature_version=(3, 8)) + ast.parse('def bar(x=1, /): ...', feature_version=(3, 8)) + with self.assertRaises(SyntaxError): + ast.parse('def foo(x, /): ...', feature_version=(3, 7)) + with self.assertRaises(SyntaxError): + ast.parse('def bar(x=1, /): ...', feature_version=(3, 7)) + + ast.parse('lambda x, /: ...', feature_version=(3, 8)) + ast.parse('lambda x=1, /: ...', feature_version=(3, 8)) + with self.assertRaises(SyntaxError): + ast.parse('lambda x, /: ...', feature_version=(3, 7)) + with self.assertRaises(SyntaxError): + ast.parse('lambda x=1, /: ...', feature_version=(3, 7)) + + def test_parenthesized_with_feature_version(self): + ast.parse('with (CtxManager() as example): ...', feature_version=(3, 10)) + # While advertised as a feature in Python 3.10, this was allowed starting 3.9 + ast.parse('with (CtxManager() as example): ...', feature_version=(3, 9)) + with self.assertRaises(SyntaxError): + ast.parse('with (CtxManager() as example): ...', feature_version=(3, 8)) + ast.parse('with CtxManager() as example: ...', feature_version=(3, 8)) + + def test_debug_f_string_feature_version(self): ast.parse('f"{x=}"', feature_version=(3, 8)) with self.assertRaises(SyntaxError): ast.parse('f"{x=}"', feature_version=(3, 7)) + def test_assignment_expression_feature_version(self): + ast.parse('(x := 0)', feature_version=(3, 8)) + with self.assertRaises(SyntaxError): + ast.parse('(x := 0)', feature_version=(3, 7)) + + def test_exception_groups_feature_version(self): + code = dedent(''' + try: ... + except* Exception: ... + ''') + ast.parse(code) + with self.assertRaises(SyntaxError): + ast.parse(code, feature_version=(3, 10)) + + def test_invalid_major_feature_version(self): + with self.assertRaises(ValueError): + ast.parse('pass', feature_version=(2, 7)) + with self.assertRaises(ValueError): + ast.parse('pass', feature_version=(4, 0)) + def test_constant_as_name(self): for constant in "True", "False", "None": expr = ast.Expression(ast.Name(constant, ast.Load())) @@ -729,6 +817,32 @@ class AST_Tests(unittest.TestCase): return self enum._test_simple_enum(_Precedence, ast._Precedence) + @support.cpython_only + def test_ast_recursion_limit(self): + fail_depth = support.EXCEEDS_RECURSION_LIMIT + crash_depth = 100_000 + success_depth = 1200 + + def check_limit(prefix, repeated): + expect_ok = prefix + repeated * success_depth + ast.parse(expect_ok) + for depth in (fail_depth, crash_depth): + broken = prefix + repeated * depth + details = "Compiling ({!r} + {!r} * {})".format( + prefix, repeated, depth) + with self.assertRaises(RecursionError, msg=details): + with support.infinite_recursion(): + ast.parse(broken) + + check_limit("a", "()") + check_limit("a", ".b") + check_limit("a", "[0]") + check_limit("a", "*a") + + def test_null_bytes(self): + with self.assertRaises(SyntaxError, + msg="source code string cannot contain null bytes"): + ast.parse("a\0b") class ASTHelpers_Test(unittest.TestCase): maxDiff = None @@ -917,6 +1031,18 @@ Module( self.assertEqual(ast.increment_lineno(src).lineno, 2) self.assertIsNone(ast.increment_lineno(src).end_lineno) + def test_increment_lineno_on_module(self): + src = ast.parse(dedent("""\ + a = 1 + b = 2 # type: ignore + c = 3 + d = 4 # type: ignore@tag + """), type_comments=True) + ast.increment_lineno(src, n=5) + self.assertEqual(src.type_ignores[0].lineno, 7) + self.assertEqual(src.type_ignores[1].lineno, 9) + self.assertEqual(src.type_ignores[1].tag, '@tag') + def test_iter_fields(self): node = ast.parse('foo()', mode='eval') d = dict(ast.iter_fields(node.body)) @@ -1030,6 +1156,14 @@ Module( self.assertRaises(ValueError, ast.literal_eval, '+True') self.assertRaises(ValueError, ast.literal_eval, '2+3') + def test_literal_eval_str_int_limit(self): + with support.adjust_int_max_str_digits(4000): + ast.literal_eval('3'*4000) # no error + with self.assertRaises(SyntaxError) as err_ctx: + ast.literal_eval('3'*4001) + self.assertIn('Exceeds the limit ', str(err_ctx.exception)) + self.assertIn(' Consider hexadecimal ', str(err_ctx.exception)) + def test_literal_eval_complex(self): # Issue #4907 self.assertEqual(ast.literal_eval('6j'), 6j) @@ -1076,8 +1210,7 @@ Module( ast.literal_eval(node) def test_literal_eval_syntax_errors(self): - msg = "unexpected character after line continuation character" - with self.assertRaisesRegex(SyntaxError, msg): + with self.assertRaisesRegex(SyntaxError, "unexpected indent"): ast.literal_eval(r''' \ (\ @@ -1310,6 +1443,26 @@ class ASTValidatorTests(unittest.TestCase): t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))]) self.stmt(t, "must have Load context") + def test_try_star(self): + p = ast.Pass() + t = ast.TryStar([], [], [], [p]) + self.stmt(t, "empty body on TryStar") + t = ast.TryStar([ast.Expr(ast.Name("x", ast.Store()))], [], [], [p]) + self.stmt(t, "must have Load context") + t = ast.TryStar([p], [], [], []) + self.stmt(t, "TryStar has neither except handlers nor finalbody") + t = ast.TryStar([p], [], [p], [p]) + self.stmt(t, "TryStar has orelse but no except handlers") + t = ast.TryStar([p], [ast.ExceptHandler(None, "x", [])], [], []) + self.stmt(t, "empty body on ExceptHandler") + e = [ast.ExceptHandler(ast.Name("x", ast.Store()), "y", [p])] + self.stmt(ast.TryStar([p], e, [], []), "must have Load context") + e = [ast.ExceptHandler(None, "x", [p])] + t = ast.TryStar([p], e, [ast.Expr(ast.Name("x", ast.Store()))], [p]) + self.stmt(t, "must have Load context") + t = ast.TryStar([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))]) + self.stmt(t, "must have Load context") + def test_assert(self): self.stmt(ast.Assert(ast.Name("x", ast.Store()), None), "must have Load context") @@ -2138,9 +2291,10 @@ class EndPositionTests(unittest.TestCase): self.assertIsNone(ast.get_source_segment(s, x)) self.assertIsNone(ast.get_source_segment(s, y)) -class NodeVisitorTests(unittest.TestCase): +class BaseNodeVisitorCases: + # Both `NodeVisitor` and `NodeTranformer` must raise these warnings: def test_old_constant_nodes(self): - class Visitor(ast.NodeVisitor): + class Visitor(self.visitor_class): def visit_Num(self, node): log.append((node.lineno, 'Num', node.n)) def visit_Str(self, node): @@ -2188,6 +2342,128 @@ class NodeVisitorTests(unittest.TestCase): ]) +class NodeVisitorTests(BaseNodeVisitorCases, unittest.TestCase): + visitor_class = ast.NodeVisitor + + +class NodeTransformerTests(ASTTestMixin, BaseNodeVisitorCases, unittest.TestCase): + visitor_class = ast.NodeTransformer + + def assertASTTransformation(self, tranformer_class, + initial_code, expected_code): + initial_ast = ast.parse(dedent(initial_code)) + expected_ast = ast.parse(dedent(expected_code)) + + tranformer = tranformer_class() + result_ast = ast.fix_missing_locations(tranformer.visit(initial_ast)) + + self.assertASTEqual(result_ast, expected_ast) + + def test_node_remove_single(self): + code = 'def func(arg) -> SomeType: ...' + expected = 'def func(arg): ...' + + # Since `FunctionDef.returns` is defined as a single value, we test + # the `if isinstance(old_value, AST):` branch here. + class SomeTypeRemover(ast.NodeTransformer): + def visit_Name(self, node: ast.Name): + self.generic_visit(node) + if node.id == 'SomeType': + return None + return node + + self.assertASTTransformation(SomeTypeRemover, code, expected) + + def test_node_remove_from_list(self): + code = """ + def func(arg): + print(arg) + yield arg + """ + expected = """ + def func(arg): + print(arg) + """ + + # Since `FunctionDef.body` is defined as a list, we test + # the `if isinstance(old_value, list):` branch here. + class YieldRemover(ast.NodeTransformer): + def visit_Expr(self, node: ast.Expr): + self.generic_visit(node) + if isinstance(node.value, ast.Yield): + return None # Remove `yield` from a function + return node + + self.assertASTTransformation(YieldRemover, code, expected) + + def test_node_return_list(self): + code = """ + class DSL(Base, kw1=True): ... + """ + expected = """ + class DSL(Base, kw1=True, kw2=True, kw3=False): ... + """ + + class ExtendKeywords(ast.NodeTransformer): + def visit_keyword(self, node: ast.keyword): + self.generic_visit(node) + if node.arg == 'kw1': + return [ + node, + ast.keyword('kw2', ast.Constant(True)), + ast.keyword('kw3', ast.Constant(False)), + ] + return node + + self.assertASTTransformation(ExtendKeywords, code, expected) + + def test_node_mutate(self): + code = """ + def func(arg): + print(arg) + """ + expected = """ + def func(arg): + log(arg) + """ + + class PrintToLog(ast.NodeTransformer): + def visit_Call(self, node: ast.Call): + self.generic_visit(node) + if isinstance(node.func, ast.Name) and node.func.id == 'print': + node.func.id = 'log' + return node + + self.assertASTTransformation(PrintToLog, code, expected) + + def test_node_replace(self): + code = """ + def func(arg): + print(arg) + """ + expected = """ + def func(arg): + logger.log(arg, debug=True) + """ + + class PrintToLog(ast.NodeTransformer): + def visit_Call(self, node: ast.Call): + self.generic_visit(node) + if isinstance(node.func, ast.Name) and node.func.id == 'print': + return ast.Call( + func=ast.Attribute( + ast.Name('logger', ctx=ast.Load()), + attr='log', + ctx=ast.Load(), + ), + args=node.args, + keywords=[ast.keyword('debug', ast.Constant(True))], + ) + return node + + self.assertASTTransformation(PrintToLog, code, expected) + + @support.cpython_only class ModuleStateTests(unittest.TestCase): # bpo-41194, bpo-41261, bpo-41631: The _ast module uses a global state. @@ -2294,8 +2570,14 @@ exec_results = [ ('Module', [('FunctionDef', (1, 0, 1, 14), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10, 1, 14))], [], None, None)], []), ('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 0, None)]), [('Pass', (1, 12, 1, 16))], [], None, None)], []), ('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0, 1, 23), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 16), 'args', ('Starred', (1, 13, 1, 16), ('Name', (1, 14, 1, 16), 'Ts', ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 19, 1, 23))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0, 1, 36), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 29), 'args', ('Starred', (1, 13, 1, 29), ('Subscript', (1, 14, 1, 29), ('Name', (1, 14, 1, 19), 'tuple', ('Load',)), ('Tuple', (1, 20, 1, 28), [('Name', (1, 20, 1, 23), 'int', ('Load',)), ('Constant', (1, 25, 1, 28), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 32, 1, 36))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0, 1, 36), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 29), 'args', ('Starred', (1, 13, 1, 29), ('Subscript', (1, 14, 1, 29), ('Name', (1, 14, 1, 19), 'tuple', ('Load',)), ('Tuple', (1, 20, 1, 28), [('Name', (1, 20, 1, 23), 'int', ('Load',)), ('Starred', (1, 25, 1, 28), ('Name', (1, 26, 1, 28), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 32, 1, 36))], [], None, None)], []), ('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []), ('Module', [('FunctionDef', (1, 0, 1, 71), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None), ('arg', (1, 9, 1, 10), 'b', None, None), ('arg', (1, 14, 1, 15), 'c', None, None), ('arg', (1, 22, 1, 23), 'd', None, None), ('arg', (1, 28, 1, 29), 'e', None, None)], ('arg', (1, 35, 1, 39), 'args', None, None), [('arg', (1, 41, 1, 42), 'f', None, None)], [('Constant', (1, 43, 1, 45), 42, None)], ('arg', (1, 49, 1, 55), 'kwargs', None, None), [('Constant', (1, 11, 1, 12), 1, None), ('Constant', (1, 16, 1, 20), None, None), ('List', (1, 24, 1, 26), [], ('Load',)), ('Dict', (1, 30, 1, 32), [], [])]), [('Expr', (1, 58, 1, 71), ('Constant', (1, 58, 1, 71), 'doc for f()', None))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0, 1, 27), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 23, 1, 27))], [], ('Subscript', (1, 11, 1, 21), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 20), [('Starred', (1, 17, 1, 20), ('Name', (1, 18, 1, 20), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []), +('Module', [('FunctionDef', (1, 0, 1, 32), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 28, 1, 32))], [], ('Subscript', (1, 11, 1, 26), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 25), [('Name', (1, 17, 1, 20), 'int', ('Load',)), ('Starred', (1, 22, 1, 25), ('Name', (1, 23, 1, 25), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []), +('Module', [('FunctionDef', (1, 0, 1, 45), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 41, 1, 45))], [], ('Subscript', (1, 11, 1, 39), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 38), [('Name', (1, 17, 1, 20), 'int', ('Load',)), ('Starred', (1, 22, 1, 38), ('Subscript', (1, 23, 1, 38), ('Name', (1, 23, 1, 28), 'tuple', ('Load',)), ('Tuple', (1, 29, 1, 37), [('Name', (1, 29, 1, 32), 'int', ('Load',)), ('Constant', (1, 34, 1, 37), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []), ('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []), ('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []), ('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []), @@ -2305,6 +2587,9 @@ exec_results = [ ('Module', [('Assign', (1, 0, 1, 7), [('Tuple', (1, 0, 1, 3), [('Name', (1, 0, 1, 1), 'a', ('Store',)), ('Name', (1, 2, 1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 6, 1, 7), 'c', ('Load',)), None)], []), ('Module', [('Assign', (1, 0, 1, 9), [('Tuple', (1, 0, 1, 5), [('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Name', (1, 3, 1, 4), 'b', ('Store',))], ('Store',))], ('Name', (1, 8, 1, 9), 'c', ('Load',)), None)], []), ('Module', [('Assign', (1, 0, 1, 9), [('List', (1, 0, 1, 5), [('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Name', (1, 3, 1, 4), 'b', ('Store',))], ('Store',))], ('Name', (1, 8, 1, 9), 'c', ('Load',)), None)], []), +('Module', [('AnnAssign', (1, 0, 1, 13), ('Name', (1, 0, 1, 1), 'x', ('Store',)), ('Subscript', (1, 3, 1, 13), ('Name', (1, 3, 1, 8), 'tuple', ('Load',)), ('Tuple', (1, 9, 1, 12), [('Starred', (1, 9, 1, 12), ('Name', (1, 10, 1, 12), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None, 1)], []), +('Module', [('AnnAssign', (1, 0, 1, 18), ('Name', (1, 0, 1, 1), 'x', ('Store',)), ('Subscript', (1, 3, 1, 18), ('Name', (1, 3, 1, 8), 'tuple', ('Load',)), ('Tuple', (1, 9, 1, 17), [('Name', (1, 9, 1, 12), 'int', ('Load',)), ('Starred', (1, 14, 1, 17), ('Name', (1, 15, 1, 17), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None, 1)], []), +('Module', [('AnnAssign', (1, 0, 1, 31), ('Name', (1, 0, 1, 1), 'x', ('Store',)), ('Subscript', (1, 3, 1, 31), ('Name', (1, 3, 1, 8), 'tuple', ('Load',)), ('Tuple', (1, 9, 1, 30), [('Name', (1, 9, 1, 12), 'int', ('Load',)), ('Starred', (1, 14, 1, 30), ('Subscript', (1, 15, 1, 30), ('Name', (1, 15, 1, 20), 'tuple', ('Load',)), ('Tuple', (1, 21, 1, 29), [('Name', (1, 21, 1, 24), 'str', ('Load',)), ('Constant', (1, 26, 1, 29), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',))], ('Load',)), ('Load',)), None, 1)], []), ('Module', [('AugAssign', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'v', ('Store',)), ('Add',), ('Constant', (1, 5, 1, 6), 1, None))], []), ('Module', [('For', (1, 0, 1, 15), ('Name', (1, 4, 1, 5), 'v', ('Store',)), ('Name', (1, 9, 1, 10), 'v', ('Load',)), [('Pass', (1, 11, 1, 15))], [], None)], []), ('Module', [('While', (1, 0, 1, 12), ('Name', (1, 6, 1, 7), 'v', ('Load',)), [('Pass', (1, 8, 1, 12))], [])], []), @@ -2316,6 +2601,7 @@ exec_results = [ ('Module', [('Raise', (1, 0, 1, 25), ('Call', (1, 6, 1, 25), ('Name', (1, 6, 1, 15), 'Exception', ('Load',)), [('Constant', (1, 16, 1, 24), 'string', None)], []), None)], []), ('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [('ExceptHandler', (3, 0, 4, 6), ('Name', (3, 7, 3, 16), 'Exception', ('Load',)), None, [('Pass', (4, 2, 4, 6))])], [], [])], []), ('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [], [], [('Pass', (4, 2, 4, 6))])], []), +('Module', [('TryStar', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [('ExceptHandler', (3, 0, 4, 6), ('Name', (3, 8, 3, 17), 'Exception', ('Load',)), None, [('Pass', (4, 2, 4, 6))])], [], [])], []), ('Module', [('Assert', (1, 0, 1, 8), ('Name', (1, 7, 1, 8), 'v', ('Load',)), None)], []), ('Module', [('Import', (1, 0, 1, 10), [('alias', (1, 7, 1, 10), 'sys', None)])], []), ('Module', [('ImportFrom', (1, 0, 1, 17), 'sys', [('alias', (1, 16, 1, 17), 'v', None)], 0)], []), diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py index 473bce484b4..0421efdbf9d 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -2,12 +2,15 @@ import inspect import types import unittest import contextlib +import warnings from test.support.import_helper import import_module -from test.support import gc_collect +from test.support import gc_collect, requires_working_socket asyncio = import_module("asyncio") +requires_working_socket(module=True) + _no_default = object() @@ -375,6 +378,26 @@ class AsyncGenTest(unittest.TestCase): self.compare_generators(sync_gen_wrapper(), async_gen_wrapper()) + def test_async_gen_exception_12(self): + async def gen(): + await anext(me) + yield 123 + + me = gen() + ai = me.__aiter__() + an = ai.__anext__() + + with self.assertRaisesRegex(RuntimeError, + r'anext\(\): asynchronous generator is already running'): + an.__next__() + + def test_async_gen_3_arg_deprecation_warning(self): + async def gen(): + yield 123 + + with self.assertWarns(DeprecationWarning): + gen().athrow(GeneratorExit, GeneratorExit(), None) + def test_async_gen_api_01(self): async def gen(): yield 123 @@ -648,7 +671,7 @@ class AsyncGenAsyncioTest(unittest.TestCase): agen = agenfn() with contextlib.closing(anext(agen, "default").__await__()) as g: self.assertEqual(g.send(None), 1) - self.assertEqual(g.throw(MyError, MyError(), None), 2) + self.assertEqual(g.throw(MyError()), 2) try: g.send(None) except StopIteration as e: @@ -661,9 +684,9 @@ class AsyncGenAsyncioTest(unittest.TestCase): agen = agenfn() with contextlib.closing(anext(agen, "default").__await__()) as g: self.assertEqual(g.send(None), 1) - self.assertEqual(g.throw(MyError, MyError(), None), 2) + self.assertEqual(g.throw(MyError()), 2) with self.assertRaises(MyError): - g.throw(MyError, MyError(), None) + g.throw(MyError()) def test3(anext): agen = agenfn() @@ -690,9 +713,9 @@ class AsyncGenAsyncioTest(unittest.TestCase): agen = agenfn() with contextlib.closing(anext(agen, "default").__await__()) as g: self.assertEqual(g.send(None), 10) - self.assertEqual(g.throw(MyError, MyError(), None), 20) + self.assertEqual(g.throw(MyError()), 20) with self.assertRaisesRegex(MyError, 'val'): - g.throw(MyError, MyError('val'), None) + g.throw(MyError('val')) def test5(anext): @types.coroutine @@ -711,7 +734,7 @@ class AsyncGenAsyncioTest(unittest.TestCase): with contextlib.closing(anext(agen, "default").__await__()) as g: self.assertEqual(g.send(None), 10) with self.assertRaisesRegex(StopIteration, 'default'): - g.throw(MyError, MyError(), None) + g.throw(MyError()) def test6(anext): @types.coroutine @@ -726,7 +749,7 @@ class AsyncGenAsyncioTest(unittest.TestCase): agen = agenfn() with contextlib.closing(anext(agen, "default").__await__()) as g: with self.assertRaises(MyError): - g.throw(MyError, MyError(), None) + g.throw(MyError()) def run_test(test): with self.subTest('pure-Python anext()'): diff --git a/Lib/test/test_asyncio/__init__.py b/Lib/test/test_asyncio/__init__.py index 5d415044d7d..ab0b5aa9489 100644 --- a/Lib/test/test_asyncio/__init__.py +++ b/Lib/test/test_asyncio/__init__.py @@ -1,7 +1,9 @@ import os +from test import support from test.support import load_package_tests from test.support import import_helper +support.requires_working_socket(module=True) # Skip tests if we don't have concurrent.futures. import_helper.import_module('concurrent.futures') diff --git a/Lib/test/test_asyncio/test_asyncio_waitfor.py b/Lib/test/test_asyncio/test_asyncio_waitfor.py deleted file mode 100644 index 2ca64abbeb5..00000000000 --- a/Lib/test/test_asyncio/test_asyncio_waitfor.py +++ /dev/null @@ -1,61 +0,0 @@ -import asyncio -import unittest -import time - -def tearDownModule(): - asyncio.set_event_loop_policy(None) - - -class SlowTask: - """ Task will run for this defined time, ignoring cancel requests """ - TASK_TIMEOUT = 0.2 - - def __init__(self): - self.exited = False - - async def run(self): - exitat = time.monotonic() + self.TASK_TIMEOUT - - while True: - tosleep = exitat - time.monotonic() - if tosleep <= 0: - break - - try: - await asyncio.sleep(tosleep) - except asyncio.CancelledError: - pass - - self.exited = True - -class AsyncioWaitForTest(unittest.TestCase): - - async def atest_asyncio_wait_for_cancelled(self): - t = SlowTask() - - waitfortask = asyncio.create_task(asyncio.wait_for(t.run(), t.TASK_TIMEOUT * 2)) - await asyncio.sleep(0) - waitfortask.cancel() - await asyncio.wait({waitfortask}) - - self.assertTrue(t.exited) - - def test_asyncio_wait_for_cancelled(self): - asyncio.run(self.atest_asyncio_wait_for_cancelled()) - - async def atest_asyncio_wait_for_timeout(self): - t = SlowTask() - - try: - await asyncio.wait_for(t.run(), t.TASK_TIMEOUT / 2) - except asyncio.TimeoutError: - pass - - self.assertTrue(t.exited) - - def test_asyncio_wait_for_timeout(self): - asyncio.run(self.atest_asyncio_wait_for_timeout()) - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index b522fac23a2..3b4026cb738 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -18,10 +18,9 @@ from test import support from test.support.script_helper import assert_python_ok from test.support import os_helper from test.support import socket_helper - +import warnings MOCK_ANY = mock.ANY -PY34 = sys.version_info >= (3, 4) def tearDownModule(): @@ -41,7 +40,6 @@ def mock_socket_module(): m_socket.socket = mock.MagicMock() m_socket.socket.return_value = test_utils.mock_nonblocking_socket() - m_socket.getaddrinfo._is_coroutine = False return m_socket @@ -255,6 +253,8 @@ class BaseEventLoopTests(test_utils.TestCase): self.assertIsInstance(h, asyncio.TimerHandle) self.assertIn(h, self.loop._scheduled) self.assertNotIn(h, self.loop._ready) + with self.assertRaises(TypeError, msg="delay must not be None"): + self.loop.call_later(None, cb) def test_call_later_negative_delays(self): calls = [] @@ -286,6 +286,8 @@ class BaseEventLoopTests(test_utils.TestCase): # tolerate a difference of +800 ms because some Python buildbots # are really slow self.assertLessEqual(dt, 0.9, dt) + with self.assertRaises(TypeError, msg="when cannot be None"): + self.loop.call_at(None, cb) def check_thread(self, loop, debug): def cb(): @@ -592,18 +594,10 @@ class BaseEventLoopTests(test_utils.TestCase): self.loop.run_forever() fut = None # Trigger Future.__del__ or futures._TracebackLogger support.gc_collect() - if PY34: - # Future.__del__ in Python 3.4 logs error with - # an actual exception context - log.error.assert_called_with( - test_utils.MockPattern('.*exception was never retrieved'), - exc_info=(ZeroDivisionError, MOCK_ANY, MOCK_ANY)) - else: - # futures._TracebackLogger logs only textual traceback - log.error.assert_called_with( - test_utils.MockPattern( - '.*exception was never retrieved.*ZeroDiv'), - exc_info=False) + # Future.__del__ in logs error with an actual exception context + log.error.assert_called_with( + test_utils.MockPattern('.*exception was never retrieved'), + exc_info=(ZeroDivisionError, MOCK_ANY, MOCK_ANY)) def test_set_exc_handler_invalid(self): with self.assertRaisesRegex(TypeError, 'A callable object or None'): @@ -643,7 +637,7 @@ class BaseEventLoopTests(test_utils.TestCase): 'Exception in callback.*zero'), exc_info=(ZeroDivisionError, MOCK_ANY, MOCK_ANY)) - assert not mock_handler.called + self.assertFalse(mock_handler.called) def test_set_exc_handler_broken(self): def run_loop(): @@ -752,7 +746,7 @@ class BaseEventLoopTests(test_utils.TestCase): def test_env_var_debug(self): code = '\n'.join(( 'import asyncio', - 'loop = asyncio.get_event_loop()', + 'loop = asyncio.new_event_loop()', 'print(loop.get_debug())')) # Test with -E to not fail if the unit test was run with @@ -801,6 +795,17 @@ class BaseEventLoopTests(test_utils.TestCase): task._log_destroy_pending = False coro.close() + def test_create_task_error_closes_coro(self): + async def test(): + pass + loop = asyncio.new_event_loop() + loop.close() + with warnings.catch_warnings(record=True) as w: + with self.assertRaises(RuntimeError): + asyncio.ensure_future(test(), loop=loop) + self.assertEqual(len(w), 0) + + def test_create_named_task_with_default_factory(self): async def test(): pass @@ -856,20 +861,15 @@ class BaseEventLoopTests(test_utils.TestCase): self.loop._process_events = mock.Mock() - try: + with self.assertRaises(KeyboardInterrupt): self.loop.run_until_complete(raise_keyboard_interrupt()) - except KeyboardInterrupt: - pass def func(): self.loop.stop() func.called = True func.called = False - try: - self.loop.call_soon(func) - self.loop.run_forever() - except KeyboardInterrupt: - pass + self.loop.call_soon(self.loop.call_soon, func) + self.loop.run_forever() self.assertTrue(func.called) def test_single_selecter_event_callback_after_stopping(self): @@ -1003,22 +1003,26 @@ class MyProto(asyncio.Protocol): if create_future: self.done = asyncio.get_running_loop().create_future() + def _assert_state(self, *expected): + if self.state not in expected: + raise AssertionError(f'state: {self.state!r}, expected: {expected!r}') + def connection_made(self, transport): self.transport = transport - assert self.state == 'INITIAL', self.state + self._assert_state('INITIAL') self.state = 'CONNECTED' transport.write(b'GET / HTTP/1.0\r\nHost: example.com\r\n\r\n') def data_received(self, data): - assert self.state == 'CONNECTED', self.state + self._assert_state('CONNECTED') self.nbytes += len(data) def eof_received(self): - assert self.state == 'CONNECTED', self.state + self._assert_state('CONNECTED') self.state = 'EOF' def connection_lost(self, exc): - assert self.state in ('CONNECTED', 'EOF'), self.state + self._assert_state('CONNECTED', 'EOF') self.state = 'CLOSED' if self.done: self.done.set_result(None) @@ -1033,20 +1037,24 @@ class MyDatagramProto(asyncio.DatagramProtocol): if create_future: self.done = loop.create_future() + def _assert_state(self, expected): + if self.state != expected: + raise AssertionError(f'state: {self.state!r}, expected: {expected!r}') + def connection_made(self, transport): self.transport = transport - assert self.state == 'INITIAL', self.state + self._assert_state('INITIAL') self.state = 'INITIALIZED' def datagram_received(self, data, addr): - assert self.state == 'INITIALIZED', self.state + self._assert_state('INITIALIZED') self.nbytes += len(data) def error_received(self, exc): - assert self.state == 'INITIALIZED', self.state + self._assert_state('INITIALIZED') def connection_lost(self, exc): - assert self.state == 'INITIALIZED', self.state + self._assert_state('INITIALIZED') self.state = 'CLOSED' if self.done: self.done.set_result(None) @@ -1096,6 +1104,15 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): self.assertEqual(str(cm.exception), 'Multiple exceptions: err1, err2') + idx = -1 + coro = self.loop.create_connection(MyProto, 'example.com', 80, all_errors=True) + with self.assertRaises(ExceptionGroup) as cm: + self.loop.run_until_complete(coro) + + self.assertIsInstance(cm.exception, ExceptionGroup) + for e in cm.exception.exceptions: + self.assertIsInstance(e, OSError) + @patch_socket def test_create_connection_timeout(self, m_socket): # Ensure that the socket is closed on timeout @@ -1215,6 +1232,14 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): self.assertRaises( OSError, self.loop.run_until_complete, coro) + coro = self.loop.create_connection(MyProto, 'example.com', 80, all_errors=True) + with self.assertRaises(ExceptionGroup) as cm: + self.loop.run_until_complete(coro) + + self.assertIsInstance(cm.exception, ExceptionGroup) + self.assertEqual(len(cm.exception.exceptions), 1) + self.assertIsInstance(cm.exception.exceptions[0], OSError) + def test_create_connection_multiple(self): async def getaddrinfo(*args, **kw): return [(2, 1, 6, '', ('0.0.0.1', 80)), @@ -1232,6 +1257,15 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): with self.assertRaises(OSError): self.loop.run_until_complete(coro) + coro = self.loop.create_connection( + MyProto, 'example.com', 80, family=socket.AF_INET, all_errors=True) + with self.assertRaises(ExceptionGroup) as cm: + self.loop.run_until_complete(coro) + + self.assertIsInstance(cm.exception, ExceptionGroup) + for e in cm.exception.exceptions: + self.assertIsInstance(e, OSError) + @patch_socket def test_create_connection_multiple_errors_local_addr(self, m_socket): @@ -1263,6 +1297,16 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): self.assertTrue(str(cm.exception).startswith('Multiple exceptions: ')) self.assertTrue(m_socket.socket.return_value.close.called) + coro = self.loop.create_connection( + MyProto, 'example.com', 80, family=socket.AF_INET, + local_addr=(None, 8080), all_errors=True) + with self.assertRaises(ExceptionGroup) as cm: + self.loop.run_until_complete(coro) + + self.assertIsInstance(cm.exception, ExceptionGroup) + for e in cm.exception.exceptions: + self.assertIsInstance(e, OSError) + def _test_create_connection_ip_addr(self, m_socket, allow_inet_pton): # Test the fallback code, even if this system has inet_pton. if not allow_inet_pton: @@ -1272,9 +1316,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): sock = m_socket.socket.return_value self.loop._add_reader = mock.Mock() - self.loop._add_reader._is_coroutine = False self.loop._add_writer = mock.Mock() - self.loop._add_writer._is_coroutine = False coro = self.loop.create_connection(asyncio.Protocol, '1.2.3.4', 80) t, p = self.loop.run_until_complete(coro) @@ -1316,9 +1358,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): sock.family = socket.AF_INET6 self.loop._add_reader = mock.Mock() - self.loop._add_reader._is_coroutine = False self.loop._add_writer = mock.Mock() - self.loop._add_writer._is_coroutine = False coro = self.loop.create_connection(asyncio.Protocol, 'fe80::1%1', 80) t, p = self.loop.run_until_complete(coro) @@ -1345,9 +1385,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): sock = m_socket.socket.return_value self.loop._add_reader = mock.Mock() - self.loop._add_reader._is_coroutine = False self.loop._add_writer = mock.Mock() - self.loop._add_writer._is_coroutine = False for service, port in ('http', 80), (b'http', 80): coro = self.loop.create_connection(asyncio.Protocol, @@ -1395,7 +1433,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): addr = ('00:01:02:03:04:05', 1) def getaddrinfo(host, port, *args, **kw): - assert (host, port) == addr + self.assertEqual((host, port), addr) return [(999, 1, 999, '', (addr, 1))] m_socket.getaddrinfo = getaddrinfo @@ -1437,44 +1475,51 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): self.loop._make_ssl_transport.side_effect = mock_make_ssl_transport ANY = mock.ANY handshake_timeout = object() + shutdown_timeout = object() # First try the default server_hostname. self.loop._make_ssl_transport.reset_mock() coro = self.loop.create_connection( MyProto, 'python.org', 80, ssl=True, - ssl_handshake_timeout=handshake_timeout) + ssl_handshake_timeout=handshake_timeout, + ssl_shutdown_timeout=shutdown_timeout) transport, _ = self.loop.run_until_complete(coro) transport.close() self.loop._make_ssl_transport.assert_called_with( ANY, ANY, ANY, ANY, server_side=False, server_hostname='python.org', - ssl_handshake_timeout=handshake_timeout) + ssl_handshake_timeout=handshake_timeout, + ssl_shutdown_timeout=shutdown_timeout) # Next try an explicit server_hostname. self.loop._make_ssl_transport.reset_mock() coro = self.loop.create_connection( MyProto, 'python.org', 80, ssl=True, server_hostname='perl.com', - ssl_handshake_timeout=handshake_timeout) + ssl_handshake_timeout=handshake_timeout, + ssl_shutdown_timeout=shutdown_timeout) transport, _ = self.loop.run_until_complete(coro) transport.close() self.loop._make_ssl_transport.assert_called_with( ANY, ANY, ANY, ANY, server_side=False, server_hostname='perl.com', - ssl_handshake_timeout=handshake_timeout) + ssl_handshake_timeout=handshake_timeout, + ssl_shutdown_timeout=shutdown_timeout) # Finally try an explicit empty server_hostname. self.loop._make_ssl_transport.reset_mock() coro = self.loop.create_connection( MyProto, 'python.org', 80, ssl=True, server_hostname='', - ssl_handshake_timeout=handshake_timeout) + ssl_handshake_timeout=handshake_timeout, + ssl_shutdown_timeout=shutdown_timeout) transport, _ = self.loop.run_until_complete(coro) transport.close() self.loop._make_ssl_transport.assert_called_with( ANY, ANY, ANY, ANY, server_side=False, server_hostname='', - ssl_handshake_timeout=handshake_timeout) + ssl_handshake_timeout=handshake_timeout, + ssl_shutdown_timeout=shutdown_timeout) def test_create_connection_no_ssl_server_hostname_errors(self): # When not using ssl, server_hostname must be None. @@ -1569,7 +1614,6 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): m_socket.getaddrinfo.return_value = [ (2, 1, 6, '', ('127.0.0.1', 10100))] - m_socket.getaddrinfo._is_coroutine = False m_sock = m_socket.socket.return_value = mock.Mock() m_sock.bind.side_effect = Err @@ -1580,7 +1624,6 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): @patch_socket def test_create_datagram_endpoint_no_addrinfo(self, m_socket): m_socket.getaddrinfo.return_value = [] - m_socket.getaddrinfo._is_coroutine = False coro = self.loop.create_datagram_endpoint( MyDatagramProto, local_addr=('localhost', 0)) @@ -1591,11 +1634,11 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): coro = self.loop.create_datagram_endpoint( MyDatagramProto, local_addr='localhost') self.assertRaises( - AssertionError, self.loop.run_until_complete, coro) + TypeError, self.loop.run_until_complete, coro) coro = self.loop.create_datagram_endpoint( MyDatagramProto, local_addr=('localhost', 1, 2, 3)) self.assertRaises( - AssertionError, self.loop.run_until_complete, coro) + TypeError, self.loop.run_until_complete, coro) def test_create_datagram_endpoint_connect_err(self): self.loop.sock_connect = mock.Mock() @@ -1694,7 +1737,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): lambda: MyDatagramProto(create_future=True, loop=self.loop), family=socket.AF_UNIX) transport, protocol = self.loop.run_until_complete(fut) - assert transport._sock.family == socket.AF_UNIX + self.assertEqual(transport._sock.family, socket.AF_UNIX) transport.close() self.loop.run_until_complete(protocol.done) self.assertEqual('CLOSED', protocol.state) @@ -1814,7 +1857,6 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): m_socket.getaddrinfo = getaddrinfo m_socket.socket.return_value.bind = bind = mock.Mock() self.loop._add_reader = mock.Mock() - self.loop._add_reader._is_coroutine = False reuseport_supported = hasattr(socket, 'SO_REUSEPORT') coro = self.loop.create_datagram_endpoint( @@ -1855,7 +1897,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): constants.ACCEPT_RETRY_DELAY, # self.loop._start_serving mock.ANY, - MyProto, sock, None, None, mock.ANY, mock.ANY) + MyProto, sock, None, None, mock.ANY, mock.ANY, mock.ANY) def test_call_coroutine(self): async def simple_coroutine(): @@ -2005,11 +2047,11 @@ class BaseLoopSockSendfileTests(test_utils.TestCase): def cleanup(): server.close() - self.run_loop(server.wait_closed()) sock.close() if proto.transport is not None: proto.transport.close() self.run_loop(proto.wait_closed()) + self.run_loop(server.wait_closed()) self.addCleanup(cleanup) diff --git a/Lib/test/test_asyncio/test_context.py b/Lib/test/test_asyncio/test_context.py index 63b1eb320ce..6b80721873d 100644 --- a/Lib/test/test_asyncio/test_context.py +++ b/Lib/test/test_asyncio/test_context.py @@ -32,3 +32,7 @@ class DecimalContextTest(unittest.TestCase): self.assertEqual(str(r2[0]), '0.333333') self.assertEqual(str(r2[1]), '0.111111') + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index e50a53d7067..214544b89bc 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -22,14 +22,13 @@ import errno import unittest from unittest import mock import weakref - +import warnings if sys.platform not in ('win32', 'vxworks'): import tty import asyncio from asyncio import coroutines from asyncio import events -from asyncio import proactor_events from asyncio import selector_events from test.test_asyncio import utils as test_utils from test import support @@ -88,23 +87,27 @@ class MyBaseProto(asyncio.Protocol): self.connected = loop.create_future() self.done = loop.create_future() + def _assert_state(self, *expected): + if self.state not in expected: + raise AssertionError(f'state: {self.state!r}, expected: {expected!r}') + def connection_made(self, transport): self.transport = transport - assert self.state == 'INITIAL', self.state + self._assert_state('INITIAL') self.state = 'CONNECTED' if self.connected: self.connected.set_result(None) def data_received(self, data): - assert self.state == 'CONNECTED', self.state + self._assert_state('CONNECTED') self.nbytes += len(data) def eof_received(self): - assert self.state == 'CONNECTED', self.state + self._assert_state('CONNECTED') self.state = 'EOF' def connection_lost(self, exc): - assert self.state in ('CONNECTED', 'EOF'), self.state + self._assert_state('CONNECTED', 'EOF') self.state = 'CLOSED' if self.done: self.done.set_result(None) @@ -125,20 +128,24 @@ class MyDatagramProto(asyncio.DatagramProtocol): if loop is not None: self.done = loop.create_future() + def _assert_state(self, expected): + if self.state != expected: + raise AssertionError(f'state: {self.state!r}, expected: {expected!r}') + def connection_made(self, transport): self.transport = transport - assert self.state == 'INITIAL', self.state + self._assert_state('INITIAL') self.state = 'INITIALIZED' def datagram_received(self, data, addr): - assert self.state == 'INITIALIZED', self.state + self._assert_state('INITIALIZED') self.nbytes += len(data) def error_received(self, exc): - assert self.state == 'INITIALIZED', self.state + self._assert_state('INITIALIZED') def connection_lost(self, exc): - assert self.state == 'INITIALIZED', self.state + self._assert_state('INITIALIZED') self.state = 'CLOSED' if self.done: self.done.set_result(None) @@ -154,23 +161,27 @@ class MyReadPipeProto(asyncio.Protocol): if loop is not None: self.done = loop.create_future() + def _assert_state(self, expected): + if self.state != expected: + raise AssertionError(f'state: {self.state!r}, expected: {expected!r}') + def connection_made(self, transport): self.transport = transport - assert self.state == ['INITIAL'], self.state + self._assert_state(['INITIAL']) self.state.append('CONNECTED') def data_received(self, data): - assert self.state == ['INITIAL', 'CONNECTED'], self.state + self._assert_state(['INITIAL', 'CONNECTED']) self.nbytes += len(data) def eof_received(self): - assert self.state == ['INITIAL', 'CONNECTED'], self.state + self._assert_state(['INITIAL', 'CONNECTED']) self.state.append('EOF') def connection_lost(self, exc): if 'EOF' not in self.state: self.state.append('EOF') # It is okay if EOF is missed. - assert self.state == ['INITIAL', 'CONNECTED', 'EOF'], self.state + self._assert_state(['INITIAL', 'CONNECTED', 'EOF']) self.state.append('CLOSED') if self.done: self.done.set_result(None) @@ -185,13 +196,17 @@ class MyWritePipeProto(asyncio.BaseProtocol): if loop is not None: self.done = loop.create_future() + def _assert_state(self, expected): + if self.state != expected: + raise AssertionError(f'state: {self.state!r}, expected: {expected!r}') + def connection_made(self, transport): self.transport = transport - assert self.state == 'INITIAL', self.state + self._assert_state('INITIAL') self.state = 'CONNECTED' def connection_lost(self, exc): - assert self.state == 'CONNECTED', self.state + self._assert_state('CONNECTED') self.state = 'CLOSED' if self.done: self.done.set_result(None) @@ -210,31 +225,35 @@ class MySubprocessProtocol(asyncio.SubprocessProtocol): self.got_data = {1: asyncio.Event(), 2: asyncio.Event()} + def _assert_state(self, expected): + if self.state != expected: + raise AssertionError(f'state: {self.state!r}, expected: {expected!r}') + def connection_made(self, transport): self.transport = transport - assert self.state == 'INITIAL', self.state + self._assert_state('INITIAL') self.state = 'CONNECTED' self.connected.set_result(None) def connection_lost(self, exc): - assert self.state == 'CONNECTED', self.state + self._assert_state('CONNECTED') self.state = 'CLOSED' self.completed.set_result(None) def pipe_data_received(self, fd, data): - assert self.state == 'CONNECTED', self.state + self._assert_state('CONNECTED') self.data[fd] += data self.got_data[fd].set() def pipe_connection_lost(self, fd, exc): - assert self.state == 'CONNECTED', self.state + self._assert_state('CONNECTED') if exc: self.disconnects[fd].set_exception(exc) else: self.disconnects[fd].set_result(exc) def process_exited(self): - assert self.state == 'CONNECTED', self.state + self._assert_state('CONNECTED') self.returncode = self.transport.get_returncode() @@ -651,6 +670,47 @@ class EventLoopTestsMixin: self.assertEqual(port, expected) tr.close() + def test_create_connection_local_addr_skip_different_family(self): + # See https://github.com/python/cpython/issues/86508 + port1 = socket_helper.find_unused_port() + port2 = socket_helper.find_unused_port() + getaddrinfo_orig = self.loop.getaddrinfo + + async def getaddrinfo(host, port, *args, **kwargs): + if port == port2: + return [(socket.AF_INET6, socket.SOCK_STREAM, 0, '', ('::1', 0, 0, 0)), + (socket.AF_INET, socket.SOCK_STREAM, 0, '', ('127.0.0.1', 0))] + return await getaddrinfo_orig(host, port, *args, **kwargs) + + self.loop.getaddrinfo = getaddrinfo + + f = self.loop.create_connection( + lambda: MyProto(loop=self.loop), + 'localhost', port1, local_addr=('localhost', port2)) + + with self.assertRaises(OSError): + self.loop.run_until_complete(f) + + def test_create_connection_local_addr_nomatch_family(self): + # See https://github.com/python/cpython/issues/86508 + port1 = socket_helper.find_unused_port() + port2 = socket_helper.find_unused_port() + getaddrinfo_orig = self.loop.getaddrinfo + + async def getaddrinfo(host, port, *args, **kwargs): + if port == port2: + return [(socket.AF_INET6, socket.SOCK_STREAM, 0, '', ('::1', 0, 0, 0))] + return await getaddrinfo_orig(host, port, *args, **kwargs) + + self.loop.getaddrinfo = getaddrinfo + + f = self.loop.create_connection( + lambda: MyProto(loop=self.loop), + 'localhost', port1, local_addr=('localhost', port2)) + + with self.assertRaises(OSError): + self.loop.run_until_complete(f) + def test_create_connection_local_addr_in_use(self): with test_utils.run_test_server() as httpd: f = self.loop.create_connection( @@ -717,14 +777,6 @@ class EventLoopTestsMixin: @unittest.skipIf(ssl is None, 'No ssl module') def test_ssl_connect_accepted_socket(self): - if (sys.platform == 'win32' and - sys.version_info < (3, 5) and - isinstance(self.loop, proactor_events.BaseProactorEventLoop) - ): - raise unittest.SkipTest( - 'SSL not supported with proactor event loops before Python 3.5' - ) - server_context = test_utils.simple_server_sslcontext() client_context = test_utils.simple_client_sslcontext() @@ -812,6 +864,29 @@ class EventLoopTestsMixin: # close server server.close() + def test_create_server_trsock(self): + proto = MyProto(self.loop) + f = self.loop.create_server(lambda: proto, '0.0.0.0', 0) + server = self.loop.run_until_complete(f) + self.assertEqual(len(server.sockets), 1) + sock = server.sockets[0] + self.assertIsInstance(sock, asyncio.trsock.TransportSocket) + host, port = sock.getsockname() + self.assertEqual(host, '0.0.0.0') + dup = sock.dup() + self.addCleanup(dup.close) + self.assertIsInstance(dup, socket.socket) + self.assertFalse(sock.get_inheritable()) + with self.assertRaises(ValueError): + sock.settimeout(1) + sock.settimeout(0) + self.assertEqual(sock.gettimeout(), 0) + with self.assertRaises(ValueError): + sock.setblocking(True) + sock.setblocking(False) + server.close() + + @unittest.skipUnless(hasattr(socket, 'SO_REUSEPORT'), 'No SO_REUSEPORT') def test_create_server_reuse_port(self): proto = MyProto(self.loop) @@ -1284,7 +1359,7 @@ class EventLoopTestsMixin: else: break else: - assert False, 'Can not create socket.' + self.fail('Can not create socket.') f = self.loop.create_datagram_endpoint( lambda: MyDatagramProto(loop=self.loop), sock=sock) @@ -2044,12 +2119,16 @@ else: class UnixEventLoopTestsMixin(EventLoopTestsMixin): def setUp(self): super().setUp() - watcher = asyncio.SafeChildWatcher() - watcher.attach_loop(self.loop) - asyncio.set_child_watcher(watcher) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + watcher = asyncio.SafeChildWatcher() + watcher.attach_loop(self.loop) + asyncio.set_child_watcher(watcher) def tearDown(self): - asyncio.set_child_watcher(None) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + asyncio.set_child_watcher(None) super().tearDown() @@ -2186,17 +2265,15 @@ class HandleTests(test_utils.TestCase): self.assertRegex(repr(h), regex) # partial method - if sys.version_info >= (3, 4): - method = HandleTests.test_handle_repr - cb = functools.partialmethod(method) - filename, lineno = test_utils.get_function_source(method) - h = asyncio.Handle(cb, (), self.loop) + method = HandleTests.test_handle_repr + cb = functools.partialmethod(method) + filename, lineno = test_utils.get_function_source(method) + h = asyncio.Handle(cb, (), self.loop) - cb_regex = r'' - cb_regex = (r'functools.partialmethod\(%s, , \)\(\)' % cb_regex) - regex = (r'^$' - % (cb_regex, re.escape(filename), lineno)) - self.assertRegex(repr(h), regex) + cb_regex = r'' + cb_regex = fr'functools.partialmethod\({cb_regex}, , \)\(\)' + regex = fr'^$' + self.assertRegex(repr(h), regex) def test_handle_repr_debug(self): self.loop.get_debug.return_value = True @@ -2322,10 +2399,6 @@ class TimerTests(unittest.TestCase): self.assertIsNone(h._callback) self.assertIsNone(h._args) - # when cannot be None - self.assertRaises(AssertionError, - asyncio.TimerHandle, None, callback, args, - self.loop) def test_timer_repr(self): self.loop.get_debug.return_value = False @@ -2541,8 +2614,9 @@ class PolicyTests(unittest.TestCase): def test_get_event_loop(self): policy = asyncio.DefaultEventLoopPolicy() self.assertIsNone(policy._local._loop) - - loop = policy.get_event_loop() + with self.assertWarns(DeprecationWarning) as cm: + loop = policy.get_event_loop() + self.assertEqual(cm.filename, __file__) self.assertIsInstance(loop, asyncio.AbstractEventLoop) self.assertIs(policy._local._loop, loop) @@ -2556,7 +2630,10 @@ class PolicyTests(unittest.TestCase): policy, "set_event_loop", wraps=policy.set_event_loop) as m_set_event_loop: - loop = policy.get_event_loop() + with self.assertWarns(DeprecationWarning) as cm: + loop = policy.get_event_loop() + self.addCleanup(loop.close) + self.assertEqual(cm.filename, __file__) # policy._local._loop must be set through .set_event_loop() # (the unix DefaultEventLoopPolicy needs this call to attach @@ -2590,9 +2667,10 @@ class PolicyTests(unittest.TestCase): def test_set_event_loop(self): policy = asyncio.DefaultEventLoopPolicy() - old_loop = policy.get_event_loop() + old_loop = policy.new_event_loop() + policy.set_event_loop(old_loop) - self.assertRaises(AssertionError, policy.set_event_loop, object()) + self.assertRaises(TypeError, policy.set_event_loop, object()) loop = policy.new_event_loop() policy.set_event_loop(loop) @@ -2608,7 +2686,7 @@ class PolicyTests(unittest.TestCase): def test_set_event_loop_policy(self): self.assertRaises( - AssertionError, asyncio.set_event_loop_policy, object()) + TypeError, asyncio.set_event_loop_policy, object()) old_policy = asyncio.get_event_loop_policy() @@ -2647,14 +2725,18 @@ class GetEventLoopTestsMixin: asyncio.set_event_loop(self.loop) if sys.platform != 'win32': - watcher = asyncio.SafeChildWatcher() - watcher.attach_loop(self.loop) - asyncio.set_child_watcher(watcher) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + watcher = asyncio.SafeChildWatcher() + watcher.attach_loop(self.loop) + asyncio.set_child_watcher(watcher) def tearDown(self): try: if sys.platform != 'win32': - asyncio.set_child_watcher(None) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + asyncio.set_child_watcher(None) super().tearDown() finally: @@ -2703,15 +2785,11 @@ class GetEventLoopTestsMixin: asyncio.set_event_loop_policy(Policy()) loop = asyncio.new_event_loop() - with self.assertWarns(DeprecationWarning) as cm: - with self.assertRaises(TestError): - asyncio.get_event_loop() - self.assertEqual(cm.warnings[0].filename, __file__) + with self.assertRaises(TestError): + asyncio.get_event_loop() asyncio.set_event_loop(None) - with self.assertWarns(DeprecationWarning) as cm: - with self.assertRaises(TestError): - asyncio.get_event_loop() - self.assertEqual(cm.warnings[0].filename, __file__) + with self.assertRaises(TestError): + asyncio.get_event_loop() with self.assertRaisesRegex(RuntimeError, 'no running'): asyncio.get_running_loop() @@ -2725,16 +2803,11 @@ class GetEventLoopTestsMixin: loop.run_until_complete(func()) asyncio.set_event_loop(loop) - with self.assertWarns(DeprecationWarning) as cm: - with self.assertRaises(TestError): - asyncio.get_event_loop() - self.assertEqual(cm.warnings[0].filename, __file__) - + with self.assertRaises(TestError): + asyncio.get_event_loop() asyncio.set_event_loop(None) - with self.assertWarns(DeprecationWarning) as cm: - with self.assertRaises(TestError): - asyncio.get_event_loop() - self.assertEqual(cm.warnings[0].filename, __file__) + with self.assertRaises(TestError): + asyncio.get_event_loop() finally: asyncio.set_event_loop_policy(old_policy) @@ -2756,12 +2829,10 @@ class GetEventLoopTestsMixin: with self.assertWarns(DeprecationWarning) as cm: loop2 = asyncio.get_event_loop() self.addCleanup(loop2.close) - self.assertEqual(cm.warnings[0].filename, __file__) + self.assertEqual(cm.filename, __file__) asyncio.set_event_loop(None) - with self.assertWarns(DeprecationWarning) as cm: - with self.assertRaisesRegex(RuntimeError, 'no current'): - asyncio.get_event_loop() - self.assertEqual(cm.warnings[0].filename, __file__) + with self.assertRaisesRegex(RuntimeError, 'no current'): + asyncio.get_event_loop() with self.assertRaisesRegex(RuntimeError, 'no running'): asyncio.get_running_loop() @@ -2775,15 +2846,11 @@ class GetEventLoopTestsMixin: loop.run_until_complete(func()) asyncio.set_event_loop(loop) - with self.assertWarns(DeprecationWarning) as cm: - self.assertIs(asyncio.get_event_loop(), loop) - self.assertEqual(cm.warnings[0].filename, __file__) + self.assertIs(asyncio.get_event_loop(), loop) asyncio.set_event_loop(None) - with self.assertWarns(DeprecationWarning) as cm: - with self.assertRaisesRegex(RuntimeError, 'no current'): - asyncio.get_event_loop() - self.assertEqual(cm.warnings[0].filename, __file__) + with self.assertRaisesRegex(RuntimeError, 'no current'): + asyncio.get_event_loop() finally: asyncio.set_event_loop_policy(old_policy) diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index 42b9499edd7..2184b2091f8 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -7,9 +7,10 @@ import sys import threading import unittest from unittest import mock - +from types import GenericAlias import asyncio from asyncio import futures +import warnings from test.test_asyncio import utils as test_utils from test import support @@ -54,30 +55,30 @@ class DuckFuture: or self.__exception is not None) def result(self): - assert not self.cancelled() + self.assertFalse(self.cancelled()) if self.__exception is not None: raise self.__exception return self.__result def exception(self): - assert not self.cancelled() + self.assertFalse(self.cancelled()) return self.__exception def set_result(self, result): - assert not self.done() - assert result is not None + self.assertFalse(self.done()) + self.assertIsNotNone(result) self.__result = result def set_exception(self, exception): - assert not self.done() - assert exception is not None + self.assertFalse(self.done()) + self.assertIsNotNone(exception) self.__exception = exception def __iter__(self): if not self.done(): self._asyncio_future_blocking = True yield self - assert self.done() + self.assertTrue(self.done()) return self.result() @@ -91,12 +92,12 @@ class DuckTests(test_utils.TestCase): def test_wrap_future(self): f = DuckFuture() g = asyncio.wrap_future(f) - assert g is f + self.assertIs(g, f) def test_ensure_future(self): f = DuckFuture() g = asyncio.ensure_future(f) - assert g is f + self.assertIs(g, f) class BaseFutureTests: @@ -109,6 +110,11 @@ class BaseFutureTests: self.loop = self.new_test_loop() self.addCleanup(self.loop.close) + def test_generic_alias(self): + future = self.cls[str] + self.assertEqual(future.__args__, (str,)) + self.assertIsInstance(future, GenericAlias) + def test_isfuture(self): class MyFuture: _asyncio_future_blocking = None @@ -140,10 +146,8 @@ class BaseFutureTests: self.assertTrue(f.cancelled()) def test_constructor_without_loop(self): - with self.assertWarns(DeprecationWarning) as cm: - with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'): - self._new_future() - self.assertEqual(cm.warnings[0].filename, __file__) + with self.assertRaisesRegex(RuntimeError, 'no current event loop'): + self._new_future() def test_constructor_use_running_loop(self): async def test(): @@ -153,12 +157,10 @@ class BaseFutureTests: self.assertIs(f.get_loop(), self.loop) def test_constructor_use_global_loop(self): - # Deprecated in 3.10 + # Deprecated in 3.10, undeprecated in 3.12 asyncio.set_event_loop(self.loop) self.addCleanup(asyncio.set_event_loop, None) - with self.assertWarns(DeprecationWarning) as cm: - f = self._new_future() - self.assertEqual(cm.warnings[0].filename, __file__) + f = self._new_future() self.assertIs(f._loop, self.loop) self.assertIs(f.get_loop(), self.loop) @@ -494,10 +496,8 @@ class BaseFutureTests: return (arg, threading.get_ident()) ex = concurrent.futures.ThreadPoolExecutor(1) f1 = ex.submit(run, 'oi') - with self.assertWarns(DeprecationWarning) as cm: - with self.assertRaises(RuntimeError): - asyncio.wrap_future(f1) - self.assertEqual(cm.warnings[0].filename, __file__) + with self.assertRaisesRegex(RuntimeError, 'no current event loop'): + asyncio.wrap_future(f1) ex.shutdown(wait=True) def test_wrap_future_use_running_loop(self): @@ -512,16 +512,14 @@ class BaseFutureTests: ex.shutdown(wait=True) def test_wrap_future_use_global_loop(self): - # Deprecated in 3.10 + # Deprecated in 3.10, undeprecated in 3.12 asyncio.set_event_loop(self.loop) self.addCleanup(asyncio.set_event_loop, None) def run(arg): return (arg, threading.get_ident()) ex = concurrent.futures.ThreadPoolExecutor(1) f1 = ex.submit(run, 'oi') - with self.assertWarns(DeprecationWarning) as cm: - f2 = asyncio.wrap_future(f1) - self.assertEqual(cm.warnings[0].filename, __file__) + f2 = asyncio.wrap_future(f1) self.assertIs(self.loop, f2._loop) ex.shutdown(wait=True) @@ -571,13 +569,10 @@ class BaseFutureTests: test_utils.run_briefly(self.loop) support.gc_collect() - if sys.version_info >= (3, 4): - regex = f'^{self.cls.__name__} exception was never retrieved\n' - exc_info = (type(exc), exc, exc.__traceback__) - m_log.error.assert_called_once_with(mock.ANY, exc_info=exc_info) - else: - regex = r'^Future/Task exception was never retrieved\n' - m_log.error.assert_called_once_with(mock.ANY, exc_info=False) + regex = f'^{self.cls.__name__} exception was never retrieved\n' + exc_info = (type(exc), exc, exc.__traceback__) + m_log.error.assert_called_once_with(mock.ANY, exc_info=exc_info) + message = m_log.error.call_args[0][0] self.assertRegex(message, re.compile(regex, re.DOTALL)) @@ -609,10 +604,16 @@ class BaseFutureTests: def test_future_iter_throw(self): fut = self._new_future(loop=self.loop) fi = iter(fut) - self.assertRaises(TypeError, fi.throw, - Exception, Exception("elephant"), 32) - self.assertRaises(TypeError, fi.throw, - Exception("elephant"), Exception("elephant")) + with self.assertWarns(DeprecationWarning): + self.assertRaises(Exception, fi.throw, Exception, Exception("zebra"), None) + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=DeprecationWarning) + self.assertRaises(TypeError, fi.throw, + Exception, Exception("elephant"), 32) + self.assertRaises(TypeError, fi.throw, + Exception("elephant"), Exception("elephant")) + # https://github.com/python/cpython/issues/101326 + self.assertRaises(ValueError, fi.throw, ValueError, None, None) self.assertRaises(TypeError, fi.throw, list) def test_future_del_collect(self): @@ -822,6 +823,21 @@ class BaseFutureDoneCallbackTests(): fut.remove_done_callback(evil()) + def test_remove_done_callbacks_list_clear(self): + # see https://github.com/python/cpython/issues/97592 for details + + fut = self._new_future() + fut.add_done_callback(str) + + for _ in range(63): + fut.add_done_callback(id) + + class evil: + def __eq__(self, other): + fut.remove_done_callback(other) + + fut.remove_done_callback(evil()) + def test_schedule_callbacks_list_mutation_1(self): # see http://bugs.python.org/issue28963 for details diff --git a/Lib/test/test_asyncio/test_futures2.py b/Lib/test/test_asyncio/test_futures2.py index 13dbc703277..9e7a5775a70 100644 --- a/Lib/test/test_asyncio/test_futures2.py +++ b/Lib/test/test_asyncio/test_futures2.py @@ -1,9 +1,83 @@ # IsolatedAsyncioTestCase based tests import asyncio +import contextvars +import traceback import unittest +from asyncio import tasks -class FutureTests(unittest.IsolatedAsyncioTestCase): +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + +class FutureTests: + + async def test_future_traceback(self): + + async def raise_exc(): + raise TypeError(42) + + future = self.cls(raise_exc()) + + for _ in range(5): + try: + await future + except TypeError as e: + tb = ''.join(traceback.format_tb(e.__traceback__)) + self.assertEqual(tb.count("await future"), 1) + else: + self.fail('TypeError was not raised') + + async def test_task_exc_handler_correct_context(self): + # see https://github.com/python/cpython/issues/96704 + name = contextvars.ContextVar('name', default='foo') + exc_handler_called = False + + def exc_handler(*args): + self.assertEqual(name.get(), 'bar') + nonlocal exc_handler_called + exc_handler_called = True + + async def task(): + name.set('bar') + 1/0 + + loop = asyncio.get_running_loop() + loop.set_exception_handler(exc_handler) + self.cls(task()) + await asyncio.sleep(0) + self.assertTrue(exc_handler_called) + + async def test_handle_exc_handler_correct_context(self): + # see https://github.com/python/cpython/issues/96704 + name = contextvars.ContextVar('name', default='foo') + exc_handler_called = False + + def exc_handler(*args): + self.assertEqual(name.get(), 'bar') + nonlocal exc_handler_called + exc_handler_called = True + + def callback(): + name.set('bar') + 1/0 + + loop = asyncio.get_running_loop() + loop.set_exception_handler(exc_handler) + loop.call_soon(callback) + await asyncio.sleep(0) + self.assertTrue(exc_handler_called) + +@unittest.skipUnless(hasattr(tasks, '_CTask'), + 'requires the C _asyncio module') +class CFutureTests(FutureTests, unittest.IsolatedAsyncioTestCase): + cls = tasks._CTask + +class PyFutureTests(FutureTests, unittest.IsolatedAsyncioTestCase): + cls = tasks._PyTask + +class FutureReprTests(unittest.IsolatedAsyncioTestCase): + async def test_recursive_repr_for_pending_tasks(self): # The call crashes if the guard for recursive call # in base_futures:_future_repr_info is absent @@ -16,3 +90,7 @@ class FutureTests(unittest.IsolatedAsyncioTestCase): # The check for returned string is not very reliable but # exact comparison for the whole string is even weaker. self.assertIn('...', repr(await asyncio.wait_for(func(), timeout=10))) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index b2492c1acfe..f6c6a282429 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -1,16 +1,19 @@ -"""Tests for lock.py""" +"""Tests for locks.py""" import unittest from unittest import mock import re import asyncio -from test.test_asyncio import utils as test_utils +import collections STR_RGX_REPR = ( r'^<(?P.*?) object at (?P
    .*?)' r'\[(?P' - r'(set|unset|locked|unlocked)(, value:\d)?(, waiters:\d+)?' + r'(set|unset|locked|unlocked|filling|draining|resetting|broken)' + r'(, value:\d)?' + r'(, waiters:\d+)?' + r'(, waiters:\d+\/\d+)?' # barrier r')\]>\Z' ) RGX_REPR = re.compile(STR_RGX_REPR) @@ -20,36 +23,29 @@ def tearDownModule(): asyncio.set_event_loop_policy(None) -class LockTests(test_utils.TestCase): +class LockTests(unittest.IsolatedAsyncioTestCase): - def setUp(self): - super().setUp() - self.loop = self.new_test_loop() - - def test_repr(self): + async def test_repr(self): lock = asyncio.Lock() self.assertTrue(repr(lock).endswith('[unlocked]>')) self.assertTrue(RGX_REPR.match(repr(lock))) - self.loop.run_until_complete(lock.acquire()) + await lock.acquire() self.assertTrue(repr(lock).endswith('[locked]>')) self.assertTrue(RGX_REPR.match(repr(lock))) - def test_lock(self): + async def test_lock(self): lock = asyncio.Lock() - async def acquire_lock(): - return await lock - with self.assertRaisesRegex( TypeError, "object Lock can't be used in 'await' expression" ): - self.loop.run_until_complete(acquire_lock()) + await lock self.assertFalse(lock.locked()) - def test_lock_doesnt_accept_loop_parameter(self): + async def test_lock_doesnt_accept_loop_parameter(self): primitives_cls = [ asyncio.Lock, asyncio.Condition, @@ -58,17 +54,17 @@ class LockTests(test_utils.TestCase): asyncio.BoundedSemaphore, ] + loop = asyncio.get_running_loop() + for cls in primitives_cls: with self.assertRaisesRegex( TypeError, - rf'As of 3.10, the \*loop\* parameter was removed from ' - rf'{cls.__name__}\(\) since it is no longer necessary' + rf"{cls.__name__}\.__init__\(\) got an unexpected " + rf"keyword argument 'loop'" ): - cls(loop=self.loop) + cls(loop=loop) - def test_lock_by_with_statement(self): - loop = asyncio.new_event_loop() # don't use TestLoop quirks - self.set_event_loop(loop) + async def test_lock_by_with_statement(self): primitives = [ asyncio.Lock(), asyncio.Condition(), @@ -76,7 +72,7 @@ class LockTests(test_utils.TestCase): asyncio.BoundedSemaphore(), ] - async def test(lock): + for lock in primitives: await asyncio.sleep(0.01) self.assertFalse(lock.locked()) with self.assertRaisesRegex( @@ -87,15 +83,11 @@ class LockTests(test_utils.TestCase): pass self.assertFalse(lock.locked()) - for primitive in primitives: - loop.run_until_complete(test(primitive)) - self.assertFalse(primitive.locked()) - - def test_acquire(self): + async def test_acquire(self): lock = asyncio.Lock() result = [] - self.assertTrue(self.loop.run_until_complete(lock.acquire())) + self.assertTrue(await lock.acquire()) async def c1(result): if await lock.acquire(): @@ -112,27 +104,27 @@ class LockTests(test_utils.TestCase): result.append(3) return True - t1 = self.loop.create_task(c1(result)) - t2 = self.loop.create_task(c2(result)) + t1 = asyncio.create_task(c1(result)) + t2 = asyncio.create_task(c2(result)) - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([], result) lock.release() - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([1], result) - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([1], result) - t3 = self.loop.create_task(c3(result)) + t3 = asyncio.create_task(c3(result)) lock.release() - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([1, 2], result) lock.release() - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([1, 2, 3], result) self.assertTrue(t1.done()) @@ -142,18 +134,17 @@ class LockTests(test_utils.TestCase): self.assertTrue(t3.done()) self.assertTrue(t3.result()) - def test_acquire_cancel(self): + async def test_acquire_cancel(self): lock = asyncio.Lock() - self.assertTrue(self.loop.run_until_complete(lock.acquire())) + self.assertTrue(await lock.acquire()) - task = self.loop.create_task(lock.acquire()) - self.loop.call_soon(task.cancel) - self.assertRaises( - asyncio.CancelledError, - self.loop.run_until_complete, task) + task = asyncio.create_task(lock.acquire()) + asyncio.get_running_loop().call_soon(task.cancel) + with self.assertRaises(asyncio.CancelledError): + await task self.assertFalse(lock._waiters) - def test_cancel_race(self): + async def test_cancel_race(self): # Several tasks: # - A acquires the lock # - B is blocked in acquire() @@ -178,15 +169,15 @@ class LockTests(test_utils.TestCase): finally: lock.release() - fa = self.loop.create_future() - ta = self.loop.create_task(lockit('A', fa)) - test_utils.run_briefly(self.loop) + fa = asyncio.get_running_loop().create_future() + ta = asyncio.create_task(lockit('A', fa)) + await asyncio.sleep(0) self.assertTrue(lock.locked()) - tb = self.loop.create_task(lockit('B', None)) - test_utils.run_briefly(self.loop) + tb = asyncio.create_task(lockit('B', None)) + await asyncio.sleep(0) self.assertEqual(len(lock._waiters), 1) - tc = self.loop.create_task(lockit('C', None)) - test_utils.run_briefly(self.loop) + tc = asyncio.create_task(lockit('C', None)) + await asyncio.sleep(0) self.assertEqual(len(lock._waiters), 2) # Create the race and check. @@ -194,16 +185,17 @@ class LockTests(test_utils.TestCase): fa.set_result(None) tb.cancel() self.assertTrue(lock._waiters[0].cancelled()) - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertFalse(lock.locked()) self.assertTrue(ta.done()) self.assertTrue(tb.cancelled()) - self.assertTrue(tc.done()) + await tc - def test_cancel_release_race(self): + async def test_cancel_release_race(self): # Issue 32734 # Acquire 4 locks, cancel second, release first # and 2 locks are taken at once. + loop = asyncio.get_running_loop() lock = asyncio.Lock() lock_count = 0 call_count = 0 @@ -215,27 +207,23 @@ class LockTests(test_utils.TestCase): await lock.acquire() lock_count += 1 - async def lockandtrigger(): - await lock.acquire() - self.loop.call_soon(trigger) - def trigger(): t1.cancel() lock.release() - t0 = self.loop.create_task(lockandtrigger()) - t1 = self.loop.create_task(lockit()) - t2 = self.loop.create_task(lockit()) - t3 = self.loop.create_task(lockit()) + await lock.acquire() - # First loop acquires all - test_utils.run_briefly(self.loop) - self.assertTrue(t0.done()) + t1 = asyncio.create_task(lockit()) + t2 = asyncio.create_task(lockit()) + t3 = asyncio.create_task(lockit()) - # Second loop calls trigger - test_utils.run_briefly(self.loop) - # Third loop calls cancellation - test_utils.run_briefly(self.loop) + # Start scheduled tasks + await asyncio.sleep(0) + + loop.call_soon(trigger) + with self.assertRaises(asyncio.CancelledError): + # Wait for cancellation + await t1 # Make sure only one lock was taken self.assertEqual(lock_count, 1) @@ -245,62 +233,56 @@ class LockTests(test_utils.TestCase): # Cleanup the task that is stuck on acquire. t3.cancel() - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertTrue(t3.cancelled()) - def test_finished_waiter_cancelled(self): + async def test_finished_waiter_cancelled(self): lock = asyncio.Lock() - ta = self.loop.create_task(lock.acquire()) - test_utils.run_briefly(self.loop) + await lock.acquire() self.assertTrue(lock.locked()) - tb = self.loop.create_task(lock.acquire()) - test_utils.run_briefly(self.loop) + tb = asyncio.create_task(lock.acquire()) + await asyncio.sleep(0) self.assertEqual(len(lock._waiters), 1) # Create a second waiter, wake up the first, and cancel it. # Without the fix, the second was not woken up. - tc = self.loop.create_task(lock.acquire()) - lock.release() + tc = asyncio.create_task(lock.acquire()) tb.cancel() - test_utils.run_briefly(self.loop) + lock.release() + await asyncio.sleep(0) self.assertTrue(lock.locked()) - self.assertTrue(ta.done()) self.assertTrue(tb.cancelled()) - def test_release_not_acquired(self): + # Cleanup + await tc + + async def test_release_not_acquired(self): lock = asyncio.Lock() self.assertRaises(RuntimeError, lock.release) - def test_release_no_waiters(self): + async def test_release_no_waiters(self): lock = asyncio.Lock() - self.loop.run_until_complete(lock.acquire()) + await lock.acquire() self.assertTrue(lock.locked()) lock.release() self.assertFalse(lock.locked()) - def test_context_manager(self): - async def f(): - lock = asyncio.Lock() - self.assertFalse(lock.locked()) + async def test_context_manager(self): + lock = asyncio.Lock() + self.assertFalse(lock.locked()) - async with lock: - self.assertTrue(lock.locked()) + async with lock: + self.assertTrue(lock.locked()) - self.assertFalse(lock.locked()) - - self.loop.run_until_complete(f()) + self.assertFalse(lock.locked()) -class EventTests(test_utils.TestCase): - - def setUp(self): - super().setUp() - self.loop = self.new_test_loop() +class EventTests(unittest.IsolatedAsyncioTestCase): def test_repr(self): ev = asyncio.Event() @@ -316,7 +298,7 @@ class EventTests(test_utils.TestCase): self.assertTrue('waiters:1' in repr(ev)) self.assertTrue(RGX_REPR.match(repr(ev))) - def test_wait(self): + async def test_wait(self): ev = asyncio.Event() self.assertFalse(ev.is_set()) @@ -334,16 +316,16 @@ class EventTests(test_utils.TestCase): if await ev.wait(): result.append(3) - t1 = self.loop.create_task(c1(result)) - t2 = self.loop.create_task(c2(result)) + t1 = asyncio.create_task(c1(result)) + t2 = asyncio.create_task(c2(result)) - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([], result) - t3 = self.loop.create_task(c3(result)) + t3 = asyncio.create_task(c3(result)) ev.set() - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([3, 1, 2], result) self.assertTrue(t1.done()) @@ -353,24 +335,23 @@ class EventTests(test_utils.TestCase): self.assertTrue(t3.done()) self.assertIsNone(t3.result()) - def test_wait_on_set(self): + async def test_wait_on_set(self): ev = asyncio.Event() ev.set() - res = self.loop.run_until_complete(ev.wait()) + res = await ev.wait() self.assertTrue(res) - def test_wait_cancel(self): + async def test_wait_cancel(self): ev = asyncio.Event() - wait = self.loop.create_task(ev.wait()) - self.loop.call_soon(wait.cancel) - self.assertRaises( - asyncio.CancelledError, - self.loop.run_until_complete, wait) + wait = asyncio.create_task(ev.wait()) + asyncio.get_running_loop().call_soon(wait.cancel) + with self.assertRaises(asyncio.CancelledError): + await wait self.assertFalse(ev._waiters) - def test_clear(self): + async def test_clear(self): ev = asyncio.Event() self.assertFalse(ev.is_set()) @@ -380,7 +361,7 @@ class EventTests(test_utils.TestCase): ev.clear() self.assertFalse(ev.is_set()) - def test_clear_with_waiters(self): + async def test_clear_with_waiters(self): ev = asyncio.Event() result = [] @@ -389,8 +370,8 @@ class EventTests(test_utils.TestCase): result.append(1) return True - t = self.loop.create_task(c1(result)) - test_utils.run_briefly(self.loop) + t = asyncio.create_task(c1(result)) + await asyncio.sleep(0) self.assertEqual([], result) ev.set() @@ -401,7 +382,7 @@ class EventTests(test_utils.TestCase): ev.set() self.assertEqual(1, len(ev._waiters)) - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([1], result) self.assertEqual(0, len(ev._waiters)) @@ -409,13 +390,9 @@ class EventTests(test_utils.TestCase): self.assertTrue(t.result()) -class ConditionTests(test_utils.TestCase): +class ConditionTests(unittest.IsolatedAsyncioTestCase): - def setUp(self): - super().setUp() - self.loop = self.new_test_loop() - - def test_wait(self): + async def test_wait(self): cond = asyncio.Condition() result = [] @@ -437,37 +414,37 @@ class ConditionTests(test_utils.TestCase): result.append(3) return True - t1 = self.loop.create_task(c1(result)) - t2 = self.loop.create_task(c2(result)) - t3 = self.loop.create_task(c3(result)) + t1 = asyncio.create_task(c1(result)) + t2 = asyncio.create_task(c2(result)) + t3 = asyncio.create_task(c3(result)) - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([], result) self.assertFalse(cond.locked()) - self.assertTrue(self.loop.run_until_complete(cond.acquire())) + self.assertTrue(await cond.acquire()) cond.notify() - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([], result) self.assertTrue(cond.locked()) cond.release() - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([1], result) self.assertTrue(cond.locked()) cond.notify(2) - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([1], result) self.assertTrue(cond.locked()) cond.release() - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([1, 2], result) self.assertTrue(cond.locked()) cond.release() - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([1, 2, 3], result) self.assertTrue(cond.locked()) @@ -478,49 +455,47 @@ class ConditionTests(test_utils.TestCase): self.assertTrue(t3.done()) self.assertTrue(t3.result()) - def test_wait_cancel(self): + async def test_wait_cancel(self): cond = asyncio.Condition() - self.loop.run_until_complete(cond.acquire()) + await cond.acquire() - wait = self.loop.create_task(cond.wait()) - self.loop.call_soon(wait.cancel) - self.assertRaises( - asyncio.CancelledError, - self.loop.run_until_complete, wait) + wait = asyncio.create_task(cond.wait()) + asyncio.get_running_loop().call_soon(wait.cancel) + with self.assertRaises(asyncio.CancelledError): + await wait self.assertFalse(cond._waiters) self.assertTrue(cond.locked()) - def test_wait_cancel_contested(self): + async def test_wait_cancel_contested(self): cond = asyncio.Condition() - self.loop.run_until_complete(cond.acquire()) + await cond.acquire() self.assertTrue(cond.locked()) - wait_task = self.loop.create_task(cond.wait()) - test_utils.run_briefly(self.loop) + wait_task = asyncio.create_task(cond.wait()) + await asyncio.sleep(0) self.assertFalse(cond.locked()) # Notify, but contest the lock before cancelling - self.loop.run_until_complete(cond.acquire()) + await cond.acquire() self.assertTrue(cond.locked()) cond.notify() - self.loop.call_soon(wait_task.cancel) - self.loop.call_soon(cond.release) + asyncio.get_running_loop().call_soon(wait_task.cancel) + asyncio.get_running_loop().call_soon(cond.release) try: - self.loop.run_until_complete(wait_task) + await wait_task except asyncio.CancelledError: # Should not happen, since no cancellation points pass self.assertTrue(cond.locked()) - def test_wait_cancel_after_notify(self): + async def test_wait_cancel_after_notify(self): # See bpo-32841 waited = False cond = asyncio.Condition() - cond._loop = self.loop async def wait_on_cond(): nonlocal waited @@ -528,27 +503,26 @@ class ConditionTests(test_utils.TestCase): waited = True # Make sure this area was reached await cond.wait() - waiter = asyncio.ensure_future(wait_on_cond(), loop=self.loop) - test_utils.run_briefly(self.loop) # Start waiting + waiter = asyncio.create_task(wait_on_cond()) + await asyncio.sleep(0) # Start waiting - self.loop.run_until_complete(cond.acquire()) + await cond.acquire() cond.notify() - test_utils.run_briefly(self.loop) # Get to acquire() + await asyncio.sleep(0) # Get to acquire() waiter.cancel() - test_utils.run_briefly(self.loop) # Activate cancellation + await asyncio.sleep(0) # Activate cancellation cond.release() - test_utils.run_briefly(self.loop) # Cancellation should occur + await asyncio.sleep(0) # Cancellation should occur self.assertTrue(waiter.cancelled()) self.assertTrue(waited) - def test_wait_unacquired(self): + async def test_wait_unacquired(self): cond = asyncio.Condition() - self.assertRaises( - RuntimeError, - self.loop.run_until_complete, cond.wait()) + with self.assertRaises(RuntimeError): + await cond.wait() - def test_wait_for(self): + async def test_wait_for(self): cond = asyncio.Condition() presult = False @@ -564,40 +538,38 @@ class ConditionTests(test_utils.TestCase): cond.release() return True - t = self.loop.create_task(c1(result)) + t = asyncio.create_task(c1(result)) - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([], result) - self.loop.run_until_complete(cond.acquire()) + await cond.acquire() cond.notify() cond.release() - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([], result) presult = True - self.loop.run_until_complete(cond.acquire()) + await cond.acquire() cond.notify() cond.release() - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([1], result) self.assertTrue(t.done()) self.assertTrue(t.result()) - def test_wait_for_unacquired(self): + async def test_wait_for_unacquired(self): cond = asyncio.Condition() # predicate can return true immediately - res = self.loop.run_until_complete(cond.wait_for(lambda: [1, 2, 3])) + res = await cond.wait_for(lambda: [1, 2, 3]) self.assertEqual([1, 2, 3], res) - self.assertRaises( - RuntimeError, - self.loop.run_until_complete, - cond.wait_for(lambda: False)) + with self.assertRaises(RuntimeError): + await cond.wait_for(lambda: False) - def test_notify(self): + async def test_notify(self): cond = asyncio.Condition() result = [] @@ -622,24 +594,24 @@ class ConditionTests(test_utils.TestCase): cond.release() return True - t1 = self.loop.create_task(c1(result)) - t2 = self.loop.create_task(c2(result)) - t3 = self.loop.create_task(c3(result)) + t1 = asyncio.create_task(c1(result)) + t2 = asyncio.create_task(c2(result)) + t3 = asyncio.create_task(c3(result)) - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([], result) - self.loop.run_until_complete(cond.acquire()) + await cond.acquire() cond.notify(1) cond.release() - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([1], result) - self.loop.run_until_complete(cond.acquire()) + await cond.acquire() cond.notify(1) cond.notify(2048) cond.release() - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([1, 2, 3], result) self.assertTrue(t1.done()) @@ -649,7 +621,7 @@ class ConditionTests(test_utils.TestCase): self.assertTrue(t3.done()) self.assertTrue(t3.result()) - def test_notify_all(self): + async def test_notify_all(self): cond = asyncio.Condition() result = [] @@ -668,16 +640,16 @@ class ConditionTests(test_utils.TestCase): cond.release() return True - t1 = self.loop.create_task(c1(result)) - t2 = self.loop.create_task(c2(result)) + t1 = asyncio.create_task(c1(result)) + t2 = asyncio.create_task(c2(result)) - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([], result) - self.loop.run_until_complete(cond.acquire()) + await cond.acquire() cond.notify_all() cond.release() - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([1, 2], result) self.assertTrue(t1.done()) @@ -693,12 +665,12 @@ class ConditionTests(test_utils.TestCase): cond = asyncio.Condition() self.assertRaises(RuntimeError, cond.notify_all) - def test_repr(self): + async def test_repr(self): cond = asyncio.Condition() self.assertTrue('unlocked' in repr(cond)) self.assertTrue(RGX_REPR.match(repr(cond))) - self.loop.run_until_complete(cond.acquire()) + await cond.acquire() self.assertTrue('locked' in repr(cond)) cond._waiters.append(mock.Mock()) @@ -709,17 +681,14 @@ class ConditionTests(test_utils.TestCase): self.assertTrue('waiters:2' in repr(cond)) self.assertTrue(RGX_REPR.match(repr(cond))) - def test_context_manager(self): - async def f(): - cond = asyncio.Condition() - self.assertFalse(cond.locked()) - async with cond: - self.assertTrue(cond.locked()) - self.assertFalse(cond.locked()) + async def test_context_manager(self): + cond = asyncio.Condition() + self.assertFalse(cond.locked()) + async with cond: + self.assertTrue(cond.locked()) + self.assertFalse(cond.locked()) - self.loop.run_until_complete(f()) - - def test_explicit_lock(self): + async def test_explicit_lock(self): async def f(lock=None, cond=None): if lock is None: lock = asyncio.Lock() @@ -740,12 +709,12 @@ class ConditionTests(test_utils.TestCase): self.assertFalse(cond.locked()) # All should work in the same way. - self.loop.run_until_complete(f()) - self.loop.run_until_complete(f(asyncio.Lock())) + await f() + await f(asyncio.Lock()) lock = asyncio.Lock() - self.loop.run_until_complete(f(lock, asyncio.Condition(lock))) + await f(lock, asyncio.Condition(lock)) - def test_ambiguous_loops(self): + async def test_ambiguous_loops(self): loop = asyncio.new_event_loop() self.addCleanup(loop.close) @@ -780,42 +749,35 @@ class ConditionTests(test_utils.TestCase): ): await cond.wait() - self.loop.run_until_complete(wrong_loop_in_lock()) - self.loop.run_until_complete(wrong_loop_in_cond()) + await wrong_loop_in_lock() + await wrong_loop_in_cond() - def test_timeout_in_block(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - async def task_timeout(): - condition = asyncio.Condition() - async with condition: - with self.assertRaises(asyncio.TimeoutError): - await asyncio.wait_for(condition.wait(), timeout=0.5) - - loop.run_until_complete(task_timeout()) + async def test_timeout_in_block(self): + condition = asyncio.Condition() + async with condition: + with self.assertRaises(asyncio.TimeoutError): + await asyncio.wait_for(condition.wait(), timeout=0.5) -class SemaphoreTests(test_utils.TestCase): - - def setUp(self): - super().setUp() - self.loop = self.new_test_loop() +class SemaphoreTests(unittest.IsolatedAsyncioTestCase): def test_initial_value_zero(self): sem = asyncio.Semaphore(0) self.assertTrue(sem.locked()) - def test_repr(self): + async def test_repr(self): sem = asyncio.Semaphore() self.assertTrue(repr(sem).endswith('[unlocked, value:1]>')) self.assertTrue(RGX_REPR.match(repr(sem))) - self.loop.run_until_complete(sem.acquire()) + await sem.acquire() self.assertTrue(repr(sem).endswith('[locked]>')) self.assertTrue('waiters' not in repr(sem)) self.assertTrue(RGX_REPR.match(repr(sem))) + if sem._waiters is None: + sem._waiters = collections.deque() + sem._waiters.append(mock.Mock()) self.assertTrue('waiters:1' in repr(sem)) self.assertTrue(RGX_REPR.match(repr(sem))) @@ -824,18 +786,15 @@ class SemaphoreTests(test_utils.TestCase): self.assertTrue('waiters:2' in repr(sem)) self.assertTrue(RGX_REPR.match(repr(sem))) - def test_semaphore(self): + async def test_semaphore(self): sem = asyncio.Semaphore() self.assertEqual(1, sem._value) - async def acquire_lock(): - return await sem - with self.assertRaisesRegex( TypeError, "object Semaphore can't be used in 'await' expression", ): - self.loop.run_until_complete(acquire_lock()) + await sem self.assertFalse(sem.locked()) self.assertEqual(1, sem._value) @@ -843,12 +802,12 @@ class SemaphoreTests(test_utils.TestCase): def test_semaphore_value(self): self.assertRaises(ValueError, asyncio.Semaphore, -1) - def test_acquire(self): + async def test_acquire(self): sem = asyncio.Semaphore(3) result = [] - self.assertTrue(self.loop.run_until_complete(sem.acquire())) - self.assertTrue(self.loop.run_until_complete(sem.acquire())) + self.assertTrue(await sem.acquire()) + self.assertTrue(await sem.acquire()) self.assertFalse(sem.locked()) async def c1(result): @@ -871,23 +830,23 @@ class SemaphoreTests(test_utils.TestCase): result.append(4) return True - t1 = self.loop.create_task(c1(result)) - t2 = self.loop.create_task(c2(result)) - t3 = self.loop.create_task(c3(result)) + t1 = asyncio.create_task(c1(result)) + t2 = asyncio.create_task(c2(result)) + t3 = asyncio.create_task(c3(result)) - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual([1], result) self.assertTrue(sem.locked()) self.assertEqual(2, len(sem._waiters)) self.assertEqual(0, sem._value) - t4 = self.loop.create_task(c4(result)) + t4 = asyncio.create_task(c4(result)) sem.release() sem.release() - self.assertEqual(2, sem._value) + self.assertEqual(0, sem._value) - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) self.assertEqual(0, sem._value) self.assertEqual(3, len(result)) self.assertTrue(sem.locked()) @@ -898,73 +857,764 @@ class SemaphoreTests(test_utils.TestCase): self.assertTrue(t1.result()) race_tasks = [t2, t3, t4] done_tasks = [t for t in race_tasks if t.done() and t.result()] - self.assertTrue(2, len(done_tasks)) + self.assertEqual(2, len(done_tasks)) # cleanup locked semaphore sem.release() - self.loop.run_until_complete(asyncio.gather(*race_tasks)) + await asyncio.gather(*race_tasks) - def test_acquire_cancel(self): + async def test_acquire_cancel(self): sem = asyncio.Semaphore() - self.loop.run_until_complete(sem.acquire()) + await sem.acquire() - acquire = self.loop.create_task(sem.acquire()) - self.loop.call_soon(acquire.cancel) - self.assertRaises( - asyncio.CancelledError, - self.loop.run_until_complete, acquire) + acquire = asyncio.create_task(sem.acquire()) + asyncio.get_running_loop().call_soon(acquire.cancel) + with self.assertRaises(asyncio.CancelledError): + await acquire self.assertTrue((not sem._waiters) or all(waiter.done() for waiter in sem._waiters)) - def test_acquire_cancel_before_awoken(self): + async def test_acquire_cancel_before_awoken(self): sem = asyncio.Semaphore(value=0) - t1 = self.loop.create_task(sem.acquire()) - t2 = self.loop.create_task(sem.acquire()) - t3 = self.loop.create_task(sem.acquire()) - t4 = self.loop.create_task(sem.acquire()) + t1 = asyncio.create_task(sem.acquire()) + t2 = asyncio.create_task(sem.acquire()) + t3 = asyncio.create_task(sem.acquire()) + t4 = asyncio.create_task(sem.acquire()) - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) - sem.release() t1.cancel() t2.cancel() + sem.release() - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) + await asyncio.sleep(0) num_done = sum(t.done() for t in [t3, t4]) self.assertEqual(num_done, 1) + self.assertTrue(t3.done()) + self.assertFalse(t4.done()) t3.cancel() t4.cancel() - test_utils.run_briefly(self.loop) + await asyncio.sleep(0) - def test_acquire_hang(self): + async def test_acquire_hang(self): sem = asyncio.Semaphore(value=0) - t1 = self.loop.create_task(sem.acquire()) - t2 = self.loop.create_task(sem.acquire()) + t1 = asyncio.create_task(sem.acquire()) + t2 = asyncio.create_task(sem.acquire()) + await asyncio.sleep(0) - test_utils.run_briefly(self.loop) - - sem.release() t1.cancel() - - test_utils.run_briefly(self.loop) + sem.release() + await asyncio.sleep(0) + await asyncio.sleep(0) self.assertTrue(sem.locked()) + self.assertTrue(t2.done()) + + async def test_acquire_no_hang(self): + + sem = asyncio.Semaphore(1) + + async def c1(): + async with sem: + await asyncio.sleep(0) + t2.cancel() + + async def c2(): + async with sem: + self.assertFalse(True) + + t1 = asyncio.create_task(c1()) + t2 = asyncio.create_task(c2()) + + r1, r2 = await asyncio.gather(t1, t2, return_exceptions=True) + self.assertTrue(r1 is None) + self.assertTrue(isinstance(r2, asyncio.CancelledError)) + + await asyncio.wait_for(sem.acquire(), timeout=1.0) def test_release_not_acquired(self): sem = asyncio.BoundedSemaphore() self.assertRaises(ValueError, sem.release) - def test_release_no_waiters(self): + async def test_release_no_waiters(self): sem = asyncio.Semaphore() - self.loop.run_until_complete(sem.acquire()) + await sem.acquire() self.assertTrue(sem.locked()) sem.release() self.assertFalse(sem.locked()) + async def test_acquire_fifo_order(self): + sem = asyncio.Semaphore(1) + result = [] + + async def coro(tag): + await sem.acquire() + result.append(f'{tag}_1') + await asyncio.sleep(0.01) + sem.release() + + await sem.acquire() + result.append(f'{tag}_2') + await asyncio.sleep(0.01) + sem.release() + + async with asyncio.TaskGroup() as tg: + tg.create_task(coro('c1')) + tg.create_task(coro('c2')) + tg.create_task(coro('c3')) + + self.assertEqual( + ['c1_1', 'c2_1', 'c3_1', 'c1_2', 'c2_2', 'c3_2'], + result + ) + + async def test_acquire_fifo_order_2(self): + sem = asyncio.Semaphore(1) + result = [] + + async def c1(result): + await sem.acquire() + result.append(1) + return True + + async def c2(result): + await sem.acquire() + result.append(2) + sem.release() + await sem.acquire() + result.append(4) + return True + + async def c3(result): + await sem.acquire() + result.append(3) + return True + + t1 = asyncio.create_task(c1(result)) + t2 = asyncio.create_task(c2(result)) + t3 = asyncio.create_task(c3(result)) + + await asyncio.sleep(0) + + sem.release() + sem.release() + + tasks = [t1, t2, t3] + await asyncio.gather(*tasks) + self.assertEqual([1, 2, 3, 4], result) + + async def test_acquire_fifo_order_3(self): + sem = asyncio.Semaphore(0) + result = [] + + async def c1(result): + await sem.acquire() + result.append(1) + return True + + async def c2(result): + await sem.acquire() + result.append(2) + return True + + async def c3(result): + await sem.acquire() + result.append(3) + return True + + t1 = asyncio.create_task(c1(result)) + t2 = asyncio.create_task(c2(result)) + t3 = asyncio.create_task(c3(result)) + + await asyncio.sleep(0) + + t1.cancel() + + await asyncio.sleep(0) + + sem.release() + sem.release() + + tasks = [t1, t2, t3] + await asyncio.gather(*tasks, return_exceptions=True) + self.assertEqual([2, 3], result) + + +class BarrierTests(unittest.IsolatedAsyncioTestCase): + + async def asyncSetUp(self): + await super().asyncSetUp() + self.N = 5 + + def make_tasks(self, n, coro): + tasks = [asyncio.create_task(coro()) for _ in range(n)] + return tasks + + async def gather_tasks(self, n, coro): + tasks = self.make_tasks(n, coro) + res = await asyncio.gather(*tasks) + return res, tasks + + async def test_barrier(self): + barrier = asyncio.Barrier(self.N) + self.assertIn("filling", repr(barrier)) + with self.assertRaisesRegex( + TypeError, + "object Barrier can't be used in 'await' expression", + ): + await barrier + + self.assertIn("filling", repr(barrier)) + + async def test_repr(self): + barrier = asyncio.Barrier(self.N) + + self.assertTrue(RGX_REPR.match(repr(barrier))) + self.assertIn("filling", repr(barrier)) + + waiters = [] + async def wait(barrier): + await barrier.wait() + + incr = 2 + for i in range(incr): + waiters.append(asyncio.create_task(wait(barrier))) + await asyncio.sleep(0) + + self.assertTrue(RGX_REPR.match(repr(barrier))) + self.assertTrue(f"waiters:{incr}/{self.N}" in repr(barrier)) + self.assertIn("filling", repr(barrier)) + + # create missing waiters + for i in range(barrier.parties - barrier.n_waiting): + waiters.append(asyncio.create_task(wait(barrier))) + await asyncio.sleep(0) + + self.assertTrue(RGX_REPR.match(repr(barrier))) + self.assertIn("draining", repr(barrier)) + + # add a part of waiters + for i in range(incr): + waiters.append(asyncio.create_task(wait(barrier))) + await asyncio.sleep(0) + # and reset + await barrier.reset() + + self.assertTrue(RGX_REPR.match(repr(barrier))) + self.assertIn("resetting", repr(barrier)) + + # add a part of waiters again + for i in range(incr): + waiters.append(asyncio.create_task(wait(barrier))) + await asyncio.sleep(0) + # and abort + await barrier.abort() + + self.assertTrue(RGX_REPR.match(repr(barrier))) + self.assertIn("broken", repr(barrier)) + self.assertTrue(barrier.broken) + + # suppress unhandled exceptions + await asyncio.gather(*waiters, return_exceptions=True) + + async def test_barrier_parties(self): + self.assertRaises(ValueError, lambda: asyncio.Barrier(0)) + self.assertRaises(ValueError, lambda: asyncio.Barrier(-4)) + + self.assertIsInstance(asyncio.Barrier(self.N), asyncio.Barrier) + + async def test_context_manager(self): + self.N = 3 + barrier = asyncio.Barrier(self.N) + results = [] + + async def coro(): + async with barrier as i: + results.append(i) + + await self.gather_tasks(self.N, coro) + + self.assertListEqual(sorted(results), list(range(self.N))) + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_filling_one_task(self): + barrier = asyncio.Barrier(1) + + async def f(): + async with barrier as i: + return True + + ret = await f() + + self.assertTrue(ret) + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_filling_one_task_twice(self): + barrier = asyncio.Barrier(1) + + t1 = asyncio.create_task(barrier.wait()) + await asyncio.sleep(0) + self.assertEqual(barrier.n_waiting, 0) + + t2 = asyncio.create_task(barrier.wait()) + await asyncio.sleep(0) + + self.assertEqual(t1.result(), t2.result()) + self.assertEqual(t1.done(), t2.done()) + + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_filling_task_by_task(self): + self.N = 3 + barrier = asyncio.Barrier(self.N) + + t1 = asyncio.create_task(barrier.wait()) + await asyncio.sleep(0) + self.assertEqual(barrier.n_waiting, 1) + self.assertIn("filling", repr(barrier)) + + t2 = asyncio.create_task(barrier.wait()) + await asyncio.sleep(0) + self.assertEqual(barrier.n_waiting, 2) + self.assertIn("filling", repr(barrier)) + + t3 = asyncio.create_task(barrier.wait()) + await asyncio.sleep(0) + + await asyncio.wait([t1, t2, t3]) + + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_filling_tasks_wait_twice(self): + barrier = asyncio.Barrier(self.N) + results = [] + + async def coro(): + async with barrier: + results.append(True) + + async with barrier: + results.append(False) + + await self.gather_tasks(self.N, coro) + + self.assertEqual(len(results), self.N*2) + self.assertEqual(results.count(True), self.N) + self.assertEqual(results.count(False), self.N) + + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_filling_tasks_check_return_value(self): + barrier = asyncio.Barrier(self.N) + results1 = [] + results2 = [] + + async def coro(): + async with barrier: + results1.append(True) + + async with barrier as i: + results2.append(True) + return i + + res, _ = await self.gather_tasks(self.N, coro) + + self.assertEqual(len(results1), self.N) + self.assertTrue(all(results1)) + self.assertEqual(len(results2), self.N) + self.assertTrue(all(results2)) + self.assertListEqual(sorted(res), list(range(self.N))) + + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_draining_state(self): + barrier = asyncio.Barrier(self.N) + results = [] + + async def coro(): + async with barrier: + # barrier state change to filling for the last task release + results.append("draining" in repr(barrier)) + + await self.gather_tasks(self.N, coro) + + self.assertEqual(len(results), self.N) + self.assertEqual(results[-1], False) + self.assertTrue(all(results[:self.N-1])) + + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_blocking_tasks_while_draining(self): + rewait = 2 + barrier = asyncio.Barrier(self.N) + barrier_nowaiting = asyncio.Barrier(self.N - rewait) + results = [] + rewait_n = rewait + counter = 0 + + async def coro(): + nonlocal rewait_n + + # first time waiting + await barrier.wait() + + # after wainting once for all tasks + if rewait_n > 0: + rewait_n -= 1 + # wait again only for rewait tasks + await barrier.wait() + else: + # wait for end of draining state` + await barrier_nowaiting.wait() + # wait for other waiting tasks + await barrier.wait() + + # a success means that barrier_nowaiting + # was waited for exactly N-rewait=3 times + await self.gather_tasks(self.N, coro) + + async def test_filling_tasks_cancel_one(self): + self.N = 3 + barrier = asyncio.Barrier(self.N) + results = [] + + async def coro(): + await barrier.wait() + results.append(True) + + t1 = asyncio.create_task(coro()) + await asyncio.sleep(0) + self.assertEqual(barrier.n_waiting, 1) + + t2 = asyncio.create_task(coro()) + await asyncio.sleep(0) + self.assertEqual(barrier.n_waiting, 2) + + t1.cancel() + await asyncio.sleep(0) + self.assertEqual(barrier.n_waiting, 1) + with self.assertRaises(asyncio.CancelledError): + await t1 + self.assertTrue(t1.cancelled()) + + t3 = asyncio.create_task(coro()) + await asyncio.sleep(0) + self.assertEqual(barrier.n_waiting, 2) + + t4 = asyncio.create_task(coro()) + await asyncio.gather(t2, t3, t4) + + self.assertEqual(len(results), self.N) + self.assertTrue(all(results)) + + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_reset_barrier(self): + barrier = asyncio.Barrier(1) + + asyncio.create_task(barrier.reset()) + await asyncio.sleep(0) + + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_reset_barrier_while_tasks_waiting(self): + barrier = asyncio.Barrier(self.N) + results = [] + + async def coro(): + try: + await barrier.wait() + except asyncio.BrokenBarrierError: + results.append(True) + + async def coro_reset(): + await barrier.reset() + + # N-1 tasks waiting on barrier with N parties + tasks = self.make_tasks(self.N-1, coro) + await asyncio.sleep(0) + + # reset the barrier + asyncio.create_task(coro_reset()) + await asyncio.gather(*tasks) + + self.assertEqual(len(results), self.N-1) + self.assertTrue(all(results)) + self.assertEqual(barrier.n_waiting, 0) + self.assertNotIn("resetting", repr(barrier)) + self.assertFalse(barrier.broken) + + async def test_reset_barrier_when_tasks_half_draining(self): + barrier = asyncio.Barrier(self.N) + results1 = [] + rest_of_tasks = self.N//2 + + async def coro(): + try: + await barrier.wait() + except asyncio.BrokenBarrierError: + # catch here waiting tasks + results1.append(True) + else: + # here drained task outside the barrier + if rest_of_tasks == barrier._count: + # tasks outside the barrier + await barrier.reset() + + await self.gather_tasks(self.N, coro) + + self.assertEqual(results1, [True]*rest_of_tasks) + self.assertEqual(barrier.n_waiting, 0) + self.assertNotIn("resetting", repr(barrier)) + self.assertFalse(barrier.broken) + + async def test_reset_barrier_when_tasks_half_draining_half_blocking(self): + barrier = asyncio.Barrier(self.N) + results1 = [] + results2 = [] + blocking_tasks = self.N//2 + count = 0 + + async def coro(): + nonlocal count + try: + await barrier.wait() + except asyncio.BrokenBarrierError: + # here catch still waiting tasks + results1.append(True) + + # so now waiting again to reach nb_parties + await barrier.wait() + else: + count += 1 + if count > blocking_tasks: + # reset now: raise asyncio.BrokenBarrierError for waiting tasks + await barrier.reset() + + # so now waiting again to reach nb_parties + await barrier.wait() + else: + try: + await barrier.wait() + except asyncio.BrokenBarrierError: + # here no catch - blocked tasks go to wait + results2.append(True) + + await self.gather_tasks(self.N, coro) + + self.assertEqual(results1, [True]*blocking_tasks) + self.assertEqual(results2, []) + self.assertEqual(barrier.n_waiting, 0) + self.assertNotIn("resetting", repr(barrier)) + self.assertFalse(barrier.broken) + + async def test_reset_barrier_while_tasks_waiting_and_waiting_again(self): + barrier = asyncio.Barrier(self.N) + results1 = [] + results2 = [] + + async def coro1(): + try: + await barrier.wait() + except asyncio.BrokenBarrierError: + results1.append(True) + finally: + await barrier.wait() + results2.append(True) + + async def coro2(): + async with barrier: + results2.append(True) + + tasks = self.make_tasks(self.N-1, coro1) + + # reset barrier, N-1 waiting tasks raise an BrokenBarrierError + asyncio.create_task(barrier.reset()) + await asyncio.sleep(0) + + # complete waiting tasks in the `finally` + asyncio.create_task(coro2()) + + await asyncio.gather(*tasks) + + self.assertFalse(barrier.broken) + self.assertEqual(len(results1), self.N-1) + self.assertTrue(all(results1)) + self.assertEqual(len(results2), self.N) + self.assertTrue(all(results2)) + + self.assertEqual(barrier.n_waiting, 0) + + + async def test_reset_barrier_while_tasks_draining(self): + barrier = asyncio.Barrier(self.N) + results1 = [] + results2 = [] + results3 = [] + count = 0 + + async def coro(): + nonlocal count + + i = await barrier.wait() + count += 1 + if count == self.N: + # last task exited from barrier + await barrier.reset() + + # wait here to reach the `parties` + await barrier.wait() + else: + try: + # second waiting + await barrier.wait() + + # N-1 tasks here + results1.append(True) + except Exception as e: + # never goes here + results2.append(True) + + # Now, pass the barrier again + # last wait, must be completed + k = await barrier.wait() + results3.append(True) + + await self.gather_tasks(self.N, coro) + + self.assertFalse(barrier.broken) + self.assertTrue(all(results1)) + self.assertEqual(len(results1), self.N-1) + self.assertEqual(len(results2), 0) + self.assertEqual(len(results3), self.N) + self.assertTrue(all(results3)) + + self.assertEqual(barrier.n_waiting, 0) + + async def test_abort_barrier(self): + barrier = asyncio.Barrier(1) + + asyncio.create_task(barrier.abort()) + await asyncio.sleep(0) + + self.assertEqual(barrier.n_waiting, 0) + self.assertTrue(barrier.broken) + + async def test_abort_barrier_when_tasks_half_draining_half_blocking(self): + barrier = asyncio.Barrier(self.N) + results1 = [] + results2 = [] + blocking_tasks = self.N//2 + count = 0 + + async def coro(): + nonlocal count + try: + await barrier.wait() + except asyncio.BrokenBarrierError: + # here catch tasks waiting to drain + results1.append(True) + else: + count += 1 + if count > blocking_tasks: + # abort now: raise asyncio.BrokenBarrierError for all tasks + await barrier.abort() + else: + try: + await barrier.wait() + except asyncio.BrokenBarrierError: + # here catch blocked tasks (already drained) + results2.append(True) + + await self.gather_tasks(self.N, coro) + + self.assertTrue(barrier.broken) + self.assertEqual(results1, [True]*blocking_tasks) + self.assertEqual(results2, [True]*(self.N-blocking_tasks-1)) + self.assertEqual(barrier.n_waiting, 0) + self.assertNotIn("resetting", repr(barrier)) + + async def test_abort_barrier_when_exception(self): + # test from threading.Barrier: see `lock_tests.test_reset` + barrier = asyncio.Barrier(self.N) + results1 = [] + results2 = [] + + async def coro(): + try: + async with barrier as i : + if i == self.N//2: + raise RuntimeError + async with barrier: + results1.append(True) + except asyncio.BrokenBarrierError: + results2.append(True) + except RuntimeError: + await barrier.abort() + + await self.gather_tasks(self.N, coro) + + self.assertTrue(barrier.broken) + self.assertEqual(len(results1), 0) + self.assertEqual(len(results2), self.N-1) + self.assertTrue(all(results2)) + self.assertEqual(barrier.n_waiting, 0) + + async def test_abort_barrier_when_exception_then_resetting(self): + # test from threading.Barrier: see `lock_tests.test_abort_and_reset`` + barrier1 = asyncio.Barrier(self.N) + barrier2 = asyncio.Barrier(self.N) + results1 = [] + results2 = [] + results3 = [] + + async def coro(): + try: + i = await barrier1.wait() + if i == self.N//2: + raise RuntimeError + await barrier1.wait() + results1.append(True) + except asyncio.BrokenBarrierError: + results2.append(True) + except RuntimeError: + await barrier1.abort() + + # Synchronize and reset the barrier. Must synchronize first so + # that everyone has left it when we reset, and after so that no + # one enters it before the reset. + i = await barrier2.wait() + if i == self.N//2: + await barrier1.reset() + await barrier2.wait() + await barrier1.wait() + results3.append(True) + + await self.gather_tasks(self.N, coro) + + self.assertFalse(barrier1.broken) + self.assertEqual(len(results1), 0) + self.assertEqual(len(results2), self.N-1) + self.assertTrue(all(results2)) + self.assertEqual(len(results3), self.N) + self.assertTrue(all(results3)) + + self.assertEqual(barrier1.n_waiting, 0) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py index 4c8906d531c..6cb7dc300c5 100644 --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -75,8 +75,12 @@ class ProactorSocketTransportTests(test_utils.TestCase): called_buf = bytearray(self.buffer_size) called_buf[:len(buf)] = buf self.loop._proactor.recv_into.assert_called_with(self.sock, called_buf) - self.protocol.data_received.assert_called_with(bytearray(buf)) + self.protocol.data_received.assert_called_with(buf) + # assert_called_with maps bytearray and bytes to the same thing so check manually + # regression test for https://github.com/python/cpython/issues/99941 + self.assertIsInstance(self.protocol.data_received.call_args.args[0], bytes) + @unittest.skipIf(sys.flags.optimize, "Assertions are disabled in optimized mode") def test_loop_reading_no_data(self): res = self.loop.create_future() res.set_result(0) @@ -241,6 +245,14 @@ class ProactorSocketTransportTests(test_utils.TestCase): test_utils.run_briefly(self.loop) self.assertFalse(self.protocol.connection_lost.called) + def test_close_invalid_sockobj(self): + tr = self.socket_transport() + self.sock.fileno.return_value = -1 + tr.close() + test_utils.run_briefly(self.loop) + self.protocol.connection_lost.assert_called_with(None) + self.assertFalse(self.sock.shutdown.called) + @mock.patch('asyncio.base_events.logger') def test_fatal_error(self, m_logging): tr = self.socket_transport() @@ -281,7 +293,33 @@ class ProactorSocketTransportTests(test_utils.TestCase): tr._closing = True tr._force_close(None) test_utils.run_briefly(self.loop) + # See https://github.com/python/cpython/issues/89237 + # `protocol.connection_lost` should be called even if + # the transport was closed forcefully otherwise + # the resources held by protocol will never be freed + # and waiters will never be notified leading to hang. + self.assertTrue(self.protocol.connection_lost.called) + + def test_force_close_protocol_connection_lost_once(self): + tr = self.socket_transport() self.assertFalse(self.protocol.connection_lost.called) + tr._closing = True + # Calling _force_close twice should not call + # protocol.connection_lost twice + tr._force_close(None) + tr._force_close(None) + test_utils.run_briefly(self.loop) + self.assertEqual(1, self.protocol.connection_lost.call_count) + + def test_close_protocol_connection_lost_once(self): + tr = self.socket_transport() + self.assertFalse(self.protocol.connection_lost.called) + # Calling close twice should not call + # protocol.connection_lost twice + tr.close() + tr.close() + test_utils.run_briefly(self.loop) + self.assertEqual(1, self.protocol.connection_lost.call_count) def test_fatal_error_2(self): tr = self.socket_transport() @@ -838,6 +876,7 @@ class BaseProactorEventLoopTests(test_utils.TestCase): def test_make_datagram_transport(self): tr = self.datagram_transport() self.assertIsInstance(tr, _ProactorDatagramTransport) + self.assertIsInstance(tr, asyncio.DatagramTransport) close_transport(tr) def test_datagram_loop_writing(self): @@ -869,6 +908,7 @@ class BaseProactorEventLoopTests(test_utils.TestCase): self.protocol.datagram_received.assert_called_with(b'data', ('127.0.0.1', 12068)) close_transport(tr) + @unittest.skipIf(sys.flags.optimize, "Assertions are disabled in optimized mode") def test_datagram_loop_reading_no_data(self): res = self.loop.create_future() res.set_result((b'', ('127.0.0.1', 12068))) diff --git a/Lib/test/test_asyncio/test_protocols.py b/Lib/test/test_asyncio/test_protocols.py index 438111cccd3..0f232631867 100644 --- a/Lib/test/test_asyncio/test_protocols.py +++ b/Lib/test/test_asyncio/test_protocols.py @@ -4,6 +4,12 @@ from unittest import mock import asyncio +def tearDownModule(): + # not needed for the test file but added for uniformness with all other + # asyncio test files for the sake of unified cleanup + asyncio.set_event_loop_policy(None) + + class ProtocolsAbsTests(unittest.TestCase): def test_base_protocol(self): @@ -55,3 +61,7 @@ class ProtocolsAbsTests(unittest.TestCase): self.assertIsNone(sp.pipe_connection_lost(1, f)) self.assertIsNone(sp.process_exited()) self.assertFalse(hasattr(sp, '__dict__')) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_asyncio/test_queues.py b/Lib/test/test_asyncio/test_queues.py index 63a9a5f270c..2d058ccf6a8 100644 --- a/Lib/test/test_asyncio/test_queues.py +++ b/Lib/test/test_asyncio/test_queues.py @@ -1,114 +1,94 @@ """Tests for queues.py""" -import unittest -from unittest import mock - import asyncio -from test.test_asyncio import utils as test_utils +import unittest +from types import GenericAlias def tearDownModule(): asyncio.set_event_loop_policy(None) -class _QueueTestBase(test_utils.TestCase): +class QueueBasicTests(unittest.IsolatedAsyncioTestCase): - def setUp(self): - super().setUp() - self.loop = self.new_test_loop() - - -class QueueBasicTests(_QueueTestBase): - - def _test_repr_or_str(self, fn, expect_id): + async def _test_repr_or_str(self, fn, expect_id): """Test Queue's repr or str. fn is repr or str. expect_id is True if we expect the Queue's id to appear in fn(Queue()). """ - def gen(): - when = yield - self.assertAlmostEqual(0.1, when) - when = yield 0.1 - self.assertAlmostEqual(0.2, when) - yield 0.1 - - loop = self.new_test_loop(gen) - q = asyncio.Queue() self.assertTrue(fn(q).startswith(''.format(type(self).__name__, self.__sock) + + +class SocketThread(threading.Thread): + + def stop(self): + self._active = False + self.join() + + def __enter__(self): + self.start() + return self + + def __exit__(self, *exc): + self.stop() + + +class TestThreadedClient(SocketThread): + + def __init__(self, test, sock, prog, timeout): + threading.Thread.__init__(self, None, None, 'test-client') + self.daemon = True + + self._timeout = timeout + self._sock = sock + self._active = True + self._prog = prog + self._test = test + + def run(self): + try: + self._prog(TestSocketWrapper(self._sock)) + except (KeyboardInterrupt, SystemExit): + raise + except BaseException as ex: + self._test._abort_socket_test(ex) + + +class TestThreadedServer(SocketThread): + + def __init__(self, test, sock, prog, timeout, max_clients): + threading.Thread.__init__(self, None, None, 'test-server') + self.daemon = True + + self._clients = 0 + self._finished_clients = 0 + self._max_clients = max_clients + self._timeout = timeout + self._sock = sock + self._active = True + + self._prog = prog + + self._s1, self._s2 = socket.socketpair() + self._s1.setblocking(False) + + self._test = test + + def stop(self): + try: + if self._s2 and self._s2.fileno() != -1: + try: + self._s2.send(b'stop') + except OSError: + pass + finally: + super().stop() + + def run(self): + try: + with self._sock: + self._sock.setblocking(False) + self._run() + finally: + self._s1.close() + self._s2.close() + + def _run(self): + while self._active: + if self._clients >= self._max_clients: + return + + r, w, x = select.select( + [self._sock, self._s1], [], [], self._timeout) + + if self._s1 in r: + return + + if self._sock in r: + try: + conn, addr = self._sock.accept() + except BlockingIOError: + continue + except socket.timeout: + if not self._active: + return + else: + raise + else: + self._clients += 1 + conn.settimeout(self._timeout) + try: + with conn: + self._handle_client(conn) + except (KeyboardInterrupt, SystemExit): + raise + except BaseException as ex: + self._active = False + try: + raise + finally: + self._test._abort_socket_test(ex) + + def _handle_client(self, sock): + self._prog(TestSocketWrapper(sock)) + + @property + def addr(self): + return self._sock.getsockname() diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index a47e43dd4ca..52a45f1c7c6 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -2,9 +2,9 @@ import logging import socket -from test import support import unittest import weakref +from test import support from unittest import mock try: import ssl @@ -15,7 +15,6 @@ import asyncio from asyncio import log from asyncio import protocols from asyncio import sslproto -from test import support from test.test_asyncio import utils as test_utils from test.test_asyncio import functional as func_tests @@ -44,16 +43,13 @@ class SslProtoHandshakeTests(test_utils.TestCase): def connection_made(self, ssl_proto, *, do_handshake=None): transport = mock.Mock() - sslpipe = mock.Mock() - sslpipe.shutdown.return_value = b'' - if do_handshake: - sslpipe.do_handshake.side_effect = do_handshake - else: - def mock_handshake(callback): - return [] - sslpipe.do_handshake.side_effect = mock_handshake - with mock.patch('asyncio.sslproto._SSLPipe', return_value=sslpipe): - ssl_proto.connection_made(transport) + sslobj = mock.Mock() + # emulate reading decompressed data + sslobj.read.side_effect = ssl.SSLWantReadError + if do_handshake is not None: + sslobj.do_handshake = do_handshake + ssl_proto._sslobj = sslobj + ssl_proto.connection_made(transport) return transport def test_handshake_timeout_zero(self): @@ -75,7 +71,10 @@ class SslProtoHandshakeTests(test_utils.TestCase): def test_eof_received_waiter(self): waiter = self.loop.create_future() ssl_proto = self.ssl_protocol(waiter=waiter) - self.connection_made(ssl_proto) + self.connection_made( + ssl_proto, + do_handshake=mock.Mock(side_effect=ssl.SSLWantReadError) + ) ssl_proto.eof_received() test_utils.run_briefly(self.loop) self.assertIsInstance(waiter.exception(), ConnectionResetError) @@ -100,7 +99,10 @@ class SslProtoHandshakeTests(test_utils.TestCase): # yield from waiter hang if lost_connection was called. waiter = self.loop.create_future() ssl_proto = self.ssl_protocol(waiter=waiter) - self.connection_made(ssl_proto) + self.connection_made( + ssl_proto, + do_handshake=mock.Mock(side_effect=ssl.SSLWantReadError) + ) ssl_proto.connection_lost(ConnectionAbortedError) test_utils.run_briefly(self.loop) self.assertIsInstance(waiter.exception(), ConnectionAbortedError) @@ -110,7 +112,10 @@ class SslProtoHandshakeTests(test_utils.TestCase): waiter = self.loop.create_future() ssl_proto = self.ssl_protocol(waiter=waiter) - transport = self.connection_made(ssl_proto) + transport = self.connection_made( + ssl_proto, + do_handshake=mock.Mock(side_effect=ssl.SSLWantReadError) + ) test_utils.run_briefly(self.loop) ssl_proto._app_transport.close() @@ -143,7 +148,7 @@ class SslProtoHandshakeTests(test_utils.TestCase): transp.close() # should not raise - self.assertIsNone(ssl_proto.data_received(b'data')) + self.assertIsNone(ssl_proto.buffer_updated(5)) def test_write_after_closing(self): ssl_proto = self.ssl_protocol() @@ -383,9 +388,9 @@ class BaseStartTLS(func_tests.FunctionalTestCaseMixin): def get_buffer(self, sizehint): return self.buf - def buffer_updated(self, nsize): - assert nsize == 1 - self.on_data.set_result(bytes(self.buf[:nsize])) + def buffer_updated(slf, nsize): + self.assertEqual(nsize, 1) + slf.on_data.set_result(bytes(slf.buf[:nsize])) class ClientProtoSecond(asyncio.Protocol): def __init__(self, on_data, on_eof): diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index a6ea24ceced..7f9dc621808 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -9,6 +9,7 @@ import sys import threading import unittest from unittest import mock +import warnings from test.support import socket_helper try: import ssl @@ -706,6 +707,69 @@ class StreamTests(test_utils.TestCase): self.assertEqual(messages, []) + @unittest.skipIf(ssl is None, 'No ssl module') + def test_start_tls(self): + + class MyServer: + + def __init__(self, loop): + self.server = None + self.loop = loop + + async def handle_client(self, client_reader, client_writer): + data1 = await client_reader.readline() + client_writer.write(data1) + await client_writer.drain() + assert client_writer.get_extra_info('sslcontext') is None + await client_writer.start_tls( + test_utils.simple_server_sslcontext()) + assert client_writer.get_extra_info('sslcontext') is not None + data2 = await client_reader.readline() + client_writer.write(data2) + await client_writer.drain() + client_writer.close() + await client_writer.wait_closed() + + def start(self): + sock = socket.create_server(('127.0.0.1', 0)) + self.server = self.loop.run_until_complete( + asyncio.start_server(self.handle_client, + sock=sock)) + return sock.getsockname() + + def stop(self): + if self.server is not None: + self.server.close() + self.loop.run_until_complete(self.server.wait_closed()) + self.server = None + + async def client(addr): + reader, writer = await asyncio.open_connection(*addr) + writer.write(b"hello world 1!\n") + await writer.drain() + msgback1 = await reader.readline() + assert writer.get_extra_info('sslcontext') is None + await writer.start_tls(test_utils.simple_client_sslcontext()) + assert writer.get_extra_info('sslcontext') is not None + writer.write(b"hello world 2!\n") + await writer.drain() + msgback2 = await reader.readline() + writer.close() + await writer.wait_closed() + return msgback1, msgback2 + + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) + + server = MyServer(self.loop) + addr = server.start() + msg1, msg2 = self.loop.run_until_complete(client(addr)) + server.stop() + + self.assertEqual(messages, []) + self.assertEqual(msg1, b"hello world 1!\n") + self.assertEqual(msg2, b"hello world 2!\n") + @unittest.skipIf(sys.platform == 'win32', "Don't have pipes") def test_read_all_from_pipe_reader(self): # See asyncio issue 168. This test is derived from the example @@ -728,11 +792,14 @@ os.close(fd) protocol = asyncio.StreamReaderProtocol(reader, loop=self.loop) transport, _ = self.loop.run_until_complete( self.loop.connect_read_pipe(lambda: protocol, pipe)) - - watcher = asyncio.SafeChildWatcher() + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + watcher = asyncio.SafeChildWatcher() watcher.attach_loop(self.loop) try: - asyncio.set_child_watcher(watcher) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + asyncio.set_child_watcher(watcher) create = asyncio.create_subprocess_exec( *args, pass_fds={wfd}, @@ -740,17 +807,17 @@ os.close(fd) proc = self.loop.run_until_complete(create) self.loop.run_until_complete(proc.wait()) finally: - asyncio.set_child_watcher(None) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + asyncio.set_child_watcher(None) os.close(wfd) data = self.loop.run_until_complete(reader.read(-1)) self.assertEqual(data, b'data') def test_streamreader_constructor_without_loop(self): - with self.assertWarns(DeprecationWarning) as cm: - with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'): - asyncio.StreamReader() - self.assertEqual(cm.warnings[0].filename, __file__) + with self.assertRaisesRegex(RuntimeError, 'no current event loop'): + asyncio.StreamReader() def test_streamreader_constructor_use_running_loop(self): # asyncio issue #184: Ensure that StreamReaderProtocol constructor @@ -764,21 +831,17 @@ os.close(fd) def test_streamreader_constructor_use_global_loop(self): # asyncio issue #184: Ensure that StreamReaderProtocol constructor # retrieves the current loop if the loop parameter is not set - # Deprecated in 3.10 + # Deprecated in 3.10, undeprecated in 3.12 self.addCleanup(asyncio.set_event_loop, None) asyncio.set_event_loop(self.loop) - with self.assertWarns(DeprecationWarning) as cm: - reader = asyncio.StreamReader() - self.assertEqual(cm.warnings[0].filename, __file__) + reader = asyncio.StreamReader() self.assertIs(reader._loop, self.loop) def test_streamreaderprotocol_constructor_without_loop(self): reader = mock.Mock() - with self.assertWarns(DeprecationWarning) as cm: - with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'): - asyncio.StreamReaderProtocol(reader) - self.assertEqual(cm.warnings[0].filename, __file__) + with self.assertRaisesRegex(RuntimeError, 'no current event loop'): + asyncio.StreamReaderProtocol(reader) def test_streamreaderprotocol_constructor_use_running_loop(self): # asyncio issue #184: Ensure that StreamReaderProtocol constructor @@ -792,15 +855,32 @@ os.close(fd) def test_streamreaderprotocol_constructor_use_global_loop(self): # asyncio issue #184: Ensure that StreamReaderProtocol constructor # retrieves the current loop if the loop parameter is not set - # Deprecated in 3.10 + # Deprecated in 3.10, undeprecated in 3.12 self.addCleanup(asyncio.set_event_loop, None) asyncio.set_event_loop(self.loop) reader = mock.Mock() - with self.assertWarns(DeprecationWarning) as cm: - protocol = asyncio.StreamReaderProtocol(reader) - self.assertEqual(cm.warnings[0].filename, __file__) + protocol = asyncio.StreamReaderProtocol(reader) self.assertIs(protocol._loop, self.loop) + def test_multiple_drain(self): + # See https://github.com/python/cpython/issues/74116 + drained = 0 + + async def drainer(stream): + nonlocal drained + await stream._drain_helper() + drained += 1 + + async def main(): + loop = asyncio.get_running_loop() + stream = asyncio.streams.FlowControlMixin(loop) + stream.pause_writing() + loop.call_later(0.1, stream.resume_writing) + await asyncio.gather(*[drainer(stream) for _ in range(10)]) + self.assertEqual(drained, 10) + + self.loop.run_until_complete(main()) + def test_drain_raises(self): # See http://bugs.python.org/issue25441 @@ -987,10 +1067,10 @@ os.close(fd) wr.close() f = wr.wait_closed() self.loop.run_until_complete(f) - assert rd.at_eof() + self.assertTrue(rd.at_eof()) f = rd.read() data = self.loop.run_until_complete(f) - assert data == b'' + self.assertEqual(data, b'') self.assertEqual(messages, []) diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index 14fa6dd76f9..f1ad10a9903 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -1,4 +1,5 @@ import os +import shutil import signal import sys import unittest @@ -15,6 +16,9 @@ from test.support import os_helper if sys.platform != 'win32': from asyncio import unix_events +if support.check_sanitizer(address=True): + raise unittest.SkipTest("Exposes ASAN flakiness in GitHub CI") + # Program blocking PROGRAM_BLOCKED = [sys.executable, '-c', 'import time; time.sleep(3600)'] @@ -47,8 +51,6 @@ class SubprocessTransportTests(test_utils.TestCase): def create_transport(self, waiter=None): protocol = mock.Mock() - protocol.connection_made._is_coroutine = False - protocol.process_exited._is_coroutine = False transport = TestSubprocessTransport( self.loop, protocol, ['test'], False, None, None, None, 0, waiter=waiter) @@ -181,6 +183,33 @@ class SubprocessMixin: else: self.assertEqual(-signal.SIGKILL, returncode) + def test_kill_issue43884(self): + if sys.platform == 'win32': + blocking_shell_command = f'{sys.executable} -c "import time; time.sleep(2)"' + else: + blocking_shell_command = 'sleep 1; sleep 1' + creationflags = 0 + if sys.platform == 'win32': + from subprocess import CREATE_NEW_PROCESS_GROUP + # On windows create a new process group so that killing process + # kills the process and all its children. + creationflags = CREATE_NEW_PROCESS_GROUP + proc = self.loop.run_until_complete( + asyncio.create_subprocess_shell(blocking_shell_command, stdout=asyncio.subprocess.PIPE, + creationflags=creationflags) + ) + self.loop.run_until_complete(asyncio.sleep(1)) + if sys.platform == 'win32': + proc.send_signal(signal.CTRL_BREAK_EVENT) + # On windows it is an alias of terminate which sets the return code + proc.kill() + returncode = self.loop.run_until_complete(proc.wait()) + if sys.platform == 'win32': + self.assertIsInstance(returncode, int) + # expect 1 but sometimes get 0 + else: + self.assertEqual(-signal.SIGKILL, returncode) + def test_terminate(self): args = PROGRAM_BLOCKED proc = self.loop.run_until_complete( @@ -401,6 +430,26 @@ class SubprocessMixin: self.assertEqual(output, None) self.assertEqual(exitcode, 0) + @unittest.skipIf(sys.platform != 'linux', "Don't have /dev/stdin") + def test_devstdin_input(self): + + async def devstdin_input(message): + code = 'file = open("/dev/stdin"); data = file.read(); print(len(data))' + proc = await asyncio.create_subprocess_exec( + sys.executable, '-c', code, + stdin=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + close_fds=False, + ) + stdout, stderr = await proc.communicate(message) + exitcode = await proc.wait() + return (stdout, exitcode) + + output, exitcode = self.loop.run_until_complete(devstdin_input(b'abc')) + self.assertEqual(output.rstrip(), b'3') + self.assertEqual(exitcode, 0) + def test_cancel_process_wait(self): # Issue #23140: cancel Process.wait() @@ -536,7 +585,9 @@ class SubprocessMixin: # manually to avoid a warning when the watcher is detached. if (sys.platform != 'win32' and isinstance(self, SubprocessFastWatcherTests)): - asyncio.get_child_watcher()._callbacks.clear() + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + asyncio.get_child_watcher()._callbacks.clear() async def _test_popen_error(self, stdin): if sys.platform == 'win32': @@ -635,6 +686,107 @@ class SubprocessMixin: self.assertIsNone(self.loop.run_until_complete(execute())) + async def check_stdout_output(self, coro, output): + proc = await coro + stdout, _ = await proc.communicate() + self.assertEqual(stdout, output) + self.assertEqual(proc.returncode, 0) + task = asyncio.create_task(proc.wait()) + await asyncio.sleep(0) + self.assertEqual(task.result(), proc.returncode) + + def test_create_subprocess_env_shell(self) -> None: + async def main() -> None: + cmd = f'''{sys.executable} -c "import os, sys; sys.stdout.write(os.getenv('FOO'))"''' + env = os.environ.copy() + env["FOO"] = "bar" + proc = await asyncio.create_subprocess_shell( + cmd, env=env, stdout=subprocess.PIPE + ) + return proc + + self.loop.run_until_complete(self.check_stdout_output(main(), b'bar')) + + def test_create_subprocess_env_exec(self) -> None: + async def main() -> None: + cmd = [sys.executable, "-c", + "import os, sys; sys.stdout.write(os.getenv('FOO'))"] + env = os.environ.copy() + env["FOO"] = "baz" + proc = await asyncio.create_subprocess_exec( + *cmd, env=env, stdout=subprocess.PIPE + ) + return proc + + self.loop.run_until_complete(self.check_stdout_output(main(), b'baz')) + + + def test_subprocess_concurrent_wait(self) -> None: + async def main() -> None: + proc = await asyncio.create_subprocess_exec( + *PROGRAM_CAT, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + ) + stdout, _ = await proc.communicate(b'some data') + self.assertEqual(stdout, b"some data") + self.assertEqual(proc.returncode, 0) + self.assertEqual(await asyncio.gather(*[proc.wait() for _ in range(10)]), + [proc.returncode] * 10) + + self.loop.run_until_complete(main()) + + def test_subprocess_consistent_callbacks(self): + events = [] + class MyProtocol(asyncio.SubprocessProtocol): + def __init__(self, exit_future: asyncio.Future) -> None: + self.exit_future = exit_future + + def pipe_data_received(self, fd, data) -> None: + events.append(('pipe_data_received', fd, data)) + + def pipe_connection_lost(self, fd, exc) -> None: + events.append('pipe_connection_lost') + + def process_exited(self) -> None: + events.append('process_exited') + self.exit_future.set_result(True) + + async def main() -> None: + loop = asyncio.get_running_loop() + exit_future = asyncio.Future() + code = 'import sys; sys.stdout.write("stdout"); sys.stderr.write("stderr")' + transport, _ = await loop.subprocess_exec(lambda: MyProtocol(exit_future), + sys.executable, '-c', code, stdin=None) + await exit_future + transport.close() + self.assertEqual(events, [ + ('pipe_data_received', 1, b'stdout'), + ('pipe_data_received', 2, b'stderr'), + 'pipe_connection_lost', + 'pipe_connection_lost', + 'process_exited', + ]) + + self.loop.run_until_complete(main()) + + def test_subprocess_communicate_stdout(self): + # See https://github.com/python/cpython/issues/100133 + async def get_command_stdout(cmd, *args): + proc = await asyncio.create_subprocess_exec( + cmd, *args, stdout=asyncio.subprocess.PIPE, + ) + stdout, _ = await proc.communicate() + return stdout.decode().strip() + + async def main(): + outputs = [f'foo{i}' for i in range(10)] + res = await asyncio.gather(*[get_command_stdout(sys.executable, '-c', + f'print({out!r})') for out in outputs]) + self.assertEqual(res, outputs) + + self.loop.run_until_complete(main()) + if sys.platform != 'win32': # Unix @@ -648,57 +800,114 @@ if sys.platform != 'win32': self.loop = policy.new_event_loop() self.set_event_loop(self.loop) - watcher = self.Watcher() + watcher = self._get_watcher() watcher.attach_loop(self.loop) - policy.set_child_watcher(watcher) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + policy.set_child_watcher(watcher) def tearDown(self): super().tearDown() policy = asyncio.get_event_loop_policy() - watcher = policy.get_child_watcher() - policy.set_child_watcher(None) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + watcher = policy.get_child_watcher() + policy.set_child_watcher(None) watcher.attach_loop(None) watcher.close() class SubprocessThreadedWatcherTests(SubprocessWatcherMixin, test_utils.TestCase): - Watcher = unix_events.ThreadedChildWatcher - - @unittest.skip("bpo-38323: MultiLoopChildWatcher has a race condition \ - and these tests can hang the test suite") - class SubprocessMultiLoopWatcherTests(SubprocessWatcherMixin, - test_utils.TestCase): - - Watcher = unix_events.MultiLoopChildWatcher + def _get_watcher(self): + return unix_events.ThreadedChildWatcher() class SubprocessSafeWatcherTests(SubprocessWatcherMixin, test_utils.TestCase): - Watcher = unix_events.SafeChildWatcher + def _get_watcher(self): + with self.assertWarns(DeprecationWarning): + return unix_events.SafeChildWatcher() + + class MultiLoopChildWatcherTests(test_utils.TestCase): + + def test_warns(self): + with self.assertWarns(DeprecationWarning): + unix_events.MultiLoopChildWatcher() class SubprocessFastWatcherTests(SubprocessWatcherMixin, test_utils.TestCase): - Watcher = unix_events.FastChildWatcher - - def has_pidfd_support(): - if not hasattr(os, 'pidfd_open'): - return False - try: - os.close(os.pidfd_open(os.getpid())) - except OSError: - return False - return True + def _get_watcher(self): + with self.assertWarns(DeprecationWarning): + return unix_events.FastChildWatcher() @unittest.skipUnless( - has_pidfd_support(), + unix_events.can_use_pidfd(), "operating system does not support pidfds", ) class SubprocessPidfdWatcherTests(SubprocessWatcherMixin, test_utils.TestCase): - Watcher = unix_events.PidfdChildWatcher + def _get_watcher(self): + return unix_events.PidfdChildWatcher() + + + class GenericWatcherTests(test_utils.TestCase): + + def test_create_subprocess_fails_with_inactive_watcher(self): + watcher = mock.create_autospec(asyncio.AbstractChildWatcher) + watcher.is_active.return_value = False + + async def execute(): + asyncio.set_child_watcher(watcher) + + with self.assertRaises(RuntimeError): + await subprocess.create_subprocess_exec( + os_helper.FakePath(sys.executable), '-c', 'pass') + + watcher.add_child_handler.assert_not_called() + + with asyncio.Runner(loop_factory=asyncio.new_event_loop) as runner: + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + self.assertIsNone(runner.run(execute())) + self.assertListEqual(watcher.mock_calls, [ + mock.call.__enter__(), + mock.call.is_active(), + mock.call.__exit__(RuntimeError, mock.ANY, mock.ANY), + ], watcher.mock_calls) + + + @unittest.skipUnless( + unix_events.can_use_pidfd(), + "operating system does not support pidfds", + ) + def test_create_subprocess_with_pidfd(self): + async def in_thread(): + proc = await asyncio.create_subprocess_exec( + *PROGRAM_CAT, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + ) + stdout, stderr = await proc.communicate(b"some data") + return proc.returncode, stdout + + async def main(): + # asyncio.Runner did not call asyncio.set_event_loop() + with self.assertRaises(RuntimeError): + asyncio.get_event_loop_policy().get_event_loop() + return await asyncio.to_thread(asyncio.run, in_thread()) + with self.assertWarns(DeprecationWarning): + asyncio.set_child_watcher(asyncio.PidfdChildWatcher()) + try: + with asyncio.Runner(loop_factory=asyncio.new_event_loop) as runner: + returncode, stdout = runner.run(main()) + self.assertEqual(returncode, 0) + self.assertEqual(stdout, b'some data') + finally: + with self.assertWarns(DeprecationWarning): + asyncio.set_child_watcher(None) else: # Windows class SubprocessProactorTests(SubprocessMixin, test_utils.TestCase): @@ -709,25 +918,5 @@ else: self.set_event_loop(self.loop) -class GenericWatcherTests: - - def test_create_subprocess_fails_with_inactive_watcher(self): - - async def execute(): - watcher = mock.create_authspec(asyncio.AbstractChildWatcher) - watcher.is_active.return_value = False - asyncio.set_child_watcher(watcher) - - with self.assertRaises(RuntimeError): - await subprocess.create_subprocess_exec( - os_helper.FakePath(sys.executable), '-c', 'pass') - - watcher.add_child_handler.assert_not_called() - - self.assertIsNone(self.loop.run_until_complete(execute())) - - - - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py new file mode 100644 index 00000000000..6a0231f2859 --- /dev/null +++ b/Lib/test/test_asyncio/test_taskgroups.py @@ -0,0 +1,784 @@ +# Adapted with permission from the EdgeDB project; +# license: PSFL. + + +import asyncio +import contextvars +import contextlib +from asyncio import taskgroups +import unittest + + +# To prevent a warning "test altered the execution environment" +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + +class MyExc(Exception): + pass + + +class MyBaseExc(BaseException): + pass + + +def get_error_types(eg): + return {type(exc) for exc in eg.exceptions} + + +class TestTaskGroup(unittest.IsolatedAsyncioTestCase): + + async def test_taskgroup_01(self): + + async def foo1(): + await asyncio.sleep(0.1) + return 42 + + async def foo2(): + await asyncio.sleep(0.2) + return 11 + + async with taskgroups.TaskGroup() as g: + t1 = g.create_task(foo1()) + t2 = g.create_task(foo2()) + + self.assertEqual(t1.result(), 42) + self.assertEqual(t2.result(), 11) + + async def test_taskgroup_02(self): + + async def foo1(): + await asyncio.sleep(0.1) + return 42 + + async def foo2(): + await asyncio.sleep(0.2) + return 11 + + async with taskgroups.TaskGroup() as g: + t1 = g.create_task(foo1()) + await asyncio.sleep(0.15) + t2 = g.create_task(foo2()) + + self.assertEqual(t1.result(), 42) + self.assertEqual(t2.result(), 11) + + async def test_taskgroup_03(self): + + async def foo1(): + await asyncio.sleep(1) + return 42 + + async def foo2(): + await asyncio.sleep(0.2) + return 11 + + async with taskgroups.TaskGroup() as g: + t1 = g.create_task(foo1()) + await asyncio.sleep(0.15) + # cancel t1 explicitly, i.e. everything should continue + # working as expected. + t1.cancel() + + t2 = g.create_task(foo2()) + + self.assertTrue(t1.cancelled()) + self.assertEqual(t2.result(), 11) + + async def test_taskgroup_04(self): + + NUM = 0 + t2_cancel = False + t2 = None + + async def foo1(): + await asyncio.sleep(0.1) + 1 / 0 + + async def foo2(): + nonlocal NUM, t2_cancel + try: + await asyncio.sleep(1) + except asyncio.CancelledError: + t2_cancel = True + raise + NUM += 1 + + async def runner(): + nonlocal NUM, t2 + + async with taskgroups.TaskGroup() as g: + g.create_task(foo1()) + t2 = g.create_task(foo2()) + + NUM += 10 + + with self.assertRaises(ExceptionGroup) as cm: + await asyncio.create_task(runner()) + + self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError}) + + self.assertEqual(NUM, 0) + self.assertTrue(t2_cancel) + self.assertTrue(t2.cancelled()) + + async def test_cancel_children_on_child_error(self): + # When a child task raises an error, the rest of the children + # are cancelled and the errors are gathered into an EG. + + NUM = 0 + t2_cancel = False + runner_cancel = False + + async def foo1(): + await asyncio.sleep(0.1) + 1 / 0 + + async def foo2(): + nonlocal NUM, t2_cancel + try: + await asyncio.sleep(5) + except asyncio.CancelledError: + t2_cancel = True + raise + NUM += 1 + + async def runner(): + nonlocal NUM, runner_cancel + + async with taskgroups.TaskGroup() as g: + g.create_task(foo1()) + g.create_task(foo1()) + g.create_task(foo1()) + g.create_task(foo2()) + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + runner_cancel = True + raise + + NUM += 10 + + # The 3 foo1 sub tasks can be racy when the host is busy - if the + # cancellation happens in the middle, we'll see partial sub errors here + with self.assertRaises(ExceptionGroup) as cm: + await asyncio.create_task(runner()) + + self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError}) + self.assertEqual(NUM, 0) + self.assertTrue(t2_cancel) + self.assertTrue(runner_cancel) + + async def test_cancellation(self): + + NUM = 0 + + async def foo(): + nonlocal NUM + try: + await asyncio.sleep(5) + except asyncio.CancelledError: + NUM += 1 + raise + + async def runner(): + async with taskgroups.TaskGroup() as g: + for _ in range(5): + g.create_task(foo()) + + r = asyncio.create_task(runner()) + await asyncio.sleep(0.1) + + self.assertFalse(r.done()) + r.cancel() + with self.assertRaises(asyncio.CancelledError) as cm: + await r + + self.assertEqual(NUM, 5) + + async def test_taskgroup_07(self): + + NUM = 0 + + async def foo(): + nonlocal NUM + try: + await asyncio.sleep(5) + except asyncio.CancelledError: + NUM += 1 + raise + + async def runner(): + nonlocal NUM + async with taskgroups.TaskGroup() as g: + for _ in range(5): + g.create_task(foo()) + + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + NUM += 10 + raise + + r = asyncio.create_task(runner()) + await asyncio.sleep(0.1) + + self.assertFalse(r.done()) + r.cancel() + with self.assertRaises(asyncio.CancelledError): + await r + + self.assertEqual(NUM, 15) + + async def test_taskgroup_08(self): + + async def foo(): + try: + await asyncio.sleep(10) + finally: + 1 / 0 + + async def runner(): + async with taskgroups.TaskGroup() as g: + for _ in range(5): + g.create_task(foo()) + + await asyncio.sleep(10) + + r = asyncio.create_task(runner()) + await asyncio.sleep(0.1) + + self.assertFalse(r.done()) + r.cancel() + with self.assertRaises(ExceptionGroup) as cm: + await r + self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError}) + + async def test_taskgroup_09(self): + + t1 = t2 = None + + async def foo1(): + await asyncio.sleep(1) + return 42 + + async def foo2(): + await asyncio.sleep(2) + return 11 + + async def runner(): + nonlocal t1, t2 + async with taskgroups.TaskGroup() as g: + t1 = g.create_task(foo1()) + t2 = g.create_task(foo2()) + await asyncio.sleep(0.1) + 1 / 0 + + try: + await runner() + except ExceptionGroup as t: + self.assertEqual(get_error_types(t), {ZeroDivisionError}) + else: + self.fail('ExceptionGroup was not raised') + + self.assertTrue(t1.cancelled()) + self.assertTrue(t2.cancelled()) + + async def test_taskgroup_10(self): + + t1 = t2 = None + + async def foo1(): + await asyncio.sleep(1) + return 42 + + async def foo2(): + await asyncio.sleep(2) + return 11 + + async def runner(): + nonlocal t1, t2 + async with taskgroups.TaskGroup() as g: + t1 = g.create_task(foo1()) + t2 = g.create_task(foo2()) + 1 / 0 + + try: + await runner() + except ExceptionGroup as t: + self.assertEqual(get_error_types(t), {ZeroDivisionError}) + else: + self.fail('ExceptionGroup was not raised') + + self.assertTrue(t1.cancelled()) + self.assertTrue(t2.cancelled()) + + async def test_taskgroup_11(self): + + async def foo(): + try: + await asyncio.sleep(10) + finally: + 1 / 0 + + async def runner(): + async with taskgroups.TaskGroup(): + async with taskgroups.TaskGroup() as g2: + for _ in range(5): + g2.create_task(foo()) + + await asyncio.sleep(10) + + r = asyncio.create_task(runner()) + await asyncio.sleep(0.1) + + self.assertFalse(r.done()) + r.cancel() + with self.assertRaises(ExceptionGroup) as cm: + await r + + self.assertEqual(get_error_types(cm.exception), {ExceptionGroup}) + self.assertEqual(get_error_types(cm.exception.exceptions[0]), {ZeroDivisionError}) + + async def test_taskgroup_12(self): + + async def foo(): + try: + await asyncio.sleep(10) + finally: + 1 / 0 + + async def runner(): + async with taskgroups.TaskGroup() as g1: + g1.create_task(asyncio.sleep(10)) + + async with taskgroups.TaskGroup() as g2: + for _ in range(5): + g2.create_task(foo()) + + await asyncio.sleep(10) + + r = asyncio.create_task(runner()) + await asyncio.sleep(0.1) + + self.assertFalse(r.done()) + r.cancel() + with self.assertRaises(ExceptionGroup) as cm: + await r + + self.assertEqual(get_error_types(cm.exception), {ExceptionGroup}) + self.assertEqual(get_error_types(cm.exception.exceptions[0]), {ZeroDivisionError}) + + async def test_taskgroup_13(self): + + async def crash_after(t): + await asyncio.sleep(t) + raise ValueError(t) + + async def runner(): + async with taskgroups.TaskGroup() as g1: + g1.create_task(crash_after(0.1)) + + async with taskgroups.TaskGroup() as g2: + g2.create_task(crash_after(10)) + + r = asyncio.create_task(runner()) + with self.assertRaises(ExceptionGroup) as cm: + await r + + self.assertEqual(get_error_types(cm.exception), {ValueError}) + + async def test_taskgroup_14(self): + + async def crash_after(t): + await asyncio.sleep(t) + raise ValueError(t) + + async def runner(): + async with taskgroups.TaskGroup() as g1: + g1.create_task(crash_after(10)) + + async with taskgroups.TaskGroup() as g2: + g2.create_task(crash_after(0.1)) + + r = asyncio.create_task(runner()) + with self.assertRaises(ExceptionGroup) as cm: + await r + + self.assertEqual(get_error_types(cm.exception), {ExceptionGroup}) + self.assertEqual(get_error_types(cm.exception.exceptions[0]), {ValueError}) + + async def test_taskgroup_15(self): + + async def crash_soon(): + await asyncio.sleep(0.3) + 1 / 0 + + async def runner(): + async with taskgroups.TaskGroup() as g1: + g1.create_task(crash_soon()) + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + await asyncio.sleep(0.5) + raise + + r = asyncio.create_task(runner()) + await asyncio.sleep(0.1) + + self.assertFalse(r.done()) + r.cancel() + with self.assertRaises(ExceptionGroup) as cm: + await r + self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError}) + + async def test_taskgroup_16(self): + + async def crash_soon(): + await asyncio.sleep(0.3) + 1 / 0 + + async def nested_runner(): + async with taskgroups.TaskGroup() as g1: + g1.create_task(crash_soon()) + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + await asyncio.sleep(0.5) + raise + + async def runner(): + t = asyncio.create_task(nested_runner()) + await t + + r = asyncio.create_task(runner()) + await asyncio.sleep(0.1) + + self.assertFalse(r.done()) + r.cancel() + with self.assertRaises(ExceptionGroup) as cm: + await r + self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError}) + + async def test_taskgroup_17(self): + NUM = 0 + + async def runner(): + nonlocal NUM + async with taskgroups.TaskGroup(): + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + NUM += 10 + raise + + r = asyncio.create_task(runner()) + await asyncio.sleep(0.1) + + self.assertFalse(r.done()) + r.cancel() + with self.assertRaises(asyncio.CancelledError): + await r + + self.assertEqual(NUM, 10) + + async def test_taskgroup_18(self): + NUM = 0 + + async def runner(): + nonlocal NUM + async with taskgroups.TaskGroup(): + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + NUM += 10 + # This isn't a good idea, but we have to support + # this weird case. + raise MyExc + + r = asyncio.create_task(runner()) + await asyncio.sleep(0.1) + + self.assertFalse(r.done()) + r.cancel() + + try: + await r + except ExceptionGroup as t: + self.assertEqual(get_error_types(t),{MyExc}) + else: + self.fail('ExceptionGroup was not raised') + + self.assertEqual(NUM, 10) + + async def test_taskgroup_19(self): + async def crash_soon(): + await asyncio.sleep(0.1) + 1 / 0 + + async def nested(): + try: + await asyncio.sleep(10) + finally: + raise MyExc + + async def runner(): + async with taskgroups.TaskGroup() as g: + g.create_task(crash_soon()) + await nested() + + r = asyncio.create_task(runner()) + try: + await r + except ExceptionGroup as t: + self.assertEqual(get_error_types(t), {MyExc, ZeroDivisionError}) + else: + self.fail('TasgGroupError was not raised') + + async def test_taskgroup_20(self): + async def crash_soon(): + await asyncio.sleep(0.1) + 1 / 0 + + async def nested(): + try: + await asyncio.sleep(10) + finally: + raise KeyboardInterrupt + + async def runner(): + async with taskgroups.TaskGroup() as g: + g.create_task(crash_soon()) + await nested() + + with self.assertRaises(KeyboardInterrupt): + await runner() + + async def test_taskgroup_20a(self): + async def crash_soon(): + await asyncio.sleep(0.1) + 1 / 0 + + async def nested(): + try: + await asyncio.sleep(10) + finally: + raise MyBaseExc + + async def runner(): + async with taskgroups.TaskGroup() as g: + g.create_task(crash_soon()) + await nested() + + with self.assertRaises(BaseExceptionGroup) as cm: + await runner() + + self.assertEqual( + get_error_types(cm.exception), {MyBaseExc, ZeroDivisionError} + ) + + async def _test_taskgroup_21(self): + # This test doesn't work as asyncio, currently, doesn't + # correctly propagate KeyboardInterrupt (or SystemExit) -- + # those cause the event loop itself to crash. + # (Compare to the previous (passing) test -- that one raises + # a plain exception but raises KeyboardInterrupt in nested(); + # this test does it the other way around.) + + async def crash_soon(): + await asyncio.sleep(0.1) + raise KeyboardInterrupt + + async def nested(): + try: + await asyncio.sleep(10) + finally: + raise TypeError + + async def runner(): + async with taskgroups.TaskGroup() as g: + g.create_task(crash_soon()) + await nested() + + with self.assertRaises(KeyboardInterrupt): + await runner() + + async def test_taskgroup_21a(self): + + async def crash_soon(): + await asyncio.sleep(0.1) + raise MyBaseExc + + async def nested(): + try: + await asyncio.sleep(10) + finally: + raise TypeError + + async def runner(): + async with taskgroups.TaskGroup() as g: + g.create_task(crash_soon()) + await nested() + + with self.assertRaises(BaseExceptionGroup) as cm: + await runner() + + self.assertEqual(get_error_types(cm.exception), {MyBaseExc, TypeError}) + + async def test_taskgroup_22(self): + + async def foo1(): + await asyncio.sleep(1) + return 42 + + async def foo2(): + await asyncio.sleep(2) + return 11 + + async def runner(): + async with taskgroups.TaskGroup() as g: + g.create_task(foo1()) + g.create_task(foo2()) + + r = asyncio.create_task(runner()) + await asyncio.sleep(0.05) + r.cancel() + + with self.assertRaises(asyncio.CancelledError): + await r + + async def test_taskgroup_23(self): + + async def do_job(delay): + await asyncio.sleep(delay) + + async with taskgroups.TaskGroup() as g: + for count in range(10): + await asyncio.sleep(0.1) + g.create_task(do_job(0.3)) + if count == 5: + self.assertLess(len(g._tasks), 5) + await asyncio.sleep(1.35) + self.assertEqual(len(g._tasks), 0) + + async def test_taskgroup_24(self): + + async def root(g): + await asyncio.sleep(0.1) + g.create_task(coro1(0.1)) + g.create_task(coro1(0.2)) + + async def coro1(delay): + await asyncio.sleep(delay) + + async def runner(): + async with taskgroups.TaskGroup() as g: + g.create_task(root(g)) + + await runner() + + async def test_taskgroup_25(self): + nhydras = 0 + + async def hydra(g): + nonlocal nhydras + nhydras += 1 + await asyncio.sleep(0.01) + g.create_task(hydra(g)) + g.create_task(hydra(g)) + + async def hercules(): + while nhydras < 10: + await asyncio.sleep(0.015) + 1 / 0 + + async def runner(): + async with taskgroups.TaskGroup() as g: + g.create_task(hydra(g)) + g.create_task(hercules()) + + with self.assertRaises(ExceptionGroup) as cm: + await runner() + + self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError}) + self.assertGreaterEqual(nhydras, 10) + + async def test_taskgroup_task_name(self): + async def coro(): + await asyncio.sleep(0) + async with taskgroups.TaskGroup() as g: + t = g.create_task(coro(), name="yolo") + self.assertEqual(t.get_name(), "yolo") + + async def test_taskgroup_task_context(self): + cvar = contextvars.ContextVar('cvar') + + async def coro(val): + await asyncio.sleep(0) + cvar.set(val) + + async with taskgroups.TaskGroup() as g: + ctx = contextvars.copy_context() + self.assertIsNone(ctx.get(cvar)) + t1 = g.create_task(coro(1), context=ctx) + await t1 + self.assertEqual(1, ctx.get(cvar)) + t2 = g.create_task(coro(2), context=ctx) + await t2 + self.assertEqual(2, ctx.get(cvar)) + + async def test_taskgroup_no_create_task_after_failure(self): + async def coro1(): + await asyncio.sleep(0.001) + 1 / 0 + async def coro2(g): + try: + await asyncio.sleep(1) + except asyncio.CancelledError: + with self.assertRaises(RuntimeError): + g.create_task(c1 := coro1()) + # We still have to await c1 to avoid a warning + with self.assertRaises(ZeroDivisionError): + await c1 + + with self.assertRaises(ExceptionGroup) as cm: + async with taskgroups.TaskGroup() as g: + g.create_task(coro1()) + g.create_task(coro2(g)) + + self.assertEqual(get_error_types(cm.exception), {ZeroDivisionError}) + + async def test_taskgroup_context_manager_exit_raises(self): + # See https://github.com/python/cpython/issues/95289 + class CustomException(Exception): + pass + + async def raise_exc(): + raise CustomException + + @contextlib.asynccontextmanager + async def database(): + try: + yield + finally: + raise CustomException + + async def main(): + task = asyncio.current_task() + try: + async with taskgroups.TaskGroup() as tg: + async with database(): + tg.create_task(raise_exc()) + await asyncio.sleep(1) + except* CustomException as err: + self.assertEqual(task.cancelling(), 0) + self.assertEqual(len(err.exceptions), 2) + + else: + self.fail('CustomException not raised') + + await asyncio.create_task(main()) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 362fbf8df08..e533d5273e9 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -1,23 +1,18 @@ """Tests for tasks.py.""" import collections -import contextlib import contextvars -import functools import gc import io import random import re import sys -import textwrap import traceback -import types import unittest -import weakref from unittest import mock +from types import GenericAlias import asyncio -from asyncio import coroutines from asyncio import futures from asyncio import tasks from test.test_asyncio import utils as test_utils @@ -85,19 +80,13 @@ class CoroLikeObject: return self -# The following value can be used as a very small timeout: -# it passes check "timeout > 0", but has almost -# no effect on the test performance -_EPSILON = 0.0001 - - class BaseTaskTests: Task = None Future = None - def new_task(self, loop, coro, name='TestTask'): - return self.__class__.Task(coro, loop=loop, name=name) + def new_task(self, loop, coro, name='TestTask', context=None): + return self.__class__.Task(coro, loop=loop, name=name, context=context) def new_future(self, loop): return self.__class__.Future(loop=loop) @@ -108,6 +97,11 @@ class BaseTaskTests: self.loop.set_task_factory(self.new_task) self.loop.create_future = lambda: self.new_future(self.loop) + def test_generic_alias(self): + task = self.__class__.Task[str] + self.assertEqual(task.__args__, (str,)) + self.assertIsInstance(task, GenericAlias) + def test_task_cancel_message_getter(self): async def coro(): pass @@ -118,9 +112,11 @@ class BaseTaskTests: t.cancel('my message') self.assertEqual(t._cancel_message, 'my message') - with self.assertRaises(asyncio.CancelledError): + with self.assertRaises(asyncio.CancelledError) as cm: self.loop.run_until_complete(t) + self.assertEqual('my message', cm.exception.args[0]) + def test_task_cancel_message_setter(self): async def coro(): pass @@ -129,9 +125,11 @@ class BaseTaskTests: t._cancel_message = 'my new message' self.assertEqual(t._cancel_message, 'my new message') - with self.assertRaises(asyncio.CancelledError): + with self.assertRaises(asyncio.CancelledError) as cm: self.loop.run_until_complete(t) + self.assertEqual('my new message', cm.exception.args[0]) + def test_task_del_collect(self): class Evil: def __del__(self): @@ -198,10 +196,8 @@ class BaseTaskTests: a = notmuch() self.addCleanup(a.close) - with self.assertWarns(DeprecationWarning) as cm: - with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'): - asyncio.ensure_future(a) - self.assertEqual(cm.warnings[0].filename, __file__) + with self.assertRaisesRegex(RuntimeError, 'no current event loop'): + asyncio.ensure_future(a) async def test(): return asyncio.ensure_future(notmuch()) @@ -211,12 +207,10 @@ class BaseTaskTests: self.assertTrue(t.done()) self.assertEqual(t.result(), 'ok') - # Deprecated in 3.10 + # Deprecated in 3.10, undeprecated in 3.12 asyncio.set_event_loop(self.loop) self.addCleanup(asyncio.set_event_loop, None) - with self.assertWarns(DeprecationWarning) as cm: - t = asyncio.ensure_future(notmuch()) - self.assertEqual(cm.warnings[0].filename, __file__) + t = asyncio.ensure_future(notmuch()) self.assertIs(t._loop, self.loop) self.loop.run_until_complete(t) self.assertTrue(t.done()) @@ -278,7 +272,7 @@ class BaseTaskTests: self.set_event_loop(loop) fut = asyncio.ensure_future(Aw(coro()), loop=loop) loop.run_until_complete(fut) - assert fut.result() == 'ok' + self.assertEqual(fut.result(), 'ok') def test_ensure_future_neither(self): with self.assertRaises(TypeError): @@ -490,6 +484,178 @@ class BaseTaskTests: # This also distinguishes from the initial has_cycle=None. self.assertEqual(has_cycle, False) + + def test_cancelling(self): + loop = asyncio.new_event_loop() + + async def task(): + await asyncio.sleep(10) + + try: + t = self.new_task(loop, task()) + self.assertFalse(t.cancelling()) + self.assertNotIn(" cancelling ", repr(t)) + self.assertTrue(t.cancel()) + self.assertTrue(t.cancelling()) + self.assertIn(" cancelling ", repr(t)) + + # Since we commented out two lines from Task.cancel(), + # this t.cancel() call now returns True. + # self.assertFalse(t.cancel()) + self.assertTrue(t.cancel()) + + with self.assertRaises(asyncio.CancelledError): + loop.run_until_complete(t) + finally: + loop.close() + + def test_uncancel_basic(self): + loop = asyncio.new_event_loop() + + async def task(): + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + asyncio.current_task().uncancel() + await asyncio.sleep(10) + + try: + t = self.new_task(loop, task()) + loop.run_until_complete(asyncio.sleep(0.01)) + + # Cancel first sleep + self.assertTrue(t.cancel()) + self.assertIn(" cancelling ", repr(t)) + self.assertEqual(t.cancelling(), 1) + self.assertFalse(t.cancelled()) # Task is still not complete + loop.run_until_complete(asyncio.sleep(0.01)) + + # after .uncancel() + self.assertNotIn(" cancelling ", repr(t)) + self.assertEqual(t.cancelling(), 0) + self.assertFalse(t.cancelled()) # Task is still not complete + + # Cancel second sleep + self.assertTrue(t.cancel()) + self.assertEqual(t.cancelling(), 1) + self.assertFalse(t.cancelled()) # Task is still not complete + with self.assertRaises(asyncio.CancelledError): + loop.run_until_complete(t) + self.assertTrue(t.cancelled()) # Finally, task complete + self.assertTrue(t.done()) + + # uncancel is no longer effective after the task is complete + t.uncancel() + self.assertTrue(t.cancelled()) + self.assertTrue(t.done()) + finally: + loop.close() + + def test_uncancel_structured_blocks(self): + # This test recreates the following high-level structure using uncancel():: + # + # async def make_request_with_timeout(): + # try: + # async with asyncio.timeout(1): + # # Structured block affected by the timeout: + # await make_request() + # await make_another_request() + # except TimeoutError: + # pass # There was a timeout + # # Outer code not affected by the timeout: + # await unrelated_code() + + loop = asyncio.new_event_loop() + + async def make_request_with_timeout(*, sleep: float, timeout: float): + task = asyncio.current_task() + loop = task.get_loop() + + timed_out = False + structured_block_finished = False + outer_code_reached = False + + def on_timeout(): + nonlocal timed_out + timed_out = True + task.cancel() + + timeout_handle = loop.call_later(timeout, on_timeout) + try: + try: + # Structured block affected by the timeout + await asyncio.sleep(sleep) + structured_block_finished = True + finally: + timeout_handle.cancel() + if ( + timed_out + and task.uncancel() == 0 + and sys.exc_info()[0] is asyncio.CancelledError + ): + # Note the five rules that are needed here to satisfy proper + # uncancellation: + # + # 1. handle uncancellation in a `finally:` block to allow for + # plain returns; + # 2. our `timed_out` flag is set, meaning that it was our event + # that triggered the need to uncancel the task, regardless of + # what exception is raised; + # 3. we can call `uncancel()` because *we* called `cancel()` + # before; + # 4. we call `uncancel()` but we only continue converting the + # CancelledError to TimeoutError if `uncancel()` caused the + # cancellation request count go down to 0. We need to look + # at the counter vs having a simple boolean flag because our + # code might have been nested (think multiple timeouts). See + # commit 7fce1063b6e5a366f8504e039a8ccdd6944625cd for + # details. + # 5. we only convert CancelledError to TimeoutError; for other + # exceptions raised due to the cancellation (like + # a ConnectionLostError from a database client), simply + # propagate them. + # + # Those checks need to take place in this exact order to make + # sure the `cancelling()` counter always stays in sync. + # + # Additionally, the original stimulus to `cancel()` the task + # needs to be unscheduled to avoid re-cancelling the task later. + # Here we do it by cancelling `timeout_handle` in the `finally:` + # block. + raise TimeoutError + except TimeoutError: + self.assertTrue(timed_out) + + # Outer code not affected by the timeout: + outer_code_reached = True + await asyncio.sleep(0) + return timed_out, structured_block_finished, outer_code_reached + + try: + # Test which timed out. + t1 = self.new_task(loop, make_request_with_timeout(sleep=10.0, timeout=0.1)) + timed_out, structured_block_finished, outer_code_reached = ( + loop.run_until_complete(t1) + ) + self.assertTrue(timed_out) + self.assertFalse(structured_block_finished) # it was cancelled + self.assertTrue(outer_code_reached) # task got uncancelled after leaving + # the structured block and continued until + # completion + self.assertEqual(t1.cancelling(), 0) # no pending cancellation of the outer task + + # Test which did not time out. + t2 = self.new_task(loop, make_request_with_timeout(sleep=0, timeout=10.0)) + timed_out, structured_block_finished, outer_code_reached = ( + loop.run_until_complete(t2) + ) + self.assertFalse(timed_out) + self.assertTrue(structured_block_finished) + self.assertTrue(outer_code_reached) + self.assertEqual(t2.cancelling(), 0) + finally: + loop.close() + def test_cancel(self): def gen(): @@ -539,11 +705,11 @@ class BaseTaskTests: with self.assertRaises(asyncio.CancelledError) as cm: loop.run_until_complete(task) exc = cm.exception - self.assertEqual(exc.args, ()) + self.assertEqual(exc.args, expected_args) actual = get_innermost_context(exc) self.assertEqual(actual, - (asyncio.CancelledError, expected_args, 2)) + (asyncio.CancelledError, expected_args, 0)) def test_cancel_with_message_then_future_exception(self): # Test Future.exception() after calling cancel() with a message. @@ -573,11 +739,39 @@ class BaseTaskTests: with self.assertRaises(asyncio.CancelledError) as cm: loop.run_until_complete(task) exc = cm.exception - self.assertEqual(exc.args, ()) + self.assertEqual(exc.args, expected_args) actual = get_innermost_context(exc) self.assertEqual(actual, - (asyncio.CancelledError, expected_args, 2)) + (asyncio.CancelledError, expected_args, 0)) + + def test_cancellation_exception_context(self): + loop = asyncio.new_event_loop() + self.set_event_loop(loop) + fut = loop.create_future() + + async def sleep(): + fut.set_result(None) + await asyncio.sleep(10) + + async def coro(): + inner_task = self.new_task(loop, sleep()) + await fut + loop.call_soon(inner_task.cancel, 'msg') + try: + await inner_task + except asyncio.CancelledError as ex: + raise ValueError("cancelled") from ex + + task = self.new_task(loop, coro()) + with self.assertRaises(ValueError) as cm: + loop.run_until_complete(task) + exc = cm.exception + self.assertEqual(exc.args, ('cancelled',)) + + actual = get_innermost_context(exc) + self.assertEqual(actual, + (asyncio.CancelledError, ('msg',), 1)) def test_cancel_with_message_before_starting_task(self): loop = asyncio.new_event_loop() @@ -597,11 +791,11 @@ class BaseTaskTests: with self.assertRaises(asyncio.CancelledError) as cm: loop.run_until_complete(task) exc = cm.exception - self.assertEqual(exc.args, ()) + self.assertEqual(exc.args, ('my message',)) actual = get_innermost_context(exc) self.assertEqual(actual, - (asyncio.CancelledError, ('my message',), 2)) + (asyncio.CancelledError, ('my message',), 0)) def test_cancel_yield(self): async def task(): @@ -885,273 +1079,6 @@ class BaseTaskTests: task._log_traceback = True self.loop.run_until_complete(task) - def test_wait_for_timeout_less_then_0_or_0_future_done(self): - def gen(): - when = yield - self.assertAlmostEqual(0, when) - - loop = self.new_test_loop(gen) - - fut = self.new_future(loop) - fut.set_result('done') - - ret = loop.run_until_complete(asyncio.wait_for(fut, 0)) - - self.assertEqual(ret, 'done') - self.assertTrue(fut.done()) - self.assertAlmostEqual(0, loop.time()) - - def test_wait_for_timeout_less_then_0_or_0_coroutine_do_not_started(self): - def gen(): - when = yield - self.assertAlmostEqual(0, when) - - loop = self.new_test_loop(gen) - - foo_started = False - - async def foo(): - nonlocal foo_started - foo_started = True - - with self.assertRaises(asyncio.TimeoutError): - loop.run_until_complete(asyncio.wait_for(foo(), 0)) - - self.assertAlmostEqual(0, loop.time()) - self.assertEqual(foo_started, False) - - def test_wait_for_timeout_less_then_0_or_0(self): - def gen(): - when = yield - self.assertAlmostEqual(0.2, when) - when = yield 0 - self.assertAlmostEqual(0, when) - - for timeout in [0, -1]: - with self.subTest(timeout=timeout): - loop = self.new_test_loop(gen) - - foo_running = None - - async def foo(): - nonlocal foo_running - foo_running = True - try: - await asyncio.sleep(0.2) - finally: - foo_running = False - return 'done' - - fut = self.new_task(loop, foo()) - - with self.assertRaises(asyncio.TimeoutError): - loop.run_until_complete(asyncio.wait_for(fut, timeout)) - self.assertTrue(fut.done()) - # it should have been cancelled due to the timeout - self.assertTrue(fut.cancelled()) - self.assertAlmostEqual(0, loop.time()) - self.assertEqual(foo_running, False) - - def test_wait_for(self): - - def gen(): - when = yield - self.assertAlmostEqual(0.2, when) - when = yield 0 - self.assertAlmostEqual(0.1, when) - when = yield 0.1 - - loop = self.new_test_loop(gen) - - foo_running = None - - async def foo(): - nonlocal foo_running - foo_running = True - try: - await asyncio.sleep(0.2) - finally: - foo_running = False - return 'done' - - fut = self.new_task(loop, foo()) - - with self.assertRaises(asyncio.TimeoutError): - loop.run_until_complete(asyncio.wait_for(fut, 0.1)) - self.assertTrue(fut.done()) - # it should have been cancelled due to the timeout - self.assertTrue(fut.cancelled()) - self.assertAlmostEqual(0.1, loop.time()) - self.assertEqual(foo_running, False) - - def test_wait_for_blocking(self): - loop = self.new_test_loop() - - async def coro(): - return 'done' - - res = loop.run_until_complete(asyncio.wait_for(coro(), timeout=None)) - self.assertEqual(res, 'done') - - def test_wait_for_race_condition(self): - - def gen(): - yield 0.1 - yield 0.1 - yield 0.1 - - loop = self.new_test_loop(gen) - - fut = self.new_future(loop) - task = asyncio.wait_for(fut, timeout=0.2) - loop.call_later(0.1, fut.set_result, "ok") - res = loop.run_until_complete(task) - self.assertEqual(res, "ok") - - def test_wait_for_cancellation_race_condition(self): - def gen(): - yield 0.1 - yield 0.1 - yield 0.1 - yield 0.1 - - loop = self.new_test_loop(gen) - - fut = self.new_future(loop) - loop.call_later(0.1, fut.set_result, "ok") - task = loop.create_task(asyncio.wait_for(fut, timeout=1)) - loop.call_later(0.1, task.cancel) - res = loop.run_until_complete(task) - self.assertEqual(res, "ok") - - def test_wait_for_waits_for_task_cancellation(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - task_done = False - - async def foo(): - async def inner(): - nonlocal task_done - try: - await asyncio.sleep(0.2) - except asyncio.CancelledError: - await asyncio.sleep(_EPSILON) - raise - finally: - task_done = True - - inner_task = self.new_task(loop, inner()) - - await asyncio.wait_for(inner_task, timeout=_EPSILON) - - with self.assertRaises(asyncio.TimeoutError) as cm: - loop.run_until_complete(foo()) - - self.assertTrue(task_done) - chained = cm.exception.__context__ - self.assertEqual(type(chained), asyncio.CancelledError) - - def test_wait_for_waits_for_task_cancellation_w_timeout_0(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - task_done = False - - async def foo(): - async def inner(): - nonlocal task_done - try: - await asyncio.sleep(10) - except asyncio.CancelledError: - await asyncio.sleep(_EPSILON) - raise - finally: - task_done = True - - inner_task = self.new_task(loop, inner()) - await asyncio.sleep(_EPSILON) - await asyncio.wait_for(inner_task, timeout=0) - - with self.assertRaises(asyncio.TimeoutError) as cm: - loop.run_until_complete(foo()) - - self.assertTrue(task_done) - chained = cm.exception.__context__ - self.assertEqual(type(chained), asyncio.CancelledError) - - def test_wait_for_reraises_exception_during_cancellation(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - class FooException(Exception): - pass - - async def foo(): - async def inner(): - try: - await asyncio.sleep(0.2) - finally: - raise FooException - - inner_task = self.new_task(loop, inner()) - - await asyncio.wait_for(inner_task, timeout=_EPSILON) - - with self.assertRaises(FooException): - loop.run_until_complete(foo()) - - def test_wait_for_raises_timeout_error_if_returned_during_cancellation(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - async def foo(): - async def inner(): - try: - await asyncio.sleep(0.2) - except asyncio.CancelledError: - return 42 - - inner_task = self.new_task(loop, inner()) - - await asyncio.wait_for(inner_task, timeout=_EPSILON) - - with self.assertRaises(asyncio.TimeoutError): - loop.run_until_complete(foo()) - - def test_wait_for_self_cancellation(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - async def foo(): - async def inner(): - try: - await asyncio.sleep(0.3) - except asyncio.CancelledError: - try: - await asyncio.sleep(0.3) - except asyncio.CancelledError: - await asyncio.sleep(0.3) - - return 42 - - inner_task = self.new_task(loop, inner()) - - wait = asyncio.wait_for(inner_task, timeout=0.1) - - # Test that wait_for itself is properly cancellable - # even when the initial task holds up the initial cancellation. - task = self.new_task(loop, wait) - await asyncio.sleep(0.2) - task.cancel() - - with self.assertRaises(asyncio.CancelledError): - await task - - self.assertEqual(await inner_task, 42) - - loop.run_until_complete(foo()) - def test_wait(self): def gen(): @@ -1185,13 +1112,12 @@ class BaseTaskTests: async def coro(s): return s - c = coro('test') + c = self.loop.create_task(coro('test')) task = self.new_task( self.loop, - asyncio.wait([c, c, coro('spam')])) + asyncio.wait([c, c, self.loop.create_task(coro('spam'))])) - with self.assertWarns(DeprecationWarning): - done, pending = self.loop.run_until_complete(task) + done, pending = self.loop.run_until_complete(task) self.assertFalse(pending) self.assertEqual(set(f.result() for f in done), {'test', 'spam'}) @@ -1568,11 +1494,9 @@ class BaseTaskTests: async def test(): futs = list(asyncio.as_completed(fs)) self.assertEqual(len(futs), 2) - waiter = asyncio.wait(futs) - # Deprecation from passing coros in futs to asyncio.wait() - with self.assertWarns(DeprecationWarning) as cm: - done, pending = await waiter - self.assertEqual(cm.warnings[0].filename, __file__) + done, pending = await asyncio.wait( + [asyncio.ensure_future(fut) for fut in futs] + ) self.assertEqual(set(f.result() for f in done), {'a', 'b'}) loop = self.new_test_loop(gen) @@ -1604,10 +1528,8 @@ class BaseTaskTests: self.addCleanup(a.close) futs = asyncio.as_completed([a]) - with self.assertWarns(DeprecationWarning) as cm: - with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'): - list(futs) - self.assertEqual(cm.warnings[0].filename, __file__) + with self.assertRaisesRegex(RuntimeError, 'no current event loop'): + list(futs) def test_as_completed_coroutine_use_running_loop(self): loop = self.new_test_loop() @@ -1622,21 +1544,6 @@ class BaseTaskTests: loop.run_until_complete(test()) - def test_as_completed_coroutine_use_global_loop(self): - # Deprecated in 3.10 - async def coro(): - return 42 - - loop = self.new_test_loop() - asyncio.set_event_loop(loop) - self.addCleanup(asyncio.set_event_loop, None) - futs = asyncio.as_completed([coro()]) - with self.assertWarns(DeprecationWarning) as cm: - futs = list(futs) - self.assertEqual(cm.warnings[0].filename, __file__) - self.assertEqual(len(futs), 1) - self.assertEqual(loop.run_until_complete(futs[0]), 42) - def test_sleep(self): def gen(): @@ -1826,6 +1733,7 @@ class BaseTaskTests: self.assertTrue(asyncio.iscoroutinefunction(fn2)) self.assertFalse(asyncio.iscoroutinefunction(mock.Mock())) + self.assertTrue(asyncio.iscoroutinefunction(mock.AsyncMock())) def test_coroutine_non_gen_function(self): async def func(): @@ -1939,7 +1847,7 @@ class BaseTaskTests: async def outer(): nonlocal proof with self.assertWarns(DeprecationWarning): - d, p = await asyncio.wait([inner()]) + d, p = await asyncio.wait([asyncio.create_task(inner())]) proof += 100 f = asyncio.ensure_future(outer(), loop=self.loop) @@ -2051,10 +1959,8 @@ class BaseTaskTests: inner = coro() self.addCleanup(inner.close) - with self.assertWarns(DeprecationWarning) as cm: - with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'): - asyncio.shield(inner) - self.assertEqual(cm.warnings[0].filename, __file__) + with self.assertRaisesRegex(RuntimeError, 'no current event loop'): + asyncio.shield(inner) def test_shield_coroutine_use_running_loop(self): async def coro(): @@ -2068,15 +1974,13 @@ class BaseTaskTests: self.assertEqual(res, 42) def test_shield_coroutine_use_global_loop(self): - # Deprecated in 3.10 + # Deprecated in 3.10, undeprecated in 3.12 async def coro(): return 42 asyncio.set_event_loop(self.loop) self.addCleanup(asyncio.set_event_loop, None) - with self.assertWarns(DeprecationWarning) as cm: - outer = asyncio.shield(coro()) - self.assertEqual(cm.warnings[0].filename, __file__) + outer = asyncio.shield(coro()) self.assertEqual(outer._loop, self.loop) res = self.loop.run_until_complete(outer) self.assertEqual(res, 42) @@ -2178,32 +2082,6 @@ class BaseTaskTests: 'test_task_source_traceback')) self.loop.run_until_complete(task) - def _test_cancel_wait_for(self, timeout): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - async def blocking_coroutine(): - fut = self.new_future(loop) - # Block: fut result is never set - await fut - - task = loop.create_task(blocking_coroutine()) - - wait = loop.create_task(asyncio.wait_for(task, timeout)) - loop.call_soon(wait.cancel) - - self.assertRaises(asyncio.CancelledError, - loop.run_until_complete, wait) - - # Python issue #23219: cancelling the wait must also cancel the task - self.assertTrue(task.cancelled()) - - def test_cancel_blocking_wait_for(self): - self._test_cancel_wait_for(None) - - def test_cancel_wait_for(self): - self._test_cancel_wait_for(60.0) - def test_cancel_gather_1(self): """Ensure that a gathering future refuses to be cancelled once all children are done""" @@ -2214,8 +2092,8 @@ class BaseTaskTests: async def create(): # The indirection fut->child_coro is needed since otherwise the # gathering task is done at the same time as the child future - def child_coro(): - return (yield from fut) + async def child_coro(): + return await fut gather_future = asyncio.gather(child_coro()) return asyncio.ensure_future(gather_future) gather_task = loop.run_until_complete(create()) @@ -2267,15 +2145,17 @@ class BaseTaskTests: try: loop.run_until_complete(main()) except asyncio.CancelledError as exc: - self.assertEqual(exc.args, ()) - exc_type, exc_args, depth = get_innermost_context(exc) - self.assertEqual((exc_type, exc_args), - (asyncio.CancelledError, expected_args)) - # The exact traceback seems to vary in CI. - self.assertIn(depth, (2, 3)) + self.assertEqual(exc.args, expected_args) + actual = get_innermost_context(exc) + self.assertEqual( + actual, + (asyncio.CancelledError, expected_args, 0), + ) else: - self.fail('gather did not propagate the cancellation ' - 'request') + self.fail( + 'gather() does not propagate CancelledError ' + 'raised by inner task to the gather() caller.' + ) def test_exception_traceback(self): # See http://bugs.python.org/issue28843 @@ -2461,6 +2341,90 @@ class BaseTaskTests: self.assertEqual(cvar.get(), -1) + def test_context_4(self): + cvar = contextvars.ContextVar('cvar') + + async def coro(val): + await asyncio.sleep(0) + cvar.set(val) + + async def main(): + ret = [] + ctx = contextvars.copy_context() + ret.append(ctx.get(cvar)) + t1 = self.new_task(loop, coro(1), context=ctx) + await t1 + ret.append(ctx.get(cvar)) + t2 = self.new_task(loop, coro(2), context=ctx) + await t2 + ret.append(ctx.get(cvar)) + return ret + + loop = asyncio.new_event_loop() + try: + task = self.new_task(loop, main()) + ret = loop.run_until_complete(task) + finally: + loop.close() + + self.assertEqual([None, 1, 2], ret) + + def test_context_5(self): + cvar = contextvars.ContextVar('cvar') + + async def coro(val): + await asyncio.sleep(0) + cvar.set(val) + + async def main(): + ret = [] + ctx = contextvars.copy_context() + ret.append(ctx.get(cvar)) + t1 = asyncio.create_task(coro(1), context=ctx) + await t1 + ret.append(ctx.get(cvar)) + t2 = asyncio.create_task(coro(2), context=ctx) + await t2 + ret.append(ctx.get(cvar)) + return ret + + loop = asyncio.new_event_loop() + try: + task = self.new_task(loop, main()) + ret = loop.run_until_complete(task) + finally: + loop.close() + + self.assertEqual([None, 1, 2], ret) + + def test_context_6(self): + cvar = contextvars.ContextVar('cvar') + + async def coro(val): + await asyncio.sleep(0) + cvar.set(val) + + async def main(): + ret = [] + ctx = contextvars.copy_context() + ret.append(ctx.get(cvar)) + t1 = loop.create_task(coro(1), context=ctx) + await t1 + ret.append(ctx.get(cvar)) + t2 = loop.create_task(coro(2), context=ctx) + await t2 + ret.append(ctx.get(cvar)) + return ret + + loop = asyncio.new_event_loop() + try: + task = loop.create_task(main()) + ret = loop.run_until_complete(task) + finally: + loop.close() + + self.assertEqual([None, 1, 2], ret) + def test_get_coro(self): loop = asyncio.new_event_loop() coro = coroutine_function() @@ -2471,6 +2435,17 @@ class BaseTaskTests: finally: loop.close() + def test_get_context(self): + loop = asyncio.new_event_loop() + coro = coroutine_function() + context = contextvars.copy_context() + try: + task = self.new_task(loop, coro, context=context) + loop.run_until_complete(task) + self.assertIs(task.get_context(), context) + finally: + loop.close() + def add_subclass_tests(cls): BaseTask = cls.Task @@ -2829,6 +2804,7 @@ class CIntrospectionTests(test_utils.TestCase, BaseTaskIntrospectionTests): class BaseCurrentLoopTests: + current_task = None def setUp(self): super().setUp() @@ -2839,33 +2815,39 @@ class BaseCurrentLoopTests: raise NotImplementedError def test_current_task_no_running_loop(self): - self.assertIsNone(asyncio.current_task(loop=self.loop)) + self.assertIsNone(self.current_task(loop=self.loop)) def test_current_task_no_running_loop_implicit(self): - with self.assertRaises(RuntimeError): - asyncio.current_task() + with self.assertRaisesRegex(RuntimeError, 'no running event loop'): + self.current_task() def test_current_task_with_implicit_loop(self): async def coro(): - self.assertIs(asyncio.current_task(loop=self.loop), task) + self.assertIs(self.current_task(loop=self.loop), task) - self.assertIs(asyncio.current_task(None), task) - self.assertIs(asyncio.current_task(), task) + self.assertIs(self.current_task(None), task) + self.assertIs(self.current_task(), task) task = self.new_task(coro()) self.loop.run_until_complete(task) - self.assertIsNone(asyncio.current_task(loop=self.loop)) + self.assertIsNone(self.current_task(loop=self.loop)) class PyCurrentLoopTests(BaseCurrentLoopTests, test_utils.TestCase): + current_task = staticmethod(tasks._py_current_task) def new_task(self, coro): return tasks._PyTask(coro, loop=self.loop) -@unittest.skipUnless(hasattr(tasks, '_CTask'), +@unittest.skipUnless(hasattr(tasks, '_CTask') and + hasattr(tasks, '_c_current_task'), 'requires the C _asyncio module') class CCurrentLoopTests(BaseCurrentLoopTests, test_utils.TestCase): + if hasattr(tasks, '_c_current_task'): + current_task = staticmethod(tasks._c_current_task) + else: + current_task = None def new_task(self, coro): return getattr(tasks, '_CTask')(coro, loop=self.loop) @@ -3006,10 +2988,8 @@ class FutureGatherTests(GatherTestsBase, test_utils.TestCase): return asyncio.gather(*args, **kwargs) def test_constructor_empty_sequence_without_loop(self): - with self.assertWarns(DeprecationWarning) as cm: - with self.assertRaises(RuntimeError): - asyncio.gather() - self.assertEqual(cm.warnings[0].filename, __file__) + with self.assertRaisesRegex(RuntimeError, 'no current event loop'): + asyncio.gather() def test_constructor_empty_sequence_use_running_loop(self): async def gather(): @@ -3022,12 +3002,10 @@ class FutureGatherTests(GatherTestsBase, test_utils.TestCase): self.assertEqual(fut.result(), []) def test_constructor_empty_sequence_use_global_loop(self): - # Deprecated in 3.10 + # Deprecated in 3.10, undeprecated in 3.12 asyncio.set_event_loop(self.one_loop) self.addCleanup(asyncio.set_event_loop, None) - with self.assertWarns(DeprecationWarning) as cm: - fut = asyncio.gather() - self.assertEqual(cm.warnings[0].filename, __file__) + fut = asyncio.gather() self.assertIsInstance(fut, asyncio.Future) self.assertIs(fut._loop, self.one_loop) self._run_loop(self.one_loop) @@ -3115,10 +3093,8 @@ class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase): self.addCleanup(gen1.close) gen2 = coro() self.addCleanup(gen2.close) - with self.assertWarns(DeprecationWarning) as cm: - with self.assertRaises(RuntimeError): - asyncio.gather(gen1, gen2) - self.assertEqual(cm.warnings[0].filename, __file__) + with self.assertRaisesRegex(RuntimeError, 'no current event loop'): + asyncio.gather(gen1, gen2) def test_constructor_use_running_loop(self): async def coro(): @@ -3132,16 +3108,14 @@ class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase): self.one_loop.run_until_complete(fut) def test_constructor_use_global_loop(self): - # Deprecated in 3.10 + # Deprecated in 3.10, undeprecated in 3.12 async def coro(): return 'abc' asyncio.set_event_loop(self.other_loop) self.addCleanup(asyncio.set_event_loop, None) gen1 = coro() gen2 = coro() - with self.assertWarns(DeprecationWarning) as cm: - fut = asyncio.gather(gen1, gen2) - self.assertEqual(cm.warnings[0].filename, __file__) + fut = asyncio.gather(gen1, gen2) self.assertIs(fut._loop, self.other_loop) self.other_loop.run_until_complete(fut) @@ -3206,6 +3180,20 @@ class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase): test_utils.run_briefly(self.one_loop) self.assertIsInstance(f.exception(), RuntimeError) + def test_issue46672(self): + with mock.patch( + 'asyncio.base_events.BaseEventLoop.call_exception_handler', + ): + async def coro(s): + return s + c = coro('abc') + + with self.assertRaises(TypeError): + self._gather(c, {}) + self._run_loop(self.one_loop) + # NameError should not happen: + self.one_loop.call_exception_handler.assert_not_called() + class RunCoroutineThreadsafeTests(test_utils.TestCase): """Test case for asyncio.run_coroutine_threadsafe.""" @@ -3334,29 +3322,6 @@ class SleepTests(test_utils.TestCase): self.assertEqual(result, 11) -class WaitTests(test_utils.TestCase): - def setUp(self): - super().setUp() - self.loop = asyncio.new_event_loop() - self.set_event_loop(self.loop) - - def tearDown(self): - self.loop.close() - self.loop = None - super().tearDown() - - def test_coro_is_deprecated_in_wait(self): - # Remove test when passing coros to asyncio.wait() is removed in 3.11 - with self.assertWarns(DeprecationWarning): - self.loop.run_until_complete( - asyncio.wait([coroutine_function()])) - - task = self.loop.create_task(coroutine_function()) - with self.assertWarns(DeprecationWarning): - self.loop.run_until_complete( - asyncio.wait([task, coroutine_function()])) - - class CompatibilityTests(test_utils.TestCase): # Tests for checking a bridge between old-styled coroutines # and async/await syntax diff --git a/Lib/test/test_asyncio/test_threads.py b/Lib/test/test_asyncio/test_threads.py index 2af322421da..1138a93e0f7 100644 --- a/Lib/test/test_asyncio/test_threads.py +++ b/Lib/test/test_asyncio/test_threads.py @@ -5,87 +5,58 @@ import unittest from contextvars import ContextVar from unittest import mock -from test.test_asyncio import utils as test_utils def tearDownModule(): asyncio.set_event_loop_policy(None) -class ToThreadTests(test_utils.TestCase): - def setUp(self): - super().setUp() - self.loop = asyncio.new_event_loop() - asyncio.set_event_loop(self.loop) - - def tearDown(self): - self.loop.run_until_complete( - self.loop.shutdown_default_executor()) - self.loop.close() - asyncio.set_event_loop(None) - self.loop = None - super().tearDown() - - def test_to_thread(self): - async def main(): - return await asyncio.to_thread(sum, [40, 2]) - - result = self.loop.run_until_complete(main()) +class ToThreadTests(unittest.IsolatedAsyncioTestCase): + async def test_to_thread(self): + result = await asyncio.to_thread(sum, [40, 2]) self.assertEqual(result, 42) - def test_to_thread_exception(self): + async def test_to_thread_exception(self): def raise_runtime(): raise RuntimeError("test") - async def main(): + with self.assertRaisesRegex(RuntimeError, "test"): await asyncio.to_thread(raise_runtime) - with self.assertRaisesRegex(RuntimeError, "test"): - self.loop.run_until_complete(main()) - - def test_to_thread_once(self): + async def test_to_thread_once(self): func = mock.Mock() - async def main(): - await asyncio.to_thread(func) - - self.loop.run_until_complete(main()) + await asyncio.to_thread(func) func.assert_called_once() - def test_to_thread_concurrent(self): + async def test_to_thread_concurrent(self): func = mock.Mock() - async def main(): - futs = [] - for _ in range(10): - fut = asyncio.to_thread(func) - futs.append(fut) - await asyncio.gather(*futs) + futs = [] + for _ in range(10): + fut = asyncio.to_thread(func) + futs.append(fut) + await asyncio.gather(*futs) - self.loop.run_until_complete(main()) self.assertEqual(func.call_count, 10) - def test_to_thread_args_kwargs(self): + async def test_to_thread_args_kwargs(self): # Unlike run_in_executor(), to_thread() should directly accept kwargs. func = mock.Mock() - async def main(): - await asyncio.to_thread(func, 'test', something=True) + await asyncio.to_thread(func, 'test', something=True) - self.loop.run_until_complete(main()) func.assert_called_once_with('test', something=True) - def test_to_thread_contextvars(self): + async def test_to_thread_contextvars(self): test_ctx = ContextVar('test_ctx') def get_ctx(): return test_ctx.get() - async def main(): - test_ctx.set('parrot') - return await asyncio.to_thread(get_ctx) + test_ctx.set('parrot') + result = await asyncio.to_thread(get_ctx) - result = self.loop.run_until_complete(main()) self.assertEqual(result, 'parrot') diff --git a/Lib/test/test_asyncio/test_timeouts.py b/Lib/test/test_asyncio/test_timeouts.py new file mode 100644 index 00000000000..b9bac6f7837 --- /dev/null +++ b/Lib/test/test_asyncio/test_timeouts.py @@ -0,0 +1,252 @@ +"""Tests for asyncio/timeouts.py""" + +import unittest +import time + +import asyncio + + +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + +class TimeoutTests(unittest.IsolatedAsyncioTestCase): + + async def test_timeout_basic(self): + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.01) as cm: + await asyncio.sleep(10) + self.assertTrue(cm.expired()) + + async def test_timeout_at_basic(self): + loop = asyncio.get_running_loop() + + with self.assertRaises(TimeoutError): + deadline = loop.time() + 0.01 + async with asyncio.timeout_at(deadline) as cm: + await asyncio.sleep(10) + self.assertTrue(cm.expired()) + self.assertEqual(deadline, cm.when()) + + async def test_nested_timeouts(self): + loop = asyncio.get_running_loop() + cancelled = False + with self.assertRaises(TimeoutError): + deadline = loop.time() + 0.01 + async with asyncio.timeout_at(deadline) as cm1: + # Only the topmost context manager should raise TimeoutError + try: + async with asyncio.timeout_at(deadline) as cm2: + await asyncio.sleep(10) + except asyncio.CancelledError: + cancelled = True + raise + self.assertTrue(cancelled) + self.assertTrue(cm1.expired()) + self.assertTrue(cm2.expired()) + + async def test_waiter_cancelled(self): + loop = asyncio.get_running_loop() + cancelled = False + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.01): + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + cancelled = True + raise + self.assertTrue(cancelled) + + async def test_timeout_not_called(self): + loop = asyncio.get_running_loop() + t0 = loop.time() + async with asyncio.timeout(10) as cm: + await asyncio.sleep(0.01) + t1 = loop.time() + + self.assertFalse(cm.expired()) + # 2 sec for slow CI boxes + self.assertLess(t1-t0, 2) + self.assertGreater(cm.when(), t1) + + async def test_timeout_disabled(self): + loop = asyncio.get_running_loop() + t0 = loop.time() + async with asyncio.timeout(None) as cm: + await asyncio.sleep(0.01) + t1 = loop.time() + + self.assertFalse(cm.expired()) + self.assertIsNone(cm.when()) + # 2 sec for slow CI boxes + self.assertLess(t1-t0, 2) + + async def test_timeout_at_disabled(self): + loop = asyncio.get_running_loop() + t0 = loop.time() + async with asyncio.timeout_at(None) as cm: + await asyncio.sleep(0.01) + t1 = loop.time() + + self.assertFalse(cm.expired()) + self.assertIsNone(cm.when()) + # 2 sec for slow CI boxes + self.assertLess(t1-t0, 2) + + async def test_timeout_zero(self): + loop = asyncio.get_running_loop() + t0 = loop.time() + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0) as cm: + await asyncio.sleep(10) + t1 = loop.time() + self.assertTrue(cm.expired()) + # 2 sec for slow CI boxes + self.assertLess(t1-t0, 2) + self.assertTrue(t0 <= cm.when() <= t1) + + async def test_timeout_zero_sleep_zero(self): + loop = asyncio.get_running_loop() + t0 = loop.time() + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0) as cm: + await asyncio.sleep(0) + t1 = loop.time() + self.assertTrue(cm.expired()) + # 2 sec for slow CI boxes + self.assertLess(t1-t0, 2) + self.assertTrue(t0 <= cm.when() <= t1) + + async def test_timeout_in_the_past_sleep_zero(self): + loop = asyncio.get_running_loop() + t0 = loop.time() + with self.assertRaises(TimeoutError): + async with asyncio.timeout(-11) as cm: + await asyncio.sleep(0) + t1 = loop.time() + self.assertTrue(cm.expired()) + # 2 sec for slow CI boxes + self.assertLess(t1-t0, 2) + self.assertTrue(t0 >= cm.when() <= t1) + + async def test_foreign_exception_passed(self): + with self.assertRaises(KeyError): + async with asyncio.timeout(0.01) as cm: + raise KeyError + self.assertFalse(cm.expired()) + + async def test_foreign_exception_on_timeout(self): + async def crash(): + try: + await asyncio.sleep(1) + finally: + 1/0 + with self.assertRaises(ZeroDivisionError): + async with asyncio.timeout(0.01): + await crash() + + async def test_foreign_cancel_doesnt_timeout_if_not_expired(self): + with self.assertRaises(asyncio.CancelledError): + async with asyncio.timeout(10) as cm: + asyncio.current_task().cancel() + await asyncio.sleep(10) + self.assertFalse(cm.expired()) + + async def test_outer_task_is_not_cancelled(self): + async def outer() -> None: + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.001): + await asyncio.sleep(10) + + task = asyncio.create_task(outer()) + await task + self.assertFalse(task.cancelled()) + self.assertTrue(task.done()) + + async def test_nested_timeouts_concurrent(self): + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.002): + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.1): + # Pretend we crunch some numbers. + time.sleep(0.01) + await asyncio.sleep(1) + + async def test_nested_timeouts_loop_busy(self): + # After the inner timeout is an expensive operation which should + # be stopped by the outer timeout. + loop = asyncio.get_running_loop() + # Disable a message about long running task + loop.slow_callback_duration = 10 + t0 = loop.time() + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.1): # (1) + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.01): # (2) + # Pretend the loop is busy for a while. + time.sleep(0.1) + await asyncio.sleep(1) + # TimeoutError was cought by (2) + await asyncio.sleep(10) # This sleep should be interrupted by (1) + t1 = loop.time() + self.assertTrue(t0 <= t1 <= t0 + 1) + + async def test_reschedule(self): + loop = asyncio.get_running_loop() + fut = loop.create_future() + deadline1 = loop.time() + 10 + deadline2 = deadline1 + 20 + + async def f(): + async with asyncio.timeout_at(deadline1) as cm: + fut.set_result(cm) + await asyncio.sleep(50) + + task = asyncio.create_task(f()) + cm = await fut + + self.assertEqual(cm.when(), deadline1) + cm.reschedule(deadline2) + self.assertEqual(cm.when(), deadline2) + cm.reschedule(None) + self.assertIsNone(cm.when()) + + task.cancel() + + with self.assertRaises(asyncio.CancelledError): + await task + self.assertFalse(cm.expired()) + + async def test_repr_active(self): + async with asyncio.timeout(10) as cm: + self.assertRegex(repr(cm), r"") + + async def test_repr_expired(self): + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.01) as cm: + await asyncio.sleep(10) + self.assertEqual(repr(cm), "") + + async def test_repr_finished(self): + async with asyncio.timeout(10) as cm: + await asyncio.sleep(0) + + self.assertEqual(repr(cm), "") + + async def test_repr_disabled(self): + async with asyncio.timeout(None) as cm: + self.assertEqual(repr(cm), r"") + + async def test_nested_timeout_in_finally(self): + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.01): + try: + await asyncio.sleep(1) + finally: + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.01): + await asyncio.sleep(10) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_asyncio/test_transports.py b/Lib/test/test_asyncio/test_transports.py index df448557a7b..bbdb218efaa 100644 --- a/Lib/test/test_asyncio/test_transports.py +++ b/Lib/test/test_asyncio/test_transports.py @@ -7,6 +7,12 @@ import asyncio from asyncio import transports +def tearDownModule(): + # not needed for the test file but added for uniformness with all other + # asyncio test files for the sake of unified cleanup + asyncio.set_event_loop_policy(None) + + class TransportTests(unittest.TestCase): def test_ctor_extra_is_none(self): diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 643638564e3..33d0ea15c6d 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -3,18 +3,21 @@ import contextlib import errno import io +import multiprocessing import os import pathlib import signal import socket import stat import sys -import tempfile import threading import unittest from unittest import mock +import warnings from test.support import os_helper from test.support import socket_helper +from test.support import wait_process +from test.support import hashlib_helper if sys.platform == 'win32': raise unittest.SkipTest('UNIX only') @@ -26,6 +29,10 @@ from asyncio import unix_events from test.test_asyncio import utils as test_utils +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + MOCK_ANY = mock.ANY @@ -34,14 +41,11 @@ def EXITCODE(exitcode): def SIGNAL(signum): - assert 1 <= signum <= 68 + if not 1 <= signum <= 68: + raise AssertionError(f'invalid signum {signum}') return 32768 - signum -def tearDownModule(): - asyncio.set_event_loop_policy(None) - - def close_pipe_transport(transport): # Don't call transport.close() because the event loop and the selector # are mocked @@ -314,11 +318,15 @@ class SelectorEventLoopUnixSocketTests(test_utils.TestCase): self.loop.run_until_complete(coro) def test_create_unix_server_existing_path_nonsock(self): - with tempfile.NamedTemporaryFile() as file: - coro = self.loop.create_unix_server(lambda: None, file.name) - with self.assertRaisesRegex(OSError, - 'Address.*is already in use'): - self.loop.run_until_complete(coro) + path = test_utils.gen_unix_socket_path() + self.addCleanup(os_helper.unlink, path) + # create the file + open(path, "wb").close() + + coro = self.loop.create_unix_server(lambda: None, path) + with self.assertRaisesRegex(OSError, + 'Address.*is already in use'): + self.loop.run_until_complete(coro) def test_create_unix_server_ssl_bool(self): coro = self.loop.create_unix_server(lambda: None, path='spam', @@ -355,20 +363,18 @@ class SelectorEventLoopUnixSocketTests(test_utils.TestCase): 'no socket.SOCK_NONBLOCK (linux only)') @socket_helper.skip_unless_bind_unix_socket def test_create_unix_server_path_stream_bittype(self): - sock = socket.socket( - socket.AF_UNIX, socket.SOCK_STREAM | socket.SOCK_NONBLOCK) - with tempfile.NamedTemporaryFile() as file: - fn = file.name - try: - with sock: - sock.bind(fn) - coro = self.loop.create_unix_server(lambda: None, path=None, - sock=sock) - srv = self.loop.run_until_complete(coro) - srv.close() - self.loop.run_until_complete(srv.wait_closed()) - finally: - os.unlink(fn) + fn = test_utils.gen_unix_socket_path() + self.addCleanup(os_helper.unlink, fn) + + sock = socket.socket(socket.AF_UNIX, + socket.SOCK_STREAM | socket.SOCK_NONBLOCK) + with sock: + sock.bind(fn) + coro = self.loop.create_unix_server(lambda: None, path=None, + sock=sock) + srv = self.loop.run_until_complete(coro) + srv.close() + self.loop.run_until_complete(srv.wait_closed()) def test_create_unix_server_ssl_timeout_with_plain_sock(self): coro = self.loop.create_unix_server(lambda: None, path='spam', @@ -1105,6 +1111,11 @@ class UnixWritePipeTransportTests(test_utils.TestCase): class AbstractChildWatcherTests(unittest.TestCase): + def test_warns_on_subclassing(self): + with self.assertWarns(DeprecationWarning): + class MyWatcher(asyncio.AbstractChildWatcher): + pass + def test_not_implemented(self): f = mock.Mock() watcher = asyncio.AbstractChildWatcher() @@ -1529,7 +1540,7 @@ class ChildWatcherTestsMixin: self.watcher._sig_chld() if isinstance(self.watcher, asyncio.FastChildWatcher): - # here the FastChildWatche enters a deadlock + # here the FastChildWatcher enters a deadlock # (there is no way to prevent it) self.assertFalse(callback.called) else: @@ -1684,12 +1695,16 @@ class ChildWatcherTestsMixin: class SafeChildWatcherTests (ChildWatcherTestsMixin, test_utils.TestCase): def create_watcher(self): - return asyncio.SafeChildWatcher() + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + return asyncio.SafeChildWatcher() class FastChildWatcherTests (ChildWatcherTestsMixin, test_utils.TestCase): def create_watcher(self): - return asyncio.FastChildWatcher() + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + return asyncio.FastChildWatcher() class PolicyTests(unittest.TestCase): @@ -1700,21 +1715,38 @@ class PolicyTests(unittest.TestCase): def test_get_default_child_watcher(self): policy = self.create_policy() self.assertIsNone(policy._watcher) - - watcher = policy.get_child_watcher() + unix_events.can_use_pidfd = mock.Mock() + unix_events.can_use_pidfd.return_value = False + with self.assertWarns(DeprecationWarning): + watcher = policy.get_child_watcher() self.assertIsInstance(watcher, asyncio.ThreadedChildWatcher) self.assertIs(policy._watcher, watcher) + with self.assertWarns(DeprecationWarning): + self.assertIs(watcher, policy.get_child_watcher()) - self.assertIs(watcher, policy.get_child_watcher()) + policy = self.create_policy() + self.assertIsNone(policy._watcher) + unix_events.can_use_pidfd = mock.Mock() + unix_events.can_use_pidfd.return_value = True + with self.assertWarns(DeprecationWarning): + watcher = policy.get_child_watcher() + self.assertIsInstance(watcher, asyncio.PidfdChildWatcher) + + self.assertIs(policy._watcher, watcher) + with self.assertWarns(DeprecationWarning): + self.assertIs(watcher, policy.get_child_watcher()) def test_get_child_watcher_after_set(self): policy = self.create_policy() - watcher = asyncio.FastChildWatcher() + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + watcher = asyncio.FastChildWatcher() + policy.set_child_watcher(watcher) - policy.set_child_watcher(watcher) self.assertIs(policy._watcher, watcher) - self.assertIs(watcher, policy.get_child_watcher()) + with self.assertWarns(DeprecationWarning): + self.assertIs(watcher, policy.get_child_watcher()) def test_get_child_watcher_thread(self): @@ -1723,7 +1755,9 @@ class PolicyTests(unittest.TestCase): self.assertIsInstance(policy.get_event_loop(), asyncio.AbstractEventLoop) - watcher = policy.get_child_watcher() + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + watcher = policy.get_child_watcher() self.assertIsInstance(watcher, asyncio.SafeChildWatcher) self.assertIsNone(watcher._loop) @@ -1731,7 +1765,9 @@ class PolicyTests(unittest.TestCase): policy.get_event_loop().close() policy = self.create_policy() - policy.set_child_watcher(asyncio.SafeChildWatcher()) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + policy.set_child_watcher(asyncio.SafeChildWatcher()) th = threading.Thread(target=f) th.start() @@ -1739,12 +1775,15 @@ class PolicyTests(unittest.TestCase): def test_child_watcher_replace_mainloop_existing(self): policy = self.create_policy() - loop = policy.get_event_loop() + loop = policy.new_event_loop() + policy.set_event_loop(loop) # Explicitly setup SafeChildWatcher, # default ThreadedChildWatcher has no _loop property - watcher = asyncio.SafeChildWatcher() - policy.set_child_watcher(watcher) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + watcher = asyncio.SafeChildWatcher() + policy.set_child_watcher(watcher) watcher.attach_loop(loop) self.assertIs(watcher._loop, loop) @@ -1832,5 +1871,105 @@ class TestFunctional(unittest.TestCase): wsock.close() +@unittest.skipUnless(hasattr(os, 'fork'), 'requires os.fork()') +class TestFork(unittest.IsolatedAsyncioTestCase): + + async def test_fork_not_share_event_loop(self): + # The forked process should not share the event loop with the parent + loop = asyncio.get_running_loop() + r, w = os.pipe() + self.addCleanup(os.close, r) + self.addCleanup(os.close, w) + pid = os.fork() + if pid == 0: + # child + try: + with self.assertWarns(DeprecationWarning): + loop = asyncio.get_event_loop_policy().get_event_loop() + os.write(w, b'LOOP:' + str(id(loop)).encode()) + except RuntimeError: + os.write(w, b'NO LOOP') + except: + os.write(w, b'ERROR:' + ascii(sys.exc_info()).encode()) + finally: + os._exit(0) + else: + # parent + result = os.read(r, 100) + self.assertEqual(result[:5], b'LOOP:', result) + self.assertNotEqual(int(result[5:]), id(loop)) + wait_process(pid, exitcode=0) + + @hashlib_helper.requires_hashdigest('md5') + def test_fork_signal_handling(self): + # Sending signal to the forked process should not affect the parent + # process + ctx = multiprocessing.get_context('fork') + manager = ctx.Manager() + self.addCleanup(manager.shutdown) + child_started = manager.Event() + child_handled = manager.Event() + parent_handled = manager.Event() + + def child_main(): + signal.signal(signal.SIGTERM, lambda *args: child_handled.set()) + child_started.set() + + async def main(): + loop = asyncio.get_running_loop() + loop.add_signal_handler(signal.SIGTERM, lambda *args: parent_handled.set()) + + process = ctx.Process(target=child_main) + process.start() + child_started.wait() + os.kill(process.pid, signal.SIGTERM) + process.join() + + async def func(): + await asyncio.sleep(0.1) + return 42 + + # Test parent's loop is still functional + self.assertEqual(await asyncio.create_task(func()), 42) + + asyncio.run(main()) + + self.assertFalse(parent_handled.is_set()) + self.assertTrue(child_handled.is_set()) + + @hashlib_helper.requires_hashdigest('md5') + def test_fork_asyncio_run(self): + ctx = multiprocessing.get_context('fork') + manager = ctx.Manager() + self.addCleanup(manager.shutdown) + result = manager.Value('i', 0) + + async def child_main(): + await asyncio.sleep(0.1) + result.value = 42 + + process = ctx.Process(target=lambda: asyncio.run(child_main())) + process.start() + process.join() + + self.assertEqual(result.value, 42) + + @hashlib_helper.requires_hashdigest('md5') + def test_fork_asyncio_subprocess(self): + ctx = multiprocessing.get_context('fork') + manager = ctx.Manager() + self.addCleanup(manager.shutdown) + result = manager.Value('i', 1) + + async def child_main(): + proc = await asyncio.create_subprocess_exec(sys.executable, '-c', 'pass') + result.value = await proc.wait() + + process = ctx.Process(target=lambda: asyncio.run(child_main())) + process.start() + process.join() + + self.assertEqual(result.value, 0) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_waitfor.py b/Lib/test/test_asyncio/test_waitfor.py new file mode 100644 index 00000000000..45498fa097f --- /dev/null +++ b/Lib/test/test_asyncio/test_waitfor.py @@ -0,0 +1,294 @@ +import asyncio +import unittest +import time + + +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + +# The following value can be used as a very small timeout: +# it passes check "timeout > 0", but has almost +# no effect on the test performance +_EPSILON = 0.0001 + + +class SlowTask: + """ Task will run for this defined time, ignoring cancel requests """ + TASK_TIMEOUT = 0.2 + + def __init__(self): + self.exited = False + + async def run(self): + exitat = time.monotonic() + self.TASK_TIMEOUT + + while True: + tosleep = exitat - time.monotonic() + if tosleep <= 0: + break + + try: + await asyncio.sleep(tosleep) + except asyncio.CancelledError: + pass + + self.exited = True + + +class AsyncioWaitForTest(unittest.IsolatedAsyncioTestCase): + + async def test_asyncio_wait_for_cancelled(self): + t = SlowTask() + + waitfortask = asyncio.create_task( + asyncio.wait_for(t.run(), t.TASK_TIMEOUT * 2)) + await asyncio.sleep(0) + waitfortask.cancel() + await asyncio.wait({waitfortask}) + + self.assertTrue(t.exited) + + async def test_asyncio_wait_for_timeout(self): + t = SlowTask() + + try: + await asyncio.wait_for(t.run(), t.TASK_TIMEOUT / 2) + except asyncio.TimeoutError: + pass + + self.assertTrue(t.exited) + + async def test_wait_for_timeout_less_then_0_or_0_future_done(self): + loop = asyncio.get_running_loop() + + fut = loop.create_future() + fut.set_result('done') + + t0 = loop.time() + ret = await asyncio.wait_for(fut, 0) + t1 = loop.time() + + self.assertEqual(ret, 'done') + self.assertTrue(fut.done()) + self.assertLess(t1 - t0, 0.1) + + async def test_wait_for_timeout_less_then_0_or_0_coroutine_do_not_started(self): + loop = asyncio.get_running_loop() + + foo_started = False + + async def foo(): + nonlocal foo_started + foo_started = True + + with self.assertRaises(asyncio.TimeoutError): + t0 = loop.time() + await asyncio.wait_for(foo(), 0) + t1 = loop.time() + + self.assertEqual(foo_started, False) + self.assertLess(t1 - t0, 0.1) + + async def test_wait_for_timeout_less_then_0_or_0(self): + loop = asyncio.get_running_loop() + + for timeout in [0, -1]: + with self.subTest(timeout=timeout): + foo_running = None + started = loop.create_future() + + async def foo(): + nonlocal foo_running + foo_running = True + started.set_result(None) + try: + await asyncio.sleep(10) + finally: + foo_running = False + return 'done' + + fut = asyncio.create_task(foo()) + await started + + with self.assertRaises(asyncio.TimeoutError): + t0 = loop.time() + await asyncio.wait_for(fut, timeout) + t1 = loop.time() + + self.assertTrue(fut.done()) + # it should have been cancelled due to the timeout + self.assertTrue(fut.cancelled()) + self.assertEqual(foo_running, False) + self.assertLess(t1 - t0, 0.1) + + async def test_wait_for(self): + loop = asyncio.get_running_loop() + foo_running = None + + async def foo(): + nonlocal foo_running + foo_running = True + try: + await asyncio.sleep(10) + finally: + foo_running = False + return 'done' + + fut = asyncio.create_task(foo()) + + with self.assertRaises(asyncio.TimeoutError): + t0 = loop.time() + await asyncio.wait_for(fut, 0.1) + t1 = loop.time() + self.assertTrue(fut.done()) + # it should have been cancelled due to the timeout + self.assertTrue(fut.cancelled()) + self.assertLess(t1 - t0, 0.5) + self.assertEqual(foo_running, False) + + async def test_wait_for_blocking(self): + async def coro(): + return 'done' + + res = await asyncio.wait_for(coro(), timeout=None) + self.assertEqual(res, 'done') + + async def test_wait_for_race_condition(self): + loop = asyncio.get_running_loop() + + fut = loop.create_future() + task = asyncio.wait_for(fut, timeout=0.2) + loop.call_later(0.1, fut.set_result, "ok") + res = await task + self.assertEqual(res, "ok") + + async def test_wait_for_cancellation_race_condition(self): + async def inner(): + with self.assertRaises(asyncio.CancelledError): + await asyncio.sleep(1) + return 1 + + result = await asyncio.wait_for(inner(), timeout=.01) + self.assertEqual(result, 1) + + async def test_wait_for_waits_for_task_cancellation(self): + task_done = False + + async def inner(): + nonlocal task_done + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + await asyncio.sleep(_EPSILON) + raise + finally: + task_done = True + + inner_task = asyncio.create_task(inner()) + + with self.assertRaises(asyncio.TimeoutError) as cm: + await asyncio.wait_for(inner_task, timeout=_EPSILON) + + self.assertTrue(task_done) + chained = cm.exception.__context__ + self.assertEqual(type(chained), asyncio.CancelledError) + + async def test_wait_for_waits_for_task_cancellation_w_timeout_0(self): + task_done = False + + async def foo(): + async def inner(): + nonlocal task_done + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + await asyncio.sleep(_EPSILON) + raise + finally: + task_done = True + + inner_task = asyncio.create_task(inner()) + await asyncio.sleep(_EPSILON) + await asyncio.wait_for(inner_task, timeout=0) + + with self.assertRaises(asyncio.TimeoutError) as cm: + await foo() + + self.assertTrue(task_done) + chained = cm.exception.__context__ + self.assertEqual(type(chained), asyncio.CancelledError) + + async def test_wait_for_reraises_exception_during_cancellation(self): + class FooException(Exception): + pass + + async def foo(): + async def inner(): + try: + await asyncio.sleep(0.2) + finally: + raise FooException + + inner_task = asyncio.create_task(inner()) + + await asyncio.wait_for(inner_task, timeout=_EPSILON) + + with self.assertRaises(FooException): + await foo() + + async def test_wait_for_self_cancellation(self): + async def inner(): + try: + await asyncio.sleep(0.3) + except asyncio.CancelledError: + try: + await asyncio.sleep(0.3) + except asyncio.CancelledError: + await asyncio.sleep(0.3) + + return 42 + + inner_task = asyncio.create_task(inner()) + + wait = asyncio.wait_for(inner_task, timeout=0.1) + + # Test that wait_for itself is properly cancellable + # even when the initial task holds up the initial cancellation. + task = asyncio.create_task(wait) + await asyncio.sleep(0.2) + task.cancel() + + with self.assertRaises(asyncio.CancelledError): + await task + + self.assertEqual(await inner_task, 42) + + async def _test_cancel_wait_for(self, timeout): + loop = asyncio.get_running_loop() + + async def blocking_coroutine(): + fut = loop.create_future() + # Block: fut result is never set + await fut + + task = asyncio.create_task(blocking_coroutine()) + + wait = asyncio.create_task(asyncio.wait_for(task, timeout)) + loop.call_soon(wait.cancel) + + with self.assertRaises(asyncio.CancelledError): + await wait + + # Python issue #23219: cancelling the wait must also cancel the task + self.assertTrue(task.cancelled()) + + async def test_cancel_blocking_wait_for(self): + await self._test_cancel_wait_for(None) + + async def test_cancel_wait_for(self): + await self._test_cancel_wait_for(60.0) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_asyncio/test_windows_events.py b/Lib/test/test_asyncio/test_windows_events.py index f276cd205a2..a36119a8004 100644 --- a/Lib/test/test_asyncio/test_windows_events.py +++ b/Lib/test/test_asyncio/test_windows_events.py @@ -45,7 +45,7 @@ class ProactorLoopCtrlC(test_utils.TestCase): signal.raise_signal(signal.SIGINT) thread = threading.Thread(target=SIGINT_after_delay) - loop = asyncio.get_event_loop() + loop = asyncio.new_event_loop() try: # only start the loop once the event loop is running loop.call_soon(thread.start) @@ -239,6 +239,57 @@ class ProactorTests(test_utils.TestCase): self.close_loop(self.loop) self.assertFalse(self.loop.call_exception_handler.called) + def test_address_argument_type_error(self): + # Regression test for https://github.com/python/cpython/issues/98793 + proactor = self.loop._proactor + sock = socket.socket(type=socket.SOCK_DGRAM) + bad_address = None + with self.assertRaises(TypeError): + proactor.connect(sock, bad_address) + with self.assertRaises(TypeError): + proactor.sendto(sock, b'abc', addr=bad_address) + sock.close() + + def test_client_pipe_stat(self): + res = self.loop.run_until_complete(self._test_client_pipe_stat()) + self.assertEqual(res, 'done') + + async def _test_client_pipe_stat(self): + # Regression test for https://github.com/python/cpython/issues/100573 + ADDRESS = r'\\.\pipe\test_client_pipe_stat-%s' % os.getpid() + + async def probe(): + # See https://github.com/python/cpython/pull/100959#discussion_r1068533658 + h = _overlapped.ConnectPipe(ADDRESS) + try: + _winapi.CloseHandle(_overlapped.ConnectPipe(ADDRESS)) + except OSError as e: + if e.winerror != _overlapped.ERROR_PIPE_BUSY: + raise + finally: + _winapi.CloseHandle(h) + + with self.assertRaises(FileNotFoundError): + await probe() + + [server] = await self.loop.start_serving_pipe(asyncio.Protocol, ADDRESS) + self.assertIsInstance(server, windows_events.PipeServer) + + errors = [] + self.loop.set_exception_handler(lambda _, data: errors.append(data)) + + for i in range(5): + await self.loop.create_task(probe()) + + self.assertEqual(len(errors), 0, errors) + + server.close() + + with self.assertRaises(FileNotFoundError): + await probe() + + return "done" + class WinPolicyTests(test_utils.TestCase): diff --git a/Lib/test/test_asyncio/utils.py b/Lib/test/test_asyncio/utils.py index 3765194cd0d..5b9c86eb985 100644 --- a/Lib/test/test_asyncio/utils.py +++ b/Lib/test/test_asyncio/utils.py @@ -11,12 +11,10 @@ import selectors import socket import socketserver import sys -import tempfile import threading -import time import unittest import weakref - +import warnings from unittest import mock from http.server import HTTPServer @@ -34,6 +32,7 @@ from asyncio import futures from asyncio import tasks from asyncio.log import logger from test import support +from test.support import socket_helper from test.support import threading_helper @@ -109,13 +108,14 @@ def run_briefly(loop): def run_until(loop, pred, timeout=support.SHORT_TIMEOUT): - deadline = time.monotonic() + timeout - while not pred(): - if timeout is not None: - timeout = deadline - time.monotonic() - if timeout <= 0: - raise futures.TimeoutError() - loop.run_until_complete(tasks.sleep(0.001)) + delay = 0.001 + for _ in support.busy_retry(timeout, error=False): + if pred(): + break + loop.run_until_complete(tasks.sleep(delay)) + delay = max(delay * 2, 1.0) + else: + raise futures.TimeoutError() def run_once(loop): @@ -250,8 +250,7 @@ if hasattr(socket, 'AF_UNIX'): def gen_unix_socket_path(): - with tempfile.NamedTemporaryFile() as file: - return file.name + return socket_helper.create_unix_domain_name() @contextlib.contextmanager @@ -281,6 +280,31 @@ def run_test_server(*, host='127.0.0.1', port=0, use_ssl=False): server_ssl_cls=SSLWSGIServer) +def echo_datagrams(sock): + while True: + data, addr = sock.recvfrom(4096) + if data == b'STOP': + sock.close() + break + else: + sock.sendto(data, addr) + + +@contextlib.contextmanager +def run_udp_echo_server(*, host='127.0.0.1', port=0): + addr_info = socket.getaddrinfo(host, port, type=socket.SOCK_DGRAM) + family, type, proto, _, sockaddr = addr_info[0] + sock = socket.socket(family, type, proto) + sock.bind((host, port)) + thread = threading.Thread(target=lambda: echo_datagrams(sock)) + thread.start() + try: + yield sock.getsockname() + finally: + sock.sendto(b'STOP', sock.getsockname()) + thread.join() + + def make_test_protocol(base): dct = {} for name in dir(base): @@ -409,12 +433,13 @@ class TestLoop(base_events.BaseEventLoop): return False def assert_writer(self, fd, callback, *args): - assert fd in self.writers, 'fd {} is not registered'.format(fd) + if fd not in self.writers: + raise AssertionError(f'fd {fd} is not registered') handle = self.writers[fd] - assert handle._callback == callback, '{!r} != {!r}'.format( - handle._callback, callback) - assert handle._args == args, '{!r} != {!r}'.format( - handle._args, args) + if handle._callback != callback: + raise AssertionError(f'{handle._callback!r} != {callback!r}') + if handle._args != args: + raise AssertionError(f'{handle._args!r} != {args!r}') def _ensure_fd_no_transport(self, fd): if not isinstance(fd, int): @@ -519,7 +544,9 @@ class TestCase(unittest.TestCase): policy = support.maybe_get_event_loop_policy() if policy is not None: try: - watcher = policy.get_child_watcher() + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + watcher = policy.get_child_watcher() except NotImplementedError: # watcher is not implemented by EventLoopPolicy, e.g. Windows pass @@ -530,7 +557,8 @@ class TestCase(unittest.TestCase): thread.join() def set_event_loop(self, loop, *, cleanup=True): - assert loop is not None + if loop is None: + raise AssertionError('loop is None') # ensure that the event loop is passed explicitly in asyncio events.set_event_loop(None) if cleanup: diff --git a/Lib/test/test_atexit.py b/Lib/test/test_atexit.py index e0feef7c653..913b7556be8 100644 --- a/Lib/test/test_atexit.py +++ b/Lib/test/test_atexit.py @@ -1,6 +1,5 @@ import atexit import os -import sys import textwrap import unittest from test import support @@ -82,6 +81,7 @@ class SubinterpreterTest(unittest.TestCase): self.assertEqual(ret, 0) self.assertEqual(atexit._ncallbacks(), n) + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_callback_on_subinterpreter_teardown(self): # This tests if a callback is called on # subinterpreter teardown. diff --git a/Lib/test/test_audioop.py b/Lib/test/test_audioop.py index 9baa62ad45c..05c0f20e122 100644 --- a/Lib/test/test_audioop.py +++ b/Lib/test/test_audioop.py @@ -1,7 +1,10 @@ -import audioop import sys +from test.support import warnings_helper import unittest +audioop = warnings_helper.import_deprecated("audioop") + + def pack(width, data): return b''.join(v.to_bytes(width, sys.byteorder, signed=True) for v in data) diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py index d99b3b7ed7d..0b69864751d 100644 --- a/Lib/test/test_audit.py +++ b/Lib/test/test_audit.py @@ -16,9 +16,12 @@ AUDIT_TESTS_PY = support.findfile("audit-tests.py") class AuditTest(unittest.TestCase): + maxDiff = None + + @support.requires_subprocess() def do_test(self, *args): with subprocess.Popen( - [sys.executable, "-Xutf8", AUDIT_TESTS_PY, *args], + [sys.executable, "-X utf8", AUDIT_TESTS_PY, *args], encoding="utf-8", stdout=subprocess.PIPE, stderr=subprocess.PIPE, @@ -29,10 +32,11 @@ class AuditTest(unittest.TestCase): if p.returncode: self.fail("".join(p.stderr)) + @support.requires_subprocess() def run_python(self, *args): events = [] with subprocess.Popen( - [sys.executable, "-Xutf8", AUDIT_TESTS_PY, *args], + [sys.executable, "-X utf8", AUDIT_TESTS_PY, *args], encoding="utf-8", stdout=subprocess.PIPE, stderr=subprocess.PIPE, @@ -152,10 +156,7 @@ class AuditTest(unittest.TestCase): def test_sqlite3(self): - try: - import sqlite3 - except ImportError: - return + sqlite3 = import_helper.import_module("sqlite3") returncode, events, stderr = self.run_python("test_sqlite3") if returncode: self.fail(stderr) @@ -173,5 +174,88 @@ class AuditTest(unittest.TestCase): self.assertEqual(actual, expected) + def test_sys_getframe(self): + returncode, events, stderr = self.run_python("test_sys_getframe") + if returncode: + self.fail(stderr) + + if support.verbose: + print(*events, sep='\n') + actual = [(ev[0], ev[2]) for ev in events] + expected = [("sys._getframe", "test_sys_getframe")] + + self.assertEqual(actual, expected) + + def test_sys_getframemodulename(self): + returncode, events, stderr = self.run_python("test_sys_getframemodulename") + if returncode: + self.fail(stderr) + + if support.verbose: + print(*events, sep='\n') + actual = [(ev[0], ev[2]) for ev in events] + expected = [("sys._getframemodulename", "0")] + + self.assertEqual(actual, expected) + + + def test_threading(self): + returncode, events, stderr = self.run_python("test_threading") + if returncode: + self.fail(stderr) + + if support.verbose: + print(*events, sep='\n') + actual = [(ev[0], ev[2]) for ev in events] + expected = [ + ("_thread.start_new_thread", "(, (), None)"), + ("test.test_func", "()"), + ] + + self.assertEqual(actual, expected) + + + def test_wmi_exec_query(self): + import_helper.import_module("_wmi") + returncode, events, stderr = self.run_python("test_wmi_exec_query") + if returncode: + self.fail(stderr) + + if support.verbose: + print(*events, sep='\n') + actual = [(ev[0], ev[2]) for ev in events] + expected = [("_wmi.exec_query", "SELECT * FROM Win32_OperatingSystem")] + + self.assertEqual(actual, expected) + + def test_syslog(self): + syslog = import_helper.import_module("syslog") + + returncode, events, stderr = self.run_python("test_syslog") + if returncode: + self.fail(stderr) + + if support.verbose: + print('Events:', *events, sep='\n ') + + self.assertSequenceEqual( + events, + [('syslog.openlog', ' ', f'python 0 {syslog.LOG_USER}'), + ('syslog.syslog', ' ', f'{syslog.LOG_INFO} test'), + ('syslog.setlogmask', ' ', f'{syslog.LOG_DEBUG}'), + ('syslog.closelog', '', ''), + ('syslog.syslog', ' ', f'{syslog.LOG_INFO} test2'), + ('syslog.openlog', ' ', f'audit-tests.py 0 {syslog.LOG_USER}'), + ('syslog.openlog', ' ', f'audit-tests.py {syslog.LOG_NDELAY} {syslog.LOG_LOCAL0}'), + ('syslog.openlog', ' ', f'None 0 {syslog.LOG_USER}'), + ('syslog.closelog', '', '')] + ) + + def test_not_in_gc(self): + returncode, _, stderr = self.run_python("test_not_in_gc") + if returncode: + self.fail(stderr) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_base64.py b/Lib/test/test_base64.py index 217f2945468..fa03fa1d61c 100644 --- a/Lib/test/test_base64.py +++ b/Lib/test/test_base64.py @@ -31,6 +31,8 @@ class LegacyBase64TestCase(unittest.TestCase): b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT" b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n") + eq(base64.encodebytes(b"Aladdin:open sesame"), + b"QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n") # Non-bytes eq(base64.encodebytes(bytearray(b'abc')), b'YWJj\n') eq(base64.encodebytes(memoryview(b'abc')), b'YWJj\n') @@ -50,6 +52,8 @@ class LegacyBase64TestCase(unittest.TestCase): b"ABCDEFGHIJKLMNOPQRSTUVWXYZ" b"0123456789!@#0^&*();:<>,. []{}") eq(base64.decodebytes(b''), b'') + eq(base64.decodebytes(b"QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n"), + b"Aladdin:open sesame") # Non-bytes eq(base64.decodebytes(bytearray(b'YWJj\n')), b'abc') eq(base64.decodebytes(memoryview(b'YWJj\n')), b'abc') @@ -762,14 +766,6 @@ class TestMain(unittest.TestCase): def get_output(self, *args): return script_helper.assert_python_ok('-m', 'base64', *args).out - def test_encode_decode(self): - output = self.get_output('-t') - self.assertSequenceEqual(output.splitlines(), ( - b"b'Aladdin:open sesame'", - br"b'QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n'", - b"b'Aladdin:open sesame'", - )) - def test_encode_file(self): with open(os_helper.TESTFN, 'wb') as fp: fp.write(b'a\xffb\n') diff --git a/Lib/test/test_baseexception.py b/Lib/test/test_baseexception.py index 0061b3fa8e6..4c3cf0b964a 100644 --- a/Lib/test/test_baseexception.py +++ b/Lib/test/test_baseexception.py @@ -114,6 +114,31 @@ class ExceptionClassTests(unittest.TestCase): [repr(exc), exc.__class__.__name__ + '()']) self.interface_test_driver(results) + def test_setstate_refcount_no_crash(self): + # gh-97591: Acquire strong reference before calling tp_hash slot + # in PyObject_SetAttr. + import gc + d = {} + class HashThisKeyWillClearTheDict(str): + def __hash__(self) -> int: + d.clear() + return super().__hash__() + class Value(str): + pass + exc = Exception() + + d[HashThisKeyWillClearTheDict()] = Value() # refcount of Value() is 1 now + + # Exception.__setstate__ should aquire a strong reference of key and + # value in the dict. Otherwise, Value()'s refcount would go below + # zero in the tp_hash call in PyObject_SetAttr(), and it would cause + # crash in GC. + exc.__setstate__(d) # __hash__() is called again here, clearing the dict. + + # This GC would crash if the refcount of Value() goes below zero. + gc.collect() + + class UsageTests(unittest.TestCase): """Test usage of exceptions""" diff --git a/Lib/test/test_bdb.py b/Lib/test/test_bdb.py index 6ec59531fa8..87a5ac308a1 100644 --- a/Lib/test/test_bdb.py +++ b/Lib/test/test_bdb.py @@ -59,6 +59,7 @@ from contextlib import contextmanager from itertools import islice, repeat from test.support import import_helper from test.support import os_helper +from test.support import patch_list class BdbException(Exception): pass @@ -713,9 +714,18 @@ class StateTestCase(BaseTestCase): with TracerRun(self) as tracer: tracer.runcall(tfunc_main) + @patch_list(sys.meta_path) def test_skip(self): # Check that tracing is skipped over the import statement in # 'tfunc_import()'. + + # Remove all but the standard importers. + sys.meta_path[:] = ( + item + for item in sys.meta_path + if item.__module__.startswith('_frozen_importlib') + ) + code = """ def main(): lno = 3 diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index b5aa847b943..a2d7d0293ce 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -4,7 +4,7 @@ import unittest import binascii import array import re -from test.support import warnings_helper +from test.support import bigmemtest, _1G, _4G # Note: "*_hex" functions are aliases for "(un)hexlify" @@ -441,6 +441,14 @@ class BytearrayBinASCIITest(BinASCIITest): class MemoryviewBinASCIITest(BinASCIITest): type2test = memoryview +class ChecksumBigBufferTestCase(unittest.TestCase): + """bpo-38256 - check that inputs >=4 GiB are handled correctly.""" + + @bigmemtest(size=_4G + 4, memuse=1, dry_run=False) + def test_big_buffer(self, size): + data = b"nyan" * (_1G + 1) + self.assertEqual(binascii.crc32(data), 1044521549) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_bisect.py b/Lib/test/test_bisect.py index 20f8b9d7c0a..97204d4cad3 100644 --- a/Lib/test/test_bisect.py +++ b/Lib/test/test_bisect.py @@ -257,6 +257,40 @@ class TestBisect: target ) + def test_insort_keynotNone(self): + x = [] + y = {"a": 2, "b": 1} + for f in (self.module.insort_left, self.module.insort_right): + self.assertRaises(TypeError, f, x, y, key = "b") + + def test_lt_returns_non_bool(self): + class A: + def __init__(self, val): + self.val = val + def __lt__(self, other): + return "nonempty" if self.val < other.val else "" + + data = [A(i) for i in range(100)] + i1 = self.module.bisect_left(data, A(33)) + i2 = self.module.bisect_right(data, A(33)) + self.assertEqual(i1, 33) + self.assertEqual(i2, 34) + + def test_lt_returns_notimplemented(self): + class A: + def __init__(self, val): + self.val = val + def __lt__(self, other): + return NotImplemented + def __gt__(self, other): + return self.val > other.val + + data = [A(i) for i in range(100)] + i1 = self.module.bisect_left(data, A(40)) + i2 = self.module.bisect_right(data, A(40)) + self.assertEqual(i1, 40) + self.assertEqual(i2, 41) + class TestBisectPython(TestBisect, unittest.TestCase): module = py_bisect diff --git a/Lib/test/test_bool.py b/Lib/test/test_bool.py index 4b32aad2419..f46f21da8da 100644 --- a/Lib/test/test_bool.py +++ b/Lib/test/test_bool.py @@ -369,6 +369,13 @@ class BoolTest(unittest.TestCase): f(x) self.assertGreaterEqual(x.count, 1) + def test_bool_new(self): + self.assertIs(bool.__new__(bool), False) + self.assertIs(bool.__new__(bool, 1), True) + self.assertIs(bool.__new__(bool, 0), False) + self.assertIs(bool.__new__(bool, False), False) + self.assertIs(bool.__new__(bool, True), True) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index 468c6ea9def..8ac3b7e7eb2 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -64,7 +64,7 @@ NATIVE = { '?':0, 'c':0, 'b':0, 'B':0, 'h':0, 'H':0, 'i':0, 'I':0, 'l':0, 'L':0, 'n':0, 'N':0, - 'f':0, 'd':0, 'P':0 + 'e':0, 'f':0, 'd':0, 'P':0 } # NumPy does not have 'n' or 'N': @@ -89,7 +89,8 @@ STANDARD = { 'i':(-(1<<31), 1<<31), 'I':(0, 1<<32), 'l':(-(1<<31), 1<<31), 'L':(0, 1<<32), 'q':(-(1<<63), 1<<63), 'Q':(0, 1<<64), - 'f':(-(1<<63), 1<<63), 'd':(-(1<<1023), 1<<1023) + 'e':(-65519, 65520), 'f':(-(1<<63), 1<<63), + 'd':(-(1<<1023), 1<<1023) } def native_type_range(fmt): @@ -98,6 +99,8 @@ def native_type_range(fmt): lh = (0, 256) elif fmt == '?': lh = (0, 2) + elif fmt == 'e': + lh = (-65519, 65520) elif fmt == 'f': lh = (-(1<<63), 1<<63) elif fmt == 'd': @@ -125,7 +128,10 @@ if struct: for fmt in fmtdict['@']: fmtdict['@'][fmt] = native_type_range(fmt) +# Format codes suppported by the memoryview object MEMORYVIEW = NATIVE.copy() + +# Format codes suppported by array.array ARRAY = NATIVE.copy() for k in NATIVE: if not k in "bBhHiIlLfd": @@ -164,7 +170,7 @@ def randrange_fmt(mode, char, obj): x = b'\x01' if char == '?': x = bool(x) - if char == 'f' or char == 'd': + if char in 'efd': x = struct.pack(char, x) x = struct.unpack(char, x)[0] return x @@ -2246,7 +2252,7 @@ class TestBufferProtocol(unittest.TestCase): ### ### Fortran output: ### --------------- - ### >>> fortran_buf = nd.tostring(order='F') + ### >>> fortran_buf = nd.tobytes(order='F') ### >>> fortran_buf ### b'\x00\x04\x08\x01\x05\t\x02\x06\n\x03\x07\x0b' ### @@ -2289,7 +2295,7 @@ class TestBufferProtocol(unittest.TestCase): self.assertEqual(memoryview(y), memoryview(nd)) if numpy_array: - self.assertEqual(b, na.tostring(order='C')) + self.assertEqual(b, na.tobytes(order='C')) # 'F' request if f == 0: # 'C' to 'F' @@ -2312,7 +2318,7 @@ class TestBufferProtocol(unittest.TestCase): self.assertEqual(memoryview(y), memoryview(nd)) if numpy_array: - self.assertEqual(b, na.tostring(order='F')) + self.assertEqual(b, na.tobytes(order='F')) # 'A' request if f == ND_FORTRAN: @@ -2336,7 +2342,7 @@ class TestBufferProtocol(unittest.TestCase): self.assertEqual(memoryview(y), memoryview(nd)) if numpy_array: - self.assertEqual(b, na.tostring(order='A')) + self.assertEqual(b, na.tobytes(order='A')) # multi-dimensional, non-contiguous input nd = ndarray(list(range(12)), shape=[3, 4], flags=ND_WRITABLE|ND_PIL) diff --git a/Lib/test/test_bufio.py b/Lib/test/test_bufio.py index 17151b13615..dc9a82dc635 100644 --- a/Lib/test/test_bufio.py +++ b/Lib/test/test_bufio.py @@ -1,5 +1,4 @@ import unittest -from test import support from test.support import os_helper import io # C implementation. diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 6dc4fa55502..9e19af0ae90 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -9,6 +9,7 @@ import fractions import gc import io import locale +import math import os import pickle import platform @@ -24,13 +25,14 @@ from functools import partial from inspect import CO_COROUTINE from itertools import product from textwrap import dedent -from types import AsyncGeneratorType, FunctionType +from types import AsyncGeneratorType, FunctionType, CellType from operator import neg from test import support from test.support import (swap_attr, maybe_get_event_loop_policy) from test.support.os_helper import (EnvironmentVarGuard, TESTFN, unlink) from test.support.script_helper import assert_python_ok from test.support.warnings_helper import check_warnings +from test.support import requires_IEEE_754 from unittest.mock import MagicMock, patch try: import pty, signal @@ -38,6 +40,12 @@ except ImportError: pty = signal = None +# Detect evidence of double-rounding: sum() does not always +# get improved accuracy on machines that suffer from double rounding. +x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer +HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4) + + class Squares: def __init__(self, max): @@ -159,7 +167,7 @@ class BuiltinTest(unittest.TestCase): __import__('string') __import__(name='sys') __import__(name='time', level=0) - self.assertRaises(ImportError, __import__, 'spamspam') + self.assertRaises(ModuleNotFoundError, __import__, 'spamspam') self.assertRaises(TypeError, __import__, 1, 2, 3, 4) self.assertRaises(ValueError, __import__, '') self.assertRaises(TypeError, __import__, 'sys', name='sys') @@ -334,11 +342,10 @@ class BuiltinTest(unittest.TestCase): self.assertRaises(TypeError, compile) self.assertRaises(ValueError, compile, 'print(42)\n', '', 'badmode') self.assertRaises(ValueError, compile, 'print(42)\n', '', 'single', 0xff) - self.assertRaises(ValueError, compile, chr(0), 'f', 'exec') self.assertRaises(TypeError, compile, 'pass', '?', 'exec', mode='eval', source='0', filename='tmp') compile('print("\xe5")\n', '', 'exec') - self.assertRaises(ValueError, compile, chr(0), 'f', 'exec') + self.assertRaises(SyntaxError, compile, chr(0), 'f', 'exec') self.assertRaises(ValueError, compile, str('a = 1'), 'f', 'bad') # test the optimize argument @@ -393,6 +400,10 @@ class BuiltinTest(unittest.TestCase): msg=f"source={source} mode={mode}") + @unittest.skipIf( + support.is_emscripten or support.is_wasi, + "socket.accept is broken" + ) def test_compile_top_level_await(self): """Test whether code some top level await can be compiled. @@ -509,6 +520,9 @@ class BuiltinTest(unittest.TestCase): sys.spam = 1 delattr(sys, 'spam') self.assertRaises(TypeError, delattr) + self.assertRaises(TypeError, delattr, sys) + msg = r"^attribute name must be string, not 'int'$" + self.assertRaisesRegex(TypeError, msg, delattr, sys, 1) def test_dir(self): # dir(wrong number of arguments) @@ -581,8 +595,8 @@ class BuiltinTest(unittest.TestCase): # dir(traceback) try: raise IndexError - except: - self.assertEqual(len(dir(sys.exc_info()[2])), 4) + except IndexError as e: + self.assertEqual(len(dir(e.__traceback__)), 4) # test that object has a __dir__() self.assertEqual(sorted([].__dir__()), dir([])) @@ -730,11 +744,7 @@ class BuiltinTest(unittest.TestCase): self.assertRaises(TypeError, exec, code, {'__builtins__': 123}) - # no __build_class__ function - code = compile("class A: pass", "", "exec") - self.assertRaisesRegex(NameError, "__build_class__ not found", - exec, code, {'__builtins__': {}}) - + def test_exec_globals_frozen(self): class frozendict_error(Exception): pass @@ -751,12 +761,51 @@ class BuiltinTest(unittest.TestCase): self.assertRaises(frozendict_error, exec, code, {'__builtins__': frozen_builtins}) + # no __build_class__ function + code = compile("class A: pass", "", "exec") + self.assertRaisesRegex(NameError, "__build_class__ not found", + exec, code, {'__builtins__': {}}) + # __build_class__ in a custom __builtins__ + exec(code, {'__builtins__': frozen_builtins}) + self.assertRaisesRegex(NameError, "__build_class__ not found", + exec, code, {'__builtins__': frozendict()}) + # read-only globals namespace = frozendict({}) code = compile("x=1", "test", "exec") self.assertRaises(frozendict_error, exec, code, namespace) + def test_exec_globals_error_on_get(self): + # custom `globals` or `builtins` can raise errors on item access + class setonlyerror(Exception): + pass + + class setonlydict(dict): + def __getitem__(self, key): + raise setonlyerror + + # globals' `__getitem__` raises + code = compile("globalname", "test", "exec") + self.assertRaises(setonlyerror, + exec, code, setonlydict({'globalname': 1})) + + # builtins' `__getitem__` raises + code = compile("superglobal", "test", "exec") + self.assertRaises(setonlyerror, exec, code, + {'__builtins__': setonlydict({'superglobal': 1})}) + + def test_exec_globals_dict_subclass(self): + class customdict(dict): # this one should not do anything fancy + pass + + code = compile("superglobal", "test", "exec") + # works correctly + exec(code, {'__builtins__': customdict({'superglobal': 1})}) + # custom builtins dict subclass is missing key + self.assertRaisesRegex(NameError, "name 'superglobal' is not defined", + exec, code, {'__builtins__': customdict()}) + def test_exec_redirected(self): savestdout = sys.stdout sys.stdout = None # Whatever that cannot flush() @@ -768,6 +817,84 @@ class BuiltinTest(unittest.TestCase): finally: sys.stdout = savestdout + def test_exec_closure(self): + def function_without_closures(): + return 3 * 5 + + result = 0 + def make_closure_functions(): + a = 2 + b = 3 + c = 5 + def three_freevars(): + nonlocal result + nonlocal a + nonlocal b + result = a*b + def four_freevars(): + nonlocal result + nonlocal a + nonlocal b + nonlocal c + result = a*b*c + return three_freevars, four_freevars + three_freevars, four_freevars = make_closure_functions() + + # "smoke" test + result = 0 + exec(three_freevars.__code__, + three_freevars.__globals__, + closure=three_freevars.__closure__) + self.assertEqual(result, 6) + + # should also work with a manually created closure + result = 0 + my_closure = (CellType(35), CellType(72), three_freevars.__closure__[2]) + exec(three_freevars.__code__, + three_freevars.__globals__, + closure=my_closure) + self.assertEqual(result, 2520) + + # should fail: closure isn't allowed + # for functions without free vars + self.assertRaises(TypeError, + exec, + function_without_closures.__code__, + function_without_closures.__globals__, + closure=my_closure) + + # should fail: closure required but wasn't specified + self.assertRaises(TypeError, + exec, + three_freevars.__code__, + three_freevars.__globals__, + closure=None) + + # should fail: closure of wrong length + self.assertRaises(TypeError, + exec, + three_freevars.__code__, + three_freevars.__globals__, + closure=four_freevars.__closure__) + + # should fail: closure using a list instead of a tuple + my_closure = list(my_closure) + self.assertRaises(TypeError, + exec, + three_freevars.__code__, + three_freevars.__globals__, + closure=my_closure) + + # should fail: closure tuple with one non-cell-var + my_closure[0] = int + my_closure = tuple(my_closure) + self.assertRaises(TypeError, + exec, + three_freevars.__code__, + three_freevars.__globals__, + closure=my_closure) + + def test_filter(self): self.assertEqual(list(filter(lambda c: 'a' <= c <= 'z', 'Hello World')), list('elloorld')) self.assertEqual(list(filter(None, [1, 'hello', [], [3], '', None, 9, 0])), [1, 'hello', [3], 9]) @@ -801,17 +928,21 @@ class BuiltinTest(unittest.TestCase): def test_getattr(self): self.assertTrue(getattr(sys, 'stdout') is sys.stdout) - self.assertRaises(TypeError, getattr, sys, 1) - self.assertRaises(TypeError, getattr, sys, 1, "foo") self.assertRaises(TypeError, getattr) + self.assertRaises(TypeError, getattr, sys) + msg = r"^attribute name must be string, not 'int'$" + self.assertRaisesRegex(TypeError, msg, getattr, sys, 1) + self.assertRaisesRegex(TypeError, msg, getattr, sys, 1, 'spam') self.assertRaises(AttributeError, getattr, sys, chr(sys.maxunicode)) # unicode surrogates are not encodable to the default encoding (utf8) self.assertRaises(AttributeError, getattr, 1, "\uDAD1\uD51E") def test_hasattr(self): self.assertTrue(hasattr(sys, 'stdout')) - self.assertRaises(TypeError, hasattr, sys, 1) self.assertRaises(TypeError, hasattr) + self.assertRaises(TypeError, hasattr, sys) + msg = r"^attribute name must be string, not 'int'$" + self.assertRaisesRegex(TypeError, msg, hasattr, sys, 1) self.assertEqual(False, hasattr(sys, chr(sys.maxunicode))) # Check that hasattr propagates all exceptions outside of @@ -1024,7 +1155,11 @@ class BuiltinTest(unittest.TestCase): max() self.assertRaises(TypeError, max, 42) - self.assertRaises(ValueError, max, ()) + with self.assertRaisesRegex( + ValueError, + r'max\(\) iterable argument is empty' + ): + max(()) class BadSeq: def __getitem__(self, index): raise ValueError @@ -1083,7 +1218,11 @@ class BuiltinTest(unittest.TestCase): min() self.assertRaises(TypeError, min, 42) - self.assertRaises(ValueError, min, ()) + with self.assertRaisesRegex( + ValueError, + r'min\(\) iterable argument is empty' + ): + min(()) class BadSeq: def __getitem__(self, index): raise ValueError @@ -1196,7 +1335,7 @@ class BuiltinTest(unittest.TestCase): del os.environ[key] self.write_testfile() - current_locale_encoding = locale.getpreferredencoding(False) + current_locale_encoding = locale.getencoding() with warnings.catch_warnings(): warnings.simplefilter("ignore", EncodingWarning) fp = open(TESTFN, 'w') @@ -1206,6 +1345,7 @@ class BuiltinTest(unittest.TestCase): os.environ.clear() os.environ.update(old_environ) + @support.requires_subprocess() def test_open_non_inheritable(self): fileobj = open(__file__, encoding="utf-8") with fileobj: @@ -1457,8 +1597,11 @@ class BuiltinTest(unittest.TestCase): def test_setattr(self): setattr(sys, 'spam', 1) self.assertEqual(sys.spam, 1) - self.assertRaises(TypeError, setattr, sys, 1, 'spam') self.assertRaises(TypeError, setattr) + self.assertRaises(TypeError, setattr, sys) + self.assertRaises(TypeError, setattr, sys, 'spam') + msg = r"^attribute name must be string, not 'int'$" + self.assertRaisesRegex(TypeError, msg, setattr, sys, 1, 'spam') # test_str(): see test_unicode.py and test_bytes.py for str() tests. @@ -1490,6 +1633,8 @@ class BuiltinTest(unittest.TestCase): self.assertEqual(repr(sum([-0.0])), '0.0') self.assertEqual(repr(sum([-0.0], -0.0)), '-0.0') self.assertEqual(repr(sum([], -0.0)), '-0.0') + self.assertTrue(math.isinf(sum([float("inf"), float("inf")]))) + self.assertTrue(math.isinf(sum([1e308, 1e308]))) self.assertRaises(TypeError, sum) self.assertRaises(TypeError, sum, 42) @@ -1514,6 +1659,14 @@ class BuiltinTest(unittest.TestCase): sum(([x] for x in range(10)), empty) self.assertEqual(empty, []) + @requires_IEEE_754 + @unittest.skipIf(HAVE_DOUBLE_ROUNDING, + "sum accuracy not guaranteed on machines with double rounding") + @support.cpython_only # Other implementations may choose a different algorithm + def test_sum_accuracy(self): + self.assertEqual(sum([0.1] * 10), 1.0) + self.assertEqual(sum([1.0, 10E100, 1.0, -10E100]), 2.0) + def test_type(self): self.assertEqual(type(''), type('123')) self.assertNotEqual(type(''), type(())) @@ -1975,6 +2128,11 @@ class TestBreakpoint(unittest.TestCase): breakpoint() mock.assert_not_called() + def test_runtime_error_when_hook_is_lost(self): + del sys.breakpointhook + with self.assertRaises(RuntimeError): + breakpoint() + @unittest.skipUnless(pty, "the pty and signal modules must be available") class PtyTests(unittest.TestCase): @@ -2090,12 +2248,24 @@ class PtyTests(unittest.TestCase): # is different and invokes GNU readline if available). self.check_input_tty("prompt", b"quux") + def skip_if_readline(self): + # bpo-13886: When the readline module is loaded, PyOS_Readline() uses + # the readline implementation. In some cases, the Python readline + # callback rlhandler() is called by readline with a string without + # non-ASCII characters. Skip tests on non-ASCII characters if the + # readline module is loaded, since test_builtin is not intended to test + # the readline module, but the builtins module. + if 'readline' in sys.modules: + self.skipTest("the readline module is loaded") + def test_input_tty_non_ascii(self): - # Check stdin/stdout encoding is used when invoking GNU readline + self.skip_if_readline() + # Check stdin/stdout encoding is used when invoking PyOS_Readline() self.check_input_tty("prompté", b"quux\xe9", "utf-8") def test_input_tty_non_ascii_unicode_errors(self): - # Check stdin/stdout error handler is used when invoking GNU readline + self.skip_if_readline() + # Check stdin/stdout error handler is used when invoking PyOS_Readline() self.check_input_tty("prompté", b"quux\xe9", "ascii") def test_input_no_stdout_fileno(self): @@ -2236,7 +2406,7 @@ class TestType(unittest.TestCase): self.assertEqual(A.__module__, __name__) with self.assertRaises(ValueError): type('A\x00B', (), {}) - with self.assertRaises(ValueError): + with self.assertRaises(UnicodeEncodeError): type('A\udcdcB', (), {}) with self.assertRaises(TypeError): type(b'A', (), {}) @@ -2253,7 +2423,7 @@ class TestType(unittest.TestCase): with self.assertRaises(ValueError): A.__name__ = 'A\x00B' self.assertEqual(A.__name__, 'C') - with self.assertRaises(ValueError): + with self.assertRaises(UnicodeEncodeError): A.__name__ = 'A\udcdcB' self.assertEqual(A.__name__, 'C') with self.assertRaises(TypeError): diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index fd8e1d4bdc4..7c62b722059 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -715,6 +715,24 @@ class BaseBytesTest: self.assertEqual(b, b'hello,\x00world!') self.assertIs(type(b), self.type2test) + def check(fmt, vals, result): + b = self.type2test(fmt) + b = b % vals + self.assertEqual(b, result) + self.assertIs(type(b), self.type2test) + + # A set of tests adapted from test_unicode:UnicodeTest.test_formatting + check(b'...%(foo)b...', {b'foo':b"abc"}, b'...abc...') + check(b'...%(f(o)o)b...', {b'f(o)o':b"abc", b'foo':b'bar'}, b'...abc...') + check(b'...%(foo)b...', {b'foo':b"abc",b'def':123}, b'...abc...') + check(b'%*b', (5, b'abc',), b' abc') + check(b'%*b', (-5, b'abc',), b'abc ') + check(b'%*.*b', (5, 2, b'abc',), b' ab') + check(b'%*.*b', (5, 3, b'abc',), b' abc') + check(b'%i %*.*b', (10, 5, 3, b'abc',), b'10 abc') + check(b'%i%b %*.*b', (10, b'3', 5, 3, b'abc',), b'103 abc') + check(b'%c', b'a', b'a') + def test_imod(self): b = self.type2test(b'hello, %b!') orig = b @@ -1207,6 +1225,8 @@ class BytesTest(BaseBytesTest, unittest.TestCase): class ByteArrayTest(BaseBytesTest, unittest.TestCase): type2test = bytearray + _testcapi = import_helper.import_module('_testcapi') + def test_getitem_error(self): b = bytearray(b'python') msg = "bytearray indices must be integers or slices" @@ -1299,47 +1319,73 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase): self.assertEqual(re.findall(br"\w+", b), [by("Hello"), by("world")]) def test_setitem(self): - b = bytearray([1, 2, 3]) - b[1] = 100 - self.assertEqual(b, bytearray([1, 100, 3])) - b[-1] = 200 - self.assertEqual(b, bytearray([1, 100, 200])) - b[0] = Indexable(10) - self.assertEqual(b, bytearray([10, 100, 200])) - try: - b[3] = 0 - self.fail("Didn't raise IndexError") - except IndexError: - pass - try: - b[-10] = 0 - self.fail("Didn't raise IndexError") - except IndexError: - pass - try: - b[0] = 256 - self.fail("Didn't raise ValueError") - except ValueError: - pass - try: - b[0] = Indexable(-1) - self.fail("Didn't raise ValueError") - except ValueError: - pass - try: - b[0] = None - self.fail("Didn't raise TypeError") - except TypeError: - pass + def setitem_as_mapping(b, i, val): + b[i] = val + + def setitem_as_sequence(b, i, val): + self._testcapi.sequence_setitem(b, i, val) + + def do_tests(setitem): + b = bytearray([1, 2, 3]) + setitem(b, 1, 100) + self.assertEqual(b, bytearray([1, 100, 3])) + setitem(b, -1, 200) + self.assertEqual(b, bytearray([1, 100, 200])) + setitem(b, 0, Indexable(10)) + self.assertEqual(b, bytearray([10, 100, 200])) + try: + setitem(b, 3, 0) + self.fail("Didn't raise IndexError") + except IndexError: + pass + try: + setitem(b, -10, 0) + self.fail("Didn't raise IndexError") + except IndexError: + pass + try: + setitem(b, 0, 256) + self.fail("Didn't raise ValueError") + except ValueError: + pass + try: + setitem(b, 0, Indexable(-1)) + self.fail("Didn't raise ValueError") + except ValueError: + pass + try: + setitem(b, 0, None) + self.fail("Didn't raise TypeError") + except TypeError: + pass + + with self.subTest("tp_as_mapping"): + do_tests(setitem_as_mapping) + + with self.subTest("tp_as_sequence"): + do_tests(setitem_as_sequence) def test_delitem(self): - b = bytearray(range(10)) - del b[0] - self.assertEqual(b, bytearray(range(1, 10))) - del b[-1] - self.assertEqual(b, bytearray(range(1, 9))) - del b[4] - self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8])) + def del_as_mapping(b, i): + del b[i] + + def del_as_sequence(b, i): + self._testcapi.sequence_delitem(b, i) + + def do_tests(delete): + b = bytearray(range(10)) + delete(b, 0) + self.assertEqual(b, bytearray(range(1, 10))) + delete(b, -1) + self.assertEqual(b, bytearray(range(1, 9))) + delete(b, 4) + self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8])) + + with self.subTest("tp_as_mapping"): + do_tests(del_as_mapping) + + with self.subTest("tp_as_sequence"): + do_tests(del_as_sequence) def test_setslice(self): b = bytearray(range(10)) @@ -1710,6 +1756,24 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase): self.assertEqual(b1, b) self.assertEqual(b3, b'xcxcxc') + def test_mutating_index(self): + # See gh-91153 + + class Boom: + def __index__(self): + b.clear() + return 0 + + with self.subTest("tp_as_mapping"): + b = bytearray(b'Now you see me...') + with self.assertRaises(IndexError): + b[0] = Boom() + + with self.subTest("tp_as_sequence"): + b = bytearray(b'Now you see me...') + with self.assertRaises(IndexError): + self._testcapi.sequence_setitem(b, 0, Boom()) + class AssortedBytesTest(unittest.TestCase): # @@ -1940,28 +2004,30 @@ class SubclassTest: def test_pickle(self): a = self.type2test(b"abcd") a.x = 10 - a.y = self.type2test(b"efgh") + a.z = self.type2test(b"efgh") for proto in range(pickle.HIGHEST_PROTOCOL + 1): b = pickle.loads(pickle.dumps(a, proto)) self.assertNotEqual(id(a), id(b)) self.assertEqual(a, b) self.assertEqual(a.x, b.x) - self.assertEqual(a.y, b.y) + self.assertEqual(a.z, b.z) self.assertEqual(type(a), type(b)) - self.assertEqual(type(a.y), type(b.y)) + self.assertEqual(type(a.z), type(b.z)) + self.assertFalse(hasattr(b, 'y')) def test_copy(self): a = self.type2test(b"abcd") a.x = 10 - a.y = self.type2test(b"efgh") + a.z = self.type2test(b"efgh") for copy_method in (copy.copy, copy.deepcopy): b = copy_method(a) self.assertNotEqual(id(a), id(b)) self.assertEqual(a, b) self.assertEqual(a.x, b.x) - self.assertEqual(a.y, b.y) + self.assertEqual(a.z, b.z) self.assertEqual(type(a), type(b)) - self.assertEqual(type(a.y), type(b.y)) + self.assertEqual(type(a.z), type(b.z)) + self.assertFalse(hasattr(b, 'y')) def test_fromhex(self): b = self.type2test.fromhex('1a2B30') @@ -1994,6 +2060,9 @@ class SubclassTest: class ByteArraySubclass(bytearray): pass +class ByteArraySubclassWithSlots(bytearray): + __slots__ = ('x', 'y', '__dict__') + class BytesSubclass(bytes): pass @@ -2014,6 +2083,9 @@ class ByteArraySubclassTest(SubclassTest, unittest.TestCase): x = subclass(newarg=4, source=b"abcd") self.assertEqual(x, b"abcd") +class ByteArraySubclassWithSlotsTest(SubclassTest, unittest.TestCase): + basetype = bytearray + type2test = ByteArraySubclassWithSlots class BytesSubclassTest(SubclassTest, unittest.TestCase): basetype = bytes diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py index 9965c1fe2e5..c97ed1cea0d 100644 --- a/Lib/test/test_bz2.py +++ b/Lib/test/test_bz2.py @@ -496,6 +496,7 @@ class BZ2FileTest(BaseTest): else: self.fail("1/0 didn't raise an exception") + @threading_helper.requires_working_threading() def testThreading(self): # Issue #7205: Using a BZ2File from several threads shouldn't deadlock. data = b"1" * 2**20 diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index c641e8c4183..3d9dcf12f2d 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -564,6 +564,19 @@ class CalendarTestCase(unittest.TestCase): new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) self.assertEqual(old_october, new_october) + def test_locale_calendar_formatweekday(self): + try: + # formatweekday uses different day names based on the available width. + cal = calendar.LocaleTextCalendar(locale='en_US') + # For short widths, a centered, abbreviated name is used. + self.assertEqual(cal.formatweekday(0, 5), " Mon ") + # For really short widths, even the abbreviated name is truncated. + self.assertEqual(cal.formatweekday(0, 2), "Mo") + # For long widths, the full day name is used. + self.assertEqual(cal.formatweekday(0, 10), " Monday ") + except locale.Error: + raise unittest.SkipTest('cannot set the en_US locale') + def test_locale_html_calendar_custom_css_class_month_name(self): try: cal = calendar.LocaleHTMLCalendar(locale='') @@ -619,6 +632,14 @@ class CalendarTestCase(unittest.TestCase): self.assertEqual(days[0][1], firstweekday) self.assertEqual(days[-1][1], (firstweekday - 1) % 7) + def test_iterweekdays(self): + week0 = list(range(7)) + for firstweekday in range(7): + cal = calendar.Calendar(firstweekday) + week = list(cal.iterweekdays()) + expected = week0[firstweekday:] + week0[:firstweekday] + self.assertEqual(week, expected) + class MonthCalendarTestCase(unittest.TestCase): def setUp(self): @@ -859,7 +880,8 @@ class CommandLineTestCase(unittest.TestCase): self.assertFailure('-L') self.assertFailure('--locale') self.assertFailure('-L', 'en') - lang, enc = locale.getdefaultlocale() + + lang, enc = locale.getlocale() lang = lang or 'C' enc = enc or 'UTF-8' try: @@ -935,8 +957,7 @@ class CommandLineTestCase(unittest.TestCase): class MiscTestCase(unittest.TestCase): def test__all__(self): not_exported = { - 'mdays', 'January', 'February', 'EPOCH', 'MONDAY', 'TUESDAY', - 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY', + 'mdays', 'January', 'February', 'EPOCH', 'different_locale', 'c', 'prweek', 'week', 'format', 'formatstring', 'main', 'monthlen', 'prevmonth', 'nextmonth'} support.check__all__(self, calendar, not_exported=not_exported) diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index 6936f093e3d..aab7b1580ea 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -1,5 +1,5 @@ import unittest -from test.support import cpython_only +from test.support import cpython_only, requires_limited_api try: import _testcapi except ImportError: @@ -9,6 +9,15 @@ import collections import itertools import gc import contextlib +import sys + + +class BadStr(str): + def __eq__(self, other): + return True + def __hash__(self): + # Guaranteed different hash + return str.__hash__(self) ^ 3 class FunctionCalls(unittest.TestCase): @@ -26,6 +35,18 @@ class FunctionCalls(unittest.TestCase): self.assertIsInstance(res, dict) self.assertEqual(list(res.items()), expected) + def test_frames_are_popped_after_failed_calls(self): + # GH-93252: stuff blows up if we don't pop the new frame after + # recovering from failed calls: + def f(): + pass + for _ in range(1000): + try: + f(None) + except TypeError: + pass + # BOOM! + @cpython_only class CFunctionCallsErrorMessages(unittest.TestCase): @@ -119,9 +140,9 @@ class CFunctionCallsErrorMessages(unittest.TestCase): itertools.product, 0, repeat=1, foo=2) def test_varargs15_kw(self): - msg = r"^ImportError\(\) takes at most 2 keyword arguments \(3 given\)$" + msg = r"^ImportError\(\) takes at most 3 keyword arguments \(4 given\)$" self.assertRaisesRegex(TypeError, msg, - ImportError, 0, name=1, path=2, foo=3) + ImportError, 0, name=1, path=2, name_from=3, foo=3) def test_varargs16_kw(self): msg = r"^min\(\) takes at most 2 keyword arguments \(3 given\)$" @@ -133,6 +154,18 @@ class CFunctionCallsErrorMessages(unittest.TestCase): self.assertRaisesRegex(TypeError, msg, print, 0, sep=1, end=2, file=3, flush=4, foo=5) + def test_varargs18_kw(self): + # _PyArg_UnpackKeywordsWithVararg() + msg = r"invalid keyword argument for print\(\)$" + with self.assertRaisesRegex(TypeError, msg): + print(0, 1, **{BadStr('foo'): ','}) + + def test_varargs19_kw(self): + # _PyArg_UnpackKeywords() + msg = r"invalid keyword argument for round\(\)$" + with self.assertRaisesRegex(TypeError, msg): + round(1.75, **{BadStr('foo'): 1}) + def test_oldargs0_1(self): msg = r"keys\(\) takes no arguments \(1 given\)" self.assertRaisesRegex(TypeError, msg, {}.keys, 0) @@ -526,7 +559,7 @@ class FastCallTests(unittest.TestCase): self.kwargs.clear() gc.collect() return 0 - x = IntWithDict(dont_inherit=IntWithDict()) + x = IntWithDict(optimize=IntWithDict()) # We test the argument handling of "compile" here, the compilation # itself is not relevant. When we pass flags=x below, x.__index__() is # called, which changes the keywords dict. @@ -547,6 +580,9 @@ def testfunction_kw(self, *, kw): return self +ADAPTIVE_WARMUP_DELAY = 2 + + class TestPEP590(unittest.TestCase): def test_method_descriptor_flag(self): @@ -574,9 +610,19 @@ class TestPEP590(unittest.TestCase): self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) self.assertTrue(_testcapi.MethodDescriptor2.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) - # Mutable heap types should not inherit Py_TPFLAGS_HAVE_VECTORCALL + # Mutable heap types should inherit Py_TPFLAGS_HAVE_VECTORCALL, + # but should lose it when __call__ is overridden class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): pass + self.assertTrue(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) + MethodDescriptorHeap.__call__ = print + self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) + + # Mutable heap types should not inherit Py_TPFLAGS_HAVE_VECTORCALL if + # they define __call__ directly + class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): + def __call__(self): + pass self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) def test_vectorcall_override(self): @@ -589,6 +635,58 @@ class TestPEP590(unittest.TestCase): f = _testcapi.MethodDescriptorNopGet() self.assertIs(f(*args), args) + def test_vectorcall_override_on_mutable_class(self): + """Setting __call__ should disable vectorcall""" + TestType = _testcapi.make_vectorcall_class() + instance = TestType() + self.assertEqual(instance(), "tp_call") + instance.set_vectorcall(TestType) + self.assertEqual(instance(), "vectorcall") # assume vectorcall is used + TestType.__call__ = lambda self: "custom" + self.assertEqual(instance(), "custom") + + def test_vectorcall_override_with_subclass(self): + """Setting __call__ on a superclass should disable vectorcall""" + SuperType = _testcapi.make_vectorcall_class() + class DerivedType(SuperType): + pass + + instance = DerivedType() + + # Derived types with its own vectorcall should be unaffected + UnaffectedType1 = _testcapi.make_vectorcall_class(DerivedType) + UnaffectedType2 = _testcapi.make_vectorcall_class(SuperType) + + # Aside: Quickly check that the C helper actually made derived types + self.assertTrue(issubclass(UnaffectedType1, DerivedType)) + self.assertTrue(issubclass(UnaffectedType2, SuperType)) + + # Initial state: tp_call + self.assertEqual(instance(), "tp_call") + self.assertEqual(_testcapi.has_vectorcall_flag(SuperType), True) + self.assertEqual(_testcapi.has_vectorcall_flag(DerivedType), True) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType1), True) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType2), True) + + # Setting the vectorcall function + instance.set_vectorcall(SuperType) + + self.assertEqual(instance(), "vectorcall") + self.assertEqual(_testcapi.has_vectorcall_flag(SuperType), True) + self.assertEqual(_testcapi.has_vectorcall_flag(DerivedType), True) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType1), True) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType2), True) + + # Setting __call__ should remove vectorcall from all subclasses + SuperType.__call__ = lambda self: "custom" + + self.assertEqual(instance(), "custom") + self.assertEqual(_testcapi.has_vectorcall_flag(SuperType), False) + self.assertEqual(_testcapi.has_vectorcall_flag(DerivedType), False) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType1), True) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType2), True) + + def test_vectorcall(self): # Test a bunch of different ways to call objects: # 1. vectorcall using PyVectorcall_Call() @@ -665,6 +763,92 @@ class TestPEP590(unittest.TestCase): self.assertEqual(expected, meth(*args1, **kwargs)) self.assertEqual(expected, wrapped(*args, **kwargs)) + def test_setvectorcall(self): + from _testcapi import function_setvectorcall + def f(num): return num + 1 + assert_equal = self.assertEqual + num = 10 + assert_equal(11, f(num)) + function_setvectorcall(f) + # make sure specializer is triggered by running > 50 times + for _ in range(10 * ADAPTIVE_WARMUP_DELAY): + assert_equal("overridden", f(num)) + + def test_setvectorcall_load_attr_specialization_skip(self): + from _testcapi import function_setvectorcall + + class X: + def __getattribute__(self, attr): + return attr + + assert_equal = self.assertEqual + x = X() + assert_equal("a", x.a) + function_setvectorcall(X.__getattribute__) + # make sure specialization doesn't trigger + # when vectorcall is overridden + for _ in range(ADAPTIVE_WARMUP_DELAY): + assert_equal("overridden", x.a) + + def test_setvectorcall_load_attr_specialization_deopt(self): + from _testcapi import function_setvectorcall + + class X: + def __getattribute__(self, attr): + return attr + + def get_a(x): + return x.a + + assert_equal = self.assertEqual + x = X() + # trigger LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN specialization + for _ in range(ADAPTIVE_WARMUP_DELAY): + assert_equal("a", get_a(x)) + function_setvectorcall(X.__getattribute__) + # make sure specialized LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN + # gets deopted due to overridden vectorcall + for _ in range(ADAPTIVE_WARMUP_DELAY): + assert_equal("overridden", get_a(x)) + + @requires_limited_api + def test_vectorcall_limited_incoming(self): + from _testcapi import pyobject_vectorcall + obj = _testcapi.LimitedVectorCallClass() + self.assertEqual(pyobject_vectorcall(obj, (), ()), "vectorcall called") + + @requires_limited_api + def test_vectorcall_limited_outgoing(self): + from _testcapi import call_vectorcall + + args_captured = [] + kwargs_captured = [] + + def f(*args, **kwargs): + args_captured.append(args) + kwargs_captured.append(kwargs) + return "success" + + self.assertEqual(call_vectorcall(f), "success") + self.assertEqual(args_captured, [("foo",)]) + self.assertEqual(kwargs_captured, [{"baz": "bar"}]) + + @requires_limited_api + def test_vectorcall_limited_outgoing_method(self): + from _testcapi import call_vectorcall_method + + args_captured = [] + kwargs_captured = [] + + class TestInstance: + def f(self, *args, **kwargs): + args_captured.append(args) + kwargs_captured.append(kwargs) + return "success" + + self.assertEqual(call_vectorcall_method(TestInstance()), "success") + self.assertEqual(args_captured, [("foo",)]) + self.assertEqual(kwargs_captured, [{"baz": "bar"}]) class A: def method_two_args(self, x, y): @@ -712,6 +896,54 @@ class TestErrorMessagesUseQualifiedName(unittest.TestCase): with self.check_raises_type_error(msg): A().method_two_args("x", "y", x="oops") +@cpython_only +class TestRecursion(unittest.TestCase): + + def test_super_deep(self): + + def recurse(n): + if n: + recurse(n-1) + + def py_recurse(n, m): + if n: + py_recurse(n-1, m) + else: + c_py_recurse(m-1) + + def c_recurse(n): + if n: + _testcapi.pyobject_fastcall(c_recurse, (n-1,)) + + def c_py_recurse(m): + if m: + _testcapi.pyobject_fastcall(py_recurse, (1000, m)) + + depth = sys.getrecursionlimit() + sys.setrecursionlimit(100_000) + try: + recurse(90_000) + with self.assertRaises(RecursionError): + recurse(101_000) + c_recurse(100) + with self.assertRaises(RecursionError): + c_recurse(90_000) + c_py_recurse(90) + with self.assertRaises(RecursionError): + c_py_recurse(100_000) + finally: + sys.setrecursionlimit(depth) + +class TestFunctionWithManyArgs(unittest.TestCase): + def test_function_with_many_args(self): + for N in (10, 500, 1000): + with self.subTest(N=N): + args = ",".join([f"a{i}" for i in range(N)]) + src = f"def f({args}) : return a{N//2}" + l = {} + exec(src, {}, l) + self.assertEqual(l['f'](*range(N)), N//2) + if __name__ == "__main__": unittest.main() diff --git a/Lib/lib2to3/tests/__init__.py b/Lib/test/test_capi/__init__.py similarity index 84% rename from Lib/lib2to3/tests/__init__.py rename to Lib/test/test_capi/__init__.py index 54221c79943..4b16ecc3115 100644 --- a/Lib/lib2to3/tests/__init__.py +++ b/Lib/test/test_capi/__init__.py @@ -1,7 +1,4 @@ -# Author: Collin Winter - import os - from test.support import load_package_tests def load_tests(*args): diff --git a/Lib/test/test_capi/__main__.py b/Lib/test/test_capi/__main__.py new file mode 100644 index 00000000000..05d01775ddf --- /dev/null +++ b/Lib/test/test_capi/__main__.py @@ -0,0 +1,3 @@ +import unittest + +unittest.main('test.test_capi') diff --git a/Lib/test/test_capi/test_codecs.py b/Lib/test/test_capi/test_codecs.py new file mode 100644 index 00000000000..e46726192aa --- /dev/null +++ b/Lib/test/test_capi/test_codecs.py @@ -0,0 +1,54 @@ +import unittest +from test.support import import_helper + +_testcapi = import_helper.import_module('_testcapi') + + +class CAPITest(unittest.TestCase): + + def test_decodeutf8(self): + """Test PyUnicode_DecodeUTF8()""" + decodeutf8 = _testcapi.unicode_decodeutf8 + + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']: + b = s.encode('utf-8') + self.assertEqual(decodeutf8(b), s) + self.assertEqual(decodeutf8(b, 'strict'), s) + + self.assertRaises(UnicodeDecodeError, decodeutf8, b'\x80') + self.assertRaises(UnicodeDecodeError, decodeutf8, b'\xc0') + self.assertRaises(UnicodeDecodeError, decodeutf8, b'\xff') + self.assertRaises(UnicodeDecodeError, decodeutf8, b'a\xf0\x9f') + self.assertEqual(decodeutf8(b'a\xf0\x9f', 'replace'), 'a\ufffd') + self.assertEqual(decodeutf8(b'a\xf0\x9fb', 'replace'), 'a\ufffdb') + + self.assertRaises(LookupError, decodeutf8, b'a\x80', 'foo') + # TODO: Test PyUnicode_DecodeUTF8() with NULL as data and + # negative size. + + def test_decodeutf8stateful(self): + """Test PyUnicode_DecodeUTF8Stateful()""" + decodeutf8stateful = _testcapi.unicode_decodeutf8stateful + + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']: + b = s.encode('utf-8') + self.assertEqual(decodeutf8stateful(b), (s, len(b))) + self.assertEqual(decodeutf8stateful(b, 'strict'), (s, len(b))) + + self.assertRaises(UnicodeDecodeError, decodeutf8stateful, b'\x80') + self.assertRaises(UnicodeDecodeError, decodeutf8stateful, b'\xc0') + self.assertRaises(UnicodeDecodeError, decodeutf8stateful, b'\xff') + self.assertEqual(decodeutf8stateful(b'a\xf0\x9f'), ('a', 1)) + self.assertEqual(decodeutf8stateful(b'a\xf0\x9f', 'replace'), ('a', 1)) + self.assertRaises(UnicodeDecodeError, decodeutf8stateful, b'a\xf0\x9fb') + self.assertEqual(decodeutf8stateful(b'a\xf0\x9fb', 'replace'), ('a\ufffdb', 4)) + + self.assertRaises(LookupError, decodeutf8stateful, b'a\x80', 'foo') + # TODO: Test PyUnicode_DecodeUTF8Stateful() with NULL as data and + # negative size. + # TODO: Test PyUnicode_DecodeUTF8Stateful() with NULL as the address of + # "consumed". + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_getargs2.py b/Lib/test/test_capi/test_getargs.py similarity index 95% rename from Lib/test/test_getargs2.py rename to Lib/test/test_capi/test_getargs.py index e0db9e40e65..3792d1a6515 100644 --- a/Lib/test/test_getargs2.py +++ b/Lib/test/test_capi/test_getargs.py @@ -746,6 +746,33 @@ class KeywordOnly_TestCase(unittest.TestCase): "'\udc80' is an invalid keyword argument for this function"): getargs_keyword_only(1, 2, **{'\uDC80': 10}) + def test_weird_str_subclass(self): + class BadStr(str): + def __eq__(self, other): + return True + def __hash__(self): + # Guaranteed different hash + return str.__hash__(self) ^ 3 + with self.assertRaisesRegex(TypeError, + "invalid keyword argument for this function"): + getargs_keyword_only(1, 2, **{BadStr("keyword_only"): 3}) + with self.assertRaisesRegex(TypeError, + "invalid keyword argument for this function"): + getargs_keyword_only(1, 2, **{BadStr("monster"): 666}) + + def test_weird_str_subclass2(self): + class BadStr(str): + def __eq__(self, other): + return False + def __hash__(self): + return str.__hash__(self) + with self.assertRaisesRegex(TypeError, + "invalid keyword argument for this function"): + getargs_keyword_only(1, 2, **{BadStr("keyword_only"): 3}) + with self.assertRaisesRegex(TypeError, + "invalid keyword argument for this function"): + getargs_keyword_only(1, 2, **{BadStr("monster"): 666}) + class PositionalOnlyAndKeywords_TestCase(unittest.TestCase): from _testcapi import getargs_positional_only_and_keywords as getargs @@ -877,9 +904,19 @@ class String_TestCase(unittest.TestCase): def test_s_hash_int(self): # "s#" without PY_SSIZE_T_CLEAN defined. from _testcapi import getargs_s_hash_int - self.assertRaises(SystemError, getargs_s_hash_int, "abc") - self.assertRaises(SystemError, getargs_s_hash_int, x=42) - # getargs_s_hash_int() don't raise SystemError because skipitem() is not called. + from _testcapi import getargs_s_hash_int2 + buf = bytearray([1, 2]) + self.assertRaises(SystemError, getargs_s_hash_int, buf, "abc") + self.assertRaises(SystemError, getargs_s_hash_int, buf, x=42) + self.assertRaises(SystemError, getargs_s_hash_int, buf, x="abc") + self.assertRaises(SystemError, getargs_s_hash_int2, buf, ("abc",)) + self.assertRaises(SystemError, getargs_s_hash_int2, buf, x=42) + self.assertRaises(SystemError, getargs_s_hash_int2, buf, x="abc") + buf.append(3) # still mutable -- not locked by a buffer export + # getargs_s_hash_int(buf) may not raise SystemError because skipitem() + # is not called. But it is an implementation detail. + # getargs_s_hash_int(buf) + # getargs_s_hash_int2(buf) def test_z(self): from _testcapi import getargs_z @@ -1048,6 +1085,10 @@ class String_TestCase(unittest.TestCase): with self.assertWarns(DeprecationWarning): self.assertIsNone(getargs_Z_hash(None)) + def test_gh_99240_clear_args(self): + from _testcapi import gh_99240_clear_args + self.assertRaises(TypeError, gh_99240_clear_args, 'a', '\0b') + class Object_TestCase(unittest.TestCase): def test_S(self): @@ -1162,7 +1203,7 @@ class SkipitemTest(unittest.TestCase): dict_b = {'b':1} keywords = ["a", "b"] - supported = ('s#', 's*', 'z#', 'z*', 'u#', 'Z#', 'y#', 'y*', 'w#', 'w*') + supported = ('s#', 's*', 'z#', 'z*', 'y#', 'y*', 'w#', 'w*') for c in string.ascii_letters: for c2 in '#*': f = c + c2 @@ -1255,14 +1296,6 @@ class Test_testcapi(unittest.TestCase): for name in dir(_testcapi) if name.startswith('test_') and name.endswith('_code')) - @warnings_helper.ignore_warnings(category=DeprecationWarning) - def test_u_code(self): - _testcapi.test_u_code() - - @warnings_helper.ignore_warnings(category=DeprecationWarning) - def test_Z_code(self): - _testcapi.test_Z_code() - if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_capi/test_mem.py b/Lib/test/test_capi/test_mem.py new file mode 100644 index 00000000000..a9ff410cb93 --- /dev/null +++ b/Lib/test/test_capi/test_mem.py @@ -0,0 +1,169 @@ +import re +import textwrap +import unittest + + +from test import support +from test.support import import_helper, requires_subprocess +from test.support.script_helper import assert_python_failure, assert_python_ok + + +# Skip this test if the _testcapi module isn't available. +_testcapi = import_helper.import_module('_testcapi') + +@requires_subprocess() +class PyMemDebugTests(unittest.TestCase): + PYTHONMALLOC = 'debug' + # '0x04c06e0' or '04C06E0' + PTR_REGEX = r'(?:0x)?[0-9a-fA-F]+' + + def check(self, code): + with support.SuppressCrashReport(): + out = assert_python_failure( + '-c', code, + PYTHONMALLOC=self.PYTHONMALLOC, + # FreeBSD: instruct jemalloc to not fill freed() memory + # with junk byte 0x5a, see JEMALLOC(3) + MALLOC_CONF="junk:false", + ) + stderr = out.err + return stderr.decode('ascii', 'replace') + + def test_buffer_overflow(self): + out = self.check('import _testcapi; _testcapi.pymem_buffer_overflow()') + regex = (r"Debug memory block at address p={ptr}: API 'm'\n" + r" 16 bytes originally requested\n" + r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n" + r" The [0-9] pad bytes at tail={ptr} are not all FORBIDDENBYTE \(0x[0-9a-f]{{2}}\):\n" + r" at tail\+0: 0x78 \*\*\* OUCH\n" + r" at tail\+1: 0xfd\n" + r" at tail\+2: 0xfd\n" + r" .*\n" + r"( The block was made by call #[0-9]+ to debug malloc/realloc.\n)?" + r" Data at p: cd cd cd .*\n" + r"\n" + r"Enable tracemalloc to get the memory block allocation traceback\n" + r"\n" + r"Fatal Python error: _PyMem_DebugRawFree: bad trailing pad byte") + regex = regex.format(ptr=self.PTR_REGEX) + regex = re.compile(regex, flags=re.DOTALL) + self.assertRegex(out, regex) + + def test_api_misuse(self): + out = self.check('import _testcapi; _testcapi.pymem_api_misuse()') + regex = (r"Debug memory block at address p={ptr}: API 'm'\n" + r" 16 bytes originally requested\n" + r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n" + r" The [0-9] pad bytes at tail={ptr} are FORBIDDENBYTE, as expected.\n" + r"( The block was made by call #[0-9]+ to debug malloc/realloc.\n)?" + r" Data at p: cd cd cd .*\n" + r"\n" + r"Enable tracemalloc to get the memory block allocation traceback\n" + r"\n" + r"Fatal Python error: _PyMem_DebugRawFree: bad ID: Allocated using API 'm', verified using API 'r'\n") + regex = regex.format(ptr=self.PTR_REGEX) + self.assertRegex(out, regex) + + def check_malloc_without_gil(self, code): + out = self.check(code) + expected = ('Fatal Python error: _PyMem_DebugMalloc: ' + 'Python memory allocator called without holding the GIL') + self.assertIn(expected, out) + + def test_pymem_malloc_without_gil(self): + # Debug hooks must raise an error if PyMem_Malloc() is called + # without holding the GIL + code = 'import _testcapi; _testcapi.pymem_malloc_without_gil()' + self.check_malloc_without_gil(code) + + def test_pyobject_malloc_without_gil(self): + # Debug hooks must raise an error if PyObject_Malloc() is called + # without holding the GIL + code = 'import _testcapi; _testcapi.pyobject_malloc_without_gil()' + self.check_malloc_without_gil(code) + + def check_pyobject_is_freed(self, func_name): + code = textwrap.dedent(f''' + import gc, os, sys, _testcapi + # Disable the GC to avoid crash on GC collection + gc.disable() + try: + _testcapi.{func_name}() + # Exit immediately to avoid a crash while deallocating + # the invalid object + os._exit(0) + except _testcapi.error: + os._exit(1) + ''') + assert_python_ok( + '-c', code, + PYTHONMALLOC=self.PYTHONMALLOC, + MALLOC_CONF="junk:false", + ) + + def test_pyobject_null_is_freed(self): + self.check_pyobject_is_freed('check_pyobject_null_is_freed') + + def test_pyobject_uninitialized_is_freed(self): + self.check_pyobject_is_freed('check_pyobject_uninitialized_is_freed') + + def test_pyobject_forbidden_bytes_is_freed(self): + self.check_pyobject_is_freed('check_pyobject_forbidden_bytes_is_freed') + + def test_pyobject_freed_is_freed(self): + self.check_pyobject_is_freed('check_pyobject_freed_is_freed') + + def test_set_nomemory(self): + code = """if 1: + import _testcapi + + class C(): pass + + # The first loop tests both functions and that remove_mem_hooks() + # can be called twice in a row. The second loop checks a call to + # set_nomemory() after a call to remove_mem_hooks(). The third + # loop checks the start and stop arguments of set_nomemory(). + for outer_cnt in range(1, 4): + start = 10 * outer_cnt + for j in range(100): + if j == 0: + if outer_cnt != 3: + _testcapi.set_nomemory(start) + else: + _testcapi.set_nomemory(start, start + 1) + try: + C() + except MemoryError as e: + if outer_cnt != 3: + _testcapi.remove_mem_hooks() + print('MemoryError', outer_cnt, j) + _testcapi.remove_mem_hooks() + break + """ + rc, out, err = assert_python_ok('-c', code) + lines = out.splitlines() + for i, line in enumerate(lines, 1): + self.assertIn(b'MemoryError', out) + *_, count = line.split(b' ') + count = int(count) + self.assertLessEqual(count, i*5) + self.assertGreaterEqual(count, i*5-2) + + +class PyMemMallocDebugTests(PyMemDebugTests): + PYTHONMALLOC = 'malloc_debug' + + +@unittest.skipUnless(support.with_pymalloc(), 'need pymalloc') +class PyMemPymallocDebugTests(PyMemDebugTests): + PYTHONMALLOC = 'pymalloc_debug' + + +@unittest.skipUnless(support.Py_DEBUG, 'need Py_DEBUG') +class PyMemDefaultTests(PyMemDebugTests): + # test default allocator of Python compiled in debug mode + PYTHONMALLOC = '' + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi/test_misc.py similarity index 55% rename from Lib/test/test_capi.py rename to Lib/test/test_capi/test_misc.py index 5e1619bf7dc..dace37c362e 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi/test_misc.py @@ -2,6 +2,7 @@ # these are all functions _testcapi exports whose name begins with 'test_'. from collections import OrderedDict +import _thread import importlib.machinery import importlib.util import os @@ -14,6 +15,7 @@ import textwrap import threading import time import unittest +import warnings import weakref from test import support from test.support import MISSING_C_DOCSTRINGS @@ -25,15 +27,16 @@ try: import _posixsubprocess except ImportError: _posixsubprocess = None +try: + import _testmultiphase +except ImportError: + _testmultiphase = None # Skip this test if the _testcapi module isn't available. _testcapi = import_helper.import_module('_testcapi') import _testinternalcapi -# Were we compiled --with-pydebug or with #define Py_DEBUG? -Py_DEBUG = hasattr(sys, 'gettotalrefcount') - def decode_stderr(err): return err.decode('utf-8', 'replace').replace('\r', '') @@ -61,27 +64,51 @@ class CAPITest(unittest.TestCase): self.assertEqual(testfunction.attribute, "test") self.assertRaises(AttributeError, setattr, inst.testfunction, "attribute", "test") + @support.requires_subprocess() def test_no_FatalError_infinite_loop(self): with support.SuppressCrashReport(): p = subprocess.Popen([sys.executable, "-c", 'import _testcapi;' '_testcapi.crash_no_current_thread()'], stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + stderr=subprocess.PIPE, + text=True) (out, err) = p.communicate() - self.assertEqual(out, b'') + self.assertEqual(out, '') # This used to cause an infinite loop. - self.assertTrue(err.rstrip().startswith( - b'Fatal Python error: ' - b'PyThreadState_Get: ' - b'the function must be called with the GIL held, ' - b'but the GIL is released ' - b'(the current Python thread state is NULL)'), + msg = ("Fatal Python error: PyThreadState_Get: " + "the function must be called with the GIL held, " + "after Python initialization and before Python finalization, " + "but the GIL is released " + "(the current Python thread state is NULL)") + self.assertTrue(err.rstrip().startswith(msg), err) def test_memoryview_from_NULL_pointer(self): self.assertRaises(ValueError, _testcapi.make_memoryview_from_NULL_pointer) + def test_exception(self): + raised_exception = ValueError("5") + new_exc = TypeError("TEST") + try: + raise raised_exception + except ValueError as e: + orig_sys_exception = sys.exception() + orig_exception = _testcapi.set_exception(new_exc) + new_sys_exception = sys.exception() + new_exception = _testcapi.set_exception(orig_exception) + reset_sys_exception = sys.exception() + + self.assertEqual(orig_exception, e) + + self.assertEqual(orig_exception, raised_exception) + self.assertEqual(orig_sys_exception, orig_exception) + self.assertEqual(reset_sys_exception, orig_exception) + self.assertEqual(new_exception, new_exc) + self.assertEqual(new_sys_exception, new_exception) + else: + self.fail("Exception not raised") + def test_exc_info(self): raised_exception = ValueError("5") new_exc = TypeError("TEST") @@ -111,8 +138,9 @@ class CAPITest(unittest.TestCase): class Z(object): def __len__(self): return 1 - self.assertRaises(TypeError, _posixsubprocess.fork_exec, - 1,Z(),3,(1, 2),5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21) + with self.assertRaisesRegex(TypeError, 'indexing'): + _posixsubprocess.fork_exec( + 1,Z(),True,(1, 2),5,6,7,8,9,10,11,12,13,14,True,True,17,False,19,20,21,22,False) # Issue #15736: overflow in _PySequence_BytesToCharpArray() class Z(object): def __len__(self): @@ -120,7 +148,7 @@ class CAPITest(unittest.TestCase): def __getitem__(self, i): return b'x' self.assertRaises(MemoryError, _posixsubprocess.fork_exec, - 1,Z(),3,(1, 2),5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21) + 1,Z(),True,(1, 2),5,6,7,8,9,10,11,12,13,14,True,True,17,False,19,20,21,22,False) @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.') def test_subprocess_fork_exec(self): @@ -130,7 +158,7 @@ class CAPITest(unittest.TestCase): # Issue #15738: crash in subprocess_fork_exec() self.assertRaises(TypeError, _posixsubprocess.fork_exec, - Z(),[b'1'],3,(1, 2),5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21) + Z(),[b'1'],True,(1, 2),5,6,7,8,9,10,11,12,13,14,True,True,17,False,19,20,21,22,False) @unittest.skipIf(MISSING_C_DOCSTRINGS, "Signature information for builtins requires docstrings") @@ -202,7 +230,7 @@ class CAPITest(unittest.TestCase): def test_return_null_without_error(self): # Issue #23571: A function must not return NULL without setting an # error - if Py_DEBUG: + if support.Py_DEBUG: code = textwrap.dedent(""" import _testcapi from test import support @@ -230,7 +258,7 @@ class CAPITest(unittest.TestCase): def test_return_result_with_error(self): # Issue #23571: A function must not return a result with an error set - if Py_DEBUG: + if support.Py_DEBUG: code = textwrap.dedent(""" import _testcapi from test import support @@ -295,42 +323,6 @@ class CAPITest(unittest.TestCase): def test_buildvalue_N(self): _testcapi.test_buildvalue_N() - def test_set_nomemory(self): - code = """if 1: - import _testcapi - - class C(): pass - - # The first loop tests both functions and that remove_mem_hooks() - # can be called twice in a row. The second loop checks a call to - # set_nomemory() after a call to remove_mem_hooks(). The third - # loop checks the start and stop arguments of set_nomemory(). - for outer_cnt in range(1, 4): - start = 10 * outer_cnt - for j in range(100): - if j == 0: - if outer_cnt != 3: - _testcapi.set_nomemory(start) - else: - _testcapi.set_nomemory(start, start + 1) - try: - C() - except MemoryError as e: - if outer_cnt != 3: - _testcapi.remove_mem_hooks() - print('MemoryError', outer_cnt, j) - _testcapi.remove_mem_hooks() - break - """ - rc, out, err = assert_python_ok('-c', code) - lines = out.splitlines() - for i, line in enumerate(lines, 1): - self.assertIn(b'MemoryError', out) - *_, count = line.split(b' ') - count = int(count) - self.assertLessEqual(count, i*5) - self.assertGreaterEqual(count, i*5-1) - def test_mapping_keys_values_items(self): class Mapping1(dict): def keys(self): @@ -375,6 +367,98 @@ class CAPITest(unittest.TestCase): self.assertRaises(TypeError, _testcapi.get_mapping_values, bad_mapping) self.assertRaises(TypeError, _testcapi.get_mapping_items, bad_mapping) + def test_mapping_has_key(self): + dct = {'a': 1} + self.assertTrue(_testcapi.mapping_has_key(dct, 'a')) + self.assertFalse(_testcapi.mapping_has_key(dct, 'b')) + + class SubDict(dict): + pass + + dct2 = SubDict({'a': 1}) + self.assertTrue(_testcapi.mapping_has_key(dct2, 'a')) + self.assertFalse(_testcapi.mapping_has_key(dct2, 'b')) + + def test_sequence_set_slice(self): + # Correct case: + data = [1, 2, 3, 4, 5] + data_copy = data.copy() + + _testcapi.sequence_set_slice(data, 1, 3, [8, 9]) + data_copy[1:3] = [8, 9] + self.assertEqual(data, data_copy) + self.assertEqual(data, [1, 8, 9, 4, 5]) + + # Custom class: + class Custom: + def __setitem__(self, index, value): + self.index = index + self.value = value + + c = Custom() + _testcapi.sequence_set_slice(c, 0, 5, 'abc') + self.assertEqual(c.index, slice(0, 5)) + self.assertEqual(c.value, 'abc') + + # Immutable sequences must raise: + bad_seq1 = (1, 2, 3, 4) + with self.assertRaises(TypeError): + _testcapi.sequence_set_slice(bad_seq1, 1, 3, (8, 9)) + self.assertEqual(bad_seq1, (1, 2, 3, 4)) + + bad_seq2 = 'abcd' + with self.assertRaises(TypeError): + _testcapi.sequence_set_slice(bad_seq2, 1, 3, 'xy') + self.assertEqual(bad_seq2, 'abcd') + + # Not a sequence: + with self.assertRaises(TypeError): + _testcapi.sequence_set_slice(None, 1, 3, 'xy') + + mapping = {1: 'a', 2: 'b', 3: 'c'} + with self.assertRaises(TypeError): + _testcapi.sequence_set_slice(mapping, 1, 3, 'xy') + self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'}) + + def test_sequence_del_slice(self): + # Correct case: + data = [1, 2, 3, 4, 5] + data_copy = data.copy() + + _testcapi.sequence_del_slice(data, 1, 3) + del data_copy[1:3] + self.assertEqual(data, data_copy) + self.assertEqual(data, [1, 4, 5]) + + # Custom class: + class Custom: + def __delitem__(self, index): + self.index = index + + c = Custom() + _testcapi.sequence_del_slice(c, 0, 5) + self.assertEqual(c.index, slice(0, 5)) + + # Immutable sequences must raise: + bad_seq1 = (1, 2, 3, 4) + with self.assertRaises(TypeError): + _testcapi.sequence_del_slice(bad_seq1, 1, 3) + self.assertEqual(bad_seq1, (1, 2, 3, 4)) + + bad_seq2 = 'abcd' + with self.assertRaises(TypeError): + _testcapi.sequence_del_slice(bad_seq2, 1, 3) + self.assertEqual(bad_seq2, 'abcd') + + # Not a sequence: + with self.assertRaises(TypeError): + _testcapi.sequence_del_slice(None, 1, 3) + + mapping = {1: 'a', 2: 'b', 3: 'c'} + with self.assertRaises(TypeError): + _testcapi.sequence_del_slice(mapping, 1, 3) + self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'}) + @unittest.skipUnless(hasattr(_testcapi, 'negative_refcount'), 'need _testcapi.negative_refcount') def test_negative_refcount(self): @@ -488,7 +572,12 @@ class CAPITest(unittest.TestCase): del subclass_instance # Test that setting __class__ modified the reference counts of the types - self.assertEqual(type_refcnt - 1, B.refcnt_in_del) + if support.Py_DEBUG: + # gh-89373: In debug mode, _Py_Dealloc() keeps a strong reference + # to the type while calling tp_dealloc() + self.assertEqual(type_refcnt, B.refcnt_in_del) + else: + self.assertEqual(type_refcnt - 1, B.refcnt_in_del) self.assertEqual(new_type_refcnt + 1, A.refcnt_in_del) # Test that the original type already has decreased its refcnt @@ -507,6 +596,30 @@ class CAPITest(unittest.TestCase): inst = _testcapi.HeapCTypeWithDict() self.assertEqual({}, inst.__dict__) + def test_heaptype_with_managed_dict(self): + inst = _testcapi.HeapCTypeWithManagedDict() + inst.foo = 42 + self.assertEqual(inst.foo, 42) + self.assertEqual(inst.__dict__, {"foo": 42}) + + inst = _testcapi.HeapCTypeWithManagedDict() + self.assertEqual({}, inst.__dict__) + + a = _testcapi.HeapCTypeWithManagedDict() + b = _testcapi.HeapCTypeWithManagedDict() + a.b = b + b.a = a + del a, b + + def test_sublclassing_managed_dict(self): + + class C(_testcapi.HeapCTypeWithManagedDict): + pass + + i = C() + i.spam = i + del i + def test_heaptype_with_negative_dict(self): inst = _testcapi.HeapCTypeWithNegativeDict() inst.foo = 42 @@ -523,6 +636,37 @@ class CAPITest(unittest.TestCase): self.assertEqual(ref(), inst) self.assertEqual(inst.weakreflist, ref) + def test_heaptype_with_managed_weakref(self): + inst = _testcapi.HeapCTypeWithManagedWeakref() + ref = weakref.ref(inst) + self.assertEqual(ref(), inst) + + def test_sublclassing_managed_weakref(self): + + class C(_testcapi.HeapCTypeWithManagedWeakref): + pass + + inst = C() + ref = weakref.ref(inst) + self.assertEqual(ref(), inst) + + def test_sublclassing_managed_both(self): + + class C1(_testcapi.HeapCTypeWithManagedWeakref, _testcapi.HeapCTypeWithManagedDict): + pass + + class C2(_testcapi.HeapCTypeWithManagedDict, _testcapi.HeapCTypeWithManagedWeakref): + pass + + for cls in (C1, C2): + inst = cls() + ref = weakref.ref(inst) + self.assertEqual(ref(), inst) + inst.spam = inst + del inst + ref = weakref.ref(cls()) + self.assertIs(ref(), None) + def test_heaptype_with_buffer(self): inst = _testcapi.HeapCTypeWithBuffer() b = bytes(inst) @@ -553,7 +697,12 @@ class CAPITest(unittest.TestCase): del subclass_instance # Test that setting __class__ modified the reference counts of the types - self.assertEqual(type_refcnt - 1, _testcapi.HeapCTypeSubclassWithFinalizer.refcnt_in_del) + if support.Py_DEBUG: + # gh-89373: In debug mode, _Py_Dealloc() keeps a strong reference + # to the type while calling tp_dealloc() + self.assertEqual(type_refcnt, _testcapi.HeapCTypeSubclassWithFinalizer.refcnt_in_del) + else: + self.assertEqual(type_refcnt - 1, _testcapi.HeapCTypeSubclassWithFinalizer.refcnt_in_del) self.assertEqual(new_type_refcnt + 1, _testcapi.HeapCTypeSubclass.refcnt_in_del) # Test that the original type already has decreased its refcnt @@ -570,16 +719,121 @@ class CAPITest(unittest.TestCase): del obj.value self.assertEqual(obj.pvalue, 0) + def test_heaptype_with_custom_metaclass(self): + self.assertTrue(issubclass(_testcapi.HeapCTypeMetaclass, type)) + self.assertTrue(issubclass(_testcapi.HeapCTypeMetaclassCustomNew, type)) + + t = _testcapi.pytype_fromspec_meta(_testcapi.HeapCTypeMetaclass) + self.assertIsInstance(t, type) + self.assertEqual(t.__name__, "HeapCTypeViaMetaclass") + self.assertIs(type(t), _testcapi.HeapCTypeMetaclass) + + msg = "Metaclasses with custom tp_new are not supported." + with self.assertRaisesRegex(TypeError, msg): + t = _testcapi.pytype_fromspec_meta(_testcapi.HeapCTypeMetaclassCustomNew) + + def test_multiple_inheritance_ctypes_with_weakref_or_dict(self): + + with self.assertRaises(TypeError): + class Both1(_testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithDict): + pass + with self.assertRaises(TypeError): + class Both2(_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithWeakref): + pass + + def test_multiple_inheritance_ctypes_with_weakref_or_dict_and_other_builtin(self): + + with self.assertRaises(TypeError): + class C1(_testcapi.HeapCTypeWithDict, list): + pass + + with self.assertRaises(TypeError): + class C2(_testcapi.HeapCTypeWithWeakref, list): + pass + + class C3(_testcapi.HeapCTypeWithManagedDict, list): + pass + class C4(_testcapi.HeapCTypeWithManagedWeakref, list): + pass + + inst = C3() + inst.append(0) + str(inst.__dict__) + + inst = C4() + inst.append(0) + str(inst.__weakref__) + + for cls in (_testcapi.HeapCTypeWithManagedDict, _testcapi.HeapCTypeWithManagedWeakref): + for cls2 in (_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithWeakref): + class S(cls, cls2): + pass + class B1(C3, cls): + pass + class B2(C4, cls): + pass + + def test_pytype_fromspec_with_repeated_slots(self): + for variant in range(2): + with self.subTest(variant=variant): + with self.assertRaises(SystemError): + _testcapi.create_type_from_repeated_slots(variant) + + @warnings_helper.ignore_warnings(category=DeprecationWarning) + def test_immutable_type_with_mutable_base(self): + # Add deprecation warning here so it's removed in 3.14 + warnings._deprecated( + 'creating immutable classes with mutable bases', remove=(3, 14)) + + class MutableBase: + def meth(self): + return 'original' + + with self.assertWarns(DeprecationWarning): + ImmutableSubclass = _testcapi.make_immutable_type_with_base( + MutableBase) + instance = ImmutableSubclass() + + self.assertEqual(instance.meth(), 'original') + + # Cannot override the static type's method + with self.assertRaisesRegex( + TypeError, + "cannot set 'meth' attribute of immutable type"): + ImmutableSubclass.meth = lambda self: 'overridden' + self.assertEqual(instance.meth(), 'original') + + # Can change the method on the mutable base + MutableBase.meth = lambda self: 'changed' + self.assertEqual(instance.meth(), 'changed') + + def test_pynumber_tobase(self): from _testcapi import pynumber_tobase - self.assertEqual(pynumber_tobase(123, 2), '0b1111011') - self.assertEqual(pynumber_tobase(123, 8), '0o173') - self.assertEqual(pynumber_tobase(123, 10), '123') - self.assertEqual(pynumber_tobase(123, 16), '0x7b') - self.assertEqual(pynumber_tobase(-123, 2), '-0b1111011') - self.assertEqual(pynumber_tobase(-123, 8), '-0o173') - self.assertEqual(pynumber_tobase(-123, 10), '-123') - self.assertEqual(pynumber_tobase(-123, 16), '-0x7b') + small_number = 123 + large_number = 2**64 + class IDX: + def __init__(self, val): + self.val = val + def __index__(self): + return self.val + + test_cases = ((2, '0b1111011', '0b10000000000000000000000000000000000000000000000000000000000000000'), + (8, '0o173', '0o2000000000000000000000'), + (10, '123', '18446744073709551616'), + (16, '0x7b', '0x10000000000000000')) + for base, small_target, large_target in test_cases: + with self.subTest(base=base, st=small_target, lt=large_target): + # Test for small number + self.assertEqual(pynumber_tobase(small_number, base), small_target) + self.assertEqual(pynumber_tobase(-small_number, base), '-' + small_target) + self.assertEqual(pynumber_tobase(IDX(small_number), base), small_target) + # Test for large number(out of range of a longlong,i.e.[-2**63, 2**63-1]) + self.assertEqual(pynumber_tobase(large_number, base), large_target) + self.assertEqual(pynumber_tobase(-large_number, base), '-' + large_target) + self.assertEqual(pynumber_tobase(IDX(large_number), base), large_target) + self.assertRaises(TypeError, pynumber_tobase, IDX(123.0), 10) + self.assertRaises(TypeError, pynumber_tobase, IDX('123'), 10) self.assertRaises(TypeError, pynumber_tobase, 123.0, 10) self.assertRaises(TypeError, pynumber_tobase, '123', 10) self.assertRaises(SystemError, pynumber_tobase, 123, 0) @@ -605,6 +859,7 @@ class CAPITest(unittest.TestCase): self.assertNotIn(name, modules) self.assertEqual(len(modules), total) + @support.requires_subprocess() def test_fatal_error(self): # By default, stdlib extension modules are ignored, # but not test modules. @@ -635,6 +890,250 @@ class CAPITest(unittest.TestCase): s = _testcapi.pyobject_bytes_from_null() self.assertEqual(s, b'') + def test_Py_CompileString(self): + # Check that Py_CompileString respects the coding cookie + _compile = _testcapi.Py_CompileString + code = b"# -*- coding: latin1 -*-\nprint('\xc2\xa4')\n" + result = _compile(code) + expected = compile(code, "", "exec") + self.assertEqual(result.co_consts, expected.co_consts) + + def test_export_symbols(self): + # bpo-44133: Ensure that the "Py_FrozenMain" and + # "PyThread_get_thread_native_id" symbols are exported by the Python + # (directly by the binary, or via by the Python dynamic library). + ctypes = import_helper.import_module('ctypes') + names = [] + + # Test if the PY_HAVE_THREAD_NATIVE_ID macro is defined + if hasattr(_thread, 'get_native_id'): + names.append('PyThread_get_thread_native_id') + + # Python/frozenmain.c fails to build on Windows when the symbols are + # missing: + # - PyWinFreeze_ExeInit + # - PyWinFreeze_ExeTerm + # - PyInitFrozenExtensions + if os.name != 'nt': + names.append('Py_FrozenMain') + + for name in names: + with self.subTest(name=name): + self.assertTrue(hasattr(ctypes.pythonapi, name)) + + def test_clear_managed_dict(self): + + class C: + def __init__(self): + self.a = 1 + + c = C() + _testcapi.clear_managed_dict(c) + self.assertEqual(c.__dict__, {}) + c = C() + self.assertEqual(c.__dict__, {'a':1}) + _testcapi.clear_managed_dict(c) + self.assertEqual(c.__dict__, {}) + + def test_eval_get_func_name(self): + def function_example(): ... + + class A: + def method_example(self): ... + + self.assertEqual(_testcapi.eval_get_func_name(function_example), + "function_example") + self.assertEqual(_testcapi.eval_get_func_name(A.method_example), + "method_example") + self.assertEqual(_testcapi.eval_get_func_name(A().method_example), + "method_example") + self.assertEqual(_testcapi.eval_get_func_name(sum), "sum") # c function + self.assertEqual(_testcapi.eval_get_func_name(A), "type") + + def test_eval_get_func_desc(self): + def function_example(): ... + + class A: + def method_example(self): ... + + self.assertEqual(_testcapi.eval_get_func_desc(function_example), + "()") + self.assertEqual(_testcapi.eval_get_func_desc(A.method_example), + "()") + self.assertEqual(_testcapi.eval_get_func_desc(A().method_example), + "()") + self.assertEqual(_testcapi.eval_get_func_desc(sum), "()") # c function + self.assertEqual(_testcapi.eval_get_func_desc(A), " object") + + def test_function_get_code(self): + import types + + def some(): + pass + + code = _testcapi.function_get_code(some) + self.assertIsInstance(code, types.CodeType) + self.assertEqual(code, some.__code__) + + with self.assertRaises(SystemError): + _testcapi.function_get_code(None) # not a function + + def test_function_get_globals(self): + def some(): + pass + + globals_ = _testcapi.function_get_globals(some) + self.assertIsInstance(globals_, dict) + self.assertEqual(globals_, some.__globals__) + + with self.assertRaises(SystemError): + _testcapi.function_get_globals(None) # not a function + + def test_function_get_module(self): + def some(): + pass + + module = _testcapi.function_get_module(some) + self.assertIsInstance(module, str) + self.assertEqual(module, some.__module__) + + with self.assertRaises(SystemError): + _testcapi.function_get_module(None) # not a function + + def test_function_get_defaults(self): + def some( + pos_only1, pos_only2='p', + /, + zero=0, optional=None, + *, + kw1, + kw2=True, + ): + pass + + defaults = _testcapi.function_get_defaults(some) + self.assertEqual(defaults, ('p', 0, None)) + self.assertEqual(defaults, some.__defaults__) + + with self.assertRaises(SystemError): + _testcapi.function_get_defaults(None) # not a function + + def test_function_set_defaults(self): + def some( + pos_only1, pos_only2='p', + /, + zero=0, optional=None, + *, + kw1, + kw2=True, + ): + pass + + old_defaults = ('p', 0, None) + self.assertEqual(_testcapi.function_get_defaults(some), old_defaults) + self.assertEqual(some.__defaults__, old_defaults) + + with self.assertRaises(SystemError): + _testcapi.function_set_defaults(some, 1) # not tuple or None + self.assertEqual(_testcapi.function_get_defaults(some), old_defaults) + self.assertEqual(some.__defaults__, old_defaults) + + with self.assertRaises(SystemError): + _testcapi.function_set_defaults(1, ()) # not a function + self.assertEqual(_testcapi.function_get_defaults(some), old_defaults) + self.assertEqual(some.__defaults__, old_defaults) + + new_defaults = ('q', 1, None) + _testcapi.function_set_defaults(some, new_defaults) + self.assertEqual(_testcapi.function_get_defaults(some), new_defaults) + self.assertEqual(some.__defaults__, new_defaults) + + # Empty tuple is fine: + new_defaults = () + _testcapi.function_set_defaults(some, new_defaults) + self.assertEqual(_testcapi.function_get_defaults(some), new_defaults) + self.assertEqual(some.__defaults__, new_defaults) + + class tuplesub(tuple): ... # tuple subclasses must work + + new_defaults = tuplesub(((1, 2), ['a', 'b'], None)) + _testcapi.function_set_defaults(some, new_defaults) + self.assertEqual(_testcapi.function_get_defaults(some), new_defaults) + self.assertEqual(some.__defaults__, new_defaults) + + # `None` is special, it sets `defaults` to `NULL`, + # it needs special handling in `_testcapi`: + _testcapi.function_set_defaults(some, None) + self.assertEqual(_testcapi.function_get_defaults(some), None) + self.assertEqual(some.__defaults__, None) + + def test_function_get_kw_defaults(self): + def some( + pos_only1, pos_only2='p', + /, + zero=0, optional=None, + *, + kw1, + kw2=True, + ): + pass + + defaults = _testcapi.function_get_kw_defaults(some) + self.assertEqual(defaults, {'kw2': True}) + self.assertEqual(defaults, some.__kwdefaults__) + + with self.assertRaises(SystemError): + _testcapi.function_get_kw_defaults(None) # not a function + + def test_function_set_kw_defaults(self): + def some( + pos_only1, pos_only2='p', + /, + zero=0, optional=None, + *, + kw1, + kw2=True, + ): + pass + + old_defaults = {'kw2': True} + self.assertEqual(_testcapi.function_get_kw_defaults(some), old_defaults) + self.assertEqual(some.__kwdefaults__, old_defaults) + + with self.assertRaises(SystemError): + _testcapi.function_set_kw_defaults(some, 1) # not dict or None + self.assertEqual(_testcapi.function_get_kw_defaults(some), old_defaults) + self.assertEqual(some.__kwdefaults__, old_defaults) + + with self.assertRaises(SystemError): + _testcapi.function_set_kw_defaults(1, {}) # not a function + self.assertEqual(_testcapi.function_get_kw_defaults(some), old_defaults) + self.assertEqual(some.__kwdefaults__, old_defaults) + + new_defaults = {'kw2': (1, 2, 3)} + _testcapi.function_set_kw_defaults(some, new_defaults) + self.assertEqual(_testcapi.function_get_kw_defaults(some), new_defaults) + self.assertEqual(some.__kwdefaults__, new_defaults) + + # Empty dict is fine: + new_defaults = {} + _testcapi.function_set_kw_defaults(some, new_defaults) + self.assertEqual(_testcapi.function_get_kw_defaults(some), new_defaults) + self.assertEqual(some.__kwdefaults__, new_defaults) + + class dictsub(dict): ... # dict subclasses must work + + new_defaults = dictsub({'kw2': None}) + _testcapi.function_set_kw_defaults(some, new_defaults) + self.assertEqual(_testcapi.function_get_kw_defaults(some), new_defaults) + self.assertEqual(some.__kwdefaults__, new_defaults) + + # `None` is special, it sets `kwdefaults` to `NULL`, + # it needs special handling in `_testcapi`: + _testcapi.function_set_kw_defaults(some, None) + self.assertEqual(_testcapi.function_get_kw_defaults(some), None) + self.assertEqual(some.__kwdefaults__, None) + class TestPendingCalls(unittest.TestCase): @@ -672,6 +1171,7 @@ class TestPendingCalls(unittest.TestCase): if False and support.verbose: print("(%i)"%(len(l),)) + @threading_helper.requires_working_threading() def test_pendingcalls_threaded(self): #do every callback on a separate thread @@ -717,6 +1217,7 @@ class TestPendingCalls(unittest.TestCase): class SubinterpreterTest(unittest.TestCase): + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_subinterps(self): import builtins r, w = os.pipe() @@ -732,6 +1233,7 @@ class SubinterpreterTest(unittest.TestCase): self.assertNotEqual(pickle.load(f), id(sys.modules)) self.assertNotEqual(pickle.load(f), id(builtins)) + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_subinterps_recent_language_features(self): r, w = os.pipe() code = """if 1: @@ -753,6 +1255,79 @@ class SubinterpreterTest(unittest.TestCase): self.assertEqual(ret, 0) self.assertEqual(pickle.load(f), {'a': '123x', 'b': '123'}) + def test_py_config_isoloated_per_interpreter(self): + # A config change in one interpreter must not leak to out to others. + # + # This test could verify ANY config value, it just happens to have been + # written around the time of int_max_str_digits. Refactoring is okay. + code = """if 1: + import sys, _testinternalcapi + + # Any config value would do, this happens to be the one being + # double checked at the time this test was written. + config = _testinternalcapi.get_config() + config['int_max_str_digits'] = 55555 + _testinternalcapi.set_config(config) + sub_value = _testinternalcapi.get_config()['int_max_str_digits'] + assert sub_value == 55555, sub_value + """ + before_config = _testinternalcapi.get_config() + assert before_config['int_max_str_digits'] != 55555 + self.assertEqual(support.run_in_subinterp(code), 0, + 'subinterp code failure, check stderr.') + after_config = _testinternalcapi.get_config() + self.assertIsNot( + before_config, after_config, + "Expected get_config() to return a new dict on each call") + self.assertEqual(before_config, after_config, + "CAUTION: Tests executed after this may be " + "running under an altered config.") + # try:...finally: calling set_config(before_config) not done + # as that results in sys.argv, sys.path, and sys.warnoptions + # "being modified by test_capi" per test.regrtest. So if this + # test fails, assume that the environment in this process may + # be altered and suspect. + + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") + def test_configured_settings(self): + """ + The config with which an interpreter is created corresponds + 1-to-1 with the new interpreter's settings. This test verifies + that they match. + """ + import json + + THREADS = 1<<10 + DAEMON_THREADS = 1<<11 + FORK = 1<<15 + EXEC = 1<<16 + + features = ['fork', 'exec', 'threads', 'daemon_threads'] + kwlist = [f'allow_{n}' for n in features] + for config, expected in { + (True, True, True, True): FORK | EXEC | THREADS | DAEMON_THREADS, + (False, False, False, False): 0, + (False, False, True, False): THREADS, + }.items(): + kwargs = dict(zip(kwlist, config)) + expected = { + 'feature_flags': expected, + } + with self.subTest(config): + r, w = os.pipe() + script = textwrap.dedent(f''' + import _testinternalcapi, json, os + settings = _testinternalcapi.get_interp_settings() + with os.fdopen({w}, "w") as stdin: + json.dump(settings, stdin) + ''') + with os.fdopen(r) as stdout: + support.run_in_subinterp_with_config(script, **kwargs) + out = stdout.read() + settings = json.loads(out) + + self.assertEqual(settings, expected) + def test_mutate_exception(self): """ Exceptions saved in global module state get shared between @@ -766,6 +1341,7 @@ class SubinterpreterTest(unittest.TestCase): self.assertFalse(hasattr(binascii.Error, "foobar")) + @unittest.skipIf(_testmultiphase is None, "test requires _testmultiphase module") def test_module_state_shared_in_global(self): """ bpo-44050: Extension module state should be shared between interpreters @@ -801,6 +1377,7 @@ class SubinterpreterTest(unittest.TestCase): class TestThreadState(unittest.TestCase): @threading_helper.reap_threads + @threading_helper.requires_working_threading() def test_thread_state(self): # some extra thread-state tests driven via _testcapi def target(): @@ -821,6 +1398,21 @@ class TestThreadState(unittest.TestCase): t.start() t.join() + @threading_helper.reap_threads + @threading_helper.requires_working_threading() + def test_gilstate_ensure_no_deadlock(self): + # See https://github.com/python/cpython/issues/96071 + code = textwrap.dedent(f""" + import _testcapi + + def callback(): + print('callback called') + + _testcapi._test_thread_state(callback) + """) + ret = assert_python_ok('-X', 'tracemalloc', '-c', code) + self.assertIn(b'callback called', ret.out) + class Test_testcapi(unittest.TestCase): locals().update((name, getattr(_testcapi, name)) @@ -832,6 +1424,9 @@ class Test_testcapi(unittest.TestCase): def test_widechar(self): _testcapi.test_widechar() + def test_version_api_data(self): + self.assertEqual(_testcapi.Py_Version, sys.hexversion) + class Test_testinternalcapi(unittest.TestCase): locals().update((name, getattr(_testinternalcapi, name)) @@ -839,114 +1434,7 @@ class Test_testinternalcapi(unittest.TestCase): if name.startswith('test_')) -class PyMemDebugTests(unittest.TestCase): - PYTHONMALLOC = 'debug' - # '0x04c06e0' or '04C06E0' - PTR_REGEX = r'(?:0x)?[0-9a-fA-F]+' - - def check(self, code): - with support.SuppressCrashReport(): - out = assert_python_failure('-c', code, - PYTHONMALLOC=self.PYTHONMALLOC) - stderr = out.err - return stderr.decode('ascii', 'replace') - - def test_buffer_overflow(self): - out = self.check('import _testcapi; _testcapi.pymem_buffer_overflow()') - regex = (r"Debug memory block at address p={ptr}: API 'm'\n" - r" 16 bytes originally requested\n" - r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n" - r" The [0-9] pad bytes at tail={ptr} are not all FORBIDDENBYTE \(0x[0-9a-f]{{2}}\):\n" - r" at tail\+0: 0x78 \*\*\* OUCH\n" - r" at tail\+1: 0xfd\n" - r" at tail\+2: 0xfd\n" - r" .*\n" - r"( The block was made by call #[0-9]+ to debug malloc/realloc.\n)?" - r" Data at p: cd cd cd .*\n" - r"\n" - r"Enable tracemalloc to get the memory block allocation traceback\n" - r"\n" - r"Fatal Python error: _PyMem_DebugRawFree: bad trailing pad byte") - regex = regex.format(ptr=self.PTR_REGEX) - regex = re.compile(regex, flags=re.DOTALL) - self.assertRegex(out, regex) - - def test_api_misuse(self): - out = self.check('import _testcapi; _testcapi.pymem_api_misuse()') - regex = (r"Debug memory block at address p={ptr}: API 'm'\n" - r" 16 bytes originally requested\n" - r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n" - r" The [0-9] pad bytes at tail={ptr} are FORBIDDENBYTE, as expected.\n" - r"( The block was made by call #[0-9]+ to debug malloc/realloc.\n)?" - r" Data at p: cd cd cd .*\n" - r"\n" - r"Enable tracemalloc to get the memory block allocation traceback\n" - r"\n" - r"Fatal Python error: _PyMem_DebugRawFree: bad ID: Allocated using API 'm', verified using API 'r'\n") - regex = regex.format(ptr=self.PTR_REGEX) - self.assertRegex(out, regex) - - def check_malloc_without_gil(self, code): - out = self.check(code) - expected = ('Fatal Python error: _PyMem_DebugMalloc: ' - 'Python memory allocator called without holding the GIL') - self.assertIn(expected, out) - - def test_pymem_malloc_without_gil(self): - # Debug hooks must raise an error if PyMem_Malloc() is called - # without holding the GIL - code = 'import _testcapi; _testcapi.pymem_malloc_without_gil()' - self.check_malloc_without_gil(code) - - def test_pyobject_malloc_without_gil(self): - # Debug hooks must raise an error if PyObject_Malloc() is called - # without holding the GIL - code = 'import _testcapi; _testcapi.pyobject_malloc_without_gil()' - self.check_malloc_without_gil(code) - - def check_pyobject_is_freed(self, func_name): - code = textwrap.dedent(f''' - import gc, os, sys, _testcapi - # Disable the GC to avoid crash on GC collection - gc.disable() - try: - _testcapi.{func_name}() - # Exit immediately to avoid a crash while deallocating - # the invalid object - os._exit(0) - except _testcapi.error: - os._exit(1) - ''') - assert_python_ok('-c', code, PYTHONMALLOC=self.PYTHONMALLOC) - - def test_pyobject_null_is_freed(self): - self.check_pyobject_is_freed('check_pyobject_null_is_freed') - - def test_pyobject_uninitialized_is_freed(self): - self.check_pyobject_is_freed('check_pyobject_uninitialized_is_freed') - - def test_pyobject_forbidden_bytes_is_freed(self): - self.check_pyobject_is_freed('check_pyobject_forbidden_bytes_is_freed') - - def test_pyobject_freed_is_freed(self): - self.check_pyobject_is_freed('check_pyobject_freed_is_freed') - - -class PyMemMallocDebugTests(PyMemDebugTests): - PYTHONMALLOC = 'malloc_debug' - - -@unittest.skipUnless(support.with_pymalloc(), 'need pymalloc') -class PyMemPymallocDebugTests(PyMemDebugTests): - PYTHONMALLOC = 'pymalloc_debug' - - -@unittest.skipUnless(Py_DEBUG, 'need Py_DEBUG') -class PyMemDefaultTests(PyMemDebugTests): - # test default allocator of Python compiled in debug mode - PYTHONMALLOC = '' - - +@unittest.skipIf(_testmultiphase is None, "test requires _testmultiphase module") class Test_ModuleStateAccess(unittest.TestCase): """Test access to module start (PEP 573)""" @@ -1017,13 +1505,49 @@ class Test_ModuleStateAccess(unittest.TestCase): with self.assertRaises(TypeError): increment_count(1, 2, 3) - def test_Py_CompileString(self): - # Check that Py_CompileString respects the coding cookie - _compile = _testcapi.Py_CompileString - code = b"# -*- coding: latin1 -*-\nprint('\xc2\xa4')\n" - result = _compile(code) - expected = compile(code, "", "exec") - self.assertEqual(result.co_consts, expected.co_consts) + def test_get_module_bad_def(self): + # PyType_GetModuleByDef fails gracefully if it doesn't + # find what it's looking for. + # see bpo-46433 + instance = self.module.StateAccessType() + with self.assertRaises(TypeError): + instance.getmodulebydef_bad_def() + + def test_get_module_static_in_mro(self): + # Here, the class PyType_GetModuleByDef is looking for + # appears in the MRO after a static type (Exception). + # see bpo-46433 + class Subclass(BaseException, self.module.StateAccessType): + pass + self.assertIs(Subclass().get_defining_module(), self.module) + + +SUFFICIENT_TO_DEOPT_AND_SPECIALIZE = 100 + +class Test_Pep523API(unittest.TestCase): + + def do_test(self, func): + calls = [] + start = SUFFICIENT_TO_DEOPT_AND_SPECIALIZE + count = start + SUFFICIENT_TO_DEOPT_AND_SPECIALIZE + for i in range(count): + if i == start: + _testinternalcapi.set_eval_frame_record(calls) + func() + _testinternalcapi.set_eval_frame_default() + self.assertEqual(len(calls), SUFFICIENT_TO_DEOPT_AND_SPECIALIZE) + for name in calls: + self.assertEqual(name, func.__name__) + + def test_pep523_with_specialization_simple(self): + def func1(): + pass + self.do_test(func1) + + def test_pep523_with_specialization_with_default(self): + def func2(x=None): + pass + self.do_test(func2) if __name__ == "__main__": diff --git a/Lib/test/test_structmembers.py b/Lib/test/test_capi/test_structmembers.py similarity index 66% rename from Lib/test/test_structmembers.py rename to Lib/test/test_capi/test_structmembers.py index 07d2f623f71..2cf46b20347 100644 --- a/Lib/test/test_structmembers.py +++ b/Lib/test/test_capi/test_structmembers.py @@ -4,32 +4,42 @@ from test.support import warnings_helper # Skip this test if the _testcapi module isn't available. import_helper.import_module('_testcapi') -from _testcapi import _test_structmembersType, \ - CHAR_MAX, CHAR_MIN, UCHAR_MAX, \ - SHRT_MAX, SHRT_MIN, USHRT_MAX, \ - INT_MAX, INT_MIN, UINT_MAX, \ - LONG_MAX, LONG_MIN, ULONG_MAX, \ - LLONG_MAX, LLONG_MIN, ULLONG_MAX, \ - PY_SSIZE_T_MAX, PY_SSIZE_T_MIN +from _testcapi import (_test_structmembersType_OldAPI, + _test_structmembersType_NewAPI, + CHAR_MAX, CHAR_MIN, UCHAR_MAX, + SHRT_MAX, SHRT_MIN, USHRT_MAX, + INT_MAX, INT_MIN, UINT_MAX, + LONG_MAX, LONG_MIN, ULONG_MAX, + LLONG_MAX, LLONG_MIN, ULLONG_MAX, + PY_SSIZE_T_MAX, PY_SSIZE_T_MIN, + ) -ts=_test_structmembersType(False, # T_BOOL - 1, # T_BYTE - 2, # T_UBYTE - 3, # T_SHORT - 4, # T_USHORT - 5, # T_INT - 6, # T_UINT - 7, # T_LONG - 8, # T_ULONG - 23, # T_PYSSIZET - 9.99999,# T_FLOAT - 10.1010101010, # T_DOUBLE - "hi" # T_STRING_INPLACE - ) +# There are two classes: one using and another using +# `Py_`-prefixed API. They should behave the same in Python -class ReadWriteTests(unittest.TestCase): +def _make_test_object(cls): + return cls(False, # T_BOOL + 1, # T_BYTE + 2, # T_UBYTE + 3, # T_SHORT + 4, # T_USHORT + 5, # T_INT + 6, # T_UINT + 7, # T_LONG + 8, # T_ULONG + 23, # T_PYSSIZET + 9.99999,# T_FLOAT + 10.1010101010, # T_DOUBLE + "hi", # T_STRING_INPLACE + ) + + +class ReadWriteTests: + def setUp(self): + self.ts = _make_test_object(self.cls) def test_bool(self): + ts = self.ts ts.T_BOOL = True self.assertEqual(ts.T_BOOL, True) ts.T_BOOL = False @@ -37,6 +47,7 @@ class ReadWriteTests(unittest.TestCase): self.assertRaises(TypeError, setattr, ts, 'T_BOOL', 1) def test_byte(self): + ts = self.ts ts.T_BYTE = CHAR_MAX self.assertEqual(ts.T_BYTE, CHAR_MAX) ts.T_BYTE = CHAR_MIN @@ -45,6 +56,7 @@ class ReadWriteTests(unittest.TestCase): self.assertEqual(ts.T_UBYTE, UCHAR_MAX) def test_short(self): + ts = self.ts ts.T_SHORT = SHRT_MAX self.assertEqual(ts.T_SHORT, SHRT_MAX) ts.T_SHORT = SHRT_MIN @@ -53,6 +65,7 @@ class ReadWriteTests(unittest.TestCase): self.assertEqual(ts.T_USHORT, USHRT_MAX) def test_int(self): + ts = self.ts ts.T_INT = INT_MAX self.assertEqual(ts.T_INT, INT_MAX) ts.T_INT = INT_MIN @@ -61,6 +74,7 @@ class ReadWriteTests(unittest.TestCase): self.assertEqual(ts.T_UINT, UINT_MAX) def test_long(self): + ts = self.ts ts.T_LONG = LONG_MAX self.assertEqual(ts.T_LONG, LONG_MAX) ts.T_LONG = LONG_MIN @@ -69,13 +83,17 @@ class ReadWriteTests(unittest.TestCase): self.assertEqual(ts.T_ULONG, ULONG_MAX) def test_py_ssize_t(self): + ts = self.ts ts.T_PYSSIZET = PY_SSIZE_T_MAX self.assertEqual(ts.T_PYSSIZET, PY_SSIZE_T_MAX) ts.T_PYSSIZET = PY_SSIZE_T_MIN self.assertEqual(ts.T_PYSSIZET, PY_SSIZE_T_MIN) - @unittest.skipUnless(hasattr(ts, "T_LONGLONG"), "long long not present") def test_longlong(self): + ts = self.ts + if not hasattr(ts, "T_LONGLONG"): + self.skipTest("long long not present") + ts.T_LONGLONG = LLONG_MAX self.assertEqual(ts.T_LONGLONG, LLONG_MAX) ts.T_LONGLONG = LLONG_MIN @@ -91,6 +109,7 @@ class ReadWriteTests(unittest.TestCase): self.assertEqual(ts.T_ULONGLONG, 4) def test_bad_assignments(self): + ts = self.ts integer_attributes = [ 'T_BOOL', 'T_BYTE', 'T_UBYTE', @@ -109,37 +128,57 @@ class ReadWriteTests(unittest.TestCase): self.assertRaises(TypeError, setattr, ts, attr, nonint) def test_inplace_string(self): + ts = self.ts self.assertEqual(ts.T_STRING_INPLACE, "hi") self.assertRaises(TypeError, setattr, ts, "T_STRING_INPLACE", "s") self.assertRaises(TypeError, delattr, ts, "T_STRING_INPLACE") +class ReadWriteTests_OldAPI(ReadWriteTests, unittest.TestCase): + cls = _test_structmembersType_OldAPI -class TestWarnings(unittest.TestCase): +class ReadWriteTests_NewAPI(ReadWriteTests, unittest.TestCase): + cls = _test_structmembersType_NewAPI + +class TestWarnings: + def setUp(self): + self.ts = _make_test_object(self.cls) def test_byte_max(self): + ts = self.ts with warnings_helper.check_warnings(('', RuntimeWarning)): ts.T_BYTE = CHAR_MAX+1 def test_byte_min(self): + ts = self.ts with warnings_helper.check_warnings(('', RuntimeWarning)): ts.T_BYTE = CHAR_MIN-1 def test_ubyte_max(self): + ts = self.ts with warnings_helper.check_warnings(('', RuntimeWarning)): ts.T_UBYTE = UCHAR_MAX+1 def test_short_max(self): + ts = self.ts with warnings_helper.check_warnings(('', RuntimeWarning)): ts.T_SHORT = SHRT_MAX+1 def test_short_min(self): + ts = self.ts with warnings_helper.check_warnings(('', RuntimeWarning)): ts.T_SHORT = SHRT_MIN-1 def test_ushort_max(self): + ts = self.ts with warnings_helper.check_warnings(('', RuntimeWarning)): ts.T_USHORT = USHRT_MAX+1 +class TestWarnings_OldAPI(TestWarnings, unittest.TestCase): + cls = _test_structmembersType_OldAPI + +class TestWarnings_NewAPI(TestWarnings, unittest.TestCase): + cls = _test_structmembersType_NewAPI + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_capi/test_unicode.py b/Lib/test/test_capi/test_unicode.py new file mode 100644 index 00000000000..857579f7583 --- /dev/null +++ b/Lib/test/test_capi/test_unicode.py @@ -0,0 +1,918 @@ +import unittest +import sys +from test import support +from test.support import import_helper + +try: + import _testcapi +except ImportError: + _testcapi = None + + +NULL = None + +class Str(str): + pass + + +class CAPITest(unittest.TestCase): + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_fromobject(self): + """Test PyUnicode_FromObject()""" + from _testcapi import unicode_fromobject as fromobject + + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600', + 'a\ud800b\udfffc', '\ud834\udd1e']: + self.assertEqual(fromobject(s), s) + o = Str(s) + s2 = fromobject(o) + self.assertEqual(s2, s) + self.assertIs(type(s2), str) + self.assertIsNot(s2, s) + + self.assertRaises(TypeError, fromobject, b'abc') + self.assertRaises(TypeError, fromobject, []) + # CRASHES fromobject(NULL) + + def test_from_format(self): + """Test PyUnicode_FromFormat()""" + import_helper.import_module('ctypes') + from ctypes import ( + c_char_p, + pythonapi, py_object, sizeof, + c_int, c_long, c_longlong, c_ssize_t, + c_uint, c_ulong, c_ulonglong, c_size_t, c_void_p) + name = "PyUnicode_FromFormat" + _PyUnicode_FromFormat = getattr(pythonapi, name) + _PyUnicode_FromFormat.argtypes = (c_char_p,) + _PyUnicode_FromFormat.restype = py_object + + def PyUnicode_FromFormat(format, *args): + cargs = tuple( + py_object(arg) if isinstance(arg, str) else arg + for arg in args) + return _PyUnicode_FromFormat(format, *cargs) + + def check_format(expected, format, *args): + text = PyUnicode_FromFormat(format, *args) + self.assertEqual(expected, text) + + # ascii format, non-ascii argument + check_format('ascii\x7f=unicode\xe9', + b'ascii\x7f=%U', 'unicode\xe9') + + # non-ascii format, ascii argument: ensure that PyUnicode_FromFormatV() + # raises an error + self.assertRaisesRegex(ValueError, + r'^PyUnicode_FromFormatV\(\) expects an ASCII-encoded format ' + 'string, got a non-ASCII byte: 0xe9$', + PyUnicode_FromFormat, b'unicode\xe9=%s', 'ascii') + + # test "%c" + check_format('\uabcd', + b'%c', c_int(0xabcd)) + check_format('\U0010ffff', + b'%c', c_int(0x10ffff)) + with self.assertRaises(OverflowError): + PyUnicode_FromFormat(b'%c', c_int(0x110000)) + # Issue #18183 + check_format('\U00010000\U00100000', + b'%c%c', c_int(0x10000), c_int(0x100000)) + + # test "%" + check_format('%', + b'%%') + check_format('%s', + b'%%s') + check_format('[%]', + b'[%%]') + check_format('%abc', + b'%%%s', b'abc') + + # truncated string + check_format('abc', + b'%.3s', b'abcdef') + check_format('abc[\ufffd', + b'%.5s', 'abc[\u20ac]'.encode('utf8')) + check_format("'\\u20acABC'", + b'%A', '\u20acABC') + check_format("'\\u20", + b'%.5A', '\u20acABCDEF') + check_format("'\u20acABC'", + b'%R', '\u20acABC') + check_format("'\u20acA", + b'%.3R', '\u20acABCDEF') + check_format('\u20acAB', + b'%.3S', '\u20acABCDEF') + check_format('\u20acAB', + b'%.3U', '\u20acABCDEF') + check_format('\u20acAB', + b'%.3V', '\u20acABCDEF', None) + check_format('abc[\ufffd', + b'%.5V', None, 'abc[\u20ac]'.encode('utf8')) + + # following tests comes from #7330 + # test width modifier and precision modifier with %S + check_format("repr= abc", + b'repr=%5S', 'abc') + check_format("repr=ab", + b'repr=%.2S', 'abc') + check_format("repr= ab", + b'repr=%5.2S', 'abc') + + # test width modifier and precision modifier with %R + check_format("repr= 'abc'", + b'repr=%8R', 'abc') + check_format("repr='ab", + b'repr=%.3R', 'abc') + check_format("repr= 'ab", + b'repr=%5.3R', 'abc') + + # test width modifier and precision modifier with %A + check_format("repr= 'abc'", + b'repr=%8A', 'abc') + check_format("repr='ab", + b'repr=%.3A', 'abc') + check_format("repr= 'ab", + b'repr=%5.3A', 'abc') + + # test width modifier and precision modifier with %s + check_format("repr= abc", + b'repr=%5s', b'abc') + check_format("repr=ab", + b'repr=%.2s', b'abc') + check_format("repr= ab", + b'repr=%5.2s', b'abc') + + # test width modifier and precision modifier with %U + check_format("repr= abc", + b'repr=%5U', 'abc') + check_format("repr=ab", + b'repr=%.2U', 'abc') + check_format("repr= ab", + b'repr=%5.2U', 'abc') + + # test width modifier and precision modifier with %V + check_format("repr= abc", + b'repr=%5V', 'abc', b'123') + check_format("repr=ab", + b'repr=%.2V', 'abc', b'123') + check_format("repr= ab", + b'repr=%5.2V', 'abc', b'123') + check_format("repr= 123", + b'repr=%5V', None, b'123') + check_format("repr=12", + b'repr=%.2V', None, b'123') + check_format("repr= 12", + b'repr=%5.2V', None, b'123') + + # test integer formats (%i, %d, %u) + check_format('010', + b'%03i', c_int(10)) + check_format('0010', + b'%0.4i', c_int(10)) + check_format('-123', + b'%i', c_int(-123)) + check_format('-123', + b'%li', c_long(-123)) + check_format('-123', + b'%lli', c_longlong(-123)) + check_format('-123', + b'%zi', c_ssize_t(-123)) + + check_format('-123', + b'%d', c_int(-123)) + check_format('-123', + b'%ld', c_long(-123)) + check_format('-123', + b'%lld', c_longlong(-123)) + check_format('-123', + b'%zd', c_ssize_t(-123)) + + check_format('123', + b'%u', c_uint(123)) + check_format('123', + b'%lu', c_ulong(123)) + check_format('123', + b'%llu', c_ulonglong(123)) + check_format('123', + b'%zu', c_size_t(123)) + + # test long output + min_longlong = -(2 ** (8 * sizeof(c_longlong) - 1)) + max_longlong = -min_longlong - 1 + check_format(str(min_longlong), + b'%lld', c_longlong(min_longlong)) + check_format(str(max_longlong), + b'%lld', c_longlong(max_longlong)) + max_ulonglong = 2 ** (8 * sizeof(c_ulonglong)) - 1 + check_format(str(max_ulonglong), + b'%llu', c_ulonglong(max_ulonglong)) + PyUnicode_FromFormat(b'%p', c_void_p(-1)) + + # test padding (width and/or precision) + check_format('123'.rjust(10, '0'), + b'%010i', c_int(123)) + check_format('123'.rjust(100), + b'%100i', c_int(123)) + check_format('123'.rjust(100, '0'), + b'%.100i', c_int(123)) + check_format('123'.rjust(80, '0').rjust(100), + b'%100.80i', c_int(123)) + + check_format('123'.rjust(10, '0'), + b'%010u', c_uint(123)) + check_format('123'.rjust(100), + b'%100u', c_uint(123)) + check_format('123'.rjust(100, '0'), + b'%.100u', c_uint(123)) + check_format('123'.rjust(80, '0').rjust(100), + b'%100.80u', c_uint(123)) + + check_format('123'.rjust(10, '0'), + b'%010x', c_int(0x123)) + check_format('123'.rjust(100), + b'%100x', c_int(0x123)) + check_format('123'.rjust(100, '0'), + b'%.100x', c_int(0x123)) + check_format('123'.rjust(80, '0').rjust(100), + b'%100.80x', c_int(0x123)) + + # test %A + check_format(r"%A:'abc\xe9\uabcd\U0010ffff'", + b'%%A:%A', 'abc\xe9\uabcd\U0010ffff') + + # test %V + check_format('repr=abc', + b'repr=%V', 'abc', b'xyz') + + # test %p + # We cannot test the exact result, + # because it returns a hex representation of a C pointer, + # which is going to be different each time. But, we can test the format. + p_format_regex = r'^0x[a-zA-Z0-9]{3,}$' + p_format1 = PyUnicode_FromFormat(b'%p', 'abc') + self.assertIsInstance(p_format1, str) + self.assertRegex(p_format1, p_format_regex) + + p_format2 = PyUnicode_FromFormat(b'%p %p', '123456', b'xyz') + self.assertIsInstance(p_format2, str) + self.assertRegex(p_format2, + r'0x[a-zA-Z0-9]{3,} 0x[a-zA-Z0-9]{3,}') + + # Extra args are ignored: + p_format3 = PyUnicode_FromFormat(b'%p', '123456', None, b'xyz') + self.assertIsInstance(p_format3, str) + self.assertRegex(p_format3, p_format_regex) + + # Test string decode from parameter of %s using utf-8. + # b'\xe4\xba\xba\xe6\xb0\x91' is utf-8 encoded byte sequence of + # '\u4eba\u6c11' + check_format('repr=\u4eba\u6c11', + b'repr=%V', None, b'\xe4\xba\xba\xe6\xb0\x91') + + #Test replace error handler. + check_format('repr=abc\ufffd', + b'repr=%V', None, b'abc\xff') + + # Issue #33817: empty strings + check_format('', + b'') + check_format('', + b'%s', b'') + + # check for crashes + for fmt in (b'%', b'%0', b'%01', b'%.', b'%.1', + b'%0%s', b'%1%s', b'%.%s', b'%.1%s', b'%1abc', + b'%l', b'%ll', b'%z', b'%ls', b'%lls', b'%zs'): + with self.subTest(fmt=fmt): + self.assertRaisesRegex(SystemError, 'invalid format string', + PyUnicode_FromFormat, fmt, b'abc') + self.assertRaisesRegex(SystemError, 'invalid format string', + PyUnicode_FromFormat, b'%+i', c_int(10)) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_aswidechar(self): + """Test PyUnicode_AsWideChar()""" + from _testcapi import unicode_aswidechar + import_helper.import_module('ctypes') + from ctypes import c_wchar, sizeof + + wchar, size = unicode_aswidechar('abcdef', 2) + self.assertEqual(size, 2) + self.assertEqual(wchar, 'ab') + + wchar, size = unicode_aswidechar('abc', 3) + self.assertEqual(size, 3) + self.assertEqual(wchar, 'abc') + + wchar, size = unicode_aswidechar('abc', 4) + self.assertEqual(size, 3) + self.assertEqual(wchar, 'abc\0') + + wchar, size = unicode_aswidechar('abc', 10) + self.assertEqual(size, 3) + self.assertEqual(wchar, 'abc\0') + + wchar, size = unicode_aswidechar('abc\0def', 20) + self.assertEqual(size, 7) + self.assertEqual(wchar, 'abc\0def\0') + + nonbmp = chr(0x10ffff) + if sizeof(c_wchar) == 2: + buflen = 3 + nchar = 2 + else: # sizeof(c_wchar) == 4 + buflen = 2 + nchar = 1 + wchar, size = unicode_aswidechar(nonbmp, buflen) + self.assertEqual(size, nchar) + self.assertEqual(wchar, nonbmp + '\0') + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_aswidecharstring(self): + """Test PyUnicode_AsWideCharString()""" + from _testcapi import unicode_aswidecharstring + import_helper.import_module('ctypes') + from ctypes import c_wchar, sizeof + + wchar, size = unicode_aswidecharstring('abc') + self.assertEqual(size, 3) + self.assertEqual(wchar, 'abc\0') + + wchar, size = unicode_aswidecharstring('abc\0def') + self.assertEqual(size, 7) + self.assertEqual(wchar, 'abc\0def\0') + + nonbmp = chr(0x10ffff) + if sizeof(c_wchar) == 2: + nchar = 2 + else: # sizeof(c_wchar) == 4 + nchar = 1 + wchar, size = unicode_aswidecharstring(nonbmp) + self.assertEqual(size, nchar) + self.assertEqual(wchar, nonbmp + '\0') + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_asucs4(self): + """Test PyUnicode_AsUCS4()""" + from _testcapi import unicode_asucs4 + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600', + 'a\ud800b\udfffc', '\ud834\udd1e']: + l = len(s) + self.assertEqual(unicode_asucs4(s, l, True), s+'\0') + self.assertEqual(unicode_asucs4(s, l, False), s+'\uffff') + self.assertEqual(unicode_asucs4(s, l+1, True), s+'\0\uffff') + self.assertEqual(unicode_asucs4(s, l+1, False), s+'\0\uffff') + self.assertRaises(SystemError, unicode_asucs4, s, l-1, True) + self.assertRaises(SystemError, unicode_asucs4, s, l-2, False) + s = '\0'.join([s, s]) + self.assertEqual(unicode_asucs4(s, len(s), True), s+'\0') + self.assertEqual(unicode_asucs4(s, len(s), False), s+'\uffff') + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_asutf8(self): + """Test PyUnicode_AsUTF8()""" + from _testcapi import unicode_asutf8 + + bmp = '\u0100' + bmp2 = '\uffff' + nonbmp = chr(0x10ffff) + + self.assertEqual(unicode_asutf8(bmp), b'\xc4\x80') + self.assertEqual(unicode_asutf8(bmp2), b'\xef\xbf\xbf') + self.assertEqual(unicode_asutf8(nonbmp), b'\xf4\x8f\xbf\xbf') + self.assertRaises(UnicodeEncodeError, unicode_asutf8, 'a\ud800b\udfffc') + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_asutf8andsize(self): + """Test PyUnicode_AsUTF8AndSize()""" + from _testcapi import unicode_asutf8andsize + + bmp = '\u0100' + bmp2 = '\uffff' + nonbmp = chr(0x10ffff) + + self.assertEqual(unicode_asutf8andsize(bmp), (b'\xc4\x80', 2)) + self.assertEqual(unicode_asutf8andsize(bmp2), (b'\xef\xbf\xbf', 3)) + self.assertEqual(unicode_asutf8andsize(nonbmp), (b'\xf4\x8f\xbf\xbf', 4)) + self.assertRaises(UnicodeEncodeError, unicode_asutf8andsize, 'a\ud800b\udfffc') + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_concat(self): + """Test PyUnicode_Concat()""" + from _testcapi import unicode_concat as concat + + self.assertEqual(concat('abc', 'def'), 'abcdef') + self.assertEqual(concat('abc', 'где'), 'abcгде') + self.assertEqual(concat('абв', 'def'), 'абвdef') + self.assertEqual(concat('абв', 'где'), 'абвгде') + self.assertEqual(concat('a\0b', 'c\0d'), 'a\0bc\0d') + + self.assertRaises(TypeError, concat, b'abc', 'def') + self.assertRaises(TypeError, concat, 'abc', b'def') + self.assertRaises(TypeError, concat, b'abc', b'def') + self.assertRaises(TypeError, concat, [], 'def') + self.assertRaises(TypeError, concat, 'abc', []) + self.assertRaises(TypeError, concat, [], []) + # CRASHES concat(NULL, 'def') + # CRASHES concat('abc', NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_split(self): + """Test PyUnicode_Split()""" + from _testcapi import unicode_split as split + + self.assertEqual(split('a|b|c|d', '|'), ['a', 'b', 'c', 'd']) + self.assertEqual(split('a|b|c|d', '|', 2), ['a', 'b', 'c|d']) + self.assertEqual(split('a|b|c|d', '\u20ac'), ['a|b|c|d']) + self.assertEqual(split('a||b|c||d', '||'), ['a', 'b|c', 'd']) + self.assertEqual(split('а|б|в|г', '|'), ['а', 'б', 'в', 'г']) + self.assertEqual(split('абабагаламага', 'а'), + ['', 'б', 'б', 'г', 'л', 'м', 'г', '']) + self.assertEqual(split(' a\tb\nc\rd\ve\f', NULL), + ['a', 'b', 'c', 'd', 'e']) + self.assertEqual(split('a\x85b\xa0c\u1680d\u2000e', NULL), + ['a', 'b', 'c', 'd', 'e']) + + self.assertRaises(ValueError, split, 'a|b|c|d', '') + self.assertRaises(TypeError, split, 'a|b|c|d', ord('|')) + self.assertRaises(TypeError, split, [], '|') + # CRASHES split(NULL, '|') + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_rsplit(self): + """Test PyUnicode_RSplit()""" + from _testcapi import unicode_rsplit as rsplit + + self.assertEqual(rsplit('a|b|c|d', '|'), ['a', 'b', 'c', 'd']) + self.assertEqual(rsplit('a|b|c|d', '|', 2), ['a|b', 'c', 'd']) + self.assertEqual(rsplit('a|b|c|d', '\u20ac'), ['a|b|c|d']) + self.assertEqual(rsplit('a||b|c||d', '||'), ['a', 'b|c', 'd']) + self.assertEqual(rsplit('а|б|в|г', '|'), ['а', 'б', 'в', 'г']) + self.assertEqual(rsplit('абабагаламага', 'а'), + ['', 'б', 'б', 'г', 'л', 'м', 'г', '']) + self.assertEqual(rsplit('aжbжcжd', 'ж'), ['a', 'b', 'c', 'd']) + self.assertEqual(rsplit(' a\tb\nc\rd\ve\f', NULL), + ['a', 'b', 'c', 'd', 'e']) + self.assertEqual(rsplit('a\x85b\xa0c\u1680d\u2000e', NULL), + ['a', 'b', 'c', 'd', 'e']) + + self.assertRaises(ValueError, rsplit, 'a|b|c|d', '') + self.assertRaises(TypeError, rsplit, 'a|b|c|d', ord('|')) + self.assertRaises(TypeError, rsplit, [], '|') + # CRASHES rsplit(NULL, '|') + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_partition(self): + """Test PyUnicode_Partition()""" + from _testcapi import unicode_partition as partition + + self.assertEqual(partition('a|b|c', '|'), ('a', '|', 'b|c')) + self.assertEqual(partition('a||b||c', '||'), ('a', '||', 'b||c')) + self.assertEqual(partition('а|б|в', '|'), ('а', '|', 'б|в')) + self.assertEqual(partition('кабан', 'а'), ('к', 'а', 'бан')) + self.assertEqual(partition('aжbжc', 'ж'), ('a', 'ж', 'bжc')) + + self.assertRaises(ValueError, partition, 'a|b|c', '') + self.assertRaises(TypeError, partition, b'a|b|c', '|') + self.assertRaises(TypeError, partition, 'a|b|c', b'|') + self.assertRaises(TypeError, partition, 'a|b|c', ord('|')) + self.assertRaises(TypeError, partition, [], '|') + # CRASHES partition(NULL, '|') + # CRASHES partition('a|b|c', NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_rpartition(self): + """Test PyUnicode_RPartition()""" + from _testcapi import unicode_rpartition as rpartition + + self.assertEqual(rpartition('a|b|c', '|'), ('a|b', '|', 'c')) + self.assertEqual(rpartition('a||b||c', '||'), ('a||b', '||', 'c')) + self.assertEqual(rpartition('а|б|в', '|'), ('а|б', '|', 'в')) + self.assertEqual(rpartition('кабан', 'а'), ('каб', 'а', 'н')) + self.assertEqual(rpartition('aжbжc', 'ж'), ('aжb', 'ж', 'c')) + + self.assertRaises(ValueError, rpartition, 'a|b|c', '') + self.assertRaises(TypeError, rpartition, b'a|b|c', '|') + self.assertRaises(TypeError, rpartition, 'a|b|c', b'|') + self.assertRaises(TypeError, rpartition, 'a|b|c', ord('|')) + self.assertRaises(TypeError, rpartition, [], '|') + # CRASHES rpartition(NULL, '|') + # CRASHES rpartition('a|b|c', NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_splitlines(self): + """Test PyUnicode_SplitLines()""" + from _testcapi import unicode_splitlines as splitlines + + self.assertEqual(splitlines('a\nb\rc\r\nd'), ['a', 'b', 'c', 'd']) + self.assertEqual(splitlines('a\nb\rc\r\nd', True), + ['a\n', 'b\r', 'c\r\n', 'd']) + self.assertEqual(splitlines('a\x85b\u2028c\u2029d'), + ['a', 'b', 'c', 'd']) + self.assertEqual(splitlines('a\x85b\u2028c\u2029d', True), + ['a\x85', 'b\u2028', 'c\u2029', 'd']) + self.assertEqual(splitlines('а\nб\rв\r\nг'), ['а', 'б', 'в', 'г']) + + self.assertRaises(TypeError, splitlines, b'a\nb\rc\r\nd') + # CRASHES splitlines(NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_translate(self): + """Test PyUnicode_Translate()""" + from _testcapi import unicode_translate as translate + + self.assertEqual(translate('abcd', {ord('a'): 'A', ord('b'): ord('B'), ord('c'): '<>'}), 'AB<>d') + self.assertEqual(translate('абвг', {ord('а'): 'Ð', ord('б'): ord('Б'), ord('в'): '<>'}), 'ÐБ<>г') + self.assertEqual(translate('abc', {}), 'abc') + self.assertEqual(translate('abc', []), 'abc') + self.assertRaises(UnicodeTranslateError, translate, 'abc', {ord('b'): None}) + self.assertRaises(UnicodeTranslateError, translate, 'abc', {ord('b'): None}, 'strict') + self.assertRaises(LookupError, translate, 'abc', {ord('b'): None}, 'foo') + self.assertEqual(translate('abc', {ord('b'): None}, 'ignore'), 'ac') + self.assertEqual(translate('abc', {ord('b'): None}, 'replace'), 'a\ufffdc') + self.assertEqual(translate('abc', {ord('b'): None}, 'backslashreplace'), r'a\x62c') + # XXX Other error handlers do not support UnicodeTranslateError + self.assertRaises(TypeError, translate, b'abc', []) + self.assertRaises(TypeError, translate, 123, []) + self.assertRaises(TypeError, translate, 'abc', {ord('a'): b'A'}) + self.assertRaises(TypeError, translate, 'abc', 123) + self.assertRaises(TypeError, translate, 'abc', NULL) + self.assertRaises(LookupError, translate, 'abc', {ord('b'): None}, 'foo') + # CRASHES translate(NULL, []) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_join(self): + """Test PyUnicode_Join()""" + from _testcapi import unicode_join as join + self.assertEqual(join('|', ['a', 'b', 'c']), 'a|b|c') + self.assertEqual(join('|', ['a', '', 'c']), 'a||c') + self.assertEqual(join('', ['a', 'b', 'c']), 'abc') + self.assertEqual(join(NULL, ['a', 'b', 'c']), 'a b c') + self.assertEqual(join('|', ['а', 'б', 'в']), 'а|б|в') + self.assertEqual(join('ж', ['а', 'б', 'в']), 'ажбжв') + self.assertRaises(TypeError, join, b'|', ['a', 'b', 'c']) + self.assertRaises(TypeError, join, '|', [b'a', b'b', b'c']) + self.assertRaises(TypeError, join, NULL, [b'a', b'b', b'c']) + self.assertRaises(TypeError, join, '|', b'123') + self.assertRaises(TypeError, join, '|', 123) + self.assertRaises(SystemError, join, '|', NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_count(self): + """Test PyUnicode_Count()""" + from _testcapi import unicode_count + + for str in "\xa1", "\u8000\u8080", "\ud800\udc02", "\U0001f100\U0001f1f1": + for i, ch in enumerate(str): + self.assertEqual(unicode_count(str, ch, 0, len(str)), 1) + + str = "!>_= end + self.assertEqual(unicode_count(str, '!', 0, 0), 0) + self.assertEqual(unicode_count(str, '!', len(str), 0), 0) + # negative + self.assertEqual(unicode_count(str, '!', -len(str), -1), 1) + # bad arguments + self.assertRaises(TypeError, unicode_count, str, b'!', 0, len(str)) + self.assertRaises(TypeError, unicode_count, b"!>__= end + self.assertEqual(find(str, '!', 0, 0, 1), -1) + self.assertEqual(find(str, '!', len(str), 0, 1), -1) + # negative + self.assertEqual(find(str, '!', -len(str), -1, 1), 0) + self.assertEqual(find(str, '!', -len(str), -1, -1), 0) + # bad arguments + self.assertRaises(TypeError, find, str, b'!', 0, len(str), 1) + self.assertRaises(TypeError, find, b"!>__= end + self.assertEqual(unicode_findchar(str, ord('!'), 0, 0, 1), -1) + self.assertEqual(unicode_findchar(str, ord('!'), len(str), 0, 1), -1) + # negative + self.assertEqual(unicode_findchar(str, ord('!'), -len(str), -1, 1), 0) + self.assertEqual(unicode_findchar(str, ord('!'), -len(str), -1, -1), 0) + # bad arguments + # CRASHES unicode_findchar(b"!>_'), '<>br<>c<>d<>br<>') + self.assertEqual(replace(str, 'abra', '='), '=cad=') + self.assertEqual(replace(str, 'a', '=', 2), '=br=cadabra') + self.assertEqual(replace(str, 'a', '=', 0), str) + self.assertEqual(replace(str, 'a', '=', sys.maxsize), '=br=c=d=br=') + self.assertEqual(replace(str, 'z', '='), str) + self.assertEqual(replace(str, '', '='), '=a=b=r=a=c=a=d=a=b=r=a=') + self.assertEqual(replace(str, 'a', 'ж'), 'жbrжcжdжbrж') + self.assertEqual(replace('абабагаламага', 'а', '='), '=б=б=г=л=м=г=') + self.assertEqual(replace('Баден-Баден', 'Баден', 'Baden'), 'Baden-Baden') + # bad arguments + self.assertRaises(TypeError, replace, 'a', 'a', b'=') + self.assertRaises(TypeError, replace, 'a', b'a', '=') + self.assertRaises(TypeError, replace, b'a', 'a', '=') + self.assertRaises(TypeError, replace, 'a', 'a', ord('=')) + self.assertRaises(TypeError, replace, 'a', ord('a'), '=') + self.assertRaises(TypeError, replace, [], 'a', '=') + # CRASHES replace('a', 'a', NULL) + # CRASHES replace('a', NULL, '=') + # CRASHES replace(NULL, 'a', '=') + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_compare(self): + """Test PyUnicode_Compare()""" + from _testcapi import unicode_compare as compare + + self.assertEqual(compare('abc', 'abc'), 0) + self.assertEqual(compare('abc', 'def'), -1) + self.assertEqual(compare('def', 'abc'), 1) + self.assertEqual(compare('abc', 'abc\0def'), -1) + self.assertEqual(compare('abc\0def', 'abc\0def'), 0) + self.assertEqual(compare('абв', 'abc'), 1) + + self.assertRaises(TypeError, compare, b'abc', 'abc') + self.assertRaises(TypeError, compare, 'abc', b'abc') + self.assertRaises(TypeError, compare, b'abc', b'abc') + self.assertRaises(TypeError, compare, [], 'abc') + self.assertRaises(TypeError, compare, 'abc', []) + self.assertRaises(TypeError, compare, [], []) + # CRASHES compare(NULL, 'abc') + # CRASHES compare('abc', NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_comparewithasciistring(self): + """Test PyUnicode_CompareWithASCIIString()""" + from _testcapi import unicode_comparewithasciistring as comparewithasciistring + + self.assertEqual(comparewithasciistring('abc', b'abc'), 0) + self.assertEqual(comparewithasciistring('abc', b'def'), -1) + self.assertEqual(comparewithasciistring('def', b'abc'), 1) + self.assertEqual(comparewithasciistring('abc', b'abc\0def'), 0) + self.assertEqual(comparewithasciistring('abc\0def', b'abc\0def'), 1) + self.assertEqual(comparewithasciistring('абв', b'abc'), 1) + + # CRASHES comparewithasciistring(b'abc', b'abc') + # CRASHES comparewithasciistring([], b'abc') + # CRASHES comparewithasciistring(NULL, b'abc') + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_richcompare(self): + """Test PyUnicode_RichCompare()""" + from _testcapi import unicode_richcompare as richcompare + + LT, LE, EQ, NE, GT, GE = range(6) + strings = ('abc', 'абв', '\U0001f600', 'abc\0') + for s1 in strings: + for s2 in strings: + self.assertIs(richcompare(s1, s2, LT), s1 < s2) + self.assertIs(richcompare(s1, s2, LE), s1 <= s2) + self.assertIs(richcompare(s1, s2, EQ), s1 == s2) + self.assertIs(richcompare(s1, s2, NE), s1 != s2) + self.assertIs(richcompare(s1, s2, GT), s1 > s2) + self.assertIs(richcompare(s1, s2, GE), s1 >= s2) + + for op in LT, LE, EQ, NE, GT, GE: + self.assertIs(richcompare(b'abc', 'abc', op), NotImplemented) + self.assertIs(richcompare('abc', b'abc', op), NotImplemented) + self.assertIs(richcompare(b'abc', b'abc', op), NotImplemented) + self.assertIs(richcompare([], 'abc', op), NotImplemented) + self.assertIs(richcompare('abc', [], op), NotImplemented) + self.assertIs(richcompare([], [], op), NotImplemented) + + # CRASHES richcompare(NULL, 'abc', op) + # CRASHES richcompare('abc', NULL, op) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_format(self): + """Test PyUnicode_Format()""" + from _testcapi import unicode_format as format + + self.assertEqual(format('x=%d!', 42), 'x=42!') + self.assertEqual(format('x=%d!', (42,)), 'x=42!') + self.assertEqual(format('x=%d y=%s!', (42, [])), 'x=42 y=[]!') + + self.assertRaises(SystemError, format, 'x=%d!', NULL) + self.assertRaises(SystemError, format, NULL, 42) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_contains(self): + """Test PyUnicode_Contains()""" + from _testcapi import unicode_contains as contains + + self.assertEqual(contains('abcd', ''), 1) + self.assertEqual(contains('abcd', 'b'), 1) + self.assertEqual(contains('abcd', 'x'), 0) + self.assertEqual(contains('abcd', 'ж'), 0) + self.assertEqual(contains('abcd', '\0'), 0) + self.assertEqual(contains('abc\0def', '\0'), 1) + self.assertEqual(contains('abcd', 'bc'), 1) + + self.assertRaises(TypeError, contains, b'abcd', 'b') + self.assertRaises(TypeError, contains, 'abcd', b'b') + self.assertRaises(TypeError, contains, b'abcd', b'b') + self.assertRaises(TypeError, contains, [], 'b') + self.assertRaises(TypeError, contains, 'abcd', ord('b')) + # CRASHES contains(NULL, 'b') + # CRASHES contains('abcd', NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_isidentifier(self): + """Test PyUnicode_IsIdentifier()""" + from _testcapi import unicode_isidentifier as isidentifier + + self.assertEqual(isidentifier("a"), 1) + self.assertEqual(isidentifier("b0"), 1) + self.assertEqual(isidentifier("µ"), 1) + self.assertEqual(isidentifier("ð”˜ð”«ð”¦ð” ð”¬ð”¡ð”¢"), 1) + + self.assertEqual(isidentifier(""), 0) + self.assertEqual(isidentifier(" "), 0) + self.assertEqual(isidentifier("["), 0) + self.assertEqual(isidentifier("©"), 0) + self.assertEqual(isidentifier("0"), 0) + self.assertEqual(isidentifier("32M"), 0) + + # CRASHES isidentifier(b"a") + # CRASHES isidentifier([]) + # CRASHES isidentifier(NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_copycharacters(self): + """Test PyUnicode_CopyCharacters()""" + from _testcapi import unicode_copycharacters + + strings = [ + 'abcde', '\xa1\xa2\xa3\xa4\xa5', + '\u4f60\u597d\u4e16\u754c\uff01', + '\U0001f600\U0001f601\U0001f602\U0001f603\U0001f604' + ] + + for idx, from_ in enumerate(strings): + # wide -> narrow: exceed maxchar limitation + for to in strings[:idx]: + self.assertRaises( + SystemError, + unicode_copycharacters, to, 0, from_, 0, 5 + ) + # same kind + for from_start in range(5): + self.assertEqual( + unicode_copycharacters(from_, 0, from_, from_start, 5), + (from_[from_start:from_start+5].ljust(5, '\0'), + 5-from_start) + ) + for to_start in range(5): + self.assertEqual( + unicode_copycharacters(from_, to_start, from_, to_start, 5), + (from_[to_start:to_start+5].rjust(5, '\0'), + 5-to_start) + ) + # narrow -> wide + # Tests omitted since this creates invalid strings. + + s = strings[0] + self.assertRaises(IndexError, unicode_copycharacters, s, 6, s, 0, 5) + self.assertRaises(IndexError, unicode_copycharacters, s, -1, s, 0, 5) + self.assertRaises(IndexError, unicode_copycharacters, s, 0, s, 6, 5) + self.assertRaises(IndexError, unicode_copycharacters, s, 0, s, -1, 5) + self.assertRaises(SystemError, unicode_copycharacters, s, 1, s, 0, 5) + self.assertRaises(SystemError, unicode_copycharacters, s, 0, s, 0, -1) + self.assertRaises(SystemError, unicode_copycharacters, s, 0, b'', 0, 0) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_pep393_utf8_caching_bug(self): + # Issue #25709: Problem with string concatenation and utf-8 cache + from _testcapi import getargs_s_hash + for k in 0x24, 0xa4, 0x20ac, 0x1f40d: + s = '' + for i in range(5): + # Due to CPython specific optimization the 's' string can be + # resized in-place. + s += chr(k) + # Parsing with the "s#" format code calls indirectly + # PyUnicode_AsUTF8AndSize() which creates the UTF-8 + # encoded string cached in the Unicode object. + self.assertEqual(getargs_s_hash(s), chr(k).encode() * (i + 1)) + # Check that the second call returns the same result + self.assertEqual(getargs_s_hash(s), chr(k).encode() * (i + 1)) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi/test_watchers.py b/Lib/test/test_capi/test_watchers.py new file mode 100644 index 00000000000..1922614ef60 --- /dev/null +++ b/Lib/test/test_capi/test_watchers.py @@ -0,0 +1,501 @@ +import unittest + +from contextlib import contextmanager, ExitStack +from test.support import catch_unraisable_exception, import_helper + + +# Skip this test if the _testcapi module isn't available. +_testcapi = import_helper.import_module('_testcapi') + + +class TestDictWatchers(unittest.TestCase): + # types of watchers testcapimodule can add: + EVENTS = 0 # appends dict events as strings to global event list + ERROR = 1 # unconditionally sets and signals a RuntimeException + SECOND = 2 # always appends "second" to global event list + + def add_watcher(self, kind=EVENTS): + return _testcapi.add_dict_watcher(kind) + + def clear_watcher(self, watcher_id): + _testcapi.clear_dict_watcher(watcher_id) + + @contextmanager + def watcher(self, kind=EVENTS): + wid = self.add_watcher(kind) + try: + yield wid + finally: + self.clear_watcher(wid) + + def assert_events(self, expected): + actual = _testcapi.get_dict_watcher_events() + self.assertEqual(actual, expected) + + def watch(self, wid, d): + _testcapi.watch_dict(wid, d) + + def unwatch(self, wid, d): + _testcapi.unwatch_dict(wid, d) + + def test_set_new_item(self): + d = {} + with self.watcher() as wid: + self.watch(wid, d) + d["foo"] = "bar" + self.assert_events(["new:foo:bar"]) + + def test_set_existing_item(self): + d = {"foo": "bar"} + with self.watcher() as wid: + self.watch(wid, d) + d["foo"] = "baz" + self.assert_events(["mod:foo:baz"]) + + def test_clone(self): + d = {} + d2 = {"foo": "bar"} + with self.watcher() as wid: + self.watch(wid, d) + d.update(d2) + self.assert_events(["clone"]) + + def test_no_event_if_not_watched(self): + d = {} + with self.watcher() as wid: + d["foo"] = "bar" + self.assert_events([]) + + def test_del(self): + d = {"foo": "bar"} + with self.watcher() as wid: + self.watch(wid, d) + del d["foo"] + self.assert_events(["del:foo"]) + + def test_pop(self): + d = {"foo": "bar"} + with self.watcher() as wid: + self.watch(wid, d) + d.pop("foo") + self.assert_events(["del:foo"]) + + def test_clear(self): + d = {"foo": "bar"} + with self.watcher() as wid: + self.watch(wid, d) + d.clear() + self.assert_events(["clear"]) + + def test_dealloc(self): + d = {"foo": "bar"} + with self.watcher() as wid: + self.watch(wid, d) + del d + self.assert_events(["dealloc"]) + + def test_unwatch(self): + d = {} + with self.watcher() as wid: + self.watch(wid, d) + d["foo"] = "bar" + self.unwatch(wid, d) + d["hmm"] = "baz" + self.assert_events(["new:foo:bar"]) + + def test_error(self): + d = {} + with self.watcher(kind=self.ERROR) as wid: + self.watch(wid, d) + with catch_unraisable_exception() as cm: + d["foo"] = "bar" + self.assertIs(cm.unraisable.object, d) + self.assertEqual(str(cm.unraisable.exc_value), "boom!") + self.assert_events([]) + + def test_two_watchers(self): + d1 = {} + d2 = {} + with self.watcher() as wid1: + with self.watcher(kind=self.SECOND) as wid2: + self.watch(wid1, d1) + self.watch(wid2, d2) + d1["foo"] = "bar" + d2["hmm"] = "baz" + self.assert_events(["new:foo:bar", "second"]) + + def test_watch_non_dict(self): + with self.watcher() as wid: + with self.assertRaisesRegex(ValueError, r"Cannot watch non-dictionary"): + self.watch(wid, 1) + + def test_watch_out_of_range_watcher_id(self): + d = {} + with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID -1"): + self.watch(-1, d) + with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID 8"): + self.watch(8, d) # DICT_MAX_WATCHERS = 8 + + def test_watch_unassigned_watcher_id(self): + d = {} + with self.assertRaisesRegex(ValueError, r"No dict watcher set for ID 1"): + self.watch(1, d) + + def test_unwatch_non_dict(self): + with self.watcher() as wid: + with self.assertRaisesRegex(ValueError, r"Cannot watch non-dictionary"): + self.unwatch(wid, 1) + + def test_unwatch_out_of_range_watcher_id(self): + d = {} + with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID -1"): + self.unwatch(-1, d) + with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID 8"): + self.unwatch(8, d) # DICT_MAX_WATCHERS = 8 + + def test_unwatch_unassigned_watcher_id(self): + d = {} + with self.assertRaisesRegex(ValueError, r"No dict watcher set for ID 1"): + self.unwatch(1, d) + + def test_clear_out_of_range_watcher_id(self): + with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID -1"): + self.clear_watcher(-1) + with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID 8"): + self.clear_watcher(8) # DICT_MAX_WATCHERS = 8 + + def test_clear_unassigned_watcher_id(self): + with self.assertRaisesRegex(ValueError, r"No dict watcher set for ID 1"): + self.clear_watcher(1) + + +class TestTypeWatchers(unittest.TestCase): + # types of watchers testcapimodule can add: + TYPES = 0 # appends modified types to global event list + ERROR = 1 # unconditionally sets and signals a RuntimeException + WRAP = 2 # appends modified type wrapped in list to global event list + + # duplicating the C constant + TYPE_MAX_WATCHERS = 8 + + def add_watcher(self, kind=TYPES): + return _testcapi.add_type_watcher(kind) + + def clear_watcher(self, watcher_id): + _testcapi.clear_type_watcher(watcher_id) + + @contextmanager + def watcher(self, kind=TYPES): + wid = self.add_watcher(kind) + try: + yield wid + finally: + self.clear_watcher(wid) + + def assert_events(self, expected): + actual = _testcapi.get_type_modified_events() + self.assertEqual(actual, expected) + + def watch(self, wid, t): + _testcapi.watch_type(wid, t) + + def unwatch(self, wid, t): + _testcapi.unwatch_type(wid, t) + + def test_watch_type(self): + class C: pass + with self.watcher() as wid: + self.watch(wid, C) + C.foo = "bar" + self.assert_events([C]) + + def test_event_aggregation(self): + class C: pass + with self.watcher() as wid: + self.watch(wid, C) + C.foo = "bar" + C.bar = "baz" + # only one event registered for both modifications + self.assert_events([C]) + + def test_lookup_resets_aggregation(self): + class C: pass + with self.watcher() as wid: + self.watch(wid, C) + C.foo = "bar" + # lookup resets type version tag + self.assertEqual(C.foo, "bar") + C.bar = "baz" + # both events registered + self.assert_events([C, C]) + + def test_unwatch_type(self): + class C: pass + with self.watcher() as wid: + self.watch(wid, C) + C.foo = "bar" + self.assertEqual(C.foo, "bar") + self.assert_events([C]) + self.unwatch(wid, C) + C.bar = "baz" + self.assert_events([C]) + + def test_clear_watcher(self): + class C: pass + # outer watcher is unused, it's just to keep events list alive + with self.watcher() as _: + with self.watcher() as wid: + self.watch(wid, C) + C.foo = "bar" + self.assertEqual(C.foo, "bar") + self.assert_events([C]) + C.bar = "baz" + # Watcher on C has been cleared, no new event + self.assert_events([C]) + + def test_watch_type_subclass(self): + class C: pass + class D(C): pass + with self.watcher() as wid: + self.watch(wid, D) + C.foo = "bar" + self.assert_events([D]) + + def test_error(self): + class C: pass + with self.watcher(kind=self.ERROR) as wid: + self.watch(wid, C) + with catch_unraisable_exception() as cm: + C.foo = "bar" + self.assertIs(cm.unraisable.object, C) + self.assertEqual(str(cm.unraisable.exc_value), "boom!") + self.assert_events([]) + + def test_two_watchers(self): + class C1: pass + class C2: pass + with self.watcher() as wid1: + with self.watcher(kind=self.WRAP) as wid2: + self.assertNotEqual(wid1, wid2) + self.watch(wid1, C1) + self.watch(wid2, C2) + C1.foo = "bar" + C2.hmm = "baz" + self.assert_events([C1, [C2]]) + + def test_watch_non_type(self): + with self.watcher() as wid: + with self.assertRaisesRegex(ValueError, r"Cannot watch non-type"): + self.watch(wid, 1) + + def test_watch_out_of_range_watcher_id(self): + class C: pass + with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID -1"): + self.watch(-1, C) + with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID 8"): + self.watch(self.TYPE_MAX_WATCHERS, C) + + def test_watch_unassigned_watcher_id(self): + class C: pass + with self.assertRaisesRegex(ValueError, r"No type watcher set for ID 1"): + self.watch(1, C) + + def test_unwatch_non_type(self): + with self.watcher() as wid: + with self.assertRaisesRegex(ValueError, r"Cannot watch non-type"): + self.unwatch(wid, 1) + + def test_unwatch_out_of_range_watcher_id(self): + class C: pass + with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID -1"): + self.unwatch(-1, C) + with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID 8"): + self.unwatch(self.TYPE_MAX_WATCHERS, C) + + def test_unwatch_unassigned_watcher_id(self): + class C: pass + with self.assertRaisesRegex(ValueError, r"No type watcher set for ID 1"): + self.unwatch(1, C) + + def test_clear_out_of_range_watcher_id(self): + with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID -1"): + self.clear_watcher(-1) + with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID 8"): + self.clear_watcher(self.TYPE_MAX_WATCHERS) + + def test_clear_unassigned_watcher_id(self): + with self.assertRaisesRegex(ValueError, r"No type watcher set for ID 1"): + self.clear_watcher(1) + + def test_no_more_ids_available(self): + contexts = [self.watcher() for i in range(self.TYPE_MAX_WATCHERS)] + with ExitStack() as stack: + for ctx in contexts: + stack.enter_context(ctx) + with self.assertRaisesRegex(RuntimeError, r"no more type watcher IDs"): + self.add_watcher() + + +class TestCodeObjectWatchers(unittest.TestCase): + @contextmanager + def code_watcher(self, which_watcher): + wid = _testcapi.add_code_watcher(which_watcher) + try: + yield wid + finally: + _testcapi.clear_code_watcher(wid) + + def assert_event_counts(self, exp_created_0, exp_destroyed_0, + exp_created_1, exp_destroyed_1): + self.assertEqual( + exp_created_0, _testcapi.get_code_watcher_num_created_events(0)) + self.assertEqual( + exp_destroyed_0, _testcapi.get_code_watcher_num_destroyed_events(0)) + self.assertEqual( + exp_created_1, _testcapi.get_code_watcher_num_created_events(1)) + self.assertEqual( + exp_destroyed_1, _testcapi.get_code_watcher_num_destroyed_events(1)) + + def test_code_object_events_dispatched(self): + # verify that all counts are zero before any watchers are registered + self.assert_event_counts(0, 0, 0, 0) + + # verify that all counts remain zero when a code object is + # created and destroyed with no watchers registered + co1 = _testcapi.code_newempty("test_watchers", "dummy1", 0) + self.assert_event_counts(0, 0, 0, 0) + del co1 + self.assert_event_counts(0, 0, 0, 0) + + # verify counts are as expected when first watcher is registered + with self.code_watcher(0): + self.assert_event_counts(0, 0, 0, 0) + co2 = _testcapi.code_newempty("test_watchers", "dummy2", 0) + self.assert_event_counts(1, 0, 0, 0) + del co2 + self.assert_event_counts(1, 1, 0, 0) + + # again with second watcher registered + with self.code_watcher(1): + self.assert_event_counts(1, 1, 0, 0) + co3 = _testcapi.code_newempty("test_watchers", "dummy3", 0) + self.assert_event_counts(2, 1, 1, 0) + del co3 + self.assert_event_counts(2, 2, 1, 1) + + # verify counts are reset and don't change after both watchers are cleared + co4 = _testcapi.code_newempty("test_watchers", "dummy4", 0) + self.assert_event_counts(0, 0, 0, 0) + del co4 + self.assert_event_counts(0, 0, 0, 0) + + def test_clear_out_of_range_watcher_id(self): + with self.assertRaisesRegex(ValueError, r"Invalid code watcher ID -1"): + _testcapi.clear_code_watcher(-1) + with self.assertRaisesRegex(ValueError, r"Invalid code watcher ID 8"): + _testcapi.clear_code_watcher(8) # CODE_MAX_WATCHERS = 8 + + def test_clear_unassigned_watcher_id(self): + with self.assertRaisesRegex(ValueError, r"No code watcher set for ID 1"): + _testcapi.clear_code_watcher(1) + + def test_allocate_too_many_watchers(self): + with self.assertRaisesRegex(RuntimeError, r"no more code watcher IDs available"): + _testcapi.allocate_too_many_code_watchers() + + +class TestFuncWatchers(unittest.TestCase): + @contextmanager + def add_watcher(self, func): + wid = _testcapi.add_func_watcher(func) + try: + yield + finally: + _testcapi.clear_func_watcher(wid) + + def test_func_events_dispatched(self): + events = [] + def watcher(*args): + events.append(args) + + with self.add_watcher(watcher): + def myfunc(): + pass + self.assertIn((_testcapi.PYFUNC_EVENT_CREATE, myfunc, None), events) + myfunc_id = id(myfunc) + + new_code = self.test_func_events_dispatched.__code__ + myfunc.__code__ = new_code + self.assertIn((_testcapi.PYFUNC_EVENT_MODIFY_CODE, myfunc, new_code), events) + + new_defaults = (123,) + myfunc.__defaults__ = new_defaults + self.assertIn((_testcapi.PYFUNC_EVENT_MODIFY_DEFAULTS, myfunc, new_defaults), events) + + new_defaults = (456,) + _testcapi.set_func_defaults_via_capi(myfunc, new_defaults) + self.assertIn((_testcapi.PYFUNC_EVENT_MODIFY_DEFAULTS, myfunc, new_defaults), events) + + new_kwdefaults = {"self": 123} + myfunc.__kwdefaults__ = new_kwdefaults + self.assertIn((_testcapi.PYFUNC_EVENT_MODIFY_KWDEFAULTS, myfunc, new_kwdefaults), events) + + new_kwdefaults = {"self": 456} + _testcapi.set_func_kwdefaults_via_capi(myfunc, new_kwdefaults) + self.assertIn((_testcapi.PYFUNC_EVENT_MODIFY_KWDEFAULTS, myfunc, new_kwdefaults), events) + + # Clear events reference to func + events = [] + del myfunc + self.assertIn((_testcapi.PYFUNC_EVENT_DESTROY, myfunc_id, None), events) + + def test_multiple_watchers(self): + events0 = [] + def first_watcher(*args): + events0.append(args) + + events1 = [] + def second_watcher(*args): + events1.append(args) + + with self.add_watcher(first_watcher): + with self.add_watcher(second_watcher): + def myfunc(): + pass + + event = (_testcapi.PYFUNC_EVENT_CREATE, myfunc, None) + self.assertIn(event, events0) + self.assertIn(event, events1) + + def test_watcher_raises_error(self): + class MyError(Exception): + pass + + def watcher(*args): + raise MyError("testing 123") + + with self.add_watcher(watcher): + with catch_unraisable_exception() as cm: + def myfunc(): + pass + + self.assertIs(cm.unraisable.object, myfunc) + self.assertIsInstance(cm.unraisable.exc_value, MyError) + + def test_clear_out_of_range_watcher_id(self): + with self.assertRaisesRegex(ValueError, r"invalid func watcher ID -1"): + _testcapi.clear_func_watcher(-1) + with self.assertRaisesRegex(ValueError, r"invalid func watcher ID 8"): + _testcapi.clear_func_watcher(8) # FUNC_MAX_WATCHERS = 8 + + def test_clear_unassigned_watcher_id(self): + with self.assertRaisesRegex(ValueError, r"no func watcher set for ID 1"): + _testcapi.clear_func_watcher(1) + + def test_allocate_too_many_watchers(self): + with self.assertRaisesRegex(RuntimeError, r"no more func watcher IDs"): + _testcapi.allocate_too_many_func_watchers() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py index c1b893d3fe5..24486e4d95a 100644 --- a/Lib/test/test_cgi.py +++ b/Lib/test/test_cgi.py @@ -1,4 +1,3 @@ -import cgi import os import sys import tempfile @@ -8,6 +7,9 @@ from io import StringIO, BytesIO from test import support from test.support import warnings_helper +cgi = warnings_helper.import_deprecated("cgi") + + class HackedSysModule: # The regression test will have real values in sys.argv, which # will completely confuse the test of the cgi module @@ -51,7 +53,7 @@ def do_test(buf, method): return ComparableException(err) parse_strict_test_cases = [ - ("", ValueError("bad query field: ''")), + ("", {}), ("&", ValueError("bad query field: ''")), ("&&", ValueError("bad query field: ''")), # Should the next few really be valid? diff --git a/Lib/test/test_cgitb.py b/Lib/test/test_cgitb.py index 590ffdea112..501c7fcce28 100644 --- a/Lib/test/test_cgitb.py +++ b/Lib/test/test_cgitb.py @@ -1,8 +1,9 @@ from test.support.os_helper import temp_dir from test.support.script_helper import assert_python_failure +from test.support.warnings_helper import import_deprecated import unittest import sys -import cgitb +cgitb = import_deprecated("cgitb") class TestCgitb(unittest.TestCase): diff --git a/Lib/test/test_check_c_globals.py b/Lib/test/test_check_c_globals.py index 030debc452e..670be52422f 100644 --- a/Lib/test/test_check_c_globals.py +++ b/Lib/test/test_check_c_globals.py @@ -1,9 +1,19 @@ import unittest import test.test_tools +from test.support.warnings_helper import save_restore_warnings_filters + + +# TODO: gh-92584: c-analyzer uses distutils which was removed in Python 3.12 +raise unittest.SkipTest("distutils has been removed in Python 3.12") + test.test_tools.skip_if_missing('c-analyzer') with test.test_tools.imports_under_tool('c-analyzer'): - from cpython.__main__ import main + # gh-95349: Save/restore warnings filters to leave them unchanged. + # Importing the c-analyzer imports docutils which imports pkg_resources + # which adds a warnings filter. + with save_restore_warnings_filters(): + from cpython.__main__ import main class ActualChecks(unittest.TestCase): diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py index 7524f58a3ce..61df81b1697 100644 --- a/Lib/test/test_class.py +++ b/Lib/test/test_class.py @@ -445,6 +445,20 @@ class ClassTests(unittest.TestCase): del testme.cardinal self.assertCallStack([('__delattr__', (testme, "cardinal"))]) + def testHasAttrString(self): + import sys + from test.support import import_helper + _testcapi = import_helper.import_module('_testcapi') + + class A: + def __init__(self): + self.attr = 1 + + a = A() + self.assertEqual(_testcapi.hasattr_string(a, "attr"), True) + self.assertEqual(_testcapi.hasattr_string(a, "noattr"), False) + self.assertEqual(sys.exc_info(), (None, None, None)) + def testDel(self): x = [] @@ -611,6 +625,49 @@ class ClassTests(unittest.TestCase): with self.assertRaises(TypeError): type.__setattr__(A, b'x', None) + def testTypeAttributeAccessErrorMessages(self): + class A: + pass + + error_msg = "type object 'A' has no attribute 'x'" + with self.assertRaisesRegex(AttributeError, error_msg): + A.x + with self.assertRaisesRegex(AttributeError, error_msg): + del A.x + + def testObjectAttributeAccessErrorMessages(self): + class A: + pass + class B: + y = 0 + __slots__ = ('z',) + + error_msg = "'A' object has no attribute 'x'" + with self.assertRaisesRegex(AttributeError, error_msg): + A().x + with self.assertRaisesRegex(AttributeError, error_msg): + del A().x + + error_msg = "'B' object has no attribute 'x'" + with self.assertRaisesRegex(AttributeError, error_msg): + B().x + with self.assertRaisesRegex(AttributeError, error_msg): + del B().x + with self.assertRaisesRegex(AttributeError, error_msg): + B().x = 0 + + error_msg = "'B' object attribute 'y' is read-only" + with self.assertRaisesRegex(AttributeError, error_msg): + del B().y + with self.assertRaisesRegex(AttributeError, error_msg): + B().y = 0 + + error_msg = 'z' + with self.assertRaisesRegex(AttributeError, error_msg): + B().z + with self.assertRaisesRegex(AttributeError, error_msg): + del B().z + def testConstructorErrorMessages(self): # bpo-31506: Improves the error message logic for object_new & object_init @@ -666,5 +723,23 @@ class ClassTests(unittest.TestCase): with self.assertRaisesRegex(TypeError, error_msg): object.__init__(E(), 42) + def testClassWithExtCall(self): + class Meta(int): + def __init__(*args, **kwargs): + pass + + def __new__(cls, name, bases, attrs, **kwargs): + return bases, kwargs + + d = {'metaclass': Meta} + + class A(**d): pass + self.assertEqual(A, ((), {})) + class A(0, 1, 2, 3, 4, 5, 6, 7, **d): pass + self.assertEqual(A, (tuple(range(8)), {})) + class A(0, *range(1, 8), **d, foo='bar'): pass + self.assertEqual(A, (tuple(range(8)), {'foo': 'bar'})) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index 4aa9691a482..4abf739cf52 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -3,7 +3,7 @@ # Licensed to the PSF under a contributor agreement. from test import support, test_tools -from test.support import os_helper +from test.support import import_helper, os_helper from unittest import TestCase import collections import inspect @@ -153,7 +153,7 @@ class ClinicGroupPermuterTest(TestCase): def test_have_left_options_but_required_is_empty(self): def fn(): clinic.permute_optional_groups(['a'], [], []) - self.assertRaises(AssertionError, fn) + self.assertRaises(ValueError, fn) class ClinicLinearFormatTest(TestCase): @@ -730,6 +730,15 @@ foo.bar x: int """) + def test_parameters_no_more_than_one_vararg(self): + s = self.parse_function_should_fail(""" +module foo +foo.bar + *vararg1: object + *vararg2: object +""") + self.assertEqual(s, "Error on line 0:\nToo many var args\n") + def test_function_not_at_column_0(self): function = self.parse_function(""" module foo @@ -820,5 +829,461 @@ class ClinicExternalTest(TestCase): self.assertEqual(new_mtime_ns, old_mtime_ns) +ac_tester = import_helper.import_module('_testclinic') + + +class ClinicFunctionalTest(unittest.TestCase): + locals().update((name, getattr(ac_tester, name)) + for name in dir(ac_tester) if name.startswith('test_')) + + def test_objects_converter(self): + with self.assertRaises(TypeError): + ac_tester.objects_converter() + self.assertEqual(ac_tester.objects_converter(1, 2), (1, 2)) + self.assertEqual(ac_tester.objects_converter([], 'whatever class'), ([], 'whatever class')) + self.assertEqual(ac_tester.objects_converter(1), (1, None)) + + def test_bytes_object_converter(self): + with self.assertRaises(TypeError): + ac_tester.bytes_object_converter(1) + self.assertEqual(ac_tester.bytes_object_converter(b'BytesObject'), (b'BytesObject',)) + + def test_byte_array_object_converter(self): + with self.assertRaises(TypeError): + ac_tester.byte_array_object_converter(1) + byte_arr = bytearray(b'ByteArrayObject') + self.assertEqual(ac_tester.byte_array_object_converter(byte_arr), (byte_arr,)) + + def test_unicode_converter(self): + with self.assertRaises(TypeError): + ac_tester.unicode_converter(1) + self.assertEqual(ac_tester.unicode_converter('unicode'), ('unicode',)) + + def test_bool_converter(self): + with self.assertRaises(TypeError): + ac_tester.bool_converter(False, False, 'not a int') + self.assertEqual(ac_tester.bool_converter(), (True, True, True)) + self.assertEqual(ac_tester.bool_converter('', [], 5), (False, False, True)) + self.assertEqual(ac_tester.bool_converter(('not empty',), {1: 2}, 0), (True, True, False)) + + def test_char_converter(self): + with self.assertRaises(TypeError): + ac_tester.char_converter(1) + with self.assertRaises(TypeError): + ac_tester.char_converter(b'ab') + chars = [b'A', b'\a', b'\b', b'\t', b'\n', b'\v', b'\f', b'\r', b'"', b"'", b'?', b'\\', b'\000', b'\377'] + expected = tuple(ord(c) for c in chars) + self.assertEqual(ac_tester.char_converter(), expected) + chars = [b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'0', b'a', b'b', b'c', b'd'] + expected = tuple(ord(c) for c in chars) + self.assertEqual(ac_tester.char_converter(*chars), expected) + + def test_unsigned_char_converter(self): + from _testcapi import UCHAR_MAX + with self.assertRaises(OverflowError): + ac_tester.unsigned_char_converter(-1) + with self.assertRaises(OverflowError): + ac_tester.unsigned_char_converter(UCHAR_MAX + 1) + with self.assertRaises(OverflowError): + ac_tester.unsigned_char_converter(0, UCHAR_MAX + 1) + with self.assertRaises(TypeError): + ac_tester.unsigned_char_converter([]) + self.assertEqual(ac_tester.unsigned_char_converter(), (12, 34, 56)) + self.assertEqual(ac_tester.unsigned_char_converter(0, 0, UCHAR_MAX + 1), (0, 0, 0)) + self.assertEqual(ac_tester.unsigned_char_converter(0, 0, (UCHAR_MAX + 1) * 3 + 123), (0, 0, 123)) + + def test_short_converter(self): + from _testcapi import SHRT_MIN, SHRT_MAX + with self.assertRaises(OverflowError): + ac_tester.short_converter(SHRT_MIN - 1) + with self.assertRaises(OverflowError): + ac_tester.short_converter(SHRT_MAX + 1) + with self.assertRaises(TypeError): + ac_tester.short_converter([]) + self.assertEqual(ac_tester.short_converter(-1234), (-1234,)) + self.assertEqual(ac_tester.short_converter(4321), (4321,)) + + def test_unsigned_short_converter(self): + from _testcapi import USHRT_MAX + with self.assertRaises(ValueError): + ac_tester.unsigned_short_converter(-1) + with self.assertRaises(OverflowError): + ac_tester.unsigned_short_converter(USHRT_MAX + 1) + with self.assertRaises(OverflowError): + ac_tester.unsigned_short_converter(0, USHRT_MAX + 1) + with self.assertRaises(TypeError): + ac_tester.unsigned_short_converter([]) + self.assertEqual(ac_tester.unsigned_short_converter(), (12, 34, 56)) + self.assertEqual(ac_tester.unsigned_short_converter(0, 0, USHRT_MAX + 1), (0, 0, 0)) + self.assertEqual(ac_tester.unsigned_short_converter(0, 0, (USHRT_MAX + 1) * 3 + 123), (0, 0, 123)) + + def test_int_converter(self): + from _testcapi import INT_MIN, INT_MAX + with self.assertRaises(OverflowError): + ac_tester.int_converter(INT_MIN - 1) + with self.assertRaises(OverflowError): + ac_tester.int_converter(INT_MAX + 1) + with self.assertRaises(TypeError): + ac_tester.int_converter(1, 2, 3) + with self.assertRaises(TypeError): + ac_tester.int_converter([]) + self.assertEqual(ac_tester.int_converter(), (12, 34, 45)) + self.assertEqual(ac_tester.int_converter(1, 2, '3'), (1, 2, ord('3'))) + + def test_unsigned_int_converter(self): + from _testcapi import UINT_MAX + with self.assertRaises(ValueError): + ac_tester.unsigned_int_converter(-1) + with self.assertRaises(OverflowError): + ac_tester.unsigned_int_converter(UINT_MAX + 1) + with self.assertRaises(OverflowError): + ac_tester.unsigned_int_converter(0, UINT_MAX + 1) + with self.assertRaises(TypeError): + ac_tester.unsigned_int_converter([]) + self.assertEqual(ac_tester.unsigned_int_converter(), (12, 34, 56)) + self.assertEqual(ac_tester.unsigned_int_converter(0, 0, UINT_MAX + 1), (0, 0, 0)) + self.assertEqual(ac_tester.unsigned_int_converter(0, 0, (UINT_MAX + 1) * 3 + 123), (0, 0, 123)) + + def test_long_converter(self): + from _testcapi import LONG_MIN, LONG_MAX + with self.assertRaises(OverflowError): + ac_tester.long_converter(LONG_MIN - 1) + with self.assertRaises(OverflowError): + ac_tester.long_converter(LONG_MAX + 1) + with self.assertRaises(TypeError): + ac_tester.long_converter([]) + self.assertEqual(ac_tester.long_converter(), (12,)) + self.assertEqual(ac_tester.long_converter(-1234), (-1234,)) + + def test_unsigned_long_converter(self): + from _testcapi import ULONG_MAX + with self.assertRaises(ValueError): + ac_tester.unsigned_long_converter(-1) + with self.assertRaises(OverflowError): + ac_tester.unsigned_long_converter(ULONG_MAX + 1) + with self.assertRaises(OverflowError): + ac_tester.unsigned_long_converter(0, ULONG_MAX + 1) + with self.assertRaises(TypeError): + ac_tester.unsigned_long_converter([]) + self.assertEqual(ac_tester.unsigned_long_converter(), (12, 34, 56)) + self.assertEqual(ac_tester.unsigned_long_converter(0, 0, ULONG_MAX + 1), (0, 0, 0)) + self.assertEqual(ac_tester.unsigned_long_converter(0, 0, (ULONG_MAX + 1) * 3 + 123), (0, 0, 123)) + + def test_long_long_converter(self): + from _testcapi import LLONG_MIN, LLONG_MAX + with self.assertRaises(OverflowError): + ac_tester.long_long_converter(LLONG_MIN - 1) + with self.assertRaises(OverflowError): + ac_tester.long_long_converter(LLONG_MAX + 1) + with self.assertRaises(TypeError): + ac_tester.long_long_converter([]) + self.assertEqual(ac_tester.long_long_converter(), (12,)) + self.assertEqual(ac_tester.long_long_converter(-1234), (-1234,)) + + def test_unsigned_long_long_converter(self): + from _testcapi import ULLONG_MAX + with self.assertRaises(ValueError): + ac_tester.unsigned_long_long_converter(-1) + with self.assertRaises(OverflowError): + ac_tester.unsigned_long_long_converter(ULLONG_MAX + 1) + with self.assertRaises(OverflowError): + ac_tester.unsigned_long_long_converter(0, ULLONG_MAX + 1) + with self.assertRaises(TypeError): + ac_tester.unsigned_long_long_converter([]) + self.assertEqual(ac_tester.unsigned_long_long_converter(), (12, 34, 56)) + self.assertEqual(ac_tester.unsigned_long_long_converter(0, 0, ULLONG_MAX + 1), (0, 0, 0)) + self.assertEqual(ac_tester.unsigned_long_long_converter(0, 0, (ULLONG_MAX + 1) * 3 + 123), (0, 0, 123)) + + def test_py_ssize_t_converter(self): + from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX + with self.assertRaises(OverflowError): + ac_tester.py_ssize_t_converter(PY_SSIZE_T_MIN - 1) + with self.assertRaises(OverflowError): + ac_tester.py_ssize_t_converter(PY_SSIZE_T_MAX + 1) + with self.assertRaises(TypeError): + ac_tester.py_ssize_t_converter([]) + self.assertEqual(ac_tester.py_ssize_t_converter(), (12, 34, 56)) + self.assertEqual(ac_tester.py_ssize_t_converter(1, 2, None), (1, 2, 56)) + + def test_slice_index_converter(self): + from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX + with self.assertRaises(TypeError): + ac_tester.slice_index_converter([]) + self.assertEqual(ac_tester.slice_index_converter(), (12, 34, 56)) + self.assertEqual(ac_tester.slice_index_converter(1, 2, None), (1, 2, 56)) + self.assertEqual(ac_tester.slice_index_converter(PY_SSIZE_T_MAX, PY_SSIZE_T_MAX + 1, PY_SSIZE_T_MAX + 1234), + (PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX)) + self.assertEqual(ac_tester.slice_index_converter(PY_SSIZE_T_MIN, PY_SSIZE_T_MIN - 1, PY_SSIZE_T_MIN - 1234), + (PY_SSIZE_T_MIN, PY_SSIZE_T_MIN, PY_SSIZE_T_MIN)) + + def test_size_t_converter(self): + with self.assertRaises(ValueError): + ac_tester.size_t_converter(-1) + with self.assertRaises(TypeError): + ac_tester.size_t_converter([]) + self.assertEqual(ac_tester.size_t_converter(), (12,)) + + def test_float_converter(self): + with self.assertRaises(TypeError): + ac_tester.float_converter([]) + self.assertEqual(ac_tester.float_converter(), (12.5,)) + self.assertEqual(ac_tester.float_converter(-0.5), (-0.5,)) + + def test_double_converter(self): + with self.assertRaises(TypeError): + ac_tester.double_converter([]) + self.assertEqual(ac_tester.double_converter(), (12.5,)) + self.assertEqual(ac_tester.double_converter(-0.5), (-0.5,)) + + def test_py_complex_converter(self): + with self.assertRaises(TypeError): + ac_tester.py_complex_converter([]) + self.assertEqual(ac_tester.py_complex_converter(complex(1, 2)), (complex(1, 2),)) + self.assertEqual(ac_tester.py_complex_converter(complex('-1-2j')), (complex('-1-2j'),)) + self.assertEqual(ac_tester.py_complex_converter(-0.5), (-0.5,)) + self.assertEqual(ac_tester.py_complex_converter(10), (10,)) + + def test_str_converter(self): + with self.assertRaises(TypeError): + ac_tester.str_converter(1) + with self.assertRaises(TypeError): + ac_tester.str_converter('a', 'b', 'c') + with self.assertRaises(ValueError): + ac_tester.str_converter('a', b'b\0b', 'c') + self.assertEqual(ac_tester.str_converter('a', b'b', 'c'), ('a', 'b', 'c')) + self.assertEqual(ac_tester.str_converter('a', b'b', b'c'), ('a', 'b', 'c')) + self.assertEqual(ac_tester.str_converter('a', b'b', 'c\0c'), ('a', 'b', 'c\0c')) + + def test_str_converter_encoding(self): + with self.assertRaises(TypeError): + ac_tester.str_converter_encoding(1) + self.assertEqual(ac_tester.str_converter_encoding('a', 'b', 'c'), ('a', 'b', 'c')) + with self.assertRaises(TypeError): + ac_tester.str_converter_encoding('a', b'b\0b', 'c') + self.assertEqual(ac_tester.str_converter_encoding('a', b'b', bytearray([ord('c')])), ('a', 'b', 'c')) + self.assertEqual(ac_tester.str_converter_encoding('a', b'b', bytearray([ord('c'), 0, ord('c')])), + ('a', 'b', 'c\x00c')) + self.assertEqual(ac_tester.str_converter_encoding('a', b'b', b'c\x00c'), ('a', 'b', 'c\x00c')) + + def test_py_buffer_converter(self): + with self.assertRaises(TypeError): + ac_tester.py_buffer_converter('a', 'b') + self.assertEqual(ac_tester.py_buffer_converter('abc', bytearray([1, 2, 3])), (b'abc', b'\x01\x02\x03')) + + def test_keywords(self): + self.assertEqual(ac_tester.keywords(1, 2), (1, 2)) + self.assertEqual(ac_tester.keywords(1, b=2), (1, 2)) + self.assertEqual(ac_tester.keywords(a=1, b=2), (1, 2)) + + def test_keywords_kwonly(self): + with self.assertRaises(TypeError): + ac_tester.keywords_kwonly(1, 2) + self.assertEqual(ac_tester.keywords_kwonly(1, b=2), (1, 2)) + self.assertEqual(ac_tester.keywords_kwonly(a=1, b=2), (1, 2)) + + def test_keywords_opt(self): + self.assertEqual(ac_tester.keywords_opt(1), (1, None, None)) + self.assertEqual(ac_tester.keywords_opt(1, 2), (1, 2, None)) + self.assertEqual(ac_tester.keywords_opt(1, 2, 3), (1, 2, 3)) + self.assertEqual(ac_tester.keywords_opt(1, b=2), (1, 2, None)) + self.assertEqual(ac_tester.keywords_opt(1, 2, c=3), (1, 2, 3)) + self.assertEqual(ac_tester.keywords_opt(a=1, c=3), (1, None, 3)) + self.assertEqual(ac_tester.keywords_opt(a=1, b=2, c=3), (1, 2, 3)) + + def test_keywords_opt_kwonly(self): + self.assertEqual(ac_tester.keywords_opt_kwonly(1), (1, None, None, None)) + self.assertEqual(ac_tester.keywords_opt_kwonly(1, 2), (1, 2, None, None)) + with self.assertRaises(TypeError): + ac_tester.keywords_opt_kwonly(1, 2, 3) + self.assertEqual(ac_tester.keywords_opt_kwonly(1, b=2), (1, 2, None, None)) + self.assertEqual(ac_tester.keywords_opt_kwonly(1, 2, c=3), (1, 2, 3, None)) + self.assertEqual(ac_tester.keywords_opt_kwonly(a=1, c=3), (1, None, 3, None)) + self.assertEqual(ac_tester.keywords_opt_kwonly(a=1, b=2, c=3, d=4), (1, 2, 3, 4)) + + def test_keywords_kwonly_opt(self): + self.assertEqual(ac_tester.keywords_kwonly_opt(1), (1, None, None)) + with self.assertRaises(TypeError): + ac_tester.keywords_kwonly_opt(1, 2) + self.assertEqual(ac_tester.keywords_kwonly_opt(1, b=2), (1, 2, None)) + self.assertEqual(ac_tester.keywords_kwonly_opt(a=1, c=3), (1, None, 3)) + self.assertEqual(ac_tester.keywords_kwonly_opt(a=1, b=2, c=3), (1, 2, 3)) + + def test_posonly_keywords(self): + with self.assertRaises(TypeError): + ac_tester.posonly_keywords(1) + with self.assertRaises(TypeError): + ac_tester.posonly_keywords(a=1, b=2) + self.assertEqual(ac_tester.posonly_keywords(1, 2), (1, 2)) + self.assertEqual(ac_tester.posonly_keywords(1, b=2), (1, 2)) + + def test_posonly_kwonly(self): + with self.assertRaises(TypeError): + ac_tester.posonly_kwonly(1) + with self.assertRaises(TypeError): + ac_tester.posonly_kwonly(1, 2) + with self.assertRaises(TypeError): + ac_tester.posonly_kwonly(a=1, b=2) + self.assertEqual(ac_tester.posonly_kwonly(1, b=2), (1, 2)) + + def test_posonly_keywords_kwonly(self): + with self.assertRaises(TypeError): + ac_tester.posonly_keywords_kwonly(1) + with self.assertRaises(TypeError): + ac_tester.posonly_keywords_kwonly(1, 2, 3) + with self.assertRaises(TypeError): + ac_tester.posonly_keywords_kwonly(a=1, b=2, c=3) + self.assertEqual(ac_tester.posonly_keywords_kwonly(1, 2, c=3), (1, 2, 3)) + self.assertEqual(ac_tester.posonly_keywords_kwonly(1, b=2, c=3), (1, 2, 3)) + + def test_posonly_keywords_opt(self): + with self.assertRaises(TypeError): + ac_tester.posonly_keywords_opt(1) + self.assertEqual(ac_tester.posonly_keywords_opt(1, 2), (1, 2, None, None)) + self.assertEqual(ac_tester.posonly_keywords_opt(1, 2, 3), (1, 2, 3, None)) + self.assertEqual(ac_tester.posonly_keywords_opt(1, 2, 3, 4), (1, 2, 3, 4)) + self.assertEqual(ac_tester.posonly_keywords_opt(1, b=2), (1, 2, None, None)) + self.assertEqual(ac_tester.posonly_keywords_opt(1, 2, c=3), (1, 2, 3, None)) + with self.assertRaises(TypeError): + ac_tester.posonly_keywords_opt(a=1, b=2, c=3, d=4) + self.assertEqual(ac_tester.posonly_keywords_opt(1, b=2, c=3, d=4), (1, 2, 3, 4)) + + def test_posonly_opt_keywords_opt(self): + self.assertEqual(ac_tester.posonly_opt_keywords_opt(1), (1, None, None, None)) + self.assertEqual(ac_tester.posonly_opt_keywords_opt(1, 2), (1, 2, None, None)) + self.assertEqual(ac_tester.posonly_opt_keywords_opt(1, 2, 3), (1, 2, 3, None)) + self.assertEqual(ac_tester.posonly_opt_keywords_opt(1, 2, 3, 4), (1, 2, 3, 4)) + with self.assertRaises(TypeError): + ac_tester.posonly_opt_keywords_opt(1, b=2) + self.assertEqual(ac_tester.posonly_opt_keywords_opt(1, 2, c=3), (1, 2, 3, None)) + self.assertEqual(ac_tester.posonly_opt_keywords_opt(1, 2, c=3, d=4), (1, 2, 3, 4)) + with self.assertRaises(TypeError): + ac_tester.posonly_opt_keywords_opt(a=1, b=2, c=3, d=4) + + def test_posonly_kwonly_opt(self): + with self.assertRaises(TypeError): + ac_tester.posonly_kwonly_opt(1) + with self.assertRaises(TypeError): + ac_tester.posonly_kwonly_opt(1, 2) + self.assertEqual(ac_tester.posonly_kwonly_opt(1, b=2), (1, 2, None, None)) + self.assertEqual(ac_tester.posonly_kwonly_opt(1, b=2, c=3), (1, 2, 3, None)) + self.assertEqual(ac_tester.posonly_kwonly_opt(1, b=2, c=3, d=4), (1, 2, 3, 4)) + with self.assertRaises(TypeError): + ac_tester.posonly_kwonly_opt(a=1, b=2, c=3, d=4) + + def test_posonly_opt_kwonly_opt(self): + self.assertEqual(ac_tester.posonly_opt_kwonly_opt(1), (1, None, None, None)) + self.assertEqual(ac_tester.posonly_opt_kwonly_opt(1, 2), (1, 2, None, None)) + with self.assertRaises(TypeError): + ac_tester.posonly_opt_kwonly_opt(1, 2, 3) + with self.assertRaises(TypeError): + ac_tester.posonly_opt_kwonly_opt(1, b=2) + self.assertEqual(ac_tester.posonly_opt_kwonly_opt(1, 2, c=3), (1, 2, 3, None)) + self.assertEqual(ac_tester.posonly_opt_kwonly_opt(1, 2, c=3, d=4), (1, 2, 3, 4)) + + def test_posonly_keywords_kwonly_opt(self): + with self.assertRaises(TypeError): + ac_tester.posonly_keywords_kwonly_opt(1) + with self.assertRaises(TypeError): + ac_tester.posonly_keywords_kwonly_opt(1, 2) + with self.assertRaises(TypeError): + ac_tester.posonly_keywords_kwonly_opt(1, b=2) + with self.assertRaises(TypeError): + ac_tester.posonly_keywords_kwonly_opt(1, 2, 3) + with self.assertRaises(TypeError): + ac_tester.posonly_keywords_kwonly_opt(a=1, b=2, c=3) + self.assertEqual(ac_tester.posonly_keywords_kwonly_opt(1, 2, c=3), (1, 2, 3, None, None)) + self.assertEqual(ac_tester.posonly_keywords_kwonly_opt(1, b=2, c=3), (1, 2, 3, None, None)) + self.assertEqual(ac_tester.posonly_keywords_kwonly_opt(1, 2, c=3, d=4), (1, 2, 3, 4, None)) + self.assertEqual(ac_tester.posonly_keywords_kwonly_opt(1, 2, c=3, d=4, e=5), (1, 2, 3, 4, 5)) + + def test_posonly_keywords_opt_kwonly_opt(self): + with self.assertRaises(TypeError): + ac_tester.posonly_keywords_opt_kwonly_opt(1) + self.assertEqual(ac_tester.posonly_keywords_opt_kwonly_opt(1, 2), (1, 2, None, None, None)) + self.assertEqual(ac_tester.posonly_keywords_opt_kwonly_opt(1, b=2), (1, 2, None, None, None)) + with self.assertRaises(TypeError): + ac_tester.posonly_keywords_opt_kwonly_opt(1, 2, 3, 4) + with self.assertRaises(TypeError): + ac_tester.posonly_keywords_opt_kwonly_opt(a=1, b=2) + self.assertEqual(ac_tester.posonly_keywords_opt_kwonly_opt(1, 2, c=3), (1, 2, 3, None, None)) + self.assertEqual(ac_tester.posonly_keywords_opt_kwonly_opt(1, b=2, c=3), (1, 2, 3, None, None)) + self.assertEqual(ac_tester.posonly_keywords_opt_kwonly_opt(1, 2, 3, d=4), (1, 2, 3, 4, None)) + self.assertEqual(ac_tester.posonly_keywords_opt_kwonly_opt(1, 2, c=3, d=4), (1, 2, 3, 4, None)) + self.assertEqual(ac_tester.posonly_keywords_opt_kwonly_opt(1, 2, 3, d=4, e=5), (1, 2, 3, 4, 5)) + self.assertEqual(ac_tester.posonly_keywords_opt_kwonly_opt(1, 2, c=3, d=4, e=5), (1, 2, 3, 4, 5)) + + def test_posonly_opt_keywords_opt_kwonly_opt(self): + self.assertEqual(ac_tester.posonly_opt_keywords_opt_kwonly_opt(1), (1, None, None, None)) + self.assertEqual(ac_tester.posonly_opt_keywords_opt_kwonly_opt(1, 2), (1, 2, None, None)) + with self.assertRaises(TypeError): + ac_tester.posonly_opt_keywords_opt_kwonly_opt(1, b=2) + self.assertEqual(ac_tester.posonly_opt_keywords_opt_kwonly_opt(1, 2, 3), (1, 2, 3, None)) + self.assertEqual(ac_tester.posonly_opt_keywords_opt_kwonly_opt(1, 2, c=3), (1, 2, 3, None)) + self.assertEqual(ac_tester.posonly_opt_keywords_opt_kwonly_opt(1, 2, 3, d=4), (1, 2, 3, 4)) + self.assertEqual(ac_tester.posonly_opt_keywords_opt_kwonly_opt(1, 2, c=3, d=4), (1, 2, 3, 4)) + with self.assertRaises(TypeError): + ac_tester.posonly_opt_keywords_opt_kwonly_opt(1, 2, 3, 4) + + def test_keyword_only_parameter(self): + with self.assertRaises(TypeError): + ac_tester.keyword_only_parameter() + with self.assertRaises(TypeError): + ac_tester.keyword_only_parameter(1) + self.assertEqual(ac_tester.keyword_only_parameter(a=1), (1,)) + + def test_posonly_vararg(self): + with self.assertRaises(TypeError): + ac_tester.posonly_vararg() + self.assertEqual(ac_tester.posonly_vararg(1, 2), (1, 2, ())) + self.assertEqual(ac_tester.posonly_vararg(1, b=2), (1, 2, ())) + self.assertEqual(ac_tester.posonly_vararg(1, 2, 3, 4), (1, 2, (3, 4))) + + def test_vararg_and_posonly(self): + with self.assertRaises(TypeError): + ac_tester.vararg_and_posonly() + with self.assertRaises(TypeError): + ac_tester.vararg_and_posonly(1, b=2) + self.assertEqual(ac_tester.vararg_and_posonly(1, 2, 3, 4), (1, (2, 3, 4))) + + def test_vararg(self): + with self.assertRaises(TypeError): + ac_tester.vararg() + with self.assertRaises(TypeError): + ac_tester.vararg(1, b=2) + self.assertEqual(ac_tester.vararg(1, 2, 3, 4), (1, (2, 3, 4))) + + def test_vararg_with_default(self): + with self.assertRaises(TypeError): + ac_tester.vararg_with_default() + self.assertEqual(ac_tester.vararg_with_default(1, b=False), (1, (), False)) + self.assertEqual(ac_tester.vararg_with_default(1, 2, 3, 4), (1, (2, 3, 4), False)) + self.assertEqual(ac_tester.vararg_with_default(1, 2, 3, 4, b=True), (1, (2, 3, 4), True)) + + def test_vararg_with_only_defaults(self): + self.assertEqual(ac_tester.vararg_with_only_defaults(), ((), None)) + self.assertEqual(ac_tester.vararg_with_only_defaults(b=2), ((), 2)) + self.assertEqual(ac_tester.vararg_with_only_defaults(1, b=2), ((1, ), 2)) + self.assertEqual(ac_tester.vararg_with_only_defaults(1, 2, 3, 4), ((1, 2, 3, 4), None)) + self.assertEqual(ac_tester.vararg_with_only_defaults(1, 2, 3, 4, b=5), ((1, 2, 3, 4), 5)) + + def test_gh_32092_oob(self): + ac_tester.gh_32092_oob(1, 2, 3, 4, kw1=5, kw2=6) + + def test_gh_32092_kw_pass(self): + ac_tester.gh_32092_kw_pass(1, 2, 3) + + def test_gh_99233_refcount(self): + arg = '*A unique string is not referenced by anywhere else.*' + arg_refcount_origin = sys.getrefcount(arg) + ac_tester.gh_99233_refcount(arg) + arg_refcount_after = sys.getrefcount(arg) + self.assertEqual(arg_refcount_origin, arg_refcount_after) + + def test_gh_99240_double_free(self): + expected_error = r'gh_99240_double_free\(\) argument 2 must be encoded string without null bytes, not str' + with self.assertRaisesRegex(TypeError, expected_error): + ac_tester.gh_99240_double_free('a', '\0b') + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_cmath.py b/Lib/test/test_cmath.py index 4bdec6d2d83..9fa08dc4ff3 100644 --- a/Lib/test/test_cmath.py +++ b/Lib/test/test_cmath.py @@ -192,14 +192,7 @@ class CMathTests(unittest.TestCase): # end up being passed to the cmath functions # usual case: new-style class implementing __complex__ - class MyComplex(object): - def __init__(self, value): - self.value = value - def __complex__(self): - return self.value - - # old-style class implementing __complex__ - class MyComplexOS: + class MyComplex: def __init__(self, value): self.value = value def __complex__(self): @@ -208,18 +201,13 @@ class CMathTests(unittest.TestCase): # classes for which __complex__ raises an exception class SomeException(Exception): pass - class MyComplexException(object): - def __complex__(self): - raise SomeException - class MyComplexExceptionOS: + class MyComplexException: def __complex__(self): raise SomeException # some classes not providing __float__ or __complex__ class NeitherComplexNorFloat(object): pass - class NeitherComplexNorFloatOS: - pass class Index: def __int__(self): return 2 def __index__(self): return 2 @@ -228,48 +216,32 @@ class CMathTests(unittest.TestCase): # other possible combinations of __float__ and __complex__ # that should work - class FloatAndComplex(object): + class FloatAndComplex: def __float__(self): return flt_arg def __complex__(self): return cx_arg - class FloatAndComplexOS: - def __float__(self): - return flt_arg - def __complex__(self): - return cx_arg - class JustFloat(object): - def __float__(self): - return flt_arg - class JustFloatOS: + class JustFloat: def __float__(self): return flt_arg for f in self.test_functions: # usual usage self.assertEqual(f(MyComplex(cx_arg)), f(cx_arg)) - self.assertEqual(f(MyComplexOS(cx_arg)), f(cx_arg)) # other combinations of __float__ and __complex__ self.assertEqual(f(FloatAndComplex()), f(cx_arg)) - self.assertEqual(f(FloatAndComplexOS()), f(cx_arg)) self.assertEqual(f(JustFloat()), f(flt_arg)) - self.assertEqual(f(JustFloatOS()), f(flt_arg)) self.assertEqual(f(Index()), f(int(Index()))) # TypeError should be raised for classes not providing # either __complex__ or __float__, even if they provide - # __int__ or __index__. An old-style class - # currently raises AttributeError instead of a TypeError; - # this could be considered a bug. + # __int__ or __index__: self.assertRaises(TypeError, f, NeitherComplexNorFloat()) self.assertRaises(TypeError, f, MyInt()) - self.assertRaises(Exception, f, NeitherComplexNorFloatOS()) # non-complex return value from __complex__ -> TypeError for bad_complex in non_complexes: self.assertRaises(TypeError, f, MyComplex(bad_complex)) - self.assertRaises(TypeError, f, MyComplexOS(bad_complex)) # exceptions in __complex__ should be propagated correctly self.assertRaises(SomeException, f, MyComplexException()) - self.assertRaises(SomeException, f, MyComplexExceptionOS()) def test_input_type(self): # ints should be acceptable inputs to all cmath diff --git a/Lib/test/test_cmd.py b/Lib/test/test_cmd.py index 5e8b17c6e87..319801c71f7 100644 --- a/Lib/test/test_cmd.py +++ b/Lib/test/test_cmd.py @@ -70,7 +70,7 @@ class samplecmdclass(cmd.Cmd): >>> mycmd.complete_help("12") [] >>> sorted(mycmd.complete_help("")) - ['add', 'exit', 'help', 'shell'] + ['add', 'exit', 'help', 'life', 'meaning', 'shell'] Test for the function do_help(): >>> mycmd.do_help("testet") @@ -79,12 +79,20 @@ class samplecmdclass(cmd.Cmd): help text for add >>> mycmd.onecmd("help add") help text for add + >>> mycmd.onecmd("help meaning") # doctest: +NORMALIZE_WHITESPACE + Try and be nice to people, avoid eating fat, read a good book every + now and then, get some walking in, and try to live together in peace + and harmony with people of all creeds and nations. >>> mycmd.do_help("") Documented commands (type help ): ======================================== add help + Miscellaneous help topics: + ========================== + life meaning + Undocumented commands: ====================== exit shell @@ -115,17 +123,22 @@ class samplecmdclass(cmd.Cmd): This test includes the preloop(), postloop(), default(), emptyline(), parseline(), do_help() functions >>> mycmd.use_rawinput=0 - >>> mycmd.cmdqueue=["", "add", "add 4 5", "help", "help add","exit"] - >>> mycmd.cmdloop() + + >>> mycmd.cmdqueue=["add", "add 4 5", "", "help", "help add", "exit"] + >>> mycmd.cmdloop() # doctest: +REPORT_NDIFF Hello from preloop - help text for add *** invalid number of arguments 9 + 9 Documented commands (type help ): ======================================== add help + Miscellaneous help topics: + ========================== + life meaning + Undocumented commands: ====================== exit shell @@ -165,6 +178,17 @@ class samplecmdclass(cmd.Cmd): print("help text for add") return + def help_meaning(self): + print("Try and be nice to people, avoid eating fat, read a " + "good book every now and then, get some walking in, " + "and try to live together in peace and harmony with " + "people of all creeds and nations.") + return + + def help_life(self): + print("Always look on the bright side of life") + return + def do_exit(self, arg): return True diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 86ee27485c9..94298003063 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -15,9 +15,8 @@ from test.support.script_helper import ( interpreter_requires_environment ) - -# Debug build? -Py_DEBUG = hasattr(sys, "gettotalrefcount") +if not support.has_subprocess_support: + raise unittest.SkipTest("test module requires subprocess") # XXX (ncoghlan): Move to script_helper and make consistent with run_python @@ -26,16 +25,47 @@ def _kill_python_and_exit_code(p): returncode = p.wait() return data, returncode + class CmdLineTest(unittest.TestCase): def test_directories(self): assert_python_failure('.') assert_python_failure('< .') def verify_valid_flag(self, cmd_line): - rc, out, err = assert_python_ok(*cmd_line) + rc, out, err = assert_python_ok(cmd_line) self.assertTrue(out == b'' or out.endswith(b'\n')) self.assertNotIn(b'Traceback', out) self.assertNotIn(b'Traceback', err) + return out + + def test_help(self): + self.verify_valid_flag('-h') + self.verify_valid_flag('-?') + out = self.verify_valid_flag('--help') + lines = out.splitlines() + self.assertIn(b'usage', lines[0]) + self.assertNotIn(b'PYTHONHOME', out) + self.assertNotIn(b'-X dev', out) + self.assertLess(len(lines), 50) + + def test_help_env(self): + out = self.verify_valid_flag('--help-env') + self.assertIn(b'PYTHONHOME', out) + + def test_help_xoptions(self): + out = self.verify_valid_flag('--help-xoptions') + self.assertIn(b'-X dev', out) + + def test_help_all(self): + out = self.verify_valid_flag('--help-all') + lines = out.splitlines() + self.assertIn(b'usage', lines[0]) + self.assertIn(b'PYTHONHOME', out) + self.assertIn(b'-X dev', out) + + # The first line contains the program name, + # but the rest should be ASCII-only + b''.join(lines[1:]).decode('ascii') def test_optimize(self): self.verify_valid_flag('-O') @@ -44,14 +74,6 @@ class CmdLineTest(unittest.TestCase): def test_site_flag(self): self.verify_valid_flag('-S') - def test_usage(self): - rc, out, err = assert_python_ok('-h') - lines = out.splitlines() - self.assertIn(b'usage', lines[0]) - # The first line contains the program name, - # but the rest should be ASCII-only - b''.join(lines[1:]).decode('ascii') - def test_version(self): version = ('Python %d.%d' % sys.version_info[:2]).encode("ascii") for switch in '-V', '--version', '-VV': @@ -83,17 +105,8 @@ class CmdLineTest(unittest.TestCase): opts = get_xoptions() self.assertEqual(opts, {}) - opts = get_xoptions('-Xno_debug_ranges', '-Xdev=1234') - self.assertEqual(opts, {'no_debug_ranges': True, 'dev': '1234'}) - - @unittest.skipIf(interpreter_requires_environment(), - 'Cannot run -E tests when PYTHON env vars are required.') - def test_unknown_xoptions(self): - rc, out, err = assert_python_failure('-X', 'blech') - self.assertIn(b'Unknown value for option -X', err) - msg = b'Fatal Python error: Unknown value for option -X' - self.assertEqual(err.splitlines().count(msg), 1) - self.assertEqual(b'', out) + opts = get_xoptions('-Xa', '-Xb=c,d=e') + self.assertEqual(opts, {'a': True, 'b': 'c,d=e'}) def test_showrefcount(self): def run_python(*args): @@ -116,10 +129,13 @@ class CmdLineTest(unittest.TestCase): self.assertEqual(out.rstrip(), b'{}') self.assertEqual(err, b'') # "-X showrefcount" shows the refcount, but only in debug builds - rc, out, err = run_python('-X', 'showrefcount', '-c', code) + rc, out, err = run_python('-I', '-X', 'showrefcount', '-c', code) self.assertEqual(out.rstrip(), b"{'showrefcount': True}") - if Py_DEBUG: - self.assertRegex(err, br'^\[\d+ refs, \d+ blocks\]') + if support.Py_DEBUG: + # bpo-46417: Tolerate negative reference count which can occur + # because of bugs in C extensions. This test is only about checking + # the showrefcount feature. + self.assertRegex(err, br'^\[-?\d+ refs, \d+ blocks\]') else: self.assertEqual(err, b'') @@ -132,7 +148,6 @@ class CmdLineTest(unittest.TestCase): } for raw, expected in tests: cmd = ['-X', f'frozen_modules{raw}', - #'-c', 'import os; print(os.__spec__.loader.__name__, end="")'] '-c', 'import os; print(os.__spec__.loader, end="")'] with self.subTest(raw): res = assert_python_ok(*cmd) @@ -161,6 +176,16 @@ class CmdLineTest(unittest.TestCase): self.assertTrue(data.find(b'1 loop') != -1) self.assertTrue(data.find(b'__main__.Timer') != -1) + def test_relativedir_bug46421(self): + # Test `python -m unittest` with a relative directory beginning with ./ + # Note: We have to switch to the project's top module's directory, as per + # the python unittest wiki. We will switch back when we are done. + projectlibpath = os.path.dirname(__file__).removesuffix("test") + with os_helper.change_cwd(projectlibpath): + # Testing with and without ./ + assert_python_ok('-m', 'unittest', "test/test_longexp.py") + assert_python_ok('-m', 'unittest', "./test/test_longexp.py") + def test_run_code(self): # Test expected operation of the '-c' switch # Switch needs an argument @@ -200,7 +225,7 @@ class CmdLineTest(unittest.TestCase): code = ( b'import locale; ' b'print(ascii("' + undecodable + b'"), ' - b'locale.getpreferredencoding())') + b'locale.getencoding())') p = subprocess.Popen( [sys.executable, "-c", code], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, @@ -234,7 +259,6 @@ class CmdLineTest(unittest.TestCase): # # Test with default config, in the C locale, in the Python UTF-8 Mode. code = 'import sys, os; s=os.fsencode(sys.argv[1]); print(ascii(s))' - base_cmd = [sys.executable, '-c', code] def run_default(arg): cmd = [sys.executable, '-c', code, arg] @@ -347,6 +371,8 @@ class CmdLineTest(unittest.TestCase): self.assertIn(path1.encode('ascii'), out) self.assertIn(path2.encode('ascii'), out) + @unittest.skipIf(sys.flags.safe_path, + 'PYTHONSAFEPATH changes default sys.path') def test_empty_PYTHONPATH_issue16309(self): # On Posix, it is documented that setting PATH to the # empty string is equivalent to not setting PATH at all, @@ -563,13 +589,13 @@ class CmdLineTest(unittest.TestCase): 'Cannot run -I tests when PYTHON env vars are required.') def test_isolatedmode(self): self.verify_valid_flag('-I') - self.verify_valid_flag('-IEs') + self.verify_valid_flag('-IEPs') rc, out, err = assert_python_ok('-I', '-c', 'from sys import flags as f; ' - 'print(f.no_user_site, f.ignore_environment, f.isolated)', + 'print(f.no_user_site, f.ignore_environment, f.isolated, f.safe_path)', # dummyvar to prevent extraneous -E dummyvar="") - self.assertEqual(out.strip(), b'1 1 1') + self.assertEqual(out.strip(), b'1 1 1 True') with os_helper.temp_cwd() as tmpdir: fake = os.path.join(tmpdir, "uuid.py") main = os.path.join(tmpdir, "main.py") @@ -578,9 +604,10 @@ class CmdLineTest(unittest.TestCase): with open(main, "w", encoding="utf-8") as f: f.write("import uuid\n") f.write("print('ok')\n") + # Use -E to ignore PYTHONSAFEPATH env var self.assertRaises(subprocess.CalledProcessError, subprocess.check_output, - [sys.executable, main], cwd=tmpdir, + [sys.executable, '-E', main], cwd=tmpdir, stderr=subprocess.DEVNULL) out = subprocess.check_output([sys.executable, "-I", main], cwd=tmpdir) @@ -666,7 +693,7 @@ class CmdLineTest(unittest.TestCase): code = ("import warnings; " "print(' '.join('%s::%s' % (f[0], f[2].__name__) " "for f in warnings.filters))") - if Py_DEBUG: + if support.Py_DEBUG: expected_filters = "default::Warning" else: expected_filters = ("default::Warning " @@ -738,7 +765,7 @@ class CmdLineTest(unittest.TestCase): expected_filters = ("error::BytesWarning " "once::UserWarning " "always::UserWarning") - if not Py_DEBUG: + if not support.Py_DEBUG: expected_filters += (" " "default::DeprecationWarning " "ignore::DeprecationWarning " @@ -776,10 +803,10 @@ class CmdLineTest(unittest.TestCase): # Test the PYTHONMALLOC environment variable pymalloc = support.with_pymalloc() if pymalloc: - default_name = 'pymalloc_debug' if Py_DEBUG else 'pymalloc' + default_name = 'pymalloc_debug' if support.Py_DEBUG else 'pymalloc' default_name_debug = 'pymalloc_debug' else: - default_name = 'malloc_debug' if Py_DEBUG else 'malloc' + default_name = 'malloc_debug' if support.Py_DEBUG else 'malloc' default_name_debug = 'malloc_debug' tests = [ @@ -838,6 +865,42 @@ class CmdLineTest(unittest.TestCase): self.assertTrue(proc.stderr.startswith(err_msg), proc.stderr) self.assertNotEqual(proc.returncode, 0) + def test_int_max_str_digits(self): + code = "import sys; print(sys.flags.int_max_str_digits, sys.get_int_max_str_digits())" + + assert_python_failure('-X', 'int_max_str_digits', '-c', code) + assert_python_failure('-X', 'int_max_str_digits=foo', '-c', code) + assert_python_failure('-X', 'int_max_str_digits=100', '-c', code) + assert_python_failure('-X', 'int_max_str_digits', '-c', code, + PYTHONINTMAXSTRDIGITS='4000') + + assert_python_failure('-c', code, PYTHONINTMAXSTRDIGITS='foo') + assert_python_failure('-c', code, PYTHONINTMAXSTRDIGITS='100') + + def res2int(res): + out = res.out.strip().decode("utf-8") + return tuple(int(i) for i in out.split()) + + res = assert_python_ok('-c', code) + current_max = sys.get_int_max_str_digits() + self.assertEqual(res2int(res), (current_max, current_max)) + res = assert_python_ok('-X', 'int_max_str_digits=0', '-c', code) + self.assertEqual(res2int(res), (0, 0)) + res = assert_python_ok('-X', 'int_max_str_digits=4000', '-c', code) + self.assertEqual(res2int(res), (4000, 4000)) + res = assert_python_ok('-X', 'int_max_str_digits=100000', '-c', code) + self.assertEqual(res2int(res), (100000, 100000)) + + res = assert_python_ok('-c', code, PYTHONINTMAXSTRDIGITS='0') + self.assertEqual(res2int(res), (0, 0)) + res = assert_python_ok('-c', code, PYTHONINTMAXSTRDIGITS='4000') + self.assertEqual(res2int(res), (4000, 4000)) + res = assert_python_ok( + '-X', 'int_max_str_digits=6000', '-c', code, + PYTHONINTMAXSTRDIGITS='4000' + ) + self.assertEqual(res2int(res), (6000, 6000)) + @unittest.skipIf(interpreter_requires_environment(), 'Cannot run -I tests when PYTHON env vars are required.') @@ -864,7 +927,8 @@ class IgnoreEnvironmentTest(unittest.TestCase): # Issue 31845: a startup refactoring broke reading flags from env vars expected_outcome = """ (sys.flags.debug == sys.flags.optimize == - sys.flags.dont_write_bytecode == sys.flags.verbose == 0) + sys.flags.dont_write_bytecode == + sys.flags.verbose == sys.flags.safe_path == 0) """ self.run_ignoring_vars( expected_outcome, @@ -872,8 +936,10 @@ class IgnoreEnvironmentTest(unittest.TestCase): PYTHONOPTIMIZE="1", PYTHONDONTWRITEBYTECODE="1", PYTHONVERBOSE="1", + PYTHONSAFEPATH="1", ) + class SyntaxErrorTests(unittest.TestCase): def check_string(self, code): proc = subprocess.run([sys.executable, "-"], input=code, diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py index 9fe748c1870..f10d72ea554 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -116,7 +116,9 @@ class CmdLineTest(unittest.TestCase): self.assertIn(printed_file.encode('utf-8'), data) self.assertIn(printed_package.encode('utf-8'), data) self.assertIn(printed_argv0.encode('utf-8'), data) - self.assertIn(printed_path0.encode('utf-8'), data) + # PYTHONSAFEPATH=1 changes the default sys.path[0] + if not sys.flags.safe_path: + self.assertIn(printed_path0.encode('utf-8'), data) self.assertIn(printed_cwd.encode('utf-8'), data) def _check_script(self, script_exec_args, expected_file, @@ -547,17 +549,18 @@ class CmdLineTest(unittest.TestCase): script_name = _make_test_script(script_dir, 'script', script) exitcode, stdout, stderr = assert_python_failure(script_name) text = stderr.decode('ascii').split('\n') - self.assertEqual(len(text), 6) + self.assertEqual(len(text), 5) self.assertTrue(text[0].startswith('Traceback')) self.assertTrue(text[1].startswith(' File ')) - self.assertTrue(text[4].startswith('NameError')) + self.assertTrue(text[3].startswith('NameError')) def test_non_ascii(self): # Mac OS X denies the creation of a file with an invalid UTF-8 name. # Windows allows creating a name with an arbitrary bytes name, but # Python cannot a undecodable bytes argument to a subprocess. + # WASI does not permit invalid UTF-8 names. if (os_helper.TESTFN_UNDECODABLE - and sys.platform not in ('win32', 'darwin')): + and sys.platform not in ('win32', 'darwin', 'emscripten', 'wasi')): name = os.fsdecode(os_helper.TESTFN_UNDECODABLE) elif os_helper.TESTFN_NONASCII: name = os_helper.TESTFN_NONASCII @@ -654,6 +657,18 @@ class CmdLineTest(unittest.TestCase): ], ) + def test_syntaxerror_null_bytes(self): + script = "x = '\0' nothing to see here\n';import os;os.system('echo pwnd')\n" + with os_helper.temp_dir() as script_dir: + script_name = _make_test_script(script_dir, 'script', script) + exitcode, stdout, stderr = assert_python_failure(script_name) + self.assertEqual( + stderr.splitlines()[-2:], + [ b" x = '", + b'SyntaxError: source code cannot contain null bytes' + ], + ) + def test_consistent_sys_path_for_direct_execution(self): # This test case ensures that the following all give the same # sys.path configuration: @@ -737,6 +752,23 @@ class CmdLineTest(unittest.TestCase): self.assertIn(": can't open file ", err) self.assertNotEqual(proc.returncode, 0) + @unittest.skipUnless(os.path.exists('/dev/fd/0'), 'requires /dev/fd platform') + @unittest.skipIf(sys.platform.startswith("freebsd") and + os.stat("/dev").st_dev == os.stat("/dev/fd").st_dev, + "Requires fdescfs mounted on /dev/fd on FreeBSD") + def test_script_as_dev_fd(self): + # GH-87235: On macOS passing a non-trivial script to /dev/fd/N can cause + # problems because all open /dev/fd/N file descriptors share the same + # offset. + script = 'print("12345678912345678912345")' + with os_helper.temp_dir() as work_dir: + script_name = _make_test_script(work_dir, 'script.py', script) + with open(script_name, "r") as fp: + p = spawn_python(f"/dev/fd/{fp.fileno()}", close_fds=False, pass_fds=(0,1,2,fp.fileno())) + out, err = p.communicate() + self.assertEqual(out, b"12345678912345678912345\n") + + def tearDownModule(): support.reap_children() diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index 0d46258d0c3..67ed1694205 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -132,6 +132,7 @@ import doctest import unittest import textwrap import weakref +import dis try: import ctypes @@ -141,6 +142,9 @@ from test.support import (cpython_only, check_impl_detail, requires_debug_ranges, gc_collect) from test.support.script_helper import assert_python_ok +from test.support import threading_helper +from opcode import opmap, opname +COPY_FREE_VARS = opmap['COPY_FREE_VARS'] def consts(t): @@ -174,6 +178,9 @@ class CodeTest(unittest.TestCase): self.assertEqual(co.co_filename, "filename") self.assertEqual(co.co_name, "funcname") self.assertEqual(co.co_firstlineno, 15) + #Empty code object should raise, but not crash the VM + with self.assertRaises(Exception): + exec(co) @cpython_only def test_closure_injection(self): @@ -185,7 +192,7 @@ class CodeTest(unittest.TestCase): def new_code(c): '''A new code object with a __class__ cell added to freevars''' - return c.replace(co_freevars=c.co_freevars + ('__class__',)) + return c.replace(co_freevars=c.co_freevars + ('__class__',), co_code=bytes([COPY_FREE_VARS, 1])+c.co_code) def add_foreign_method(cls, name, f): code = new_code(f.__code__) @@ -228,9 +235,7 @@ class CodeTest(unittest.TestCase): co.co_name, co.co_qualname, co.co_firstlineno, - co.co_lnotab, - co.co_endlinetable, - co.co_columntable, + co.co_linetable, co.co_exceptiontable, co.co_freevars, co.co_cellvars) @@ -271,8 +276,6 @@ class CodeTest(unittest.TestCase): ("co_filename", "newfilename"), ("co_name", "newname"), ("co_linetable", code2.co_linetable), - ("co_endlinetable", code2.co_endlinetable), - ("co_columntable", code2.co_columntable), ): with self.subTest(attr=attr, value=value): new_code = code.replace(**{attr: value}) @@ -309,9 +312,7 @@ class CodeTest(unittest.TestCase): co.co_name, co.co_qualname, co.co_firstlineno, - co.co_lnotab, - co.co_endlinetable, - co.co_columntable, + co.co_linetable, co.co_exceptiontable, co.co_freevars, co.co_cellvars, @@ -337,6 +338,21 @@ class CodeTest(unittest.TestCase): new_code = code = func.__code__.replace(co_linetable=b'') self.assertEqual(list(new_code.co_lines()), []) + def test_invalid_bytecode(self): + def foo(): + pass + + # assert that opcode 238 is invalid + self.assertEqual(opname[238], '<238>') + + # change first opcode to 0xee (=238) + foo.__code__ = foo.__code__.replace( + co_code=b'\xee' + foo.__code__.co_code[1:]) + + msg = f"unknown opcode 238" + with self.assertRaisesRegex(SystemError, msg): + foo() + @requires_debug_ranges() def test_co_positions_artificial_instructions(self): import dis @@ -355,7 +371,7 @@ class CodeTest(unittest.TestCase): artificial_instructions = [] for instr, positions in zip( - dis.get_instructions(code), + dis.get_instructions(code, show_caches=True), code.co_positions(), strict=True ): @@ -365,7 +381,7 @@ class CodeTest(unittest.TestCase): # get assigned the first_lineno but they don't have other positions. # There is no easy way of inferring them at that stage, so for now # we don't support it. - self.assertTrue(positions.count(None) in [0, 4]) + self.assertIn(positions.count(None), [0, 3, 4]) if not any(positions): artificial_instructions.append(instr) @@ -381,19 +397,24 @@ class CodeTest(unittest.TestCase): ("STORE_NAME", "e"), # XX: we know the location for this ("DELETE_NAME", "e"), ("RERAISE", 1), - ("POP_EXCEPT_AND_RERAISE", None) + ("COPY", 3), + ("POP_EXCEPT", None), + ("RERAISE", 1) ] ) def test_endline_and_columntable_none_when_no_debug_ranges(self): - # Make sure that if `-X no_debug_ranges` is used, the endlinetable and - # columntable are None. + # Make sure that if `-X no_debug_ranges` is used, there is + # minimal debug info code = textwrap.dedent(""" def f(): pass - assert f.__code__.co_endlinetable is None - assert f.__code__.co_columntable is None + positions = f.__code__.co_positions() + for line, end_line, column, end_column in positions: + assert line == end_line + assert column is None + assert end_column is None """) assert_python_ok('-X', 'no_debug_ranges', '-c', code) @@ -403,8 +424,11 @@ class CodeTest(unittest.TestCase): def f(): pass - assert f.__code__.co_endlinetable is None - assert f.__code__.co_columntable is None + positions = f.__code__.co_positions() + for line, end_line, column, end_column in positions: + assert line == end_line + assert column is None + assert end_column is None """) assert_python_ok('-c', code, PYTHONNODEBUGRANGES='1') @@ -415,29 +439,57 @@ class CodeTest(unittest.TestCase): def func(): x = 1 new_code = func.__code__.replace(co_linetable=b'') - for line, end_line, column, end_column in new_code.co_positions(): + positions = new_code.co_positions() + for line, end_line, column, end_column in positions: self.assertIsNone(line) self.assertEqual(end_line, new_code.co_firstlineno + 1) - @requires_debug_ranges() - def test_co_positions_empty_endlinetable(self): - def func(): - x = 1 - new_code = func.__code__.replace(co_endlinetable=b'') - for line, end_line, column, end_column in new_code.co_positions(): - self.assertEqual(line, new_code.co_firstlineno + 1) - self.assertIsNone(end_line) + def test_code_equality(self): + def f(): + try: + a() + except: + b() + else: + c() + finally: + d() + code_a = f.__code__ + code_b = code_a.replace(co_linetable=b"") + code_c = code_a.replace(co_exceptiontable=b"") + code_d = code_b.replace(co_exceptiontable=b"") + self.assertNotEqual(code_a, code_b) + self.assertNotEqual(code_a, code_c) + self.assertNotEqual(code_a, code_d) + self.assertNotEqual(code_b, code_c) + self.assertNotEqual(code_b, code_d) + self.assertNotEqual(code_c, code_d) - @requires_debug_ranges() - def test_co_positions_empty_columntable(self): - def func(): - x = 1 - new_code = func.__code__.replace(co_columntable=b'') - for line, end_line, column, end_column in new_code.co_positions(): - self.assertEqual(line, new_code.co_firstlineno + 1) - self.assertEqual(end_line, new_code.co_firstlineno + 1) - self.assertIsNone(column) - self.assertIsNone(end_column) + def test_code_hash_uses_firstlineno(self): + c1 = (lambda: 1).__code__ + c2 = (lambda: 1).__code__ + self.assertNotEqual(c1, c2) + self.assertNotEqual(hash(c1), hash(c2)) + c3 = c1.replace(co_firstlineno=17) + self.assertNotEqual(c1, c3) + self.assertNotEqual(hash(c1), hash(c3)) + + def test_code_hash_uses_order(self): + # Swapping posonlyargcount and kwonlyargcount should change the hash. + c = (lambda x, y, *, z=1, w=1: 1).__code__ + self.assertEqual(c.co_argcount, 2) + self.assertEqual(c.co_posonlyargcount, 0) + self.assertEqual(c.co_kwonlyargcount, 2) + swapped = c.replace(co_posonlyargcount=2, co_kwonlyargcount=0) + self.assertNotEqual(c, swapped) + self.assertNotEqual(hash(c), hash(swapped)) + + def test_code_hash_uses_bytecode(self): + c = (lambda x, y: x + y).__code__ + d = (lambda x, y: x * y).__code__ + c1 = c.replace(co_code=d.co_code) + self.assertNotEqual(c, c1) + self.assertNotEqual(hash(c), hash(c1)) def isinterned(s): @@ -516,6 +568,184 @@ class CodeWeakRefTest(unittest.TestCase): self.assertFalse(bool(coderef())) self.assertTrue(self.called) +# Python implementation of location table parsing algorithm +def read(it): + return next(it) + +def read_varint(it): + b = read(it) + val = b & 63; + shift = 0; + while b & 64: + b = read(it) + shift += 6 + val |= (b&63) << shift + return val + +def read_signed_varint(it): + uval = read_varint(it) + if uval & 1: + return -(uval >> 1) + else: + return uval >> 1 + +def parse_location_table(code): + line = code.co_firstlineno + it = iter(code.co_linetable) + while True: + try: + first_byte = read(it) + except StopIteration: + return + code = (first_byte >> 3) & 15 + length = (first_byte & 7) + 1 + if code == 15: + yield (code, length, None, None, None, None) + elif code == 14: + line_delta = read_signed_varint(it) + line += line_delta + end_line = line + read_varint(it) + col = read_varint(it) + if col == 0: + col = None + else: + col -= 1 + end_col = read_varint(it) + if end_col == 0: + end_col = None + else: + end_col -= 1 + yield (code, length, line, end_line, col, end_col) + elif code == 13: # No column + line_delta = read_signed_varint(it) + line += line_delta + yield (code, length, line, line, None, None) + elif code in (10, 11, 12): # new line + line_delta = code - 10 + line += line_delta + column = read(it) + end_column = read(it) + yield (code, length, line, line, column, end_column) + else: + assert (0 <= code < 10) + second_byte = read(it) + column = code << 3 | (second_byte >> 4) + yield (code, length, line, line, column, column + (second_byte & 15)) + +def positions_from_location_table(code): + for _, length, line, end_line, col, end_col in parse_location_table(code): + for _ in range(length): + yield (line, end_line, col, end_col) + +def dedup(lst, prev=object()): + for item in lst: + if item != prev: + yield item + prev = item + +def lines_from_postions(positions): + return dedup(l for (l, _, _, _) in positions) + +def misshappen(): + """ + + + + + + """ + x = ( + + + 4 + + + + + y + + ) + y = ( + a + + + b + + + + d + ) + return q if ( + + x + + ) else p + +def bug93662(): + example_report_generation_message= ( + """ + """ + ).strip() + raise ValueError() + + +class CodeLocationTest(unittest.TestCase): + + def check_positions(self, func): + pos1 = list(func.__code__.co_positions()) + pos2 = list(positions_from_location_table(func.__code__)) + for l1, l2 in zip(pos1, pos2): + self.assertEqual(l1, l2) + self.assertEqual(len(pos1), len(pos2)) + + def test_positions(self): + self.check_positions(parse_location_table) + self.check_positions(misshappen) + self.check_positions(bug93662) + + def check_lines(self, func): + co = func.__code__ + lines1 = [line for _, _, line in co.co_lines()] + self.assertEqual(lines1, list(dedup(lines1))) + lines2 = list(lines_from_postions(positions_from_location_table(co))) + for l1, l2 in zip(lines1, lines2): + self.assertEqual(l1, l2) + self.assertEqual(len(lines1), len(lines2)) + + def test_lines(self): + self.check_lines(parse_location_table) + self.check_lines(misshappen) + self.check_lines(bug93662) + + @cpython_only + def test_code_new_empty(self): + # If this test fails, it means that the construction of PyCode_NewEmpty + # needs to be modified! Please update this test *and* PyCode_NewEmpty, + # so that they both stay in sync. + def f(): + pass + PY_CODE_LOCATION_INFO_NO_COLUMNS = 13 + f.__code__ = f.__code__.replace( + co_firstlineno=42, + co_code=bytes( + [ + dis.opmap["RESUME"], 0, + dis.opmap["LOAD_ASSERTION_ERROR"], 0, + dis.opmap["RAISE_VARARGS"], 1, + ] + ), + co_linetable=bytes( + [ + (1 << 7) + | (PY_CODE_LOCATION_INFO_NO_COLUMNS << 3) + | (3 - 1), + 0, + ] + ), + ) + self.assertRaises(AssertionError, f) + self.assertEqual( + list(f.__code__.co_positions()), + 3 * [(42, 42, None, None)], + ) + if check_impl_detail(cpython=True) and ctypes is not None: py = ctypes.pythonapi @@ -589,6 +819,7 @@ if check_impl_detail(cpython=True) and ctypes is not None: self.assertEqual(extra.value, 300) del f + @threading_helper.requires_working_threading() def test_free_different_thread(self): # Freeing a code object on a different thread then # where the co_extra was set should be safe. diff --git a/Lib/test/test_codeccallbacks.py b/Lib/test/test_codeccallbacks.py index 243f002c4ec..4991330489d 100644 --- a/Lib/test/test_codeccallbacks.py +++ b/Lib/test/test_codeccallbacks.py @@ -1,5 +1,6 @@ import codecs import html.entities +import itertools import sys import unicodedata import unittest @@ -22,6 +23,18 @@ class PosReturn: self.pos = len(exc.object) return ("", oldpos) +class RepeatedPosReturn: + def __init__(self, repl=""): + self.repl = repl + self.pos = 0 + self.count = 0 + + def handle(self, exc): + if self.count > 0: + self.count -= 1 + return (self.repl, self.pos) + return (self.repl, exc.end) + # A UnicodeEncodeError object with a bad start attribute class BadStartUnicodeEncodeError(UnicodeEncodeError): def __init__(self): @@ -783,20 +796,104 @@ class CodecCallbackTest(unittest.TestCase): codecs.lookup_error("namereplace") ) - def test_unencodablereplacement(self): + def test_encode_nonascii_replacement(self): + def handle(exc): + if isinstance(exc, UnicodeEncodeError): + return (repl, exc.end) + raise TypeError("don't know how to handle %r" % exc) + codecs.register_error("test.replacing", handle) + + for enc, input, repl in ( + ("ascii", "[¤]", "abc"), + ("iso-8859-1", "[€]", "½¾"), + ("iso-8859-15", "[¤]", "œŸ"), + ): + res = input.encode(enc, "test.replacing") + self.assertEqual(res, ("[" + repl + "]").encode(enc)) + + for enc, input, repl in ( + ("utf-8", "[\udc80]", "\U0001f40d"), + ("utf-16", "[\udc80]", "\U0001f40d"), + ("utf-32", "[\udc80]", "\U0001f40d"), + ): + with self.subTest(encoding=enc): + with self.assertRaises(UnicodeEncodeError) as cm: + input.encode(enc, "test.replacing") + exc = cm.exception + self.assertEqual(exc.start, 1) + self.assertEqual(exc.end, 2) + self.assertEqual(exc.object, input) + + def test_encode_unencodable_replacement(self): def unencrepl(exc): if isinstance(exc, UnicodeEncodeError): - return ("\u4242", exc.end) + return (repl, exc.end) else: raise TypeError("don't know how to handle %r" % exc) codecs.register_error("test.unencreplhandler", unencrepl) - for enc in ("ascii", "iso-8859-1", "iso-8859-15"): - self.assertRaises( - UnicodeEncodeError, - "\u4242".encode, - enc, - "test.unencreplhandler" - ) + + for enc, input, repl in ( + ("ascii", "[¤]", "½"), + ("iso-8859-1", "[€]", "Å“"), + ("iso-8859-15", "[¤]", "½"), + ("utf-8", "[\udc80]", "\udcff"), + ("utf-16", "[\udc80]", "\udcff"), + ("utf-32", "[\udc80]", "\udcff"), + ): + with self.subTest(encoding=enc): + with self.assertRaises(UnicodeEncodeError) as cm: + input.encode(enc, "test.unencreplhandler") + exc = cm.exception + self.assertEqual(exc.start, 1) + self.assertEqual(exc.end, 2) + self.assertEqual(exc.object, input) + + def test_encode_bytes_replacement(self): + def handle(exc): + if isinstance(exc, UnicodeEncodeError): + return (repl, exc.end) + raise TypeError("don't know how to handle %r" % exc) + codecs.register_error("test.replacing", handle) + + # It works even if the bytes sequence is not decodable. + for enc, input, repl in ( + ("ascii", "[¤]", b"\xbd\xbe"), + ("iso-8859-1", "[€]", b"\xbd\xbe"), + ("iso-8859-15", "[¤]", b"\xbd\xbe"), + ("utf-8", "[\udc80]", b"\xbd\xbe"), + ("utf-16le", "[\udc80]", b"\xbd\xbe"), + ("utf-16be", "[\udc80]", b"\xbd\xbe"), + ("utf-32le", "[\udc80]", b"\xbc\xbd\xbe\xbf"), + ("utf-32be", "[\udc80]", b"\xbc\xbd\xbe\xbf"), + ): + with self.subTest(encoding=enc): + res = input.encode(enc, "test.replacing") + self.assertEqual(res, "[".encode(enc) + repl + "]".encode(enc)) + + def test_encode_odd_bytes_replacement(self): + def handle(exc): + if isinstance(exc, UnicodeEncodeError): + return (repl, exc.end) + raise TypeError("don't know how to handle %r" % exc) + codecs.register_error("test.replacing", handle) + + input = "[\udc80]" + # Tests in which the replacement bytestring contains not whole number + # of code units. + for enc, repl in ( + *itertools.product(("utf-16le", "utf-16be"), + [b"a", b"abc"]), + *itertools.product(("utf-32le", "utf-32be"), + [b"a", b"ab", b"abc", b"abcde"]), + ): + with self.subTest(encoding=enc, repl=repl): + with self.assertRaises(UnicodeEncodeError) as cm: + input.encode(enc, "test.replacing") + exc = cm.exception + self.assertEqual(exc.start, 1) + self.assertEqual(exc.end, 2) + self.assertEqual(exc.object, input) + self.assertEqual(exc.reason, "surrogates not allowed") def test_badregistercall(self): # enhance coverage of: @@ -940,6 +1037,68 @@ class CodecCallbackTest(unittest.TestCase): self.assertRaises(ValueError, codecs.charmap_encode, "\xff", err, D()) self.assertRaises(TypeError, codecs.charmap_encode, "\xff", err, {0xff: 300}) + def test_decodehelper_bug36819(self): + handler = RepeatedPosReturn("x") + codecs.register_error("test.bug36819", handler.handle) + + testcases = [ + ("ascii", b"\xff"), + ("utf-8", b"\xff"), + ("utf-16be", b'\xdc\x80'), + ("utf-32be", b'\x00\x00\xdc\x80'), + ("iso-8859-6", b"\xff"), + ] + for enc, bad in testcases: + input = "abcd".encode(enc) + bad + with self.subTest(encoding=enc): + handler.count = 50 + decoded = input.decode(enc, "test.bug36819") + self.assertEqual(decoded, 'abcdx' * 51) + + def test_encodehelper_bug36819(self): + handler = RepeatedPosReturn() + codecs.register_error("test.bug36819", handler.handle) + + input = "abcd\udc80" + encodings = ["ascii", "latin1", "utf-8", "utf-16", "utf-32"] # built-in + encodings += ["iso-8859-15"] # charmap codec + if sys.platform == 'win32': + encodings = ["mbcs", "oem"] # code page codecs + + handler.repl = "\udcff" + for enc in encodings: + with self.subTest(encoding=enc): + handler.count = 50 + with self.assertRaises(UnicodeEncodeError) as cm: + input.encode(enc, "test.bug36819") + exc = cm.exception + self.assertEqual(exc.start, 4) + self.assertEqual(exc.end, 5) + self.assertEqual(exc.object, input) + if sys.platform == "win32": + handler.count = 50 + with self.assertRaises(UnicodeEncodeError) as cm: + codecs.code_page_encode(437, input, "test.bug36819") + exc = cm.exception + self.assertEqual(exc.start, 4) + self.assertEqual(exc.end, 5) + self.assertEqual(exc.object, input) + + handler.repl = "x" + for enc in encodings: + with self.subTest(encoding=enc): + # The interpreter should segfault after a handful of attempts. + # 50 was chosen to try to ensure a segfault without a fix, + # but not OOM a machine with one. + handler.count = 50 + encoded = input.encode(enc, "test.bug36819") + self.assertEqual(encoded.decode(enc), "abcdx" * 51) + if sys.platform == "win32": + handler.count = 50 + encoded = codecs.code_page_encode(437, input, "test.bug36819") + self.assertEqual(encoded[0].decode(), "abcdx" * 51) + self.assertEqual(encoded[1], len(input)) + def test_translatehelper(self): # enhance coverage of: # Objects/unicodeobject.c::unicode_encode_call_errorhandler() diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index f924826db94..e3add0c1ee9 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -9,12 +9,15 @@ from unittest import mock from test import support from test.support import os_helper -from test.support import warnings_helper try: import _testcapi except ImportError: _testcapi = None +try: + import _testinternalcapi +except ImportError: + _testinternalcapi = None try: import ctypes @@ -32,7 +35,7 @@ def coding_checker(self, coder): # On small versions of Windows like Windows IoT or Windows Nano Server not all codepages are present def is_code_page_present(cp): from ctypes import POINTER, WINFUNCTYPE, WinDLL - from ctypes.wintypes import BOOL, UINT, BYTE, WCHAR, UINT, DWORD + from ctypes.wintypes import BOOL, BYTE, WCHAR, UINT, DWORD MAX_LEADBYTES = 12 # 5 ranges, 2 bytes ea., 0 term. MAX_DEFAULTCHAR = 2 # single or double byte @@ -705,7 +708,8 @@ class UTF16Test(ReadTest, unittest.TestCase): "spamspam", self.spambe) def test_bug691291(self): - # Files are always opened in binary mode, even if no binary mode was + # If encoding is not None, then + # files are always opened in binary mode, even if no binary mode was # specified. This means that no automatic conversion of '\n' is done # on reading and writing. s1 = 'Hello\r\nworld\r\n' @@ -1189,7 +1193,6 @@ class EscapeDecodeTest(unittest.TestCase): check(br"[\418]", b"[!8]") check(br"[\101]", b"[A]") check(br"[\1010]", b"[A0]") - check(br"[\501]", b"[A]") check(br"[\x41]", b"[A]") check(br"[\x410]", b"[A0]") for i in range(97, 123): @@ -1205,6 +1208,9 @@ class EscapeDecodeTest(unittest.TestCase): check(br"\9", b"\\9") with self.assertWarns(DeprecationWarning): check(b"\\\xfa", b"\\\xfa") + for i in range(0o400, 0o1000): + with self.assertWarns(DeprecationWarning): + check(rb'\%o' % i, bytes([i & 0o377])) def test_errors(self): decode = codecs.escape_decode @@ -1546,6 +1552,12 @@ class IDNACodecTest(unittest.TestCase): self.assertEqual("pyth\xf6n.org".encode("idna"), b"xn--pythn-mua.org") self.assertEqual("pyth\xf6n.org.".encode("idna"), b"xn--pythn-mua.org.") + def test_builtin_decode_length_limit(self): + with self.assertRaisesRegex(UnicodeError, "way too long"): + (b"xn--016c"+b"a"*1100).decode("idna") + with self.assertRaisesRegex(UnicodeError, "too long"): + (b"xn--016c"+b"a"*70).decode("idna") + def test_stream(self): r = codecs.getreader("idna")(io.BytesIO(b"abc")) r.read(3) @@ -1900,7 +1912,10 @@ class BasicUnicodeTest(unittest.TestCase, MixInCheckStateHandling): name += "_codec" elif encoding == "latin_1": name = "latin_1" - self.assertEqual(encoding.replace("_", "-"), name.replace("_", "-")) + # Skip the mbcs alias on Windows + if name != "mbcs": + self.assertEqual(encoding.replace("_", "-"), + name.replace("_", "-")) (b, size) = codecs.getencoder(encoding)(s) self.assertEqual(size, len(s), "encoding=%r" % encoding) @@ -2428,6 +2443,9 @@ class UnicodeEscapeTest(ReadTest, unittest.TestCase): check(br"\9", "\\9") with self.assertWarns(DeprecationWarning): check(b"\\\xfa", "\\\xfa") + for i in range(0o400, 0o1000): + with self.assertWarns(DeprecationWarning): + check(rb'\%o' % i, chr(i)) def test_decode_errors(self): decode = codecs.unicode_escape_decode @@ -3186,9 +3204,14 @@ class CodePageTest(unittest.TestCase): def test_mbcs_alias(self): # Check that looking up our 'default' codepage will return # mbcs when we don't have a more specific one available - with mock.patch('_winapi.GetACP', return_value=123): - codec = codecs.lookup('cp123') - self.assertEqual(codec.name, 'mbcs') + code_page = 99_999 + name = f'cp{code_page}' + with mock.patch('_winapi.GetACP', return_value=code_page): + try: + codec = codecs.lookup(name) + self.assertEqual(codec.name, 'mbcs') + finally: + codecs.unregister(name) @support.bigmemtest(size=2**31, memuse=7, dry_run=False) def test_large_input(self, size): @@ -3345,7 +3368,7 @@ class StreamRecoderTest(unittest.TestCase): self.assertEqual(sr.readline(), b'789\n') -@unittest.skipIf(_testcapi is None, 'need _testcapi module') +@unittest.skipIf(_testinternalcapi is None, 'need _testinternalcapi module') class LocaleCodecTest(unittest.TestCase): """ Test indirectly _Py_DecodeUTF8Ex() and _Py_EncodeUTF8Ex(). @@ -3359,7 +3382,7 @@ class LocaleCodecTest(unittest.TestCase): SURROGATES = "\uDC80\uDCFF" def encode(self, text, errors="strict"): - return _testcapi.EncodeLocaleEx(text, 0, errors) + return _testinternalcapi.EncodeLocaleEx(text, 0, errors) def check_encode_strings(self, errors): for text in self.STRINGS: @@ -3399,7 +3422,7 @@ class LocaleCodecTest(unittest.TestCase): self.assertEqual(str(cm.exception), 'unsupported error handler') def decode(self, encoded, errors="strict"): - return _testcapi.DecodeLocaleEx(encoded, 0, errors) + return _testinternalcapi.DecodeLocaleEx(encoded, 0, errors) def check_decode_strings(self, errors): is_utf8 = (self.ENCODING == "utf-8") diff --git a/Lib/test/test_codeop.py b/Lib/test/test_codeop.py index 17376c7ed75..6966c2ffd81 100644 --- a/Lib/test/test_codeop.py +++ b/Lib/test/test_codeop.py @@ -2,47 +2,18 @@ Test cases for codeop.py Nick Mathewson """ -import sys import unittest import warnings -from test import support from test.support import warnings_helper from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT -import io - -if support.is_jython: - - def unify_callables(d): - for n,v in d.items(): - if hasattr(v, '__call__'): - d[n] = True - return d class CodeopTests(unittest.TestCase): def assertValid(self, str, symbol='single'): '''succeed iff str is a valid piece of code''' - if support.is_jython: - code = compile_command(str, "", symbol) - self.assertTrue(code) - if symbol == "single": - d,r = {},{} - saved_stdout = sys.stdout - sys.stdout = io.StringIO() - try: - exec(code, d) - exec(compile(str,"","single"), r) - finally: - sys.stdout = saved_stdout - elif symbol == 'eval': - ctx = {'a': 2} - d = { 'value': eval(code,ctx) } - r = { 'value': eval(str,ctx) } - self.assertEqual(unify_callables(r),unify_callables(d)) - else: - expected = compile(str, "", symbol, PyCF_DONT_IMPLY_DEDENT) - self.assertEqual(compile_command(str, "", symbol), expected) + expected = compile(str, "", symbol, PyCF_DONT_IMPLY_DEDENT) + self.assertEqual(compile_command(str, "", symbol), expected) def assertIncomplete(self, str, symbol='single'): '''succeed iff str is the start of a valid piece of code''' @@ -62,16 +33,12 @@ class CodeopTests(unittest.TestCase): av = self.assertValid # special case - if not support.is_jython: - self.assertEqual(compile_command(""), - compile("pass", "", 'single', - PyCF_DONT_IMPLY_DEDENT)) - self.assertEqual(compile_command("\n"), - compile("pass", "", 'single', - PyCF_DONT_IMPLY_DEDENT)) - else: - av("") - av("\n") + self.assertEqual(compile_command(""), + compile("pass", "", 'single', + PyCF_DONT_IMPLY_DEDENT)) + self.assertEqual(compile_command("\n"), + compile("pass", "", 'single', + PyCF_DONT_IMPLY_DEDENT)) av("a = 1") av("\na = 1") @@ -310,8 +277,8 @@ class CodeopTests(unittest.TestCase): def test_warning(self): # Test that the warning is only returned once. with warnings_helper.check_warnings( - (".*literal", SyntaxWarning), - (".*invalid", DeprecationWarning), + ('"is" with a literal', SyntaxWarning), + ("invalid escape sequence", SyntaxWarning), ) as w: compile_command(r"'\e' is 0") self.assertEqual(len(w.warnings), 2) @@ -321,6 +288,26 @@ class CodeopTests(unittest.TestCase): warnings.simplefilter('error', SyntaxWarning) compile_command('1 is 1', symbol='exec') + # Check SyntaxWarning treated as an SyntaxError + with warnings.catch_warnings(), self.assertRaises(SyntaxError): + warnings.simplefilter('error', SyntaxWarning) + compile_command(r"'\e'", symbol='exec') + + def test_incomplete_warning(self): + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + self.assertIncomplete("'\\e' + (") + self.assertEqual(w, []) + + def test_invalid_warning(self): + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + self.assertInvalid("'\\e' 1") + self.assertEqual(len(w), 1) + self.assertEqual(w[0].category, SyntaxWarning) + self.assertRegex(str(w[0].message), 'invalid escape sequence') + self.assertEqual(w[0].filename, '') + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index 1bfd44f9547..bfe18c7fc50 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -71,6 +71,14 @@ class TestUserObjects(unittest.TestCase): obj[123] = "abc" self._copy_test(obj) + def test_dict_missing(self): + class A(UserDict): + def __missing__(self, key): + return 456 + self.assertEqual(A()[123], 456) + # get() ignores __missing__ on dict + self.assertIs(A().get(123), None) + ################################################################################ ### ChainMap (helper class for configparser and the string module) @@ -537,7 +545,7 @@ class TestNamedTuple(unittest.TestCase): self.assertEqual(Dot(1)._replace(d=999), (999,)) self.assertEqual(Dot(1)._fields, ('d',)) - n = 5000 + n = support.EXCEEDS_RECURSION_LIMIT names = list(set(''.join([choice(string.ascii_letters) for j in range(10)]) for i in range(n))) n = len(names) @@ -668,6 +676,7 @@ class TestNamedTuple(unittest.TestCase): a.w = 5 self.assertEqual(a.__dict__, {'w': 5}) + @support.cpython_only def test_field_descriptor(self): Point = namedtuple('Point', 'x y') p = Point(11, 22) @@ -676,14 +685,16 @@ class TestNamedTuple(unittest.TestCase): self.assertRaises(AttributeError, Point.x.__set__, p, 33) self.assertRaises(AttributeError, Point.x.__delete__, p) - class NewPoint(tuple): - x = pickle.loads(pickle.dumps(Point.x)) - y = pickle.loads(pickle.dumps(Point.y)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + class NewPoint(tuple): + x = pickle.loads(pickle.dumps(Point.x, proto)) + y = pickle.loads(pickle.dumps(Point.y, proto)) - np = NewPoint([1, 2]) + np = NewPoint([1, 2]) - self.assertEqual(np.x, 1) - self.assertEqual(np.y, 2) + self.assertEqual(np.x, 1) + self.assertEqual(np.y, 2) def test_new_builtins_issue_43102(self): obj = namedtuple('C', ()) @@ -695,6 +706,18 @@ class TestNamedTuple(unittest.TestCase): Point = namedtuple('Point', 'x y') self.assertEqual(Point.__match_args__, ('x', 'y')) + def test_non_generic_subscript(self): + # For backward compatibility, subscription works + # on arbitrary named tuple types. + Group = collections.namedtuple('Group', 'key group') + A = Group[int, list[int]] + self.assertEqual(A.__origin__, Group) + self.assertEqual(A.__parameters__, ()) + self.assertEqual(A.__args__, (int, list[int])) + a = A(1, [2]) + self.assertIs(type(a), Group) + self.assertEqual(a, (1, [2])) + ################################################################################ ### Abstract Base Classes @@ -787,6 +810,8 @@ class TestOneTrickPonyABCs(ABCTestCase): def __await__(self): yield + self.validate_abstract_methods(Awaitable, '__await__') + non_samples = [None, int(), gen(), object()] for x in non_samples: self.assertNotIsInstance(x, Awaitable) @@ -837,6 +862,8 @@ class TestOneTrickPonyABCs(ABCTestCase): def __await__(self): yield + self.validate_abstract_methods(Coroutine, '__await__', 'send', 'throw') + non_samples = [None, int(), gen(), object(), Bar()] for x in non_samples: self.assertNotIsInstance(x, Coroutine) @@ -1579,6 +1606,7 @@ class TestCollectionABCs(ABCTestCase): containers = [ seq, ItemsView({1: nan, 2: obj}), + KeysView({1: nan, 2: obj}), ValuesView({1: nan, 2: obj}) ] for container in containers: @@ -1842,6 +1870,8 @@ class TestCollectionABCs(ABCTestCase): mymap['red'] = 5 self.assertIsInstance(mymap.keys(), Set) self.assertIsInstance(mymap.keys(), KeysView) + self.assertIsInstance(mymap.values(), Collection) + self.assertIsInstance(mymap.values(), ValuesView) self.assertIsInstance(mymap.items(), Set) self.assertIsInstance(mymap.items(), ItemsView) @@ -1917,6 +1947,7 @@ class TestCollectionABCs(ABCTestCase): self.assertFalse(issubclass(sample, ByteString)) self.assertNotIsInstance(memoryview(b""), ByteString) self.assertFalse(issubclass(memoryview, ByteString)) + self.validate_abstract_methods(ByteString, '__getitem__', '__len__') def test_MutableSequence(self): for sample in [tuple, str, bytes]: diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index f72c7ca68f3..05a5ed1fa9a 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -8,8 +8,10 @@ import _ast import tempfile import types import textwrap +import warnings from test import support -from test.support import script_helper, requires_debug_ranges +from test.support import (script_helper, requires_debug_ranges, + requires_specialization) from test.support.os_helper import FakePath @@ -108,8 +110,10 @@ class TestSpecifics(unittest.TestCase): exec('z = a', g, d) self.assertEqual(d['z'], 12) + @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") def test_extended_arg(self): - longexpr = 'x = x or ' + '-x' * 2500 + repeat = 2000 + longexpr = 'x = x or ' + '-x' * repeat g = {} code = ''' def f(x): @@ -158,7 +162,8 @@ if 1: s256 = "".join(["\n"] * 256 + ["spam"]) co = compile(s256, 'fn', 'exec') self.assertEqual(co.co_firstlineno, 1) - self.assertEqual(list(co.co_lines()), [(0, 8, 257)]) + lines = [line for _, _, line in co.co_lines()] + self.assertEqual(lines, [0, 257]) def test_literals_with_leading_zeroes(self): for arg in ["077787", "0xj", "0x.", "0e", "090000000000000", @@ -193,6 +198,19 @@ if 1: self.assertEqual(eval("0o777"), 511) self.assertEqual(eval("-0o0000010"), -8) + def test_int_literals_too_long(self): + n = 3000 + source = f"a = 1\nb = 2\nc = {'3'*n}\nd = 4" + with support.adjust_int_max_str_digits(n): + compile(source, "", "exec") # no errors. + with support.adjust_int_max_str_digits(n-1): + with self.assertRaises(SyntaxError) as err_ctx: + compile(source, "", "exec") + exc = err_ctx.exception + self.assertEqual(exc.lineno, 3) + self.assertIn('Exceeds the limit ', str(exc)) + self.assertIn(' Consider hexadecimal ', str(exc)) + def test_unary_minus(self): # Verify treatment of unary minus on negative numbers SF bug #660455 if sys.maxsize == 2147483647: @@ -476,9 +494,8 @@ if 1: code = compile('pass', filename, 'exec') self.assertEqual(code.co_filename, 'file.py') for filename in bytearray(b'file.py'), memoryview(b'file.py'): - with self.assertWarns(DeprecationWarning): - code = compile('pass', filename, 'exec') - self.assertEqual(code.co_filename, 'file.py') + with self.assertRaises(TypeError): + compile('pass', filename, 'exec') self.assertRaises(TypeError, compile, 'pass', list(b'file.py'), 'exec') @support.cpython_only @@ -504,6 +521,7 @@ if 1: self.compile_single("if x:\n f(x)") self.compile_single("if x:\n f(x)\nelse:\n g(x)") self.compile_single("class T:\n pass") + self.compile_single("c = '''\na=1\nb=2\nc=3\n'''") def test_bad_single_statement(self): self.assertInvalidSingle('1\n2') @@ -514,6 +532,7 @@ if 1: self.assertInvalidSingle('f()\n# blah\nblah()') self.assertInvalidSingle('f()\nxy # blah\nblah()') self.assertInvalidSingle('x = 5 # comment\nx = 6\n') + self.assertInvalidSingle("c = '''\nd=1\n'''\na = 1\n\nb = 2\n") def test_particularly_evil_undecodable(self): # Issue 24022 @@ -523,7 +542,7 @@ if 1: with open(fn, "wb") as fp: fp.write(src) res = script_helper.run_python_until_end(fn)[0] - self.assertIn(b"Non-UTF-8", res.err) + self.assertIn(b"source code cannot contain null bytes", res.err) def test_yet_more_evil_still_undecodable(self): # Issue #25388 @@ -533,9 +552,10 @@ if 1: with open(fn, "wb") as fp: fp.write(src) res = script_helper.run_python_until_end(fn)[0] - self.assertIn(b"Non-UTF-8", res.err) + self.assertIn(b"source code cannot contain null bytes", res.err) @support.cpython_only + @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") def test_compiler_recursion_limit(self): # Expected limit is sys.getrecursionlimit() * the scaling factor # in symtable.c (currently 3) @@ -569,9 +589,9 @@ if 1: def test_null_terminated(self): # The source code is null-terminated internally, but bytes-like # objects are accepted, which could be not terminated. - with self.assertRaisesRegex(ValueError, "cannot contain null"): + with self.assertRaisesRegex(SyntaxError, "cannot contain null"): compile("123\x00", "", "eval") - with self.assertRaisesRegex(ValueError, "cannot contain null"): + with self.assertRaisesRegex(SyntaxError, "cannot contain null"): compile(memoryview(b"123\x00"), "", "eval") code = compile(memoryview(b"123\x00")[1:-1], "", "eval") self.assertEqual(eval(code), 23) @@ -607,7 +627,7 @@ if 1: exec(code, ns) f1 = ns['f1'] f2 = ns['f2'] - self.assertIs(f1.__code__, f2.__code__) + self.assertIs(f1.__code__.co_consts, f2.__code__.co_consts) self.check_constant(f1, const) self.assertEqual(repr(f1()), repr(const)) @@ -620,7 +640,7 @@ if 1: # Note: "lambda: ..." emits "LOAD_CONST Ellipsis", # whereas "lambda: Ellipsis" emits "LOAD_GLOBAL Ellipsis" f1, f2 = lambda: ..., lambda: ... - self.assertIs(f1.__code__, f2.__code__) + self.assertIs(f1.__code__.co_consts, f2.__code__.co_consts) self.check_constant(f1, Ellipsis) self.assertEqual(repr(f1()), repr(Ellipsis)) @@ -635,11 +655,11 @@ if 1: # {0} is converted to a constant frozenset({0}) by the peephole # optimizer f1, f2 = lambda x: x in {0}, lambda x: x in {0} - self.assertIs(f1.__code__, f2.__code__) + self.assertIs(f1.__code__.co_consts, f2.__code__.co_consts) self.check_constant(f1, frozenset({0})) self.assertTrue(f1(0)) - # Merging equal co_linetable and co_code is not a strict requirement + # Merging equal co_linetable is not a strict requirement # for the Python semantics, it's a more an implementation detail. @support.cpython_only def test_merge_code_attrs(self): @@ -648,12 +668,57 @@ if 1: f2 = lambda a: a.b.c self.assertIs(f1.__code__.co_linetable, f2.__code__.co_linetable) - self.assertIs(f1.__code__.co_code, f2.__code__.co_code) + + @support.cpython_only + def test_remove_unused_consts(self): + def f(): + "docstring" + if True: + return "used" + else: + return "unused" + + self.assertEqual(f.__code__.co_consts, + ("docstring", "used")) + + @support.cpython_only + def test_remove_unused_consts_no_docstring(self): + # the first item (None for no docstring in this case) is + # always retained. + def f(): + if True: + return "used" + else: + return "unused" + + self.assertEqual(f.__code__.co_consts, + (None, "used")) + + @support.cpython_only + def test_remove_unused_consts_extended_args(self): + N = 1000 + code = ["def f():\n"] + code.append("\ts = ''\n") + code.append("\tfor i in range(1):\n") + for i in range(N): + code.append(f"\t\tif True: s += 't{i}'\n") + code.append(f"\t\tif False: s += 'f{i}'\n") + code.append("\treturn s\n") + + code = "".join(code) + g = {} + eval(compile(code, "file.py", "exec"), g) + exec(code, g) + f = g['f'] + expected = tuple([None, '', 1] + [f't{i}' for i in range(N)]) + self.assertEqual(f.__code__.co_consts, expected) + expected = "".join(expected[3:]) + self.assertEqual(expected, f()) # Stripping unused constants is not a strict requirement for the # Python semantics, it's a more an implementation detail. @support.cpython_only - def test_strip_unused_consts(self): + def test_strip_unused_None(self): # Python 3.10rc1 appended None to co_consts when None is not used # at all. See bpo-45056. def f1(): @@ -757,7 +822,7 @@ if 1: for func in funcs: opcodes = list(dis.get_instructions(func)) - self.assertLessEqual(len(opcodes), 3) + self.assertLessEqual(len(opcodes), 4) self.assertEqual('LOAD_CONST', opcodes[-2].opname) self.assertEqual(None, opcodes[-2].argval) self.assertEqual('RETURN_VALUE', opcodes[-1].opname) @@ -776,10 +841,10 @@ if 1: # Check that we did not raise but we also don't generate bytecode for func in funcs: opcodes = list(dis.get_instructions(func)) - self.assertEqual(2, len(opcodes)) - self.assertEqual('LOAD_CONST', opcodes[0].opname) - self.assertEqual(None, opcodes[0].argval) - self.assertEqual('RETURN_VALUE', opcodes[1].opname) + self.assertEqual(3, len(opcodes)) + self.assertEqual('LOAD_CONST', opcodes[1].opname) + self.assertEqual(None, opcodes[1].argval) + self.assertEqual('RETURN_VALUE', opcodes[2].opname) def test_consts_in_conditionals(self): def and_true(x): @@ -800,9 +865,9 @@ if 1: for func in funcs: with self.subTest(func=func): opcodes = list(dis.get_instructions(func)) - self.assertEqual(2, len(opcodes)) - self.assertIn('LOAD_', opcodes[0].opname) - self.assertEqual('RETURN_VALUE', opcodes[1].opname) + self.assertLessEqual(len(opcodes), 3) + self.assertIn('LOAD_', opcodes[-2].opname) + self.assertEqual('RETURN_VALUE', opcodes[-1].opname) def test_imported_load_method(self): sources = [ @@ -835,9 +900,8 @@ if 1: opcodes = list(dis.get_instructions(func)) instructions = [opcode.opname for opcode in opcodes] self.assertNotIn('LOAD_METHOD', instructions) - self.assertNotIn('CALL_METHOD', instructions) self.assertIn('LOAD_ATTR', instructions) - self.assertIn('CALL_FUNCTION', instructions) + self.assertIn('CALL', instructions) def test_lineno_procedure_call(self): def call(): @@ -891,20 +955,27 @@ if 1: for func in (no_code1, no_code2): with self.subTest(func=func): code = func.__code__ - lines = list(code.co_lines()) - self.assertEqual(len(lines), 1) - start, end, line = lines[0] + [(start, end, line)] = code.co_lines() self.assertEqual(start, 0) self.assertEqual(end, len(code.co_code)) self.assertEqual(line, code.co_firstlineno) + def get_code_lines(self, code): + last_line = -2 + res = [] + for _, _, line in code.co_lines(): + if line is not None and line != last_line: + res.append(line - code.co_firstlineno) + last_line = line + return res + def test_lineno_attribute(self): def load_attr(): return ( o. a ) - load_attr_lines = [ 2, 3, 1 ] + load_attr_lines = [ 0, 2, 3, 1 ] def load_method(): return ( @@ -913,7 +984,7 @@ if 1: 0 ) ) - load_method_lines = [ 2, 3, 4, 3, 1 ] + load_method_lines = [ 0, 2, 3, 4, 3, 1 ] def store_attr(): ( @@ -922,7 +993,7 @@ if 1: ) = ( v ) - store_attr_lines = [ 5, 2, 3 ] + store_attr_lines = [ 0, 5, 2, 3 ] def aug_store_attr(): ( @@ -931,7 +1002,7 @@ if 1: ) += ( v ) - aug_store_attr_lines = [ 2, 3, 5, 1, 3 ] + aug_store_attr_lines = [ 0, 2, 3, 5, 1, 3 ] funcs = [ load_attr, load_method, store_attr, aug_store_attr] func_lines = [ load_attr_lines, load_method_lines, @@ -939,8 +1010,7 @@ if 1: for func, lines in zip(funcs, func_lines, strict=True): with self.subTest(func=func): - code_lines = [ line-func.__code__.co_firstlineno - for (_, _, line) in func.__code__.co_lines() ] + code_lines = self.get_code_lines(func.__code__) self.assertEqual(lines, code_lines) def test_line_number_genexp(self): @@ -951,11 +1021,10 @@ if 1: x in y) - genexp_lines = [None, 1, 3, 1] + genexp_lines = [0, 2, 0] genexp_code = return_genexp.__code__.co_consts[1] - code_lines = [ None if line is None else line-return_genexp.__code__.co_firstlineno - for (_, _, line) in genexp_code.co_lines() ] + code_lines = self.get_code_lines(genexp_code) self.assertEqual(genexp_lines, code_lines) def test_line_number_implicit_return_after_async_for(self): @@ -964,9 +1033,8 @@ if 1: async for i in aseq: body - expected_lines = [None, 1, 2, 1] - code_lines = [ None if line is None else line-test.__code__.co_firstlineno - for (_, _, line) in test.__code__.co_lines() ] + expected_lines = [0, 1, 2, 1] + code_lines = self.get_code_lines(test.__code__) self.assertEqual(expected_lines, code_lines) def test_big_dict_literal(self): @@ -1000,12 +1068,96 @@ if 1: 'JUMP_FORWARD', ) - for line, instr in enumerate(dis.Bytecode(if_else_break)): + for line, instr in enumerate( + dis.Bytecode(if_else_break, show_caches=True) + ): if instr.opname == 'JUMP_FORWARD': self.assertNotEqual(instr.arg, 0) elif instr.opname in HANDLED_JUMPS: self.assertNotEqual(instr.arg, (line + 1)*INSTR_SIZE) + def test_no_wraparound_jump(self): + # See https://bugs.python.org/issue46724 + + def while_not_chained(a, b, c): + while not (a < b < c): + pass + + for instr in dis.Bytecode(while_not_chained): + self.assertNotEqual(instr.opname, "EXTENDED_ARG") + + @support.cpython_only + def test_uses_slice_instructions(self): + + def check_op_count(func, op, expected): + actual = 0 + for instr in dis.Bytecode(func): + if instr.opname == op: + actual += 1 + self.assertEqual(actual, expected) + + def load(): + return x[a:b] + x [a:] + x[:b] + x[:] + + def store(): + x[a:b] = y + x [a:] = y + x[:b] = y + x[:] = y + + def long_slice(): + return x[a:b:c] + + def aug(): + x[a:b] += y + + check_op_count(load, "BINARY_SLICE", 4) + check_op_count(load, "BUILD_SLICE", 0) + check_op_count(store, "STORE_SLICE", 4) + check_op_count(store, "BUILD_SLICE", 0) + check_op_count(long_slice, "BUILD_SLICE", 1) + check_op_count(long_slice, "BINARY_SLICE", 0) + check_op_count(aug, "BINARY_SLICE", 1) + check_op_count(aug, "STORE_SLICE", 1) + check_op_count(aug, "BUILD_SLICE", 0) + + def test_compare_positions(self): + for opname_prefix, op in [ + ("COMPARE_", "<"), + ("COMPARE_", "<="), + ("COMPARE_", ">"), + ("COMPARE_", ">="), + ("CONTAINS_OP", "in"), + ("CONTAINS_OP", "not in"), + ("IS_OP", "is"), + ("IS_OP", "is not"), + ]: + expr = f'a {op} b {op} c' + expected_positions = 2 * [(2, 2, 0, len(expr))] + for source in [ + f"\\\n{expr}", f'if \\\n{expr}: x', f"x if \\\n{expr} else y" + ]: + code = compile(source, "", "exec") + actual_positions = [ + instruction.positions + for instruction in dis.get_instructions(code) + if instruction.opname.startswith(opname_prefix) + ] + with self.subTest(source): + self.assertEqual(actual_positions, expected_positions) + + def test_if_expression_expression_empty_block(self): + # See regression in gh-99708 + exprs = [ + "assert (False if 1 else True)", + "def f():\n\tif not (False if 1 else True): raise AssertionError", + "def f():\n\tif not (False if 1 else True): return 12", + ] + for expr in exprs: + with self.subTest(expr=expr): + compile(expr, "", "exec") + + @requires_debug_ranges() class TestSourcePositions(unittest.TestCase): # Ensure that compiled code snippets have correct line and column numbers @@ -1023,7 +1175,7 @@ class TestSourcePositions(unittest.TestCase): class SourceOffsetVisitor(ast.NodeVisitor): def generic_visit(self, node): super().generic_visit(node) - if not isinstance(node, ast.expr) and not isinstance(node, ast.stmt): + if not isinstance(node, (ast.expr, ast.stmt, ast.pattern)): return lines.add(node.lineno) end_lines.add(node.end_lineno) @@ -1034,6 +1186,8 @@ class TestSourcePositions(unittest.TestCase): # Check against the positions in the code object. for (line, end_line, col, end_col) in code.co_positions(): + if line == 0: + continue # This is an artificial module-start line # If the offset is not None (indicating missing data), ensure that # it was part of one of the AST nodes. if line is not None: @@ -1050,7 +1204,9 @@ class TestSourcePositions(unittest.TestCase): def assertOpcodeSourcePositionIs(self, code, opcode, line, end_line, column, end_column, occurrence=1): - for instr, position in zip(dis.Bytecode(code), code.co_positions()): + for instr, position in zip( + dis.Bytecode(code, show_caches=True), code.co_positions(), strict=True + ): if instr.opname == opcode: occurrence -= 1 if not occurrence: @@ -1093,18 +1249,314 @@ f( ) """ compiled_code, _ = self.check_positions_against_ast(snippet) - self.assertOpcodeSourcePositionIs(compiled_code, 'CALL_FUNCTION', + self.assertOpcodeSourcePositionIs(compiled_code, 'CALL', line=1, end_line=3, column=0, end_column=1) + @requires_specialization + def test_multiline_boolean_expression(self): + snippet = """\ +if (a or + (b and not c) or + not ( + d > 0)): + x = 42 +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + # jump if a is true: + self.assertOpcodeSourcePositionIs(compiled_code, 'POP_JUMP_IF_TRUE', + line=1, end_line=1, column=4, end_column=5, occurrence=1) + # jump if b is false: + self.assertOpcodeSourcePositionIs(compiled_code, 'POP_JUMP_IF_FALSE', + line=2, end_line=2, column=5, end_column=6, occurrence=1) + # jump if c is false: + self.assertOpcodeSourcePositionIs(compiled_code, 'POP_JUMP_IF_FALSE', + line=2, end_line=2, column=15, end_column=16, occurrence=2) + # compare d and 0 + self.assertOpcodeSourcePositionIs(compiled_code, 'COMPARE_AND_BRANCH', + line=4, end_line=4, column=8, end_column=13, occurrence=1) + # jump if comparison it True + self.assertOpcodeSourcePositionIs(compiled_code, 'POP_JUMP_IF_TRUE', + line=4, end_line=4, column=8, end_column=13, occurrence=2) + + def test_multiline_assert(self): + snippet = """\ +assert (a > 0 and + bb > 0 and + ccc == 4), "error msg" +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertOpcodeSourcePositionIs(compiled_code, 'LOAD_ASSERTION_ERROR', + line=1, end_line=3, column=0, end_column=30, occurrence=1) + # The "error msg": + self.assertOpcodeSourcePositionIs(compiled_code, 'LOAD_CONST', + line=3, end_line=3, column=19, end_column=30, occurrence=4) + self.assertOpcodeSourcePositionIs(compiled_code, 'CALL', + line=1, end_line=3, column=0, end_column=30, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'RAISE_VARARGS', + line=1, end_line=3, column=0, end_column=30, occurrence=1) + + def test_multiline_generator_expression(self): + snippet = """\ +((x, + 2*x) + for x + in [1,2,3] if (x > 0 + and x < 100 + and x != 50)) +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + compiled_code = compiled_code.co_consts[0] + self.assertIsInstance(compiled_code, types.CodeType) + self.assertOpcodeSourcePositionIs(compiled_code, 'YIELD_VALUE', + line=1, end_line=2, column=1, end_column=8, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', + line=1, end_line=2, column=1, end_column=8, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE', + line=1, end_line=6, column=0, end_column=32, occurrence=1) + + def test_multiline_async_generator_expression(self): + snippet = """\ +((x, + 2*x) + async for x + in [1,2,3] if (x > 0 + and x < 100 + and x != 50)) +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + compiled_code = compiled_code.co_consts[0] + self.assertIsInstance(compiled_code, types.CodeType) + self.assertOpcodeSourcePositionIs(compiled_code, 'YIELD_VALUE', + line=1, end_line=2, column=1, end_column=8, occurrence=2) + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE', + line=1, end_line=6, column=0, end_column=32, occurrence=1) + + def test_multiline_list_comprehension(self): + snippet = """\ +[(x, + 2*x) + for x + in [1,2,3] if (x > 0 + and x < 100 + and x != 50)] +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + compiled_code = compiled_code.co_consts[0] + self.assertIsInstance(compiled_code, types.CodeType) + self.assertOpcodeSourcePositionIs(compiled_code, 'LIST_APPEND', + line=1, end_line=2, column=1, end_column=8, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', + line=1, end_line=2, column=1, end_column=8, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE', + line=1, end_line=6, column=0, end_column=32, occurrence=1) + + def test_multiline_async_list_comprehension(self): + snippet = """\ +async def f(): + [(x, + 2*x) + async for x + in [1,2,3] if (x > 0 + and x < 100 + and x != 50)] +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + g = {} + eval(compiled_code, g) + compiled_code = g['f'].__code__.co_consts[1] + self.assertIsInstance(compiled_code, types.CodeType) + self.assertOpcodeSourcePositionIs(compiled_code, 'LIST_APPEND', + line=2, end_line=3, column=5, end_column=12, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', + line=2, end_line=3, column=5, end_column=12, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE', + line=2, end_line=7, column=4, end_column=36, occurrence=1) + + def test_multiline_set_comprehension(self): + snippet = """\ +{(x, + 2*x) + for x + in [1,2,3] if (x > 0 + and x < 100 + and x != 50)} +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + compiled_code = compiled_code.co_consts[0] + self.assertIsInstance(compiled_code, types.CodeType) + self.assertOpcodeSourcePositionIs(compiled_code, 'SET_ADD', + line=1, end_line=2, column=1, end_column=8, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', + line=1, end_line=2, column=1, end_column=8, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE', + line=1, end_line=6, column=0, end_column=32, occurrence=1) + + def test_multiline_async_set_comprehension(self): + snippet = """\ +async def f(): + {(x, + 2*x) + async for x + in [1,2,3] if (x > 0 + and x < 100 + and x != 50)} +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + g = {} + eval(compiled_code, g) + compiled_code = g['f'].__code__.co_consts[1] + self.assertIsInstance(compiled_code, types.CodeType) + self.assertOpcodeSourcePositionIs(compiled_code, 'SET_ADD', + line=2, end_line=3, column=5, end_column=12, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', + line=2, end_line=3, column=5, end_column=12, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE', + line=2, end_line=7, column=4, end_column=36, occurrence=1) + + def test_multiline_dict_comprehension(self): + snippet = """\ +{x: + 2*x + for x + in [1,2,3] if (x > 0 + and x < 100 + and x != 50)} +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + compiled_code = compiled_code.co_consts[0] + self.assertIsInstance(compiled_code, types.CodeType) + self.assertOpcodeSourcePositionIs(compiled_code, 'MAP_ADD', + line=1, end_line=2, column=1, end_column=7, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', + line=1, end_line=2, column=1, end_column=7, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE', + line=1, end_line=6, column=0, end_column=32, occurrence=1) + + def test_multiline_async_dict_comprehension(self): + snippet = """\ +async def f(): + {x: + 2*x + async for x + in [1,2,3] if (x > 0 + and x < 100 + and x != 50)} +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + g = {} + eval(compiled_code, g) + compiled_code = g['f'].__code__.co_consts[1] + self.assertIsInstance(compiled_code, types.CodeType) + self.assertOpcodeSourcePositionIs(compiled_code, 'MAP_ADD', + line=2, end_line=3, column=5, end_column=11, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', + line=2, end_line=3, column=5, end_column=11, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_VALUE', + line=2, end_line=7, column=4, end_column=36, occurrence=1) + + def test_matchcase_sequence(self): + snippet = """\ +match x: + case a, b: + pass +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_SEQUENCE', + line=2, end_line=2, column=9, end_column=13, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'UNPACK_SEQUENCE', + line=2, end_line=2, column=9, end_column=13, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=13, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=13, occurrence=2) + + def test_matchcase_sequence_wildcard(self): + snippet = """\ +match x: + case a, *b, c: + pass +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_SEQUENCE', + line=2, end_line=2, column=9, end_column=17, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'UNPACK_EX', + line=2, end_line=2, column=9, end_column=17, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=17, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=17, occurrence=2) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=17, occurrence=3) + + def test_matchcase_mapping(self): + snippet = """\ +match x: + case {"a" : a, "b": b}: + pass +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_MAPPING', + line=2, end_line=2, column=9, end_column=26, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_KEYS', + line=2, end_line=2, column=9, end_column=26, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=26, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=26, occurrence=2) + + def test_matchcase_mapping_wildcard(self): + snippet = """\ +match x: + case {"a" : a, "b": b, **c}: + pass +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_MAPPING', + line=2, end_line=2, column=9, end_column=31, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_KEYS', + line=2, end_line=2, column=9, end_column=31, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=31, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=31, occurrence=2) + + def test_matchcase_class(self): + snippet = """\ +match x: + case C(a, b): + pass +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_CLASS', + line=2, end_line=2, column=9, end_column=16, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'UNPACK_SEQUENCE', + line=2, end_line=2, column=9, end_column=16, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=16, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=16, occurrence=2) + + def test_matchcase_or(self): + snippet = """\ +match x: + case C(1) | C(2): + pass +""" + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_CLASS', + line=2, end_line=2, column=9, end_column=13, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_CLASS', + line=2, end_line=2, column=16, end_column=20, occurrence=2) + def test_very_long_line_end_offset(self): - # Make sure we get None for when the column offset is too large to - # store in a byte. + # Make sure we get the correct column offset for offsets + # too large to store in a byte. long_string = "a" * 1000 snippet = f"g('{long_string}')" compiled_code, _ = self.check_positions_against_ast(snippet) - self.assertOpcodeSourcePositionIs(compiled_code, 'CALL_FUNCTION', - line=1, end_line=1, column=None, end_column=None) + self.assertOpcodeSourcePositionIs(compiled_code, 'CALL', + line=1, end_line=1, column=0, end_column=1005) def test_complex_single_line_expression(self): snippet = "a - b @ (c * x['key'] + 23)" @@ -1121,6 +1573,148 @@ f( self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_OP', line=1, end_line=1, column=0, end_column=27, occurrence=4) + def test_multiline_assert_rewritten_as_method_call(self): + # GH-94694: Don't crash if pytest rewrites a multiline assert as a + # method call with the same location information: + tree = ast.parse("assert (\n42\n)") + old_node = tree.body[0] + new_node = ast.Expr( + ast.Call( + ast.Attribute( + ast.Name("spam", ast.Load()), + "eggs", + ast.Load(), + ), + [], + [], + ) + ) + ast.copy_location(new_node, old_node) + ast.fix_missing_locations(new_node) + tree.body[0] = new_node + compile(tree, "", "exec") + + def test_push_null_load_global_positions(self): + source_template = """ + import abc, dis + import ast as art + + abc = None + dix = dis + ast = art + + def f(): + {} + """ + for body in [ + " abc.a()", + " art.a()", + " ast.a()", + " dis.a()", + " dix.a()", + " abc[...]()", + " art()()", + " (ast or ...)()", + " [dis]()", + " (dix + ...)()", + ]: + with self.subTest(body): + namespace = {} + source = textwrap.dedent(source_template.format(body)) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', SyntaxWarning) + exec(source, namespace) + code = namespace["f"].__code__ + self.assertOpcodeSourcePositionIs( + code, + "LOAD_GLOBAL", + line=10, + end_line=10, + column=4, + end_column=7, + ) + + def test_attribute_augassign(self): + source = "(\n lhs \n . \n rhs \n ) += 42" + code = compile(source, "", "exec") + self.assertOpcodeSourcePositionIs( + code, "LOAD_ATTR", line=4, end_line=4, column=5, end_column=8 + ) + self.assertOpcodeSourcePositionIs( + code, "STORE_ATTR", line=4, end_line=4, column=5, end_column=8 + ) + + def test_attribute_del(self): + source = "del (\n lhs \n . \n rhs \n )" + code = compile(source, "", "exec") + self.assertOpcodeSourcePositionIs( + code, "DELETE_ATTR", line=4, end_line=4, column=5, end_column=8 + ) + + def test_attribute_load(self): + source = "(\n lhs \n . \n rhs \n )" + code = compile(source, "", "exec") + self.assertOpcodeSourcePositionIs( + code, "LOAD_ATTR", line=4, end_line=4, column=5, end_column=8 + ) + + def test_attribute_store(self): + source = "(\n lhs \n . \n rhs \n ) = 42" + code = compile(source, "", "exec") + self.assertOpcodeSourcePositionIs( + code, "STORE_ATTR", line=4, end_line=4, column=5, end_column=8 + ) + + def test_method_call(self): + source = "(\n lhs \n . \n rhs \n )()" + code = compile(source, "", "exec") + self.assertOpcodeSourcePositionIs( + code, "LOAD_ATTR", line=4, end_line=4, column=5, end_column=8 + ) + self.assertOpcodeSourcePositionIs( + code, "CALL", line=4, end_line=5, column=5, end_column=10 + ) + + def test_weird_attribute_position_regressions(self): + def f(): + (bar. + baz) + (bar. + baz( + )) + files().setdefault( + 0 + ).setdefault( + 0 + ) + for line, end_line, column, end_column in f.__code__.co_positions(): + self.assertIsNotNone(line) + self.assertIsNotNone(end_line) + self.assertIsNotNone(column) + self.assertIsNotNone(end_column) + self.assertLessEqual((line, column), (end_line, end_column)) + + @support.cpython_only + def test_column_offset_deduplication(self): + # GH-95150: Code with different column offsets shouldn't be merged! + for source in [ + "lambda: a", + "(a for b in c)", + "[a for b in c]", + "{a for b in c}", + "{a: b for c in d}", + ]: + with self.subTest(source): + code = compile(f"{source}, {source}", "", "eval") + self.assertEqual(len(code.co_consts), 2) + self.assertIsInstance(code.co_consts[0], types.CodeType) + self.assertIsInstance(code.co_consts[1], types.CodeType) + self.assertNotEqual(code.co_consts[0], code.co_consts[1]) + self.assertNotEqual( + list(code.co_consts[0].co_positions()), + list(code.co_consts[1].co_positions()), + ) + class TestExpressionStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object @@ -1173,7 +1767,7 @@ class TestExpressionStackSize(unittest.TestCase): kwargs = (f'a{i}=x' for i in range(self.N)) self.check_stack_size("f(" + ", ".join(kwargs) + ")") - def test_func_args(self): + def test_meth_args(self): self.check_stack_size("o.m(" + "x, " * self.N + ")") def test_meth_kwargs(self): @@ -1185,6 +1779,19 @@ class TestExpressionStackSize(unittest.TestCase): code += " x and x\n" * self.N self.check_stack_size(code) + def test_stack_3050(self): + M = 3050 + code = "x," * M + "=t" + # This raised on 3.10.0 to 3.10.5 + compile(code, "", "single") + + def test_stack_3050_2(self): + M = 3050 + args = ", ".join(f"arg{i}:type{i}" for i in range(M)) + code = f"def f({args}):\n pass" + # This raised on 3.10.0 to 3.10.5 + compile(code, "", "single") + class TestStackSizeStability(unittest.TestCase): # Check that repeating certain snippets doesn't increase the stack size @@ -1261,6 +1868,39 @@ class TestStackSizeStability(unittest.TestCase): """ self.check_stack_size(snippet) + def test_try_except_star_qualified(self): + snippet = """ + try: + a + except* ImportError: + b + else: + c + """ + self.check_stack_size(snippet) + + def test_try_except_star_as(self): + snippet = """ + try: + a + except* ImportError as e: + b + else: + c + """ + self.check_stack_size(snippet) + + def test_try_except_star_finally(self): + snippet = """ + try: + a + except* A: + b + finally: + c + """ + self.check_stack_size(snippet) + def test_try_finally(self): snippet = """ try: diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py index 9e15ecf3aae..05154c8f1c6 100644 --- a/Lib/test/test_compileall.py +++ b/Lib/test/test_compileall.py @@ -3,7 +3,6 @@ import contextlib import filecmp import importlib.util import io -import itertools import os import pathlib import py_compile @@ -16,22 +15,21 @@ import time import unittest from unittest import mock, skipUnless -from concurrent.futures import ProcessPoolExecutor try: # compileall relies on ProcessPoolExecutor if ProcessPoolExecutor exists # and it can function. + from concurrent.futures import ProcessPoolExecutor from concurrent.futures.process import _check_system_limits _check_system_limits() _have_multiprocessing = True -except NotImplementedError: +except (NotImplementedError, ModuleNotFoundError): _have_multiprocessing = False from test import support from test.support import os_helper from test.support import script_helper - -from .test_py_compile import without_source_date_epoch -from .test_py_compile import SourceDateEpochTestMeta +from test.test_py_compile import without_source_date_epoch +from test.test_py_compile import SourceDateEpochTestMeta def get_pyc(script, opt): @@ -169,6 +167,20 @@ class CompileallTestsBase: quiet=2)) self.assertTrue(os.path.isfile(self.bc_path)) + def test_compile_file_pathlike_stripdir(self): + self.assertFalse(os.path.isfile(self.bc_path)) + self.assertTrue(compileall.compile_file(pathlib.Path(self.source_path), + stripdir=pathlib.Path('stripdir_path'), + quiet=2)) + self.assertTrue(os.path.isfile(self.bc_path)) + + def test_compile_file_pathlike_prependdir(self): + self.assertFalse(os.path.isfile(self.bc_path)) + self.assertTrue(compileall.compile_file(pathlib.Path(self.source_path), + prependdir=pathlib.Path('prependdir_path'), + quiet=2)) + self.assertTrue(os.path.isfile(self.bc_path)) + def test_compile_path(self): with test.test_importlib.util.import_state(path=[self.directory]): self.assertTrue(compileall.compile_path(quiet=2)) @@ -221,6 +233,20 @@ class CompileallTestsBase: self.assertRegex(line, r'Listing ([^WindowsPath|PosixPath].*)') self.assertTrue(os.path.isfile(self.bc_path)) + def test_compile_dir_pathlike_stripdir(self): + self.assertFalse(os.path.isfile(self.bc_path)) + self.assertTrue(compileall.compile_dir(pathlib.Path(self.directory), + stripdir=pathlib.Path('stripdir_path'), + quiet=2)) + self.assertTrue(os.path.isfile(self.bc_path)) + + def test_compile_dir_pathlike_prependdir(self): + self.assertFalse(os.path.isfile(self.bc_path)) + self.assertTrue(compileall.compile_dir(pathlib.Path(self.directory), + prependdir=pathlib.Path('prependdir_path'), + quiet=2)) + self.assertTrue(os.path.isfile(self.bc_path)) + @skipUnless(_have_multiprocessing, "requires multiprocessing") @mock.patch('concurrent.futures.ProcessPoolExecutor') def test_compile_pool_called(self, pool_mock): @@ -246,6 +272,7 @@ class CompileallTestsBase: self.assertFalse(pool_mock.called) self.assertTrue(compile_file_mock.called) + @skipUnless(_have_multiprocessing, "requires multiprocessing") @mock.patch('concurrent.futures.ProcessPoolExecutor', new=None) @mock.patch('compileall.compile_file') def test_compile_missing_multiprocessing(self, compile_file_mock): @@ -298,6 +325,7 @@ class CompileallTestsBase: """Recursive compile_dir ddir= contains package paths; bpo39769.""" return self._test_ddir_only(ddir="", parallel=False) + @skipUnless(_have_multiprocessing, "requires multiprocessing") def test_ddir_multiple_workers(self): """Recursive compile_dir ddir= contains package paths; bpo39769.""" return self._test_ddir_only(ddir="", parallel=True) @@ -306,6 +334,7 @@ class CompileallTestsBase: """Recursive compile_dir ddir='' contains package paths; bpo39769.""" return self._test_ddir_only(ddir="", parallel=False) + @skipUnless(_have_multiprocessing, "requires multiprocessing") def test_ddir_empty_multiple_workers(self): """Recursive compile_dir ddir='' contains package paths; bpo39769.""" return self._test_ddir_only(ddir="", parallel=True) @@ -433,6 +462,9 @@ class CompileallTestsWithoutSourceEpoch(CompileallTestsBase, pass +# WASI does not have a temp directory and uses cwd instead. The cwd contains +# non-ASCII chars, so _walk_dir() fails to encode self.directory. +@unittest.skipIf(support.is_wasi, "tempdir is not encodable on WASI") class EncodingTest(unittest.TestCase): """Issue 6716: compileall should escape source code when printing errors to stdout.""" @@ -459,31 +491,29 @@ class EncodingTest(unittest.TestCase): class CommandLineTestsBase: """Test compileall's CLI.""" - @classmethod - def setUpClass(cls): - for path in filter(os.path.isdir, sys.path): - directory_created = False - directory = pathlib.Path(path) / '__pycache__' - path = directory / 'test.try' - try: - if not directory.is_dir(): - directory.mkdir() - directory_created = True - path.write_text('# for test_compileall', encoding="utf-8") - except OSError: - sys_path_writable = False - break - finally: - os_helper.unlink(str(path)) - if directory_created: - directory.rmdir() - else: - sys_path_writable = True - cls._sys_path_writable = sys_path_writable + def setUp(self): + self.directory = tempfile.mkdtemp() + self.addCleanup(os_helper.rmtree, self.directory) + self.pkgdir = os.path.join(self.directory, 'foo') + os.mkdir(self.pkgdir) + self.pkgdir_cachedir = os.path.join(self.pkgdir, '__pycache__') + # Create the __init__.py and a package module. + self.initfn = script_helper.make_script(self.pkgdir, '__init__', '') + self.barfn = script_helper.make_script(self.pkgdir, 'bar', '') - def _skip_if_sys_path_not_writable(self): - if not self._sys_path_writable: - raise unittest.SkipTest('not all entries on sys.path are writable') + @contextlib.contextmanager + def temporary_pycache_prefix(self): + """Adjust and restore sys.pycache_prefix.""" + old_prefix = sys.pycache_prefix + new_prefix = os.path.join(self.directory, '__testcache__') + try: + sys.pycache_prefix = new_prefix + yield { + 'PYTHONPATH': self.directory, + 'PYTHONPYCACHEPREFIX': new_prefix, + } + finally: + sys.pycache_prefix = old_prefix def _get_run_args(self, args): return [*support.optim_args_from_interpreter_flags(), @@ -511,49 +541,39 @@ class CommandLineTestsBase: path = importlib.util.cache_from_source(fn) self.assertFalse(os.path.exists(path)) - def setUp(self): - self.directory = tempfile.mkdtemp() - self.addCleanup(os_helper.rmtree, self.directory) - self.pkgdir = os.path.join(self.directory, 'foo') - os.mkdir(self.pkgdir) - self.pkgdir_cachedir = os.path.join(self.pkgdir, '__pycache__') - # Create the __init__.py and a package module. - self.initfn = script_helper.make_script(self.pkgdir, '__init__', '') - self.barfn = script_helper.make_script(self.pkgdir, 'bar', '') - def test_no_args_compiles_path(self): # Note that -l is implied for the no args case. - self._skip_if_sys_path_not_writable() bazfn = script_helper.make_script(self.directory, 'baz', '') - self.assertRunOK(PYTHONPATH=self.directory) - self.assertCompiled(bazfn) - self.assertNotCompiled(self.initfn) - self.assertNotCompiled(self.barfn) + with self.temporary_pycache_prefix() as env: + self.assertRunOK(**env) + self.assertCompiled(bazfn) + self.assertNotCompiled(self.initfn) + self.assertNotCompiled(self.barfn) @without_source_date_epoch # timestamp invalidation test def test_no_args_respects_force_flag(self): - self._skip_if_sys_path_not_writable() bazfn = script_helper.make_script(self.directory, 'baz', '') - self.assertRunOK(PYTHONPATH=self.directory) - pycpath = importlib.util.cache_from_source(bazfn) + with self.temporary_pycache_prefix() as env: + self.assertRunOK(**env) + pycpath = importlib.util.cache_from_source(bazfn) # Set atime/mtime backward to avoid file timestamp resolution issues os.utime(pycpath, (time.time()-60,)*2) mtime = os.stat(pycpath).st_mtime # Without force, no recompilation - self.assertRunOK(PYTHONPATH=self.directory) + self.assertRunOK(**env) mtime2 = os.stat(pycpath).st_mtime self.assertEqual(mtime, mtime2) # Now force it. - self.assertRunOK('-f', PYTHONPATH=self.directory) + self.assertRunOK('-f', **env) mtime2 = os.stat(pycpath).st_mtime self.assertNotEqual(mtime, mtime2) def test_no_args_respects_quiet_flag(self): - self._skip_if_sys_path_not_writable() script_helper.make_script(self.directory, 'baz', '') - noisy = self.assertRunOK(PYTHONPATH=self.directory) + with self.temporary_pycache_prefix() as env: + noisy = self.assertRunOK(**env) self.assertIn(b'Listing ', noisy) - quiet = self.assertRunOK('-q', PYTHONPATH=self.directory) + quiet = self.assertRunOK('-q', **env) self.assertNotIn(b'Listing ', quiet) # Ensure that the default behavior of compileall's CLI is to create @@ -926,6 +946,7 @@ class CommandLineTestsNoSourceEpoch(CommandLineTestsBase, +@unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') class HardlinkDedupTestsBase: # Test hardlink_dupes parameter of compileall.compile_dir() diff --git a/Lib/test/test_compiler_codegen.py b/Lib/test/test_compiler_codegen.py new file mode 100644 index 00000000000..f2e14c1e628 --- /dev/null +++ b/Lib/test/test_compiler_codegen.py @@ -0,0 +1,50 @@ + +from test.support.bytecode_helper import CodegenTestCase + +# Tests for the code-generation stage of the compiler. +# Examine the un-optimized code generated from the AST. + +class IsolatedCodeGenTests(CodegenTestCase): + + def codegen_test(self, snippet, expected_insts): + import ast + a = ast.parse(snippet, "my_file.py", "exec"); + insts = self.generate_code(a) + self.assertInstructionsMatch(insts, expected_insts) + + def test_if_expression(self): + snippet = "42 if True else 24" + false_lbl = self.Label() + expected = [ + ('RESUME', 0, 0), + ('LOAD_CONST', 0, 1), + ('POP_JUMP_IF_FALSE', false_lbl := self.Label(), 1), + ('LOAD_CONST', 1, 1), + ('JUMP', exit_lbl := self.Label()), + false_lbl, + ('LOAD_CONST', 2, 1), + exit_lbl, + ('POP_TOP', None), + ] + self.codegen_test(snippet, expected) + + def test_for_loop(self): + snippet = "for x in l:\n\tprint(x)" + false_lbl = self.Label() + expected = [ + ('RESUME', 0, 0), + ('LOAD_NAME', 0, 1), + ('GET_ITER', None, 1), + loop_lbl := self.Label(), + ('FOR_ITER', exit_lbl := self.Label(), 1), + ('STORE_NAME', None, 1), + ('PUSH_NULL', None, 2), + ('LOAD_NAME', None, 2), + ('LOAD_NAME', None, 2), + ('CALL', None, 2), + ('POP_TOP', None), + ('JUMP', loop_lbl), + exit_lbl, + ('END_FOR', None), + ] + self.codegen_test(snippet, expected) diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index e046577b935..51ba151505f 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -306,15 +306,10 @@ class ComplexTest(unittest.TestCase): self.assertClose(complex(5.3, 9.8).conjugate(), 5.3-9.8j) def test_constructor(self): - class OS: + class NS: def __init__(self, value): self.value = value def __complex__(self): return self.value - class NS(object): - def __init__(self, value): self.value = value - def __complex__(self): return self.value - self.assertEqual(complex(OS(1+10j)), 1+10j) self.assertEqual(complex(NS(1+10j)), 1+10j) - self.assertRaises(TypeError, complex, OS(None)) self.assertRaises(TypeError, complex, NS(None)) self.assertRaises(TypeError, complex, {}) self.assertRaises(TypeError, complex, NS(1.5)) diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index bbb6aa1eef8..b3520ae3994 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -26,10 +26,16 @@ from concurrent.futures._base import ( PENDING, RUNNING, CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED, Future, BrokenExecutor) from concurrent.futures.process import BrokenProcessPool, _check_system_limits -from multiprocessing import get_context import multiprocessing.process import multiprocessing.util +import multiprocessing as mp + + +if support.check_sanitizer(address=True, memory=True): + # bpo-46633: Skip the test because it is too slow when Python is built + # with ASAN/MSAN: between 5 and 20 minutes on GitHub Actions. + raise unittest.SkipTest("test too slow on ASAN/MSAN build") def create_future(state=PENDING, exception=None, result=None): @@ -124,7 +130,6 @@ class ExecutorMixin: self.executor = self.executor_type( max_workers=self.worker_count, **self.executor_kwargs) - self._prime_executor() def tearDown(self): self.executor.shutdown(wait=True) @@ -138,15 +143,7 @@ class ExecutorMixin: super().tearDown() def get_context(self): - return get_context(self.ctx) - - def _prime_executor(self): - # Make sure that the executor is ready to do work before running the - # tests. This should reduce the probability of timeouts in the tests. - futures = [self.executor.submit(time.sleep, 0.1) - for _ in range(self.worker_count)] - for f in futures: - f.result() + return mp.get_context(self.ctx) class ThreadPoolMixin(ExecutorMixin): @@ -259,19 +256,17 @@ class FailingInitializerMixin(ExecutorMixin): else: with self.assertRaises(BrokenExecutor): future.result() + # At some point, the executor should break - t1 = time.monotonic() - while not self.executor._broken: - if time.monotonic() - t1 > 5: - self.fail("executor not broken after 5 s.") - time.sleep(0.01) + for _ in support.sleeping_retry(support.SHORT_TIMEOUT, + "executor not broken"): + if self.executor._broken: + break + # ... and from this point submit() is guaranteed to fail with self.assertRaises(BrokenExecutor): self.executor.submit(get_init_status) - def _prime_executor(self): - pass - @contextlib.contextmanager def _assert_logged(self, msg): if self.log_queue is not None: @@ -358,14 +353,14 @@ class ExecutorShutdownTest: f.result() def test_cancel_futures(self): - executor = self.executor_type(max_workers=3) - fs = [executor.submit(time.sleep, .1) for _ in range(50)] - executor.shutdown(cancel_futures=True) + assert self.worker_count <= 5, "test needs few workers" + fs = [self.executor.submit(time.sleep, .1) for _ in range(50)] + self.executor.shutdown(cancel_futures=True) # We can't guarantee the exact number of cancellations, but we can - # guarantee that *some* were cancelled. With setting max_workers to 3, - # most of the submitted futures should have been cancelled. + # guarantee that *some* were cancelled. With few workers, many of + # the submitted futures should have been cancelled. cancelled = [fut for fut in fs if fut.cancelled()] - self.assertTrue(len(cancelled) >= 35, msg=f"{len(cancelled)=}") + self.assertGreater(len(cancelled), 20) # Ensure the other futures were able to finish. # Use "not fut.cancelled()" instead of "fut.done()" to include futures @@ -378,33 +373,32 @@ class ExecutorShutdownTest: # Similar to the number of cancelled futures, we can't guarantee the # exact number that completed. But, we can guarantee that at least # one finished. - self.assertTrue(len(others) > 0, msg=f"{len(others)=}") + self.assertGreater(len(others), 0) - def test_hang_issue39205(self): + def test_hang_gh83386(self): """shutdown(wait=False) doesn't hang at exit with running futures. - See https://bugs.python.org/issue39205. + See https://github.com/python/cpython/issues/83386. """ if self.executor_type == futures.ProcessPoolExecutor: raise unittest.SkipTest( - "Hangs due to https://bugs.python.org/issue39205") + "Hangs, see https://github.com/python/cpython/issues/83386") rc, out, err = assert_python_ok('-c', """if True: from concurrent.futures import {executor_type} from test.test_concurrent_futures import sleep_and_print if __name__ == "__main__": + if {context!r}: multiprocessing.set_start_method({context!r}) t = {executor_type}(max_workers=3) t.submit(sleep_and_print, 1.0, "apple") t.shutdown(wait=False) - """.format(executor_type=self.executor_type.__name__)) + """.format(executor_type=self.executor_type.__name__, + context=getattr(self, 'ctx', None))) self.assertFalse(err) self.assertEqual(out.strip(), b"apple") class ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest, BaseTestCase): - def _prime_executor(self): - pass - def test_threads_terminate(self): def acquire_lock(lock): lock.acquire() @@ -491,7 +485,7 @@ class ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest, BaseTestCase t = ThreadPoolExecutor() t.submit(sleep_and_print, .1, "apple") t.shutdown(wait=False, cancel_futures=True) - """.format(executor_type=self.executor_type.__name__)) + """) # Errors in atexit hooks don't change the process exit code, check # stderr manually. self.assertFalse(err) @@ -499,18 +493,21 @@ class ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest, BaseTestCase class ProcessPoolShutdownTest(ExecutorShutdownTest): - def _prime_executor(self): - pass - def test_processes_terminate(self): def acquire_lock(lock): lock.acquire() - mp_context = get_context() + mp_context = self.get_context() + if mp_context.get_start_method(allow_none=False) == "fork": + # fork pre-spawns, not on demand. + expected_num_processes = self.worker_count + else: + expected_num_processes = 3 + sem = mp_context.Semaphore(0) for _ in range(3): self.executor.submit(acquire_lock, sem) - self.assertEqual(len(self.executor._processes), 3) + self.assertEqual(len(self.executor._processes), expected_num_processes) for _ in range(3): sem.release() processes = self.executor._processes @@ -520,7 +517,8 @@ class ProcessPoolShutdownTest(ExecutorShutdownTest): p.join() def test_context_manager_shutdown(self): - with futures.ProcessPoolExecutor(max_workers=5) as e: + with futures.ProcessPoolExecutor( + max_workers=5, mp_context=self.get_context()) as e: processes = e._processes self.assertEqual(list(e.map(abs, range(-5, 5))), [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) @@ -529,7 +527,8 @@ class ProcessPoolShutdownTest(ExecutorShutdownTest): p.join() def test_del_shutdown(self): - executor = futures.ProcessPoolExecutor(max_workers=5) + executor = futures.ProcessPoolExecutor( + max_workers=5, mp_context=self.get_context()) res = executor.map(abs, range(-5, 5)) executor_manager_thread = executor._executor_manager_thread processes = executor._processes @@ -552,7 +551,8 @@ class ProcessPoolShutdownTest(ExecutorShutdownTest): def test_shutdown_no_wait(self): # Ensure that the executor cleans up the processes when calling # shutdown with wait=False - executor = futures.ProcessPoolExecutor(max_workers=5) + executor = futures.ProcessPoolExecutor( + max_workers=5, mp_context=self.get_context()) res = executor.map(abs, range(-5, 5)) processes = executor._processes call_queue = executor._call_queue @@ -578,6 +578,14 @@ create_executor_tests(ProcessPoolShutdownTest, class WaitTests: + def test_20369(self): + # See https://bugs.python.org/issue20369 + future = self.executor.submit(time.sleep, 1.5) + done, not_done = futures.wait([future, future], + return_when=futures.ALL_COMPLETED) + self.assertEqual({future}, done) + self.assertEqual(set(), not_done) + def test_first_completed(self): future1 = self.executor.submit(mul, 21, 2) @@ -703,7 +711,6 @@ create_executor_tests(WaitTests, class AsCompletedTests: - # TODO(brian@sweetapp.com): Should have a test with a non-zero timeout. def test_no_timeout(self): future1 = self.executor.submit(mul, 2, 21) future2 = self.executor.submit(mul, 7, 6) @@ -720,24 +727,29 @@ class AsCompletedTests: future1, future2]), completed) - def test_zero_timeout(self): - future1 = self.executor.submit(time.sleep, 2) - completed_futures = set() - try: - for future in futures.as_completed( - [CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1], - timeout=0): - completed_futures.add(future) - except futures.TimeoutError: - pass + def test_future_times_out(self): + """Test ``futures.as_completed`` timing out before + completing it's final future.""" + already_completed = {CANCELLED_AND_NOTIFIED_FUTURE, + EXCEPTION_FUTURE, + SUCCESSFUL_FUTURE} - self.assertEqual(set([CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE]), - completed_futures) + for timeout in (0, 0.01): + with self.subTest(timeout): + + future = self.executor.submit(time.sleep, 0.1) + completed_futures = set() + try: + for f in futures.as_completed( + already_completed | {future}, + timeout + ): + completed_futures.add(f) + except futures.TimeoutError: + pass + + # Check that ``future`` wasn't completed. + self.assertEqual(completed_futures, already_completed) def test_duplicate_futures(self): # Issue 20367. Duplicate futures should not raise exceptions or give @@ -921,9 +933,36 @@ class ThreadPoolExecutorTest(ThreadPoolMixin, ExecutorTest, BaseTestCase): pool.submit(submit, pool) for _ in range(50): - with futures.ProcessPoolExecutor(1, mp_context=get_context('fork')) as workers: + with futures.ProcessPoolExecutor(1, mp_context=mp.get_context('fork')) as workers: workers.submit(tuple) + def test_executor_map_current_future_cancel(self): + stop_event = threading.Event() + log = [] + + def log_n_wait(ident): + log.append(f"{ident=} started") + try: + stop_event.wait() + finally: + log.append(f"{ident=} stopped") + + with self.executor_type(max_workers=1) as pool: + # submit work to saturate the pool + fut = pool.submit(log_n_wait, ident="first") + try: + with contextlib.closing( + pool.map(log_n_wait, ["second", "third"], timeout=0) + ) as gen: + with self.assertRaises(TimeoutError): + next(gen) + finally: + stop_event.set() + fut.result() + # ident='second' is cancelled as a result of raising a TimeoutError + # ident='third' is cancelled because it remained in the collection of futures + self.assertListEqual(log, ["ident='first' started", "ident='first' stopped"]) + class ProcessPoolExecutorTest(ExecutorTest): @@ -991,7 +1030,7 @@ class ProcessPoolExecutorTest(ExecutorTest): def test_ressources_gced_in_workers(self): # Ensure that argument for a job are correctly gc-ed after the job # is finished - mgr = get_context(self.ctx).Manager() + mgr = self.get_context().Manager() obj = EventfulGCObj(mgr) future = self.executor.submit(id, obj) future.result() @@ -1007,38 +1046,50 @@ class ProcessPoolExecutorTest(ExecutorTest): mgr.join() def test_saturation(self): - executor = self.executor_type(4) - mp_context = get_context() + executor = self.executor + mp_context = self.get_context() sem = mp_context.Semaphore(0) job_count = 15 * executor._max_workers - try: - for _ in range(job_count): - executor.submit(sem.acquire) - self.assertEqual(len(executor._processes), executor._max_workers) - for _ in range(job_count): - sem.release() - finally: - executor.shutdown() + for _ in range(job_count): + executor.submit(sem.acquire) + self.assertEqual(len(executor._processes), executor._max_workers) + for _ in range(job_count): + sem.release() def test_idle_process_reuse_one(self): - executor = self.executor_type(4) + executor = self.executor + assert executor._max_workers >= 4 + if self.get_context().get_start_method(allow_none=False) == "fork": + raise unittest.SkipTest("Incompatible with the fork start method.") executor.submit(mul, 21, 2).result() executor.submit(mul, 6, 7).result() executor.submit(mul, 3, 14).result() self.assertEqual(len(executor._processes), 1) - executor.shutdown() def test_idle_process_reuse_multiple(self): - executor = self.executor_type(4) + executor = self.executor + assert executor._max_workers <= 5 + if self.get_context().get_start_method(allow_none=False) == "fork": + raise unittest.SkipTest("Incompatible with the fork start method.") executor.submit(mul, 12, 7).result() executor.submit(mul, 33, 25) executor.submit(mul, 25, 26).result() executor.submit(mul, 18, 29) - self.assertLessEqual(len(executor._processes), 2) + executor.submit(mul, 1, 2).result() + executor.submit(mul, 0, 9) + self.assertLessEqual(len(executor._processes), 3) executor.shutdown() def test_max_tasks_per_child(self): - executor = self.executor_type(1, max_tasks_per_child=3) + context = self.get_context() + if context.get_start_method(allow_none=False) == "fork": + with self.assertRaises(ValueError): + self.executor_type(1, mp_context=context, max_tasks_per_child=3) + return + # not using self.executor as we need to control construction. + # arguably this could go in another class w/o that mixin. + executor = self.executor_type( + 1, mp_context=context, max_tasks_per_child=3) f1 = executor.submit(os.getpid) original_pid = f1.result() # The worker pid remains the same as the worker could be reused @@ -1057,8 +1108,20 @@ class ProcessPoolExecutorTest(ExecutorTest): executor.shutdown() + def test_max_tasks_per_child_defaults_to_spawn_context(self): + # not using self.executor as we need to control construction. + # arguably this could go in another class w/o that mixin. + executor = self.executor_type(1, max_tasks_per_child=3) + self.assertEqual(executor._mp_context.get_start_method(), "spawn") + def test_max_tasks_early_shutdown(self): - executor = self.executor_type(3, max_tasks_per_child=1) + context = self.get_context() + if context.get_start_method(allow_none=False) == "fork": + raise unittest.SkipTest("Incompatible with the fork start method.") + # not using self.executor as we need to control construction. + # arguably this could go in another class w/o that mixin. + executor = self.executor_type( + 3, mp_context=context, max_tasks_per_child=1) futures = [] for i in range(6): futures.append(executor.submit(mul, i, i)) @@ -1168,7 +1231,7 @@ class ExecutorDeadlockTest: self.executor.shutdown(wait=True) executor = self.executor_type( - max_workers=2, mp_context=get_context(self.ctx)) + max_workers=2, mp_context=self.get_context()) res = executor.submit(func, *args) if ignore_stderr: @@ -1247,7 +1310,7 @@ class ExecutorDeadlockTest: # if a worker fails after the shutdown call. self.executor.shutdown(wait=True) with self.executor_type(max_workers=2, - mp_context=get_context(self.ctx)) as executor: + mp_context=self.get_context()) as executor: self.executor = executor # Allow clean up in fail_on_deadlock f = executor.submit(_crash, delay=.1) executor.shutdown(wait=True) @@ -1260,7 +1323,7 @@ class ExecutorDeadlockTest: # Reported in bpo-39104. self.executor.shutdown(wait=True) with self.executor_type(max_workers=2, - mp_context=get_context(self.ctx)) as executor: + mp_context=self.get_context()) as executor: self.executor = executor # Allow clean up in fail_on_deadlock # Start the executor and get the executor_manager_thread to collect diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index cedf505122d..da17c00063c 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -114,7 +114,7 @@ class BasicTestCase(CfgParserTestCaseClass): # The use of spaces in the section names serves as a # regression test for SourceForge bug #583248: - # http://www.python.org/sf/583248 + # https://bugs.python.org/issue583248 # API access eq(cf.get('Foo Bar', 'foo'), 'bar1') @@ -932,7 +932,7 @@ class ConfigParserTestCase(BasicTestCase, unittest.TestCase): ('name', 'value')]) def test_safe_interpolation(self): - # See http://www.python.org/sf/511737 + # See https://bugs.python.org/issue511737 cf = self.fromstring("[section]\n" "option1{eq}xxx\n" "option2{eq}%(option1)s/xxx\n" @@ -1028,7 +1028,9 @@ class ConfigParserTestCaseNoInterpolation(BasicTestCase, unittest.TestCase): class ConfigParserTestCaseLegacyInterpolation(ConfigParserTestCase): config_class = configparser.ConfigParser - interpolation = configparser.LegacyInterpolation() + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + interpolation = configparser.LegacyInterpolation() def test_set_malformatted_interpolation(self): cf = self.fromstring("[sect]\n" @@ -1048,6 +1050,14 @@ class ConfigParserTestCaseLegacyInterpolation(ConfigParserTestCase): self.assertEqual(cf.get("sect", "option2"), "foo%%bar") +class ConfigParserTestCaseInvalidInterpolationType(unittest.TestCase): + def test_error_on_wrong_type_for_interpolation(self): + for value in [configparser.ExtendedInterpolation, 42, "a string"]: + with self.subTest(value=value): + with self.assertRaises(TypeError): + configparser.ConfigParser(interpolation=value) + + class ConfigParserTestCaseNonStandardDelimiters(ConfigParserTestCase): delimiters = (':=', '$') comment_prefixes = ('//', '"') @@ -1602,15 +1612,11 @@ class CoverageOneHundredTestCase(unittest.TestCase): self.assertEqual(error.section, 'section') def test_parsing_error(self): - with self.assertRaises(ValueError) as cm: + with self.assertRaises(TypeError) as cm: configparser.ParsingError() - self.assertEqual(str(cm.exception), "Required argument `source' not " - "given.") - with self.assertRaises(ValueError) as cm: - configparser.ParsingError(source='source', filename='filename') - self.assertEqual(str(cm.exception), "Cannot specify both `filename' " - "and `source'. Use `source'.") - error = configparser.ParsingError(filename='source') + error = configparser.ParsingError(source='source') + self.assertEqual(error.source, 'source') + error = configparser.ParsingError('source') self.assertEqual(error.source, 'source') def test_interpolation_validation(self): @@ -1630,6 +1636,14 @@ class CoverageOneHundredTestCase(unittest.TestCase): self.assertEqual(str(cm.exception), "bad interpolation variable " "reference '%(()'") + def test_legacyinterpolation_deprecation(self): + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always", DeprecationWarning) + configparser.LegacyInterpolation() + self.assertGreaterEqual(len(w), 1) + for warning in w: + self.assertIs(warning.category, DeprecationWarning) + def test_sectionproxy_repr(self): parser = configparser.ConfigParser() parser.read_string(""" @@ -1795,7 +1809,7 @@ class ExceptionPicklingTestCase(unittest.TestCase): self.assertEqual(e1.source, e2.source) self.assertEqual(e1.errors, e2.errors) self.assertEqual(repr(e1), repr(e2)) - e1 = configparser.ParsingError(filename='filename') + e1 = configparser.ParsingError('filename') e1.append(1, 'line1') e1.append(2, 'line2') e1.append(3, 'line3') diff --git a/Lib/test/test_context.py b/Lib/test/test_context.py index 2d8b63a1f59..b1aece4f5c9 100644 --- a/Lib/test/test_context.py +++ b/Lib/test/test_context.py @@ -6,6 +6,7 @@ import random import time import unittest import weakref +from test.support import threading_helper try: from _testcapi import hamt @@ -341,6 +342,7 @@ class ContextTest(unittest.TestCase): ctx1.run(ctx1_fun) @isolated_context + @threading_helper.requires_working_threading() def test_context_threads_1(self): cvar = contextvars.ContextVar('cvar') @@ -533,6 +535,41 @@ class HamtTest(unittest.TestCase): self.assertEqual(len(h4), 2) self.assertEqual(len(h5), 3) + def test_hamt_collision_3(self): + # Test that iteration works with the deepest tree possible. + # https://github.com/python/cpython/issues/93065 + + C = HashKey(0b10000000_00000000_00000000_00000000, 'C') + D = HashKey(0b10000000_00000000_00000000_00000000, 'D') + + E = HashKey(0b00000000_00000000_00000000_00000000, 'E') + + h = hamt() + h = h.set(C, 'C') + h = h.set(D, 'D') + h = h.set(E, 'E') + + # BitmapNode(size=2 count=1 bitmap=0b1): + # NULL: + # BitmapNode(size=2 count=1 bitmap=0b1): + # NULL: + # BitmapNode(size=2 count=1 bitmap=0b1): + # NULL: + # BitmapNode(size=2 count=1 bitmap=0b1): + # NULL: + # BitmapNode(size=2 count=1 bitmap=0b1): + # NULL: + # BitmapNode(size=2 count=1 bitmap=0b1): + # NULL: + # BitmapNode(size=4 count=2 bitmap=0b101): + # : 'E' + # NULL: + # CollisionNode(size=4 id=0x107a24520): + # : 'C' + # : 'D' + + self.assertEqual({k.name for k in h.keys()}, {'C', 'D', 'E'}) + def test_hamt_stress(self): COLLECTION_SIZE = 7000 TEST_ITERS_EVERY = 647 diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py index bc8e4e4e291..ec06785b566 100644 --- a/Lib/test/test_contextlib.py +++ b/Lib/test/test_contextlib.py @@ -5,6 +5,7 @@ import os import sys import tempfile import threading +import traceback import unittest from contextlib import * # Tests __all__ from test import support @@ -87,6 +88,56 @@ class ContextManagerTestCase(unittest.TestCase): raise ZeroDivisionError() self.assertEqual(state, [1, 42, 999]) + def test_contextmanager_traceback(self): + @contextmanager + def f(): + yield + + try: + with f(): + 1/0 + except ZeroDivisionError as e: + frames = traceback.extract_tb(e.__traceback__) + + self.assertEqual(len(frames), 1) + self.assertEqual(frames[0].name, 'test_contextmanager_traceback') + self.assertEqual(frames[0].line, '1/0') + + # Repeat with RuntimeError (which goes through a different code path) + class RuntimeErrorSubclass(RuntimeError): + pass + + try: + with f(): + raise RuntimeErrorSubclass(42) + except RuntimeErrorSubclass as e: + frames = traceback.extract_tb(e.__traceback__) + + self.assertEqual(len(frames), 1) + self.assertEqual(frames[0].name, 'test_contextmanager_traceback') + self.assertEqual(frames[0].line, 'raise RuntimeErrorSubclass(42)') + + class StopIterationSubclass(StopIteration): + pass + + for stop_exc in ( + StopIteration('spam'), + StopIterationSubclass('spam'), + ): + with self.subTest(type=type(stop_exc)): + try: + with f(): + raise stop_exc + except type(stop_exc) as e: + self.assertIs(e, stop_exc) + frames = traceback.extract_tb(e.__traceback__) + else: + self.fail(f'{stop_exc} was suppressed') + + self.assertEqual(len(frames), 1) + self.assertEqual(frames[0].name, 'test_contextmanager_traceback') + self.assertEqual(frames[0].line, 'raise stop_exc') + def test_contextmanager_no_reraise(self): @contextmanager def whee(): @@ -721,6 +772,38 @@ class TestBaseExitStack: stack.push(lambda *exc: True) 1/0 + def test_exit_exception_traceback(self): + # This test captures the current behavior of ExitStack so that we know + # if we ever unintendedly change it. It is not a statement of what the + # desired behavior is (for instance, we may want to remove some of the + # internal contextlib frames). + + def raise_exc(exc): + raise exc + + try: + with self.exit_stack() as stack: + stack.callback(raise_exc, ValueError) + 1/0 + except ValueError as e: + exc = e + + self.assertIsInstance(exc, ValueError) + ve_frames = traceback.extract_tb(exc.__traceback__) + expected = \ + [('test_exit_exception_traceback', 'with self.exit_stack() as stack:')] + \ + self.callback_error_internal_frames + \ + [('_exit_wrapper', 'callback(*args, **kwds)'), + ('raise_exc', 'raise exc')] + + self.assertEqual( + [(f.name, f.line) for f in ve_frames], expected) + + self.assertIsInstance(exc.__context__, ZeroDivisionError) + zde_frames = traceback.extract_tb(exc.__context__.__traceback__) + self.assertEqual([(f.name, f.line) for f in zde_frames], + [('test_exit_exception_traceback', '1/0')]) + def test_exit_exception_chaining_reference(self): # Sanity check to make sure that ExitStack chaining matches # actual nested with statements @@ -990,6 +1073,10 @@ class TestBaseExitStack: class TestExitStack(TestBaseExitStack, unittest.TestCase): exit_stack = ExitStack + callback_error_internal_frames = [ + ('__exit__', 'raise exc_details[1]'), + ('__exit__', 'if cb(*exc_details):'), + ] class TestRedirectStream: @@ -1117,9 +1204,15 @@ class TestSuppress(unittest.TestCase): class TestChdir(unittest.TestCase): + def make_relative_path(self, *parts): + return os.path.join( + os.path.dirname(os.path.realpath(__file__)), + *parts, + ) + def test_simple(self): old_cwd = os.getcwd() - target = os.path.join(os.path.dirname(__file__), 'data') + target = self.make_relative_path('data') self.assertNotEqual(old_cwd, target) with chdir(target): @@ -1128,8 +1221,8 @@ class TestChdir(unittest.TestCase): def test_reentrant(self): old_cwd = os.getcwd() - target1 = os.path.join(os.path.dirname(__file__), 'data') - target2 = os.path.join(os.path.dirname(__file__), 'ziptestdata') + target1 = self.make_relative_path('data') + target2 = self.make_relative_path('ziptestdata') self.assertNotIn(old_cwd, (target1, target2)) chdir1, chdir2 = chdir(target1), chdir(target2) @@ -1145,7 +1238,7 @@ class TestChdir(unittest.TestCase): def test_exception(self): old_cwd = os.getcwd() - target = os.path.join(os.path.dirname(__file__), 'data') + target = self.make_relative_path('data') self.assertNotEqual(old_cwd, target) try: diff --git a/Lib/test/test_contextlib_async.py b/Lib/test/test_contextlib_async.py index c16c7ecd19a..3d43ed0fcab 100644 --- a/Lib/test/test_contextlib_async.py +++ b/Lib/test/test_contextlib_async.py @@ -5,24 +5,23 @@ from contextlib import ( import functools from test import support import unittest +import traceback from test.test_contextlib import TestBaseExitStack +support.requires_working_socket(module=True) def _async_test(func): """Decorator to turn an async function into a test case.""" @functools.wraps(func) def wrapper(*args, **kwargs): coro = func(*args, **kwargs) - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - try: - return loop.run_until_complete(coro) - finally: - loop.close() - asyncio.set_event_loop_policy(None) + asyncio.run(coro) return wrapper +def tearDownModule(): + asyncio.set_event_loop_policy(None) + class TestAbstractAsyncContextManager(unittest.TestCase): @@ -127,6 +126,62 @@ class AsyncContextManagerTestCase(unittest.TestCase): raise ZeroDivisionError() self.assertEqual(state, [1, 42, 999]) + @_async_test + async def test_contextmanager_traceback(self): + @asynccontextmanager + async def f(): + yield + + try: + async with f(): + 1/0 + except ZeroDivisionError as e: + frames = traceback.extract_tb(e.__traceback__) + + self.assertEqual(len(frames), 1) + self.assertEqual(frames[0].name, 'test_contextmanager_traceback') + self.assertEqual(frames[0].line, '1/0') + + # Repeat with RuntimeError (which goes through a different code path) + class RuntimeErrorSubclass(RuntimeError): + pass + + try: + async with f(): + raise RuntimeErrorSubclass(42) + except RuntimeErrorSubclass as e: + frames = traceback.extract_tb(e.__traceback__) + + self.assertEqual(len(frames), 1) + self.assertEqual(frames[0].name, 'test_contextmanager_traceback') + self.assertEqual(frames[0].line, 'raise RuntimeErrorSubclass(42)') + + class StopIterationSubclass(StopIteration): + pass + + class StopAsyncIterationSubclass(StopAsyncIteration): + pass + + for stop_exc in ( + StopIteration('spam'), + StopAsyncIteration('ham'), + StopIterationSubclass('spam'), + StopAsyncIterationSubclass('spam') + ): + with self.subTest(type=type(stop_exc)): + try: + async with f(): + raise stop_exc + except type(stop_exc) as e: + self.assertIs(e, stop_exc) + frames = traceback.extract_tb(e.__traceback__) + else: + self.fail(f'{stop_exc} was suppressed') + + self.assertEqual(len(frames), 1) + self.assertEqual(frames[0].name, 'test_contextmanager_traceback') + self.assertEqual(frames[0].line, 'raise stop_exc') + @_async_test async def test_contextmanager_no_reraise(self): @asynccontextmanager @@ -486,6 +541,13 @@ class TestAsyncExitStack(TestBaseExitStack, unittest.TestCase): return self.run_coroutine(self.__aexit__(*exc_details)) exit_stack = SyncAsyncExitStack + callback_error_internal_frames = [ + ('__exit__', 'return self.run_coroutine(self.__aexit__(*exc_details))'), + ('run_coroutine', 'raise exc'), + ('run_coroutine', 'raise exc'), + ('__aexit__', 'raise exc_details[1]'), + ('__aexit__', 'cb_suppress = cb(*exc_details)'), + ] def setUp(self): self.loop = asyncio.new_event_loop() diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py index f1ca8cb254d..826e46824e0 100644 --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -51,6 +51,9 @@ class TestCopy(unittest.TestCase): self.assertRaises(TypeError, copy.copy, x) copyreg.pickle(C, pickle_C, C) y = copy.copy(x) + self.assertIsNot(x, y) + self.assertEqual(type(y), C) + self.assertEqual(y.foo, x.foo) def test_copy_reduce_ex(self): class C(object): @@ -88,9 +91,7 @@ class TestCopy(unittest.TestCase): # Type-specific _copy_xxx() methods def test_copy_atomic(self): - class Classic: - pass - class NewStyle(object): + class NewStyle: pass def f(): pass @@ -100,7 +101,7 @@ class TestCopy(unittest.TestCase): 42, 2**100, 3.14, True, False, 1j, "hello", "hello\u1234", f.__code__, b"world", bytes(range(256)), range(10), slice(1, 10, 2), - NewStyle, Classic, max, WithMetaclass, property()] + NewStyle, max, WithMetaclass, property()] for x in tests: self.assertIs(copy.copy(x), x) @@ -313,6 +314,9 @@ class TestCopy(unittest.TestCase): self.assertRaises(TypeError, copy.deepcopy, x) copyreg.pickle(C, pickle_C, C) y = copy.deepcopy(x) + self.assertIsNot(x, y) + self.assertEqual(type(y), C) + self.assertEqual(y.foo, x.foo) def test_deepcopy_reduce_ex(self): class C(object): @@ -350,15 +354,13 @@ class TestCopy(unittest.TestCase): # Type-specific _deepcopy_xxx() methods def test_deepcopy_atomic(self): - class Classic: - pass - class NewStyle(object): + class NewStyle: pass def f(): pass - tests = [None, 42, 2**100, 3.14, True, False, 1j, - "hello", "hello\u1234", f.__code__, - NewStyle, range(10), Classic, max, property()] + tests = [None, ..., NotImplemented, 42, 2**100, 3.14, True, False, 1j, + b"bytes", "hello", "hello\u1234", f.__code__, + NewStyle, range(10), max, property()] for x in tests: self.assertIs(copy.deepcopy(x), x) @@ -678,6 +680,28 @@ class TestCopy(unittest.TestCase): self.assertIsNot(x, y) self.assertIsNot(x["foo"], y["foo"]) + def test_reduce_6tuple(self): + def state_setter(*args, **kwargs): + self.fail("shouldn't call this") + class C: + def __reduce__(self): + return C, (), self.__dict__, None, None, state_setter + x = C() + with self.assertRaises(TypeError): + copy.copy(x) + with self.assertRaises(TypeError): + copy.deepcopy(x) + + def test_reduce_6tuple_none(self): + class C: + def __reduce__(self): + return C, (), self.__dict__, None, None, None + x = C() + with self.assertRaises(TypeError): + copy.copy(x) + with self.assertRaises(TypeError): + copy.deepcopy(x) + def test_copy_slots(self): class C(object): __slots__ = ["foo"] diff --git a/Lib/test/test_copyreg.py b/Lib/test/test_copyreg.py index e3f1cd81aab..e158c19db2d 100644 --- a/Lib/test/test_copyreg.py +++ b/Lib/test/test_copyreg.py @@ -6,6 +6,9 @@ from test.pickletester import ExtensionSaver class C: pass +def pickle_C(c): + return C, () + class WithoutSlots(object): pass @@ -32,16 +35,15 @@ class WithInherited(WithSingleString): class CopyRegTestCase(unittest.TestCase): def test_class(self): - self.assertRaises(TypeError, copyreg.pickle, - C, None, None) + copyreg.pickle(C, pickle_C) def test_noncallable_reduce(self): self.assertRaises(TypeError, copyreg.pickle, - type(1), "not a callable") + C, "not a callable") def test_noncallable_constructor(self): self.assertRaises(TypeError, copyreg.pickle, - type(1), int, "not a callable") + C, pickle_C, "not a callable") def test_bool(self): import copy diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 4350e185a24..6ab19efcc58 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -4,6 +4,7 @@ import inspect import pickle import sys import types +import traceback import unittest import warnings from test import support @@ -708,9 +709,16 @@ class CoroutineTest(unittest.TestCase): aw = coro.__await__() next(aw) with self.assertRaises(ZeroDivisionError): - aw.throw(ZeroDivisionError, None, None) + aw.throw(ZeroDivisionError()) self.assertEqual(N, 102) + coro = foo() + aw = coro.__await__() + next(aw) + with self.assertRaises(ZeroDivisionError): + with self.assertWarns(DeprecationWarning): + aw.throw(ZeroDivisionError, ZeroDivisionError(), None) + def test_func_11(self): async def func(): pass coro = func() @@ -1279,7 +1287,7 @@ class CoroutineTest(unittest.TestCase): async def func(): async with CM(): - assert (1, ) == 1 + self.assertEqual((1, ), 1) with self.assertRaises(AssertionError): run_async(func()) @@ -2191,7 +2199,51 @@ class CoroutineTest(unittest.TestCase): return 'end' self.assertEqual(run_async(run_gen()), ([], 'end')) + def test_bpo_45813_1(self): + 'This would crash the interpreter in 3.11a2' + async def f(): + pass + with self.assertWarns(RuntimeWarning): + frame = f().cr_frame + frame.clear() + def test_bpo_45813_2(self): + 'This would crash the interpreter in 3.11a2' + async def f(): + pass + gen = f() + with self.assertWarns(RuntimeWarning): + gen.cr_frame.clear() + gen.close() + + def test_stack_in_coroutine_throw(self): + # Regression test for https://github.com/python/cpython/issues/93592 + async def a(): + return await b() + + async def b(): + return await c() + + @types.coroutine + def c(): + try: + # traceback.print_stack() + yield len(traceback.extract_stack()) + except ZeroDivisionError: + # traceback.print_stack() + yield len(traceback.extract_stack()) + + coro = a() + len_send = coro.send(None) + len_throw = coro.throw(ZeroDivisionError) + # before fixing, visible stack from throw would be shorter than from send. + self.assertEqual(len_send, len_throw) + + +@unittest.skipIf( + support.is_emscripten or support.is_wasi, + "asyncio does not work under Emscripten/WASI yet." +) class CoroAsyncIOCompatTest(unittest.TestCase): def test_asyncio_1(self): @@ -2367,7 +2419,8 @@ class UnawaitedWarningDuringShutdownTest(unittest.TestCase): def test_unawaited_warning_during_shutdown(self): code = ("import asyncio\n" "async def f(): pass\n" - "asyncio.gather(f())\n") + "async def t(): asyncio.gather(f())\n" + "asyncio.run(t())\n") assert_python_ok("-c", code) code = ("import sys\n" diff --git a/Lib/test/test_cppext.py b/Lib/test/test_cppext.py new file mode 100644 index 00000000000..465894d24e7 --- /dev/null +++ b/Lib/test/test_cppext.py @@ -0,0 +1,105 @@ +# gh-91321: Build a basic C++ test extension to check that the Python C API is +# compatible with C++ and does not emit C++ compiler warnings. +import os.path +import sys +import unittest +import subprocess +import sysconfig +from test import support +from test.support import os_helper + + +MS_WINDOWS = (sys.platform == 'win32') + + +SETUP_TESTCPPEXT = support.findfile('setup_testcppext.py') + + +@support.requires_subprocess() +class TestCPPExt(unittest.TestCase): + def test_build_cpp11(self): + self.check_build(False, '_testcpp11ext') + + def test_build_cpp03(self): + self.check_build(True, '_testcpp03ext') + + # With MSVC, the linker fails with: cannot open file 'python311.lib' + # https://github.com/python/cpython/pull/32175#issuecomment-1111175897 + @unittest.skipIf(MS_WINDOWS, 'test fails on Windows') + # Building and running an extension in clang sanitizing mode is not + # straightforward + @unittest.skipIf( + '-fsanitize' in (sysconfig.get_config_var('PY_CFLAGS') or ''), + 'test does not work with analyzing builds') + # the test uses venv+pip: skip if it's not available + @support.requires_venv_with_pip() + def check_build(self, std_cpp03, extension_name): + # Build in a temporary directory + with os_helper.temp_cwd(): + self._check_build(std_cpp03, extension_name) + + def _check_build(self, std_cpp03, extension_name): + venv_dir = 'env' + verbose = support.verbose + + # Create virtual environment to get setuptools + cmd = [sys.executable, '-X', 'dev', '-m', 'venv', venv_dir] + if verbose: + print() + print('Run:', ' '.join(cmd)) + subprocess.run(cmd, check=True) + + # Get the Python executable of the venv + python_exe = 'python' + if sys.executable.endswith('.exe'): + python_exe += '.exe' + if MS_WINDOWS: + python = os.path.join(venv_dir, 'Scripts', python_exe) + else: + python = os.path.join(venv_dir, 'bin', python_exe) + + def run_cmd(operation, cmd): + if verbose: + print('Run:', ' '.join(cmd)) + subprocess.run(cmd, check=True) + else: + proc = subprocess.run(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True) + if proc.returncode: + print(proc.stdout, end='') + self.fail( + f"{operation} failed with exit code {proc.returncode}") + + # Build the C++ extension + cmd = [python, '-X', 'dev', + SETUP_TESTCPPEXT, 'build_ext', '--verbose'] + if std_cpp03: + cmd.append('-std=c++03') + run_cmd('Build', cmd) + + # Install the C++ extension + cmd = [python, '-X', 'dev', + SETUP_TESTCPPEXT, 'install'] + run_cmd('Install', cmd) + + # Do a reference run. Until we test that running python + # doesn't leak references (gh-94755), run it so one can manually check + # -X showrefcount results against this baseline. + cmd = [python, + '-X', 'dev', + '-X', 'showrefcount', + '-c', 'pass'] + run_cmd('Reference run', cmd) + + # Import the C++ extension + cmd = [python, + '-X', 'dev', + '-X', 'showrefcount', + '-c', f"import {extension_name}"] + run_cmd('Import', cmd) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_crypt.py b/Lib/test/test_crypt.py index 5dc83b4ecbf..b2a5ce6db09 100644 --- a/Lib/test/test_crypt.py +++ b/Lib/test/test_crypt.py @@ -1,9 +1,12 @@ import sys import unittest +from test.support import check_sanitizer, warnings_helper try: - import crypt + if check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("The crypt module SEGFAULTs on ASAN/MSAN builds") + crypt = warnings_helper.import_deprecated("crypt") IMPORT_ERROR = None except ImportError as ex: if sys.platform != 'win32': diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index 95a19dd46cb..8289ddb1c3a 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -362,6 +362,11 @@ class Test_Csv(unittest.TestCase): self._read_test(['1,@,3,@,5'], [['1', ',3,', '5']], quotechar='@') self._read_test(['1,\0,3,\0,5'], [['1', ',3,', '5']], quotechar='\0') + def test_read_skipinitialspace(self): + self._read_test(['no space, space, spaces,\ttab'], + [['no space', 'space', 'spaces', '\ttab']], + skipinitialspace=True) + def test_read_bigfield(self): # This exercises the buffer realloc functionality and field size # limits. @@ -448,6 +453,34 @@ class TestDialectRegistry(unittest.TestCase): self.assertEqual(csv.get_dialect(name).delimiter, ';') self.assertEqual([['X', 'Y', 'Z']], list(csv.reader(['X;Y;Z'], name))) + def test_register_kwargs_override(self): + class mydialect(csv.Dialect): + delimiter = "\t" + quotechar = '"' + doublequote = True + skipinitialspace = False + lineterminator = '\r\n' + quoting = csv.QUOTE_MINIMAL + + name = 'test_dialect' + csv.register_dialect(name, mydialect, + delimiter=';', + quotechar="'", + doublequote=False, + skipinitialspace=True, + lineterminator='\n', + quoting=csv.QUOTE_ALL) + self.addCleanup(csv.unregister_dialect, name) + + # Ensure that kwargs do override attributes of a dialect class: + dialect = csv.get_dialect(name) + self.assertEqual(dialect.delimiter, ';') + self.assertEqual(dialect.quotechar, "'") + self.assertEqual(dialect.doublequote, False) + self.assertEqual(dialect.skipinitialspace, True) + self.assertEqual(dialect.lineterminator, '\n') + self.assertEqual(dialect.quoting, csv.QUOTE_ALL) + def test_incomplete_dialect(self): class myexceltsv(csv.Dialect): delimiter = "\t" @@ -729,6 +762,10 @@ class TestDictFields(unittest.TestCase): dictrow = {'f0': 0, 'f1': 1, 'f2': 2, 'f3': 3} self.assertRaises(ValueError, csv.DictWriter.writerow, writer, dictrow) + # see bpo-44512 (differently cased 'raise' should not result in 'ignore') + writer = csv.DictWriter(fileobj, ['f1', 'f2'], extrasaction="RAISE") + self.assertRaises(ValueError, csv.DictWriter.writerow, writer, dictrow) + def test_write_field_not_in_field_names_ignore(self): fileobj = StringIO() writer = csv.DictWriter(fileobj, ['f1', 'f2'], extrasaction="ignore") @@ -736,6 +773,38 @@ class TestDictFields(unittest.TestCase): csv.DictWriter.writerow(writer, dictrow) self.assertEqual(fileobj.getvalue(), "1,2\r\n") + # bpo-44512 + writer = csv.DictWriter(fileobj, ['f1', 'f2'], extrasaction="IGNORE") + csv.DictWriter.writerow(writer, dictrow) + + def test_dict_reader_fieldnames_accepts_iter(self): + fieldnames = ["a", "b", "c"] + f = StringIO() + reader = csv.DictReader(f, iter(fieldnames)) + self.assertEqual(reader.fieldnames, fieldnames) + + def test_dict_reader_fieldnames_accepts_list(self): + fieldnames = ["a", "b", "c"] + f = StringIO() + reader = csv.DictReader(f, fieldnames) + self.assertEqual(reader.fieldnames, fieldnames) + + def test_dict_writer_fieldnames_rejects_iter(self): + fieldnames = ["a", "b", "c"] + f = StringIO() + writer = csv.DictWriter(f, iter(fieldnames)) + self.assertEqual(writer.fieldnames, fieldnames) + + def test_dict_writer_fieldnames_accepts_list(self): + fieldnames = ["a", "b", "c"] + f = StringIO() + writer = csv.DictWriter(f, fieldnames) + self.assertEqual(writer.fieldnames, fieldnames) + + def test_dict_reader_fieldnames_is_optional(self): + f = StringIO() + reader = csv.DictReader(f, fieldnames=None) + def test_read_dict_fields(self): with TemporaryFile("w+", encoding="utf-8") as fileobj: fileobj.write("1,2,abc\r\n") diff --git a/Lib/test/test_ctypes.py b/Lib/test/test_ctypes.py deleted file mode 100644 index b0a12c97347..00000000000 --- a/Lib/test/test_ctypes.py +++ /dev/null @@ -1,10 +0,0 @@ -import unittest -from test.support.import_helper import import_module - - -ctypes_test = import_module('ctypes.test') - -load_tests = ctypes_test.load_tests - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/ctypes/test/__init__.py b/Lib/test/test_ctypes/__init__.py similarity index 100% rename from Lib/ctypes/test/__init__.py rename to Lib/test/test_ctypes/__init__.py diff --git a/Lib/test/test_ctypes/__main__.py b/Lib/test/test_ctypes/__main__.py new file mode 100644 index 00000000000..3003d4db890 --- /dev/null +++ b/Lib/test/test_ctypes/__main__.py @@ -0,0 +1,4 @@ +from test.test_ctypes import load_tests +import unittest + +unittest.main() diff --git a/Lib/ctypes/test/test_anon.py b/Lib/test/test_ctypes/test_anon.py similarity index 100% rename from Lib/ctypes/test/test_anon.py rename to Lib/test/test_ctypes/test_anon.py diff --git a/Lib/ctypes/test/test_array_in_pointer.py b/Lib/test/test_ctypes/test_array_in_pointer.py similarity index 100% rename from Lib/ctypes/test/test_array_in_pointer.py rename to Lib/test/test_ctypes/test_array_in_pointer.py diff --git a/Lib/ctypes/test/test_arrays.py b/Lib/test/test_ctypes/test_arrays.py similarity index 99% rename from Lib/ctypes/test/test_arrays.py rename to Lib/test/test_ctypes/test_arrays.py index 14603b7049c..415a5785a9c 100644 --- a/Lib/ctypes/test/test_arrays.py +++ b/Lib/test/test_ctypes/test_arrays.py @@ -3,7 +3,7 @@ from test.support import bigmemtest, _2G import sys from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol formats = "bBhHiIlLqQfd" diff --git a/Lib/ctypes/test/test_as_parameter.py b/Lib/test/test_ctypes/test_as_parameter.py similarity index 98% rename from Lib/ctypes/test/test_as_parameter.py rename to Lib/test/test_ctypes/test_as_parameter.py index f9d27cb89d3..e9ec9ad847b 100644 --- a/Lib/ctypes/test/test_as_parameter.py +++ b/Lib/test/test_ctypes/test_as_parameter.py @@ -1,6 +1,6 @@ import unittest from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import _ctypes_test dll = CDLL(_ctypes_test.__file__) @@ -122,6 +122,7 @@ class BasicWrapTestCase(unittest.TestCase): result = f(self.wrap(-10), self.wrap(cb)) self.assertEqual(result, -18) + @need_symbol('c_longlong') def test_longlong_callbacks(self): f = dll._testfunc_callback_q_qf diff --git a/Lib/ctypes/test/test_bitfields.py b/Lib/test/test_ctypes/test_bitfields.py similarity index 98% rename from Lib/ctypes/test/test_bitfields.py rename to Lib/test/test_ctypes/test_bitfields.py index 992b8c4da3a..dad71a0ba7e 100644 --- a/Lib/ctypes/test/test_bitfields.py +++ b/Lib/test/test_ctypes/test_bitfields.py @@ -1,5 +1,6 @@ from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol +from test import support import unittest import os @@ -39,6 +40,8 @@ class C_Test(unittest.TestCase): setattr(b, name, i) self.assertEqual(getattr(b, name), func(byref(b), name.encode('ascii'))) + # bpo-46913: _ctypes/cfield.c h_get() has an undefined behavior + @support.skip_if_sanitizer(ub=True) def test_shorts(self): b = BITS() name = "M" diff --git a/Lib/ctypes/test/test_buffers.py b/Lib/test/test_ctypes/test_buffers.py similarity index 98% rename from Lib/ctypes/test/test_buffers.py rename to Lib/test/test_ctypes/test_buffers.py index 15782be757c..a9be2023aa0 100644 --- a/Lib/ctypes/test/test_buffers.py +++ b/Lib/test/test_ctypes/test_buffers.py @@ -1,5 +1,5 @@ from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import unittest class StringBufferTestCase(unittest.TestCase): diff --git a/Lib/ctypes/test/test_bytes.py b/Lib/test/test_ctypes/test_bytes.py similarity index 100% rename from Lib/ctypes/test/test_bytes.py rename to Lib/test/test_ctypes/test_bytes.py diff --git a/Lib/ctypes/test/test_byteswap.py b/Lib/test/test_ctypes/test_byteswap.py similarity index 79% rename from Lib/ctypes/test/test_byteswap.py rename to Lib/test/test_ctypes/test_byteswap.py index 01c97e83ca7..7e98559dfbc 100644 --- a/Lib/ctypes/test/test_byteswap.py +++ b/Lib/test/test_ctypes/test_byteswap.py @@ -170,40 +170,34 @@ class Test(unittest.TestCase): self.assertIs(c_char.__ctype_le__, c_char) self.assertIs(c_char.__ctype_be__, c_char) - def test_struct_fields_1(self): - if sys.byteorder == "little": - base = BigEndianStructure - else: - base = LittleEndianStructure + def test_struct_fields_unsupported_byte_order(self): - class T(base): - pass - _fields_ = [("a", c_ubyte), - ("b", c_byte), - ("c", c_short), - ("d", c_ushort), - ("e", c_int), - ("f", c_uint), - ("g", c_long), - ("h", c_ulong), - ("i", c_longlong), - ("k", c_ulonglong), - ("l", c_float), - ("m", c_double), - ("n", c_char), - - ("b1", c_byte, 3), - ("b2", c_byte, 3), - ("b3", c_byte, 2), - ("a", c_int * 3 * 3 * 3)] - T._fields_ = _fields_ + fields = [ + ("a", c_ubyte), + ("b", c_byte), + ("c", c_short), + ("d", c_ushort), + ("e", c_int), + ("f", c_uint), + ("g", c_long), + ("h", c_ulong), + ("i", c_longlong), + ("k", c_ulonglong), + ("l", c_float), + ("m", c_double), + ("n", c_char), + ("b1", c_byte, 3), + ("b2", c_byte, 3), + ("b3", c_byte, 2), + ("a", c_int * 3 * 3 * 3) + ] # these fields do not support different byte order: for typ in c_wchar, c_void_p, POINTER(c_int): - _fields_.append(("x", typ)) - class T(base): - pass - self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)]) + with self.assertRaises(TypeError): + class T(BigEndianStructure if sys.byteorder == "little" else LittleEndianStructure): + _fields_ = fields + [("x", typ)] + def test_struct_struct(self): # nested structures with different byteorders @@ -233,7 +227,7 @@ class Test(unittest.TestCase): self.assertEqual(s.point.x, 1) self.assertEqual(s.point.y, 2) - def test_struct_fields_2(self): + def test_struct_field_alignment(self): # standard packing in struct uses no alignment. # So, we have to align using pad bytes. # @@ -267,7 +261,6 @@ class Test(unittest.TestCase): class S(base): _pack_ = 1 _fields_ = [("b", c_byte), - ("h", c_short), ("_1", c_byte), @@ -311,5 +304,61 @@ class Test(unittest.TestCase): s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14) self.assertEqual(bin(s1), bin(s2)) + def test_union_fields_unsupported_byte_order(self): + + fields = [ + ("a", c_ubyte), + ("b", c_byte), + ("c", c_short), + ("d", c_ushort), + ("e", c_int), + ("f", c_uint), + ("g", c_long), + ("h", c_ulong), + ("i", c_longlong), + ("k", c_ulonglong), + ("l", c_float), + ("m", c_double), + ("n", c_char), + ("b1", c_byte, 3), + ("b2", c_byte, 3), + ("b3", c_byte, 2), + ("a", c_int * 3 * 3 * 3) + ] + + # these fields do not support different byte order: + for typ in c_wchar, c_void_p, POINTER(c_int): + with self.assertRaises(TypeError): + class T(BigEndianUnion if sys.byteorder == "little" else LittleEndianUnion): + _fields_ = fields + [("x", typ)] + + def test_union_struct(self): + # nested structures in unions with different byteorders + + # create nested structures in unions with given byteorders and set memory to data + + for nested, data in ( + (BigEndianStructure, b'\0\0\0\1\0\0\0\2'), + (LittleEndianStructure, b'\1\0\0\0\2\0\0\0'), + ): + for parent in ( + BigEndianUnion, + LittleEndianUnion, + Union, + ): + class NestedStructure(nested): + _fields_ = [("x", c_uint32), + ("y", c_uint32)] + + class TestUnion(parent): + _fields_ = [("point", NestedStructure)] + + self.assertEqual(len(data), sizeof(TestUnion)) + ptr = POINTER(TestUnion) + s = cast(data, ptr)[0] + del ctypes._pointer_type_cache[TestUnion] + self.assertEqual(s.point.x, 1) + self.assertEqual(s.point.y, 2) + if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_callbacks.py b/Lib/test/test_ctypes/test_callbacks.py similarity index 91% rename from Lib/ctypes/test/test_callbacks.py rename to Lib/test/test_ctypes/test_callbacks.py index d8e9c5a760e..e8fa3e6f7ac 100644 --- a/Lib/ctypes/test/test_callbacks.py +++ b/Lib/test/test_ctypes/test_callbacks.py @@ -1,9 +1,11 @@ +import sys import functools import unittest from test import support from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol +from _ctypes import CTYPES_MAX_ARGCOUNT import _ctypes_test class Callbacks(unittest.TestCase): @@ -64,10 +66,12 @@ class Callbacks(unittest.TestCase): def test_ulong(self): self.check_type(c_ulong, 42) + @need_symbol('c_longlong') def test_longlong(self): self.check_type(c_longlong, 42) self.check_type(c_longlong, -42) + @need_symbol('c_ulonglong') def test_ulonglong(self): self.check_type(c_ulonglong, 42) @@ -81,6 +85,7 @@ class Callbacks(unittest.TestCase): self.check_type(c_double, 3.14) self.check_type(c_double, -3.14) + @need_symbol('c_longdouble') def test_longdouble(self): self.check_type(c_longdouble, 3.14) self.check_type(c_longdouble, -3.14) @@ -146,6 +151,18 @@ class Callbacks(unittest.TestCase): gc.collect() CFUNCTYPE(None)(lambda x=Nasty(): None) + @need_symbol('WINFUNCTYPE') + def test_i38748_stackCorruption(self): + callback_funcType = WINFUNCTYPE(c_long, c_long, c_longlong) + @callback_funcType + def callback(a, b): + c = a + b + print(f"a={a}, b={b}, c={c}") + return c + dll = cdll[_ctypes_test.__file__] + # With no fix for i38748, the next line will raise OSError and cause the test to fail. + self.assertEqual(dll._test_i38748_runCallback(callback, 5, 10), 15) + @need_symbol('WINFUNCTYPE') class StdcallCallbacks(Callbacks): @@ -293,16 +310,21 @@ class SampleCallbacksTestCase(unittest.TestCase): def func(*args): return len(args) - CTYPES_MAX_ARGCOUNT = 1024 + # valid call with nargs <= CTYPES_MAX_ARGCOUNT proto = CFUNCTYPE(c_int, *(c_int,) * CTYPES_MAX_ARGCOUNT) cb = proto(func) args1 = (1,) * CTYPES_MAX_ARGCOUNT self.assertEqual(cb(*args1), CTYPES_MAX_ARGCOUNT) + # invalid call with nargs > CTYPES_MAX_ARGCOUNT args2 = (1,) * (CTYPES_MAX_ARGCOUNT + 1) with self.assertRaises(ArgumentError): cb(*args2) + # error when creating the type with too many arguments + with self.assertRaises(ArgumentError): + CFUNCTYPE(c_int, *(c_int,) * (CTYPES_MAX_ARGCOUNT + 1)) + def test_convert_result_error(self): def func(): return ("tuple",) diff --git a/Lib/ctypes/test/test_cast.py b/Lib/test/test_ctypes/test_cast.py similarity index 98% rename from Lib/ctypes/test/test_cast.py rename to Lib/test/test_ctypes/test_cast.py index 6878f973282..7ee23b16f1b 100644 --- a/Lib/ctypes/test/test_cast.py +++ b/Lib/test/test_ctypes/test_cast.py @@ -1,5 +1,5 @@ from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import unittest import sys diff --git a/Lib/ctypes/test/test_cfuncs.py b/Lib/test/test_ctypes/test_cfuncs.py similarity index 97% rename from Lib/ctypes/test/test_cfuncs.py rename to Lib/test/test_ctypes/test_cfuncs.py index ac2240fa197..7cba4b0e527 100644 --- a/Lib/ctypes/test/test_cfuncs.py +++ b/Lib/test/test_ctypes/test_cfuncs.py @@ -3,7 +3,7 @@ import unittest from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import _ctypes_test @@ -111,24 +111,28 @@ class CFunctions(unittest.TestCase): self.assertEqual(self._dll.tf_bL(b' ', 4294967295), 1431655765) self.assertEqual(self.U(), 4294967295) + @need_symbol('c_longlong') def test_longlong(self): self._dll.tf_q.restype = c_longlong self._dll.tf_q.argtypes = (c_longlong, ) self.assertEqual(self._dll.tf_q(-9223372036854775806), -3074457345618258602) self.assertEqual(self.S(), -9223372036854775806) + @need_symbol('c_longlong') def test_longlong_plus(self): self._dll.tf_bq.restype = c_longlong self._dll.tf_bq.argtypes = (c_byte, c_longlong) self.assertEqual(self._dll.tf_bq(0, -9223372036854775806), -3074457345618258602) self.assertEqual(self.S(), -9223372036854775806) + @need_symbol('c_ulonglong') def test_ulonglong(self): self._dll.tf_Q.restype = c_ulonglong self._dll.tf_Q.argtypes = (c_ulonglong, ) self.assertEqual(self._dll.tf_Q(18446744073709551615), 6148914691236517205) self.assertEqual(self.U(), 18446744073709551615) + @need_symbol('c_ulonglong') def test_ulonglong_plus(self): self._dll.tf_bQ.restype = c_ulonglong self._dll.tf_bQ.argtypes = (c_byte, c_ulonglong) @@ -159,12 +163,14 @@ class CFunctions(unittest.TestCase): self.assertEqual(self._dll.tf_bd(0, 42.), 14.) self.assertEqual(self.S(), 42) + @need_symbol('c_longdouble') def test_longdouble(self): self._dll.tf_D.restype = c_longdouble self._dll.tf_D.argtypes = (c_longdouble,) self.assertEqual(self._dll.tf_D(42.), 14.) self.assertEqual(self.S(), 42) + @need_symbol('c_longdouble') def test_longdouble_plus(self): self._dll.tf_bD.restype = c_longdouble self._dll.tf_bD.argtypes = (c_byte, c_longdouble) diff --git a/Lib/ctypes/test/test_checkretval.py b/Lib/test/test_ctypes/test_checkretval.py similarity index 95% rename from Lib/ctypes/test/test_checkretval.py rename to Lib/test/test_ctypes/test_checkretval.py index e9567dc3912..1492099f4b9 100644 --- a/Lib/ctypes/test/test_checkretval.py +++ b/Lib/test/test_ctypes/test_checkretval.py @@ -1,7 +1,7 @@ import unittest from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol class CHECKED(c_int): def _check_retval_(value): diff --git a/Lib/ctypes/test/test_delattr.py b/Lib/test/test_ctypes/test_delattr.py similarity index 100% rename from Lib/ctypes/test/test_delattr.py rename to Lib/test/test_ctypes/test_delattr.py diff --git a/Lib/ctypes/test/test_errno.py b/Lib/test/test_ctypes/test_errno.py similarity index 100% rename from Lib/ctypes/test/test_errno.py rename to Lib/test/test_ctypes/test_errno.py diff --git a/Lib/ctypes/test/test_find.py b/Lib/test/test_ctypes/test_find.py similarity index 100% rename from Lib/ctypes/test/test_find.py rename to Lib/test/test_ctypes/test_find.py diff --git a/Lib/ctypes/test/test_frombuffer.py b/Lib/test/test_ctypes/test_frombuffer.py similarity index 100% rename from Lib/ctypes/test/test_frombuffer.py rename to Lib/test/test_ctypes/test_frombuffer.py diff --git a/Lib/ctypes/test/test_funcptr.py b/Lib/test/test_ctypes/test_funcptr.py similarity index 100% rename from Lib/ctypes/test/test_funcptr.py rename to Lib/test/test_ctypes/test_funcptr.py diff --git a/Lib/ctypes/test/test_functions.py b/Lib/test/test_ctypes/test_functions.py similarity index 90% rename from Lib/ctypes/test/test_functions.py rename to Lib/test/test_ctypes/test_functions.py index c5456ba107a..703bd2c601c 100644 --- a/Lib/ctypes/test/test_functions.py +++ b/Lib/test/test_ctypes/test_functions.py @@ -6,7 +6,7 @@ Later... """ from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import sys, unittest try: @@ -35,33 +35,40 @@ class FunctionTestCase(unittest.TestCase): # wasn't checked, and it even crashed Python. # Found by Greg Chapman. - try: + with self.assertRaises(TypeError): class X(object, Array): _length_ = 5 _type_ = "i" - except TypeError: - pass - from _ctypes import _Pointer - try: + with self.assertRaises(TypeError): class X(object, _Pointer): pass - except TypeError: - pass from _ctypes import _SimpleCData - try: + with self.assertRaises(TypeError): class X(object, _SimpleCData): _type_ = "i" - except TypeError: - pass - try: + with self.assertRaises(TypeError): class X(object, Structure): _fields_ = [] - except TypeError: - pass + + def test_c_char_parm(self): + proto = CFUNCTYPE(c_int, c_char) + def callback(*args): + return 0 + + callback = proto(callback) + + self.assertEqual(callback(b"a"), 0) + + with self.assertRaises(ArgumentError) as cm: + callback(b"abc") + + self.assertEqual(str(cm.exception), + "argument 1: TypeError: one character bytes, " + "bytearray or integer expected") @need_symbol('c_wchar') @@ -72,6 +79,18 @@ class FunctionTestCase(unittest.TestCase): self.assertEqual(result, 139) self.assertEqual(type(result), int) + with self.assertRaises(ArgumentError) as cm: + f(1, 2, 3, 4, 5.0, 6.0) + self.assertEqual(str(cm.exception), + "argument 2: TypeError: unicode string expected " + "instead of int instance") + + with self.assertRaises(ArgumentError) as cm: + f(1, "abc", 3, 4, 5.0, 6.0) + self.assertEqual(str(cm.exception), + "argument 2: TypeError: one character unicode string " + "expected") + @need_symbol('c_wchar') def test_wchar_result(self): f = dll._testfunc_i_bhilfd @@ -138,6 +157,7 @@ class FunctionTestCase(unittest.TestCase): self.assertEqual(result, -21) self.assertEqual(type(result), float) + @need_symbol('c_longdouble') def test_longdoubleresult(self): f = dll._testfunc_D_bhilfD f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_longdouble] @@ -380,7 +400,7 @@ class FunctionTestCase(unittest.TestCase): (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9)) def test_sf1651235(self): - # see https://www.python.org/sf/1651235 + # see https://bugs.python.org/issue1651235 proto = CFUNCTYPE(c_int, RECT, POINT) def callback(*args): diff --git a/Lib/ctypes/test/test_incomplete.py b/Lib/test/test_ctypes/test_incomplete.py similarity index 100% rename from Lib/ctypes/test/test_incomplete.py rename to Lib/test/test_ctypes/test_incomplete.py diff --git a/Lib/ctypes/test/test_init.py b/Lib/test/test_ctypes/test_init.py similarity index 100% rename from Lib/ctypes/test/test_init.py rename to Lib/test/test_ctypes/test_init.py diff --git a/Lib/ctypes/test/test_internals.py b/Lib/test/test_ctypes/test_internals.py similarity index 100% rename from Lib/ctypes/test/test_internals.py rename to Lib/test/test_ctypes/test_internals.py diff --git a/Lib/ctypes/test/test_keeprefs.py b/Lib/test/test_ctypes/test_keeprefs.py similarity index 100% rename from Lib/ctypes/test/test_keeprefs.py rename to Lib/test/test_ctypes/test_keeprefs.py diff --git a/Lib/ctypes/test/test_libc.py b/Lib/test/test_ctypes/test_libc.py similarity index 100% rename from Lib/ctypes/test/test_libc.py rename to Lib/test/test_ctypes/test_libc.py diff --git a/Lib/ctypes/test/test_loading.py b/Lib/test/test_ctypes/test_loading.py similarity index 96% rename from Lib/ctypes/test/test_loading.py rename to Lib/test/test_ctypes/test_loading.py index ea892277c4e..15e365ed267 100644 --- a/Lib/ctypes/test/test_loading.py +++ b/Lib/test/test_ctypes/test_loading.py @@ -93,7 +93,7 @@ class LoaderTest(unittest.TestCase): # NOT fit into a 32-bit integer. FreeLibrary must be able # to accept this address. - # These are tests for https://www.python.org/sf/1703286 + # These are tests for https://bugs.python.org/issue1703286 handle = LoadLibrary("advapi32") FreeLibrary(handle) @@ -116,6 +116,12 @@ class LoaderTest(unittest.TestCase): # This is the real test: call the function via 'call_function' self.assertEqual(0, call_function(proc, (None,))) + @unittest.skipUnless(os.name == "nt", + 'test specific to Windows') + def test_load_hasattr(self): + # bpo-34816: shouldn't raise OSError + self.assertFalse(hasattr(windll, 'test')) + @unittest.skipUnless(os.name == "nt", 'test specific to Windows') def test_load_dll_with_flags(self): diff --git a/Lib/test/test_ctypes/test_macholib.py b/Lib/test/test_ctypes/test_macholib.py new file mode 100644 index 00000000000..bc75f1a05a8 --- /dev/null +++ b/Lib/test/test_ctypes/test_macholib.py @@ -0,0 +1,110 @@ +import os +import sys +import unittest + +# Bob Ippolito: +# +# Ok.. the code to find the filename for __getattr__ should look +# something like: +# +# import os +# from macholib.dyld import dyld_find +# +# def find_lib(name): +# possible = ['lib'+name+'.dylib', name+'.dylib', +# name+'.framework/'+name] +# for dylib in possible: +# try: +# return os.path.realpath(dyld_find(dylib)) +# except ValueError: +# pass +# raise ValueError, "%s not found" % (name,) +# +# It'll have output like this: +# +# >>> find_lib('pthread') +# '/usr/lib/libSystem.B.dylib' +# >>> find_lib('z') +# '/usr/lib/libz.1.dylib' +# >>> find_lib('IOKit') +# '/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit' +# +# -bob + +from ctypes.macholib.dyld import dyld_find +from ctypes.macholib.dylib import dylib_info +from ctypes.macholib.framework import framework_info + +def find_lib(name): + possible = ['lib'+name+'.dylib', name+'.dylib', name+'.framework/'+name] + for dylib in possible: + try: + return os.path.realpath(dyld_find(dylib)) + except ValueError: + pass + raise ValueError("%s not found" % (name,)) + + +def d(location=None, name=None, shortname=None, version=None, suffix=None): + return {'location': location, 'name': name, 'shortname': shortname, + 'version': version, 'suffix': suffix} + + +class MachOTest(unittest.TestCase): + @unittest.skipUnless(sys.platform == "darwin", 'OSX-specific test') + def test_find(self): + self.assertEqual(dyld_find('libSystem.dylib'), + '/usr/lib/libSystem.dylib') + self.assertEqual(dyld_find('System.framework/System'), + '/System/Library/Frameworks/System.framework/System') + + # On Mac OS 11, system dylibs are only present in the shared cache, + # so symlinks like libpthread.dylib -> libSystem.B.dylib will not + # be resolved by dyld_find + self.assertIn(find_lib('pthread'), + ('/usr/lib/libSystem.B.dylib', '/usr/lib/libpthread.dylib')) + + result = find_lib('z') + # Issue #21093: dyld default search path includes $HOME/lib and + # /usr/local/lib before /usr/lib, which caused test failures if + # a local copy of libz exists in one of them. Now ignore the head + # of the path. + self.assertRegex(result, r".*/lib/libz.*\.dylib") + + self.assertIn(find_lib('IOKit'), + ('/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit', + '/System/Library/Frameworks/IOKit.framework/IOKit')) + + @unittest.skipUnless(sys.platform == "darwin", 'OSX-specific test') + def test_info(self): + self.assertIsNone(dylib_info('completely/invalid')) + self.assertIsNone(dylib_info('completely/invalide_debug')) + self.assertEqual(dylib_info('P/Foo.dylib'), d('P', 'Foo.dylib', 'Foo')) + self.assertEqual(dylib_info('P/Foo_debug.dylib'), + d('P', 'Foo_debug.dylib', 'Foo', suffix='debug')) + self.assertEqual(dylib_info('P/Foo.A.dylib'), + d('P', 'Foo.A.dylib', 'Foo', 'A')) + self.assertEqual(dylib_info('P/Foo_debug.A.dylib'), + d('P', 'Foo_debug.A.dylib', 'Foo_debug', 'A')) + self.assertEqual(dylib_info('P/Foo.A_debug.dylib'), + d('P', 'Foo.A_debug.dylib', 'Foo', 'A', 'debug')) + + @unittest.skipUnless(sys.platform == "darwin", 'OSX-specific test') + def test_framework_info(self): + self.assertIsNone(framework_info('completely/invalid')) + self.assertIsNone(framework_info('completely/invalid/_debug')) + self.assertIsNone(framework_info('P/F.framework')) + self.assertIsNone(framework_info('P/F.framework/_debug')) + self.assertEqual(framework_info('P/F.framework/F'), + d('P', 'F.framework/F', 'F')) + self.assertEqual(framework_info('P/F.framework/F_debug'), + d('P', 'F.framework/F_debug', 'F', suffix='debug')) + self.assertIsNone(framework_info('P/F.framework/Versions')) + self.assertIsNone(framework_info('P/F.framework/Versions/A')) + self.assertEqual(framework_info('P/F.framework/Versions/A/F'), + d('P', 'F.framework/Versions/A/F', 'F', 'A')) + self.assertEqual(framework_info('P/F.framework/Versions/A/F_debug'), + d('P', 'F.framework/Versions/A/F_debug', 'F', 'A', 'debug')) + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/ctypes/test/test_memfunctions.py b/Lib/test/test_ctypes/test_memfunctions.py similarity index 98% rename from Lib/ctypes/test/test_memfunctions.py rename to Lib/test/test_ctypes/test_memfunctions.py index e784b9a7068..d5c97352117 100644 --- a/Lib/ctypes/test/test_memfunctions.py +++ b/Lib/test/test_ctypes/test_memfunctions.py @@ -2,7 +2,7 @@ import sys from test import support import unittest from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol class MemFunctionsTest(unittest.TestCase): @unittest.skip('test disabled') diff --git a/Lib/ctypes/test/test_numbers.py b/Lib/test/test_ctypes/test_numbers.py similarity index 100% rename from Lib/ctypes/test/test_numbers.py rename to Lib/test/test_ctypes/test_numbers.py diff --git a/Lib/ctypes/test/test_objects.py b/Lib/test/test_ctypes/test_objects.py similarity index 87% rename from Lib/ctypes/test/test_objects.py rename to Lib/test/test_ctypes/test_objects.py index 19e3dc1f2d7..44a3c61ad79 100644 --- a/Lib/ctypes/test/test_objects.py +++ b/Lib/test/test_ctypes/test_objects.py @@ -42,7 +42,7 @@ The'array' attribute of the 'x' object shares part of the memory buffer of 'x' ('_b_base_' is either None, or the root object owning the memory block): >>> print(x.array._b_base_) # doctest: +ELLIPSIS - + >>> >>> x.array[0] = b'spam spam spam' @@ -56,12 +56,12 @@ of 'x' ('_b_base_' is either None, or the root object owning the memory block): import unittest, doctest -import ctypes.test.test_objects +import test.test_ctypes.test_objects class TestCase(unittest.TestCase): def test(self): - failures, tests = doctest.testmod(ctypes.test.test_objects) + failures, tests = doctest.testmod(test.test_ctypes.test_objects) self.assertFalse(failures, 'doctests failed, see output above') if __name__ == '__main__': - doctest.testmod(ctypes.test.test_objects) + doctest.testmod(test.test_ctypes.test_objects) diff --git a/Lib/ctypes/test/test_parameters.py b/Lib/test/test_ctypes/test_parameters.py similarity index 80% rename from Lib/ctypes/test/test_parameters.py rename to Lib/test/test_ctypes/test_parameters.py index 38af7ac13d7..06cc95107b7 100644 --- a/Lib/ctypes/test/test_parameters.py +++ b/Lib/test/test_ctypes/test_parameters.py @@ -1,11 +1,10 @@ import unittest -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import test.support class SimpleTypesTestCase(unittest.TestCase): def setUp(self): - import ctypes try: from _ctypes import set_conversion_mode except ImportError: @@ -79,6 +78,29 @@ class SimpleTypesTestCase(unittest.TestCase): pa = c_wchar_p.from_param(c_wchar_p("123")) self.assertEqual(type(pa), c_wchar_p) + def test_c_char(self): + from ctypes import c_char + + with self.assertRaises(TypeError) as cm: + c_char.from_param(b"abc") + self.assertEqual(str(cm.exception), + "one character bytes, bytearray or integer expected") + + @need_symbol('c_wchar') + def test_c_wchar(self): + from ctypes import c_wchar + + with self.assertRaises(TypeError) as cm: + c_wchar.from_param("abc") + self.assertEqual(str(cm.exception), + "one character unicode string expected") + + + with self.assertRaises(TypeError) as cm: + c_wchar.from_param(123) + self.assertEqual(str(cm.exception), + "unicode string expected instead of int instance") + def test_int_pointers(self): from ctypes import c_short, c_uint, c_int, c_long, POINTER, pointer LPINT = POINTER(c_int) @@ -244,6 +266,58 @@ class SimpleTypesTestCase(unittest.TestCase): self.assertRegex(repr(c_wchar_p.from_param('hihi')), r"^$") self.assertRegex(repr(c_void_p.from_param(0x12)), r"^$") + @test.support.cpython_only + def test_from_param_result_refcount(self): + # Issue #99952 + import _ctypes_test + from ctypes import PyDLL, c_int, c_void_p, py_object, Structure + + class X(Structure): + """This struct size is <= sizeof(void*).""" + _fields_ = [("a", c_void_p)] + + def __del__(self): + trace.append(4) + + @classmethod + def from_param(cls, value): + trace.append(2) + return cls() + + PyList_Append = PyDLL(_ctypes_test.__file__)._testfunc_pylist_append + PyList_Append.restype = c_int + PyList_Append.argtypes = [py_object, py_object, X] + + trace = [] + trace.append(1) + PyList_Append(trace, 3, "dummy") + trace.append(5) + + self.assertEqual(trace, [1, 2, 3, 4, 5]) + + class Y(Structure): + """This struct size is > sizeof(void*).""" + _fields_ = [("a", c_void_p), ("b", c_void_p)] + + def __del__(self): + trace.append(4) + + @classmethod + def from_param(cls, value): + trace.append(2) + return cls() + + PyList_Append = PyDLL(_ctypes_test.__file__)._testfunc_pylist_append + PyList_Append.restype = c_int + PyList_Append.argtypes = [py_object, py_object, Y] + + trace = [] + trace.append(1) + PyList_Append(trace, 3, "dummy") + trace.append(5) + + self.assertEqual(trace, [1, 2, 3, 4, 5]) + ################################################################ if __name__ == '__main__': diff --git a/Lib/ctypes/test/test_pep3118.py b/Lib/test/test_ctypes/test_pep3118.py similarity index 98% rename from Lib/ctypes/test/test_pep3118.py rename to Lib/test/test_ctypes/test_pep3118.py index 81e8ca7638f..efffc80a66f 100644 --- a/Lib/ctypes/test/test_pep3118.py +++ b/Lib/test/test_ctypes/test_pep3118.py @@ -176,7 +176,9 @@ native_types = [ ## arrays and pointers (c_double * 4, " (2, 4): - c_py_ssize_t = c_size_t -else: - c_py_ssize_t = c_int class PythonAPITestCase(unittest.TestCase): @@ -21,7 +17,7 @@ class PythonAPITestCase(unittest.TestCase): PyBytes_FromStringAndSize = pythonapi.PyBytes_FromStringAndSize PyBytes_FromStringAndSize.restype = py_object - PyBytes_FromStringAndSize.argtypes = c_char_p, c_py_ssize_t + PyBytes_FromStringAndSize.argtypes = c_char_p, c_size_t self.assertEqual(PyBytes_FromStringAndSize(b"abcdefghi", 3), b"abc") diff --git a/Lib/ctypes/test/test_random_things.py b/Lib/test/test_ctypes/test_random_things.py similarity index 100% rename from Lib/ctypes/test/test_random_things.py rename to Lib/test/test_ctypes/test_random_things.py diff --git a/Lib/ctypes/test/test_refcounts.py b/Lib/test/test_ctypes/test_refcounts.py similarity index 82% rename from Lib/ctypes/test/test_refcounts.py rename to Lib/test/test_ctypes/test_refcounts.py index f2edfa6400e..48958cd2a60 100644 --- a/Lib/ctypes/test/test_refcounts.py +++ b/Lib/test/test_ctypes/test_refcounts.py @@ -97,5 +97,20 @@ class AnotherLeak(unittest.TestCase): f(1, 2) self.assertEqual(sys.getrefcount(ctypes.c_int), a) + @support.refcount_test + def test_callback_py_object_none_return(self): + # bpo-36880: test that returning None from a py_object callback + # does not decrement the refcount of None. + + for FUNCTYPE in (ctypes.CFUNCTYPE, ctypes.PYFUNCTYPE): + with self.subTest(FUNCTYPE=FUNCTYPE): + @FUNCTYPE(ctypes.py_object) + def func(): + return None + + # Check that calling func does not affect None's refcount. + for _ in range(10000): + func() + if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_repr.py b/Lib/test/test_ctypes/test_repr.py similarity index 100% rename from Lib/ctypes/test/test_repr.py rename to Lib/test/test_ctypes/test_repr.py diff --git a/Lib/ctypes/test/test_returnfuncptrs.py b/Lib/test/test_ctypes/test_returnfuncptrs.py similarity index 100% rename from Lib/ctypes/test/test_returnfuncptrs.py rename to Lib/test/test_ctypes/test_returnfuncptrs.py diff --git a/Lib/ctypes/test/test_simplesubclasses.py b/Lib/test/test_ctypes/test_simplesubclasses.py similarity index 100% rename from Lib/ctypes/test/test_simplesubclasses.py rename to Lib/test/test_ctypes/test_simplesubclasses.py diff --git a/Lib/ctypes/test/test_sizes.py b/Lib/test/test_ctypes/test_sizes.py similarity index 90% rename from Lib/ctypes/test/test_sizes.py rename to Lib/test/test_ctypes/test_sizes.py index 4ceacbc2900..bf8d6ea35aa 100644 --- a/Lib/ctypes/test/test_sizes.py +++ b/Lib/test/test_ctypes/test_sizes.py @@ -28,6 +28,9 @@ class SizesTestCase(unittest.TestCase): def test_ssize_t(self): self.assertEqual(sizeof(c_void_p), sizeof(c_ssize_t)) + def test_time_t(self): + self.assertEqual(sizeof(c_time_t), SIZEOF_TIME_T) + if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_slicing.py b/Lib/test/test_ctypes/test_slicing.py similarity index 99% rename from Lib/ctypes/test/test_slicing.py rename to Lib/test/test_ctypes/test_slicing.py index a3932f17672..b3e68f9a822 100644 --- a/Lib/ctypes/test/test_slicing.py +++ b/Lib/test/test_ctypes/test_slicing.py @@ -1,6 +1,6 @@ import unittest from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import _ctypes_test diff --git a/Lib/ctypes/test/test_stringptr.py b/Lib/test/test_ctypes/test_stringptr.py similarity index 100% rename from Lib/ctypes/test/test_stringptr.py rename to Lib/test/test_ctypes/test_stringptr.py diff --git a/Lib/ctypes/test/test_strings.py b/Lib/test/test_ctypes/test_strings.py similarity index 99% rename from Lib/ctypes/test/test_strings.py rename to Lib/test/test_ctypes/test_strings.py index 12e208828a7..a9003be3f50 100644 --- a/Lib/ctypes/test/test_strings.py +++ b/Lib/test/test_ctypes/test_strings.py @@ -1,6 +1,6 @@ import unittest from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol class StringArrayTestCase(unittest.TestCase): def test(self): diff --git a/Lib/ctypes/test/test_struct_fields.py b/Lib/test/test_ctypes/test_struct_fields.py similarity index 83% rename from Lib/ctypes/test/test_struct_fields.py rename to Lib/test/test_ctypes/test_struct_fields.py index ee8415f3e63..e444f5e1f77 100644 --- a/Lib/ctypes/test/test_struct_fields.py +++ b/Lib/test/test_ctypes/test_struct_fields.py @@ -54,6 +54,21 @@ class StructFieldsTestCase(unittest.TestCase): x.char = b'a\0b\0' self.assertEqual(bytes(x), b'a\x00###') + def test_6(self): + class X(Structure): + _fields_ = [("x", c_int)] + CField = type(X.x) + self.assertRaises(TypeError, CField) + + def test_gh99275(self): + class BrokenStructure(Structure): + def __init_subclass__(cls, **kwargs): + cls._fields_ = [] # This line will fail, `stgdict` is not ready + + with self.assertRaisesRegex(TypeError, + 'ctypes state is not initialized'): + class Subclass(BrokenStructure): ... + # __set__ and __get__ should raise a TypeError in case their self # argument is not a ctype instance. def test___set__(self): diff --git a/Lib/ctypes/test/test_structures.py b/Lib/test/test_ctypes/test_structures.py similarity index 99% rename from Lib/ctypes/test/test_structures.py rename to Lib/test/test_ctypes/test_structures.py index 97ad2b8ed8a..df39dc7f50d 100644 --- a/Lib/ctypes/test/test_structures.py +++ b/Lib/test/test_ctypes/test_structures.py @@ -2,7 +2,7 @@ import platform import sys import unittest from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol from struct import calcsize import _ctypes_test from test import support @@ -332,13 +332,13 @@ class StructureTestCase(unittest.TestCase): cls, msg = self.get_except(Person, b"Someone", (1, 2)) self.assertEqual(cls, RuntimeError) self.assertEqual(msg, - "(Phone) : " + "(Phone) TypeError: " "expected bytes, int found") cls, msg = self.get_except(Person, b"Someone", (b"a", b"b", b"c")) self.assertEqual(cls, RuntimeError) self.assertEqual(msg, - "(Phone) : too many initializers") + "(Phone) TypeError: too many initializers") def test_huge_field_name(self): # issue12881: segfault with large structure field names diff --git a/Lib/ctypes/test/test_unaligned_structures.py b/Lib/test/test_ctypes/test_unaligned_structures.py similarity index 100% rename from Lib/ctypes/test/test_unaligned_structures.py rename to Lib/test/test_ctypes/test_unaligned_structures.py diff --git a/Lib/ctypes/test/test_unicode.py b/Lib/test/test_ctypes/test_unicode.py similarity index 97% rename from Lib/ctypes/test/test_unicode.py rename to Lib/test/test_ctypes/test_unicode.py index 60c75424b76..319cb3b1dca 100644 --- a/Lib/ctypes/test/test_unicode.py +++ b/Lib/test/test_ctypes/test_unicode.py @@ -1,6 +1,6 @@ import unittest import ctypes -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import _ctypes_test diff --git a/Lib/ctypes/test/test_values.py b/Lib/test/test_ctypes/test_values.py similarity index 91% rename from Lib/ctypes/test/test_values.py rename to Lib/test/test_ctypes/test_values.py index 3e8b13768b4..435fdd22ea2 100644 --- a/Lib/ctypes/test/test_values.py +++ b/Lib/test/test_ctypes/test_values.py @@ -54,6 +54,7 @@ class PythonValuesTestCase(unittest.TestCase): _fields_ = [("name", c_char_p), ("code", POINTER(c_ubyte)), ("size", c_int), + ("is_package", c_int), ("get_code", POINTER(c_ubyte)), # Function ptr ] FrozenTable = POINTER(struct_frozen) @@ -71,13 +72,14 @@ class PythonValuesTestCase(unittest.TestCase): modname = entry.name.decode("ascii") modules.append(modname) with self.subTest(modname): - # Do a sanity check on entry.size and entry.code. - self.assertGreater(abs(entry.size), 10) - self.assertTrue([entry.code[i] for i in range(abs(entry.size))]) + if entry.size != 0: + # Do a sanity check on entry.size and entry.code. + self.assertGreater(abs(entry.size), 10) + self.assertTrue([entry.code[i] for i in range(abs(entry.size))]) # Check the module's package-ness. with import_helper.frozen_modules(): spec = importlib.util.find_spec(modname) - if entry.size < 0: + if entry.is_package: # It's a package. self.assertIsNotNone(spec.submodule_search_locations) else: diff --git a/Lib/ctypes/test/test_varsize_struct.py b/Lib/test/test_ctypes/test_varsize_struct.py similarity index 100% rename from Lib/ctypes/test/test_varsize_struct.py rename to Lib/test/test_ctypes/test_varsize_struct.py diff --git a/Lib/ctypes/test/test_win32.py b/Lib/test/test_ctypes/test_win32.py similarity index 100% rename from Lib/ctypes/test/test_win32.py rename to Lib/test/test_ctypes/test_win32.py diff --git a/Lib/ctypes/test/test_wintypes.py b/Lib/test/test_ctypes/test_wintypes.py similarity index 67% rename from Lib/ctypes/test/test_wintypes.py rename to Lib/test/test_ctypes/test_wintypes.py index 243d5962ffa..a01b9b1d0f3 100644 --- a/Lib/ctypes/test/test_wintypes.py +++ b/Lib/test/test_ctypes/test_wintypes.py @@ -1,3 +1,6 @@ +# See +# for reference. + import unittest # also work on POSIX @@ -38,6 +41,22 @@ class WinTypesTest(unittest.TestCase): vb.value = [] self.assertIs(vb.value, False) + def assertIsSigned(self, ctype): + self.assertLess(ctype(-1).value, 0) + + def assertIsUnsigned(self, ctype): + self.assertGreater(ctype(-1).value, 0) + + def test_signedness(self): + for ctype in (wintypes.BYTE, wintypes.WORD, wintypes.DWORD, + wintypes.BOOLEAN, wintypes.UINT, wintypes.ULONG): + with self.subTest(ctype=ctype): + self.assertIsUnsigned(ctype) + + for ctype in (wintypes.BOOL, wintypes.INT, wintypes.LONG): + with self.subTest(ctype=ctype): + self.assertIsSigned(ctype) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index d3c152c42cf..b550f4af555 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -268,7 +268,12 @@ class TestCurses(unittest.TestCase): stdscr.echochar(b'A') stdscr.echochar(65) with self.assertRaises((UnicodeEncodeError, OverflowError)): - stdscr.echochar('\u20ac') + # Unicode is not fully supported yet, but at least it does + # not crash. + # It is supposed to fail because either the character is + # not encodable with the current encoding, or it is encoded to + # a multibyte sequence. + stdscr.echochar('\u0114') stdscr.echochar('A', curses.A_BOLD) self.assertIs(stdscr.is_wintouched(), False) diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index b00d0484d38..81a36aa241a 100644 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -8,11 +8,13 @@ import abc import pickle import inspect import builtins +import types +import weakref import unittest from unittest.mock import Mock -from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional, Protocol +from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional, Protocol, DefaultDict from typing import get_type_hints -from collections import deque, OrderedDict, namedtuple +from collections import deque, OrderedDict, namedtuple, defaultdict from functools import total_ordering import typing # Needed for the string "typing.ClassVar[int]" to work as an annotation. @@ -66,6 +68,50 @@ class TestCase(unittest.TestCase): self.assertEqual(repr_output, expected_output) + def test_field_recursive_repr(self): + rec_field = field() + rec_field.type = rec_field + rec_field.name = "id" + repr_output = repr(rec_field) + + self.assertIn(",type=...,", repr_output) + + def test_recursive_annotation(self): + class C: + pass + + @dataclass + class D: + C: C = field() + + self.assertIn(",type=...,", repr(D.__dataclass_fields__["C"])) + + def test_dataclass_params_repr(self): + # Even though this is testing an internal implementation detail, + # it's testing a feature we want to make sure is correctly implemented + # for the sake of dataclasses itself + @dataclass(slots=True, frozen=True) + class Some: pass + + repr_output = repr(Some.__dataclass_params__) + expected_output = "_DataclassParams(init=True,repr=True," \ + "eq=True,order=False,unsafe_hash=False,frozen=True," \ + "match_args=True,kw_only=False," \ + "slots=True,weakref_slot=False)" + self.assertEqual(repr_output, expected_output) + + def test_dataclass_params_signature(self): + # Even though this is testing an internal implementation detail, + # it's testing a feature we want to make sure is correctly implemented + # for the sake of dataclasses itself + @dataclass + class Some: pass + + for param in inspect.signature(dataclass).parameters: + if param == 'cls': + continue + self.assertTrue(hasattr(Some.__dataclass_params__, param), msg=param) + def test_named_init_params(self): @dataclass class C: @@ -229,6 +275,14 @@ class TestCase(unittest.TestCase): c = C('foo') self.assertEqual(c.object, 'foo') + def test_field_named_BUILTINS_frozen(self): + # gh-96151 + @dataclass(frozen=True) + class C: + BUILTINS: int + c = C(5) + self.assertEqual(c.BUILTINS, 5) + def test_field_named_like_builtin(self): # Attribute names can shadow built-in names # since code generation is used. @@ -500,6 +554,32 @@ class TestCase(unittest.TestCase): self.assertNotEqual(C(3), C(4, 10)) self.assertNotEqual(C(3, 10), C(4, 10)) + def test_no_unhashable_default(self): + # See bpo-44674. + class Unhashable: + __hash__ = None + + unhashable_re = 'mutable default .* for field a is not allowed' + with self.assertRaisesRegex(ValueError, unhashable_re): + @dataclass + class A: + a: dict = {} + + with self.assertRaisesRegex(ValueError, unhashable_re): + @dataclass + class A: + a: Any = Unhashable() + + # Make sure that the machinery looking for hashability is using the + # class's __hash__, not the instance's __hash__. + with self.assertRaisesRegex(ValueError, unhashable_re): + unhashable = Unhashable() + # This shouldn't make the variable hashable. + unhashable.__hash__ = lambda: 0 + @dataclass + class A: + a: Any = unhashable + def test_hash_field_rules(self): # Test all 6 cases of: # hash=True/False/None @@ -989,6 +1069,65 @@ class TestCase(unittest.TestCase): self.assertEqual((c.x, c.y), (3, 4)) self.assertTrue(C.flag) + def test_post_init_not_auto_added(self): + # See bpo-46757, which had proposed always adding __post_init__. As + # Raymond Hettinger pointed out, that would be a breaking change. So, + # add a test to make sure that the current behavior doesn't change. + + @dataclass + class A0: + pass + + @dataclass + class B0: + b_called: bool = False + def __post_init__(self): + self.b_called = True + + @dataclass + class C0(A0, B0): + c_called: bool = False + def __post_init__(self): + super().__post_init__() + self.c_called = True + + # Since A0 has no __post_init__, and one wasn't automatically added + # (because that's the rule: it's never added by @dataclass, it's only + # the class author that can add it), then B0.__post_init__ is called. + # Verify that. + c = C0() + self.assertTrue(c.b_called) + self.assertTrue(c.c_called) + + ###################################### + # Now, the same thing, except A1 defines __post_init__. + @dataclass + class A1: + def __post_init__(self): + pass + + @dataclass + class B1: + b_called: bool = False + def __post_init__(self): + self.b_called = True + + @dataclass + class C1(A1, B1): + c_called: bool = False + def __post_init__(self): + super().__post_init__() + self.c_called = True + + # This time, B1.__post_init__ isn't being called. This mimics what + # would happen if A1.__post_init__ had been automatically added, + # instead of manually added as we see here. This test isn't really + # needed, but I'm including it just to demonstrate the changed + # behavior when A1 does define __post_init__. + c = C1() + self.assertFalse(c.b_called) + self.assertTrue(c.c_called) + def test_class_var(self): # Make sure ClassVars are ignored in __init__, __repr__, etc. @dataclass @@ -1126,6 +1265,10 @@ class TestCase(unittest.TestCase): self.assertEqual(repr(InitVar[int]), 'dataclasses.InitVar[int]') self.assertEqual(repr(InitVar[List[int]]), 'dataclasses.InitVar[typing.List[int]]') + self.assertEqual(repr(InitVar[list[int]]), + 'dataclasses.InitVar[list[int]]') + self.assertEqual(repr(InitVar[int|str]), + 'dataclasses.InitVar[int | str]') def test_init_var_inheritance(self): # Note that this deliberately tests that a dataclass need not @@ -1350,6 +1493,17 @@ class TestCase(unittest.TestCase): with self.assertRaisesRegex(TypeError, 'should be called on dataclass instances'): replace(obj, x=0) + def test_is_dataclass_genericalias(self): + @dataclass + class A(types.GenericAlias): + origin: type + args: type + self.assertTrue(is_dataclass(A)) + a = A(list, int) + self.assertTrue(is_dataclass(type(a))) + self.assertTrue(is_dataclass(a)) + + def test_helper_fields_with_class_instance(self): # Check that we can call fields() on either a class or instance, # and get back the same thing. @@ -1549,6 +1703,23 @@ class TestCase(unittest.TestCase): self.assertIsNot(d['f'], t) self.assertEqual(d['f'].my_a(), 6) + def test_helper_asdict_defaultdict(self): + # Ensure asdict() does not throw exceptions when a + # defaultdict is a member of a dataclass + + @dataclass + class C: + mp: DefaultDict[str, List] + + + dd = defaultdict(list) + dd["x"].append(12) + c = C(mp=dd) + d = asdict(c) + + assert d == {"mp": {"x": [12]}} + assert d["mp"] is not c.mp # make sure defaultdict is copied + def test_helper_astuple(self): # Basic tests for astuple(), it should return a new tuple. @dataclass @@ -2113,12 +2284,12 @@ class TestInit(unittest.TestCase): self.assertEqual(c.z, 100) def test_no_init(self): - dataclass(init=False) + @dataclass(init=False) class C: i: int = 0 self.assertEqual(C().i, 0) - dataclass(init=False) + @dataclass(init=False) class C: i: int = 2 def __init__(self): @@ -2825,23 +2996,58 @@ class TestSlots(unittest.TestCase): x: int def test_generated_slots_value(self): - @dataclass(slots=True) - class Base: - x: int - self.assertEqual(Base.__slots__, ('x',)) + class Root: + __slots__ = {'x'} + + class Root2(Root): + __slots__ = {'k': '...', 'j': ''} + + class Root3(Root2): + __slots__ = ['h'] + + class Root4(Root3): + __slots__ = 'aa' @dataclass(slots=True) - class Delivered(Base): + class Base(Root4): y: int + j: str + h: str - self.assertEqual(Delivered.__slots__, ('x', 'y')) + self.assertEqual(Base.__slots__, ('y', )) + + @dataclass(slots=True) + class Derived(Base): + aa: float + x: str + z: int + k: str + h: str + + self.assertEqual(Derived.__slots__, ('z', )) @dataclass - class AnotherDelivered(Base): + class AnotherDerived(Base): z: int - self.assertTrue('__slots__' not in AnotherDelivered.__dict__) + self.assertNotIn('__slots__', AnotherDerived.__dict__) + + def test_cant_inherit_from_iterator_slots(self): + + class Root: + __slots__ = iter(['a']) + + class Root2(Root): + __slots__ = ('b', ) + + with self.assertRaisesRegex( + TypeError, + "^Slots of 'Root' cannot be determined" + ): + @dataclass(slots=True) + class C(Root2): + x: int def test_returns_new_class(self): class A: @@ -2880,6 +3086,147 @@ class TestSlots(unittest.TestCase): self.assertIsNot(obj, p) self.assertEqual(obj, p) + def test_slots_with_default_no_init(self): + # Originally reported in bpo-44649. + @dataclass(slots=True) + class A: + a: str + b: str = field(default='b', init=False) + + obj = A("a") + self.assertEqual(obj.a, 'a') + self.assertEqual(obj.b, 'b') + + def test_slots_with_default_factory_no_init(self): + # Originally reported in bpo-44649. + @dataclass(slots=True) + class A: + a: str + b: str = field(default_factory=lambda:'b', init=False) + + obj = A("a") + self.assertEqual(obj.a, 'a') + self.assertEqual(obj.b, 'b') + + def test_slots_no_weakref(self): + @dataclass(slots=True) + class A: + # No weakref. + pass + + self.assertNotIn("__weakref__", A.__slots__) + a = A() + with self.assertRaisesRegex(TypeError, + "cannot create weak reference"): + weakref.ref(a) + + def test_slots_weakref(self): + @dataclass(slots=True, weakref_slot=True) + class A: + a: int + + self.assertIn("__weakref__", A.__slots__) + a = A(1) + weakref.ref(a) + + def test_slots_weakref_base_str(self): + class Base: + __slots__ = '__weakref__' + + @dataclass(slots=True) + class A(Base): + a: int + + # __weakref__ is in the base class, not A. But an A is still weakref-able. + self.assertIn("__weakref__", Base.__slots__) + self.assertNotIn("__weakref__", A.__slots__) + a = A(1) + weakref.ref(a) + + def test_slots_weakref_base_tuple(self): + # Same as test_slots_weakref_base, but use a tuple instead of a string + # in the base class. + class Base: + __slots__ = ('__weakref__',) + + @dataclass(slots=True) + class A(Base): + a: int + + # __weakref__ is in the base class, not A. But an A is still + # weakref-able. + self.assertIn("__weakref__", Base.__slots__) + self.assertNotIn("__weakref__", A.__slots__) + a = A(1) + weakref.ref(a) + + def test_weakref_slot_without_slot(self): + with self.assertRaisesRegex(TypeError, + "weakref_slot is True but slots is False"): + @dataclass(weakref_slot=True) + class A: + a: int + + def test_weakref_slot_make_dataclass(self): + A = make_dataclass('A', [('a', int),], slots=True, weakref_slot=True) + self.assertIn("__weakref__", A.__slots__) + a = A(1) + weakref.ref(a) + + # And make sure if raises if slots=True is not given. + with self.assertRaisesRegex(TypeError, + "weakref_slot is True but slots is False"): + B = make_dataclass('B', [('a', int),], weakref_slot=True) + + def test_weakref_slot_subclass_weakref_slot(self): + @dataclass(slots=True, weakref_slot=True) + class Base: + field: int + + # A *can* also specify weakref_slot=True if it wants to (gh-93521) + @dataclass(slots=True, weakref_slot=True) + class A(Base): + ... + + # __weakref__ is in the base class, not A. But an instance of A + # is still weakref-able. + self.assertIn("__weakref__", Base.__slots__) + self.assertNotIn("__weakref__", A.__slots__) + a = A(1) + weakref.ref(a) + + def test_weakref_slot_subclass_no_weakref_slot(self): + @dataclass(slots=True, weakref_slot=True) + class Base: + field: int + + @dataclass(slots=True) + class A(Base): + ... + + # __weakref__ is in the base class, not A. Even though A doesn't + # specify weakref_slot, it should still be weakref-able. + self.assertIn("__weakref__", Base.__slots__) + self.assertNotIn("__weakref__", A.__slots__) + a = A(1) + weakref.ref(a) + + def test_weakref_slot_normal_base_weakref_slot(self): + class Base: + __slots__ = ('__weakref__',) + + @dataclass(slots=True, weakref_slot=True) + class A(Base): + field: int + + # __weakref__ is in the base class, not A. But an instance of + # A is still weakref-able. + self.assertIn("__weakref__", Base.__slots__) + self.assertNotIn("__weakref__", A.__slots__) + a = A(1) + weakref.ref(a) + + class TestDescriptors(unittest.TestCase): def test_set_name(self): # See bpo-33141. @@ -2951,6 +3298,115 @@ class TestDescriptors(unittest.TestCase): self.assertEqual(D.__set_name__.call_count, 1) + def test_init_calls_set(self): + class D: + pass + + D.__set__ = Mock() + + @dataclass + class C: + i: D = D() + + # Make sure D.__set__ is called. + D.__set__.reset_mock() + c = C(5) + self.assertEqual(D.__set__.call_count, 1) + + def test_getting_field_calls_get(self): + class D: + pass + + D.__set__ = Mock() + D.__get__ = Mock() + + @dataclass + class C: + i: D = D() + + c = C(5) + + # Make sure D.__get__ is called. + D.__get__.reset_mock() + value = c.i + self.assertEqual(D.__get__.call_count, 1) + + def test_setting_field_calls_set(self): + class D: + pass + + D.__set__ = Mock() + + @dataclass + class C: + i: D = D() + + c = C(5) + + # Make sure D.__set__ is called. + D.__set__.reset_mock() + c.i = 10 + self.assertEqual(D.__set__.call_count, 1) + + def test_setting_uninitialized_descriptor_field(self): + class D: + pass + + D.__set__ = Mock() + + @dataclass + class C: + i: D + + # D.__set__ is not called because there's no D instance to call it on + D.__set__.reset_mock() + c = C(5) + self.assertEqual(D.__set__.call_count, 0) + + # D.__set__ still isn't called after setting i to an instance of D + # because descriptors don't behave like that when stored as instance vars + c.i = D() + c.i = 5 + self.assertEqual(D.__set__.call_count, 0) + + def test_default_value(self): + class D: + def __get__(self, instance: Any, owner: object) -> int: + if instance is None: + return 100 + + return instance._x + + def __set__(self, instance: Any, value: int) -> None: + instance._x = value + + @dataclass + class C: + i: D = D() + + c = C() + self.assertEqual(c.i, 100) + + c = C(5) + self.assertEqual(c.i, 5) + + def test_no_default_value(self): + class D: + def __get__(self, instance: Any, owner: object) -> int: + if instance is None: + raise AttributeError() + + return instance._x + + def __set__(self, instance: Any, value: int) -> None: + instance._x = value + + @dataclass + class C: + i: D = D() + + with self.assertRaisesRegex(TypeError, 'missing 1 required positional argument'): + c = C() class TestStringAnnotations(unittest.TestCase): def test_classvar(self): @@ -3532,7 +3988,7 @@ class TestAbstract(unittest.TestCase): day: 'int' self.assertTrue(inspect.isabstract(Date)) - msg = 'class Date with abstract method foo' + msg = "class Date without an implementation for abstract method 'foo'" self.assertRaisesRegex(TypeError, msg, Date) diff --git a/Lib/test/test_dbm_dumb.py b/Lib/test/test_dbm_dumb.py index 73cff638f1e..a481175b3bf 100644 --- a/Lib/test/test_dbm_dumb.py +++ b/Lib/test/test_dbm_dumb.py @@ -42,6 +42,7 @@ class DumbDBMTestCase(unittest.TestCase): self.read_helper(f) @unittest.skipUnless(hasattr(os, 'umask'), 'test needs os.umask()') + @os_helper.skip_unless_working_chmod def test_dumbdbm_creation_mode(self): try: old_umask = os.umask(0o002) @@ -265,6 +266,7 @@ class DumbDBMTestCase(unittest.TestCase): "'r', 'w', 'c', or 'n'"): dumbdbm.open(_fname, flag) + @os_helper.skip_unless_working_chmod def test_readonly_files(self): with os_helper.temp_dir() as dir: fname = os.path.join(dir, 'db') diff --git a/Lib/test/test_dbm_gnu.py b/Lib/test/test_dbm_gnu.py index 4eaa0f474b0..73602cab518 100644 --- a/Lib/test/test_dbm_gnu.py +++ b/Lib/test/test_dbm_gnu.py @@ -118,6 +118,20 @@ class TestGdbm(unittest.TestCase): self.assertEqual(str(cm.exception), "GDBM object has already been closed") + def test_bool_empty(self): + with gdbm.open(filename, 'c') as db: + self.assertFalse(bool(db)) + + def test_bool_not_empty(self): + with gdbm.open(filename, 'c') as db: + db['a'] = 'b' + self.assertTrue(bool(db)) + + def test_bool_on_closed_db_raises(self): + with gdbm.open(filename, 'c') as db: + db['a'] = 'b' + self.assertRaises(gdbm.error, bool, db) + def test_bytes(self): with gdbm.open(filename, 'c') as db: db[b'bytes key \xbd'] = b'bytes value \xbd' diff --git a/Lib/test/test_dbm_ndbm.py b/Lib/test/test_dbm_ndbm.py index e57d9cab115..8f37e3cc624 100644 --- a/Lib/test/test_dbm_ndbm.py +++ b/Lib/test/test_dbm_ndbm.py @@ -133,6 +133,20 @@ class DbmTestCase(unittest.TestCase): def test_open_with_pathlib_bytes_path(self): dbm.ndbm.open(os_helper.FakePath(os.fsencode(self.filename)), "c").close() + def test_bool_empty(self): + with dbm.ndbm.open(self.filename, 'c') as db: + self.assertFalse(bool(db)) + + def test_bool_not_empty(self): + with dbm.ndbm.open(self.filename, 'c') as db: + db['a'] = 'b' + self.assertTrue(bool(db)) + + def test_bool_on_closed_db_raises(self): + with dbm.ndbm.open(self.filename, 'c') as db: + db['a'] = 'b' + self.assertRaises(dbm.ndbm.error, bool, db) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index b6173a5ffec..67ccaab40c5 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -34,26 +34,16 @@ import numbers import locale from test.support import (run_unittest, run_doctest, is_resource_enabled, requires_IEEE_754, requires_docstrings, - requires_legacy_unicode_capi) + requires_legacy_unicode_capi, check_sanitizer) from test.support import (TestFailed, run_with_locale, cpython_only, - darwin_malloc_err_warning) + darwin_malloc_err_warning, is_emscripten) from test.support.import_helper import import_fresh_module +from test.support import threading_helper from test.support import warnings_helper import random import inspect import threading -import sysconfig -_cflags = sysconfig.get_config_var('CFLAGS') or '' -_config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' -MEMORY_SANITIZER = ( - '-fsanitize=memory' in _cflags or - '--with-memory-sanitizer' in _config_args -) - -ADDRESS_SANITIZER = ( - '-fsanitize=address' in _cflags -) if sys.platform == 'darwin': @@ -1082,6 +1072,57 @@ class FormatTest(unittest.TestCase): (',e', '123456', '1.23456e+5'), (',E', '123456', '1.23456E+5'), + # negative zero: default behavior + ('.1f', '-0', '-0.0'), + ('.1f', '-.0', '-0.0'), + ('.1f', '-.01', '-0.0'), + + # negative zero: z option + ('z.1f', '0.', '0.0'), + ('z6.1f', '0.', ' 0.0'), + ('z6.1f', '-1.', ' -1.0'), + ('z.1f', '-0.', '0.0'), + ('z.1f', '.01', '0.0'), + ('z.1f', '-.01', '0.0'), + ('z.2f', '0.', '0.00'), + ('z.2f', '-0.', '0.00'), + ('z.2f', '.001', '0.00'), + ('z.2f', '-.001', '0.00'), + + ('z.1e', '0.', '0.0e+1'), + ('z.1e', '-0.', '0.0e+1'), + ('z.1E', '0.', '0.0E+1'), + ('z.1E', '-0.', '0.0E+1'), + + ('z.2e', '-0.001', '-1.00e-3'), # tests for mishandled rounding + ('z.2g', '-0.001', '-0.001'), + ('z.2%', '-0.001', '-0.10%'), + + ('zf', '-0.0000', '0.0000'), # non-normalized form is preserved + + ('z.1f', '-00000.000001', '0.0'), + ('z.1f', '-00000.', '0.0'), + ('z.1f', '-.0000000000', '0.0'), + + ('z.2f', '-00000.000001', '0.00'), + ('z.2f', '-00000.', '0.00'), + ('z.2f', '-.0000000000', '0.00'), + + ('z.1f', '.09', '0.1'), + ('z.1f', '-.09', '-0.1'), + + (' z.0f', '-0.', ' 0'), + ('+z.0f', '-0.', '+0'), + ('-z.0f', '-0.', '0'), + (' z.0f', '-1.', '-1'), + ('+z.0f', '-1.', '-1'), + ('-z.0f', '-1.', '-1'), + + ('z>6.1f', '-0.', 'zz-0.0'), + ('z>z6.1f', '-0.', 'zzz0.0'), + ('x>z6.1f', '-0.', 'xxx0.0'), + ('🖤>z6.1f', '-0.', '🖤🖤🖤0.0'), # multi-byte fill char + # issue 6850 ('a=-7.0', '0.12345', 'aaaa0.1'), @@ -1096,6 +1137,15 @@ class FormatTest(unittest.TestCase): # bytes format argument self.assertRaises(TypeError, Decimal(1).__format__, b'-020') + def test_negative_zero_format_directed_rounding(self): + with self.decimal.localcontext() as ctx: + ctx.rounding = ROUND_CEILING + self.assertEqual(format(self.decimal.Decimal('-0.001'), 'z.2f'), + '0.00') + + def test_negative_zero_bad_format(self): + self.assertRaises(ValueError, format, self.decimal.Decimal('1.23'), 'fz') + def test_n_format(self): Decimal = self.decimal.Decimal @@ -1602,6 +1652,8 @@ def thfunc2(cls): for sig in Overflow, Underflow, DivisionByZero, InvalidOperation: cls.assertFalse(thiscontext.flags[sig]) + +@threading_helper.requires_working_threading() class ThreadingTest(unittest.TestCase): '''Unit tests for thread local contexts in Decimal.''' @@ -2474,6 +2526,15 @@ class CUsabilityTest(UsabilityTest): class PyUsabilityTest(UsabilityTest): decimal = P + def setUp(self): + super().setUp() + self._previous_int_limit = sys.get_int_max_str_digits() + sys.set_int_max_str_digits(7000) + + def tearDown(self): + sys.set_int_max_str_digits(self._previous_int_limit) + super().tearDown() + class PythonAPItests(unittest.TestCase): def test_abc(self): @@ -2552,6 +2613,13 @@ class PythonAPItests(unittest.TestCase): self.assertRaises(OverflowError, int, Decimal('inf')) self.assertRaises(OverflowError, int, Decimal('-inf')) + @cpython_only + def test_small_ints(self): + Decimal = self.decimal.Decimal + # bpo-46361 + for x in range(-5, 257): + self.assertIs(int(Decimal(x)), x) + def test_trunc(self): Decimal = self.decimal.Decimal @@ -3606,6 +3674,40 @@ class ContextWithStatement(unittest.TestCase): self.assertIsNot(new_ctx, set_ctx, 'did not copy the context') self.assertIs(set_ctx, enter_ctx, '__enter__ returned wrong context') + def test_localcontext_kwargs(self): + with self.decimal.localcontext( + prec=10, rounding=ROUND_HALF_DOWN, + Emin=-20, Emax=20, capitals=0, + clamp=1 + ) as ctx: + self.assertEqual(ctx.prec, 10) + self.assertEqual(ctx.rounding, self.decimal.ROUND_HALF_DOWN) + self.assertEqual(ctx.Emin, -20) + self.assertEqual(ctx.Emax, 20) + self.assertEqual(ctx.capitals, 0) + self.assertEqual(ctx.clamp, 1) + + self.assertRaises(TypeError, self.decimal.localcontext, precision=10) + + self.assertRaises(ValueError, self.decimal.localcontext, Emin=1) + self.assertRaises(ValueError, self.decimal.localcontext, Emax=-1) + self.assertRaises(ValueError, self.decimal.localcontext, capitals=2) + self.assertRaises(ValueError, self.decimal.localcontext, clamp=2) + + self.assertRaises(TypeError, self.decimal.localcontext, rounding="") + self.assertRaises(TypeError, self.decimal.localcontext, rounding=1) + + self.assertRaises(TypeError, self.decimal.localcontext, flags="") + self.assertRaises(TypeError, self.decimal.localcontext, traps="") + self.assertRaises(TypeError, self.decimal.localcontext, Emin="") + self.assertRaises(TypeError, self.decimal.localcontext, Emax="") + + def test_local_context_kwargs_does_not_overwrite_existing_argument(self): + ctx = self.decimal.getcontext() + ctx.prec = 28 + with self.decimal.localcontext(prec=10) as ctx2: + self.assertEqual(ctx.prec, 28) + def test_nested_with_statements(self): # Use a copy of the supplied context in the block Decimal = self.decimal.Decimal @@ -4533,6 +4635,15 @@ class CCoverage(Coverage): class PyCoverage(Coverage): decimal = P + def setUp(self): + super().setUp() + self._previous_int_limit = sys.get_int_max_str_digits() + sys.set_int_max_str_digits(7000) + + def tearDown(self): + sys.set_int_max_str_digits(self._previous_int_limit) + super().tearDown() + class PyFunctionality(unittest.TestCase): """Extra functionality in decimal.py""" @@ -5427,6 +5538,7 @@ class CWhitebox(unittest.TestCase): with localcontext() as c: + c.prec = 9 c.traps[InvalidOperation] = True c.traps[Overflow] = True c.traps[Underflow] = True @@ -5511,7 +5623,9 @@ class CWhitebox(unittest.TestCase): # Issue 41540: @unittest.skipIf(sys.platform.startswith("aix"), "AIX: default ulimit: test is flaky because of extreme over-allocation") - @unittest.skipIf(MEMORY_SANITIZER or ADDRESS_SANITIZER, "sanitizer defaults to crashing " + @unittest.skipIf(is_emscripten, "Test is unstable on Emscripten") + @unittest.skipIf(check_sanitizer(address=True, memory=True), + "ASAN/MSAN sanitizer defaults to crashing " "instead of returning NULL for malloc failure.") def test_maxcontext_exact_arith(self): diff --git a/Lib/test/test_decorators.py b/Lib/test/test_decorators.py index 57a741ffd29..4b492178c15 100644 --- a/Lib/test/test_decorators.py +++ b/Lib/test/test_decorators.py @@ -1,4 +1,3 @@ -from test import support import unittest from types import MethodType @@ -330,6 +329,16 @@ class TestDecorators(unittest.TestCase): self.assertEqual(Class().inner(), 'spam') self.assertEqual(Class().outer(), 'eggs') + def test_bound_function_inside_classmethod(self): + class A: + def foo(self, cls): + return 'spam' + + class B: + bar = classmethod(A().foo) + + self.assertEqual(B.bar(), 'spam') + def test_wrapped_classmethod_inside_classmethod(self): class MyClassMethod1: def __init__(self, func): diff --git a/Lib/test/test_defaultdict.py b/Lib/test/test_defaultdict.py index 68fc449780a..bdbe9b81e8f 100644 --- a/Lib/test/test_defaultdict.py +++ b/Lib/test/test_defaultdict.py @@ -1,9 +1,7 @@ """Unit tests for collections.defaultdict.""" -import os import copy import pickle -import tempfile import unittest from collections import defaultdict diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py index 0be3feca010..ae1dfacd726 100644 --- a/Lib/test/test_deque.py +++ b/Lib/test/test_deque.py @@ -781,6 +781,9 @@ class TestVariousIteratorArgs(unittest.TestCase): class Deque(deque): pass +class DequeWithSlots(deque): + __slots__ = ('x', 'y', '__dict__') + class DequeWithBadIter(deque): def __iter__(self): raise TypeError @@ -810,40 +813,28 @@ class TestSubclass(unittest.TestCase): self.assertEqual(len(d), 0) def test_copy_pickle(self): + for cls in Deque, DequeWithSlots: + for d in cls('abc'), cls('abcde', maxlen=4): + d.x = ['x'] + d.z = ['z'] - d = Deque('abc') + e = d.__copy__() + self.assertEqual(type(d), type(e)) + self.assertEqual(list(d), list(e)) - e = d.__copy__() - self.assertEqual(type(d), type(e)) - self.assertEqual(list(d), list(e)) + e = cls(d) + self.assertEqual(type(d), type(e)) + self.assertEqual(list(d), list(e)) - e = Deque(d) - self.assertEqual(type(d), type(e)) - self.assertEqual(list(d), list(e)) - - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - s = pickle.dumps(d, proto) - e = pickle.loads(s) - self.assertNotEqual(id(d), id(e)) - self.assertEqual(type(d), type(e)) - self.assertEqual(list(d), list(e)) - - d = Deque('abcde', maxlen=4) - - e = d.__copy__() - self.assertEqual(type(d), type(e)) - self.assertEqual(list(d), list(e)) - - e = Deque(d) - self.assertEqual(type(d), type(e)) - self.assertEqual(list(d), list(e)) - - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - s = pickle.dumps(d, proto) - e = pickle.loads(s) - self.assertNotEqual(id(d), id(e)) - self.assertEqual(type(d), type(e)) - self.assertEqual(list(d), list(e)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + s = pickle.dumps(d, proto) + e = pickle.loads(s) + self.assertNotEqual(id(d), id(e)) + self.assertEqual(type(d), type(e)) + self.assertEqual(list(d), list(e)) + self.assertEqual(e.x, d.x) + self.assertEqual(e.z, d.z) + self.assertFalse(hasattr(e, 'y')) def test_pickle_recursive(self): for proto in range(pickle.HIGHEST_PROTOCOL + 1): diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index a4131bec602..cbc020d1d39 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -13,6 +13,7 @@ import warnings import weakref from copy import deepcopy +from contextlib import redirect_stdout from test import support try: @@ -20,6 +21,11 @@ try: except ImportError: _testcapi = None +try: + import xxsubtype +except ImportError: + xxsubtype = None + class OperatorsTest(unittest.TestCase): @@ -298,6 +304,7 @@ class OperatorsTest(unittest.TestCase): self.assertEqual(float.__rsub__(3.0, 1), -2.0) @support.impl_detail("the module 'xxsubtype' is internal") + @unittest.skipIf(xxsubtype is None, "requires xxsubtype module") def test_spam_lists(self): # Testing spamlist operations... import copy, xxsubtype as spam @@ -342,6 +349,7 @@ class OperatorsTest(unittest.TestCase): self.assertEqual(a.getstate(), 42) @support.impl_detail("the module 'xxsubtype' is internal") + @unittest.skipIf(xxsubtype is None, "requires xxsubtype module") def test_spam_dicts(self): # Testing spamdict operations... import copy, xxsubtype as spam @@ -425,7 +433,7 @@ class ClassPropertiesAndMethods(unittest.TestCase): def __getitem__(self, key): return self.get(key, 0) def __setitem__(self_local, key, value): - self.assertIsInstance(key, type(0)) + self.assertIsInstance(key, int) dict.__setitem__(self_local, key, value) def setstate(self, state): self.state = state @@ -837,7 +845,7 @@ class ClassPropertiesAndMethods(unittest.TestCase): ("getattr", "foo"), ("delattr", "foo")]) - # http://python.org/sf/1174712 + # https://bugs.python.org/issue1174712 try: class Module(types.ModuleType, str): pass @@ -870,7 +878,7 @@ class ClassPropertiesAndMethods(unittest.TestCase): self.assertEqual(a.getstate(), 10) class D(dict, C): def __init__(self): - type({}).__init__(self) + dict.__init__(self) C.__init__(self) d = D() self.assertEqual(list(d.keys()), []) @@ -1309,6 +1317,15 @@ order (MRO) for bases """ with self.assertRaisesRegex(AttributeError, "'X' object has no attribute 'a'"): X().a + # Test string subclass in `__slots__`, see gh-98783 + class SubStr(str): + pass + class X(object): + __slots__ = (SubStr('x'),) + X().x = 1 + with self.assertRaisesRegex(AttributeError, "'X' object has no attribute 'a'"): + X().a + def test_slots_special(self): # Testing __dict__ and __weakref__ in __slots__... class D(object): @@ -1445,12 +1462,9 @@ order (MRO) for bases """ raise AttributeError return object.__setattr__(self, name, value) C.__setattr__ = mysetattr - try: + with self.assertRaises(AttributeError): a.spam = "not spam" - except AttributeError: - pass - else: - self.fail("expected AttributeError") + self.assertEqual(a.spam, "spam") class D(C): pass @@ -1602,6 +1616,7 @@ order (MRO) for bases """ self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) @support.impl_detail("the module 'xxsubtype' is internal") + @unittest.skipIf(xxsubtype is None, "requires xxsubtype module") def test_classmethods_in_c(self): # Testing C-based class methods... import xxsubtype as spam @@ -1685,6 +1700,7 @@ order (MRO) for bases """ self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) @support.impl_detail("the module 'xxsubtype' is internal") + @unittest.skipIf(xxsubtype is None, "requires xxsubtype module") def test_staticmethods_in_c(self): # Testing C-based static methods... import xxsubtype as spam @@ -1963,6 +1979,20 @@ order (MRO) for bases """ del a[0:10] self.assertEqual(a.delitem, (slice(0, 10))) + def test_load_attr_extended_arg(self): + # https://github.com/python/cpython/issues/91625 + class Numbers: + def __getattr__(self, attr): + return int(attr.lstrip("_")) + attrs = ", ".join(f"Z._{n:03d}" for n in range(280)) + code = f"def number_attrs(Z):\n return [ {attrs} ]" + ns = {} + exec(code, ns) + number_attrs = ns["number_attrs"] + # Warm up the the function for quickening (PEP 659) + for _ in range(30): + self.assertEqual(number_attrs(Numbers()), list(range(280))) + def test_methods(self): # Testing methods... class C(object): @@ -2063,7 +2093,6 @@ order (MRO) for bases """ ("__format__", format, format_impl, set(), {}), ("__floor__", math.floor, zero, set(), {}), ("__trunc__", math.trunc, zero, set(), {}), - ("__trunc__", int, zero, set(), {}), ("__ceil__", math.ceil, zero, set(), {}), ("__dir__", dir, empty_seq, set(), {}), ("__round__", round, zero, set(), {}), @@ -2431,12 +2460,8 @@ order (MRO) for bases """ else: self.fail("no TypeError from dict(%r)" % badarg) - try: + with self.assertRaises(TypeError): dict({}, {}) - except TypeError: - pass - else: - self.fail("no TypeError from dict({}, {})") class Mapping: # Lacks a .keys() method; will be added later. @@ -2545,10 +2570,8 @@ order (MRO) for bases """ m2instance.b = 2 m2instance.a = 1 self.assertEqual(m2instance.__dict__, "Not a dict!") - try: + with self.assertRaises(TypeError): dir(m2instance) - except TypeError: - pass # Two essentially featureless objects, (Ellipsis just inherits stuff # from object. @@ -3238,12 +3261,8 @@ order (MRO) for bases """ if otype: otype = otype.__name__ return 'object=%s; type=%s' % (object, otype) - class OldClass: + class NewClass: __doc__ = DocDescr() - class NewClass(object): - __doc__ = DocDescr() - self.assertEqual(OldClass.__doc__, 'object=None; type=OldClass') - self.assertEqual(OldClass().__doc__, 'object=OldClass instance; type=OldClass') self.assertEqual(NewClass.__doc__, 'object=None; type=NewClass') self.assertEqual(NewClass().__doc__, 'object=NewClass instance; type=NewClass') @@ -3283,7 +3302,7 @@ order (MRO) for bases """ cant(True, int) cant(2, bool) o = object() - cant(o, type(1)) + cant(o, int) cant(o, type(None)) del o class G(object): @@ -3558,7 +3577,6 @@ order (MRO) for bases """ def test_str_of_str_subclass(self): # Testing __str__ defined in subclass of str ... import binascii - import io class octetstring(str): def __str__(self): @@ -3576,6 +3594,16 @@ order (MRO) for bases """ self.assertEqual(o.__str__(), '41') self.assertEqual(o.__repr__(), 'A repr') + def test_repr_with_module_str_subclass(self): + # gh-98783 + class StrSub(str): + pass + class Some: + pass + Some.__module__ = StrSub('example') + self.assertIsInstance(repr(Some), str) # should not crash + self.assertIsInstance(repr(Some()), str) # should not crash + def test_keyword_arguments(self): # Testing keyword arguments to __init__, __call__... def f(a): return a @@ -3591,12 +3619,8 @@ order (MRO) for bases """ pass A.__call__ = A() - try: + with self.assertRaises(RecursionError): A()() - except RecursionError: - pass - else: - self.fail("Recursion limit should have been reached for __call__()") def test_delete_hook(self): # Testing __del__ hook... @@ -4066,7 +4090,7 @@ order (MRO) for bases """ except TypeError: pass else: - assert 0, "best_base calculation found wanting" + self.fail("best_base calculation found wanting") def test_unsubclassable_types(self): with self.assertRaises(TypeError): @@ -4442,18 +4466,14 @@ order (MRO) for bases """ def test_file_fault(self): # Testing sys.stdout is changed in getattr... - test_stdout = sys.stdout class StdoutGuard: def __getattr__(self, attr): sys.stdout = sys.__stdout__ - raise RuntimeError("Premature access to sys.stdout.%s" % attr) - sys.stdout = StdoutGuard() - try: - print("Oops!") - except RuntimeError: - pass - finally: - sys.stdout = test_stdout + raise RuntimeError(f"Premature access to sys.stdout.{attr}") + + with redirect_stdout(StdoutGuard()): + with self.assertRaises(RuntimeError): + print("Oops!") def test_vicious_descriptor_nonsense(self): # Testing vicious_descriptor_nonsense... @@ -4729,6 +4749,33 @@ order (MRO) for bases """ with self.assertRaises(TypeError): str.__add__(fake_str, "abc") + def test_specialized_method_calls_check_types(self): + # https://github.com/python/cpython/issues/92063 + class Thing: + pass + thing = Thing() + for i in range(20): + with self.assertRaises(TypeError): + # PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS + list.sort(thing) + for i in range(20): + with self.assertRaises(TypeError): + # PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS + str.split(thing) + for i in range(20): + with self.assertRaises(TypeError): + # PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS + str.upper(thing) + for i in range(20): + with self.assertRaises(TypeError): + # PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST + str.strip(thing) + from collections import deque + for i in range(20): + with self.assertRaises(TypeError): + # PRECALL_NO_KW_METHOD_DESCRIPTOR_O + deque.append(thing, thing) + def test_repr_as_str(self): # Issue #11603: crash or infinite loop when rebinding __str__ as # __repr__. @@ -4939,6 +4986,23 @@ order (MRO) for bases """ cls.lst = [2**i for i in range(10000)] X.descr + def test_remove_subclass(self): + # bpo-46417: when the last subclass of a type is deleted, + # remove_subclass() clears the internal dictionary of subclasses: + # set PyTypeObject.tp_subclasses to NULL. remove_subclass() is called + # when a type is deallocated. + class Parent: + pass + self.assertEqual(Parent.__subclasses__(), []) + + class Child(Parent): + pass + self.assertEqual(Parent.__subclasses__(), [Child]) + + del Child + gc.collect() + self.assertEqual(Parent.__subclasses__(), []) + class DictProxyTests(unittest.TestCase): def setUp(self): @@ -5505,7 +5569,7 @@ class SharedKeyTests(unittest.TestCase): pass #Shrink keys by repeatedly creating instances - [(A(), B()) for _ in range(20)] + [(A(), B()) for _ in range(30)] a, b = A(), B() self.assertEqual(sys.getsizeof(vars(a)), sys.getsizeof(vars(b))) @@ -5743,6 +5807,23 @@ class MroTest(unittest.TestCase): class A(metaclass=M): pass + def test_disappearing_custom_mro(self): + """ + gh-92112: A custom mro() returning a result conflicting with + __bases__ and deleting itself caused a double free. + """ + class B: + pass + + class M(DebugHelperMeta): + def mro(cls): + del M.mro + return (B,) + + with self.assertRaises(TypeError): + class A(metaclass=M): + pass + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_descrtut.py b/Lib/test/test_descrtut.py index 2af683e707c..7796031ed06 100644 --- a/Lib/test/test_descrtut.py +++ b/Lib/test/test_descrtut.py @@ -1,7 +1,7 @@ # This contains most of the executable examples from Guido's descr # tutorial, once at # -# http://www.python.org/2.2/descrintro.html +# https://www.python.org/download/releases/2.2.3/descrintro/ # # A few examples left implicit in the writeup were fleshed out, a few were # skipped due to lack of interest (e.g., faking super() by hand isn't @@ -9,7 +9,6 @@ # deterministic. from test.support import sortdict -import pprint import doctest import unittest @@ -167,6 +166,7 @@ For instance of built-in types, x.__class__ is now the same as type(x): You can get the information from the list type: + >>> import pprint >>> pprint.pprint(dir(list)) # like list.__dict__.keys(), but sorted ['__add__', '__class__', @@ -181,6 +181,7 @@ You can get the information from the list type: '__ge__', '__getattribute__', '__getitem__', + '__getstate__', '__gt__', '__hash__', '__iadd__', diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 66f5d56deea..79638340059 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1077,6 +1077,38 @@ class DictTest(unittest.TestCase): self.assertEqual(list(a), ['x', 'y']) self.assertEqual(list(b), ['x', 'y', 'z']) + @support.cpython_only + def test_splittable_update(self): + """dict.update(other) must preserve order in other.""" + class C: + def __init__(self, order): + if order: + self.a, self.b, self.c = 1, 2, 3 + else: + self.c, self.b, self.a = 1, 2, 3 + o = C(True) + o = C(False) # o.__dict__ has reversed order. + self.assertEqual(list(o.__dict__), ["c", "b", "a"]) + + d = {} + d.update(o.__dict__) + self.assertEqual(list(d), ["c", "b", "a"]) + + @support.cpython_only + def test_splittable_to_generic_combinedtable(self): + """split table must be correctly resized and converted to generic combined table""" + class C: + pass + + a = C() + a.x = 1 + d = a.__dict__ + before_resize = sys.getsizeof(d) + d[2] = 2 # split table is resized to a generic combined table + + self.assertGreater(sys.getsizeof(d), before_resize) + self.assertEqual(list(d), ['x', 2]) + def test_iterator_pickling(self): for proto in range(pickle.HIGHEST_PROTOCOL + 1): data = {1:"a", 2:"b", 3:"c"} @@ -1438,7 +1470,7 @@ class DictTest(unittest.TestCase): self.assertTrue(gc.is_tracked(next(it))) @support.cpython_only - def test_dict_items_result_gc(self): + def test_dict_items_result_gc_reversed(self): # Same as test_dict_items_result_gc above, but reversed. it = reversed({None: []}.items()) gc.collect() diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py index be271bebaaf..924f4a6829e 100644 --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -170,6 +170,10 @@ class DictSetTest(unittest.TestCase): {('a', 1), ('b', 2)}) self.assertEqual(d1.items() & set(d2.items()), {('b', 2)}) self.assertEqual(d1.items() & set(d3.items()), set()) + self.assertEqual(d1.items() & (("a", 1), ("b", 2)), + {('a', 1), ('b', 2)}) + self.assertEqual(d1.items() & (("a", 2), ("b", 2)), {('b', 2)}) + self.assertEqual(d1.items() & (("d", 4), ("e", 5)), set()) self.assertEqual(d1.items() | d1.items(), {('a', 1), ('b', 2)}) @@ -183,12 +187,23 @@ class DictSetTest(unittest.TestCase): {('a', 1), ('a', 2), ('b', 2)}) self.assertEqual(d1.items() | set(d3.items()), {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) + self.assertEqual(d1.items() | (('a', 1), ('b', 2)), + {('a', 1), ('b', 2)}) + self.assertEqual(d1.items() | (('a', 2), ('b', 2)), + {('a', 1), ('a', 2), ('b', 2)}) + self.assertEqual(d1.items() | (('d', 4), ('e', 5)), + {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) self.assertEqual(d1.items() ^ d1.items(), set()) self.assertEqual(d1.items() ^ d2.items(), {('a', 1), ('a', 2)}) self.assertEqual(d1.items() ^ d3.items(), {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) + self.assertEqual(d1.items() ^ (('a', 1), ('b', 2)), set()) + self.assertEqual(d1.items() ^ (("a", 2), ("b", 2)), + {('a', 1), ('a', 2)}) + self.assertEqual(d1.items() ^ (("d", 4), ("e", 5)), + {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) self.assertEqual(d1.items() - d1.items(), set()) self.assertEqual(d1.items() - d2.items(), {('a', 1)}) @@ -196,6 +211,9 @@ class DictSetTest(unittest.TestCase): self.assertEqual(d1.items() - set(d1.items()), set()) self.assertEqual(d1.items() - set(d2.items()), {('a', 1)}) self.assertEqual(d1.items() - set(d3.items()), {('a', 1), ('b', 2)}) + self.assertEqual(d1.items() - (('a', 1), ('b', 2)), set()) + self.assertEqual(d1.items() - (("a", 2), ("b", 2)), {('a', 1)}) + self.assertEqual(d1.items() - (("d", 4), ("e", 5)), {('a', 1), ('b', 2)}) self.assertFalse(d1.items().isdisjoint(d1.items())) self.assertFalse(d1.items().isdisjoint(d2.items())) @@ -320,6 +338,9 @@ class DictSetTest(unittest.TestCase): self.assertIsInstance(d.values(), collections.abc.ValuesView) self.assertIsInstance(d.values(), collections.abc.MappingView) self.assertIsInstance(d.values(), collections.abc.Sized) + self.assertIsInstance(d.values(), collections.abc.Collection) + self.assertIsInstance(d.values(), collections.abc.Iterable) + self.assertIsInstance(d.values(), collections.abc.Container) self.assertIsInstance(d.items(), collections.abc.ItemsView) self.assertIsInstance(d.items(), collections.abc.MappingView) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 3b8ebb5dba9..bdf48c15309 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -1,14 +1,18 @@ # Minimal tests for dis module -from test.support import captured_stdout, requires_debug_ranges -from test.support.bytecode_helper import BytecodeTestCase -import unittest -import sys +import contextlib import dis import io import re +import sys import types -import contextlib +import unittest +from test.support import (captured_stdout, requires_debug_ranges, + requires_specialization, cpython_only) +from test.support.bytecode_helper import BytecodeTestCase + +import opcode + def get_tb(): def _error(): @@ -38,43 +42,50 @@ class _C: cls.x = x == 1 dis_c_instance_method = """\ -%3d 0 LOAD_FAST 1 (x) - 2 LOAD_CONST 1 (1) - 4 COMPARE_OP 2 (==) - 6 LOAD_FAST 0 (self) - 8 STORE_ATTR 0 (x) - 10 LOAD_CONST 0 (None) - 12 RETURN_VALUE -""" % (_C.__init__.__code__.co_firstlineno + 1,) +%3d RESUME 0 + +%3d LOAD_FAST 1 (x) + LOAD_CONST 1 (1) + COMPARE_OP 32 (==) + LOAD_FAST 0 (self) + STORE_ATTR 0 (x) + LOAD_CONST 0 (None) + RETURN_VALUE +""" % (_C.__init__.__code__.co_firstlineno, _C.__init__.__code__.co_firstlineno + 1,) dis_c_instance_method_bytes = """\ - 0 LOAD_FAST 1 - 2 LOAD_CONST 1 - 4 COMPARE_OP 2 (==) - 6 LOAD_FAST 0 - 8 STORE_ATTR 0 - 10 LOAD_CONST 0 - 12 RETURN_VALUE + RESUME 0 + LOAD_FAST 1 + LOAD_CONST 1 + COMPARE_OP 32 (==) + LOAD_FAST 0 + STORE_ATTR 0 + LOAD_CONST 0 + RETURN_VALUE """ dis_c_class_method = """\ -%3d 0 LOAD_FAST 1 (x) - 2 LOAD_CONST 1 (1) - 4 COMPARE_OP 2 (==) - 6 LOAD_FAST 0 (cls) - 8 STORE_ATTR 0 (x) - 10 LOAD_CONST 0 (None) - 12 RETURN_VALUE -""" % (_C.cm.__code__.co_firstlineno + 2,) +%3d RESUME 0 + +%3d LOAD_FAST 1 (x) + LOAD_CONST 1 (1) + COMPARE_OP 32 (==) + LOAD_FAST 0 (cls) + STORE_ATTR 0 (x) + LOAD_CONST 0 (None) + RETURN_VALUE +""" % (_C.cm.__code__.co_firstlineno, _C.cm.__code__.co_firstlineno + 2,) dis_c_static_method = """\ -%3d 0 LOAD_FAST 0 (x) - 2 LOAD_CONST 1 (1) - 4 COMPARE_OP 2 (==) - 6 STORE_FAST 0 (x) - 8 LOAD_CONST 0 (None) - 10 RETURN_VALUE -""" % (_C.sm.__code__.co_firstlineno + 2,) +%3d RESUME 0 + +%3d LOAD_FAST 0 (x) + LOAD_CONST 1 (1) + COMPARE_OP 32 (==) + STORE_FAST 0 (x) + LOAD_CONST 0 (None) + RETURN_VALUE +""" % (_C.sm.__code__.co_firstlineno, _C.sm.__code__.co_firstlineno + 2,) # Class disassembling info has an extra newline at end. dis_c = """\ @@ -93,24 +104,28 @@ def _f(a): return 1 dis_f = """\ -%3d 0 LOAD_GLOBAL 0 (print) - 2 LOAD_FAST 0 (a) - 4 CALL_FUNCTION 1 - 6 POP_TOP +%3d RESUME 0 -%3d 8 LOAD_CONST 1 (1) - 10 RETURN_VALUE -""" % (_f.__code__.co_firstlineno + 1, +%3d LOAD_GLOBAL 1 (NULL + print) + LOAD_FAST 0 (a) + CALL 1 + POP_TOP + +%3d LOAD_CONST 1 (1) + RETURN_VALUE +""" % (_f.__code__.co_firstlineno, + _f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 2) dis_f_co_code = """\ - 0 LOAD_GLOBAL 0 - 2 LOAD_FAST 0 - 4 CALL_FUNCTION 1 - 6 POP_TOP - 8 LOAD_CONST 1 - 10 RETURN_VALUE + RESUME 0 + LOAD_GLOBAL 1 + LOAD_FAST 0 + CALL 1 + POP_TOP + LOAD_CONST 1 + RETURN_VALUE """ @@ -120,21 +135,25 @@ def bug708901(): pass dis_bug708901 = """\ -%3d 0 LOAD_GLOBAL 0 (range) - 2 LOAD_CONST 1 (1) +%3d RESUME 0 -%3d 4 LOAD_CONST 2 (10) +%3d LOAD_GLOBAL 1 (NULL + range) + LOAD_CONST 1 (1) -%3d 6 CALL_FUNCTION 2 - 8 GET_ITER - >> 10 FOR_ITER 2 (to 16) - 12 STORE_FAST 0 (res) +%3d LOAD_CONST 2 (10) -%3d 14 JUMP_ABSOLUTE 5 (to 10) +%3d CALL 2 + GET_ITER + >> FOR_ITER 2 (to 38) + STORE_FAST 0 (res) -%3d >> 16 LOAD_CONST 0 (None) - 18 RETURN_VALUE -""" % (bug708901.__code__.co_firstlineno + 1, +%3d JUMP_BACKWARD 4 (to 30) + +%3d >> END_FOR + LOAD_CONST 0 (None) + RETURN_VALUE +""" % (bug708901.__code__.co_firstlineno, + bug708901.__code__.co_firstlineno + 1, bug708901.__code__.co_firstlineno + 2, bug708901.__code__.co_firstlineno + 1, bug708901.__code__.co_firstlineno + 3, @@ -147,19 +166,22 @@ def bug1333982(x=[]): pass dis_bug1333982 = """\ -%3d 0 LOAD_ASSERTION_ERROR - 2 LOAD_CONST 2 ( at 0x..., file "%s", line %d>) - 4 MAKE_FUNCTION 0 - 6 LOAD_FAST 0 (x) - 8 GET_ITER - 10 CALL_FUNCTION 1 +%3d RESUME 0 -%3d 12 LOAD_CONST 3 (1) +%3d LOAD_ASSERTION_ERROR + LOAD_CONST 1 ( at 0x..., file "%s", line %d>) + MAKE_FUNCTION 0 + LOAD_FAST 0 (x) + GET_ITER + CALL 0 -%3d 14 BINARY_OP 0 (+) - 16 CALL_FUNCTION 1 - 18 RAISE_VARARGS 1 -""" % (bug1333982.__code__.co_firstlineno + 1, +%3d LOAD_CONST 2 (1) + +%3d BINARY_OP 0 (+) + CALL 0 + RAISE_VARARGS 1 +""" % (bug1333982.__code__.co_firstlineno, + bug1333982.__code__.co_firstlineno + 1, __file__, bug1333982.__code__.co_firstlineno + 1, bug1333982.__code__.co_firstlineno + 2, @@ -171,12 +193,13 @@ def bug42562(): # Set line number for 'pass' to None -bug42562.__code__ = bug42562.__code__.replace(co_linetable=b'\x04\x80') +bug42562.__code__ = bug42562.__code__.replace(co_linetable=b'\xf8') dis_bug42562 = """\ - 0 LOAD_CONST 0 (None) - 2 RETURN_VALUE + RESUME 0 + LOAD_CONST 0 (None) + RETURN_VALUE """ # Extended arg followed by NOP @@ -189,56 +212,82 @@ code_bug_45757 = bytes([ ]) dis_bug_45757 = """\ - 0 EXTENDED_ARG 1 - 2 NOP - 4 EXTENDED_ARG 1 - 6 LOAD_CONST 297 - 8 RETURN_VALUE + EXTENDED_ARG 1 + NOP + EXTENDED_ARG 1 + LOAD_CONST 297 + RETURN_VALUE +""" + +# [255, 255, 255, 252] is -4 in a 4 byte signed integer +bug46724 = bytes([ + opcode.EXTENDED_ARG, 255, + opcode.EXTENDED_ARG, 255, + opcode.EXTENDED_ARG, 255, + opcode.opmap['JUMP_FORWARD'], 252, +]) + + +dis_bug46724 = """\ + >> EXTENDED_ARG 255 + EXTENDED_ARG 65535 + EXTENDED_ARG 16777215 + JUMP_FORWARD -4 (to 0) """ _BIG_LINENO_FORMAT = """\ -%3d 0 LOAD_GLOBAL 0 (spam) - 2 POP_TOP - 4 LOAD_CONST 0 (None) - 6 RETURN_VALUE + 1 RESUME 0 + +%3d LOAD_GLOBAL 0 (spam) + POP_TOP + LOAD_CONST 0 (None) + RETURN_VALUE """ _BIG_LINENO_FORMAT2 = """\ -%4d 0 LOAD_GLOBAL 0 (spam) - 2 POP_TOP - 4 LOAD_CONST 0 (None) - 6 RETURN_VALUE + 1 RESUME 0 + +%4d LOAD_GLOBAL 0 (spam) + POP_TOP + LOAD_CONST 0 (None) + RETURN_VALUE """ dis_module_expected_results = """\ Disassembly of f: - 4 0 LOAD_CONST 0 (None) - 2 RETURN_VALUE + 4 RESUME 0 + LOAD_CONST 0 (None) + RETURN_VALUE Disassembly of g: - 5 0 LOAD_CONST 0 (None) - 2 RETURN_VALUE + 5 RESUME 0 + LOAD_CONST 0 (None) + RETURN_VALUE """ expr_str = "x + 1" dis_expr_str = """\ - 1 0 LOAD_NAME 0 (x) - 2 LOAD_CONST 0 (1) - 4 BINARY_OP 0 (+) - 6 RETURN_VALUE + 0 RESUME 0 + + 1 LOAD_NAME 0 (x) + LOAD_CONST 0 (1) + BINARY_OP 0 (+) + RETURN_VALUE """ simple_stmt_str = "x = x + 1" dis_simple_stmt_str = """\ - 1 0 LOAD_NAME 0 (x) - 2 LOAD_CONST 0 (1) - 4 BINARY_OP 0 (+) - 6 STORE_NAME 0 (x) - 8 LOAD_CONST 1 (None) - 10 RETURN_VALUE + 0 RESUME 0 + + 1 LOAD_NAME 0 (x) + LOAD_CONST 0 (1) + BINARY_OP 0 (+) + STORE_NAME 0 (x) + LOAD_CONST 1 (None) + RETURN_VALUE """ annot_stmt_str = """\ @@ -250,31 +299,35 @@ lst[fun(0)]: int = 1 # leading newline is for a reason (tests lineno) dis_annot_stmt_str = """\ - 2 0 SETUP_ANNOTATIONS - 2 LOAD_CONST 0 (1) - 4 STORE_NAME 0 (x) - 6 LOAD_NAME 1 (int) - 8 LOAD_NAME 2 (__annotations__) - 10 LOAD_CONST 1 ('x') - 12 STORE_SUBSCR + 0 RESUME 0 - 3 14 LOAD_NAME 3 (fun) - 16 LOAD_CONST 0 (1) - 18 CALL_FUNCTION 1 - 20 LOAD_NAME 2 (__annotations__) - 22 LOAD_CONST 2 ('y') - 24 STORE_SUBSCR + 2 SETUP_ANNOTATIONS + LOAD_CONST 0 (1) + STORE_NAME 0 (x) + LOAD_NAME 1 (int) + LOAD_NAME 2 (__annotations__) + LOAD_CONST 1 ('x') + STORE_SUBSCR - 4 26 LOAD_CONST 0 (1) - 28 LOAD_NAME 4 (lst) - 30 LOAD_NAME 3 (fun) - 32 LOAD_CONST 3 (0) - 34 CALL_FUNCTION 1 - 36 STORE_SUBSCR - 38 LOAD_NAME 1 (int) - 40 POP_TOP - 42 LOAD_CONST 4 (None) - 44 RETURN_VALUE + 3 PUSH_NULL + LOAD_NAME 3 (fun) + LOAD_CONST 0 (1) + CALL 1 + LOAD_NAME 2 (__annotations__) + LOAD_CONST 2 ('y') + STORE_SUBSCR + + 4 LOAD_CONST 0 (1) + LOAD_NAME 4 (lst) + PUSH_NULL + LOAD_NAME 3 (fun) + LOAD_CONST 3 (0) + CALL 1 + STORE_SUBSCR + LOAD_NAME 1 (int) + POP_TOP + LOAD_CONST 4 (None) + RETURN_VALUE """ compound_stmt_str = """\ @@ -284,60 +337,63 @@ while 1: # Trailing newline has been deliberately omitted dis_compound_stmt_str = """\ - 1 0 LOAD_CONST 0 (0) - 2 STORE_NAME 0 (x) + 0 RESUME 0 - 2 4 NOP + 1 LOAD_CONST 0 (0) + STORE_NAME 0 (x) - 3 >> 6 LOAD_NAME 0 (x) - 8 LOAD_CONST 1 (1) - 10 BINARY_OP 13 (+=) - 12 STORE_NAME 0 (x) + 2 NOP - 2 14 JUMP_ABSOLUTE 3 (to 6) + 3 >> LOAD_NAME 0 (x) + LOAD_CONST 1 (1) + BINARY_OP 13 (+=) + STORE_NAME 0 (x) + + 2 JUMP_BACKWARD 6 (to 8) """ dis_traceback = """\ -%3d 0 NOP +%3d RESUME 0 -%3d 2 LOAD_CONST 1 (1) - 4 LOAD_CONST 2 (0) - --> 6 BINARY_OP 11 (/) - 8 POP_TOP +%3d NOP -%3d 10 LOAD_FAST 1 (tb) - 12 RETURN_VALUE - >> 14 PUSH_EXC_INFO +%3d LOAD_CONST 1 (1) + LOAD_CONST 2 (0) + --> BINARY_OP 11 (/) + POP_TOP -%3d 16 LOAD_GLOBAL 0 (Exception) - 18 JUMP_IF_NOT_EXC_MATCH 26 (to 52) - 20 POP_TOP - 22 STORE_FAST 0 (e) - 24 POP_TOP +%3d LOAD_FAST_CHECK 1 (tb) + RETURN_VALUE + >> PUSH_EXC_INFO -%3d 26 LOAD_FAST 0 (e) - 28 LOAD_ATTR 1 (__traceback__) - 30 STORE_FAST 1 (tb) - 32 POP_EXCEPT - 34 LOAD_CONST 0 (None) - 36 STORE_FAST 0 (e) - 38 DELETE_FAST 0 (e) +%3d LOAD_GLOBAL 0 (Exception) + CHECK_EXC_MATCH + POP_JUMP_IF_FALSE 23 (to 82) + STORE_FAST 0 (e) -%3d 40 LOAD_FAST 1 (tb) - 42 RETURN_VALUE - >> 44 LOAD_CONST 0 (None) - 46 STORE_FAST 0 (e) - 48 DELETE_FAST 0 (e) - 50 RERAISE 1 +%3d LOAD_FAST 0 (e) + LOAD_ATTR 2 (__traceback__) + STORE_FAST 1 (tb) + POP_EXCEPT + LOAD_CONST 0 (None) + STORE_FAST 0 (e) + DELETE_FAST 0 (e) -%3d >> 52 RERAISE 0 - >> 54 POP_EXCEPT_AND_RERAISE +%3d LOAD_FAST 1 (tb) + RETURN_VALUE + >> LOAD_CONST 0 (None) + STORE_FAST 0 (e) + DELETE_FAST 0 (e) + RERAISE 1 + +%3d >> RERAISE 0 + >> COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: - 2 to 8 -> 14 [0] - 14 to 24 -> 54 [3] lasti - 26 to 30 -> 44 [3] lasti - 44 to 52 -> 54 [3] lasti -""" % (TRACEBACK_CODE.co_firstlineno + 1, +4 rows +""" % (TRACEBACK_CODE.co_firstlineno, + TRACEBACK_CODE.co_firstlineno + 1, TRACEBACK_CODE.co_firstlineno + 2, TRACEBACK_CODE.co_firstlineno + 5, TRACEBACK_CODE.co_firstlineno + 3, @@ -349,22 +405,158 @@ def _fstring(a, b, c, d): return f'{a} {b:4} {c!r} {d!r:4}' dis_fstring = """\ -%3d 0 LOAD_FAST 0 (a) - 2 FORMAT_VALUE 0 - 4 LOAD_CONST 1 (' ') - 6 LOAD_FAST 1 (b) - 8 LOAD_CONST 2 ('4') - 10 FORMAT_VALUE 4 (with format) - 12 LOAD_CONST 1 (' ') - 14 LOAD_FAST 2 (c) - 16 FORMAT_VALUE 2 (repr) - 18 LOAD_CONST 1 (' ') - 20 LOAD_FAST 3 (d) - 22 LOAD_CONST 2 ('4') - 24 FORMAT_VALUE 6 (repr, with format) - 26 BUILD_STRING 7 - 28 RETURN_VALUE -""" % (_fstring.__code__.co_firstlineno + 1,) +%3d RESUME 0 + +%3d LOAD_FAST 0 (a) + FORMAT_VALUE 0 + LOAD_CONST 1 (' ') + LOAD_FAST 1 (b) + LOAD_CONST 2 ('4') + FORMAT_VALUE 4 (with format) + LOAD_CONST 1 (' ') + LOAD_FAST 2 (c) + FORMAT_VALUE 2 (repr) + LOAD_CONST 1 (' ') + LOAD_FAST 3 (d) + LOAD_CONST 2 ('4') + FORMAT_VALUE 6 (repr, with format) + BUILD_STRING 7 + RETURN_VALUE +""" % (_fstring.__code__.co_firstlineno, _fstring.__code__.co_firstlineno + 1) + +def _with(c): + with c: + x = 1 + y = 2 + +dis_with = """\ +%3d RESUME 0 + +%3d LOAD_FAST 0 (c) + BEFORE_WITH + POP_TOP + +%3d LOAD_CONST 1 (1) + STORE_FAST 1 (x) + +%3d LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + CALL 2 + POP_TOP + +%3d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + LOAD_CONST 0 (None) + RETURN_VALUE + +%3d >> PUSH_EXC_INFO + WITH_EXCEPT_START + POP_JUMP_IF_TRUE 1 (to 46) + RERAISE 2 + >> POP_TOP + POP_EXCEPT + POP_TOP + POP_TOP + +%3d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + LOAD_CONST 0 (None) + RETURN_VALUE + >> COPY 3 + POP_EXCEPT + RERAISE 1 +ExceptionTable: +2 rows +""" % (_with.__code__.co_firstlineno, + _with.__code__.co_firstlineno + 1, + _with.__code__.co_firstlineno + 2, + _with.__code__.co_firstlineno + 1, + _with.__code__.co_firstlineno + 3, + _with.__code__.co_firstlineno + 1, + _with.__code__.co_firstlineno + 3, + ) + +async def _asyncwith(c): + async with c: + x = 1 + y = 2 + +dis_asyncwith = """\ +%3d RETURN_GENERATOR + POP_TOP + RESUME 0 + +%3d LOAD_FAST 0 (c) + BEFORE_ASYNC_WITH + GET_AWAITABLE 1 + LOAD_CONST 0 (None) + >> SEND 3 (to 22) + YIELD_VALUE 2 + RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 4 (to 14) + >> POP_TOP + +%3d LOAD_CONST 1 (1) + STORE_FAST 1 (x) + +%3d LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + CALL 2 + GET_AWAITABLE 2 + LOAD_CONST 0 (None) + >> SEND 3 (to 56) + YIELD_VALUE 2 + RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 4 (to 48) + >> POP_TOP + +%3d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + LOAD_CONST 0 (None) + RETURN_VALUE + +%3d >> CLEANUP_THROW + JUMP_BACKWARD 24 (to 22) + >> CLEANUP_THROW + JUMP_BACKWARD 9 (to 56) + >> PUSH_EXC_INFO + WITH_EXCEPT_START + GET_AWAITABLE 2 + LOAD_CONST 0 (None) + >> SEND 4 (to 92) + YIELD_VALUE 3 + RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 4 (to 82) + >> CLEANUP_THROW + >> POP_JUMP_IF_TRUE 1 (to 96) + RERAISE 2 + >> POP_TOP + POP_EXCEPT + POP_TOP + POP_TOP + +%3d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + LOAD_CONST 0 (None) + RETURN_VALUE + >> COPY 3 + POP_EXCEPT + RERAISE 1 + >> CALL_INTRINSIC_1 3 + RERAISE 1 +ExceptionTable: +12 rows +""" % (_asyncwith.__code__.co_firstlineno, + _asyncwith.__code__.co_firstlineno + 1, + _asyncwith.__code__.co_firstlineno + 2, + _asyncwith.__code__.co_firstlineno + 1, + _asyncwith.__code__.co_firstlineno + 3, + _asyncwith.__code__.co_firstlineno + 1, + _asyncwith.__code__.co_firstlineno + 3, + ) + def _tryfinally(a, b): try: @@ -379,47 +571,60 @@ def _tryfinallyconst(b): b() dis_tryfinally = """\ -%3d 0 NOP +%3d RESUME 0 -%3d 2 LOAD_FAST 0 (a) +%3d NOP -%3d 4 LOAD_FAST 1 (b) - 6 CALL_FUNCTION 0 - 8 POP_TOP - 10 RETURN_VALUE - >> 12 PUSH_EXC_INFO - 14 LOAD_FAST 1 (b) - 16 CALL_FUNCTION 0 - 18 POP_TOP - 20 RERAISE 0 - >> 22 POP_EXCEPT_AND_RERAISE +%3d LOAD_FAST 0 (a) + +%3d PUSH_NULL + LOAD_FAST 1 (b) + CALL 0 + POP_TOP + RETURN_VALUE + >> PUSH_EXC_INFO + PUSH_NULL + LOAD_FAST 1 (b) + CALL 0 + POP_TOP + RERAISE 0 + >> COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: - 2 to 2 -> 12 [0] - 12 to 20 -> 22 [3] lasti -""" % (_tryfinally.__code__.co_firstlineno + 1, +2 rows +""" % (_tryfinally.__code__.co_firstlineno, + _tryfinally.__code__.co_firstlineno + 1, _tryfinally.__code__.co_firstlineno + 2, _tryfinally.__code__.co_firstlineno + 4, ) dis_tryfinallyconst = """\ -%3d 0 NOP +%3d RESUME 0 -%3d 2 NOP +%3d NOP -%3d 4 LOAD_FAST 0 (b) - 6 CALL_FUNCTION 0 - 8 POP_TOP - 10 LOAD_CONST 1 (1) - 12 RETURN_VALUE - 14 PUSH_EXC_INFO - 16 LOAD_FAST 0 (b) - 18 CALL_FUNCTION 0 - 20 POP_TOP - 22 RERAISE 0 - >> 24 POP_EXCEPT_AND_RERAISE +%3d NOP + +%3d PUSH_NULL + LOAD_FAST 0 (b) + CALL 0 + POP_TOP + LOAD_CONST 1 (1) + RETURN_VALUE + PUSH_EXC_INFO + PUSH_NULL + LOAD_FAST 0 (b) + CALL 0 + POP_TOP + RERAISE 0 + >> COPY 3 + POP_EXCEPT + RERAISE 1 ExceptionTable: - 14 to 22 -> 24 [3] lasti -""" % (_tryfinallyconst.__code__.co_firstlineno + 1, +1 row +""" % (_tryfinallyconst.__code__.co_firstlineno, + _tryfinallyconst.__code__.co_firstlineno + 1, _tryfinallyconst.__code__.co_firstlineno + 2, _tryfinallyconst.__code__.co_firstlineno + 4, ) @@ -441,17 +646,20 @@ def _h(y): return foo dis_nested_0 = """\ - 0 MAKE_CELL 0 (y) + MAKE_CELL 0 (y) -%3d 2 LOAD_CLOSURE 0 (y) - 4 BUILD_TUPLE 1 - 6 LOAD_CONST 1 () - 8 MAKE_FUNCTION 8 (closure) - 10 STORE_FAST 1 (foo) +%3d RESUME 0 -%3d 12 LOAD_FAST 1 (foo) - 14 RETURN_VALUE -""" % (_h.__code__.co_firstlineno + 1, +%3d LOAD_CLOSURE 0 (y) + BUILD_TUPLE 1 + LOAD_CONST 1 () + MAKE_FUNCTION 8 (closure) + STORE_FAST 1 (foo) + +%3d LOAD_FAST 1 (foo) + RETURN_VALUE +""" % (_h.__code__.co_firstlineno, + _h.__code__.co_firstlineno + 1, __file__, _h.__code__.co_firstlineno + 1, _h.__code__.co_firstlineno + 4, @@ -459,19 +667,23 @@ dis_nested_0 = """\ dis_nested_1 = """%s Disassembly of : - 0 MAKE_CELL 0 (x) + COPY_FREE_VARS 1 + MAKE_CELL 0 (x) -%3d 2 LOAD_CLOSURE 0 (x) - 4 BUILD_TUPLE 1 - 6 LOAD_CONST 1 ( at 0x..., file "%s", line %d>) - 8 MAKE_FUNCTION 8 (closure) - 10 LOAD_DEREF 1 (y) - 12 GET_ITER - 14 CALL_FUNCTION 1 - 16 RETURN_VALUE +%3d RESUME 0 + +%3d LOAD_CLOSURE 0 (x) + BUILD_TUPLE 1 + LOAD_CONST 1 ( at 0x..., file "%s", line %d>) + MAKE_FUNCTION 8 (closure) + LOAD_DEREF 1 (y) + GET_ITER + CALL 0 + RETURN_VALUE """ % (dis_nested_0, __file__, _h.__code__.co_firstlineno + 1, + _h.__code__.co_firstlineno + 1, _h.__code__.co_firstlineno + 3, __file__, _h.__code__.co_firstlineno + 3, @@ -479,24 +691,174 @@ Disassembly of : dis_nested_2 = """%s Disassembly of at 0x..., file "%s", line %d>: -%3d 0 BUILD_LIST 0 - 2 LOAD_FAST 0 (.0) - >> 4 FOR_ITER 6 (to 18) - 6 STORE_FAST 1 (z) - 8 LOAD_DEREF 2 (x) - 10 LOAD_FAST 1 (z) - 12 BINARY_OP 0 (+) - 14 LIST_APPEND 2 - 16 JUMP_ABSOLUTE 2 (to 4) - >> 18 RETURN_VALUE + COPY_FREE_VARS 1 + +%3d RESUME 0 + BUILD_LIST 0 + LOAD_FAST 0 (.0) + >> FOR_ITER 7 (to 26) + STORE_FAST 1 (z) + LOAD_DEREF 2 (x) + LOAD_FAST 1 (z) + BINARY_OP 0 (+) + LIST_APPEND 2 + JUMP_BACKWARD 9 (to 8) + >> END_FOR + RETURN_VALUE """ % (dis_nested_1, __file__, _h.__code__.co_firstlineno + 3, _h.__code__.co_firstlineno + 3, ) +def load_test(x, y=0): + a, b = x, y + return a, b -class DisTests(unittest.TestCase): +dis_load_test_quickened_code = """\ +%3d 0 RESUME 0 + +%3d 2 LOAD_FAST__LOAD_FAST 0 (x) + 4 LOAD_FAST 1 (y) + 6 STORE_FAST__STORE_FAST 3 (b) + 8 STORE_FAST__LOAD_FAST 2 (a) + +%3d 10 LOAD_FAST__LOAD_FAST 2 (a) + 12 LOAD_FAST 3 (b) + 14 BUILD_TUPLE 2 + 16 RETURN_VALUE +""" % (load_test.__code__.co_firstlineno, + load_test.__code__.co_firstlineno + 1, + load_test.__code__.co_firstlineno + 2) + +def loop_test(): + for i in [1, 2, 3] * 3: + load_test(i) + +dis_loop_test_quickened_code = """\ +%3d RESUME 0 + +%3d BUILD_LIST 0 + LOAD_CONST 1 ((1, 2, 3)) + LIST_EXTEND 1 + LOAD_CONST 2 (3) + BINARY_OP 5 (*) + GET_ITER + >> FOR_ITER_LIST 15 (to 50) + STORE_FAST 0 (i) + +%3d LOAD_GLOBAL_MODULE 1 (NULL + load_test) + LOAD_FAST 0 (i) + CALL_PY_WITH_DEFAULTS 1 + POP_TOP + JUMP_BACKWARD 17 (to 16) + +%3d >> END_FOR + LOAD_CONST 0 (None) + RETURN_VALUE +""" % (loop_test.__code__.co_firstlineno, + loop_test.__code__.co_firstlineno + 1, + loop_test.__code__.co_firstlineno + 2, + loop_test.__code__.co_firstlineno + 1,) + +def extended_arg_quick(): + *_, _ = ... + +dis_extended_arg_quick_code = """\ +%3d 0 RESUME 0 + +%3d 2 LOAD_CONST 1 (Ellipsis) + 4 EXTENDED_ARG 1 + 6 UNPACK_EX 256 + 8 STORE_FAST 0 (_) + 10 STORE_FAST 0 (_) + 12 LOAD_CONST 0 (None) + 14 RETURN_VALUE +"""% (extended_arg_quick.__code__.co_firstlineno, + extended_arg_quick.__code__.co_firstlineno + 1,) + +ADAPTIVE_WARMUP_DELAY = 2 + +class DisTestBase(unittest.TestCase): + "Common utilities for DisTests and TestDisTraceback" + + def strip_addresses(self, text): + return re.sub(r'\b0x[0-9A-Fa-f]+\b', '0x...', text) + + def find_offset_column(self, lines): + for line in lines: + if line and not line.startswith("Disassembly"): + break + else: + return 0, 0 + offset = 5 + while (line[offset] == " "): + offset += 1 + if (line[offset] == ">"): + offset += 2 + while (line[offset] == " "): + offset += 1 + end = offset + while line[end] in "0123456789": + end += 1 + return end-5, end + + def assert_offsets_increasing(self, text, delta): + expected_offset = 0 + lines = text.splitlines() + start, end = self.find_offset_column(lines) + for line in lines: + if not line: + continue + if line.startswith("Disassembly"): + expected_offset = 0 + continue + if line.startswith("Exception"): + break + offset = int(line[start:end]) + self.assertGreaterEqual(offset, expected_offset, line) + expected_offset = offset + delta + + def assert_exception_table_increasing(self, lines): + prev_start, prev_end = -1, -1 + count = 0 + for line in lines: + m = re.match(r' (\d+) to (\d+) -> \d+ \[\d+\]', line) + start, end = [int(g) for g in m.groups()] + self.assertGreaterEqual(end, start) + self.assertGreater(start, prev_end) + prev_start, prev_end = start, end + count += 1 + return count + + def strip_offsets(self, text): + lines = text.splitlines(True) + start, end = self.find_offset_column(lines) + res = [] + lines = iter(lines) + for line in lines: + if line.startswith("Exception"): + res.append(line) + break + if not line or line.startswith("Disassembly"): + res.append(line) + else: + res.append(line[:start] + line[end:]) + num_rows = self.assert_exception_table_increasing(lines) + if num_rows: + res.append(f"{num_rows} row{'s' if num_rows > 1 else ''}\n") + return "".join(res) + + def do_disassembly_compare(self, got, expected, with_offsets=False): + if not with_offsets: + self.assert_offsets_increasing(got, 2) + got = self.strip_offsets(got) + if got != expected: + got = self.strip_addresses(got) + self.assertEqual(got, expected) + + +class DisTests(DisTestBase): maxDiff = None @@ -513,14 +875,10 @@ class DisTests(unittest.TestCase): def get_disassemble_as_string(self, func, lasti=-1): return self.get_disassembly(func, lasti, False) - def strip_addresses(self, text): - return re.sub(r'\b0x[0-9A-Fa-f]+\b', '0x...', text) - - def do_disassembly_test(self, func, expected): + def do_disassembly_test(self, func, expected, with_offsets=False): + self.maxDiff = None got = self.get_disassembly(func, depth=0) - if got != expected: - got = self.strip_addresses(got) - self.assertEqual(got, expected) + self.do_disassembly_compare(got, expected, with_offsets) def test_opmap(self): self.assertEqual(dis.opmap["NOP"], 9) @@ -535,14 +893,14 @@ class DisTests(unittest.TestCase): self.assertEqual(dis.opmap["STORE_NAME"], dis.HAVE_ARGUMENT) def test_widths(self): + long_opcodes = set(['JUMP_BACKWARD_NO_INTERRUPT', + ]) for opcode, opname in enumerate(dis.opname): - if opname in ('BUILD_MAP_UNPACK_WITH_CALL', - 'BUILD_TUPLE_UNPACK_WITH_CALL', - 'JUMP_IF_NOT_EXC_MATCH'): + if opname in long_opcodes: continue with self.subTest(opname=opname): width = dis._OPNAME_WIDTH - if opcode < dis.HAVE_ARGUMENT: + if opcode in dis.hasarg: width += 1 + dis._OPARG_WIDTH self.assertLessEqual(len(opname), width) @@ -567,6 +925,10 @@ class DisTests(unittest.TestCase): # Extended arg followed by NOP self.do_disassembly_test(code_bug_45757, dis_bug_45757) + def test_bug_46724(self): + # Test that negative operargs are handled properly + self.do_disassembly_test(bug46724, dis_bug46724) + def test_big_linenos(self): def func(count): namespace = {} @@ -592,6 +954,7 @@ class DisTests(unittest.TestCase): self.do_disassembly_test(dis_module, dis_module_expected_results) def test_big_offsets(self): + self.maxDiff = None def func(count): namespace = {} func = "def foo(x):\n " + ";".join(["x = x + 1"] * count) + "\n return x" @@ -600,24 +963,28 @@ class DisTests(unittest.TestCase): def expected(count, w): s = ['''\ + 1 %*d RESUME 0 + +''' % (w, 0)] + s += ['''\ %*d LOAD_FAST 0 (x) %*d LOAD_CONST 1 (1) %*d BINARY_OP 0 (+) %*d STORE_FAST 0 (x) -''' % (w, 8*i, w, 8*i + 2, w, 8*i + 4, w, 8*i + 6) +''' % (w, 10*i + 2, w, 10*i + 4, w, 10*i + 6, w, 10*i + 10) for i in range(count)] s += ['''\ 3 %*d LOAD_FAST 0 (x) %*d RETURN_VALUE -''' % (w, 8*count, w, 8*count + 2)] - s[0] = ' 2' + s[0][3:] +''' % (w, 10*count + 2, w, 10*count + 4)] + s[1] = ' 2' + s[1][3:] return ''.join(s) for i in range(1, 5): - self.do_disassembly_test(func(i), expected(i, 4)) - self.do_disassembly_test(func(1249), expected(1249, 4)) - self.do_disassembly_test(func(1250), expected(1250, 5)) + self.do_disassembly_test(func(i), expected(i, 4), True) + self.do_disassembly_test(func(999), expected(999, 4), True) + self.do_disassembly_test(func(1000), expected(1000, 5), True) def test_disassemble_str(self): self.do_disassembly_test(expr_str, dis_expr_str) @@ -664,6 +1031,12 @@ class DisTests(unittest.TestCase): def test_disassemble_fstring(self): self.do_disassembly_test(_fstring, dis_fstring) + def test_disassemble_with(self): + self.do_disassembly_test(_with, dis_with) + + def test_disassemble_asyncwith(self): + self.do_disassembly_test(_asyncwith, dis_asyncwith) + def test_disassemble_try_finally(self): self.do_disassembly_test(_tryfinally, dis_tryfinally) self.do_disassembly_test(_tryfinallyconst, dis_tryfinallyconst) @@ -676,6 +1049,7 @@ class DisTests(unittest.TestCase): self.assertRaises(RuntimeError, dis.dis, None) def test_dis_traceback(self): + self.maxDiff = None try: del sys.last_traceback except AttributeError: @@ -688,7 +1062,7 @@ class DisTests(unittest.TestCase): sys.last_traceback = tb tb_dis = self.get_disassemble_as_string(tb.tb_frame.f_code, tb.tb_lasti) - self.do_disassembly_test(None, tb_dis) + self.do_disassembly_test(None, tb_dis, True) def test_dis_object(self): self.assertRaises(TypeError, dis.dis, object()) @@ -697,6 +1071,7 @@ class DisTests(unittest.TestCase): def check(expected, **kwargs): dis = self.get_disassembly(_h, **kwargs) dis = self.strip_addresses(dis) + dis = self.strip_offsets(dis) self.assertEqual(dis, expected) check(dis_nested_0, depth=0) @@ -706,6 +1081,134 @@ class DisTests(unittest.TestCase): check(dis_nested_2, depth=None) check(dis_nested_2) + @staticmethod + def code_quicken(f, times=ADAPTIVE_WARMUP_DELAY): + for _ in range(times): + f() + + @cpython_only + @requires_specialization + def test_super_instructions(self): + self.code_quicken(lambda: load_test(0, 0)) + got = self.get_disassembly(load_test, adaptive=True) + self.do_disassembly_compare(got, dis_load_test_quickened_code, True) + + @cpython_only + @requires_specialization + def test_binary_specialize(self): + binary_op_quicken = """\ + 0 0 RESUME 0 + + 1 2 LOAD_NAME 0 (a) + 4 LOAD_NAME 1 (b) + 6 %s + 10 RETURN_VALUE +""" + co_int = compile('a + b', "", "eval") + self.code_quicken(lambda: exec(co_int, {}, {'a': 1, 'b': 2})) + got = self.get_disassembly(co_int, adaptive=True) + self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_INT 0 (+)", True) + + co_unicode = compile('a + b', "", "eval") + self.code_quicken(lambda: exec(co_unicode, {}, {'a': 'a', 'b': 'b'})) + got = self.get_disassembly(co_unicode, adaptive=True) + self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_UNICODE 0 (+)", True) + + binary_subscr_quicken = """\ + 0 0 RESUME 0 + + 1 2 LOAD_NAME 0 (a) + 4 LOAD_CONST 0 (0) + 6 %s + 16 RETURN_VALUE +""" + co_list = compile('a[0]', "", "eval") + self.code_quicken(lambda: exec(co_list, {}, {'a': [0]})) + got = self.get_disassembly(co_list, adaptive=True) + self.do_disassembly_compare(got, binary_subscr_quicken % "BINARY_SUBSCR_LIST_INT", True) + + co_dict = compile('a[0]', "", "eval") + self.code_quicken(lambda: exec(co_dict, {}, {'a': {0: '1'}})) + got = self.get_disassembly(co_dict, adaptive=True) + self.do_disassembly_compare(got, binary_subscr_quicken % "BINARY_SUBSCR_DICT", True) + + @cpython_only + @requires_specialization + def test_load_attr_specialize(self): + load_attr_quicken = """\ + 0 0 RESUME 0 + + 1 2 LOAD_CONST 0 ('a') + 4 LOAD_ATTR_SLOT 0 (__class__) + 24 RETURN_VALUE +""" + co = compile("'a'.__class__", "", "eval") + self.code_quicken(lambda: exec(co, {}, {})) + got = self.get_disassembly(co, adaptive=True) + self.do_disassembly_compare(got, load_attr_quicken, True) + + @cpython_only + @requires_specialization + def test_call_specialize(self): + call_quicken = """\ + 0 RESUME 0 + + 1 PUSH_NULL + LOAD_NAME 0 (str) + LOAD_CONST 0 (1) + CALL_NO_KW_STR_1 1 + RETURN_VALUE +""" + co = compile("str(1)", "", "eval") + self.code_quicken(lambda: exec(co, {}, {})) + got = self.get_disassembly(co, adaptive=True) + self.do_disassembly_compare(got, call_quicken) + + @cpython_only + @requires_specialization + def test_loop_quicken(self): + # Loop can trigger a quicken where the loop is located + self.code_quicken(loop_test, 1) + got = self.get_disassembly(loop_test, adaptive=True) + self.do_disassembly_compare(got, dis_loop_test_quickened_code) + + @cpython_only + def test_extended_arg_quick(self): + got = self.get_disassembly(extended_arg_quick) + self.do_disassembly_compare(got, dis_extended_arg_quick_code, True) + + def get_cached_values(self, quickened, adaptive): + def f(): + l = [] + for i in range(42): + l.append(i) + if quickened: + self.code_quicken(f) + else: + # "copy" the code to un-quicken it: + f.__code__ = f.__code__.replace() + for instruction in dis.get_instructions( + f, show_caches=True, adaptive=adaptive + ): + if instruction.opname == "CACHE": + yield instruction.argrepr + + @cpython_only + def test_show_caches(self): + for quickened in (False, True): + for adaptive in (False, True): + with self.subTest(f"{quickened=}, {adaptive=}"): + if adaptive: + pattern = r"^(\w+: \d+)?$" + else: + pattern = r"^(\w+: 0)?$" + caches = list(self.get_cached_values(quickened, adaptive)) + for cache in caches: + self.assertRegex(cache, pattern) + total_caches = 23 + empty_caches = 8 + self.assertEqual(caches.count(""), empty_caches) + self.assertEqual(len(caches), total_caches) class DisWithFileTests(DisTests): @@ -719,7 +1222,7 @@ class DisWithFileTests(DisTests): return output.getvalue() -if sys.flags.optimize: +if dis.code_info.__doc__ is None: code_info_consts = "0: None" else: code_info_consts = "0: 'Formatted details of methods, functions, or code.'" @@ -731,7 +1234,7 @@ Argument count: 1 Positional-only arguments: 0 Kw-only arguments: 0 Number of locals: 1 -Stack size: 3 +Stack size: \\d+ Flags: OPTIMIZED, NEWLOCALS Constants: {code_info_consts} @@ -755,7 +1258,7 @@ Argument count: 5 Positional-only arguments: 2 Kw-only arguments: 3 Number of locals: 10 -Stack size: 9 +Stack size: \\d+ Flags: OPTIMIZED, NEWLOCALS, VARARGS, VARKEYWORDS, GENERATOR Constants: 0: None @@ -788,7 +1291,7 @@ Argument count: 1 Positional-only arguments: 0 Kw-only arguments: 0 Number of locals: 1 -Stack size: 10 +Stack size: \\d+ Flags: OPTIMIZED, NEWLOCALS, NESTED Constants: 0: None @@ -811,7 +1314,7 @@ Argument count: 0 Positional-only arguments: 0 Kw-only arguments: 0 Number of locals: 0 -Stack size: 2 +Stack size: \\d+ Flags: 0x0 Constants: 0: 1 @@ -825,7 +1328,7 @@ Argument count: 0 Positional-only arguments: 0 Kw-only arguments: 0 Number of locals: 0 -Stack size: 2 +Stack size: \\d+ Flags: 0x0 Constants: 0: 1 @@ -840,7 +1343,7 @@ Argument count: 0 Positional-only arguments: 0 Kw-only arguments: 0 Number of locals: 0 -Stack size: 2 +Stack size: \\d+ Flags: 0x0 Constants: 0: 0 @@ -861,7 +1364,7 @@ Argument count: 0 Positional-only arguments: 0 Kw-only arguments: 0 Number of locals: 2 -Stack size: 10 +Stack size: \\d+ Flags: OPTIMIZED, NEWLOCALS, COROUTINE Constants: 0: None @@ -949,9 +1452,9 @@ def jumpy(): # End fodder for opinfo generation tests expected_outer_line = 1 _line_offset = outer.__code__.co_firstlineno - 1 -code_object_f = outer.__code__.co_consts[3] +code_object_f = outer.__code__.co_consts[1] expected_f_line = code_object_f.co_firstlineno - _line_offset -code_object_inner = code_object_f.co_consts[3] +code_object_inner = code_object_f.co_consts[1] expected_inner_line = code_object_inner.co_firstlineno - _line_offset expected_jumpy_line = 1 @@ -983,200 +1486,196 @@ def _prepare_test_cases(): #_prepare_test_cases() Instruction = dis.Instruction + expected_opinfo_outer = [ Instruction(opname='MAKE_CELL', opcode=135, arg=0, argval='a', argrepr='a', offset=0, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='MAKE_CELL', opcode=135, arg=1, argval='b', argrepr='b', offset=2, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=(3, 4), argrepr='(3, 4)', offset=4, starts_line=2, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CLOSURE', opcode=136, arg=0, argval='a', argrepr='a', offset=6, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CLOSURE', opcode=136, arg=1, argval='b', argrepr='b', offset=8, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BUILD_TUPLE', opcode=102, arg=2, argval=2, argrepr='', offset=10, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_f, argrepr=repr(code_object_f), offset=12, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=14, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=16, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=18, starts_line=7, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='a', argrepr='a', offset=20, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='b', argrepr='b', offset=22, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='', argrepr="''", offset=24, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=26, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=28, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=30, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Hello world!', argrepr="'Hello world!'", offset=32, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=7, argval=7, argrepr='', offset=34, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=36, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=38, starts_line=8, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=40, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=4, starts_line=1, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=(3, 4), argrepr='(3, 4)', offset=6, starts_line=2, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CLOSURE', opcode=136, arg=0, argval='a', argrepr='a', offset=8, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CLOSURE', opcode=136, arg=1, argval='b', argrepr='b', offset=10, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BUILD_TUPLE', opcode=102, arg=2, argval=2, argrepr='', offset=12, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=code_object_f, argrepr=repr(code_object_f), offset=14, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=16, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=18, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='NULL + print', offset=20, starts_line=7, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='a', argrepr='a', offset=32, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='b', argrepr='b', offset=34, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval='', argrepr="''", offset=36, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=1, argrepr='1', offset=38, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=40, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=42, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='Hello world!', argrepr="'Hello world!'", offset=44, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=7, argval=7, argrepr='', offset=46, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=56, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=58, starts_line=8, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=60, starts_line=None, is_jump_target=False, positions=None), ] - expected_opinfo_f = [ - Instruction(opname='MAKE_CELL', opcode=135, arg=0, argval='c', argrepr='c', offset=0, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='MAKE_CELL', opcode=135, arg=1, argval='d', argrepr='d', offset=2, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval=(5, 6), argrepr='(5, 6)', offset=4, starts_line=3, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CLOSURE', opcode=136, arg=3, argval='a', argrepr='a', offset=6, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CLOSURE', opcode=136, arg=4, argval='b', argrepr='b', offset=8, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CLOSURE', opcode=136, arg=0, argval='c', argrepr='c', offset=10, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CLOSURE', opcode=136, arg=1, argval='d', argrepr='d', offset=12, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BUILD_TUPLE', opcode=102, arg=4, argval=4, argrepr='', offset=14, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_inner, argrepr=repr(code_object_inner), offset=16, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=18, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=20, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=22, starts_line=5, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='a', argrepr='a', offset=24, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='b', argrepr='b', offset=26, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='c', argrepr='c', offset=28, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='d', argrepr='d', offset=30, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=4, argval=4, argrepr='', offset=32, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=34, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=36, starts_line=6, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=38, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COPY_FREE_VARS', opcode=149, arg=2, argval=2, argrepr='', offset=0, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='MAKE_CELL', opcode=135, arg=0, argval='c', argrepr='c', offset=2, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='MAKE_CELL', opcode=135, arg=1, argval='d', argrepr='d', offset=4, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=6, starts_line=2, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=(5, 6), argrepr='(5, 6)', offset=8, starts_line=3, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CLOSURE', opcode=136, arg=3, argval='a', argrepr='a', offset=10, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CLOSURE', opcode=136, arg=4, argval='b', argrepr='b', offset=12, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CLOSURE', opcode=136, arg=0, argval='c', argrepr='c', offset=14, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CLOSURE', opcode=136, arg=1, argval='d', argrepr='d', offset=16, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BUILD_TUPLE', opcode=102, arg=4, argval=4, argrepr='', offset=18, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=22, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=24, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='NULL + print', offset=26, starts_line=5, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='a', argrepr='a', offset=38, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='b', argrepr='b', offset=40, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='c', argrepr='c', offset=42, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='d', argrepr='d', offset=44, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=4, argval=4, argrepr='', offset=46, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=56, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=58, starts_line=6, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=60, starts_line=None, is_jump_target=False, positions=None), ] expected_opinfo_inner = [ - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=0, starts_line=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=2, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='c', argrepr='c', offset=6, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=5, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='e', argrepr='e', offset=10, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='f', argrepr='f', offset=12, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=6, argval=6, argrepr='', offset=14, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=16, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=18, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=20, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COPY_FREE_VARS', opcode=149, arg=4, argval=4, argrepr='', offset=0, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=2, starts_line=3, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='NULL + print', offset=4, starts_line=4, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=2, argval='a', argrepr='a', offset=16, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='b', argrepr='b', offset=18, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='c', argrepr='c', offset=20, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=5, argval='d', argrepr='d', offset=22, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='e', argrepr='e', offset=24, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='f', argrepr='f', offset=26, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=6, argval=6, argrepr='', offset=28, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=38, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=40, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=42, starts_line=None, is_jump_target=False, positions=None), ] expected_opinfo_jumpy = [ - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='range', argrepr='range', offset=0, starts_line=3, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=2, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=4, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=6, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='FOR_ITER', opcode=93, arg=17, argval=44, argrepr='to 44', offset=8, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=10, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=12, starts_line=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=14, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=16, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=18, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=20, starts_line=5, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=22, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=24, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=15, argval=30, argrepr='to 30', offset=26, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=4, argval=8, argrepr='to 8', offset=28, starts_line=6, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=30, starts_line=7, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=32, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=34, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=21, argval=42, argrepr='to 42', offset=36, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=38, starts_line=8, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=5, argval=52, argrepr='to 52', offset=40, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=4, argval=8, argrepr='to 8', offset=42, starts_line=7, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=44, starts_line=10, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=46, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=48, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=50, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=52, starts_line=11, is_jump_target=True, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=48, argval=96, argrepr='to 96', offset=54, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=56, starts_line=12, is_jump_target=True, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=58, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=60, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=62, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=64, starts_line=13, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=66, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BINARY_OP', opcode=122, arg=23, argval=23, argrepr='-=', offset=68, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=70, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=72, starts_line=14, is_jump_target=False, positions=None), + Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=0, starts_line=1, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='range', argrepr='NULL + range', offset=2, starts_line=3, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=14, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=16, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=26, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='FOR_ITER', opcode=93, arg=28, argval=88, argrepr='to 88', offset=28, starts_line=None, is_jump_target=True, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=32, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=34, starts_line=4, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=46, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=48, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=58, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=60, starts_line=5, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=62, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_AND_BRANCH', opcode=141, arg=13, argval='<', argrepr='<', offset=64, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=1, argval=72, argrepr='to 72', offset=68, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=140, arg=22, argval=28, argrepr='to 28', offset=70, starts_line=6, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=72, starts_line=7, is_jump_target=True, positions=None), Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=74, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=76, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=41, argval=82, argrepr='to 82', offset=78, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=26, argval=52, argrepr='to 52', offset=80, starts_line=15, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=82, starts_line=16, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=84, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=86, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=46, argval=92, argrepr='to 92', offset=88, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=6, argval=104, argrepr='to 104', offset=90, starts_line=17, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=92, starts_line=11, is_jump_target=True, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=28, argval=56, argrepr='to 56', offset=94, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=96, starts_line=19, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=98, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=100, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=102, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=104, starts_line=20, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=106, starts_line=21, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=108, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=110, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=112, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=14, argval=144, argrepr='to 144', offset=114, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=116, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=118, starts_line=22, is_jump_target=False, positions=None), - Instruction(opname='JUMP_IF_NOT_EXC_MATCH', opcode=121, arg=70, argval=140, argrepr='to 140', offset=120, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=122, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=124, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=126, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=128, starts_line=23, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=130, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=132, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=134, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=136, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=33, argval=206, argrepr='to 206', offset=138, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=140, starts_line=22, is_jump_target=True, positions=None), - Instruction(opname='POP_EXCEPT_AND_RERAISE', opcode=37, arg=None, argval=None, argrepr='', offset=142, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=144, starts_line=25, is_jump_target=True, positions=None), - Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=146, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=148, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=150, starts_line=26, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Never reach this', argrepr="'Never reach this'", offset=152, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=154, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=156, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=158, starts_line=25, is_jump_target=False, positions=None), - Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=160, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=162, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=3, argval=3, argrepr='', offset=164, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=166, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=25, argval=220, argrepr='to 220', offset=168, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=170, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=172, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=90, argval=180, argrepr='to 180', offset=174, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=4, argval=4, argrepr='', offset=176, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT_AND_RERAISE', opcode=37, arg=None, argval=None, argrepr='', offset=178, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=180, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=182, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=184, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=186, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=188, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=190, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=192, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=194, starts_line=28, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=196, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=198, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=200, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=202, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=204, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=206, starts_line=23, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=208, starts_line=28, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=210, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=212, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=214, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=216, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=218, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=220, starts_line=25, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=222, starts_line=28, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=224, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=226, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=228, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=230, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=232, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=234, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=236, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=238, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=240, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=242, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=244, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT_AND_RERAISE', opcode=37, arg=None, argval=None, argrepr='', offset=246, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_AND_BRANCH', opcode=141, arg=68, argval='>', argrepr='>', offset=76, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=1, argval=84, argrepr='to 84', offset=80, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=140, arg=28, argval=28, argrepr='to 28', offset=82, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=84, starts_line=8, is_jump_target=True, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=14, argval=116, argrepr='to 116', offset=86, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='END_FOR', opcode=4, arg=None, argval=None, argrepr='', offset=88, starts_line=3, is_jump_target=True, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=90, starts_line=10, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=102, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=104, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=114, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST_CHECK', opcode=127, arg=0, argval='i', argrepr='i', offset=116, starts_line=11, is_jump_target=True, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=33, argval=186, argrepr='to 186', offset=118, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=120, starts_line=12, is_jump_target=True, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=132, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=134, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=144, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=146, starts_line=13, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=148, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BINARY_OP', opcode=122, arg=23, argval=23, argrepr='-=', offset=150, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=154, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=156, starts_line=14, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=158, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_AND_BRANCH', opcode=141, arg=75, argval='>', argrepr='>', offset=160, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=1, argval=168, argrepr='to 168', offset=164, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=140, arg=26, argval=116, argrepr='to 116', offset=166, starts_line=15, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=168, starts_line=16, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=170, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_AND_BRANCH', opcode=141, arg=13, argval='<', argrepr='<', offset=172, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=1, argval=180, argrepr='to 180', offset=176, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=16, argval=212, argrepr='to 212', offset=178, starts_line=17, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=180, starts_line=11, is_jump_target=True, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=1, argval=186, argrepr='to 186', offset=182, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=140, arg=33, argval=120, argrepr='to 120', offset=184, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=186, starts_line=19, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=198, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=200, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=210, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=212, starts_line=20, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=214, starts_line=21, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=216, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=218, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=222, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=224, starts_line=25, is_jump_target=False, positions=None), + Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=226, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=228, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=230, starts_line=26, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=242, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=244, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=254, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=256, starts_line=25, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=258, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=260, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=2, argval=2, argrepr='', offset=262, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=272, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=274, starts_line=28, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=286, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=288, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=298, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=300, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=302, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=304, starts_line=25, is_jump_target=False, positions=None), + Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=306, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=1, argval=312, argrepr='to 312', offset=308, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=310, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=312, starts_line=None, is_jump_target=True, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=314, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=316, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=318, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=140, arg=24, argval=274, argrepr='to 274', offset=320, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=322, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=324, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=326, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=328, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=330, starts_line=22, is_jump_target=False, positions=None), + Instruction(opname='CHECK_EXC_MATCH', opcode=36, arg=None, argval=None, argrepr='', offset=342, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=16, argval=378, argrepr='to 378', offset=344, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=346, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=348, starts_line=23, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=360, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=362, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=372, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=374, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=140, arg=52, argval=274, argrepr='to 274', offset=376, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=378, starts_line=22, is_jump_target=True, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=380, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=382, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=384, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=386, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=388, starts_line=28, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=400, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=402, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=412, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=414, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=416, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=418, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=420, starts_line=None, is_jump_target=False, positions=None), ] # One last piece of inspect fodder to check the default line number handling def simple(): pass expected_opinfo_simple = [ - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=0, starts_line=simple.__code__.co_firstlineno, is_jump_target=False), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=2, starts_line=None, is_jump_target=False) + Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=0, starts_line=simple.__code__.co_firstlineno, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=2, starts_line=None, is_jump_target=False), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=4, starts_line=None, is_jump_target=False) ] @@ -1229,6 +1728,8 @@ class InstructionTests(InstructionTestCase): for instr in dis.get_instructions(code) ] expected = [ + (0, 1, 0, 0), + (1, 1, 0, 1), (1, 1, 0, 1), (2, 2, 2, 3), (2, 2, 5, 6), @@ -1240,32 +1741,61 @@ class InstructionTests(InstructionTestCase): ] self.assertEqual(positions, expected) + named_positions = [ + (pos.lineno, pos.end_lineno, pos.col_offset, pos.end_col_offset) + for pos in positions + ] + self.assertEqual(named_positions, expected) + @requires_debug_ranges() def test_co_positions_missing_info(self): code = compile('x, y, z', '', 'exec') - code_without_column_table = code.replace(co_columntable=b'') - actual = dis.get_instructions(code_without_column_table) + code_without_location_table = code.replace(co_linetable=b'') + actual = dis.get_instructions(code_without_location_table) for instruction in actual: with self.subTest(instruction=instruction): - start_line, end_line, start_offset, end_offset = instruction.positions - assert start_line == 1 - assert end_line == 1 - assert start_offset is None - assert end_offset is None + positions = instruction.positions + self.assertEqual(len(positions), 4) + if instruction.opname == "RESUME": + continue + self.assertIsNone(positions.lineno) + self.assertIsNone(positions.end_lineno) + self.assertIsNone(positions.col_offset) + self.assertIsNone(positions.end_col_offset) - code_without_endline_table = code.replace(co_endlinetable=b'') - actual = dis.get_instructions(code_without_endline_table) - for instruction in actual: - with self.subTest(instruction=instruction): - start_line, end_line, start_offset, end_offset = instruction.positions - assert start_line == 1 - assert end_line is None - assert start_offset is not None - assert end_offset is not None + @requires_debug_ranges() + def test_co_positions_with_lots_of_caches(self): + def roots(a, b, c): + d = b**2 - 4 * a * c + yield (-b - cmath.sqrt(d)) / (2 * a) + if d: + yield (-b + cmath.sqrt(d)) / (2 * a) + code = roots.__code__ + ops = code.co_code[::2] + cache_opcode = opcode.opmap["CACHE"] + caches = sum(op == cache_opcode for op in ops) + non_caches = len(ops) - caches + # Make sure we have "lots of caches". If not, roots should be changed: + assert 1 / 3 <= caches / non_caches, "this test needs more caches!" + for show_caches in (False, True): + for adaptive in (False, True): + with self.subTest(f"{adaptive=}, {show_caches=}"): + co_positions = [ + positions + for op, positions in zip(ops, code.co_positions(), strict=True) + if show_caches or op != cache_opcode + ] + dis_positions = [ + instruction.positions + for instruction in dis.get_instructions( + code, adaptive=adaptive, show_caches=show_caches + ) + ] + self.assertEqual(co_positions, dis_positions) # get_instructions has its own tests above, so can rely on it to validate # the object oriented API -class BytecodeTests(InstructionTestCase): +class BytecodeTests(InstructionTestCase, DisTestBase): def test_instantiation(self): # Test with function, method, code string and code object @@ -1306,7 +1836,7 @@ class BytecodeTests(InstructionTestCase): def test_disassembled(self): actual = dis.Bytecode(_f).dis() - self.assertEqual(actual, dis_f) + self.do_disassembly_compare(actual, dis_f) def test_from_traceback(self): tb = get_tb() @@ -1319,7 +1849,7 @@ class BytecodeTests(InstructionTestCase): self.maxDiff = None tb = get_tb() b = dis.Bytecode.from_traceback(tb) - self.assertEqual(b.dis(), dis_traceback) + self.assertEqual(self.strip_offsets(b.dis()), dis_traceback) @requires_debug_ranges() def test_bytecode_co_positions(self): @@ -1377,8 +1907,18 @@ class TestFinderMethods(unittest.TestCase): res = tuple(dis._find_store_names(code)) self.assertEqual(res, expected) + def test_findlabels(self): + labels = dis.findlabels(jumpy.__code__.co_code) + jumps = [ + instr.offset + for instr in expected_opinfo_jumpy + if instr.is_jump_target + ] -class TestDisTraceback(unittest.TestCase): + self.assertEqual(sorted(labels), sorted(jumps)) + + +class TestDisTraceback(DisTestBase): def setUp(self) -> None: try: # We need to clean up existing tracebacks del sys.last_traceback @@ -1397,16 +1937,18 @@ class TestDisTraceback(unittest.TestCase): dis.distb() def test_distb_last_traceback(self): + self.maxDiff = None # We need to have an existing last traceback in `sys`: tb = get_tb() sys.last_traceback = tb - self.assertEqual(self.get_disassembly(None), dis_traceback) + self.do_disassembly_compare(self.get_disassembly(None), dis_traceback) def test_distb_explicit_arg(self): + self.maxDiff = None tb = get_tb() - self.assertEqual(self.get_disassembly(tb), dis_traceback) + self.do_disassembly_compare(self.get_disassembly(tb), dis_traceback) class TestDisTracebackWithFile(TestDisTraceback): diff --git a/Lib/test/test_distutils.py b/Lib/test/test_distutils.py deleted file mode 100644 index 4b40af02132..00000000000 --- a/Lib/test/test_distutils.py +++ /dev/null @@ -1,28 +0,0 @@ -"""Tests for distutils. - -The tests for distutils are defined in the distutils.tests package; -the test_suite() function there returns a test suite that's ready to -be run. -""" - -import warnings -from test import support -from test.support import warnings_helper - -with warnings_helper.check_warnings( - ("The distutils package is deprecated", DeprecationWarning), quiet=True): - - import distutils.tests - - -def load_tests(*_): - # used by unittest - return distutils.tests.test_suite() - - -def tearDownModule(): - support.reap_children() - - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index 407a14c7ddf..65e215f1cdd 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -4,7 +4,6 @@ Test script for doctest. from test import support from test.support import import_helper -from test.support import os_helper import doctest import functools import os @@ -14,12 +13,17 @@ import importlib.abc import importlib.util import unittest import tempfile -import shutil import types import contextlib + +if not support.has_subprocess_support: + raise unittest.SkipTest("test_CLI requires subprocess support.") + + # NOTE: There are some additional tests relating to interaction with # zipimport in the test_zipimport_support test module. +# There are also related tests in `test_doctest2` module. ###################################################################### ## Sample Objects (used by test cases) @@ -455,7 +459,7 @@ We'll simulate a __file__ attr that ends in pyc: >>> tests = finder.find(sample_func) >>> print(tests) # doctest: +ELLIPSIS - [] + [] The exact name depends on how test_doctest was invoked, so allow for leading path components. @@ -637,6 +641,26 @@ displays. 1 SampleClass.double 1 SampleClass.get +When used with `exclude_empty=False` we are also interested in line numbers +of doctests that are empty. +It used to be broken for quite some time until `bpo-28249`. + + >>> from test import doctest_lineno + >>> tests = doctest.DocTestFinder(exclude_empty=False).find(doctest_lineno) + >>> for t in tests: + ... print('%5s %s' % (t.lineno, t.name)) + None test.doctest_lineno + 22 test.doctest_lineno.ClassWithDocstring + 30 test.doctest_lineno.ClassWithDoctest + None test.doctest_lineno.ClassWithoutDocstring + None test.doctest_lineno.MethodWrapper + 39 test.doctest_lineno.MethodWrapper.method_with_docstring + 45 test.doctest_lineno.MethodWrapper.method_with_doctest + None test.doctest_lineno.MethodWrapper.method_without_docstring + 4 test.doctest_lineno.func_with_docstring + 12 test.doctest_lineno.func_with_doctest + None test.doctest_lineno.func_without_docstring + Turning off Recursion ~~~~~~~~~~~~~~~~~~~~~ DocTestFinder can be told not to look for tests in contained objects @@ -2785,6 +2809,8 @@ in it, and use a package hook to install a custom loader; on any platform, at least one of the line endings will raise a ValueError for inconsistent whitespace if doctest does not correctly do the newline conversion. + >>> from test.support import os_helper + >>> import shutil >>> dn = tempfile.mkdtemp() >>> pkg = os.path.join(dn, "doctest_testpkg") >>> os.mkdir(pkg) @@ -2828,7 +2854,7 @@ except UnicodeEncodeError: # Skip the test: the filesystem encoding is unable to encode the filename supports_unicode = False -if supports_unicode and not support.has_no_debug_ranges(): +if supports_unicode: def test_unicode(): """ Check doctest with a non-ascii filename: @@ -2850,10 +2876,8 @@ Check doctest with a non-ascii filename: Traceback (most recent call last): File ... exec(compile(example.source, filename, "single", - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1, in raise Exception('clé') - ^^^^^^^^^^^^^^^^^^^^^^ Exception: clé TestResults(failed=1, attempted=1) """ @@ -3130,6 +3154,22 @@ def test_no_trailing_whitespace_stripping(): """ +def test_run_doctestsuite_multiple_times(): + """ + It was not possible to run the same DocTestSuite multiple times + http://bugs.python.org/issue2604 + http://bugs.python.org/issue9736 + + >>> import unittest + >>> import test.sample_doctest + >>> suite = doctest.DocTestSuite(test.sample_doctest) + >>> suite.run(unittest.TestResult()) + + >>> suite.run(unittest.TestResult()) + + """ + + def load_tests(loader, tests, pattern): tests.addTest(doctest.DocTestSuite(doctest)) tests.addTest(doctest.DocTestSuite()) diff --git a/Lib/test/test_docxmlrpc.py b/Lib/test/test_docxmlrpc.py index 9a06be45855..2ad422079b7 100644 --- a/Lib/test/test_docxmlrpc.py +++ b/Lib/test/test_docxmlrpc.py @@ -4,6 +4,9 @@ import re import sys import threading import unittest +from test import support + +support.requires_working_socket(module=True) def make_request_and_skipIf(condition, reason): # If we skip the test, we have to make a request because @@ -143,9 +146,9 @@ class DocXMLRPCHTTPGETServer(unittest.TestCase): self.assertIn( (b'
    add(x, y)
    ' b'Add two instances together. This ' - b'follows ' + b'follows ' b'PEP008, but has nothing
    \nto do ' - b'with ' + b'with ' b'RFC1952. Case should matter: pEp008 ' b'and rFC1952.  Things
    \nthat start ' b'with http and ftp should be ' diff --git a/Lib/test/test_dtrace.py b/Lib/test/test_dtrace.py index 3957077f5d6..4b971deacc1 100644 --- a/Lib/test/test_dtrace.py +++ b/Lib/test/test_dtrace.py @@ -6,9 +6,14 @@ import sys import types import unittest +from test import support from test.support import findfile +if not support.has_subprocess_support: + raise unittest.SkipTest("test module requires subprocess") + + def abspath(filename): return os.path.abspath(findfile(filename, subdir="dtracedata")) @@ -170,4 +175,4 @@ class SystemTapOptimizedTests(TraceTests, unittest.TestCase): if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_dynamic.py b/Lib/test/test_dynamic.py index 3ae090fd66a..7e12d428e0f 100644 --- a/Lib/test/test_dynamic.py +++ b/Lib/test/test_dynamic.py @@ -1,6 +1,7 @@ # Test the most dynamic corner cases of Python's runtime semantics. import builtins +import sys import unittest from test.support import swap_item, swap_attr @@ -133,6 +134,63 @@ class RebindBuiltinsTests(unittest.TestCase): self.assertEqual(foo(), 7) + def test_load_global_specialization_failure_keeps_oparg(self): + # https://github.com/python/cpython/issues/91625 + class MyGlobals(dict): + def __missing__(self, key): + return int(key.removeprefix("_number_")) + + # Need more than 256 variables to use EXTENDED_ARGS + variables = 400 + code = "lambda: " + "+".join(f"_number_{i}" for i in range(variables)) + sum_func = eval(code, MyGlobals()) + expected = sum(range(variables)) + # Warm up the the function for quickening (PEP 659) + for _ in range(30): + self.assertEqual(sum_func(), expected) + + +class TestTracing(unittest.TestCase): + + def setUp(self): + self.addCleanup(sys.settrace, sys.gettrace()) + sys.settrace(None) + + def test_after_specialization(self): + + def trace(frame, event, arg): + return trace + + turn_on_trace = False + + class C: + def __init__(self, x): + self.x = x + def __del__(self): + if turn_on_trace: + sys.settrace(trace) + + def f(): + # LOAD_GLOBAL[_BUILTIN] immediately follows the call to C.__del__ + C(0).x, len + + def g(): + # BINARY_SUSCR[_LIST_INT] immediately follows the call to C.__del__ + [0][C(0).x] + + def h(): + # BINARY_OP[_ADD_INT] immediately follows the call to C.__del__ + 0 + C(0).x + + for func in (f, g, h): + with self.subTest(func.__name__): + for _ in range(58): + func() + turn_on_trace = True + func() + sys.settrace(None) + turn_on_trace = False + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_email/data/PyBanner048.gif b/Lib/test/test_email/data/PyBanner048.gif deleted file mode 100644 index 1a5c87f647f..00000000000 Binary files a/Lib/test/test_email/data/PyBanner048.gif and /dev/null differ diff --git a/Lib/test/test_email/data/python.bmp b/Lib/test/test_email/data/python.bmp new file mode 100644 index 00000000000..675f95191a4 Binary files /dev/null and b/Lib/test/test_email/data/python.bmp differ diff --git a/Lib/test/test_email/data/python.exr b/Lib/test/test_email/data/python.exr new file mode 100644 index 00000000000..773c81ee1fb Binary files /dev/null and b/Lib/test/test_email/data/python.exr differ diff --git a/Lib/test/test_email/data/python.gif b/Lib/test/test_email/data/python.gif new file mode 100644 index 00000000000..efa0be3861d Binary files /dev/null and b/Lib/test/test_email/data/python.gif differ diff --git a/Lib/test/test_email/data/python.jpg b/Lib/test/test_email/data/python.jpg new file mode 100644 index 00000000000..21222c09f5a Binary files /dev/null and b/Lib/test/test_email/data/python.jpg differ diff --git a/Lib/test/test_email/data/python.pbm b/Lib/test/test_email/data/python.pbm new file mode 100644 index 00000000000..1848ba7ff06 --- /dev/null +++ b/Lib/test/test_email/data/python.pbm @@ -0,0 +1,3 @@ +P4 +16 16 +ûñ¿úßÕ­±[ñ¥a_ÁX°°ðððð?ÿÿ \ No newline at end of file diff --git a/Lib/test/test_email/data/python.pgm b/Lib/test/test_email/data/python.pgm new file mode 100644 index 00000000000..8349f2a53a9 Binary files /dev/null and b/Lib/test/test_email/data/python.pgm differ diff --git a/Lib/test/test_email/data/python.png b/Lib/test/test_email/data/python.png new file mode 100644 index 00000000000..1a987f79fcd Binary files /dev/null and b/Lib/test/test_email/data/python.png differ diff --git a/Lib/test/test_email/data/python.ppm b/Lib/test/test_email/data/python.ppm new file mode 100644 index 00000000000..7d9cdb32158 Binary files /dev/null and b/Lib/test/test_email/data/python.ppm differ diff --git a/Lib/test/test_email/data/python.ras b/Lib/test/test_email/data/python.ras new file mode 100644 index 00000000000..130e96f817e Binary files /dev/null and b/Lib/test/test_email/data/python.ras differ diff --git a/Lib/test/test_email/data/python.sgi b/Lib/test/test_email/data/python.sgi new file mode 100644 index 00000000000..ffe9081c7a5 Binary files /dev/null and b/Lib/test/test_email/data/python.sgi differ diff --git a/Lib/test/test_email/data/python.tiff b/Lib/test/test_email/data/python.tiff new file mode 100644 index 00000000000..39d0bfcec02 Binary files /dev/null and b/Lib/test/test_email/data/python.tiff differ diff --git a/Lib/test/test_email/data/python.webp b/Lib/test/test_email/data/python.webp new file mode 100644 index 00000000000..e824ec7fb1c Binary files /dev/null and b/Lib/test/test_email/data/python.webp differ diff --git a/Lib/test/test_email/data/python.xbm b/Lib/test/test_email/data/python.xbm new file mode 100644 index 00000000000..cfbee2e9806 --- /dev/null +++ b/Lib/test/test_email/data/python.xbm @@ -0,0 +1,6 @@ +#define python_width 16 +#define python_height 16 +static char python_bits[] = { + 0xDF, 0xFE, 0x8F, 0xFD, 0x5F, 0xFB, 0xAB, 0xFE, 0xB5, 0x8D, 0xDA, 0x8F, + 0xA5, 0x86, 0xFA, 0x83, 0x1A, 0x80, 0x0D, 0x80, 0x0D, 0x80, 0x0F, 0xE0, + 0x0F, 0xF8, 0x0F, 0xF8, 0x0F, 0xFC, 0xFF, 0xFF, }; diff --git a/Lib/test/test_email/data/sndhdr.aifc b/Lib/test/test_email/data/sndhdr.aifc new file mode 100644 index 00000000000..8aae4e730bd Binary files /dev/null and b/Lib/test/test_email/data/sndhdr.aifc differ diff --git a/Lib/test/test_email/data/sndhdr.aiff b/Lib/test/test_email/data/sndhdr.aiff new file mode 100644 index 00000000000..8c279a762f1 Binary files /dev/null and b/Lib/test/test_email/data/sndhdr.aiff differ diff --git a/Lib/test/test_email/data/audiotest.au b/Lib/test/test_email/data/sndhdr.au similarity index 100% rename from Lib/test/test_email/data/audiotest.au rename to Lib/test/test_email/data/sndhdr.au diff --git a/Lib/test/test_email/data/sndhdr.wav b/Lib/test/test_email/data/sndhdr.wav new file mode 100644 index 00000000000..0dca36739cd Binary files /dev/null and b/Lib/test/test_email/data/sndhdr.wav differ diff --git a/Lib/test/test_email/test__encoded_words.py b/Lib/test/test_email/test__encoded_words.py index 0b8b1de3359..1713962f94c 100644 --- a/Lib/test/test_email/test__encoded_words.py +++ b/Lib/test/test_email/test__encoded_words.py @@ -130,6 +130,13 @@ class TestDecode(TestEmailBase): # XXX Should this be a new Defect instead? defects = [errors.CharsetError]) + def test_invalid_character_in_charset(self): + self._test('=?utf-8\udce2\udc80\udc9d?q?foo=ACbar?=', + b'foo\xacbar'.decode('ascii', 'surrogateescape'), + charset = 'utf-8\udce2\udc80\udc9d', + # XXX Should this be a new Defect instead? + defects = [errors.CharsetError]) + def test_q_nonascii(self): self._test('=?utf-8?q?=C3=89ric?=', 'Éric', diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py index 1bdcfa129b4..854f2ff009c 100644 --- a/Lib/test/test_email/test__header_value_parser.py +++ b/Lib/test/test_email/test__header_value_parser.py @@ -395,7 +395,7 @@ class TestParser(TestParserMixin, TestEmailBase): [errors.InvalidHeaderDefect], '') - def test_get_unstructured_invalid_ew(self): + def test_get_unstructured_invalid_ew2(self): self._test_get_x(self._get_unst, '=?utf-8?q?=somevalue?=', '=?utf-8?q?=somevalue?=', diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index 54ffcdc544e..44b405740c4 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -18,24 +18,25 @@ import email import email.policy from email.charset import Charset -from email.header import Header, decode_header, make_header -from email.parser import Parser, HeaderParser from email.generator import Generator, DecodedGenerator, BytesGenerator +from email.header import Header, decode_header, make_header +from email.headerregistry import HeaderRegistry from email.message import Message from email.mime.application import MIMEApplication from email.mime.audio import MIMEAudio -from email.mime.text import MIMEText -from email.mime.image import MIMEImage from email.mime.base import MIMEBase +from email.mime.image import MIMEImage from email.mime.message import MIMEMessage from email.mime.multipart import MIMEMultipart from email.mime.nonmultipart import MIMENonMultipart -from email import utils -from email import errors -from email import encoders -from email import iterators +from email.mime.text import MIMEText +from email.parser import Parser, HeaderParser from email import base64mime +from email import encoders +from email import errors +from email import iterators from email import quoprimime +from email import utils from test.support import threading_helper from test.support.os_helper import unlink @@ -43,7 +44,7 @@ from test.test_email import openfile, TestEmailBase # These imports are documented to work, but we are testing them using a # different path, so we import them here just to make sure they are importable. -from email.parser import FeedParser, BytesFeedParser +from email.parser import FeedParser NL = '\n' EMPTYSTRING = '' @@ -797,7 +798,7 @@ class TestMessageAPI(TestEmailBase): class TestEncoders(unittest.TestCase): def test_EncodersEncode_base64(self): - with openfile('PyBanner048.gif', 'rb') as fp: + with openfile('python.gif', 'rb') as fp: bindata = fp.read() mimed = email.mime.image.MIMEImage(bindata) base64ed = mimed.get_payload() @@ -1514,37 +1515,49 @@ Blah blah blah # Test the basic MIMEAudio class class TestMIMEAudio(unittest.TestCase): - def setUp(self): - with openfile('audiotest.au', 'rb') as fp: + def _make_audio(self, ext): + with openfile(f'sndhdr.{ext}', 'rb') as fp: self._audiodata = fp.read() self._au = MIMEAudio(self._audiodata) def test_guess_minor_type(self): - self.assertEqual(self._au.get_content_type(), 'audio/basic') + for ext, subtype in { + 'aifc': 'x-aiff', + 'aiff': 'x-aiff', + 'wav': 'x-wav', + 'au': 'basic', + }.items(): + self._make_audio(ext) + subtype = ext if subtype is None else subtype + self.assertEqual(self._au.get_content_type(), f'audio/{subtype}') def test_encoding(self): + self._make_audio('au') payload = self._au.get_payload() self.assertEqual(base64.decodebytes(bytes(payload, 'ascii')), - self._audiodata) + self._audiodata) def test_checkSetMinor(self): + self._make_audio('au') au = MIMEAudio(self._audiodata, 'fish') self.assertEqual(au.get_content_type(), 'audio/fish') def test_add_header(self): + self._make_audio('au') eq = self.assertEqual self._au.add_header('Content-Disposition', 'attachment', - filename='audiotest.au') + filename='sndhdr.au') eq(self._au['content-disposition'], - 'attachment; filename="audiotest.au"') + 'attachment; filename="sndhdr.au"') eq(self._au.get_params(header='content-disposition'), - [('attachment', ''), ('filename', 'audiotest.au')]) + [('attachment', ''), ('filename', 'sndhdr.au')]) eq(self._au.get_param('filename', header='content-disposition'), - 'audiotest.au') + 'sndhdr.au') missing = [] eq(self._au.get_param('attachment', header='content-disposition'), '') - self.assertIs(self._au.get_param('foo', failobj=missing, - header='content-disposition'), missing) + self.assertIs(self._au.get_param( + 'foo', failobj=missing, + header='content-disposition'), missing) # Try some missing stuff self.assertIs(self._au.get_param('foobar', missing), missing) self.assertIs(self._au.get_param('attachment', missing, @@ -1554,24 +1567,44 @@ class TestMIMEAudio(unittest.TestCase): # Test the basic MIMEImage class class TestMIMEImage(unittest.TestCase): - def setUp(self): - with openfile('PyBanner048.gif', 'rb') as fp: + def _make_image(self, ext): + with openfile(f'python.{ext}', 'rb') as fp: self._imgdata = fp.read() self._im = MIMEImage(self._imgdata) def test_guess_minor_type(self): - self.assertEqual(self._im.get_content_type(), 'image/gif') + for ext, subtype in { + 'bmp': None, + 'exr': None, + 'gif': None, + 'jpg': 'jpeg', + 'pbm': None, + 'pgm': None, + 'png': None, + 'ppm': None, + 'ras': 'rast', + 'sgi': 'rgb', + 'tiff': None, + 'webp': None, + 'xbm': None, + }.items(): + self._make_image(ext) + subtype = ext if subtype is None else subtype + self.assertEqual(self._im.get_content_type(), f'image/{subtype}') def test_encoding(self): + self._make_image('gif') payload = self._im.get_payload() self.assertEqual(base64.decodebytes(bytes(payload, 'ascii')), - self._imgdata) + self._imgdata) def test_checkSetMinor(self): + self._make_image('gif') im = MIMEImage(self._imgdata, 'fish') self.assertEqual(im.get_content_type(), 'image/fish') def test_add_header(self): + self._make_image('gif') eq = self.assertEqual self._im.add_header('Content-Disposition', 'attachment', filename='dingusfish.gif') @@ -1591,7 +1624,6 @@ class TestMIMEImage(unittest.TestCase): header='foobar'), missing) - # Test the basic MIMEApplication class class TestMIMEApplication(unittest.TestCase): def test_headers(self): @@ -1747,7 +1779,7 @@ class TestMIMEText(unittest.TestCase): # Test complicated multipart/* messages class TestMultipart(TestEmailBase): def setUp(self): - with openfile('PyBanner048.gif', 'rb') as fp: + with openfile('python.gif', 'rb') as fp: data = fp.read() container = MIMEBase('multipart', 'mixed', boundary='BOUNDARY') image = MIMEImage(data, name='dingusfish.gif') @@ -2743,6 +2775,20 @@ message 2 self.assertEqual(str(cm.exception), 'There may be at most 1 To headers in a message') + +# Test the NonMultipart class +class TestNonMultipart(TestEmailBase): + def test_nonmultipart_is_not_multipart(self): + msg = MIMENonMultipart('text', 'plain') + self.assertFalse(msg.is_multipart()) + + def test_attach_raises_exception(self): + msg = Message() + msg['Subject'] = 'subpart 1' + r = MIMENonMultipart('text', 'plain') + self.assertRaises(errors.MultipartConversionError, r.attach, msg) + + # A general test of parser->model->generator idempotency. IOW, read a message # in, parse it into a message object tree, then without touching the tree, # regenerate the plain text. The original text and the transformed text @@ -3001,33 +3047,43 @@ class TestMiscellaneous(TestEmailBase): # parsedate and parsedate_tz will become deprecated interfaces someday def test_parsedate_returns_None_for_invalid_strings(self): - self.assertIsNone(utils.parsedate('')) - self.assertIsNone(utils.parsedate_tz('')) - self.assertIsNone(utils.parsedate(' ')) - self.assertIsNone(utils.parsedate_tz(' ')) - self.assertIsNone(utils.parsedate('0')) - self.assertIsNone(utils.parsedate_tz('0')) - self.assertIsNone(utils.parsedate('A Complete Waste of Time')) - self.assertIsNone(utils.parsedate_tz('A Complete Waste of Time')) - self.assertIsNone(utils.parsedate_tz('Wed, 3 Apr 2002 12.34.56.78+0800')) + # See also test_parsedate_to_datetime_with_invalid_raises_valueerror + # in test_utils. + invalid_dates = [ + '', + ' ', + '0', + 'A Complete Waste of Time', + 'Wed, 3 Apr 2002 12.34.56.78+0800', + '17 June , 2022', + 'Friday, -Nov-82 16:14:55 EST', + 'Friday, Nov--82 16:14:55 EST', + 'Friday, 19-Nov- 16:14:55 EST', + ] + for dtstr in invalid_dates: + with self.subTest(dtstr=dtstr): + self.assertIsNone(utils.parsedate(dtstr)) + self.assertIsNone(utils.parsedate_tz(dtstr)) # Not a part of the spec but, but this has historically worked: self.assertIsNone(utils.parsedate(None)) self.assertIsNone(utils.parsedate_tz(None)) def test_parsedate_compact(self): + self.assertEqual(utils.parsedate_tz('Wed, 3 Apr 2002 14:58:26 +0800'), + (2002, 4, 3, 14, 58, 26, 0, 1, -1, 28800)) # The FWS after the comma is optional - self.assertEqual(utils.parsedate('Wed,3 Apr 2002 14:58:26 +0800'), - utils.parsedate('Wed, 3 Apr 2002 14:58:26 +0800')) + self.assertEqual(utils.parsedate_tz('Wed,3 Apr 2002 14:58:26 +0800'), + (2002, 4, 3, 14, 58, 26, 0, 1, -1, 28800)) + # The comma is optional + self.assertEqual(utils.parsedate_tz('Wed 3 Apr 2002 14:58:26 +0800'), + (2002, 4, 3, 14, 58, 26, 0, 1, -1, 28800)) def test_parsedate_no_dayofweek(self): - eq = self.assertEqual - eq(utils.parsedate_tz('25 Feb 2003 13:47:26 -0800'), - (2003, 2, 25, 13, 47, 26, 0, 1, -1, -28800)) - - def test_parsedate_compact_no_dayofweek(self): eq = self.assertEqual eq(utils.parsedate_tz('5 Feb 2003 13:47:26 -0800'), (2003, 2, 5, 13, 47, 26, 0, 1, -1, -28800)) + eq(utils.parsedate_tz('February 5, 2003 13:47:26 -0800'), + (2003, 2, 5, 13, 47, 26, 0, 1, -1, -28800)) def test_parsedate_no_space_before_positive_offset(self): self.assertEqual(utils.parsedate_tz('Wed, 3 Apr 2002 14:58:26+0800'), @@ -3038,7 +3094,6 @@ class TestMiscellaneous(TestEmailBase): self.assertEqual(utils.parsedate_tz('Wed, 3 Apr 2002 14:58:26-0800'), (2002, 4, 3, 14, 58, 26, 0, 1, -1, -28800)) - def test_parsedate_accepts_time_with_dots(self): eq = self.assertEqual eq(utils.parsedate_tz('5 Feb 2003 13.47.26 -0800'), @@ -3046,6 +3101,20 @@ class TestMiscellaneous(TestEmailBase): eq(utils.parsedate_tz('5 Feb 2003 13.47 -0800'), (2003, 2, 5, 13, 47, 0, 0, 1, -1, -28800)) + def test_parsedate_rfc_850(self): + self.assertEqual(utils.parsedate_tz('Friday, 19-Nov-82 16:14:55 EST'), + (1982, 11, 19, 16, 14, 55, 0, 1, -1, -18000)) + + def test_parsedate_no_seconds(self): + self.assertEqual(utils.parsedate_tz('Wed, 3 Apr 2002 14:58 +0800'), + (2002, 4, 3, 14, 58, 0, 0, 1, -1, 28800)) + + def test_parsedate_dot_time_delimiter(self): + self.assertEqual(utils.parsedate_tz('Wed, 3 Apr 2002 14.58.26 +0800'), + (2002, 4, 3, 14, 58, 26, 0, 1, -1, 28800)) + self.assertEqual(utils.parsedate_tz('Wed, 3 Apr 2002 14.58 +0800'), + (2002, 4, 3, 14, 58, 0, 0, 1, -1, 28800)) + def test_parsedate_acceptable_to_time_functions(self): eq = self.assertEqual timetup = utils.parsedate('5 Feb 2003 13:47:26 -0800') @@ -3271,6 +3340,7 @@ Foo addrs = utils.getaddresses([Header('Al Person ')]) self.assertEqual(addrs[0][1], 'aperson@dom.ain') + @threading_helper.requires_working_threading() def test_make_msgid_collisions(self): # Test make_msgid uniqueness, even with multiple threads class MsgidsThread(Thread): @@ -3427,9 +3497,9 @@ multipart/report self.assertEqual(s.getvalue(), msgtxt) def test_mime_classes_policy_argument(self): - with openfile('audiotest.au', 'rb') as fp: + with openfile('sndhdr.au', 'rb') as fp: audiodata = fp.read() - with openfile('PyBanner048.gif', 'rb') as fp: + with openfile('python.gif', 'rb') as fp: bindata = fp.read() classes = [ (MIMEApplication, ('',)), @@ -5309,6 +5379,15 @@ Content-Disposition: inline; Content-Transfer-Encoding: 8bit Content-Disposition: inline; filename*=X-UNKNOWN''myfile.txt +""" + msg = email.message_from_string(m) + self.assertEqual(msg.get_filename(), 'myfile.txt') + + def test_rfc2231_bad_character_in_encoding(self): + m = """\ +Content-Transfer-Encoding: 8bit +Content-Disposition: inline; filename*=utf-8\udce2\udc80\udc9d''myfile.txt + """ msg = email.message_from_string(m) self.assertEqual(msg.get_filename(), 'myfile.txt') @@ -5485,7 +5564,12 @@ class TestSigned(TestEmailBase): result = fp.getvalue() self._signed_parts_eq(original, result) - +class TestHeaderRegistry(TestEmailBase): + # See issue gh-93010. + def test_HeaderRegistry(self): + reg = HeaderRegistry() + a = reg('Content-Disposition', 'attachment; 0*00="foo"') + self.assertIsInstance(a.defects[0], errors.InvalidHeaderDefect) if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_email/test_headerregistry.py b/Lib/test/test_email/test_headerregistry.py index 59fcd932e0e..25347ef13c2 100644 --- a/Lib/test/test_email/test_headerregistry.py +++ b/Lib/test/test_email/test_headerregistry.py @@ -714,6 +714,18 @@ class TestContentTypeHeader(TestHeaderBase): " charset*=unknown-8bit''utf-8%E2%80%9D\n", ), + 'rfc2231_nonascii_in_charset_of_charset_parameter_value': ( + "text/plain; charset*=utf-8â€''utf-8%E2%80%9D", + 'text/plain', + 'text', + 'plain', + {'charset': 'utf-8â€'}, + [], + 'text/plain; charset="utf-8â€"', + "Content-Type: text/plain;" + " charset*=utf-8''utf-8%E2%80%9D\n", + ), + 'rfc2231_encoded_then_unencoded_segments': ( ('application/x-foo;' '\tname*0*="us-ascii\'en-us\'My";' diff --git a/Lib/test/test_email/test_utils.py b/Lib/test/test_email/test_utils.py index e3d3eaebc93..78afb358035 100644 --- a/Lib/test/test_email/test_utils.py +++ b/Lib/test/test_email/test_utils.py @@ -49,12 +49,21 @@ class DateTimeTests(unittest.TestCase): self.naive_dt) def test_parsedate_to_datetime_with_invalid_raises_valueerror(self): - invalid_dates = ['', - '0', - 'A Complete Waste of Time' - 'Tue, 06 Jun 2017 27:39:33 +0600', - 'Tue, 06 Jun 2017 07:39:33 +2600', - 'Tue, 06 Jun 2017 27:39:33'] + # See also test_parsedate_returns_None_for_invalid_strings in test_email. + invalid_dates = [ + '', + ' ', + '0', + 'A Complete Waste of Time', + 'Wed, 3 Apr 2002 12.34.56.78+0800' + 'Tue, 06 Jun 2017 27:39:33 +0600', + 'Tue, 06 Jun 2017 07:39:33 +2600', + 'Tue, 06 Jun 2017 27:39:33', + '17 June , 2022', + 'Friday, -Nov-82 16:14:55 EST', + 'Friday, Nov--82 16:14:55 EST', + 'Friday, 19-Nov- 16:14:55 EST', + ] for dtstr in invalid_dates: with self.subTest(dtstr=dtstr): self.assertRaises(ValueError, utils.parsedate_to_datetime, dtstr) diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index e1af15dd70f..4d422da5b99 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -2,6 +2,7 @@ from test import support from test.support import import_helper from test.support import os_helper +from test.support import requires_specialization import unittest from collections import namedtuple @@ -13,13 +14,15 @@ import re import shutil import subprocess import sys +import sysconfig import tempfile import textwrap +if not support.has_subprocess_support: + raise unittest.SkipTest("test module requires subprocess") MS_WINDOWS = (os.name == 'nt') MACOS = (sys.platform == 'darwin') - PYMEM_ALLOCATOR_NOT_SET = 0 PYMEM_ALLOCATOR_DEBUG = 2 PYMEM_ALLOCATOR_MALLOC = 3 @@ -31,7 +34,7 @@ API_PYTHON = 2 # _PyCoreConfig_InitIsolatedConfig() API_ISOLATED = 3 -INIT_LOOPS = 16 +INIT_LOOPS = 4 MAX_HASH_SEED = 4294967295 @@ -65,18 +68,16 @@ class EmbeddingTestsMixin: ext = ("_d" if debug_build(sys.executable) else "") + ".exe" exename += ext exepath = builddir - expecteddir = support.REPO_ROOT else: exepath = os.path.join(builddir, 'Programs') - expecteddir = os.path.join(support.REPO_ROOT, 'Programs') self.test_exe = exe = os.path.join(exepath, exename) - if exepath != expecteddir or not os.path.exists(exe): + if not os.path.exists(exe): self.skipTest("%r doesn't exist" % exe) # This is needed otherwise we get a fatal error: # "Py_Initialize: Unable to get the locale encoding # LookupError: no codec search functions registered: can't find encoding" self.oldcwd = os.getcwd() - os.chdir(support.REPO_ROOT) + os.chdir(builddir) def tearDown(self): os.chdir(self.oldcwd) @@ -283,7 +284,7 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase): "test_pre_initialization_sys_options", env=env) expected_output = ( "sys.warnoptions: ['once', 'module', 'default']\n" - "sys._xoptions: {'dev': '2', 'utf8': '1'}\n" + "sys._xoptions: {'not_an_option': '1', 'also_not_an_option': '2'}\n" "warnings.filters[:3]: ['default', 'module', 'once']\n" ) self.assertIn(expected_output, out) @@ -328,6 +329,68 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase): self.assertEqual(out, "Py_RunMain(): sys.argv=['-c', 'arg2']\n" * nloop) self.assertEqual(err, '') + def test_finalize_structseq(self): + # bpo-46417: Py_Finalize() clears structseq static types. Check that + # sys attributes using struct types still work when + # Py_Finalize()/Py_Initialize() is called multiple times. + # print() calls type->tp_repr(instance) and so checks that the types + # are still working properly. + script = support.findfile('_test_embed_structseq.py') + with open(script, encoding="utf-8") as fp: + code = fp.read() + out, err = self.run_embedded_interpreter("test_repeated_init_exec", code) + self.assertEqual(out, 'Tests passed\n' * INIT_LOOPS) + + def test_simple_initialization_api(self): + # _testembed now uses Py_InitializeFromConfig by default + # This case specifically checks Py_Initialize(Ex) still works + out, err = self.run_embedded_interpreter("test_repeated_simple_init") + self.assertEqual(out, 'Finalized\n' * INIT_LOOPS) + + @requires_specialization + def test_specialized_static_code_gets_unspecialized_at_Py_FINALIZE(self): + # https://github.com/python/cpython/issues/92031 + + code = textwrap.dedent("""\ + import dis + import importlib._bootstrap + import opcode + import test.test_dis + + def is_specialized(f): + for instruction in dis.get_instructions(f, adaptive=True): + opname = instruction.opname + if ( + opname in opcode._specialized_instructions + # Exclude superinstructions: + and "__" not in opname + ): + return True + return False + + func = importlib._bootstrap._handle_fromlist + + # "copy" the code to un-specialize it: + func.__code__ = func.__code__.replace() + + assert not is_specialized(func), "specialized instructions found" + + for i in range(test.test_dis.ADAPTIVE_WARMUP_DELAY): + func(importlib._bootstrap, ["x"], lambda *args: None) + + assert is_specialized(func), "no specialized instructions found" + + print("Tests passed") + """) + run = self.run_embedded_interpreter + out, err = run("test_repeated_init_exec", code) + self.assertEqual(out, 'Tests passed\n' * INIT_LOOPS) + + def test_ucnhash_capi_reset(self): + # bpo-47182: unicodeobject.c:ucnhash_capi was not reset on shutdown. + code = "print('\\N{digit nine}')" + out, err = self.run_embedded_interpreter("test_repeated_init_exec", code) + self.assertEqual(out, '9\n' * INIT_LOOPS) class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): maxDiff = 4096 @@ -383,10 +446,12 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'install_signal_handlers': 1, 'use_hash_seed': 0, 'hash_seed': 0, + 'int_max_str_digits': sys.int_info.default_max_str_digits, 'faulthandler': 0, 'tracemalloc': 0, + 'perf_profiling': 0, 'import_time': 0, - 'no_debug_ranges': 0, + 'code_debug_ranges': 1, 'show_ref_count': 0, 'dump_refs': 0, 'malloc_stats': 0, @@ -443,8 +508,9 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'check_hash_pycs_mode': 'default', 'pathconfig_warnings': 1, '_init_main': 1, - '_isolated_interpreter': 0, - 'use_frozen_modules': 1, + 'use_frozen_modules': not support.Py_DEBUG, + 'safe_path': 0, + '_is_python_build': IGNORE_CONFIG, } if MS_WINDOWS: CONFIG_COMPAT.update({ @@ -461,11 +527,13 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): isolated=1, use_environment=0, user_site_directory=0, + safe_path=1, dev_mode=0, install_signal_handlers=0, use_hash_seed=0, faulthandler=0, tracemalloc=0, + perf_profiling=0, pathconfig_warnings=0, ) if MS_WINDOWS: @@ -508,32 +576,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): ('Py_LegacyWindowsStdioFlag', 'legacy_windows_stdio'), )) - # path config - if MS_WINDOWS: - PATH_CONFIG = { - 'isolated': -1, - 'site_import': -1, - 'python3_dll': GET_DEFAULT_CONFIG, - } - else: - PATH_CONFIG = {} - # other keys are copied by COPY_PATH_CONFIG - - COPY_PATH_CONFIG = [ - # Copy core config to global config for expected values - 'prefix', - 'exec_prefix', - 'program_name', - 'home', - 'stdlib_dir', - # program_full_path and module_search_path are copied indirectly from - # the core configuration in check_path_config(). - ] - if MS_WINDOWS: - COPY_PATH_CONFIG.extend(( - 'base_executable', - )) - EXPECTED_CONFIG = None @classmethod @@ -599,8 +641,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): return configs def get_expected_config(self, expected_preconfig, expected, - expected_pathconfig, env, api, - modify_path_cb=None): + env, api, modify_path_cb=None): configs = self._get_expected_config() pre_config = configs['pre_config'] @@ -608,11 +649,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): if value is self.GET_DEFAULT_CONFIG: expected_preconfig[key] = pre_config[key] - path_config = configs['path_config'] - for key, value in expected_pathconfig.items(): - if value is self.GET_DEFAULT_CONFIG: - expected_pathconfig[key] = path_config[key] - if not expected_preconfig['configure_locale'] or api == API_COMPAT: # there is no easy way to get the locale encoding before # setlocale(LC_CTYPE, "") is called: don't test encodings @@ -677,6 +713,13 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): def check_config(self, configs, expected): config = dict(configs['config']) + if MS_WINDOWS: + value = config.get(key := 'program_name') + if value and isinstance(value, str): + value = value[:len(value.lower().removesuffix('.exe'))] + if debug_build(sys.executable): + value = value[:len(value.lower().removesuffix('_d'))] + config[key] = value for key, value in list(expected.items()): if value is self.IGNORE_CONFIG: config.pop(key, None) @@ -705,18 +748,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): self.assertEqual(configs['global_config'], expected) - def check_path_config(self, configs, expected): - config = configs['config'] - - for key in self.COPY_PATH_CONFIG: - expected[key] = config[key] - expected['module_search_path'] = os.path.pathsep.join(config['module_search_paths']) - expected['program_full_path'] = config['executable'] - - self.assertEqual(configs['path_config'], expected) - def check_all_configs(self, testname, expected_config=None, - expected_preconfig=None, expected_pathconfig=None, + expected_preconfig=None, modify_path_cb=None, stderr=None, *, api, preconfig_api=None, env=None, ignore_stderr=False, cwd=None): @@ -740,10 +773,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): if expected_config is None: expected_config = {} - if expected_pathconfig is None: - expected_pathconfig = {} - expected_pathconfig = dict(self.PATH_CONFIG, **expected_pathconfig) - if api == API_PYTHON: default_config = self.CONFIG_PYTHON elif api == API_ISOLATED: @@ -754,7 +783,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): self.get_expected_config(expected_preconfig, expected_config, - expected_pathconfig, env, api, modify_path_cb) @@ -772,7 +800,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): self.check_pre_config(configs, expected_preconfig) self.check_config(configs, expected_config) self.check_global_config(configs) - self.check_path_config(configs, expected_pathconfig) return configs def test_init_default_config(self): @@ -817,8 +844,9 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'use_hash_seed': 1, 'hash_seed': 123, 'tracemalloc': 2, + 'perf_profiling': 0, 'import_time': 1, - 'no_debug_ranges': 1, + 'code_debug_ranges': 0, 'show_ref_count': 1, 'malloc_stats': 1, @@ -830,14 +858,15 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'argv': ['-c', 'arg2'], 'orig_argv': ['python3', '-W', 'cmdline_warnoption', - '-X', 'dev', + '-X', 'cmdline_xoption', '-c', 'pass', 'arg2'], 'parse_argv': 2, 'xoptions': [ - 'dev=3', - 'utf8', - 'dev', + 'config_xoption1=3', + 'config_xoption2=', + 'config_xoption3', + 'cmdline_xoption', ], 'warnoptions': [ 'cmdline_warnoption', @@ -860,11 +889,11 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'faulthandler': 1, 'platlibdir': 'my_platlibdir', 'module_search_paths': self.IGNORE_CONFIG, + 'safe_path': 1, + 'int_max_str_digits': 31337, 'check_hash_pycs_mode': 'always', 'pathconfig_warnings': 0, - - '_isolated_interpreter': 1, } self.check_all_configs("test_init_from_config", config, preconfig, api=API_COMPAT) @@ -877,8 +906,9 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'use_hash_seed': 1, 'hash_seed': 42, 'tracemalloc': 2, + 'perf_profiling': 0, 'import_time': 1, - 'no_debug_ranges': 1, + 'code_debug_ranges': 0, 'malloc_stats': 1, 'inspect': 1, 'optimization_level': 2, @@ -894,6 +924,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'warnoptions': ['EnvVar'], 'platlibdir': 'env_platlibdir', 'module_search_paths': self.IGNORE_CONFIG, + 'safe_path': 1, + 'int_max_str_digits': 4567, } self.check_all_configs("test_init_compat_env", config, preconfig, api=API_COMPAT) @@ -907,8 +939,9 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'use_hash_seed': 1, 'hash_seed': 42, 'tracemalloc': 2, + 'perf_profiling': 0, 'import_time': 1, - 'no_debug_ranges': 1, + 'code_debug_ranges': 0, 'malloc_stats': 1, 'inspect': 1, 'optimization_level': 2, @@ -924,6 +957,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'warnoptions': ['EnvVar'], 'platlibdir': 'env_platlibdir', 'module_search_paths': self.IGNORE_CONFIG, + 'safe_path': 1, + 'int_max_str_digits': 4567, } self.check_all_configs("test_init_python_env", config, preconfig, api=API_PYTHON) @@ -964,12 +999,13 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): } config = { 'argv': ['script.py'], - 'orig_argv': ['python3', '-X', 'dev', 'script.py'], + 'orig_argv': ['python3', '-X', 'dev', '-P', 'script.py'], 'run_filename': os.path.abspath('script.py'), 'dev_mode': 1, 'faulthandler': 1, 'warnoptions': ['default'], 'xoptions': ['dev'], + 'safe_path': 1, } self.check_all_configs("test_preinit_parse_argv", config, preconfig, api=API_PYTHON) @@ -980,7 +1016,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'isolated': 0, } argv = ["python3", - "-E", "-I", + "-E", "-I", "-P", "-X", "dev", "-X", "utf8", "script.py"] @@ -995,6 +1031,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): def test_init_isolated_flag(self): config = { 'isolated': 1, + 'safe_path': 1, 'use_environment': 0, 'user_site_directory': 0, } @@ -1004,6 +1041,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): # _PyPreConfig.isolated=1, _PyCoreConfig.isolated not set config = { 'isolated': 1, + 'safe_path': 1, 'use_environment': 0, 'user_site_directory': 0, } @@ -1013,6 +1051,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): # _PyPreConfig.isolated=0, _PyCoreConfig.isolated=1 config = { 'isolated': 1, + 'safe_path': 1, 'use_environment': 0, 'user_site_directory': 0, } @@ -1039,10 +1078,13 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): self.check_all_configs("test_init_dont_configure_locale", {}, preconfig, api=API_PYTHON) + @unittest.skip('as of 3.11 this test no longer works because ' + 'path calculations do not occur on read') def test_init_read_set(self): config = { 'program_name': './init_read_set', 'executable': 'my_executable', + 'base_executable': 'my_executable', } def modify_path(path): path.insert(1, "test_path_insert1") @@ -1055,8 +1097,9 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): config = { 'faulthandler': 1, 'xoptions': [ - 'dev', - 'utf8', + 'config_xoption', + 'cmdline_xoption', + 'sysadd_xoption', 'faulthandler', ], 'warnoptions': [ @@ -1066,12 +1109,9 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): ], 'orig_argv': ['python3', '-W', 'ignore:::cmdline_warnoption', - '-X', 'utf8'], + '-X', 'cmdline_xoption'], } - preconfig = {'utf8_mode': 1} - self.check_all_configs("test_init_sys_add", config, - expected_preconfig=preconfig, - api=API_PYTHON) + self.check_all_configs("test_init_sys_add", config, api=API_PYTHON) def test_init_run_main(self): code = ('import _testinternalcapi, json; ' @@ -1156,7 +1196,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): # The current getpath.c doesn't determine the stdlib dir # in this case. 'stdlib_dir': '', - 'use_frozen_modules': -1, } self.default_program_name(config) env = {'TESTPATH': os.path.pathsep.join(paths)} @@ -1180,7 +1219,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): # The current getpath.c doesn't determine the stdlib dir # in this case. 'stdlib_dir': '', - 'use_frozen_modules': -1, + 'use_frozen_modules': not support.Py_DEBUG, # overridden by PyConfig 'program_name': 'conf_program_name', 'base_executable': 'conf_executable', @@ -1210,30 +1249,24 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): ] @contextlib.contextmanager - def tmpdir_with_python(self): + def tmpdir_with_python(self, subdir=None): # Temporary directory with a copy of the Python program with tempfile.TemporaryDirectory() as tmpdir: # bpo-38234: On macOS and FreeBSD, the temporary directory # can be symbolic link. For example, /tmp can be a symbolic link # to /var/tmp. Call realpath() to resolve all symbolic links. tmpdir = os.path.realpath(tmpdir) + if subdir: + tmpdir = os.path.normpath(os.path.join(tmpdir, subdir)) + os.makedirs(tmpdir) if MS_WINDOWS: # Copy pythonXY.dll (or pythonXY_d.dll) - ver = sys.version_info - dll = f'python{ver.major}{ver.minor}' - dll3 = f'python{ver.major}' - if debug_build(sys.executable): - dll += '_d' - dll3 += '_d' - dll += '.dll' - dll3 += '.dll' - dll = os.path.join(os.path.dirname(self.test_exe), dll) - dll3 = os.path.join(os.path.dirname(self.test_exe), dll3) - dll_copy = os.path.join(tmpdir, os.path.basename(dll)) - dll3_copy = os.path.join(tmpdir, os.path.basename(dll3)) - shutil.copyfile(dll, dll_copy) - shutil.copyfile(dll3, dll3_copy) + import fnmatch + exedir = os.path.dirname(self.test_exe) + for f in os.listdir(exedir): + if fnmatch.fnmatch(f, '*.dll'): + shutil.copyfile(os.path.join(exedir, f), os.path.join(tmpdir, f)) # Copy Python program exec_copy = os.path.join(tmpdir, os.path.basename(self.test_exe)) @@ -1260,11 +1293,14 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): prefix = exec_prefix = home if MS_WINDOWS: - stdlib = os.path.join(home, sys.platlibdir) + stdlib = os.path.join(home, "Lib") + # Because we are specifying 'home', module search paths + # are fairly static + expected_paths = [paths[0], os.path.join(home, 'DLLs'), stdlib] else: version = f'{sys.version_info.major}.{sys.version_info.minor}' stdlib = os.path.join(home, sys.platlibdir, f'python{version}') - expected_paths = self.module_search_paths(prefix=home, exec_prefix=home) + expected_paths = self.module_search_paths(prefix=home, exec_prefix=home) config = { 'home': home, @@ -1277,12 +1313,70 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'stdlib_dir': stdlib, } self.default_program_name(config) - if not config['executable']: - config['use_frozen_modules'] = -1 env = {'TESTHOME': home, 'PYTHONPATH': paths_str} self.check_all_configs("test_init_setpythonhome", config, api=API_COMPAT, env=env) + def test_init_is_python_build_with_home(self): + # Test _Py_path_config._is_python_build configuration (gh-91985) + config = self._get_expected_config() + paths = config['config']['module_search_paths'] + paths_str = os.path.pathsep.join(paths) + + for path in paths: + if not os.path.isdir(path): + continue + if os.path.exists(os.path.join(path, 'os.py')): + home = os.path.dirname(path) + break + else: + self.fail(f"Unable to find home in {paths!r}") + + prefix = exec_prefix = home + if MS_WINDOWS: + stdlib = os.path.join(home, "Lib") + # Because we are specifying 'home', module search paths + # are fairly static + expected_paths = [paths[0], os.path.join(home, 'DLLs'), stdlib] + else: + version = f'{sys.version_info.major}.{sys.version_info.minor}' + stdlib = os.path.join(home, sys.platlibdir, f'python{version}') + expected_paths = self.module_search_paths(prefix=home, exec_prefix=home) + + config = { + 'home': home, + 'module_search_paths': expected_paths, + 'prefix': prefix, + 'base_prefix': prefix, + 'exec_prefix': exec_prefix, + 'base_exec_prefix': exec_prefix, + 'pythonpath_env': paths_str, + 'stdlib_dir': stdlib, + } + # The code above is taken from test_init_setpythonhome() + env = {'TESTHOME': home, 'PYTHONPATH': paths_str} + + env['NEGATIVE_ISPYTHONBUILD'] = '1' + config['_is_python_build'] = 0 + self.check_all_configs("test_init_is_python_build", config, + api=API_COMPAT, env=env) + + env['NEGATIVE_ISPYTHONBUILD'] = '0' + config['_is_python_build'] = 1 + exedir = os.path.dirname(sys.executable) + with open(os.path.join(exedir, 'pybuilddir.txt'), encoding='utf8') as f: + expected_paths[1 if MS_WINDOWS else 2] = os.path.normpath( + os.path.join(exedir, f'{f.read()}\n$'.splitlines()[0])) + if not MS_WINDOWS: + # PREFIX (default) is set when running in build directory + prefix = exec_prefix = sys.prefix + # stdlib calculation (/Lib) is not yet supported + expected_paths[0] = self.module_search_paths(prefix=prefix)[0] + config.update(prefix=prefix, base_prefix=prefix, + exec_prefix=exec_prefix, base_exec_prefix=exec_prefix) + self.check_all_configs("test_init_is_python_build", config, + api=API_COMPAT, env=env) + def copy_paths_by_env(self, config): all_configs = self._get_expected_config() paths = all_configs['config']['module_search_paths'] @@ -1291,15 +1385,18 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): env = {'PYTHONPATH': paths_str} return env - @unittest.skipIf(MS_WINDOWS, 'Windows does not use pybuilddir.txt') + @unittest.skipIf(MS_WINDOWS, 'See test_init_pybuilddir_win32') def test_init_pybuilddir(self): # Test path configuration with pybuilddir.txt configuration file with self.tmpdir_with_python() as tmpdir: # pybuilddir.txt is a sub-directory relative to the current # directory (tmpdir) + vpath = sysconfig.get_config_var("VPATH") or '' subdir = 'libdir' libdir = os.path.join(tmpdir, subdir) + # The stdlib dir is dirname(executable) + VPATH + 'Lib' + stdlibdir = os.path.normpath(os.path.join(tmpdir, vpath, 'Lib')) os.mkdir(libdir) filename = os.path.join(tmpdir, 'pybuilddir.txt') @@ -1307,21 +1404,63 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): fp.write(subdir) module_search_paths = self.module_search_paths() + module_search_paths[-2] = stdlibdir module_search_paths[-1] = libdir executable = self.test_exe config = { + 'base_exec_prefix': sysconfig.get_config_var("exec_prefix"), + 'base_prefix': sysconfig.get_config_var("prefix"), 'base_executable': executable, 'executable': executable, 'module_search_paths': module_search_paths, - 'stdlib_dir': STDLIB_INSTALL, - 'use_frozen_modules': 1 if STDLIB_INSTALL else -1, + 'stdlib_dir': stdlibdir, } env = self.copy_paths_by_env(config) self.check_all_configs("test_init_compat_config", config, api=API_COMPAT, env=env, ignore_stderr=True, cwd=tmpdir) + @unittest.skipUnless(MS_WINDOWS, 'See test_init_pybuilddir') + def test_init_pybuilddir_win32(self): + # Test path configuration with pybuilddir.txt configuration file + + vpath = sysconfig.get_config_var("VPATH") + subdir = r'PCbuild\arch' + if os.path.normpath(vpath).count(os.sep) == 2: + subdir = os.path.join(subdir, 'instrumented') + + with self.tmpdir_with_python(subdir) as tmpdir: + # The prefix is dirname(executable) + VPATH + prefix = os.path.normpath(os.path.join(tmpdir, vpath)) + # The stdlib dir is dirname(executable) + VPATH + 'Lib' + stdlibdir = os.path.normpath(os.path.join(tmpdir, vpath, 'Lib')) + + filename = os.path.join(tmpdir, 'pybuilddir.txt') + with open(filename, "w", encoding="utf8") as fp: + fp.write(tmpdir) + + module_search_paths = self.module_search_paths() + module_search_paths[-3] = os.path.join(tmpdir, os.path.basename(module_search_paths[-3])) + module_search_paths[-2] = tmpdir + module_search_paths[-1] = stdlibdir + + executable = self.test_exe + config = { + 'base_exec_prefix': prefix, + 'base_prefix': prefix, + 'base_executable': executable, + 'executable': executable, + 'prefix': prefix, + 'exec_prefix': prefix, + 'module_search_paths': module_search_paths, + 'stdlib_dir': stdlibdir, + } + env = self.copy_paths_by_env(config) + self.check_all_configs("test_init_compat_config", config, + api=API_COMPAT, env=env, + ignore_stderr=False, cwd=tmpdir) + def test_init_pyvenv_cfg(self): # Test path configuration with pyvenv.cfg configuration file @@ -1336,12 +1475,12 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'lib-dynload') os.makedirs(lib_dynload) else: - lib_dynload = os.path.join(pyvenv_home, 'lib') - os.makedirs(lib_dynload) - # getpathp.c uses Lib\os.py as the LANDMARK + lib_folder = os.path.join(pyvenv_home, 'Lib') + os.makedirs(lib_folder) + # getpath.py uses Lib\os.py as the LANDMARK shutil.copyfile( os.path.join(support.STDLIB_DIR, 'os.py'), - os.path.join(lib_dynload, 'os.py'), + os.path.join(lib_folder, 'os.py'), ) filename = os.path.join(tmpdir, 'pyvenv.cfg') @@ -1353,48 +1492,67 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): if not MS_WINDOWS: paths[-1] = lib_dynload else: - for index, path in enumerate(paths): - if index == 0: - paths[index] = os.path.join(tmpdir, os.path.basename(path)) - else: - paths[index] = os.path.join(pyvenv_home, os.path.basename(path)) - paths[-1] = pyvenv_home + paths = [ + os.path.join(tmpdir, os.path.basename(paths[0])), + pyvenv_home, + os.path.join(pyvenv_home, "Lib"), + ] executable = self.test_exe + base_executable = os.path.join(pyvenv_home, os.path.basename(executable)) exec_prefix = pyvenv_home config = { + 'base_prefix': sysconfig.get_config_var("prefix"), 'base_exec_prefix': exec_prefix, 'exec_prefix': exec_prefix, - 'base_executable': executable, + 'base_executable': base_executable, 'executable': executable, 'module_search_paths': paths, } - path_config = {} if MS_WINDOWS: config['base_prefix'] = pyvenv_home config['prefix'] = pyvenv_home - config['stdlib_dir'] = os.path.join(pyvenv_home, 'lib') - config['use_frozen_modules'] = 1 - - ver = sys.version_info - dll = f'python{ver.major}' - if debug_build(executable): - dll += '_d' - dll += '.DLL' - dll = os.path.join(os.path.dirname(executable), dll) - path_config['python3_dll'] = dll + config['stdlib_dir'] = os.path.join(pyvenv_home, 'Lib') + config['use_frozen_modules'] = int(not support.Py_DEBUG) else: - # The current getpath.c doesn't determine the stdlib dir - # in this case. - config['stdlib_dir'] = STDLIB_INSTALL - config['use_frozen_modules'] = 1 if STDLIB_INSTALL else -1 + # cannot reliably assume stdlib_dir here because it + # depends too much on our build. But it ought to be found + config['stdlib_dir'] = self.IGNORE_CONFIG + config['use_frozen_modules'] = int(not support.Py_DEBUG) env = self.copy_paths_by_env(config) self.check_all_configs("test_init_compat_config", config, - expected_pathconfig=path_config, api=API_COMPAT, env=env, ignore_stderr=True, cwd=tmpdir) + @unittest.skipUnless(MS_WINDOWS, 'specific to Windows') + def test_getpath_abspath_win32(self): + # Check _Py_abspath() is passed a backslashed path not to fall back to + # GetFullPathNameW() on startup, which (re-)normalizes the path overly. + # Currently, _Py_normpath() doesn't trim trailing dots and spaces. + CASES = [ + ("C:/a. . .", "C:\\a. . ."), + ("C:\\a. . .", "C:\\a. . ."), + ("\\\\?\\C:////a////b. . .", "\\\\?\\C:\\a\\b. . ."), + ("//a/b/c. . .", "\\\\a\\b\\c. . ."), + ("\\\\a\\b\\c. . .", "\\\\a\\b\\c. . ."), + ("a. . .", f"{os.getcwd()}\\a"), # relpath gets fully normalized + ] + out, err = self.run_embedded_interpreter( + "test_init_initialize_config", + env={**remove_python_envvars(), + "PYTHONPATH": os.path.pathsep.join(c[0] for c in CASES)} + ) + self.assertEqual(err, "") + try: + out = json.loads(out) + except json.JSONDecodeError: + self.fail(f"fail to decode stdout: {out!r}") + + results = out['config']["module_search_paths"] + for (_, expected), result in zip(CASES, results): + self.assertEqual(result, expected) + def test_global_pathconfig(self): # Test C API functions getting the path configuration: # @@ -1497,15 +1655,39 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): self.check_all_configs("test_init_use_frozen_modules", config, api=API_PYTHON, env=env) + def test_init_main_interpreter_settings(self): + THREADS = 1<<10 + DAEMON_THREADS = 1<<11 + FORK = 1<<15 + EXEC = 1<<16 + expected = { + # All optional features should be enabled. + 'feature_flags': FORK | EXEC | THREADS | DAEMON_THREADS, + } + out, err = self.run_embedded_interpreter( + 'test_init_main_interpreter_settings', + ) + self.assertEqual(err, '') + try: + out = json.loads(out) + except json.JSONDecodeError: + self.fail(f'fail to decode stdout: {out!r}') + + self.assertEqual(out, expected) + class SetConfigTests(unittest.TestCase): def test_set_config(self): # bpo-42260: Test _PyInterpreterState_SetConfig() import_helper.import_module('_testcapi') - cmd = [sys.executable, '-I', '-m', 'test._test_embed_set_config'] + cmd = [sys.executable, '-X', 'utf8', '-I', '-m', 'test._test_embed_set_config'] proc = subprocess.run(cmd, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + stderr=subprocess.PIPE, + encoding='utf-8', errors='backslashreplace') + if proc.returncode and support.verbose: + print(proc.stdout) + print(proc.stderr) self.assertEqual(proc.returncode, 0, (proc.returncode, proc.stdout, proc.stderr)) @@ -1560,6 +1742,9 @@ class AuditingTests(EmbeddingTestsMixin, unittest.TestCase): timeout=support.SHORT_TIMEOUT, returncode=1) + def test_get_incomplete_frame(self): + self.run_embedded_interpreter("test_get_incomplete_frame") + class MiscTests(EmbeddingTestsMixin, unittest.TestCase): def test_unicode_id_init(self): @@ -1586,6 +1771,34 @@ class MiscTests(EmbeddingTestsMixin, unittest.TestCase): """).lstrip() self.assertEqual(out, expected) + @unittest.skipUnless(support.Py_DEBUG, + '-X showrefcount requires a Python debug build') + def test_no_memleak(self): + # bpo-1635741: Python must release all memory at exit + tests = ( + ('off', 'pass'), + ('on', 'pass'), + ('off', 'import __hello__'), + ('on', 'import __hello__'), + ) + for flag, stmt in tests: + xopt = f"frozen_modules={flag}" + cmd = [sys.executable, "-I", "-X", "showrefcount", "-X", xopt, "-c", stmt] + proc = subprocess.run(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True) + self.assertEqual(proc.returncode, 0) + out = proc.stdout.rstrip() + match = re.match(r'^\[(-?\d+) refs, (-?\d+) blocks\]', out) + if not match: + self.fail(f"unexpected output: {out!a}") + refs = int(match.group(1)) + blocks = int(match.group(2)) + with self.subTest(frozen_modules=flag, stmt=stmt): + self.assertEqual(refs, 0, out) + self.assertEqual(blocks, 0, out) + class StdPrinterTests(EmbeddingTestsMixin, unittest.TestCase): # Test PyStdPrinter_Type which is used by _PySys_SetPreliminaryStderr(): diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 7d220871a35..1e653e94f6b 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -1,3 +1,4 @@ +import copy import enum import doctest import inspect @@ -6,15 +7,20 @@ import pydoc import sys import unittest import threading +import typing +import builtins as bltns from collections import OrderedDict +from datetime import date from enum import Enum, IntEnum, StrEnum, EnumType, Flag, IntFlag, unique, auto from enum import STRICT, CONFORM, EJECT, KEEP, _simple_enum, _test_simple_enum -from enum import verify, UNIQUE, CONTINUOUS, NAMED_FLAGS +from enum import verify, UNIQUE, CONTINUOUS, NAMED_FLAGS, ReprEnum +from enum import member, nonmember, _iter_bits_lsb from io import StringIO from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL from test import support from test.support import ALWAYS_EQ from test.support import threading_helper +from textwrap import dedent from datetime import timedelta python_version = sys.version_info[:2] @@ -28,7 +34,7 @@ def load_tests(loader, tests, ignore): )) return tests -MODULE = ('test.test_enum', '__main__')[__name__=='__main__'] +MODULE = __name__ SHORT_MODULE = MODULE.split('.')[-1] # for pickle tests @@ -60,10 +66,27 @@ try: class FlagStooges(Flag): LARRY = 1 CURLY = 2 - MOE = 3 + MOE = 4 except Exception as exc: FlagStooges = exc +class FlagStoogesWithZero(Flag): + NOFLAG = 0 + LARRY = 1 + CURLY = 2 + MOE = 4 + +class IntFlagStooges(IntFlag): + LARRY = 1 + CURLY = 2 + MOE = 4 + +class IntFlagStoogesWithZero(IntFlag): + NOFLAG = 0 + LARRY = 1 + CURLY = 2 + MOE = 4 + # for pickle test and subclass tests class Name(StrEnum): BDFL = 'Guido van Rossum' @@ -107,6 +130,12 @@ def test_pickle_exception(assertion, exception, obj): class TestHelpers(unittest.TestCase): # _is_descriptor, _is_sunder, _is_dunder + sunder_names = '_bad_', '_good_', '_what_ho_' + dunder_names = '__mal__', '__bien__', '__que_que__' + private_names = '_MyEnum__private', '_MyEnum__still_private' + private_and_sunder_names = '_MyEnum__private_', '_MyEnum__also_private_' + random_names = 'okay', '_semi_private', '_weird__', '_MyEnum__' + def test_is_descriptor(self): class foo: pass @@ -116,21 +145,40 @@ class TestHelpers(unittest.TestCase): setattr(obj, attr, 1) self.assertTrue(enum._is_descriptor(obj)) - def test_is_sunder(self): + def test_sunder(self): + for name in self.sunder_names + self.private_and_sunder_names: + self.assertTrue(enum._is_sunder(name), '%r is a not sunder name?' % name) + for name in self.dunder_names + self.private_names + self.random_names: + self.assertFalse(enum._is_sunder(name), '%r is a sunder name?' % name) for s in ('_a_', '_aa_'): self.assertTrue(enum._is_sunder(s)) - for s in ('a', 'a_', '_a', '__a', 'a__', '__a__', '_a__', '__a_', '_', '__', '___', '____', '_____',): self.assertFalse(enum._is_sunder(s)) - def test_is_dunder(self): + def test_dunder(self): + for name in self.dunder_names: + self.assertTrue(enum._is_dunder(name), '%r is a not dunder name?' % name) + for name in self.sunder_names + self.private_names + self.private_and_sunder_names + self.random_names: + self.assertFalse(enum._is_dunder(name), '%r is a dunder name?' % name) for s in ('__a__', '__aa__'): self.assertTrue(enum._is_dunder(s)) for s in ('a', 'a_', '_a', '__a', 'a__', '_a_', '_a__', '__a_', '_', '__', '___', '____', '_____',): self.assertFalse(enum._is_dunder(s)) + + def test_is_private(self): + for name in self.private_names + self.private_and_sunder_names: + self.assertTrue(enum._is_private('MyEnum', name), '%r is a not private name?') + for name in self.sunder_names + self.dunder_names + self.random_names: + self.assertFalse(enum._is_private('MyEnum', name), '%r is a private name?') + + def test_iter_bits_lsb(self): + self.assertEqual(list(_iter_bits_lsb(7)), [1, 2, 4]) + self.assertRaisesRegex(ValueError, '-8 is not a positive integer', list, _iter_bits_lsb(-8)) + + # for subclassing tests class classproperty: @@ -164,9 +212,658 @@ class HeadlightsC(IntFlag, boundary=enum.CONFORM): FOG_C = auto() +@enum.global_enum +class NoName(Flag): + ONE = 1 + TWO = 2 + + # tests -class TestEnum(unittest.TestCase): +class _EnumTests: + """ + Test for behavior that is the same across the different types of enumerations. + """ + + values = None + + def setUp(self): + class BaseEnum(self.enum_type): + @enum.property + def first(self): + return '%s is first!' % self.name + class MainEnum(BaseEnum): + first = auto() + second = auto() + third = auto() + if issubclass(self.enum_type, Flag): + dupe = 3 + else: + dupe = third + self.MainEnum = MainEnum + # + class NewStrEnum(self.enum_type): + def __str__(self): + return self.name.upper() + first = auto() + self.NewStrEnum = NewStrEnum + # + class NewFormatEnum(self.enum_type): + def __format__(self, spec): + return self.name.upper() + first = auto() + self.NewFormatEnum = NewFormatEnum + # + class NewStrFormatEnum(self.enum_type): + def __str__(self): + return self.name.title() + def __format__(self, spec): + return ''.join(reversed(self.name)) + first = auto() + self.NewStrFormatEnum = NewStrFormatEnum + # + class NewBaseEnum(self.enum_type): + def __str__(self): + return self.name.title() + def __format__(self, spec): + return ''.join(reversed(self.name)) + class NewSubEnum(NewBaseEnum): + first = auto() + self.NewSubEnum = NewSubEnum + # + self.is_flag = False + self.names = ['first', 'second', 'third'] + if issubclass(MainEnum, StrEnum): + self.values = self.names + elif MainEnum._member_type_ is str: + self.values = ['1', '2', '3'] + elif issubclass(self.enum_type, Flag): + self.values = [1, 2, 4] + self.is_flag = True + self.dupe2 = MainEnum(5) + else: + self.values = self.values or [1, 2, 3] + # + if not getattr(self, 'source_values', False): + self.source_values = self.values + + def assertFormatIsValue(self, spec, member): + self.assertEqual(spec.format(member), spec.format(member.value)) + + def assertFormatIsStr(self, spec, member): + self.assertEqual(spec.format(member), spec.format(str(member))) + + def test_attribute_deletion(self): + class Season(self.enum_type): + SPRING = auto() + SUMMER = auto() + AUTUMN = auto() + # + def spam(cls): + pass + # + self.assertTrue(hasattr(Season, 'spam')) + del Season.spam + self.assertFalse(hasattr(Season, 'spam')) + # + with self.assertRaises(AttributeError): + del Season.SPRING + with self.assertRaises(AttributeError): + del Season.DRY + with self.assertRaises(AttributeError): + del Season.SPRING.name + + def test_basics(self): + TE = self.MainEnum + if self.is_flag: + self.assertEqual(repr(TE), "") + self.assertEqual(str(TE), "") + self.assertEqual(format(TE), "") + self.assertTrue(TE(5) is self.dupe2) + else: + self.assertEqual(repr(TE), "") + self.assertEqual(str(TE), "") + self.assertEqual(format(TE), "") + self.assertEqual(list(TE), [TE.first, TE.second, TE.third]) + self.assertEqual( + [m.name for m in TE], + self.names, + ) + self.assertEqual( + [m.value for m in TE], + self.values, + ) + self.assertEqual( + [m.first for m in TE], + ['first is first!', 'second is first!', 'third is first!'] + ) + for member, name in zip(TE, self.names, strict=True): + self.assertIs(TE[name], member) + for member, value in zip(TE, self.values, strict=True): + self.assertIs(TE(value), member) + if issubclass(TE, StrEnum): + self.assertTrue(TE.dupe is TE('third') is TE['dupe']) + elif TE._member_type_ is str: + self.assertTrue(TE.dupe is TE('3') is TE['dupe']) + elif issubclass(TE, Flag): + self.assertTrue(TE.dupe is TE(3) is TE['dupe']) + else: + self.assertTrue(TE.dupe is TE(self.values[2]) is TE['dupe']) + + def test_bool_is_true(self): + class Empty(self.enum_type): + pass + self.assertTrue(Empty) + # + self.assertTrue(self.MainEnum) + for member in self.MainEnum: + self.assertTrue(member) + + def test_changing_member_fails(self): + MainEnum = self.MainEnum + with self.assertRaises(AttributeError): + self.MainEnum.second = 'really first' + + def test_contains_tf(self): + MainEnum = self.MainEnum + self.assertIn(MainEnum.first, MainEnum) + self.assertTrue(self.values[0] in MainEnum) + if type(self) is not TestStrEnum: + self.assertFalse('first' in MainEnum) + val = MainEnum.dupe + self.assertIn(val, MainEnum) + # + class OtherEnum(Enum): + one = auto() + two = auto() + self.assertNotIn(OtherEnum.two, MainEnum) + # + if MainEnum._member_type_ is object: + # enums without mixed data types will always be False + class NotEqualEnum(self.enum_type): + this = self.source_values[0] + that = self.source_values[1] + self.assertNotIn(NotEqualEnum.this, MainEnum) + self.assertNotIn(NotEqualEnum.that, MainEnum) + else: + # enums with mixed data types may be True + class EqualEnum(self.enum_type): + this = self.source_values[0] + that = self.source_values[1] + self.assertIn(EqualEnum.this, MainEnum) + self.assertIn(EqualEnum.that, MainEnum) + + def test_contains_same_name_diff_enum_diff_values(self): + MainEnum = self.MainEnum + # + class OtherEnum(Enum): + first = "brand" + second = "new" + third = "values" + # + self.assertIn(MainEnum.first, MainEnum) + self.assertIn(MainEnum.second, MainEnum) + self.assertIn(MainEnum.third, MainEnum) + self.assertNotIn(MainEnum.first, OtherEnum) + self.assertNotIn(MainEnum.second, OtherEnum) + self.assertNotIn(MainEnum.third, OtherEnum) + # + self.assertIn(OtherEnum.first, OtherEnum) + self.assertIn(OtherEnum.second, OtherEnum) + self.assertIn(OtherEnum.third, OtherEnum) + self.assertNotIn(OtherEnum.first, MainEnum) + self.assertNotIn(OtherEnum.second, MainEnum) + self.assertNotIn(OtherEnum.third, MainEnum) + + def test_dir_on_class(self): + TE = self.MainEnum + self.assertEqual(set(dir(TE)), set(enum_dir(TE))) + + def test_dir_on_item(self): + TE = self.MainEnum + self.assertEqual(set(dir(TE.first)), set(member_dir(TE.first))) + + def test_dir_with_added_behavior(self): + class Test(self.enum_type): + this = auto() + these = auto() + def wowser(self): + return ("Wowser! I'm %s!" % self.name) + self.assertTrue('wowser' not in dir(Test)) + self.assertTrue('wowser' in dir(Test.this)) + + def test_dir_on_sub_with_behavior_on_super(self): + # see issue22506 + class SuperEnum(self.enum_type): + def invisible(self): + return "did you see me?" + class SubEnum(SuperEnum): + sample = auto() + self.assertTrue('invisible' not in dir(SubEnum)) + self.assertTrue('invisible' in dir(SubEnum.sample)) + + def test_dir_on_sub_with_behavior_including_instance_dict_on_super(self): + # see issue40084 + class SuperEnum(self.enum_type): + def __new__(cls, *value, **kwds): + new = self.enum_type._member_type_.__new__ + if self.enum_type._member_type_ is object: + obj = new(cls) + else: + if isinstance(value[0], tuple): + create_value ,= value[0] + else: + create_value = value + obj = new(cls, *create_value) + obj._value_ = value[0] if len(value) == 1 else value + obj.description = 'test description' + return obj + class SubEnum(SuperEnum): + sample = self.source_values[1] + self.assertTrue('description' not in dir(SubEnum)) + self.assertTrue('description' in dir(SubEnum.sample), dir(SubEnum.sample)) + + def test_enum_in_enum_out(self): + Main = self.MainEnum + self.assertIs(Main(Main.first), Main.first) + + def test_hash(self): + MainEnum = self.MainEnum + mapping = {} + mapping[MainEnum.first] = '1225' + mapping[MainEnum.second] = '0315' + mapping[MainEnum.third] = '0704' + self.assertEqual(mapping[MainEnum.second], '0315') + + def test_invalid_names(self): + with self.assertRaises(ValueError): + class Wrong(self.enum_type): + mro = 9 + with self.assertRaises(ValueError): + class Wrong(self.enum_type): + _create_= 11 + with self.assertRaises(ValueError): + class Wrong(self.enum_type): + _get_mixins_ = 9 + with self.assertRaises(ValueError): + class Wrong(self.enum_type): + _find_new_ = 1 + with self.assertRaises(ValueError): + class Wrong(self.enum_type): + _any_name_ = 9 + + def test_object_str_override(self): + "check that setting __str__ to object's is not reset to Enum's" + class Generic(self.enum_type): + item = self.source_values[2] + def __repr__(self): + return "%s.test" % (self._name_, ) + __str__ = object.__str__ + self.assertEqual(str(Generic.item), 'item.test') + + def test_overridden_str(self): + NS = self.NewStrEnum + self.assertEqual(str(NS.first), NS.first.name.upper()) + self.assertEqual(format(NS.first), NS.first.name.upper()) + + def test_overridden_str_format(self): + NSF = self.NewStrFormatEnum + self.assertEqual(str(NSF.first), NSF.first.name.title()) + self.assertEqual(format(NSF.first), ''.join(reversed(NSF.first.name))) + + def test_overridden_str_format_inherited(self): + NSE = self.NewSubEnum + self.assertEqual(str(NSE.first), NSE.first.name.title()) + self.assertEqual(format(NSE.first), ''.join(reversed(NSE.first.name))) + + def test_programmatic_function_string(self): + MinorEnum = self.enum_type('MinorEnum', 'june july august') + lst = list(MinorEnum) + self.assertEqual(len(lst), len(MinorEnum)) + self.assertEqual(len(MinorEnum), 3, MinorEnum) + self.assertEqual( + [MinorEnum.june, MinorEnum.july, MinorEnum.august], + lst, + ) + values = self.values + if self.enum_type is StrEnum: + values = ['june','july','august'] + for month, av in zip('june july august'.split(), values): + e = MinorEnum[month] + self.assertEqual(e.value, av, list(MinorEnum)) + self.assertEqual(e.name, month) + if MinorEnum._member_type_ is not object and issubclass(MinorEnum, MinorEnum._member_type_): + self.assertEqual(e, av) + else: + self.assertNotEqual(e, av) + self.assertIn(e, MinorEnum) + self.assertIs(type(e), MinorEnum) + self.assertIs(e, MinorEnum(av)) + + def test_programmatic_function_string_list(self): + MinorEnum = self.enum_type('MinorEnum', ['june', 'july', 'august']) + lst = list(MinorEnum) + self.assertEqual(len(lst), len(MinorEnum)) + self.assertEqual(len(MinorEnum), 3, MinorEnum) + self.assertEqual( + [MinorEnum.june, MinorEnum.july, MinorEnum.august], + lst, + ) + values = self.values + if self.enum_type is StrEnum: + values = ['june','july','august'] + for month, av in zip('june july august'.split(), values): + e = MinorEnum[month] + self.assertEqual(e.value, av) + self.assertEqual(e.name, month) + if MinorEnum._member_type_ is not object and issubclass(MinorEnum, MinorEnum._member_type_): + self.assertEqual(e, av) + else: + self.assertNotEqual(e, av) + self.assertIn(e, MinorEnum) + self.assertIs(type(e), MinorEnum) + self.assertIs(e, MinorEnum(av)) + + def test_programmatic_function_iterable(self): + MinorEnum = self.enum_type( + 'MinorEnum', + (('june', self.source_values[0]), ('july', self.source_values[1]), ('august', self.source_values[2])) + ) + lst = list(MinorEnum) + self.assertEqual(len(lst), len(MinorEnum)) + self.assertEqual(len(MinorEnum), 3, MinorEnum) + self.assertEqual( + [MinorEnum.june, MinorEnum.july, MinorEnum.august], + lst, + ) + for month, av in zip('june july august'.split(), self.values): + e = MinorEnum[month] + self.assertEqual(e.value, av) + self.assertEqual(e.name, month) + if MinorEnum._member_type_ is not object and issubclass(MinorEnum, MinorEnum._member_type_): + self.assertEqual(e, av) + else: + self.assertNotEqual(e, av) + self.assertIn(e, MinorEnum) + self.assertIs(type(e), MinorEnum) + self.assertIs(e, MinorEnum(av)) + + def test_programmatic_function_from_dict(self): + MinorEnum = self.enum_type( + 'MinorEnum', + OrderedDict((('june', self.source_values[0]), ('july', self.source_values[1]), ('august', self.source_values[2]))) + ) + lst = list(MinorEnum) + self.assertEqual(len(lst), len(MinorEnum)) + self.assertEqual(len(MinorEnum), 3, MinorEnum) + self.assertEqual( + [MinorEnum.june, MinorEnum.july, MinorEnum.august], + lst, + ) + for month, av in zip('june july august'.split(), self.values): + e = MinorEnum[month] + if MinorEnum._member_type_ is not object and issubclass(MinorEnum, MinorEnum._member_type_): + self.assertEqual(e, av) + else: + self.assertNotEqual(e, av) + self.assertIn(e, MinorEnum) + self.assertIs(type(e), MinorEnum) + self.assertIs(e, MinorEnum(av)) + + def test_repr(self): + TE = self.MainEnum + if self.is_flag: + self.assertEqual(repr(TE(0)), "") + self.assertEqual(repr(TE.dupe), "") + self.assertEqual(repr(self.dupe2), "") + elif issubclass(TE, StrEnum): + self.assertEqual(repr(TE.dupe), "") + else: + self.assertEqual(repr(TE.dupe), "" % (self.values[2], ), TE._value_repr_) + for name, value, member in zip(self.names, self.values, TE, strict=True): + self.assertEqual(repr(member), "" % (member.name, member.value)) + + def test_repr_override(self): + class Generic(self.enum_type): + first = auto() + second = auto() + third = auto() + def __repr__(self): + return "don't you just love shades of %s?" % self.name + self.assertEqual( + repr(Generic.third), + "don't you just love shades of third?", + ) + + def test_inherited_repr(self): + class MyEnum(self.enum_type): + def __repr__(self): + return "My name is %s." % self.name + class MySubEnum(MyEnum): + this = auto() + that = auto() + theother = auto() + self.assertEqual(repr(MySubEnum.that), "My name is that.") + + def test_reversed_iteration_order(self): + self.assertEqual( + list(reversed(self.MainEnum)), + [self.MainEnum.third, self.MainEnum.second, self.MainEnum.first], + ) + +class _PlainOutputTests: + + def test_str(self): + TE = self.MainEnum + if self.is_flag: + self.assertEqual(str(TE(0)), "MainEnum(0)") + self.assertEqual(str(TE.dupe), "MainEnum.dupe") + self.assertEqual(str(self.dupe2), "MainEnum.first|third") + else: + self.assertEqual(str(TE.dupe), "MainEnum.third") + for name, value, member in zip(self.names, self.values, TE, strict=True): + self.assertEqual(str(member), "MainEnum.%s" % (member.name, )) + + def test_format(self): + TE = self.MainEnum + if self.is_flag: + self.assertEqual(format(TE.dupe), "MainEnum.dupe") + self.assertEqual(format(self.dupe2), "MainEnum.first|third") + else: + self.assertEqual(format(TE.dupe), "MainEnum.third") + for name, value, member in zip(self.names, self.values, TE, strict=True): + self.assertEqual(format(member), "MainEnum.%s" % (member.name, )) + + def test_overridden_format(self): + NF = self.NewFormatEnum + self.assertEqual(str(NF.first), "NewFormatEnum.first", '%s %r' % (NF.__str__, NF.first)) + self.assertEqual(format(NF.first), "FIRST") + + def test_format_specs(self): + TE = self.MainEnum + self.assertFormatIsStr('{}', TE.second) + self.assertFormatIsStr('{:}', TE.second) + self.assertFormatIsStr('{:20}', TE.second) + self.assertFormatIsStr('{:^20}', TE.second) + self.assertFormatIsStr('{:>20}', TE.second) + self.assertFormatIsStr('{:<20}', TE.second) + self.assertFormatIsStr('{:5.2}', TE.second) + + +class _MixedOutputTests: + + def test_str(self): + TE = self.MainEnum + if self.is_flag: + self.assertEqual(str(TE.dupe), "MainEnum.dupe") + self.assertEqual(str(self.dupe2), "MainEnum.first|third") + else: + self.assertEqual(str(TE.dupe), "MainEnum.third") + for name, value, member in zip(self.names, self.values, TE, strict=True): + self.assertEqual(str(member), "MainEnum.%s" % (member.name, )) + + def test_format(self): + TE = self.MainEnum + if self.is_flag: + self.assertEqual(format(TE.dupe), "MainEnum.dupe") + self.assertEqual(format(self.dupe2), "MainEnum.first|third") + else: + self.assertEqual(format(TE.dupe), "MainEnum.third") + for name, value, member in zip(self.names, self.values, TE, strict=True): + self.assertEqual(format(member), "MainEnum.%s" % (member.name, )) + + def test_overridden_format(self): + NF = self.NewFormatEnum + self.assertEqual(str(NF.first), "NewFormatEnum.first") + self.assertEqual(format(NF.first), "FIRST") + + def test_format_specs(self): + TE = self.MainEnum + self.assertFormatIsStr('{}', TE.first) + self.assertFormatIsStr('{:}', TE.first) + self.assertFormatIsStr('{:20}', TE.first) + self.assertFormatIsStr('{:^20}', TE.first) + self.assertFormatIsStr('{:>20}', TE.first) + self.assertFormatIsStr('{:<20}', TE.first) + self.assertFormatIsStr('{:5.2}', TE.first) + + +class _MinimalOutputTests: + + def test_str(self): + TE = self.MainEnum + if self.is_flag: + self.assertEqual(str(TE.dupe), "3") + self.assertEqual(str(self.dupe2), "5") + else: + self.assertEqual(str(TE.dupe), str(self.values[2])) + for name, value, member in zip(self.names, self.values, TE, strict=True): + self.assertEqual(str(member), str(value)) + + def test_format(self): + TE = self.MainEnum + if self.is_flag: + self.assertEqual(format(TE.dupe), "3") + self.assertEqual(format(self.dupe2), "5") + else: + self.assertEqual(format(TE.dupe), format(self.values[2])) + for name, value, member in zip(self.names, self.values, TE, strict=True): + self.assertEqual(format(member), format(value)) + + def test_overridden_format(self): + NF = self.NewFormatEnum + self.assertEqual(str(NF.first), str(self.values[0])) + self.assertEqual(format(NF.first), "FIRST") + + def test_format_specs(self): + TE = self.MainEnum + self.assertFormatIsValue('{}', TE.third) + self.assertFormatIsValue('{:}', TE.third) + self.assertFormatIsValue('{:20}', TE.third) + self.assertFormatIsValue('{:^20}', TE.third) + self.assertFormatIsValue('{:>20}', TE.third) + self.assertFormatIsValue('{:<20}', TE.third) + if TE._member_type_ is float: + self.assertFormatIsValue('{:n}', TE.third) + self.assertFormatIsValue('{:5.2}', TE.third) + self.assertFormatIsValue('{:f}', TE.third) + + def test_copy(self): + TE = self.MainEnum + copied = copy.copy(TE) + self.assertEqual(copied, TE) + deep = copy.deepcopy(TE) + self.assertEqual(deep, TE) + + +class _FlagTests: + + def test_default_missing_with_wrong_type_value(self): + with self.assertRaisesRegex( + ValueError, + "'RED' is not a valid ", + ) as ctx: + self.MainEnum('RED') + self.assertIs(ctx.exception.__context__, None) + +class TestPlainEnum(_EnumTests, _PlainOutputTests, unittest.TestCase): + enum_type = Enum + + +class TestPlainFlag(_EnumTests, _PlainOutputTests, _FlagTests, unittest.TestCase): + enum_type = Flag + + +class TestIntEnum(_EnumTests, _MinimalOutputTests, unittest.TestCase): + enum_type = IntEnum + + +class TestStrEnum(_EnumTests, _MinimalOutputTests, unittest.TestCase): + enum_type = StrEnum + + +class TestIntFlag(_EnumTests, _MinimalOutputTests, _FlagTests, unittest.TestCase): + enum_type = IntFlag + + +class TestMixedInt(_EnumTests, _MixedOutputTests, unittest.TestCase): + class enum_type(int, Enum): pass + + +class TestMixedStr(_EnumTests, _MixedOutputTests, unittest.TestCase): + class enum_type(str, Enum): pass + + +class TestMixedIntFlag(_EnumTests, _MixedOutputTests, _FlagTests, unittest.TestCase): + class enum_type(int, Flag): pass + + +class TestMixedDate(_EnumTests, _MixedOutputTests, unittest.TestCase): + + values = [date(2021, 12, 25), date(2020, 3, 15), date(2019, 11, 27)] + source_values = [(2021, 12, 25), (2020, 3, 15), (2019, 11, 27)] + + class enum_type(date, Enum): + def _generate_next_value_(name, start, count, last_values): + values = [(2021, 12, 25), (2020, 3, 15), (2019, 11, 27)] + return values[count] + + +class TestMinimalDate(_EnumTests, _MinimalOutputTests, unittest.TestCase): + + values = [date(2023, 12, 1), date(2016, 2, 29), date(2009, 1, 1)] + source_values = [(2023, 12, 1), (2016, 2, 29), (2009, 1, 1)] + + class enum_type(date, ReprEnum): + def _generate_next_value_(name, start, count, last_values): + values = [(2023, 12, 1), (2016, 2, 29), (2009, 1, 1)] + return values[count] + + +class TestMixedFloat(_EnumTests, _MixedOutputTests, unittest.TestCase): + + values = [1.1, 2.2, 3.3] + + class enum_type(float, Enum): + def _generate_next_value_(name, start, count, last_values): + values = [1.1, 2.2, 3.3] + return values[count] + + +class TestMinimalFloat(_EnumTests, _MinimalOutputTests, unittest.TestCase): + + values = [4.4, 5.5, 6.6] + + class enum_type(float, ReprEnum): + def _generate_next_value_(name, start, count, last_values): + values = [4.4, 5.5, 6.6] + return values[count] + + +class TestSpecial(unittest.TestCase): + """ + various operations that are not attributable to every possible enum + """ def setUp(self): class Season(Enum): @@ -175,13 +872,7 @@ class TestEnum(unittest.TestCase): AUTUMN = 3 WINTER = 4 self.Season = Season - - class Konstants(float, Enum): - E = 2.7182818 - PI = 3.1415926 - TAU = 2 * PI - self.Konstants = Konstants - + # class Grades(IntEnum): A = 5 B = 4 @@ -189,170 +880,20 @@ class TestEnum(unittest.TestCase): D = 2 F = 0 self.Grades = Grades - + # class Directional(str, Enum): EAST = 'east' WEST = 'west' NORTH = 'north' SOUTH = 'south' self.Directional = Directional - + # from datetime import date class Holiday(date, Enum): NEW_YEAR = 2013, 1, 1 IDES_OF_MARCH = 2013, 3, 15 self.Holiday = Holiday - def test_dir_on_class(self): - Season = self.Season - self.assertEqual( - set(dir(Season)), - set(['__class__', '__doc__', '__members__', '__module__', - 'SPRING', 'SUMMER', 'AUTUMN', 'WINTER']), - ) - - def test_dir_on_item(self): - Season = self.Season - self.assertEqual( - set(dir(Season.WINTER)), - set(['__class__', '__doc__', '__module__', 'name', 'value']), - ) - - def test_dir_with_added_behavior(self): - class Test(Enum): - this = 'that' - these = 'those' - def wowser(self): - return ("Wowser! I'm %s!" % self.name) - self.assertEqual( - set(dir(Test)), - set(['__class__', '__doc__', '__members__', '__module__', 'this', 'these']), - ) - self.assertEqual( - set(dir(Test.this)), - set(['__class__', '__doc__', '__module__', 'name', 'value', 'wowser']), - ) - - def test_dir_on_sub_with_behavior_on_super(self): - # see issue22506 - class SuperEnum(Enum): - def invisible(self): - return "did you see me?" - class SubEnum(SuperEnum): - sample = 5 - self.assertEqual( - set(dir(SubEnum.sample)), - set(['__class__', '__doc__', '__module__', 'name', 'value', 'invisible']), - ) - - def test_dir_on_sub_with_behavior_including_instance_dict_on_super(self): - # see issue40084 - class SuperEnum(IntEnum): - def __new__(cls, value, description=""): - obj = int.__new__(cls, value) - obj._value_ = value - obj.description = description - return obj - class SubEnum(SuperEnum): - sample = 5 - self.assertTrue({'description'} <= set(dir(SubEnum.sample))) - - def test_enum_in_enum_out(self): - Season = self.Season - self.assertIs(Season(Season.WINTER), Season.WINTER) - - def test_enum_value(self): - Season = self.Season - self.assertEqual(Season.SPRING.value, 1) - - def test_intenum_value(self): - self.assertEqual(IntStooges.CURLY.value, 2) - - def test_enum(self): - Season = self.Season - lst = list(Season) - self.assertEqual(len(lst), len(Season)) - self.assertEqual(len(Season), 4, Season) - self.assertEqual( - [Season.SPRING, Season.SUMMER, Season.AUTUMN, Season.WINTER], lst) - - for i, season in enumerate('SPRING SUMMER AUTUMN WINTER'.split(), 1): - e = Season(i) - self.assertEqual(e, getattr(Season, season)) - self.assertEqual(e.value, i) - self.assertNotEqual(e, i) - self.assertEqual(e.name, season) - self.assertIn(e, Season) - self.assertIs(type(e), Season) - self.assertIsInstance(e, Season) - self.assertEqual(str(e), season) - self.assertEqual(repr(e), 'Season.{0}'.format(season)) - - def test_value_name(self): - Season = self.Season - self.assertEqual(Season.SPRING.name, 'SPRING') - self.assertEqual(Season.SPRING.value, 1) - with self.assertRaises(AttributeError): - Season.SPRING.name = 'invierno' - with self.assertRaises(AttributeError): - Season.SPRING.value = 2 - - def test_changing_member(self): - Season = self.Season - with self.assertRaises(AttributeError): - Season.WINTER = 'really cold' - - def test_attribute_deletion(self): - class Season(Enum): - SPRING = 1 - SUMMER = 2 - AUTUMN = 3 - WINTER = 4 - - def spam(cls): - pass - - self.assertTrue(hasattr(Season, 'spam')) - del Season.spam - self.assertFalse(hasattr(Season, 'spam')) - - with self.assertRaises(AttributeError): - del Season.SPRING - with self.assertRaises(AttributeError): - del Season.DRY - with self.assertRaises(AttributeError): - del Season.SPRING.name - - def test_bool_of_class(self): - class Empty(Enum): - pass - self.assertTrue(bool(Empty)) - - def test_bool_of_member(self): - class Count(Enum): - zero = 0 - one = 1 - two = 2 - for member in Count: - self.assertTrue(bool(member)) - - def test_invalid_names(self): - with self.assertRaises(ValueError): - class Wrong(Enum): - mro = 9 - with self.assertRaises(ValueError): - class Wrong(Enum): - _create_= 11 - with self.assertRaises(ValueError): - class Wrong(Enum): - _get_mixins_ = 9 - with self.assertRaises(ValueError): - class Wrong(Enum): - _find_new_ = 1 - with self.assertRaises(ValueError): - class Wrong(Enum): - _any_name_ = 9 - def test_bool(self): # plain Enum members are always True class Logic(Enum): @@ -375,92 +916,57 @@ class TestEnum(unittest.TestCase): self.assertTrue(IntLogic.true) self.assertFalse(IntLogic.false) - @unittest.skipIf( - python_version >= (3, 12), - '__contains__ now returns True/False for all inputs', - ) - def test_contains_er(self): - Season = self.Season - self.assertIn(Season.AUTUMN, Season) - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 3 in Season - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 'AUTUMN' in Season - val = Season(3) - self.assertIn(val, Season) - # - class OtherEnum(Enum): - one = 1; two = 2 - self.assertNotIn(OtherEnum.two, Season) - - @unittest.skipIf( - python_version < (3, 12), - '__contains__ only works with enum memmbers before 3.12', - ) - def test_contains_tf(self): - Season = self.Season - self.assertIn(Season.AUTUMN, Season) - self.assertTrue(3 in Season) - self.assertFalse('AUTUMN' in Season) - val = Season(3) - self.assertIn(val, Season) - # - class OtherEnum(Enum): - one = 1; two = 2 - self.assertNotIn(OtherEnum.two, Season) - def test_comparisons(self): Season = self.Season with self.assertRaises(TypeError): Season.SPRING < Season.WINTER with self.assertRaises(TypeError): Season.SPRING > 4 - + # self.assertNotEqual(Season.SPRING, 1) - + # class Part(Enum): SPRING = 1 CLIP = 2 BARREL = 3 - + # self.assertNotEqual(Season.SPRING, Part.SPRING) with self.assertRaises(TypeError): Season.SPRING < Part.CLIP - def test_enum_duplicates(self): - class Season(Enum): - SPRING = 1 - SUMMER = 2 - AUTUMN = FALL = 3 - WINTER = 4 - ANOTHER_SPRING = 1 - lst = list(Season) - self.assertEqual( - lst, - [Season.SPRING, Season.SUMMER, - Season.AUTUMN, Season.WINTER, - ]) - self.assertIs(Season.FALL, Season.AUTUMN) - self.assertEqual(Season.FALL.value, 3) - self.assertEqual(Season.AUTUMN.value, 3) - self.assertIs(Season(3), Season.AUTUMN) - self.assertIs(Season(1), Season.SPRING) - self.assertEqual(Season.FALL.name, 'AUTUMN') - self.assertEqual( - [k for k,v in Season.__members__.items() if v.name != k], - ['FALL', 'ANOTHER_SPRING'], - ) + @unittest.skip('to-do list') + def test_dir_with_custom_dunders(self): + class PlainEnum(Enum): + pass + cls_dir = dir(PlainEnum) + self.assertNotIn('__repr__', cls_dir) + self.assertNotIn('__str__', cls_dir) + self.assertNotIn('__format__', cls_dir) + self.assertNotIn('__init__', cls_dir) + # + class MyEnum(Enum): + def __repr__(self): + return object.__repr__(self) + def __str__(self): + return object.__repr__(self) + def __format__(self): + return object.__repr__(self) + def __init__(self): + pass + cls_dir = dir(MyEnum) + self.assertIn('__repr__', cls_dir) + self.assertIn('__str__', cls_dir) + self.assertIn('__format__', cls_dir) + self.assertIn('__init__', cls_dir) - def test_duplicate_name(self): + def test_duplicate_name_error(self): with self.assertRaises(TypeError): class Color(Enum): red = 1 green = 2 blue = 3 red = 4 - + # with self.assertRaises(TypeError): class Color(Enum): red = 1 @@ -468,232 +974,216 @@ class TestEnum(unittest.TestCase): blue = 3 def red(self): return 'red' - + # with self.assertRaises(TypeError): class Color(Enum): - @property + @enum.property def red(self): return 'redder' red = 1 green = 2 blue = 3 - def test_reserved__sunder_(self): - with self.assertRaisesRegex( - ValueError, - '_sunder_ names, such as ._bad_., are reserved', - ): - class Bad(Enum): - _bad_ = 1 + def test_enum_function_with_qualname(self): + if isinstance(Theory, Exception): + raise Theory + self.assertEqual(Theory.__qualname__, 'spanish_inquisition') + + def test_enum_of_types(self): + """Support using Enum to refer to types deliberately.""" + class MyTypes(Enum): + i = int + f = float + s = str + self.assertEqual(MyTypes.i.value, int) + self.assertEqual(MyTypes.f.value, float) + self.assertEqual(MyTypes.s.value, str) + class Foo: + pass + class Bar: + pass + class MyTypes2(Enum): + a = Foo + b = Bar + self.assertEqual(MyTypes2.a.value, Foo) + self.assertEqual(MyTypes2.b.value, Bar) + class SpamEnumNotInner: + pass + class SpamEnum(Enum): + spam = SpamEnumNotInner + self.assertEqual(SpamEnum.spam.value, SpamEnumNotInner) + + def test_enum_of_generic_aliases(self): + class E(Enum): + a = typing.List[int] + b = list[int] + self.assertEqual(E.a.value, typing.List[int]) + self.assertEqual(E.b.value, list[int]) + self.assertEqual(repr(E.a), '') + self.assertEqual(repr(E.b), '') + + @unittest.skipIf( + python_version >= (3, 13), + 'inner classes are not members', + ) + def test_nested_classes_in_enum_are_members(self): + """ + Check for warnings pre-3.13 + """ + with self.assertWarnsRegex(DeprecationWarning, 'will not become a member'): + class Outer(Enum): + a = 1 + b = 2 + class Inner(Enum): + foo = 10 + bar = 11 + self.assertTrue(isinstance(Outer.Inner, Outer)) + self.assertEqual(Outer.a.value, 1) + self.assertEqual(Outer.Inner.value.foo.value, 10) + self.assertEqual( + list(Outer.Inner.value), + [Outer.Inner.value.foo, Outer.Inner.value.bar], + ) + self.assertEqual( + list(Outer), + [Outer.a, Outer.b, Outer.Inner], + ) + + @unittest.skipIf( + python_version < (3, 13), + 'inner classes are still members', + ) + def test_nested_classes_in_enum_are_not_members(self): + """Support locally-defined nested classes.""" + class Outer(Enum): + a = 1 + b = 2 + class Inner(Enum): + foo = 10 + bar = 11 + self.assertTrue(isinstance(Outer.Inner, type)) + self.assertEqual(Outer.a.value, 1) + self.assertEqual(Outer.Inner.foo.value, 10) + self.assertEqual( + list(Outer.Inner), + [Outer.Inner.foo, Outer.Inner.bar], + ) + self.assertEqual( + list(Outer), + [Outer.a, Outer.b], + ) + + def test_nested_classes_in_enum_with_nonmember(self): + class Outer(Enum): + a = 1 + b = 2 + @nonmember + class Inner(Enum): + foo = 10 + bar = 11 + self.assertTrue(isinstance(Outer.Inner, type)) + self.assertEqual(Outer.a.value, 1) + self.assertEqual(Outer.Inner.foo.value, 10) + self.assertEqual( + list(Outer.Inner), + [Outer.Inner.foo, Outer.Inner.bar], + ) + self.assertEqual( + list(Outer), + [Outer.a, Outer.b], + ) + + def test_enum_of_types_with_nonmember(self): + """Support using Enum to refer to types deliberately.""" + class MyTypes(Enum): + i = int + f = nonmember(float) + s = str + self.assertEqual(MyTypes.i.value, int) + self.assertTrue(MyTypes.f is float) + self.assertEqual(MyTypes.s.value, str) + class Foo: + pass + class Bar: + pass + class MyTypes2(Enum): + a = Foo + b = nonmember(Bar) + self.assertEqual(MyTypes2.a.value, Foo) + self.assertTrue(MyTypes2.b is Bar) + class SpamEnumIsInner: + pass + class SpamEnum(Enum): + spam = nonmember(SpamEnumIsInner) + self.assertTrue(SpamEnum.spam is SpamEnumIsInner) + + def test_nested_classes_in_enum_with_member(self): + """Support locally-defined nested classes.""" + class Outer(Enum): + a = 1 + b = 2 + @member + class Inner(Enum): + foo = 10 + bar = 11 + self.assertTrue(isinstance(Outer.Inner, Outer)) + self.assertEqual(Outer.a.value, 1) + self.assertEqual(Outer.Inner.value.foo.value, 10) + self.assertEqual( + list(Outer.Inner.value), + [Outer.Inner.value.foo, Outer.Inner.value.bar], + ) + self.assertEqual( + list(Outer), + [Outer.a, Outer.b, Outer.Inner], + ) def test_enum_with_value_name(self): class Huh(Enum): name = 1 value = 2 - self.assertEqual( - list(Huh), - [Huh.name, Huh.value], - ) + self.assertEqual(list(Huh), [Huh.name, Huh.value]) self.assertIs(type(Huh.name), Huh) self.assertEqual(Huh.name.name, 'name') self.assertEqual(Huh.name.value, 1) - def test_format_enum(self): - Season = self.Season - self.assertEqual('{}'.format(Season.SPRING), - '{}'.format(str(Season.SPRING))) - self.assertEqual( '{:}'.format(Season.SPRING), - '{:}'.format(str(Season.SPRING))) - self.assertEqual('{:20}'.format(Season.SPRING), - '{:20}'.format(str(Season.SPRING))) - self.assertEqual('{:^20}'.format(Season.SPRING), - '{:^20}'.format(str(Season.SPRING))) - self.assertEqual('{:>20}'.format(Season.SPRING), - '{:>20}'.format(str(Season.SPRING))) - self.assertEqual('{:<20}'.format(Season.SPRING), - '{:<20}'.format(str(Season.SPRING))) + def test_contains_name_and_value_overlap(self): + class IntEnum1(IntEnum): + X = 1 + class IntEnum2(IntEnum): + X = 1 + class IntEnum3(IntEnum): + X = 2 + class IntEnum4(IntEnum): + Y = 1 + self.assertIn(IntEnum1.X, IntEnum1) + self.assertIn(IntEnum1.X, IntEnum2) + self.assertNotIn(IntEnum1.X, IntEnum3) + self.assertIn(IntEnum1.X, IntEnum4) - def test_str_override_enum(self): - class EnumWithStrOverrides(Enum): - one = auto() - two = auto() - - def __str__(self): - return 'Str!' - self.assertEqual(str(EnumWithStrOverrides.one), 'Str!') - self.assertEqual('{}'.format(EnumWithStrOverrides.one), 'Str!') - - def test_format_override_enum(self): - class EnumWithFormatOverride(Enum): - one = 1.0 - two = 2.0 - def __format__(self, spec): - return 'Format!!' - self.assertEqual(str(EnumWithFormatOverride.one), 'one') - self.assertEqual('{}'.format(EnumWithFormatOverride.one), 'Format!!') - - def test_str_and_format_override_enum(self): - class EnumWithStrFormatOverrides(Enum): - one = auto() - two = auto() - def __str__(self): - return 'Str!' - def __format__(self, spec): - return 'Format!' - self.assertEqual(str(EnumWithStrFormatOverrides.one), 'Str!') - self.assertEqual('{}'.format(EnumWithStrFormatOverrides.one), 'Format!') - - def test_str_override_mixin(self): - class MixinEnumWithStrOverride(float, Enum): - one = 1.0 - two = 2.0 - def __str__(self): - return 'Overridden!' - self.assertEqual(str(MixinEnumWithStrOverride.one), 'Overridden!') - self.assertEqual('{}'.format(MixinEnumWithStrOverride.one), 'Overridden!') - - def test_str_and_format_override_mixin(self): - class MixinWithStrFormatOverrides(float, Enum): - one = 1.0 - two = 2.0 - def __str__(self): - return 'Str!' - def __format__(self, spec): - return 'Format!' - self.assertEqual(str(MixinWithStrFormatOverrides.one), 'Str!') - self.assertEqual('{}'.format(MixinWithStrFormatOverrides.one), 'Format!') - - def test_format_override_mixin(self): - class TestFloat(float, Enum): - one = 1.0 - two = 2.0 - def __format__(self, spec): - return 'TestFloat success!' - self.assertEqual(str(TestFloat.one), 'one') - self.assertEqual('{}'.format(TestFloat.one), 'TestFloat success!') - - @unittest.skipIf( - python_version < (3, 12), - 'mixin-format is still using member.value', - ) - def test_mixin_format_warning(self): - class Grades(int, Enum): - A = 5 - B = 4 - C = 3 - D = 2 - F = 0 - self.assertEqual(f'{self.Grades.B}', 'B') - - @unittest.skipIf( - python_version >= (3, 12), - 'mixin-format now uses member instead of member.value', - ) - def test_mixin_format_warning(self): - class Grades(int, Enum): - A = 5 - B = 4 - C = 3 - D = 2 - F = 0 - with self.assertWarns(DeprecationWarning): - self.assertEqual(f'{Grades.B}', '4') - - def assertFormatIsValue(self, spec, member): - if python_version < (3, 12) and (not spec or spec in ('{}','{:}')): - with self.assertWarns(DeprecationWarning): - self.assertEqual(spec.format(member), spec.format(member.value)) - else: - self.assertEqual(spec.format(member), spec.format(member.value)) - - def test_format_enum_date(self): - Holiday = self.Holiday - self.assertFormatIsValue('{}', Holiday.IDES_OF_MARCH) - self.assertFormatIsValue('{:}', Holiday.IDES_OF_MARCH) - self.assertFormatIsValue('{:20}', Holiday.IDES_OF_MARCH) - self.assertFormatIsValue('{:^20}', Holiday.IDES_OF_MARCH) - self.assertFormatIsValue('{:>20}', Holiday.IDES_OF_MARCH) - self.assertFormatIsValue('{:<20}', Holiday.IDES_OF_MARCH) - self.assertFormatIsValue('{:%Y %m}', Holiday.IDES_OF_MARCH) - self.assertFormatIsValue('{:%Y %m %M:00}', Holiday.IDES_OF_MARCH) - - def test_format_enum_float(self): - Konstants = self.Konstants - self.assertFormatIsValue('{}', Konstants.TAU) - self.assertFormatIsValue('{:}', Konstants.TAU) - self.assertFormatIsValue('{:20}', Konstants.TAU) - self.assertFormatIsValue('{:^20}', Konstants.TAU) - self.assertFormatIsValue('{:>20}', Konstants.TAU) - self.assertFormatIsValue('{:<20}', Konstants.TAU) - self.assertFormatIsValue('{:n}', Konstants.TAU) - self.assertFormatIsValue('{:5.2}', Konstants.TAU) - self.assertFormatIsValue('{:f}', Konstants.TAU) - - def test_format_enum_int(self): - class Grades(int, Enum): - A = 5 - B = 4 - C = 3 - D = 2 - F = 0 - self.assertFormatIsValue('{}', Grades.C) - self.assertFormatIsValue('{:}', Grades.C) - self.assertFormatIsValue('{:20}', Grades.C) - self.assertFormatIsValue('{:^20}', Grades.C) - self.assertFormatIsValue('{:>20}', Grades.C) - self.assertFormatIsValue('{:<20}', Grades.C) - self.assertFormatIsValue('{:+}', Grades.C) - self.assertFormatIsValue('{:08X}', Grades.C) - self.assertFormatIsValue('{:b}', Grades.C) - - def test_format_enum_str(self): - Directional = self.Directional - self.assertFormatIsValue('{}', Directional.WEST) - self.assertFormatIsValue('{:}', Directional.WEST) - self.assertFormatIsValue('{:20}', Directional.WEST) - self.assertFormatIsValue('{:^20}', Directional.WEST) - self.assertFormatIsValue('{:>20}', Directional.WEST) - self.assertFormatIsValue('{:<20}', Directional.WEST) - - def test_object_str_override(self): - class Colors(Enum): - RED, GREEN, BLUE = 1, 2, 3 - def __repr__(self): - return "test.%s" % (self._name_, ) - __str__ = object.__str__ - self.assertEqual(str(Colors.RED), 'test.RED') - - def test_enum_str_override(self): - class MyStrEnum(Enum): - def __str__(self): - return 'MyStr' - class MyMethodEnum(Enum): - def hello(self): - return 'Hello! My name is %s' % self.name - class Test1Enum(MyMethodEnum, int, MyStrEnum): - One = 1 - Two = 2 - self.assertTrue(Test1Enum._member_type_ is int) - self.assertEqual(str(Test1Enum.One), 'MyStr') - self.assertEqual(format(Test1Enum.One, ''), 'MyStr') - # - class Test2Enum(MyStrEnum, MyMethodEnum): - One = 1 - Two = 2 - self.assertEqual(str(Test2Enum.One), 'MyStr') - self.assertEqual(format(Test1Enum.One, ''), 'MyStr') + def test_contains_different_types_same_members(self): + class IntEnum1(IntEnum): + X = 1 + class IntFlag1(IntFlag): + X = 1 + self.assertIn(IntEnum1.X, IntFlag1) + self.assertIn(IntFlag1.X, IntEnum1) def test_inherited_data_type(self): class HexInt(int): + __qualname__ = 'HexInt' def __repr__(self): return hex(self) class MyEnum(HexInt, enum.Enum): + __qualname__ = 'MyEnum' A = 1 B = 2 C = 3 - def __repr__(self): - return '<%s.%s: %r>' % (self.__class__.__name__, self._name_, self._value_) self.assertEqual(repr(MyEnum.A), '') + globals()['HexInt'] = HexInt + globals()['MyEnum'] = MyEnum + test_pickle_dump_load(self.assertIs, MyEnum.A) + test_pickle_dump_load(self.assertIs, MyEnum) # class SillyInt(HexInt): __qualname__ = 'SillyInt' @@ -709,7 +1199,7 @@ class TestEnum(unittest.TestCase): test_pickle_dump_load(self.assertIs, MyOtherEnum.E) test_pickle_dump_load(self.assertIs, MyOtherEnum) # - # This did not work in 3.9, but does now with pickling by name + # This did not work in 3.10, but does now with pickling by name class UnBrokenInt(int): __qualname__ = 'UnBrokenInt' def __new__(cls, value): @@ -726,6 +1216,139 @@ class TestEnum(unittest.TestCase): test_pickle_dump_load(self.assertIs, MyUnBrokenEnum.I) test_pickle_dump_load(self.assertIs, MyUnBrokenEnum) + def test_floatenum_fromhex(self): + h = float.hex(FloatStooges.MOE.value) + self.assertIs(FloatStooges.fromhex(h), FloatStooges.MOE) + h = float.hex(FloatStooges.MOE.value + 0.01) + with self.assertRaises(ValueError): + FloatStooges.fromhex(h) + + def test_programmatic_function_type(self): + MinorEnum = Enum('MinorEnum', 'june july august', type=int) + lst = list(MinorEnum) + self.assertEqual(len(lst), len(MinorEnum)) + self.assertEqual(len(MinorEnum), 3, MinorEnum) + self.assertEqual( + [MinorEnum.june, MinorEnum.july, MinorEnum.august], + lst, + ) + for i, month in enumerate('june july august'.split(), 1): + e = MinorEnum(i) + self.assertEqual(e, i) + self.assertEqual(e.name, month) + self.assertIn(e, MinorEnum) + self.assertIs(type(e), MinorEnum) + + def test_programmatic_function_string_with_start(self): + MinorEnum = Enum('MinorEnum', 'june july august', start=10) + lst = list(MinorEnum) + self.assertEqual(len(lst), len(MinorEnum)) + self.assertEqual(len(MinorEnum), 3, MinorEnum) + self.assertEqual( + [MinorEnum.june, MinorEnum.july, MinorEnum.august], + lst, + ) + for i, month in enumerate('june july august'.split(), 10): + e = MinorEnum(i) + self.assertEqual(int(e.value), i) + self.assertNotEqual(e, i) + self.assertEqual(e.name, month) + self.assertIn(e, MinorEnum) + self.assertIs(type(e), MinorEnum) + + def test_programmatic_function_type_with_start(self): + MinorEnum = Enum('MinorEnum', 'june july august', type=int, start=30) + lst = list(MinorEnum) + self.assertEqual(len(lst), len(MinorEnum)) + self.assertEqual(len(MinorEnum), 3, MinorEnum) + self.assertEqual( + [MinorEnum.june, MinorEnum.july, MinorEnum.august], + lst, + ) + for i, month in enumerate('june july august'.split(), 30): + e = MinorEnum(i) + self.assertEqual(e, i) + self.assertEqual(e.name, month) + self.assertIn(e, MinorEnum) + self.assertIs(type(e), MinorEnum) + + def test_programmatic_function_string_list_with_start(self): + MinorEnum = Enum('MinorEnum', ['june', 'july', 'august'], start=20) + lst = list(MinorEnum) + self.assertEqual(len(lst), len(MinorEnum)) + self.assertEqual(len(MinorEnum), 3, MinorEnum) + self.assertEqual( + [MinorEnum.june, MinorEnum.july, MinorEnum.august], + lst, + ) + for i, month in enumerate('june july august'.split(), 20): + e = MinorEnum(i) + self.assertEqual(int(e.value), i) + self.assertNotEqual(e, i) + self.assertEqual(e.name, month) + self.assertIn(e, MinorEnum) + self.assertIs(type(e), MinorEnum) + + def test_programmatic_function_type_from_subclass(self): + MinorEnum = IntEnum('MinorEnum', 'june july august') + lst = list(MinorEnum) + self.assertEqual(len(lst), len(MinorEnum)) + self.assertEqual(len(MinorEnum), 3, MinorEnum) + self.assertEqual( + [MinorEnum.june, MinorEnum.july, MinorEnum.august], + lst, + ) + for i, month in enumerate('june july august'.split(), 1): + e = MinorEnum(i) + self.assertEqual(e, i) + self.assertEqual(e.name, month) + self.assertIn(e, MinorEnum) + self.assertIs(type(e), MinorEnum) + + def test_programmatic_function_type_from_subclass_with_start(self): + MinorEnum = IntEnum('MinorEnum', 'june july august', start=40) + lst = list(MinorEnum) + self.assertEqual(len(lst), len(MinorEnum)) + self.assertEqual(len(MinorEnum), 3, MinorEnum) + self.assertEqual( + [MinorEnum.june, MinorEnum.july, MinorEnum.august], + lst, + ) + for i, month in enumerate('june july august'.split(), 40): + e = MinorEnum(i) + self.assertEqual(e, i) + self.assertEqual(e.name, month) + self.assertIn(e, MinorEnum) + self.assertIs(type(e), MinorEnum) + + def test_programmatic_function_is_value_call(self): + class TwoPart(Enum): + ONE = 1, 1.0 + TWO = 2, 2.0 + THREE = 3, 3.0 + self.assertRaisesRegex(ValueError, '1 is not a valid .*TwoPart', TwoPart, 1) + self.assertIs(TwoPart((1, 1.0)), TwoPart.ONE) + self.assertIs(TwoPart(1, 1.0), TwoPart.ONE) + class ThreePart(Enum): + ONE = 1, 1.0, 'one' + TWO = 2, 2.0, 'two' + THREE = 3, 3.0, 'three' + self.assertIs(ThreePart((3, 3.0, 'three')), ThreePart.THREE) + self.assertIs(ThreePart(3, 3.0, 'three'), ThreePart.THREE) + + def test_intenum_from_bytes(self): + self.assertIs(IntStooges.from_bytes(b'\x00\x03', 'big'), IntStooges.MOE) + with self.assertRaises(ValueError): + IntStooges.from_bytes(b'\x00\x05', 'big') + + def test_reserved_sunder_error(self): + with self.assertRaisesRegex( + ValueError, + '_sunder_ names, such as ._bad_., are reserved', + ): + class Bad(Enum): + _bad_ = 1 + def test_too_many_data_types(self): with self.assertRaisesRegex(TypeError, 'too many data types'): class Huh(str, int, Enum): @@ -741,112 +1364,6 @@ class TestEnum(unittest.TestCase): class Huh(MyStr, MyInt, Enum): One = 1 - def test_hash(self): - Season = self.Season - dates = {} - dates[Season.WINTER] = '1225' - dates[Season.SPRING] = '0315' - dates[Season.SUMMER] = '0704' - dates[Season.AUTUMN] = '1031' - self.assertEqual(dates[Season.AUTUMN], '1031') - - def test_intenum_from_scratch(self): - class phy(int, Enum): - pi = 3 - tau = 2 * pi - self.assertTrue(phy.pi < phy.tau) - - def test_intenum_inherited(self): - class IntEnum(int, Enum): - pass - class phy(IntEnum): - pi = 3 - tau = 2 * pi - self.assertTrue(phy.pi < phy.tau) - - def test_floatenum_from_scratch(self): - class phy(float, Enum): - pi = 3.1415926 - tau = 2 * pi - self.assertTrue(phy.pi < phy.tau) - - def test_floatenum_inherited(self): - class FloatEnum(float, Enum): - pass - class phy(FloatEnum): - pi = 3.1415926 - tau = 2 * pi - self.assertTrue(phy.pi < phy.tau) - - def test_strenum_from_scratch(self): - class phy(str, Enum): - pi = 'Pi' - tau = 'Tau' - self.assertTrue(phy.pi < phy.tau) - - def test_strenum_inherited_methods(self): - class phy(StrEnum): - pi = 'Pi' - tau = 'Tau' - self.assertTrue(phy.pi < phy.tau) - self.assertEqual(phy.pi.upper(), 'PI') - self.assertEqual(phy.tau.count('a'), 1) - - def test_intenum(self): - class WeekDay(IntEnum): - SUNDAY = 1 - MONDAY = 2 - TUESDAY = 3 - WEDNESDAY = 4 - THURSDAY = 5 - FRIDAY = 6 - SATURDAY = 7 - - self.assertEqual(['a', 'b', 'c'][WeekDay.MONDAY], 'c') - self.assertEqual([i for i in range(WeekDay.TUESDAY)], [0, 1, 2]) - - lst = list(WeekDay) - self.assertEqual(len(lst), len(WeekDay)) - self.assertEqual(len(WeekDay), 7) - target = 'SUNDAY MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY' - target = target.split() - for i, weekday in enumerate(target, 1): - e = WeekDay(i) - self.assertEqual(e, i) - self.assertEqual(int(e), i) - self.assertEqual(e.name, weekday) - self.assertIn(e, WeekDay) - self.assertEqual(lst.index(e)+1, i) - self.assertTrue(0 < e < 8) - self.assertIs(type(e), WeekDay) - self.assertIsInstance(e, int) - self.assertIsInstance(e, Enum) - - def test_intenum_duplicates(self): - class WeekDay(IntEnum): - SUNDAY = 1 - MONDAY = 2 - TUESDAY = TEUSDAY = 3 - WEDNESDAY = 4 - THURSDAY = 5 - FRIDAY = 6 - SATURDAY = 7 - self.assertIs(WeekDay.TEUSDAY, WeekDay.TUESDAY) - self.assertEqual(WeekDay(3).name, 'TUESDAY') - self.assertEqual([k for k,v in WeekDay.__members__.items() - if v.name != k], ['TEUSDAY', ]) - - def test_intenum_from_bytes(self): - self.assertIs(IntStooges.from_bytes(b'\x00\x03', 'big'), IntStooges.MOE) - with self.assertRaises(ValueError): - IntStooges.from_bytes(b'\x00\x05', 'big') - - def test_floatenum_fromhex(self): - h = float.hex(FloatStooges.MOE.value) - self.assertIs(FloatStooges.fromhex(h), FloatStooges.MOE) - h = float.hex(FloatStooges.MOE.value + 0.01) - with self.assertRaises(ValueError): - FloatStooges.fromhex(h) def test_pickle_enum(self): if isinstance(Stooges, Exception): @@ -878,12 +1395,7 @@ class TestEnum(unittest.TestCase): test_pickle_dump_load(self.assertIs, Question.who) test_pickle_dump_load(self.assertIs, Question) - def test_enum_function_with_qualname(self): - if isinstance(Theory, Exception): - raise Theory - self.assertEqual(Theory.__qualname__, 'spanish_inquisition') - - def test_class_nested_enum_and_pickle_protocol_four(self): + def test_pickle_nested_class(self): # would normally just have this directly in the class namespace class NestedEnum(Enum): twigs = 'common' @@ -901,7 +1413,7 @@ class TestEnum(unittest.TestCase): for proto in range(HIGHEST_PROTOCOL): self.assertEqual(ReplaceGlobalInt.TWO.__reduce_ex__(proto), 'TWO') - def test_exploding_pickle(self): + def test_pickle_explodes(self): BadPickle = Enum( 'BadPickle', 'dill sweet bread-n-butter', module=__name__) globals()['BadPickle'] = BadPickle @@ -942,185 +1454,6 @@ class TestEnum(unittest.TestCase): [Season.SUMMER, Season.WINTER, Season.AUTUMN, Season.SPRING], ) - def test_reversed_iteration_order(self): - self.assertEqual( - list(reversed(self.Season)), - [self.Season.WINTER, self.Season.AUTUMN, self.Season.SUMMER, - self.Season.SPRING] - ) - - def test_programmatic_function_string(self): - SummerMonth = Enum('SummerMonth', 'june july august') - lst = list(SummerMonth) - self.assertEqual(len(lst), len(SummerMonth)) - self.assertEqual(len(SummerMonth), 3, SummerMonth) - self.assertEqual( - [SummerMonth.june, SummerMonth.july, SummerMonth.august], - lst, - ) - for i, month in enumerate('june july august'.split(), 1): - e = SummerMonth(i) - self.assertEqual(int(e.value), i) - self.assertNotEqual(e, i) - self.assertEqual(e.name, month) - self.assertIn(e, SummerMonth) - self.assertIs(type(e), SummerMonth) - - def test_programmatic_function_string_with_start(self): - SummerMonth = Enum('SummerMonth', 'june july august', start=10) - lst = list(SummerMonth) - self.assertEqual(len(lst), len(SummerMonth)) - self.assertEqual(len(SummerMonth), 3, SummerMonth) - self.assertEqual( - [SummerMonth.june, SummerMonth.july, SummerMonth.august], - lst, - ) - for i, month in enumerate('june july august'.split(), 10): - e = SummerMonth(i) - self.assertEqual(int(e.value), i) - self.assertNotEqual(e, i) - self.assertEqual(e.name, month) - self.assertIn(e, SummerMonth) - self.assertIs(type(e), SummerMonth) - - def test_programmatic_function_string_list(self): - SummerMonth = Enum('SummerMonth', ['june', 'july', 'august']) - lst = list(SummerMonth) - self.assertEqual(len(lst), len(SummerMonth)) - self.assertEqual(len(SummerMonth), 3, SummerMonth) - self.assertEqual( - [SummerMonth.june, SummerMonth.july, SummerMonth.august], - lst, - ) - for i, month in enumerate('june july august'.split(), 1): - e = SummerMonth(i) - self.assertEqual(int(e.value), i) - self.assertNotEqual(e, i) - self.assertEqual(e.name, month) - self.assertIn(e, SummerMonth) - self.assertIs(type(e), SummerMonth) - - def test_programmatic_function_string_list_with_start(self): - SummerMonth = Enum('SummerMonth', ['june', 'july', 'august'], start=20) - lst = list(SummerMonth) - self.assertEqual(len(lst), len(SummerMonth)) - self.assertEqual(len(SummerMonth), 3, SummerMonth) - self.assertEqual( - [SummerMonth.june, SummerMonth.july, SummerMonth.august], - lst, - ) - for i, month in enumerate('june july august'.split(), 20): - e = SummerMonth(i) - self.assertEqual(int(e.value), i) - self.assertNotEqual(e, i) - self.assertEqual(e.name, month) - self.assertIn(e, SummerMonth) - self.assertIs(type(e), SummerMonth) - - def test_programmatic_function_iterable(self): - SummerMonth = Enum( - 'SummerMonth', - (('june', 1), ('july', 2), ('august', 3)) - ) - lst = list(SummerMonth) - self.assertEqual(len(lst), len(SummerMonth)) - self.assertEqual(len(SummerMonth), 3, SummerMonth) - self.assertEqual( - [SummerMonth.june, SummerMonth.july, SummerMonth.august], - lst, - ) - for i, month in enumerate('june july august'.split(), 1): - e = SummerMonth(i) - self.assertEqual(int(e.value), i) - self.assertNotEqual(e, i) - self.assertEqual(e.name, month) - self.assertIn(e, SummerMonth) - self.assertIs(type(e), SummerMonth) - - def test_programmatic_function_from_dict(self): - SummerMonth = Enum( - 'SummerMonth', - OrderedDict((('june', 1), ('july', 2), ('august', 3))) - ) - lst = list(SummerMonth) - self.assertEqual(len(lst), len(SummerMonth)) - self.assertEqual(len(SummerMonth), 3, SummerMonth) - self.assertEqual( - [SummerMonth.june, SummerMonth.july, SummerMonth.august], - lst, - ) - for i, month in enumerate('june july august'.split(), 1): - e = SummerMonth(i) - self.assertEqual(int(e.value), i) - self.assertNotEqual(e, i) - self.assertEqual(e.name, month) - self.assertIn(e, SummerMonth) - self.assertIs(type(e), SummerMonth) - - def test_programmatic_function_type(self): - SummerMonth = Enum('SummerMonth', 'june july august', type=int) - lst = list(SummerMonth) - self.assertEqual(len(lst), len(SummerMonth)) - self.assertEqual(len(SummerMonth), 3, SummerMonth) - self.assertEqual( - [SummerMonth.june, SummerMonth.july, SummerMonth.august], - lst, - ) - for i, month in enumerate('june july august'.split(), 1): - e = SummerMonth(i) - self.assertEqual(e, i) - self.assertEqual(e.name, month) - self.assertIn(e, SummerMonth) - self.assertIs(type(e), SummerMonth) - - def test_programmatic_function_type_with_start(self): - SummerMonth = Enum('SummerMonth', 'june july august', type=int, start=30) - lst = list(SummerMonth) - self.assertEqual(len(lst), len(SummerMonth)) - self.assertEqual(len(SummerMonth), 3, SummerMonth) - self.assertEqual( - [SummerMonth.june, SummerMonth.july, SummerMonth.august], - lst, - ) - for i, month in enumerate('june july august'.split(), 30): - e = SummerMonth(i) - self.assertEqual(e, i) - self.assertEqual(e.name, month) - self.assertIn(e, SummerMonth) - self.assertIs(type(e), SummerMonth) - - def test_programmatic_function_type_from_subclass(self): - SummerMonth = IntEnum('SummerMonth', 'june july august') - lst = list(SummerMonth) - self.assertEqual(len(lst), len(SummerMonth)) - self.assertEqual(len(SummerMonth), 3, SummerMonth) - self.assertEqual( - [SummerMonth.june, SummerMonth.july, SummerMonth.august], - lst, - ) - for i, month in enumerate('june july august'.split(), 1): - e = SummerMonth(i) - self.assertEqual(e, i) - self.assertEqual(e.name, month) - self.assertIn(e, SummerMonth) - self.assertIs(type(e), SummerMonth) - - def test_programmatic_function_type_from_subclass_with_start(self): - SummerMonth = IntEnum('SummerMonth', 'june july august', start=40) - lst = list(SummerMonth) - self.assertEqual(len(lst), len(SummerMonth)) - self.assertEqual(len(SummerMonth), 3, SummerMonth) - self.assertEqual( - [SummerMonth.june, SummerMonth.july, SummerMonth.august], - lst, - ) - for i, month in enumerate('june july august'.split(), 40): - e = SummerMonth(i) - self.assertEqual(e, i) - self.assertEqual(e.name, month) - self.assertIn(e, SummerMonth) - self.assertIs(type(e), SummerMonth) - def test_subclassing(self): if isinstance(Name, Exception): raise Name @@ -1134,14 +1467,19 @@ class TestEnum(unittest.TestCase): red = 1 green = 2 blue = 3 + # with self.assertRaises(TypeError): class MoreColor(Color): cyan = 4 magenta = 5 yellow = 6 - with self.assertRaisesRegex(TypeError, "EvenMoreColor: cannot extend enumeration 'Color'"): + # + with self.assertRaisesRegex(TypeError, " cannot extend "): class EvenMoreColor(Color, IntEnum): chartruese = 7 + # + with self.assertRaisesRegex(ValueError, r"\(.Foo., \(.pink., .black.\)\) is not a valid .*Color"): + Color('Foo', ('pink', 'black')) def test_exclude_methods(self): class whatever(Enum): @@ -1244,27 +1582,7 @@ class TestEnum(unittest.TestCase): with self.assertRaises(KeyError): Color['chartreuse'] - def test_new_repr(self): - class Color(Enum): - red = 1 - green = 2 - blue = 3 - def __repr__(self): - return "don't you just love shades of %s?" % self.name - self.assertEqual( - repr(Color.blue), - "don't you just love shades of blue?", - ) - - def test_inherited_repr(self): - class MyEnum(Enum): - def __repr__(self): - return "My name is %s." % self.name - class MyIntEnum(int, MyEnum): - this = 1 - that = 2 - theother = 3 - self.assertEqual(repr(MyIntEnum.that), "My name is that.") + # tests that need to be evalualted for moving def test_multiple_mixin_mro(self): class auto_enum(type(Enum)): @@ -1317,7 +1635,7 @@ class TestEnum(unittest.TestCase): return self def __getnewargs__(self): return self._args - @property + @bltns.property def __name__(self): return self._intname def __repr__(self): @@ -1377,7 +1695,7 @@ class TestEnum(unittest.TestCase): return self def __getnewargs_ex__(self): return self._args, {} - @property + @bltns.property def __name__(self): return self._intname def __repr__(self): @@ -1437,7 +1755,7 @@ class TestEnum(unittest.TestCase): return self def __reduce__(self): return self.__class__, self._args - @property + @bltns.property def __name__(self): return self._intname def __repr__(self): @@ -1497,7 +1815,7 @@ class TestEnum(unittest.TestCase): return self def __reduce_ex__(self, proto): return self.__class__, self._args - @property + @bltns.property def __name__(self): return self._intname def __repr__(self): @@ -1554,7 +1872,7 @@ class TestEnum(unittest.TestCase): self._intname = name self._args = _args return self - @property + @bltns.property def __name__(self): return self._intname def __repr__(self): @@ -1609,7 +1927,7 @@ class TestEnum(unittest.TestCase): self._intname = name self._args = _args return self - @property + @bltns.property def __name__(self): return self._intname def __repr__(self): @@ -1798,6 +2116,7 @@ class TestEnum(unittest.TestCase): class Test(Base): test = 1 self.assertEqual(Test.test.test, 'dynamic') + self.assertEqual(Test.test.value, 1) class Base2(Enum): @enum.property def flash(self): @@ -1805,6 +2124,7 @@ class TestEnum(unittest.TestCase): class Test(Base2): flash = 1 self.assertEqual(Test.flash.flash, 'flashy dynamic') + self.assertEqual(Test.flash.value, 1) def test_no_duplicates(self): class UniqueEnum(Enum): @@ -1841,7 +2161,7 @@ class TestEnum(unittest.TestCase): def __init__(self, mass, radius): self.mass = mass # in kilograms self.radius = radius # in meters - @property + @enum.property def surface_gravity(self): # universal gravitational constant (m3 kg-1 s-2) G = 6.67300E-11 @@ -1911,90 +2231,7 @@ class TestEnum(unittest.TestCase): self.assertEqual(LabelledList.unprocessed, 1) self.assertEqual(LabelledList(1), LabelledList.unprocessed) - def test_auto_number(self): - class Color(Enum): - red = auto() - blue = auto() - green = auto() - - self.assertEqual(list(Color), [Color.red, Color.blue, Color.green]) - self.assertEqual(Color.red.value, 1) - self.assertEqual(Color.blue.value, 2) - self.assertEqual(Color.green.value, 3) - - def test_auto_name(self): - class Color(Enum): - def _generate_next_value_(name, start, count, last): - return name - red = auto() - blue = auto() - green = auto() - - self.assertEqual(list(Color), [Color.red, Color.blue, Color.green]) - self.assertEqual(Color.red.value, 'red') - self.assertEqual(Color.blue.value, 'blue') - self.assertEqual(Color.green.value, 'green') - - def test_auto_name_inherit(self): - class AutoNameEnum(Enum): - def _generate_next_value_(name, start, count, last): - return name - class Color(AutoNameEnum): - red = auto() - blue = auto() - green = auto() - - self.assertEqual(list(Color), [Color.red, Color.blue, Color.green]) - self.assertEqual(Color.red.value, 'red') - self.assertEqual(Color.blue.value, 'blue') - self.assertEqual(Color.green.value, 'green') - - def test_auto_garbage(self): - class Color(Enum): - red = 'red' - blue = auto() - self.assertEqual(Color.blue.value, 1) - - def test_auto_garbage_corrected(self): - class Color(Enum): - red = 'red' - blue = 2 - green = auto() - - self.assertEqual(list(Color), [Color.red, Color.blue, Color.green]) - self.assertEqual(Color.red.value, 'red') - self.assertEqual(Color.blue.value, 2) - self.assertEqual(Color.green.value, 3) - - def test_auto_order(self): - with self.assertRaises(TypeError): - class Color(Enum): - red = auto() - green = auto() - blue = auto() - def _generate_next_value_(name, start, count, last): - return name - - def test_auto_order_wierd(self): - weird_auto = auto() - weird_auto.value = 'pathological case' - class Color(Enum): - red = weird_auto - def _generate_next_value_(name, start, count, last): - return name - blue = auto() - self.assertEqual(list(Color), [Color.red, Color.blue]) - self.assertEqual(Color.red.value, 'pathological case') - self.assertEqual(Color.blue.value, 'blue') - - def test_duplicate_auto(self): - class Dupes(Enum): - first = primero = auto() - second = auto() - third = auto() - self.assertEqual([Dupes.first, Dupes.second, Dupes.third], list(Dupes)) - - def test_default_missing(self): + def test_default_missing_no_chained_exception(self): class Color(Enum): RED = 1 GREEN = 2 @@ -2006,7 +2243,7 @@ class TestEnum(unittest.TestCase): else: raise Exception('Exception not raised.') - def test_missing(self): + def test_missing_override(self): class Color(Enum): red = 1 green = 2 @@ -2070,9 +2307,9 @@ class TestEnum(unittest.TestCase): class_1_ref = weakref.ref(Class1()) class_2_ref = weakref.ref(Class2()) # - # The exception raised by Enum creates a reference loop and thus - # Class2 instances will stick around until the next garbage collection - # cycle, unlike Class1. + # The exception raised by Enum used to create a reference loop and thus + # Class2 instances would stick around until the next garbage collection + # cycle, unlike Class1. Verify Class2 no longer does this. gc.collect() # For PyPy or other GCs. self.assertIs(class_1_ref(), None) self.assertIs(class_2_ref(), None) @@ -2103,11 +2340,12 @@ class TestEnum(unittest.TestCase): self.assertEqual(Color.GREEN.value, 2) self.assertEqual(Color.BLUE.value, 3) self.assertEqual(Color.MAX, 3) - self.assertEqual(str(Color.BLUE), 'BLUE') + self.assertEqual(str(Color.BLUE), 'Color.BLUE') class Color(MaxMixin, StrMixin, Enum): RED = auto() GREEN = auto() BLUE = auto() + __str__ = StrMixin.__str__ # needed as of 3.11 self.assertEqual(Color.RED.value, 1) self.assertEqual(Color.GREEN.value, 2) self.assertEqual(Color.BLUE.value, 3) @@ -2117,6 +2355,7 @@ class TestEnum(unittest.TestCase): RED = auto() GREEN = auto() BLUE = auto() + __str__ = StrMixin.__str__ # needed as of 3.11 self.assertEqual(Color.RED.value, 1) self.assertEqual(Color.GREEN.value, 2) self.assertEqual(Color.BLUE.value, 3) @@ -2126,6 +2365,7 @@ class TestEnum(unittest.TestCase): RED = auto() GREEN = auto() BLUE = auto() + __str__ = StrMixin.__str__ # needed as of 3.11 self.assertEqual(CoolColor.RED.value, 1) self.assertEqual(CoolColor.GREEN.value, 2) self.assertEqual(CoolColor.BLUE.value, 3) @@ -2135,6 +2375,7 @@ class TestEnum(unittest.TestCase): RED = auto() GREEN = auto() BLUE = auto() + __str__ = StrMixin.__str__ # needed as of 3.11 self.assertEqual(CoolerColor.RED.value, 1) self.assertEqual(CoolerColor.GREEN.value, 2) self.assertEqual(CoolerColor.BLUE.value, 3) @@ -2145,6 +2386,7 @@ class TestEnum(unittest.TestCase): RED = auto() GREEN = auto() BLUE = auto() + __str__ = StrMixin.__str__ # needed as of 3.11 self.assertEqual(CoolestColor.RED.value, 1) self.assertEqual(CoolestColor.GREEN.value, 2) self.assertEqual(CoolestColor.BLUE.value, 3) @@ -2155,6 +2397,7 @@ class TestEnum(unittest.TestCase): RED = auto() GREEN = auto() BLUE = auto() + __str__ = StrMixin.__str__ # needed as of 3.11 self.assertEqual(ConfusedColor.RED.value, 1) self.assertEqual(ConfusedColor.GREEN.value, 2) self.assertEqual(ConfusedColor.BLUE.value, 3) @@ -2165,6 +2408,7 @@ class TestEnum(unittest.TestCase): RED = auto() GREEN = auto() BLUE = auto() + __str__ = StrMixin.__str__ # needed as of 3.11 self.assertEqual(ReformedColor.RED.value, 1) self.assertEqual(ReformedColor.GREEN.value, 2) self.assertEqual(ReformedColor.BLUE.value, 3) @@ -2197,11 +2441,12 @@ class TestEnum(unittest.TestCase): return hex(self) class MyIntEnum(HexMixin, MyInt, enum.Enum): - pass + __repr__ = HexMixin.__repr__ class Foo(MyIntEnum): TEST = 1 self.assertTrue(isinstance(Foo.TEST, MyInt)) + self.assertEqual(Foo._member_type_, MyInt) self.assertEqual(repr(Foo.TEST), "0x1") class Fee(MyIntEnum): @@ -2213,7 +2458,7 @@ class TestEnum(unittest.TestCase): return member self.assertEqual(Fee.TEST, 2) - def test_miltuple_mixin_with_common_data_type(self): + def test_multiple_mixin_with_common_data_type(self): class CaseInsensitiveStrEnum(str, Enum): @classmethod def _missing_(cls, value): @@ -2233,7 +2478,7 @@ class TestEnum(unittest.TestCase): unknown._value_ = value cls._member_map_[value] = unknown return unknown - @property + @enum.property def valid(self): return self._valid # @@ -2277,7 +2522,7 @@ class TestEnum(unittest.TestCase): self.assertEqual('{}'.format(GoodStrEnum.one), '1') self.assertEqual(GoodStrEnum.one, str(GoodStrEnum.one)) self.assertEqual(GoodStrEnum.one, '{}'.format(GoodStrEnum.one)) - self.assertEqual(repr(GoodStrEnum.one), 'GoodStrEnum.one') + self.assertEqual(repr(GoodStrEnum.one), "") # class DumbMixin: def __str__(self): @@ -2286,6 +2531,7 @@ class TestEnum(unittest.TestCase): five = '5' six = '6' seven = '7' + __str__ = DumbMixin.__str__ # needed as of 3.11 self.assertEqual(DumbStrEnum.seven, '7') self.assertEqual(str(DumbStrEnum.seven), "don't do this") # @@ -2327,74 +2573,6 @@ class TestEnum(unittest.TestCase): one = '1' two = b'2', 'ascii', 9 - @unittest.skipIf( - python_version >= (3, 12), - 'mixin-format now uses member instead of member.value', - ) - def test_custom_strenum_with_warning(self): - class CustomStrEnum(str, Enum): - pass - class OkayEnum(CustomStrEnum): - one = '1' - two = '2' - three = b'3', 'ascii' - four = b'4', 'latin1', 'strict' - self.assertEqual(OkayEnum.one, '1') - self.assertEqual(str(OkayEnum.one), 'one') - with self.assertWarns(DeprecationWarning): - self.assertEqual('{}'.format(OkayEnum.one), '1') - self.assertEqual(OkayEnum.one, '{}'.format(OkayEnum.one)) - self.assertEqual(repr(OkayEnum.one), 'OkayEnum.one') - # - class DumbMixin: - def __str__(self): - return "don't do this" - class DumbStrEnum(DumbMixin, CustomStrEnum): - five = '5' - six = '6' - seven = '7' - self.assertEqual(DumbStrEnum.seven, '7') - self.assertEqual(str(DumbStrEnum.seven), "don't do this") - # - class EnumMixin(Enum): - def hello(self): - print('hello from %s' % (self, )) - class HelloEnum(EnumMixin, CustomStrEnum): - eight = '8' - self.assertEqual(HelloEnum.eight, '8') - self.assertEqual(str(HelloEnum.eight), 'eight') - # - class GoodbyeMixin: - def goodbye(self): - print('%s wishes you a fond farewell') - class GoodbyeEnum(GoodbyeMixin, EnumMixin, CustomStrEnum): - nine = '9' - self.assertEqual(GoodbyeEnum.nine, '9') - self.assertEqual(str(GoodbyeEnum.nine), 'nine') - # - class FirstFailedStrEnum(CustomStrEnum): - one = 1 # this will become '1' - two = '2' - class SecondFailedStrEnum(CustomStrEnum): - one = '1' - two = 2, # this will become '2' - three = '3' - class ThirdFailedStrEnum(CustomStrEnum): - one = '1' - two = 2 # this will become '2' - with self.assertRaisesRegex(TypeError, '.encoding. must be str, not '): - class ThirdFailedStrEnum(CustomStrEnum): - one = '1' - two = b'2', sys.getdefaultencoding - with self.assertRaisesRegex(TypeError, '.errors. must be str, not '): - class ThirdFailedStrEnum(CustomStrEnum): - one = '1' - two = b'2', 'ascii', 9 - - @unittest.skipIf( - python_version < (3, 12), - 'mixin-format currently uses member.value', - ) def test_custom_strenum(self): class CustomStrEnum(str, Enum): pass @@ -2404,9 +2582,9 @@ class TestEnum(unittest.TestCase): three = b'3', 'ascii' four = b'4', 'latin1', 'strict' self.assertEqual(OkayEnum.one, '1') - self.assertEqual(str(OkayEnum.one), 'one') - self.assertEqual('{}'.format(OkayEnum.one), 'one') - self.assertEqual(repr(OkayEnum.one), 'OkayEnum.one') + self.assertEqual(str(OkayEnum.one), 'OkayEnum.one') + self.assertEqual('{}'.format(OkayEnum.one), 'OkayEnum.one') + self.assertEqual(repr(OkayEnum.one), "") # class DumbMixin: def __str__(self): @@ -2415,6 +2593,7 @@ class TestEnum(unittest.TestCase): five = '5' six = '6' seven = '7' + __str__ = DumbMixin.__str__ # needed as of 3.11 self.assertEqual(DumbStrEnum.seven, '7') self.assertEqual(str(DumbStrEnum.seven), "don't do this") # @@ -2424,7 +2603,7 @@ class TestEnum(unittest.TestCase): class HelloEnum(EnumMixin, CustomStrEnum): eight = '8' self.assertEqual(HelloEnum.eight, '8') - self.assertEqual(str(HelloEnum.eight), 'eight') + self.assertEqual(str(HelloEnum.eight), 'HelloEnum.eight') # class GoodbyeMixin: def goodbye(self): @@ -2432,7 +2611,7 @@ class TestEnum(unittest.TestCase): class GoodbyeEnum(GoodbyeMixin, EnumMixin, CustomStrEnum): nine = '9' self.assertEqual(GoodbyeEnum.nine, '9') - self.assertEqual(str(GoodbyeEnum.nine), 'nine') + self.assertEqual(str(GoodbyeEnum.nine), 'GoodbyeEnum.nine') # class FirstFailedStrEnum(CustomStrEnum): one = 1 # this will become '1' @@ -2478,21 +2657,6 @@ class TestEnum(unittest.TestCase): code = 'An$(5,1)', 2 description = 'Bn$', 3 - @unittest.skipUnless( - python_version == (3, 9), - 'private variables are now normal attributes', - ) - def test_warning_for_private_variables(self): - with self.assertWarns(DeprecationWarning): - class Private(Enum): - __corporal = 'Radar' - self.assertEqual(Private._Private__corporal.value, 'Radar') - try: - with self.assertWarns(DeprecationWarning): - class Private(Enum): - __major_ = 'Hoolihan' - except ValueError: - pass def test_private_variable_is_normal_attribute(self): class Private(Enum): @@ -2501,35 +2665,28 @@ class TestEnum(unittest.TestCase): self.assertEqual(Private._Private__corporal, 'Radar') self.assertEqual(Private._Private__major_, 'Hoolihan') - @unittest.skipUnless( - python_version < (3, 12), - 'member-member access now raises an exception', - ) - def test_warning_for_member_from_member_access(self): - with self.assertWarns(DeprecationWarning): - class Di(Enum): - YES = 1 - NO = 0 - nope = Di.YES.NO - self.assertIs(Di.NO, nope) - - @unittest.skipUnless( - python_version >= (3, 12), - 'member-member access currently issues a warning', + @unittest.skipIf( + python_version <= (3, 13), + 'member.member access currently deprecated', ) def test_exception_for_member_from_member_access(self): - with self.assertRaisesRegex(AttributeError, "Di: no instance attribute .NO."): + with self.assertRaisesRegex(AttributeError, " member has no attribute .NO."): class Di(Enum): YES = 1 NO = 0 nope = Di.YES.NO - def test_strenum_auto(self): - class Strings(StrEnum): - ONE = auto() - TWO = auto() - self.assertEqual([Strings.ONE, Strings.TWO], ['one', 'two']) - + @unittest.skipIf( + python_version > (3, 13), + 'member.member access now raises', + ) + def test_warning_for_member_from_member_access(self): + with self.assertWarnsRegex(DeprecationWarning, '`member.member` access .* is deprecated and will be removed in 3.14'): + class Di(Enum): + YES = 1 + NO = 0 + warn = Di.YES.NO + self.assertIs(warn, Di.NO) def test_dynamic_members_with_static_methods(self): # @@ -2546,7 +2703,7 @@ class TestEnum(unittest.TestCase): self.assertEqual(Foo.FOO_CAT.value, 'aloof') self.assertEqual(Foo.FOO_HORSE.upper(), 'BIG') # - with self.assertRaisesRegex(TypeError, "'FOO_CAT' already defined as: 'aloof'"): + with self.assertRaisesRegex(TypeError, "'FOO_CAT' already defined as 'aloof'"): class FooBar(Enum): vars().update({ k: v @@ -2558,8 +2715,148 @@ class TestEnum(unittest.TestCase): def upper(self): return self.value.upper() + def test_repr_with_dataclass(self): + "ensure dataclass-mixin has correct repr()" + # + # check overridden dataclass __repr__ is used + # + from dataclasses import dataclass, field + @dataclass(repr=False) + class Foo: + __qualname__ = 'Foo' + a: int + def __repr__(self): + return 'ha hah!' + class Entries(Foo, Enum): + ENTRY1 = 1 + self.assertTrue(isinstance(Entries.ENTRY1, Foo)) + self.assertTrue(Entries._member_type_ is Foo, Entries._member_type_) + self.assertTrue(Entries.ENTRY1.value == Foo(1), Entries.ENTRY1.value) + self.assertEqual(repr(Entries.ENTRY1), '') + # + # check auto-generated dataclass __repr__ is not used + # + @dataclass + class CreatureDataMixin: + __qualname__ = 'CreatureDataMixin' + size: str + legs: int + tail: bool = field(repr=False, default=True) + class Creature(CreatureDataMixin, Enum): + __qualname__ = 'Creature' + BEETLE = ('small', 6) + DOG = ('medium', 4) + self.assertEqual(repr(Creature.DOG), "") + # + # check inherited repr used + # + class Huh: + def __repr__(self): + return 'inherited' + @dataclass(repr=False) + class CreatureDataMixin(Huh): + __qualname__ = 'CreatureDataMixin' + size: str + legs: int + tail: bool = field(repr=False, default=True) + class Creature(CreatureDataMixin, Enum): + __qualname__ = 'Creature' + BEETLE = ('small', 6) + DOG = ('medium', 4) + self.assertEqual(repr(Creature.DOG), "") + # + # check default object.__repr__ used if nothing provided + # + @dataclass(repr=False) + class CreatureDataMixin: + __qualname__ = 'CreatureDataMixin' + size: str + legs: int + tail: bool = field(repr=False, default=True) + class Creature(CreatureDataMixin, Enum): + __qualname__ = 'Creature' + BEETLE = ('small', 6) + DOG = ('medium', 4) + self.assertRegex(repr(Creature.DOG), "") + + def test_repr_with_init_data_type_mixin(self): + # non-data_type is a mixin that doesn't define __new__ + class Foo: + def __init__(self, a): + self.a = a + def __repr__(self): + return f'Foo(a={self.a!r})' + class Entries(Foo, Enum): + ENTRY1 = 1 + # + self.assertEqual(repr(Entries.ENTRY1), '') + + def test_repr_and_str_with_non_data_type_mixin(self): + # non-data_type is a mixin that doesn't define __new__ + class Foo: + def __repr__(self): + return 'Foo' + def __str__(self): + return 'ooF' + class Entries(Foo, Enum): + ENTRY1 = 1 + # + self.assertEqual(repr(Entries.ENTRY1), 'Foo') + self.assertEqual(str(Entries.ENTRY1), 'ooF') + + def test_value_backup_assign(self): + # check that enum will add missing values when custom __new__ does not + class Some(Enum): + def __new__(cls, val): + return object.__new__(cls) + x = 1 + y = 2 + self.assertEqual(Some.x.value, 1) + self.assertEqual(Some.y.value, 2) + + def test_custom_flag_bitwise(self): + class MyIntFlag(int, Flag): + ONE = 1 + TWO = 2 + FOUR = 4 + self.assertTrue(isinstance(MyIntFlag.ONE | MyIntFlag.TWO, MyIntFlag), MyIntFlag.ONE | MyIntFlag.TWO) + self.assertTrue(isinstance(MyIntFlag.ONE | 2, MyIntFlag)) + + def test_int_flags_copy(self): + class MyIntFlag(IntFlag): + ONE = 1 + TWO = 2 + FOUR = 4 + + flags = MyIntFlag.ONE | MyIntFlag.TWO + copied = copy.copy(flags) + deep = copy.deepcopy(flags) + self.assertEqual(copied, flags) + self.assertEqual(deep, flags) + + flags = MyIntFlag.ONE | MyIntFlag.TWO | 8 + copied = copy.copy(flags) + deep = copy.deepcopy(flags) + self.assertEqual(copied, flags) + self.assertEqual(deep, flags) + self.assertEqual(copied.value, 1 | 2 | 8) + + def test_namedtuple_as_value(self): + from collections import namedtuple + TTuple = namedtuple('TTuple', 'id a blist') + class NTEnum(Enum): + NONE = TTuple(0, 0, []) + A = TTuple(1, 2, [4]) + B = TTuple(2, 4, [0, 1, 2]) + self.assertEqual(repr(NTEnum.NONE), "") + self.assertEqual(NTEnum.NONE.value, TTuple(id=0, a=0, blist=[])) + self.assertEqual( + [x.value for x in NTEnum], + [TTuple(id=0, a=0, blist=[]), TTuple(id=1, a=2, blist=[4]), TTuple(id=2, a=4, blist=[0, 1, 2])], + ) class TestOrder(unittest.TestCase): + "test usage of the `_order_` attribute" def test_same_members(self): class Color(Enum): @@ -2621,7 +2918,7 @@ class TestOrder(unittest.TestCase): verde = green -class TestFlag(unittest.TestCase): +class OldTestFlag(unittest.TestCase): """Tests of the Flags.""" class Perm(Flag): @@ -2644,65 +2941,6 @@ class TestFlag(unittest.TestCase): WHITE = RED|GREEN|BLUE BLANCO = RED|GREEN|BLUE - def test_str(self): - Perm = self.Perm - self.assertEqual(str(Perm.R), 'R') - self.assertEqual(str(Perm.W), 'W') - self.assertEqual(str(Perm.X), 'X') - self.assertEqual(str(Perm.R | Perm.W), 'R|W') - self.assertEqual(str(Perm.R | Perm.W | Perm.X), 'R|W|X') - self.assertEqual(str(Perm(0)), 'Perm(0)') - self.assertEqual(str(~Perm.R), 'W|X') - self.assertEqual(str(~Perm.W), 'R|X') - self.assertEqual(str(~Perm.X), 'R|W') - self.assertEqual(str(~(Perm.R | Perm.W)), 'X') - self.assertEqual(str(~(Perm.R | Perm.W | Perm.X)), 'Perm(0)') - self.assertEqual(str(Perm(~0)), 'R|W|X') - - Open = self.Open - self.assertEqual(str(Open.RO), 'RO') - self.assertEqual(str(Open.WO), 'WO') - self.assertEqual(str(Open.AC), 'AC') - self.assertEqual(str(Open.RO | Open.CE), 'CE') - self.assertEqual(str(Open.WO | Open.CE), 'WO|CE') - self.assertEqual(str(~Open.RO), 'WO|RW|CE') - self.assertEqual(str(~Open.WO), 'RW|CE') - self.assertEqual(str(~Open.AC), 'CE') - self.assertEqual(str(~(Open.RO | Open.CE)), 'AC') - self.assertEqual(str(~(Open.WO | Open.CE)), 'RW') - - def test_repr(self): - Perm = self.Perm - self.assertEqual(repr(Perm.R), 'Perm.R') - self.assertEqual(repr(Perm.W), 'Perm.W') - self.assertEqual(repr(Perm.X), 'Perm.X') - self.assertEqual(repr(Perm.R | Perm.W), 'Perm.R|Perm.W') - self.assertEqual(repr(Perm.R | Perm.W | Perm.X), 'Perm.R|Perm.W|Perm.X') - self.assertEqual(repr(Perm(0)), '0x0') - self.assertEqual(repr(~Perm.R), 'Perm.W|Perm.X') - self.assertEqual(repr(~Perm.W), 'Perm.R|Perm.X') - self.assertEqual(repr(~Perm.X), 'Perm.R|Perm.W') - self.assertEqual(repr(~(Perm.R | Perm.W)), 'Perm.X') - self.assertEqual(repr(~(Perm.R | Perm.W | Perm.X)), '0x0') - self.assertEqual(repr(Perm(~0)), 'Perm.R|Perm.W|Perm.X') - - Open = self.Open - self.assertEqual(repr(Open.RO), 'Open.RO') - self.assertEqual(repr(Open.WO), 'Open.WO') - self.assertEqual(repr(Open.AC), 'Open.AC') - self.assertEqual(repr(Open.RO | Open.CE), 'Open.CE') - self.assertEqual(repr(Open.WO | Open.CE), 'Open.WO|Open.CE') - self.assertEqual(repr(~Open.RO), 'Open.WO|Open.RW|Open.CE') - self.assertEqual(repr(~Open.WO), 'Open.RW|Open.CE') - self.assertEqual(repr(~Open.AC), 'Open.CE') - self.assertEqual(repr(~(Open.RO | Open.CE)), 'Open.AC') - self.assertEqual(repr(~(Open.WO | Open.CE)), 'Open.RW') - - def test_format(self): - Perm = self.Perm - self.assertEqual(format(Perm.R, ''), 'R') - self.assertEqual(format(Perm.R | Perm.X, ''), 'R|X') - def test_or(self): Perm = self.Perm for i in Perm: @@ -2771,7 +3009,7 @@ class TestFlag(unittest.TestCase): self.assertEqual(bool(f.value), bool(f)) def test_boundary(self): - self.assertIs(enum.Flag._boundary_, STRICT) + self.assertIs(enum.Flag._boundary_, CONFORM) class Iron(Flag, boundary=STRICT): ONE = 1 TWO = 2 @@ -2795,7 +3033,7 @@ class TestFlag(unittest.TestCase): c = 4 d = 6 # - self.assertRaisesRegex(ValueError, 'invalid value: 7', Iron, 7) + self.assertRaisesRegex(ValueError, 'invalid value 7', Iron, 7) # self.assertIs(Water(7), Water.ONE|Water.TWO) self.assertIs(Water(~9), Water.TWO) @@ -2891,35 +3129,32 @@ class TestFlag(unittest.TestCase): def test_pickle(self): if isinstance(FlagStooges, Exception): raise FlagStooges - test_pickle_dump_load(self.assertIs, FlagStooges.CURLY|FlagStooges.MOE) + test_pickle_dump_load(self.assertIs, FlagStooges.CURLY) + test_pickle_dump_load(self.assertEqual, + FlagStooges.CURLY|FlagStooges.MOE) + test_pickle_dump_load(self.assertEqual, + FlagStooges.CURLY&~FlagStooges.CURLY) test_pickle_dump_load(self.assertIs, FlagStooges) - @unittest.skipIf( - python_version >= (3, 12), - '__contains__ now returns True/False for all inputs', - ) - def test_contains_er(self): - Open = self.Open - Color = self.Color - self.assertFalse(Color.BLACK in Open) - self.assertFalse(Open.RO in Color) - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 'BLACK' in Color - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 'RO' in Open - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 1 in Color - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 1 in Open + test_pickle_dump_load(self.assertIs, FlagStoogesWithZero.CURLY) + test_pickle_dump_load(self.assertEqual, + FlagStoogesWithZero.CURLY|FlagStoogesWithZero.MOE) + test_pickle_dump_load(self.assertIs, FlagStoogesWithZero.NOFLAG) + + test_pickle_dump_load(self.assertIs, IntFlagStooges.CURLY) + test_pickle_dump_load(self.assertEqual, + IntFlagStooges.CURLY|IntFlagStooges.MOE) + test_pickle_dump_load(self.assertEqual, + IntFlagStooges.CURLY|IntFlagStooges.MOE|0x30) + test_pickle_dump_load(self.assertEqual, IntFlagStooges(0)) + test_pickle_dump_load(self.assertEqual, IntFlagStooges(0x30)) + test_pickle_dump_load(self.assertIs, IntFlagStooges) + + test_pickle_dump_load(self.assertIs, IntFlagStoogesWithZero.CURLY) + test_pickle_dump_load(self.assertEqual, + IntFlagStoogesWithZero.CURLY|IntFlagStoogesWithZero.MOE) + test_pickle_dump_load(self.assertIs, IntFlagStoogesWithZero.NOFLAG) - @unittest.skipIf( - python_version < (3, 12), - '__contains__ only works with enum memmbers before 3.12', - ) def test_contains_tf(self): Open = self.Open Color = self.Color @@ -2927,6 +3162,8 @@ class TestFlag(unittest.TestCase): self.assertFalse(Open.RO in Color) self.assertFalse('BLACK' in Color) self.assertFalse('RO' in Open) + self.assertTrue(Color.BLACK in Color) + self.assertTrue(Open.RO in Open) self.assertTrue(1 in Color) self.assertTrue(1 in Open) @@ -3004,7 +3241,7 @@ class TestFlag(unittest.TestCase): self.assertEqual(Color.green.value, 4) def test_auto_number_garbage(self): - with self.assertRaisesRegex(TypeError, 'Invalid Flag value: .not an int.'): + with self.assertRaisesRegex(TypeError, 'invalid flag value .not an int.'): class Color(Flag): red = 'not an int' blue = auto() @@ -3039,11 +3276,12 @@ class TestFlag(unittest.TestCase): self.assertEqual(Color.GREEN.value, 2) self.assertEqual(Color.BLUE.value, 4) self.assertEqual(Color.ALL.value, 7) - self.assertEqual(str(Color.BLUE), 'BLUE') + self.assertEqual(str(Color.BLUE), 'Color.BLUE') class Color(AllMixin, StrMixin, Flag): RED = auto() GREEN = auto() BLUE = auto() + __str__ = StrMixin.__str__ self.assertEqual(Color.RED.value, 1) self.assertEqual(Color.GREEN.value, 2) self.assertEqual(Color.BLUE.value, 4) @@ -3053,6 +3291,7 @@ class TestFlag(unittest.TestCase): RED = auto() GREEN = auto() BLUE = auto() + __str__ = StrMixin.__str__ self.assertEqual(Color.RED.value, 1) self.assertEqual(Color.GREEN.value, 2) self.assertEqual(Color.BLUE.value, 4) @@ -3060,6 +3299,7 @@ class TestFlag(unittest.TestCase): self.assertEqual(str(Color.BLUE), 'blue') @threading_helper.reap_threads + @threading_helper.requires_working_threading() def test_unique_composite(self): # override __eq__ to be identity only class TestFlag(Flag): @@ -3134,7 +3374,7 @@ class TestFlag(unittest.TestCase): self.assertFalse(NeverEnum.__dict__.get('_test2', False)) -class TestIntFlag(unittest.TestCase): +class OldTestIntFlag(unittest.TestCase): """Tests of the IntFlags.""" class Perm(IntFlag): @@ -3179,73 +3419,6 @@ class TestIntFlag(unittest.TestCase): self.assertTrue(isinstance(Open.WO | Open.RW, Open)) self.assertEqual(Open.WO | Open.RW, 3) - - def test_str(self): - Perm = self.Perm - self.assertEqual(str(Perm.R), 'R') - self.assertEqual(str(Perm.W), 'W') - self.assertEqual(str(Perm.X), 'X') - self.assertEqual(str(Perm.R | Perm.W), 'R|W') - self.assertEqual(str(Perm.R | Perm.W | Perm.X), 'R|W|X') - self.assertEqual(str(Perm.R | 8), '12') - self.assertEqual(str(Perm(0)), 'Perm(0)') - self.assertEqual(str(Perm(8)), '8') - self.assertEqual(str(~Perm.R), 'W|X') - self.assertEqual(str(~Perm.W), 'R|X') - self.assertEqual(str(~Perm.X), 'R|W') - self.assertEqual(str(~(Perm.R | Perm.W)), 'X') - self.assertEqual(str(~(Perm.R | Perm.W | Perm.X)), 'Perm(0)') - self.assertEqual(str(~(Perm.R | 8)), '-13') - self.assertEqual(str(Perm(~0)), 'R|W|X') - self.assertEqual(str(Perm(~8)), '-9') - - Open = self.Open - self.assertEqual(str(Open.RO), 'RO') - self.assertEqual(str(Open.WO), 'WO') - self.assertEqual(str(Open.AC), 'AC') - self.assertEqual(str(Open.RO | Open.CE), 'CE') - self.assertEqual(str(Open.WO | Open.CE), 'WO|CE') - self.assertEqual(str(Open(4)), '4') - self.assertEqual(str(~Open.RO), 'WO|RW|CE') - self.assertEqual(str(~Open.WO), 'RW|CE') - self.assertEqual(str(~Open.AC), 'CE') - self.assertEqual(str(~(Open.RO | Open.CE)), 'AC') - self.assertEqual(str(~(Open.WO | Open.CE)), 'RW') - self.assertEqual(str(Open(~4)), '-5') - - def test_repr(self): - Perm = self.Perm - self.assertEqual(repr(Perm.R), 'Perm.R') - self.assertEqual(repr(Perm.W), 'Perm.W') - self.assertEqual(repr(Perm.X), 'Perm.X') - self.assertEqual(repr(Perm.R | Perm.W), 'Perm.R|Perm.W') - self.assertEqual(repr(Perm.R | Perm.W | Perm.X), 'Perm.R|Perm.W|Perm.X') - self.assertEqual(repr(Perm.R | 8), '12') - self.assertEqual(repr(Perm(0)), '0x0') - self.assertEqual(repr(Perm(8)), '8') - self.assertEqual(repr(~Perm.R), 'Perm.W|Perm.X') - self.assertEqual(repr(~Perm.W), 'Perm.R|Perm.X') - self.assertEqual(repr(~Perm.X), 'Perm.R|Perm.W') - self.assertEqual(repr(~(Perm.R | Perm.W)), 'Perm.X') - self.assertEqual(repr(~(Perm.R | Perm.W | Perm.X)), '0x0') - self.assertEqual(repr(~(Perm.R | 8)), '-13') - self.assertEqual(repr(Perm(~0)), 'Perm.R|Perm.W|Perm.X') - self.assertEqual(repr(Perm(~8)), '-9') - - Open = self.Open - self.assertEqual(repr(Open.RO), 'Open.RO') - self.assertEqual(repr(Open.WO), 'Open.WO') - self.assertEqual(repr(Open.AC), 'Open.AC') - self.assertEqual(repr(Open.RO | Open.CE), 'Open.CE') - self.assertEqual(repr(Open.WO | Open.CE), 'Open.WO|Open.CE') - self.assertEqual(repr(Open(4)), '4') - self.assertEqual(repr(~Open.RO), 'Open.WO|Open.RW|Open.CE') - self.assertEqual(repr(~Open.WO), 'Open.RW|Open.CE') - self.assertEqual(repr(~Open.AC), 'Open.CE') - self.assertEqual(repr(~(Open.RO | Open.CE)), 'Open.AC') - self.assertEqual(repr(~(Open.WO | Open.CE)), 'Open.RW') - self.assertEqual(repr(Open(~4)), '-5') - def test_global_repr_keep(self): self.assertEqual( repr(HeadlightsK(0)), @@ -3253,11 +3426,11 @@ class TestIntFlag(unittest.TestCase): ) self.assertEqual( repr(HeadlightsK(2**0 + 2**2 + 2**3)), - '%(m)s.LOW_BEAM_K|%(m)s.FOG_K|0x8' % {'m': SHORT_MODULE}, + '%(m)s.LOW_BEAM_K|%(m)s.FOG_K|8' % {'m': SHORT_MODULE}, ) self.assertEqual( repr(HeadlightsK(2**3)), - '%(m)s.HeadlightsK(0x8)' % {'m': SHORT_MODULE}, + '%(m)s.HeadlightsK(8)' % {'m': SHORT_MODULE}, ) def test_global_repr_conform1(self): @@ -3274,6 +3447,10 @@ class TestIntFlag(unittest.TestCase): '%(m)s.OFF_C' % {'m': SHORT_MODULE}, ) + def test_global_enum_str(self): + self.assertEqual(str(NoName.ONE & NoName.TWO), 'NoName(0)') + self.assertEqual(str(NoName(0)), 'NoName(0)') + def test_format(self): Perm = self.Perm self.assertEqual(format(Perm.R, ''), '4') @@ -3374,7 +3551,10 @@ class TestIntFlag(unittest.TestCase): self.assertIs((Open.WO|Open.CE) & ~Open.WO, Open.CE) def test_boundary(self): - self.assertIs(enum.IntFlag._boundary_, EJECT) + self.assertIs(enum.IntFlag._boundary_, KEEP) + class Simple(IntFlag, boundary=KEEP): + SINGLE = 1 + # class Iron(IntFlag, boundary=STRICT): ONE = 1 TWO = 2 @@ -3393,13 +3573,12 @@ class TestIntFlag(unittest.TestCase): EIGHT = 8 self.assertIs(Space._boundary_, EJECT) # - # class Bizarre(IntFlag, boundary=KEEP): b = 3 c = 4 d = 6 # - self.assertRaisesRegex(ValueError, 'invalid value: 5', Iron, 5) + self.assertRaisesRegex(ValueError, 'invalid value 5', Iron, 5) # self.assertIs(Water(7), Water.ONE|Water.TWO) self.assertIs(Water(~9), Water.TWO) @@ -3410,6 +3589,12 @@ class TestIntFlag(unittest.TestCase): self.assertEqual(list(Bizarre), [Bizarre.c]) self.assertIs(Bizarre(3), Bizarre.b) self.assertIs(Bizarre(6), Bizarre.d) + # + simple = Simple.SINGLE | Iron.TWO + self.assertEqual(simple, 3) + self.assertIsInstance(simple, Simple) + self.assertEqual(repr(simple), ': 3>') + self.assertEqual(str(simple), '3') def test_iter(self): Color = self.Color @@ -3518,41 +3703,11 @@ class TestIntFlag(unittest.TestCase): self.assertEqual(len(lst), len(Thing)) self.assertEqual(len(Thing), 0, Thing) - @unittest.skipIf( - python_version >= (3, 12), - '__contains__ now returns True/False for all inputs', - ) - def test_contains_er(self): - Open = self.Open - Color = self.Color - self.assertTrue(Color.GREEN in Color) - self.assertTrue(Open.RW in Open) - self.assertFalse(Color.GREEN in Open) - self.assertFalse(Open.RW in Color) - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 'GREEN' in Color - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 'RW' in Open - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 2 in Color - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 2 in Open - - @unittest.skipIf( - python_version < (3, 12), - '__contains__ only works with enum memmbers before 3.12', - ) def test_contains_tf(self): Open = self.Open Color = self.Color self.assertTrue(Color.GREEN in Color) self.assertTrue(Open.RW in Open) - self.assertTrue(Color.GREEN in Open) - self.assertTrue(Open.RW in Color) self.assertFalse('GREEN' in Color) self.assertFalse('RW' in Open) self.assertTrue(2 in Color) @@ -3636,11 +3791,12 @@ class TestIntFlag(unittest.TestCase): self.assertEqual(Color.GREEN.value, 2) self.assertEqual(Color.BLUE.value, 4) self.assertEqual(Color.ALL.value, 7) - self.assertEqual(str(Color.BLUE), 'BLUE') + self.assertEqual(str(Color.BLUE), '4') class Color(AllMixin, StrMixin, IntFlag): RED = auto() GREEN = auto() BLUE = auto() + __str__ = StrMixin.__str__ self.assertEqual(Color.RED.value, 1) self.assertEqual(Color.GREEN.value, 2) self.assertEqual(Color.BLUE.value, 4) @@ -3650,6 +3806,7 @@ class TestIntFlag(unittest.TestCase): RED = auto() GREEN = auto() BLUE = auto() + __str__ = StrMixin.__str__ self.assertEqual(Color.RED.value, 1) self.assertEqual(Color.GREEN.value, 2) self.assertEqual(Color.BLUE.value, 4) @@ -3657,6 +3814,7 @@ class TestIntFlag(unittest.TestCase): self.assertEqual(str(Color.BLUE), 'blue') @threading_helper.reap_threads + @threading_helper.requires_working_threading() def test_unique_composite(self): # override __eq__ to be identity only class TestFlag(IntFlag): @@ -3884,7 +4042,17 @@ class TestVerify(unittest.TestCase): triple = 3 value = 4 -class TestHelpers(unittest.TestCase): + def test_negative_alias(self): + @verify(NAMED_FLAGS) + class Color(Flag): + RED = 1 + GREEN = 2 + BLUE = 4 + WHITE = -1 + # no error means success + + +class TestInternals(unittest.TestCase): sunder_names = '_bad_', '_good_', '_what_ho_' dunder_names = '__mal__', '__bien__', '__que_que__' @@ -3910,6 +4078,180 @@ class TestHelpers(unittest.TestCase): for name in self.sunder_names + self.dunder_names + self.random_names: self.assertFalse(enum._is_private('MyEnum', name), '%r is a private name?') + def test_auto_number(self): + class Color(Enum): + red = auto() + blue = auto() + green = auto() + + self.assertEqual(list(Color), [Color.red, Color.blue, Color.green]) + self.assertEqual(Color.red.value, 1) + self.assertEqual(Color.blue.value, 2) + self.assertEqual(Color.green.value, 3) + + def test_auto_name(self): + class Color(Enum): + def _generate_next_value_(name, start, count, last): + return name + red = auto() + blue = auto() + green = auto() + + self.assertEqual(list(Color), [Color.red, Color.blue, Color.green]) + self.assertEqual(Color.red.value, 'red') + self.assertEqual(Color.blue.value, 'blue') + self.assertEqual(Color.green.value, 'green') + + def test_auto_name_inherit(self): + class AutoNameEnum(Enum): + def _generate_next_value_(name, start, count, last): + return name + class Color(AutoNameEnum): + red = auto() + blue = auto() + green = auto() + + self.assertEqual(list(Color), [Color.red, Color.blue, Color.green]) + self.assertEqual(Color.red.value, 'red') + self.assertEqual(Color.blue.value, 'blue') + self.assertEqual(Color.green.value, 'green') + + @unittest.skipIf( + python_version >= (3, 13), + 'mixed types with auto() no longer supported', + ) + def test_auto_garbage_ok(self): + with self.assertWarnsRegex(DeprecationWarning, 'will require all values to be sortable'): + class Color(Enum): + red = 'red' + blue = auto() + self.assertEqual(Color.blue.value, 1) + + @unittest.skipIf( + python_version >= (3, 13), + 'mixed types with auto() no longer supported', + ) + def test_auto_garbage_corrected_ok(self): + with self.assertWarnsRegex(DeprecationWarning, 'will require all values to be sortable'): + class Color(Enum): + red = 'red' + blue = 2 + green = auto() + + self.assertEqual(list(Color), [Color.red, Color.blue, Color.green]) + self.assertEqual(Color.red.value, 'red') + self.assertEqual(Color.blue.value, 2) + self.assertEqual(Color.green.value, 3) + + @unittest.skipIf( + python_version < (3, 13), + 'mixed types with auto() will raise in 3.13', + ) + def test_auto_garbage_fail(self): + with self.assertRaisesRegex(TypeError, 'will require all values to be sortable'): + class Color(Enum): + red = 'red' + blue = auto() + + @unittest.skipIf( + python_version < (3, 13), + 'mixed types with auto() will raise in 3.13', + ) + def test_auto_garbage_corrected_fail(self): + with self.assertRaisesRegex(TypeError, 'will require all values to be sortable'): + class Color(Enum): + red = 'red' + blue = 2 + green = auto() + + def test_auto_order(self): + with self.assertRaises(TypeError): + class Color(Enum): + red = auto() + green = auto() + blue = auto() + def _generate_next_value_(name, start, count, last): + return name + + def test_auto_order_wierd(self): + weird_auto = auto() + weird_auto.value = 'pathological case' + class Color(Enum): + red = weird_auto + def _generate_next_value_(name, start, count, last): + return name + blue = auto() + self.assertEqual(list(Color), [Color.red, Color.blue]) + self.assertEqual(Color.red.value, 'pathological case') + self.assertEqual(Color.blue.value, 'blue') + + @unittest.skipIf( + python_version < (3, 13), + 'auto() will return highest value + 1 in 3.13', + ) + def test_auto_with_aliases(self): + class Color(Enum): + red = auto() + blue = auto() + oxford = blue + crimson = red + green = auto() + self.assertIs(Color.crimson, Color.red) + self.assertIs(Color.oxford, Color.blue) + self.assertIsNot(Color.green, Color.red) + self.assertIsNot(Color.green, Color.blue) + + def test_duplicate_auto(self): + class Dupes(Enum): + first = primero = auto() + second = auto() + third = auto() + self.assertEqual([Dupes.first, Dupes.second, Dupes.third], list(Dupes)) + + def test_multiple_auto_on_line(self): + class Huh(Enum): + ONE = auto() + TWO = auto(), auto() + THREE = auto(), auto(), auto() + self.assertEqual(Huh.ONE.value, 1) + self.assertEqual(Huh.TWO.value, (2, 3)) + self.assertEqual(Huh.THREE.value, (4, 5, 6)) + # + class Hah(Enum): + def __new__(cls, value, abbr=None): + member = object.__new__(cls) + member._value_ = value + member.abbr = abbr or value[:3].lower() + return member + def _generate_next_value_(name, start, count, last): + return name + # + MONDAY = auto() + TUESDAY = auto() + WEDNESDAY = auto(), 'WED' + THURSDAY = auto(), 'Thu' + FRIDAY = auto() + self.assertEqual(Hah.MONDAY.value, 'MONDAY') + self.assertEqual(Hah.MONDAY.abbr, 'mon') + self.assertEqual(Hah.TUESDAY.value, 'TUESDAY') + self.assertEqual(Hah.TUESDAY.abbr, 'tue') + self.assertEqual(Hah.WEDNESDAY.value, 'WEDNESDAY') + self.assertEqual(Hah.WEDNESDAY.abbr, 'WED') + self.assertEqual(Hah.THURSDAY.value, 'THURSDAY') + self.assertEqual(Hah.THURSDAY.abbr, 'Thu') + self.assertEqual(Hah.FRIDAY.value, 'FRIDAY') + self.assertEqual(Hah.FRIDAY.abbr, 'fri') + # + class Huh(Enum): + def _generate_next_value_(name, start, count, last): + return count+1 + ONE = auto() + TWO = auto(), auto() + THREE = auto(), auto(), auto() + self.assertEqual(Huh.ONE.value, 1) + self.assertEqual(Huh.TWO.value, (2, 2)) + self.assertEqual(Huh.THREE.value, (3, 3, 3)) + class TestEnumTypeSubclassing(unittest.TestCase): pass @@ -3917,38 +4259,55 @@ expected_help_output_with_docs = """\ Help on class Color in module %s: class Color(enum.Enum) - | Color(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None) - |\x20\x20 - | An enumeration. - |\x20\x20 + | Color(*values) + | | Method resolution order: | Color | enum.Enum | builtins.object - |\x20\x20 + | | Data and other attributes defined here: - |\x20\x20 - | blue = Color.blue - |\x20\x20 - | green = Color.green - |\x20\x20 - | red = Color.red - |\x20\x20 + | + | CYAN = + | + | MAGENTA = + | + | YELLOW = + | | ---------------------------------------------------------------------- | Data descriptors inherited from enum.Enum: - |\x20\x20 + | | name | The name of the Enum member. - |\x20\x20 + | | value | The value of the Enum member. - |\x20\x20 + | + | ---------------------------------------------------------------------- + | Methods inherited from enum.EnumType: + | + | __contains__(value) from enum.EnumType + | Return True if `value` is in `cls`. + | + | `value` is in `cls` if: + | 1) `value` is a member of `cls`, or + | 2) `value` is the value of one of the `cls`'s members. + | + | __getitem__(name) from enum.EnumType + | Return the member matching `name`. + | + | __iter__() from enum.EnumType + | Return members in definition order. + | + | __len__() from enum.EnumType + | Return the number of members (no aliases) + | | ---------------------------------------------------------------------- | Readonly properties inherited from enum.EnumType: - |\x20\x20 + | | __members__ | Returns a mapping of member name->value. - |\x20\x20\x20\x20\x20\x20 + | | This mapping lists all enum members, including aliases. Note that this | is a read-only view of the internal mapping.""" @@ -3956,31 +4315,31 @@ expected_help_output_without_docs = """\ Help on class Color in module %s: class Color(enum.Enum) - | Color(value, names=None, *, module=None, qualname=None, type=None, start=1) - |\x20\x20 + | Color(*values) + | | Method resolution order: | Color | enum.Enum | builtins.object - |\x20\x20 + | | Data and other attributes defined here: - |\x20\x20 - | blue = Color.blue - |\x20\x20 - | green = Color.green - |\x20\x20 - | red = Color.red - |\x20\x20 + | + | YELLOW = + | + | MAGENTA = + | + | CYAN = + | | ---------------------------------------------------------------------- | Data descriptors inherited from enum.Enum: - |\x20\x20 + | | name - |\x20\x20 + | | value - |\x20\x20 + | | ---------------------------------------------------------------------- | Data descriptors inherited from enum.EnumType: - |\x20\x20 + | | __members__""" class TestStdLib(unittest.TestCase): @@ -3988,9 +4347,9 @@ class TestStdLib(unittest.TestCase): maxDiff = None class Color(Enum): - red = 1 - green = 2 - blue = 3 + CYAN = 1 + MAGENTA = 2 + YELLOW = 3 def test_pydoc(self): # indirectly test __objclass__ @@ -4002,24 +4361,34 @@ class TestStdLib(unittest.TestCase): helper = pydoc.Helper(output=output) helper(self.Color) result = output.getvalue().strip() - self.assertEqual(result, expected_text) + self.assertEqual(result, expected_text, result) def test_inspect_getmembers(self): values = dict(( ('__class__', EnumType), - ('__doc__', 'An enumeration.'), + ('__doc__', '...'), ('__members__', self.Color.__members__), ('__module__', __name__), - ('blue', self.Color.blue), - ('green', self.Color.green), + ('YELLOW', self.Color.YELLOW), + ('MAGENTA', self.Color.MAGENTA), + ('CYAN', self.Color.CYAN), ('name', Enum.__dict__['name']), - ('red', self.Color.red), ('value', Enum.__dict__['value']), + ('__len__', self.Color.__len__), + ('__contains__', self.Color.__contains__), + ('__name__', 'Color'), + ('__getitem__', self.Color.__getitem__), + ('__qualname__', 'TestStdLib.Color'), + ('__init_subclass__', getattr(self.Color, '__init_subclass__')), + ('__iter__', self.Color.__iter__), )) result = dict(inspect.getmembers(self.Color)) self.assertEqual(set(values.keys()), set(result.keys())) failed = False for k in values.keys(): + if k == '__doc__': + # __doc__ is huge, not comparing + continue if result[k] != values[k]: print() print('\n%s\n key: %s\n result: %s\nexpected: %s\n%s\n' % @@ -4034,23 +4403,42 @@ class TestStdLib(unittest.TestCase): values = [ Attribute(name='__class__', kind='data', defining_class=object, object=EnumType), + Attribute(name='__contains__', kind='method', + defining_class=EnumType, object=self.Color.__contains__), Attribute(name='__doc__', kind='data', - defining_class=self.Color, object='An enumeration.'), + defining_class=self.Color, object='...'), + Attribute(name='__getitem__', kind='method', + defining_class=EnumType, object=self.Color.__getitem__), + Attribute(name='__iter__', kind='method', + defining_class=EnumType, object=self.Color.__iter__), + Attribute(name='__init_subclass__', kind='class method', + defining_class=object, object=getattr(self.Color, '__init_subclass__')), + Attribute(name='__len__', kind='method', + defining_class=EnumType, object=self.Color.__len__), Attribute(name='__members__', kind='property', defining_class=EnumType, object=EnumType.__members__), Attribute(name='__module__', kind='data', defining_class=self.Color, object=__name__), - Attribute(name='blue', kind='data', - defining_class=self.Color, object=self.Color.blue), - Attribute(name='green', kind='data', - defining_class=self.Color, object=self.Color.green), - Attribute(name='red', kind='data', - defining_class=self.Color, object=self.Color.red), + Attribute(name='__name__', kind='data', + defining_class=self.Color, object='Color'), + Attribute(name='__qualname__', kind='data', + defining_class=self.Color, object='TestStdLib.Color'), + Attribute(name='YELLOW', kind='data', + defining_class=self.Color, object=self.Color.YELLOW), + Attribute(name='MAGENTA', kind='data', + defining_class=self.Color, object=self.Color.MAGENTA), + Attribute(name='CYAN', kind='data', + defining_class=self.Color, object=self.Color.CYAN), Attribute(name='name', kind='data', defining_class=Enum, object=Enum.__dict__['name']), Attribute(name='value', kind='data', defining_class=Enum, object=Enum.__dict__['value']), ] + for v in values: + try: + v.name + except AttributeError: + print(v) values.sort(key=lambda item: item.name) result = list(inspect.classify_class_attrs(self.Color)) result.sort(key=lambda item: item.name) @@ -4060,24 +4448,59 @@ class TestStdLib(unittest.TestCase): ) failed = False for v, r in zip(values, result): - if r != v: + if r.name in ('__init_subclass__', '__doc__'): + # not sure how to make the __init_subclass_ Attributes match + # so as long as there is one, call it good + # __doc__ is too big to check exactly, so treat the same as __init_subclass__ + for name in ('name','kind','defining_class'): + if getattr(v, name) != getattr(r, name): + print('\n%s\n%s\n%s\n%s\n' % ('=' * 75, r, v, '=' * 75), sep='') + failed = True + elif r != v: print('\n%s\n%s\n%s\n%s\n' % ('=' * 75, r, v, '=' * 75), sep='') failed = True if failed: self.fail("result does not equal expected, see print above") + def test_inspect_signatures(self): + from inspect import signature, Signature, Parameter + self.assertEqual( + signature(Enum), + Signature([ + Parameter('new_class_name', Parameter.POSITIONAL_ONLY), + Parameter('names', Parameter.POSITIONAL_OR_KEYWORD), + Parameter('module', Parameter.KEYWORD_ONLY, default=None), + Parameter('qualname', Parameter.KEYWORD_ONLY, default=None), + Parameter('type', Parameter.KEYWORD_ONLY, default=None), + Parameter('start', Parameter.KEYWORD_ONLY, default=1), + Parameter('boundary', Parameter.KEYWORD_ONLY, default=None), + ]), + ) + self.assertEqual( + signature(enum.FlagBoundary), + Signature([ + Parameter('values', Parameter.VAR_POSITIONAL), + ]), + ) + def test_test_simple_enum(self): @_simple_enum(Enum) class SimpleColor: - RED = 1 - GREEN = 2 - BLUE = 3 + CYAN = 1 + MAGENTA = 2 + YELLOW = 3 + @bltns.property + def zeroth(self): + return 'zeroed %s' % self.name class CheckedColor(Enum): - RED = 1 - GREEN = 2 - BLUE = 3 + CYAN = 1 + MAGENTA = 2 + YELLOW = 3 + @bltns.property + def zeroth(self): + return 'zeroed %s' % self.name self.assertTrue(_test_simple_enum(CheckedColor, SimpleColor) is None) - SimpleColor.GREEN._value_ = 9 + SimpleColor.MAGENTA._value_ = 9 self.assertRaisesRegex( TypeError, "enum mismatch", _test_simple_enum, CheckedColor, SimpleColor, @@ -4103,9 +4526,37 @@ class TestStdLib(unittest.TestCase): class MiscTestCase(unittest.TestCase): + def test__all__(self): support.check__all__(self, enum, not_exported={'bin', 'show_flag_values'}) + def test_doc_1(self): + class Single(Enum): + ONE = 1 + self.assertEqual(Single.__doc__, None) + + def test_doc_2(self): + class Double(Enum): + ONE = 1 + TWO = 2 + self.assertEqual(Double.__doc__, None) + + + def test_doc_1(self): + class Triple(Enum): + ONE = 1 + TWO = 2 + THREE = 3 + self.assertEqual(Triple.__doc__, None) + + def test_doc_1(self): + class Quadruple(Enum): + ONE = 1 + TWO = 2 + THREE = 3 + FOUR = 4 + self.assertEqual(Quadruple.__doc__, None) + # These are unordered here on purpose to ensure that declaration order # makes no difference. @@ -4123,14 +4574,34 @@ CONVERT_STRING_TEST_NAME_A = 5 # This one should sort first. CONVERT_STRING_TEST_NAME_E = 5 CONVERT_STRING_TEST_NAME_F = 5 -class TestIntEnumConvert(unittest.TestCase): - def setUp(self): +# global names for StrEnum._convert_ test +CONVERT_STR_TEST_2 = 'goodbye' +CONVERT_STR_TEST_1 = 'hello' + +# We also need values that cannot be compared: +UNCOMPARABLE_A = 5 +UNCOMPARABLE_C = (9, 1) # naming order is broken on purpose +UNCOMPARABLE_B = 'value' + +COMPLEX_C = 1j +COMPLEX_A = 2j +COMPLEX_B = 3j + +class TestConvert(unittest.TestCase): + def tearDown(self): # Reset the module-level test variables to their original integer # values, otherwise the already created enum values get converted # instead. + g = globals() for suffix in ['A', 'B', 'C', 'D', 'E', 'F']: - globals()[f'CONVERT_TEST_NAME_{suffix}'] = 5 - globals()[f'CONVERT_STRING_TEST_NAME_{suffix}'] = 5 + g['CONVERT_TEST_NAME_%s' % suffix] = 5 + g['CONVERT_STRING_TEST_NAME_%s' % suffix] = 5 + for suffix, value in (('A', 5), ('B', (9, 1)), ('C', 'value')): + g['UNCOMPARABLE_%s' % suffix] = value + for suffix, value in (('A', 2j), ('B', 3j), ('C', 1j)): + g['COMPLEX_%s' % suffix] = value + for suffix, value in (('1', 'hello'), ('2', 'goodbye')): + g['CONVERT_STR_TEST_%s' % suffix] = value def test_convert_value_lookup_priority(self): test_type = enum.IntEnum._convert_( @@ -4142,7 +4613,7 @@ class TestIntEnumConvert(unittest.TestCase): # report the first lexigraphical name in that case. self.assertEqual(test_type(5).name, 'CONVERT_TEST_NAME_A') - def test_convert(self): + def test_convert_int(self): test_type = enum.IntEnum._convert_( 'UnittestConvert', MODULE, @@ -4155,21 +4626,58 @@ class TestIntEnumConvert(unittest.TestCase): self.assertEqual(test_type.CONVERT_TEST_NAME_D, 5) self.assertEqual(test_type.CONVERT_TEST_NAME_E, 5) # Ensure that test_type only picked up names matching the filter. - self.assertEqual([name for name in dir(test_type) - if name[0:2] not in ('CO', '__')], - [], msg='Names other than CONVERT_TEST_* found.') + extra = [name for name in dir(test_type) if name not in enum_dir(test_type)] + missing = [name for name in enum_dir(test_type) if name not in dir(test_type)] + self.assertEqual( + extra + missing, + [], + msg='extra names: %r; missing names: %r' % (extra, missing), + ) - @unittest.skipUnless(python_version == (3, 8), - '_convert was deprecated in 3.8') - def test_convert_warn(self): - with self.assertWarns(DeprecationWarning): - enum.IntEnum._convert( + + def test_convert_uncomparable(self): + uncomp = enum.Enum._convert_( + 'Uncomparable', + MODULE, + filter=lambda x: x.startswith('UNCOMPARABLE_')) + # Should be ordered by `name` only: + self.assertEqual( + list(uncomp), + [uncomp.UNCOMPARABLE_A, uncomp.UNCOMPARABLE_B, uncomp.UNCOMPARABLE_C], + ) + + def test_convert_complex(self): + uncomp = enum.Enum._convert_( + 'Uncomparable', + MODULE, + filter=lambda x: x.startswith('COMPLEX_')) + # Should be ordered by `name` only: + self.assertEqual( + list(uncomp), + [uncomp.COMPLEX_A, uncomp.COMPLEX_B, uncomp.COMPLEX_C], + ) + + def test_convert_str(self): + test_type = enum.StrEnum._convert_( 'UnittestConvert', MODULE, - filter=lambda x: x.startswith('CONVERT_TEST_')) + filter=lambda x: x.startswith('CONVERT_STR_'), + as_global=True) + # Ensure that test_type has all of the desired names and values. + self.assertEqual(test_type.CONVERT_STR_TEST_1, 'hello') + self.assertEqual(test_type.CONVERT_STR_TEST_2, 'goodbye') + # Ensure that test_type only picked up names matching the filter. + extra = [name for name in dir(test_type) if name not in enum_dir(test_type)] + missing = [name for name in enum_dir(test_type) if name not in dir(test_type)] + self.assertEqual( + extra + missing, + [], + msg='extra names: %r; missing names: %r' % (extra, missing), + ) + self.assertEqual(repr(test_type.CONVERT_STR_TEST_1), '%s.CONVERT_STR_TEST_1' % SHORT_MODULE) + self.assertEqual(str(test_type.CONVERT_STR_TEST_2), 'goodbye') + self.assertEqual(format(test_type.CONVERT_STR_TEST_1), 'hello') - @unittest.skipUnless(python_version >= (3, 9), - '_convert was removed in 3.9') def test_convert_raise(self): with self.assertRaises(AttributeError): enum.IntEnum._convert( @@ -4181,43 +4689,50 @@ class TestIntEnumConvert(unittest.TestCase): test_type = enum.IntEnum._convert_( 'UnittestConvert', MODULE, - filter=lambda x: x.startswith('CONVERT_STRING_TEST_')) + filter=lambda x: x.startswith('CONVERT_STRING_TEST_'), + as_global=True) self.assertEqual(repr(test_type.CONVERT_STRING_TEST_NAME_A), '%s.CONVERT_STRING_TEST_NAME_A' % SHORT_MODULE) - self.assertEqual(str(test_type.CONVERT_STRING_TEST_NAME_A), 'CONVERT_STRING_TEST_NAME_A') + self.assertEqual(str(test_type.CONVERT_STRING_TEST_NAME_A), '5') self.assertEqual(format(test_type.CONVERT_STRING_TEST_NAME_A), '5') -# global names for StrEnum._convert_ test -CONVERT_STR_TEST_2 = 'goodbye' -CONVERT_STR_TEST_1 = 'hello' -class TestStrEnumConvert(unittest.TestCase): - def setUp(self): - global CONVERT_STR_TEST_1 - global CONVERT_STR_TEST_2 - CONVERT_STR_TEST_2 = 'goodbye' - CONVERT_STR_TEST_1 = 'hello' +# helpers - def test_convert(self): - test_type = enum.StrEnum._convert_( - 'UnittestConvert', - MODULE, - filter=lambda x: x.startswith('CONVERT_STR_')) - # Ensure that test_type has all of the desired names and values. - self.assertEqual(test_type.CONVERT_STR_TEST_1, 'hello') - self.assertEqual(test_type.CONVERT_STR_TEST_2, 'goodbye') - # Ensure that test_type only picked up names matching the filter. - self.assertEqual([name for name in dir(test_type) - if name[0:2] not in ('CO', '__')], - [], msg='Names other than CONVERT_STR_* found.') +def enum_dir(cls): + interesting = set([ + '__class__', '__contains__', '__doc__', '__getitem__', + '__iter__', '__len__', '__members__', '__module__', + '__name__', '__qualname__', + ] + + cls._member_names_ + ) + if cls._new_member_ is not object.__new__: + interesting.add('__new__') + if cls.__init_subclass__ is not object.__init_subclass__: + interesting.add('__init_subclass__') + if cls._member_type_ is object: + return sorted(interesting) + else: + # return whatever mixed-in data type has + return sorted(set(dir(cls._member_type_)) | interesting) - def test_convert_repr_and_str(self): - test_type = enum.StrEnum._convert_( - 'UnittestConvert', - MODULE, - filter=lambda x: x.startswith('CONVERT_STR_')) - self.assertEqual(repr(test_type.CONVERT_STR_TEST_1), '%s.CONVERT_STR_TEST_1' % SHORT_MODULE) - self.assertEqual(str(test_type.CONVERT_STR_TEST_2), 'goodbye') - self.assertEqual(format(test_type.CONVERT_STR_TEST_1), 'hello') +def member_dir(member): + if member.__class__._member_type_ is object: + allowed = set(['__class__', '__doc__', '__eq__', '__hash__', '__module__', 'name', 'value']) + else: + allowed = set(dir(member)) + for cls in member.__class__.mro(): + for name, obj in cls.__dict__.items(): + if name[0] == '_': + continue + if isinstance(obj, enum.property): + if obj.fget is not None or name not in member._member_map_: + allowed.add(name) + else: + allowed.discard(name) + else: + allowed.add(name) + return sorted(allowed) if __name__ == '__main__': diff --git a/Lib/test/test_enumerate.py b/Lib/test/test_enumerate.py index 906bfc21a26..5cb54cff9b7 100644 --- a/Lib/test/test_enumerate.py +++ b/Lib/test/test_enumerate.py @@ -128,6 +128,18 @@ class EnumerateTestCase(unittest.TestCase, PickleTest): self.assertRaises(TypeError, self.enum, 'abc', 'a') # wrong type self.assertRaises(TypeError, self.enum, 'abc', 2, 3) # too many arguments + def test_kwargs(self): + self.assertEqual(list(self.enum(iterable=Ig(self.seq))), self.res) + expected = list(self.enum(Ig(self.seq), 0)) + self.assertEqual(list(self.enum(iterable=Ig(self.seq), start=0)), + expected) + self.assertEqual(list(self.enum(start=0, iterable=Ig(self.seq))), + expected) + self.assertRaises(TypeError, self.enum, iterable=[], x=3) + self.assertRaises(TypeError, self.enum, start=0, x=3) + self.assertRaises(TypeError, self.enum, x=0, y=3) + self.assertRaises(TypeError, self.enum, x=0) + @support.cpython_only def test_tuple_reuse(self): # Tests an implementation detail where tuple is reused @@ -266,14 +278,16 @@ class EnumerateStartTestCase(EnumerateTestCase): class TestStart(EnumerateStartTestCase): + def enum(self, iterable, start=11): + return enumerate(iterable, start=start) - enum = lambda self, i: enumerate(i, start=11) seq, res = 'abc', [(11, 'a'), (12, 'b'), (13, 'c')] class TestLongStart(EnumerateStartTestCase): + def enum(self, iterable, start=sys.maxsize + 1): + return enumerate(iterable, start=start) - enum = lambda self, i: enumerate(i, start=sys.maxsize+1) seq, res = 'abc', [(sys.maxsize+1,'a'), (sys.maxsize+2,'b'), (sys.maxsize+3,'c')] diff --git a/Lib/test/test_except_star.py b/Lib/test/test_except_star.py new file mode 100644 index 00000000000..9de72dbd5a3 --- /dev/null +++ b/Lib/test/test_except_star.py @@ -0,0 +1,1203 @@ +import sys +import unittest +import textwrap + +class TestInvalidExceptStar(unittest.TestCase): + def test_mixed_except_and_except_star_is_syntax_error(self): + errors = [ + "try: pass\nexcept ValueError: pass\nexcept* TypeError: pass\n", + "try: pass\nexcept* ValueError: pass\nexcept TypeError: pass\n", + "try: pass\nexcept ValueError as e: pass\nexcept* TypeError: pass\n", + "try: pass\nexcept* ValueError as e: pass\nexcept TypeError: pass\n", + "try: pass\nexcept ValueError: pass\nexcept* TypeError as e: pass\n", + "try: pass\nexcept* ValueError: pass\nexcept TypeError as e: pass\n", + "try: pass\nexcept ValueError: pass\nexcept*: pass\n", + "try: pass\nexcept* ValueError: pass\nexcept: pass\n", + ] + + for err in errors: + with self.assertRaises(SyntaxError): + compile(err, "", "exec") + + def test_except_star_ExceptionGroup_is_runtime_error_single(self): + with self.assertRaises(TypeError): + try: + raise OSError("blah") + except* ExceptionGroup as e: + pass + + def test_except_star_ExceptionGroup_is_runtime_error_tuple(self): + with self.assertRaises(TypeError): + try: + raise ExceptionGroup("eg", [ValueError(42)]) + except* (TypeError, ExceptionGroup): + pass + + def test_except_star_invalid_exception_type(self): + with self.assertRaises(TypeError): + try: + raise ValueError + except* 42: + pass + + with self.assertRaises(TypeError): + try: + raise ValueError + except* (ValueError, 42): + pass + + +class TestBreakContinueReturnInExceptStarBlock(unittest.TestCase): + MSG = (r"'break', 'continue' and 'return'" + r" cannot appear in an except\* block") + + def check_invalid(self, src): + with self.assertRaisesRegex(SyntaxError, self.MSG): + compile(textwrap.dedent(src), "", "exec") + + def test_break_in_except_star(self): + self.check_invalid( + """ + try: + raise ValueError + except* Exception as e: + break + """) + + self.check_invalid( + """ + for i in range(5): + try: + pass + except* Exception as e: + if i == 2: + break + """) + + self.check_invalid( + """ + for i in range(5): + try: + pass + except* Exception as e: + if i == 2: + break + finally: + return 0 + """) + + + def test_continue_in_except_star_block_invalid(self): + self.check_invalid( + """ + for i in range(5): + try: + raise ValueError + except* Exception as e: + continue + """) + + self.check_invalid( + """ + for i in range(5): + try: + pass + except* Exception as e: + if i == 2: + continue + """) + + self.check_invalid( + """ + for i in range(5): + try: + pass + except* Exception as e: + if i == 2: + continue + finally: + return 0 + """) + + def test_return_in_except_star_block_invalid(self): + self.check_invalid( + """ + def f(): + try: + raise ValueError + except* Exception as e: + return 42 + """) + + self.check_invalid( + """ + def f(): + try: + pass + except* Exception as e: + return 42 + finally: + finished = True + """) + + def test_break_continue_in_except_star_block_valid(self): + try: + raise ValueError(42) + except* Exception as e: + count = 0 + for i in range(5): + if i == 0: + continue + if i == 4: + break + count += 1 + + self.assertEqual(count, 3) + self.assertEqual(i, 4) + exc = e + self.assertIsInstance(exc, ExceptionGroup) + + def test_return_in_except_star_block_valid(self): + try: + raise ValueError(42) + except* Exception as e: + def f(x): + return 2*x + r = f(3) + exc = e + self.assertEqual(r, 6) + self.assertIsInstance(exc, ExceptionGroup) + + +class ExceptStarTest(unittest.TestCase): + def assertExceptionIsLike(self, exc, template): + if exc is None and template is None: + return + + if template is None: + self.fail(f"unexpected exception: {exc}") + + if exc is None: + self.fail(f"expected an exception like {template!r}, got None") + + if not isinstance(exc, ExceptionGroup): + self.assertEqual(exc.__class__, template.__class__) + self.assertEqual(exc.args[0], template.args[0]) + else: + self.assertEqual(exc.message, template.message) + self.assertEqual(len(exc.exceptions), len(template.exceptions)) + for e, t in zip(exc.exceptions, template.exceptions): + self.assertExceptionIsLike(e, t) + + def assertMetadataEqual(self, e1, e2): + if e1 is None or e2 is None: + self.assertTrue(e1 is None and e2 is None) + else: + self.assertEqual(e1.__context__, e2.__context__) + self.assertEqual(e1.__cause__, e2.__cause__) + self.assertEqual(e1.__traceback__, e2.__traceback__) + + def assertMetadataNotEqual(self, e1, e2): + if e1 is None or e2 is None: + self.assertNotEqual(e1, e2) + else: + return not (e1.__context__ == e2.__context__ + and e1.__cause__ == e2.__cause__ + and e1.__traceback__ == e2.__traceback__) + + +class TestExceptStarSplitSemantics(ExceptStarTest): + def doSplitTestNamed(self, exc, T, match_template, rest_template): + initial_exc_info = sys.exc_info() + exc_info = match = rest = None + try: + try: + raise exc + except* T as e: + exc_info = sys.exc_info() + match = e + except BaseException as e: + rest = e + + if match_template: + self.assertEqual(exc_info[1], match) + else: + self.assertIsNone(exc_info) + self.assertExceptionIsLike(match, match_template) + self.assertExceptionIsLike(rest, rest_template) + self.assertEqual(sys.exc_info(), initial_exc_info) + + def doSplitTestUnnamed(self, exc, T, match_template, rest_template): + initial_exc_info = sys.exc_info() + exc_info = match = rest = None + try: + try: + raise exc + except* T: + exc_info = sys.exc_info() + match = sys.exc_info()[1] + else: + if rest_template: + self.fail("Exception not raised") + except BaseException as e: + rest = e + self.assertExceptionIsLike(match, match_template) + if match_template: + self.assertEqual(exc_info[0], type(match_template)) + self.assertExceptionIsLike(rest, rest_template) + self.assertEqual(sys.exc_info(), initial_exc_info) + + def doSplitTestInExceptHandler(self, exc, T, match_template, rest_template): + try: + raise ExceptionGroup('eg', [TypeError(1), ValueError(2)]) + except Exception: + self.doSplitTestNamed(exc, T, match_template, rest_template) + self.doSplitTestUnnamed(exc, T, match_template, rest_template) + + def doSplitTestInExceptStarHandler(self, exc, T, match_template, rest_template): + try: + raise ExceptionGroup('eg', [TypeError(1), ValueError(2)]) + except* Exception: + self.doSplitTestNamed(exc, T, match_template, rest_template) + self.doSplitTestUnnamed(exc, T, match_template, rest_template) + + def doSplitTest(self, exc, T, match_template, rest_template): + self.doSplitTestNamed(exc, T, match_template, rest_template) + self.doSplitTestUnnamed(exc, T, match_template, rest_template) + self.doSplitTestInExceptHandler(exc, T, match_template, rest_template) + self.doSplitTestInExceptStarHandler(exc, T, match_template, rest_template) + + def test_no_match_single_type(self): + self.doSplitTest( + ExceptionGroup("test1", [ValueError("V"), TypeError("T")]), + SyntaxError, + None, + ExceptionGroup("test1", [ValueError("V"), TypeError("T")])) + + def test_match_single_type(self): + self.doSplitTest( + ExceptionGroup("test2", [ValueError("V1"), ValueError("V2")]), + ValueError, + ExceptionGroup("test2", [ValueError("V1"), ValueError("V2")]), + None) + + def test_match_single_type_partial_match(self): + self.doSplitTest( + ExceptionGroup( + "test3", + [ValueError("V1"), OSError("OS"), ValueError("V2")]), + ValueError, + ExceptionGroup("test3", [ValueError("V1"), ValueError("V2")]), + ExceptionGroup("test3", [OSError("OS")])) + + def test_match_single_type_nested(self): + self.doSplitTest( + ExceptionGroup( + "g1", [ + ValueError("V1"), + OSError("OS1"), + ExceptionGroup( + "g2", [ + OSError("OS2"), + ValueError("V2"), + TypeError("T")])]), + ValueError, + ExceptionGroup( + "g1", [ + ValueError("V1"), + ExceptionGroup("g2", [ValueError("V2")])]), + ExceptionGroup("g1", [ + OSError("OS1"), + ExceptionGroup("g2", [ + OSError("OS2"), TypeError("T")])])) + + def test_match_type_tuple_nested(self): + self.doSplitTest( + ExceptionGroup( + "h1", [ + ValueError("V1"), + OSError("OS1"), + ExceptionGroup( + "h2", [OSError("OS2"), ValueError("V2"), TypeError("T")])]), + (ValueError, TypeError), + ExceptionGroup( + "h1", [ + ValueError("V1"), + ExceptionGroup("h2", [ValueError("V2"), TypeError("T")])]), + ExceptionGroup( + "h1", [ + OSError("OS1"), + ExceptionGroup("h2", [OSError("OS2")])])) + + def test_empty_groups_removed(self): + self.doSplitTest( + ExceptionGroup( + "eg", [ + ExceptionGroup("i1", [ValueError("V1")]), + ExceptionGroup("i2", [ValueError("V2"), TypeError("T1")]), + ExceptionGroup("i3", [TypeError("T2")])]), + TypeError, + ExceptionGroup("eg", [ + ExceptionGroup("i2", [TypeError("T1")]), + ExceptionGroup("i3", [TypeError("T2")])]), + ExceptionGroup("eg", [ + ExceptionGroup("i1", [ValueError("V1")]), + ExceptionGroup("i2", [ValueError("V2")])])) + + def test_singleton_groups_are_kept(self): + self.doSplitTest( + ExceptionGroup("j1", [ + ExceptionGroup("j2", [ + ExceptionGroup("j3", [ValueError("V1")]), + ExceptionGroup("j4", [TypeError("T")])])]), + TypeError, + ExceptionGroup( + "j1", + [ExceptionGroup("j2", [ExceptionGroup("j4", [TypeError("T")])])]), + ExceptionGroup( + "j1", + [ExceptionGroup("j2", [ExceptionGroup("j3", [ValueError("V1")])])])) + + def test_naked_exception_matched_wrapped1(self): + self.doSplitTest( + ValueError("V"), + ValueError, + ExceptionGroup("", [ValueError("V")]), + None) + + def test_naked_exception_matched_wrapped2(self): + self.doSplitTest( + ValueError("V"), + Exception, + ExceptionGroup("", [ValueError("V")]), + None) + + def test_exception_group_except_star_Exception_not_wrapped(self): + self.doSplitTest( + ExceptionGroup("eg", [ValueError("V")]), + Exception, + ExceptionGroup("eg", [ValueError("V")]), + None) + + def test_plain_exception_not_matched(self): + self.doSplitTest( + ValueError("V"), + TypeError, + None, + ValueError("V")) + + def test_match__supertype(self): + self.doSplitTest( + ExceptionGroup("st", [BlockingIOError("io"), TypeError("T")]), + OSError, + ExceptionGroup("st", [BlockingIOError("io")]), + ExceptionGroup("st", [TypeError("T")])) + + def test_multiple_matches_named(self): + try: + raise ExceptionGroup("mmn", [OSError("os"), BlockingIOError("io")]) + except* BlockingIOError as e: + self.assertExceptionIsLike(e, + ExceptionGroup("mmn", [BlockingIOError("io")])) + except* OSError as e: + self.assertExceptionIsLike(e, + ExceptionGroup("mmn", [OSError("os")])) + else: + self.fail("Exception not raised") + + def test_multiple_matches_unnamed(self): + try: + raise ExceptionGroup("mmu", [OSError("os"), BlockingIOError("io")]) + except* BlockingIOError: + e = sys.exc_info()[1] + self.assertExceptionIsLike(e, + ExceptionGroup("mmu", [BlockingIOError("io")])) + except* OSError: + e = sys.exc_info()[1] + self.assertExceptionIsLike(e, + ExceptionGroup("mmu", [OSError("os")])) + else: + self.fail("Exception not raised") + + def test_first_match_wins_named(self): + try: + raise ExceptionGroup("fst", [BlockingIOError("io")]) + except* OSError as e: + self.assertExceptionIsLike(e, + ExceptionGroup("fst", [BlockingIOError("io")])) + except* BlockingIOError: + self.fail("Should have been matched as OSError") + else: + self.fail("Exception not raised") + + def test_first_match_wins_unnamed(self): + try: + raise ExceptionGroup("fstu", [BlockingIOError("io")]) + except* OSError: + e = sys.exc_info()[1] + self.assertExceptionIsLike(e, + ExceptionGroup("fstu", [BlockingIOError("io")])) + except* BlockingIOError: + pass + else: + self.fail("Exception not raised") + + def test_nested_except_stars(self): + try: + raise ExceptionGroup("n", [BlockingIOError("io")]) + except* BlockingIOError: + try: + raise ExceptionGroup("n", [ValueError("io")]) + except* ValueError: + pass + else: + self.fail("Exception not raised") + e = sys.exc_info()[1] + self.assertExceptionIsLike(e, + ExceptionGroup("n", [BlockingIOError("io")])) + else: + self.fail("Exception not raised") + + def test_nested_in_loop(self): + for _ in range(2): + try: + raise ExceptionGroup("nl", [BlockingIOError("io")]) + except* BlockingIOError: + pass + else: + self.fail("Exception not raised") + + +class TestExceptStarReraise(ExceptStarTest): + def test_reraise_all_named(self): + try: + try: + raise ExceptionGroup( + "eg", [TypeError(1), ValueError(2), OSError(3)]) + except* TypeError as e: + raise + except* ValueError as e: + raise + # OSError not handled + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, + ExceptionGroup("eg", [TypeError(1), ValueError(2), OSError(3)])) + + def test_reraise_all_unnamed(self): + try: + try: + raise ExceptionGroup( + "eg", [TypeError(1), ValueError(2), OSError(3)]) + except* TypeError: + raise + except* ValueError: + raise + # OSError not handled + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, + ExceptionGroup("eg", [TypeError(1), ValueError(2), OSError(3)])) + + def test_reraise_some_handle_all_named(self): + try: + try: + raise ExceptionGroup( + "eg", [TypeError(1), ValueError(2), OSError(3)]) + except* TypeError as e: + raise + except* ValueError as e: + pass + # OSError not handled + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, ExceptionGroup("eg", [TypeError(1), OSError(3)])) + + def test_reraise_partial_handle_all_unnamed(self): + try: + try: + raise ExceptionGroup( + "eg", [TypeError(1), ValueError(2)]) + except* TypeError: + raise + except* ValueError: + pass + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, ExceptionGroup("eg", [TypeError(1)])) + + def test_reraise_partial_handle_some_named(self): + try: + try: + raise ExceptionGroup( + "eg", [TypeError(1), ValueError(2), OSError(3)]) + except* TypeError as e: + raise + except* ValueError as e: + pass + # OSError not handled + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, ExceptionGroup("eg", [TypeError(1), OSError(3)])) + + def test_reraise_partial_handle_some_unnamed(self): + try: + try: + raise ExceptionGroup( + "eg", [TypeError(1), ValueError(2), OSError(3)]) + except* TypeError: + raise + except* ValueError: + pass + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, ExceptionGroup("eg", [TypeError(1), OSError(3)])) + + def test_reraise_plain_exception_named(self): + try: + try: + raise ValueError(42) + except* ValueError as e: + raise + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, ExceptionGroup("", [ValueError(42)])) + + def test_reraise_plain_exception_unnamed(self): + try: + try: + raise ValueError(42) + except* ValueError: + raise + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, ExceptionGroup("", [ValueError(42)])) + + +class TestExceptStarRaise(ExceptStarTest): + def test_raise_named(self): + orig = ExceptionGroup("eg", [ValueError(1), OSError(2)]) + try: + try: + raise orig + except* OSError as e: + raise TypeError(3) + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, + ExceptionGroup( + "", [TypeError(3), ExceptionGroup("eg", [ValueError(1)])])) + + self.assertExceptionIsLike( + exc.exceptions[0].__context__, + ExceptionGroup("eg", [OSError(2)])) + + self.assertMetadataNotEqual(orig, exc) + self.assertMetadataEqual(orig, exc.exceptions[0].__context__) + + def test_raise_unnamed(self): + orig = ExceptionGroup("eg", [ValueError(1), OSError(2)]) + try: + try: + raise orig + except* OSError: + raise TypeError(3) + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, + ExceptionGroup( + "", [TypeError(3), ExceptionGroup("eg", [ValueError(1)])])) + + self.assertExceptionIsLike( + exc.exceptions[0].__context__, + ExceptionGroup("eg", [OSError(2)])) + + self.assertMetadataNotEqual(orig, exc) + self.assertMetadataEqual(orig, exc.exceptions[0].__context__) + + def test_raise_handle_all_raise_one_named(self): + orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)]) + try: + try: + raise orig + except* (TypeError, ValueError) as e: + raise SyntaxError(3) + except BaseException as e: + exc = e + + self.assertExceptionIsLike( + exc, ExceptionGroup("", [SyntaxError(3)])) + + self.assertExceptionIsLike( + exc.exceptions[0].__context__, + ExceptionGroup("eg", [TypeError(1), ValueError(2)])) + + self.assertMetadataNotEqual(orig, exc) + self.assertMetadataEqual(orig, exc.exceptions[0].__context__) + + def test_raise_handle_all_raise_one_unnamed(self): + orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)]) + try: + try: + raise orig + except* (TypeError, ValueError) as e: + raise SyntaxError(3) + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, ExceptionGroup("", [SyntaxError(3)])) + + self.assertExceptionIsLike( + exc.exceptions[0].__context__, + ExceptionGroup("eg", [TypeError(1), ValueError(2)])) + + self.assertMetadataNotEqual(orig, exc) + self.assertMetadataEqual(orig, exc.exceptions[0].__context__) + + def test_raise_handle_all_raise_two_named(self): + orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)]) + try: + try: + raise orig + except* TypeError as e: + raise SyntaxError(3) + except* ValueError as e: + raise SyntaxError(4) + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, ExceptionGroup("", [SyntaxError(3), SyntaxError(4)])) + + self.assertExceptionIsLike( + exc.exceptions[0].__context__, + ExceptionGroup("eg", [TypeError(1)])) + + self.assertExceptionIsLike( + exc.exceptions[1].__context__, + ExceptionGroup("eg", [ValueError(2)])) + + self.assertMetadataNotEqual(orig, exc) + self.assertMetadataEqual(orig, exc.exceptions[0].__context__) + self.assertMetadataEqual(orig, exc.exceptions[1].__context__) + + def test_raise_handle_all_raise_two_unnamed(self): + orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)]) + try: + try: + raise orig + except* TypeError: + raise SyntaxError(3) + except* ValueError: + raise SyntaxError(4) + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, ExceptionGroup("", [SyntaxError(3), SyntaxError(4)])) + + self.assertExceptionIsLike( + exc.exceptions[0].__context__, + ExceptionGroup("eg", [TypeError(1)])) + + self.assertExceptionIsLike( + exc.exceptions[1].__context__, + ExceptionGroup("eg", [ValueError(2)])) + + self.assertMetadataNotEqual(orig, exc) + self.assertMetadataEqual(orig, exc.exceptions[0].__context__) + self.assertMetadataEqual(orig, exc.exceptions[1].__context__) + + +class TestExceptStarRaiseFrom(ExceptStarTest): + def test_raise_named(self): + orig = ExceptionGroup("eg", [ValueError(1), OSError(2)]) + try: + try: + raise orig + except* OSError as e: + raise TypeError(3) from e + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, + ExceptionGroup( + "", [TypeError(3), ExceptionGroup("eg", [ValueError(1)])])) + + self.assertExceptionIsLike( + exc.exceptions[0].__context__, + ExceptionGroup("eg", [OSError(2)])) + + self.assertExceptionIsLike( + exc.exceptions[0].__cause__, + ExceptionGroup("eg", [OSError(2)])) + + self.assertMetadataNotEqual(orig, exc) + self.assertMetadataEqual(orig, exc.exceptions[0].__context__) + self.assertMetadataEqual(orig, exc.exceptions[0].__cause__) + self.assertMetadataNotEqual(orig, exc.exceptions[1].__context__) + self.assertMetadataNotEqual(orig, exc.exceptions[1].__cause__) + + def test_raise_unnamed(self): + orig = ExceptionGroup("eg", [ValueError(1), OSError(2)]) + try: + try: + raise orig + except* OSError: + e = sys.exc_info()[1] + raise TypeError(3) from e + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, + ExceptionGroup( + "", [TypeError(3), ExceptionGroup("eg", [ValueError(1)])])) + + self.assertExceptionIsLike( + exc.exceptions[0].__context__, + ExceptionGroup("eg", [OSError(2)])) + + self.assertExceptionIsLike( + exc.exceptions[0].__cause__, + ExceptionGroup("eg", [OSError(2)])) + + self.assertMetadataNotEqual(orig, exc) + self.assertMetadataEqual(orig, exc.exceptions[0].__context__) + self.assertMetadataEqual(orig, exc.exceptions[0].__cause__) + self.assertMetadataNotEqual(orig, exc.exceptions[1].__context__) + self.assertMetadataNotEqual(orig, exc.exceptions[1].__cause__) + + def test_raise_handle_all_raise_one_named(self): + orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)]) + try: + try: + raise orig + except* (TypeError, ValueError) as e: + raise SyntaxError(3) from e + except BaseException as e: + exc = e + + self.assertExceptionIsLike( + exc, ExceptionGroup("", [SyntaxError(3)])) + + self.assertExceptionIsLike( + exc.exceptions[0].__context__, + ExceptionGroup("eg", [TypeError(1), ValueError(2)])) + + self.assertExceptionIsLike( + exc.exceptions[0].__cause__, + ExceptionGroup("eg", [TypeError(1), ValueError(2)])) + + self.assertMetadataNotEqual(orig, exc) + self.assertMetadataEqual(orig, exc.exceptions[0].__context__) + self.assertMetadataEqual(orig, exc.exceptions[0].__cause__) + + def test_raise_handle_all_raise_one_unnamed(self): + orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)]) + try: + try: + raise orig + except* (TypeError, ValueError) as e: + e = sys.exc_info()[1] + raise SyntaxError(3) from e + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, ExceptionGroup("", [SyntaxError(3)])) + + self.assertExceptionIsLike( + exc.exceptions[0].__context__, + ExceptionGroup("eg", [TypeError(1), ValueError(2)])) + + self.assertExceptionIsLike( + exc.exceptions[0].__cause__, + ExceptionGroup("eg", [TypeError(1), ValueError(2)])) + + self.assertMetadataNotEqual(orig, exc) + self.assertMetadataEqual(orig, exc.exceptions[0].__context__) + self.assertMetadataEqual(orig, exc.exceptions[0].__cause__) + + def test_raise_handle_all_raise_two_named(self): + orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)]) + try: + try: + raise orig + except* TypeError as e: + raise SyntaxError(3) from e + except* ValueError as e: + raise SyntaxError(4) from e + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, ExceptionGroup("", [SyntaxError(3), SyntaxError(4)])) + + self.assertExceptionIsLike( + exc.exceptions[0].__context__, + ExceptionGroup("eg", [TypeError(1)])) + + self.assertExceptionIsLike( + exc.exceptions[0].__cause__, + ExceptionGroup("eg", [TypeError(1)])) + + self.assertExceptionIsLike( + exc.exceptions[1].__context__, + ExceptionGroup("eg", [ValueError(2)])) + + self.assertExceptionIsLike( + exc.exceptions[1].__cause__, + ExceptionGroup("eg", [ValueError(2)])) + + self.assertMetadataNotEqual(orig, exc) + self.assertMetadataEqual(orig, exc.exceptions[0].__context__) + self.assertMetadataEqual(orig, exc.exceptions[0].__cause__) + + def test_raise_handle_all_raise_two_unnamed(self): + orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)]) + try: + try: + raise orig + except* TypeError: + e = sys.exc_info()[1] + raise SyntaxError(3) from e + except* ValueError: + e = sys.exc_info()[1] + raise SyntaxError(4) from e + except ExceptionGroup as e: + exc = e + + self.assertExceptionIsLike( + exc, ExceptionGroup("", [SyntaxError(3), SyntaxError(4)])) + + self.assertExceptionIsLike( + exc.exceptions[0].__context__, + ExceptionGroup("eg", [TypeError(1)])) + + self.assertExceptionIsLike( + exc.exceptions[0].__cause__, + ExceptionGroup("eg", [TypeError(1)])) + + self.assertExceptionIsLike( + exc.exceptions[1].__context__, + ExceptionGroup("eg", [ValueError(2)])) + + self.assertExceptionIsLike( + exc.exceptions[1].__cause__, + ExceptionGroup("eg", [ValueError(2)])) + + self.assertMetadataNotEqual(orig, exc) + self.assertMetadataEqual(orig, exc.exceptions[0].__context__) + self.assertMetadataEqual(orig, exc.exceptions[0].__cause__) + self.assertMetadataEqual(orig, exc.exceptions[1].__context__) + self.assertMetadataEqual(orig, exc.exceptions[1].__cause__) + + +class TestExceptStarExceptionGroupSubclass(ExceptStarTest): + def test_except_star_EG_subclass(self): + class EG(ExceptionGroup): + def __new__(cls, message, excs, code): + obj = super().__new__(cls, message, excs) + obj.code = code + return obj + + def derive(self, excs): + return EG(self.message, excs, self.code) + + try: + try: + try: + try: + raise TypeError(2) + except TypeError as te: + raise EG("nested", [te], 101) from None + except EG as nested: + try: + raise ValueError(1) + except ValueError as ve: + raise EG("eg", [ve, nested], 42) + except* ValueError as eg: + veg = eg + except EG as eg: + teg = eg + + self.assertIsInstance(veg, EG) + self.assertIsInstance(teg, EG) + self.assertIsInstance(teg.exceptions[0], EG) + self.assertMetadataEqual(veg, teg) + self.assertEqual(veg.code, 42) + self.assertEqual(teg.code, 42) + self.assertEqual(teg.exceptions[0].code, 101) + + def test_falsy_exception_group_subclass(self): + class FalsyEG(ExceptionGroup): + def __bool__(self): + return False + + def derive(self, excs): + return FalsyEG(self.message, excs) + + try: + try: + raise FalsyEG("eg", [TypeError(1), ValueError(2)]) + except *TypeError as e: + tes = e + raise + except *ValueError as e: + ves = e + pass + except Exception as e: + exc = e + + for e in [tes, ves, exc]: + self.assertFalse(e) + self.assertIsInstance(e, FalsyEG) + + self.assertExceptionIsLike(exc, FalsyEG("eg", [TypeError(1)])) + self.assertExceptionIsLike(tes, FalsyEG("eg", [TypeError(1)])) + self.assertExceptionIsLike(ves, FalsyEG("eg", [ValueError(2)])) + + +class TestExceptStarCleanup(ExceptStarTest): + def test_exc_info_restored(self): + try: + try: + raise ValueError(42) + except: + try: + raise TypeError(int) + except* Exception: + pass + 1/0 + except Exception as e: + exc = e + + self.assertExceptionIsLike(exc, ZeroDivisionError('division by zero')) + self.assertExceptionIsLike(exc.__context__, ValueError(42)) + self.assertEqual(sys.exc_info(), (None, None, None)) + + +class TestExceptStar_WeirdLeafExceptions(ExceptStarTest): + # Test that except* works when leaf exceptions are + # unhashable or have a bad custom __eq__ + + class UnhashableExc(ValueError): + __hash__ = None + + class AlwaysEqualExc(ValueError): + def __eq__(self, other): + return True + + class NeverEqualExc(ValueError): + def __eq__(self, other): + return False + + class BrokenEqualExc(ValueError): + def __eq__(self, other): + raise RuntimeError() + + def setUp(self): + self.bad_types = [self.UnhashableExc, + self.AlwaysEqualExc, + self.NeverEqualExc, + self.BrokenEqualExc] + + def except_type(self, eg, type): + match, rest = None, None + try: + try: + raise eg + except* type as e: + match = e + except Exception as e: + rest = e + return match, rest + + def test_catch_unhashable_leaf_exception(self): + for Bad in self.bad_types: + with self.subTest(Bad): + eg = ExceptionGroup("eg", [TypeError(1), Bad(2)]) + match, rest = self.except_type(eg, Bad) + self.assertExceptionIsLike( + match, ExceptionGroup("eg", [Bad(2)])) + self.assertExceptionIsLike( + rest, ExceptionGroup("eg", [TypeError(1)])) + + def test_propagate_unhashable_leaf(self): + for Bad in self.bad_types: + with self.subTest(Bad): + eg = ExceptionGroup("eg", [TypeError(1), Bad(2)]) + match, rest = self.except_type(eg, TypeError) + self.assertExceptionIsLike( + match, ExceptionGroup("eg", [TypeError(1)])) + self.assertExceptionIsLike( + rest, ExceptionGroup("eg", [Bad(2)])) + + def test_catch_nothing_unhashable_leaf(self): + for Bad in self.bad_types: + with self.subTest(Bad): + eg = ExceptionGroup("eg", [TypeError(1), Bad(2)]) + match, rest = self.except_type(eg, OSError) + self.assertIsNone(match) + self.assertExceptionIsLike(rest, eg) + + def test_catch_everything_unhashable_leaf(self): + for Bad in self.bad_types: + with self.subTest(Bad): + eg = ExceptionGroup("eg", [TypeError(1), Bad(2)]) + match, rest = self.except_type(eg, Exception) + self.assertExceptionIsLike(match, eg) + self.assertIsNone(rest) + + def test_reraise_unhashable_leaf(self): + for Bad in self.bad_types: + with self.subTest(Bad): + eg = ExceptionGroup( + "eg", [TypeError(1), Bad(2), ValueError(3)]) + + try: + try: + raise eg + except* TypeError: + pass + except* Bad: + raise + except Exception as e: + exc = e + + self.assertExceptionIsLike( + exc, ExceptionGroup("eg", [Bad(2), ValueError(3)])) + + +class TestExceptStar_WeirdExceptionGroupSubclass(ExceptStarTest): + # Test that except* works with exception groups that are + # unhashable or have a bad custom __eq__ + + class UnhashableEG(ExceptionGroup): + __hash__ = None + + def derive(self, excs): + return type(self)(self.message, excs) + + class AlwaysEqualEG(ExceptionGroup): + def __eq__(self, other): + return True + + def derive(self, excs): + return type(self)(self.message, excs) + + class NeverEqualEG(ExceptionGroup): + def __eq__(self, other): + return False + + def derive(self, excs): + return type(self)(self.message, excs) + + class BrokenEqualEG(ExceptionGroup): + def __eq__(self, other): + raise RuntimeError() + + def derive(self, excs): + return type(self)(self.message, excs) + + def setUp(self): + self.bad_types = [self.UnhashableEG, + self.AlwaysEqualEG, + self.NeverEqualEG, + self.BrokenEqualEG] + + def except_type(self, eg, type): + match, rest = None, None + try: + try: + raise eg + except* type as e: + match = e + except Exception as e: + rest = e + return match, rest + + def test_catch_some_unhashable_exception_group_subclass(self): + for BadEG in self.bad_types: + with self.subTest(BadEG): + eg = BadEG("eg", + [TypeError(1), + BadEG("nested", [ValueError(2)])]) + + match, rest = self.except_type(eg, TypeError) + self.assertExceptionIsLike(match, BadEG("eg", [TypeError(1)])) + self.assertExceptionIsLike(rest, + BadEG("eg", [BadEG("nested", [ValueError(2)])])) + + def test_catch_none_unhashable_exception_group_subclass(self): + for BadEG in self.bad_types: + with self.subTest(BadEG): + + eg = BadEG("eg", + [TypeError(1), + BadEG("nested", [ValueError(2)])]) + + match, rest = self.except_type(eg, OSError) + self.assertIsNone(match) + self.assertExceptionIsLike(rest, eg) + + def test_catch_all_unhashable_exception_group_subclass(self): + for BadEG in self.bad_types: + with self.subTest(BadEG): + + eg = BadEG("eg", + [TypeError(1), + BadEG("nested", [ValueError(2)])]) + + match, rest = self.except_type(eg, Exception) + self.assertExceptionIsLike(match, eg) + self.assertIsNone(rest) + + def test_reraise_unhashable_eg(self): + for BadEG in self.bad_types: + with self.subTest(BadEG): + + eg = BadEG("eg", + [TypeError(1), ValueError(2), + BadEG("nested", [ValueError(3), OSError(4)])]) + + try: + try: + raise eg + except* ValueError: + pass + except* OSError: + raise + except Exception as e: + exc = e + + self.assertExceptionIsLike( + exc, BadEG("eg", [TypeError(1), + BadEG("nested", [OSError(4)])])) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_exception_group.py b/Lib/test/test_exception_group.py index 62ec1ee248d..b11524e778e 100644 --- a/Lib/test/test_exception_group.py +++ b/Lib/test/test_exception_group.py @@ -1,5 +1,4 @@ import collections.abc -import traceback import types import unittest @@ -11,7 +10,7 @@ class TestExceptionGroupTypeHierarchy(unittest.TestCase): self.assertTrue(issubclass(BaseExceptionGroup, BaseException)) def test_exception_is_not_generic_type(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, 'Exception'): Exception[OSError] def test_exception_group_is_generic_type(self): @@ -22,7 +21,7 @@ class TestExceptionGroupTypeHierarchy(unittest.TestCase): class BadConstructorArgs(unittest.TestCase): def test_bad_EG_construction__too_many_args(self): - MSG = 'function takes exactly 2 arguments' + MSG = r'BaseExceptionGroup.__new__\(\) takes exactly 2 arguments' with self.assertRaisesRegex(TypeError, MSG): ExceptionGroup('no errors') with self.assertRaisesRegex(TypeError, MSG): @@ -79,16 +78,30 @@ class InstanceCreation(unittest.TestCase): beg = BaseExceptionGroup("beg", [ValueError(1), KeyboardInterrupt(2)]) self.assertIs(type(beg), BaseExceptionGroup) - def test_EG_subclass_wraps_anything(self): + def test_EG_subclass_wraps_non_base_exceptions(self): class MyEG(ExceptionGroup): pass self.assertIs( type(MyEG("eg", [ValueError(12), TypeError(42)])), MyEG) - self.assertIs( - type(MyEG("eg", [ValueError(12), KeyboardInterrupt(42)])), - MyEG) + + def test_EG_subclass_does_not_wrap_base_exceptions(self): + class MyEG(ExceptionGroup): + pass + + msg = "Cannot nest BaseExceptions in 'MyEG'" + with self.assertRaisesRegex(TypeError, msg): + MyEG("eg", [ValueError(12), KeyboardInterrupt(42)]) + + def test_BEG_and_E_subclass_does_not_wrap_base_exceptions(self): + class MyEG(BaseExceptionGroup, ValueError): + pass + + msg = "Cannot nest BaseExceptions in 'MyEG'" + with self.assertRaisesRegex(TypeError, msg): + MyEG("eg", [ValueError(12), KeyboardInterrupt(42)]) + def test_BEG_subclass_wraps_anything(self): class MyBEG(BaseExceptionGroup): @@ -102,6 +115,71 @@ class InstanceCreation(unittest.TestCase): MyBEG) +class StrAndReprTests(unittest.TestCase): + def test_ExceptionGroup(self): + eg = BaseExceptionGroup( + 'flat', [ValueError(1), TypeError(2)]) + + self.assertEqual(str(eg), "flat (2 sub-exceptions)") + self.assertEqual(repr(eg), + "ExceptionGroup('flat', [ValueError(1), TypeError(2)])") + + eg = BaseExceptionGroup( + 'nested', [eg, ValueError(1), eg, TypeError(2)]) + + self.assertEqual(str(eg), "nested (4 sub-exceptions)") + self.assertEqual(repr(eg), + "ExceptionGroup('nested', " + "[ExceptionGroup('flat', " + "[ValueError(1), TypeError(2)]), " + "ValueError(1), " + "ExceptionGroup('flat', " + "[ValueError(1), TypeError(2)]), TypeError(2)])") + + def test_BaseExceptionGroup(self): + eg = BaseExceptionGroup( + 'flat', [ValueError(1), KeyboardInterrupt(2)]) + + self.assertEqual(str(eg), "flat (2 sub-exceptions)") + self.assertEqual(repr(eg), + "BaseExceptionGroup(" + "'flat', " + "[ValueError(1), KeyboardInterrupt(2)])") + + eg = BaseExceptionGroup( + 'nested', [eg, ValueError(1), eg]) + + self.assertEqual(str(eg), "nested (3 sub-exceptions)") + self.assertEqual(repr(eg), + "BaseExceptionGroup('nested', " + "[BaseExceptionGroup('flat', " + "[ValueError(1), KeyboardInterrupt(2)]), " + "ValueError(1), " + "BaseExceptionGroup('flat', " + "[ValueError(1), KeyboardInterrupt(2)])])") + + def test_custom_exception(self): + class MyEG(ExceptionGroup): + pass + + eg = MyEG( + 'flat', [ValueError(1), TypeError(2)]) + + self.assertEqual(str(eg), "flat (2 sub-exceptions)") + self.assertEqual(repr(eg), "MyEG('flat', [ValueError(1), TypeError(2)])") + + eg = MyEG( + 'nested', [eg, ValueError(1), eg, TypeError(2)]) + + self.assertEqual(str(eg), "nested (4 sub-exceptions)") + self.assertEqual(repr(eg), ( + "MyEG('nested', " + "[MyEG('flat', [ValueError(1), TypeError(2)]), " + "ValueError(1), " + "MyEG('flat', [ValueError(1), TypeError(2)]), " + "TypeError(2)])")) + + def create_simple_eg(): excs = [] try: @@ -211,7 +289,8 @@ class ExceptionGroupSubgroupTests(ExceptionGroupTestBase): def test_basics_subgroup_split__bad_arg_type(self): bad_args = ["bad arg", OSError('instance not type'), - [OSError('instance not type')],] + [OSError, TypeError], + (OSError, 42)] for arg in bad_args: with self.assertRaises(TypeError): self.eg.subgroup(arg) @@ -494,13 +573,16 @@ class ExceptionGroupSplitTestBase(ExceptionGroupTestBase): match and e in match_leaves, rest and e in rest_leaves) - # message, cause and context equal to eg + # message, cause and context, traceback and note equal to eg for part in [match, rest, sg]: if part is not None: self.assertEqual(eg.message, part.message) self.assertIs(eg.__cause__, part.__cause__) self.assertIs(eg.__context__, part.__context__) self.assertIs(eg.__traceback__, part.__traceback__) + self.assertEqual( + getattr(eg, '__notes__', None), + getattr(part, '__notes__', None)) def tbs_for_leaf(leaf, eg): for e, tbs in leaf_generator(eg): @@ -565,6 +647,7 @@ class NestedExceptionGroupSplitTest(ExceptionGroupSplitTestBase): try: nested_group() except ExceptionGroup as e: + e.add_note(f"the note: {id(e)}") eg = e eg_template = [ @@ -660,6 +743,47 @@ class NestedExceptionGroupSplitTest(ExceptionGroupSplitTestBase): self.assertMatchesTemplate( rest, ExceptionGroup, [ValueError(1)]) + def test_split_copies_notes(self): + # make sure each exception group after a split has its own __notes__ list + eg = ExceptionGroup("eg", [ValueError(1), TypeError(2)]) + eg.add_note("note1") + eg.add_note("note2") + orig_notes = list(eg.__notes__) + match, rest = eg.split(TypeError) + self.assertEqual(eg.__notes__, orig_notes) + self.assertEqual(match.__notes__, orig_notes) + self.assertEqual(rest.__notes__, orig_notes) + self.assertIsNot(eg.__notes__, match.__notes__) + self.assertIsNot(eg.__notes__, rest.__notes__) + self.assertIsNot(match.__notes__, rest.__notes__) + eg.add_note("eg") + match.add_note("match") + rest.add_note("rest") + self.assertEqual(eg.__notes__, orig_notes + ["eg"]) + self.assertEqual(match.__notes__, orig_notes + ["match"]) + self.assertEqual(rest.__notes__, orig_notes + ["rest"]) + + def test_split_does_not_copy_non_sequence_notes(self): + # __notes__ should be a sequence, which is shallow copied. + # If it is not a sequence, the split parts don't get any notes. + eg = ExceptionGroup("eg", [ValueError(1), TypeError(2)]) + eg.__notes__ = 123 + match, rest = eg.split(TypeError) + self.assertFalse(hasattr(match, '__notes__')) + self.assertFalse(hasattr(rest, '__notes__')) + + def test_drive_invalid_return_value(self): + class MyEg(ExceptionGroup): + def derive(self, excs): + return 42 + + eg = MyEg('eg', [TypeError(1), ValueError(2)]) + msg = "derive must return an instance of BaseExceptionGroup" + with self.assertRaisesRegex(TypeError, msg): + eg.split(TypeError) + with self.assertRaisesRegex(TypeError, msg): + eg.subgroup(TypeError) + class NestedExceptionGroupSubclassSplitTest(ExceptionGroupSplitTestBase): diff --git a/Lib/test/test_exception_hierarchy.py b/Lib/test/test_exception_hierarchy.py index 89fe9ddcefb..3318fa8e774 100644 --- a/Lib/test/test_exception_hierarchy.py +++ b/Lib/test/test_exception_hierarchy.py @@ -63,7 +63,7 @@ class HierarchyTest(unittest.TestCase): +-- InterruptedError EINTR +-- IsADirectoryError EISDIR +-- NotADirectoryError ENOTDIR - +-- PermissionError EACCES, EPERM + +-- PermissionError EACCES, EPERM, ENOTCAPABLE +-- ProcessLookupError ESRCH +-- TimeoutError ETIMEDOUT """ @@ -75,6 +75,8 @@ class HierarchyTest(unittest.TestCase): continue excname, _, errnames = line.partition(' ') for errname in filter(None, errnames.strip().split(', ')): + if errname == "ENOTCAPABLE" and not hasattr(errno, errname): + continue _map[getattr(errno, errname)] = getattr(builtins, excname) return _map _map = _make_map(_pep_map) @@ -91,7 +93,7 @@ class HierarchyTest(unittest.TestCase): othercodes = set(errno.errorcode) - set(self._map) for errcode in othercodes: e = OSError(errcode, "Some message") - self.assertIs(type(e), OSError) + self.assertIs(type(e), OSError, repr(e)) def test_try_except(self): filename = "some_hopefully_non_existing_file" diff --git a/Lib/test/test_exception_variations.py b/Lib/test/test_exception_variations.py index d874b0e3d10..a83a41d2975 100644 --- a/Lib/test/test_exception_variations.py +++ b/Lib/test/test_exception_variations.py @@ -1,7 +1,7 @@ import unittest -class ExceptionTestCase(unittest.TestCase): +class ExceptTestCases(unittest.TestCase): def test_try_except_else_finally(self): hit_except = False hit_else = False @@ -172,5 +172,404 @@ class ExceptionTestCase(unittest.TestCase): self.assertTrue(hit_finally) self.assertTrue(hit_except) + def test_nested_exception_in_except(self): + hit_else = False + hit_finally = False + hit_except = False + hit_inner_except = False + hit_inner_else = False + + try: + try: + raise Exception('inner exception') + except: + hit_inner_except = True + raise Exception('outer exception') + else: + hit_inner_else = True + except: + hit_except = True + else: + hit_else = True + finally: + hit_finally = True + + self.assertTrue(hit_inner_except) + self.assertFalse(hit_inner_else) + self.assertFalse(hit_else) + self.assertTrue(hit_finally) + self.assertTrue(hit_except) + + def test_nested_exception_in_else(self): + hit_else = False + hit_finally = False + hit_except = False + hit_inner_except = False + hit_inner_else = False + + try: + try: + pass + except: + hit_inner_except = True + else: + hit_inner_else = True + raise Exception('outer exception') + except: + hit_except = True + else: + hit_else = True + finally: + hit_finally = True + + self.assertFalse(hit_inner_except) + self.assertTrue(hit_inner_else) + self.assertFalse(hit_else) + self.assertTrue(hit_finally) + self.assertTrue(hit_except) + + def test_nested_exception_in_finally_no_exception(self): + hit_else = False + hit_finally = False + hit_except = False + hit_inner_except = False + hit_inner_else = False + hit_inner_finally = False + + try: + try: + pass + except: + hit_inner_except = True + else: + hit_inner_else = True + finally: + hit_inner_finally = True + raise Exception('outer exception') + except: + hit_except = True + else: + hit_else = True + finally: + hit_finally = True + + self.assertFalse(hit_inner_except) + self.assertTrue(hit_inner_else) + self.assertTrue(hit_inner_finally) + self.assertFalse(hit_else) + self.assertTrue(hit_finally) + self.assertTrue(hit_except) + + def test_nested_exception_in_finally_with_exception(self): + hit_else = False + hit_finally = False + hit_except = False + hit_inner_except = False + hit_inner_else = False + hit_inner_finally = False + + try: + try: + raise Exception('inner exception') + except: + hit_inner_except = True + else: + hit_inner_else = True + finally: + hit_inner_finally = True + raise Exception('outer exception') + except: + hit_except = True + else: + hit_else = True + finally: + hit_finally = True + + + self.assertTrue(hit_inner_except) + self.assertFalse(hit_inner_else) + self.assertTrue(hit_inner_finally) + self.assertFalse(hit_else) + self.assertTrue(hit_finally) + self.assertTrue(hit_except) + + +class ExceptStarTestCases(unittest.TestCase): + def test_try_except_else_finally(self): + hit_except = False + hit_else = False + hit_finally = False + + try: + raise Exception('nyaa!') + except* BaseException: + hit_except = True + else: + hit_else = True + finally: + hit_finally = True + + self.assertTrue(hit_except) + self.assertTrue(hit_finally) + self.assertFalse(hit_else) + + def test_try_except_else_finally_no_exception(self): + hit_except = False + hit_else = False + hit_finally = False + + try: + pass + except* BaseException: + hit_except = True + else: + hit_else = True + finally: + hit_finally = True + + self.assertFalse(hit_except) + self.assertTrue(hit_finally) + self.assertTrue(hit_else) + + def test_try_except_finally(self): + hit_except = False + hit_finally = False + + try: + raise Exception('yarr!') + except* BaseException: + hit_except = True + finally: + hit_finally = True + + self.assertTrue(hit_except) + self.assertTrue(hit_finally) + + def test_try_except_finally_no_exception(self): + hit_except = False + hit_finally = False + + try: + pass + except* BaseException: + hit_except = True + finally: + hit_finally = True + + self.assertFalse(hit_except) + self.assertTrue(hit_finally) + + def test_try_except(self): + hit_except = False + + try: + raise Exception('ahoy!') + except* BaseException: + hit_except = True + + self.assertTrue(hit_except) + + def test_try_except_no_exception(self): + hit_except = False + + try: + pass + except* BaseException: + hit_except = True + + self.assertFalse(hit_except) + + def test_try_except_else(self): + hit_except = False + hit_else = False + + try: + raise Exception('foo!') + except* BaseException: + hit_except = True + else: + hit_else = True + + self.assertFalse(hit_else) + self.assertTrue(hit_except) + + def test_try_except_else_no_exception(self): + hit_except = False + hit_else = False + + try: + pass + except* BaseException: + hit_except = True + else: + hit_else = True + + self.assertFalse(hit_except) + self.assertTrue(hit_else) + + def test_try_finally_no_exception(self): + hit_finally = False + + try: + pass + finally: + hit_finally = True + + self.assertTrue(hit_finally) + + def test_nested(self): + hit_finally = False + hit_inner_except = False + hit_inner_finally = False + + try: + try: + raise Exception('inner exception') + except* BaseException: + hit_inner_except = True + finally: + hit_inner_finally = True + finally: + hit_finally = True + + self.assertTrue(hit_inner_except) + self.assertTrue(hit_inner_finally) + self.assertTrue(hit_finally) + + def test_nested_else(self): + hit_else = False + hit_finally = False + hit_except = False + hit_inner_except = False + hit_inner_else = False + + try: + try: + pass + except* BaseException: + hit_inner_except = True + else: + hit_inner_else = True + + raise Exception('outer exception') + except* BaseException: + hit_except = True + else: + hit_else = True + finally: + hit_finally = True + + self.assertFalse(hit_inner_except) + self.assertTrue(hit_inner_else) + self.assertFalse(hit_else) + self.assertTrue(hit_finally) + self.assertTrue(hit_except) + + def test_nested_mixed1(self): + hit_except = False + hit_finally = False + hit_inner_except = False + hit_inner_finally = False + + try: + try: + raise Exception('inner exception') + except* BaseException: + hit_inner_except = True + finally: + hit_inner_finally = True + except: + hit_except = True + finally: + hit_finally = True + + self.assertTrue(hit_inner_except) + self.assertTrue(hit_inner_finally) + self.assertFalse(hit_except) + self.assertTrue(hit_finally) + + def test_nested_mixed2(self): + hit_except = False + hit_finally = False + hit_inner_except = False + hit_inner_finally = False + + try: + try: + raise Exception('inner exception') + except: + hit_inner_except = True + finally: + hit_inner_finally = True + except* BaseException: + hit_except = True + finally: + hit_finally = True + + self.assertTrue(hit_inner_except) + self.assertTrue(hit_inner_finally) + self.assertFalse(hit_except) + self.assertTrue(hit_finally) + + + def test_nested_else_mixed1(self): + hit_else = False + hit_finally = False + hit_except = False + hit_inner_except = False + hit_inner_else = False + + try: + try: + pass + except* BaseException: + hit_inner_except = True + else: + hit_inner_else = True + + raise Exception('outer exception') + except: + hit_except = True + else: + hit_else = True + finally: + hit_finally = True + + self.assertFalse(hit_inner_except) + self.assertTrue(hit_inner_else) + self.assertFalse(hit_else) + self.assertTrue(hit_finally) + self.assertTrue(hit_except) + + def test_nested_else_mixed2(self): + hit_else = False + hit_finally = False + hit_except = False + hit_inner_except = False + hit_inner_else = False + + try: + try: + pass + except: + hit_inner_except = True + else: + hit_inner_else = True + + raise Exception('outer exception') + except* BaseException: + hit_except = True + else: + hit_else = True + finally: + hit_finally = True + + self.assertFalse(hit_inner_except) + self.assertTrue(hit_inner_else) + self.assertFalse(hit_else) + self.assertTrue(hit_finally) + self.assertTrue(hit_except) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 4c18a59f6e9..f629321458d 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1,7 +1,6 @@ # Python test set -- part 5, built-in exceptions import copy -import gc import os import sys import unittest @@ -198,18 +197,23 @@ class ExceptionTests(unittest.TestCase): s = '''if True:\n print()\n\texec "mixed tabs and spaces"''' ckmsg(s, "inconsistent use of tabs and spaces in indentation", TabError) - def check(self, src, lineno, offset, encoding='utf-8'): + def check(self, src, lineno, offset, end_lineno=None, end_offset=None, encoding='utf-8'): with self.subTest(source=src, lineno=lineno, offset=offset): with self.assertRaises(SyntaxError) as cm: compile(src, '', 'exec') self.assertEqual(cm.exception.lineno, lineno) self.assertEqual(cm.exception.offset, offset) + if end_lineno is not None: + self.assertEqual(cm.exception.end_lineno, end_lineno) + if end_offset is not None: + self.assertEqual(cm.exception.end_offset, end_offset) + if cm.exception.text is not None: if not isinstance(src, str): src = src.decode(encoding, 'replace') line = src.split('\n')[lineno-1] self.assertIn(line, cm.exception.text) - + def test_error_offset_continuation_characters(self): check = self.check check('"\\\n"(1 for c in I,\\\n\\', 2, 2) @@ -226,20 +230,27 @@ class ExceptionTests(unittest.TestCase): check(b'Python = "\xcf\xb3\xf2\xee\xed" +', 1, 18) check('x = "a', 1, 5) check('lambda x: x = 2', 1, 1) - check('f{a + b + c}', 1, 1) - check('[file for str(file) in []\n])', 1, 11) + check('f{a + b + c}', 1, 2) + check('[file for str(file) in []\n]', 1, 11) check('a = « hello » « world »', 1, 5) check('[\nfile\nfor str(file)\nin\n[]\n]', 3, 5) check('[file for\n str(file) in []]', 2, 2) - check("ages = {'Alice'=22, 'Bob'=23}", 1, 16) + check("ages = {'Alice'=22, 'Bob'=23}", 1, 9) check('match ...:\n case {**rest, "key": value}:\n ...', 2, 19) - check("a b c d e f", 1, 1) + check("[a b c d e f]", 1, 2) + check("for x yfff:", 1, 7) + check("f(a for a in b, c)", 1, 3, 1, 15) + check("f(a for a in b if a, c)", 1, 3, 1, 20) + check("f(a, b for b in c)", 1, 6, 1, 18) + check("f(a, b for b in c, d)", 1, 6, 1, 18) # Errors thrown by compile.c check('class foo:return 1', 1, 11) check('def f():\n continue', 2, 3) check('def f():\n break', 2, 3) check('try:\n pass\nexcept:\n pass\nexcept ValueError:\n pass', 3, 1) + check('try:\n pass\nexcept*:\n pass', 3, 8) + check('try:\n pass\nexcept*:\n pass\nexcept* ValueError:\n pass', 3, 8) # Errors thrown by tokenizer.c check('(0x+1)', 1, 3) @@ -265,11 +276,30 @@ class ExceptionTests(unittest.TestCase): check("(1+)", 1, 4) check("[interesting\nfoo()\n", 1, 1) check(b"\xef\xbb\xbf#coding: utf8\nprint('\xe6\x88\x91')\n", 0, -1) + check("""f''' + { + (123_a) + }'''""", 3, 17) + check("""f''' + { + f\"\"\" + { + (123_a) + } + \"\"\" + }'''""", 5, 17) + check('''f""" + + + { + 6 + 0="""''', 5, 13) # Errors thrown by symtable.c - check('x = [(yield i) for i in range(3)]', 1, 5) - check('def f():\n from _ import *', 1, 1) - check('def f(x, x):\n pass', 1, 1) + check('x = [(yield i) for i in range(3)]', 1, 7) + check('def f():\n from _ import *', 2, 17) + check('def f(x, x):\n pass', 1, 10) + check('{i for i in range(5) if (j := 0) for j in range(5)}', 1, 38) check('def f(x):\n nonlocal x', 2, 3) check('def f(x):\n x = 1\n global x', 3, 3) check('nonlocal x', 1, 1) @@ -330,10 +360,9 @@ class ExceptionTests(unittest.TestCase): self.assertRaises(SystemError, _testcapi.raise_exception, InvalidException, 1) - if not sys.platform.startswith('java'): - test_capi1() - test_capi2() - test_capi3() + test_capi1() + test_capi2() + test_capi3() def test_WindowsError(self): try: @@ -516,6 +545,56 @@ class ExceptionTests(unittest.TestCase): 'pickled "%r", attribute "%s' % (e, checkArgName)) + def test_setstate(self): + e = Exception(42) + e.blah = 53 + self.assertEqual(e.args, (42,)) + self.assertEqual(e.blah, 53) + self.assertRaises(AttributeError, getattr, e, 'a') + self.assertRaises(AttributeError, getattr, e, 'b') + e.__setstate__({'a': 1 , 'b': 2}) + self.assertEqual(e.args, (42,)) + self.assertEqual(e.blah, 53) + self.assertEqual(e.a, 1) + self.assertEqual(e.b, 2) + e.__setstate__({'a': 11, 'args': (1,2,3), 'blah': 35}) + self.assertEqual(e.args, (1,2,3)) + self.assertEqual(e.blah, 35) + self.assertEqual(e.a, 11) + self.assertEqual(e.b, 2) + + def test_invalid_setstate(self): + e = Exception(42) + with self.assertRaisesRegex(TypeError, "state is not a dictionary"): + e.__setstate__(42) + + def test_notes(self): + for e in [BaseException(1), Exception(2), ValueError(3)]: + with self.subTest(e=e): + self.assertFalse(hasattr(e, '__notes__')) + e.add_note("My Note") + self.assertEqual(e.__notes__, ["My Note"]) + + with self.assertRaises(TypeError): + e.add_note(42) + self.assertEqual(e.__notes__, ["My Note"]) + + e.add_note("Your Note") + self.assertEqual(e.__notes__, ["My Note", "Your Note"]) + + del e.__notes__ + self.assertFalse(hasattr(e, '__notes__')) + + e.add_note("Our Note") + self.assertEqual(e.__notes__, ["Our Note"]) + + e.__notes__ = 42 + self.assertEqual(e.__notes__, 42) + + with self.assertRaises(TypeError): + e.add_note("will not work") + self.assertEqual(e.__notes__, 42) + def testWithTraceback(self): try: raise IndexError(4) @@ -545,11 +624,30 @@ class ExceptionTests(unittest.TestCase): else: self.fail("No exception raised") - def testInvalidAttrs(self): - self.assertRaises(TypeError, setattr, Exception(), '__cause__', 1) - self.assertRaises(TypeError, delattr, Exception(), '__cause__') - self.assertRaises(TypeError, setattr, Exception(), '__context__', 1) - self.assertRaises(TypeError, delattr, Exception(), '__context__') + def test_invalid_setattr(self): + TE = TypeError + exc = Exception() + msg = "'int' object is not iterable" + self.assertRaisesRegex(TE, msg, setattr, exc, 'args', 1) + msg = "__traceback__ must be a traceback or None" + self.assertRaisesRegex(TE, msg, setattr, exc, '__traceback__', 1) + msg = "exception cause must be None or derive from BaseException" + self.assertRaisesRegex(TE, msg, setattr, exc, '__cause__', 1) + msg = "exception context must be None or derive from BaseException" + self.assertRaisesRegex(TE, msg, setattr, exc, '__context__', 1) + + def test_invalid_delattr(self): + TE = TypeError + try: + raise IndexError(4) + except Exception as e: + exc = e + + msg = "may not be deleted" + self.assertRaisesRegex(TE, msg, delattr, exc, 'args') + self.assertRaisesRegex(TE, msg, delattr, exc, '__traceback__') + self.assertRaisesRegex(TE, msg, delattr, exc, '__cause__') + self.assertRaisesRegex(TE, msg, delattr, exc, '__context__') def testNoneClearsTracebackAttr(self): try: @@ -628,15 +726,27 @@ class ExceptionTests(unittest.TestCase): self.assertTrue(str(Exception('a'))) self.assertTrue(str(Exception('a', 'b'))) - def testExceptionCleanupNames(self): + def test_exception_cleanup_names(self): # Make sure the local variable bound to the exception instance by # an "except" statement is only visible inside the except block. try: raise Exception() except Exception as e: - self.assertTrue(e) + self.assertIsInstance(e, Exception) + self.assertNotIn('e', locals()) + with self.assertRaises(UnboundLocalError): + e + + def test_exception_cleanup_names2(self): + # Make sure the cleanup doesn't break if the variable is explicitly deleted. + try: + raise Exception() + except Exception as e: + self.assertIsInstance(e, Exception) del e self.assertNotIn('e', locals()) + with self.assertRaises(UnboundLocalError): + e def testExceptionCleanupState(self): # Make sure exception state is cleaned up as soon as the except @@ -1108,6 +1218,56 @@ class ExceptionTests(unittest.TestCase): self.assertIs(b.__context__, a) self.assertIs(a.__context__, c) + def test_context_of_exception_in_try_and_finally(self): + try: + try: + te = TypeError(1) + raise te + finally: + ve = ValueError(2) + raise ve + except Exception as e: + exc = e + + self.assertIs(exc, ve) + self.assertIs(exc.__context__, te) + + def test_context_of_exception_in_except_and_finally(self): + try: + try: + te = TypeError(1) + raise te + except: + ve = ValueError(2) + raise ve + finally: + oe = OSError(3) + raise oe + except Exception as e: + exc = e + + self.assertIs(exc, oe) + self.assertIs(exc.__context__, ve) + self.assertIs(exc.__context__.__context__, te) + + def test_context_of_exception_in_else_and_finally(self): + try: + try: + pass + except: + pass + else: + ve = ValueError(1) + raise ve + finally: + oe = OSError(2) + raise oe + except Exception as e: + exc = e + + self.assertIs(exc, oe) + self.assertIs(exc.__context__, ve) + def test_unicode_change_attributes(self): # See issue 7309. This was a crasher. @@ -1211,6 +1371,7 @@ class ExceptionTests(unittest.TestCase): code = """if 1: import sys from _testinternalcapi import get_recursion_depth + from test import support class MyException(Exception): pass @@ -1238,13 +1399,8 @@ class ExceptionTests(unittest.TestCase): generator = gen() next(generator) recursionlimit = sys.getrecursionlimit() - depth = get_recursion_depth() try: - # Upon the last recursive invocation of recurse(), - # tstate->recursion_depth is equal to (recursion_limit - 1) - # and is equal to recursion_limit when _gen_throw() calls - # PyErr_NormalizeException(). - recurse(setrecursionlimit(depth + 2) - depth) + recurse(support.EXCEEDS_RECURSION_LIMIT) finally: sys.setrecursionlimit(recursionlimit) print('Done.') @@ -1342,9 +1498,7 @@ class ExceptionTests(unittest.TestCase): """ with SuppressCrashReport(): rc, out, err = script_helper.assert_python_failure("-c", code) - self.assertIn(b'Fatal Python error: _PyErr_NormalizeException: ' - b'Cannot recover from MemoryErrors while ' - b'normalizing exceptions.', err) + self.assertIn(b'MemoryError', err) @cpython_only def test_MemoryError(self): @@ -1611,7 +1765,6 @@ class ExceptionTests(unittest.TestCase): gc_collect() -global_for_suggestions = None class NameErrorTests(unittest.TestCase): def test_name_error_has_name(self): @@ -1620,272 +1773,6 @@ class NameErrorTests(unittest.TestCase): except NameError as exc: self.assertEqual("bluch", exc.name) - def test_name_error_suggestions(self): - def Substitution(): - noise = more_noise = a = bc = None - blech = None - print(bluch) - - def Elimination(): - noise = more_noise = a = bc = None - blch = None - print(bluch) - - def Addition(): - noise = more_noise = a = bc = None - bluchin = None - print(bluch) - - def SubstitutionOverElimination(): - blach = None - bluc = None - print(bluch) - - def SubstitutionOverAddition(): - blach = None - bluchi = None - print(bluch) - - def EliminationOverAddition(): - blucha = None - bluc = None - print(bluch) - - for func, suggestion in [(Substitution, "'blech'?"), - (Elimination, "'blch'?"), - (Addition, "'bluchin'?"), - (EliminationOverAddition, "'blucha'?"), - (SubstitutionOverElimination, "'blach'?"), - (SubstitutionOverAddition, "'blach'?")]: - err = None - try: - func() - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertIn(suggestion, err.getvalue()) - - def test_name_error_suggestions_from_globals(self): - def func(): - print(global_for_suggestio) - try: - func() - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertIn("'global_for_suggestions'?", err.getvalue()) - - def test_name_error_suggestions_from_builtins(self): - def func(): - print(ZeroDivisionErrrrr) - try: - func() - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertIn("'ZeroDivisionError'?", err.getvalue()) - - def test_name_error_suggestions_do_not_trigger_for_long_names(self): - def f(): - somethingverywronghehehehehehe = None - print(somethingverywronghe) - - try: - f() - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("somethingverywronghehe", err.getvalue()) - - def test_name_error_bad_suggestions_do_not_trigger_for_small_names(self): - vvv = mom = w = id = pytho = None - - with self.subTest(name="b"): - try: - b - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertNotIn("you mean", err.getvalue()) - self.assertNotIn("vvv", err.getvalue()) - self.assertNotIn("mom", err.getvalue()) - self.assertNotIn("'id'", err.getvalue()) - self.assertNotIn("'w'", err.getvalue()) - self.assertNotIn("'pytho'", err.getvalue()) - - with self.subTest(name="v"): - try: - v - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertNotIn("you mean", err.getvalue()) - self.assertNotIn("vvv", err.getvalue()) - self.assertNotIn("mom", err.getvalue()) - self.assertNotIn("'id'", err.getvalue()) - self.assertNotIn("'w'", err.getvalue()) - self.assertNotIn("'pytho'", err.getvalue()) - - with self.subTest(name="m"): - try: - m - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertNotIn("you mean", err.getvalue()) - self.assertNotIn("vvv", err.getvalue()) - self.assertNotIn("mom", err.getvalue()) - self.assertNotIn("'id'", err.getvalue()) - self.assertNotIn("'w'", err.getvalue()) - self.assertNotIn("'pytho'", err.getvalue()) - - with self.subTest(name="py"): - try: - py - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertNotIn("you mean", err.getvalue()) - self.assertNotIn("vvv", err.getvalue()) - self.assertNotIn("mom", err.getvalue()) - self.assertNotIn("'id'", err.getvalue()) - self.assertNotIn("'w'", err.getvalue()) - self.assertNotIn("'pytho'", err.getvalue()) - - def test_name_error_suggestions_do_not_trigger_for_too_many_locals(self): - def f(): - # Mutating locals() is unreliable, so we need to do it by hand - a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 = a10 = \ - a11 = a12 = a13 = a14 = a15 = a16 = a17 = a18 = a19 = a20 = \ - a21 = a22 = a23 = a24 = a25 = a26 = a27 = a28 = a29 = a30 = \ - a31 = a32 = a33 = a34 = a35 = a36 = a37 = a38 = a39 = a40 = \ - a41 = a42 = a43 = a44 = a45 = a46 = a47 = a48 = a49 = a50 = \ - a51 = a52 = a53 = a54 = a55 = a56 = a57 = a58 = a59 = a60 = \ - a61 = a62 = a63 = a64 = a65 = a66 = a67 = a68 = a69 = a70 = \ - a71 = a72 = a73 = a74 = a75 = a76 = a77 = a78 = a79 = a80 = \ - a81 = a82 = a83 = a84 = a85 = a86 = a87 = a88 = a89 = a90 = \ - a91 = a92 = a93 = a94 = a95 = a96 = a97 = a98 = a99 = a100 = \ - a101 = a102 = a103 = a104 = a105 = a106 = a107 = a108 = a109 = a110 = \ - a111 = a112 = a113 = a114 = a115 = a116 = a117 = a118 = a119 = a120 = \ - a121 = a122 = a123 = a124 = a125 = a126 = a127 = a128 = a129 = a130 = \ - a131 = a132 = a133 = a134 = a135 = a136 = a137 = a138 = a139 = a140 = \ - a141 = a142 = a143 = a144 = a145 = a146 = a147 = a148 = a149 = a150 = \ - a151 = a152 = a153 = a154 = a155 = a156 = a157 = a158 = a159 = a160 = \ - a161 = a162 = a163 = a164 = a165 = a166 = a167 = a168 = a169 = a170 = \ - a171 = a172 = a173 = a174 = a175 = a176 = a177 = a178 = a179 = a180 = \ - a181 = a182 = a183 = a184 = a185 = a186 = a187 = a188 = a189 = a190 = \ - a191 = a192 = a193 = a194 = a195 = a196 = a197 = a198 = a199 = a200 = \ - a201 = a202 = a203 = a204 = a205 = a206 = a207 = a208 = a209 = a210 = \ - a211 = a212 = a213 = a214 = a215 = a216 = a217 = a218 = a219 = a220 = \ - a221 = a222 = a223 = a224 = a225 = a226 = a227 = a228 = a229 = a230 = \ - a231 = a232 = a233 = a234 = a235 = a236 = a237 = a238 = a239 = a240 = \ - a241 = a242 = a243 = a244 = a245 = a246 = a247 = a248 = a249 = a250 = \ - a251 = a252 = a253 = a254 = a255 = a256 = a257 = a258 = a259 = a260 = \ - a261 = a262 = a263 = a264 = a265 = a266 = a267 = a268 = a269 = a270 = \ - a271 = a272 = a273 = a274 = a275 = a276 = a277 = a278 = a279 = a280 = \ - a281 = a282 = a283 = a284 = a285 = a286 = a287 = a288 = a289 = a290 = \ - a291 = a292 = a293 = a294 = a295 = a296 = a297 = a298 = a299 = a300 = \ - a301 = a302 = a303 = a304 = a305 = a306 = a307 = a308 = a309 = a310 = \ - a311 = a312 = a313 = a314 = a315 = a316 = a317 = a318 = a319 = a320 = \ - a321 = a322 = a323 = a324 = a325 = a326 = a327 = a328 = a329 = a330 = \ - a331 = a332 = a333 = a334 = a335 = a336 = a337 = a338 = a339 = a340 = \ - a341 = a342 = a343 = a344 = a345 = a346 = a347 = a348 = a349 = a350 = \ - a351 = a352 = a353 = a354 = a355 = a356 = a357 = a358 = a359 = a360 = \ - a361 = a362 = a363 = a364 = a365 = a366 = a367 = a368 = a369 = a370 = \ - a371 = a372 = a373 = a374 = a375 = a376 = a377 = a378 = a379 = a380 = \ - a381 = a382 = a383 = a384 = a385 = a386 = a387 = a388 = a389 = a390 = \ - a391 = a392 = a393 = a394 = a395 = a396 = a397 = a398 = a399 = a400 = \ - a401 = a402 = a403 = a404 = a405 = a406 = a407 = a408 = a409 = a410 = \ - a411 = a412 = a413 = a414 = a415 = a416 = a417 = a418 = a419 = a420 = \ - a421 = a422 = a423 = a424 = a425 = a426 = a427 = a428 = a429 = a430 = \ - a431 = a432 = a433 = a434 = a435 = a436 = a437 = a438 = a439 = a440 = \ - a441 = a442 = a443 = a444 = a445 = a446 = a447 = a448 = a449 = a450 = \ - a451 = a452 = a453 = a454 = a455 = a456 = a457 = a458 = a459 = a460 = \ - a461 = a462 = a463 = a464 = a465 = a466 = a467 = a468 = a469 = a470 = \ - a471 = a472 = a473 = a474 = a475 = a476 = a477 = a478 = a479 = a480 = \ - a481 = a482 = a483 = a484 = a485 = a486 = a487 = a488 = a489 = a490 = \ - a491 = a492 = a493 = a494 = a495 = a496 = a497 = a498 = a499 = a500 = \ - a501 = a502 = a503 = a504 = a505 = a506 = a507 = a508 = a509 = a510 = \ - a511 = a512 = a513 = a514 = a515 = a516 = a517 = a518 = a519 = a520 = \ - a521 = a522 = a523 = a524 = a525 = a526 = a527 = a528 = a529 = a530 = \ - a531 = a532 = a533 = a534 = a535 = a536 = a537 = a538 = a539 = a540 = \ - a541 = a542 = a543 = a544 = a545 = a546 = a547 = a548 = a549 = a550 = \ - a551 = a552 = a553 = a554 = a555 = a556 = a557 = a558 = a559 = a560 = \ - a561 = a562 = a563 = a564 = a565 = a566 = a567 = a568 = a569 = a570 = \ - a571 = a572 = a573 = a574 = a575 = a576 = a577 = a578 = a579 = a580 = \ - a581 = a582 = a583 = a584 = a585 = a586 = a587 = a588 = a589 = a590 = \ - a591 = a592 = a593 = a594 = a595 = a596 = a597 = a598 = a599 = a600 = \ - a601 = a602 = a603 = a604 = a605 = a606 = a607 = a608 = a609 = a610 = \ - a611 = a612 = a613 = a614 = a615 = a616 = a617 = a618 = a619 = a620 = \ - a621 = a622 = a623 = a624 = a625 = a626 = a627 = a628 = a629 = a630 = \ - a631 = a632 = a633 = a634 = a635 = a636 = a637 = a638 = a639 = a640 = \ - a641 = a642 = a643 = a644 = a645 = a646 = a647 = a648 = a649 = a650 = \ - a651 = a652 = a653 = a654 = a655 = a656 = a657 = a658 = a659 = a660 = \ - a661 = a662 = a663 = a664 = a665 = a666 = a667 = a668 = a669 = a670 = \ - a671 = a672 = a673 = a674 = a675 = a676 = a677 = a678 = a679 = a680 = \ - a681 = a682 = a683 = a684 = a685 = a686 = a687 = a688 = a689 = a690 = \ - a691 = a692 = a693 = a694 = a695 = a696 = a697 = a698 = a699 = a700 = \ - a701 = a702 = a703 = a704 = a705 = a706 = a707 = a708 = a709 = a710 = \ - a711 = a712 = a713 = a714 = a715 = a716 = a717 = a718 = a719 = a720 = \ - a721 = a722 = a723 = a724 = a725 = a726 = a727 = a728 = a729 = a730 = \ - a731 = a732 = a733 = a734 = a735 = a736 = a737 = a738 = a739 = a740 = \ - a741 = a742 = a743 = a744 = a745 = a746 = a747 = a748 = a749 = a750 = \ - a751 = a752 = a753 = a754 = a755 = a756 = a757 = a758 = a759 = a760 = \ - a761 = a762 = a763 = a764 = a765 = a766 = a767 = a768 = a769 = a770 = \ - a771 = a772 = a773 = a774 = a775 = a776 = a777 = a778 = a779 = a780 = \ - a781 = a782 = a783 = a784 = a785 = a786 = a787 = a788 = a789 = a790 = \ - a791 = a792 = a793 = a794 = a795 = a796 = a797 = a798 = a799 = a800 \ - = None - print(a0) - - try: - f() - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotRegex(err.getvalue(), r"NameError.*a1") - - def test_name_error_with_custom_exceptions(self): - def f(): - blech = None - raise NameError() - - try: - f() - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("blech", err.getvalue()) - - def f(): - blech = None - raise NameError - - try: - f() - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("blech", err.getvalue()) - - def test_unbound_local_error_doesn_not_match(self): - def foo(): - something = 3 - print(somethong) - somethong = 3 - - try: - foo() - except UnboundLocalError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("something", err.getvalue()) - def test_issue45826(self): # regression test for bpo-45826 def f(): @@ -1917,6 +1804,8 @@ class NameErrorTests(unittest.TestCase): self.assertIn("nonsense", err.getvalue()) self.assertIn("ZeroDivisionError", err.getvalue()) + # Note: name suggestion tests live in `test_traceback`. + class AttributeErrorTests(unittest.TestCase): def test_attributes(self): @@ -1940,6 +1829,11 @@ class AttributeErrorTests(unittest.TestCase): except AttributeError as exc: self.assertEqual("bluch", exc.name) self.assertEqual(obj, exc.obj) + try: + object.__getattribute__(obj, "bluch") + except AttributeError as exc: + self.assertEqual("bluch", exc.name) + self.assertEqual(obj, exc.obj) def test_getattr_has_name_and_obj_for_method(self): class A: @@ -1953,221 +1847,7 @@ class AttributeErrorTests(unittest.TestCase): self.assertEqual("bluch", exc.name) self.assertEqual(obj, exc.obj) - def test_getattr_suggestions(self): - class Substitution: - noise = more_noise = a = bc = None - blech = None - - class Elimination: - noise = more_noise = a = bc = None - blch = None - - class Addition: - noise = more_noise = a = bc = None - bluchin = None - - class SubstitutionOverElimination: - blach = None - bluc = None - - class SubstitutionOverAddition: - blach = None - bluchi = None - - class EliminationOverAddition: - blucha = None - bluc = None - - for cls, suggestion in [(Substitution, "'blech'?"), - (Elimination, "'blch'?"), - (Addition, "'bluchin'?"), - (EliminationOverAddition, "'bluc'?"), - (SubstitutionOverElimination, "'blach'?"), - (SubstitutionOverAddition, "'blach'?")]: - try: - cls().bluch - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertIn(suggestion, err.getvalue()) - - def test_getattr_suggestions_do_not_trigger_for_long_attributes(self): - class A: - blech = None - - try: - A().somethingverywrong - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("blech", err.getvalue()) - - def test_getattr_error_bad_suggestions_do_not_trigger_for_small_names(self): - class MyClass: - vvv = mom = w = id = pytho = None - - with self.subTest(name="b"): - try: - MyClass.b - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertNotIn("you mean", err.getvalue()) - self.assertNotIn("vvv", err.getvalue()) - self.assertNotIn("mom", err.getvalue()) - self.assertNotIn("'id'", err.getvalue()) - self.assertNotIn("'w'", err.getvalue()) - self.assertNotIn("'pytho'", err.getvalue()) - - with self.subTest(name="v"): - try: - MyClass.v - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertNotIn("you mean", err.getvalue()) - self.assertNotIn("vvv", err.getvalue()) - self.assertNotIn("mom", err.getvalue()) - self.assertNotIn("'id'", err.getvalue()) - self.assertNotIn("'w'", err.getvalue()) - self.assertNotIn("'pytho'", err.getvalue()) - - with self.subTest(name="m"): - try: - MyClass.m - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertNotIn("you mean", err.getvalue()) - self.assertNotIn("vvv", err.getvalue()) - self.assertNotIn("mom", err.getvalue()) - self.assertNotIn("'id'", err.getvalue()) - self.assertNotIn("'w'", err.getvalue()) - self.assertNotIn("'pytho'", err.getvalue()) - - with self.subTest(name="py"): - try: - MyClass.py - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertNotIn("you mean", err.getvalue()) - self.assertNotIn("vvv", err.getvalue()) - self.assertNotIn("mom", err.getvalue()) - self.assertNotIn("'id'", err.getvalue()) - self.assertNotIn("'w'", err.getvalue()) - self.assertNotIn("'pytho'", err.getvalue()) - - - def test_getattr_suggestions_do_not_trigger_for_big_dicts(self): - class A: - blech = None - # A class with a very big __dict__ will not be consider - # for suggestions. - for index in range(2000): - setattr(A, f"index_{index}", None) - - try: - A().bluch - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("blech", err.getvalue()) - - def test_getattr_suggestions_no_args(self): - class A: - blech = None - def __getattr__(self, attr): - raise AttributeError() - - try: - A().bluch - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertIn("blech", err.getvalue()) - - class A: - blech = None - def __getattr__(self, attr): - raise AttributeError - - try: - A().bluch - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertIn("blech", err.getvalue()) - - def test_getattr_suggestions_invalid_args(self): - class NonStringifyClass: - __str__ = None - __repr__ = None - - class A: - blech = None - def __getattr__(self, attr): - raise AttributeError(NonStringifyClass()) - - class B: - blech = None - def __getattr__(self, attr): - raise AttributeError("Error", 23) - - class C: - blech = None - def __getattr__(self, attr): - raise AttributeError(23) - - for cls in [A, B, C]: - try: - cls().bluch - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertIn("blech", err.getvalue()) - - def test_getattr_suggestions_for_same_name(self): - class A: - def __dir__(self): - return ['blech'] - try: - A().blech - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("Did you mean", err.getvalue()) - - def test_attribute_error_with_failing_dict(self): - class T: - bluch = 1 - def __dir__(self): - raise AttributeError("oh no!") - - try: - T().blich - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("blech", err.getvalue()) - self.assertNotIn("oh no!", err.getvalue()) - - def test_attribute_error_with_bad_name(self): - try: - raise AttributeError(name=12, obj=23) - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("?", err.getvalue()) + # Note: name suggestion tests live in `test_traceback`. class ImportErrorTests(unittest.TestCase): @@ -2366,6 +2046,18 @@ class SyntaxErrorTests(unittest.TestCase): finally: unlink(TESTFN) + def test_non_utf8(self): + # Check non utf-8 characters + try: + with open(TESTFN, 'bw') as testfile: + testfile.write(b"\x89") + rc, out, err = script_helper.assert_python_failure('-Wd', '-X', 'utf8', TESTFN) + err = err.decode('utf-8').splitlines() + + self.assertIn("SyntaxError: Non-UTF-8 code starting with '\\x89' in file", err[-1]) + finally: + unlink(TESTFN) + def test_attributes_new_constructor(self): args = ("bad.py", 1, 2, "abcdefg", 1, 100) the_exception = SyntaxError("bad bad", args) @@ -2401,6 +2093,21 @@ class SyntaxErrorTests(unittest.TestCase): self.assertRaises(TypeError, SyntaxError, "bad bad", args) +class TestInvalidExceptionMatcher(unittest.TestCase): + def test_except_star_invalid_exception_type(self): + with self.assertRaises(TypeError): + try: + raise ValueError + except 42: + pass + + with self.assertRaises(TypeError): + try: + raise ValueError + except (ValueError, 42): + pass + + class PEP626Tests(unittest.TestCase): def lineno_after_raise(self, f, *expected): @@ -2495,7 +2202,7 @@ class PEP626Tests(unittest.TestCase): def f(): 1/0 self.lineno_after_raise(f, 1) - f.__code__ = f.__code__.replace(co_linetable=b'\x04\x80\xff\x80') + f.__code__ = f.__code__.replace(co_linetable=b'\xf8\xf8\xf8\xf9\xf8\xf8\xf8') self.lineno_after_raise(f, None) def test_lineno_after_raise_in_with_exit(self): diff --git a/Lib/test/test_extcall.py b/Lib/test/test_extcall.py index 13265ea0d8c..d9d85fe79af 100644 --- a/Lib/test/test_extcall.py +++ b/Lib/test/test_extcall.py @@ -8,6 +8,7 @@ We're going the use these types for extra testing We're defining four helper functions + >>> from test import support >>> def e(a,b): ... print(a, b) @@ -381,6 +382,27 @@ Test a kwargs mapping with duplicated keys. ... TypeError: test.test_extcall.g() got multiple values for keyword argument 'x' +Call with dict subtype: + + >>> class MyDict(dict): + ... pass + + >>> def s1(**kwargs): + ... return kwargs + >>> def s2(*args, **kwargs): + ... return (args, kwargs) + >>> def s3(*, n, **kwargs): + ... return (n, kwargs) + + >>> md = MyDict({'a': 1, 'b': 2}) + >>> assert s1(**md) == {'a': 1, 'b': 2} + >>> assert s2(*(1, 2), **md) == ((1, 2), {'a': 1, 'b': 2}) + >>> assert s3(**MyDict({'n': 1, 'b': 2})) == (1, {'b': 2}) + >>> s3(**md) + Traceback (most recent call last): + ... + TypeError: s3() missing 1 required keyword-only argument: 'n' + Another helper function >>> def f2(*a, **b): @@ -522,7 +544,6 @@ Same with keyword only args: import doctest import unittest -from test import support def load_tests(loader, tests, pattern): tests.addTest(doctest.DocTestSuite()) diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py index de986a3cbea..8d106daaf65 100644 --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -6,10 +6,10 @@ import re import signal import subprocess import sys -import sysconfig from test import support from test.support import os_helper from test.support import script_helper, is_android +from test.support import skip_if_sanitizer import tempfile import unittest from textwrap import dedent @@ -19,18 +19,11 @@ try: except ImportError: _testcapi = None +if not support.has_subprocess_support: + raise unittest.SkipTest("test module requires subprocess") + TIMEOUT = 0.5 MS_WINDOWS = (os.name == 'nt') -_cflags = sysconfig.get_config_var('CFLAGS') or '' -_config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' -UB_SANITIZER = ( - '-fsanitize=undefined' in _cflags or - '--with-undefined-behavior-sanitizer' in _config_args -) -MEMORY_SANITIZER = ( - '-fsanitize=memory' in _cflags or - '--with-memory-sanitizer' in _config_args -) def expected_traceback(lineno1, lineno2, header, min_count=1): @@ -311,8 +304,8 @@ class FaultHandlerTests(unittest.TestCase): 3, 'Segmentation fault') - @unittest.skipIf(UB_SANITIZER or MEMORY_SANITIZER, - "sanitizer builds change crashing process output.") + @skip_if_sanitizer(memory=True, ub=True, reason="sanitizer " + "builds change crashing process output.") @skip_segfault_on_android def test_enable_file(self): with temporary_filename() as filename: @@ -328,8 +321,8 @@ class FaultHandlerTests(unittest.TestCase): @unittest.skipIf(sys.platform == "win32", "subprocess doesn't support pass_fds on Windows") - @unittest.skipIf(UB_SANITIZER or MEMORY_SANITIZER, - "sanitizer builds change crashing process output.") + @skip_if_sanitizer(memory=True, ub=True, reason="sanitizer " + "builds change crashing process output.") @skip_segfault_on_android def test_enable_fd(self): with tempfile.TemporaryFile('wb+') as fp: @@ -412,6 +405,7 @@ class FaultHandlerTests(unittest.TestCase): finally: sys.stderr = orig_stderr + @support.requires_subprocess() def test_disabled_by_default(self): # By default, the module should be disabled code = "import faulthandler; print(faulthandler.is_enabled())" @@ -420,6 +414,7 @@ class FaultHandlerTests(unittest.TestCase): output = subprocess.check_output(args) self.assertEqual(output.rstrip(), b"False") + @support.requires_subprocess() def test_sys_xoptions(self): # Test python -X faulthandler code = "import faulthandler; print(faulthandler.is_enabled())" @@ -432,6 +427,7 @@ class FaultHandlerTests(unittest.TestCase): output = subprocess.check_output(args, env=env) self.assertEqual(output.rstrip(), b"True") + @support.requires_subprocess() def test_env_var(self): # empty env var code = "import faulthandler; print(faulthandler.is_enabled())" diff --git a/Lib/test/test_file.py b/Lib/test/test_file.py index 1146a37323c..9df55278693 100644 --- a/Lib/test/test_file.py +++ b/Lib/test/test_file.py @@ -217,7 +217,7 @@ class OtherFileTests: self._checkBufferSize(1) def testTruncateOnWindows(self): - # SF bug + # SF bug # "file.truncate fault on windows" f = self.open(TESTFN, 'wb') diff --git a/Lib/test/test_file_eintr.py b/Lib/test/test_file_eintr.py index 01408d838a8..f9236f45ca4 100644 --- a/Lib/test/test_file_eintr.py +++ b/Lib/test/test_file_eintr.py @@ -15,12 +15,15 @@ import subprocess import sys import time import unittest +from test import support + +if not support.has_subprocess_support: + raise unittest.SkipTest("test module requires subprocess") # Test import all of the things we're about to try testing up front. import _io import _pyio - @unittest.skipUnless(os.name == 'posix', 'tests requires a posix system.') class TestFileIOSignalInterrupt: def setUp(self): diff --git a/Lib/test/test_fileinput.py b/Lib/test/test_fileinput.py index 819200010a2..ac20c74baa0 100644 --- a/Lib/test/test_fileinput.py +++ b/Lib/test/test_fileinput.py @@ -326,6 +326,16 @@ class FileInputTests(BaseTests, unittest.TestCase): with open(temp_file, 'rb') as f: self.assertEqual(f.read(), b'New line.') + def test_inplace_encoding_errors(self): + temp_file = self.writeTmp(b'Initial text \x88', mode='wb') + with FileInput(temp_file, inplace=True, + encoding="ascii", errors="replace") as fobj: + line = fobj.readline() + self.assertEqual(line, 'Initial text \ufffd') + print("New line \x88") + with open(temp_file, 'rb') as f: + self.assertEqual(f.read().rstrip(b'\r\n'), b'New line ?') + def test_file_hook_backward_compatibility(self): def old_hook(filename, mode): return io.StringIO("I used to receive only filename and mode") diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py index 4269b0e53f5..2263604ed1f 100644 --- a/Lib/test/test_fileio.py +++ b/Lib/test/test_fileio.py @@ -9,7 +9,9 @@ from array import array from weakref import proxy from functools import wraps -from test.support import cpython_only, swap_attr, gc_collect +from test.support import ( + cpython_only, swap_attr, gc_collect, is_emscripten, is_wasi +) from test.support.os_helper import (TESTFN, TESTFN_UNICODE, make_bad_fd) from test.support.warnings_helper import check_warnings from collections import UserList @@ -65,6 +67,7 @@ class AutoFileTests: self.assertRaises((AttributeError, TypeError), setattr, f, attr, 'oops') + @unittest.skipIf(is_wasi, "WASI does not expose st_blksize.") def testBlksize(self): # test private _blksize attribute blksize = io.DEFAULT_BUFFER_SIZE @@ -373,7 +376,7 @@ class OtherFileTests: self.assertEqual(f.isatty(), False) f.close() - if sys.platform != "win32": + if sys.platform != "win32" and not is_emscripten: try: f = self.FileIO("/dev/tty", "a") except OSError: @@ -500,7 +503,7 @@ class OtherFileTests: def testTruncateOnWindows(self): def bug801631(): - # SF bug + # SF bug # "file.truncate fault on windows" f = self.FileIO(TESTFN, 'w') f.write(bytes(range(11))) diff --git a/Lib/test/test_fileutils.py b/Lib/test/test_fileutils.py index 45b3f3233c6..ff13498fbfe 100644 --- a/Lib/test/test_fileutils.py +++ b/Lib/test/test_fileutils.py @@ -15,7 +15,7 @@ class PathTests(unittest.TestCase): if os.name == 'nt': raise unittest.SkipTest('Windows has its own helper for this') else: - from .test_posixpath import PosixPathTest as posixdata + from test.test_posixpath import PosixPathTest as posixdata tests = posixdata.NORMPATH_CASES for filename, expected in tests: if not os.path.isabs(filename): diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index f033736917c..f8350c1e4ca 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -8,19 +8,20 @@ import time import unittest from test import support -from test.support import import_helper from test.test_grammar import (VALID_UNDERSCORE_LITERALS, INVALID_UNDERSCORE_LITERALS) from math import isinf, isnan, copysign, ldexp +import math +try: + import _testcapi +except ImportError: + _testcapi = None + +HAVE_IEEE_754 = float.__getformat__("double").startswith("IEEE") INF = float("inf") NAN = float("nan") -have_getformat = hasattr(float, "__getformat__") -requires_getformat = unittest.skipUnless(have_getformat, - "requires __getformat__") -requires_setformat = unittest.skipUnless(hasattr(float, "__setformat__"), - "requires __setformat__") #locate file with float format test values test_dir = os.path.dirname(__file__) or os.curdir @@ -136,6 +137,10 @@ class GeneralFloatCases(unittest.TestCase): check('123\xbd') check(' 123 456 ') check(b' 123 456 ') + # all whitespace (cf. https://github.com/python/cpython/issues/95605) + check('') + check(' ') + check('\t \n') # non-ascii digits (error came from non-digit '!') check('\u0663\u0661\u0664!') @@ -612,17 +617,8 @@ class GeneralFloatCases(unittest.TestCase): self.assertEqual(hash(value), object.__hash__(value)) -@requires_setformat +@unittest.skipUnless(hasattr(float, "__getformat__"), "requires __getformat__") class FormatFunctionsTestCase(unittest.TestCase): - - def setUp(self): - self.save_formats = {'double':float.__getformat__('double'), - 'float':float.__getformat__('float')} - - def tearDown(self): - float.__setformat__('double', self.save_formats['double']) - float.__setformat__('float', self.save_formats['float']) - def test_getformat(self): self.assertIn(float.__getformat__('double'), ['unknown', 'IEEE, big-endian', 'IEEE, little-endian']) @@ -631,24 +627,6 @@ class FormatFunctionsTestCase(unittest.TestCase): self.assertRaises(ValueError, float.__getformat__, 'chicken') self.assertRaises(TypeError, float.__getformat__, 1) - def test_setformat(self): - for t in 'double', 'float': - float.__setformat__(t, 'unknown') - if self.save_formats[t] == 'IEEE, big-endian': - self.assertRaises(ValueError, float.__setformat__, - t, 'IEEE, little-endian') - elif self.save_formats[t] == 'IEEE, little-endian': - self.assertRaises(ValueError, float.__setformat__, - t, 'IEEE, big-endian') - else: - self.assertRaises(ValueError, float.__setformat__, - t, 'IEEE, big-endian') - self.assertRaises(ValueError, float.__setformat__, - t, 'IEEE, little-endian') - self.assertRaises(ValueError, float.__setformat__, - t, 'chicken') - self.assertRaises(ValueError, float.__setformat__, - 'chicken', 'unknown') BE_DOUBLE_INF = b'\x7f\xf0\x00\x00\x00\x00\x00\x00' LE_DOUBLE_INF = bytes(reversed(BE_DOUBLE_INF)) @@ -660,36 +638,6 @@ LE_FLOAT_INF = bytes(reversed(BE_FLOAT_INF)) BE_FLOAT_NAN = b'\x7f\xc0\x00\x00' LE_FLOAT_NAN = bytes(reversed(BE_FLOAT_NAN)) -# on non-IEEE platforms, attempting to unpack a bit pattern -# representing an infinity or a NaN should raise an exception. - -@requires_setformat -class UnknownFormatTestCase(unittest.TestCase): - def setUp(self): - self.save_formats = {'double':float.__getformat__('double'), - 'float':float.__getformat__('float')} - float.__setformat__('double', 'unknown') - float.__setformat__('float', 'unknown') - - def tearDown(self): - float.__setformat__('double', self.save_formats['double']) - float.__setformat__('float', self.save_formats['float']) - - def test_double_specials_dont_unpack(self): - for fmt, data in [('>d', BE_DOUBLE_INF), - ('>d', BE_DOUBLE_NAN), - ('f', BE_FLOAT_INF), - ('>f', BE_FLOAT_NAN), - ('\x00') + self.assertEqual(_testcapi.float_pack(4, 1.5, BIG_ENDIAN), + b'?\xc0\x00\x00') + self.assertEqual(_testcapi.float_pack(8, 1.5, BIG_ENDIAN), + b'?\xf8\x00\x00\x00\x00\x00\x00') + self.assertEqual(_testcapi.float_pack(2, 1.5, LITTLE_ENDIAN), + b'\x00>') + self.assertEqual(_testcapi.float_pack(4, 1.5, LITTLE_ENDIAN), + b'\x00\x00\xc0?') + self.assertEqual(_testcapi.float_pack(8, 1.5, LITTLE_ENDIAN), + b'\x00\x00\x00\x00\x00\x00\xf8?') + + def test_unpack(self): + self.assertEqual(_testcapi.float_unpack(b'>\x00', BIG_ENDIAN), + 1.5) + self.assertEqual(_testcapi.float_unpack(b'?\xc0\x00\x00', BIG_ENDIAN), + 1.5) + self.assertEqual(_testcapi.float_unpack(b'?\xf8\x00\x00\x00\x00\x00\x00', BIG_ENDIAN), + 1.5) + self.assertEqual(_testcapi.float_unpack(b'\x00>', LITTLE_ENDIAN), + 1.5) + self.assertEqual(_testcapi.float_unpack(b'\x00\x00\xc0?', LITTLE_ENDIAN), + 1.5) + self.assertEqual(_testcapi.float_unpack(b'\x00\x00\x00\x00\x00\x00\xf8?', LITTLE_ENDIAN), + 1.5) + + def test_roundtrip(self): + large = 2.0 ** 100 + values = [1.0, 1.5, large, 1.0/7, math.pi] + if HAVE_IEEE_754: + values.extend((INF, NAN)) + for value in values: + for size in (2, 4, 8,): + if size == 2 and value == large: + # too large for 16-bit float + continue + rel_tol = EPSILON[size] + for endian in (BIG_ENDIAN, LITTLE_ENDIAN): + with self.subTest(value=value, size=size, endian=endian): + data = _testcapi.float_pack(size, value, endian) + value2 = _testcapi.float_unpack(data, endian) + if isnan(value): + self.assertTrue(isnan(value2), (value, value2)) + elif size < 8: + self.assertTrue(math.isclose(value2, value, rel_tol=rel_tol), + (value, value2)) + else: + self.assertEqual(value2, value) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_flufl.py b/Lib/test/test_flufl.py index 0ff54aa227e..fd264c926bd 100644 --- a/Lib/test/test_flufl.py +++ b/Lib/test/test_flufl.py @@ -1,6 +1,5 @@ import __future__ import unittest -from test import support class FLUFLTests(unittest.TestCase): @@ -17,7 +16,7 @@ class FLUFLTests(unittest.TestCase): self.assertIn('2 != 3', cm.exception.text) self.assertEqual(cm.exception.filename, '') - self.assertTrue(cm.exception.lineno, 2) + self.assertEqual(cm.exception.lineno, 2) # The old parser reports the end of the token and the new # parser reports the start of the token self.assertEqual(cm.exception.offset, 3) diff --git a/Lib/test/test_fnmatch.py b/Lib/test/test_fnmatch.py index 10668e4f610..10ed496d4e2 100644 --- a/Lib/test/test_fnmatch.py +++ b/Lib/test/test_fnmatch.py @@ -2,6 +2,7 @@ import unittest import os +import string import warnings from fnmatch import fnmatch, fnmatchcase, translate, filter @@ -91,6 +92,119 @@ class FnmatchTestCase(unittest.TestCase): check('usr/bin', 'usr\\bin', normsep) check('usr\\bin', 'usr\\bin') + def test_char_set(self): + ignorecase = os.path.normcase('ABC') == os.path.normcase('abc') + check = self.check_match + tescases = string.ascii_lowercase + string.digits + string.punctuation + for c in tescases: + check(c, '[az]', c in 'az') + check(c, '[!az]', c not in 'az') + # Case insensitive. + for c in tescases: + check(c, '[AZ]', (c in 'az') and ignorecase) + check(c, '[!AZ]', (c not in 'az') or not ignorecase) + for c in string.ascii_uppercase: + check(c, '[az]', (c in 'AZ') and ignorecase) + check(c, '[!az]', (c not in 'AZ') or not ignorecase) + # Repeated same character. + for c in tescases: + check(c, '[aa]', c == 'a') + # Special cases. + for c in tescases: + check(c, '[^az]', c in '^az') + check(c, '[[az]', c in '[az') + check(c, r'[!]]', c != ']') + check('[', '[') + check('[]', '[]') + check('[!', '[!') + check('[!]', '[!]') + + def test_range(self): + ignorecase = os.path.normcase('ABC') == os.path.normcase('abc') + normsep = os.path.normcase('\\') == os.path.normcase('/') + check = self.check_match + tescases = string.ascii_lowercase + string.digits + string.punctuation + for c in tescases: + check(c, '[b-d]', c in 'bcd') + check(c, '[!b-d]', c not in 'bcd') + check(c, '[b-dx-z]', c in 'bcdxyz') + check(c, '[!b-dx-z]', c not in 'bcdxyz') + # Case insensitive. + for c in tescases: + check(c, '[B-D]', (c in 'bcd') and ignorecase) + check(c, '[!B-D]', (c not in 'bcd') or not ignorecase) + for c in string.ascii_uppercase: + check(c, '[b-d]', (c in 'BCD') and ignorecase) + check(c, '[!b-d]', (c not in 'BCD') or not ignorecase) + # Upper bound == lower bound. + for c in tescases: + check(c, '[b-b]', c == 'b') + # Special cases. + for c in tescases: + check(c, '[!-#]', c not in '-#') + check(c, '[!--.]', c not in '-.') + check(c, '[^-`]', c in '^_`') + if not (normsep and c == '/'): + check(c, '[[-^]', c in r'[\]^') + check(c, r'[\-^]', c in r'\]^') + check(c, '[b-]', c in '-b') + check(c, '[!b-]', c not in '-b') + check(c, '[-b]', c in '-b') + check(c, '[!-b]', c not in '-b') + check(c, '[-]', c in '-') + check(c, '[!-]', c not in '-') + # Upper bound is less that lower bound: error in RE. + for c in tescases: + check(c, '[d-b]', False) + check(c, '[!d-b]', True) + check(c, '[d-bx-z]', c in 'xyz') + check(c, '[!d-bx-z]', c not in 'xyz') + check(c, '[d-b^-`]', c in '^_`') + if not (normsep and c == '/'): + check(c, '[d-b[-^]', c in r'[\]^') + + def test_sep_in_char_set(self): + normsep = os.path.normcase('\\') == os.path.normcase('/') + check = self.check_match + check('/', r'[/]') + check('\\', r'[\]') + check('/', r'[\]', normsep) + check('\\', r'[/]', normsep) + check('[/]', r'[/]', False) + check(r'[\\]', r'[/]', False) + check('\\', r'[\t]') + check('/', r'[\t]', normsep) + check('t', r'[\t]') + check('\t', r'[\t]', False) + + def test_sep_in_range(self): + normsep = os.path.normcase('\\') == os.path.normcase('/') + check = self.check_match + check('a/b', 'a[.-0]b', not normsep) + check('a\\b', 'a[.-0]b', False) + check('a\\b', 'a[Z-^]b', not normsep) + check('a/b', 'a[Z-^]b', False) + + check('a/b', 'a[/-0]b', not normsep) + check(r'a\b', 'a[/-0]b', False) + check('a[/-0]b', 'a[/-0]b', False) + check(r'a[\-0]b', 'a[/-0]b', False) + + check('a/b', 'a[.-/]b') + check(r'a\b', 'a[.-/]b', normsep) + check('a[.-/]b', 'a[.-/]b', False) + check(r'a[.-\]b', 'a[.-/]b', False) + + check(r'a\b', r'a[\-^]b') + check('a/b', r'a[\-^]b', normsep) + check(r'a[\-^]b', r'a[\-^]b', False) + check('a[/-^]b', r'a[\-^]b', False) + + check(r'a\b', r'a[Z-\]b', not normsep) + check('a/b', r'a[Z-\]b', False) + check(r'a[Z-\]b', r'a[Z-\]b', False) + check('a[Z-/]b', r'a[Z-\]b', False) + def test_warnings(self): with warnings.catch_warnings(): warnings.simplefilter('error', Warning) @@ -124,17 +238,9 @@ class TranslateTestCase(unittest.TestCase): self.assertEqual(translate('A*********?[?]?'), r'(?s:A.*.[?].)\Z') # fancy translation to prevent exponential-time match failure t = translate('**a*a****a') - digits = re.findall(r'\d+', t) - self.assertEqual(len(digits), 4) - self.assertEqual(digits[0], digits[1]) - self.assertEqual(digits[2], digits[3]) - g1 = f"g{digits[0]}" # e.g., group name "g4" - g2 = f"g{digits[2]}" # e.g., group name "g5" - self.assertEqual(t, - fr'(?s:(?=(?P<{g1}>.*?a))(?P={g1})(?=(?P<{g2}>.*?a))(?P={g2}).*a)\Z') + self.assertEqual(t, r'(?s:(?>.*?a)(?>.*?a).*a)\Z') # and try pasting multiple translate results - it's an undocumented - # feature that this works; all the pain of generating unique group - # names across calls exists to support this + # feature that this works r1 = translate('**a**a**a*') r2 = translate('**b**b**b*') r3 = translate('*c*c*c*') diff --git a/Lib/test/test_fork1.py b/Lib/test/test_fork1.py index a2f7cfee9cf..a6523bbc518 100644 --- a/Lib/test/test_fork1.py +++ b/Lib/test/test_fork1.py @@ -14,7 +14,9 @@ from test import support # Skip test if fork does not exist. -support.get_attribute(os, 'fork') +if not support.has_fork_support: + raise unittest.SkipTest("test module requires working os.fork") + class ForkTest(ForkWait): def test_threaded_import_lock_fork(self): diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py index 16d29d1ea3d..69b0d5f1c5a 100644 --- a/Lib/test/test_format.py +++ b/Lib/test/test_format.py @@ -546,6 +546,80 @@ class FormatTest(unittest.TestCase): with self.assertRaisesRegex(ValueError, str_err): "{a:%ЫйЯЧ}".format(a='a') + def test_negative_zero(self): + ## default behavior + self.assertEqual(f"{-0.:.1f}", "-0.0") + self.assertEqual(f"{-.01:.1f}", "-0.0") + self.assertEqual(f"{-0:.1f}", "0.0") # integers do not distinguish -0 + + ## z sign option + self.assertEqual(f"{0.:z.1f}", "0.0") + self.assertEqual(f"{0.:z6.1f}", " 0.0") + self.assertEqual(f"{-1.:z6.1f}", " -1.0") + self.assertEqual(f"{-0.:z.1f}", "0.0") + self.assertEqual(f"{.01:z.1f}", "0.0") + self.assertEqual(f"{-0:z.1f}", "0.0") # z is allowed for integer input + self.assertEqual(f"{-.01:z.1f}", "0.0") + self.assertEqual(f"{0.:z.2f}", "0.00") + self.assertEqual(f"{-0.:z.2f}", "0.00") + self.assertEqual(f"{.001:z.2f}", "0.00") + self.assertEqual(f"{-.001:z.2f}", "0.00") + + self.assertEqual(f"{0.:z.1e}", "0.0e+00") + self.assertEqual(f"{-0.:z.1e}", "0.0e+00") + self.assertEqual(f"{0.:z.1E}", "0.0E+00") + self.assertEqual(f"{-0.:z.1E}", "0.0E+00") + + self.assertEqual(f"{-0.001:z.2e}", "-1.00e-03") # tests for mishandled + # rounding + self.assertEqual(f"{-0.001:z.2g}", "-0.001") + self.assertEqual(f"{-0.001:z.2%}", "-0.10%") + + self.assertEqual(f"{-00000.000001:z.1f}", "0.0") + self.assertEqual(f"{-00000.:z.1f}", "0.0") + self.assertEqual(f"{-.0000000000:z.1f}", "0.0") + + self.assertEqual(f"{-00000.000001:z.2f}", "0.00") + self.assertEqual(f"{-00000.:z.2f}", "0.00") + self.assertEqual(f"{-.0000000000:z.2f}", "0.00") + + self.assertEqual(f"{.09:z.1f}", "0.1") + self.assertEqual(f"{-.09:z.1f}", "-0.1") + + self.assertEqual(f"{-0.: z.0f}", " 0") + self.assertEqual(f"{-0.:+z.0f}", "+0") + self.assertEqual(f"{-0.:-z.0f}", "0") + self.assertEqual(f"{-1.: z.0f}", "-1") + self.assertEqual(f"{-1.:+z.0f}", "-1") + self.assertEqual(f"{-1.:-z.0f}", "-1") + + self.assertEqual(f"{0.j:z.1f}", "0.0+0.0j") + self.assertEqual(f"{-0.j:z.1f}", "0.0+0.0j") + self.assertEqual(f"{.01j:z.1f}", "0.0+0.0j") + self.assertEqual(f"{-.01j:z.1f}", "0.0+0.0j") + + self.assertEqual(f"{-0.:z>6.1f}", "zz-0.0") # test fill, esp. 'z' fill + self.assertEqual(f"{-0.:z>z6.1f}", "zzz0.0") + self.assertEqual(f"{-0.:x>z6.1f}", "xxx0.0") + self.assertEqual(f"{-0.:🖤>z6.1f}", "🖤🖤🖤0.0") # multi-byte fill char + + def test_specifier_z_error(self): + error_msg = re.compile("Invalid format specifier '.*z.*'") + with self.assertRaisesRegex(ValueError, error_msg): + f"{0:z+f}" # wrong position + with self.assertRaisesRegex(ValueError, error_msg): + f"{0:fz}" # wrong position + + error_msg = re.escape("Negative zero coercion (z) not allowed") + with self.assertRaisesRegex(ValueError, error_msg): + f"{0:zd}" # can't apply to int presentation type + with self.assertRaisesRegex(ValueError, error_msg): + f"{'x':zs}" # can't apply to string + + error_msg = re.escape("unsupported format character 'z'") + with self.assertRaisesRegex(ValueError, error_msg): + "%z.1f" % 0 # not allowed in old style string interpolation + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index fc46e8674fc..3bc6b409e05 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -162,6 +162,7 @@ class FractionTest(unittest.TestCase): def testFromString(self): self.assertEqual((5, 1), _components(F("5"))) self.assertEqual((3, 2), _components(F("3/2"))) + self.assertEqual((3, 2), _components(F("3 / 2"))) self.assertEqual((3, 2), _components(F(" \n +3/2"))) self.assertEqual((-3, 2), _components(F("-3/2 "))) self.assertEqual((13, 2), _components(F(" 013/02 \n "))) @@ -190,9 +191,6 @@ class FractionTest(unittest.TestCase): self.assertRaisesMessage( ValueError, "Invalid literal for Fraction: '/2'", F, "/2") - self.assertRaisesMessage( - ValueError, "Invalid literal for Fraction: '3 /2'", - F, "3 /2") self.assertRaisesMessage( # Denominators don't need a sign. ValueError, "Invalid literal for Fraction: '3/+2'", @@ -342,6 +340,19 @@ class FractionTest(unittest.TestCase): ValueError, "cannot convert NaN to integer ratio", F.from_decimal, Decimal("snan")) + def test_is_integer(self): + self.assertTrue(F(1, 1).is_integer()) + self.assertTrue(F(-1, 1).is_integer()) + self.assertTrue(F(1, -1).is_integer()) + self.assertTrue(F(2, 2).is_integer()) + self.assertTrue(F(-2, 2).is_integer()) + self.assertTrue(F(2, -2).is_integer()) + + self.assertFalse(F(1, 2).is_integer()) + self.assertFalse(F(-1, 2).is_integer()) + self.assertFalse(F(1, -2).is_integer()) + self.assertFalse(F(-1, -2).is_integer()) + def test_as_integer_ratio(self): self.assertEqual(F(4, 6).as_integer_ratio(), (2, 3)) self.assertEqual(F(-4, 6).as_integer_ratio(), (-2, 3)) @@ -832,6 +843,382 @@ class FractionTest(unittest.TestCase): self.assertEqual(type(f.numerator), myint) self.assertEqual(type(f.denominator), myint) + def test_format_no_presentation_type(self): + # Triples (fraction, specification, expected_result) + testcases = [ + (F(1, 3), '', '1/3'), + (F(-1, 3), '', '-1/3'), + (F(3), '', '3'), + (F(-3), '', '-3'), + ] + for fraction, spec, expected in testcases: + with self.subTest(fraction=fraction, spec=spec): + self.assertEqual(format(fraction, spec), expected) + + def test_format_e_presentation_type(self): + # Triples (fraction, specification, expected_result) + testcases = [ + (F(2, 3), '.6e', '6.666667e-01'), + (F(3, 2), '.6e', '1.500000e+00'), + (F(2, 13), '.6e', '1.538462e-01'), + (F(2, 23), '.6e', '8.695652e-02'), + (F(2, 33), '.6e', '6.060606e-02'), + (F(13, 2), '.6e', '6.500000e+00'), + (F(20, 2), '.6e', '1.000000e+01'), + (F(23, 2), '.6e', '1.150000e+01'), + (F(33, 2), '.6e', '1.650000e+01'), + (F(2, 3), '.6e', '6.666667e-01'), + (F(3, 2), '.6e', '1.500000e+00'), + # Zero + (F(0), '.3e', '0.000e+00'), + # Powers of 10, to exercise the log10 boundary logic + (F(1, 1000), '.3e', '1.000e-03'), + (F(1, 100), '.3e', '1.000e-02'), + (F(1, 10), '.3e', '1.000e-01'), + (F(1, 1), '.3e', '1.000e+00'), + (F(10), '.3e', '1.000e+01'), + (F(100), '.3e', '1.000e+02'), + (F(1000), '.3e', '1.000e+03'), + # Boundary where we round up to the next power of 10 + (F('99.999994999999'), '.6e', '9.999999e+01'), + (F('99.999995'), '.6e', '1.000000e+02'), + (F('99.999995000001'), '.6e', '1.000000e+02'), + # Negatives + (F(-2, 3), '.6e', '-6.666667e-01'), + (F(-3, 2), '.6e', '-1.500000e+00'), + (F(-100), '.6e', '-1.000000e+02'), + # Large and small + (F('1e1000'), '.3e', '1.000e+1000'), + (F('1e-1000'), '.3e', '1.000e-1000'), + # Using 'E' instead of 'e' should give us a capital 'E' + (F(2, 3), '.6E', '6.666667E-01'), + # Tiny precision + (F(2, 3), '.1e', '6.7e-01'), + (F('0.995'), '.0e', '1e+00'), + # Default precision is 6 + (F(22, 7), 'e', '3.142857e+00'), + # Alternate form forces a decimal point + (F('0.995'), '#.0e', '1.e+00'), + # Check that padding takes the exponent into account. + (F(22, 7), '11.6e', '3.142857e+00'), + (F(22, 7), '12.6e', '3.142857e+00'), + (F(22, 7), '13.6e', ' 3.142857e+00'), + # Thousands separators + (F('1234567.123456'), ',.5e', '1.23457e+06'), + (F('123.123456'), '012_.2e', '0_001.23e+02'), + # z flag is legal, but never makes a difference to the output + (F(-1, 7**100), 'z.6e', '-3.091690e-85'), + ] + for fraction, spec, expected in testcases: + with self.subTest(fraction=fraction, spec=spec): + self.assertEqual(format(fraction, spec), expected) + + def test_format_f_presentation_type(self): + # Triples (fraction, specification, expected_result) + testcases = [ + # Simple .f formatting + (F(0, 1), '.2f', '0.00'), + (F(1, 3), '.2f', '0.33'), + (F(2, 3), '.2f', '0.67'), + (F(4, 3), '.2f', '1.33'), + (F(1, 8), '.2f', '0.12'), + (F(3, 8), '.2f', '0.38'), + (F(1, 13), '.2f', '0.08'), + (F(1, 199), '.2f', '0.01'), + (F(1, 200), '.2f', '0.00'), + (F(22, 7), '.5f', '3.14286'), + (F('399024789'), '.2f', '399024789.00'), + # Large precision (more than float can provide) + (F(104348, 33215), '.50f', + '3.14159265392142104470871594159265392142104470871594'), + # Precision defaults to 6 if not given + (F(22, 7), 'f', '3.142857'), + (F(0), 'f', '0.000000'), + (F(-22, 7), 'f', '-3.142857'), + # Round-ties-to-even checks + (F('1.225'), '.2f', '1.22'), + (F('1.2250000001'), '.2f', '1.23'), + (F('1.2349999999'), '.2f', '1.23'), + (F('1.235'), '.2f', '1.24'), + (F('1.245'), '.2f', '1.24'), + (F('1.2450000001'), '.2f', '1.25'), + (F('1.2549999999'), '.2f', '1.25'), + (F('1.255'), '.2f', '1.26'), + (F('-1.225'), '.2f', '-1.22'), + (F('-1.2250000001'), '.2f', '-1.23'), + (F('-1.2349999999'), '.2f', '-1.23'), + (F('-1.235'), '.2f', '-1.24'), + (F('-1.245'), '.2f', '-1.24'), + (F('-1.2450000001'), '.2f', '-1.25'), + (F('-1.2549999999'), '.2f', '-1.25'), + (F('-1.255'), '.2f', '-1.26'), + # Negatives and sign handling + (F(2, 3), '.2f', '0.67'), + (F(2, 3), '-.2f', '0.67'), + (F(2, 3), '+.2f', '+0.67'), + (F(2, 3), ' .2f', ' 0.67'), + (F(-2, 3), '.2f', '-0.67'), + (F(-2, 3), '-.2f', '-0.67'), + (F(-2, 3), '+.2f', '-0.67'), + (F(-2, 3), ' .2f', '-0.67'), + # Formatting to zero places + (F(1, 2), '.0f', '0'), + (F(-1, 2), '.0f', '-0'), + (F(22, 7), '.0f', '3'), + (F(-22, 7), '.0f', '-3'), + # Formatting to zero places, alternate form + (F(1, 2), '#.0f', '0.'), + (F(-1, 2), '#.0f', '-0.'), + (F(22, 7), '#.0f', '3.'), + (F(-22, 7), '#.0f', '-3.'), + # z flag for suppressing negative zeros + (F('-0.001'), 'z.2f', '0.00'), + (F('-0.001'), '-z.2f', '0.00'), + (F('-0.001'), '+z.2f', '+0.00'), + (F('-0.001'), ' z.2f', ' 0.00'), + (F('0.001'), 'z.2f', '0.00'), + (F('0.001'), '-z.2f', '0.00'), + (F('0.001'), '+z.2f', '+0.00'), + (F('0.001'), ' z.2f', ' 0.00'), + # Specifying a minimum width + (F(2, 3), '6.2f', ' 0.67'), + (F(12345), '6.2f', '12345.00'), + (F(12345), '12f', '12345.000000'), + # Fill and alignment + (F(2, 3), '>6.2f', ' 0.67'), + (F(2, 3), '<6.2f', '0.67 '), + (F(2, 3), '^3.2f', '0.67'), + (F(2, 3), '^4.2f', '0.67'), + (F(2, 3), '^5.2f', '0.67 '), + (F(2, 3), '^6.2f', ' 0.67 '), + (F(2, 3), '^7.2f', ' 0.67 '), + (F(2, 3), '^8.2f', ' 0.67 '), + # '=' alignment + (F(-2, 3), '=+8.2f', '- 0.67'), + (F(2, 3), '=+8.2f', '+ 0.67'), + # Fill character + (F(-2, 3), 'X>3.2f', '-0.67'), + (F(-2, 3), 'X>7.2f', 'XX-0.67'), + (F(-2, 3), 'X<7.2f', '-0.67XX'), + (F(-2, 3), 'X^7.2f', 'X-0.67X'), + (F(-2, 3), 'X=7.2f', '-XX0.67'), + (F(-2, 3), ' >7.2f', ' -0.67'), + # Corner cases: weird fill characters + (F(-2, 3), '\x00>7.2f', '\x00\x00-0.67'), + (F(-2, 3), '\n>7.2f', '\n\n-0.67'), + (F(-2, 3), '\t>7.2f', '\t\t-0.67'), + (F(-2, 3), '>>7.2f', '>>-0.67'), + (F(-2, 3), '<>7.2f', '<<-0.67'), + (F(-2, 3), '→>7.2f', '→→-0.67'), + # Zero-padding + (F(-2, 3), '07.2f', '-000.67'), + (F(-2, 3), '-07.2f', '-000.67'), + (F(2, 3), '+07.2f', '+000.67'), + (F(2, 3), ' 07.2f', ' 000.67'), + # An isolated zero is a minimum width, not a zero-pad flag. + # So unlike zero-padding, it's legal in combination with alignment. + (F(2, 3), '0.2f', '0.67'), + (F(2, 3), '>0.2f', '0.67'), + (F(2, 3), '<0.2f', '0.67'), + (F(2, 3), '^0.2f', '0.67'), + (F(2, 3), '=0.2f', '0.67'), + # Corner case: zero-padding _and_ a zero minimum width. + (F(2, 3), '00.2f', '0.67'), + # Thousands separator (only affects portion before the point) + (F(2, 3), ',.2f', '0.67'), + (F(2, 3), ',.7f', '0.6666667'), + (F('123456.789'), ',.2f', '123,456.79'), + (F('1234567'), ',.2f', '1,234,567.00'), + (F('12345678'), ',.2f', '12,345,678.00'), + (F('12345678'), ',f', '12,345,678.000000'), + # Underscore as thousands separator + (F(2, 3), '_.2f', '0.67'), + (F(2, 3), '_.7f', '0.6666667'), + (F('123456.789'), '_.2f', '123_456.79'), + (F('1234567'), '_.2f', '1_234_567.00'), + (F('12345678'), '_.2f', '12_345_678.00'), + # Thousands and zero-padding + (F('1234.5678'), '07,.2f', '1,234.57'), + (F('1234.5678'), '08,.2f', '1,234.57'), + (F('1234.5678'), '09,.2f', '01,234.57'), + (F('1234.5678'), '010,.2f', '001,234.57'), + (F('1234.5678'), '011,.2f', '0,001,234.57'), + (F('1234.5678'), '012,.2f', '0,001,234.57'), + (F('1234.5678'), '013,.2f', '00,001,234.57'), + (F('1234.5678'), '014,.2f', '000,001,234.57'), + (F('1234.5678'), '015,.2f', '0,000,001,234.57'), + (F('1234.5678'), '016,.2f', '0,000,001,234.57'), + (F('-1234.5678'), '07,.2f', '-1,234.57'), + (F('-1234.5678'), '08,.2f', '-1,234.57'), + (F('-1234.5678'), '09,.2f', '-1,234.57'), + (F('-1234.5678'), '010,.2f', '-01,234.57'), + (F('-1234.5678'), '011,.2f', '-001,234.57'), + (F('-1234.5678'), '012,.2f', '-0,001,234.57'), + (F('-1234.5678'), '013,.2f', '-0,001,234.57'), + (F('-1234.5678'), '014,.2f', '-00,001,234.57'), + (F('-1234.5678'), '015,.2f', '-000,001,234.57'), + (F('-1234.5678'), '016,.2f', '-0,000,001,234.57'), + # Corner case: no decimal point + (F('-1234.5678'), '06,.0f', '-1,235'), + (F('-1234.5678'), '07,.0f', '-01,235'), + (F('-1234.5678'), '08,.0f', '-001,235'), + (F('-1234.5678'), '09,.0f', '-0,001,235'), + # Corner-case - zero-padding specified through fill and align + # instead of the zero-pad character - in this case, treat '0' as a + # regular fill character and don't attempt to insert commas into + # the filled portion. This differs from the int and float + # behaviour. + (F('1234.5678'), '0=12,.2f', '00001,234.57'), + # Corner case where it's not clear whether the '0' indicates zero + # padding or gives the minimum width, but there's still an obvious + # answer to give. We want this to work in case the minimum width + # is being inserted programmatically: spec = f'{width}.2f'. + (F('12.34'), '0.2f', '12.34'), + (F('12.34'), 'X>0.2f', '12.34'), + # 'F' should work identically to 'f' + (F(22, 7), '.5F', '3.14286'), + # %-specifier + (F(22, 7), '.2%', '314.29%'), + (F(1, 7), '.2%', '14.29%'), + (F(1, 70), '.2%', '1.43%'), + (F(1, 700), '.2%', '0.14%'), + (F(1, 7000), '.2%', '0.01%'), + (F(1, 70000), '.2%', '0.00%'), + (F(1, 7), '.0%', '14%'), + (F(1, 7), '#.0%', '14.%'), + (F(100, 7), ',.2%', '1,428.57%'), + (F(22, 7), '7.2%', '314.29%'), + (F(22, 7), '8.2%', ' 314.29%'), + (F(22, 7), '08.2%', '0314.29%'), + # Test cases from #67790 and discuss.python.org Ideas thread. + (F(1, 3), '.2f', '0.33'), + (F(1, 8), '.2f', '0.12'), + (F(3, 8), '.2f', '0.38'), + (F(2545, 1000), '.2f', '2.54'), + (F(2549, 1000), '.2f', '2.55'), + (F(2635, 1000), '.2f', '2.64'), + (F(1, 100), '.1f', '0.0'), + (F(49, 1000), '.1f', '0.0'), + (F(51, 1000), '.1f', '0.1'), + (F(149, 1000), '.1f', '0.1'), + (F(151, 1000), '.1f', '0.2'), + ] + for fraction, spec, expected in testcases: + with self.subTest(fraction=fraction, spec=spec): + self.assertEqual(format(fraction, spec), expected) + + def test_format_g_presentation_type(self): + # Triples (fraction, specification, expected_result) + testcases = [ + (F('0.000012345678'), '.6g', '1.23457e-05'), + (F('0.00012345678'), '.6g', '0.000123457'), + (F('0.0012345678'), '.6g', '0.00123457'), + (F('0.012345678'), '.6g', '0.0123457'), + (F('0.12345678'), '.6g', '0.123457'), + (F('1.2345678'), '.6g', '1.23457'), + (F('12.345678'), '.6g', '12.3457'), + (F('123.45678'), '.6g', '123.457'), + (F('1234.5678'), '.6g', '1234.57'), + (F('12345.678'), '.6g', '12345.7'), + (F('123456.78'), '.6g', '123457'), + (F('1234567.8'), '.6g', '1.23457e+06'), + # Rounding up cases + (F('9.99999e+2'), '.4g', '1000'), + (F('9.99999e-8'), '.4g', '1e-07'), + (F('9.99999e+8'), '.4g', '1e+09'), + # Check round-ties-to-even behaviour + (F('-0.115'), '.2g', '-0.12'), + (F('-0.125'), '.2g', '-0.12'), + (F('-0.135'), '.2g', '-0.14'), + (F('-0.145'), '.2g', '-0.14'), + (F('0.115'), '.2g', '0.12'), + (F('0.125'), '.2g', '0.12'), + (F('0.135'), '.2g', '0.14'), + (F('0.145'), '.2g', '0.14'), + # Trailing zeros and decimal point suppressed by default ... + (F(0), '.6g', '0'), + (F('123.400'), '.6g', '123.4'), + (F('123.000'), '.6g', '123'), + (F('120.000'), '.6g', '120'), + (F('12000000'), '.6g', '1.2e+07'), + # ... but not when alternate form is in effect + (F(0), '#.6g', '0.00000'), + (F('123.400'), '#.6g', '123.400'), + (F('123.000'), '#.6g', '123.000'), + (F('120.000'), '#.6g', '120.000'), + (F('12000000'), '#.6g', '1.20000e+07'), + # 'G' format (uses 'E' instead of 'e' for the exponent indicator) + (F('123.45678'), '.6G', '123.457'), + (F('1234567.8'), '.6G', '1.23457E+06'), + # Default precision is 6 significant figures + (F('3.1415926535'), 'g', '3.14159'), + # Precision 0 is treated the same as precision 1. + (F('0.000031415'), '.0g', '3e-05'), + (F('0.00031415'), '.0g', '0.0003'), + (F('0.31415'), '.0g', '0.3'), + (F('3.1415'), '.0g', '3'), + (F('3.1415'), '#.0g', '3.'), + (F('31.415'), '.0g', '3e+01'), + (F('31.415'), '#.0g', '3.e+01'), + (F('0.000031415'), '.1g', '3e-05'), + (F('0.00031415'), '.1g', '0.0003'), + (F('0.31415'), '.1g', '0.3'), + (F('3.1415'), '.1g', '3'), + (F('3.1415'), '#.1g', '3.'), + (F('31.415'), '.1g', '3e+01'), + # Thousands separator + (F(2**64), '_.25g', '18_446_744_073_709_551_616'), + # As with 'e' format, z flag is legal, but has no effect + (F(-1, 7**100), 'zg', '-3.09169e-85'), + ] + for fraction, spec, expected in testcases: + with self.subTest(fraction=fraction, spec=spec): + self.assertEqual(format(fraction, spec), expected) + + def test_invalid_formats(self): + fraction = F(2, 3) + with self.assertRaises(TypeError): + format(fraction, None) + + invalid_specs = [ + 'Q6f', # regression test + # illegal to use fill or alignment when zero padding + 'X>010f', + 'X<010f', + 'X^010f', + 'X=010f', + '0>010f', + '0<010f', + '0^010f', + '0=010f', + '>010f', + '<010f', + '^010f', + '=010e', + '=010f', + '=010g', + '=010%', + '>00.2f', + '>00f', + # Too many zeros - minimum width should not have leading zeros + '006f', + # Leading zeros in precision + '.010f', + '.02f', + '.000f', + # Missing precision + '.e', + '.f', + '.g', + '.%', + # Z instead of z for negative zero suppression + 'Z.2f' + ] + for spec in invalid_specs: + with self.subTest(spec=spec): + with self.assertRaises(ValueError): + format(fraction, spec) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py index a715e725a7e..6bb0144e9b1 100644 --- a/Lib/test/test_frame.py +++ b/Lib/test/test_frame.py @@ -1,10 +1,20 @@ +import gc +import operator import re import sys +import textwrap +import threading import types import unittest import weakref +try: + import _testcapi +except ImportError: + _testcapi = None from test import support +from test.support import threading_helper +from test.support.script_helper import assert_python_ok class ClearTest(unittest.TestCase): @@ -235,6 +245,199 @@ class ReprTest(unittest.TestCase): r"^$" % (file_repr, offset + 5)) +class TestIncompleteFrameAreInvisible(unittest.TestCase): + + def test_issue95818(self): + # See GH-95818 for details + code = textwrap.dedent(f""" + import gc + + gc.set_threshold(1,1,1) + class GCHello: + def __del__(self): + print("Destroyed from gc") + + def gen(): + yield + + fd = open({__file__!r}) + l = [fd, GCHello()] + l.append(l) + del fd + del l + gen() + """) + assert_python_ok("-c", code) + + @support.cpython_only + def test_sneaky_frame_object(self): + + def trace(frame, event, arg): + """ + Don't actually do anything, just force a frame object to be created. + """ + + def callback(phase, info): + """ + Yo dawg, I heard you like frames, so I'm allocating a frame while + you're allocating a frame, so you can have a frame while you have a + frame! + """ + nonlocal sneaky_frame_object + sneaky_frame_object = sys._getframe().f_back.f_back + # We're done here: + gc.callbacks.remove(callback) + + def f(): + while True: + yield + + old_threshold = gc.get_threshold() + old_callbacks = gc.callbacks[:] + old_enabled = gc.isenabled() + old_trace = sys.gettrace() + try: + # Stop the GC for a second while we set things up: + gc.disable() + # Create a paused generator: + g = f() + next(g) + # Move all objects to the oldest generation, and tell the GC to run + # on the *very next* allocation: + gc.collect() + gc.set_threshold(1, 0, 0) + # Okay, so here's the nightmare scenario: + # - We're tracing the resumption of a generator, which creates a new + # frame object. + # - The allocation of this frame object triggers a collection + # *before* the frame object is actually created. + # - During the collection, we request the exact same frame object. + # This test does it with a GC callback, but in real code it would + # likely be a trace function, weakref callback, or finalizer. + # - The collection finishes, and the original frame object is + # created. We now have two frame objects fighting over ownership + # of the same interpreter frame! + sys.settrace(trace) + gc.callbacks.append(callback) + sneaky_frame_object = None + gc.enable() + next(g) + # g.gi_frame should be the the frame object from the callback (the + # one that was *requested* second, but *created* first): + self.assertIs(g.gi_frame, sneaky_frame_object) + finally: + gc.set_threshold(*old_threshold) + gc.callbacks[:] = old_callbacks + sys.settrace(old_trace) + if old_enabled: + gc.enable() + + @support.cpython_only + @threading_helper.requires_working_threading() + def test_sneaky_frame_object_teardown(self): + + class SneakyDel: + def __del__(self): + """ + Stash a reference to the entire stack for walking later. + + It may look crazy, but you'd be surprised how common this is + when using a test runner (like pytest). The typical recipe is: + ResourceWarning + -Werror + a custom sys.unraisablehook. + """ + nonlocal sneaky_frame_object + sneaky_frame_object = sys._getframe() + + class SneakyThread(threading.Thread): + """ + A separate thread isn't needed to make this code crash, but it does + make crashes more consistent, since it means sneaky_frame_object is + backed by freed memory after the thread completes! + """ + + def run(self): + """Run SneakyDel.__del__ as this frame is popped.""" + ref = SneakyDel() + + sneaky_frame_object = None + t = SneakyThread() + t.start() + t.join() + # sneaky_frame_object can be anything, really, but it's crucial that + # SneakyThread.run's frame isn't anywhere on the stack while it's being + # torn down: + self.assertIsNotNone(sneaky_frame_object) + while sneaky_frame_object is not None: + self.assertIsNot( + sneaky_frame_object.f_code, SneakyThread.run.__code__ + ) + sneaky_frame_object = sneaky_frame_object.f_back + + def test_entry_frames_are_invisible_during_teardown(self): + class C: + """A weakref'able class.""" + + def f(): + """Try to find globals and locals as this frame is being cleared.""" + ref = C() + # Ignore the fact that exec(C()) is a nonsense callback. We're only + # using exec here because it tries to access the current frame's + # globals and locals. If it's trying to get those from a shim frame, + # we'll crash before raising: + return weakref.ref(ref, exec) + + with support.catch_unraisable_exception() as catcher: + # Call from C, so there is a shim frame directly above f: + weak = operator.call(f) # BOOM! + # Cool, we didn't crash. Check that the callback actually happened: + self.assertIs(catcher.unraisable.exc_type, TypeError) + self.assertIsNone(weak()) + +@unittest.skipIf(_testcapi is None, 'need _testcapi') +class TestCAPI(unittest.TestCase): + def getframe(self): + return sys._getframe() + + def test_frame_getters(self): + frame = self.getframe() + self.assertEqual(frame.f_locals, _testcapi.frame_getlocals(frame)) + self.assertIs(frame.f_globals, _testcapi.frame_getglobals(frame)) + self.assertIs(frame.f_builtins, _testcapi.frame_getbuiltins(frame)) + self.assertEqual(frame.f_lasti, _testcapi.frame_getlasti(frame)) + + def test_getvar(self): + current_frame = sys._getframe() + x = 1 + self.assertEqual(_testcapi.frame_getvar(current_frame, "x"), 1) + self.assertEqual(_testcapi.frame_getvarstring(current_frame, b"x"), 1) + with self.assertRaises(NameError): + _testcapi.frame_getvar(current_frame, "y") + with self.assertRaises(NameError): + _testcapi.frame_getvarstring(current_frame, b"y") + + # wrong name type + with self.assertRaises(TypeError): + _testcapi.frame_getvar(current_frame, b'x') + with self.assertRaises(TypeError): + _testcapi.frame_getvar(current_frame, 123) + + def getgenframe(self): + yield sys._getframe() + + def test_frame_get_generator(self): + gen = self.getgenframe() + frame = next(gen) + self.assertIs(gen, _testcapi.frame_getgenerator(frame)) + + def test_frame_fback_api(self): + """Test that accessing `f_back` does not cause a segmentation fault on + a frame created with `PyFrame_New` (GH-99110).""" + def dummy(): + pass + + frame = _testcapi.frame_new(dummy.__code__, globals(), locals()) + # The following line should not cause a segmentation fault. + self.assertIsNone(frame.f_back) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 14a4c678fc9..318f38a6ed5 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -346,10 +346,39 @@ non-important content self.assertEqual(binop.lineno, 4) self.assertEqual(binop.left.lineno, 4) self.assertEqual(binop.right.lineno, 6) - self.assertEqual(binop.col_offset, 4) - self.assertEqual(binop.left.col_offset, 4) + self.assertEqual(binop.col_offset, 3) + self.assertEqual(binop.left.col_offset, 3) self.assertEqual(binop.right.col_offset, 7) + expr = """ +a = f''' + {blech} + ''' +""" + t = ast.parse(expr) + self.assertEqual(type(t), ast.Module) + self.assertEqual(len(t.body), 1) + # Check f'...' + self.assertEqual(type(t.body[0]), ast.Assign) + self.assertEqual(type(t.body[0].value), ast.JoinedStr) + self.assertEqual(len(t.body[0].value.values), 3) + self.assertEqual(type(t.body[0].value.values[1]), ast.FormattedValue) + self.assertEqual(t.body[0].lineno, 2) + self.assertEqual(t.body[0].value.lineno, 2) + self.assertEqual(t.body[0].value.values[0].lineno, 2) + self.assertEqual(t.body[0].value.values[1].lineno, 2) + self.assertEqual(t.body[0].value.values[2].lineno, 2) + self.assertEqual(t.body[0].col_offset, 0) + self.assertEqual(t.body[0].value.col_offset, 4) + self.assertEqual(t.body[0].value.values[0].col_offset, 4) + self.assertEqual(t.body[0].value.values[1].col_offset, 4) + self.assertEqual(t.body[0].value.values[2].col_offset, 4) + # Check {blech} + self.assertEqual(t.body[0].value.values[1].value.lineno, 3) + self.assertEqual(t.body[0].value.values[1].value.end_lineno, 3) + self.assertEqual(t.body[0].value.values[1].value.col_offset, 11) + self.assertEqual(t.body[0].value.values[1].value.end_col_offset, 16) + def test_ast_line_numbers_with_parentheses(self): expr = """ x = ( @@ -590,7 +619,9 @@ x = ( self.assertEqual(f'{-10:{"-"}#{1}0{"x"}}', ' -0xa') self.assertEqual(f'{10:#{3 != {4:5} and width}x}', ' 0xa') - self.assertAllRaise(SyntaxError, "f-string: expecting '}'", + self.assertAllRaise(SyntaxError, + """f-string: invalid conversion character 'r{"': """ + """expected 's', 'r', or 'a'""", ["""f'{"s"!r{":10"}}'""", # This looks like a nested format spec. @@ -628,16 +659,27 @@ x = ( ["f'{}'", "f'{ }'" "f' {} '", - "f'{!r}'", - "f'{ !r}'", "f'{10:{ }}'", "f' { } '", # The Python parser ignores also the following # whitespace characters in additional to a space. "f'''{\t\f\r\n}'''", + ]) - # Catch the empty expression before the + # Different error messeges are raised when a specfier ('!', ':' or '=') is used after an empty expression + self.assertAllRaise(SyntaxError, "f-string: expression required before '!'", + ["f'{!r}'", + "f'{ !r}'", + "f'{!}'", + "f'''{\t\f\r\n!a}'''", + + # Catch empty expression before the + # missing closing brace. + "f'{!'", + "f'{!s:'", + + # Catch empty expression before the # invalid conversion. "f'{!x}'", "f'{ !xr}'", @@ -645,16 +687,23 @@ x = ( "f'{!x:a}'", "f'{ !xr:}'", "f'{ !xr:a}'", + ]) - "f'{!}'", - "f'{:}'", - - # We find the empty expression before the - # missing closing brace. - "f'{!'", - "f'{!s:'", + self.assertAllRaise(SyntaxError, "f-string: expression required before ':'", + ["f'{:}'", + "f'{ :!}'", + "f'{:2}'", + "f'''{\t\f\r\n:a}'''", "f'{:'", - "f'{:x'", + ]) + + self.assertAllRaise(SyntaxError, "f-string: expression required before '='", + ["f'{=}'", + "f'{ =}'", + "f'{ =:}'", + "f'{ =!}'", + "f'''{\t\f\r\n=}'''", + "f'{='", ]) # Different error message is raised for other whitespace characters. @@ -727,7 +776,7 @@ x = ( self.assertEqual(f'2\x203', '2 3') self.assertEqual(f'\x203', ' 3') - with self.assertWarns(DeprecationWarning): # invalid escape sequence + with self.assertWarns(SyntaxWarning): # invalid escape sequence value = eval(r"f'\{6*7}'") self.assertEqual(value, '\\42') self.assertEqual(f'\\{6*7}', '\\42') @@ -746,12 +795,16 @@ x = ( # differently inside f-strings. self.assertAllRaise(SyntaxError, r"\(unicode error\) 'unicodeescape' codec can't decode bytes in position .*: malformed \\N character escape", [r"f'\N'", + r"f'\N '", + r"f'\N '", # See bpo-46503. r"f'\N{'", r"f'\N{GREEK CAPITAL LETTER DELTA'", # Here are the non-f-string versions, # which should give the same errors. r"'\N'", + r"'\N '", + r"'\N '", r"'\N{'", r"'\N{GREEK CAPITAL LETTER DELTA'", ]) @@ -944,7 +997,7 @@ x = ( "Bf''", "BF''",] double_quote_cases = [case.replace("'", '"') for case in single_quote_cases] - self.assertAllRaise(SyntaxError, 'unexpected EOF while parsing', + self.assertAllRaise(SyntaxError, 'invalid syntax', single_quote_cases + double_quote_cases) def test_leading_trailing_spaces(self): @@ -990,19 +1043,28 @@ x = ( # Not a conversion, but show that ! is allowed in a format spec. self.assertEqual(f'{3.14:!<10.10}', '3.14!!!!!!') - self.assertAllRaise(SyntaxError, 'f-string: invalid conversion character', - ["f'{3!g}'", - "f'{3!A}'", - "f'{3!3}'", - "f'{3!G}'", - "f'{3!!}'", - "f'{3!:}'", - "f'{3! s}'", # no space before conversion char + self.assertAllRaise(SyntaxError, "f-string: expecting '}'", + ["f'{3!'", + "f'{3!s'", + "f'{3!g'", ]) - self.assertAllRaise(SyntaxError, "f-string: expecting '}'", - ["f'{x!s{y}}'", - "f'{3!ss}'", + self.assertAllRaise(SyntaxError, 'f-string: missed conversion character', + ["f'{3!}'", + "f'{3!:'", + "f'{3!:}'", + ]) + + for conv in 'g', 'A', '3', 'G', '!', ' s', 's ', ' s ', 'ä', 'É', 'ª': + self.assertAllRaise(SyntaxError, + "f-string: invalid conversion character %r: " + "expected 's', 'r', or 'a'" % conv, + ["f'{3!" + conv + "}'"]) + + self.assertAllRaise(SyntaxError, + "f-string: invalid conversion character 'ss': " + "expected 's', 'r', or 'a'", + ["f'{3!ss}'", "f'{3!ss:}'", "f'{3!ss:s}'", ]) @@ -1049,6 +1111,9 @@ x = ( "f'{{{'", "f'{{}}{'", "f'{'", + "f'x{<'", # See bpo-46762. + "f'x{>'", + "f'{i='", # See gh-93418. ]) # But these are just normal strings. diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py index c9edfac9687..544228e3bab 100644 --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -18,14 +18,16 @@ except ImportError: from unittest import TestCase, skipUnless from test import support -from test.support import _asynchat as asynchat -from test.support import _asyncore as asyncore -from test.support import socket_helper from test.support import threading_helper +from test.support import socket_helper from test.support import warnings_helper +from test.support import asynchat +from test.support import asyncore from test.support.socket_helper import HOST, HOSTv6 +support.requires_working_socket(module=True) + TIMEOUT = support.LOOPBACK_TIMEOUT DEFAULT_ENCODING = 'utf-8' # the dummy data returned by server over the data channel when @@ -52,6 +54,13 @@ MLSD_DATA = ("type=cdir;perm=el;unique==keVO1+ZF4; test\r\n" "type=file;perm=r;unique==SGP2; file \xAE non-ascii char\r\n") +def default_error_handler(): + # bpo-44359: Silently ignore socket errors. Such errors occur when a client + # socket is closed, in TestFTPClass.tearDown() and makepasv() tests, and + # the server gets an error on its side. + pass + + class DummyDTPHandler(asynchat.async_chat): dtp_conn_closed = False @@ -83,7 +92,7 @@ class DummyDTPHandler(asynchat.async_chat): super(DummyDTPHandler, self).push(what.encode(self.encoding)) def handle_error(self): - raise Exception + default_error_handler() class DummyFTPHandler(asynchat.async_chat): @@ -133,7 +142,7 @@ class DummyFTPHandler(asynchat.async_chat): self.push('550 command "%s" not understood.' %cmd) def handle_error(self): - raise Exception + default_error_handler() def push(self, data): asynchat.async_chat.push(self, data.encode(self.encoding) + b'\r\n') @@ -311,7 +320,7 @@ class DummyFTPServer(asyncore.dispatcher, threading.Thread): return 0 def handle_error(self): - raise Exception + default_error_handler() if ssl is not None: @@ -414,7 +423,7 @@ if ssl is not None: raise def handle_error(self): - raise Exception + default_error_handler() def close(self): if (isinstance(self.socket, ssl.SSLSocket) and @@ -973,11 +982,11 @@ class TestTLS_FTPClass(TestCase): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE - self.assertRaises(ValueError, ftplib.FTP_TLS, keyfile=CERTFILE, + self.assertRaises(TypeError, ftplib.FTP_TLS, keyfile=CERTFILE, context=ctx) - self.assertRaises(ValueError, ftplib.FTP_TLS, certfile=CERTFILE, + self.assertRaises(TypeError, ftplib.FTP_TLS, certfile=CERTFILE, context=ctx) - self.assertRaises(ValueError, ftplib.FTP_TLS, certfile=CERTFILE, + self.assertRaises(TypeError, ftplib.FTP_TLS, certfile=CERTFILE, keyfile=CERTFILE, context=ctx) self.client = ftplib.FTP_TLS(context=ctx, timeout=TIMEOUT) diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 08cf457cc17..730ab1f595f 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -13,15 +13,14 @@ import time import typing import unittest import unittest.mock -import os import weakref import gc from weakref import proxy import contextlib +from inspect import Signature from test.support import import_helper from test.support import threading_helper -from test.support.script_helper import assert_python_ok import functools @@ -943,6 +942,10 @@ class TestCmpToKey: self.assertRaises(TypeError, hash, k) self.assertNotIsInstance(k, collections.abc.Hashable) + def test_cmp_to_signature(self): + self.assertEqual(str(Signature.from_callable(self.cmp_to_key)), + '(mycmp)') + @unittest.skipUnless(c_functools, 'requires the C _functools module') class TestCmpToKeyC(TestCmpToKey, unittest.TestCase): @@ -1049,6 +1052,73 @@ class TestTotalOrdering(unittest.TestCase): class A: pass + def test_notimplemented(self): + # Verify NotImplemented results are correctly handled + @functools.total_ordering + class ImplementsLessThan: + def __init__(self, value): + self.value = value + def __eq__(self, other): + if isinstance(other, ImplementsLessThan): + return self.value == other.value + return False + def __lt__(self, other): + if isinstance(other, ImplementsLessThan): + return self.value < other.value + return NotImplemented + + @functools.total_ordering + class ImplementsLessThanEqualTo: + def __init__(self, value): + self.value = value + def __eq__(self, other): + if isinstance(other, ImplementsLessThanEqualTo): + return self.value == other.value + return False + def __le__(self, other): + if isinstance(other, ImplementsLessThanEqualTo): + return self.value <= other.value + return NotImplemented + + @functools.total_ordering + class ImplementsGreaterThan: + def __init__(self, value): + self.value = value + def __eq__(self, other): + if isinstance(other, ImplementsGreaterThan): + return self.value == other.value + return False + def __gt__(self, other): + if isinstance(other, ImplementsGreaterThan): + return self.value > other.value + return NotImplemented + + @functools.total_ordering + class ImplementsGreaterThanEqualTo: + def __init__(self, value): + self.value = value + def __eq__(self, other): + if isinstance(other, ImplementsGreaterThanEqualTo): + return self.value == other.value + return False + def __ge__(self, other): + if isinstance(other, ImplementsGreaterThanEqualTo): + return self.value >= other.value + return NotImplemented + + self.assertIs(ImplementsLessThan(1).__le__(1), NotImplemented) + self.assertIs(ImplementsLessThan(1).__gt__(1), NotImplemented) + self.assertIs(ImplementsLessThan(1).__ge__(1), NotImplemented) + self.assertIs(ImplementsLessThanEqualTo(1).__lt__(1), NotImplemented) + self.assertIs(ImplementsLessThanEqualTo(1).__gt__(1), NotImplemented) + self.assertIs(ImplementsLessThanEqualTo(1).__ge__(1), NotImplemented) + self.assertIs(ImplementsGreaterThan(1).__lt__(1), NotImplemented) + self.assertIs(ImplementsGreaterThan(1).__gt__(1), NotImplemented) + self.assertIs(ImplementsGreaterThan(1).__ge__(1), NotImplemented) + self.assertIs(ImplementsGreaterThanEqualTo(1).__lt__(1), NotImplemented) + self.assertIs(ImplementsGreaterThanEqualTo(1).__le__(1), NotImplemented) + self.assertIs(ImplementsGreaterThanEqualTo(1).__gt__(1), NotImplemented) + def test_type_error_when_not_implemented(self): # bug 10042; ensure stack overflow does not occur # when decorated types return NotImplemented @@ -1414,7 +1484,7 @@ class TestLRU: def test_lru_star_arg_handling(self): # Test regression that arose in ea064ff3c10f - @functools.lru_cache() + @self.module.lru_cache() def f(*args): return args @@ -1426,11 +1496,11 @@ class TestLRU: # lru_cache was leaking when one of the arguments # wasn't cacheable. - @functools.lru_cache(maxsize=None) + @self.module.lru_cache(maxsize=None) def infinite_cache(o): pass - @functools.lru_cache(maxsize=10) + @self.module.lru_cache(maxsize=10) def limited_cache(o): pass @@ -1570,6 +1640,7 @@ class TestLRU: for attr in self.module.WRAPPER_ASSIGNMENTS: self.assertEqual(getattr(g, attr), getattr(f, attr)) + @threading_helper.requires_working_threading() def test_lru_cache_threaded(self): n, m = 5, 11 def orig(x, y): @@ -1618,6 +1689,7 @@ class TestLRU: finally: sys.setswitchinterval(orig_si) + @threading_helper.requires_working_threading() def test_lru_cache_threaded2(self): # Simultaneous call with the same arguments n, m = 5, 7 @@ -1645,6 +1717,7 @@ class TestLRU: pause.reset() self.assertEqual(f.cache_info(), (0, (i+1)*n, m*n, i+1)) + @threading_helper.requires_working_threading() def test_lru_cache_threaded3(self): @self.module.lru_cache(maxsize=2) def f(x): @@ -1785,6 +1858,13 @@ class TestLRU: for ref in refs: self.assertIsNone(ref()) + def test_common_signatures(self): + def orig(): ... + lru = self.module.lru_cache(1)(orig) + + self.assertEqual(str(Signature.from_callable(lru.cache_info)), '()') + self.assertEqual(str(Signature.from_callable(lru.cache_clear)), '()') + @py_functools.lru_cache() def py_cached_func(x, y): @@ -1935,7 +2015,7 @@ class TestSingleDispatch(unittest.TestCase): c.MutableSequence.register(D) bases = [c.MutableSequence, c.MutableMapping] for haystack in permutations(bases): - m = mro(D, bases) + m = mro(D, haystack) self.assertEqual(m, [D, c.MutableSequence, c.Sequence, c.Reversible, collections.defaultdict, dict, c.MutableMapping, c.Mapping, c.Collection, c.Sized, c.Iterable, c.Container, @@ -2684,6 +2764,17 @@ class TestSingleDispatch(unittest.TestCase): 'typing.Iterable[str] is not a class.' )) + with self.assertRaises(TypeError) as exc: + @i.register + def _(arg: typing.Union[int, typing.Iterable[str]]): + return "Invalid Union" + self.assertTrue(str(exc.exception).startswith( + "Invalid annotation for 'arg'." + )) + self.assertTrue(str(exc.exception).endswith( + 'typing.Union[int, typing.Iterable[str]] not all arguments are classes.' + )) + def test_invalid_positional_argument(self): @functools.singledispatch def f(*args): @@ -2692,6 +2783,128 @@ class TestSingleDispatch(unittest.TestCase): with self.assertRaisesRegex(TypeError, msg): f() + def test_union(self): + @functools.singledispatch + def f(arg): + return "default" + + @f.register + def _(arg: typing.Union[str, bytes]): + return "typing.Union" + + @f.register + def _(arg: int | float): + return "types.UnionType" + + self.assertEqual(f([]), "default") + self.assertEqual(f(""), "typing.Union") + self.assertEqual(f(b""), "typing.Union") + self.assertEqual(f(1), "types.UnionType") + self.assertEqual(f(1.0), "types.UnionType") + + def test_union_conflict(self): + @functools.singledispatch + def f(arg): + return "default" + + @f.register + def _(arg: typing.Union[str, bytes]): + return "typing.Union" + + @f.register + def _(arg: int | str): + return "types.UnionType" + + self.assertEqual(f([]), "default") + self.assertEqual(f(""), "types.UnionType") # last one wins + self.assertEqual(f(b""), "typing.Union") + self.assertEqual(f(1), "types.UnionType") + + def test_union_None(self): + @functools.singledispatch + def typing_union(arg): + return "default" + + @typing_union.register + def _(arg: typing.Union[str, None]): + return "typing.Union" + + self.assertEqual(typing_union(1), "default") + self.assertEqual(typing_union(""), "typing.Union") + self.assertEqual(typing_union(None), "typing.Union") + + @functools.singledispatch + def types_union(arg): + return "default" + + @types_union.register + def _(arg: int | None): + return "types.UnionType" + + self.assertEqual(types_union(""), "default") + self.assertEqual(types_union(1), "types.UnionType") + self.assertEqual(types_union(None), "types.UnionType") + + def test_register_genericalias(self): + @functools.singledispatch + def f(arg): + return "default" + + with self.assertRaisesRegex(TypeError, "Invalid first argument to "): + f.register(list[int], lambda arg: "types.GenericAlias") + with self.assertRaisesRegex(TypeError, "Invalid first argument to "): + f.register(typing.List[int], lambda arg: "typing.GenericAlias") + with self.assertRaisesRegex(TypeError, "Invalid first argument to "): + f.register(list[int] | str, lambda arg: "types.UnionTypes(types.GenericAlias)") + with self.assertRaisesRegex(TypeError, "Invalid first argument to "): + f.register(typing.List[float] | bytes, lambda arg: "typing.Union[typing.GenericAlias]") + + self.assertEqual(f([1]), "default") + self.assertEqual(f([1.0]), "default") + self.assertEqual(f(""), "default") + self.assertEqual(f(b""), "default") + + def test_register_genericalias_decorator(self): + @functools.singledispatch + def f(arg): + return "default" + + with self.assertRaisesRegex(TypeError, "Invalid first argument to "): + f.register(list[int]) + with self.assertRaisesRegex(TypeError, "Invalid first argument to "): + f.register(typing.List[int]) + with self.assertRaisesRegex(TypeError, "Invalid first argument to "): + f.register(list[int] | str) + with self.assertRaisesRegex(TypeError, "Invalid first argument to "): + f.register(typing.List[int] | str) + + def test_register_genericalias_annotation(self): + @functools.singledispatch + def f(arg): + return "default" + + with self.assertRaisesRegex(TypeError, "Invalid annotation for 'arg'"): + @f.register + def _(arg: list[int]): + return "types.GenericAlias" + with self.assertRaisesRegex(TypeError, "Invalid annotation for 'arg'"): + @f.register + def _(arg: typing.List[float]): + return "typing.GenericAlias" + with self.assertRaisesRegex(TypeError, "Invalid annotation for 'arg'"): + @f.register + def _(arg: list[int] | str): + return "types.UnionType(types.GenericAlias)" + with self.assertRaisesRegex(TypeError, "Invalid annotation for 'arg'"): + @f.register + def _(arg: typing.List[float] | bytes): + return "typing.Union[typing.GenericAlias]" + + self.assertEqual(f([1]), "default") + self.assertEqual(f([1.0]), "default") + self.assertEqual(f(""), "default") + self.assertEqual(f(b""), "default") + class CachedCostItem: _cost = 1 @@ -2757,6 +2970,7 @@ class TestCachedProperty(unittest.TestCase): self.assertEqual(item.get_cost(), 4) self.assertEqual(item.cached_cost, 3) + @threading_helper.requires_working_threading() def test_threaded(self): go = threading.Event() item = CachedCostItemWait(go) diff --git a/Lib/test/test_future.py b/Lib/test/test_future.py index 5a3944e69e6..b8b591a1bcf 100644 --- a/Lib/test/test_future.py +++ b/Lib/test/test_future.py @@ -3,7 +3,6 @@ import __future__ import ast import unittest -from test import support from test.support import import_helper from textwrap import dedent import os @@ -61,7 +60,7 @@ class FutureTest(unittest.TestCase): def test_badfuture7(self): with self.assertRaises(SyntaxError) as cm: from test import badsyntax_future7 - self.check_syntax_error(cm.exception, "badsyntax_future7", 3, 53) + self.check_syntax_error(cm.exception, "badsyntax_future7", 3, 54) def test_badfuture8(self): with self.assertRaises(SyntaxError) as cm: @@ -175,7 +174,7 @@ class AnnotationsFutureTestCase(unittest.TestCase): scope = {} exec( "from __future__ import annotations\n" - + code, {}, scope + + code, scope ) return scope @@ -287,10 +286,11 @@ class AnnotationsFutureTestCase(unittest.TestCase): eq("list[str]") eq("dict[str, int]") eq("set[str,]") + eq("tuple[()]") eq("tuple[str, ...]") - eq("tuple[(str, *types)]") + eq("tuple[str, *types]") eq("tuple[str, int, (str, int)]") - eq("tuple[(*int, str, str, (str, int))]") + eq("tuple[*int, str, str, (str, int)]") eq("tuple[str, int, float, dict[str, int]]") eq("slice[0]") eq("slice[0:1]") @@ -305,6 +305,21 @@ class AnnotationsFutureTestCase(unittest.TestCase): eq("slice[1:2, 1]") eq("slice[1:2, 2, 3]") eq("slice[()]") + # Note that `slice[*Ts]`, `slice[*Ts,]`, and `slice[(*Ts,)]` all have + # the same AST, but only `slice[*Ts,]` passes this test, because that's + # what the unparser produces. + eq("slice[*Ts,]") + eq("slice[1, *Ts]") + eq("slice[*Ts, 2]") + eq("slice[1, *Ts, 2]") + eq("slice[*Ts, *Ts]") + eq("slice[1, *Ts, *Ts]") + eq("slice[*Ts, 1, *Ts]") + eq("slice[*Ts, *Ts, 1]") + eq("slice[1, *Ts, *Ts, 2]") + eq("slice[1:2, *Ts]") + eq("slice[*Ts, 1:2]") + eq("slice[1:2, *Ts, 3:4]") eq("slice[a, b:c, d:e:f]") eq("slice[(x for x in a)]") eq('str or None if sys.version_info[0] > (3,) else str or bytes or None') @@ -403,6 +418,25 @@ class AnnotationsFutureTestCase(unittest.TestCase): def bar(arg: (yield)): pass """)) + def test_get_type_hints_on_func_with_variadic_arg(self): + # `typing.get_type_hints` might break on a function with a variadic + # annotation (e.g. `f(*args: *Ts)`) if `from __future__ import + # annotations`, because it could try to evaluate `*Ts` as an expression, + # which on its own isn't value syntax. + namespace = self._exec_future(dedent("""\ + class StarredC: pass + class C: + def __iter__(self): + yield StarredC() + c = C() + def f(*args: *c): pass + import typing + hints = typing.get_type_hints(f) + """)) + + hints = namespace.pop('hints') + self.assertIsInstance(hints['args'], namespace['StarredC']) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py index 52948f1c7bd..db7cb9ace6e 100644 --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py @@ -1,7 +1,7 @@ import unittest import unittest.mock from test.support import (verbose, refcount_test, - cpython_only) + cpython_only, requires_subprocess) from test.support.import_helper import import_module from test.support.os_helper import temp_dir, TESTFN, unlink from test.support.script_helper import assert_python_ok, make_script @@ -227,6 +227,73 @@ class GCTests(unittest.TestCase): del d self.assertEqual(gc.collect(), 2) + def test_function_tp_clear_leaves_consistent_state(self): + # https://github.com/python/cpython/issues/91636 + code = """if 1: + + import gc + import weakref + + class LateFin: + __slots__ = ('ref',) + + def __del__(self): + + # 8. Now `latefin`'s finalizer is called. Here we + # obtain a reference to `func`, which is currently + # undergoing `tp_clear`. + global func + func = self.ref() + + class Cyclic(tuple): + __slots__ = () + + # 4. The finalizers of all garbage objects are called. In + # this case this is only us as `func` doesn't have a + # finalizer. + def __del__(self): + + # 5. Create a weakref to `func` now. If we had created + # it earlier, it would have been cleared by the + # garbage collector before calling the finalizers. + self[1].ref = weakref.ref(self[0]) + + # 6. Drop the global reference to `latefin`. The only + # remaining reference is the one we have. + global latefin + del latefin + + # 7. Now `func` is `tp_clear`-ed. This drops the last + # reference to `Cyclic`, which gets `tp_dealloc`-ed. + # This drops the last reference to `latefin`. + + latefin = LateFin() + def func(): + pass + cyc = tuple.__new__(Cyclic, (func, latefin)) + + # 1. Create a reference cycle of `cyc` and `func`. + func.__module__ = cyc + + # 2. Make the cycle unreachable, but keep the global reference + # to `latefin` so that it isn't detected as garbage. This + # way its finalizer will not be called immediately. + del func, cyc + + # 3. Invoke garbage collection, + # which will find `cyc` and `func` as garbage. + gc.collect() + + # 9. Previously, this would crash because `func_qualname` + # had been NULL-ed out by func_clear(). + print(f"{func=}") + """ + # We're mostly just checking that this doesn't crash. + rc, stdout, stderr = assert_python_ok("-c", code) + self.assertEqual(rc, 0) + self.assertRegex(stdout, rb"""\A\s*func=\s*\Z""") + self.assertFalse(stderr) + @refcount_test def test_frame(self): def f(): @@ -365,6 +432,7 @@ class GCTests(unittest.TestCase): v = {1: v, 2: Ouch()} gc.disable() + @threading_helper.requires_working_threading() def test_trashcan_threads(self): # Issue #13992: trashcan mechanism should be thread-safe NESTING = 60 @@ -474,48 +542,6 @@ class GCTests(unittest.TestCase): self.assertEqual(gc.collect(), 2) self.assertEqual(len(gc.garbage), garbagelen) - def test_boom_new(self): - # boom__new and boom2_new are exactly like boom and boom2, except use - # new-style classes. - - class Boom_New(object): - def __getattr__(self, someattribute): - del self.attr - raise AttributeError - - a = Boom_New() - b = Boom_New() - a.attr = b - b.attr = a - - gc.collect() - garbagelen = len(gc.garbage) - del a, b - self.assertEqual(gc.collect(), 2) - self.assertEqual(len(gc.garbage), garbagelen) - - def test_boom2_new(self): - class Boom2_New(object): - def __init__(self): - self.x = 0 - - def __getattr__(self, someattribute): - self.x += 1 - if self.x > 1: - del self.attr - raise AttributeError - - a = Boom2_New() - b = Boom2_New() - a.attr = b - b.attr = a - - gc.collect() - garbagelen = len(gc.garbage) - del a, b - self.assertEqual(gc.collect(), 2) - self.assertEqual(len(gc.garbage), garbagelen) - def test_get_referents(self): alist = [1, 3, 5] got = gc.get_referents(alist) @@ -661,6 +687,7 @@ class GCTests(unittest.TestCase): gc.collect() # this blows up (bad C pointer) when it fails @cpython_only + @requires_subprocess() def test_garbage_at_shutdown(self): import subprocess code = """if 1: @@ -1371,19 +1398,13 @@ class PythonFinalizationTests(unittest.TestCase): code = textwrap.dedent(""" import ast import codecs + from test import support # Small AST tree to keep their AST types alive tree = ast.parse("def f(x, y): return 2*x-y") - x = [tree] - x.append(x) - # Put the cycle somewhere to survive until the last GC collection. - # Codec search functions are only cleared at the end of - # interpreter_clear(). - def search_func(encoding): - return None - search_func.a = x - codecs.register(search_func) + # Store the tree somewhere to survive until the last GC collection + support.late_deletion(tree) """) assert_python_ok("-c", code) diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index eaeb6fb8ff5..0f39b8f4571 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -117,6 +117,9 @@ gdbpy_version, _ = run_gdb("--eval-command=python import sys; print(sys.version_ if not gdbpy_version: raise unittest.SkipTest("gdb not built with embedded python support") +if "major=2" in gdbpy_version: + raise unittest.SkipTest("gdb built with Python 2") + # Verify that "gdb" can load our custom hooks, as OS security settings may # disallow this without a customized .gdbinit. _, gdbpy_errors = run_gdb('--args', sys.executable) @@ -897,15 +900,19 @@ id(42) # to suppress these. See also the comment in DebuggerTests.get_stack_trace def test_pycfunction(self): 'Verify that "py-bt" displays invocations of PyCFunction instances' + # bpo-46600: If the compiler inlines _null_to_none() in meth_varargs() + # (ex: clang -Og), _null_to_none() is the frame #1. Otherwise, + # meth_varargs() is the frame #1. + expected_frame = r'#(1|2)' # Various optimizations multiply the code paths by which these are # called, so test a variety of calling conventions. - for func_name, args, expected_frame in ( - ('meth_varargs', '', 1), - ('meth_varargs_keywords', '', 1), - ('meth_o', '[]', 1), - ('meth_noargs', '', 1), - ('meth_fastcall', '', 1), - ('meth_fastcall_keywords', '', 1), + for func_name, args in ( + ('meth_varargs', ''), + ('meth_varargs_keywords', ''), + ('meth_o', '[]'), + ('meth_noargs', ''), + ('meth_fastcall', ''), + ('meth_fastcall_keywords', ''), ): for obj in ( '_testcapi', @@ -945,10 +952,9 @@ id(42) # defined.' message in stderr. ignore_stderr=True, ) - self.assertIn( - f'#{expected_frame} >> type(i) >>> [s for s in dir(i) if not s.startswith('_')] -['close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw'] +['close', 'gi_code', 'gi_frame', 'gi_running', 'gi_suspended', 'gi_yieldfrom', 'send', 'throw'] >>> from test.support import HAVE_DOCSTRINGS >>> print(i.__next__.__doc__ if HAVE_DOCSTRINGS else 'Implement next(self).') Implement next(self). @@ -2068,6 +2161,12 @@ caught ValueError () >>> g.throw(ValueError("xyz")) # value only caught ValueError (xyz) +>>> import warnings +>>> warnings.filterwarnings("ignore", category=DeprecationWarning) + +# Filter DeprecationWarning: regarding the (type, val, tb) signature of throw(). +# Deprecation warnings are re-enabled below. + >>> g.throw(ValueError, ValueError(1)) # value+matching type caught ValueError (1) @@ -2136,6 +2235,12 @@ Traceback (most recent call last): ... ValueError: 7 +>>> warnings.filters.pop(0) +('ignore', None, , None, 0) + +# Re-enable DeprecationWarning: the (type, val, tb) exception representation is deprecated, +# and may be removed in a future version of Python. + Plain "raise" inside a generator should preserve the traceback (#13188). The traceback should have 3 levels: - g.throw() diff --git a/Lib/test/test_genericalias.py b/Lib/test/test_genericalias.py index 0daaff099a8..9b59d1e3e0a 100644 --- a/Lib/test/test_genericalias.py +++ b/Lib/test/test_genericalias.py @@ -2,6 +2,7 @@ import unittest import pickle +from array import array import copy from collections import ( defaultdict, deque, OrderedDict, Counter, UserDict, UserList @@ -11,8 +12,11 @@ from concurrent.futures import Future from concurrent.futures.thread import _WorkItem from contextlib import AbstractContextManager, AbstractAsyncContextManager from contextvars import ContextVar, Token +from csv import DictReader, DictWriter from dataclasses import Field from functools import partial, partialmethod, cached_property +from graphlib import TopologicalSorter +from logging import LoggerAdapter, StreamHandler from mailbox import Mailbox, _PartialFile try: import ctypes @@ -23,14 +27,24 @@ from filecmp import dircmp from fileinput import FileInput from itertools import chain from http.cookies import Morsel -from multiprocessing.managers import ValueProxy -from multiprocessing.pool import ApplyResult +try: + from multiprocessing.managers import ValueProxy + from multiprocessing.pool import ApplyResult + from multiprocessing.queues import SimpleQueue as MPSimpleQueue + from multiprocessing.queues import Queue as MPQueue + from multiprocessing.queues import JoinableQueue as MPJoinableQueue +except ImportError: + # _multiprocessing module is optional + ValueProxy = None + ApplyResult = None + MPSimpleQueue = None + MPQueue = None + MPJoinableQueue = None try: from multiprocessing.shared_memory import ShareableList except ImportError: # multiprocessing.shared_memory is not available on e.g. Android ShareableList = None -from multiprocessing.queues import SimpleQueue as MPSimpleQueue from os import DirEntry from re import Pattern, Match from types import GenericAlias, MappingProxyType, AsyncGeneratorType @@ -40,12 +54,44 @@ from unittest.case import _AssertRaisesContext from queue import Queue, SimpleQueue from weakref import WeakSet, ReferenceType, ref import typing +from typing import Unpack from typing import TypeVar T = TypeVar('T') K = TypeVar('K') V = TypeVar('V') +_UNPACKED_TUPLES = [ + # Unpacked tuple using `*` + (*tuple[int],)[0], + (*tuple[T],)[0], + (*tuple[int, str],)[0], + (*tuple[int, ...],)[0], + (*tuple[T, ...],)[0], + tuple[*tuple[int, ...]], + tuple[*tuple[T, ...]], + tuple[str, *tuple[int, ...]], + tuple[*tuple[int, ...], str], + tuple[float, *tuple[int, ...], str], + tuple[*tuple[*tuple[int, ...]]], + # Unpacked tuple using `Unpack` + Unpack[tuple[int]], + Unpack[tuple[T]], + Unpack[tuple[int, str]], + Unpack[tuple[int, ...]], + Unpack[tuple[T, ...]], + tuple[Unpack[tuple[int, ...]]], + tuple[Unpack[tuple[T, ...]]], + tuple[str, Unpack[tuple[int, ...]]], + tuple[Unpack[tuple[int, ...]], str], + tuple[float, Unpack[tuple[int, ...]], str], + tuple[Unpack[tuple[Unpack[tuple[int, ...]]]]], + # Unpacked tuple using `*` AND `Unpack` + tuple[Unpack[tuple[*tuple[int, ...]]]], + tuple[*tuple[Unpack[tuple[int, ...]]]], +] + + class BaseTest(unittest.TestCase): """Test basics.""" generic_types = [type, tuple, list, dict, set, frozenset, enumerate, @@ -56,6 +102,7 @@ class BaseTest(unittest.TestCase): OrderedDict, Counter, UserDict, UserList, Pattern, Match, partial, partialmethod, cached_property, + TopologicalSorter, AbstractContextManager, AbstractAsyncContextManager, Awaitable, Coroutine, AsyncIterable, AsyncIterator, @@ -73,17 +120,22 @@ class BaseTest(unittest.TestCase): MappingProxyType, AsyncGeneratorType, DirEntry, chain, + LoggerAdapter, StreamHandler, TemporaryDirectory, SpooledTemporaryFile, Queue, SimpleQueue, _AssertRaisesContext, SplitResult, ParseResult, - ValueProxy, ApplyResult, WeakSet, ReferenceType, ref, - ShareableList, MPSimpleQueue, + ShareableList, Future, _WorkItem, - Morsel] + Morsel, + DictReader, DictWriter, + array] if ctypes is not None: generic_types.extend((ctypes.Array, ctypes.LibraryLoader)) + if ValueProxy is not None: + generic_types.extend((ValueProxy, ApplyResult, + MPSimpleQueue, MPQueue, MPJoinableQueue)) def test_subscriptable(self): for t in self.generic_types: @@ -100,7 +152,7 @@ class BaseTest(unittest.TestCase): for t in int, str, float, Sized, Hashable: tname = t.__name__ with self.subTest(f"Testing {tname}"): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, tname): t[int] def test_instantiate(self): @@ -160,6 +212,12 @@ class BaseTest(unittest.TestCase): self.assertEqual(repr(list[str]), 'list[str]') self.assertEqual(repr(list[()]), 'list[()]') self.assertEqual(repr(tuple[int, ...]), 'tuple[int, ...]') + x1 = tuple[*tuple[int]] + self.assertEqual(repr(x1), 'tuple[*tuple[int]]') + x2 = tuple[*tuple[int, str]] + self.assertEqual(repr(x2), 'tuple[*tuple[int, str]]') + x3 = tuple[*tuple[int, ...]] + self.assertEqual(repr(x3), 'tuple[*tuple[int, ...]]') self.assertTrue(repr(MyList[int]).endswith('.BaseTest.test_repr..MyList[int]')) self.assertEqual(repr(list[str]()), '[]') # instances should keep their normal repr @@ -173,6 +231,7 @@ class BaseTest(unittest.TestCase): def test_parameters(self): from typing import List, Dict, Callable + D0 = dict[str, int] self.assertEqual(D0.__args__, (str, int)) self.assertEqual(D0.__parameters__, ()) @@ -188,6 +247,7 @@ class BaseTest(unittest.TestCase): D2b = dict[T, T] self.assertEqual(D2b.__args__, (T, T)) self.assertEqual(D2b.__parameters__, (T,)) + L0 = list[str] self.assertEqual(L0.__args__, (str,)) self.assertEqual(L0.__parameters__, ()) @@ -210,6 +270,27 @@ class BaseTest(unittest.TestCase): self.assertEqual(L5.__args__, (Callable[[K, V], K],)) self.assertEqual(L5.__parameters__, (K, V)) + T1 = tuple[*tuple[int]] + self.assertEqual( + T1.__args__, + (*tuple[int],), + ) + self.assertEqual(T1.__parameters__, ()) + + T2 = tuple[*tuple[T]] + self.assertEqual( + T2.__args__, + (*tuple[T],), + ) + self.assertEqual(T2.__parameters__, (T,)) + + T4 = tuple[*tuple[int, str]] + self.assertEqual( + T4.__args__, + (*tuple[int, str],), + ) + self.assertEqual(T4.__parameters__, ()) + def test_parameter_chaining(self): from typing import List, Dict, Union, Callable self.assertEqual(list[T][int], list[int]) @@ -240,9 +321,13 @@ class BaseTest(unittest.TestCase): def test_equality(self): self.assertEqual(list[int], list[int]) self.assertEqual(dict[str, int], dict[str, int]) + self.assertEqual((*tuple[int],)[0], (*tuple[int],)[0]) + self.assertEqual(tuple[*tuple[int]], tuple[*tuple[int]]) self.assertNotEqual(dict[str, int], dict[str, str]) self.assertNotEqual(list, list[int]) self.assertNotEqual(list[int], list) + self.assertNotEqual(list[int], tuple[int]) + self.assertNotEqual((*tuple[int],)[0], tuple[int]) def test_isinstance(self): self.assertTrue(isinstance([], list)) @@ -266,17 +351,20 @@ class BaseTest(unittest.TestCase): def test_type_subclass_generic(self): class MyType(type): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, 'MyType'): MyType[int] def test_pickle(self): - alias = GenericAlias(list, T) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - s = pickle.dumps(alias, proto) - loaded = pickle.loads(s) - self.assertEqual(loaded.__origin__, alias.__origin__) - self.assertEqual(loaded.__args__, alias.__args__) - self.assertEqual(loaded.__parameters__, alias.__parameters__) + aliases = [GenericAlias(list, T)] + _UNPACKED_TUPLES + for alias in aliases: + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(alias=alias, proto=proto): + s = pickle.dumps(alias, proto) + loaded = pickle.loads(s) + self.assertEqual(loaded.__origin__, alias.__origin__) + self.assertEqual(loaded.__args__, alias.__args__) + self.assertEqual(loaded.__parameters__, alias.__parameters__) + self.assertEqual(type(loaded), type(alias)) def test_copy(self): class X(list): @@ -285,16 +373,27 @@ class BaseTest(unittest.TestCase): def __deepcopy__(self, memo): return self - for origin in list, deque, X: - alias = GenericAlias(origin, T) - copied = copy.copy(alias) - self.assertEqual(copied.__origin__, alias.__origin__) - self.assertEqual(copied.__args__, alias.__args__) - self.assertEqual(copied.__parameters__, alias.__parameters__) - copied = copy.deepcopy(alias) - self.assertEqual(copied.__origin__, alias.__origin__) - self.assertEqual(copied.__args__, alias.__args__) - self.assertEqual(copied.__parameters__, alias.__parameters__) + aliases = [ + GenericAlias(list, T), + GenericAlias(deque, T), + GenericAlias(X, T) + ] + _UNPACKED_TUPLES + for alias in aliases: + with self.subTest(alias=alias): + copied = copy.copy(alias) + self.assertEqual(copied.__origin__, alias.__origin__) + self.assertEqual(copied.__args__, alias.__args__) + self.assertEqual(copied.__parameters__, alias.__parameters__) + copied = copy.deepcopy(alias) + self.assertEqual(copied.__origin__, alias.__origin__) + self.assertEqual(copied.__args__, alias.__args__) + self.assertEqual(copied.__parameters__, alias.__parameters__) + + def test_unpack(self): + alias = tuple[str, ...] + self.assertIs(alias.__unpacked__, False) + unpacked = (*alias,)[0] + self.assertIs(unpacked.__unpacked__, True) def test_union(self): a = typing.Union[list[int], list[str]] @@ -337,6 +436,44 @@ class BaseTest(unittest.TestCase): with self.assertRaises(TypeError): Bad(list, int, bad=int) + def test_iter_creates_starred_tuple(self): + t = tuple[int, str] + iter_t = iter(t) + x = next(iter_t) + self.assertEqual(repr(x), '*tuple[int, str]') + + def test_calling_next_twice_raises_stopiteration(self): + t = tuple[int, str] + iter_t = iter(t) + next(iter_t) + with self.assertRaises(StopIteration): + next(iter_t) + + def test_del_iter(self): + t = tuple[int, str] + iter_x = iter(t) + del iter_x + + +class TypeIterationTests(unittest.TestCase): + _UNITERABLE_TYPES = (list, tuple) + + def test_cannot_iterate(self): + for test_type in self._UNITERABLE_TYPES: + with self.subTest(type=test_type): + expected_error_regex = "object is not iterable" + with self.assertRaisesRegex(TypeError, expected_error_regex): + iter(test_type) + with self.assertRaisesRegex(TypeError, expected_error_regex): + list(test_type) + with self.assertRaisesRegex(TypeError, expected_error_regex): + for _ in test_type: + pass + + def test_is_not_instance_of_iterable(self): + for type_to_test in self._UNITERABLE_TYPES: + self.assertNotIsInstance(type_to_test, Iterable) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_genericclass.py b/Lib/test/test_genericclass.py index 27420d4f2ba..d8bb37f69e1 100644 --- a/Lib/test/test_genericclass.py +++ b/Lib/test/test_genericclass.py @@ -220,6 +220,7 @@ class TestClassGetitem(unittest.TestCase): return None with self.assertRaises(TypeError): C_too_few[int] + class C_too_many: def __class_getitem__(cls, one, two): return None @@ -232,16 +233,23 @@ class TestClassGetitem(unittest.TestCase): return None with self.assertRaises(TypeError): C()[int] + class E: ... e = E() e.__class_getitem__ = lambda cls, item: 'This will not work' with self.assertRaises(TypeError): e[int] + class C_not_callable: __class_getitem__ = "Surprise!" with self.assertRaises(TypeError): C_not_callable[int] + class C_is_none(tuple): + __class_getitem__ = None + with self.assertRaisesRegex(TypeError, "C_is_none"): + C_is_none[int] + def test_class_getitem_metaclass(self): class Meta(type): def __class_getitem__(cls, item): diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index 1ff7f75ad3e..489044f8090 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -7,6 +7,7 @@ import os import sys import unittest import warnings +from test.support import is_emscripten from test.support import os_helper from test.support import warnings_helper from test.support.script_helper import assert_python_ok @@ -154,6 +155,7 @@ class GenericTest: self.assertIs(self.pathmodule.lexists(bfilename + b'\x00'), False) @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") + @unittest.skipIf(is_emscripten, "Emscripten pipe fds have no stat") def test_exists_fd(self): r, w = os.pipe() try: @@ -246,6 +248,7 @@ class GenericTest: def test_samefile_on_symlink(self): self._test_samefile_on_link_func(os.symlink) + @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') def test_samefile_on_link(self): try: self._test_samefile_on_link_func(os.link) @@ -288,6 +291,7 @@ class GenericTest: def test_samestat_on_symlink(self): self._test_samestat_on_link_func(os.symlink) + @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') def test_samestat_on_link(self): try: self._test_samestat_on_link_func(os.link) @@ -476,11 +480,11 @@ class CommonTest(GenericTest): def test_nonascii_abspath(self): if (os_helper.TESTFN_UNDECODABLE - # Mac OS X denies the creation of a directory with an invalid - # UTF-8 name. Windows allows creating a directory with an + # macOS and Emscripten deny the creation of a directory with an + # invalid UTF-8 name. Windows allows creating a directory with an # arbitrary bytes name, but fails to enter this directory # (when the bytes name is used). - and sys.platform not in ('win32', 'darwin')): + and sys.platform not in ('win32', 'darwin', 'emscripten', 'wasi')): name = os_helper.TESTFN_UNDECODABLE elif os_helper.TESTFN_NONASCII: name = os_helper.TESTFN_NONASCII diff --git a/Lib/test/test_getopt.py b/Lib/test/test_getopt.py index 9261276ebb9..c96a33b77fe 100644 --- a/Lib/test/test_getopt.py +++ b/Lib/test/test_getopt.py @@ -11,14 +11,10 @@ sentinel = object() class GetoptTests(unittest.TestCase): def setUp(self): - self.env = EnvironmentVarGuard() + self.env = self.enterContext(EnvironmentVarGuard()) if "POSIXLY_CORRECT" in self.env: del self.env["POSIXLY_CORRECT"] - def tearDown(self): - self.env.__exit__() - del self.env - def assertError(self, *args, **kwargs): self.assertRaises(getopt.GetoptError, *args, **kwargs) @@ -87,7 +83,7 @@ class GetoptTests(unittest.TestCase): # Much like the preceding, except with a non-alpha character ("-") in # option name that precedes "="; failed in - # http://python.org/sf/126863 + # https://bugs.python.org/issue126863 opts, args = getopt.do_longs([], 'foo=42', ['foo-bar', 'foo=',], []) self.assertEqual(opts, [('--foo', '42')]) self.assertEqual(args, []) diff --git a/Lib/test/test_getpass.py b/Lib/test/test_getpass.py index 3452e46213a..98ecec94336 100644 --- a/Lib/test/test_getpass.py +++ b/Lib/test/test_getpass.py @@ -28,6 +28,9 @@ class GetpassGetuserTest(unittest.TestCase): getpass.getuser() except ImportError: # in case there's no pwd module pass + except KeyError: + # current user has no pwd entry + pass self.assertEqual( environ.get.call_args_list, [mock.call(x) for x in ('LOGNAME', 'USER', 'LNAME', 'USERNAME')]) diff --git a/Lib/test/test_getpath.py b/Lib/test/test_getpath.py new file mode 100644 index 00000000000..b9cbe1d92c4 --- /dev/null +++ b/Lib/test/test_getpath.py @@ -0,0 +1,1212 @@ +import copy +import ntpath +import pathlib +import posixpath +import unittest + +from test.support import verbose + +try: + # If we are in a source tree, use the original source file for tests + SOURCE = (pathlib.Path(__file__).absolute().parent.parent.parent / "Modules/getpath.py").read_bytes() +except FileNotFoundError: + # Try from _testcapimodule instead + from _testinternalcapi import get_getpath_codeobject + SOURCE = get_getpath_codeobject() + + +class MockGetPathTests(unittest.TestCase): + def __init__(self, *a, **kw): + super().__init__(*a, **kw) + self.maxDiff = None + + def test_normal_win32(self): + "Test a 'standard' install layout on Windows." + ns = MockNTNamespace( + argv0=r"C:\Python\python.exe", + real_executable=r"C:\Python\python.exe", + ) + ns.add_known_xfile(r"C:\Python\python.exe") + ns.add_known_file(r"C:\Python\Lib\os.py") + ns.add_known_dir(r"C:\Python\DLLs") + expected = dict( + executable=r"C:\Python\python.exe", + base_executable=r"C:\Python\python.exe", + prefix=r"C:\Python", + exec_prefix=r"C:\Python", + module_search_paths_set=1, + module_search_paths=[ + r"C:\Python\python98.zip", + r"C:\Python\DLLs", + r"C:\Python\Lib", + r"C:\Python", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_buildtree_win32(self): + "Test an in-build-tree layout on Windows." + ns = MockNTNamespace( + argv0=r"C:\CPython\PCbuild\amd64\python.exe", + real_executable=r"C:\CPython\PCbuild\amd64\python.exe", + ) + ns.add_known_xfile(r"C:\CPython\PCbuild\amd64\python.exe") + ns.add_known_file(r"C:\CPython\Lib\os.py") + ns.add_known_file(r"C:\CPython\PCbuild\amd64\pybuilddir.txt", [""]) + expected = dict( + executable=r"C:\CPython\PCbuild\amd64\python.exe", + base_executable=r"C:\CPython\PCbuild\amd64\python.exe", + prefix=r"C:\CPython", + exec_prefix=r"C:\CPython", + build_prefix=r"C:\CPython", + _is_python_build=1, + module_search_paths_set=1, + module_search_paths=[ + r"C:\CPython\PCbuild\amd64\python98.zip", + r"C:\CPython\PCbuild\amd64", + r"C:\CPython\Lib", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_venv_win32(self): + """Test a venv layout on Windows. + + This layout is discovered by the presence of %__PYVENV_LAUNCHER__%, + specifying the original launcher executable. site.py is responsible + for updating prefix and exec_prefix. + """ + ns = MockNTNamespace( + argv0=r"C:\Python\python.exe", + ENV___PYVENV_LAUNCHER__=r"C:\venv\Scripts\python.exe", + real_executable=r"C:\Python\python.exe", + ) + ns.add_known_xfile(r"C:\Python\python.exe") + ns.add_known_xfile(r"C:\venv\Scripts\python.exe") + ns.add_known_file(r"C:\Python\Lib\os.py") + ns.add_known_dir(r"C:\Python\DLLs") + ns.add_known_file(r"C:\venv\pyvenv.cfg", [ + r"home = C:\Python" + ]) + expected = dict( + executable=r"C:\venv\Scripts\python.exe", + prefix=r"C:\Python", + exec_prefix=r"C:\Python", + base_executable=r"C:\Python\python.exe", + base_prefix=r"C:\Python", + base_exec_prefix=r"C:\Python", + module_search_paths_set=1, + module_search_paths=[ + r"C:\Python\python98.zip", + r"C:\Python\DLLs", + r"C:\Python\Lib", + r"C:\Python", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_registry_win32(self): + """Test registry lookup on Windows. + + On Windows there are registry entries that are intended for other + applications to register search paths. + """ + hkey = rf"HKLM\Software\Python\PythonCore\9.8-XY\PythonPath" + winreg = MockWinreg({ + hkey: None, + f"{hkey}\\Path1": "path1-dir", + f"{hkey}\\Path1\\Subdir": "not-subdirs", + }) + ns = MockNTNamespace( + argv0=r"C:\Python\python.exe", + real_executable=r"C:\Python\python.exe", + winreg=winreg, + ) + ns.add_known_xfile(r"C:\Python\python.exe") + ns.add_known_file(r"C:\Python\Lib\os.py") + ns.add_known_dir(r"C:\Python\DLLs") + expected = dict( + module_search_paths_set=1, + module_search_paths=[ + r"C:\Python\python98.zip", + "path1-dir", + # should not contain not-subdirs + r"C:\Python\DLLs", + r"C:\Python\Lib", + r"C:\Python", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + ns["config"]["use_environment"] = 0 + ns["config"]["module_search_paths_set"] = 0 + ns["config"]["module_search_paths"] = None + expected = dict( + module_search_paths_set=1, + module_search_paths=[ + r"C:\Python\python98.zip", + r"C:\Python\DLLs", + r"C:\Python\Lib", + r"C:\Python", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_symlink_normal_win32(self): + "Test a 'standard' install layout via symlink on Windows." + ns = MockNTNamespace( + argv0=r"C:\LinkedFrom\python.exe", + real_executable=r"C:\Python\python.exe", + ) + ns.add_known_xfile(r"C:\LinkedFrom\python.exe") + ns.add_known_xfile(r"C:\Python\python.exe") + ns.add_known_link(r"C:\LinkedFrom\python.exe", r"C:\Python\python.exe") + ns.add_known_file(r"C:\Python\Lib\os.py") + ns.add_known_dir(r"C:\Python\DLLs") + expected = dict( + executable=r"C:\LinkedFrom\python.exe", + base_executable=r"C:\LinkedFrom\python.exe", + prefix=r"C:\Python", + exec_prefix=r"C:\Python", + module_search_paths_set=1, + module_search_paths=[ + r"C:\Python\python98.zip", + r"C:\Python\DLLs", + r"C:\Python\Lib", + r"C:\Python", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_symlink_buildtree_win32(self): + "Test an in-build-tree layout via symlink on Windows." + ns = MockNTNamespace( + argv0=r"C:\LinkedFrom\python.exe", + real_executable=r"C:\CPython\PCbuild\amd64\python.exe", + ) + ns.add_known_xfile(r"C:\LinkedFrom\python.exe") + ns.add_known_xfile(r"C:\CPython\PCbuild\amd64\python.exe") + ns.add_known_link(r"C:\LinkedFrom\python.exe", r"C:\CPython\PCbuild\amd64\python.exe") + ns.add_known_file(r"C:\CPython\Lib\os.py") + ns.add_known_file(r"C:\CPython\PCbuild\amd64\pybuilddir.txt", [""]) + expected = dict( + executable=r"C:\LinkedFrom\python.exe", + base_executable=r"C:\LinkedFrom\python.exe", + prefix=r"C:\CPython", + exec_prefix=r"C:\CPython", + build_prefix=r"C:\CPython", + _is_python_build=1, + module_search_paths_set=1, + module_search_paths=[ + r"C:\CPython\PCbuild\amd64\python98.zip", + r"C:\CPython\PCbuild\amd64", + r"C:\CPython\Lib", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_buildtree_pythonhome_win32(self): + "Test an out-of-build-tree layout on Windows with PYTHONHOME override." + ns = MockNTNamespace( + argv0=r"C:\Out\python.exe", + real_executable=r"C:\Out\python.exe", + ENV_PYTHONHOME=r"C:\CPython", + ) + ns.add_known_xfile(r"C:\Out\python.exe") + ns.add_known_file(r"C:\CPython\Lib\os.py") + ns.add_known_file(r"C:\Out\pybuilddir.txt", [""]) + expected = dict( + executable=r"C:\Out\python.exe", + base_executable=r"C:\Out\python.exe", + prefix=r"C:\CPython", + exec_prefix=r"C:\CPython", + # This build_prefix is a miscalculation, because we have + # moved the output direction out of the prefix. + # Specify PYTHONHOME to get the correct prefix/exec_prefix + build_prefix="C:\\", + _is_python_build=1, + module_search_paths_set=1, + module_search_paths=[ + r"C:\Out\python98.zip", + r"C:\Out", + r"C:\CPython\Lib", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_no_dlls_win32(self): + "Test a layout on Windows with no DLLs directory." + ns = MockNTNamespace( + argv0=r"C:\Python\python.exe", + real_executable=r"C:\Python\python.exe", + ) + ns.add_known_xfile(r"C:\Python\python.exe") + ns.add_known_file(r"C:\Python\Lib\os.py") + expected = dict( + executable=r"C:\Python\python.exe", + base_executable=r"C:\Python\python.exe", + prefix=r"C:\Python", + exec_prefix=r"C:\Python", + module_search_paths_set=1, + module_search_paths=[ + r"C:\Python\python98.zip", + r"C:\Python", + r"C:\Python\Lib", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_normal_posix(self): + "Test a 'standard' install layout on *nix" + ns = MockPosixNamespace( + PREFIX="/usr", + argv0="python", + ENV_PATH="/usr/bin", + ) + ns.add_known_xfile("/usr/bin/python") + ns.add_known_file("/usr/lib/python9.8/os.py") + ns.add_known_dir("/usr/lib/python9.8/lib-dynload") + expected = dict( + executable="/usr/bin/python", + base_executable="/usr/bin/python", + prefix="/usr", + exec_prefix="/usr", + module_search_paths_set=1, + module_search_paths=[ + "/usr/lib/python98.zip", + "/usr/lib/python9.8", + "/usr/lib/python9.8/lib-dynload", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_buildpath_posix(self): + """Test an in-build-tree layout on POSIX. + + This layout is discovered from the presence of pybuilddir.txt, which + contains the relative path from the executable's directory to the + platstdlib path. + """ + ns = MockPosixNamespace( + argv0=r"/home/cpython/python", + PREFIX="/usr/local", + ) + ns.add_known_xfile("/home/cpython/python") + ns.add_known_xfile("/usr/local/bin/python") + ns.add_known_file("/home/cpython/pybuilddir.txt", ["build/lib.linux-x86_64-9.8"]) + ns.add_known_file("/home/cpython/Lib/os.py") + ns.add_known_dir("/home/cpython/lib-dynload") + expected = dict( + executable="/home/cpython/python", + prefix="/usr/local", + exec_prefix="/usr/local", + base_executable="/home/cpython/python", + build_prefix="/home/cpython", + _is_python_build=1, + module_search_paths_set=1, + module_search_paths=[ + "/usr/local/lib/python98.zip", + "/home/cpython/Lib", + "/home/cpython/build/lib.linux-x86_64-9.8", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_venv_posix(self): + "Test a venv layout on *nix." + ns = MockPosixNamespace( + argv0="python", + PREFIX="/usr", + ENV_PATH="/venv/bin:/usr/bin", + ) + ns.add_known_xfile("/usr/bin/python") + ns.add_known_xfile("/venv/bin/python") + ns.add_known_file("/usr/lib/python9.8/os.py") + ns.add_known_dir("/usr/lib/python9.8/lib-dynload") + ns.add_known_file("/venv/pyvenv.cfg", [ + r"home = /usr/bin" + ]) + expected = dict( + executable="/venv/bin/python", + prefix="/usr", + exec_prefix="/usr", + base_executable="/usr/bin/python", + base_prefix="/usr", + base_exec_prefix="/usr", + module_search_paths_set=1, + module_search_paths=[ + "/usr/lib/python98.zip", + "/usr/lib/python9.8", + "/usr/lib/python9.8/lib-dynload", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_venv_changed_name_posix(self): + "Test a venv layout on *nix." + ns = MockPosixNamespace( + argv0="python", + PREFIX="/usr", + ENV_PATH="/venv/bin:/usr/bin", + ) + ns.add_known_xfile("/usr/bin/python3") + ns.add_known_xfile("/venv/bin/python") + ns.add_known_link("/venv/bin/python", "/usr/bin/python3") + ns.add_known_file("/usr/lib/python9.8/os.py") + ns.add_known_dir("/usr/lib/python9.8/lib-dynload") + ns.add_known_file("/venv/pyvenv.cfg", [ + r"home = /usr/bin" + ]) + expected = dict( + executable="/venv/bin/python", + prefix="/usr", + exec_prefix="/usr", + base_executable="/usr/bin/python3", + base_prefix="/usr", + base_exec_prefix="/usr", + module_search_paths_set=1, + module_search_paths=[ + "/usr/lib/python98.zip", + "/usr/lib/python9.8", + "/usr/lib/python9.8/lib-dynload", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_venv_non_installed_zip_path_posix(self): + "Test a venv created from non-installed python has correct zip path.""" + ns = MockPosixNamespace( + argv0="/venv/bin/python", + PREFIX="/usr", + ENV_PATH="/venv/bin:/usr/bin", + ) + ns.add_known_xfile("/path/to/non-installed/bin/python") + ns.add_known_xfile("/venv/bin/python") + ns.add_known_link("/venv/bin/python", + "/path/to/non-installed/bin/python") + ns.add_known_file("/path/to/non-installed/lib/python9.8/os.py") + ns.add_known_dir("/path/to/non-installed/lib/python9.8/lib-dynload") + ns.add_known_file("/venv/pyvenv.cfg", [ + r"home = /path/to/non-installed" + ]) + expected = dict( + executable="/venv/bin/python", + prefix="/path/to/non-installed", + exec_prefix="/path/to/non-installed", + base_executable="/path/to/non-installed/bin/python", + base_prefix="/path/to/non-installed", + base_exec_prefix="/path/to/non-installed", + module_search_paths_set=1, + module_search_paths=[ + "/path/to/non-installed/lib/python98.zip", + "/path/to/non-installed/lib/python9.8", + "/path/to/non-installed/lib/python9.8/lib-dynload", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_venv_changed_name_copy_posix(self): + "Test a venv --copies layout on *nix that lacks a distributed 'python'" + ns = MockPosixNamespace( + argv0="python", + PREFIX="/usr", + ENV_PATH="/venv/bin:/usr/bin", + ) + ns.add_known_xfile("/usr/bin/python9") + ns.add_known_xfile("/venv/bin/python") + ns.add_known_file("/usr/lib/python9.8/os.py") + ns.add_known_dir("/usr/lib/python9.8/lib-dynload") + ns.add_known_file("/venv/pyvenv.cfg", [ + r"home = /usr/bin" + ]) + expected = dict( + executable="/venv/bin/python", + prefix="/usr", + exec_prefix="/usr", + base_executable="/usr/bin/python9", + base_prefix="/usr", + base_exec_prefix="/usr", + module_search_paths_set=1, + module_search_paths=[ + "/usr/lib/python98.zip", + "/usr/lib/python9.8", + "/usr/lib/python9.8/lib-dynload", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_symlink_normal_posix(self): + "Test a 'standard' install layout via symlink on *nix" + ns = MockPosixNamespace( + PREFIX="/usr", + argv0="/linkfrom/python", + ) + ns.add_known_xfile("/linkfrom/python") + ns.add_known_xfile("/usr/bin/python") + ns.add_known_link("/linkfrom/python", "/usr/bin/python") + ns.add_known_file("/usr/lib/python9.8/os.py") + ns.add_known_dir("/usr/lib/python9.8/lib-dynload") + expected = dict( + executable="/linkfrom/python", + base_executable="/linkfrom/python", + prefix="/usr", + exec_prefix="/usr", + module_search_paths_set=1, + module_search_paths=[ + "/usr/lib/python98.zip", + "/usr/lib/python9.8", + "/usr/lib/python9.8/lib-dynload", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_symlink_buildpath_posix(self): + """Test an in-build-tree layout on POSIX. + + This layout is discovered from the presence of pybuilddir.txt, which + contains the relative path from the executable's directory to the + platstdlib path. + """ + ns = MockPosixNamespace( + argv0=r"/linkfrom/python", + PREFIX="/usr/local", + ) + ns.add_known_xfile("/linkfrom/python") + ns.add_known_xfile("/home/cpython/python") + ns.add_known_link("/linkfrom/python", "/home/cpython/python") + ns.add_known_xfile("/usr/local/bin/python") + ns.add_known_file("/home/cpython/pybuilddir.txt", ["build/lib.linux-x86_64-9.8"]) + ns.add_known_file("/home/cpython/Lib/os.py") + ns.add_known_dir("/home/cpython/lib-dynload") + expected = dict( + executable="/linkfrom/python", + prefix="/usr/local", + exec_prefix="/usr/local", + base_executable="/linkfrom/python", + build_prefix="/home/cpython", + _is_python_build=1, + module_search_paths_set=1, + module_search_paths=[ + "/usr/local/lib/python98.zip", + "/home/cpython/Lib", + "/home/cpython/build/lib.linux-x86_64-9.8", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_custom_platlibdir_posix(self): + "Test an install with custom platlibdir on *nix" + ns = MockPosixNamespace( + PREFIX="/usr", + argv0="/linkfrom/python", + PLATLIBDIR="lib64", + ) + ns.add_known_xfile("/usr/bin/python") + ns.add_known_file("/usr/lib64/python9.8/os.py") + ns.add_known_dir("/usr/lib64/python9.8/lib-dynload") + expected = dict( + executable="/linkfrom/python", + base_executable="/linkfrom/python", + prefix="/usr", + exec_prefix="/usr", + module_search_paths_set=1, + module_search_paths=[ + "/usr/lib64/python98.zip", + "/usr/lib64/python9.8", + "/usr/lib64/python9.8/lib-dynload", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_framework_macos(self): + """ Test framework layout on macOS + + This layout is primarily detected using a compile-time option + (WITH_NEXT_FRAMEWORK). + """ + ns = MockPosixNamespace( + os_name="darwin", + argv0="/Library/Frameworks/Python.framework/Versions/9.8/Resources/Python.app/Contents/MacOS/Python", + WITH_NEXT_FRAMEWORK=1, + PREFIX="/Library/Frameworks/Python.framework/Versions/9.8", + EXEC_PREFIX="/Library/Frameworks/Python.framework/Versions/9.8", + ENV___PYVENV_LAUNCHER__="/Library/Frameworks/Python.framework/Versions/9.8/bin/python9.8", + real_executable="/Library/Frameworks/Python.framework/Versions/9.8/Resources/Python.app/Contents/MacOS/Python", + library="/Library/Frameworks/Python.framework/Versions/9.8/Python", + ) + ns.add_known_xfile("/Library/Frameworks/Python.framework/Versions/9.8/Resources/Python.app/Contents/MacOS/Python") + ns.add_known_xfile("/Library/Frameworks/Python.framework/Versions/9.8/bin/python9.8") + ns.add_known_dir("/Library/Frameworks/Python.framework/Versions/9.8/lib/python9.8/lib-dynload") + ns.add_known_file("/Library/Frameworks/Python.framework/Versions/9.8/lib/python9.8/os.py") + + # This is definitely not the stdlib (see discusion in bpo-46890) + #ns.add_known_file("/Library/Frameworks/lib/python98.zip") + + expected = dict( + executable="/Library/Frameworks/Python.framework/Versions/9.8/bin/python9.8", + prefix="/Library/Frameworks/Python.framework/Versions/9.8", + exec_prefix="/Library/Frameworks/Python.framework/Versions/9.8", + base_executable="/Library/Frameworks/Python.framework/Versions/9.8/bin/python9.8", + base_prefix="/Library/Frameworks/Python.framework/Versions/9.8", + base_exec_prefix="/Library/Frameworks/Python.framework/Versions/9.8", + module_search_paths_set=1, + module_search_paths=[ + "/Library/Frameworks/Python.framework/Versions/9.8/lib/python98.zip", + "/Library/Frameworks/Python.framework/Versions/9.8/lib/python9.8", + "/Library/Frameworks/Python.framework/Versions/9.8/lib/python9.8/lib-dynload", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_alt_framework_macos(self): + """ Test framework layout on macOS with alternate framework name + + ``--with-framework-name=DebugPython`` + + This layout is primarily detected using a compile-time option + (WITH_NEXT_FRAMEWORK). + """ + ns = MockPosixNamespace( + argv0="/Library/Frameworks/DebugPython.framework/Versions/9.8/Resources/Python.app/Contents/MacOS/DebugPython", + os_name="darwin", + WITH_NEXT_FRAMEWORK=1, + PREFIX="/Library/Frameworks/DebugPython.framework/Versions/9.8", + EXEC_PREFIX="/Library/Frameworks/DebugPython.framework/Versions/9.8", + ENV___PYVENV_LAUNCHER__="/Library/Frameworks/DebugPython.framework/Versions/9.8/bin/python9.8", + real_executable="/Library/Frameworks/DebugPython.framework/Versions/9.8/Resources/Python.app/Contents/MacOS/DebugPython", + library="/Library/Frameworks/DebugPython.framework/Versions/9.8/DebugPython", + PYTHONPATH=None, + ENV_PYTHONHOME=None, + ENV_PYTHONEXECUTABLE=None, + executable_dir=None, + py_setpath=None, + ) + ns.add_known_xfile("/Library/Frameworks/DebugPython.framework/Versions/9.8/Resources/Python.app/Contents/MacOS/DebugPython") + ns.add_known_xfile("/Library/Frameworks/DebugPython.framework/Versions/9.8/bin/python9.8") + ns.add_known_dir("/Library/Frameworks/DebugPython.framework/Versions/9.8/lib/python9.8/lib-dynload") + ns.add_known_xfile("/Library/Frameworks/DebugPython.framework/Versions/9.8/lib/python9.8/os.py") + + # This is definitely not the stdlib (see discusion in bpo-46890) + #ns.add_known_xfile("/Library/lib/python98.zip") + expected = dict( + executable="/Library/Frameworks/DebugPython.framework/Versions/9.8/bin/python9.8", + prefix="/Library/Frameworks/DebugPython.framework/Versions/9.8", + exec_prefix="/Library/Frameworks/DebugPython.framework/Versions/9.8", + base_executable="/Library/Frameworks/DebugPython.framework/Versions/9.8/bin/python9.8", + base_prefix="/Library/Frameworks/DebugPython.framework/Versions/9.8", + base_exec_prefix="/Library/Frameworks/DebugPython.framework/Versions/9.8", + module_search_paths_set=1, + module_search_paths=[ + "/Library/Frameworks/DebugPython.framework/Versions/9.8/lib/python98.zip", + "/Library/Frameworks/DebugPython.framework/Versions/9.8/lib/python9.8", + "/Library/Frameworks/DebugPython.framework/Versions/9.8/lib/python9.8/lib-dynload", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_venv_framework_macos(self): + """Test a venv layout on macOS using a framework build + """ + venv_path = "/tmp/workdir/venv" + ns = MockPosixNamespace( + os_name="darwin", + argv0="/Library/Frameworks/Python.framework/Versions/9.8/Resources/Python.app/Contents/MacOS/Python", + WITH_NEXT_FRAMEWORK=1, + PREFIX="/Library/Frameworks/Python.framework/Versions/9.8", + EXEC_PREFIX="/Library/Frameworks/Python.framework/Versions/9.8", + ENV___PYVENV_LAUNCHER__=f"{venv_path}/bin/python", + real_executable="/Library/Frameworks/Python.framework/Versions/9.8/Resources/Python.app/Contents/MacOS/Python", + library="/Library/Frameworks/Python.framework/Versions/9.8/Python", + ) + ns.add_known_dir(venv_path) + ns.add_known_dir(f"{venv_path}/bin") + ns.add_known_dir(f"{venv_path}/lib") + ns.add_known_dir(f"{venv_path}/lib/python9.8") + ns.add_known_xfile(f"{venv_path}/bin/python") + ns.add_known_xfile("/Library/Frameworks/Python.framework/Versions/9.8/Resources/Python.app/Contents/MacOS/Python") + ns.add_known_xfile("/Library/Frameworks/Python.framework/Versions/9.8/bin/python9.8") + ns.add_known_dir("/Library/Frameworks/Python.framework/Versions/9.8/lib/python9.8/lib-dynload") + ns.add_known_xfile("/Library/Frameworks/Python.framework/Versions/9.8/lib/python9.8/os.py") + ns.add_known_file(f"{venv_path}/pyvenv.cfg", [ + "home = /Library/Frameworks/Python.framework/Versions/9.8/bin" + ]) + expected = dict( + executable=f"{venv_path}/bin/python", + prefix="/Library/Frameworks/Python.framework/Versions/9.8", + exec_prefix="/Library/Frameworks/Python.framework/Versions/9.8", + base_executable="/Library/Frameworks/Python.framework/Versions/9.8/bin/python9.8", + base_prefix="/Library/Frameworks/Python.framework/Versions/9.8", + base_exec_prefix="/Library/Frameworks/Python.framework/Versions/9.8", + module_search_paths_set=1, + module_search_paths=[ + "/Library/Frameworks/Python.framework/Versions/9.8/lib/python98.zip", + "/Library/Frameworks/Python.framework/Versions/9.8/lib/python9.8", + "/Library/Frameworks/Python.framework/Versions/9.8/lib/python9.8/lib-dynload", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_venv_alt_framework_macos(self): + """Test a venv layout on macOS using a framework build + + ``--with-framework-name=DebugPython`` + """ + venv_path = "/tmp/workdir/venv" + ns = MockPosixNamespace( + os_name="darwin", + argv0="/Library/Frameworks/DebugPython.framework/Versions/9.8/Resources/Python.app/Contents/MacOS/DebugPython", + WITH_NEXT_FRAMEWORK=1, + PREFIX="/Library/Frameworks/DebugPython.framework/Versions/9.8", + EXEC_PREFIX="/Library/Frameworks/DebugPython.framework/Versions/9.8", + ENV___PYVENV_LAUNCHER__=f"{venv_path}/bin/python", + real_executable="/Library/Frameworks/DebugPython.framework/Versions/9.8/Resources/Python.app/Contents/MacOS/DebugPython", + library="/Library/Frameworks/DebugPython.framework/Versions/9.8/DebugPython", + ) + ns.add_known_dir(venv_path) + ns.add_known_dir(f"{venv_path}/bin") + ns.add_known_dir(f"{venv_path}/lib") + ns.add_known_dir(f"{venv_path}/lib/python9.8") + ns.add_known_xfile(f"{venv_path}/bin/python") + ns.add_known_xfile("/Library/Frameworks/DebugPython.framework/Versions/9.8/Resources/Python.app/Contents/MacOS/DebugPython") + ns.add_known_xfile("/Library/Frameworks/DebugPython.framework/Versions/9.8/bin/python9.8") + ns.add_known_dir("/Library/Frameworks/DebugPython.framework/Versions/9.8/lib/python9.8/lib-dynload") + ns.add_known_xfile("/Library/Frameworks/DebugPython.framework/Versions/9.8/lib/python9.8/os.py") + ns.add_known_file(f"{venv_path}/pyvenv.cfg", [ + "home = /Library/Frameworks/DebugPython.framework/Versions/9.8/bin" + ]) + expected = dict( + executable=f"{venv_path}/bin/python", + prefix="/Library/Frameworks/DebugPython.framework/Versions/9.8", + exec_prefix="/Library/Frameworks/DebugPython.framework/Versions/9.8", + base_executable="/Library/Frameworks/DebugPython.framework/Versions/9.8/bin/python9.8", + base_prefix="/Library/Frameworks/DebugPython.framework/Versions/9.8", + base_exec_prefix="/Library/Frameworks/DebugPython.framework/Versions/9.8", + module_search_paths_set=1, + module_search_paths=[ + "/Library/Frameworks/DebugPython.framework/Versions/9.8/lib/python98.zip", + "/Library/Frameworks/DebugPython.framework/Versions/9.8/lib/python9.8", + "/Library/Frameworks/DebugPython.framework/Versions/9.8/lib/python9.8/lib-dynload", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_venv_macos(self): + """Test a venv layout on macOS. + + This layout is discovered when 'executable' and 'real_executable' match, + but $__PYVENV_LAUNCHER__ has been set to the original process. + """ + ns = MockPosixNamespace( + os_name="darwin", + argv0="/usr/bin/python", + PREFIX="/usr", + ENV___PYVENV_LAUNCHER__="/framework/Python9.8/python", + real_executable="/usr/bin/python", + ) + ns.add_known_xfile("/usr/bin/python") + ns.add_known_xfile("/framework/Python9.8/python") + ns.add_known_file("/usr/lib/python9.8/os.py") + ns.add_known_dir("/usr/lib/python9.8/lib-dynload") + ns.add_known_file("/framework/Python9.8/pyvenv.cfg", [ + "home = /usr/bin" + ]) + expected = dict( + executable="/framework/Python9.8/python", + prefix="/usr", + exec_prefix="/usr", + base_executable="/usr/bin/python", + base_prefix="/usr", + base_exec_prefix="/usr", + module_search_paths_set=1, + module_search_paths=[ + "/usr/lib/python98.zip", + "/usr/lib/python9.8", + "/usr/lib/python9.8/lib-dynload", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_symlink_normal_macos(self): + "Test a 'standard' install layout via symlink on macOS" + ns = MockPosixNamespace( + os_name="darwin", + PREFIX="/usr", + argv0="python", + ENV_PATH="/linkfrom:/usr/bin", + # real_executable on macOS matches the invocation path + real_executable="/linkfrom/python", + ) + ns.add_known_xfile("/linkfrom/python") + ns.add_known_xfile("/usr/bin/python") + ns.add_known_link("/linkfrom/python", "/usr/bin/python") + ns.add_known_file("/usr/lib/python9.8/os.py") + ns.add_known_dir("/usr/lib/python9.8/lib-dynload") + expected = dict( + executable="/linkfrom/python", + base_executable="/linkfrom/python", + prefix="/usr", + exec_prefix="/usr", + module_search_paths_set=1, + module_search_paths=[ + "/usr/lib/python98.zip", + "/usr/lib/python9.8", + "/usr/lib/python9.8/lib-dynload", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + def test_symlink_buildpath_macos(self): + """Test an in-build-tree layout via symlink on macOS. + + This layout is discovered from the presence of pybuilddir.txt, which + contains the relative path from the executable's directory to the + platstdlib path. + """ + ns = MockPosixNamespace( + os_name="darwin", + argv0=r"python", + ENV_PATH="/linkfrom:/usr/bin", + PREFIX="/usr/local", + # real_executable on macOS matches the invocation path + real_executable="/linkfrom/python", + ) + ns.add_known_xfile("/linkfrom/python") + ns.add_known_xfile("/home/cpython/python") + ns.add_known_link("/linkfrom/python", "/home/cpython/python") + ns.add_known_xfile("/usr/local/bin/python") + ns.add_known_file("/home/cpython/pybuilddir.txt", ["build/lib.macos-9.8"]) + ns.add_known_file("/home/cpython/Lib/os.py") + ns.add_known_dir("/home/cpython/lib-dynload") + expected = dict( + executable="/linkfrom/python", + prefix="/usr/local", + exec_prefix="/usr/local", + base_executable="/linkfrom/python", + build_prefix="/home/cpython", + _is_python_build=1, + module_search_paths_set=1, + module_search_paths=[ + "/usr/local/lib/python98.zip", + "/home/cpython/Lib", + "/home/cpython/build/lib.macos-9.8", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + + +# ****************************************************************************** + +DEFAULT_NAMESPACE = dict( + PREFIX="", + EXEC_PREFIX="", + PYTHONPATH="", + VPATH="", + PLATLIBDIR="", + PYDEBUGEXT="", + VERSION_MAJOR=9, # fixed version number for ease + VERSION_MINOR=8, # of testing + PYWINVER=None, + EXE_SUFFIX=None, + + ENV_PATH="", + ENV_PYTHONHOME="", + ENV_PYTHONEXECUTABLE="", + ENV___PYVENV_LAUNCHER__="", + argv0="", + py_setpath="", + real_executable="", + executable_dir="", + library="", + winreg=None, + build_prefix=None, + venv_prefix=None, +) + +DEFAULT_CONFIG = dict( + home=None, + platlibdir=None, + pythonpath=None, + program_name=None, + prefix=None, + exec_prefix=None, + base_prefix=None, + base_exec_prefix=None, + executable=None, + base_executable="", + stdlib_dir=None, + platstdlib_dir=None, + module_search_paths=None, + module_search_paths_set=0, + pythonpath_env=None, + argv=None, + orig_argv=None, + + isolated=0, + use_environment=1, + use_site=1, +) + +class MockNTNamespace(dict): + def __init__(self, *a, argv0=None, config=None, **kw): + self.update(DEFAULT_NAMESPACE) + self["config"] = DEFAULT_CONFIG.copy() + self["os_name"] = "nt" + self["PLATLIBDIR"] = "DLLs" + self["PYWINVER"] = "9.8-XY" + self["VPATH"] = r"..\.." + super().__init__(*a, **kw) + if argv0: + self["config"]["orig_argv"] = [argv0] + if config: + self["config"].update(config) + self._files = {} + self._links = {} + self._dirs = set() + self._warnings = [] + + def add_known_file(self, path, lines=None): + self._files[path.casefold()] = list(lines or ()) + self.add_known_dir(path.rpartition("\\")[0]) + + def add_known_xfile(self, path): + self.add_known_file(path) + + def add_known_link(self, path, target): + self._links[path.casefold()] = target + + def add_known_dir(self, path): + p = path.rstrip("\\").casefold() + while p: + self._dirs.add(p) + p = p.rpartition("\\")[0] + + def __missing__(self, key): + try: + return getattr(self, key) + except AttributeError: + raise KeyError(key) from None + + def abspath(self, path): + if self.isabs(path): + return path + return self.joinpath("C:\\Absolute", path) + + def basename(self, path): + return path.rpartition("\\")[2] + + def dirname(self, path): + name = path.rstrip("\\").rpartition("\\")[0] + if name[1:] == ":": + return name + "\\" + return name + + def hassuffix(self, path, suffix): + return path.casefold().endswith(suffix.casefold()) + + def isabs(self, path): + return path[1:3] == ":\\" + + def isdir(self, path): + if verbose: + print("Check if", path, "is a dir") + return path.casefold() in self._dirs + + def isfile(self, path): + if verbose: + print("Check if", path, "is a file") + return path.casefold() in self._files + + def ismodule(self, path): + if verbose: + print("Check if", path, "is a module") + path = path.casefold() + return path in self._files and path.rpartition(".")[2] == "py".casefold() + + def isxfile(self, path): + if verbose: + print("Check if", path, "is a executable") + path = path.casefold() + return path in self._files and path.rpartition(".")[2] == "exe".casefold() + + def joinpath(self, *path): + return ntpath.normpath(ntpath.join(*path)) + + def readlines(self, path): + try: + return self._files[path.casefold()] + except KeyError: + raise FileNotFoundError(path) from None + + def realpath(self, path, _trail=None): + if verbose: + print("Read link from", path) + try: + link = self._links[path.casefold()] + except KeyError: + return path + if _trail is None: + _trail = set() + elif link.casefold() in _trail: + raise OSError("circular link") + _trail.add(link.casefold()) + return self.realpath(link, _trail) + + def warn(self, message): + self._warnings.append(message) + if verbose: + print(message) + + +class MockWinreg: + HKEY_LOCAL_MACHINE = "HKLM" + HKEY_CURRENT_USER = "HKCU" + + def __init__(self, keys): + self.keys = {k.casefold(): v for k, v in keys.items()} + self.open = {} + + def __repr__(self): + return "" + + def __eq__(self, other): + return isinstance(other, type(self)) + + def open_keys(self): + return list(self.open) + + def OpenKeyEx(self, hkey, subkey): + if verbose: + print(f"OpenKeyEx({hkey}, {subkey})") + key = f"{hkey}\\{subkey}".casefold() + if key in self.keys: + self.open[key] = self.open.get(key, 0) + 1 + return key + raise FileNotFoundError() + + def CloseKey(self, hkey): + if verbose: + print(f"CloseKey({hkey})") + hkey = hkey.casefold() + if hkey not in self.open: + raise RuntimeError("key is not open") + self.open[hkey] -= 1 + if not self.open[hkey]: + del self.open[hkey] + + def EnumKey(self, hkey, i): + if verbose: + print(f"EnumKey({hkey}, {i})") + hkey = hkey.casefold() + if hkey not in self.open: + raise RuntimeError("key is not open") + prefix = f'{hkey}\\' + subkeys = [k[len(prefix):] for k in sorted(self.keys) if k.startswith(prefix)] + subkeys[:] = [k for k in subkeys if '\\' not in k] + for j, n in enumerate(subkeys): + if j == i: + return n.removeprefix(prefix) + raise OSError("end of enumeration") + + def QueryValue(self, hkey, subkey): + if verbose: + print(f"QueryValue({hkey}, {subkey})") + hkey = hkey.casefold() + if hkey not in self.open: + raise RuntimeError("key is not open") + if subkey: + subkey = subkey.casefold() + hkey = f'{hkey}\\{subkey}' + try: + return self.keys[hkey] + except KeyError: + raise OSError() + + +class MockPosixNamespace(dict): + def __init__(self, *a, argv0=None, config=None, **kw): + self.update(DEFAULT_NAMESPACE) + self["config"] = DEFAULT_CONFIG.copy() + self["os_name"] = "posix" + self["PLATLIBDIR"] = "lib" + self["WITH_NEXT_FRAMEWORK"] = 0 + super().__init__(*a, **kw) + if argv0: + self["config"]["orig_argv"] = [argv0] + if config: + self["config"].update(config) + self._files = {} + self._xfiles = set() + self._links = {} + self._dirs = set() + self._warnings = [] + + def add_known_file(self, path, lines=None): + self._files[path] = list(lines or ()) + self.add_known_dir(path.rpartition("/")[0]) + + def add_known_xfile(self, path): + self.add_known_file(path) + self._xfiles.add(path) + + def add_known_link(self, path, target): + self._links[path] = target + + def add_known_dir(self, path): + p = path.rstrip("/") + while p: + self._dirs.add(p) + p = p.rpartition("/")[0] + + def __missing__(self, key): + try: + return getattr(self, key) + except AttributeError: + raise KeyError(key) from None + + def abspath(self, path): + if self.isabs(path): + return path + return self.joinpath("/Absolute", path) + + def basename(self, path): + return path.rpartition("/")[2] + + def dirname(self, path): + return path.rstrip("/").rpartition("/")[0] + + def hassuffix(self, path, suffix): + return path.endswith(suffix) + + def isabs(self, path): + return path[0:1] == "/" + + def isdir(self, path): + if verbose: + print("Check if", path, "is a dir") + return path in self._dirs + + def isfile(self, path): + if verbose: + print("Check if", path, "is a file") + return path in self._files + + def ismodule(self, path): + if verbose: + print("Check if", path, "is a module") + return path in self._files and path.rpartition(".")[2] == "py" + + def isxfile(self, path): + if verbose: + print("Check if", path, "is an xfile") + return path in self._xfiles + + def joinpath(self, *path): + return posixpath.normpath(posixpath.join(*path)) + + def readlines(self, path): + try: + return self._files[path] + except KeyError: + raise FileNotFoundError(path) from None + + def realpath(self, path, _trail=None): + if verbose: + print("Read link from", path) + try: + link = self._links[path] + except KeyError: + return path + if _trail is None: + _trail = set() + elif link in _trail: + raise OSError("circular link") + _trail.add(link) + return self.realpath(link, _trail) + + def warn(self, message): + self._warnings.append(message) + if verbose: + print(message) + + +def diff_dict(before, after, prefix="global"): + diff = [] + for k in sorted(before): + if k[:2] == "__": + continue + if k == "config": + diff_dict(before[k], after[k], prefix="config") + continue + if k in after and after[k] != before[k]: + diff.append((k, before[k], after[k])) + if not diff: + return + max_k = max(len(k) for k, _, _ in diff) + indent = " " * (len(prefix) + 1 + max_k) + if verbose: + for k, b, a in diff: + if b: + print("{}.{} -{!r}\n{} +{!r}".format(prefix, k.ljust(max_k), b, indent, a)) + else: + print("{}.{} +{!r}".format(prefix, k.ljust(max_k), a)) + + +def dump_dict(before, after, prefix="global"): + if not verbose or not after: + return + max_k = max(len(k) for k in after) + for k, v in sorted(after.items(), key=lambda i: i[0]): + if k[:2] == "__": + continue + if k == "config": + dump_dict(before[k], after[k], prefix="config") + continue + try: + if v != before[k]: + print("{}.{} {!r} (was {!r})".format(prefix, k.ljust(max_k), v, before[k])) + continue + except KeyError: + pass + print("{}.{} {!r}".format(prefix, k.ljust(max_k), v)) + + +def getpath(ns, keys): + before = copy.deepcopy(ns) + failed = True + try: + exec(SOURCE, ns) + failed = False + finally: + if failed: + dump_dict(before, ns) + else: + diff_dict(before, ns) + return { + k: ns['config'].get(k, ns.get(k, ...)) + for k in keys + } diff --git a/Lib/test/test_gettext.py b/Lib/test/test_gettext.py index 467652a41f0..1608d1b18e9 100644 --- a/Lib/test/test_gettext.py +++ b/Lib/test/test_gettext.py @@ -117,6 +117,7 @@ MMOFILE = os.path.join(LOCALEDIR, 'metadata.mo') class GettextBaseTest(unittest.TestCase): def setUp(self): + self.addCleanup(os_helper.rmtree, os.path.split(LOCALEDIR)[0]) if not os.path.isdir(LOCALEDIR): os.makedirs(LOCALEDIR) with open(MOFILE, 'wb') as fp: @@ -129,14 +130,10 @@ class GettextBaseTest(unittest.TestCase): fp.write(base64.decodebytes(UMO_DATA)) with open(MMOFILE, 'wb') as fp: fp.write(base64.decodebytes(MMO_DATA)) - self.env = os_helper.EnvironmentVarGuard() + self.env = self.enterContext(os_helper.EnvironmentVarGuard()) self.env['LANGUAGE'] = 'xx' gettext._translations.clear() - def tearDown(self): - self.env.__exit__() - del self.env - os_helper.rmtree(os.path.split(LOCALEDIR)[0]) GNU_MO_DATA_ISSUE_17898 = b'''\ 3hIElQAAAAABAAAAHAAAACQAAAAAAAAAAAAAAAAAAAAsAAAAggAAAC0AAAAAUGx1cmFsLUZvcm1z diff --git a/Lib/test/test_glob.py b/Lib/test/test_glob.py index 96db31b2681..f4b5821f408 100644 --- a/Lib/test/test_glob.py +++ b/Lib/test/test_glob.py @@ -30,6 +30,7 @@ class GlobTests(unittest.TestCase): self.mktemp('aab', 'F') self.mktemp('.aa', 'G') self.mktemp('.bb', 'H') + self.mktemp('.bb', '.J') self.mktemp('aaa', 'zzzF') self.mktemp('ZZZ') self.mktemp('EF') @@ -56,7 +57,9 @@ class GlobTests(unittest.TestCase): pattern = os.path.join(*parts) p = os.path.join(self.tempdir, pattern) res = glob.glob(p, **kwargs) + res2 = glob.iglob(p, **kwargs) self.assertCountEqual(glob.iglob(p, **kwargs), res) + bres = [os.fsencode(x) for x in res] self.assertCountEqual(glob.glob(os.fsencode(p), **kwargs), bres) self.assertCountEqual(glob.iglob(os.fsencode(p), **kwargs), bres) @@ -249,6 +252,17 @@ class GlobTests(unittest.TestCase): def rglob(self, *parts, **kwargs): return self.glob(*parts, recursive=True, **kwargs) + def hglob(self, *parts, **kwargs): + return self.glob(*parts, include_hidden=True, **kwargs) + + def test_hidden_glob(self): + eq = self.assertSequencesEqual_noorder + l = [('aaa',), ('.aa',)] + eq(self.hglob('?aa'), self.joins(*l)) + eq(self.hglob('*aa'), self.joins(*l)) + l2 = [('.aa','G',)] + eq(self.hglob('**', 'G'), self.joins(*l2)) + def test_recursive_glob(self): eq = self.assertSequencesEqual_noorder full = [('EF',), ('ZZZ',), @@ -314,6 +328,10 @@ class GlobTests(unittest.TestCase): expect += [join('sym3', 'EF')] eq(glob.glob(join('**', 'EF'), recursive=True), expect) + rec = [('.bb','H'), ('.bb','.J'), ('.aa','G'), ('.aa',), ('.bb',)] + eq(glob.glob('**', recursive=True, include_hidden=True), + [join(*i) for i in full+rec]) + def test_glob_many_open_files(self): depth = 30 base = os.path.join(self.tempdir, 'deep') diff --git a/Lib/test/test_global.py b/Lib/test/test_global.py index d0bde3fd040..f5b38c25ea0 100644 --- a/Lib/test/test_global.py +++ b/Lib/test/test_global.py @@ -9,14 +9,9 @@ import warnings class GlobalTests(unittest.TestCase): def setUp(self): - self._warnings_manager = check_warnings() - self._warnings_manager.__enter__() + self.enterContext(check_warnings()) warnings.filterwarnings("error", module="") - def tearDown(self): - self._warnings_manager.__exit__(None, None, None) - - def test1(self): prog_text_1 = """\ def wrong1(): @@ -54,9 +49,7 @@ x = 2 def setUpModule(): - cm = warnings.catch_warnings() - cm.__enter__() - unittest.addModuleCleanup(cm.__exit__, None, None, None) + unittest.enterModuleContext(warnings.catch_warnings()) warnings.filterwarnings("error", module="") diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index b6c45746560..5b946020994 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -104,6 +104,7 @@ INVALID_UNDERSCORE_LITERALS = [ class TokenTests(unittest.TestCase): from test.support import check_syntax_error + from test.support.warnings_helper import check_syntax_warning def test_backslash(self): # Backslash means line continuation: @@ -178,7 +179,7 @@ class TokenTests(unittest.TestCase): def test_float_exponent_tokenization(self): # See issue 21642. with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) + warnings.simplefilter('ignore', SyntaxWarning) self.assertEqual(eval("1 if 1else 0"), 1) self.assertEqual(eval("1 if 0else 0"), 0) self.assertRaises(SyntaxError, eval, "0 if 1Else 0") @@ -214,90 +215,43 @@ class TokenTests(unittest.TestCase): check("1e+", "invalid decimal literal") def test_end_of_numerical_literals(self): - def check(test): - with self.assertWarns(DeprecationWarning): - compile(test, "", "eval") + def check(test, error=False): + with self.subTest(expr=test): + if error: + with warnings.catch_warnings(record=True) as w: + with self.assertRaisesRegex(SyntaxError, + r'invalid \w+ literal'): + compile(test, "", "eval") + self.assertEqual(w, []) + else: + self.check_syntax_warning(test, + errtext=r'invalid \w+ literal') - def check_error(test): - with warnings.catch_warnings(record=True) as w: - with self.assertRaises(SyntaxError): - compile(test, "", "eval") - self.assertEqual(w, []) + for num in "0xf", "0o7", "0b1", "9", "0", "1.", "1e3", "1j": + compile(num, "", "eval") + check(f"{num}and x", error=(num == "0xf")) + check(f"{num}or x", error=(num == "0")) + check(f"{num}in x") + check(f"{num}not in x") + check(f"{num}if x else y") + check(f"x if {num}else y", error=(num == "0xf")) + check(f"[{num}for x in ()]") + check(f"{num}spam", error=True) - check_error("0xfand x") - check("0o7and x") - check("0b1and x") - check("9and x") - check("0and x") - check("1.and x") - check("1e3and x") - check("1jand x") - - check("0xfor x") - check("0o7or x") - check("0b1or x") - check("9or x") - check_error("0or x") - check("1.or x") - check("1e3or x") - check("1jor x") - - check("0xfin x") - check("0o7in x") - check("0b1in x") - check("9in x") - check("0in x") - check("1.in x") - check("1e3in x") - check("1jin x") - - with warnings.catch_warnings(): - warnings.simplefilter('ignore', SyntaxWarning) - check("0xfis x") - check("0o7is x") - check("0b1is x") - check("9is x") - check("0is x") - check("1.is x") - check("1e3is x") - check("1jis x") - - check("0xfif x else y") - check("0o7if x else y") - check("0b1if x else y") - check("9if x else y") - check("0if x else y") - check("1.if x else y") - check("1e3if x else y") - check("1jif x else y") - - check_error("x if 0xfelse y") - check("x if 0o7else y") - check("x if 0b1else y") - check("x if 9else y") - check("x if 0else y") - check("x if 1.else y") - check("x if 1e3else y") - check("x if 1jelse y") + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', '"is" with a literal', + SyntaxWarning) + with self.assertWarnsRegex(SyntaxWarning, + r'invalid \w+ literal'): + compile(f"{num}is x", "", "eval") + warnings.simplefilter('error', SyntaxWarning) + with self.assertRaisesRegex(SyntaxError, + r'invalid \w+ literal'): + compile(f"{num}is x", "", "eval") check("[0x1ffor x in ()]") check("[0x1for x in ()]") check("[0xfor x in ()]") - check("[0o7for x in ()]") - check("[0b1for x in ()]") - check("[9for x in ()]") - check("[1.for x in ()]") - check("[1e3for x in ()]") - check("[1jfor x in ()]") - - check_error("0xfspam") - check_error("0o7spam") - check_error("0b1spam") - check_error("9spam") - check_error("0spam") - check_error("1.spam") - check_error("1e3spam") - check_error("1jspam") def test_string_literals(self): x = ''; y = ""; self.assertTrue(len(x) == 0 and x == y) @@ -461,6 +415,28 @@ class GrammarTests(unittest.TestCase): x: int x.y: list = [] + def test_annotations_inheritance(self): + # Check that annotations are not inherited by derived classes + class A: + attr: int + class B(A): + pass + class C(A): + attr: str + class D: + attr2: int + class E(A, D): + pass + class F(C, A): + pass + self.assertEqual(A.__annotations__, {"attr": int}) + self.assertEqual(B.__annotations__, {}) + self.assertEqual(C.__annotations__, {"attr" : str}) + self.assertEqual(D.__annotations__, {"attr2" : int}) + self.assertEqual(E.__annotations__, {}) + self.assertEqual(F.__annotations__, {}) + + def test_var_annot_metaclass_semantics(self): class CMeta(type): @classmethod @@ -1394,6 +1370,12 @@ class GrammarTests(unittest.TestCase): result.append(x) self.assertEqual(result, [1, 2, 3]) + result = [] + a = b = c = [1, 2, 3] + for x in *a, *b, *c: + result.append(x) + self.assertEqual(result, 3 * a) + def test_try(self): ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] ### | 'try' ':' suite 'finally' ':' suite @@ -1419,6 +1401,30 @@ class GrammarTests(unittest.TestCase): compile("try:\n pass\nexcept Exception as a.b:\n pass", "?", "exec") compile("try:\n pass\nexcept Exception as a[b]:\n pass", "?", "exec") + def test_try_star(self): + ### try_stmt: 'try': suite (except_star_clause : suite) + ['else' ':' suite] + ### except_star_clause: 'except*' expr ['as' NAME] + try: + 1/0 + except* ZeroDivisionError: + pass + else: + pass + try: 1/0 + except* EOFError: pass + except* ZeroDivisionError as msg: pass + else: pass + try: 1/0 + except* (EOFError, TypeError, ZeroDivisionError): pass + try: 1/0 + except* (EOFError, TypeError, ZeroDivisionError) as msg: pass + try: pass + finally: pass + with self.assertRaises(SyntaxError): + compile("try:\n pass\nexcept* Exception as a.b:\n pass", "?", "exec") + compile("try:\n pass\nexcept* Exception as a[b]:\n pass", "?", "exec") + compile("try:\n pass\nexcept*:\n pass", "?", "exec") + def test_suite(self): # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT if 1: pass @@ -1608,7 +1614,7 @@ class GrammarTests(unittest.TestCase): s = a[-5:] s = a[:-1] s = a[-4:-3] - # A rough test of SF bug 1333982. http://python.org/sf/1333982 + # A rough test of SF bug 1333982. https://bugs.python.org/issue1333982 # The testing here is fairly incomplete. # Test cases should include: commas with 1 and 2 colons d = {} diff --git a/Lib/test/test_graphlib.py b/Lib/test/test_graphlib.py index 86246a62ed6..5f38af4024c 100644 --- a/Lib/test/test_graphlib.py +++ b/Lib/test/test_graphlib.py @@ -1,4 +1,3 @@ -from itertools import chain import graphlib import os import unittest @@ -34,7 +33,7 @@ class TestTopologicalSort(unittest.TestCase): try: ts.prepare() except graphlib.CycleError as e: - msg, seq = e.args + _, seq = e.args self.assertIn(" ".join(map(str, cycle)), " ".join(map(str, seq * 2))) else: raise diff --git a/Lib/test/test_grp.py b/Lib/test/test_grp.py index c7ec03ec0e4..e52e17b8dc7 100644 --- a/Lib/test/test_grp.py +++ b/Lib/test/test_grp.py @@ -49,10 +49,12 @@ class GroupDatabaseTestCase(unittest.TestCase): def test_errors(self): self.assertRaises(TypeError, grp.getgrgid) + self.assertRaises(TypeError, grp.getgrgid, 3.14) self.assertRaises(TypeError, grp.getgrnam) + self.assertRaises(TypeError, grp.getgrnam, 42) self.assertRaises(TypeError, grp.getgrall, 42) # embedded null character - self.assertRaises(ValueError, grp.getgrnam, 'a\x00b') + self.assertRaisesRegex(ValueError, 'null', grp.getgrnam, 'a\x00b') # try to get some errors bynames = {} diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py index 6476921b752..2e6f7385249 100644 --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -13,7 +13,7 @@ import zlib from subprocess import PIPE, Popen from test.support import import_helper from test.support import os_helper -from test.support import _4G, bigmemtest +from test.support import _4G, bigmemtest, requires_subprocess from test.support.script_helper import assert_python_ok, assert_python_failure gzip = import_helper.import_module('gzip') @@ -553,6 +553,15 @@ class TestGzip(BaseTest): f.read(1) # to set mtime attribute self.assertEqual(f.mtime, mtime) + def test_compress_correct_level(self): + # gzip.compress calls with mtime == 0 take a different code path. + for mtime in (0, 42): + with self.subTest(mtime=mtime): + nocompress = gzip.compress(data1, compresslevel=0, mtime=mtime) + yescompress = gzip.compress(data1, compresslevel=1, mtime=mtime) + self.assertIn(data1, nocompress) + self.assertNotIn(data1, yescompress) + def test_decompress(self): for data in (data1, data2): buf = io.BytesIO() @@ -790,6 +799,7 @@ def create_and_remove_directory(directory): class TestCommandLine(unittest.TestCase): data = b'This is a simple test with gzip' + @requires_subprocess() def test_decompress_stdin_stdout(self): with io.BytesIO() as bytes_io: with gzip.GzipFile(fileobj=bytes_io, mode='wb') as gzip_file: @@ -825,6 +835,7 @@ class TestCommandLine(unittest.TestCase): self.assertEqual(rc, 1) self.assertEqual(out, b'') + @requires_subprocess() @create_and_remove_directory(TEMPDIR) def test_compress_stdin_outfile(self): args = sys.executable, '-m', 'gzip' diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index 1623bf350e2..450dc4933f4 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -10,6 +10,7 @@ import array from binascii import unhexlify import hashlib import importlib +import io import itertools import os import sys @@ -20,12 +21,11 @@ import warnings from test import support from test.support import _4G, bigmemtest from test.support.import_helper import import_fresh_module +from test.support import os_helper from test.support import threading_helper from test.support import warnings_helper from http.client import HTTPException -# Were we compiled --with-pydebug or with #define Py_DEBUG? -COMPILED_WITH_PYDEBUG = hasattr(sys, 'gettotalrefcount') # default builtin hash module default_builtin_hashes = {'md5', 'sha1', 'sha256', 'sha512', 'sha3', 'blake2'} @@ -48,12 +48,15 @@ else: builtin_hashlib = None try: - from _hashlib import HASH, HASHXOF, openssl_md_meth_names + from _hashlib import HASH, HASHXOF, openssl_md_meth_names, get_fips_mode except ImportError: HASH = None HASHXOF = None openssl_md_meth_names = frozenset() + def get_fips_mode(): + return 0 + try: import _blake2 except ImportError: @@ -61,6 +64,10 @@ except ImportError: requires_blake2 = unittest.skipUnless(_blake2, 'requires _blake2') +# bpo-46913: Don't test the _sha3 extension on a Python UBSAN build +SKIP_SHA3 = support.check_sanitizer(ub=True) +requires_sha3 = unittest.skipUnless(not SKIP_SHA3, 'requires _sha3') + def hexstr(s): assert isinstance(s, bytes), repr(s) @@ -100,7 +107,7 @@ class HashLibTestCase(unittest.TestCase): shakes = {'shake_128', 'shake_256'} # Issue #14693: fallback modules are always compiled under POSIX - _warn_on_extension_import = os.name == 'posix' or COMPILED_WITH_PYDEBUG + _warn_on_extension_import = (os.name == 'posix' or support.Py_DEBUG) def _conditional_import_module(self, module_name): """Import a module and return a reference to it or None on failure.""" @@ -122,6 +129,8 @@ class HashLibTestCase(unittest.TestCase): self.constructors_to_test = {} for algorithm in algorithms: + if SKIP_SHA3 and algorithm.startswith('sha3_'): + continue self.constructors_to_test[algorithm] = set() # For each algorithm, test the direct constructor and the use @@ -174,14 +183,15 @@ class HashLibTestCase(unittest.TestCase): add_builtin_constructor('blake2s') add_builtin_constructor('blake2b') - _sha3 = self._conditional_import_module('_sha3') - if _sha3: - add_builtin_constructor('sha3_224') - add_builtin_constructor('sha3_256') - add_builtin_constructor('sha3_384') - add_builtin_constructor('sha3_512') - add_builtin_constructor('shake_128') - add_builtin_constructor('shake_256') + if not SKIP_SHA3: + _sha3 = self._conditional_import_module('_sha3') + if _sha3: + add_builtin_constructor('sha3_224') + add_builtin_constructor('sha3_256') + add_builtin_constructor('sha3_384') + add_builtin_constructor('sha3_512') + add_builtin_constructor('shake_128') + add_builtin_constructor('shake_256') super(HashLibTestCase, self).__init__(*args, **kwargs) @@ -192,10 +202,7 @@ class HashLibTestCase(unittest.TestCase): @property def is_fips_mode(self): - if hasattr(self._hashlib, "get_fips_mode"): - return self._hashlib.get_fips_mode() - else: - return None + return get_fips_mode() def test_hash_array(self): a = array.array("b", range(10)) @@ -214,6 +221,10 @@ class HashLibTestCase(unittest.TestCase): def test_algorithms_available(self): self.assertTrue(set(hashlib.algorithms_guaranteed). issubset(hashlib.algorithms_available)) + # all available algorithms must be loadable, bpo-47101 + self.assertNotIn("undefined", hashlib.algorithms_available) + for name in hashlib.algorithms_available: + digest = hashlib.new(name, usedforsecurity=False) def test_usedforsecurity_true(self): hashlib.new("sha256", usedforsecurity=True) @@ -364,6 +375,36 @@ class HashLibTestCase(unittest.TestCase): if not shake: self.assertEqual(len(digest), m.digest_size) + if not shake and kwargs.get("key") is None: + # skip shake and blake2 extended parameter tests + self.check_file_digest(name, data, hexdigest) + + def check_file_digest(self, name, data, hexdigest): + hexdigest = hexdigest.lower() + try: + hashlib.new(name) + except ValueError: + # skip, algorithm is blocked by security policy. + return + digests = [name] + digests.extend(self.constructors_to_test[name]) + + with open(os_helper.TESTFN, "wb") as f: + f.write(data) + + try: + for digest in digests: + buf = io.BytesIO(data) + buf.seek(0) + self.assertEqual( + hashlib.file_digest(buf, digest).hexdigest(), hexdigest + ) + with open(os_helper.TESTFN, "rb") as f: + digestobj = hashlib.file_digest(f, digest) + self.assertEqual(digestobj.hexdigest(), hexdigest) + finally: + os.unlink(os_helper.TESTFN) + def check_no_unicode(self, algorithm_name): # Unicode objects are not allowed as input. constructors = self.constructors_to_test[algorithm_name] @@ -383,6 +424,7 @@ class HashLibTestCase(unittest.TestCase): self.check_no_unicode('blake2b') self.check_no_unicode('blake2s') + @requires_sha3 def test_no_unicode_sha3(self): self.check_no_unicode('sha3_224') self.check_no_unicode('sha3_256') @@ -418,6 +460,7 @@ class HashLibTestCase(unittest.TestCase): self.check_blocksize_name('sha384', 128, 48) self.check_blocksize_name('sha512', 128, 64) + @requires_sha3 def test_blocksize_name_sha3(self): self.check_blocksize_name('sha3_224', 144, 28) self.check_blocksize_name('sha3_256', 136, 32) @@ -438,6 +481,7 @@ class HashLibTestCase(unittest.TestCase): self.assertEqual(m._rate_bits, rate) self.assertEqual(m._suffix, suffix) + @requires_sha3 def test_extra_sha3(self): self.check_sha3('sha3_224', 448, 1152, b'\x06') self.check_sha3('sha3_256', 512, 1088, b'\x06') @@ -777,36 +821,44 @@ class HashLibTestCase(unittest.TestCase): key = bytes.fromhex(key) self.check('blake2s', msg, md, key=key) + @requires_sha3 def test_case_sha3_224_0(self): self.check('sha3_224', b"", "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7") + @requires_sha3 def test_case_sha3_224_vector(self): for msg, md in read_vectors('sha3_224'): self.check('sha3_224', msg, md) + @requires_sha3 def test_case_sha3_256_0(self): self.check('sha3_256', b"", "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a") + @requires_sha3 def test_case_sha3_256_vector(self): for msg, md in read_vectors('sha3_256'): self.check('sha3_256', msg, md) + @requires_sha3 def test_case_sha3_384_0(self): self.check('sha3_384', b"", "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2a"+ "c3713831264adb47fb6bd1e058d5f004") + @requires_sha3 def test_case_sha3_384_vector(self): for msg, md in read_vectors('sha3_384'): self.check('sha3_384', msg, md) + @requires_sha3 def test_case_sha3_512_0(self): self.check('sha3_512', b"", "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a6"+ "15b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26") + @requires_sha3 def test_case_sha3_512_vector(self): for msg, md in read_vectors('sha3_512'): self.check('sha3_512', msg, md) @@ -861,6 +913,7 @@ class HashLibTestCase(unittest.TestCase): ) @threading_helper.reap_threads + @threading_helper.requires_working_threading() def test_threaded_hashing(self): # Updating the same hash object from several threads at once # using data chunk sizes containing the same byte sequences. @@ -1017,7 +1070,7 @@ class KDFTests(unittest.TestCase): self.assertEqual(out, expected, (digest_name, password, salt, rounds)) - with self.assertRaisesRegex(ValueError, 'unsupported hash type'): + with self.assertRaisesRegex(ValueError, '.*unsupported.*'): pbkdf2('unknown', b'pass', b'salt', 1) if 'sha1' in supported: @@ -1043,20 +1096,13 @@ class KDFTests(unittest.TestCase): iterations=1, dklen=None) self.assertEqual(out, self.pbkdf2_results['sha1'][0][0]) - @unittest.skipIf(builtin_hashlib is None, "test requires builtin_hashlib") - def test_pbkdf2_hmac_py(self): - with warnings_helper.check_warnings(): - self._test_pbkdf2_hmac( - builtin_hashlib.pbkdf2_hmac, builtin_hashes - ) - - @unittest.skipUnless(hasattr(openssl_hashlib, 'pbkdf2_hmac'), - ' test requires OpenSSL > 1.0') + @unittest.skipIf(openssl_hashlib is None, "requires OpenSSL bindings") def test_pbkdf2_hmac_c(self): self._test_pbkdf2_hmac(openssl_hashlib.pbkdf2_hmac, openssl_md_meth_names) @unittest.skipUnless(hasattr(hashlib, 'scrypt'), ' test requires OpenSSL > 1.1') + @unittest.skipIf(get_fips_mode(), reason="scrypt is blocked in FIPS mode") def test_scrypt(self): for password, salt, n, r, p, expected in self.scrypt_test_vectors: result = hashlib.scrypt(password, salt=salt, n=n, r=r, p=p) @@ -1098,6 +1144,33 @@ class KDFTests(unittest.TestCase): self.assertNotIn("blake2b512", hashlib.algorithms_available) self.assertNotIn("sha3-512", hashlib.algorithms_available) + def test_file_digest(self): + data = b'a' * 65536 + d1 = hashlib.sha256() + self.addCleanup(os.unlink, os_helper.TESTFN) + with open(os_helper.TESTFN, "wb") as f: + for _ in range(10): + d1.update(data) + f.write(data) + + with open(os_helper.TESTFN, "rb") as f: + d2 = hashlib.file_digest(f, hashlib.sha256) + + self.assertEqual(d1.hexdigest(), d2.hexdigest()) + self.assertEqual(d1.name, d2.name) + self.assertIs(type(d1), type(d2)) + + with self.assertRaises(ValueError): + hashlib.file_digest(None, "sha256") + + with self.assertRaises(ValueError): + with open(os_helper.TESTFN, "r") as f: + hashlib.file_digest(f, "sha256") + + with self.assertRaises(ValueError): + with open(os_helper.TESTFN, "wb") as f: + hashlib.file_digest(f, "sha256") + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_heapq.py b/Lib/test/test_heapq.py index cb1e4505b02..1aa8e4e2897 100644 --- a/Lib/test/test_heapq.py +++ b/Lib/test/test_heapq.py @@ -4,7 +4,6 @@ import random import unittest import doctest -from test import support from test.support import import_helper from unittest import TestCase, skipUnless from operator import itemgetter diff --git a/Lib/test/test_htmlparser.py b/Lib/test/test_htmlparser.py index 12917755a56..b42a611c62c 100644 --- a/Lib/test/test_htmlparser.py +++ b/Lib/test/test_htmlparser.py @@ -4,6 +4,8 @@ import html.parser import pprint import unittest +from unittest.mock import patch + class EventCollector(html.parser.HTMLParser): @@ -787,5 +789,17 @@ class AttributesTestCase(TestCaseBase): ('starttag', 'form', [('action', 'bogus|&#()value')])]) + +class TestInheritance(unittest.TestCase): + + @patch("_markupbase.ParserBase.__init__") + @patch("_markupbase.ParserBase.reset") + def test_base_class_methods_called(self, super_reset_method, super_init_method): + with patch('_markupbase.ParserBase') as parser_base: + EventCollector() + super_init_method.assert_called_once() + super_reset_method.assert_called_once() + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py index 9450104d0b9..97e9c82cde9 100644 --- a/Lib/test/test_http_cookiejar.py +++ b/Lib/test/test_http_cookiejar.py @@ -1,8 +1,9 @@ """Tests for http/cookiejar.py.""" import os +import stat +import sys import re -import test.support from test.support import os_helper from test.support import warnings_helper import time @@ -17,6 +18,7 @@ from http.cookiejar import (time2isoz, http2time, iso2time, time2netscape, reach, is_HDN, domain_match, user_domain_match, request_path, request_port, request_host) +mswindows = (sys.platform == "win32") class DateTimeTests(unittest.TestCase): @@ -364,10 +366,63 @@ class FileCookieJarTests(unittest.TestCase): c = LWPCookieJar() c.load(filename, ignore_discard=True) finally: - try: os.unlink(filename) - except OSError: pass + os_helper.unlink(filename) self.assertEqual(c._cookies["www.acme.com"]["/"]["boo"].value, None) + @unittest.skipIf(mswindows, "windows file permissions are incompatible with file modes") + @os_helper.skip_unless_working_chmod + def test_lwp_filepermissions(self): + # Cookie file should only be readable by the creator + filename = os_helper.TESTFN + c = LWPCookieJar() + interact_netscape(c, "http://www.acme.com/", 'boo') + try: + c.save(filename, ignore_discard=True) + st = os.stat(filename) + self.assertEqual(stat.S_IMODE(st.st_mode), 0o600) + finally: + os_helper.unlink(filename) + + @unittest.skipIf(mswindows, "windows file permissions are incompatible with file modes") + @os_helper.skip_unless_working_chmod + def test_mozilla_filepermissions(self): + # Cookie file should only be readable by the creator + filename = os_helper.TESTFN + c = MozillaCookieJar() + interact_netscape(c, "http://www.acme.com/", 'boo') + try: + c.save(filename, ignore_discard=True) + st = os.stat(filename) + self.assertEqual(stat.S_IMODE(st.st_mode), 0o600) + finally: + os_helper.unlink(filename) + + @unittest.skipIf(mswindows, "windows file permissions are incompatible with file modes") + @os_helper.skip_unless_working_chmod + def test_cookie_files_are_truncated(self): + filename = os_helper.TESTFN + for cookiejar_class in (LWPCookieJar, MozillaCookieJar): + c = cookiejar_class(filename) + + req = urllib.request.Request("http://www.acme.com/") + headers = ["Set-Cookie: pll_lang=en; Max-Age=31536000; path=/"] + res = FakeResponse(headers, "http://www.acme.com/") + c.extract_cookies(res, req) + self.assertEqual(len(c), 1) + + try: + # Save the first version with contents: + c.save() + # Now, clear cookies and re-save: + c.clear() + c.save() + # Check that file was truncated: + c.load() + finally: + os_helper.unlink(filename) + + self.assertEqual(len(c), 0) + def test_bad_magic(self): # OSErrors (eg. file doesn't exist) are allowed to propagate filename = os_helper.TESTFN @@ -391,8 +446,7 @@ class FileCookieJarTests(unittest.TestCase): c = cookiejar_class() self.assertRaises(LoadError, c.load, filename) finally: - try: os.unlink(filename) - except OSError: pass + os_helper.unlink(filename) class CookieTests(unittest.TestCase): # XXX @@ -496,7 +550,7 @@ class CookieTests(unittest.TestCase): c = MozillaCookieJar(filename) c.revert(ignore_expires=True, ignore_discard=True) finally: - os.unlink(c.filename) + os_helper.unlink(c.filename) # cookies unchanged apart from lost info re. whether path was specified self.assertEqual( repr(c), @@ -920,6 +974,48 @@ class CookieTests(unittest.TestCase): ## self.assertEqual(len(c), 2) self.assertEqual(len(c), 4) + def test_localhost_domain(self): + c = CookieJar() + + interact_netscape(c, "http://localhost", "foo=bar; domain=localhost;") + + self.assertEqual(len(c), 1) + + def test_localhost_domain_contents(self): + c = CookieJar() + + interact_netscape(c, "http://localhost", "foo=bar; domain=localhost;") + + self.assertEqual(c._cookies[".localhost"]["/"]["foo"].value, "bar") + + def test_localhost_domain_contents_2(self): + c = CookieJar() + + interact_netscape(c, "http://localhost", "foo=bar;") + + self.assertEqual(c._cookies["localhost.local"]["/"]["foo"].value, "bar") + + def test_evil_nonlocal_domain(self): + c = CookieJar() + + interact_netscape(c, "http://evil.com", "foo=bar; domain=.localhost") + + self.assertEqual(len(c), 0) + + def test_evil_local_domain(self): + c = CookieJar() + + interact_netscape(c, "http://localhost", "foo=bar; domain=.evil.com") + + self.assertEqual(len(c), 0) + + def test_evil_local_domain_2(self): + c = CookieJar() + + interact_netscape(c, "http://localhost", "foo=bar; domain=.someother.local") + + self.assertEqual(len(c), 0) + def test_two_component_domain_rfc2965(self): pol = DefaultCookiePolicy(rfc2965=True) c = CookieJar(pol) @@ -1251,11 +1347,11 @@ class CookieTests(unittest.TestCase): r'port="90,100, 80,8080"; ' r'max-age=100; Comment = "Just kidding! (\"|\\\\) "') - versions = [1, 1, 1, 0, 1] - names = ["bang", "foo", "foo", "spam", "foo"] - domains = [".sol.no", "blah.spam.org", "www.acme.com", - "www.acme.com", "www.acme.com"] - paths = ["/", "/", "/", "/blah", "/blah/"] + versions = [1, 0, 1, 1, 1] + names = ["foo", "spam", "foo", "foo", "bang"] + domains = ["blah.spam.org", "www.acme.com", "www.acme.com", + "www.acme.com", ".sol.no"] + paths = ["/", "/blah", "/blah/", "/", "/"] for i in range(4): i = 0 @@ -1724,8 +1820,7 @@ class LWPCookieTests(unittest.TestCase): c = LWPCookieJar(policy=pol) c.load(filename, ignore_discard=True) finally: - try: os.unlink(filename) - except OSError: pass + os_helper.unlink(filename) self.assertEqual(old, repr(c)) @@ -1784,8 +1879,7 @@ class LWPCookieTests(unittest.TestCase): DefaultCookiePolicy(rfc2965=True)) new_c.load(ignore_discard=ignore_discard) finally: - try: os.unlink(filename) - except OSError: pass + os_helper.unlink(filename) return new_c new_c = save_and_restore(c, True) diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index 8265b8d1d6d..620a5b19109 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -19,6 +19,7 @@ from test.support import os_helper from test.support import socket_helper from test.support import warnings_helper +support.requires_working_socket(module=True) here = os.path.dirname(__file__) # Self-signed cert file for 'localhost' @@ -552,6 +553,27 @@ class BasicTest(TestCase): obj.phrase = phrase obj.description = description return obj + + @property + def is_informational(self): + return 100 <= self <= 199 + + @property + def is_success(self): + return 200 <= self <= 299 + + @property + def is_redirection(self): + return 300 <= self <= 399 + + @property + def is_client_error(self): + return 400 <= self <= 499 + + @property + def is_server_error(self): + return 500 <= self <= 599 + # informational CONTINUE = 100, 'Continue', 'Request received, please continue' SWITCHING_PROTOCOLS = (101, 'Switching Protocols', @@ -668,6 +690,30 @@ class BasicTest(TestCase): 'The client needs to authenticate to gain network access') enum._test_simple_enum(CheckedHTTPStatus, HTTPStatus) + def test_httpstatus_range(self): + """Checks that the statuses are in the 100-599 range""" + + for member in HTTPStatus.__members__.values(): + self.assertGreaterEqual(member, 100) + self.assertLessEqual(member, 599) + + def test_httpstatus_category(self): + """Checks that the statuses belong to the standard categories""" + + categories = ( + ((100, 199), "is_informational"), + ((200, 299), "is_success"), + ((300, 399), "is_redirection"), + ((400, 499), "is_client_error"), + ((500, 599), "is_server_error"), + ) + for member in HTTPStatus.__members__.values(): + for (lower, upper), category in categories: + category_indicator = getattr(member, category) + if lower <= member <= upper: + self.assertTrue(category_indicator) + else: + self.assertFalse(category_indicator) def test_status_lines(self): # Test HTTP status lines @@ -1932,7 +1978,7 @@ class HTTPSTest(TestCase): self.assertEqual(exc_info.exception.reason, 'CERTIFICATE_VERIFY_FAILED') def test_local_good_hostname(self): - # The (valid) cert validates the HTTP hostname + # The (valid) cert validates the HTTPS hostname import ssl server = self.make_server(CERT_localhost) context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) @@ -1945,7 +1991,7 @@ class HTTPSTest(TestCase): self.assertEqual(resp.status, 404) def test_local_bad_hostname(self): - # The (valid) cert doesn't validate the HTTP hostname + # The (valid) cert doesn't validate the HTTPS hostname import ssl server = self.make_server(CERT_fakehostname) context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) @@ -1953,38 +1999,21 @@ class HTTPSTest(TestCase): h = client.HTTPSConnection('localhost', server.port, context=context) with self.assertRaises(ssl.CertificateError): h.request('GET', '/') - # Same with explicit check_hostname=True - with warnings_helper.check_warnings(('', DeprecationWarning)): - h = client.HTTPSConnection('localhost', server.port, - context=context, check_hostname=True) + + # Same with explicit context.check_hostname=True + context.check_hostname = True + h = client.HTTPSConnection('localhost', server.port, context=context) with self.assertRaises(ssl.CertificateError): h.request('GET', '/') - # With check_hostname=False, the mismatching is ignored - context.check_hostname = False - with warnings_helper.check_warnings(('', DeprecationWarning)): - h = client.HTTPSConnection('localhost', server.port, - context=context, check_hostname=False) - h.request('GET', '/nonexistent') - resp = h.getresponse() - resp.close() - h.close() - self.assertEqual(resp.status, 404) - # The context's check_hostname setting is used if one isn't passed to - # HTTPSConnection. + + # With context.check_hostname=False, the mismatching is ignored context.check_hostname = False h = client.HTTPSConnection('localhost', server.port, context=context) h.request('GET', '/nonexistent') resp = h.getresponse() - self.assertEqual(resp.status, 404) resp.close() h.close() - # Passing check_hostname to HTTPSConnection should override the - # context's setting. - with warnings_helper.check_warnings(('', DeprecationWarning)): - h = client.HTTPSConnection('localhost', server.port, - context=context, check_hostname=True) - with self.assertRaises(ssl.CertificateError): - h.request('GET', '/') + self.assertEqual(resp.status, 404) @unittest.skipIf(not hasattr(client, 'HTTPSConnection'), 'http.client.HTTPSConnection not available') @@ -2020,11 +2049,9 @@ class HTTPSTest(TestCase): self.assertIs(h._context, context) self.assertFalse(h._context.post_handshake_auth) - with warnings.catch_warnings(): - warnings.filterwarnings('ignore', 'key_file, cert_file and check_hostname are deprecated', - DeprecationWarning) - h = client.HTTPSConnection('localhost', 443, context=context, - cert_file=CERT_localhost) + context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT, cert_file=CERT_localhost) + context.post_handshake_auth = True + h = client.HTTPSConnection('localhost', 443, context=context) self.assertTrue(h._context.post_handshake_auth) diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index 1cc020f6353..cbcf94136ac 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -26,13 +26,14 @@ import time import datetime import threading from unittest import mock -from io import BytesIO +from io import BytesIO, StringIO import unittest from test import support from test.support import os_helper from test.support import threading_helper +support.requires_working_socket(module=True) class NoLogRequestHandler: def log_message(self, *args): @@ -333,7 +334,7 @@ class SimpleHTTPServerTestCase(BaseTestCase): pass def setUp(self): - BaseTestCase.setUp(self) + super().setUp() self.cwd = os.getcwd() basetempdir = tempfile.gettempdir() os.chdir(basetempdir) @@ -361,7 +362,7 @@ class SimpleHTTPServerTestCase(BaseTestCase): except: pass finally: - BaseTestCase.tearDown(self) + super().tearDown() def check_status_and_reason(self, response, status, data=None): def close_conn(): @@ -417,6 +418,55 @@ class SimpleHTTPServerTestCase(BaseTestCase): self.check_status_and_reason(response, HTTPStatus.OK, data=os_helper.TESTFN_UNDECODABLE) + def test_get_dir_redirect_location_domain_injection_bug(self): + """Ensure //evil.co/..%2f../../X does not put //evil.co/ in Location. + + //netloc/ in a Location header is a redirect to a new host. + https://github.com/python/cpython/issues/87389 + + This checks that a path resolving to a directory on our server cannot + resolve into a redirect to another server. + """ + os.mkdir(os.path.join(self.tempdir, 'existing_directory')) + url = f'/python.org/..%2f..%2f..%2f..%2f..%2f../%0a%0d/../{self.tempdir_name}/existing_directory' + expected_location = f'{url}/' # /python.org.../ single slash single prefix, trailing slash + # Canonicalizes to /tmp/tempdir_name/existing_directory which does + # exist and is a dir, triggering the 301 redirect logic. + response = self.request(url) + self.check_status_and_reason(response, HTTPStatus.MOVED_PERMANENTLY) + location = response.getheader('Location') + self.assertEqual(location, expected_location, msg='non-attack failed!') + + # //python.org... multi-slash prefix, no trailing slash + attack_url = f'/{url}' + response = self.request(attack_url) + self.check_status_and_reason(response, HTTPStatus.MOVED_PERMANENTLY) + location = response.getheader('Location') + self.assertFalse(location.startswith('//'), msg=location) + self.assertEqual(location, expected_location, + msg='Expected Location header to start with a single / and ' + 'end with a / as this is a directory redirect.') + + # ///python.org... triple-slash prefix, no trailing slash + attack3_url = f'//{url}' + response = self.request(attack3_url) + self.check_status_and_reason(response, HTTPStatus.MOVED_PERMANENTLY) + self.assertEqual(response.getheader('Location'), expected_location) + + # If the second word in the http request (Request-URI for the http + # method) is a full URI, we don't worry about it, as that'll be parsed + # and reassembled as a full URI within BaseHTTPRequestHandler.send_head + # so no errant scheme-less //netloc//evil.co/ domain mixup can happen. + attack_scheme_netloc_2slash_url = f'https://pypi.org/{url}' + expected_scheme_netloc_location = f'{attack_scheme_netloc_2slash_url}/' + response = self.request(attack_scheme_netloc_2slash_url) + self.check_status_and_reason(response, HTTPStatus.MOVED_PERMANENTLY) + location = response.getheader('Location') + # We're just ensuring that the scheme and domain make it through, if + # there are or aren't multiple slashes at the start of the path that + # follows that isn't important in this Location: header. + self.assertTrue(location.startswith('https://pypi.org/'), msg=location) + def test_get(self): #constructs the path relative to the root directory of the HTTPServer response = self.request(self.base_url + '/test') @@ -439,6 +489,9 @@ class SimpleHTTPServerTestCase(BaseTestCase): self.check_status_and_reason(response, HTTPStatus.NOT_FOUND) response = self.request('/' + 'ThisDoesNotExist' + '/') self.check_status_and_reason(response, HTTPStatus.NOT_FOUND) + os.makedirs(os.path.join(self.tempdir, 'spam', 'index.html')) + response = self.request(self.base_url + '/spam/') + self.check_status_and_reason(response, HTTPStatus.OK) data = b"Dummy index file\r\n" with open(os.path.join(self.tempdir_name, 'index.html'), 'wb') as f: @@ -569,14 +622,19 @@ print("Hello World") cgi_file2 = """\ #!%s -import cgi +import os +import sys +import urllib.parse print("Content-type: text/html") print() -form = cgi.FieldStorage() -print("%%s, %%s, %%s" %% (form.getfirst("spam"), form.getfirst("eggs"), - form.getfirst("bacon"))) +content_length = int(os.environ["CONTENT_LENGTH"]) +query_string = sys.stdin.buffer.read(content_length) +params = {key.decode("utf-8"): val.decode("utf-8") + for key, val in urllib.parse.parse_qsl(query_string)} + +print("%%s, %%s, %%s" %% (params["spam"], params["eggs"], params["bacon"])) """ cgi_file4 = """\ @@ -935,6 +993,27 @@ class BaseHTTPRequestHandlerTestCase(unittest.TestCase): match = self.HTTPResponseMatch.search(response) self.assertIsNotNone(match) + def test_unprintable_not_logged(self): + # We call the method from the class directly as our Socketless + # Handler subclass overrode it... nice for everything BUT this test. + self.handler.client_address = ('127.0.0.1', 1337) + log_message = BaseHTTPRequestHandler.log_message + with mock.patch.object(sys, 'stderr', StringIO()) as fake_stderr: + log_message(self.handler, '/foo') + log_message(self.handler, '/\033bar\000\033') + log_message(self.handler, '/spam %s.', 'a') + log_message(self.handler, '/spam %s.', '\033\x7f\x9f\xa0beans') + log_message(self.handler, '"GET /foo\\b"ar\007 HTTP/1.0"') + stderr = fake_stderr.getvalue() + self.assertNotIn('\033', stderr) # non-printable chars are caught. + self.assertNotIn('\000', stderr) # non-printable chars are caught. + lines = stderr.splitlines() + self.assertIn('/foo', lines[0]) + self.assertIn(r'/\x1bbar\x00\x1b', lines[1]) + self.assertIn('/spam a.', lines[2]) + self.assertIn('/spam \\x1b\\x7f\\x9f\xa0beans.', lines[3]) + self.assertIn(r'"GET /foo\\b"ar\x07 HTTP/1.0"', lines[4]) + def test_http_1_1(self): result = self.send_typical_request(b'GET / HTTP/1.1\r\n\r\n') self.verify_http_server_response(result[0]) diff --git a/Lib/test/test_idle.py b/Lib/test/test_idle.py index 8756b766334..b94b18a541a 100644 --- a/Lib/test/test_idle.py +++ b/Lib/test/test_idle.py @@ -1,5 +1,9 @@ import unittest from test.support.import_helper import import_module +from test.support import check_sanitizer + +if check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("Tests involvin libX11 can SEGFAULT on ASAN/MSAN builds") # Skip test_idle if _tkinter wasn't built, if tkinter is missing, # if tcl/tk is not the 8.5+ needed for ttk widgets, diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index c2b935f5816..7626d9572e1 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -10,8 +10,7 @@ import calendar import threading import socket -from test.support import (verbose, - run_with_tz, run_with_locale, cpython_only) +from test.support import verbose, run_with_tz, run_with_locale, cpython_only from test.support import hashlib_helper from test.support import threading_helper from test.support import warnings_helper @@ -23,6 +22,8 @@ try: except ImportError: ssl = None +support.requires_working_socket(module=True) + CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "keycert3.pem") CAFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "pycacert.pem") @@ -387,7 +388,7 @@ class NewIMAPTestsMixin(): self.assertEqual(code, 'OK') self.assertEqual(server.response, b'ZmFrZQ==\r\n') # b64 encoded 'fake' - @hashlib_helper.requires_hashdigest('md5') + @hashlib_helper.requires_hashdigest('md5', openssl=True) def test_login_cram_md5_bytes(self): class AuthHandler(SimpleIMAPHandler): capabilities = 'LOGINDISABLED AUTH=CRAM-MD5' @@ -405,7 +406,7 @@ class NewIMAPTestsMixin(): ret, _ = client.login_cram_md5("tim", b"tanstaaftanstaaf") self.assertEqual(ret, "OK") - @hashlib_helper.requires_hashdigest('md5') + @hashlib_helper.requires_hashdigest('md5', openssl=True) def test_login_cram_md5_plain_text(self): class AuthHandler(SimpleIMAPHandler): capabilities = 'LOGINDISABLED AUTH=CRAM-MD5' @@ -572,15 +573,6 @@ class NewIMAPSSLTests(NewIMAPTestsMixin, unittest.TestCase): ssl_context=ssl_context) client.shutdown() - # Mock the private method _connect(), so mark the test as specific - # to CPython stdlib - @cpython_only - def test_certfile_arg_warn(self): - with warnings_helper.check_warnings(('', DeprecationWarning)): - with mock.patch.object(self.imap_class, 'open'): - with mock.patch.object(self.imap_class, '_connect'): - self.imap_class('localhost', 143, certfile=CERTFILE) - class ThreadedNetworkedTests(unittest.TestCase): server_class = socketserver.TCPServer imap_class = imaplib.IMAP4 @@ -851,7 +843,7 @@ class ThreadedNetworkedTests(unittest.TestCase): b'ZmFrZQ==\r\n') # b64 encoded 'fake' @threading_helper.reap_threads - @hashlib_helper.requires_hashdigest('md5') + @hashlib_helper.requires_hashdigest('md5', openssl=True) def test_login_cram_md5(self): class AuthHandler(SimpleIMAPHandler): @@ -936,6 +928,7 @@ class ThreadedNetworkedTests(unittest.TestCase): @threading_helper.reap_threads @cpython_only + @unittest.skipUnless(__debug__, "Won't work if __debug__ is False") def test_dump_ur(self): # See: http://bugs.python.org/issue26543 untagged_resp_dict = {'READ-WRITE': [b'']} @@ -1068,18 +1061,6 @@ class RemoteIMAP_SSLTest(RemoteIMAPTest): rs = _server.logout() self.assertEqual(rs[0], 'BYE', rs) - def test_ssl_context_certfile_exclusive(self): - with socket_helper.transient_internet(self.host): - self.assertRaises( - ValueError, self.imap_class, self.host, self.port, - certfile=CERTFILE, ssl_context=self.create_ssl_context()) - - def test_ssl_context_keyfile_exclusive(self): - with socket_helper.transient_internet(self.host): - self.assertRaises( - ValueError, self.imap_class, self.host, self.port, - keyfile=CERTFILE, ssl_context=self.create_ssl_context()) - if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_imghdr.py b/Lib/test/test_imghdr.py index ca0a0b23c3c..208c8eee455 100644 --- a/Lib/test/test_imghdr.py +++ b/Lib/test/test_imghdr.py @@ -1,12 +1,13 @@ -import imghdr import io import os import pathlib import unittest import warnings -from test.support import findfile +from test.support import findfile, warnings_helper from test.support.os_helper import TESTFN, unlink +imghdr = warnings_helper.import_deprecated("imghdr") + TEST_FILES = ( ('python.png', 'png'), diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py index 1a21025fe6e..80abc720c32 100644 --- a/Lib/test/test_imp.py +++ b/Lib/test/test_imp.py @@ -1,3 +1,4 @@ +import gc import importlib import importlib.util import os @@ -8,11 +9,10 @@ from test import support from test.support import import_helper from test.support import os_helper from test.support import script_helper +from test.support import warnings_helper import unittest import warnings -with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - import imp +imp = warnings_helper.import_deprecated('imp') import _imp @@ -23,7 +23,7 @@ def requires_load_dynamic(meth): """Decorator to skip a test if not running under CPython or lacking imp.load_dynamic().""" meth = support.cpython_only(meth) - return unittest.skipIf(not hasattr(imp, 'load_dynamic'), + return unittest.skipIf(getattr(imp, 'load_dynamic', None) is None, 'imp.load_dynamic() required')(meth) @@ -67,11 +67,7 @@ class ImportTests(unittest.TestCase): self.test_strings = mod.test_strings self.test_path = mod.__path__ - def test_import_encoded_module(self): - for modname, encoding, teststr in self.test_strings: - mod = importlib.import_module('test.encoded_modules.' - 'module_' + modname) - self.assertEqual(teststr, mod.test) + # test_import_encoded_module moved to test_source_encoding.py def test_find_module_encoding(self): for mod, encoding, _ in self.test_strings: @@ -383,6 +379,69 @@ class ImportTests(unittest.TestCase): mod = imp.load_module('mymod', file, path, description) self.assertEqual(mod.x, 42) + def test_issue98354(self): + # _imp.create_builtin should raise TypeError + # if 'name' attribute of 'spec' argument is not a 'str' instance + + create_builtin = support.get_attribute(_imp, "create_builtin") + + class FakeSpec: + def __init__(self, name): + self.name = self + spec = FakeSpec("time") + with self.assertRaises(TypeError): + create_builtin(spec) + + class FakeSpec2: + name = [1, 2, 3, 4] + spec = FakeSpec2() + with self.assertRaises(TypeError): + create_builtin(spec) + + import builtins + class UnicodeSubclass(str): + pass + class GoodSpec: + name = UnicodeSubclass("builtins") + spec = GoodSpec() + bltin = create_builtin(spec) + self.assertEqual(bltin, builtins) + + class UnicodeSubclassFakeSpec(str): + def __init__(self, name): + self.name = self + spec = UnicodeSubclassFakeSpec("builtins") + bltin = create_builtin(spec) + self.assertEqual(bltin, builtins) + + @support.cpython_only + def test_create_builtin_subinterp(self): + # gh-99578: create_builtin() behavior changes after the creation of the + # first sub-interpreter. Test both code paths, before and after the + # creation of a sub-interpreter. Previously, create_builtin() had + # a reference leak after the creation of the first sub-interpreter. + + import builtins + create_builtin = support.get_attribute(_imp, "create_builtin") + class Spec: + name = "builtins" + spec = Spec() + + def check_get_builtins(): + refcnt = sys.getrefcount(builtins) + mod = _imp.create_builtin(spec) + self.assertIs(mod, builtins) + self.assertEqual(sys.getrefcount(builtins), refcnt + 1) + # Check that a GC collection doesn't crash + gc.collect() + + check_get_builtins() + + ret = support.run_in_subinterp("import builtins") + self.assertEqual(ret, 0) + + check_get_builtins() + class ReloadTests(unittest.TestCase): diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 8857fd5000b..1e4429ed7ef 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -20,7 +20,8 @@ from unittest import mock from test.support import os_helper from test.support import ( - STDLIB_DIR, is_jython, swap_attr, swap_item, cpython_only) + STDLIB_DIR, swap_attr, swap_item, cpython_only, is_emscripten, + is_wasi) from test.support.import_helper import ( forget, make_legacy_pyc, unlink, unload, DirsOnSysPath, CleanImport) from test.support.os_helper import ( @@ -101,8 +102,17 @@ class ImportTests(unittest.TestCase): with self.assertRaises(ImportError) as cm: from _testcapi import i_dont_exist self.assertEqual(cm.exception.name, '_testcapi') - self.assertEqual(cm.exception.path, _testcapi.__file__) - self.assertRegex(str(cm.exception), r"cannot import name 'i_dont_exist' from '_testcapi' \(.*\.(so|pyd)\)") + if hasattr(_testcapi, "__file__"): + self.assertEqual(cm.exception.path, _testcapi.__file__) + self.assertRegex( + str(cm.exception), + r"cannot import name 'i_dont_exist' from '_testcapi' \(.*\.(so|pyd)\)" + ) + else: + self.assertEqual( + str(cm.exception), + "cannot import name 'i_dont_exist' from '_testcapi' (unknown location)" + ) def test_from_import_missing_attr_has_name(self): with self.assertRaises(ImportError) as cm: @@ -153,10 +163,7 @@ class ImportTests(unittest.TestCase): def test_with_extension(ext): # The extension is normally ".py", perhaps ".pyw". source = TESTFN + ext - if is_jython: - pyc = TESTFN + "$py.class" - else: - pyc = TESTFN + ".pyc" + pyc = TESTFN + ".pyc" with open(source, "w", encoding='utf-8') as f: print("# This tests Python's ability to import a", @@ -439,6 +446,7 @@ class ImportTests(unittest.TestCase): with self.assertRaises(AttributeError): os.does_not_exist + @threading_helper.requires_working_threading() def test_concurrency(self): # bpo 38091: this is a hack to slow down the code that calls # has_deadlock(); the logic was itself sometimes deadlocking. @@ -525,6 +533,10 @@ class FilePermissionTests(unittest.TestCase): @unittest.skipUnless(os.name == 'posix', "test meaningful only on posix systems") + @unittest.skipIf( + is_emscripten or is_wasi, + "Emscripten's/WASI's umask is a stub." + ) def test_creation_mode(self): mask = 0o022 with temp_umask(mask), _ready_to_import() as (name, path): @@ -542,6 +554,7 @@ class FilePermissionTests(unittest.TestCase): @unittest.skipUnless(os.name == 'posix', "test meaningful only on posix systems") + @os_helper.skip_unless_working_chmod def test_cached_mode_issue_2051(self): # permissions of .pyc should match those of .py, regardless of mask mode = 0o600 @@ -558,6 +571,7 @@ class FilePermissionTests(unittest.TestCase): @unittest.skipUnless(os.name == 'posix', "test meaningful only on posix systems") + @os_helper.skip_unless_working_chmod def test_cached_readonly(self): mode = 0o400 with temp_umask(0o022), _ready_to_import() as (name, path): @@ -868,9 +882,10 @@ class PycacheTests(unittest.TestCase): @unittest.skipUnless(os.name == 'posix', "test meaningful only on posix systems") - @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, - "due to varying filesystem permission semantics (issue #11956)") @skip_if_dont_write_bytecode + @os_helper.skip_unless_working_chmod + @os_helper.skip_if_dac_override + @unittest.skipIf(is_emscripten, "umask is a stub") def test_unwritable_directory(self): # When the umask causes the new __pycache__ directory to be # unwritable, the import still succeeds but no .pyc file is written. @@ -909,7 +924,7 @@ class PycacheTests(unittest.TestCase): m = __import__(TESTFN) try: self.assertEqual(m.__file__, - os.path.join(os.getcwd(), os.curdir, os.path.relpath(pyc_file))) + os.path.join(os.getcwd(), os.path.relpath(pyc_file))) finally: os.remove(pyc_file) @@ -917,7 +932,7 @@ class PycacheTests(unittest.TestCase): # Modules now also have an __cached__ that points to the pyc file. m = __import__(TESTFN) pyc_file = importlib.util.cache_from_source(TESTFN + '.py') - self.assertEqual(m.__cached__, os.path.join(os.getcwd(), os.curdir, pyc_file)) + self.assertEqual(m.__cached__, os.path.join(os.getcwd(), pyc_file)) @skip_if_dont_write_bytecode def test___cached___legacy_pyc(self): @@ -933,7 +948,7 @@ class PycacheTests(unittest.TestCase): importlib.invalidate_caches() m = __import__(TESTFN) self.assertEqual(m.__cached__, - os.path.join(os.getcwd(), os.curdir, os.path.relpath(pyc_file))) + os.path.join(os.getcwd(), os.path.relpath(pyc_file))) @skip_if_dont_write_bytecode def test_package___cached__(self): @@ -953,10 +968,10 @@ class PycacheTests(unittest.TestCase): m = __import__('pep3147.foo') init_pyc = importlib.util.cache_from_source( os.path.join('pep3147', '__init__.py')) - self.assertEqual(m.__cached__, os.path.join(os.getcwd(), os.curdir, init_pyc)) + self.assertEqual(m.__cached__, os.path.join(os.getcwd(), init_pyc)) foo_pyc = importlib.util.cache_from_source(os.path.join('pep3147', 'foo.py')) self.assertEqual(sys.modules['pep3147.foo'].__cached__, - os.path.join(os.getcwd(), os.curdir, foo_pyc)) + os.path.join(os.getcwd(), foo_pyc)) def test_package___cached___from_pyc(self): # Like test___cached__ but ensuring __cached__ when imported from a @@ -980,10 +995,10 @@ class PycacheTests(unittest.TestCase): m = __import__('pep3147.foo') init_pyc = importlib.util.cache_from_source( os.path.join('pep3147', '__init__.py')) - self.assertEqual(m.__cached__, os.path.join(os.getcwd(), os.curdir, init_pyc)) + self.assertEqual(m.__cached__, os.path.join(os.getcwd(), init_pyc)) foo_pyc = importlib.util.cache_from_source(os.path.join('pep3147', 'foo.py')) self.assertEqual(sys.modules['pep3147.foo'].__cached__, - os.path.join(os.getcwd(), os.curdir, foo_pyc)) + os.path.join(os.getcwd(), foo_pyc)) def test_recompute_pyc_same_second(self): # Even when the source file doesn't change timestamp, a change in diff --git a/Lib/test/test_importlib/builtin/test_finder.py b/Lib/test/test_importlib/builtin/test_finder.py index 6f51abab9bc..a4869e07b9c 100644 --- a/Lib/test/test_importlib/builtin/test_finder.py +++ b/Lib/test/test_importlib/builtin/test_finder.py @@ -1,5 +1,4 @@ -from .. import abc -from .. import util +from test.test_importlib import abc, util machinery = util.import_importlib('importlib.machinery') diff --git a/Lib/test/test_importlib/builtin/test_loader.py b/Lib/test/test_importlib/builtin/test_loader.py index f6b6d97cd5b..7e9d1b1960f 100644 --- a/Lib/test/test_importlib/builtin/test_loader.py +++ b/Lib/test/test_importlib/builtin/test_loader.py @@ -1,5 +1,4 @@ -from .. import abc -from .. import util +from test.test_importlib import abc, util machinery = util.import_importlib('importlib.machinery') diff --git a/Lib/test/test_importlib/data/example2-1.0.0-py3-none-any.whl b/Lib/test/test_importlib/data/example2-1.0.0-py3-none-any.whl new file mode 100644 index 00000000000..5ca93657f81 Binary files /dev/null and b/Lib/test/test_importlib/data/example2-1.0.0-py3-none-any.whl differ diff --git a/Lib/test/test_importlib/extension/test_case_sensitivity.py b/Lib/test/test_importlib/extension/test_case_sensitivity.py index 20bf035cb5f..0bb74fff5fc 100644 --- a/Lib/test/test_importlib/extension/test_case_sensitivity.py +++ b/Lib/test/test_importlib/extension/test_case_sensitivity.py @@ -2,13 +2,13 @@ from importlib import _bootstrap_external from test.support import os_helper import unittest import sys -from .. import util +from test.test_importlib import util importlib = util.import_importlib('importlib') machinery = util.import_importlib('importlib.machinery') -@unittest.skipIf(util.EXTENSIONS.filename is None, '_testcapi not available') +@unittest.skipIf(util.EXTENSIONS.filename is None, f'{util.EXTENSIONS.name} not available') @util.case_insensitive_tests class ExtensionModuleCaseSensitivityTest(util.CASEOKTestBase): diff --git a/Lib/test/test_importlib/extension/test_finder.py b/Lib/test/test_importlib/extension/test_finder.py index e8065d7dade..1d5b6e7a5de 100644 --- a/Lib/test/test_importlib/extension/test_finder.py +++ b/Lib/test/test_importlib/extension/test_finder.py @@ -1,16 +1,23 @@ -from .. import abc -from .. import util +from test.test_importlib import abc, util machinery = util.import_importlib('importlib.machinery') import unittest -import warnings +import sys class FinderTests(abc.FinderTests): """Test the finder for extension modules.""" + def setUp(self): + if not self.machinery.EXTENSION_SUFFIXES: + raise unittest.SkipTest("Requires dynamic loading support.") + if util.EXTENSIONS.name in sys.builtin_module_names: + raise unittest.SkipTest( + f"{util.EXTENSIONS.name} is a builtin module" + ) + def find_spec(self, fullname): importer = self.machinery.FileFinder(util.EXTENSIONS.path, (self.machinery.ExtensionFileLoader, diff --git a/Lib/test/test_importlib/extension/test_loader.py b/Lib/test/test_importlib/extension/test_loader.py index 8fd556dbed5..3bf2bbdcdcc 100644 --- a/Lib/test/test_importlib/extension/test_loader.py +++ b/Lib/test/test_importlib/extension/test_loader.py @@ -1,6 +1,5 @@ from warnings import catch_warnings -from .. import abc -from .. import util +from test.test_importlib import abc, util machinery = util.import_importlib('importlib.machinery') @@ -13,11 +12,18 @@ import importlib.util import importlib from test.support.script_helper import assert_python_failure -class LoaderTests(abc.LoaderTests): - """Test load_module() for extension modules.""" +class LoaderTests: + + """Test ExtensionFileLoader.""" def setUp(self): + if not self.machinery.EXTENSION_SUFFIXES: + raise unittest.SkipTest("Requires dynamic loading support.") + if util.EXTENSIONS.name in sys.builtin_module_names: + raise unittest.SkipTest( + f"{util.EXTENSIONS.name} is a builtin module" + ) self.loader = self.machinery.ExtensionFileLoader(util.EXTENSIONS.name, util.EXTENSIONS.file_path) @@ -26,15 +32,6 @@ class LoaderTests(abc.LoaderTests): warnings.simplefilter("ignore", DeprecationWarning) return self.loader.load_module(fullname) - def test_load_module_API(self): - # Test the default argument for load_module(). - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - self.loader.load_module() - self.loader.load_module(None) - with self.assertRaises(ImportError): - self.load_module('XXX') - def test_equality(self): other = self.machinery.ExtensionFileLoader(util.EXTENSIONS.name, util.EXTENSIONS.file_path) @@ -45,6 +42,15 @@ class LoaderTests(abc.LoaderTests): util.EXTENSIONS.file_path) self.assertNotEqual(self.loader, other) + def test_load_module_API(self): + # Test the default argument for load_module(). + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + self.loader.load_module() + self.loader.load_module(None) + with self.assertRaises(ImportError): + self.load_module('XXX') + def test_module(self): with util.uncache(util.EXTENSIONS.name): module = self.load_module(util.EXTENSIONS.name) @@ -62,12 +68,6 @@ class LoaderTests(abc.LoaderTests): # No extension module in a package available for testing. test_lacking_parent = None - def test_module_reuse(self): - with util.uncache(util.EXTENSIONS.name): - module1 = self.load_module(util.EXTENSIONS.name) - module2 = self.load_module(util.EXTENSIONS.name) - self.assertIs(module1, module2) - # No easy way to trigger a failure after a successful import. test_state_after_failure = None @@ -77,6 +77,12 @@ class LoaderTests(abc.LoaderTests): self.load_module(name) self.assertEqual(cm.exception.name, name) + def test_module_reuse(self): + with util.uncache(util.EXTENSIONS.name): + module1 = self.load_module(util.EXTENSIONS.name) + module2 = self.load_module(util.EXTENSIONS.name) + self.assertIs(module1, module2) + def test_is_package(self): self.assertFalse(self.loader.is_package(util.EXTENSIONS.name)) for suffix in self.machinery.EXTENSION_SUFFIXES: @@ -84,15 +90,104 @@ class LoaderTests(abc.LoaderTests): loader = self.machinery.ExtensionFileLoader('pkg', path) self.assertTrue(loader.is_package('pkg')) + (Frozen_LoaderTests, Source_LoaderTests ) = util.test_both(LoaderTests, machinery=machinery) + +class SinglePhaseExtensionModuleTests(abc.LoaderTests): + # Test loading extension modules without multi-phase initialization. + + def setUp(self): + if not self.machinery.EXTENSION_SUFFIXES: + raise unittest.SkipTest("Requires dynamic loading support.") + self.name = '_testsinglephase' + if self.name in sys.builtin_module_names: + raise unittest.SkipTest( + f"{self.name} is a builtin module" + ) + finder = self.machinery.FileFinder(None) + self.spec = importlib.util.find_spec(self.name) + assert self.spec + self.loader = self.machinery.ExtensionFileLoader( + self.name, self.spec.origin) + + def load_module(self): + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + return self.loader.load_module(self.name) + + def load_module_by_name(self, fullname): + # Load a module from the test extension by name. + origin = self.spec.origin + loader = self.machinery.ExtensionFileLoader(fullname, origin) + spec = importlib.util.spec_from_loader(fullname, loader) + module = importlib.util.module_from_spec(spec) + loader.exec_module(module) + return module + + def test_module(self): + # Test loading an extension module. + with util.uncache(self.name): + module = self.load_module() + for attr, value in [('__name__', self.name), + ('__file__', self.spec.origin), + ('__package__', '')]: + self.assertEqual(getattr(module, attr), value) + with self.assertRaises(AttributeError): + module.__path__ + self.assertIs(module, sys.modules[self.name]) + self.assertIsInstance(module.__loader__, + self.machinery.ExtensionFileLoader) + + # No extension module as __init__ available for testing. + test_package = None + + # No extension module in a package available for testing. + test_lacking_parent = None + + # No easy way to trigger a failure after a successful import. + test_state_after_failure = None + + def test_unloadable(self): + name = 'asdfjkl;' + with self.assertRaises(ImportError) as cm: + self.load_module_by_name(name) + self.assertEqual(cm.exception.name, name) + + def test_unloadable_nonascii(self): + # Test behavior with nonexistent module with non-ASCII name. + name = 'fo\xf3' + with self.assertRaises(ImportError) as cm: + self.load_module_by_name(name) + self.assertEqual(cm.exception.name, name) + + # It may make sense to add the equivalent to + # the following MultiPhaseExtensionModuleTests tests: + # + # * test_nonmodule + # * test_nonmodule_with_methods + # * test_bad_modules + # * test_nonascii + + +(Frozen_SinglePhaseExtensionModuleTests, + Source_SinglePhaseExtensionModuleTests + ) = util.test_both(SinglePhaseExtensionModuleTests, machinery=machinery) + + class MultiPhaseExtensionModuleTests(abc.LoaderTests): # Test loading extension modules with multi-phase initialization (PEP 489). def setUp(self): + if not self.machinery.EXTENSION_SUFFIXES: + raise unittest.SkipTest("Requires dynamic loading support.") self.name = '_testmultiphase' + if self.name in sys.builtin_module_names: + raise unittest.SkipTest( + f"{self.name} is a builtin module" + ) finder = self.machinery.FileFinder(None) self.spec = importlib.util.find_spec(self.name) assert self.spec @@ -256,9 +351,14 @@ class MultiPhaseExtensionModuleTests(abc.LoaderTests): ]: with self.subTest(name_base): name = self.name + '_' + name_base - with self.assertRaises(SystemError): + with self.assertRaises(SystemError) as cm: self.load_module_by_name(name) + # If there is an unreported exception, it should be chained + # with the `SystemError`. + if "unreported_exception" in name_base: + self.assertIsNotNone(cm.exception.__cause__) + def test_nonascii(self): # Test that modules with non-ASCII names can be loaded. # punycode behaves slightly differently in some-ASCII and no-ASCII diff --git a/Lib/test/test_importlib/extension/test_path_hook.py b/Lib/test/test_importlib/extension/test_path_hook.py index a4b5a64aae2..a0adc70ad1e 100644 --- a/Lib/test/test_importlib/extension/test_path_hook.py +++ b/Lib/test/test_importlib/extension/test_path_hook.py @@ -1,4 +1,4 @@ -from .. import util +from test.test_importlib import util machinery = util.import_importlib('importlib.machinery') diff --git a/Lib/test/test_importlib/fixtures.py b/Lib/test/test_importlib/fixtures.py index 12ed07d3374..e7be77b3957 100644 --- a/Lib/test/test_importlib/fixtures.py +++ b/Lib/test/test_importlib/fixtures.py @@ -5,11 +5,21 @@ import shutil import pathlib import tempfile import textwrap +import functools import contextlib from test.support.os_helper import FS_NONASCII +from test.support import requires_zlib from typing import Dict, Union +try: + from importlib import resources # type: ignore + + getattr(resources, 'files') + getattr(resources, 'as_file') +except (ImportError, AttributeError): + import importlib_resources as resources # type: ignore + @contextlib.contextmanager def tempdir(): @@ -54,7 +64,7 @@ class Fixtures: class SiteDir(Fixtures): def setUp(self): - super(SiteDir, self).setUp() + super().setUp() self.site_dir = self.fixtures.enter_context(tempdir()) @@ -69,7 +79,7 @@ class OnSysPath(Fixtures): sys.path.remove(str(dir)) def setUp(self): - super(OnSysPath, self).setUp() + super().setUp() self.fixtures.enter_context(self.add_sys_path(self.site_dir)) @@ -106,7 +116,7 @@ class DistInfoPkg(OnSysPath, SiteDir): } def setUp(self): - super(DistInfoPkg, self).setUp() + super().setUp() build_files(DistInfoPkg.files, self.site_dir) def make_uppercase(self): @@ -131,7 +141,7 @@ class DistInfoPkgWithDot(OnSysPath, SiteDir): } def setUp(self): - super(DistInfoPkgWithDot, self).setUp() + super().setUp() build_files(DistInfoPkgWithDot.files, self.site_dir) @@ -152,13 +162,13 @@ class DistInfoPkgWithDotLegacy(OnSysPath, SiteDir): } def setUp(self): - super(DistInfoPkgWithDotLegacy, self).setUp() + super().setUp() build_files(DistInfoPkgWithDotLegacy.files, self.site_dir) class DistInfoPkgOffPath(SiteDir): def setUp(self): - super(DistInfoPkgOffPath, self).setUp() + super().setUp() build_files(DistInfoPkg.files, self.site_dir) @@ -198,7 +208,7 @@ class EggInfoPkg(OnSysPath, SiteDir): } def setUp(self): - super(EggInfoPkg, self).setUp() + super().setUp() build_files(EggInfoPkg.files, prefix=self.site_dir) @@ -219,25 +229,10 @@ class EggInfoFile(OnSysPath, SiteDir): } def setUp(self): - super(EggInfoFile, self).setUp() + super().setUp() build_files(EggInfoFile.files, prefix=self.site_dir) -class LocalPackage: - files: FilesDef = { - "setup.py": """ - import setuptools - setuptools.setup(name="local-pkg", version="2.0.1") - """, - } - - def setUp(self): - self.fixtures = contextlib.ExitStack() - self.addCleanup(self.fixtures.close) - self.fixtures.enter_context(tempdir_as_cwd()) - build_files(self.files) - - def build_files(file_defs, prefix=pathlib.Path()): """Build a set of files/directories, as described by the @@ -285,3 +280,35 @@ def DALS(str): class NullFinder: def find_module(self, name): pass + + +@requires_zlib() +class ZipFixtures: + root = 'test.test_importlib.data' + + def _fixture_on_path(self, filename): + pkg_file = resources.files(self.root).joinpath(filename) + file = self.resources.enter_context(resources.as_file(pkg_file)) + assert file.name.startswith('example'), file.name + sys.path.insert(0, str(file)) + self.resources.callback(sys.path.pop, 0) + + def setUp(self): + # Add self.zip_name to the front of sys.path. + self.resources = contextlib.ExitStack() + self.addCleanup(self.resources.close) + + +def parameterize(*args_set): + """Run test method with a series of parameters.""" + + def wrapper(func): + @functools.wraps(func) + def _inner(self): + for args in args_set: + with self.subTest(**args): + func(self, **args) + + return _inner + + return wrapper diff --git a/Lib/test/test_importlib/frozen/test_finder.py b/Lib/test/test_importlib/frozen/test_finder.py index 66080b2ade0..069755606b4 100644 --- a/Lib/test/test_importlib/frozen/test_finder.py +++ b/Lib/test/test_importlib/frozen/test_finder.py @@ -1,5 +1,4 @@ -from .. import abc -from .. import util +from test.test_importlib import abc, util machinery = util.import_importlib('importlib.machinery') diff --git a/Lib/test/test_importlib/frozen/test_loader.py b/Lib/test/test_importlib/frozen/test_loader.py index f1ccb8a188a..da1569e3d06 100644 --- a/Lib/test/test_importlib/frozen/test_loader.py +++ b/Lib/test/test_importlib/frozen/test_loader.py @@ -1,5 +1,4 @@ -from .. import abc -from .. import util +from test.test_importlib import abc, util machinery = util.import_importlib('importlib.machinery') @@ -104,15 +103,7 @@ class ExecModuleTests(abc.LoaderTests): expected=value)) self.assertEqual(output, 'Hello world!\n') - def test_module_repr(self): - name = '__hello__' - module, output = self.exec_module(name) - with deprecated(): - repr_str = self.machinery.FrozenImporter.module_repr(module) - self.assertEqual(repr_str, - "") - - def test_module_repr_indirect(self): + def test_module_repr_indirect_through_spec(self): name = '__hello__' module, output = self.exec_module(name) self.assertEqual(repr(module), @@ -199,13 +190,6 @@ class LoaderTests(abc.LoaderTests): self.assertEqual(stdout.getvalue(), 'Hello world!\nHello world!\n') - def test_module_repr(self): - with fresh('__hello__', oldapi=True): - module = self.machinery.FrozenImporter.load_module('__hello__') - repr_str = self.machinery.FrozenImporter.module_repr(module) - self.assertEqual(repr_str, - "") - # No way to trigger an error in a frozen module. test_state_after_failure = None diff --git a/Lib/test/test_importlib/import_/test___loader__.py b/Lib/test/test_importlib/import_/test___loader__.py index ecd83c6567e..eaf665a6f5b 100644 --- a/Lib/test/test_importlib/import_/test___loader__.py +++ b/Lib/test/test_importlib/import_/test___loader__.py @@ -4,7 +4,7 @@ import types import unittest import warnings -from .. import util +from test.test_importlib import util class SpecLoaderMock: diff --git a/Lib/test/test_importlib/import_/test___package__.py b/Lib/test/test_importlib/import_/test___package__.py index 4a2b34e5f67..ab1b35ee3c1 100644 --- a/Lib/test/test_importlib/import_/test___package__.py +++ b/Lib/test/test_importlib/import_/test___package__.py @@ -6,7 +6,7 @@ of using the typical __path__/__name__ test). """ import unittest import warnings -from .. import util +from test.test_importlib import util class Using__package__: @@ -74,8 +74,8 @@ class Using__package__: self.assertEqual(module.__name__, 'pkg') def test_warn_when_package_and_spec_disagree(self): - # Raise an ImportWarning if __package__ != __spec__.parent. - with self.assertWarns(ImportWarning): + # Raise a DeprecationWarning if __package__ != __spec__.parent. + with self.assertWarns(DeprecationWarning): self.import_module({'__package__': 'pkg.fake', '__spec__': FakeSpec('pkg.fakefake')}) diff --git a/Lib/test/test_importlib/import_/test_api.py b/Lib/test/test_importlib/import_/test_api.py index 35c26977ea3..0ee032b0206 100644 --- a/Lib/test/test_importlib/import_/test_api.py +++ b/Lib/test/test_importlib/import_/test_api.py @@ -1,4 +1,4 @@ -from .. import util +from test.test_importlib import util from importlib import machinery import sys diff --git a/Lib/test/test_importlib/import_/test_caching.py b/Lib/test/test_importlib/import_/test_caching.py index 0f987b22100..3ca765fb4ad 100644 --- a/Lib/test/test_importlib/import_/test_caching.py +++ b/Lib/test/test_importlib/import_/test_caching.py @@ -1,5 +1,5 @@ """Test that sys.modules is used properly by import.""" -from .. import util +from test.test_importlib import util import sys from types import MethodType import unittest diff --git a/Lib/test/test_importlib/import_/test_fromlist.py b/Lib/test/test_importlib/import_/test_fromlist.py index deb21710a61..4b4b9bc3f5e 100644 --- a/Lib/test/test_importlib/import_/test_fromlist.py +++ b/Lib/test/test_importlib/import_/test_fromlist.py @@ -1,5 +1,5 @@ """Test that the semantics relating to the 'fromlist' argument are correct.""" -from .. import util +from test.test_importlib import util import warnings import unittest diff --git a/Lib/test/test_importlib/import_/test_helpers.py b/Lib/test/test_importlib/import_/test_helpers.py new file mode 100644 index 00000000000..550f88d1d7a --- /dev/null +++ b/Lib/test/test_importlib/import_/test_helpers.py @@ -0,0 +1,184 @@ +"""Tests for helper functions used by import.c .""" + +from importlib import _bootstrap_external, machinery +import os.path +from types import ModuleType, SimpleNamespace +import unittest +import warnings + +from .. import util + + +class FixUpModuleTests: + + def test_no_loader_but_spec(self): + loader = object() + name = "hello" + path = "hello.py" + spec = machinery.ModuleSpec(name, loader) + ns = {"__spec__": spec} + _bootstrap_external._fix_up_module(ns, name, path) + + expected = {"__spec__": spec, "__loader__": loader, "__file__": path, + "__cached__": None} + self.assertEqual(ns, expected) + + def test_no_loader_no_spec_but_sourceless(self): + name = "hello" + path = "hello.py" + ns = {} + _bootstrap_external._fix_up_module(ns, name, path, path) + + expected = {"__file__": path, "__cached__": path} + + for key, val in expected.items(): + with self.subTest(f"{key}: {val}"): + self.assertEqual(ns[key], val) + + spec = ns["__spec__"] + self.assertIsInstance(spec, machinery.ModuleSpec) + self.assertEqual(spec.name, name) + self.assertEqual(spec.origin, os.path.abspath(path)) + self.assertEqual(spec.cached, os.path.abspath(path)) + self.assertIsInstance(spec.loader, machinery.SourcelessFileLoader) + self.assertEqual(spec.loader.name, name) + self.assertEqual(spec.loader.path, path) + self.assertEqual(spec.loader, ns["__loader__"]) + + def test_no_loader_no_spec_but_source(self): + name = "hello" + path = "hello.py" + ns = {} + _bootstrap_external._fix_up_module(ns, name, path) + + expected = {"__file__": path, "__cached__": None} + + for key, val in expected.items(): + with self.subTest(f"{key}: {val}"): + self.assertEqual(ns[key], val) + + spec = ns["__spec__"] + self.assertIsInstance(spec, machinery.ModuleSpec) + self.assertEqual(spec.name, name) + self.assertEqual(spec.origin, os.path.abspath(path)) + self.assertIsInstance(spec.loader, machinery.SourceFileLoader) + self.assertEqual(spec.loader.name, name) + self.assertEqual(spec.loader.path, path) + self.assertEqual(spec.loader, ns["__loader__"]) + + +FrozenFixUpModuleTests, SourceFixUpModuleTests = util.test_both(FixUpModuleTests) + + +class TestBlessMyLoader(unittest.TestCase): + # GH#86298 is part of the migration away from module attributes and toward + # __spec__ attributes. There are several cases to test here. This will + # have to change in Python 3.14 when we actually remove/ignore __loader__ + # in favor of requiring __spec__.loader. + + def test_gh86298_no_loader_and_no_spec(self): + bar = ModuleType('bar') + del bar.__loader__ + del bar.__spec__ + # 2022-10-06(warsaw): For backward compatibility with the + # implementation in _warnings.c, this can't raise an + # AttributeError. See _bless_my_loader() in _bootstrap_external.py + # If working with a module: + ## self.assertRaises( + ## AttributeError, _bootstrap_external._bless_my_loader, + ## bar.__dict__) + self.assertIsNone(_bootstrap_external._bless_my_loader(bar.__dict__)) + + def test_gh86298_loader_is_none_and_no_spec(self): + bar = ModuleType('bar') + bar.__loader__ = None + del bar.__spec__ + # 2022-10-06(warsaw): For backward compatibility with the + # implementation in _warnings.c, this can't raise an + # AttributeError. See _bless_my_loader() in _bootstrap_external.py + # If working with a module: + ## self.assertRaises( + ## AttributeError, _bootstrap_external._bless_my_loader, + ## bar.__dict__) + self.assertIsNone(_bootstrap_external._bless_my_loader(bar.__dict__)) + + def test_gh86298_no_loader_and_spec_is_none(self): + bar = ModuleType('bar') + del bar.__loader__ + bar.__spec__ = None + self.assertRaises( + ValueError, + _bootstrap_external._bless_my_loader, bar.__dict__) + + def test_gh86298_loader_is_none_and_spec_is_none(self): + bar = ModuleType('bar') + bar.__loader__ = None + bar.__spec__ = None + self.assertRaises( + ValueError, + _bootstrap_external._bless_my_loader, bar.__dict__) + + def test_gh86298_loader_is_none_and_spec_loader_is_none(self): + bar = ModuleType('bar') + bar.__loader__ = None + bar.__spec__ = SimpleNamespace(loader=None) + self.assertRaises( + ValueError, + _bootstrap_external._bless_my_loader, bar.__dict__) + + def test_gh86298_no_spec(self): + bar = ModuleType('bar') + bar.__loader__ = object() + del bar.__spec__ + with warnings.catch_warnings(): + self.assertWarns( + DeprecationWarning, + _bootstrap_external._bless_my_loader, bar.__dict__) + + def test_gh86298_spec_is_none(self): + bar = ModuleType('bar') + bar.__loader__ = object() + bar.__spec__ = None + with warnings.catch_warnings(): + self.assertWarns( + DeprecationWarning, + _bootstrap_external._bless_my_loader, bar.__dict__) + + def test_gh86298_no_spec_loader(self): + bar = ModuleType('bar') + bar.__loader__ = object() + bar.__spec__ = SimpleNamespace() + with warnings.catch_warnings(): + self.assertWarns( + DeprecationWarning, + _bootstrap_external._bless_my_loader, bar.__dict__) + + def test_gh86298_loader_and_spec_loader_disagree(self): + bar = ModuleType('bar') + bar.__loader__ = object() + bar.__spec__ = SimpleNamespace(loader=object()) + with warnings.catch_warnings(): + self.assertWarns( + DeprecationWarning, + _bootstrap_external._bless_my_loader, bar.__dict__) + + def test_gh86298_no_loader_and_no_spec_loader(self): + bar = ModuleType('bar') + del bar.__loader__ + bar.__spec__ = SimpleNamespace() + self.assertRaises( + AttributeError, + _bootstrap_external._bless_my_loader, bar.__dict__) + + def test_gh86298_no_loader_with_spec_loader_okay(self): + bar = ModuleType('bar') + del bar.__loader__ + loader = object() + bar.__spec__ = SimpleNamespace(loader=loader) + self.assertEqual( + _bootstrap_external._bless_my_loader(bar.__dict__), + loader) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_importlib/import_/test_meta_path.py b/Lib/test/test_importlib/import_/test_meta_path.py index 5730119fe99..c8b898ec237 100644 --- a/Lib/test/test_importlib/import_/test_meta_path.py +++ b/Lib/test/test_importlib/import_/test_meta_path.py @@ -1,4 +1,4 @@ -from .. import util +from test.test_importlib import util import importlib._bootstrap import sys from types import MethodType diff --git a/Lib/test/test_importlib/import_/test_packages.py b/Lib/test/test_importlib/import_/test_packages.py index c73ac63f6ee..eb0831f7d6d 100644 --- a/Lib/test/test_importlib/import_/test_packages.py +++ b/Lib/test/test_importlib/import_/test_packages.py @@ -1,4 +1,4 @@ -from .. import util +from test.test_importlib import util import sys import unittest from test import support diff --git a/Lib/test/test_importlib/import_/test_path.py b/Lib/test/test_importlib/import_/test_path.py index 57a25228fc0..de620842bbc 100644 --- a/Lib/test/test_importlib/import_/test_path.py +++ b/Lib/test/test_importlib/import_/test_path.py @@ -1,4 +1,4 @@ -from .. import util +from test.test_importlib import util importlib = util.import_importlib('importlib') machinery = util.import_importlib('importlib.machinery') @@ -202,10 +202,11 @@ class FinderTests: def invalidate_caches(self): self.called = True - cache = {'leave_alone': object(), 'finder_to_invalidate': FakeFinder()} + key = os.path.abspath('finder_to_invalidate') + cache = {'leave_alone': object(), key: FakeFinder()} with util.import_state(path_importer_cache=cache): self.machinery.PathFinder.invalidate_caches() - self.assertTrue(cache['finder_to_invalidate'].called) + self.assertTrue(cache[key].called) def test_invalidate_caches_clear_out_None(self): # Clear out None in sys.path_importer_cache() when invalidating caches. @@ -214,6 +215,16 @@ class FinderTests: self.machinery.PathFinder.invalidate_caches() self.assertEqual(len(cache), 0) + def test_invalidate_caches_clear_out_relative_path(self): + class FakeFinder: + def invalidate_caches(self): + pass + + cache = {'relative_path': FakeFinder()} + with util.import_state(path_importer_cache=cache): + self.machinery.PathFinder.invalidate_caches() + self.assertEqual(cache, {}) + class FindModuleTests(FinderTests): def find(self, *args, **kwargs): diff --git a/Lib/test/test_importlib/import_/test_relative_imports.py b/Lib/test/test_importlib/import_/test_relative_imports.py index 41aa1826995..99c24f1fd94 100644 --- a/Lib/test/test_importlib/import_/test_relative_imports.py +++ b/Lib/test/test_importlib/import_/test_relative_imports.py @@ -1,5 +1,5 @@ """Test relative imports (PEP 328).""" -from .. import util +from test.test_importlib import util import unittest import warnings diff --git a/Lib/test/test_importlib/resources/_path.py b/Lib/test/test_importlib/resources/_path.py new file mode 100644 index 00000000000..c630e4d3d3f --- /dev/null +++ b/Lib/test/test_importlib/resources/_path.py @@ -0,0 +1,50 @@ +import pathlib +import functools + + +#### +# from jaraco.path 3.4 + + +def build(spec, prefix=pathlib.Path()): + """ + Build a set of files/directories, as described by the spec. + + Each key represents a pathname, and the value represents + the content. Content may be a nested directory. + + >>> spec = { + ... 'README.txt': "A README file", + ... "foo": { + ... "__init__.py": "", + ... "bar": { + ... "__init__.py": "", + ... }, + ... "baz.py": "# Some code", + ... } + ... } + >>> tmpdir = getfixture('tmpdir') + >>> build(spec, tmpdir) + """ + for name, contents in spec.items(): + create(contents, pathlib.Path(prefix) / name) + + +@functools.singledispatch +def create(content, path): + path.mkdir(exist_ok=True) + build(content, prefix=path) # type: ignore + + +@create.register +def _(content: bytes, path): + path.write_bytes(content) + + +@create.register +def _(content: str, path): + path.write_text(content) + + +# end from jaraco.path +#### diff --git a/Lib/lib2to3/tests/data/fixers/myfixes/__init__.py b/Lib/test/test_importlib/resources/data01/__init__.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/myfixes/__init__.py rename to Lib/test/test_importlib/resources/data01/__init__.py diff --git a/Lib/test/test_importlib/data01/binary.file b/Lib/test/test_importlib/resources/data01/binary.file similarity index 100% rename from Lib/test/test_importlib/data01/binary.file rename to Lib/test/test_importlib/resources/data01/binary.file diff --git a/Lib/test/test_importlib/data01/__init__.py b/Lib/test/test_importlib/resources/data01/subdirectory/__init__.py similarity index 100% rename from Lib/test/test_importlib/data01/__init__.py rename to Lib/test/test_importlib/resources/data01/subdirectory/__init__.py diff --git a/Lib/test/test_importlib/data01/subdirectory/binary.file b/Lib/test/test_importlib/resources/data01/subdirectory/binary.file similarity index 100% rename from Lib/test/test_importlib/data01/subdirectory/binary.file rename to Lib/test/test_importlib/resources/data01/subdirectory/binary.file diff --git a/Lib/test/test_importlib/data01/utf-16.file b/Lib/test/test_importlib/resources/data01/utf-16.file similarity index 100% rename from Lib/test/test_importlib/data01/utf-16.file rename to Lib/test/test_importlib/resources/data01/utf-16.file diff --git a/Lib/test/test_importlib/data01/utf-8.file b/Lib/test/test_importlib/resources/data01/utf-8.file similarity index 100% rename from Lib/test/test_importlib/data01/utf-8.file rename to Lib/test/test_importlib/resources/data01/utf-8.file diff --git a/Lib/test/test_importlib/data01/subdirectory/__init__.py b/Lib/test/test_importlib/resources/data02/__init__.py similarity index 100% rename from Lib/test/test_importlib/data01/subdirectory/__init__.py rename to Lib/test/test_importlib/resources/data02/__init__.py diff --git a/Lib/test/test_importlib/data02/__init__.py b/Lib/test/test_importlib/resources/data02/one/__init__.py similarity index 100% rename from Lib/test/test_importlib/data02/__init__.py rename to Lib/test/test_importlib/resources/data02/one/__init__.py diff --git a/Lib/test/test_importlib/data02/one/resource1.txt b/Lib/test/test_importlib/resources/data02/one/resource1.txt similarity index 100% rename from Lib/test/test_importlib/data02/one/resource1.txt rename to Lib/test/test_importlib/resources/data02/one/resource1.txt diff --git a/Lib/test/test_importlib/data02/one/__init__.py b/Lib/test/test_importlib/resources/data02/two/__init__.py similarity index 100% rename from Lib/test/test_importlib/data02/one/__init__.py rename to Lib/test/test_importlib/resources/data02/two/__init__.py diff --git a/Lib/test/test_importlib/data02/two/resource2.txt b/Lib/test/test_importlib/resources/data02/two/resource2.txt similarity index 100% rename from Lib/test/test_importlib/data02/two/resource2.txt rename to Lib/test/test_importlib/resources/data02/two/resource2.txt diff --git a/Lib/test/test_importlib/data02/two/__init__.py b/Lib/test/test_importlib/resources/data03/__init__.py similarity index 100% rename from Lib/test/test_importlib/data02/two/__init__.py rename to Lib/test/test_importlib/resources/data03/__init__.py diff --git a/Lib/test/test_importlib/data03/__init__.py b/Lib/test/test_importlib/resources/data03/namespace/portion1/__init__.py similarity index 100% rename from Lib/test/test_importlib/data03/__init__.py rename to Lib/test/test_importlib/resources/data03/namespace/portion1/__init__.py diff --git a/Lib/test/test_importlib/data03/namespace/portion1/__init__.py b/Lib/test/test_importlib/resources/data03/namespace/portion2/__init__.py similarity index 100% rename from Lib/test/test_importlib/data03/namespace/portion1/__init__.py rename to Lib/test/test_importlib/resources/data03/namespace/portion2/__init__.py diff --git a/Lib/test/test_importlib/data03/namespace/resource1.txt b/Lib/test/test_importlib/resources/data03/namespace/resource1.txt similarity index 100% rename from Lib/test/test_importlib/data03/namespace/resource1.txt rename to Lib/test/test_importlib/resources/data03/namespace/resource1.txt diff --git a/Lib/test/test_importlib/namespacedata01/binary.file b/Lib/test/test_importlib/resources/namespacedata01/binary.file similarity index 100% rename from Lib/test/test_importlib/namespacedata01/binary.file rename to Lib/test/test_importlib/resources/namespacedata01/binary.file diff --git a/Lib/test/test_importlib/namespacedata01/utf-16.file b/Lib/test/test_importlib/resources/namespacedata01/utf-16.file similarity index 100% rename from Lib/test/test_importlib/namespacedata01/utf-16.file rename to Lib/test/test_importlib/resources/namespacedata01/utf-16.file diff --git a/Lib/test/test_importlib/namespacedata01/utf-8.file b/Lib/test/test_importlib/resources/namespacedata01/utf-8.file similarity index 100% rename from Lib/test/test_importlib/namespacedata01/utf-8.file rename to Lib/test/test_importlib/resources/namespacedata01/utf-8.file diff --git a/Lib/test/test_importlib/test_compatibilty_files.py b/Lib/test/test_importlib/resources/test_compatibilty_files.py similarity index 98% rename from Lib/test/test_importlib/test_compatibilty_files.py rename to Lib/test/test_importlib/resources/test_compatibilty_files.py index d703c060c44..6fa18a24973 100644 --- a/Lib/test/test_importlib/test_compatibilty_files.py +++ b/Lib/test/test_importlib/resources/test_compatibilty_files.py @@ -3,12 +3,12 @@ import unittest from importlib import resources -from importlib._adapters import ( +from importlib.resources._adapters import ( CompatibilityFiles, wrap_spec, ) -from .resources import util +from . import util class CompatibilityFilesTests(unittest.TestCase): diff --git a/Lib/test/test_importlib/test_contents.py b/Lib/test/test_importlib/resources/test_contents.py similarity index 85% rename from Lib/test/test_importlib/test_contents.py rename to Lib/test/test_importlib/resources/test_contents.py index 0f3aa84f5b5..1a13f043a86 100644 --- a/Lib/test/test_importlib/test_contents.py +++ b/Lib/test/test_importlib/resources/test_contents.py @@ -2,7 +2,7 @@ import unittest from importlib import resources from . import data01 -from .resources import util +from . import util class ContentsTests: @@ -15,7 +15,8 @@ class ContentsTests: } def test_contents(self): - assert self.expected <= set(resources.contents(self.data)) + contents = {path.name for path in resources.files(self.data).iterdir()} + assert self.expected <= contents class ContentsDiskTests(ContentsTests, unittest.TestCase): diff --git a/Lib/test/test_importlib/resources/test_files.py b/Lib/test/test_importlib/resources/test_files.py new file mode 100644 index 00000000000..fe813ae7d08 --- /dev/null +++ b/Lib/test/test_importlib/resources/test_files.py @@ -0,0 +1,113 @@ +import typing +import textwrap +import unittest +import warnings +import importlib +import contextlib + +from importlib import resources +from importlib.resources.abc import Traversable +from . import data01 +from . import util +from . import _path +from test.support import os_helper +from test.support import import_helper + + +@contextlib.contextmanager +def suppress_known_deprecation(): + with warnings.catch_warnings(record=True) as ctx: + warnings.simplefilter('default', category=DeprecationWarning) + yield ctx + + +class FilesTests: + def test_read_bytes(self): + files = resources.files(self.data) + actual = files.joinpath('utf-8.file').read_bytes() + assert actual == b'Hello, UTF-8 world!\n' + + def test_read_text(self): + files = resources.files(self.data) + actual = files.joinpath('utf-8.file').read_text(encoding='utf-8') + assert actual == 'Hello, UTF-8 world!\n' + + @unittest.skipUnless( + hasattr(typing, 'runtime_checkable'), + "Only suitable when typing supports runtime_checkable", + ) + def test_traversable(self): + assert isinstance(resources.files(self.data), Traversable) + + def test_old_parameter(self): + """ + Files used to take a 'package' parameter. Make sure anyone + passing by name is still supported. + """ + with suppress_known_deprecation(): + resources.files(package=self.data) + + +class OpenDiskTests(FilesTests, unittest.TestCase): + def setUp(self): + self.data = data01 + + +class OpenZipTests(FilesTests, util.ZipSetup, unittest.TestCase): + pass + + +class OpenNamespaceTests(FilesTests, unittest.TestCase): + def setUp(self): + from . import namespacedata01 + + self.data = namespacedata01 + + +class SiteDir: + def setUp(self): + self.fixtures = contextlib.ExitStack() + self.addCleanup(self.fixtures.close) + self.site_dir = self.fixtures.enter_context(os_helper.temp_dir()) + self.fixtures.enter_context(import_helper.DirsOnSysPath(self.site_dir)) + self.fixtures.enter_context(import_helper.CleanImport()) + + +class ModulesFilesTests(SiteDir, unittest.TestCase): + def test_module_resources(self): + """ + A module can have resources found adjacent to the module. + """ + spec = { + 'mod.py': '', + 'res.txt': 'resources are the best', + } + _path.build(spec, self.site_dir) + import mod + + actual = resources.files(mod).joinpath('res.txt').read_text() + assert actual == spec['res.txt'] + + +class ImplicitContextFilesTests(SiteDir, unittest.TestCase): + def test_implicit_files(self): + """ + Without any parameter, files() will infer the location as the caller. + """ + spec = { + 'somepkg': { + '__init__.py': textwrap.dedent( + """ + import importlib.resources as res + val = res.files().joinpath('res.txt').read_text() + """ + ), + 'res.txt': 'resources are the best', + }, + } + _path.build(spec, self.site_dir) + assert importlib.import_module('somepkg').val == 'resources are the best' + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_importlib/test_open.py b/Lib/test/test_importlib/resources/test_open.py similarity index 62% rename from Lib/test/test_importlib/test_open.py rename to Lib/test/test_importlib/resources/test_open.py index 6f88ff78b73..0554c41ba67 100644 --- a/Lib/test/test_importlib/test_open.py +++ b/Lib/test/test_importlib/resources/test_open.py @@ -2,42 +2,48 @@ import unittest from importlib import resources from . import data01 -from .resources import util +from . import util class CommonBinaryTests(util.CommonTests, unittest.TestCase): def execute(self, package, path): - with resources.open_binary(package, path): + target = resources.files(package).joinpath(path) + with target.open('rb'): pass class CommonTextTests(util.CommonTests, unittest.TestCase): def execute(self, package, path): - with resources.open_text(package, path): + target = resources.files(package).joinpath(path) + with target.open(): pass class OpenTests: def test_open_binary(self): - with resources.open_binary(self.data, 'binary.file') as fp: + target = resources.files(self.data) / 'binary.file' + with target.open('rb') as fp: result = fp.read() self.assertEqual(result, b'\x00\x01\x02\x03') def test_open_text_default_encoding(self): - with resources.open_text(self.data, 'utf-8.file') as fp: + target = resources.files(self.data) / 'utf-8.file' + with target.open() as fp: result = fp.read() self.assertEqual(result, 'Hello, UTF-8 world!\n') def test_open_text_given_encoding(self): - with resources.open_text(self.data, 'utf-16.file', 'utf-16', 'strict') as fp: + target = resources.files(self.data) / 'utf-16.file' + with target.open(encoding='utf-16', errors='strict') as fp: result = fp.read() self.assertEqual(result, 'Hello, UTF-16 world!\n') def test_open_text_with_errors(self): # Raises UnicodeError without the 'errors' argument. - with resources.open_text(self.data, 'utf-16.file', 'utf-8', 'strict') as fp: + target = resources.files(self.data) / 'utf-16.file' + with target.open(encoding='utf-8', errors='strict') as fp: self.assertRaises(UnicodeError, fp.read) - with resources.open_text(self.data, 'utf-16.file', 'utf-8', 'ignore') as fp: + with target.open(encoding='utf-8', errors='ignore') as fp: result = fp.read() self.assertEqual( result, @@ -47,14 +53,12 @@ class OpenTests: ) def test_open_binary_FileNotFoundError(self): - self.assertRaises( - FileNotFoundError, resources.open_binary, self.data, 'does-not-exist' - ) + target = resources.files(self.data) / 'does-not-exist' + self.assertRaises(FileNotFoundError, target.open, 'rb') def test_open_text_FileNotFoundError(self): - self.assertRaises( - FileNotFoundError, resources.open_text, self.data, 'does-not-exist' - ) + target = resources.files(self.data) / 'does-not-exist' + self.assertRaises(FileNotFoundError, target.open) class OpenDiskTests(OpenTests, unittest.TestCase): diff --git a/Lib/test/test_importlib/test_path.py b/Lib/test/test_importlib/resources/test_path.py similarity index 80% rename from Lib/test/test_importlib/test_path.py rename to Lib/test/test_importlib/resources/test_path.py index 4436d7f34ef..adcf75feea7 100644 --- a/Lib/test/test_importlib/test_path.py +++ b/Lib/test/test_importlib/resources/test_path.py @@ -3,12 +3,12 @@ import unittest from importlib import resources from . import data01 -from .resources import util +from . import util class CommonTests(util.CommonTests, unittest.TestCase): def execute(self, package, path): - with resources.path(package, path): + with resources.as_file(resources.files(package).joinpath(path)): pass @@ -17,7 +17,8 @@ class PathTests: # Path should be readable. # Test also implicitly verifies the returned object is a pathlib.Path # instance. - with resources.path(self.data, 'utf-8.file') as path: + target = resources.files(self.data) / 'utf-8.file' + with resources.as_file(target) as path: self.assertTrue(path.name.endswith("utf-8.file"), repr(path)) # pathlib.Path.read_text() was introduced in Python 3.5. with path.open('r', encoding='utf-8') as file: @@ -32,7 +33,8 @@ class PathDiskTests(PathTests, unittest.TestCase): # Guarantee the internal implementation detail that # file-system-backed resources do not get the tempdir # treatment. - with resources.path(self.data, 'utf-8.file') as path: + target = resources.files(self.data) / 'utf-8.file' + with resources.as_file(target) as path: assert 'data' in str(path) @@ -51,7 +53,8 @@ class PathZipTests(PathTests, util.ZipSetup, unittest.TestCase): def test_remove_in_context_manager(self): # It is not an error if the file that was temporarily stashed on the # file system is removed inside the `with` stanza. - with resources.path(self.data, 'utf-8.file') as path: + target = resources.files(self.data) / 'utf-8.file' + with resources.as_file(target) as path: path.unlink() diff --git a/Lib/test/test_importlib/test_read.py b/Lib/test/test_importlib/resources/test_read.py similarity index 61% rename from Lib/test/test_importlib/test_read.py rename to Lib/test/test_importlib/resources/test_read.py index 357980132b6..0ca8ee9d028 100644 --- a/Lib/test/test_importlib/test_read.py +++ b/Lib/test/test_importlib/resources/test_read.py @@ -2,36 +2,41 @@ import unittest from importlib import import_module, resources from . import data01 -from .resources import util +from . import util class CommonBinaryTests(util.CommonTests, unittest.TestCase): def execute(self, package, path): - resources.read_binary(package, path) + resources.files(package).joinpath(path).read_bytes() class CommonTextTests(util.CommonTests, unittest.TestCase): def execute(self, package, path): - resources.read_text(package, path) + resources.files(package).joinpath(path).read_text() class ReadTests: - def test_read_binary(self): - result = resources.read_binary(self.data, 'binary.file') + def test_read_bytes(self): + result = resources.files(self.data).joinpath('binary.file').read_bytes() self.assertEqual(result, b'\0\1\2\3') def test_read_text_default_encoding(self): - result = resources.read_text(self.data, 'utf-8.file') + result = resources.files(self.data).joinpath('utf-8.file').read_text() self.assertEqual(result, 'Hello, UTF-8 world!\n') def test_read_text_given_encoding(self): - result = resources.read_text(self.data, 'utf-16.file', encoding='utf-16') + result = ( + resources.files(self.data) + .joinpath('utf-16.file') + .read_text(encoding='utf-16') + ) self.assertEqual(result, 'Hello, UTF-16 world!\n') def test_read_text_with_errors(self): # Raises UnicodeError without the 'errors' argument. - self.assertRaises(UnicodeError, resources.read_text, self.data, 'utf-16.file') - result = resources.read_text(self.data, 'utf-16.file', errors='ignore') + target = resources.files(self.data) / 'utf-16.file' + self.assertRaises(UnicodeError, target.read_text, encoding='utf-8') + result = target.read_text(encoding='utf-8', errors='ignore') self.assertEqual( result, 'H\x00e\x00l\x00l\x00o\x00,\x00 ' @@ -47,11 +52,15 @@ class ReadDiskTests(ReadTests, unittest.TestCase): class ReadZipTests(ReadTests, util.ZipSetup, unittest.TestCase): def test_read_submodule_resource(self): submodule = import_module('ziptestdata.subdirectory') - result = resources.read_binary(submodule, 'binary.file') + result = resources.files(submodule).joinpath('binary.file').read_bytes() self.assertEqual(result, b'\0\1\2\3') def test_read_submodule_resource_by_name(self): - result = resources.read_binary('ziptestdata.subdirectory', 'binary.file') + result = ( + resources.files('ziptestdata.subdirectory') + .joinpath('binary.file') + .read_bytes() + ) self.assertEqual(result, b'\0\1\2\3') diff --git a/Lib/test/test_importlib/test_reader.py b/Lib/test/test_importlib/resources/test_reader.py similarity index 95% rename from Lib/test/test_importlib/test_reader.py rename to Lib/test/test_importlib/resources/test_reader.py index 9d20c976b82..4fd9e6bbe42 100644 --- a/Lib/test/test_importlib/test_reader.py +++ b/Lib/test/test_importlib/resources/test_reader.py @@ -75,6 +75,11 @@ class MultiplexedPathTest(unittest.TestCase): str(path.joinpath('imaginary'))[len(prefix) + 1 :], os.path.join('namespacedata01', 'imaginary'), ) + self.assertEqual(path.joinpath(), path) + + def test_join_path_compound(self): + path = MultiplexedPath(self.folder) + assert not path.joinpath('imaginary/foo.py').exists() def test_repr(self): self.assertEqual( diff --git a/Lib/test/test_importlib/test_resource.py b/Lib/test/test_importlib/resources/test_resource.py similarity index 64% rename from Lib/test/test_importlib/test_resource.py rename to Lib/test/test_importlib/resources/test_resource.py index 612bada5e03..f7e3abbdc80 100644 --- a/Lib/test/test_importlib/test_resource.py +++ b/Lib/test/test_importlib/resources/test_resource.py @@ -5,7 +5,7 @@ import pathlib from . import data01 from . import zipdata01, zipdata02 -from .resources import util +from . import util from importlib import resources, import_module from test.support import import_helper from test.support.os_helper import unlink @@ -14,34 +14,18 @@ from test.support.os_helper import unlink class ResourceTests: # Subclasses are expected to set the `data` attribute. - def test_is_resource_good_path(self): - self.assertTrue(resources.is_resource(self.data, 'binary.file')) + def test_is_file_exists(self): + target = resources.files(self.data) / 'binary.file' + self.assertTrue(target.is_file()) - def test_is_resource_missing(self): - self.assertFalse(resources.is_resource(self.data, 'not-a-file')) + def test_is_file_missing(self): + target = resources.files(self.data) / 'not-a-file' + self.assertFalse(target.is_file()) - def test_is_resource_subresource_directory(self): - # Directories are not resources. - self.assertFalse(resources.is_resource(self.data, 'subdirectory')) - - def test_contents(self): - contents = set(resources.contents(self.data)) - # There may be cruft in the directory listing of the data directory. - # It could have a __pycache__ directory, - # an artifact of the - # test suite importing these modules, which - # are not germane to this test, so just filter them out. - contents.discard('__pycache__') - self.assertEqual( - sorted(contents), - [ - '__init__.py', - 'binary.file', - 'subdirectory', - 'utf-16.file', - 'utf-8.file', - ], - ) + def test_is_dir(self): + target = resources.files(self.data) / 'subdirectory' + self.assertFalse(target.is_file()) + self.assertTrue(target.is_dir()) class ResourceDiskTests(ResourceTests, unittest.TestCase): @@ -53,30 +37,34 @@ class ResourceZipTests(ResourceTests, util.ZipSetup, unittest.TestCase): pass +def names(traversable): + return {item.name for item in traversable.iterdir()} + + class ResourceLoaderTests(unittest.TestCase): def test_resource_contents(self): package = util.create_package( file=data01, path=data01.__file__, contents=['A', 'B', 'C'] ) - self.assertEqual(set(resources.contents(package)), {'A', 'B', 'C'}) + self.assertEqual(names(resources.files(package)), {'A', 'B', 'C'}) - def test_resource_is_resource(self): + def test_is_file(self): package = util.create_package( file=data01, path=data01.__file__, contents=['A', 'B', 'C', 'D/E', 'D/F'] ) - self.assertTrue(resources.is_resource(package, 'B')) + self.assertTrue(resources.files(package).joinpath('B').is_file()) - def test_resource_directory_is_not_resource(self): + def test_is_dir(self): package = util.create_package( file=data01, path=data01.__file__, contents=['A', 'B', 'C', 'D/E', 'D/F'] ) - self.assertFalse(resources.is_resource(package, 'D')) + self.assertTrue(resources.files(package).joinpath('D').is_dir()) - def test_resource_missing_is_not_resource(self): + def test_resource_missing(self): package = util.create_package( file=data01, path=data01.__file__, contents=['A', 'B', 'C', 'D/E', 'D/F'] ) - self.assertFalse(resources.is_resource(package, 'Z')) + self.assertFalse(resources.files(package).joinpath('Z').is_file()) class ResourceCornerCaseTests(unittest.TestCase): @@ -94,7 +82,7 @@ class ResourceCornerCaseTests(unittest.TestCase): module.__file__ = '/path/which/shall/not/be/named' module.__spec__.loader = module.__loader__ module.__spec__.origin = module.__file__ - self.assertFalse(resources.is_resource(module, 'A')) + self.assertFalse(resources.files(module).joinpath('A').is_file()) class ResourceFromZipsTest01(util.ZipSetupBase, unittest.TestCase): @@ -102,25 +90,35 @@ class ResourceFromZipsTest01(util.ZipSetupBase, unittest.TestCase): def test_is_submodule_resource(self): submodule = import_module('ziptestdata.subdirectory') - self.assertTrue(resources.is_resource(submodule, 'binary.file')) + self.assertTrue(resources.files(submodule).joinpath('binary.file').is_file()) def test_read_submodule_resource_by_name(self): self.assertTrue( - resources.is_resource('ziptestdata.subdirectory', 'binary.file') + resources.files('ziptestdata.subdirectory') + .joinpath('binary.file') + .is_file() ) def test_submodule_contents(self): submodule = import_module('ziptestdata.subdirectory') self.assertEqual( - set(resources.contents(submodule)), {'__init__.py', 'binary.file'} + names(resources.files(submodule)), {'__init__.py', 'binary.file'} ) def test_submodule_contents_by_name(self): self.assertEqual( - set(resources.contents('ziptestdata.subdirectory')), + names(resources.files('ziptestdata.subdirectory')), {'__init__.py', 'binary.file'}, ) + def test_as_file_directory(self): + with resources.as_file(resources.files('ziptestdata')) as data: + assert data.name == 'ziptestdata' + assert data.is_dir() + assert data.joinpath('subdirectory').is_dir() + assert len(list(data.iterdir())) + assert not data.parent.exists() + class ResourceFromZipsTest02(util.ZipSetupBase, unittest.TestCase): ZIP_MODULE = zipdata02 # type: ignore @@ -131,10 +129,12 @@ class ResourceFromZipsTest02(util.ZipSetupBase, unittest.TestCase): distinct resources. Ref python/importlib_resources#44. """ self.assertEqual( - set(resources.contents('ziptestdata.one')), {'__init__.py', 'resource1.txt'} + names(resources.files('ziptestdata.one')), + {'__init__.py', 'resource1.txt'}, ) self.assertEqual( - set(resources.contents('ziptestdata.two')), {'__init__.py', 'resource2.txt'} + names(resources.files('ziptestdata.two')), + {'__init__.py', 'resource2.txt'}, ) @@ -175,41 +175,43 @@ class DeletingZipsTest(unittest.TestCase): # If the test fails, this will probably fail too pass - def test_contents_does_not_keep_open(self): - c = resources.contents('ziptestdata') + def test_iterdir_does_not_keep_open(self): + c = [item.name for item in resources.files('ziptestdata').iterdir()] self.zip_path.unlink() del c - def test_is_resource_does_not_keep_open(self): - c = resources.is_resource('ziptestdata', 'binary.file') + def test_is_file_does_not_keep_open(self): + c = resources.files('ziptestdata').joinpath('binary.file').is_file() self.zip_path.unlink() del c - def test_is_resource_failure_does_not_keep_open(self): - c = resources.is_resource('ziptestdata', 'not-present') + def test_is_file_failure_does_not_keep_open(self): + c = resources.files('ziptestdata').joinpath('not-present').is_file() self.zip_path.unlink() del c @unittest.skip("Desired but not supported.") - def test_path_does_not_keep_open(self): - c = resources.path('ziptestdata', 'binary.file') + def test_as_file_does_not_keep_open(self): # pragma: no cover + c = resources.as_file(resources.files('ziptestdata') / 'binary.file') self.zip_path.unlink() del c def test_entered_path_does_not_keep_open(self): # This is what certifi does on import to make its bundle # available for the process duration. - c = resources.path('ziptestdata', 'binary.file').__enter__() + c = resources.as_file( + resources.files('ziptestdata') / 'binary.file' + ).__enter__() self.zip_path.unlink() del c def test_read_binary_does_not_keep_open(self): - c = resources.read_binary('ziptestdata', 'binary.file') + c = resources.files('ziptestdata').joinpath('binary.file').read_bytes() self.zip_path.unlink() del c def test_read_text_does_not_keep_open(self): - c = resources.read_text('ziptestdata', 'utf-8.file', encoding='utf-8') + c = resources.files('ziptestdata').joinpath('utf-8.file').read_text() self.zip_path.unlink() del c @@ -227,14 +229,18 @@ class ResourceFromNamespaceTest01(unittest.TestCase): def test_is_submodule_resource(self): self.assertTrue( - resources.is_resource(import_module('namespacedata01'), 'binary.file') + resources.files(import_module('namespacedata01')) + .joinpath('binary.file') + .is_file() ) def test_read_submodule_resource_by_name(self): - self.assertTrue(resources.is_resource('namespacedata01', 'binary.file')) + self.assertTrue( + resources.files('namespacedata01').joinpath('binary.file').is_file() + ) def test_submodule_contents(self): - contents = set(resources.contents(import_module('namespacedata01'))) + contents = names(resources.files(import_module('namespacedata01'))) try: contents.remove('__pycache__') except KeyError: @@ -242,7 +248,7 @@ class ResourceFromNamespaceTest01(unittest.TestCase): self.assertEqual(contents, {'binary.file', 'utf-8.file', 'utf-16.file'}) def test_submodule_contents_by_name(self): - contents = set(resources.contents('namespacedata01')) + contents = names(resources.files('namespacedata01')) try: contents.remove('__pycache__') except KeyError: diff --git a/Lib/test/test_importlib/update-zips.py b/Lib/test/test_importlib/resources/update-zips.py similarity index 96% rename from Lib/test/test_importlib/update-zips.py rename to Lib/test/test_importlib/resources/update-zips.py index 9ef0224ca65..231334aa7e3 100755 --- a/Lib/test/test_importlib/update-zips.py +++ b/Lib/test/test_importlib/resources/update-zips.py @@ -42,7 +42,7 @@ def generate(suffix): def walk(datapath): for dirpath, dirnames, filenames in os.walk(datapath): - with contextlib.suppress(KeyError): + with contextlib.suppress(ValueError): dirnames.remove('__pycache__') for filename in filenames: res = pathlib.Path(dirpath) / filename diff --git a/Lib/test/test_importlib/resources/util.py b/Lib/test/test_importlib/resources/util.py index d7a049bf804..1e72b91ff6b 100644 --- a/Lib/test/test_importlib/resources/util.py +++ b/Lib/test/test_importlib/resources/util.py @@ -3,11 +3,11 @@ import importlib import io import sys import types -from pathlib import Path, PurePath +import pathlib -from .. import data01 -from .. import zipdata01 -from importlib.abc import ResourceReader +from . import data01 +from . import zipdata01 +from importlib.resources.abc import ResourceReader from test.support import import_helper @@ -94,37 +94,14 @@ class CommonTests(metaclass=abc.ABCMeta): def test_pathlib_path(self): # Passing in a pathlib.PurePath object for the path should succeed. - path = PurePath('utf-8.file') + path = pathlib.PurePath('utf-8.file') self.execute(data01, path) - def test_absolute_path(self): - # An absolute path is a ValueError. - path = Path(__file__) - full_path = path.parent / 'utf-8.file' - with self.assertRaises(ValueError): - self.execute(data01, full_path) - - def test_relative_path(self): - # A reative path is a ValueError. - with self.assertRaises(ValueError): - self.execute(data01, '../data01/utf-8.file') - def test_importing_module_as_side_effect(self): # The anchor package can already be imported. del sys.modules[data01.__name__] self.execute(data01.__name__, 'utf-8.file') - def test_non_package_by_name(self): - # The anchor package cannot be a module. - with self.assertRaises(TypeError): - self.execute(__name__, 'utf-8.file') - - def test_non_package_by_package(self): - # The anchor package cannot be a module. - with self.assertRaises(TypeError): - module = sys.modules['test.test_importlib.resources.util'] - self.execute(module, 'utf-8.file') - def test_missing_path(self): # Attempting to open or read or request the path for a # non-existent path should succeed if open_resource @@ -156,7 +133,7 @@ class ZipSetupBase: @classmethod def setUpClass(cls): - data_path = Path(cls.ZIP_MODULE.__file__) + data_path = pathlib.Path(cls.ZIP_MODULE.__file__) data_dir = data_path.parent cls._zip_path = str(data_dir / 'ziptestdata.zip') sys.path.append(cls._zip_path) diff --git a/Lib/test/test_importlib/data03/namespace/portion2/__init__.py b/Lib/test/test_importlib/resources/zipdata01/__init__.py similarity index 100% rename from Lib/test/test_importlib/data03/namespace/portion2/__init__.py rename to Lib/test/test_importlib/resources/zipdata01/__init__.py diff --git a/Lib/test/test_importlib/zipdata01/ziptestdata.zip b/Lib/test/test_importlib/resources/zipdata01/ziptestdata.zip similarity index 100% rename from Lib/test/test_importlib/zipdata01/ziptestdata.zip rename to Lib/test/test_importlib/resources/zipdata01/ziptestdata.zip diff --git a/Lib/test/test_importlib/zipdata01/__init__.py b/Lib/test/test_importlib/resources/zipdata02/__init__.py similarity index 100% rename from Lib/test/test_importlib/zipdata01/__init__.py rename to Lib/test/test_importlib/resources/zipdata02/__init__.py diff --git a/Lib/test/test_importlib/zipdata02/ziptestdata.zip b/Lib/test/test_importlib/resources/zipdata02/ziptestdata.zip similarity index 100% rename from Lib/test/test_importlib/zipdata02/ziptestdata.zip rename to Lib/test/test_importlib/resources/zipdata02/ziptestdata.zip diff --git a/Lib/test/test_importlib/source/test_case_sensitivity.py b/Lib/test/test_importlib/source/test_case_sensitivity.py index 19543f4a665..9d472707abe 100644 --- a/Lib/test/test_importlib/source/test_case_sensitivity.py +++ b/Lib/test/test_importlib/source/test_case_sensitivity.py @@ -1,7 +1,7 @@ """Test case-sensitivity (PEP 235).""" import sys -from .. import util +from test.test_importlib import util importlib = util.import_importlib('importlib') machinery = util.import_importlib('importlib.machinery') diff --git a/Lib/test/test_importlib/source/test_file_loader.py b/Lib/test/test_importlib/source/test_file_loader.py index 1065ac55fce..f35adec1a8e 100644 --- a/Lib/test/test_importlib/source/test_file_loader.py +++ b/Lib/test/test_importlib/source/test_file_loader.py @@ -1,5 +1,4 @@ -from .. import abc -from .. import util +from test.test_importlib import abc, util importlib = util.import_importlib('importlib') importlib_abc = util.import_importlib('importlib.abc') @@ -52,7 +51,6 @@ class SimpleTest(abc.LoaderTests): def get_code(self, _): pass def get_source(self, _): pass def is_package(self, _): pass - def module_repr(self, _): pass path = 'some_path' name = 'some_name' diff --git a/Lib/test/test_importlib/source/test_finder.py b/Lib/test/test_importlib/source/test_finder.py index 80e930cc6a1..bed9d56dca8 100644 --- a/Lib/test/test_importlib/source/test_finder.py +++ b/Lib/test/test_importlib/source/test_finder.py @@ -1,5 +1,4 @@ -from .. import abc -from .. import util +from test.test_importlib import abc, util machinery = util.import_importlib('importlib.machinery') @@ -158,21 +157,12 @@ class FinderTests(abc.FinderTests): def test_no_read_directory(self): # Issue #16730 tempdir = tempfile.TemporaryDirectory() + self.enterContext(tempdir) + # Since we muck with the permissions, we want to set them back to + # their original values to make sure the directory can be properly + # cleaned up. original_mode = os.stat(tempdir.name).st_mode - def cleanup(tempdir): - """Cleanup function for the temporary directory. - - Since we muck with the permissions, we want to set them back to - their original values to make sure the directory can be properly - cleaned up. - - """ - os.chmod(tempdir.name, original_mode) - # If this is not explicitly called then the __del__ method is used, - # but since already mucking around might as well explicitly clean - # up. - tempdir.__exit__(None, None, None) - self.addCleanup(cleanup, tempdir) + self.addCleanup(os.chmod, tempdir.name, original_mode) os.chmod(tempdir.name, stat.S_IWUSR | stat.S_IXUSR) finder = self.get_finder(tempdir.name) found = self._find(finder, 'doesnotexist') diff --git a/Lib/test/test_importlib/source/test_path_hook.py b/Lib/test/test_importlib/source/test_path_hook.py index 795d436c3b9..ead62f5e945 100644 --- a/Lib/test/test_importlib/source/test_path_hook.py +++ b/Lib/test/test_importlib/source/test_path_hook.py @@ -1,4 +1,4 @@ -from .. import util +from test.test_importlib import util machinery = util.import_importlib('importlib.machinery') diff --git a/Lib/test/test_importlib/source/test_source_encoding.py b/Lib/test/test_importlib/source/test_source_encoding.py index c0b9b031262..c09c9aa12b8 100644 --- a/Lib/test/test_importlib/source/test_source_encoding.py +++ b/Lib/test/test_importlib/source/test_source_encoding.py @@ -1,4 +1,4 @@ -from .. import util +from test.test_importlib import util machinery = util.import_importlib('importlib.machinery') diff --git a/Lib/test/test_importlib/test_abc.py b/Lib/test/test_importlib/test_abc.py index 45cbf907917..3c9149c4e45 100644 --- a/Lib/test/test_importlib/test_abc.py +++ b/Lib/test/test_importlib/test_abc.py @@ -2,14 +2,13 @@ import io import marshal import os import sys -from test import support from test.support import import_helper import types import unittest from unittest import mock import warnings -from . import util as test_util +from test.test_importlib import util as test_util init = test_util.import_importlib('importlib') abc = test_util.import_importlib('importlib.abc') @@ -222,8 +221,6 @@ class LoaderDefaultsTests(ABCTestHarness): mod = types.ModuleType('blah') with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) - with self.assertRaises(NotImplementedError): - self.ins.module_repr(mod) original_repr = repr(mod) mod.__loader__ = self.ins # Should still return a proper repr. @@ -323,32 +320,6 @@ class ResourceReader: return super().contents(*args, **kwargs) -class ResourceReaderDefaultsTests(ABCTestHarness): - - SPLIT = make_abc_subclasses(ResourceReader) - - def test_open_resource(self): - with self.assertRaises(FileNotFoundError): - self.ins.open_resource('dummy_file') - - def test_resource_path(self): - with self.assertRaises(FileNotFoundError): - self.ins.resource_path('dummy_file') - - def test_is_resource(self): - with self.assertRaises(FileNotFoundError): - self.ins.is_resource('dummy_file') - - def test_contents(self): - with self.assertRaises(FileNotFoundError): - self.ins.contents() - - -(Frozen_RRDefaultTests, - Source_RRDefaultsTests - ) = test_util.test_both(ResourceReaderDefaultsTests) - - ##### MetaPathFinder concrete methods ########################################## class MetaPathFinderFindModuleTests: @@ -716,9 +687,6 @@ class SourceOnlyLoader: def get_filename(self, fullname): return self.path - def module_repr(self, module): - return '' - SPLIT_SOL = make_abc_subclasses(SourceOnlyLoader, 'SourceLoader') @@ -803,13 +771,7 @@ class SourceLoaderTestHarness: class SourceOnlyLoaderTests(SourceLoaderTestHarness): - - """Test importlib.abc.SourceLoader for source-only loading. - - Reload testing is subsumed by the tests for - importlib.util.module_for_loader. - - """ + """Test importlib.abc.SourceLoader for source-only loading.""" def test_get_source(self): # Verify the source code is returned as a string. diff --git a/Lib/test/test_importlib/test_api.py b/Lib/test/test_importlib/test_api.py index 763b2add073..b3a99dc2dd5 100644 --- a/Lib/test/test_importlib/test_api.py +++ b/Lib/test/test_importlib/test_api.py @@ -1,4 +1,4 @@ -from . import util as test_util +from test.test_importlib import util as test_util init = test_util.import_importlib('importlib') util = test_util.import_importlib('importlib.util') @@ -6,7 +6,6 @@ machinery = test_util.import_importlib('importlib.machinery') import os.path import sys -from test import support from test.support import import_helper from test.support import os_helper import types @@ -301,7 +300,8 @@ class ReloadTests: name = 'spam' with os_helper.temp_cwd(None) as cwd: with test_util.uncache('spam'): - with import_helper.DirsOnSysPath(cwd): + with test_util.import_state(path=[cwd]): + self.init._bootstrap_external._install(self.init._bootstrap) # Start as a namespace package. self.init.invalidate_caches() bad_path = os.path.join(cwd, name, '__init.py') @@ -395,7 +395,7 @@ class InvalidateCacheTests: def invalidate_caches(self): self.called = True - key = 'gobledeegook' + key = os.path.abspath('gobledeegook') meta_ins = InvalidatingNullFinder() path_ins = InvalidatingNullFinder() sys.meta_path.insert(0, meta_ins) diff --git a/Lib/test/test_importlib/test_files.py b/Lib/test/test_importlib/test_files.py deleted file mode 100644 index b9170d83bea..00000000000 --- a/Lib/test/test_importlib/test_files.py +++ /dev/null @@ -1,46 +0,0 @@ -import typing -import unittest - -from importlib import resources -from importlib.abc import Traversable -from . import data01 -from .resources import util - - -class FilesTests: - def test_read_bytes(self): - files = resources.files(self.data) - actual = files.joinpath('utf-8.file').read_bytes() - assert actual == b'Hello, UTF-8 world!\n' - - def test_read_text(self): - files = resources.files(self.data) - actual = files.joinpath('utf-8.file').read_text(encoding='utf-8') - assert actual == 'Hello, UTF-8 world!\n' - - @unittest.skipUnless( - hasattr(typing, 'runtime_checkable'), - "Only suitable when typing supports runtime_checkable", - ) - def test_traversable(self): - assert isinstance(resources.files(self.data), Traversable) - - -class OpenDiskTests(FilesTests, unittest.TestCase): - def setUp(self): - self.data = data01 - - -class OpenZipTests(FilesTests, util.ZipSetup, unittest.TestCase): - pass - - -class OpenNamespaceTests(FilesTests, unittest.TestCase): - def setUp(self): - from . import namespacedata01 - - self.data = namespacedata01 - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_importlib/test_lazy.py b/Lib/test/test_importlib/test_lazy.py index 28608e95d06..cc993f333e3 100644 --- a/Lib/test/test_importlib/test_lazy.py +++ b/Lib/test/test_importlib/test_lazy.py @@ -5,7 +5,7 @@ import sys import types import unittest -from . import util as test_util +from test.test_importlib import util as test_util class CollectInit: diff --git a/Lib/test/test_importlib/test_locks.py b/Lib/test/test_importlib/test_locks.py index 9290bac80a7..56d73c496e6 100644 --- a/Lib/test/test_importlib/test_locks.py +++ b/Lib/test/test_importlib/test_locks.py @@ -1,4 +1,4 @@ -from . import util as test_util +from test.test_importlib import util as test_util init = test_util.import_importlib('importlib') @@ -12,6 +12,9 @@ from test.support import threading_helper from test import lock_tests +threading_helper.requires_working_threading(module=True) + + class ModuleLockAsRLockTests: locktype = classmethod(lambda cls: cls.LockType("some_lock")) @@ -146,4 +149,4 @@ def setUpModule(): if __name__ == '__main__': - unittets.main() + unittest.main() diff --git a/Lib/test/test_importlib/test_main.py b/Lib/test/test_importlib/test_main.py index 52cb63712a5..30b68b6ae7d 100644 --- a/Lib/test/test_importlib/test_main.py +++ b/Lib/test/test_importlib/test_main.py @@ -1,9 +1,6 @@ import re -import json import pickle -import textwrap import unittest -import warnings import importlib.metadata try: @@ -16,9 +13,11 @@ from importlib.metadata import ( Distribution, EntryPoint, PackageNotFoundError, + _unique, distributions, entry_points, metadata, + packages_distributions, version, ) @@ -36,10 +35,12 @@ class BasicTests(fixtures.DistInfoPkg, unittest.TestCase): Distribution.from_name('does-not-exist') def test_package_not_found_mentions_metadata(self): - # When a package is not found, that could indicate that the - # packgae is not installed or that it is installed without - # metadata. Ensure the exception mentions metadata to help - # guide users toward the cause. See #124. + """ + When a package is not found, that could indicate that the + packgae is not installed or that it is installed without + metadata. Ensure the exception mentions metadata to help + guide users toward the cause. See #124. + """ with self.assertRaises(PackageNotFoundError) as ctx: Distribution.from_name('does-not-exist') @@ -48,6 +49,14 @@ class BasicTests(fixtures.DistInfoPkg, unittest.TestCase): def test_new_style_classes(self): self.assertIsInstance(Distribution, type) + @fixtures.parameterize( + dict(name=None), + dict(name=''), + ) + def test_invalid_inputs_to_from_name(self, name): + with self.assertRaises(Exception): + Distribution.from_name(name) + class ImportTests(fixtures.DistInfoPkg, unittest.TestCase): def test_import_nonexistent_module(self): @@ -75,44 +84,50 @@ class ImportTests(fixtures.DistInfoPkg, unittest.TestCase): class NameNormalizationTests(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase): @staticmethod - def pkg_with_dashes(site_dir): + def make_pkg(name): """ - Create minimal metadata for a package with dashes - in the name (and thus underscores in the filename). + Create minimal metadata for a dist-info package with + the indicated name on the file system. """ - metadata_dir = site_dir / 'my_pkg.dist-info' - metadata_dir.mkdir() - metadata = metadata_dir / 'METADATA' - with metadata.open('w', encoding='utf-8') as strm: - strm.write('Version: 1.0\n') - return 'my-pkg' + return { + f'{name}.dist-info': { + 'METADATA': 'VERSION: 1.0\n', + }, + } def test_dashes_in_dist_name_found_as_underscores(self): - # For a package with a dash in the name, the dist-info metadata - # uses underscores in the name. Ensure the metadata loads. - pkg_name = self.pkg_with_dashes(self.site_dir) - assert version(pkg_name) == '1.0' - - @staticmethod - def pkg_with_mixed_case(site_dir): """ - Create minimal metadata for a package with mixed case - in the name. + For a package with a dash in the name, the dist-info metadata + uses underscores in the name. Ensure the metadata loads. """ - metadata_dir = site_dir / 'CherryPy.dist-info' - metadata_dir.mkdir() - metadata = metadata_dir / 'METADATA' - with metadata.open('w', encoding='utf-8') as strm: - strm.write('Version: 1.0\n') - return 'CherryPy' + fixtures.build_files(self.make_pkg('my_pkg'), self.site_dir) + assert version('my-pkg') == '1.0' def test_dist_name_found_as_any_case(self): - # Ensure the metadata loads when queried with any case. - pkg_name = self.pkg_with_mixed_case(self.site_dir) + """ + Ensure the metadata loads when queried with any case. + """ + pkg_name = 'CherryPy' + fixtures.build_files(self.make_pkg(pkg_name), self.site_dir) assert version(pkg_name) == '1.0' assert version(pkg_name.lower()) == '1.0' assert version(pkg_name.upper()) == '1.0' + def test_unique_distributions(self): + """ + Two distributions varying only by non-normalized name on + the file system should resolve as the same. + """ + fixtures.build_files(self.make_pkg('abc'), self.site_dir) + before = list(_unique(distributions())) + + alt_site_dir = self.fixtures.enter_context(fixtures.tempdir()) + self.fixtures.enter_context(self.add_sys_path(alt_site_dir)) + fixtures.build_files(self.make_pkg('ABC'), alt_site_dir) + after = list(_unique(distributions())) + + assert len(after) == len(before) + class NonASCIITests(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase): @staticmethod @@ -121,11 +136,12 @@ class NonASCIITests(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase): Create minimal metadata for a package with non-ASCII in the description. """ - metadata_dir = site_dir / 'portend.dist-info' - metadata_dir.mkdir() - metadata = metadata_dir / 'METADATA' - with metadata.open('w', encoding='utf-8') as fp: - fp.write('Description: pôrˈtend') + contents = { + 'portend.dist-info': { + 'METADATA': 'Description: pôrˈtend', + }, + } + fixtures.build_files(contents, site_dir) return 'portend' @staticmethod @@ -134,19 +150,15 @@ class NonASCIITests(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase): Create minimal metadata for an egg-info package with non-ASCII in the description. """ - metadata_dir = site_dir / 'portend.dist-info' - metadata_dir.mkdir() - metadata = metadata_dir / 'METADATA' - with metadata.open('w', encoding='utf-8') as fp: - fp.write( - textwrap.dedent( - """ + contents = { + 'portend.dist-info': { + 'METADATA': """ Name: portend - pôrˈtend - """ - ).strip() - ) + pôrˈtend""", + }, + } + fixtures.build_files(contents, site_dir) return 'portend' def test_metadata_loads(self): @@ -203,7 +215,7 @@ class InaccessibleSysPath(fixtures.OnSysPath, ffs.TestCase): site_dir = '/access-denied' def setUp(self): - super(InaccessibleSysPath, self).setUp() + super().setUp() self.setUpPyfakefs() self.fs.create_dir(self.site_dir, perm_bits=000) @@ -217,13 +229,21 @@ class InaccessibleSysPath(fixtures.OnSysPath, ffs.TestCase): class TestEntryPoints(unittest.TestCase): def __init__(self, *args): - super(TestEntryPoints, self).__init__(*args) - self.ep = importlib.metadata.EntryPoint('name', 'value', 'group') + super().__init__(*args) + self.ep = importlib.metadata.EntryPoint( + name='name', value='value', group='group' + ) def test_entry_point_pickleable(self): revived = pickle.loads(pickle.dumps(self.ep)) assert revived == self.ep + def test_positional_args(self): + """ + Capture legacy (namedtuple) construction, discouraged. + """ + EntryPoint('name', 'value', 'group') + def test_immutable(self): """EntryPoints should be immutable""" with self.assertRaises(AttributeError): @@ -235,15 +255,9 @@ class TestEntryPoints(unittest.TestCase): assert "'name'" in repr(self.ep) def test_hashable(self): - # EntryPoints should be hashable. + """EntryPoints should be hashable""" hash(self.ep) - def test_json_dump(self): - # json should not expect to be able to dump an EntryPoint. - with self.assertRaises(Exception): - with warnings.catch_warnings(record=True): - json.dumps(self.ep) - def test_module(self): assert self.ep.module == 'value' @@ -251,11 +265,13 @@ class TestEntryPoints(unittest.TestCase): assert self.ep.attr is None def test_sortable(self): - # EntryPoint objects are sortable, but result is undefined. + """ + EntryPoint objects are sortable, but result is undefined. + """ sorted( [ - EntryPoint('b', 'val', 'group'), - EntryPoint('a', 'val', 'group'), + EntryPoint(name='b', value='val', group='group'), + EntryPoint(name='a', value='val', group='group'), ] ) @@ -264,10 +280,47 @@ class FileSystem( fixtures.OnSysPath, fixtures.SiteDir, fixtures.FileBuilder, unittest.TestCase ): def test_unicode_dir_on_sys_path(self): - # Ensure a Unicode subdirectory of a directory on sys.path - # does not crash. + """ + Ensure a Unicode subdirectory of a directory on sys.path + does not crash. + """ fixtures.build_files( {self.unicode_filename(): {}}, prefix=self.site_dir, ) list(distributions()) + + +class PackagesDistributionsPrebuiltTest(fixtures.ZipFixtures, unittest.TestCase): + def test_packages_distributions_example(self): + self._fixture_on_path('example-21.12-py3-none-any.whl') + assert packages_distributions()['example'] == ['example'] + + def test_packages_distributions_example2(self): + """ + Test packages_distributions on a wheel built + by trampolim. + """ + self._fixture_on_path('example2-1.0.0-py3-none-any.whl') + assert packages_distributions()['example2'] == ['example2'] + + +class PackagesDistributionsTest( + fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase +): + def test_packages_distributions_neither_toplevel_nor_files(self): + """ + Test a package built without 'top-level.txt' or a file list. + """ + fixtures.build_files( + { + 'trim_example-1.0.0.dist-info': { + 'METADATA': """ + Name: trim_example + Version: 1.0.0 + """, + } + }, + prefix=self.site_dir, + ) + packages_distributions() diff --git a/Lib/test/test_importlib/test_metadata_api.py b/Lib/test/test_importlib/test_metadata_api.py index dc9c234d15b..71c47e62d27 100644 --- a/Lib/test/test_importlib/test_metadata_api.py +++ b/Lib/test/test_importlib/test_metadata_api.py @@ -21,7 +21,7 @@ from importlib.metadata import ( @contextlib.contextmanager def suppress_known_deprecation(): with warnings.catch_warnings(record=True) as ctx: - warnings.simplefilter('default') + warnings.simplefilter('default', category=DeprecationWarning) yield ctx @@ -89,13 +89,15 @@ class APITests( self.assertIn(ep.dist.name, ('distinfo-pkg', 'egginfo-pkg')) self.assertEqual(ep.dist.version, "1.0.0") - def test_entry_points_unique_packages(self): - # Entry points should only be exposed for the first package - # on sys.path with a given name. + def test_entry_points_unique_packages_normalized(self): + """ + Entry points should only be exposed for the first package + on sys.path with a given name (even when normalized). + """ alt_site_dir = self.fixtures.enter_context(fixtures.tempdir()) self.fixtures.enter_context(self.add_sys_path(alt_site_dir)) alt_pkg = { - "distinfo_pkg-1.1.0.dist-info": { + "DistInfo_pkg-1.1.0.dist-info": { "METADATA": """ Name: distinfo-pkg Version: 1.1.0 @@ -113,7 +115,7 @@ class APITests( for ep in entries ) # ns:sub doesn't exist in alt_pkg - assert 'ns:sub' not in entries + assert 'ns:sub' not in entries.names def test_entry_points_missing_name(self): with self.assertRaises(KeyError): @@ -122,55 +124,10 @@ class APITests( def test_entry_points_missing_group(self): assert entry_points(group='missing') == () - def test_entry_points_dict_construction(self): - # Prior versions of entry_points() returned simple lists and - # allowed casting those lists into maps by name using ``dict()``. - # Capture this now deprecated use-case. - with suppress_known_deprecation() as caught: - eps = dict(entry_points(group='entries')) - - assert 'main' in eps - assert eps['main'] == entry_points(group='entries')['main'] - - # check warning - expected = next(iter(caught)) - assert expected.category is DeprecationWarning - assert "Construction of dict of EntryPoints is deprecated" in str(expected) - - def test_entry_points_by_index(self): - """ - Prior versions of Distribution.entry_points would return a - tuple that allowed access by index. - Capture this now deprecated use-case - See python/importlib_metadata#300 and bpo-44246. - """ - eps = distribution('distinfo-pkg').entry_points - with suppress_known_deprecation() as caught: - eps[0] - - # check warning - expected = next(iter(caught)) - assert expected.category is DeprecationWarning - assert "Accessing entry points by index is deprecated" in str(expected) - - def test_entry_points_groups_getitem(self): - # Prior versions of entry_points() returned a dict. Ensure - # that callers using '.__getitem__()' are supported but warned to - # migrate. - with suppress_known_deprecation(): - entry_points()['entries'] == entry_points(group='entries') - - with self.assertRaises(KeyError): - entry_points()['missing'] - - def test_entry_points_groups_get(self): - # Prior versions of entry_points() returned a dict. Ensure - # that callers using '.get()' are supported but warned to - # migrate. - with suppress_known_deprecation(): - entry_points().get('missing', 'default') == 'default' - entry_points().get('entries', 'default') == entry_points()['entries'] - entry_points().get('missing', ()) == () + def test_entry_points_allows_no_attributes(self): + ep = entry_points().select(group='entries', name='main') + with self.assertRaises(AttributeError): + ep.foo = 4 def test_metadata_for_this_package(self): md = metadata('egginfo-pkg') @@ -194,10 +151,8 @@ class APITests( file.read_text() def test_file_hash_repr(self): - assertRegex = self.assertRegex - util = [p for p in files('distinfo-pkg') if p.name == 'mod.py'][0] - assertRegex(repr(util.hash), '') + self.assertRegex(repr(util.hash), '') def test_files_dist_info(self): self._test_files(files('distinfo-pkg')) @@ -217,6 +172,16 @@ class APITests( assert len(deps) == 2 assert any(dep == 'wheel >= 1.0; python_version >= "2.7"' for dep in deps) + def test_requires_egg_info_empty(self): + fixtures.build_files( + { + 'requires.txt': '', + }, + self.site_dir.joinpath('egginfo_pkg.egg-info'), + ) + deps = requires('egginfo-pkg') + assert deps == [] + def test_requires_dist_info(self): deps = requires('distinfo-pkg') assert len(deps) == 2 @@ -235,6 +200,7 @@ class APITests( [extra1] dep4 + dep6@ git+https://example.com/python/dep.git@v1.0.0 [extra2:python_version < "3"] dep5 @@ -247,6 +213,7 @@ class APITests( 'dep3; python_version < "3"', 'dep4; extra == "extra1"', 'dep5; (python_version < "3") and extra == "extra2"', + 'dep6@ git+https://example.com/python/dep.git@v1.0.0 ; extra == "extra1"', ] # It's important that the environment marker expression be # wrapped in parentheses to avoid the following 'and' binding more @@ -298,7 +265,7 @@ class OffSysPathTests(fixtures.DistInfoPkgOffPath, unittest.TestCase): assert any(dist.metadata['Name'] == 'distinfo-pkg' for dist in dists) def test_distribution_at_pathlib(self): - # Demonstrate how to load metadata direct from a directory. + """Demonstrate how to load metadata direct from a directory.""" dist_info_path = self.site_dir / 'distinfo_pkg-1.0.0.dist-info' dist = Distribution.at(dist_info_path) assert dist.version == '1.0.0' diff --git a/Lib/test/test_importlib/test_namespace_pkgs.py b/Lib/test/test_importlib/test_namespace_pkgs.py index f80283233f9..65428c3d3ea 100644 --- a/Lib/test/test_importlib/test_namespace_pkgs.py +++ b/Lib/test/test_importlib/test_namespace_pkgs.py @@ -4,6 +4,7 @@ import importlib.abc import importlib.machinery import os import sys +import tempfile import unittest import warnings @@ -64,12 +65,7 @@ class NamespacePackageTest(unittest.TestCase): self.resolved_paths = [ os.path.join(self.root, path) for path in self.paths ] - self.ctx = namespace_tree_context(path=self.resolved_paths) - self.ctx.__enter__() - - def tearDown(self): - # TODO: will we ever want to pass exc_info to __exit__? - self.ctx.__exit__(None, None, None) + self.enterContext(namespace_tree_context(path=self.resolved_paths)) class SingleNamespacePackage(NamespacePackageTest): @@ -83,12 +79,9 @@ class SingleNamespacePackage(NamespacePackageTest): with self.assertRaises(ImportError): import foo.two - def test_module_repr(self): + def test_simple_repr(self): import foo.one - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - self.assertEqual(foo.__spec__.loader.module_repr(foo), - "") + assert repr(foo).startswith("'.format(module.__name__) - self.module.__loader__ = Loader() - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, '') - - def test_module___loader___module_repr_bad(self): - class Loader(TestLoader): - def module_repr(self, module): - raise Exception - self.module.__loader__ = Loader() - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, - ')>'.format('spam')) - - def test_module___spec__(self): - origin = 'in a hole, in the ground' - self.spec.origin = origin - self.module.__spec__ = self.spec - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, ''.format('spam', origin)) - - def test_module___spec___location(self): - location = 'in_a_galaxy_far_far_away.py' - self.spec.origin = location - self.spec._set_fileattr = True - self.module.__spec__ = self.spec - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, - ''.format('spam', location)) - - def test_module___spec___no_origin(self): - self.spec.loader = TestLoader() - self.module.__spec__ = self.spec - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, - ')>'.format('spam')) - - def test_module___spec___no_origin_no_loader(self): - self.spec.loader = None - self.module.__spec__ = self.spec - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, ''.format('spam')) - - def test_module_no_name(self): - del self.module.__name__ - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, ''.format('?')) - - def test_module_with_file(self): - filename = 'e/i/e/i/o/spam.py' - self.module.__file__ = filename - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, - ''.format('spam', filename)) - - def test_module_no_file(self): - self.module.__loader__ = TestLoader() - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, - ')>'.format('spam')) - - def test_module_no_file_no_loader(self): - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, ''.format('spam')) - - -(Frozen_ModuleReprTests, - Source_ModuleReprTests - ) = test_util.test_both(ModuleReprTests, init=init, util=util, - machinery=machinery) - - class FactoryTests: def setUp(self): diff --git a/Lib/test/test_importlib/test_threaded_import.py b/Lib/test/test_importlib/test_threaded_import.py index 76b028eac97..85c3032aed5 100644 --- a/Lib/test/test_importlib/test_threaded_import.py +++ b/Lib/test/test_importlib/test_threaded_import.py @@ -15,10 +15,12 @@ import threading import unittest from unittest import mock from test.support import verbose -from test.support.import_helper import forget +from test.support.import_helper import forget, mock_register_at_fork from test.support.os_helper import (TESTFN, unlink, rmtree) from test.support import script_helper, threading_helper +threading_helper.requires_working_threading(module=True) + def task(N, done, done_tasks, errors): try: # We don't use modulefinder but still import it in order to stress @@ -39,12 +41,6 @@ def task(N, done, done_tasks, errors): if finished: done.set() -def mock_register_at_fork(func): - # bpo-30599: Mock os.register_at_fork() when importing the random module, - # since this function doesn't allow to unregister callbacks and would leak - # memory. - return mock.patch('os.register_at_fork', create=True)(func) - # Create a circular import structure: A -> C -> B -> D -> A # NOTE: `time` is already loaded and therefore doesn't threaten to deadlock. @@ -270,4 +266,4 @@ def setUpModule(): if __name__ == "__main__": - unittets.main() + unittest.main() diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index 104452267c0..08a615ecf52 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -1,4 +1,5 @@ -from . import util +from test.test_importlib import util + abc = util.import_importlib('importlib.abc') init = util.import_importlib('importlib') machinery = util.import_importlib('importlib.machinery') @@ -120,247 +121,6 @@ class ModuleFromSpecTests: util=importlib_util) -class ModuleForLoaderTests: - - """Tests for importlib.util.module_for_loader.""" - - @classmethod - def module_for_loader(cls, func): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - return cls.util.module_for_loader(func) - - def test_warning(self): - # Should raise a PendingDeprecationWarning when used. - with warnings.catch_warnings(): - warnings.simplefilter('error', DeprecationWarning) - with self.assertRaises(DeprecationWarning): - func = self.util.module_for_loader(lambda x: x) - - def return_module(self, name): - fxn = self.module_for_loader(lambda self, module: module) - return fxn(self, name) - - def raise_exception(self, name): - def to_wrap(self, module): - raise ImportError - fxn = self.module_for_loader(to_wrap) - try: - fxn(self, name) - except ImportError: - pass - - def test_new_module(self): - # Test that when no module exists in sys.modules a new module is - # created. - module_name = 'a.b.c' - with util.uncache(module_name): - module = self.return_module(module_name) - self.assertIn(module_name, sys.modules) - self.assertIsInstance(module, types.ModuleType) - self.assertEqual(module.__name__, module_name) - - def test_reload(self): - # Test that a module is reused if already in sys.modules. - class FakeLoader: - def is_package(self, name): - return True - @self.module_for_loader - def load_module(self, module): - return module - name = 'a.b.c' - module = types.ModuleType('a.b.c') - module.__loader__ = 42 - module.__package__ = 42 - with util.uncache(name): - sys.modules[name] = module - loader = FakeLoader() - returned_module = loader.load_module(name) - self.assertIs(returned_module, sys.modules[name]) - self.assertEqual(module.__loader__, loader) - self.assertEqual(module.__package__, name) - - def test_new_module_failure(self): - # Test that a module is removed from sys.modules if added but an - # exception is raised. - name = 'a.b.c' - with util.uncache(name): - self.raise_exception(name) - self.assertNotIn(name, sys.modules) - - def test_reload_failure(self): - # Test that a failure on reload leaves the module in-place. - name = 'a.b.c' - module = types.ModuleType(name) - with util.uncache(name): - sys.modules[name] = module - self.raise_exception(name) - self.assertIs(module, sys.modules[name]) - - def test_decorator_attrs(self): - def fxn(self, module): pass - wrapped = self.module_for_loader(fxn) - self.assertEqual(wrapped.__name__, fxn.__name__) - self.assertEqual(wrapped.__qualname__, fxn.__qualname__) - - def test_false_module(self): - # If for some odd reason a module is considered false, still return it - # from sys.modules. - class FalseModule(types.ModuleType): - def __bool__(self): return False - - name = 'mod' - module = FalseModule(name) - with util.uncache(name): - self.assertFalse(module) - sys.modules[name] = module - given = self.return_module(name) - self.assertIs(given, module) - - def test_attributes_set(self): - # __name__, __loader__, and __package__ should be set (when - # is_package() is defined; undefined implicitly tested elsewhere). - class FakeLoader: - def __init__(self, is_package): - self._pkg = is_package - def is_package(self, name): - return self._pkg - @self.module_for_loader - def load_module(self, module): - return module - - name = 'pkg.mod' - with util.uncache(name): - loader = FakeLoader(False) - module = loader.load_module(name) - self.assertEqual(module.__name__, name) - self.assertIs(module.__loader__, loader) - self.assertEqual(module.__package__, 'pkg') - - name = 'pkg.sub' - with util.uncache(name): - loader = FakeLoader(True) - module = loader.load_module(name) - self.assertEqual(module.__name__, name) - self.assertIs(module.__loader__, loader) - self.assertEqual(module.__package__, name) - - -(Frozen_ModuleForLoaderTests, - Source_ModuleForLoaderTests - ) = util.test_both(ModuleForLoaderTests, util=importlib_util) - - -class SetPackageTests: - - """Tests for importlib.util.set_package.""" - - def verify(self, module, expect): - """Verify the module has the expected value for __package__ after - passing through set_package.""" - fxn = lambda: module - wrapped = self.util.set_package(fxn) - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - wrapped() - self.assertTrue(hasattr(module, '__package__')) - self.assertEqual(expect, module.__package__) - - def test_top_level(self): - # __package__ should be set to the empty string if a top-level module. - # Implicitly tests when package is set to None. - module = types.ModuleType('module') - module.__package__ = None - self.verify(module, '') - - def test_package(self): - # Test setting __package__ for a package. - module = types.ModuleType('pkg') - module.__path__ = [''] - module.__package__ = None - self.verify(module, 'pkg') - - def test_submodule(self): - # Test __package__ for a module in a package. - module = types.ModuleType('pkg.mod') - module.__package__ = None - self.verify(module, 'pkg') - - def test_setting_if_missing(self): - # __package__ should be set if it is missing. - module = types.ModuleType('mod') - if hasattr(module, '__package__'): - delattr(module, '__package__') - self.verify(module, '') - - def test_leaving_alone(self): - # If __package__ is set and not None then leave it alone. - for value in (True, False): - module = types.ModuleType('mod') - module.__package__ = value - self.verify(module, value) - - def test_decorator_attrs(self): - def fxn(module): pass - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - wrapped = self.util.set_package(fxn) - self.assertEqual(wrapped.__name__, fxn.__name__) - self.assertEqual(wrapped.__qualname__, fxn.__qualname__) - - -(Frozen_SetPackageTests, - Source_SetPackageTests - ) = util.test_both(SetPackageTests, util=importlib_util) - - -class SetLoaderTests: - - """Tests importlib.util.set_loader().""" - - @property - def DummyLoader(self): - # Set DummyLoader on the class lazily. - class DummyLoader: - @self.util.set_loader - def load_module(self, module): - return self.module - self.__class__.DummyLoader = DummyLoader - return DummyLoader - - def test_no_attribute(self): - loader = self.DummyLoader() - loader.module = types.ModuleType('blah') - try: - del loader.module.__loader__ - except AttributeError: - pass - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - self.assertEqual(loader, loader.load_module('blah').__loader__) - - def test_attribute_is_None(self): - loader = self.DummyLoader() - loader.module = types.ModuleType('blah') - loader.module.__loader__ = None - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - self.assertEqual(loader, loader.load_module('blah').__loader__) - - def test_not_reset(self): - loader = self.DummyLoader() - loader.module = types.ModuleType('blah') - loader.module.__loader__ = 42 - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - self.assertEqual(42, loader.load_module('blah').__loader__) - - -(Frozen_SetLoaderTests, - Source_SetLoaderTests - ) = util.test_both(SetLoaderTests, util=importlib_util) - - class ResolveNameTests: """Tests importlib.util.resolve_name().""" @@ -859,7 +619,7 @@ class MagicNumberTests(unittest.TestCase): # stakeholders such as OS package maintainers must be notified # in advance. Such exceptional releases will then require an # adjustment to this test case. - EXPECTED_MAGIC_NUMBER = 3413 + EXPECTED_MAGIC_NUMBER = 3495 actual = int.from_bytes(importlib.util.MAGIC_NUMBER[:2], 'little') msg = ( diff --git a/Lib/test/test_importlib/test_windows.py b/Lib/test/test_importlib/test_windows.py index 6f09c5a7a5a..b7dfe865a03 100644 --- a/Lib/test/test_importlib/test_windows.py +++ b/Lib/test/test_importlib/test_windows.py @@ -1,4 +1,4 @@ -from . import util as test_util +from test.test_importlib import util as test_util machinery = test_util.import_importlib('importlib.machinery') import os @@ -6,10 +6,9 @@ import re import sys import unittest import warnings -from test import support from test.support import import_helper from contextlib import contextmanager -from .util import temp_module +from test.test_importlib.util import temp_module import_helper.import_module('winreg', required_on=['win']) from winreg import ( @@ -61,17 +60,28 @@ def setup_module(machinery, name, path=None): root = machinery.WindowsRegistryFinder.REGISTRY_KEY key = root.format(fullname=name, sys_version='%d.%d' % sys.version_info[:2]) + base_key = "Software\\Python\\PythonCore\\{}.{}".format( + sys.version_info.major, sys.version_info.minor) + assert key.casefold().startswith(base_key.casefold()), ( + "expected key '{}' to start with '{}'".format(key, base_key)) try: with temp_module(name, "a = 1") as location: + try: + OpenKey(HKEY_CURRENT_USER, base_key) + if machinery.WindowsRegistryFinder.DEBUG_BUILD: + delete_key = os.path.dirname(key) + else: + delete_key = key + except OSError: + delete_key = base_key subkey = CreateKey(HKEY_CURRENT_USER, key) if path is None: path = location + ".py" SetValue(subkey, "", REG_SZ, path) yield finally: - if machinery.WindowsRegistryFinder.DEBUG_BUILD: - key = os.path.dirname(key) - delete_registry_tree(HKEY_CURRENT_USER, key) + if delete_key: + delete_registry_tree(HKEY_CURRENT_USER, delete_key) @unittest.skipUnless(sys.platform.startswith('win'), 'requires Windows') @@ -178,3 +188,6 @@ class WindowsBootstrapPathTests(unittest.TestCase): self.check_join("C:", "C:", "") self.check_join("//Server/Share\\", "//Server/Share/", "") self.check_join("//Server/Share\\", "//Server/Share", "") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_importlib/test_zip.py b/Lib/test/test_importlib/test_zip.py index bf16a3b95e1..276f6288c91 100644 --- a/Lib/test/test_importlib/test_zip.py +++ b/Lib/test/test_importlib/test_zip.py @@ -1,7 +1,7 @@ import sys import unittest -from contextlib import ExitStack +from . import fixtures from importlib.metadata import ( PackageNotFoundError, distribution, @@ -10,27 +10,11 @@ from importlib.metadata import ( files, version, ) -from importlib import resources - -from test.support import requires_zlib -@requires_zlib() -class TestZip(unittest.TestCase): - root = 'test.test_importlib.data' - - def _fixture_on_path(self, filename): - pkg_file = resources.files(self.root).joinpath(filename) - file = self.resources.enter_context(resources.as_file(pkg_file)) - assert file.name.startswith('example-'), file.name - sys.path.insert(0, str(file)) - self.resources.callback(sys.path.pop, 0) - +class TestZip(fixtures.ZipFixtures, unittest.TestCase): def setUp(self): - # Find the path to the example-*.whl so we can add it to the front of - # sys.path, where we'll then try to find the metadata thereof. - self.resources = ExitStack() - self.addCleanup(self.resources.close) + super().setUp() self._fixture_on_path('example-21.12-py3-none-any.whl') def test_zip_version(self): @@ -63,13 +47,9 @@ class TestZip(unittest.TestCase): assert len(dists) == 1 -@requires_zlib() class TestEgg(TestZip): def setUp(self): - # Find the path to the example-*.egg so we can add it to the front of - # sys.path, where we'll then try to find the metadata thereof. - self.resources = ExitStack() - self.addCleanup(self.resources.close) + super().setUp() self._fixture_on_path('example-21.12-py3.6.egg') def test_files(self): diff --git a/Lib/test/test_importlib/util.py b/Lib/test/test_importlib/util.py index c07ac2a64c2..9032fd18d3f 100644 --- a/Lib/test/test_importlib/util.py +++ b/Lib/test/test_importlib/util.py @@ -27,7 +27,7 @@ EXTENSIONS.path = None EXTENSIONS.ext = None EXTENSIONS.filename = None EXTENSIONS.file_path = None -EXTENSIONS.name = '_testcapi' +EXTENSIONS.name = '_testsinglephase' def _extension_details(): global EXTENSIONS @@ -298,7 +298,7 @@ def writes_bytecode_files(fxn): """Decorator to protect sys.dont_write_bytecode from mutation and to skip tests that require it to be set to False.""" if sys.dont_write_bytecode: - return lambda *args, **kwargs: None + return unittest.skip("relies on writing bytecode")(fxn) @functools.wraps(fxn) def wrapper(*args, **kwargs): original = sys.dont_write_bytecode diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index d43486a2191..92aba519d28 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -7,6 +7,7 @@ import inspect import io import linecache import os +import dis from os.path import normcase import _pickle import pickle @@ -44,7 +45,8 @@ from test.test_import import _ready_to_import # isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers, # getdoc, getfile, getmodule, getsourcefile, getcomments, getsource, # getclasstree, getargvalues, formatargvalues, -# currentframe, stack, trace, isdatadescriptor +# currentframe, stack, trace, isdatadescriptor, +# ismethodwrapper # NOTE: There are some additional tests relating to interaction with # zipimport in the test_zipimport_support test module. @@ -93,7 +95,8 @@ class IsTestBase(unittest.TestCase): inspect.ismodule, inspect.istraceback, inspect.isgenerator, inspect.isgeneratorfunction, inspect.iscoroutine, inspect.iscoroutinefunction, - inspect.isasyncgen, inspect.isasyncgenfunction]) + inspect.isasyncgen, inspect.isasyncgenfunction, + inspect.ismethodwrapper]) def istest(self, predicate, exp): obj = eval(exp) @@ -107,6 +110,9 @@ class IsTestBase(unittest.TestCase): continue self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp)) + def test__all__(self): + support.check__all__(self, inspect, not_exported=("modulesbyfile",)) + def generator_function_example(self): for i in range(2): yield i @@ -132,8 +138,8 @@ class TestPredicates(IsTestBase): self.istest(inspect.iscode, 'mod.spam.__code__') try: 1/0 - except: - tb = sys.exc_info()[2] + except Exception as e: + tb = e.__traceback__ self.istest(inspect.isframe, 'tb.tb_frame') self.istest(inspect.istraceback, 'tb') if hasattr(types, 'GetSetDescriptorType'): @@ -166,6 +172,14 @@ class TestPredicates(IsTestBase): self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days') else: self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days)) + self.istest(inspect.ismethodwrapper, "object().__str__") + self.istest(inspect.ismethodwrapper, "object().__eq__") + self.istest(inspect.ismethodwrapper, "object().__repr__") + self.assertFalse(inspect.ismethodwrapper(type)) + self.assertFalse(inspect.ismethodwrapper(int)) + self.assertFalse(inspect.ismethodwrapper(type("AnyClass", (), {}))) + + def test_iscoroutine(self): async_gen_coro = async_generator_function_example(1) @@ -188,6 +202,63 @@ class TestPredicates(IsTestBase): gen_coroutine_function_example)))) self.assertTrue(inspect.isgenerator(gen_coro)) + async def _fn3(): + pass + + @inspect.markcoroutinefunction + def fn3(): + return _fn3() + + self.assertTrue(inspect.iscoroutinefunction(fn3)) + self.assertTrue( + inspect.iscoroutinefunction( + inspect.markcoroutinefunction(lambda: _fn3()) + ) + ) + + class Cl: + async def __call__(self): + pass + + self.assertFalse(inspect.iscoroutinefunction(Cl)) + # instances with async def __call__ are NOT recognised. + self.assertFalse(inspect.iscoroutinefunction(Cl())) + # unless explicitly marked. + self.assertTrue(inspect.iscoroutinefunction( + inspect.markcoroutinefunction(Cl()) + )) + + class Cl2: + @inspect.markcoroutinefunction + def __call__(self): + pass + + self.assertFalse(inspect.iscoroutinefunction(Cl2)) + # instances with marked __call__ are NOT recognised. + self.assertFalse(inspect.iscoroutinefunction(Cl2())) + # unless explicitly marked. + self.assertTrue(inspect.iscoroutinefunction( + inspect.markcoroutinefunction(Cl2()) + )) + + class Cl3: + @inspect.markcoroutinefunction + @classmethod + def do_something_classy(cls): + pass + + @inspect.markcoroutinefunction + @staticmethod + def do_something_static(): + pass + + self.assertTrue(inspect.iscoroutinefunction(Cl3.do_something_classy)) + self.assertTrue(inspect.iscoroutinefunction(Cl3.do_something_static)) + + self.assertFalse( + inspect.iscoroutinefunction(unittest.mock.Mock())) + self.assertTrue( + inspect.iscoroutinefunction(unittest.mock.AsyncMock())) self.assertTrue( inspect.iscoroutinefunction(coroutine_function_example)) self.assertTrue( @@ -196,6 +267,10 @@ class TestPredicates(IsTestBase): coroutine_function_example)))) self.assertTrue(inspect.iscoroutine(coro)) + self.assertFalse( + inspect.isgeneratorfunction(unittest.mock.Mock())) + self.assertFalse( + inspect.isgeneratorfunction(unittest.mock.AsyncMock())) self.assertFalse( inspect.isgeneratorfunction(coroutine_function_example)) self.assertFalse( @@ -204,6 +279,12 @@ class TestPredicates(IsTestBase): coroutine_function_example)))) self.assertFalse(inspect.isgenerator(coro)) + self.assertFalse( + inspect.isasyncgenfunction(unittest.mock.Mock())) + self.assertFalse( + inspect.isasyncgenfunction(unittest.mock.AsyncMock())) + self.assertFalse( + inspect.isasyncgenfunction(coroutine_function_example)) self.assertTrue( inspect.isasyncgenfunction(async_generator_function_example)) self.assertTrue( @@ -238,8 +319,38 @@ class TestPredicates(IsTestBase): coro.close(); gen_coro.close() # silence warnings def test_isroutine(self): - self.assertTrue(inspect.isroutine(mod.spam)) + # method + self.assertTrue(inspect.isroutine(git.argue)) + self.assertTrue(inspect.isroutine(mod.custom_method)) self.assertTrue(inspect.isroutine([].count)) + # function + self.assertTrue(inspect.isroutine(mod.spam)) + self.assertTrue(inspect.isroutine(mod.StupidGit.abuse)) + # slot-wrapper + self.assertTrue(inspect.isroutine(object.__init__)) + self.assertTrue(inspect.isroutine(object.__str__)) + self.assertTrue(inspect.isroutine(object.__lt__)) + self.assertTrue(inspect.isroutine(int.__lt__)) + # method-wrapper + self.assertTrue(inspect.isroutine(object().__init__)) + self.assertTrue(inspect.isroutine(object().__str__)) + self.assertTrue(inspect.isroutine(object().__lt__)) + self.assertTrue(inspect.isroutine((42).__lt__)) + # method-descriptor + self.assertTrue(inspect.isroutine(str.join)) + self.assertTrue(inspect.isroutine(list.append)) + self.assertTrue(inspect.isroutine(''.join)) + self.assertTrue(inspect.isroutine([].append)) + # object + self.assertFalse(inspect.isroutine(object)) + self.assertFalse(inspect.isroutine(object())) + self.assertFalse(inspect.isroutine(str())) + # module + self.assertFalse(inspect.isroutine(mod)) + # type + self.assertFalse(inspect.isroutine(type)) + self.assertFalse(inspect.isroutine(int)) + self.assertFalse(inspect.isroutine(type('some_class', (), {}))) def test_isclass(self): self.istest(inspect.isclass, 'mod.StupidGit') @@ -318,14 +429,23 @@ class TestInterpreterStack(IsTestBase): def test_stack(self): self.assertTrue(len(mod.st) >= 5) - self.assertEqual(revise(*mod.st[0][1:]), + frame1, frame2, frame3, frame4, *_ = mod.st + frameinfo = revise(*frame1[1:]) + self.assertEqual(frameinfo, (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0)) - self.assertEqual(revise(*mod.st[1][1:]), + self.assertEqual(frame1.positions, dis.Positions(16, 16, 9, 24)) + frameinfo = revise(*frame2[1:]) + self.assertEqual(frameinfo, (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0)) - self.assertEqual(revise(*mod.st[2][1:]), + self.assertEqual(frame2.positions, dis.Positions(9, 9, 4, 22)) + frameinfo = revise(*frame3[1:]) + self.assertEqual(frameinfo, (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0)) - self.assertEqual(revise(*mod.st[3][1:]), + self.assertEqual(frame3.positions, dis.Positions(43, 43, 12, 25)) + frameinfo = revise(*frame4[1:]) + self.assertEqual(frameinfo, (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0)) + self.assertEqual(frame4.positions, dis.Positions(39, 39, 8, 27)) # Test named tuple fields record = mod.st[0] self.assertIs(record.frame, mod.fr) @@ -337,12 +457,16 @@ class TestInterpreterStack(IsTestBase): def test_trace(self): self.assertEqual(len(git.tr), 3) - self.assertEqual(revise(*git.tr[0][1:]), + frame1, frame2, frame3, = git.tr + self.assertEqual(revise(*frame1[1:]), (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0)) - self.assertEqual(revise(*git.tr[1][1:]), + self.assertEqual(frame1.positions, dis.Positions(43, 43, 12, 25)) + self.assertEqual(revise(*frame2[1:]), (modfile, 9, 'spam', [' eggs(b + d, c + f)\n'], 0)) - self.assertEqual(revise(*git.tr[2][1:]), + self.assertEqual(frame2.positions, dis.Positions(9, 9, 4, 22)) + self.assertEqual(revise(*frame3[1:]), (modfile, 18, 'eggs', [' q = y / 0\n'], 0)) + self.assertEqual(frame3.positions, dis.Positions(18, 18, 8, 13)) def test_frame(self): args, varargs, varkw, locals = inspect.getargvalues(mod.fr) @@ -785,6 +909,10 @@ class TestBuggyCases(GetSourceBase): self.assertSourceEqual(mod2.cls213, 218, 222) self.assertSourceEqual(mod2.cls213().func219(), 220, 221) + @unittest.skipIf( + support.is_emscripten or support.is_wasi, + "socket.accept is broken" + ) def test_nested_class_definition_inside_async_function(self): import asyncio self.addCleanup(asyncio.set_event_loop_policy, None) @@ -811,6 +939,12 @@ class TestNoEOL(GetSourceBase): self.assertSourceEqual(self.fodderModule.X, 1, 2) +class TestComplexDecorator(GetSourceBase): + fodderModule = mod2 + + def test_parens_in_decorator(self): + self.assertSourceEqual(self.fodderModule.complex_decorated, 273, 275) + class _BrokenDataDescriptor(object): """ A broken data descriptor. See bug #1785. @@ -1212,8 +1346,30 @@ class TestClassesAndFunctions(unittest.TestCase): @types.DynamicClassAttribute def eggs(self): return 'spam' + class B: + def __getattr__(self, attribute): + return None self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A)) self.assertIn(('eggs', 'spam'), inspect.getmembers(A())) + b = B() + self.assertIn(('__getattr__', b.__getattr__), inspect.getmembers(b)) + + def test_getmembers_static(self): + class A: + @property + def name(self): + raise NotImplementedError + @types.DynamicClassAttribute + def eggs(self): + raise NotImplementedError + + a = A() + instance_members = inspect.getmembers_static(a) + class_members = inspect.getmembers_static(A) + self.assertIn(('name', inspect.getattr_static(a, 'name')), instance_members) + self.assertIn(('eggs', inspect.getattr_static(a, 'eggs')), instance_members) + self.assertIn(('name', inspect.getattr_static(A, 'name')), class_members) + self.assertIn(('eggs', inspect.getattr_static(A, 'eggs')), class_members) def test_getmembers_with_buggy_dir(self): class M(type): @@ -1324,6 +1480,13 @@ class TestClassesAndFunctions(unittest.TestCase): self.assertEqual(inspect.get_annotations(isa.MyClassWithLocalAnnotations, eval_str=True), {'x': int}) +class TestFormatAnnotation(unittest.TestCase): + def test_typing_replacement(self): + from test.typinganndata.ann_module9 import ann, ann1 + self.assertEqual(inspect.formatannotation(ann), 'Union[List[str], int]') + self.assertEqual(inspect.formatannotation(ann1), 'Union[List[testModule.typing.A], int]') + + class TestIsDataDescriptor(unittest.TestCase): def test_custom_descriptors(self): @@ -2370,7 +2533,7 @@ class TestSignatureObject(unittest.TestCase): self.assertEqual(p('f'), False) self.assertEqual(p('local'), 3) self.assertEqual(p('sys'), sys.maxsize) - self.assertNotIn('exp', signature.parameters) + self.assertEqual(p('exp'), sys.maxsize - 1) test_callable(object) @@ -2856,8 +3019,6 @@ class TestSignatureObject(unittest.TestCase): self.assertEqual(str(inspect.signature(foo)), '(a)') def test_signature_on_decorated(self): - import functools - def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs) -> int: @@ -2869,6 +3030,8 @@ class TestSignatureObject(unittest.TestCase): def bar(self, a, b): pass + bar = decorator(Foo().bar) + self.assertEqual(self.signature(Foo.bar), ((('self', ..., ..., "positional_or_keyword"), ('a', ..., ..., "positional_or_keyword"), @@ -2887,6 +3050,11 @@ class TestSignatureObject(unittest.TestCase): # from "func" to "wrapper", hence no # return_annotation + self.assertEqual(self.signature(bar), + ((('a', ..., ..., "positional_or_keyword"), + ('b', ..., ..., "positional_or_keyword")), + ...)) + # Test that we handle method wrappers correctly def decorator(func): @functools.wraps(func) @@ -3123,6 +3291,25 @@ class TestSignatureObject(unittest.TestCase): ((('a', 10, ..., "positional_or_keyword"),), ...)) + def test_signature_on_mocks(self): + # https://github.com/python/cpython/issues/96127 + for mock in ( + unittest.mock.Mock(), + unittest.mock.AsyncMock(), + unittest.mock.MagicMock(), + ): + with self.subTest(mock=mock): + self.assertEqual(str(inspect.signature(mock)), '(*args, **kwargs)') + + def test_signature_on_noncallable_mocks(self): + for mock in ( + unittest.mock.NonCallableMock(), + unittest.mock.NonCallableMagicMock(), + ): + with self.subTest(mock=mock): + with self.assertRaises(TypeError): + inspect.signature(mock) + def test_signature_equality(self): def foo(a, *, b:int) -> float: pass self.assertFalse(inspect.signature(foo) == 42) @@ -3499,6 +3686,38 @@ class TestSignatureObject(unittest.TestCase): self.assertEqual(signature_func(foo), inspect.Signature()) self.assertEqual(inspect.get_annotations(foo), {}) + def test_signature_as_str(self): + self.maxDiff = None + class S: + __signature__ = '(a, b=2)' + + self.assertEqual(self.signature(S), + ((('a', ..., ..., 'positional_or_keyword'), + ('b', 2, ..., 'positional_or_keyword')), + ...)) + + def test_signature_as_callable(self): + # __signature__ should be either a staticmethod or a bound classmethod + class S: + @classmethod + def __signature__(cls): + return '(a, b=2)' + + self.assertEqual(self.signature(S), + ((('a', ..., ..., 'positional_or_keyword'), + ('b', 2, ..., 'positional_or_keyword')), + ...)) + + class S: + @staticmethod + def __signature__(): + return '(a, b=2)' + + self.assertEqual(self.signature(S), + ((('a', ..., ..., 'positional_or_keyword'), + ('b', 2, ..., 'positional_or_keyword')), + ...)) + class TestParameterObject(unittest.TestCase): def test_signature_parameter_kinds(self): @@ -3524,6 +3743,9 @@ class TestParameterObject(unittest.TestCase): with self.assertRaisesRegex(ValueError, 'not a valid parameter name'): inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD) + with self.assertRaisesRegex(ValueError, 'not a valid parameter name'): + inspect.Parameter('from', kind=inspect.Parameter.VAR_KEYWORD) + with self.assertRaisesRegex(TypeError, 'name must be a str'): inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD) @@ -3791,7 +4013,8 @@ class TestSignatureBind(unittest.TestCase): self.call(test, 1, bar=2, spam='ham') with self.assertRaisesRegex(TypeError, - "missing a required argument: 'bar'"): + "missing a required keyword-only " + "argument: 'bar'"): self.call(test, 1) def test(foo, *, bar, **bin): @@ -4127,10 +4350,40 @@ class TestSignatureDefinitions(unittest.TestCase): sig = inspect.signature(func) self.assertIsNotNone(sig) self.assertEqual(str(sig), '(self, /, a, b=1, *args, c, d=2, **kwargs)') + func.__text_signature__ = '($self, a, b=1, /, *args, c, d=2, **kwargs)' sig = inspect.signature(func) self.assertEqual(str(sig), '(self, a, b=1, /, *args, c, d=2, **kwargs)') + func.__text_signature__ = '(self, a=1+2, b=4-3, c=1 | 3 | 16)' + sig = inspect.signature(func) + self.assertEqual(str(sig), '(self, a=3, b=1, c=19)') + + func.__text_signature__ = '(self, a=1,\nb=2,\n\n\n c=3)' + sig = inspect.signature(func) + self.assertEqual(str(sig), '(self, a=1, b=2, c=3)') + + func.__text_signature__ = '(self, x=does_not_exist)' + with self.assertRaises(ValueError): + inspect.signature(func) + func.__text_signature__ = '(self, x=sys, y=inspect)' + with self.assertRaises(ValueError): + inspect.signature(func) + func.__text_signature__ = '(self, 123)' + with self.assertRaises(ValueError): + inspect.signature(func) + + def test_base_class_have_text_signature(self): + # see issue 43118 + from test.ann_module7 import BufferedReader + class MyBufferedReader(BufferedReader): + """buffer reader class.""" + + text_signature = BufferedReader.__text_signature__ + self.assertEqual(text_signature, '(raw, buffer_size=DEFAULT_BUFFER_SIZE)') + sig = inspect.signature(MyBufferedReader) + self.assertEqual(str(sig), '(raw, buffer_size=8192)') + class NTimesUnwrappable: def __init__(self, n): @@ -4247,8 +4500,11 @@ class TestMain(unittest.TestCase): 'unittest', '--details') output = out.decode() # Just a quick sanity check on the output + self.assertIn(module.__spec__.name, output) self.assertIn(module.__name__, output) + self.assertIn(module.__spec__.origin, output) self.assertIn(module.__file__, output) + self.assertIn(module.__spec__.cached, output) self.assertIn(module.__cached__, output) self.assertEqual(err, b'') diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py index d6be64e7c18..334fea0774b 100644 --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -1,10 +1,17 @@ import sys +import time import unittest +from unittest import mock from test import support from test.test_grammar import (VALID_UNDERSCORE_LITERALS, INVALID_UNDERSCORE_LITERALS) +try: + import _pylong +except ImportError: + _pylong = None + L = [ ('0', 0), ('1', 1), @@ -369,12 +376,14 @@ class IntTestCases(unittest.TestCase): class JustTrunc(base): def __trunc__(self): return 42 - self.assertEqual(int(JustTrunc()), 42) + with self.assertWarns(DeprecationWarning): + self.assertEqual(int(JustTrunc()), 42) class ExceptionalTrunc(base): def __trunc__(self): 1 / 0 - with self.assertRaises(ZeroDivisionError): + with self.assertRaises(ZeroDivisionError), \ + self.assertWarns(DeprecationWarning): int(ExceptionalTrunc()) for trunc_result_base in (object, Classic): @@ -385,7 +394,8 @@ class IntTestCases(unittest.TestCase): class TruncReturnsNonInt(base): def __trunc__(self): return Index() - self.assertEqual(int(TruncReturnsNonInt()), 42) + with self.assertWarns(DeprecationWarning): + self.assertEqual(int(TruncReturnsNonInt()), 42) class Intable(trunc_result_base): def __int__(self): @@ -394,7 +404,8 @@ class IntTestCases(unittest.TestCase): class TruncReturnsNonIndex(base): def __trunc__(self): return Intable() - self.assertEqual(int(TruncReturnsNonInt()), 42) + with self.assertWarns(DeprecationWarning): + self.assertEqual(int(TruncReturnsNonInt()), 42) class NonIntegral(trunc_result_base): def __trunc__(self): @@ -405,7 +416,8 @@ class IntTestCases(unittest.TestCase): def __trunc__(self): return NonIntegral() try: - int(TruncReturnsNonIntegral()) + with self.assertWarns(DeprecationWarning): + int(TruncReturnsNonIntegral()) except TypeError as e: self.assertEqual(str(e), "__trunc__ returned non-Integral" @@ -423,7 +435,8 @@ class IntTestCases(unittest.TestCase): def __trunc__(self): return BadInt() - with self.assertRaises(TypeError): + with self.assertRaises(TypeError), \ + self.assertWarns(DeprecationWarning): int(TruncReturnsBadInt()) def test_int_subclass_with_index(self): @@ -517,13 +530,16 @@ class IntTestCases(unittest.TestCase): self.assertIs(type(n), int) bad_int = TruncReturnsBadInt() - self.assertRaises(TypeError, int, bad_int) + with self.assertWarns(DeprecationWarning): + self.assertRaises(TypeError, int, bad_int) good_int = TruncReturnsIntSubclass() - n = int(good_int) + with self.assertWarns(DeprecationWarning): + n = int(good_int) self.assertEqual(n, 1) self.assertIs(type(n), int) - n = IntSubclass(good_int) + with self.assertWarns(DeprecationWarning): + n = IntSubclass(good_int) self.assertEqual(n, 1) self.assertIs(type(n), IntSubclass) @@ -568,5 +584,302 @@ class IntTestCases(unittest.TestCase): self.assertEqual(int('1_2_3_4_5_6_7', 32), 1144132807) +class IntStrDigitLimitsTests(unittest.TestCase): + + int_class = int # Override this in subclasses to reuse the suite. + + def setUp(self): + super().setUp() + self._previous_limit = sys.get_int_max_str_digits() + sys.set_int_max_str_digits(2048) + + def tearDown(self): + sys.set_int_max_str_digits(self._previous_limit) + super().tearDown() + + def test_disabled_limit(self): + self.assertGreater(sys.get_int_max_str_digits(), 0) + self.assertLess(sys.get_int_max_str_digits(), 20_000) + with support.adjust_int_max_str_digits(0): + self.assertEqual(sys.get_int_max_str_digits(), 0) + i = self.int_class('1' * 20_000) + str(i) + self.assertGreater(sys.get_int_max_str_digits(), 0) + + def test_max_str_digits_edge_cases(self): + """Ignore the +/- sign and space padding.""" + int_class = self.int_class + maxdigits = sys.get_int_max_str_digits() + + int_class('1' * maxdigits) + int_class(' ' + '1' * maxdigits) + int_class('1' * maxdigits + ' ') + int_class('+' + '1' * maxdigits) + int_class('-' + '1' * maxdigits) + self.assertEqual(len(str(10 ** (maxdigits - 1))), maxdigits) + + def check(self, i, base=None): + with self.assertRaises(ValueError): + if base is None: + self.int_class(i) + else: + self.int_class(i, base) + + def test_max_str_digits(self): + maxdigits = sys.get_int_max_str_digits() + + self.check('1' * (maxdigits + 1)) + self.check(' ' + '1' * (maxdigits + 1)) + self.check('1' * (maxdigits + 1) + ' ') + self.check('+' + '1' * (maxdigits + 1)) + self.check('-' + '1' * (maxdigits + 1)) + self.check('1' * (maxdigits + 1)) + + i = 10 ** maxdigits + with self.assertRaises(ValueError): + str(i) + + def test_denial_of_service_prevented_int_to_str(self): + """Regression test: ensure we fail before performing O(N**2) work.""" + maxdigits = sys.get_int_max_str_digits() + assert maxdigits < 50_000, maxdigits # A test prerequisite. + get_time = time.process_time + if get_time() <= 0: # some platforms like WASM lack process_time() + get_time = time.monotonic + + huge_int = int(f'0x{"c"*65_000}', base=16) # 78268 decimal digits. + digits = 78_268 + with support.adjust_int_max_str_digits(digits): + start = get_time() + huge_decimal = str(huge_int) + seconds_to_convert = get_time() - start + self.assertEqual(len(huge_decimal), digits) + # Ensuring that we chose a slow enough conversion to measure. + # It takes 0.1 seconds on a Zen based cloud VM in an opt build. + # Some OSes have a low res 1/64s timer, skip if hard to measure. + if seconds_to_convert < 1/64: + raise unittest.SkipTest('"slow" conversion took only ' + f'{seconds_to_convert} seconds.') + + # We test with the limit almost at the size needed to check performance. + # The performant limit check is slightly fuzzy, give it a some room. + with support.adjust_int_max_str_digits(int(.995 * digits)): + with self.assertRaises(ValueError) as err: + start = get_time() + str(huge_int) + seconds_to_fail_huge = get_time() - start + self.assertIn('conversion', str(err.exception)) + self.assertLessEqual(seconds_to_fail_huge, seconds_to_convert/2) + + # Now we test that a conversion that would take 30x as long also fails + # in a similarly fast fashion. + extra_huge_int = int(f'0x{"c"*500_000}', base=16) # 602060 digits. + with self.assertRaises(ValueError) as err: + start = get_time() + # If not limited, 8 seconds said Zen based cloud VM. + str(extra_huge_int) + seconds_to_fail_extra_huge = get_time() - start + self.assertIn('conversion', str(err.exception)) + self.assertLess(seconds_to_fail_extra_huge, seconds_to_convert/2) + + def test_denial_of_service_prevented_str_to_int(self): + """Regression test: ensure we fail before performing O(N**2) work.""" + maxdigits = sys.get_int_max_str_digits() + assert maxdigits < 100_000, maxdigits # A test prerequisite. + get_time = time.process_time + if get_time() <= 0: # some platforms like WASM lack process_time() + get_time = time.monotonic + + digits = 133700 + huge = '8'*digits + with support.adjust_int_max_str_digits(digits): + start = get_time() + int(huge) + seconds_to_convert = get_time() - start + # Ensuring that we chose a slow enough conversion to measure. + # It takes 0.1 seconds on a Zen based cloud VM in an opt build. + # Some OSes have a low res 1/64s timer, skip if hard to measure. + if seconds_to_convert < 1/64: + raise unittest.SkipTest('"slow" conversion took only ' + f'{seconds_to_convert} seconds.') + + with support.adjust_int_max_str_digits(digits - 1): + with self.assertRaises(ValueError) as err: + start = get_time() + int(huge) + seconds_to_fail_huge = get_time() - start + self.assertIn('conversion', str(err.exception)) + self.assertLessEqual(seconds_to_fail_huge, seconds_to_convert/2) + + # Now we test that a conversion that would take 30x as long also fails + # in a similarly fast fashion. + extra_huge = '7'*1_200_000 + with self.assertRaises(ValueError) as err: + start = get_time() + # If not limited, 8 seconds in the Zen based cloud VM. + int(extra_huge) + seconds_to_fail_extra_huge = get_time() - start + self.assertIn('conversion', str(err.exception)) + self.assertLessEqual(seconds_to_fail_extra_huge, seconds_to_convert/2) + + def test_power_of_two_bases_unlimited(self): + """The limit does not apply to power of 2 bases.""" + maxdigits = sys.get_int_max_str_digits() + + for base in (2, 4, 8, 16, 32): + with self.subTest(base=base): + self.int_class('1' * (maxdigits + 1), base) + assert maxdigits < 100_000 + self.int_class('1' * 100_000, base) + + def test_underscores_ignored(self): + maxdigits = sys.get_int_max_str_digits() + + triples = maxdigits // 3 + s = '111' * triples + s_ = '1_11' * triples + self.int_class(s) # succeeds + self.int_class(s_) # succeeds + self.check(f'{s}111') + self.check(f'{s_}_111') + + def test_sign_not_counted(self): + int_class = self.int_class + max_digits = sys.get_int_max_str_digits() + s = '5' * max_digits + i = int_class(s) + pos_i = int_class(f'+{s}') + assert i == pos_i + neg_i = int_class(f'-{s}') + assert -pos_i == neg_i + str(pos_i) + str(neg_i) + + def _other_base_helper(self, base): + int_class = self.int_class + max_digits = sys.get_int_max_str_digits() + s = '2' * max_digits + i = int_class(s, base) + if base > 10: + with self.assertRaises(ValueError): + str(i) + elif base < 10: + str(i) + with self.assertRaises(ValueError) as err: + int_class(f'{s}1', base) + + def test_int_from_other_bases(self): + base = 3 + with self.subTest(base=base): + self._other_base_helper(base) + base = 36 + with self.subTest(base=base): + self._other_base_helper(base) + + def test_int_max_str_digits_is_per_interpreter(self): + # Changing the limit in one interpreter does not change others. + code = """if 1: + # Subinterpreters maintain and enforce their own limit + import sys + sys.set_int_max_str_digits(2323) + try: + int('3'*3333) + except ValueError: + pass + else: + raise AssertionError('Expected a int max str digits ValueError.') + """ + with support.adjust_int_max_str_digits(4000): + before_value = sys.get_int_max_str_digits() + self.assertEqual(support.run_in_subinterp(code), 0, + 'subinterp code failure, check stderr.') + after_value = sys.get_int_max_str_digits() + self.assertEqual(before_value, after_value) + + +class IntSubclassStrDigitLimitsTests(IntStrDigitLimitsTests): + int_class = IntSubclass + + +class PyLongModuleTests(unittest.TestCase): + # Tests of the functions in _pylong.py. Those get used when the + # number of digits in the input values are large enough. + + def setUp(self): + super().setUp() + self._previous_limit = sys.get_int_max_str_digits() + sys.set_int_max_str_digits(0) + + def tearDown(self): + sys.set_int_max_str_digits(self._previous_limit) + super().tearDown() + + def test_pylong_int_to_decimal(self): + n = (1 << 100_000) - 1 + suffix = '9883109375' + s = str(n) + assert s[-10:] == suffix + s = str(-n) + assert s[-10:] == suffix + s = '%d' % n + assert s[-10:] == suffix + s = b'%d' % n + assert s[-10:] == suffix.encode('ascii') + + def test_pylong_int_divmod(self): + n = (1 << 100_000) + a, b = divmod(n*3 + 1, n) + assert a == 3 and b == 1 + + def test_pylong_str_to_int(self): + v1 = 1 << 100_000 + s = str(v1) + v2 = int(s) + assert v1 == v2 + v3 = int(' -' + s) + assert -v1 == v3 + v4 = int(' +' + s + ' ') + assert v1 == v4 + with self.assertRaises(ValueError) as err: + int(s + 'z') + with self.assertRaises(ValueError) as err: + int(s + '_') + with self.assertRaises(ValueError) as err: + int('_' + s) + + @support.cpython_only # tests implementation details of CPython. + @unittest.skipUnless(_pylong, "_pylong module required") + @mock.patch.object(_pylong, "int_to_decimal_string") + def test_pylong_misbehavior_error_path_to_str( + self, mock_int_to_str): + with support.adjust_int_max_str_digits(20_000): + big_value = int('7'*19_999) + mock_int_to_str.return_value = None # not a str + with self.assertRaises(TypeError) as ctx: + str(big_value) + self.assertIn('_pylong.int_to_decimal_string did not', + str(ctx.exception)) + mock_int_to_str.side_effect = RuntimeError("testABC") + with self.assertRaises(RuntimeError): + str(big_value) + + @support.cpython_only # tests implementation details of CPython. + @unittest.skipUnless(_pylong, "_pylong module required") + @mock.patch.object(_pylong, "int_from_string") + def test_pylong_misbehavior_error_path_from_str( + self, mock_int_from_str): + big_value = '7'*19_999 + with support.adjust_int_max_str_digits(20_000): + mock_int_from_str.return_value = b'not an int' + with self.assertRaises(TypeError) as ctx: + int(big_value) + self.assertIn('_pylong.int_from_string did not', + str(ctx.exception)) + + mock_int_from_str.side_effect = RuntimeError("test123") + with self.assertRaises(RuntimeError): + int(big_value) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_interpreters.py b/Lib/test/test_interpreters.py index 6266aa7c33b..b969ddf33d8 100644 --- a/Lib/test/test_interpreters.py +++ b/Lib/test/test_interpreters.py @@ -5,7 +5,9 @@ from textwrap import dedent import unittest import time -import _xxsubinterpreters as _interpreters +from test import support +from test.support import import_helper +_interpreters = import_helper.import_module('_xxsubinterpreters') from test.support import interpreters @@ -407,7 +409,7 @@ class TestInterpreterRun(TestBase): self.assertEqual(out, 'it worked!') - @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()") + @support.requires_fork() def test_fork(self): interp = interpreters.create() import tempfile diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 3619e749d17..c5f2e5060a5 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -28,7 +28,6 @@ import pickle import random import signal import sys -import sysconfig import textwrap import threading import time @@ -44,6 +43,7 @@ from test.support import import_helper from test.support import os_helper from test.support import threading_helper from test.support import warnings_helper +from test.support import skip_if_sanitizer from test.support.os_helper import FakePath import codecs @@ -66,20 +66,9 @@ else: class EmptyStruct(ctypes.Structure): pass -_cflags = sysconfig.get_config_var('CFLAGS') or '' -_config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' -MEMORY_SANITIZER = ( - '-fsanitize=memory' in _cflags or - '--with-memory-sanitizer' in _config_args -) - -ADDRESS_SANITIZER = ( - '-fsanitize=address' in _cflags -) - # Does io.IOBase finalizer log the exception if the close() method fails? # The exception is ignored silently by default in release build. -IOBASE_EMITS_UNRAISABLE = (hasattr(sys, "gettotalrefcount") or sys.flags.dev_mode) +IOBASE_EMITS_UNRAISABLE = (support.Py_DEBUG or sys.flags.dev_mode) def _default_chunk_size(): @@ -87,6 +76,10 @@ def _default_chunk_size(): with open(__file__, "r", encoding="latin-1") as f: return f._CHUNK_SIZE +requires_alarm = unittest.skipUnless( + hasattr(signal, "alarm"), "test requires signal.alarm()" +) + class MockRawIOWithoutRead: """A RawIO implementation without read(), so as to exercise the default @@ -433,6 +426,10 @@ class IOTest(unittest.TestCase): self.assertRaises(exc, fp.seek, 1, self.SEEK_CUR) self.assertRaises(exc, fp.seek, -1, self.SEEK_END) + @unittest.skipIf( + support.is_emscripten, "fstat() of a pipe fd is not supported" + ) + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_optional_abilities(self): # Test for OSError when optional APIs are not supported # The purpose of this test is to try fileno(), reading, writing and @@ -891,6 +888,14 @@ class IOTest(unittest.TestCase): open('non-existent', 'r', opener=badopener) self.assertEqual(str(cm.exception), 'opener returned -2') + def test_opener_invalid_fd(self): + # Check that OSError is raised with error code EBADF if the + # opener returns an invalid file descriptor (see gh-82212). + fd = os_helper.make_bad_fd() + with self.assertRaises(OSError) as cm: + self.open('foo', opener=lambda name, flags: fd) + self.assertEqual(cm.exception.errno, errno.EBADF) + def test_fileio_closefd(self): # Issue #4841 with self.open(__file__, 'rb') as f1, \ @@ -1455,6 +1460,7 @@ class BufferedReaderTest(unittest.TestCase, CommonBufferedTests): self.assertEqual(b"abcdefg", bufio.read()) @support.requires_resource('cpu') + @threading_helper.requires_working_threading() def test_threads(self): try: # Write out many bytes with exactly the same number of 0's, @@ -1533,11 +1539,25 @@ class BufferedReaderTest(unittest.TestCase, CommonBufferedTests): def test_read_on_closed(self): # Issue #23796 - b = io.BufferedReader(io.BytesIO(b"12")) + b = self.BufferedReader(self.BytesIO(b"12")) b.read(1) b.close() - self.assertRaises(ValueError, b.peek) - self.assertRaises(ValueError, b.read1, 1) + with self.subTest('peek'): + self.assertRaises(ValueError, b.peek) + with self.subTest('read1'): + self.assertRaises(ValueError, b.read1, 1) + with self.subTest('read'): + self.assertRaises(ValueError, b.read) + with self.subTest('readinto'): + self.assertRaises(ValueError, b.readinto, bytearray()) + with self.subTest('readinto1'): + self.assertRaises(ValueError, b.readinto1, bytearray()) + with self.subTest('flush'): + self.assertRaises(ValueError, b.flush) + with self.subTest('truncate'): + self.assertRaises(ValueError, b.truncate) + with self.subTest('seek'): + self.assertRaises(ValueError, b.seek, 0) def test_truncate_on_read_only(self): rawio = self.MockFileIO(b"abc") @@ -1550,8 +1570,8 @@ class BufferedReaderTest(unittest.TestCase, CommonBufferedTests): class CBufferedReaderTest(BufferedReaderTest, SizeofTest): tp = io.BufferedReader - @unittest.skipIf(MEMORY_SANITIZER or ADDRESS_SANITIZER, "sanitizer defaults to crashing " - "instead of returning NULL for malloc failure.") + @skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing " + "instead of returning NULL for malloc failure.") def test_constructor(self): BufferedReaderTest.test_constructor(self) # The allocation can succeed on 32-bit builds, e.g. with more @@ -1595,10 +1615,10 @@ class CBufferedReaderTest(BufferedReaderTest, SizeofTest): def test_args_error(self): # Issue #17275 with self.assertRaisesRegex(TypeError, "BufferedReader"): - self.tp(io.BytesIO(), 1024, 1024, 1024) + self.tp(self.BytesIO(), 1024, 1024, 1024) def test_bad_readinto_value(self): - rawio = io.BufferedReader(io.BytesIO(b"12")) + rawio = self.tp(self.BytesIO(b"12")) rawio.readinto = lambda buf: -1 bufio = self.tp(rawio) with self.assertRaises(OSError) as cm: @@ -1606,7 +1626,7 @@ class CBufferedReaderTest(BufferedReaderTest, SizeofTest): self.assertIsNone(cm.exception.__cause__) def test_bad_readinto_type(self): - rawio = io.BufferedReader(io.BytesIO(b"12")) + rawio = self.tp(self.BytesIO(b"12")) rawio.readinto = lambda buf: b'' bufio = self.tp(rawio) with self.assertRaises(OSError) as cm: @@ -1749,7 +1769,7 @@ class BufferedWriterTest(unittest.TestCase, CommonBufferedTests): self.assertTrue(s.startswith(b"01234567A"), s) def test_write_and_rewind(self): - raw = io.BytesIO() + raw = self.BytesIO() bufio = self.tp(raw, 4) self.assertEqual(bufio.write(b"abcdef"), 6) self.assertEqual(bufio.tell(), 6) @@ -1829,6 +1849,7 @@ class BufferedWriterTest(unittest.TestCase, CommonBufferedTests): self.assertEqual(f.tell(), buffer_size + 2) @support.requires_resource('cpu') + @threading_helper.requires_working_threading() def test_threads(self): try: # Write out many bytes from many threads and test they were @@ -1899,6 +1920,7 @@ class BufferedWriterTest(unittest.TestCase, CommonBufferedTests): self.assertRaises(OSError, b.close) # exception not swallowed self.assertTrue(b.closed) + @threading_helper.requires_working_threading() def test_slow_close_from_thread(self): # Issue #31976 rawio = self.SlowFlushRawIO() @@ -1915,8 +1937,8 @@ class BufferedWriterTest(unittest.TestCase, CommonBufferedTests): class CBufferedWriterTest(BufferedWriterTest, SizeofTest): tp = io.BufferedWriter - @unittest.skipIf(MEMORY_SANITIZER or ADDRESS_SANITIZER, "sanitizer defaults to crashing " - "instead of returning NULL for malloc failure.") + @skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing " + "instead of returning NULL for malloc failure.") def test_constructor(self): BufferedWriterTest.test_constructor(self) # The allocation can succeed on 32-bit builds, e.g. with more @@ -1957,7 +1979,7 @@ class CBufferedWriterTest(BufferedWriterTest, SizeofTest): def test_args_error(self): # Issue #17275 with self.assertRaisesRegex(TypeError, "BufferedWriter"): - self.tp(io.BytesIO(), 1024, 1024, 1024) + self.tp(self.BytesIO(), 1024, 1024, 1024) class PyBufferedWriterTest(BufferedWriterTest): @@ -2414,8 +2436,8 @@ class BufferedRandomTest(BufferedReaderTest, BufferedWriterTest): class CBufferedRandomTest(BufferedRandomTest, SizeofTest): tp = io.BufferedRandom - @unittest.skipIf(MEMORY_SANITIZER or ADDRESS_SANITIZER, "sanitizer defaults to crashing " - "instead of returning NULL for malloc failure.") + @skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing " + "instead of returning NULL for malloc failure.") def test_constructor(self): BufferedRandomTest.test_constructor(self) # The allocation can succeed on 32-bit builds, e.g. with more @@ -2433,7 +2455,7 @@ class CBufferedRandomTest(BufferedRandomTest, SizeofTest): def test_args_error(self): # Issue #17275 with self.assertRaisesRegex(TypeError, "BufferedRandom"): - self.tp(io.BytesIO(), 1024, 1024, 1024) + self.tp(self.BytesIO(), 1024, 1024, 1024) class PyBufferedRandomTest(BufferedRandomTest): @@ -2727,7 +2749,7 @@ class TextIOWrapperTest(unittest.TestCase): if key in os.environ: del os.environ[key] - current_locale_encoding = locale.getpreferredencoding(False) + current_locale_encoding = locale.getencoding() b = self.BytesIO() with warnings.catch_warnings(): warnings.simplefilter("ignore", EncodingWarning) @@ -2737,17 +2759,6 @@ class TextIOWrapperTest(unittest.TestCase): os.environ.clear() os.environ.update(old_environ) - @support.cpython_only - @unittest.skipIf(sys.flags.utf8_mode, "utf-8 mode is enabled") - def test_device_encoding(self): - # Issue 15989 - import _testcapi - b = self.BytesIO() - b.fileno = lambda: _testcapi.INT_MAX + 1 - self.assertRaises(OverflowError, self.TextIOWrapper, b, encoding="locale") - b.fileno = lambda: _testcapi.UINT_MAX + 1 - self.assertRaises(OverflowError, self.TextIOWrapper, b, encoding="locale") - def test_encoding(self): # Check the encoding attribute is always set, and valid b = self.BytesIO() @@ -3291,6 +3302,7 @@ class TextIOWrapperTest(unittest.TestCase): self.assertEqual(f.errors, "replace") @support.no_tracing + @threading_helper.requires_working_threading() def test_threads_write(self): # Issue6750: concurrent writes could duplicate data event = threading.Event() @@ -3475,7 +3487,7 @@ class TextIOWrapperTest(unittest.TestCase): # encode() is invalid shouldn't cause an assertion failure. rot13 = codecs.lookup("rot13") with support.swap_attr(rot13, '_is_text_encoding', True): - t = io.TextIOWrapper(io.BytesIO(b'foo'), encoding="rot13") + t = self.TextIOWrapper(self.BytesIO(b'foo'), encoding="rot13") self.assertRaises(TypeError, t.write, 'bar') def test_illegal_decoder(self): @@ -3580,6 +3592,10 @@ class TextIOWrapperTest(unittest.TestCase): F.tell = lambda x: 0 t = self.TextIOWrapper(F(), encoding='utf-8') + def test_reconfigure_locale(self): + wrapper = self.TextIOWrapper(self.BytesIO(b"test")) + wrapper.reconfigure(encoding="locale") + def test_reconfigure_encoding_read(self): # latin1 -> utf8 # (latin1 can decode utf-8 encoded string) @@ -3747,7 +3763,7 @@ class CTextIOWrapperTest(TextIOWrapperTest): # all data to disk. # The Python version has __del__, so it ends in gc.garbage instead. with warnings_helper.check_warnings(('', ResourceWarning)): - rawio = io.FileIO(os_helper.TESTFN, "wb") + rawio = self.FileIO(os_helper.TESTFN, "wb") b = self.BufferedWriter(rawio) t = self.TextIOWrapper(b, encoding="ascii") t.write("456def") @@ -3929,7 +3945,15 @@ class IncrementalNewlineDecoderTest(unittest.TestCase): self.assertEqual(decoder.decode(b"\r\r\n"), "\r\r\n") class CIncrementalNewlineDecoderTest(IncrementalNewlineDecoderTest): - pass + @support.cpython_only + def test_uninitialized(self): + uninitialized = self.IncrementalNewlineDecoder.__new__( + self.IncrementalNewlineDecoder) + self.assertRaises(ValueError, uninitialized.decode, b'bar') + self.assertRaises(ValueError, uninitialized.getstate) + self.assertRaises(ValueError, uninitialized.setstate, (b'foo', 0)) + self.assertRaises(ValueError, uninitialized.reset) + class PyIncrementalNewlineDecoderTest(IncrementalNewlineDecoderTest): pass @@ -3978,6 +4002,10 @@ class MiscIOTest(unittest.TestCase): self.open(os_helper.TESTFN, mode) self.assertIn('invalid mode', str(cm.exception)) + @unittest.skipIf( + support.is_emscripten, "fstat() of a pipe fd is not supported" + ) + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_open_pipe_with_append(self): # bpo-27805: Ignore ESPIPE from lseek() in open(). r, w = os.pipe() @@ -4116,6 +4144,7 @@ class MiscIOTest(unittest.TestCase): with warnings_helper.check_no_resource_warning(self): open(r, *args, closefd=False, **kwargs) + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_warn_on_dealloc_fd(self): self._check_warn_on_dealloc_fd("rb", buffering=0) self._check_warn_on_dealloc_fd("rb") @@ -4141,14 +4170,21 @@ class MiscIOTest(unittest.TestCase): with self.open(os_helper.TESTFN, **kwargs) as f: self.assertRaises(TypeError, pickle.dumps, f, protocol) + @unittest.skipIf( + support.is_emscripten, "fstat() of a pipe fd is not supported" + ) def test_nonblock_pipe_write_bigbuf(self): self._test_nonblock_pipe_write(16*1024) + @unittest.skipIf( + support.is_emscripten, "fstat() of a pipe fd is not supported" + ) def test_nonblock_pipe_write_smallbuf(self): self._test_nonblock_pipe_write(1024) @unittest.skipUnless(hasattr(os, 'set_blocking'), 'os.set_blocking() required for this test') + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def _test_nonblock_pipe_write(self, bufsize): sent = [] received = [] @@ -4284,13 +4320,16 @@ class MiscIOTest(unittest.TestCase): self.assertTrue( warnings[1].startswith(b":8: EncodingWarning: ")) - @support.cpython_only - # Depending if OpenWrapper was already created or not, the warning is - # emitted or not. For example, the attribute is already created when this - # test is run multiple times. - @warnings_helper.ignore_warnings(category=DeprecationWarning) - def test_openwrapper(self): - self.assertIs(self.io.OpenWrapper, self.io.open) + def test_text_encoding(self): + # PEP 597, bpo-47000. io.text_encoding() returns "locale" or "utf-8" + # based on sys.flags.utf8_mode + code = "import io; print(io.text_encoding(None))" + + proc = assert_python_ok('-X', 'utf8=0', '-c', code) + self.assertEqual(b"locale", proc.out.strip()) + + proc = assert_python_ok('-X', 'utf8=1', '-c', code) + self.assertEqual(b"utf-8", proc.out.strip()) class CMiscIOTest(MiscIOTest): @@ -4346,9 +4385,11 @@ class CMiscIOTest(MiscIOTest): else: self.assertFalse(err.strip('.!')) + @threading_helper.requires_working_threading() def test_daemon_threads_shutdown_stdout_deadlock(self): self.check_daemon_threads_shutdown_deadlock('stdout') + @threading_helper.requires_working_threading() def test_daemon_threads_shutdown_stderr_deadlock(self): self.check_daemon_threads_shutdown_deadlock('stderr') @@ -4446,12 +4487,18 @@ class SignalsTest(unittest.TestCase): if e.errno != errno.EBADF: raise + @requires_alarm + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_interrupted_write_unbuffered(self): self.check_interrupted_write(b"xy", b"xy", mode="wb", buffering=0) + @requires_alarm + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_interrupted_write_buffered(self): self.check_interrupted_write(b"xy", b"xy", mode="wb") + @requires_alarm + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_interrupted_write_text(self): self.check_interrupted_write("xy", b"xy", mode="w", encoding="ascii") @@ -4483,9 +4530,11 @@ class SignalsTest(unittest.TestCase): wio.close() os.close(r) + @requires_alarm def test_reentrant_write_buffered(self): self.check_reentrant_write(b"xy", mode="wb") + @requires_alarm def test_reentrant_write_text(self): self.check_reentrant_write("xy", mode="w", encoding="ascii") @@ -4513,10 +4562,12 @@ class SignalsTest(unittest.TestCase): os.close(w) os.close(r) + @requires_alarm def test_interrupted_read_retry_buffered(self): self.check_interrupted_read_retry(lambda x: x.decode('latin1'), mode="rb") + @requires_alarm def test_interrupted_read_retry_text(self): self.check_interrupted_read_retry(lambda x: x, mode="r", encoding="latin1") @@ -4589,9 +4640,11 @@ class SignalsTest(unittest.TestCase): if e.errno != errno.EBADF: raise + @requires_alarm def test_interrupted_write_retry_buffered(self): self.check_interrupted_write_retry(b"x", mode="wb") + @requires_alarm def test_interrupted_write_retry_text(self): self.check_interrupted_write_retry("x", mode="w", encoding="latin1") diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py index b0605f0be04..a5388b2e5de 100644 --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -579,6 +579,10 @@ class NetmaskTestMixin_v4(CommonTestMixin_v4): assertBadAddress("1.2.3.256", re.escape("256 (> 255)")) def test_valid_netmask(self): + self.assertEqual(str(self.factory(('192.0.2.0', 24))), '192.0.2.0/24') + self.assertEqual(str(self.factory(('192.0.2.0', '24'))), '192.0.2.0/24') + self.assertEqual(str(self.factory(('192.0.2.0', '255.255.255.0'))), + '192.0.2.0/24') self.assertEqual(str(self.factory('192.0.2.0/255.255.255.0')), '192.0.2.0/24') for i in range(0, 33): @@ -739,6 +743,10 @@ class NetmaskTestMixin_v6(CommonTestMixin_v6): def test_valid_netmask(self): # We only support CIDR for IPv6, because expanded netmasks are not # standard notation. + self.assertEqual(str(self.factory(('2001:db8::', 32))), + '2001:db8::/32') + self.assertEqual(str(self.factory(('2001:db8::', '32'))), + '2001:db8::/32') self.assertEqual(str(self.factory('2001:db8::/32')), '2001:db8::/32') for i in range(0, 129): # Generate and re-parse the CIDR format (trivial). @@ -1132,6 +1140,14 @@ class IpaddrUnitTest(unittest.TestCase): self.assertEqual(ipaddress.IPv4Interface((3221225985, 24)), ipaddress.IPv4Interface('192.0.2.1/24')) + # Invalid netmask + with self.assertRaises(ValueError): + ipaddress.IPv4Network(('192.0.2.1', '255.255.255.255.0')) + + # Invalid netmask using factory + with self.assertRaises(ValueError): + ipaddress.ip_network(('192.0.2.1', '255.255.255.255.0')) + # issue #16531: constructing IPv6Network from an (address, mask) tuple def testIPv6Tuple(self): # /128 @@ -1191,6 +1207,14 @@ class IpaddrUnitTest(unittest.TestCase): ipaddress.IPv6Network((ip_scoped, 96)) # strict=False and host bits set + # Invalid netmask + with self.assertRaises(ValueError): + ipaddress.IPv6Network(('2001:db8::1', '255.255.255.0')) + + # Invalid netmask using factory + with self.assertRaises(ValueError): + ipaddress.ip_network(('2001:db8::1', '255.255.255.0')) + # issue57 def testAddressIntMath(self): self.assertEqual(ipaddress.IPv4Address('1.1.1.1') + 255, @@ -1628,7 +1652,7 @@ class IpaddrUnitTest(unittest.TestCase): self.assertRaises(IndexError, self.ipv6_scoped_network.__getitem__, 1 << 64) def testGetitem(self): - # http://code.google.com/p/ipaddr-py/issues/detail?id=15 + # https://code.google.com/p/ipaddr-py/issues/detail?id=15 addr = ipaddress.IPv4Network('172.31.255.128/255.255.255.240') self.assertEqual(28, addr.prefixlen) addr_list = list(addr) @@ -2253,6 +2277,39 @@ class IpaddrUnitTest(unittest.TestCase): self.assertEqual(False, ipaddress.ip_address('128.0.0.0').is_loopback) self.assertEqual(True, ipaddress.ip_network('0.0.0.0').is_unspecified) + def testPrivateNetworks(self): + self.assertEqual(False, ipaddress.ip_network("0.0.0.0/0").is_private) + self.assertEqual(False, ipaddress.ip_network("1.0.0.0/8").is_private) + + self.assertEqual(True, ipaddress.ip_network("0.0.0.0/8").is_private) + self.assertEqual(True, ipaddress.ip_network("10.0.0.0/8").is_private) + self.assertEqual(True, ipaddress.ip_network("127.0.0.0/8").is_private) + self.assertEqual(True, ipaddress.ip_network("169.254.0.0/16").is_private) + self.assertEqual(True, ipaddress.ip_network("172.16.0.0/12").is_private) + self.assertEqual(True, ipaddress.ip_network("192.0.0.0/29").is_private) + self.assertEqual(True, ipaddress.ip_network("192.0.0.170/31").is_private) + self.assertEqual(True, ipaddress.ip_network("192.0.2.0/24").is_private) + self.assertEqual(True, ipaddress.ip_network("192.168.0.0/16").is_private) + self.assertEqual(True, ipaddress.ip_network("198.18.0.0/15").is_private) + self.assertEqual(True, ipaddress.ip_network("198.51.100.0/24").is_private) + self.assertEqual(True, ipaddress.ip_network("203.0.113.0/24").is_private) + self.assertEqual(True, ipaddress.ip_network("240.0.0.0/4").is_private) + self.assertEqual(True, ipaddress.ip_network("255.255.255.255/32").is_private) + + self.assertEqual(False, ipaddress.ip_network("::/0").is_private) + self.assertEqual(False, ipaddress.ip_network("::ff/128").is_private) + + self.assertEqual(True, ipaddress.ip_network("::1/128").is_private) + self.assertEqual(True, ipaddress.ip_network("::/128").is_private) + self.assertEqual(True, ipaddress.ip_network("::ffff:0:0/96").is_private) + self.assertEqual(True, ipaddress.ip_network("100::/64").is_private) + self.assertEqual(True, ipaddress.ip_network("2001::/23").is_private) + self.assertEqual(True, ipaddress.ip_network("2001:2::/48").is_private) + self.assertEqual(True, ipaddress.ip_network("2001:db8::/32").is_private) + self.assertEqual(True, ipaddress.ip_network("2001:10::/28").is_private) + self.assertEqual(True, ipaddress.ip_network("fc00::/7").is_private) + self.assertEqual(True, ipaddress.ip_network("fe80::/10").is_private) + def testReservedIpv6(self): self.assertEqual(True, ipaddress.ip_network('ffff::').is_multicast) diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py index 9d37cff9903..2fcf6ebbee7 100644 --- a/Lib/test/test_isinstance.py +++ b/Lib/test/test_isinstance.py @@ -8,7 +8,7 @@ import typing from test import support - + class TestIsInstanceExceptions(unittest.TestCase): # Test to make sure that an AttributeError when accessing the instance's # class's bases is masked. This was actually a bug in Python 2.2 and @@ -97,7 +97,7 @@ class TestIsInstanceExceptions(unittest.TestCase): class D: pass self.assertRaises(RuntimeError, isinstance, c, D) - + # These tests are similar to above, but tickle certain code paths in # issubclass() instead of isinstance() -- really PyObject_IsSubclass() # vs. PyObject_IsInstance(). @@ -147,7 +147,7 @@ class TestIsSubclassExceptions(unittest.TestCase): self.assertRaises(TypeError, issubclass, B, C()) - + # meta classes for creating abstract classes and instances class AbstractClass(object): def __init__(self, bases): @@ -179,7 +179,7 @@ class Super: class Child(Super): pass - + class TestIsInstanceIsSubclass(unittest.TestCase): # Tests to ensure that isinstance and issubclass work on abstract # classes and instances. Before the 2.2 release, TypeErrors were @@ -225,7 +225,7 @@ class TestIsInstanceIsSubclass(unittest.TestCase): with self.assertRaises(TypeError): isinstance(2, list[int] | int) with self.assertRaises(TypeError): - isinstance(2, int | str | list[int] | float) + isinstance(2, float | str | list[int] | int) @@ -353,10 +353,10 @@ def blowstack(fxn, arg, compare_to): # Make sure that calling isinstance with a deeply nested tuple for its # argument will raise RecursionError eventually. tuple_arg = (compare_to,) - for cnt in range(sys.getrecursionlimit()+5): + for cnt in range(support.EXCEEDS_RECURSION_LIMIT): tuple_arg = (tuple_arg,) fxn(arg, tuple_arg) - + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_iter.py b/Lib/test/test_iter.py index 554f602f625..acbdcb5f302 100644 --- a/Lib/test/test_iter.py +++ b/Lib/test/test_iter.py @@ -81,6 +81,16 @@ class BadIterableClass: def __iter__(self): raise ZeroDivisionError +class CallableIterClass: + def __init__(self): + self.i = 0 + def __call__(self): + i = self.i + self.i = i + 1 + if i > 100: + raise IndexError # Emergency stop + return i + # Main test suite class TestCase(unittest.TestCase): @@ -237,16 +247,7 @@ class TestCase(unittest.TestCase): # Test two-argument iter() with callable instance def test_iter_callable(self): - class C: - def __init__(self): - self.i = 0 - def __call__(self): - i = self.i - self.i = i + 1 - if i > 100: - raise IndexError # Emergency stop - return i - self.check_iterator(iter(C(), 10), list(range(10)), pickle=False) + self.check_iterator(iter(CallableIterClass(), 10), list(range(10)), pickle=True) # Test two-argument iter() with function def test_iter_function(self): diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py index 808c32f7dd7..b447b6cbab9 100644 --- a/Lib/test/test_itertools.py +++ b/Lib/test/test_itertools.py @@ -1,6 +1,7 @@ import doctest import unittest from test import support +from test.support import threading_helper from itertools import * import weakref from decimal import Decimal @@ -158,6 +159,44 @@ class TestBasicOps(unittest.TestCase): with self.assertRaises(TypeError): list(accumulate([10, 20], 100)) + def test_batched(self): + self.assertEqual(list(batched('ABCDEFG', 3)), + [('A', 'B', 'C'), ('D', 'E', 'F'), ('G',)]) + self.assertEqual(list(batched('ABCDEFG', 2)), + [('A', 'B'), ('C', 'D'), ('E', 'F'), ('G',)]) + self.assertEqual(list(batched('ABCDEFG', 1)), + [('A',), ('B',), ('C',), ('D',), ('E',), ('F',), ('G',)]) + + with self.assertRaises(TypeError): # Too few arguments + list(batched('ABCDEFG')) + with self.assertRaises(TypeError): + list(batched('ABCDEFG', 3, None)) # Too many arguments + with self.assertRaises(TypeError): + list(batched(None, 3)) # Non-iterable input + with self.assertRaises(TypeError): + list(batched('ABCDEFG', 'hello')) # n is a string + with self.assertRaises(ValueError): + list(batched('ABCDEFG', 0)) # n is zero + with self.assertRaises(ValueError): + list(batched('ABCDEFG', -1)) # n is negative + + data = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + for n in range(1, 6): + for i in range(len(data)): + s = data[:i] + batches = list(batched(s, n)) + with self.subTest(s=s, n=n, batches=batches): + # Order is preserved and no data is lost + self.assertEqual(''.join(chain(*batches)), s) + # Each batch is an exact tuple + self.assertTrue(all(type(batch) is tuple for batch in batches)) + # All but the last batch is of size n + if batches: + last_batch = batches.pop() + self.assertTrue(all(len(batch) == n for batch in batches)) + self.assertTrue(len(last_batch) <= n) + batches.append(last_batch) + def test_chain(self): def chain2(*iterables): @@ -179,6 +218,7 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(list(chain.from_iterable([''])), []) self.assertEqual(take(4, chain.from_iterable(['abc', 'def'])), list('abcd')) self.assertRaises(TypeError, list, chain.from_iterable([2, 3])) + self.assertEqual(list(islice(chain.from_iterable(repeat(range(5))), 2)), [0, 1]) def test_chain_reducible(self): for oper in [copy.deepcopy] + picklecopiers: @@ -635,6 +675,7 @@ class TestBasicOps(unittest.TestCase): self.assertRaises(TypeError, cycle, 5) self.assertEqual(list(islice(cycle(gen3()),10)), [0,1,2,0,1,2,0,1,2,0]) + def test_cycle_copy_pickle(self): # check copy, deepcopy, pickle c = cycle('abc') self.assertEqual(next(c), 'a') @@ -670,6 +711,37 @@ class TestBasicOps(unittest.TestCase): d = pickle.loads(p) # rebuild the cycle object self.assertEqual(take(20, d), list('cdeabcdeabcdeabcdeab')) + def test_cycle_unpickle_compat(self): + testcases = [ + b'citertools\ncycle\n(c__builtin__\niter\n((lI1\naI2\naI3\natRI1\nbtR((lI1\naI0\ntb.', + b'citertools\ncycle\n(c__builtin__\niter\n(](K\x01K\x02K\x03etRK\x01btR(]K\x01aK\x00tb.', + b'\x80\x02citertools\ncycle\nc__builtin__\niter\n](K\x01K\x02K\x03e\x85RK\x01b\x85R]K\x01aK\x00\x86b.', + b'\x80\x03citertools\ncycle\ncbuiltins\niter\n](K\x01K\x02K\x03e\x85RK\x01b\x85R]K\x01aK\x00\x86b.', + b'\x80\x04\x95=\x00\x00\x00\x00\x00\x00\x00\x8c\titertools\x8c\x05cycle\x93\x8c\x08builtins\x8c\x04iter\x93](K\x01K\x02K\x03e\x85RK\x01b\x85R]K\x01aK\x00\x86b.', + + b'citertools\ncycle\n(c__builtin__\niter\n((lp0\nI1\naI2\naI3\natRI1\nbtR(g0\nI1\ntb.', + b'citertools\ncycle\n(c__builtin__\niter\n(]q\x00(K\x01K\x02K\x03etRK\x01btR(h\x00K\x01tb.', + b'\x80\x02citertools\ncycle\nc__builtin__\niter\n]q\x00(K\x01K\x02K\x03e\x85RK\x01b\x85Rh\x00K\x01\x86b.', + b'\x80\x03citertools\ncycle\ncbuiltins\niter\n]q\x00(K\x01K\x02K\x03e\x85RK\x01b\x85Rh\x00K\x01\x86b.', + b'\x80\x04\x95<\x00\x00\x00\x00\x00\x00\x00\x8c\titertools\x8c\x05cycle\x93\x8c\x08builtins\x8c\x04iter\x93]\x94(K\x01K\x02K\x03e\x85RK\x01b\x85Rh\x00K\x01\x86b.', + + b'citertools\ncycle\n(c__builtin__\niter\n((lI1\naI2\naI3\natRI1\nbtR((lI1\naI00\ntb.', + b'citertools\ncycle\n(c__builtin__\niter\n(](K\x01K\x02K\x03etRK\x01btR(]K\x01aI00\ntb.', + b'\x80\x02citertools\ncycle\nc__builtin__\niter\n](K\x01K\x02K\x03e\x85RK\x01b\x85R]K\x01a\x89\x86b.', + b'\x80\x03citertools\ncycle\ncbuiltins\niter\n](K\x01K\x02K\x03e\x85RK\x01b\x85R]K\x01a\x89\x86b.', + b'\x80\x04\x95<\x00\x00\x00\x00\x00\x00\x00\x8c\titertools\x8c\x05cycle\x93\x8c\x08builtins\x8c\x04iter\x93](K\x01K\x02K\x03e\x85RK\x01b\x85R]K\x01a\x89\x86b.', + + b'citertools\ncycle\n(c__builtin__\niter\n((lp0\nI1\naI2\naI3\natRI1\nbtR(g0\nI01\ntb.', + b'citertools\ncycle\n(c__builtin__\niter\n(]q\x00(K\x01K\x02K\x03etRK\x01btR(h\x00I01\ntb.', + b'\x80\x02citertools\ncycle\nc__builtin__\niter\n]q\x00(K\x01K\x02K\x03e\x85RK\x01b\x85Rh\x00\x88\x86b.', + b'\x80\x03citertools\ncycle\ncbuiltins\niter\n]q\x00(K\x01K\x02K\x03e\x85RK\x01b\x85Rh\x00\x88\x86b.', + b'\x80\x04\x95;\x00\x00\x00\x00\x00\x00\x00\x8c\titertools\x8c\x05cycle\x93\x8c\x08builtins\x8c\x04iter\x93]\x94(K\x01K\x02K\x03e\x85RK\x01b\x85Rh\x00\x88\x86b.', + ] + assert len(testcases) == 20 + for t in testcases: + it = pickle.loads(t) + self.assertEqual(take(10, it), [2, 3, 1, 2, 3, 1, 2, 3, 1, 2]) + def test_cycle_setstate(self): # Verify both modes for restoring state @@ -1533,6 +1605,7 @@ class TestBasicOps(unittest.TestCase): with self.assertRaisesRegex(RuntimeError, "tee"): next(a) + @threading_helper.requires_working_threading() def test_tee_concurrent(self): start = threading.Event() finish = threading.Event() @@ -1734,6 +1807,31 @@ class TestExamples(unittest.TestCase): class TestPurePythonRoughEquivalents(unittest.TestCase): + def test_batched_recipe(self): + def batched_recipe(iterable, n): + "Batch data into tuples of length n. The last batch may be shorter." + # batched('ABCDEFG', 3) --> ABC DEF G + if n < 1: + raise ValueError('n must be at least one') + it = iter(iterable) + while (batch := tuple(islice(it, n))): + yield batch + + for iterable, n in product( + ['', 'a', 'ab', 'abc', 'abcd', 'abcde', 'abcdef', 'abcdefg', None], + [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, None]): + with self.subTest(iterable=iterable, n=n): + try: + e1, r1 = None, list(batched(iterable, n)) + except Exception as e: + e1, r1 = type(e), None + try: + e2, r2 = None, list(batched_recipe(iterable, n)) + except Exception as e: + e2, r2 = type(e), None + self.assertEqual(r1, r2) + self.assertEqual(e1, e2) + @staticmethod def islice(iterable, *args): s = slice(*args) @@ -1785,6 +1883,10 @@ class TestGC(unittest.TestCase): a = [] self.makecycle(accumulate([1,2,a,3]), a) + def test_batched(self): + a = [] + self.makecycle(batched([1,2,a,3], 2), a) + def test_chain(self): a = [] self.makecycle(chain(a), a) @@ -1942,6 +2044,20 @@ class E: def __next__(self): 3 // 0 +class E2: + 'Test propagation of exceptions after two iterations' + def __init__(self, seqn): + self.seqn = seqn + self.i = 0 + def __iter__(self): + return self + def __next__(self): + if self.i == 2: + raise ZeroDivisionError + v = self.seqn[self.i] + self.i += 1 + return v + class S: 'Test immediate stop' def __init__(self, seqn): @@ -1969,6 +2085,19 @@ class TestVariousIteratorArgs(unittest.TestCase): self.assertRaises(TypeError, accumulate, N(s)) self.assertRaises(ZeroDivisionError, list, accumulate(E(s))) + def test_batched(self): + s = 'abcde' + r = [('a', 'b'), ('c', 'd'), ('e',)] + n = 2 + for g in (G, I, Ig, L, R): + with self.subTest(g=g): + self.assertEqual(list(batched(g(s), n)), r) + self.assertEqual(list(batched(S(s), 2)), []) + self.assertRaises(TypeError, batched, X(s), 2) + self.assertRaises(TypeError, batched, N(s), 2) + self.assertRaises(ZeroDivisionError, list, batched(E(s), 2)) + self.assertRaises(ZeroDivisionError, list, batched(E2(s), 4)) + def test_chain(self): for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)): for g in (G, I, Ig, S, L, R): @@ -2321,376 +2450,6 @@ class SizeofTest(unittest.TestCase): basesize + 10 * self.ssize_t + 4 * self.ssize_t) -libreftest = """ Doctest for examples in the library reference: libitertools.tex - - ->>> amounts = [120.15, 764.05, 823.14] ->>> for checknum, amount in zip(count(1200), amounts): -... print('Check %d is for $%.2f' % (checknum, amount)) -... -Check 1200 is for $120.15 -Check 1201 is for $764.05 -Check 1202 is for $823.14 - ->>> import operator ->>> for cube in map(operator.pow, range(1,4), repeat(3)): -... print(cube) -... -1 -8 -27 - ->>> reportlines = ['EuroPython', 'Roster', '', 'alex', '', 'laura', '', 'martin', '', 'walter', '', 'samuele'] ->>> for name in islice(reportlines, 3, None, 2): -... print(name.title()) -... -Alex -Laura -Martin -Walter -Samuele - ->>> from operator import itemgetter ->>> d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3) ->>> di = sorted(sorted(d.items()), key=itemgetter(1)) ->>> for k, g in groupby(di, itemgetter(1)): -... print(k, list(map(itemgetter(0), g))) -... -1 ['a', 'c', 'e'] -2 ['b', 'd', 'f'] -3 ['g'] - -# Find runs of consecutive numbers using groupby. The key to the solution -# is differencing with a range so that consecutive numbers all appear in -# same group. ->>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28] ->>> for k, g in groupby(enumerate(data), lambda t:t[0]-t[1]): -... print(list(map(operator.itemgetter(1), g))) -... -[1] -[4, 5, 6] -[10] -[15, 16, 17, 18] -[22] -[25, 26, 27, 28] - ->>> def take(n, iterable): -... "Return first n items of the iterable as a list" -... return list(islice(iterable, n)) - ->>> def prepend(value, iterator): -... "Prepend a single value in front of an iterator" -... # prepend(1, [2, 3, 4]) -> 1 2 3 4 -... return chain([value], iterator) - ->>> def enumerate(iterable, start=0): -... return zip(count(start), iterable) - ->>> def tabulate(function, start=0): -... "Return function(0), function(1), ..." -... return map(function, count(start)) - ->>> import collections ->>> def consume(iterator, n=None): -... "Advance the iterator n-steps ahead. If n is None, consume entirely." -... # Use functions that consume iterators at C speed. -... if n is None: -... # feed the entire iterator into a zero-length deque -... collections.deque(iterator, maxlen=0) -... else: -... # advance to the empty slice starting at position n -... next(islice(iterator, n, n), None) - ->>> def nth(iterable, n, default=None): -... "Returns the nth item or a default value" -... return next(islice(iterable, n, None), default) - ->>> def all_equal(iterable): -... "Returns True if all the elements are equal to each other" -... g = groupby(iterable) -... return next(g, True) and not next(g, False) - ->>> def quantify(iterable, pred=bool): -... "Count how many times the predicate is true" -... return sum(map(pred, iterable)) - ->>> def pad_none(iterable): -... "Returns the sequence elements and then returns None indefinitely" -... return chain(iterable, repeat(None)) - ->>> def ncycles(iterable, n): -... "Returns the sequence elements n times" -... return chain(*repeat(iterable, n)) - ->>> def dotproduct(vec1, vec2): -... return sum(map(operator.mul, vec1, vec2)) - ->>> def flatten(listOfLists): -... return list(chain.from_iterable(listOfLists)) - ->>> def repeatfunc(func, times=None, *args): -... "Repeat calls to func with specified arguments." -... " Example: repeatfunc(random.random)" -... if times is None: -... return starmap(func, repeat(args)) -... else: -... return starmap(func, repeat(args, times)) - ->>> def triplewise(iterable): -... "Return overlapping triplets from an iterable" -... # pairwise('ABCDEFG') -> ABC BCD CDE DEF EFG -... for (a, _), (b, c) in pairwise(pairwise(iterable)): -... yield a, b, c - ->>> import collections ->>> def sliding_window(iterable, n): -... # sliding_window('ABCDEFG', 4) -> ABCD BCDE CDEF DEFG -... it = iter(iterable) -... window = collections.deque(islice(it, n), maxlen=n) -... if len(window) == n: -... yield tuple(window) -... for x in it: -... window.append(x) -... yield tuple(window) - ->>> def grouper(n, iterable, fillvalue=None): -... "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" -... args = [iter(iterable)] * n -... return zip_longest(*args, fillvalue=fillvalue) - ->>> def roundrobin(*iterables): -... "roundrobin('ABC', 'D', 'EF') --> A D E B F C" -... # Recipe credited to George Sakkis -... pending = len(iterables) -... nexts = cycle(iter(it).__next__ for it in iterables) -... while pending: -... try: -... for next in nexts: -... yield next() -... except StopIteration: -... pending -= 1 -... nexts = cycle(islice(nexts, pending)) - ->>> def partition(pred, iterable): -... "Use a predicate to partition entries into false entries and true entries" -... # partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9 -... t1, t2 = tee(iterable) -... return filterfalse(pred, t1), filter(pred, t2) - ->>> def before_and_after(predicate, it): -... ''' Variant of takewhile() that allows complete -... access to the remainder of the iterator. -... -... >>> all_upper, remainder = before_and_after(str.isupper, 'ABCdEfGhI') -... >>> str.join('', all_upper) -... 'ABC' -... >>> str.join('', remainder) -... 'dEfGhI' -... -... Note that the first iterator must be fully -... consumed before the second iterator can -... generate valid results. -... ''' -... it = iter(it) -... transition = [] -... def true_iterator(): -... for elem in it: -... if predicate(elem): -... yield elem -... else: -... transition.append(elem) -... return -... def remainder_iterator(): -... yield from transition -... yield from it -... return true_iterator(), remainder_iterator() - ->>> def powerset(iterable): -... "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" -... s = list(iterable) -... return chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) - ->>> def unique_everseen(iterable, key=None): -... "List unique elements, preserving order. Remember all elements ever seen." -... # unique_everseen('AAAABBBCCDAABBB') --> A B C D -... # unique_everseen('ABBCcAD', str.lower) --> A B C D -... seen = set() -... seen_add = seen.add -... if key is None: -... for element in iterable: -... if element not in seen: -... seen_add(element) -... yield element -... else: -... for element in iterable: -... k = key(element) -... if k not in seen: -... seen_add(k) -... yield element - ->>> def unique_justseen(iterable, key=None): -... "List unique elements, preserving order. Remember only the element just seen." -... # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B -... # unique_justseen('ABBCcAD', str.lower) --> A B C A D -... return map(next, map(itemgetter(1), groupby(iterable, key))) - ->>> def first_true(iterable, default=False, pred=None): -... '''Returns the first true value in the iterable. -... -... If no true value is found, returns *default* -... -... If *pred* is not None, returns the first item -... for which pred(item) is true. -... -... ''' -... # first_true([a,b,c], x) --> a or b or c or x -... # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x -... return next(filter(pred, iterable), default) - ->>> def nth_combination(iterable, r, index): -... 'Equivalent to list(combinations(iterable, r))[index]' -... pool = tuple(iterable) -... n = len(pool) -... if r < 0 or r > n: -... raise ValueError -... c = 1 -... k = min(r, n-r) -... for i in range(1, k+1): -... c = c * (n - k + i) // i -... if index < 0: -... index += c -... if index < 0 or index >= c: -... raise IndexError -... result = [] -... while r: -... c, n, r = c*r//n, n-1, r-1 -... while index >= c: -... index -= c -... c, n = c*(n-r)//n, n-1 -... result.append(pool[-1-n]) -... return tuple(result) - - -This is not part of the examples but it tests to make sure the definitions -perform as purported. - ->>> take(10, count()) -[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - ->>> list(prepend(1, [2, 3, 4])) -[1, 2, 3, 4] - ->>> list(enumerate('abc')) -[(0, 'a'), (1, 'b'), (2, 'c')] - ->>> list(islice(tabulate(lambda x: 2*x), 4)) -[0, 2, 4, 6] - ->>> it = iter(range(10)) ->>> consume(it, 3) ->>> next(it) -3 ->>> consume(it) ->>> next(it, 'Done') -'Done' - ->>> nth('abcde', 3) -'d' - ->>> nth('abcde', 9) is None -True - ->>> [all_equal(s) for s in ('', 'A', 'AAAA', 'AAAB', 'AAABA')] -[True, True, True, False, False] - ->>> quantify(range(99), lambda x: x%2==0) -50 - ->>> a = [[1, 2, 3], [4, 5, 6]] ->>> flatten(a) -[1, 2, 3, 4, 5, 6] - ->>> list(repeatfunc(pow, 5, 2, 3)) -[8, 8, 8, 8, 8] - ->>> import random ->>> take(5, map(int, repeatfunc(random.random))) -[0, 0, 0, 0, 0] - ->>> list(islice(pad_none('abc'), 0, 6)) -['a', 'b', 'c', None, None, None] - ->>> list(ncycles('abc', 3)) -['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c'] - ->>> dotproduct([1,2,3], [4,5,6]) -32 - ->>> list(grouper(3, 'abcdefg', 'x')) -[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'x', 'x')] - ->>> list(triplewise('ABCDEFG')) -[('A', 'B', 'C'), ('B', 'C', 'D'), ('C', 'D', 'E'), ('D', 'E', 'F'), ('E', 'F', 'G')] - ->>> list(sliding_window('ABCDEFG', 4)) -[('A', 'B', 'C', 'D'), ('B', 'C', 'D', 'E'), ('C', 'D', 'E', 'F'), ('D', 'E', 'F', 'G')] - ->>> list(roundrobin('abc', 'd', 'ef')) -['a', 'd', 'e', 'b', 'f', 'c'] - ->>> def is_odd(x): -... return x % 2 == 1 - ->>> evens, odds = partition(is_odd, range(10)) ->>> list(evens) -[0, 2, 4, 6, 8] ->>> list(odds) -[1, 3, 5, 7, 9] - ->>> it = iter('ABCdEfGhI') ->>> all_upper, remainder = before_and_after(str.isupper, it) ->>> ''.join(all_upper) -'ABC' ->>> ''.join(remainder) -'dEfGhI' - ->>> list(powerset([1,2,3])) -[(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)] - ->>> all(len(list(powerset(range(n)))) == 2**n for n in range(18)) -True - ->>> list(powerset('abcde')) == sorted(sorted(set(powerset('abcde'))), key=len) -True - ->>> list(unique_everseen('AAAABBBCCDAABBB')) -['A', 'B', 'C', 'D'] - ->>> list(unique_everseen('ABBCcAD', str.lower)) -['A', 'B', 'C', 'D'] - ->>> list(unique_justseen('AAAABBBCCDAABBB')) -['A', 'B', 'C', 'D', 'A', 'B'] - ->>> list(unique_justseen('ABBCcAD', str.lower)) -['A', 'B', 'C', 'A', 'D'] - ->>> first_true('ABC0DEF1', '9', str.isdigit) -'0' - ->>> population = 'ABCDEFGH' ->>> for r in range(len(population) + 1): -... seq = list(combinations(population, r)) -... for i in range(len(seq)): -... assert nth_combination(population, r, i) == seq[i] -... for i in range(-len(seq), 0): -... assert nth_combination(population, r, i) == seq[i] - - -""" - -__test__ = {'libreftest' : libreftest} - def load_tests(loader, tests, pattern): tests.addTest(doctest.DocTestSuite()) return tests diff --git a/Lib/test/test_json/__init__.py b/Lib/test/test_json/__init__.py index 74b64ed86a3..37b2e0d5e26 100644 --- a/Lib/test/test_json/__init__.py +++ b/Lib/test/test_json/__init__.py @@ -18,6 +18,7 @@ class PyTest(unittest.TestCase): json = pyjson loads = staticmethod(pyjson.loads) dumps = staticmethod(pyjson.dumps) + AttrDict = pyjson.AttrDict JSONDecodeError = staticmethod(pyjson.JSONDecodeError) @unittest.skipUnless(cjson, 'requires _json') diff --git a/Lib/test/test_json/test_attrdict.py b/Lib/test/test_json/test_attrdict.py new file mode 100644 index 00000000000..143ea462d31 --- /dev/null +++ b/Lib/test/test_json/test_attrdict.py @@ -0,0 +1,145 @@ +from test.test_json import PyTest +import pickle +import sys +import unittest + +kepler_dict = { + "orbital_period": { + "mercury": 88, + "venus": 225, + "earth": 365, + "mars": 687, + "jupiter": 4331, + "saturn": 10_756, + "uranus": 30_687, + "neptune": 60_190, + }, + "dist_from_sun": { + "mercury": 58, + "venus": 108, + "earth": 150, + "mars": 228, + "jupiter": 778, + "saturn": 1_400, + "uranus": 2_900, + "neptune": 4_500, + } +} + +class TestAttrDict(PyTest): + + def test_dict_subclass(self): + self.assertTrue(issubclass(self.AttrDict, dict)) + + def test_slots(self): + d = self.AttrDict(x=1, y=2) + with self.assertRaises(TypeError): + vars(d) + + def test_constructor_signatures(self): + AttrDict = self.AttrDict + target = dict(x=1, y=2) + self.assertEqual(AttrDict(x=1, y=2), target) # kwargs + self.assertEqual(AttrDict(dict(x=1, y=2)), target) # mapping + self.assertEqual(AttrDict(dict(x=1, y=0), y=2), target) # mapping, kwargs + self.assertEqual(AttrDict([('x', 1), ('y', 2)]), target) # iterable + self.assertEqual(AttrDict([('x', 1), ('y', 0)], y=2), target) # iterable, kwargs + + def test_getattr(self): + d = self.AttrDict(x=1, y=2) + self.assertEqual(d.x, 1) + with self.assertRaises(AttributeError): + d.z + + def test_setattr(self): + d = self.AttrDict(x=1, y=2) + d.x = 3 + d.z = 5 + self.assertEqual(d, dict(x=3, y=2, z=5)) + + def test_delattr(self): + d = self.AttrDict(x=1, y=2) + del d.x + self.assertEqual(d, dict(y=2)) + with self.assertRaises(AttributeError): + del d.z + + def test_dir(self): + d = self.AttrDict(x=1, y=2) + self.assertTrue(set(dir(d)), set(dir(dict)).union({'x', 'y'})) + + def test_repr(self): + # This repr is doesn't round-trip. It matches a regular dict. + # That seems to be the norm for AttrDict recipes being used + # in the wild. Also it supports the design concept that an + # AttrDict is just like a regular dict but has optional + # attribute style lookup. + self.assertEqual(repr(self.AttrDict(x=1, y=2)), + repr(dict(x=1, y=2))) + + def test_overlapping_keys_and_methods(self): + d = self.AttrDict(items=50) + self.assertEqual(d['items'], 50) + self.assertEqual(d.items(), dict(d).items()) + + def test_invalid_attribute_names(self): + d = self.AttrDict({ + 'control': 'normal case', + 'class': 'keyword', + 'two words': 'contains space', + 'hypen-ate': 'contains a hyphen' + }) + self.assertEqual(d.control, dict(d)['control']) + self.assertEqual(d['class'], dict(d)['class']) + self.assertEqual(d['two words'], dict(d)['two words']) + self.assertEqual(d['hypen-ate'], dict(d)['hypen-ate']) + + def test_object_hook_use_case(self): + AttrDict = self.AttrDict + json_string = self.dumps(kepler_dict) + kepler_ad = self.loads(json_string, object_hook=AttrDict) + + self.assertEqual(kepler_ad, kepler_dict) # Match regular dict + self.assertIsInstance(kepler_ad, AttrDict) # Verify conversion + self.assertIsInstance(kepler_ad.orbital_period, AttrDict) # Nested + + # Exercise dotted lookups + self.assertEqual(kepler_ad.orbital_period, kepler_dict['orbital_period']) + self.assertEqual(kepler_ad.orbital_period.earth, + kepler_dict['orbital_period']['earth']) + self.assertEqual(kepler_ad['orbital_period'].earth, + kepler_dict['orbital_period']['earth']) + + # Dict style error handling and Attribute style error handling + with self.assertRaises(KeyError): + kepler_ad.orbital_period['pluto'] + with self.assertRaises(AttributeError): + kepler_ad.orbital_period.Pluto + + # Order preservation + self.assertEqual(list(kepler_ad.items()), list(kepler_dict.items())) + self.assertEqual(list(kepler_ad.orbital_period.items()), + list(kepler_dict['orbital_period'].items())) + + # Round trip + self.assertEqual(self.dumps(kepler_ad), json_string) + + def test_pickle(self): + AttrDict = self.AttrDict + json_string = self.dumps(kepler_dict) + kepler_ad = self.loads(json_string, object_hook=AttrDict) + + # Pickling requires the cached module to be the real module + cached_module = sys.modules.get('json') + sys.modules['json'] = self.json + try: + for protocol in range(pickle.HIGHEST_PROTOCOL + 1): + kepler_ad2 = pickle.loads(pickle.dumps(kepler_ad, protocol)) + self.assertEqual(kepler_ad2, kepler_ad) + self.assertEqual(type(kepler_ad2), AttrDict) + finally: + sys.modules['json'] = cached_module + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_json/test_decode.py b/Lib/test/test_json/test_decode.py index fdb9e62124e..124045b1318 100644 --- a/Lib/test/test_json/test_decode.py +++ b/Lib/test/test_json/test_decode.py @@ -2,6 +2,7 @@ import decimal from io import StringIO from collections import OrderedDict from test.test_json import PyTest, CTest +from test import support class TestDecode: @@ -95,5 +96,13 @@ class TestDecode: d = self.json.JSONDecoder() self.assertRaises(ValueError, d.raw_decode, 'a'*42, -50000) + def test_limit_int(self): + maxdigits = 5000 + with support.adjust_int_max_str_digits(maxdigits): + self.loads('1' * maxdigits) + with self.assertRaises(ValueError): + self.loads('1' * (maxdigits + 1)) + + class TestPyDecode(TestDecode, PyTest): pass class TestCDecode(TestDecode, CTest): pass diff --git a/Lib/test/test_json/test_default.py b/Lib/test/test_json/test_default.py index 9b8325e9c38..3ce16684a08 100644 --- a/Lib/test/test_json/test_default.py +++ b/Lib/test/test_json/test_default.py @@ -1,3 +1,4 @@ +import collections from test.test_json import PyTest, CTest @@ -7,6 +8,16 @@ class TestDefault: self.dumps(type, default=repr), self.dumps(repr(type))) + def test_ordereddict(self): + od = collections.OrderedDict(a=1, b=2, c=3, d=4) + od.move_to_end('b') + self.assertEqual( + self.dumps(od), + '{"a": 1, "c": 3, "d": 4, "b": 2}') + self.assertEqual( + self.dumps(od, sort_keys=True), + '{"a": 1, "b": 2, "c": 3, "d": 4}') + class TestPyDefault(TestDefault, PyTest): pass class TestCDefault(TestDefault, CTest): pass diff --git a/Lib/test/test_json/test_fail.py b/Lib/test/test_json/test_fail.py index eb9064edea9..efc982e8b0e 100644 --- a/Lib/test/test_json/test_fail.py +++ b/Lib/test/test_json/test_fail.py @@ -2,73 +2,73 @@ from test.test_json import PyTest, CTest # 2007-10-05 JSONDOCS = [ - # http://json.org/JSON_checker/test/fail1.json + # https://json.org/JSON_checker/test/fail1.json '"A JSON payload should be an object or array, not a string."', - # http://json.org/JSON_checker/test/fail2.json + # https://json.org/JSON_checker/test/fail2.json '["Unclosed array"', - # http://json.org/JSON_checker/test/fail3.json + # https://json.org/JSON_checker/test/fail3.json '{unquoted_key: "keys must be quoted"}', - # http://json.org/JSON_checker/test/fail4.json + # https://json.org/JSON_checker/test/fail4.json '["extra comma",]', - # http://json.org/JSON_checker/test/fail5.json + # https://json.org/JSON_checker/test/fail5.json '["double extra comma",,]', - # http://json.org/JSON_checker/test/fail6.json + # https://json.org/JSON_checker/test/fail6.json '[ , "<-- missing value"]', - # http://json.org/JSON_checker/test/fail7.json + # https://json.org/JSON_checker/test/fail7.json '["Comma after the close"],', - # http://json.org/JSON_checker/test/fail8.json + # https://json.org/JSON_checker/test/fail8.json '["Extra close"]]', - # http://json.org/JSON_checker/test/fail9.json + # https://json.org/JSON_checker/test/fail9.json '{"Extra comma": true,}', - # http://json.org/JSON_checker/test/fail10.json + # https://json.org/JSON_checker/test/fail10.json '{"Extra value after close": true} "misplaced quoted value"', - # http://json.org/JSON_checker/test/fail11.json + # https://json.org/JSON_checker/test/fail11.json '{"Illegal expression": 1 + 2}', - # http://json.org/JSON_checker/test/fail12.json + # https://json.org/JSON_checker/test/fail12.json '{"Illegal invocation": alert()}', - # http://json.org/JSON_checker/test/fail13.json + # https://json.org/JSON_checker/test/fail13.json '{"Numbers cannot have leading zeroes": 013}', - # http://json.org/JSON_checker/test/fail14.json + # https://json.org/JSON_checker/test/fail14.json '{"Numbers cannot be hex": 0x14}', - # http://json.org/JSON_checker/test/fail15.json + # https://json.org/JSON_checker/test/fail15.json '["Illegal backslash escape: \\x15"]', - # http://json.org/JSON_checker/test/fail16.json + # https://json.org/JSON_checker/test/fail16.json '[\\naked]', - # http://json.org/JSON_checker/test/fail17.json + # https://json.org/JSON_checker/test/fail17.json '["Illegal backslash escape: \\017"]', - # http://json.org/JSON_checker/test/fail18.json + # https://json.org/JSON_checker/test/fail18.json '[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]', - # http://json.org/JSON_checker/test/fail19.json + # https://json.org/JSON_checker/test/fail19.json '{"Missing colon" null}', - # http://json.org/JSON_checker/test/fail20.json + # https://json.org/JSON_checker/test/fail20.json '{"Double colon":: null}', - # http://json.org/JSON_checker/test/fail21.json + # https://json.org/JSON_checker/test/fail21.json '{"Comma instead of colon", null}', - # http://json.org/JSON_checker/test/fail22.json + # https://json.org/JSON_checker/test/fail22.json '["Colon instead of comma": false]', - # http://json.org/JSON_checker/test/fail23.json + # https://json.org/JSON_checker/test/fail23.json '["Bad value", truth]', - # http://json.org/JSON_checker/test/fail24.json + # https://json.org/JSON_checker/test/fail24.json "['single quote']", - # http://json.org/JSON_checker/test/fail25.json + # https://json.org/JSON_checker/test/fail25.json '["\ttab\tcharacter\tin\tstring\t"]', - # http://json.org/JSON_checker/test/fail26.json + # https://json.org/JSON_checker/test/fail26.json '["tab\\ character\\ in\\ string\\ "]', - # http://json.org/JSON_checker/test/fail27.json + # https://json.org/JSON_checker/test/fail27.json '["line\nbreak"]', - # http://json.org/JSON_checker/test/fail28.json + # https://json.org/JSON_checker/test/fail28.json '["line\\\nbreak"]', - # http://json.org/JSON_checker/test/fail29.json + # https://json.org/JSON_checker/test/fail29.json '[0e]', - # http://json.org/JSON_checker/test/fail30.json + # https://json.org/JSON_checker/test/fail30.json '[0e+]', - # http://json.org/JSON_checker/test/fail31.json + # https://json.org/JSON_checker/test/fail31.json '[0e+-1]', - # http://json.org/JSON_checker/test/fail32.json + # https://json.org/JSON_checker/test/fail32.json '{"Comma instead if closing brace": true,', - # http://json.org/JSON_checker/test/fail33.json + # https://json.org/JSON_checker/test/fail33.json '["mismatch"}', - # http://code.google.com/p/simplejson/issues/detail?id=3 + # https://code.google.com/archive/p/simplejson/issues/3 '["A\u001FZ control characters in string"]', ] diff --git a/Lib/test/test_json/test_float.py b/Lib/test/test_json/test_float.py index d0c7214334d..61540a3a02c 100644 --- a/Lib/test/test_json/test_float.py +++ b/Lib/test/test_json/test_float.py @@ -26,7 +26,8 @@ class TestFloat: res = self.loads(out) self.assertEqual(len(res), 1) self.assertNotEqual(res[0], res[0]) - self.assertRaises(ValueError, self.dumps, [val], allow_nan=False) + msg = f'Out of range float values are not JSON compliant: {val}' + self.assertRaisesRegex(ValueError, msg, self.dumps, [val], allow_nan=False) class TestPyFloat(TestFloat, PyTest): pass diff --git a/Lib/test/test_json/test_pass1.py b/Lib/test/test_json/test_pass1.py index 15e64b0aeae..26bf3cdbd77 100644 --- a/Lib/test/test_json/test_pass1.py +++ b/Lib/test/test_json/test_pass1.py @@ -1,7 +1,7 @@ from test.test_json import PyTest, CTest -# from http://json.org/JSON_checker/test/pass1.json +# from https://json.org/JSON_checker/test/pass1.json JSON = r''' [ "JSON Test Pattern pass1", diff --git a/Lib/test/test_json/test_pass2.py b/Lib/test/test_json/test_pass2.py index 35075249e3b..9340de665aa 100644 --- a/Lib/test/test_json/test_pass2.py +++ b/Lib/test/test_json/test_pass2.py @@ -1,7 +1,7 @@ from test.test_json import PyTest, CTest -# from http://json.org/JSON_checker/test/pass2.json +# from https://json.org/JSON_checker/test/pass2.json JSON = r''' [[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] ''' diff --git a/Lib/test/test_json/test_pass3.py b/Lib/test/test_json/test_pass3.py index cd0cf170d27..0adccc1c2a5 100644 --- a/Lib/test/test_json/test_pass3.py +++ b/Lib/test/test_json/test_pass3.py @@ -1,7 +1,7 @@ from test.test_json import PyTest, CTest -# from http://json.org/JSON_checker/test/pass3.json +# from https://json.org/JSON_checker/test/pass3.json JSON = r''' { "JSON Test Pattern pass3": { diff --git a/Lib/test/test_json/test_recursion.py b/Lib/test/test_json/test_recursion.py index 543c62839b2..9919d7fbe54 100644 --- a/Lib/test/test_json/test_recursion.py +++ b/Lib/test/test_json/test_recursion.py @@ -1,3 +1,4 @@ +from test import support from test.test_json import PyTest, CTest @@ -69,11 +70,14 @@ class TestRecursion: # test that loading highly-nested objects doesn't segfault when C # accelerations are used. See #12017 with self.assertRaises(RecursionError): - self.loads('{"a":' * 100000 + '1' + '}' * 100000) + with support.infinite_recursion(): + self.loads('{"a":' * 100000 + '1' + '}' * 100000) with self.assertRaises(RecursionError): - self.loads('{"a":' * 100000 + '[1]' + '}' * 100000) + with support.infinite_recursion(): + self.loads('{"a":' * 100000 + '[1]' + '}' * 100000) with self.assertRaises(RecursionError): - self.loads('[' * 100000 + '1' + ']' * 100000) + with support.infinite_recursion(): + self.loads('[' * 100000 + '1' + ']' * 100000) def test_highly_nested_objects_encoding(self): # See #12051 @@ -81,9 +85,11 @@ class TestRecursion: for x in range(100000): l, d = [l], {'k':d} with self.assertRaises(RecursionError): - self.dumps(l) + with support.infinite_recursion(): + self.dumps(l) with self.assertRaises(RecursionError): - self.dumps(d) + with support.infinite_recursion(): + self.dumps(d) def test_endless_recursion(self): # See #12051 @@ -93,7 +99,8 @@ class TestRecursion: return [o] with self.assertRaises(RecursionError): - EndlessJSONEncoder(check_circular=False).encode(5j) + with support.infinite_recursion(): + EndlessJSONEncoder(check_circular=False).encode(5j) class TestPyRecursion(TestRecursion, PyTest): pass diff --git a/Lib/test/test_json/test_tool.py b/Lib/test/test_json/test_tool.py index 1d7fca6efb1..2b63810d539 100644 --- a/Lib/test/test_json/test_tool.py +++ b/Lib/test/test_json/test_tool.py @@ -10,6 +10,7 @@ from test.support import os_helper from test.support.script_helper import assert_python_ok +@support.requires_subprocess() class TestTool(unittest.TestCase): data = """ diff --git a/Lib/test/test_largefile.py b/Lib/test/test_largefile.py index 8f6bec16200..3c11c59baef 100644 --- a/Lib/test/test_largefile.py +++ b/Lib/test/test_largefile.py @@ -156,6 +156,8 @@ class TestFileMethods(LargeFileTest): def skip_no_disk_space(path, required): def decorator(fun): def wrapper(*args, **kwargs): + if not hasattr(shutil, "disk_usage"): + raise unittest.SkipTest("requires shutil.disk_usage") if shutil.disk_usage(os.path.realpath(path)).free < required: hsize = int(required / 1024 / 1024) raise unittest.SkipTest( diff --git a/Lib/test/test_launcher.py b/Lib/test/test_launcher.py new file mode 100644 index 00000000000..351a638c1dd --- /dev/null +++ b/Lib/test/test_launcher.py @@ -0,0 +1,698 @@ +import contextlib +import itertools +import os +import re +import shutil +import subprocess +import sys +import sysconfig +import tempfile +import unittest +from pathlib import Path +from test import support + +if sys.platform != "win32": + raise unittest.SkipTest("test only applies to Windows") + +# Get winreg after the platform check +import winreg + + +PY_EXE = "py.exe" +if sys.executable.casefold().endswith("_d.exe".casefold()): + PY_EXE = "py_d.exe" + +# Registry data to create. On removal, everything beneath top-level names will +# be deleted. +TEST_DATA = { + "PythonTestSuite": { + "DisplayName": "Python Test Suite", + "SupportUrl": "https://www.python.org/", + "3.100": { + "DisplayName": "X.Y version", + "InstallPath": { + None: sys.prefix, + "ExecutablePath": "X.Y.exe", + } + }, + "3.100-32": { + "DisplayName": "X.Y-32 version", + "InstallPath": { + None: sys.prefix, + "ExecutablePath": "X.Y-32.exe", + } + }, + "3.100-arm64": { + "DisplayName": "X.Y-arm64 version", + "InstallPath": { + None: sys.prefix, + "ExecutablePath": "X.Y-arm64.exe", + "ExecutableArguments": "-X fake_arg_for_test", + } + }, + "ignored": { + "DisplayName": "Ignored because no ExecutablePath", + "InstallPath": { + None: sys.prefix, + } + }, + } +} + + +TEST_PY_ENV = dict( + PY_PYTHON="PythonTestSuite/3.100", + PY_PYTHON2="PythonTestSuite/3.100-32", + PY_PYTHON3="PythonTestSuite/3.100-arm64", +) + + +TEST_PY_DEFAULTS = "\n".join([ + "[defaults]", + *[f"{k[3:].lower()}={v}" for k, v in TEST_PY_ENV.items()], +]) + + +TEST_PY_COMMANDS = "\n".join([ + "[commands]", + "test-command=TEST_EXE.exe", +]) + +def create_registry_data(root, data): + def _create_registry_data(root, key, value): + if isinstance(value, dict): + # For a dict, we recursively create keys + with winreg.CreateKeyEx(root, key) as hkey: + for k, v in value.items(): + _create_registry_data(hkey, k, v) + elif isinstance(value, str): + # For strings, we set values. 'key' may be None in this case + winreg.SetValueEx(root, key, None, winreg.REG_SZ, value) + else: + raise TypeError("don't know how to create data for '{}'".format(value)) + + for k, v in data.items(): + _create_registry_data(root, k, v) + + +def enum_keys(root): + for i in itertools.count(): + try: + yield winreg.EnumKey(root, i) + except OSError as ex: + if ex.winerror == 259: + break + raise + + +def delete_registry_data(root, keys): + ACCESS = winreg.KEY_WRITE | winreg.KEY_ENUMERATE_SUB_KEYS + for key in list(keys): + with winreg.OpenKey(root, key, access=ACCESS) as hkey: + delete_registry_data(hkey, enum_keys(hkey)) + winreg.DeleteKey(root, key) + + +def is_installed(tag): + key = rf"Software\Python\PythonCore\{tag}\InstallPath" + for root, flag in [ + (winreg.HKEY_CURRENT_USER, 0), + (winreg.HKEY_LOCAL_MACHINE, winreg.KEY_WOW64_64KEY), + (winreg.HKEY_LOCAL_MACHINE, winreg.KEY_WOW64_32KEY), + ]: + try: + winreg.CloseKey(winreg.OpenKey(root, key, access=winreg.KEY_READ | flag)) + return True + except OSError: + pass + return False + + +class PreservePyIni: + def __init__(self, path, content): + self.path = Path(path) + self.content = content + self._preserved = None + + def __enter__(self): + try: + self._preserved = self.path.read_bytes() + except FileNotFoundError: + self._preserved = None + self.path.write_text(self.content, encoding="utf-16") + + def __exit__(self, *exc_info): + if self._preserved is None: + self.path.unlink() + else: + self.path.write_bytes(self._preserved) + + +class RunPyMixin: + py_exe = None + + @classmethod + def find_py(cls): + py_exe = None + if sysconfig.is_python_build(): + py_exe = Path(sys.executable).parent / PY_EXE + else: + for p in os.getenv("PATH").split(";"): + if p: + py_exe = Path(p) / PY_EXE + if py_exe.is_file(): + break + else: + py_exe = None + + # Test launch and check version, to exclude installs of older + # releases when running outside of a source tree + if py_exe: + try: + with subprocess.Popen( + [py_exe, "-h"], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + encoding="ascii", + errors="ignore", + ) as p: + p.stdin.close() + version = next(p.stdout, "\n").splitlines()[0].rpartition(" ")[2] + p.stdout.read() + p.wait(10) + if not sys.version.startswith(version): + py_exe = None + except OSError: + py_exe = None + + if not py_exe: + raise unittest.SkipTest( + "cannot locate '{}' for test".format(PY_EXE) + ) + return py_exe + + def get_py_exe(self): + if not self.py_exe: + self.py_exe = self.find_py() + return self.py_exe + + def run_py(self, args, env=None, allow_fail=False, expect_returncode=0, argv=None): + if not self.py_exe: + self.py_exe = self.find_py() + + ignore = {"VIRTUAL_ENV", "PY_PYTHON", "PY_PYTHON2", "PY_PYTHON3"} + env = { + **{k.upper(): v for k, v in os.environ.items() if k.upper() not in ignore}, + "PYLAUNCHER_DEBUG": "1", + "PYLAUNCHER_DRYRUN": "1", + **{k.upper(): v for k, v in (env or {}).items()}, + } + if not argv: + argv = [self.py_exe, *args] + with subprocess.Popen( + argv, + env=env, + executable=self.py_exe, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) as p: + p.stdin.close() + p.wait(10) + out = p.stdout.read().decode("utf-8", "replace") + err = p.stderr.read().decode("ascii", "replace") + if p.returncode != expect_returncode and support.verbose and not allow_fail: + print("++ COMMAND ++") + print([self.py_exe, *args]) + print("++ STDOUT ++") + print(out) + print("++ STDERR ++") + print(err) + if allow_fail and p.returncode != expect_returncode: + raise subprocess.CalledProcessError(p.returncode, [self.py_exe, *args], out, err) + else: + self.assertEqual(expect_returncode, p.returncode) + data = { + s.partition(":")[0]: s.partition(":")[2].lstrip() + for s in err.splitlines() + if not s.startswith("#") and ":" in s + } + data["stdout"] = out + data["stderr"] = err + return data + + def py_ini(self, content): + local_appdata = os.environ.get("LOCALAPPDATA") + if not local_appdata: + raise unittest.SkipTest("LOCALAPPDATA environment variable is " + "missing or empty") + return PreservePyIni(Path(local_appdata) / "py.ini", content) + + @contextlib.contextmanager + def script(self, content, encoding="utf-8"): + file = Path(tempfile.mktemp(dir=os.getcwd()) + ".py") + file.write_text(content, encoding=encoding) + try: + yield file + finally: + file.unlink() + + @contextlib.contextmanager + def fake_venv(self): + venv = Path.cwd() / "Scripts" + venv.mkdir(exist_ok=True, parents=True) + venv_exe = (venv / Path(sys.executable).name) + venv_exe.touch() + try: + yield venv_exe, {"VIRTUAL_ENV": str(venv.parent)} + finally: + shutil.rmtree(venv) + + +class TestLauncher(unittest.TestCase, RunPyMixin): + @classmethod + def setUpClass(cls): + with winreg.CreateKey(winreg.HKEY_CURRENT_USER, rf"Software\Python") as key: + create_registry_data(key, TEST_DATA) + + if support.verbose: + p = subprocess.check_output("reg query HKCU\\Software\\Python /s") + #print(p.decode('mbcs')) + + + @classmethod + def tearDownClass(cls): + with winreg.OpenKey(winreg.HKEY_CURRENT_USER, rf"Software\Python", access=winreg.KEY_WRITE | winreg.KEY_ENUMERATE_SUB_KEYS) as key: + delete_registry_data(key, TEST_DATA) + + + def test_version(self): + data = self.run_py(["-0"]) + self.assertEqual(self.py_exe, Path(data["argv0"])) + self.assertEqual(sys.version.partition(" ")[0], data["version"]) + + def test_help_option(self): + data = self.run_py(["-h"]) + self.assertEqual("True", data["SearchInfo.help"]) + + def test_list_option(self): + for opt, v1, v2 in [ + ("-0", "True", "False"), + ("-0p", "False", "True"), + ("--list", "True", "False"), + ("--list-paths", "False", "True"), + ]: + with self.subTest(opt): + data = self.run_py([opt]) + self.assertEqual(v1, data["SearchInfo.list"]) + self.assertEqual(v2, data["SearchInfo.listPaths"]) + + def test_list(self): + data = self.run_py(["--list"]) + found = {} + expect = {} + for line in data["stdout"].splitlines(): + m = re.match(r"\s*(.+?)\s+?(\*\s+)?(.+)$", line) + if m: + found[m.group(1)] = m.group(3) + for company in TEST_DATA: + company_data = TEST_DATA[company] + tags = [t for t in company_data if isinstance(company_data[t], dict)] + for tag in tags: + arg = f"-V:{company}/{tag}" + expect[arg] = company_data[tag]["DisplayName"] + expect.pop(f"-V:{company}/ignored", None) + + actual = {k: v for k, v in found.items() if k in expect} + try: + self.assertDictEqual(expect, actual) + except: + if support.verbose: + print("*** STDOUT ***") + print(data["stdout"]) + raise + + def test_list_paths(self): + data = self.run_py(["--list-paths"]) + found = {} + expect = {} + for line in data["stdout"].splitlines(): + m = re.match(r"\s*(.+?)\s+?(\*\s+)?(.+)$", line) + if m: + found[m.group(1)] = m.group(3) + for company in TEST_DATA: + company_data = TEST_DATA[company] + tags = [t for t in company_data if isinstance(company_data[t], dict)] + for tag in tags: + arg = f"-V:{company}/{tag}" + install = company_data[tag]["InstallPath"] + try: + expect[arg] = install["ExecutablePath"] + try: + expect[arg] += " " + install["ExecutableArguments"] + except KeyError: + pass + except KeyError: + expect[arg] = str(Path(install[None]) / Path(sys.executable).name) + + expect.pop(f"-V:{company}/ignored", None) + + actual = {k: v for k, v in found.items() if k in expect} + try: + self.assertDictEqual(expect, actual) + except: + if support.verbose: + print("*** STDOUT ***") + print(data["stdout"]) + raise + + def test_filter_to_company(self): + company = "PythonTestSuite" + data = self.run_py([f"-V:{company}/"]) + self.assertEqual("X.Y.exe", data["LaunchCommand"]) + self.assertEqual(company, data["env.company"]) + self.assertEqual("3.100", data["env.tag"]) + + def test_filter_to_company_with_default(self): + company = "PythonTestSuite" + data = self.run_py([f"-V:{company}/"], env=dict(PY_PYTHON="3.0")) + self.assertEqual("X.Y.exe", data["LaunchCommand"]) + self.assertEqual(company, data["env.company"]) + self.assertEqual("3.100", data["env.tag"]) + + def test_filter_to_tag(self): + company = "PythonTestSuite" + data = self.run_py([f"-V:3.100"]) + self.assertEqual("X.Y.exe", data["LaunchCommand"]) + self.assertEqual(company, data["env.company"]) + self.assertEqual("3.100", data["env.tag"]) + + data = self.run_py([f"-V:3.100-3"]) + self.assertEqual("X.Y-32.exe", data["LaunchCommand"]) + self.assertEqual(company, data["env.company"]) + self.assertEqual("3.100-32", data["env.tag"]) + + data = self.run_py([f"-V:3.100-a"]) + self.assertEqual("X.Y-arm64.exe -X fake_arg_for_test", data["LaunchCommand"]) + self.assertEqual(company, data["env.company"]) + self.assertEqual("3.100-arm64", data["env.tag"]) + + def test_filter_to_company_and_tag(self): + company = "PythonTestSuite" + data = self.run_py([f"-V:{company}/3.1"]) + self.assertEqual("X.Y.exe", data["LaunchCommand"]) + self.assertEqual(company, data["env.company"]) + self.assertEqual("3.100", data["env.tag"]) + + def test_search_major_3(self): + try: + data = self.run_py(["-3"], allow_fail=True) + except subprocess.CalledProcessError: + raise unittest.SkipTest("requires at least one Python 3.x install") + self.assertEqual("PythonCore", data["env.company"]) + self.assertTrue(data["env.tag"].startswith("3."), data["env.tag"]) + + def test_search_major_3_32(self): + try: + data = self.run_py(["-3-32"], allow_fail=True) + except subprocess.CalledProcessError: + if not any(is_installed(f"3.{i}-32") for i in range(5, 11)): + raise unittest.SkipTest("requires at least one 32-bit Python 3.x install") + raise + self.assertEqual("PythonCore", data["env.company"]) + self.assertTrue(data["env.tag"].startswith("3."), data["env.tag"]) + self.assertTrue(data["env.tag"].endswith("-32"), data["env.tag"]) + + def test_search_major_2(self): + try: + data = self.run_py(["-2"], allow_fail=True) + except subprocess.CalledProcessError: + if not is_installed("2.7"): + raise unittest.SkipTest("requires at least one Python 2.x install") + self.assertEqual("PythonCore", data["env.company"]) + self.assertTrue(data["env.tag"].startswith("2."), data["env.tag"]) + + def test_py_default(self): + with self.py_ini(TEST_PY_DEFAULTS): + data = self.run_py(["-arg"]) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100", data["SearchInfo.tag"]) + self.assertEqual("X.Y.exe -arg", data["stdout"].strip()) + + def test_py2_default(self): + with self.py_ini(TEST_PY_DEFAULTS): + data = self.run_py(["-2", "-arg"]) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100-32", data["SearchInfo.tag"]) + self.assertEqual("X.Y-32.exe -arg", data["stdout"].strip()) + + def test_py3_default(self): + with self.py_ini(TEST_PY_DEFAULTS): + data = self.run_py(["-3", "-arg"]) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100-arm64", data["SearchInfo.tag"]) + self.assertEqual("X.Y-arm64.exe -X fake_arg_for_test -arg", data["stdout"].strip()) + + def test_py_default_env(self): + data = self.run_py(["-arg"], env=TEST_PY_ENV) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100", data["SearchInfo.tag"]) + self.assertEqual("X.Y.exe -arg", data["stdout"].strip()) + + def test_py2_default_env(self): + data = self.run_py(["-2", "-arg"], env=TEST_PY_ENV) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100-32", data["SearchInfo.tag"]) + self.assertEqual("X.Y-32.exe -arg", data["stdout"].strip()) + + def test_py3_default_env(self): + data = self.run_py(["-3", "-arg"], env=TEST_PY_ENV) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100-arm64", data["SearchInfo.tag"]) + self.assertEqual("X.Y-arm64.exe -X fake_arg_for_test -arg", data["stdout"].strip()) + + def test_py_default_short_argv0(self): + with self.py_ini(TEST_PY_DEFAULTS): + for argv0 in ['"py.exe"', 'py.exe', '"py"', 'py']: + with self.subTest(argv0): + data = self.run_py(["--version"], argv=f'{argv0} --version') + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100", data["SearchInfo.tag"]) + self.assertEqual(f'X.Y.exe --version', data["stdout"].strip()) + + def test_py_default_in_list(self): + data = self.run_py(["-0"], env=TEST_PY_ENV) + default = None + for line in data["stdout"].splitlines(): + m = re.match(r"\s*-V:(.+?)\s+?\*\s+(.+)$", line) + if m: + default = m.group(1) + break + self.assertEqual("PythonTestSuite/3.100", default) + + def test_virtualenv_in_list(self): + with self.fake_venv() as (venv_exe, env): + data = self.run_py(["-0p"], env=env) + for line in data["stdout"].splitlines(): + m = re.match(r"\s*\*\s+(.+)$", line) + if m: + self.assertEqual(str(venv_exe), m.group(1)) + break + else: + self.fail("did not find active venv path") + + data = self.run_py(["-0"], env=env) + for line in data["stdout"].splitlines(): + m = re.match(r"\s*\*\s+(.+)$", line) + if m: + self.assertEqual("Active venv", m.group(1)) + break + else: + self.fail("did not find active venv entry") + + def test_virtualenv_with_env(self): + with self.fake_venv() as (venv_exe, env): + data1 = self.run_py([], env={**env, "PY_PYTHON": "PythonTestSuite/3"}) + data2 = self.run_py(["-V:PythonTestSuite/3"], env={**env, "PY_PYTHON": "PythonTestSuite/3"}) + # Compare stdout, because stderr goes via ascii + self.assertEqual(data1["stdout"].strip(), str(venv_exe)) + self.assertEqual(data1["SearchInfo.lowPriorityTag"], "True") + # Ensure passing the argument doesn't trigger the same behaviour + self.assertNotEqual(data2["stdout"].strip(), str(venv_exe)) + self.assertNotEqual(data2["SearchInfo.lowPriorityTag"], "True") + + def test_py_shebang(self): + with self.py_ini(TEST_PY_DEFAULTS): + with self.script("#! /usr/bin/python -prearg") as script: + data = self.run_py([script, "-postarg"]) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100", data["SearchInfo.tag"]) + self.assertEqual(f"X.Y.exe -prearg {script} -postarg", data["stdout"].strip()) + + def test_python_shebang(self): + with self.py_ini(TEST_PY_DEFAULTS): + with self.script("#! python -prearg") as script: + data = self.run_py([script, "-postarg"]) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100", data["SearchInfo.tag"]) + self.assertEqual(f"X.Y.exe -prearg {script} -postarg", data["stdout"].strip()) + + def test_py2_shebang(self): + with self.py_ini(TEST_PY_DEFAULTS): + with self.script("#! /usr/bin/python2 -prearg") as script: + data = self.run_py([script, "-postarg"]) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100-32", data["SearchInfo.tag"]) + self.assertEqual(f"X.Y-32.exe -prearg {script} -postarg", data["stdout"].strip()) + + def test_py3_shebang(self): + with self.py_ini(TEST_PY_DEFAULTS): + with self.script("#! /usr/bin/python3 -prearg") as script: + data = self.run_py([script, "-postarg"]) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100-arm64", data["SearchInfo.tag"]) + self.assertEqual(f"X.Y-arm64.exe -X fake_arg_for_test -prearg {script} -postarg", data["stdout"].strip()) + + def test_py_shebang_nl(self): + with self.py_ini(TEST_PY_DEFAULTS): + with self.script("#! /usr/bin/python -prearg\n") as script: + data = self.run_py([script, "-postarg"]) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100", data["SearchInfo.tag"]) + self.assertEqual(f"X.Y.exe -prearg {script} -postarg", data["stdout"].strip()) + + def test_py2_shebang_nl(self): + with self.py_ini(TEST_PY_DEFAULTS): + with self.script("#! /usr/bin/python2 -prearg\n") as script: + data = self.run_py([script, "-postarg"]) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100-32", data["SearchInfo.tag"]) + self.assertEqual(f"X.Y-32.exe -prearg {script} -postarg", data["stdout"].strip()) + + def test_py3_shebang_nl(self): + with self.py_ini(TEST_PY_DEFAULTS): + with self.script("#! /usr/bin/python3 -prearg\n") as script: + data = self.run_py([script, "-postarg"]) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100-arm64", data["SearchInfo.tag"]) + self.assertEqual(f"X.Y-arm64.exe -X fake_arg_for_test -prearg {script} -postarg", data["stdout"].strip()) + + def test_py_shebang_short_argv0(self): + with self.py_ini(TEST_PY_DEFAULTS): + with self.script("#! /usr/bin/python -prearg") as script: + # Override argv to only pass "py.exe" as the command + data = self.run_py([script, "-postarg"], argv=f'"py.exe" "{script}" -postarg') + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100", data["SearchInfo.tag"]) + self.assertEqual(f'X.Y.exe -prearg "{script}" -postarg', data["stdout"].strip()) + + def test_py_handle_64_in_ini(self): + with self.py_ini("\n".join(["[defaults]", "python=3.999-64"])): + # Expect this to fail, but should get oldStyleTag flipped on + data = self.run_py([], allow_fail=True, expect_returncode=103) + self.assertEqual("3.999-64", data["SearchInfo.tag"]) + self.assertEqual("True", data["SearchInfo.oldStyleTag"]) + + def test_search_path(self): + stem = Path(sys.executable).stem + with self.py_ini(TEST_PY_DEFAULTS): + with self.script(f"#! /usr/bin/env {stem} -prearg") as script: + data = self.run_py( + [script, "-postarg"], + env={"PATH": f"{Path(sys.executable).parent};{os.getenv('PATH')}"}, + ) + self.assertEqual(f"{sys.executable} -prearg {script} -postarg", data["stdout"].strip()) + + def test_search_path_exe(self): + # Leave the .exe on the name to ensure we don't add it a second time + name = Path(sys.executable).name + with self.py_ini(TEST_PY_DEFAULTS): + with self.script(f"#! /usr/bin/env {name} -prearg") as script: + data = self.run_py( + [script, "-postarg"], + env={"PATH": f"{Path(sys.executable).parent};{os.getenv('PATH')}"}, + ) + self.assertEqual(f"{sys.executable} -prearg {script} -postarg", data["stdout"].strip()) + + def test_recursive_search_path(self): + stem = self.get_py_exe().stem + with self.py_ini(TEST_PY_DEFAULTS): + with self.script(f"#! /usr/bin/env {stem}") as script: + data = self.run_py( + [script], + env={"PATH": f"{self.get_py_exe().parent};{os.getenv('PATH')}"}, + ) + # The recursive search is ignored and we get normal "py" behavior + self.assertEqual(f"X.Y.exe {script}", data["stdout"].strip()) + + def test_install(self): + data = self.run_py(["-V:3.10"], env={"PYLAUNCHER_ALWAYS_INSTALL": "1"}, expect_returncode=111) + cmd = data["stdout"].strip() + # If winget is runnable, we should find it. Otherwise, we'll be trying + # to open the Store. + try: + subprocess.check_call(["winget.exe", "--version"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + except FileNotFoundError: + self.assertIn("ms-windows-store://", cmd) + else: + self.assertIn("winget.exe", cmd) + # Both command lines include the store ID + self.assertIn("9PJPW5LDXLZ5", cmd) + + def test_literal_shebang_absolute(self): + with self.script(f"#! C:/some_random_app -witharg") as script: + data = self.run_py([script]) + self.assertEqual( + f"C:\\some_random_app -witharg {script}", + data["stdout"].strip(), + ) + + def test_literal_shebang_relative(self): + with self.script(f"#! ..\\some_random_app -witharg") as script: + data = self.run_py([script]) + self.assertEqual( + f"{script.parent.parent}\\some_random_app -witharg {script}", + data["stdout"].strip(), + ) + + def test_literal_shebang_quoted(self): + with self.script(f'#! "some random app" -witharg') as script: + data = self.run_py([script]) + self.assertEqual( + f'"{script.parent}\\some random app" -witharg {script}', + data["stdout"].strip(), + ) + + with self.script(f'#! some" random "app -witharg') as script: + data = self.run_py([script]) + self.assertEqual( + f'"{script.parent}\\some random app" -witharg {script}', + data["stdout"].strip(), + ) + + def test_literal_shebang_quoted_escape(self): + with self.script(f'#! some\\" random "app -witharg') as script: + data = self.run_py([script]) + self.assertEqual( + f'"{script.parent}\\some\\ random app" -witharg {script}', + data["stdout"].strip(), + ) + + def test_literal_shebang_command(self): + with self.py_ini(TEST_PY_COMMANDS): + with self.script('#! test-command arg1') as script: + data = self.run_py([script]) + self.assertEqual( + f"TEST_EXE.exe arg1 {script}", + data["stdout"].strip(), + ) + + def test_literal_shebang_invalid_template(self): + with self.script('#! /usr/bin/not-python arg1') as script: + data = self.run_py([script]) + expect = script.parent / "/usr/bin/not-python" + self.assertEqual( + f"{expect} arg1 {script}", + data["stdout"].strip(), + ) diff --git a/Lib/test/test_lib2to3.py b/Lib/test/test_lib2to3.py deleted file mode 100644 index 6ea8aa4a56e..00000000000 --- a/Lib/test/test_lib2to3.py +++ /dev/null @@ -1,9 +0,0 @@ -import unittest -from test.support.import_helper import import_fresh_module -from test.support.warnings_helper import check_warnings - -with check_warnings(("", DeprecationWarning)): - load_tests = import_fresh_module('lib2to3.tests', fresh=['lib2to3']).load_tests - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_lib2to3/__init__.py b/Lib/test/test_lib2to3/__init__.py new file mode 100644 index 00000000000..f323c2355b2 --- /dev/null +++ b/Lib/test/test_lib2to3/__init__.py @@ -0,0 +1,11 @@ +# Author: Collin Winter + +import os +import warnings + +from test.support import load_package_tests + +def load_tests(*args): + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', category=DeprecationWarning, message='lib2to3') + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/lib2to3/tests/__main__.py b/Lib/test/test_lib2to3/__main__.py similarity index 100% rename from Lib/lib2to3/tests/__main__.py rename to Lib/test/test_lib2to3/__main__.py diff --git a/Lib/lib2to3/tests/data/README b/Lib/test/test_lib2to3/data/README similarity index 100% rename from Lib/lib2to3/tests/data/README rename to Lib/test/test_lib2to3/data/README diff --git a/Lib/lib2to3/tests/data/bom.py b/Lib/test/test_lib2to3/data/bom.py similarity index 100% rename from Lib/lib2to3/tests/data/bom.py rename to Lib/test/test_lib2to3/data/bom.py diff --git a/Lib/lib2to3/tests/data/crlf.py b/Lib/test/test_lib2to3/data/crlf.py similarity index 100% rename from Lib/lib2to3/tests/data/crlf.py rename to Lib/test/test_lib2to3/data/crlf.py diff --git a/Lib/lib2to3/tests/data/different_encoding.py b/Lib/test/test_lib2to3/data/different_encoding.py similarity index 100% rename from Lib/lib2to3/tests/data/different_encoding.py rename to Lib/test/test_lib2to3/data/different_encoding.py diff --git a/Lib/lib2to3/tests/data/false_encoding.py b/Lib/test/test_lib2to3/data/false_encoding.py similarity index 100% rename from Lib/lib2to3/tests/data/false_encoding.py rename to Lib/test/test_lib2to3/data/false_encoding.py diff --git a/Lib/lib2to3/tests/data/fixers/bad_order.py b/Lib/test/test_lib2to3/data/fixers/bad_order.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/bad_order.py rename to Lib/test/test_lib2to3/data/fixers/bad_order.py diff --git a/Lib/test/test_importlib/zipdata02/__init__.py b/Lib/test/test_lib2to3/data/fixers/myfixes/__init__.py similarity index 100% rename from Lib/test/test_importlib/zipdata02/__init__.py rename to Lib/test/test_lib2to3/data/fixers/myfixes/__init__.py diff --git a/Lib/lib2to3/tests/data/fixers/myfixes/fix_explicit.py b/Lib/test/test_lib2to3/data/fixers/myfixes/fix_explicit.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/myfixes/fix_explicit.py rename to Lib/test/test_lib2to3/data/fixers/myfixes/fix_explicit.py diff --git a/Lib/lib2to3/tests/data/fixers/myfixes/fix_first.py b/Lib/test/test_lib2to3/data/fixers/myfixes/fix_first.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/myfixes/fix_first.py rename to Lib/test/test_lib2to3/data/fixers/myfixes/fix_first.py diff --git a/Lib/lib2to3/tests/data/fixers/myfixes/fix_last.py b/Lib/test/test_lib2to3/data/fixers/myfixes/fix_last.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/myfixes/fix_last.py rename to Lib/test/test_lib2to3/data/fixers/myfixes/fix_last.py diff --git a/Lib/lib2to3/tests/data/fixers/myfixes/fix_parrot.py b/Lib/test/test_lib2to3/data/fixers/myfixes/fix_parrot.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/myfixes/fix_parrot.py rename to Lib/test/test_lib2to3/data/fixers/myfixes/fix_parrot.py diff --git a/Lib/lib2to3/tests/data/fixers/myfixes/fix_preorder.py b/Lib/test/test_lib2to3/data/fixers/myfixes/fix_preorder.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/myfixes/fix_preorder.py rename to Lib/test/test_lib2to3/data/fixers/myfixes/fix_preorder.py diff --git a/Lib/lib2to3/tests/data/fixers/no_fixer_cls.py b/Lib/test/test_lib2to3/data/fixers/no_fixer_cls.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/no_fixer_cls.py rename to Lib/test/test_lib2to3/data/fixers/no_fixer_cls.py diff --git a/Lib/lib2to3/tests/data/fixers/parrot_example.py b/Lib/test/test_lib2to3/data/fixers/parrot_example.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/parrot_example.py rename to Lib/test/test_lib2to3/data/fixers/parrot_example.py diff --git a/Lib/lib2to3/tests/data/infinite_recursion.py b/Lib/test/test_lib2to3/data/infinite_recursion.py similarity index 99% rename from Lib/lib2to3/tests/data/infinite_recursion.py rename to Lib/test/test_lib2to3/data/infinite_recursion.py index 71715ef29dc..acc62ed4f1a 100644 --- a/Lib/lib2to3/tests/data/infinite_recursion.py +++ b/Lib/test/test_lib2to3/data/infinite_recursion.py @@ -1,5 +1,5 @@ -# This file is used to verify that 2to3 falls back to a slower, iterative pattern matching -# scheme in the event that the faster recursive system fails due to infinite recursion. +# Verify that 2to3 falls back from the recursive pattern matching scheme to a +# slower, iterative scheme in the event of a RecursionError. from ctypes import * STRING = c_char_p diff --git a/Lib/lib2to3/tests/data/py2_test_grammar.py b/Lib/test/test_lib2to3/data/py2_test_grammar.py similarity index 99% rename from Lib/lib2to3/tests/data/py2_test_grammar.py rename to Lib/test/test_lib2to3/data/py2_test_grammar.py index f9e4ea1374f..1a631510f4d 100644 --- a/Lib/lib2to3/tests/data/py2_test_grammar.py +++ b/Lib/test/test_lib2to3/data/py2_test_grammar.py @@ -735,7 +735,7 @@ hello world s = a[-5:] s = a[:-1] s = a[-4:-3] - # A rough test of SF bug 1333982. https://python.org/sf/1333982 + # A rough test of SF bug 1333982. https://bugs.python.org/issue1333982 # The testing here is fairly incomplete. # Test cases should include: commas with 1 and 2 colons d = {} diff --git a/Lib/lib2to3/tests/data/py3_test_grammar.py b/Lib/test/test_lib2to3/data/py3_test_grammar.py similarity index 99% rename from Lib/lib2to3/tests/data/py3_test_grammar.py rename to Lib/test/test_lib2to3/data/py3_test_grammar.py index a4a3f7eac0d..774851f5bd7 100644 --- a/Lib/lib2to3/tests/data/py3_test_grammar.py +++ b/Lib/test/test_lib2to3/data/py3_test_grammar.py @@ -714,7 +714,7 @@ class GrammarTests(unittest.TestCase): s = a[-5:] s = a[:-1] s = a[-4:-3] - # A rough test of SF bug 1333982. https://python.org/sf/1333982 + # A rough test of SF bug 1333982. https://bugs.python.org/issue1333982 # The testing here is fairly incomplete. # Test cases should include: commas with 1 and 2 colons d = {} diff --git a/Lib/lib2to3/tests/pytree_idempotency.py b/Lib/test/test_lib2to3/pytree_idempotency.py similarity index 96% rename from Lib/lib2to3/tests/pytree_idempotency.py rename to Lib/test/test_lib2to3/pytree_idempotency.py index 2e7e9781d42..eb2e2aa02ae 100755 --- a/Lib/lib2to3/tests/pytree_idempotency.py +++ b/Lib/test/test_lib2to3/pytree_idempotency.py @@ -17,9 +17,9 @@ import sys import logging # Local imports -from .. import pytree -from .. import pgen2 -from ..pgen2 import driver +from lib2to3 import pytree +from lib2to3 import pgen2 +from lib2to3.pgen2 import driver logging.basicConfig() diff --git a/Lib/lib2to3/tests/support.py b/Lib/test/test_lib2to3/support.py similarity index 77% rename from Lib/lib2to3/tests/support.py rename to Lib/test/test_lib2to3/support.py index fe084e8903f..9e56273e959 100644 --- a/Lib/lib2to3/tests/support.py +++ b/Lib/test/test_lib2to3/support.py @@ -8,12 +8,14 @@ import os.path from textwrap import dedent # Local imports +import lib2to3 from lib2to3 import pytree, refactor from lib2to3.pgen2 import driver as pgen2_driver +lib2to3_dir = os.path.dirname(lib2to3.__file__) test_dir = os.path.dirname(__file__) proj_dir = os.path.normpath(os.path.join(test_dir, "..")) -grammar_path = os.path.join(test_dir, "..", "Grammar.txt") +grammar_path = os.path.join(lib2to3_dir, "Grammar.txt") grammar = pgen2_driver.load_grammar(grammar_path) grammar_no_print_statement = pgen2_driver.load_grammar(grammar_path) del grammar_no_print_statement.keywords["print"] @@ -49,10 +51,19 @@ def get_refactorer(fixer_pkg="lib2to3", fixers=None, options=None): options = options or {} return refactor.RefactoringTool(fixers, options, explicit=True) -def all_project_files(): - for dirpath, dirnames, filenames in os.walk(proj_dir): +def _all_project_files(root, files): + for dirpath, dirnames, filenames in os.walk(root): for filename in filenames: - if filename.endswith(".py"): - yield os.path.join(dirpath, filename) + if not filename.endswith(".py"): + continue + files.append(os.path.join(dirpath, filename)) + +def all_project_files(): + files = [] + _all_project_files(lib2to3_dir, files) + _all_project_files(test_dir, files) + # Sort to get more reproducible tests + files.sort() + return files TestCase = unittest.TestCase diff --git a/Lib/test/test_lib2to3/test_all_fixers.py b/Lib/test/test_lib2to3/test_all_fixers.py new file mode 100644 index 00000000000..d0fca707248 --- /dev/null +++ b/Lib/test/test_lib2to3/test_all_fixers.py @@ -0,0 +1,41 @@ +"""Tests that run all fixer modules over an input stream. + +This has been broken out into its own test module because of its +running time. +""" +# Author: Collin Winter + +# Python imports +import os.path +import test.support +import unittest + +# Local imports +from . import support + + +@test.support.requires_resource('cpu') +class Test_all(support.TestCase): + + def setUp(self): + self.refactor = support.get_refactorer() + + def refactor_file(self, filepath): + if test.support.verbose: + print(f"Refactor file: {filepath}") + if os.path.basename(filepath) == 'infinite_recursion.py': + # bpo-46542: Processing infinite_recursion.py can crash Python + # if Python is built in debug mode: lower the recursion limit + # to prevent a crash. + with test.support.infinite_recursion(150): + self.refactor.refactor_file(filepath) + else: + self.refactor.refactor_file(filepath) + + def test_all_project_files(self): + for filepath in support.all_project_files(): + with self.subTest(filepath=filepath): + self.refactor_file(filepath) + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/lib2to3/tests/test_fixers.py b/Lib/test/test_lib2to3/test_fixers.py similarity index 99% rename from Lib/lib2to3/tests/test_fixers.py rename to Lib/test/test_lib2to3/test_fixers.py index 121ebe68e54..68efeee7abb 100644 --- a/Lib/lib2to3/tests/test_fixers.py +++ b/Lib/test/test_lib2to3/test_fixers.py @@ -7,7 +7,7 @@ from operator import itemgetter # Local imports from lib2to3 import pygram, fixer_util -from lib2to3.tests import support +from test.test_lib2to3 import support class FixerTestCase(support.TestCase): @@ -1791,7 +1791,7 @@ class ImportsFixerTests: class Test_imports(FixerTestCase, ImportsFixerTests): fixer = "imports" - from ..fixes.fix_imports import MAPPING as modules + from lib2to3.fixes.fix_imports import MAPPING as modules def test_multiple_imports(self): b = """import urlparse, cStringIO""" @@ -1812,16 +1812,16 @@ class Test_imports(FixerTestCase, ImportsFixerTests): class Test_imports2(FixerTestCase, ImportsFixerTests): fixer = "imports2" - from ..fixes.fix_imports2 import MAPPING as modules + from lib2to3.fixes.fix_imports2 import MAPPING as modules class Test_imports_fixer_order(FixerTestCase, ImportsFixerTests): def setUp(self): super(Test_imports_fixer_order, self).setUp(['imports', 'imports2']) - from ..fixes.fix_imports2 import MAPPING as mapping2 + from lib2to3.fixes.fix_imports2 import MAPPING as mapping2 self.modules = mapping2.copy() - from ..fixes.fix_imports import MAPPING as mapping1 + from lib2to3.fixes.fix_imports import MAPPING as mapping1 for key in ('dbhash', 'dumbdbm', 'dbm', 'gdbm'): self.modules[key] = mapping1[key] @@ -1833,7 +1833,7 @@ class Test_imports_fixer_order(FixerTestCase, ImportsFixerTests): class Test_urllib(FixerTestCase): fixer = "urllib" - from ..fixes.fix_urllib import MAPPING as modules + from lib2to3.fixes.fix_urllib import MAPPING as modules def test_import_module(self): for old, changes in self.modules.items(): diff --git a/Lib/lib2to3/tests/test_main.py b/Lib/test/test_lib2to3/test_main.py similarity index 100% rename from Lib/lib2to3/tests/test_main.py rename to Lib/test/test_lib2to3/test_main.py diff --git a/Lib/lib2to3/tests/test_parser.py b/Lib/test/test_lib2to3/test_parser.py similarity index 95% rename from Lib/lib2to3/tests/test_parser.py rename to Lib/test/test_lib2to3/test_parser.py index 5eefb5aad7d..2c798b181fd 100644 --- a/Lib/lib2to3/tests/test_parser.py +++ b/Lib/test/test_lib2to3/test_parser.py @@ -20,12 +20,13 @@ import shutil import subprocess import sys import tempfile +import test.support import unittest # Local imports from lib2to3.pgen2 import driver as pgen2_driver from lib2to3.pgen2 import tokenize -from ..pgen2.parse import ParseError +from lib2to3.pgen2.parse import ParseError from lib2to3.pygram import python_symbols as syms @@ -61,6 +62,9 @@ class TestPgen2Caching(support.TestCase): shutil.rmtree(tmpdir) @unittest.skipIf(sys.executable is None, 'sys.executable required') + @unittest.skipIf( + sys.platform in {'emscripten', 'wasi'}, 'requires working subprocess' + ) def test_load_grammar_from_subprocess(self): tmpdir = tempfile.mkdtemp() tmpsubdir = os.path.join(tmpdir, 'subdir') @@ -88,10 +92,8 @@ class TestPgen2Caching(support.TestCase): from lib2to3.pgen2 import driver as pgen2_driver pgen2_driver.load_grammar(%r, save=True, force=True) """ % (grammar_sub_copy,) - msg = ("lib2to3 package is deprecated and may not be able " - "to parse Python 3.10+") cmd = [sys.executable, - f'-Wignore:{msg}:PendingDeprecationWarning', + '-Wignore:lib2to3:DeprecationWarning', '-c', code] subprocess.check_call( cmd, env=sub_env) self.assertTrue(os.path.exists(pickle_sub_name)) @@ -586,25 +588,31 @@ class TestParserIdempotency(support.TestCase): """A cut-down version of pytree_idempotency.py.""" + def parse_file(self, filepath): + if test.support.verbose: + print(f"Parse file: {filepath}") + with open(filepath, "rb") as fp: + encoding = tokenize.detect_encoding(fp.readline)[0] + self.assertIsNotNone(encoding, + "can't detect encoding for %s" % filepath) + with open(filepath, "r", encoding=encoding) as fp: + source = fp.read() + try: + tree = driver.parse_string(source) + except ParseError: + try: + tree = driver_no_print_statement.parse_string(source) + except ParseError as err: + self.fail('ParseError on file %s (%s)' % (filepath, err)) + new = str(tree) + if new != source: + print(diff_texts(source, new, filepath)) + self.fail("Idempotency failed: %s" % filepath) + def test_all_project_files(self): for filepath in support.all_project_files(): - with open(filepath, "rb") as fp: - encoding = tokenize.detect_encoding(fp.readline)[0] - self.assertIsNotNone(encoding, - "can't detect encoding for %s" % filepath) - with open(filepath, "r", encoding=encoding) as fp: - source = fp.read() - try: - tree = driver.parse_string(source) - except ParseError: - try: - tree = driver_no_print_statement.parse_string(source) - except ParseError as err: - self.fail('ParseError on file %s (%s)' % (filepath, err)) - new = str(tree) - if new != source: - print(diff_texts(source, new, filepath)) - self.fail("Idempotency failed: %s" % filepath) + with self.subTest(filepath=filepath): + self.parse_file(filepath) def test_extended_unpacking(self): driver.parse_string("a, *b, c = x\n") diff --git a/Lib/lib2to3/tests/test_pytree.py b/Lib/test/test_lib2to3/test_pytree.py similarity index 100% rename from Lib/lib2to3/tests/test_pytree.py rename to Lib/test/test_lib2to3/test_pytree.py diff --git a/Lib/lib2to3/tests/test_refactor.py b/Lib/test/test_lib2to3/test_refactor.py similarity index 100% rename from Lib/lib2to3/tests/test_refactor.py rename to Lib/test/test_lib2to3/test_refactor.py diff --git a/Lib/lib2to3/tests/test_util.py b/Lib/test/test_lib2to3/test_util.py similarity index 100% rename from Lib/lib2to3/tests/test_util.py rename to Lib/test/test_lib2to3/test_util.py diff --git a/Lib/test/test_linecache.py b/Lib/test/test_linecache.py index c6e2dadbb25..72dd40136cf 100644 --- a/Lib/test/test_linecache.py +++ b/Lib/test/test_linecache.py @@ -73,12 +73,10 @@ class GetLineTestsBadData(TempFile): # file_byte_string = b'Bad data goes here' def test_getline(self): - self.assertRaises((SyntaxError, UnicodeDecodeError), - linecache.getline, self.file_name, 1) + self.assertEqual(linecache.getline(self.file_name, 1), '') def test_getlines(self): - self.assertRaises((SyntaxError, UnicodeDecodeError), - linecache.getlines, self.file_name) + self.assertEqual(linecache.getlines(self.file_name), []) class EmptyFile(GetLineTestsGoodData, unittest.TestCase): @@ -92,9 +90,11 @@ class SingleEmptyLine(GetLineTestsGoodData, unittest.TestCase): class GoodUnicode(GetLineTestsGoodData, unittest.TestCase): file_list = ['á\n', 'b\n', 'abcdef\n', 'ááááá\n'] +class BadUnicode_NoDeclaration(GetLineTestsBadData, unittest.TestCase): + file_byte_string = b'\n\x80abc' -class BadUnicode(GetLineTestsBadData, unittest.TestCase): - file_byte_string = b'\x80abc' +class BadUnicode_WithDeclaration(GetLineTestsBadData, unittest.TestCase): + file_byte_string = b'# coding=utf-8\n\x80abc' class LineCacheTests(unittest.TestCase): diff --git a/Lib/test/test_list.py b/Lib/test/test_list.py index d3da05ba84a..2969c6e2f98 100644 --- a/Lib/test/test_list.py +++ b/Lib/test/test_list.py @@ -96,6 +96,19 @@ class ListTest(list_tests.CommonTest): self.assertRaises((MemoryError, OverflowError), mul, lst, n) self.assertRaises((MemoryError, OverflowError), imul, lst, n) + def test_list_resize_overflow(self): + # gh-97616: test new_allocated * sizeof(PyObject*) overflow + # check in list_resize() + lst = [0] * 65 + del lst[1:] + self.assertEqual(len(lst), 1) + + size = sys.maxsize + with self.assertRaises((MemoryError, OverflowError)): + lst * size + with self.assertRaises((MemoryError, OverflowError)): + lst *= size + def test_repr_large(self): # Check the repr of large list objects def check(n): diff --git a/Lib/test/test_lltrace.py b/Lib/test/test_lltrace.py index 06e33f4c4c2..f638b649bfb 100644 --- a/Lib/test/test_lltrace.py +++ b/Lib/test/test_lltrace.py @@ -1,31 +1,111 @@ -import os +import dis import textwrap import unittest +from test import support from test.support import os_helper from test.support.script_helper import assert_python_ok +def example(): + x = [] + for i in range(0): + x.append(i) + x = "this is" + y = "an example" + print(x, y) + +@unittest.skipUnless(support.Py_DEBUG, "lltrace requires Py_DEBUG") class TestLLTrace(unittest.TestCase): + def run_code(self, code): + code = textwrap.dedent(code).strip() + with open(os_helper.TESTFN, 'w', encoding='utf-8') as fd: + self.addCleanup(os_helper.unlink, os_helper.TESTFN) + fd.write(code) + status, stdout, stderr = assert_python_ok(os_helper.TESTFN) + self.assertEqual(stderr, b"") + self.assertEqual(status, 0) + result = stdout.decode('utf-8') + if support.verbose: + print("\n\n--- code ---") + print(code) + print("\n--- stdout ---") + print(result) + print() + return result + + def test_lltrace(self): + stdout = self.run_code(""" + def dont_trace_1(): + a = "a" + a = 10 * a + def trace_me(): + for i in range(3): + +i + def dont_trace_2(): + x = 42 + y = -x + dont_trace_1() + __lltrace__ = 1 + trace_me() + del __lltrace__ + dont_trace_2() + """) + self.assertIn("GET_ITER", stdout) + self.assertIn("FOR_ITER", stdout) + self.assertIn("CALL_INTRINSIC_1", stdout) + self.assertIn("POP_TOP", stdout) + self.assertNotIn("BINARY_OP", stdout) + self.assertNotIn("UNARY_NEGATIVE", stdout) + + self.assertIn("'trace_me' in module '__main__'", stdout) + self.assertNotIn("dont_trace_1", stdout) + self.assertNotIn("'dont_trace_2' in module", stdout) + + def test_lltrace_different_module(self): + stdout = self.run_code(""" + from test import test_lltrace + test_lltrace.__lltrace__ = 1 + test_lltrace.example() + """) + self.assertIn("'example' in module 'test.test_lltrace'", stdout) + self.assertIn('LOAD_CONST', stdout) + self.assertIn('FOR_ITER', stdout) + self.assertIn('this is an example', stdout) + + # check that offsets match the output of dis.dis() + instr_map = {i.offset: i for i in dis.get_instructions(example, adaptive=True)} + for line in stdout.splitlines(): + offset, colon, opname_oparg = line.partition(":") + if not colon: + continue + offset = int(offset) + opname_oparg = opname_oparg.split() + if len(opname_oparg) == 2: + opname, oparg = opname_oparg + oparg = int(oparg) + else: + (opname,) = opname_oparg + oparg = None + self.assertEqual(instr_map[offset].opname, opname) + self.assertEqual(instr_map[offset].arg, oparg) + def test_lltrace_does_not_crash_on_subscript_operator(self): # If this test fails, it will reproduce a crash reported as # bpo-34113. The crash happened at the command line console of - # debug Python builds with __ltrace__ enabled (only possible in console), + # debug Python builds with __lltrace__ enabled (only possible in console), # when the internal Python stack was negatively adjusted - with open(os_helper.TESTFN, 'w', encoding='utf-8') as fd: - self.addCleanup(os_helper.unlink, os_helper.TESTFN) - fd.write(textwrap.dedent("""\ + stdout = self.run_code(""" import code console = code.InteractiveConsole() - console.push('__ltrace__ = 1') + console.push('__lltrace__ = 1') console.push('a = [1, 2, 3]') console.push('a[0] = 1') print('unreachable if bug exists') - """)) - - assert_python_ok(os_helper.TESTFN) + """) + self.assertIn("unreachable if bug exists", stdout) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py index f844e62ca2e..b0d79985597 100644 --- a/Lib/test/test_locale.py +++ b/Lib/test/test_locale.py @@ -1,5 +1,5 @@ from decimal import Decimal -from test.support import verbose, is_android +from test.support import verbose, is_android, is_emscripten, is_wasi from test.support.warnings_helper import check_warnings import unittest import locale @@ -141,18 +141,9 @@ class BaseFormattingTest(object): # Utility functions for formatting tests # - def _test_formatfunc(self, format, value, out, func, **format_opts): - self.assertEqual( - func(format, value, **format_opts), out) - - def _test_format(self, format, value, out, **format_opts): - with check_warnings(('', DeprecationWarning)): - self._test_formatfunc(format, value, out, - func=locale.format, **format_opts) - def _test_format_string(self, format, value, out, **format_opts): - self._test_formatfunc(format, value, out, - func=locale.format_string, **format_opts) + self.assertEqual( + locale.format_string(format, value, **format_opts), out) def _test_currency(self, value, out, **format_opts): self.assertEqual(locale.currency(value, **format_opts), out) @@ -166,44 +157,40 @@ class EnUSNumberFormatting(BaseFormattingTest): self.sep = locale.localeconv()['thousands_sep'] def test_grouping(self): - self._test_format("%f", 1024, grouping=1, out='1%s024.000000' % self.sep) - self._test_format("%f", 102, grouping=1, out='102.000000') - self._test_format("%f", -42, grouping=1, out='-42.000000') - self._test_format("%+f", -42, grouping=1, out='-42.000000') + self._test_format_string("%f", 1024, grouping=1, out='1%s024.000000' % self.sep) + self._test_format_string("%f", 102, grouping=1, out='102.000000') + self._test_format_string("%f", -42, grouping=1, out='-42.000000') + self._test_format_string("%+f", -42, grouping=1, out='-42.000000') def test_grouping_and_padding(self): - self._test_format("%20.f", -42, grouping=1, out='-42'.rjust(20)) + self._test_format_string("%20.f", -42, grouping=1, out='-42'.rjust(20)) if self.sep: - self._test_format("%+10.f", -4200, grouping=1, + self._test_format_string("%+10.f", -4200, grouping=1, out=('-4%s200' % self.sep).rjust(10)) - self._test_format("%-10.f", -4200, grouping=1, + self._test_format_string("%-10.f", -4200, grouping=1, out=('-4%s200' % self.sep).ljust(10)) def test_integer_grouping(self): - self._test_format("%d", 4200, grouping=True, out='4%s200' % self.sep) - self._test_format("%+d", 4200, grouping=True, out='+4%s200' % self.sep) - self._test_format("%+d", -4200, grouping=True, out='-4%s200' % self.sep) + self._test_format_string("%d", 4200, grouping=True, out='4%s200' % self.sep) + self._test_format_string("%+d", 4200, grouping=True, out='+4%s200' % self.sep) + self._test_format_string("%+d", -4200, grouping=True, out='-4%s200' % self.sep) def test_integer_grouping_and_padding(self): - self._test_format("%10d", 4200, grouping=True, + self._test_format_string("%10d", 4200, grouping=True, out=('4%s200' % self.sep).rjust(10)) - self._test_format("%-10d", -4200, grouping=True, + self._test_format_string("%-10d", -4200, grouping=True, out=('-4%s200' % self.sep).ljust(10)) def test_simple(self): - self._test_format("%f", 1024, grouping=0, out='1024.000000') - self._test_format("%f", 102, grouping=0, out='102.000000') - self._test_format("%f", -42, grouping=0, out='-42.000000') - self._test_format("%+f", -42, grouping=0, out='-42.000000') + self._test_format_string("%f", 1024, grouping=0, out='1024.000000') + self._test_format_string("%f", 102, grouping=0, out='102.000000') + self._test_format_string("%f", -42, grouping=0, out='-42.000000') + self._test_format_string("%+f", -42, grouping=0, out='-42.000000') def test_padding(self): - self._test_format("%20.f", -42, grouping=0, out='-42'.rjust(20)) - self._test_format("%+10.f", -4200, grouping=0, out='-4200'.rjust(10)) - self._test_format("%-10.f", 4200, grouping=0, out='4200'.ljust(10)) - - def test_format_deprecation(self): - with self.assertWarns(DeprecationWarning): - locale.format("%-10.f", 4200, grouping=True) + self._test_format_string("%20.f", -42, grouping=0, out='-42'.rjust(20)) + self._test_format_string("%+10.f", -4200, grouping=0, out='-4200'.rjust(10)) + self._test_format_string("%-10.f", 4200, grouping=0, out='4200'.ljust(10)) def test_complex_formatting(self): # Spaces in formatting string @@ -230,20 +217,9 @@ class EnUSNumberFormatting(BaseFormattingTest): out='int 1%s000 float 1%s000.00 str str' % (self.sep, self.sep)) - -class TestFormatPatternArg(unittest.TestCase): - # Test handling of pattern argument of format - - def test_onlyOnePattern(self): - with check_warnings(('', DeprecationWarning)): - # Issue 2522: accept exactly one % pattern, and no extra chars. - self.assertRaises(ValueError, locale.format, "%f\n", 'foo') - self.assertRaises(ValueError, locale.format, "%f\r", 'foo') - self.assertRaises(ValueError, locale.format, "%f\r\n", 'foo') - self.assertRaises(ValueError, locale.format, " %f", 'foo') - self.assertRaises(ValueError, locale.format, "%fg", 'foo') - self.assertRaises(ValueError, locale.format, "%^g", 'foo') - self.assertRaises(ValueError, locale.format, "%f%%", 'foo') + self._test_format_string("total=%i%%", 100, out='total=100%') + self._test_format_string("newline: %i\n", 3, out='newline: 3\n') + self._test_format_string("extra: %ii", 3, out='extra: 3i') class TestLocaleFormatString(unittest.TestCase): @@ -292,45 +268,45 @@ class TestCNumberFormatting(CCookedTest, BaseFormattingTest): # Test number formatting with a cooked "C" locale. def test_grouping(self): - self._test_format("%.2f", 12345.67, grouping=True, out='12345.67') + self._test_format_string("%.2f", 12345.67, grouping=True, out='12345.67') def test_grouping_and_padding(self): - self._test_format("%9.2f", 12345.67, grouping=True, out=' 12345.67') + self._test_format_string("%9.2f", 12345.67, grouping=True, out=' 12345.67') class TestFrFRNumberFormatting(FrFRCookedTest, BaseFormattingTest): # Test number formatting with a cooked "fr_FR" locale. def test_decimal_point(self): - self._test_format("%.2f", 12345.67, out='12345,67') + self._test_format_string("%.2f", 12345.67, out='12345,67') def test_grouping(self): - self._test_format("%.2f", 345.67, grouping=True, out='345,67') - self._test_format("%.2f", 12345.67, grouping=True, out='12 345,67') + self._test_format_string("%.2f", 345.67, grouping=True, out='345,67') + self._test_format_string("%.2f", 12345.67, grouping=True, out='12 345,67') def test_grouping_and_padding(self): - self._test_format("%6.2f", 345.67, grouping=True, out='345,67') - self._test_format("%7.2f", 345.67, grouping=True, out=' 345,67') - self._test_format("%8.2f", 12345.67, grouping=True, out='12 345,67') - self._test_format("%9.2f", 12345.67, grouping=True, out='12 345,67') - self._test_format("%10.2f", 12345.67, grouping=True, out=' 12 345,67') - self._test_format("%-6.2f", 345.67, grouping=True, out='345,67') - self._test_format("%-7.2f", 345.67, grouping=True, out='345,67 ') - self._test_format("%-8.2f", 12345.67, grouping=True, out='12 345,67') - self._test_format("%-9.2f", 12345.67, grouping=True, out='12 345,67') - self._test_format("%-10.2f", 12345.67, grouping=True, out='12 345,67 ') + self._test_format_string("%6.2f", 345.67, grouping=True, out='345,67') + self._test_format_string("%7.2f", 345.67, grouping=True, out=' 345,67') + self._test_format_string("%8.2f", 12345.67, grouping=True, out='12 345,67') + self._test_format_string("%9.2f", 12345.67, grouping=True, out='12 345,67') + self._test_format_string("%10.2f", 12345.67, grouping=True, out=' 12 345,67') + self._test_format_string("%-6.2f", 345.67, grouping=True, out='345,67') + self._test_format_string("%-7.2f", 345.67, grouping=True, out='345,67 ') + self._test_format_string("%-8.2f", 12345.67, grouping=True, out='12 345,67') + self._test_format_string("%-9.2f", 12345.67, grouping=True, out='12 345,67') + self._test_format_string("%-10.2f", 12345.67, grouping=True, out='12 345,67 ') def test_integer_grouping(self): - self._test_format("%d", 200, grouping=True, out='200') - self._test_format("%d", 4200, grouping=True, out='4 200') + self._test_format_string("%d", 200, grouping=True, out='200') + self._test_format_string("%d", 4200, grouping=True, out='4 200') def test_integer_grouping_and_padding(self): - self._test_format("%4d", 4200, grouping=True, out='4 200') - self._test_format("%5d", 4200, grouping=True, out='4 200') - self._test_format("%10d", 4200, grouping=True, out='4 200'.rjust(10)) - self._test_format("%-4d", 4200, grouping=True, out='4 200') - self._test_format("%-5d", 4200, grouping=True, out='4 200') - self._test_format("%-10d", 4200, grouping=True, out='4 200'.ljust(10)) + self._test_format_string("%4d", 4200, grouping=True, out='4 200') + self._test_format_string("%5d", 4200, grouping=True, out='4 200') + self._test_format_string("%10d", 4200, grouping=True, out='4 200'.rjust(10)) + self._test_format_string("%-4d", 4200, grouping=True, out='4 200') + self._test_format_string("%-5d", 4200, grouping=True, out='4 200') + self._test_format_string("%-10d", 4200, grouping=True, out='4 200'.ljust(10)) def test_currency(self): euro = '\u20ac' @@ -363,7 +339,7 @@ class TestEnUSCollation(BaseLocalizedTest, TestCollation): locale_type = locale.LC_ALL def setUp(self): - enc = codecs.lookup(locale.getpreferredencoding(False) or 'ascii').name + enc = codecs.lookup(locale.getencoding() or 'ascii').name if enc not in ('utf-8', 'iso8859-1', 'cp1252'): raise unittest.SkipTest('encoding not suitable') if enc != 'iso8859-1' and (sys.platform == 'darwin' or is_android or @@ -373,11 +349,19 @@ class TestEnUSCollation(BaseLocalizedTest, TestCollation): @unittest.skipIf(sys.platform.startswith('aix'), 'bpo-29972: broken test on AIX') + @unittest.skipIf( + is_emscripten or is_wasi, + "musl libc issue on Emscripten/WASI, bpo-46390" + ) def test_strcoll_with_diacritic(self): self.assertLess(locale.strcoll('à', 'b'), 0) @unittest.skipIf(sys.platform.startswith('aix'), 'bpo-29972: broken test on AIX') + @unittest.skipIf( + is_emscripten or is_wasi, + "musl libc issue on Emscripten/WASI, bpo-46390" + ) def test_strxfrm_with_diacritic(self): self.assertLess(locale.strxfrm('à'), locale.strxfrm('b')) @@ -518,7 +502,8 @@ class TestMiscellaneous(unittest.TestCase): os.environ['LC_CTYPE'] = 'UTF-8' - self.assertEqual(locale.getdefaultlocale(), (None, 'UTF-8')) + with check_warnings(('', DeprecationWarning)): + self.assertEqual(locale.getdefaultlocale(), (None, 'UTF-8')) finally: for k in orig_env: @@ -530,6 +515,14 @@ class TestMiscellaneous(unittest.TestCase): if orig_getlocale is not None: _locale._getdefaultlocale = orig_getlocale + def test_getencoding(self): + # Invoke getencoding to make sure it does not cause exceptions. + enc = locale.getencoding() + self.assertIsInstance(enc, str) + self.assertNotEqual(enc, "") + # make sure it is valid + codecs.lookup(enc) + def test_getpreferredencoding(self): # Invoke getpreferredencoding to make sure it does not cause exceptions. enc = locale.getpreferredencoding() diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index e709ea327fb..072056d3722 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -1,4 +1,4 @@ -# Copyright 2001-2019 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2022 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -16,9 +16,8 @@ """Test harness for the logging module. Run all tests. -Copyright (C) 2001-2019 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2022 Vinay Sajip. All Rights Reserved. """ - import logging import logging.handlers import logging.config @@ -30,27 +29,29 @@ import datetime import pathlib import pickle import io +import itertools import gc import json import os import queue import random import re +import shutil import socket import struct import sys import tempfile from test.support.script_helper import assert_python_ok, assert_python_failure from test import support -from test.support import _asyncore as asyncore -from test.support import _smtpd as smtpd from test.support import os_helper from test.support import socket_helper from test.support import threading_helper from test.support import warnings_helper +from test.support import asyncore from test.support.logging_helper import TestHandler import textwrap import threading +import asyncio import time import unittest import warnings @@ -61,6 +62,9 @@ from urllib.parse import urlparse, parse_qs from socketserver import (ThreadingUDPServer, DatagramRequestHandler, ThreadingTCPServer, StreamRequestHandler) +with warnings.catch_warnings(): + from . import smtpd + try: import win32evtlog, win32evtlogutil, pywintypes except ImportError: @@ -71,6 +75,7 @@ try: except ImportError: pass + class BaseTest(unittest.TestCase): """Base class for logging tests.""" @@ -462,6 +467,51 @@ class CustomLevelsAndFiltersTest(BaseTest): for lvl in LEVEL_RANGE: logger.log(lvl, self.next_message()) + def test_handler_filter_replaces_record(self): + def replace_message(record: logging.LogRecord): + record = copy.copy(record) + record.msg = "new message!" + return record + + # Set up a logging hierarchy such that "child" and it's handler + # (and thus `replace_message()`) always get called before + # propagating up to "parent". + # Then we can confirm that `replace_message()` was able to + # replace the log record without having a side effect on + # other loggers or handlers. + parent = logging.getLogger("parent") + child = logging.getLogger("parent.child") + stream_1 = io.StringIO() + stream_2 = io.StringIO() + handler_1 = logging.StreamHandler(stream_1) + handler_2 = logging.StreamHandler(stream_2) + handler_2.addFilter(replace_message) + parent.addHandler(handler_1) + child.addHandler(handler_2) + + child.info("original message") + handler_1.flush() + handler_2.flush() + self.assertEqual(stream_1.getvalue(), "original message\n") + self.assertEqual(stream_2.getvalue(), "new message!\n") + + def test_logging_filter_replaces_record(self): + records = set() + + class RecordingFilter(logging.Filter): + def filter(self, record: logging.LogRecord): + records.add(id(record)) + return copy.copy(record) + + logger = logging.getLogger("logger") + logger.setLevel(logging.INFO) + logger.addFilter(RecordingFilter()) + logger.addFilter(RecordingFilter()) + + logger.info("msg") + + self.assertEqual(2, len(records)) + def test_logger_filter(self): # Filter at logger level. self.root_logger.setLevel(VERBOSE) @@ -535,6 +585,12 @@ class CustomLevelsAndFiltersTest(BaseTest): handler.removeFilter(garr) +def make_temp_file(*args, **kwargs): + fd, fn = tempfile.mkstemp(*args, **kwargs) + os.close(fd) + return fn + + class HandlerTest(BaseTest): def test_name(self): h = logging.Handler() @@ -549,8 +605,7 @@ class HandlerTest(BaseTest): # but we can try instantiating them with various options if sys.platform in ('linux', 'darwin'): for existing in (True, False): - fd, fn = tempfile.mkstemp() - os.close(fd) + fn = make_temp_file() if not existing: os.unlink(fn) h = logging.handlers.WatchedFileHandler(fn, encoding='utf-8', delay=True) @@ -604,8 +659,7 @@ class HandlerTest(BaseTest): See Issue #27493. """ - fd, fn = tempfile.mkstemp() - os.close(fd) + fn = make_temp_file() os.unlink(fn) pfn = pathlib.Path(fn) cases = ( @@ -622,6 +676,10 @@ class HandlerTest(BaseTest): os.unlink(fn) @unittest.skipIf(os.name == 'nt', 'WatchedFileHandler not appropriate for Windows.') + @unittest.skipIf( + support.is_emscripten, "Emscripten cannot fstat unlinked files." + ) + @threading_helper.requires_working_threading() def test_race(self): # Issue #14632 refers. def remove_loop(fname, tries): @@ -640,8 +698,7 @@ class HandlerTest(BaseTest): self.deletion_time = None for delay in (False, True): - fd, fn = tempfile.mkstemp('.log', 'test_logging-3-') - os.close(fd) + fn = make_temp_file('.log', 'test_logging-3-') remover = threading.Thread(target=remove_loop, args=(fn, del_count)) remover.daemon = True remover.start() @@ -670,7 +727,8 @@ class HandlerTest(BaseTest): # based on os.fork existing because that is what users and this test use. # This helps ensure that when fork exists (the important concept) that the # register_at_fork mechanism is also present and used. - @unittest.skipIf(not hasattr(os, 'fork'), 'Test requires os.fork().') + @support.requires_fork() + @threading_helper.requires_working_threading() def test_post_fork_child_no_deadlock(self): """Ensure child logging locks are not held; bpo-6721 & bpo-36533.""" class _OurHandler(logging.Handler): @@ -1054,6 +1112,8 @@ if hasattr(socket, "AF_UNIX"): # - end of server_helper section +@support.requires_working_socket() +@threading_helper.requires_working_threading() class SMTPHandlerTest(BaseTest): # bpo-14314, bpo-19665, bpo-34092: don't wait forever TIMEOUT = support.LONG_TIMEOUT @@ -1163,6 +1223,36 @@ class MemoryHandlerTest(BaseTest): # assert that no new lines have been added self.assert_log_lines(lines) # no change + def test_shutdown_flush_on_close(self): + """ + Test that the flush-on-close configuration is respected by the + shutdown method. + """ + self.mem_logger.debug(self.next_message()) + self.assert_log_lines([]) + self.mem_logger.info(self.next_message()) + self.assert_log_lines([]) + # Default behaviour is to flush on close. Check that it happens. + logging.shutdown(handlerList=[logging.weakref.ref(self.mem_hdlr)]) + lines = [ + ('DEBUG', '1'), + ('INFO', '2'), + ] + self.assert_log_lines(lines) + # Now configure for flushing not to be done on close. + self.mem_hdlr = logging.handlers.MemoryHandler(10, logging.WARNING, + self.root_hdlr, + False) + self.mem_logger.addHandler(self.mem_hdlr) + self.mem_logger.debug(self.next_message()) + self.assert_log_lines(lines) # no change + self.mem_logger.info(self.next_message()) + self.assert_log_lines(lines) # no change + # assert that no new lines have been added after shutdown + logging.shutdown(handlerList=[logging.weakref.ref(self.mem_hdlr)]) + self.assert_log_lines(lines) # no change + + @threading_helper.requires_working_threading() def test_race_between_set_target_and_flush(self): class MockRaceConditionHandler: def __init__(self, mem_hdlr): @@ -1195,6 +1285,9 @@ class ExceptionFormatter(logging.Formatter): def formatException(self, ei): return "Got a [%s]" % ei[0].__name__ +def closeFileHandler(h, fn): + h.close() + os.remove(fn) class ConfigFileTest(BaseTest): @@ -1578,13 +1671,8 @@ class ConfigFileTest(BaseTest): def test_config8_ok(self): - def cleanup(h1, fn): - h1.close() - os.remove(fn) - with self.check_no_resource_warning(): - fd, fn = tempfile.mkstemp(".log", "test_logging-X-") - os.close(fd) + fn = make_temp_file(".log", "test_logging-X-") # Replace single backslash with double backslash in windows # to avoid unicode error during string formatting @@ -1597,7 +1685,7 @@ class ConfigFileTest(BaseTest): self.apply_config(config8) handler = logging.root.handlers[0] - self.addCleanup(cleanup, handler, fn) + self.addCleanup(closeFileHandler, handler, fn) def test_logger_disabling(self): self.apply_config(self.disable_test) @@ -1677,6 +1765,8 @@ class ConfigFileTest(BaseTest): os.unlink(fn) +@support.requires_working_socket() +@threading_helper.requires_working_threading() class SocketHandlerTest(BaseTest): """Test for SocketHandler objects.""" @@ -1766,13 +1856,6 @@ class SocketHandlerTest(BaseTest): time.sleep(self.sock_hdlr.retryTime - now + 0.001) self.root_logger.error('Nor this') -def _get_temp_domain_socket(): - fd, fn = tempfile.mkstemp(prefix='test_logging_', suffix='.sock') - os.close(fd) - # just need a name - file can't be present, or we'll get an - # 'address already in use' error. - os.remove(fn) - return fn @unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required") class UnixSocketHandlerTest(SocketHandlerTest): @@ -1784,13 +1867,12 @@ class UnixSocketHandlerTest(SocketHandlerTest): def setUp(self): # override the definition in the base class - self.address = _get_temp_domain_socket() + self.address = socket_helper.create_unix_domain_name() + self.addCleanup(os_helper.unlink, self.address) SocketHandlerTest.setUp(self) - def tearDown(self): - SocketHandlerTest.tearDown(self) - os_helper.unlink(self.address) - +@support.requires_working_socket() +@threading_helper.requires_working_threading() class DatagramHandlerTest(BaseTest): """Test for DatagramHandler.""" @@ -1865,13 +1947,12 @@ class UnixDatagramHandlerTest(DatagramHandlerTest): def setUp(self): # override the definition in the base class - self.address = _get_temp_domain_socket() + self.address = socket_helper.create_unix_domain_name() + self.addCleanup(os_helper.unlink, self.address) DatagramHandlerTest.setUp(self) - def tearDown(self): - DatagramHandlerTest.tearDown(self) - os_helper.unlink(self.address) - +@support.requires_working_socket() +@threading_helper.requires_working_threading() class SysLogHandlerTest(BaseTest): """Test for SysLogHandler using UDP.""" @@ -1900,7 +1981,7 @@ class SysLogHandlerTest(BaseTest): self.sl_hdlr = hcls((server.server_address[0], server.port)) else: self.sl_hdlr = hcls(server.server_address) - self.log_output = '' + self.log_output = b'' self.root_logger.removeHandler(self.root_logger.handlers[0]) self.root_logger.addHandler(self.sl_hdlr) self.handled = threading.Event() @@ -1957,13 +2038,10 @@ class UnixSysLogHandlerTest(SysLogHandlerTest): def setUp(self): # override the definition in the base class - self.address = _get_temp_domain_socket() + self.address = socket_helper.create_unix_domain_name() + self.addCleanup(os_helper.unlink, self.address) SysLogHandlerTest.setUp(self) - def tearDown(self): - SysLogHandlerTest.tearDown(self) - os_helper.unlink(self.address) - @unittest.skipUnless(socket_helper.IPV6_ENABLED, 'IPv6 support required for this test.') class IPv6SysLogHandlerTest(SysLogHandlerTest): @@ -1981,6 +2059,8 @@ class IPv6SysLogHandlerTest(SysLogHandlerTest): self.server_class.address_family = socket.AF_INET super(IPv6SysLogHandlerTest, self).tearDown() +@support.requires_working_socket() +@threading_helper.requires_working_threading() class HTTPHandlerTest(BaseTest): """Test for HTTPHandler.""" @@ -2114,8 +2194,7 @@ class EncodingTest(BaseTest): def test_encoding_plain_file(self): # In Python 2.x, a plain file object is treated as having no encoding. log = logging.getLogger("test") - fd, fn = tempfile.mkstemp(".log", "test_logging-1-") - os.close(fd) + fn = make_temp_file(".log", "test_logging-1-") # the non-ascii data we write to the log. data = "foo\x80" try: @@ -2212,6 +2291,21 @@ def handlerFunc(): class CustomHandler(logging.StreamHandler): pass +class CustomListener(logging.handlers.QueueListener): + pass + +class CustomQueue(queue.Queue): + pass + +def queueMaker(): + return queue.Queue() + +def listenerMaker(arg1, arg2, respect_handler_level=False): + def func(queue, *handlers, **kwargs): + kwargs.setdefault('respect_handler_level', respect_handler_level) + return CustomListener(queue, *handlers, **kwargs) + return func + class ConfigDictTest(BaseTest): """Reading logging config from a dictionary.""" @@ -2815,7 +2909,7 @@ class ConfigDictTest(BaseTest): }, } - out_of_order = { + bad_format = { "version": 1, "formatters": { "mySimpleFormatter": { @@ -2835,7 +2929,7 @@ class ConfigDictTest(BaseTest): "formatter": "mySimpleFormatter", "target": "fileGlobal", "level": "DEBUG" - } + } }, "loggers": { "mymodule": { @@ -2954,13 +3048,36 @@ class ConfigDictTest(BaseTest): } } + config_queue_handler = { + 'version': 1, + 'handlers' : { + 'h1' : { + 'class': 'logging.FileHandler', + }, + # key is before depended on handlers to test that deferred config works + 'ah' : { + 'class': 'logging.handlers.QueueHandler', + 'handlers': ['h1'] + }, + }, + "root": { + "level": "DEBUG", + "handlers": ["ah"] + } + } + def apply_config(self, conf): logging.config.dictConfig(conf) + def check_handler(self, name, cls): + h = logging.getHandlerByName(name) + self.assertIsInstance(h, cls) + def test_config0_ok(self): # A simple config which overrides the default settings. with support.captured_stdout() as output: self.apply_config(self.config0) + self.check_handler('hand1', logging.StreamHandler) logger = logging.getLogger() # Won't output anything logger.info(self.next_message()) @@ -3007,6 +3124,7 @@ class ConfigDictTest(BaseTest): # A config specifying a custom formatter class. with support.captured_stdout() as output: self.apply_config(self.config4) + self.check_handler('hand1', logging.StreamHandler) #logger = logging.getLogger() try: raise RuntimeError() @@ -3035,6 +3153,7 @@ class ConfigDictTest(BaseTest): def test_config5_ok(self): self.test_config1_ok(config=self.config5) + self.check_handler('hand1', CustomHandler) def test_config6_failure(self): self.assertRaises(Exception, self.apply_config, self.config6) @@ -3054,6 +3173,7 @@ class ConfigDictTest(BaseTest): self.assert_log_lines([]) with support.captured_stdout() as output: self.apply_config(self.config7) + self.check_handler('hand1', logging.StreamHandler) logger = logging.getLogger("compiler.parser") self.assertTrue(logger.disabled) logger = logging.getLogger("compiler.lexer") @@ -3083,6 +3203,7 @@ class ConfigDictTest(BaseTest): self.assert_log_lines([]) with support.captured_stdout() as output: self.apply_config(self.config8) + self.check_handler('hand1', logging.StreamHandler) logger = logging.getLogger("compiler.parser") self.assertFalse(logger.disabled) # Both will output a message @@ -3104,6 +3225,7 @@ class ConfigDictTest(BaseTest): def test_config_8a_ok(self): with support.captured_stdout() as output: self.apply_config(self.config1a) + self.check_handler('hand1', logging.StreamHandler) logger = logging.getLogger("compiler.parser") # See issue #11424. compiler-hyphenated sorts # between compiler and compiler.xyz and this @@ -3124,6 +3246,7 @@ class ConfigDictTest(BaseTest): self.assert_log_lines([]) with support.captured_stdout() as output: self.apply_config(self.config8a) + self.check_handler('hand1', logging.StreamHandler) logger = logging.getLogger("compiler.parser") self.assertFalse(logger.disabled) # Both will output a message @@ -3147,6 +3270,7 @@ class ConfigDictTest(BaseTest): def test_config_9_ok(self): with support.captured_stdout() as output: self.apply_config(self.config9) + self.check_handler('hand1', logging.StreamHandler) logger = logging.getLogger("compiler.parser") # Nothing will be output since both handler and logger are set to WARNING logger.info(self.next_message()) @@ -3165,6 +3289,7 @@ class ConfigDictTest(BaseTest): def test_config_10_ok(self): with support.captured_stdout() as output: self.apply_config(self.config10) + self.check_handler('hand1', logging.StreamHandler) logger = logging.getLogger("compiler.parser") logger.warning(self.next_message()) logger = logging.getLogger('compiler') @@ -3201,13 +3326,8 @@ class ConfigDictTest(BaseTest): def test_config15_ok(self): - def cleanup(h1, fn): - h1.close() - os.remove(fn) - with self.check_no_resource_warning(): - fd, fn = tempfile.mkstemp(".log", "test_logging-X-") - os.close(fd) + fn = make_temp_file(".log", "test_logging-X-") config = { "version": 1, @@ -3227,7 +3347,7 @@ class ConfigDictTest(BaseTest): self.apply_config(config) handler = logging.root.handlers[0] - self.addCleanup(cleanup, handler, fn) + self.addCleanup(closeFileHandler, handler, fn) def setup_via_listener(self, text, verify=None): text = text.encode("utf-8") @@ -3257,9 +3377,11 @@ class ConfigDictTest(BaseTest): logging.config.stopListening() threading_helper.join_thread(t) + @support.requires_working_socket() def test_listen_config_10_ok(self): with support.captured_stdout() as output: self.setup_via_listener(json.dumps(self.config10)) + self.check_handler('hand1', logging.StreamHandler) logger = logging.getLogger("compiler.parser") logger.warning(self.next_message()) logger = logging.getLogger('compiler') @@ -3276,6 +3398,7 @@ class ConfigDictTest(BaseTest): ('ERROR', '4'), ], stream=output) + @support.requires_working_socket() def test_listen_config_1_ok(self): with support.captured_stdout() as output: self.setup_via_listener(textwrap.dedent(ConfigFileTest.config1)) @@ -3290,6 +3413,7 @@ class ConfigDictTest(BaseTest): # Original logger output is empty. self.assert_log_lines([]) + @support.requires_working_socket() def test_listen_verify(self): def verify_fail(stuff): @@ -3352,11 +3476,11 @@ class ConfigDictTest(BaseTest): ('ERROR', '2'), ], pat=r"^[\w.]+ -> (\w+): (\d+)$") - def test_out_of_order(self): - self.assertRaises(ValueError, self.apply_config, self.out_of_order) + def test_bad_format(self): + self.assertRaises(ValueError, self.apply_config, self.bad_format) - def test_out_of_order_with_dollar_style(self): - config = copy.deepcopy(self.out_of_order) + def test_bad_format_with_dollar_style(self): + config = copy.deepcopy(self.bad_format) config['formatters']['mySimpleFormatter']['format'] = "${asctime} (${name}) ${levelname}: ${message}" self.apply_config(config) @@ -3364,6 +3488,8 @@ class ConfigDictTest(BaseTest): self.assertIsInstance(handler.target, logging.Handler) self.assertIsInstance(handler.formatter._style, logging.StringTemplateStyle) + self.assertEqual(sorted(logging.getHandlerNames()), + ['bufferGlobal', 'fileGlobal']) def test_custom_formatter_class_with_validate(self): self.apply_config(self.custom_formatter_class_validate) @@ -3379,7 +3505,7 @@ class ConfigDictTest(BaseTest): config = self.custom_formatter_class_validate.copy() config['formatters']['form1']['style'] = "$" - # Exception should not be raise as we have configured 'validate' to False + # Exception should not be raised as we have configured 'validate' to False self.apply_config(config) handler = logging.getLogger("my_test_logger_custom_formatter").handlers[0] self.assertIsInstance(handler.formatter, ExceptionFormatter) @@ -3443,6 +3569,142 @@ class ConfigDictTest(BaseTest): logging.info('some log') self.assertEqual(stderr.getvalue(), 'some log my_type\n') + def test_config_callable_filter_works(self): + def filter_(_): + return 1 + self.apply_config({ + "version": 1, "root": {"level": "DEBUG", "filters": [filter_]} + }) + assert logging.getLogger().filters[0] is filter_ + logging.getLogger().filters = [] + + def test_config_filter_works(self): + filter_ = logging.Filter("spam.eggs") + self.apply_config({ + "version": 1, "root": {"level": "DEBUG", "filters": [filter_]} + }) + assert logging.getLogger().filters[0] is filter_ + logging.getLogger().filters = [] + + def test_config_filter_method_works(self): + class FakeFilter: + def filter(self, _): + return 1 + filter_ = FakeFilter() + self.apply_config({ + "version": 1, "root": {"level": "DEBUG", "filters": [filter_]} + }) + assert logging.getLogger().filters[0] is filter_ + logging.getLogger().filters = [] + + def test_invalid_type_raises(self): + class NotAFilter: pass + for filter_ in [None, 1, NotAFilter()]: + self.assertRaises( + ValueError, + self.apply_config, + {"version": 1, "root": {"level": "DEBUG", "filters": [filter_]}} + ) + + def do_queuehandler_configuration(self, qspec, lspec): + cd = copy.deepcopy(self.config_queue_handler) + fn = make_temp_file('.log', 'test_logging-cqh-') + cd['handlers']['h1']['filename'] = fn + if qspec is not None: + cd['handlers']['ah']['queue'] = qspec + if lspec is not None: + cd['handlers']['ah']['listener'] = lspec + qh = None + try: + self.apply_config(cd) + qh = logging.getHandlerByName('ah') + self.assertEqual(sorted(logging.getHandlerNames()), ['ah', 'h1']) + self.assertIsNotNone(qh.listener) + qh.listener.start() + logging.debug('foo') + logging.info('bar') + logging.warning('baz') + + # Need to let the listener thread finish its work + while support.sleeping_retry(support.LONG_TIMEOUT, + "queue not empty"): + if qh.listener.queue.empty(): + break + + # wait until the handler completed its last task + qh.listener.queue.join() + + with open(fn, encoding='utf-8') as f: + data = f.read().splitlines() + self.assertEqual(data, ['foo', 'bar', 'baz']) + finally: + if qh: + qh.listener.stop() + h = logging.getHandlerByName('h1') + if h: + self.addCleanup(closeFileHandler, h, fn) + else: + self.addCleanup(os.remove, fn) + + @threading_helper.requires_working_threading() + def test_config_queue_handler(self): + q = CustomQueue() + dq = { + '()': __name__ + '.CustomQueue', + 'maxsize': 10 + } + dl = { + '()': __name__ + '.listenerMaker', + 'arg1': None, + 'arg2': None, + 'respect_handler_level': True + } + qvalues = (None, __name__ + '.queueMaker', __name__ + '.CustomQueue', dq, q) + lvalues = (None, __name__ + '.CustomListener', dl, CustomListener) + for qspec, lspec in itertools.product(qvalues, lvalues): + self.do_queuehandler_configuration(qspec, lspec) + + # Some failure cases + qvalues = (None, 4, int, '', 'foo') + lvalues = (None, 4, int, '', 'bar') + for qspec, lspec in itertools.product(qvalues, lvalues): + if lspec is None and qspec is None: + continue + with self.assertRaises(ValueError) as ctx: + self.do_queuehandler_configuration(qspec, lspec) + msg = str(ctx.exception) + self.assertEqual(msg, "Unable to configure handler 'ah'") + + def test_90195(self): + # See gh-90195 + config = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + }, + }, + 'loggers': { + 'a': { + 'level': 'DEBUG', + 'handlers': ['console'] + } + } + } + logger = logging.getLogger('a') + self.assertFalse(logger.disabled) + self.apply_config(config) + self.assertFalse(logger.disabled) + # Should disable all loggers ... + self.apply_config({'version': 1}) + self.assertTrue(logger.disabled) + del config['disable_existing_loggers'] + self.apply_config(config) + # Logger should be enabled, since explicitly mentioned + self.assertFalse(logger.disabled) + class ManagerTest(BaseTest): def test_manager_loggerclass(self): logged = [] @@ -3482,6 +3744,20 @@ class ChildLoggerTest(BaseTest): self.assertIs(c2, logging.getLogger('abc.def.ghi')) self.assertIs(c2, c3) + def test_get_children(self): + r = logging.getLogger() + l1 = logging.getLogger('foo') + l2 = logging.getLogger('foo.bar') + l3 = logging.getLogger('foo.bar.baz.bozz') + l4 = logging.getLogger('bar') + kids = r.getChildren() + expected = {l1, l4} + self.assertEqual(expected, kids & expected) # might be other kids for root + self.assertNotIn(l2, expected) + kids = l1.getChildren() + self.assertEqual({l2}, kids) + kids = l2.getChildren() + self.assertEqual(set(), kids) class DerivedLogRecord(logging.LogRecord): pass @@ -3521,6 +3797,7 @@ class LogRecordFactoryTest(BaseTest): ]) +@threading_helper.requires_working_threading() class QueueHandlerTest(BaseTest): # Do not bother with a logger name group. expected_log_pat = r"^[\w.]+ -> (\w+): (\d+)$" @@ -3602,7 +3879,7 @@ class QueueHandlerTest(BaseTest): @unittest.skipUnless(hasattr(logging.handlers, 'QueueListener'), 'logging.handlers.QueueListener required for this test') def test_queue_listener_with_StreamHandler(self): - # Test that traceback only appends once (bpo-34334). + # Test that traceback and stack-info only appends once (bpo-34334, bpo-46755). listener = logging.handlers.QueueListener(self.queue, self.root_hdlr) listener.start() try: @@ -3610,8 +3887,10 @@ class QueueHandlerTest(BaseTest): except ZeroDivisionError as e: exc = e self.que_logger.exception(self.next_message(), exc_info=exc) + self.que_logger.error(self.next_message(), stack_info=True) listener.stop() self.assertEqual(self.stream.getvalue().strip().count('Traceback'), 1) + self.assertEqual(self.stream.getvalue().strip().count('Stack'), 1) @unittest.skipUnless(hasattr(logging.handlers, 'QueueListener'), 'logging.handlers.QueueListener required for this test') @@ -3630,6 +3909,7 @@ if hasattr(logging.handlers, 'QueueListener'): import multiprocessing from unittest.mock import patch + @threading_helper.requires_working_threading() class QueueListenerTest(BaseTest): """ Tests based on patch submitted for issue #27930. Ensure that @@ -4022,6 +4302,14 @@ class FormatterTest(unittest.TestCase, AssertErrorMessage): f.converter = time.gmtime self.assertEqual(f.formatTime(r), '21/04/1993 08:03:00') + def test_issue_89047(self): + f = logging.Formatter(fmt='{asctime}.{msecs:03.0f} {message}', style='{', datefmt="%Y-%m-%d %H:%M:%S") + for i in range(2500): + time.sleep(0.0004) + r = logging.makeLogRecord({'msg': 'Message %d' % (i + 1)}) + s = f.format(r) + self.assertNotIn('.1000', s) + class TestBufferingFormatter(logging.BufferingFormatter): def formatHeader(self, records): @@ -4451,6 +4739,7 @@ class LogRecordTest(BaseTest): return results def test_multiprocessing(self): + support.skip_if_broken_multiprocessing_synchronize() multiprocessing_imported = 'multiprocessing' in sys.modules try: # logMultiprocessing is True by default @@ -4487,29 +4776,65 @@ class LogRecordTest(BaseTest): import multiprocessing def test_optional(self): - r = logging.makeLogRecord({}) + NONE = self.assertIsNone NOT_NONE = self.assertIsNotNone + + r = logging.makeLogRecord({}) NOT_NONE(r.thread) NOT_NONE(r.threadName) NOT_NONE(r.process) NOT_NONE(r.processName) + NONE(r.taskName) log_threads = logging.logThreads log_processes = logging.logProcesses log_multiprocessing = logging.logMultiprocessing + log_asyncio_tasks = logging.logAsyncioTasks try: logging.logThreads = False logging.logProcesses = False logging.logMultiprocessing = False + logging.logAsyncioTasks = False r = logging.makeLogRecord({}) - NONE = self.assertIsNone + NONE(r.thread) NONE(r.threadName) NONE(r.process) NONE(r.processName) + NONE(r.taskName) finally: logging.logThreads = log_threads logging.logProcesses = log_processes logging.logMultiprocessing = log_multiprocessing + logging.logAsyncioTasks = log_asyncio_tasks + + async def _make_record_async(self, assertion): + r = logging.makeLogRecord({}) + assertion(r.taskName) + + @support.requires_working_socket() + def test_taskName_with_asyncio_imported(self): + try: + make_record = self._make_record_async + with asyncio.Runner() as runner: + logging.logAsyncioTasks = True + runner.run(make_record(self.assertIsNotNone)) + logging.logAsyncioTasks = False + runner.run(make_record(self.assertIsNone)) + finally: + asyncio.set_event_loop_policy(None) + + @support.requires_working_socket() + def test_taskName_without_asyncio_imported(self): + try: + make_record = self._make_record_async + with asyncio.Runner() as runner, support.swap_item(sys.modules, 'asyncio', None): + logging.logAsyncioTasks = True + runner.run(make_record(self.assertIsNone)) + logging.logAsyncioTasks = False + runner.run(make_record(self.assertIsNone)) + finally: + asyncio.set_event_loop_policy(None) + class BasicConfigTest(unittest.TestCase): @@ -4788,6 +5113,35 @@ class BasicConfigTest(unittest.TestCase): # didn't write anything due to the encoding error self.assertEqual(data, r'') + @support.requires_working_socket() + def test_log_taskName(self): + async def log_record(): + logging.warning('hello world') + + handler = None + log_filename = make_temp_file('.log', 'test-logging-taskname-') + self.addCleanup(os.remove, log_filename) + try: + encoding = 'utf-8' + logging.basicConfig(filename=log_filename, errors='strict', + encoding=encoding, level=logging.WARNING, + format='%(taskName)s - %(message)s') + + self.assertEqual(len(logging.root.handlers), 1) + handler = logging.root.handlers[0] + self.assertIsInstance(handler, logging.FileHandler) + + with asyncio.Runner(debug=True) as runner: + logging.logAsyncioTasks = True + runner.run(log_record()) + with open(log_filename, encoding='utf-8') as f: + data = f.read().strip() + self.assertRegex(data, r'Task-\d+ - hello world') + finally: + asyncio.set_event_loop_policy(None) + if handler: + handler.close() + def _test_log(self, method, level=None): # logging.root has no handlers so basicConfig should be called @@ -4995,9 +5349,10 @@ class LoggerTest(BaseTest, AssertErrorMessage): def test_find_caller_with_stacklevel(self): the_level = 1 + trigger = self.logger.warning def innermost(): - self.logger.warning('test', stacklevel=the_level) + trigger('test', stacklevel=the_level) def inner(): innermost() @@ -5019,6 +5374,13 @@ class LoggerTest(BaseTest, AssertErrorMessage): self.assertEqual(records[-1].funcName, 'outer') self.assertGreater(records[-1].lineno, lineno) lineno = records[-1].lineno + root_logger = logging.getLogger() + root_logger.addHandler(self.recording) + trigger = logging.warning + outer() + self.assertEqual(records[-1].funcName, 'outer') + root_logger.removeHandler(self.recording) + trigger = self.logger.warning the_level += 1 outer() self.assertEqual(records[-1].funcName, 'test_find_caller_with_stacklevel') @@ -5163,8 +5525,7 @@ class BaseFileTest(BaseTest): def setUp(self): BaseTest.setUp(self) - fd, self.fn = tempfile.mkstemp(".log", "test_logging-2-") - os.close(fd) + self.fn = make_temp_file(".log", "test_logging-2-") self.rmfiles = [] def tearDown(self): @@ -5207,6 +5568,7 @@ class FileHandlerTest(BaseFileTest): self.assertEqual(fp.read().strip(), '1') class RotatingFileHandlerTest(BaseFileTest): + @unittest.skipIf(support.is_wasi, "WASI does not have /dev/null.") def test_should_not_rollover(self): # If maxbytes is zero rollover never occurs rh = logging.handlers.RotatingFileHandler( @@ -5314,6 +5676,7 @@ class RotatingFileHandlerTest(BaseFileTest): rh.close() class TimedRotatingFileHandlerTest(BaseFileTest): + @unittest.skipIf(support.is_wasi, "WASI does not have /dev/null.") def test_should_not_rollover(self): # See bpo-45401. Should only ever rollover regular files fh = logging.handlers.TimedRotatingFileHandler( @@ -5431,6 +5794,54 @@ class TimedRotatingFileHandlerTest(BaseFileTest): finally: rh.close() + def test_compute_files_to_delete(self): + # See bpo-46063 for background + wd = tempfile.mkdtemp(prefix='test_logging_') + self.addCleanup(shutil.rmtree, wd) + times = [] + dt = datetime.datetime.now() + for i in range(10): + times.append(dt.strftime('%Y-%m-%d_%H-%M-%S')) + dt += datetime.timedelta(seconds=5) + prefixes = ('a.b', 'a.b.c', 'd.e', 'd.e.f') + files = [] + rotators = [] + for prefix in prefixes: + p = os.path.join(wd, '%s.log' % prefix) + rotator = logging.handlers.TimedRotatingFileHandler(p, when='s', + interval=5, + backupCount=7, + delay=True) + rotators.append(rotator) + if prefix.startswith('a.b'): + for t in times: + files.append('%s.log.%s' % (prefix, t)) + else: + rotator.namer = lambda name: name.replace('.log', '') + '.log' + for t in times: + files.append('%s.%s.log' % (prefix, t)) + # Create empty files + for fn in files: + p = os.path.join(wd, fn) + with open(p, 'wb') as f: + pass + # Now the checks that only the correct files are offered up for deletion + for i, prefix in enumerate(prefixes): + rotator = rotators[i] + candidates = rotator.getFilesToDelete() + self.assertEqual(len(candidates), 3) + if prefix.startswith('a.b'): + p = '%s.log.' % prefix + for c in candidates: + d, fn = os.path.split(c) + self.assertTrue(fn.startswith(p)) + else: + for c in candidates: + d, fn = os.path.split(c) + self.assertTrue(fn.endswith('.log')) + self.assertTrue(fn.startswith(prefix + '.') and + fn[len(prefix) + 2].isdigit()) + def secs(**kw): return datetime.timedelta(**kw) // datetime.timedelta(seconds=1) @@ -5472,8 +5883,8 @@ for when, exp in (('S', 1), print('currentSecond: %s' % currentSecond, file=sys.stderr) print('r: %s' % r, file=sys.stderr) print('result: %s' % result, file=sys.stderr) - except Exception: - print('exception in diagnostic code: %s' % sys.exc_info()[1], file=sys.stderr) + except Exception as e: + print('exception in diagnostic code: %s' % e, file=sys.stderr) self.assertEqual(exp, actual) rh.close() setattr(TimedRotatingFileHandlerTest, "test_compute_rollover_%s" % when, test_compute_rollover) @@ -5521,7 +5932,7 @@ class MiscTestCase(unittest.TestCase): 'logThreads', 'logMultiprocessing', 'logProcesses', 'currentframe', 'PercentStyle', 'StrFormatStyle', 'StringTemplateStyle', 'Filterer', 'PlaceHolder', 'Manager', 'RootLogger', 'root', - 'threading'} + 'threading', 'logAsyncioTasks'} support.check__all__(self, logging, not_exported=not_exported) @@ -5529,9 +5940,7 @@ class MiscTestCase(unittest.TestCase): # why the test does this, but in any case we save the current locale # first and restore it at the end. def setUpModule(): - cm = support.run_with_locale('LC_ALL', '') - cm.__enter__() - unittest.addModuleCleanup(cm.__exit__, None, None, None) + unittest.enterModuleContext(support.run_with_locale('LC_ALL', '')) if __name__ == "__main__": diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py index e5c4d7fc422..569ab15820e 100644 --- a/Lib/test/test_long.py +++ b/Lib/test/test_long.py @@ -392,7 +392,8 @@ class LongTest(unittest.TestCase): return 42 def __trunc__(self): return 1729 - self.assertEqual(int(LongTrunc()), 1729) + with self.assertWarns(DeprecationWarning): + self.assertEqual(int(LongTrunc()), 1729) def check_float_conversion(self, n): # Check that int -> float conversion behaviour matches @@ -946,8 +947,13 @@ class LongTest(unittest.TestCase): self.assertEqual(1 << (sys.maxsize + 1000), 1 << 1000 << sys.maxsize) def test_huge_rshift(self): - self.assertEqual(42 >> (1 << 1000), 0) - self.assertEqual((-42) >> (1 << 1000), -1) + huge_shift = 1 << 1000 + self.assertEqual(42 >> huge_shift, 0) + self.assertEqual((-42) >> huge_shift, -1) + self.assertEqual(1123 >> huge_shift, 0) + self.assertEqual((-1123) >> huge_shift, -1) + self.assertEqual(2**128 >> huge_shift, 0) + self.assertEqual(-2**128 >> huge_shift, -1) @support.cpython_only @support.bigmemtest(sys.maxsize + 500, memuse=2/15, dry_run=False) @@ -956,6 +962,64 @@ class LongTest(unittest.TestCase): self.assertEqual(huge >> (sys.maxsize + 1), (1 << 499) + 5) self.assertEqual(huge >> (sys.maxsize + 1000), 0) + def test_small_rshift(self): + self.assertEqual(42 >> 1, 21) + self.assertEqual((-42) >> 1, -21) + self.assertEqual(43 >> 1, 21) + self.assertEqual((-43) >> 1, -22) + + self.assertEqual(1122 >> 1, 561) + self.assertEqual((-1122) >> 1, -561) + self.assertEqual(1123 >> 1, 561) + self.assertEqual((-1123) >> 1, -562) + + self.assertEqual(2**128 >> 1, 2**127) + self.assertEqual(-2**128 >> 1, -2**127) + self.assertEqual((2**128 + 1) >> 1, 2**127) + self.assertEqual(-(2**128 + 1) >> 1, -2**127 - 1) + + def test_medium_rshift(self): + self.assertEqual(42 >> 9, 0) + self.assertEqual((-42) >> 9, -1) + self.assertEqual(1122 >> 9, 2) + self.assertEqual((-1122) >> 9, -3) + self.assertEqual(2**128 >> 9, 2**119) + self.assertEqual(-2**128 >> 9, -2**119) + # Exercise corner case of the current algorithm, where the result of + # shifting a two-limb int by the limb size still has two limbs. + self.assertEqual((1 - BASE*BASE) >> SHIFT, -BASE) + self.assertEqual((BASE - 1 - BASE*BASE) >> SHIFT, -BASE) + + def test_big_rshift(self): + self.assertEqual(42 >> 32, 0) + self.assertEqual((-42) >> 32, -1) + self.assertEqual(1122 >> 32, 0) + self.assertEqual((-1122) >> 32, -1) + self.assertEqual(2**128 >> 32, 2**96) + self.assertEqual(-2**128 >> 32, -2**96) + + def test_small_lshift(self): + self.assertEqual(42 << 1, 84) + self.assertEqual((-42) << 1, -84) + self.assertEqual(561 << 1, 1122) + self.assertEqual((-561) << 1, -1122) + self.assertEqual(2**127 << 1, 2**128) + self.assertEqual(-2**127 << 1, -2**128) + + def test_medium_lshift(self): + self.assertEqual(42 << 9, 21504) + self.assertEqual((-42) << 9, -21504) + self.assertEqual(1122 << 9, 574464) + self.assertEqual((-1122) << 9, -574464) + + def test_big_lshift(self): + self.assertEqual(42 << 32, 42 * 2**32) + self.assertEqual((-42) << 32, -42 * 2**32) + self.assertEqual(1122 << 32, 1122 * 2**32) + self.assertEqual((-1122) << 32, -1122 * 2**32) + self.assertEqual(2**128 << 32, 2**160) + self.assertEqual(-2**128 << 32, -2**160) + @support.cpython_only def test_small_ints_in_huge_calculation(self): a = 2 ** 100 @@ -964,6 +1028,48 @@ class LongTest(unittest.TestCase): self.assertIs(a + b, 1) self.assertIs(c - a, 1) + @support.cpython_only + def test_pow_uses_cached_small_ints(self): + self.assertIs(pow(10, 3, 998), 2) + self.assertIs(10 ** 3 % 998, 2) + a, p, m = 10, 3, 998 + self.assertIs(a ** p % m, 2) + + self.assertIs(pow(2, 31, 2 ** 31 - 1), 1) + self.assertIs(2 ** 31 % (2 ** 31 - 1), 1) + a, p, m = 2, 31, 2 ** 31 - 1 + self.assertIs(a ** p % m, 1) + + self.assertIs(pow(2, 100, 2**100 - 3), 3) + self.assertIs(2 ** 100 % (2 ** 100 - 3), 3) + a, p, m = 2, 100, 2**100 - 3 + self.assertIs(a ** p % m, 3) + + @support.cpython_only + def test_divmod_uses_cached_small_ints(self): + big = 10 ** 100 + + self.assertIs((big + 1) % big, 1) + self.assertIs((big + 1) // big, 1) + self.assertIs(big // (big // 2), 2) + self.assertIs(big // (big // -4), -4) + + q, r = divmod(2 * big + 3, big) + self.assertIs(q, 2) + self.assertIs(r, 3) + + q, r = divmod(-4 * big + 100, big) + self.assertIs(q, -4) + self.assertIs(r, 100) + + q, r = divmod(3 * (-big) - 1, -big) + self.assertIs(q, 3) + self.assertIs(r, -1) + + q, r = divmod(3 * big - 1, -big) + self.assertIs(q, -3) + self.assertIs(r, -1) + def test_small_ints(self): for i in range(-5, 257): self.assertIs(i, i + 0) @@ -1228,6 +1334,12 @@ class LongTest(unittest.TestCase): b'\xff\xff\xff\xff\xff') self.assertRaises(OverflowError, (1).to_bytes, 0, 'big') + # gh-98783 + class SubStr(str): + pass + self.assertEqual((0).to_bytes(1, SubStr('big')), b'\x00') + self.assertEqual((0).to_bytes(0, SubStr('little')), b'') + def test_from_bytes(self): def check(tests, byteorder, signed=False): def equivalent_python(byte_array, byteorder, signed=False): @@ -1412,6 +1524,40 @@ class LongTest(unittest.TestCase): self.assertEqual(i, 1) self.assertEqual(getattr(i, 'foo', 'none'), 'bar') + class ValidBytes: + def __bytes__(self): + return b'\x01' + class InvalidBytes: + def __bytes__(self): + return 'abc' + class MissingBytes: ... + class RaisingBytes: + def __bytes__(self): + 1 / 0 + + self.assertEqual(int.from_bytes(ValidBytes()), 1) + self.assertRaises(TypeError, int.from_bytes, InvalidBytes()) + self.assertRaises(TypeError, int.from_bytes, MissingBytes()) + self.assertRaises(ZeroDivisionError, int.from_bytes, RaisingBytes()) + + # gh-98783 + class SubStr(str): + pass + self.assertEqual(int.from_bytes(b'', SubStr('big')), 0) + self.assertEqual(int.from_bytes(b'\x00', SubStr('little')), 0) + + @support.cpython_only + def test_from_bytes_small(self): + # bpo-46361 + for i in range(-5, 257): + b = i.to_bytes(2, signed=True) + self.assertIs(int.from_bytes(b, signed=True), i) + + def test_is_integer(self): + self.assertTrue((-1).is_integer()) + self.assertTrue((0).is_integer()) + self.assertTrue((1).is_integer()) + def test_access_to_nonexistent_digit_0(self): # http://bugs.python.org/issue14630: A bug in _PyLong_Copy meant that # ob_digit[0] was being incorrectly accessed for instances of a @@ -1443,6 +1589,17 @@ class LongTest(unittest.TestCase): self.assertEqual(type(numerator), int) self.assertEqual(type(denominator), int) + def test_square(self): + # Multiplication makes a special case of multiplying an int with + # itself, using a special, faster algorithm. This test is mostly + # to ensure that no asserts in the implementation trigger, in + # cases with a maximal amount of carries. + for bitlen in range(1, 400): + n = (1 << bitlen) - 1 # solid string of 1 bits + with self.subTest(bitlen=bitlen, n=n): + # (2**i - 1)**2 = 2**(2*i) - 2*2**i + 1 + self.assertEqual(n**2, + (1 << (2 * bitlen)) - (1 << (bitlen + 1)) + 1) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_lzma.py b/Lib/test/test_lzma.py index 145c8cfced4..18f474ba2a8 100644 --- a/Lib/test/test_lzma.py +++ b/Lib/test/test_lzma.py @@ -825,10 +825,7 @@ class FileTestCase(unittest.TestCase): def test_read_10(self): with LZMAFile(BytesIO(COMPRESSED_XZ)) as f: chunks = [] - while True: - result = f.read(10) - if not result: - break + while result := f.read(10): self.assertLessEqual(len(result), 10) chunks.append(result) self.assertEqual(b"".join(chunks), INPUT) @@ -911,10 +908,7 @@ class FileTestCase(unittest.TestCase): def test_read1(self): with LZMAFile(BytesIO(COMPRESSED_XZ)) as f: blocks = [] - while True: - result = f.read1() - if not result: - break + while result := f.read1(): blocks.append(result) self.assertEqual(b"".join(blocks), INPUT) self.assertEqual(f.read1(), b"") @@ -926,10 +920,7 @@ class FileTestCase(unittest.TestCase): def test_read1_10(self): with LZMAFile(BytesIO(COMPRESSED_XZ)) as f: blocks = [] - while True: - result = f.read1(10) - if not result: - break + while result := f.read1(10): blocks.append(result) self.assertEqual(b"".join(blocks), INPUT) self.assertEqual(f.read1(), b"") @@ -937,10 +928,7 @@ class FileTestCase(unittest.TestCase): def test_read1_multistream(self): with LZMAFile(BytesIO(COMPRESSED_XZ * 5)) as f: blocks = [] - while True: - result = f.read1() - if not result: - break + while result := f.read1(): blocks.append(result) self.assertEqual(b"".join(blocks), INPUT * 5) self.assertEqual(f.read1(), b"") diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py index 604fc4525f5..07c2764dfd1 100644 --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -10,12 +10,17 @@ import io import tempfile from test import support from test.support import os_helper +from test.support import socket_helper import unittest import textwrap import mailbox import glob +if not socket_helper.has_gethostname: + raise unittest.SkipTest("test requires gethostname()") + + class TestBase: all_mailbox_types = (mailbox.Message, mailbox.MaildirMessage, @@ -1061,7 +1066,7 @@ class _TestMboxMMDF(_TestSingleFile): self.assertEqual(contents, f.read()) self._box = self._factory(self._path) - @unittest.skipUnless(hasattr(os, 'fork'), "Test needs fork().") + @support.requires_fork() @unittest.skipUnless(hasattr(socket, 'socketpair'), "Test needs socketpair().") def test_lock_conflict(self): # Fork off a child process that will lock the mailbox temporarily, diff --git a/Lib/test/test_mailcap.py b/Lib/test/test_mailcap.py index ef9cad498a7..819dc80a266 100644 --- a/Lib/test/test_mailcap.py +++ b/Lib/test/test_mailcap.py @@ -1,10 +1,14 @@ -import mailcap -import os import copy -import test.support -from test.support import os_helper -import unittest +import os import sys +import test.support +import unittest +from test.support import os_helper +from test.support import warnings_helper + + +mailcap = warnings_helper.import_deprecated('mailcap') + # Location of mailcap file MAILCAPFILE = test.support.findfile("mailcap.txt") @@ -123,7 +127,8 @@ class HelperFunctionTest(unittest.TestCase): (["", "audio/*", "foo.txt"], ""), (["echo foo", "audio/*", "foo.txt"], "echo foo"), (["echo %s", "audio/*", "foo.txt"], "echo foo.txt"), - (["echo %t", "audio/*", "foo.txt"], "echo audio/*"), + (["echo %t", "audio/*", "foo.txt"], None), + (["echo %t", "audio/wav", "foo.txt"], "echo audio/wav"), (["echo \\%t", "audio/*", "foo.txt"], "echo %t"), (["echo foo", "audio/*", "foo.txt", plist], "echo foo"), (["echo %{total}", "audio/*", "foo.txt", plist], "echo 3") @@ -207,7 +212,10 @@ class FindmatchTest(unittest.TestCase): ('"An audio fragment"', audio_basic_entry)), ([c, "audio/*"], {"filename": fname}, - ("/usr/local/bin/showaudio audio/*", audio_entry)), + (None, None)), + ([c, "audio/wav"], + {"filename": fname}, + ("/usr/local/bin/showaudio audio/wav", audio_entry)), ([c, "message/external-body"], {"plist": plist}, ("showexternal /dev/null default john python.org /tmp foo bar", message_entry)) @@ -216,6 +224,10 @@ class FindmatchTest(unittest.TestCase): @unittest.skipUnless(os.name == "posix", "Requires 'test' command on system") @unittest.skipIf(sys.platform == "vxworks", "'test' command is not supported on VxWorks") + @unittest.skipUnless( + test.support.has_subprocess_support, + "'test' command needs process support." + ) def test_test(self): # findmatch() will automatically check any "test" conditions and skip # the entry if the check fails. diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py index 8d55382b195..3d9d6d5d0ac 100644 --- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -117,7 +117,8 @@ class CodeTestCase(unittest.TestCase): def test_many_codeobjects(self): # Issue2957: bad recursion count on code objects - count = 5000 # more than MAX_MARSHAL_STACK_DEPTH + # more than MAX_MARSHAL_STACK_DEPTH + count = support.EXCEEDS_RECURSION_LIMIT codes = (ExceptionTestCase.test_exceptions.__code__,) * count marshal.loads(marshal.dumps(codes)) @@ -129,18 +130,18 @@ class CodeTestCase(unittest.TestCase): self.assertEqual(co2.co_filename, "f2") @requires_debug_ranges() - def test_no_columntable_and_endlinetable_with_no_debug_ranges(self): + def test_minimal_linetable_with_no_debug_ranges(self): # Make sure when demarshalling objects with `-X no_debug_ranges` - # that the columntable and endlinetable are None. + # that the columns are None. co = ExceptionTestCase.test_exceptions.__code__ code = textwrap.dedent(""" import sys import marshal with open(sys.argv[1], 'rb') as f: co = marshal.load(f) - - assert co.co_endlinetable is None - assert co.co_columntable is None + positions = list(co.co_positions()) + assert positions[0][2] is None + assert positions[0][3] is None """) try: @@ -256,9 +257,11 @@ class BugsTestCase(unittest.TestCase): # The max stack depth should match the value in Python/marshal.c. # BUG: https://bugs.python.org/issue33720 # Windows always limits the maximum depth on release and debug builds - #if os.name == 'nt' and hasattr(sys, 'gettotalrefcount'): + #if os.name == 'nt' and support.Py_DEBUG: if os.name == 'nt': MAX_MARSHAL_STACK_DEPTH = 1000 + elif sys.platform == 'wasi': + MAX_MARSHAL_STACK_DEPTH = 1500 else: MAX_MARSHAL_STACK_DEPTH = 2000 for i in range(MAX_MARSHAL_STACK_DEPTH - 2): @@ -352,7 +355,7 @@ class BugsTestCase(unittest.TestCase): for elements in ( "float('nan'), b'a', b'b', b'c', 'x', 'y', 'z'", # Also test for bad interactions with backreferencing: - "('Spam', 0), ('Spam', 1), ('Spam', 2)", + "('Spam', 0), ('Spam', 1), ('Spam', 2), ('Spam', 3), ('Spam', 4), ('Spam', 5)", ): s = f"{kind}([{elements}])" with self.subTest(s): diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index a9f1b1e11bc..2c84e55ab45 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -4,6 +4,7 @@ from test.support import verbose, requires_IEEE_754 from test import support import unittest +import fractions import itertools import decimal import math @@ -501,6 +502,17 @@ class MathTests(unittest.TestCase): self.assertTrue(math.isnan(math.exp(NAN))) self.assertRaises(OverflowError, math.exp, 1000000) + def testExp2(self): + self.assertRaises(TypeError, math.exp2) + self.ftest('exp2(-1)', math.exp2(-1), 0.5) + self.ftest('exp2(0)', math.exp2(0), 1) + self.ftest('exp2(1)', math.exp2(1), 2) + self.ftest('exp2(2.3)', math.exp2(2.3), 4.924577653379665) + self.assertEqual(math.exp2(INF), INF) + self.assertEqual(math.exp2(NINF), 0.) + self.assertTrue(math.isnan(math.exp2(NAN))) + self.assertRaises(OverflowError, math.exp2, 1000000) + def testFabs(self): self.assertRaises(TypeError, math.fabs) self.ftest('fabs(-1)', math.fabs(-1), 1) @@ -995,6 +1007,11 @@ class MathTests(unittest.TestCase): self.assertEqual(math.dist(p, q), 5*scale) self.assertEqual(math.dist(q, p), 5*scale) + def test_math_dist_leak(self): + # gh-98897: Check for error handling does not leak memory + with self.assertRaises(ValueError): + math.dist([1, 2], [3, 4, 5]) + def testIsqrt(self): # Test a variety of inputs, large and small. test_values = ( @@ -1129,6 +1146,7 @@ class MathTests(unittest.TestCase): self.ftest('log(1/e)', math.log(1/math.e), -1) self.ftest('log(1)', math.log(1), 0) self.ftest('log(e)', math.log(math.e), 1) + self.ftest('log(e, None)', math.log(math.e, None), 1) self.ftest('log(32,2)', math.log(32,2), 5) self.ftest('log(10**40, 10)', math.log(10**40, 10), 40) self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2) @@ -1186,6 +1204,255 @@ class MathTests(unittest.TestCase): self.assertEqual(math.log(INF), INF) self.assertTrue(math.isnan(math.log10(NAN))) + def testSumProd(self): + sumprod = math.sumprod + Decimal = decimal.Decimal + Fraction = fractions.Fraction + + # Core functionality + self.assertEqual(sumprod(iter([10, 20, 30]), (1, 2, 3)), 140) + self.assertEqual(sumprod([1.5, 2.5], [3.5, 4.5]), 16.5) + self.assertEqual(sumprod([], []), 0) + + # Type preservation and coercion + for v in [ + (10, 20, 30), + (1.5, -2.5), + (Fraction(3, 5), Fraction(4, 5)), + (Decimal(3.5), Decimal(4.5)), + (2.5, 10), # float/int + (2.5, Fraction(3, 5)), # float/fraction + (25, Fraction(3, 5)), # int/fraction + (25, Decimal(4.5)), # int/decimal + ]: + for p, q in [(v, v), (v, v[::-1])]: + with self.subTest(p=p, q=q): + expected = sum(p_i * q_i for p_i, q_i in zip(p, q, strict=True)) + actual = sumprod(p, q) + self.assertEqual(expected, actual) + self.assertEqual(type(expected), type(actual)) + + # Bad arguments + self.assertRaises(TypeError, sumprod) # No args + self.assertRaises(TypeError, sumprod, []) # One arg + self.assertRaises(TypeError, sumprod, [], [], []) # Three args + self.assertRaises(TypeError, sumprod, None, [10]) # Non-iterable + self.assertRaises(TypeError, sumprod, [10], None) # Non-iterable + + # Uneven lengths + self.assertRaises(ValueError, sumprod, [10, 20], [30]) + self.assertRaises(ValueError, sumprod, [10], [20, 30]) + + # Error in iterator + def raise_after(n): + for i in range(n): + yield i + raise RuntimeError + with self.assertRaises(RuntimeError): + sumprod(range(10), raise_after(5)) + with self.assertRaises(RuntimeError): + sumprod(raise_after(5), range(10)) + + # Error in multiplication + class BadMultiply: + def __mul__(self, other): + raise RuntimeError + def __rmul__(self, other): + raise RuntimeError + with self.assertRaises(RuntimeError): + sumprod([10, BadMultiply(), 30], [1, 2, 3]) + with self.assertRaises(RuntimeError): + sumprod([1, 2, 3], [10, BadMultiply(), 30]) + + # Error in addition + with self.assertRaises(TypeError): + sumprod(['abc', 3], [5, 10]) + with self.assertRaises(TypeError): + sumprod([5, 10], ['abc', 3]) + + # Special values should give the same as the pure python recipe + self.assertEqual(sumprod([10.1, math.inf], [20.2, 30.3]), math.inf) + self.assertEqual(sumprod([10.1, math.inf], [math.inf, 30.3]), math.inf) + self.assertEqual(sumprod([10.1, math.inf], [math.inf, math.inf]), math.inf) + self.assertEqual(sumprod([10.1, -math.inf], [20.2, 30.3]), -math.inf) + self.assertTrue(math.isnan(sumprod([10.1, math.inf], [-math.inf, math.inf]))) + self.assertTrue(math.isnan(sumprod([10.1, math.nan], [20.2, 30.3]))) + self.assertTrue(math.isnan(sumprod([10.1, math.inf], [math.nan, 30.3]))) + self.assertTrue(math.isnan(sumprod([10.1, math.inf], [20.3, math.nan]))) + + # Error cases that arose during development + args = ((-5, -5, 10), (1.5, 4611686018427387904, 2305843009213693952)) + self.assertEqual(sumprod(*args), 0.0) + + + @requires_IEEE_754 + @unittest.skipIf(HAVE_DOUBLE_ROUNDING, + "sumprod() accuracy not guaranteed on machines with double rounding") + @support.cpython_only # Other implementations may choose a different algorithm + def test_sumprod_accuracy(self): + sumprod = math.sumprod + self.assertEqual(sumprod([0.1] * 10, [1]*10), 1.0) + self.assertEqual(sumprod([0.1] * 20, [True, False] * 10), 1.0) + self.assertEqual(sumprod([1.0, 10E100, 1.0, -10E100], [1.0]*4), 2.0) + + @support.requires_resource('cpu') + def test_sumprod_stress(self): + sumprod = math.sumprod + product = itertools.product + Decimal = decimal.Decimal + Fraction = fractions.Fraction + + class Int(int): + def __add__(self, other): + return Int(int(self) + int(other)) + def __mul__(self, other): + return Int(int(self) * int(other)) + __radd__ = __add__ + __rmul__ = __mul__ + def __repr__(self): + return f'Int({int(self)})' + + class Flt(float): + def __add__(self, other): + return Int(int(self) + int(other)) + def __mul__(self, other): + return Int(int(self) * int(other)) + __radd__ = __add__ + __rmul__ = __mul__ + def __repr__(self): + return f'Flt({int(self)})' + + def baseline_sumprod(p, q): + """This defines the target behavior including expections and special values. + However, it is subject to rounding errors, so float inputs should be exactly + representable with only a few bits. + """ + total = 0 + for p_i, q_i in zip(p, q, strict=True): + total += p_i * q_i + return total + + def run(func, *args): + "Make comparing functions easier. Returns error status, type, and result." + try: + result = func(*args) + except (AssertionError, NameError): + raise + except Exception as e: + return type(e), None, 'None' + return None, type(result), repr(result) + + pools = [ + (-5, 10, -2**20, 2**31, 2**40, 2**61, 2**62, 2**80, 1.5, Int(7)), + (5.25, -3.5, 4.75, 11.25, 400.5, 0.046875, 0.25, -1.0, -0.078125), + (-19.0*2**500, 11*2**1000, -3*2**1500, 17*2*333, + 5.25, -3.25, -3.0*2**(-333), 3, 2**513), + (3.75, 2.5, -1.5, float('inf'), -float('inf'), float('NaN'), 14, + 9, 3+4j, Flt(13), 0.0), + (13.25, -4.25, Decimal('10.5'), Decimal('-2.25'), Fraction(13, 8), + Fraction(-11, 16), 4.75 + 0.125j, 97, -41, Int(3)), + (Decimal('6.125'), Decimal('12.375'), Decimal('-2.75'), Decimal(0), + Decimal('Inf'), -Decimal('Inf'), Decimal('NaN'), 12, 13.5), + (-2.0 ** -1000, 11*2**1000, 3, 7, -37*2**32, -2*2**-537, -2*2**-538, + 2*2**-513), + (-7 * 2.0 ** -510, 5 * 2.0 ** -520, 17, -19.0, -6.25), + (11.25, -3.75, -0.625, 23.375, True, False, 7, Int(5)), + ] + + for pool in pools: + for size in range(4): + for args1 in product(pool, repeat=size): + for args2 in product(pool, repeat=size): + args = (args1, args2) + self.assertEqual( + run(baseline_sumprod, *args), + run(sumprod, *args), + args, + ) + + @requires_IEEE_754 + @unittest.skipIf(HAVE_DOUBLE_ROUNDING, + "sumprod() accuracy not guaranteed on machines with double rounding") + @support.cpython_only # Other implementations may choose a different algorithm + @support.requires_resource('cpu') + def test_sumprod_extended_precision_accuracy(self): + import operator + from fractions import Fraction + from itertools import starmap + from collections import namedtuple + from math import log2, exp2, fabs + from random import choices, uniform, shuffle + from statistics import median + + DotExample = namedtuple('DotExample', ('x', 'y', 'target_sumprod', 'condition')) + + def DotExact(x, y): + vec1 = map(Fraction, x) + vec2 = map(Fraction, y) + return sum(starmap(operator.mul, zip(vec1, vec2, strict=True))) + + def Condition(x, y): + return 2.0 * DotExact(map(abs, x), map(abs, y)) / abs(DotExact(x, y)) + + def linspace(lo, hi, n): + width = (hi - lo) / (n - 1) + return [lo + width * i for i in range(n)] + + def GenDot(n, c): + """ Algorithm 6.1 (GenDot) works as follows. The condition number (5.7) of + the dot product xT y is proportional to the degree of cancellation. In + order to achieve a prescribed cancellation, we generate the first half of + the vectors x and y randomly within a large exponent range. This range is + chosen according to the anticipated condition number. The second half of x + and y is then constructed choosing xi randomly with decreasing exponent, + and calculating yi such that some cancellation occurs. Finally, we permute + the vectors x, y randomly and calculate the achieved condition number. + """ + + assert n >= 6 + n2 = n // 2 + x = [0.0] * n + y = [0.0] * n + b = log2(c) + + # First half with exponents from 0 to |_b/2_| and random ints in between + e = choices(range(int(b/2)), k=n2) + e[0] = int(b / 2) + 1 + e[-1] = 0.0 + + x[:n2] = [uniform(-1.0, 1.0) * exp2(p) for p in e] + y[:n2] = [uniform(-1.0, 1.0) * exp2(p) for p in e] + + # Second half + e = list(map(round, linspace(b/2, 0.0 , n-n2))) + for i in range(n2, n): + x[i] = uniform(-1.0, 1.0) * exp2(e[i - n2]) + y[i] = (uniform(-1.0, 1.0) * exp2(e[i - n2]) - DotExact(x, y)) / x[i] + + # Shuffle + pairs = list(zip(x, y)) + shuffle(pairs) + x, y = zip(*pairs) + + return DotExample(x, y, DotExact(x, y), Condition(x, y)) + + def RelativeError(res, ex): + x, y, target_sumprod, condition = ex + n = DotExact(list(x) + [-res], list(y) + [1]) + return fabs(n / target_sumprod) + + def Trial(dotfunc, c, n): + ex = GenDot(10, c) + res = dotfunc(ex.x, ex.y) + return RelativeError(res, ex) + + times = 1000 # Number of trials + n = 20 # Length of vectors + c = 1e30 # Target condition number + + relative_err = median(Trial(math.sumprod, c, n) for i in range(times)) + self.assertLess(relative_err, 1e-16) + def testModf(self): self.assertRaises(TypeError, math.modf) @@ -1878,8 +2145,8 @@ class MathTests(unittest.TestCase): perm = math.perm factorial = math.factorial # Test if factorial definition is satisfied - for n in range(100): - for k in range(n + 1): + for n in range(500): + for k in (range(n + 1) if n < 100 else range(30) if n < 200 else range(10)): self.assertEqual(perm(n, k), factorial(n) // factorial(n - k)) @@ -1942,8 +2209,8 @@ class MathTests(unittest.TestCase): comb = math.comb factorial = math.factorial # Test if factorial definition is satisfied - for n in range(100): - for k in range(n + 1): + for n in range(500): + for k in (range(n + 1) if n < 100 else range(30) if n < 200 else range(10)): self.assertEqual(comb(n, k), factorial(n) // (factorial(k) * factorial(n - k))) diff --git a/Lib/test/test_memoryview.py b/Lib/test/test_memoryview.py index d7e3f0c0eff..0eb2a367603 100644 --- a/Lib/test/test_memoryview.py +++ b/Lib/test/test_memoryview.py @@ -13,6 +13,7 @@ import array import io import copy import pickle +import struct from test.support import import_helper @@ -527,6 +528,14 @@ class OtherTest(unittest.TestCase): m[2:] = memoryview(p6).cast(format)[2:] self.assertEqual(d.value, 0.6) + def test_half_float(self): + half_data = struct.pack('eee', 0.0, -1.5, 1.5) + float_data = struct.pack('fff', 0.0, -1.5, 1.5) + half_view = memoryview(half_data).cast('e') + float_view = memoryview(float_data).cast('f') + self.assertEqual(half_view.nbytes * 2, float_view.nbytes) + self.assertListEqual(half_view.tolist(), float_view.tolist()) + def test_memoryview_hex(self): # Issue #9951: memoryview.hex() segfaults with non-contiguous buffers. x = b'0' * 200000 @@ -545,6 +554,107 @@ class OtherTest(unittest.TestCase): with self.assertRaises(TypeError): pickle.dumps(m, proto) + def test_use_released_memory(self): + # gh-92888: Previously it was possible to use a memoryview even after + # backing buffer is freed in certain cases. This tests that those + # cases raise an exception. + size = 128 + def release(): + m.release() + nonlocal ba + ba = bytearray(size) + class MyIndex: + def __index__(self): + release() + return 4 + class MyFloat: + def __float__(self): + release() + return 4.25 + class MyBool: + def __bool__(self): + release() + return True + + ba = None + m = memoryview(bytearray(b'\xff'*size)) + with self.assertRaises(ValueError): + m[MyIndex()] + + ba = None + m = memoryview(bytearray(b'\xff'*size)) + self.assertEqual(list(m[:MyIndex()]), [255] * 4) + + ba = None + m = memoryview(bytearray(b'\xff'*size)) + self.assertEqual(list(m[MyIndex():8]), [255] * 4) + + ba = None + m = memoryview(bytearray(b'\xff'*size)).cast('B', (64, 2)) + with self.assertRaisesRegex(ValueError, "operation forbidden"): + m[MyIndex(), 0] + + ba = None + m = memoryview(bytearray(b'\xff'*size)).cast('B', (2, 64)) + with self.assertRaisesRegex(ValueError, "operation forbidden"): + m[0, MyIndex()] + + ba = None + m = memoryview(bytearray(b'\xff'*size)) + with self.assertRaisesRegex(ValueError, "operation forbidden"): + m[MyIndex()] = 42 + self.assertEqual(ba[:8], b'\0'*8) + + ba = None + m = memoryview(bytearray(b'\xff'*size)) + with self.assertRaisesRegex(ValueError, "operation forbidden"): + m[:MyIndex()] = b'spam' + self.assertEqual(ba[:8], b'\0'*8) + + ba = None + m = memoryview(bytearray(b'\xff'*size)) + with self.assertRaisesRegex(ValueError, "operation forbidden"): + m[MyIndex():8] = b'spam' + self.assertEqual(ba[:8], b'\0'*8) + + ba = None + m = memoryview(bytearray(b'\xff'*size)).cast('B', (64, 2)) + with self.assertRaisesRegex(ValueError, "operation forbidden"): + m[MyIndex(), 0] = 42 + self.assertEqual(ba[8:16], b'\0'*8) + ba = None + m = memoryview(bytearray(b'\xff'*size)).cast('B', (2, 64)) + with self.assertRaisesRegex(ValueError, "operation forbidden"): + m[0, MyIndex()] = 42 + self.assertEqual(ba[:8], b'\0'*8) + + ba = None + m = memoryview(bytearray(b'\xff'*size)) + with self.assertRaisesRegex(ValueError, "operation forbidden"): + m[0] = MyIndex() + self.assertEqual(ba[:8], b'\0'*8) + + for fmt in 'bhilqnBHILQN': + with self.subTest(fmt=fmt): + ba = None + m = memoryview(bytearray(b'\xff'*size)).cast(fmt) + with self.assertRaisesRegex(ValueError, "operation forbidden"): + m[0] = MyIndex() + self.assertEqual(ba[:8], b'\0'*8) + + for fmt in 'fd': + with self.subTest(fmt=fmt): + ba = None + m = memoryview(bytearray(b'\xff'*size)).cast(fmt) + with self.assertRaisesRegex(ValueError, "operation forbidden"): + m[0] = MyFloat() + self.assertEqual(ba[:8], b'\0'*8) + + ba = None + m = memoryview(bytearray(b'\xff'*size)).cast('?') + with self.assertRaisesRegex(ValueError, "operation forbidden"): + m[0] = MyBool() + self.assertEqual(ba[:8], b'\0'*8) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 4098a226440..d64aee71fc4 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -1,5 +1,4 @@ import io -import locale import mimetypes import pathlib import sys @@ -34,6 +33,13 @@ class MimeTypesTestCase(unittest.TestCase): def setUp(self): self.db = mimetypes.MimeTypes() + def test_case_sensitivity(self): + eq = self.assertEqual + eq(self.db.guess_type("foobar.HTML"), self.db.guess_type("foobar.html")) + eq(self.db.guess_type("foobar.TGZ"), self.db.guess_type("foobar.tgz")) + eq(self.db.guess_type("foobar.tar.Z"), ("application/x-tar", "compress")) + eq(self.db.guess_type("foobar.tar.z"), (None, None)) + def test_default_data(self): eq = self.assertEqual eq(self.db.guess_type("foo.html"), ("text/html", None)) @@ -90,12 +96,14 @@ class MimeTypesTestCase(unittest.TestCase): # First try strict eq(self.db.guess_type('foo.xul', strict=True), (None, None)) eq(self.db.guess_extension('image/jpg', strict=True), None) + eq(self.db.guess_extension('image/webp', strict=True), None) # And then non-strict eq(self.db.guess_type('foo.xul', strict=False), ('text/xul', None)) eq(self.db.guess_type('foo.XUL', strict=False), ('text/xul', None)) eq(self.db.guess_type('foo.invalid', strict=False), (None, None)) eq(self.db.guess_extension('image/jpg', strict=False), '.jpg') eq(self.db.guess_extension('image/JPG', strict=False), '.jpg') + eq(self.db.guess_extension('image/webp', strict=False), '.webp') def test_filename_with_url_delimiters(self): # bpo-38449: URL delimiters cases should be handled also. @@ -138,11 +146,6 @@ class MimeTypesTestCase(unittest.TestCase): self.assertNotIn('.no-such-ext', all) def test_encoding(self): - getpreferredencoding = locale.getpreferredencoding - self.addCleanup(setattr, locale, 'getpreferredencoding', - getpreferredencoding) - locale.getpreferredencoding = lambda: 'ascii' - filename = support.findfile("mime.types") mimes = mimetypes.MimeTypes([filename]) exts = mimes.guess_all_extensions('application/vnd.geocube+xml', @@ -159,6 +162,15 @@ class MimeTypesTestCase(unittest.TestCase): # Poison should be gone. self.assertEqual(mimetypes.guess_extension('foo/bar'), None) + @unittest.skipIf(sys.platform.startswith("win"), "Non-Windows only") + def test_guess_known_extensions(self): + # Issue 37529 + # The test fails on Windows because Windows adds mime types from the Registry + # and that creates some duplicates. + from mimetypes import types_map + for v in types_map.values(): + self.assertIsNotNone(mimetypes.guess_extension(v)) + def test_preferred_extension(self): def check_extensions(): self.assertEqual(mimetypes.guess_extension('application/octet-stream'), '.bin') @@ -170,6 +182,7 @@ class MimeTypesTestCase(unittest.TestCase): self.assertEqual(mimetypes.guess_extension('application/x-troff'), '.roff') self.assertEqual(mimetypes.guess_extension('application/xml'), '.xsl') self.assertEqual(mimetypes.guess_extension('audio/mpeg'), '.mp3') + self.assertEqual(mimetypes.guess_extension('image/avif'), '.avif') self.assertEqual(mimetypes.guess_extension('image/jpeg'), '.jpg') self.assertEqual(mimetypes.guess_extension('image/tiff'), '.tiff') self.assertEqual(mimetypes.guess_extension('message/rfc822'), '.eml') diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py index 1663b1f1143..2ca3908bd1c 100644 --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -6,10 +6,12 @@ import io from test import support import unittest +import pyexpat import xml.dom.minidom -from xml.dom.minidom import parse, Node, Document, parseString +from xml.dom.minidom import parse, Attr, Node, Document, parseString from xml.dom.minidom import getDOMImplementation +from xml.parsers.expat import ExpatError tstfile = support.findfile("test.xml", subdir="xmltestdata") @@ -75,6 +77,20 @@ class MinidomTest(unittest.TestCase): dom.unlink() self.confirm(isinstance(dom, Document)) + def testAttrModeSetsParamsAsAttrs(self): + attr = Attr("qName", "namespaceURI", "localName", "prefix") + self.assertEqual(attr.name, "qName") + self.assertEqual(attr.namespaceURI, "namespaceURI") + self.assertEqual(attr.prefix, "prefix") + self.assertEqual(attr.localName, "localName") + + def testAttrModeSetsNonOptionalAttrs(self): + attr = Attr("qName", "namespaceURI", None, "prefix") + self.assertEqual(attr.name, "qName") + self.assertEqual(attr.namespaceURI, "namespaceURI") + self.assertEqual(attr.prefix, "prefix") + self.assertEqual(attr.localName, attr.name) + def testGetElementsByTagName(self): dom = parse(tstfile) self.confirm(dom.getElementsByTagName("LI") == \ @@ -1147,8 +1163,10 @@ class MinidomTest(unittest.TestCase): # Verify that character decoding errors raise exceptions instead # of crashing - self.assertRaises(UnicodeDecodeError, parseString, - b'Comment \xe7a va ? Tr\xe8s bien ?') + with self.assertRaises((UnicodeDecodeError, ExpatError)): + parseString( + b'Comment \xe7a va ? Tr\xe8s bien ?' + ) doc.unlink() @@ -1609,8 +1627,11 @@ class MinidomTest(unittest.TestCase): self.confirm(doc2.namespaceURI == xml.dom.EMPTY_NAMESPACE) def testExceptionOnSpacesInXMLNSValue(self): - with self.assertRaisesRegex(ValueError, 'Unsupported syntax'): - parseString('') + with self.assertRaises((ValueError, ExpatError)): + parseString( + '' + + '' + ) def testDocRemoveChild(self): doc = parse(tstfile) diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index 014171cbb49..213a44d56f3 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -1,4 +1,6 @@ -from test.support import (requires, _2G, _4G, gc_collect, cpython_only) +from test.support import ( + requires, _2G, _4G, gc_collect, cpython_only, is_emscripten +) from test.support.import_helper import import_module from test.support.os_helper import TESTFN, unlink import unittest @@ -21,6 +23,12 @@ def random_tagname(length=10): suffix = ''.join(random.choices(string.ascii_uppercase, k=length)) return f'{tagname_prefix}_{suffix}' +# Python's mmap module dup()s the file descriptor. Emscripten's FS layer +# does not materialize file changes through a dupped fd to a new mmap. +if is_emscripten: + raise unittest.SkipTest("incompatible with Emscripten's mmap emulation.") + + class MmapTests(unittest.TestCase): def setUp(self): diff --git a/Lib/test/test_module.py b/Lib/test/test_module.py index 619348e0e40..70e4efea693 100644 --- a/Lib/test/test_module.py +++ b/Lib/test/test_module.py @@ -8,10 +8,10 @@ from test.support.script_helper import assert_python_ok import sys ModuleType = type(sys) + class FullLoader: - @classmethod - def module_repr(cls, m): - return "".format(m.__name__) + pass + class BareLoader: pass @@ -236,10 +236,9 @@ a = A(destroyed)""" # Yes, a class not an instance. m.__loader__ = FullLoader self.assertEqual( - repr(m), "") + repr(m), ")>") def test_module_repr_with_bare_loader_and_filename(self): - # Because the loader has no module_repr(), use the file name. m = ModuleType('foo') # Yes, a class not an instance. m.__loader__ = BareLoader @@ -247,12 +246,11 @@ a = A(destroyed)""" self.assertEqual(repr(m), "") def test_module_repr_with_full_loader_and_filename(self): - # Even though the module has an __file__, use __loader__.module_repr() m = ModuleType('foo') # Yes, a class not an instance. m.__loader__ = FullLoader m.__file__ = '/tmp/foo.py' - self.assertEqual(repr(m), "") + self.assertEqual(repr(m), "") def test_module_repr_builtin(self): self.assertEqual(repr(sys), "") @@ -346,6 +344,25 @@ a = A(destroyed)""" # frozen and namespace module reprs are tested in importlib. + def test_subclass_with_slots(self): + # In 3.11alpha this crashed, as the slots weren't NULLed. + + class ModuleWithSlots(ModuleType): + __slots__ = ("a", "b") + + def __init__(self, name): + super().__init__(name) + + m = ModuleWithSlots("name") + with self.assertRaises(AttributeError): + m.a + with self.assertRaises(AttributeError): + m.b + m.a, m.b = 1, 2 + self.assertEqual(m.a, 1) + self.assertEqual(m.b, 2) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_modulefinder.py b/Lib/test/test_modulefinder.py index ca1058b8d40..b64e684f805 100644 --- a/Lib/test/test_modulefinder.py +++ b/Lib/test/test_modulefinder.py @@ -10,9 +10,6 @@ from test import support import modulefinder -TEST_DIR = tempfile.mkdtemp() -TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)] - # Each test description is a list of 5 items: # # 1. a module name that will be imported by modulefinder @@ -23,9 +20,9 @@ TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)] # about because they MAY be not found # 5. a string specifying packages to create; the format is obvious imo. # -# Each package will be created in TEST_DIR, and TEST_DIR will be +# Each package will be created in test_dir, and test_dir will be # removed after the tests again. -# Modulefinder searches in a path that contains TEST_DIR, plus +# Modulefinder searches in a path that contains test_dir, plus # the standard Lib directory. maybe_test = [ @@ -300,7 +297,7 @@ def open_file(path): return open(path, 'wb') -def create_package(source): +def create_package(test_dir, source): ofi = None try: for line in source.splitlines(): @@ -313,41 +310,45 @@ def create_package(source): ofi.close() if type(line) == bytes: line = line.decode('utf-8') - ofi = open_file(os.path.join(TEST_DIR, line.strip())) + ofi = open_file(os.path.join(test_dir, line.strip())) finally: if ofi: ofi.close() class ModuleFinderTest(unittest.TestCase): + def setUp(self): + self.test_dir = tempfile.mkdtemp() + self.test_path = [self.test_dir, os.path.dirname(tempfile.__file__)] + + def tearDown(self): + shutil.rmtree(self.test_dir) + def _do_test(self, info, report=False, debug=0, replace_paths=[], modulefinder_class=modulefinder.ModuleFinder): import_this, modules, missing, maybe_missing, source = info - create_package(source) - try: - mf = modulefinder_class(path=TEST_PATH, debug=debug, - replace_paths=replace_paths) - mf.import_hook(import_this) - if report: - mf.report() -## # This wouldn't work in general when executed several times: -## opath = sys.path[:] -## sys.path = TEST_PATH -## try: -## __import__(import_this) -## except: -## import traceback; traceback.print_exc() -## sys.path = opath -## return - modules = sorted(set(modules)) - found = sorted(mf.modules) - # check if we found what we expected, not more, not less - self.assertEqual(found, modules) + create_package(self.test_dir, source) + mf = modulefinder_class(path=self.test_path, debug=debug, + replace_paths=replace_paths) + mf.import_hook(import_this) + if report: + mf.report() +## # This wouldn't work in general when executed several times: +## opath = sys.path[:] +## sys.path = self.test_path +## try: +## __import__(import_this) +## except: +## import traceback; traceback.print_exc() +## sys.path = opath +## return + modules = sorted(set(modules)) + found = sorted(mf.modules) + # check if we found what we expected, not more, not less + self.assertEqual(found, modules) - # check for missing and maybe missing modules - bad, maybe = mf.any_missing_maybe() - self.assertEqual(bad, missing) - self.assertEqual(maybe, maybe_missing) - finally: - shutil.rmtree(TEST_DIR) + # check for missing and maybe missing modules + bad, maybe = mf.any_missing_maybe() + self.assertEqual(bad, missing) + self.assertEqual(maybe, maybe_missing) def test_package(self): self._do_test(package_test) @@ -380,7 +381,7 @@ class ModuleFinderTest(unittest.TestCase): self._do_test(same_name_as_bad_test) def test_bytecode(self): - base_path = os.path.join(TEST_DIR, 'a') + base_path = os.path.join(self.test_dir, 'a') source_path = base_path + importlib.machinery.SOURCE_SUFFIXES[0] bytecode_path = base_path + importlib.machinery.BYTECODE_SUFFIXES[0] with open_file(source_path) as file: @@ -390,8 +391,8 @@ class ModuleFinderTest(unittest.TestCase): self._do_test(bytecode_test) def test_replace_paths(self): - old_path = os.path.join(TEST_DIR, 'a', 'module.py') - new_path = os.path.join(TEST_DIR, 'a', 'spam.py') + old_path = os.path.join(self.test_dir, 'a', 'module.py') + new_path = os.path.join(self.test_dir, 'a', 'spam.py') with support.captured_stdout() as output: self._do_test(maybe_test, debug=2, replace_paths=[(old_path, new_path)]) diff --git a/Lib/test/test_msilib.py b/Lib/test/test_msilib.py index e29cd4a84c5..db16f62a4c1 100644 --- a/Lib/test/test_msilib.py +++ b/Lib/test/test_msilib.py @@ -3,7 +3,10 @@ import os import unittest from test.support.import_helper import import_module from test.support.os_helper import TESTFN, unlink -msilib = import_module('msilib') +import warnings +with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + msilib = import_module('msilib') import msilib.schema diff --git a/Lib/test/test_multiprocessing_main_handling.py b/Lib/test/test_multiprocessing_main_handling.py index 510d8d3a759..6b30a893167 100644 --- a/Lib/test/test_multiprocessing_main_handling.py +++ b/Lib/test/test_multiprocessing_main_handling.py @@ -40,6 +40,7 @@ test_source = """\ import sys import time from multiprocessing import Pool, set_start_method +from test import support # We use this __main__ defined function in the map call below in order to # check that multiprocessing in correctly running the unguarded @@ -59,13 +60,12 @@ if __name__ == '__main__': results = [] with Pool(5) as pool: pool.map_async(f, [1, 2, 3], callback=results.extend) - start_time = time.monotonic() - while not results: - time.sleep(0.05) - # up to 1 min to report the results - dt = time.monotonic() - start_time - if dt > 60.0: - raise RuntimeError("Timed out waiting for results (%.1f sec)" % dt) + + # up to 1 min to report the results + for _ in support.sleeping_retry(support.LONG_TIMEOUT, + "Timed out waiting for results"): + if results: + break results.sort() print(start_method, "->", results) @@ -86,19 +86,18 @@ if __name__ != "__main__": import sys import time from multiprocessing import Pool, set_start_method +from test import support start_method = sys.argv[1] set_start_method(start_method) results = [] with Pool(5) as pool: pool.map_async(int, [1, 4, 9], callback=results.extend) - start_time = time.monotonic() - while not results: - time.sleep(0.05) - # up to 1 min to report the results - dt = time.monotonic() - start_time - if dt > 60.0: - raise RuntimeError("Timed out waiting for results (%.1f sec)" % dt) + # up to 1 min to report the results + for _ in support.sleeping_retry(support.LONG_TIMEOUT, + "Timed out waiting for results"): + if results: + break results.sort() print(start_method, "->", results) diff --git a/Lib/test/test_named_expressions.py b/Lib/test/test_named_expressions.py index 20ac2e699f0..7b2fa844827 100644 --- a/Lib/test/test_named_expressions.py +++ b/Lib/test/test_named_expressions.py @@ -114,6 +114,69 @@ class NamedExpressionInvalidTest(unittest.TestCase): "assignment expression within a comprehension cannot be used in a class body"): exec(code, {}, {}) + def test_named_expression_valid_rebinding_iteration_variable(self): + # This test covers that we can reassign variables + # that are not directly assigned in the + # iterable part of a comprehension. + cases = [ + # Regression tests from https://github.com/python/cpython/issues/87447 + ("Complex expression: c", + "{0}(c := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ("Complex expression: d", + "{0}(d := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ("Complex expression: e", + "{0}(e := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ("Complex expression: f", + "{0}(f := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ("Complex expression: g", + "{0}(g := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ("Complex expression: h", + "{0}(h := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ("Complex expression: i", + "{0}(i := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ("Complex expression: j", + "{0}(j := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ] + for test_case, code in cases: + for lpar, rpar in [('(', ')'), ('[', ']'), ('{', '}')]: + code = code.format(lpar, rpar) + with self.subTest(case=test_case, lpar=lpar, rpar=rpar): + # Names used in snippets are not defined, + # but we are fine with it: just must not be a SyntaxError. + # Names used in snippets are not defined, + # but we are fine with it: just must not be a SyntaxError. + with self.assertRaises(NameError): + exec(code, {}) # Module scope + with self.assertRaises(NameError): + exec(code, {}, {}) # Class scope + exec(f"lambda: {code}", {}) # Function scope + + def test_named_expression_invalid_rebinding_iteration_variable(self): + # This test covers that we cannot reassign variables + # that are directly assigned in the iterable part of a comprehension. + cases = [ + # Regression tests from https://github.com/python/cpython/issues/87447 + ("Complex expression: a", "a", + "{0}(a := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ("Complex expression: b", "b", + "{0}(b := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ] + for test_case, target, code in cases: + msg = f"assignment expression cannot rebind comprehension iteration variable '{target}'" + for lpar, rpar in [('(', ')'), ('[', ']'), ('{', '}')]: + code = code.format(lpar, rpar) + with self.subTest(case=test_case, lpar=lpar, rpar=rpar): + # Names used in snippets are not defined, + # but we are fine with it: just must not be a SyntaxError. + # Names used in snippets are not defined, + # but we are fine with it: just must not be a SyntaxError. + with self.assertRaisesRegex(SyntaxError, msg): + exec(code, {}) # Module scope + with self.assertRaisesRegex(SyntaxError, msg): + exec(code, {}, {}) # Class scope + with self.assertRaisesRegex(SyntaxError, msg): + exec(f"lambda: {code}", {}) # Function scope + def test_named_expression_invalid_rebinding_list_comprehension_iteration_variable(self): cases = [ ("Local reuse", 'i', "[i := 0 for i in range(5)]"), @@ -129,7 +192,11 @@ class NamedExpressionInvalidTest(unittest.TestCase): msg = f"assignment expression cannot rebind comprehension iteration variable '{target}'" with self.subTest(case=case): with self.assertRaisesRegex(SyntaxError, msg): - exec(code, {}, {}) + exec(code, {}) # Module scope + with self.assertRaisesRegex(SyntaxError, msg): + exec(code, {}, {}) # Class scope + with self.assertRaisesRegex(SyntaxError, msg): + exec(f"lambda: {code}", {}) # Function scope def test_named_expression_invalid_rebinding_list_comprehension_inner_loop(self): cases = [ @@ -178,12 +245,21 @@ class NamedExpressionInvalidTest(unittest.TestCase): ("Unreachable reuse", 'i', "{False or (i:=0) for i in range(5)}"), ("Unreachable nested reuse", 'i', "{(i, j) for i in range(5) for j in range(5) if True or (i:=10)}"), + # Regression tests from https://github.com/python/cpython/issues/87447 + ("Complex expression: a", "a", + "{(a := 1) for a, (*b, c[d+e::f(g)], h.i) in j}"), + ("Complex expression: b", "b", + "{(b := 1) for a, (*b, c[d+e::f(g)], h.i) in j}"), ] for case, target, code in cases: msg = f"assignment expression cannot rebind comprehension iteration variable '{target}'" with self.subTest(case=case): with self.assertRaisesRegex(SyntaxError, msg): - exec(code, {}, {}) + exec(code, {}) # Module scope + with self.assertRaisesRegex(SyntaxError, msg): + exec(code, {}, {}) # Class scope + with self.assertRaisesRegex(SyntaxError, msg): + exec(f"lambda: {code}", {}) # Function scope def test_named_expression_invalid_rebinding_set_comprehension_inner_loop(self): cases = [ diff --git a/Lib/test/test_netrc.py b/Lib/test/test_netrc.py index a6b4bc47a32..573d636de95 100644 --- a/Lib/test/test_netrc.py +++ b/Lib/test/test_netrc.py @@ -1,6 +1,11 @@ import netrc, os, unittest, sys, textwrap from test.support import os_helper, run_unittest +try: + import pwd +except ImportError: + pwd = None + temp_filename = os_helper.TESTFN class NetrcTestCase(unittest.TestCase): @@ -10,7 +15,7 @@ class NetrcTestCase(unittest.TestCase): mode = 'w' if sys.platform != 'cygwin': mode += 't' - with open(temp_filename, mode) as fp: + with open(temp_filename, mode, encoding="utf-8") as fp: fp.write(test_data) try: nrc = netrc.netrc(temp_filename) @@ -266,6 +271,8 @@ class NetrcTestCase(unittest.TestCase): @unittest.skipUnless(os.name == 'posix', 'POSIX only test') + @unittest.skipIf(pwd is None, 'security check requires pwd module') + @os_helper.skip_unless_working_chmod def test_security(self): # This test is incomplete since we are normally not run as root and # therefore can't test the file ownership being wrong. diff --git a/Lib/test/test_nis.py b/Lib/test/test_nis.py index a22142f4069..f327ecf3d1d 100644 --- a/Lib/test/test_nis.py +++ b/Lib/test/test_nis.py @@ -1,10 +1,12 @@ -from test import support from test.support import import_helper import unittest +import warnings # Skip test if nis module does not exist. -nis = import_helper.import_module('nis') +with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + nis = import_helper.import_module('nis') class NisTests(unittest.TestCase): diff --git a/Lib/test/test_nntplib.py b/Lib/test/test_nntplib.py index 4f0592188f8..31a02f86abb 100644 --- a/Lib/test/test_nntplib.py +++ b/Lib/test/test_nntplib.py @@ -5,13 +5,13 @@ import textwrap import unittest import functools import contextlib -import nntplib import os.path import re import threading from test import support -from test.support import socket_helper +from test.support import socket_helper, warnings_helper +nntplib = warnings_helper.import_deprecated("nntplib") from nntplib import NNTP, GroupInfo from unittest.mock import patch try: @@ -1593,8 +1593,7 @@ class LocalServerTests(unittest.TestCase): self.background.start() self.addCleanup(self.background.join) - self.nntp = NNTP(socket_helper.HOST, port, usenetrc=False).__enter__() - self.addCleanup(self.nntp.__exit__, None, None, None) + self.nntp = self.enterContext(NNTP(socket_helper.HOST, port, usenetrc=False)) def run_server(self, sock): # Could be generalized to handle more commands in separate methods diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 661c59d6171..bce38a534a6 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -4,7 +4,7 @@ import sys import unittest import warnings from test.support import os_helper -from test.support import TestFailed +from test.support import TestFailed, is_emscripten from test.support.os_helper import FakePath from test import test_genericpath from tempfile import TemporaryFile @@ -98,25 +98,106 @@ class TestNtpath(NtpathTestCase): tester('ntpath.splitext("c:a/b\\c.d")', ('c:a/b\\c', '.d')) def test_splitdrive(self): - tester('ntpath.splitdrive("c:\\foo\\bar")', - ('c:', '\\foo\\bar')) - tester('ntpath.splitdrive("c:/foo/bar")', - ('c:', '/foo/bar')) + tester("ntpath.splitdrive('')", ('', '')) + tester("ntpath.splitdrive('foo')", ('', 'foo')) + tester("ntpath.splitdrive('foo\\bar')", ('', 'foo\\bar')) + tester("ntpath.splitdrive('foo/bar')", ('', 'foo/bar')) + tester("ntpath.splitdrive('\\')", ('', '\\')) + tester("ntpath.splitdrive('/')", ('', '/')) + tester("ntpath.splitdrive('\\foo\\bar')", ('', '\\foo\\bar')) + tester("ntpath.splitdrive('/foo/bar')", ('', '/foo/bar')) + tester('ntpath.splitdrive("c:foo\\bar")', ('c:', 'foo\\bar')) + tester('ntpath.splitdrive("c:foo/bar")', ('c:', 'foo/bar')) + tester('ntpath.splitdrive("c:\\foo\\bar")', ('c:', '\\foo\\bar')) + tester('ntpath.splitdrive("c:/foo/bar")', ('c:', '/foo/bar')) + tester("ntpath.splitdrive('\\\\')", ('\\\\', '')) + tester("ntpath.splitdrive('//')", ('//', '')) tester('ntpath.splitdrive("\\\\conky\\mountpoint\\foo\\bar")', ('\\\\conky\\mountpoint', '\\foo\\bar')) tester('ntpath.splitdrive("//conky/mountpoint/foo/bar")', ('//conky/mountpoint', '/foo/bar')) - tester('ntpath.splitdrive("\\\\\\conky\\mountpoint\\foo\\bar")', - ('', '\\\\\\conky\\mountpoint\\foo\\bar')) - tester('ntpath.splitdrive("///conky/mountpoint/foo/bar")', - ('', '///conky/mountpoint/foo/bar')) - tester('ntpath.splitdrive("\\\\conky\\\\mountpoint\\foo\\bar")', - ('', '\\\\conky\\\\mountpoint\\foo\\bar')) - tester('ntpath.splitdrive("//conky//mountpoint/foo/bar")', - ('', '//conky//mountpoint/foo/bar')) + tester('ntpath.splitdrive("\\\\?\\UNC\\server\\share\\dir")', + ("\\\\?\\UNC\\server\\share", "\\dir")) + tester('ntpath.splitdrive("//?/UNC/server/share/dir")', + ("//?/UNC/server/share", "/dir")) + + def test_splitroot(self): + tester("ntpath.splitroot('')", ('', '', '')) + tester("ntpath.splitroot('foo')", ('', '', 'foo')) + tester("ntpath.splitroot('foo\\bar')", ('', '', 'foo\\bar')) + tester("ntpath.splitroot('foo/bar')", ('', '', 'foo/bar')) + tester("ntpath.splitroot('\\')", ('', '\\', '')) + tester("ntpath.splitroot('/')", ('', '/', '')) + tester("ntpath.splitroot('\\foo\\bar')", ('', '\\', 'foo\\bar')) + tester("ntpath.splitroot('/foo/bar')", ('', '/', 'foo/bar')) + tester('ntpath.splitroot("c:foo\\bar")', ('c:', '', 'foo\\bar')) + tester('ntpath.splitroot("c:foo/bar")', ('c:', '', 'foo/bar')) + tester('ntpath.splitroot("c:\\foo\\bar")', ('c:', '\\', 'foo\\bar')) + tester('ntpath.splitroot("c:/foo/bar")', ('c:', '/', 'foo/bar')) + + # Redundant slashes are not included in the root. + tester("ntpath.splitroot('c:\\\\a')", ('c:', '\\', '\\a')) + tester("ntpath.splitroot('c:\\\\\\a/b')", ('c:', '\\', '\\\\a/b')) + + # Mixed path separators. + tester("ntpath.splitroot('c:/\\')", ('c:', '/', '\\')) + tester("ntpath.splitroot('c:\\/')", ('c:', '\\', '/')) + tester("ntpath.splitroot('/\\a/b\\/\\')", ('/\\a/b', '\\', '/\\')) + tester("ntpath.splitroot('\\/a\\b/\\/')", ('\\/a\\b', '/', '\\/')) + + # UNC paths. + tester("ntpath.splitroot('\\\\')", ('\\\\', '', '')) + tester("ntpath.splitroot('//')", ('//', '', '')) + tester('ntpath.splitroot("\\\\conky\\mountpoint\\foo\\bar")', + ('\\\\conky\\mountpoint', '\\', 'foo\\bar')) + tester('ntpath.splitroot("//conky/mountpoint/foo/bar")', + ('//conky/mountpoint', '/', 'foo/bar')) + tester('ntpath.splitroot("\\\\\\conky\\mountpoint\\foo\\bar")', + ('\\\\\\conky', '\\', 'mountpoint\\foo\\bar')) + tester('ntpath.splitroot("///conky/mountpoint/foo/bar")', + ('///conky', '/', 'mountpoint/foo/bar')) + tester('ntpath.splitroot("\\\\conky\\\\mountpoint\\foo\\bar")', + ('\\\\conky\\', '\\', 'mountpoint\\foo\\bar')) + tester('ntpath.splitroot("//conky//mountpoint/foo/bar")', + ('//conky/', '/', 'mountpoint/foo/bar')) + # Issue #19911: UNC part containing U+0130 - self.assertEqual(ntpath.splitdrive('//conky/MOUNTPOİNT/foo/bar'), - ('//conky/MOUNTPOİNT', '/foo/bar')) + self.assertEqual(ntpath.splitroot('//conky/MOUNTPOİNT/foo/bar'), + ('//conky/MOUNTPOİNT', '/', 'foo/bar')) + + # gh-81790: support device namespace, including UNC drives. + tester('ntpath.splitroot("//?/c:")', ("//?/c:", "", "")) + tester('ntpath.splitroot("//?/c:/")', ("//?/c:", "/", "")) + tester('ntpath.splitroot("//?/c:/dir")', ("//?/c:", "/", "dir")) + tester('ntpath.splitroot("//?/UNC")', ("//?/UNC", "", "")) + tester('ntpath.splitroot("//?/UNC/")', ("//?/UNC/", "", "")) + tester('ntpath.splitroot("//?/UNC/server/")', ("//?/UNC/server/", "", "")) + tester('ntpath.splitroot("//?/UNC/server/share")', ("//?/UNC/server/share", "", "")) + tester('ntpath.splitroot("//?/UNC/server/share/dir")', ("//?/UNC/server/share", "/", "dir")) + tester('ntpath.splitroot("//?/VOLUME{00000000-0000-0000-0000-000000000000}/spam")', + ('//?/VOLUME{00000000-0000-0000-0000-000000000000}', '/', 'spam')) + tester('ntpath.splitroot("//?/BootPartition/")', ("//?/BootPartition", "/", "")) + + tester('ntpath.splitroot("\\\\?\\c:")', ("\\\\?\\c:", "", "")) + tester('ntpath.splitroot("\\\\?\\c:\\")', ("\\\\?\\c:", "\\", "")) + tester('ntpath.splitroot("\\\\?\\c:\\dir")', ("\\\\?\\c:", "\\", "dir")) + tester('ntpath.splitroot("\\\\?\\UNC")', ("\\\\?\\UNC", "", "")) + tester('ntpath.splitroot("\\\\?\\UNC\\")', ("\\\\?\\UNC\\", "", "")) + tester('ntpath.splitroot("\\\\?\\UNC\\server\\")', ("\\\\?\\UNC\\server\\", "", "")) + tester('ntpath.splitroot("\\\\?\\UNC\\server\\share")', + ("\\\\?\\UNC\\server\\share", "", "")) + tester('ntpath.splitroot("\\\\?\\UNC\\server\\share\\dir")', + ("\\\\?\\UNC\\server\\share", "\\", "dir")) + tester('ntpath.splitroot("\\\\?\\VOLUME{00000000-0000-0000-0000-000000000000}\\spam")', + ('\\\\?\\VOLUME{00000000-0000-0000-0000-000000000000}', '\\', 'spam')) + tester('ntpath.splitroot("\\\\?\\BootPartition\\")', ("\\\\?\\BootPartition", "\\", "")) + + # gh-96290: support partial/invalid UNC drives + tester('ntpath.splitroot("//")', ("//", "", "")) # empty server & missing share + tester('ntpath.splitroot("///")', ("///", "", "")) # empty server & empty share + tester('ntpath.splitroot("///y")', ("///y", "", "")) # empty server & non-empty share + tester('ntpath.splitroot("//x")', ("//x", "", "")) # non-empty server & missing share + tester('ntpath.splitroot("//x/")', ("//x/", "", "")) # non-empty server & empty share def test_split(self): tester('ntpath.split("c:\\foo\\bar")', ('c:\\foo', 'bar')) @@ -136,6 +217,10 @@ class TestNtpath(NtpathTestCase): tester('ntpath.isabs("\\foo")', 1) tester('ntpath.isabs("\\foo\\bar")', 1) + # gh-96290: normal UNC paths and device paths without trailing backslashes + tester('ntpath.isabs("\\\\conky\\mountpoint")', 1) + tester('ntpath.isabs("\\\\.\\C:")', 1) + def test_commonprefix(self): tester('ntpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"])', "/home/swen") @@ -235,6 +320,21 @@ class TestNtpath(NtpathTestCase): tester("ntpath.normpath('\\\\.\\NUL')", r'\\.\NUL') tester("ntpath.normpath('\\\\?\\D:/XY\\Z')", r'\\?\D:/XY\Z') + tester("ntpath.normpath('handbook/../../Tests/image.png')", r'..\Tests\image.png') + tester("ntpath.normpath('handbook/../../../Tests/image.png')", r'..\..\Tests\image.png') + tester("ntpath.normpath('handbook///../a/.././../b/c')", r'..\b\c') + tester("ntpath.normpath('handbook/a/../..///../../b/c')", r'..\..\b\c') + + tester("ntpath.normpath('//server/share/..')" , '\\\\server\\share\\') + tester("ntpath.normpath('//server/share/../')" , '\\\\server\\share\\') + tester("ntpath.normpath('//server/share/../..')", '\\\\server\\share\\') + tester("ntpath.normpath('//server/share/../../')", '\\\\server\\share\\') + + # gh-96290: don't normalize partial/invalid UNC drives as rooted paths. + tester("ntpath.normpath('\\\\foo\\\\')", '\\\\foo\\\\') + tester("ntpath.normpath('\\\\foo\\')", '\\\\foo\\') + tester("ntpath.normpath('\\\\foo')", '\\\\foo') + tester("ntpath.normpath('\\\\')", '\\\\') def test_realpath_curdir(self): expected = ntpath.normpath(os.getcwd()) @@ -604,6 +704,40 @@ class TestNtpath(NtpathTestCase): @unittest.skipUnless(nt, "abspath requires 'nt' module") def test_abspath(self): tester('ntpath.abspath("C:\\")', "C:\\") + tester('ntpath.abspath("\\\\?\\C:////spam////eggs. . .")', "\\\\?\\C:\\spam\\eggs") + tester('ntpath.abspath("\\\\.\\C:////spam////eggs. . .")', "\\\\.\\C:\\spam\\eggs") + tester('ntpath.abspath("//spam//eggs. . .")', "\\\\spam\\eggs") + tester('ntpath.abspath("\\\\spam\\\\eggs. . .")', "\\\\spam\\eggs") + tester('ntpath.abspath("C:/spam. . .")', "C:\\spam") + tester('ntpath.abspath("C:\\spam. . .")', "C:\\spam") + tester('ntpath.abspath("C:/nul")', "\\\\.\\nul") + tester('ntpath.abspath("C:\\nul")', "\\\\.\\nul") + tester('ntpath.abspath("//..")', "\\\\") + tester('ntpath.abspath("//../")', "\\\\..\\") + tester('ntpath.abspath("//../..")', "\\\\..\\") + tester('ntpath.abspath("//../../")', "\\\\..\\..\\") + tester('ntpath.abspath("//../../../")', "\\\\..\\..\\") + tester('ntpath.abspath("//../../../..")', "\\\\..\\..\\") + tester('ntpath.abspath("//../../../../")', "\\\\..\\..\\") + tester('ntpath.abspath("//server")', "\\\\server") + tester('ntpath.abspath("//server/")', "\\\\server\\") + tester('ntpath.abspath("//server/..")', "\\\\server\\") + tester('ntpath.abspath("//server/../")', "\\\\server\\..\\") + tester('ntpath.abspath("//server/../..")', "\\\\server\\..\\") + tester('ntpath.abspath("//server/../../")', "\\\\server\\..\\") + tester('ntpath.abspath("//server/../../..")', "\\\\server\\..\\") + tester('ntpath.abspath("//server/../../../")', "\\\\server\\..\\") + tester('ntpath.abspath("//server/share")', "\\\\server\\share") + tester('ntpath.abspath("//server/share/")', "\\\\server\\share\\") + tester('ntpath.abspath("//server/share/..")', "\\\\server\\share\\") + tester('ntpath.abspath("//server/share/../")', "\\\\server\\share\\") + tester('ntpath.abspath("//server/share/../..")', "\\\\server\\share\\") + tester('ntpath.abspath("//server/share/../../")', "\\\\server\\share\\") + tester('ntpath.abspath("C:\\nul. . .")', "\\\\.\\nul") + tester('ntpath.abspath("//... . .")', "\\\\") + tester('ntpath.abspath("//.. . . .")', "\\\\") + tester('ntpath.abspath("//../... . .")', "\\\\..\\") + tester('ntpath.abspath("//../.. . . .")', "\\\\..\\") with os_helper.temp_cwd(os_helper.TESTFN) as cwd_dir: # bpo-31047 tester('ntpath.abspath("")', cwd_dir) tester('ntpath.abspath(" ")', cwd_dir + "\\ ") @@ -704,6 +838,7 @@ class TestNtpath(NtpathTestCase): self.assertRaises(TypeError, ntpath.commonpath, ['Program Files', b'C:\\Program Files\\Foo']) + @unittest.skipIf(is_emscripten, "Emscripten cannot fstat unnamed files.") def test_sameopenfile(self): with TemporaryFile() as tf1, TemporaryFile() as tf2: # Make sure the same file is really the same @@ -741,8 +876,9 @@ class TestNtpath(NtpathTestCase): # (or any other volume root). The drive-relative # locations below cannot then refer to mount points # - drive, path = ntpath.splitdrive(sys.executable) - with os_helper.change_cwd(ntpath.dirname(sys.executable)): + test_cwd = os.getenv("SystemRoot") + drive, path = ntpath.splitdrive(test_cwd) + with os_helper.change_cwd(test_cwd): self.assertFalse(ntpath.ismount(drive.lower())) self.assertFalse(ntpath.ismount(drive.upper())) @@ -786,6 +922,23 @@ class TestNtpath(NtpathTestCase): self.assertIsInstance(b_final_path, bytes) self.assertGreater(len(b_final_path), 0) + @unittest.skipIf(sys.platform != 'win32', "Can only test junctions with creation on win32.") + def test_isjunction(self): + with os_helper.temp_dir() as d: + with os_helper.change_cwd(d): + os.mkdir('tmpdir') + + import _winapi + try: + _winapi.CreateJunction('tmpdir', 'testjunc') + except OSError: + raise unittest.SkipTest('creating the test junction failed') + + self.assertTrue(ntpath.isjunction('testjunc')) + self.assertFalse(ntpath.isjunction('tmpdir')) + self.assertPathEqual(ntpath.realpath('testjunc'), ntpath.realpath('tmpdir')) + + class NtCommonTest(test_genericpath.CommonTest, unittest.TestCase): pathmodule = ntpath attributes = ['relpath'] @@ -807,6 +960,8 @@ class PathLikeTests(NtpathTestCase): def test_path_normcase(self): self._check_function(self.path.normcase) + if sys.platform == 'win32': + self.assertEqual(ntpath.normcase('\u03a9\u2126'), 'ωΩ') def test_path_isabs(self): self._check_function(self.path.isabs) @@ -824,6 +979,9 @@ class PathLikeTests(NtpathTestCase): def test_path_splitdrive(self): self._check_function(self.path.splitdrive) + def test_path_splitroot(self): + self._check_function(self.path.splitroot) + def test_path_basename(self): self._check_function(self.path.basename) diff --git a/Lib/test/test_numeric_tower.py b/Lib/test/test_numeric_tower.py index c54dedb8b79..9cd85e13634 100644 --- a/Lib/test/test_numeric_tower.py +++ b/Lib/test/test_numeric_tower.py @@ -14,6 +14,27 @@ from fractions import Fraction as F _PyHASH_MODULUS = sys.hash_info.modulus _PyHASH_INF = sys.hash_info.inf + +class DummyIntegral(int): + """Dummy Integral class to test conversion of the Rational to float.""" + + def __mul__(self, other): + return DummyIntegral(super().__mul__(other)) + __rmul__ = __mul__ + + def __truediv__(self, other): + return NotImplemented + __rtruediv__ = __truediv__ + + @property + def numerator(self): + return DummyIntegral(self) + + @property + def denominator(self): + return DummyIntegral(1) + + class HashTest(unittest.TestCase): def check_equal_hash(self, x, y): # check both that x and y are equal and that their hashes are equal @@ -121,6 +142,13 @@ class HashTest(unittest.TestCase): self.assertEqual(hash(F(7*_PyHASH_MODULUS, 1)), 0) self.assertEqual(hash(F(-_PyHASH_MODULUS, 1)), 0) + # The numbers ABC doesn't enforce that the "true" division + # of integers produces a float. This tests that the + # Rational.__float__() method has required type conversions. + x = F(DummyIntegral(1), DummyIntegral(2), _normalize=False) + self.assertRaises(TypeError, lambda: x.numerator/x.denominator) + self.assertEqual(float(x), 0.5) + def test_hash_normalization(self): # Test for a bug encountered while changing long_hash. # diff --git a/Lib/test/test_opcache.py b/Lib/test/test_opcache.py index 61f337d70ea..e39b7260624 100644 --- a/Lib/test/test_opcache.py +++ b/Lib/test/test_opcache.py @@ -1,5 +1,6 @@ import unittest + class TestLoadAttrCache(unittest.TestCase): def test_descriptor_added_after_optimization(self): class Descriptor: @@ -21,3 +22,413 @@ class TestLoadAttrCache(unittest.TestCase): Descriptor.__set__ = lambda *args: None self.assertEqual(f(o), 2) + + def test_metaclass_descriptor_added_after_optimization(self): + class Descriptor: + pass + + class Metaclass(type): + attribute = Descriptor() + + class Class(metaclass=Metaclass): + attribute = True + + def __get__(self, instance, owner): + return False + + def __set__(self, instance, value): + return None + + def f(): + return Class.attribute + + for _ in range(1025): + self.assertTrue(f()) + + Descriptor.__get__ = __get__ + Descriptor.__set__ = __set__ + + for _ in range(1025): + self.assertFalse(f()) + + def test_metaclass_descriptor_shadows_class_attribute(self): + class Metaclass(type): + @property + def attribute(self): + return True + + class Class(metaclass=Metaclass): + attribute = False + + def f(): + return Class.attribute + + for _ in range(1025): + self.assertTrue(f()) + + def test_metaclass_set_descriptor_after_optimization(self): + class Metaclass(type): + pass + + class Class(metaclass=Metaclass): + attribute = True + + @property + def attribute(self): + return False + + def f(): + return Class.attribute + + for _ in range(1025): + self.assertTrue(f()) + + Metaclass.attribute = attribute + + for _ in range(1025): + self.assertFalse(f()) + + def test_metaclass_del_descriptor_after_optimization(self): + class Metaclass(type): + @property + def attribute(self): + return True + + class Class(metaclass=Metaclass): + attribute = False + + def f(): + return Class.attribute + + for _ in range(1025): + self.assertTrue(f()) + + del Metaclass.attribute + + for _ in range(1025): + self.assertFalse(f()) + + def test_type_descriptor_shadows_attribute_method(self): + class Class: + mro = None + + def f(): + return Class.mro + + for _ in range(1025): + self.assertIsNone(f()) + + def test_type_descriptor_shadows_attribute_member(self): + class Class: + __base__ = None + + def f(): + return Class.__base__ + + for _ in range(1025): + self.assertIs(f(), object) + + def test_type_descriptor_shadows_attribute_getset(self): + class Class: + __name__ = "Spam" + + def f(): + return Class.__name__ + + for _ in range(1025): + self.assertEqual(f(), "Class") + + def test_metaclass_getattribute(self): + class Metaclass(type): + def __getattribute__(self, name): + return True + + class Class(metaclass=Metaclass): + attribute = False + + def f(): + return Class.attribute + + for _ in range(1025): + self.assertTrue(f()) + + def test_metaclass_swap(self): + class OldMetaclass(type): + @property + def attribute(self): + return True + + class NewMetaclass(type): + @property + def attribute(self): + return False + + class Class(metaclass=OldMetaclass): + pass + + def f(): + return Class.attribute + + for _ in range(1025): + self.assertTrue(f()) + + Class.__class__ = NewMetaclass + + for _ in range(1025): + self.assertFalse(f()) + + def test_load_shadowing_slot_should_raise_type_error(self): + class Class: + __slots__ = ("slot",) + + class Sneaky: + __slots__ = ("shadowed",) + shadowing = Class.slot + + def f(o): + o.shadowing + + o = Sneaky() + o.shadowed = 42 + + for _ in range(1025): + with self.assertRaises(TypeError): + f(o) + + def test_store_shadowing_slot_should_raise_type_error(self): + class Class: + __slots__ = ("slot",) + + class Sneaky: + __slots__ = ("shadowed",) + shadowing = Class.slot + + def f(o): + o.shadowing = 42 + + o = Sneaky() + + for _ in range(1025): + with self.assertRaises(TypeError): + f(o) + + def test_load_borrowed_slot_should_not_crash(self): + class Class: + __slots__ = ("slot",) + + class Sneaky: + borrowed = Class.slot + + def f(o): + o.borrowed + + o = Sneaky() + + for _ in range(1025): + with self.assertRaises(TypeError): + f(o) + + def test_store_borrowed_slot_should_not_crash(self): + class Class: + __slots__ = ("slot",) + + class Sneaky: + borrowed = Class.slot + + def f(o): + o.borrowed = 42 + + o = Sneaky() + + for _ in range(1025): + with self.assertRaises(TypeError): + f(o) + + +class TestLoadMethodCache(unittest.TestCase): + def test_descriptor_added_after_optimization(self): + class Descriptor: + pass + + class Class: + attribute = Descriptor() + + def __get__(self, instance, owner): + return lambda: False + + def __set__(self, instance, value): + return None + + def attribute(): + return True + + instance = Class() + instance.attribute = attribute + + def f(): + return instance.attribute() + + for _ in range(1025): + self.assertTrue(f()) + + Descriptor.__get__ = __get__ + Descriptor.__set__ = __set__ + + for _ in range(1025): + self.assertFalse(f()) + + def test_metaclass_descriptor_added_after_optimization(self): + class Descriptor: + pass + + class Metaclass(type): + attribute = Descriptor() + + class Class(metaclass=Metaclass): + def attribute(): + return True + + def __get__(self, instance, owner): + return lambda: False + + def __set__(self, instance, value): + return None + + def f(): + return Class.attribute() + + for _ in range(1025): + self.assertTrue(f()) + + Descriptor.__get__ = __get__ + Descriptor.__set__ = __set__ + + for _ in range(1025): + self.assertFalse(f()) + + def test_metaclass_descriptor_shadows_class_attribute(self): + class Metaclass(type): + @property + def attribute(self): + return lambda: True + + class Class(metaclass=Metaclass): + def attribute(): + return False + + def f(): + return Class.attribute() + + for _ in range(1025): + self.assertTrue(f()) + + def test_metaclass_set_descriptor_after_optimization(self): + class Metaclass(type): + pass + + class Class(metaclass=Metaclass): + def attribute(): + return True + + @property + def attribute(self): + return lambda: False + + def f(): + return Class.attribute() + + for _ in range(1025): + self.assertTrue(f()) + + Metaclass.attribute = attribute + + for _ in range(1025): + self.assertFalse(f()) + + def test_metaclass_del_descriptor_after_optimization(self): + class Metaclass(type): + @property + def attribute(self): + return lambda: True + + class Class(metaclass=Metaclass): + def attribute(): + return False + + def f(): + return Class.attribute() + + for _ in range(1025): + self.assertTrue(f()) + + del Metaclass.attribute + + for _ in range(1025): + self.assertFalse(f()) + + def test_type_descriptor_shadows_attribute_method(self): + class Class: + def mro(): + return ["Spam", "eggs"] + + def f(): + return Class.mro() + + for _ in range(1025): + self.assertEqual(f(), ["Spam", "eggs"]) + + def test_type_descriptor_shadows_attribute_member(self): + class Class: + def __base__(): + return "Spam" + + def f(): + return Class.__base__() + + for _ in range(1025): + self.assertNotEqual(f(), "Spam") + + def test_metaclass_getattribute(self): + class Metaclass(type): + def __getattribute__(self, name): + return lambda: True + + class Class(metaclass=Metaclass): + def attribute(): + return False + + def f(): + return Class.attribute() + + for _ in range(1025): + self.assertTrue(f()) + + def test_metaclass_swap(self): + class OldMetaclass(type): + @property + def attribute(self): + return lambda: True + + class NewMetaclass(type): + @property + def attribute(self): + return lambda: False + + class Class(metaclass=OldMetaclass): + pass + + def f(): + return Class.attribute() + + for _ in range(1025): + self.assertTrue(f()) + + Class.__class__ = NewMetaclass + + for _ in range(1025): + self.assertFalse(f()) + + +if __name__ == "__main__": + import unittest + unittest.main() diff --git a/Lib/test/test_ordered_dict.py b/Lib/test/test_ordered_dict.py index d51296a2d12..37447fd249b 100644 --- a/Lib/test/test_ordered_dict.py +++ b/Lib/test/test_ordered_dict.py @@ -287,6 +287,8 @@ class OrderedDictTests: # and have a repr/eval round-trip pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] od = OrderedDict(pairs) + od.x = ['x'] + od.z = ['z'] def check(dup): msg = "\ncopy: %s\nod: %s" % (dup, od) self.assertIsNot(dup, od, msg) @@ -295,13 +297,27 @@ class OrderedDictTests: self.assertEqual(len(dup), len(od)) self.assertEqual(type(dup), type(od)) check(od.copy()) - check(copy.copy(od)) - check(copy.deepcopy(od)) + dup = copy.copy(od) + check(dup) + self.assertIs(dup.x, od.x) + self.assertIs(dup.z, od.z) + self.assertFalse(hasattr(dup, 'y')) + dup = copy.deepcopy(od) + check(dup) + self.assertEqual(dup.x, od.x) + self.assertIsNot(dup.x, od.x) + self.assertEqual(dup.z, od.z) + self.assertIsNot(dup.z, od.z) + self.assertFalse(hasattr(dup, 'y')) # pickle directly pulls the module, so we have to fake it with replaced_module('collections', self.module): for proto in range(pickle.HIGHEST_PROTOCOL + 1): with self.subTest(proto=proto): - check(pickle.loads(pickle.dumps(od, proto))) + dup = pickle.loads(pickle.dumps(od, proto)) + check(dup) + self.assertEqual(dup.x, od.x) + self.assertEqual(dup.z, od.z) + self.assertFalse(hasattr(dup, 'y')) check(eval(repr(od))) update_test = OrderedDict() update_test.update(od) @@ -846,6 +862,23 @@ class CPythonOrderedDictSubclassTests(CPythonOrderedDictTests): pass +class PurePythonOrderedDictWithSlotsCopyingTests(unittest.TestCase): + + module = py_coll + class OrderedDict(py_coll.OrderedDict): + __slots__ = ('x', 'y') + test_copying = OrderedDictTests.test_copying + + +@unittest.skipUnless(c_coll, 'requires the C version of the collections module') +class CPythonOrderedDictWithSlotsCopyingTests(unittest.TestCase): + + module = c_coll + class OrderedDict(c_coll.OrderedDict): + __slots__ = ('x', 'y') + test_copying = OrderedDictTests.test_copying + + class PurePythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol): @classmethod diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 5e153405156..58e04dd1348 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -2,6 +2,7 @@ # does add tests for a few functions which have been determined to be more # portable than they had been thought to be. +import asyncio import codecs import contextlib import decimal @@ -10,7 +11,6 @@ import fnmatch import fractions import itertools import locale -import mmap import os import pickle import select @@ -23,19 +23,17 @@ import subprocess import sys import sysconfig import tempfile -import threading +import textwrap import time import types import unittest import uuid import warnings from test import support -from test.support import _asynchat as asynchat -from test.support import _asyncore as asyncore from test.support import import_helper from test.support import os_helper from test.support import socket_helper -from test.support import threading_helper +from test.support import set_recursion_limit from test.support import warnings_helper from platform import win32_is_iot @@ -61,6 +59,10 @@ try: except ImportError: INT_MAX = PY_SSIZE_T_MAX = sys.maxsize +try: + import mmap +except ImportError: + mmap = None from test.support.script_helper import assert_python_ok from test.support import unix_shell @@ -98,6 +100,10 @@ requires_splice_pipe = unittest.skipIf(sys.platform.startswith("aix"), 'on AIX, splice() only accepts sockets') +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + class MiscTests(unittest.TestCase): def test_getcwd(self): cwd = os.getcwd() @@ -178,6 +184,12 @@ class FileTests(unittest.TestCase): os.close(f) self.assertTrue(os.access(os_helper.TESTFN, os.W_OK)) + @unittest.skipIf( + support.is_emscripten, "Test is unstable under Emscripten." + ) + @unittest.skipIf( + support.is_wasi, "WASI does not support dup." + ) def test_closerange(self): first = os.open(os_helper.TESTFN, os.O_CREAT|os.O_RDWR) # We must allocate two consecutive file descriptors, otherwise @@ -595,12 +607,13 @@ class StatAttributeTests(unittest.TestCase): def test_stat_result_pickle(self): result = os.stat(self.fname) for proto in range(pickle.HIGHEST_PROTOCOL + 1): - p = pickle.dumps(result, proto) - self.assertIn(b'stat_result', p) - if proto < 4: - self.assertIn(b'cos\nstat_result\n', p) - unpickled = pickle.loads(p) - self.assertEqual(result, unpickled) + with self.subTest(f'protocol {proto}'): + p = pickle.dumps(result, proto) + self.assertIn(b'stat_result', p) + if proto < 4: + self.assertIn(b'cos\nstat_result\n', p) + unpickled = pickle.loads(p) + self.assertEqual(result, unpickled) @unittest.skipUnless(hasattr(os, 'statvfs'), 'test needs os.statvfs()') def test_statvfs_attributes(self): @@ -845,12 +858,9 @@ class UtimeTests(unittest.TestCase): def test_utime_dir_fd(self): def set_time(filename, ns): dirname, name = os.path.split(filename) - dirfd = os.open(dirname, os.O_RDONLY) - try: + with os_helper.open_dir_fd(dirname) as dirfd: # pass dir_fd to test utimensat(timespec) or futimesat(timeval) os.utime(name, dir_fd=dirfd, ns=ns) - finally: - os.close(dirfd) self._test_utime(set_time) def test_utime_directory(self): @@ -992,6 +1002,7 @@ class EnvironTests(mapping_tests.BasicTestMappingProtocol): @unittest.skipUnless(unix_shell and os.path.exists(unix_shell), 'requires a shell') @unittest.skipUnless(hasattr(os, 'popen'), "needs os.popen()") + @support.requires_subprocess() def test_update2(self): os.environ.clear() os.environ.update(HELLO="World") @@ -1002,6 +1013,7 @@ class EnvironTests(mapping_tests.BasicTestMappingProtocol): @unittest.skipUnless(unix_shell and os.path.exists(unix_shell), 'requires a shell') @unittest.skipUnless(hasattr(os, 'popen'), "needs os.popen()") + @support.requires_subprocess() def test_os_popen_iter(self): with os.popen("%s -c 'echo \"line1\nline2\nline3\"'" % unix_shell) as popen: @@ -1096,6 +1108,7 @@ class EnvironTests(mapping_tests.BasicTestMappingProtocol): value_str = value.decode(sys.getfilesystemencoding(), 'surrogateescape') self.assertEqual(os.environ['bytes'], value_str) + @support.requires_subprocess() def test_putenv_unsetenv(self): name = "PYTHONTESTVAR" value = "testvalue" @@ -1172,6 +1185,8 @@ class EnvironTests(mapping_tests.BasicTestMappingProtocol): def _test_underlying_process_env(self, var, expected): if not (unix_shell and os.path.exists(unix_shell)): return + elif not support.has_subprocess_support: + return with os.popen(f"{unix_shell} -c 'echo ${var}'") as popen: value = popen.read().strip() @@ -1328,7 +1343,9 @@ class WalkTests(unittest.TestCase): else: self.sub2_tree = (sub2_path, ["SUB21"], ["tmp3"]) - os.chmod(sub21_path, 0) + if not support.is_emscripten: + # Emscripten fails with inaccessible directory + os.chmod(sub21_path, 0) try: os.listdir(sub21_path) except PermissionError: @@ -1455,6 +1472,46 @@ class WalkTests(unittest.TestCase): self.assertEqual(next(it), expected) p = os.path.join(p, 'd') + def test_walk_above_recursion_limit(self): + depth = 50 + os.makedirs(os.path.join(self.walk_path, *(['d'] * depth))) + with set_recursion_limit(depth - 5): + all = list(self.walk(self.walk_path)) + + sub2_path = self.sub2_tree[0] + for root, dirs, files in all: + if root == sub2_path: + dirs.sort() + files.sort() + + d_entries = [] + d_path = self.walk_path + for _ in range(depth): + d_path = os.path.join(d_path, "d") + d_entries.append((d_path, ["d"], [])) + d_entries[-1][1].clear() + + # Sub-sequences where the order is known + sections = { + "SUB1": [ + (self.sub1_path, ["SUB11"], ["tmp2"]), + (self.sub11_path, [], []), + ], + "SUB2": [self.sub2_tree], + "d": d_entries, + } + + # The ordering of sub-dirs is arbitrary but determines the order in + # which sub-sequences appear + dirs = all[0][1] + expected = [(self.walk_path, dirs, ["tmp1"])] + for d in dirs: + expected.extend(sections[d]) + + self.assertEqual(len(all), depth + 4) + self.assertEqual(sorted(dirs), ["SUB1", "SUB2", "d"]) + self.assertEqual(all, expected) + @unittest.skipUnless(hasattr(os, 'fwalk'), "Test needs os.fwalk()") class FwalkTests(WalkTests): @@ -1511,6 +1568,9 @@ class FwalkTests(WalkTests): # check that listdir() returns consistent information self.assertEqual(set(os.listdir(rootfd)), set(dirs) | set(files)) + @unittest.skipIf( + support.is_emscripten, "Cannot dup stdout on Emscripten" + ) def test_fd_leak(self): # Since we're opening a lot of FDs, we must be careful to avoid leaks: # we both check that calling fwalk() a large number of times doesn't @@ -1526,6 +1586,8 @@ class FwalkTests(WalkTests): # fwalk() keeps file descriptors open test_walk_many_open_files = None + # fwalk() still uses recursion + test_walk_above_recursion_limit = None class BytesWalkTests(WalkTests): @@ -1573,6 +1635,10 @@ class MakedirTests(unittest.TestCase): 'dir5', 'dir6') os.makedirs(path) + @unittest.skipIf( + support.is_emscripten or support.is_wasi, + "Emscripten's/WASI's umask is a stub." + ) def test_mode(self): with os_helper.temp_umask(0o002): base = os_helper.TESTFN @@ -1585,6 +1651,10 @@ class MakedirTests(unittest.TestCase): self.assertEqual(os.stat(path).st_mode & 0o777, 0o555) self.assertEqual(os.stat(parent).st_mode & 0o777, 0o775) + @unittest.skipIf( + support.is_emscripten or support.is_wasi, + "Emscripten's/WASI's umask is a stub." + ) def test_exist_ok_existing_directory(self): path = os.path.join(os_helper.TESTFN, 'dir1') mode = 0o777 @@ -1599,6 +1669,10 @@ class MakedirTests(unittest.TestCase): # Issue #25583: A drive root could raise PermissionError on Windows os.makedirs(os.path.abspath('/'), exist_ok=True) + @unittest.skipIf( + support.is_emscripten or support.is_wasi, + "Emscripten's/WASI's umask is a stub." + ) def test_exist_ok_s_isgid_directory(self): path = os.path.join(os_helper.TESTFN, 'dir1') S_ISGID = stat.S_ISGID @@ -1648,7 +1722,7 @@ class MakedirTests(unittest.TestCase): os.removedirs(path) -@unittest.skipUnless(hasattr(os, 'chown'), "Test needs chown") +@os_helper.skip_unless_working_chmod class ChownFileTests(unittest.TestCase): @classmethod @@ -1749,6 +1823,7 @@ class RemoveDirsTests(unittest.TestCase): self.assertTrue(os.path.exists(os_helper.TESTFN)) +@unittest.skipIf(support.is_wasi, "WASI has no /dev/null") class DevNullTests(unittest.TestCase): def test_devnull(self): with open(os.devnull, 'wb', 0) as f: @@ -2095,6 +2170,7 @@ class Win32ErrorTests(unittest.TestCase): self.assertRaises(OSError, os.chmod, os_helper.TESTFN, 0) +@unittest.skipIf(support.is_wasi, "Cannot create invalid FD on WASI.") class TestInvalidFD(unittest.TestCase): singles = ["fchdir", "dup", "fdatasync", "fstat", "fstatvfs", "fsync", "tcgetpgrp", "ttyname"] @@ -2153,6 +2229,10 @@ class TestInvalidFD(unittest.TestCase): self.check(os.fchown, -1, -1) @unittest.skipUnless(hasattr(os, 'fpathconf'), 'test needs os.fpathconf()') + @unittest.skipIf( + support.is_emscripten or support.is_wasi, + "musl libc issue on Emscripten/WASI, bpo-46390" + ) def test_fpathconf(self): self.check(os.pathconf, "PC_NAME_MAX") self.check(os.fpathconf, "PC_NAME_MAX") @@ -2187,6 +2267,7 @@ class TestInvalidFD(unittest.TestCase): def test_writev(self): self.check(os.writev, [b'abc']) + @support.requires_subprocess() def test_inheritable(self): self.check(os.get_inheritable) self.check(os.set_inheritable, True) @@ -2198,6 +2279,7 @@ class TestInvalidFD(unittest.TestCase): self.check(os.set_blocking, True) +@unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') class LinkTests(unittest.TestCase): def setUp(self): self.file1 = os_helper.TESTFN @@ -2279,6 +2361,7 @@ class PosixUidGidTests(unittest.TestCase): self.assertRaises(OverflowError, os.setreuid, 0, self.UID_OVERFLOW) @unittest.skipUnless(hasattr(os, 'setreuid'), 'test needs os.setreuid()') + @support.requires_subprocess() def test_setreuid_neg1(self): # Needs to accept -1. We run this in a subprocess to avoid # altering the test runner's process state (issue8045). @@ -2287,6 +2370,7 @@ class PosixUidGidTests(unittest.TestCase): 'import os,sys;os.setreuid(-1,-1);sys.exit(0)']) @unittest.skipUnless(hasattr(os, 'setregid'), 'test needs os.setregid()') + @support.requires_subprocess() def test_setregid(self): if os.getuid() != 0 and not HAVE_WHEEL_GROUP: self.assertRaises(OSError, os.setregid, 0, 0) @@ -2296,6 +2380,7 @@ class PosixUidGidTests(unittest.TestCase): self.assertRaises(OverflowError, os.setregid, 0, self.GID_OVERFLOW) @unittest.skipUnless(hasattr(os, 'setregid'), 'test needs os.setregid()') + @support.requires_subprocess() def test_setregid_neg1(self): # Needs to accept -1. We run this in a subprocess to avoid # altering the test runner's process state (issue8045). @@ -2439,6 +2524,7 @@ class Win32KillTests(unittest.TestCase): # os.kill on Windows can take an int which gets set as the exit code self._kill(100) + @unittest.skipIf(mmap is None, "requires mmap") def _kill_with_event(self, event, name): tagname = "test_os_%s" % uuid.uuid1() m = mmap.mmap(-1, 1, tagname) @@ -2469,6 +2555,7 @@ class Win32KillTests(unittest.TestCase): self.fail("subprocess did not stop on {}".format(name)) @unittest.skip("subprocesses aren't inheriting Ctrl+C property") + @support.requires_subprocess() def test_CTRL_C_EVENT(self): from ctypes import wintypes import ctypes @@ -2487,6 +2574,7 @@ class Win32KillTests(unittest.TestCase): self._kill_with_event(signal.CTRL_C_EVENT, "CTRL_C_EVENT") + @support.requires_subprocess() def test_CTRL_BREAK_EVENT(self): self._kill_with_event(signal.CTRL_BREAK_EVENT, "CTRL_BREAK_EVENT") @@ -2861,6 +2949,49 @@ class Win32NtTests(unittest.TestCase): self.assertEqual(0, handle_delta) + @support.requires_subprocess() + def test_stat_unlink_race(self): + # bpo-46785: the implementation of os.stat() falls back to reading + # the parent directory if CreateFileW() fails with a permission + # error. If reading the parent directory fails because the file or + # directory are subsequently unlinked, or because the volume or + # share are no longer available, then the original permission error + # should not be restored. + filename = os_helper.TESTFN + self.addCleanup(os_helper.unlink, filename) + deadline = time.time() + 5 + command = textwrap.dedent("""\ + import os + import sys + import time + + filename = sys.argv[1] + deadline = float(sys.argv[2]) + + while time.time() < deadline: + try: + with open(filename, "w") as f: + pass + except OSError: + pass + try: + os.remove(filename) + except OSError: + pass + """) + + with subprocess.Popen([sys.executable, '-c', command, filename, str(deadline)]) as proc: + while time.time() < deadline: + try: + os.stat(filename) + except FileNotFoundError as e: + assert e.winerror == 2 # ERROR_FILE_NOT_FOUND + try: + proc.wait(1) + except subprocess.TimeoutExpired: + proc.terminate() + + @os_helper.skip_unless_symlink class NonLocalSymlinkTests(unittest.TestCase): @@ -2918,12 +3049,16 @@ class DeviceEncodingTests(unittest.TestCase): @unittest.skipUnless(os.isatty(0) and not win32_is_iot() and (sys.platform.startswith('win') or (hasattr(locale, 'nl_langinfo') and hasattr(locale, 'CODESET'))), 'test requires a tty and either Windows or nl_langinfo(CODESET)') + @unittest.skipIf( + support.is_emscripten, "Cannot get encoding of stdin on Emscripten" + ) def test_device_encoding(self): encoding = os.device_encoding(0) self.assertIsNotNone(encoding) self.assertTrue(codecs.lookup(encoding)) +@support.requires_subprocess() class PidTests(unittest.TestCase): @unittest.skipUnless(hasattr(os, 'getppid'), "test needs os.getppid") def test_getppid(self): @@ -2996,6 +3131,7 @@ class PidTests(unittest.TestCase): self.check_waitpid(code, exitcode=-signum, callback=kill_process) +@support.requires_subprocess() class SpawnTests(unittest.TestCase): def create_args(self, *, with_env=False, use_bytes=False): self.exitcode = 17 @@ -3207,94 +3343,8 @@ class ProgramPriorityTests(unittest.TestCase): raise -class SendfileTestServer(asyncore.dispatcher, threading.Thread): - - class Handler(asynchat.async_chat): - - def __init__(self, conn): - asynchat.async_chat.__init__(self, conn) - self.in_buffer = [] - self.accumulate = True - self.closed = False - self.push(b"220 ready\r\n") - - def handle_read(self): - data = self.recv(4096) - if self.accumulate: - self.in_buffer.append(data) - - def get_data(self): - return b''.join(self.in_buffer) - - def handle_close(self): - self.close() - self.closed = True - - def handle_error(self): - raise - - def __init__(self, address): - threading.Thread.__init__(self) - asyncore.dispatcher.__init__(self) - self.create_socket(socket.AF_INET, socket.SOCK_STREAM) - self.bind(address) - self.listen(5) - self.host, self.port = self.socket.getsockname()[:2] - self.handler_instance = None - self._active = False - self._active_lock = threading.Lock() - - # --- public API - - @property - def running(self): - return self._active - - def start(self): - assert not self.running - self.__flag = threading.Event() - threading.Thread.start(self) - self.__flag.wait() - - def stop(self): - assert self.running - self._active = False - self.join() - - def wait(self): - # wait for handler connection to be closed, then stop the server - while not getattr(self.handler_instance, "closed", False): - time.sleep(0.001) - self.stop() - - # --- internals - - def run(self): - self._active = True - self.__flag.set() - while self._active and asyncore.socket_map: - self._active_lock.acquire() - asyncore.loop(timeout=0.001, count=1) - self._active_lock.release() - asyncore.close_all() - - def handle_accept(self): - conn, addr = self.accept() - self.handler_instance = self.Handler(conn) - - def handle_connect(self): - self.close() - handle_read = handle_connect - - def writable(self): - return 0 - - def handle_error(self): - raise - - @unittest.skipUnless(hasattr(os, 'sendfile'), "test needs os.sendfile()") -class TestSendfile(unittest.TestCase): +class TestSendfile(unittest.IsolatedAsyncioTestCase): DATA = b"12345abcde" * 16 * 1024 # 160 KiB SUPPORT_HEADERS_TRAILERS = not sys.platform.startswith("linux") and \ @@ -3307,40 +3357,52 @@ class TestSendfile(unittest.TestCase): @classmethod def setUpClass(cls): - cls.key = threading_helper.threading_setup() create_file(os_helper.TESTFN, cls.DATA) @classmethod def tearDownClass(cls): - threading_helper.threading_cleanup(*cls.key) os_helper.unlink(os_helper.TESTFN) - def setUp(self): - self.server = SendfileTestServer((socket_helper.HOST, 0)) - self.server.start() + @staticmethod + async def chunks(reader): + while not reader.at_eof(): + yield await reader.read() + + async def handle_new_client(self, reader, writer): + self.server_buffer = b''.join([x async for x in self.chunks(reader)]) + writer.close() + self.server.close() # The test server processes a single client only + + async def asyncSetUp(self): + self.server_buffer = b'' + self.server = await asyncio.start_server(self.handle_new_client, + socket_helper.HOSTv4) + server_name = self.server.sockets[0].getsockname() self.client = socket.socket() - self.client.connect((self.server.host, self.server.port)) - self.client.settimeout(1) - # synchronize by waiting for "220 ready" response - self.client.recv(1024) + self.client.setblocking(False) + await asyncio.get_running_loop().sock_connect(self.client, server_name) self.sockno = self.client.fileno() self.file = open(os_helper.TESTFN, 'rb') self.fileno = self.file.fileno() - def tearDown(self): + async def asyncTearDown(self): self.file.close() self.client.close() - if self.server.running: - self.server.stop() - self.server = None + await self.server.wait_closed() - def sendfile_wrapper(self, *args, **kwargs): + # Use the test subject instead of asyncio.loop.sendfile + @staticmethod + async def async_sendfile(*args, **kwargs): + return await asyncio.to_thread(os.sendfile, *args, **kwargs) + + @staticmethod + async def sendfile_wrapper(*args, **kwargs): """A higher level wrapper representing how an application is supposed to use sendfile(). """ while True: try: - return os.sendfile(*args, **kwargs) + return await TestSendfile.async_sendfile(*args, **kwargs) except OSError as err: if err.errno == errno.ECONNRESET: # disconnected @@ -3351,13 +3413,14 @@ class TestSendfile(unittest.TestCase): else: raise - def test_send_whole_file(self): + async def test_send_whole_file(self): # normal send total_sent = 0 offset = 0 nbytes = 4096 while total_sent < len(self.DATA): - sent = self.sendfile_wrapper(self.sockno, self.fileno, offset, nbytes) + sent = await self.sendfile_wrapper(self.sockno, self.fileno, + offset, nbytes) if sent == 0: break offset += sent @@ -3368,19 +3431,19 @@ class TestSendfile(unittest.TestCase): self.assertEqual(total_sent, len(self.DATA)) self.client.shutdown(socket.SHUT_RDWR) self.client.close() - self.server.wait() - data = self.server.handler_instance.get_data() - self.assertEqual(len(data), len(self.DATA)) - self.assertEqual(data, self.DATA) + await self.server.wait_closed() + self.assertEqual(len(self.server_buffer), len(self.DATA)) + self.assertEqual(self.server_buffer, self.DATA) - def test_send_at_certain_offset(self): + async def test_send_at_certain_offset(self): # start sending a file at a certain offset total_sent = 0 offset = len(self.DATA) // 2 must_send = len(self.DATA) - offset nbytes = 4096 while total_sent < must_send: - sent = self.sendfile_wrapper(self.sockno, self.fileno, offset, nbytes) + sent = await self.sendfile_wrapper(self.sockno, self.fileno, + offset, nbytes) if sent == 0: break offset += sent @@ -3389,18 +3452,18 @@ class TestSendfile(unittest.TestCase): self.client.shutdown(socket.SHUT_RDWR) self.client.close() - self.server.wait() - data = self.server.handler_instance.get_data() + await self.server.wait_closed() expected = self.DATA[len(self.DATA) // 2:] self.assertEqual(total_sent, len(expected)) - self.assertEqual(len(data), len(expected)) - self.assertEqual(data, expected) + self.assertEqual(len(self.server_buffer), len(expected)) + self.assertEqual(self.server_buffer, expected) - def test_offset_overflow(self): + async def test_offset_overflow(self): # specify an offset > file size offset = len(self.DATA) + 4096 try: - sent = os.sendfile(self.sockno, self.fileno, offset, 4096) + sent = await self.async_sendfile(self.sockno, self.fileno, + offset, 4096) except OSError as e: # Solaris can raise EINVAL if offset >= file length, ignore. if e.errno != errno.EINVAL: @@ -3409,39 +3472,38 @@ class TestSendfile(unittest.TestCase): self.assertEqual(sent, 0) self.client.shutdown(socket.SHUT_RDWR) self.client.close() - self.server.wait() - data = self.server.handler_instance.get_data() - self.assertEqual(data, b'') + await self.server.wait_closed() + self.assertEqual(self.server_buffer, b'') - def test_invalid_offset(self): + async def test_invalid_offset(self): with self.assertRaises(OSError) as cm: - os.sendfile(self.sockno, self.fileno, -1, 4096) + await self.async_sendfile(self.sockno, self.fileno, -1, 4096) self.assertEqual(cm.exception.errno, errno.EINVAL) - def test_keywords(self): + async def test_keywords(self): # Keyword arguments should be supported - os.sendfile(out_fd=self.sockno, in_fd=self.fileno, - offset=0, count=4096) + await self.async_sendfile(out_fd=self.sockno, in_fd=self.fileno, + offset=0, count=4096) if self.SUPPORT_HEADERS_TRAILERS: - os.sendfile(out_fd=self.sockno, in_fd=self.fileno, - offset=0, count=4096, - headers=(), trailers=(), flags=0) + await self.async_sendfile(out_fd=self.sockno, in_fd=self.fileno, + offset=0, count=4096, + headers=(), trailers=(), flags=0) # --- headers / trailers tests @requires_headers_trailers - def test_headers(self): + async def test_headers(self): total_sent = 0 expected_data = b"x" * 512 + b"y" * 256 + self.DATA[:-1] - sent = os.sendfile(self.sockno, self.fileno, 0, 4096, - headers=[b"x" * 512, b"y" * 256]) + sent = await self.async_sendfile(self.sockno, self.fileno, 0, 4096, + headers=[b"x" * 512, b"y" * 256]) self.assertLessEqual(sent, 512 + 256 + 4096) total_sent += sent offset = 4096 while total_sent < len(expected_data): nbytes = min(len(expected_data) - total_sent, 4096) - sent = self.sendfile_wrapper(self.sockno, self.fileno, - offset, nbytes) + sent = await self.sendfile_wrapper(self.sockno, self.fileno, + offset, nbytes) if sent == 0: break self.assertLessEqual(sent, nbytes) @@ -3450,12 +3512,11 @@ class TestSendfile(unittest.TestCase): self.assertEqual(total_sent, len(expected_data)) self.client.close() - self.server.wait() - data = self.server.handler_instance.get_data() - self.assertEqual(hash(data), hash(expected_data)) + await self.server.wait_closed() + self.assertEqual(hash(self.server_buffer), hash(expected_data)) @requires_headers_trailers - def test_trailers(self): + async def test_trailers(self): TESTFN2 = os_helper.TESTFN + "2" file_data = b"abcdef" @@ -3463,38 +3524,37 @@ class TestSendfile(unittest.TestCase): create_file(TESTFN2, file_data) with open(TESTFN2, 'rb') as f: - os.sendfile(self.sockno, f.fileno(), 0, 5, - trailers=[b"123456", b"789"]) + await self.async_sendfile(self.sockno, f.fileno(), 0, 5, + trailers=[b"123456", b"789"]) self.client.close() - self.server.wait() - data = self.server.handler_instance.get_data() - self.assertEqual(data, b"abcde123456789") + await self.server.wait_closed() + self.assertEqual(self.server_buffer, b"abcde123456789") @requires_headers_trailers @requires_32b - def test_headers_overflow_32bits(self): + async def test_headers_overflow_32bits(self): self.server.handler_instance.accumulate = False with self.assertRaises(OSError) as cm: - os.sendfile(self.sockno, self.fileno, 0, 0, - headers=[b"x" * 2**16] * 2**15) + await self.async_sendfile(self.sockno, self.fileno, 0, 0, + headers=[b"x" * 2**16] * 2**15) self.assertEqual(cm.exception.errno, errno.EINVAL) @requires_headers_trailers @requires_32b - def test_trailers_overflow_32bits(self): + async def test_trailers_overflow_32bits(self): self.server.handler_instance.accumulate = False with self.assertRaises(OSError) as cm: - os.sendfile(self.sockno, self.fileno, 0, 0, - trailers=[b"x" * 2**16] * 2**15) + await self.async_sendfile(self.sockno, self.fileno, 0, 0, + trailers=[b"x" * 2**16] * 2**15) self.assertEqual(cm.exception.errno, errno.EINVAL) @requires_headers_trailers @unittest.skipUnless(hasattr(os, 'SF_NODISKIO'), 'test needs os.SF_NODISKIO') - def test_flags(self): + async def test_flags(self): try: - os.sendfile(self.sockno, self.fileno, 0, 4096, - flags=os.SF_NODISKIO) + await self.async_sendfile(self.sockno, self.fileno, 0, 4096, + flags=os.SF_NODISKIO) except OSError as err: if err.errno not in (errno.EBUSY, errno.EAGAIN): raise @@ -3649,6 +3709,19 @@ class TermsizeTests(unittest.TestCase): raise self.assertEqual(expected, actual) + @unittest.skipUnless(sys.platform == 'win32', 'Windows specific test') + def test_windows_fd(self): + """Check if get_terminal_size() returns a meaningful value in Windows""" + try: + conout = open('conout$', 'w') + except OSError: + self.skipTest('failed to open conout$') + with conout: + size = os.get_terminal_size(conout.fileno()) + + self.assertGreaterEqual(size.columns, 0) + self.assertGreaterEqual(size.lines, 0) + @unittest.skipUnless(hasattr(os, 'memfd_create'), 'requires os.memfd_create') @support.requires_linux_version(3, 17) @@ -3768,35 +3841,23 @@ class OSErrorTests(unittest.TestCase): else: encoded = os.fsencode(os_helper.TESTFN) self.bytes_filenames.append(encoded) - self.bytes_filenames.append(bytearray(encoded)) - self.bytes_filenames.append(memoryview(encoded)) self.filenames = self.bytes_filenames + self.unicode_filenames def test_oserror_filename(self): funcs = [ (self.filenames, os.chdir,), - (self.filenames, os.chmod, 0o777), (self.filenames, os.lstat,), (self.filenames, os.open, os.O_RDONLY), (self.filenames, os.rmdir,), (self.filenames, os.stat,), (self.filenames, os.unlink,), + (self.filenames, os.listdir,), + (self.filenames, os.rename, "dst"), + (self.filenames, os.replace, "dst"), ] - if sys.platform == "win32": - funcs.extend(( - (self.bytes_filenames, os.rename, b"dst"), - (self.bytes_filenames, os.replace, b"dst"), - (self.unicode_filenames, os.rename, "dst"), - (self.unicode_filenames, os.replace, "dst"), - (self.unicode_filenames, os.listdir, ), - )) - else: - funcs.extend(( - (self.filenames, os.listdir,), - (self.filenames, os.rename, "dst"), - (self.filenames, os.replace, "dst"), - )) + if os_helper.can_chmod(): + funcs.append((self.filenames, os.chmod, 0o777)) if hasattr(os, "chown"): funcs.append((self.filenames, os.chown, 0, 0)) if hasattr(os, "lchown"): @@ -3810,11 +3871,7 @@ class OSErrorTests(unittest.TestCase): if hasattr(os, "chroot"): funcs.append((self.filenames, os.chroot,)) if hasattr(os, "link"): - if sys.platform == "win32": - funcs.append((self.bytes_filenames, os.link, b"dst")) - funcs.append((self.unicode_filenames, os.link, "dst")) - else: - funcs.append((self.filenames, os.link, "dst")) + funcs.append((self.filenames, os.link, "dst")) if hasattr(os, "listxattr"): funcs.extend(( (self.filenames, os.listxattr,), @@ -3827,21 +3884,16 @@ class OSErrorTests(unittest.TestCase): if hasattr(os, "readlink"): funcs.append((self.filenames, os.readlink,)) - for filenames, func, *func_args in funcs: for name in filenames: try: - if isinstance(name, (str, bytes)): - func(name, *func_args) - else: - with self.assertWarnsRegex(DeprecationWarning, 'should be'): - func(name, *func_args) + func(name, *func_args) except OSError as err: self.assertIs(err.filename, name, str(func)) except UnicodeDecodeError: pass else: - self.fail("No exception thrown by {}".format(func)) + self.fail(f"No exception thrown by {func}") class CPUCountTests(unittest.TestCase): def test_cpu_count(self): @@ -3853,6 +3905,8 @@ class CPUCountTests(unittest.TestCase): self.skipTest("Could not determine the number of CPUs") +# FD inheritance check is only useful for systems with process support. +@support.requires_subprocess() class FDInheritanceTests(unittest.TestCase): def test_get_set_inheritable(self): fd = os.open(__file__, os.O_RDONLY) @@ -3983,7 +4037,7 @@ class PathTConverterTests(unittest.TestCase): ('access', False, (os.F_OK,), None), ('chflags', False, (0,), None), ('lchflags', False, (0,), None), - ('open', False, (0,), getattr(os, 'close', None)), + ('open', False, (os.O_RDONLY,), getattr(os, 'close', None)), ] def test_path_t_converter(self): @@ -4042,6 +4096,7 @@ class PathTConverterTests(unittest.TestCase): @unittest.skipUnless(hasattr(os, 'get_blocking'), 'needs os.get_blocking() and os.set_blocking()') +@unittest.skipIf(support.is_emscripten, "Cannot unset blocking flag") class BlockingTests(unittest.TestCase): def test_blocking(self): fd = os.open(__file__, os.O_RDONLY) @@ -4147,6 +4202,8 @@ class TestScandir(unittest.TestCase): self.assertEqual(entry.is_file(follow_symlinks=False), stat.S_ISREG(entry_lstat.st_mode)) + self.assertEqual(entry.is_junction(), os.path.isjunction(entry.path)) + self.assert_stat_equal(entry.stat(), entry_stat, os.name == 'nt' and not is_symlink) @@ -4195,6 +4252,21 @@ class TestScandir(unittest.TestCase): entry = entries['symlink_file.txt'] self.check_entry(entry, 'symlink_file.txt', False, True, True) + @unittest.skipIf(sys.platform != 'win32', "Can only test junctions with creation on win32.") + def test_attributes_junctions(self): + dirname = os.path.join(self.path, "tgtdir") + os.mkdir(dirname) + + import _winapi + try: + _winapi.CreateJunction(dirname, os.path.join(self.path, "srcjunc")) + except OSError: + raise unittest.SkipTest('creating the test junction failed') + + entries = self.get_entries(['srcjunc', 'tgtdir']) + self.assertEqual(entries['srcjunc'].is_junction(), True) + self.assertEqual(entries['tgtdir'].is_junction(), False) + def get_entry(self, name): path = self.bytes_path if isinstance(name, bytes) else self.path entries = list(os.scandir(path)) @@ -4317,16 +4389,8 @@ class TestScandir(unittest.TestCase): for cls in bytearray, memoryview: path_bytes = cls(os.fsencode(self.path)) - with self.assertWarns(DeprecationWarning): - entries = list(os.scandir(path_bytes)) - self.assertEqual(len(entries), 1, entries) - entry = entries[0] - - self.assertEqual(entry.name, b'file.txt') - self.assertEqual(entry.path, - os.fsencode(os.path.join(self.path, 'file.txt'))) - self.assertIs(type(entry.name), bytes) - self.assertIs(type(entry.path), bytes) + with self.assertRaises(TypeError): + os.scandir(path_bytes) @unittest.skipUnless(os.listdir in os.supports_fd, 'fd support for listdir required for this test.') @@ -4338,8 +4402,7 @@ class TestScandir(unittest.TestCase): os.symlink('file.txt', os.path.join(self.path, 'link')) expected_names.append('link') - fd = os.open(self.path, os.O_RDONLY) - try: + with os_helper.open_dir_fd(self.path) as fd: with os.scandir(fd) as it: entries = list(it) names = [entry.name for entry in entries] @@ -4354,9 +4417,8 @@ class TestScandir(unittest.TestCase): self.assertEqual(entry.stat(), st) st = os.stat(entry.name, dir_fd=fd, follow_symlinks=False) self.assertEqual(entry.stat(follow_symlinks=False), st) - finally: - os.close(fd) + @unittest.skipIf(support.is_wasi, "WASI maps '' to cwd") def test_empty_path(self): self.assertRaises(FileNotFoundError, os.scandir, '') @@ -4500,7 +4562,7 @@ class TimesTests(unittest.TestCase): self.assertEqual(times.elapsed, 0) -@requires_os_func('fork') +@support.requires_fork() class ForkTests(unittest.TestCase): def test_fork(self): # bpo-42540: ensure os.fork() with non-default memory allocator does @@ -4515,6 +4577,34 @@ class ForkTests(unittest.TestCase): assert_python_ok("-c", code) assert_python_ok("-c", code, PYTHONMALLOC="malloc_debug") + @unittest.skipUnless(sys.platform in ("linux", "darwin"), + "Only Linux and macOS detect this today.") + def test_fork_warns_when_non_python_thread_exists(self): + code = """if 1: + import os, threading, warnings + from _testcapi import _spawn_pthread_waiter, _end_spawned_pthread + _spawn_pthread_waiter() + try: + with warnings.catch_warnings(record=True) as ws: + warnings.filterwarnings( + "always", category=DeprecationWarning) + if os.fork() == 0: + assert not ws, f"unexpected warnings in child: {ws}" + os._exit(0) # child + else: + assert ws[0].category == DeprecationWarning, ws[0] + assert 'fork' in str(ws[0].message), ws[0] + # Waiting allows an error in the child to hit stderr. + exitcode = os.wait()[1] + assert exitcode == 0, f"child exited {exitcode}" + assert threading.active_count() == 1, threading.enumerate() + finally: + _end_spawned_pthread() + """ + _, out, err = assert_python_ok("-c", code, PYTHONOPTIMIZE='0') + self.assertEqual(err.decode("utf-8"), "") + self.assertEqual(out.decode("utf-8"), "") + # Only test if the C version is provided, otherwise TestPEP519 already tested # the pure Python implementation. diff --git a/Lib/test/test_ossaudiodev.py b/Lib/test/test_ossaudiodev.py index ebce3e9c272..2cc641a49b6 100644 --- a/Lib/test/test_ossaudiodev.py +++ b/Lib/test/test_ossaudiodev.py @@ -1,16 +1,19 @@ from test import support -from test.support import import_helper +from test.support import import_helper, warnings_helper +import warnings support.requires('audio') from test.support import findfile -ossaudiodev = import_helper.import_module('ossaudiodev') +with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + ossaudiodev = import_helper.import_module('ossaudiodev') +audioop = warnings_helper.import_deprecated('audioop') +sunau = warnings_helper.import_deprecated('sunau') import errno import sys -import sunau import time -import audioop import unittest # Arggh, AFMT_S16_NE not defined on all platforms -- seems to be a diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 5f6d9f47d13..a596795b44f 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -1,3 +1,4 @@ +import contextlib import collections.abc import io import os @@ -12,6 +13,7 @@ import unittest from unittest import mock from test.support import import_helper +from test.support import is_emscripten, is_wasi from test.support import os_helper from test.support.os_helper import TESTFN, FakePath @@ -24,7 +26,7 @@ except ImportError: class _BaseFlavourTest(object): def _check_parse_parts(self, arg, expected): - f = self.flavour.parse_parts + f = self.cls._parse_parts sep = self.flavour.sep altsep = self.flavour.altsep actual = f([x.replace('/', sep) for x in arg]) @@ -63,7 +65,8 @@ class _BaseFlavourTest(object): class PosixFlavourTest(_BaseFlavourTest, unittest.TestCase): - flavour = pathlib._posix_flavour + cls = pathlib.PurePosixPath + flavour = pathlib.PurePosixPath._flavour def test_parse_parts(self): check = self._check_parse_parts @@ -77,29 +80,10 @@ class PosixFlavourTest(_BaseFlavourTest, unittest.TestCase): check(['c:\\a'], ('', '', ['c:\\a'])) check(['\\a'], ('', '', ['\\a'])) - def test_splitroot(self): - f = self.flavour.splitroot - self.assertEqual(f(''), ('', '', '')) - self.assertEqual(f('a'), ('', '', 'a')) - self.assertEqual(f('a/b'), ('', '', 'a/b')) - self.assertEqual(f('a/b/'), ('', '', 'a/b/')) - self.assertEqual(f('/a'), ('', '/', 'a')) - self.assertEqual(f('/a/b'), ('', '/', 'a/b')) - self.assertEqual(f('/a/b/'), ('', '/', 'a/b/')) - # The root is collapsed when there are redundant slashes - # except when there are exactly two leading slashes, which - # is a special case in POSIX. - self.assertEqual(f('//a'), ('', '//', 'a')) - self.assertEqual(f('///a'), ('', '/', 'a')) - self.assertEqual(f('///a/b'), ('', '/', 'a/b')) - # Paths which look like NT paths aren't treated specially. - self.assertEqual(f('c:/a/b'), ('', '', 'c:/a/b')) - self.assertEqual(f('\\/a/b'), ('', '', '\\/a/b')) - self.assertEqual(f('\\a\\b'), ('', '', '\\a\\b')) - class NTFlavourTest(_BaseFlavourTest, unittest.TestCase): - flavour = pathlib._windows_flavour + cls = pathlib.PureWindowsPath + flavour = pathlib.PureWindowsPath._flavour def test_parse_parts(self): check = self._check_parse_parts @@ -134,30 +118,10 @@ class NTFlavourTest(_BaseFlavourTest, unittest.TestCase): check(['a', '/b', 'c'], ('', '\\', ['\\', 'b', 'c'])) check(['Z:/a', '/b', 'c'], ('Z:', '\\', ['Z:\\', 'b', 'c'])) check(['//?/Z:/a', '/b', 'c'], ('\\\\?\\Z:', '\\', ['\\\\?\\Z:\\', 'b', 'c'])) - - def test_splitroot(self): - f = self.flavour.splitroot - self.assertEqual(f(''), ('', '', '')) - self.assertEqual(f('a'), ('', '', 'a')) - self.assertEqual(f('a\\b'), ('', '', 'a\\b')) - self.assertEqual(f('\\a'), ('', '\\', 'a')) - self.assertEqual(f('\\a\\b'), ('', '\\', 'a\\b')) - self.assertEqual(f('c:a\\b'), ('c:', '', 'a\\b')) - self.assertEqual(f('c:\\a\\b'), ('c:', '\\', 'a\\b')) - # Redundant slashes in the root are collapsed. - self.assertEqual(f('\\\\a'), ('', '\\', 'a')) - self.assertEqual(f('\\\\\\a/b'), ('', '\\', 'a/b')) - self.assertEqual(f('c:\\\\a'), ('c:', '\\', 'a')) - self.assertEqual(f('c:\\\\\\a/b'), ('c:', '\\', 'a/b')) - # Valid UNC paths. - self.assertEqual(f('\\\\a\\b'), ('\\\\a\\b', '\\', '')) - self.assertEqual(f('\\\\a\\b\\'), ('\\\\a\\b', '\\', '')) - self.assertEqual(f('\\\\a\\b\\c\\d'), ('\\\\a\\b', '\\', 'c\\d')) - # These are non-UNC paths (according to ntpath.py and test_ntpath). - # However, command.com says such paths are invalid, so it's - # difficult to know what the right semantics are. - self.assertEqual(f('\\\\\\a\\b'), ('', '\\', 'a\\b')) - self.assertEqual(f('\\\\a'), ('', '\\', 'a')) + # Joining with the same drive => the first path is appended to if + # the second path is relative. + check(['c:/a/b', 'c:x/y'], ('c:', '\\', ['c:\\', 'a', 'b', 'x', 'y'])) + check(['c:/a/b', 'c:/x/y'], ('c:', '\\', ['c:\\', 'x', 'y'])) # @@ -176,8 +140,7 @@ class _BasePurePathTest(object): ('', 'a', 'b'), ('a', '', 'b'), ('a', 'b', ''), ], '/b/c/d': [ - ('a', '/b/c', 'd'), ('a', '///b//c', 'd/'), - ('/a', '/b/c', 'd'), + ('a', '/b/c', 'd'), ('/a', '/b/c', 'd'), # Empty components get removed. ('/', 'b', '', 'c/d'), ('/', '', 'b/c/d'), ('', '/b/c/d'), ], @@ -285,19 +248,26 @@ class _BasePurePathTest(object): def test_repr_common(self): for pathstr in ('a', 'a/b', 'a/b/c', '/', '/a/b', '/a/b/c'): - p = self.cls(pathstr) - clsname = p.__class__.__name__ - r = repr(p) - # The repr() is in the form ClassName("forward-slashes path"). - self.assertTrue(r.startswith(clsname + '('), r) - self.assertTrue(r.endswith(')'), r) - inner = r[len(clsname) + 1 : -1] - self.assertEqual(eval(inner), p.as_posix()) - # The repr() roundtrips. - q = eval(r, pathlib.__dict__) - self.assertIs(q.__class__, p.__class__) - self.assertEqual(q, p) - self.assertEqual(repr(q), r) + with self.subTest(pathstr=pathstr): + p = self.cls(pathstr) + clsname = p.__class__.__name__ + r = repr(p) + # The repr() is in the form ClassName("forward-slashes path"). + self.assertTrue(r.startswith(clsname + '('), r) + self.assertTrue(r.endswith(')'), r) + inner = r[len(clsname) + 1 : -1] + self.assertEqual(eval(inner), p.as_posix()) + + def test_repr_roundtrips(self): + for pathstr in ('a', 'a/b', 'a/b/c', '/', '/a/b', '/a/b/c'): + with self.subTest(pathstr=pathstr): + p = self.cls(pathstr) + r = repr(p) + # The repr() roundtrips. + q = eval(r, pathlib.__dict__) + self.assertIs(q.__class__, p.__class__) + self.assertEqual(q, p) + self.assertEqual(repr(q), r) def test_eq_common(self): P = self.cls @@ -463,6 +433,9 @@ class _BasePurePathTest(object): self.assertEqual(par[0], P('/a/b')) self.assertEqual(par[1], P('/a')) self.assertEqual(par[2], P('/')) + self.assertEqual(par[-1], P('/')) + self.assertEqual(par[-2], P('/a')) + self.assertEqual(par[-3], P('/a/b')) self.assertEqual(par[0:1], (P('/a/b'),)) self.assertEqual(par[:2], (P('/a/b'), P('/a'))) self.assertEqual(par[:-1], (P('/a/b'), P('/a'))) @@ -470,6 +443,8 @@ class _BasePurePathTest(object): self.assertEqual(par[::2], (P('/a/b'), P('/'))) self.assertEqual(par[::-1], (P('/'), P('/a'), P('/a/b'))) self.assertEqual(list(par), [P('/a/b'), P('/a'), P('/')]) + with self.assertRaises(IndexError): + par[-4] with self.assertRaises(IndexError): par[3] @@ -629,13 +604,30 @@ class _BasePurePathTest(object): self.assertEqual(p.relative_to('a/'), P('b')) self.assertEqual(p.relative_to(P('a/b')), P()) self.assertEqual(p.relative_to('a/b'), P()) + self.assertEqual(p.relative_to(P(), walk_up=True), P('a/b')) + self.assertEqual(p.relative_to('', walk_up=True), P('a/b')) + self.assertEqual(p.relative_to(P('a'), walk_up=True), P('b')) + self.assertEqual(p.relative_to('a', walk_up=True), P('b')) + self.assertEqual(p.relative_to('a/', walk_up=True), P('b')) + self.assertEqual(p.relative_to(P('a/b'), walk_up=True), P()) + self.assertEqual(p.relative_to('a/b', walk_up=True), P()) + self.assertEqual(p.relative_to(P('a/c'), walk_up=True), P('../b')) + self.assertEqual(p.relative_to('a/c', walk_up=True), P('../b')) + self.assertEqual(p.relative_to(P('a/b/c'), walk_up=True), P('..')) + self.assertEqual(p.relative_to('a/b/c', walk_up=True), P('..')) + self.assertEqual(p.relative_to(P('c'), walk_up=True), P('../a/b')) + self.assertEqual(p.relative_to('c', walk_up=True), P('../a/b')) # With several args. - self.assertEqual(p.relative_to('a', 'b'), P()) + with self.assertWarns(DeprecationWarning): + p.relative_to('a', 'b') + p.relative_to('a', 'b', walk_up=True) # Unrelated paths. self.assertRaises(ValueError, p.relative_to, P('c')) self.assertRaises(ValueError, p.relative_to, P('a/b/c')) self.assertRaises(ValueError, p.relative_to, P('a/c')) self.assertRaises(ValueError, p.relative_to, P('/a')) + self.assertRaises(ValueError, p.relative_to, P('/'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('/a'), walk_up=True) p = P('/a/b') self.assertEqual(p.relative_to(P('/')), P('a/b')) self.assertEqual(p.relative_to('/'), P('a/b')) @@ -644,6 +636,19 @@ class _BasePurePathTest(object): self.assertEqual(p.relative_to('/a/'), P('b')) self.assertEqual(p.relative_to(P('/a/b')), P()) self.assertEqual(p.relative_to('/a/b'), P()) + self.assertEqual(p.relative_to(P('/'), walk_up=True), P('a/b')) + self.assertEqual(p.relative_to('/', walk_up=True), P('a/b')) + self.assertEqual(p.relative_to(P('/a'), walk_up=True), P('b')) + self.assertEqual(p.relative_to('/a', walk_up=True), P('b')) + self.assertEqual(p.relative_to('/a/', walk_up=True), P('b')) + self.assertEqual(p.relative_to(P('/a/b'), walk_up=True), P()) + self.assertEqual(p.relative_to('/a/b', walk_up=True), P()) + self.assertEqual(p.relative_to(P('/a/c'), walk_up=True), P('../b')) + self.assertEqual(p.relative_to('/a/c', walk_up=True), P('../b')) + self.assertEqual(p.relative_to(P('/a/b/c'), walk_up=True), P('..')) + self.assertEqual(p.relative_to('/a/b/c', walk_up=True), P('..')) + self.assertEqual(p.relative_to(P('/c'), walk_up=True), P('../a/b')) + self.assertEqual(p.relative_to('/c', walk_up=True), P('../a/b')) # Unrelated paths. self.assertRaises(ValueError, p.relative_to, P('/c')) self.assertRaises(ValueError, p.relative_to, P('/a/b/c')) @@ -651,6 +656,8 @@ class _BasePurePathTest(object): self.assertRaises(ValueError, p.relative_to, P()) self.assertRaises(ValueError, p.relative_to, '') self.assertRaises(ValueError, p.relative_to, P('a')) + self.assertRaises(ValueError, p.relative_to, P(''), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('a'), walk_up=True) def test_is_relative_to_common(self): P = self.cls @@ -664,7 +671,8 @@ class _BasePurePathTest(object): self.assertTrue(p.is_relative_to(P('a/b'))) self.assertTrue(p.is_relative_to('a/b')) # With several args. - self.assertTrue(p.is_relative_to('a', 'b')) + with self.assertWarns(DeprecationWarning): + p.is_relative_to('a', 'b') # Unrelated paths. self.assertFalse(p.is_relative_to(P('c'))) self.assertFalse(p.is_relative_to(P('a/b/c'))) @@ -1113,6 +1121,16 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertEqual(p.relative_to('c:foO/'), P('Bar')) self.assertEqual(p.relative_to(P('c:foO/baR')), P()) self.assertEqual(p.relative_to('c:foO/baR'), P()) + self.assertEqual(p.relative_to(P('c:'), walk_up=True), P('Foo/Bar')) + self.assertEqual(p.relative_to('c:', walk_up=True), P('Foo/Bar')) + self.assertEqual(p.relative_to(P('c:foO'), walk_up=True), P('Bar')) + self.assertEqual(p.relative_to('c:foO', walk_up=True), P('Bar')) + self.assertEqual(p.relative_to('c:foO/', walk_up=True), P('Bar')) + self.assertEqual(p.relative_to(P('c:foO/baR'), walk_up=True), P()) + self.assertEqual(p.relative_to('c:foO/baR', walk_up=True), P()) + self.assertEqual(p.relative_to(P('C:Foo/Bar/Baz'), walk_up=True), P('..')) + self.assertEqual(p.relative_to(P('C:Foo/Baz'), walk_up=True), P('../Bar')) + self.assertEqual(p.relative_to(P('C:Baz/Bar'), walk_up=True), P('../../Foo/Bar')) # Unrelated paths. self.assertRaises(ValueError, p.relative_to, P()) self.assertRaises(ValueError, p.relative_to, '') @@ -1123,11 +1141,14 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertRaises(ValueError, p.relative_to, P('C:/Foo')) self.assertRaises(ValueError, p.relative_to, P('C:Foo/Bar/Baz')) self.assertRaises(ValueError, p.relative_to, P('C:Foo/Baz')) + self.assertRaises(ValueError, p.relative_to, P(), walk_up=True) + self.assertRaises(ValueError, p.relative_to, '', walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('d:'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('/'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('Foo'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('/Foo'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('C:/Foo'), walk_up=True) p = P('C:/Foo/Bar') - self.assertEqual(p.relative_to(P('c:')), P('/Foo/Bar')) - self.assertEqual(p.relative_to('c:'), P('/Foo/Bar')) - self.assertEqual(str(p.relative_to(P('c:'))), '\\Foo\\Bar') - self.assertEqual(str(p.relative_to('c:')), '\\Foo\\Bar') self.assertEqual(p.relative_to(P('c:/')), P('Foo/Bar')) self.assertEqual(p.relative_to('c:/'), P('Foo/Bar')) self.assertEqual(p.relative_to(P('c:/foO')), P('Bar')) @@ -1135,7 +1156,19 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertEqual(p.relative_to('c:/foO/'), P('Bar')) self.assertEqual(p.relative_to(P('c:/foO/baR')), P()) self.assertEqual(p.relative_to('c:/foO/baR'), P()) + self.assertEqual(p.relative_to(P('c:/'), walk_up=True), P('Foo/Bar')) + self.assertEqual(p.relative_to('c:/', walk_up=True), P('Foo/Bar')) + self.assertEqual(p.relative_to(P('c:/foO'), walk_up=True), P('Bar')) + self.assertEqual(p.relative_to('c:/foO', walk_up=True), P('Bar')) + self.assertEqual(p.relative_to('c:/foO/', walk_up=True), P('Bar')) + self.assertEqual(p.relative_to(P('c:/foO/baR'), walk_up=True), P()) + self.assertEqual(p.relative_to('c:/foO/baR', walk_up=True), P()) + self.assertEqual(p.relative_to('C:/Baz', walk_up=True), P('../Foo/Bar')) + self.assertEqual(p.relative_to('C:/Foo/Bar/Baz', walk_up=True), P('..')) + self.assertEqual(p.relative_to('C:/Foo/Baz', walk_up=True), P('../Bar')) # Unrelated paths. + self.assertRaises(ValueError, p.relative_to, 'c:') + self.assertRaises(ValueError, p.relative_to, P('c:')) self.assertRaises(ValueError, p.relative_to, P('C:/Baz')) self.assertRaises(ValueError, p.relative_to, P('C:/Foo/Bar/Baz')) self.assertRaises(ValueError, p.relative_to, P('C:/Foo/Baz')) @@ -1145,6 +1178,14 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertRaises(ValueError, p.relative_to, P('/')) self.assertRaises(ValueError, p.relative_to, P('/Foo')) self.assertRaises(ValueError, p.relative_to, P('//C/Foo')) + self.assertRaises(ValueError, p.relative_to, 'c:', walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('c:'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('C:Foo'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('d:'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('d:/'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('/'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('/Foo'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('//C/Foo'), walk_up=True) # UNC paths. p = P('//Server/Share/Foo/Bar') self.assertEqual(p.relative_to(P('//sErver/sHare')), P('Foo/Bar')) @@ -1155,11 +1196,25 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertEqual(p.relative_to('//sErver/sHare/Foo/'), P('Bar')) self.assertEqual(p.relative_to(P('//sErver/sHare/Foo/Bar')), P()) self.assertEqual(p.relative_to('//sErver/sHare/Foo/Bar'), P()) + self.assertEqual(p.relative_to(P('//sErver/sHare'), walk_up=True), P('Foo/Bar')) + self.assertEqual(p.relative_to('//sErver/sHare', walk_up=True), P('Foo/Bar')) + self.assertEqual(p.relative_to('//sErver/sHare/', walk_up=True), P('Foo/Bar')) + self.assertEqual(p.relative_to(P('//sErver/sHare/Foo'), walk_up=True), P('Bar')) + self.assertEqual(p.relative_to('//sErver/sHare/Foo', walk_up=True), P('Bar')) + self.assertEqual(p.relative_to('//sErver/sHare/Foo/', walk_up=True), P('Bar')) + self.assertEqual(p.relative_to(P('//sErver/sHare/Foo/Bar'), walk_up=True), P()) + self.assertEqual(p.relative_to('//sErver/sHare/Foo/Bar', walk_up=True), P()) + self.assertEqual(p.relative_to(P('//sErver/sHare/bar'), walk_up=True), P('../Foo/Bar')) + self.assertEqual(p.relative_to('//sErver/sHare/bar', walk_up=True), P('../Foo/Bar')) # Unrelated paths. self.assertRaises(ValueError, p.relative_to, P('/Server/Share/Foo')) self.assertRaises(ValueError, p.relative_to, P('c:/Server/Share/Foo')) self.assertRaises(ValueError, p.relative_to, P('//z/Share/Foo')) self.assertRaises(ValueError, p.relative_to, P('//Server/z/Foo')) + self.assertRaises(ValueError, p.relative_to, P('/Server/Share/Foo'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('c:/Server/Share/Foo'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('//z/Share/Foo'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('//Server/z/Foo'), walk_up=True) def test_is_relative_to(self): P = self.cls @@ -1182,13 +1237,13 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertFalse(p.is_relative_to(P('C:Foo/Bar/Baz'))) self.assertFalse(p.is_relative_to(P('C:Foo/Baz'))) p = P('C:/Foo/Bar') - self.assertTrue(p.is_relative_to('c:')) self.assertTrue(p.is_relative_to(P('c:/'))) self.assertTrue(p.is_relative_to(P('c:/foO'))) self.assertTrue(p.is_relative_to('c:/foO/')) self.assertTrue(p.is_relative_to(P('c:/foO/baR'))) self.assertTrue(p.is_relative_to('c:/foO/baR')) # Unrelated paths. + self.assertFalse(p.is_relative_to('c:')) self.assertFalse(p.is_relative_to(P('C:/Baz'))) self.assertFalse(p.is_relative_to(P('C:/Foo/Bar/Baz'))) self.assertFalse(p.is_relative_to(P('C:/Foo/Baz'))) @@ -1386,6 +1441,7 @@ class _BasePathTest(object): # | |-- dirD # | | `-- fileD # | `-- fileC + # | `-- novel.txt # |-- dirE # No permissions # |-- fileA # |-- linkA -> fileA @@ -1410,6 +1466,8 @@ class _BasePathTest(object): f.write(b"this is file B\n") with open(join('dirC', 'fileC'), 'wb') as f: f.write(b"this is file C\n") + with open(join('dirC', 'novel.txt'), 'wb') as f: + f.write(b"this is a novel\n") with open(join('dirC', 'dirD', 'fileD'), 'wb') as f: f.write(b"this is file D\n") os.chmod(join('dirE'), 0) @@ -1456,6 +1514,28 @@ class _BasePathTest(object): p = self.cls.cwd() self._test_cwd(p) + def test_absolute_common(self): + P = self.cls + + with mock.patch("os.getcwd") as getcwd: + getcwd.return_value = BASE + + # Simple relative paths. + self.assertEqual(str(P().absolute()), BASE) + self.assertEqual(str(P('.').absolute()), BASE) + self.assertEqual(str(P('a').absolute()), os.path.join(BASE, 'a')) + self.assertEqual(str(P('a', 'b', 'c').absolute()), os.path.join(BASE, 'a', 'b', 'c')) + + # Symlinks should not be resolved. + self.assertEqual(str(P('linkB', 'fileB').absolute()), os.path.join(BASE, 'linkB', 'fileB')) + self.assertEqual(str(P('brokenLink').absolute()), os.path.join(BASE, 'brokenLink')) + self.assertEqual(str(P('brokenLinkLoop').absolute()), os.path.join(BASE, 'brokenLinkLoop')) + + # '..' entries should be preserved and not normalised. + self.assertEqual(str(P('..').absolute()), os.path.join(BASE, '..')) + self.assertEqual(str(P('a', '..').absolute()), os.path.join(BASE, 'a', '..')) + self.assertEqual(str(P('..', 'b').absolute()), os.path.join(BASE, '..', 'b')) + def _test_home(self, p): q = self.cls(os.path.expanduser('~')) self.assertEqual(p, q) @@ -1463,6 +1543,9 @@ class _BasePathTest(object): self.assertIs(type(p), type(q)) self.assertTrue(p.is_absolute()) + @unittest.skipIf( + pwd is None, reason="Test requires pwd module to get homedir." + ) def test_home(self): with os_helper.EnvironmentVarGuard() as env: self._test_home(self.cls.home()) @@ -1500,6 +1583,7 @@ class _BasePathTest(object): p = self.cls('') self.assertEqual(p.stat(), os.stat('.')) + @unittest.skipIf(is_wasi, "WASI has no user accounts.") def test_expanduser_common(self): P = self.cls p = P('~') @@ -1632,6 +1716,11 @@ class _BasePathTest(object): else: _check(p.glob("*/fileB"), ['dirB/fileB', 'linkB/fileB']) + if not os_helper.can_symlink(): + _check(p.glob("*/"), ["dirA", "dirB", "dirC", "dirE"]) + else: + _check(p.glob("*/"), ["dirA", "dirB", "dirC", "dirE", "linkB"]) + def test_rglob_common(self): def _check(glob, expected): self.assertEqual(set(glob), { P(BASE, q) for q in expected }) @@ -1649,9 +1738,27 @@ class _BasePathTest(object): "linkB/fileB", "dirA/linkC/fileB"]) _check(p.rglob("file*"), ["fileA", "dirB/fileB", "dirC/fileC", "dirC/dirD/fileD"]) + if not os_helper.can_symlink(): + _check(p.rglob("*/"), [ + "dirA", "dirB", "dirC", "dirC/dirD", "dirE", + ]) + else: + _check(p.rglob("*/"), [ + "dirA", "dirA/linkC", "dirB", "dirB/linkD", "dirC", + "dirC/dirD", "dirE", "linkB", + ]) + _check(p.rglob(""), ["", "dirA", "dirB", "dirC", "dirE", "dirC/dirD"]) + p = P(BASE, "dirC") + _check(p.rglob("*"), ["dirC/fileC", "dirC/novel.txt", + "dirC/dirD", "dirC/dirD/fileD"]) _check(p.rglob("file*"), ["dirC/fileC", "dirC/dirD/fileD"]) _check(p.rglob("*/*"), ["dirC/dirD/fileD"]) + _check(p.rglob("*/"), ["dirC/dirD"]) + _check(p.rglob(""), ["dirC", "dirC/dirD"]) + # gh-91616, a re module regression + _check(p.rglob("*.txt"), ["dirC/novel.txt"]) + _check(p.rglob("*.*"), ["dirC/novel.txt"]) @os_helper.skip_unless_symlink def test_rglob_symlink_loop(self): @@ -1662,7 +1769,8 @@ class _BasePathTest(object): expect = {'brokenLink', 'dirA', 'dirA/linkC', 'dirB', 'dirB/fileB', 'dirB/linkD', - 'dirC', 'dirC/dirD', 'dirC/dirD/fileD', 'dirC/fileC', + 'dirC', 'dirC/dirD', 'dirC/dirD/fileD', + 'dirC/fileC', 'dirC/novel.txt', 'dirE', 'fileA', 'linkA', @@ -1716,21 +1824,18 @@ class _BasePathTest(object): # Patching is needed to avoid relying on the filesystem # to return the order of the files as the error will not # happen if the symlink is the last item. + real_scandir = os.scandir + def my_scandir(path): + with real_scandir(path) as scandir_it: + entries = list(scandir_it) + entries.sort(key=lambda entry: entry.name) + return contextlib.nullcontext(entries) - with mock.patch("os.scandir") as scandir: - scandir.return_value = sorted(os.scandir(base)) + with mock.patch("os.scandir", my_scandir): self.assertEqual(len(set(base.glob("*"))), 3) - - subdir.mkdir() - - with mock.patch("os.scandir") as scandir: - scandir.return_value = sorted(os.scandir(base)) + subdir.mkdir() self.assertEqual(len(set(base.glob("*"))), 4) - - subdir.chmod(000) - - with mock.patch("os.scandir") as scandir: - scandir.return_value = sorted(os.scandir(base)) + subdir.chmod(000) self.assertEqual(len(set(base.glob("*"))), 4) def _check_resolve(self, p, expected, strict=True): @@ -1830,8 +1935,10 @@ class _BasePathTest(object): it = p.iterdir() it2 = p.iterdir() next(it2) - with p: - pass + # bpo-46556: path context managers are deprecated in Python 3.11. + with self.assertWarns(DeprecationWarning): + with p: + pass # Using a path as a context manager is a no-op, thus the following # operations should still succeed after the context manage exits. next(it) @@ -1839,9 +1946,11 @@ class _BasePathTest(object): p.exists() p.resolve() p.absolute() - with p: - pass + with self.assertWarns(DeprecationWarning): + with p: + pass + @os_helper.skip_unless_working_chmod def test_chmod(self): p = self.cls(BASE) / 'fileA' mode = p.stat().st_mode @@ -1856,6 +1965,7 @@ class _BasePathTest(object): # On Windows, os.chmod does not follow symlinks (issue #15411) @only_posix + @os_helper.skip_unless_working_chmod def test_chmod_follow_symlinks_true(self): p = self.cls(BASE) / 'linkA' q = p.resolve() @@ -1871,6 +1981,7 @@ class _BasePathTest(object): # XXX also need a test for lchmod. + @os_helper.skip_unless_working_chmod def test_stat(self): p = self.cls(BASE) / 'fileA' st = p.stat() @@ -1943,28 +2054,6 @@ class _BasePathTest(object): self.assertFileNotFound(p.stat) self.assertFileNotFound(p.unlink) - @unittest.skipUnless(hasattr(os, "link"), "os.link() is not present") - def test_link_to(self): - P = self.cls(BASE) - p = P / 'fileA' - size = p.stat().st_size - # linking to another path. - q = P / 'dirA' / 'fileAA' - try: - with self.assertWarns(DeprecationWarning): - p.link_to(q) - except PermissionError as e: - self.skipTest('os.link(): %s' % e) - self.assertEqual(q.stat().st_size, size) - self.assertEqual(os.path.samefile(p, q), True) - self.assertTrue(p.stat) - # Linking to a str of a relative path. - r = rel_join('fileAAA') - with self.assertWarns(DeprecationWarning): - q.link_to(r) - self.assertEqual(os.stat(r).st_size, size) - self.assertTrue(q.stat) - @unittest.skipUnless(hasattr(os, "link"), "os.link() is not present") def test_hardlink_to(self): P = self.cls(BASE) @@ -1990,7 +2079,7 @@ class _BasePathTest(object): # linking to another path. q = P / 'dirA' / 'fileAA' with self.assertRaises(NotImplementedError): - p.link_to(q) + q.hardlink_to(p) def test_rename(self): P = self.cls(BASE) @@ -2132,6 +2221,7 @@ class _BasePathTest(object): self.assertTrue(p.exists()) self.assertEqual(p.stat().st_ctime, st_ctime_first) + @unittest.skipIf(is_emscripten, "FS root cannot be modified on Emscripten.") def test_mkdir_exist_ok_root(self): # Issue #25803: A drive root could raise PermissionError on Windows. self.cls('/').resolve().mkdir(exist_ok=True) @@ -2177,6 +2267,7 @@ class _BasePathTest(object): p = self.cls(BASE, 'dirCPC%d' % pattern_num) self.assertFalse(p.exists()) + real_mkdir = os.mkdir def my_mkdir(path, mode=0o777): path = str(path) # Emulate another process that would create the directory @@ -2185,15 +2276,15 @@ class _BasePathTest(object): # function is called at most 5 times (dirCPC/dir1/dir2, # dirCPC/dir1, dirCPC, dirCPC/dir1, dirCPC/dir1/dir2). if pattern.pop(): - os.mkdir(path, mode) # From another process. + real_mkdir(path, mode) # From another process. concurrently_created.add(path) - os.mkdir(path, mode) # Our real call. + real_mkdir(path, mode) # Our real call. pattern = [bool(pattern_num & (1 << n)) for n in range(5)] concurrently_created = set() p12 = p / 'dir1' / 'dir2' try: - with mock.patch("pathlib._normal_accessor.mkdir", my_mkdir): + with mock.patch("os.mkdir", my_mkdir): p12.mkdir(parents=True, exist_ok=False) except FileExistsError: self.assertIn(str(p12), concurrently_created) @@ -2251,10 +2342,12 @@ class _BasePathTest(object): self.assertIs((P / 'fileA\udfff').is_file(), False) self.assertIs((P / 'fileA\x00').is_file(), False) - @only_posix def test_is_mount(self): P = self.cls(BASE) - R = self.cls('/') # TODO: Work out Windows. + if os.name == 'nt': + R = self.cls('c:\\') + else: + R = self.cls('/') self.assertFalse((P / 'fileA').is_mount()) self.assertFalse((P / 'dirA').is_mount()) self.assertFalse((P / 'non-existing').is_mount()) @@ -2262,8 +2355,7 @@ class _BasePathTest(object): self.assertTrue(R.is_mount()) if os_helper.can_symlink(): self.assertFalse((P / 'linkA').is_mount()) - self.assertIs(self.cls('/\udfff').is_mount(), False) - self.assertIs(self.cls('/\x00').is_mount(), False) + self.assertIs((R / '\udfff').is_mount(), False) def test_is_symlink(self): P = self.cls(BASE) @@ -2281,6 +2373,13 @@ class _BasePathTest(object): self.assertIs((P / 'linkA\udfff').is_file(), False) self.assertIs((P / 'linkA\x00').is_file(), False) + def test_is_junction(self): + P = self.cls(BASE) + + with mock.patch.object(P._flavour, 'isjunction'): + self.assertEqual(P.is_junction(), P._flavour.isjunction.return_value) + P._flavour.isjunction.assert_called_once_with(P) + def test_is_fifo_false(self): P = self.cls(BASE) self.assertFalse((P / 'fileA').is_fifo()) @@ -2315,6 +2414,12 @@ class _BasePathTest(object): self.assertIs((P / 'fileA\x00').is_socket(), False) @unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required") + @unittest.skipIf( + is_emscripten, "Unix sockets are not implemented on Emscripten." + ) + @unittest.skipIf( + is_wasi, "Cannot create socket on WASI." + ) def test_is_socket_true(self): P = self.cls(BASE, 'mysock') sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) @@ -2429,13 +2534,213 @@ class _BasePathTest(object): def test_complex_symlinks_relative_dot_dot(self): self._check_complex_symlinks(os.path.join('dirA', '..')) + def test_passing_kwargs_deprecated(self): + with self.assertWarns(DeprecationWarning): + self.cls(foo="bar") + + +class WalkTests(unittest.TestCase): + + def setUp(self): + self.addCleanup(os_helper.rmtree, os_helper.TESTFN) + + # Build: + # TESTFN/ + # TEST1/ a file kid and two directory kids + # tmp1 + # SUB1/ a file kid and a directory kid + # tmp2 + # SUB11/ no kids + # SUB2/ a file kid and a dirsymlink kid + # tmp3 + # SUB21/ not readable + # tmp5 + # link/ a symlink to TEST2 + # broken_link + # broken_link2 + # broken_link3 + # TEST2/ + # tmp4 a lone file + self.walk_path = pathlib.Path(os_helper.TESTFN, "TEST1") + self.sub1_path = self.walk_path / "SUB1" + self.sub11_path = self.sub1_path / "SUB11" + self.sub2_path = self.walk_path / "SUB2" + sub21_path= self.sub2_path / "SUB21" + tmp1_path = self.walk_path / "tmp1" + tmp2_path = self.sub1_path / "tmp2" + tmp3_path = self.sub2_path / "tmp3" + tmp5_path = sub21_path / "tmp3" + self.link_path = self.sub2_path / "link" + t2_path = pathlib.Path(os_helper.TESTFN, "TEST2") + tmp4_path = pathlib.Path(os_helper.TESTFN, "TEST2", "tmp4") + broken_link_path = self.sub2_path / "broken_link" + broken_link2_path = self.sub2_path / "broken_link2" + broken_link3_path = self.sub2_path / "broken_link3" + + os.makedirs(self.sub11_path) + os.makedirs(self.sub2_path) + os.makedirs(sub21_path) + os.makedirs(t2_path) + + for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path, tmp5_path: + with open(path, "x", encoding='utf-8') as f: + f.write(f"I'm {path} and proud of it. Blame test_pathlib.\n") + + if os_helper.can_symlink(): + os.symlink(os.path.abspath(t2_path), self.link_path) + os.symlink('broken', broken_link_path, True) + os.symlink(pathlib.Path('tmp3', 'broken'), broken_link2_path, True) + os.symlink(pathlib.Path('SUB21', 'tmp5'), broken_link3_path, True) + self.sub2_tree = (self.sub2_path, ["SUB21"], + ["broken_link", "broken_link2", "broken_link3", + "link", "tmp3"]) + else: + self.sub2_tree = (self.sub2_path, ["SUB21"], ["tmp3"]) + + if not is_emscripten: + # Emscripten fails with inaccessible directories. + os.chmod(sub21_path, 0) + try: + os.listdir(sub21_path) + except PermissionError: + self.addCleanup(os.chmod, sub21_path, stat.S_IRWXU) + else: + os.chmod(sub21_path, stat.S_IRWXU) + os.unlink(tmp5_path) + os.rmdir(sub21_path) + del self.sub2_tree[1][:1] + + def test_walk_topdown(self): + all = list(self.walk_path.walk()) + + self.assertEqual(len(all), 4) + # We can't know which order SUB1 and SUB2 will appear in. + # Not flipped: TESTFN, SUB1, SUB11, SUB2 + # flipped: TESTFN, SUB2, SUB1, SUB11 + flipped = all[0][1][0] != "SUB1" + all[0][1].sort() + all[3 - 2 * flipped][-1].sort() + all[3 - 2 * flipped][1].sort() + self.assertEqual(all[0], (self.walk_path, ["SUB1", "SUB2"], ["tmp1"])) + self.assertEqual(all[1 + flipped], (self.sub1_path, ["SUB11"], ["tmp2"])) + self.assertEqual(all[2 + flipped], (self.sub11_path, [], [])) + self.assertEqual(all[3 - 2 * flipped], self.sub2_tree) + + def test_walk_prune(self, walk_path=None): + if walk_path is None: + walk_path = self.walk_path + # Prune the search. + all = [] + for root, dirs, files in walk_path.walk(): + all.append((root, dirs, files)) + if 'SUB1' in dirs: + # Note that this also mutates the dirs we appended to all! + dirs.remove('SUB1') + + self.assertEqual(len(all), 2) + self.assertEqual(all[0], (self.walk_path, ["SUB2"], ["tmp1"])) + + all[1][-1].sort() + all[1][1].sort() + self.assertEqual(all[1], self.sub2_tree) + + def test_file_like_path(self): + self.test_walk_prune(FakePath(self.walk_path).__fspath__()) + + def test_walk_bottom_up(self): + all = list(self.walk_path.walk( top_down=False)) + + self.assertEqual(len(all), 4, all) + # We can't know which order SUB1 and SUB2 will appear in. + # Not flipped: SUB11, SUB1, SUB2, TESTFN + # flipped: SUB2, SUB11, SUB1, TESTFN + flipped = all[3][1][0] != "SUB1" + all[3][1].sort() + all[2 - 2 * flipped][-1].sort() + all[2 - 2 * flipped][1].sort() + self.assertEqual(all[3], + (self.walk_path, ["SUB1", "SUB2"], ["tmp1"])) + self.assertEqual(all[flipped], + (self.sub11_path, [], [])) + self.assertEqual(all[flipped + 1], + (self.sub1_path, ["SUB11"], ["tmp2"])) + self.assertEqual(all[2 - 2 * flipped], + self.sub2_tree) + + @os_helper.skip_unless_symlink + def test_walk_follow_symlinks(self): + walk_it = self.walk_path.walk(follow_symlinks=True) + for root, dirs, files in walk_it: + if root == self.link_path: + self.assertEqual(dirs, []) + self.assertEqual(files, ["tmp4"]) + break + else: + self.fail("Didn't follow symlink with follow_symlinks=True") + + @os_helper.skip_unless_symlink + def test_walk_symlink_location(self): + # Tests whether symlinks end up in filenames or dirnames depending + # on the `follow_symlinks` argument. + walk_it = self.walk_path.walk(follow_symlinks=False) + for root, dirs, files in walk_it: + if root == self.sub2_path: + self.assertIn("link", files) + break + else: + self.fail("symlink not found") + + walk_it = self.walk_path.walk(follow_symlinks=True) + for root, dirs, files in walk_it: + if root == self.sub2_path: + self.assertIn("link", dirs) + break + + def test_walk_bad_dir(self): + errors = [] + walk_it = self.walk_path.walk(on_error=errors.append) + root, dirs, files = next(walk_it) + self.assertEqual(errors, []) + dir1 = 'SUB1' + path1 = root / dir1 + path1new = (root / dir1).with_suffix(".new") + path1.rename(path1new) + try: + roots = [r for r, _, _ in walk_it] + self.assertTrue(errors) + self.assertNotIn(path1, roots) + self.assertNotIn(path1new, roots) + for dir2 in dirs: + if dir2 != dir1: + self.assertIn(root / dir2, roots) + finally: + path1new.rename(path1) + + def test_walk_many_open_files(self): + depth = 30 + base = pathlib.Path(os_helper.TESTFN, 'deep') + path = pathlib.Path(base, *(['d']*depth)) + path.mkdir(parents=True) + + iters = [base.walk(top_down=False) for _ in range(100)] + for i in range(depth + 1): + expected = (path, ['d'] if i else [], []) + for it in iters: + self.assertEqual(next(it), expected) + path = path.parent + + iters = [base.walk(top_down=True) for _ in range(100)] + path = base + for i in range(depth + 1): + expected = (path, ['d'] if i < depth else [], []) + for it in iters: + self.assertEqual(next(it), expected) + path = path / 'd' + class PathTest(_BasePathTest, unittest.TestCase): cls = pathlib.Path - def test_class_getitem(self): - self.assertIs(self.cls[str], self.cls) - def test_concrete_class(self): p = self.cls('a') self.assertIs(type(p), @@ -2457,11 +2762,26 @@ class PathTest(_BasePathTest, unittest.TestCase): class PosixPathTest(_BasePathTest, unittest.TestCase): cls = pathlib.PosixPath + def test_absolute(self): + P = self.cls + self.assertEqual(str(P('/').absolute()), '/') + self.assertEqual(str(P('/a').absolute()), '/a') + self.assertEqual(str(P('/a/b').absolute()), '/a/b') + + # '//'-prefixed absolute path (supported by POSIX). + self.assertEqual(str(P('//').absolute()), '//') + self.assertEqual(str(P('//a').absolute()), '//a') + self.assertEqual(str(P('//a/b').absolute()), '//a/b') + def _check_symlink_loop(self, *args, strict=True): path = self.cls(*args) with self.assertRaises(RuntimeError): print(path.resolve(strict)) + @unittest.skipIf( + is_emscripten or is_wasi, + "umask is not implemented on Emscripten/WASI." + ) def test_open_mode(self): old_mask = os.umask(0) self.addCleanup(os.umask, old_mask) @@ -2485,6 +2805,10 @@ class PosixPathTest(_BasePathTest, unittest.TestCase): finally: os.chdir(current_directory) + @unittest.skipIf( + is_emscripten or is_wasi, + "umask is not implemented on Emscripten/WASI." + ) def test_touch_mode(self): old_mask = os.umask(0) self.addCleanup(os.umask, old_mask) @@ -2558,13 +2882,21 @@ class PosixPathTest(_BasePathTest, unittest.TestCase): othername = username otherhome = userhome + fakename = 'fakeuser' + # This user can theoretically exist on a test runner. Create unique name: + try: + while pwd.getpwnam(fakename): + fakename += '1' + except KeyError: + pass # Non-existent name found + p1 = P('~/Documents') - p2 = P('~' + username + '/Documents') - p3 = P('~' + othername + '/Documents') - p4 = P('../~' + username + '/Documents') - p5 = P('/~' + username + '/Documents') + p2 = P(f'~{username}/Documents') + p3 = P(f'~{othername}/Documents') + p4 = P(f'../~{username}/Documents') + p5 = P(f'/~{username}/Documents') p6 = P('') - p7 = P('~fakeuser/Documents') + p7 = P(f'~{fakename}/Documents') with os_helper.EnvironmentVarGuard() as env: env.pop('HOME', None) @@ -2614,10 +2946,36 @@ class PosixPathTest(_BasePathTest, unittest.TestCase): class WindowsPathTest(_BasePathTest, unittest.TestCase): cls = pathlib.WindowsPath + def test_absolute(self): + P = self.cls + + # Simple absolute paths. + self.assertEqual(str(P('c:\\').absolute()), 'c:\\') + self.assertEqual(str(P('c:\\a').absolute()), 'c:\\a') + self.assertEqual(str(P('c:\\a\\b').absolute()), 'c:\\a\\b') + + # UNC absolute paths. + share = '\\\\server\\share\\' + self.assertEqual(str(P(share).absolute()), share) + self.assertEqual(str(P(share + 'a').absolute()), share + 'a') + self.assertEqual(str(P(share + 'a\\b').absolute()), share + 'a\\b') + + # UNC relative paths. + with mock.patch("os.getcwd") as getcwd: + getcwd.return_value = share + + self.assertEqual(str(P().absolute()), share) + self.assertEqual(str(P('.').absolute()), share) + self.assertEqual(str(P('a').absolute()), os.path.join(share, 'a')) + self.assertEqual(str(P('a', 'b', 'c').absolute()), + os.path.join(share, 'a', 'b', 'c')) + + def test_glob(self): P = self.cls p = P(BASE) self.assertEqual(set(p.glob("FILEa")), { P(BASE, "fileA") }) + self.assertEqual(set(p.glob("*a\\")), { P(BASE, "dirA") }) self.assertEqual(set(p.glob("F*a")), { P(BASE, "fileA") }) self.assertEqual(set(map(str, p.glob("FILEa"))), {f"{p}\\FILEa"}) self.assertEqual(set(map(str, p.glob("F*a"))), {f"{p}\\fileA"}) @@ -2626,6 +2984,7 @@ class WindowsPathTest(_BasePathTest, unittest.TestCase): P = self.cls p = P(BASE, "dirC") self.assertEqual(set(p.rglob("FILEd")), { P(BASE, "dirC/dirD/fileD") }) + self.assertEqual(set(p.rglob("*\\")), { P(BASE, "dirC/dirD") }) self.assertEqual(set(map(str, p.rglob("FILEd"))), {f"{p}\\dirD\\FILEd"}) def test_expanduser(self): @@ -2682,6 +3041,22 @@ class WindowsPathTest(_BasePathTest, unittest.TestCase): check() +class PurePathSubclassTest(_BasePurePathTest, unittest.TestCase): + class cls(pathlib.PurePath): + pass + + # repr() roundtripping is not supported in custom subclass. + test_repr_roundtrips = None + + +class PathSubclassTest(_BasePathTest, unittest.TestCase): + class cls(pathlib.Path): + pass + + # repr() roundtripping is not supported in custom subclass. + test_repr_roundtrips = None + + class CompatiblePathTest(unittest.TestCase): """ Test that a type can be made compatible with PurePath diff --git a/Lib/test/test_patma.py b/Lib/test/test_patma.py index 57d3b1ec701..0ed54079c99 100644 --- a/Lib/test/test_patma.py +++ b/Lib/test/test_patma.py @@ -2654,6 +2654,20 @@ class TestPatma(unittest.TestCase): self.assertEqual(y, 'bar') + def test_patma_249(self): + class C: + __attr = "eggs" # mangled to _C__attr + _Outer__attr = "bacon" + class Outer: + def f(self, x): + match x: + # looks up __attr, not _C__attr or _Outer__attr + case C(__attr=y): + return y + c = C() + setattr(c, "__attr", "spam") # setattr is needed because we're in a class scope + self.assertEqual(Outer().f(c), "spam") + class TestSyntaxErrors(unittest.TestCase): @@ -3151,6 +3165,27 @@ class TestTracing(unittest.TestCase): self.assertListEqual(self._trace(f, "go x"), [1, 2, 3]) self.assertListEqual(self._trace(f, "spam"), [1, 2, 3]) + def test_parser_deeply_nested_patterns(self): + # Deeply nested patterns can cause exponential backtracking when parsing. + # See gh-93671 for more information. + + levels = 100 + + patterns = [ + "A" + "(" * levels + ")" * levels, + "{1:" * levels + "1" + "}" * levels, + "[" * levels + "1" + "]" * levels, + ] + + for pattern in patterns: + with self.subTest(pattern): + code = inspect.cleandoc(""" + match None: + case {}: + pass + """.format(pattern)) + compile(code, "", "exec") + if __name__ == "__main__": """ diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 01263db28f1..48f419e62fb 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -13,6 +13,7 @@ import linecache from contextlib import ExitStack, redirect_stdout from io import StringIO +from test import support from test.support import os_helper # This little helper class is essential for testing pdb under doctest. from test.test_doctest import _FakeInput @@ -1362,12 +1363,126 @@ def test_pdb_issue_43318(): 4 """ +def test_pdb_issue_gh_91742(): + """See GH-91742 + >>> def test_function(): + ... __author__ = "pi" + ... __version__ = "3.14" + ... + ... def about(): + ... '''About''' + ... print(f"Author: {__author__!r}", + ... f"Version: {__version__!r}", + ... sep=" ") + ... + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... about() + + + >>> reset_Breakpoint() + >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE + ... 'step', + ... 'next', + ... 'next', + ... 'jump 5', + ... 'continue' + ... ]): + ... test_function() + > (12)test_function() + -> about() + (Pdb) step + --Call-- + > (5)about() + -> def about(): + (Pdb) next + > (7)about() + -> print(f"Author: {__author__!r}", + (Pdb) next + > (8)about() + -> f"Version: {__version__!r}", + (Pdb) jump 5 + > (5)about() + -> def about(): + (Pdb) continue + Author: 'pi' Version: '3.14' + """ + +def test_pdb_issue_gh_94215(): + """See GH-94215 + + Check that frame_setlineno() does not leak references. + + >>> def test_function(): + ... def func(): + ... def inner(v): pass + ... inner( + ... 42 + ... ) + ... + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... func() + + >>> reset_Breakpoint() + >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE + ... 'step', + ... 'next', + ... 'next', + ... 'jump 3', + ... 'next', + ... 'next', + ... 'jump 3', + ... 'next', + ... 'next', + ... 'jump 3', + ... 'continue' + ... ]): + ... test_function() + > (9)test_function() + -> func() + (Pdb) step + --Call-- + > (2)func() + -> def func(): + (Pdb) next + > (3)func() + -> def inner(v): pass + (Pdb) next + > (4)func() + -> inner( + (Pdb) jump 3 + > (3)func() + -> def inner(v): pass + (Pdb) next + > (4)func() + -> inner( + (Pdb) next + > (5)func() + -> 42 + (Pdb) jump 3 + > (3)func() + -> def inner(v): pass + (Pdb) next + > (4)func() + -> inner( + (Pdb) next + > (5)func() + -> 42 + (Pdb) jump 3 + > (3)func() + -> def inner(v): pass + (Pdb) continue + """ + + +@support.requires_subprocess() class PdbTestCase(unittest.TestCase): def tearDown(self): os_helper.unlink(os_helper.TESTFN) - def _run_pdb(self, pdb_args, commands): + @unittest.skipIf(sys.flags.safe_path, + 'PYTHONSAFEPATH changes default sys.path') + def _run_pdb(self, pdb_args, commands, expected_returncode=0): self.addCleanup(os_helper.rmtree, '__pycache__') cmd = [sys.executable, '-m', 'pdb'] + pdb_args with subprocess.Popen( @@ -1380,15 +1495,20 @@ class PdbTestCase(unittest.TestCase): stdout, stderr = proc.communicate(str.encode(commands)) stdout = stdout and bytes.decode(stdout) stderr = stderr and bytes.decode(stderr) + self.assertEqual( + proc.returncode, + expected_returncode, + f"Unexpected return code\nstdout: {stdout}\nstderr: {stderr}" + ) return stdout, stderr - def run_pdb_script(self, script, commands): + def run_pdb_script(self, script, commands, expected_returncode=0): """Run 'script' lines with pdb and the pdb 'commands'.""" filename = 'main.py' with open(filename, 'w') as f: f.write(textwrap.dedent(script)) self.addCleanup(os_helper.unlink, filename) - return self._run_pdb([filename], commands) + return self._run_pdb([filename], commands, expected_returncode) def run_pdb_module(self, script, commands): """Runs the script code as part of a module""" @@ -1474,6 +1594,27 @@ def bÅ“r(): self.assertNotIn(b'SyntaxError', stdout, "Got a syntax error running test script under PDB") + def test_issue46434(self): + # Temporarily patch in an extra help command which doesn't have a + # docstring to emulate what happens in an embeddable distribution + script = """ + def do_testcmdwithnodocs(self, arg): + pass + + import pdb + pdb.Pdb.do_testcmdwithnodocs = do_testcmdwithnodocs + """ + commands = """ + continue + help testcmdwithnodocs + """ + stdout, stderr = self.run_pdb_script(script, commands) + output = (stdout or '') + (stderr or '') + self.assertNotIn('AttributeError', output, + 'Calling help on a command with no docs should be handled gracefully') + self.assertIn("*** No help for 'testcmdwithnodocs'; __doc__ string missing", output, + 'Calling help on a command with no docs should print an error') + def test_issue13183(self): script = """ from bar import bar @@ -1573,7 +1714,9 @@ def bÅ“r(): script = "def f: pass\n" commands = '' expected = "SyntaxError:" - stdout, stderr = self.run_pdb_script(script, commands) + stdout, stderr = self.run_pdb_script( + script, commands, expected_returncode=1 + ) self.assertIn(expected, stdout, '\n\nExpected:\n{}\nGot:\n{}\n' 'Fail to handle a syntax error in the debuggee.' @@ -1736,7 +1879,9 @@ def bÅ“r(): with open(init_file, 'w'): pass self.addCleanup(os_helper.rmtree, module_name) - stdout, stderr = self._run_pdb(['-m', module_name], "") + stdout, stderr = self._run_pdb( + ['-m', module_name], "", expected_returncode=1 + ) self.assertIn("ImportError: No module named t_main.__main__", stdout.splitlines()) @@ -1749,7 +1894,9 @@ def bÅ“r(): with open(modpath + '/__init__.py', 'w'): pass self.addCleanup(os_helper.rmtree, pkg_name) - stdout, stderr = self._run_pdb(['-m', modpath.replace('/', '.')], "") + stdout, stderr = self._run_pdb( + ['-m', modpath.replace('/', '.')], "", expected_returncode=1 + ) self.assertIn( "'t_pkg.t_main' is a package and cannot be directly executed", stdout) @@ -1938,6 +2085,70 @@ def bÅ“r(): expected = '(Pdb) The correct file was executed' self.assertEqual(stdout.split('\n')[6].rstrip('\r'), expected) + def test_gh_94215_crash(self): + script = """\ + def func(): + def inner(v): pass + inner( + 42 + ) + func() + """ + commands = textwrap.dedent(""" + break func + continue + next + next + jump 2 + """) + stdout, stderr = self.run_pdb_script(script, commands) + self.assertFalse(stderr) + + def test_gh_93696_frozen_list(self): + frozen_src = """ + def func(): + x = "Sentinel string for gh-93696" + print(x) + """ + host_program = """ + import os + import sys + + def _create_fake_frozen_module(): + with open('gh93696.py') as f: + src = f.read() + + # this function has a co_filename as if it were in a frozen module + dummy_mod = compile(src, "", "exec") + func_code = dummy_mod.co_consts[0] + + mod = type(sys)("gh93696") + mod.func = type(lambda: None)(func_code, mod.__dict__) + mod.__file__ = 'gh93696.py' + + return mod + + mod = _create_fake_frozen_module() + mod.func() + """ + commands = """ + break 20 + continue + step + list + quit + """ + with open('gh93696.py', 'w') as f: + f.write(textwrap.dedent(frozen_src)) + + with open('gh93696_host.py', 'w') as f: + f.write(textwrap.dedent(host_program)) + + self.addCleanup(os_helper.unlink, 'gh93696.py') + self.addCleanup(os_helper.unlink, 'gh93696_host.py') + stdout, stderr = self._run_pdb(["gh93696_host.py"], commands) + # verify that pdb found the source of the "frozen" function + self.assertIn('x = "Sentinel string for gh-93696"', stdout, "Sentinel statement not found") class ChecklineTests(unittest.TestCase): def setUp(self): diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index 8306c896a57..239c9d03fd9 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -1,8 +1,24 @@ import dis from itertools import combinations, product +import sys +import textwrap import unittest -from test.support.bytecode_helper import BytecodeTestCase +from test.support.bytecode_helper import BytecodeTestCase, CfgOptimizationTestCase + + +def compile_pattern_with_fast_locals(pattern): + source = textwrap.dedent( + f""" + def f(x): + match x: + case {pattern}: + pass + """ + ) + namespace = {} + exec(source, namespace) + return namespace["f"].__code__ def count_instr_recursively(f, opname): @@ -28,11 +44,11 @@ class TestTranforms(BytecodeTestCase): continue tgt = targets[instr.argval] # jump to unconditional jump - if tgt.opname in ('JUMP_ABSOLUTE', 'JUMP_FORWARD'): + if tgt.opname in ('JUMP_BACKWARD', 'JUMP_FORWARD'): self.fail(f'{instr.opname} at {instr.offset} ' f'jumps to {tgt.opname} at {tgt.offset}') # unconditional jump to RETURN_VALUE - if (instr.opname in ('JUMP_ABSOLUTE', 'JUMP_FORWARD') and + if (instr.opname in ('JUMP_BACKWARD', 'JUMP_FORWARD') and tgt.opname == 'RETURN_VALUE'): self.fail(f'{instr.opname} at {instr.offset} ' f'jumps to {tgt.opname} at {tgt.offset}') @@ -112,21 +128,21 @@ class TestTranforms(BytecodeTestCase): return list for elem in ('LOAD_CONST', 'POP_JUMP_IF_FALSE'): self.assertNotInBytecode(f, elem) - for elem in ('JUMP_ABSOLUTE',): + for elem in ('JUMP_BACKWARD',): self.assertInBytecode(f, elem) self.check_lnotab(f) def test_pack_unpack(self): for line, elem in ( ('a, = a,', 'LOAD_CONST',), - ('a, b = a, b', 'ROT_TWO',), - ('a, b, c = a, b, c', 'ROT_THREE',), + ('a, b = a, b', 'SWAP',), + ('a, b, c = a, b, c', 'SWAP',), ): with self.subTest(line=line): code = compile(line,'','single') self.assertInBytecode(code, elem) self.assertNotInBytecode(code, 'BUILD_TUPLE') - self.assertNotInBytecode(code, 'UNPACK_TUPLE') + self.assertNotInBytecode(code, 'UNPACK_SEQUENCE') self.check_lnotab(code) def test_folding_of_tuples_of_constants(self): @@ -336,7 +352,7 @@ class TestTranforms(BytecodeTestCase): else false_value) self.check_jump_targets(f) self.assertNotInBytecode(f, 'JUMP_FORWARD') - self.assertNotInBytecode(f, 'JUMP_ABSOLUTE') + self.assertNotInBytecode(f, 'JUMP_BACKWARD') returns = [instr for instr in dis.get_instructions(f) if instr.opname == 'RETURN_VALUE'] self.assertEqual(len(returns), 2) @@ -356,7 +372,7 @@ class TestTranforms(BytecodeTestCase): self.check_lnotab(f) def test_elim_jump_to_uncond_jump2(self): - # POP_JUMP_IF_FALSE to JUMP_ABSOLUTE --> POP_JUMP_IF_FALSE to non-jump + # POP_JUMP_IF_FALSE to JUMP_BACKWARD --> POP_JUMP_IF_FALSE to non-jump def f(): while a: # Intentionally use two-line expression to test issue37213. @@ -401,6 +417,13 @@ class TestTranforms(BytecodeTestCase): self.assertInBytecode(f, 'JUMP_IF_FALSE_OR_POP') self.assertInBytecode(f, 'POP_JUMP_IF_TRUE') + def test_elim_jump_to_uncond_jump4(self): + def f(): + for i in range(5): + if i > 3: + print(i) + self.check_jump_targets(f) + def test_elim_jump_after_return1(self): # Eliminate dead code: jumps immediately after returns can't be reached def f(cond1, cond2): @@ -413,7 +436,7 @@ class TestTranforms(BytecodeTestCase): return 5 return 6 self.assertNotInBytecode(f, 'JUMP_FORWARD') - self.assertNotInBytecode(f, 'JUMP_ABSOLUTE') + self.assertNotInBytecode(f, 'JUMP_BACKWARD') returns = [instr for instr in dis.get_instructions(f) if instr.opname == 'RETURN_VALUE'] self.assertLessEqual(len(returns), 6) @@ -580,6 +603,58 @@ class TestTranforms(BytecodeTestCase): 'not all arguments converted during string formatting'): eval("'%s, %s' % (x, *y)", {'x': 1, 'y': [2, 3]}) + def test_static_swaps_unpack_two(self): + def f(a, b): + a, b = a, b + b, a = a, b + self.assertNotInBytecode(f, "SWAP") + + def test_static_swaps_unpack_three(self): + def f(a, b, c): + a, b, c = a, b, c + a, c, b = a, b, c + b, a, c = a, b, c + b, c, a = a, b, c + c, a, b = a, b, c + c, b, a = a, b, c + self.assertNotInBytecode(f, "SWAP") + + def test_static_swaps_match_mapping(self): + for a, b, c in product("_a", "_b", "_c"): + pattern = f"{{'a': {a}, 'b': {b}, 'c': {c}}}" + with self.subTest(pattern): + code = compile_pattern_with_fast_locals(pattern) + self.assertNotInBytecode(code, "SWAP") + + def test_static_swaps_match_class(self): + forms = [ + "C({}, {}, {})", + "C({}, {}, c={})", + "C({}, b={}, c={})", + "C(a={}, b={}, c={})" + ] + for a, b, c in product("_a", "_b", "_c"): + for form in forms: + pattern = form.format(a, b, c) + with self.subTest(pattern): + code = compile_pattern_with_fast_locals(pattern) + self.assertNotInBytecode(code, "SWAP") + + def test_static_swaps_match_sequence(self): + swaps = {"*_, b, c", "a, *_, c", "a, b, *_"} + forms = ["{}, {}, {}", "{}, {}, *{}", "{}, *{}, {}", "*{}, {}, {}"] + for a, b, c in product("_a", "_b", "_c"): + for form in forms: + pattern = form.format(a, b, c) + with self.subTest(pattern): + code = compile_pattern_with_fast_locals(pattern) + if pattern in swaps: + # If this fails... great! Remove this pattern from swaps + # to prevent regressing on any improvement: + self.assertInBytecode(code, "SWAP") + else: + self.assertNotInBytecode(code, "SWAP") + class TestBuglets(unittest.TestCase): @@ -607,5 +682,376 @@ class TestBuglets(unittest.TestCase): compile("while True or not spam: pass", "", "exec") +class TestMarkingVariablesAsUnKnown(BytecodeTestCase): + + def setUp(self): + self.addCleanup(sys.settrace, sys.gettrace()) + sys.settrace(None) + + def test_load_fast_known_simple(self): + def f(): + x = 1 + y = x + x + self.assertInBytecode(f, 'LOAD_FAST') + + def test_load_fast_unknown_simple(self): + def f(): + if condition(): + x = 1 + print(x) + self.assertInBytecode(f, 'LOAD_FAST_CHECK') + self.assertNotInBytecode(f, 'LOAD_FAST') + + def test_load_fast_unknown_because_del(self): + def f(): + x = 1 + del x + print(x) + self.assertInBytecode(f, 'LOAD_FAST_CHECK') + self.assertNotInBytecode(f, 'LOAD_FAST') + + def test_load_fast_known_because_parameter(self): + def f1(x): + print(x) + self.assertInBytecode(f1, 'LOAD_FAST') + self.assertNotInBytecode(f1, 'LOAD_FAST_CHECK') + + def f2(*, x): + print(x) + self.assertInBytecode(f2, 'LOAD_FAST') + self.assertNotInBytecode(f2, 'LOAD_FAST_CHECK') + + def f3(*args): + print(args) + self.assertInBytecode(f3, 'LOAD_FAST') + self.assertNotInBytecode(f3, 'LOAD_FAST_CHECK') + + def f4(**kwargs): + print(kwargs) + self.assertInBytecode(f4, 'LOAD_FAST') + self.assertNotInBytecode(f4, 'LOAD_FAST_CHECK') + + def f5(x=0): + print(x) + self.assertInBytecode(f5, 'LOAD_FAST') + self.assertNotInBytecode(f5, 'LOAD_FAST_CHECK') + + def test_load_fast_known_because_already_loaded(self): + def f(): + if condition(): + x = 1 + print(x) + print(x) + self.assertInBytecode(f, 'LOAD_FAST_CHECK') + self.assertInBytecode(f, 'LOAD_FAST') + + def test_load_fast_known_multiple_branches(self): + def f(): + if condition(): + x = 1 + else: + x = 2 + print(x) + self.assertInBytecode(f, 'LOAD_FAST') + self.assertNotInBytecode(f, 'LOAD_FAST_CHECK') + + def test_load_fast_unknown_after_error(self): + def f(): + try: + res = 1 / 0 + except ZeroDivisionError: + pass + return res + # LOAD_FAST (known) still occurs in the no-exception branch. + # Assert that it doesn't occur in the LOAD_FAST_CHECK branch. + self.assertInBytecode(f, 'LOAD_FAST_CHECK') + + def test_load_fast_unknown_after_error_2(self): + def f(): + try: + 1 / 0 + except: + print(a, b, c, d, e, f, g) + a = b = c = d = e = f = g = 1 + self.assertInBytecode(f, 'LOAD_FAST_CHECK') + self.assertNotInBytecode(f, 'LOAD_FAST') + + def test_load_fast_too_many_locals(self): + # When there get to be too many locals to analyze completely, + # later locals are all converted to LOAD_FAST_CHECK, except + # when a store or prior load occurred in the same basicblock. + def f(): + a00 = a01 = a02 = a03 = a04 = a05 = a06 = a07 = a08 = a09 = 1 + a10 = a11 = a12 = a13 = a14 = a15 = a16 = a17 = a18 = a19 = 1 + a20 = a21 = a22 = a23 = a24 = a25 = a26 = a27 = a28 = a29 = 1 + a30 = a31 = a32 = a33 = a34 = a35 = a36 = a37 = a38 = a39 = 1 + a40 = a41 = a42 = a43 = a44 = a45 = a46 = a47 = a48 = a49 = 1 + a50 = a51 = a52 = a53 = a54 = a55 = a56 = a57 = a58 = a59 = 1 + a60 = a61 = a62 = a63 = a64 = a65 = a66 = a67 = a68 = a69 = 1 + a70 = a71 = a72 = a73 = a74 = a75 = a76 = a77 = a78 = a79 = 1 + del a72, a73 + print(a73) + print(a70, a71, a72, a73) + while True: + print(a00, a01, a62, a63) + print(a64, a65, a78, a79) + + for i in 0, 1, 62, 63: + # First 64 locals: analyze completely + self.assertInBytecode(f, 'LOAD_FAST', f"a{i:02}") + self.assertNotInBytecode(f, 'LOAD_FAST_CHECK', f"a{i:02}") + for i in 64, 65, 78, 79: + # Locals >=64 not in the same basicblock + self.assertInBytecode(f, 'LOAD_FAST_CHECK', f"a{i:02}") + self.assertNotInBytecode(f, 'LOAD_FAST', f"a{i:02}") + for i in 70, 71: + # Locals >=64 in the same basicblock + self.assertInBytecode(f, 'LOAD_FAST', f"a{i:02}") + self.assertNotInBytecode(f, 'LOAD_FAST_CHECK', f"a{i:02}") + # del statements should invalidate within basicblocks. + self.assertInBytecode(f, 'LOAD_FAST_CHECK', "a72") + self.assertNotInBytecode(f, 'LOAD_FAST', "a72") + # previous checked loads within a basicblock enable unchecked loads + self.assertInBytecode(f, 'LOAD_FAST_CHECK', "a73") + self.assertInBytecode(f, 'LOAD_FAST', "a73") + + def test_setting_lineno_no_undefined(self): + code = textwrap.dedent(f"""\ + def f(): + x = y = 2 + if not x: + return 4 + for i in range(55): + x + 6 + L = 7 + L = 8 + L = 9 + L = 10 + """) + ns = {} + exec(code, ns) + f = ns['f'] + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + co_code = f.__code__.co_code + def trace(frame, event, arg): + if event == 'line' and frame.f_lineno == 9: + frame.f_lineno = 3 + sys.settrace(None) + return None + return trace + sys.settrace(trace) + result = f() + self.assertIsNone(result) + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + self.assertEqual(f.__code__.co_code, co_code) + + def test_setting_lineno_one_undefined(self): + code = textwrap.dedent(f"""\ + def f(): + x = y = 2 + if not x: + return 4 + for i in range(55): + x + 6 + del x + L = 8 + L = 9 + L = 10 + """) + ns = {} + exec(code, ns) + f = ns['f'] + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + co_code = f.__code__.co_code + def trace(frame, event, arg): + if event == 'line' and frame.f_lineno == 9: + frame.f_lineno = 3 + sys.settrace(None) + return None + return trace + e = r"assigning None to 1 unbound local" + with self.assertWarnsRegex(RuntimeWarning, e): + sys.settrace(trace) + result = f() + self.assertEqual(result, 4) + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + self.assertEqual(f.__code__.co_code, co_code) + + def test_setting_lineno_two_undefined(self): + code = textwrap.dedent(f"""\ + def f(): + x = y = 2 + if not x: + return 4 + for i in range(55): + x + 6 + del x, y + L = 8 + L = 9 + L = 10 + """) + ns = {} + exec(code, ns) + f = ns['f'] + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + co_code = f.__code__.co_code + def trace(frame, event, arg): + if event == 'line' and frame.f_lineno == 9: + frame.f_lineno = 3 + sys.settrace(None) + return None + return trace + e = r"assigning None to 2 unbound locals" + with self.assertWarnsRegex(RuntimeWarning, e): + sys.settrace(trace) + result = f() + self.assertEqual(result, 4) + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + self.assertEqual(f.__code__.co_code, co_code) + + def make_function_with_no_checks(self): + code = textwrap.dedent("""\ + def f(): + x = 2 + L = 3 + L = 4 + L = 5 + if not L: + x + 7 + y = 2 + """) + ns = {} + exec(code, ns) + f = ns['f'] + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + return f + + def test_deleting_local_warns_and_assigns_none(self): + f = self.make_function_with_no_checks() + co_code = f.__code__.co_code + def trace(frame, event, arg): + if event == 'line' and frame.f_lineno == 4: + del frame.f_locals["x"] + sys.settrace(None) + return None + return trace + e = r"assigning None to unbound local 'x'" + with self.assertWarnsRegex(RuntimeWarning, e): + sys.settrace(trace) + f() + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + self.assertEqual(f.__code__.co_code, co_code) + + def test_modifying_local_does_not_add_check(self): + f = self.make_function_with_no_checks() + def trace(frame, event, arg): + if event == 'line' and frame.f_lineno == 4: + frame.f_locals["x"] = 42 + sys.settrace(None) + return None + return trace + sys.settrace(trace) + f() + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + + def test_initializing_local_does_not_add_check(self): + f = self.make_function_with_no_checks() + def trace(frame, event, arg): + if event == 'line' and frame.f_lineno == 4: + frame.f_locals["y"] = 42 + sys.settrace(None) + return None + return trace + sys.settrace(trace) + f() + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + + +class DirectiCfgOptimizerTests(CfgOptimizationTestCase): + + def cfg_optimization_test(self, insts, expected_insts, + consts=None, expected_consts=None): + if expected_consts is None: + expected_consts = consts + opt_insts, opt_consts = self.get_optimized(insts, consts) + self.assertInstructionsMatch(opt_insts, expected_insts) + self.assertEqual(opt_consts, expected_consts) + + def test_conditional_jump_forward_non_const_condition(self): + insts = [ + ('LOAD_NAME', 1, 11), + ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), + ('LOAD_CONST', 2, 13), + lbl, + ('LOAD_CONST', 3, 14), + ] + expected = [ + ('LOAD_NAME', '1', 11), + ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), + ('LOAD_CONST', '2', 13), + lbl, + ('LOAD_CONST', '3', 14) + ] + self.cfg_optimization_test(insts, expected, consts=list(range(5))) + + def test_conditional_jump_forward_const_condition(self): + # The unreachable branch of the jump is removed, the jump + # becomes redundant and is replaced by a NOP (for the lineno) + + insts = [ + ('LOAD_CONST', 3, 11), + ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), + ('LOAD_CONST', 2, 13), + lbl, + ('LOAD_CONST', 3, 14), + ] + expected = [ + ('NOP', None, 11), + ('NOP', None, 12), + ('LOAD_CONST', '3', 14) + ] + self.cfg_optimization_test(insts, expected, consts=list(range(5))) + + def test_conditional_jump_backward_non_const_condition(self): + insts = [ + lbl1 := self.Label(), + ('LOAD_NAME', 1, 11), + ('POP_JUMP_IF_TRUE', lbl1, 12), + ('LOAD_CONST', 2, 13), + ] + expected = [ + lbl := self.Label(), + ('LOAD_NAME', '1', 11), + ('POP_JUMP_IF_TRUE', lbl, 12), + ('LOAD_CONST', '2', 13) + ] + self.cfg_optimization_test(insts, expected, consts=list(range(5))) + + def test_conditional_jump_backward_const_condition(self): + # The unreachable branch of the jump is removed + insts = [ + lbl1 := self.Label(), + ('LOAD_CONST', 1, 11), + ('POP_JUMP_IF_TRUE', lbl1, 12), + ('LOAD_CONST', 2, 13), + ] + expected = [ + lbl := self.Label(), + ('NOP', None, 11), + ('JUMP', lbl, 12) + ] + self.cfg_optimization_test(insts, expected, consts=list(range(5))) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_peg_generator/__init__.py b/Lib/test/test_peg_generator/__init__.py index fa855f2104c..7c402c3d7c5 100644 --- a/Lib/test/test_peg_generator/__init__.py +++ b/Lib/test/test_peg_generator/__init__.py @@ -1,7 +1,18 @@ -import os - +import os.path +import unittest +from test import support from test.support import load_package_tests +# TODO: gh-92584: peg_generator uses distutils which was removed in Python 3.12 +raise unittest.SkipTest("distutils has been removed in Python 3.12") + + +if support.check_sanitizer(address=True, memory=True): + # bpo-46633: Skip the test because it is too slow when Python is built + # with ASAN/MSAN: between 5 and 20 minutes on GitHub Actions. + raise unittest.SkipTest("test too slow on ASAN/MSAN build") + + # Load all tests in package def load_tests(*args): return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_peg_generator/test_c_parser.py b/Lib/test/test_peg_generator/test_c_parser.py index b761bd493f5..1b3fcbb92f8 100644 --- a/Lib/test/test_peg_generator/test_c_parser.py +++ b/Lib/test/test_peg_generator/test_c_parser.py @@ -70,17 +70,33 @@ unittest.main() """ +@support.requires_subprocess() class TestCParser(unittest.TestCase): + + @classmethod + def setUpClass(cls): + # When running under regtest, a separate tempdir is used + # as the current directory and watched for left-overs. + # Reusing that as the base for temporary directories + # ensures everything is cleaned up properly and + # cleans up afterwards if not (with warnings). + cls.tmp_base = os.getcwd() + if os.path.samefile(cls.tmp_base, os_helper.SAVEDCWD): + cls.tmp_base = None + # Create a directory for the reuseable static library part of + # the pegen extension build process. This greatly reduces the + # runtime overhead of spawning compiler processes. + cls.library_dir = tempfile.mkdtemp(dir=cls.tmp_base) + cls.addClassCleanup(shutil.rmtree, cls.library_dir) + def setUp(self): self._backup_config_vars = dict(sysconfig._CONFIG_VARS) cmd = support.missing_compiler_executable() if cmd is not None: self.skipTest("The %r command is not found" % cmd) self.old_cwd = os.getcwd() - self.tmp_path = tempfile.mkdtemp() - change_cwd = os_helper.change_cwd(self.tmp_path) - change_cwd.__enter__() - self.addCleanup(change_cwd.__exit__, None, None, None) + self.tmp_path = tempfile.mkdtemp(dir=self.tmp_base) + self.enterContext(os_helper.change_cwd(self.tmp_path)) def tearDown(self): os.chdir(self.old_cwd) @@ -90,7 +106,10 @@ class TestCParser(unittest.TestCase): def build_extension(self, grammar_source): grammar = parse_string(grammar_source, GrammarParser) - generate_parser_c_extension(grammar, Path(self.tmp_path)) + # Because setUp() already changes the current directory to the + # temporary path, use a relative path here to prevent excessive + # path lengths when compiling. + generate_parser_c_extension(grammar, Path('.'), library_dir=self.library_dir) def run_test(self, grammar_source, test_source): self.build_extension(grammar_source) diff --git a/Lib/test/test_pep646_syntax.py b/Lib/test/test_pep646_syntax.py new file mode 100644 index 00000000000..3ffa82dc55f --- /dev/null +++ b/Lib/test/test_pep646_syntax.py @@ -0,0 +1,326 @@ +doctests = """ + +Setup + + >>> class AClass: + ... def __init__(self): + ... self._setitem_name = None + ... self._setitem_val = None + ... self._delitem_name = None + ... def __setitem__(self, name, val): + ... self._delitem_name = None + ... self._setitem_name = name + ... self._setitem_val = val + ... def __repr__(self): + ... if self._setitem_name is not None: + ... return f"A[{self._setitem_name}]={self._setitem_val}" + ... elif self._delitem_name is not None: + ... return f"delA[{self._delitem_name}]" + ... def __getitem__(self, name): + ... return ParameterisedA(name) + ... def __delitem__(self, name): + ... self._setitem_name = None + ... self._delitem_name = name + ... + >>> class ParameterisedA: + ... def __init__(self, name): + ... self._name = name + ... def __repr__(self): + ... return f"A[{self._name}]" + ... def __iter__(self): + ... for p in self._name: + ... yield p + >>> class B: + ... def __iter__(self): + ... yield StarredB() + ... def __repr__(self): + ... return "B" + >>> class StarredB: + ... def __repr__(self): + ... return "StarredB" + >>> A = AClass() + >>> b = B() + +Slices that are supposed to work, starring our custom B class + + >>> A[*b] + A[(StarredB,)] + >>> A[*b] = 1; A + A[(StarredB,)]=1 + >>> del A[*b]; A + delA[(StarredB,)] + + >>> A[*b, *b] + A[(StarredB, StarredB)] + >>> A[*b, *b] = 1; A + A[(StarredB, StarredB)]=1 + >>> del A[*b, *b]; A + delA[(StarredB, StarredB)] + + >>> A[b, *b] + A[(B, StarredB)] + >>> A[b, *b] = 1; A + A[(B, StarredB)]=1 + >>> del A[b, *b]; A + delA[(B, StarredB)] + + >>> A[*b, b] + A[(StarredB, B)] + >>> A[*b, b] = 1; A + A[(StarredB, B)]=1 + >>> del A[*b, b]; A + delA[(StarredB, B)] + + >>> A[b, b, *b] + A[(B, B, StarredB)] + >>> A[b, b, *b] = 1; A + A[(B, B, StarredB)]=1 + >>> del A[b, b, *b]; A + delA[(B, B, StarredB)] + + >>> A[*b, b, b] + A[(StarredB, B, B)] + >>> A[*b, b, b] = 1; A + A[(StarredB, B, B)]=1 + >>> del A[*b, b, b]; A + delA[(StarredB, B, B)] + + >>> A[b, *b, b] + A[(B, StarredB, B)] + >>> A[b, *b, b] = 1; A + A[(B, StarredB, B)]=1 + >>> del A[b, *b, b]; A + delA[(B, StarredB, B)] + + >>> A[b, b, *b, b] + A[(B, B, StarredB, B)] + >>> A[b, b, *b, b] = 1; A + A[(B, B, StarredB, B)]=1 + >>> del A[b, b, *b, b]; A + delA[(B, B, StarredB, B)] + + >>> A[b, *b, b, b] + A[(B, StarredB, B, B)] + >>> A[b, *b, b, b] = 1; A + A[(B, StarredB, B, B)]=1 + >>> del A[b, *b, b, b]; A + delA[(B, StarredB, B, B)] + + >>> A[A[b, *b, b]] + A[A[(B, StarredB, B)]] + >>> A[A[b, *b, b]] = 1; A + A[A[(B, StarredB, B)]]=1 + >>> del A[A[b, *b, b]]; A + delA[A[(B, StarredB, B)]] + + >>> A[*A[b, *b, b]] + A[(B, StarredB, B)] + >>> A[*A[b, *b, b]] = 1; A + A[(B, StarredB, B)]=1 + >>> del A[*A[b, *b, b]]; A + delA[(B, StarredB, B)] + + >>> A[b, ...] + A[(B, Ellipsis)] + >>> A[b, ...] = 1; A + A[(B, Ellipsis)]=1 + >>> del A[b, ...]; A + delA[(B, Ellipsis)] + + >>> A[*A[b, ...]] + A[(B, Ellipsis)] + >>> A[*A[b, ...]] = 1; A + A[(B, Ellipsis)]=1 + >>> del A[*A[b, ...]]; A + delA[(B, Ellipsis)] + +Slices that are supposed to work, starring a list + + >>> l = [1, 2, 3] + + >>> A[*l] + A[(1, 2, 3)] + >>> A[*l] = 1; A + A[(1, 2, 3)]=1 + >>> del A[*l]; A + delA[(1, 2, 3)] + + >>> A[*l, 4] + A[(1, 2, 3, 4)] + >>> A[*l, 4] = 1; A + A[(1, 2, 3, 4)]=1 + >>> del A[*l, 4]; A + delA[(1, 2, 3, 4)] + + >>> A[0, *l] + A[(0, 1, 2, 3)] + >>> A[0, *l] = 1; A + A[(0, 1, 2, 3)]=1 + >>> del A[0, *l]; A + delA[(0, 1, 2, 3)] + + >>> A[1:2, *l] + A[(slice(1, 2, None), 1, 2, 3)] + >>> A[1:2, *l] = 1; A + A[(slice(1, 2, None), 1, 2, 3)]=1 + >>> del A[1:2, *l]; A + delA[(slice(1, 2, None), 1, 2, 3)] + + >>> repr(A[1:2, *l]) == repr(A[1:2, 1, 2, 3]) + True + +Slices that are supposed to work, starring a tuple + + >>> t = (1, 2, 3) + + >>> A[*t] + A[(1, 2, 3)] + >>> A[*t] = 1; A + A[(1, 2, 3)]=1 + >>> del A[*t]; A + delA[(1, 2, 3)] + + >>> A[*t, 4] + A[(1, 2, 3, 4)] + >>> A[*t, 4] = 1; A + A[(1, 2, 3, 4)]=1 + >>> del A[*t, 4]; A + delA[(1, 2, 3, 4)] + + >>> A[0, *t] + A[(0, 1, 2, 3)] + >>> A[0, *t] = 1; A + A[(0, 1, 2, 3)]=1 + >>> del A[0, *t]; A + delA[(0, 1, 2, 3)] + + >>> A[1:2, *t] + A[(slice(1, 2, None), 1, 2, 3)] + >>> A[1:2, *t] = 1; A + A[(slice(1, 2, None), 1, 2, 3)]=1 + >>> del A[1:2, *t]; A + delA[(slice(1, 2, None), 1, 2, 3)] + + >>> repr(A[1:2, *t]) == repr(A[1:2, 1, 2, 3]) + True + +Starring an expression (rather than a name) in a slice + + >>> def returns_list(): + ... return [1, 2, 3] + + >>> A[returns_list()] + A[[1, 2, 3]] + >>> A[returns_list()] = 1; A + A[[1, 2, 3]]=1 + >>> del A[returns_list()]; A + delA[[1, 2, 3]] + + >>> A[returns_list(), 4] + A[([1, 2, 3], 4)] + >>> A[returns_list(), 4] = 1; A + A[([1, 2, 3], 4)]=1 + >>> del A[returns_list(), 4]; A + delA[([1, 2, 3], 4)] + + >>> A[*returns_list()] + A[(1, 2, 3)] + >>> A[*returns_list()] = 1; A + A[(1, 2, 3)]=1 + >>> del A[*returns_list()]; A + delA[(1, 2, 3)] + + >>> A[*returns_list(), 4] + A[(1, 2, 3, 4)] + >>> A[*returns_list(), 4] = 1; A + A[(1, 2, 3, 4)]=1 + >>> del A[*returns_list(), 4]; A + delA[(1, 2, 3, 4)] + + >>> A[0, *returns_list()] + A[(0, 1, 2, 3)] + >>> A[0, *returns_list()] = 1; A + A[(0, 1, 2, 3)]=1 + >>> del A[0, *returns_list()]; A + delA[(0, 1, 2, 3)] + + >>> A[*returns_list(), *returns_list()] + A[(1, 2, 3, 1, 2, 3)] + >>> A[*returns_list(), *returns_list()] = 1; A + A[(1, 2, 3, 1, 2, 3)]=1 + >>> del A[*returns_list(), *returns_list()]; A + delA[(1, 2, 3, 1, 2, 3)] + +Using both a starred object and a start:stop in a slice +(See also tests in test_syntax confirming that starring *inside* a start:stop +is *not* valid syntax.) + + >>> A[1:2, *b] + A[(slice(1, 2, None), StarredB)] + >>> A[*b, 1:2] + A[(StarredB, slice(1, 2, None))] + >>> A[1:2, *b, 1:2] + A[(slice(1, 2, None), StarredB, slice(1, 2, None))] + >>> A[*b, 1:2, *b] + A[(StarredB, slice(1, 2, None), StarredB)] + + >>> A[1:, *b] + A[(slice(1, None, None), StarredB)] + >>> A[*b, 1:] + A[(StarredB, slice(1, None, None))] + >>> A[1:, *b, 1:] + A[(slice(1, None, None), StarredB, slice(1, None, None))] + >>> A[*b, 1:, *b] + A[(StarredB, slice(1, None, None), StarredB)] + + >>> A[:1, *b] + A[(slice(None, 1, None), StarredB)] + >>> A[*b, :1] + A[(StarredB, slice(None, 1, None))] + >>> A[:1, *b, :1] + A[(slice(None, 1, None), StarredB, slice(None, 1, None))] + >>> A[*b, :1, *b] + A[(StarredB, slice(None, 1, None), StarredB)] + + >>> A[:, *b] + A[(slice(None, None, None), StarredB)] + >>> A[*b, :] + A[(StarredB, slice(None, None, None))] + >>> A[:, *b, :] + A[(slice(None, None, None), StarredB, slice(None, None, None))] + >>> A[*b, :, *b] + A[(StarredB, slice(None, None, None), StarredB)] + +*args annotated as starred expression + + >>> def f1(*args: *b): pass + >>> f1.__annotations__ + {'args': StarredB} + + >>> def f2(*args: *b, arg1): pass + >>> f2.__annotations__ + {'args': StarredB} + + >>> def f3(*args: *b, arg1: int): pass + >>> f3.__annotations__ + {'args': StarredB, 'arg1': } + + >>> def f4(*args: *b, arg1: int = 2): pass + >>> f4.__annotations__ + {'args': StarredB, 'arg1': } + + >>> def f5(*args: *b = (1,)): pass + Traceback (most recent call last): + ... + SyntaxError: invalid syntax +""" + +__test__ = {'doctests' : doctests} + +def test_main(verbose=False): + from test import support + from test import test_pep646_syntax + support.run_doctest(test_pep646_syntax, verbose) + +if __name__ == "__main__": + test_main(verbose=True) diff --git a/Lib/test/test_perf_profiler.py b/Lib/test/test_perf_profiler.py new file mode 100644 index 00000000000..2b977d78d39 --- /dev/null +++ b/Lib/test/test_perf_profiler.py @@ -0,0 +1,348 @@ +import unittest +import subprocess +import sys +import sysconfig +import os +import pathlib +from test import support +from test.support.script_helper import ( + make_script, + assert_python_failure, + assert_python_ok, +) +from test.support.os_helper import temp_dir + + +if not support.has_subprocess_support: + raise unittest.SkipTest("test module requires subprocess") + + +def supports_trampoline_profiling(): + perf_trampoline = sysconfig.get_config_var("PY_HAVE_PERF_TRAMPOLINE") + if not perf_trampoline: + return False + return int(perf_trampoline) == 1 + + +if not supports_trampoline_profiling(): + raise unittest.SkipTest("perf trampoline profiling not supported") + + +class TestPerfTrampoline(unittest.TestCase): + def setUp(self): + super().setUp() + self.perf_files = set(pathlib.Path("/tmp/").glob("perf-*.map")) + + def tearDown(self) -> None: + super().tearDown() + files_to_delete = ( + set(pathlib.Path("/tmp/").glob("perf-*.map")) - self.perf_files + ) + for file in files_to_delete: + file.unlink() + + def test_trampoline_works(self): + code = """if 1: + def foo(): + pass + + def bar(): + foo() + + def baz(): + bar() + + baz() + """ + with temp_dir() as script_dir: + script = make_script(script_dir, "perftest", code) + with subprocess.Popen( + [sys.executable, "-Xperf", script], + text=True, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + ) as process: + stdout, stderr = process.communicate() + + self.assertEqual(stderr, "") + self.assertEqual(stdout, "") + + perf_file = pathlib.Path(f"/tmp/perf-{process.pid}.map") + self.assertTrue(perf_file.exists()) + perf_file_contents = perf_file.read_text() + self.assertIn(f"py::foo:{script}", perf_file_contents) + self.assertIn(f"py::bar:{script}", perf_file_contents) + self.assertIn(f"py::baz:{script}", perf_file_contents) + + def test_trampoline_works_with_forks(self): + code = """if 1: + import os, sys + + def foo_fork(): + pass + + def bar_fork(): + foo_fork() + + def baz_fork(): + bar_fork() + + def foo(): + pid = os.fork() + if pid == 0: + print(os.getpid()) + baz_fork() + else: + _, status = os.waitpid(-1, 0) + sys.exit(status) + + def bar(): + foo() + + def baz(): + bar() + + baz() + """ + with temp_dir() as script_dir: + script = make_script(script_dir, "perftest", code) + with subprocess.Popen( + [sys.executable, "-Xperf", script], + text=True, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + ) as process: + stdout, stderr = process.communicate() + + self.assertEqual(process.returncode, 0) + self.assertEqual(stderr, "") + child_pid = int(stdout.strip()) + perf_file = pathlib.Path(f"/tmp/perf-{process.pid}.map") + perf_child_file = pathlib.Path(f"/tmp/perf-{child_pid}.map") + self.assertTrue(perf_file.exists()) + self.assertTrue(perf_child_file.exists()) + + perf_file_contents = perf_file.read_text() + self.assertIn(f"py::foo:{script}", perf_file_contents) + self.assertIn(f"py::bar:{script}", perf_file_contents) + self.assertIn(f"py::baz:{script}", perf_file_contents) + + child_perf_file_contents = perf_child_file.read_text() + self.assertIn(f"py::foo_fork:{script}", child_perf_file_contents) + self.assertIn(f"py::bar_fork:{script}", child_perf_file_contents) + self.assertIn(f"py::baz_fork:{script}", child_perf_file_contents) + + def test_sys_api(self): + code = """if 1: + import sys + def foo(): + pass + + def spam(): + pass + + def bar(): + sys.deactivate_stack_trampoline() + foo() + sys.activate_stack_trampoline("perf") + spam() + + def baz(): + bar() + + sys.activate_stack_trampoline("perf") + baz() + """ + with temp_dir() as script_dir: + script = make_script(script_dir, "perftest", code) + with subprocess.Popen( + [sys.executable, script], + text=True, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + ) as process: + stdout, stderr = process.communicate() + + self.assertEqual(stderr, "") + self.assertEqual(stdout, "") + + perf_file = pathlib.Path(f"/tmp/perf-{process.pid}.map") + self.assertTrue(perf_file.exists()) + perf_file_contents = perf_file.read_text() + self.assertNotIn(f"py::foo:{script}", perf_file_contents) + self.assertIn(f"py::spam:{script}", perf_file_contents) + self.assertIn(f"py::bar:{script}", perf_file_contents) + self.assertIn(f"py::baz:{script}", perf_file_contents) + + def test_sys_api_with_existing_trampoline(self): + code = """if 1: + import sys + sys.activate_stack_trampoline("perf") + sys.activate_stack_trampoline("perf") + """ + assert_python_ok("-c", code) + + def test_sys_api_with_invalid_trampoline(self): + code = """if 1: + import sys + sys.activate_stack_trampoline("invalid") + """ + rc, out, err = assert_python_failure("-c", code) + self.assertIn("invalid backend: invalid", err.decode()) + + def test_sys_api_get_status(self): + code = """if 1: + import sys + sys.activate_stack_trampoline("perf") + assert sys.is_stack_trampoline_active() is True + sys.deactivate_stack_trampoline() + assert sys.is_stack_trampoline_active() is False + """ + assert_python_ok("-c", code) + + +def is_unwinding_reliable(): + cflags = sysconfig.get_config_var("PY_CORE_CFLAGS") + if not cflags: + return False + return "no-omit-frame-pointer" in cflags + + +def perf_command_works(): + try: + cmd = ["perf", "--help"] + stdout = subprocess.check_output(cmd, text=True) + except (subprocess.SubprocessError, OSError): + return False + + # perf version does not return a version number on Fedora. Use presence + # of "perf.data" in help as indicator that it's perf from Linux tools. + if "perf.data" not in stdout: + return False + + # Check that we can run a simple perf run + with temp_dir() as script_dir: + try: + output_file = script_dir + "/perf_output.perf" + cmd = ( + "perf", + "record", + "-g", + "--call-graph=fp", + "-o", + output_file, + "--", + sys.executable, + "-c", + 'print("hello")', + ) + stdout = subprocess.check_output( + cmd, cwd=script_dir, text=True, stderr=subprocess.STDOUT + ) + except (subprocess.SubprocessError, OSError): + return False + + if "hello" not in stdout: + return False + + return True + + +def run_perf(cwd, *args, **env_vars): + if env_vars: + env = os.environ.copy() + env.update(env_vars) + else: + env = None + output_file = cwd + "/perf_output.perf" + base_cmd = ("perf", "record", "-g", "--call-graph=fp", "-o", output_file, "--") + proc = subprocess.run( + base_cmd + args, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=env, + ) + if proc.returncode: + print(proc.stderr) + raise ValueError(f"Perf failed with return code {proc.returncode}") + + base_cmd = ("perf", "script") + proc = subprocess.run( + ("perf", "script", "-i", output_file), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=env, + check=True, + ) + return proc.stdout.decode("utf-8", "replace"), proc.stderr.decode( + "utf-8", "replace" + ) + + +@unittest.skipUnless(perf_command_works(), "perf command doesn't work") +@unittest.skipUnless(is_unwinding_reliable(), "Unwinding is unreliable") +@support.skip_if_sanitizer(address=True, memory=True, ub=True) +class TestPerfProfiler(unittest.TestCase): + def setUp(self): + super().setUp() + self.perf_files = set(pathlib.Path("/tmp/").glob("perf-*.map")) + + def tearDown(self) -> None: + super().tearDown() + files_to_delete = ( + set(pathlib.Path("/tmp/").glob("perf-*.map")) - self.perf_files + ) + for file in files_to_delete: + file.unlink() + + def test_python_calls_appear_in_the_stack_if_perf_activated(self): + with temp_dir() as script_dir: + code = """if 1: + def foo(n): + x = 0 + for i in range(n): + x += i + + def bar(n): + foo(n) + + def baz(n): + bar(n) + + baz(10000000) + """ + script = make_script(script_dir, "perftest", code) + stdout, stderr = run_perf(script_dir, sys.executable, "-Xperf", script) + self.assertEqual(stderr, "") + + self.assertIn(f"py::foo:{script}", stdout) + self.assertIn(f"py::bar:{script}", stdout) + self.assertIn(f"py::baz:{script}", stdout) + + def test_python_calls_do_not_appear_in_the_stack_if_perf_activated(self): + with temp_dir() as script_dir: + code = """if 1: + def foo(n): + x = 0 + for i in range(n): + x += i + + def bar(n): + foo(n) + + def baz(n): + bar(n) + + baz(10000000) + """ + script = make_script(script_dir, "perftest", code) + stdout, stderr = run_perf(script_dir, sys.executable, script) + self.assertEqual(stderr, "") + + self.assertNotIn(f"py::foo:{script}", stdout) + self.assertNotIn(f"py::bar:{script}", stdout) + self.assertNotIn(f"py::baz:{script}", stdout) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py index 057af21e71f..44fdca7a6b1 100644 --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -154,6 +154,29 @@ class PyIdPersPicklerTests(AbstractIdentityPersistentPicklerTests, return obj check(PersPickler) + @support.cpython_only + def test_custom_pickler_dispatch_table_memleak(self): + # See https://github.com/python/cpython/issues/89988 + + class Pickler(self.pickler): + def __init__(self, *args, **kwargs): + self.dispatch_table = table + super().__init__(*args, **kwargs) + + class DispatchTable: + pass + + table = DispatchTable() + pickler = Pickler(io.BytesIO()) + self.assertIs(pickler.dispatch_table, table) + table_ref = weakref.ref(table) + self.assertIsNotNone(table_ref()) + del pickler + del table + support.gc_collect() + self.assertIsNone(table_ref()) + + @support.cpython_only def test_unpickler_reference_cycle(self): def check(Unpickler): diff --git a/Lib/test/test_pipes.py b/Lib/test/test_pipes.py index 6335e7cbe09..09e21153ec8 100644 --- a/Lib/test/test_pipes.py +++ b/Lib/test/test_pipes.py @@ -1,10 +1,12 @@ -import pipes import os import string import unittest import shutil from test.support import reap_children, unix_shell from test.support.os_helper import TESTFN, unlink +from test.support.warnings_helper import import_deprecated + +pipes = import_deprecated("pipes") if os.name != 'posix': diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index 1a688775f46..72942dda342 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -79,6 +79,7 @@ class PlatformTest(unittest.TestCase): res = platform.architecture() @os_helper.skip_unless_symlink + @support.requires_subprocess() def test_architecture_via_symlink(self): # issue3762 with support.PythonSymlink() as py: cmd = "-c", "import platform; print(platform.architecture())" @@ -228,6 +229,14 @@ class PlatformTest(unittest.TestCase): self.assertEqual(res[-1], res.processor) self.assertEqual(len(res), 6) + @unittest.skipUnless(sys.platform.startswith('win'), "windows only test") + def test_uname_win32_without_wmi(self): + def raises_oserror(*a): + raise OSError() + + with support.swap_attr(platform, '_wmi_query', raises_oserror): + self.test_uname() + def test_uname_cast_to_tuple(self): res = platform.uname() expected = ( @@ -268,7 +277,16 @@ class PlatformTest(unittest.TestCase): self.assertEqual(res[:], expected) self.assertEqual(res[:5], expected[:5]) + def test_uname_fields(self): + self.assertIn('processor', platform.uname()._fields) + + def test_uname_asdict(self): + res = platform.uname()._asdict() + self.assertEqual(len(res), 6) + self.assertIn('processor', res) + @unittest.skipIf(sys.platform in ['win32', 'OpenVMS'], "uname -p not used") + @support.requires_subprocess() def test_uname_processor(self): """ On some systems, the processor must match the output @@ -287,24 +305,31 @@ class PlatformTest(unittest.TestCase): # on 64 bit Windows: if PROCESSOR_ARCHITEW6432 exists we should be # using it, per # http://blogs.msdn.com/david.wang/archive/2006/03/26/HOWTO-Detect-Process-Bitness.aspx - try: + + # We also need to suppress WMI checks, as those are reliable and + # overrule the environment variables + def raises_oserror(*a): + raise OSError() + + with support.swap_attr(platform, '_wmi_query', raises_oserror): with os_helper.EnvironmentVarGuard() as environ: - if 'PROCESSOR_ARCHITEW6432' in environ: - del environ['PROCESSOR_ARCHITEW6432'] - environ['PROCESSOR_ARCHITECTURE'] = 'foo' - platform._uname_cache = None - system, node, release, version, machine, processor = platform.uname() - self.assertEqual(machine, 'foo') - environ['PROCESSOR_ARCHITEW6432'] = 'bar' - platform._uname_cache = None - system, node, release, version, machine, processor = platform.uname() - self.assertEqual(machine, 'bar') - finally: - platform._uname_cache = None + try: + if 'PROCESSOR_ARCHITEW6432' in environ: + del environ['PROCESSOR_ARCHITEW6432'] + environ['PROCESSOR_ARCHITECTURE'] = 'foo' + platform._uname_cache = None + system, node, release, version, machine, processor = platform.uname() + self.assertEqual(machine, 'foo') + environ['PROCESSOR_ARCHITEW6432'] = 'bar' + platform._uname_cache = None + system, node, release, version, machine, processor = platform.uname() + self.assertEqual(machine, 'bar') + finally: + platform._uname_cache = None def test_java_ver(self): res = platform.java_ver() - if sys.platform == 'java': + if sys.platform == 'java': # Is never actually checked in CI self.assertTrue(all(res)) def test_win32_ver(self): @@ -362,6 +387,7 @@ class PlatformTest(unittest.TestCase): # parent support.wait_process(pid, exitcode=0) + @unittest.skipIf(support.is_emscripten, "Does not apply to Emscripten") def test_libc_ver(self): # check that libc_ver(executable) doesn't raise an exception if os.path.isdir(sys.executable) and \ diff --git a/Lib/test/test_poll.py b/Lib/test/test_poll.py index 82bbb3af9f1..02165a0244d 100644 --- a/Lib/test/test_poll.py +++ b/Lib/test/test_poll.py @@ -7,7 +7,9 @@ import select import threading import time import unittest -from test.support import cpython_only +from test.support import ( + cpython_only, requires_subprocess, requires_working_socket +) from test.support import threading_helper from test.support.os_helper import TESTFN @@ -17,6 +19,7 @@ try: except AttributeError: raise unittest.SkipTest("select.poll not defined") +requires_working_socket(module=True) def find_ready_matching(ready, flag): match = [] @@ -120,12 +123,12 @@ class PollTests(unittest.TestCase): # Another test case for poll(). This is copied from the test case for # select(), modified to use poll() instead. + @requires_subprocess() def test_poll2(self): cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done' proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, bufsize=0) - proc.__enter__() - self.addCleanup(proc.__exit__, None, None, None) + self.enterContext(proc) p = proc.stdout pollster = select.poll() pollster.register( p, select.POLLIN ) diff --git a/Lib/test/test_popen.py b/Lib/test/test_popen.py index cac2f6177f3..e6bfc480cbd 100644 --- a/Lib/test/test_popen.py +++ b/Lib/test/test_popen.py @@ -19,6 +19,7 @@ python = sys.executable if ' ' in python: python = '"' + python + '"' # quote embedded space for cmdline +@support.requires_subprocess() class PopenTest(unittest.TestCase): def _do_test_commandline(self, cmdline, expected): diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py index 23c6be3a801..fa41ba0b6e4 100644 --- a/Lib/test/test_poplib.py +++ b/Lib/test/test_poplib.py @@ -12,11 +12,14 @@ import threading import unittest from unittest import TestCase, skipUnless from test import support as test_support -from test.support import _asynchat as asynchat -from test.support import _asyncore as asyncore from test.support import hashlib_helper from test.support import socket_helper from test.support import threading_helper +from test.support import asynchat +from test.support import asyncore + + +test_support.requires_working_socket(module=True) HOST = socket_helper.HOST PORT = 0 @@ -314,11 +317,11 @@ class TestPOP3Class(TestCase): def test_rpop(self): self.assertOK(self.client.rpop('foo')) - @hashlib_helper.requires_hashdigest('md5') + @hashlib_helper.requires_hashdigest('md5', openssl=True) def test_apop_normal(self): self.assertOK(self.client.apop('foo', 'dummypassword')) - @hashlib_helper.requires_hashdigest('md5') + @hashlib_helper.requires_hashdigest('md5', openssl=True) def test_apop_REDOS(self): # Replace welcome with very long evil welcome. # NB The upper bound on welcome length is currently 2048. @@ -419,13 +422,6 @@ class TestPOP3_SSLClass(TestPOP3Class): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE - self.assertRaises(ValueError, poplib.POP3_SSL, self.server.host, - self.server.port, keyfile=CERTFILE, context=ctx) - self.assertRaises(ValueError, poplib.POP3_SSL, self.server.host, - self.server.port, certfile=CERTFILE, context=ctx) - self.assertRaises(ValueError, poplib.POP3_SSL, self.server.host, - self.server.port, keyfile=CERTFILE, - certfile=CERTFILE, context=ctx) self.client.quit() self.client = poplib.POP3_SSL(self.server.host, self.server.port, diff --git a/Lib/test/test_positional_only_arg.py b/Lib/test/test_positional_only_arg.py index 0a9503e2025..1a193814d75 100644 --- a/Lib/test/test_positional_only_arg.py +++ b/Lib/test/test_positional_only_arg.py @@ -23,10 +23,11 @@ class PositionalOnlyTestCase(unittest.TestCase): compile(codestr + "\n", "", "single") def test_invalid_syntax_errors(self): - check_syntax_error(self, "def f(a, b = 5, /, c): pass", "non-default argument follows default argument") - check_syntax_error(self, "def f(a = 5, b, /, c): pass", "non-default argument follows default argument") - check_syntax_error(self, "def f(a = 5, b=1, /, c, *, d=2): pass", "non-default argument follows default argument") - check_syntax_error(self, "def f(a = 5, b, /): pass", "non-default argument follows default argument") + check_syntax_error(self, "def f(a, b = 5, /, c): pass", "parameter without a default follows parameter with a default") + check_syntax_error(self, "def f(a = 5, b, /, c): pass", "parameter without a default follows parameter with a default") + check_syntax_error(self, "def f(a = 5, b=1, /, c, *, d=2): pass", "parameter without a default follows parameter with a default") + check_syntax_error(self, "def f(a = 5, b, /): pass", "parameter without a default follows parameter with a default") + check_syntax_error(self, "def f(a, /, b = 5, c): pass", "parameter without a default follows parameter with a default") check_syntax_error(self, "def f(*args, /): pass") check_syntax_error(self, "def f(*args, a, /): pass") check_syntax_error(self, "def f(**kwargs, /): pass") @@ -44,10 +45,11 @@ class PositionalOnlyTestCase(unittest.TestCase): check_syntax_error(self, "def f(a, *, c, /, d, e): pass") def test_invalid_syntax_errors_async(self): - check_syntax_error(self, "async def f(a, b = 5, /, c): pass", "non-default argument follows default argument") - check_syntax_error(self, "async def f(a = 5, b, /, c): pass", "non-default argument follows default argument") - check_syntax_error(self, "async def f(a = 5, b=1, /, c, d=2): pass", "non-default argument follows default argument") - check_syntax_error(self, "async def f(a = 5, b, /): pass", "non-default argument follows default argument") + check_syntax_error(self, "async def f(a, b = 5, /, c): pass", "parameter without a default follows parameter with a default") + check_syntax_error(self, "async def f(a = 5, b, /, c): pass", "parameter without a default follows parameter with a default") + check_syntax_error(self, "async def f(a = 5, b=1, /, c, d=2): pass", "parameter without a default follows parameter with a default") + check_syntax_error(self, "async def f(a = 5, b, /): pass", "parameter without a default follows parameter with a default") + check_syntax_error(self, "async def f(a, /, b = 5, c): pass", "parameter without a default follows parameter with a default") check_syntax_error(self, "async def f(*args, /): pass") check_syntax_error(self, "async def f(*args, a, /): pass") check_syntax_error(self, "async def f(**kwargs, /): pass") @@ -231,9 +233,11 @@ class PositionalOnlyTestCase(unittest.TestCase): self.assertEqual(x(1, 2), 3) def test_invalid_syntax_lambda(self): - check_syntax_error(self, "lambda a, b = 5, /, c: None", "non-default argument follows default argument") - check_syntax_error(self, "lambda a = 5, b, /, c: None", "non-default argument follows default argument") - check_syntax_error(self, "lambda a = 5, b, /: None", "non-default argument follows default argument") + check_syntax_error(self, "lambda a, b = 5, /, c: None", "parameter without a default follows parameter with a default") + check_syntax_error(self, "lambda a = 5, b, /, c: None", "parameter without a default follows parameter with a default") + check_syntax_error(self, "lambda a = 5, b=1, /, c, *, d=2: None", "parameter without a default follows parameter with a default") + check_syntax_error(self, "lambda a = 5, b, /: None", "parameter without a default follows parameter with a default") + check_syntax_error(self, "lambda a, /, b = 5, c: None", "parameter without a default follows parameter with a default") check_syntax_error(self, "lambda *args, /: None") check_syntax_error(self, "lambda *args, a, /: None") check_syntax_error(self, "lambda **kwargs, /: None") diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 56b72f465c1..77f42f7f9c9 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -15,18 +15,26 @@ import signal import time import os import platform -import pwd import stat import tempfile import unittest import warnings import textwrap +from contextlib import contextmanager + +try: + import pwd +except ImportError: + pwd = None _DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(), os_helper.TESTFN + '-dummy-symlink') -requires_32b = unittest.skipUnless(sys.maxsize < 2**32, - 'test is only meaningful on 32-bit builds') +requires_32b = unittest.skipUnless( + # Emscripten/WASI have 32 bits pointers, but support 64 bits syscall args. + sys.maxsize < 2**32 and not (support.is_emscripten or support.is_wasi), + 'test is only meaningful on 32-bit builds' +) def _supports_sched(): if not hasattr(posix, 'sched_getscheduler'): @@ -45,19 +53,13 @@ class PosixTester(unittest.TestCase): def setUp(self): # create empty file + self.addCleanup(os_helper.unlink, os_helper.TESTFN) with open(os_helper.TESTFN, "wb"): pass - self.teardown_files = [ os_helper.TESTFN ] - self._warnings_manager = warnings_helper.check_warnings() - self._warnings_manager.__enter__() + self.enterContext(warnings_helper.check_warnings()) warnings.filterwarnings('ignore', '.* potential security risk .*', RuntimeWarning) - def tearDown(self): - for teardown_file in self.teardown_files: - os_helper.unlink(teardown_file) - self._warnings_manager.__exit__(None, None, None) - def testNoArgFunctions(self): # test posix functions which take no arguments and have # no side-effects which we need to cleanup (e.g., fork, wait, abort) @@ -70,8 +72,9 @@ class PosixTester(unittest.TestCase): for name in NO_ARG_FUNCTIONS: posix_func = getattr(posix, name, None) if posix_func is not None: - posix_func() - self.assertRaises(TypeError, posix_func, 1) + with self.subTest(name): + posix_func() + self.assertRaises(TypeError, posix_func, 1) @unittest.skipUnless(hasattr(posix, 'getresuid'), 'test needs posix.getresuid()') @@ -125,6 +128,7 @@ class PosixTester(unittest.TestCase): @unittest.skipUnless(hasattr(posix, 'initgroups'), "test needs os.initgroups()") + @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()") def test_initgroups(self): # It takes a string and an integer; check that it raises a TypeError # for other argument lists. @@ -183,7 +187,7 @@ class PosixTester(unittest.TestCase): posix.truncate(os_helper.TESTFN, 0) @unittest.skipUnless(getattr(os, 'execve', None) in os.supports_fd, "test needs execve() to support the fd parameter") - @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()") + @support.requires_fork() def test_fexecve(self): fp = os.open(sys.executable, os.O_RDONLY) try: @@ -198,7 +202,7 @@ class PosixTester(unittest.TestCase): @unittest.skipUnless(hasattr(posix, 'waitid'), "test needs posix.waitid()") - @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()") + @support.requires_fork() def test_waitid(self): pid = os.fork() if pid == 0: @@ -208,7 +212,7 @@ class PosixTester(unittest.TestCase): res = posix.waitid(posix.P_PID, pid, posix.WEXITED) self.assertEqual(pid, res.si_pid) - @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()") + @support.requires_fork() def test_register_at_fork(self): with self.assertRaises(TypeError, msg="Positional args not allowed"): os.register_at_fork(lambda: None) @@ -543,6 +547,7 @@ class PosixTester(unittest.TestCase): @unittest.skipUnless(hasattr(posix, 'dup'), 'test needs posix.dup()') + @unittest.skipIf(support.is_wasi, "WASI does not have dup()") def test_dup(self): fp = open(os_helper.TESTFN) try: @@ -560,6 +565,7 @@ class PosixTester(unittest.TestCase): @unittest.skipUnless(hasattr(posix, 'dup2'), 'test needs posix.dup2()') + @unittest.skipIf(support.is_wasi, "WASI does not have dup2()") def test_dup2(self): fp1 = open(os_helper.TESTFN) fp2 = open(os_helper.TESTFN) @@ -571,6 +577,7 @@ class PosixTester(unittest.TestCase): @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC") @support.requires_linux_version(2, 6, 23) + @support.requires_subprocess() def test_oscloexec(self): fd = os.open(os_helper.TESTFN, os.O_RDONLY|os.O_CLOEXEC) self.addCleanup(os.close, fd) @@ -627,7 +634,7 @@ class PosixTester(unittest.TestCase): self.assertTrue(posix.stat(os_helper.TESTFN)) self.assertTrue(posix.stat(os.fsencode(os_helper.TESTFN))) - self.assertWarnsRegex(DeprecationWarning, + self.assertRaisesRegex(TypeError, 'should be string, bytes, os.PathLike or integer, not', posix.stat, bytearray(os.fsencode(os_helper.TESTFN))) self.assertRaisesRegex(TypeError, @@ -730,7 +737,11 @@ class PosixTester(unittest.TestCase): is_root = (uid in (0, 1)) else: is_root = (uid == 0) - if is_root: + if support.is_emscripten: + # Emscripten getuid() / geteuid() always return 0 (root), but + # cannot chown uid/gid to random value. + pass + elif is_root: # Try an amusingly large uid/gid to make sure we handle # large unsigned values. (chown lets you use any # uid/gid you like, even if they aren't defined.) @@ -775,7 +786,8 @@ class PosixTester(unittest.TestCase): self.assertRaises(TypeError, chown_func, first_param, uid, t(gid)) check_stat(uid, gid) - @unittest.skipUnless(hasattr(posix, 'chown'), "test needs os.chown()") + @os_helper.skip_unless_working_chmod + @unittest.skipIf(support.is_emscripten, "getgid() is a stub") def test_chown(self): # raise an OSError if the file does not exist os.unlink(os_helper.TESTFN) @@ -785,7 +797,9 @@ class PosixTester(unittest.TestCase): os_helper.create_empty_file(os_helper.TESTFN) self._test_all_chown_common(posix.chown, os_helper.TESTFN, posix.stat) + @os_helper.skip_unless_working_chmod @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()") + @unittest.skipIf(support.is_emscripten, "getgid() is a stub") def test_fchown(self): os.unlink(os_helper.TESTFN) @@ -798,6 +812,7 @@ class PosixTester(unittest.TestCase): finally: test_file.close() + @os_helper.skip_unless_working_chmod @unittest.skipUnless(hasattr(posix, 'lchown'), "test needs os.lchown()") def test_lchown(self): os.unlink(os_helper.TESTFN) @@ -826,11 +841,8 @@ class PosixTester(unittest.TestCase): def test_listdir_bytes_like(self): for cls in bytearray, memoryview: - with self.assertWarns(DeprecationWarning): - names = posix.listdir(cls(b'.')) - self.assertIn(os.fsencode(os_helper.TESTFN), names) - for name in names: - self.assertIs(type(name), bytes) + with self.assertRaises(TypeError): + posix.listdir(cls(b'.')) @unittest.skipUnless(posix.listdir in os.supports_fd, "test needs fd support for posix.listdir()") @@ -958,8 +970,8 @@ class PosixTester(unittest.TestCase): self.assertTrue(hasattr(testfn_st, 'st_flags')) + self.addCleanup(os_helper.unlink, _DUMMY_SYMLINK) os.symlink(os_helper.TESTFN, _DUMMY_SYMLINK) - self.teardown_files.append(_DUMMY_SYMLINK) dummy_symlink_st = os.lstat(_DUMMY_SYMLINK) def chflags_nofollow(path, flags): @@ -1055,6 +1067,7 @@ class PosixTester(unittest.TestCase): @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()") @unittest.skipUnless(hasattr(os, 'popen'), "test needs os.popen()") + @support.requires_subprocess() def test_getgroups(self): with os.popen('id -G 2>/dev/null') as idg: groups = idg.read().strip() @@ -1081,187 +1094,6 @@ class PosixTester(unittest.TestCase): symdiff = idg_groups.symmetric_difference(posix.getgroups()) self.assertTrue(not symdiff or symdiff == {posix.getegid()}) - # tests for the posix *at functions follow - - @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()") - def test_access_dir_fd(self): - f = posix.open(posix.getcwd(), posix.O_RDONLY) - try: - self.assertTrue(posix.access(os_helper.TESTFN, os.R_OK, dir_fd=f)) - finally: - posix.close(f) - - @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()") - def test_chmod_dir_fd(self): - os.chmod(os_helper.TESTFN, stat.S_IRUSR) - - f = posix.open(posix.getcwd(), posix.O_RDONLY) - try: - posix.chmod(os_helper.TESTFN, stat.S_IRUSR | stat.S_IWUSR, dir_fd=f) - - s = posix.stat(os_helper.TESTFN) - self.assertEqual(s[0] & stat.S_IRWXU, stat.S_IRUSR | stat.S_IWUSR) - finally: - posix.close(f) - - @unittest.skipUnless(hasattr(os, 'chown') and (os.chown in os.supports_dir_fd), - "test needs dir_fd support in os.chown()") - def test_chown_dir_fd(self): - os_helper.unlink(os_helper.TESTFN) - os_helper.create_empty_file(os_helper.TESTFN) - - f = posix.open(posix.getcwd(), posix.O_RDONLY) - try: - posix.chown(os_helper.TESTFN, os.getuid(), os.getgid(), dir_fd=f) - finally: - posix.close(f) - - @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()") - def test_stat_dir_fd(self): - os_helper.unlink(os_helper.TESTFN) - with open(os_helper.TESTFN, 'w') as outfile: - outfile.write("testline\n") - - f = posix.open(posix.getcwd(), posix.O_RDONLY) - try: - s1 = posix.stat(os_helper.TESTFN) - s2 = posix.stat(os_helper.TESTFN, dir_fd=f) - self.assertEqual(s1, s2) - s2 = posix.stat(os_helper.TESTFN, dir_fd=None) - self.assertEqual(s1, s2) - self.assertRaisesRegex(TypeError, 'should be integer or None, not', - posix.stat, os_helper.TESTFN, dir_fd=posix.getcwd()) - self.assertRaisesRegex(TypeError, 'should be integer or None, not', - posix.stat, os_helper.TESTFN, dir_fd=float(f)) - self.assertRaises(OverflowError, - posix.stat, os_helper.TESTFN, dir_fd=10**20) - finally: - posix.close(f) - - @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()") - def test_utime_dir_fd(self): - f = posix.open(posix.getcwd(), posix.O_RDONLY) - try: - now = time.time() - posix.utime(os_helper.TESTFN, None, dir_fd=f) - posix.utime(os_helper.TESTFN, dir_fd=f) - self.assertRaises(TypeError, posix.utime, os_helper.TESTFN, - now, dir_fd=f) - self.assertRaises(TypeError, posix.utime, os_helper.TESTFN, - (None, None), dir_fd=f) - self.assertRaises(TypeError, posix.utime, os_helper.TESTFN, - (now, None), dir_fd=f) - self.assertRaises(TypeError, posix.utime, os_helper.TESTFN, - (None, now), dir_fd=f) - self.assertRaises(TypeError, posix.utime, os_helper.TESTFN, - (now, "x"), dir_fd=f) - posix.utime(os_helper.TESTFN, (int(now), int(now)), dir_fd=f) - posix.utime(os_helper.TESTFN, (now, now), dir_fd=f) - posix.utime(os_helper.TESTFN, - (int(now), int((now - int(now)) * 1e9)), dir_fd=f) - posix.utime(os_helper.TESTFN, dir_fd=f, - times=(int(now), int((now - int(now)) * 1e9))) - - # try dir_fd and follow_symlinks together - if os.utime in os.supports_follow_symlinks: - try: - posix.utime(os_helper.TESTFN, follow_symlinks=False, - dir_fd=f) - except ValueError: - # whoops! using both together not supported on this platform. - pass - - finally: - posix.close(f) - - @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()") - def test_link_dir_fd(self): - f = posix.open(posix.getcwd(), posix.O_RDONLY) - try: - posix.link(os_helper.TESTFN, os_helper.TESTFN + 'link', - src_dir_fd=f, dst_dir_fd=f) - except PermissionError as e: - self.skipTest('posix.link(): %s' % e) - else: - # should have same inodes - self.assertEqual(posix.stat(os_helper.TESTFN)[1], - posix.stat(os_helper.TESTFN + 'link')[1]) - finally: - posix.close(f) - os_helper.unlink(os_helper.TESTFN + 'link') - - @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()") - def test_mkdir_dir_fd(self): - f = posix.open(posix.getcwd(), posix.O_RDONLY) - try: - posix.mkdir(os_helper.TESTFN + 'dir', dir_fd=f) - posix.stat(os_helper.TESTFN + 'dir') # should not raise exception - finally: - posix.close(f) - os_helper.rmtree(os_helper.TESTFN + 'dir') - - @unittest.skipUnless(hasattr(os, 'mknod') - and (os.mknod in os.supports_dir_fd) - and hasattr(stat, 'S_IFIFO'), - "test requires both stat.S_IFIFO and dir_fd support for os.mknod()") - def test_mknod_dir_fd(self): - # Test using mknodat() to create a FIFO (the only use specified - # by POSIX). - os_helper.unlink(os_helper.TESTFN) - mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR - f = posix.open(posix.getcwd(), posix.O_RDONLY) - try: - posix.mknod(os_helper.TESTFN, mode, 0, dir_fd=f) - except OSError as e: - # Some old systems don't allow unprivileged users to use - # mknod(), or only support creating device nodes. - self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES)) - else: - self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode)) - finally: - posix.close(f) - - @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()") - def test_open_dir_fd(self): - os_helper.unlink(os_helper.TESTFN) - with open(os_helper.TESTFN, 'w') as outfile: - outfile.write("testline\n") - a = posix.open(posix.getcwd(), posix.O_RDONLY) - b = posix.open(os_helper.TESTFN, posix.O_RDONLY, dir_fd=a) - try: - res = posix.read(b, 9).decode(encoding="utf-8") - self.assertEqual("testline\n", res) - finally: - posix.close(a) - posix.close(b) - - @unittest.skipUnless(hasattr(os, 'readlink') and (os.readlink in os.supports_dir_fd), - "test needs dir_fd support in os.readlink()") - def test_readlink_dir_fd(self): - os.symlink(os_helper.TESTFN, os_helper.TESTFN + 'link') - f = posix.open(posix.getcwd(), posix.O_RDONLY) - try: - self.assertEqual(posix.readlink(os_helper.TESTFN + 'link'), - posix.readlink(os_helper.TESTFN + 'link', dir_fd=f)) - finally: - os_helper.unlink(os_helper.TESTFN + 'link') - posix.close(f) - - @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()") - def test_rename_dir_fd(self): - os_helper.unlink(os_helper.TESTFN) - os_helper.create_empty_file(os_helper.TESTFN + 'ren') - f = posix.open(posix.getcwd(), posix.O_RDONLY) - try: - posix.rename(os_helper.TESTFN + 'ren', os_helper.TESTFN, src_dir_fd=f, dst_dir_fd=f) - except: - posix.rename(os_helper.TESTFN + 'ren', os_helper.TESTFN) - raise - else: - posix.stat(os_helper.TESTFN) # should not raise exception - finally: - posix.close(f) - @unittest.skipUnless(hasattr(signal, 'SIGCHLD'), 'CLD_XXXX be placed in si_code for a SIGCHLD signal') @unittest.skipUnless(hasattr(os, 'waitid_result'), "test needs os.waitid_result") def test_cld_xxxx_constants(self): @@ -1272,47 +1104,6 @@ class PosixTester(unittest.TestCase): os.CLD_STOPPED os.CLD_CONTINUED - @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()") - def test_symlink_dir_fd(self): - f = posix.open(posix.getcwd(), posix.O_RDONLY) - try: - posix.symlink(os_helper.TESTFN, os_helper.TESTFN + 'link', - dir_fd=f) - self.assertEqual(posix.readlink(os_helper.TESTFN + 'link'), - os_helper.TESTFN) - finally: - posix.close(f) - os_helper.unlink(os_helper.TESTFN + 'link') - - @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()") - def test_unlink_dir_fd(self): - f = posix.open(posix.getcwd(), posix.O_RDONLY) - os_helper.create_empty_file(os_helper.TESTFN + 'del') - posix.stat(os_helper.TESTFN + 'del') # should not raise exception - try: - posix.unlink(os_helper.TESTFN + 'del', dir_fd=f) - except: - os_helper.unlink(os_helper.TESTFN + 'del') - raise - else: - self.assertRaises(OSError, posix.stat, os_helper.TESTFN + 'link') - finally: - posix.close(f) - - @unittest.skipUnless(os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()") - def test_mkfifo_dir_fd(self): - os_helper.unlink(os_helper.TESTFN) - f = posix.open(posix.getcwd(), posix.O_RDONLY) - try: - try: - posix.mkfifo(os_helper.TESTFN, - stat.S_IRUSR | stat.S_IWUSR, dir_fd=f) - except PermissionError as e: - self.skipTest('posix.mkfifo(): %s' % e) - self.assertTrue(stat.S_ISFIFO(posix.stat(os_helper.TESTFN).st_mode)) - finally: - posix.close(f) - requires_sched_h = unittest.skipUnless(hasattr(posix, 'sched_yield'), "don't have scheduling support") requires_sched_affinity = unittest.skipUnless(hasattr(posix, 'sched_setaffinity'), @@ -1400,7 +1191,9 @@ class PosixTester(unittest.TestCase): mask = posix.sched_getaffinity(0) self.assertIsInstance(mask, set) self.assertGreaterEqual(len(mask), 1) - self.assertRaises(OSError, posix.sched_getaffinity, -1) + if not sys.platform.startswith("freebsd"): + # bpo-47205: does not raise OSError on FreeBSD + self.assertRaises(OSError, posix.sched_getaffinity, -1) for cpu in mask: self.assertIsInstance(cpu, int) self.assertGreaterEqual(cpu, 0) @@ -1418,8 +1211,11 @@ class PosixTester(unittest.TestCase): self.assertRaises(ValueError, posix.sched_setaffinity, 0, [-10]) self.assertRaises(ValueError, posix.sched_setaffinity, 0, map(int, "0X")) self.assertRaises(OverflowError, posix.sched_setaffinity, 0, [1<<128]) - self.assertRaises(OSError, posix.sched_setaffinity, -1, mask) + if not sys.platform.startswith("freebsd"): + # bpo-47205: does not raise OSError on FreeBSD + self.assertRaises(OSError, posix.sched_setaffinity, -1, mask) + @unittest.skipIf(support.is_wasi, "No dynamic linking on WASI") def test_rtld_constants(self): # check presence of major RTLD_* constants posix.RTLD_LAZY @@ -1519,6 +1315,208 @@ class PosixTester(unittest.TestCase): self.assertEqual(cm.exception.errno, errno.EINVAL) os.close(os.pidfd_open(os.getpid(), 0)) + +# tests for the posix *at functions follow +class TestPosixDirFd(unittest.TestCase): + count = 0 + + @contextmanager + def prepare(self): + TestPosixDirFd.count += 1 + name = f'{os_helper.TESTFN}_{self.count}' + base_dir = f'{os_helper.TESTFN}_{self.count}base' + posix.mkdir(base_dir) + self.addCleanup(posix.rmdir, base_dir) + fullname = os.path.join(base_dir, name) + assert not os.path.exists(fullname) + with os_helper.open_dir_fd(base_dir) as dir_fd: + yield (dir_fd, name, fullname) + + @contextmanager + def prepare_file(self): + with self.prepare() as (dir_fd, name, fullname): + os_helper.create_empty_file(fullname) + self.addCleanup(posix.unlink, fullname) + yield (dir_fd, name, fullname) + + @unittest.skipUnless(os.access in os.supports_dir_fd, "test needs dir_fd support for os.access()") + def test_access_dir_fd(self): + with self.prepare_file() as (dir_fd, name, fullname): + self.assertTrue(posix.access(name, os.R_OK, dir_fd=dir_fd)) + + @unittest.skipUnless(os.chmod in os.supports_dir_fd, "test needs dir_fd support in os.chmod()") + def test_chmod_dir_fd(self): + with self.prepare_file() as (dir_fd, name, fullname): + posix.chmod(fullname, stat.S_IRUSR) + posix.chmod(name, stat.S_IRUSR | stat.S_IWUSR, dir_fd=dir_fd) + s = posix.stat(fullname) + self.assertEqual(s.st_mode & stat.S_IRWXU, + stat.S_IRUSR | stat.S_IWUSR) + + @unittest.skipUnless(hasattr(os, 'chown') and (os.chown in os.supports_dir_fd), + "test needs dir_fd support in os.chown()") + @unittest.skipIf(support.is_emscripten, "getgid() is a stub") + def test_chown_dir_fd(self): + with self.prepare_file() as (dir_fd, name, fullname): + posix.chown(name, os.getuid(), os.getgid(), dir_fd=dir_fd) + + @unittest.skipUnless(os.stat in os.supports_dir_fd, "test needs dir_fd support in os.stat()") + def test_stat_dir_fd(self): + with self.prepare() as (dir_fd, name, fullname): + with open(fullname, 'w') as outfile: + outfile.write("testline\n") + self.addCleanup(posix.unlink, fullname) + + s1 = posix.stat(fullname) + s2 = posix.stat(name, dir_fd=dir_fd) + self.assertEqual(s1, s2) + s2 = posix.stat(fullname, dir_fd=None) + self.assertEqual(s1, s2) + + self.assertRaisesRegex(TypeError, 'should be integer or None, not', + posix.stat, name, dir_fd=posix.getcwd()) + self.assertRaisesRegex(TypeError, 'should be integer or None, not', + posix.stat, name, dir_fd=float(dir_fd)) + self.assertRaises(OverflowError, + posix.stat, name, dir_fd=10**20) + + @unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()") + def test_utime_dir_fd(self): + with self.prepare_file() as (dir_fd, name, fullname): + now = time.time() + posix.utime(name, None, dir_fd=dir_fd) + posix.utime(name, dir_fd=dir_fd) + self.assertRaises(TypeError, posix.utime, name, + now, dir_fd=dir_fd) + self.assertRaises(TypeError, posix.utime, name, + (None, None), dir_fd=dir_fd) + self.assertRaises(TypeError, posix.utime, name, + (now, None), dir_fd=dir_fd) + self.assertRaises(TypeError, posix.utime, name, + (None, now), dir_fd=dir_fd) + self.assertRaises(TypeError, posix.utime, name, + (now, "x"), dir_fd=dir_fd) + posix.utime(name, (int(now), int(now)), dir_fd=dir_fd) + posix.utime(name, (now, now), dir_fd=dir_fd) + posix.utime(name, + (int(now), int((now - int(now)) * 1e9)), dir_fd=dir_fd) + posix.utime(name, dir_fd=dir_fd, + times=(int(now), int((now - int(now)) * 1e9))) + + # try dir_fd and follow_symlinks together + if os.utime in os.supports_follow_symlinks: + try: + posix.utime(name, follow_symlinks=False, dir_fd=dir_fd) + except ValueError: + # whoops! using both together not supported on this platform. + pass + + @unittest.skipIf( + support.is_wasi, + "WASI: symlink following on path_link is not supported" + ) + @unittest.skipUnless( + hasattr(os, "link") and os.link in os.supports_dir_fd, + "test needs dir_fd support in os.link()" + ) + def test_link_dir_fd(self): + with self.prepare_file() as (dir_fd, name, fullname), \ + self.prepare() as (dir_fd2, linkname, fulllinkname): + try: + posix.link(name, linkname, src_dir_fd=dir_fd, dst_dir_fd=dir_fd2) + except PermissionError as e: + self.skipTest('posix.link(): %s' % e) + self.addCleanup(posix.unlink, fulllinkname) + # should have same inodes + self.assertEqual(posix.stat(fullname)[1], + posix.stat(fulllinkname)[1]) + + @unittest.skipUnless(os.mkdir in os.supports_dir_fd, "test needs dir_fd support in os.mkdir()") + def test_mkdir_dir_fd(self): + with self.prepare() as (dir_fd, name, fullname): + posix.mkdir(name, dir_fd=dir_fd) + self.addCleanup(posix.rmdir, fullname) + posix.stat(fullname) # should not raise exception + + @unittest.skipUnless(hasattr(os, 'mknod') + and (os.mknod in os.supports_dir_fd) + and hasattr(stat, 'S_IFIFO'), + "test requires both stat.S_IFIFO and dir_fd support for os.mknod()") + def test_mknod_dir_fd(self): + # Test using mknodat() to create a FIFO (the only use specified + # by POSIX). + with self.prepare() as (dir_fd, name, fullname): + mode = stat.S_IFIFO | stat.S_IRUSR | stat.S_IWUSR + try: + posix.mknod(name, mode, 0, dir_fd=dir_fd) + except OSError as e: + # Some old systems don't allow unprivileged users to use + # mknod(), or only support creating device nodes. + self.assertIn(e.errno, (errno.EPERM, errno.EINVAL, errno.EACCES)) + else: + self.addCleanup(posix.unlink, fullname) + self.assertTrue(stat.S_ISFIFO(posix.stat(fullname).st_mode)) + + @unittest.skipUnless(os.open in os.supports_dir_fd, "test needs dir_fd support in os.open()") + def test_open_dir_fd(self): + with self.prepare() as (dir_fd, name, fullname): + with open(fullname, 'wb') as outfile: + outfile.write(b"testline\n") + self.addCleanup(posix.unlink, fullname) + fd = posix.open(name, posix.O_RDONLY, dir_fd=dir_fd) + try: + res = posix.read(fd, 9) + self.assertEqual(b"testline\n", res) + finally: + posix.close(fd) + + @unittest.skipUnless(hasattr(os, 'readlink') and (os.readlink in os.supports_dir_fd), + "test needs dir_fd support in os.readlink()") + def test_readlink_dir_fd(self): + with self.prepare() as (dir_fd, name, fullname): + os.symlink('symlink', fullname) + self.addCleanup(posix.unlink, fullname) + self.assertEqual(posix.readlink(name, dir_fd=dir_fd), 'symlink') + + @unittest.skipUnless(os.rename in os.supports_dir_fd, "test needs dir_fd support in os.rename()") + def test_rename_dir_fd(self): + with self.prepare_file() as (dir_fd, name, fullname), \ + self.prepare() as (dir_fd2, name2, fullname2): + posix.rename(name, name2, + src_dir_fd=dir_fd, dst_dir_fd=dir_fd2) + posix.stat(fullname2) # should not raise exception + posix.rename(fullname2, fullname) + + @unittest.skipUnless(os.symlink in os.supports_dir_fd, "test needs dir_fd support in os.symlink()") + def test_symlink_dir_fd(self): + with self.prepare() as (dir_fd, name, fullname): + posix.symlink('symlink', name, dir_fd=dir_fd) + self.addCleanup(posix.unlink, fullname) + self.assertEqual(posix.readlink(fullname), 'symlink') + + @unittest.skipUnless(os.unlink in os.supports_dir_fd, "test needs dir_fd support in os.unlink()") + def test_unlink_dir_fd(self): + with self.prepare() as (dir_fd, name, fullname): + os_helper.create_empty_file(fullname) + posix.stat(fullname) # should not raise exception + try: + posix.unlink(name, dir_fd=dir_fd) + self.assertRaises(OSError, posix.stat, fullname) + except: + self.addCleanup(posix.unlink, fullname) + raise + + @unittest.skipUnless(hasattr(os, 'mkfifo') and os.mkfifo in os.supports_dir_fd, "test needs dir_fd support in os.mkfifo()") + def test_mkfifo_dir_fd(self): + with self.prepare() as (dir_fd, name, fullname): + try: + posix.mkfifo(name, stat.S_IRUSR | stat.S_IWUSR, dir_fd=dir_fd) + except PermissionError as e: + self.skipTest('posix.mkfifo(): %s' % e) + self.addCleanup(posix.unlink, fullname) + self.assertTrue(stat.S_ISFIFO(posix.stat(fullname).st_mode)) + + class PosixGroupsTester(unittest.TestCase): def setUp(self): @@ -1648,12 +1646,6 @@ class _PosixSpawnMixin: ) support.wait_process(pid, exitcode=0) - def test_resetids_wrong_type(self): - with self.assertRaises(TypeError): - self.spawn_func(sys.executable, - [sys.executable, "-c", "pass"], - os.environ, resetids=None) - def test_setpgroup(self): pid = self.spawn_func( sys.executable, @@ -2089,6 +2081,28 @@ class TestPosixWeaklinking(unittest.TestCase): with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"): os.mkdir("dir", dir_fd=0) + def test_mkfifo(self): + self._verify_available("HAVE_MKFIFOAT") + if self.mac_ver >= (13, 0): + self.assertIn("HAVE_MKFIFOAT", posix._have_functions) + + else: + self.assertNotIn("HAVE_MKFIFOAT", posix._have_functions) + + with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"): + os.mkfifo("path", dir_fd=0) + + def test_mknod(self): + self._verify_available("HAVE_MKNODAT") + if self.mac_ver >= (13, 0): + self.assertIn("HAVE_MKNODAT", posix._have_functions) + + else: + self.assertNotIn("HAVE_MKNODAT", posix._have_functions) + + with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"): + os.mknod("path", dir_fd=0) + def test_rename_replace(self): self._verify_available("HAVE_RENAMEAT") if self.mac_ver >= (10, 10): @@ -2171,6 +2185,53 @@ class TestPosixWeaklinking(unittest.TestCase): os.utime("path", dir_fd=0) +class NamespacesTests(unittest.TestCase): + """Tests for os.unshare() and os.setns().""" + + @unittest.skipUnless(hasattr(os, 'unshare'), 'needs os.unshare()') + @unittest.skipUnless(hasattr(os, 'setns'), 'needs os.setns()') + @unittest.skipUnless(os.path.exists('/proc/self/ns/uts'), 'need /proc/self/ns/uts') + @support.requires_linux_version(3, 0, 0) + def test_unshare_setns(self): + code = """if 1: + import errno + import os + import sys + fd = os.open('/proc/self/ns/uts', os.O_RDONLY) + try: + original = os.readlink('/proc/self/ns/uts') + try: + os.unshare(os.CLONE_NEWUTS) + except OSError as e: + if e.errno == errno.ENOSPC: + # skip test if limit is exceeded + sys.exit() + raise + new = os.readlink('/proc/self/ns/uts') + if original == new: + raise Exception('os.unshare failed') + os.setns(fd, os.CLONE_NEWUTS) + restored = os.readlink('/proc/self/ns/uts') + if original != restored: + raise Exception('os.setns failed') + except PermissionError: + # The calling process did not have the required privileges + # for this operation + pass + except OSError as e: + # Skip the test on these errors: + # - ENOSYS: syscall not available + # - EINVAL: kernel was not configured with the CONFIG_UTS_NS option + # - ENOMEM: not enough memory + if e.errno not in (errno.ENOSYS, errno.EINVAL, errno.ENOMEM): + raise + finally: + os.close(fd) + """ + + assert_python_ok("-c", code) + + def tearDownModule(): support.reap_children() diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index e4d8384ef0b..9be4640f970 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -115,6 +115,32 @@ class PosixPathTest(unittest.TestCase): self.splitextTest("........", "........", "") self.splitextTest("", "", "") + def test_splitroot(self): + f = posixpath.splitroot + self.assertEqual(f(''), ('', '', '')) + self.assertEqual(f('a'), ('', '', 'a')) + self.assertEqual(f('a/b'), ('', '', 'a/b')) + self.assertEqual(f('a/b/'), ('', '', 'a/b/')) + self.assertEqual(f('/a'), ('', '/', 'a')) + self.assertEqual(f('/a/b'), ('', '/', 'a/b')) + self.assertEqual(f('/a/b/'), ('', '/', 'a/b/')) + # The root is collapsed when there are redundant slashes + # except when there are exactly two leading slashes, which + # is a special case in POSIX. + self.assertEqual(f('//a'), ('', '//', 'a')) + self.assertEqual(f('///a'), ('', '/', '//a')) + self.assertEqual(f('///a/b'), ('', '/', '//a/b')) + # Paths which look like NT paths aren't treated specially. + self.assertEqual(f('c:/a/b'), ('', '', 'c:/a/b')) + self.assertEqual(f('\\/a/b'), ('', '', '\\/a/b')) + self.assertEqual(f('\\a\\b'), ('', '', '\\a\\b')) + # Byte paths are supported + self.assertEqual(f(b''), (b'', b'', b'')) + self.assertEqual(f(b'a'), (b'', b'', b'a')) + self.assertEqual(f(b'/a'), (b'', b'/', b'a')) + self.assertEqual(f(b'//a'), (b'', b'//', b'a')) + self.assertEqual(f(b'///a'), (b'', b'/', b'//a')) + def test_isabs(self): self.assertIs(posixpath.isabs(""), False) self.assertIs(posixpath.isabs("/"), True) @@ -178,6 +204,8 @@ class PosixPathTest(unittest.TestCase): def test_ismount(self): self.assertIs(posixpath.ismount("/"), True) self.assertIs(posixpath.ismount(b"/"), True) + self.assertIs(posixpath.ismount(FakePath("/")), True) + self.assertIs(posixpath.ismount(FakePath(b"/")), True) def test_ismount_non_existent(self): # Non-existent mountpoint. @@ -193,8 +221,7 @@ class PosixPathTest(unittest.TestCase): self.assertIs(posixpath.ismount('/\x00'), False) self.assertIs(posixpath.ismount(b'/\x00'), False) - @unittest.skipUnless(os_helper.can_symlink(), - "Test requires symlink support") + @os_helper.skip_unless_symlink def test_ismount_symlinks(self): # Symlinks are never mountpoints. try: @@ -243,6 +270,9 @@ class PosixPathTest(unittest.TestCase): finally: os.lstat = save_lstat + def test_isjunction(self): + self.assertFalse(posixpath.isjunction(ABSTFN)) + def test_expanduser(self): self.assertEqual(posixpath.expanduser("foo"), "foo") self.assertEqual(posixpath.expanduser(b"foo"), b"foo") @@ -329,13 +359,30 @@ class PosixPathTest(unittest.TestCase): ("/..", "/"), ("/../", "/"), ("/..//", "/"), + ("//.", "//"), ("//..", "//"), + ("//...", "//..."), + ("//../foo", "//foo"), + ("//../../foo", "//foo"), ("/../foo", "/foo"), ("/../../foo", "/foo"), ("/../foo/../", "/"), ("/../foo/../bar", "/bar"), ("/../../foo/../bar/./baz/boom/..", "/bar/baz"), ("/../../foo/../bar/./baz/boom/.", "/bar/baz/boom"), + ("foo/../bar/baz", "bar/baz"), + ("foo/../../bar/baz", "../bar/baz"), + ("foo/../../../bar/baz", "../../bar/baz"), + ("foo///../bar/.././../baz/boom", "../baz/boom"), + ("foo/bar/../..///../../baz/boom", "../../baz/boom"), + ("/foo/..", "/"), + ("/foo/../..", "/"), + ("//foo/..", "//"), + ("//foo/../..", "//"), + ("///foo/..", "/"), + ("///foo/../..", "/"), + ("////foo/..", "/"), + ("/////foo/..", "/"), ] def test_normpath(self): @@ -370,8 +417,7 @@ class PosixPathTest(unittest.TestCase): self.assertEqual(realpath(b'../..'), dirname(dirname(os.getcwdb()))) self.assertEqual(realpath(b'/'.join([b'..'] * 100)), b'/') - @unittest.skipUnless(hasattr(os, "symlink"), - "Missing symlink implementation") + @os_helper.skip_unless_symlink @skip_if_ABSTFN_contains_backslash def test_realpath_basic(self): # Basic operation. @@ -381,8 +427,7 @@ class PosixPathTest(unittest.TestCase): finally: os_helper.unlink(ABSTFN) - @unittest.skipUnless(hasattr(os, "symlink"), - "Missing symlink implementation") + @os_helper.skip_unless_symlink @skip_if_ABSTFN_contains_backslash def test_realpath_strict(self): # Bug #43757: raise FileNotFoundError in strict mode if we encounter @@ -394,8 +439,7 @@ class PosixPathTest(unittest.TestCase): finally: os_helper.unlink(ABSTFN) - @unittest.skipUnless(hasattr(os, "symlink"), - "Missing symlink implementation") + @os_helper.skip_unless_symlink @skip_if_ABSTFN_contains_backslash def test_realpath_relative(self): try: @@ -404,8 +448,7 @@ class PosixPathTest(unittest.TestCase): finally: os_helper.unlink(ABSTFN) - @unittest.skipUnless(hasattr(os, "symlink"), - "Missing symlink implementation") + @os_helper.skip_unless_symlink @skip_if_ABSTFN_contains_backslash def test_realpath_symlink_loops(self): # Bug #930024, return the path unchanged if we get into an infinite @@ -446,8 +489,7 @@ class PosixPathTest(unittest.TestCase): os_helper.unlink(ABSTFN+"c") os_helper.unlink(ABSTFN+"a") - @unittest.skipUnless(hasattr(os, "symlink"), - "Missing symlink implementation") + @os_helper.skip_unless_symlink @skip_if_ABSTFN_contains_backslash def test_realpath_symlink_loops_strict(self): # Bug #43757, raise OSError if we get into an infinite symlink loop in @@ -488,8 +530,7 @@ class PosixPathTest(unittest.TestCase): os_helper.unlink(ABSTFN+"c") os_helper.unlink(ABSTFN+"a") - @unittest.skipUnless(hasattr(os, "symlink"), - "Missing symlink implementation") + @os_helper.skip_unless_symlink @skip_if_ABSTFN_contains_backslash def test_realpath_repeated_indirect_symlinks(self): # Issue #6975. @@ -503,8 +544,7 @@ class PosixPathTest(unittest.TestCase): os_helper.unlink(ABSTFN + '/link') safe_rmdir(ABSTFN) - @unittest.skipUnless(hasattr(os, "symlink"), - "Missing symlink implementation") + @os_helper.skip_unless_symlink @skip_if_ABSTFN_contains_backslash def test_realpath_deep_recursion(self): depth = 10 @@ -523,8 +563,7 @@ class PosixPathTest(unittest.TestCase): os_helper.unlink(ABSTFN + '/%d' % i) safe_rmdir(ABSTFN) - @unittest.skipUnless(hasattr(os, "symlink"), - "Missing symlink implementation") + @os_helper.skip_unless_symlink @skip_if_ABSTFN_contains_backslash def test_realpath_resolve_parents(self): # We also need to resolve any symlinks in the parents of a relative @@ -543,8 +582,7 @@ class PosixPathTest(unittest.TestCase): safe_rmdir(ABSTFN + "/y") safe_rmdir(ABSTFN) - @unittest.skipUnless(hasattr(os, "symlink"), - "Missing symlink implementation") + @os_helper.skip_unless_symlink @skip_if_ABSTFN_contains_backslash def test_realpath_resolve_before_normalizing(self): # Bug #990669: Symbolic links should be resolved before we @@ -572,8 +610,7 @@ class PosixPathTest(unittest.TestCase): safe_rmdir(ABSTFN + "/k") safe_rmdir(ABSTFN) - @unittest.skipUnless(hasattr(os, "symlink"), - "Missing symlink implementation") + @os_helper.skip_unless_symlink @skip_if_ABSTFN_contains_backslash def test_realpath_resolve_first(self): # Bug #1213894: The first component of the path, if not absolute, @@ -741,6 +778,9 @@ class PathLikeTests(unittest.TestCase): def test_path_splitdrive(self): self.assertPathEqual(self.path.splitdrive) + def test_path_splitroot(self): + self.assertPathEqual(self.path.splitroot) + def test_path_basename(self): self.assertPathEqual(self.path.basename) diff --git a/Lib/test/test_pow.py b/Lib/test/test_pow.py index 660ff80bbf5..5cea9ceb20f 100644 --- a/Lib/test/test_pow.py +++ b/Lib/test/test_pow.py @@ -93,6 +93,28 @@ class PowTest(unittest.TestCase): pow(int(i),j,k) ) + def test_big_exp(self): + import random + self.assertEqual(pow(2, 50000), 1 << 50000) + # Randomized modular tests, checking the identities + # a**(b1 + b2) == a**b1 * a**b2 + # a**(b1 * b2) == (a**b1)**b2 + prime = 1000000000039 # for speed, relatively small prime modulus + for i in range(10): + a = random.randrange(1000, 1000000) + bpower = random.randrange(1000, 50000) + b = random.randrange(1 << (bpower - 1), 1 << bpower) + b1 = random.randrange(1, b) + b2 = b - b1 + got1 = pow(a, b, prime) + got2 = pow(a, b1, prime) * pow(a, b2, prime) % prime + if got1 != got2: + self.fail(f"{a=:x} {b1=:x} {b2=:x} {got1=:x} {got2=:x}") + got3 = pow(a, b1 * b2, prime) + got4 = pow(pow(a, b1, prime), b2, prime) + if got3 != got4: + self.fail(f"{a=:x} {b1=:x} {b2=:x} {got3=:x} {got4=:x}") + def test_bug643260(self): class TestRpow: def __rpow__(self, other): diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py index c7b98939434..6ea7e7db2ce 100644 --- a/Lib/test/test_pprint.py +++ b/Lib/test/test_pprint.py @@ -203,7 +203,7 @@ class QueryTestCase(unittest.TestCase): def test_unreadable(self): # Not recursive but not readable anyway pp = pprint.PrettyPrinter() - for unreadable in type(3), pprint, pprint.isrecursive: + for unreadable in object(), int, pprint, pprint.isrecursive: # module-level convenience functions self.assertFalse(pprint.isrecursive(unreadable), "expected not isrecursive for %r" % (unreadable,)) diff --git a/Lib/test/test_property.py b/Lib/test/test_property.py index 7f3813fc8cd..d4bdf50c019 100644 --- a/Lib/test/test_property.py +++ b/Lib/test/test_property.py @@ -214,11 +214,31 @@ class PropertyTests(unittest.TestCase): ): p.__set_name__(*([0] * i)) + def test_property_setname_on_property_subclass(self): + # https://github.com/python/cpython/issues/100942 + # Copy was setting the name field without first + # verifying that the copy was an actual property + # instance. As a result, the code below was + # causing a segfault. + + class pro(property): + def __new__(typ, *args, **kwargs): + return "abcdef" + + class A: + pass + + p = property.__new__(pro) + p.__set_name__(A, 1) + np = p.getter(lambda self: 1) # Issue 5890: subclasses of property do not preserve method __doc__ strings class PropertySub(property): """This is a subclass of property""" +class PropertySubWoDoc(property): + pass + class PropertySubSlots(property): """This is a subclass of property that defines __slots__""" __slots__ = () @@ -237,6 +257,38 @@ class PropertySubclassTests(unittest.TestCase): else: raise Exception("AttributeError not raised") + @unittest.skipIf(sys.flags.optimize >= 2, + "Docstrings are omitted with -O2 and above") + def test_issue41287(self): + + self.assertEqual(PropertySub.__doc__, "This is a subclass of property", + "Docstring of `property` subclass is ignored") + + doc = PropertySub(None, None, None, "issue 41287 is fixed").__doc__ + self.assertEqual(doc, "issue 41287 is fixed", + "Subclasses of `property` ignores `doc` constructor argument") + + def getter(x): + """Getter docstring""" + + def getter_wo_doc(x): + pass + + for ps in property, PropertySub, PropertySubWoDoc: + doc = ps(getter, None, None, "issue 41287 is fixed").__doc__ + self.assertEqual(doc, "issue 41287 is fixed", + "Getter overrides explicit property docstring (%s)" % ps.__name__) + + doc = ps(getter, None, None, None).__doc__ + self.assertEqual(doc, "Getter docstring", "Getter docstring is not picked-up (%s)" % ps.__name__) + + doc = ps(getter_wo_doc, None, None, "issue 41287 is fixed").__doc__ + self.assertEqual(doc, "issue 41287 is fixed", + "Getter overrides explicit property docstring (%s)" % ps.__name__) + + doc = ps(getter_wo_doc, None, None, None).__doc__ + self.assertIsNone(doc, "Property class doc appears in instance __doc__ (%s)" % ps.__name__) + @unittest.skipIf(sys.flags.optimize >= 2, "Docstrings are omitted with -O2 and above") def test_docstring_copy(self): @@ -249,6 +301,66 @@ class PropertySubclassTests(unittest.TestCase): Foo.spam.__doc__, "spam wrapped in property subclass") + @unittest.skipIf(sys.flags.optimize >= 2, + "Docstrings are omitted with -O2 and above") + def test_docstring_copy2(self): + """ + Property tries to provide the best docstring it finds for its instances. + If a user-provided docstring is available, it is preserved on copies. + If no docstring is available during property creation, the property + will utilize the docstring from the getter if available. + """ + def getter1(self): + return 1 + def getter2(self): + """doc 2""" + return 2 + def getter3(self): + """doc 3""" + return 3 + + # Case-1: user-provided doc is preserved in copies + # of property with undocumented getter + p = property(getter1, None, None, "doc-A") + + p2 = p.getter(getter2) + self.assertEqual(p.__doc__, "doc-A") + self.assertEqual(p2.__doc__, "doc-A") + + # Case-2: user-provided doc is preserved in copies + # of property with documented getter + p = property(getter2, None, None, "doc-A") + + p2 = p.getter(getter3) + self.assertEqual(p.__doc__, "doc-A") + self.assertEqual(p2.__doc__, "doc-A") + + # Case-3: with no user-provided doc new getter doc + # takes precendence + p = property(getter2, None, None, None) + + p2 = p.getter(getter3) + self.assertEqual(p.__doc__, "doc 2") + self.assertEqual(p2.__doc__, "doc 3") + + # Case-4: A user-provided doc is assigned after property construction + # with documented getter. The doc IS NOT preserved. + # It's an odd behaviour, but it's a strange enough + # use case with no easy solution. + p = property(getter2, None, None, None) + p.__doc__ = "user" + p2 = p.getter(getter3) + self.assertEqual(p.__doc__, "user") + self.assertEqual(p2.__doc__, "doc 3") + + # Case-5: A user-provided doc is assigned after property construction + # with UNdocumented getter. The doc IS preserved. + p = property(getter1, None, None, None) + p.__doc__ = "user" + p2 = p.getter(getter2) + self.assertEqual(p.__doc__, "user") + self.assertEqual(p2.__doc__, "user") + @unittest.skipIf(sys.flags.optimize >= 2, "Docstrings are omitted with -O2 and above") def test_property_setter_copies_getter_docstring(self): @@ -322,27 +434,27 @@ class _PropertyUnreachableAttribute: cls.obj = cls.cls() def test_get_property(self): - with self.assertRaisesRegex(AttributeError, self._format_exc_msg("unreadable attribute")): + with self.assertRaisesRegex(AttributeError, self._format_exc_msg("has no getter")): self.obj.foo def test_set_property(self): - with self.assertRaisesRegex(AttributeError, self._format_exc_msg("can't set attribute")): + with self.assertRaisesRegex(AttributeError, self._format_exc_msg("has no setter")): self.obj.foo = None def test_del_property(self): - with self.assertRaisesRegex(AttributeError, self._format_exc_msg("can't delete attribute")): + with self.assertRaisesRegex(AttributeError, self._format_exc_msg("has no deleter")): del self.obj.foo class PropertyUnreachableAttributeWithName(_PropertyUnreachableAttribute, unittest.TestCase): - msg_format = "^{} 'foo'$" + msg_format = r"^property 'foo' of 'PropertyUnreachableAttributeWithName\.cls' object {}$" class cls: foo = property() class PropertyUnreachableAttributeNoName(_PropertyUnreachableAttribute, unittest.TestCase): - msg_format = "^{}$" + msg_format = r"^property of 'PropertyUnreachableAttributeNoName\.cls' object {}$" class cls: pass diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index 0c178127571..fa0dbcc16f3 100644 --- a/Lib/test/test_pty.py +++ b/Lib/test/test_pty.py @@ -1,8 +1,9 @@ from test.support import verbose, reap_children from test.support.import_helper import import_module -# Skip these tests if termios is not available +# Skip these tests if termios or fcntl are not available import_module('termios') +import_module("fcntl") import errno import os @@ -16,7 +17,6 @@ import io # readline import unittest import struct -import tty import fcntl import warnings diff --git a/Lib/test/test_pwd.py b/Lib/test/test_pwd.py index f8f12571ca9..aa090b464a7 100644 --- a/Lib/test/test_pwd.py +++ b/Lib/test/test_pwd.py @@ -59,6 +59,8 @@ class PwdTest(unittest.TestCase): self.assertRaises(TypeError, pwd.getpwnam) self.assertRaises(TypeError, pwd.getpwnam, 42) self.assertRaises(TypeError, pwd.getpwall, 42) + # embedded null character + self.assertRaisesRegex(ValueError, 'null', pwd.getpwnam, 'a\x00b') # try to get some errors bynames = {} @@ -69,7 +71,7 @@ class PwdTest(unittest.TestCase): allnames = list(bynames.keys()) namei = 0 - fakename = allnames[namei] + fakename = allnames[namei] if allnames else "invaliduser" while fakename in bynames: chars = list(fakename) for i in range(len(chars)): diff --git a/Lib/test/test_py_compile.py b/Lib/test/test_py_compile.py index 5ed98dbff17..5e0a44ad969 100644 --- a/Lib/test/test_py_compile.py +++ b/Lib/test/test_py_compile.py @@ -115,10 +115,10 @@ class PyCompileTestsBase: self.assertTrue(os.path.exists(self.pyc_path)) self.assertFalse(os.path.exists(self.cache_path)) - @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, - 'non-root user required') + @os_helper.skip_if_dac_override @unittest.skipIf(os.name == 'nt', 'cannot control directory permissions on Windows') + @os_helper.skip_unless_working_chmod def test_exceptions_propagate(self): # Make sure that exceptions raised thanks to issues with writing # bytecode. @@ -230,15 +230,17 @@ class PyCompileCLITestCase(unittest.TestCase): def tearDown(self): os_helper.rmtree(self.directory) + @support.requires_subprocess() def pycompilecmd(self, *args, **kwargs): # assert_python_* helpers don't return proc object. We'll just use # subprocess.run() instead of spawn_python() and its friends to test # stdin support of the CLI. + opts = '-m' if __debug__ else '-Om' if args and args[0] == '-' and 'input' in kwargs: - return subprocess.run([sys.executable, '-m', 'py_compile', '-'], + return subprocess.run([sys.executable, opts, 'py_compile', '-'], input=kwargs['input'].encode(), capture_output=True) - return script_helper.assert_python_ok('-m', 'py_compile', *args, **kwargs) + return script_helper.assert_python_ok(opts, 'py_compile', *args, **kwargs) def pycompilecmd_failure(self, *args): return script_helper.assert_python_failure('-m', 'py_compile', *args) diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py index 4bb9cfcad9a..23453e34015 100644 --- a/Lib/test/test_pyclbr.py +++ b/Lib/test/test_pyclbr.py @@ -9,6 +9,7 @@ from types import FunctionType, MethodType, BuiltinFunctionType import pyclbr from unittest import TestCase, main as unittest_main from test.test_importlib import util as test_importlib_util +import warnings StaticMethodType = type(staticmethod(lambda: None)) @@ -216,16 +217,19 @@ class PyclbrTest(TestCase): def test_others(self): cm = self.checkModule - # These were once about the 10 longest modules + # These were once some of the longest modules. cm('random', ignore=('Random',)) # from _random import Random as CoreGenerator - cm('cgi', ignore=('log',)) # set with = in module + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + cm('cgi', ignore=('log',)) # set with = in module cm('pickle', ignore=('partial', 'PickleBuffer')) - cm('aifc', ignore=('_aifc_params',)) # set with = in module - cm('sre_parse', ignore=('dump', 'groups', 'pos')) # from sre_constants import *; property + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + cm('sre_parse', ignore=('dump', 'groups', 'pos')) # from sre_constants import *; property cm( 'pdb', # pyclbr does not handle elegantly `typing` or properties - ignore=('Union', 'ModuleTarget', 'ScriptTarget'), + ignore=('Union', '_ModuleTarget', '_ScriptTarget'), ) cm('pydoc', ignore=('input', 'output',)) # properties diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 057780d51f9..cefc71cb5a7 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -27,7 +27,8 @@ from test.support import os_helper from test.support.script_helper import assert_python_ok, assert_python_failure from test.support import threading_helper from test.support import (reap_children, captured_output, captured_stdout, - captured_stderr, requires_docstrings) + captured_stderr, is_emscripten, is_wasi, + requires_docstrings) from test.support.os_helper import (TESTFN, rmtree, unlink) from test import pydoc_mod @@ -53,53 +54,58 @@ CLASSES A B C -\x20\x20\x20\x20 + class A(builtins.object) | Hello and goodbye - |\x20\x20 + | | Methods defined here: - |\x20\x20 + | | __init__() | Wow, I have no function! - |\x20\x20 + | | ---------------------------------------------------------------------- | Data descriptors defined here: - |\x20\x20 + | | __dict__%s - |\x20\x20 + | | __weakref__%s -\x20\x20\x20\x20 + class B(builtins.object) | Data descriptors defined here: - |\x20\x20 + | | __dict__%s - |\x20\x20 + | | __weakref__%s - |\x20\x20 + | | ---------------------------------------------------------------------- | Data and other attributes defined here: - |\x20\x20 + | | NO_MEANING = 'eggs' - |\x20\x20 + | | __annotations__ = {'NO_MEANING': } -\x20\x20\x20\x20 + class C(builtins.object) | Methods defined here: - |\x20\x20 + | | get_answer(self) | Return say_no() - |\x20\x20 + | | is_it_true(self) | Return self.get_answer() - |\x20\x20 + | | say_no(self) - |\x20\x20 + | + | ---------------------------------------------------------------------- + | Class methods defined here: + | + | __class_getitem__(item) from builtins.type + | | ---------------------------------------------------------------------- | Data descriptors defined here: - |\x20\x20 + | | __dict__ | dictionary for instance variables (if defined) - |\x20\x20 + | | __weakref__ | list of weak references to the object (if defined) @@ -109,11 +115,16 @@ FUNCTIONS hunger lack of Python war -\x20\x20\x20\x20 + nodoc_func() DATA __xyz__ = 'X, Y and Z' + c_alias = test.pydoc_mod.C[int] + list_alias1 = typing.List[int] + list_alias2 = list[int] + type_union1 = typing.Union[int, str] + type_union2 = int | str VERSION 1.2.3.4 @@ -135,6 +146,10 @@ html2text_of_expected = """ test.pydoc_mod (version 1.2.3.4) This is a test module for test_pydoc +Modules + types + typing + Classes builtins.object A @@ -172,6 +187,8 @@ class C(builtins.object) is_it_true(self) Return self.get_answer() say_no(self) + Class methods defined here: + __class_getitem__(item) from builtins.type Data descriptors defined here: __dict__ dictionary for instance variables (if defined) @@ -188,6 +205,11 @@ Functions Data __xyz__ = 'X, Y and Z' + c_alias = test.pydoc_mod.C[int] + list_alias1 = typing.List[int] + list_alias2 = list[int] + type_union1 = typing.Union[int, str] + type_union2 = int | str Author Benjamin Peterson @@ -213,16 +235,16 @@ Help on class DA in module %s: class DA(builtins.object) | Data descriptors defined here: - |\x20\x20 + | | __dict__%s - |\x20\x20 + | | __weakref__%s - |\x20\x20 + | | ham - |\x20\x20 + | | ---------------------------------------------------------------------- | Data and other attributes inherited from Meta: - |\x20\x20 + | | ham = 'spam' """.strip() @@ -231,7 +253,7 @@ Help on class Class in module %s: class Class(builtins.object) | Data and other attributes inherited from Meta: - |\x20\x20 + | | LIFE = 42 """.strip() @@ -240,7 +262,7 @@ Help on class Class1 in module %s: class Class1(builtins.object) | Data and other attributes inherited from Meta1: - |\x20\x20 + | | one = 1 """.strip() @@ -252,19 +274,19 @@ class Class2(Class1) | Class2 | Class1 | builtins.object - |\x20\x20 + | | Data and other attributes inherited from Meta1: - |\x20\x20 + | | one = 1 - |\x20\x20 + | | ---------------------------------------------------------------------- | Data and other attributes inherited from Meta3: - |\x20\x20 + | | three = 3 - |\x20\x20 + | | ---------------------------------------------------------------------- | Data and other attributes inherited from Meta2: - |\x20\x20 + | | two = 2 """.strip() @@ -273,7 +295,7 @@ Help on class C in module %s: class C(builtins.object) | Data and other attributes defined here: - |\x20\x20 + | | here = 'present!' """.strip() @@ -340,9 +362,10 @@ def html2text(html): Tailored for pydoc tests only. """ - return pydoc.replace( - re.sub("<.*?>", "", html), - " ", " ", ">", ">", "<", "<") + html = html.replace("
    ", "\n") + html = re.sub("<.*?>", "", html) + html = pydoc.replace(html, " ", " ", ">", ">", "<", "<") + return html class PydocBaseTest(unittest.TestCase): @@ -384,9 +407,12 @@ class PydocDocTest(unittest.TestCase): def test_html_doc(self): result, doc_loc = get_pydoc_html(pydoc_mod) text_result = html2text(result) - expected_lines = [line.strip() for line in html2text_of_expected if line] - for line in expected_lines: - self.assertIn(line, text_result) + text_lines = [line.strip() for line in text_result.splitlines()] + text_lines = [line for line in text_lines if line] + del text_lines[1] + expected_lines = html2text_of_expected.splitlines() + expected_lines = [line.strip() for line in expected_lines if line] + self.assertEqual(text_lines, expected_lines) mod_file = inspect.getabsfile(pydoc_mod) mod_url = urllib.parse.quote(mod_file) self.assertIn(mod_url, result) @@ -676,7 +702,7 @@ class PydocDocTest(unittest.TestCase): def test_synopsis_sourceless(self): os = import_helper.import_fresh_module('os') expected = os.__doc__.splitlines()[0] - filename = os.__cached__ + filename = os.__spec__.cached synopsis = pydoc.synopsis(filename) self.assertEqual(synopsis, expected) @@ -759,33 +785,33 @@ class B(A) | B | A | builtins.object - |\x20\x20 + | | Methods defined here: - |\x20\x20 + | | b_size = a_size(self) - |\x20\x20 + | | itemconfig = itemconfigure(self, tagOrId, cnf=None, **kw) - |\x20\x20 + | | itemconfigure(self, tagOrId, cnf=None, **kw) | Configure resources of an item TAGORID. - |\x20\x20 + | | ---------------------------------------------------------------------- | Methods inherited from A: - |\x20\x20 + | | a_size(self) | Return size - |\x20\x20 + | | lift = tkraise(self, aboveThis=None) - |\x20\x20 + | | tkraise(self, aboveThis=None) | Raise this widget in the stacking order. - |\x20\x20 + | | ---------------------------------------------------------------------- | Data descriptors inherited from A: - |\x20\x20 + | | __dict__ | dictionary for instance variables (if defined) - |\x20\x20 + | | __weakref__ | list of weak references to the object (if defined) ''' % __name__) @@ -825,6 +851,23 @@ class B(A) for expected_line in expected_lines: self.assertIn(expected_line, as_text) + def test__future__imports(self): + # __future__ features are excluded from module help, + # except when it's the __future__ module itself + import __future__ + future_text, _ = get_pydoc_text(__future__) + future_html, _ = get_pydoc_html(__future__) + pydoc_mod_text, _ = get_pydoc_text(pydoc_mod) + pydoc_mod_html, _ = get_pydoc_html(pydoc_mod) + + for feature in __future__.all_feature_names: + txt = f"{feature} = _Feature" + html = f"{feature} = _Feature" + self.assertIn(txt, future_text) + self.assertIn(html, future_html) + self.assertNotIn(txt, pydoc_mod_text) + self.assertNotIn(html, pydoc_mod_html) + class PydocImportTest(PydocBaseTest): @@ -890,6 +933,8 @@ class PydocImportTest(PydocBaseTest): self.assertEqual(out.getvalue(), '') self.assertEqual(err.getvalue(), '') + @os_helper.skip_unless_working_chmod + @unittest.skipIf(is_emscripten, "cannot remove x bit") def test_apropos_empty_doc(self): pkgdir = os.path.join(TESTFN, 'walkpkg') os.mkdir(pkgdir) @@ -996,6 +1041,43 @@ class TestDescriptions(unittest.TestCase): expected = 'C in module %s object' % __name__ self.assertIn(expected, pydoc.render_doc(c)) + def test_generic_alias(self): + self.assertEqual(pydoc.describe(typing.List[int]), '_GenericAlias') + doc = pydoc.render_doc(typing.List[int], renderer=pydoc.plaintext) + self.assertIn('_GenericAlias in module typing', doc) + self.assertIn('List = class list(object)', doc) + self.assertIn(list.__doc__.strip().splitlines()[0], doc) + + self.assertEqual(pydoc.describe(list[int]), 'GenericAlias') + doc = pydoc.render_doc(list[int], renderer=pydoc.plaintext) + self.assertIn('GenericAlias in module builtins', doc) + self.assertIn('\nclass list(object)', doc) + self.assertIn(list.__doc__.strip().splitlines()[0], doc) + + def test_union_type(self): + self.assertEqual(pydoc.describe(typing.Union[int, str]), '_UnionGenericAlias') + doc = pydoc.render_doc(typing.Union[int, str], renderer=pydoc.plaintext) + self.assertIn('_UnionGenericAlias in module typing', doc) + self.assertIn('Union = typing.Union', doc) + if typing.Union.__doc__: + self.assertIn(typing.Union.__doc__.strip().splitlines()[0], doc) + + self.assertEqual(pydoc.describe(int | str), 'UnionType') + doc = pydoc.render_doc(int | str, renderer=pydoc.plaintext) + self.assertIn('UnionType in module types object', doc) + self.assertIn('\nclass UnionType(builtins.object)', doc) + self.assertIn(types.UnionType.__doc__.strip().splitlines()[0], doc) + + def test_special_form(self): + self.assertEqual(pydoc.describe(typing.NoReturn), '_SpecialForm') + doc = pydoc.render_doc(typing.NoReturn, renderer=pydoc.plaintext) + self.assertIn('_SpecialForm in module typing', doc) + if typing.NoReturn.__doc__: + self.assertIn('NoReturn = typing.NoReturn', doc) + self.assertIn(typing.NoReturn.__doc__.strip().splitlines()[0], doc) + else: + self.assertIn('NoReturn = class _SpecialForm(_Final)', doc) + def test_typing_pydoc(self): def foo(data: typing.List[typing.Any], x: int) -> typing.Iterator[typing.Tuple[int, typing.Any]]: @@ -1098,7 +1180,7 @@ sm(x, y) """) self.assertIn(""" | Static methods defined here: - |\x20\x20 + | | sm(x, y) | A static method """, pydoc.plain(pydoc.render_doc(X))) @@ -1119,7 +1201,7 @@ cm(x) method of builtins.type instance """) self.assertIn(""" | Class methods defined here: - |\x20\x20 + | | cm(x) from builtins.type | A class method """, pydoc.plain(pydoc.render_doc(X))) @@ -1277,6 +1359,10 @@ foo ) +@unittest.skipIf( + is_emscripten or is_wasi, + "Socket server not available on Emscripten/WASI." +) class PydocServerTest(unittest.TestCase): """Tests for pydoc._start_server""" diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py index b2b4dea0605..863c1194672 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py @@ -12,7 +12,7 @@ import traceback from xml.parsers import expat from xml.parsers.expat import errors -from test.support import sortdict +from test.support import sortdict, is_emscripten, is_wasi class SetAttributeTest(unittest.TestCase): @@ -466,7 +466,11 @@ class HandlerExceptionTest(unittest.TestCase): "pyexpat.c", "StartElement") self.check_traceback_entry(entries[2], "test_pyexpat.py", "StartElementHandler") - if sysconfig.is_python_build() and not (sys.platform == 'win32' and platform.machine() == 'ARM'): + if (sysconfig.is_python_build() + and not (sys.platform == 'win32' and platform.machine() == 'ARM') + and not is_emscripten + and not is_wasi + ): self.assertIn('call_with_frame("StartElement"', entries[1][3]) @@ -504,7 +508,7 @@ class PositionTest(unittest.TestCase): class sf1296433Test(unittest.TestCase): def test_parse_only_xml_data(self): - # http://python.org/sf/1296433 + # https://bugs.python.org/issue1296433 # xml = "%s" % ('a' * 1025) # this one doesn't crash diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index cfa6003a867..33113a72e6b 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -10,6 +10,8 @@ from test.support import gc_collect from test.support import import_helper from test.support import threading_helper +# queue module depends on threading primitives +threading_helper.requires_working_threading(module=True) py_queue = import_helper.import_fresh_module('queue', blocked=['_queue']) c_queue = import_helper.import_fresh_module('queue', fresh=['_queue']) @@ -289,6 +291,7 @@ class CPriorityQueueTest(PriorityQueueTest, unittest.TestCase): # A Queue subclass that can provoke failure at a moment's notice :) class FailingQueueException(Exception): pass + class FailingQueueTest(BlockingTestMixin): def setUp(self): diff --git a/Lib/test/test_quopri.py b/Lib/test/test_quopri.py index 715544c8a96..152d1858dcd 100644 --- a/Lib/test/test_quopri.py +++ b/Lib/test/test_quopri.py @@ -3,6 +3,7 @@ import unittest import sys, io, subprocess import quopri +from test import support ENCSAMPLE = b"""\ @@ -180,6 +181,7 @@ zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz''') for p, e in self.HSTRINGS: self.assertEqual(quopri.decodestring(e, header=True), p) + @support.requires_subprocess() def test_scriptencode(self): (p, e) = self.STRINGS[-1] process = subprocess.Popen([sys.executable, "-mquopri"], @@ -196,6 +198,7 @@ zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz''') self.assertEqual(cout[i], e[i]) self.assertEqual(cout, e) + @support.requires_subprocess() def test_scriptdecode(self): (p, e) = self.STRINGS[-1] process = subprocess.Popen([sys.executable, "-mquopri", "-d"], diff --git a/Lib/test/test_raise.py b/Lib/test/test_raise.py index 8dc62a933e8..5936d7535ed 100644 --- a/Lib/test/test_raise.py +++ b/Lib/test/test_raise.py @@ -12,8 +12,8 @@ import unittest def get_tb(): try: raise OSError() - except: - return sys.exc_info()[2] + except OSError as e: + return e.__traceback__ class Context: @@ -303,7 +303,7 @@ class TestContext(unittest.TestCase): except: raise OSError() except OSError as e: - self.assertEqual(e.__context__, context) + self.assertIs(e.__context__, context) else: self.fail("No exception raised") @@ -315,7 +315,7 @@ class TestContext(unittest.TestCase): except: raise OSError() except OSError as e: - self.assertNotEqual(e.__context__, context) + self.assertIsNot(e.__context__, context) self.assertIsInstance(e.__context__, context) else: self.fail("No exception raised") @@ -328,7 +328,7 @@ class TestContext(unittest.TestCase): except: raise OSError except OSError as e: - self.assertNotEqual(e.__context__, context) + self.assertIsNot(e.__context__, context) self.assertIsInstance(e.__context__, context) else: self.fail("No exception raised") @@ -415,6 +415,22 @@ class TestContext(unittest.TestCase): except NameError as e: self.assertIsNone(e.__context__.__context__) + def test_not_last(self): + # Context is not necessarily the last exception + context = Exception("context") + try: + raise context + except Exception: + try: + raise Exception("caught") + except Exception: + pass + try: + raise Exception("new") + except Exception as exc: + raised = exc + self.assertIs(raised.__context__, context) + def test_3118(self): # deleting the generator caused the __context__ to be cleared def gen(): diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index cdae8897c2a..50bea7be6d5 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -111,6 +111,21 @@ class TestBasicOps: self.assertEqual(choice([50]), 50) self.assertIn(choice([25, 75]), [25, 75]) + def test_choice_with_numpy(self): + # Accommodation for NumPy arrays which have disabled __bool__(). + # See: https://github.com/python/cpython/issues/100805 + choice = self.gen.choice + + class NA(list): + "Simulate numpy.array() behavior" + def __bool__(self): + raise RuntimeError + + with self.assertRaises(IndexError): + choice(NA([])) + self.assertEqual(choice(NA([50])), 50) + self.assertIn(choice(NA([25, 75])), [25, 75]) + def test_sample(self): # For the entire allowable range of 0 <= k <= N, validate that # the sample is of the correct length and contains only unique items @@ -409,6 +424,10 @@ class TestBasicOps: self.assertRaises(ValueError, self.gen.randbytes, -1) self.assertRaises(TypeError, self.gen.randbytes, 1.0) + def test_mu_sigma_default_args(self): + self.assertIsInstance(self.gen.normalvariate(), float) + self.assertIsInstance(self.gen.gauss(), float) + try: random.SystemRandom().random() @@ -816,10 +835,6 @@ class MersenneTwister_TestBasicOps(TestBasicOps, unittest.TestCase): maxsize+1, maxsize=maxsize ) self.gen._randbelow_without_getrandbits(5640, maxsize=maxsize) - # issue 33203: test that _randbelow returns zero on - # n == 0 also in its getrandbits-independent branch. - x = self.gen._randbelow_without_getrandbits(0, maxsize=maxsize) - self.assertEqual(x, 0) # This might be going too far to test a single line, but because of our # noble aim of achieving 100% test coverage we need to write a case in @@ -988,6 +1003,7 @@ class TestDistributions(unittest.TestCase): g.random = x[:].pop; g.uniform(1,10) g.random = x[:].pop; g.paretovariate(1.0) g.random = x[:].pop; g.expovariate(1.0) + g.random = x[:].pop; g.expovariate() g.random = x[:].pop; g.weibullvariate(1.0, 1.0) g.random = x[:].pop; g.vonmisesvariate(1.0, 1.0) g.random = x[:].pop; g.normalvariate(0.0, 1.0) @@ -1045,6 +1061,9 @@ class TestDistributions(unittest.TestCase): (g.lognormvariate, (0.0, 0.0), 1.0), (g.lognormvariate, (-float('inf'), 0.0), 0.0), (g.normalvariate, (10.0, 0.0), 10.0), + (g.binomialvariate, (0, 0.5), 0), + (g.binomialvariate, (10, 0.0), 0), + (g.binomialvariate, (10, 1.0), 10), (g.paretovariate, (float('inf'),), 1.0), (g.weibullvariate, (10.0, float('inf')), 10.0), (g.weibullvariate, (0.0, 10.0), 0.0), @@ -1052,6 +1071,59 @@ class TestDistributions(unittest.TestCase): for i in range(N): self.assertEqual(variate(*args), expected) + def test_binomialvariate(self): + B = random.binomialvariate + + # Cover all the code paths + with self.assertRaises(ValueError): + B(n=-1) # Negative n + with self.assertRaises(ValueError): + B(n=1, p=-0.5) # Negative p + with self.assertRaises(ValueError): + B(n=1, p=1.5) # p > 1.0 + self.assertEqual(B(10, 0.0), 0) # p == 0.0 + self.assertEqual(B(10, 1.0), 10) # p == 1.0 + self.assertTrue(B(1, 0.3) in {0, 1}) # n == 1 fast path + self.assertTrue(B(1, 0.9) in {0, 1}) # n == 1 fast path + self.assertTrue(B(1, 0.0) in {0}) # n == 1 fast path + self.assertTrue(B(1, 1.0) in {1}) # n == 1 fast path + + # BG method p <= 0.5 and n*p=1.25 + self.assertTrue(B(5, 0.25) in set(range(6))) + + # BG method p >= 0.5 and n*(1-p)=1.25 + self.assertTrue(B(5, 0.75) in set(range(6))) + + # BTRS method p <= 0.5 and n*p=25 + self.assertTrue(B(100, 0.25) in set(range(101))) + + # BTRS method p > 0.5 and n*(1-p)=25 + self.assertTrue(B(100, 0.75) in set(range(101))) + + # Statistical tests chosen such that they are + # exceedingly unlikely to ever fail for correct code. + + # BG code path + # Expected dist: [31641, 42188, 21094, 4688, 391] + c = Counter(B(4, 0.25) for i in range(100_000)) + self.assertTrue(29_641 <= c[0] <= 33_641, c) + self.assertTrue(40_188 <= c[1] <= 44_188) + self.assertTrue(19_094 <= c[2] <= 23_094) + self.assertTrue(2_688 <= c[3] <= 6_688) + self.assertEqual(set(c), {0, 1, 2, 3, 4}) + + # BTRS code path + # Sum of c[20], c[21], c[22], c[23], c[24] expected to be 36,214 + c = Counter(B(100, 0.25) for i in range(100_000)) + self.assertTrue(34_214 <= c[20]+c[21]+c[22]+c[23]+c[24] <= 38_214) + self.assertTrue(set(c) <= set(range(101))) + self.assertEqual(c.total(), 100_000) + + # Demonstrate the BTRS works for huge values of n + self.assertTrue(19_000_000 <= B(100_000_000, 0.2) <= 21_000_000) + self.assertTrue(89_000_000 <= B(100_000_000, 0.9) <= 91_000_000) + + def test_von_mises_range(self): # Issue 17149: von mises variates were not consistently in the # range [0, 2*PI]. @@ -1297,7 +1369,7 @@ class TestModule(unittest.TestCase): # tests validity but not completeness of the __all__ list self.assertTrue(set(random.__all__) <= set(dir(random))) - @unittest.skipUnless(hasattr(os, "fork"), "fork() required") + @test.support.requires_fork() def test_after_fork(self): # Test the global Random instance gets reseeded in child r, w = os.pipe() diff --git a/Lib/test/test_range.py b/Lib/test/test_range.py index 851ad5b7c2f..3870b153688 100644 --- a/Lib/test/test_range.py +++ b/Lib/test/test_range.py @@ -407,11 +407,7 @@ class RangeTest(unittest.TestCase): for proto in range(pickle.HIGHEST_PROTOCOL + 1): with self.subTest(proto=proto): it = iter(range(2**32 + 2)) - _, _, idx = it.__reduce__() - self.assertEqual(idx, 0) - it.__setstate__(2**32 + 1) # undocumented way to set r->index - _, _, idx = it.__reduce__() - self.assertEqual(idx, 2**32 + 1) + it.__setstate__(2**32 + 1) # undocumented way to advance an iterator d = pickle.dumps(it, proto) it = pickle.loads(d) self.assertEqual(next(it), 2**32 + 1) @@ -442,6 +438,38 @@ class RangeTest(unittest.TestCase): self.assertEqual(list(i), []) self.assertEqual(list(i2), []) + def test_iterator_unpickle_compat(self): + testcases = [ + b'c__builtin__\niter\n(c__builtin__\nxrange\n(I10\nI20\nI2\ntRtRI2\nb.', + b'c__builtin__\niter\n(c__builtin__\nxrange\n(K\nK\x14K\x02tRtRK\x02b.', + b'\x80\x02c__builtin__\niter\nc__builtin__\nxrange\nK\nK\x14K\x02\x87R\x85RK\x02b.', + b'\x80\x03cbuiltins\niter\ncbuiltins\nrange\nK\nK\x14K\x02\x87R\x85RK\x02b.', + b'\x80\x04\x951\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x8c\x04iter\x93\x8c\x08builtins\x8c\x05range\x93K\nK\x14K\x02\x87R\x85RK\x02b.', + + b'c__builtin__\niter\n(c__builtin__\nxrange\n(L-36893488147419103232L\nI20\nI2\ntRtRL18446744073709551623L\nb.', + b'c__builtin__\niter\n(c__builtin__\nxrange\n(L-36893488147419103232L\nK\x14K\x02tRtRL18446744073709551623L\nb.', + b'\x80\x02c__builtin__\niter\nc__builtin__\nxrange\n\x8a\t\x00\x00\x00\x00\x00\x00\x00\x00\xfeK\x14K\x02\x87R\x85R\x8a\t\x07\x00\x00\x00\x00\x00\x00\x00\x01b.', + b'\x80\x03cbuiltins\niter\ncbuiltins\nrange\n\x8a\t\x00\x00\x00\x00\x00\x00\x00\x00\xfeK\x14K\x02\x87R\x85R\x8a\t\x07\x00\x00\x00\x00\x00\x00\x00\x01b.', + b'\x80\x04\x95C\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x8c\x04iter\x93\x8c\x08builtins\x8c\x05range\x93\x8a\t\x00\x00\x00\x00\x00\x00\x00\x00\xfeK\x14K\x02\x87R\x85R\x8a\t\x07\x00\x00\x00\x00\x00\x00\x00\x01b.', + ] + for t in testcases: + it = pickle.loads(t) + self.assertEqual(list(it), [14, 16, 18]) + + def test_iterator_setstate(self): + it = iter(range(10, 20, 2)) + it.__setstate__(2) + self.assertEqual(list(it), [14, 16, 18]) + it = reversed(range(10, 20, 2)) + it.__setstate__(3) + self.assertEqual(list(it), [12, 10]) + it = iter(range(-2**65, 20, 2)) + it.__setstate__(2**64 + 7) + self.assertEqual(list(it), [14, 16, 18]) + it = reversed(range(10, 2**65, 2)) + it.__setstate__(2**64 - 7) + self.assertEqual(list(it), [12, 10]) + def test_odd_bug(self): # This used to raise a "SystemError: NULL result without error" # because the range validation step was eating the exception @@ -514,6 +542,7 @@ class RangeTest(unittest.TestCase): for start in limits for end in limits for step in (-2**63, -2**31, -2, -1, 1, 2)] + test_ranges += [(-2**63, 2**63-2, 1)] # regression test for gh-100810 for start, end, step in test_ranges: iter1 = range(start, end, step) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 18fa24a99ce..11628a236ad 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1,15 +1,25 @@ from test.support import (gc_collect, bigmemtest, _2G, cpython_only, captured_stdout, - check_disallow_instantiation) + check_disallow_instantiation, is_emscripten, is_wasi, + SHORT_TIMEOUT) import locale import re -import sre_compile import string +import sys +import time import unittest import warnings from re import Scanner from weakref import proxy +# some platforms lack working multiprocessing +try: + import _multiprocessing +except ImportError: + multiprocessing = None +else: + import multiprocessing + # Misc tests from Tim Peters' re.doc # WARNING: Don't change details in these tests if you don't know @@ -83,6 +93,23 @@ class ReTests(unittest.TestCase): self.assertEqual(re.match('x*', 'xxxa').span(), (0, 3)) self.assertIsNone(re.match('a+', 'xxx')) + def test_branching(self): + """Test Branching + Test expressions using the OR ('|') operator.""" + self.assertEqual(re.match('(ab|ba)', 'ab').span(), (0, 2)) + self.assertEqual(re.match('(ab|ba)', 'ba').span(), (0, 2)) + self.assertEqual(re.match('(abc|bac|ca|cb)', 'abc').span(), + (0, 3)) + self.assertEqual(re.match('(abc|bac|ca|cb)', 'bac').span(), + (0, 3)) + self.assertEqual(re.match('(abc|bac|ca|cb)', 'ca').span(), + (0, 2)) + self.assertEqual(re.match('(abc|bac|ca|cb)', 'cb').span(), + (0, 2)) + self.assertEqual(re.match('((a)|(b)|(c))', 'a').span(), (0, 1)) + self.assertEqual(re.match('((a)|(b)|(c))', 'b').span(), (0, 1)) + self.assertEqual(re.match('((a)|(b)|(c))', 'c').span(), (0, 1)) + def bump_num(self, matchobj): int_value = int(matchobj.group(0)) return str(int_value + 1) @@ -117,6 +144,7 @@ class ReTests(unittest.TestCase): self.assertEqual(re.sub('(?Px)', r'\g\g<1>', 'xx'), 'xxxx') self.assertEqual(re.sub('(?Px)', r'\g\g', 'xx'), 'xxxx') self.assertEqual(re.sub('(?Px)', r'\g<1>\g<1>', 'xx'), 'xxxx') + self.assertEqual(re.sub('()x', r'\g<0>\g<0>', 'xx'), 'xxxx') self.assertEqual(re.sub('a', r'\t\n\v\r\f\a\b', 'a'), '\t\n\v\r\f\a\b') self.assertEqual(re.sub('a', '\t\n\v\r\f\a\b', 'a'), '\t\n\v\r\f\a\b') @@ -218,6 +246,16 @@ class ReTests(unittest.TestCase): re.compile(r'(?Px)(?P=a)(?(a)y)') re.compile(r'(?Px)(?P=a1)(?(a1)y)') re.compile(r'(?Px)\1(?(1)y)') + re.compile(b'(?Px)(?P=a1)(?(a1)y)') + # New valid identifiers in Python 3 + re.compile('(?P<µ>x)(?P=µ)(?(µ)y)') + re.compile('(?P<ð”˜ð”«ð”¦ð” ð”¬ð”¡ð”¢>x)(?P=ð”˜ð”«ð”¦ð” ð”¬ð”¡ð”¢)(?(ð”˜ð”«ð”¦ð” ð”¬ð”¡ð”¢)y)') + # Support > 100 groups. + pat = '|'.join('x(?P%x)y' % (i, i) for i in range(1, 200 + 1)) + pat = '(?:%s)(?(200)z|t)' % pat + self.assertEqual(re.match(pat, 'xc8yz').span(), (0, 5)) + + def test_symbolic_groups_errors(self): self.checkPatternError(r'(?P)(?P)', "redefinition of group name 'a' as group 2; " "was group 1") @@ -243,16 +281,28 @@ class ReTests(unittest.TestCase): self.checkPatternError(r'(?(-1))', "bad character in group name '-1'", 3) self.checkPatternError(r'(?(1a))', "bad character in group name '1a'", 3) self.checkPatternError(r'(?(a.))', "bad character in group name 'a.'", 3) - # New valid/invalid identifiers in Python 3 - re.compile('(?P<µ>x)(?P=µ)(?(µ)y)') - re.compile('(?P<ð”˜ð”«ð”¦ð” ð”¬ð”¡ð”¢>x)(?P=ð”˜ð”«ð”¦ð” ð”¬ð”¡ð”¢)(?(ð”˜ð”«ð”¦ð” ð”¬ð”¡ð”¢)y)') self.checkPatternError('(?P<©>x)', "bad character in group name '©'", 4) - # Support > 100 groups. - pat = '|'.join('x(?P%x)y' % (i, i) for i in range(1, 200 + 1)) - pat = '(?:%s)(?(200)z|t)' % pat - self.assertEqual(re.match(pat, 'xc8yz').span(), (0, 5)) + self.checkPatternError('(?P=©)', "bad character in group name '©'", 4) + self.checkPatternError('(?(©)y)', "bad character in group name '©'", 3) + self.checkPatternError(b'(?P<\xc2\xb5>x)', + r"bad character in group name '\xc2\xb5'", 4) + self.checkPatternError(b'(?P=\xc2\xb5)', + r"bad character in group name '\xc2\xb5'", 4) + self.checkPatternError(b'(?(\xc2\xb5)y)', + r"bad character in group name '\xc2\xb5'", 3) def test_symbolic_refs(self): + self.assertEqual(re.sub('(?Px)|(?Py)', r'\g', 'xx'), '') + self.assertEqual(re.sub('(?Px)|(?Py)', r'\2', 'xx'), '') + self.assertEqual(re.sub(b'(?Px)', br'\g', b'xx'), b'xx') + # New valid identifiers in Python 3 + self.assertEqual(re.sub('(?P<µ>x)', r'\g<µ>', 'xx'), 'xx') + self.assertEqual(re.sub('(?P<ð”˜ð”«ð”¦ð” ð”¬ð”¡ð”¢>x)', r'\g<ð”˜ð”«ð”¦ð” ð”¬ð”¡ð”¢>', 'xx'), 'xx') + # Support > 100 groups. + pat = '|'.join('x(?P%x)y' % (i, i) for i in range(1, 200 + 1)) + self.assertEqual(re.sub(pat, r'\g<200>', 'xc8yzxc8y'), 'c8zc8') + + def test_symbolic_refs_errors(self): self.checkTemplateError('(?Px)', r'\g, unterminated name', 3) self.checkTemplateError('(?Px)', r'\g<', 'xx', @@ -270,18 +320,24 @@ class ReTests(unittest.TestCase): 'invalid group reference 2', 1) with self.assertRaisesRegex(IndexError, "unknown group name 'ab'"): re.sub('(?Px)', r'\g', 'xx') - self.assertEqual(re.sub('(?Px)|(?Py)', r'\g', 'xx'), '') - self.assertEqual(re.sub('(?Px)|(?Py)', r'\2', 'xx'), '') self.checkTemplateError('(?Px)', r'\g<-1>', 'xx', "bad character in group name '-1'", 3) - # New valid/invalid identifiers in Python 3 - self.assertEqual(re.sub('(?P<µ>x)', r'\g<µ>', 'xx'), 'xx') - self.assertEqual(re.sub('(?P<ð”˜ð”«ð”¦ð” ð”¬ð”¡ð”¢>x)', r'\g<ð”˜ð”«ð”¦ð” ð”¬ð”¡ð”¢>', 'xx'), 'xx') + self.checkTemplateError('(?Px)', r'\g<+1>', 'xx', + "bad character in group name '+1'", 3) + self.checkTemplateError('()'*10, r'\g<1_0>', 'xx', + "bad character in group name '1_0'", 3) + self.checkTemplateError('(?Px)', r'\g< 1 >', 'xx', + "bad character in group name ' 1 '", 3) self.checkTemplateError('(?Px)', r'\g<©>', 'xx', "bad character in group name '©'", 3) - # Support > 100 groups. - pat = '|'.join('x(?P%x)y' % (i, i) for i in range(1, 200 + 1)) - self.assertEqual(re.sub(pat, r'\g<200>', 'xc8yzxc8y'), 'c8zc8') + self.checkTemplateError(b'(?Px)', b'\\g<\xc2\xb5>', b'xx', + r"bad character in group name '\xc2\xb5'", 3) + self.checkTemplateError('(?Px)', r'\g<㊀>', 'xx', + "bad character in group name '㊀'", 3) + self.checkTemplateError('(?Px)', r'\g<¹>', 'xx', + "bad character in group name '¹'", 3) + self.checkTemplateError('(?Px)', r'\g<१>', 'xx', + "bad character in group name '१'", 3) def test_re_subn(self): self.assertEqual(re.subn("(?i)b+", "x", "bbbb BBBB"), ('x x', 2)) @@ -543,15 +599,44 @@ class ReTests(unittest.TestCase): pat = '(?:%s)(?(200)z)' % pat self.assertEqual(re.match(pat, 'xc8yz').span(), (0, 5)) - self.checkPatternError(r'(?P)(?(0))', 'bad group number', 10) + def test_re_groupref_exists_errors(self): + self.checkPatternError(r'(?P)(?(0)a|b)', 'bad group number', 10) + self.checkPatternError(r'()(?(-1)a|b)', + "bad character in group name '-1'", 5) + self.checkPatternError(r'()(?(+1)a|b)', + "bad character in group name '+1'", 5) + self.checkPatternError(r'()'*10 + r'(?(1_0)a|b)', + "bad character in group name '1_0'", 23) + self.checkPatternError(r'()(?( 1 )a|b)', + "bad character in group name ' 1 '", 5) + self.checkPatternError(r'()(?(㊀)a|b)', + "bad character in group name '㊀'", 5) + self.checkPatternError(r'()(?(¹)a|b)', + "bad character in group name '¹'", 5) + self.checkPatternError(r'()(?(१)a|b)', + "bad character in group name '१'", 5) + self.checkPatternError(r'()(?(1', + "missing ), unterminated name", 5) + self.checkPatternError(r'()(?(1)a', + "missing ), unterminated subpattern", 2) self.checkPatternError(r'()(?(1)a|b', 'missing ), unterminated subpattern', 2) + self.checkPatternError(r'()(?(1)a|b|c', + 'conditional backref with more than ' + 'two branches', 10) self.checkPatternError(r'()(?(1)a|b|c)', 'conditional backref with more than ' 'two branches', 10) + self.checkPatternError(r'()(?(2)a)', + "invalid group reference 2", 5) + + def test_re_groupref_exists_validation_bug(self): + for i in range(256): + with self.subTest(code=i): + re.compile(r'()(?(1)\x%02x?)' % i) def test_re_groupref_overflow(self): - from sre_constants import MAXGROUPS + from re._constants import MAXGROUPS self.checkTemplateError('()', r'\g<%s>' % MAXGROUPS, 'xx', 'invalid group reference %d' % MAXGROUPS, 3) self.checkPatternError(r'(?P)(?(%d))' % MAXGROUPS, @@ -728,6 +813,10 @@ class ReTests(unittest.TestCase): "undefined character name 'SPAM'", 0) self.checkPatternError(r'[\N{SPAM}]', "undefined character name 'SPAM'", 1) + self.checkPatternError(r'\N{KEYCAP NUMBER SIGN}', + "undefined character name 'KEYCAP NUMBER SIGN'", 0) + self.checkPatternError(r'[\N{KEYCAP NUMBER SIGN}]', + "undefined character name 'KEYCAP NUMBER SIGN'", 1) self.checkPatternError(br'\N{LESS-THAN SIGN}', r'bad escape \N', 0) self.checkPatternError(br'[\N{LESS-THAN SIGN}]', r'bad escape \N', 1) @@ -841,16 +930,30 @@ class ReTests(unittest.TestCase): self.assertEqual(re.match(r"((a)\s(abc|a))", "a a", re.I).group(1), "a a") self.assertEqual(re.match(r"((a)\s(abc|a)*)", "a aa", re.I).group(1), "a aa") - assert '\u212a'.lower() == 'k' # 'K' + # Two different characters have the same lowercase. + assert 'K'.lower() == '\u212a'.lower() == 'k' # 'K' self.assertTrue(re.match(r'K', '\u212a', re.I)) self.assertTrue(re.match(r'k', '\u212a', re.I)) self.assertTrue(re.match(r'\u212a', 'K', re.I)) self.assertTrue(re.match(r'\u212a', 'k', re.I)) - assert '\u017f'.upper() == 'S' # 'Å¿' + + # Two different characters have the same uppercase. + assert 's'.upper() == '\u017f'.upper() == 'S' # 'Å¿' self.assertTrue(re.match(r'S', '\u017f', re.I)) self.assertTrue(re.match(r's', '\u017f', re.I)) self.assertTrue(re.match(r'\u017f', 'S', re.I)) self.assertTrue(re.match(r'\u017f', 's', re.I)) + + # Two different characters have the same uppercase. Unicode 9.0+. + assert '\u0432'.upper() == '\u1c80'.upper() == '\u0412' # 'в', 'á²€', 'Ð’' + self.assertTrue(re.match(r'\u0412', '\u0432', re.I)) + self.assertTrue(re.match(r'\u0412', '\u1c80', re.I)) + self.assertTrue(re.match(r'\u0432', '\u0412', re.I)) + self.assertTrue(re.match(r'\u0432', '\u1c80', re.I)) + self.assertTrue(re.match(r'\u1c80', '\u0412', re.I)) + self.assertTrue(re.match(r'\u1c80', '\u0432', re.I)) + + # Two different characters have the same multicharacter uppercase. assert '\ufb05'.upper() == '\ufb06'.upper() == 'ST' # 'ſt', 'st' self.assertTrue(re.match(r'\ufb05', '\ufb06', re.I)) self.assertTrue(re.match(r'\ufb06', '\ufb05', re.I)) @@ -864,16 +967,31 @@ class ReTests(unittest.TestCase): self.assertTrue(re.match(br'[19a]', b'a', re.I)) self.assertTrue(re.match(br'[19a]', b'A', re.I)) self.assertTrue(re.match(br'[19A]', b'a', re.I)) - assert '\u212a'.lower() == 'k' # 'K' + + # Two different characters have the same lowercase. + assert 'K'.lower() == '\u212a'.lower() == 'k' # 'K' self.assertTrue(re.match(r'[19K]', '\u212a', re.I)) self.assertTrue(re.match(r'[19k]', '\u212a', re.I)) self.assertTrue(re.match(r'[19\u212a]', 'K', re.I)) self.assertTrue(re.match(r'[19\u212a]', 'k', re.I)) - assert '\u017f'.upper() == 'S' # 'Å¿' + + # Two different characters have the same uppercase. + assert 's'.upper() == '\u017f'.upper() == 'S' # 'Å¿' self.assertTrue(re.match(r'[19S]', '\u017f', re.I)) self.assertTrue(re.match(r'[19s]', '\u017f', re.I)) self.assertTrue(re.match(r'[19\u017f]', 'S', re.I)) self.assertTrue(re.match(r'[19\u017f]', 's', re.I)) + + # Two different characters have the same uppercase. Unicode 9.0+. + assert '\u0432'.upper() == '\u1c80'.upper() == '\u0412' # 'в', 'á²€', 'Ð’' + self.assertTrue(re.match(r'[19\u0412]', '\u0432', re.I)) + self.assertTrue(re.match(r'[19\u0412]', '\u1c80', re.I)) + self.assertTrue(re.match(r'[19\u0432]', '\u0412', re.I)) + self.assertTrue(re.match(r'[19\u0432]', '\u1c80', re.I)) + self.assertTrue(re.match(r'[19\u1c80]', '\u0412', re.I)) + self.assertTrue(re.match(r'[19\u1c80]', '\u0432', re.I)) + + # Two different characters have the same multicharacter uppercase. assert '\ufb05'.upper() == '\ufb06'.upper() == 'ST' # 'ſt', 'st' self.assertTrue(re.match(r'[19\ufb05]', '\ufb06', re.I)) self.assertTrue(re.match(r'[19\ufb06]', '\ufb05', re.I)) @@ -897,16 +1015,30 @@ class ReTests(unittest.TestCase): self.assertTrue(re.match(r'[\U00010400-\U00010427]', '\U00010428', re.I)) self.assertTrue(re.match(r'[\U00010400-\U00010427]', '\U00010400', re.I)) - assert '\u212a'.lower() == 'k' # 'K' + # Two different characters have the same lowercase. + assert 'K'.lower() == '\u212a'.lower() == 'k' # 'K' self.assertTrue(re.match(r'[J-M]', '\u212a', re.I)) self.assertTrue(re.match(r'[j-m]', '\u212a', re.I)) self.assertTrue(re.match(r'[\u2129-\u212b]', 'K', re.I)) self.assertTrue(re.match(r'[\u2129-\u212b]', 'k', re.I)) - assert '\u017f'.upper() == 'S' # 'Å¿' + + # Two different characters have the same uppercase. + assert 's'.upper() == '\u017f'.upper() == 'S' # 'Å¿' self.assertTrue(re.match(r'[R-T]', '\u017f', re.I)) self.assertTrue(re.match(r'[r-t]', '\u017f', re.I)) self.assertTrue(re.match(r'[\u017e-\u0180]', 'S', re.I)) self.assertTrue(re.match(r'[\u017e-\u0180]', 's', re.I)) + + # Two different characters have the same uppercase. Unicode 9.0+. + assert '\u0432'.upper() == '\u1c80'.upper() == '\u0412' # 'в', 'á²€', 'Ð’' + self.assertTrue(re.match(r'[\u0411-\u0413]', '\u0432', re.I)) + self.assertTrue(re.match(r'[\u0411-\u0413]', '\u1c80', re.I)) + self.assertTrue(re.match(r'[\u0431-\u0433]', '\u0412', re.I)) + self.assertTrue(re.match(r'[\u0431-\u0433]', '\u1c80', re.I)) + self.assertTrue(re.match(r'[\u1c80-\u1c82]', '\u0412', re.I)) + self.assertTrue(re.match(r'[\u1c80-\u1c82]', '\u0432', re.I)) + + # Two different characters have the same multicharacter uppercase. assert '\ufb05'.upper() == '\ufb06'.upper() == 'ST' # 'ſt', 'st' self.assertTrue(re.match(r'[\ufb04-\ufb05]', '\ufb06', re.I)) self.assertTrue(re.match(r'[\ufb06-\ufb07]', '\ufb05', re.I)) @@ -1239,11 +1371,13 @@ class ReTests(unittest.TestCase): 'nothing to repeat', 3) def test_multiple_repeat(self): - for outer_reps in '*', '+', '{1,2}': - for outer_mod in '', '?': + for outer_reps in '*', '+', '?', '{1,2}': + for outer_mod in '', '?', '+': outer_op = outer_reps + outer_mod for inner_reps in '*', '+', '?', '{1,2}': - for inner_mod in '', '?': + for inner_mod in '', '?', '+': + if inner_mod + outer_reps in ('?', '+'): + continue inner_op = inner_reps + inner_mod self.checkPatternError(r'x%s%s' % (inner_op, outer_op), 'multiple repeat', 1 + len(inner_op)) @@ -1439,67 +1573,27 @@ class ReTests(unittest.TestCase): self.assertTrue(re.match('(?x) (?i) ' + upper_char, lower_char)) self.assertTrue(re.match(' (?x) (?i) ' + upper_char, lower_char, re.X)) - p = upper_char + '(?i)' - with self.assertWarns(DeprecationWarning) as warns: - self.assertTrue(re.match(p, lower_char)) - self.assertEqual( - str(warns.warnings[0].message), - 'Flags not at the start of the expression %r' % p - ) - self.assertEqual(warns.warnings[0].filename, __file__) - - p = upper_char + '(?i)%s' % ('.?' * 100) - with self.assertWarns(DeprecationWarning) as warns: - self.assertTrue(re.match(p, lower_char)) - self.assertEqual( - str(warns.warnings[0].message), - 'Flags not at the start of the expression %r (truncated)' % p[:20] - ) - self.assertEqual(warns.warnings[0].filename, __file__) + msg = "global flags not at the start of the expression" + self.checkPatternError(upper_char + '(?i)', msg, 1) # bpo-30605: Compiling a bytes instance regex was throwing a BytesWarning with warnings.catch_warnings(): warnings.simplefilter('error', BytesWarning) - p = b'A(?i)' - with self.assertWarns(DeprecationWarning) as warns: - self.assertTrue(re.match(p, b'a')) - self.assertEqual( - str(warns.warnings[0].message), - 'Flags not at the start of the expression %r' % p - ) - self.assertEqual(warns.warnings[0].filename, __file__) + self.checkPatternError(b'A(?i)', msg, 1) - with self.assertWarns(DeprecationWarning): - self.assertTrue(re.match('(?s).(?i)' + upper_char, '\n' + lower_char)) - with self.assertWarns(DeprecationWarning): - self.assertTrue(re.match('(?i) ' + upper_char + ' (?x)', lower_char)) - with self.assertWarns(DeprecationWarning): - self.assertTrue(re.match(' (?x) (?i) ' + upper_char, lower_char)) - with self.assertWarns(DeprecationWarning): - self.assertTrue(re.match('^(?i)' + upper_char, lower_char)) - with self.assertWarns(DeprecationWarning): - self.assertTrue(re.match('$|(?i)' + upper_char, lower_char)) - with self.assertWarns(DeprecationWarning) as warns: - self.assertTrue(re.match('(?:(?i)' + upper_char + ')', lower_char)) - self.assertRegex(str(warns.warnings[0].message), - 'Flags not at the start') - self.assertEqual(warns.warnings[0].filename, __file__) - with self.assertWarns(DeprecationWarning) as warns: - self.assertTrue(re.fullmatch('(^)?(?(1)(?i)' + upper_char + ')', - lower_char)) - self.assertRegex(str(warns.warnings[0].message), - 'Flags not at the start') - self.assertEqual(warns.warnings[0].filename, __file__) - with self.assertWarns(DeprecationWarning) as warns: - self.assertTrue(re.fullmatch('($)?(?(1)|(?i)' + upper_char + ')', - lower_char)) - self.assertRegex(str(warns.warnings[0].message), - 'Flags not at the start') - self.assertEqual(warns.warnings[0].filename, __file__) + self.checkPatternError('(?s).(?i)' + upper_char, msg, 5) + self.checkPatternError('(?i) ' + upper_char + ' (?x)', msg, 7) + self.checkPatternError(' (?x) (?i) ' + upper_char, msg, 1) + self.checkPatternError('^(?i)' + upper_char, msg, 1) + self.checkPatternError('$|(?i)' + upper_char, msg, 2) + self.checkPatternError('(?:(?i)' + upper_char + ')', msg, 3) + self.checkPatternError('(^)?(?(1)(?i)' + upper_char + ')', msg, 9) + self.checkPatternError('($)?(?(1)|(?i)' + upper_char + ')', msg, 10) def test_dollar_matches_twice(self): - "$ matches the end of string, and just before the terminating \n" + r"""Test that $ does not include \n + $ matches the end of string, and just before the terminating \n""" pattern = re.compile('$') self.assertEqual(pattern.sub('#', 'a\nb\n'), 'a\nb#\n#') self.assertEqual(pattern.sub('#', 'a\nb\nc'), 'a\nb\nc#') @@ -1605,11 +1699,6 @@ class ReTests(unittest.TestCase): self.assertIsNone(re.match(r'(?i:(?-i:a)b)', 'Ab')) self.assertTrue(re.match(r'(?i:(?-i:a)b)', 'aB')) - self.assertTrue(re.match(r'(?x: a) b', 'a b')) - self.assertIsNone(re.match(r'(?x: a) b', ' a b')) - self.assertTrue(re.match(r'(?-x: a) b', ' ab', re.VERBOSE)) - self.assertIsNone(re.match(r'(?-x: a) b', 'ab', re.VERBOSE)) - self.assertTrue(re.match(r'\w(?a:\W)\w', '\xe0\xe0\xe0')) self.assertTrue(re.match(r'(?a:\W(?u:\w)\W)', '\xe0\xe0\xe0')) self.assertTrue(re.match(r'\W(?u:\w)\W', '\xe0\xe0\xe0', re.ASCII)) @@ -1635,6 +1724,33 @@ class ReTests(unittest.TestCase): self.checkPatternError(r'(?i+', 'missing -, : or )', 3) self.checkPatternError(r'(?iz', 'unknown flag', 3) + def test_ignore_spaces(self): + for space in " \t\n\r\v\f": + self.assertTrue(re.fullmatch(space + 'a', 'a', re.VERBOSE)) + for space in b" ", b"\t", b"\n", b"\r", b"\v", b"\f": + self.assertTrue(re.fullmatch(space + b'a', b'a', re.VERBOSE)) + self.assertTrue(re.fullmatch('(?x) a', 'a')) + self.assertTrue(re.fullmatch(' (?x) a', 'a', re.VERBOSE)) + self.assertTrue(re.fullmatch('(?x) (?x) a', 'a')) + self.assertTrue(re.fullmatch(' a(?x: b) c', ' ab c')) + self.assertTrue(re.fullmatch(' a(?-x: b) c', 'a bc', re.VERBOSE)) + self.assertTrue(re.fullmatch('(?x) a(?-x: b) c', 'a bc')) + self.assertTrue(re.fullmatch('(?x) a| b', 'a')) + self.assertTrue(re.fullmatch('(?x) a| b', 'b')) + + def test_comments(self): + self.assertTrue(re.fullmatch('#x\na', 'a', re.VERBOSE)) + self.assertTrue(re.fullmatch(b'#x\na', b'a', re.VERBOSE)) + self.assertTrue(re.fullmatch('(?x)#x\na', 'a')) + self.assertTrue(re.fullmatch('#x\n(?x)#y\na', 'a', re.VERBOSE)) + self.assertTrue(re.fullmatch('(?x)#x\n(?x)#y\na', 'a')) + self.assertTrue(re.fullmatch('#x\na(?x:#y\nb)#z\nc', '#x\nab#z\nc')) + self.assertTrue(re.fullmatch('#x\na(?-x:#y\nb)#z\nc', 'a#y\nbc', + re.VERBOSE)) + self.assertTrue(re.fullmatch('(?x)#x\na(?-x:#y\nb)#z\nc', 'a#y\nbc')) + self.assertTrue(re.fullmatch('(?x)#x\na|#y\nb', 'a')) + self.assertTrue(re.fullmatch('(?x)#x\na|#y\nb', 'b')) + def test_bug_6509(self): # Replacement strings of both types must parse properly. # all strings @@ -1815,60 +1931,6 @@ class ReTests(unittest.TestCase): self.assertEqual(m.group(1), "") self.assertEqual(m.group(2), "y") - @cpython_only - def test_debug_flag(self): - pat = r'(\.)(?:[ch]|py)(?(1)$|: )' - with captured_stdout() as out: - re.compile(pat, re.DEBUG) - self.maxDiff = None - dump = '''\ -SUBPATTERN 1 0 0 - LITERAL 46 -BRANCH - IN - LITERAL 99 - LITERAL 104 -OR - LITERAL 112 - LITERAL 121 -GROUPREF_EXISTS 1 - AT AT_END -ELSE - LITERAL 58 - LITERAL 32 - - 0. INFO 8 0b1 2 5 (to 9) - prefix_skip 0 - prefix [0x2e] ('.') - overlap [0] - 9: MARK 0 -11. LITERAL 0x2e ('.') -13. MARK 1 -15. BRANCH 10 (to 26) -17. IN 6 (to 24) -19. LITERAL 0x63 ('c') -21. LITERAL 0x68 ('h') -23. FAILURE -24: JUMP 9 (to 34) -26: branch 7 (to 33) -27. LITERAL 0x70 ('p') -29. LITERAL 0x79 ('y') -31. JUMP 2 (to 34) -33: FAILURE -34: GROUPREF_EXISTS 0 6 (to 41) -37. AT END -39. JUMP 5 (to 45) -41: LITERAL 0x3a (':') -43. LITERAL 0x20 (' ') -45: SUCCESS -''' - self.assertEqual(out.getvalue(), dump) - # Debug output is output again even a second time (bypassing - # the cache -- issue #20426). - with captured_stdout() as out: - re.compile(pat, re.DEBUG) - self.assertEqual(out.getvalue(), dump) - def test_keyword_parameters(self): # Issue #20283: Accepting the string keyword parameter. pat = re.compile(r'(ab)') @@ -1892,6 +1954,10 @@ ELSE # with ignore case. self.assertEqual(re.fullmatch('[a-c]+', 'ABC', re.I).span(), (0, 3)) + @unittest.skipIf( + is_emscripten or is_wasi, + "musl libc issue on Emscripten/WASI, bpo-46390" + ) def test_locale_caching(self): # Issue #22410 oldlocale = locale.setlocale(locale.LC_CTYPE) @@ -1928,6 +1994,10 @@ ELSE self.assertIsNone(re.match(b'(?Li)\xc5', b'\xe5')) self.assertIsNone(re.match(b'(?Li)\xe5', b'\xc5')) + @unittest.skipIf( + is_emscripten or is_wasi, + "musl libc issue on Emscripten/WASI, bpo-46390" + ) def test_locale_compiled(self): oldlocale = locale.setlocale(locale.LC_CTYPE) self.addCleanup(locale.setlocale, locale.LC_CTYPE, oldlocale) @@ -2105,12 +2175,371 @@ ELSE {'tag': 'foo', 'text': None}, {'tag': 'foo', 'text': None}]) + def test_MARK_PUSH_macro_bug(self): + # issue35859, MARK_PUSH() macro didn't protect MARK-0 if it + # was the only available mark. + self.assertEqual(re.match(r'(ab|a)*?b', 'ab').groups(), ('a',)) + self.assertEqual(re.match(r'(ab|a)+?b', 'ab').groups(), ('a',)) + self.assertEqual(re.match(r'(ab|a){0,2}?b', 'ab').groups(), ('a',)) + self.assertEqual(re.match(r'(.b|a)*?b', 'ab').groups(), ('a',)) + + def test_MIN_UNTIL_mark_bug(self): + # Fixed in issue35859, reported in issue9134. + # JUMP_MIN_UNTIL_2 should MARK_PUSH() if in a repeat + s = 'axxzbcz' + p = r'(?:(?:a|bc)*?(xx)??z)*' + self.assertEqual(re.match(p, s).groups(), ('xx',)) + + # test-case provided by issue9134 + s = 'xtcxyzxc' + p = r'((x|yz)+?(t)??c)*' + m = re.match(p, s) + self.assertEqual(m.span(), (0, 8)) + self.assertEqual(m.span(2), (6, 7)) + self.assertEqual(m.groups(), ('xyzxc', 'x', 't')) + + def test_REPEAT_ONE_mark_bug(self): + # issue35859 + # JUMP_REPEAT_ONE_1 should MARK_PUSH() if in a repeat + s = 'aabaab' + p = r'(?:[^b]*a(?=(b)|(a))ab)*' + m = re.match(p, s) + self.assertEqual(m.span(), (0, 6)) + self.assertEqual(m.span(2), (4, 5)) + self.assertEqual(m.groups(), (None, 'a')) + + # JUMP_REPEAT_ONE_2 should MARK_PUSH() if in a repeat + s = 'abab' + p = r'(?:[^b]*(?=(b)|(a))ab)*' + m = re.match(p, s) + self.assertEqual(m.span(), (0, 4)) + self.assertEqual(m.span(2), (2, 3)) + self.assertEqual(m.groups(), (None, 'a')) + + self.assertEqual(re.match(r'(ab?)*?b', 'ab').groups(), ('a',)) + + def test_MIN_REPEAT_ONE_mark_bug(self): + # issue35859 + # JUMP_MIN_REPEAT_ONE should MARK_PUSH() if in a repeat + s = 'abab' + p = r'(?:.*?(?=(a)|(b))b)*' + m = re.match(p, s) + self.assertEqual(m.span(), (0, 4)) + self.assertEqual(m.span(2), (3, 4)) + self.assertEqual(m.groups(), (None, 'b')) + + s = 'axxzaz' + p = r'(?:a*?(xx)??z)*' + self.assertEqual(re.match(p, s).groups(), ('xx',)) + + def test_ASSERT_NOT_mark_bug(self): + # Fixed in issue35859, reported in issue725149. + # JUMP_ASSERT_NOT should LASTMARK_SAVE() + self.assertEqual(re.match(r'(?!(..)c)', 'ab').groups(), (None,)) + + # JUMP_ASSERT_NOT should MARK_PUSH() if in a repeat + m = re.match(r'((?!(ab)c)(.))*', 'abab') + self.assertEqual(m.span(), (0, 4)) + self.assertEqual(m.span(1), (3, 4)) + self.assertEqual(m.span(3), (3, 4)) + self.assertEqual(m.groups(), ('b', None, 'b')) + def test_bug_40736(self): with self.assertRaisesRegex(TypeError, "got 'int'"): re.search("x*", 5) with self.assertRaisesRegex(TypeError, "got 'type'"): re.search("x*", type) + def test_search_anchor_at_beginning(self): + s = 'x'*10**7 + start = time.perf_counter() + for p in r'\Ay', r'^y': + self.assertIsNone(re.search(p, s)) + self.assertEqual(re.split(p, s), [s]) + self.assertEqual(re.findall(p, s), []) + self.assertEqual(list(re.finditer(p, s)), []) + self.assertEqual(re.sub(p, '', s), s) + t = time.perf_counter() - start + # Without optimization it takes 1 second on my computer. + # With optimization -- 0.0003 seconds. + self.assertLess(t, 0.1) + + def test_possessive_quantifiers(self): + """Test Possessive Quantifiers + Test quantifiers of the form @+ for some repetition operator @, + e.g. x{3,5}+ meaning match from 3 to 5 greadily and proceed + without creating a stack frame for rolling the stack back and + trying 1 or more fewer matches.""" + self.assertIsNone(re.match('e*+e', 'eeee')) + self.assertEqual(re.match('e++a', 'eeea').group(0), 'eeea') + self.assertEqual(re.match('e?+a', 'ea').group(0), 'ea') + self.assertEqual(re.match('e{2,4}+a', 'eeea').group(0), 'eeea') + self.assertIsNone(re.match('(.)++.', 'ee')) + self.assertEqual(re.match('(ae)*+a', 'aea').groups(), ('ae',)) + self.assertEqual(re.match('([ae][ae])?+a', 'aea').groups(), + ('ae',)) + self.assertEqual(re.match('(e?){2,4}+a', 'eeea').groups(), + ('',)) + self.assertEqual(re.match('()*+a', 'a').groups(), ('',)) + self.assertEqual(re.search('x*+', 'axx').span(), (0, 0)) + self.assertEqual(re.search('x++', 'axx').span(), (1, 3)) + self.assertEqual(re.match('a*+', 'xxx').span(), (0, 0)) + self.assertEqual(re.match('x*+', 'xxxa').span(), (0, 3)) + self.assertIsNone(re.match('a++', 'xxx')) + self.assertIsNone(re.match(r"^(\w){1}+$", "abc")) + self.assertIsNone(re.match(r"^(\w){1,2}+$", "abc")) + + self.assertEqual(re.match(r"^(\w){3}+$", "abc").group(1), "c") + self.assertEqual(re.match(r"^(\w){1,3}+$", "abc").group(1), "c") + self.assertEqual(re.match(r"^(\w){1,4}+$", "abc").group(1), "c") + + self.assertIsNone(re.match("^x{1}+$", "xxx")) + self.assertIsNone(re.match("^x{1,2}+$", "xxx")) + + self.assertTrue(re.match("^x{3}+$", "xxx")) + self.assertTrue(re.match("^x{1,3}+$", "xxx")) + self.assertTrue(re.match("^x{1,4}+$", "xxx")) + + self.assertIsNone(re.match("^x{}+$", "xxx")) + self.assertTrue(re.match("^x{}+$", "x{}")) + + def test_fullmatch_possessive_quantifiers(self): + self.assertTrue(re.fullmatch(r'a++', 'a')) + self.assertTrue(re.fullmatch(r'a*+', 'a')) + self.assertTrue(re.fullmatch(r'a?+', 'a')) + self.assertTrue(re.fullmatch(r'a{1,3}+', 'a')) + self.assertIsNone(re.fullmatch(r'a++', 'ab')) + self.assertIsNone(re.fullmatch(r'a*+', 'ab')) + self.assertIsNone(re.fullmatch(r'a?+', 'ab')) + self.assertIsNone(re.fullmatch(r'a{1,3}+', 'ab')) + self.assertTrue(re.fullmatch(r'a++b', 'ab')) + self.assertTrue(re.fullmatch(r'a*+b', 'ab')) + self.assertTrue(re.fullmatch(r'a?+b', 'ab')) + self.assertTrue(re.fullmatch(r'a{1,3}+b', 'ab')) + + self.assertTrue(re.fullmatch(r'(?:ab)++', 'ab')) + self.assertTrue(re.fullmatch(r'(?:ab)*+', 'ab')) + self.assertTrue(re.fullmatch(r'(?:ab)?+', 'ab')) + self.assertTrue(re.fullmatch(r'(?:ab){1,3}+', 'ab')) + self.assertIsNone(re.fullmatch(r'(?:ab)++', 'abc')) + self.assertIsNone(re.fullmatch(r'(?:ab)*+', 'abc')) + self.assertIsNone(re.fullmatch(r'(?:ab)?+', 'abc')) + self.assertIsNone(re.fullmatch(r'(?:ab){1,3}+', 'abc')) + self.assertTrue(re.fullmatch(r'(?:ab)++c', 'abc')) + self.assertTrue(re.fullmatch(r'(?:ab)*+c', 'abc')) + self.assertTrue(re.fullmatch(r'(?:ab)?+c', 'abc')) + self.assertTrue(re.fullmatch(r'(?:ab){1,3}+c', 'abc')) + + def test_findall_possessive_quantifiers(self): + self.assertEqual(re.findall(r'a++', 'aab'), ['aa']) + self.assertEqual(re.findall(r'a*+', 'aab'), ['aa', '', '']) + self.assertEqual(re.findall(r'a?+', 'aab'), ['a', 'a', '', '']) + self.assertEqual(re.findall(r'a{1,3}+', 'aab'), ['aa']) + + self.assertEqual(re.findall(r'(?:ab)++', 'ababc'), ['abab']) + self.assertEqual(re.findall(r'(?:ab)*+', 'ababc'), ['abab', '', '']) + self.assertEqual(re.findall(r'(?:ab)?+', 'ababc'), ['ab', 'ab', '', '']) + self.assertEqual(re.findall(r'(?:ab){1,3}+', 'ababc'), ['abab']) + + def test_atomic_grouping(self): + """Test Atomic Grouping + Test non-capturing groups of the form (?>...), which does + not maintain any stack point created within the group once the + group is finished being evaluated.""" + pattern1 = re.compile(r'a(?>bc|b)c') + self.assertIsNone(pattern1.match('abc')) + self.assertTrue(pattern1.match('abcc')) + self.assertIsNone(re.match(r'(?>.*).', 'abc')) + self.assertTrue(re.match(r'(?>x)++', 'xxx')) + self.assertTrue(re.match(r'(?>x++)', 'xxx')) + self.assertIsNone(re.match(r'(?>x)++x', 'xxx')) + self.assertIsNone(re.match(r'(?>x++)x', 'xxx')) + + def test_fullmatch_atomic_grouping(self): + self.assertTrue(re.fullmatch(r'(?>a+)', 'a')) + self.assertTrue(re.fullmatch(r'(?>a*)', 'a')) + self.assertTrue(re.fullmatch(r'(?>a?)', 'a')) + self.assertTrue(re.fullmatch(r'(?>a{1,3})', 'a')) + self.assertIsNone(re.fullmatch(r'(?>a+)', 'ab')) + self.assertIsNone(re.fullmatch(r'(?>a*)', 'ab')) + self.assertIsNone(re.fullmatch(r'(?>a?)', 'ab')) + self.assertIsNone(re.fullmatch(r'(?>a{1,3})', 'ab')) + self.assertTrue(re.fullmatch(r'(?>a+)b', 'ab')) + self.assertTrue(re.fullmatch(r'(?>a*)b', 'ab')) + self.assertTrue(re.fullmatch(r'(?>a?)b', 'ab')) + self.assertTrue(re.fullmatch(r'(?>a{1,3})b', 'ab')) + + self.assertTrue(re.fullmatch(r'(?>(?:ab)+)', 'ab')) + self.assertTrue(re.fullmatch(r'(?>(?:ab)*)', 'ab')) + self.assertTrue(re.fullmatch(r'(?>(?:ab)?)', 'ab')) + self.assertTrue(re.fullmatch(r'(?>(?:ab){1,3})', 'ab')) + self.assertIsNone(re.fullmatch(r'(?>(?:ab)+)', 'abc')) + self.assertIsNone(re.fullmatch(r'(?>(?:ab)*)', 'abc')) + self.assertIsNone(re.fullmatch(r'(?>(?:ab)?)', 'abc')) + self.assertIsNone(re.fullmatch(r'(?>(?:ab){1,3})', 'abc')) + self.assertTrue(re.fullmatch(r'(?>(?:ab)+)c', 'abc')) + self.assertTrue(re.fullmatch(r'(?>(?:ab)*)c', 'abc')) + self.assertTrue(re.fullmatch(r'(?>(?:ab)?)c', 'abc')) + self.assertTrue(re.fullmatch(r'(?>(?:ab){1,3})c', 'abc')) + + def test_findall_atomic_grouping(self): + self.assertEqual(re.findall(r'(?>a+)', 'aab'), ['aa']) + self.assertEqual(re.findall(r'(?>a*)', 'aab'), ['aa', '', '']) + self.assertEqual(re.findall(r'(?>a?)', 'aab'), ['a', 'a', '', '']) + self.assertEqual(re.findall(r'(?>a{1,3})', 'aab'), ['aa']) + + self.assertEqual(re.findall(r'(?>(?:ab)+)', 'ababc'), ['abab']) + self.assertEqual(re.findall(r'(?>(?:ab)*)', 'ababc'), ['abab', '', '']) + self.assertEqual(re.findall(r'(?>(?:ab)?)', 'ababc'), ['ab', 'ab', '', '']) + self.assertEqual(re.findall(r'(?>(?:ab){1,3})', 'ababc'), ['abab']) + + def test_bug_gh91616(self): + self.assertTrue(re.fullmatch(r'(?s:(?>.*?\.).*)\Z', "a.txt")) # reproducer + self.assertTrue(re.fullmatch(r'(?s:(?=(?P.*?\.))(?P=g0).*)\Z', "a.txt")) + + def test_template_function_and_flag_is_deprecated(self): + with self.assertWarns(DeprecationWarning) as cm: + template_re1 = re.template(r'a') + self.assertIn('re.template()', str(cm.warning)) + self.assertIn('is deprecated', str(cm.warning)) + self.assertIn('function', str(cm.warning)) + self.assertNotIn('flag', str(cm.warning)) + + with self.assertWarns(DeprecationWarning) as cm: + # we deliberately use more flags here to test that that still + # triggers the warning + # if paranoid, we could test multiple different combinations, + # but it's probably not worth it + template_re2 = re.compile(r'a', flags=re.TEMPLATE|re.UNICODE) + self.assertIn('re.TEMPLATE', str(cm.warning)) + self.assertIn('is deprecated', str(cm.warning)) + self.assertIn('flag', str(cm.warning)) + self.assertNotIn('function', str(cm.warning)) + + # while deprecated, is should still function + self.assertEqual(template_re1, template_re2) + self.assertTrue(template_re1.match('ahoy')) + self.assertFalse(template_re1.match('nope')) + + @unittest.skipIf(multiprocessing is None, 'test requires multiprocessing') + def test_regression_gh94675(self): + pattern = re.compile(r'(?<=[({}])(((//[^\n]*)?[\n])([\000-\040])*)*' + r'((/[^/\[\n]*(([^\n]|(\[\n]*(]*)*\]))' + r'[^/\[]*)*/))((((//[^\n]*)?[\n])' + r'([\000-\040]|(/\*[^*]*\*+' + r'([^/*]\*+)*/))*)+(?=[^\000-\040);\]}]))') + input_js = '''a(function() { + /////////////////////////////////////////////////////////////////// + });''' + p = multiprocessing.Process(target=pattern.sub, args=('', input_js)) + p.start() + p.join(SHORT_TIMEOUT) + try: + self.assertFalse(p.is_alive(), 'pattern.sub() timed out') + finally: + if p.is_alive(): + p.terminate() + p.join() + + +def get_debug_out(pat): + with captured_stdout() as out: + re.compile(pat, re.DEBUG) + return out.getvalue() + + +@cpython_only +class DebugTests(unittest.TestCase): + maxDiff = None + + def test_debug_flag(self): + pat = r'(\.)(?:[ch]|py)(?(1)$|: )' + dump = '''\ +SUBPATTERN 1 0 0 + LITERAL 46 +BRANCH + IN + LITERAL 99 + LITERAL 104 +OR + LITERAL 112 + LITERAL 121 +GROUPREF_EXISTS 1 + AT AT_END +ELSE + LITERAL 58 + LITERAL 32 + + 0. INFO 8 0b1 2 5 (to 9) + prefix_skip 0 + prefix [0x2e] ('.') + overlap [0] + 9: MARK 0 +11. LITERAL 0x2e ('.') +13. MARK 1 +15. BRANCH 10 (to 26) +17. IN 6 (to 24) +19. LITERAL 0x63 ('c') +21. LITERAL 0x68 ('h') +23. FAILURE +24: JUMP 9 (to 34) +26: branch 7 (to 33) +27. LITERAL 0x70 ('p') +29. LITERAL 0x79 ('y') +31. JUMP 2 (to 34) +33: FAILURE +34: GROUPREF_EXISTS 0 6 (to 41) +37. AT END +39. JUMP 5 (to 45) +41: LITERAL 0x3a (':') +43. LITERAL 0x20 (' ') +45: SUCCESS +''' + self.assertEqual(get_debug_out(pat), dump) + # Debug output is output again even a second time (bypassing + # the cache -- issue #20426). + self.assertEqual(get_debug_out(pat), dump) + + def test_atomic_group(self): + self.assertEqual(get_debug_out(r'(?>ab?)'), '''\ +ATOMIC_GROUP [(LITERAL, 97), (MAX_REPEAT, (0, 1, [(LITERAL, 98)]))] + + 0. INFO 4 0b0 1 2 (to 5) + 5: ATOMIC_GROUP 11 (to 17) + 7. LITERAL 0x61 ('a') + 9. REPEAT_ONE 6 0 1 (to 16) +13. LITERAL 0x62 ('b') +15. SUCCESS +16: SUCCESS +17: SUCCESS +''') + + def test_possesive_repeat_one(self): + self.assertEqual(get_debug_out(r'a?+'), '''\ +POSSESSIVE_REPEAT 0 1 + LITERAL 97 + + 0. INFO 4 0b0 0 1 (to 5) + 5: POSSESSIVE_REPEAT_ONE 6 0 1 (to 12) + 9. LITERAL 0x61 ('a') +11. SUCCESS +12: SUCCESS +''') + + def test_possesive_repeat(self): + self.assertEqual(get_debug_out(r'(?:ab)?+'), '''\ +POSSESSIVE_REPEAT 0 1 + LITERAL 97 + LITERAL 98 + + 0. INFO 4 0b0 0 2 (to 5) + 5: POSSESSIVE_REPEAT 7 0 1 (to 13) + 9. LITERAL 0x61 ('a') +11. LITERAL 0x62 ('b') +13: SUCCESS +14. SUCCESS +''') + class PatternReprTests(unittest.TestCase): def check(self, pattern, expected): @@ -2210,7 +2639,7 @@ class ImplementationTest(unittest.TestCase): tp.foo = 1 def test_overlap_table(self): - f = sre_compile._generate_overlap_table + f = re._compiler._generate_overlap_table self.assertEqual(f(""), []) self.assertEqual(f("a"), [0]) self.assertEqual(f("abcd"), [0, 0, 0, 0]) @@ -2219,8 +2648,8 @@ class ImplementationTest(unittest.TestCase): self.assertEqual(f("abcabdac"), [0, 0, 0, 1, 2, 0, 1, 0]) def test_signedness(self): - self.assertGreaterEqual(sre_compile.MAXREPEAT, 0) - self.assertGreaterEqual(sre_compile.MAXGROUPS, 0) + self.assertGreaterEqual(re._compiler.MAXREPEAT, 0) + self.assertGreaterEqual(re._compiler.MAXGROUPS, 0) @cpython_only def test_disallow_instantiation(self): @@ -2230,6 +2659,32 @@ class ImplementationTest(unittest.TestCase): pat = re.compile("") check_disallow_instantiation(self, type(pat.scanner(""))) + def test_deprecated_modules(self): + deprecated = { + 'sre_compile': ['compile', 'error', + 'SRE_FLAG_IGNORECASE', 'SUBPATTERN', + '_compile_info'], + 'sre_constants': ['error', 'SRE_FLAG_IGNORECASE', 'SUBPATTERN', + '_NamedIntConstant'], + 'sre_parse': ['SubPattern', 'parse', + 'SRE_FLAG_IGNORECASE', 'SUBPATTERN', + '_parse_sub'], + } + for name in deprecated: + with self.subTest(module=name): + sys.modules.pop(name, None) + with self.assertWarns(DeprecationWarning) as w: + __import__(name) + self.assertEqual(str(w.warning), + f"module {name!r} is deprecated") + self.assertEqual(w.filename, __file__) + self.assertIn(name, sys.modules) + mod = sys.modules[name] + self.assertEqual(mod.__name__, name) + self.assertEqual(mod.__package__, '') + for attr in deprecated[name]: + self.assertTrue(hasattr(mod, attr)) + del sys.modules[name] class ExternalTests(unittest.TestCase): diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 08e2c87e15c..baae4efc2ad 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -15,19 +15,24 @@ import sys import sysconfig import tempfile import textwrap -import time import unittest from test import libregrtest from test import support from test.support import os_helper from test.libregrtest import utils, setup +if not support.has_subprocess_support: + raise unittest.SkipTest("test module requires subprocess") -Py_DEBUG = hasattr(sys, 'gettotalrefcount') ROOT_DIR = os.path.join(os.path.dirname(__file__), '..', '..') ROOT_DIR = os.path.abspath(os.path.normpath(ROOT_DIR)) LOG_PREFIX = r'[0-9]+:[0-9]+:[0-9]+ (?:load avg: [0-9]+\.[0-9]{2} )?' +EXITCODE_BAD_TEST = 2 +EXITCODE_ENV_CHANGED = 3 +EXITCODE_NO_TESTS_RAN = 4 +EXITCODE_INTERRUPTED = 130 + TEST_INTERRUPTED = textwrap.dedent(""" from signal import SIGINT, raise_signal try: @@ -497,7 +502,7 @@ class BaseTestCase(unittest.TestCase): result.append('INTERRUPTED') if not any((good, result, failed, interrupted, skipped, env_changed, fail_env_changed)): - result.append("NO TEST RUN") + result.append("NO TESTS RAN") elif not result: result.append('SUCCESS') result = ', '.join(result) @@ -663,7 +668,7 @@ class ProgramsTestCase(BaseTestCase): test_args.append('-arm32') # 32-bit ARM build elif platform.architecture()[0] == '64bit': test_args.append('-x64') # 64-bit build - if not Py_DEBUG: + if not support.Py_DEBUG: test_args.append('+d') # Release build, use python.exe self.run_batch(script, *test_args, *self.tests) @@ -680,7 +685,7 @@ class ProgramsTestCase(BaseTestCase): rt_args.append('-arm32') # 32-bit ARM build elif platform.architecture()[0] == '64bit': rt_args.append('-x64') # 64-bit build - if Py_DEBUG: + if support.Py_DEBUG: rt_args.append('-d') # Debug build, use python_d.exe self.run_batch(script, *rt_args, *self.regrtest_args, *self.tests) @@ -707,7 +712,7 @@ class ArgsTestCase(BaseTestCase): test_failing = self.create_test('failing', code=code) tests = [test_ok, test_failing] - output = self.run_tests(*tests, exitcode=2) + output = self.run_tests(*tests, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, tests, failed=test_failing) def test_resources(self): @@ -748,13 +753,14 @@ class ArgsTestCase(BaseTestCase): test = self.create_test('random', code) # first run to get the output with the random seed - output = self.run_tests('-r', test) + output = self.run_tests('-r', test, exitcode=EXITCODE_NO_TESTS_RAN) randseed = self.parse_random_seed(output) match = self.regex_search(r'TESTRANDOM: ([0-9]+)', output) test_random = int(match.group(1)) # try to reproduce with the random seed - output = self.run_tests('-r', '--randseed=%s' % randseed, test) + output = self.run_tests('-r', '--randseed=%s' % randseed, test, + exitcode=EXITCODE_NO_TESTS_RAN) randseed2 = self.parse_random_seed(output) self.assertEqual(randseed2, randseed) @@ -813,7 +819,7 @@ class ArgsTestCase(BaseTestCase): def test_interrupted(self): code = TEST_INTERRUPTED test = self.create_test('sigint', code=code) - output = self.run_tests(test, exitcode=130) + output = self.run_tests(test, exitcode=EXITCODE_INTERRUPTED) self.check_executed_tests(output, test, omitted=test, interrupted=True) @@ -838,7 +844,7 @@ class ArgsTestCase(BaseTestCase): args = ("--slowest", "-j2", test) else: args = ("--slowest", test) - output = self.run_tests(*args, exitcode=130) + output = self.run_tests(*args, exitcode=EXITCODE_INTERRUPTED) self.check_executed_tests(output, test, omitted=test, interrupted=True) @@ -878,7 +884,7 @@ class ArgsTestCase(BaseTestCase): builtins.__dict__['RUN'] = 1 """) test = self.create_test('forever', code=code) - output = self.run_tests('--forever', test, exitcode=2) + output = self.run_tests('--forever', test, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, [test]*3, failed=test) def check_leak(self, code, what): @@ -887,7 +893,7 @@ class ArgsTestCase(BaseTestCase): filename = 'reflog.txt' self.addCleanup(os_helper.unlink, filename) output = self.run_tests('--huntrleaks', '3:3:', test, - exitcode=2, + exitcode=EXITCODE_BAD_TEST, stderr=subprocess.STDOUT) self.check_executed_tests(output, [test], failed=test) @@ -901,7 +907,7 @@ class ArgsTestCase(BaseTestCase): reflog = fp.read() self.assertIn(line2, reflog) - @unittest.skipUnless(Py_DEBUG, 'need a debug build') + @unittest.skipUnless(support.Py_DEBUG, 'need a debug build') def test_huntrleaks(self): # test --huntrleaks code = textwrap.dedent(""" @@ -915,7 +921,7 @@ class ArgsTestCase(BaseTestCase): """) self.check_leak(code, 'references') - @unittest.skipUnless(Py_DEBUG, 'need a debug build') + @unittest.skipUnless(support.Py_DEBUG, 'need a debug build') def test_huntrleaks_fd_leak(self): # test --huntrleaks for file descriptor leak code = textwrap.dedent(""" @@ -969,7 +975,7 @@ class ArgsTestCase(BaseTestCase): crash_test = self.create_test(name="crash", code=code) tests = [crash_test] - output = self.run_tests("-j2", *tests, exitcode=2) + output = self.run_tests("-j2", *tests, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, tests, failed=crash_test, randomize=True) @@ -1069,7 +1075,8 @@ class ArgsTestCase(BaseTestCase): self.check_executed_tests(output, [testname], env_changed=testname) # fail with --fail-env-changed - output = self.run_tests("--fail-env-changed", testname, exitcode=3) + output = self.run_tests("--fail-env-changed", testname, + exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=testname, fail_env_changed=True) @@ -1088,7 +1095,7 @@ class ArgsTestCase(BaseTestCase): """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=2) + output = self.run_tests("-w", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, [testname], failed=testname, rerun={testname: "test_fail_always"}) @@ -1123,7 +1130,8 @@ class ArgsTestCase(BaseTestCase): """) testname = self.create_test(code=code) - output = self.run_tests(testname, "-m", "nosuchtest", exitcode=0) + output = self.run_tests(testname, "-m", "nosuchtest", + exitcode=EXITCODE_NO_TESTS_RAN) self.check_executed_tests(output, [testname], no_test_ran=testname) def test_no_tests_ran_skip(self): @@ -1136,7 +1144,7 @@ class ArgsTestCase(BaseTestCase): """) testname = self.create_test(code=code) - output = self.run_tests(testname, exitcode=0) + output = self.run_tests(testname) self.check_executed_tests(output, [testname]) def test_no_tests_ran_multiple_tests_nonexistent(self): @@ -1150,7 +1158,8 @@ class ArgsTestCase(BaseTestCase): testname = self.create_test(code=code) testname2 = self.create_test(code=code) - output = self.run_tests(testname, testname2, "-m", "nosuchtest", exitcode=0) + output = self.run_tests(testname, testname2, "-m", "nosuchtest", + exitcode=EXITCODE_NO_TESTS_RAN) self.check_executed_tests(output, [testname, testname2], no_test_ran=[testname, testname2]) @@ -1198,7 +1207,8 @@ class ArgsTestCase(BaseTestCase): """) testname = self.create_test(code=code) - output = self.run_tests("--fail-env-changed", testname, exitcode=3) + output = self.run_tests("--fail-env-changed", testname, + exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], fail_env_changed=True) @@ -1224,7 +1234,8 @@ class ArgsTestCase(BaseTestCase): """) testname = self.create_test(code=code) - output = self.run_tests("-j2", "--timeout=1.0", testname, exitcode=2) + output = self.run_tests("-j2", "--timeout=1.0", testname, + exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, [testname], failed=testname) self.assertRegex(output, @@ -1256,7 +1267,8 @@ class ArgsTestCase(BaseTestCase): """) testname = self.create_test(code=code) - output = self.run_tests("--fail-env-changed", "-v", testname, exitcode=3) + output = self.run_tests("--fail-env-changed", "-v", testname, + exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], fail_env_changed=True) @@ -1287,7 +1299,8 @@ class ArgsTestCase(BaseTestCase): """) testname = self.create_test(code=code) - output = self.run_tests("--fail-env-changed", "-v", testname, exitcode=3) + output = self.run_tests("--fail-env-changed", "-v", testname, + exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], fail_env_changed=True) @@ -1328,7 +1341,7 @@ class ArgsTestCase(BaseTestCase): for option in ("-v", "-W"): with self.subTest(option=option): cmd = ["--fail-env-changed", option, testname] - output = self.run_tests(*cmd, exitcode=3) + output = self.run_tests(*cmd, exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], fail_env_changed=True) @@ -1337,7 +1350,7 @@ class ArgsTestCase(BaseTestCase): def test_unicode_guard_env(self): guard = os.environ.get(setup.UNICODE_GUARD_ENV) self.assertIsNotNone(guard, f"{setup.UNICODE_GUARD_ENV} not set") - if guard != "\N{SMILING FACE WITH SUNGLASSES}": + if guard.isascii(): # Skip to signify that the env var value was changed by the user; # possibly to something ASCII to work around Unicode issues. self.skipTest("Modified guard") @@ -1357,6 +1370,33 @@ class ArgsTestCase(BaseTestCase): for name in names: self.assertFalse(os.path.exists(name), name) + @unittest.skipIf(support.is_wasi, + 'checking temp files is not implemented on WASI') + def test_leak_tmp_file(self): + code = textwrap.dedent(r""" + import os.path + import tempfile + import unittest + + class FileTests(unittest.TestCase): + def test_leak_tmp_file(self): + filename = os.path.join(tempfile.gettempdir(), 'mytmpfile') + with open(filename, "wb") as fp: + fp.write(b'content') + """) + testnames = [self.create_test(code=code) for _ in range(3)] + + output = self.run_tests("--fail-env-changed", "-v", "-j2", *testnames, + exitcode=EXITCODE_ENV_CHANGED) + self.check_executed_tests(output, testnames, + env_changed=testnames, + fail_env_changed=True, + randomize=True) + for testname in testnames: + self.assertIn(f"Warning -- {testname} leaked temporary " + f"files (1): mytmpfile", + output) + class TestUtils(unittest.TestCase): def test_format_duration(self): diff --git a/Lib/test/test_repl.py b/Lib/test/test_repl.py index 03bf8d8b548..ddb4aa68048 100644 --- a/Lib/test/test_repl.py +++ b/Lib/test/test_repl.py @@ -5,9 +5,14 @@ import os import unittest import subprocess from textwrap import dedent -from test.support import cpython_only, SuppressCrashReport +from test.support import cpython_only, has_subprocess_support, SuppressCrashReport from test.support.script_helper import kill_python + +if not has_subprocess_support: + raise unittest.SkipTest("test module requires subprocess") + + def spawn_repl(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw): """Run the Python REPL with the given arguments. @@ -36,6 +41,21 @@ def spawn_repl(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw): stdout=stdout, stderr=stderr, **kw) +def run_on_interactive_mode(source): + """Spawn a new Python interpreter, pass the given + input source code from the stdin and return the + result back. If the interpreter exits non-zero, it + raises a ValueError.""" + + process = spawn_repl() + process.stdin.write(source) + output = kill_python(process) + + if process.returncode != 0: + raise ValueError("Process didn't exit properly.") + return output + + class TestInteractiveInterpreter(unittest.TestCase): @cpython_only @@ -108,5 +128,23 @@ class TestInteractiveInterpreter(unittest.TestCase): self.assertIn('before close', output) +class TestInteractiveModeSyntaxErrors(unittest.TestCase): + + def test_interactive_syntax_error_correct_line(self): + output = run_on_interactive_mode(dedent("""\ + def f(): + print(0) + return yield 42 + """)) + + traceback_lines = output.splitlines()[-4:-1] + expected_lines = [ + ' return yield 42', + ' ^^^^^', + 'SyntaxError: invalid syntax' + ] + self.assertEqual(traceback_lines, expected_lines) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_reprlib.py b/Lib/test/test_reprlib.py index aa326399ab2..e7216d42720 100644 --- a/Lib/test/test_reprlib.py +++ b/Lib/test/test_reprlib.py @@ -9,6 +9,7 @@ import shutil import importlib import importlib.util import unittest +import textwrap from test.support import verbose from test.support.os_helper import create_empty_file @@ -25,6 +26,29 @@ def nestedTuple(nesting): class ReprTests(unittest.TestCase): + def test_init_kwargs(self): + example_kwargs = { + "maxlevel": 101, + "maxtuple": 102, + "maxlist": 103, + "maxarray": 104, + "maxdict": 105, + "maxset": 106, + "maxfrozenset": 107, + "maxdeque": 108, + "maxstring": 109, + "maxlong": 110, + "maxother": 111, + "fillvalue": "x" * 112, + "indent": "x" * 113, + } + r1 = Repr() + for attr, val in example_kwargs.items(): + setattr(r1, attr, val) + r2 = Repr(**example_kwargs) + for attr in example_kwargs: + self.assertEqual(getattr(r1, attr), getattr(r2, attr), msg=attr) + def test_string(self): eq = self.assertEqual eq(r("abc"), "'abc'") @@ -224,6 +248,338 @@ class ReprTests(unittest.TestCase): r(y) r(z) + def test_valid_indent(self): + test_cases = [ + { + 'object': (), + 'tests': ( + (dict(indent=None), '()'), + (dict(indent=False), '()'), + (dict(indent=True), '()'), + (dict(indent=0), '()'), + (dict(indent=1), '()'), + (dict(indent=4), '()'), + (dict(indent=4, maxlevel=2), '()'), + (dict(indent=''), '()'), + (dict(indent='-->'), '()'), + (dict(indent='....'), '()'), + ), + }, + { + 'object': '', + 'tests': ( + (dict(indent=None), "''"), + (dict(indent=False), "''"), + (dict(indent=True), "''"), + (dict(indent=0), "''"), + (dict(indent=1), "''"), + (dict(indent=4), "''"), + (dict(indent=4, maxlevel=2), "''"), + (dict(indent=''), "''"), + (dict(indent='-->'), "''"), + (dict(indent='....'), "''"), + ), + }, + { + 'object': [1, 'spam', {'eggs': True, 'ham': []}], + 'tests': ( + (dict(indent=None), '''\ + [1, 'spam', {'eggs': True, 'ham': []}]'''), + (dict(indent=False), '''\ + [ + 1, + 'spam', + { + 'eggs': True, + 'ham': [], + }, + ]'''), + (dict(indent=True), '''\ + [ + 1, + 'spam', + { + 'eggs': True, + 'ham': [], + }, + ]'''), + (dict(indent=0), '''\ + [ + 1, + 'spam', + { + 'eggs': True, + 'ham': [], + }, + ]'''), + (dict(indent=1), '''\ + [ + 1, + 'spam', + { + 'eggs': True, + 'ham': [], + }, + ]'''), + (dict(indent=4), '''\ + [ + 1, + 'spam', + { + 'eggs': True, + 'ham': [], + }, + ]'''), + (dict(indent=4, maxlevel=2), '''\ + [ + 1, + 'spam', + { + 'eggs': True, + 'ham': [], + }, + ]'''), + (dict(indent=''), '''\ + [ + 1, + 'spam', + { + 'eggs': True, + 'ham': [], + }, + ]'''), + (dict(indent='-->'), '''\ + [ + -->1, + -->'spam', + -->{ + -->-->'eggs': True, + -->-->'ham': [], + -->}, + ]'''), + (dict(indent='....'), '''\ + [ + ....1, + ....'spam', + ....{ + ........'eggs': True, + ........'ham': [], + ....}, + ]'''), + ), + }, + { + 'object': { + 1: 'two', + b'three': [ + (4.5, 6.7), + [set((8, 9)), frozenset((10, 11))], + ], + }, + 'tests': ( + (dict(indent=None), '''\ + {1: 'two', b'three': [(4.5, 6.7), [{8, 9}, frozenset({10, 11})]]}'''), + (dict(indent=False), '''\ + { + 1: 'two', + b'three': [ + ( + 4.5, + 6.7, + ), + [ + { + 8, + 9, + }, + frozenset({ + 10, + 11, + }), + ], + ], + }'''), + (dict(indent=True), '''\ + { + 1: 'two', + b'three': [ + ( + 4.5, + 6.7, + ), + [ + { + 8, + 9, + }, + frozenset({ + 10, + 11, + }), + ], + ], + }'''), + (dict(indent=0), '''\ + { + 1: 'two', + b'three': [ + ( + 4.5, + 6.7, + ), + [ + { + 8, + 9, + }, + frozenset({ + 10, + 11, + }), + ], + ], + }'''), + (dict(indent=1), '''\ + { + 1: 'two', + b'three': [ + ( + 4.5, + 6.7, + ), + [ + { + 8, + 9, + }, + frozenset({ + 10, + 11, + }), + ], + ], + }'''), + (dict(indent=4), '''\ + { + 1: 'two', + b'three': [ + ( + 4.5, + 6.7, + ), + [ + { + 8, + 9, + }, + frozenset({ + 10, + 11, + }), + ], + ], + }'''), + (dict(indent=4, maxlevel=2), '''\ + { + 1: 'two', + b'three': [ + (...), + [...], + ], + }'''), + (dict(indent=''), '''\ + { + 1: 'two', + b'three': [ + ( + 4.5, + 6.7, + ), + [ + { + 8, + 9, + }, + frozenset({ + 10, + 11, + }), + ], + ], + }'''), + (dict(indent='-->'), '''\ + { + -->1: 'two', + -->b'three': [ + -->-->( + -->-->-->4.5, + -->-->-->6.7, + -->-->), + -->-->[ + -->-->-->{ + -->-->-->-->8, + -->-->-->-->9, + -->-->-->}, + -->-->-->frozenset({ + -->-->-->-->10, + -->-->-->-->11, + -->-->-->}), + -->-->], + -->], + }'''), + (dict(indent='....'), '''\ + { + ....1: 'two', + ....b'three': [ + ........( + ............4.5, + ............6.7, + ........), + ........[ + ............{ + ................8, + ................9, + ............}, + ............frozenset({ + ................10, + ................11, + ............}), + ........], + ....], + }'''), + ), + }, + ] + for test_case in test_cases: + with self.subTest(test_object=test_case['object']): + for repr_settings, expected_repr in test_case['tests']: + with self.subTest(repr_settings=repr_settings): + r = Repr() + for attribute, value in repr_settings.items(): + setattr(r, attribute, value) + resulting_repr = r.repr(test_case['object']) + expected_repr = textwrap.dedent(expected_repr) + self.assertEqual(resulting_repr, expected_repr) + + def test_invalid_indent(self): + test_object = [1, 'spam', {'eggs': True, 'ham': []}] + test_cases = [ + (-1, (ValueError, '[Nn]egative|[Pp]ositive')), + (-4, (ValueError, '[Nn]egative|[Pp]ositive')), + ((), (TypeError, None)), + ([], (TypeError, None)), + ((4,), (TypeError, None)), + ([4,], (TypeError, None)), + (object(), (TypeError, None)), + ] + for indent, (expected_error, expected_msg) in test_cases: + with self.subTest(indent=indent): + r = Repr() + r.indent = indent + expected_msg = expected_msg or f'{type(indent)}' + with self.assertRaisesRegex(expected_error, expected_msg): + r.repr(test_object) + def write_file(path, text): with open(path, 'w', encoding='ASCII') as fp: fp.write(text) diff --git a/Lib/test/test_resource.py b/Lib/test/test_resource.py index f2642c6ba18..317e7ca8f8c 100644 --- a/Lib/test/test_resource.py +++ b/Lib/test/test_resource.py @@ -98,6 +98,7 @@ class ResourceTest(unittest.TestCase): except (OverflowError, ValueError): pass + @unittest.skipUnless(hasattr(resource, "getrusage"), "needs getrusage") def test_getrusage(self): self.assertRaises(TypeError, resource.getrusage) self.assertRaises(TypeError, resource.getrusage, 42, 42) diff --git a/Lib/test/test_rlcompleter.py b/Lib/test/test_rlcompleter.py index 1f7a6ed3f63..6b5fc9a0247 100644 --- a/Lib/test/test_rlcompleter.py +++ b/Lib/test/test_rlcompleter.py @@ -138,6 +138,9 @@ class TestRlcompleter(unittest.TestCase): self.assertEqual(completer.complete('el', 0), 'elif ') self.assertEqual(completer.complete('el', 1), 'else') self.assertEqual(completer.complete('tr', 0), 'try:') + self.assertEqual(completer.complete('_', 0), '_') + self.assertEqual(completer.complete('match', 0), 'match ') + self.assertEqual(completer.complete('case', 0), 'case ') def test_duplicate_globals(self): namespace = { diff --git a/Lib/test/test_robotparser.py b/Lib/test/test_robotparser.py index b0bed431d4b..8d89e2a8224 100644 --- a/Lib/test/test_robotparser.py +++ b/Lib/test/test_robotparser.py @@ -308,6 +308,10 @@ class RobotHandler(BaseHTTPRequestHandler): pass +@unittest.skipUnless( + support.has_socket_support, + "Socket server requires working socket." +) class PasswordProtectedSiteTestCase(unittest.TestCase): def setUp(self): @@ -342,6 +346,7 @@ class PasswordProtectedSiteTestCase(unittest.TestCase): self.assertFalse(parser.can_fetch("*", robots_url)) +@support.requires_working_socket() class NetworkTestCase(unittest.TestCase): base_url = 'http://www.pythontest.net/' diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index 2954dfedc7e..6aaa288c14e 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -12,7 +12,7 @@ import tempfile import textwrap import unittest import warnings -from test.support import no_tracing, verbose +from test.support import no_tracing, verbose, requires_subprocess from test.support.import_helper import forget, make_legacy_pyc, unload from test.support.os_helper import create_empty_file, temp_dir from test.support.script_helper import make_script, make_zip_script @@ -740,8 +740,7 @@ class RunPathTestCase(unittest.TestCase, CodeExecutionMixin): "runpy.run_path(%r)\n") % dummy_dir script_name = self._make_test_script(script_dir, mod_name, source) zip_name, fname = make_zip_script(script_dir, 'test_zip', script_name) - msg = "recursion depth exceeded" - self.assertRaisesRegex(RecursionError, msg, run_path, zip_name) + self.assertRaises(RecursionError, run_path, zip_name) def test_encoding(self): with temp_dir() as script_dir: @@ -781,13 +780,16 @@ class TestExit(unittest.TestCase): ) super().run(*args, **kwargs) - def assertSigInt(self, *args, **kwargs): - proc = subprocess.run(*args, **kwargs, text=True, stderr=subprocess.PIPE) - self.assertTrue(proc.stderr.endswith("\nKeyboardInterrupt\n")) + @requires_subprocess() + def assertSigInt(self, cmd, *args, **kwargs): + # Use -E to ignore PYTHONSAFEPATH + cmd = [sys.executable, '-E', *cmd] + proc = subprocess.run(cmd, *args, **kwargs, text=True, stderr=subprocess.PIPE) + self.assertTrue(proc.stderr.endswith("\nKeyboardInterrupt\n"), proc.stderr) self.assertEqual(proc.returncode, self.EXPECTED_CODE) def test_pymain_run_file(self): - self.assertSigInt([sys.executable, self.ham]) + self.assertSigInt([self.ham]) def test_pymain_run_file_runpy_run_module(self): tmp = self.ham.parent @@ -800,7 +802,7 @@ class TestExit(unittest.TestCase): """ ) ) - self.assertSigInt([sys.executable, run_module], cwd=tmp) + self.assertSigInt([run_module], cwd=tmp) def test_pymain_run_file_runpy_run_module_as_main(self): tmp = self.ham.parent @@ -813,23 +815,23 @@ class TestExit(unittest.TestCase): """ ) ) - self.assertSigInt([sys.executable, run_module_as_main], cwd=tmp) + self.assertSigInt([run_module_as_main], cwd=tmp) def test_pymain_run_command_run_module(self): self.assertSigInt( - [sys.executable, "-c", "import runpy; runpy.run_module('ham')"], + ["-c", "import runpy; runpy.run_module('ham')"], cwd=self.ham.parent, ) def test_pymain_run_command(self): - self.assertSigInt([sys.executable, "-c", "import ham"], cwd=self.ham.parent) + self.assertSigInt(["-c", "import ham"], cwd=self.ham.parent) def test_pymain_run_stdin(self): - self.assertSigInt([sys.executable], input="import ham", cwd=self.ham.parent) + self.assertSigInt([], input="import ham", cwd=self.ham.parent) def test_pymain_run_module(self): ham = self.ham - self.assertSigInt([sys.executable, "-m", ham.stem], cwd=ham.parent) + self.assertSigInt(["-m", ham.stem], cwd=ham.parent) if __name__ == "__main__": diff --git a/Lib/test/test_sched.py b/Lib/test/test_sched.py index 7ae7baae85e..eb52ac7983f 100644 --- a/Lib/test/test_sched.py +++ b/Lib/test/test_sched.py @@ -58,6 +58,7 @@ class TestCase(unittest.TestCase): scheduler.run() self.assertEqual(l, [0.01, 0.02, 0.03, 0.04, 0.05]) + @threading_helper.requires_working_threading() def test_enter_concurrent(self): q = queue.Queue() fun = q.put @@ -91,10 +92,23 @@ class TestCase(unittest.TestCase): l = [] fun = lambda x: l.append(x) scheduler = sched.scheduler(time.time, time.sleep) - for priority in [1, 2, 3, 4, 5]: - z = scheduler.enterabs(0.01, priority, fun, (priority,)) - scheduler.run() - self.assertEqual(l, [1, 2, 3, 4, 5]) + + cases = [ + ([1, 2, 3, 4, 5], [1, 2, 3, 4, 5]), + ([5, 4, 3, 2, 1], [1, 2, 3, 4, 5]), + ([2, 5, 3, 1, 4], [1, 2, 3, 4, 5]), + ([1, 2, 3, 2, 1], [1, 1, 2, 2, 3]), + ] + for priorities, expected in cases: + with self.subTest(priorities=priorities, expected=expected): + for priority in priorities: + scheduler.enterabs(0.01, priority, fun, (priority,)) + scheduler.run() + self.assertEqual(l, expected) + + # Cleanup: + self.assertTrue(scheduler.empty()) + l.clear() def test_cancel(self): l = [] @@ -111,6 +125,7 @@ class TestCase(unittest.TestCase): scheduler.run() self.assertEqual(l, [0.02, 0.03, 0.04]) + @threading_helper.requires_working_threading() def test_cancel_concurrent(self): q = queue.Queue() fun = q.put diff --git a/Lib/test/test_script_helper.py b/Lib/test/test_script_helper.py index 4ade2cbc0d4..f7871fd3b77 100644 --- a/Lib/test/test_script_helper.py +++ b/Lib/test/test_script_helper.py @@ -3,7 +3,7 @@ import subprocess import sys import os -from test.support import script_helper +from test.support import script_helper, requires_subprocess import unittest from unittest import mock @@ -69,6 +69,7 @@ class TestScriptHelper(unittest.TestCase): self.assertNotIn('-E', popen_command) +@requires_subprocess() class TestScriptHelperEnvironment(unittest.TestCase): """Code coverage for interpreter_requires_environment().""" diff --git a/Lib/test/test_select.py b/Lib/test/test_select.py index cf32cf2f6a6..a82584d6904 100644 --- a/Lib/test/test_select.py +++ b/Lib/test/test_select.py @@ -1,5 +1,4 @@ import errno -import os import select import subprocess import sys @@ -7,6 +6,8 @@ import textwrap import unittest from test import support +support.requires_working_socket(module=True) + @unittest.skipIf((sys.platform[:3]=='win'), "can't easily test on this system") class SelectTestCase(unittest.TestCase): @@ -46,7 +47,7 @@ class SelectTestCase(unittest.TestCase): self.assertIsNot(r, x) self.assertIsNot(w, x) - @unittest.skipUnless(hasattr(os, 'popen'), "need os.popen()") + @support.requires_fork() def test_select(self): code = textwrap.dedent(''' import time @@ -78,6 +79,9 @@ class SelectTestCase(unittest.TestCase): rfd, wfd, xfd) # Issue 16230: Crash on select resized list + @unittest.skipIf( + support.is_emscripten, "Emscripten cannot select a fd multiple times." + ) def test_select_mutated(self): a = [] class F: diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py index fe6b725a4bd..c2db88c2039 100644 --- a/Lib/test/test_selectors.py +++ b/Lib/test/test_selectors.py @@ -19,6 +19,10 @@ except ImportError: resource = None +if support.is_emscripten or support.is_wasi: + raise unittest.SkipTest("Cannot create socketpair on Emscripten/WASI.") + + if hasattr(socket, 'socketpair'): socketpair = socket.socketpair else: diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py index 65fda9e469b..2dd65240f5f 100644 --- a/Lib/test/test_set.py +++ b/Lib/test/test_set.py @@ -227,14 +227,17 @@ class TestJointOps: def test_pickling(self): for i in range(pickle.HIGHEST_PROTOCOL + 1): + if type(self.s) not in (set, frozenset): + self.s.x = ['x'] + self.s.z = ['z'] p = pickle.dumps(self.s, i) dup = pickle.loads(p) self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup)) if type(self.s) not in (set, frozenset): - self.s.x = 10 - p = pickle.dumps(self.s, i) - dup = pickle.loads(p) self.assertEqual(self.s.x, dup.x) + self.assertEqual(self.s.z, dup.z) + self.assertFalse(hasattr(self.s, 'y')) + del self.s.x, self.s.z def test_iterator_pickling(self): for proto in range(pickle.HIGHEST_PROTOCOL + 1): @@ -424,7 +427,7 @@ class TestSet(TestJointOps, unittest.TestCase): self.assertRaises(KeyError, self.s.remove, self.thetype(self.word)) def test_remove_keyerror_unpacking(self): - # bug: www.python.org/sf/1576657 + # https://bugs.python.org/issue1576657 for v1 in ['Q', (1,)]: try: self.s.remove(v1) @@ -667,10 +670,13 @@ class TestSetSubclass(TestSet): self = super().__new__(cls, arg) self.newarg = newarg return self - u = subclass_with_new([1, 2], newarg=3) + u = subclass_with_new([1, 2]) self.assertIs(type(u), subclass_with_new) self.assertEqual(set(u), {1, 2}) - self.assertEqual(u.newarg, 3) + self.assertIsNone(u.newarg) + # disallow kwargs in __new__ only (https://bugs.python.org/issue43413#msg402000) + with self.assertRaises(TypeError): + subclass_with_new([1, 2], newarg=3) class TestFrozenSet(TestJointOps, unittest.TestCase): @@ -805,6 +811,21 @@ class TestFrozenSetSubclass(TestFrozenSet): # All empty frozenset subclass instances should have different ids self.assertEqual(len(set(map(id, efs))), len(efs)) + +class SetSubclassWithSlots(set): + __slots__ = ('x', 'y', '__dict__') + +class TestSetSubclassWithSlots(unittest.TestCase): + thetype = SetSubclassWithSlots + setUp = TestJointOps.setUp + test_pickling = TestJointOps.test_pickling + +class FrozenSetSubclassWithSlots(frozenset): + __slots__ = ('x', 'y', '__dict__') + +class TestFrozenSetSubclassWithSlots(TestSetSubclassWithSlots): + thetype = FrozenSetSubclassWithSlots + # Tests taken from test_sets.py ============================================= empty_set = set() @@ -1001,8 +1022,7 @@ class TestBasicOpsBytes(TestBasicOps, unittest.TestCase): class TestBasicOpsMixedStringBytes(TestBasicOps, unittest.TestCase): def setUp(self): - self._warning_filters = warnings_helper.check_warnings() - self._warning_filters.__enter__() + self.enterContext(warnings_helper.check_warnings()) warnings.simplefilter('ignore', BytesWarning) self.case = "string and bytes set" self.values = ["a", "b", b"a", b"b"] @@ -1010,9 +1030,6 @@ class TestBasicOpsMixedStringBytes(TestBasicOps, unittest.TestCase): self.dup = set(self.values) self.length = 4 - def tearDown(self): - self._warning_filters.__exit__(None, None, None) - def test_repr(self): self.check_repr_against_values() @@ -1812,6 +1829,192 @@ class TestWeirdBugs(unittest.TestCase): s = {0} s.update(other) + +class TestOperationsMutating: + """Regression test for bpo-46615""" + + constructor1 = None + constructor2 = None + + def make_sets_of_bad_objects(self): + class Bad: + def __eq__(self, other): + if not enabled: + return False + if randrange(20) == 0: + set1.clear() + if randrange(20) == 0: + set2.clear() + return bool(randrange(2)) + def __hash__(self): + return randrange(2) + # Don't behave poorly during construction. + enabled = False + set1 = self.constructor1(Bad() for _ in range(randrange(50))) + set2 = self.constructor2(Bad() for _ in range(randrange(50))) + # Now start behaving poorly + enabled = True + return set1, set2 + + def check_set_op_does_not_crash(self, function): + for _ in range(100): + set1, set2 = self.make_sets_of_bad_objects() + try: + function(set1, set2) + except RuntimeError as e: + # Just make sure we don't crash here. + self.assertIn("changed size during iteration", str(e)) + + +class TestBinaryOpsMutating(TestOperationsMutating): + + def test_eq_with_mutation(self): + self.check_set_op_does_not_crash(lambda a, b: a == b) + + def test_ne_with_mutation(self): + self.check_set_op_does_not_crash(lambda a, b: a != b) + + def test_lt_with_mutation(self): + self.check_set_op_does_not_crash(lambda a, b: a < b) + + def test_le_with_mutation(self): + self.check_set_op_does_not_crash(lambda a, b: a <= b) + + def test_gt_with_mutation(self): + self.check_set_op_does_not_crash(lambda a, b: a > b) + + def test_ge_with_mutation(self): + self.check_set_op_does_not_crash(lambda a, b: a >= b) + + def test_and_with_mutation(self): + self.check_set_op_does_not_crash(lambda a, b: a & b) + + def test_or_with_mutation(self): + self.check_set_op_does_not_crash(lambda a, b: a | b) + + def test_sub_with_mutation(self): + self.check_set_op_does_not_crash(lambda a, b: a - b) + + def test_xor_with_mutation(self): + self.check_set_op_does_not_crash(lambda a, b: a ^ b) + + def test_iadd_with_mutation(self): + def f(a, b): + a &= b + self.check_set_op_does_not_crash(f) + + def test_ior_with_mutation(self): + def f(a, b): + a |= b + self.check_set_op_does_not_crash(f) + + def test_isub_with_mutation(self): + def f(a, b): + a -= b + self.check_set_op_does_not_crash(f) + + def test_ixor_with_mutation(self): + def f(a, b): + a ^= b + self.check_set_op_does_not_crash(f) + + def test_iteration_with_mutation(self): + def f1(a, b): + for x in a: + pass + for y in b: + pass + def f2(a, b): + for y in b: + pass + for x in a: + pass + def f3(a, b): + for x, y in zip(a, b): + pass + self.check_set_op_does_not_crash(f1) + self.check_set_op_does_not_crash(f2) + self.check_set_op_does_not_crash(f3) + + +class TestBinaryOpsMutating_Set_Set(TestBinaryOpsMutating, unittest.TestCase): + constructor1 = set + constructor2 = set + +class TestBinaryOpsMutating_Subclass_Subclass(TestBinaryOpsMutating, unittest.TestCase): + constructor1 = SetSubclass + constructor2 = SetSubclass + +class TestBinaryOpsMutating_Set_Subclass(TestBinaryOpsMutating, unittest.TestCase): + constructor1 = set + constructor2 = SetSubclass + +class TestBinaryOpsMutating_Subclass_Set(TestBinaryOpsMutating, unittest.TestCase): + constructor1 = SetSubclass + constructor2 = set + + +class TestMethodsMutating(TestOperationsMutating): + + def test_issubset_with_mutation(self): + self.check_set_op_does_not_crash(set.issubset) + + def test_issuperset_with_mutation(self): + self.check_set_op_does_not_crash(set.issuperset) + + def test_intersection_with_mutation(self): + self.check_set_op_does_not_crash(set.intersection) + + def test_union_with_mutation(self): + self.check_set_op_does_not_crash(set.union) + + def test_difference_with_mutation(self): + self.check_set_op_does_not_crash(set.difference) + + def test_symmetric_difference_with_mutation(self): + self.check_set_op_does_not_crash(set.symmetric_difference) + + def test_isdisjoint_with_mutation(self): + self.check_set_op_does_not_crash(set.isdisjoint) + + def test_difference_update_with_mutation(self): + self.check_set_op_does_not_crash(set.difference_update) + + def test_intersection_update_with_mutation(self): + self.check_set_op_does_not_crash(set.intersection_update) + + def test_symmetric_difference_update_with_mutation(self): + self.check_set_op_does_not_crash(set.symmetric_difference_update) + + def test_update_with_mutation(self): + self.check_set_op_does_not_crash(set.update) + + +class TestMethodsMutating_Set_Set(TestMethodsMutating, unittest.TestCase): + constructor1 = set + constructor2 = set + +class TestMethodsMutating_Subclass_Subclass(TestMethodsMutating, unittest.TestCase): + constructor1 = SetSubclass + constructor2 = SetSubclass + +class TestMethodsMutating_Set_Subclass(TestMethodsMutating, unittest.TestCase): + constructor1 = set + constructor2 = SetSubclass + +class TestMethodsMutating_Subclass_Set(TestMethodsMutating, unittest.TestCase): + constructor1 = SetSubclass + constructor2 = set + +class TestMethodsMutating_Set_Dict(TestMethodsMutating, unittest.TestCase): + constructor1 = set + constructor2 = dict.fromkeys + +class TestMethodsMutating_Set_List(TestMethodsMutating, unittest.TestCase): + constructor1 = set + constructor2 = list + + # Application tests (based on David Eppstein's graph recipes ==================================== def powerset(U): diff --git a/Lib/test/test_shelve.py b/Lib/test/test_shelve.py index b9eb007c827..08c6562f2a2 100644 --- a/Lib/test/test_shelve.py +++ b/Lib/test/test_shelve.py @@ -1,11 +1,9 @@ import unittest import dbm import shelve -import glob import pickle import os -from test import support from test.support import os_helper from collections.abc import MutableMapping from test.test_dbm import dbm_iterator diff --git a/Lib/test/test_shlex.py b/Lib/test/test_shlex.py index 3081a785204..92598dbbd5f 100644 --- a/Lib/test/test_shlex.py +++ b/Lib/test/test_shlex.py @@ -162,9 +162,8 @@ class ShlexTest(unittest.TestCase): tok = lex.get_token() return ret - @mock.patch('sys.stdin', io.StringIO()) - def testSplitNoneDeprecation(self): - with self.assertWarns(DeprecationWarning): + def testSplitNone(self): + with self.assertRaises(ValueError): shlex.split(None) def testSplitPosix(self): diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 7669b94ac35..8fe62216ecd 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -51,6 +51,9 @@ try: except ImportError: _winapi = None +no_chdir = unittest.mock.patch('os.chdir', + side_effect=AssertionError("shouldn't call os.chdir()")) + def _fake_rename(*args, **kwargs): # Pretend the destination path is on a different filesystem. raise OSError(getattr(errno, 'EXDEV', 18), "Invalid cross-device link") @@ -309,8 +312,8 @@ class TestRmTree(BaseTest, unittest.TestCase): @unittest.skipIf(sys.platform[:6] == 'cygwin', "This test can't be run on Cygwin (issue #1071513).") - @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, - "This test can't be run reliably as root (issue #1076467).") + @os_helper.skip_if_dac_override + @os_helper.skip_unless_working_chmod def test_on_error(self): self.errorState = 0 os.mkdir(TESTFN) @@ -405,6 +408,27 @@ class TestRmTree(BaseTest, unittest.TestCase): self.assertFalse(shutil._use_fd_functions) self.assertFalse(shutil.rmtree.avoids_symlink_attacks) + @unittest.skipUnless(shutil._use_fd_functions, "dir_fd is not supported") + def test_rmtree_with_dir_fd(self): + tmp_dir = self.mkdtemp() + victim = 'killme' + fullname = os.path.join(tmp_dir, victim) + dir_fd = os.open(tmp_dir, os.O_RDONLY) + self.addCleanup(os.close, dir_fd) + os.mkdir(fullname) + os.mkdir(os.path.join(fullname, 'subdir')) + write_file(os.path.join(fullname, 'subdir', 'somefile'), 'foo') + self.assertTrue(os.path.exists(fullname)) + shutil.rmtree(victim, dir_fd=dir_fd) + self.assertFalse(os.path.exists(fullname)) + + @unittest.skipIf(shutil._use_fd_functions, "dir_fd is supported") + def test_rmtree_with_dir_fd_unsupported(self): + tmp_dir = self.mkdtemp() + with self.assertRaises(NotImplementedError): + shutil.rmtree(tmp_dir, dir_fd=0) + self.assertTrue(os.path.exists(tmp_dir)) + def test_rmtree_dont_delete_file(self): # When called on a file instead of a directory, don't delete it. handle, path = tempfile.mkstemp(dir=self.mkdtemp()) @@ -728,18 +752,25 @@ class TestCopyTree(BaseTest, unittest.TestCase): @os_helper.skip_unless_symlink def test_copytree_dangling_symlinks(self): - # a dangling symlink raises an error at the end src_dir = self.mkdtemp() + valid_file = os.path.join(src_dir, 'test.txt') + write_file(valid_file, 'abc') + dir_a = os.path.join(src_dir, 'dir_a') + os.mkdir(dir_a) + for d in src_dir, dir_a: + os.symlink('IDONTEXIST', os.path.join(d, 'broken')) + os.symlink(valid_file, os.path.join(d, 'valid')) + + # A dangling symlink should raise an error. dst_dir = os.path.join(self.mkdtemp(), 'destination') - os.symlink('IDONTEXIST', os.path.join(src_dir, 'test.txt')) - os.mkdir(os.path.join(src_dir, 'test_dir')) - write_file((src_dir, 'test_dir', 'test.txt'), '456') self.assertRaises(Error, shutil.copytree, src_dir, dst_dir) - # a dangling symlink is ignored with the proper flag + # Dangling symlinks should be ignored with the proper flag. dst_dir = os.path.join(self.mkdtemp(), 'destination2') shutil.copytree(src_dir, dst_dir, ignore_dangling_symlinks=True) - self.assertNotIn('test.txt', os.listdir(dst_dir)) + for root, dirs, files in os.walk(dst_dir): + self.assertNotIn('broken', files) + self.assertIn('valid', files) # a dangling symlink is copied if symlinks=True dst_dir = os.path.join(self.mkdtemp(), 'destination3') @@ -1008,8 +1039,7 @@ class TestCopy(BaseTest, unittest.TestCase): @os_helper.skip_unless_symlink @os_helper.skip_unless_xattr - @unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() == 0, - 'root privileges required') + @os_helper.skip_unless_dac_override def test_copyxattr_symlinks(self): # On Linux, it's only possible to access non-user xattr for symlinks; # which in turn require root privileges. This test should be expanded @@ -1273,6 +1303,10 @@ class TestCopy(BaseTest, unittest.TestCase): self.assertEqual(read_file(src_file), 'foo') @unittest.skipIf(MACOS or SOLARIS or _winapi, 'On MACOS, Solaris and Windows the errors are not confusing (though different)') + # gh-92670: The test uses a trailing slash to force the OS consider + # the path as a directory, but on AIX the trailing slash has no effect + # and is considered as a file. + @unittest.skipIf(AIX, 'Not valid on AIX, see gh-92670') def test_copyfile_nonexistent_dir(self): # Issue 43219 src_dir = self.mkdtemp() @@ -1316,7 +1350,7 @@ class TestArchives(BaseTest, unittest.TestCase): work_dir = os.path.dirname(tmpdir2) rel_base_name = os.path.join(os.path.basename(tmpdir2), 'archive') - with os_helper.change_cwd(work_dir): + with os_helper.change_cwd(work_dir), no_chdir: base_name = os.path.abspath(rel_base_name) tarball = make_archive(rel_base_name, 'gztar', root_dir, '.') @@ -1330,7 +1364,7 @@ class TestArchives(BaseTest, unittest.TestCase): './file1', './file2', './sub/file3']) # trying an uncompressed one - with os_helper.change_cwd(work_dir): + with os_helper.change_cwd(work_dir), no_chdir: tarball = make_archive(rel_base_name, 'tar', root_dir, '.') self.assertEqual(tarball, base_name + '.tar') self.assertTrue(os.path.isfile(tarball)) @@ -1366,7 +1400,8 @@ class TestArchives(BaseTest, unittest.TestCase): def test_tarfile_vs_tar(self): root_dir, base_dir = self._create_files() base_name = os.path.join(self.mkdtemp(), 'archive') - tarball = make_archive(base_name, 'gztar', root_dir, base_dir) + with no_chdir: + tarball = make_archive(base_name, 'gztar', root_dir, base_dir) # check if the compressed tarball was created self.assertEqual(tarball, base_name + '.tar.gz') @@ -1383,13 +1418,15 @@ class TestArchives(BaseTest, unittest.TestCase): self.assertEqual(self._tarinfo(tarball), self._tarinfo(tarball2)) # trying an uncompressed one - tarball = make_archive(base_name, 'tar', root_dir, base_dir) + with no_chdir: + tarball = make_archive(base_name, 'tar', root_dir, base_dir) self.assertEqual(tarball, base_name + '.tar') self.assertTrue(os.path.isfile(tarball)) # now for a dry_run - tarball = make_archive(base_name, 'tar', root_dir, base_dir, - dry_run=True) + with no_chdir: + tarball = make_archive(base_name, 'tar', root_dir, base_dir, + dry_run=True) self.assertEqual(tarball, base_name + '.tar') self.assertTrue(os.path.isfile(tarball)) @@ -1405,7 +1442,7 @@ class TestArchives(BaseTest, unittest.TestCase): work_dir = os.path.dirname(tmpdir2) rel_base_name = os.path.join(os.path.basename(tmpdir2), 'archive') - with os_helper.change_cwd(work_dir): + with os_helper.change_cwd(work_dir), no_chdir: base_name = os.path.abspath(rel_base_name) res = make_archive(rel_base_name, 'zip', root_dir) @@ -1418,7 +1455,7 @@ class TestArchives(BaseTest, unittest.TestCase): 'dist/file1', 'dist/file2', 'dist/sub/file3', 'outer']) - with os_helper.change_cwd(work_dir): + with os_helper.change_cwd(work_dir), no_chdir: base_name = os.path.abspath(rel_base_name) res = make_archive(rel_base_name, 'zip', root_dir, base_dir) @@ -1436,7 +1473,8 @@ class TestArchives(BaseTest, unittest.TestCase): def test_zipfile_vs_zip(self): root_dir, base_dir = self._create_files() base_name = os.path.join(self.mkdtemp(), 'archive') - archive = make_archive(base_name, 'zip', root_dir, base_dir) + with no_chdir: + archive = make_archive(base_name, 'zip', root_dir, base_dir) # check if ZIP file was created self.assertEqual(archive, base_name + '.zip') @@ -1462,7 +1500,8 @@ class TestArchives(BaseTest, unittest.TestCase): def test_unzip_zipfile(self): root_dir, base_dir = self._create_files() base_name = os.path.join(self.mkdtemp(), 'archive') - archive = make_archive(base_name, 'zip', root_dir, base_dir) + with no_chdir: + archive = make_archive(base_name, 'zip', root_dir, base_dir) # check if ZIP file was created self.assertEqual(archive, base_name + '.zip') @@ -1520,7 +1559,7 @@ class TestArchives(BaseTest, unittest.TestCase): base_name = os.path.join(self.mkdtemp(), 'archive') group = grp.getgrgid(0)[0] owner = pwd.getpwuid(0)[0] - with os_helper.change_cwd(root_dir): + with os_helper.change_cwd(root_dir), no_chdir: archive_name = make_archive(base_name, 'gztar', root_dir, 'dist', owner=owner, group=group) @@ -1536,17 +1575,61 @@ class TestArchives(BaseTest, unittest.TestCase): finally: archive.close() - def test_make_archive_cwd(self): + def test_make_archive_cwd_default(self): current_dir = os.getcwd() - def _breaks(*args, **kw): + def archiver(base_name, base_dir, **kw): + self.assertNotIn('root_dir', kw) + self.assertEqual(base_name, 'basename') + self.assertEqual(os.getcwd(), current_dir) raise RuntimeError() - register_archive_format('xxx', _breaks, [], 'xxx file') + register_archive_format('xxx', archiver, [], 'xxx file') try: - try: - make_archive('xxx', 'xxx', root_dir=self.mkdtemp()) - except Exception: - pass + with no_chdir: + with self.assertRaises(RuntimeError): + make_archive('basename', 'xxx') + self.assertEqual(os.getcwd(), current_dir) + finally: + unregister_archive_format('xxx') + + def test_make_archive_cwd(self): + current_dir = os.getcwd() + root_dir = self.mkdtemp() + def archiver(base_name, base_dir, **kw): + self.assertNotIn('root_dir', kw) + self.assertEqual(base_name, os.path.join(current_dir, 'basename')) + self.assertEqual(os.getcwd(), root_dir) + raise RuntimeError() + dirs = [] + def _chdir(path): + dirs.append(path) + orig_chdir(path) + + register_archive_format('xxx', archiver, [], 'xxx file') + try: + with support.swap_attr(os, 'chdir', _chdir) as orig_chdir: + with self.assertRaises(RuntimeError): + make_archive('basename', 'xxx', root_dir=root_dir) + self.assertEqual(os.getcwd(), current_dir) + self.assertEqual(dirs, [root_dir, current_dir]) + finally: + unregister_archive_format('xxx') + + def test_make_archive_cwd_supports_root_dir(self): + current_dir = os.getcwd() + root_dir = self.mkdtemp() + def archiver(base_name, base_dir, **kw): + self.assertEqual(base_name, 'basename') + self.assertEqual(kw['root_dir'], root_dir) + self.assertEqual(os.getcwd(), current_dir) + raise RuntimeError() + archiver.supports_root_dir = True + + register_archive_format('xxx', archiver, [], 'xxx file') + try: + with no_chdir: + with self.assertRaises(RuntimeError): + make_archive('basename', 'xxx', root_dir=root_dir) self.assertEqual(os.getcwd(), current_dir) finally: unregister_archive_format('xxx') @@ -1554,7 +1637,7 @@ class TestArchives(BaseTest, unittest.TestCase): def test_make_tarfile_in_curdir(self): # Issue #21280 root_dir = self.mkdtemp() - with os_helper.change_cwd(root_dir): + with os_helper.change_cwd(root_dir), no_chdir: self.assertEqual(make_archive('test', 'tar'), 'test.tar') self.assertTrue(os.path.isfile('test.tar')) @@ -1562,7 +1645,7 @@ class TestArchives(BaseTest, unittest.TestCase): def test_make_zipfile_in_curdir(self): # Issue #21280 root_dir = self.mkdtemp() - with os_helper.change_cwd(root_dir): + with os_helper.change_cwd(root_dir), no_chdir: self.assertEqual(make_archive('test', 'zip'), 'test.zip') self.assertTrue(os.path.isfile('test.zip')) @@ -1789,8 +1872,7 @@ class TestWhich(BaseTest, unittest.TestCase): # Other platforms: shouldn't match in the current directory. self.assertIsNone(rv) - @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, - 'non-root user required') + @os_helper.skip_if_dac_override def test_non_matching_mode(self): # Set the file read-only and ask for writeable files. os.chmod(self.temp_file.name, stat.S_IREAD) @@ -2141,11 +2223,11 @@ class TestMove(BaseTest, unittest.TestCase): os.rmdir(dst_dir) - @unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() == 0 - and hasattr(os, 'lchflags') + @os_helper.skip_unless_dac_override + @unittest.skipUnless(hasattr(os, 'lchflags') and hasattr(stat, 'SF_IMMUTABLE') and hasattr(stat, 'UF_OPAQUE'), - 'root privileges required') + 'requires lchflags') def test_move_dir_permission_denied(self): # bpo-42782: shutil.move should not create destination directories # if the source directory cannot be removed. @@ -2627,6 +2709,7 @@ class TestGetTerminalSize(unittest.TestCase): self.assertEqual(expected, actual) + @unittest.skipIf(support.is_wasi, "WASI has no /dev/null") def test_fallback(self): with os_helper.EnvironmentVarGuard() as env: del env['LINES'] diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index daecf196fa1..2562a57ea42 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -1,5 +1,6 @@ import enum import errno +import inspect import os import random import signal @@ -13,6 +14,7 @@ import unittest from test import support from test.support import os_helper from test.support.script_helper import assert_python_ok, spawn_python +from test.support import threading_helper try: import _testcapi except ImportError: @@ -60,6 +62,14 @@ class GenericTests(unittest.TestCase): ) enum._test_simple_enum(CheckedSigmasks, Sigmasks) + def test_functions_module_attr(self): + # Issue #27718: If __all__ is not defined all non-builtin functions + # should have correct __module__ to be displayed by pydoc. + for name in dir(signal): + value = getattr(signal, name) + if inspect.isroutine(value) and not inspect.isbuiltin(value): + self.assertEqual(value.__module__, 'signal') + @unittest.skipIf(sys.platform == "win32", "Not valid on Windows") class PosixTests(unittest.TestCase): @@ -97,6 +107,10 @@ class PosixTests(unittest.TestCase): script = os.path.join(dirname, 'signalinterproctester.py') assert_python_ok(script) + @unittest.skipUnless( + hasattr(signal, "valid_signals"), + "requires signal.valid_signals" + ) def test_valid_signals(self): s = signal.valid_signals() self.assertIsInstance(s, set) @@ -106,7 +120,21 @@ class PosixTests(unittest.TestCase): self.assertNotIn(signal.NSIG, s) self.assertLess(len(s), signal.NSIG) + # gh-91145: Make sure that all SIGxxx constants exposed by the Python + # signal module have a number in the [0; signal.NSIG-1] range. + for name in dir(signal): + if not name.startswith("SIG"): + continue + if name in {"SIG_IGN", "SIG_DFL"}: + # SIG_IGN and SIG_DFL are pointers + continue + with self.subTest(name=name): + signum = getattr(signal, name) + self.assertGreaterEqual(signum, 0) + self.assertLess(signum, signal.NSIG) + @unittest.skipUnless(sys.executable, "sys.executable required.") + @support.requires_subprocess() def test_keyboard_interrupt_exit_code(self): """KeyboardInterrupt triggers exit via SIGINT.""" process = subprocess.run( @@ -157,6 +185,7 @@ class WindowsSignalTests(unittest.TestCase): signal.signal(7, handler) @unittest.skipUnless(sys.executable, "sys.executable required.") + @support.requires_subprocess() def test_keyboard_interrupt_exit_code(self): """KeyboardInterrupt triggers an exit using STATUS_CONTROL_C_EXIT.""" # We don't test via os.kill(os.getpid(), signal.CTRL_C_EVENT) here @@ -187,6 +216,7 @@ class WakeupFDTests(unittest.TestCase): self.assertRaises((ValueError, OSError), signal.set_wakeup_fd, fd) + @unittest.skipUnless(support.has_socket_support, "needs working sockets.") def test_invalid_socket(self): sock = socket.socket() fd = sock.fileno() @@ -194,6 +224,10 @@ class WakeupFDTests(unittest.TestCase): self.assertRaises((ValueError, OSError), signal.set_wakeup_fd, fd) + # Emscripten does not support fstat on pipes yet. + # https://github.com/emscripten-core/emscripten/issues/16414 + @unittest.skipIf(support.is_emscripten, "Emscripten cannot fstat pipes.") + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_set_wakeup_fd_result(self): r1, w1 = os.pipe() self.addCleanup(os.close, r1) @@ -211,6 +245,8 @@ class WakeupFDTests(unittest.TestCase): self.assertEqual(signal.set_wakeup_fd(-1), w2) self.assertEqual(signal.set_wakeup_fd(-1), -1) + @unittest.skipIf(support.is_emscripten, "Emscripten cannot fstat pipes.") + @unittest.skipUnless(support.has_socket_support, "needs working sockets.") def test_set_wakeup_fd_socket_result(self): sock1 = socket.socket() self.addCleanup(sock1.close) @@ -230,6 +266,8 @@ class WakeupFDTests(unittest.TestCase): # On Windows, files are always blocking and Windows does not provide a # function to test if a socket is in non-blocking mode. @unittest.skipIf(sys.platform == "win32", "tests specific to POSIX") + @unittest.skipIf(support.is_emscripten, "Emscripten cannot fstat pipes.") + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_set_wakeup_fd_blocking(self): rfd, wfd = os.pipe() self.addCleanup(os.close, rfd) @@ -290,6 +328,7 @@ class WakeupSignalTests(unittest.TestCase): assert_python_ok('-c', code) @unittest.skipIf(_testcapi is None, 'need _testcapi') + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_wakeup_write_error(self): # Issue #16105: write() errors in the C signal handler should not # pass silently. @@ -628,6 +667,8 @@ class WakeupSocketSignalTests(unittest.TestCase): @unittest.skipIf(sys.platform == "win32", "Not valid on Windows") @unittest.skipUnless(hasattr(signal, 'siginterrupt'), "needs signal.siginterrupt()") +@support.requires_subprocess() +@unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") class SiginterruptTest(unittest.TestCase): def readpipe_interrupted(self, interrupt): @@ -771,15 +812,12 @@ class ItimerTest(unittest.TestCase): signal.signal(signal.SIGVTALRM, self.sig_vtalrm) signal.setitimer(self.itimer, 0.3, 0.2) - start_time = time.monotonic() - while time.monotonic() - start_time < 60.0: + for _ in support.busy_retry(support.LONG_TIMEOUT): # use up some virtual time by doing real work _ = pow(12345, 67890, 10000019) if signal.getitimer(self.itimer) == (0.0, 0.0): - break # sig_vtalrm handler stopped this itimer - else: # Issue 8424 - self.skipTest("timeout: likely cause: machine too slow or load too " - "high") + # sig_vtalrm handler stopped this itimer + break # virtual itimer should be (0.0, 0.0) now self.assertEqual(signal.getitimer(self.itimer), (0.0, 0.0)) @@ -791,15 +829,12 @@ class ItimerTest(unittest.TestCase): signal.signal(signal.SIGPROF, self.sig_prof) signal.setitimer(self.itimer, 0.2, 0.2) - start_time = time.monotonic() - while time.monotonic() - start_time < 60.0: + for _ in support.busy_retry(support.LONG_TIMEOUT): # do some work _ = pow(12345, 67890, 10000019) if signal.getitimer(self.itimer) == (0.0, 0.0): - break # sig_prof handler stopped this itimer - else: # Issue 8424 - self.skipTest("timeout: likely cause: machine too slow or load too " - "high") + # sig_prof handler stopped this itimer + break # profiling itimer should be (0.0, 0.0) now self.assertEqual(signal.getitimer(self.itimer), (0.0, 0.0)) @@ -859,6 +894,7 @@ class PendingSignalsTests(unittest.TestCase): @unittest.skipUnless(hasattr(signal, 'pthread_kill'), 'need signal.pthread_kill()') + @threading_helper.requires_working_threading() def test_pthread_kill(self): code = """if 1: import signal @@ -899,7 +935,7 @@ class PendingSignalsTests(unittest.TestCase): %s - blocked = %r + blocked = %s signum = signal.SIGALRM # child: block and wait the signal @@ -995,6 +1031,7 @@ class PendingSignalsTests(unittest.TestCase): 'need signal.sigwait()') @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), 'need signal.pthread_sigmask()') + @threading_helper.requires_working_threading() def test_sigwait_thread(self): # Check that calling sigwait() from a thread doesn't suspend the whole # process. A new interpreter is spawned to avoid problems when mixing @@ -1050,6 +1087,7 @@ class PendingSignalsTests(unittest.TestCase): @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), 'need signal.pthread_sigmask()') + @threading_helper.requires_working_threading() def test_pthread_sigmask(self): code = """if 1: import signal @@ -1127,6 +1165,7 @@ class PendingSignalsTests(unittest.TestCase): @unittest.skipUnless(hasattr(signal, 'pthread_kill'), 'need signal.pthread_kill()') + @threading_helper.requires_working_threading() def test_pthread_kill_main_thread(self): # Test that a signal can be sent to the main thread with pthread_kill() # before any other thread has been created (see issue #12392). @@ -1262,8 +1301,6 @@ class StressTest(unittest.TestCase): self.setsig(signal.SIGALRM, handler) # for ITIMER_REAL expected_sigs = 0 - deadline = time.monotonic() + support.SHORT_TIMEOUT - while expected_sigs < N: # Hopefully the SIGALRM will be received somewhere during # initial processing of SIGUSR1. @@ -1272,8 +1309,9 @@ class StressTest(unittest.TestCase): expected_sigs += 2 # Wait for handlers to run to avoid signal coalescing - while len(sigs) < expected_sigs and time.monotonic() < deadline: - time.sleep(1e-5) + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if len(sigs) >= expected_sigs: + break # All ITIMER_REAL signals should have been delivered to the # Python handler @@ -1281,6 +1319,7 @@ class StressTest(unittest.TestCase): @unittest.skipUnless(hasattr(signal, "SIGUSR1"), "test needs SIGUSR1") + @threading_helper.requires_working_threading() def test_stress_modifying_handlers(self): # bpo-43406: race condition between trip_signal() and signal.signal signum = signal.SIGUSR1 diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index 5f06a0d4b03..9e701fd847a 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -10,9 +10,9 @@ from test import support from test.support import os_helper from test.support import socket_helper from test.support import captured_stderr -from test.support.os_helper import TESTFN, EnvironmentVarGuard, change_cwd +from test.support.os_helper import TESTFN, EnvironmentVarGuard +import ast import builtins -import encodings import glob import io import os @@ -205,14 +205,15 @@ class HelperFunctionsTests(unittest.TestCase): scheme = 'osx_framework_user' else: scheme = os.name + '_user' - self.assertEqual(site._get_path(site._getuserbase()), + self.assertEqual(os.path.normpath(site._get_path(site._getuserbase())), sysconfig.get_path('purelib', scheme)) @unittest.skipUnless(site.ENABLE_USER_SITE, "requires access to PEP 370 " "user-site (site.ENABLE_USER_SITE)") + @support.requires_subprocess() def test_s_option(self): # (ncoghlan) Change this to use script_helper... - usersite = site.USER_SITE + usersite = os.path.normpath(site.USER_SITE) self.assertIn(usersite, sys.path) env = os.environ.copy() @@ -300,7 +301,8 @@ class HelperFunctionsTests(unittest.TestCase): self.assertEqual(len(dirs), 2) self.assertEqual(dirs[0], 'xoxo') wanted = os.path.join('xoxo', 'lib', 'site-packages') - self.assertEqual(dirs[1], wanted) + self.assertEqual(os.path.normcase(dirs[1]), + os.path.normcase(wanted)) @unittest.skipUnless(HAS_USER_SITE, 'need user site') def test_no_home_directory(self): @@ -453,16 +455,6 @@ class ImportSideEffectTests(unittest.TestCase): # 'help' should be set in builtins self.assertTrue(hasattr(builtins, "help")) - def test_aliasing_mbcs(self): - if sys.platform == "win32": - import locale - if locale.getdefaultlocale()[1].startswith('cp'): - for value in encodings.aliases.aliases.values(): - if value == "mbcs": - break - else: - self.fail("did not alias mbcs") - def test_sitecustomize_executed(self): # If sitecustomize is available, it should have been imported. if "sitecustomize" not in sys.modules: @@ -495,15 +487,17 @@ class ImportSideEffectTests(unittest.TestCase): class StartupImportTests(unittest.TestCase): + @support.requires_subprocess() def test_startup_imports(self): # Get sys.path in isolated mode (python3 -I) - popen = subprocess.Popen([sys.executable, '-I', '-c', - 'import sys; print(repr(sys.path))'], + popen = subprocess.Popen([sys.executable, '-X', 'utf8', '-I', + '-c', 'import sys; print(repr(sys.path))'], stdout=subprocess.PIPE, - encoding='utf-8') + encoding='utf-8', + errors='surrogateescape') stdout = popen.communicate()[0] self.assertEqual(popen.returncode, 0, repr(stdout)) - isolated_paths = eval(stdout) + isolated_paths = ast.literal_eval(stdout) # bpo-27807: Even with -I, the site module executes all .pth files # found in sys.path (see site.addpackage()). Skip the test if at least @@ -515,19 +509,20 @@ class StartupImportTests(unittest.TestCase): # This tests checks which modules are loaded by Python when it # initially starts upon startup. - popen = subprocess.Popen([sys.executable, '-I', '-v', '-c', - 'import sys; print(set(sys.modules))'], + popen = subprocess.Popen([sys.executable, '-X', 'utf8', '-I', '-v', + '-c', 'import sys; print(set(sys.modules))'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, - encoding='utf-8') + encoding='utf-8', + errors='surrogateescape') stdout, stderr = popen.communicate() self.assertEqual(popen.returncode, 0, (stdout, stderr)) - modules = eval(stdout) + modules = ast.literal_eval(stdout) self.assertIn('site', modules) # http://bugs.python.org/issue19205 - re_mods = {'re', '_sre', 'sre_compile', 'sre_constants', 'sre_parse'} + re_mods = {'re', '_sre', 're._compiler', 're._constants', 're._parser'} self.assertFalse(modules.intersection(re_mods), stderr) # http://bugs.python.org/issue9548 @@ -543,43 +538,61 @@ class StartupImportTests(unittest.TestCase): }.difference(sys.builtin_module_names) self.assertFalse(modules.intersection(collection_mods), stderr) + @support.requires_subprocess() def test_startup_interactivehook(self): r = subprocess.Popen([sys.executable, '-c', 'import sys; sys.exit(hasattr(sys, "__interactivehook__"))']).wait() self.assertTrue(r, "'__interactivehook__' not added by site") + @support.requires_subprocess() def test_startup_interactivehook_isolated(self): # issue28192 readline is not automatically enabled in isolated mode r = subprocess.Popen([sys.executable, '-I', '-c', 'import sys; sys.exit(hasattr(sys, "__interactivehook__"))']).wait() self.assertFalse(r, "'__interactivehook__' added in isolated mode") + @support.requires_subprocess() def test_startup_interactivehook_isolated_explicit(self): # issue28192 readline can be explicitly enabled in isolated mode r = subprocess.Popen([sys.executable, '-I', '-c', 'import site, sys; site.enablerlcompleter(); sys.exit(hasattr(sys, "__interactivehook__"))']).wait() self.assertTrue(r, "'__interactivehook__' not added by enablerlcompleter()") -@unittest.skipUnless(sys.platform == 'win32', "only supported on Windows") class _pthFileTests(unittest.TestCase): - def _create_underpth_exe(self, lines, exe_pth=True): - import _winapi - temp_dir = tempfile.mkdtemp() - self.addCleanup(os_helper.rmtree, temp_dir) - exe_file = os.path.join(temp_dir, os.path.split(sys.executable)[1]) - dll_src_file = _winapi.GetModuleFileName(sys.dllhandle) - dll_file = os.path.join(temp_dir, os.path.split(dll_src_file)[1]) - shutil.copy(sys.executable, exe_file) - shutil.copy(dll_src_file, dll_file) - if exe_pth: - _pth_file = os.path.splitext(exe_file)[0] + '._pth' - else: - _pth_file = os.path.splitext(dll_file)[0] + '._pth' - with open(_pth_file, 'w') as f: - for line in lines: - print(line, file=f) - return exe_file + if sys.platform == 'win32': + def _create_underpth_exe(self, lines, exe_pth=True): + import _winapi + temp_dir = tempfile.mkdtemp() + self.addCleanup(os_helper.rmtree, temp_dir) + exe_file = os.path.join(temp_dir, os.path.split(sys.executable)[1]) + dll_src_file = _winapi.GetModuleFileName(sys.dllhandle) + dll_file = os.path.join(temp_dir, os.path.split(dll_src_file)[1]) + shutil.copy(sys.executable, exe_file) + shutil.copy(dll_src_file, dll_file) + for fn in glob.glob(os.path.join(os.path.split(dll_src_file)[0], "vcruntime*.dll")): + shutil.copy(fn, os.path.join(temp_dir, os.path.split(fn)[1])) + if exe_pth: + _pth_file = os.path.splitext(exe_file)[0] + '._pth' + else: + _pth_file = os.path.splitext(dll_file)[0] + '._pth' + with open(_pth_file, 'w') as f: + for line in lines: + print(line, file=f) + return exe_file + else: + def _create_underpth_exe(self, lines, exe_pth=True): + if not exe_pth: + raise unittest.SkipTest("library ._pth file not supported on this platform") + temp_dir = tempfile.mkdtemp() + self.addCleanup(os_helper.rmtree, temp_dir) + exe_file = os.path.join(temp_dir, os.path.split(sys.executable)[1]) + os.symlink(sys.executable, exe_file) + _pth_file = exe_file + '._pth' + with open(_pth_file, 'w') as f: + for line in lines: + print(line, file=f) + return exe_file def _calc_sys_path_for_underpth_nosite(self, sys_prefix, lines): sys_path = [] @@ -590,6 +603,28 @@ class _pthFileTests(unittest.TestCase): sys_path.append(abs_path) return sys_path + @support.requires_subprocess() + def test_underpth_basic(self): + libpath = test.support.STDLIB_DIR + exe_prefix = os.path.dirname(sys.executable) + pth_lines = ['#.', '# ..', *sys.path, '.', '..'] + exe_file = self._create_underpth_exe(pth_lines) + sys_path = self._calc_sys_path_for_underpth_nosite( + os.path.dirname(exe_file), + pth_lines) + + output = subprocess.check_output([exe_file, '-c', + 'import sys; print("\\n".join(sys.path) if sys.flags.no_site else "")' + ], encoding='utf-8', errors='surrogateescape') + actual_sys_path = output.rstrip().split('\n') + self.assertTrue(actual_sys_path, "sys.flags.no_site was False") + self.assertEqual( + actual_sys_path, + sys_path, + "sys.path is incorrect" + ) + + @support.requires_subprocess() def test_underpth_nosite_file(self): libpath = test.support.STDLIB_DIR exe_prefix = os.path.dirname(sys.executable) @@ -606,10 +641,10 @@ class _pthFileTests(unittest.TestCase): env = os.environ.copy() env['PYTHONPATH'] = 'from-env' - env['PATH'] = '{};{}'.format(exe_prefix, os.getenv('PATH')) + env['PATH'] = '{}{}{}'.format(exe_prefix, os.pathsep, os.getenv('PATH')) output = subprocess.check_output([exe_file, '-c', 'import sys; print("\\n".join(sys.path) if sys.flags.no_site else "")' - ], env=env, encoding='ansi') + ], env=env, encoding='utf-8', errors='surrogateescape') actual_sys_path = output.rstrip().split('\n') self.assertTrue(actual_sys_path, "sys.flags.no_site was False") self.assertEqual( @@ -618,6 +653,7 @@ class _pthFileTests(unittest.TestCase): "sys.path is incorrect" ) + @support.requires_subprocess() def test_underpth_file(self): libpath = test.support.STDLIB_DIR exe_prefix = os.path.dirname(sys.executable) @@ -642,7 +678,7 @@ class _pthFileTests(unittest.TestCase): )], env=env) self.assertTrue(rc, "sys.path is incorrect") - + @support.requires_subprocess() def test_underpth_dll_file(self): libpath = test.support.STDLIB_DIR exe_prefix = os.path.dirname(sys.executable) diff --git a/Lib/test/test_slice.py b/Lib/test/test_slice.py index 4ae4142c60c..03fde3275e1 100644 --- a/Lib/test/test_slice.py +++ b/Lib/test/test_slice.py @@ -5,6 +5,7 @@ import operator import sys import unittest import weakref +import copy from pickle import loads, dumps from test import support @@ -235,13 +236,50 @@ class SliceTest(unittest.TestCase): self.assertEqual(tmp, [(slice(1, 2), 42)]) def test_pickle(self): + import pickle + s = slice(10, 20, 3) - for protocol in (0,1,2): + for protocol in range(pickle.HIGHEST_PROTOCOL + 1): t = loads(dumps(s, protocol)) self.assertEqual(s, t) self.assertEqual(s.indices(15), t.indices(15)) self.assertNotEqual(id(s), id(t)) + def test_copy(self): + s = slice(1, 10) + c = copy.copy(s) + self.assertIs(s, c) + + s = slice(1, 10, 2) + c = copy.copy(s) + self.assertIs(s, c) + + # Corner case for mutable indices: + s = slice([1, 2], [3, 4], [5, 6]) + c = copy.copy(s) + self.assertIs(s, c) + self.assertIs(s.start, c.start) + self.assertIs(s.stop, c.stop) + self.assertIs(s.step, c.step) + + def test_deepcopy(self): + s = slice(1, 10) + c = copy.deepcopy(s) + self.assertEqual(s, c) + + s = slice(1, 10, 2) + c = copy.deepcopy(s) + self.assertEqual(s, c) + + # Corner case for mutable indices: + s = slice([1, 2], [3, 4], [5, 6]) + c = copy.deepcopy(s) + self.assertIsNot(s, c) + self.assertEqual(s, c) + self.assertIsNot(s.start, c.start) + self.assertIsNot(s.stop, c.stop) + self.assertIsNot(s.step, c.step) + def test_cycle(self): class myobj(): pass o = myobj() diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index bdce3e37095..b6d5b8c3d82 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -18,13 +18,17 @@ import threading import unittest from test import support, mock_socket -from test.support import _asyncore as asyncore -from test.support import _smtpd as smtpd from test.support import hashlib_helper from test.support import socket_helper from test.support import threading_helper +from test.support import asyncore from unittest.mock import Mock +from . import smtpd + + +support.requires_working_socket(module=True) + HOST = socket_helper.HOST if sys.platform == 'darwin': @@ -1167,7 +1171,7 @@ class SMTPSimTests(unittest.TestCase): finally: smtp.close() - @hashlib_helper.requires_hashdigest('md5') + @hashlib_helper.requires_hashdigest('md5', openssl=True) def testAUTH_CRAM_MD5(self): self.serv.add_feature("AUTH CRAM-MD5") smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', @@ -1176,7 +1180,7 @@ class SMTPSimTests(unittest.TestCase): self.assertEqual(resp, (235, b'Authentication Succeeded')) smtp.close() - @hashlib_helper.requires_hashdigest('md5') + @hashlib_helper.requires_hashdigest('md5', openssl=True) def testAUTH_multiple(self): # Test that multiple authentication methods are tried. self.serv.add_feature("AUTH BOGUS PLAIN LOGIN CRAM-MD5") diff --git a/Lib/test/test_sndhdr.py b/Lib/test/test_sndhdr.py index 426417c0382..4d97437f907 100644 --- a/Lib/test/test_sndhdr.py +++ b/Lib/test/test_sndhdr.py @@ -1,7 +1,10 @@ -import sndhdr import pickle import unittest from test.support import findfile +from test.support import warnings_helper + +sndhdr = warnings_helper.import_deprecated("sndhdr") + class TestFormats(unittest.TestCase): def test_data(self): diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py old mode 100755 new mode 100644 index 394d2942483..f1b4018c265 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -4,30 +4,30 @@ from test.support import os_helper from test.support import socket_helper from test.support import threading_helper +import _thread as thread +import array +import contextlib import errno import io import itertools -import socket +import math +import os +import pickle +import platform +import queue +import random +import re import select +import signal +import socket +import string +import struct +import sys import tempfile +import threading import time import traceback -import queue -import sys -import os -import platform -import array -import contextlib from weakref import proxy -import signal -import math -import pickle -import struct -import random -import shutil -import string -import _thread as thread -import threading try: import multiprocessing except ImportError: @@ -37,6 +37,8 @@ try: except ImportError: fcntl = None +support.requires_working_socket(module=True) + HOST = socket_helper.HOST # test unicode string and carriage return MSG = 'Michael Gilfix was here\u1234\r\n'.encode('utf-8') @@ -141,6 +143,17 @@ def _have_socket_bluetooth(): return True +def _have_socket_hyperv(): + """Check whether AF_HYPERV sockets are supported on this host.""" + try: + s = socket.socket(socket.AF_HYPERV, socket.SOCK_STREAM, socket.HV_PROTOCOL_RAW) + except (AttributeError, OSError): + return False + else: + s.close() + return True + + @contextlib.contextmanager def socket_setdefaulttimeout(timeout): old_timeout = socket.getdefaulttimeout() @@ -169,6 +182,8 @@ HAVE_SOCKET_UDPLITE = hasattr(socket, "IPPROTO_UDPLITE") HAVE_SOCKET_BLUETOOTH = _have_socket_bluetooth() +HAVE_SOCKET_HYPERV = _have_socket_hyperv() + # Size in bytes of the int type SIZEOF_INT = array.array("i").itemsize @@ -336,9 +351,7 @@ class ThreadableTest: self.server_ready.set() def _setUp(self): - self.wait_threads = threading_helper.wait_threads_exit() - self.wait_threads.__enter__() - self.addCleanup(self.wait_threads.__exit__, None, None, None) + self.enterContext(threading_helper.wait_threads_exit()) self.server_ready = threading.Event() self.client_ready = threading.Event() @@ -591,17 +604,18 @@ class SocketTestBase(unittest.TestCase): def setUp(self): self.serv = self.newSocket() + self.addCleanup(self.close_server) self.bindServer() + def close_server(self): + self.serv.close() + self.serv = None + def bindServer(self): """Bind server socket and set self.serv_addr to its address.""" self.bindSock(self.serv) self.serv_addr = self.serv.getsockname() - def tearDown(self): - self.serv.close() - self.serv = None - class SocketListeningTestMixin(SocketTestBase): """Mixin to listen on the server socket.""" @@ -686,15 +700,10 @@ class UnixSocketTestBase(SocketTestBase): # can't send anything that might be problematic for a privileged # user running the tests. - def setUp(self): - self.dir_path = tempfile.mkdtemp() - self.addCleanup(os.rmdir, self.dir_path) - super().setUp() - def bindSock(self, sock): - path = tempfile.mktemp(dir=self.dir_path) - socket_helper.bind_unix_socket(sock, path) + path = socket_helper.create_unix_domain_name() self.addCleanup(os_helper.unlink, path) + socket_helper.bind_unix_socket(sock, path) class UnixStreamBase(UnixSocketTestBase): """Base class for Unix-domain SOCK_STREAM tests.""" @@ -956,6 +965,19 @@ class GeneralModuleTests(unittest.TestCase): socket.IPPROTO_L2TP socket.IPPROTO_SCTP + @unittest.skipIf(support.is_wasi, "WASI is missing these methods") + def test_socket_methods(self): + # socket methods that depend on a configure HAVE_ check. They should + # be present on all platforms except WASI. + names = [ + "_accept", "bind", "connect", "connect_ex", "getpeername", + "getsockname", "listen", "recvfrom", "recvfrom_into", "sendto", + "setsockopt", "shutdown" + ] + for name in names: + if not hasattr(socket.socket, name): + self.fail(f"socket method {name} is missing") + @unittest.skipUnless(sys.platform == 'darwin', 'macOS specific test') @unittest.skipUnless(socket_helper.IPV6_ENABLED, 'IPv6 required for this test') def test3542SocketOptions(self): @@ -1376,10 +1398,21 @@ class GeneralModuleTests(unittest.TestCase): def testSockName(self): # Testing getsockname() - port = socket_helper.find_unused_port() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.addCleanup(sock.close) - sock.bind(("0.0.0.0", port)) + + # Since find_unused_port() is inherently subject to race conditions, we + # call it a couple times if necessary. + for i in itertools.count(): + port = socket_helper.find_unused_port() + try: + sock.bind(("0.0.0.0", port)) + except OSError as e: + if e.errno != errno.EADDRINUSE or i == 5: + raise + else: + break + name = sock.getsockname() # XXX(nnorwitz): http://tinyurl.com/os5jz seems to indicate # it reasonable to get the host's addr in addition to 0.0.0.0. @@ -1517,9 +1550,11 @@ class GeneralModuleTests(unittest.TestCase): infos = socket.getaddrinfo(HOST, 80, socket.AF_INET, socket.SOCK_STREAM) for family, type, _, _, _ in infos: self.assertEqual(family, socket.AF_INET) - self.assertEqual(str(family), 'AF_INET') + self.assertEqual(repr(family), '' % family.value) + self.assertEqual(str(family), str(family.value)) self.assertEqual(type, socket.SOCK_STREAM) - self.assertEqual(str(type), 'SOCK_STREAM') + self.assertEqual(repr(type), '' % type.value) + self.assertEqual(str(type), str(type.value)) infos = socket.getaddrinfo(HOST, None, 0, socket.SOCK_STREAM) for _, socktype, _, _, _ in infos: self.assertEqual(socktype, socket.SOCK_STREAM) @@ -1734,6 +1769,10 @@ class GeneralModuleTests(unittest.TestCase): ) self.assertEqual(sockaddr, ('ff02::1de:c0:face:8d', 1234, 0, 0)) + def test_getfqdn_filter_localhost(self): + self.assertEqual(socket.getfqdn(), socket.getfqdn("0.0.0.0")) + self.assertEqual(socket.getfqdn(), socket.getfqdn("::")) + @unittest.skipUnless(socket_helper.IPV6_ENABLED, 'IPv6 required for this test.') @unittest.skipIf(sys.platform == 'win32', 'does not work on Windows') @unittest.skipIf(AIX, 'Symbolic scope id does not work') @@ -1793,8 +1832,10 @@ class GeneralModuleTests(unittest.TestCase): # Make sure that the AF_* and SOCK_* constants have enum-like string # reprs. with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - self.assertEqual(str(s.family), 'AF_INET') - self.assertEqual(str(s.type), 'SOCK_STREAM') + self.assertEqual(repr(s.family), '' % s.family.value) + self.assertEqual(repr(s.type), '' % s.type.value) + self.assertEqual(str(s.family), str(s.family.value)) + self.assertEqual(str(s.type), str(s.type.value)) def test_socket_consistent_sock_type(self): SOCK_NONBLOCK = getattr(socket, 'SOCK_NONBLOCK', 0) @@ -1887,17 +1928,18 @@ class GeneralModuleTests(unittest.TestCase): self._test_socket_fileno(s, socket.AF_INET6, socket.SOCK_STREAM) if hasattr(socket, "AF_UNIX"): - tmpdir = tempfile.mkdtemp() - self.addCleanup(shutil.rmtree, tmpdir) + unix_name = socket_helper.create_unix_domain_name() + self.addCleanup(os_helper.unlink, unix_name) + s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - self.addCleanup(s.close) - try: - s.bind(os.path.join(tmpdir, 'socket')) - except PermissionError: - pass - else: - self._test_socket_fileno(s, socket.AF_UNIX, - socket.SOCK_STREAM) + with s: + try: + s.bind(unix_name) + except PermissionError: + pass + else: + self._test_socket_fileno(s, socket.AF_UNIX, + socket.SOCK_STREAM) def test_socket_fileno_rejects_float(self): with self.assertRaises(TypeError): @@ -2455,6 +2497,59 @@ class BasicBluetoothTest(unittest.TestCase): pass +@unittest.skipUnless(HAVE_SOCKET_HYPERV, + 'Hyper-V sockets required for this test.') +class BasicHyperVTest(unittest.TestCase): + + def testHyperVConstants(self): + socket.HVSOCKET_CONNECT_TIMEOUT + socket.HVSOCKET_CONNECT_TIMEOUT_MAX + socket.HVSOCKET_CONNECTED_SUSPEND + socket.HVSOCKET_ADDRESS_FLAG_PASSTHRU + socket.HV_GUID_ZERO + socket.HV_GUID_WILDCARD + socket.HV_GUID_BROADCAST + socket.HV_GUID_CHILDREN + socket.HV_GUID_LOOPBACK + socket.HV_GUID_LOOPBACK + + def testCreateHyperVSocketWithUnknownProtoFailure(self): + expected = "A protocol was specified in the socket function call " \ + "that does not support the semantics of the socket type requested" + with self.assertRaisesRegex(OSError, expected): + socket.socket(socket.AF_HYPERV, socket.SOCK_STREAM) + + def testCreateHyperVSocketAddrNotTupleFailure(self): + expected = "connect(): AF_HYPERV address must be tuple, not str" + with socket.socket(socket.AF_HYPERV, socket.SOCK_STREAM, socket.HV_PROTOCOL_RAW) as s: + with self.assertRaisesRegex(TypeError, re.escape(expected)): + s.connect(socket.HV_GUID_ZERO) + + def testCreateHyperVSocketAddrNotTupleOf2StrsFailure(self): + expected = "AF_HYPERV address must be a str tuple (vm_id, service_id)" + with socket.socket(socket.AF_HYPERV, socket.SOCK_STREAM, socket.HV_PROTOCOL_RAW) as s: + with self.assertRaisesRegex(TypeError, re.escape(expected)): + s.connect((socket.HV_GUID_ZERO,)) + + def testCreateHyperVSocketAddrNotTupleOfStrsFailure(self): + expected = "AF_HYPERV address must be a str tuple (vm_id, service_id)" + with socket.socket(socket.AF_HYPERV, socket.SOCK_STREAM, socket.HV_PROTOCOL_RAW) as s: + with self.assertRaisesRegex(TypeError, re.escape(expected)): + s.connect((1, 2)) + + def testCreateHyperVSocketAddrVmIdNotValidUUIDFailure(self): + expected = "connect(): AF_HYPERV address vm_id is not a valid UUID string" + with socket.socket(socket.AF_HYPERV, socket.SOCK_STREAM, socket.HV_PROTOCOL_RAW) as s: + with self.assertRaisesRegex(ValueError, re.escape(expected)): + s.connect(("00", socket.HV_GUID_ZERO)) + + def testCreateHyperVSocketAddrServiceIdNotValidUUIDFailure(self): + expected = "connect(): AF_HYPERV address service_id is not a valid UUID string" + with socket.socket(socket.AF_HYPERV, socket.SOCK_STREAM, socket.HV_PROTOCOL_RAW) as s: + with self.assertRaisesRegex(ValueError, re.escape(expected)): + s.connect((socket.HV_GUID_ZERO, "00")) + + class BasicTCPTest(SocketConnectedTest): def __init__(self, methodName='runTest'): @@ -5171,6 +5266,24 @@ class NetworkConnectionNoServer(unittest.TestCase): expected_errnos = socket_helper.get_socket_conn_refused_errs() self.assertIn(cm.exception.errno, expected_errnos) + def test_create_connection_all_errors(self): + port = socket_helper.find_unused_port() + try: + socket.create_connection((HOST, port), all_errors=True) + except ExceptionGroup as e: + eg = e + else: + self.fail('expected connection to fail') + + self.assertIsInstance(eg, ExceptionGroup) + for e in eg.exceptions: + self.assertIsInstance(e, OSError) + + addresses = socket.getaddrinfo( + 'localhost', port, 0, socket.SOCK_STREAM) + # assert that we got an exception for each address + self.assertEqual(len(addresses), len(eg.exceptions)) + def test_create_connection_timeout(self): # Issue #9792: create_connection() should not recast timeout errors # as generic socket errors. @@ -5458,6 +5571,20 @@ class TestLinuxAbstractNamespace(unittest.TestCase): s.bind(bytearray(b"\x00python\x00test\x00")) self.assertEqual(s.getsockname(), b"\x00python\x00test\x00") + def testAutobind(self): + # Check that binding to an empty string binds to an available address + # in the abstract namespace as specified in unix(7) "Autobind feature". + abstract_address = b"^\0[0-9a-f]{5}" + with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s1: + s1.bind("") + self.assertRegex(s1.getsockname(), abstract_address) + # Each socket is bound to a different abstract address. + with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s2: + s2.bind("") + self.assertRegex(s2.getsockname(), abstract_address) + self.assertNotEqual(s1.getsockname(), s2.getsockname()) + + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'test needs socket.AF_UNIX') class TestUnixDomain(unittest.TestCase): @@ -5527,6 +5654,11 @@ class TestUnixDomain(unittest.TestCase): self.addCleanup(os_helper.unlink, path) self.assertEqual(self.sock.getsockname(), path) + @unittest.skipIf(sys.platform == 'linux', 'Linux specific test') + def testEmptyAddress(self): + # Test that binding empty address fails. + self.assertRaises(OSError, self.sock.bind, "") + class BufferIOTest(SocketConnectedTest): """ diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index 211321f3761..2fa50694233 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -8,7 +8,6 @@ import os import select import signal import socket -import tempfile import threading import unittest import socketserver @@ -21,6 +20,8 @@ from test.support import threading_helper test.support.requires("network") +test.support.requires_working_socket(module=True) + TEST_STR = b"hello world\n" HOST = socket_helper.HOST @@ -28,7 +29,7 @@ HOST = socket_helper.HOST HAVE_UNIX_SOCKETS = hasattr(socket, "AF_UNIX") requires_unix_sockets = unittest.skipUnless(HAVE_UNIX_SOCKETS, 'requires Unix sockets') -HAVE_FORKING = hasattr(os, "fork") +HAVE_FORKING = test.support.has_fork_support requires_forking = unittest.skipUnless(HAVE_FORKING, 'requires forking') def signal_alarm(n): @@ -96,8 +97,7 @@ class SocketServerTest(unittest.TestCase): else: # XXX: We need a way to tell AF_UNIX to pick its own name # like AF_INET provides port==0. - dir = None - fn = tempfile.mktemp(prefix='unix_socket.', dir=dir) + fn = socket_helper.create_unix_domain_name() self.test_files.append(fn) return fn diff --git a/Lib/test/test_sort.py b/Lib/test/test_sort.py index 41de4b684f6..3b6ad4d17b0 100644 --- a/Lib/test/test_sort.py +++ b/Lib/test/test_sort.py @@ -378,6 +378,12 @@ class TestOptimizedCompares(unittest.TestCase): self.assertRaises(TypeError, [(1.0, 1.0), (False, "A"), 6].sort) self.assertRaises(TypeError, [('a', 1), (1, 'a')].sort) self.assertRaises(TypeError, [(1, 'a'), ('a', 1)].sort) + + def test_none_in_tuples(self): + expected = [(None, 1), (None, 2)] + actual = sorted([(None, 2), (None, 1)]) + self.assertEqual(actual, expected) + #============================================================================== if __name__ == "__main__": diff --git a/Lib/test/test_source_encoding.py b/Lib/test/test_source_encoding.py index a0cb605c165..b05173ad00d 100644 --- a/Lib/test/test_source_encoding.py +++ b/Lib/test/test_source_encoding.py @@ -1,7 +1,7 @@ -# -*- coding: koi8-r -*- +# -*- coding: utf-8 -*- import unittest -from test.support import script_helper, captured_stdout +from test.support import script_helper, captured_stdout, requires_subprocess from test.support.os_helper import TESTFN, unlink, rmtree from test.support.import_helper import unload import importlib @@ -12,15 +12,14 @@ import tempfile class MiscSourceEncodingTest(unittest.TestCase): - def test_pep263(self): - self.assertEqual( - "ðÉÔÏÎ".encode("utf-8"), - b'\xd0\x9f\xd0\xb8\xd1\x82\xd0\xbe\xd0\xbd' - ) - self.assertEqual( - "\ð".encode("utf-8"), - b'\\\xd0\x9f' - ) + def test_import_encoded_module(self): + from test.encoded_modules import test_strings + # Make sure we're actually testing something + self.assertGreaterEqual(len(test_strings), 1) + for modname, encoding, teststr in test_strings: + mod = importlib.import_module('test.encoded_modules.' + 'module_' + modname) + self.assertEqual(teststr, mod.test) def test_compilestring(self): # see #1882 @@ -65,6 +64,7 @@ class MiscSourceEncodingTest(unittest.TestCase): # two bytes in common with the UTF-8 BOM self.assertRaises(SyntaxError, eval, b'\xef\xbb\x20') + @requires_subprocess() def test_20731(self): sub = subprocess.Popen([sys.executable, os.path.join(os.path.dirname(__file__), @@ -147,6 +147,30 @@ class MiscSourceEncodingTest(unittest.TestCase): self.assertTrue(c.exception.args[0].startswith(expected), msg=c.exception.args[0]) + def test_file_parse_error_multiline(self): + # gh96611: + with open(TESTFN, "wb") as fd: + fd.write(b'print("""\n\xb1""")\n') + + try: + retcode, stdout, stderr = script_helper.assert_python_failure(TESTFN) + + self.assertGreater(retcode, 0) + self.assertIn(b"Non-UTF-8 code starting with '\\xb1'", stderr) + finally: + os.unlink(TESTFN) + + def test_tokenizer_fstring_warning_in_first_line(self): + source = "0b1and 2" + with open(TESTFN, "w") as fd: + fd.write("{}".format(source)) + try: + retcode, stdout, stderr = script_helper.assert_python_ok(TESTFN) + self.assertIn(b"SyntaxWarning: invalid binary litera", stderr) + self.assertEqual(stderr.count(source.encode()), 1) + finally: + os.unlink(TESTFN) + class AbstractSourceEncodingTest: @@ -223,6 +247,74 @@ class AbstractSourceEncodingTest: out = self.check_script_output(src, br"'\n\n\n'") +class UTF8ValidatorTest(unittest.TestCase): + @unittest.skipIf(not sys.platform.startswith("linux"), + "Too slow to run on non-Linux platforms") + def test_invalid_utf8(self): + # This is a port of test_utf8_decode_invalid_sequences in + # test_unicode.py to exercise the separate utf8 validator in + # Parser/tokenizer.c used when reading source files. + + # That file is written using low-level C file I/O, so the only way to + # test it is to write actual files to disk. + + # Each example is put inside a string at the top of the file so + # it's an otherwise valid Python source file. Put some newlines + # beforehand so we can assert that the error is reported on the + # correct line. + template = b'\n\n\n"%s"\n' + + fn = TESTFN + self.addCleanup(unlink, fn) + + def check(content): + with open(fn, 'wb') as fp: + fp.write(template % content) + rc, stdout, stderr = script_helper.assert_python_failure(fn) + # We want to assert that the python subprocess failed gracefully, + # not via a signal. + self.assertGreaterEqual(rc, 1) + self.assertIn(b"Non-UTF-8 code starting with", stderr) + self.assertIn(b"on line 4", stderr) + + # continuation bytes in a sequence of 2, 3, or 4 bytes + continuation_bytes = [bytes([x]) for x in range(0x80, 0xC0)] + # start bytes of a 2-byte sequence equivalent to code points < 0x7F + invalid_2B_seq_start_bytes = [bytes([x]) for x in range(0xC0, 0xC2)] + # start bytes of a 4-byte sequence equivalent to code points > 0x10FFFF + invalid_4B_seq_start_bytes = [bytes([x]) for x in range(0xF5, 0xF8)] + invalid_start_bytes = ( + continuation_bytes + invalid_2B_seq_start_bytes + + invalid_4B_seq_start_bytes + [bytes([x]) for x in range(0xF7, 0x100)] + ) + + for byte in invalid_start_bytes: + check(byte) + + for sb in invalid_2B_seq_start_bytes: + for cb in continuation_bytes: + check(sb + cb) + + for sb in invalid_4B_seq_start_bytes: + for cb1 in continuation_bytes[:3]: + for cb3 in continuation_bytes[:3]: + check(sb+cb1+b'\x80'+cb3) + + for cb in [bytes([x]) for x in range(0x80, 0xA0)]: + check(b'\xE0'+cb+b'\x80') + check(b'\xE0'+cb+b'\xBF') + # surrogates + for cb in [bytes([x]) for x in range(0xA0, 0xC0)]: + check(b'\xED'+cb+b'\x80') + check(b'\xED'+cb+b'\xBF') + for cb in [bytes([x]) for x in range(0x80, 0x90)]: + check(b'\xF0'+cb+b'\x80\x80') + check(b'\xF0'+cb+b'\xBF\xBF') + for cb in [bytes([x]) for x in range(0x90, 0xC0)]: + check(b'\xF4'+cb+b'\x80\x80') + check(b'\xF4'+cb+b'\xBF\xBF') + + class BytesSourceEncodingTest(AbstractSourceEncodingTest, unittest.TestCase): def check_script_output(self, src, expected): diff --git a/Lib/test/test_spwd.py b/Lib/test/test_spwd.py index a143acc659e..50766c25482 100644 --- a/Lib/test/test_spwd.py +++ b/Lib/test/test_spwd.py @@ -1,9 +1,12 @@ import os import unittest from test.support import import_helper +import warnings -spwd = import_helper.import_module('spwd') +with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + spwd = import_helper.import_module('spwd') @unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() == 0, diff --git a/Lib/test/test_sqlite3/__init__.py b/Lib/test/test_sqlite3/__init__.py index 099c01e3b3c..d777fca82da 100644 --- a/Lib/test/test_sqlite3/__init__.py +++ b/Lib/test/test_sqlite3/__init__.py @@ -3,7 +3,6 @@ from test.support import import_helper, load_package_tests, verbose # Skip test if _sqlite3 module not installed. import_helper.import_module('_sqlite3') -import unittest import os import sqlite3 @@ -13,6 +12,4 @@ def load_tests(*args): return load_package_tests(pkg_dir, *args) if verbose: - print("test_sqlite3: testing with version", - "{!r}, sqlite_version {!r}".format(sqlite3.version, - sqlite3.sqlite_version)) + print(f"test_sqlite3: testing with SQLite version {sqlite3.sqlite_version}") diff --git a/Lib/test/test_sqlite3/__main__.py b/Lib/test/test_sqlite3/__main__.py index 51eddc3c2fd..ca6a8347fbd 100644 --- a/Lib/test/test_sqlite3/__main__.py +++ b/Lib/test/test_sqlite3/__main__.py @@ -1,5 +1,4 @@ from test.test_sqlite3 import load_tests # Needed for the "load tests" protocol. import unittest -if __name__ == "__main__": - unittest.main() +unittest.main() diff --git a/Lib/test/test_sqlite3/test_cli.py b/Lib/test/test_sqlite3/test_cli.py new file mode 100644 index 00000000000..d374f8ee4fc --- /dev/null +++ b/Lib/test/test_sqlite3/test_cli.py @@ -0,0 +1,155 @@ +"""sqlite3 CLI tests.""" + +import sqlite3 as sqlite +import subprocess +import sys +import unittest + +from test.support import SHORT_TIMEOUT, requires_subprocess +from test.support.os_helper import TESTFN, unlink + + +@requires_subprocess() +class CommandLineInterface(unittest.TestCase): + + def _do_test(self, *args, expect_success=True): + with subprocess.Popen( + [sys.executable, "-Xutf8", "-m", "sqlite3", *args], + encoding="utf-8", + bufsize=0, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) as proc: + proc.wait() + if expect_success == bool(proc.returncode): + self.fail("".join(proc.stderr)) + stdout = proc.stdout.read() + stderr = proc.stderr.read() + if expect_success: + self.assertEqual(stderr, "") + else: + self.assertEqual(stdout, "") + return stdout, stderr + + def expect_success(self, *args): + out, _ = self._do_test(*args) + return out + + def expect_failure(self, *args): + _, err = self._do_test(*args, expect_success=False) + return err + + def test_cli_help(self): + out = self.expect_success("-h") + self.assertIn("usage: python -m sqlite3", out) + + def test_cli_version(self): + out = self.expect_success("-v") + self.assertIn(sqlite.sqlite_version, out) + + def test_cli_execute_sql(self): + out = self.expect_success(":memory:", "select 1") + self.assertIn("(1,)", out) + + def test_cli_execute_too_much_sql(self): + stderr = self.expect_failure(":memory:", "select 1; select 2") + err = "ProgrammingError: You can only execute one statement at a time" + self.assertIn(err, stderr) + + def test_cli_execute_incomplete_sql(self): + stderr = self.expect_failure(":memory:", "sel") + self.assertIn("OperationalError (SQLITE_ERROR)", stderr) + + def test_cli_on_disk_db(self): + self.addCleanup(unlink, TESTFN) + out = self.expect_success(TESTFN, "create table t(t)") + self.assertEqual(out, "") + out = self.expect_success(TESTFN, "select count(t) from t") + self.assertIn("(0,)", out) + + +@requires_subprocess() +class InteractiveSession(unittest.TestCase): + TIMEOUT = SHORT_TIMEOUT / 10. + MEMORY_DB_MSG = "Connected to a transient in-memory database" + PS1 = "sqlite> " + PS2 = "... " + + def start_cli(self, *args): + return subprocess.Popen( + [sys.executable, "-Xutf8", "-m", "sqlite3", *args], + encoding="utf-8", + bufsize=0, + stdin=subprocess.PIPE, + # Note: the banner is printed to stderr, the prompt to stdout. + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + + def expect_success(self, proc): + proc.wait() + if proc.returncode: + self.fail("".join(proc.stderr)) + + def test_interact(self): + with self.start_cli() as proc: + out, err = proc.communicate(timeout=self.TIMEOUT) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn(self.PS1, out) + self.expect_success(proc) + + def test_interact_quit(self): + with self.start_cli() as proc: + out, err = proc.communicate(input=".quit", timeout=self.TIMEOUT) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn(self.PS1, out) + self.expect_success(proc) + + def test_interact_version(self): + with self.start_cli() as proc: + out, err = proc.communicate(input=".version", timeout=self.TIMEOUT) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn(sqlite.sqlite_version, out) + self.expect_success(proc) + + def test_interact_valid_sql(self): + with self.start_cli() as proc: + out, err = proc.communicate(input="select 1;", + timeout=self.TIMEOUT) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn("(1,)", out) + self.expect_success(proc) + + def test_interact_valid_multiline_sql(self): + with self.start_cli() as proc: + out, err = proc.communicate(input="select 1\n;", + timeout=self.TIMEOUT) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn(self.PS2, out) + self.assertIn("(1,)", out) + self.expect_success(proc) + + def test_interact_invalid_sql(self): + with self.start_cli() as proc: + out, err = proc.communicate(input="sel;", timeout=self.TIMEOUT) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn("OperationalError (SQLITE_ERROR)", err) + self.expect_success(proc) + + def test_interact_on_disk_file(self): + self.addCleanup(unlink, TESTFN) + with self.start_cli(TESTFN) as proc: + out, err = proc.communicate(input="create table t(t);", + timeout=self.TIMEOUT) + self.assertIn(TESTFN, err) + self.assertIn(self.PS1, out) + self.expect_success(proc) + with self.start_cli(TESTFN, "select count(t) from t") as proc: + out = proc.stdout.read() + err = proc.stderr.read() + self.assertIn("(0,)", out) + self.expect_success(proc) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py index 4eb4e180bf1..363a308f3e5 100644 --- a/Lib/test/test_sqlite3/test_dbapi.py +++ b/Lib/test/test_sqlite3/test_dbapi.py @@ -21,30 +21,22 @@ # 3. This notice may not be removed or altered from any source distribution. import contextlib +import os import sqlite3 as sqlite import subprocess import sys import threading import unittest +import urllib.parse from test.support import ( - SHORT_TIMEOUT, - check_disallow_instantiation, - threading_helper, + SHORT_TIMEOUT, check_disallow_instantiation, requires_subprocess, + is_emscripten, is_wasi ) -from test.support.os_helper import TESTFN, unlink, temp_dir - - -# Helper for tests using TESTFN -@contextlib.contextmanager -def managed_connect(*args, in_mem=False, **kwargs): - cx = sqlite.connect(*args, **kwargs) - try: - yield cx - finally: - cx.close() - if not in_mem: - unlink(TESTFN) +from test.support import threading_helper +from _testcapi import INT_MAX, ULLONG_MAX +from os import SEEK_SET, SEEK_CUR, SEEK_END +from test.support.os_helper import TESTFN, TESTFN_UNDECODABLE, unlink, temp_dir, FakePath # Helper for temporary memory databases @@ -68,6 +60,17 @@ class ModuleTests(unittest.TestCase): self.assertEqual(sqlite.apilevel, "2.0", "apilevel is %s, should be 2.0" % sqlite.apilevel) + def test_deprecated_version(self): + msg = "deprecated and will be removed in Python 3.14" + for attr in "version", "version_info": + with self.subTest(attr=attr): + with self.assertWarnsRegex(DeprecationWarning, msg) as cm: + getattr(sqlite, attr) + self.assertEqual(cm.filename, __file__) + with self.assertWarnsRegex(DeprecationWarning, msg) as cm: + getattr(sqlite.dbapi2, attr) + self.assertEqual(cm.filename, __file__) + def test_thread_safety(self): self.assertIn(sqlite.threadsafety, {0, 1, 3}, "threadsafety is %d, should be 0, 1 or 3" % @@ -239,7 +242,7 @@ class ModuleTests(unittest.TestCase): "SQLITE_READONLY_CANTLOCK", "SQLITE_READONLY_RECOVERY", ] - if sqlite.version_info >= (3, 7, 16): + if sqlite.sqlite_version_info >= (3, 7, 16): consts += [ "SQLITE_CONSTRAINT_CHECK", "SQLITE_CONSTRAINT_COMMITHOOK", @@ -252,63 +255,63 @@ class ModuleTests(unittest.TestCase): "SQLITE_CONSTRAINT_VTAB", "SQLITE_READONLY_ROLLBACK", ] - if sqlite.version_info >= (3, 7, 17): + if sqlite.sqlite_version_info >= (3, 7, 17): consts += [ "SQLITE_IOERR_MMAP", "SQLITE_NOTICE_RECOVER_ROLLBACK", "SQLITE_NOTICE_RECOVER_WAL", ] - if sqlite.version_info >= (3, 8, 0): + if sqlite.sqlite_version_info >= (3, 8, 0): consts += [ "SQLITE_BUSY_SNAPSHOT", "SQLITE_IOERR_GETTEMPPATH", "SQLITE_WARNING_AUTOINDEX", ] - if sqlite.version_info >= (3, 8, 1): + if sqlite.sqlite_version_info >= (3, 8, 1): consts += ["SQLITE_CANTOPEN_CONVPATH", "SQLITE_IOERR_CONVPATH"] - if sqlite.version_info >= (3, 8, 2): + if sqlite.sqlite_version_info >= (3, 8, 2): consts.append("SQLITE_CONSTRAINT_ROWID") - if sqlite.version_info >= (3, 8, 3): + if sqlite.sqlite_version_info >= (3, 8, 3): consts.append("SQLITE_READONLY_DBMOVED") - if sqlite.version_info >= (3, 8, 7): + if sqlite.sqlite_version_info >= (3, 8, 7): consts.append("SQLITE_AUTH_USER") - if sqlite.version_info >= (3, 9, 0): + if sqlite.sqlite_version_info >= (3, 9, 0): consts.append("SQLITE_IOERR_VNODE") - if sqlite.version_info >= (3, 10, 0): + if sqlite.sqlite_version_info >= (3, 10, 0): consts.append("SQLITE_IOERR_AUTH") - if sqlite.version_info >= (3, 14, 1): + if sqlite.sqlite_version_info >= (3, 14, 1): consts.append("SQLITE_OK_LOAD_PERMANENTLY") - if sqlite.version_info >= (3, 21, 0): + if sqlite.sqlite_version_info >= (3, 21, 0): consts += [ "SQLITE_IOERR_BEGIN_ATOMIC", "SQLITE_IOERR_COMMIT_ATOMIC", "SQLITE_IOERR_ROLLBACK_ATOMIC", ] - if sqlite.version_info >= (3, 22, 0): + if sqlite.sqlite_version_info >= (3, 22, 0): consts += [ "SQLITE_ERROR_MISSING_COLLSEQ", "SQLITE_ERROR_RETRY", "SQLITE_READONLY_CANTINIT", "SQLITE_READONLY_DIRECTORY", ] - if sqlite.version_info >= (3, 24, 0): + if sqlite.sqlite_version_info >= (3, 24, 0): consts += ["SQLITE_CORRUPT_SEQUENCE", "SQLITE_LOCKED_VTAB"] - if sqlite.version_info >= (3, 25, 0): + if sqlite.sqlite_version_info >= (3, 25, 0): consts += ["SQLITE_CANTOPEN_DIRTYWAL", "SQLITE_ERROR_SNAPSHOT"] - if sqlite.version_info >= (3, 31, 0): + if sqlite.sqlite_version_info >= (3, 31, 0): consts += [ "SQLITE_CANTOPEN_SYMLINK", "SQLITE_CONSTRAINT_PINNED", "SQLITE_OK_SYMLINK", ] - if sqlite.version_info >= (3, 32, 0): + if sqlite.sqlite_version_info >= (3, 32, 0): consts += [ "SQLITE_BUSY_TIMEOUT", "SQLITE_CORRUPT_INDEX", "SQLITE_IOERR_DATA", ] - if sqlite.version_info >= (3, 34, 0): - const.append("SQLITE_IOERR_CORRUPTFS") + if sqlite.sqlite_version_info >= (3, 34, 0): + consts.append("SQLITE_IOERR_CORRUPTFS") for const in consts: with self.subTest(const=const): self.assertTrue(hasattr(sqlite, const)) @@ -330,7 +333,7 @@ class ModuleTests(unittest.TestCase): @unittest.skipIf(sqlite.sqlite_version_info <= (3, 7, 16), "Requires SQLite 3.7.16 or newer") def test_extended_error_code_on_exception(self): - with managed_connect(":memory:", in_mem=True) as con: + with memory_database() as con: with con: con.execute("create table t(t integer check(t > 0))") errmsg = "constraint failed" @@ -341,18 +344,10 @@ class ModuleTests(unittest.TestCase): sqlite.SQLITE_CONSTRAINT_CHECK) self.assertEqual(exc.sqlite_errorname, "SQLITE_CONSTRAINT_CHECK") - # sqlite3_enable_shared_cache() is deprecated on macOS and calling it may raise - # OperationalError on some buildbots. - @unittest.skipIf(sys.platform == "darwin", "shared cache is deprecated on macOS") - def test_shared_cache_deprecated(self): - for enable in (True, False): - with self.assertWarns(DeprecationWarning) as cm: - sqlite.enable_shared_cache(enable) - self.assertIn("dbapi.py", cm.filename) - def test_disallow_instantiation(self): cx = sqlite.connect(":memory:") check_disallow_instantiation(self, type(cx("select 1"))) + check_disallow_instantiation(self, sqlite.Blob) def test_complete_statement(self): self.assertFalse(sqlite.complete_statement("select t")) @@ -396,7 +391,7 @@ class ConnectionTests(unittest.TestCase): def test_failed_open(self): YOU_CANNOT_OPEN_THIS = "/foo/bar/bla/23534/mydb.db" with self.assertRaises(sqlite.OperationalError): - con = sqlite.connect(YOU_CANNOT_OPEN_THIS) + sqlite.connect(YOU_CANNOT_OPEN_THIS) def test_close(self): self.cx.close() @@ -603,30 +598,135 @@ class UninitialisedConnectionTests(unittest.TestCase): func) +@unittest.skipUnless(hasattr(sqlite.Connection, "serialize"), + "Needs SQLite serialize API") +class SerializeTests(unittest.TestCase): + def test_serialize_deserialize(self): + with memory_database() as cx: + with cx: + cx.execute("create table t(t)") + data = cx.serialize() + self.assertEqual(len(data), 8192) + + # Remove test table, verify that it was removed. + with cx: + cx.execute("drop table t") + regex = "no such table" + with self.assertRaisesRegex(sqlite.OperationalError, regex): + cx.execute("select t from t") + + # Deserialize and verify that test table is restored. + cx.deserialize(data) + cx.execute("select t from t") + + def test_deserialize_wrong_args(self): + dataset = ( + (BufferError, memoryview(b"blob")[::2]), + (TypeError, []), + (TypeError, 1), + (TypeError, None), + ) + for exc, arg in dataset: + with self.subTest(exc=exc, arg=arg): + with memory_database() as cx: + self.assertRaises(exc, cx.deserialize, arg) + + def test_deserialize_corrupt_database(self): + with memory_database() as cx: + regex = "file is not a database" + with self.assertRaisesRegex(sqlite.DatabaseError, regex): + cx.deserialize(b"\0\1\3") + # SQLite does not generate an error until you try to query the + # deserialized database. + cx.execute("create table fail(f)") + + class OpenTests(unittest.TestCase): _sql = "create table test(id integer)" def test_open_with_path_like_object(self): """ Checks that we can successfully connect to a database using an object that is PathLike, i.e. has __fspath__(). """ - class Path: - def __fspath__(self): - return TESTFN - path = Path() - with managed_connect(path) as cx: + path = FakePath(TESTFN) + self.addCleanup(unlink, path) + self.assertFalse(os.path.exists(path)) + with contextlib.closing(sqlite.connect(path)) as cx: + self.assertTrue(os.path.exists(path)) + cx.execute(self._sql) + + @unittest.skipIf(sys.platform == "win32", "skipped on Windows") + @unittest.skipIf(sys.platform == "darwin", "skipped on macOS") + @unittest.skipIf(is_emscripten or is_wasi, "not supported on Emscripten/WASI") + @unittest.skipUnless(TESTFN_UNDECODABLE, "only works if there are undecodable paths") + def test_open_with_undecodable_path(self): + path = TESTFN_UNDECODABLE + self.addCleanup(unlink, path) + self.assertFalse(os.path.exists(path)) + with contextlib.closing(sqlite.connect(path)) as cx: + self.assertTrue(os.path.exists(path)) cx.execute(self._sql) def test_open_uri(self): - with managed_connect(TESTFN) as cx: + path = TESTFN + self.addCleanup(unlink, path) + uri = "file:" + urllib.parse.quote(os.fsencode(path)) + self.assertFalse(os.path.exists(path)) + with contextlib.closing(sqlite.connect(uri, uri=True)) as cx: + self.assertTrue(os.path.exists(path)) cx.execute(self._sql) - with managed_connect(f"file:{TESTFN}", uri=True) as cx: + + def test_open_unquoted_uri(self): + path = TESTFN + self.addCleanup(unlink, path) + uri = "file:" + path + self.assertFalse(os.path.exists(path)) + with contextlib.closing(sqlite.connect(uri, uri=True)) as cx: + self.assertTrue(os.path.exists(path)) cx.execute(self._sql) + + def test_open_uri_readonly(self): + path = TESTFN + self.addCleanup(unlink, path) + uri = "file:" + urllib.parse.quote(os.fsencode(path)) + "?mode=ro" + self.assertFalse(os.path.exists(path)) + # Cannot create new DB with self.assertRaises(sqlite.OperationalError): - with managed_connect(f"file:{TESTFN}?mode=ro", uri=True) as cx: + sqlite.connect(uri, uri=True) + self.assertFalse(os.path.exists(path)) + sqlite.connect(path).close() + self.assertTrue(os.path.exists(path)) + # Cannot modify new DB + with contextlib.closing(sqlite.connect(uri, uri=True)) as cx: + with self.assertRaises(sqlite.OperationalError): cx.execute(self._sql) + @unittest.skipIf(sys.platform == "win32", "skipped on Windows") + @unittest.skipIf(sys.platform == "darwin", "skipped on macOS") + @unittest.skipIf(is_emscripten or is_wasi, "not supported on Emscripten/WASI") + @unittest.skipUnless(TESTFN_UNDECODABLE, "only works if there are undecodable paths") + def test_open_undecodable_uri(self): + path = TESTFN_UNDECODABLE + self.addCleanup(unlink, path) + uri = "file:" + urllib.parse.quote(path) + self.assertFalse(os.path.exists(path)) + with contextlib.closing(sqlite.connect(uri, uri=True)) as cx: + self.assertTrue(os.path.exists(path)) + cx.execute(self._sql) + + def test_factory_database_arg(self): + def factory(database, *args, **kwargs): + nonlocal database_arg + database_arg = database + return sqlite.Connection(":memory:", *args, **kwargs) + + for database in (TESTFN, os.fsencode(TESTFN), + FakePath(TESTFN), FakePath(os.fsencode(TESTFN))): + database_arg = None + sqlite.connect(database, factory=factory).close() + self.assertEqual(database_arg, database) + def test_database_keyword(self): - with sqlite.connect(database=":memory:") as cx: + with contextlib.closing(sqlite.connect(database=":memory:")) as cx: self.assertEqual(type(cx), sqlite.Connection) @@ -651,21 +751,44 @@ class CursorTests(unittest.TestCase): with self.assertRaises(sqlite.OperationalError): self.cu.execute("select asdf") - def test_execute_too_much_sql(self): - with self.assertRaises(sqlite.Warning): - self.cu.execute("select 5+4; select 4+5") + def test_execute_multiple_statements(self): + msg = "You can only execute one statement at a time" + dataset = ( + "select 1; select 2", + "select 1; // c++ comments are not allowed", + "select 1; *not a comment", + "select 1; -*not a comment", + "select 1; /* */ a", + "select 1; /**/a", + "select 1; -", + "select 1; /", + "select 1; -\n- select 2", + """select 1; + -- comment + select 2 + """, + ) + for query in dataset: + with self.subTest(query=query): + with self.assertRaisesRegex(sqlite.ProgrammingError, msg): + self.cu.execute(query) - def test_execute_too_much_sql2(self): - self.cu.execute("select 5+4; -- foo bar") - - def test_execute_too_much_sql3(self): - self.cu.execute(""" + def test_execute_with_appended_comments(self): + dataset = ( + "select 1; -- foo bar", + "select 1; --", + "select 1; /*", # Unclosed comments ending in \0 are skipped. + """ select 5+4; /* foo */ - """) + """, + ) + for query in dataset: + with self.subTest(query=query): + self.cu.execute(query) def test_execute_wrong_sql_arg(self): with self.assertRaises(TypeError): @@ -688,7 +811,7 @@ class CursorTests(unittest.TestCase): self.assertEqual(row[0], "Hu\x00go") def test_execute_non_iterable(self): - with self.assertRaises(ValueError) as cm: + with self.assertRaises(sqlite.ProgrammingError) as cm: self.cu.execute("insert into test(id) values (?)", 42) self.assertEqual(str(cm.exception), 'parameters are of unsupported type') @@ -802,6 +925,38 @@ class CursorTests(unittest.TestCase): self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)]) self.assertEqual(self.cu.rowcount, 3) + @unittest.skipIf(sqlite.sqlite_version_info < (3, 35, 0), + "Requires SQLite 3.35.0 or newer") + def test_rowcount_update_returning(self): + # gh-93421: rowcount is updated correctly for UPDATE...RETURNING queries + self.cu.execute("update test set name='bar' where name='foo' returning 1") + self.assertEqual(self.cu.fetchone()[0], 1) + self.assertEqual(self.cu.rowcount, 1) + + def test_rowcount_prefixed_with_comment(self): + # gh-79579: rowcount is updated even if query is prefixed with comments + self.cu.execute(""" + -- foo + insert into test(name) values ('foo'), ('foo') + """) + self.assertEqual(self.cu.rowcount, 2) + self.cu.execute(""" + /* -- messy *r /* /* ** *- *-- + */ + /* one more */ insert into test(name) values ('messy') + """) + self.assertEqual(self.cu.rowcount, 1) + self.cu.execute("/* bar */ update test set name='bar' where name='foo'") + self.assertEqual(self.cu.rowcount, 3) + + def test_rowcount_vaccuum(self): + data = ((1,), (2,), (3,)) + self.cu.executemany("insert into test(income) values(?)", data) + self.assertEqual(self.cu.rowcount, 3) + self.cx.commit() + self.cu.execute("vacuum") + self.assertEqual(self.cu.rowcount, -1) + def test_total_changes(self): self.cu.execute("insert into test(name) values ('foo')") self.cu.execute("insert into test(name) values ('foo')") @@ -989,11 +1144,327 @@ class CursorTests(unittest.TestCase): self.assertEqual(cu.fetchall(), [(1,)]) +class BlobTests(unittest.TestCase): + def setUp(self): + self.cx = sqlite.connect(":memory:") + self.cx.execute("create table test(b blob)") + self.data = b"this blob data string is exactly fifty bytes long!" + self.cx.execute("insert into test(b) values (?)", (self.data,)) + self.blob = self.cx.blobopen("test", "b", 1) + + def tearDown(self): + self.blob.close() + self.cx.close() + + def test_blob_is_a_blob(self): + self.assertIsInstance(self.blob, sqlite.Blob) + + def test_blob_seek_and_tell(self): + self.blob.seek(10) + self.assertEqual(self.blob.tell(), 10) + + self.blob.seek(10, SEEK_SET) + self.assertEqual(self.blob.tell(), 10) + + self.blob.seek(10, SEEK_CUR) + self.assertEqual(self.blob.tell(), 20) + + self.blob.seek(-10, SEEK_END) + self.assertEqual(self.blob.tell(), 40) + + def test_blob_seek_error(self): + msg_oor = "offset out of blob range" + msg_orig = "'origin' should be os.SEEK_SET, os.SEEK_CUR, or os.SEEK_END" + msg_of = "seek offset results in overflow" + + dataset = ( + (ValueError, msg_oor, lambda: self.blob.seek(1000)), + (ValueError, msg_oor, lambda: self.blob.seek(-10)), + (ValueError, msg_orig, lambda: self.blob.seek(10, -1)), + (ValueError, msg_orig, lambda: self.blob.seek(10, 3)), + ) + for exc, msg, fn in dataset: + with self.subTest(exc=exc, msg=msg, fn=fn): + self.assertRaisesRegex(exc, msg, fn) + + # Force overflow errors + self.blob.seek(1, SEEK_SET) + with self.assertRaisesRegex(OverflowError, msg_of): + self.blob.seek(INT_MAX, SEEK_CUR) + with self.assertRaisesRegex(OverflowError, msg_of): + self.blob.seek(INT_MAX, SEEK_END) + + def test_blob_read(self): + buf = self.blob.read() + self.assertEqual(buf, self.data) + + def test_blob_read_oversized(self): + buf = self.blob.read(len(self.data) * 2) + self.assertEqual(buf, self.data) + + def test_blob_read_advance_offset(self): + n = 10 + buf = self.blob.read(n) + self.assertEqual(buf, self.data[:n]) + self.assertEqual(self.blob.tell(), n) + + def test_blob_read_at_offset(self): + self.blob.seek(10) + self.assertEqual(self.blob.read(10), self.data[10:20]) + + def test_blob_read_error_row_changed(self): + self.cx.execute("update test set b='aaaa' where rowid=1") + with self.assertRaises(sqlite.OperationalError): + self.blob.read() + + def test_blob_write(self): + new_data = b"new data".ljust(50) + self.blob.write(new_data) + row = self.cx.execute("select b from test").fetchone() + self.assertEqual(row[0], new_data) + + def test_blob_write_at_offset(self): + new_data = b"c" * 25 + self.blob.seek(25) + self.blob.write(new_data) + row = self.cx.execute("select b from test").fetchone() + self.assertEqual(row[0], self.data[:25] + new_data) + + def test_blob_write_advance_offset(self): + self.blob.write(b"d"*10) + self.assertEqual(self.blob.tell(), 10) + + def test_blob_write_error_length(self): + with self.assertRaisesRegex(ValueError, "data longer than blob"): + self.blob.write(b"a" * 1000) + + self.blob.seek(0, SEEK_SET) + n = len(self.blob) + self.blob.write(b"a" * (n-1)) + self.blob.write(b"a") + with self.assertRaisesRegex(ValueError, "data longer than blob"): + self.blob.write(b"a") + + def test_blob_write_error_row_changed(self): + self.cx.execute("update test set b='aaaa' where rowid=1") + with self.assertRaises(sqlite.OperationalError): + self.blob.write(b"aaa") + + def test_blob_write_error_readonly(self): + ro_blob = self.cx.blobopen("test", "b", 1, readonly=True) + with self.assertRaisesRegex(sqlite.OperationalError, "readonly"): + ro_blob.write(b"aaa") + ro_blob.close() + + def test_blob_open_error(self): + dataset = ( + (("test", "b", 1), {"name": "notexisting"}), + (("notexisting", "b", 1), {}), + (("test", "notexisting", 1), {}), + (("test", "b", 2), {}), + ) + regex = "no such" + for args, kwds in dataset: + with self.subTest(args=args, kwds=kwds): + with self.assertRaisesRegex(sqlite.OperationalError, regex): + self.cx.blobopen(*args, **kwds) + + def test_blob_length(self): + self.assertEqual(len(self.blob), 50) + + def test_blob_get_item(self): + self.assertEqual(self.blob[5], ord("b")) + self.assertEqual(self.blob[6], ord("l")) + self.assertEqual(self.blob[7], ord("o")) + self.assertEqual(self.blob[8], ord("b")) + self.assertEqual(self.blob[-1], ord("!")) + + def test_blob_set_item(self): + self.blob[0] = ord("b") + expected = b"b" + self.data[1:] + actual = self.cx.execute("select b from test").fetchone()[0] + self.assertEqual(actual, expected) + + def test_blob_set_item_with_offset(self): + self.blob.seek(0, SEEK_END) + self.assertEqual(self.blob.read(), b"") # verify that we're at EOB + self.blob[0] = ord("T") + self.blob[-1] = ord(".") + self.blob.seek(0, SEEK_SET) + expected = b"This blob data string is exactly fifty bytes long." + self.assertEqual(self.blob.read(), expected) + + def test_blob_set_slice_buffer_object(self): + from array import array + self.blob[0:5] = memoryview(b"12345") + self.assertEqual(self.blob[0:5], b"12345") + + self.blob[0:5] = bytearray(b"23456") + self.assertEqual(self.blob[0:5], b"23456") + + self.blob[0:5] = array("b", [1, 2, 3, 4, 5]) + self.assertEqual(self.blob[0:5], b"\x01\x02\x03\x04\x05") + + def test_blob_set_item_negative_index(self): + self.blob[-1] = 255 + self.assertEqual(self.blob[-1], 255) + + def test_blob_get_slice(self): + self.assertEqual(self.blob[5:14], b"blob data") + + def test_blob_get_empty_slice(self): + self.assertEqual(self.blob[5:5], b"") + + def test_blob_get_slice_negative_index(self): + self.assertEqual(self.blob[5:-5], self.data[5:-5]) + + def test_blob_get_slice_with_skip(self): + self.assertEqual(self.blob[0:10:2], b"ti lb") + + def test_blob_set_slice(self): + self.blob[0:5] = b"12345" + expected = b"12345" + self.data[5:] + actual = self.cx.execute("select b from test").fetchone()[0] + self.assertEqual(actual, expected) + + def test_blob_set_empty_slice(self): + self.blob[0:0] = b"" + self.assertEqual(self.blob[:], self.data) + + def test_blob_set_slice_with_skip(self): + self.blob[0:10:2] = b"12345" + actual = self.cx.execute("select b from test").fetchone()[0] + expected = b"1h2s3b4o5 " + self.data[10:] + self.assertEqual(actual, expected) + + def test_blob_mapping_invalid_index_type(self): + msg = "indices must be integers" + with self.assertRaisesRegex(TypeError, msg): + self.blob[5:5.5] + with self.assertRaisesRegex(TypeError, msg): + self.blob[1.5] + with self.assertRaisesRegex(TypeError, msg): + self.blob["a"] = b"b" + + def test_blob_get_item_error(self): + dataset = [len(self.blob), 105, -105] + for idx in dataset: + with self.subTest(idx=idx): + with self.assertRaisesRegex(IndexError, "index out of range"): + self.blob[idx] + with self.assertRaisesRegex(IndexError, "cannot fit 'int'"): + self.blob[ULLONG_MAX] + + # Provoke read error + self.cx.execute("update test set b='aaaa' where rowid=1") + with self.assertRaises(sqlite.OperationalError): + self.blob[0] + + def test_blob_set_item_error(self): + with self.assertRaisesRegex(TypeError, "cannot be interpreted"): + self.blob[0] = b"multiple" + with self.assertRaisesRegex(TypeError, "cannot be interpreted"): + self.blob[0] = b"1" + with self.assertRaisesRegex(TypeError, "cannot be interpreted"): + self.blob[0] = bytearray(b"1") + with self.assertRaisesRegex(TypeError, "doesn't support.*deletion"): + del self.blob[0] + with self.assertRaisesRegex(IndexError, "Blob index out of range"): + self.blob[1000] = 0 + with self.assertRaisesRegex(ValueError, "must be in range"): + self.blob[0] = -1 + with self.assertRaisesRegex(ValueError, "must be in range"): + self.blob[0] = 256 + # Overflow errors are overridden with ValueError + with self.assertRaisesRegex(ValueError, "must be in range"): + self.blob[0] = 2**65 + + def test_blob_set_slice_error(self): + with self.assertRaisesRegex(IndexError, "wrong size"): + self.blob[5:10] = b"a" + with self.assertRaisesRegex(IndexError, "wrong size"): + self.blob[5:10] = b"a" * 1000 + with self.assertRaisesRegex(TypeError, "doesn't support.*deletion"): + del self.blob[5:10] + with self.assertRaisesRegex(ValueError, "step cannot be zero"): + self.blob[5:10:0] = b"12345" + with self.assertRaises(BufferError): + self.blob[5:10] = memoryview(b"abcde")[::2] + + def test_blob_sequence_not_supported(self): + with self.assertRaisesRegex(TypeError, "unsupported operand"): + self.blob + self.blob + with self.assertRaisesRegex(TypeError, "unsupported operand"): + self.blob * 5 + with self.assertRaisesRegex(TypeError, "is not iterable"): + b"a" in self.blob + + def test_blob_context_manager(self): + data = b"a" * 50 + with self.cx.blobopen("test", "b", 1) as blob: + blob.write(data) + actual = self.cx.execute("select b from test").fetchone()[0] + self.assertEqual(actual, data) + + # Check that __exit__ closed the blob + with self.assertRaisesRegex(sqlite.ProgrammingError, "closed blob"): + blob.read() + + def test_blob_context_manager_reraise_exceptions(self): + class DummyException(Exception): + pass + with self.assertRaisesRegex(DummyException, "reraised"): + with self.cx.blobopen("test", "b", 1) as blob: + raise DummyException("reraised") + + + def test_blob_closed(self): + with memory_database() as cx: + cx.execute("create table test(b blob)") + cx.execute("insert into test values (zeroblob(100))") + blob = cx.blobopen("test", "b", 1) + blob.close() + + msg = "Cannot operate on a closed blob" + with self.assertRaisesRegex(sqlite.ProgrammingError, msg): + blob.read() + with self.assertRaisesRegex(sqlite.ProgrammingError, msg): + blob.write(b"") + with self.assertRaisesRegex(sqlite.ProgrammingError, msg): + blob.seek(0) + with self.assertRaisesRegex(sqlite.ProgrammingError, msg): + blob.tell() + with self.assertRaisesRegex(sqlite.ProgrammingError, msg): + blob.__enter__() + with self.assertRaisesRegex(sqlite.ProgrammingError, msg): + blob.__exit__(None, None, None) + with self.assertRaisesRegex(sqlite.ProgrammingError, msg): + len(blob) + with self.assertRaisesRegex(sqlite.ProgrammingError, msg): + blob[0] + with self.assertRaisesRegex(sqlite.ProgrammingError, msg): + blob[0:1] + with self.assertRaisesRegex(sqlite.ProgrammingError, msg): + blob[0] = b"" + + def test_blob_closed_db_read(self): + with memory_database() as cx: + cx.execute("create table test(b blob)") + cx.execute("insert into test(b) values (zeroblob(100))") + blob = cx.blobopen("test", "b", 1) + cx.close() + self.assertRaisesRegex(sqlite.ProgrammingError, + "Cannot operate on a closed database", + blob.read) + + +@threading_helper.requires_working_threading() class ThreadTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") self.cur = self.con.cursor() - self.cur.execute("create table test(name text)") + self.cur.execute("create table test(name text, b blob)") + self.cur.execute("insert into test values('blob', zeroblob(1))") def tearDown(self): self.cur.close() @@ -1028,7 +1499,14 @@ class ThreadTests(unittest.TestCase): lambda: self.con.create_collation("foo", None), lambda: self.con.setlimit(sqlite.SQLITE_LIMIT_LENGTH, -1), lambda: self.con.getlimit(sqlite.SQLITE_LIMIT_LENGTH), + lambda: self.con.blobopen("test", "b", 1), ] + if hasattr(sqlite.Connection, "serialize"): + fns.append(lambda: self.con.serialize()) + fns.append(lambda: self.con.deserialize(b"")) + if sqlite.sqlite_version_info >= (3, 25, 0): + fns.append(lambda: self.con.create_window_function("foo", 0, None)) + for fn in fns: with self.subTest(fn=fn): self._run_test(fn) @@ -1345,6 +1823,7 @@ class SqliteOnConflictTests(unittest.TestCase): self.assertEqual(self.cu.fetchall(), [('Very different data!', 'foo')]) +@requires_subprocess() class MultiprocessTests(unittest.TestCase): CONNECTION_TIMEOUT = SHORT_TIMEOUT / 1000. # Defaults to 30 ms diff --git a/Lib/test/test_sqlite3/test_dump.py b/Lib/test/test_sqlite3/test_dump.py index 1f14c620f0d..d0c24b9c60e 100644 --- a/Lib/test/test_sqlite3/test_dump.py +++ b/Lib/test/test_sqlite3/test_dump.py @@ -2,6 +2,8 @@ import unittest import sqlite3 as sqlite +from .test_dbapi import memory_database + class DumpTests(unittest.TestCase): def setUp(self): @@ -49,6 +51,51 @@ class DumpTests(unittest.TestCase): [self.assertEqual(expected_sqls[i], actual_sqls[i]) for i in range(len(expected_sqls))] + def test_dump_autoincrement(self): + expected = [ + 'CREATE TABLE "t1" (id integer primary key autoincrement);', + 'INSERT INTO "t1" VALUES(NULL);', + 'CREATE TABLE "t2" (id integer primary key autoincrement);', + ] + self.cu.executescript("".join(expected)) + + # the NULL value should now be automatically be set to 1 + expected[1] = expected[1].replace("NULL", "1") + expected.insert(0, "BEGIN TRANSACTION;") + expected.extend([ + 'DELETE FROM "sqlite_sequence";', + 'INSERT INTO "sqlite_sequence" VALUES(\'t1\',1);', + 'COMMIT;', + ]) + + actual = [stmt for stmt in self.cx.iterdump()] + self.assertEqual(expected, actual) + + def test_dump_autoincrement_create_new_db(self): + self.cu.execute("BEGIN TRANSACTION") + self.cu.execute("CREATE TABLE t1 (id integer primary key autoincrement)") + self.cu.execute("CREATE TABLE t2 (id integer primary key autoincrement)") + self.cu.executemany("INSERT INTO t1 VALUES(?)", ((None,) for _ in range(9))) + self.cu.executemany("INSERT INTO t2 VALUES(?)", ((None,) for _ in range(4))) + self.cx.commit() + + with memory_database() as cx2: + query = "".join(self.cx.iterdump()) + cx2.executescript(query) + cu2 = cx2.cursor() + + dataset = ( + ("t1", 9), + ("t2", 4), + ) + for table, seq in dataset: + with self.subTest(table=table, seq=seq): + res = cu2.execute(""" + SELECT "seq" FROM "sqlite_sequence" WHERE "name" == ? + """, (table,)) + rows = res.fetchall() + self.assertEqual(rows[0][0], seq) + def test_unorderable_row(self): # iterdump() should be able to cope with unorderable row types (issue #15545) class UnorderableRow: diff --git a/Lib/test/test_sqlite3/test_factory.py b/Lib/test/test_sqlite3/test_factory.py index 420855ba34b..7c36135ecad 100644 --- a/Lib/test/test_sqlite3/test_factory.py +++ b/Lib/test/test_sqlite3/test_factory.py @@ -50,6 +50,26 @@ class ConnectionFactoryTests(unittest.TestCase): con = sqlite.connect(":memory:", factory=factory) self.assertIsInstance(con, factory) + def test_connection_factory_relayed_call(self): + # gh-95132: keyword args must not be passed as positional args + class Factory(sqlite.Connection): + def __init__(self, *args, **kwargs): + kwargs["isolation_level"] = None + super(Factory, self).__init__(*args, **kwargs) + + con = sqlite.connect(":memory:", factory=Factory) + self.assertIsNone(con.isolation_level) + self.assertIsInstance(con, Factory) + + def test_connection_factory_as_positional_arg(self): + class Factory(sqlite.Connection): + def __init__(self, *args, **kwargs): + super(Factory, self).__init__(*args, **kwargs) + + con = sqlite.connect(":memory:", 5.0, 0, None, True, Factory) + self.assertIsNone(con.isolation_level) + self.assertIsInstance(con, Factory) + class CursorFactoryTests(unittest.TestCase): def setUp(self): @@ -159,8 +179,14 @@ class RowFactoryTests(unittest.TestCase): """Checks if the row object is iterable""" self.con.row_factory = sqlite.Row row = self.con.execute("select 1 as a, 2 as b").fetchone() - for col in row: - pass + + # Is iterable in correct order and produces valid results: + items = [col for col in row] + self.assertEqual(items, [1, 2]) + + # Is iterable the second time: + items = [col for col in row] + self.assertEqual(items, [1, 2]) def test_sqlite_row_as_tuple(self): """Checks if the row object can be converted to a tuple""" @@ -256,18 +282,6 @@ class TextFactoryTests(unittest.TestCase): self.assertEqual(type(row[0]), str, "type of row[0] must be unicode") self.assertTrue(row[0].endswith("reich"), "column must contain original data") - def test_optimized_unicode(self): - # OptimizedUnicode is deprecated as of Python 3.10 - with self.assertWarns(DeprecationWarning) as cm: - self.con.text_factory = sqlite.OptimizedUnicode - self.assertIn("factory.py", cm.filename) - austria = "Österreich" - germany = "Deutchland" - a_row = self.con.execute("select ?", (austria,)).fetchone() - d_row = self.con.execute("select ?", (germany,)).fetchone() - self.assertEqual(type(a_row[0]), str, "type of non-ASCII row must be str") - self.assertEqual(type(d_row[0]), str, "type of ASCII-only row must be str") - def tearDown(self): self.con.close() diff --git a/Lib/test/test_sqlite3/test_hooks.py b/Lib/test/test_sqlite3/test_hooks.py index bf454b2aa88..21042b9bf10 100644 --- a/Lib/test/test_sqlite3/test_hooks.py +++ b/Lib/test/test_sqlite3/test_hooks.py @@ -20,11 +20,15 @@ # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. -import unittest +import contextlib import sqlite3 as sqlite +import unittest from test.support.os_helper import TESTFN, unlink -from .test_userfunctions import with_tracebacks + +from test.test_sqlite3.test_dbapi import memory_database, cx_limit +from test.test_sqlite3.test_userfunctions import with_tracebacks + class CollationTests(unittest.TestCase): def test_create_collation_not_string(self): @@ -197,7 +201,7 @@ class ProgressTests(unittest.TestCase): con.execute("select 1 union select 2 union select 3").fetchall() self.assertEqual(action, 0, "progress handler was not cleared") - @with_tracebacks(['bad_progress', 'ZeroDivisionError']) + @with_tracebacks(ZeroDivisionError, name="bad_progress") def test_error_in_progress_handler(self): con = sqlite.connect(":memory:") def bad_progress(): @@ -208,7 +212,7 @@ class ProgressTests(unittest.TestCase): create table foo(a, b) """) - @with_tracebacks(['__bool__', 'ZeroDivisionError']) + @with_tracebacks(ZeroDivisionError, name="bad_progress") def test_error_in_progress_handler_result(self): con = sqlite.connect(":memory:") class BadBool: @@ -224,6 +228,16 @@ class ProgressTests(unittest.TestCase): class TraceCallbackTests(unittest.TestCase): + @contextlib.contextmanager + def check_stmt_trace(self, cx, expected): + try: + traced = [] + cx.set_trace_callback(lambda stmt: traced.append(stmt)) + yield + finally: + self.assertEqual(traced, expected) + cx.set_trace_callback(None) + def test_trace_callback_used(self): """ Test that the trace callback is invoked once it is set. @@ -289,6 +303,52 @@ class TraceCallbackTests(unittest.TestCase): con2.close() self.assertEqual(traced_statements, queries) + def test_trace_expanded_sql(self): + expected = [ + "create table t(t)", + "BEGIN ", + "insert into t values(0)", + "insert into t values(1)", + "insert into t values(2)", + "COMMIT", + ] + with memory_database() as cx, self.check_stmt_trace(cx, expected): + with cx: + cx.execute("create table t(t)") + cx.executemany("insert into t values(?)", ((v,) for v in range(3))) + + @with_tracebacks( + sqlite.DataError, + regex="Expanded SQL string exceeds the maximum string length" + ) + def test_trace_too_much_expanded_sql(self): + # If the expanded string is too large, we'll fall back to the + # unexpanded SQL statement (for SQLite 3.14.0 and newer). + # The resulting string length is limited by the runtime limit + # SQLITE_LIMIT_LENGTH. + template = "select 1 as a where a=" + category = sqlite.SQLITE_LIMIT_LENGTH + with memory_database() as cx, cx_limit(cx, category=category) as lim: + ok_param = "a" + bad_param = "a" * lim + + unexpanded_query = template + "?" + expected = [unexpanded_query] + if sqlite.sqlite_version_info < (3, 14, 0): + expected = [] + with self.check_stmt_trace(cx, expected): + cx.execute(unexpanded_query, (bad_param,)) + + expanded_query = f"{template}'{ok_param}'" + with self.check_stmt_trace(cx, [expanded_query]): + cx.execute(unexpanded_query, (ok_param,)) + + @with_tracebacks(ZeroDivisionError, regex="division by zero") + def test_trace_bad_handler(self): + with memory_database() as cx: + cx.set_trace_callback(lambda stmt: 5/0) + cx.execute("select 1") + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_sqlite3/test_regression.py b/Lib/test/test_sqlite3/test_regression.py index eb34069d3e5..ad83a97c8c4 100644 --- a/Lib/test/test_sqlite3/test_regression.py +++ b/Lib/test/test_sqlite3/test_regression.py @@ -21,14 +21,14 @@ # 3. This notice may not be removed or altered from any source distribution. import datetime -import sys import unittest import sqlite3 as sqlite import weakref import functools -from test import support -from .test_dbapi import memory_database, managed_connect, cx_limit +from test import support +from unittest.mock import patch +from test.test_sqlite3.test_dbapi import memory_database, cx_limit class RegressionTests(unittest.TestCase): @@ -129,7 +129,8 @@ class RegressionTests(unittest.TestCase): con = sqlite.connect(":memory:",detect_types=sqlite.PARSE_DECLTYPES) cur = con.cursor() cur.execute("create table foo(bar timestamp)") - cur.execute("insert into foo(bar) values (?)", (datetime.datetime.now(),)) + with self.assertWarnsRegex(DeprecationWarning, "adapter"): + cur.execute("insert into foo(bar) values (?)", (datetime.datetime.now(),)) cur.execute(SELECT) cur.execute("drop table foo") cur.execute("create table foo(bar integer)") @@ -231,28 +232,6 @@ class RegressionTests(unittest.TestCase): with self.assertRaises(sqlite.ProgrammingError): cur = con.cursor() - def test_cursor_registration(self): - """ - Verifies that subclassed cursor classes are correctly registered with - the connection object, too. (fetch-across-rollback problem) - """ - class Connection(sqlite.Connection): - def cursor(self): - return Cursor(self) - - class Cursor(sqlite.Cursor): - def __init__(self, con): - sqlite.Cursor.__init__(self, con) - - con = Connection(":memory:") - cur = con.cursor() - cur.execute("create table foo(x)") - cur.executemany("insert into foo(x) values (?)", [(3,), (4,), (5,)]) - cur.execute("select x from foo") - con.rollback() - with self.assertRaises(sqlite.InterfaceError): - cur.fetchall() - def test_auto_commit(self): """ Verifies that creating a connection in autocommit mode works. @@ -327,7 +306,8 @@ class RegressionTests(unittest.TestCase): cur.execute("INSERT INTO t (x) VALUES ('2012-04-04 15:06:00.123456789')") cur.execute("SELECT * FROM t") - values = [x[0] for x in cur.fetchall()] + with self.assertWarnsRegex(DeprecationWarning, "converter"): + values = [x[0] for x in cur.fetchall()] self.assertEqual(values, [ datetime.datetime(2012, 4, 4, 15, 6, 0, 456000), @@ -342,12 +322,15 @@ class RegressionTests(unittest.TestCase): def test_null_character(self): # Issue #21147 - con = sqlite.connect(":memory:") - self.assertRaises(ValueError, con, "\0select 1") - self.assertRaises(ValueError, con, "select 1\0") - cur = con.cursor() - self.assertRaises(ValueError, cur.execute, " \0select 2") - self.assertRaises(ValueError, cur.execute, "select 2\0") + cur = self.con.cursor() + queries = ["\0select 1", "select 1\0"] + for query in queries: + with self.subTest(query=query): + self.assertRaisesRegex(sqlite.ProgrammingError, "null char", + self.con.execute, query) + with self.subTest(query=query): + self.assertRaisesRegex(sqlite.ProgrammingError, "null char", + cur.execute, query) def test_surrogates(self): con = sqlite.connect(":memory:") @@ -441,7 +424,7 @@ class RegressionTests(unittest.TestCase): self.assertEqual(val, b'') def test_table_lock_cursor_replace_stmt(self): - with managed_connect(":memory:", in_mem=True) as con: + with memory_database() as con: cur = con.cursor() cur.execute("create table t(t)") cur.executemany("insert into t values(?)", @@ -452,7 +435,7 @@ class RegressionTests(unittest.TestCase): con.commit() def test_table_lock_cursor_dealloc(self): - with managed_connect(":memory:", in_mem=True) as con: + with memory_database() as con: con.execute("create table t(t)") con.executemany("insert into t values(?)", ((v,) for v in range(5))) @@ -463,7 +446,7 @@ class RegressionTests(unittest.TestCase): con.commit() def test_table_lock_cursor_non_readonly_select(self): - with managed_connect(":memory:", in_mem=True) as con: + with memory_database() as con: con.execute("create table t(t)") con.executemany("insert into t values(?)", ((v,) for v in range(5))) @@ -478,7 +461,7 @@ class RegressionTests(unittest.TestCase): con.commit() def test_executescript_step_through_select(self): - with managed_connect(":memory:", in_mem=True) as con: + with memory_database() as con: values = [(v,) for v in range(5)] with con: con.execute("create table t(t)") @@ -489,5 +472,43 @@ class RegressionTests(unittest.TestCase): self.assertEqual(steps, values) +class RecursiveUseOfCursors(unittest.TestCase): + # GH-80254: sqlite3 should not segfault for recursive use of cursors. + msg = "Recursive use of cursors not allowed" + + def setUp(self): + self.con = sqlite.connect(":memory:", + detect_types=sqlite.PARSE_COLNAMES) + self.cur = self.con.cursor() + self.cur.execute("create table test(x foo)") + self.cur.executemany("insert into test(x) values (?)", + [("foo",), ("bar",)]) + + def tearDown(self): + self.cur.close() + self.con.close() + + def test_recursive_cursor_init(self): + conv = lambda x: self.cur.__init__(self.con) + with patch.dict(sqlite.converters, {"INIT": conv}): + self.cur.execute(f'select x as "x [INIT]", x from test') + self.assertRaisesRegex(sqlite.ProgrammingError, self.msg, + self.cur.fetchall) + + def test_recursive_cursor_close(self): + conv = lambda x: self.cur.close() + with patch.dict(sqlite.converters, {"CLOSE": conv}): + self.cur.execute(f'select x as "x [CLOSE]", x from test') + self.assertRaisesRegex(sqlite.ProgrammingError, self.msg, + self.cur.fetchall) + + def test_recursive_cursor_iter(self): + conv = lambda x, l=[]: self.cur.fetchone() if l else l.append(None) + with patch.dict(sqlite.converters, {"ITER": conv}): + self.cur.execute(f'select x as "x [ITER]", x from test') + self.assertRaisesRegex(sqlite.ProgrammingError, self.msg, + self.cur.fetchall) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_sqlite3/test_transactions.py b/Lib/test/test_sqlite3/test_transactions.py index 3efa2c1e604..5d211dd47b0 100644 --- a/Lib/test/test_sqlite3/test_transactions.py +++ b/Lib/test/test_sqlite3/test_transactions.py @@ -20,38 +20,38 @@ # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. -import os, unittest +import unittest import sqlite3 as sqlite +from contextlib import contextmanager -from .test_dbapi import memory_database +from test.support import LOOPBACK_TIMEOUT +from test.support.os_helper import TESTFN, unlink +from test.support.script_helper import assert_python_ok + +from test.test_sqlite3.test_dbapi import memory_database + + +TIMEOUT = LOOPBACK_TIMEOUT / 10 -def get_db_path(): - return "sqlite_testdb" class TransactionTests(unittest.TestCase): def setUp(self): - try: - os.remove(get_db_path()) - except OSError: - pass - - self.con1 = sqlite.connect(get_db_path(), timeout=0.1) + self.con1 = sqlite.connect(TESTFN, timeout=TIMEOUT) self.cur1 = self.con1.cursor() - self.con2 = sqlite.connect(get_db_path(), timeout=0.1) + self.con2 = sqlite.connect(TESTFN, timeout=TIMEOUT) self.cur2 = self.con2.cursor() def tearDown(self): - self.cur1.close() - self.con1.close() - - self.cur2.close() - self.con2.close() - try: - os.unlink(get_db_path()) - except OSError: - pass + self.cur1.close() + self.con1.close() + + self.cur2.close() + self.con2.close() + + finally: + unlink(TESTFN) def test_dml_does_not_auto_commit_before(self): self.cur1.execute("create table test(i)") @@ -131,10 +131,7 @@ class TransactionTests(unittest.TestCase): self.con1.commit() def test_rollback_cursor_consistency(self): - """ - Checks if cursors on the connection are set into a "reset" state - when a rollback is done on the connection. - """ + """Check that cursors behave correctly after rollback.""" con = sqlite.connect(":memory:") cur = con.cursor() cur.execute("create table test(x)") @@ -142,8 +139,83 @@ class TransactionTests(unittest.TestCase): cur.execute("select 1 union select 2 union select 3") con.rollback() - with self.assertRaises(sqlite.InterfaceError): - cur.fetchall() + self.assertEqual(cur.fetchall(), [(1,), (2,), (3,)]) + + def test_multiple_cursors_and_iternext(self): + # gh-94028: statements are cleared and reset in cursor iternext. + + # Provoke the gh-94028 by using a cursor cache. + CURSORS = {} + def sql(cx, sql, *args): + cu = cx.cursor() + cu.execute(sql, args) + CURSORS[id(sql)] = cu + return cu + + self.con1.execute("create table t(t)") + sql(self.con1, "insert into t values (?), (?), (?)", "u1", "u2", "u3") + self.con1.commit() + + # On second connection, verify rows are visible, then delete them. + count = sql(self.con2, "select count(*) from t").fetchone()[0] + self.assertEqual(count, 3) + changes = sql(self.con2, "delete from t").rowcount + self.assertEqual(changes, 3) + self.con2.commit() + + # Back in original connection, create 2 new users. + sql(self.con1, "insert into t values (?)", "u4") + sql(self.con1, "insert into t values (?)", "u5") + + # The second connection cannot see uncommitted changes. + count = sql(self.con2, "select count(*) from t").fetchone()[0] + self.assertEqual(count, 0) + + # First connection can see its own changes. + count = sql(self.con1, "select count(*) from t").fetchone()[0] + self.assertEqual(count, 2) + + # The second connection can now see the changes. + self.con1.commit() + count = sql(self.con2, "select count(*) from t").fetchone()[0] + self.assertEqual(count, 2) + + +class RollbackTests(unittest.TestCase): + """bpo-44092: sqlite3 now leaves it to SQLite to resolve rollback issues""" + + def setUp(self): + self.con = sqlite.connect(":memory:") + self.cur1 = self.con.cursor() + self.cur2 = self.con.cursor() + with self.con: + self.con.execute("create table t(c)"); + self.con.executemany("insert into t values(?)", [(0,), (1,), (2,)]) + self.cur1.execute("begin transaction") + select = "select c from t" + self.cur1.execute(select) + self.con.rollback() + self.res = self.cur2.execute(select) # Reusing stmt from cache + + def tearDown(self): + self.con.close() + + def _check_rows(self): + for i, row in enumerate(self.res): + self.assertEqual(row[0], i) + + def test_no_duplicate_rows_after_rollback_del_cursor(self): + del self.cur1 + self._check_rows() + + def test_no_duplicate_rows_after_rollback_close_cursor(self): + self.cur1.close() + self._check_rows() + + def test_no_duplicate_rows_after_rollback_new_query(self): + self.cur1.execute("select c from t where c = 1") + self._check_rows() + class SpecialCommandTests(unittest.TestCase): @@ -296,5 +368,176 @@ class IsolationLevelPostInit(unittest.TestCase): self.assertEqual(self.traced, [self.QUERY]) +class AutocommitAttribute(unittest.TestCase): + """Test PEP 249-compliant autocommit behaviour.""" + legacy = sqlite.LEGACY_TRANSACTION_CONTROL + + @contextmanager + def check_stmt_trace(self, cx, expected, reset=True): + try: + traced = [] + cx.set_trace_callback(lambda stmt: traced.append(stmt)) + yield + finally: + self.assertEqual(traced, expected) + if reset: + cx.set_trace_callback(None) + + def test_autocommit_default(self): + with memory_database() as cx: + self.assertEqual(cx.autocommit, + sqlite.LEGACY_TRANSACTION_CONTROL) + + def test_autocommit_setget(self): + dataset = ( + True, + False, + sqlite.LEGACY_TRANSACTION_CONTROL, + ) + for mode in dataset: + with self.subTest(mode=mode): + with memory_database(autocommit=mode) as cx: + self.assertEqual(cx.autocommit, mode) + with memory_database() as cx: + cx.autocommit = mode + self.assertEqual(cx.autocommit, mode) + + def test_autocommit_setget_invalid(self): + msg = "autocommit must be True, False, or.*LEGACY" + for mode in "a", 12, (), None: + with self.subTest(mode=mode): + with self.assertRaisesRegex(ValueError, msg): + sqlite.connect(":memory:", autocommit=mode) + + def test_autocommit_disabled(self): + expected = [ + "SELECT 1", + "COMMIT", + "BEGIN", + "ROLLBACK", + "BEGIN", + ] + with memory_database(autocommit=False) as cx: + self.assertTrue(cx.in_transaction) + with self.check_stmt_trace(cx, expected): + cx.execute("SELECT 1") + cx.commit() + cx.rollback() + + def test_autocommit_disabled_implicit_rollback(self): + expected = ["ROLLBACK"] + with memory_database(autocommit=False) as cx: + self.assertTrue(cx.in_transaction) + with self.check_stmt_trace(cx, expected, reset=False): + cx.close() + + def test_autocommit_enabled(self): + expected = ["CREATE TABLE t(t)", "INSERT INTO t VALUES(1)"] + with memory_database(autocommit=True) as cx: + self.assertFalse(cx.in_transaction) + with self.check_stmt_trace(cx, expected): + cx.execute("CREATE TABLE t(t)") + cx.execute("INSERT INTO t VALUES(1)") + self.assertFalse(cx.in_transaction) + + def test_autocommit_enabled_txn_ctl(self): + for op in "commit", "rollback": + with self.subTest(op=op): + with memory_database(autocommit=True) as cx: + meth = getattr(cx, op) + self.assertFalse(cx.in_transaction) + with self.check_stmt_trace(cx, []): + meth() # expect this to pass silently + self.assertFalse(cx.in_transaction) + + def test_autocommit_disabled_then_enabled(self): + expected = ["COMMIT"] + with memory_database(autocommit=False) as cx: + self.assertTrue(cx.in_transaction) + with self.check_stmt_trace(cx, expected): + cx.autocommit = True # should commit + self.assertFalse(cx.in_transaction) + + def test_autocommit_enabled_then_disabled(self): + expected = ["BEGIN"] + with memory_database(autocommit=True) as cx: + self.assertFalse(cx.in_transaction) + with self.check_stmt_trace(cx, expected): + cx.autocommit = False # should begin + self.assertTrue(cx.in_transaction) + + def test_autocommit_explicit_then_disabled(self): + expected = ["BEGIN DEFERRED"] + with memory_database(autocommit=True) as cx: + self.assertFalse(cx.in_transaction) + with self.check_stmt_trace(cx, expected): + cx.execute("BEGIN DEFERRED") + cx.autocommit = False # should now be a no-op + self.assertTrue(cx.in_transaction) + + def test_autocommit_enabled_ctx_mgr(self): + with memory_database(autocommit=True) as cx: + # The context manager is a no-op if autocommit=True + with self.check_stmt_trace(cx, []): + with cx: + self.assertFalse(cx.in_transaction) + self.assertFalse(cx.in_transaction) + + def test_autocommit_disabled_ctx_mgr(self): + expected = ["COMMIT", "BEGIN"] + with memory_database(autocommit=False) as cx: + with self.check_stmt_trace(cx, expected): + with cx: + self.assertTrue(cx.in_transaction) + self.assertTrue(cx.in_transaction) + + def test_autocommit_compat_ctx_mgr(self): + expected = ["BEGIN ", "INSERT INTO T VALUES(1)", "COMMIT"] + with memory_database(autocommit=self.legacy) as cx: + cx.execute("create table t(t)") + with self.check_stmt_trace(cx, expected): + with cx: + self.assertFalse(cx.in_transaction) + cx.execute("INSERT INTO T VALUES(1)") + self.assertTrue(cx.in_transaction) + self.assertFalse(cx.in_transaction) + + def test_autocommit_enabled_executescript(self): + expected = ["BEGIN", "SELECT 1"] + with memory_database(autocommit=True) as cx: + with self.check_stmt_trace(cx, expected): + self.assertFalse(cx.in_transaction) + cx.execute("BEGIN") + cx.executescript("SELECT 1") + self.assertTrue(cx.in_transaction) + + def test_autocommit_disabled_executescript(self): + expected = ["SELECT 1"] + with memory_database(autocommit=False) as cx: + with self.check_stmt_trace(cx, expected): + self.assertTrue(cx.in_transaction) + cx.executescript("SELECT 1") + self.assertTrue(cx.in_transaction) + + def test_autocommit_compat_executescript(self): + expected = ["BEGIN", "COMMIT", "SELECT 1"] + with memory_database(autocommit=self.legacy) as cx: + with self.check_stmt_trace(cx, expected): + self.assertFalse(cx.in_transaction) + cx.execute("BEGIN") + cx.executescript("SELECT 1") + self.assertFalse(cx.in_transaction) + + def test_autocommit_disabled_implicit_shutdown(self): + # The implicit ROLLBACK should not call back into Python during + # interpreter tear-down. + code = """if 1: + import sqlite3 + cx = sqlite3.connect(":memory:", autocommit=False) + cx.set_trace_callback(print) + """ + assert_python_ok("-c", code, PYTHONIOENCODING="utf-8") + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_sqlite3/test_types.py b/Lib/test/test_sqlite3/test_types.py index 0cfb72c5f09..5e0ff353cbb 100644 --- a/Lib/test/test_sqlite3/test_types.py +++ b/Lib/test/test_sqlite3/test_types.py @@ -106,9 +106,9 @@ class SqliteTypeTests(unittest.TestCase): @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform') @support.bigmemtest(size=2**31, memuse=4, dry_run=False) def test_too_large_string(self, maxsize): - with self.assertRaises(sqlite.InterfaceError): + with self.assertRaises(sqlite.DataError): self.cur.execute("insert into test(s) values (?)", ('x'*(2**31-1),)) - with self.assertRaises(OverflowError): + with self.assertRaises(sqlite.DataError): self.cur.execute("insert into test(s) values (?)", ('x'*(2**31),)) self.cur.execute("select 1 from test") row = self.cur.fetchone() @@ -117,9 +117,9 @@ class SqliteTypeTests(unittest.TestCase): @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform') @support.bigmemtest(size=2**31, memuse=3, dry_run=False) def test_too_large_blob(self, maxsize): - with self.assertRaises(sqlite.InterfaceError): + with self.assertRaises(sqlite.DataError): self.cur.execute("insert into test(s) values (?)", (b'x'*(2**31-1),)) - with self.assertRaises(OverflowError): + with self.assertRaises(sqlite.DataError): self.cur.execute("insert into test(s) values (?)", (b'x'*(2**31),)) self.cur.execute("select 1 from test") row = self.cur.fetchone() @@ -255,9 +255,9 @@ class DeclTypesTests(unittest.TestCase): def test_error_in_conform(self): val = DeclTypesTests.BadConform(TypeError) - with self.assertRaises(sqlite.InterfaceError): + with self.assertRaises(sqlite.ProgrammingError): self.cur.execute("insert into test(bad) values (?)", (val,)) - with self.assertRaises(sqlite.InterfaceError): + with self.assertRaises(sqlite.ProgrammingError): self.cur.execute("insert into test(bad) values (:val)", {"val": val}) val = DeclTypesTests.BadConform(KeyboardInterrupt) @@ -269,13 +269,13 @@ class DeclTypesTests(unittest.TestCase): def test_unsupported_seq(self): class Bar: pass val = Bar() - with self.assertRaises(sqlite.InterfaceError): + with self.assertRaises(sqlite.ProgrammingError): self.cur.execute("insert into test(f) values (?)", (val,)) def test_unsupported_dict(self): class Bar: pass val = Bar() - with self.assertRaises(sqlite.InterfaceError): + with self.assertRaises(sqlite.ProgrammingError): self.cur.execute("insert into test(f) values (:val)", {"val": val}) def test_blob(self): @@ -496,38 +496,51 @@ class DateTimeTests(unittest.TestCase): def test_sqlite_date(self): d = sqlite.Date(2004, 2, 14) - self.cur.execute("insert into test(d) values (?)", (d,)) + with self.assertWarnsRegex(DeprecationWarning, "adapter") as cm: + self.cur.execute("insert into test(d) values (?)", (d,)) + self.assertEqual(cm.filename, __file__) self.cur.execute("select d from test") - d2 = self.cur.fetchone()[0] + with self.assertWarnsRegex(DeprecationWarning, "converter") as cm: + d2 = self.cur.fetchone()[0] + self.assertEqual(cm.filename, __file__) self.assertEqual(d, d2) def test_sqlite_timestamp(self): ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0) - self.cur.execute("insert into test(ts) values (?)", (ts,)) + with self.assertWarnsRegex(DeprecationWarning, "adapter") as cm: + self.cur.execute("insert into test(ts) values (?)", (ts,)) + self.assertEqual(cm.filename, __file__) self.cur.execute("select ts from test") - ts2 = self.cur.fetchone()[0] + with self.assertWarnsRegex(DeprecationWarning, "converter") as cm: + ts2 = self.cur.fetchone()[0] + self.assertEqual(cm.filename, __file__) self.assertEqual(ts, ts2) def test_sql_timestamp(self): now = datetime.datetime.utcnow() self.cur.execute("insert into test(ts) values (current_timestamp)") self.cur.execute("select ts from test") - ts = self.cur.fetchone()[0] + with self.assertWarnsRegex(DeprecationWarning, "converter"): + ts = self.cur.fetchone()[0] self.assertEqual(type(ts), datetime.datetime) self.assertEqual(ts.year, now.year) def test_date_time_sub_seconds(self): ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0, 500000) - self.cur.execute("insert into test(ts) values (?)", (ts,)) + with self.assertWarnsRegex(DeprecationWarning, "adapter"): + self.cur.execute("insert into test(ts) values (?)", (ts,)) self.cur.execute("select ts from test") - ts2 = self.cur.fetchone()[0] + with self.assertWarnsRegex(DeprecationWarning, "converter"): + ts2 = self.cur.fetchone()[0] self.assertEqual(ts, ts2) def test_date_time_sub_seconds_floating_point(self): ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0, 510241) - self.cur.execute("insert into test(ts) values (?)", (ts,)) + with self.assertWarnsRegex(DeprecationWarning, "adapter"): + self.cur.execute("insert into test(ts) values (?)", (ts,)) self.cur.execute("select ts from test") - ts2 = self.cur.fetchone()[0] + with self.assertWarnsRegex(DeprecationWarning, "converter"): + ts2 = self.cur.fetchone()[0] self.assertEqual(ts, ts2) diff --git a/Lib/test/test_sqlite3/test_userfunctions.py b/Lib/test/test_sqlite3/test_userfunctions.py index 62a11a5431b..0970b0378ad 100644 --- a/Lib/test/test_sqlite3/test_userfunctions.py +++ b/Lib/test/test_sqlite3/test_userfunctions.py @@ -23,48 +23,54 @@ import contextlib import functools -import gc import io +import re import sys import unittest -import unittest.mock import sqlite3 as sqlite -from test.support import bigmemtest -from .test_dbapi import cx_limit +from unittest.mock import Mock, patch +from test.support import bigmemtest, catch_unraisable_exception, gc_collect + +from test.test_sqlite3.test_dbapi import cx_limit -def with_tracebacks(strings, traceback=True): +def with_tracebacks(exc, regex="", name=""): """Convenience decorator for testing callback tracebacks.""" - if traceback: - strings.append('Traceback') - def decorator(func): + _regex = re.compile(regex) if regex else None @functools.wraps(func) def wrapper(self, *args, **kwargs): - # First, run the test with traceback enabled. - with check_tracebacks(self, strings): - func(self, *args, **kwargs) + with catch_unraisable_exception() as cm: + # First, run the test with traceback enabled. + with check_tracebacks(self, cm, exc, _regex, name): + func(self, *args, **kwargs) # Then run the test with traceback disabled. func(self, *args, **kwargs) return wrapper return decorator + @contextlib.contextmanager -def check_tracebacks(self, strings): +def check_tracebacks(self, cm, exc, regex, obj_name): """Convenience context manager for testing callback tracebacks.""" sqlite.enable_callback_tracebacks(True) try: buf = io.StringIO() with contextlib.redirect_stderr(buf): yield - tb = buf.getvalue() - for s in strings: - self.assertIn(s, tb) + + self.assertEqual(cm.unraisable.exc_type, exc) + if regex: + msg = str(cm.unraisable.exc_value) + self.assertIsNotNone(regex.search(msg)) + if obj_name: + self.assertEqual(cm.unraisable.object.__name__, obj_name) finally: sqlite.enable_callback_tracebacks(False) + def func_returntext(): return "foo" def func_returntextwithnull(): @@ -88,22 +94,6 @@ def func_memoryerror(): def func_overflowerror(): raise OverflowError -def func_isstring(v): - return type(v) is str -def func_isint(v): - return type(v) is int -def func_isfloat(v): - return type(v) is float -def func_isnone(v): - return type(v) is type(None) -def func_isblob(v): - return isinstance(v, (bytes, memoryview)) -def func_islonglong(v): - return isinstance(v, int) and v >= 1<<31 - -def func(*args): - return len(args) - class AggrNoStep: def __init__(self): pass @@ -204,17 +194,17 @@ class FunctionTests(unittest.TestCase): self.con.create_function("returnnull", 0, func_returnnull) self.con.create_function("returnblob", 0, func_returnblob) self.con.create_function("returnlonglong", 0, func_returnlonglong) + self.con.create_function("returnnan", 0, lambda: float("nan")) + self.con.create_function("returntoolargeint", 0, lambda: 1 << 65) + self.con.create_function("return_noncont_blob", 0, + lambda: memoryview(b"blob")[::2]) self.con.create_function("raiseexception", 0, func_raiseexception) self.con.create_function("memoryerror", 0, func_memoryerror) self.con.create_function("overflowerror", 0, func_overflowerror) - self.con.create_function("isstring", 1, func_isstring) - self.con.create_function("isint", 1, func_isint) - self.con.create_function("isfloat", 1, func_isfloat) - self.con.create_function("isnone", 1, func_isnone) - self.con.create_function("isblob", 1, func_isblob) - self.con.create_function("islonglong", 1, func_islonglong) - self.con.create_function("spam", -1, func) + self.con.create_function("isblob", 1, lambda x: isinstance(x, bytes)) + self.con.create_function("isnone", 1, lambda x: x is None) + self.con.create_function("spam", -1, lambda *x: len(x)) self.con.execute("create table test(t text)") def tearDown(self): @@ -299,7 +289,17 @@ class FunctionTests(unittest.TestCase): val = cur.fetchone()[0] self.assertEqual(val, 1<<31) - @with_tracebacks(['func_raiseexception', '5/0', 'ZeroDivisionError']) + def test_func_return_nan(self): + cur = self.con.cursor() + cur.execute("select returnnan()") + self.assertIsNone(cur.fetchone()[0]) + + def test_func_return_too_large_int(self): + cur = self.con.cursor() + self.assertRaisesRegex(sqlite.DataError, "string or blob too big", + self.con.execute, "select returntoolargeint()") + + @with_tracebacks(ZeroDivisionError, name="func_raiseexception") def test_func_exception(self): cur = self.con.cursor() with self.assertRaises(sqlite.OperationalError) as cm: @@ -307,58 +307,20 @@ class FunctionTests(unittest.TestCase): cur.fetchone() self.assertEqual(str(cm.exception), 'user-defined function raised exception') - @with_tracebacks(['func_memoryerror', 'MemoryError']) + @with_tracebacks(MemoryError, name="func_memoryerror") def test_func_memory_error(self): cur = self.con.cursor() with self.assertRaises(MemoryError): cur.execute("select memoryerror()") cur.fetchone() - @with_tracebacks(['func_overflowerror', 'OverflowError']) + @with_tracebacks(OverflowError, name="func_overflowerror") def test_func_overflow_error(self): cur = self.con.cursor() with self.assertRaises(sqlite.DataError): cur.execute("select overflowerror()") cur.fetchone() - def test_param_string(self): - cur = self.con.cursor() - for text in ["foo", str()]: - with self.subTest(text=text): - cur.execute("select isstring(?)", (text,)) - val = cur.fetchone()[0] - self.assertEqual(val, 1) - - def test_param_int(self): - cur = self.con.cursor() - cur.execute("select isint(?)", (42,)) - val = cur.fetchone()[0] - self.assertEqual(val, 1) - - def test_param_float(self): - cur = self.con.cursor() - cur.execute("select isfloat(?)", (3.14,)) - val = cur.fetchone()[0] - self.assertEqual(val, 1) - - def test_param_none(self): - cur = self.con.cursor() - cur.execute("select isnone(?)", (None,)) - val = cur.fetchone()[0] - self.assertEqual(val, 1) - - def test_param_blob(self): - cur = self.con.cursor() - cur.execute("select isblob(?)", (memoryview(b"blob"),)) - val = cur.fetchone()[0] - self.assertEqual(val, 1) - - def test_param_long_long(self): - cur = self.con.cursor() - cur.execute("select islonglong(?)", (1<<42,)) - val = cur.fetchone()[0] - self.assertEqual(val, 1) - def test_any_arguments(self): cur = self.con.cursor() cur.execute("select spam(?, ?)", (1, 2)) @@ -369,6 +331,59 @@ class FunctionTests(unittest.TestCase): cur = self.con.execute("select isblob(x'')") self.assertTrue(cur.fetchone()[0]) + def test_nan_float(self): + cur = self.con.execute("select isnone(?)", (float("nan"),)) + # SQLite has no concept of nan; it is converted to NULL + self.assertTrue(cur.fetchone()[0]) + + def test_too_large_int(self): + err = "Python int too large to convert to SQLite INTEGER" + self.assertRaisesRegex(OverflowError, err, self.con.execute, + "select spam(?)", (1 << 65,)) + + def test_non_contiguous_blob(self): + self.assertRaisesRegex(BufferError, + "underlying buffer is not C-contiguous", + self.con.execute, "select spam(?)", + (memoryview(b"blob")[::2],)) + + @with_tracebacks(BufferError, regex="buffer.*contiguous") + def test_return_non_contiguous_blob(self): + with self.assertRaises(sqlite.OperationalError): + cur = self.con.execute("select return_noncont_blob()") + cur.fetchone() + + def test_param_surrogates(self): + self.assertRaisesRegex(UnicodeEncodeError, "surrogates not allowed", + self.con.execute, "select spam(?)", + ("\ud803\ude6d",)) + + def test_func_params(self): + results = [] + def append_result(arg): + results.append((arg, type(arg))) + self.con.create_function("test_params", 1, append_result) + + dataset = [ + (42, int), + (-1, int), + (1234567890123456789, int), + (4611686018427387905, int), # 63-bit int with non-zero low bits + (3.14, float), + (float('inf'), float), + ("text", str), + ("1\x002", str), + ("\u02e2q\u02e1\u2071\u1d57\u1d49", str), + (b"blob", bytes), + (bytearray(range(2)), bytes), + (memoryview(b"blob"), bytes), + (None, type(None)), + ] + for val, _ in dataset: + cur = self.con.execute("select test_params(?)", (val,)) + cur.fetchone() + self.assertEqual(dataset, results) + # Regarding deterministic functions: # # Between 3.8.3 and 3.15.0, deterministic functions were only used to @@ -378,7 +393,7 @@ class FunctionTests(unittest.TestCase): # indices, which allows testing based on syntax, iso. the query optimizer. @unittest.skipIf(sqlite.sqlite_version_info < (3, 8, 3), "Requires SQLite 3.8.3 or higher") def test_func_non_deterministic(self): - mock = unittest.mock.Mock(return_value=None) + mock = Mock(return_value=None) self.con.create_function("nondeterministic", 0, mock, deterministic=False) if sqlite.sqlite_version_info < (3, 15, 0): self.con.execute("select nondeterministic() = nondeterministic()") @@ -389,7 +404,7 @@ class FunctionTests(unittest.TestCase): @unittest.skipIf(sqlite.sqlite_version_info < (3, 8, 3), "Requires SQLite 3.8.3 or higher") def test_func_deterministic(self): - mock = unittest.mock.Mock(return_value=None) + mock = Mock(return_value=None) self.con.create_function("deterministic", 0, mock, deterministic=True) if sqlite.sqlite_version_info < (3, 15, 0): self.con.execute("select deterministic() = deterministic()") @@ -424,24 +439,23 @@ class FunctionTests(unittest.TestCase): y.append(y) del x,y - gc.collect() + gc_collect() + @with_tracebacks(OverflowError) def test_func_return_too_large_int(self): cur = self.con.cursor() for value in 2**63, -2**63-1, 2**64: self.con.create_function("largeint", 0, lambda value=value: value) - with check_tracebacks(self, ['OverflowError']): - with self.assertRaises(sqlite.DataError): - cur.execute("select largeint()") + with self.assertRaises(sqlite.DataError): + cur.execute("select largeint()") + @with_tracebacks(UnicodeEncodeError, "surrogates not allowed", "chr") def test_func_return_text_with_surrogates(self): cur = self.con.cursor() self.con.create_function("pychr", 1, chr) for value in 0xd8ff, 0xdcff: - with check_tracebacks(self, - ['UnicodeEncodeError', 'surrogates not allowed']): - with self.assertRaises(sqlite.OperationalError): - cur.execute("select pychr(?)", (value,)) + with self.assertRaises(sqlite.OperationalError): + cur.execute("select pychr(?)", (value,)) @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform') @bigmemtest(size=2**31, memuse=3, dry_run=False) @@ -461,6 +475,170 @@ class FunctionTests(unittest.TestCase): with self.assertRaises(sqlite.DataError): cur.execute("select largeblob()") + def test_func_return_illegal_value(self): + self.con.create_function("badreturn", 0, lambda: self) + msg = "user-defined function raised exception" + self.assertRaisesRegex(sqlite.OperationalError, msg, + self.con.execute, "select badreturn()") + + +class WindowSumInt: + def __init__(self): + self.count = 0 + + def step(self, value): + self.count += value + + def value(self): + return self.count + + def inverse(self, value): + self.count -= value + + def finalize(self): + return self.count + +class BadWindow(Exception): + pass + + +@unittest.skipIf(sqlite.sqlite_version_info < (3, 25, 0), + "Requires SQLite 3.25.0 or newer") +class WindowFunctionTests(unittest.TestCase): + def setUp(self): + self.con = sqlite.connect(":memory:") + self.cur = self.con.cursor() + + # Test case taken from https://www.sqlite.org/windowfunctions.html#udfwinfunc + values = [ + ("a", 4), + ("b", 5), + ("c", 3), + ("d", 8), + ("e", 1), + ] + with self.con: + self.con.execute("create table test(x, y)") + self.con.executemany("insert into test values(?, ?)", values) + self.expected = [ + ("a", 9), + ("b", 12), + ("c", 16), + ("d", 12), + ("e", 9), + ] + self.query = """ + select x, %s(y) over ( + order by x rows between 1 preceding and 1 following + ) as sum_y + from test order by x + """ + self.con.create_window_function("sumint", 1, WindowSumInt) + + def test_win_sum_int(self): + self.cur.execute(self.query % "sumint") + self.assertEqual(self.cur.fetchall(), self.expected) + + def test_win_error_on_create(self): + self.assertRaises(sqlite.ProgrammingError, + self.con.create_window_function, + "shouldfail", -100, WindowSumInt) + + @with_tracebacks(BadWindow) + def test_win_exception_in_method(self): + for meth in "__init__", "step", "value", "inverse": + with self.subTest(meth=meth): + with patch.object(WindowSumInt, meth, side_effect=BadWindow): + name = f"exc_{meth}" + self.con.create_window_function(name, 1, WindowSumInt) + msg = f"'{meth}' method raised error" + with self.assertRaisesRegex(sqlite.OperationalError, msg): + self.cur.execute(self.query % name) + self.cur.fetchall() + + @with_tracebacks(BadWindow) + def test_win_exception_in_finalize(self): + # Note: SQLite does not (as of version 3.38.0) propagate finalize + # callback errors to sqlite3_step(); this implies that OperationalError + # is _not_ raised. + with patch.object(WindowSumInt, "finalize", side_effect=BadWindow): + name = f"exception_in_finalize" + self.con.create_window_function(name, 1, WindowSumInt) + self.cur.execute(self.query % name) + self.cur.fetchall() + + @with_tracebacks(AttributeError) + def test_win_missing_method(self): + class MissingValue: + def step(self, x): pass + def inverse(self, x): pass + def finalize(self): return 42 + + class MissingInverse: + def step(self, x): pass + def value(self): return 42 + def finalize(self): return 42 + + class MissingStep: + def value(self): return 42 + def inverse(self, x): pass + def finalize(self): return 42 + + dataset = ( + ("step", MissingStep), + ("value", MissingValue), + ("inverse", MissingInverse), + ) + for meth, cls in dataset: + with self.subTest(meth=meth, cls=cls): + name = f"exc_{meth}" + self.con.create_window_function(name, 1, cls) + with self.assertRaisesRegex(sqlite.OperationalError, + f"'{meth}' method not defined"): + self.cur.execute(self.query % name) + self.cur.fetchall() + + @with_tracebacks(AttributeError) + def test_win_missing_finalize(self): + # Note: SQLite does not (as of version 3.38.0) propagate finalize + # callback errors to sqlite3_step(); this implies that OperationalError + # is _not_ raised. + class MissingFinalize: + def step(self, x): pass + def value(self): return 42 + def inverse(self, x): pass + + name = "missing_finalize" + self.con.create_window_function(name, 1, MissingFinalize) + self.cur.execute(self.query % name) + self.cur.fetchall() + + def test_win_clear_function(self): + self.con.create_window_function("sumint", 1, None) + self.assertRaises(sqlite.OperationalError, self.cur.execute, + self.query % "sumint") + + def test_win_redefine_function(self): + # Redefine WindowSumInt; adjust the expected results accordingly. + class Redefined(WindowSumInt): + def step(self, value): self.count += value * 2 + def inverse(self, value): self.count -= value * 2 + expected = [(v[0], v[1]*2) for v in self.expected] + + self.con.create_window_function("sumint", 1, Redefined) + self.cur.execute(self.query % "sumint") + self.assertEqual(self.cur.fetchall(), expected) + + def test_win_error_value_return(self): + class ErrorValueReturn: + def __init__(self): pass + def step(self, x): pass + def value(self): return 1 << 65 + + self.con.create_window_function("err_val_ret", 1, ErrorValueReturn) + self.assertRaisesRegex(sqlite.DataError, "string or blob too big", + self.cur.execute, self.query % "err_val_ret") + class AggregateTests(unittest.TestCase): def setUp(self): @@ -497,20 +675,22 @@ class AggregateTests(unittest.TestCase): with self.assertRaises(sqlite.OperationalError): self.con.create_function("bla", -100, AggrSum) + @with_tracebacks(AttributeError, name="AggrNoStep") def test_aggr_no_step(self): cur = self.con.cursor() - with self.assertRaises(AttributeError) as cm: + with self.assertRaises(sqlite.OperationalError) as cm: cur.execute("select nostep(t) from test") - self.assertEqual(str(cm.exception), "'AggrNoStep' object has no attribute 'step'") + self.assertEqual(str(cm.exception), + "user-defined aggregate's 'step' method not defined") def test_aggr_no_finalize(self): cur = self.con.cursor() - with self.assertRaises(sqlite.OperationalError) as cm: + msg = "user-defined aggregate's 'finalize' method not defined" + with self.assertRaisesRegex(sqlite.OperationalError, msg): cur.execute("select nofinalize(t) from test") val = cur.fetchone()[0] - self.assertEqual(str(cm.exception), "user-defined aggregate's 'finalize' method raised error") - @with_tracebacks(['__init__', '5/0', 'ZeroDivisionError']) + @with_tracebacks(ZeroDivisionError, name="AggrExceptionInInit") def test_aggr_exception_in_init(self): cur = self.con.cursor() with self.assertRaises(sqlite.OperationalError) as cm: @@ -518,7 +698,7 @@ class AggregateTests(unittest.TestCase): val = cur.fetchone()[0] self.assertEqual(str(cm.exception), "user-defined aggregate's '__init__' method raised error") - @with_tracebacks(['step', '5/0', 'ZeroDivisionError']) + @with_tracebacks(ZeroDivisionError, name="AggrExceptionInStep") def test_aggr_exception_in_step(self): cur = self.con.cursor() with self.assertRaises(sqlite.OperationalError) as cm: @@ -526,7 +706,7 @@ class AggregateTests(unittest.TestCase): val = cur.fetchone()[0] self.assertEqual(str(cm.exception), "user-defined aggregate's 'step' method raised error") - @with_tracebacks(['finalize', '5/0', 'ZeroDivisionError']) + @with_tracebacks(ZeroDivisionError, name="AggrExceptionInFinalize") def test_aggr_exception_in_finalize(self): cur = self.con.cursor() with self.assertRaises(sqlite.OperationalError) as cm: @@ -643,11 +823,11 @@ class AuthorizerRaiseExceptionTests(AuthorizerTests): raise ValueError return sqlite.SQLITE_OK - @with_tracebacks(['authorizer_cb', 'ValueError']) + @with_tracebacks(ValueError, name="authorizer_cb") def test_table_access(self): super().test_table_access() - @with_tracebacks(['authorizer_cb', 'ValueError']) + @with_tracebacks(ValueError, name="authorizer_cb") def test_column_access(self): super().test_table_access() diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 88eeb07afa0..d4eb2d2e81f 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -4,16 +4,15 @@ import sys import unittest import unittest.mock from test import support -from test.support import _asyncore as asyncore from test.support import import_helper from test.support import os_helper from test.support import socket_helper from test.support import threading_helper from test.support import warnings_helper +from test.support import asyncore import socket import select import time -import datetime import enum import gc import os @@ -37,8 +36,7 @@ import _ssl from ssl import TLSVersion, _TLSContentType, _TLSMessageType, _TLSAlertType -Py_DEBUG = hasattr(sys, 'gettotalrefcount') -Py_DEBUG_WIN32 = Py_DEBUG and sys.platform == 'win32' +Py_DEBUG_WIN32 = support.Py_DEBUG and sys.platform == 'win32' PROTOCOLS = sorted(ssl._PROTOCOL_NAMES) HOST = socket_helper.HOST @@ -47,7 +45,7 @@ PY_SSL_DEFAULT_CIPHERS = sysconfig.get_config_var('PY_SSL_DEFAULT_CIPHERS') PROTOCOL_TO_TLS_VERSION = {} for proto, ver in ( - ("PROTOCOL_SSLv23", "SSLv3"), + ("PROTOCOL_SSLv3", "SSLv3"), ("PROTOCOL_TLSv1", "TLSv1"), ("PROTOCOL_TLSv1_1", "TLSv1_1"), ): @@ -208,10 +206,6 @@ def has_tls_version(version): :param version: TLS version name or ssl.TLSVersion member :return: bool """ - if version == "SSLv2": - # never supported and not even in TLSVersion enum - return False - if isinstance(version, str): version = ssl.TLSVersion.__members__[version] @@ -370,7 +364,8 @@ class BasicSocketTests(unittest.TestCase): # Make sure that the PROTOCOL_* constants have enum-like string # reprs. proto = ssl.PROTOCOL_TLS_CLIENT - self.assertEqual(str(proto), 'PROTOCOL_TLS_CLIENT') + self.assertEqual(repr(proto), '<_SSLMethod.PROTOCOL_TLS_CLIENT: %r>' % proto.value) + self.assertEqual(str(proto), str(proto.value)) ctx = ssl.SSLContext(proto) self.assertIs(ctx.protocol, proto) @@ -381,10 +376,6 @@ class BasicSocketTests(unittest.TestCase): % (v, (v and "sufficient randomness") or "insufficient randomness")) - with warnings_helper.check_warnings(): - data, is_cryptographic = ssl.RAND_pseudo_bytes(16) - self.assertEqual(len(data), 16) - self.assertEqual(is_cryptographic, v == 1) if v: data = ssl.RAND_bytes(16) self.assertEqual(len(data), 16) @@ -393,8 +384,6 @@ class BasicSocketTests(unittest.TestCase): # negative num is invalid self.assertRaises(ValueError, ssl.RAND_bytes, -5) - with warnings_helper.check_warnings(): - self.assertRaises(ValueError, ssl.RAND_pseudo_bytes, -5) ssl.RAND_add("this is a random string", 75.0) ssl.RAND_add(b"this is a random bytes object", 75.0) @@ -537,7 +526,11 @@ class BasicSocketTests(unittest.TestCase): self.assertLessEqual(status, 15) libressl_ver = f"LibreSSL {major:d}" - openssl_ver = f"OpenSSL {major:d}.{minor:d}.{fix:d}" + if major >= 3: + # 3.x uses 0xMNN00PP0L + openssl_ver = f"OpenSSL {major:d}.{minor:d}.{patch:d}" + else: + openssl_ver = f"OpenSSL {major:d}.{minor:d}.{fix:d}" self.assertTrue( s.startswith((openssl_ver, libressl_ver)), (s, t, hex(n)) @@ -611,54 +604,29 @@ class BasicSocketTests(unittest.TestCase): ) for protocol in protocols: + if not has_tls_protocol(protocol): + continue with self.subTest(protocol=protocol): with self.assertWarns(DeprecationWarning) as cm: ssl.SSLContext(protocol) self.assertEqual( - f'{protocol!r} is deprecated', + f'ssl.{protocol.name} is deprecated', str(cm.warning) ) for version in versions: + if not has_tls_version(version): + continue with self.subTest(version=version): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) with self.assertWarns(DeprecationWarning) as cm: ctx.minimum_version = version + version_text = '%s.%s' % (version.__class__.__name__, version.name) self.assertEqual( - f'ssl.{version!r} is deprecated', + f'ssl.{version_text} is deprecated', str(cm.warning) ) - @ignore_deprecation - def test_errors_sslwrap(self): - sock = socket.socket() - self.assertRaisesRegex(ValueError, - "certfile must be specified", - ssl.wrap_socket, sock, keyfile=CERTFILE) - self.assertRaisesRegex(ValueError, - "certfile must be specified for server-side operations", - ssl.wrap_socket, sock, server_side=True) - self.assertRaisesRegex(ValueError, - "certfile must be specified for server-side operations", - ssl.wrap_socket, sock, server_side=True, certfile="") - with ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE) as s: - self.assertRaisesRegex(ValueError, "can't connect in server-side mode", - s.connect, (HOST, 8080)) - with self.assertRaises(OSError) as cm: - with socket.socket() as sock: - ssl.wrap_socket(sock, certfile=NONEXISTINGCERT) - self.assertEqual(cm.exception.errno, errno.ENOENT) - with self.assertRaises(OSError) as cm: - with socket.socket() as sock: - ssl.wrap_socket(sock, - certfile=CERTFILE, keyfile=NONEXISTINGCERT) - self.assertEqual(cm.exception.errno, errno.ENOENT) - with self.assertRaises(OSError) as cm: - with socket.socket() as sock: - ssl.wrap_socket(sock, - certfile=NONEXISTINGCERT, keyfile=NONEXISTINGCERT) - self.assertEqual(cm.exception.errno, errno.ENOENT) - def bad_cert_test(self, certfile): """Check that trying to use the given client certificate fails""" certfile = os.path.join(os.path.dirname(__file__) or os.curdir, @@ -681,205 +649,6 @@ class BasicSocketTests(unittest.TestCase): """Wrapping with a badly formatted key (syntax error)""" self.bad_cert_test("badkey.pem") - @ignore_deprecation - def test_match_hostname(self): - def ok(cert, hostname): - ssl.match_hostname(cert, hostname) - def fail(cert, hostname): - self.assertRaises(ssl.CertificateError, - ssl.match_hostname, cert, hostname) - - # -- Hostname matching -- - - cert = {'subject': ((('commonName', 'example.com'),),)} - ok(cert, 'example.com') - ok(cert, 'ExAmple.cOm') - fail(cert, 'www.example.com') - fail(cert, '.example.com') - fail(cert, 'example.org') - fail(cert, 'exampleXcom') - - cert = {'subject': ((('commonName', '*.a.com'),),)} - ok(cert, 'foo.a.com') - fail(cert, 'bar.foo.a.com') - fail(cert, 'a.com') - fail(cert, 'Xa.com') - fail(cert, '.a.com') - - # only match wildcards when they are the only thing - # in left-most segment - cert = {'subject': ((('commonName', 'f*.com'),),)} - fail(cert, 'foo.com') - fail(cert, 'f.com') - fail(cert, 'bar.com') - fail(cert, 'foo.a.com') - fail(cert, 'bar.foo.com') - - # NULL bytes are bad, CVE-2013-4073 - cert = {'subject': ((('commonName', - 'null.python.org\x00example.org'),),)} - ok(cert, 'null.python.org\x00example.org') # or raise an error? - fail(cert, 'example.org') - fail(cert, 'null.python.org') - - # error cases with wildcards - cert = {'subject': ((('commonName', '*.*.a.com'),),)} - fail(cert, 'bar.foo.a.com') - fail(cert, 'a.com') - fail(cert, 'Xa.com') - fail(cert, '.a.com') - - cert = {'subject': ((('commonName', 'a.*.com'),),)} - fail(cert, 'a.foo.com') - fail(cert, 'a..com') - fail(cert, 'a.com') - - # wildcard doesn't match IDNA prefix 'xn--' - idna = 'püthon.python.org'.encode("idna").decode("ascii") - cert = {'subject': ((('commonName', idna),),)} - ok(cert, idna) - cert = {'subject': ((('commonName', 'x*.python.org'),),)} - fail(cert, idna) - cert = {'subject': ((('commonName', 'xn--p*.python.org'),),)} - fail(cert, idna) - - # wildcard in first fragment and IDNA A-labels in sequent fragments - # are supported. - idna = 'www*.pythön.org'.encode("idna").decode("ascii") - cert = {'subject': ((('commonName', idna),),)} - fail(cert, 'www.pythön.org'.encode("idna").decode("ascii")) - fail(cert, 'www1.pythön.org'.encode("idna").decode("ascii")) - fail(cert, 'ftp.pythön.org'.encode("idna").decode("ascii")) - fail(cert, 'pythön.org'.encode("idna").decode("ascii")) - - # Slightly fake real-world example - cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT', - 'subject': ((('commonName', 'linuxfrz.org'),),), - 'subjectAltName': (('DNS', 'linuxfr.org'), - ('DNS', 'linuxfr.com'), - ('othername', ''))} - ok(cert, 'linuxfr.org') - ok(cert, 'linuxfr.com') - # Not a "DNS" entry - fail(cert, '') - # When there is a subjectAltName, commonName isn't used - fail(cert, 'linuxfrz.org') - - # A pristine real-world example - cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT', - 'subject': ((('countryName', 'US'),), - (('stateOrProvinceName', 'California'),), - (('localityName', 'Mountain View'),), - (('organizationName', 'Google Inc'),), - (('commonName', 'mail.google.com'),))} - ok(cert, 'mail.google.com') - fail(cert, 'gmail.com') - # Only commonName is considered - fail(cert, 'California') - - # -- IPv4 matching -- - cert = {'subject': ((('commonName', 'example.com'),),), - 'subjectAltName': (('DNS', 'example.com'), - ('IP Address', '10.11.12.13'), - ('IP Address', '14.15.16.17'), - ('IP Address', '127.0.0.1'))} - ok(cert, '10.11.12.13') - ok(cert, '14.15.16.17') - # socket.inet_ntoa(socket.inet_aton('127.1')) == '127.0.0.1' - fail(cert, '127.1') - fail(cert, '14.15.16.17 ') - fail(cert, '14.15.16.17 extra data') - fail(cert, '14.15.16.18') - fail(cert, 'example.net') - - # -- IPv6 matching -- - if socket_helper.IPV6_ENABLED: - cert = {'subject': ((('commonName', 'example.com'),),), - 'subjectAltName': ( - ('DNS', 'example.com'), - ('IP Address', '2001:0:0:0:0:0:0:CAFE\n'), - ('IP Address', '2003:0:0:0:0:0:0:BABA\n'))} - ok(cert, '2001::cafe') - ok(cert, '2003::baba') - fail(cert, '2003::baba ') - fail(cert, '2003::baba extra data') - fail(cert, '2003::bebe') - fail(cert, 'example.net') - - # -- Miscellaneous -- - - # Neither commonName nor subjectAltName - cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT', - 'subject': ((('countryName', 'US'),), - (('stateOrProvinceName', 'California'),), - (('localityName', 'Mountain View'),), - (('organizationName', 'Google Inc'),))} - fail(cert, 'mail.google.com') - - # No DNS entry in subjectAltName but a commonName - cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT', - 'subject': ((('countryName', 'US'),), - (('stateOrProvinceName', 'California'),), - (('localityName', 'Mountain View'),), - (('commonName', 'mail.google.com'),)), - 'subjectAltName': (('othername', 'blabla'), )} - ok(cert, 'mail.google.com') - - # No DNS entry subjectAltName and no commonName - cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT', - 'subject': ((('countryName', 'US'),), - (('stateOrProvinceName', 'California'),), - (('localityName', 'Mountain View'),), - (('organizationName', 'Google Inc'),)), - 'subjectAltName': (('othername', 'blabla'),)} - fail(cert, 'google.com') - - # Empty cert / no cert - self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com') - self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com') - - # Issue #17980: avoid denials of service by refusing more than one - # wildcard per fragment. - cert = {'subject': ((('commonName', 'a*b.example.com'),),)} - with self.assertRaisesRegex( - ssl.CertificateError, - "partial wildcards in leftmost label are not supported"): - ssl.match_hostname(cert, 'axxb.example.com') - - cert = {'subject': ((('commonName', 'www.*.example.com'),),)} - with self.assertRaisesRegex( - ssl.CertificateError, - "wildcard can only be present in the leftmost label"): - ssl.match_hostname(cert, 'www.sub.example.com') - - cert = {'subject': ((('commonName', 'a*b*.example.com'),),)} - with self.assertRaisesRegex( - ssl.CertificateError, - "too many wildcards"): - ssl.match_hostname(cert, 'axxbxxc.example.com') - - cert = {'subject': ((('commonName', '*'),),)} - with self.assertRaisesRegex( - ssl.CertificateError, - "sole wildcard without additional labels are not support"): - ssl.match_hostname(cert, 'host') - - cert = {'subject': ((('commonName', '*.com'),),)} - with self.assertRaisesRegex( - ssl.CertificateError, - r"hostname 'com' doesn't match '\*.com'"): - ssl.match_hostname(cert, 'com') - - # extra checks for _inet_paton() - for invalid in ['1', '', '1.2.3', '256.0.0.1', '127.0.0.1/24']: - with self.assertRaises(ValueError): - ssl._inet_paton(invalid) - for ipaddr in ['127.0.0.1', '192.168.0.1']: - self.assertTrue(ssl._inet_paton(ipaddr)) - if socket_helper.IPV6_ENABLED: - for ipaddr in ['::1', '2001:db8:85a3::8a2e:370:7334']: - self.assertTrue(ssl._inet_paton(ipaddr)) - def test_server_side(self): # server_hostname doesn't work for server sockets ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) @@ -1133,9 +902,10 @@ class ContextTests(unittest.TestCase): def test_constructor(self): for protocol in PROTOCOLS: - with warnings_helper.check_warnings(): - ctx = ssl.SSLContext(protocol) - self.assertEqual(ctx.protocol, protocol) + if has_tls_protocol(protocol): + with warnings_helper.check_warnings(): + ctx = ssl.SSLContext(protocol) + self.assertEqual(ctx.protocol, protocol) with warnings_helper.check_warnings(): ctx = ssl.SSLContext() self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLS) @@ -1166,8 +936,20 @@ class ContextTests(unittest.TestCase): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx.set_ciphers('AESGCM') names = set(d['name'] for d in ctx.get_ciphers()) - self.assertIn('AES256-GCM-SHA384', names) - self.assertIn('AES128-GCM-SHA256', names) + expected = { + 'AES128-GCM-SHA256', + 'ECDHE-ECDSA-AES128-GCM-SHA256', + 'ECDHE-RSA-AES128-GCM-SHA256', + 'DHE-RSA-AES128-GCM-SHA256', + 'AES256-GCM-SHA384', + 'ECDHE-ECDSA-AES256-GCM-SHA384', + 'ECDHE-RSA-AES256-GCM-SHA384', + 'DHE-RSA-AES256-GCM-SHA384', + } + intersection = names.intersection(expected) + self.assertGreaterEqual( + len(intersection), 2, f"\ngot: {sorted(names)}\nexpected: {sorted(expected)}" + ) def test_options(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) @@ -1280,7 +1062,7 @@ class ContextTests(unittest.TestCase): ctx.maximum_version = ssl.TLSVersion.MINIMUM_SUPPORTED self.assertIn( ctx.maximum_version, - {ssl.TLSVersion.TLSv1, ssl.TLSVersion.SSLv3} + {ssl.TLSVersion.TLSv1, ssl.TLSVersion.TLSv1_1, ssl.TLSVersion.SSLv3} ) ctx.minimum_version = ssl.TLSVersion.MAXIMUM_SUPPORTED @@ -1292,19 +1074,19 @@ class ContextTests(unittest.TestCase): with self.assertRaises(ValueError): ctx.minimum_version = 42 - ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_1) - - self.assertIn( - ctx.minimum_version, minimum_range - ) - self.assertEqual( - ctx.maximum_version, ssl.TLSVersion.MAXIMUM_SUPPORTED - ) - with self.assertRaises(ValueError): - ctx.minimum_version = ssl.TLSVersion.MINIMUM_SUPPORTED - with self.assertRaises(ValueError): - ctx.maximum_version = ssl.TLSVersion.TLSv1 + if has_tls_protocol(ssl.PROTOCOL_TLSv1_1): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_1) + self.assertIn( + ctx.minimum_version, minimum_range + ) + self.assertEqual( + ctx.maximum_version, ssl.TLSVersion.MAXIMUM_SUPPORTED + ) + with self.assertRaises(ValueError): + ctx.minimum_version = ssl.TLSVersion.MINIMUM_SUPPORTED + with self.assertRaises(ValueError): + ctx.maximum_version = ssl.TLSVersion.TLSv1 @unittest.skipUnless( hasattr(ssl.SSLContext, 'security_level'), @@ -1650,7 +1432,8 @@ class ContextTests(unittest.TestCase): self.assertEqual(ctx.cert_store_stats(), {"crl": 0, "x509": 1, "x509_ca": 0}) @unittest.skipUnless(sys.platform == "win32", "Windows specific") - @unittest.skipIf(hasattr(sys, "gettotalrefcount"), "Debug build does not share environment between CRTs") + @unittest.skipIf(support.Py_DEBUG, + "Debug build does not share environment between CRTs") def test_load_default_certs_env_windows(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx.load_default_certs() @@ -1678,6 +1461,8 @@ class ContextTests(unittest.TestCase): if OP_CIPHER_SERVER_PREFERENCE != 0: self.assertEqual(ctx.options & OP_CIPHER_SERVER_PREFERENCE, OP_CIPHER_SERVER_PREFERENCE) + self.assertEqual(ctx.options & ssl.OP_LEGACY_SERVER_CONNECT, + 0 if IS_OPENSSL_3_0_0 else ssl.OP_LEGACY_SERVER_CONNECT) def test_create_default_context(self): ctx = ssl.create_default_context() @@ -1700,8 +1485,6 @@ class ContextTests(unittest.TestCase): self.assertEqual(ctx.verify_mode, ssl.CERT_NONE) self._assert_context_options(ctx) - - def test__create_stdlib_context(self): ctx = ssl._create_stdlib_context() self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLS_CLIENT) @@ -1709,11 +1492,12 @@ class ContextTests(unittest.TestCase): self.assertFalse(ctx.check_hostname) self._assert_context_options(ctx) - with warnings_helper.check_warnings(): - ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1) - self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1) - self.assertEqual(ctx.verify_mode, ssl.CERT_NONE) - self._assert_context_options(ctx) + if has_tls_protocol(ssl.PROTOCOL_TLSv1): + with warnings_helper.check_warnings(): + ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1) + self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1) + self.assertEqual(ctx.verify_mode, ssl.CERT_NONE) + self._assert_context_options(ctx) with warnings_helper.check_warnings(): ctx = ssl._create_stdlib_context( @@ -1992,9 +1776,8 @@ class SimpleBackgroundTests(unittest.TestCase): self.server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) self.server_context.load_cert_chain(SIGNED_CERTFILE) server = ThreadedEchoServer(context=self.server_context) + self.enterContext(server) self.server_addr = (HOST, server.port) - server.__enter__() - self.addCleanup(server.__exit__, None, None, None) def test_connect(self): with test_wrap_socket(socket.socket(socket.AF_INET), @@ -2256,11 +2039,8 @@ class SimpleBackgroundTests(unittest.TestCase): # A simple IO loop. Call func(*args) depending on the error we get # (WANT_READ or WANT_WRITE) move data between the socket and the BIOs. timeout = kwargs.get('timeout', support.SHORT_TIMEOUT) - deadline = time.monotonic() + timeout count = 0 - while True: - if time.monotonic() > deadline: - self.fail("timeout") + for _ in support.busy_retry(timeout): errno = None count += 1 try: @@ -3327,37 +3107,10 @@ class ThreadedTests(unittest.TestCase): self.assertIn(msg, repr(e)) self.assertIn('certificate verify failed', repr(e)) - @requires_tls_version('SSLv2') - def test_protocol_sslv2(self): - """Connecting to an SSLv2 server with various client options""" - if support.verbose: - sys.stdout.write("\n") - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True) - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL) - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED) - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLS, False) - if has_tls_version('SSLv3'): - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False) - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False) - # SSLv23 client with specific SSL options - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLS, False, - client_options=ssl.OP_NO_SSLv3) - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLS, False, - client_options=ssl.OP_NO_TLSv1) - def test_PROTOCOL_TLS(self): """Connecting to an SSLv23 server with various client options""" if support.verbose: sys.stdout.write("\n") - if has_tls_version('SSLv2'): - try: - try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv2, True) - except OSError as x: - # this fails on some older versions of OpenSSL (0.9.7l, for instance) - if support.verbose: - sys.stdout.write( - " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n" - % str(x)) if has_tls_version('SSLv3'): try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLS, True) @@ -3395,8 +3148,6 @@ class ThreadedTests(unittest.TestCase): try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3') try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL) try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED) - if has_tls_version('SSLv2'): - try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False) try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLS, False, client_options=ssl.OP_NO_SSLv3) try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False) @@ -3409,8 +3160,6 @@ class ThreadedTests(unittest.TestCase): try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1') try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL) try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED) - if has_tls_version('SSLv2'): - try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False) if has_tls_version('SSLv3'): try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLS, False, @@ -3423,8 +3172,6 @@ class ThreadedTests(unittest.TestCase): if support.verbose: sys.stdout.write("\n") try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1') - if has_tls_version('SSLv2'): - try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False) if has_tls_version('SSLv3'): try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLS, False, @@ -3443,18 +3190,18 @@ class ThreadedTests(unittest.TestCase): try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2', server_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2, client_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,) - if has_tls_version('SSLv2'): - try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False) if has_tls_version('SSLv3'): try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLS, False, client_options=ssl.OP_NO_TLSv1_2) try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2') - try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1, False) - try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_2, False) - try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False) - try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False) + if has_tls_protocol(ssl.PROTOCOL_TLSv1): + try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1, False) + try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_2, False) + if has_tls_protocol(ssl.PROTOCOL_TLSv1_1): + try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False) + try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False) def test_starttls(self): """Switching from clear text to encrypted and back again.""" @@ -3706,8 +3453,7 @@ class ThreadedTests(unittest.TestCase): def test_recv_zero(self): server = ThreadedEchoServer(CERTFILE) - server.__enter__() - self.addCleanup(server.__exit__, None, None) + self.enterContext(server) s = socket.create_connection((HOST, server.port)) self.addCleanup(s.close) s = test_wrap_socket(s, suppress_ragged_eofs=False) @@ -4071,6 +3817,20 @@ class ThreadedTests(unittest.TestCase): sni_name=hostname) self.assertIs(stats['compression'], None) + def test_legacy_server_connect(self): + client_context, server_context, hostname = testing_context() + client_context.options |= ssl.OP_LEGACY_SERVER_CONNECT + server_params_test(client_context, server_context, + chatty=True, connectionchatty=True, + sni_name=hostname) + + def test_no_legacy_server_connect(self): + client_context, server_context, hostname = testing_context() + client_context.options &= ~ssl.OP_LEGACY_SERVER_CONNECT + server_params_test(client_context, server_context, + chatty=True, connectionchatty=True, + sni_name=hostname) + @unittest.skipIf(Py_DEBUG_WIN32, "Avoid mixing debug/release CRT on Windows") def test_dh_params(self): # Check we can get a connection with ephemeral Diffie-Hellman diff --git a/Lib/test/test_stable_abi_ctypes.py b/Lib/test/test_stable_abi_ctypes.py index 1e27bcaf889..67c653428a6 100644 --- a/Lib/test/test_stable_abi_ctypes.py +++ b/Lib/test/test_stable_abi_ctypes.py @@ -4,17 +4,36 @@ """Test that all symbols of the Stable ABI are accessible using ctypes """ +import sys import unittest from test.support.import_helper import import_module +from _testcapi import get_feature_macros +feature_macros = get_feature_macros() ctypes_test = import_module('ctypes') class TestStableABIAvailability(unittest.TestCase): def test_available_symbols(self): + for symbol_name in SYMBOL_NAMES: with self.subTest(symbol_name): ctypes_test.pythonapi[symbol_name] + def test_feature_macros(self): + self.assertEqual( + set(get_feature_macros()), EXPECTED_FEATURE_MACROS) + + # The feature macros for Windows are used in creating the DLL + # definition, so they must be known on all platforms. + # If we are on Windows, we check that the hardcoded data matches + # the reality. + @unittest.skipIf(sys.platform != "win32", "Windows specific test") + def test_windows_feature_macros(self): + for name, value in WINDOWS_FEATURE_MACROS.items(): + if value != 'maybe': + with self.subTest(name): + self.assertEqual(feature_macros[name], value) + SYMBOL_NAMES = ( "PyAIter_Check", @@ -28,6 +47,14 @@ SYMBOL_NAMES = ( "PyBaseObject_Type", "PyBool_FromLong", "PyBool_Type", + "PyBuffer_FillContiguousStrides", + "PyBuffer_FillInfo", + "PyBuffer_FromContiguous", + "PyBuffer_GetPointer", + "PyBuffer_IsContiguous", + "PyBuffer_Release", + "PyBuffer_SizeFromFormat", + "PyBuffer_ToContiguous", "PyByteArrayIter_Type", "PyByteArray_AsString", "PyByteArray_Concat", @@ -144,6 +171,7 @@ SYMBOL_NAMES = ( "PyErr_Format", "PyErr_FormatV", "PyErr_GetExcInfo", + "PyErr_GetHandledException", "PyErr_GivenExceptionMatches", "PyErr_NewException", "PyErr_NewExceptionWithDoc", @@ -160,6 +188,7 @@ SYMBOL_NAMES = ( "PyErr_SetFromErrnoWithFilename", "PyErr_SetFromErrnoWithFilenameObject", "PyErr_SetFromErrnoWithFilenameObjects", + "PyErr_SetHandledException", "PyErr_SetImportError", "PyErr_SetImportErrorSubclass", "PyErr_SetInterrupt", @@ -381,6 +410,7 @@ SYMBOL_NAMES = ( "PyMemberDescr_Type", "PyMember_GetOne", "PyMember_SetOne", + "PyMemoryView_FromBuffer", "PyMemoryView_FromMemory", "PyMemoryView_FromObject", "PyMemoryView_GetContiguous", @@ -470,8 +500,10 @@ SYMBOL_NAMES = ( "PyObject_CallNoArgs", "PyObject_CallObject", "PyObject_Calloc", + "PyObject_CheckBuffer", "PyObject_CheckReadBuffer", "PyObject_ClearWeakRefs", + "PyObject_CopyData", "PyObject_DelItem", "PyObject_DelItemString", "PyObject_Dir", @@ -489,6 +521,7 @@ SYMBOL_NAMES = ( "PyObject_GetAIter", "PyObject_GetAttr", "PyObject_GetAttrString", + "PyObject_GetBuffer", "PyObject_GetItem", "PyObject_GetIter", "PyObject_HasAttr", @@ -514,6 +547,8 @@ SYMBOL_NAMES = ( "PyObject_Size", "PyObject_Str", "PyObject_Type", + "PyObject_Vectorcall", + "PyObject_VectorcallMethod", "PyProperty_Type", "PyRangeIter_Type", "PyRange_Type", @@ -603,7 +638,6 @@ SYMBOL_NAMES = ( "PyThread_get_key_value", "PyThread_get_stacksize", "PyThread_get_thread_ident", - "PyThread_get_thread_native_id", "PyThread_init_thread", "PyThread_release_lock", "PyThread_set_key_value", @@ -628,6 +662,7 @@ SYMBOL_NAMES = ( "PyTuple_Size", "PyTuple_Type", "PyType_ClearCache", + "PyType_FromMetaclass", "PyType_FromModuleAndSpec", "PyType_FromSpec", "PyType_FromSpecWithBases", @@ -749,6 +784,8 @@ SYMBOL_NAMES = ( "PyUnicode_Translate", "PyUnicode_Type", "PyUnicode_WriteChar", + "PyVectorcall_Call", + "PyVectorcall_NARGS", "PyWeakref_GetObject", "PyWeakref_NewProxy", "PyWeakref_NewRef", @@ -808,6 +845,7 @@ SYMBOL_NAMES = ( "Py_SetRecursionLimit", "Py_UTF8Mode", "Py_VaBuildValue", + "Py_Version", "Py_XNewRef", "_PyArg_ParseTupleAndKeywords_SizeT", "_PyArg_ParseTuple_SizeT", @@ -817,7 +855,6 @@ SYMBOL_NAMES = ( "_PyErr_BadInternalCall", "_PyObject_CallFunction_SizeT", "_PyObject_CallMethod_SizeT", - "_PyObject_GC_Malloc", "_PyObject_GC_New", "_PyObject_GC_NewVar", "_PyObject_GC_Resize", @@ -842,3 +879,49 @@ SYMBOL_NAMES = ( "_Py_TrueStruct", "_Py_VaBuildValue_SizeT", ) +if feature_macros['MS_WINDOWS']: + SYMBOL_NAMES += ( + 'PyErr_SetExcFromWindowsErr', + 'PyErr_SetExcFromWindowsErrWithFilename', + 'PyErr_SetExcFromWindowsErrWithFilenameObject', + 'PyErr_SetExcFromWindowsErrWithFilenameObjects', + 'PyErr_SetFromWindowsErr', + 'PyErr_SetFromWindowsErrWithFilename', + 'PyExc_WindowsError', + 'PyUnicode_AsMBCSString', + 'PyUnicode_DecodeCodePageStateful', + 'PyUnicode_DecodeMBCS', + 'PyUnicode_DecodeMBCSStateful', + 'PyUnicode_EncodeCodePage', + ) +if feature_macros['HAVE_FORK']: + SYMBOL_NAMES += ( + 'PyOS_AfterFork', + 'PyOS_AfterFork_Child', + 'PyOS_AfterFork_Parent', + 'PyOS_BeforeFork', + ) +if feature_macros['USE_STACKCHECK']: + SYMBOL_NAMES += ( + 'PyOS_CheckStack', + ) +if feature_macros['PY_HAVE_THREAD_NATIVE_ID']: + SYMBOL_NAMES += ( + 'PyThread_get_thread_native_id', + ) +if feature_macros['Py_REF_DEBUG']: + SYMBOL_NAMES += ( + '_Py_NegativeRefcount', + '_Py_RefTotal', + ) + +EXPECTED_FEATURE_MACROS = set(['HAVE_FORK', + 'MS_WINDOWS', + 'PY_HAVE_THREAD_NATIVE_ID', + 'Py_REF_DEBUG', + 'USE_STACKCHECK']) +WINDOWS_FEATURE_MACROS = {'HAVE_FORK': False, + 'MS_WINDOWS': True, + 'PY_HAVE_THREAD_NATIVE_ID': True, + 'Py_REF_DEBUG': 'maybe', + 'USE_STACKCHECK': 'maybe'} diff --git a/Lib/test/test_stat.py b/Lib/test/test_stat.py index 2e1e2c349c8..4ba37aed2dc 100644 --- a/Lib/test/test_stat.py +++ b/Lib/test/test_stat.py @@ -113,6 +113,7 @@ class TestFilemode: else: self.assertFalse(func(mode)) + @os_helper.skip_unless_working_chmod def test_mode(self): with open(TESTFN, 'w'): pass @@ -151,6 +152,7 @@ class TestFilemode: self.assertEqual(self.statmod.S_IFMT(st_mode), self.statmod.S_IFREG) + @os_helper.skip_unless_working_chmod def test_directory(self): os.mkdir(TESTFN) os.chmod(TESTFN, 0o700) @@ -161,7 +163,7 @@ class TestFilemode: else: self.assertEqual(modestr[0], 'd') - @unittest.skipUnless(hasattr(os, 'symlink'), 'os.symlink not available') + @os_helper.skip_unless_symlink def test_link(self): try: os.symlink(os.getcwd(), TESTFN) diff --git a/Lib/test/test_statistics.py b/Lib/test/test_statistics.py index c0e427d9355..31a3cb6b53a 100644 --- a/Lib/test/test_statistics.py +++ b/Lib/test/test_statistics.py @@ -9,13 +9,14 @@ import collections.abc import copy import decimal import doctest +import itertools import math import pickle import random import sys import unittest from test import support -from test.support import import_helper +from test.support import import_helper, requires_IEEE_754 from decimal import Decimal from fractions import Fraction @@ -1039,50 +1040,6 @@ class FailNegTest(unittest.TestCase): self.assertEqual(errmsg, msg) -class FindLteqTest(unittest.TestCase): - # Test _find_lteq private function. - - def test_invalid_input_values(self): - for a, x in [ - ([], 1), - ([1, 2], 3), - ([1, 3], 2) - ]: - with self.subTest(a=a, x=x): - with self.assertRaises(ValueError): - statistics._find_lteq(a, x) - - def test_locate_successfully(self): - for a, x, expected_i in [ - ([1, 1, 1, 2, 3], 1, 0), - ([0, 1, 1, 1, 2, 3], 1, 1), - ([1, 2, 3, 3, 3], 3, 2) - ]: - with self.subTest(a=a, x=x): - self.assertEqual(expected_i, statistics._find_lteq(a, x)) - - -class FindRteqTest(unittest.TestCase): - # Test _find_rteq private function. - - def test_invalid_input_values(self): - for a, l, x in [ - ([1], 2, 1), - ([1, 3], 0, 2) - ]: - with self.assertRaises(ValueError): - statistics._find_rteq(a, l, x) - - def test_locate_successfully(self): - for a, l, x, expected_i in [ - ([1, 1, 1, 2, 3], 0, 1, 2), - ([0, 1, 1, 1, 2, 3], 0, 1, 3), - ([1, 2, 3, 3, 3], 0, 3, 4) - ]: - with self.subTest(a=a, l=l, x=x): - self.assertEqual(expected_i, statistics._find_rteq(a, l, x)) - - # === Tests for public functions === class UnivariateCommonMixin: @@ -1785,6 +1742,12 @@ class TestMedianGrouped(TestMedian): data = [x]*count self.assertEqual(self.func(data), float(x)) + def test_single_value(self): + # Override method from AverageMixin. + # Average of a single value is the value as a float. + for x in (23, 42.5, 1.3e15, Fraction(15, 19), Decimal('0.28')): + self.assertEqual(self.func([x]), float(x)) + def test_odd_fractions(self): # Test median_grouped works with an odd number of Fractions. F = Fraction @@ -2161,6 +2124,103 @@ class TestPStdev(VarianceStdevMixin, NumericTestCase): self.assertEqual(self.func(data), 2.5) self.assertEqual(self.func(data, mu=0.5), 6.5) +class TestSqrtHelpers(unittest.TestCase): + + def test_integer_sqrt_of_frac_rto(self): + for n, m in itertools.product(range(100), range(1, 1000)): + r = statistics._integer_sqrt_of_frac_rto(n, m) + self.assertIsInstance(r, int) + if r*r*m == n: + # Root is exact + continue + # Inexact, so the root should be odd + self.assertEqual(r&1, 1) + # Verify correct rounding + self.assertTrue(m * (r - 1)**2 < n < m * (r + 1)**2) + + @requires_IEEE_754 + def test_float_sqrt_of_frac(self): + + def is_root_correctly_rounded(x: Fraction, root: float) -> bool: + if not x: + return root == 0.0 + + # Extract adjacent representable floats + r_up: float = math.nextafter(root, math.inf) + r_down: float = math.nextafter(root, -math.inf) + assert r_down < root < r_up + + # Convert to fractions for exact arithmetic + frac_root: Fraction = Fraction(root) + half_way_up: Fraction = (frac_root + Fraction(r_up)) / 2 + half_way_down: Fraction = (frac_root + Fraction(r_down)) / 2 + + # Check a closed interval. + # Does not test for a midpoint rounding rule. + return half_way_down ** 2 <= x <= half_way_up ** 2 + + randrange = random.randrange + + for i in range(60_000): + numerator: int = randrange(10 ** randrange(50)) + denonimator: int = randrange(10 ** randrange(50)) + 1 + with self.subTest(numerator=numerator, denonimator=denonimator): + x: Fraction = Fraction(numerator, denonimator) + root: float = statistics._float_sqrt_of_frac(numerator, denonimator) + self.assertTrue(is_root_correctly_rounded(x, root)) + + # Verify that corner cases and error handling match math.sqrt() + self.assertEqual(statistics._float_sqrt_of_frac(0, 1), 0.0) + with self.assertRaises(ValueError): + statistics._float_sqrt_of_frac(-1, 1) + with self.assertRaises(ValueError): + statistics._float_sqrt_of_frac(1, -1) + + # Error handling for zero denominator matches that for Fraction(1, 0) + with self.assertRaises(ZeroDivisionError): + statistics._float_sqrt_of_frac(1, 0) + + # The result is well defined if both inputs are negative + self.assertEqual(statistics._float_sqrt_of_frac(-2, -1), statistics._float_sqrt_of_frac(2, 1)) + + def test_decimal_sqrt_of_frac(self): + root: Decimal + numerator: int + denominator: int + + for root, numerator, denominator in [ + (Decimal('0.4481904599041192673635338663'), 200874688349065940678243576378, 1000000000000000000000000000000), # No adj + (Decimal('0.7924949131383786609961759598'), 628048187350206338833590574929, 1000000000000000000000000000000), # Adj up + (Decimal('0.8500554152289934068192208727'), 722594208960136395984391238251, 1000000000000000000000000000000), # Adj down + ]: + with decimal.localcontext(decimal.DefaultContext): + self.assertEqual(statistics._decimal_sqrt_of_frac(numerator, denominator), root) + + # Confirm expected root with a quad precision decimal computation + with decimal.localcontext(decimal.DefaultContext) as ctx: + ctx.prec *= 4 + high_prec_ratio = Decimal(numerator) / Decimal(denominator) + ctx.rounding = decimal.ROUND_05UP + high_prec_root = high_prec_ratio.sqrt() + with decimal.localcontext(decimal.DefaultContext): + target_root = +high_prec_root + self.assertEqual(root, target_root) + + # Verify that corner cases and error handling match Decimal.sqrt() + self.assertEqual(statistics._decimal_sqrt_of_frac(0, 1), 0.0) + with self.assertRaises(decimal.InvalidOperation): + statistics._decimal_sqrt_of_frac(-1, 1) + with self.assertRaises(decimal.InvalidOperation): + statistics._decimal_sqrt_of_frac(1, -1) + + # Error handling for zero denominator matches that for Fraction(1, 0) + with self.assertRaises(ZeroDivisionError): + statistics._decimal_sqrt_of_frac(1, 0) + + # The result is well defined if both inputs are negative + self.assertEqual(statistics._decimal_sqrt_of_frac(-2, -1), statistics._decimal_sqrt_of_frac(2, 1)) + + class TestStdev(VarianceStdevMixin, NumericTestCase): # Tests for sample standard deviation. def setUp(self): @@ -2175,7 +2235,7 @@ class TestStdev(VarianceStdevMixin, NumericTestCase): # Test that stdev is, in fact, the square root of variance. data = [random.uniform(-2, 9) for _ in range(1000)] expected = math.sqrt(statistics.variance(data)) - self.assertEqual(self.func(data), expected) + self.assertAlmostEqual(self.func(data), expected) def test_center_not_at_mean(self): data = (1.0, 2.0) @@ -2505,6 +2565,22 @@ class TestCorrelationAndCovariance(unittest.TestCase): self.assertAlmostEqual(statistics.covariance(x, y), 0.1) + def test_correlation_spearman(self): + # https://statistics.laerd.com/statistical-guides/spearmans-rank-order-correlation-statistical-guide-2.php + # Compare with: + # >>> import scipy.stats.mstats + # >>> scipy.stats.mstats.spearmanr(reading, mathematics) + # SpearmanrResult(correlation=0.6686960980480712, pvalue=0.03450954165178532) + # And Wolfram Alpha gives: 0.668696 + # https://www.wolframalpha.com/input?i=SpearmanRho%5B%7B56%2C+75%2C+45%2C+71%2C+61%2C+64%2C+58%2C+80%2C+76%2C+61%7D%2C+%7B66%2C+70%2C+40%2C+60%2C+65%2C+56%2C+59%2C+77%2C+67%2C+63%7D%5D + reading = [56, 75, 45, 71, 61, 64, 58, 80, 76, 61] + mathematics = [66, 70, 40, 60, 65, 56, 59, 77, 67, 63] + self.assertAlmostEqual(statistics.correlation(reading, mathematics, method='ranked'), + 0.6686960980480712) + + with self.assertRaises(ValueError): + statistics.correlation(reading, mathematics, method='bad_method') + class TestLinearRegression(unittest.TestCase): def test_constant_input_error(self): @@ -2741,9 +2817,10 @@ class TestNormalDist: iq.inv_cdf(1.0) # p is one with self.assertRaises(self.module.StatisticsError): iq.inv_cdf(1.1) # p over one - with self.assertRaises(self.module.StatisticsError): - iq = NormalDist(100, 0) # sigma is zero - iq.inv_cdf(0.5) + + # Supported case: + iq = NormalDist(100, 0) # sigma is zero + self.assertEqual(iq.inv_cdf(0.5), 100) # Special values self.assertTrue(math.isnan(Z.inv_cdf(float('NaN')))) @@ -2926,14 +3003,19 @@ class TestNormalDist: nd = NormalDist(100, 15) self.assertNotEqual(nd, lnd) - def test_pickle_and_copy(self): + def test_copy(self): nd = self.module.NormalDist(37.5, 5.625) nd1 = copy.copy(nd) self.assertEqual(nd, nd1) nd2 = copy.deepcopy(nd) self.assertEqual(nd, nd2) - nd3 = pickle.loads(pickle.dumps(nd)) - self.assertEqual(nd, nd3) + + def test_pickle(self): + nd = self.module.NormalDist(37.5, 5.625) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + pickled = pickle.loads(pickle.dumps(nd, protocol=proto)) + self.assertEqual(nd, pickled) def test_hashability(self): ND = self.module.NormalDist diff --git a/Lib/test/test_strftime.py b/Lib/test/test_strftime.py index be43c49e40a..cebfc892786 100644 --- a/Lib/test/test_strftime.py +++ b/Lib/test/test_strftime.py @@ -54,14 +54,10 @@ class StrftimeTest(unittest.TestCase): self.now = now def setUp(self): - try: - import java - java.util.Locale.setDefault(java.util.Locale.US) - except ImportError: - from locale import setlocale, LC_TIME - saved_locale = setlocale(LC_TIME) - setlocale(LC_TIME, 'C') - self.addCleanup(setlocale, LC_TIME, saved_locale) + from locale import setlocale, LC_TIME + saved_locale = setlocale(LC_TIME) + setlocale(LC_TIME, 'C') + self.addCleanup(setlocale, LC_TIME, saved_locale) def test_strftime(self): now = time.time() diff --git a/Lib/test/test_string.py b/Lib/test/test_string.py index 0be28fdb609..824b89ad517 100644 --- a/Lib/test/test_string.py +++ b/Lib/test/test_string.py @@ -475,6 +475,57 @@ class TestTemplate(unittest.TestCase): self.assertEqual(s.substitute(dict(who='tim', what='ham')), 'tim likes to eat a bag of ham worth $100') + def test_is_valid(self): + eq = self.assertEqual + s = Template('$who likes to eat a bag of ${what} worth $$100') + self.assertTrue(s.is_valid()) + + s = Template('$who likes to eat a bag of ${what} worth $100') + self.assertFalse(s.is_valid()) + + # if the pattern has an unrecognized capture group, + # it should raise ValueError like substitute and safe_substitute do + class BadPattern(Template): + pattern = r""" + (?P.*) | + (?P@{2}) | + @(?P[_a-z][._a-z0-9]*) | + @{(?P[_a-z][._a-z0-9]*)} | + (?P@) | + """ + s = BadPattern('@bag.foo.who likes to eat a bag of @bag.what') + self.assertRaises(ValueError, s.is_valid) + + def test_get_identifiers(self): + eq = self.assertEqual + raises = self.assertRaises + s = Template('$who likes to eat a bag of ${what} worth $$100') + ids = s.get_identifiers() + eq(ids, ['who', 'what']) + + # repeated identifiers only included once + s = Template('$who likes to eat a bag of ${what} worth $$100; ${who} likes to eat a bag of $what worth $$100') + ids = s.get_identifiers() + eq(ids, ['who', 'what']) + + # invalid identifiers are ignored + s = Template('$who likes to eat a bag of ${what} worth $100') + ids = s.get_identifiers() + eq(ids, ['who', 'what']) + + # if the pattern has an unrecognized capture group, + # it should raise ValueError like substitute and safe_substitute do + class BadPattern(Template): + pattern = r""" + (?P.*) | + (?P@{2}) | + @(?P[_a-z][._a-z0-9]*) | + @{(?P[_a-z][._a-z0-9]*)} | + (?P@) | + """ + s = BadPattern('@bag.foo.who likes to eat a bag of @bag.what') + self.assertRaises(ValueError, s.get_identifiers) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_string_literals.py b/Lib/test/test_string_literals.py index 7231970acf1..9b663c00223 100644 --- a/Lib/test/test_string_literals.py +++ b/Lib/test/test_string_literals.py @@ -109,22 +109,49 @@ class TestLiterals(unittest.TestCase): for b in range(1, 128): if b in b"""\n\r"'01234567NU\\abfnrtuvx""": continue - with self.assertWarns(DeprecationWarning): + with self.assertWarns(SyntaxWarning): self.assertEqual(eval(r"'\%c'" % b), '\\' + chr(b)) with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always', category=DeprecationWarning) + warnings.simplefilter('always', category=SyntaxWarning) eval("'''\n\\z'''") self.assertEqual(len(w), 1) + self.assertEqual(str(w[0].message), r"invalid escape sequence '\z'") self.assertEqual(w[0].filename, '') self.assertEqual(w[0].lineno, 1) with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('error', category=DeprecationWarning) + warnings.simplefilter('error', category=SyntaxWarning) with self.assertRaises(SyntaxError) as cm: eval("'''\n\\z'''") exc = cm.exception self.assertEqual(w, []) + self.assertEqual(exc.msg, r"invalid escape sequence '\z'") + self.assertEqual(exc.filename, '') + self.assertEqual(exc.lineno, 1) + self.assertEqual(exc.offset, 1) + + def test_eval_str_invalid_octal_escape(self): + for i in range(0o400, 0o1000): + with self.assertWarns(SyntaxWarning): + self.assertEqual(eval(r"'\%o'" % i), chr(i)) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always', category=SyntaxWarning) + eval("'''\n\\407'''") + self.assertEqual(len(w), 1) + self.assertEqual(str(w[0].message), + r"invalid octal escape sequence '\407'") + self.assertEqual(w[0].filename, '') + self.assertEqual(w[0].lineno, 1) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('error', category=SyntaxWarning) + with self.assertRaises(SyntaxError) as cm: + eval("'''\n\\407'''") + exc = cm.exception + self.assertEqual(w, []) + self.assertEqual(exc.msg, r"invalid octal escape sequence '\407'") self.assertEqual(exc.filename, '') self.assertEqual(exc.lineno, 1) self.assertEqual(exc.offset, 1) @@ -159,22 +186,48 @@ class TestLiterals(unittest.TestCase): for b in range(1, 128): if b in b"""\n\r"'01234567\\abfnrtvx""": continue - with self.assertWarns(DeprecationWarning): + with self.assertWarns(SyntaxWarning): self.assertEqual(eval(r"b'\%c'" % b), b'\\' + bytes([b])) with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always', category=DeprecationWarning) + warnings.simplefilter('always', category=SyntaxWarning) eval("b'''\n\\z'''") self.assertEqual(len(w), 1) + self.assertEqual(str(w[0].message), r"invalid escape sequence '\z'") self.assertEqual(w[0].filename, '') self.assertEqual(w[0].lineno, 1) with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('error', category=DeprecationWarning) + warnings.simplefilter('error', category=SyntaxWarning) with self.assertRaises(SyntaxError) as cm: eval("b'''\n\\z'''") exc = cm.exception self.assertEqual(w, []) + self.assertEqual(exc.msg, r"invalid escape sequence '\z'") + self.assertEqual(exc.filename, '') + self.assertEqual(exc.lineno, 1) + + def test_eval_bytes_invalid_octal_escape(self): + for i in range(0o400, 0o1000): + with self.assertWarns(SyntaxWarning): + self.assertEqual(eval(r"b'\%o'" % i), bytes([i & 0o377])) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always', category=SyntaxWarning) + eval("b'''\n\\407'''") + self.assertEqual(len(w), 1) + self.assertEqual(str(w[0].message), + r"invalid octal escape sequence '\407'") + self.assertEqual(w[0].filename, '') + self.assertEqual(w[0].lineno, 1) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('error', category=SyntaxWarning) + with self.assertRaises(SyntaxError) as cm: + eval("b'''\n\\407'''") + exc = cm.exception + self.assertEqual(w, []) + self.assertEqual(exc.msg, r"invalid octal escape sequence '\407'") self.assertEqual(exc.filename, '') self.assertEqual(exc.lineno, 1) @@ -213,6 +266,13 @@ class TestLiterals(unittest.TestCase): self.assertRaises(SyntaxError, eval, """ bu'' """) self.assertRaises(SyntaxError, eval, """ ub'' """) + def test_uppercase_prefixes(self): + self.assertEqual(eval(""" B'x' """), b'x') + self.assertEqual(eval(r""" R'\x01' """), r'\x01') + self.assertEqual(eval(r""" BR'\x01' """), br'\x01') + self.assertEqual(eval(""" F'{1+1}' """), f'{1+1}') + self.assertEqual(eval(r""" U'\U0001d120' """), u'\U0001d120') + def check_encoding(self, encoding, extra=""): modname = "xx_" + encoding.replace("-", "_") fn = os.path.join(self.tmpdir, modname + ".py") diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index 55a0f426731..e3fcabef946 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -70,6 +70,9 @@ class LocaleTime_Tests(unittest.TestCase): self.assertEqual(self.LT_ins.am_pm[position], strftime_output, "AM/PM representation in the wrong position within the tuple") + @unittest.skipIf( + support.is_emscripten, "musl libc issue on Emscripten, bpo-46390" + ) def test_timezone(self): # Make sure timezone is correct timezone = time.strftime("%Z", self.time_tuple).lower() @@ -368,6 +371,9 @@ class StrptimeTests(unittest.TestCase): self.assertEqual("Inconsistent use of : in -01:3030", str(err.exception)) @skip_if_buggy_ucrt_strfptime + @unittest.skipIf( + support.is_emscripten, "musl libc issue on Emscripten, bpo-46390" + ) def test_timezone(self): # Test timezone directives. # When gmtime() is used with %Z, entire result of strftime() is empty. @@ -390,6 +396,9 @@ class StrptimeTests(unittest.TestCase): "LocaleTime().timezone has duplicate values and " "time.daylight but timezone value not set to -1") + @unittest.skipUnless( + hasattr(time, "tzset"), "time module has no attribute tzset" + ) def test_bad_timezone(self): # Explicitly test possibility of bad timezone; # when time.tzname[0] == time.tzname[1] and time.daylight diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index 94873ff6124..6b1f22f66fd 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -1,10 +1,12 @@ from collections import abc import array +import gc import math import operator import unittest import struct import sys +import weakref from test import support from test.support import import_helper @@ -672,6 +674,47 @@ class StructTest(unittest.TestCase): self.assertIn(b"Exception ignored in:", stderr) self.assertIn(b"C.__del__", stderr) + def test__struct_reference_cycle_cleaned_up(self): + # Regression test for python/cpython#94207. + + # When we create a new struct module, trigger use of its cache, + # and then delete it ... + _struct_module = import_helper.import_fresh_module("_struct") + module_ref = weakref.ref(_struct_module) + _struct_module.calcsize("b") + del _struct_module + + # Then the module should have been garbage collected. + gc.collect() + self.assertIsNone( + module_ref(), "_struct module was not garbage collected") + + @support.cpython_only + def test__struct_types_immutable(self): + # See https://github.com/python/cpython/issues/94254 + + Struct = struct.Struct + unpack_iterator = type(struct.iter_unpack("b", b'x')) + for cls in (Struct, unpack_iterator): + with self.subTest(cls=cls): + with self.assertRaises(TypeError): + cls.x = 1 + + @support.cpython_only + def test__struct_Struct__new__initialized(self): + # See https://github.com/python/cpython/issues/78724 + + s = struct.Struct.__new__(struct.Struct, "b") + s.unpack_from(b"abcd") + + @support.cpython_only + def test__struct_Struct_subclassing(self): + class Bob(struct.Struct): + pass + + s = Bob("b") + s.unpack_from(b"abcd") + def test_issue35714(self): # Embedded null characters should not be allowed in format strings. for s in '\0', '2\0i', b'\0': @@ -680,23 +723,56 @@ class StructTest(unittest.TestCase): struct.calcsize(s) @support.cpython_only - def test_issue45034_unsigned(self): - _testcapi = import_helper.import_module('_testcapi') - error_msg = f'ushort format requires 0 <= number <= {_testcapi.USHRT_MAX}' - with self.assertRaisesRegex(struct.error, error_msg): - struct.pack('H', 70000) # too large - with self.assertRaisesRegex(struct.error, error_msg): - struct.pack('H', -1) # too small + def test_issue98248(self): + def test_error_msg(prefix, int_type, is_unsigned): + fmt_str = prefix + int_type + size = struct.calcsize(fmt_str) + if is_unsigned: + max_ = 2 ** (size * 8) - 1 + min_ = 0 + else: + max_ = 2 ** (size * 8 - 1) - 1 + min_ = -2 ** (size * 8 - 1) + error_msg = f"'{int_type}' format requires {min_} <= number <= {max_}" + for number in [int(-1e50), min_ - 1, max_ + 1, int(1e50)]: + with self.subTest(format_str=fmt_str, number=number): + with self.assertRaisesRegex(struct.error, error_msg): + struct.pack(fmt_str, number) + error_msg = "required argument is not an integer" + not_number = "" + with self.subTest(format_str=fmt_str, number=not_number): + with self.assertRaisesRegex(struct.error, error_msg): + struct.pack(fmt_str, not_number) + + for prefix in '@=<>': + for int_type in 'BHILQ': + test_error_msg(prefix, int_type, True) + for int_type in 'bhilq': + test_error_msg(prefix, int_type, False) + + int_type = 'N' + test_error_msg('@', int_type, True) + + int_type = 'n' + test_error_msg('@', int_type, False) @support.cpython_only - def test_issue45034_signed(self): - _testcapi = import_helper.import_module('_testcapi') - error_msg = f'short format requires {_testcapi.SHRT_MIN} <= number <= {_testcapi.SHRT_MAX}' - with self.assertRaisesRegex(struct.error, error_msg): - struct.pack('h', 70000) # too large - with self.assertRaisesRegex(struct.error, error_msg): - struct.pack('h', -70000) # too small + def test_issue98248_error_propagation(self): + class Div0: + def __index__(self): + 1 / 0 + def test_error_propagation(fmt_str): + with self.subTest(format_str=fmt_str, exception="ZeroDivisionError"): + with self.assertRaises(ZeroDivisionError): + struct.pack(fmt_str, Div0()) + + for prefix in '@=<>': + for int_type in 'BHILQbhilq': + test_error_propagation(prefix + int_type) + + test_error_propagation('N') + test_error_propagation('n') class UnpackIteratorTest(unittest.TestCase): """ diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 3af523e8346..abd0dd8b256 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -48,6 +48,9 @@ except: if support.PGO: raise unittest.SkipTest("test is not helpful for PGO") +if not support.has_subprocess_support: + raise unittest.SkipTest("test module requires subprocess") + mswindows = (sys.platform == "win32") # @@ -235,6 +238,12 @@ class ProcessTestCase(BaseTestCase): input=None, universal_newlines=True) self.assertNotIn('XX', output) + def test_check_output_input_none_encoding_errors(self): + output = subprocess.check_output( + [sys.executable, "-c", "print('foo')"], + input=None, encoding='utf-8', errors='ignore') + self.assertIn('foo', output) + def test_check_output_stdout_arg(self): # check_output() refuses to accept 'stdout' argument with self.assertRaises(ValueError) as c: @@ -1540,6 +1549,22 @@ class ProcessTestCase(BaseTestCase): self.assertIsInstance(subprocess.Popen[bytes], types.GenericAlias) self.assertIsInstance(subprocess.CompletedProcess[str], types.GenericAlias) + @unittest.skipIf(not sysconfig.get_config_var("HAVE_VFORK"), + "vfork() not enabled by configure.") + @mock.patch("subprocess._fork_exec") + def test__use_vfork(self, mock_fork_exec): + self.assertTrue(subprocess._USE_VFORK) # The default value regardless. + mock_fork_exec.side_effect = RuntimeError("just testing args") + with self.assertRaises(RuntimeError): + subprocess.run([sys.executable, "-c", "pass"]) + mock_fork_exec.assert_called_once() + self.assertTrue(mock_fork_exec.call_args.args[-1]) + with mock.patch.object(subprocess, '_USE_VFORK', False): + with self.assertRaises(RuntimeError): + subprocess.run([sys.executable, "-c", "pass"]) + self.assertFalse(mock_fork_exec.call_args_list[-1].args[-1]) + + class RunFuncTestCase(BaseTestCase): def run_python(self, code, **kwargs): """Run Python code in a subprocess using subprocess.run""" @@ -1714,6 +1739,19 @@ class RunFuncTestCase(BaseTestCase): msg="TimeoutExpired was delayed! Bad traceback:\n```\n" f"{stacks}```") + def test_encoding_warning(self): + code = textwrap.dedent("""\ + from subprocess import * + run("echo hello", shell=True, text=True) + check_output("echo hello", shell=True, text=True) + """) + cp = subprocess.run([sys.executable, "-Xwarn_default_encoding", "-c", code], + capture_output=True) + lines = cp.stderr.splitlines() + self.assertEqual(len(lines), 2, lines) + self.assertTrue(lines[0].startswith(b":2: EncodingWarning: ")) + self.assertTrue(lines[1].startswith(b":3: EncodingWarning: ")) + def _get_test_grp_name(): for name_group in ('staff', 'nogroup', 'grp', 'nobody', 'nfsnobody'): @@ -1802,7 +1840,7 @@ class POSIXProcessTestCase(BaseTestCase): def __del__(self): pass - @mock.patch("subprocess._posixsubprocess.fork_exec") + @mock.patch("subprocess._fork_exec") def test_exception_errpipe_normal(self, fork_exec): """Test error passing done through errpipe_write in the good case""" def proper_error(*args): @@ -1819,7 +1857,7 @@ class POSIXProcessTestCase(BaseTestCase): with self.assertRaises(IsADirectoryError): self.PopenNoDestructor(["non_existent_command"]) - @mock.patch("subprocess._posixsubprocess.fork_exec") + @mock.patch("subprocess._fork_exec") def test_exception_errpipe_bad_data(self, fork_exec): """Test error passing done through errpipe_write where its not in the expected format""" @@ -1873,14 +1911,32 @@ class POSIXProcessTestCase(BaseTestCase): output = subprocess.check_output( [sys.executable, "-c", "import os; print(os.getsid(0))"], start_new_session=True) - except OSError as e: + except PermissionError as e: if e.errno != errno.EPERM: - raise + raise # EACCES? else: parent_sid = os.getsid(0) child_sid = int(output) self.assertNotEqual(parent_sid, child_sid) + @unittest.skipUnless(hasattr(os, 'setpgid') and hasattr(os, 'getpgid'), + 'no setpgid or getpgid on platform') + def test_process_group_0(self): + # For code coverage of calling setpgid(). We don't care if we get an + # EPERM error from it depending on the test execution environment, that + # still indicates that it was called. + try: + output = subprocess.check_output( + [sys.executable, "-c", "import os; print(os.getpgid(0))"], + process_group=0) + except PermissionError as e: + if e.errno != errno.EPERM: + raise # EACCES? + else: + parent_pgid = os.getpgid(0) + child_pgid = int(output) + self.assertNotEqual(parent_pgid, child_pgid) + @unittest.skipUnless(hasattr(os, 'setreuid'), 'no setreuid on platform') def test_user(self): # For code coverage of the user parameter. We don't care if we get an @@ -2109,7 +2165,7 @@ class POSIXProcessTestCase(BaseTestCase): preexec_fn=raise_it) except subprocess.SubprocessError as e: self.assertTrue( - subprocess._posixsubprocess, + subprocess._fork_exec, "Expected a ValueError from the preexec_fn") except ValueError as e: self.assertIn("coconut", e.args[0]) @@ -2597,11 +2653,11 @@ class POSIXProcessTestCase(BaseTestCase): preexec_fn=prepare) except ValueError as err: # Pure Python implementations keeps the message - self.assertIsNone(subprocess._posixsubprocess) + self.assertIsNone(subprocess._fork_exec) self.assertEqual(str(err), "surrogate:\uDCff") except subprocess.SubprocessError as err: # _posixsubprocess uses a default message - self.assertIsNotNone(subprocess._posixsubprocess) + self.assertIsNotNone(subprocess._fork_exec) self.assertEqual(str(err), "Exception occurred in preexec_fn.") else: self.fail("Expected ValueError or subprocess.SubprocessError") @@ -2776,7 +2832,7 @@ class POSIXProcessTestCase(BaseTestCase): @unittest.skipIf(sys.platform.startswith("freebsd") and os.stat("/dev").st_dev == os.stat("/dev/fd").st_dev, - "Requires fdescfs mounted on /dev/fd on FreeBSD.") + "Requires fdescfs mounted on /dev/fd on FreeBSD") def test_close_fds_when_max_fd_is_lowered(self): """Confirm that issue21618 is fixed (may fail under valgrind).""" fd_status = support.findfile("fd_status.py", subdir="subprocessdata") @@ -3102,9 +3158,9 @@ class POSIXProcessTestCase(BaseTestCase): True, (), cwd, env_list, -1, -1, -1, -1, 1, 2, 3, 4, - True, True, + True, True, 0, False, [], 0, -1, - func) + func, False) # Attempt to prevent # "TypeError: fork_exec() takes exactly N arguments (M given)" # from passing the test. More refactoring to have us start @@ -3151,9 +3207,9 @@ class POSIXProcessTestCase(BaseTestCase): True, fds_to_keep, None, [b"env"], -1, -1, -1, -1, 1, 2, 3, 4, - True, True, + True, True, 0, None, None, None, -1, - None) + None, True) self.assertIn('fds_to_keep', str(c.exception)) finally: if not gc_enabled: diff --git a/Lib/test/test_sunau.py b/Lib/test/test_sunau.py index 7f1c0a5cbde..40408b01eda 100644 --- a/Lib/test/test_sunau.py +++ b/Lib/test/test_sunau.py @@ -1,10 +1,12 @@ import unittest from test import audiotests -from audioop import byteswap import io import struct import sys -import sunau +from test.support import warnings_helper + +sunau = warnings_helper.import_deprecated("sunau") +audioop = warnings_helper.import_deprecated("audioop") class SunauTest(audiotests.AudioWriteTests, @@ -116,7 +118,7 @@ class SunauULAWTest(SunauTest, unittest.TestCase): E5040CBC 617C0A3C 08BC0A3C 2C7C0B3C 517C0E3C 8A8410FC B6840EBC 457C0A3C \ """) if sys.byteorder != 'big': - frames = byteswap(frames, 2) + frames = audioop.byteswap(frames, 2) class SunauLowLevelTest(unittest.TestCase): diff --git a/Lib/test/test_sundry.py b/Lib/test/test_sundry.py index de2e7305ccc..f4a8d434ed1 100644 --- a/Lib/test/test_sundry.py +++ b/Lib/test/test_sundry.py @@ -18,29 +18,6 @@ class TestUntestedModules(unittest.TestCase): self.fail('{} has tests even though test_sundry claims ' 'otherwise'.format(name)) - import distutils.bcppcompiler - import distutils.ccompiler - import distutils.cygwinccompiler - import distutils.filelist - import distutils.text_file - import distutils.unixccompiler - - import distutils.command.bdist_dumb - import distutils.command.bdist - import distutils.command.bdist_rpm - import distutils.command.build_clib - import distutils.command.build_ext - import distutils.command.build - import distutils.command.clean - import distutils.command.config - import distutils.command.install_data - import distutils.command.install_egg_info - import distutils.command.install_headers - import distutils.command.install_lib - import distutils.command.register - import distutils.command.sdist - import distutils.command.upload - import html.entities try: diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py index 5d94372bf6e..a68b38cf79d 100644 --- a/Lib/test/test_super.py +++ b/Lib/test/test_super.py @@ -317,6 +317,14 @@ class TestSuper(unittest.TestCase): for i in range(1000): super.__init__(sp, int, i) + def test_super_argcount(self): + with self.assertRaisesRegex(TypeError, "expected at most"): + super(int, int, int) + + def test_super_argtype(self): + with self.assertRaisesRegex(TypeError, "argument 1 must be a type"): + super(1, int) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index d5a1d447f05..7738ca5e9b4 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -9,7 +9,6 @@ import subprocess import sys import tempfile import textwrap -import time import unittest import warnings @@ -123,15 +122,18 @@ class TestSupport(unittest.TestCase): os_helper.unlink(mod_filename) os_helper.rmtree('__pycache__') + @support.requires_working_socket() def test_HOST(self): s = socket.create_server((socket_helper.HOST, 0)) s.close() + @support.requires_working_socket() def test_find_unused_port(self): port = socket_helper.find_unused_port() s = socket.create_server((socket_helper.HOST, port)) s.close() + @support.requires_working_socket() def test_bind_port(self): s = socket.socket() socket_helper.bind_port(s) @@ -198,7 +200,7 @@ class TestSupport(unittest.TestCase): f'temporary directory {path!r}: '), warn) - @unittest.skipUnless(hasattr(os, "fork"), "test requires os.fork") + @support.requires_fork() def test_temp_dir__forked_child(self): """Test that a forked child process does not remove the directory.""" # See bpo-30028 for details. @@ -447,6 +449,7 @@ class TestSupport(unittest.TestCase): @unittest.skipUnless(hasattr(os, 'waitpid') and hasattr(os, 'WNOHANG'), 'need os.waitpid() and os.WNOHANG') + @support.requires_fork() def test_reap_children(self): # Make sure that there is no other pending child process support.reap_children() @@ -457,18 +460,12 @@ class TestSupport(unittest.TestCase): # child process: do nothing, just exit os._exit(0) - t0 = time.monotonic() - deadline = time.monotonic() + support.SHORT_TIMEOUT - was_altered = support.environment_altered try: support.environment_altered = False stderr = io.StringIO() - while True: - if time.monotonic() > deadline: - self.fail("timeout") - + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): with support.swap_attr(support.print_warning, 'orig_stderr', stderr): support.reap_children() @@ -477,9 +474,6 @@ class TestSupport(unittest.TestCase): if support.environment_altered: break - # loop until the child process completed - time.sleep(0.100) - msg = "Warning -- reap_children() reaped child process %s" % pid self.assertIn(msg, stderr.getvalue()) self.assertTrue(support.environment_altered) @@ -490,6 +484,7 @@ class TestSupport(unittest.TestCase): # pending child process support.reap_children() + @support.requires_subprocess() def check_options(self, args, func, expected=None): code = f'from test.support import {func}; print(repr({func}()))' cmd = [sys.executable, *args, '-c', code] @@ -517,6 +512,7 @@ class TestSupport(unittest.TestCase): ['-E'], ['-v'], ['-b'], + ['-P'], ['-q'], ['-I'], # same option multiple times @@ -536,7 +532,8 @@ class TestSupport(unittest.TestCase): with self.subTest(opts=opts): self.check_options(opts, 'args_from_interpreter_flags') - self.check_options(['-I', '-E', '-s'], 'args_from_interpreter_flags', + self.check_options(['-I', '-E', '-s', '-P'], + 'args_from_interpreter_flags', ['-I']) def test_optim_args_from_interpreter_flags(self): @@ -656,10 +653,14 @@ class TestSupport(unittest.TestCase): self.assertFalse(support.match_test(test_access)) self.assertTrue(support.match_test(test_chdir)) + @unittest.skipIf(support.is_emscripten, "Unstable in Emscripten") + @unittest.skipIf(support.is_wasi, "Unavailable on WASI") def test_fd_count(self): # We cannot test the absolute value of fd_count(): on old Linux # kernel or glibc versions, os.urandom() keeps a FD open on # /dev/urandom device and Python has 4 FD opens instead of 3. + # Test is unstable on Emscripten. The platform starts and stops + # background threads that use pipes and epoll fds. start = os_helper.fd_count() fd = os.open(__file__, os.O_RDONLY) try: @@ -680,6 +681,12 @@ class TestSupport(unittest.TestCase): self.check_print_warning("a\nb", 'Warning -- a\nWarning -- b\n') + def test_has_strftime_extensions(self): + if support.is_emscripten or sys.platform == "win32": + self.assertFalse(support.has_strftime_extensions) + else: + self.assertTrue(support.has_strftime_extensions) + # XXX -follows a list of untested API # make_legacy_pyc # is_resource_enabled diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py index 819354e4eee..25714aecda3 100644 --- a/Lib/test/test_symtable.py +++ b/Lib/test/test_symtable.py @@ -222,10 +222,9 @@ class SymtableTest(unittest.TestCase): checkfilename("def f(x): foo)(", 14) # parse-time checkfilename("def f(x): global x", 11) # symtable-build-time symtable.symtable("pass", b"spam", "exec") - with self.assertWarns(DeprecationWarning), \ - self.assertRaises(TypeError): + with self.assertRaises(TypeError): symtable.symtable("pass", bytearray(b"spam"), "exec") - with self.assertWarns(DeprecationWarning): + with self.assertRaises(TypeError): symtable.symtable("pass", memoryview(b"spam"), "exec") with self.assertRaises(TypeError): symtable.symtable("pass", list(b"spam"), "exec") diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index fc3c62954a2..cb284195d97 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -334,7 +334,12 @@ From ast_for_arguments(): >>> def f(x, y=1, z): ... pass Traceback (most recent call last): -SyntaxError: non-default argument follows default argument +SyntaxError: parameter without a default follows parameter with a default + +>>> def f(x, /, y=1, z): +... pass +Traceback (most recent call last): +SyntaxError: parameter without a default follows parameter with a default >>> def f(x, None): ... pass @@ -351,6 +356,218 @@ SyntaxError: invalid syntax Traceback (most recent call last): SyntaxError: invalid syntax +>>> def foo(/,a,b=,c): +... pass +Traceback (most recent call last): +SyntaxError: at least one argument must precede / + +>>> def foo(a,/,/,b,c): +... pass +Traceback (most recent call last): +SyntaxError: / may appear only once + +>>> def foo(a,/,a1,/,b,c): +... pass +Traceback (most recent call last): +SyntaxError: / may appear only once + +>>> def foo(a=1,/,/,*b,/,c): +... pass +Traceback (most recent call last): +SyntaxError: / may appear only once + +>>> def foo(a,/,a1=1,/,b,c): +... pass +Traceback (most recent call last): +SyntaxError: / may appear only once + +>>> def foo(a,*b,c,/,d,e): +... pass +Traceback (most recent call last): +SyntaxError: / must be ahead of * + +>>> def foo(a=1,*b,c=3,/,d,e): +... pass +Traceback (most recent call last): +SyntaxError: / must be ahead of * + +>>> def foo(a,*b=3,c): +... pass +Traceback (most recent call last): +SyntaxError: var-positional argument cannot have default value + +>>> def foo(a,*b: int=,c): +... pass +Traceback (most recent call last): +SyntaxError: var-positional argument cannot have default value + +>>> def foo(a,**b=3): +... pass +Traceback (most recent call last): +SyntaxError: var-keyword argument cannot have default value + +>>> def foo(a,**b: int=3): +... pass +Traceback (most recent call last): +SyntaxError: var-keyword argument cannot have default value + +>>> def foo(a,*a, b, **c, d): +... pass +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> def foo(a,*a, b, **c, d=4): +... pass +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> def foo(a,*a, b, **c, *d): +... pass +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> def foo(a,*a, b, **c, **d): +... pass +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> def foo(a=1,/,**b,/,c): +... pass +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> def foo(*b,*d): +... pass +Traceback (most recent call last): +SyntaxError: * argument may appear only once + +>>> def foo(a,*b,c,*d,*e,c): +... pass +Traceback (most recent call last): +SyntaxError: * argument may appear only once + +>>> def foo(a,b,/,c,*b,c,*d,*e,c): +... pass +Traceback (most recent call last): +SyntaxError: * argument may appear only once + +>>> def foo(a,b,/,c,*b,c,*d,**e): +... pass +Traceback (most recent call last): +SyntaxError: * argument may appear only once + +>>> def foo(a=1,/*,b,c): +... pass +Traceback (most recent call last): +SyntaxError: expected comma between / and * + +>>> def foo(a=1,d=,c): +... pass +Traceback (most recent call last): +SyntaxError: expected default value expression + +>>> def foo(a,d=,c): +... pass +Traceback (most recent call last): +SyntaxError: expected default value expression + +>>> def foo(a,d: int=,c): +... pass +Traceback (most recent call last): +SyntaxError: expected default value expression + +>>> lambda /,a,b,c: None +Traceback (most recent call last): +SyntaxError: at least one argument must precede / + +>>> lambda a,/,/,b,c: None +Traceback (most recent call last): +SyntaxError: / may appear only once + +>>> lambda a,/,a1,/,b,c: None +Traceback (most recent call last): +SyntaxError: / may appear only once + +>>> lambda a=1,/,/,*b,/,c: None +Traceback (most recent call last): +SyntaxError: / may appear only once + +>>> lambda a,/,a1=1,/,b,c: None +Traceback (most recent call last): +SyntaxError: / may appear only once + +>>> lambda a,*b,c,/,d,e: None +Traceback (most recent call last): +SyntaxError: / must be ahead of * + +>>> lambda a=1,*b,c=3,/,d,e: None +Traceback (most recent call last): +SyntaxError: / must be ahead of * + +>>> lambda a=1,/*,b,c: None +Traceback (most recent call last): +SyntaxError: expected comma between / and * + +>>> lambda a,*b=3,c: None +Traceback (most recent call last): +SyntaxError: var-positional argument cannot have default value + +>>> lambda a,**b=3: None +Traceback (most recent call last): +SyntaxError: var-keyword argument cannot have default value + +>>> lambda a, *a, b, **c, d: None +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> lambda a,*a, b, **c, d=4: None +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> lambda a,*a, b, **c, *d: None +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> lambda a,*a, b, **c, **d: None +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> lambda a=1,/,**b,/,c: None +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> lambda *b,*d: None +Traceback (most recent call last): +SyntaxError: * argument may appear only once + +>>> lambda a,*b,c,*d,*e,c: None +Traceback (most recent call last): +SyntaxError: * argument may appear only once + +>>> lambda a,b,/,c,*b,c,*d,*e,c: None +Traceback (most recent call last): +SyntaxError: * argument may appear only once + +>>> lambda a,b,/,c,*b,c,*d,**e: None +Traceback (most recent call last): +SyntaxError: * argument may appear only once + +>>> lambda a=1,d=,c: None +Traceback (most recent call last): +SyntaxError: expected default value expression + +>>> lambda a,d=,c: None +Traceback (most recent call last): +SyntaxError: expected default value expression + +>>> lambda a,d=3,c: None +Traceback (most recent call last): +SyntaxError: parameter without a default follows parameter with a default + +>>> lambda a,/,d=3,c: None +Traceback (most recent call last): +SyntaxError: parameter without a default follows parameter with a default + >>> import ast; ast.parse(''' ... def f( ... *, # type: int @@ -403,7 +620,7 @@ SyntaxError: Generator expression must be parenthesized >>> class C(x for x in L): ... pass Traceback (most recent call last): -SyntaxError: expected ':' +SyntaxError: invalid syntax >>> def g(*args, **kwargs): ... print(args, sorted(kwargs.items())) @@ -539,6 +756,27 @@ SyntaxError: cannot assign to __debug__ >>> __debug__: int Traceback (most recent call last): SyntaxError: cannot assign to __debug__ +>>> f(a=) +Traceback (most recent call last): +SyntaxError: expected argument value expression +>>> f(a, b, c=) +Traceback (most recent call last): +SyntaxError: expected argument value expression +>>> f(a, b, c=, d) +Traceback (most recent call last): +SyntaxError: expected argument value expression +>>> f(*args=[0]) +Traceback (most recent call last): +SyntaxError: cannot assign to iterable argument unpacking +>>> f(a, b, *args=[0]) +Traceback (most recent call last): +SyntaxError: cannot assign to iterable argument unpacking +>>> f(**kwargs={'a': 1}) +Traceback (most recent call last): +SyntaxError: cannot assign to keyword argument unpacking +>>> f(a, b, *args, **kwargs={'a': 1}) +Traceback (most recent call last): +SyntaxError: cannot assign to keyword argument unpacking More set_context(): @@ -759,17 +997,22 @@ leading to spurious errors. ... SyntaxError: cannot assign to function call here. Maybe you meant '==' instead of '='? - Missing ':' before suites: +Missing ':' before suites: - >>> def f() - ... pass - Traceback (most recent call last): - SyntaxError: expected ':' + >>> def f() + ... pass + Traceback (most recent call last): + SyntaxError: expected ':' - >>> class A - ... pass - Traceback (most recent call last): - SyntaxError: expected ':' + >>> class A + ... pass + Traceback (most recent call last): + SyntaxError: expected ':' + + >>> class R&D: + ... pass + Traceback (most recent call last): + SyntaxError: invalid syntax >>> if 1 ... pass @@ -803,6 +1046,11 @@ leading to spurious errors. Traceback (most recent call last): SyntaxError: expected ':' + >>> for x in range 10: + ... pass + Traceback (most recent call last): + SyntaxError: invalid syntax + >>> while True ... pass Traceback (most recent call last): @@ -848,6 +1096,11 @@ leading to spurious errors. Traceback (most recent call last): SyntaxError: expected ':' + >>> with block ad something: + ... pass + Traceback (most recent call last): + SyntaxError: invalid syntax + >>> try ... pass Traceback (most recent call last): @@ -866,6 +1119,12 @@ leading to spurious errors. Traceback (most recent call last): SyntaxError: expected ':' + >>> match x x: + ... case list(): + ... pass + Traceback (most recent call last): + SyntaxError: invalid syntax + >>> match x: ... case list() ... pass @@ -955,6 +1214,48 @@ Custom error messages for try blocks that are not followed by except/finally Traceback (most recent call last): SyntaxError: expected 'except' or 'finally' block +Custom error message for try block mixing except and except* + + >>> try: + ... pass + ... except TypeError: + ... pass + ... except* ValueError: + ... pass + Traceback (most recent call last): + SyntaxError: cannot have both 'except' and 'except*' on the same 'try' + + >>> try: + ... pass + ... except* TypeError: + ... pass + ... except ValueError: + ... pass + Traceback (most recent call last): + SyntaxError: cannot have both 'except' and 'except*' on the same 'try' + + >>> try: + ... pass + ... except TypeError: + ... pass + ... except TypeError: + ... pass + ... except* ValueError: + ... pass + Traceback (most recent call last): + SyntaxError: cannot have both 'except' and 'except*' on the same 'try' + + >>> try: + ... pass + ... except* TypeError: + ... pass + ... except* TypeError: + ... pass + ... except ValueError: + ... pass + Traceback (most recent call last): + SyntaxError: cannot have both 'except' and 'except*' on the same 'try' + Ensure that early = are not matched by the parser as invalid comparisons >>> f(2, 4, x=34); 1 $ 2 Traceback (most recent call last): @@ -998,12 +1299,22 @@ Incomplete dictionary literals Traceback (most recent call last): SyntaxError: expression expected after dictionary key and ':' - # Ensure that the error is not raise for syntax errors that happen after sets + # Ensure that the error is not raised for syntax errors that happen after sets >>> {1} $ Traceback (most recent call last): SyntaxError: invalid syntax + # Ensure that the error is not raised for invalid expressions + + >>> {1: 2, 3: foo(,), 4: 5} + Traceback (most recent call last): + SyntaxError: invalid syntax + + >>> {1: $, 2: 3} + Traceback (most recent call last): + SyntaxError: invalid syntax + Specialized indentation errors: >>> while condition: @@ -1063,7 +1374,7 @@ Specialized indentation errors: >>> try: ... something() - ... except A: + ... except: ... pass Traceback (most recent call last): IndentationError: expected an indented block after 'except' statement on line 3 @@ -1071,6 +1382,29 @@ Specialized indentation errors: >>> try: ... something() ... except A: + ... pass + Traceback (most recent call last): + IndentationError: expected an indented block after 'except' statement on line 3 + + >>> try: + ... something() + ... except* A: + ... pass + Traceback (most recent call last): + IndentationError: expected an indented block after 'except*' statement on line 3 + + >>> try: + ... something() + ... except A: + ... pass + ... finally: + ... pass + Traceback (most recent call last): + IndentationError: expected an indented block after 'finally' statement on line 5 + + >>> try: + ... something() + ... except* A: ... pass ... finally: ... pass @@ -1180,6 +1514,48 @@ raise a custom exception SyntaxError: multiple exception types must be parenthesized + >>> try: + ... pass + ... except* A, B: + ... pass + Traceback (most recent call last): + SyntaxError: multiple exception types must be parenthesized + + >>> try: + ... pass + ... except* A, B, C: + ... pass + Traceback (most recent call last): + SyntaxError: multiple exception types must be parenthesized + + >>> try: + ... pass + ... except* A, B, C as blech: + ... pass + Traceback (most recent call last): + SyntaxError: multiple exception types must be parenthesized + + >>> try: + ... pass + ... except* A, B, C as blech: + ... pass + ... finally: + ... pass + Traceback (most recent call last): + SyntaxError: multiple exception types must be parenthesized + +Custom exception for 'except*' without an exception type + + >>> try: + ... pass + ... except* A as a: + ... pass + ... except*: + ... pass + Traceback (most recent call last): + SyntaxError: expected one or more exception types + + >>> f(a=23, a=234) Traceback (most recent call last): ... @@ -1229,6 +1605,22 @@ SyntaxError: trailing comma not allowed without surrounding parentheses Traceback (most recent call last): SyntaxError: trailing comma not allowed without surrounding parentheses +>>> import a from b +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a.y.z from b.y.z +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a from b as bar +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a.y.z from b.y.z as bar +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + # Check that we dont raise the "trailing comma" error if there is more # input to the left of the valid part that we parsed. @@ -1318,6 +1710,149 @@ Corner-cases that used to crash: ... ... Traceback (most recent call last): SyntaxError: positional patterns follow keyword patterns + +Uses of the star operator which should fail: + +A[:*b] + + >>> A[:*b] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> A[:(*b)] + Traceback (most recent call last): + ... + SyntaxError: cannot use starred expression here + >>> A[:*b] = 1 + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> del A[:*b] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +A[*b:] + + >>> A[*b:] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> A[(*b):] + Traceback (most recent call last): + ... + SyntaxError: cannot use starred expression here + >>> A[*b:] = 1 + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> del A[*b:] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +A[*b:*b] + + >>> A[*b:*b] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> A[(*b:*b)] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> A[*b:*b] = 1 + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> del A[*b:*b] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +A[*(1:2)] + + >>> A[*(1:2)] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> A[*(1:2)] = 1 + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> del A[*(1:2)] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +A[*:] and A[:*] + + >>> A[*:] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> A[:*] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +A[*] + + >>> A[*] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +A[**] + + >>> A[**] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +A[**b] + + >>> A[**b] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> A[**b] = 1 + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> del A[**b] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +def f(x: *b) + + >>> def f6(x: *b): pass + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> def f7(x: *b = 1): pass + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +**kwargs: *a + + >>> def f8(**kwargs: *a): pass + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +x: *b + + >>> x: *b + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> x: *b = 1 + Traceback (most recent call last): + ... + SyntaxError: invalid syntax """ import re @@ -1500,6 +2035,16 @@ class SyntaxTestCase(unittest.TestCase): "Generator expression must be parenthesized", lineno=1, end_lineno=1, offset=11, end_offset=53) + def test_except_then_except_star(self): + self._check_error("try: pass\nexcept ValueError: pass\nexcept* TypeError: pass", + r"cannot have both 'except' and 'except\*' on the same 'try'", + lineno=3, end_lineno=3, offset=1, end_offset=8) + + def test_except_star_then_except(self): + self._check_error("try: pass\nexcept* ValueError: pass\nexcept TypeError: pass", + r"cannot have both 'except' and 'except\*' on the same 'try'", + lineno=3, end_lineno=3, offset=1, end_offset=7) + def test_empty_line_after_linecont(self): # See issue-40847 s = r"""\ @@ -1513,6 +2058,37 @@ pass except SyntaxError: self.fail("Empty line after a line continuation character is valid.") + # See issue-46091 + s1 = r"""\ +def fib(n): + \ +'''Print a Fibonacci series up to n.''' + \ +a, b = 0, 1 +""" + s2 = r"""\ +def fib(n): + '''Print a Fibonacci series up to n.''' + a, b = 0, 1 +""" + try: + compile(s1, '', 'exec') + compile(s2, '', 'exec') + except SyntaxError: + self.fail("Indented statement over multiple lines is valid") + + def test_continuation_bad_indentation(self): + # Check that code that breaks indentation across multiple lines raises a syntax error + + code = r"""\ +if x: + y = 1 + \ + foo = 1 + """ + + self.assertRaises(IndentationError, exec, code) + @support.cpython_only def test_nested_named_except_blocks(self): code = "" @@ -1563,9 +2139,28 @@ def func2(): for paren in "([{": self._check_error(paren + "1 + 2", f"\\{paren}' was never closed") + for paren in "([{": + self._check_error(f"a = {paren} 1, 2, 3\nb=3", f"\\{paren}' was never closed") + for paren in ")]}": self._check_error(paren + "1 + 2", f"unmatched '\\{paren}'") + # Some more complex examples: + code = """\ +func( + a=["unclosed], # Need a quote in this comment: " + b=2, +) +""" + self._check_error(code, "parenthesis '\\)' does not match opening parenthesis '\\['") + + def test_error_string_literal(self): + + self._check_error("'blech", "unterminated string literal") + self._check_error('"blech', "unterminated string literal") + self._check_error("'''blech", "unterminated triple-quoted string literal") + self._check_error('"""blech', "unterminated triple-quoted string literal") + def test_invisible_characters(self): self._check_error('print\x17("Hello")', "invalid non-printable character") @@ -1629,6 +2224,22 @@ while 1: """ self._check_error(source, "too many statically nested blocks") + @support.cpython_only + def test_error_on_parser_stack_overflow(self): + source = "-" * 100000 + "4" + for mode in ["exec", "eval", "single"]: + with self.subTest(mode=mode): + with self.assertRaises(MemoryError): + compile(source, "", mode) + + @support.cpython_only + def test_deep_invalid_rule(self): + # Check that a very deep invalid rule in the PEG + # parser doesn't have exponential backtracking. + source = "d{{{{{{{{{{{{{{{{{{{{{{{{{```{{{{{{{ef f():y" + with self.assertRaises(SyntaxError): + compile(source, "", "exec") + def load_tests(loader, tests, pattern): tests.addTest(doctest.DocTestSuite()) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index b0688e1e605..ab1a0659471 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -71,6 +71,69 @@ class DisplayHookTest(unittest.TestCase): code = compile("42", "", "single") self.assertRaises(ValueError, eval, code) +class ActiveExceptionTests(unittest.TestCase): + def test_exc_info_no_exception(self): + self.assertEqual(sys.exc_info(), (None, None, None)) + + def test_sys_exception_no_exception(self): + self.assertEqual(sys.exception(), None) + + def test_exc_info_with_exception_instance(self): + def f(): + raise ValueError(42) + + try: + f() + except Exception as e_: + e = e_ + exc_info = sys.exc_info() + + self.assertIsInstance(e, ValueError) + self.assertIs(exc_info[0], ValueError) + self.assertIs(exc_info[1], e) + self.assertIs(exc_info[2], e.__traceback__) + + def test_exc_info_with_exception_type(self): + def f(): + raise ValueError + + try: + f() + except Exception as e_: + e = e_ + exc_info = sys.exc_info() + + self.assertIsInstance(e, ValueError) + self.assertIs(exc_info[0], ValueError) + self.assertIs(exc_info[1], e) + self.assertIs(exc_info[2], e.__traceback__) + + def test_sys_exception_with_exception_instance(self): + def f(): + raise ValueError(42) + + try: + f() + except Exception as e_: + e = e_ + exc = sys.exception() + + self.assertIsInstance(e, ValueError) + self.assertIs(exc, e) + + def test_sys_exception_with_exception_type(self): + def f(): + raise ValueError + + try: + f() + except Exception as e_: + e = e_ + exc = sys.exception() + + self.assertIsInstance(e, ValueError) + self.assertIs(exc, e) + class ExceptHookTest(unittest.TestCase): @@ -336,8 +399,29 @@ class SysModuleTest(unittest.TestCase): is sys._getframe().f_code ) + def test_getframemodulename(self): + # Default depth gets ourselves + self.assertEqual(__name__, sys._getframemodulename()) + self.assertEqual("unittest.case", sys._getframemodulename(1)) + i = 0 + f = sys._getframe(i) + while f: + self.assertEqual( + f.f_globals['__name__'], + sys._getframemodulename(i) or '__main__' + ) + i += 1 + f2 = f.f_back + try: + f = sys._getframe(i) + except ValueError: + break + self.assertIs(f, f2) + self.assertIsNone(sys._getframemodulename(i)) + # sys._current_frames() is a CPython-only gimmick. @threading_helper.reap_threads + @threading_helper.requires_working_threading() def test_current_frames(self): import threading import traceback @@ -403,6 +487,7 @@ class SysModuleTest(unittest.TestCase): t.join() @threading_helper.reap_threads + @threading_helper.requires_working_threading() def test_current_exceptions(self): import threading import traceback @@ -485,11 +570,17 @@ class SysModuleTest(unittest.TestCase): self.assertIsInstance(sys.executable, str) self.assertEqual(len(sys.float_info), 11) self.assertEqual(sys.float_info.radix, 2) - self.assertEqual(len(sys.int_info), 2) + self.assertEqual(len(sys.int_info), 4) self.assertTrue(sys.int_info.bits_per_digit % 5 == 0) self.assertTrue(sys.int_info.sizeof_digit >= 1) + self.assertGreaterEqual(sys.int_info.default_max_str_digits, 500) + self.assertGreaterEqual(sys.int_info.str_digits_check_threshold, 100) + self.assertGreater(sys.int_info.default_max_str_digits, + sys.int_info.str_digits_check_threshold) self.assertEqual(type(sys.int_info.bits_per_digit), int) self.assertEqual(type(sys.int_info.sizeof_digit), int) + self.assertIsInstance(sys.int_info.default_max_str_digits, int) + self.assertIsInstance(sys.int_info.str_digits_check_threshold, int) self.assertIsInstance(sys.hexversion, int) self.assertEqual(len(sys.hash_info), 9) @@ -561,8 +652,24 @@ class SysModuleTest(unittest.TestCase): def test_thread_info(self): info = sys.thread_info self.assertEqual(len(info), 3) - self.assertIn(info.name, ('nt', 'pthread', 'solaris', None)) + self.assertIn(info.name, ('nt', 'pthread', 'pthread-stubs', 'solaris', None)) self.assertIn(info.lock, ('semaphore', 'mutex+cond', None)) + if sys.platform.startswith(("linux", "freebsd")): + self.assertEqual(info.name, "pthread") + elif sys.platform == "win32": + self.assertEqual(info.name, "nt") + elif sys.platform == "emscripten": + self.assertIn(info.name, {"pthread", "pthread-stubs"}) + elif sys.platform == "wasi": + self.assertEqual(info.name, "pthread-stubs") + + @unittest.skipUnless(support.is_emscripten, "only available on Emscripten") + def test_emscripten_info(self): + self.assertEqual(len(sys._emscripten_info), 4) + self.assertIsInstance(sys._emscripten_info.emscripten_version, tuple) + self.assertIsInstance(sys._emscripten_info.runtime, (str, type(None))) + self.assertIsInstance(sys._emscripten_info.pthreads, bool) + self.assertIsInstance(sys._emscripten_info.shared_memory, bool) def test_43581(self): # Can't use sys.stdout, as this is a StringIO object when @@ -596,10 +703,10 @@ class SysModuleTest(unittest.TestCase): "dont_write_bytecode", "no_user_site", "no_site", "ignore_environment", "verbose", "bytes_warning", "quiet", "hash_randomization", "isolated", "dev_mode", "utf8_mode", - "warn_default_encoding") + "warn_default_encoding", "safe_path", "int_max_str_digits") for attr in attrs: self.assertTrue(hasattr(sys.flags, attr), attr) - attr_type = bool if attr == "dev_mode" else int + attr_type = bool if attr in ("dev_mode", "safe_path") else int self.assertEqual(type(getattr(sys.flags, attr)), attr_type, attr) self.assertTrue(repr(sys.flags)) self.assertEqual(len(sys.flags), len(attrs)) @@ -631,6 +738,7 @@ class SysModuleTest(unittest.TestCase): def test_clear_type_cache(self): sys._clear_type_cache() + @support.requires_subprocess() def test_ioencoding(self): env = dict(os.environ) @@ -678,6 +786,7 @@ class SysModuleTest(unittest.TestCase): 'requires OS support of non-ASCII encodings') @unittest.skipUnless(sys.getfilesystemencoding() == locale.getpreferredencoding(False), 'requires FS encoding to match locale') + @support.requires_subprocess() def test_ioencoding_nonascii(self): env = dict(os.environ) @@ -690,6 +799,7 @@ class SysModuleTest(unittest.TestCase): @unittest.skipIf(sys.base_prefix != sys.prefix, 'Test is not venv-compatible') + @support.requires_subprocess() def test_executable(self): # sys.executable should be absolute self.assertEqual(os.path.abspath(sys.executable), sys.executable) @@ -791,9 +901,11 @@ class SysModuleTest(unittest.TestCase): 'stdout: surrogateescape\n' 'stderr: backslashreplace\n') + @support.requires_subprocess() def test_c_locale_surrogateescape(self): self.check_locale_surrogateescape('C') + @support.requires_subprocess() def test_posix_locale_surrogateescape(self): self.check_locale_surrogateescape('POSIX') @@ -942,6 +1054,7 @@ class SysModuleTest(unittest.TestCase): self.assertIsInstance(level, int) self.assertGreater(level, 0) + @support.requires_subprocess() def test_sys_tracebacklimit(self): code = """if 1: import sys @@ -988,6 +1101,7 @@ class SysModuleTest(unittest.TestCase): out = out.decode('ascii', 'replace').rstrip() self.assertEqual(out, 'mbcs replace') + @support.requires_subprocess() def test_orig_argv(self): code = textwrap.dedent(''' import sys @@ -1106,11 +1220,12 @@ class UnraisableHookTest(unittest.TestCase): for moduleName in 'builtins', '__main__', 'some_module': with self.subTest(moduleName=moduleName): A.B.X.__module__ = moduleName - with test.support.captured_stderr() as stderr, \ - test.support.swap_attr(sys, 'unraisablehook', - sys.__unraisablehook__): - expected = self.write_unraisable_exc( - A.B.X(), "msg", "obj"); + with test.support.captured_stderr() as stderr, test.support.swap_attr( + sys, 'unraisablehook', sys.__unraisablehook__ + ): + expected = self.write_unraisable_exc( + A.B.X(), "msg", "obj" + ) report = stderr.getvalue() self.assertIn(A.B.X.__qualname__, report) if moduleName in ['builtins', '__main__']: @@ -1206,7 +1321,7 @@ class SizeofTest(unittest.TestCase): def __sizeof__(self): return int(self) self.assertEqual(sys.getsizeof(OverflowSizeof(sys.maxsize)), - sys.maxsize + self.gc_headsize) + sys.maxsize + self.gc_headsize*2) with self.assertRaises(OverflowError): sys.getsizeof(OverflowSizeof(sys.maxsize + 1)) with self.assertRaises(ValueError): @@ -1227,6 +1342,7 @@ class SizeofTest(unittest.TestCase): check = self.check_sizeof # bool check(True, vsize('') + self.longdigit) + check(False, vsize('') + self.longdigit) # buffer # XXX # builtin_function_or_method @@ -1276,8 +1392,12 @@ class SizeofTest(unittest.TestCase): check({}.__iter__, size('2P')) # empty dict check({}, size('nQ2P')) - # dict - check({"a": 1}, size('nQ2P') + calcsize(DICT_KEY_STRUCT_FORMAT) + 8 + (8*2//3)*calcsize('n2P')) + # dict (string key) + check({"a": 1}, size('nQ2P') + calcsize(DICT_KEY_STRUCT_FORMAT) + 8 + (8*2//3)*calcsize('2P')) + longdict = {str(i): i for i in range(8)} + check(longdict, size('nQ2P') + calcsize(DICT_KEY_STRUCT_FORMAT) + 16 + (16*2//3)*calcsize('2P')) + # dict (non-string key) + check({1: 1}, size('nQ2P') + calcsize(DICT_KEY_STRUCT_FORMAT) + 8 + (8*2//3)*calcsize('n2P')) longdict = {1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8} check(longdict, size('nQ2P') + calcsize(DICT_KEY_STRUCT_FORMAT) + 16 + (16*2//3)*calcsize('n2P')) # dictionary-keyview @@ -1298,13 +1418,13 @@ class SizeofTest(unittest.TestCase): class C(object): pass check(C.__dict__, size('P')) # BaseException - check(BaseException(), size('5Pb')) + check(BaseException(), size('6Pb')) # UnicodeEncodeError - check(UnicodeEncodeError("", "", 0, 0, ""), size('5Pb 2P2nP')) + check(UnicodeEncodeError("", "", 0, 0, ""), size('6Pb 2P2nP')) # UnicodeDecodeError - check(UnicodeDecodeError("", b"", 0, 0, ""), size('5Pb 2P2nP')) + check(UnicodeDecodeError("", b"", 0, 0, ""), size('6Pb 2P2nP')) # UnicodeTranslateError - check(UnicodeTranslateError("", 0, 1, ""), size('5Pb 2P2nP')) + check(UnicodeTranslateError("", 0, 1, ""), size('6Pb 2P2nP')) # ellipses check(Ellipsis, size('')) # EncodingMap @@ -1312,7 +1432,7 @@ class SizeofTest(unittest.TestCase): x = codecs.charmap_build(encodings.iso8859_3.decoding_table) check(x, size('32B2iB')) # enumerate - check(enumerate([]), size('n3P')) + check(enumerate([]), size('n4P')) # reverse check(reversed(''), size('nP')) # float @@ -1320,9 +1440,10 @@ class SizeofTest(unittest.TestCase): # sys.floatinfo check(sys.float_info, vsize('') + self.P * len(sys.float_info)) # frame - import inspect - x = inspect.currentframe() - check(x, size('3Pi3c')) + def func(): + return sys._getframe() + x = func() + check(x, size('3Pi3c7P2ic??2P')) # function def func(): pass check(func, size('14Pi')) @@ -1339,16 +1460,17 @@ class SizeofTest(unittest.TestCase): check(bar, size('PP')) # generator def get_gen(): yield 1 - check(get_gen(), size('P2PPP4P')) + check(get_gen(), size('P2P4P4c7P2ic??2P')) # iterator check(iter('abc'), size('lP')) # callable-iterator import re check(re.finditer('',''), size('2P')) # list - samples = [[], [1,2,3], ['1', '2', '3']] - for sample in samples: - check(list(sample), vsize('Pn') + len(sample)*self.P) + check(list([]), vsize('Pn')) + check(list([1]), vsize('Pn') + 2*self.P) + check(list([1, 2]), vsize('Pn') + 2*self.P) + check(list([1, 2, 3]), vsize('Pn') + 4*self.P) # sortwrapper (list) # XXX # cmpwrapper (list) @@ -1358,7 +1480,7 @@ class SizeofTest(unittest.TestCase): # listreverseiterator (list) check(reversed([]), size('nP')) # int - check(0, vsize('')) + check(0, vsize('') + self.longdigit) check(1, vsize('') + self.longdigit) check(-1, vsize('') + self.longdigit) PyLong_BASE = 2**sys.int_info.bits_per_digit @@ -1383,7 +1505,8 @@ class SizeofTest(unittest.TestCase): # PyCapsule # XXX # rangeiterator - check(iter(range(1)), size('4l')) + check(iter(range(1)), size('3l')) + check(iter(range(2**65)), size('3P')) # reverse check(reversed(''), size('nP')) # range @@ -1420,8 +1543,8 @@ class SizeofTest(unittest.TestCase): check((1,2,3), vsize('') + 3*self.P) # type # static type: PyTypeObject - fmt = 'P2nPI13Pl4Pn9Pn12PIPP' - s = vsize(fmt) + fmt = 'P2nPI13Pl4Pn9Pn12PIPc' + s = vsize('2P' + fmt) check(int, s) # class s = vsize(fmt + # PyTypeObject @@ -1430,18 +1553,21 @@ class SizeofTest(unittest.TestCase): '3P' # PyMappingMethods '10P' # PySequenceMethods '2P' # PyBufferProcs - '6P') + '6P' + '1P' # Specializer cache + ) class newstyleclass(object): pass # Separate block for PyDictKeysObject with 8 keys and 5 entries - check(newstyleclass, s + calcsize(DICT_KEY_STRUCT_FORMAT) + 32 + 21*calcsize("n2P")) + check(newstyleclass, s + calcsize(DICT_KEY_STRUCT_FORMAT) + 64 + 42*calcsize("2P")) # dict with shared keys - check(newstyleclass().__dict__, size('nQ2P') + 15*self.P) + [newstyleclass() for _ in range(100)] + check(newstyleclass().__dict__, size('nQ2P') + self.P) o = newstyleclass() o.a = o.b = o.c = o.d = o.e = o.f = o.g = o.h = 1 # Separate block for PyDictKeysObject with 16 keys and 10 entries - check(newstyleclass, s + calcsize(DICT_KEY_STRUCT_FORMAT) + 32 + 21*calcsize("n2P")) + check(newstyleclass, s + calcsize(DICT_KEY_STRUCT_FORMAT) + 64 + 42*calcsize("2P")) # dict with shared keys - check(newstyleclass().__dict__, size('nQ2P') + 13*self.P) + check(newstyleclass().__dict__, size('nQ2P') + self.P) # unicode # each tuple contains a string and its expected character size # don't put any static strings here, as they may contain @@ -1449,8 +1575,9 @@ class SizeofTest(unittest.TestCase): samples = ['1'*100, '\xff'*50, '\u0100'*40, '\uffff'*100, '\U00010000'*30, '\U0010ffff'*100] - asciifields = "nnbP" - compactfields = asciifields + "nPn" + # also update field definitions in test_unicode.test_raiseMemError + asciifields = "nnb" + compactfields = asciifields + "nP" unicodefields = compactfields + "P" for s in samples: maxchar = ord(max(s)) @@ -1474,11 +1601,11 @@ class SizeofTest(unittest.TestCase): # TODO: add check that forces layout of unicodefields # weakref import weakref - check(weakref.ref(int), size('2Pn2P')) + check(weakref.ref(int), size('2Pn3P')) # weakproxy # XXX # weakcallableproxy - check(weakref.proxy(int), size('2Pn2P')) + check(weakref.proxy(int), size('2Pn3P')) def check_slots(self, obj, base, extra): expected = sys.getsizeof(base) + struct.calcsize(extra) diff --git a/Lib/test/test_sys_setprofile.py b/Lib/test/test_sys_setprofile.py index 21a09b51926..acae433cd0a 100644 --- a/Lib/test/test_sys_setprofile.py +++ b/Lib/test/test_sys_setprofile.py @@ -2,6 +2,7 @@ import gc import pprint import sys import unittest +from test import support class TestGetProfile(unittest.TestCase): @@ -415,5 +416,39 @@ def show_events(callable): pprint.pprint(capture_events(callable)) +class TestEdgeCases(unittest.TestCase): + + def setUp(self): + self.addCleanup(sys.setprofile, sys.getprofile()) + sys.setprofile(None) + + def test_reentrancy(self): + def foo(*args): + ... + + def bar(*args): + ... + + class A: + def __call__(self, *args): + pass + + def __del__(self): + sys.setprofile(bar) + + sys.setprofile(A()) + sys.setprofile(foo) + self.assertEqual(sys.getprofile(), bar) + + + def test_same_object(self): + def foo(*args): + ... + + sys.setprofile(foo) + del foo + sys.setprofile(sys.getprofile()) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index b565bef4c44..a251b2272e9 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -2,12 +2,15 @@ from test import support import unittest +from unittest.mock import MagicMock import sys import difflib import gc from functools import wraps import asyncio +from test.support import import_helper +support.requires_working_socket(module=True) class tracecontext: """Context manager that traces its enter and exit.""" @@ -343,7 +346,7 @@ class TraceTestCase(unittest.TestCase): return Tracer() def compare_events(self, line_offset, events, expected_events): - events = [(l - line_offset, e) for (l, e) in events] + events = [(l - line_offset if l is not None else None, e) for (l, e) in events] if events != expected_events: self.fail( "events did not match expectation:\n" + @@ -607,6 +610,58 @@ class TraceTestCase(unittest.TestCase): self.compare_events(doit_async.__code__.co_firstlineno, tracer.events, events) + def test_async_for_backwards_jump_has_no_line(self): + async def arange(n): + for i in range(n): + yield i + async def f(): + async for i in arange(3): + if i > 100: + break # should never be traced + + tracer = self.make_tracer() + coro = f() + try: + sys.settrace(tracer.trace) + coro.send(None) + except Exception: + pass + finally: + sys.settrace(None) + + events = [ + (0, 'call'), + (1, 'line'), + (-3, 'call'), + (-2, 'line'), + (-1, 'line'), + (-1, 'return'), + (1, 'exception'), + (2, 'line'), + (1, 'line'), + (-1, 'call'), + (-2, 'line'), + (-1, 'line'), + (-1, 'return'), + (1, 'exception'), + (2, 'line'), + (1, 'line'), + (-1, 'call'), + (-2, 'line'), + (-1, 'line'), + (-1, 'return'), + (1, 'exception'), + (2, 'line'), + (1, 'line'), + (-1, 'call'), + (-2, 'line'), + (-2, 'return'), + (1, 'exception'), + (1, 'return'), + ] + self.compare_events(f.__code__.co_firstlineno, + tracer.events, events) + def test_21_repeated_pass(self): def func(): pass @@ -642,15 +697,59 @@ class TraceTestCase(unittest.TestCase): 2 except: 4 - finally: + else: 6 + if False: + 8 + else: + 10 + if func.__name__ == 'Fred': + 12 + finally: + 14 self.run_and_compare(func, [(0, 'call'), (1, 'line'), (2, 'line'), (6, 'line'), - (6, 'return')]) + (7, 'line'), + (10, 'line'), + (11, 'line'), + (14, 'line'), + (14, 'return')]) + + def test_try_exception_in_else(self): + + def func(): + try: + try: + 3 + except: + 5 + else: + 7 + raise Exception + finally: + 10 + except: + 12 + finally: + 14 + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (3, 'line'), + (7, 'line'), + (8, 'line'), + (8, 'exception'), + (10, 'line'), + (11, 'line'), + (12, 'line'), + (14, 'line'), + (14, 'return')]) def test_nested_loops(self): @@ -735,9 +834,8 @@ class TraceTestCase(unittest.TestCase): (5, 'line'), (6, 'line'), (7, 'line'), - (10, 'line'), - (13, 'line'), - (13, 'return')]) + (10, 'line')] + + ([(13, 'line'), (13, 'return')] if __debug__ else [(10, 'return')])) def test_continue_through_finally(self): @@ -772,9 +870,8 @@ class TraceTestCase(unittest.TestCase): (6, 'line'), (7, 'line'), (10, 'line'), - (3, 'line'), - (13, 'line'), - (13, 'return')]) + (3, 'line')] + + ([(13, 'line'), (13, 'return')] if __debug__ else [(3, 'return')])) def test_return_through_finally(self): @@ -1016,6 +1113,47 @@ class TraceTestCase(unittest.TestCase): (3, 'line'), (3, 'return')]) + def test_try_in_try_with_exception(self): + + def func(): + try: + try: + raise TypeError + except ValueError as ex: + 5 + except TypeError: + 7 + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (3, 'line'), + (3, 'exception'), + (4, 'line'), + (6, 'line'), + (7, 'line'), + (7, 'return')]) + + def func(): + try: + try: + raise ValueError + except ValueError as ex: + 5 + except TypeError: + 7 + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (3, 'line'), + (3, 'exception'), + (4, 'line'), + (5, 'line'), + (5, 'return')]) + def test_if_in_if_in_if(self): def func(a=0, p=1, z=1): if p: @@ -1169,6 +1307,298 @@ class TraceTestCase(unittest.TestCase): (5, 'line'), (5, 'return')]) + def test_try_except_star_no_exception(self): + + def func(): + try: + 2 + except* Exception: + 4 + else: + 6 + if False: + 8 + else: + 10 + if func.__name__ == 'Fred': + 12 + finally: + 14 + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (6, 'line'), + (7, 'line'), + (10, 'line'), + (11, 'line'), + (14, 'line'), + (14, 'return')]) + + def test_try_except_star_named_no_exception(self): + + def func(): + try: + 2 + except* Exception as e: + 4 + else: + 6 + finally: + 8 + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (6, 'line'), + (8, 'line'), + (8, 'return')]) + + def test_try_except_star_exception_caught(self): + + def func(): + try: + raise ValueError(2) + except* ValueError: + 4 + else: + 6 + finally: + 8 + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (2, 'exception'), + (3, 'line'), + (4, 'line'), + (8, 'line'), + (8, 'return')]) + + def test_try_except_star_named_exception_caught(self): + + def func(): + try: + raise ValueError(2) + except* ValueError as e: + 4 + else: + 6 + finally: + 8 + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (2, 'exception'), + (3, 'line'), + (4, 'line'), + (8, 'line'), + (8, 'return')]) + + def test_try_except_star_exception_not_caught(self): + + def func(): + try: + try: + raise ValueError(3) + except* TypeError: + 5 + except ValueError: + 7 + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (3, 'line'), + (3, 'exception'), + (4, 'line'), + (6, 'line'), + (7, 'line'), + (7, 'return')]) + + def test_try_except_star_named_exception_not_caught(self): + + def func(): + try: + try: + raise ValueError(3) + except* TypeError as e: + 5 + except ValueError: + 7 + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (3, 'line'), + (3, 'exception'), + (4, 'line'), + (6, 'line'), + (7, 'line'), + (7, 'return')]) + + def test_try_except_star_nested(self): + + def func(): + try: + try: + raise ExceptionGroup( + 'eg', + [ValueError(5), TypeError('bad type')]) + except* TypeError as e: + 7 + except* OSError: + 9 + except* ValueError: + raise + except* ValueError: + try: + raise TypeError(14) + except* OSError: + 16 + except* TypeError as e: + 18 + return 0 + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (3, 'line'), + (4, 'line'), + (5, 'line'), + (3, 'line'), + (3, 'exception'), + (6, 'line'), + (7, 'line'), + (8, 'line'), + (10, 'line'), + (11, 'line'), + (12, 'line'), + (13, 'line'), + (14, 'line'), + (14, 'exception'), + (15, 'line'), + (17, 'line'), + (18, 'line'), + (19, 'line'), + (19, 'return')]) + + def test_notrace_lambda(self): + #Regression test for issue 46314 + + def func(): + 1 + lambda x: 2 + 3 + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (3, 'line'), + (3, 'return')]) + + def test_class_creation_with_docstrings(self): + + def func(): + class Class_1: + ''' the docstring. 2''' + def __init__(self): + ''' Another docstring. 4''' + self.a = 5 + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (1, 'call'), + (1, 'line'), + (2, 'line'), + (3, 'line'), + (3, 'return'), + (1, 'return')]) + + @support.cpython_only + def test_no_line_event_after_creating_generator(self): + # Spurious line events before call events only show up with C tracer + + # Skip this test if the _testcapi module isn't available. + _testcapi = import_helper.import_module('_testcapi') + + def gen(): + yield 1 + + def func(): + for _ in ( + gen() + ): + pass + + EXPECTED_EVENTS = [ + (0, 'call'), + (2, 'line'), + (1, 'line'), + (-3, 'call'), + (-2, 'line'), + (-2, 'return'), + (4, 'line'), + (1, 'line'), + (-2, 'call'), + (-2, 'return'), + (1, 'return'), + ] + + # C level events should be the same as expected and the same as Python level. + + events = [] + # Turning on and off tracing must be on same line to avoid unwanted LINE events. + _testcapi.settrace_to_record(events); func(); sys.settrace(None) + start_line = func.__code__.co_firstlineno + events = [ + (line-start_line, EVENT_NAMES[what]) + for (what, line, arg) in events + ] + self.assertEqual(events, EXPECTED_EVENTS) + + self.run_and_compare(func, EXPECTED_EVENTS) + + def test_very_large_function(self): + # There is a separate code path when the number of lines > (1 << 15). + d = {} + exec("""def f(): # line 0 + x = 0 # line 1 + y = 1 # line 2 + %s # lines 3 through (1 << 16) + x += 1 # + return""" % ('\n' * (1 << 16),), d) + f = d['f'] + + EXPECTED_EVENTS = [ + (0, 'call'), + (1, 'line'), + (2, 'line'), + (65540, 'line'), + (65541, 'line'), + (65541, 'return'), + ] + + self.run_and_compare(f, EXPECTED_EVENTS) + + +EVENT_NAMES = [ + 'call', + 'exception', + 'line', + 'return' +] + class SkipLineEventsTraceTestCase(TraceTestCase): """Repeat the trace tests, but with per-line events skipped""" @@ -1289,6 +1719,20 @@ class RaisingTraceFuncTestCase(unittest.TestCase): finally: sys.settrace(existing) + def test_line_event_raises_before_opcode_event(self): + exception = ValueError("BOOM!") + def trace(frame, event, arg): + if event == "line": + raise exception + frame.f_trace_opcodes = True + return trace + def f(): + pass + with self.assertRaises(ValueError) as caught: + sys.settrace(trace) + f() + self.assertIs(caught.exception, exception) + # 'Jump' tests: assigning to frame.f_lineno within a trace function # moves the execution position - it's how debuggers implement a Jump @@ -1447,7 +1891,7 @@ class JumpTestCase(unittest.TestCase): output.append(6) output.append(7) - @async_jump_test(4, 5, [3], (ValueError, 'into')) + @async_jump_test(4, 5, [3, 5]) async def test_jump_out_of_async_for_block_forwards(output): for i in [1]: async for i in asynciter([1, 2]): @@ -1489,7 +1933,7 @@ class JumpTestCase(unittest.TestCase): output.append(8) output.append(9) - @jump_test(6, 7, [2], (ValueError, 'within')) + @jump_test(6, 7, [2, 7], (ZeroDivisionError, '')) def test_jump_in_nested_finally_2(output): try: output.append(2) @@ -1500,7 +1944,7 @@ class JumpTestCase(unittest.TestCase): output.append(7) output.append(8) - @jump_test(6, 11, [2], (ValueError, 'within')) + @jump_test(6, 11, [2, 11], (ZeroDivisionError, '')) def test_jump_in_nested_finally_3(output): try: output.append(2) @@ -1611,8 +2055,8 @@ class JumpTestCase(unittest.TestCase): output.append(5) raise - @jump_test(5, 7, [4], (ValueError, 'within')) - def test_no_jump_between_except_blocks(output): + @jump_test(5, 7, [4, 7, 8]) + def test_jump_between_except_blocks(output): try: 1/0 except ZeroDivisionError: @@ -1622,8 +2066,19 @@ class JumpTestCase(unittest.TestCase): output.append(7) output.append(8) - @jump_test(5, 6, [4], (ValueError, 'within')) - def test_no_jump_within_except_block(output): + @jump_test(5, 7, [4, 7, 8]) + def test_jump_from_except_to_finally(output): + try: + 1/0 + except ZeroDivisionError: + output.append(4) + output.append(5) + finally: + output.append(7) + output.append(8) + + @jump_test(5, 6, [4, 6, 7]) + def test_jump_within_except_block(output): try: 1/0 except: @@ -1632,6 +2087,15 @@ class JumpTestCase(unittest.TestCase): output.append(6) output.append(7) + @jump_test(6, 1, [1, 5, 1, 5]) + def test_jump_over_try_except(output): + output.append(1) + try: + 1 / 0 + except ZeroDivisionError as e: + output.append(5) + x = 42 # has to be a two-instruction block + @jump_test(2, 4, [1, 4, 5, -4]) def test_jump_across_with(output): output.append(1) @@ -1849,31 +2313,31 @@ class JumpTestCase(unittest.TestCase): output.append(2) output.append(3) - @async_jump_test(3, 2, [2, 2], (ValueError, 'within')) + @async_jump_test(3, 2, [2, 2], (ValueError, "can't jump into the body of a for loop")) async def test_no_jump_backwards_into_async_for_block(output): async for i in asynciter([1, 2]): output.append(2) output.append(3) - @jump_test(1, 3, [], (ValueError, 'depth')) + @jump_test(1, 3, [], (ValueError, 'stack')) def test_no_jump_forwards_into_with_block(output): output.append(1) with tracecontext(output, 2): output.append(3) - @async_jump_test(1, 3, [], (ValueError, 'depth')) + @async_jump_test(1, 3, [], (ValueError, 'stack')) async def test_no_jump_forwards_into_async_with_block(output): output.append(1) async with asynctracecontext(output, 2): output.append(3) - @jump_test(3, 2, [1, 2, -1], (ValueError, 'depth')) + @jump_test(3, 2, [1, 2, -1], (ValueError, 'stack')) def test_no_jump_backwards_into_with_block(output): with tracecontext(output, 1): output.append(2) output.append(3) - @async_jump_test(3, 2, [1, 2, -1], (ValueError, 'depth')) + @async_jump_test(3, 2, [1, 2, -1], (ValueError, 'stack')) async def test_no_jump_backwards_into_async_with_block(output): async with asynctracecontext(output, 1): output.append(2) @@ -1914,8 +2378,8 @@ class JumpTestCase(unittest.TestCase): output.append(6) # 'except' with a variable creates an implicit finally block - @jump_test(5, 7, [4], (ValueError, 'within')) - def test_no_jump_between_except_blocks_2(output): + @jump_test(5, 7, [4, 7, 8]) + def test_jump_between_except_blocks_2(output): try: 1/0 except ZeroDivisionError: @@ -1951,7 +2415,7 @@ class JumpTestCase(unittest.TestCase): finally: output.append(5) - @jump_test(1, 5, [], (ValueError, "into an exception")) + @jump_test(1, 5, [], (ValueError, "can't jump into an 'except' block as there's no exception")) def test_no_jump_into_bare_except_block(output): output.append(1) try: @@ -1959,7 +2423,7 @@ class JumpTestCase(unittest.TestCase): except: output.append(5) - @jump_test(1, 5, [], (ValueError, "into an exception")) + @jump_test(1, 5, [], (ValueError, "can't jump into an 'except' block as there's no exception")) def test_no_jump_into_qualified_except_block(output): output.append(1) try: @@ -1967,7 +2431,7 @@ class JumpTestCase(unittest.TestCase): except Exception: output.append(5) - @jump_test(3, 6, [2, 5, 6], (ValueError, "into an exception")) + @jump_test(3, 6, [2, 5, 6], (ValueError, "can't jump into an 'except' block as there's no exception")) def test_no_jump_into_bare_except_block_from_try_block(output): try: output.append(2) @@ -1978,7 +2442,7 @@ class JumpTestCase(unittest.TestCase): raise output.append(8) - @jump_test(3, 6, [2], (ValueError, "into an exception")) + @jump_test(3, 6, [2], (ValueError, "can't jump into an 'except' block as there's no exception")) def test_no_jump_into_qualified_except_block_from_try_block(output): try: output.append(2) @@ -1989,8 +2453,8 @@ class JumpTestCase(unittest.TestCase): raise output.append(8) - @jump_test(7, 1, [1, 3, 6], (ValueError, "within")) - def test_no_jump_out_of_bare_except_block(output): + @jump_test(7, 1, [1, 3, 6, 1, 3, 6, 7]) + def test_jump_out_of_bare_except_block(output): output.append(1) try: output.append(3) @@ -1999,8 +2463,8 @@ class JumpTestCase(unittest.TestCase): output.append(6) output.append(7) - @jump_test(7, 1, [1, 3, 6], (ValueError, "within")) - def test_no_jump_out_of_qualified_except_block(output): + @jump_test(7, 1, [1, 3, 6, 1, 3, 6, 7]) + def test_jump_out_of_qualified_except_block(output): output.append(1) try: output.append(3) @@ -2127,6 +2591,223 @@ output.append(4) next(gen()) output.append(5) + @jump_test(2, 3, [1, 3]) + def test_jump_forward_over_listcomp(output): + output.append(1) + x = [i for i in range(10)] + output.append(3) + + # checking for segfaults. + # See https://github.com/python/cpython/issues/92311 + @jump_test(3, 1, []) + def test_jump_backward_over_listcomp(output): + a = 1 + x = [i for i in range(10)] + c = 3 + + @jump_test(8, 2, [2, 7, 2]) + def test_jump_backward_over_listcomp_v2(output): + flag = False + output.append(2) + if flag: + return + x = [i for i in range(5)] + flag = 6 + output.append(7) + output.append(8) + + @async_jump_test(2, 3, [1, 3]) + async def test_jump_forward_over_async_listcomp(output): + output.append(1) + x = [i async for i in asynciter(range(10))] + output.append(3) + + @async_jump_test(3, 1, []) + async def test_jump_backward_over_async_listcomp(output): + a = 1 + x = [i async for i in asynciter(range(10))] + c = 3 + + @async_jump_test(8, 2, [2, 7, 2]) + async def test_jump_backward_over_async_listcomp_v2(output): + flag = False + output.append(2) + if flag: + return + x = [i async for i in asynciter(range(5))] + flag = 6 + output.append(7) + output.append(8) + + # checking for segfaults. + @jump_test(3, 7, [], error=(ValueError, "stack")) + def test_jump_with_null_on_stack_load_global(output): + a = 1 + print( + output.append(3) + ) + output.append(5) + ( + ( # 7 + a + + + 10 + ) + + + 13 + ) + output.append(15) + + # checking for segfaults. + @jump_test(4, 8, [], error=(ValueError, "stack")) + def test_jump_with_null_on_stack_push_null(output): + a = 1 + f = print + f( + output.append(4) + ) + output.append(6) + ( + ( # 8 + a + + + 11 + ) + + + 14 + ) + output.append(16) + + # checking for segfaults. + @jump_test(3, 7, [], error=(ValueError, "stack")) + def test_jump_with_null_on_stack_load_attr(output): + a = 1 + list.append( + output, 3 + ) + output.append(5) + ( + ( # 7 + a + + + 10 + ) + + + 13 + ) + output.append(15) + + @jump_test(2, 3, [1, 3]) + def test_jump_extended_args_unpack_ex_simple(output): + output.append(1) + _, *_, _ = output.append(2) or "Spam" + output.append(3) + + @jump_test(3, 4, [1, 4, 4, 5]) + def test_jump_extended_args_unpack_ex_tricky(output): + output.append(1) + ( + _, *_, _ + ) = output.append(4) or "Spam" + output.append(5) + + def test_jump_extended_args_for_iter(self): + # In addition to failing when extended arg handling is broken, this can + # also hang for a *very* long time: + source = [ + "def f(output):", + " output.append(1)", + " for _ in spam:", + *(f" output.append({i})" for i in range(3, 100_000)), + f" output.append(100_000)", + ] + namespace = {} + exec("\n".join(source), namespace) + f = namespace["f"] + self.run_test(f, 2, 100_000, [1, 100_000]) + + @jump_test(2, 3, [1, 3]) + def test_jump_or_pop(output): + output.append(1) + _ = output.append(2) and "Spam" + output.append(3) + + +class TestExtendedArgs(unittest.TestCase): + + def setUp(self): + self.addCleanup(sys.settrace, sys.gettrace()) + sys.settrace(None) + + def count_traces(self, func): + # warmup + for _ in range(20): + func() + + counts = {"call": 0, "line": 0, "return": 0} + def trace(frame, event, arg): + counts[event] += 1 + return trace + + sys.settrace(trace) + func() + sys.settrace(None) + + return counts + + def test_trace_unpack_long_sequence(self): + ns = {} + code = "def f():\n (" + "y,\n "*300 + ") = range(300)" + exec(code, ns) + counts = self.count_traces(ns["f"]) + self.assertEqual(counts, {'call': 1, 'line': 301, 'return': 1}) + + def test_trace_lots_of_globals(self): + code = """if 1: + def f(): + return ( + {} + ) + """.format("\n+\n".join(f"var{i}\n" for i in range(1000))) + ns = {f"var{i}": i for i in range(1000)} + exec(code, ns) + counts = self.count_traces(ns["f"]) + self.assertEqual(counts, {'call': 1, 'line': 2000, 'return': 1}) + + +class TestEdgeCases(unittest.TestCase): + + def setUp(self): + self.addCleanup(sys.settrace, sys.gettrace()) + sys.settrace(None) + + def test_reentrancy(self): + def foo(*args): + ... + + def bar(*args): + ... + + class A: + def __call__(self, *args): + pass + + def __del__(self): + sys.settrace(bar) + + sys.settrace(A()) + sys.settrace(foo) + self.assertEqual(sys.gettrace(), bar) + + + def test_same_object(self): + def foo(*args): + ... + + sys.settrace(foo) + del foo + sys.settrace(sys.gettrace()) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 9408657c918..b6dbf3d52cb 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -5,11 +5,12 @@ import subprocess import shutil from copy import copy -from test.support import (captured_stdout, PythonSymlink) +from test.support import ( + captured_stdout, PythonSymlink, requires_subprocess, is_wasi +) from test.support.import_helper import import_module from test.support.os_helper import (TESTFN, unlink, skip_unless_symlink, change_cwd) -from test.support.warnings_helper import check_warnings import sysconfig from sysconfig import (get_paths, get_platform, get_config_vars, @@ -102,6 +103,10 @@ class TestSysConfig(unittest.TestCase): def test_get_path(self): config_vars = get_config_vars() + if os.name == 'nt': + # On Windows, we replace the native platlibdir name with the + # default so that POSIX schemes resolve correctly + config_vars = config_vars | {'platlibdir': 'lib'} for scheme in _INSTALL_SCHEMES: for name in _INSTALL_SCHEMES[scheme]: expected = _INSTALL_SCHEMES[scheme][name].format(**config_vars) @@ -135,6 +140,72 @@ class TestSysConfig(unittest.TestCase): self.assertIsInstance(schemes, dict) self.assertEqual(set(schemes), expected_schemes) + def test_posix_venv_scheme(self): + # The following directories were hardcoded in the venv module + # before bpo-45413, here we assert the posix_venv scheme does not regress + binpath = 'bin' + incpath = 'include' + libpath = os.path.join('lib', + 'python%d.%d' % sys.version_info[:2], + 'site-packages') + + # Resolve the paths in prefix + binpath = os.path.join(sys.prefix, binpath) + incpath = os.path.join(sys.prefix, incpath) + libpath = os.path.join(sys.prefix, libpath) + + self.assertEqual(binpath, sysconfig.get_path('scripts', scheme='posix_venv')) + self.assertEqual(libpath, sysconfig.get_path('purelib', scheme='posix_venv')) + + # The include directory on POSIX isn't exactly the same as before, + # but it is "within" + sysconfig_includedir = sysconfig.get_path('include', scheme='posix_venv') + self.assertTrue(sysconfig_includedir.startswith(incpath + os.sep)) + + def test_nt_venv_scheme(self): + # The following directories were hardcoded in the venv module + # before bpo-45413, here we assert the posix_venv scheme does not regress + binpath = 'Scripts' + incpath = 'Include' + libpath = os.path.join('Lib', 'site-packages') + + # Resolve the paths in prefix + binpath = os.path.join(sys.prefix, binpath) + incpath = os.path.join(sys.prefix, incpath) + libpath = os.path.join(sys.prefix, libpath) + + self.assertEqual(binpath, sysconfig.get_path('scripts', scheme='nt_venv')) + self.assertEqual(incpath, sysconfig.get_path('include', scheme='nt_venv')) + self.assertEqual(libpath, sysconfig.get_path('purelib', scheme='nt_venv')) + + def test_venv_scheme(self): + if sys.platform == 'win32': + self.assertEqual( + sysconfig.get_path('scripts', scheme='venv'), + sysconfig.get_path('scripts', scheme='nt_venv') + ) + self.assertEqual( + sysconfig.get_path('include', scheme='venv'), + sysconfig.get_path('include', scheme='nt_venv') + ) + self.assertEqual( + sysconfig.get_path('purelib', scheme='venv'), + sysconfig.get_path('purelib', scheme='nt_venv') + ) + else: + self.assertEqual( + sysconfig.get_path('scripts', scheme='venv'), + sysconfig.get_path('scripts', scheme='posix_venv') + ) + self.assertEqual( + sysconfig.get_path('include', scheme='venv'), + sysconfig.get_path('include', scheme='posix_venv') + ) + self.assertEqual( + sysconfig.get_path('purelib', scheme='venv'), + sysconfig.get_path('purelib', scheme='posix_venv') + ) + def test_get_config_vars(self): cvars = get_config_vars() self.assertIsInstance(cvars, dict) @@ -258,17 +329,19 @@ class TestSysConfig(unittest.TestCase): # XXX more platforms to tests here + @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds") def test_get_config_h_filename(self): config_h = sysconfig.get_config_h_filename() self.assertTrue(os.path.isfile(config_h), config_h) def test_get_scheme_names(self): - wanted = ['nt', 'posix_home', 'posix_prefix'] + wanted = ['nt', 'posix_home', 'posix_prefix', 'posix_venv', 'nt_venv', 'venv'] if HAS_USER_BASE: wanted.extend(['nt_user', 'osx_framework_user', 'posix_user']) self.assertEqual(get_scheme_names(), tuple(sorted(wanted))) @skip_unless_symlink + @requires_subprocess() def test_symlink(self): # Issue 7880 with PythonSymlink() as py: cmd = "-c", "import sysconfig; print(sysconfig.get_platform())" @@ -296,7 +369,7 @@ class TestSysConfig(unittest.TestCase): base = base.replace(sys.base_prefix, sys.prefix) if HAS_USER_BASE: user_path = get_path(name, 'posix_user') - expected = global_path.replace(base, user, 1) + expected = os.path.normpath(global_path.replace(base, user, 1)) # bpo-44860: platlib of posix_user doesn't use sys.platlibdir, # whereas posix_prefix does. if name == 'platlib': @@ -322,6 +395,7 @@ class TestSysConfig(unittest.TestCase): self.assertIn(ldflags, ldshared) @unittest.skipUnless(sys.platform == "darwin", "test only relevant on MacOSX") + @requires_subprocess() def test_platform_in_subprocess(self): my_platform = sysconfig.get_platform() @@ -364,6 +438,7 @@ class TestSysConfig(unittest.TestCase): self.assertEqual(status, 0) self.assertEqual(my_platform, test_platform) + @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds") def test_srcdir(self): # See Issues #15322, #15364. srcdir = sysconfig.get_config_var('srcdir') @@ -376,7 +451,11 @@ class TestSysConfig(unittest.TestCase): # should be a full source checkout. Python_h = os.path.join(srcdir, 'Include', 'Python.h') self.assertTrue(os.path.exists(Python_h), Python_h) - self.assertTrue(sysconfig._is_python_source_dir(srcdir)) + # /PC/pyconfig.h always exists even if unused on POSIX. + pyconfig_h = os.path.join(srcdir, 'PC', 'pyconfig.h') + self.assertTrue(os.path.exists(pyconfig_h), pyconfig_h) + pyconfig_h_in = os.path.join(srcdir, 'pyconfig.h.in') + self.assertTrue(os.path.exists(pyconfig_h_in), pyconfig_h_in) elif os.name == 'posix': makefile_dir = os.path.dirname(sysconfig.get_makefile_filename()) # Issue #19340: srcdir has been realpath'ed already @@ -391,26 +470,13 @@ class TestSysConfig(unittest.TestCase): srcdir2 = sysconfig.get_config_var('srcdir') self.assertEqual(srcdir, srcdir2) - @unittest.skipIf(sysconfig.get_config_var('EXT_SUFFIX') is None, - 'EXT_SUFFIX required for this test') - def test_SO_deprecation(self): - self.assertWarns(DeprecationWarning, - sysconfig.get_config_var, 'SO') - - @unittest.skipIf(sysconfig.get_config_var('EXT_SUFFIX') is None, - 'EXT_SUFFIX required for this test') - def test_SO_value(self): - with check_warnings(('', DeprecationWarning)): - self.assertEqual(sysconfig.get_config_var('SO'), - sysconfig.get_config_var('EXT_SUFFIX')) - @unittest.skipIf(sysconfig.get_config_var('EXT_SUFFIX') is None, 'EXT_SUFFIX required for this test') def test_EXT_SUFFIX_in_vars(self): import _imp + if not _imp.extension_suffixes(): + self.skipTest("stub loader has no suffixes") vars = sysconfig.get_config_vars() - self.assertIsNotNone(vars['SO']) - self.assertEqual(vars['SO'], vars['EXT_SUFFIX']) self.assertEqual(vars['EXT_SUFFIX'], _imp.extension_suffixes()[0]) @unittest.skipUnless(sys.platform == 'linux' and @@ -425,11 +491,11 @@ class TestSysConfig(unittest.TestCase): self.assertTrue('linux' in suffix, suffix) if re.match('(i[3-6]86|x86_64)$', machine): if ctypes.sizeof(ctypes.c_char_p()) == 4: - self.assertTrue(suffix.endswith('i386-linux-gnu.so') or - suffix.endswith('x86_64-linux-gnux32.so'), - suffix) + expected_suffixes = 'i386-linux-gnu.so', 'x86_64-linux-gnux32.so', 'i386-linux-musl.so' else: # 8 byte pointer size - self.assertTrue(suffix.endswith('x86_64-linux-gnu.so'), suffix) + expected_suffixes = 'x86_64-linux-gnu.so', 'x86_64-linux-musl.so' + self.assertTrue(suffix.endswith(expected_suffixes), + f'unexpected suffix {suffix!r}') @unittest.skipUnless(sys.platform == 'darwin', 'OS X-specific test') def test_osx_ext_suffix(self): @@ -440,6 +506,7 @@ class MakefileTests(unittest.TestCase): @unittest.skipIf(sys.platform.startswith('win'), 'Test is not Windows compatible') + @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds") def test_get_makefile_filename(self): makefile = sysconfig.get_makefile_filename() self.assertTrue(os.path.isfile(makefile), makefile) diff --git a/Lib/test/test_syslog.py b/Lib/test/test_syslog.py index fe09bd39f8b..54db80fa9df 100644 --- a/Lib/test/test_syslog.py +++ b/Lib/test/test_syslog.py @@ -1,6 +1,11 @@ -from test.support import import_helper +from test.support import import_helper, threading_helper syslog = import_helper.import_module("syslog") #skip if not supported +from test import support +import sys +import threading +import time import unittest +from textwrap import dedent # XXX(nnorwitz): This test sucks. I don't know of a platform independent way # to verify that the messages were really logged. @@ -8,6 +13,9 @@ import unittest class Test(unittest.TestCase): + def tearDown(self): + syslog.closelog() + def test_openlog(self): syslog.openlog('python') # Issue #6697. @@ -18,22 +26,122 @@ class Test(unittest.TestCase): syslog.syslog('test message from python test_syslog') syslog.syslog(syslog.LOG_ERR, 'test error from python test_syslog') + def test_syslog_implicit_open(self): + syslog.closelog() # Make sure log is closed + syslog.syslog('test message from python test_syslog') + syslog.syslog(syslog.LOG_ERR, 'test error from python test_syslog') + def test_closelog(self): syslog.openlog('python') syslog.closelog() + syslog.closelog() # idempotent operation def test_setlogmask(self): - syslog.setlogmask(syslog.LOG_DEBUG) + mask = syslog.LOG_UPTO(syslog.LOG_WARNING) + oldmask = syslog.setlogmask(mask) + self.assertEqual(syslog.setlogmask(0), mask) + self.assertEqual(syslog.setlogmask(oldmask), mask) def test_log_mask(self): - syslog.LOG_MASK(syslog.LOG_INFO) - - def test_log_upto(self): - syslog.LOG_UPTO(syslog.LOG_INFO) + mask = syslog.LOG_UPTO(syslog.LOG_WARNING) + self.assertTrue(mask & syslog.LOG_MASK(syslog.LOG_WARNING)) + self.assertTrue(mask & syslog.LOG_MASK(syslog.LOG_ERR)) + self.assertFalse(mask & syslog.LOG_MASK(syslog.LOG_INFO)) def test_openlog_noargs(self): syslog.openlog() syslog.syslog('test message from python test_syslog') + @threading_helper.requires_working_threading() + def test_syslog_threaded(self): + start = threading.Event() + stop = False + def opener(): + start.wait(10) + i = 1 + while not stop: + syslog.openlog(f'python-test-{i}') # new string object + i += 1 + def logger(): + start.wait(10) + while not stop: + syslog.syslog('test message from python test_syslog') + + orig_si = sys.getswitchinterval() + support.setswitchinterval(1e-9) + try: + threads = [threading.Thread(target=opener)] + threads += [threading.Thread(target=logger) for k in range(10)] + with threading_helper.start_threads(threads): + start.set() + time.sleep(0.1) + stop = True + finally: + sys.setswitchinterval(orig_si) + + def test_subinterpreter_syslog(self): + # syslog.syslog() is not allowed in subinterpreters, but only if + # syslog.openlog() hasn't been called in the main interpreter yet. + with self.subTest('before openlog()'): + code = dedent(''' + import syslog + caught_error = False + try: + syslog.syslog('foo') + except RuntimeError: + caught_error = True + assert(caught_error) + ''') + res = support.run_in_subinterp(code) + self.assertEqual(res, 0) + + syslog.openlog() + try: + with self.subTest('after openlog()'): + code = dedent(''' + import syslog + syslog.syslog('foo') + ''') + res = support.run_in_subinterp(code) + self.assertEqual(res, 0) + finally: + syslog.closelog() + + def test_subinterpreter_openlog(self): + try: + code = dedent(''' + import syslog + caught_error = False + try: + syslog.openlog() + except RuntimeError: + caught_error = True + + assert(caught_error) + ''') + res = support.run_in_subinterp(code) + self.assertEqual(res, 0) + finally: + syslog.closelog() + + def test_subinterpreter_closelog(self): + syslog.openlog('python') + try: + code = dedent(''' + import syslog + caught_error = False + try: + syslog.closelog() + except RuntimeError: + caught_error = True + + assert(caught_error) + ''') + res = support.run_in_subinterp(code) + self.assertEqual(res, 0) + finally: + syslog.closelog() + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_tabnanny.py b/Lib/test/test_tabnanny.py index 4dfbd2985d5..e0a82e95c48 100644 --- a/Lib/test/test_tabnanny.py +++ b/Lib/test/test_tabnanny.py @@ -4,7 +4,6 @@ Glossary: * errored : Whitespace related problems present in file. """ from unittest import TestCase, mock -from unittest import mock import errno import os import tabnanny @@ -293,8 +292,8 @@ class TestCommandLine(TestCase): _, out, err = script_helper.assert_python_ok('-m', 'tabnanny', *args) # Note: The `splitlines()` will solve the problem of CRLF(\r) added # by OS Windows. - out = out.decode('ascii') - err = err.decode('ascii') + out = os.fsdecode(out) + err = os.fsdecode(err) if partial: for std, output in ((stdout, out), (stderr, err)): _output = output.splitlines() diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index e4b5c52bf1e..21393206920 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -220,6 +220,26 @@ class UstarReadTest(ReadTest, unittest.TestCase): def test_issue14160(self): self._test_fileobj_link("symtype2", "ustar/regtype") + def test_add_dir_getmember(self): + # bpo-21987 + self.add_dir_and_getmember('bar') + self.add_dir_and_getmember('a'*101) + + def add_dir_and_getmember(self, name): + with os_helper.temp_cwd(): + with tarfile.open(tmpname, 'w') as tar: + tar.format = tarfile.USTAR_FORMAT + try: + os.mkdir(name) + tar.add(name) + finally: + os.rmdir(name) + with tarfile.open(tmpname) as tar: + self.assertEqual( + tar.getmember(name), + tar.getmember(name + '/') + ) + class GzipUstarReadTest(GzipTest, UstarReadTest): pass @@ -356,6 +376,18 @@ class CommonReadTest(ReadTest): with open(self.tarname, "rb") as fobj: self.assertTrue(tarfile.is_tarfile(io.BytesIO(fobj.read()))) + def test_is_tarfile_keeps_position(self): + # Test for issue44289: tarfile.is_tarfile() modifies + # file object's current position + with open(self.tarname, "rb") as fobj: + tarfile.is_tarfile(fobj) + self.assertEqual(fobj.tell(), 0) + + with open(self.tarname, "rb") as fobj: + file_like = io.BytesIO(fobj.read()) + tarfile.is_tarfile(file_like) + self.assertEqual(file_like.tell(), 0) + def test_empty_tarfile(self): # Test for issue6123: Allow opening empty archives. # This test checks if tarfile.open() is able to open an empty tar @@ -599,6 +631,7 @@ class MiscReadTestBase(CommonReadTest): data = f.read() self.assertEqual(sha256sum(data), sha256_regtype) + @os_helper.skip_unless_working_chmod def test_extractall(self): # Test if extractall() correctly restores directory permissions # and times (see issue1735). @@ -629,6 +662,7 @@ class MiscReadTestBase(CommonReadTest): tar.close() os_helper.rmtree(DIR) + @os_helper.skip_unless_working_chmod def test_extract_directory(self): dirtype = "ustar/dirtype" DIR = os.path.join(TEMPDIR, "extractdir") @@ -700,6 +734,18 @@ class MiscReadTestBase(CommonReadTest): with self.assertRaises(tarfile.ReadError): tarfile.open(self.tarname) + def test_next_on_empty_tarfile(self): + fd = io.BytesIO() + tf = tarfile.open(fileobj=fd, mode="w") + tf.close() + + fd.seek(0) + with tarfile.open(fileobj=fd, mode="r|") as tf: + self.assertEqual(tf.next(), None) + + fd.seek(0) + with tarfile.open(fileobj=fd, mode="r") as tf: + self.assertEqual(tf.next(), None) class MiscReadTest(MiscReadTestBase, unittest.TestCase): test_fail_comp = None @@ -987,11 +1033,26 @@ class LongnameTest: "iso8859-1", "strict") self.assertEqual(tarinfo.type, self.longnametype) + def test_longname_directory(self): + # Test reading a longlink directory. Issue #47231. + longdir = ('a' * 101) + '/' + with os_helper.temp_cwd(): + with tarfile.open(tmpname, 'w') as tar: + tar.format = self.format + try: + os.mkdir(longdir) + tar.add(longdir) + finally: + os.rmdir(longdir.rstrip("/")) + with tarfile.open(tmpname) as tar: + self.assertIsNotNone(tar.getmember(longdir)) + self.assertIsNotNone(tar.getmember(longdir.removesuffix('/'))) class GNUReadTest(LongnameTest, ReadTest, unittest.TestCase): subdir = "gnu" longnametype = tarfile.GNUTYPE_LONGNAME + format = tarfile.GNU_FORMAT # Since 3.2 tarfile is supposed to accurately restore sparse members and # produce files with holes. This is what we actually want to test here. @@ -1051,6 +1112,7 @@ class PaxReadTest(LongnameTest, ReadTest, unittest.TestCase): subdir = "pax" longnametype = tarfile.XHDTYPE + format = tarfile.PAX_FORMAT def test_pax_global_headers(self): tar = tarfile.open(tarname, encoding="iso8859-1") @@ -1467,6 +1529,10 @@ class StreamWriteTest(WriteTestBase, unittest.TestCase): @unittest.skipUnless(sys.platform != "win32" and hasattr(os, "umask"), "Missing umask implementation") + @unittest.skipIf( + support.is_emscripten or support.is_wasi, + "Emscripten's/WASI's umask is a stub." + ) def test_file_mode(self): # Test for issue #8464: Create files with correct # permissions. @@ -1500,6 +1566,75 @@ class Bz2StreamWriteTest(Bz2Test, StreamWriteTest): class LzmaStreamWriteTest(LzmaTest, StreamWriteTest): decompressor = lzma.LZMADecompressor if lzma else None +class _CompressedWriteTest(TarTest): + # This is not actually a standalone test. + # It does not inherit WriteTest because it only makes sense with gz,bz2 + source = (b"And we move to Bristol where they have a special, " + + b"Very Silly candidate") + + def _compressed_tar(self, compresslevel): + fobj = io.BytesIO() + with tarfile.open(tmpname, self.mode, fobj, + compresslevel=compresslevel) as tarfl: + tarfl.addfile(tarfile.TarInfo("foo"), io.BytesIO(self.source)) + return fobj + + def _test_bz2_header(self, compresslevel): + fobj = self._compressed_tar(compresslevel) + self.assertEqual(fobj.getvalue()[0:10], + b"BZh%d1AY&SY" % compresslevel) + + def _test_gz_header(self, compresslevel): + fobj = self._compressed_tar(compresslevel) + self.assertEqual(fobj.getvalue()[:3], b"\x1f\x8b\x08") + +class Bz2CompressWriteTest(Bz2Test, _CompressedWriteTest, unittest.TestCase): + prefix = "w:" + def test_compression_levels(self): + self._test_bz2_header(1) + self._test_bz2_header(5) + self._test_bz2_header(9) + +class Bz2CompressStreamWriteTest(Bz2Test, _CompressedWriteTest, + unittest.TestCase): + prefix = "w|" + def test_compression_levels(self): + self._test_bz2_header(1) + self._test_bz2_header(5) + self._test_bz2_header(9) + +class GzCompressWriteTest(GzipTest, _CompressedWriteTest, unittest.TestCase): + prefix = "w:" + def test_compression_levels(self): + self._test_gz_header(1) + self._test_gz_header(5) + self._test_gz_header(9) + +class GzCompressStreamWriteTest(GzipTest, _CompressedWriteTest, + unittest.TestCase): + prefix = "w|" + def test_compression_levels(self): + self._test_gz_header(1) + self._test_gz_header(5) + self._test_gz_header(9) + +class CompressLevelRaises(unittest.TestCase): + def test_compresslevel_wrong_modes(self): + compresslevel = 5 + fobj = io.BytesIO() + with self.assertRaises(TypeError): + tarfile.open(tmpname, "w:", fobj, compresslevel=compresslevel) + + @support.requires_bz2() + def test_wrong_compresslevels(self): + # BZ2 checks that the compresslevel is in [1,9]. gz does not + fobj = io.BytesIO() + with self.assertRaises(ValueError): + tarfile.open(tmpname, "w:bz2", fobj, compresslevel=0) + with self.assertRaises(ValueError): + tarfile.open(tmpname, "w:bz2", fobj, compresslevel=10) + with self.assertRaises(ValueError): + tarfile.open(tmpname, "w|bz2", fobj, compresslevel=10) class GNUWriteTest(unittest.TestCase): # This testcase checks for correct creation of GNU Longname @@ -1880,6 +2015,61 @@ class PaxWriteTest(GNUWriteTest): finally: tar.close() + def test_create_pax_header(self): + # The ustar header should contain values that can be + # represented reasonably, even if a better (e.g. higher + # precision) version is set in the pax header. + # Issue #45863 + + # values that should be kept + t = tarfile.TarInfo() + t.name = "foo" + t.mtime = 1000.1 + t.size = 100 + t.uid = 123 + t.gid = 124 + info = t.get_info() + header = t.create_pax_header(info, encoding="iso8859-1") + self.assertEqual(info['name'], "foo") + # mtime should be rounded to nearest second + self.assertIsInstance(info['mtime'], int) + self.assertEqual(info['mtime'], 1000) + self.assertEqual(info['size'], 100) + self.assertEqual(info['uid'], 123) + self.assertEqual(info['gid'], 124) + self.assertEqual(header, + b'././@PaxHeader' + bytes(86) \ + + b'0000000\x000000000\x000000000\x0000000000020\x0000000000000\x00010205\x00 x' \ + + bytes(100) + b'ustar\x0000'+ bytes(247) \ + + b'16 mtime=1000.1\n' + bytes(496) + b'foo' + bytes(97) \ + + b'0000644\x000000173\x000000174\x0000000000144\x0000000001750\x00006516\x00 0' \ + + bytes(100) + b'ustar\x0000' + bytes(247)) + + # values that should be changed + t = tarfile.TarInfo() + t.name = "foo\u3374" # can't be represented in ascii + t.mtime = 10**10 # too big + t.size = 10**10 # too big + t.uid = 8**8 # too big + t.gid = 8**8+1 # too big + info = t.get_info() + header = t.create_pax_header(info, encoding="iso8859-1") + # name is kept as-is in info but should be added to pax header + self.assertEqual(info['name'], "foo\u3374") + self.assertEqual(info['mtime'], 0) + self.assertEqual(info['size'], 0) + self.assertEqual(info['uid'], 0) + self.assertEqual(info['gid'], 0) + self.assertEqual(header, + b'././@PaxHeader' + bytes(86) \ + + b'0000000\x000000000\x000000000\x0000000000130\x0000000000000\x00010207\x00 x' \ + + bytes(100) + b'ustar\x0000' + bytes(247) \ + + b'15 path=foo\xe3\x8d\xb4\n16 uid=16777216\n' \ + + b'16 gid=16777217\n20 size=10000000000\n' \ + + b'21 mtime=10000000000\n'+ bytes(424) + b'foo?' + bytes(96) \ + + b'0000644\x000000000\x000000000\x0000000000000\x0000000000000\x00006540\x00 0' \ + + bytes(100) + b'ustar\x0000' + bytes(247)) + class UnicodeTest: diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py index 581c31ccb72..cd79024ab2c 100644 --- a/Lib/test/test_tcl.py +++ b/Lib/test/test_tcl.py @@ -1,10 +1,7 @@ import unittest -import locale -import re import subprocess import sys import os -import warnings from test import support from test.support import import_helper from test.support import os_helper @@ -28,15 +25,7 @@ def get_tk_patchlevel(): global _tk_patchlevel if _tk_patchlevel is None: tcl = Tcl() - patchlevel = tcl.call('info', 'patchlevel') - m = re.fullmatch(r'(\d+)\.(\d+)([ab.])(\d+)', patchlevel) - major, minor, releaselevel, serial = m.groups() - major, minor, serial = int(major), int(minor), int(serial) - releaselevel = {'a': 'alpha', 'b': 'beta', '.': 'final'}[releaselevel] - if releaselevel == 'final': - _tk_patchlevel = major, minor, serial, releaselevel, 0 - else: - _tk_patchlevel = major, minor, 0, releaselevel, serial + _tk_patchlevel = tcl.info_patchlevel() return _tk_patchlevel @@ -143,27 +132,18 @@ class TclTest(unittest.TestCase): self.assertRaises(TclError,tcl.unsetvar,'a') def get_integers(self): - integers = (0, 1, -1, 2**31-1, -2**31, 2**31, -2**31-1, 2**63-1, -2**63) - # bignum was added in Tcl 8.5, but its support is able only since 8.5.8. - # Actually it is determined at compile time, so using get_tk_patchlevel() - # is not reliable. - # TODO: expose full static version. - if tcl_version >= (8, 5): - v = get_tk_patchlevel() - if v >= (8, 6, 0, 'final') or (8, 5, 8) <= v < (8, 6): - integers += (2**63, -2**63-1, 2**1000, -2**1000) - return integers + return (0, 1, -1, + 2**31-1, -2**31, 2**31, -2**31-1, + 2**63-1, -2**63, 2**63, -2**63-1, + 2**1000, -2**1000) def test_getint(self): tcl = self.interp.tk for i in self.get_integers(): self.assertEqual(tcl.getint(' %d ' % i), i) - if tcl_version >= (8, 5): - self.assertEqual(tcl.getint(' %#o ' % i), i) + self.assertEqual(tcl.getint(' %#o ' % i), i) self.assertEqual(tcl.getint((' %#o ' % i).replace('o', '')), i) self.assertEqual(tcl.getint(' %#x ' % i), i) - if tcl_version < (8, 5): # bignum was added in Tcl 8.5 - self.assertRaises(TclError, tcl.getint, str(2**1000)) self.assertEqual(tcl.getint(42), 42) self.assertRaises(TypeError, tcl.getint) self.assertRaises(TypeError, tcl.getint, '42', '10') @@ -317,8 +297,7 @@ class TclTest(unittest.TestCase): check('"a\xbd\u20ac"', 'a\xbd\u20ac') check(r'"a\xbd\u20ac"', 'a\xbd\u20ac') check(r'"a\0b"', 'a\x00b') - if tcl_version >= (8, 5): # bignum was added in Tcl 8.5 - check('2**64', str(2**64)) + check('2**64', str(2**64)) def test_exprdouble(self): tcl = self.interp @@ -349,8 +328,7 @@ class TclTest(unittest.TestCase): check('[string length "a\xbd\u20ac"]', 3.0) check(r'[string length "a\xbd\u20ac"]', 3.0) self.assertRaises(TclError, tcl.exprdouble, '"abc"') - if tcl_version >= (8, 5): # bignum was added in Tcl 8.5 - check('2**64', float(2**64)) + check('2**64', float(2**64)) def test_exprlong(self): tcl = self.interp @@ -381,8 +359,7 @@ class TclTest(unittest.TestCase): check('[string length "a\xbd\u20ac"]', 3) check(r'[string length "a\xbd\u20ac"]', 3) self.assertRaises(TclError, tcl.exprlong, '"abc"') - if tcl_version >= (8, 5): # bignum was added in Tcl 8.5 - self.assertRaises(TclError, tcl.exprlong, '2**64') + self.assertRaises(TclError, tcl.exprlong, '2**64') def test_exprboolean(self): tcl = self.interp @@ -422,10 +399,8 @@ class TclTest(unittest.TestCase): check('[string length "a\xbd\u20ac"]', True) check(r'[string length "a\xbd\u20ac"]', True) self.assertRaises(TclError, tcl.exprboolean, '"abc"') - if tcl_version >= (8, 5): # bignum was added in Tcl 8.5 - check('2**64', True) + check('2**64', True) - @unittest.skipUnless(tcl_version >= (8, 5), 'requires Tcl version >= 8.5') def test_booleans(self): tcl = self.interp def check(expr, expected): @@ -455,8 +430,6 @@ class TclTest(unittest.TestCase): else: self.assertEqual(result, str(i)) self.assertIsInstance(result, str) - if get_tk_patchlevel() < (8, 5): # bignum was added in Tcl 8.5 - self.assertRaises(TclError, tcl.call, 'expr', str(2**1000)) def test_passing_values(self): def passValue(value): @@ -485,8 +458,6 @@ class TclTest(unittest.TestCase): b'str\xbding' if self.wantobjects else 'str\xbding') for i in self.get_integers(): self.assertEqual(passValue(i), i if self.wantobjects else str(i)) - if tcl_version < (8, 5): # bignum was added in Tcl 8.5 - self.assertEqual(passValue(2**1000), str(2**1000)) for f in (0.0, 1.0, -1.0, 1/3, sys.float_info.min, sys.float_info.max, -sys.float_info.min, -sys.float_info.max): @@ -552,8 +523,6 @@ class TclTest(unittest.TestCase): check(b'str\xc0\x80ing\xe2\x82\xac', 'str\xc0\x80ing\xe2\x82\xac') for i in self.get_integers(): check(i, str(i)) - if tcl_version < (8, 5): # bignum was added in Tcl 8.5 - check(2**1000, str(2**1000)) for f in (0.0, 1.0, -1.0): check(f, repr(f)) for f in (1/3.0, sys.float_info.min, sys.float_info.max, @@ -600,16 +569,14 @@ class TclTest(unittest.TestCase): ('1', '2', '3.4')), ] tk_patchlevel = get_tk_patchlevel() - if tcl_version >= (8, 5): - if not self.wantobjects or tk_patchlevel < (8, 5, 5): - # Before 8.5.5 dicts were converted to lists through string - expected = ('12', '\u20ac', '\xe2\x82\xac', '3.4') - else: - expected = (12, '\u20ac', b'\xe2\x82\xac', (3.4,)) - testcases += [ - (call('dict', 'create', 12, '\u20ac', b'\xe2\x82\xac', (3.4,)), - expected), - ] + if not self.wantobjects: + expected = ('12', '\u20ac', '\xe2\x82\xac', '3.4') + else: + expected = (12, '\u20ac', b'\xe2\x82\xac', (3.4,)) + testcases += [ + (call('dict', 'create', 12, '\u20ac', b'\xe2\x82\xac', (3.4,)), + expected), + ] dbg_info = ('want objects? %s, Tcl version: %s, Tk patchlevel: %s' % (self.wantobjects, tcl_version, tk_patchlevel)) for arg, res in testcases: @@ -642,15 +609,13 @@ class TclTest(unittest.TestCase): {'a': (1, 2, 3) if self.wantobjects else '1 2 3', 'something': 'foo', 'status': ''}) - if tcl_version >= (8, 5): - arg = tcl.call('dict', 'create', - '-a', (1, 2, 3), '-something', 'foo', 'status', ()) - if not self.wantobjects or get_tk_patchlevel() < (8, 5, 5): - # Before 8.5.5 dicts were converted to lists through string - expected = {'a': '1 2 3', 'something': 'foo', 'status': ''} - else: - expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''} - self.assertEqual(splitdict(tcl, arg), expected) + arg = tcl.call('dict', 'create', + '-a', (1, 2, 3), '-something', 'foo', 'status', ()) + if not self.wantobjects: + expected = {'a': '1 2 3', 'something': 'foo', 'status': ''} + else: + expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''} + self.assertEqual(splitdict(tcl, arg), expected) def test_join(self): join = tkinter._join @@ -747,7 +712,7 @@ class BigmemTclTest(unittest.TestCase): def setUpModule(): if support.verbose: tcl = Tcl() - print('patchlevel =', tcl.call('info', 'patchlevel')) + print('patchlevel =', tcl.call('info', 'patchlevel'), flush=True) if __name__ == "__main__": diff --git a/Lib/test/test_telnetlib.py b/Lib/test/test_telnetlib.py index 41c4fcd4195..a9cade2ee46 100644 --- a/Lib/test/test_telnetlib.py +++ b/Lib/test/test_telnetlib.py @@ -1,13 +1,16 @@ import socket import selectors -import telnetlib import threading import contextlib from test import support -from test.support import socket_helper +from test.support import socket_helper, warnings_helper import unittest +support.requires_working_socket(module=True) + +telnetlib = warnings_helper.import_deprecated('telnetlib') + HOST = socket_helper.HOST def server(evt, serv): diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index 2b0ec46a103..7c2c8de7a2e 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -11,6 +11,7 @@ import contextlib import stat import types import weakref +import gc from unittest import mock import unittest @@ -90,14 +91,10 @@ class BaseTestCase(unittest.TestCase): b_check = re.compile(br"^[a-z0-9_-]{8}$") def setUp(self): - self._warnings_manager = warnings_helper.check_warnings() - self._warnings_manager.__enter__() + self.enterContext(warnings_helper.check_warnings()) warnings.filterwarnings("ignore", category=RuntimeWarning, message="mktemp", module=__name__) - def tearDown(self): - self._warnings_manager.__exit__(None, None, None) - def nameCheck(self, name, dir, pre, suf): (ndir, nbase) = os.path.split(name) npre = nbase[:len(pre)] @@ -198,8 +195,7 @@ class TestRandomNameSequence(BaseTestCase): if i == 20: break - @unittest.skipUnless(hasattr(os, 'fork'), - "os.fork is required for this test") + @support.requires_fork() def test_process_awareness(self): # ensure that the random source differs between # child and parent. @@ -290,19 +286,14 @@ class TestGetDefaultTempdir(BaseTestCase): def raise_OSError(*args, **kwargs): raise OSError() - with support.swap_attr(io, "open", raise_OSError): - # test again with failing io.open() + with support.swap_attr(os, "open", raise_OSError): + # test again with failing os.open() with self.assertRaises(FileNotFoundError): tempfile._get_default_tempdir() self.assertEqual(os.listdir(our_temp_directory), []) - def bad_writer(*args, **kwargs): - fp = orig_open(*args, **kwargs) - fp.write = raise_OSError - return fp - - with support.swap_attr(io, "open", bad_writer) as orig_open: - # test again with failing write() + with support.swap_attr(os, "write", raise_OSError): + # test again with failing os.write() with self.assertRaises(FileNotFoundError): tempfile._get_default_tempdir() self.assertEqual(os.listdir(our_temp_directory), []) @@ -342,6 +333,9 @@ def _mock_candidate_names(*names): class TestBadTempdir: + @unittest.skipIf( + support.is_emscripten, "Emscripten cannot remove write bits." + ) def test_read_only_directory(self): with _inside_empty_temp_dir(): oldmode = mode = os.stat(tempfile.tempdir).st_mode @@ -452,6 +446,7 @@ class TestMkstempInner(TestBadTempdir, BaseTestCase): support.gc_collect() # For PyPy or other GCs. os.rmdir(dir) + @os_helper.skip_unless_working_chmod def test_file_mode(self): # _mkstemp_inner creates files with the proper mode @@ -466,6 +461,7 @@ class TestMkstempInner(TestBadTempdir, BaseTestCase): self.assertEqual(mode, expected) @unittest.skipUnless(has_spawnl, 'os.spawnl not available') + @support.requires_subprocess() def test_noinherit(self): # _mkstemp_inner file handles are not inherited by child processes @@ -788,6 +784,7 @@ class TestMkdtemp(TestBadTempdir, BaseTestCase): finally: os.rmdir(dir) + @os_helper.skip_unless_working_chmod def test_mode(self): # mkdtemp creates directories with the proper mode @@ -977,6 +974,7 @@ class TestNamedTemporaryFile(BaseTestCase): try: with tempfile.NamedTemporaryFile(dir=dir) as f: f.write(b'blat') + self.assertEqual(os.listdir(dir), []) self.assertFalse(os.path.exists(f.name), "NamedTemporaryFile %s exists after close" % f.name) finally: @@ -1016,18 +1014,101 @@ class TestNamedTemporaryFile(BaseTestCase): pass self.assertRaises(ValueError, use_closed) - def test_no_leak_fd(self): - # Issue #21058: don't leak file descriptor when io.open() fails - closed = [] - os_close = os.close - def close(fd): - closed.append(fd) - os_close(fd) + def test_context_man_not_del_on_close_if_delete_on_close_false(self): + # Issue gh-58451: tempfile.NamedTemporaryFile is not particulary useful + # on Windows + # A NamedTemporaryFile is NOT deleted when closed if + # delete_on_close=False, but is deleted on context manager exit + dir = tempfile.mkdtemp() + try: + with tempfile.NamedTemporaryFile(dir=dir, + delete=True, + delete_on_close=False) as f: + f.write(b'blat') + f_name = f.name + f.close() + with self.subTest(): + # Testing that file is not deleted on close + self.assertTrue(os.path.exists(f.name), + f"NamedTemporaryFile {f.name!r} is incorrectly " + f"deleted on closure when delete_on_close=False") - with mock.patch('os.close', side_effect=close): - with mock.patch('io.open', side_effect=ValueError): - self.assertRaises(ValueError, tempfile.NamedTemporaryFile) - self.assertEqual(len(closed), 1) + with self.subTest(): + # Testing that file is deleted on context manager exit + self.assertFalse(os.path.exists(f.name), + f"NamedTemporaryFile {f.name!r} exists " + f"after context manager exit") + + finally: + os.rmdir(dir) + + def test_context_man_ok_to_delete_manually(self): + # In the case of delete=True, a NamedTemporaryFile can be manually + # deleted in a with-statement context without causing an error. + dir = tempfile.mkdtemp() + try: + with tempfile.NamedTemporaryFile(dir=dir, + delete=True, + delete_on_close=False) as f: + f.write(b'blat') + f.close() + os.unlink(f.name) + + finally: + os.rmdir(dir) + + def test_context_man_not_del_if_delete_false(self): + # A NamedTemporaryFile is not deleted if delete = False + dir = tempfile.mkdtemp() + f_name = "" + try: + # Test that delete_on_close=True has no effect if delete=False. + with tempfile.NamedTemporaryFile(dir=dir, delete=False, + delete_on_close=True) as f: + f.write(b'blat') + f_name = f.name + self.assertTrue(os.path.exists(f.name), + f"NamedTemporaryFile {f.name!r} exists after close") + finally: + os.unlink(f_name) + os.rmdir(dir) + + def test_del_by_finalizer(self): + # A NamedTemporaryFile is deleted when finalized in the case of + # delete=True, delete_on_close=False, and no with-statement is used. + def my_func(dir): + f = tempfile.NamedTemporaryFile(dir=dir, delete=True, + delete_on_close=False) + tmp_name = f.name + f.write(b'blat') + # Testing extreme case, where the file is not explicitly closed + # f.close() + return tmp_name + # Make sure that the garbage collector has finalized the file object. + gc.collect() + dir = tempfile.mkdtemp() + try: + tmp_name = my_func(dir) + self.assertFalse(os.path.exists(tmp_name), + f"NamedTemporaryFile {tmp_name!r} " + f"exists after finalizer ") + finally: + os.rmdir(dir) + + def test_correct_finalizer_work_if_already_deleted(self): + # There should be no error in the case of delete=True, + # delete_on_close=False, no with-statement is used, and the file is + # deleted manually. + def my_func(dir)->str: + f = tempfile.NamedTemporaryFile(dir=dir, delete=True, + delete_on_close=False) + tmp_name = f.name + f.write(b'blat') + f.close() + os.unlink(tmp_name) + return tmp_name + # Make sure that the garbage collector has finalized the file object. + gc.collect() def test_bad_mode(self): dir = tempfile.mkdtemp() @@ -1038,6 +1119,24 @@ class TestNamedTemporaryFile(BaseTestCase): tempfile.NamedTemporaryFile(mode=2, dir=dir) self.assertEqual(os.listdir(dir), []) + def test_bad_encoding(self): + dir = tempfile.mkdtemp() + self.addCleanup(os_helper.rmtree, dir) + with self.assertRaises(LookupError): + tempfile.NamedTemporaryFile('w', encoding='bad-encoding', dir=dir) + self.assertEqual(os.listdir(dir), []) + + def test_unexpected_error(self): + dir = tempfile.mkdtemp() + self.addCleanup(os_helper.rmtree, dir) + with mock.patch('tempfile._TemporaryFileWrapper') as mock_ntf, \ + mock.patch('io.open', mock.mock_open()) as mock_open: + mock_ntf.side_effect = KeyboardInterrupt() + with self.assertRaises(KeyboardInterrupt): + tempfile.NamedTemporaryFile(dir=dir) + mock_open().close.assert_called() + self.assertEqual(os.listdir(dir), []) + # How to test the mode and bufsize parameters? class TestSpooledTemporaryFile(BaseTestCase): @@ -1058,6 +1157,31 @@ class TestSpooledTemporaryFile(BaseTestCase): f = self.do_create(max_size=100, pre="a", suf=".txt") self.assertFalse(f._rolled) + def test_is_iobase(self): + # SpooledTemporaryFile should implement io.IOBase + self.assertIsInstance(self.do_create(), io.IOBase) + + def test_iobase_interface(self): + # SpooledTemporaryFile should implement the io.IOBase interface. + # Ensure it has all the required methods and properties. + iobase_attrs = { + # From IOBase + 'fileno', 'seek', 'truncate', 'close', 'closed', '__enter__', + '__exit__', 'flush', 'isatty', '__iter__', '__next__', 'readable', + 'readline', 'readlines', 'seekable', 'tell', 'writable', + 'writelines', + # From BufferedIOBase (binary mode) and TextIOBase (text mode) + 'detach', 'read', 'read1', 'write', 'readinto', 'readinto1', + 'encoding', 'errors', 'newlines', + } + spooledtempfile_attrs = set(dir(tempfile.SpooledTemporaryFile)) + missing_attrs = iobase_attrs - spooledtempfile_attrs + self.assertFalse( + missing_attrs, + 'SpooledTemporaryFile missing attributes from ' + 'IOBase/BufferedIOBase/TextIOBase' + ) + def test_del_on_close(self): # A SpooledTemporaryFile is deleted when closed dir = tempfile.mkdtemp() @@ -1068,11 +1192,40 @@ class TestSpooledTemporaryFile(BaseTestCase): self.assertTrue(f._rolled) filename = f.name f.close() - self.assertFalse(isinstance(filename, str) and os.path.exists(filename), - "SpooledTemporaryFile %s exists after close" % filename) + self.assertEqual(os.listdir(dir), []) + if not isinstance(filename, int): + self.assertFalse(os.path.exists(filename), + "SpooledTemporaryFile %s exists after close" % filename) finally: os.rmdir(dir) + def test_del_unrolled_file(self): + # The unrolled SpooledTemporaryFile should raise a ResourceWarning + # when deleted since the file was not explicitly closed. + f = self.do_create(max_size=10) + f.write(b'foo') + self.assertEqual(f.name, None) # Unrolled so no filename/fd + with self.assertWarns(ResourceWarning): + f.__del__() + + @unittest.skipIf( + support.is_emscripten, "Emscripten cannot fstat renamed files." + ) + def test_del_rolled_file(self): + # The rolled file should be deleted when the SpooledTemporaryFile + # object is deleted. This should raise a ResourceWarning since the file + # was not explicitly closed. + f = self.do_create(max_size=2) + f.write(b'foo') + name = f.name # This is a fd on posix+cygwin, a filename everywhere else + self.assertTrue(os.path.exists(name)) + with self.assertWarns(ResourceWarning): + f.__del__() + self.assertFalse( + os.path.exists(name), + "Rolled SpooledTemporaryFile (name=%s) exists after delete" % name + ) + def test_rewrite_small(self): # A SpooledTemporaryFile can be written to multiple within the max_size f = self.do_create(max_size=30) @@ -1283,6 +1436,9 @@ class TestSpooledTemporaryFile(BaseTestCase): pass self.assertRaises(ValueError, use_closed) + @unittest.skipIf( + support.is_emscripten, "Emscripten cannot fstat renamed files." + ) def test_truncate_with_size_parameter(self): # A SpooledTemporaryFile can be truncated to zero size f = tempfile.SpooledTemporaryFile(max_size=10) @@ -1356,19 +1512,34 @@ if tempfile.NamedTemporaryFile is not tempfile.TemporaryFile: roundtrip("\u039B", "w+", encoding="utf-16") roundtrip("foo\r\n", "w+", newline="") - def test_no_leak_fd(self): - # Issue #21058: don't leak file descriptor when io.open() fails - closed = [] - os_close = os.close - def close(fd): - closed.append(fd) - os_close(fd) + def test_bad_mode(self): + dir = tempfile.mkdtemp() + self.addCleanup(os_helper.rmtree, dir) + with self.assertRaises(ValueError): + tempfile.TemporaryFile(mode='wr', dir=dir) + with self.assertRaises(TypeError): + tempfile.TemporaryFile(mode=2, dir=dir) + self.assertEqual(os.listdir(dir), []) - with mock.patch('os.close', side_effect=close): - with mock.patch('io.open', side_effect=ValueError): - self.assertRaises(ValueError, tempfile.TemporaryFile) - self.assertEqual(len(closed), 1) + def test_bad_encoding(self): + dir = tempfile.mkdtemp() + self.addCleanup(os_helper.rmtree, dir) + with self.assertRaises(LookupError): + tempfile.TemporaryFile('w', encoding='bad-encoding', dir=dir) + self.assertEqual(os.listdir(dir), []) + def test_unexpected_error(self): + dir = tempfile.mkdtemp() + self.addCleanup(os_helper.rmtree, dir) + with mock.patch('tempfile._O_TMPFILE_WORKS', False), \ + mock.patch('os.unlink') as mock_unlink, \ + mock.patch('os.open') as mock_open, \ + mock.patch('os.close') as mock_close: + mock_unlink.side_effect = KeyboardInterrupt() + with self.assertRaises(KeyboardInterrupt): + tempfile.TemporaryFile(dir=dir) + mock_close.assert_called() + self.assertEqual(os.listdir(dir), []) # Helper for test_del_on_shutdown diff --git a/Lib/test/test_thread.py b/Lib/test/test_thread.py index 4ae8a833b99..8656fbdd83e 100644 --- a/Lib/test/test_thread.py +++ b/Lib/test/test_thread.py @@ -5,13 +5,15 @@ from test import support from test.support import threading_helper import _thread as thread import time +import warnings import weakref from test import lock_tests +threading_helper.requires_working_threading(module=True) + NUMTASKS = 10 NUMTRIPS = 3 -POLL_SLEEP = 0.010 # seconds = 10 ms _print_mutex = thread.allocate_lock() @@ -119,19 +121,24 @@ class ThreadRunningTests(BasicThreadTest): with threading_helper.wait_threads_exit(): thread.start_new_thread(task, ()) - while not started: - time.sleep(POLL_SLEEP) + for _ in support.sleeping_retry(support.LONG_TIMEOUT): + if started: + break self.assertEqual(thread._count(), orig + 1) + # Allow the task to finish. mut.release() + # The only reliable way to be sure that the thread ended from the - # interpreter's point of view is to wait for the function object to be - # destroyed. + # interpreter's point of view is to wait for the function object to + # be destroyed. done = [] wr = weakref.ref(task, lambda _: done.append(None)) del task - while not done: - time.sleep(POLL_SLEEP) + + for _ in support.sleeping_retry(support.LONG_TIMEOUT): + if done: + break support.gc_collect() # For PyPy or other GCs. self.assertEqual(thread._count(), orig) @@ -224,7 +231,7 @@ class TestForkInThread(unittest.TestCase): def setUp(self): self.read_fd, self.write_fd = os.pipe() - @unittest.skipUnless(hasattr(os, 'fork'), 'need os.fork') + @support.requires_fork() @threading_helper.reap_threads def test_forkinthread(self): pid = None @@ -232,11 +239,13 @@ class TestForkInThread(unittest.TestCase): def fork_thread(read_fd, write_fd): nonlocal pid - # fork in a thread - pid = os.fork() - if pid: - # parent process - return + # Ignore the warning about fork with threads. + with warnings.catch_warnings(category=DeprecationWarning, + action="ignore"): + # fork in a thread (DANGER, undefined per POSIX) + if (pid := os.fork()): + # parent process + return # child process try: diff --git a/Lib/test/test_threadedtempfile.py b/Lib/test/test_threadedtempfile.py index fe63c9e9143..420fc6ec8be 100644 --- a/Lib/test/test_threadedtempfile.py +++ b/Lib/test/test_threadedtempfile.py @@ -21,6 +21,7 @@ import io import threading from traceback import print_exc +threading_helper.requires_working_threading(module=True) NUM_THREADS = 20 FILES_PER_THREAD = 50 diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index a8f3c139b24..31bf46311a8 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -3,7 +3,7 @@ Tests for the threading module. """ import test.support -from test.support import threading_helper +from test.support import threading_helper, requires_subprocess from test.support import verbose, cpython_only, os_helper from test.support.import_helper import import_module from test.support.script_helper import assert_python_ok, assert_python_failure @@ -20,11 +20,13 @@ import subprocess import signal import textwrap import traceback +import warnings from unittest import mock from test import lock_tests from test import support +threading_helper.requires_working_threading(module=True) # Between fork() and exec(), only async-safe functions are allowed (issues # #12316 and #11870), and fork() from a worker thread is known to trigger @@ -32,9 +34,6 @@ from test import support # on platforms known to behave badly. platforms_to_skip = ('netbsd5', 'hp-ux11') -# Is Python built with Py_DEBUG macro defined? -Py_DEBUG = hasattr(sys, 'gettotalrefcount') - def restore_default_excepthook(testcase): testcase.addCleanup(setattr, threading, 'excepthook', threading.excepthook) @@ -123,6 +122,33 @@ class ThreadTests(BaseTestCase): thread = threading.Thread(target=func) self.assertEqual(thread.name, "Thread-5 (func)") + def test_args_argument(self): + # bpo-45735: Using list or tuple as *args* in constructor could + # achieve the same effect. + num_list = [1] + num_tuple = (1,) + + str_list = ["str"] + str_tuple = ("str",) + + list_in_tuple = ([1],) + tuple_in_list = [(1,)] + + test_cases = ( + (num_list, lambda arg: self.assertEqual(arg, 1)), + (num_tuple, lambda arg: self.assertEqual(arg, 1)), + (str_list, lambda arg: self.assertEqual(arg, "str")), + (str_tuple, lambda arg: self.assertEqual(arg, "str")), + (list_in_tuple, lambda arg: self.assertEqual(arg, [1])), + (tuple_in_list, lambda arg: self.assertEqual(arg, (1,))) + ) + + for args, target in test_cases: + with self.subTest(target=target, args=args): + t = threading.Thread(target=target, args=args) + t.start() + t.join() + @cpython_only def test_disallow_instantiation(self): # Ensure that the type disallows instantiation (bpo-43916) @@ -505,7 +531,7 @@ class ThreadTests(BaseTestCase): t = threading.Thread(daemon=True) self.assertTrue(t.daemon) - @unittest.skipUnless(hasattr(os, 'fork'), 'needs os.fork()') + @support.requires_fork() def test_fork_at_exit(self): # bpo-42350: Calling os.fork() after threading._shutdown() must # not log an error. @@ -533,12 +559,12 @@ class ThreadTests(BaseTestCase): self.assertEqual(out, b'') self.assertEqual(err.rstrip(), b'child process ok') - @unittest.skipUnless(hasattr(os, 'fork'), 'test needs fork()') + @support.requires_fork() def test_dummy_thread_after_fork(self): # Issue #14308: a dummy thread in the active list doesn't mess up # the after-fork mechanism. code = """if 1: - import _thread, threading, os, time + import _thread, threading, os, time, warnings def background_thread(evt): # Creates and registers the _DummyThread instance @@ -550,17 +576,22 @@ class ThreadTests(BaseTestCase): _thread.start_new_thread(background_thread, (evt,)) evt.wait() assert threading.active_count() == 2, threading.active_count() - if os.fork() == 0: - assert threading.active_count() == 1, threading.active_count() - os._exit(0) - else: - os.wait() + with warnings.catch_warnings(record=True) as ws: + warnings.filterwarnings( + "always", category=DeprecationWarning) + if os.fork() == 0: + assert threading.active_count() == 1, threading.active_count() + os._exit(0) + else: + assert ws[0].category == DeprecationWarning, ws[0] + assert 'fork' in str(ws[0].message), ws[0] + os.wait() """ _, out, err = assert_python_ok("-c", code) self.assertEqual(out, b'') self.assertEqual(err, b'') - @unittest.skipUnless(hasattr(os, 'fork'), "needs os.fork()") + @support.requires_fork() def test_is_alive_after_fork(self): # Try hard to trigger #18418: is_alive() could sometimes be True on # threads that vanished after a fork. @@ -573,13 +604,15 @@ class ThreadTests(BaseTestCase): for i in range(20): t = threading.Thread(target=lambda: None) t.start() - pid = os.fork() - if pid == 0: - os._exit(11 if t.is_alive() else 10) - else: - t.join() + # Ignore the warning about fork with threads. + with warnings.catch_warnings(category=DeprecationWarning, + action="ignore"): + if (pid := os.fork()) == 0: + os._exit(11 if t.is_alive() else 10) + else: + t.join() - support.wait_process(pid, exitcode=10) + support.wait_process(pid, exitcode=10) def test_main_thread(self): main = threading.main_thread() @@ -594,7 +627,7 @@ class ThreadTests(BaseTestCase): th.start() th.join() - @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()") + @support.requires_fork() @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()") def test_main_thread_after_fork(self): code = """if 1: @@ -616,25 +649,30 @@ class ThreadTests(BaseTestCase): self.assertEqual(data, "MainThread\nTrue\nTrue\n") @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") - @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()") + @support.requires_fork() @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()") def test_main_thread_after_fork_from_nonmain_thread(self): code = """if 1: - import os, threading, sys + import os, threading, sys, warnings from test import support def func(): - pid = os.fork() - if pid == 0: - main = threading.main_thread() - print(main.name) - print(main.ident == threading.current_thread().ident) - print(main.ident == threading.get_ident()) - # stdout is fully buffered because not a tty, - # we have to flush before exit. - sys.stdout.flush() - else: - support.wait_process(pid, exitcode=0) + with warnings.catch_warnings(record=True) as ws: + warnings.filterwarnings( + "always", category=DeprecationWarning) + pid = os.fork() + if pid == 0: + main = threading.main_thread() + print(main.name) + print(main.ident == threading.current_thread().ident) + print(main.ident == threading.get_ident()) + # stdout is fully buffered because not a tty, + # we have to flush before exit. + sys.stdout.flush() + else: + assert ws[0].category == DeprecationWarning, ws[0] + assert 'fork' in str(ws[0].message), ws[0] + support.wait_process(pid, exitcode=0) th = threading.Thread(target=func) th.start() @@ -642,7 +680,7 @@ class ThreadTests(BaseTestCase): """ _, out, err = assert_python_ok("-c", code) data = out.decode().replace('\r', '') - self.assertEqual(err, b"") + self.assertEqual(err.decode('utf-8'), "") self.assertEqual(data, "Thread-1 (func)\nTrue\nTrue\n") def test_main_thread_during_shutdown(self): @@ -828,6 +866,7 @@ class ThreadTests(BaseTestCase): callback() finally: sys.settrace(old_trace) + threading.settrace(old_trace) def test_gettrace(self): def noop_trace(frame, event, arg): @@ -841,6 +880,35 @@ class ThreadTests(BaseTestCase): finally: threading.settrace(old_trace) + def test_gettrace_all_threads(self): + def fn(*args): pass + old_trace = threading.gettrace() + first_check = threading.Event() + second_check = threading.Event() + + trace_funcs = [] + def checker(): + trace_funcs.append(sys.gettrace()) + first_check.set() + second_check.wait() + trace_funcs.append(sys.gettrace()) + + try: + t = threading.Thread(target=checker) + t.start() + first_check.wait() + threading.settrace_all_threads(fn) + second_check.set() + t.join() + self.assertEqual(trace_funcs, [None, fn]) + self.assertEqual(threading.gettrace(), fn) + self.assertEqual(sys.gettrace(), fn) + finally: + threading.settrace_all_threads(old_trace) + + self.assertEqual(threading.gettrace(), old_trace) + self.assertEqual(sys.gettrace(), old_trace) + def test_getprofile(self): def fn(*args): pass old_profile = threading.getprofile() @@ -850,6 +918,35 @@ class ThreadTests(BaseTestCase): finally: threading.setprofile(old_profile) + def test_getprofile_all_threads(self): + def fn(*args): pass + old_profile = threading.getprofile() + first_check = threading.Event() + second_check = threading.Event() + + profile_funcs = [] + def checker(): + profile_funcs.append(sys.getprofile()) + first_check.set() + second_check.wait() + profile_funcs.append(sys.getprofile()) + + try: + t = threading.Thread(target=checker) + t.start() + first_check.wait() + threading.setprofile_all_threads(fn) + second_check.set() + t.join() + self.assertEqual(profile_funcs, [None, fn]) + self.assertEqual(threading.getprofile(), fn) + self.assertEqual(sys.getprofile(), fn) + finally: + threading.setprofile_all_threads(old_profile) + + self.assertEqual(threading.getprofile(), old_profile) + self.assertEqual(sys.getprofile(), old_profile) + @cpython_only def test_shutdown_locks(self): for daemon in (False, True): @@ -918,16 +1015,6 @@ class ThreadTests(BaseTestCase): threading.Thread(target=noop).start() # Thread.join() is not called - @unittest.skipUnless(Py_DEBUG, 'need debug build (Py_DEBUG)') - def test_debug_deprecation(self): - # bpo-44584: The PYTHONTHREADDEBUG environment variable is deprecated - rc, out, err = assert_python_ok("-Wdefault", "-c", "pass", - PYTHONTHREADDEBUG="1") - msg = (b'DeprecationWarning: The threading debug ' - b'(PYTHONTHREADDEBUG environment variable) ' - b'is deprecated and will be removed in Python 3.12') - self.assertIn(msg, err) - def test_import_from_another_thread(self): # bpo-1596321: If the threading module is first import from a thread # different than the main thread, threading._shutdown() must handle @@ -993,7 +1080,7 @@ class ThreadJoinOnShutdown(BaseTestCase): """ self._run_and_join(script) - @unittest.skipUnless(hasattr(os, 'fork'), "needs os.fork()") + @support.requires_fork() @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") def test_2_join_in_forked_process(self): # Like the test above, but from a forked interpreter @@ -1014,7 +1101,7 @@ class ThreadJoinOnShutdown(BaseTestCase): """ self._run_and_join(script) - @unittest.skipUnless(hasattr(os, 'fork'), "needs os.fork()") + @support.requires_fork() @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") def test_3_join_in_forked_from_thread(self): # Like the test above, but fork() was called from a worker thread @@ -1085,7 +1172,7 @@ class ThreadJoinOnShutdown(BaseTestCase): rc, out, err = assert_python_ok('-c', script) self.assertFalse(err) - @unittest.skipUnless(hasattr(os, 'fork'), "needs os.fork()") + @support.requires_fork() @unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug") def test_reinit_tls_after_fork(self): # Issue #13817: fork() would deadlock in a multithreaded program with @@ -1099,17 +1186,20 @@ class ThreadJoinOnShutdown(BaseTestCase): else: os._exit(50) - # start a bunch of threads that will fork() child processes - threads = [] - for i in range(16): - t = threading.Thread(target=do_fork_and_wait) - threads.append(t) - t.start() + # Ignore the warning about fork with threads. + with warnings.catch_warnings(category=DeprecationWarning, + action="ignore"): + # start a bunch of threads that will fork() child processes + threads = [] + for i in range(16): + t = threading.Thread(target=do_fork_and_wait) + threads.append(t) + t.start() - for t in threads: - t.join() + for t in threads: + t.join() - @unittest.skipUnless(hasattr(os, 'fork'), "needs os.fork()") + @support.requires_fork() def test_clear_threads_states_after_fork(self): # Issue #17094: check that threads states are cleared after fork() @@ -1120,18 +1210,22 @@ class ThreadJoinOnShutdown(BaseTestCase): threads.append(t) t.start() - pid = os.fork() - if pid == 0: - # check that threads states have been cleared - if len(sys._current_frames()) == 1: - os._exit(51) - else: - os._exit(52) - else: - support.wait_process(pid, exitcode=51) - - for t in threads: - t.join() + try: + # Ignore the warning about fork with threads. + with warnings.catch_warnings(category=DeprecationWarning, + action="ignore"): + pid = os.fork() + if pid == 0: + # check that threads states have been cleared + if len(sys._current_frames()) == 1: + os._exit(51) + else: + os._exit(52) + else: + support.wait_process(pid, exitcode=51) + finally: + for t in threads: + t.join() class SubinterpThreadingTests(BaseTestCase): @@ -1231,6 +1325,62 @@ class SubinterpThreadingTests(BaseTestCase): self.assertIn("Fatal Python error: Py_EndInterpreter: " "not the last thread", err.decode()) + def _check_allowed(self, before_start='', *, + allowed=True, + daemon_allowed=True, + daemon=False, + ): + subinterp_code = textwrap.dedent(f""" + import test.support + import threading + def func(): + print('this should not have run!') + t = threading.Thread(target=func, daemon={daemon}) + {before_start} + t.start() + """) + script = textwrap.dedent(f""" + import test.support + test.support.run_in_subinterp_with_config( + {subinterp_code!r}, + allow_fork=True, + allow_exec=True, + allow_threads={allowed}, + allow_daemon_threads={daemon_allowed}, + ) + """) + with test.support.SuppressCrashReport(): + _, _, err = assert_python_ok("-c", script) + return err.decode() + + @cpython_only + def test_threads_not_allowed(self): + err = self._check_allowed( + allowed=False, + daemon_allowed=False, + daemon=False, + ) + self.assertIn('RuntimeError', err) + + @cpython_only + def test_daemon_threads_not_allowed(self): + with self.subTest('via Thread()'): + err = self._check_allowed( + allowed=True, + daemon_allowed=False, + daemon=True, + ) + self.assertIn('RuntimeError', err) + + with self.subTest('via Thread.daemon setter'): + err = self._check_allowed( + 't.daemon = True', + allowed=True, + daemon_allowed=False, + daemon=False, + ) + self.assertIn('RuntimeError', err) + class ThreadingExceptionTests(BaseTestCase): # A RuntimeError should be raised if Thread.start() is called @@ -1259,6 +1409,7 @@ class ThreadingExceptionTests(BaseTestCase): lock = threading.Lock() self.assertRaises(RuntimeError, lock.release) + @requires_subprocess() def test_recursion_limit(self): # Issue 9670 # test that excessive recursion within a non-main thread causes diff --git a/Lib/test/test_threading_local.py b/Lib/test/test_threading_local.py index 1567c41000b..f0b829a978f 100644 --- a/Lib/test/test_threading_local.py +++ b/Lib/test/test_threading_local.py @@ -3,8 +3,8 @@ import unittest from doctest import DocTestSuite from test import support from test.support import threading_helper +from test.support.import_helper import import_module import weakref -import gc # Modules under test import _thread @@ -12,6 +12,9 @@ import threading import _threading_local +threading_helper.requires_working_threading(module=True) + + class Weak(object): pass @@ -194,6 +197,18 @@ class BaseLocalTest: self.assertIsNone(wr()) + def test_threading_local_clear_race(self): + # See https://github.com/python/cpython/issues/100892 + + _testcapi = import_module('_testcapi') + _testcapi.call_in_temporary_c_thread(lambda: None, False) + + for _ in range(1000): + _ = threading.local() + + _testcapi.join_temporary_c_thread() + + class ThreadLocalTest(unittest.TestCase, BaseLocalTest): _local = _thread._local diff --git a/Lib/test/test_threadsignals.py b/Lib/test/test_threadsignals.py index bac82b8a445..6a53d655015 100644 --- a/Lib/test/test_threadsignals.py +++ b/Lib/test/test_threadsignals.py @@ -36,6 +36,9 @@ def send_signals(): os.kill(process_pid, signal.SIGUSR2) signalled_all.release() + +@threading_helper.requires_working_threading() +@unittest.skipUnless(hasattr(signal, "alarm"), "test requires signal.alarm") class ThreadSignals(unittest.TestCase): def test_signals(self): diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index f98aec2651d..02cc3f43a66 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -117,12 +117,13 @@ class TimeTestCase(unittest.TestCase): clk_id = time.pthread_getcpuclockid(threading.get_ident()) self.assertTrue(type(clk_id) is int) # when in 32-bit mode AIX only returns the predefined constant - if not platform.system() == "AIX": - self.assertNotEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID) - elif (sys.maxsize.bit_length() > 32): - self.assertNotEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID) - else: + if platform.system() == "AIX" and (sys.maxsize.bit_length() <= 32): self.assertEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID) + # Solaris returns CLOCK_THREAD_CPUTIME_ID when current thread is given + elif sys.platform.startswith("sunos"): + self.assertEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID) + else: + self.assertNotEqual(clk_id, time.CLOCK_THREAD_CPUTIME_ID) t1 = time.clock_gettime(clk_id) t2 = time.clock_gettime(clk_id) self.assertLessEqual(t1, t2) @@ -158,6 +159,13 @@ class TimeTestCase(unittest.TestCase): self.assertRaises(ValueError, time.sleep, -1) time.sleep(1.2) + def test_epoch(self): + # bpo-43869: Make sure that Python use the same Epoch on all platforms: + # January 1, 1970, 00:00:00 (UTC). + epoch = time.gmtime(0) + # Only test the date and time, ignore other gmtime() members + self.assertEqual(tuple(epoch)[:6], (1970, 1, 1, 0, 0, 0), epoch) + def test_strftime(self): tt = time.gmtime(self.t) for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I', @@ -305,6 +313,9 @@ class TimeTestCase(unittest.TestCase): def test_asctime_bounding_check(self): self._bounds_checking(time.asctime) + @unittest.skipIf( + support.is_emscripten, "musl libc issue on Emscripten, bpo-46390" + ) def test_ctime(self): t = time.mktime((1973, 9, 16, 1, 3, 52, 0, 0, -1)) self.assertEqual(time.ctime(t), 'Sun Sep 16 01:03:52 1973') @@ -478,6 +489,9 @@ class TimeTestCase(unittest.TestCase): def test_perf_counter(self): time.perf_counter() + @unittest.skipIf( + support.is_wasi, "process_time not available on WASI" + ) def test_process_time(self): # process_time() should not include time spend during a sleep start = time.process_time() @@ -548,20 +562,27 @@ class TimeTestCase(unittest.TestCase): self.assertRaises(ValueError, time.ctime, float("nan")) def test_get_clock_info(self): - clocks = ['monotonic', 'perf_counter', 'process_time', 'time'] + clocks = [ + 'monotonic', + 'perf_counter', + 'process_time', + 'time', + ] + if hasattr(time, 'thread_time'): + clocks.append('thread_time') for name in clocks: - info = time.get_clock_info(name) + with self.subTest(name=name): + info = time.get_clock_info(name) - #self.assertIsInstance(info, dict) - self.assertIsInstance(info.implementation, str) - self.assertNotEqual(info.implementation, '') - self.assertIsInstance(info.monotonic, bool) - self.assertIsInstance(info.resolution, float) - # 0.0 < resolution <= 1.0 - self.assertGreater(info.resolution, 0.0) - self.assertLessEqual(info.resolution, 1.0) - self.assertIsInstance(info.adjustable, bool) + self.assertIsInstance(info.implementation, str) + self.assertNotEqual(info.implementation, '') + self.assertIsInstance(info.monotonic, bool) + self.assertIsInstance(info.resolution, float) + # 0.0 < resolution <= 1.0 + self.assertGreater(info.resolution, 0.0) + self.assertLessEqual(info.resolution, 1.0) + self.assertIsInstance(info.adjustable, bool) self.assertRaises(ValueError, time.get_clock_info, 'xxx') @@ -608,6 +629,9 @@ class _TestStrftimeYear: def yearstr(self, y): return time.strftime('%Y', (y,) + (0,) * 8) + @unittest.skipUnless( + support.has_strftime_extensions, "requires strftime extension" + ) def test_4dyear(self): # Check that we can return the zero padded value. if self._format == '%04d': @@ -681,6 +705,9 @@ class TestStrftime4dyear(_TestStrftimeYear, _Test4dYear, unittest.TestCase): class TestPytime(unittest.TestCase): @skip_if_buggy_ucrt_strfptime @unittest.skipUnless(time._STRUCT_TM_ITEMS == 11, "needs tm_zone support") + @unittest.skipIf( + support.is_emscripten, "musl libc issue on Emscripten, bpo-46390" + ) def test_localtime_timezone(self): # Get the localtime and examine it for the offset and zone. @@ -821,7 +848,7 @@ class CPyTimeTestCase: # test rounding ns_timestamps = self._rounding_values(use_float) valid_values = convert_values(ns_timestamps) - for time_rnd, decimal_rnd in ROUNDING_MODES : + for time_rnd, decimal_rnd in ROUNDING_MODES: with decimal.localcontext() as context: context.rounding = decimal_rnd diff --git a/Lib/test/test_timeout.py b/Lib/test/test_timeout.py index 70a0175d771..30e843a423a 100644 --- a/Lib/test/test_timeout.py +++ b/Lib/test/test_timeout.py @@ -5,9 +5,6 @@ import unittest from test import support from test.support import socket_helper -# This requires the 'network' resource as given on the regrtest command line. -skip_expected = not support.is_resource_enabled('network') - import time import errno import socket @@ -53,10 +50,10 @@ class CreationTestCase(unittest.TestCase): def testReturnType(self): # Test return type of gettimeout() self.sock.settimeout(1) - self.assertEqual(type(self.sock.gettimeout()), type(1.0)) + self.assertIs(type(self.sock.gettimeout()), float) self.sock.settimeout(3.9) - self.assertEqual(type(self.sock.gettimeout()), type(1.0)) + self.assertIs(type(self.sock.gettimeout()), float) def testTypeCheck(self): # Test type checking by settimeout() @@ -292,6 +289,7 @@ class UDPTimeoutTestCase(TimeoutTestCase): def setUpModule(): support.requires('network') + support.requires_working_socket(module=True) if __name__ == "__main__": diff --git a/Lib/test/test_tix.py b/Lib/test/test_tix.py index 8a60c7c8e1f..454baeb38a9 100644 --- a/Lib/test/test_tix.py +++ b/Lib/test/test_tix.py @@ -2,6 +2,11 @@ import sys import unittest from test import support from test.support import import_helper +from test.support import check_sanitizer + +if check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("Tests involvin libX11 can SEGFAULT on ASAN/MSAN builds") + # Skip this test if the _tkinter module wasn't built. _tkinter = import_helper.import_module('_tkinter') diff --git a/Lib/test/test_tk.py b/Lib/test/test_tk.py deleted file mode 100644 index 69cc2322cd9..00000000000 --- a/Lib/test/test_tk.py +++ /dev/null @@ -1,14 +0,0 @@ -from test import support -from test.support import import_helper -# Skip test if _tkinter wasn't built. -import_helper.import_module('_tkinter') - -# Skip test if tk cannot be initialized. -support.requires('gui') - -def load_tests(loader, tests, pattern): - return loader.discover('tkinter.test.test_tkinter') - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/tkinter/test/README b/Lib/test/test_tkinter/README similarity index 100% rename from Lib/tkinter/test/README rename to Lib/test/test_tkinter/README diff --git a/Lib/test/test_tkinter/__init__.py b/Lib/test/test_tkinter/__init__.py new file mode 100644 index 00000000000..edcb44951bd --- /dev/null +++ b/Lib/test/test_tkinter/__init__.py @@ -0,0 +1,18 @@ +import os.path +import unittest +from test import support +from test.support import import_helper + + +if support.check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("Tests involving libX11 can SEGFAULT on ASAN/MSAN builds") + +# Skip test if _tkinter wasn't built. +import_helper.import_module('_tkinter') + +# Skip test if tk cannot be initialized. +support.requires('gui') + + +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_tkinter/__main__.py b/Lib/test/test_tkinter/__main__.py new file mode 100644 index 00000000000..40a23a297ec --- /dev/null +++ b/Lib/test/test_tkinter/__main__.py @@ -0,0 +1,4 @@ +from . import load_tests +import unittest + +unittest.main() diff --git a/Lib/tkinter/test/support.py b/Lib/test/test_tkinter/support.py similarity index 88% rename from Lib/tkinter/test/support.py rename to Lib/test/test_tkinter/support.py index dbc47a81e65..9154ebac5c4 100644 --- a/Lib/tkinter/test/support.py +++ b/Lib/test/test_tkinter/support.py @@ -1,5 +1,4 @@ import functools -import re import tkinter import unittest @@ -101,15 +100,7 @@ def get_tk_patchlevel(): global _tk_patchlevel if _tk_patchlevel is None: tcl = tkinter.Tcl() - patchlevel = tcl.call('info', 'patchlevel') - m = re.fullmatch(r'(\d+)\.(\d+)([ab.])(\d+)', patchlevel) - major, minor, releaselevel, serial = m.groups() - major, minor, serial = int(major), int(minor), int(serial) - releaselevel = {'a': 'alpha', 'b': 'beta', '.': 'final'}[releaselevel] - if releaselevel == 'final': - _tk_patchlevel = major, minor, serial, releaselevel, 0 - else: - _tk_patchlevel = major, minor, 0, releaselevel, serial + _tk_patchlevel = tcl.info_patchlevel() return _tk_patchlevel units = { diff --git a/Lib/tkinter/test/test_tkinter/test_colorchooser.py b/Lib/test/test_tkinter/test_colorchooser.py similarity index 96% rename from Lib/tkinter/test/test_tkinter/test_colorchooser.py rename to Lib/test/test_tkinter/test_colorchooser.py index 488162ff0dd..9bba21392d8 100644 --- a/Lib/tkinter/test/test_tkinter/test_colorchooser.py +++ b/Lib/test/test_tkinter/test_colorchooser.py @@ -1,7 +1,7 @@ import unittest import tkinter from test.support import requires, swap_attr -from tkinter.test.support import AbstractDefaultRootTest, AbstractTkTest +from test.test_tkinter.support import AbstractDefaultRootTest, AbstractTkTest from tkinter import colorchooser from tkinter.colorchooser import askcolor from tkinter.commondialog import Dialog diff --git a/Lib/tkinter/test/test_tkinter/test_font.py b/Lib/test/test_tkinter/test_font.py similarity index 98% rename from Lib/tkinter/test/test_tkinter/test_font.py rename to Lib/test/test_tkinter/test_font.py index 058c53a9023..563707ddd2f 100644 --- a/Lib/tkinter/test/test_tkinter/test_font.py +++ b/Lib/test/test_tkinter/test_font.py @@ -2,7 +2,7 @@ import unittest import tkinter from tkinter import font from test.support import requires, gc_collect, ALWAYS_EQ -from tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest +from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest requires('gui') diff --git a/Lib/tkinter/test/test_tkinter/test_geometry_managers.py b/Lib/test/test_tkinter/test_geometry_managers.py similarity index 96% rename from Lib/tkinter/test/test_tkinter/test_geometry_managers.py rename to Lib/test/test_tkinter/test_geometry_managers.py index c645d430079..3663048a145 100644 --- a/Lib/tkinter/test/test_tkinter/test_geometry_managers.py +++ b/Lib/test/test_tkinter/test_geometry_managers.py @@ -4,8 +4,8 @@ import tkinter from tkinter import TclError from test.support import requires -from tkinter.test.support import pixels_conv, tcl_version, requires_tcl -from tkinter.test.widget_tests import AbstractWidgetTest +from test.test_tkinter.support import pixels_conv +from test.test_tkinter.widget_tests import AbstractWidgetTest requires('gui') @@ -295,8 +295,7 @@ class PlaceTest(AbstractWidgetTest, unittest.TestCase): with self.assertRaisesRegex(TclError, "can't place %s relative to " "itself" % re.escape(str(f2))): f2.place_configure(in_=f2) - if tcl_version >= (8, 5): - self.assertEqual(f2.winfo_manager(), '') + self.assertEqual(f2.winfo_manager(), '') with self.assertRaisesRegex(TclError, 'bad window path name'): f2.place_configure(in_='spam') f2.place_configure(in_=f) @@ -491,8 +490,7 @@ class GridTest(AbstractWidgetTest, unittest.TestCase): for i in range(rows + 1): self.root.grid_rowconfigure(i, weight=0, minsize=0, pad=0, uniform='') self.root.grid_propagate(1) - if tcl_version >= (8, 5): - self.root.grid_anchor('nw') + self.root.grid_anchor('nw') super().tearDown() def test_grid_configure(self): @@ -619,16 +617,14 @@ class GridTest(AbstractWidgetTest, unittest.TestCase): self.root.grid_columnconfigure((0, 3)) b = tkinter.Button(self.root) b.grid_configure(column=0, row=0) - if tcl_version >= (8, 5): - self.root.grid_columnconfigure('all', weight=3) - with self.assertRaisesRegex(TclError, 'expected integer but got "all"'): - self.root.grid_columnconfigure('all') - self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3) + self.root.grid_columnconfigure('all', weight=3) + with self.assertRaisesRegex(TclError, 'expected integer but got "all"'): + self.root.grid_columnconfigure('all') + self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3) self.assertEqual(self.root.grid_columnconfigure(3, 'weight'), 2) self.assertEqual(self.root.grid_columnconfigure(265, 'weight'), 0) - if tcl_version >= (8, 5): - self.root.grid_columnconfigure(b, weight=4) - self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 4) + self.root.grid_columnconfigure(b, weight=4) + self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 4) def test_grid_columnconfigure_minsize(self): with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'): @@ -675,16 +671,14 @@ class GridTest(AbstractWidgetTest, unittest.TestCase): self.root.grid_rowconfigure((0, 3)) b = tkinter.Button(self.root) b.grid_configure(column=0, row=0) - if tcl_version >= (8, 5): - self.root.grid_rowconfigure('all', weight=3) - with self.assertRaisesRegex(TclError, 'expected integer but got "all"'): - self.root.grid_rowconfigure('all') - self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3) + self.root.grid_rowconfigure('all', weight=3) + with self.assertRaisesRegex(TclError, 'expected integer but got "all"'): + self.root.grid_rowconfigure('all') + self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3) self.assertEqual(self.root.grid_rowconfigure(3, 'weight'), 2) self.assertEqual(self.root.grid_rowconfigure(265, 'weight'), 0) - if tcl_version >= (8, 5): - self.root.grid_rowconfigure(b, weight=4) - self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 4) + self.root.grid_rowconfigure(b, weight=4) + self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 4) def test_grid_rowconfigure_minsize(self): with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'): @@ -774,7 +768,6 @@ class GridTest(AbstractWidgetTest, unittest.TestCase): self.assertEqual(info['pady'], self._str(4)) self.assertEqual(info['sticky'], 'ns') - @requires_tcl(8, 5) def test_grid_anchor(self): with self.assertRaisesRegex(TclError, 'bad anchor "x"'): self.root.grid_anchor('x') diff --git a/Lib/tkinter/test/test_tkinter/test_images.py b/Lib/test/test_tkinter/test_images.py similarity index 99% rename from Lib/tkinter/test/test_tkinter/test_images.py rename to Lib/test/test_tkinter/test_images.py index cc69ccac62d..b6f8b79ae68 100644 --- a/Lib/tkinter/test/test_tkinter/test_images.py +++ b/Lib/test/test_tkinter/test_images.py @@ -2,7 +2,7 @@ import unittest import tkinter from test import support from test.support import os_helper -from tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest, requires_tcl +from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest, requires_tcl support.requires('gui') diff --git a/Lib/tkinter/test/test_tkinter/test_loadtk.py b/Lib/test/test_tkinter/test_loadtk.py similarity index 100% rename from Lib/tkinter/test/test_tkinter/test_loadtk.py rename to Lib/test/test_tkinter/test_loadtk.py diff --git a/Lib/tkinter/test/test_tkinter/test_messagebox.py b/Lib/test/test_tkinter/test_messagebox.py similarity index 94% rename from Lib/tkinter/test/test_tkinter/test_messagebox.py rename to Lib/test/test_tkinter/test_messagebox.py index d38541a5a45..f41bdc98286 100644 --- a/Lib/tkinter/test/test_tkinter/test_messagebox.py +++ b/Lib/test/test_tkinter/test_messagebox.py @@ -1,7 +1,7 @@ import unittest import tkinter from test.support import requires, swap_attr -from tkinter.test.support import AbstractDefaultRootTest +from test.test_tkinter.support import AbstractDefaultRootTest from tkinter.commondialog import Dialog from tkinter.messagebox import showinfo diff --git a/Lib/tkinter/test/test_tkinter/test_misc.py b/Lib/test/test_tkinter/test_misc.py similarity index 88% rename from Lib/tkinter/test/test_tkinter/test_misc.py rename to Lib/test/test_tkinter/test_misc.py index 2c78eaca2c8..d1aca58d15f 100644 --- a/Lib/tkinter/test/test_tkinter/test_misc.py +++ b/Lib/test/test_tkinter/test_misc.py @@ -3,7 +3,7 @@ import unittest import tkinter import enum from test import support -from tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest +from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest support.requires('gui') @@ -201,6 +201,13 @@ class MiscTest(AbstractTkTest, unittest.TestCase): root.clipboard_get() def test_winfo_rgb(self): + + def assertApprox(col1, col2): + # A small amount of flexibility is required (bpo-45496) + # 33 is ~0.05% of 65535, which is a reasonable margin + for col1_channel, col2_channel in zip(col1, col2): + self.assertAlmostEqual(col1_channel, col2_channel, delta=33) + root = self.root rgb = root.winfo_rgb @@ -210,9 +217,9 @@ class MiscTest(AbstractTkTest, unittest.TestCase): # #RGB - extends each 4-bit hex value to be 16-bit. self.assertEqual(rgb('#F0F'), (0xFFFF, 0x0000, 0xFFFF)) # #RRGGBB - extends each 8-bit hex value to be 16-bit. - self.assertEqual(rgb('#4a3c8c'), (0x4a4a, 0x3c3c, 0x8c8c)) + assertApprox(rgb('#4a3c8c'), (0x4a4a, 0x3c3c, 0x8c8c)) # #RRRRGGGGBBBB - self.assertEqual(rgb('#dede14143939'), (0xdede, 0x1414, 0x3939)) + assertApprox(rgb('#dede14143939'), (0xdede, 0x1414, 0x3939)) # Invalid string. with self.assertRaises(tkinter.TclError): rgb('#123456789a') @@ -334,6 +341,35 @@ class MiscTest(AbstractTkTest, unittest.TestCase): self.assertEqual(log, [1]) self.assertTrue(self.root.winfo_exists()) + def test_info_patchlevel(self): + vi = self.root.info_patchlevel() + f = tkinter.Frame(self.root) + self.assertEqual(f.info_patchlevel(), vi) + # The following is almost a copy of tests for sys.version_info. + self.assertIsInstance(vi[:], tuple) + self.assertEqual(len(vi), 5) + self.assertIsInstance(vi[0], int) + self.assertIsInstance(vi[1], int) + self.assertIsInstance(vi[2], int) + self.assertIn(vi[3], ("alpha", "beta", "candidate", "final")) + self.assertIsInstance(vi[4], int) + self.assertIsInstance(vi.major, int) + self.assertIsInstance(vi.minor, int) + self.assertIsInstance(vi.micro, int) + self.assertIn(vi.releaselevel, ("alpha", "beta", "final")) + self.assertIsInstance(vi.serial, int) + self.assertEqual(vi[0], vi.major) + self.assertEqual(vi[1], vi.minor) + self.assertEqual(vi[2], vi.micro) + self.assertEqual(vi[3], vi.releaselevel) + self.assertEqual(vi[4], vi.serial) + self.assertTrue(vi > (1,0,0)) + if vi.releaselevel == 'final': + self.assertEqual(vi.serial, 0) + else: + self.assertEqual(vi.micro, 0) + self.assertTrue(str(vi).startswith(f'{vi.major}.{vi.minor}')) + class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase): diff --git a/Lib/tkinter/test/test_tkinter/test_simpledialog.py b/Lib/test/test_tkinter/test_simpledialog.py similarity index 93% rename from Lib/tkinter/test/test_tkinter/test_simpledialog.py rename to Lib/test/test_tkinter/test_simpledialog.py index 18cd2712b0c..502f7f7098a 100644 --- a/Lib/tkinter/test/test_tkinter/test_simpledialog.py +++ b/Lib/test/test_tkinter/test_simpledialog.py @@ -1,7 +1,7 @@ import unittest import tkinter from test.support import requires, swap_attr -from tkinter.test.support import AbstractDefaultRootTest +from test.test_tkinter.support import AbstractDefaultRootTest from tkinter.simpledialog import Dialog, askinteger requires('gui') diff --git a/Lib/test/test_tkinter/test_text.py b/Lib/test/test_tkinter/test_text.py new file mode 100644 index 00000000000..328e4256ce0 --- /dev/null +++ b/Lib/test/test_tkinter/test_text.py @@ -0,0 +1,97 @@ +import unittest +import tkinter +from test.support import requires +from test.test_tkinter.support import AbstractTkTest + +requires('gui') + +class TextTest(AbstractTkTest, unittest.TestCase): + + def setUp(self): + super().setUp() + self.text = tkinter.Text(self.root) + + def test_debug(self): + text = self.text + olddebug = text.debug() + try: + text.debug(0) + self.assertEqual(text.debug(), 0) + text.debug(1) + self.assertEqual(text.debug(), 1) + finally: + text.debug(olddebug) + self.assertEqual(text.debug(), olddebug) + + def test_search(self): + text = self.text + + # pattern and index are obligatory arguments. + self.assertRaises(tkinter.TclError, text.search, None, '1.0') + self.assertRaises(tkinter.TclError, text.search, 'a', None) + self.assertRaises(tkinter.TclError, text.search, None, None) + + # Invalid text index. + self.assertRaises(tkinter.TclError, text.search, '', 0) + + # Check if we are getting the indices as strings -- you are likely + # to get Tcl_Obj under Tk 8.5 if Tkinter doesn't convert it. + text.insert('1.0', 'hi-test') + self.assertEqual(text.search('-test', '1.0', 'end'), '1.2') + self.assertEqual(text.search('test', '1.0', 'end'), '1.3') + + def test_count(self): + # XXX Some assertions do not check against the intended result, + # but instead check the current result to prevent regression. + text = self.text + text.insert('1.0', + 'Lorem ipsum dolor sit amet,\n' + 'consectetur adipiscing elit,\n' + 'sed do eiusmod tempor incididunt\n' + 'ut labore et dolore magna aliqua.') + + options = ('chars', 'indices', 'lines', + 'displaychars', 'displayindices', 'displaylines', + 'xpixels', 'ypixels') + if self.wantobjects: + self.assertEqual(len(text.count('1.0', 'end', *options)), 8) + else: + text.count('1.0', 'end', *options) + self.assertEqual(text.count('1.0', 'end', 'chars', 'lines'), (124, 4) + if self.wantobjects else '124 4') + self.assertEqual(text.count('1.3', '4.5', 'chars', 'lines'), (92, 3) + if self.wantobjects else '92 3') + self.assertEqual(text.count('4.5', '1.3', 'chars', 'lines'), (-92, -3) + if self.wantobjects else '-92 -3') + self.assertEqual(text.count('1.3', '1.3', 'chars', 'lines'), (0, 0) + if self.wantobjects else '0 0') + self.assertEqual(text.count('1.0', 'end', 'lines'), (4,) + if self.wantobjects else ('4',)) + self.assertEqual(text.count('end', '1.0', 'lines'), (-4,) + if self.wantobjects else ('-4',)) + self.assertEqual(text.count('1.3', '1.5', 'lines'), None + if self.wantobjects else ('0',)) + self.assertEqual(text.count('1.3', '1.3', 'lines'), None + if self.wantobjects else ('0',)) + self.assertEqual(text.count('1.0', 'end'), (124,) # 'indices' by default + if self.wantobjects else ('124',)) + self.assertRaises(tkinter.TclError, text.count, '1.0', 'end', 'spam') + self.assertRaises(tkinter.TclError, text.count, '1.0', 'end', '-lines') + + self.assertIsInstance(text.count('1.3', '1.5', 'ypixels'), tuple) + self.assertIsInstance(text.count('1.3', '1.5', 'update', 'ypixels'), int + if self.wantobjects else str) + self.assertEqual(text.count('1.3', '1.3', 'update', 'ypixels'), None + if self.wantobjects else '0') + self.assertEqual(text.count('1.3', '1.5', 'update', 'indices'), 2 + if self.wantobjects else '2') + self.assertEqual(text.count('1.3', '1.3', 'update', 'indices'), None + if self.wantobjects else '0') + self.assertEqual(text.count('1.3', '1.5', 'update'), (2,) + if self.wantobjects else ('2',)) + self.assertEqual(text.count('1.3', '1.3', 'update'), None + if self.wantobjects else ('0',)) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/tkinter/test/test_tkinter/test_variables.py b/Lib/test/test_tkinter/test_variables.py similarity index 99% rename from Lib/tkinter/test/test_tkinter/test_variables.py rename to Lib/test/test_tkinter/test_variables.py index 427e1684543..c1d232e2feb 100644 --- a/Lib/tkinter/test/test_tkinter/test_variables.py +++ b/Lib/test/test_tkinter/test_variables.py @@ -6,7 +6,7 @@ import tkinter from tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl, TclError) from test.support import ALWAYS_EQ -from tkinter.test.support import AbstractDefaultRootTest +from test.test_tkinter.support import AbstractDefaultRootTest class Var(Variable): diff --git a/Lib/tkinter/test/test_tkinter/test_widgets.py b/Lib/test/test_tkinter/test_widgets.py similarity index 83% rename from Lib/tkinter/test/test_tkinter/test_widgets.py rename to Lib/test/test_tkinter/test_widgets.py index cc227e57967..6fde93cbecc 100644 --- a/Lib/tkinter/test/test_tkinter/test_widgets.py +++ b/Lib/test/test_tkinter/test_widgets.py @@ -4,11 +4,11 @@ from tkinter import TclError import os from test.support import requires -from tkinter.test.support import (tcl_version, requires_tcl, +from test.test_tkinter.support import (requires_tcl, get_tk_patchlevel, widget_eq, AbstractDefaultRootTest) -from tkinter.test.widget_tests import ( - add_standard_options, noconv, pixels_round, +from test.test_tkinter.widget_tests import ( + add_standard_options, AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests, setUpModule) @@ -20,7 +20,7 @@ def float_round(x): class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests): - _conv_pad_pixels = noconv + _conv_pad_pixels = False def test_configure_class(self): widget = self.create() @@ -139,7 +139,7 @@ class LabelFrameTest(AbstractToplevelTest, unittest.TestCase): class AbstractLabelTest(AbstractWidgetTest, IntegerSizeTests): - _conv_pixels = noconv + _conv_pixels = False def test_configure_highlightthickness(self): widget = self.create() @@ -212,6 +212,32 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase): widget = self.create() self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string') + def test_unique_variables(self): + frames = [] + buttons = [] + for i in range(2): + f = tkinter.Frame(self.root) + f.pack() + frames.append(f) + for j in 'AB': + b = tkinter.Checkbutton(f, text=j) + b.pack() + buttons.append(b) + variables = [str(b['variable']) for b in buttons] + self.assertEqual(len(set(variables)), 4, variables) + + def test_same_name(self): + f1 = tkinter.Frame(self.root) + f2 = tkinter.Frame(self.root) + b1 = tkinter.Checkbutton(f1, name='test', text='Test1') + b2 = tkinter.Checkbutton(f2, name='test', text='Test2') + + v = tkinter.IntVar(self.root, name='test') + b1.select() + self.assertEqual(v.get(), 1) + b2.deselect() + self.assertEqual(v.get(), 0) + @add_standard_options(StandardOptionsTests) class RadiobuttonTest(AbstractLabelTest, unittest.TestCase): @@ -249,7 +275,7 @@ class MenubuttonTest(AbstractLabelTest, unittest.TestCase): 'takefocus', 'text', 'textvariable', 'underline', 'width', 'wraplength', ) - _conv_pixels = staticmethod(pixels_round) + _conv_pixels = round def create(self, **kwargs): return tkinter.Menubutton(self.root, **kwargs) @@ -345,10 +371,7 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase): self.checkPixelsParam(widget, 'insertwidth', 1.3, 3.6, '10p') self.checkParam(widget, 'insertwidth', 0.1, expected=2) self.checkParam(widget, 'insertwidth', -2, expected=2) - if pixels_round(0.9) <= 0: - self.checkParam(widget, 'insertwidth', 0.9, expected=2) - else: - self.checkParam(widget, 'insertwidth', 0.9, expected=1) + self.checkParam(widget, 'insertwidth', 0.9, expected=1) def test_configure_invalidcommand(self): widget = self.create() @@ -550,8 +573,6 @@ class TextTest(AbstractWidgetTest, unittest.TestCase): 'tabs', 'tabstyle', 'takefocus', 'undo', 'width', 'wrap', 'xscrollcommand', 'yscrollcommand', ) - if tcl_version < (8, 5): - _stringify = True def create(self, **kwargs): return tkinter.Text(self.root, **kwargs) @@ -560,12 +581,10 @@ class TextTest(AbstractWidgetTest, unittest.TestCase): widget = self.create() self.checkBooleanParam(widget, 'autoseparators') - @requires_tcl(8, 5) def test_configure_blockcursor(self): widget = self.create() self.checkBooleanParam(widget, 'blockcursor') - @requires_tcl(8, 5) def test_configure_endline(self): widget = self.create() text = '\n'.join('Line %d' for i in range(100)) @@ -589,7 +608,6 @@ class TextTest(AbstractWidgetTest, unittest.TestCase): widget = self.create() self.checkIntegerParam(widget, 'maxundo', 0, 5, -1) - @requires_tcl(8, 5) def test_configure_inactiveselectbackground(self): widget = self.create() self.checkColorParam(widget, 'inactiveselectbackground') @@ -603,8 +621,7 @@ class TextTest(AbstractWidgetTest, unittest.TestCase): def test_configure_selectborderwidth(self): widget = self.create() self.checkPixelsParam(widget, 'selectborderwidth', - 1.3, 2.6, -2, '10p', conv=noconv, - keep_orig=tcl_version >= (8, 5)) + 1.3, 2.6, -2, '10p', conv=False) def test_configure_spacing1(self): widget = self.create() @@ -621,7 +638,6 @@ class TextTest(AbstractWidgetTest, unittest.TestCase): self.checkPixelsParam(widget, 'spacing3', 20, 21.4, 22.6, '0.5c') self.checkParam(widget, 'spacing3', -10, expected=0) - @requires_tcl(8, 5) def test_configure_startline(self): widget = self.create() text = '\n'.join('Line %d' for i in range(100)) @@ -637,27 +653,18 @@ class TextTest(AbstractWidgetTest, unittest.TestCase): def test_configure_state(self): widget = self.create() - if tcl_version < (8, 5): - self.checkParams(widget, 'state', 'disabled', 'normal') - else: - self.checkEnumParam(widget, 'state', 'disabled', 'normal') + self.checkEnumParam(widget, 'state', 'disabled', 'normal') def test_configure_tabs(self): widget = self.create() - if get_tk_patchlevel() < (8, 5, 11): - self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i'), - expected=('10.2', '20.7', '1i', '2i')) - else: - self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i')) + self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i')) self.checkParam(widget, 'tabs', '10.2 20.7 1i 2i', expected=('10.2', '20.7', '1i', '2i')) self.checkParam(widget, 'tabs', '2c left 4c 6c center', expected=('2c', 'left', '4c', '6c', 'center')) self.checkInvalidParam(widget, 'tabs', 'spam', - errmsg='bad screen distance "spam"', - keep_orig=tcl_version >= (8, 5)) + errmsg='bad screen distance "spam"') - @requires_tcl(8, 5) def test_configure_tabstyle(self): widget = self.create() self.checkEnumParam(widget, 'tabstyle', 'tabular', 'wordprocessor') @@ -674,10 +681,7 @@ class TextTest(AbstractWidgetTest, unittest.TestCase): def test_configure_wrap(self): widget = self.create() - if tcl_version < (8, 5): - self.checkParams(widget, 'wrap', 'char', 'none', 'word') - else: - self.checkEnumParam(widget, 'wrap', 'char', 'none', 'word') + self.checkEnumParam(widget, 'wrap', 'char', 'none', 'word') def test_bbox(self): widget = self.create() @@ -755,6 +759,164 @@ class CanvasTest(AbstractWidgetTest, unittest.TestCase): self.checkPixelsParam(widget, 'yscrollincrement', 10, 0, 11.2, 13.6, -10, '0.1i') + def _test_option_joinstyle(self, c, factory): + for joinstyle in 'bevel', 'miter', 'round': + i = factory(joinstyle=joinstyle) + self.assertEqual(c.itemcget(i, 'joinstyle'), joinstyle) + self.assertRaises(TclError, factory, joinstyle='spam') + + def _test_option_smooth(self, c, factory): + for smooth in 1, True, '1', 'true', 'yes', 'on': + i = factory(smooth=smooth) + self.assertEqual(c.itemcget(i, 'smooth'), 'true') + for smooth in 0, False, '0', 'false', 'no', 'off': + i = factory(smooth=smooth) + self.assertEqual(c.itemcget(i, 'smooth'), '0') + i = factory(smooth=True, splinestep=30) + self.assertEqual(c.itemcget(i, 'smooth'), 'true') + self.assertEqual(c.itemcget(i, 'splinestep'), '30') + i = factory(smooth='raw', splinestep=30) + self.assertEqual(c.itemcget(i, 'smooth'), 'raw') + self.assertEqual(c.itemcget(i, 'splinestep'), '30') + self.assertRaises(TclError, factory, smooth='spam') + + def test_create_rectangle(self): + c = self.create() + i1 = c.create_rectangle(20, 30, 60, 10) + self.assertEqual(c.coords(i1), [20.0, 10.0, 60.0, 30.0]) + self.assertEqual(c.bbox(i1), (19, 9, 61, 31)) + + i2 = c.create_rectangle([21, 31, 61, 11]) + self.assertEqual(c.coords(i2), [21.0, 11.0, 61.0, 31.0]) + self.assertEqual(c.bbox(i2), (20, 10, 62, 32)) + + i3 = c.create_rectangle((22, 32), (62, 12)) + self.assertEqual(c.coords(i3), [22.0, 12.0, 62.0, 32.0]) + self.assertEqual(c.bbox(i3), (21, 11, 63, 33)) + + i4 = c.create_rectangle([(23, 33), (63, 13)]) + self.assertEqual(c.coords(i4), [23.0, 13.0, 63.0, 33.0]) + self.assertEqual(c.bbox(i4), (22, 12, 64, 34)) + + self.assertRaises(TclError, c.create_rectangle, 20, 30, 60) + self.assertRaises(TclError, c.create_rectangle, [20, 30, 60]) + self.assertRaises(TclError, c.create_rectangle, 20, 30, 40, 50, 60, 10) + self.assertRaises(TclError, c.create_rectangle, [20, 30, 40, 50, 60, 10]) + self.assertRaises(TclError, c.create_rectangle, 20, 30) + self.assertRaises(TclError, c.create_rectangle, [20, 30]) + self.assertRaises(IndexError, c.create_rectangle) + self.assertRaises(IndexError, c.create_rectangle, []) + + def test_create_line(self): + c = self.create() + i1 = c.create_line(20, 30, 40, 50, 60, 10) + self.assertEqual(c.coords(i1), [20.0, 30.0, 40.0, 50.0, 60.0, 10.0]) + self.assertEqual(c.bbox(i1), (18, 8, 62, 52)) + self.assertEqual(c.itemcget(i1, 'arrow'), 'none') + self.assertEqual(c.itemcget(i1, 'arrowshape'), '8 10 3') + self.assertEqual(c.itemcget(i1, 'capstyle'), 'butt') + self.assertEqual(c.itemcget(i1, 'joinstyle'), 'round') + self.assertEqual(c.itemcget(i1, 'smooth'), '0') + self.assertEqual(c.itemcget(i1, 'splinestep'), '12') + + i2 = c.create_line([21, 31, 41, 51, 61, 11]) + self.assertEqual(c.coords(i2), [21.0, 31.0, 41.0, 51.0, 61.0, 11.0]) + self.assertEqual(c.bbox(i2), (19, 9, 63, 53)) + + i3 = c.create_line((22, 32), (42, 52), (62, 12)) + self.assertEqual(c.coords(i3), [22.0, 32.0, 42.0, 52.0, 62.0, 12.0]) + self.assertEqual(c.bbox(i3), (20, 10, 64, 54)) + + i4 = c.create_line([(23, 33), (43, 53), (63, 13)]) + self.assertEqual(c.coords(i4), [23.0, 33.0, 43.0, 53.0, 63.0, 13.0]) + self.assertEqual(c.bbox(i4), (21, 11, 65, 55)) + + self.assertRaises(TclError, c.create_line, 20, 30, 60) + self.assertRaises(TclError, c.create_line, [20, 30, 60]) + self.assertRaises(TclError, c.create_line, 20, 30) + self.assertRaises(TclError, c.create_line, [20, 30]) + self.assertRaises(IndexError, c.create_line) + self.assertRaises(IndexError, c.create_line, []) + + for arrow in 'none', 'first', 'last', 'both': + i = c.create_line(20, 30, 60, 10, arrow=arrow) + self.assertEqual(c.itemcget(i, 'arrow'), arrow) + i = c.create_line(20, 30, 60, 10, arrow='first', arrowshape=[10, 15, 5]) + self.assertEqual(c.itemcget(i, 'arrowshape'), '10 15 5') + self.assertRaises(TclError, c.create_line, 20, 30, 60, 10, arrow='spam') + + for capstyle in 'butt', 'projecting', 'round': + i = c.create_line(20, 30, 60, 10, capstyle=capstyle) + self.assertEqual(c.itemcget(i, 'capstyle'), capstyle) + self.assertRaises(TclError, c.create_line, 20, 30, 60, 10, capstyle='spam') + + self._test_option_joinstyle(c, + lambda **kwargs: c.create_line(20, 30, 40, 50, 60, 10, **kwargs)) + self._test_option_smooth(c, + lambda **kwargs: c.create_line(20, 30, 60, 10, **kwargs)) + + def test_create_polygon(self): + c = self.create() + i1 = c.create_polygon(20, 30, 40, 50, 60, 10) + self.assertEqual(c.coords(i1), [20.0, 30.0, 40.0, 50.0, 60.0, 10.0]) + self.assertEqual(c.bbox(i1), (19, 9, 61, 51)) + self.assertEqual(c.itemcget(i1, 'joinstyle'), 'round') + self.assertEqual(c.itemcget(i1, 'smooth'), '0') + self.assertEqual(c.itemcget(i1, 'splinestep'), '12') + + i2 = c.create_polygon([21, 31, 41, 51, 61, 11]) + self.assertEqual(c.coords(i2), [21.0, 31.0, 41.0, 51.0, 61.0, 11.0]) + self.assertEqual(c.bbox(i2), (20, 10, 62, 52)) + + i3 = c.create_polygon((22, 32), (42, 52), (62, 12)) + self.assertEqual(c.coords(i3), [22.0, 32.0, 42.0, 52.0, 62.0, 12.0]) + self.assertEqual(c.bbox(i3), (21, 11, 63, 53)) + + i4 = c.create_polygon([(23, 33), (43, 53), (63, 13)]) + self.assertEqual(c.coords(i4), [23.0, 33.0, 43.0, 53.0, 63.0, 13.0]) + self.assertEqual(c.bbox(i4), (22, 12, 64, 54)) + + self.assertRaises(TclError, c.create_polygon, 20, 30, 60) + self.assertRaises(TclError, c.create_polygon, [20, 30, 60]) + self.assertRaises(IndexError, c.create_polygon) + self.assertRaises(IndexError, c.create_polygon, []) + + self._test_option_joinstyle(c, + lambda **kwargs: c.create_polygon(20, 30, 40, 50, 60, 10, **kwargs)) + self._test_option_smooth(c, + lambda **kwargs: c.create_polygon(20, 30, 40, 50, 60, 10, **kwargs)) + + def test_coords(self): + c = self.create() + i = c.create_line(20, 30, 40, 50, 60, 10, tags='x') + self.assertEqual(c.coords(i), [20.0, 30.0, 40.0, 50.0, 60.0, 10.0]) + self.assertEqual(c.coords('x'), [20.0, 30.0, 40.0, 50.0, 60.0, 10.0]) + self.assertEqual(c.bbox(i), (18, 8, 62, 52)) + + c.coords(i, 50, 60, 70, 80, 90, 40) + self.assertEqual(c.coords(i), [50.0, 60.0, 70.0, 80.0, 90.0, 40.0]) + self.assertEqual(c.bbox(i), (48, 38, 92, 82)) + + c.coords(i, [21, 31, 41, 51, 61, 11]) + self.assertEqual(c.coords(i), [21.0, 31.0, 41.0, 51.0, 61.0, 11.0]) + + c.coords(i, 20, 30, 60, 10) + self.assertEqual(c.coords(i), [20.0, 30.0, 60.0, 10.0]) + self.assertEqual(c.bbox(i), (18, 8, 62, 32)) + + self.assertRaises(TclError, c.coords, i, 20, 30, 60) + self.assertRaises(TclError, c.coords, i, [20, 30, 60]) + self.assertRaises(TclError, c.coords, i, 20, 30) + self.assertRaises(TclError, c.coords, i, [20, 30]) + + c.coords(i, '20', '30c', '60i', '10p') + coords = c.coords(i) + self.assertIsInstance(coords, list) + self.assertEqual(len(coords), 4) + self.assertEqual(coords[0], 20) + for i in range(4): + self.assertIsInstance(coords[i], float) + @requires_tcl(8, 6) def test_moveto(self): widget = self.create() @@ -800,7 +962,7 @@ class ListboxTest(AbstractWidgetTest, unittest.TestCase): self.checkEnumParam(widget, 'activestyle', 'dotbox', 'none', 'underline') - test_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_configure_justify) + test_configure_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_configure_justify) def test_configure_listvariable(self): widget = self.create() @@ -939,7 +1101,7 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase): def test_configure_from(self): widget = self.create() - conv = False if get_tk_patchlevel() >= (8, 6, 10) else float_round + conv = float if get_tk_patchlevel() >= (8, 6, 10) else float_round self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=conv) def test_configure_label(self): @@ -1055,12 +1217,12 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): def test_configure_handlesize(self): widget = self.create() self.checkPixelsParam(widget, 'handlesize', 8, 9.4, 10.6, -3, '2m', - conv=noconv) + conv=False) def test_configure_height(self): widget = self.create() self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i', - conv=noconv) + conv=False) def test_configure_opaqueresize(self): widget = self.create() @@ -1076,7 +1238,7 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): widget = self.create() self.checkPixelsParam(widget, 'proxyborderwidth', 0, 1.3, 2.9, 6, -2, '10p', - conv=noconv) + conv=False) @requires_tcl(8, 6, 5) def test_configure_proxyrelief(self): @@ -1098,7 +1260,7 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): def test_configure_sashwidth(self): widget = self.create() self.checkPixelsParam(widget, 'sashwidth', 10, 11.1, 15.6, -3, '1m', - conv=noconv) + conv=False) def test_configure_showhandle(self): widget = self.create() @@ -1107,7 +1269,7 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): def test_configure_width(self): widget = self.create() self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i', - conv=noconv) + conv=False) def create2(self): p = self.create() @@ -1127,15 +1289,12 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): self.assertEqual(v, p.paneconfigure(b, k)) self.assertEqual(v[4], p.panecget(b, k)) - def check_paneconfigure(self, p, b, name, value, expected, stringify=False): - conv = lambda x: x - if not self.wantobjects or stringify: + def check_paneconfigure(self, p, b, name, value, expected): + if not self.wantobjects: expected = str(expected) - if self.wantobjects and stringify: - conv = str p.paneconfigure(b, **{name: value}) - self.assertEqual(conv(p.paneconfigure(b, name)[4]), expected) - self.assertEqual(conv(p.panecget(b, name)), expected) + self.assertEqual(p.paneconfigure(b, name)[4], expected) + self.assertEqual(p.panecget(b, name), expected) def check_paneconfigure_bad(self, p, b, name, msg): with self.assertRaisesRegex(TclError, msg): @@ -1155,12 +1314,10 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): def test_paneconfigure_height(self): p, b, c = self.create2() - self.check_paneconfigure(p, b, 'height', 10, 10, - stringify=get_tk_patchlevel() < (8, 5, 11)) + self.check_paneconfigure(p, b, 'height', 10, 10) self.check_paneconfigure_bad(p, b, 'height', 'bad screen distance "badValue"') - @requires_tcl(8, 5) def test_paneconfigure_hide(self): p, b, c = self.create2() self.check_paneconfigure(p, b, 'hide', False, 0) @@ -1193,7 +1350,6 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): 'be a string containing zero or more of ' 'n, e, s, and w') - @requires_tcl(8, 5) def test_paneconfigure_stretch(self): p, b, c = self.create2() self.check_paneconfigure(p, b, 'stretch', 'alw', 'always') @@ -1203,8 +1359,7 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): def test_paneconfigure_width(self): p, b, c = self.create2() - self.check_paneconfigure(p, b, 'width', 10, 10, - stringify=get_tk_patchlevel() < (8, 5, 11)) + self.check_paneconfigure(p, b, 'width', 10, 10) self.check_paneconfigure_bad(p, b, 'width', 'bad screen distance "badValue"') @@ -1218,7 +1373,7 @@ class MenuTest(AbstractWidgetTest, unittest.TestCase): 'postcommand', 'relief', 'selectcolor', 'takefocus', 'tearoff', 'tearoffcommand', 'title', 'type', ) - _conv_pixels = noconv + _conv_pixels = False def create(self, **kwargs): return tkinter.Menu(self.root, **kwargs) @@ -1290,7 +1445,7 @@ class MessageTest(AbstractWidgetTest, unittest.TestCase): 'justify', 'padx', 'pady', 'relief', 'takefocus', 'text', 'textvariable', 'width', ) - _conv_pad_pixels = noconv + _conv_pad_pixels = False def create(self, **kwargs): return tkinter.Message(self.root, **kwargs) diff --git a/Lib/tkinter/test/widget_tests.py b/Lib/test/test_tkinter/widget_tests.py similarity index 94% rename from Lib/tkinter/test/widget_tests.py rename to Lib/test/test_tkinter/widget_tests.py index 9702ff45300..85b0511aba3 100644 --- a/Lib/tkinter/test/widget_tests.py +++ b/Lib/test/test_tkinter/widget_tests.py @@ -1,27 +1,15 @@ # Common tests for test_tkinter/test_widgets.py and test_ttk/test_widgets.py -import unittest import tkinter -from tkinter.test.support import (AbstractTkTest, tcl_version, requires_tcl, - get_tk_patchlevel, pixels_conv, tcl_obj_eq) +from test.test_tkinter.support import (AbstractTkTest, tcl_version, + pixels_conv, tcl_obj_eq) import test.support -noconv = False -if get_tk_patchlevel() < (8, 5, 11): - noconv = str - -pixels_round = round -if get_tk_patchlevel()[:3] == (8, 5, 11): - # Issue #19085: Workaround a bug in Tk - # http://core.tcl.tk/tk/info/3497848 - pixels_round = int - - _sentinel = object() class AbstractWidgetTest(AbstractTkTest): - _conv_pixels = staticmethod(pixels_round) + _conv_pixels = round _conv_pad_pixels = None _stringify = False @@ -65,8 +53,7 @@ class AbstractWidgetTest(AbstractTkTest): self.assertEqual(len(t), 5) self.assertEqual2(t[4], expected, eq=eq) - def checkInvalidParam(self, widget, name, value, errmsg=None, *, - keep_orig=True): + def checkInvalidParam(self, widget, name, value, errmsg=None): orig = widget[name] if errmsg is not None: errmsg = errmsg.format(value) @@ -74,18 +61,12 @@ class AbstractWidgetTest(AbstractTkTest): widget[name] = value if errmsg is not None: self.assertEqual(str(cm.exception), errmsg) - if keep_orig: - self.assertEqual(widget[name], orig) - else: - widget[name] = orig + self.assertEqual(widget[name], orig) with self.assertRaises(tkinter.TclError) as cm: widget.configure({name: value}) if errmsg is not None: self.assertEqual(str(cm.exception), errmsg) - if keep_orig: - self.assertEqual(widget[name], orig) - else: - widget[name] = orig + self.assertEqual(widget[name], orig) def checkParams(self, widget, name, *values, **kwargs): for value in values: @@ -128,8 +109,7 @@ class AbstractWidgetTest(AbstractTkTest): def checkCursorParam(self, widget, name, **kwargs): self.checkParams(widget, name, 'arrow', 'watch', 'cross', '',**kwargs) - if tcl_version >= (8, 5): - self.checkParam(widget, name, 'none') + self.checkParam(widget, name, 'none') self.checkInvalidParam(widget, name, 'spam', errmsg='bad cursor spec "spam"') @@ -154,7 +134,7 @@ class AbstractWidgetTest(AbstractTkTest): self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg) def checkPixelsParam(self, widget, name, *values, - conv=None, keep_orig=True, **kwargs): + conv=None, **kwargs): if conv is None: conv = self._conv_pixels for value in values: @@ -167,9 +147,9 @@ class AbstractWidgetTest(AbstractTkTest): self.checkParam(widget, name, value, expected=expected, conv=conv1, **kwargs) self.checkInvalidParam(widget, name, '6x', - errmsg='bad screen distance "6x"', keep_orig=keep_orig) + errmsg='bad screen distance "6x"') self.checkInvalidParam(widget, name, 'spam', - errmsg='bad screen distance "spam"', keep_orig=keep_orig) + errmsg='bad screen distance "spam"') def checkReliefParam(self, widget, name): self.checkParams(widget, name, @@ -475,12 +455,10 @@ class StandardOptionsTests: widget = self.create() self.checkImageParam(widget, 'selectimage') - @requires_tcl(8, 5) def test_configure_tristateimage(self): widget = self.create() self.checkImageParam(widget, 'tristateimage') - @requires_tcl(8, 5) def test_configure_tristatevalue(self): widget = self.create() self.checkParam(widget, 'tristatevalue', 'unknowable') @@ -538,4 +516,4 @@ def add_standard_options(*source_classes): def setUpModule(): if test.support.verbose: tcl = tkinter.Tcl() - print('patchlevel =', tcl.call('info', 'patchlevel')) + print('patchlevel =', tcl.call('info', 'patchlevel'), flush=True) diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py index ca2821de7c0..63c2501cfe2 100644 --- a/Lib/test/test_tokenize.py +++ b/Lib/test/test_tokenize.py @@ -3,12 +3,15 @@ from test.support import os_helper from tokenize import (tokenize, _tokenize, untokenize, NUMBER, NAME, OP, STRING, ENDMARKER, ENCODING, tok_name, detect_encoding, open as tokenize_open, Untokenizer, generate_tokens, - NEWLINE, _generate_tokens_from_c_tokenizer) + NEWLINE, _generate_tokens_from_c_tokenizer, DEDENT) from io import BytesIO, StringIO import unittest +from textwrap import dedent from unittest import TestCase, mock from test.test_grammar import (VALID_UNDERSCORE_LITERALS, INVALID_UNDERSCORE_LITERALS) +from test.support import os_helper +from test.support.script_helper import run_test_script, make_script import os import token @@ -44,7 +47,6 @@ class TokenizeTest(TestCase): # The ENDMARKER and final NEWLINE are omitted. f = BytesIO(s.encode('utf-8')) result = stringify_tokens_from_source(tokenize(f.readline), s) - self.assertEqual(result, [" ENCODING 'utf-8' (0, 0) (0, 0)"] + expected.rstrip().splitlines()) @@ -2512,6 +2514,138 @@ async def f(): self.assertRaises(SyntaxError, get_tokens, "("*1000+"a"+")"*1000) self.assertRaises(SyntaxError, get_tokens, "]") + def test_max_indent(self): + MAXINDENT = 100 + + def generate_source(indents): + source = ''.join((' ' * x) + 'if True:\n' for x in range(indents)) + source += ' ' * indents + 'pass\n' + return source + + valid = generate_source(MAXINDENT - 1) + tokens = list(_generate_tokens_from_c_tokenizer(valid)) + self.assertEqual(tokens[-1].type, DEDENT) + compile(valid, "", "exec") + + invalid = generate_source(MAXINDENT) + tokens = list(_generate_tokens_from_c_tokenizer(invalid)) + self.assertEqual(tokens[-1].type, NEWLINE) + self.assertRaises( + IndentationError, compile, invalid, "", "exec" + ) + + def test_continuation_lines_indentation(self): + def get_tokens(string): + return [(kind, string) for (kind, string, *_) in _generate_tokens_from_c_tokenizer(string)] + + code = dedent(""" + def fib(n): + \\ + '''Print a Fibonacci series up to n.''' + \\ + a, b = 0, 1 + """) + + self.check_tokenize(code, """\ + NAME 'def' (2, 0) (2, 3) + NAME 'fib' (2, 4) (2, 7) + LPAR '(' (2, 7) (2, 8) + NAME 'n' (2, 8) (2, 9) + RPAR ')' (2, 9) (2, 10) + COLON ':' (2, 10) (2, 11) + NEWLINE '' (2, 11) (2, 11) + INDENT '' (4, -1) (4, -1) + STRING "'''Print a Fibonacci series up to n.'''" (4, 0) (4, 39) + NEWLINE '' (4, 39) (4, 39) + NAME 'a' (6, 0) (6, 1) + COMMA ',' (6, 1) (6, 2) + NAME 'b' (6, 3) (6, 4) + EQUAL '=' (6, 5) (6, 6) + NUMBER '0' (6, 7) (6, 8) + COMMA ',' (6, 8) (6, 9) + NUMBER '1' (6, 10) (6, 11) + NEWLINE '' (6, 11) (6, 11) + DEDENT '' (6, -1) (6, -1) + """) + + code_no_cont = dedent(""" + def fib(n): + '''Print a Fibonacci series up to n.''' + a, b = 0, 1 + """) + + self.assertEqual(get_tokens(code), get_tokens(code_no_cont)) + + code = dedent(""" + pass + \\ + + pass + """) + + self.check_tokenize(code, """\ + NAME 'pass' (2, 0) (2, 4) + NEWLINE '' (2, 4) (2, 4) + NAME 'pass' (5, 0) (5, 4) + NEWLINE '' (5, 4) (5, 4) + """) + + code_no_cont = dedent(""" + pass + pass + """) + + self.assertEqual(get_tokens(code), get_tokens(code_no_cont)) + + code = dedent(""" + if x: + y = 1 + \\ + \\ + \\ + \\ + foo = 1 + """) + + self.check_tokenize(code, """\ + NAME 'if' (2, 0) (2, 2) + NAME 'x' (2, 3) (2, 4) + COLON ':' (2, 4) (2, 5) + NEWLINE '' (2, 5) (2, 5) + INDENT '' (3, -1) (3, -1) + NAME 'y' (3, 4) (3, 5) + EQUAL '=' (3, 6) (3, 7) + NUMBER '1' (3, 8) (3, 9) + NEWLINE '' (3, 9) (3, 9) + NAME 'foo' (8, 4) (8, 7) + EQUAL '=' (8, 8) (8, 9) + NUMBER '1' (8, 10) (8, 11) + NEWLINE '' (8, 11) (8, 11) + DEDENT '' (8, -1) (8, -1) + """) + + code_no_cont = dedent(""" + if x: + y = 1 + foo = 1 + """) + + self.assertEqual(get_tokens(code), get_tokens(code_no_cont)) + + +class CTokenizerBufferTests(unittest.TestCase): + def test_newline_at_the_end_of_buffer(self): + # See issue 99581: Make sure that if we need to add a new line at the + # end of the buffer, we have enough space in the buffer, specially when + # the current line is as long as the buffer space available. + test_script = f"""\ + #coding: latin-1 + #{"a"*10000} + #{"a"*10002}""" + with os_helper.temp_dir() as temp_dir: + file_name = make_script(temp_dir, 'foo', test_script) + run_test_script(file_name) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_tomllib/__init__.py b/Lib/test/test_tomllib/__init__.py new file mode 100644 index 00000000000..6204c6e47f0 --- /dev/null +++ b/Lib/test/test_tomllib/__init__.py @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +__all__ = ("tomllib",) + +# By changing this one line, we can run the tests against +# a different module name. +import tomllib + +import os +from test.support import load_package_tests + +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_tomllib/__main__.py b/Lib/test/test_tomllib/__main__.py new file mode 100644 index 00000000000..dd063653437 --- /dev/null +++ b/Lib/test/test_tomllib/__main__.py @@ -0,0 +1,6 @@ +import unittest + +from . import load_tests + + +unittest.main() diff --git a/Lib/test/test_tomllib/burntsushi.py b/Lib/test/test_tomllib/burntsushi.py new file mode 100644 index 00000000000..71228c65369 --- /dev/null +++ b/Lib/test/test_tomllib/burntsushi.py @@ -0,0 +1,120 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +"""Utilities for tests that are in the "burntsushi" format.""" + +import datetime +from typing import Any + +# Aliases for converting TOML compliance format [1] to BurntSushi format [2] +# [1] https://github.com/toml-lang/compliance/blob/db7c3211fda30ff9ddb10292f4aeda7e2e10abc4/docs/json-encoding.md # noqa: E501 +# [2] https://github.com/BurntSushi/toml-test/blob/4634fdf3a6ecd6aaea5f4cdcd98b2733c2694993/README.md # noqa: E501 +_aliases = { + "boolean": "bool", + "offset datetime": "datetime", + "local datetime": "datetime-local", + "local date": "date-local", + "local time": "time-local", +} + + +def convert(obj): # noqa: C901 + if isinstance(obj, str): + return {"type": "string", "value": obj} + elif isinstance(obj, bool): + return {"type": "bool", "value": str(obj).lower()} + elif isinstance(obj, int): + return {"type": "integer", "value": str(obj)} + elif isinstance(obj, float): + return {"type": "float", "value": _normalize_float_str(str(obj))} + elif isinstance(obj, datetime.datetime): + val = _normalize_datetime_str(obj.isoformat()) + if obj.tzinfo: + return {"type": "datetime", "value": val} + return {"type": "datetime-local", "value": val} + elif isinstance(obj, datetime.time): + return { + "type": "time-local", + "value": _normalize_localtime_str(str(obj)), + } + elif isinstance(obj, datetime.date): + return { + "type": "date-local", + "value": str(obj), + } + elif isinstance(obj, list): + return [convert(i) for i in obj] + elif isinstance(obj, dict): + return {k: convert(v) for k, v in obj.items()} + raise Exception("unsupported type") + + +def normalize(obj: Any) -> Any: + """Normalize test objects. + + This normalizes primitive values (e.g. floats), and also converts from + TOML compliance format [1] to BurntSushi format [2]. + + [1] https://github.com/toml-lang/compliance/blob/db7c3211fda30ff9ddb10292f4aeda7e2e10abc4/docs/json-encoding.md # noqa: E501 + [2] https://github.com/BurntSushi/toml-test/blob/4634fdf3a6ecd6aaea5f4cdcd98b2733c2694993/README.md # noqa: E501 + """ + if isinstance(obj, list): + return [normalize(item) for item in obj] + if isinstance(obj, dict): + if "type" in obj and "value" in obj: + type_ = obj["type"] + norm_type = _aliases.get(type_, type_) + value = obj["value"] + if norm_type == "float": + norm_value = _normalize_float_str(value) + elif norm_type in {"datetime", "datetime-local"}: + norm_value = _normalize_datetime_str(value) + elif norm_type == "time-local": + norm_value = _normalize_localtime_str(value) + else: + norm_value = value + + if norm_type == "array": + return [normalize(item) for item in value] + return {"type": norm_type, "value": norm_value} + return {k: normalize(v) for k, v in obj.items()} + raise AssertionError("Burntsushi fixtures should be dicts/lists only") + + +def _normalize_datetime_str(dt_str: str) -> str: + if dt_str[-1].lower() == "z": + dt_str = dt_str[:-1] + "+00:00" + + date = dt_str[:10] + rest = dt_str[11:] + + if "+" in rest: + sign = "+" + elif "-" in rest: + sign = "-" + else: + sign = "" + + if sign: + time, _, offset = rest.partition(sign) + else: + time = rest + offset = "" + + time = time.rstrip("0") if "." in time else time + return date + "T" + time + sign + offset + + +def _normalize_localtime_str(lt_str: str) -> str: + return lt_str.rstrip("0") if "." in lt_str else lt_str + + +def _normalize_float_str(float_str: str) -> str: + as_float = float(float_str) + + # Normalize "-0.0" and "+0.0" + if as_float == 0: + return "0" + + return str(as_float) diff --git a/Lib/test/test_tomllib/data/invalid/array-missing-comma.toml b/Lib/test/test_tomllib/data/invalid/array-missing-comma.toml new file mode 100644 index 00000000000..9431d907995 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/array-missing-comma.toml @@ -0,0 +1 @@ +arrr = [true false] diff --git a/Lib/test/test_tomllib/data/invalid/array-of-tables/overwrite-array-in-parent.toml b/Lib/test/test_tomllib/data/invalid/array-of-tables/overwrite-array-in-parent.toml new file mode 100644 index 00000000000..f867c28deeb --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/array-of-tables/overwrite-array-in-parent.toml @@ -0,0 +1,4 @@ +[[parent-table.arr]] +[parent-table] +not-arr = 1 +arr = 2 diff --git a/Lib/test/test_tomllib/data/invalid/array-of-tables/overwrite-bool-with-aot.toml b/Lib/test/test_tomllib/data/invalid/array-of-tables/overwrite-bool-with-aot.toml new file mode 100644 index 00000000000..b1892d6a449 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/array-of-tables/overwrite-bool-with-aot.toml @@ -0,0 +1,2 @@ +a=true +[[a]] \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/array/file-end-after-val.toml b/Lib/test/test_tomllib/data/invalid/array/file-end-after-val.toml new file mode 100644 index 00000000000..00196bb03ea --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/array/file-end-after-val.toml @@ -0,0 +1 @@ +a=[1 \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/array/unclosed-after-item.toml b/Lib/test/test_tomllib/data/invalid/array/unclosed-after-item.toml new file mode 100644 index 00000000000..9edec37078f --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/array/unclosed-after-item.toml @@ -0,0 +1 @@ +v=[1, \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/array/unclosed-empty.toml b/Lib/test/test_tomllib/data/invalid/array/unclosed-empty.toml new file mode 100644 index 00000000000..1fd099d3683 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/array/unclosed-empty.toml @@ -0,0 +1 @@ +v=[ \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/basic-str-ends-in-escape.toml b/Lib/test/test_tomllib/data/invalid/basic-str-ends-in-escape.toml new file mode 100644 index 00000000000..713ea544f82 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/basic-str-ends-in-escape.toml @@ -0,0 +1 @@ +"backslash is the last char\ \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/boolean/invalid-false-casing.toml b/Lib/test/test_tomllib/data/invalid/boolean/invalid-false-casing.toml new file mode 100644 index 00000000000..336d2d808e7 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/boolean/invalid-false-casing.toml @@ -0,0 +1 @@ +val=falsE \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/boolean/invalid-true-casing.toml b/Lib/test/test_tomllib/data/invalid/boolean/invalid-true-casing.toml new file mode 100644 index 00000000000..0370d6cdb67 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/boolean/invalid-true-casing.toml @@ -0,0 +1 @@ +val=trUe \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/dates-and-times/invalid-day.toml b/Lib/test/test_tomllib/data/invalid/dates-and-times/invalid-day.toml new file mode 100644 index 00000000000..c69f0914451 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/dates-and-times/invalid-day.toml @@ -0,0 +1 @@ +"only 28 or 29 days in february" = 1988-02-30 diff --git a/Lib/test/test_tomllib/data/invalid/dotted-keys/access-non-table.toml b/Lib/test/test_tomllib/data/invalid/dotted-keys/access-non-table.toml new file mode 100644 index 00000000000..ada02005a3e --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/dotted-keys/access-non-table.toml @@ -0,0 +1,2 @@ +a = false +a.b = true \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-aot.toml b/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-aot.toml new file mode 100644 index 00000000000..1c3c34b8571 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-aot.toml @@ -0,0 +1,3 @@ +[[tab.arr]] +[tab] +arr.val1=1 diff --git a/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-table-with-subtable.toml b/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-table-with-subtable.toml new file mode 100644 index 00000000000..70e2ac5be89 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-table-with-subtable.toml @@ -0,0 +1,4 @@ +[a.b.c.d] + z = 9 +[a] + b.c.d.k.t = 8 diff --git a/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-table.toml b/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-table.toml new file mode 100644 index 00000000000..c88c179d3c1 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-table.toml @@ -0,0 +1,4 @@ +[a.b.c] + z = 9 +[a] + b.c.t = 9 diff --git a/Lib/test/test_tomllib/data/invalid/inline-table-missing-comma.toml b/Lib/test/test_tomllib/data/invalid/inline-table-missing-comma.toml new file mode 100644 index 00000000000..d98b41dd037 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table-missing-comma.toml @@ -0,0 +1 @@ +arrr = { comma-missing = true valid-toml = false } diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/define-twice-in-subtable.toml b/Lib/test/test_tomllib/data/invalid/inline-table/define-twice-in-subtable.toml new file mode 100644 index 00000000000..706834135d1 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/define-twice-in-subtable.toml @@ -0,0 +1 @@ +table1 = { table2.dupe = 1, table2.dupe = 2 } \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/define-twice.toml b/Lib/test/test_tomllib/data/invalid/inline-table/define-twice.toml new file mode 100644 index 00000000000..8202b98ff2d --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/define-twice.toml @@ -0,0 +1 @@ +table = { dupe = 1, dupe = 2 } \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/file-end-after-key-val.toml b/Lib/test/test_tomllib/data/invalid/inline-table/file-end-after-key-val.toml new file mode 100644 index 00000000000..52d4e779704 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/file-end-after-key-val.toml @@ -0,0 +1 @@ +a={b=1 \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/mutate.toml b/Lib/test/test_tomllib/data/invalid/inline-table/mutate.toml new file mode 100644 index 00000000000..4e5e9ff1569 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/mutate.toml @@ -0,0 +1,2 @@ +a = { b = 1 } +a.b = 2 \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/override-val-in-table.toml b/Lib/test/test_tomllib/data/invalid/inline-table/override-val-in-table.toml new file mode 100644 index 00000000000..6e87cfa456d --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/override-val-in-table.toml @@ -0,0 +1,5 @@ +[tab.nested] +inline-t = { nest = {} } + +[tab] +nested.inline-t.nest = 2 diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/override-val-with-array.toml b/Lib/test/test_tomllib/data/invalid/inline-table/override-val-with-array.toml new file mode 100644 index 00000000000..79b4f325874 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/override-val-with-array.toml @@ -0,0 +1,3 @@ +inline-t = { nest = {} } + +[[inline-t.nest]] diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/override-val-with-table.toml b/Lib/test/test_tomllib/data/invalid/inline-table/override-val-with-table.toml new file mode 100644 index 00000000000..d0cd6b641ac --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/override-val-with-table.toml @@ -0,0 +1,3 @@ +inline-t = { nest = {} } + +[inline-t.nest] diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-implicitly.toml b/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-implicitly.toml new file mode 100644 index 00000000000..462c28f1684 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-implicitly.toml @@ -0,0 +1 @@ +a = { b = 1, b.c = 2 } diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-value-in-inner-array.toml b/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-value-in-inner-array.toml new file mode 100644 index 00000000000..34ddb85eeec --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-value-in-inner-array.toml @@ -0,0 +1 @@ +tab = { inner.table = [{}], inner.table.val = "bad" } \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-value-in-inner-table.toml b/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-value-in-inner-table.toml new file mode 100644 index 00000000000..750853f0d96 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-value-in-inner-table.toml @@ -0,0 +1 @@ +tab = { inner = { dog = "best" }, inner.cat = "worst" } \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/unclosed-empty.toml b/Lib/test/test_tomllib/data/invalid/inline-table/unclosed-empty.toml new file mode 100644 index 00000000000..032edb7266c --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/unclosed-empty.toml @@ -0,0 +1 @@ +a={ \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/invalid-comment-char.toml b/Lib/test/test_tomllib/data/invalid/invalid-comment-char.toml new file mode 100644 index 00000000000..dc5ae336c6a --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/invalid-comment-char.toml @@ -0,0 +1 @@ +# form feed ( ) not allowed in comments \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/invalid-escaped-unicode.toml b/Lib/test/test_tomllib/data/invalid/invalid-escaped-unicode.toml new file mode 100644 index 00000000000..8feba3a30a4 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/invalid-escaped-unicode.toml @@ -0,0 +1 @@ +escaped-unicode = "\uabag" diff --git a/Lib/test/test_tomllib/data/invalid/invalid-hex.toml b/Lib/test/test_tomllib/data/invalid/invalid-hex.toml new file mode 100644 index 00000000000..5c55fe80c45 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/invalid-hex.toml @@ -0,0 +1 @@ +hex = 0xgabba00f1 diff --git a/Lib/test/test_tomllib/data/invalid/keys-and-vals/ends-early-table-def.toml b/Lib/test/test_tomllib/data/invalid/keys-and-vals/ends-early-table-def.toml new file mode 100644 index 00000000000..75d43a37eda --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/keys-and-vals/ends-early-table-def.toml @@ -0,0 +1 @@ +[fwfw.wafw \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/keys-and-vals/ends-early.toml b/Lib/test/test_tomllib/data/invalid/keys-and-vals/ends-early.toml new file mode 100644 index 00000000000..e70e265ae20 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/keys-and-vals/ends-early.toml @@ -0,0 +1 @@ +fs.fw \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/keys-and-vals/no-value.toml b/Lib/test/test_tomllib/data/invalid/keys-and-vals/no-value.toml new file mode 100644 index 00000000000..4f9ab16c613 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/keys-and-vals/no-value.toml @@ -0,0 +1 @@ +why-no-value= \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/keys-and-vals/only-ws-after-dot.toml b/Lib/test/test_tomllib/data/invalid/keys-and-vals/only-ws-after-dot.toml new file mode 100644 index 00000000000..abe52587c9e --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/keys-and-vals/only-ws-after-dot.toml @@ -0,0 +1 @@ +fs. \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/keys-and-vals/overwrite-with-deep-table.toml b/Lib/test/test_tomllib/data/invalid/keys-and-vals/overwrite-with-deep-table.toml new file mode 100644 index 00000000000..103d928bcf7 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/keys-and-vals/overwrite-with-deep-table.toml @@ -0,0 +1,2 @@ +a=1 +[a.b.c.d] diff --git a/Lib/test/test_tomllib/data/invalid/literal-str/unclosed.toml b/Lib/test/test_tomllib/data/invalid/literal-str/unclosed.toml new file mode 100644 index 00000000000..b1612aa1f6d --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/literal-str/unclosed.toml @@ -0,0 +1 @@ +unclosed='dwdd \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/missing-closing-double-square-bracket.toml b/Lib/test/test_tomllib/data/invalid/missing-closing-double-square-bracket.toml new file mode 100644 index 00000000000..ae1d0d9cf9a --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/missing-closing-double-square-bracket.toml @@ -0,0 +1,2 @@ +[[closing-bracket.missing] +blaa=2 diff --git a/Lib/test/test_tomllib/data/invalid/missing-closing-square-bracket.toml b/Lib/test/test_tomllib/data/invalid/missing-closing-square-bracket.toml new file mode 100644 index 00000000000..354d0167fcd --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/missing-closing-square-bracket.toml @@ -0,0 +1,2 @@ +[closing-bracket.missingö +blaa=2 diff --git a/Lib/test/test_tomllib/data/invalid/multiline-basic-str/carriage-return.toml b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/carriage-return.toml new file mode 100644 index 00000000000..4c455cfe0e0 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/carriage-return.toml @@ -0,0 +1,2 @@ +s="""cr is not an allowed line ending but we just tried to use it +""" \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/multiline-basic-str/escape-only.toml b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/escape-only.toml new file mode 100644 index 00000000000..f3bd9fca231 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/escape-only.toml @@ -0,0 +1 @@ +bee = """\""" diff --git a/Lib/test/test_tomllib/data/invalid/multiline-basic-str/file-ends-after-opening.toml b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/file-ends-after-opening.toml new file mode 100644 index 00000000000..1c2a5644440 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/file-ends-after-opening.toml @@ -0,0 +1 @@ +a=""" \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/multiline-basic-str/last-line-escape.toml b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/last-line-escape.toml new file mode 100644 index 00000000000..92b22b06566 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/last-line-escape.toml @@ -0,0 +1,4 @@ +bee = """ +hee \ + +gee \ """ diff --git a/Lib/test/test_tomllib/data/invalid/multiline-basic-str/unclosed-ends-in-whitespace-escape.toml b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/unclosed-ends-in-whitespace-escape.toml new file mode 100644 index 00000000000..3ba7febbd0c --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/unclosed-ends-in-whitespace-escape.toml @@ -0,0 +1,3 @@ +bee = """ +hee +gee\ \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/multiline-literal-str/file-ends-after-opening.toml b/Lib/test/test_tomllib/data/invalid/multiline-literal-str/file-ends-after-opening.toml new file mode 100644 index 00000000000..9a3924a103f --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/multiline-literal-str/file-ends-after-opening.toml @@ -0,0 +1 @@ +a=''' \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/multiline-literal-str/unclosed.toml b/Lib/test/test_tomllib/data/invalid/multiline-literal-str/unclosed.toml new file mode 100644 index 00000000000..decd3789913 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/multiline-literal-str/unclosed.toml @@ -0,0 +1,3 @@ +bee = ''' +hee +gee '' \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/non-scalar-escaped.toml b/Lib/test/test_tomllib/data/invalid/non-scalar-escaped.toml new file mode 100644 index 00000000000..c787f9ad354 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/non-scalar-escaped.toml @@ -0,0 +1 @@ +a="\ud800" \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/table/eof-after-opening.toml b/Lib/test/test_tomllib/data/invalid/table/eof-after-opening.toml new file mode 100644 index 00000000000..8e2f0bef135 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/table/eof-after-opening.toml @@ -0,0 +1 @@ +[ \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/table/redefine-1.toml b/Lib/test/test_tomllib/data/invalid/table/redefine-1.toml new file mode 100644 index 00000000000..d2c66eb38c7 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/table/redefine-1.toml @@ -0,0 +1,3 @@ +[t1] +t2.t3.v = 0 +[t1.t2] diff --git a/Lib/test/test_tomllib/data/invalid/table/redefine-2.toml b/Lib/test/test_tomllib/data/invalid/table/redefine-2.toml new file mode 100644 index 00000000000..918017f892a --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/table/redefine-2.toml @@ -0,0 +1,3 @@ +[t1] +t2.t3.v = 0 +[t1.t2.t3] diff --git a/Lib/test/test_tomllib/data/invalid/unclosed-multiline-string.toml b/Lib/test/test_tomllib/data/invalid/unclosed-multiline-string.toml new file mode 100644 index 00000000000..401adec2a33 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/unclosed-multiline-string.toml @@ -0,0 +1,4 @@ +not-closed= """ +diibaa +blibae ete +eteta diff --git a/Lib/test/test_tomllib/data/invalid/unclosed-string.toml b/Lib/test/test_tomllib/data/invalid/unclosed-string.toml new file mode 100644 index 00000000000..89f75acf771 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/unclosed-string.toml @@ -0,0 +1 @@ +"a-string".must-be = "closed \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/valid/apostrophes-in-literal-string.json b/Lib/test/test_tomllib/data/valid/apostrophes-in-literal-string.json new file mode 100644 index 00000000000..fddafe7769c --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/apostrophes-in-literal-string.json @@ -0,0 +1 @@ +{"this-str-has-apostrophes": {"type": "string", "value": "' there's one already\n'' two more\n''"}} diff --git a/Lib/test/test_tomllib/data/valid/apostrophes-in-literal-string.toml b/Lib/test/test_tomllib/data/valid/apostrophes-in-literal-string.toml new file mode 100644 index 00000000000..4288d080ca3 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/apostrophes-in-literal-string.toml @@ -0,0 +1,3 @@ +this-str-has-apostrophes='''' there's one already +'' two more +''''' diff --git a/Lib/test/test_tomllib/data/valid/array/array-subtables.json b/Lib/test/test_tomllib/data/valid/array/array-subtables.json new file mode 100644 index 00000000000..69ad37e9834 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/array/array-subtables.json @@ -0,0 +1,11 @@ +{"arr": + {"type":"array","value": + [ + {"subtab": + {"val": {"type":"integer","value":"1"} + } + }, + {"subtab": {"val": {"type":"integer","value":"2"}}} + ] + } +} diff --git a/Lib/test/test_tomllib/data/valid/array/array-subtables.toml b/Lib/test/test_tomllib/data/valid/array/array-subtables.toml new file mode 100644 index 00000000000..70753078411 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/array/array-subtables.toml @@ -0,0 +1,7 @@ +[[arr]] +[arr.subtab] +val=1 + +[[arr]] +[arr.subtab] +val=2 diff --git a/Lib/test/test_tomllib/data/valid/array/open-parent-table.json b/Lib/test/test_tomllib/data/valid/array/open-parent-table.json new file mode 100644 index 00000000000..7dba1b69d6a --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/array/open-parent-table.json @@ -0,0 +1,6 @@ +{ + "parent-table": { + "arr": {"type":"array","value":[{},{}]}, + "not-arr": {"type":"integer","value":"1"} + } +} diff --git a/Lib/test/test_tomllib/data/valid/array/open-parent-table.toml b/Lib/test/test_tomllib/data/valid/array/open-parent-table.toml new file mode 100644 index 00000000000..8eaad12fe3a --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/array/open-parent-table.toml @@ -0,0 +1,4 @@ +[[parent-table.arr]] +[[parent-table.arr]] +[parent-table] +not-arr = 1 diff --git a/Lib/test/test_tomllib/data/valid/boolean.json b/Lib/test/test_tomllib/data/valid/boolean.json new file mode 100644 index 00000000000..2540d252776 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/boolean.json @@ -0,0 +1,4 @@ +{ + "a": {"type":"bool","value":"true"}, + "b": {"type":"bool","value":"false"} +} diff --git a/Lib/test/test_tomllib/data/valid/boolean.toml b/Lib/test/test_tomllib/data/valid/boolean.toml new file mode 100644 index 00000000000..e5aaba35ea8 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/boolean.toml @@ -0,0 +1,2 @@ +'a'=true +"b"=false \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/valid/dates-and-times/datetimes.json b/Lib/test/test_tomllib/data/valid/dates-and-times/datetimes.json new file mode 100644 index 00000000000..99aca873480 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/dates-and-times/datetimes.json @@ -0,0 +1,4 @@ +{ + "local-dt": {"type":"datetime-local","value":"1988-10-27t01:01:01"}, + "zulu-dt": {"type":"datetime","value":"1988-10-27t01:01:01z"} +} diff --git a/Lib/test/test_tomllib/data/valid/dates-and-times/datetimes.toml b/Lib/test/test_tomllib/data/valid/dates-and-times/datetimes.toml new file mode 100644 index 00000000000..cf84159de46 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/dates-and-times/datetimes.toml @@ -0,0 +1,2 @@ +local-dt=1988-10-27t01:01:01 +zulu-dt=1988-10-27t01:01:01z diff --git a/Lib/test/test_tomllib/data/valid/dates-and-times/localtime.json b/Lib/test/test_tomllib/data/valid/dates-and-times/localtime.json new file mode 100644 index 00000000000..4d96abcbc79 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/dates-and-times/localtime.json @@ -0,0 +1,2 @@ +{"t": + {"type":"time-local","value":"00:00:00.999999"}} diff --git a/Lib/test/test_tomllib/data/valid/dates-and-times/localtime.toml b/Lib/test/test_tomllib/data/valid/dates-and-times/localtime.toml new file mode 100644 index 00000000000..87547c1cf3b --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/dates-and-times/localtime.toml @@ -0,0 +1 @@ +t=00:00:00.99999999999999 \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/valid/empty-inline-table.json b/Lib/test/test_tomllib/data/valid/empty-inline-table.json new file mode 100644 index 00000000000..2655cfd3ab0 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/empty-inline-table.json @@ -0,0 +1 @@ +{"empty": {}} \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/valid/empty-inline-table.toml b/Lib/test/test_tomllib/data/valid/empty-inline-table.toml new file mode 100644 index 00000000000..d2d15ab9e08 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/empty-inline-table.toml @@ -0,0 +1 @@ +empty ={ }#nothing here diff --git a/Lib/test/test_tomllib/data/valid/five-quotes.json b/Lib/test/test_tomllib/data/valid/five-quotes.json new file mode 100644 index 00000000000..5cc527408ec --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/five-quotes.json @@ -0,0 +1,4 @@ +{ + "five-quotes": {"type":"string","value":"Closing with five quotes\n\"\""}, + "four-quotes": {"type":"string","value":"Closing with four quotes\n\""} +} diff --git a/Lib/test/test_tomllib/data/valid/five-quotes.toml b/Lib/test/test_tomllib/data/valid/five-quotes.toml new file mode 100644 index 00000000000..ccc98c07416 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/five-quotes.toml @@ -0,0 +1,6 @@ +five-quotes = """ +Closing with five quotes +""""" +four-quotes = """ +Closing with four quotes +"""" diff --git a/Lib/test/test_tomllib/data/valid/hex-char.json b/Lib/test/test_tomllib/data/valid/hex-char.json new file mode 100644 index 00000000000..e632e202fad --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/hex-char.json @@ -0,0 +1,5 @@ +{ + "a": {"type":"string","value":"a"}, + "b": {"type":"string","value":"b"}, + "c": {"type":"string","value":"c"} +} diff --git a/Lib/test/test_tomllib/data/valid/hex-char.toml b/Lib/test/test_tomllib/data/valid/hex-char.toml new file mode 100644 index 00000000000..1d9cdf6a437 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/hex-char.toml @@ -0,0 +1,3 @@ +a="\u0061" +b="\u0062" +c="\U00000063" \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/valid/multiline-basic-str/ends-in-whitespace-escape.json b/Lib/test/test_tomllib/data/valid/multiline-basic-str/ends-in-whitespace-escape.json new file mode 100644 index 00000000000..fc54a7c2a3c --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/multiline-basic-str/ends-in-whitespace-escape.json @@ -0,0 +1 @@ +{"beee": {"type": "string", "value": "heeee\ngeeee"}} diff --git a/Lib/test/test_tomllib/data/valid/multiline-basic-str/ends-in-whitespace-escape.toml b/Lib/test/test_tomllib/data/valid/multiline-basic-str/ends-in-whitespace-escape.toml new file mode 100644 index 00000000000..4dffe55fcb5 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/multiline-basic-str/ends-in-whitespace-escape.toml @@ -0,0 +1,6 @@ +beee = """ +heeee +geeee\ + + + """ diff --git a/Lib/test/test_tomllib/data/valid/no-newlines.json b/Lib/test/test_tomllib/data/valid/no-newlines.json new file mode 100644 index 00000000000..0967ef424bc --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/no-newlines.json @@ -0,0 +1 @@ +{} diff --git a/Lib/test/test_tomllib/data/valid/no-newlines.toml b/Lib/test/test_tomllib/data/valid/no-newlines.toml new file mode 100644 index 00000000000..4b87f4c77c9 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/no-newlines.toml @@ -0,0 +1 @@ +#no newlines at all here \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/valid/trailing-comma.json b/Lib/test/test_tomllib/data/valid/trailing-comma.json new file mode 100644 index 00000000000..dc6f1665d1f --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/trailing-comma.json @@ -0,0 +1,7 @@ +{"arr": + {"type":"array","value": + [ + {"type":"integer","value":"1"} + ] + } +} diff --git a/Lib/test/test_tomllib/data/valid/trailing-comma.toml b/Lib/test/test_tomllib/data/valid/trailing-comma.toml new file mode 100644 index 00000000000..c5d5b9b4122 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/trailing-comma.toml @@ -0,0 +1 @@ +arr=[1,] \ No newline at end of file diff --git a/Lib/test/test_tomllib/test_data.py b/Lib/test/test_tomllib/test_data.py new file mode 100644 index 00000000000..3483d93022b --- /dev/null +++ b/Lib/test/test_tomllib/test_data.py @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +import json +from pathlib import Path +import unittest + +from . import burntsushi, tomllib + + +class MissingFile: + def __init__(self, path: Path): + self.path = path + + +DATA_DIR = Path(__file__).parent / "data" + +VALID_FILES = tuple((DATA_DIR / "valid").glob("**/*.toml")) +assert VALID_FILES, "Valid TOML test files not found" + +_expected_files = [] +for p in VALID_FILES: + json_path = p.with_suffix(".json") + try: + text = json.loads(json_path.read_bytes().decode()) + except FileNotFoundError: + text = MissingFile(json_path) + _expected_files.append(text) +VALID_FILES_EXPECTED = tuple(_expected_files) + +INVALID_FILES = tuple((DATA_DIR / "invalid").glob("**/*.toml")) +assert INVALID_FILES, "Invalid TOML test files not found" + + +class TestData(unittest.TestCase): + def test_invalid(self): + for invalid in INVALID_FILES: + with self.subTest(msg=invalid.stem): + toml_bytes = invalid.read_bytes() + try: + toml_str = toml_bytes.decode() + except UnicodeDecodeError: + # Some BurntSushi tests are not valid UTF-8. Skip those. + continue + with self.assertRaises(tomllib.TOMLDecodeError): + tomllib.loads(toml_str) + + def test_valid(self): + for valid, expected in zip(VALID_FILES, VALID_FILES_EXPECTED): + with self.subTest(msg=valid.stem): + if isinstance(expected, MissingFile): + # For a poor man's xfail, assert that this is one of the + # test cases where expected data is known to be missing. + assert valid.stem in { + "qa-array-inline-nested-1000", + "qa-table-inline-nested-1000", + } + continue + toml_str = valid.read_bytes().decode() + actual = tomllib.loads(toml_str) + actual = burntsushi.convert(actual) + expected = burntsushi.normalize(expected) + self.assertEqual(actual, expected) diff --git a/Lib/test/test_tomllib/test_error.py b/Lib/test/test_tomllib/test_error.py new file mode 100644 index 00000000000..72446267f04 --- /dev/null +++ b/Lib/test/test_tomllib/test_error.py @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +import unittest + +from . import tomllib + + +class TestError(unittest.TestCase): + def test_line_and_col(self): + with self.assertRaises(tomllib.TOMLDecodeError) as exc_info: + tomllib.loads("val=.") + self.assertEqual(str(exc_info.exception), "Invalid value (at line 1, column 5)") + + with self.assertRaises(tomllib.TOMLDecodeError) as exc_info: + tomllib.loads(".") + self.assertEqual( + str(exc_info.exception), "Invalid statement (at line 1, column 1)" + ) + + with self.assertRaises(tomllib.TOMLDecodeError) as exc_info: + tomllib.loads("\n\nval=.") + self.assertEqual(str(exc_info.exception), "Invalid value (at line 3, column 5)") + + with self.assertRaises(tomllib.TOMLDecodeError) as exc_info: + tomllib.loads("\n\n.") + self.assertEqual( + str(exc_info.exception), "Invalid statement (at line 3, column 1)" + ) + + def test_missing_value(self): + with self.assertRaises(tomllib.TOMLDecodeError) as exc_info: + tomllib.loads("\n\nfwfw=") + self.assertEqual(str(exc_info.exception), "Invalid value (at end of document)") + + def test_invalid_char_quotes(self): + with self.assertRaises(tomllib.TOMLDecodeError) as exc_info: + tomllib.loads("v = '\n'") + self.assertTrue(" '\\n' " in str(exc_info.exception)) + + def test_module_name(self): + self.assertEqual(tomllib.TOMLDecodeError().__module__, tomllib.__name__) + + def test_invalid_parse_float(self): + def dict_returner(s: str) -> dict: + return {} + + def list_returner(s: str) -> list: + return [] + + for invalid_parse_float in (dict_returner, list_returner): + with self.assertRaises(ValueError) as exc_info: + tomllib.loads("f=0.1", parse_float=invalid_parse_float) + self.assertEqual( + str(exc_info.exception), "parse_float must not return dicts or lists" + ) diff --git a/Lib/test/test_tomllib/test_misc.py b/Lib/test/test_tomllib/test_misc.py new file mode 100644 index 00000000000..a477a219fd9 --- /dev/null +++ b/Lib/test/test_tomllib/test_misc.py @@ -0,0 +1,104 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +import copy +import datetime +from decimal import Decimal as D +from pathlib import Path +import sys +import tempfile +import unittest + +from . import tomllib + + +class TestMiscellaneous(unittest.TestCase): + def test_load(self): + content = "one=1 \n two='two' \n arr=[]" + expected = {"one": 1, "two": "two", "arr": []} + with tempfile.TemporaryDirectory() as tmp_dir_path: + file_path = Path(tmp_dir_path) / "test.toml" + file_path.write_text(content) + + with open(file_path, "rb") as bin_f: + actual = tomllib.load(bin_f) + self.assertEqual(actual, expected) + + def test_incorrect_load(self): + content = "one=1" + with tempfile.TemporaryDirectory() as tmp_dir_path: + file_path = Path(tmp_dir_path) / "test.toml" + file_path.write_text(content) + + with open(file_path, "r") as txt_f: + with self.assertRaises(TypeError): + tomllib.load(txt_f) # type: ignore[arg-type] + + def test_parse_float(self): + doc = """ + val=0.1 + biggest1=inf + biggest2=+inf + smallest=-inf + notnum1=nan + notnum2=-nan + notnum3=+nan + """ + obj = tomllib.loads(doc, parse_float=D) + expected = { + "val": D("0.1"), + "biggest1": D("inf"), + "biggest2": D("inf"), + "smallest": D("-inf"), + "notnum1": D("nan"), + "notnum2": D("-nan"), + "notnum3": D("nan"), + } + for k, expected_val in expected.items(): + actual_val = obj[k] + self.assertIsInstance(actual_val, D) + if actual_val.is_nan(): + self.assertTrue(expected_val.is_nan()) + else: + self.assertEqual(actual_val, expected_val) + + def test_deepcopy(self): + doc = """ + [bliibaa.diibaa] + offsettime=[1979-05-27T00:32:00.999999-07:00] + """ + obj = tomllib.loads(doc) + obj_copy = copy.deepcopy(obj) + self.assertEqual(obj_copy, obj) + expected_obj = { + "bliibaa": { + "diibaa": { + "offsettime": [ + datetime.datetime( + 1979, + 5, + 27, + 0, + 32, + 0, + 999999, + tzinfo=datetime.timezone(datetime.timedelta(hours=-7)), + ) + ] + } + } + } + self.assertEqual(obj_copy, expected_obj) + + def test_inline_array_recursion_limit(self): + # 465 with default recursion limit + nest_count = int(sys.getrecursionlimit() * 0.465) + recursive_array_toml = "arr = " + nest_count * "[" + nest_count * "]" + tomllib.loads(recursive_array_toml) + + def test_inline_table_recursion_limit(self): + # 310 with default recursion limit + nest_count = int(sys.getrecursionlimit() * 0.31) + recursive_table_toml = nest_count * "key = {" + nest_count * "}" + tomllib.loads(recursive_table_toml) diff --git a/Lib/test/test_tools/__init__.py b/Lib/test/test_tools/__init__.py index 61af6578e09..2102b9fceff 100644 --- a/Lib/test/test_tools/__init__.py +++ b/Lib/test/test_tools/__init__.py @@ -6,6 +6,17 @@ import unittest from test import support from test.support import import_helper + +if support.check_sanitizer(address=True, memory=True): + # bpo-46633: Skip the test because it is too slow when Python is built + # with ASAN/MSAN: between 5 and 20 minutes on GitHub Actions. + raise unittest.SkipTest("test too slow on ASAN/MSAN build") + + +if not support.has_subprocess_support: + raise unittest.SkipTest("test module requires subprocess") + + basepath = os.path.normpath( os.path.dirname( # os.path.dirname( # Lib diff --git a/Lib/test/test_tools/test_fixcid.py b/Lib/test/test_tools/test_fixcid.py deleted file mode 100644 index a72f74b8b15..00000000000 --- a/Lib/test/test_tools/test_fixcid.py +++ /dev/null @@ -1,94 +0,0 @@ -'''Test Tools/scripts/fixcid.py.''' - -from io import StringIO -import os, os.path -import runpy -import sys -from test import support -from test.support import os_helper -from test.test_tools import skip_if_missing, scriptsdir -import unittest - -skip_if_missing() - -class Test(unittest.TestCase): - def test_parse_strings(self): - old1 = 'int xx = "xx\\"xx"[xx];\n' - old2 = "int xx = 'x\\'xx' + xx;\n" - output = self.run_script(old1 + old2) - new1 = 'int yy = "xx\\"xx"[yy];\n' - new2 = "int yy = 'x\\'xx' + yy;\n" - self.assertMultiLineEqual(output, - "1\n" - "< {old1}" - "> {new1}" - "{new1}" - "2\n" - "< {old2}" - "> {new2}" - "{new2}".format(old1=old1, old2=old2, new1=new1, new2=new2) - ) - - def test_alter_comments(self): - output = self.run_script( - substfile= - "xx yy\n" - "*aa bb\n", - args=("-c", "-",), - input= - "/* xx altered */\n" - "int xx;\n" - "/* aa unaltered */\n" - "int aa;\n", - ) - self.assertMultiLineEqual(output, - "1\n" - "< /* xx altered */\n" - "> /* yy altered */\n" - "/* yy altered */\n" - "2\n" - "< int xx;\n" - "> int yy;\n" - "int yy;\n" - "/* aa unaltered */\n" - "4\n" - "< int aa;\n" - "> int bb;\n" - "int bb;\n" - ) - - def test_directory(self): - os.mkdir(os_helper.TESTFN) - self.addCleanup(os_helper.rmtree, os_helper.TESTFN) - c_filename = os.path.join(os_helper.TESTFN, "file.c") - with open(c_filename, "w", encoding="utf-8") as file: - file.write("int xx;\n") - with open(os.path.join(os_helper.TESTFN, "file.py"), "w", - encoding="utf-8") as file: - file.write("xx = 'unaltered'\n") - script = os.path.join(scriptsdir, "fixcid.py") - output = self.run_script(args=(os_helper.TESTFN,)) - self.assertMultiLineEqual(output, - "{}:\n" - "1\n" - '< int xx;\n' - '> int yy;\n'.format(c_filename) - ) - - def run_script(self, input="", *, args=("-",), substfile="xx yy\n"): - substfilename = os_helper.TESTFN + ".subst" - with open(substfilename, "w", encoding="utf-8") as file: - file.write(substfile) - self.addCleanup(os_helper.unlink, substfilename) - - argv = ["fixcid.py", "-s", substfilename] + list(args) - script = os.path.join(scriptsdir, "fixcid.py") - with support.swap_attr(sys, "argv", argv), \ - support.swap_attr(sys, "stdin", StringIO(input)), \ - support.captured_stdout() as output, \ - support.captured_stderr(): - try: - runpy.run_path(script, run_name="__main__") - except SystemExit as exit: - self.assertEqual(exit.code, 0) - return output.getvalue() diff --git a/Lib/test/test_tools/test_freeze.py b/Lib/test/test_tools/test_freeze.py index 392a776f042..2ba36ca208f 100644 --- a/Lib/test/test_tools/test_freeze.py +++ b/Lib/test/test_tools/test_freeze.py @@ -5,13 +5,14 @@ import textwrap import unittest from test import support +from test.support import os_helper +from test.test_tools import imports_under_tool, skip_if_missing -from . import imports_under_tool, skip_if_missing skip_if_missing('freeze') with imports_under_tool('freeze', 'test'): import freeze as helper - +@support.requires_zlib() @unittest.skipIf(sys.platform.startswith('win'), 'not supported on Windows') @support.skip_if_buildbot('not all buildbots have enough space') class TestFreeze(unittest.TestCase): @@ -22,8 +23,8 @@ class TestFreeze(unittest.TestCase): print('running...') sys.exit(0) """) - outdir, scriptfile, python = helper.prepare(script) - - executable = helper.freeze(python, scriptfile, outdir) - text = helper.run(executable) + with os_helper.temp_dir() as outdir: + outdir, scriptfile, python = helper.prepare(script, outdir) + executable = helper.freeze(python, scriptfile, outdir) + text = helper.run(executable) self.assertEqual(text, 'running...') diff --git a/Lib/test/test_tools/test_gprof2html.py b/Lib/test/test_tools/test_gprof2html.py deleted file mode 100644 index 7cceb8faf8e..00000000000 --- a/Lib/test/test_tools/test_gprof2html.py +++ /dev/null @@ -1,35 +0,0 @@ -"""Tests for the gprof2html script in the Tools directory.""" - -import os -import sys -import unittest -from unittest import mock -import tempfile - -from test.test_tools import skip_if_missing, import_tool - -skip_if_missing() - -class Gprof2htmlTests(unittest.TestCase): - - def setUp(self): - self.gprof = import_tool('gprof2html') - oldargv = sys.argv - def fixup(): - sys.argv = oldargv - self.addCleanup(fixup) - sys.argv = [] - - def test_gprof(self): - # Issue #14508: this used to fail with a NameError. - with mock.patch.object(self.gprof, 'webbrowser') as wmock, \ - tempfile.TemporaryDirectory() as tmpdir: - fn = os.path.join(tmpdir, 'abc') - open(fn, 'wb').close() - sys.argv = ['gprof2html', fn] - self.gprof.main() - self.assertTrue(wmock.open.called) - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_tools/test_i18n.py b/Lib/test/test_tools/test_i18n.py index 7f18edaaa8c..c083a04475e 100644 --- a/Lib/test/test_tools/test_i18n.py +++ b/Lib/test/test_tools/test_i18n.py @@ -155,6 +155,26 @@ class Test_pygettext(unittest.TestCase): ''')) self.assertFalse([msgid for msgid in msgids if 'doc' in msgid]) + def test_moduledocstring(self): + for doc in ('"""doc"""', "r'''doc'''", "R'doc'", 'u"doc"'): + with self.subTest(doc): + msgids = self.extract_docstrings_from_str(dedent('''\ + %s + ''' % doc)) + self.assertIn('doc', msgids) + + def test_moduledocstring_bytes(self): + msgids = self.extract_docstrings_from_str(dedent('''\ + b"""doc""" + ''')) + self.assertFalse([msgid for msgid in msgids if 'doc' in msgid]) + + def test_moduledocstring_fstring(self): + msgids = self.extract_docstrings_from_str(dedent('''\ + f"""doc""" + ''')) + self.assertFalse([msgid for msgid in msgids if 'doc' in msgid]) + def test_msgid(self): msgids = self.extract_docstrings_from_str( '''_("""doc""" r'str' u"ing")''') diff --git a/Lib/test/test_tools/test_lll.py b/Lib/test/test_tools/test_lll.py deleted file mode 100644 index 6eeb96ed9b6..00000000000 --- a/Lib/test/test_tools/test_lll.py +++ /dev/null @@ -1,41 +0,0 @@ -"""Tests for the lll script in the Tools/script directory.""" - -import os -import tempfile -from test import support -from test.support import os_helper -from test.test_tools import skip_if_missing, import_tool -import unittest - -skip_if_missing() - - -class lllTests(unittest.TestCase): - - def setUp(self): - self.lll = import_tool('lll') - - @os_helper.skip_unless_symlink - def test_lll_multiple_dirs(self): - with tempfile.TemporaryDirectory() as dir1, \ - tempfile.TemporaryDirectory() as dir2: - fn1 = os.path.join(dir1, 'foo1') - fn2 = os.path.join(dir2, 'foo2') - for fn, dir in (fn1, dir1), (fn2, dir2): - open(fn, 'wb').close() - os.symlink(fn, os.path.join(dir, 'symlink')) - - with support.captured_stdout() as output: - self.lll.main([dir1, dir2]) - prefix = '\\\\?\\' if os.name == 'nt' else '' - self.assertEqual(output.getvalue(), - f'{dir1}:\n' - f'symlink -> {prefix}{fn1}\n' - f'\n' - f'{dir2}:\n' - f'symlink -> {prefix}{fn2}\n' - ) - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_tools/test_md5sum.py b/Lib/test/test_tools/test_md5sum.py deleted file mode 100644 index 92315f181c8..00000000000 --- a/Lib/test/test_tools/test_md5sum.py +++ /dev/null @@ -1,79 +0,0 @@ -"""Tests for the md5sum script in the Tools directory.""" - -import sys -import os -import unittest -from test.support import os_helper -from test.support import hashlib_helper -from test.support.script_helper import assert_python_ok, assert_python_failure - -from test.test_tools import scriptsdir, skip_if_missing - -skip_if_missing() - -@hashlib_helper.requires_hashdigest('md5') -class MD5SumTests(unittest.TestCase): - @classmethod - def setUpClass(cls): - cls.script = os.path.join(scriptsdir, 'md5sum.py') - os.mkdir(os_helper.TESTFN_ASCII) - cls.fodder = os.path.join(os_helper.TESTFN_ASCII, 'md5sum.fodder') - with open(cls.fodder, 'wb') as f: - f.write(b'md5sum\r\ntest file\r\n') - cls.fodder_md5 = b'd38dae2eb1ab346a292ef6850f9e1a0d' - cls.fodder_textmode_md5 = b'a8b07894e2ca3f2a4c3094065fa6e0a5' - - @classmethod - def tearDownClass(cls): - os_helper.rmtree(os_helper.TESTFN_ASCII) - - def test_noargs(self): - rc, out, err = assert_python_ok(self.script) - self.assertEqual(rc, 0) - self.assertTrue( - out.startswith(b'd41d8cd98f00b204e9800998ecf8427e ')) - self.assertFalse(err) - - def test_checksum_fodder(self): - rc, out, err = assert_python_ok(self.script, self.fodder) - self.assertEqual(rc, 0) - self.assertTrue(out.startswith(self.fodder_md5)) - for part in self.fodder.split(os.path.sep): - self.assertIn(part.encode(), out) - self.assertFalse(err) - - def test_dash_l(self): - rc, out, err = assert_python_ok(self.script, '-l', self.fodder) - self.assertEqual(rc, 0) - self.assertIn(self.fodder_md5, out) - parts = self.fodder.split(os.path.sep) - self.assertIn(parts[-1].encode(), out) - self.assertNotIn(parts[-2].encode(), out) - - def test_dash_t(self): - rc, out, err = assert_python_ok(self.script, '-t', self.fodder) - self.assertEqual(rc, 0) - self.assertTrue(out.startswith(self.fodder_textmode_md5)) - self.assertNotIn(self.fodder_md5, out) - - def test_dash_s(self): - rc, out, err = assert_python_ok(self.script, '-s', '512', self.fodder) - self.assertEqual(rc, 0) - self.assertIn(self.fodder_md5, out) - - def test_multiple_files(self): - rc, out, err = assert_python_ok(self.script, self.fodder, self.fodder) - self.assertEqual(rc, 0) - lines = out.splitlines() - self.assertEqual(len(lines), 2) - self.assertEqual(*lines) - - def test_usage(self): - rc, out, err = assert_python_failure(self.script, '-h') - self.assertEqual(rc, 2) - self.assertEqual(out, b'') - self.assertGreater(err, b'') - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_tools/test_pathfix.py b/Lib/test/test_tools/test_pathfix.py deleted file mode 100644 index ff61935298b..00000000000 --- a/Lib/test/test_tools/test_pathfix.py +++ /dev/null @@ -1,132 +0,0 @@ -import os -import subprocess -import sys -import unittest -from test import support -from test.support import os_helper -from test.test_tools import scriptsdir, skip_if_missing - - -# need Tools/script/ directory: skip if run on Python installed on the system -skip_if_missing() - - -class TestPathfixFunctional(unittest.TestCase): - script = os.path.join(scriptsdir, 'pathfix.py') - - def setUp(self): - self.addCleanup(os_helper.unlink, os_helper.TESTFN) - - def pathfix(self, shebang, pathfix_flags, exitcode=0, stdout='', stderr='', - directory=''): - if directory: - # bpo-38347: Test filename should contain lowercase, uppercase, - # "-", "_" and digits. - filename = os.path.join(directory, 'script-A_1.py') - pathfix_arg = directory - else: - filename = os_helper.TESTFN - pathfix_arg = filename - - with open(filename, 'w', encoding='utf8') as f: - f.write(f'{shebang}\n' + 'print("Hello world")\n') - - encoding = sys.getfilesystemencoding() - proc = subprocess.run( - [sys.executable, self.script, - *pathfix_flags, '-n', pathfix_arg], - env={**os.environ, 'PYTHONIOENCODING': encoding}, - capture_output=True) - - if stdout == '' and proc.returncode == 0: - stdout = f'{filename}: updating\n' - self.assertEqual(proc.returncode, exitcode, proc) - self.assertEqual(proc.stdout.decode(encoding), stdout.replace('\n', os.linesep), proc) - self.assertEqual(proc.stderr.decode(encoding), stderr.replace('\n', os.linesep), proc) - - with open(filename, 'r', encoding='utf8') as f: - output = f.read() - - lines = output.split('\n') - self.assertEqual(lines[1:], ['print("Hello world")', '']) - new_shebang = lines[0] - - if proc.returncode != 0: - self.assertEqual(shebang, new_shebang) - - return new_shebang - - def test_recursive(self): - tmpdir = os_helper.TESTFN + '.d' - self.addCleanup(os_helper.rmtree, tmpdir) - os.mkdir(tmpdir) - expected_stderr = f"recursedown('{os.path.basename(tmpdir)}')\n" - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python', - ['-i', '/usr/bin/python3'], - directory=tmpdir, - stderr=expected_stderr), - '#! /usr/bin/python3') - - def test_pathfix(self): - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python', - ['-i', '/usr/bin/python3']), - '#! /usr/bin/python3') - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python -R', - ['-i', '/usr/bin/python3']), - '#! /usr/bin/python3') - - def test_pathfix_keeping_flags(self): - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python -R', - ['-i', '/usr/bin/python3', '-k']), - '#! /usr/bin/python3 -R') - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python', - ['-i', '/usr/bin/python3', '-k']), - '#! /usr/bin/python3') - - def test_pathfix_adding_flag(self): - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python', - ['-i', '/usr/bin/python3', '-a', 's']), - '#! /usr/bin/python3 -s') - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python -S', - ['-i', '/usr/bin/python3', '-a', 's']), - '#! /usr/bin/python3 -s') - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python -V', - ['-i', '/usr/bin/python3', '-a', 'v', '-k']), - '#! /usr/bin/python3 -vV') - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python', - ['-i', '/usr/bin/python3', '-a', 'Rs']), - '#! /usr/bin/python3 -Rs') - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python -W default', - ['-i', '/usr/bin/python3', '-a', 's', '-k']), - '#! /usr/bin/python3 -sW default') - - def test_pathfix_adding_errors(self): - self.pathfix( - '#! /usr/bin/env python -E', - ['-i', '/usr/bin/python3', '-a', 'W default', '-k'], - exitcode=2, - stderr="-a option doesn't support whitespaces") - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_tools/test_pdeps.py b/Lib/test/test_tools/test_pdeps.py deleted file mode 100644 index a986d10e499..00000000000 --- a/Lib/test/test_tools/test_pdeps.py +++ /dev/null @@ -1,32 +0,0 @@ -"""Tests for the pdeps script in the Tools directory.""" - -import os -import unittest -import tempfile - -from test.test_tools import skip_if_missing, import_tool - -skip_if_missing() - - -class PdepsTests(unittest.TestCase): - - @classmethod - def setUpClass(self): - self.pdeps = import_tool('pdeps') - - def test_process_errors(self): - # Issue #14492: m_import.match(line) can be None. - with tempfile.TemporaryDirectory() as tmpdir: - fn = os.path.join(tmpdir, 'foo') - with open(fn, 'w', encoding='utf-8') as stream: - stream.write("#!/this/will/fail") - self.pdeps.process(fn, {}) - - def test_inverse_attribute_error(self): - # Issue #14492: this used to fail with an AttributeError. - self.pdeps.inverse({'a': []}) - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_tools/test_pindent.py b/Lib/test/test_tools/test_pindent.py deleted file mode 100644 index 01f13850eae..00000000000 --- a/Lib/test/test_tools/test_pindent.py +++ /dev/null @@ -1,340 +0,0 @@ -"""Tests for the pindent script in the Tools directory.""" - -import os -import sys -import unittest -import subprocess -import textwrap -from test import support -from test.support import os_helper -from test.support.script_helper import assert_python_ok - -from test.test_tools import scriptsdir, skip_if_missing - -skip_if_missing() - - -class PindentTests(unittest.TestCase): - script = os.path.join(scriptsdir, 'pindent.py') - - def assertFileEqual(self, fn1, fn2): - with open(fn1) as f1, open(fn2) as f2: - self.assertEqual(f1.readlines(), f2.readlines()) - - def pindent(self, source, *args): - with subprocess.Popen( - (sys.executable, self.script) + args, - stdin=subprocess.PIPE, stdout=subprocess.PIPE, - universal_newlines=True) as proc: - out, err = proc.communicate(source) - self.assertIsNone(err) - return out - - def lstriplines(self, data): - return '\n'.join(line.lstrip() for line in data.splitlines()) + '\n' - - def test_selftest(self): - self.maxDiff = None - with os_helper.temp_dir() as directory: - data_path = os.path.join(directory, '_test.py') - with open(self.script, encoding='utf-8') as f: - closed = f.read() - with open(data_path, 'w', encoding='utf-8') as f: - f.write(closed) - - rc, out, err = assert_python_ok(self.script, '-d', data_path) - self.assertEqual(out, b'') - self.assertEqual(err, b'') - backup = data_path + '~' - self.assertTrue(os.path.exists(backup)) - with open(backup, encoding='utf-8') as f: - self.assertEqual(f.read(), closed) - with open(data_path, encoding='utf-8') as f: - clean = f.read() - compile(clean, '_test.py', 'exec') - self.assertEqual(self.pindent(clean, '-c'), closed) - self.assertEqual(self.pindent(closed, '-d'), clean) - - rc, out, err = assert_python_ok(self.script, '-c', data_path) - self.assertEqual(out, b'') - self.assertEqual(err, b'') - with open(backup, encoding='utf-8') as f: - self.assertEqual(f.read(), clean) - with open(data_path, encoding='utf-8') as f: - self.assertEqual(f.read(), closed) - - broken = self.lstriplines(closed) - with open(data_path, 'w', encoding='utf-8') as f: - f.write(broken) - rc, out, err = assert_python_ok(self.script, '-r', data_path) - self.assertEqual(out, b'') - self.assertEqual(err, b'') - with open(backup, encoding='utf-8') as f: - self.assertEqual(f.read(), broken) - with open(data_path, encoding='utf-8') as f: - indented = f.read() - compile(indented, '_test.py', 'exec') - self.assertEqual(self.pindent(broken, '-r'), indented) - - def pindent_test(self, clean, closed): - self.assertEqual(self.pindent(clean, '-c'), closed) - self.assertEqual(self.pindent(closed, '-d'), clean) - broken = self.lstriplines(closed) - self.assertEqual(self.pindent(broken, '-r', '-e', '-s', '4'), closed) - - def test_statements(self): - clean = textwrap.dedent("""\ - if a: - pass - - if a: - pass - else: - pass - - if a: - pass - elif: - pass - else: - pass - - while a: - break - - while a: - break - else: - pass - - for i in a: - break - - for i in a: - break - else: - pass - - try: - pass - finally: - pass - - try: - pass - except TypeError: - pass - except ValueError: - pass - else: - pass - - try: - pass - except TypeError: - pass - except ValueError: - pass - finally: - pass - - with a: - pass - - class A: - pass - - def f(): - pass - """) - - closed = textwrap.dedent("""\ - if a: - pass - # end if - - if a: - pass - else: - pass - # end if - - if a: - pass - elif: - pass - else: - pass - # end if - - while a: - break - # end while - - while a: - break - else: - pass - # end while - - for i in a: - break - # end for - - for i in a: - break - else: - pass - # end for - - try: - pass - finally: - pass - # end try - - try: - pass - except TypeError: - pass - except ValueError: - pass - else: - pass - # end try - - try: - pass - except TypeError: - pass - except ValueError: - pass - finally: - pass - # end try - - with a: - pass - # end with - - class A: - pass - # end class A - - def f(): - pass - # end def f - """) - self.pindent_test(clean, closed) - - def test_multilevel(self): - clean = textwrap.dedent("""\ - def foobar(a, b): - if a == b: - a = a+1 - elif a < b: - b = b-1 - if b > a: a = a-1 - else: - print 'oops!' - """) - closed = textwrap.dedent("""\ - def foobar(a, b): - if a == b: - a = a+1 - elif a < b: - b = b-1 - if b > a: a = a-1 - # end if - else: - print 'oops!' - # end if - # end def foobar - """) - self.pindent_test(clean, closed) - - def test_preserve_indents(self): - clean = textwrap.dedent("""\ - if a: - if b: - pass - """) - closed = textwrap.dedent("""\ - if a: - if b: - pass - # end if - # end if - """) - self.assertEqual(self.pindent(clean, '-c'), closed) - self.assertEqual(self.pindent(closed, '-d'), clean) - broken = self.lstriplines(closed) - self.assertEqual(self.pindent(broken, '-r', '-e', '-s', '9'), closed) - clean = textwrap.dedent("""\ - if a: - \tif b: - \t\tpass - """) - closed = textwrap.dedent("""\ - if a: - \tif b: - \t\tpass - \t# end if - # end if - """) - self.assertEqual(self.pindent(clean, '-c'), closed) - self.assertEqual(self.pindent(closed, '-d'), clean) - broken = self.lstriplines(closed) - self.assertEqual(self.pindent(broken, '-r'), closed) - - def test_escaped_newline(self): - clean = textwrap.dedent("""\ - class\\ - \\ - A: - def\ - \\ - f: - pass - """) - closed = textwrap.dedent("""\ - class\\ - \\ - A: - def\ - \\ - f: - pass - # end def f - # end class A - """) - self.assertEqual(self.pindent(clean, '-c'), closed) - self.assertEqual(self.pindent(closed, '-d'), clean) - - def test_empty_line(self): - clean = textwrap.dedent("""\ - if a: - - pass - """) - closed = textwrap.dedent("""\ - if a: - - pass - # end if - """) - self.pindent_test(clean, closed) - - def test_oneline(self): - clean = textwrap.dedent("""\ - if a: pass - """) - closed = textwrap.dedent("""\ - if a: pass - # end if - """) - self.pindent_test(clean, closed) - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_tools/test_reindent.py b/Lib/test/test_tools/test_reindent.py index 34df0c5d511..3b0c793a38e 100644 --- a/Lib/test/test_tools/test_reindent.py +++ b/Lib/test/test_tools/test_reindent.py @@ -9,12 +9,12 @@ import unittest from test.support.script_helper import assert_python_ok from test.support import findfile -from test.test_tools import scriptsdir, skip_if_missing +from test.test_tools import toolsdir, skip_if_missing skip_if_missing() class ReindentTests(unittest.TestCase): - script = os.path.join(scriptsdir, 'reindent.py') + script = os.path.join(toolsdir, 'patchcheck', 'reindent.py') def test_noargs(self): assert_python_ok(self.script) diff --git a/Lib/test/test_tools/test_sundry.py b/Lib/test/test_tools/test_sundry.py index 52369ec09a7..81f06763980 100644 --- a/Lib/test/test_tools/test_sundry.py +++ b/Lib/test/test_tools/test_sundry.py @@ -19,17 +19,19 @@ class TestSundryScripts(unittest.TestCase): # added for a script it should be added to the allowlist below. # scripts that have independent tests. - allowlist = ['reindent', 'pdeps', 'gprof2html', 'md5sum'] + allowlist = ['reindent'] # scripts that can't be imported without running denylist = ['make_ctype'] - # scripts that use windows-only modules - windows_only = ['win_add2path'] # denylisted for other reasons - other = ['analyze_dxp', '2to3'] + other = ['2to3'] - skiplist = denylist + allowlist + windows_only + other + skiplist = denylist + allowlist + other - def test_sundry(self): + # import logging registers "atfork" functions which keep indirectly the + # logging module dictionary alive. Mock the function to be able to unload + # cleanly the logging module. + @import_helper.mock_register_at_fork + def test_sundry(self, mock_os): old_modules = import_helper.modules_setup() try: for fn in os.listdir(scriptsdir): @@ -45,18 +47,6 @@ class TestSundryScripts(unittest.TestCase): # Unload all modules loaded in this test import_helper.modules_cleanup(*old_modules) - @unittest.skipIf(sys.platform != "win32", "Windows-only test") - def test_sundry_windows(self): - for name in self.windows_only: - import_tool(name) - - def test_analyze_dxp_import(self): - if hasattr(sys, 'getdxp'): - import_tool('analyze_dxp') - else: - with self.assertRaises(RuntimeError): - import_tool('analyze_dxp') - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py index dbfefca7ee5..fad2b3b8379 100644 --- a/Lib/test/test_trace.py +++ b/Lib/test/test_trace.py @@ -1,4 +1,5 @@ import os +from pickle import dump import sys from test.support import captured_stdout from test.support.os_helper import (TESTFN, rmtree, unlink) @@ -11,6 +12,11 @@ from trace import Trace from test.tracedmodules import testmod +## +## See also test_sys_settrace.py, which contains tests that cover +## tracing of many more code blocks. +## + #------------------------------- Utilities -----------------------------------# def fix_ext_py(filename): @@ -200,9 +206,9 @@ class TestLineCounts(unittest.TestCase): (self.my_py_filename, firstlineno + 4): 1, (self.my_py_filename, firstlineno + 5): 1, (self.my_py_filename, firstlineno + 6): 1, - (self.my_py_filename, firstlineno + 7): 1, - (self.my_py_filename, firstlineno + 8): 1, - (self.my_py_filename, firstlineno + 9): 1, + (self.my_py_filename, firstlineno + 7): 2, + (self.my_py_filename, firstlineno + 8): 2, + (self.my_py_filename, firstlineno + 9): 2, (self.my_py_filename, firstlineno + 10): 1, (self.my_py_filename, firstlineno + 11): 1, } @@ -407,6 +413,15 @@ class TestCoverage(unittest.TestCase): self.assertIn(modname, coverage) self.assertEqual(coverage[modname], (5, 100)) + def test_coverageresults_update(self): + # Update empty CoverageResults with a non-empty infile. + infile = TESTFN + '-infile' + with open(infile, 'wb') as f: + dump(({}, {}, {'caller': 1}), f, protocol=1) + self.addCleanup(unlink, infile) + results = trace.CoverageResults({}, {}, infile, {}) + self.assertEqual(results.callers, {'caller': 1}) + ### Tests that don't mess with sys.settrace and can be traced ### themselves TODO: Skip tests that do mess with sys.settrace when ### regrtest is invoked with -T option. diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index d88851ddda4..95b1bae4f60 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -4,20 +4,31 @@ from collections import namedtuple from io import StringIO import linecache import sys +import types import inspect +import importlib +import builtins import unittest import re +import tempfile +import random +import string from test import support +import shutil from test.support import (Error, captured_output, cpython_only, ALWAYS_EQ, - requires_debug_ranges, has_no_debug_ranges) + requires_debug_ranges, has_no_debug_ranges, + requires_subprocess) from test.support.os_helper import TESTFN, unlink from test.support.script_helper import assert_python_ok, assert_python_failure +from test.support.import_helper import forget -import os +import json import textwrap import traceback from functools import partial +from pathlib import Path +MODULE_PREFIX = f'{__name__}.' if __name__ == '__main__' else '' test_code = namedtuple('code', ['co_filename', 'co_name']) test_code.co_positions = lambda _: iter([(6, 6, 0, 0)]) @@ -25,6 +36,9 @@ test_frame = namedtuple('frame', ['f_code', 'f_globals', 'f_locals']) test_tb = namedtuple('tb', ['tb_frame', 'tb_lineno', 'tb_next', 'tb_lasti']) +LEVENSHTEIN_DATA_FILE = Path(__file__).parent / 'levenshtein_examples.json' + + class TracebackCases(unittest.TestCase): # For now, a very minimal set of tests. I want to be sure that # formatting of SyntaxErrors works based on changes for 2.1. @@ -202,6 +216,7 @@ class TracebackCases(unittest.TestCase): str_name = '.'.join([X.__module__, X.__qualname__]) self.assertEqual(err[0], "%s: %s\n" % (str_name, str_value)) + @requires_subprocess() def test_encoded_file(self): # Test that tracebacks are correctly printed for encoded source files: # - correct line number (Issue2384) @@ -249,7 +264,7 @@ class TracebackCases(unittest.TestCase): self.assertTrue(stdout[2].endswith(err_line), "Invalid traceback line: {0!r} instead of {1!r}".format( stdout[2], err_line)) - actual_err_msg = stdout[3 if has_no_debug_ranges() else 4] + actual_err_msg = stdout[3] self.assertTrue(actual_err_msg == err_msg, "Invalid error message: {0!r} instead of {1!r}".format( actual_err_msg, err_msg)) @@ -368,33 +383,50 @@ class TracebackCases(unittest.TestCase): '(exc, /, value=)') -@requires_debug_ranges() -class TracebackErrorLocationCaretTests(unittest.TestCase): - """ - Tests for printing code error expressions as part of PEP 657 - """ - def get_exception(self, callable): +class PurePythonExceptionFormattingMixin: + def get_exception(self, callable, slice_start=0, slice_end=-1): try: callable() self.fail("No exception thrown.") except: - return traceback.format_exc().splitlines()[:-1] + return traceback.format_exc().splitlines()[slice_start:slice_end] callable_line = get_exception.__code__.co_firstlineno + 2 + +class CAPIExceptionFormattingMixin: + def get_exception(self, callable, slice_start=0, slice_end=-1): + from _testcapi import exception_print + try: + callable() + self.fail("No exception thrown.") + except Exception as e: + with captured_output("stderr") as tbstderr: + exception_print(e) + return tbstderr.getvalue().splitlines()[slice_start:slice_end] + + callable_line = get_exception.__code__.co_firstlineno + 3 + + +@requires_debug_ranges() +class TracebackErrorLocationCaretTestBase: + """ + Tests for printing code error expressions as part of PEP 657 + """ def test_basic_caret(self): + # NOTE: In caret tests, "if True:" is used as a way to force indicator + # display, since the raising expression spans only part of the line. def f(): - raise ValueError("basic caret tests") + if True: raise ValueError("basic caret tests") lineno_f = f.__code__.co_firstlineno expected_f = ( 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' - ' ^^^^^^^^^^\n' f' File "{__file__}", line {lineno_f+1}, in f\n' - ' raise ValueError("basic caret tests")\n' - ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' + ' if True: raise ValueError("basic caret tests")\n' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' ) result_lines = self.get_exception(f) self.assertEqual(result_lines, expected_f.splitlines()) @@ -403,17 +435,16 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): # Make sure that even if a line contains multi-byte unicode characters # the correct carets are printed. def f_with_unicode(): - raise ValueError("Ĥellö Wörld") + if True: raise ValueError("Ĥellö Wörld") lineno_f = f_with_unicode.__code__.co_firstlineno expected_f = ( 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' - ' ^^^^^^^^^^\n' f' File "{__file__}", line {lineno_f+1}, in f_with_unicode\n' - ' raise ValueError("Ĥellö Wörld")\n' - ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' + ' if True: raise ValueError("Ĥellö Wörld")\n' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' ) result_lines = self.get_exception(f_with_unicode) self.assertEqual(result_lines, expected_f.splitlines()) @@ -428,7 +459,6 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' - ' ^^^^^^^^^^\n' f' File "{__file__}", line {lineno_f+1}, in f_with_type\n' ' def foo(a: THIS_DOES_NOT_EXIST ) -> int:\n' ' ^^^^^^^^^^^^^^^^^^^\n' @@ -440,7 +470,7 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): # Make sure no carets are printed for expressions spanning multiple # lines. def f_with_multiline(): - raise ValueError( + if True: raise ValueError( "error over multiple lines" ) @@ -449,22 +479,55 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' - ' ^^^^^^^^^^\n' f' File "{__file__}", line {lineno_f+1}, in f_with_multiline\n' - ' raise ValueError(\n' - ' ^^^^^^^^^^^^^^^^^' + ' if True: raise ValueError(\n' + ' ^^^^^^^^^^^^^^^^^' ) result_lines = self.get_exception(f_with_multiline) self.assertEqual(result_lines, expected_f.splitlines()) + def test_caret_multiline_expression_syntax_error(self): + # Make sure an expression spanning multiple lines that has + # a syntax error is correctly marked with carets. + code = textwrap.dedent(""" + def foo(*args, **kwargs): + pass + + a, b, c = 1, 2, 3 + + foo(a, z + for z in + range(10), b, c) + """) + + def f_with_multiline(): + # Need to defer the compilation until in self.get_exception(..) + return compile(code, "?", "exec") + + lineno_f = f_with_multiline.__code__.co_firstlineno + + expected_f = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + f' File "{__file__}", line {lineno_f+2}, in f_with_multiline\n' + ' return compile(code, "?", "exec")\n' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^\n' + ' File "?", line 7\n' + ' foo(a, z\n' + ' ^' + ) + + result_lines = self.get_exception(f_with_multiline) + self.assertEqual(result_lines, expected_f.splitlines()) + def test_caret_multiline_expression_bin_op(self): # Make sure no carets are printed for expressions spanning multiple # lines. def f_with_multiline(): return ( - 1 / - 0 + - 2 + 2 + 1 / + 0 ) lineno_f = f_with_multiline.__code__.co_firstlineno @@ -472,10 +535,9 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' - ' ^^^^^^^^^^\n' f' File "{__file__}", line {lineno_f+2}, in f_with_multiline\n' - ' 1 /\n' - ' ^^^' + ' 2 + 1 /\n' + ' ^^^' ) result_lines = self.get_exception(f_with_multiline) self.assertEqual(result_lines, expected_f.splitlines()) @@ -490,7 +552,6 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' - ' ^^^^^^^^^^\n' f' File "{__file__}", line {lineno_f+2}, in f_with_binary_operator\n' ' return 10 + divisor / 0 + 30\n' ' ~~~~~~~~^~~\n' @@ -498,6 +559,23 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): result_lines = self.get_exception(f_with_binary_operator) self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_binary_operators_with_unicode(self): + def f_with_binary_operator(): + áóí = 20 + return 10 + áóí / 0 + 30 + + lineno_f = f_with_binary_operator.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + f' File "{__file__}", line {lineno_f+2}, in f_with_binary_operator\n' + ' return 10 + áóí / 0 + 30\n' + ' ~~~~^~~\n' + ) + result_lines = self.get_exception(f_with_binary_operator) + self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_binary_operators_two_char(self): def f_with_binary_operator(): divisor = 20 @@ -508,7 +586,6 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' - ' ^^^^^^^^^^\n' f' File "{__file__}", line {lineno_f+2}, in f_with_binary_operator\n' ' return 10 + divisor // 0 + 30\n' ' ~~~~~~~~^^~~\n' @@ -526,7 +603,6 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' - ' ^^^^^^^^^^\n' f' File "{__file__}", line {lineno_f+2}, in f_with_subscript\n' " return some_dict['x']['y']['z']\n" ' ~~~~~~~~~~~~~~~~~~~^^^^^\n' @@ -534,6 +610,23 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): result_lines = self.get_exception(f_with_subscript) self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_subscript_unicode(self): + def f_with_subscript(): + some_dict = {'ó': {'á': {'í': {'theta': 1}}}} + return some_dict['ó']['á']['í']['beta'] + + lineno_f = f_with_subscript.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + f' File "{__file__}", line {lineno_f+2}, in f_with_subscript\n' + " return some_dict['ó']['á']['í']['beta']\n" + ' ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^\n' + ) + result_lines = self.get_exception(f_with_subscript) + self.assertEqual(result_lines, expected_error.splitlines()) + def test_traceback_specialization_with_syntax_error(self): bytecode = compile("1 / 0 / 1 / 2\n", TESTFN, "exec") @@ -550,7 +643,6 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' - ' ^^^^^^^^^^\n' f' File "{TESTFN}", line {lineno_f}, in \n' " 1 $ 0 / 1 / 2\n" ' ^^^^^\n' @@ -558,7 +650,7 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): self.assertEqual(result_lines, expected_error.splitlines()) def test_traceback_very_long_line(self): - source = "a" * 256 + source = "if True: " + "a" * 256 bytecode = compile(source, TESTFN, "exec") with open(TESTFN, "w") as file: @@ -573,12 +665,54 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): 'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' ' callable()\n' - ' ^^^^^^^^^^\n' f' File "{TESTFN}", line {lineno_f}, in \n' f' {source}\n' + f' {" "*len("if True: ") + "^"*256}\n' ) self.assertEqual(result_lines, expected_error.splitlines()) + def test_secondary_caret_not_elided(self): + # Always show a line's indicators if they include the secondary character. + def f_with_subscript(): + some_dict = {'x': {'y': None}} + some_dict['x']['y']['z'] + + lineno_f = f_with_subscript.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + f' File "{__file__}", line {lineno_f+2}, in f_with_subscript\n' + " some_dict['x']['y']['z']\n" + ' ~~~~~~~~~~~~~~~~~~~^^^^^\n' + ) + result_lines = self.get_exception(f_with_subscript) + self.assertEqual(result_lines, expected_error.splitlines()) + + def test_caret_exception_group(self): + # Notably, this covers whether indicators handle margin strings correctly. + # (Exception groups use margin strings to display vertical indicators.) + # The implementation must account for both "indent" and "margin" offsets. + + def exc(): + if True: raise ExceptionGroup("eg", [ValueError(1), TypeError(2)]) + + expected_error = ( + f' + Exception Group Traceback (most recent call last):\n' + f' | File "{__file__}", line {self.callable_line}, in get_exception\n' + f' | callable()\n' + f' | File "{__file__}", line {exc.__code__.co_firstlineno + 1}, in exc\n' + f' | if True: raise ExceptionGroup("eg", [ValueError(1), TypeError(2)])\n' + f' | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' + f' | ExceptionGroup: eg (2 sub-exceptions)\n' + f' +-+---------------- 1 ----------------\n' + f' | ValueError: 1\n' + f' +---------------- 2 ----------------\n' + f' | TypeError: 2\n') + + result_lines = self.get_exception(exc) + self.assertEqual(result_lines, expected_error.splitlines()) + def assertSpecialized(self, func, expected_specialization): result_lines = self.get_exception(func) specialization_line = result_lines[-1] @@ -616,26 +750,168 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): self.assertSpecialized(lambda: 1// 0, "~^^~~") + def test_decorator_application_lineno_correct(self): + def dec_error(func): + raise TypeError + def dec_fine(func): + return func + def applydecs(): + @dec_error + @dec_fine + def g(): pass + result_lines = self.get_exception(applydecs) + lineno_applydescs = applydecs.__code__.co_firstlineno + lineno_dec_error = dec_error.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + f' File "{__file__}", line {lineno_applydescs + 1}, in applydecs\n' + ' @dec_error\n' + ' ^^^^^^^^^\n' + f' File "{__file__}", line {lineno_dec_error + 1}, in dec_error\n' + ' raise TypeError\n' + ) + self.assertEqual(result_lines, expected_error.splitlines()) + + def applydecs_class(): + @dec_error + @dec_fine + class A: pass + result_lines = self.get_exception(applydecs_class) + lineno_applydescs_class = applydecs_class.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + f' File "{__file__}", line {lineno_applydescs_class + 1}, in applydecs_class\n' + ' @dec_error\n' + ' ^^^^^^^^^\n' + f' File "{__file__}", line {lineno_dec_error + 1}, in dec_error\n' + ' raise TypeError\n' + ) + self.assertEqual(result_lines, expected_error.splitlines()) + + def test_multiline_method_call_a(self): + def f(): + (None + .method + )() + actual = self.get_exception(f) + expected = [ + f"Traceback (most recent call last):", + f" File \"{__file__}\", line {self.callable_line}, in get_exception", + f" callable()", + f" File \"{__file__}\", line {f.__code__.co_firstlineno + 2}, in f", + f" .method", + f" ^^^^^^", + ] + self.assertEqual(actual, expected) + + def test_multiline_method_call_b(self): + def f(): + (None. + method + )() + actual = self.get_exception(f) + expected = [ + f"Traceback (most recent call last):", + f" File \"{__file__}\", line {self.callable_line}, in get_exception", + f" callable()", + f" File \"{__file__}\", line {f.__code__.co_firstlineno + 2}, in f", + f" method", + ] + self.assertEqual(actual, expected) + + def test_multiline_method_call_c(self): + def f(): + (None + . method + )() + actual = self.get_exception(f) + expected = [ + f"Traceback (most recent call last):", + f" File \"{__file__}\", line {self.callable_line}, in get_exception", + f" callable()", + f" File \"{__file__}\", line {f.__code__.co_firstlineno + 2}, in f", + f" . method", + f" ^^^^^^", + ] + self.assertEqual(actual, expected) + + def test_wide_characters_unicode_with_problematic_byte_offset(self): + def f(): + width + + actual = self.get_exception(f) + expected = [ + f"Traceback (most recent call last):", + f" File \"{__file__}\", line {self.callable_line}, in get_exception", + f" callable()", + f" File \"{__file__}\", line {f.__code__.co_firstlineno + 1}, in f", + f" width", + ] + self.assertEqual(actual, expected) + + + def test_byte_offset_with_wide_characters_middle(self): + def f(): + width = 1 + raise ValueError(width) + + actual = self.get_exception(f) + expected = [ + f"Traceback (most recent call last):", + f" File \"{__file__}\", line {self.callable_line}, in get_exception", + f" callable()", + f" File \"{__file__}\", line {f.__code__.co_firstlineno + 2}, in f", + f" raise ValueError(width)", + ] + self.assertEqual(actual, expected) + + def test_byte_offset_multiline(self): + def f(): + ï½—ï½—ï½— = 1 + th = 0 + + print(1, ï½—ï½—ï½—( + th)) + + actual = self.get_exception(f) + expected = [ + f"Traceback (most recent call last):", + f" File \"{__file__}\", line {self.callable_line}, in get_exception", + f" callable()", + f" File \"{__file__}\", line {f.__code__.co_firstlineno + 4}, in f", + f" print(1, ï½—ï½—ï½—(", + f" ^^^^", + ] + self.assertEqual(actual, expected) + + + +@requires_debug_ranges() +class PurePythonTracebackErrorCaretTests( + PurePythonExceptionFormattingMixin, + TracebackErrorLocationCaretTestBase, + unittest.TestCase, +): + """ + Same set of tests as above using the pure Python implementation of + traceback printing in traceback.py. + """ + @cpython_only @requires_debug_ranges() -class CPythonTracebackErrorCaretTests(TracebackErrorLocationCaretTests): +class CPythonTracebackErrorCaretTests( + CAPIExceptionFormattingMixin, + TracebackErrorLocationCaretTestBase, + unittest.TestCase, +): """ Same set of tests as above but with Python's internal traceback printing. """ - def get_exception(self, callable): - from _testcapi import traceback_print - try: - callable() - self.fail("No exception thrown.") - except: - type_, value, tb = sys.exc_info() - - file_ = StringIO() - traceback_print(tb, file_) - return file_.getvalue().splitlines() - - callable_line = get_exception.__code__.co_firstlineno + 3 class TracebackFormatTests(unittest.TestCase): @@ -682,12 +958,8 @@ class TracebackFormatTests(unittest.TestCase): # Make sure that the traceback is properly indented. tb_lines = python_fmt.splitlines() banner = tb_lines[0] - if has_no_debug_ranges(): - self.assertEqual(len(tb_lines), 5) - location, source_line = tb_lines[-2], tb_lines[-1] - else: - self.assertEqual(len(tb_lines), 7) - location, source_line = tb_lines[-3], tb_lines[-2] + self.assertEqual(len(tb_lines), 5) + location, source_line = tb_lines[-2], tb_lines[-1] self.assertTrue(banner.startswith('Traceback')) self.assertTrue(location.startswith(' File')) self.assertTrue(source_line.startswith(' raise')) @@ -751,16 +1023,12 @@ class TracebackFormatTests(unittest.TestCase): 'Traceback (most recent call last):\n' f' File "{__file__}", line {lineno_f+5}, in _check_recursive_traceback_display\n' ' f()\n' - ' ^^^\n' f' File "{__file__}", line {lineno_f+1}, in f\n' ' f()\n' - ' ^^^\n' f' File "{__file__}", line {lineno_f+1}, in f\n' ' f()\n' - ' ^^^\n' f' File "{__file__}", line {lineno_f+1}, in f\n' ' f()\n' - ' ^^^\n' # XXX: The following line changes depending on whether the tests # are run through the interactive interpreter or with -m # It also varies depending on the platform (stack size) @@ -811,14 +1079,12 @@ class TracebackFormatTests(unittest.TestCase): ' [Previous line repeated 7 more times]\n' f' File "{__file__}", line {lineno_g+3}, in g\n' ' raise ValueError\n' - ' ^^^^^^^^^^^^^^^^\n' 'ValueError\n' ) tb_line = ( 'Traceback (most recent call last):\n' f' File "{__file__}", line {lineno_g+7}, in _check_recursive_traceback_display\n' ' g()\n' - ' ^^^\n' ) expected = (tb_line + result_g).splitlines() actual = stderr_g.getvalue().splitlines() @@ -843,7 +1109,6 @@ class TracebackFormatTests(unittest.TestCase): 'Traceback (most recent call last):\n' f' File "{__file__}", line {lineno_h+7}, in _check_recursive_traceback_display\n' ' h()\n' - ' ^^^\n' f' File "{__file__}", line {lineno_h+2}, in h\n' ' return h(count-1)\n' ' ^^^^^^^^^^\n' @@ -856,7 +1121,6 @@ class TracebackFormatTests(unittest.TestCase): ' [Previous line repeated 7 more times]\n' f' File "{__file__}", line {lineno_h+3}, in h\n' ' g()\n' - ' ^^^\n' ) expected = (result_h + result_g).splitlines() actual = stderr_h.getvalue().splitlines() @@ -882,14 +1146,12 @@ class TracebackFormatTests(unittest.TestCase): ' ^^^^^^^^^^\n' f' File "{__file__}", line {lineno_g+3}, in g\n' ' raise ValueError\n' - ' ^^^^^^^^^^^^^^^^\n' 'ValueError\n' ) tb_line = ( 'Traceback (most recent call last):\n' - f' File "{__file__}", line {lineno_g+81}, in _check_recursive_traceback_display\n' + f' File "{__file__}", line {lineno_g+77}, in _check_recursive_traceback_display\n' ' g(traceback._RECURSIVE_CUTOFF)\n' - ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' ) expected = (tb_line + result_g).splitlines() actual = stderr_g.getvalue().splitlines() @@ -916,14 +1178,12 @@ class TracebackFormatTests(unittest.TestCase): ' [Previous line repeated 1 more time]\n' f' File "{__file__}", line {lineno_g+3}, in g\n' ' raise ValueError\n' - ' ^^^^^^^^^^^^^^^^\n' 'ValueError\n' ) tb_line = ( 'Traceback (most recent call last):\n' - f' File "{__file__}", line {lineno_g+114}, in _check_recursive_traceback_display\n' + f' File "{__file__}", line {lineno_g+108}, in _check_recursive_traceback_display\n' ' g(traceback._RECURSIVE_CUTOFF + 1)\n' - ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' ) expected = (tb_line + result_g).splitlines() actual = stderr_g.getvalue().splitlines() @@ -976,16 +1236,10 @@ class TracebackFormatTests(unittest.TestCase): exception_print(exc_val) tb = stderr_f.getvalue().strip().splitlines() - if has_no_debug_ranges(): - self.assertEqual(11, len(tb)) - self.assertEqual(context_message.strip(), tb[5]) - self.assertIn('UnhashableException: ex2', tb[3]) - self.assertIn('UnhashableException: ex1', tb[10]) - else: - self.assertEqual(13, len(tb)) - self.assertEqual(context_message.strip(), tb[6]) - self.assertIn('UnhashableException: ex2', tb[4]) - self.assertIn('UnhashableException: ex1', tb[12]) + self.assertEqual(11, len(tb)) + self.assertEqual(context_message.strip(), tb[5]) + self.assertIn('UnhashableException: ex2', tb[3]) + self.assertIn('UnhashableException: ex1', tb[10]) def deep_eg(self): e = TypeError(1) @@ -1015,6 +1269,22 @@ class TracebackFormatTests(unittest.TestCase): self.assertIn('ExceptionGroup', output) self.assertLessEqual(output.count('ExceptionGroup'), LIMIT) + @cpython_only + def test_print_exception_bad_type_capi(self): + from _testcapi import exception_print + with captured_output("stderr") as stderr: + exception_print(42) + self.assertEqual( + stderr.getvalue(), + ('TypeError: print_exception(): ' + 'Exception expected for value, int found\n') + ) + + def test_print_exception_bad_type_python(self): + msg = "Exception expected for value, int found" + with self.assertRaisesRegex(TypeError, msg): + traceback.print_exception(42) + cause_message = ( "\nThe above exception was the direct cause " @@ -1030,7 +1300,7 @@ boundaries = re.compile( class BaseExceptionReportingTests: def get_exception(self, exception_or_callable): - if isinstance(exception_or_callable, Exception): + if isinstance(exception_or_callable, BaseException): return exception_or_callable try: exception_or_callable() @@ -1105,12 +1375,8 @@ class BaseExceptionReportingTests: except ZeroDivisionError as _: e = _ lines = self.get_report(e).splitlines() - if has_no_debug_ranges(): - self.assertEqual(len(lines), 4) - self.assertTrue(lines[3].startswith('ZeroDivisionError')) - else: - self.assertEqual(len(lines), 5) - self.assertTrue(lines[4].startswith('ZeroDivisionError')) + self.assertEqual(len(lines), 4) + self.assertTrue(lines[3].startswith('ZeroDivisionError')) self.assertTrue(lines[0].startswith('Traceback')) self.assertTrue(lines[1].startswith(' File')) self.assertIn('ZeroDivisionError from None', lines[2]) @@ -1224,6 +1490,81 @@ class BaseExceptionReportingTests: exp = "\n".join(expected) self.assertEqual(exp, err) + def test_exception_with_note(self): + e = ValueError(123) + vanilla = self.get_report(e) + + e.add_note('My Note') + self.assertEqual(self.get_report(e), vanilla + 'My Note\n') + + del e.__notes__ + e.add_note('') + self.assertEqual(self.get_report(e), vanilla + '\n') + + del e.__notes__ + e.add_note('Your Note') + self.assertEqual(self.get_report(e), vanilla + 'Your Note\n') + + del e.__notes__ + self.assertEqual(self.get_report(e), vanilla) + + def test_exception_with_invalid_notes(self): + e = ValueError(123) + vanilla = self.get_report(e) + + # non-sequence __notes__ + class BadThing: + def __str__(self): + return 'bad str' + + def __repr__(self): + return 'bad repr' + + # unprintable, non-sequence __notes__ + class Unprintable: + def __repr__(self): + raise ValueError('bad value') + + e.__notes__ = BadThing() + notes_repr = 'bad repr' + self.assertEqual(self.get_report(e), vanilla + notes_repr) + + e.__notes__ = Unprintable() + err_msg = '<__notes__ repr() failed>' + self.assertEqual(self.get_report(e), vanilla + err_msg) + + # non-string item in the __notes__ sequence + e.__notes__ = [BadThing(), 'Final Note'] + bad_note = 'bad str' + self.assertEqual(self.get_report(e), vanilla + bad_note + '\nFinal Note\n') + + # unprintable, non-string item in the __notes__ sequence + e.__notes__ = [Unprintable(), 'Final Note'] + err_msg = '' + self.assertEqual(self.get_report(e), vanilla + err_msg + '\nFinal Note\n') + + def test_exception_with_note_with_multiple_notes(self): + e = ValueError(42) + vanilla = self.get_report(e) + + e.add_note('Note 1') + e.add_note('Note 2') + e.add_note('Note 3') + + self.assertEqual( + self.get_report(e), + vanilla + 'Note 1\n' + 'Note 2\n' + 'Note 3\n') + + del e.__notes__ + e.add_note('Note 4') + del e.__notes__ + e.add_note('Note 5') + e.add_note('Note 6') + + self.assertEqual( + self.get_report(e), + vanilla + 'Note 5\n' + 'Note 6\n') + def test_exception_qualname(self): class A: class B: @@ -1235,7 +1576,7 @@ class BaseExceptionReportingTests: str_value = 'I am X' str_name = '.'.join([A.B.X.__module__, A.B.X.__qualname__]) exp = "%s: %s\n" % (str_name, str_value) - self.assertEqual(exp, err) + self.assertEqual(exp, MODULE_PREFIX + err) def test_exception_modulename(self): class X(Exception): @@ -1254,6 +1595,32 @@ class BaseExceptionReportingTests: exp = "%s: %s\n" % (str_name, str_value) self.assertEqual(exp, err) + def test_exception_angle_bracketed_filename(self): + src = textwrap.dedent(""" + try: + raise ValueError(42) + except Exception as e: + exc = e + """) + + code = compile(src, "", "exec") + g, l = {}, {} + exec(code, g, l) + err = self.get_report(l['exc']) + exp = ' File "", line 3, in \nValueError: 42\n' + self.assertIn(exp, err) + + def test_exception_modulename_not_unicode(self): + class X(Exception): + def __str__(self): + return "I am X" + + X.__module__ = 42 + + err = self.get_report(X()) + exp = f'.{X.__qualname__}: I am X\n' + self.assertEqual(exp, err) + def test_exception_bad__str__(self): class X(Exception): def __str__(self): @@ -1261,7 +1628,7 @@ class BaseExceptionReportingTests: err = self.get_report(X()) str_value = '' str_name = '.'.join([X.__module__, X.__qualname__]) - self.assertEqual(err, f"{str_name}: {str_value}\n") + self.assertEqual(MODULE_PREFIX + err, f"{str_name}: {str_value}\n") # #### Exception Groups #### @@ -1274,11 +1641,9 @@ class BaseExceptionReportingTests: f' + Exception Group Traceback (most recent call last):\n' f' | File "{__file__}", line {self.callable_line}, in get_exception\n' f' | exception_or_callable()\n' - f' | ^^^^^^^^^^^^^^^^^^^^^^^\n' f' | File "{__file__}", line {exc.__code__.co_firstlineno + 1}, in exc\n' f' | raise ExceptionGroup("eg", [ValueError(1), TypeError(2)])\n' - f' | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' - f' | ExceptionGroup: eg\n' + f' | ExceptionGroup: eg (2 sub-exceptions)\n' f' +-+---------------- 1 ----------------\n' f' | ValueError: 1\n' f' +---------------- 2 ----------------\n' @@ -1299,8 +1664,7 @@ class BaseExceptionReportingTests: expected = (f' + Exception Group Traceback (most recent call last):\n' f' | File "{__file__}", line {exc.__code__.co_firstlineno + 3}, in exc\n' f' | raise EG("eg1", [ValueError(1), TypeError(2)])\n' - f' | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' - f' | ExceptionGroup: eg1\n' + f' | ExceptionGroup: eg1 (2 sub-exceptions)\n' f' +-+---------------- 1 ----------------\n' f' | ValueError: 1\n' f' +---------------- 2 ----------------\n' @@ -1312,11 +1676,9 @@ class BaseExceptionReportingTests: f' + Exception Group Traceback (most recent call last):\n' f' | File "{__file__}", line {self.callable_line}, in get_exception\n' f' | exception_or_callable()\n' - f' | ^^^^^^^^^^^^^^^^^^^^^^^\n' f' | File "{__file__}", line {exc.__code__.co_firstlineno + 5}, in exc\n' f' | raise EG("eg2", [ValueError(3), TypeError(4)]) from e\n' - f' | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' - f' | ExceptionGroup: eg2\n' + f' | ExceptionGroup: eg2 (2 sub-exceptions)\n' f' +-+---------------- 1 ----------------\n' f' | ValueError: 3\n' f' +---------------- 2 ----------------\n' @@ -1341,8 +1703,7 @@ class BaseExceptionReportingTests: f' + Exception Group Traceback (most recent call last):\n' f' | File "{__file__}", line {exc.__code__.co_firstlineno + 4}, in exc\n' f' | raise EG("eg1", [ValueError(1), TypeError(2)])\n' - f' | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' - f' | ExceptionGroup: eg1\n' + f' | ExceptionGroup: eg1 (2 sub-exceptions)\n' f' +-+---------------- 1 ----------------\n' f' | ValueError: 1\n' f' +---------------- 2 ----------------\n' @@ -1354,8 +1715,7 @@ class BaseExceptionReportingTests: f' + Exception Group Traceback (most recent call last):\n' f' | File "{__file__}", line {exc.__code__.co_firstlineno + 6}, in exc\n' f' | raise EG("eg2", [ValueError(3), TypeError(4)])\n' - f' | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' - f' | ExceptionGroup: eg2\n' + f' | ExceptionGroup: eg2 (2 sub-exceptions)\n' f' +-+---------------- 1 ----------------\n' f' | ValueError: 3\n' f' +---------------- 2 ----------------\n' @@ -1367,10 +1727,8 @@ class BaseExceptionReportingTests: f'Traceback (most recent call last):\n' f' File "{__file__}", line {self.callable_line}, in get_exception\n' f' exception_or_callable()\n' - f' ^^^^^^^^^^^^^^^^^^^^^^^\n' f' File "{__file__}", line {exc.__code__.co_firstlineno + 8}, in exc\n' f' raise ImportError(5)\n' - f' ^^^^^^^^^^^^^^^^^^^^\n' f'ImportError: 5\n') report = self.get_report(exc) @@ -1393,16 +1751,14 @@ class BaseExceptionReportingTests: expected = (f' + Exception Group Traceback (most recent call last):\n' f' | File "{__file__}", line {exc.__code__.co_firstlineno + 9}, in exc\n' f' | raise EG("eg", [VE(1), exc, VE(4)])\n' - f' | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' - f' | ExceptionGroup: eg\n' + f' | ExceptionGroup: eg (3 sub-exceptions)\n' f' +-+---------------- 1 ----------------\n' f' | ValueError: 1\n' f' +---------------- 2 ----------------\n' f' | Exception Group Traceback (most recent call last):\n' f' | File "{__file__}", line {exc.__code__.co_firstlineno + 6}, in exc\n' f' | raise EG("nested", [TE(2), TE(3)])\n' - f' | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n' - f' | ExceptionGroup: nested\n' + f' | ExceptionGroup: nested (2 sub-exceptions)\n' f' +-+---------------- 1 ----------------\n' f' | TypeError: 2\n' f' +---------------- 2 ----------------\n' @@ -1417,11 +1773,9 @@ class BaseExceptionReportingTests: f' + Exception Group Traceback (most recent call last):\n' f' | File "{__file__}", line {self.callable_line}, in get_exception\n' f' | exception_or_callable()\n' - f' | ^^^^^^^^^^^^^^^^^^^^^^^\n' f' | File "{__file__}", line {exc.__code__.co_firstlineno + 11}, in exc\n' f' | raise EG("top", [VE(5)])\n' - f' | ^^^^^^^^^^^^^^^^^^^^^^^^\n' - f' | ExceptionGroup: top\n' + f' | ExceptionGroup: top (1 sub-exception)\n' f' +-+---------------- 1 ----------------\n' f' | ValueError: 5\n' f' +------------------------------------\n') @@ -1435,7 +1789,7 @@ class BaseExceptionReportingTests: excs.append(ValueError(i)) eg = ExceptionGroup('eg', excs) - expected = (' | ExceptionGroup: eg\n' + expected = (' | ExceptionGroup: eg (1000 sub-exceptions)\n' ' +-+---------------- 1 ----------------\n' ' | ValueError: 0\n' ' +---------------- 2 ----------------\n' @@ -1480,43 +1834,43 @@ class BaseExceptionReportingTests: f'eg{i}', [ValueError(i), exc, ValueError(-i)]) - expected = (' | ExceptionGroup: eg999\n' + expected = (' | ExceptionGroup: eg999 (3 sub-exceptions)\n' ' +-+---------------- 1 ----------------\n' ' | ValueError: 999\n' ' +---------------- 2 ----------------\n' - ' | ExceptionGroup: eg998\n' + ' | ExceptionGroup: eg998 (3 sub-exceptions)\n' ' +-+---------------- 1 ----------------\n' ' | ValueError: 998\n' ' +---------------- 2 ----------------\n' - ' | ExceptionGroup: eg997\n' + ' | ExceptionGroup: eg997 (3 sub-exceptions)\n' ' +-+---------------- 1 ----------------\n' ' | ValueError: 997\n' ' +---------------- 2 ----------------\n' - ' | ExceptionGroup: eg996\n' + ' | ExceptionGroup: eg996 (3 sub-exceptions)\n' ' +-+---------------- 1 ----------------\n' ' | ValueError: 996\n' ' +---------------- 2 ----------------\n' - ' | ExceptionGroup: eg995\n' + ' | ExceptionGroup: eg995 (3 sub-exceptions)\n' ' +-+---------------- 1 ----------------\n' ' | ValueError: 995\n' ' +---------------- 2 ----------------\n' - ' | ExceptionGroup: eg994\n' + ' | ExceptionGroup: eg994 (3 sub-exceptions)\n' ' +-+---------------- 1 ----------------\n' ' | ValueError: 994\n' ' +---------------- 2 ----------------\n' - ' | ExceptionGroup: eg993\n' + ' | ExceptionGroup: eg993 (3 sub-exceptions)\n' ' +-+---------------- 1 ----------------\n' ' | ValueError: 993\n' ' +---------------- 2 ----------------\n' - ' | ExceptionGroup: eg992\n' + ' | ExceptionGroup: eg992 (3 sub-exceptions)\n' ' +-+---------------- 1 ----------------\n' ' | ValueError: 992\n' ' +---------------- 2 ----------------\n' - ' | ExceptionGroup: eg991\n' + ' | ExceptionGroup: eg991 (3 sub-exceptions)\n' ' +-+---------------- 1 ----------------\n' ' | ValueError: 991\n' ' +---------------- 2 ----------------\n' - ' | ExceptionGroup: eg990\n' + ' | ExceptionGroup: eg990 (3 sub-exceptions)\n' ' +-+---------------- 1 ----------------\n' ' | ValueError: 990\n' ' +---------------- 2 ----------------\n' @@ -1555,6 +1909,134 @@ class BaseExceptionReportingTests: report = self.get_report(exc) self.assertEqual(report, expected) + def test_exception_group_with_notes(self): + def exc(): + try: + excs = [] + for msg in ['bad value', 'terrible value']: + try: + raise ValueError(msg) + except ValueError as e: + e.add_note(f'the {msg}') + excs.append(e) + raise ExceptionGroup("nested", excs) + except ExceptionGroup as e: + e.add_note(('>> Multi line note\n' + '>> Because I am such\n' + '>> an important exception.\n' + '>> empty lines work too\n' + '\n' + '(that was an empty line)')) + raise + + expected = (f' + Exception Group Traceback (most recent call last):\n' + f' | File "{__file__}", line {self.callable_line}, in get_exception\n' + f' | exception_or_callable()\n' + f' | File "{__file__}", line {exc.__code__.co_firstlineno + 9}, in exc\n' + f' | raise ExceptionGroup("nested", excs)\n' + f' | ExceptionGroup: nested (2 sub-exceptions)\n' + f' | >> Multi line note\n' + f' | >> Because I am such\n' + f' | >> an important exception.\n' + f' | >> empty lines work too\n' + f' | \n' + f' | (that was an empty line)\n' + f' +-+---------------- 1 ----------------\n' + f' | Traceback (most recent call last):\n' + f' | File "{__file__}", line {exc.__code__.co_firstlineno + 5}, in exc\n' + f' | raise ValueError(msg)\n' + f' | ValueError: bad value\n' + f' | the bad value\n' + f' +---------------- 2 ----------------\n' + f' | Traceback (most recent call last):\n' + f' | File "{__file__}", line {exc.__code__.co_firstlineno + 5}, in exc\n' + f' | raise ValueError(msg)\n' + f' | ValueError: terrible value\n' + f' | the terrible value\n' + f' +------------------------------------\n') + + report = self.get_report(exc) + self.assertEqual(report, expected) + + def test_exception_group_with_multiple_notes(self): + def exc(): + try: + excs = [] + for msg in ['bad value', 'terrible value']: + try: + raise ValueError(msg) + except ValueError as e: + e.add_note(f'the {msg}') + e.add_note(f'Goodbye {msg}') + excs.append(e) + raise ExceptionGroup("nested", excs) + except ExceptionGroup as e: + e.add_note(('>> Multi line note\n' + '>> Because I am such\n' + '>> an important exception.\n' + '>> empty lines work too\n' + '\n' + '(that was an empty line)')) + e.add_note('Goodbye!') + raise + + expected = (f' + Exception Group Traceback (most recent call last):\n' + f' | File "{__file__}", line {self.callable_line}, in get_exception\n' + f' | exception_or_callable()\n' + f' | File "{__file__}", line {exc.__code__.co_firstlineno + 10}, in exc\n' + f' | raise ExceptionGroup("nested", excs)\n' + f' | ExceptionGroup: nested (2 sub-exceptions)\n' + f' | >> Multi line note\n' + f' | >> Because I am such\n' + f' | >> an important exception.\n' + f' | >> empty lines work too\n' + f' | \n' + f' | (that was an empty line)\n' + f' | Goodbye!\n' + f' +-+---------------- 1 ----------------\n' + f' | Traceback (most recent call last):\n' + f' | File "{__file__}", line {exc.__code__.co_firstlineno + 5}, in exc\n' + f' | raise ValueError(msg)\n' + f' | ValueError: bad value\n' + f' | the bad value\n' + f' | Goodbye bad value\n' + f' +---------------- 2 ----------------\n' + f' | Traceback (most recent call last):\n' + f' | File "{__file__}", line {exc.__code__.co_firstlineno + 5}, in exc\n' + f' | raise ValueError(msg)\n' + f' | ValueError: terrible value\n' + f' | the terrible value\n' + f' | Goodbye terrible value\n' + f' +------------------------------------\n') + + report = self.get_report(exc) + self.assertEqual(report, expected) + + def test_KeyboardInterrupt_at_first_line_of_frame(self): + # see GH-93249 + def f(): + return sys._getframe() + + tb_next = None + frame = f() + lasti = 0 + lineno = f.__code__.co_firstlineno + tb = types.TracebackType(tb_next, frame, lasti, lineno) + + exc = KeyboardInterrupt() + exc.__traceback__ = tb + + expected = (f'Traceback (most recent call last):\n' + f' File "{__file__}", line {lineno}, in f\n' + f' def f():\n' + f'\n' + f'KeyboardInterrupt\n') + + report = self.get_report(exc) + # remove trailing writespace: + report = '\n'.join([l.rstrip() for l in report.split('\n')]) + self.assertEqual(report, expected) + class PyExcReportingTests(BaseExceptionReportingTests, unittest.TestCase): # @@ -1899,33 +2381,36 @@ class TestStack(unittest.TestCase): [f'{__file__}:{some_inner.__code__.co_firstlineno + 1}']) def test_dropping_frames(self): - def f(): - 1/0 + def f(): + 1/0 - def g(): - try: - f() - except: - return sys.exc_info() + def g(): + try: + f() + except: + return sys.exc_info() - exc_info = g() + exc_info = g() - class Skip_G(traceback.StackSummary): - def format_frame_summary(self, frame_summary): - if frame_summary.name == 'g': - return None - return super().format_frame_summary(frame_summary) + class Skip_G(traceback.StackSummary): + def format_frame_summary(self, frame_summary): + if frame_summary.name == 'g': + return None + return super().format_frame_summary(frame_summary) - stack = Skip_G.extract( - traceback.walk_tb(exc_info[2])).format() + stack = Skip_G.extract( + traceback.walk_tb(exc_info[2])).format() - self.assertEqual(len(stack), 1) - lno = f.__code__.co_firstlineno + 1 - self.assertEqual( - stack[0], - f' File "{__file__}", line {lno}, in f\n 1/0\n' - ) + self.assertEqual(len(stack), 1) + lno = f.__code__.co_firstlineno + 1 + self.assertEqual( + stack[0], + f' File "{__file__}", line {lno}, in f\n 1/0\n' + ) +class Unrepresentable: + def __repr__(self) -> str: + raise Exception("Unrepresentable") class TestTracebackException(unittest.TestCase): @@ -2193,12 +2678,13 @@ class TestTracebackException(unittest.TestCase): linecache.updatecache('/foo.py', globals()) e = Exception("uh oh") c = test_code('/foo.py', 'method') - f = test_frame(c, globals(), {'something': 1, 'other': 'string'}) + f = test_frame(c, globals(), {'something': 1, 'other': 'string', 'unrepresentable': Unrepresentable()}) tb = test_tb(f, 6, None, 0) exc = traceback.TracebackException( Exception, e, tb, capture_locals=True) self.assertEqual( - exc.stack[0].locals, {'something': '1', 'other': "'string'"}) + exc.stack[0].locals, + {'something': '1', 'other': "'string'", 'unrepresentable': ''}) def test_no_locals(self): linecache.updatecache('/foo.py', globals()) @@ -2282,7 +2768,7 @@ class TestTracebackException_ExceptionGroups(unittest.TestCase): def test_exception_group_format_exception_only(self): teg = traceback.TracebackException(*self.eg_info) formatted = ''.join(teg.format_exception_only()).split('\n') - expected = "ExceptionGroup: eg2\n".split('\n') + expected = "ExceptionGroup: eg2 (2 sub-exceptions)\n".split('\n') self.assertEqual(formatted, expected) @@ -2297,19 +2783,16 @@ class TestTracebackException_ExceptionGroups(unittest.TestCase): f' + Exception Group Traceback (most recent call last):', f' | File "{__file__}", line {lno_g+23}, in _get_exception_group', f' | raise ExceptionGroup("eg2", [exc3, exc4])', - f' | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^', - f' | ExceptionGroup: eg2', + f' | ExceptionGroup: eg2 (2 sub-exceptions)', f' +-+---------------- 1 ----------------', f' | Exception Group Traceback (most recent call last):', f' | File "{__file__}", line {lno_g+16}, in _get_exception_group', f' | raise ExceptionGroup("eg1", [exc1, exc2])', - f' | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^', - f' | ExceptionGroup: eg1', + f' | ExceptionGroup: eg1 (2 sub-exceptions)', f' +-+---------------- 1 ----------------', f' | Traceback (most recent call last):', f' | File "{__file__}", line {lno_g+9}, in _get_exception_group', f' | f()', - f' | ^^^', f' | File "{__file__}", line {lno_f+1}, in f', f' | 1/0', f' | ~^~', @@ -2318,20 +2801,16 @@ class TestTracebackException_ExceptionGroups(unittest.TestCase): f' | Traceback (most recent call last):', f' | File "{__file__}", line {lno_g+13}, in _get_exception_group', f' | g(42)', - f' | ^^^^^', f' | File "{__file__}", line {lno_g+1}, in g', f' | raise ValueError(v)', - f' | ^^^^^^^^^^^^^^^^^^^', f' | ValueError: 42', f' +------------------------------------', f' +---------------- 2 ----------------', f' | Traceback (most recent call last):', f' | File "{__file__}", line {lno_g+20}, in _get_exception_group', f' | g(24)', - f' | ^^^^^', f' | File "{__file__}", line {lno_g+1}, in g', f' | raise ValueError(v)', - f' | ^^^^^^^^^^^^^^^^^^^', f' | ValueError: 24', f' +------------------------------------', f''] @@ -2353,9 +2832,9 @@ class TestTracebackException_ExceptionGroups(unittest.TestCase): formatted = ''.join(teg.format()).split('\n') expected = [ - f' | ExceptionGroup: eg', + f' | ExceptionGroup: eg (2 sub-exceptions)', f' +-+---------------- 1 ----------------', - f' | ExceptionGroup: eg1', + f' | ExceptionGroup: eg1 (3 sub-exceptions)', f' +-+---------------- 1 ----------------', f' | ValueError: 0', f' +---------------- 2 ----------------', @@ -2364,7 +2843,7 @@ class TestTracebackException_ExceptionGroups(unittest.TestCase): f' | and 1 more exception', f' +------------------------------------', f' +---------------- 2 ----------------', - f' | ExceptionGroup: eg2', + f' | ExceptionGroup: eg2 (10 sub-exceptions)', f' +-+---------------- 1 ----------------', f' | TypeError: 0', f' +---------------- 2 ----------------', @@ -2385,11 +2864,11 @@ class TestTracebackException_ExceptionGroups(unittest.TestCase): formatted = ''.join(teg.format()).split('\n') expected = [ - f' | ExceptionGroup: exc', + f' | ExceptionGroup: exc (3 sub-exceptions)', f' +-+---------------- 1 ----------------', f' | ValueError: -2', f' +---------------- 2 ----------------', - f' | ExceptionGroup: exc', + f' | ExceptionGroup: exc (3 sub-exceptions)', f' +-+---------------- 1 ----------------', f' | ValueError: -1', f' +---------------- 2 ----------------', @@ -2426,6 +2905,564 @@ class TestTracebackException_ExceptionGroups(unittest.TestCase): self.assertEqual(exc, ALWAYS_EQ) +global_for_suggestions = None + + +class SuggestionFormattingTestBase: + def get_suggestion(self, obj, attr_name=None): + if attr_name is not None: + def callable(): + getattr(obj, attr_name) + else: + callable = obj + + result_lines = self.get_exception( + callable, slice_start=-1, slice_end=None + ) + return result_lines[0] + + def test_getattr_suggestions(self): + class Substitution: + noise = more_noise = a = bc = None + blech = None + + class Elimination: + noise = more_noise = a = bc = None + blch = None + + class Addition: + noise = more_noise = a = bc = None + bluchin = None + + class SubstitutionOverElimination: + blach = None + bluc = None + + class SubstitutionOverAddition: + blach = None + bluchi = None + + class EliminationOverAddition: + blucha = None + bluc = None + + class CaseChangeOverSubstitution: + Luch = None + fluch = None + BLuch = None + + for cls, suggestion in [ + (Addition, "'bluchin'?"), + (Substitution, "'blech'?"), + (Elimination, "'blch'?"), + (Addition, "'bluchin'?"), + (SubstitutionOverElimination, "'blach'?"), + (SubstitutionOverAddition, "'blach'?"), + (EliminationOverAddition, "'bluc'?"), + (CaseChangeOverSubstitution, "'BLuch'?"), + ]: + actual = self.get_suggestion(cls(), 'bluch') + self.assertIn(suggestion, actual) + + def test_getattr_suggestions_do_not_trigger_for_long_attributes(self): + class A: + blech = None + + actual = self.get_suggestion(A(), 'somethingverywrong') + self.assertNotIn("blech", actual) + + def test_getattr_error_bad_suggestions_do_not_trigger_for_small_names(self): + class MyClass: + vvv = mom = w = id = pytho = None + + for name in ("b", "v", "m", "py"): + with self.subTest(name=name): + actual = self.get_suggestion(MyClass, name) + self.assertNotIn("Did you mean", actual) + self.assertNotIn("'vvv", actual) + self.assertNotIn("'mom'", actual) + self.assertNotIn("'id'", actual) + self.assertNotIn("'w'", actual) + self.assertNotIn("'pytho'", actual) + + def test_getattr_suggestions_do_not_trigger_for_big_dicts(self): + class A: + blech = None + # A class with a very big __dict__ will not be consider + # for suggestions. + for index in range(2000): + setattr(A, f"index_{index}", None) + + actual = self.get_suggestion(A(), 'bluch') + self.assertNotIn("blech", actual) + + def test_getattr_suggestions_no_args(self): + class A: + blech = None + def __getattr__(self, attr): + raise AttributeError() + + actual = self.get_suggestion(A(), 'bluch') + self.assertIn("blech", actual) + + class A: + blech = None + def __getattr__(self, attr): + raise AttributeError + + actual = self.get_suggestion(A(), 'bluch') + self.assertIn("blech", actual) + + def test_getattr_suggestions_invalid_args(self): + class NonStringifyClass: + __str__ = None + __repr__ = None + + class A: + blech = None + def __getattr__(self, attr): + raise AttributeError(NonStringifyClass()) + + class B: + blech = None + def __getattr__(self, attr): + raise AttributeError("Error", 23) + + class C: + blech = None + def __getattr__(self, attr): + raise AttributeError(23) + + for cls in [A, B, C]: + actual = self.get_suggestion(cls(), 'bluch') + self.assertIn("blech", actual) + + def test_getattr_suggestions_for_same_name(self): + class A: + def __dir__(self): + return ['blech'] + actual = self.get_suggestion(A(), 'blech') + self.assertNotIn("Did you mean", actual) + + def test_attribute_error_with_failing_dict(self): + class T: + bluch = 1 + def __dir__(self): + raise AttributeError("oh no!") + + actual = self.get_suggestion(T(), 'blich') + self.assertNotIn("blech", actual) + self.assertNotIn("oh no!", actual) + + def test_attribute_error_with_bad_name(self): + def raise_attribute_error_with_bad_name(): + raise AttributeError(name=12, obj=23) + + result_lines = self.get_exception( + raise_attribute_error_with_bad_name, slice_start=-1, slice_end=None + ) + self.assertNotIn("?", result_lines[-1]) + + def test_attribute_error_inside_nested_getattr(self): + class A: + bluch = 1 + + class B: + def __getattribute__(self, attr): + a = A() + return a.blich + + actual = self.get_suggestion(B(), 'something') + self.assertIn("Did you mean", actual) + self.assertIn("bluch", actual) + + def make_module(self, code): + tmpdir = Path(tempfile.mkdtemp()) + self.addCleanup(shutil.rmtree, tmpdir) + + sys.path.append(str(tmpdir)) + self.addCleanup(sys.path.pop) + + mod_name = ''.join(random.choices(string.ascii_letters, k=16)) + module = tmpdir / (mod_name + ".py") + module.write_text(code) + + return mod_name + + def get_import_from_suggestion(self, mod_dict, name): + modname = self.make_module(mod_dict) + + def callable(): + try: + exec(f"from {modname} import {name}") + except ImportError as e: + raise e from None + except Exception as e: + self.fail(f"Expected ImportError but got {type(e)}") + self.addCleanup(forget, modname) + + result_lines = self.get_exception( + callable, slice_start=-1, slice_end=None + ) + return result_lines[0] + + def test_import_from_suggestions(self): + substitution = textwrap.dedent("""\ + noise = more_noise = a = bc = None + blech = None + """) + + elimination = textwrap.dedent(""" + noise = more_noise = a = bc = None + blch = None + """) + + addition = textwrap.dedent(""" + noise = more_noise = a = bc = None + bluchin = None + """) + + substitutionOverElimination = textwrap.dedent(""" + blach = None + bluc = None + """) + + substitutionOverAddition = textwrap.dedent(""" + blach = None + bluchi = None + """) + + eliminationOverAddition = textwrap.dedent(""" + blucha = None + bluc = None + """) + + caseChangeOverSubstitution = textwrap.dedent(""" + Luch = None + fluch = None + BLuch = None + """) + + for code, suggestion in [ + (addition, "'bluchin'?"), + (substitution, "'blech'?"), + (elimination, "'blch'?"), + (addition, "'bluchin'?"), + (substitutionOverElimination, "'blach'?"), + (substitutionOverAddition, "'blach'?"), + (eliminationOverAddition, "'bluc'?"), + (caseChangeOverSubstitution, "'BLuch'?"), + ]: + actual = self.get_import_from_suggestion(code, 'bluch') + self.assertIn(suggestion, actual) + + def test_import_from_suggestions_do_not_trigger_for_long_attributes(self): + code = "blech = None" + + actual = self.get_suggestion(code, 'somethingverywrong') + self.assertNotIn("blech", actual) + + def test_import_from_error_bad_suggestions_do_not_trigger_for_small_names(self): + code = "vvv = mom = w = id = pytho = None" + + for name in ("b", "v", "m", "py"): + with self.subTest(name=name): + actual = self.get_import_from_suggestion(code, name) + self.assertNotIn("Did you mean", actual) + self.assertNotIn("'vvv'", actual) + self.assertNotIn("'mom'", actual) + self.assertNotIn("'id'", actual) + self.assertNotIn("'w'", actual) + self.assertNotIn("'pytho'", actual) + + def test_import_from_suggestions_do_not_trigger_for_big_namespaces(self): + # A module with lots of names will not be considered for suggestions. + chunks = [f"index_{index} = " for index in range(200)] + chunks.append(" None") + code = " ".join(chunks) + actual = self.get_import_from_suggestion(code, 'bluch') + self.assertNotIn("blech", actual) + + def test_import_from_error_with_bad_name(self): + def raise_attribute_error_with_bad_name(): + raise ImportError(name=12, obj=23, name_from=11) + + result_lines = self.get_exception( + raise_attribute_error_with_bad_name, slice_start=-1, slice_end=None + ) + self.assertNotIn("?", result_lines[-1]) + + def test_name_error_suggestions(self): + def Substitution(): + noise = more_noise = a = bc = None + blech = None + print(bluch) + + def Elimination(): + noise = more_noise = a = bc = None + blch = None + print(bluch) + + def Addition(): + noise = more_noise = a = bc = None + bluchin = None + print(bluch) + + def SubstitutionOverElimination(): + blach = None + bluc = None + print(bluch) + + def SubstitutionOverAddition(): + blach = None + bluchi = None + print(bluch) + + def EliminationOverAddition(): + blucha = None + bluc = None + print(bluch) + + for func, suggestion in [(Substitution, "'blech'?"), + (Elimination, "'blch'?"), + (Addition, "'bluchin'?"), + (EliminationOverAddition, "'blucha'?"), + (SubstitutionOverElimination, "'blach'?"), + (SubstitutionOverAddition, "'blach'?")]: + actual = self.get_suggestion(func) + self.assertIn(suggestion, actual) + + def test_name_error_suggestions_from_globals(self): + def func(): + print(global_for_suggestio) + actual = self.get_suggestion(func) + self.assertIn("'global_for_suggestions'?", actual) + + def test_name_error_suggestions_from_builtins(self): + def func(): + print(ZeroDivisionErrrrr) + actual = self.get_suggestion(func) + self.assertIn("'ZeroDivisionError'?", actual) + + def test_name_error_suggestions_from_builtins_when_builtins_is_module(self): + def func(): + custom_globals = globals().copy() + custom_globals["__builtins__"] = builtins + print(eval("ZeroDivisionErrrrr", custom_globals)) + actual = self.get_suggestion(func) + self.assertIn("'ZeroDivisionError'?", actual) + + def test_name_error_suggestions_do_not_trigger_for_long_names(self): + def func(): + somethingverywronghehehehehehe = None + print(somethingverywronghe) + actual = self.get_suggestion(func) + self.assertNotIn("somethingverywronghehe", actual) + + def test_name_error_bad_suggestions_do_not_trigger_for_small_names(self): + + def f_b(): + vvv = mom = w = id = pytho = None + b + + def f_v(): + vvv = mom = w = id = pytho = None + v + + def f_m(): + vvv = mom = w = id = pytho = None + m + + def f_py(): + vvv = mom = w = id = pytho = None + py + + for name, func in (("b", f_b), ("v", f_v), ("m", f_m), ("py", f_py)): + with self.subTest(name=name): + actual = self.get_suggestion(func) + self.assertNotIn("you mean", actual) + self.assertNotIn("vvv", actual) + self.assertNotIn("mom", actual) + self.assertNotIn("'id'", actual) + self.assertNotIn("'w'", actual) + self.assertNotIn("'pytho'", actual) + + def test_name_error_suggestions_do_not_trigger_for_too_many_locals(self): + def func(): + # Mutating locals() is unreliable, so we need to do it by hand + a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 = a10 = \ + a11 = a12 = a13 = a14 = a15 = a16 = a17 = a18 = a19 = a20 = \ + a21 = a22 = a23 = a24 = a25 = a26 = a27 = a28 = a29 = a30 = \ + a31 = a32 = a33 = a34 = a35 = a36 = a37 = a38 = a39 = a40 = \ + a41 = a42 = a43 = a44 = a45 = a46 = a47 = a48 = a49 = a50 = \ + a51 = a52 = a53 = a54 = a55 = a56 = a57 = a58 = a59 = a60 = \ + a61 = a62 = a63 = a64 = a65 = a66 = a67 = a68 = a69 = a70 = \ + a71 = a72 = a73 = a74 = a75 = a76 = a77 = a78 = a79 = a80 = \ + a81 = a82 = a83 = a84 = a85 = a86 = a87 = a88 = a89 = a90 = \ + a91 = a92 = a93 = a94 = a95 = a96 = a97 = a98 = a99 = a100 = \ + a101 = a102 = a103 = a104 = a105 = a106 = a107 = a108 = a109 = a110 = \ + a111 = a112 = a113 = a114 = a115 = a116 = a117 = a118 = a119 = a120 = \ + a121 = a122 = a123 = a124 = a125 = a126 = a127 = a128 = a129 = a130 = \ + a131 = a132 = a133 = a134 = a135 = a136 = a137 = a138 = a139 = a140 = \ + a141 = a142 = a143 = a144 = a145 = a146 = a147 = a148 = a149 = a150 = \ + a151 = a152 = a153 = a154 = a155 = a156 = a157 = a158 = a159 = a160 = \ + a161 = a162 = a163 = a164 = a165 = a166 = a167 = a168 = a169 = a170 = \ + a171 = a172 = a173 = a174 = a175 = a176 = a177 = a178 = a179 = a180 = \ + a181 = a182 = a183 = a184 = a185 = a186 = a187 = a188 = a189 = a190 = \ + a191 = a192 = a193 = a194 = a195 = a196 = a197 = a198 = a199 = a200 = \ + a201 = a202 = a203 = a204 = a205 = a206 = a207 = a208 = a209 = a210 = \ + a211 = a212 = a213 = a214 = a215 = a216 = a217 = a218 = a219 = a220 = \ + a221 = a222 = a223 = a224 = a225 = a226 = a227 = a228 = a229 = a230 = \ + a231 = a232 = a233 = a234 = a235 = a236 = a237 = a238 = a239 = a240 = \ + a241 = a242 = a243 = a244 = a245 = a246 = a247 = a248 = a249 = a250 = \ + a251 = a252 = a253 = a254 = a255 = a256 = a257 = a258 = a259 = a260 = \ + a261 = a262 = a263 = a264 = a265 = a266 = a267 = a268 = a269 = a270 = \ + a271 = a272 = a273 = a274 = a275 = a276 = a277 = a278 = a279 = a280 = \ + a281 = a282 = a283 = a284 = a285 = a286 = a287 = a288 = a289 = a290 = \ + a291 = a292 = a293 = a294 = a295 = a296 = a297 = a298 = a299 = a300 = \ + a301 = a302 = a303 = a304 = a305 = a306 = a307 = a308 = a309 = a310 = \ + a311 = a312 = a313 = a314 = a315 = a316 = a317 = a318 = a319 = a320 = \ + a321 = a322 = a323 = a324 = a325 = a326 = a327 = a328 = a329 = a330 = \ + a331 = a332 = a333 = a334 = a335 = a336 = a337 = a338 = a339 = a340 = \ + a341 = a342 = a343 = a344 = a345 = a346 = a347 = a348 = a349 = a350 = \ + a351 = a352 = a353 = a354 = a355 = a356 = a357 = a358 = a359 = a360 = \ + a361 = a362 = a363 = a364 = a365 = a366 = a367 = a368 = a369 = a370 = \ + a371 = a372 = a373 = a374 = a375 = a376 = a377 = a378 = a379 = a380 = \ + a381 = a382 = a383 = a384 = a385 = a386 = a387 = a388 = a389 = a390 = \ + a391 = a392 = a393 = a394 = a395 = a396 = a397 = a398 = a399 = a400 = \ + a401 = a402 = a403 = a404 = a405 = a406 = a407 = a408 = a409 = a410 = \ + a411 = a412 = a413 = a414 = a415 = a416 = a417 = a418 = a419 = a420 = \ + a421 = a422 = a423 = a424 = a425 = a426 = a427 = a428 = a429 = a430 = \ + a431 = a432 = a433 = a434 = a435 = a436 = a437 = a438 = a439 = a440 = \ + a441 = a442 = a443 = a444 = a445 = a446 = a447 = a448 = a449 = a450 = \ + a451 = a452 = a453 = a454 = a455 = a456 = a457 = a458 = a459 = a460 = \ + a461 = a462 = a463 = a464 = a465 = a466 = a467 = a468 = a469 = a470 = \ + a471 = a472 = a473 = a474 = a475 = a476 = a477 = a478 = a479 = a480 = \ + a481 = a482 = a483 = a484 = a485 = a486 = a487 = a488 = a489 = a490 = \ + a491 = a492 = a493 = a494 = a495 = a496 = a497 = a498 = a499 = a500 = \ + a501 = a502 = a503 = a504 = a505 = a506 = a507 = a508 = a509 = a510 = \ + a511 = a512 = a513 = a514 = a515 = a516 = a517 = a518 = a519 = a520 = \ + a521 = a522 = a523 = a524 = a525 = a526 = a527 = a528 = a529 = a530 = \ + a531 = a532 = a533 = a534 = a535 = a536 = a537 = a538 = a539 = a540 = \ + a541 = a542 = a543 = a544 = a545 = a546 = a547 = a548 = a549 = a550 = \ + a551 = a552 = a553 = a554 = a555 = a556 = a557 = a558 = a559 = a560 = \ + a561 = a562 = a563 = a564 = a565 = a566 = a567 = a568 = a569 = a570 = \ + a571 = a572 = a573 = a574 = a575 = a576 = a577 = a578 = a579 = a580 = \ + a581 = a582 = a583 = a584 = a585 = a586 = a587 = a588 = a589 = a590 = \ + a591 = a592 = a593 = a594 = a595 = a596 = a597 = a598 = a599 = a600 = \ + a601 = a602 = a603 = a604 = a605 = a606 = a607 = a608 = a609 = a610 = \ + a611 = a612 = a613 = a614 = a615 = a616 = a617 = a618 = a619 = a620 = \ + a621 = a622 = a623 = a624 = a625 = a626 = a627 = a628 = a629 = a630 = \ + a631 = a632 = a633 = a634 = a635 = a636 = a637 = a638 = a639 = a640 = \ + a641 = a642 = a643 = a644 = a645 = a646 = a647 = a648 = a649 = a650 = \ + a651 = a652 = a653 = a654 = a655 = a656 = a657 = a658 = a659 = a660 = \ + a661 = a662 = a663 = a664 = a665 = a666 = a667 = a668 = a669 = a670 = \ + a671 = a672 = a673 = a674 = a675 = a676 = a677 = a678 = a679 = a680 = \ + a681 = a682 = a683 = a684 = a685 = a686 = a687 = a688 = a689 = a690 = \ + a691 = a692 = a693 = a694 = a695 = a696 = a697 = a698 = a699 = a700 = \ + a701 = a702 = a703 = a704 = a705 = a706 = a707 = a708 = a709 = a710 = \ + a711 = a712 = a713 = a714 = a715 = a716 = a717 = a718 = a719 = a720 = \ + a721 = a722 = a723 = a724 = a725 = a726 = a727 = a728 = a729 = a730 = \ + a731 = a732 = a733 = a734 = a735 = a736 = a737 = a738 = a739 = a740 = \ + a741 = a742 = a743 = a744 = a745 = a746 = a747 = a748 = a749 = a750 = \ + a751 = a752 = a753 = a754 = a755 = a756 = a757 = a758 = a759 = a760 = \ + a761 = a762 = a763 = a764 = a765 = a766 = a767 = a768 = a769 = a770 = \ + a771 = a772 = a773 = a774 = a775 = a776 = a777 = a778 = a779 = a780 = \ + a781 = a782 = a783 = a784 = a785 = a786 = a787 = a788 = a789 = a790 = \ + a791 = a792 = a793 = a794 = a795 = a796 = a797 = a798 = a799 = a800 \ + = None + print(a0) + + actual = self.get_suggestion(func) + self.assertNotRegex(actual, r"NameError.*a1") + + def test_name_error_with_custom_exceptions(self): + def func(): + blech = None + raise NameError() + + actual = self.get_suggestion(func) + self.assertNotIn("blech", actual) + + def func(): + blech = None + raise NameError + + actual = self.get_suggestion(func) + self.assertNotIn("blech", actual) + + def test_name_error_with_instance(self): + class A: + def __init__(self): + self.blech = None + def foo(self): + blich = 1 + x = blech + + instance = A() + actual = self.get_suggestion(instance.foo) + self.assertIn("self.blech", actual) + + def test_unbound_local_error_with_instance(self): + class A: + def __init__(self): + self.blech = None + def foo(self): + blich = 1 + x = blech + blech = 1 + + instance = A() + actual = self.get_suggestion(instance.foo) + self.assertNotIn("self.blech", actual) + + def test_unbound_local_error_does_not_match(self): + def func(): + something = 3 + print(somethong) + somethong = 3 + + actual = self.get_suggestion(func) + self.assertNotIn("something", actual) + + def test_name_error_for_stdlib_modules(self): + def func(): + stream = io.StringIO() + + actual = self.get_suggestion(func) + self.assertIn("forget to import 'io'", actual) + + def test_name_error_for_private_stdlib_modules(self): + def func(): + stream = _io.StringIO() + + actual = self.get_suggestion(func) + self.assertIn("forget to import '_io'", actual) + + + +class PurePythonSuggestionFormattingTests( + PurePythonExceptionFormattingMixin, + SuggestionFormattingTestBase, + unittest.TestCase, +): + """ + Same set of tests as above using the pure Python implementation of + traceback printing in traceback.py. + """ + + +@cpython_only +class CPythonSuggestionFormattingTests( + CAPIExceptionFormattingMixin, + SuggestionFormattingTestBase, + unittest.TestCase, +): + """ + Same set of tests as above but with Python's internal traceback printing. + """ + + class MiscTest(unittest.TestCase): def test_all(self): @@ -2439,6 +3476,59 @@ class MiscTest(unittest.TestCase): expected.add(name) self.assertCountEqual(traceback.__all__, expected) + def test_levenshtein_distance(self): + # copied from _testinternalcapi.test_edit_cost + # to also exercise the Python implementation + + def CHECK(a, b, expected): + actual = traceback._levenshtein_distance(a, b, 4044) + self.assertEqual(actual, expected) + + CHECK("", "", 0) + CHECK("", "a", 2) + CHECK("a", "A", 1) + CHECK("Apple", "Aple", 2) + CHECK("Banana", "B@n@n@", 6) + CHECK("Cherry", "Cherry!", 2) + CHECK("---0---", "------", 2) + CHECK("abc", "y", 6) + CHECK("aa", "bb", 4) + CHECK("aaaaa", "AAAAA", 5) + CHECK("wxyz", "wXyZ", 2) + CHECK("wxyz", "wXyZ123", 8) + CHECK("Python", "Java", 12) + CHECK("Java", "C#", 8) + CHECK("AbstractFoobarManager", "abstract_foobar_manager", 3+2*2) + CHECK("CPython", "PyPy", 10) + CHECK("CPython", "pypy", 11) + CHECK("AttributeError", "AttributeErrop", 2) + CHECK("AttributeError", "AttributeErrorTests", 10) + CHECK("ABA", "AAB", 4) + + def test_levenshtein_distance_short_circuit(self): + if not LEVENSHTEIN_DATA_FILE.is_file(): + self.fail( + f"{LEVENSHTEIN_DATA_FILE} is missing." + f" Run `make regen-test-levenshtein`" + ) + + with LEVENSHTEIN_DATA_FILE.open("r") as f: + examples = json.load(f) + for a, b, expected in examples: + res1 = traceback._levenshtein_distance(a, b, 1000) + self.assertEqual(res1, expected, msg=(a, b)) + + for threshold in [expected, expected + 1, expected + 2]: + # big enough thresholds shouldn't change the result + res2 = traceback._levenshtein_distance(a, b, threshold) + self.assertEqual(res2, expected, msg=(a, b, threshold)) + + for threshold in range(expected): + # for small thresholds, the only piece of information + # we receive is "strings not close enough". + res3 = traceback._levenshtein_distance(a, b, threshold) + self.assertGreater(res3, threshold, msg=(a, b, threshold)) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py index 82be98dfd8f..94bcee302fe 100644 --- a/Lib/test/test_tracemalloc.py +++ b/Lib/test/test_tracemalloc.py @@ -346,7 +346,7 @@ class TestTracemallocEnabled(unittest.TestCase): # everything is fine return 0 - @unittest.skipUnless(hasattr(os, 'fork'), 'need os.fork()') + @support.requires_fork() def test_fork(self): # check that tracemalloc is still working after fork pid = os.fork() @@ -360,6 +360,20 @@ class TestTracemallocEnabled(unittest.TestCase): else: support.wait_process(pid, exitcode=0) + def test_no_incomplete_frames(self): + tracemalloc.stop() + tracemalloc.start(8) + + def f(x): + def g(): + return x + return g + + obj = f(0).__closure__[0] + traceback = tracemalloc.get_object_traceback(obj) + self.assertIn("test_tracemalloc", traceback[-1].filename) + self.assertNotIn("test_tracemalloc", traceback[-2].filename) + class TestSnapshot(unittest.TestCase): maxDiff = 4000 diff --git a/Lib/test/test_ttk_guionly.py b/Lib/test/test_ttk/__init__.py similarity index 72% rename from Lib/test/test_ttk_guionly.py rename to Lib/test/test_ttk/__init__.py index 8f59839d066..7ee7ffbd6d7 100644 --- a/Lib/test/test_ttk_guionly.py +++ b/Lib/test/test_ttk/__init__.py @@ -1,13 +1,19 @@ +import os.path import unittest from test import support from test.support import import_helper + +if support.check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("Tests involving libX11 can SEGFAULT on ASAN/MSAN builds") + # Skip this test if _tkinter wasn't built. import_helper.import_module('_tkinter') # Skip test if tk cannot be initialized. support.requires('gui') + import tkinter from _tkinter import TclError from tkinter import ttk @@ -28,9 +34,6 @@ def setUpModule(): root.destroy() del root -def load_tests(loader, tests, pattern): - return loader.discover('tkinter.test.test_ttk') - -if __name__ == '__main__': - unittest.main() +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_ttk/__main__.py b/Lib/test/test_ttk/__main__.py new file mode 100644 index 00000000000..40a23a297ec --- /dev/null +++ b/Lib/test/test_ttk/__main__.py @@ -0,0 +1,4 @@ +from . import load_tests +import unittest + +unittest.main() diff --git a/Lib/tkinter/test/test_ttk/test_extensions.py b/Lib/test/test_ttk/test_extensions.py similarity index 99% rename from Lib/tkinter/test/test_ttk/test_extensions.py rename to Lib/test/test_ttk/test_extensions.py index 1220c4831c5..6135c49701f 100644 --- a/Lib/tkinter/test/test_ttk/test_extensions.py +++ b/Lib/test/test_ttk/test_extensions.py @@ -3,7 +3,7 @@ import unittest import tkinter from tkinter import ttk from test.support import requires, gc_collect -from tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest +from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest requires('gui') diff --git a/Lib/tkinter/test/test_ttk/test_style.py b/Lib/test/test_ttk/test_style.py similarity index 96% rename from Lib/tkinter/test/test_ttk/test_style.py rename to Lib/test/test_ttk/test_style.py index a33c24ac55b..0ec95cf6b5f 100644 --- a/Lib/tkinter/test/test_ttk/test_style.py +++ b/Lib/test/test_ttk/test_style.py @@ -4,7 +4,7 @@ import tkinter from tkinter import ttk from test import support from test.support import requires -from tkinter.test.support import AbstractTkTest +from test.test_tkinter.support import AbstractTkTest, get_tk_patchlevel requires('gui') @@ -170,6 +170,8 @@ class StyleTest(AbstractTkTest, unittest.TestCase): newname = f'C.{name}' self.assertEqual(style.map(newname), {}) style.map(newname, **default) + if theme == 'alt' and name == '.' and get_tk_patchlevel() < (8, 6, 1): + default['embossed'] = [('disabled', '1')] self.assertEqual(style.map(newname), default) for key, value in default.items(): self.assertEqual(style.map(newname, key), value) diff --git a/Lib/tkinter/test/test_ttk/test_widgets.py b/Lib/test/test_ttk/test_widgets.py similarity index 98% rename from Lib/tkinter/test/test_ttk/test_widgets.py rename to Lib/test/test_ttk/test_widgets.py index 1cb7e74c66e..6f47ccb8e8b 100644 --- a/Lib/tkinter/test/test_ttk/test_widgets.py +++ b/Lib/test/test_ttk/test_widgets.py @@ -5,9 +5,9 @@ from test.support import requires, gc_collect import sys from test.test_ttk_textonly import MockTclObj -from tkinter.test.support import (AbstractTkTest, tcl_version, get_tk_patchlevel, +from test.test_tkinter.support import (AbstractTkTest, tcl_version, get_tk_patchlevel, simulate_mouse_click, AbstractDefaultRootTest) -from tkinter.test.widget_tests import (add_standard_options, noconv, +from test.test_tkinter.widget_tests import (add_standard_options, AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests, setUpModule) @@ -110,7 +110,7 @@ class WidgetTest(AbstractTkTest, unittest.TestCase): class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests): - _conv_pixels = noconv + _conv_pixels = False @add_standard_options(StandardTtkOptionsTests) @@ -193,7 +193,7 @@ class LabelTest(AbstractLabelTest, unittest.TestCase): 'takefocus', 'text', 'textvariable', 'underline', 'width', 'wraplength', ) - _conv_pixels = noconv + _conv_pixels = False def create(self, **kwargs): return ttk.Label(self.root, **kwargs) @@ -275,6 +275,21 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase): self.assertEqual(cbtn['offvalue'], cbtn.tk.globalgetvar(cbtn['variable'])) + def test_unique_variables(self): + frames = [] + buttons = [] + for i in range(2): + f = ttk.Frame(self.root) + f.pack() + frames.append(f) + for j in 'AB': + b = ttk.Checkbutton(f, text=j) + b.pack() + buttons.append(b) + variables = [str(b['variable']) for b in buttons] + print(variables) + self.assertEqual(len(set(variables)), 4, variables) + @add_standard_options(IntegerSizeTests, StandardTtkOptionsTests) class EntryTest(AbstractWidgetTest, unittest.TestCase): @@ -473,8 +488,7 @@ class ComboboxTest(EntryTest, unittest.TestCase): self.assertEqual(self.combo.get(), getval) self.assertEqual(self.combo.current(), currval) - self.assertEqual(self.combo['values'], - () if tcl_version < (8, 5) else '') + self.assertEqual(self.combo['values'], '') check_get_current('', -1) self.checkParam(self.combo, 'values', 'mon tue wed thur', @@ -741,7 +755,7 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase): 'class', 'command', 'cursor', 'from', 'length', 'orient', 'style', 'takefocus', 'to', 'value', 'variable', ) - _conv_pixels = noconv + _conv_pixels = False default_orient = 'horizontal' def setUp(self): @@ -848,7 +862,7 @@ class ProgressbarTest(AbstractWidgetTest, unittest.TestCase): 'mode', 'maximum', 'phase', 'style', 'takefocus', 'value', 'variable', ) - _conv_pixels = noconv + _conv_pixels = False default_orient = 'horizontal' def create(self, **kwargs): @@ -1231,8 +1245,7 @@ class SpinboxTest(EntryTest, unittest.TestCase): self.assertEqual(self.spin.get(), '1') def test_configure_values(self): - self.assertEqual(self.spin['values'], - () if tcl_version < (8, 5) else '') + self.assertEqual(self.spin['values'], '') self.checkParam(self.spin, 'values', 'mon tue wed thur', expected=('mon', 'tue', 'wed', 'thur')) self.checkParam(self.spin, 'values', ('mon', 'tue', 'wed', 'thur')) @@ -1316,7 +1329,7 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase): def test_configure_height(self): widget = self.create() self.checkPixelsParam(widget, 'height', 100, -100, 0, '3c', conv=False) - self.checkPixelsParam(widget, 'height', 101.2, 102.6, conv=noconv) + self.checkPixelsParam(widget, 'height', 101.2, 102.6, conv=False) def test_configure_selectmode(self): widget = self.create() diff --git a/Lib/test/test_turtle.py b/Lib/test/test_turtle.py index 8d6d3a7bd80..95af84e3779 100644 --- a/Lib/test/test_turtle.py +++ b/Lib/test/test_turtle.py @@ -235,7 +235,7 @@ class TestVec2D(VectorComparisonMixin, unittest.TestCase): self.assertVectorsAlmostEqual(-vec, expected) def test_distance(self): - self.assertEqual(abs(Vec2D(6, 8)), 10) + self.assertAlmostEqual(abs(Vec2D(6, 8)), 10) self.assertEqual(abs(Vec2D(0, 0)), 0) self.assertAlmostEqual(abs(Vec2D(2.5, 6)), 6.5) diff --git a/Lib/test/test_type_comments.py b/Lib/test/test_type_comments.py index 71d1430dbc9..8db7394d151 100644 --- a/Lib/test/test_type_comments.py +++ b/Lib/test/test_type_comments.py @@ -1,7 +1,6 @@ import ast import sys import unittest -from test import support funcdef = """\ @@ -323,7 +322,7 @@ class TypeCommentTests(unittest.TestCase): self.assertEqual(tree.type_ignores, []) def test_longargs(self): - for tree in self.parse_all(longargs): + for tree in self.parse_all(longargs, minver=8): for t in tree.body: # The expected args are encoded in the function name todo = set(t.name[1:]) diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index b1218abc8af..af095632a36 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -524,18 +524,16 @@ class TypesTests(unittest.TestCase): self.assertRaises(TypeError, 3.0.__format__, None) self.assertRaises(TypeError, 3.0.__format__, 0) - # other format specifiers shouldn't work on floats, - # in particular int specifiers - for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] + - [chr(x) for x in range(ord('A'), ord('Z')+1)]): - if not format_spec in 'eEfFgGn%': - self.assertRaises(ValueError, format, 0.0, format_spec) - self.assertRaises(ValueError, format, 1.0, format_spec) - self.assertRaises(ValueError, format, -1.0, format_spec) - self.assertRaises(ValueError, format, 1e100, format_spec) - self.assertRaises(ValueError, format, -1e100, format_spec) - self.assertRaises(ValueError, format, 1e-100, format_spec) - self.assertRaises(ValueError, format, -1e-100, format_spec) + # confirm format options expected to fail on floats, such as integer + # presentation types + for format_spec in 'sbcdoxX': + self.assertRaises(ValueError, format, 0.0, format_spec) + self.assertRaises(ValueError, format, 1.0, format_spec) + self.assertRaises(ValueError, format, -1.0, format_spec) + self.assertRaises(ValueError, format, 1e100, format_spec) + self.assertRaises(ValueError, format, -1e100, format_spec) + self.assertRaises(ValueError, format, 1e-100, format_spec) + self.assertRaises(ValueError, format, -1e-100, format_spec) # Alternate float formatting test(1.0, '.0e', '1e+00') @@ -599,6 +597,12 @@ class TypesTests(unittest.TestCase): self.assertIsInstance(object.__lt__, types.WrapperDescriptorType) self.assertIsInstance(int.__lt__, types.WrapperDescriptorType) + def test_dunder_get_signature(self): + sig = inspect.signature(object.__init__.__get__) + self.assertEqual(list(sig.parameters), ["instance", "owner"]) + # gh-93021: Second parameter is optional + self.assertIs(sig.parameters["owner"].default, None) + def test_method_wrapper_types(self): self.assertIsInstance(object().__init__, types.MethodWrapperType) self.assertIsInstance(object().__str__, types.MethodWrapperType) @@ -624,6 +628,14 @@ class TypesTests(unittest.TestCase): def test_none_type(self): self.assertIsInstance(None, types.NoneType) + def test_traceback_and_frame_types(self): + try: + raise OSError + except OSError as e: + exc = e + self.assertIsInstance(exc.__traceback__, types.TracebackType) + self.assertIsInstance(exc.__traceback__.tb_frame, types.FrameType) + class UnionTests(unittest.TestCase): @@ -695,22 +707,62 @@ class UnionTests(unittest.TestCase): self.assertEqual(hash(int | str), hash(str | int)) self.assertEqual(hash(int | str), hash(typing.Union[int, str])) - def test_instancecheck(self): - x = int | str - self.assertIsInstance(1, x) - self.assertIsInstance(True, x) - self.assertIsInstance('a', x) - self.assertNotIsInstance(None, x) - self.assertTrue(issubclass(int, x)) - self.assertTrue(issubclass(bool, x)) - self.assertTrue(issubclass(str, x)) - self.assertFalse(issubclass(type(None), x)) - x = int | None - self.assertIsInstance(None, x) - self.assertTrue(issubclass(type(None), x)) - x = int | collections.abc.Mapping - self.assertIsInstance({}, x) - self.assertTrue(issubclass(dict, x)) + def test_instancecheck_and_subclasscheck(self): + for x in (int | str, typing.Union[int, str]): + with self.subTest(x=x): + self.assertIsInstance(1, x) + self.assertIsInstance(True, x) + self.assertIsInstance('a', x) + self.assertNotIsInstance(None, x) + self.assertTrue(issubclass(int, x)) + self.assertTrue(issubclass(bool, x)) + self.assertTrue(issubclass(str, x)) + self.assertFalse(issubclass(type(None), x)) + + for x in (int | None, typing.Union[int, None]): + with self.subTest(x=x): + self.assertIsInstance(None, x) + self.assertTrue(issubclass(type(None), x)) + + for x in ( + int | collections.abc.Mapping, + typing.Union[int, collections.abc.Mapping], + ): + with self.subTest(x=x): + self.assertIsInstance({}, x) + self.assertNotIsInstance((), x) + self.assertTrue(issubclass(dict, x)) + self.assertFalse(issubclass(list, x)) + + def test_instancecheck_and_subclasscheck_order(self): + T = typing.TypeVar('T') + + will_resolve = ( + int | T, + typing.Union[int, T], + ) + for x in will_resolve: + with self.subTest(x=x): + self.assertIsInstance(1, x) + self.assertTrue(issubclass(int, x)) + + wont_resolve = ( + T | int, + typing.Union[T, int], + ) + for x in wont_resolve: + with self.subTest(x=x): + with self.assertRaises(TypeError): + issubclass(int, x) + with self.assertRaises(TypeError): + isinstance(1, x) + + for x in (*will_resolve, *wont_resolve): + with self.subTest(x=x): + with self.assertRaises(TypeError): + issubclass(object, x) + with self.assertRaises(TypeError): + isinstance(object(), x) def test_bad_instancecheck(self): class BadMeta(type): @@ -827,7 +879,7 @@ class UnionTests(unittest.TestCase): T = typing.TypeVar("T") x = int | T with self.assertRaises(TypeError): - x[42] + x[int, str] def test_or_type_operator_with_forward(self): T = typing.TypeVar('T') @@ -905,9 +957,9 @@ class UnionTests(unittest.TestCase): with self.assertRaises(ZeroDivisionError): list[int] | list[bt] - union_ga = (int | list[str], int | collections.abc.Callable[..., str], - int | d) - # Raise error when isinstance(type, type | genericalias) + union_ga = (list[str] | int, collections.abc.Callable[..., str] | int, + d | int) + # Raise error when isinstance(type, genericalias | type) for type_ in union_ga: with self.subTest(f"check isinstance/issubclass is invalid for {type_}"): with self.assertRaises(TypeError): @@ -1151,6 +1203,16 @@ class MappingProxyTests(unittest.TestCase): self.assertDictEqual(mapping, {'a': 0, 'b': 1, 'c': 2}) self.assertDictEqual(other, {'c': 3, 'p': 0}) + def test_hash(self): + class HashableDict(dict): + def __hash__(self): + return 3844817361 + view = self.mappingproxy({'a': 1, 'b': 2}) + self.assertRaises(TypeError, hash, view) + mapping = HashableDict({'a': 1, 'b': 2}) + view = self.mappingproxy(mapping) + self.assertEqual(hash(view), hash(mapping)) + class ClassCreationTests(unittest.TestCase): @@ -1236,6 +1298,17 @@ class ClassCreationTests(unittest.TestCase): self.assertEqual(D.__orig_bases__, (c,)) self.assertEqual(D.__mro__, (D, A, object)) + def test_new_class_with_mro_entry_genericalias(self): + L1 = types.new_class('L1', (typing.List[int],), {}) + self.assertEqual(L1.__bases__, (list, typing.Generic)) + self.assertEqual(L1.__orig_bases__, (typing.List[int],)) + self.assertEqual(L1.__mro__, (L1, list, typing.Generic, object)) + + L2 = types.new_class('L2', (list[int],), {}) + self.assertEqual(L2.__bases__, (list,)) + self.assertEqual(L2.__orig_bases__, (list[int],)) + self.assertEqual(L2.__mro__, (L2, list, object)) + def test_new_class_with_mro_entry_none(self): class A: pass class B: pass @@ -1351,6 +1424,11 @@ class ClassCreationTests(unittest.TestCase): for bases in [x, y, z, t]: self.assertIs(types.resolve_bases(bases), bases) + def test_resolve_bases_with_mro_entry(self): + self.assertEqual(types.resolve_bases((typing.List[int],)), + (list, typing.Generic)) + self.assertEqual(types.resolve_bases((list[int],)), (list,)) + def test_metaclass_derivation(self): # issue1294232: correct metaclass calculation new_calls = [] # to check the order of __new__ calls @@ -1994,7 +2072,7 @@ class CoroutineTests(unittest.TestCase): wrapper = foo() wrapper.send(None) with self.assertRaisesRegex(Exception, 'ham'): - wrapper.throw(Exception, Exception('ham')) + wrapper.throw(Exception('ham')) # decorate foo second time foo = types.coroutine(foo) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 90d6bea59f8..5aa49bb0e24 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1,39 +1,48 @@ import contextlib import collections +from collections import defaultdict +from functools import lru_cache, wraps +import inspect +import itertools import pickle import re import sys import warnings from unittest import TestCase, main, skipUnless, skip +from unittest.mock import patch from copy import copy, deepcopy -from typing import Any, NoReturn -from typing import TypeVar, AnyStr +from typing import Any, NoReturn, Never, assert_never +from typing import overload, get_overloads, clear_overloads +from typing import TypeVar, TypeVarTuple, Unpack, AnyStr from typing import T, KT, VT # Not in __all__. from typing import Union, Optional, Literal from typing import Tuple, List, Dict, MutableMapping from typing import Callable from typing import Generic, ClassVar, Final, final, Protocol -from typing import cast, runtime_checkable +from typing import assert_type, cast, runtime_checkable from typing import get_type_hints from typing import get_origin, get_args from typing import is_typeddict +from typing import reveal_type +from typing import dataclass_transform from typing import no_type_check, no_type_check_decorator from typing import Type -from typing import NewType -from typing import NamedTuple, TypedDict +from typing import NamedTuple, NotRequired, Required, TypedDict from typing import IO, TextIO, BinaryIO from typing import Pattern, Match from typing import Annotated, ForwardRef +from typing import Self, LiteralString from typing import TypeAlias from typing import ParamSpec, Concatenate, ParamSpecArgs, ParamSpecKwargs from typing import TypeGuard import abc +import textwrap import typing import weakref import types -from test.support import import_helper +from test.support import import_helper, captured_stderr, cpython_only from test import mod_generics_cache from test import _typed_dict_helper @@ -42,6 +51,10 @@ py_typing = import_helper.import_fresh_module('typing', blocked=['_typing']) c_typing = import_helper.import_fresh_module('typing', fresh=['_typing']) +CANNOT_SUBCLASS_TYPE = 'Cannot subclass special typing classes' +CANNOT_SUBCLASS_INSTANCE = 'Cannot subclass an instance of %s' + + class BaseTestCase(TestCase): def assertIsSubclass(self, cls, class_or_tuple, msg=None): @@ -63,6 +76,18 @@ class BaseTestCase(TestCase): f() +def all_pickle_protocols(test_func): + """Runs `test_func` with various values for `proto` argument.""" + + @wraps(test_func) + def wrapper(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(pickle_proto=proto): + test_func(self, proto=proto) + + return wrapper + + class Employee: pass @@ -85,28 +110,36 @@ class AnyTests(BaseTestCase): with self.assertRaises(TypeError): isinstance(42, Any) - def test_any_subclass_type_error(self): - with self.assertRaises(TypeError): - issubclass(Employee, Any) - with self.assertRaises(TypeError): - issubclass(Any, Employee) - def test_repr(self): self.assertEqual(repr(Any), 'typing.Any') + class Sub(Any): pass + self.assertEqual( + repr(Sub), + ".Sub'>", + ) + def test_errors(self): with self.assertRaises(TypeError): issubclass(42, Any) with self.assertRaises(TypeError): Any[int] # Any is not a generic type. - def test_cannot_subclass(self): - with self.assertRaises(TypeError): - class A(Any): - pass - with self.assertRaises(TypeError): - class A(type(Any)): - pass + def test_can_subclass(self): + class Mock(Any): pass + self.assertTrue(issubclass(Mock, Any)) + self.assertIsInstance(Mock(), Mock) + + class Something: pass + self.assertFalse(issubclass(Something, Any)) + self.assertNotIsInstance(Something(), Mock) + + class MockSomething(Something, Mock): pass + self.assertTrue(issubclass(MockSomething, Any)) + ms = MockSomething() + self.assertIsInstance(ms, MockSomething) + self.assertIsInstance(ms, Something) + self.assertIsInstance(ms, Mock) def test_cannot_instantiate(self): with self.assertRaises(TypeError): @@ -121,42 +154,215 @@ class AnyTests(BaseTestCase): typing.IO[Any] -class NoReturnTests(BaseTestCase): +class BottomTypeTestsMixin: + bottom_type: ClassVar[Any] - def test_noreturn_instance_type_error(self): - with self.assertRaises(TypeError): - isinstance(42, NoReturn) + def test_equality(self): + self.assertEqual(self.bottom_type, self.bottom_type) + self.assertIs(self.bottom_type, self.bottom_type) + self.assertNotEqual(self.bottom_type, None) - def test_noreturn_subclass_type_error(self): - with self.assertRaises(TypeError): - issubclass(Employee, NoReturn) - with self.assertRaises(TypeError): - issubclass(NoReturn, Employee) + def test_get_origin(self): + self.assertIs(get_origin(self.bottom_type), None) - def test_repr(self): - self.assertEqual(repr(NoReturn), 'typing.NoReturn') + def test_instance_type_error(self): + with self.assertRaises(TypeError): + isinstance(42, self.bottom_type) + + def test_subclass_type_error(self): + with self.assertRaises(TypeError): + issubclass(Employee, self.bottom_type) + with self.assertRaises(TypeError): + issubclass(NoReturn, self.bottom_type) def test_not_generic(self): with self.assertRaises(TypeError): - NoReturn[int] + self.bottom_type[int] def test_cannot_subclass(self): - with self.assertRaises(TypeError): - class A(NoReturn): + with self.assertRaisesRegex(TypeError, + 'Cannot subclass ' + re.escape(str(self.bottom_type))): + class A(self.bottom_type): pass - with self.assertRaises(TypeError): - class A(type(NoReturn)): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class A(type(self.bottom_type)): pass def test_cannot_instantiate(self): with self.assertRaises(TypeError): - NoReturn() + self.bottom_type() with self.assertRaises(TypeError): - type(NoReturn)() + type(self.bottom_type)() +class NoReturnTests(BottomTypeTestsMixin, BaseTestCase): + bottom_type = NoReturn + + def test_repr(self): + self.assertEqual(repr(NoReturn), 'typing.NoReturn') + + def test_get_type_hints(self): + def some(arg: NoReturn) -> NoReturn: ... + def some_str(arg: 'NoReturn') -> 'typing.NoReturn': ... + + expected = {'arg': NoReturn, 'return': NoReturn} + for target in [some, some_str]: + with self.subTest(target=target): + self.assertEqual(gth(target), expected) + + def test_not_equality(self): + self.assertNotEqual(NoReturn, Never) + self.assertNotEqual(Never, NoReturn) + + +class NeverTests(BottomTypeTestsMixin, BaseTestCase): + bottom_type = Never + + def test_repr(self): + self.assertEqual(repr(Never), 'typing.Never') + + def test_get_type_hints(self): + def some(arg: Never) -> Never: ... + def some_str(arg: 'Never') -> 'typing.Never': ... + + expected = {'arg': Never, 'return': Never} + for target in [some, some_str]: + with self.subTest(target=target): + self.assertEqual(gth(target), expected) + + +class AssertNeverTests(BaseTestCase): + def test_exception(self): + with self.assertRaises(AssertionError): + assert_never(None) + + value = "some value" + with self.assertRaisesRegex(AssertionError, value): + assert_never(value) + + # Make sure a huge value doesn't get printed in its entirety + huge_value = "a" * 10000 + with self.assertRaises(AssertionError) as cm: + assert_never(huge_value) + self.assertLess( + len(cm.exception.args[0]), + typing._ASSERT_NEVER_REPR_MAX_LENGTH * 2, + ) + + +class SelfTests(BaseTestCase): + def test_equality(self): + self.assertEqual(Self, Self) + self.assertIs(Self, Self) + self.assertNotEqual(Self, None) + + def test_basics(self): + class Foo: + def bar(self) -> Self: ... + class FooStr: + def bar(self) -> 'Self': ... + class FooStrTyping: + def bar(self) -> 'typing.Self': ... + + for target in [Foo, FooStr, FooStrTyping]: + with self.subTest(target=target): + self.assertEqual(gth(target.bar), {'return': Self}) + self.assertIs(get_origin(Self), None) + + def test_repr(self): + self.assertEqual(repr(Self), 'typing.Self') + + def test_cannot_subscript(self): + with self.assertRaises(TypeError): + Self[int] + + def test_cannot_subclass(self): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class C(type(Self)): + pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.Self'): + class C(Self): + pass + + def test_cannot_init(self): + with self.assertRaises(TypeError): + Self() + with self.assertRaises(TypeError): + type(Self)() + + def test_no_isinstance(self): + with self.assertRaises(TypeError): + isinstance(1, Self) + with self.assertRaises(TypeError): + issubclass(int, Self) + + def test_alias(self): + # TypeAliases are not actually part of the spec + alias_1 = Tuple[Self, Self] + alias_2 = List[Self] + alias_3 = ClassVar[Self] + self.assertEqual(get_args(alias_1), (Self, Self)) + self.assertEqual(get_args(alias_2), (Self,)) + self.assertEqual(get_args(alias_3), (Self,)) + + +class LiteralStringTests(BaseTestCase): + def test_equality(self): + self.assertEqual(LiteralString, LiteralString) + self.assertIs(LiteralString, LiteralString) + self.assertNotEqual(LiteralString, None) + + def test_basics(self): + class Foo: + def bar(self) -> LiteralString: ... + class FooStr: + def bar(self) -> 'LiteralString': ... + class FooStrTyping: + def bar(self) -> 'typing.LiteralString': ... + + for target in [Foo, FooStr, FooStrTyping]: + with self.subTest(target=target): + self.assertEqual(gth(target.bar), {'return': LiteralString}) + self.assertIs(get_origin(LiteralString), None) + + def test_repr(self): + self.assertEqual(repr(LiteralString), 'typing.LiteralString') + + def test_cannot_subscript(self): + with self.assertRaises(TypeError): + LiteralString[int] + + def test_cannot_subclass(self): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class C(type(LiteralString)): + pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.LiteralString'): + class C(LiteralString): + pass + + def test_cannot_init(self): + with self.assertRaises(TypeError): + LiteralString() + with self.assertRaises(TypeError): + type(LiteralString)() + + def test_no_isinstance(self): + with self.assertRaises(TypeError): + isinstance(1, LiteralString) + with self.assertRaises(TypeError): + issubclass(int, LiteralString) + + def test_alias(self): + alias_1 = Tuple[LiteralString, LiteralString] + alias_2 = List[LiteralString] + alias_3 = ClassVar[LiteralString] + self.assertEqual(get_args(alias_1), (LiteralString, LiteralString)) + self.assertEqual(get_args(alias_2), (LiteralString,)) + self.assertEqual(get_args(alias_3), (LiteralString,)) + class TypeVarTests(BaseTestCase): - def test_basic_plain(self): T = TypeVar('T') # T equals itself. @@ -222,15 +428,13 @@ class TypeVarTests(BaseTestCase): self.assertNotEqual(TypeVar('T'), TypeVar('T')) self.assertNotEqual(TypeVar('T', int, str), TypeVar('T', int, str)) - def test_cannot_subclass_vars(self): - with self.assertRaises(TypeError): - class V(TypeVar('T')): - pass - - def test_cannot_subclass_var_itself(self): - with self.assertRaises(TypeError): - class V(TypeVar): - pass + def test_cannot_subclass(self): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class V(TypeVar): pass + T = TypeVar("T") + with self.assertRaisesRegex(TypeError, + CANNOT_SUBCLASS_INSTANCE % 'TypeVar'): + class V(T): pass def test_cannot_instantiate_vars(self): with self.assertRaises(TypeError): @@ -238,7 +442,7 @@ class TypeVarTests(BaseTestCase): def test_bound_errors(self): with self.assertRaises(TypeError): - TypeVar('X', bound=42) + TypeVar('X', bound=Union) with self.assertRaises(TypeError): TypeVar('X', str, float, bound=Employee) @@ -253,6 +457,1172 @@ class TypeVarTests(BaseTestCase): with self.assertRaises(ValueError): TypeVar('T', covariant=True, contravariant=True) + def test_var_substitution(self): + T = TypeVar('T') + subst = T.__typing_subst__ + self.assertIs(subst(int), int) + self.assertEqual(subst(list[int]), list[int]) + self.assertEqual(subst(List[int]), List[int]) + self.assertEqual(subst(List), List) + self.assertIs(subst(Any), Any) + self.assertIs(subst(None), type(None)) + self.assertIs(subst(T), T) + self.assertEqual(subst(int|str), int|str) + self.assertEqual(subst(Union[int, str]), Union[int, str]) + + def test_bad_var_substitution(self): + T = TypeVar('T') + P = ParamSpec("P") + bad_args = ( + (), (int, str), Union, + Generic, Generic[T], Protocol, Protocol[T], + Final, Final[int], ClassVar, ClassVar[int], + ) + for arg in bad_args: + with self.subTest(arg=arg): + with self.assertRaises(TypeError): + T.__typing_subst__(arg) + with self.assertRaises(TypeError): + List[T][arg] + with self.assertRaises(TypeError): + list[T][arg] + + +def template_replace(templates: list[str], replacements: dict[str, list[str]]) -> list[tuple[str]]: + """Renders templates with possible combinations of replacements. + + Example 1: Suppose that: + templates = ["dog_breed are awesome", "dog_breed are cool"] + replacements = ["dog_breed": ["Huskies", "Beagles"]] + Then we would return: + [ + ("Huskies are awesome", "Huskies are cool"), + ("Beagles are awesome", "Beagles are cool") + ] + + Example 2: Suppose that: + templates = ["Huskies are word1 but also word2"] + replacements = {"word1": ["playful", "cute"], + "word2": ["feisty", "tiring"]} + Then we would return: + [ + ("Huskies are playful but also feisty"), + ("Huskies are playful but also tiring"), + ("Huskies are cute but also feisty"), + ("Huskies are cute but also tiring") + ] + + Note that if any of the replacements do not occur in any template: + templates = ["Huskies are word1", "Beagles!"] + replacements = {"word1": ["playful", "cute"], + "word2": ["feisty", "tiring"]} + Then we do not generate duplicates, returning: + [ + ("Huskies are playful", "Beagles!"), + ("Huskies are cute", "Beagles!") + ] + """ + # First, build a structure like: + # [ + # [("word1", "playful"), ("word1", "cute")], + # [("word2", "feisty"), ("word2", "tiring")] + # ] + replacement_combos = [] + for original, possible_replacements in replacements.items(): + original_replacement_tuples = [] + for replacement in possible_replacements: + original_replacement_tuples.append((original, replacement)) + replacement_combos.append(original_replacement_tuples) + + # Second, generate rendered templates, including possible duplicates. + rendered_templates = [] + for replacement_combo in itertools.product(*replacement_combos): + # replacement_combo would be e.g. + # [("word1", "playful"), ("word2", "feisty")] + templates_with_replacements = [] + for template in templates: + for original, replacement in replacement_combo: + template = template.replace(original, replacement) + templates_with_replacements.append(template) + rendered_templates.append(tuple(templates_with_replacements)) + + # Finally, remove the duplicates (but keep the order). + rendered_templates_no_duplicates = [] + for x in rendered_templates: + # Inefficient, but should be fine for our purposes. + if x not in rendered_templates_no_duplicates: + rendered_templates_no_duplicates.append(x) + + return rendered_templates_no_duplicates + + +class TemplateReplacementTests(BaseTestCase): + + def test_two_templates_two_replacements_yields_correct_renders(self): + actual = template_replace( + templates=["Cats are word1", "Dogs are word2"], + replacements={ + "word1": ["small", "cute"], + "word2": ["big", "fluffy"], + }, + ) + expected = [ + ("Cats are small", "Dogs are big"), + ("Cats are small", "Dogs are fluffy"), + ("Cats are cute", "Dogs are big"), + ("Cats are cute", "Dogs are fluffy"), + ] + self.assertEqual(actual, expected) + + def test_no_duplicates_if_replacement_not_in_templates(self): + actual = template_replace( + templates=["Cats are word1", "Dogs!"], + replacements={ + "word1": ["small", "cute"], + "word2": ["big", "fluffy"], + }, + ) + expected = [ + ("Cats are small", "Dogs!"), + ("Cats are cute", "Dogs!"), + ] + self.assertEqual(actual, expected) + + +class GenericAliasSubstitutionTests(BaseTestCase): + """Tests for type variable substitution in generic aliases. + + For variadic cases, these tests should be regarded as the source of truth, + since we hadn't realised the full complexity of variadic substitution + at the time of finalizing PEP 646. For full discussion, see + https://github.com/python/cpython/issues/91162. + """ + + def test_one_parameter(self): + T = TypeVar('T') + Ts = TypeVarTuple('Ts') + Ts2 = TypeVarTuple('Ts2') + + class C(Generic[T]): pass + + generics = ['C', 'list', 'List'] + tuple_types = ['tuple', 'Tuple'] + + tests = [ + # Alias # Args # Expected result + ('generic[T]', '[()]', 'TypeError'), + ('generic[T]', '[int]', 'generic[int]'), + ('generic[T]', '[int, str]', 'TypeError'), + ('generic[T]', '[tuple_type[int, ...]]', 'generic[tuple_type[int, ...]]'), + ('generic[T]', '[*tuple_type[int]]', 'generic[int]'), + ('generic[T]', '[*tuple_type[()]]', 'TypeError'), + ('generic[T]', '[*tuple_type[int, str]]', 'TypeError'), + ('generic[T]', '[*tuple_type[int, ...]]', 'TypeError'), + ('generic[T]', '[*Ts]', 'TypeError'), + ('generic[T]', '[T, *Ts]', 'TypeError'), + ('generic[T]', '[*Ts, T]', 'TypeError'), + # Raises TypeError because C is not variadic. + # (If C _were_ variadic, it'd be fine.) + ('C[T, *tuple_type[int, ...]]', '[int]', 'TypeError'), + # Should definitely raise TypeError: list only takes one argument. + ('list[T, *tuple_type[int, ...]]', '[int]', 'list[int, *tuple_type[int, ...]]'), + ('List[T, *tuple_type[int, ...]]', '[int]', 'TypeError'), + # Should raise, because more than one `TypeVarTuple` is not supported. + ('generic[*Ts, *Ts2]', '[int]', 'TypeError'), + ] + + for alias_template, args_template, expected_template in tests: + rendered_templates = template_replace( + templates=[alias_template, args_template, expected_template], + replacements={'generic': generics, 'tuple_type': tuple_types} + ) + for alias_str, args_str, expected_str in rendered_templates: + with self.subTest(alias=alias_str, args=args_str, expected=expected_str): + if expected_str == 'TypeError': + with self.assertRaises(TypeError): + eval(alias_str + args_str) + else: + self.assertEqual( + eval(alias_str + args_str), + eval(expected_str) + ) + + + def test_two_parameters(self): + T1 = TypeVar('T1') + T2 = TypeVar('T2') + Ts = TypeVarTuple('Ts') + + class C(Generic[T1, T2]): pass + + generics = ['C', 'dict', 'Dict'] + tuple_types = ['tuple', 'Tuple'] + + tests = [ + # Alias # Args # Expected result + ('generic[T1, T2]', '[()]', 'TypeError'), + ('generic[T1, T2]', '[int]', 'TypeError'), + ('generic[T1, T2]', '[int, str]', 'generic[int, str]'), + ('generic[T1, T2]', '[int, str, bool]', 'TypeError'), + ('generic[T1, T2]', '[*tuple_type[int]]', 'TypeError'), + ('generic[T1, T2]', '[*tuple_type[int, str]]', 'generic[int, str]'), + ('generic[T1, T2]', '[*tuple_type[int, str, bool]]', 'TypeError'), + + ('generic[T1, T2]', '[int, *tuple_type[str]]', 'generic[int, str]'), + ('generic[T1, T2]', '[*tuple_type[int], str]', 'generic[int, str]'), + ('generic[T1, T2]', '[*tuple_type[int], *tuple_type[str]]', 'generic[int, str]'), + ('generic[T1, T2]', '[*tuple_type[int, str], *tuple_type[()]]', 'generic[int, str]'), + ('generic[T1, T2]', '[*tuple_type[()], *tuple_type[int, str]]', 'generic[int, str]'), + ('generic[T1, T2]', '[*tuple_type[int], *tuple_type[()]]', 'TypeError'), + ('generic[T1, T2]', '[*tuple_type[()], *tuple_type[int]]', 'TypeError'), + ('generic[T1, T2]', '[*tuple_type[int, str], *tuple_type[float]]', 'TypeError'), + ('generic[T1, T2]', '[*tuple_type[int], *tuple_type[str, float]]', 'TypeError'), + ('generic[T1, T2]', '[*tuple_type[int, str], *tuple_type[float, bool]]', 'TypeError'), + + ('generic[T1, T2]', '[tuple_type[int, ...]]', 'TypeError'), + ('generic[T1, T2]', '[tuple_type[int, ...], tuple_type[str, ...]]', 'generic[tuple_type[int, ...], tuple_type[str, ...]]'), + ('generic[T1, T2]', '[*tuple_type[int, ...]]', 'TypeError'), + ('generic[T1, T2]', '[int, *tuple_type[str, ...]]', 'TypeError'), + ('generic[T1, T2]', '[*tuple_type[int, ...], str]', 'TypeError'), + ('generic[T1, T2]', '[*tuple_type[int, ...], *tuple_type[str, ...]]', 'TypeError'), + ('generic[T1, T2]', '[*Ts]', 'TypeError'), + ('generic[T1, T2]', '[T, *Ts]', 'TypeError'), + ('generic[T1, T2]', '[*Ts, T]', 'TypeError'), + # This one isn't technically valid - none of the things that + # `generic` can be (defined in `generics` above) are variadic, so we + # shouldn't really be able to do `generic[T1, *tuple_type[int, ...]]`. + # So even if type checkers shouldn't allow it, we allow it at + # runtime, in accordance with a general philosophy of "Keep the + # runtime lenient so people can experiment with typing constructs". + ('generic[T1, *tuple_type[int, ...]]', '[str]', 'generic[str, *tuple_type[int, ...]]'), + ] + + for alias_template, args_template, expected_template in tests: + rendered_templates = template_replace( + templates=[alias_template, args_template, expected_template], + replacements={'generic': generics, 'tuple_type': tuple_types} + ) + for alias_str, args_str, expected_str in rendered_templates: + with self.subTest(alias=alias_str, args=args_str, expected=expected_str): + if expected_str == 'TypeError': + with self.assertRaises(TypeError): + eval(alias_str + args_str) + else: + self.assertEqual( + eval(alias_str + args_str), + eval(expected_str) + ) + + def test_three_parameters(self): + T1 = TypeVar('T1') + T2 = TypeVar('T2') + T3 = TypeVar('T3') + + class C(Generic[T1, T2, T3]): pass + + generics = ['C'] + tuple_types = ['tuple', 'Tuple'] + + tests = [ + # Alias # Args # Expected result + ('generic[T1, bool, T2]', '[int, str]', 'generic[int, bool, str]'), + ('generic[T1, bool, T2]', '[*tuple_type[int, str]]', 'generic[int, bool, str]'), + ] + + for alias_template, args_template, expected_template in tests: + rendered_templates = template_replace( + templates=[alias_template, args_template, expected_template], + replacements={'generic': generics, 'tuple_type': tuple_types} + ) + for alias_str, args_str, expected_str in rendered_templates: + with self.subTest(alias=alias_str, args=args_str, expected=expected_str): + if expected_str == 'TypeError': + with self.assertRaises(TypeError): + eval(alias_str + args_str) + else: + self.assertEqual( + eval(alias_str + args_str), + eval(expected_str) + ) + + def test_variadic_parameters(self): + T1 = TypeVar('T1') + T2 = TypeVar('T2') + Ts = TypeVarTuple('Ts') + + class C(Generic[*Ts]): pass + + generics = ['C', 'tuple', 'Tuple'] + tuple_types = ['tuple', 'Tuple'] + + tests = [ + # Alias # Args # Expected result + ('generic[*Ts]', '[()]', 'generic[()]'), + ('generic[*Ts]', '[int]', 'generic[int]'), + ('generic[*Ts]', '[int, str]', 'generic[int, str]'), + ('generic[*Ts]', '[*tuple_type[int]]', 'generic[int]'), + ('generic[*Ts]', '[*tuple_type[*Ts]]', 'generic[*Ts]'), + ('generic[*Ts]', '[*tuple_type[int, str]]', 'generic[int, str]'), + ('generic[*Ts]', '[str, *tuple_type[int, ...], bool]', 'generic[str, *tuple_type[int, ...], bool]'), + ('generic[*Ts]', '[tuple_type[int, ...]]', 'generic[tuple_type[int, ...]]'), + ('generic[*Ts]', '[tuple_type[int, ...], tuple_type[str, ...]]', 'generic[tuple_type[int, ...], tuple_type[str, ...]]'), + ('generic[*Ts]', '[*tuple_type[int, ...]]', 'generic[*tuple_type[int, ...]]'), + ('generic[*Ts]', '[*tuple_type[int, ...], *tuple_type[str, ...]]', 'TypeError'), + + ('generic[*Ts]', '[*Ts]', 'generic[*Ts]'), + ('generic[*Ts]', '[T, *Ts]', 'generic[T, *Ts]'), + ('generic[*Ts]', '[*Ts, T]', 'generic[*Ts, T]'), + ('generic[T, *Ts]', '[()]', 'TypeError'), + ('generic[T, *Ts]', '[int]', 'generic[int]'), + ('generic[T, *Ts]', '[int, str]', 'generic[int, str]'), + ('generic[T, *Ts]', '[int, str, bool]', 'generic[int, str, bool]'), + ('generic[list[T], *Ts]', '[()]', 'TypeError'), + ('generic[list[T], *Ts]', '[int]', 'generic[list[int]]'), + ('generic[list[T], *Ts]', '[int, str]', 'generic[list[int], str]'), + ('generic[list[T], *Ts]', '[int, str, bool]', 'generic[list[int], str, bool]'), + + ('generic[*Ts, T]', '[()]', 'TypeError'), + ('generic[*Ts, T]', '[int]', 'generic[int]'), + ('generic[*Ts, T]', '[int, str]', 'generic[int, str]'), + ('generic[*Ts, T]', '[int, str, bool]', 'generic[int, str, bool]'), + ('generic[*Ts, list[T]]', '[()]', 'TypeError'), + ('generic[*Ts, list[T]]', '[int]', 'generic[list[int]]'), + ('generic[*Ts, list[T]]', '[int, str]', 'generic[int, list[str]]'), + ('generic[*Ts, list[T]]', '[int, str, bool]', 'generic[int, str, list[bool]]'), + + ('generic[T1, T2, *Ts]', '[()]', 'TypeError'), + ('generic[T1, T2, *Ts]', '[int]', 'TypeError'), + ('generic[T1, T2, *Ts]', '[int, str]', 'generic[int, str]'), + ('generic[T1, T2, *Ts]', '[int, str, bool]', 'generic[int, str, bool]'), + ('generic[T1, T2, *Ts]', '[int, str, bool, bytes]', 'generic[int, str, bool, bytes]'), + + ('generic[*Ts, T1, T2]', '[()]', 'TypeError'), + ('generic[*Ts, T1, T2]', '[int]', 'TypeError'), + ('generic[*Ts, T1, T2]', '[int, str]', 'generic[int, str]'), + ('generic[*Ts, T1, T2]', '[int, str, bool]', 'generic[int, str, bool]'), + ('generic[*Ts, T1, T2]', '[int, str, bool, bytes]', 'generic[int, str, bool, bytes]'), + + ('generic[T1, *Ts, T2]', '[()]', 'TypeError'), + ('generic[T1, *Ts, T2]', '[int]', 'TypeError'), + ('generic[T1, *Ts, T2]', '[int, str]', 'generic[int, str]'), + ('generic[T1, *Ts, T2]', '[int, str, bool]', 'generic[int, str, bool]'), + ('generic[T1, *Ts, T2]', '[int, str, bool, bytes]', 'generic[int, str, bool, bytes]'), + + ('generic[T, *Ts]', '[*tuple_type[int, ...]]', 'generic[int, *tuple_type[int, ...]]'), + ('generic[T, *Ts]', '[str, *tuple_type[int, ...]]', 'generic[str, *tuple_type[int, ...]]'), + ('generic[T, *Ts]', '[*tuple_type[int, ...], str]', 'generic[int, *tuple_type[int, ...], str]'), + ('generic[*Ts, T]', '[*tuple_type[int, ...]]', 'generic[*tuple_type[int, ...], int]'), + ('generic[*Ts, T]', '[str, *tuple_type[int, ...]]', 'generic[str, *tuple_type[int, ...], int]'), + ('generic[*Ts, T]', '[*tuple_type[int, ...], str]', 'generic[*tuple_type[int, ...], str]'), + ('generic[T1, *Ts, T2]', '[*tuple_type[int, ...]]', 'generic[int, *tuple_type[int, ...], int]'), + ('generic[T, str, *Ts]', '[*tuple_type[int, ...]]', 'generic[int, str, *tuple_type[int, ...]]'), + ('generic[*Ts, str, T]', '[*tuple_type[int, ...]]', 'generic[*tuple_type[int, ...], str, int]'), + ('generic[list[T], *Ts]', '[*tuple_type[int, ...]]', 'generic[list[int], *tuple_type[int, ...]]'), + ('generic[*Ts, list[T]]', '[*tuple_type[int, ...]]', 'generic[*tuple_type[int, ...], list[int]]'), + + ('generic[T, *tuple_type[int, ...]]', '[str]', 'generic[str, *tuple_type[int, ...]]'), + ('generic[T1, T2, *tuple_type[int, ...]]', '[str, bool]', 'generic[str, bool, *tuple_type[int, ...]]'), + ('generic[T1, *tuple_type[int, ...], T2]', '[str, bool]', 'generic[str, *tuple_type[int, ...], bool]'), + ('generic[T1, *tuple_type[int, ...], T2]', '[str, bool, float]', 'TypeError'), + + ('generic[T1, *tuple_type[T2, ...]]', '[int, str]', 'generic[int, *tuple_type[str, ...]]'), + ('generic[*tuple_type[T1, ...], T2]', '[int, str]', 'generic[*tuple_type[int, ...], str]'), + ('generic[T1, *tuple_type[generic[*Ts], ...]]', '[int, str, bool]', 'generic[int, *tuple_type[generic[str, bool], ...]]'), + ('generic[*tuple_type[generic[*Ts], ...], T1]', '[int, str, bool]', 'generic[*tuple_type[generic[int, str], ...], bool]'), + ] + + for alias_template, args_template, expected_template in tests: + rendered_templates = template_replace( + templates=[alias_template, args_template, expected_template], + replacements={'generic': generics, 'tuple_type': tuple_types} + ) + for alias_str, args_str, expected_str in rendered_templates: + with self.subTest(alias=alias_str, args=args_str, expected=expected_str): + if expected_str == 'TypeError': + with self.assertRaises(TypeError): + eval(alias_str + args_str) + else: + self.assertEqual( + eval(alias_str + args_str), + eval(expected_str) + ) + + + +class UnpackTests(BaseTestCase): + + def test_accepts_single_type(self): + (*tuple[int],) + Unpack[Tuple[int]] + + def test_rejects_multiple_types(self): + with self.assertRaises(TypeError): + Unpack[Tuple[int], Tuple[str]] + # We can't do the equivalent for `*` here - + # *(Tuple[int], Tuple[str]) is just plain tuple unpacking, + # which is valid. + + def test_rejects_multiple_parameterization(self): + with self.assertRaises(TypeError): + (*tuple[int],)[0][tuple[int]] + with self.assertRaises(TypeError): + Unpack[Tuple[int]][Tuple[int]] + + def test_cannot_be_called(self): + with self.assertRaises(TypeError): + Unpack() + + +class TypeVarTupleTests(BaseTestCase): + + def assertEndsWith(self, string, tail): + if not string.endswith(tail): + self.fail(f"String {string!r} does not end with {tail!r}") + + def test_name(self): + Ts = TypeVarTuple('Ts') + self.assertEqual(Ts.__name__, 'Ts') + Ts2 = TypeVarTuple('Ts2') + self.assertEqual(Ts2.__name__, 'Ts2') + + def test_instance_is_equal_to_itself(self): + Ts = TypeVarTuple('Ts') + self.assertEqual(Ts, Ts) + + def test_different_instances_are_different(self): + self.assertNotEqual(TypeVarTuple('Ts'), TypeVarTuple('Ts')) + + def test_instance_isinstance_of_typevartuple(self): + Ts = TypeVarTuple('Ts') + self.assertIsInstance(Ts, TypeVarTuple) + + def test_cannot_call_instance(self): + Ts = TypeVarTuple('Ts') + with self.assertRaises(TypeError): + Ts() + + def test_unpacked_typevartuple_is_equal_to_itself(self): + Ts = TypeVarTuple('Ts') + self.assertEqual((*Ts,)[0], (*Ts,)[0]) + self.assertEqual(Unpack[Ts], Unpack[Ts]) + + def test_parameterised_tuple_is_equal_to_itself(self): + Ts = TypeVarTuple('Ts') + self.assertEqual(tuple[*Ts], tuple[*Ts]) + self.assertEqual(Tuple[Unpack[Ts]], Tuple[Unpack[Ts]]) + + def tests_tuple_arg_ordering_matters(self): + Ts1 = TypeVarTuple('Ts1') + Ts2 = TypeVarTuple('Ts2') + self.assertNotEqual( + tuple[*Ts1, *Ts2], + tuple[*Ts2, *Ts1], + ) + self.assertNotEqual( + Tuple[Unpack[Ts1], Unpack[Ts2]], + Tuple[Unpack[Ts2], Unpack[Ts1]], + ) + + def test_tuple_args_and_parameters_are_correct(self): + Ts = TypeVarTuple('Ts') + t1 = tuple[*Ts] + self.assertEqual(t1.__args__, (*Ts,)) + self.assertEqual(t1.__parameters__, (Ts,)) + t2 = Tuple[Unpack[Ts]] + self.assertEqual(t2.__args__, (Unpack[Ts],)) + self.assertEqual(t2.__parameters__, (Ts,)) + + def test_var_substitution(self): + Ts = TypeVarTuple('Ts') + T = TypeVar('T') + T2 = TypeVar('T2') + class G1(Generic[*Ts]): pass + class G2(Generic[Unpack[Ts]]): pass + + for A in G1, G2, Tuple, tuple: + B = A[*Ts] + self.assertEqual(B[()], A[()]) + self.assertEqual(B[float], A[float]) + self.assertEqual(B[float, str], A[float, str]) + + C = A[Unpack[Ts]] + self.assertEqual(C[()], A[()]) + self.assertEqual(C[float], A[float]) + self.assertEqual(C[float, str], A[float, str]) + + D = list[A[*Ts]] + self.assertEqual(D[()], list[A[()]]) + self.assertEqual(D[float], list[A[float]]) + self.assertEqual(D[float, str], list[A[float, str]]) + + E = List[A[Unpack[Ts]]] + self.assertEqual(E[()], List[A[()]]) + self.assertEqual(E[float], List[A[float]]) + self.assertEqual(E[float, str], List[A[float, str]]) + + F = A[T, *Ts, T2] + with self.assertRaises(TypeError): + F[()] + with self.assertRaises(TypeError): + F[float] + self.assertEqual(F[float, str], A[float, str]) + self.assertEqual(F[float, str, int], A[float, str, int]) + self.assertEqual(F[float, str, int, bytes], A[float, str, int, bytes]) + + G = A[T, Unpack[Ts], T2] + with self.assertRaises(TypeError): + G[()] + with self.assertRaises(TypeError): + G[float] + self.assertEqual(G[float, str], A[float, str]) + self.assertEqual(G[float, str, int], A[float, str, int]) + self.assertEqual(G[float, str, int, bytes], A[float, str, int, bytes]) + + H = tuple[list[T], A[*Ts], list[T2]] + with self.assertRaises(TypeError): + H[()] + with self.assertRaises(TypeError): + H[float] + if A != Tuple: + self.assertEqual(H[float, str], + tuple[list[float], A[()], list[str]]) + self.assertEqual(H[float, str, int], + tuple[list[float], A[str], list[int]]) + self.assertEqual(H[float, str, int, bytes], + tuple[list[float], A[str, int], list[bytes]]) + + I = Tuple[List[T], A[Unpack[Ts]], List[T2]] + with self.assertRaises(TypeError): + I[()] + with self.assertRaises(TypeError): + I[float] + if A != Tuple: + self.assertEqual(I[float, str], + Tuple[List[float], A[()], List[str]]) + self.assertEqual(I[float, str, int], + Tuple[List[float], A[str], List[int]]) + self.assertEqual(I[float, str, int, bytes], + Tuple[List[float], A[str, int], List[bytes]]) + + def test_bad_var_substitution(self): + Ts = TypeVarTuple('Ts') + T = TypeVar('T') + T2 = TypeVar('T2') + class G1(Generic[*Ts]): pass + class G2(Generic[Unpack[Ts]]): pass + + for A in G1, G2, Tuple, tuple: + B = A[Ts] + with self.assertRaises(TypeError): + B[int, str] + + C = A[T, T2] + with self.assertRaises(TypeError): + C[*Ts] + with self.assertRaises(TypeError): + C[Unpack[Ts]] + + B = A[T, *Ts, str, T2] + with self.assertRaises(TypeError): + B[int, *Ts] + with self.assertRaises(TypeError): + B[int, *Ts, *Ts] + + C = A[T, Unpack[Ts], str, T2] + with self.assertRaises(TypeError): + C[int, Unpack[Ts]] + with self.assertRaises(TypeError): + C[int, Unpack[Ts], Unpack[Ts]] + + def test_repr_is_correct(self): + Ts = TypeVarTuple('Ts') + T = TypeVar('T') + T2 = TypeVar('T2') + + class G1(Generic[*Ts]): pass + class G2(Generic[Unpack[Ts]]): pass + + self.assertEqual(repr(Ts), 'Ts') + + self.assertEqual(repr((*Ts,)[0]), '*Ts') + self.assertEqual(repr(Unpack[Ts]), '*Ts') + + self.assertEqual(repr(tuple[*Ts]), 'tuple[*Ts]') + self.assertEqual(repr(Tuple[Unpack[Ts]]), 'typing.Tuple[*Ts]') + + self.assertEqual(repr(*tuple[*Ts]), '*tuple[*Ts]') + self.assertEqual(repr(Unpack[Tuple[Unpack[Ts]]]), '*typing.Tuple[*Ts]') + + def test_variadic_class_repr_is_correct(self): + Ts = TypeVarTuple('Ts') + class A(Generic[*Ts]): pass + class B(Generic[Unpack[Ts]]): pass + + self.assertEndsWith(repr(A[()]), 'A[()]') + self.assertEndsWith(repr(B[()]), 'B[()]') + self.assertEndsWith(repr(A[float]), 'A[float]') + self.assertEndsWith(repr(B[float]), 'B[float]') + self.assertEndsWith(repr(A[float, str]), 'A[float, str]') + self.assertEndsWith(repr(B[float, str]), 'B[float, str]') + + self.assertEndsWith(repr(A[*tuple[int, ...]]), + 'A[*tuple[int, ...]]') + self.assertEndsWith(repr(B[Unpack[Tuple[int, ...]]]), + 'B[*typing.Tuple[int, ...]]') + + self.assertEndsWith(repr(A[float, *tuple[int, ...]]), + 'A[float, *tuple[int, ...]]') + self.assertEndsWith(repr(A[float, Unpack[Tuple[int, ...]]]), + 'A[float, *typing.Tuple[int, ...]]') + + self.assertEndsWith(repr(A[*tuple[int, ...], str]), + 'A[*tuple[int, ...], str]') + self.assertEndsWith(repr(B[Unpack[Tuple[int, ...]], str]), + 'B[*typing.Tuple[int, ...], str]') + + self.assertEndsWith(repr(A[float, *tuple[int, ...], str]), + 'A[float, *tuple[int, ...], str]') + self.assertEndsWith(repr(B[float, Unpack[Tuple[int, ...]], str]), + 'B[float, *typing.Tuple[int, ...], str]') + + def test_variadic_class_alias_repr_is_correct(self): + Ts = TypeVarTuple('Ts') + class A(Generic[Unpack[Ts]]): pass + + B = A[*Ts] + self.assertEndsWith(repr(B), 'A[*Ts]') + self.assertEndsWith(repr(B[()]), 'A[()]') + self.assertEndsWith(repr(B[float]), 'A[float]') + self.assertEndsWith(repr(B[float, str]), 'A[float, str]') + + C = A[Unpack[Ts]] + self.assertEndsWith(repr(C), 'A[*Ts]') + self.assertEndsWith(repr(C[()]), 'A[()]') + self.assertEndsWith(repr(C[float]), 'A[float]') + self.assertEndsWith(repr(C[float, str]), 'A[float, str]') + + D = A[*Ts, int] + self.assertEndsWith(repr(D), 'A[*Ts, int]') + self.assertEndsWith(repr(D[()]), 'A[int]') + self.assertEndsWith(repr(D[float]), 'A[float, int]') + self.assertEndsWith(repr(D[float, str]), 'A[float, str, int]') + + E = A[Unpack[Ts], int] + self.assertEndsWith(repr(E), 'A[*Ts, int]') + self.assertEndsWith(repr(E[()]), 'A[int]') + self.assertEndsWith(repr(E[float]), 'A[float, int]') + self.assertEndsWith(repr(E[float, str]), 'A[float, str, int]') + + F = A[int, *Ts] + self.assertEndsWith(repr(F), 'A[int, *Ts]') + self.assertEndsWith(repr(F[()]), 'A[int]') + self.assertEndsWith(repr(F[float]), 'A[int, float]') + self.assertEndsWith(repr(F[float, str]), 'A[int, float, str]') + + G = A[int, Unpack[Ts]] + self.assertEndsWith(repr(G), 'A[int, *Ts]') + self.assertEndsWith(repr(G[()]), 'A[int]') + self.assertEndsWith(repr(G[float]), 'A[int, float]') + self.assertEndsWith(repr(G[float, str]), 'A[int, float, str]') + + H = A[int, *Ts, str] + self.assertEndsWith(repr(H), 'A[int, *Ts, str]') + self.assertEndsWith(repr(H[()]), 'A[int, str]') + self.assertEndsWith(repr(H[float]), 'A[int, float, str]') + self.assertEndsWith(repr(H[float, str]), 'A[int, float, str, str]') + + I = A[int, Unpack[Ts], str] + self.assertEndsWith(repr(I), 'A[int, *Ts, str]') + self.assertEndsWith(repr(I[()]), 'A[int, str]') + self.assertEndsWith(repr(I[float]), 'A[int, float, str]') + self.assertEndsWith(repr(I[float, str]), 'A[int, float, str, str]') + + J = A[*Ts, *tuple[str, ...]] + self.assertEndsWith(repr(J), 'A[*Ts, *tuple[str, ...]]') + self.assertEndsWith(repr(J[()]), 'A[*tuple[str, ...]]') + self.assertEndsWith(repr(J[float]), 'A[float, *tuple[str, ...]]') + self.assertEndsWith(repr(J[float, str]), 'A[float, str, *tuple[str, ...]]') + + K = A[Unpack[Ts], Unpack[Tuple[str, ...]]] + self.assertEndsWith(repr(K), 'A[*Ts, *typing.Tuple[str, ...]]') + self.assertEndsWith(repr(K[()]), 'A[*typing.Tuple[str, ...]]') + self.assertEndsWith(repr(K[float]), 'A[float, *typing.Tuple[str, ...]]') + self.assertEndsWith(repr(K[float, str]), 'A[float, str, *typing.Tuple[str, ...]]') + + def test_cannot_subclass(self): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class C(TypeVarTuple): pass + Ts = TypeVarTuple('Ts') + with self.assertRaisesRegex(TypeError, + CANNOT_SUBCLASS_INSTANCE % 'TypeVarTuple'): + class C(Ts): pass + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class C(type(Unpack)): pass + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class C(type(*Ts)): pass + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class C(type(Unpack[Ts])): pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.Unpack'): + class C(Unpack): pass + with self.assertRaisesRegex(TypeError, r'Cannot subclass \*Ts'): + class C(*Ts): pass + with self.assertRaisesRegex(TypeError, r'Cannot subclass \*Ts'): + class C(Unpack[Ts]): pass + + def test_variadic_class_args_are_correct(self): + T = TypeVar('T') + Ts = TypeVarTuple('Ts') + class A(Generic[*Ts]): pass + class B(Generic[Unpack[Ts]]): pass + + C = A[()] + D = B[()] + self.assertEqual(C.__args__, ()) + self.assertEqual(D.__args__, ()) + + E = A[int] + F = B[int] + self.assertEqual(E.__args__, (int,)) + self.assertEqual(F.__args__, (int,)) + + G = A[int, str] + H = B[int, str] + self.assertEqual(G.__args__, (int, str)) + self.assertEqual(H.__args__, (int, str)) + + I = A[T] + J = B[T] + self.assertEqual(I.__args__, (T,)) + self.assertEqual(J.__args__, (T,)) + + K = A[*Ts] + L = B[Unpack[Ts]] + self.assertEqual(K.__args__, (*Ts,)) + self.assertEqual(L.__args__, (Unpack[Ts],)) + + M = A[T, *Ts] + N = B[T, Unpack[Ts]] + self.assertEqual(M.__args__, (T, *Ts)) + self.assertEqual(N.__args__, (T, Unpack[Ts])) + + O = A[*Ts, T] + P = B[Unpack[Ts], T] + self.assertEqual(O.__args__, (*Ts, T)) + self.assertEqual(P.__args__, (Unpack[Ts], T)) + + def test_variadic_class_origin_is_correct(self): + Ts = TypeVarTuple('Ts') + + class C(Generic[*Ts]): pass + self.assertIs(C[int].__origin__, C) + self.assertIs(C[T].__origin__, C) + self.assertIs(C[Unpack[Ts]].__origin__, C) + + class D(Generic[Unpack[Ts]]): pass + self.assertIs(D[int].__origin__, D) + self.assertIs(D[T].__origin__, D) + self.assertIs(D[Unpack[Ts]].__origin__, D) + + def test_get_type_hints_on_unpack_args(self): + Ts = TypeVarTuple('Ts') + + def func1(*args: *Ts): pass + self.assertEqual(gth(func1), {'args': Unpack[Ts]}) + + def func2(*args: *tuple[int, str]): pass + self.assertEqual(gth(func2), {'args': Unpack[tuple[int, str]]}) + + class CustomVariadic(Generic[*Ts]): pass + + def func3(*args: *CustomVariadic[int, str]): pass + self.assertEqual(gth(func3), {'args': Unpack[CustomVariadic[int, str]]}) + + def test_get_type_hints_on_unpack_args_string(self): + Ts = TypeVarTuple('Ts') + + def func1(*args: '*Ts'): pass + self.assertEqual(gth(func1, localns={'Ts': Ts}), + {'args': Unpack[Ts]}) + + def func2(*args: '*tuple[int, str]'): pass + self.assertEqual(gth(func2), {'args': Unpack[tuple[int, str]]}) + + class CustomVariadic(Generic[*Ts]): pass + + def func3(*args: '*CustomVariadic[int, str]'): pass + self.assertEqual(gth(func3, localns={'CustomVariadic': CustomVariadic}), + {'args': Unpack[CustomVariadic[int, str]]}) + + def test_tuple_args_are_correct(self): + Ts = TypeVarTuple('Ts') + + self.assertEqual(tuple[*Ts].__args__, (*Ts,)) + self.assertEqual(Tuple[Unpack[Ts]].__args__, (Unpack[Ts],)) + + self.assertEqual(tuple[*Ts, int].__args__, (*Ts, int)) + self.assertEqual(Tuple[Unpack[Ts], int].__args__, (Unpack[Ts], int)) + + self.assertEqual(tuple[int, *Ts].__args__, (int, *Ts)) + self.assertEqual(Tuple[int, Unpack[Ts]].__args__, (int, Unpack[Ts])) + + self.assertEqual(tuple[int, *Ts, str].__args__, + (int, *Ts, str)) + self.assertEqual(Tuple[int, Unpack[Ts], str].__args__, + (int, Unpack[Ts], str)) + + self.assertEqual(tuple[*Ts, int].__args__, (*Ts, int)) + self.assertEqual(Tuple[Unpack[Ts]].__args__, (Unpack[Ts],)) + + def test_callable_args_are_correct(self): + Ts = TypeVarTuple('Ts') + Ts1 = TypeVarTuple('Ts1') + Ts2 = TypeVarTuple('Ts2') + + # TypeVarTuple in the arguments + + a = Callable[[*Ts], None] + b = Callable[[Unpack[Ts]], None] + self.assertEqual(a.__args__, (*Ts, type(None))) + self.assertEqual(b.__args__, (Unpack[Ts], type(None))) + + c = Callable[[int, *Ts], None] + d = Callable[[int, Unpack[Ts]], None] + self.assertEqual(c.__args__, (int, *Ts, type(None))) + self.assertEqual(d.__args__, (int, Unpack[Ts], type(None))) + + e = Callable[[*Ts, int], None] + f = Callable[[Unpack[Ts], int], None] + self.assertEqual(e.__args__, (*Ts, int, type(None))) + self.assertEqual(f.__args__, (Unpack[Ts], int, type(None))) + + g = Callable[[str, *Ts, int], None] + h = Callable[[str, Unpack[Ts], int], None] + self.assertEqual(g.__args__, (str, *Ts, int, type(None))) + self.assertEqual(h.__args__, (str, Unpack[Ts], int, type(None))) + + # TypeVarTuple as the return + + i = Callable[[None], *Ts] + j = Callable[[None], Unpack[Ts]] + self.assertEqual(i.__args__, (type(None), *Ts)) + self.assertEqual(i.__args__, (type(None), Unpack[Ts])) + + k = Callable[[None], tuple[int, *Ts]] + l = Callable[[None], Tuple[int, Unpack[Ts]]] + self.assertEqual(k.__args__, (type(None), tuple[int, *Ts])) + self.assertEqual(l.__args__, (type(None), Tuple[int, Unpack[Ts]])) + + m = Callable[[None], tuple[*Ts, int]] + n = Callable[[None], Tuple[Unpack[Ts], int]] + self.assertEqual(m.__args__, (type(None), tuple[*Ts, int])) + self.assertEqual(n.__args__, (type(None), Tuple[Unpack[Ts], int])) + + o = Callable[[None], tuple[str, *Ts, int]] + p = Callable[[None], Tuple[str, Unpack[Ts], int]] + self.assertEqual(o.__args__, (type(None), tuple[str, *Ts, int])) + self.assertEqual(p.__args__, (type(None), Tuple[str, Unpack[Ts], int])) + + # TypeVarTuple in both + + q = Callable[[*Ts], *Ts] + r = Callable[[Unpack[Ts]], Unpack[Ts]] + self.assertEqual(q.__args__, (*Ts, *Ts)) + self.assertEqual(r.__args__, (Unpack[Ts], Unpack[Ts])) + + s = Callable[[*Ts1], *Ts2] + u = Callable[[Unpack[Ts1]], Unpack[Ts2]] + self.assertEqual(s.__args__, (*Ts1, *Ts2)) + self.assertEqual(u.__args__, (Unpack[Ts1], Unpack[Ts2])) + + def test_variadic_class_with_duplicate_typevartuples_fails(self): + Ts1 = TypeVarTuple('Ts1') + Ts2 = TypeVarTuple('Ts2') + + with self.assertRaises(TypeError): + class C(Generic[*Ts1, *Ts1]): pass + with self.assertRaises(TypeError): + class C(Generic[Unpack[Ts1], Unpack[Ts1]]): pass + + with self.assertRaises(TypeError): + class C(Generic[*Ts1, *Ts2, *Ts1]): pass + with self.assertRaises(TypeError): + class C(Generic[Unpack[Ts1], Unpack[Ts2], Unpack[Ts1]]): pass + + def test_type_concatenation_in_variadic_class_argument_list_succeeds(self): + Ts = TypeVarTuple('Ts') + class C(Generic[Unpack[Ts]]): pass + + C[int, *Ts] + C[int, Unpack[Ts]] + + C[*Ts, int] + C[Unpack[Ts], int] + + C[int, *Ts, str] + C[int, Unpack[Ts], str] + + C[int, bool, *Ts, float, str] + C[int, bool, Unpack[Ts], float, str] + + def test_type_concatenation_in_tuple_argument_list_succeeds(self): + Ts = TypeVarTuple('Ts') + + tuple[int, *Ts] + tuple[*Ts, int] + tuple[int, *Ts, str] + tuple[int, bool, *Ts, float, str] + + Tuple[int, Unpack[Ts]] + Tuple[Unpack[Ts], int] + Tuple[int, Unpack[Ts], str] + Tuple[int, bool, Unpack[Ts], float, str] + + def test_variadic_class_definition_using_packed_typevartuple_fails(self): + Ts = TypeVarTuple('Ts') + with self.assertRaises(TypeError): + class C(Generic[Ts]): pass + + def test_variadic_class_definition_using_concrete_types_fails(self): + Ts = TypeVarTuple('Ts') + with self.assertRaises(TypeError): + class F(Generic[*Ts, int]): pass + with self.assertRaises(TypeError): + class E(Generic[Unpack[Ts], int]): pass + + def test_variadic_class_with_2_typevars_accepts_2_or_more_args(self): + Ts = TypeVarTuple('Ts') + T1 = TypeVar('T1') + T2 = TypeVar('T2') + + class A(Generic[T1, T2, *Ts]): pass + A[int, str] + A[int, str, float] + A[int, str, float, bool] + + class B(Generic[T1, T2, Unpack[Ts]]): pass + B[int, str] + B[int, str, float] + B[int, str, float, bool] + + class C(Generic[T1, *Ts, T2]): pass + C[int, str] + C[int, str, float] + C[int, str, float, bool] + + class D(Generic[T1, Unpack[Ts], T2]): pass + D[int, str] + D[int, str, float] + D[int, str, float, bool] + + class E(Generic[*Ts, T1, T2]): pass + E[int, str] + E[int, str, float] + E[int, str, float, bool] + + class F(Generic[Unpack[Ts], T1, T2]): pass + F[int, str] + F[int, str, float] + F[int, str, float, bool] + + def test_variadic_args_annotations_are_correct(self): + Ts = TypeVarTuple('Ts') + + def f(*args: Unpack[Ts]): pass + def g(*args: *Ts): pass + self.assertEqual(f.__annotations__, {'args': Unpack[Ts]}) + self.assertEqual(g.__annotations__, {'args': (*Ts,)[0]}) + + def test_variadic_args_with_ellipsis_annotations_are_correct(self): + Ts = TypeVarTuple('Ts') + + def a(*args: *tuple[int, ...]): pass + self.assertEqual(a.__annotations__, + {'args': (*tuple[int, ...],)[0]}) + + def b(*args: Unpack[Tuple[int, ...]]): pass + self.assertEqual(b.__annotations__, + {'args': Unpack[Tuple[int, ...]]}) + + def test_concatenation_in_variadic_args_annotations_are_correct(self): + Ts = TypeVarTuple('Ts') + + # Unpacking using `*`, native `tuple` type + + def a(*args: *tuple[int, *Ts]): pass + self.assertEqual( + a.__annotations__, + {'args': (*tuple[int, *Ts],)[0]}, + ) + + def b(*args: *tuple[*Ts, int]): pass + self.assertEqual( + b.__annotations__, + {'args': (*tuple[*Ts, int],)[0]}, + ) + + def c(*args: *tuple[str, *Ts, int]): pass + self.assertEqual( + c.__annotations__, + {'args': (*tuple[str, *Ts, int],)[0]}, + ) + + def d(*args: *tuple[int, bool, *Ts, float, str]): pass + self.assertEqual( + d.__annotations__, + {'args': (*tuple[int, bool, *Ts, float, str],)[0]}, + ) + + # Unpacking using `Unpack`, `Tuple` type from typing.py + + def e(*args: Unpack[Tuple[int, Unpack[Ts]]]): pass + self.assertEqual( + e.__annotations__, + {'args': Unpack[Tuple[int, Unpack[Ts]]]}, + ) + + def f(*args: Unpack[Tuple[Unpack[Ts], int]]): pass + self.assertEqual( + f.__annotations__, + {'args': Unpack[Tuple[Unpack[Ts], int]]}, + ) + + def g(*args: Unpack[Tuple[str, Unpack[Ts], int]]): pass + self.assertEqual( + g.__annotations__, + {'args': Unpack[Tuple[str, Unpack[Ts], int]]}, + ) + + def h(*args: Unpack[Tuple[int, bool, Unpack[Ts], float, str]]): pass + self.assertEqual( + h.__annotations__, + {'args': Unpack[Tuple[int, bool, Unpack[Ts], float, str]]}, + ) + + def test_variadic_class_same_args_results_in_equalty(self): + Ts = TypeVarTuple('Ts') + class C(Generic[*Ts]): pass + class D(Generic[Unpack[Ts]]): pass + + self.assertEqual(C[int], C[int]) + self.assertEqual(D[int], D[int]) + + Ts1 = TypeVarTuple('Ts1') + Ts2 = TypeVarTuple('Ts2') + + self.assertEqual( + C[*Ts1], + C[*Ts1], + ) + self.assertEqual( + D[Unpack[Ts1]], + D[Unpack[Ts1]], + ) + + self.assertEqual( + C[*Ts1, *Ts2], + C[*Ts1, *Ts2], + ) + self.assertEqual( + D[Unpack[Ts1], Unpack[Ts2]], + D[Unpack[Ts1], Unpack[Ts2]], + ) + + self.assertEqual( + C[int, *Ts1, *Ts2], + C[int, *Ts1, *Ts2], + ) + self.assertEqual( + D[int, Unpack[Ts1], Unpack[Ts2]], + D[int, Unpack[Ts1], Unpack[Ts2]], + ) + + def test_variadic_class_arg_ordering_matters(self): + Ts = TypeVarTuple('Ts') + class C(Generic[*Ts]): pass + class D(Generic[Unpack[Ts]]): pass + + self.assertNotEqual( + C[int, str], + C[str, int], + ) + self.assertNotEqual( + D[int, str], + D[str, int], + ) + + Ts1 = TypeVarTuple('Ts1') + Ts2 = TypeVarTuple('Ts2') + + self.assertNotEqual( + C[*Ts1, *Ts2], + C[*Ts2, *Ts1], + ) + self.assertNotEqual( + D[Unpack[Ts1], Unpack[Ts2]], + D[Unpack[Ts2], Unpack[Ts1]], + ) + + def test_variadic_class_arg_typevartuple_identity_matters(self): + Ts = TypeVarTuple('Ts') + Ts1 = TypeVarTuple('Ts1') + Ts2 = TypeVarTuple('Ts2') + + class C(Generic[*Ts]): pass + class D(Generic[Unpack[Ts]]): pass + + self.assertNotEqual(C[*Ts1], C[*Ts2]) + self.assertNotEqual(D[Unpack[Ts1]], D[Unpack[Ts2]]) + + +class TypeVarTuplePicklingTests(BaseTestCase): + # These are slightly awkward tests to run, because TypeVarTuples are only + # picklable if defined in the global scope. We therefore need to push + # various things defined in these tests into the global scope with `global` + # statements at the start of each test. + + @all_pickle_protocols + def test_pickling_then_unpickling_results_in_same_identity(self, proto): + global global_Ts1 # See explanation at start of class. + global_Ts1 = TypeVarTuple('global_Ts1') + global_Ts2 = pickle.loads(pickle.dumps(global_Ts1, proto)) + self.assertIs(global_Ts1, global_Ts2) + + @all_pickle_protocols + def test_pickling_then_unpickling_unpacked_results_in_same_identity(self, proto): + global global_Ts # See explanation at start of class. + global_Ts = TypeVarTuple('global_Ts') + + unpacked1 = (*global_Ts,)[0] + unpacked2 = pickle.loads(pickle.dumps(unpacked1, proto)) + self.assertIs(unpacked1, unpacked2) + + unpacked3 = Unpack[global_Ts] + unpacked4 = pickle.loads(pickle.dumps(unpacked3, proto)) + self.assertIs(unpacked3, unpacked4) + + @all_pickle_protocols + def test_pickling_then_unpickling_tuple_with_typevartuple_equality( + self, proto + ): + global global_T, global_Ts # See explanation at start of class. + global_T = TypeVar('global_T') + global_Ts = TypeVarTuple('global_Ts') + + tuples = [ + tuple[*global_Ts], + Tuple[Unpack[global_Ts]], + + tuple[T, *global_Ts], + Tuple[T, Unpack[global_Ts]], + + tuple[int, *global_Ts], + Tuple[int, Unpack[global_Ts]], + ] + for t in tuples: + t2 = pickle.loads(pickle.dumps(t, proto)) + self.assertEqual(t, t2) + class UnionTests(BaseTestCase): @@ -324,14 +1694,25 @@ class UnionTests(BaseTestCase): u = Union[int | float] self.assertEqual(repr(u), 'typing.Union[int, float]') + u = Union[None, str] + self.assertEqual(repr(u), 'typing.Optional[str]') + u = Union[str, None] + self.assertEqual(repr(u), 'typing.Optional[str]') + u = Union[None, str, int] + self.assertEqual(repr(u), 'typing.Union[NoneType, str, int]') + u = Optional[str] + self.assertEqual(repr(u), 'typing.Optional[str]') + def test_cannot_subclass(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.Union'): class C(Union): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(Union)): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.Union\[int, str\]'): class C(Union[int, str]): pass @@ -419,6 +1800,8 @@ class TupleTests(BaseTestCase): class MyTuple(tuple): pass self.assertIsSubclass(MyTuple, Tuple) + self.assertIsSubclass(Tuple, Tuple) + self.assertIsSubclass(tuple, Tuple) def test_tuple_instance_type_error(self): with self.assertRaises(TypeError): @@ -446,6 +1829,7 @@ class BaseCallableTests: with self.assertRaises(TypeError): issubclass(types.FunctionType, Callable[[int], int]) self.assertIsSubclass(types.FunctionType, Callable) + self.assertIsSubclass(Callable, Callable) def test_eq_hash(self): Callable = self.Callable @@ -521,6 +1905,10 @@ class BaseCallableTests: # Shouldn't crash; see https://github.com/python/typing/issues/259 typing.List[Callable[..., str]] + def test_or_and_ror(self): + Callable = self.Callable + self.assertEqual(Callable | Tuple, Union[Callable, Tuple]) + self.assertEqual(Tuple | Callable, Union[Tuple, Callable]) def test_basic(self): Callable = self.Callable @@ -553,8 +1941,10 @@ class BaseCallableTests: C2 = Callable[[KT, T], VT] C3 = Callable[..., T] self.assertEqual(C1[str], Callable[[int, str], str]) + self.assertEqual(C1[None], Callable[[int, type(None)], type(None)]) self.assertEqual(C2[int, float, str], Callable[[int, float], str]) self.assertEqual(C3[int], Callable[..., int]) + self.assertEqual(C3[NoReturn], Callable[..., NoReturn]) # multi chaining C4 = C2[int, VT, str] @@ -614,10 +2004,29 @@ class BaseCallableTests: def test_concatenate(self): Callable = self.Callable fullname = f"{Callable.__module__}.Callable" + T = TypeVar('T') P = ParamSpec('P') - C1 = Callable[typing.Concatenate[int, P], int] - self.assertEqual(repr(C1), - f"{fullname}[typing.Concatenate[int, ~P], int]") + P2 = ParamSpec('P2') + C = Callable[Concatenate[int, P], T] + self.assertEqual(repr(C), + f"{fullname}[typing.Concatenate[int, ~P], ~T]") + self.assertEqual(C[P2, int], Callable[Concatenate[int, P2], int]) + self.assertEqual(C[[str, float], int], Callable[[int, str, float], int]) + self.assertEqual(C[[], int], Callable[[int], int]) + self.assertEqual(C[Concatenate[str, P2], int], + Callable[Concatenate[int, str, P2], int]) + self.assertEqual(C[..., int], Callable[Concatenate[int, ...], int]) + + C = Callable[Concatenate[int, P], int] + self.assertEqual(repr(C), + f"{fullname}[typing.Concatenate[int, ~P], int]") + self.assertEqual(C[P2], Callable[Concatenate[int, P2], int]) + self.assertEqual(C[[str, float]], Callable[[int, str, float], int]) + self.assertEqual(C[str, float], Callable[[int, str, float], int]) + self.assertEqual(C[[]], Callable[[int], int]) + self.assertEqual(C[Concatenate[str, P2]], + Callable[Concatenate[int, str, P2], int]) + self.assertEqual(C[...], Callable[Concatenate[int, ...], int]) def test_errors(self): Callable = self.Callable @@ -919,6 +2328,32 @@ class ProtocolTests(BaseTestCase): with self.assertRaises(TypeError): CG[int](42) + def test_protocol_defining_init_does_not_get_overridden(self): + # check that P.__init__ doesn't get clobbered + # see https://bugs.python.org/issue44807 + + class P(Protocol): + x: int + def __init__(self, x: int) -> None: + self.x = x + class C: pass + + c = C() + P.__init__(c, 1) + self.assertEqual(c.x, 1) + + def test_concrete_class_inheriting_init_from_protocol(self): + class P(Protocol): + x: int + def __init__(self, x: int) -> None: + self.x = x + + class C(P): pass + + c = C(1) + self.assertIsInstance(c, C) + self.assertEqual(c.x, 1) + def test_cannot_instantiate_abstract(self): @runtime_checkable class P(Protocol): @@ -1517,7 +2952,7 @@ class ProtocolTests(BaseTestCase): self.assertEqual(x.bar, 'abc') self.assertEqual(x.x, 1) self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) - s = pickle.dumps(P) + s = pickle.dumps(P, proto) D = pickle.loads(s) class E: @@ -1663,6 +3098,11 @@ class GenericTests(BaseTestCase): class MyGeneric(Generic[T], Generic[S]): ... with self.assertRaises(TypeError): class MyGeneric(List[T], Generic[S]): ... + with self.assertRaises(TypeError): + Generic[()] + class C(Generic[T]): pass + with self.assertRaises(TypeError): + C[()] def test_init(self): T = TypeVar('T') @@ -1938,13 +3378,12 @@ class GenericTests(BaseTestCase): self.assertNotEqual(typing.FrozenSet[A[str]], typing.FrozenSet[mod_generics_cache.B.A[str]]) - if sys.version_info[:2] > (3, 2): - self.assertTrue(repr(Tuple[A[str]]).endswith('.A[str]]')) - self.assertTrue(repr(Tuple[B.A[str]]).endswith('.B.A[str]]')) - self.assertTrue(repr(Tuple[mod_generics_cache.A[str]]) - .endswith('mod_generics_cache.A[str]]')) - self.assertTrue(repr(Tuple[mod_generics_cache.B.A[str]]) - .endswith('mod_generics_cache.B.A[str]]')) + self.assertTrue(repr(Tuple[A[str]]).endswith('.A[str]]')) + self.assertTrue(repr(Tuple[B.A[str]]).endswith('.B.A[str]]')) + self.assertTrue(repr(Tuple[mod_generics_cache.A[str]]) + .endswith('mod_generics_cache.A[str]]')) + self.assertTrue(repr(Tuple[mod_generics_cache.B.A[str]]) + .endswith('mod_generics_cache.B.A[str]]')) def test_extended_generic_rules_eq(self): T = TypeVar('T') @@ -1959,9 +3398,6 @@ class GenericTests(BaseTestCase): class Base: ... class Derived(Base): ... self.assertEqual(Union[T, Base][Union[Base, Derived]], Union[Base, Derived]) - with self.assertRaises(TypeError): - Union[T, int][1] - self.assertEqual(Callable[[T], T][KT], Callable[[KT], KT]) self.assertEqual(Callable[..., List[T]][int], Callable[..., List[int]]) @@ -2002,6 +3438,45 @@ class GenericTests(BaseTestCase): def barfoo2(x: CT): ... self.assertIs(get_type_hints(barfoo2, globals(), locals())['x'], CT) + def test_generic_pep585_forward_ref(self): + # See https://bugs.python.org/issue41370 + + class C1: + a: list['C1'] + self.assertEqual( + get_type_hints(C1, globals(), locals()), + {'a': list[C1]} + ) + + class C2: + a: dict['C1', list[List[list['C2']]]] + self.assertEqual( + get_type_hints(C2, globals(), locals()), + {'a': dict[C1, list[List[list[C2]]]]} + ) + + # Test stringified annotations + scope = {} + exec(textwrap.dedent(''' + from __future__ import annotations + class C3: + a: List[list["C2"]] + '''), scope) + C3 = scope['C3'] + self.assertEqual(C3.__annotations__['a'], "List[list['C2']]") + self.assertEqual( + get_type_hints(C3, globals(), locals()), + {'a': List[list[C2]]} + ) + + # Test recursive types + X = list["X"] + def f(x: X): ... + self.assertEqual( + get_type_hints(f, globals(), locals()), + {'x': list[list[ForwardRef('X')]]} + ) + def test_extended_generic_rules_subclassing(self): class T1(Tuple[T, KT]): ... class T2(Tuple[T, ...]): ... @@ -2037,7 +3512,7 @@ class GenericTests(BaseTestCase): with self.assertRaises(TypeError): Tuple[Optional] with self.assertRaises(TypeError): - ClassVar[ClassVar] + ClassVar[ClassVar[int]] with self.assertRaises(TypeError): List[ClassVar[int]] @@ -2063,18 +3538,19 @@ class GenericTests(BaseTestCase): class MyDef(typing.DefaultDict[str, T]): ... self.assertIs(MyDef[int]().__class__, MyDef) self.assertEqual(MyDef[int]().__orig_class__, MyDef[int]) - # ChainMap was added in 3.3 - if sys.version_info >= (3, 3): - class MyChain(typing.ChainMap[str, T]): ... - self.assertIs(MyChain[int]().__class__, MyChain) - self.assertEqual(MyChain[int]().__orig_class__, MyChain[int]) + class MyChain(typing.ChainMap[str, T]): ... + self.assertIs(MyChain[int]().__class__, MyChain) + self.assertEqual(MyChain[int]().__orig_class__, MyChain[int]) def test_all_repr_eq_any(self): objs = (getattr(typing, el) for el in typing.__all__) for obj in objs: self.assertNotEqual(repr(obj), '') self.assertEqual(obj, obj) - if getattr(obj, '__parameters__', None) and len(obj.__parameters__) == 1: + if (getattr(obj, '__parameters__', None) + and not isinstance(obj, typing.TypeVar) + and isinstance(obj.__parameters__, tuple) + and len(obj.__parameters__) == 1): self.assertEqual(obj[Any].__args__, (Any,)) if isinstance(obj, type): for base in obj.__mro__: @@ -2101,7 +3577,8 @@ class GenericTests(BaseTestCase): self.assertEqual(x.bar, 'abc') self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) samples = [Any, Union, Tuple, Callable, ClassVar, - Union[int, str], ClassVar[List], Tuple[int, ...], Callable[[str], bytes], + Union[int, str], ClassVar[List], Tuple[int, ...], Tuple[()], + Callable[[str], bytes], typing.DefaultDict, typing.FrozenSet[int]] for s in samples: for proto in range(pickle.HIGHEST_PROTOCOL + 1): @@ -2119,7 +3596,8 @@ class GenericTests(BaseTestCase): def test_copy_and_deepcopy(self): T = TypeVar('T') class Node(Generic[T]): ... - things = [Union[T, int], Tuple[T, int], Callable[..., T], Callable[[int], int], + things = [Union[T, int], Tuple[T, int], Tuple[()], + Callable[..., T], Callable[[int], int], Tuple[Any, Any], Node[T], Node[int], Node[Any], typing.Iterable[T], typing.Iterable[Any], typing.Iterable[int], typing.Dict[int, str], typing.Dict[T, Any], ClassVar[int], ClassVar[List[T]], Tuple['T', 'T'], @@ -2131,22 +3609,30 @@ class GenericTests(BaseTestCase): def test_immutability_by_copy_and_pickle(self): # Special forms like Union, Any, etc., generic aliases to containers like List, # Mapping, etc., and type variabcles are considered immutable by copy and pickle. - global TP, TPB, TPV # for pickle + global TP, TPB, TPV, PP # for pickle TP = TypeVar('TP') TPB = TypeVar('TPB', bound=int) TPV = TypeVar('TPV', bytes, str) - for X in [TP, TPB, TPV, List, typing.Mapping, ClassVar, typing.Iterable, + PP = ParamSpec('PP') + for X in [TP, TPB, TPV, PP, + List, typing.Mapping, ClassVar, typing.Iterable, Union, Any, Tuple, Callable]: - self.assertIs(copy(X), X) - self.assertIs(deepcopy(X), X) - self.assertIs(pickle.loads(pickle.dumps(X)), X) + with self.subTest(thing=X): + self.assertIs(copy(X), X) + self.assertIs(deepcopy(X), X) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.assertIs(pickle.loads(pickle.dumps(X, proto)), X) + del TP, TPB, TPV, PP + # Check that local type variables are copyable. TL = TypeVar('TL') TLB = TypeVar('TLB', bound=int) TLV = TypeVar('TLV', bytes, str) - for X in [TL, TLB, TLV]: - self.assertIs(copy(X), X) - self.assertIs(deepcopy(X), X) + PL = ParamSpec('PL') + for X in [TL, TLB, TLV, PL]: + with self.subTest(thing=X): + self.assertIs(copy(X), X) + self.assertIs(deepcopy(X), X) def test_copy_generic_instances(self): T = TypeVar('T') @@ -2360,11 +3846,11 @@ class GenericTests(BaseTestCase): self.assertEqual(D.__parameters__, ()) - with self.assertRaises(Exception): + with self.assertRaises(TypeError): D[int] - with self.assertRaises(Exception): + with self.assertRaises(TypeError): D[Any] - with self.assertRaises(Exception): + with self.assertRaises(TypeError): D[T] def test_new_with_args(self): @@ -2453,11 +3939,66 @@ class GenericTests(BaseTestCase): class Foo(obj): pass + def test_complex_subclasses(self): + T_co = TypeVar("T_co", covariant=True) + + class Base(Generic[T_co]): + ... + + T = TypeVar("T") + + # see gh-94607: this fails in that bug + class Sub(Base, Generic[T]): + ... + + def test_parameter_detection(self): + self.assertEqual(List[T].__parameters__, (T,)) + self.assertEqual(List[List[T]].__parameters__, (T,)) + class A: + __parameters__ = (T,) + # Bare classes should be skipped + for a in (List, list): + for b in (A, int, TypeVar, TypeVarTuple, ParamSpec, types.GenericAlias, types.UnionType): + with self.subTest(generic=a, sub=b): + with self.assertRaisesRegex(TypeError, '.* is not a generic class'): + a[b][str] + # Duck-typing anything that looks like it has __parameters__. + # These tests are optional and failure is okay. + self.assertEqual(List[A()].__parameters__, (T,)) + # C version of GenericAlias + self.assertEqual(list[A()].__parameters__, (T,)) + + def test_non_generic_subscript(self): + T = TypeVar('T') + class G(Generic[T]): + pass + class A: + __parameters__ = (T,) + + for s in (int, G, A, List, list, + TypeVar, TypeVarTuple, ParamSpec, + types.GenericAlias, types.UnionType): + + for t in Tuple, tuple: + with self.subTest(tuple=t, sub=s): + self.assertEqual(t[s, T][int], t[s, int]) + self.assertEqual(t[T, s][int], t[int, s]) + a = t[s] + with self.assertRaises(TypeError): + a[int] + + for c in Callable, collections.abc.Callable: + with self.subTest(callable=c, sub=s): + self.assertEqual(c[[s], T][int], c[[s], int]) + self.assertEqual(c[[T], s][int], c[[int], s]) + a = c[[s], s] + with self.assertRaises(TypeError): + a[int] + + class ClassVarTests(BaseTestCase): def test_basics(self): - with self.assertRaises(TypeError): - ClassVar[1] with self.assertRaises(TypeError): ClassVar[int, str] with self.assertRaises(TypeError): @@ -2471,12 +4012,20 @@ class ClassVarTests(BaseTestCase): self.assertEqual(repr(cv), 'typing.ClassVar[%s.Employee]' % __name__) def test_cannot_subclass(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(ClassVar)): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(ClassVar[int])): pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.ClassVar'): + class C(ClassVar): + pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.ClassVar\[int\]'): + class C(ClassVar[int]): + pass def test_cannot_init(self): with self.assertRaises(TypeError): @@ -2496,8 +4045,6 @@ class FinalTests(BaseTestCase): def test_basics(self): Final[int] # OK - with self.assertRaises(TypeError): - Final[1] with self.assertRaises(TypeError): Final[int, str] with self.assertRaises(TypeError): @@ -2515,12 +4062,20 @@ class FinalTests(BaseTestCase): self.assertEqual(repr(cv), 'typing.Final[tuple[int]]') def test_cannot_subclass(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(Final)): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(Final[int])): pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.Final'): + class C(Final): + pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.Final\[int\]'): + class C(Final[int]): + pass def test_cannot_init(self): with self.assertRaises(TypeError): @@ -2536,10 +4091,80 @@ class FinalTests(BaseTestCase): with self.assertRaises(TypeError): issubclass(int, Final) + +class FinalDecoratorTests(BaseTestCase): def test_final_unmodified(self): def func(x): ... self.assertIs(func, final(func)) + def test_dunder_final(self): + @final + def func(): ... + @final + class Cls: ... + self.assertIs(True, func.__final__) + self.assertIs(True, Cls.__final__) + + class Wrapper: + __slots__ = ("func",) + def __init__(self, func): + self.func = func + def __call__(self, *args, **kwargs): + return self.func(*args, **kwargs) + + # Check that no error is thrown if the attribute + # is not writable. + @final + @Wrapper + def wrapped(): ... + self.assertIsInstance(wrapped, Wrapper) + self.assertIs(False, hasattr(wrapped, "__final__")) + + class Meta(type): + @property + def __final__(self): return "can't set me" + @final + class WithMeta(metaclass=Meta): ... + self.assertEqual(WithMeta.__final__, "can't set me") + + # Builtin classes throw TypeError if you try to set an + # attribute. + final(int) + self.assertIs(False, hasattr(int, "__final__")) + + # Make sure it works with common builtin decorators + class Methods: + @final + @classmethod + def clsmethod(cls): ... + + @final + @staticmethod + def stmethod(): ... + + # The other order doesn't work because property objects + # don't allow attribute assignment. + @property + @final + def prop(self): ... + + @final + @lru_cache() + def cached(self): ... + + # Use getattr_static because the descriptor returns the + # underlying function, which doesn't have __final__. + self.assertIs( + True, + inspect.getattr_static(Methods, "clsmethod").__final__ + ) + self.assertIs( + True, + inspect.getattr_static(Methods, "stmethod").__final__ + ) + self.assertIs(True, Methods.prop.fget.__final__) + self.assertIs(True, Methods.cached.__final__) + class CastTests(BaseTestCase): @@ -2559,6 +4184,34 @@ class CastTests(BaseTestCase): cast('hello', 42) +class AssertTypeTests(BaseTestCase): + + def test_basics(self): + arg = 42 + self.assertIs(assert_type(arg, int), arg) + self.assertIs(assert_type(arg, str | float), arg) + self.assertIs(assert_type(arg, AnyStr), arg) + self.assertIs(assert_type(arg, None), arg) + + def test_errors(self): + # Bogus calls are not expected to fail. + arg = 42 + self.assertIs(assert_type(arg, 42), arg) + self.assertIs(assert_type(arg, 'hello'), arg) + + +# We need this to make sure that `@no_type_check` respects `__module__` attr: +from test import ann_module8 + +@no_type_check +class NoTypeCheck_Outer: + Inner = ann_module8.NoTypeCheck_Outer.Inner + +@no_type_check +class NoTypeCheck_WithFunction: + NoTypeCheck_function = ann_module8.NoTypeCheck_function + + class ForwardRefTests(BaseTestCase): def test_basics(self): @@ -2586,16 +4239,15 @@ class ForwardRefTests(BaseTestCase): t = Node[int] both_hints = get_type_hints(t.add_both, globals(), locals()) self.assertEqual(both_hints['left'], Optional[Node[T]]) - self.assertEqual(both_hints['right'], Optional[Node[T]]) - self.assertEqual(both_hints['left'], both_hints['right']) - self.assertEqual(both_hints['stuff'], Optional[int]) + self.assertEqual(both_hints['right'], Node[T]) + self.assertEqual(both_hints['stuff'], int) self.assertNotIn('blah', both_hints) left_hints = get_type_hints(t.add_left, globals(), locals()) self.assertEqual(left_hints['node'], Optional[Node[T]]) right_hints = get_type_hints(t.add_right, globals(), locals()) - self.assertEqual(right_hints['node'], Optional[Node[T]]) + self.assertEqual(right_hints['node'], Node[T]) def test_forwardref_instance_type_error(self): fr = typing.ForwardRef('int') @@ -2607,10 +4259,18 @@ class ForwardRefTests(BaseTestCase): with self.assertRaises(TypeError): issubclass(int, fr) + def test_forwardref_only_str_arg(self): + with self.assertRaises(TypeError): + typing.ForwardRef(1) # only `str` type is allowed + def test_forward_equality(self): fr = typing.ForwardRef('int') self.assertEqual(fr, typing.ForwardRef('int')) self.assertNotEqual(List['int'], List[int]) + self.assertNotEqual(fr, typing.ForwardRef('int', module=__name__)) + frm = typing.ForwardRef('int', module=__name__) + self.assertEqual(frm, typing.ForwardRef('int', module=__name__)) + self.assertNotEqual(frm, typing.ForwardRef('int', module='__other_name__')) def test_forward_equality_gth(self): c1 = typing.ForwardRef('C') @@ -2647,6 +4307,14 @@ class ForwardRefTests(BaseTestCase): self.assertEqual(hash(c1_gth), hash(c2_gth)) self.assertEqual(hash(c1), hash(c1_gth)) + c3 = typing.ForwardRef('int', module=__name__) + c4 = typing.ForwardRef('int', module='__other_name__') + + self.assertNotEqual(hash(c3), hash(c1)) + self.assertNotEqual(hash(c3), hash(c1_gth)) + self.assertNotEqual(hash(c3), hash(c4)) + self.assertEqual(hash(c3), hash(typing.ForwardRef('int', module=__name__))) + def test_forward_equality_namespace(self): class A: pass @@ -2673,6 +4341,8 @@ class ForwardRefTests(BaseTestCase): def test_forward_repr(self): self.assertEqual(repr(List['int']), "typing.List[ForwardRef('int')]") + self.assertEqual(repr(List[ForwardRef('int', module='mod')]), + "typing.List[ForwardRef('int', module='mod')]") def test_union_forward(self): @@ -2781,6 +4451,24 @@ class ForwardRefTests(BaseTestCase): self.assertEqual(get_type_hints(foo, globals(), locals()), {'a': Callable[..., T]}) + def test_special_forms_forward(self): + + class C: + a: Annotated['ClassVar[int]', (3, 5)] = 4 + b: Annotated['Final[int]', "const"] = 4 + x: 'ClassVar' = 4 + y: 'Final' = 4 + + class CF: + b: List['Final[int]'] = 4 + + self.assertEqual(get_type_hints(C, globals())['a'], ClassVar[int]) + self.assertEqual(get_type_hints(C, globals())['b'], Final[int]) + self.assertEqual(get_type_hints(C, globals())['x'], ClassVar) + self.assertEqual(get_type_hints(C, globals())['y'], Final) + with self.assertRaises(TypeError): + get_type_hints(CF, globals()), + def test_syntax_error(self): with self.assertRaises(SyntaxError): @@ -2794,14 +4482,6 @@ class ForwardRefTests(BaseTestCase): with self.assertRaises(SyntaxError): get_type_hints(foo) - def test_type_error(self): - - def foo(a: Tuple['42']): - pass - - with self.assertRaises(TypeError): - get_type_hints(foo) - def test_name_error(self): def foo(a: 'Noode[T]'): @@ -2837,9 +4517,98 @@ class ForwardRefTests(BaseTestCase): @no_type_check class D(C): c = C + # verify that @no_type_check never affects bases self.assertEqual(get_type_hints(C.meth), {'x': int}) + # and never child classes: + class Child(D): + def foo(self, x: int): ... + + self.assertEqual(get_type_hints(Child.foo), {'x': int}) + + def test_no_type_check_nested_types(self): + # See https://bugs.python.org/issue46571 + class Other: + o: int + class B: # Has the same `__name__`` as `A.B` and different `__qualname__` + o: int + @no_type_check + class A: + a: int + class B: + b: int + class C: + c: int + class D: + d: int + + Other = Other + + for klass in [A, A.B, A.B.C, A.D]: + with self.subTest(klass=klass): + self.assertTrue(klass.__no_type_check__) + self.assertEqual(get_type_hints(klass), {}) + + for not_modified in [Other, B]: + with self.subTest(not_modified=not_modified): + with self.assertRaises(AttributeError): + not_modified.__no_type_check__ + self.assertNotEqual(get_type_hints(not_modified), {}) + + def test_no_type_check_class_and_static_methods(self): + @no_type_check + class Some: + @staticmethod + def st(x: int) -> int: ... + @classmethod + def cl(cls, y: int) -> int: ... + + self.assertTrue(Some.st.__no_type_check__) + self.assertEqual(get_type_hints(Some.st), {}) + self.assertTrue(Some.cl.__no_type_check__) + self.assertEqual(get_type_hints(Some.cl), {}) + + def test_no_type_check_other_module(self): + self.assertTrue(NoTypeCheck_Outer.__no_type_check__) + with self.assertRaises(AttributeError): + ann_module8.NoTypeCheck_Outer.__no_type_check__ + with self.assertRaises(AttributeError): + ann_module8.NoTypeCheck_Outer.Inner.__no_type_check__ + + self.assertTrue(NoTypeCheck_WithFunction.__no_type_check__) + with self.assertRaises(AttributeError): + ann_module8.NoTypeCheck_function.__no_type_check__ + + def test_no_type_check_foreign_functions(self): + # We should not modify this function: + def some(*args: int) -> int: + ... + + @no_type_check + class A: + some_alias = some + some_class = classmethod(some) + some_static = staticmethod(some) + + with self.assertRaises(AttributeError): + some.__no_type_check__ + self.assertEqual(get_type_hints(some), {'args': int, 'return': int}) + + def test_no_type_check_lambda(self): + @no_type_check + class A: + # Corner case: `lambda` is both an assignment and a function: + bar: Callable[[int], int] = lambda arg: arg + + self.assertTrue(A.bar.__no_type_check__) + self.assertEqual(get_type_hints(A.bar), {}) + + def test_no_type_check_TypeError(self): + # This simply should not fail with + # `TypeError: can't set attributes of built-in/extension type 'dict'` + no_type_check(dict) + def test_no_type_check_forward_ref_as_string(self): class C: foo: typing.ClassVar[int] = 7 @@ -2912,12 +4681,23 @@ class ForwardRefTests(BaseTestCase): self.assertEqual("x" | X, Union["x", X]) +@lru_cache() +def cached_func(x, y): + return 3 * x + y + + +class MethodHolder: + @classmethod + def clsmethod(cls): ... + @staticmethod + def stmethod(): ... + def method(self): ... + + class OverloadTests(BaseTestCase): def test_overload_fails(self): - from typing import overload - - with self.assertRaises(RuntimeError): + with self.assertRaises(NotImplementedError): @overload def blah(): @@ -2926,8 +4706,6 @@ class OverloadTests(BaseTestCase): blah() def test_overload_succeeds(self): - from typing import overload - @overload def blah(): pass @@ -2937,8 +4715,80 @@ class OverloadTests(BaseTestCase): blah() + @cpython_only # gh-98713 + def test_overload_on_compiled_functions(self): + with patch("typing._overload_registry", + defaultdict(lambda: defaultdict(dict))): + # The registry starts out empty: + self.assertEqual(typing._overload_registry, {}) -ASYNCIO_TESTS = """ + # This should just not fail: + overload(sum) + overload(print) + + # No overloads are recorded (but, it still has a side-effect): + self.assertEqual(typing.get_overloads(sum), []) + self.assertEqual(typing.get_overloads(print), []) + + def set_up_overloads(self): + def blah(): + pass + + overload1 = blah + overload(blah) + + def blah(): + pass + + overload2 = blah + overload(blah) + + def blah(): + pass + + return blah, [overload1, overload2] + + # Make sure we don't clear the global overload registry + @patch("typing._overload_registry", + defaultdict(lambda: defaultdict(dict))) + def test_overload_registry(self): + # The registry starts out empty + self.assertEqual(typing._overload_registry, {}) + + impl, overloads = self.set_up_overloads() + self.assertNotEqual(typing._overload_registry, {}) + self.assertEqual(list(get_overloads(impl)), overloads) + + def some_other_func(): pass + overload(some_other_func) + other_overload = some_other_func + def some_other_func(): pass + self.assertEqual(list(get_overloads(some_other_func)), [other_overload]) + # Unrelated function still has no overloads: + def not_overloaded(): pass + self.assertEqual(list(get_overloads(not_overloaded)), []) + + # Make sure that after we clear all overloads, the registry is + # completely empty. + clear_overloads() + self.assertEqual(typing._overload_registry, {}) + self.assertEqual(get_overloads(impl), []) + + # Querying a function with no overloads shouldn't change the registry. + def the_only_one(): pass + self.assertEqual(get_overloads(the_only_one), []) + self.assertEqual(typing._overload_registry, {}) + + def test_overload_registry_repeated(self): + for _ in range(2): + impl, overloads = self.set_up_overloads() + + self.assertEqual(list(get_overloads(impl)), overloads) + + +# Definitions needed for features introduced in Python 3.6 + +from test import ann_module, ann_module2, ann_module3, ann_module5, ann_module6 import asyncio T_a = TypeVar('T_a') @@ -2972,19 +4822,6 @@ class ACM: return 42 async def __aexit__(self, etype, eval, tb): return None -""" - -try: - exec(ASYNCIO_TESTS) -except ImportError: - ASYNCIO = False # multithreading is not enabled -else: - ASYNCIO = True - -# Definitions needed for features introduced in Python 3.6 - -from test import ann_module, ann_module2, ann_module3, ann_module5, ann_module6 -from typing import AsyncContextManager class A: y: float @@ -3031,20 +4868,47 @@ class Point2D(TypedDict): x: int y: int +class Point2DGeneric(Generic[T], TypedDict): + a: T + b: T + class Bar(_typed_dict_helper.Foo, total=False): b: int +class BarGeneric(_typed_dict_helper.FooGeneric[T], total=False): + b: int + class LabelPoint2D(Point2D, Label): ... class Options(TypedDict, total=False): log_level: int log_path: str +class TotalMovie(TypedDict): + title: str + year: NotRequired[int] + +class NontotalMovie(TypedDict, total=False): + title: Required[str] + year: int + +class AnnotatedMovie(TypedDict): + title: Annotated[Required[str], "foobar"] + year: NotRequired[Annotated[int, 2000]] + +class DeeplyAnnotatedMovie(TypedDict): + title: Annotated[Annotated[Required[str], "foobar"], "another level"] + year: NotRequired[Annotated[int, 2000]] + +class WeirdlyQuotedMovie(TypedDict): + title: Annotated['Annotated[Required[str], "foobar"]', "another level"] + year: NotRequired['Annotated[int, 2000]'] + class HasForeignBaseClass(mod_generics_cache.A): some_xrepr: 'XRepr' other_a: 'mod_generics_cache.A' -async def g_with(am: AsyncContextManager[int]): +async def g_with(am: typing.AsyncContextManager[int]): x: int async with am as x: return x @@ -3116,6 +4980,12 @@ class GetTypeHintTests(BaseTestCase): 'my_inner_a2': mod_generics_cache.B.A, 'my_outer_a': mod_generics_cache.A}) + def test_get_type_hints_classes_no_implicit_optional(self): + class WithNoneDefault: + field: int = None # most type-checkers won't be happy with it + + self.assertEqual(gth(WithNoneDefault), {'field': int}) + def test_respect_no_type_check(self): @no_type_check class NoTpCheck: @@ -3195,7 +5065,7 @@ class GetTypeHintTests(BaseTestCase): BA = Tuple[Annotated[T, (1, 0)], ...] def barfoo(x: BA): ... self.assertEqual(get_type_hints(barfoo, globals(), locals())['x'], Tuple[T, ...]) - self.assertIs( + self.assertEqual( get_type_hints(barfoo, globals(), locals(), include_extras=True)['x'], BA ) @@ -3203,7 +5073,7 @@ class GetTypeHintTests(BaseTestCase): BA = tuple[Annotated[T, (1, 0)], ...] def barfoo(x: BA): ... self.assertEqual(get_type_hints(barfoo, globals(), locals())['x'], tuple[T, ...]) - self.assertIs( + self.assertEqual( get_type_hints(barfoo, globals(), locals(), include_extras=True)['x'], BA ) @@ -3232,6 +5102,15 @@ class GetTypeHintTests(BaseTestCase): {"x": typing.Annotated[int | float, "const"]} ) + def test_get_type_hints_annotated_in_union(self): # bpo-46603 + def with_union(x: int | list[Annotated[str, 'meta']]): ... + + self.assertEqual(get_type_hints(with_union), {'x': int | list[str]}) + self.assertEqual( + get_type_hints(with_union, include_extras=True), + {'x': int | list[Annotated[str, 'meta']]}, + ) + def test_get_type_hints_annotated_refs(self): Const = Annotated[T, "Const"] @@ -3259,6 +5138,18 @@ class GetTypeHintTests(BaseTestCase): {'other': MySet[T], 'return': MySet[T]} ) + def test_get_type_hints_annotated_with_none_default(self): + # See: https://bugs.python.org/issue46195 + def annotated_with_none_default(x: Annotated[int, 'data'] = None): ... + self.assertEqual( + get_type_hints(annotated_with_none_default), + {'x': int}, + ) + self.assertEqual( + get_type_hints(annotated_with_none_default, include_extras=True), + {'x': Annotated[int, 'data']}, + ) + def test_get_type_hints_classes_str_annotations(self): class Foo: y = str @@ -3300,10 +5191,52 @@ class GetTypeHintTests(BaseTestCase): ): get_type_hints(ann_module6) + def test_get_type_hints_typeddict(self): + self.assertEqual(get_type_hints(TotalMovie), {'title': str, 'year': int}) + self.assertEqual(get_type_hints(TotalMovie, include_extras=True), { + 'title': str, + 'year': NotRequired[int], + }) + + self.assertEqual(get_type_hints(AnnotatedMovie), {'title': str, 'year': int}) + self.assertEqual(get_type_hints(AnnotatedMovie, include_extras=True), { + 'title': Annotated[Required[str], "foobar"], + 'year': NotRequired[Annotated[int, 2000]], + }) + + self.assertEqual(get_type_hints(DeeplyAnnotatedMovie), {'title': str, 'year': int}) + self.assertEqual(get_type_hints(DeeplyAnnotatedMovie, include_extras=True), { + 'title': Annotated[Required[str], "foobar", "another level"], + 'year': NotRequired[Annotated[int, 2000]], + }) + + self.assertEqual(get_type_hints(WeirdlyQuotedMovie), {'title': str, 'year': int}) + self.assertEqual(get_type_hints(WeirdlyQuotedMovie, include_extras=True), { + 'title': Annotated[Required[str], "foobar", "another level"], + 'year': NotRequired[Annotated[int, 2000]], + }) + + self.assertEqual(get_type_hints(_typed_dict_helper.VeryAnnotated), {'a': int}) + self.assertEqual(get_type_hints(_typed_dict_helper.VeryAnnotated, include_extras=True), { + 'a': Annotated[Required[int], "a", "b", "c"] + }) + + def test_get_type_hints_collections_abc_callable(self): + # https://github.com/python/cpython/issues/91621 + P = ParamSpec('P') + def f(x: collections.abc.Callable[[int], int]): ... + def g(x: collections.abc.Callable[..., int]): ... + def h(x: collections.abc.Callable[P, int]): ... + + self.assertEqual(get_type_hints(f), {'x': collections.abc.Callable[[int], int]}) + self.assertEqual(get_type_hints(g), {'x': collections.abc.Callable[..., int]}) + self.assertEqual(get_type_hints(h), {'x': collections.abc.Callable[P, int]}) + class GetUtilitiesTestCase(TestCase): def test_get_origin(self): T = TypeVar('T') + Ts = TypeVarTuple('Ts') P = ParamSpec('P') class C(Generic[T]): pass self.assertIs(get_origin(C[int]), C) @@ -3325,27 +5258,44 @@ class GetUtilitiesTestCase(TestCase): self.assertIs(get_origin(list | str), types.UnionType) self.assertIs(get_origin(P.args), P) self.assertIs(get_origin(P.kwargs), P) + self.assertIs(get_origin(Required[int]), Required) + self.assertIs(get_origin(NotRequired[int]), NotRequired) + self.assertIs(get_origin((*Ts,)[0]), Unpack) + self.assertIs(get_origin(Unpack[Ts]), Unpack) + self.assertIs(get_origin((*tuple[*Ts],)[0]), tuple) + self.assertIs(get_origin(Unpack[Tuple[Unpack[Ts]]]), Unpack) def test_get_args(self): T = TypeVar('T') class C(Generic[T]): pass self.assertEqual(get_args(C[int]), (int,)) self.assertEqual(get_args(C[T]), (T,)) + self.assertEqual(get_args(typing.SupportsAbs[int]), (int,)) # Protocol + self.assertEqual(get_args(typing.SupportsAbs[T]), (T,)) + self.assertEqual(get_args(Point2DGeneric[int]), (int,)) # TypedDict + self.assertEqual(get_args(Point2DGeneric[T]), (T,)) + self.assertEqual(get_args(T), ()) self.assertEqual(get_args(int), ()) + self.assertEqual(get_args(Any), ()) + self.assertEqual(get_args(Self), ()) + self.assertEqual(get_args(LiteralString), ()) self.assertEqual(get_args(ClassVar[int]), (int,)) self.assertEqual(get_args(Union[int, str]), (int, str)) self.assertEqual(get_args(Literal[42, 43]), (42, 43)) self.assertEqual(get_args(Final[List[int]]), (List[int],)) + self.assertEqual(get_args(Optional[int]), (int, type(None))) + self.assertEqual(get_args(Union[int, None]), (int, type(None))) self.assertEqual(get_args(Union[int, Tuple[T, int]][str]), (int, Tuple[str, int])) self.assertEqual(get_args(typing.Dict[int, Tuple[T, T]][Optional[int]]), (int, Tuple[Optional[int], Optional[int]])) self.assertEqual(get_args(Callable[[], T][int]), ([], int)) self.assertEqual(get_args(Callable[..., int]), (..., int)) + self.assertEqual(get_args(Callable[[int], str]), ([int], str)) self.assertEqual(get_args(Union[int, Callable[[Tuple[T, ...]], str]]), (int, Callable[[Tuple[T, ...]], str])) self.assertEqual(get_args(Tuple[int, ...]), (int, ...)) - self.assertEqual(get_args(Tuple[()]), ((),)) + self.assertEqual(get_args(Tuple[()]), ()) self.assertEqual(get_args(Annotated[T, 'one', 2, ['three']]), (T, 'one', 2, ['three'])) self.assertEqual(get_args(List), ()) self.assertEqual(get_args(Tuple), ()) @@ -3358,10 +5308,29 @@ class GetUtilitiesTestCase(TestCase): self.assertEqual(get_args(collections.abc.Callable[[int], str]), get_args(Callable[[int], str])) P = ParamSpec('P') + self.assertEqual(get_args(P), ()) + self.assertEqual(get_args(P.args), ()) + self.assertEqual(get_args(P.kwargs), ()) self.assertEqual(get_args(Callable[P, int]), (P, int)) + self.assertEqual(get_args(collections.abc.Callable[P, int]), (P, int)) self.assertEqual(get_args(Callable[Concatenate[int, P], int]), (Concatenate[int, P], int)) + self.assertEqual(get_args(collections.abc.Callable[Concatenate[int, P], int]), + (Concatenate[int, P], int)) + self.assertEqual(get_args(Concatenate[int, str, P]), (int, str, P)) self.assertEqual(get_args(list | str), (list, str)) + self.assertEqual(get_args(Required[int]), (int,)) + self.assertEqual(get_args(NotRequired[int]), (int,)) + self.assertEqual(get_args(TypeAlias), ()) + self.assertEqual(get_args(TypeGuard[int]), (int,)) + Ts = TypeVarTuple('Ts') + self.assertEqual(get_args(Ts), ()) + self.assertEqual(get_args((*Ts,)[0]), (Ts,)) + self.assertEqual(get_args(Unpack[Ts]), (Ts,)) + self.assertEqual(get_args(tuple[*Ts]), (*Ts,)) + self.assertEqual(get_args(tuple[Unpack[Ts]]), (Unpack[Ts],)) + self.assertEqual(get_args((*tuple[*Ts],)[0]), (*Ts,)) + self.assertEqual(get_args(Unpack[tuple[Unpack[Ts]]]), (tuple[Unpack[Ts]],)) class CollectionsAbcTests(BaseTestCase): @@ -3386,7 +5355,6 @@ class CollectionsAbcTests(BaseTestCase): self.assertIsInstance(it, typing.Iterator) self.assertNotIsInstance(42, typing.Iterator) - @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') def test_awaitable(self): ns = {} exec( @@ -3399,7 +5367,6 @@ class CollectionsAbcTests(BaseTestCase): self.assertNotIsInstance(foo, typing.Awaitable) g.send(None) # Run foo() till completion, to avoid warning. - @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') def test_coroutine(self): ns = {} exec( @@ -3417,7 +5384,6 @@ class CollectionsAbcTests(BaseTestCase): except StopIteration: pass - @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') def test_async_iterable(self): base_it = range(10) # type: Iterator[int] it = AsyncIteratorWrapper(base_it) @@ -3425,7 +5391,6 @@ class CollectionsAbcTests(BaseTestCase): self.assertIsInstance(it, typing.AsyncIterable) self.assertNotIsInstance(42, typing.AsyncIterable) - @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') def test_async_iterator(self): base_it = range(10) # type: Iterator[int] it = AsyncIteratorWrapper(base_it) @@ -3441,11 +5406,10 @@ class CollectionsAbcTests(BaseTestCase): self.assertNotIsInstance(42, typing.Container) def test_collection(self): - if hasattr(typing, 'Collection'): - self.assertIsInstance(tuple(), typing.Collection) - self.assertIsInstance(frozenset(), typing.Collection) - self.assertIsSubclass(dict, typing.Collection) - self.assertNotIsInstance(42, typing.Collection) + self.assertIsInstance(tuple(), typing.Collection) + self.assertIsInstance(frozenset(), typing.Collection) + self.assertIsSubclass(dict, typing.Collection) + self.assertNotIsInstance(42, typing.Collection) def test_abstractset(self): self.assertIsInstance(set(), typing.AbstractSet) @@ -3580,7 +5544,6 @@ class CollectionsAbcTests(BaseTestCase): self.assertIsSubclass(MyOrdDict, collections.OrderedDict) self.assertNotIsSubclass(collections.OrderedDict, MyOrdDict) - @skipUnless(sys.version_info >= (3, 3), 'ChainMap was added in 3.3') def test_chainmap_instantiation(self): self.assertIs(type(typing.ChainMap()), collections.ChainMap) self.assertIs(type(typing.ChainMap[KT, VT]()), collections.ChainMap) @@ -3588,7 +5551,6 @@ class CollectionsAbcTests(BaseTestCase): class CM(typing.ChainMap[KT, VT]): ... self.assertIs(type(CM[int, str]()), CM) - @skipUnless(sys.version_info >= (3, 3), 'ChainMap was added in 3.3') def test_chainmap_subclass(self): class MyChainMap(typing.ChainMap[str, int]): @@ -3840,6 +5802,10 @@ class CollectionsAbcTests(BaseTestCase): A.register(B) self.assertIsSubclass(B, typing.Mapping) + def test_or_and_ror(self): + self.assertEqual(typing.Sized | typing.Awaitable, Union[typing.Sized, typing.Awaitable]) + self.assertEqual(typing.Coroutine | typing.Hashable, Union[typing.Coroutine, typing.Hashable]) + class OtherABCTests(BaseTestCase): @@ -3852,7 +5818,6 @@ class OtherABCTests(BaseTestCase): self.assertIsInstance(cm, typing.ContextManager) self.assertNotIsInstance(42, typing.ContextManager) - @skipUnless(ASYNCIO, 'Python 3.5 required') def test_async_contextmanager(self): class NotACM: pass @@ -4005,6 +5970,17 @@ class NewTypeTests: ) exec(code, {}) + def test_error_message_when_subclassing(self): + with self.assertRaisesRegex( + TypeError, + re.escape( + "Cannot subclass an instance of NewType. Perhaps you were looking for: " + "`ProUserId = NewType('ProUserId', UserId)`" + ) + ): + class ProUserId(UserId): + ... + class NewTypePythonTests(NewTypeTests, BaseTestCase): module = py_typing @@ -4036,14 +6012,6 @@ class NamedTupleTests(BaseTestCase): self.assertEqual(Emp.__annotations__, collections.OrderedDict([('name', str), ('id', int)])) - def test_namedtuple_pyversion(self): - if sys.version_info[:2] < (3, 6): - with self.assertRaises(TypeError): - NamedTuple('Name', one=int, other=str) - with self.assertRaises(TypeError): - class NotYet(NamedTuple): - whatever = 0 - def test_annotation_usage(self): tim = CoolEmployee('Tim', 9000) self.assertIsInstance(tim, CoolEmployee) @@ -4099,6 +6067,62 @@ class NamedTupleTests(BaseTestCase): with self.assertRaises(TypeError): class X(NamedTuple, A): x: int + with self.assertRaises(TypeError): + class X(NamedTuple, tuple): + x: int + with self.assertRaises(TypeError): + class X(NamedTuple, NamedTuple): + x: int + class A(NamedTuple): + x: int + with self.assertRaises(TypeError): + class X(NamedTuple, A): + y: str + + def test_generic(self): + class X(NamedTuple, Generic[T]): + x: T + self.assertEqual(X.__bases__, (tuple, Generic)) + self.assertEqual(X.__orig_bases__, (NamedTuple, Generic[T])) + self.assertEqual(X.__mro__, (X, tuple, Generic, object)) + + class Y(Generic[T], NamedTuple): + x: T + self.assertEqual(Y.__bases__, (Generic, tuple)) + self.assertEqual(Y.__orig_bases__, (Generic[T], NamedTuple)) + self.assertEqual(Y.__mro__, (Y, Generic, tuple, object)) + + for G in X, Y: + with self.subTest(type=G): + self.assertEqual(G.__parameters__, (T,)) + self.assertEqual(G[T].__args__, (T,)) + self.assertEqual(get_args(G[T]), (T,)) + A = G[int] + self.assertIs(A.__origin__, G) + self.assertEqual(A.__args__, (int,)) + self.assertEqual(get_args(A), (int,)) + self.assertEqual(A.__parameters__, ()) + + a = A(3) + self.assertIs(type(a), G) + self.assertEqual(a.x, 3) + + with self.assertRaises(TypeError): + G[int, str] + + def test_non_generic_subscript(self): + # For backward compatibility, subscription works + # on arbitrary NamedTuple types. + class Group(NamedTuple): + key: T + group: list[T] + A = Group[int] + self.assertEqual(A.__origin__, Group) + self.assertEqual(A.__parameters__, ()) + self.assertEqual(A.__args__, (int,)) + a = A(1, [2]) + self.assertIs(type(a), Group) + self.assertEqual(a, (1, [2])) def test_namedtuple_keyword_usage(self): LocalEmployee = NamedTuple("LocalEmployee", name=str, age=int) @@ -4110,8 +6134,6 @@ class NamedTupleTests(BaseTestCase): self.assertEqual(LocalEmployee.__annotations__, dict(name=str, age=int)) with self.assertRaises(TypeError): NamedTuple('Name', [('x', int)], y=str) - with self.assertRaises(TypeError): - NamedTuple('Name', x=1, y='a') def test_namedtuple_special_keyword_names(self): NT = NamedTuple("NT", cls=type, self=object, typename=str, fields=list) @@ -4147,8 +6169,6 @@ class NamedTupleTests(BaseTestCase): NamedTuple('Emp', [('_name', str)]) with self.assertRaises(TypeError): NamedTuple(typename='Emp', name=str, id=int) - with self.assertRaises(TypeError): - NamedTuple('Emp', fields=[('name', str), ('id', int)]) def test_copy_and_pickle(self): global Emp # pickle wants to reference the class by name @@ -4188,7 +6208,8 @@ class TypedDictTests(BaseTestCase): self.assertEqual(Emp.__total__, True) def test_basics_keywords_syntax(self): - Emp = TypedDict('Emp', name=str, id=int) + with self.assertWarns(DeprecationWarning): + Emp = TypedDict('Emp', name=str, id=int) self.assertIsSubclass(Emp, dict) self.assertIsSubclass(Emp, typing.MutableMapping) self.assertNotIsSubclass(Emp, collections.abc.Sequence) @@ -4203,7 +6224,8 @@ class TypedDictTests(BaseTestCase): self.assertEqual(Emp.__total__, True) def test_typeddict_special_keyword_names(self): - TD = TypedDict("TD", cls=type, self=object, typename=str, _typename=int, fields=list, _fields=dict) + with self.assertWarns(DeprecationWarning): + TD = TypedDict("TD", cls=type, self=object, typename=str, _typename=int, fields=list, _fields=dict) self.assertEqual(TD.__name__, 'TD') self.assertEqual(TD.__annotations__, {'cls': type, 'self': object, 'typename': str, '_typename': int, 'fields': list, '_fields': dict}) a = TD(cls=str, self=42, typename='foo', _typename=53, fields=[('bar', tuple)], _fields={'baz', set}) @@ -4221,11 +6243,8 @@ class TypedDictTests(BaseTestCase): TypedDict() with self.assertRaises(TypeError): TypedDict('Emp', [('name', str)], None) - with self.assertRaises(TypeError): TypedDict(_typename='Emp', name=str, id=int) - with self.assertRaises(TypeError): - TypedDict('Emp', _fields={'name': str, 'id': int}) def test_typeddict_errors(self): Emp = TypedDict('Emp', {'name': str, 'id': int}) @@ -4237,10 +6256,6 @@ class TypedDictTests(BaseTestCase): isinstance(jim, Emp) with self.assertRaises(TypeError): issubclass(dict, Emp) - with self.assertRaises(TypeError): - TypedDict('Hi', x=1) - with self.assertRaises(TypeError): - TypedDict('Hi', [('x', int), ('y', 1)]) with self.assertRaises(TypeError): TypedDict('Hi', [('x', int)], y=int) @@ -4259,7 +6274,7 @@ class TypedDictTests(BaseTestCase): def test_pickle(self): global EmpD # pickle wants to reference the class by name - EmpD = TypedDict('EmpD', name=str, id=int) + EmpD = TypedDict('EmpD', {'name': str, 'id': int}) jane = EmpD({'name': 'jane', 'id': 37}) for proto in range(pickle.HIGHEST_PROTOCOL + 1): z = pickle.dumps(jane, proto) @@ -4270,8 +6285,19 @@ class TypedDictTests(BaseTestCase): EmpDnew = pickle.loads(ZZ) self.assertEqual(EmpDnew({'name': 'jane', 'id': 37}), jane) + def test_pickle_generic(self): + point = Point2DGeneric(a=5.0, b=3.0) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + z = pickle.dumps(point, proto) + point2 = pickle.loads(z) + self.assertEqual(point2, point) + self.assertEqual(point2, {'a': 5.0, 'b': 3.0}) + ZZ = pickle.dumps(Point2DGeneric, proto) + Point2DGenericNew = pickle.loads(ZZ) + self.assertEqual(Point2DGenericNew({'a': 5.0, 'b': 3.0}), point) + def test_optional(self): - EmpD = TypedDict('EmpD', name=str, id=int) + EmpD = TypedDict('EmpD', {'name': str, 'id': int}) self.assertEqual(typing.Optional[EmpD], typing.Union[None, EmpD]) self.assertNotEqual(typing.List[EmpD], typing.Tuple[EmpD]) @@ -4329,6 +6355,119 @@ class TypedDictTests(BaseTestCase): 'voice': str, } + def test_required_notrequired_keys(self): + self.assertEqual(NontotalMovie.__required_keys__, + frozenset({"title"})) + self.assertEqual(NontotalMovie.__optional_keys__, + frozenset({"year"})) + + self.assertEqual(TotalMovie.__required_keys__, + frozenset({"title"})) + self.assertEqual(TotalMovie.__optional_keys__, + frozenset({"year"})) + + self.assertEqual(_typed_dict_helper.VeryAnnotated.__required_keys__, + frozenset()) + self.assertEqual(_typed_dict_helper.VeryAnnotated.__optional_keys__, + frozenset({"a"})) + + self.assertEqual(AnnotatedMovie.__required_keys__, + frozenset({"title"})) + self.assertEqual(AnnotatedMovie.__optional_keys__, + frozenset({"year"})) + + self.assertEqual(WeirdlyQuotedMovie.__required_keys__, + frozenset({"title"})) + self.assertEqual(WeirdlyQuotedMovie.__optional_keys__, + frozenset({"year"})) + + def test_multiple_inheritance(self): + class One(TypedDict): + one: int + class Two(TypedDict): + two: str + class Untotal(TypedDict, total=False): + untotal: str + Inline = TypedDict('Inline', {'inline': bool}) + class Regular: + pass + + class Child(One, Two): + child: bool + self.assertEqual( + Child.__required_keys__, + frozenset(['one', 'two', 'child']), + ) + self.assertEqual( + Child.__optional_keys__, + frozenset([]), + ) + self.assertEqual( + Child.__annotations__, + {'one': int, 'two': str, 'child': bool}, + ) + + class ChildWithOptional(One, Untotal): + child: bool + self.assertEqual( + ChildWithOptional.__required_keys__, + frozenset(['one', 'child']), + ) + self.assertEqual( + ChildWithOptional.__optional_keys__, + frozenset(['untotal']), + ) + self.assertEqual( + ChildWithOptional.__annotations__, + {'one': int, 'untotal': str, 'child': bool}, + ) + + class ChildWithTotalFalse(One, Untotal, total=False): + child: bool + self.assertEqual( + ChildWithTotalFalse.__required_keys__, + frozenset(['one']), + ) + self.assertEqual( + ChildWithTotalFalse.__optional_keys__, + frozenset(['untotal', 'child']), + ) + self.assertEqual( + ChildWithTotalFalse.__annotations__, + {'one': int, 'untotal': str, 'child': bool}, + ) + + class ChildWithInlineAndOptional(Untotal, Inline): + child: bool + self.assertEqual( + ChildWithInlineAndOptional.__required_keys__, + frozenset(['inline', 'child']), + ) + self.assertEqual( + ChildWithInlineAndOptional.__optional_keys__, + frozenset(['untotal']), + ) + self.assertEqual( + ChildWithInlineAndOptional.__annotations__, + {'inline': bool, 'untotal': str, 'child': bool}, + ) + + wrong_bases = [ + (One, Regular), + (Regular, One), + (One, Two, Regular), + (Inline, Regular), + (Untotal, Regular), + ] + for bases in wrong_bases: + with self.subTest(bases=bases): + with self.assertRaisesRegex( + TypeError, + 'cannot inherit from both a TypedDict type and a non-TypedDict', + ): + class Wrong(*bases): + pass + def test_is_typeddict(self): assert is_typeddict(Point2D) is True assert is_typeddict(Union[str, int]) is False @@ -4341,6 +6480,233 @@ class TypedDictTests(BaseTestCase): {'a': typing.Optional[int], 'b': int} ) + def test_get_type_hints_generic(self): + self.assertEqual( + get_type_hints(BarGeneric), + {'a': typing.Optional[T], 'b': int} + ) + + class FooBarGeneric(BarGeneric[int]): + c: str + + self.assertEqual( + get_type_hints(FooBarGeneric), + {'a': typing.Optional[T], 'b': int, 'c': str} + ) + + def test_generic_inheritance(self): + class A(TypedDict, Generic[T]): + a: T + + self.assertEqual(A.__bases__, (Generic, dict)) + self.assertEqual(A.__orig_bases__, (TypedDict, Generic[T])) + self.assertEqual(A.__mro__, (A, Generic, dict, object)) + self.assertEqual(A.__parameters__, (T,)) + self.assertEqual(A[str].__parameters__, ()) + self.assertEqual(A[str].__args__, (str,)) + + class A2(Generic[T], TypedDict): + a: T + + self.assertEqual(A2.__bases__, (Generic, dict)) + self.assertEqual(A2.__orig_bases__, (Generic[T], TypedDict)) + self.assertEqual(A2.__mro__, (A2, Generic, dict, object)) + self.assertEqual(A2.__parameters__, (T,)) + self.assertEqual(A2[str].__parameters__, ()) + self.assertEqual(A2[str].__args__, (str,)) + + class B(A[KT], total=False): + b: KT + + self.assertEqual(B.__bases__, (Generic, dict)) + self.assertEqual(B.__orig_bases__, (A[KT],)) + self.assertEqual(B.__mro__, (B, Generic, dict, object)) + self.assertEqual(B.__parameters__, (KT,)) + self.assertEqual(B.__total__, False) + self.assertEqual(B.__optional_keys__, frozenset(['b'])) + self.assertEqual(B.__required_keys__, frozenset(['a'])) + + self.assertEqual(B[str].__parameters__, ()) + self.assertEqual(B[str].__args__, (str,)) + self.assertEqual(B[str].__origin__, B) + + class C(B[int]): + c: int + + self.assertEqual(C.__bases__, (Generic, dict)) + self.assertEqual(C.__orig_bases__, (B[int],)) + self.assertEqual(C.__mro__, (C, Generic, dict, object)) + self.assertEqual(C.__parameters__, ()) + self.assertEqual(C.__total__, True) + self.assertEqual(C.__optional_keys__, frozenset(['b'])) + self.assertEqual(C.__required_keys__, frozenset(['a', 'c'])) + assert C.__annotations__ == { + 'a': T, + 'b': KT, + 'c': int, + } + with self.assertRaises(TypeError): + C[str] + + + class Point3D(Point2DGeneric[T], Generic[T, KT]): + c: KT + + self.assertEqual(Point3D.__bases__, (Generic, dict)) + self.assertEqual(Point3D.__orig_bases__, (Point2DGeneric[T], Generic[T, KT])) + self.assertEqual(Point3D.__mro__, (Point3D, Generic, dict, object)) + self.assertEqual(Point3D.__parameters__, (T, KT)) + self.assertEqual(Point3D.__total__, True) + self.assertEqual(Point3D.__optional_keys__, frozenset()) + self.assertEqual(Point3D.__required_keys__, frozenset(['a', 'b', 'c'])) + assert Point3D.__annotations__ == { + 'a': T, + 'b': T, + 'c': KT, + } + self.assertEqual(Point3D[int, str].__origin__, Point3D) + + with self.assertRaises(TypeError): + Point3D[int] + + with self.assertRaises(TypeError): + class Point3D(Point2DGeneric[T], Generic[KT]): + c: KT + + def test_implicit_any_inheritance(self): + class A(TypedDict, Generic[T]): + a: T + + class B(A[KT], total=False): + b: KT + + class WithImplicitAny(B): + c: int + + self.assertEqual(WithImplicitAny.__bases__, (Generic, dict,)) + self.assertEqual(WithImplicitAny.__mro__, (WithImplicitAny, Generic, dict, object)) + # Consistent with GenericTests.test_implicit_any + self.assertEqual(WithImplicitAny.__parameters__, ()) + self.assertEqual(WithImplicitAny.__total__, True) + self.assertEqual(WithImplicitAny.__optional_keys__, frozenset(['b'])) + self.assertEqual(WithImplicitAny.__required_keys__, frozenset(['a', 'c'])) + assert WithImplicitAny.__annotations__ == { + 'a': T, + 'b': KT, + 'c': int, + } + with self.assertRaises(TypeError): + WithImplicitAny[str] + + def test_non_generic_subscript(self): + # For backward compatibility, subscription works + # on arbitrary TypedDict types. + class TD(TypedDict): + a: T + A = TD[int] + self.assertEqual(A.__origin__, TD) + self.assertEqual(A.__parameters__, ()) + self.assertEqual(A.__args__, (int,)) + a = A(a = 1) + self.assertIs(type(a), dict) + self.assertEqual(a, {'a': 1}) + + +class RequiredTests(BaseTestCase): + + def test_basics(self): + with self.assertRaises(TypeError): + Required[NotRequired] + with self.assertRaises(TypeError): + Required[int, str] + with self.assertRaises(TypeError): + Required[int][str] + + def test_repr(self): + self.assertEqual(repr(Required), 'typing.Required') + cv = Required[int] + self.assertEqual(repr(cv), 'typing.Required[int]') + cv = Required[Employee] + self.assertEqual(repr(cv), f'typing.Required[{__name__}.Employee]') + + def test_cannot_subclass(self): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class C(type(Required)): + pass + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class C(type(Required[int])): + pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.Required'): + class C(Required): + pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.Required\[int\]'): + class C(Required[int]): + pass + + def test_cannot_init(self): + with self.assertRaises(TypeError): + Required() + with self.assertRaises(TypeError): + type(Required)() + with self.assertRaises(TypeError): + type(Required[Optional[int]])() + + def test_no_isinstance(self): + with self.assertRaises(TypeError): + isinstance(1, Required[int]) + with self.assertRaises(TypeError): + issubclass(int, Required) + + +class NotRequiredTests(BaseTestCase): + + def test_basics(self): + with self.assertRaises(TypeError): + NotRequired[Required] + with self.assertRaises(TypeError): + NotRequired[int, str] + with self.assertRaises(TypeError): + NotRequired[int][str] + + def test_repr(self): + self.assertEqual(repr(NotRequired), 'typing.NotRequired') + cv = NotRequired[int] + self.assertEqual(repr(cv), 'typing.NotRequired[int]') + cv = NotRequired[Employee] + self.assertEqual(repr(cv), f'typing.NotRequired[{__name__}.Employee]') + + def test_cannot_subclass(self): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class C(type(NotRequired)): + pass + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class C(type(NotRequired[int])): + pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.NotRequired'): + class C(NotRequired): + pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.NotRequired\[int\]'): + class C(NotRequired[int]): + pass + + def test_cannot_init(self): + with self.assertRaises(TypeError): + NotRequired() + with self.assertRaises(TypeError): + type(NotRequired)() + with self.assertRaises(TypeError): + type(NotRequired[Optional[int]])() + + def test_no_isinstance(self): + with self.assertRaises(TypeError): + isinstance(1, NotRequired[int]) + with self.assertRaises(TypeError): + issubclass(int, NotRequired) + class IOTests(BaseTestCase): @@ -4434,17 +6800,29 @@ class RETests(BaseTestCase): self.assertEqual(len(w), 1) def test_cannot_subclass(self): - with self.assertRaises(TypeError) as ex: - + with self.assertRaisesRegex( + TypeError, + r"type 're\.Match' is not an acceptable base type", + ): class A(typing.Match): pass - - self.assertEqual(str(ex.exception), - "type 're.Match' is not an acceptable base type") + with self.assertRaisesRegex( + TypeError, + r"type 're\.Pattern' is not an acceptable base type", + ): + class A(typing.Pattern): + pass class AnnotatedTests(BaseTestCase): + def test_new(self): + with self.assertRaisesRegex( + TypeError, + 'Type Annotated cannot be instantiated', + ): + Annotated() + def test_repr(self): self.assertEqual( repr(Annotated[int, 4, 5]), @@ -4529,6 +6907,14 @@ class AnnotatedTests(BaseTestCase): A.x = 5 self.assertEqual(C.x, 5) + def test_special_form_containment(self): + class C: + classvar: Annotated[ClassVar[int], "a decoration"] = 4 + const: Annotated[Final[int], "Const"] = 4 + + self.assertEqual(get_type_hints(C, globals())['classvar'], ClassVar[int]) + self.assertEqual(get_type_hints(C, globals())['const'], Final[int]) + def test_hash_eq(self): self.assertEqual(len({Annotated[int, 4, 5], Annotated[int, 4, 5]}), 1) self.assertNotEqual(Annotated[int, 4, 5], Annotated[int, 5, 4]) @@ -4552,6 +6938,10 @@ class AnnotatedTests(BaseTestCase): with self.assertRaises(TypeError): issubclass(int, Annotated[int, "positive"]) + def test_too_few_type_args(self): + with self.assertRaisesRegex(TypeError, 'at least two arguments'): + Annotated[int] + def test_pickle(self): samples = [typing.Any, typing.Union[int, str], typing.Optional[str], Tuple[int, ...], @@ -4611,6 +7001,120 @@ class AnnotatedTests(BaseTestCase): with self.assertRaises(TypeError): LI[None] + def test_typevar_subst(self): + dec = "a decoration" + Ts = TypeVarTuple('Ts') + T = TypeVar('T') + T1 = TypeVar('T1') + T2 = TypeVar('T2') + + A = Annotated[tuple[*Ts], dec] + self.assertEqual(A[int], Annotated[tuple[int], dec]) + self.assertEqual(A[str, int], Annotated[tuple[str, int], dec]) + with self.assertRaises(TypeError): + Annotated[*Ts, dec] + + B = Annotated[Tuple[Unpack[Ts]], dec] + self.assertEqual(B[int], Annotated[Tuple[int], dec]) + self.assertEqual(B[str, int], Annotated[Tuple[str, int], dec]) + with self.assertRaises(TypeError): + Annotated[Unpack[Ts], dec] + + C = Annotated[tuple[T, *Ts], dec] + self.assertEqual(C[int], Annotated[tuple[int], dec]) + self.assertEqual(C[int, str], Annotated[tuple[int, str], dec]) + self.assertEqual( + C[int, str, float], + Annotated[tuple[int, str, float], dec] + ) + with self.assertRaises(TypeError): + C[()] + + D = Annotated[Tuple[T, Unpack[Ts]], dec] + self.assertEqual(D[int], Annotated[Tuple[int], dec]) + self.assertEqual(D[int, str], Annotated[Tuple[int, str], dec]) + self.assertEqual( + D[int, str, float], + Annotated[Tuple[int, str, float], dec] + ) + with self.assertRaises(TypeError): + D[()] + + E = Annotated[tuple[*Ts, T], dec] + self.assertEqual(E[int], Annotated[tuple[int], dec]) + self.assertEqual(E[int, str], Annotated[tuple[int, str], dec]) + self.assertEqual( + E[int, str, float], + Annotated[tuple[int, str, float], dec] + ) + with self.assertRaises(TypeError): + E[()] + + F = Annotated[Tuple[Unpack[Ts], T], dec] + self.assertEqual(F[int], Annotated[Tuple[int], dec]) + self.assertEqual(F[int, str], Annotated[Tuple[int, str], dec]) + self.assertEqual( + F[int, str, float], + Annotated[Tuple[int, str, float], dec] + ) + with self.assertRaises(TypeError): + F[()] + + G = Annotated[tuple[T1, *Ts, T2], dec] + self.assertEqual(G[int, str], Annotated[tuple[int, str], dec]) + self.assertEqual( + G[int, str, float], + Annotated[tuple[int, str, float], dec] + ) + self.assertEqual( + G[int, str, bool, float], + Annotated[tuple[int, str, bool, float], dec] + ) + with self.assertRaises(TypeError): + G[int] + + H = Annotated[Tuple[T1, Unpack[Ts], T2], dec] + self.assertEqual(H[int, str], Annotated[Tuple[int, str], dec]) + self.assertEqual( + H[int, str, float], + Annotated[Tuple[int, str, float], dec] + ) + self.assertEqual( + H[int, str, bool, float], + Annotated[Tuple[int, str, bool, float], dec] + ) + with self.assertRaises(TypeError): + H[int] + + # Now let's try creating an alias from an alias. + + Ts2 = TypeVarTuple('Ts2') + T3 = TypeVar('T3') + T4 = TypeVar('T4') + + # G is Annotated[tuple[T1, *Ts, T2], dec]. + I = G[T3, *Ts2, T4] + J = G[T3, Unpack[Ts2], T4] + + for x, y in [ + (I, Annotated[tuple[T3, *Ts2, T4], dec]), + (J, Annotated[tuple[T3, Unpack[Ts2], T4], dec]), + (I[int, str], Annotated[tuple[int, str], dec]), + (J[int, str], Annotated[tuple[int, str], dec]), + (I[int, str, float], Annotated[tuple[int, str, float], dec]), + (J[int, str, float], Annotated[tuple[int, str, float], dec]), + (I[int, str, bool, float], + Annotated[tuple[int, str, bool, float], dec]), + (J[int, str, bool, float], + Annotated[tuple[int, str, bool, float], dec]), + ]: + self.assertEqual(x, y) + + with self.assertRaises(TypeError): + I[int] + with self.assertRaises(TypeError): + J[int] + def test_annotated_in_other_types(self): X = List[Annotated[T, 5]] self.assertEqual(X[int], List[Annotated[int, 5]]) @@ -4636,6 +7140,11 @@ class TypeAliasTests(BaseTestCase): with self.assertRaises(TypeError): isinstance(42, TypeAlias) + def test_stringized_usage(self): + class A: + a: "TypeAlias" + self.assertEqual(get_type_hints(A), {'a': TypeAlias}) + def test_no_issubclass(self): with self.assertRaises(TypeError): issubclass(Employee, TypeAlias) @@ -4644,7 +7153,8 @@ class TypeAliasTests(BaseTestCase): issubclass(TypeAlias, Employee) def test_cannot_subclass(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.TypeAlias'): class C(TypeAlias): pass @@ -4686,15 +7196,35 @@ class ParamSpecTests(BaseTestCase): def test_args_kwargs(self): P = ParamSpec('P') + P_2 = ParamSpec('P_2') self.assertIn('args', dir(P)) self.assertIn('kwargs', dir(P)) self.assertIsInstance(P.args, ParamSpecArgs) self.assertIsInstance(P.kwargs, ParamSpecKwargs) self.assertIs(P.args.__origin__, P) self.assertIs(P.kwargs.__origin__, P) + self.assertEqual(P.args, P.args) + self.assertEqual(P.kwargs, P.kwargs) + self.assertNotEqual(P.args, P_2.args) + self.assertNotEqual(P.kwargs, P_2.kwargs) + self.assertNotEqual(P.args, P.kwargs) + self.assertNotEqual(P.kwargs, P.args) + self.assertNotEqual(P.args, P_2.kwargs) self.assertEqual(repr(P.args), "P.args") self.assertEqual(repr(P.kwargs), "P.kwargs") + def test_stringized(self): + P = ParamSpec('P') + class C(Generic[P]): + func: Callable["P", int] + def foo(self, *args: "P.args", **kwargs: "P.kwargs"): + pass + + self.assertEqual(gth(C, globals(), locals()), {"func": Callable[P, int]}) + self.assertEqual( + gth(C.foo, globals(), locals()), {"args": P.args, "kwargs": P.kwargs} + ) + def test_user_generics(self): T = TypeVar("T") P = ParamSpec("P") @@ -4763,21 +7293,88 @@ class ParamSpecTests(BaseTestCase): self.assertEqual(G1.__args__, ((int, str), (bytes,))) self.assertEqual(G2.__args__, ((int,), (str, bytes))) - def test_no_paramspec_in__parameters__(self): - # ParamSpec should not be found in __parameters__ - # of generics. Usages outside Callable, Concatenate - # and Generic are invalid. + def test_typevartuple_and_paramspecs_in_user_generics(self): + Ts = TypeVarTuple("Ts") + P = ParamSpec("P") + + class X(Generic[*Ts, P]): + f: Callable[P, int] + g: Tuple[*Ts] + + G1 = X[int, [bytes]] + self.assertEqual(G1.__args__, (int, (bytes,))) + G2 = X[int, str, [bytes]] + self.assertEqual(G2.__args__, (int, str, (bytes,))) + G3 = X[[bytes]] + self.assertEqual(G3.__args__, ((bytes,),)) + G4 = X[[]] + self.assertEqual(G4.__args__, ((),)) + with self.assertRaises(TypeError): + X[()] + + class Y(Generic[P, *Ts]): + f: Callable[P, int] + g: Tuple[*Ts] + + G1 = Y[[bytes], int] + self.assertEqual(G1.__args__, ((bytes,), int)) + G2 = Y[[bytes], int, str] + self.assertEqual(G2.__args__, ((bytes,), int, str)) + G3 = Y[[bytes]] + self.assertEqual(G3.__args__, ((bytes,),)) + G4 = Y[[]] + self.assertEqual(G4.__args__, ((),)) + with self.assertRaises(TypeError): + Y[()] + + def test_typevartuple_and_paramspecs_in_generic_aliases(self): + P = ParamSpec('P') + T = TypeVar('T') + Ts = TypeVarTuple('Ts') + + for C in Callable, collections.abc.Callable: + with self.subTest(generic=C): + A = C[P, Tuple[*Ts]] + B = A[[int, str], bytes, float] + self.assertEqual(B.__args__, (int, str, Tuple[bytes, float])) + + class X(Generic[T, P]): + pass + + A = X[Tuple[*Ts], P] + B = A[bytes, float, [int, str]] + self.assertEqual(B.__args__, (Tuple[bytes, float], (int, str,))) + + class Y(Generic[P, T]): + pass + + A = Y[P, Tuple[*Ts]] + B = A[[int, str], bytes, float] + self.assertEqual(B.__args__, ((int, str,), Tuple[bytes, float])) + + def test_var_substitution(self): T = TypeVar("T") P = ParamSpec("P") - self.assertNotIn(P, List[P].__parameters__) - self.assertIn(T, Tuple[T, P].__parameters__) + subst = P.__typing_subst__ + self.assertEqual(subst((int, str)), (int, str)) + self.assertEqual(subst([int, str]), (int, str)) + self.assertEqual(subst([None]), (type(None),)) + self.assertIs(subst(...), ...) + self.assertIs(subst(P), P) + self.assertEqual(subst(Concatenate[int, P]), Concatenate[int, P]) - # Test for consistency with builtin generics. - self.assertNotIn(P, list[P].__parameters__) - self.assertIn(T, tuple[T, P].__parameters__) - - self.assertNotIn(P, (list[P] | int).__parameters__) - self.assertIn(T, (tuple[T, P] | int).__parameters__) + def test_bad_var_substitution(self): + T = TypeVar('T') + P = ParamSpec('P') + bad_args = (42, int, None, T, int|str, Union[int, str]) + for arg in bad_args: + with self.subTest(arg=arg): + with self.assertRaises(TypeError): + P.__typing_subst__(arg) + with self.assertRaises(TypeError): + typing.Callable[P, T][arg, str] + with self.assertRaises(TypeError): + collections.abc.Callable[P, T][arg, str] def test_paramspec_in_nested_generics(self): # Although ParamSpec should not be found in __parameters__ of most @@ -4792,6 +7389,49 @@ class ParamSpecTests(BaseTestCase): self.assertEqual(G1.__parameters__, (P, T)) self.assertEqual(G2.__parameters__, (P, T)) self.assertEqual(G3.__parameters__, (P, T)) + C = Callable[[int, str], float] + self.assertEqual(G1[[int, str], float], List[C]) + self.assertEqual(G2[[int, str], float], list[C]) + self.assertEqual(G3[[int, str], float], list[C] | int) + + def test_paramspec_gets_copied(self): + # bpo-46581 + P = ParamSpec('P') + P2 = ParamSpec('P2') + C1 = Callable[P, int] + self.assertEqual(C1.__parameters__, (P,)) + self.assertEqual(C1[P2].__parameters__, (P2,)) + self.assertEqual(C1[str].__parameters__, ()) + self.assertEqual(C1[str, T].__parameters__, (T,)) + self.assertEqual(C1[Concatenate[str, P2]].__parameters__, (P2,)) + self.assertEqual(C1[Concatenate[T, P2]].__parameters__, (T, P2)) + self.assertEqual(C1[...].__parameters__, ()) + + C2 = Callable[Concatenate[str, P], int] + self.assertEqual(C2.__parameters__, (P,)) + self.assertEqual(C2[P2].__parameters__, (P2,)) + self.assertEqual(C2[str].__parameters__, ()) + self.assertEqual(C2[str, T].__parameters__, (T,)) + self.assertEqual(C2[Concatenate[str, P2]].__parameters__, (P2,)) + self.assertEqual(C2[Concatenate[T, P2]].__parameters__, (T, P2)) + + def test_cannot_subclass(self): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class C(ParamSpec): pass + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class C(ParamSpecArgs): pass + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): + class C(ParamSpecKwargs): pass + P = ParamSpec('P') + with self.assertRaisesRegex(TypeError, + CANNOT_SUBCLASS_INSTANCE % 'ParamSpec'): + class C(P): pass + with self.assertRaisesRegex(TypeError, + CANNOT_SUBCLASS_INSTANCE % 'ParamSpecArgs'): + class C(P.args): pass + with self.assertRaisesRegex(TypeError, + CANNOT_SUBCLASS_INSTANCE % 'ParamSpecKwargs'): + class C(P.kwargs): pass class ConcatenateTests(BaseTestCase): @@ -4819,6 +7459,25 @@ class ConcatenateTests(BaseTestCase): self.assertEqual(C4.__args__, (Concatenate[int, T, P], T)) self.assertEqual(C4.__parameters__, (T, P)) + def test_var_substitution(self): + T = TypeVar('T') + P = ParamSpec('P') + P2 = ParamSpec('P2') + C = Concatenate[T, P] + self.assertEqual(C[int, P2], Concatenate[int, P2]) + self.assertEqual(C[int, [str, float]], (int, str, float)) + self.assertEqual(C[int, []], (int,)) + self.assertEqual(C[int, Concatenate[str, P2]], + Concatenate[int, str, P2]) + self.assertEqual(C[int, ...], Concatenate[int, ...]) + + C = Concatenate[int, P] + self.assertEqual(C[P2], Concatenate[int, P2]) + self.assertEqual(C[[str, float]], (int, str, float)) + self.assertEqual(C[str, float], (int, str, float)) + self.assertEqual(C[[]], (int,)) + self.assertEqual(C[Concatenate[str, P2]], Concatenate[int, str, P2]) + self.assertEqual(C[...], Concatenate[int, ...]) class TypeGuardTests(BaseTestCase): def test_basics(self): @@ -4827,6 +7486,9 @@ class TypeGuardTests(BaseTestCase): def foo(arg) -> TypeGuard[int]: ... self.assertEqual(gth(foo), {'return': TypeGuard[int]}) + with self.assertRaises(TypeError): + TypeGuard[int, str] + def test_repr(self): self.assertEqual(repr(TypeGuard), 'typing.TypeGuard') cv = TypeGuard[int] @@ -4837,12 +7499,20 @@ class TypeGuardTests(BaseTestCase): self.assertEqual(repr(cv), 'typing.TypeGuard[tuple[int]]') def test_cannot_subclass(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(TypeGuard)): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(TypeGuard[int])): pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.TypeGuard'): + class C(TypeGuard): + pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.TypeGuard\[int\]'): + class C(TypeGuard[int]): + pass def test_cannot_init(self): with self.assertRaises(TypeError): @@ -4954,13 +7624,16 @@ class SpecialAttrsTests(BaseTestCase): typing.Literal: 'Literal', typing.NewType: 'NewType', typing.NoReturn: 'NoReturn', + typing.Never: 'Never', typing.Optional: 'Optional', typing.TypeAlias: 'TypeAlias', typing.TypeGuard: 'TypeGuard', typing.TypeVar: 'TypeVar', typing.Union: 'Union', + typing.Self: 'Self', # Subscribed special forms typing.Annotated[Any, "Annotation"]: 'Annotated', + typing.Annotated[int, 'Annotation']: 'Annotated', typing.ClassVar[Any]: 'ClassVar', typing.Concatenate[Any, SpecialAttrsP]: 'Concatenate', typing.Final[Any]: 'Final', @@ -5010,7 +7683,7 @@ class SpecialAttrsTests(BaseTestCase): ) self.assertEqual( SpecialAttrsTests.TypeName.__module__, - 'test.test_typing', + __name__, ) # NewTypes are picklable assuming correct qualname information. for proto in range(pickle.HIGHEST_PROTOCOL + 1): @@ -5024,7 +7697,7 @@ class SpecialAttrsTests(BaseTestCase): # __qualname__ is unnecessary. self.assertEqual(SpecialAttrsT.__name__, 'SpecialAttrsT') self.assertFalse(hasattr(SpecialAttrsT, '__qualname__')) - self.assertEqual(SpecialAttrsT.__module__, 'test.test_typing') + self.assertEqual(SpecialAttrsT.__module__, __name__) # Module-level type variables are picklable. for proto in range(pickle.HIGHEST_PROTOCOL + 1): s = pickle.dumps(SpecialAttrsT, proto) @@ -5033,13 +7706,120 @@ class SpecialAttrsTests(BaseTestCase): self.assertEqual(SpecialAttrsP.__name__, 'SpecialAttrsP') self.assertFalse(hasattr(SpecialAttrsP, '__qualname__')) - self.assertEqual(SpecialAttrsP.__module__, 'test.test_typing') + self.assertEqual(SpecialAttrsP.__module__, __name__) # Module-level ParamSpecs are picklable. for proto in range(pickle.HIGHEST_PROTOCOL + 1): s = pickle.dumps(SpecialAttrsP, proto) loaded = pickle.loads(s) self.assertIs(SpecialAttrsP, loaded) + def test_genericalias_dir(self): + class Foo(Generic[T]): + def bar(self): + pass + baz = 3 + # The class attributes of the original class should be visible even + # in dir() of the GenericAlias. See bpo-45755. + self.assertIn('bar', dir(Foo[int])) + self.assertIn('baz', dir(Foo[int])) + + +class RevealTypeTests(BaseTestCase): + def test_reveal_type(self): + obj = object() + with captured_stderr() as stderr: + self.assertIs(obj, reveal_type(obj)) + self.assertEqual(stderr.getvalue(), "Runtime type is 'object'\n") + + +class DataclassTransformTests(BaseTestCase): + def test_decorator(self): + def create_model(*, frozen: bool = False, kw_only: bool = True): + return lambda cls: cls + + decorated = dataclass_transform(kw_only_default=True, order_default=False)(create_model) + + class CustomerModel: + id: int + + self.assertIs(decorated, create_model) + self.assertEqual( + decorated.__dataclass_transform__, + { + "eq_default": True, + "order_default": False, + "kw_only_default": True, + "frozen_default": False, + "field_specifiers": (), + "kwargs": {}, + } + ) + self.assertIs( + decorated(frozen=True, kw_only=False)(CustomerModel), + CustomerModel + ) + + def test_base_class(self): + class ModelBase: + def __init_subclass__(cls, *, frozen: bool = False): ... + + Decorated = dataclass_transform( + eq_default=True, + order_default=True, + # Arbitrary unrecognized kwargs are accepted at runtime. + make_everything_awesome=True, + )(ModelBase) + + class CustomerModel(Decorated, frozen=True): + id: int + + self.assertIs(Decorated, ModelBase) + self.assertEqual( + Decorated.__dataclass_transform__, + { + "eq_default": True, + "order_default": True, + "kw_only_default": False, + "frozen_default": False, + "field_specifiers": (), + "kwargs": {"make_everything_awesome": True}, + } + ) + self.assertIsSubclass(CustomerModel, Decorated) + + def test_metaclass(self): + class Field: ... + + class ModelMeta(type): + def __new__( + cls, name, bases, namespace, *, init: bool = True, + ): + return super().__new__(cls, name, bases, namespace) + + Decorated = dataclass_transform( + order_default=True, frozen_default=True, field_specifiers=(Field,) + )(ModelMeta) + + class ModelBase(metaclass=Decorated): ... + + class CustomerModel(ModelBase, init=False): + id: int + + self.assertIs(Decorated, ModelMeta) + self.assertEqual( + Decorated.__dataclass_transform__, + { + "eq_default": True, + "order_default": True, + "kw_only_default": False, + "frozen_default": True, + "field_specifiers": (Field,), + "kwargs": {}, + } + ) + self.assertIsInstance(CustomerModel, Decorated) + + class AllTests(BaseTestCase): """Tests for __all__.""" @@ -5050,8 +7830,9 @@ class AllTests(BaseTestCase): self.assertIn('ValuesView', a) self.assertIn('cast', a) self.assertIn('overload', a) - if hasattr(contextlib, 'AbstractContextManager'): - self.assertIn('ContextManager', a) + # Context managers. + self.assertIn('ContextManager', a) + self.assertIn('AsyncContextManager', a) # Check that io and re are not exported. self.assertNotIn('io', a) self.assertNotIn('re', a) @@ -5065,8 +7846,6 @@ class AllTests(BaseTestCase): self.assertIn('SupportsComplex', a) def test_all_exported_names(self): - import typing - actual_all = set(typing.__all__) computed_all = { k for k, v in vars(typing).items() @@ -5085,6 +7864,37 @@ class AllTests(BaseTestCase): self.assertSetEqual(computed_all, actual_all) +class TypeIterationTests(BaseTestCase): + _UNITERABLE_TYPES = ( + Any, + Union, + Union[str, int], + Union[str, T], + List, + Tuple, + Callable, + Callable[..., T], + Callable[[T], str], + Annotated, + Annotated[T, ''], + ) + + def test_cannot_iterate(self): + expected_error_regex = "object is not iterable" + for test_type in self._UNITERABLE_TYPES: + with self.subTest(type=test_type): + with self.assertRaisesRegex(TypeError, expected_error_regex): + iter(test_type) + with self.assertRaisesRegex(TypeError, expected_error_regex): + list(test_type) + with self.assertRaisesRegex(TypeError, expected_error_regex): + for _ in test_type: + pass + + def test_is_not_instance_of_iterable(self): + for type_to_test in self._UNITERABLE_TYPES: + self.assertNotIsInstance(type_to_test, collections.abc.Iterable) + if __name__ == '__main__': main() diff --git a/Lib/test/test_unary.py b/Lib/test/test_unary.py index c3c17cc9f61..a45fbf6bd6b 100644 --- a/Lib/test/test_unary.py +++ b/Lib/test/test_unary.py @@ -8,7 +8,6 @@ class UnaryOpTestCase(unittest.TestCase): self.assertTrue(-2 == 0 - 2) self.assertEqual(-0, 0) self.assertEqual(--2, 2) - self.assertTrue(-2 == 0 - 2) self.assertTrue(-2.0 == 0 - 2.0) self.assertTrue(-2j == 0 - 2j) @@ -16,15 +15,13 @@ class UnaryOpTestCase(unittest.TestCase): self.assertEqual(+2, 2) self.assertEqual(+0, 0) self.assertEqual(++2, 2) - self.assertEqual(+2, 2) self.assertEqual(+2.0, 2.0) self.assertEqual(+2j, 2j) def test_invert(self): - self.assertTrue(-2 == 0 - 2) - self.assertEqual(-0, 0) - self.assertEqual(--2, 2) - self.assertTrue(-2 == 0 - 2) + self.assertTrue(~2 == -(2+1)) + self.assertEqual(~0, -1) + self.assertEqual(~~2, 2) def test_no_overflow(self): nines = "9" * 32 diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index d5e2c5266aa..4ebbb9d32a3 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -9,13 +9,13 @@ import _string import codecs import itertools import operator +import pickle import struct import sys import textwrap import unicodedata import unittest import warnings -from test.support import import_helper from test.support import warnings_helper from test import support, string_tests from test.support.script_helper import assert_python_failure @@ -94,88 +94,85 @@ class UnicodeTest(string_tests.CommonTest, self.assertNotEqual(r"\u0020", " ") def test_ascii(self): - if not sys.platform.startswith('java'): - # Test basic sanity of repr() - self.assertEqual(ascii('abc'), "'abc'") - self.assertEqual(ascii('ab\\c'), "'ab\\\\c'") - self.assertEqual(ascii('ab\\'), "'ab\\\\'") - self.assertEqual(ascii('\\c'), "'\\\\c'") - self.assertEqual(ascii('\\'), "'\\\\'") - self.assertEqual(ascii('\n'), "'\\n'") - self.assertEqual(ascii('\r'), "'\\r'") - self.assertEqual(ascii('\t'), "'\\t'") - self.assertEqual(ascii('\b'), "'\\x08'") - self.assertEqual(ascii("'\""), """'\\'"'""") - self.assertEqual(ascii("'\""), """'\\'"'""") - self.assertEqual(ascii("'"), '''"'"''') - self.assertEqual(ascii('"'), """'"'""") - latin1repr = ( - "'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r" - "\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a" - "\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHI" - "JKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f" - "\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d" - "\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b" - "\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9" - "\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7" - "\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5" - "\\xc6\\xc7\\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\\xd0\\xd1\\xd2\\xd3" - "\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\\xe0\\xe1" - "\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef" - "\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd" - "\\xfe\\xff'") - testrepr = ascii(''.join(map(chr, range(256)))) - self.assertEqual(testrepr, latin1repr) - # Test ascii works on wide unicode escapes without overflow. - self.assertEqual(ascii("\U00010000" * 39 + "\uffff" * 4096), - ascii("\U00010000" * 39 + "\uffff" * 4096)) + self.assertEqual(ascii('abc'), "'abc'") + self.assertEqual(ascii('ab\\c'), "'ab\\\\c'") + self.assertEqual(ascii('ab\\'), "'ab\\\\'") + self.assertEqual(ascii('\\c'), "'\\\\c'") + self.assertEqual(ascii('\\'), "'\\\\'") + self.assertEqual(ascii('\n'), "'\\n'") + self.assertEqual(ascii('\r'), "'\\r'") + self.assertEqual(ascii('\t'), "'\\t'") + self.assertEqual(ascii('\b'), "'\\x08'") + self.assertEqual(ascii("'\""), """'\\'"'""") + self.assertEqual(ascii("'\""), """'\\'"'""") + self.assertEqual(ascii("'"), '''"'"''') + self.assertEqual(ascii('"'), """'"'""") + latin1repr = ( + "'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r" + "\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a" + "\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHI" + "JKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f" + "\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d" + "\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b" + "\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9" + "\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7" + "\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5" + "\\xc6\\xc7\\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\\xd0\\xd1\\xd2\\xd3" + "\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\\xe0\\xe1" + "\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef" + "\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd" + "\\xfe\\xff'") + testrepr = ascii(''.join(map(chr, range(256)))) + self.assertEqual(testrepr, latin1repr) + # Test ascii works on wide unicode escapes without overflow. + self.assertEqual(ascii("\U00010000" * 39 + "\uffff" * 4096), + ascii("\U00010000" * 39 + "\uffff" * 4096)) - class WrongRepr: - def __repr__(self): - return b'byte-repr' - self.assertRaises(TypeError, ascii, WrongRepr()) + class WrongRepr: + def __repr__(self): + return b'byte-repr' + self.assertRaises(TypeError, ascii, WrongRepr()) def test_repr(self): - if not sys.platform.startswith('java'): - # Test basic sanity of repr() - self.assertEqual(repr('abc'), "'abc'") - self.assertEqual(repr('ab\\c'), "'ab\\\\c'") - self.assertEqual(repr('ab\\'), "'ab\\\\'") - self.assertEqual(repr('\\c'), "'\\\\c'") - self.assertEqual(repr('\\'), "'\\\\'") - self.assertEqual(repr('\n'), "'\\n'") - self.assertEqual(repr('\r'), "'\\r'") - self.assertEqual(repr('\t'), "'\\t'") - self.assertEqual(repr('\b'), "'\\x08'") - self.assertEqual(repr("'\""), """'\\'"'""") - self.assertEqual(repr("'\""), """'\\'"'""") - self.assertEqual(repr("'"), '''"'"''') - self.assertEqual(repr('"'), """'"'""") - latin1repr = ( - "'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r" - "\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a" - "\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHI" - "JKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f" - "\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d" - "\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b" - "\\x9c\\x9d\\x9e\\x9f\\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9" - "\xaa\xab\xac\\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7" - "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5" - "\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3" - "\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1" - "\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" - "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd" - "\xfe\xff'") - testrepr = repr(''.join(map(chr, range(256)))) - self.assertEqual(testrepr, latin1repr) - # Test repr works on wide unicode escapes without overflow. - self.assertEqual(repr("\U00010000" * 39 + "\uffff" * 4096), - repr("\U00010000" * 39 + "\uffff" * 4096)) + # Test basic sanity of repr() + self.assertEqual(repr('abc'), "'abc'") + self.assertEqual(repr('ab\\c'), "'ab\\\\c'") + self.assertEqual(repr('ab\\'), "'ab\\\\'") + self.assertEqual(repr('\\c'), "'\\\\c'") + self.assertEqual(repr('\\'), "'\\\\'") + self.assertEqual(repr('\n'), "'\\n'") + self.assertEqual(repr('\r'), "'\\r'") + self.assertEqual(repr('\t'), "'\\t'") + self.assertEqual(repr('\b'), "'\\x08'") + self.assertEqual(repr("'\""), """'\\'"'""") + self.assertEqual(repr("'\""), """'\\'"'""") + self.assertEqual(repr("'"), '''"'"''') + self.assertEqual(repr('"'), """'"'""") + latin1repr = ( + "'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r" + "\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a" + "\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHI" + "JKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f" + "\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d" + "\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b" + "\\x9c\\x9d\\x9e\\x9f\\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9" + "\xaa\xab\xac\\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7" + "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5" + "\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3" + "\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1" + "\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd" + "\xfe\xff'") + testrepr = repr(''.join(map(chr, range(256)))) + self.assertEqual(testrepr, latin1repr) + # Test repr works on wide unicode escapes without overflow. + self.assertEqual(repr("\U00010000" * 39 + "\uffff" * 4096), + repr("\U00010000" * 39 + "\uffff" * 4096)) - class WrongRepr: - def __repr__(self): - return b'byte-repr' - self.assertRaises(TypeError, repr, WrongRepr()) + class WrongRepr: + def __repr__(self): + return b'byte-repr' + self.assertRaises(TypeError, repr, WrongRepr()) def test_iterators(self): # Make sure unicode objects have an __iter__ method @@ -185,6 +182,36 @@ class UnicodeTest(string_tests.CommonTest, self.assertEqual(next(it), "\u3333") self.assertRaises(StopIteration, next, it) + def test_iterators_invocation(self): + cases = [type(iter('abc')), type(iter('🚀'))] + for cls in cases: + with self.subTest(cls=cls): + self.assertRaises(TypeError, cls) + + def test_iteration(self): + cases = ['abc', '🚀🚀🚀', "\u1111\u2222\u3333"] + for case in cases: + with self.subTest(string=case): + self.assertEqual(case, "".join(iter(case))) + + def test_exhausted_iterator(self): + cases = ['abc', '🚀🚀🚀', "\u1111\u2222\u3333"] + for case in cases: + with self.subTest(case=case): + iterator = iter(case) + tuple(iterator) + self.assertRaises(StopIteration, next, iterator) + + def test_pickle_iterator(self): + cases = ['abc', '🚀🚀🚀', "\u1111\u2222\u3333"] + for case in cases: + with self.subTest(case=case): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + it = iter(case) + with self.subTest(proto=proto): + pickled = "".join(pickle.loads(pickle.dumps(it, proto))) + self.assertEqual(case, pickled) + def test_count(self): string_tests.CommonTest.test_count(self) # check mixed argument types @@ -210,6 +237,10 @@ class UnicodeTest(string_tests.CommonTest, self.checkequal(0, 'a' * 10, 'count', 'a\u0102') self.checkequal(0, 'a' * 10, 'count', 'a\U00100304') self.checkequal(0, '\u0102' * 10, 'count', '\u0102\U00100304') + # test subclass + class MyStr(str): + pass + self.checkequal(3, MyStr('aaa'), 'count', 'a') def test_find(self): string_tests.CommonTest.test_find(self) @@ -226,6 +257,20 @@ class UnicodeTest(string_tests.CommonTest, self.checkequalnofix(9, 'abcdefghiabc', 'find', 'abc', 1) self.checkequalnofix(-1, 'abcdefghiabc', 'find', 'def', 4) + # test utf-8 non-ascii char + self.checkequal(0, 'теÑÑ‚', 'find', 'Ñ‚') + self.checkequal(3, 'теÑÑ‚', 'find', 'Ñ‚', 1) + self.checkequal(-1, 'теÑÑ‚', 'find', 'Ñ‚', 1, 3) + self.checkequal(-1, 'теÑÑ‚', 'find', 'e') # english `e` + # test utf-8 non-ascii slice + self.checkequal(1, 'теÑÑ‚ теÑÑ‚', 'find', 'еÑ') + self.checkequal(1, 'теÑÑ‚ теÑÑ‚', 'find', 'еÑ', 1) + self.checkequal(1, 'теÑÑ‚ теÑÑ‚', 'find', 'еÑ', 1, 3) + self.checkequal(6, 'теÑÑ‚ теÑÑ‚', 'find', 'еÑ', 2) + self.checkequal(-1, 'теÑÑ‚ теÑÑ‚', 'find', 'еÑ', 6, 7) + self.checkequal(-1, 'теÑÑ‚ теÑÑ‚', 'find', 'еÑ', 7) + self.checkequal(-1, 'теÑÑ‚ теÑÑ‚', 'find', 'ec') # english `ec` + self.assertRaises(TypeError, 'hello'.find) self.assertRaises(TypeError, 'hello'.find, 42) # test mixed kinds @@ -256,6 +301,19 @@ class UnicodeTest(string_tests.CommonTest, self.checkequalnofix(9, 'abcdefghiabc', 'rfind', 'abc') self.checkequalnofix(12, 'abcdefghiabc', 'rfind', '') self.checkequalnofix(12, 'abcdefghiabc', 'rfind', '') + # test utf-8 non-ascii char + self.checkequal(1, 'теÑÑ‚', 'rfind', 'е') + self.checkequal(1, 'теÑÑ‚', 'rfind', 'е', 1) + self.checkequal(-1, 'теÑÑ‚', 'rfind', 'е', 2) + self.checkequal(-1, 'теÑÑ‚', 'rfind', 'e') # english `e` + # test utf-8 non-ascii slice + self.checkequal(6, 'теÑÑ‚ теÑÑ‚', 'rfind', 'еÑ') + self.checkequal(6, 'теÑÑ‚ теÑÑ‚', 'rfind', 'еÑ', 1) + self.checkequal(1, 'теÑÑ‚ теÑÑ‚', 'rfind', 'еÑ', 1, 3) + self.checkequal(6, 'теÑÑ‚ теÑÑ‚', 'rfind', 'еÑ', 2) + self.checkequal(-1, 'теÑÑ‚ теÑÑ‚', 'rfind', 'еÑ', 6, 7) + self.checkequal(-1, 'теÑÑ‚ теÑÑ‚', 'rfind', 'еÑ', 7) + self.checkequal(-1, 'теÑÑ‚ теÑÑ‚', 'rfind', 'ec') # english `ec` # test mixed kinds self.checkequal(0, 'a' + '\u0102' * 100, 'rfind', 'a') self.checkequal(0, 'a' + '\U00100304' * 100, 'rfind', 'a') @@ -410,10 +468,10 @@ class UnicodeTest(string_tests.CommonTest, def test_rsplit(self): string_tests.CommonTest.test_rsplit(self) # test mixed kinds - for left, right in ('ba', '\u0101\u0100', '\U00010301\U00010300'): + for left, right in ('ba', 'ÑŽÑ‘', '\u0101\u0100', '\U00010301\U00010300'): left *= 9 right *= 9 - for delim in ('c', '\u0102', '\U00010302'): + for delim in ('c', 'Ñ‹', '\u0102', '\U00010302'): self.checkequal([left + right], left + right, 'rsplit', delim) self.checkequal([left, right], @@ -423,6 +481,10 @@ class UnicodeTest(string_tests.CommonTest, self.checkequal([left, right], left + delim * 2 + right, 'rsplit', delim *2) + # Check `None` as well: + self.checkequal([left + right], + left + right, 'rsplit', None) + def test_partition(self): string_tests.MixinStrUnicodeUserStringTest.test_partition(self) # test mixed kinds @@ -619,8 +681,7 @@ class UnicodeTest(string_tests.CommonTest, def test_isupper(self): super().test_isupper() - if not sys.platform.startswith('java'): - self.checkequalnofix(False, '\u1FFc', 'isupper') + self.checkequalnofix(False, '\u1FFc', 'isupper') self.assertTrue('\u2167'.isupper()) self.assertFalse('\u2177'.isupper()) # non-BMP, uppercase @@ -1245,6 +1306,20 @@ class UnicodeTest(string_tests.CommonTest, self.assertRaises(ValueError, ("{" + big + "}").format) self.assertRaises(ValueError, ("{[" + big + "]}").format, [0]) + # test number formatter errors: + self.assertRaises(ValueError, '{0:x}'.format, 1j) + self.assertRaises(ValueError, '{0:x}'.format, 1.0) + self.assertRaises(ValueError, '{0:X}'.format, 1j) + self.assertRaises(ValueError, '{0:X}'.format, 1.0) + self.assertRaises(ValueError, '{0:o}'.format, 1j) + self.assertRaises(ValueError, '{0:o}'.format, 1.0) + self.assertRaises(ValueError, '{0:u}'.format, 1j) + self.assertRaises(ValueError, '{0:u}'.format, 1.0) + self.assertRaises(ValueError, '{0:i}'.format, 1j) + self.assertRaises(ValueError, '{0:i}'.format, 1.0) + self.assertRaises(ValueError, '{0:d}'.format, 1j) + self.assertRaises(ValueError, '{0:d}'.format, 1.0) + # issue 6089 self.assertRaises(ValueError, "{0[0]x}".format, [None]) self.assertRaises(ValueError, "{0[0](10)}".format, [None]) @@ -1408,10 +1483,9 @@ class UnicodeTest(string_tests.CommonTest, self.assertEqual("%s, %s, %i, %f, %5.2f" % ("abc", "abc", -1, -2, 3.5), 'abc, abc, -1, -2.000000, 3.50') self.assertEqual("%s, %s, %i, %f, %5.2f" % ("abc", "abc", -1, -2, 3.57), 'abc, abc, -1, -2.000000, 3.57') self.assertEqual("%s, %s, %i, %f, %5.2f" % ("abc", "abc", -1, -2, 1003.57), 'abc, abc, -1, -2.000000, 1003.57') - if not sys.platform.startswith('java'): - self.assertEqual("%r, %r" % (b"abc", "abc"), "b'abc', 'abc'") - self.assertEqual("%r" % ("\u1234",), "'\u1234'") - self.assertEqual("%a" % ("\u1234",), "'\\u1234'") + self.assertEqual("%r, %r" % (b"abc", "abc"), "b'abc', 'abc'") + self.assertEqual("%r" % ("\u1234",), "'\u1234'") + self.assertEqual("%a" % ("\u1234",), "'\\u1234'") self.assertEqual("%(x)s, %(y)s" % {'x':"abc", 'y':"def"}, 'abc, def') self.assertEqual("%(x)s, %(\xfc)s" % {'x':"abc", '\xfc':"def"}, 'abc, def') @@ -1480,18 +1554,40 @@ class UnicodeTest(string_tests.CommonTest, self.assertEqual('%X' % letter_m, '6D') self.assertEqual('%o' % letter_m, '155') self.assertEqual('%c' % letter_m, 'm') - self.assertRaisesRegex(TypeError, '%x format: an integer is required, not float', operator.mod, '%x', 3.14), - self.assertRaisesRegex(TypeError, '%X format: an integer is required, not float', operator.mod, '%X', 2.11), - self.assertRaisesRegex(TypeError, '%o format: an integer is required, not float', operator.mod, '%o', 1.79), - self.assertRaisesRegex(TypeError, '%x format: an integer is required, not PseudoFloat', operator.mod, '%x', pi), - self.assertRaises(TypeError, operator.mod, '%c', pi), + self.assertRaisesRegex(TypeError, '%x format: an integer is required, not float', operator.mod, '%x', 3.14) + self.assertRaisesRegex(TypeError, '%X format: an integer is required, not float', operator.mod, '%X', 2.11) + self.assertRaisesRegex(TypeError, '%o format: an integer is required, not float', operator.mod, '%o', 1.79) + self.assertRaisesRegex(TypeError, '%x format: an integer is required, not PseudoFloat', operator.mod, '%x', pi) + self.assertRaisesRegex(TypeError, '%x format: an integer is required, not complex', operator.mod, '%x', 3j) + self.assertRaisesRegex(TypeError, '%X format: an integer is required, not complex', operator.mod, '%X', 2j) + self.assertRaisesRegex(TypeError, '%o format: an integer is required, not complex', operator.mod, '%o', 1j) + self.assertRaisesRegex(TypeError, '%u format: a real number is required, not complex', operator.mod, '%u', 3j) + self.assertRaisesRegex(TypeError, '%i format: a real number is required, not complex', operator.mod, '%i', 2j) + self.assertRaisesRegex(TypeError, '%d format: a real number is required, not complex', operator.mod, '%d', 1j) + self.assertRaisesRegex(TypeError, '%c requires int or char', operator.mod, '%c', pi) + + class RaisingNumber: + def __int__(self): + raise RuntimeError('int') # should not be `TypeError` + def __index__(self): + raise RuntimeError('index') # should not be `TypeError` + + rn = RaisingNumber() + self.assertRaisesRegex(RuntimeError, 'int', operator.mod, '%d', rn) + self.assertRaisesRegex(RuntimeError, 'int', operator.mod, '%i', rn) + self.assertRaisesRegex(RuntimeError, 'int', operator.mod, '%u', rn) + self.assertRaisesRegex(RuntimeError, 'index', operator.mod, '%x', rn) + self.assertRaisesRegex(RuntimeError, 'index', operator.mod, '%X', rn) + self.assertRaisesRegex(RuntimeError, 'index', operator.mod, '%o', rn) def test_formatting_with_enum(self): # issue18780 import enum class Float(float, enum.Enum): + # a mixed-in type will use the name for %s etc. PI = 3.1415926 class Int(enum.IntEnum): + # IntEnum uses the value and not the name for %s etc. IDES = 15 class Str(enum.StrEnum): # StrEnum uses the value and not the name for %s etc. @@ -1508,8 +1604,10 @@ class UnicodeTest(string_tests.CommonTest, # formatting jobs delegated from the string implementation: self.assertEqual('...%(foo)s...' % {'foo':Str.ABC}, '...abc...') + self.assertEqual('...%(foo)r...' % {'foo':Int.IDES}, + '......') self.assertEqual('...%(foo)s...' % {'foo':Int.IDES}, - '...IDES...') + '...15...') self.assertEqual('...%(foo)i...' % {'foo':Int.IDES}, '...15...') self.assertEqual('...%(foo)d...' % {'foo':Int.IDES}, @@ -1602,29 +1700,27 @@ class UnicodeTest(string_tests.CommonTest, # unicode(obj, encoding, error) tests (this maps to # PyUnicode_FromEncodedObject() at C level) - if not sys.platform.startswith('java'): - self.assertRaises( - TypeError, - str, - 'decoding unicode is not supported', - 'utf-8', - 'strict' - ) + self.assertRaises( + TypeError, + str, + 'decoding unicode is not supported', + 'utf-8', + 'strict' + ) self.assertEqual( str(b'strings are decoded to unicode', 'utf-8', 'strict'), 'strings are decoded to unicode' ) - if not sys.platform.startswith('java'): - self.assertEqual( - str( - memoryview(b'character buffers are decoded to unicode'), - 'utf-8', - 'strict' - ), - 'character buffers are decoded to unicode' - ) + self.assertEqual( + str( + memoryview(b'character buffers are decoded to unicode'), + 'utf-8', + 'strict' + ), + 'character buffers are decoded to unicode' + ) self.assertRaises(TypeError, str, 42, 42, 42) @@ -2310,12 +2406,7 @@ class UnicodeTest(string_tests.CommonTest, def __repr__(self): return '\\n' - class s2: - def __repr__(self): - return '\\n' - self.assertEqual(repr(s1()), '\\n') - self.assertEqual(repr(s2()), '\\n') def test_printable_repr(self): self.assertEqual(repr('\U00010000'), "'%c'" % (0x10000,)) # printable @@ -2335,20 +2426,19 @@ class UnicodeTest(string_tests.CommonTest, self.assertIs(s.expandtabs(), s) def test_raiseMemError(self): - if struct.calcsize('P') == 8: - # 64 bits pointers - ascii_struct_size = 48 - compact_struct_size = 72 - else: - # 32 bits pointers - ascii_struct_size = 24 - compact_struct_size = 36 + asciifields = "nnb" + compactfields = asciifields + "nP" + ascii_struct_size = support.calcobjsize(asciifields) + compact_struct_size = support.calcobjsize(compactfields) for char in ('a', '\xe9', '\u20ac', '\U0010ffff'): code = ord(char) - if code < 0x100: + if code < 0x80: char_size = 1 # sizeof(Py_UCS1) struct_size = ascii_struct_size + elif code < 0x100: + char_size = 1 # sizeof(Py_UCS1) + struct_size = compact_struct_size elif code < 0x10000: char_size = 2 # sizeof(Py_UCS2) struct_size = compact_struct_size @@ -2360,8 +2450,18 @@ class UnicodeTest(string_tests.CommonTest, # be allocatable, given enough memory. maxlen = ((sys.maxsize - struct_size) // char_size) alloc = lambda: char * maxlen - self.assertRaises(MemoryError, alloc) - self.assertRaises(MemoryError, alloc) + with self.subTest( + char=char, + struct_size=struct_size, + char_size=char_size + ): + # self-check + self.assertEqual( + sys.getsizeof(char * 42), + struct_size + (char_size * (42 + 1)) + ) + self.assertRaises(MemoryError, alloc) + self.assertRaises(MemoryError, alloc) def test_format_subclass(self): class S(str): @@ -2549,447 +2649,6 @@ class UnicodeTest(string_tests.CommonTest, self.assertEqual(proc.rc, 10, proc) -class CAPITest(unittest.TestCase): - - # Test PyUnicode_FromFormat() - def test_from_format(self): - import_helper.import_module('ctypes') - from ctypes import ( - c_char_p, - pythonapi, py_object, sizeof, - c_int, c_long, c_longlong, c_ssize_t, - c_uint, c_ulong, c_ulonglong, c_size_t, c_void_p) - name = "PyUnicode_FromFormat" - _PyUnicode_FromFormat = getattr(pythonapi, name) - _PyUnicode_FromFormat.argtypes = (c_char_p,) - _PyUnicode_FromFormat.restype = py_object - - def PyUnicode_FromFormat(format, *args): - cargs = tuple( - py_object(arg) if isinstance(arg, str) else arg - for arg in args) - return _PyUnicode_FromFormat(format, *cargs) - - def check_format(expected, format, *args): - text = PyUnicode_FromFormat(format, *args) - self.assertEqual(expected, text) - - # ascii format, non-ascii argument - check_format('ascii\x7f=unicode\xe9', - b'ascii\x7f=%U', 'unicode\xe9') - - # non-ascii format, ascii argument: ensure that PyUnicode_FromFormatV() - # raises an error - self.assertRaisesRegex(ValueError, - r'^PyUnicode_FromFormatV\(\) expects an ASCII-encoded format ' - 'string, got a non-ASCII byte: 0xe9$', - PyUnicode_FromFormat, b'unicode\xe9=%s', 'ascii') - - # test "%c" - check_format('\uabcd', - b'%c', c_int(0xabcd)) - check_format('\U0010ffff', - b'%c', c_int(0x10ffff)) - with self.assertRaises(OverflowError): - PyUnicode_FromFormat(b'%c', c_int(0x110000)) - # Issue #18183 - check_format('\U00010000\U00100000', - b'%c%c', c_int(0x10000), c_int(0x100000)) - - # test "%" - check_format('%', - b'%') - check_format('%', - b'%%') - check_format('%s', - b'%%s') - check_format('[%]', - b'[%%]') - check_format('%abc', - b'%%%s', b'abc') - - # truncated string - check_format('abc', - b'%.3s', b'abcdef') - check_format('abc[\ufffd', - b'%.5s', 'abc[\u20ac]'.encode('utf8')) - check_format("'\\u20acABC'", - b'%A', '\u20acABC') - check_format("'\\u20", - b'%.5A', '\u20acABCDEF') - check_format("'\u20acABC'", - b'%R', '\u20acABC') - check_format("'\u20acA", - b'%.3R', '\u20acABCDEF') - check_format('\u20acAB', - b'%.3S', '\u20acABCDEF') - check_format('\u20acAB', - b'%.3U', '\u20acABCDEF') - check_format('\u20acAB', - b'%.3V', '\u20acABCDEF', None) - check_format('abc[\ufffd', - b'%.5V', None, 'abc[\u20ac]'.encode('utf8')) - - # following tests comes from #7330 - # test width modifier and precision modifier with %S - check_format("repr= abc", - b'repr=%5S', 'abc') - check_format("repr=ab", - b'repr=%.2S', 'abc') - check_format("repr= ab", - b'repr=%5.2S', 'abc') - - # test width modifier and precision modifier with %R - check_format("repr= 'abc'", - b'repr=%8R', 'abc') - check_format("repr='ab", - b'repr=%.3R', 'abc') - check_format("repr= 'ab", - b'repr=%5.3R', 'abc') - - # test width modifier and precision modifier with %A - check_format("repr= 'abc'", - b'repr=%8A', 'abc') - check_format("repr='ab", - b'repr=%.3A', 'abc') - check_format("repr= 'ab", - b'repr=%5.3A', 'abc') - - # test width modifier and precision modifier with %s - check_format("repr= abc", - b'repr=%5s', b'abc') - check_format("repr=ab", - b'repr=%.2s', b'abc') - check_format("repr= ab", - b'repr=%5.2s', b'abc') - - # test width modifier and precision modifier with %U - check_format("repr= abc", - b'repr=%5U', 'abc') - check_format("repr=ab", - b'repr=%.2U', 'abc') - check_format("repr= ab", - b'repr=%5.2U', 'abc') - - # test width modifier and precision modifier with %V - check_format("repr= abc", - b'repr=%5V', 'abc', b'123') - check_format("repr=ab", - b'repr=%.2V', 'abc', b'123') - check_format("repr= ab", - b'repr=%5.2V', 'abc', b'123') - check_format("repr= 123", - b'repr=%5V', None, b'123') - check_format("repr=12", - b'repr=%.2V', None, b'123') - check_format("repr= 12", - b'repr=%5.2V', None, b'123') - - # test integer formats (%i, %d, %u) - check_format('010', - b'%03i', c_int(10)) - check_format('0010', - b'%0.4i', c_int(10)) - check_format('-123', - b'%i', c_int(-123)) - check_format('-123', - b'%li', c_long(-123)) - check_format('-123', - b'%lli', c_longlong(-123)) - check_format('-123', - b'%zi', c_ssize_t(-123)) - - check_format('-123', - b'%d', c_int(-123)) - check_format('-123', - b'%ld', c_long(-123)) - check_format('-123', - b'%lld', c_longlong(-123)) - check_format('-123', - b'%zd', c_ssize_t(-123)) - - check_format('123', - b'%u', c_uint(123)) - check_format('123', - b'%lu', c_ulong(123)) - check_format('123', - b'%llu', c_ulonglong(123)) - check_format('123', - b'%zu', c_size_t(123)) - - # test long output - min_longlong = -(2 ** (8 * sizeof(c_longlong) - 1)) - max_longlong = -min_longlong - 1 - check_format(str(min_longlong), - b'%lld', c_longlong(min_longlong)) - check_format(str(max_longlong), - b'%lld', c_longlong(max_longlong)) - max_ulonglong = 2 ** (8 * sizeof(c_ulonglong)) - 1 - check_format(str(max_ulonglong), - b'%llu', c_ulonglong(max_ulonglong)) - PyUnicode_FromFormat(b'%p', c_void_p(-1)) - - # test padding (width and/or precision) - check_format('123'.rjust(10, '0'), - b'%010i', c_int(123)) - check_format('123'.rjust(100), - b'%100i', c_int(123)) - check_format('123'.rjust(100, '0'), - b'%.100i', c_int(123)) - check_format('123'.rjust(80, '0').rjust(100), - b'%100.80i', c_int(123)) - - check_format('123'.rjust(10, '0'), - b'%010u', c_uint(123)) - check_format('123'.rjust(100), - b'%100u', c_uint(123)) - check_format('123'.rjust(100, '0'), - b'%.100u', c_uint(123)) - check_format('123'.rjust(80, '0').rjust(100), - b'%100.80u', c_uint(123)) - - check_format('123'.rjust(10, '0'), - b'%010x', c_int(0x123)) - check_format('123'.rjust(100), - b'%100x', c_int(0x123)) - check_format('123'.rjust(100, '0'), - b'%.100x', c_int(0x123)) - check_format('123'.rjust(80, '0').rjust(100), - b'%100.80x', c_int(0x123)) - - # test %A - check_format(r"%A:'abc\xe9\uabcd\U0010ffff'", - b'%%A:%A', 'abc\xe9\uabcd\U0010ffff') - - # test %V - check_format('repr=abc', - b'repr=%V', 'abc', b'xyz') - - # Test string decode from parameter of %s using utf-8. - # b'\xe4\xba\xba\xe6\xb0\x91' is utf-8 encoded byte sequence of - # '\u4eba\u6c11' - check_format('repr=\u4eba\u6c11', - b'repr=%V', None, b'\xe4\xba\xba\xe6\xb0\x91') - - #Test replace error handler. - check_format('repr=abc\ufffd', - b'repr=%V', None, b'abc\xff') - - # not supported: copy the raw format string. these tests are just here - # to check for crashes and should not be considered as specifications - check_format('%s', - b'%1%s', b'abc') - check_format('%1abc', - b'%1abc') - check_format('%+i', - b'%+i', c_int(10)) - check_format('%.%s', - b'%.%s', b'abc') - - # Issue #33817: empty strings - check_format('', - b'') - check_format('', - b'%s', b'') - - # Test PyUnicode_AsWideChar() - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') - def test_aswidechar(self): - from _testcapi import unicode_aswidechar - import_helper.import_module('ctypes') - from ctypes import c_wchar, sizeof - - wchar, size = unicode_aswidechar('abcdef', 2) - self.assertEqual(size, 2) - self.assertEqual(wchar, 'ab') - - wchar, size = unicode_aswidechar('abc', 3) - self.assertEqual(size, 3) - self.assertEqual(wchar, 'abc') - - wchar, size = unicode_aswidechar('abc', 4) - self.assertEqual(size, 3) - self.assertEqual(wchar, 'abc\0') - - wchar, size = unicode_aswidechar('abc', 10) - self.assertEqual(size, 3) - self.assertEqual(wchar, 'abc\0') - - wchar, size = unicode_aswidechar('abc\0def', 20) - self.assertEqual(size, 7) - self.assertEqual(wchar, 'abc\0def\0') - - nonbmp = chr(0x10ffff) - if sizeof(c_wchar) == 2: - buflen = 3 - nchar = 2 - else: # sizeof(c_wchar) == 4 - buflen = 2 - nchar = 1 - wchar, size = unicode_aswidechar(nonbmp, buflen) - self.assertEqual(size, nchar) - self.assertEqual(wchar, nonbmp + '\0') - - # Test PyUnicode_AsWideCharString() - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') - def test_aswidecharstring(self): - from _testcapi import unicode_aswidecharstring - import_helper.import_module('ctypes') - from ctypes import c_wchar, sizeof - - wchar, size = unicode_aswidecharstring('abc') - self.assertEqual(size, 3) - self.assertEqual(wchar, 'abc\0') - - wchar, size = unicode_aswidecharstring('abc\0def') - self.assertEqual(size, 7) - self.assertEqual(wchar, 'abc\0def\0') - - nonbmp = chr(0x10ffff) - if sizeof(c_wchar) == 2: - nchar = 2 - else: # sizeof(c_wchar) == 4 - nchar = 1 - wchar, size = unicode_aswidecharstring(nonbmp) - self.assertEqual(size, nchar) - self.assertEqual(wchar, nonbmp + '\0') - - # Test PyUnicode_AsUCS4() - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') - def test_asucs4(self): - from _testcapi import unicode_asucs4 - for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600', - 'a\ud800b\udfffc', '\ud834\udd1e']: - l = len(s) - self.assertEqual(unicode_asucs4(s, l, True), s+'\0') - self.assertEqual(unicode_asucs4(s, l, False), s+'\uffff') - self.assertEqual(unicode_asucs4(s, l+1, True), s+'\0\uffff') - self.assertEqual(unicode_asucs4(s, l+1, False), s+'\0\uffff') - self.assertRaises(SystemError, unicode_asucs4, s, l-1, True) - self.assertRaises(SystemError, unicode_asucs4, s, l-2, False) - s = '\0'.join([s, s]) - self.assertEqual(unicode_asucs4(s, len(s), True), s+'\0') - self.assertEqual(unicode_asucs4(s, len(s), False), s+'\uffff') - - # Test PyUnicode_AsUTF8() - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') - def test_asutf8(self): - from _testcapi import unicode_asutf8 - - bmp = '\u0100' - bmp2 = '\uffff' - nonbmp = chr(0x10ffff) - - self.assertEqual(unicode_asutf8(bmp), b'\xc4\x80') - self.assertEqual(unicode_asutf8(bmp2), b'\xef\xbf\xbf') - self.assertEqual(unicode_asutf8(nonbmp), b'\xf4\x8f\xbf\xbf') - self.assertRaises(UnicodeEncodeError, unicode_asutf8, 'a\ud800b\udfffc') - - # Test PyUnicode_AsUTF8AndSize() - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') - def test_asutf8andsize(self): - from _testcapi import unicode_asutf8andsize - - bmp = '\u0100' - bmp2 = '\uffff' - nonbmp = chr(0x10ffff) - - self.assertEqual(unicode_asutf8andsize(bmp), (b'\xc4\x80', 2)) - self.assertEqual(unicode_asutf8andsize(bmp2), (b'\xef\xbf\xbf', 3)) - self.assertEqual(unicode_asutf8andsize(nonbmp), (b'\xf4\x8f\xbf\xbf', 4)) - self.assertRaises(UnicodeEncodeError, unicode_asutf8andsize, 'a\ud800b\udfffc') - - # Test PyUnicode_FindChar() - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') - def test_findchar(self): - from _testcapi import unicode_findchar - - for str in "\xa1", "\u8000\u8080", "\ud800\udc02", "\U0001f100\U0001f1f1": - for i, ch in enumerate(str): - self.assertEqual(unicode_findchar(str, ord(ch), 0, len(str), 1), i) - self.assertEqual(unicode_findchar(str, ord(ch), 0, len(str), -1), i) - - str = "!>_= end - self.assertEqual(unicode_findchar(str, ord('!'), 0, 0, 1), -1) - self.assertEqual(unicode_findchar(str, ord('!'), len(str), 0, 1), -1) - # negative - self.assertEqual(unicode_findchar(str, ord('!'), -len(str), -1, 1), 0) - self.assertEqual(unicode_findchar(str, ord('!'), -len(str), -1, -1), 0) - - # Test PyUnicode_CopyCharacters() - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') - def test_copycharacters(self): - from _testcapi import unicode_copycharacters - - strings = [ - 'abcde', '\xa1\xa2\xa3\xa4\xa5', - '\u4f60\u597d\u4e16\u754c\uff01', - '\U0001f600\U0001f601\U0001f602\U0001f603\U0001f604' - ] - - for idx, from_ in enumerate(strings): - # wide -> narrow: exceed maxchar limitation - for to in strings[:idx]: - self.assertRaises( - SystemError, - unicode_copycharacters, to, 0, from_, 0, 5 - ) - # same kind - for from_start in range(5): - self.assertEqual( - unicode_copycharacters(from_, 0, from_, from_start, 5), - (from_[from_start:from_start+5].ljust(5, '\0'), - 5-from_start) - ) - for to_start in range(5): - self.assertEqual( - unicode_copycharacters(from_, to_start, from_, to_start, 5), - (from_[to_start:to_start+5].rjust(5, '\0'), - 5-to_start) - ) - # narrow -> wide - # Tests omitted since this creates invalid strings. - - s = strings[0] - self.assertRaises(IndexError, unicode_copycharacters, s, 6, s, 0, 5) - self.assertRaises(IndexError, unicode_copycharacters, s, -1, s, 0, 5) - self.assertRaises(IndexError, unicode_copycharacters, s, 0, s, 6, 5) - self.assertRaises(IndexError, unicode_copycharacters, s, 0, s, -1, 5) - self.assertRaises(SystemError, unicode_copycharacters, s, 1, s, 0, 5) - self.assertRaises(SystemError, unicode_copycharacters, s, 0, s, 0, -1) - self.assertRaises(SystemError, unicode_copycharacters, s, 0, b'', 0, 0) - - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') - def test_pep393_utf8_caching_bug(self): - # Issue #25709: Problem with string concatenation and utf-8 cache - from _testcapi import getargs_s_hash - for k in 0x24, 0xa4, 0x20ac, 0x1f40d: - s = '' - for i in range(5): - # Due to CPython specific optimization the 's' string can be - # resized in-place. - s += chr(k) - # Parsing with the "s#" format code calls indirectly - # PyUnicode_AsUTF8AndSize() which creates the UTF-8 - # encoded string cached in the Unicode object. - self.assertEqual(getargs_s_hash(s), chr(k).encode() * (i + 1)) - # Check that the second call returns the same result - self.assertEqual(getargs_s_hash(s), chr(k).encode() * (i + 1)) - class StringModuleTest(unittest.TestCase): def test_formatter_parser(self): def parse(format): @@ -3040,6 +2699,30 @@ class StringModuleTest(unittest.TestCase): ]]) self.assertRaises(TypeError, _string.formatter_field_name_split, 1) + def test_str_subclass_attr(self): + + name = StrSubclass("name") + name2 = StrSubclass("name2") + class Bag: + pass + + o = Bag() + with self.assertRaises(AttributeError): + delattr(o, name) + setattr(o, name, 1) + self.assertEqual(o.name, 1) + o.name = 2 + self.assertEqual(list(o.__dict__), [name]) + + with self.assertRaises(AttributeError): + delattr(o, name2) + with self.assertRaises(AttributeError): + del o.name2 + setattr(o, name2, 3) + self.assertEqual(o.name2, 3) + o.name2 = 4 + self.assertEqual(list(o.__dict__), [name, name2]) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_unicode_file.py b/Lib/test/test_unicode_file.py index 80c22c6cdd1..fe25bfe9f88 100644 --- a/Lib/test/test_unicode_file.py +++ b/Lib/test/test_unicode_file.py @@ -110,7 +110,7 @@ class TestUnicodeFiles(unittest.TestCase): os.unlink(filename) self.assertTrue(not os.path.exists(filename)) # and again with os.open. - f = os.open(filename, os.O_CREAT) + f = os.open(filename, os.O_CREAT | os.O_WRONLY) os.close(f) try: self._do_single(filename) diff --git a/Lib/test/test_unicode_file_functions.py b/Lib/test/test_unicode_file_functions.py index 54916dec4ea..47619c8807b 100644 --- a/Lib/test/test_unicode_file_functions.py +++ b/Lib/test/test_unicode_file_functions.py @@ -6,6 +6,7 @@ import unittest import warnings from unicodedata import normalize from test.support import os_helper +from test import support filenames = [ @@ -123,6 +124,10 @@ class UnicodeFileTests(unittest.TestCase): # NFKD in Python is useless, because darwin will normalize it later and so # open(), os.stat(), etc. don't raise any exception. @unittest.skipIf(sys.platform == 'darwin', 'irrelevant test on Mac OS X') + @unittest.skipIf( + support.is_emscripten or support.is_wasi, + "test fails on Emscripten/WASI when host platform is macOS." + ) def test_normalize(self): files = set(self.files) others = set() diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py index 3514697f548..74503c89e55 100644 --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -12,13 +12,14 @@ import sys import unicodedata import unittest from test.support import (open_urlresource, requires_resource, script_helper, - cpython_only, check_disallow_instantiation) + cpython_only, check_disallow_instantiation, + ResourceDenied) class UnicodeMethodsTest(unittest.TestCase): # update this, if the database changes - expectedchecksum = '4739770dd4d0e5f1b1677accfc3552ed3c8ef326' + expectedchecksum = 'e708c31c0d51f758adf475cb7201cf80917362be' @requires_resource('cpu') def test_method_checksum(self): @@ -71,7 +72,7 @@ class UnicodeFunctionsTest(UnicodeDatabaseTest): # Update this if the database changes. Make sure to do a full rebuild # (e.g. 'make distclean && make') to get the correct checksum. - expectedchecksum = '98d602e1f69d5c5bb8a5910c40bbbad4e18e8370' + expectedchecksum = '26ff0d31c14194b4606a5b3a81ac36df3a14e331' @requires_resource('cpu') def test_function_checksum(self): @@ -90,11 +91,20 @@ class UnicodeFunctionsTest(UnicodeDatabaseTest): self.db.decomposition(char), str(self.db.mirrored(char)), str(self.db.combining(char)), + unicodedata.east_asian_width(char), + self.db.name(char, ""), ] h.update(''.join(data).encode("ascii")) result = h.hexdigest() self.assertEqual(result, self.expectedchecksum) + @requires_resource('cpu') + def test_name_inverse_lookup(self): + for i in range(sys.maxunicode + 1): + char = chr(i) + if looked_name := self.db.name(char, None): + self.assertEqual(self.db.lookup(looked_name), char) + def test_digit(self): self.assertEqual(self.db.digit('A', None), None) self.assertEqual(self.db.digit('9'), 9) @@ -220,6 +230,23 @@ class UnicodeFunctionsTest(UnicodeDatabaseTest): self.assertEqual(eaw('\u2010'), 'A') self.assertEqual(eaw('\U00020000'), 'W') + def test_east_asian_width_unassigned(self): + eaw = self.db.east_asian_width + # unassigned + for char in '\u0530\u0ecf\u10c6\u20fc\uaaca\U000107bd\U000115f2': + self.assertEqual(eaw(char), 'N') + self.assertIs(self.db.name(char, None), None) + + # unassigned but reserved for CJK + for char in '\uFA6E\uFADA\U0002A6E0\U0002FA20\U0003134B\U0003FFFD': + self.assertEqual(eaw(char), 'W') + self.assertIs(self.db.name(char, None), None) + + # private use areas + for char in '\uE000\uF800\U000F0000\U000FFFEE\U00100000\U0010FFF0': + self.assertEqual(eaw(char), 'A') + self.assertIs(self.db.name(char, None), None) + def test_east_asian_width_9_0_changes(self): self.assertEqual(self.db.ucd_3_2_0.east_asian_width('\u231a'), 'N') self.assertEqual(self.db.east_asian_width('\u231a'), 'W') @@ -338,8 +365,8 @@ class NormalizationTest(unittest.TestCase): except PermissionError: self.skipTest(f"Permission error when downloading {TESTDATAURL} " f"into the test data directory") - except (OSError, HTTPException): - self.fail(f"Could not retrieve {TESTDATAURL}") + except (OSError, HTTPException) as exc: + self.skipTest(f"Failed to download {TESTDATAURL}: {exc}") with testdata: self.run_normalization_tests(testdata) diff --git a/Lib/test/test_unittest.py b/Lib/test/test_unittest.py deleted file mode 100644 index 1079c7df2e5..00000000000 --- a/Lib/test/test_unittest.py +++ /dev/null @@ -1,16 +0,0 @@ -import unittest.test - -from test import support - - -def load_tests(*_): - # used by unittest - return unittest.test.suite() - - -def tearDownModule(): - support.reap_children() - - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/test/test_unittest/__init__.py b/Lib/test/test_unittest/__init__.py new file mode 100644 index 00000000000..bc502ef32d2 --- /dev/null +++ b/Lib/test/test_unittest/__init__.py @@ -0,0 +1,6 @@ +import os.path +from test.support import load_package_tests + + +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_unittest/__main__.py b/Lib/test/test_unittest/__main__.py new file mode 100644 index 00000000000..40a23a297ec --- /dev/null +++ b/Lib/test/test_unittest/__main__.py @@ -0,0 +1,4 @@ +from . import load_tests +import unittest + +unittest.main() diff --git a/Lib/unittest/test/_test_warnings.py b/Lib/test/test_unittest/_test_warnings.py similarity index 100% rename from Lib/unittest/test/_test_warnings.py rename to Lib/test/test_unittest/_test_warnings.py diff --git a/Lib/unittest/test/dummy.py b/Lib/test/test_unittest/dummy.py similarity index 100% rename from Lib/unittest/test/dummy.py rename to Lib/test/test_unittest/dummy.py diff --git a/Lib/unittest/test/support.py b/Lib/test/test_unittest/support.py similarity index 100% rename from Lib/unittest/test/support.py rename to Lib/test/test_unittest/support.py diff --git a/Lib/unittest/test/test_assertions.py b/Lib/test/test_unittest/test_assertions.py similarity index 100% rename from Lib/unittest/test/test_assertions.py rename to Lib/test/test_unittest/test_assertions.py diff --git a/Lib/unittest/test/test_async_case.py b/Lib/test/test_unittest/test_async_case.py similarity index 64% rename from Lib/unittest/test/test_async_case.py rename to Lib/test/test_unittest/test_async_case.py index 3717486b265..a465103b59b 100644 --- a/Lib/unittest/test/test_async_case.py +++ b/Lib/test/test_unittest/test_async_case.py @@ -1,7 +1,10 @@ import asyncio +import contextvars import unittest from test import support +support.requires_working_socket(module=True) + class MyException(Exception): pass @@ -11,76 +14,134 @@ def tearDownModule(): asyncio.set_event_loop_policy(None) +class TestCM: + def __init__(self, ordering, enter_result=None): + self.ordering = ordering + self.enter_result = enter_result + + async def __aenter__(self): + self.ordering.append('enter') + return self.enter_result + + async def __aexit__(self, *exc_info): + self.ordering.append('exit') + + +class LacksEnterAndExit: + pass +class LacksEnter: + async def __aexit__(self, *exc_info): + pass +class LacksExit: + async def __aenter__(self): + pass + + +VAR = contextvars.ContextVar('VAR', default=()) + + class TestAsyncCase(unittest.TestCase): maxDiff = None - def tearDown(self): + def setUp(self): # Ensure that IsolatedAsyncioTestCase instances are destroyed before # starting a new event loop - support.gc_collect() + self.addCleanup(support.gc_collect) def test_full_cycle(self): + expected = ['setUp', + 'asyncSetUp', + 'test', + 'asyncTearDown', + 'tearDown', + 'cleanup6', + 'cleanup5', + 'cleanup4', + 'cleanup3', + 'cleanup2', + 'cleanup1'] class Test(unittest.IsolatedAsyncioTestCase): def setUp(self): self.assertEqual(events, []) events.append('setUp') - - async def asyncSetUp(self): - self.assertEqual(events, ['setUp']) - events.append('asyncSetUp') - self.addAsyncCleanup(self.on_cleanup1) - - async def test_func(self): - self.assertEqual(events, ['setUp', - 'asyncSetUp']) - events.append('test') + VAR.set(VAR.get() + ('setUp',)) + self.addCleanup(self.on_cleanup1) self.addAsyncCleanup(self.on_cleanup2) + async def asyncSetUp(self): + self.assertEqual(events, expected[:1]) + events.append('asyncSetUp') + VAR.set(VAR.get() + ('asyncSetUp',)) + self.addCleanup(self.on_cleanup3) + self.addAsyncCleanup(self.on_cleanup4) + + async def test_func(self): + self.assertEqual(events, expected[:2]) + events.append('test') + VAR.set(VAR.get() + ('test',)) + self.addCleanup(self.on_cleanup5) + self.addAsyncCleanup(self.on_cleanup6) + async def asyncTearDown(self): - self.assertEqual(events, ['setUp', - 'asyncSetUp', - 'test']) + self.assertEqual(events, expected[:3]) + VAR.set(VAR.get() + ('asyncTearDown',)) events.append('asyncTearDown') def tearDown(self): - self.assertEqual(events, ['setUp', - 'asyncSetUp', - 'test', - 'asyncTearDown']) + self.assertEqual(events, expected[:4]) events.append('tearDown') + VAR.set(VAR.get() + ('tearDown',)) - async def on_cleanup1(self): - self.assertEqual(events, ['setUp', - 'asyncSetUp', - 'test', - 'asyncTearDown', - 'tearDown', - 'cleanup2']) + def on_cleanup1(self): + self.assertEqual(events, expected[:10]) events.append('cleanup1') + VAR.set(VAR.get() + ('cleanup1',)) + nonlocal cvar + cvar = VAR.get() async def on_cleanup2(self): - self.assertEqual(events, ['setUp', - 'asyncSetUp', - 'test', - 'asyncTearDown', - 'tearDown']) + self.assertEqual(events, expected[:9]) events.append('cleanup2') + VAR.set(VAR.get() + ('cleanup2',)) + + def on_cleanup3(self): + self.assertEqual(events, expected[:8]) + events.append('cleanup3') + VAR.set(VAR.get() + ('cleanup3',)) + + async def on_cleanup4(self): + self.assertEqual(events, expected[:7]) + events.append('cleanup4') + VAR.set(VAR.get() + ('cleanup4',)) + + def on_cleanup5(self): + self.assertEqual(events, expected[:6]) + events.append('cleanup5') + VAR.set(VAR.get() + ('cleanup5',)) + + async def on_cleanup6(self): + self.assertEqual(events, expected[:5]) + events.append('cleanup6') + VAR.set(VAR.get() + ('cleanup6',)) events = [] + cvar = () test = Test("test_func") result = test.run() self.assertEqual(result.errors, []) self.assertEqual(result.failures, []) - expected = ['setUp', 'asyncSetUp', 'test', - 'asyncTearDown', 'tearDown', 'cleanup2', 'cleanup1'] self.assertEqual(events, expected) + self.assertEqual(cvar, tuple(expected)) events = [] + cvar = () test = Test("test_func") test.debug() self.assertEqual(events, expected) + self.assertEqual(cvar, tuple(expected)) test.doCleanups() self.assertEqual(events, expected) + self.assertEqual(cvar, tuple(expected)) def test_exception_in_setup(self): class Test(unittest.IsolatedAsyncioTestCase): @@ -108,6 +169,7 @@ class TestAsyncCase(unittest.TestCase): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioRunner) try: test.debug() except MyException: @@ -143,6 +205,7 @@ class TestAsyncCase(unittest.TestCase): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioRunner) try: test.debug() except MyException: @@ -178,6 +241,7 @@ class TestAsyncCase(unittest.TestCase): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioRunner) try: test.debug() except MyException: @@ -219,6 +283,7 @@ class TestAsyncCase(unittest.TestCase): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioRunner) try: test.debug() except MyException: @@ -230,24 +295,35 @@ class TestAsyncCase(unittest.TestCase): self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown', 'cleanup2', 'cleanup1']) def test_deprecation_of_return_val_from_test(self): - # Issue 41322 - deprecate return of value!=None from a test + # Issue 41322 - deprecate return of value that is not None from a test + class Nothing: + def __eq__(self, o): + return o is None class Test(unittest.IsolatedAsyncioTestCase): async def test1(self): return 1 async def test2(self): yield 1 + async def test3(self): + return Nothing() with self.assertWarns(DeprecationWarning) as w: Test('test1').run() - self.assertIn('It is deprecated to return a value!=None', str(w.warnings[0].message)) - self.assertIn('test1', str(w.warnings[0].message)) - self.assertEqual(w.warnings[0].filename, __file__) + self.assertIn('It is deprecated to return a value that is not None', str(w.warning)) + self.assertIn('test1', str(w.warning)) + self.assertEqual(w.filename, __file__) with self.assertWarns(DeprecationWarning) as w: Test('test2').run() - self.assertIn('It is deprecated to return a value!=None', str(w.warnings[0].message)) - self.assertIn('test2', str(w.warnings[0].message)) - self.assertEqual(w.warnings[0].filename, __file__) + self.assertIn('It is deprecated to return a value that is not None', str(w.warning)) + self.assertIn('test2', str(w.warning)) + self.assertEqual(w.filename, __file__) + + with self.assertWarns(DeprecationWarning) as w: + Test('test3').run() + self.assertIn('It is deprecated to return a value that is not None', str(w.warning)) + self.assertIn('test3', str(w.warning)) + self.assertEqual(w.filename, __file__) def test_cleanups_interleave_order(self): events = [] @@ -317,6 +393,36 @@ class TestAsyncCase(unittest.TestCase): output = test.run() self.assertTrue(cancelled) + def test_enterAsyncContext(self): + events = [] + + class Test(unittest.IsolatedAsyncioTestCase): + async def test_func(slf): + slf.addAsyncCleanup(events.append, 'cleanup1') + cm = TestCM(events, 42) + self.assertEqual(await slf.enterAsyncContext(cm), 42) + slf.addAsyncCleanup(events.append, 'cleanup2') + events.append('test') + + test = Test('test_func') + output = test.run() + self.assertTrue(output.wasSuccessful(), output) + self.assertEqual(events, ['enter', 'test', 'cleanup2', 'exit', 'cleanup1']) + + def test_enterAsyncContext_arg_errors(self): + class Test(unittest.IsolatedAsyncioTestCase): + async def test_func(slf): + with self.assertRaisesRegex(TypeError, 'asynchronous context manager'): + await slf.enterAsyncContext(LacksEnterAndExit()) + with self.assertRaisesRegex(TypeError, 'asynchronous context manager'): + await slf.enterAsyncContext(LacksEnter()) + with self.assertRaisesRegex(TypeError, 'asynchronous context manager'): + await slf.enterAsyncContext(LacksExit()) + + test = Test('test_func') + output = test.run() + self.assertTrue(output.wasSuccessful()) + def test_debug_cleanup_same_loop(self): class Test(unittest.IsolatedAsyncioTestCase): async def asyncSetUp(self): @@ -351,6 +457,7 @@ class TestAsyncCase(unittest.TestCase): events = [] test = Test("test_func") + self.addCleanup(test._tearDownAsyncioRunner) try: test.debug() except MyException: @@ -361,6 +468,21 @@ class TestAsyncCase(unittest.TestCase): test.doCleanups() self.assertEqual(events, ['asyncSetUp', 'test', 'cleanup']) + def test_setup_get_event_loop(self): + # See https://github.com/python/cpython/issues/95736 + # Make sure the default event loop is not used + asyncio.set_event_loop(None) + + class TestCase1(unittest.IsolatedAsyncioTestCase): + def setUp(self): + asyncio.get_event_loop_policy().get_event_loop() + + async def test_demo1(self): + pass + + test = TestCase1('test_demo1') + result = test.run() + self.assertTrue(result.wasSuccessful()) if __name__ == "__main__": unittest.main() diff --git a/Lib/unittest/test/test_break.py b/Lib/test/test_unittest/test_break.py similarity index 68% rename from Lib/unittest/test/test_break.py rename to Lib/test/test_unittest/test_break.py index eebd2b610ce..33cbdd2661c 100644 --- a/Lib/unittest/test/test_break.py +++ b/Lib/test/test_unittest/test_break.py @@ -4,14 +4,18 @@ import os import sys import signal import weakref - import unittest +from test import support + @unittest.skipUnless(hasattr(os, 'kill'), "Test requires os.kill") @unittest.skipIf(sys.platform =="win32", "Test cannot run on Windows") class TestBreak(unittest.TestCase): int_handler = None + # This number was smart-guessed, previously tests were failing + # after 7th run. So, we take `x * 2 + 1` to be sure. + default_repeats = 15 def setUp(self): self._default_handler = signal.getsignal(signal.SIGINT) @@ -24,6 +28,27 @@ class TestBreak(unittest.TestCase): unittest.signals._interrupt_handler = None + def withRepeats(self, test_function, repeats=None): + if not support.check_impl_detail(cpython=True): + # Override repeats count on non-cpython to execute only once. + # Because this test only makes sense to be repeated on CPython. + repeats = 1 + elif repeats is None: + repeats = self.default_repeats + + for repeat in range(repeats): + with self.subTest(repeat=repeat): + # We don't run `setUp` for the very first repeat + # and we don't run `tearDown` for the very last one, + # because they are handled by the test class itself. + if repeat != 0: + self.setUp() + try: + test_function() + finally: + if repeat != repeats - 1: + self.tearDown() + def testInstallHandler(self): default_handler = signal.getsignal(signal.SIGINT) unittest.installHandler() @@ -48,35 +73,34 @@ class TestBreak(unittest.TestCase): unittest.removeResult(result) def testInterruptCaught(self): - default_handler = signal.getsignal(signal.SIGINT) - - result = unittest.TestResult() - unittest.installHandler() - unittest.registerResult(result) - - self.assertNotEqual(signal.getsignal(signal.SIGINT), default_handler) - def test(result): pid = os.getpid() os.kill(pid, signal.SIGINT) result.breakCaught = True self.assertTrue(result.shouldStop) - try: - test(result) - except KeyboardInterrupt: - self.fail("KeyboardInterrupt not handled") - self.assertTrue(result.breakCaught) + def test_function(): + result = unittest.TestResult() + unittest.installHandler() + unittest.registerResult(result) + self.assertNotEqual( + signal.getsignal(signal.SIGINT), + self._default_handler, + ) + + try: + test(result) + except KeyboardInterrupt: + self.fail("KeyboardInterrupt not handled") + self.assertTrue(result.breakCaught) + self.withRepeats(test_function) def testSecondInterrupt(self): # Can't use skipIf decorator because the signal handler may have # been changed after defining this method. if signal.getsignal(signal.SIGINT) == signal.SIG_IGN: self.skipTest("test requires SIGINT to not be ignored") - result = unittest.TestResult() - unittest.installHandler() - unittest.registerResult(result) def test(result): pid = os.getpid() @@ -86,40 +110,40 @@ class TestBreak(unittest.TestCase): os.kill(pid, signal.SIGINT) self.fail("Second KeyboardInterrupt not raised") - try: - test(result) - except KeyboardInterrupt: - pass - else: - self.fail("Second KeyboardInterrupt not raised") - self.assertTrue(result.breakCaught) + def test_function(): + result = unittest.TestResult() + unittest.installHandler() + unittest.registerResult(result) + + with self.assertRaises(KeyboardInterrupt): + test(result) + self.assertTrue(result.breakCaught) + self.withRepeats(test_function) def testTwoResults(self): - unittest.installHandler() + def test_function(): + unittest.installHandler() - result = unittest.TestResult() - unittest.registerResult(result) - new_handler = signal.getsignal(signal.SIGINT) + result = unittest.TestResult() + unittest.registerResult(result) + new_handler = signal.getsignal(signal.SIGINT) - result2 = unittest.TestResult() - unittest.registerResult(result2) - self.assertEqual(signal.getsignal(signal.SIGINT), new_handler) + result2 = unittest.TestResult() + unittest.registerResult(result2) + self.assertEqual(signal.getsignal(signal.SIGINT), new_handler) - result3 = unittest.TestResult() + result3 = unittest.TestResult() - def test(result): - pid = os.getpid() - os.kill(pid, signal.SIGINT) + try: + os.kill(os.getpid(), signal.SIGINT) + except KeyboardInterrupt: + self.fail("KeyboardInterrupt not handled") - try: - test(result) - except KeyboardInterrupt: - self.fail("KeyboardInterrupt not handled") - - self.assertTrue(result.shouldStop) - self.assertTrue(result2.shouldStop) - self.assertFalse(result3.shouldStop) + self.assertTrue(result.shouldStop) + self.assertTrue(result2.shouldStop) + self.assertFalse(result3.shouldStop) + self.withRepeats(test_function) def testHandlerReplacedButCalled(self): @@ -127,23 +151,25 @@ class TestBreak(unittest.TestCase): # been changed after defining this method. if signal.getsignal(signal.SIGINT) == signal.SIG_IGN: self.skipTest("test requires SIGINT to not be ignored") - # If our handler has been replaced (is no longer installed) but is - # called by the *new* handler, then it isn't safe to delay the - # SIGINT and we should immediately delegate to the default handler - unittest.installHandler() - handler = signal.getsignal(signal.SIGINT) - def new_handler(frame, signum): - handler(frame, signum) - signal.signal(signal.SIGINT, new_handler) + def test_function(): + # If our handler has been replaced (is no longer installed) but is + # called by the *new* handler, then it isn't safe to delay the + # SIGINT and we should immediately delegate to the default handler + unittest.installHandler() - try: - pid = os.getpid() - os.kill(pid, signal.SIGINT) - except KeyboardInterrupt: - pass - else: - self.fail("replaced but delegated handler doesn't raise interrupt") + handler = signal.getsignal(signal.SIGINT) + def new_handler(frame, signum): + handler(frame, signum) + signal.signal(signal.SIGINT, new_handler) + + try: + os.kill(os.getpid(), signal.SIGINT) + except KeyboardInterrupt: + pass + else: + self.fail("replaced but delegated handler doesn't raise interrupt") + self.withRepeats(test_function) def testRunner(self): # Creating a TextTestRunner with the appropriate argument should diff --git a/Lib/unittest/test/test_case.py b/Lib/test/test_unittest/test_case.py similarity index 98% rename from Lib/unittest/test/test_case.py rename to Lib/test/test_unittest/test_case.py index ee4c0b354f7..05d60a8ad3c 100644 --- a/Lib/unittest/test/test_case.py +++ b/Lib/test/test_unittest/test_case.py @@ -15,7 +15,7 @@ from test import support import unittest -from unittest.test.support import ( +from test.test_unittest.support import ( TestEquality, TestHashing, LoggingResult, LegacyLoggingResult, ResultWithNoStartTestRunStopTestRun ) @@ -307,24 +307,35 @@ class Test_TestCase(unittest.TestCase, TestEquality, TestHashing): Foo('test').run() def test_deprecation_of_return_val_from_test(self): - # Issue 41322 - deprecate return of value!=None from a test + # Issue 41322 - deprecate return of value that is not None from a test + class Nothing: + def __eq__(self, o): + return o is None class Foo(unittest.TestCase): def test1(self): return 1 def test2(self): yield 1 + def test3(self): + return Nothing() with self.assertWarns(DeprecationWarning) as w: Foo('test1').run() - self.assertIn('It is deprecated to return a value!=None', str(w.warnings[0].message)) - self.assertIn('test1', str(w.warnings[0].message)) - self.assertEqual(w.warnings[0].filename, __file__) + self.assertIn('It is deprecated to return a value that is not None', str(w.warning)) + self.assertIn('test1', str(w.warning)) + self.assertEqual(w.filename, __file__) with self.assertWarns(DeprecationWarning) as w: Foo('test2').run() - self.assertIn('It is deprecated to return a value!=None', str(w.warnings[0].message)) - self.assertIn('test2', str(w.warnings[0].message)) - self.assertEqual(w.warnings[0].filename, __file__) + self.assertIn('It is deprecated to return a value that is not None', str(w.warning)) + self.assertIn('test2', str(w.warning)) + self.assertEqual(w.filename, __file__) + + with self.assertWarns(DeprecationWarning) as w: + Foo('test3').run() + self.assertIn('It is deprecated to return a value that is not None', str(w.warning)) + self.assertIn('test3', str(w.warning)) + self.assertEqual(w.filename, __file__) def _check_call_order__subtests(self, result, events, expected_events): class Foo(Test.LoggingTestCase): @@ -631,6 +642,8 @@ class Test_TestCase(unittest.TestCase, TestEquality, TestHashing): 'Tests shortDescription() for a method with a longer ' 'docstring.') + @unittest.skipIf(sys.flags.optimize >= 2, + "Docstrings are omitted with -O2 and above") def testShortDescriptionWhitespaceTrimming(self): """ Tests shortDescription() whitespace is trimmed, so that the first @@ -1759,7 +1772,7 @@ test case self.assertIsNone(value) def testDeprecatedFailMethods(self): - """Test that the deprecated fail* methods get removed in 3.11""" + """Test that the deprecated fail* methods get removed in 3.12""" deprecated_names = [ 'failIfEqual', 'failUnlessEqual', 'failUnlessAlmostEqual', 'failIfAlmostEqual', 'failUnless', 'failUnlessRaises', 'failIf', diff --git a/Lib/unittest/test/test_discovery.py b/Lib/test/test_unittest/test_discovery.py similarity index 95% rename from Lib/unittest/test/test_discovery.py rename to Lib/test/test_unittest/test_discovery.py index 9d502c51fb3..946fa1258ea 100644 --- a/Lib/unittest/test/test_discovery.py +++ b/Lib/test/test_unittest/test_discovery.py @@ -10,7 +10,7 @@ import test.test_importlib.util import unittest import unittest.mock -import unittest.test +import test.test_unittest class TestableTestProgram(unittest.TestProgram): @@ -396,7 +396,7 @@ class TestDiscovery(unittest.TestCase): self.addCleanup(restore_isdir) _find_tests_args = [] - def _find_tests(start_dir, pattern, namespace=None): + def _find_tests(start_dir, pattern): _find_tests_args.append((start_dir, pattern)) return ['tests'] loader._find_tests = _find_tests @@ -789,15 +789,15 @@ class TestDiscovery(unittest.TestCase): loader = unittest.TestLoader() tests = [self] - expectedPath = os.path.abspath(os.path.dirname(unittest.test.__file__)) + expectedPath = os.path.abspath(os.path.dirname(test.test_unittest.__file__)) self.wasRun = False - def _find_tests(start_dir, pattern, namespace=None): + def _find_tests(start_dir, pattern): self.wasRun = True self.assertEqual(start_dir, expectedPath) return tests loader._find_tests = _find_tests - suite = loader.discover('unittest.test') + suite = loader.discover('test.test_unittest') self.assertTrue(self.wasRun) self.assertEqual(suite._tests, tests) @@ -825,37 +825,6 @@ class TestDiscovery(unittest.TestCase): 'Can not use builtin modules ' 'as dotted module names') - def test_discovery_from_dotted_namespace_packages(self): - loader = unittest.TestLoader() - - package = types.ModuleType('package') - package.__path__ = ['/a', '/b'] - package.__spec__ = types.SimpleNamespace( - loader=None, - submodule_search_locations=['/a', '/b'] - ) - - def _import(packagename, *args, **kwargs): - sys.modules[packagename] = package - return package - - _find_tests_args = [] - def _find_tests(start_dir, pattern, namespace=None): - _find_tests_args.append((start_dir, pattern)) - return ['%s/tests' % start_dir] - - loader._find_tests = _find_tests - loader.suiteClass = list - - with unittest.mock.patch('builtins.__import__', _import): - # Since loader.discover() can modify sys.path, restore it when done. - with import_helper.DirsOnSysPath(): - # Make sure to remove 'package' from sys.modules when done. - with test.test_importlib.util.uncache('package'): - suite = loader.discover('package') - - self.assertEqual(suite, ['/a/tests', '/b/tests']) - def test_discovery_failed_discovery(self): loader = unittest.TestLoader() package = types.ModuleType('package') diff --git a/Lib/unittest/test/test_functiontestcase.py b/Lib/test/test_unittest/test_functiontestcase.py similarity index 99% rename from Lib/unittest/test/test_functiontestcase.py rename to Lib/test/test_unittest/test_functiontestcase.py index 4971729880d..2ebed9564ad 100644 --- a/Lib/unittest/test/test_functiontestcase.py +++ b/Lib/test/test_unittest/test_functiontestcase.py @@ -1,6 +1,6 @@ import unittest -from unittest.test.support import LoggingResult +from test.test_unittest.support import LoggingResult class Test_FunctionTestCase(unittest.TestCase): diff --git a/Lib/unittest/test/test_loader.py b/Lib/test/test_unittest/test_loader.py similarity index 99% rename from Lib/unittest/test/test_loader.py rename to Lib/test/test_unittest/test_loader.py index fc0d46ee8d0..bbdfb247eba 100644 --- a/Lib/unittest/test/test_loader.py +++ b/Lib/test/test_unittest/test_loader.py @@ -176,7 +176,7 @@ class Test_TestLoader(unittest.TestCase): self.assertIsInstance(suite, unittest.TestSuite) self.assertEqual(load_tests_args, [loader, suite, None]) - # In Python 3.11, the undocumented and unofficial use_load_tests has + # In Python 3.12, the undocumented and unofficial use_load_tests has # been removed. with self.assertRaises(TypeError): loader.loadTestsFromModule(m, False) @@ -583,7 +583,7 @@ class Test_TestLoader(unittest.TestCase): # We're going to try to load this module as a side-effect, so it # better not be loaded before we try. # - module_name = 'unittest.test.dummy' + module_name = 'test.test_unittest.dummy' sys.modules.pop(module_name, None) loader = unittest.TestLoader() @@ -711,7 +711,7 @@ class Test_TestLoader(unittest.TestCase): loader = unittest.TestLoader() suite = loader.loadTestsFromNames( - ['unittest.loader.sdasfasfasdf', 'unittest.test.dummy']) + ['unittest.loader.sdasfasfasdf', 'test.test_unittest.dummy']) error, test = self.check_deferred_error(loader, list(suite)[0]) expected = "module 'unittest.loader' has no attribute 'sdasfasfasdf'" self.assertIn( @@ -1008,7 +1008,7 @@ class Test_TestLoader(unittest.TestCase): # We're going to try to load this module as a side-effect, so it # better not be loaded before we try. # - module_name = 'unittest.test.dummy' + module_name = 'test.test_unittest.dummy' sys.modules.pop(module_name, None) loader = unittest.TestLoader() @@ -1476,7 +1476,7 @@ class TestObsoleteFunctions(unittest.TestCase): tests = unittest.getTestCaseNames(self.MyTestCase, prefix='check', sortUsing=self.reverse_three_way_cmp, testNamePatterns=None) - self.assertEqual(w.warnings[0].filename, __file__) + self.assertEqual(w.filename, __file__) self.assertEqual(tests, ['check_2', 'check_1']) def test_makeSuite(self): @@ -1484,7 +1484,7 @@ class TestObsoleteFunctions(unittest.TestCase): suite = unittest.makeSuite(self.MyTestCase, prefix='check', sortUsing=self.reverse_three_way_cmp, suiteClass=self.MyTestSuite) - self.assertEqual(w.warnings[0].filename, __file__) + self.assertEqual(w.filename, __file__) self.assertIsInstance(suite, self.MyTestSuite) expected = self.MyTestSuite([self.MyTestCase('check_2'), self.MyTestCase('check_1')]) @@ -1498,7 +1498,7 @@ class TestObsoleteFunctions(unittest.TestCase): suite = unittest.findTestCases(m, prefix='check', sortUsing=self.reverse_three_way_cmp, suiteClass=self.MyTestSuite) - self.assertEqual(w.warnings[0].filename, __file__) + self.assertEqual(w.filename, __file__) self.assertIsInstance(suite, self.MyTestSuite) expected = [self.MyTestSuite([self.MyTestCase('check_2'), self.MyTestCase('check_1')])] diff --git a/Lib/unittest/test/test_program.py b/Lib/test/test_unittest/test_program.py similarity index 85% rename from Lib/unittest/test/test_program.py rename to Lib/test/test_unittest/test_program.py index 93a61097e93..3645bcf4b43 100644 --- a/Lib/unittest/test/test_program.py +++ b/Lib/test/test_unittest/test_program.py @@ -1,11 +1,10 @@ -import io - import os import sys import subprocess from test import support import unittest -import unittest.test +import test.test_unittest +from test.test_unittest.test_result import BufferedWriter class Test_TestProgram(unittest.TestCase): @@ -14,7 +13,7 @@ class Test_TestProgram(unittest.TestCase): loader = unittest.TestLoader() tests = [self] - expectedPath = os.path.abspath(os.path.dirname(unittest.test.__file__)) + expectedPath = os.path.abspath(os.path.dirname(test.test_unittest.__file__)) self.wasRun = False def _find_tests(start_dir, pattern): @@ -22,7 +21,7 @@ class Test_TestProgram(unittest.TestCase): self.assertEqual(start_dir, expectedPath) return tests loader._find_tests = _find_tests - suite = loader.discover('unittest.test') + suite = loader.discover('test.test_unittest') self.assertTrue(self.wasRun) self.assertEqual(suite._tests, tests) @@ -57,9 +56,20 @@ class Test_TestProgram(unittest.TestCase): class FooBar(unittest.TestCase): def testPass(self): - assert True + pass def testFail(self): - assert False + raise AssertionError + def testError(self): + 1/0 + @unittest.skip('skipping') + def testSkipped(self): + raise AssertionError + @unittest.expectedFailure + def testExpectedFailure(self): + raise AssertionError + @unittest.expectedFailure + def testUnexpectedSuccess(self): + pass class FooBarLoader(unittest.TestLoader): """Test loader that returns a suite containing FooBar.""" @@ -81,10 +91,10 @@ class Test_TestProgram(unittest.TestCase): sys.argv = ['faketest'] runner = FakeRunner() program = unittest.TestProgram(testRunner=runner, exit=False, - defaultTest='unittest.test', + defaultTest='test.test_unittest', testLoader=self.FooBarLoader()) sys.argv = old_argv - self.assertEqual(('unittest.test',), program.testNames) + self.assertEqual(('test.test_unittest',), program.testNames) def test_defaultTest_with_iterable(self): class FakeRunner(object): @@ -97,37 +107,59 @@ class Test_TestProgram(unittest.TestCase): runner = FakeRunner() program = unittest.TestProgram( testRunner=runner, exit=False, - defaultTest=['unittest.test', 'unittest.test2'], + defaultTest=['test.test_unittest', 'test.test_unittest2'], testLoader=self.FooBarLoader()) sys.argv = old_argv - self.assertEqual(['unittest.test', 'unittest.test2'], + self.assertEqual(['test.test_unittest', 'test.test_unittest2'], program.testNames) def test_NonExit(self): + stream = BufferedWriter() program = unittest.main(exit=False, argv=["foobar"], - testRunner=unittest.TextTestRunner(stream=io.StringIO()), + testRunner=unittest.TextTestRunner(stream=stream), testLoader=self.FooBarLoader()) self.assertTrue(hasattr(program, 'result')) - + out = stream.getvalue() + self.assertIn('\nFAIL: testFail ', out) + self.assertIn('\nERROR: testError ', out) + self.assertIn('\nUNEXPECTED SUCCESS: testUnexpectedSuccess ', out) + expected = ('\n\nFAILED (failures=1, errors=1, skipped=1, ' + 'expected failures=1, unexpected successes=1)\n') + self.assertTrue(out.endswith(expected)) def test_Exit(self): + stream = BufferedWriter() self.assertRaises( SystemExit, unittest.main, argv=["foobar"], - testRunner=unittest.TextTestRunner(stream=io.StringIO()), + testRunner=unittest.TextTestRunner(stream=stream), exit=True, testLoader=self.FooBarLoader()) - + out = stream.getvalue() + self.assertIn('\nFAIL: testFail ', out) + self.assertIn('\nERROR: testError ', out) + self.assertIn('\nUNEXPECTED SUCCESS: testUnexpectedSuccess ', out) + expected = ('\n\nFAILED (failures=1, errors=1, skipped=1, ' + 'expected failures=1, unexpected successes=1)\n') + self.assertTrue(out.endswith(expected)) def test_ExitAsDefault(self): + stream = BufferedWriter() self.assertRaises( SystemExit, unittest.main, argv=["foobar"], - testRunner=unittest.TextTestRunner(stream=io.StringIO()), + testRunner=unittest.TextTestRunner(stream=stream), testLoader=self.FooBarLoader()) + out = stream.getvalue() + self.assertIn('\nFAIL: testFail ', out) + self.assertIn('\nERROR: testError ', out) + self.assertIn('\nUNEXPECTED SUCCESS: testUnexpectedSuccess ', out) + expected = ('\n\nFAILED (failures=1, errors=1, skipped=1, ' + 'expected failures=1, unexpected successes=1)\n') + self.assertTrue(out.endswith(expected)) class InitialisableProgram(unittest.TestProgram): @@ -162,6 +194,7 @@ class FakeRunner(object): return RESULT +@support.requires_subprocess() class TestCommandLineArgs(unittest.TestCase): def setUp(self): @@ -419,7 +452,9 @@ class TestCommandLineArgs(unittest.TestCase): def testSelectedTestNamesFunctionalTest(self): def run_unittest(args): - p = subprocess.Popen([sys.executable, '-m', 'unittest'] + args, + # Use -E to ignore PYTHONSAFEPATH env var + cmd = [sys.executable, '-E', '-m', 'unittest'] + args + p = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, cwd=os.path.dirname(__file__)) with p: _, stderr = p.communicate() diff --git a/Lib/unittest/test/test_result.py b/Lib/test/test_unittest/test_result.py similarity index 85% rename from Lib/unittest/test/test_result.py rename to Lib/test/test_unittest/test_result.py index c4a49b48752..efd9c902350 100644 --- a/Lib/unittest/test/test_result.py +++ b/Lib/test/test_unittest/test_result.py @@ -2,7 +2,7 @@ import io import sys import textwrap -from test.support import warnings_helper, captured_stdout, captured_stderr +from test.support import warnings_helper, captured_stdout import traceback import unittest @@ -33,6 +33,22 @@ def bad_cleanup2(): raise ValueError('bad cleanup2') +class BufferedWriter: + def __init__(self): + self.result = '' + self.buffer = '' + + def write(self, arg): + self.buffer += arg + + def flush(self): + self.result += self.buffer + self.buffer = '' + + def getvalue(self): + return self.result + + class Test_TestResult(unittest.TestCase): # Note: there are not separate tests for TestResult.wasSuccessful(), # TestResult.errors, TestResult.failures, TestResult.testsRun or @@ -204,6 +220,117 @@ class Test_TestResult(unittest.TestCase): self.assertIs(test_case, test) self.assertIsInstance(formatted_exc, str) + def test_addFailure_filter_traceback_frames(self): + class Foo(unittest.TestCase): + def test_1(self): + pass + + test = Foo('test_1') + def get_exc_info(): + try: + test.fail("foo") + except: + return sys.exc_info() + + exc_info_tuple = get_exc_info() + + full_exc = traceback.format_exception(*exc_info_tuple) + + result = unittest.TestResult() + result.startTest(test) + result.addFailure(test, exc_info_tuple) + result.stopTest(test) + + formatted_exc = result.failures[0][1] + dropped = [l for l in full_exc if l not in formatted_exc] + self.assertEqual(len(dropped), 1) + self.assertIn("raise self.failureException(msg)", dropped[0]) + + def test_addFailure_filter_traceback_frames_context(self): + class Foo(unittest.TestCase): + def test_1(self): + pass + + test = Foo('test_1') + def get_exc_info(): + try: + try: + test.fail("foo") + except: + raise ValueError(42) + except: + return sys.exc_info() + + exc_info_tuple = get_exc_info() + + full_exc = traceback.format_exception(*exc_info_tuple) + + result = unittest.TestResult() + result.startTest(test) + result.addFailure(test, exc_info_tuple) + result.stopTest(test) + + formatted_exc = result.failures[0][1] + dropped = [l for l in full_exc if l not in formatted_exc] + self.assertEqual(len(dropped), 1) + self.assertIn("raise self.failureException(msg)", dropped[0]) + + def test_addFailure_filter_traceback_frames_chained_exception_self_loop(self): + class Foo(unittest.TestCase): + def test_1(self): + pass + + def get_exc_info(): + try: + loop = Exception("Loop") + loop.__cause__ = loop + loop.__context__ = loop + raise loop + except: + return sys.exc_info() + + exc_info_tuple = get_exc_info() + + test = Foo('test_1') + result = unittest.TestResult() + result.startTest(test) + result.addFailure(test, exc_info_tuple) + result.stopTest(test) + + formatted_exc = result.failures[0][1] + self.assertEqual(formatted_exc.count("Exception: Loop\n"), 1) + + def test_addFailure_filter_traceback_frames_chained_exception_cycle(self): + class Foo(unittest.TestCase): + def test_1(self): + pass + + def get_exc_info(): + try: + # Create two directionally opposed cycles + # __cause__ in one direction, __context__ in the other + A, B, C = Exception("A"), Exception("B"), Exception("C") + edges = [(C, B), (B, A), (A, C)] + for ex1, ex2 in edges: + ex1.__cause__ = ex2 + ex2.__context__ = ex1 + raise C + except: + return sys.exc_info() + + exc_info_tuple = get_exc_info() + + test = Foo('test_1') + result = unittest.TestResult() + result.startTest(test) + result.addFailure(test, exc_info_tuple) + result.stopTest(test) + + formatted_exc = result.failures[0][1] + self.assertEqual(formatted_exc.count("Exception: A\n"), 1) + self.assertEqual(formatted_exc.count("Exception: B\n"), 1) + self.assertEqual(formatted_exc.count("Exception: C\n"), 1) + # "addError(test, err)" # ... # "Called when the test case test raises an unexpected exception err @@ -335,10 +462,13 @@ class Test_TestResult(unittest.TestCase): self.assertTrue(result.shouldStop) def testFailFastSetByRunner(self): - runner = unittest.TextTestRunner(stream=io.StringIO(), failfast=True) + stream = BufferedWriter() + runner = unittest.TextTestRunner(stream=stream, failfast=True) def test(result): self.assertTrue(result.failfast) result = runner.run(test) + stream.flush() + self.assertTrue(stream.getvalue().endswith('\n\nOK\n')) class Test_TextTestResult(unittest.TestCase): @@ -349,7 +479,7 @@ class Test_TextTestResult(unittest.TestCase): self.assertEqual( result.getDescription(self), 'testGetDescriptionWithoutDocstring (' + __name__ + - '.Test_TextTestResult)') + '.Test_TextTestResult.testGetDescriptionWithoutDocstring)') def testGetSubTestDescriptionWithoutDocstring(self): with self.subTest(foo=1, bar=2): @@ -357,13 +487,14 @@ class Test_TextTestResult(unittest.TestCase): self.assertEqual( result.getDescription(self._subtest), 'testGetSubTestDescriptionWithoutDocstring (' + __name__ + - '.Test_TextTestResult) (foo=1, bar=2)') + '.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstring) (foo=1, bar=2)') + with self.subTest('some message'): result = unittest.TextTestResult(None, True, 1) self.assertEqual( result.getDescription(self._subtest), 'testGetSubTestDescriptionWithoutDocstring (' + __name__ + - '.Test_TextTestResult) [some message]') + '.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstring) [some message]') def testGetSubTestDescriptionWithoutDocstringAndParams(self): with self.subTest(): @@ -371,10 +502,11 @@ class Test_TextTestResult(unittest.TestCase): self.assertEqual( result.getDescription(self._subtest), 'testGetSubTestDescriptionWithoutDocstringAndParams ' - '(' + __name__ + '.Test_TextTestResult) ()') + '(' + __name__ + '.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstringAndParams) ' + '()') - def testGetSubTestDescriptionForFalsyValues(self): - expected = 'testGetSubTestDescriptionForFalsyValues (%s.Test_TextTestResult) [%s]' + def testGetSubTestDescriptionForFalseValues(self): + expected = 'testGetSubTestDescriptionForFalseValues (%s.Test_TextTestResult.testGetSubTestDescriptionForFalseValues) [%s]' result = unittest.TextTestResult(None, True, 1) for arg in [0, None, []]: with self.subTest(arg): @@ -390,7 +522,8 @@ class Test_TextTestResult(unittest.TestCase): self.assertEqual( result.getDescription(self._subtest), 'testGetNestedSubTestDescriptionWithoutDocstring ' - '(' + __name__ + '.Test_TextTestResult) (baz=2, bar=3, foo=1)') + '(' + __name__ + '.Test_TextTestResult.testGetNestedSubTestDescriptionWithoutDocstring) ' + '(baz=2, bar=3, foo=1)') def testGetDuplicatedNestedSubTestDescriptionWithoutDocstring(self): with self.subTest(foo=1, bar=2): @@ -399,7 +532,7 @@ class Test_TextTestResult(unittest.TestCase): self.assertEqual( result.getDescription(self._subtest), 'testGetDuplicatedNestedSubTestDescriptionWithoutDocstring ' - '(' + __name__ + '.Test_TextTestResult) (baz=3, bar=4, foo=1)') + '(' + __name__ + '.Test_TextTestResult.testGetDuplicatedNestedSubTestDescriptionWithoutDocstring) (baz=3, bar=4, foo=1)') @unittest.skipIf(sys.flags.optimize >= 2, "Docstrings are omitted with -O2 and above") @@ -409,7 +542,7 @@ class Test_TextTestResult(unittest.TestCase): self.assertEqual( result.getDescription(self), ('testGetDescriptionWithOneLineDocstring ' - '(' + __name__ + '.Test_TextTestResult)\n' + '(' + __name__ + '.Test_TextTestResult.testGetDescriptionWithOneLineDocstring)\n' 'Tests getDescription() for a method with a docstring.')) @unittest.skipIf(sys.flags.optimize >= 2, @@ -421,7 +554,9 @@ class Test_TextTestResult(unittest.TestCase): self.assertEqual( result.getDescription(self._subtest), ('testGetSubTestDescriptionWithOneLineDocstring ' - '(' + __name__ + '.Test_TextTestResult) (foo=1, bar=2)\n' + '(' + __name__ + '.Test_TextTestResult.testGetSubTestDescriptionWithOneLineDocstring) ' + '(foo=1, bar=2)\n' + 'Tests getDescription() for a method with a docstring.')) @unittest.skipIf(sys.flags.optimize >= 2, @@ -434,7 +569,7 @@ class Test_TextTestResult(unittest.TestCase): self.assertEqual( result.getDescription(self), ('testGetDescriptionWithMultiLineDocstring ' - '(' + __name__ + '.Test_TextTestResult)\n' + '(' + __name__ + '.Test_TextTestResult.testGetDescriptionWithMultiLineDocstring)\n' 'Tests getDescription() for a method with a longer ' 'docstring.')) @@ -449,7 +584,8 @@ class Test_TextTestResult(unittest.TestCase): self.assertEqual( result.getDescription(self._subtest), ('testGetSubTestDescriptionWithMultiLineDocstring ' - '(' + __name__ + '.Test_TextTestResult) (foo=1, bar=2)\n' + '(' + __name__ + '.Test_TextTestResult.testGetSubTestDescriptionWithMultiLineDocstring) ' + '(foo=1, bar=2)\n' 'Tests getDescription() for a method with a longer ' 'docstring.')) @@ -462,6 +598,12 @@ class Test_TextTestResult(unittest.TestCase): self.fail('fail') def testError(self): raise Exception('error') + @unittest.expectedFailure + def testExpectedFailure(self): + self.fail('fail') + @unittest.expectedFailure + def testUnexpectedSuccess(self): + pass def testSubTestSuccess(self): with self.subTest('one', a=1): pass @@ -483,7 +625,7 @@ class Test_TextTestResult(unittest.TestCase): raise self.tearDownError def _run_test(self, test_name, verbosity, tearDownError=None): - stream = io.StringIO() + stream = BufferedWriter() stream = unittest.runner._WritelnDecorator(stream) result = unittest.TextTestResult(stream, True, verbosity) test = self.Test(test_name) @@ -496,17 +638,23 @@ class Test_TextTestResult(unittest.TestCase): self.assertEqual(self._run_test('testSkip', 1), 's') self.assertEqual(self._run_test('testFail', 1), 'F') self.assertEqual(self._run_test('testError', 1), 'E') + self.assertEqual(self._run_test('testExpectedFailure', 1), 'x') + self.assertEqual(self._run_test('testUnexpectedSuccess', 1), 'u') def testLongOutput(self): classname = f'{__name__}.{self.Test.__qualname__}' self.assertEqual(self._run_test('testSuccess', 2), - f'testSuccess ({classname}) ... ok\n') + f'testSuccess ({classname}.testSuccess) ... ok\n') self.assertEqual(self._run_test('testSkip', 2), - f"testSkip ({classname}) ... skipped 'skip'\n") + f"testSkip ({classname}.testSkip) ... skipped 'skip'\n") self.assertEqual(self._run_test('testFail', 2), - f'testFail ({classname}) ... FAIL\n') + f'testFail ({classname}.testFail) ... FAIL\n') self.assertEqual(self._run_test('testError', 2), - f'testError ({classname}) ... ERROR\n') + f'testError ({classname}.testError) ... ERROR\n') + self.assertEqual(self._run_test('testExpectedFailure', 2), + f'testExpectedFailure ({classname}.testExpectedFailure) ... expected failure\n') + self.assertEqual(self._run_test('testUnexpectedSuccess', 2), + f'testUnexpectedSuccess ({classname}.testUnexpectedSuccess) ... unexpected success\n') def testDotsOutputSubTestSuccess(self): self.assertEqual(self._run_test('testSubTestSuccess', 1), '.') @@ -514,7 +662,7 @@ class Test_TextTestResult(unittest.TestCase): def testLongOutputSubTestSuccess(self): classname = f'{__name__}.{self.Test.__qualname__}' self.assertEqual(self._run_test('testSubTestSuccess', 2), - f'testSubTestSuccess ({classname}) ... ok\n') + f'testSubTestSuccess ({classname}.testSubTestSuccess) ... ok\n') def testDotsOutputSubTestMixed(self): self.assertEqual(self._run_test('testSubTestMixed', 1), 'sFE') @@ -522,10 +670,10 @@ class Test_TextTestResult(unittest.TestCase): def testLongOutputSubTestMixed(self): classname = f'{__name__}.{self.Test.__qualname__}' self.assertEqual(self._run_test('testSubTestMixed', 2), - f'testSubTestMixed ({classname}) ... \n' - f" testSubTestMixed ({classname}) [skip] (b=2) ... skipped 'skip'\n" - f' testSubTestMixed ({classname}) [fail] (c=3) ... FAIL\n' - f' testSubTestMixed ({classname}) [error] (d=4) ... ERROR\n') + f'testSubTestMixed ({classname}.testSubTestMixed) ... \n' + f" testSubTestMixed ({classname}.testSubTestMixed) [skip] (b=2) ... skipped 'skip'\n" + f' testSubTestMixed ({classname}.testSubTestMixed) [fail] (c=3) ... FAIL\n' + f' testSubTestMixed ({classname}.testSubTestMixed) [error] (d=4) ... ERROR\n') def testDotsOutputTearDownFail(self): out = self._run_test('testSuccess', 1, AssertionError('fail')) @@ -541,19 +689,19 @@ class Test_TextTestResult(unittest.TestCase): classname = f'{__name__}.{self.Test.__qualname__}' out = self._run_test('testSuccess', 2, AssertionError('fail')) self.assertEqual(out, - f'testSuccess ({classname}) ... FAIL\n') + f'testSuccess ({classname}.testSuccess) ... FAIL\n') out = self._run_test('testError', 2, AssertionError('fail')) self.assertEqual(out, - f'testError ({classname}) ... ERROR\n' - f'testError ({classname}) ... FAIL\n') + f'testError ({classname}.testError) ... ERROR\n' + f'testError ({classname}.testError) ... FAIL\n') out = self._run_test('testFail', 2, Exception('error')) self.assertEqual(out, - f'testFail ({classname}) ... FAIL\n' - f'testFail ({classname}) ... ERROR\n') + f'testFail ({classname}.testFail) ... FAIL\n' + f'testFail ({classname}.testFail) ... ERROR\n') out = self._run_test('testSkip', 2, AssertionError('fail')) self.assertEqual(out, - f"testSkip ({classname}) ... skipped 'skip'\n" - f'testSkip ({classname}) ... FAIL\n') + f"testSkip ({classname}.testSkip) ... skipped 'skip'\n" + f'testSkip ({classname}.testSkip) ... FAIL\n') classDict = dict(unittest.TestResult.__dict__) @@ -766,7 +914,7 @@ class TestOutputBuffering(unittest.TestCase): expected_out = '\nStdout:\nset up\n' self.assertEqual(stdout.getvalue(), expected_out) self.assertEqual(len(result.errors), 1) - description = f'test_foo ({strclass(Foo)})' + description = f'test_foo ({strclass(Foo)}.test_foo)' test_case, formatted_exc = result.errors[0] self.assertEqual(str(test_case), description) self.assertIn('ZeroDivisionError: division by zero', formatted_exc) @@ -788,7 +936,7 @@ class TestOutputBuffering(unittest.TestCase): expected_out = '\nStdout:\ntear down\n' self.assertEqual(stdout.getvalue(), expected_out) self.assertEqual(len(result.errors), 1) - description = f'test_foo ({strclass(Foo)})' + description = f'test_foo ({strclass(Foo)}.test_foo)' test_case, formatted_exc = result.errors[0] self.assertEqual(str(test_case), description) self.assertIn('ZeroDivisionError: division by zero', formatted_exc) @@ -811,7 +959,7 @@ class TestOutputBuffering(unittest.TestCase): expected_out = '\nStdout:\nset up\ndo cleanup2\ndo cleanup1\n' self.assertEqual(stdout.getvalue(), expected_out) self.assertEqual(len(result.errors), 2) - description = f'test_foo ({strclass(Foo)})' + description = f'test_foo ({strclass(Foo)}.test_foo)' test_case, formatted_exc = result.errors[0] self.assertEqual(str(test_case), description) self.assertIn('ValueError: bad cleanup2', formatted_exc) @@ -842,7 +990,7 @@ class TestOutputBuffering(unittest.TestCase): expected_out = '\nStdout:\nset up\ndo cleanup2\ndo cleanup1\n' self.assertEqual(stdout.getvalue(), expected_out) self.assertEqual(len(result.errors), 3) - description = f'test_foo ({strclass(Foo)})' + description = f'test_foo ({strclass(Foo)}.test_foo)' test_case, formatted_exc = result.errors[0] self.assertEqual(str(test_case), description) self.assertIn('ZeroDivisionError: division by zero', formatted_exc) @@ -885,7 +1033,7 @@ class TestOutputBuffering(unittest.TestCase): expected_out = '\nStdout:\nset up\ntear down\ndo cleanup2\ndo cleanup1\n' self.assertEqual(stdout.getvalue(), expected_out) self.assertEqual(len(result.errors), 3) - description = f'test_foo ({strclass(Foo)})' + description = f'test_foo ({strclass(Foo)}.test_foo)' test_case, formatted_exc = result.errors[0] self.assertEqual(str(test_case), description) self.assertIn('ZeroDivisionError: division by zero', formatted_exc) diff --git a/Lib/unittest/test/test_runner.py b/Lib/test/test_unittest/test_runner.py similarity index 88% rename from Lib/unittest/test/test_runner.py rename to Lib/test/test_unittest/test_runner.py index bcf7538c26f..df584b7620d 100644 --- a/Lib/unittest/test/test_runner.py +++ b/Lib/test/test_unittest/test_runner.py @@ -3,11 +3,12 @@ import os import sys import pickle import subprocess +from test import support import unittest from unittest.case import _Outcome -from unittest.test.support import (LoggingResult, +from test.test_unittest.support import (LoggingResult, ResultWithNoStartTestRunStopTestRun) @@ -45,6 +46,29 @@ def cleanup(ordering, blowUp=False): raise Exception('CleanUpExc') +class TestCM: + def __init__(self, ordering, enter_result=None): + self.ordering = ordering + self.enter_result = enter_result + + def __enter__(self): + self.ordering.append('enter') + return self.enter_result + + def __exit__(self, *exc_info): + self.ordering.append('exit') + + +class LacksEnterAndExit: + pass +class LacksEnter: + def __exit__(self, *exc_info): + pass +class LacksExit: + def __enter__(self): + pass + + class TestCleanUp(unittest.TestCase): def testCleanUp(self): class TestableTest(unittest.TestCase): @@ -110,11 +134,13 @@ class TestCleanUp(unittest.TestCase): class TestableTest(unittest.TestCase): def setUp(self): ordering.append('setUp') + test.addCleanup(cleanup2) if blowUp: raise Exception('foo') def testNothing(self): ordering.append('test') + test.addCleanup(cleanup3) def tearDown(self): ordering.append('tearDown') @@ -125,8 +151,9 @@ class TestCleanUp(unittest.TestCase): ordering.append('cleanup1') def cleanup2(): ordering.append('cleanup2') + def cleanup3(): + ordering.append('cleanup3') test.addCleanup(cleanup1) - test.addCleanup(cleanup2) def success(some_test): self.assertEqual(some_test, test) @@ -136,7 +163,7 @@ class TestCleanUp(unittest.TestCase): result.addSuccess = success test.run(result) - self.assertEqual(ordering, ['setUp', 'test', 'tearDown', + self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup3', 'cleanup2', 'cleanup1', 'success']) blowUp = True @@ -144,7 +171,7 @@ class TestCleanUp(unittest.TestCase): test = TestableTest('testNothing') test.addCleanup(cleanup1) test.run(result) - self.assertEqual(ordering, ['setUp', 'cleanup1']) + self.assertEqual(ordering, ['setUp', 'cleanup2', 'cleanup1']) def testTestCaseDebugExecutesCleanups(self): ordering = [] @@ -156,9 +183,11 @@ class TestCleanUp(unittest.TestCase): def testNothing(self): ordering.append('test') + self.addCleanup(cleanup3) def tearDown(self): ordering.append('tearDown') + test.addCleanup(cleanup4) test = TestableTest('testNothing') @@ -167,9 +196,47 @@ class TestCleanUp(unittest.TestCase): test.addCleanup(cleanup2) def cleanup2(): ordering.append('cleanup2') + def cleanup3(): + ordering.append('cleanup3') + def cleanup4(): + ordering.append('cleanup4') test.debug() - self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup1', 'cleanup2']) + self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup4', + 'cleanup3', 'cleanup1', 'cleanup2']) + + + def test_enterContext(self): + class TestableTest(unittest.TestCase): + def testNothing(self): + pass + + test = TestableTest('testNothing') + cleanups = [] + + test.addCleanup(cleanups.append, 'cleanup1') + cm = TestCM(cleanups, 42) + self.assertEqual(test.enterContext(cm), 42) + test.addCleanup(cleanups.append, 'cleanup2') + + self.assertTrue(test.doCleanups()) + self.assertEqual(cleanups, ['enter', 'cleanup2', 'exit', 'cleanup1']) + + def test_enterContext_arg_errors(self): + class TestableTest(unittest.TestCase): + def testNothing(self): + pass + + test = TestableTest('testNothing') + + with self.assertRaisesRegex(TypeError, 'the context manager'): + test.enterContext(LacksEnterAndExit()) + with self.assertRaisesRegex(TypeError, 'the context manager'): + test.enterContext(LacksEnter()) + with self.assertRaisesRegex(TypeError, 'the context manager'): + test.enterContext(LacksExit()) + + self.assertEqual(test._cleanups, []) class TestClassCleanup(unittest.TestCase): @@ -295,13 +362,14 @@ class TestClassCleanup(unittest.TestCase): ordering.append('test') @classmethod def tearDownClass(cls): + ordering.append('tearDownClass') raise Exception('TearDownClassExc') suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) with self.assertRaises(Exception) as cm: suite.debug() self.assertEqual(str(cm.exception), 'TearDownClassExc') - self.assertEqual(ordering, ['setUpClass', 'test']) + self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass']) self.assertTrue(TestableTest._class_cleanups) TestableTest._class_cleanups.clear() @@ -311,7 +379,7 @@ class TestClassCleanup(unittest.TestCase): with self.assertRaises(Exception) as cm: suite.debug() self.assertEqual(str(cm.exception), 'TearDownClassExc') - self.assertEqual(ordering, ['setUpClass', 'test']) + self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass']) self.assertTrue(TestableTest._class_cleanups) TestableTest._class_cleanups.clear() @@ -450,6 +518,62 @@ class TestClassCleanup(unittest.TestCase): self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass', 'cleanup_good']) + def test_enterClassContext(self): + class TestableTest(unittest.TestCase): + def testNothing(self): + pass + + cleanups = [] + + TestableTest.addClassCleanup(cleanups.append, 'cleanup1') + cm = TestCM(cleanups, 42) + self.assertEqual(TestableTest.enterClassContext(cm), 42) + TestableTest.addClassCleanup(cleanups.append, 'cleanup2') + + TestableTest.doClassCleanups() + self.assertEqual(cleanups, ['enter', 'cleanup2', 'exit', 'cleanup1']) + + def test_enterClassContext_arg_errors(self): + class TestableTest(unittest.TestCase): + def testNothing(self): + pass + + with self.assertRaisesRegex(TypeError, 'the context manager'): + TestableTest.enterClassContext(LacksEnterAndExit()) + with self.assertRaisesRegex(TypeError, 'the context manager'): + TestableTest.enterClassContext(LacksEnter()) + with self.assertRaisesRegex(TypeError, 'the context manager'): + TestableTest.enterClassContext(LacksExit()) + + self.assertEqual(TestableTest._class_cleanups, []) + + def test_run_nested_test(self): + ordering = [] + + class InnerTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + ordering.append('inner setup') + cls.addClassCleanup(ordering.append, 'inner cleanup') + def test(self): + ordering.append('inner test') + + class OuterTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + ordering.append('outer setup') + cls.addClassCleanup(ordering.append, 'outer cleanup') + def test(self): + ordering.append('start outer test') + runTests(InnerTest) + ordering.append('end outer test') + + runTests(OuterTest) + self.assertEqual(ordering, [ + 'outer setup', 'start outer test', + 'inner setup', 'inner test', 'inner cleanup', + 'end outer test', 'outer cleanup']) + class TestModuleCleanUp(unittest.TestCase): def test_add_and_do_ModuleCleanup(self): @@ -661,6 +785,7 @@ class TestModuleCleanUp(unittest.TestCase): unittest.addModuleCleanup(cleanup, ordering) @staticmethod def tearDownModule(): + ordering.append('tearDownModule') raise Exception('CleanUpExc') class TestableTest(unittest.TestCase): @@ -679,7 +804,8 @@ class TestModuleCleanUp(unittest.TestCase): self.assertEqual(result.errors[0][1].splitlines()[-1], 'Exception: CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', - 'tearDownClass', 'cleanup_good']) + 'tearDownClass', 'tearDownModule', + 'cleanup_good']) self.assertEqual(unittest.case._module_cleanups, []) def test_debug_module_executes_cleanUp(self): @@ -733,6 +859,7 @@ class TestModuleCleanUp(unittest.TestCase): unittest.addModuleCleanup(cleanup, ordering, blowUp=blowUp) @staticmethod def tearDownModule(): + ordering.append('tearDownModule') raise Exception('TearDownModuleExc') class TestableTest(unittest.TestCase): @@ -752,7 +879,7 @@ class TestModuleCleanUp(unittest.TestCase): suite.debug() self.assertEqual(str(cm.exception), 'TearDownModuleExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', - 'tearDownClass']) + 'tearDownClass', 'tearDownModule']) self.assertTrue(unittest.case._module_cleanups) unittest.case._module_cleanups.clear() @@ -763,7 +890,7 @@ class TestModuleCleanUp(unittest.TestCase): suite.debug() self.assertEqual(str(cm.exception), 'TearDownModuleExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', - 'tearDownClass']) + 'tearDownClass', 'tearDownModule']) self.assertTrue(unittest.case._module_cleanups) unittest.case._module_cleanups.clear() @@ -999,6 +1126,31 @@ class TestModuleCleanUp(unittest.TestCase): 'cleanup2', 'setUp2', 'test2', 'tearDown2', 'cleanup3', 'tearDownModule', 'cleanup1']) + def test_enterModuleContext(self): + cleanups = [] + + unittest.addModuleCleanup(cleanups.append, 'cleanup1') + cm = TestCM(cleanups, 42) + self.assertEqual(unittest.enterModuleContext(cm), 42) + unittest.addModuleCleanup(cleanups.append, 'cleanup2') + + unittest.case.doModuleCleanups() + self.assertEqual(cleanups, ['enter', 'cleanup2', 'exit', 'cleanup1']) + + def test_enterModuleContext_arg_errors(self): + class TestableTest(unittest.TestCase): + def testNothing(self): + pass + + with self.assertRaisesRegex(TypeError, 'the context manager'): + unittest.enterModuleContext(LacksEnterAndExit()) + with self.assertRaisesRegex(TypeError, 'the context manager'): + unittest.enterModuleContext(LacksEnter()) + with self.assertRaisesRegex(TypeError, 'the context manager'): + unittest.enterModuleContext(LacksExit()) + + self.assertEqual(unittest.case._module_cleanups, []) + class Test_TextTestRunner(unittest.TestCase): """Tests for TextTestRunner.""" @@ -1139,6 +1291,7 @@ class Test_TextTestRunner(unittest.TestCase): expectedresult = (runner.stream, DESCRIPTIONS, VERBOSITY) self.assertEqual(runner._makeResult(), expectedresult) + @support.requires_subprocess() def test_warnings(self): """ Check that warnings argument of TextTestRunner correctly affects the diff --git a/Lib/unittest/test/test_setups.py b/Lib/test/test_unittest/test_setups.py similarity index 100% rename from Lib/unittest/test/test_setups.py rename to Lib/test/test_unittest/test_setups.py diff --git a/Lib/unittest/test/test_skipping.py b/Lib/test/test_unittest/test_skipping.py similarity index 99% rename from Lib/unittest/test/test_skipping.py rename to Lib/test/test_unittest/test_skipping.py index 64ceeae37ef..f146dcac18e 100644 --- a/Lib/unittest/test/test_skipping.py +++ b/Lib/test/test_unittest/test_skipping.py @@ -1,6 +1,6 @@ import unittest -from unittest.test.support import LoggingResult +from test.test_unittest.support import LoggingResult class Test_TestSkipping(unittest.TestCase): diff --git a/Lib/unittest/test/test_suite.py b/Lib/test/test_unittest/test_suite.py similarity index 99% rename from Lib/unittest/test/test_suite.py rename to Lib/test/test_unittest/test_suite.py index 0551a169967..ca52ee9d9c0 100644 --- a/Lib/unittest/test/test_suite.py +++ b/Lib/test/test_unittest/test_suite.py @@ -3,7 +3,7 @@ import unittest import gc import sys import weakref -from unittest.test.support import LoggingResult, TestEquality +from test.test_unittest.support import LoggingResult, TestEquality ### Support code for Test_TestSuite diff --git a/Lib/test/test_unittest/testmock/__init__.py b/Lib/test/test_unittest/testmock/__init__.py new file mode 100644 index 00000000000..bc502ef32d2 --- /dev/null +++ b/Lib/test/test_unittest/testmock/__init__.py @@ -0,0 +1,6 @@ +import os.path +from test.support import load_package_tests + + +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/unittest/test/testmock/__main__.py b/Lib/test/test_unittest/testmock/__main__.py similarity index 86% rename from Lib/unittest/test/testmock/__main__.py rename to Lib/test/test_unittest/testmock/__main__.py index 45c633a4ee4..1e3068b0ddf 100644 --- a/Lib/unittest/test/testmock/__main__.py +++ b/Lib/test/test_unittest/testmock/__main__.py @@ -6,7 +6,7 @@ def load_tests(loader, standard_tests, pattern): # top level directory cached on loader instance this_dir = os.path.dirname(__file__) pattern = pattern or "test*.py" - # We are inside unittest.test.testmock, so the top-level is three notches up + # We are inside test.test_unittest.testmock, so the top-level is three notches up top_level_dir = os.path.dirname(os.path.dirname(os.path.dirname(this_dir))) package_tests = loader.discover(start_dir=this_dir, pattern=pattern, top_level_dir=top_level_dir) diff --git a/Lib/unittest/test/testmock/support.py b/Lib/test/test_unittest/testmock/support.py similarity index 100% rename from Lib/unittest/test/testmock/support.py rename to Lib/test/test_unittest/testmock/support.py diff --git a/Lib/unittest/test/testmock/testasync.py b/Lib/test/test_unittest/testmock/testasync.py similarity index 96% rename from Lib/unittest/test/testmock/testasync.py rename to Lib/test/test_unittest/testmock/testasync.py index 122e6956635..5f12f9f9566 100644 --- a/Lib/unittest/test/testmock/testasync.py +++ b/Lib/test/test_unittest/testmock/testasync.py @@ -4,11 +4,14 @@ import inspect import re import unittest from contextlib import contextmanager +from test import support + +support.requires_working_socket(module=True) from asyncio import run, iscoroutinefunction from unittest import IsolatedAsyncioTestCase from unittest.mock import (ANY, call, AsyncMock, patch, MagicMock, Mock, - create_autospec, sentinel, _CallList) + create_autospec, sentinel, _CallList, seal) def tearDownModule(): @@ -146,6 +149,23 @@ class AsyncPatchCMTest(unittest.TestCase): run(test_async()) + def test_patch_dict_async_def(self): + foo = {'a': 'a'} + @patch.dict(foo, {'a': 'b'}) + async def test_async(): + self.assertEqual(foo['a'], 'b') + + self.assertTrue(iscoroutinefunction(test_async)) + run(test_async()) + + def test_patch_dict_async_def_context(self): + foo = {'a': 'a'} + async def test_async(): + with patch.dict(foo, {'a': 'b'}): + self.assertEqual(foo['a'], 'b') + + run(test_async()) + class AsyncMockTest(unittest.TestCase): def test_iscoroutinefunction_default(self): @@ -198,10 +218,6 @@ class AsyncAutospecTest(unittest.TestCase): with self.assertRaises(RuntimeError): create_autospec(async_func, instance=True) - @unittest.skip('Broken test from https://bugs.python.org/issue37251') - def test_create_autospec_awaitable_class(self): - self.assertIsInstance(create_autospec(AwaitableClass), AsyncMock) - def test_create_autospec(self): spec = create_autospec(async_func_args) awaitable = spec(1, 2, c=3) @@ -280,6 +296,27 @@ class AsyncSpecTest(unittest.TestCase): self.assertIsInstance(mock.async_method, AsyncMock) self.assertIsInstance(mock.normal_method, Mock) + def test_spec_normal_methods_on_class_with_mock_seal(self): + mock = Mock(AsyncClass) + seal(mock) + with self.assertRaises(AttributeError): + mock.normal_method + with self.assertRaises(AttributeError): + mock.async_method + + def test_spec_async_attributes_instance(self): + async_instance = AsyncClass() + async_instance.async_func_attr = async_func + async_instance.later_async_func_attr = normal_func + + mock_async_instance = Mock(spec_set=async_instance) + + async_instance.later_async_func_attr = async_func + + self.assertIsInstance(mock_async_instance.async_func_attr, AsyncMock) + # only the shape of the spec at the time of mock construction matters + self.assertNotIsInstance(mock_async_instance.later_async_func_attr, AsyncMock) + def test_spec_mock_type_kw(self): def inner_test(mock_type): async_mock = mock_type(spec=async_func) @@ -1056,3 +1093,7 @@ class AsyncMockAssert(unittest.TestCase): 'Actual: [call(1)]'))) as cm: self.mock.assert_has_awaits([call(), call(1, 2)]) self.assertIsInstance(cm.exception.__cause__, TypeError) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/unittest/test/testmock/testcallable.py b/Lib/test/test_unittest/testmock/testcallable.py similarity index 98% rename from Lib/unittest/test/testmock/testcallable.py rename to Lib/test/test_unittest/testmock/testcallable.py index 5eadc007049..ca88511f639 100644 --- a/Lib/unittest/test/testmock/testcallable.py +++ b/Lib/test/test_unittest/testmock/testcallable.py @@ -3,7 +3,7 @@ # http://www.voidspace.org.uk/python/mock/ import unittest -from unittest.test.testmock.support import is_instance, X, SomeClass +from test.test_unittest.testmock.support import is_instance, X, SomeClass from unittest.mock import ( Mock, MagicMock, NonCallableMagicMock, diff --git a/Lib/unittest/test/testmock/testhelpers.py b/Lib/test/test_unittest/testmock/testhelpers.py similarity index 100% rename from Lib/unittest/test/testmock/testhelpers.py rename to Lib/test/test_unittest/testmock/testhelpers.py diff --git a/Lib/unittest/test/testmock/testmagicmethods.py b/Lib/test/test_unittest/testmock/testmagicmethods.py similarity index 100% rename from Lib/unittest/test/testmock/testmagicmethods.py rename to Lib/test/test_unittest/testmock/testmagicmethods.py diff --git a/Lib/unittest/test/testmock/testmock.py b/Lib/test/test_unittest/testmock/testmock.py similarity index 98% rename from Lib/unittest/test/testmock/testmock.py rename to Lib/test/test_unittest/testmock/testmock.py index fdba543b535..d1cae47a40e 100644 --- a/Lib/unittest/test/testmock/testmock.py +++ b/Lib/test/test_unittest/testmock/testmock.py @@ -5,7 +5,7 @@ import tempfile from test.support import ALWAYS_EQ import unittest -from unittest.test.testmock.support import is_instance +from test.test_unittest.testmock.support import is_instance from unittest import mock from unittest.mock import ( call, DEFAULT, patch, sentinel, @@ -226,6 +226,14 @@ class MockTest(unittest.TestCase): with self.assertRaisesRegex(InvalidSpecError, "Cannot spec attr 'B' as the spec_set "): mock.patch.object(A, 'B', spec_set=A.B).start() + with self.assertRaisesRegex(InvalidSpecError, + "Cannot spec attr 'B' as the spec_set "): + mock.patch.object(A, 'B', spec_set=A.B).start() + with self.assertRaisesRegex(InvalidSpecError, "Cannot spec a Mock object."): + mock.Mock(A.B) + with mock.patch('builtins.open', mock.mock_open()): + mock.mock_open() # should still be valid with open() mocked + def test_reset_mock(self): parent = Mock() @@ -1637,12 +1645,48 @@ class MockTest(unittest.TestCase): m.aseert_foo_call() with self.assertRaisesRegex(AttributeError, msg): m.assrt_foo_call() + with self.assertRaisesRegex(AttributeError, msg): + m.called_once_with() + with self.assertRaisesRegex(AttributeError, msg): + m.called_once() + with self.assertRaisesRegex(AttributeError, msg): + m.has_calls() + + class Foo(object): + def called_once(self): pass + + def has_calls(self): pass + + m = Mock(spec=Foo) + m.called_once() + m.has_calls() + + m.called_once.assert_called_once() + m.has_calls.assert_called_once() + m = Mock(unsafe=True) m.assert_foo_call() m.assret_foo_call() m.asert_foo_call() m.aseert_foo_call() m.assrt_foo_call() + m.called_once() + m.called_once_with() + m.has_calls() + + # gh-100739 + def test_mock_safe_with_spec(self): + class Foo(object): + def assert_bar(self): pass + + def assertSome(self): pass + + m = Mock(spec=Foo) + m.assert_bar() + m.assertSome() + + m.assert_bar.assert_called_once() + m.assertSome.assert_called_once() #Issue21262 def test_assert_not_called(self): diff --git a/Lib/unittest/test/testmock/testpatch.py b/Lib/test/test_unittest/testmock/testpatch.py similarity index 98% rename from Lib/unittest/test/testmock/testpatch.py rename to Lib/test/test_unittest/testmock/testpatch.py index d8c1515f834..8ceb5d973e1 100644 --- a/Lib/unittest/test/testmock/testpatch.py +++ b/Lib/test/test_unittest/testmock/testpatch.py @@ -7,8 +7,8 @@ import sys from collections import OrderedDict import unittest -from unittest.test.testmock import support -from unittest.test.testmock.support import SomeClass, is_instance +from test.test_unittest.testmock import support +from test.test_unittest.testmock.support import SomeClass, is_instance from test.test_importlib.util import uncache from unittest.mock import ( @@ -669,7 +669,7 @@ class PatchTest(unittest.TestCase): # the new dictionary during function call original = support.target.copy() - @patch.dict('unittest.test.testmock.support.target', {'bar': 'BAR'}) + @patch.dict('test.test_unittest.testmock.support.target', {'bar': 'BAR'}) def test(): self.assertEqual(support.target, {'foo': 'BAZ', 'bar': 'BAR'}) @@ -1614,7 +1614,7 @@ class PatchTest(unittest.TestCase): def test_patch_nested_autospec_repr(self): - with patch('unittest.test.testmock.support', autospec=True) as m: + with patch('test.test_unittest.testmock.support', autospec=True) as m: self.assertIn(" name='support.SomeClass.wibble()'", repr(m.SomeClass.wibble())) self.assertIn(" name='support.SomeClass().wibble()'", @@ -1875,13 +1875,14 @@ class PatchTest(unittest.TestCase): self.assertEqual(foo(), 1) self.assertEqual(foo(), 0) + orig_doc = foo.__doc__ with patch.object(foo, '__doc__', "FUN"): self.assertEqual(foo.__doc__, "FUN") - self.assertEqual(foo.__doc__, "TEST") + self.assertEqual(foo.__doc__, orig_doc) with patch.object(foo, '__module__', "testpatch2"): self.assertEqual(foo.__module__, "testpatch2") - self.assertEqual(foo.__module__, 'unittest.test.testmock.testpatch') + self.assertEqual(foo.__module__, 'test.test_unittest.testmock.testpatch') with patch.object(foo, '__annotations__', dict([('s', 1, )])): self.assertEqual(foo.__annotations__, dict([('s', 1, )])) @@ -1916,28 +1917,33 @@ class PatchTest(unittest.TestCase): # This exercises the AttributeError branch of _dot_lookup. # make sure it's there - import unittest.test.testmock.support + import test.test_unittest.testmock.support # now make sure it's not: with patch.dict('sys.modules'): - del sys.modules['unittest.test.testmock.support'] - del sys.modules['unittest.test.testmock'] - del sys.modules['unittest.test'] - del sys.modules['unittest'] + del sys.modules['test.test_unittest.testmock.support'] + del sys.modules['test.test_unittest.testmock'] + del sys.modules['test.test_unittest'] + del sys.modules['test'] # now make sure we can patch based on a dotted path: - @patch('unittest.test.testmock.support.X') + @patch('test.test_unittest.testmock.support.X') def test(mock): pass test() def test_invalid_target(self): - with self.assertRaises(TypeError): - patch('') + class Foo: + pass + + for target in ['', 12, Foo()]: + with self.subTest(target=target): + with self.assertRaises(TypeError): + patch(target) def test_cant_set_kwargs_when_passing_a_mock(self): - @patch('unittest.test.testmock.support.X', new=object(), x=1) + @patch('test.test_unittest.testmock.support.X', new=object(), x=1) def test(): pass with self.assertRaises(TypeError): test() diff --git a/Lib/unittest/test/testmock/testsealable.py b/Lib/test/test_unittest/testmock/testsealable.py similarity index 96% rename from Lib/unittest/test/testmock/testsealable.py rename to Lib/test/test_unittest/testmock/testsealable.py index daba2b49b46..8bf98cfa562 100644 --- a/Lib/unittest/test/testmock/testsealable.py +++ b/Lib/test/test_unittest/testmock/testsealable.py @@ -175,15 +175,12 @@ class TestSealable(unittest.TestCase): # https://bugs.python.org/issue45156 class Foo: foo = 0 - def bar1(self): - return 1 - def bar2(self): - return 2 + def bar1(self): pass + def bar2(self): pass class Baz: baz = 3 - def ban(self): - return 4 + def ban(self): pass for spec_set in (True, False): with self.subTest(spec_set=spec_set): @@ -200,6 +197,9 @@ class TestSealable(unittest.TestCase): self.assertIsInstance(foo.Baz.baz, mock.NonCallableMagicMock) self.assertIsInstance(foo.Baz.ban, mock.MagicMock) + # see gh-91803 + self.assertIsInstance(foo.bar2(), mock.MagicMock) + self.assertEqual(foo.bar1(), 'a') foo.bar1.return_value = 'new_a' self.assertEqual(foo.bar1(), 'new_a') @@ -212,7 +212,7 @@ class TestSealable(unittest.TestCase): with self.assertRaises(AttributeError): foo.bar = 1 with self.assertRaises(AttributeError): - foo.bar2() + foo.bar2().x foo.bar2.return_value = 'bar2' self.assertEqual(foo.bar2(), 'bar2') diff --git a/Lib/unittest/test/testmock/testsentinel.py b/Lib/test/test_unittest/testmock/testsentinel.py similarity index 100% rename from Lib/unittest/test/testmock/testsentinel.py rename to Lib/test/test_unittest/testmock/testsentinel.py diff --git a/Lib/unittest/test/testmock/testwith.py b/Lib/test/test_unittest/testmock/testwith.py similarity index 98% rename from Lib/unittest/test/testmock/testwith.py rename to Lib/test/test_unittest/testmock/testwith.py index 42ebf3898c8..8dc8eb11376 100644 --- a/Lib/unittest/test/testmock/testwith.py +++ b/Lib/test/test_unittest/testmock/testwith.py @@ -1,7 +1,7 @@ import unittest from warnings import catch_warnings -from unittest.test.testmock.support import is_instance +from test.test_unittest.testmock.support import is_instance from unittest.mock import MagicMock, Mock, patch, sentinel, mock_open, call @@ -130,8 +130,8 @@ class WithTest(unittest.TestCase): c = C() - with patch.object(c, 'f', autospec=True) as patch1: - with patch.object(c, 'f', autospec=True) as patch2: + with patch.object(c, 'f') as patch1: + with patch.object(c, 'f') as patch2: c.f() self.assertEqual(patch2.call_count, 1) self.assertEqual(patch1.call_count, 0) diff --git a/Lib/test/test_univnewlines.py b/Lib/test/test_univnewlines.py index b9054918780..ed2e0970bac 100644 --- a/Lib/test/test_univnewlines.py +++ b/Lib/test/test_univnewlines.py @@ -4,7 +4,6 @@ import _pyio as pyio import unittest import os import sys -from test import support from test.support import os_helper diff --git a/Lib/test/test_unpack.py b/Lib/test/test_unpack.py index 472c8343eb2..f5ca1d455b5 100644 --- a/Lib/test/test_unpack.py +++ b/Lib/test/test_unpack.py @@ -151,5 +151,21 @@ def load_tests(loader, tests, pattern): return tests +class TestCornerCases(unittest.TestCase): + def test_extended_oparg_not_ignored(self): + # https://github.com/python/cpython/issues/91625 + target = "(" + "y,"*400 + ")" + code = f"""def unpack_400(x): + {target} = x + return y + """ + ns = {} + exec(code, ns) + unpack_400 = ns["unpack_400"] + # Warm up the the function for quickening (PEP 659) + for _ in range(30): + y = unpack_400(range(400)) + self.assertEqual(y, 399) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_unparse.py b/Lib/test/test_unparse.py index d8ba487328b..88c7c3a0af8 100644 --- a/Lib/test/test_unparse.py +++ b/Lib/test/test_unparse.py @@ -6,6 +6,7 @@ import pathlib import random import tokenize import ast +from test.support.ast_helper import ASTTestMixin def read_pyfile(filename): @@ -93,6 +94,19 @@ finally: suite5 """ +try_except_star_finally = """\ +try: + suite1 +except* ex1: + suite2 +except* ex2: + suite3 +else: + suite4 +finally: + suite5 +""" + with_simple = """\ with f(): suite1 @@ -115,10 +129,7 @@ docstring_prefixes = ( "async def foo():\n ", ) -class ASTTestCase(unittest.TestCase): - def assertASTEqual(self, ast1, ast2): - self.assertEqual(ast.dump(ast1), ast.dump(ast2)) - +class ASTTestCase(ASTTestMixin, unittest.TestCase): def check_ast_roundtrip(self, code1, **kwargs): with self.subTest(code1=code1, ast_parse_kwargs=kwargs): ast1 = ast.parse(code1, **kwargs) @@ -304,6 +315,9 @@ class UnparseTestCase(ASTTestCase): def test_try_except_finally(self): self.check_ast_roundtrip(try_except_finally) + def test_try_except_star_finally(self): + self.check_ast_roundtrip(try_except_star_finally) + def test_starred_assignment(self): self.check_ast_roundtrip("a, *b, c = seq") self.check_ast_roundtrip("a, (*b, c) = seq") @@ -328,7 +342,17 @@ class UnparseTestCase(ASTTestCase): self.check_ast_roundtrip("a[i]") self.check_ast_roundtrip("a[i,]") self.check_ast_roundtrip("a[i, j]") + # The AST for these next two both look like `a[(*a,)]` self.check_ast_roundtrip("a[(*a,)]") + self.check_ast_roundtrip("a[*a]") + self.check_ast_roundtrip("a[b, *a]") + self.check_ast_roundtrip("a[*a, c]") + self.check_ast_roundtrip("a[b, *a, c]") + self.check_ast_roundtrip("a[*a, *a]") + self.check_ast_roundtrip("a[b, *a, *a]") + self.check_ast_roundtrip("a[*a, b, *a]") + self.check_ast_roundtrip("a[*a, *a, b]") + self.check_ast_roundtrip("a[b, *a, *a, c]") self.check_ast_roundtrip("a[(a:=b)]") self.check_ast_roundtrip("a[(a:=b,c)]") self.check_ast_roundtrip("a[()]") @@ -360,6 +384,12 @@ class UnparseTestCase(ASTTestCase): def test_invalid_yield_from(self): self.check_invalid(ast.YieldFrom(value=None)) + def test_import_from_level_none(self): + tree = ast.ImportFrom(module='mod', names=[ast.alias(name='x')]) + self.assertEqual(ast.unparse(tree), "from mod import x") + tree = ast.ImportFrom(module='mod', names=[ast.alias(name='x')], level=None) + self.assertEqual(ast.unparse(tree), "from mod import x") + def test_docstrings(self): docstrings = ( 'this ends with double quote"', @@ -527,9 +557,23 @@ class CosmeticTestCase(ASTTestCase): self.check_src_roundtrip(f"{prefix} 1") def test_slices(self): + self.check_src_roundtrip("a[()]") self.check_src_roundtrip("a[1]") self.check_src_roundtrip("a[1, 2]") - self.check_src_roundtrip("a[(1, *a)]") + # Note that `a[*a]`, `a[*a,]`, and `a[(*a,)]` all evaluate to the same + # thing at runtime and have the same AST, but only `a[*a,]` passes + # this test, because that's what `ast.unparse` produces. + self.check_src_roundtrip("a[*a,]") + self.check_src_roundtrip("a[1, *a]") + self.check_src_roundtrip("a[*a, 2]") + self.check_src_roundtrip("a[1, *a, 2]") + self.check_src_roundtrip("a[*a, *a]") + self.check_src_roundtrip("a[1, *a, *a]") + self.check_src_roundtrip("a[*a, 1, *a]") + self.check_src_roundtrip("a[*a, *a, 1]") + self.check_src_roundtrip("a[1, *a, *a, 2]") + self.check_src_roundtrip("a[1:2, *a]") + self.check_src_roundtrip("a[*a, 1:2]") def test_lambda_parameters(self): self.check_src_roundtrip("lambda: something") @@ -572,6 +616,9 @@ class CosmeticTestCase(ASTTestCase): self.check_src_roundtrip(source.format(target=target)) def test_star_expr_assign_target_multiple(self): + self.check_src_roundtrip("() = []") + self.check_src_roundtrip("[] = ()") + self.check_src_roundtrip("() = [a] = c, = [d] = e, f = () = g = h") self.check_src_roundtrip("a = b = c = d") self.check_src_roundtrip("a, b = c, d = e, f = g") self.check_src_roundtrip("[a, b] = [c, d] = [e, f] = g") diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index 82f1d9dc2e7..2df74f5e6f9 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -10,6 +10,7 @@ import unittest from unittest.mock import patch from test import support from test.support import os_helper +from test.support import socket_helper from test.support import warnings_helper import os try: @@ -24,6 +25,10 @@ from base64 import b64encode import collections +if not socket_helper.has_gethostname: + raise unittest.SkipTest("test requires gethostname()") + + def hexescape(char): """Escape char as RFC 2396 specifies""" hex_repr = hex(ord(char))[2:].upper() @@ -232,17 +237,12 @@ class ProxyTests(unittest.TestCase): def setUp(self): # Records changes to env vars - self.env = os_helper.EnvironmentVarGuard() + self.env = self.enterContext(os_helper.EnvironmentVarGuard()) # Delete all proxy related env vars for k in list(os.environ): if 'proxy' in k.lower(): self.env.unset(k) - def tearDown(self): - # Restore all proxy related env vars - self.env.__exit__() - del self.env - def test_getproxies_environment_keep_no_proxies(self): self.env.set('NO_PROXY', 'localhost') proxies = urllib.request.getproxies_environment() @@ -1104,6 +1104,8 @@ class UnquotingTests(unittest.TestCase): self.assertEqual(result.count('%'), 1, "using unquote(): not all characters escaped: " "%s" % result) + + def test_unquote_rejects_none_and_tuple(self): self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, None) self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, ()) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index a2b1340e0bf..498c0382d21 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -1,7 +1,6 @@ import unittest from test import support from test.support import os_helper -from test.support import socket_helper from test.support import warnings_helper from test import test_urllib @@ -24,6 +23,8 @@ from urllib.parse import urlparse import urllib.error import http.client +support.requires_working_socket(module=True) + # XXX # Request # CacheFTPHandler (hard to write) @@ -164,7 +165,6 @@ class RequestHdrsTests(unittest.TestCase): self.assertEqual(find_user_pass("Some Realm", "http://example.com/spam"), ('joe', 'password')) - self.assertEqual(find_user_pass("Some Realm", "http://example.com/spam/spam"), ('joe', 'password')) @@ -173,12 +173,29 @@ class RequestHdrsTests(unittest.TestCase): add("c", "http://example.com/foo", "foo", "ni") add("c", "http://example.com/bar", "bar", "nini") + add("c", "http://example.com/foo/bar", "foobar", "nibar") self.assertEqual(find_user_pass("c", "http://example.com/foo"), ('foo', 'ni')) - self.assertEqual(find_user_pass("c", "http://example.com/bar"), ('bar', 'nini')) + self.assertEqual(find_user_pass("c", "http://example.com/foo/"), + ('foo', 'ni')) + self.assertEqual(find_user_pass("c", "http://example.com/foo/bar"), + ('foo', 'ni')) + self.assertEqual(find_user_pass("c", "http://example.com/foo/baz"), + ('foo', 'ni')) + self.assertEqual(find_user_pass("c", "http://example.com/foobar"), + (None, None)) + + add("c", "http://example.com/baz/", "baz", "ninini") + + self.assertEqual(find_user_pass("c", "http://example.com/baz"), + (None, None)) + self.assertEqual(find_user_pass("c", "http://example.com/baz/"), + ('baz', 'ninini')) + self.assertEqual(find_user_pass("c", "http://example.com/baz/bar"), + ('baz', 'ninini')) # For the same path, newer password should be considered. @@ -1539,11 +1556,11 @@ class HandlerTests(unittest.TestCase): def test_basic_and_digest_auth_handlers(self): # HTTPDigestAuthHandler raised an exception if it couldn't handle a 40* - # response (http://python.org/sf/1479302), where it should instead + # response (https://bugs.python.org/issue1479302), where it should instead # return None to allow another handler (especially # HTTPBasicAuthHandler) to handle the response. - # Also (http://python.org/sf/14797027, RFC 2617 section 1.2), we must + # Also (https://bugs.python.org/issue14797027, RFC 2617 section 1.2), we must # try digest first (since it's the strongest auth scheme), so we record # order of calls here to check digest comes first: class RecordingOpenerDirector(OpenerDirector): @@ -1658,8 +1675,9 @@ class HandlerTests(unittest.TestCase): auth_prior_handler.add_password( None, request_url, user, password, is_authenticated=True) - is_auth = pwd_manager.is_authenticated(request_url) - self.assertTrue(is_auth) + self.assertTrue(pwd_manager.is_authenticated(request_url)) + self.assertTrue(pwd_manager.is_authenticated(request_url + '/nested')) + self.assertFalse(pwd_manager.is_authenticated(request_url + 'plain')) opener = OpenerDirector() opener.add_handler(auth_prior_handler) @@ -1788,22 +1806,6 @@ class MiscTests(unittest.TestCase): self.opener_has_handler(o, MyHTTPHandler) self.opener_has_handler(o, MyOtherHTTPHandler) - @unittest.skipUnless(support.is_resource_enabled('network'), - 'test requires network access') - def test_issue16464(self): - with socket_helper.transient_internet("http://www.example.com/"): - opener = urllib.request.build_opener() - request = urllib.request.Request("http://www.example.com/") - self.assertEqual(None, request.data) - - opener.open(request, "1".encode("us-ascii")) - self.assertEqual(b"1", request.data) - self.assertEqual("1", request.get_header("Content-length")) - - opener.open(request, "1234567890".encode("us-ascii")) - self.assertEqual(b"1234567890", request.data) - self.assertEqual("10", request.get_header("Content-length")) - def test_HTTPError_interface(self): """ Issue 13211 reveals that HTTPError didn't implement the URLError @@ -1822,6 +1824,10 @@ class MiscTests(unittest.TestCase): expected_errmsg = '' % (err.code, err.msg) self.assertEqual(repr(err), expected_errmsg) + def test_gh_98778(self): + x = urllib.error.HTTPError("url", 405, "METHOD NOT ALLOWED", None, None) + self.assertEqual(getattr(x, "__notes__", ()), ()) + def test_parse_proxy(self): parse_proxy_test_cases = [ ('proxy.example.com', diff --git a/Lib/test/test_urllib2_localnet.py b/Lib/test/test_urllib2_localnet.py index 36fb05d3db0..f4729358557 100644 --- a/Lib/test/test_urllib2_localnet.py +++ b/Lib/test/test_urllib2_localnet.py @@ -8,6 +8,7 @@ import threading import unittest import hashlib +from test import support from test.support import hashlib_helper from test.support import threading_helper from test.support import warnings_helper @@ -17,6 +18,8 @@ try: except ImportError: ssl = None +support.requires_working_socket(module=True) + here = os.path.dirname(__file__) # Self-signed cert file for 'localhost' CERT_localhost = os.path.join(here, 'keycert.pem') @@ -317,7 +320,7 @@ class BasicAuthTests(unittest.TestCase): self.assertRaises(urllib.error.HTTPError, urllib.request.urlopen, self.server_url) -@hashlib_helper.requires_hashdigest("md5") +@hashlib_helper.requires_hashdigest("md5", openssl=True) class ProxyAuthTests(unittest.TestCase): URL = "http://localhost" @@ -614,6 +617,15 @@ class TestUrlopen(unittest.TestCase): pass self.assertEqual(handler.headers_received["Range"], "bytes=20-39") + def test_sending_headers_camel(self): + handler = self.start_server() + req = urllib.request.Request("http://localhost:%s/" % handler.port, + headers={"X-SoMe-hEader": "foobar"}) + with urllib.request.urlopen(req): + pass + self.assertIn("X-Some-Header", handler.headers_received.keys()) + self.assertNotIn("X-SoMe-hEader", handler.headers_received.keys()) + def test_basic(self): handler = self.start_server() with urllib.request.urlopen("http://localhost:%s" % handler.port) as open_url: @@ -660,6 +672,24 @@ class TestUrlopen(unittest.TestCase): (index, len(lines[index]), len(line))) self.assertEqual(index + 1, len(lines)) + def test_issue16464(self): + # See https://bugs.python.org/issue16464 + # and https://bugs.python.org/issue46648 + handler = self.start_server([ + (200, [], b'any'), + (200, [], b'any'), + ]) + opener = urllib.request.build_opener() + request = urllib.request.Request("http://localhost:%s" % handler.port) + self.assertEqual(None, request.data) + + opener.open(request, "1".encode("us-ascii")) + self.assertEqual(b"1", request.data) + self.assertEqual("1", request.get_header("Content-length")) + + opener.open(request, "1234567890".encode("us-ascii")) + self.assertEqual(b"1234567890", request.data) + self.assertEqual("10", request.get_header("Content-length")) def setUpModule(): thread_info = threading_helper.threading_setup() diff --git a/Lib/test/test_urllib2net.py b/Lib/test/test_urllib2net.py index aa41811560c..5da41c37bbf 100644 --- a/Lib/test/test_urllib2net.py +++ b/Lib/test/test_urllib2net.py @@ -3,6 +3,7 @@ import unittest from test import support from test.support import os_helper from test.support import socket_helper +from test.support import ResourceDenied from test.test_urllib2 import sanepathname2url import os @@ -28,13 +29,6 @@ def _wrap_with_retry_thrice(func, exc): return _retry_thrice(func, exc, *args, **kwargs) return wrapped -# bpo-35411: FTP tests of test_urllib2net randomly fail -# with "425 Security: Bad IP connecting" on Travis CI -skip_ftp_test_on_travis = unittest.skipIf('TRAVIS' in os.environ, - 'bpo-35411: skip FTP test ' - 'on Travis CI') - - # Connecting to remote hosts is flaky. Make it more robust by retrying # the connection several times. _urlopen_with_retry = _wrap_with_retry_thrice(urllib.request.urlopen, @@ -139,7 +133,6 @@ class OtherNetworkTests(unittest.TestCase): # XXX The rest of these tests aren't very good -- they don't check much. # They do sometimes catch some major disasters, though. - @skip_ftp_test_on_travis def test_ftp(self): urls = [ 'ftp://www.pythontest.net/README', @@ -339,7 +332,6 @@ class TimeoutTest(unittest.TestCase): FTP_HOST = 'ftp://www.pythontest.net/' - @skip_ftp_test_on_travis def test_ftp_basic(self): self.assertIsNone(socket.getdefaulttimeout()) with socket_helper.transient_internet(self.FTP_HOST, timeout=None): @@ -347,7 +339,6 @@ class TimeoutTest(unittest.TestCase): self.addCleanup(u.close) self.assertIsNone(u.fp.fp.raw._sock.gettimeout()) - @skip_ftp_test_on_travis def test_ftp_default_timeout(self): self.assertIsNone(socket.getdefaulttimeout()) with socket_helper.transient_internet(self.FTP_HOST): @@ -359,7 +350,6 @@ class TimeoutTest(unittest.TestCase): socket.setdefaulttimeout(None) self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) - @skip_ftp_test_on_travis def test_ftp_no_timeout(self): self.assertIsNone(socket.getdefaulttimeout()) with socket_helper.transient_internet(self.FTP_HOST): @@ -371,7 +361,6 @@ class TimeoutTest(unittest.TestCase): socket.setdefaulttimeout(None) self.assertIsNone(u.fp.fp.raw._sock.gettimeout()) - @skip_ftp_test_on_travis def test_ftp_timeout(self): with socket_helper.transient_internet(self.FTP_HOST): u = _urlopen_with_retry(self.FTP_HOST, timeout=60) diff --git a/Lib/test/test_urllib_response.py b/Lib/test/test_urllib_response.py index 73d2ef0424f..b76763f4ed8 100644 --- a/Lib/test/test_urllib_response.py +++ b/Lib/test/test_urllib_response.py @@ -4,6 +4,11 @@ import socket import tempfile import urllib.response import unittest +from test import support + +if support.is_wasi: + raise unittest.SkipTest("Cannot create socket on WASI") + class TestResponse(unittest.TestCase): diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index 2f629c72ae7..80fb9e5cd2a 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -653,18 +653,39 @@ class UrlParseTestCase(unittest.TestCase): """Check handling of invalid ports.""" for bytes in (False, True): for parse in (urllib.parse.urlsplit, urllib.parse.urlparse): - for port in ("foo", "1.5", "-1", "0x10"): + for port in ("foo", "1.5", "-1", "0x10", "-0", "1_1", " 1", "1 ", "६"): with self.subTest(bytes=bytes, parse=parse, port=port): netloc = "www.example.net:" + port url = "http://" + netloc if bytes: - netloc = netloc.encode("ascii") - url = url.encode("ascii") + if netloc.isascii() and port.isascii(): + netloc = netloc.encode("ascii") + url = url.encode("ascii") + else: + continue p = parse(url) self.assertEqual(p.netloc, netloc) with self.assertRaises(ValueError): p.port + def test_attributes_bad_scheme(self): + """Check handling of invalid schemes.""" + for bytes in (False, True): + for parse in (urllib.parse.urlsplit, urllib.parse.urlparse): + for scheme in (".", "+", "-", "0", "http&", "६http"): + with self.subTest(bytes=bytes, parse=parse, scheme=scheme): + url = scheme + "://www.example.net" + if bytes: + if url.isascii(): + url = url.encode("ascii") + else: + continue + p = parse(url) + if bytes: + self.assertEqual(p.scheme, b"") + else: + self.assertEqual(p.scheme, "") + def test_attributes_without_netloc(self): # This example is straight from RFC 3261. It looks like it # should allow the username, hostname, and port to be filled @@ -985,6 +1006,10 @@ class UrlParseTestCase(unittest.TestCase): self.assertEqual(result, 'archaeological%20arcana') result = urllib.parse.quote_from_bytes(b'') self.assertEqual(result, '') + result = urllib.parse.quote_from_bytes(b'A'*10_000) + self.assertEqual(result, 'A'*10_000) + result = urllib.parse.quote_from_bytes(b'z\x01/ '*253_183) + self.assertEqual(result, 'z%01/%20'*253_183) def test_unquote_to_bytes(self): result = urllib.parse.unquote_to_bytes('abc%20def') @@ -1195,6 +1220,7 @@ class Utility_Tests(unittest.TestCase): self.assertEqual(splitnport('127.0.0.1', 55), ('127.0.0.1', 55)) self.assertEqual(splitnport('parrot:cheese'), ('parrot', None)) self.assertEqual(splitnport('parrot:cheese', 55), ('parrot', None)) + self.assertEqual(splitnport('parrot: +1_0 '), ('parrot', None)) def test_splitquery(self): # Normal cases are exercised by other tests; ensure that we also diff --git a/Lib/test/test_utf8_mode.py b/Lib/test/test_utf8_mode.py index 8b6332ee227..ec29ba6d51b 100644 --- a/Lib/test/test_utf8_mode.py +++ b/Lib/test/test_utf8_mode.py @@ -161,7 +161,7 @@ class UTF8ModeTests(unittest.TestCase): filename = __file__ out = self.get_output('-c', code, filename, PYTHONUTF8='1') - self.assertEqual(out, 'UTF-8/strict') + self.assertEqual(out.lower(), 'utf-8/strict') def _check_io_encoding(self, module, encoding=None, errors=None): filename = __file__ @@ -183,10 +183,10 @@ class UTF8ModeTests(unittest.TestCase): PYTHONUTF8='1') if not encoding: - encoding = 'UTF-8' + encoding = 'utf-8' if not errors: errors = 'strict' - self.assertEqual(out, f'{encoding}/{errors}') + self.assertEqual(out.lower(), f'{encoding}/{errors}') def check_io_encoding(self, module): self._check_io_encoding(module, encoding="latin1") @@ -203,12 +203,12 @@ class UTF8ModeTests(unittest.TestCase): def test_locale_getpreferredencoding(self): code = 'import locale; print(locale.getpreferredencoding(False), locale.getpreferredencoding(True))' out = self.get_output('-X', 'utf8', '-c', code) - self.assertEqual(out, 'UTF-8 UTF-8') + self.assertEqual(out, 'utf-8 utf-8') for loc in POSIX_LOCALES: with self.subTest(LC_ALL=loc): out = self.get_output('-X', 'utf8', '-c', code, LC_ALL=loc) - self.assertEqual(out, 'UTF-8 UTF-8') + self.assertEqual(out, 'utf-8 utf-8') @unittest.skipIf(MS_WINDOWS, 'test specific to Unix') def test_cmd_line(self): @@ -255,6 +255,7 @@ class UTF8ModeTests(unittest.TestCase): @unittest.skipIf(MS_WINDOWS, "os.device_encoding() doesn't implement " "the UTF-8 Mode on Windows") + @support.requires_subprocess() def test_device_encoding(self): # Use stdout as TTY if not sys.stdout.isatty(): @@ -275,7 +276,7 @@ class UTF8ModeTests(unittest.TestCase): # In UTF-8 Mode, device_encoding(fd) returns "UTF-8" if fd is a TTY with open(filename, encoding="utf8") as fp: out = fp.read().rstrip() - self.assertEqual(out, 'True UTF-8') + self.assertEqual(out, 'True utf-8') if __name__ == "__main__": diff --git a/Lib/test/test_uu.py b/Lib/test/test_uu.py index 753b31eef0d..0493aae4fc6 100644 --- a/Lib/test/test_uu.py +++ b/Lib/test/test_uu.py @@ -4,12 +4,13 @@ Nick Mathewson """ import unittest -from test.support import os_helper +from test.support import os_helper, warnings_helper + +uu = warnings_helper.import_deprecated("uu") import os import stat import sys -import uu import io plaintext = b"The symbols on top of your keyboard are !@#$%^&*()_+|~\n" @@ -73,6 +74,7 @@ class UUTest(unittest.TestCase): with self.assertRaises(TypeError): uu.encode(inp, out, "t1", 0o644, True) + @os_helper.skip_unless_working_chmod def test_decode(self): for backtick in True, False: inp = io.BytesIO(encodedtextwrapped(0o666, "t1", backtick=backtick)) @@ -198,6 +200,8 @@ class UUFileTest(unittest.TestCase): s = fout.read() self.assertEqual(s, encodedtextwrapped(0o644, self.tmpin)) + # decode() calls chmod() + @os_helper.skip_unless_working_chmod def test_decode(self): with open(self.tmpin, 'wb') as f: f.write(encodedtextwrapped(0o644, self.tmpout)) @@ -210,6 +214,7 @@ class UUFileTest(unittest.TestCase): self.assertEqual(s, plaintext) # XXX is there an xp way to verify the mode? + @os_helper.skip_unless_working_chmod def test_decode_filename(self): with open(self.tmpin, 'wb') as f: f.write(encodedtextwrapped(0o644, self.tmpout)) @@ -220,6 +225,7 @@ class UUFileTest(unittest.TestCase): s = f.read() self.assertEqual(s, plaintext) + @os_helper.skip_unless_working_chmod def test_decodetwice(self): # Verify that decode() will refuse to overwrite an existing file with open(self.tmpin, 'wb') as f: @@ -230,6 +236,7 @@ class UUFileTest(unittest.TestCase): with open(self.tmpin, 'rb') as f: self.assertRaises(uu.Error, uu.decode, f) + @os_helper.skip_unless_working_chmod def test_decode_mode(self): # Verify that decode() will set the given mode for the out_file expected_mode = 0o444 diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py index 3f56192c70e..b2c229cd634 100755 --- a/Lib/test/test_uuid.py +++ b/Lib/test/test_uuid.py @@ -647,7 +647,7 @@ class BaseTestUUID: equal(u, self.uuid.UUID(v)) equal(str(u), v) - @unittest.skipUnless(hasattr(os, 'fork'), 'need os.fork') + @support.requires_fork() def testIssue8621(self): # On at least some versions of OSX self.uuid.uuid4 generates # the same sequence of UUIDs in the parent and any @@ -675,6 +675,64 @@ class BaseTestUUID: weak = weakref.ref(strong) self.assertIs(strong, weak()) + @mock.patch.object(sys, "argv", ["", "-u", "uuid3", "-n", "@dns"]) + def test_cli_namespace_required_for_uuid3(self): + with self.assertRaises(SystemExit) as cm: + self.uuid.main() + + # Check that exception code is the same as argparse.ArgumentParser.error + self.assertEqual(cm.exception.code, 2) + + @mock.patch.object(sys, "argv", ["", "-u", "uuid3", "-N", "python.org"]) + def test_cli_name_required_for_uuid3(self): + with self.assertRaises(SystemExit) as cm: + self.uuid.main() + + # Check that exception code is the same as argparse.ArgumentParser.error + self.assertEqual(cm.exception.code, 2) + + @mock.patch.object(sys, "argv", [""]) + def test_cli_uuid4_outputted_with_no_args(self): + stdout = io.StringIO() + with contextlib.redirect_stdout(stdout): + self.uuid.main() + + output = stdout.getvalue().strip() + uuid_output = self.uuid.UUID(output) + + # Output uuid should be in the format of uuid4 + self.assertEqual(output, str(uuid_output)) + self.assertEqual(uuid_output.version, 4) + + @mock.patch.object(sys, "argv", + ["", "-u", "uuid3", "-n", "@dns", "-N", "python.org"]) + def test_cli_uuid3_ouputted_with_valid_namespace_and_name(self): + stdout = io.StringIO() + with contextlib.redirect_stdout(stdout): + self.uuid.main() + + output = stdout.getvalue().strip() + uuid_output = self.uuid.UUID(output) + + # Output should be in the form of uuid5 + self.assertEqual(output, str(uuid_output)) + self.assertEqual(uuid_output.version, 3) + + @mock.patch.object(sys, "argv", + ["", "-u", "uuid5", "-n", "@dns", "-N", "python.org"]) + def test_cli_uuid5_ouputted_with_valid_namespace_and_name(self): + stdout = io.StringIO() + with contextlib.redirect_stdout(stdout): + self.uuid.main() + + output = stdout.getvalue().strip() + uuid_output = self.uuid.UUID(output) + + # Output should be in the form of uuid5 + self.assertEqual(output, str(uuid_output)) + self.assertEqual(uuid_output.version, 5) + + class TestUUIDWithoutExtModule(BaseTestUUID, unittest.TestCase): uuid = py_uuid diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 94d626598ba..4e18dfc23c4 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -5,21 +5,26 @@ Copyright (C) 2011-2012 Vinay Sajip. Licensed to the PSF under a contributor agreement. """ +import contextlib import ensurepip import os import os.path +import pathlib import re import shutil import struct import subprocess import sys +import sysconfig import tempfile -from test.support import (captured_stdout, captured_stderr, requires_zlib, - skip_if_broken_multiprocessing_synchronize) +from test.support import (captured_stdout, captured_stderr, + skip_if_broken_multiprocessing_synchronize, verbose, + requires_subprocess, is_emscripten, is_wasi, + requires_venv_with_pip, TEST_HOME_DIR) from test.support.os_helper import (can_symlink, EnvironmentVarGuard, rmtree) import unittest import venv -from unittest.mock import patch +from unittest.mock import patch, Mock try: import ctypes @@ -33,6 +38,10 @@ requireVenvCreate = unittest.skipUnless( or sys._base_executable != sys.executable, 'cannot run venv.create from within a venv on this platform') +if is_emscripten or is_wasi: + raise unittest.SkipTest("venv is not available on Emscripten/WASI.") + +@requires_subprocess() def check_output(cmd, encoding=None): p = subprocess.Popen(cmd, stdout=subprocess.PIPE, @@ -40,6 +49,8 @@ def check_output(cmd, encoding=None): encoding=encoding) out, err = p.communicate() if p.returncode: + if verbose and err: + print(err.decode('utf-8', 'backslashreplace')) raise subprocess.CalledProcessError( p.returncode, cmd, out, err) return out, err @@ -91,12 +102,23 @@ class BasicTest(BaseTest): fn = self.get_env_file(*args) self.assertTrue(os.path.isdir(fn)) - def test_defaults(self): + def test_defaults_with_str_path(self): """ - Test the create function with default arguments. + Test the create function with default arguments and a str path. """ rmtree(self.env_dir) self.run_with_capture(venv.create, self.env_dir) + self._check_output_of_default_create() + + def test_defaults_with_pathlib_path(self): + """ + Test the create function with default arguments and a pathlib.Path path. + """ + rmtree(self.env_dir) + self.run_with_capture(venv.create, pathlib.Path(self.env_dir)) + self._check_output_of_default_create() + + def _check_output_of_default_create(self): self.isdir(self.bindir) self.isdir(self.include) self.isdir(*self.lib) @@ -112,6 +134,11 @@ class BasicTest(BaseTest): executable = sys._base_executable path = os.path.dirname(executable) self.assertIn('home = %s' % path, data) + self.assertIn('executable = %s' % + os.path.realpath(sys.executable), data) + copies = '' if os.name=='nt' else ' --copies' + cmd = f'command = {sys.executable} -m venv{copies} --without-pip {self.env_dir}' + self.assertIn(cmd, data) fn = self.get_env_file(self.bindir, self.exe) if not os.path.exists(fn): # diagnostics for Windows buildbot failures bd = self.get_env_file(self.bindir) @@ -119,6 +146,37 @@ class BasicTest(BaseTest): print(' %r' % os.listdir(bd)) self.assertTrue(os.path.exists(fn), 'File %r should exist.' % fn) + def test_config_file_command_key(self): + attrs = [ + (None, None), + ('symlinks', '--copies'), + ('with_pip', '--without-pip'), + ('system_site_packages', '--system-site-packages'), + ('clear', '--clear'), + ('upgrade', '--upgrade'), + ('upgrade_deps', '--upgrade-deps'), + ('prompt', '--prompt'), + ] + for attr, opt in attrs: + rmtree(self.env_dir) + if not attr: + b = venv.EnvBuilder() + else: + b = venv.EnvBuilder( + **{attr: False if attr in ('with_pip', 'symlinks') else True}) + b.upgrade_dependencies = Mock() # avoid pip command to upgrade deps + b._setup_pip = Mock() # avoid pip setup + self.run_with_capture(b.create, self.env_dir) + data = self.get_text_file_contents('pyvenv.cfg') + if not attr: + for opt in ('--system-site-packages', '--clear', '--upgrade', + '--upgrade-deps', '--prompt'): + self.assertNotRegex(data, rf'command = .* {opt}') + elif os.name=='nt' and attr=='symlinks': + pass + else: + self.assertRegex(data, rf'command = .* {opt}') + def test_prompt(self): env_name = os.path.split(self.env_dir)[1] @@ -158,7 +216,7 @@ class BasicTest(BaseTest): if sys.platform == 'win32': expect_exe = os.path.normcase(os.path.realpath(expect_exe)) - def pip_cmd_checker(cmd): + def pip_cmd_checker(cmd, **kwargs): cmd[0] = os.path.normcase(cmd[0]) self.assertEqual( cmd, @@ -174,7 +232,7 @@ class BasicTest(BaseTest): ) fake_context = builder.ensure_directories(fake_env_dir) - with patch('venv.subprocess.check_call', pip_cmd_checker): + with patch('venv.subprocess.check_output', pip_cmd_checker): builder.upgrade_dependencies(fake_context) @requireVenvCreate @@ -194,7 +252,52 @@ class BasicTest(BaseTest): ('base_exec_prefix', sys.base_exec_prefix)): cmd[2] = 'import sys; print(sys.%s)' % prefix out, err = check_output(cmd) - self.assertEqual(out.strip(), expected.encode()) + self.assertEqual(out.strip(), expected.encode(), prefix) + + @requireVenvCreate + def test_sysconfig(self): + """ + Test that the sysconfig functions work in a virtual environment. + """ + rmtree(self.env_dir) + self.run_with_capture(venv.create, self.env_dir, symlinks=False) + envpy = os.path.join(self.env_dir, self.bindir, self.exe) + cmd = [envpy, '-c', None] + for call, expected in ( + # installation scheme + ('get_preferred_scheme("prefix")', 'venv'), + ('get_default_scheme()', 'venv'), + # build environment + ('is_python_build()', str(sysconfig.is_python_build())), + ('get_makefile_filename()', sysconfig.get_makefile_filename()), + ('get_config_h_filename()', sysconfig.get_config_h_filename())): + with self.subTest(call): + cmd[2] = 'import sysconfig; print(sysconfig.%s)' % call + out, err = check_output(cmd) + self.assertEqual(out.strip(), expected.encode(), err) + + @requireVenvCreate + @unittest.skipUnless(can_symlink(), 'Needs symlinks') + def test_sysconfig_symlinks(self): + """ + Test that the sysconfig functions work in a virtual environment. + """ + rmtree(self.env_dir) + self.run_with_capture(venv.create, self.env_dir, symlinks=True) + envpy = os.path.join(self.env_dir, self.bindir, self.exe) + cmd = [envpy, '-c', None] + for call, expected in ( + # installation scheme + ('get_preferred_scheme("prefix")', 'venv'), + ('get_default_scheme()', 'venv'), + # build environment + ('is_python_build()', str(sysconfig.is_python_build())), + ('get_makefile_filename()', sysconfig.get_makefile_filename()), + ('get_config_h_filename()', sysconfig.get_config_h_filename())): + with self.subTest(call): + cmd[2] = 'import sysconfig; print(sysconfig.%s)' % call + out, err = check_output(cmd) + self.assertEqual(out.strip(), expected.encode(), err) if sys.platform == 'win32': ENV_SUBDIRS = ( @@ -379,6 +482,20 @@ class BasicTest(BaseTest): 'pool.terminate()']) self.assertEqual(out.strip(), "python".encode()) + @requireVenvCreate + def test_multiprocessing_recursion(self): + """ + Test that the multiprocessing is able to spawn itself + """ + skip_if_broken_multiprocessing_synchronize() + + rmtree(self.env_dir) + self.run_with_capture(venv.create, self.env_dir) + envpy = os.path.join(os.path.realpath(self.env_dir), + self.bindir, self.exe) + script = os.path.join(TEST_HOME_DIR, '_test_venv_multiprocessing.py') + subprocess.check_call([envpy, script]) + @unittest.skipIf(os.name == 'nt', 'not relevant on Windows') def test_deactivate_with_strict_bash_opts(self): bash = shutil.which("bash") @@ -410,6 +527,90 @@ class BasicTest(BaseTest): 'import os; print("__PYVENV_LAUNCHER__" in os.environ)']) self.assertEqual(out.strip(), 'False'.encode()) + def test_pathsep_error(self): + """ + Test that venv creation fails when the target directory contains + the path separator. + """ + rmtree(self.env_dir) + bad_itempath = self.env_dir + os.pathsep + self.assertRaises(ValueError, venv.create, bad_itempath) + self.assertRaises(ValueError, venv.create, pathlib.Path(bad_itempath)) + + @unittest.skipIf(os.name == 'nt', 'not relevant on Windows') + @requireVenvCreate + def test_zippath_from_non_installed_posix(self): + """ + Test that when create venv from non-installed python, the zip path + value is as expected. + """ + rmtree(self.env_dir) + # First try to create a non-installed python. It's not a real full + # functional non-installed python, but enough for this test. + platlibdir = sys.platlibdir + non_installed_dir = os.path.realpath(tempfile.mkdtemp()) + self.addCleanup(rmtree, non_installed_dir) + bindir = os.path.join(non_installed_dir, self.bindir) + os.mkdir(bindir) + shutil.copy2(sys.executable, bindir) + libdir = os.path.join(non_installed_dir, platlibdir, self.lib[1]) + os.makedirs(libdir) + landmark = os.path.join(libdir, "os.py") + stdlib_zip = "python%d%d.zip" % sys.version_info[:2] + zip_landmark = os.path.join(non_installed_dir, + platlibdir, + stdlib_zip) + additional_pythonpath_for_non_installed = [] + # Copy stdlib files to the non-installed python so venv can + # correctly calculate the prefix. + for eachpath in sys.path: + if eachpath.endswith(".zip"): + if os.path.isfile(eachpath): + shutil.copyfile( + eachpath, + os.path.join(non_installed_dir, platlibdir)) + elif os.path.isfile(os.path.join(eachpath, "os.py")): + for name in os.listdir(eachpath): + if name == "site-packages": + continue + fn = os.path.join(eachpath, name) + if os.path.isfile(fn): + shutil.copy(fn, libdir) + elif os.path.isdir(fn): + shutil.copytree(fn, os.path.join(libdir, name)) + else: + additional_pythonpath_for_non_installed.append( + eachpath) + cmd = [os.path.join(non_installed_dir, self.bindir, self.exe), + "-m", + "venv", + "--without-pip", + self.env_dir] + # Our fake non-installed python is not fully functional because + # it cannot find the extensions. Set PYTHONPATH so it can run the + # venv module correctly. + pythonpath = os.pathsep.join( + additional_pythonpath_for_non_installed) + # For python built with shared enabled. We need to set + # LD_LIBRARY_PATH so the non-installed python can find and link + # libpython.so + ld_library_path = sysconfig.get_config_var("LIBDIR") + if not ld_library_path or sysconfig.is_python_build(): + ld_library_path = os.path.abspath(os.path.dirname(sys.executable)) + if sys.platform == 'darwin': + ld_library_path_env = "DYLD_LIBRARY_PATH" + else: + ld_library_path_env = "LD_LIBRARY_PATH" + subprocess.check_call(cmd, + env={"PYTHONPATH": pythonpath, + ld_library_path_env: ld_library_path}) + envpy = os.path.join(self.env_dir, self.bindir, self.exe) + # Now check the venv created from the non-installed python has + # correct zip path in pythonpath. + cmd = [envpy, '-S', '-c', 'import sys; print(sys.path)'] + out, err = check_output(cmd) + self.assertTrue(zip_landmark.encode() in out) + @requireVenvCreate class EnsurePipTest(BaseTest): """Test venv module installation of pip.""" @@ -478,16 +679,10 @@ class EnsurePipTest(BaseTest): # Actually run the create command with all that unhelpful # config in place to ensure we ignore it - try: + with self.nicer_error(): self.run_with_capture(venv.create, self.env_dir, system_site_packages=system_site_packages, with_pip=True) - except subprocess.CalledProcessError as exc: - # The output this produces can be a little hard to read, - # but at least it has all the details - details = exc.output.decode(errors="replace") - msg = "{}\n\n**Subprocess Output**\n{}" - self.fail(msg.format(exc, details)) # Ensure pip is available in the virtual environment envpy = os.path.join(os.path.realpath(self.env_dir), self.bindir, self.exe) # Ignore DeprecationWarning since pip code is not part of Python @@ -508,13 +703,14 @@ class EnsurePipTest(BaseTest): # Check the private uninstall command provided for the Windows # installers works (at least in a virtual environment) with EnvironmentVarGuard() as envvars: - # It seems ensurepip._uninstall calls subprocesses which do not - # inherit the interpreter settings. - envvars["PYTHONWARNINGS"] = "ignore" - out, err = check_output([envpy, - '-W', 'ignore::DeprecationWarning', - '-W', 'ignore::ImportWarning', '-I', - '-m', 'ensurepip._uninstall']) + with self.nicer_error(): + # It seems ensurepip._uninstall calls subprocesses which do not + # inherit the interpreter settings. + envvars["PYTHONWARNINGS"] = "ignore" + out, err = check_output([envpy, + '-W', 'ignore::DeprecationWarning', + '-W', 'ignore::ImportWarning', '-I', + '-m', 'ensurepip._uninstall']) # We force everything to text, so unittest gives the detailed diff # if we get unexpected results err = err.decode("latin-1") # Force to text, prevent decoding errors @@ -540,12 +736,30 @@ class EnsurePipTest(BaseTest): if not system_site_packages: self.assert_pip_not_installed() - # Issue #26610: pip/pep425tags.py requires ctypes - @unittest.skipUnless(ctypes, 'pip requires ctypes') - @requires_zlib() + @contextlib.contextmanager + def nicer_error(self): + """ + Capture output from a failed subprocess for easier debugging. + + The output this handler produces can be a little hard to read, + but at least it has all the details. + """ + try: + yield + except subprocess.CalledProcessError as exc: + out = (exc.output or b'').decode(errors="replace") + err = (exc.stderr or b'').decode(errors="replace") + self.fail( + f"{exc}\n\n" + f"**Subprocess Output**\n{out}\n\n" + f"**Subprocess Error**\n{err}" + ) + + @requires_venv_with_pip() def test_with_pip(self): self.do_test_with_pip(False) self.do_test_with_pip(True) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_wait3.py b/Lib/test/test_wait3.py index aa166baa400..eae885a6130 100644 --- a/Lib/test/test_wait3.py +++ b/Lib/test/test_wait3.py @@ -4,13 +4,12 @@ import os import subprocess import sys -import time import unittest from test.fork_wait import ForkWait from test import support -if not hasattr(os, 'fork'): - raise unittest.SkipTest("os.fork not defined") +if not support.has_fork_support: + raise unittest.SkipTest("requires working os.fork()") if not hasattr(os, 'wait3'): raise unittest.SkipTest("os.wait3 not defined") @@ -20,14 +19,12 @@ class Wait3Test(ForkWait): # This many iterations can be required, since some previously run # tests (e.g. test_ctypes) could have spawned a lot of children # very quickly. - deadline = time.monotonic() + support.SHORT_TIMEOUT - while time.monotonic() <= deadline: + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): # wait3() shouldn't hang, but some of the buildbots seem to hang # in the forking tests. This is an attempt to fix the problem. spid, status, rusage = os.wait3(os.WNOHANG) if spid == cpid: break - time.sleep(0.1) self.assertEqual(spid, cpid) self.assertEqual(os.waitstatus_to_exitcode(status), exitcode) diff --git a/Lib/test/test_wait4.py b/Lib/test/test_wait4.py index f8d5e13014f..67afab1d6f2 100644 --- a/Lib/test/test_wait4.py +++ b/Lib/test/test_wait4.py @@ -2,14 +2,15 @@ """ import os -import time import sys import unittest from test.fork_wait import ForkWait from test import support # If either of these do not exist, skip this test. -support.get_attribute(os, 'fork') +if not support.has_fork_support: + raise unittest.SkipTest("requires working os.fork()") + support.get_attribute(os, 'wait4') @@ -20,14 +21,12 @@ class Wait4Test(ForkWait): # Issue #11185: wait4 is broken on AIX and will always return 0 # with WNOHANG. option = 0 - deadline = time.monotonic() + support.SHORT_TIMEOUT - while time.monotonic() <= deadline: + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): # wait4() shouldn't hang, but some of the buildbots seem to hang # in the forking tests. This is an attempt to fix the problem. spid, status, rusage = os.wait4(cpid, option) if spid == cpid: break - time.sleep(0.1) self.assertEqual(spid, cpid) self.assertEqual(os.waitstatus_to_exitcode(status), exitcode) self.assertTrue(rusage) diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index 4b1b4e193cb..9e680c847da 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -12,6 +12,7 @@ from test.support import os_helper from test.support import warnings_helper from test.support.script_helper import assert_python_ok, assert_python_failure +from test.test_warnings.data import package_helper from test.test_warnings.data import stacklevel as warning_tests import warnings as original_warnings @@ -22,8 +23,6 @@ py_warnings = import_helper.import_fresh_module('warnings', c_warnings = import_helper.import_fresh_module('warnings', fresh=['_warnings']) -Py_DEBUG = hasattr(sys, 'gettotalrefcount') - @contextmanager def warnings_state(module): """Use a specific warnings implementation in warning_tests.""" @@ -373,6 +372,25 @@ class FilterTests(BaseTest): "appended duplicate changed order of filters" ) + def test_catchwarnings_with_simplefilter_ignore(self): + with original_warnings.catch_warnings(module=self.module): + self.module.resetwarnings() + self.module.simplefilter("error") + with self.module.catch_warnings( + module=self.module, action="ignore" + ): + self.module.warn("This will be ignored") + + def test_catchwarnings_with_simplefilter_error(self): + with original_warnings.catch_warnings(module=self.module): + self.module.resetwarnings() + with self.module.catch_warnings( + module=self.module, action="error", category=FutureWarning + ): + self.module.warn("Other types of warnings are not errors") + self.assertRaises(FutureWarning, + self.module.warn, FutureWarning("msg")) + class CFilterTests(FilterTests, unittest.TestCase): module = c_warnings @@ -455,6 +473,42 @@ class WarnTests(BaseTest): self.assertEqual(len(w), 1) self.assertEqual(w[0].filename, __file__) + def test_skip_file_prefixes(self): + with warnings_state(self.module): + with original_warnings.catch_warnings(record=True, + module=self.module) as w: + self.module.simplefilter('always') + + # Warning never attributed to the data/ package. + package_helper.inner_api( + "inner_api", stacklevel=2, + warnings_module=warning_tests.warnings) + self.assertEqual(w[-1].filename, __file__) + warning_tests.package("package api", stacklevel=2) + self.assertEqual(w[-1].filename, __file__) + self.assertEqual(w[-2].filename, w[-1].filename) + # Low stacklevels are overridden to 2 behavior. + warning_tests.package("package api 1", stacklevel=1) + self.assertEqual(w[-1].filename, __file__) + warning_tests.package("package api 0", stacklevel=0) + self.assertEqual(w[-1].filename, __file__) + warning_tests.package("package api -99", stacklevel=-99) + self.assertEqual(w[-1].filename, __file__) + + # The stacklevel still goes up out of the package. + warning_tests.package("prefix02", stacklevel=3) + self.assertIn("unittest", w[-1].filename) + + def test_skip_file_prefixes_type_errors(self): + with warnings_state(self.module): + warn = warning_tests.warnings.warn + with self.assertRaises(TypeError): + warn("msg", skip_file_prefixes=[]) + with self.assertRaises(TypeError): + warn("msg", skip_file_prefixes=(b"bytes",)) + with self.assertRaises(TypeError): + warn("msg", skip_file_prefixes="a sequence of strs") + def test_exec_filename(self): filename = "" codeobj = compile(("import warnings\n" @@ -470,7 +524,14 @@ class WarnTests(BaseTest): module=self.module) as w: self.module.resetwarnings() self.module.filterwarnings("always", category=UserWarning) - for filename in ("nonascii\xe9\u20ac", "surrogate\udc80"): + filenames = ["nonascii\xe9\u20ac"] + if not support.is_emscripten: + # JavaScript does not like surrogates. + # Invalid UTF-8 leading byte 0x80 encountered when + # deserializing a UTF-8 string in wasm memory to a JS + # string! + filenames.append("surrogate\udc80") + for filename in filenames: try: os.fsencode(filename) except UnicodeEncodeError: @@ -871,7 +932,7 @@ class WarningsDisplayTests(BaseTest): message = "msg" category = Warning file_name = os.path.splitext(warning_tests.__file__)[0] + '.py' - line_num = 3 + line_num = 5 file_line = linecache.getline(file_name, line_num).strip() format = "%s:%s: %s: %s\n %s\n" expect = format % (file_name, line_num, category.__name__, message, @@ -1172,7 +1233,7 @@ class EnvironmentVariableTests(BaseTest): def test_default_filter_configuration(self): pure_python_api = self.module is py_warnings - if Py_DEBUG: + if support.Py_DEBUG: expected_default_filters = [] else: if pure_python_api: @@ -1219,7 +1280,47 @@ class PyEnvironmentVariableTests(EnvironmentVariableTests, unittest.TestCase): module = py_warnings +class _DeprecatedTest(BaseTest, unittest.TestCase): + + """Test _deprecated().""" + + module = original_warnings + + def test_warning(self): + version = (3, 11, 0, "final", 0) + test = [(4, 12), (4, 11), (4, 0), (3, 12)] + for remove in test: + msg = rf".*test_warnings.*{remove[0]}\.{remove[1]}" + filter = msg, DeprecationWarning + with self.subTest(remove=remove): + with warnings_helper.check_warnings(filter, quiet=False): + self.module._deprecated("test_warnings", remove=remove, + _version=version) + + version = (3, 11, 0, "alpha", 0) + msg = r".*test_warnings.*3\.11" + with warnings_helper.check_warnings((msg, DeprecationWarning), quiet=False): + self.module._deprecated("test_warnings", remove=(3, 11), + _version=version) + + def test_RuntimeError(self): + version = (3, 11, 0, "final", 0) + test = [(2, 0), (2, 12), (3, 10)] + for remove in test: + with self.subTest(remove=remove): + with self.assertRaises(RuntimeError): + self.module._deprecated("test_warnings", remove=remove, + _version=version) + for level in ["beta", "candidate", "final"]: + version = (3, 11, 0, level, 0) + with self.subTest(releaselevel=level): + with self.assertRaises(RuntimeError): + self.module._deprecated("test_warnings", remove=(3, 11), + _version=version) + + class BootstrapTest(unittest.TestCase): + def test_issue_8766(self): # "import encodings" emits a warning whereas the warnings is not loaded # or not completely loaded (warnings imports indirectly encodings by diff --git a/Lib/test/test_warnings/data/package_helper.py b/Lib/test/test_warnings/data/package_helper.py new file mode 100644 index 00000000000..c22a4f6405c --- /dev/null +++ b/Lib/test/test_warnings/data/package_helper.py @@ -0,0 +1,10 @@ +# helper to the helper for testing skip_file_prefixes. + +import os + +package_path = os.path.dirname(__file__) + +def inner_api(message, *, stacklevel, warnings_module): + warnings_module.warn( + message, stacklevel=stacklevel, + skip_file_prefixes=(package_path,)) diff --git a/Lib/test/test_warnings/data/stacklevel.py b/Lib/test/test_warnings/data/stacklevel.py index d0519effdc8..c6dd24733b3 100644 --- a/Lib/test/test_warnings/data/stacklevel.py +++ b/Lib/test/test_warnings/data/stacklevel.py @@ -1,9 +1,15 @@ -# Helper module for testing the skipmodules argument of warnings.warn() +# Helper module for testing stacklevel and skip_file_prefixes arguments +# of warnings.warn() import warnings +from test.test_warnings.data import package_helper def outer(message, stacklevel=1): inner(message, stacklevel) def inner(message, stacklevel=1): warnings.warn(message, stacklevel=stacklevel) + +def package(message, *, stacklevel): + package_helper.inner_api(message, stacklevel=stacklevel, + warnings_module=warnings) diff --git a/Lib/test/test_wave.py b/Lib/test/test_wave.py index f85e40b31d0..6c3362857fc 100644 --- a/Lib/test/test_wave.py +++ b/Lib/test/test_wave.py @@ -1,7 +1,6 @@ import unittest from test import audiotests from test import support -from audioop import byteswap import io import struct import sys @@ -48,7 +47,7 @@ class WavePCM16Test(WaveTest, unittest.TestCase): E4B50CEB 63440A5A 08CA0A1F 2BBA0B0B 51460E47 8BCB113C B6F50EEA 44150A59 \ """) if sys.byteorder != 'big': - frames = byteswap(frames, 2) + frames = wave._byteswap(frames, 2) class WavePCM24Test(WaveTest, unittest.TestCase): @@ -75,7 +74,34 @@ class WavePCM24Test(WaveTest, unittest.TestCase): 51486F0E44E1 8BCC64113B05 B6F4EC0EEB36 4413170A5B48 \ """) if sys.byteorder != 'big': - frames = byteswap(frames, 3) + frames = wave._byteswap(frames, 3) + + +class WavePCM24ExtTest(WaveTest, unittest.TestCase): + sndfilename = 'pluck-pcm24-ext.wav' + sndfilenframes = 3307 + nchannels = 2 + sampwidth = 3 + framerate = 11025 + nframes = 48 + comptype = 'NONE' + compname = 'not compressed' + frames = bytes.fromhex("""\ + 022D65FFEB9D 4B5A0F00FA54 3113C304EE2B 80DCD6084303 \ + CBDEC006B261 48A99803F2F8 BFE82401B07D 036BFBFE7B5D \ + B85756FA3EC9 B4B055F3502B 299830EBCB62 1A5CA7E6D99A \ + EDFA3EE491BD C625EBE27884 0E05A9E0B6CF EF2929E02922 \ + 5758D8E27067 FB3557E83E16 1377BFEF8402 D82C5BF7272A \ + 978F16FB7745 F5F865FC1013 086635FB9C4E DF30FCFB40EE \ + 117FE0FA3438 3EE6B8FB5AC3 BC77A3FCB2F4 66D6DAFF5F32 \ + CF13B9041275 431D69097A8C C1BB600EC74E 5120B912A2BA \ + EEDF641754C0 8207001664B7 7FFFFF14453F 8000001294E6 \ + 499C1B0EB3B2 52B73E0DBCA0 EFB2B20F5FD8 CE3CDB0FBE12 \ + E4B49C0CEA2D 6344A80A5A7C 08C8FE0A1FFE 2BB9860B0A0E \ + 51486F0E44E1 8BCC64113B05 B6F4EC0EEB36 4413170A5B48 \ + """) + if sys.byteorder != 'big': + frames = wave._byteswap(frames, 3) class WavePCM32Test(WaveTest, unittest.TestCase): @@ -102,12 +128,13 @@ class WavePCM32Test(WaveTest, unittest.TestCase): 51486F800E44E190 8BCC6480113B0580 B6F4EC000EEB3630 441317800A5B48A0 \ """) if sys.byteorder != 'big': - frames = byteswap(frames, 4) + frames = wave._byteswap(frames, 4) class MiscTestCase(unittest.TestCase): def test__all__(self): - support.check__all__(self, wave, not_exported={'WAVE_FORMAT_PCM'}) + not_exported = {'WAVE_FORMAT_PCM', 'WAVE_FORMAT_EXTENSIBLE', 'KSDATAFORMAT_SUBTYPE_PCM'} + support.check__all__(self, wave, not_exported=not_exported) class WaveLowLevelTest(unittest.TestCase): diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index 46dac022829..7c5920797d2 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -14,6 +14,7 @@ import random from test import support from test.support import script_helper, ALWAYS_EQ from test.support import gc_collect +from test.support import threading_helper # Used in ReferencesTestCase.test_ref_created_during_del() . ref_from_del = None @@ -596,7 +597,7 @@ class ReferencesTestCase(TestBase): # deallocation of c2. del c2 - def test_callback_in_cycle_1(self): + def test_callback_in_cycle(self): import gc class J(object): @@ -636,40 +637,11 @@ class ReferencesTestCase(TestBase): del I, J, II gc.collect() - def test_callback_in_cycle_2(self): + def test_callback_reachable_one_way(self): import gc - # This is just like test_callback_in_cycle_1, except that II is an - # old-style class. The symptom is different then: an instance of an - # old-style class looks in its own __dict__ first. 'J' happens to - # get cleared from I.__dict__ before 'wr', and 'J' was never in II's - # __dict__, so the attribute isn't found. The difference is that - # the old-style II doesn't have a NULL __mro__ (it doesn't have any - # __mro__), so no segfault occurs. Instead it got: - # test_callback_in_cycle_2 (__main__.ReferencesTestCase) ... - # Exception exceptions.AttributeError: - # "II instance has no attribute 'J'" in > ignored - - class J(object): - pass - - class II: - def acallback(self, ignore): - self.J - - I = II() - I.J = J - I.wr = weakref.ref(J, I.acallback) - - del I, J, II - gc.collect() - - def test_callback_in_cycle_3(self): - import gc - - # This one broke the first patch that fixed the last two. In this - # case, the objects reachable from the callback aren't also reachable + # This one broke the first patch that fixed the previous test. In this case, + # the objects reachable from the callback aren't also reachable # from the object (c1) *triggering* the callback: you can get to # c1 from c2, but not vice-versa. The result was that c2's __dict__ # got tp_clear'ed by the time the c2.cb callback got invoked. @@ -689,10 +661,10 @@ class ReferencesTestCase(TestBase): del c1, c2 gc.collect() - def test_callback_in_cycle_4(self): + def test_callback_different_classes(self): import gc - # Like test_callback_in_cycle_3, except c2 and c1 have different + # Like test_callback_reachable_one_way, except c2 and c1 have different # classes. c2's class (C) isn't reachable from c1 then, so protecting # objects reachable from the dying object (c1) isn't enough to stop # c2's class (C) from getting tp_clear'ed before c2.cb is invoked. @@ -1851,6 +1823,7 @@ class MappingTestCase(TestBase): dict = weakref.WeakKeyDictionary() self.assertRegex(repr(dict), '') + @threading_helper.requires_working_threading() def test_threaded_weak_valued_setdefault(self): d = weakref.WeakValueDictionary() with collect_in_thread(): @@ -1859,6 +1832,7 @@ class MappingTestCase(TestBase): self.assertIsNot(x, None) # we never put None in there! del x + @threading_helper.requires_working_threading() def test_threaded_weak_valued_pop(self): d = weakref.WeakValueDictionary() with collect_in_thread(): @@ -1867,6 +1841,7 @@ class MappingTestCase(TestBase): x = d.pop(10, 10) self.assertIsNot(x, None) # we never put None in there! + @threading_helper.requires_working_threading() def test_threaded_weak_valued_consistency(self): # Issue #28427: old keys should not remove new values from # WeakValueDictionary when collecting from another thread. @@ -1940,21 +1915,25 @@ class MappingTestCase(TestBase): if exc: raise exc[0] + @threading_helper.requires_working_threading() def test_threaded_weak_key_dict_copy(self): # Issue #35615: Weakref keys or values getting GC'ed during dict # copying should not result in a crash. self.check_threaded_weak_dict_copy(weakref.WeakKeyDictionary, False) + @threading_helper.requires_working_threading() def test_threaded_weak_key_dict_deepcopy(self): # Issue #35615: Weakref keys or values getting GC'ed during dict # copying should not result in a crash. self.check_threaded_weak_dict_copy(weakref.WeakKeyDictionary, True) + @threading_helper.requires_working_threading() def test_threaded_weak_value_dict_copy(self): # Issue #35615: Weakref keys or values getting GC'ed during dict # copying should not result in a crash. self.check_threaded_weak_dict_copy(weakref.WeakValueDictionary, False) + @threading_helper.requires_working_threading() def test_threaded_weak_value_dict_deepcopy(self): # Issue #35615: Weakref keys or values getting GC'ed during dict # copying should not result in a crash. @@ -2146,6 +2125,17 @@ class FinalizeTestCase(unittest.TestCase): self.assertTrue(b'ZeroDivisionError' in err) +class ModuleTestCase(unittest.TestCase): + def test_names(self): + for name in ('ReferenceType', 'ProxyType', 'CallableProxyType', + 'WeakMethod', 'WeakSet', 'WeakKeyDictionary', 'WeakValueDictionary'): + obj = getattr(weakref, name) + if name != 'WeakSet': + self.assertEqual(obj.__module__, 'weakref') + self.assertEqual(obj.__name__, name) + self.assertEqual(obj.__qualname__, name) + + libreftest = """ Doctest for examples in the library reference: weakref.rst >>> from test.support import gc_collect diff --git a/Lib/test/test_weakset.py b/Lib/test/test_weakset.py index 9b31d5fce34..d6c88596cff 100644 --- a/Lib/test/test_weakset.py +++ b/Lib/test/test_weakset.py @@ -1,5 +1,6 @@ import unittest from weakref import WeakSet +import copy import string from collections import UserString as ustr from collections.abc import Set, MutableSet @@ -15,6 +16,12 @@ class RefCycle: def __init__(self): self.cycle = self +class WeakSetSubclass(WeakSet): + pass + +class WeakSetWithSlots(WeakSet): + __slots__ = ('x', 'y') + class TestWeakSet(unittest.TestCase): @@ -447,6 +454,30 @@ class TestWeakSet(unittest.TestCase): self.assertIsInstance(self.s, Set) self.assertIsInstance(self.s, MutableSet) + def test_copying(self): + for cls in WeakSet, WeakSetWithSlots: + s = cls(self.items) + s.x = ['x'] + s.z = ['z'] + + dup = copy.copy(s) + self.assertIsInstance(dup, cls) + self.assertEqual(dup, s) + self.assertIsNot(dup, s) + self.assertIs(dup.x, s.x) + self.assertIs(dup.z, s.z) + self.assertFalse(hasattr(dup, 'y')) + + dup = copy.deepcopy(s) + self.assertIsInstance(dup, cls) + self.assertEqual(dup, s) + self.assertIsNot(dup, s) + self.assertEqual(dup.x, s.x) + self.assertIsNot(dup.x, s.x) + self.assertEqual(dup.z, s.z) + self.assertIsNot(dup.z, s.z) + self.assertFalse(hasattr(dup, 'y')) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py index 673cc995d3f..9d608d63a01 100644 --- a/Lib/test/test_webbrowser.py +++ b/Lib/test/test_webbrowser.py @@ -8,6 +8,8 @@ from test import support from test.support import import_helper from test.support import os_helper +if not support.has_subprocess_support: + raise unittest.SkipTest("test webserver requires subprocess") URL = 'http://www.example.com' CMD_NAME = 'test' @@ -304,7 +306,7 @@ class ImportTest(unittest.TestCase): webbrowser = import_helper.import_fresh_module('webbrowser') try: browser = webbrowser.get().name - except (webbrowser.Error, AttributeError) as err: + except webbrowser.Error as err: self.skipTest(str(err)) with os_helper.EnvironmentVarGuard() as env: env["BROWSER"] = browser @@ -316,7 +318,7 @@ class ImportTest(unittest.TestCase): try: webbrowser.get() least_preferred_browser = webbrowser.get(webbrowser._tryorder[-1]).name - except (webbrowser.Error, AttributeError, IndexError) as err: + except (webbrowser.Error, IndexError) as err: self.skipTest(str(err)) with os_helper.EnvironmentVarGuard() as env: diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index 8157c2da6ef..769ab67b0f5 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -113,7 +113,6 @@ class BaseWinregTests(unittest.TestCase): "does not close the actual key!") except OSError: pass - def _read_test_data(self, root_key, subkeystr="sub_key", OpenKey=OpenKey): # Check we can get default value for this key. val = QueryValue(root_key, test_key_name) @@ -340,6 +339,23 @@ class LocalWinregTests(BaseWinregTests): finally: DeleteKey(HKEY_CURRENT_USER, test_key_name) + def test_setvalueex_negative_one_check(self): + # Test for Issue #43984, check -1 was not set by SetValueEx. + # Py2Reg, which gets called by SetValueEx, wasn't checking return + # value by PyLong_AsUnsignedLong, thus setting -1 as value in the registry. + # The implementation now checks PyLong_AsUnsignedLong return value to assure + # the value set was not -1. + try: + with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck: + with self.assertRaises(OverflowError): + SetValueEx(ck, "test_name_dword", None, REG_DWORD, -1) + SetValueEx(ck, "test_name_qword", None, REG_QWORD, -1) + self.assertRaises(FileNotFoundError, QueryValueEx, ck, "test_name_dword") + self.assertRaises(FileNotFoundError, QueryValueEx, ck, "test_name_qword") + + finally: + DeleteKey(HKEY_CURRENT_USER, test_key_name) + def test_queryvalueex_return_value(self): # Test for Issue #16759, return unsigned int from QueryValueEx. # Reg2Py, which gets called by QueryValueEx, was returning a value diff --git a/Lib/test/test_winsound.py b/Lib/test/test_winsound.py index 3c3359b9004..a59d0d24f5d 100644 --- a/Lib/test/test_winsound.py +++ b/Lib/test/test_winsound.py @@ -1,6 +1,7 @@ # Ridiculously simple test of the winsound module for Windows. import functools +import pathlib import time import unittest @@ -84,6 +85,13 @@ class MessageBeepTest(unittest.TestCase): safe_MessageBeep(type=winsound.MB_OK) +# A class for testing winsound when the given path resolves +# to bytes rather than str. +class BytesPath(pathlib.WindowsPath): + def __fspath__(self): + return bytes(super().__fspath__(), 'UTF-8') + + class PlaySoundTest(unittest.TestCase): def test_errors(self): @@ -116,6 +124,20 @@ class PlaySoundTest(unittest.TestCase): fn = support.findfile('pluck-pcm8.wav', subdir='audiodata') safe_PlaySound(fn, winsound.SND_FILENAME | winsound.SND_NODEFAULT) + def test_snd_filepath(self): + fn = support.findfile('pluck-pcm8.wav', subdir='audiodata') + path = pathlib.Path(fn) + safe_PlaySound(path, winsound.SND_FILENAME | winsound.SND_NODEFAULT) + + def test_snd_filepath_as_bytes(self): + fn = support.findfile('pluck-pcm8.wav', subdir='audiodata') + self.assertRaises( + TypeError, + winsound.PlaySound, + BytesPath(fn), + winsound.SND_FILENAME | winsound.SND_NODEFAULT + ) + def test_aliases(self): aliases = [ "SystemAsterisk", diff --git a/Lib/test/test_wmi.py b/Lib/test/test_wmi.py new file mode 100644 index 00000000000..3f579595290 --- /dev/null +++ b/Lib/test/test_wmi.py @@ -0,0 +1,75 @@ +# Test the internal _wmi module on Windows +# This is used by the platform module, and potentially others + +import sys +import unittest +from test.support import import_helper, requires_resource + + +# Do this first so test will be skipped if module doesn't exist +_wmi = import_helper.import_module('_wmi', required_on=['win']) + + +class WmiTests(unittest.TestCase): + def test_wmi_query_os_version(self): + r = _wmi.exec_query("SELECT Version FROM Win32_OperatingSystem").split("\0") + self.assertEqual(1, len(r)) + k, eq, v = r[0].partition("=") + self.assertEqual("=", eq, r[0]) + self.assertEqual("Version", k, r[0]) + # Best we can check for the version is that it's digits, dot, digits, anything + # Otherwise, we are likely checking the result of the query against itself + self.assertRegex(v, r"\d+\.\d+.+$", r[0]) + + def test_wmi_query_repeated(self): + # Repeated queries should not break + for _ in range(10): + self.test_wmi_query_os_version() + + def test_wmi_query_error(self): + # Invalid queries fail with OSError + try: + _wmi.exec_query("SELECT InvalidColumnName FROM InvalidTableName") + except OSError as ex: + if ex.winerror & 0xFFFFFFFF == 0x80041010: + # This is the expected error code. All others should fail the test + return + self.fail("Expected OSError") + + def test_wmi_query_repeated_error(self): + for _ in range(10): + self.test_wmi_query_error() + + def test_wmi_query_not_select(self): + # Queries other than SELECT are blocked to avoid potential exploits + with self.assertRaises(ValueError): + _wmi.exec_query("not select, just in case someone tries something") + + @requires_resource('cpu') + def test_wmi_query_overflow(self): + # Ensure very big queries fail + # Test multiple times to ensure consistency + for _ in range(2): + with self.assertRaises(OSError): + _wmi.exec_query("SELECT * FROM CIM_DataFile") + + def test_wmi_query_multiple_rows(self): + # Multiple instances should have an extra null separator + r = _wmi.exec_query("SELECT ProcessId FROM Win32_Process WHERE ProcessId < 1000") + self.assertFalse(r.startswith("\0"), r) + self.assertFalse(r.endswith("\0"), r) + it = iter(r.split("\0")) + try: + while True: + self.assertRegex(next(it), r"ProcessId=\d+") + self.assertEqual("", next(it)) + except StopIteration: + pass + + def test_wmi_query_threads(self): + from concurrent.futures import ThreadPoolExecutor + query = "SELECT ProcessId FROM Win32_Process WHERE ProcessId < 1000" + with ThreadPoolExecutor(4) as pool: + task = [pool.submit(_wmi.exec_query, query) for _ in range(32)] + for t in task: + self.assertRegex(t.result(), "ProcessId=") diff --git a/Lib/test/test_xdrlib.py b/Lib/test/test_xdrlib.py index 3df5f264ced..226b70ae87b 100644 --- a/Lib/test/test_xdrlib.py +++ b/Lib/test/test_xdrlib.py @@ -1,6 +1,8 @@ import unittest +from test.support import warnings_helper + +xdrlib = warnings_helper.import_deprecated("xdrlib") -import xdrlib class XDRTest(unittest.TestCase): diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 285559a872a..ca5bb562996 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -10,7 +10,6 @@ import functools import html import io import itertools -import locale import operator import os import pickle @@ -130,6 +129,9 @@ def checkwarnings(*filters, quiet=False): return newtest return decorator +def convlinesep(data): + return data.replace(b'\n', os.linesep.encode()) + class ModuleTest(unittest.TestCase): def test_sanity(self): @@ -658,6 +660,14 @@ class ElementTreeTest(unittest.TestCase): 'junk after document element: line 1, column 12') del cm, it + # Not exhausting the iterator still closes the resource (bpo-43292) + with warnings_helper.check_no_resource_warning(self): + it = iterparse(TESTFN) + del it + + with self.assertRaises(FileNotFoundError): + iterparse("nonexistent") + def test_writefile(self): elem = ET.Element("tag") elem.text = "text" @@ -758,6 +768,15 @@ class ElementTreeTest(unittest.TestCase): ('end-ns', ''), ]) + def test_initialize_parser_without_target(self): + # Explicit None + parser = ET.XMLParser(target=None) + self.assertIsInstance(parser.target, ET.TreeBuilder) + + # Implicit None + parser2 = ET.XMLParser() + self.assertIsInstance(parser2.target, ET.TreeBuilder) + def test_children(self): # Test Element children iteration @@ -958,15 +977,13 @@ class ElementTreeTest(unittest.TestCase): def test_tostring_xml_declaration_unicode_encoding(self): elem = ET.XML('') - preferredencoding = locale.getpreferredencoding() self.assertEqual( - f"\n", - ET.tostring(elem, encoding='unicode', xml_declaration=True) + ET.tostring(elem, encoding='unicode', xml_declaration=True), + "\n" ) def test_tostring_xml_declaration_cases(self): elem = ET.XML('ø') - preferredencoding = locale.getpreferredencoding() TESTCASES = [ # (expected_retval, encoding, xml_declaration) # ... xml_declaration = None @@ -993,7 +1010,7 @@ class ElementTreeTest(unittest.TestCase): b"ø", 'US-ASCII', True), (b"\n" b"\xf8", 'ISO-8859-1', True), - (f"\n" + ("\n" "ø", 'unicode', True), ] @@ -1031,11 +1048,10 @@ class ElementTreeTest(unittest.TestCase): b"\n" ) - preferredencoding = locale.getpreferredencoding() stringlist = ET.tostringlist(elem, encoding='unicode', xml_declaration=True) self.assertEqual( ''.join(stringlist), - f"\n" + "\n" ) self.assertRegex(stringlist[0], r"^<\?xml version='1.0' encoding='.+'?>") self.assertEqual(['', '', ''], stringlist[1:]) @@ -1341,8 +1357,9 @@ class ElementTreeTest(unittest.TestCase): def test_html_empty_elems_serialization(self): # issue 15970 # from http://www.w3.org/TR/html401/index/elements.html - for element in ['AREA', 'BASE', 'BASEFONT', 'BR', 'COL', 'FRAME', 'HR', - 'IMG', 'INPUT', 'ISINDEX', 'LINK', 'META', 'PARAM']: + for element in ['AREA', 'BASE', 'BASEFONT', 'BR', 'COL', 'EMBED', 'FRAME', + 'HR', 'IMG', 'INPUT', 'ISINDEX', 'LINK', 'META', 'PARAM', + 'SOURCE', 'TRACK', 'WBR']: for elem in [element, element.lower()]: expected = '<%s>' % elem serialized = serialize(ET.XML('<%s />' % elem), method='html') @@ -2183,12 +2200,6 @@ class BugsTest(unittest.TestCase): b"\n" b'tãg') - def test_issue3151(self): - e = ET.XML('') - self.assertEqual(e.tag, '{${stuff}}localname') - t = ET.ElementTree(e) - self.assertEqual(ET.tostring(e), b'') - def test_issue6565(self): elem = ET.XML("") self.assertEqual(summarize_list(elem), ['tag']) @@ -2322,35 +2333,6 @@ class BasicElementTest(ElementTestCase, unittest.TestCase): self.assertIsNot(element_foo.attrib, attrib) self.assertNotEqual(element_foo.attrib, attrib) - def test_copy(self): - # Only run this test if Element.copy() is defined. - if "copy" not in dir(ET.Element): - raise unittest.SkipTest("Element.copy() not present") - - element_foo = ET.Element("foo", { "zix": "wyp" }) - element_foo.append(ET.Element("bar", { "baz": "qix" })) - - with self.assertWarns(DeprecationWarning): - element_foo2 = element_foo.copy() - - # elements are not the same - self.assertIsNot(element_foo2, element_foo) - - # string attributes are equal - self.assertEqual(element_foo2.tag, element_foo.tag) - self.assertEqual(element_foo2.text, element_foo.text) - self.assertEqual(element_foo2.tail, element_foo.tail) - - # number of children is the same - self.assertEqual(len(element_foo2), len(element_foo)) - - # children are the same - for (child1, child2) in itertools.zip_longest(element_foo, element_foo2): - self.assertIs(child1, child2) - - # attrib is a copy - self.assertEqual(element_foo2.attrib, element_foo.attrib) - def test___copy__(self): element_foo = ET.Element("foo", { "zix": "wyp" }) element_foo.append(ET.Element("bar", { "baz": "qix" })) @@ -2512,8 +2494,7 @@ class BasicElementTest(ElementTestCase, unittest.TestCase): 4 """ e1 = dumper.fromstring(XMLTEXT) - if hasattr(e1, '__getstate__'): - self.assertEqual(e1.__getstate__()['tag'], 'group') + self.assertEqual(e1.__getstate__()['tag'], 'group') e2 = self.pickleRoundTrip(e1, 'xml.etree.ElementTree', dumper, loader, proto) self.assertEqual(e2.tag, 'group') @@ -2724,6 +2705,20 @@ class BadElementPathTest(ElementTestCase, unittest.TestCase): except ZeroDivisionError: pass + def test_findtext_with_falsey_text_attribute(self): + root_elem = ET.Element('foo') + sub_elem = ET.SubElement(root_elem, 'bar') + falsey = ["", 0, False, [], (), {}] + for val in falsey: + sub_elem.text = val + self.assertEqual(root_elem.findtext('./bar'), val) + + def test_findtext_with_none_text_attribute(self): + root_elem = ET.Element('foo') + sub_elem = ET.SubElement(root_elem, 'bar') + sub_elem.text = None + self.assertEqual(root_elem.findtext('./bar'), '') + def test_findall_with_mutating(self): e = ET.Element('foo') e.extend([ET.Element('bar')]) @@ -3702,32 +3697,85 @@ class IOTest(unittest.TestCase): def test_write_to_filename(self): self.addCleanup(os_helper.unlink, TESTFN) - tree = ET.ElementTree(ET.XML('''''')) + tree = ET.ElementTree(ET.XML('''\xf8''')) tree.write(TESTFN) with open(TESTFN, 'rb') as f: - self.assertEqual(f.read(), b'''''') + self.assertEqual(f.read(), b'''ø''') + + def test_write_to_filename_with_encoding(self): + self.addCleanup(os_helper.unlink, TESTFN) + tree = ET.ElementTree(ET.XML('''\xf8''')) + tree.write(TESTFN, encoding='utf-8') + with open(TESTFN, 'rb') as f: + self.assertEqual(f.read(), b'''\xc3\xb8''') + + tree.write(TESTFN, encoding='ISO-8859-1') + with open(TESTFN, 'rb') as f: + self.assertEqual(f.read(), convlinesep( + b'''\n''' + b'''\xf8''')) + + def test_write_to_filename_as_unicode(self): + self.addCleanup(os_helper.unlink, TESTFN) + with open(TESTFN, 'w') as f: + encoding = f.encoding + os_helper.unlink(TESTFN) + + tree = ET.ElementTree(ET.XML('''\xf8''')) + tree.write(TESTFN, encoding='unicode') + with open(TESTFN, 'rb') as f: + self.assertEqual(f.read(), b"\xc3\xb8") def test_write_to_text_file(self): self.addCleanup(os_helper.unlink, TESTFN) - tree = ET.ElementTree(ET.XML('''''')) + tree = ET.ElementTree(ET.XML('''\xf8''')) with open(TESTFN, 'w', encoding='utf-8') as f: tree.write(f, encoding='unicode') self.assertFalse(f.closed) with open(TESTFN, 'rb') as f: - self.assertEqual(f.read(), b'''''') + self.assertEqual(f.read(), b'''\xc3\xb8''') + + with open(TESTFN, 'w', encoding='ascii', errors='xmlcharrefreplace') as f: + tree.write(f, encoding='unicode') + self.assertFalse(f.closed) + with open(TESTFN, 'rb') as f: + self.assertEqual(f.read(), b'''ø''') + + with open(TESTFN, 'w', encoding='ISO-8859-1') as f: + tree.write(f, encoding='unicode') + self.assertFalse(f.closed) + with open(TESTFN, 'rb') as f: + self.assertEqual(f.read(), b'''\xf8''') def test_write_to_binary_file(self): self.addCleanup(os_helper.unlink, TESTFN) - tree = ET.ElementTree(ET.XML('''''')) + tree = ET.ElementTree(ET.XML('''\xf8''')) with open(TESTFN, 'wb') as f: tree.write(f) self.assertFalse(f.closed) with open(TESTFN, 'rb') as f: - self.assertEqual(f.read(), b'''''') + self.assertEqual(f.read(), b'''ø''') + + def test_write_to_binary_file_with_encoding(self): + self.addCleanup(os_helper.unlink, TESTFN) + tree = ET.ElementTree(ET.XML('''\xf8''')) + with open(TESTFN, 'wb') as f: + tree.write(f, encoding='utf-8') + self.assertFalse(f.closed) + with open(TESTFN, 'rb') as f: + self.assertEqual(f.read(), b'''\xc3\xb8''') + + with open(TESTFN, 'wb') as f: + tree.write(f, encoding='ISO-8859-1') + self.assertFalse(f.closed) + with open(TESTFN, 'rb') as f: + self.assertEqual(f.read(), + b'''\n''' + b'''\xf8''') def test_write_to_binary_file_with_bom(self): self.addCleanup(os_helper.unlink, TESTFN) - tree = ET.ElementTree(ET.XML('''''')) + tree = ET.ElementTree(ET.XML('''\xf8''')) # test BOM writing to buffered file with open(TESTFN, 'wb') as f: tree.write(f, encoding='utf-16') @@ -3735,7 +3783,7 @@ class IOTest(unittest.TestCase): with open(TESTFN, 'rb') as f: self.assertEqual(f.read(), '''\n''' - ''''''.encode("utf-16")) + '''\xf8'''.encode("utf-16")) # test BOM writing to non-buffered file with open(TESTFN, 'wb', buffering=0) as f: tree.write(f, encoding='utf-16') @@ -3743,7 +3791,7 @@ class IOTest(unittest.TestCase): with open(TESTFN, 'rb') as f: self.assertEqual(f.read(), '''\n''' - ''''''.encode("utf-16")) + '''\xf8'''.encode("utf-16")) def test_read_from_stringio(self): tree = ET.ElementTree() @@ -3752,10 +3800,10 @@ class IOTest(unittest.TestCase): self.assertEqual(tree.getroot().tag, 'site') def test_write_to_stringio(self): - tree = ET.ElementTree(ET.XML('''''')) + tree = ET.ElementTree(ET.XML('''\xf8''')) stream = io.StringIO() tree.write(stream, encoding='unicode') - self.assertEqual(stream.getvalue(), '''''') + self.assertEqual(stream.getvalue(), '''\xf8''') def test_read_from_bytesio(self): tree = ET.ElementTree() @@ -3764,10 +3812,10 @@ class IOTest(unittest.TestCase): self.assertEqual(tree.getroot().tag, 'site') def test_write_to_bytesio(self): - tree = ET.ElementTree(ET.XML('''''')) + tree = ET.ElementTree(ET.XML('''\xf8''')) raw = io.BytesIO() tree.write(raw) - self.assertEqual(raw.getvalue(), b'''''') + self.assertEqual(raw.getvalue(), b'''ø''') class dummy: pass @@ -3781,12 +3829,12 @@ class IOTest(unittest.TestCase): self.assertEqual(tree.getroot().tag, 'site') def test_write_to_user_text_writer(self): - tree = ET.ElementTree(ET.XML('''''')) + tree = ET.ElementTree(ET.XML('''\xf8''')) stream = io.StringIO() writer = self.dummy() writer.write = stream.write tree.write(writer, encoding='unicode') - self.assertEqual(stream.getvalue(), '''''') + self.assertEqual(stream.getvalue(), '''\xf8''') def test_read_from_user_binary_reader(self): raw = io.BytesIO(b'''''') @@ -3798,12 +3846,12 @@ class IOTest(unittest.TestCase): tree = ET.ElementTree() def test_write_to_user_binary_writer(self): - tree = ET.ElementTree(ET.XML('''''')) + tree = ET.ElementTree(ET.XML('''\xf8''')) raw = io.BytesIO() writer = self.dummy() writer.write = raw.write tree.write(writer) - self.assertEqual(raw.getvalue(), b'''''') + self.assertEqual(raw.getvalue(), b'''ø''') def test_write_to_user_binary_writer_with_bom(self): tree = ET.ElementTree(ET.XML('''''')) @@ -3909,6 +3957,25 @@ class NoAcceleratorTest(unittest.TestCase): self.assertIsInstance(pyET.Element.__init__, types.FunctionType) self.assertIsInstance(pyET.XMLParser.__init__, types.FunctionType) +# -------------------------------------------------------------------- + +class BoolTest(unittest.TestCase): + def test_warning(self): + e = ET.fromstring('') + msg = ( + r"Testing an element's truth value will raise an exception in " + r"future versions. " + r"Use specific 'len\(elem\)' or 'elem is not None' test instead.") + with self.assertWarnsRegex(DeprecationWarning, msg): + result = bool(e) + # Emulate prior behavior for now + self.assertIs(result, False) + + # Element with children + ET.SubElement(e, 'b') + with self.assertWarnsRegex(DeprecationWarning, msg): + new_result = bool(e) + self.assertIs(new_result, True) # -------------------------------------------------------------------- @@ -4175,6 +4242,7 @@ def test_main(module=None): XMLPullParserTest, BugsTest, KeywordArgsTest, + BoolTest, C14NTest, ] diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py index e68613bb910..fd27b575ec8 100644 --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -169,6 +169,38 @@ class MiscTests(unittest.TestCase): del parser support.gc_collect() + def test_dict_disappearing_during_get_item(self): + # test fix for seg fault reported in issue 27946 + class X: + def __hash__(self): + e.attrib = {} # this frees e->extra->attrib + [{i: i} for i in range(1000)] # exhaust the dict keys cache + return 13 + + e = cET.Element("elem", {1: 2}) + r = e.get(X()) + self.assertIsNone(r) + + @support.cpython_only + def test_immutable_types(self): + root = cET.fromstring('') + dataset = ( + cET.Element, + cET.TreeBuilder, + cET.XMLParser, + type(root.iter()), + ) + for tp in dataset: + with self.subTest(tp=tp): + with self.assertRaisesRegex(TypeError, "immutable"): + tp.foo = 1 + + @support.cpython_only + def test_disallow_instantiation(self): + root = cET.fromstring('') + iter_type = type(root.iter()) + support.check_disallow_instantiation(self, iter_type) + @unittest.skipUnless(cET, 'requires _elementtree') class TestAliasWorking(unittest.TestCase): diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py index 1f06f5fdf48..9ff5545f786 100644 --- a/Lib/test/test_xmlrpc.py +++ b/Lib/test/test_xmlrpc.py @@ -25,6 +25,8 @@ try: except ImportError: gzip = None +support.requires_working_socket(module=True) + alist = [{'astring': 'foo@bar.baz.spam', 'afloat': 7283.43, 'anint': 2**20, @@ -287,6 +289,16 @@ class XMLRPCTestCase(unittest.TestCase): check('9876543210.0123456789', decimal.Decimal('9876543210.0123456789')) + def test_limit_int(self): + check = self.check_loads + maxdigits = 5000 + with support.adjust_int_max_str_digits(maxdigits): + s = '1' * (maxdigits + 1) + with self.assertRaises(ValueError): + check(f'{s}', None) + with self.assertRaises(ValueError): + check(f'{s}', None) + def test_get_host_info(self): # see bug #3613, this raised a TypeError transp = xmlrpc.client.Transport() diff --git a/Lib/test/test_xxlimited.py b/Lib/test/test_xxlimited.py index e3f521d9b04..6dbfb3f4393 100644 --- a/Lib/test/test_xxlimited.py +++ b/Lib/test/test_xxlimited.py @@ -58,6 +58,17 @@ class TestXXLimited(CommonTests, unittest.TestCase): with self.assertRaises(self.module.Error): raise self.module.Error + def test_buffer(self): + xxo = self.module.Xxo() + self.assertEqual(xxo.x_exports, 0) + b1 = memoryview(xxo) + self.assertEqual(xxo.x_exports, 1) + b2 = memoryview(xxo) + self.assertEqual(xxo.x_exports, 2) + b1[0] = 1 + self.assertEqual(b1[0], 1) + self.assertEqual(b2[0], 1) + class TestXXLimited35(CommonTests, unittest.TestCase): module = xxlimited_35 diff --git a/Lib/test/test_yield_from.py b/Lib/test/test_yield_from.py index d105d8c6eb5..1a60357a1bc 100644 --- a/Lib/test/test_yield_from.py +++ b/Lib/test/test_yield_from.py @@ -1049,6 +1049,533 @@ class TestPEP380Operation(unittest.TestCase): g.send((1, 2, 3, 4)) self.assertEqual(v, (1, 2, 3, 4)) +class TestInterestingEdgeCases(unittest.TestCase): + + def assert_stop_iteration(self, iterator): + with self.assertRaises(StopIteration) as caught: + next(iterator) + self.assertIsNone(caught.exception.value) + self.assertIsNone(caught.exception.__context__) + + def assert_generator_raised_stop_iteration(self): + return self.assertRaisesRegex(RuntimeError, r"^generator raised StopIteration$") + + def assert_generator_ignored_generator_exit(self): + return self.assertRaisesRegex(RuntimeError, r"^generator ignored GeneratorExit$") + + def test_close_and_throw_work(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + yield yielded_first + yield yielded_second + return returned + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + g.close() + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = GeneratorExit() + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + self.assertIs(caught.exception, thrown) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = StopIteration() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.throw(thrown) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = BaseException() + with self.assertRaises(BaseException) as caught: + g.throw(thrown) + self.assertIs(caught.exception, thrown) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = Exception() + with self.assertRaises(Exception) as caught: + g.throw(thrown) + self.assertIs(caught.exception, thrown) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + def test_close_and_throw_raise_generator_exit(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + yield yielded_second + return returned + finally: + raise raised + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = GeneratorExit() + # GeneratorExit is suppressed. This is consistent with PEP 342: + # https://peps.python.org/pep-0342/#new-generator-method-close + g.close() + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = GeneratorExit() + thrown = GeneratorExit() + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + # The raised GeneratorExit is suppressed, but the thrown one + # propagates. This is consistent with PEP 380: + # https://peps.python.org/pep-0380/#proposal + self.assertIs(caught.exception, thrown) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = GeneratorExit() + thrown = StopIteration() + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = GeneratorExit() + thrown = BaseException() + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = GeneratorExit() + thrown = Exception() + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + def test_close_and_throw_raise_stop_iteration(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + yield yielded_second + return returned + finally: + raise raised + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = StopIteration() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.close() + self.assertIs(caught.exception.__context__, raised) + self.assertIsInstance(caught.exception.__context__.__context__, GeneratorExit) + self.assertIsNone(caught.exception.__context__.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = StopIteration() + thrown = GeneratorExit() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.throw(thrown) + self.assertIs(caught.exception.__context__, raised) + # This isn't the same GeneratorExit as thrown! It's the one created + # by calling inner.close(): + self.assertIsInstance(caught.exception.__context__.__context__, GeneratorExit) + self.assertIsNone(caught.exception.__context__.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = StopIteration() + thrown = StopIteration() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.throw(thrown) + self.assertIs(caught.exception.__context__, raised) + self.assertIs(caught.exception.__context__.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = StopIteration() + thrown = BaseException() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.throw(thrown) + self.assertIs(caught.exception.__context__, raised) + self.assertIs(caught.exception.__context__.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = StopIteration() + thrown = Exception() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.throw(thrown) + self.assertIs(caught.exception.__context__, raised) + self.assertIs(caught.exception.__context__.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__.__context__) + self.assert_stop_iteration(g) + + def test_close_and_throw_raise_base_exception(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + yield yielded_second + return returned + finally: + raise raised + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = BaseException() + with self.assertRaises(BaseException) as caught: + g.close() + self.assertIs(caught.exception, raised) + self.assertIsInstance(caught.exception.__context__, GeneratorExit) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = BaseException() + thrown = GeneratorExit() + with self.assertRaises(BaseException) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + # This isn't the same GeneratorExit as thrown! It's the one created + # by calling inner.close(): + self.assertIsInstance(caught.exception.__context__, GeneratorExit) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = BaseException() + thrown = StopIteration() + with self.assertRaises(BaseException) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = BaseException() + thrown = BaseException() + with self.assertRaises(BaseException) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = BaseException() + thrown = Exception() + with self.assertRaises(BaseException) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + def test_close_and_throw_raise_exception(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + yield yielded_second + return returned + finally: + raise raised + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = Exception() + with self.assertRaises(Exception) as caught: + g.close() + self.assertIs(caught.exception, raised) + self.assertIsInstance(caught.exception.__context__, GeneratorExit) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = Exception() + thrown = GeneratorExit() + with self.assertRaises(Exception) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + # This isn't the same GeneratorExit as thrown! It's the one created + # by calling inner.close(): + self.assertIsInstance(caught.exception.__context__, GeneratorExit) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = Exception() + thrown = StopIteration() + with self.assertRaises(Exception) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = Exception() + thrown = BaseException() + with self.assertRaises(Exception) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = Exception() + thrown = Exception() + with self.assertRaises(Exception) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + def test_close_and_throw_yield(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + finally: + yield yielded_second + return returned + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + # No chaining happens. This is consistent with PEP 342: + # https://peps.python.org/pep-0342/#new-generator-method-close + with self.assert_generator_ignored_generator_exit() as caught: + g.close() + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = GeneratorExit() + # No chaining happens. This is consistent with PEP 342: + # https://peps.python.org/pep-0342/#new-generator-method-close + with self.assert_generator_ignored_generator_exit() as caught: + g.throw(thrown) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = StopIteration() + self.assertEqual(g.throw(thrown), yielded_second) + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + next(g) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = BaseException() + self.assertEqual(g.throw(thrown), yielded_second) + with self.assertRaises(BaseException) as caught: + next(g) + self.assertIs(caught.exception, thrown) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = Exception() + self.assertEqual(g.throw(thrown), yielded_second) + with self.assertRaises(Exception) as caught: + next(g) + self.assertIs(caught.exception, thrown) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + def test_close_and_throw_return(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + yield yielded_second + finally: + return returned + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + # StopIteration is suppressed. This is consistent with PEP 342: + # https://peps.python.org/pep-0342/#new-generator-method-close + g.close() + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = GeneratorExit() + # StopIteration is suppressed. This is consistent with PEP 342: + # https://peps.python.org/pep-0342/#new-generator-method-close + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + self.assertIs(caught.exception, thrown) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = StopIteration() + with self.assertRaises(StopIteration) as caught: + g.throw(thrown) + self.assertIs(caught.exception.value, returned) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = BaseException() + with self.assertRaises(StopIteration) as caught: + g.throw(thrown) + self.assertIs(caught.exception.value, returned) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = Exception() + with self.assertRaises(StopIteration) as caught: + g.throw(thrown) + self.assertIs(caught.exception.value, returned) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_zipapp.py b/Lib/test/test_zipapp.py index 69f2e55d563..f1c6b2d9762 100644 --- a/Lib/test/test_zipapp.py +++ b/Lib/test/test_zipapp.py @@ -9,6 +9,7 @@ import unittest import zipapp import zipfile from test.support import requires_zlib +from test.support import os_helper from unittest.mock import patch @@ -54,6 +55,22 @@ class ZipAppTest(unittest.TestCase): self.assertIn('foo/', z.namelist()) self.assertIn('bar/', z.namelist()) + def test_create_sorted_archive(self): + # Test that zipapps order their files by name + source = self.tmpdir / 'source' + source.mkdir() + (source / 'zed.py').touch() + (source / 'bin').mkdir() + (source / 'bin' / 'qux').touch() + (source / 'bin' / 'baz').touch() + (source / '__main__.py').touch() + target = io.BytesIO() + zipapp.create_archive(str(source), target) + target.seek(0) + with zipfile.ZipFile(target, 'r') as zf: + self.assertEqual(zf.namelist(), + ["__main__.py", "bin/", "bin/baz", "bin/qux", "zed.py"]) + def test_create_archive_with_filter(self): # Test packing a directory and using filter to specify # which files to include. @@ -301,6 +318,7 @@ class ZipAppTest(unittest.TestCase): # (Unix only) tests that archives with shebang lines are made executable @unittest.skipIf(sys.platform == 'win32', 'Windows does not support an executable bit') + @os_helper.skip_unless_working_chmod def test_shebang_is_executable(self): # Test that an archive with a shebang line is made executable. source = self.tmpdir / 'source' diff --git a/Lib/test/test_zipfile/__init__.py b/Lib/test/test_zipfile/__init__.py new file mode 100644 index 00000000000..4b16ecc3115 --- /dev/null +++ b/Lib/test/test_zipfile/__init__.py @@ -0,0 +1,5 @@ +import os +from test.support import load_package_tests + +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_zipfile/__main__.py b/Lib/test/test_zipfile/__main__.py new file mode 100644 index 00000000000..e25ac946edf --- /dev/null +++ b/Lib/test/test_zipfile/__main__.py @@ -0,0 +1,7 @@ +import unittest + +from . import load_tests # noqa: F401 + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_zipfile/_functools.py b/Lib/test/test_zipfile/_functools.py new file mode 100644 index 00000000000..75f2b20e06d --- /dev/null +++ b/Lib/test/test_zipfile/_functools.py @@ -0,0 +1,9 @@ +import functools + + +# from jaraco.functools 3.5.2 +def compose(*funcs): + def compose_two(f1, f2): + return lambda *args, **kwargs: f1(f2(*args, **kwargs)) + + return functools.reduce(compose_two, funcs) diff --git a/Lib/test/test_zipfile/_itertools.py b/Lib/test/test_zipfile/_itertools.py new file mode 100644 index 00000000000..559f3f111b8 --- /dev/null +++ b/Lib/test/test_zipfile/_itertools.py @@ -0,0 +1,12 @@ +# from more_itertools v8.13.0 +def always_iterable(obj, base_type=(str, bytes)): + if obj is None: + return iter(()) + + if (base_type is not None) and isinstance(obj, base_type): + return iter((obj,)) + + try: + return iter(obj) + except TypeError: + return iter((obj,)) diff --git a/Lib/test/test_zipfile/_test_params.py b/Lib/test/test_zipfile/_test_params.py new file mode 100644 index 00000000000..bc95b4ebf4a --- /dev/null +++ b/Lib/test/test_zipfile/_test_params.py @@ -0,0 +1,39 @@ +import types +import functools + +from ._itertools import always_iterable + + +def parameterize(names, value_groups): + """ + Decorate a test method to run it as a set of subtests. + + Modeled after pytest.parametrize. + """ + + def decorator(func): + @functools.wraps(func) + def wrapped(self): + for values in value_groups: + resolved = map(Invoked.eval, always_iterable(values)) + params = dict(zip(always_iterable(names), resolved)) + with self.subTest(**params): + func(self, **params) + + return wrapped + + return decorator + + +class Invoked(types.SimpleNamespace): + """ + Wrap a function to be invoked for each usage. + """ + + @classmethod + def wrap(cls, func): + return cls(func=func) + + @classmethod + def eval(cls, cand): + return cand.func() if isinstance(cand, cls) else cand diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile/test_core.py similarity index 89% rename from Lib/test/test_zipfile.py rename to Lib/test/test_zipfile/test_core.py index df48fabff95..cf41d0e8cb8 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile/test_core.py @@ -1,3 +1,4 @@ +import array import contextlib import importlib.util import io @@ -5,7 +6,6 @@ import itertools import os import pathlib import posixpath -import string import struct import subprocess import sys @@ -13,16 +13,19 @@ import time import unittest import unittest.mock as mock import zipfile -import functools from tempfile import TemporaryFile from random import randint, random, randbytes from test.support import script_helper -from test.support import (findfile, requires_zlib, requires_bz2, - requires_lzma, captured_stdout) -from test.support.os_helper import TESTFN, unlink, rmtree, temp_dir, temp_cwd +from test.support import ( + findfile, requires_zlib, requires_bz2, requires_lzma, + captured_stdout, captured_stderr, requires_subprocess +) +from test.support.os_helper import ( + TESTFN, unlink, rmtree, temp_dir, temp_cwd, fd_count +) TESTFN2 = TESTFN + "2" @@ -119,8 +122,9 @@ class AbstractTestsWithSourceFile: self.assertEqual(info.filename, nm) self.assertEqual(info.file_size, len(self.data)) - # Check that testzip doesn't raise an exception - zipfp.testzip() + # Check that testzip thinks the archive is ok + # (it returns None if all contents could be read properly) + self.assertIsNone(zipfp.testzip()) def test_basic(self): for f in get_files(self): @@ -743,8 +747,8 @@ class AbstractTestZip64InSmallFiles: self.assertEqual(info.filename, nm) self.assertEqual(info.file_size, len(self.data)) - # Check that testzip doesn't raise an exception - zipfp.testzip() + # Check that testzip thinks the archive is valid + self.assertIsNone(zipfp.testzip()) def test_basic(self): for f in get_files(self): @@ -1119,6 +1123,14 @@ class AbstractWriterTests: self.assertRaises(ValueError, w.write, b'') self.assertEqual(zipf.read('test'), data) + def test_issue44439(self): + q = array.array('Q', [1, 2, 3, 4, 5]) + LENGTH = len(q) * q.itemsize + with zipfile.ZipFile(io.BytesIO(), 'w', self.compression) as zip: + with zip.open('data', 'w') as data: + self.assertEqual(data.write(q), LENGTH) + self.assertEqual(zip.getinfo('data').file_size, LENGTH) + class StoredWriterTests(AbstractWriterTests, unittest.TestCase): compression = zipfile.ZIP_STORED @@ -1427,6 +1439,8 @@ class ExtractTests(unittest.TestCase): self.assertEqual(san(r',,?,C:,foo,bar/z', ','), r'_,C_,foo,bar/z') self.assertEqual(san(r'a\b,ce|f"g?h*i', ','), r'a\b,c_d_e_f_g_h_i') self.assertEqual(san('../../foo../../ba..r', '/'), r'foo/ba..r') + self.assertEqual(san(' / /foo / /ba r', '/'), r'foo/ba r') + self.assertEqual(san(' . /. /foo ./ . /. ./ba .r', '/'), r'foo/ba .r') def test_extract_hackers_arcnames_common_cases(self): common_hacknames = [ @@ -1455,10 +1469,10 @@ class ExtractTests(unittest.TestCase): (r'C:\foo\bar', 'foo/bar'), (r'//conky/mountpoint/foo/bar', 'foo/bar'), (r'\\conky\mountpoint\foo\bar', 'foo/bar'), - (r'///conky/mountpoint/foo/bar', 'conky/mountpoint/foo/bar'), - (r'\\\conky\mountpoint\foo\bar', 'conky/mountpoint/foo/bar'), - (r'//conky//mountpoint/foo/bar', 'conky/mountpoint/foo/bar'), - (r'\\conky\\mountpoint\foo\bar', 'conky/mountpoint/foo/bar'), + (r'///conky/mountpoint/foo/bar', 'mountpoint/foo/bar'), + (r'\\\conky\mountpoint\foo\bar', 'mountpoint/foo/bar'), + (r'//conky//mountpoint/foo/bar', 'mountpoint/foo/bar'), + (r'\\conky\\mountpoint\foo\bar', 'mountpoint/foo/bar'), (r'//?/C:/foo/bar', 'foo/bar'), (r'\\?\C:\foo\bar', 'foo/bar'), (r'C:/../C:/foo/bar', 'C_/foo/bar'), @@ -1727,6 +1741,17 @@ class OtherTests(unittest.TestCase): fp.write("short file") self.assertRaises(zipfile.BadZipFile, zipfile.ZipFile, TESTFN) + def test_negative_central_directory_offset_raises_BadZipFile(self): + # Zip file containing an empty EOCD record + buffer = bytearray(b'PK\x05\x06' + b'\0'*18) + + # Set the size of the central directory bytes to become 1, + # causing the central directory offset to become negative + for dirsize in 1, 2**32-1: + buffer[12:16] = struct.pack(':8: EncodingWarning:") + self.assertRegex(warnings[1], rb"^:9: EncodingWarning:") + + def test_open_write(self): + """ + If the zipfile is open for write, it should be possible to + write bytes or text to it. + """ + zf = zipfile.Path(zipfile.ZipFile(io.BytesIO(), mode='w')) + with zf.joinpath('file.bin').open('wb') as strm: + strm.write(b'binary contents') + with zf.joinpath('file.txt').open('w', encoding="utf-8") as strm: + strm.write('text file') + + def test_open_extant_directory(self): + """ + Attempting to open a directory raises IsADirectoryError. + """ + zf = zipfile.Path(add_dirs(build_alpharep_fixture())) + with self.assertRaises(IsADirectoryError): + zf.joinpath('b').open() + + @pass_alpharep + def test_open_binary_invalid_args(self, alpharep): + root = zipfile.Path(alpharep) + with self.assertRaises(ValueError): + root.joinpath('a.txt').open('rb', encoding='utf-8') + with self.assertRaises(ValueError): + root.joinpath('a.txt').open('rb', 'utf-8') + + def test_open_missing_directory(self): + """ + Attempting to open a missing directory raises FileNotFoundError. + """ + zf = zipfile.Path(add_dirs(build_alpharep_fixture())) + with self.assertRaises(FileNotFoundError): + zf.joinpath('z').open() + + @pass_alpharep + def test_read(self, alpharep): + root = zipfile.Path(alpharep) + a, b, g = root.iterdir() + assert a.read_text(encoding="utf-8") == "content of a" + a.read_text("utf-8") # No positional arg TypeError per gh-101144. + assert a.read_bytes() == b"content of a" + + @pass_alpharep + def test_joinpath(self, alpharep): + root = zipfile.Path(alpharep) + a = root.joinpath("a.txt") + assert a.is_file() + e = root.joinpath("b").joinpath("d").joinpath("e.txt") + assert e.read_text(encoding="utf-8") == "content of e" + + @pass_alpharep + def test_joinpath_multiple(self, alpharep): + root = zipfile.Path(alpharep) + e = root.joinpath("b", "d", "e.txt") + assert e.read_text(encoding="utf-8") == "content of e" + + @pass_alpharep + def test_traverse_truediv(self, alpharep): + root = zipfile.Path(alpharep) + a = root / "a.txt" + assert a.is_file() + e = root / "b" / "d" / "e.txt" + assert e.read_text(encoding="utf-8") == "content of e" + + @pass_alpharep + def test_traverse_simplediv(self, alpharep): + """ + Disable the __future__.division when testing traversal. + """ + code = compile( + source="zipfile.Path(alpharep) / 'a'", + filename="(test)", + mode="eval", + dont_inherit=True, + ) + eval(code) + + @pass_alpharep + def test_pathlike_construction(self, alpharep): + """ + zipfile.Path should be constructable from a path-like object + """ + zipfile_ondisk = self.zipfile_ondisk(alpharep) + pathlike = pathlib.Path(str(zipfile_ondisk)) + zipfile.Path(pathlike) + + @pass_alpharep + def test_traverse_pathlike(self, alpharep): + root = zipfile.Path(alpharep) + root / pathlib.Path("a") + + @pass_alpharep + def test_parent(self, alpharep): + root = zipfile.Path(alpharep) + assert (root / 'a').parent.at == '' + assert (root / 'a' / 'b').parent.at == 'a/' + + @pass_alpharep + def test_dir_parent(self, alpharep): + root = zipfile.Path(alpharep) + assert (root / 'b').parent.at == '' + assert (root / 'b/').parent.at == '' + + @pass_alpharep + def test_missing_dir_parent(self, alpharep): + root = zipfile.Path(alpharep) + assert (root / 'missing dir/').parent.at == '' + + @pass_alpharep + def test_mutability(self, alpharep): + """ + If the underlying zipfile is changed, the Path object should + reflect that change. + """ + root = zipfile.Path(alpharep) + a, b, g = root.iterdir() + alpharep.writestr('foo.txt', 'foo') + alpharep.writestr('bar/baz.txt', 'baz') + assert any(child.name == 'foo.txt' for child in root.iterdir()) + assert (root / 'foo.txt').read_text(encoding="utf-8") == 'foo' + (baz,) = (root / 'bar').iterdir() + assert baz.read_text(encoding="utf-8") == 'baz' + + HUGE_ZIPFILE_NUM_ENTRIES = 2**13 + + def huge_zipfile(self): + """Create a read-only zipfile with a huge number of entries entries.""" + strm = io.BytesIO() + zf = zipfile.ZipFile(strm, "w") + for entry in map(str, range(self.HUGE_ZIPFILE_NUM_ENTRIES)): + zf.writestr(entry, entry) + zf.mode = 'r' + return zf + + def test_joinpath_constant_time(self): + """ + Ensure joinpath on items in zipfile is linear time. + """ + root = zipfile.Path(self.huge_zipfile()) + entries = jaraco.itertools.Counter(root.iterdir()) + for entry in entries: + entry.joinpath('suffix') + # Check the file iterated all items + assert entries.count == self.HUGE_ZIPFILE_NUM_ENTRIES + + # @func_timeout.func_set_timeout(3) + def test_implied_dirs_performance(self): + data = ['/'.join(string.ascii_lowercase + str(n)) for n in range(10000)] + zipfile.CompleteDirs._implied_dirs(data) + + @pass_alpharep + def test_read_does_not_close(self, alpharep): + alpharep = self.zipfile_ondisk(alpharep) + with zipfile.ZipFile(alpharep) as file: + for rep in range(2): + zipfile.Path(file, 'a.txt').read_text(encoding="utf-8") + + @pass_alpharep + def test_subclass(self, alpharep): + class Subclass(zipfile.Path): + pass + + root = Subclass(alpharep) + assert isinstance(root / 'b', Subclass) + + @pass_alpharep + def test_filename(self, alpharep): + root = zipfile.Path(alpharep) + assert root.filename == pathlib.Path('alpharep.zip') + + @pass_alpharep + def test_root_name(self, alpharep): + """ + The name of the root should be the name of the zipfile + """ + root = zipfile.Path(alpharep) + assert root.name == 'alpharep.zip' == root.filename.name + + @pass_alpharep + def test_suffix(self, alpharep): + """ + The suffix of the root should be the suffix of the zipfile. + The suffix of each nested file is the final component's last suffix, if any. + Includes the leading period, just like pathlib.Path. + """ + root = zipfile.Path(alpharep) + assert root.suffix == '.zip' == root.filename.suffix + + b = root / "b.txt" + assert b.suffix == ".txt" + + c = root / "c" / "filename.tar.gz" + assert c.suffix == ".gz" + + d = root / "d" + assert d.suffix == "" + + @pass_alpharep + def test_suffixes(self, alpharep): + """ + The suffix of the root should be the suffix of the zipfile. + The suffix of each nested file is the final component's last suffix, if any. + Includes the leading period, just like pathlib.Path. + """ + root = zipfile.Path(alpharep) + assert root.suffixes == ['.zip'] == root.filename.suffixes + + b = root / 'b.txt' + assert b.suffixes == ['.txt'] + + c = root / 'c' / 'filename.tar.gz' + assert c.suffixes == ['.tar', '.gz'] + + d = root / 'd' + assert d.suffixes == [] + + e = root / '.hgrc' + assert e.suffixes == [] + + @pass_alpharep + def test_stem(self, alpharep): + """ + The final path component, without its suffix + """ + root = zipfile.Path(alpharep) + assert root.stem == 'alpharep' == root.filename.stem + + b = root / "b.txt" + assert b.stem == "b" + + c = root / "c" / "filename.tar.gz" + assert c.stem == "filename.tar" + + d = root / "d" + assert d.stem == "d" + + @pass_alpharep + def test_root_parent(self, alpharep): + root = zipfile.Path(alpharep) + assert root.parent == pathlib.Path('.') + root.root.filename = 'foo/bar.zip' + assert root.parent == pathlib.Path('foo') + + @pass_alpharep + def test_root_unnamed(self, alpharep): + """ + It is an error to attempt to get the name + or parent of an unnamed zipfile. + """ + alpharep.filename = None + root = zipfile.Path(alpharep) + with self.assertRaises(TypeError): + root.name + with self.assertRaises(TypeError): + root.parent + + # .name and .parent should still work on subs + sub = root / "b" + assert sub.name == "b" + assert sub.parent + + @pass_alpharep + def test_inheritance(self, alpharep): + cls = type('PathChild', (zipfile.Path,), {}) + file = cls(alpharep).joinpath('some dir').parent + assert isinstance(file, cls) + + @parameterize( + ['alpharep', 'path_type', 'subpath'], + itertools.product( + alpharep_generators, + [str, pathlib.Path], + ['', 'b/'], + ), + ) + def test_pickle(self, alpharep, path_type, subpath): + zipfile_ondisk = path_type(self.zipfile_ondisk(alpharep)) + + saved_1 = pickle.dumps(zipfile.Path(zipfile_ondisk, at=subpath)) + restored_1 = pickle.loads(saved_1) + first, *rest = restored_1.iterdir() + assert first.read_text().startswith('content of ') diff --git a/Lib/test/test_zipfile64.py b/Lib/test/test_zipfile64.py index 810fdedef39..be654a8478b 100644 --- a/Lib/test/test_zipfile64.py +++ b/Lib/test/test_zipfile64.py @@ -18,8 +18,9 @@ import sys from tempfile import TemporaryFile from test.support import os_helper -from test.support import TESTFN, requires_zlib +from test.support import requires_zlib +TESTFN = os_helper.TESTFN TESTFN2 = TESTFN + "2" # How much time in seconds can pass before we print a 'Still working' message. @@ -31,10 +32,6 @@ class TestsWithSourceFile(unittest.TestCase): line_gen = ("Test of zipfile line %d." % i for i in range(1000000)) self.data = '\n'.join(line_gen).encode('ascii') - # And write it to a file. - with open(TESTFN, "wb") as fp: - fp.write(self.data) - def zipTest(self, f, compression): # Create the ZIP archive. with zipfile.ZipFile(f, "w", compression) as zipfp: @@ -66,6 +63,9 @@ class TestsWithSourceFile(unittest.TestCase): (num, filecount)), file=sys.__stdout__) sys.__stdout__.flush() + # Check that testzip thinks the archive is valid + self.assertIsNone(zipfp.testzip()) + def testStored(self): # Try the temp file first. If we do TESTFN2 first, then it hogs # gigabytes of disk space for the duration of the test. @@ -84,9 +84,7 @@ class TestsWithSourceFile(unittest.TestCase): self.zipTest(TESTFN2, zipfile.ZIP_DEFLATED) def tearDown(self): - for fname in TESTFN, TESTFN2: - if os.path.exists(fname): - os.remove(fname) + os_helper.unlink(TESTFN2) class OtherTests(unittest.TestCase): diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index 392dcfa87a1..52d43bdead6 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -460,12 +460,6 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase): # PEP 302 with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) - find_mod = zi.find_module('spam') - self.assertIsNotNone(find_mod) - self.assertIsInstance(find_mod, zipimport.zipimporter) - self.assertFalse(find_mod.is_package('spam')) - load_mod = find_mod.load_module('spam') - self.assertEqual(find_mod.get_filename('spam'), load_mod.__file__) mod = zi.load_module(TESTPACK) self.assertEqual(zi.get_filename(TESTPACK), mod.__file__) @@ -586,16 +580,6 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase): pkg_path = TEMP_ZIP + os.sep + packdir + TESTPACK2 zi2 = zipimport.zipimporter(pkg_path) - # PEP 302 - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - find_mod_dotted = zi2.find_module(TESTMOD) - self.assertIsNotNone(find_mod_dotted) - self.assertIsInstance(find_mod_dotted, zipimport.zipimporter) - self.assertFalse(zi2.is_package(TESTMOD)) - load_mod = find_mod_dotted.load_module(TESTMOD) - self.assertEqual( - find_mod_dotted.get_filename(TESTMOD), load_mod.__file__) # PEP 451 spec = zi2.find_spec(TESTMOD) @@ -654,7 +638,10 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase): sys.path.insert(0, TEMP_ZIP) mod = importlib.import_module(TESTMOD) self.assertEqual(mod.test(1), 1) - self.assertRaises(AssertionError, mod.test, False) + if __debug__: + self.assertRaises(AssertionError, mod.test, False) + else: + self.assertEqual(mod.test(0), 0) def testImport_WithStuff(self): # try importing from a zipfile which contains additional @@ -710,8 +697,8 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase): def doTraceback(self, module): try: module.do_raise() - except: - tb = sys.exc_info()[2].tb_next + except Exception as e: + tb = e.__traceback__.tb_next f,lno,n,line = extract_tb(tb, 1)[0] self.assertEqual(line, raise_src.strip()) @@ -755,7 +742,8 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase): z.writestr(zinfo, test_src) zipimport.zipimporter(filename) - zipimport.zipimporter(os.fsencode(filename)) + with self.assertRaises(TypeError): + zipimport.zipimporter(os.fsencode(filename)) with self.assertRaises(TypeError): zipimport.zipimporter(bytearray(os.fsencode(filename))) with self.assertRaises(TypeError): @@ -804,6 +792,7 @@ class BadFileZipImportTestCase(unittest.TestCase): os_helper.create_empty_file(TESTMOD) self.assertZipFailure(TESTMOD) + @unittest.skipIf(support.is_wasi, "mode 000 not supported.") def testFileUnreadable(self): os_helper.unlink(TESTMOD) fd = os.open(TESTMOD, os.O_CREAT, 000) diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py index 04fb4d93de4..ae54f6c4689 100644 --- a/Lib/test/test_zlib.py +++ b/Lib/test/test_zlib.py @@ -3,6 +3,7 @@ from test import support from test.support import import_helper import binascii import copy +import os import pickle import random import sys @@ -18,6 +19,35 @@ requires_Decompress_copy = unittest.skipUnless( hasattr(zlib.decompressobj(), "copy"), 'requires Decompress.copy()') +# bpo-46623: On s390x, when a hardware accelerator is used, using different +# ways to compress data with zlib can produce different compressed data. +# Simplified test_pair() code: +# +# def func1(data): +# return zlib.compress(data) +# +# def func2(data) +# co = zlib.compressobj() +# x1 = co.compress(data) +# x2 = co.flush() +# return x1 + x2 +# +# On s390x if zlib uses a hardware accelerator, func1() creates a single +# "final" compressed block whereas func2() produces 3 compressed blocks (the +# last one is a final block). On other platforms with no accelerator, func1() +# and func2() produce the same compressed data made of a single (final) +# compressed block. +# +# Only the compressed data is different, the decompression returns the original +# data: +# +# zlib.decompress(func1(data)) == zlib.decompress(func2(data)) == data +# +# Make the assumption that s390x always has an accelerator to simplify the skip +# condition. Windows doesn't have os.uname() but it doesn't support s390x. +skip_on_s390x = unittest.skipIf(hasattr(os, 'uname') and os.uname().machine == 's390x', + 'skipped on s390x') + class VersionTestCase(unittest.TestCase): @@ -182,6 +212,7 @@ class CompressTestCase(BaseCompressTestCase, unittest.TestCase): bufsize=zlib.DEF_BUF_SIZE), HAMLET_SCENE) + @skip_on_s390x def test_speech128(self): # compress more data data = HAMLET_SCENE * 128 @@ -233,6 +264,7 @@ class CompressTestCase(BaseCompressTestCase, unittest.TestCase): class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase): # Test compression object + @skip_on_s390x def test_pair(self): # straightforward compress/decompress objects datasrc = HAMLET_SCENE * 128 @@ -912,6 +944,173 @@ LAERTES """ +class ZlibDecompressorTest(): + # Test adopted from test_bz2.py + TEXT = HAMLET_SCENE + DATA = zlib.compress(HAMLET_SCENE) + BAD_DATA = b"Not a valid deflate block" + def test_Constructor(self): + self.assertRaises(TypeError, zlib._ZlibDecompressor, 42) + + def testDecompress(self): + zlibd = zlib._ZlibDecompressor() + self.assertRaises(TypeError, zlibd.decompress) + text = zlibd.decompress(self.DATA) + self.assertEqual(text, self.TEXT) + + def testDecompressChunks10(self): + zlibd = zlib._ZlibDecompressor() + text = b'' + n = 0 + while True: + str = self.DATA[n*10:(n+1)*10] + if not str: + break + text += zlibd.decompress(str) + n += 1 + self.assertEqual(text, self.TEXT) + + def testDecompressUnusedData(self): + zlibd = zlib._ZlibDecompressor() + unused_data = b"this is unused data" + text = zlibd.decompress(self.DATA+unused_data) + self.assertEqual(text, self.TEXT) + self.assertEqual(zlibd.unused_data, unused_data) + + def testEOFError(self): + zlibd = zlib._ZlibDecompressor() + text = zlibd.decompress(self.DATA) + self.assertRaises(EOFError, zlibd.decompress, b"anything") + self.assertRaises(EOFError, zlibd.decompress, b"") + + @support.skip_if_pgo_task + @bigmemtest(size=_4G + 100, memuse=3.3) + def testDecompress4G(self, size): + # "Test zlib._ZlibDecompressor.decompress() with >4GiB input" + blocksize = 10 * 1024 * 1024 + block = random.randbytes(blocksize) + try: + data = block * (size // blocksize + 1) + compressed = zlib.compress(data) + zlibd = zlib._ZlibDecompressor() + decompressed = zlibd.decompress(compressed) + self.assertTrue(decompressed == data) + finally: + data = None + compressed = None + decompressed = None + + def testPickle(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises(TypeError): + pickle.dumps(zlib._ZlibDecompressor(), proto) + + def testDecompressorChunksMaxsize(self): + zlibd = zlib._ZlibDecompressor() + max_length = 100 + out = [] + + # Feed some input + len_ = len(self.BIG_DATA) - 64 + out.append(zlibd.decompress(self.BIG_DATA[:len_], + max_length=max_length)) + self.assertFalse(zlibd.needs_input) + self.assertEqual(len(out[-1]), max_length) + + # Retrieve more data without providing more input + out.append(zlibd.decompress(b'', max_length=max_length)) + self.assertFalse(zlibd.needs_input) + self.assertEqual(len(out[-1]), max_length) + + # Retrieve more data while providing more input + out.append(zlibd.decompress(self.BIG_DATA[len_:], + max_length=max_length)) + self.assertLessEqual(len(out[-1]), max_length) + + # Retrieve remaining uncompressed data + while not zlibd.eof: + out.append(zlibd.decompress(b'', max_length=max_length)) + self.assertLessEqual(len(out[-1]), max_length) + + out = b"".join(out) + self.assertEqual(out, self.BIG_TEXT) + self.assertEqual(zlibd.unused_data, b"") + + def test_decompressor_inputbuf_1(self): + # Test reusing input buffer after moving existing + # contents to beginning + zlibd = zlib._ZlibDecompressor() + out = [] + + # Create input buffer and fill it + self.assertEqual(zlibd.decompress(self.DATA[:100], + max_length=0), b'') + + # Retrieve some results, freeing capacity at beginning + # of input buffer + out.append(zlibd.decompress(b'', 2)) + + # Add more data that fits into input buffer after + # moving existing data to beginning + out.append(zlibd.decompress(self.DATA[100:105], 15)) + + # Decompress rest of data + out.append(zlibd.decompress(self.DATA[105:])) + self.assertEqual(b''.join(out), self.TEXT) + + def test_decompressor_inputbuf_2(self): + # Test reusing input buffer by appending data at the + # end right away + zlibd = zlib._ZlibDecompressor() + out = [] + + # Create input buffer and empty it + self.assertEqual(zlibd.decompress(self.DATA[:200], + max_length=0), b'') + out.append(zlibd.decompress(b'')) + + # Fill buffer with new data + out.append(zlibd.decompress(self.DATA[200:280], 2)) + + # Append some more data, not enough to require resize + out.append(zlibd.decompress(self.DATA[280:300], 2)) + + # Decompress rest of data + out.append(zlibd.decompress(self.DATA[300:])) + self.assertEqual(b''.join(out), self.TEXT) + + def test_decompressor_inputbuf_3(self): + # Test reusing input buffer after extending it + + zlibd = zlib._ZlibDecompressor() + out = [] + + # Create almost full input buffer + out.append(zlibd.decompress(self.DATA[:200], 5)) + + # Add even more data to it, requiring resize + out.append(zlibd.decompress(self.DATA[200:300], 5)) + + # Decompress rest of data + out.append(zlibd.decompress(self.DATA[300:])) + self.assertEqual(b''.join(out), self.TEXT) + + def test_failure(self): + zlibd = zlib._ZlibDecompressor() + self.assertRaises(Exception, zlibd.decompress, self.BAD_DATA * 30) + # Previously, a second call could crash due to internal inconsistency + self.assertRaises(Exception, zlibd.decompress, self.BAD_DATA * 30) + + @support.refcount_test + def test_refleaks_in___init__(self): + gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount') + zlibd = zlib._ZlibDecompressor() + refs_before = gettotalrefcount() + for i in range(100): + zlibd.__init__() + self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) + + class CustomInt: def __index__(self): return 100 diff --git a/Lib/test/test_zoneinfo/test_zoneinfo.py b/Lib/test/test_zoneinfo/test_zoneinfo.py index 59b35ef63f9..fd0e3bc032e 100644 --- a/Lib/test/test_zoneinfo/test_zoneinfo.py +++ b/Lib/test/test_zoneinfo/test_zoneinfo.py @@ -17,8 +17,8 @@ import unittest from datetime import date, datetime, time, timedelta, timezone from functools import cached_property -from . import _support as test_support -from ._support import OS_ENV_LOCK, TZPATH_TEST_LOCK, ZoneInfoTestBase +from test.test_zoneinfo import _support as test_support +from test.test_zoneinfo._support import OS_ENV_LOCK, TZPATH_TEST_LOCK, ZoneInfoTestBase from test.support.import_helper import import_module lzma = import_module('lzma') @@ -404,6 +404,19 @@ class ZoneInfoTest(TzPathUserMixin, ZoneInfoTestBase): class CZoneInfoTest(ZoneInfoTest): module = c_zoneinfo + def test_signatures(self): + """Ensure that C module has valid method signatures.""" + import inspect + + must_have_signatures = ( + self.klass.clear_cache, + self.klass.no_cache, + self.klass.from_file, + ) + for method in must_have_signatures: + with self.subTest(method=method): + inspect.Signature.from_callable(method) + def test_fold_mutate(self): """Test that fold isn't mutated when no change is necessary. @@ -2107,3 +2120,7 @@ class ZoneDumpData: _ZONEDUMP_DATA = None _FIXED_OFFSET_ZONES = None + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/tkinter/test/__init__.py b/Lib/test/typinganndata/__init__.py similarity index 100% rename from Lib/tkinter/test/__init__.py rename to Lib/test/typinganndata/__init__.py diff --git a/Lib/test/typinganndata/ann_module9.py b/Lib/test/typinganndata/ann_module9.py new file mode 100644 index 00000000000..952217393e1 --- /dev/null +++ b/Lib/test/typinganndata/ann_module9.py @@ -0,0 +1,14 @@ +# Test ``inspect.formatannotation`` +# https://github.com/python/cpython/issues/96073 + +from typing import Union, List + +ann = Union[List[str], int] + +# mock typing._type_repr behaviour +class A: ... + +A.__module__ = 'testModule.typing' +A.__qualname__ = 'A' + +ann1 = Union[List[A], int] diff --git a/Lib/textwrap.py b/Lib/textwrap.py index 841de9baecf..98bedd27ea3 100644 --- a/Lib/textwrap.py +++ b/Lib/textwrap.py @@ -63,10 +63,7 @@ class TextWrapper: Append to the last line of truncated text. """ - unicode_whitespace_trans = {} - uspace = ord(' ') - for x in _whitespace: - unicode_whitespace_trans[ord(x)] = uspace + unicode_whitespace_trans = dict.fromkeys(map(ord, _whitespace), ord(' ')) # This funky little regex is just the trick for splitting # text up into word-wrappable chunks. E.g. diff --git a/Lib/threading.py b/Lib/threading.py index 6068d06ab6c..df273870fa4 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -7,7 +7,7 @@ import functools from time import monotonic as _time from _weakrefset import WeakSet -from itertools import islice as _islice, count as _count +from itertools import count as _count try: from _collections import deque as _deque except ImportError: @@ -28,10 +28,12 @@ __all__ = ['get_ident', 'active_count', 'Condition', 'current_thread', 'Event', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread', 'Barrier', 'BrokenBarrierError', 'Timer', 'ThreadError', 'setprofile', 'settrace', 'local', 'stack_size', - 'excepthook', 'ExceptHookArgs', 'gettrace', 'getprofile'] + 'excepthook', 'ExceptHookArgs', 'gettrace', 'getprofile', + 'setprofile_all_threads','settrace_all_threads'] # Rename some stuff so "from threading import *" is safe _start_new_thread = _thread.start_new_thread +_daemon_threads_allowed = _thread.daemon_threads_allowed _allocate_lock = _thread.allocate_lock _set_sentinel = _thread._set_sentinel get_ident = _thread.get_ident @@ -60,11 +62,20 @@ def setprofile(func): The func will be passed to sys.setprofile() for each thread, before its run() method is called. - """ global _profile_hook _profile_hook = func +def setprofile_all_threads(func): + """Set a profile function for all threads started from the threading module + and all Python threads that are currently executing. + + The func will be passed to sys.setprofile() for each thread, before its + run() method is called. + """ + setprofile(func) + _sys._setprofileallthreads(func) + def getprofile(): """Get the profiler function as set by threading.setprofile().""" return _profile_hook @@ -74,11 +85,20 @@ def settrace(func): The func will be passed to sys.settrace() for each thread, before its run() method is called. - """ global _trace_hook _trace_hook = func +def settrace_all_threads(func): + """Set a trace function for all threads started from the threading module + and all Python threads that are currently executing. + + The func will be passed to sys.settrace() for each thread, before its run() + method is called. + """ + settrace(func) + _sys._settraceallthreads(func) + def gettrace(): """Get the trace function as set by threading.settrace().""" return _trace_hook @@ -243,18 +263,12 @@ class Condition: # If the lock defines _release_save() and/or _acquire_restore(), # these override the default implementations (which just call # release() and acquire() on the lock). Ditto for _is_owned(). - try: + if hasattr(lock, '_release_save'): self._release_save = lock._release_save - except AttributeError: - pass - try: + if hasattr(lock, '_acquire_restore'): self._acquire_restore = lock._acquire_restore - except AttributeError: - pass - try: + if hasattr(lock, '_is_owned'): self._is_owned = lock._is_owned - except AttributeError: - pass self._waiters = _deque() def _at_fork_reinit(self): @@ -368,14 +382,21 @@ class Condition: """ if not self._is_owned(): raise RuntimeError("cannot notify on un-acquired lock") - all_waiters = self._waiters - waiters_to_notify = _deque(_islice(all_waiters, n)) - if not waiters_to_notify: - return - for waiter in waiters_to_notify: - waiter.release() + waiters = self._waiters + while waiters and n > 0: + waiter = waiters[0] try: - all_waiters.remove(waiter) + waiter.release() + except RuntimeError: + # gh-92530: The previous call of notify() released the lock, + # but was interrupted before removing it from the queue. + # It can happen if a signal handler raises an exception, + # like CTRL+C which raises KeyboardInterrupt. + pass + else: + n -= 1 + try: + waiters.remove(waiter) except ValueError: pass @@ -481,8 +502,7 @@ class Semaphore: raise ValueError('n must be one or more') with self._cond: self._value += n - for i in range(n): - self._cond.notify() + self._cond.notify(n) def __exit__(self, t, v, tb): self.release() @@ -506,7 +526,7 @@ class BoundedSemaphore(Semaphore): """ def __init__(self, value=1): - Semaphore.__init__(self, value) + super().__init__(value) self._initial_value = value def __repr__(self): @@ -530,8 +550,7 @@ class BoundedSemaphore(Semaphore): if self._value + n > self._initial_value: raise ValueError("Semaphore released too many times") self._value += n - for i in range(n): - self._cond.notify() + self._cond.notify(n) class Event: @@ -565,7 +584,7 @@ class Event: def isSet(self): """Return true if and only if the internal flag is true. - This method is deprecated, use notify_all() instead. + This method is deprecated, use is_set() instead. """ import warnings @@ -852,7 +871,7 @@ class Thread: *name* is the thread name. By default, a unique name is constructed of the form "Thread-N" where N is a small decimal number. - *args* is the argument tuple for the target invocation. Defaults to (). + *args* is a list or tuple of arguments for the target invocation. Defaults to (). *kwargs* is a dictionary of keyword arguments for the target invocation. Defaults to {}. @@ -881,6 +900,8 @@ class Thread: self._args = args self._kwargs = kwargs if daemon is not None: + if daemon and not _daemon_threads_allowed(): + raise RuntimeError('daemon threads are disabled in this (sub)interpreter') self._daemonic = daemon else: self._daemonic = current_thread().daemon @@ -1208,6 +1229,8 @@ class Thread: def daemon(self, daemonic): if not self._initialized: raise RuntimeError("Thread.__init__() not called") + if daemonic and not _daemon_threads_allowed(): + raise RuntimeError('daemon threads are disabled in this interpreter') if self._started.is_set(): raise RuntimeError("cannot set daemon status of active thread") self._daemonic = daemonic @@ -1414,7 +1437,8 @@ class _MainThread(Thread): class _DummyThread(Thread): def __init__(self): - Thread.__init__(self, name=_newname("Dummy-%d"), daemon=True) + Thread.__init__(self, name=_newname("Dummy-%d"), + daemon=_daemon_threads_allowed()) self._started.set() self._set_ident() @@ -1466,6 +1490,8 @@ def active_count(): enumerate(). """ + # NOTE: if the logic in here ever changes, update Modules/posixmodule.c + # warn_about_fork_with_threads() to match. with _active_limbo_lock: return len(_active) + len(_limbo) diff --git a/Lib/timeit.py b/Lib/timeit.py index 9dfd454936e..0cf8db67723 100755 --- a/Lib/timeit.py +++ b/Lib/timeit.py @@ -259,10 +259,9 @@ def main(args=None, *, _wrap_timer=None): args = sys.argv[1:] import getopt try: - opts, args = getopt.getopt(args, "n:u:s:r:tcpvh", + opts, args = getopt.getopt(args, "n:u:s:r:pvh", ["number=", "setup=", "repeat=", - "time", "clock", "process", - "verbose", "unit=", "help"]) + "process", "verbose", "unit=", "help"]) except getopt.error as err: print(err) print("use -h/--help for command line help") diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 2e7e21c6648..7565e0f7e46 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -30,6 +30,7 @@ button.pack(side=BOTTOM) tk.mainloop() """ +import collections import enum import sys import types @@ -143,6 +144,28 @@ def _splitdict(tk, v, cut_minus=True, conv=None): dict[key] = value return dict +class _VersionInfoType(collections.namedtuple('_VersionInfoType', + ('major', 'minor', 'micro', 'releaselevel', 'serial'))): + def __str__(self): + if self.releaselevel == 'final': + return f'{self.major}.{self.minor}.{self.micro}' + else: + return f'{self.major}.{self.minor}{self.releaselevel[0]}{self.serial}' + +def _parse_version(version): + import re + m = re.fullmatch(r'(\d+)\.(\d+)([ab.])(\d+)', version) + major, minor, releaselevel, serial = m.groups() + major, minor, serial = int(major), int(minor), int(serial) + if releaselevel == '.': + micro = serial + serial = 0 + releaselevel = 'final' + else: + micro = 0 + releaselevel = {'a': 'alpha', 'b': 'beta'}[releaselevel] + return _VersionInfoType(major, minor, micro, releaselevel, serial) + @enum._simple_enum(enum.StrEnum) class EventType: @@ -1055,6 +1078,11 @@ class Misc: lift = tkraise + def info_patchlevel(self): + """Returns the exact version of the Tcl library.""" + patchlevel = self.tk.call('info', 'patchlevel') + return _parse_version(patchlevel) + def winfo_atom(self, name, displayof=0): """Return integer which represents atom NAME.""" args = ('winfo', 'atom') + self._displayof(displayof) + (name,) @@ -2098,7 +2126,7 @@ class Wm: the bitmap if None is given. Under Windows, the DEFAULT parameter can be used to set the icon - for the widget and any descendents that don't have an icon set + for the widget and any descendants that don't have an icon set explicitly. DEFAULT can be the relative path to a .ico file (example: root.iconbitmap(default='myicon.ico') ). See Tk documentation for more information.""" @@ -2277,7 +2305,7 @@ class Tk(Misc, Wm): def __init__(self, screenName=None, baseName=None, className='Tk', useTk=True, sync=False, use=None): - """Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will + """Return a new top level widget on screen SCREENNAME. A new Tcl interpreter will be created. BASENAME will be used for the identification of the profile file (see readprofile). It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME @@ -2344,9 +2372,9 @@ class Tk(Misc, Wm): _default_root = None def readprofile(self, baseName, className): - """Internal function. It reads BASENAME.tcl and CLASSNAME.tcl into - the Tcl Interpreter and calls exec on the contents of BASENAME.py and - CLASSNAME.py if such a file exists in the home directory.""" + """Internal function. It reads .BASENAME.tcl and .CLASSNAME.tcl into + the Tcl Interpreter and calls exec on the contents of .BASENAME.py and + .CLASSNAME.py if such a file exists in the home directory.""" import os if 'HOME' in os.environ: home = os.environ['HOME'] else: home = os.curdir @@ -2591,7 +2619,7 @@ class BaseWidget(Misc): if kw: cnf = _cnfmerge((cnf, kw)) self.widgetName = widgetName - BaseWidget._setup(self, master, cnf) + self._setup(master, cnf) if self._tclCommands is None: self._tclCommands = [] classes = [(k, v) for k, v in cnf.items() if isinstance(k, type)] @@ -3010,6 +3038,8 @@ class Canvas(Widget, XView, YView): return self.tk.call(self._w, 'type', tagOrId) or None +_checkbutton_count = 0 + class Checkbutton(Widget): """Checkbutton widget which is either in on- or off-state.""" @@ -3025,6 +3055,14 @@ class Checkbutton(Widget): underline, variable, width, wraplength.""" Widget.__init__(self, master, 'checkbutton', cnf, kw) + def _setup(self, master, cnf): + if not cnf.get('name'): + global _checkbutton_count + name = self.__class__.__name__.lower() + _checkbutton_count += 1 + cnf['name'] = f'!{name}{_checkbutton_count}' + super()._setup(master, cnf) + def deselect(self): """Put the button in off-state.""" self.tk.call(self._w, 'deselect') @@ -3610,7 +3648,7 @@ class Text(Widget, XView, YView): "lines", "xpixels" and "ypixels". There is an additional possible option "update", which if given then all subsequent options ensure that any possible out of date information is recalculated.""" - args = ['-%s' % arg for arg in args if not arg.startswith('-')] + args = ['-%s' % arg for arg in args] args += [index1, index2] res = self.tk.call(self._w, 'count', *args) or None if res is not None and len(args) <= 3: diff --git a/Lib/tkinter/commondialog.py b/Lib/tkinter/commondialog.py index e595c99defb..86f5387e001 100644 --- a/Lib/tkinter/commondialog.py +++ b/Lib/tkinter/commondialog.py @@ -10,7 +10,7 @@ __all__ = ["Dialog"] -from tkinter import Frame, _get_temp_root, _destroy_temp_root +from tkinter import _get_temp_root, _destroy_temp_root class Dialog: diff --git a/Lib/tkinter/dialog.py b/Lib/tkinter/dialog.py index 8ae21401172..36ae6c277cb 100644 --- a/Lib/tkinter/dialog.py +++ b/Lib/tkinter/dialog.py @@ -11,7 +11,7 @@ class Dialog(Widget): def __init__(self, master=None, cnf={}, **kw): cnf = _cnfmerge((cnf, kw)) self.widgetName = '__dialog__' - Widget._setup(self, master, cnf) + self._setup(master, cnf) self.num = self.tk.getint( self.tk.call( 'tk_dialog', self._w, diff --git a/Lib/tkinter/test/test_tkinter/__init__.py b/Lib/tkinter/test/test_tkinter/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/Lib/tkinter/test/test_tkinter/test_text.py b/Lib/tkinter/test/test_tkinter/test_text.py deleted file mode 100644 index 482f150df55..00000000000 --- a/Lib/tkinter/test/test_tkinter/test_text.py +++ /dev/null @@ -1,45 +0,0 @@ -import unittest -import tkinter -from test.support import requires -from tkinter.test.support import AbstractTkTest - -requires('gui') - -class TextTest(AbstractTkTest, unittest.TestCase): - - def setUp(self): - super().setUp() - self.text = tkinter.Text(self.root) - - def test_debug(self): - text = self.text - olddebug = text.debug() - try: - text.debug(0) - self.assertEqual(text.debug(), 0) - text.debug(1) - self.assertEqual(text.debug(), 1) - finally: - text.debug(olddebug) - self.assertEqual(text.debug(), olddebug) - - def test_search(self): - text = self.text - - # pattern and index are obligatory arguments. - self.assertRaises(tkinter.TclError, text.search, None, '1.0') - self.assertRaises(tkinter.TclError, text.search, 'a', None) - self.assertRaises(tkinter.TclError, text.search, None, None) - - # Invalid text index. - self.assertRaises(tkinter.TclError, text.search, '', 0) - - # Check if we are getting the indices as strings -- you are likely - # to get Tcl_Obj under Tk 8.5 if Tkinter doesn't convert it. - text.insert('1.0', 'hi-test') - self.assertEqual(text.search('-test', '1.0', 'end'), '1.2') - self.assertEqual(text.search('test', '1.0', 'end'), '1.3') - - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/tkinter/test/test_ttk/__init__.py b/Lib/tkinter/test/test_ttk/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/Lib/tkinter/tix.py b/Lib/tkinter/tix.py index 44ecae1a326..ce218265d4a 100644 --- a/Lib/tkinter/tix.py +++ b/Lib/tkinter/tix.py @@ -310,7 +310,7 @@ class TixWidget(tkinter.Widget): del cnf[k] self.widgetName = widgetName - Widget._setup(self, master, cnf) + self._setup(master, cnf) # If widgetName is None, this is a dummy creation call where the # corresponding Tk widget has already been created by Tix diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py index acdd565ec48..efeabb7a92c 100644 --- a/Lib/tkinter/ttk.py +++ b/Lib/tkinter/ttk.py @@ -28,23 +28,6 @@ __all__ = ["Button", "Checkbutton", "Combobox", "Entry", "Frame", "Label", import tkinter from tkinter import _flatten, _join, _stringify, _splitdict -# Verify if Tk is new enough to not need the Tile package -_REQUIRE_TILE = True if tkinter.TkVersion < 8.5 else False - -def _load_tile(master): - if _REQUIRE_TILE: - import os - tilelib = os.environ.get('TILE_LIBRARY') - if tilelib: - # append custom tile path to the list of directories that - # Tcl uses when attempting to resolve packages with the package - # command - master.tk.eval( - 'global auto_path; ' - 'lappend auto_path {%s}' % tilelib) - - master.tk.eval('package require tile') # TclError may be raised here - master._tile_loaded = True def _format_optvalue(value, script=False): """Internal function.""" @@ -360,11 +343,6 @@ class Style(object): def __init__(self, master=None): master = setup_master(master) - - if not getattr(master, '_tile_loaded', False): - # Load tile now, if needed - _load_tile(master) - self.master = master self.tk = self.master.tk @@ -546,9 +524,6 @@ class Widget(tkinter.Widget): readonly, alternate, invalid """ master = setup_master(master) - if not getattr(master, '_tile_loaded', False): - # Load tile now, if needed - _load_tile(master) tkinter.Widget.__init__(self, master, widgetname, kw=kw) diff --git a/Lib/token.py b/Lib/token.py index 9d0c0bf0fb0..95b107c6643 100644 --- a/Lib/token.py +++ b/Lib/token.py @@ -1,5 +1,5 @@ """Token constants.""" -# Auto-generated by Tools/scripts/generate_token.py +# Auto-generated by Tools/build/generate_token.py __all__ = ['tok_name', 'ISTERMINAL', 'ISNONTERMINAL', 'ISEOF'] diff --git a/Lib/tokenize.py b/Lib/tokenize.py index 0b9e2383100..46d2224f5cc 100644 --- a/Lib/tokenize.py +++ b/Lib/tokenize.py @@ -143,6 +143,7 @@ for _prefix in _all_string_prefixes(): endpats[_prefix + '"'] = Double endpats[_prefix + "'''"] = Single3 endpats[_prefix + '"""'] = Double3 +del _prefix # A set of all of the single and triple quoted string prefixes, # including the opening quotes. @@ -153,6 +154,7 @@ for t in _all_string_prefixes(): single_quoted.add(u) for u in (t + '"""', t + "'''"): triple_quoted.add(u) +del t, u tabsize = 8 diff --git a/Lib/tomllib/__init__.py b/Lib/tomllib/__init__.py new file mode 100644 index 00000000000..ef91cb9d25d --- /dev/null +++ b/Lib/tomllib/__init__.py @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +__all__ = ("loads", "load", "TOMLDecodeError") + +from ._parser import TOMLDecodeError, load, loads + +# Pretend this exception was created here. +TOMLDecodeError.__module__ = __name__ diff --git a/Lib/tomllib/_parser.py b/Lib/tomllib/_parser.py new file mode 100644 index 00000000000..45ca7a89630 --- /dev/null +++ b/Lib/tomllib/_parser.py @@ -0,0 +1,691 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +from __future__ import annotations + +from collections.abc import Iterable +import string +from types import MappingProxyType +from typing import Any, BinaryIO, NamedTuple + +from ._re import ( + RE_DATETIME, + RE_LOCALTIME, + RE_NUMBER, + match_to_datetime, + match_to_localtime, + match_to_number, +) +from ._types import Key, ParseFloat, Pos + +ASCII_CTRL = frozenset(chr(i) for i in range(32)) | frozenset(chr(127)) + +# Neither of these sets include quotation mark or backslash. They are +# currently handled as separate cases in the parser functions. +ILLEGAL_BASIC_STR_CHARS = ASCII_CTRL - frozenset("\t") +ILLEGAL_MULTILINE_BASIC_STR_CHARS = ASCII_CTRL - frozenset("\t\n") + +ILLEGAL_LITERAL_STR_CHARS = ILLEGAL_BASIC_STR_CHARS +ILLEGAL_MULTILINE_LITERAL_STR_CHARS = ILLEGAL_MULTILINE_BASIC_STR_CHARS + +ILLEGAL_COMMENT_CHARS = ILLEGAL_BASIC_STR_CHARS + +TOML_WS = frozenset(" \t") +TOML_WS_AND_NEWLINE = TOML_WS | frozenset("\n") +BARE_KEY_CHARS = frozenset(string.ascii_letters + string.digits + "-_") +KEY_INITIAL_CHARS = BARE_KEY_CHARS | frozenset("\"'") +HEXDIGIT_CHARS = frozenset(string.hexdigits) + +BASIC_STR_ESCAPE_REPLACEMENTS = MappingProxyType( + { + "\\b": "\u0008", # backspace + "\\t": "\u0009", # tab + "\\n": "\u000A", # linefeed + "\\f": "\u000C", # form feed + "\\r": "\u000D", # carriage return + '\\"': "\u0022", # quote + "\\\\": "\u005C", # backslash + } +) + + +class TOMLDecodeError(ValueError): + """An error raised if a document is not valid TOML.""" + + +def load(fp: BinaryIO, /, *, parse_float: ParseFloat = float) -> dict[str, Any]: + """Parse TOML from a binary file object.""" + b = fp.read() + try: + s = b.decode() + except AttributeError: + raise TypeError( + "File must be opened in binary mode, e.g. use `open('foo.toml', 'rb')`" + ) from None + return loads(s, parse_float=parse_float) + + +def loads(s: str, /, *, parse_float: ParseFloat = float) -> dict[str, Any]: # noqa: C901 + """Parse TOML from a string.""" + + # The spec allows converting "\r\n" to "\n", even in string + # literals. Let's do so to simplify parsing. + src = s.replace("\r\n", "\n") + pos = 0 + out = Output(NestedDict(), Flags()) + header: Key = () + parse_float = make_safe_parse_float(parse_float) + + # Parse one statement at a time + # (typically means one line in TOML source) + while True: + # 1. Skip line leading whitespace + pos = skip_chars(src, pos, TOML_WS) + + # 2. Parse rules. Expect one of the following: + # - end of file + # - end of line + # - comment + # - key/value pair + # - append dict to list (and move to its namespace) + # - create dict (and move to its namespace) + # Skip trailing whitespace when applicable. + try: + char = src[pos] + except IndexError: + break + if char == "\n": + pos += 1 + continue + if char in KEY_INITIAL_CHARS: + pos = key_value_rule(src, pos, out, header, parse_float) + pos = skip_chars(src, pos, TOML_WS) + elif char == "[": + try: + second_char: str | None = src[pos + 1] + except IndexError: + second_char = None + out.flags.finalize_pending() + if second_char == "[": + pos, header = create_list_rule(src, pos, out) + else: + pos, header = create_dict_rule(src, pos, out) + pos = skip_chars(src, pos, TOML_WS) + elif char != "#": + raise suffixed_err(src, pos, "Invalid statement") + + # 3. Skip comment + pos = skip_comment(src, pos) + + # 4. Expect end of line or end of file + try: + char = src[pos] + except IndexError: + break + if char != "\n": + raise suffixed_err( + src, pos, "Expected newline or end of document after a statement" + ) + pos += 1 + + return out.data.dict + + +class Flags: + """Flags that map to parsed keys/namespaces.""" + + # Marks an immutable namespace (inline array or inline table). + FROZEN = 0 + # Marks a nest that has been explicitly created and can no longer + # be opened using the "[table]" syntax. + EXPLICIT_NEST = 1 + + def __init__(self) -> None: + self._flags: dict[str, dict] = {} + self._pending_flags: set[tuple[Key, int]] = set() + + def add_pending(self, key: Key, flag: int) -> None: + self._pending_flags.add((key, flag)) + + def finalize_pending(self) -> None: + for key, flag in self._pending_flags: + self.set(key, flag, recursive=False) + self._pending_flags.clear() + + def unset_all(self, key: Key) -> None: + cont = self._flags + for k in key[:-1]: + if k not in cont: + return + cont = cont[k]["nested"] + cont.pop(key[-1], None) + + def set(self, key: Key, flag: int, *, recursive: bool) -> None: # noqa: A003 + cont = self._flags + key_parent, key_stem = key[:-1], key[-1] + for k in key_parent: + if k not in cont: + cont[k] = {"flags": set(), "recursive_flags": set(), "nested": {}} + cont = cont[k]["nested"] + if key_stem not in cont: + cont[key_stem] = {"flags": set(), "recursive_flags": set(), "nested": {}} + cont[key_stem]["recursive_flags" if recursive else "flags"].add(flag) + + def is_(self, key: Key, flag: int) -> bool: + if not key: + return False # document root has no flags + cont = self._flags + for k in key[:-1]: + if k not in cont: + return False + inner_cont = cont[k] + if flag in inner_cont["recursive_flags"]: + return True + cont = inner_cont["nested"] + key_stem = key[-1] + if key_stem in cont: + cont = cont[key_stem] + return flag in cont["flags"] or flag in cont["recursive_flags"] + return False + + +class NestedDict: + def __init__(self) -> None: + # The parsed content of the TOML document + self.dict: dict[str, Any] = {} + + def get_or_create_nest( + self, + key: Key, + *, + access_lists: bool = True, + ) -> dict: + cont: Any = self.dict + for k in key: + if k not in cont: + cont[k] = {} + cont = cont[k] + if access_lists and isinstance(cont, list): + cont = cont[-1] + if not isinstance(cont, dict): + raise KeyError("There is no nest behind this key") + return cont + + def append_nest_to_list(self, key: Key) -> None: + cont = self.get_or_create_nest(key[:-1]) + last_key = key[-1] + if last_key in cont: + list_ = cont[last_key] + if not isinstance(list_, list): + raise KeyError("An object other than list found behind this key") + list_.append({}) + else: + cont[last_key] = [{}] + + +class Output(NamedTuple): + data: NestedDict + flags: Flags + + +def skip_chars(src: str, pos: Pos, chars: Iterable[str]) -> Pos: + try: + while src[pos] in chars: + pos += 1 + except IndexError: + pass + return pos + + +def skip_until( + src: str, + pos: Pos, + expect: str, + *, + error_on: frozenset[str], + error_on_eof: bool, +) -> Pos: + try: + new_pos = src.index(expect, pos) + except ValueError: + new_pos = len(src) + if error_on_eof: + raise suffixed_err(src, new_pos, f"Expected {expect!r}") from None + + if not error_on.isdisjoint(src[pos:new_pos]): + while src[pos] not in error_on: + pos += 1 + raise suffixed_err(src, pos, f"Found invalid character {src[pos]!r}") + return new_pos + + +def skip_comment(src: str, pos: Pos) -> Pos: + try: + char: str | None = src[pos] + except IndexError: + char = None + if char == "#": + return skip_until( + src, pos + 1, "\n", error_on=ILLEGAL_COMMENT_CHARS, error_on_eof=False + ) + return pos + + +def skip_comments_and_array_ws(src: str, pos: Pos) -> Pos: + while True: + pos_before_skip = pos + pos = skip_chars(src, pos, TOML_WS_AND_NEWLINE) + pos = skip_comment(src, pos) + if pos == pos_before_skip: + return pos + + +def create_dict_rule(src: str, pos: Pos, out: Output) -> tuple[Pos, Key]: + pos += 1 # Skip "[" + pos = skip_chars(src, pos, TOML_WS) + pos, key = parse_key(src, pos) + + if out.flags.is_(key, Flags.EXPLICIT_NEST) or out.flags.is_(key, Flags.FROZEN): + raise suffixed_err(src, pos, f"Cannot declare {key} twice") + out.flags.set(key, Flags.EXPLICIT_NEST, recursive=False) + try: + out.data.get_or_create_nest(key) + except KeyError: + raise suffixed_err(src, pos, "Cannot overwrite a value") from None + + if not src.startswith("]", pos): + raise suffixed_err(src, pos, "Expected ']' at the end of a table declaration") + return pos + 1, key + + +def create_list_rule(src: str, pos: Pos, out: Output) -> tuple[Pos, Key]: + pos += 2 # Skip "[[" + pos = skip_chars(src, pos, TOML_WS) + pos, key = parse_key(src, pos) + + if out.flags.is_(key, Flags.FROZEN): + raise suffixed_err(src, pos, f"Cannot mutate immutable namespace {key}") + # Free the namespace now that it points to another empty list item... + out.flags.unset_all(key) + # ...but this key precisely is still prohibited from table declaration + out.flags.set(key, Flags.EXPLICIT_NEST, recursive=False) + try: + out.data.append_nest_to_list(key) + except KeyError: + raise suffixed_err(src, pos, "Cannot overwrite a value") from None + + if not src.startswith("]]", pos): + raise suffixed_err(src, pos, "Expected ']]' at the end of an array declaration") + return pos + 2, key + + +def key_value_rule( + src: str, pos: Pos, out: Output, header: Key, parse_float: ParseFloat +) -> Pos: + pos, key, value = parse_key_value_pair(src, pos, parse_float) + key_parent, key_stem = key[:-1], key[-1] + abs_key_parent = header + key_parent + + relative_path_cont_keys = (header + key[:i] for i in range(1, len(key))) + for cont_key in relative_path_cont_keys: + # Check that dotted key syntax does not redefine an existing table + if out.flags.is_(cont_key, Flags.EXPLICIT_NEST): + raise suffixed_err(src, pos, f"Cannot redefine namespace {cont_key}") + # Containers in the relative path can't be opened with the table syntax or + # dotted key/value syntax in following table sections. + out.flags.add_pending(cont_key, Flags.EXPLICIT_NEST) + + if out.flags.is_(abs_key_parent, Flags.FROZEN): + raise suffixed_err( + src, pos, f"Cannot mutate immutable namespace {abs_key_parent}" + ) + + try: + nest = out.data.get_or_create_nest(abs_key_parent) + except KeyError: + raise suffixed_err(src, pos, "Cannot overwrite a value") from None + if key_stem in nest: + raise suffixed_err(src, pos, "Cannot overwrite a value") + # Mark inline table and array namespaces recursively immutable + if isinstance(value, (dict, list)): + out.flags.set(header + key, Flags.FROZEN, recursive=True) + nest[key_stem] = value + return pos + + +def parse_key_value_pair( + src: str, pos: Pos, parse_float: ParseFloat +) -> tuple[Pos, Key, Any]: + pos, key = parse_key(src, pos) + try: + char: str | None = src[pos] + except IndexError: + char = None + if char != "=": + raise suffixed_err(src, pos, "Expected '=' after a key in a key/value pair") + pos += 1 + pos = skip_chars(src, pos, TOML_WS) + pos, value = parse_value(src, pos, parse_float) + return pos, key, value + + +def parse_key(src: str, pos: Pos) -> tuple[Pos, Key]: + pos, key_part = parse_key_part(src, pos) + key: Key = (key_part,) + pos = skip_chars(src, pos, TOML_WS) + while True: + try: + char: str | None = src[pos] + except IndexError: + char = None + if char != ".": + return pos, key + pos += 1 + pos = skip_chars(src, pos, TOML_WS) + pos, key_part = parse_key_part(src, pos) + key += (key_part,) + pos = skip_chars(src, pos, TOML_WS) + + +def parse_key_part(src: str, pos: Pos) -> tuple[Pos, str]: + try: + char: str | None = src[pos] + except IndexError: + char = None + if char in BARE_KEY_CHARS: + start_pos = pos + pos = skip_chars(src, pos, BARE_KEY_CHARS) + return pos, src[start_pos:pos] + if char == "'": + return parse_literal_str(src, pos) + if char == '"': + return parse_one_line_basic_str(src, pos) + raise suffixed_err(src, pos, "Invalid initial character for a key part") + + +def parse_one_line_basic_str(src: str, pos: Pos) -> tuple[Pos, str]: + pos += 1 + return parse_basic_str(src, pos, multiline=False) + + +def parse_array(src: str, pos: Pos, parse_float: ParseFloat) -> tuple[Pos, list]: + pos += 1 + array: list = [] + + pos = skip_comments_and_array_ws(src, pos) + if src.startswith("]", pos): + return pos + 1, array + while True: + pos, val = parse_value(src, pos, parse_float) + array.append(val) + pos = skip_comments_and_array_ws(src, pos) + + c = src[pos : pos + 1] + if c == "]": + return pos + 1, array + if c != ",": + raise suffixed_err(src, pos, "Unclosed array") + pos += 1 + + pos = skip_comments_and_array_ws(src, pos) + if src.startswith("]", pos): + return pos + 1, array + + +def parse_inline_table(src: str, pos: Pos, parse_float: ParseFloat) -> tuple[Pos, dict]: + pos += 1 + nested_dict = NestedDict() + flags = Flags() + + pos = skip_chars(src, pos, TOML_WS) + if src.startswith("}", pos): + return pos + 1, nested_dict.dict + while True: + pos, key, value = parse_key_value_pair(src, pos, parse_float) + key_parent, key_stem = key[:-1], key[-1] + if flags.is_(key, Flags.FROZEN): + raise suffixed_err(src, pos, f"Cannot mutate immutable namespace {key}") + try: + nest = nested_dict.get_or_create_nest(key_parent, access_lists=False) + except KeyError: + raise suffixed_err(src, pos, "Cannot overwrite a value") from None + if key_stem in nest: + raise suffixed_err(src, pos, f"Duplicate inline table key {key_stem!r}") + nest[key_stem] = value + pos = skip_chars(src, pos, TOML_WS) + c = src[pos : pos + 1] + if c == "}": + return pos + 1, nested_dict.dict + if c != ",": + raise suffixed_err(src, pos, "Unclosed inline table") + if isinstance(value, (dict, list)): + flags.set(key, Flags.FROZEN, recursive=True) + pos += 1 + pos = skip_chars(src, pos, TOML_WS) + + +def parse_basic_str_escape( + src: str, pos: Pos, *, multiline: bool = False +) -> tuple[Pos, str]: + escape_id = src[pos : pos + 2] + pos += 2 + if multiline and escape_id in {"\\ ", "\\\t", "\\\n"}: + # Skip whitespace until next non-whitespace character or end of + # the doc. Error if non-whitespace is found before newline. + if escape_id != "\\\n": + pos = skip_chars(src, pos, TOML_WS) + try: + char = src[pos] + except IndexError: + return pos, "" + if char != "\n": + raise suffixed_err(src, pos, "Unescaped '\\' in a string") + pos += 1 + pos = skip_chars(src, pos, TOML_WS_AND_NEWLINE) + return pos, "" + if escape_id == "\\u": + return parse_hex_char(src, pos, 4) + if escape_id == "\\U": + return parse_hex_char(src, pos, 8) + try: + return pos, BASIC_STR_ESCAPE_REPLACEMENTS[escape_id] + except KeyError: + raise suffixed_err(src, pos, "Unescaped '\\' in a string") from None + + +def parse_basic_str_escape_multiline(src: str, pos: Pos) -> tuple[Pos, str]: + return parse_basic_str_escape(src, pos, multiline=True) + + +def parse_hex_char(src: str, pos: Pos, hex_len: int) -> tuple[Pos, str]: + hex_str = src[pos : pos + hex_len] + if len(hex_str) != hex_len or not HEXDIGIT_CHARS.issuperset(hex_str): + raise suffixed_err(src, pos, "Invalid hex value") + pos += hex_len + hex_int = int(hex_str, 16) + if not is_unicode_scalar_value(hex_int): + raise suffixed_err(src, pos, "Escaped character is not a Unicode scalar value") + return pos, chr(hex_int) + + +def parse_literal_str(src: str, pos: Pos) -> tuple[Pos, str]: + pos += 1 # Skip starting apostrophe + start_pos = pos + pos = skip_until( + src, pos, "'", error_on=ILLEGAL_LITERAL_STR_CHARS, error_on_eof=True + ) + return pos + 1, src[start_pos:pos] # Skip ending apostrophe + + +def parse_multiline_str(src: str, pos: Pos, *, literal: bool) -> tuple[Pos, str]: + pos += 3 + if src.startswith("\n", pos): + pos += 1 + + if literal: + delim = "'" + end_pos = skip_until( + src, + pos, + "'''", + error_on=ILLEGAL_MULTILINE_LITERAL_STR_CHARS, + error_on_eof=True, + ) + result = src[pos:end_pos] + pos = end_pos + 3 + else: + delim = '"' + pos, result = parse_basic_str(src, pos, multiline=True) + + # Add at maximum two extra apostrophes/quotes if the end sequence + # is 4 or 5 chars long instead of just 3. + if not src.startswith(delim, pos): + return pos, result + pos += 1 + if not src.startswith(delim, pos): + return pos, result + delim + pos += 1 + return pos, result + (delim * 2) + + +def parse_basic_str(src: str, pos: Pos, *, multiline: bool) -> tuple[Pos, str]: + if multiline: + error_on = ILLEGAL_MULTILINE_BASIC_STR_CHARS + parse_escapes = parse_basic_str_escape_multiline + else: + error_on = ILLEGAL_BASIC_STR_CHARS + parse_escapes = parse_basic_str_escape + result = "" + start_pos = pos + while True: + try: + char = src[pos] + except IndexError: + raise suffixed_err(src, pos, "Unterminated string") from None + if char == '"': + if not multiline: + return pos + 1, result + src[start_pos:pos] + if src.startswith('"""', pos): + return pos + 3, result + src[start_pos:pos] + pos += 1 + continue + if char == "\\": + result += src[start_pos:pos] + pos, parsed_escape = parse_escapes(src, pos) + result += parsed_escape + start_pos = pos + continue + if char in error_on: + raise suffixed_err(src, pos, f"Illegal character {char!r}") + pos += 1 + + +def parse_value( # noqa: C901 + src: str, pos: Pos, parse_float: ParseFloat +) -> tuple[Pos, Any]: + try: + char: str | None = src[pos] + except IndexError: + char = None + + # IMPORTANT: order conditions based on speed of checking and likelihood + + # Basic strings + if char == '"': + if src.startswith('"""', pos): + return parse_multiline_str(src, pos, literal=False) + return parse_one_line_basic_str(src, pos) + + # Literal strings + if char == "'": + if src.startswith("'''", pos): + return parse_multiline_str(src, pos, literal=True) + return parse_literal_str(src, pos) + + # Booleans + if char == "t": + if src.startswith("true", pos): + return pos + 4, True + if char == "f": + if src.startswith("false", pos): + return pos + 5, False + + # Arrays + if char == "[": + return parse_array(src, pos, parse_float) + + # Inline tables + if char == "{": + return parse_inline_table(src, pos, parse_float) + + # Dates and times + datetime_match = RE_DATETIME.match(src, pos) + if datetime_match: + try: + datetime_obj = match_to_datetime(datetime_match) + except ValueError as e: + raise suffixed_err(src, pos, "Invalid date or datetime") from e + return datetime_match.end(), datetime_obj + localtime_match = RE_LOCALTIME.match(src, pos) + if localtime_match: + return localtime_match.end(), match_to_localtime(localtime_match) + + # Integers and "normal" floats. + # The regex will greedily match any type starting with a decimal + # char, so needs to be located after handling of dates and times. + number_match = RE_NUMBER.match(src, pos) + if number_match: + return number_match.end(), match_to_number(number_match, parse_float) + + # Special floats + first_three = src[pos : pos + 3] + if first_three in {"inf", "nan"}: + return pos + 3, parse_float(first_three) + first_four = src[pos : pos + 4] + if first_four in {"-inf", "+inf", "-nan", "+nan"}: + return pos + 4, parse_float(first_four) + + raise suffixed_err(src, pos, "Invalid value") + + +def suffixed_err(src: str, pos: Pos, msg: str) -> TOMLDecodeError: + """Return a `TOMLDecodeError` where error message is suffixed with + coordinates in source.""" + + def coord_repr(src: str, pos: Pos) -> str: + if pos >= len(src): + return "end of document" + line = src.count("\n", 0, pos) + 1 + if line == 1: + column = pos + 1 + else: + column = pos - src.rindex("\n", 0, pos) + return f"line {line}, column {column}" + + return TOMLDecodeError(f"{msg} (at {coord_repr(src, pos)})") + + +def is_unicode_scalar_value(codepoint: int) -> bool: + return (0 <= codepoint <= 55295) or (57344 <= codepoint <= 1114111) + + +def make_safe_parse_float(parse_float: ParseFloat) -> ParseFloat: + """A decorator to make `parse_float` safe. + + `parse_float` must not return dicts or lists, because these types + would be mixed with parsed TOML tables and arrays, thus confusing + the parser. The returned decorated callable raises `ValueError` + instead of returning illegal types. + """ + # The default `float` callable never returns illegal types. Optimize it. + if parse_float is float: # type: ignore[comparison-overlap] + return float + + def safe_parse_float(float_str: str) -> Any: + float_value = parse_float(float_str) + if isinstance(float_value, (dict, list)): + raise ValueError("parse_float must not return dicts or lists") + return float_value + + return safe_parse_float diff --git a/Lib/tomllib/_re.py b/Lib/tomllib/_re.py new file mode 100644 index 00000000000..994bb7493fd --- /dev/null +++ b/Lib/tomllib/_re.py @@ -0,0 +1,107 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +from __future__ import annotations + +from datetime import date, datetime, time, timedelta, timezone, tzinfo +from functools import lru_cache +import re +from typing import Any + +from ._types import ParseFloat + +# E.g. +# - 00:32:00.999999 +# - 00:32:00 +_TIME_RE_STR = r"([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(?:\.([0-9]{1,6})[0-9]*)?" + +RE_NUMBER = re.compile( + r""" +0 +(?: + x[0-9A-Fa-f](?:_?[0-9A-Fa-f])* # hex + | + b[01](?:_?[01])* # bin + | + o[0-7](?:_?[0-7])* # oct +) +| +[+-]?(?:0|[1-9](?:_?[0-9])*) # dec, integer part +(?P + (?:\.[0-9](?:_?[0-9])*)? # optional fractional part + (?:[eE][+-]?[0-9](?:_?[0-9])*)? # optional exponent part +) +""", + flags=re.VERBOSE, +) +RE_LOCALTIME = re.compile(_TIME_RE_STR) +RE_DATETIME = re.compile( + rf""" +([0-9]{{4}})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01]) # date, e.g. 1988-10-27 +(?: + [Tt ] + {_TIME_RE_STR} + (?:([Zz])|([+-])([01][0-9]|2[0-3]):([0-5][0-9]))? # optional time offset +)? +""", + flags=re.VERBOSE, +) + + +def match_to_datetime(match: re.Match) -> datetime | date: + """Convert a `RE_DATETIME` match to `datetime.datetime` or `datetime.date`. + + Raises ValueError if the match does not correspond to a valid date + or datetime. + """ + ( + year_str, + month_str, + day_str, + hour_str, + minute_str, + sec_str, + micros_str, + zulu_time, + offset_sign_str, + offset_hour_str, + offset_minute_str, + ) = match.groups() + year, month, day = int(year_str), int(month_str), int(day_str) + if hour_str is None: + return date(year, month, day) + hour, minute, sec = int(hour_str), int(minute_str), int(sec_str) + micros = int(micros_str.ljust(6, "0")) if micros_str else 0 + if offset_sign_str: + tz: tzinfo | None = cached_tz( + offset_hour_str, offset_minute_str, offset_sign_str + ) + elif zulu_time: + tz = timezone.utc + else: # local date-time + tz = None + return datetime(year, month, day, hour, minute, sec, micros, tzinfo=tz) + + +@lru_cache(maxsize=None) +def cached_tz(hour_str: str, minute_str: str, sign_str: str) -> timezone: + sign = 1 if sign_str == "+" else -1 + return timezone( + timedelta( + hours=sign * int(hour_str), + minutes=sign * int(minute_str), + ) + ) + + +def match_to_localtime(match: re.Match) -> time: + hour_str, minute_str, sec_str, micros_str = match.groups() + micros = int(micros_str.ljust(6, "0")) if micros_str else 0 + return time(int(hour_str), int(minute_str), int(sec_str), micros) + + +def match_to_number(match: re.Match, parse_float: ParseFloat) -> Any: + if match.group("floatpart"): + return parse_float(match.group()) + return int(match.group(), 0) diff --git a/Lib/tomllib/_types.py b/Lib/tomllib/_types.py new file mode 100644 index 00000000000..d949412e03b --- /dev/null +++ b/Lib/tomllib/_types.py @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +from typing import Any, Callable, Tuple + +# Type annotations +ParseFloat = Callable[[str], Any] +Key = Tuple[str, ...] +Pos = int diff --git a/Lib/trace.py b/Lib/trace.py index 2cf3643878d..213e46517d6 100755 --- a/Lib/trace.py +++ b/Lib/trace.py @@ -172,7 +172,7 @@ class CoverageResults: try: with open(self.infile, 'rb') as f: counts, calledfuncs, callers = pickle.load(f) - self.update(self.__class__(counts, calledfuncs, callers)) + self.update(self.__class__(counts, calledfuncs, callers=callers)) except (OSError, EOFError, ValueError) as err: print(("Skipping counts file %r: %s" % (self.infile, err)), file=sys.stderr) diff --git a/Lib/traceback.py b/Lib/traceback.py index 97caa1372f4..c43c4720ae5 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -1,6 +1,6 @@ """Extract, format and print information about Python stack traces.""" -import collections +import collections.abc import itertools import linecache import sys @@ -98,7 +98,11 @@ def _parse_value_tb(exc, value, tb): raise ValueError("Both or neither of value and tb must be given") if value is tb is _sentinel: if exc is not None: - return exc, exc.__traceback__ + if isinstance(exc, BaseException): + return exc, exc.__traceback__ + + raise TypeError(f'Exception expected for value, ' + f'{type(exc).__name__} found') else: return None, None return value, tb @@ -159,18 +163,18 @@ def format_exception_only(exc, /, value=_sentinel): # -- not official API but folk probably use these two functions. def _format_final_exc_line(etype, value): - valuestr = _some_str(value) + valuestr = _safe_string(value, 'exception') if value is None or not valuestr: line = "%s\n" % etype else: line = "%s: %s\n" % (etype, valuestr) return line -def _some_str(value): +def _safe_string(value, what, func=str): try: - return str(value) + return func(value) except: - return '' + return f'<{what} {func.__name__}() failed>' # -- @@ -275,7 +279,8 @@ class FrameSummary: self._line = line if lookup_line: self.line - self.locals = {k: repr(v) for k, v in locals.items()} if locals else None + self.locals = {k: _safe_string(v, 'local', func=repr) + for k, v in locals.items()} if locals else None self.end_lineno = end_lineno self.colno = colno self.end_colno = end_colno @@ -461,7 +466,8 @@ class StackSummary(list): row.append(' File "{}", line {}, in {}\n'.format( frame_summary.filename, frame_summary.lineno, frame_summary.name)) if frame_summary.line: - row.append(' {}\n'.format(frame_summary.line.strip())) + stripped_line = frame_summary.line.strip() + row.append(' {}\n'.format(stripped_line)) orig_line_len = len(frame_summary._original_line) frame_line_len = len(frame_summary.line.lstrip()) @@ -470,31 +476,34 @@ class StackSummary(list): frame_summary.colno is not None and frame_summary.end_colno is not None ): - colno = _byte_offset_to_character_offset( - frame_summary._original_line, frame_summary.colno) - end_colno = _byte_offset_to_character_offset( - frame_summary._original_line, frame_summary.end_colno) + start_offset = _byte_offset_to_character_offset( + frame_summary._original_line, frame_summary.colno) + 1 + end_offset = _byte_offset_to_character_offset( + frame_summary._original_line, frame_summary.end_colno) + 1 anchors = None if frame_summary.lineno == frame_summary.end_lineno: with suppress(Exception): anchors = _extract_caret_anchors_from_line_segment( - frame_summary._original_line[colno - 1:end_colno - 1] + frame_summary._original_line[start_offset - 1:end_offset - 1] ) else: - end_colno = stripped_characters + len(frame_summary.line.strip()) + end_offset = stripped_characters + len(stripped_line) - row.append(' ') - row.append(' ' * (colno - stripped_characters)) + # show indicators if primary char doesn't span the frame line + if end_offset - start_offset < len(stripped_line) or ( + anchors and anchors.right_start_offset - anchors.left_end_offset > 0): + row.append(' ') + row.append(' ' * (start_offset - stripped_characters)) - if anchors: - row.append(anchors.primary_char * (anchors.left_end_offset)) - row.append(anchors.secondary_char * (anchors.right_start_offset - anchors.left_end_offset)) - row.append(anchors.primary_char * (end_colno - colno - anchors.right_start_offset)) - else: - row.append('^' * (end_colno - colno)) + if anchors: + row.append(anchors.primary_char * (anchors.left_end_offset)) + row.append(anchors.secondary_char * (anchors.right_start_offset - anchors.left_end_offset)) + row.append(anchors.primary_char * (end_offset - start_offset - anchors.right_start_offset)) + else: + row.append('^' * (end_offset - start_offset)) - row.append('\n') + row.append('\n') if frame_summary.locals: for name, value in sorted(frame_summary.locals.items()): @@ -552,10 +561,7 @@ class StackSummary(list): def _byte_offset_to_character_offset(str, offset): as_utf8 = str.encode('utf-8') - if offset > len(as_utf8): - offset = len(as_utf8) - - return len(as_utf8[:offset + 1].decode("utf-8")) + return len(as_utf8[:offset].decode("utf-8", errors="replace")) _Anchors = collections.namedtuple( @@ -580,12 +586,15 @@ def _extract_caret_anchors_from_line_segment(segment): if len(tree.body) != 1: return None + normalize = lambda offset: _byte_offset_to_character_offset(segment, offset) statement = tree.body[0] match statement: case ast.Expr(expr): match expr: case ast.BinOp(): - operator_str = segment[expr.left.end_col_offset:expr.right.col_offset] + operator_start = normalize(expr.left.end_col_offset) + operator_end = normalize(expr.right.col_offset) + operator_str = segment[operator_start:operator_end] operator_offset = len(operator_str) - len(operator_str.lstrip()) left_anchor = expr.left.end_col_offset + operator_offset @@ -595,9 +604,11 @@ def _extract_caret_anchors_from_line_segment(segment): and not operator_str[operator_offset + 1].isspace() ): right_anchor += 1 - return _Anchors(left_anchor, right_anchor) + return _Anchors(normalize(left_anchor), normalize(right_anchor)) case ast.Subscript(): - return _Anchors(expr.value.end_col_offset, expr.slice.end_col_offset + 1) + subscript_start = normalize(expr.value.end_col_offset) + subscript_end = normalize(expr.slice.end_col_offset + 1) + return _Anchors(subscript_start, subscript_end) return None @@ -684,7 +695,9 @@ class TracebackException: self.exc_type = exc_type # Capture now to permit freeing resources: only complication is in the # unofficial API _format_final_exc_line - self._str = _some_str(exc_value) + self._str = _safe_string(exc_value, 'exception') + self.__notes__ = getattr(exc_value, '__notes__', None) + if exc_type and issubclass(exc_type, SyntaxError): # Handle SyntaxError's specially self.filename = exc_value.filename @@ -696,6 +709,25 @@ class TracebackException: self.offset = exc_value.offset self.end_offset = exc_value.end_offset self.msg = exc_value.msg + elif exc_type and issubclass(exc_type, ImportError) and \ + getattr(exc_value, "name_from", None) is not None: + wrong_name = getattr(exc_value, "name_from", None) + suggestion = _compute_suggestion_error(exc_value, exc_traceback, wrong_name) + if suggestion: + self._str += f". Did you mean: '{suggestion}'?" + elif exc_type and issubclass(exc_type, (NameError, AttributeError)) and \ + getattr(exc_value, "name", None) is not None: + wrong_name = getattr(exc_value, "name", None) + suggestion = _compute_suggestion_error(exc_value, exc_traceback, wrong_name) + if suggestion: + self._str += f". Did you mean: '{suggestion}'?" + if issubclass(exc_type, NameError): + wrong_name = getattr(exc_value, "name", None) + if wrong_name is not None and wrong_name in sys.stdlib_module_names: + if suggestion: + self._str += f" Or did you forget to import '{wrong_name}'" + else: + self._str += f". Did you forget to import '{wrong_name}'" if lookup_lines: self._load_lines() self.__suppress_context__ = \ @@ -808,12 +840,20 @@ class TracebackException: stype = self.exc_type.__qualname__ smod = self.exc_type.__module__ if smod not in ("__main__", "builtins"): + if not isinstance(smod, str): + smod = "" stype = smod + '.' + stype if not issubclass(self.exc_type, SyntaxError): yield _format_final_exc_line(stype, self._str) else: yield from self._format_syntax_error(stype) + if isinstance(self.__notes__, collections.abc.Sequence): + for note in self.__notes__: + note = _safe_string(note, 'note') + yield from [l + '\n' for l in note.split('\n')] + elif self.__notes__ is not None: + yield _safe_string(self.__notes__, '__notes__', func=repr) def _format_syntax_error(self, stype): """Format SyntaxError exceptions (internal helper).""" @@ -903,7 +943,7 @@ class TracebackException: # format exception group is_toplevel = (_ctx.exception_group_depth == 0) if is_toplevel: - _ctx.exception_group_depth += 1 + _ctx.exception_group_depth += 1 if exc.stack: yield from _ctx.emit( @@ -958,3 +998,140 @@ class TracebackException: file = sys.stderr for line in self.format(chain=chain): print(line, file=file, end="") + + +_MAX_CANDIDATE_ITEMS = 750 +_MAX_STRING_SIZE = 40 +_MOVE_COST = 2 +_CASE_COST = 1 + + +def _substitution_cost(ch_a, ch_b): + if ch_a == ch_b: + return 0 + if ch_a.lower() == ch_b.lower(): + return _CASE_COST + return _MOVE_COST + + +def _compute_suggestion_error(exc_value, tb, wrong_name): + if wrong_name is None or not isinstance(wrong_name, str): + return None + if isinstance(exc_value, AttributeError): + obj = exc_value.obj + try: + d = dir(obj) + except Exception: + return None + elif isinstance(exc_value, ImportError): + try: + mod = __import__(exc_value.name) + d = dir(mod) + except Exception: + return None + else: + assert isinstance(exc_value, NameError) + # find most recent frame + if tb is None: + return None + while tb.tb_next is not None: + tb = tb.tb_next + frame = tb.tb_frame + d = ( + list(frame.f_locals) + + list(frame.f_globals) + + list(frame.f_builtins) + ) + + # Check first if we are in a method and the instance + # has the wrong name as attribute + if 'self' in frame.f_locals: + self = frame.f_locals['self'] + if hasattr(self, wrong_name): + return f"self.{wrong_name}" + + # Compute closest match + + if len(d) > _MAX_CANDIDATE_ITEMS: + return None + wrong_name_len = len(wrong_name) + if wrong_name_len > _MAX_STRING_SIZE: + return None + best_distance = wrong_name_len + suggestion = None + for possible_name in d: + if possible_name == wrong_name: + # A missing attribute is "found". Don't suggest it (see GH-88821). + continue + # No more than 1/3 of the involved characters should need changed. + max_distance = (len(possible_name) + wrong_name_len + 3) * _MOVE_COST // 6 + # Don't take matches we've already beaten. + max_distance = min(max_distance, best_distance - 1) + current_distance = _levenshtein_distance(wrong_name, possible_name, max_distance) + if current_distance > max_distance: + continue + if not suggestion or current_distance < best_distance: + suggestion = possible_name + best_distance = current_distance + return suggestion + + +def _levenshtein_distance(a, b, max_cost): + # A Python implementation of Python/suggestions.c:levenshtein_distance. + + # Both strings are the same + if a == b: + return 0 + + # Trim away common affixes + pre = 0 + while a[pre:] and b[pre:] and a[pre] == b[pre]: + pre += 1 + a = a[pre:] + b = b[pre:] + post = 0 + while a[:post or None] and b[:post or None] and a[post-1] == b[post-1]: + post -= 1 + a = a[:post or None] + b = b[:post or None] + if not a or not b: + return _MOVE_COST * (len(a) + len(b)) + if len(a) > _MAX_STRING_SIZE or len(b) > _MAX_STRING_SIZE: + return max_cost + 1 + + # Prefer shorter buffer + if len(b) < len(a): + a, b = b, a + + # Quick fail when a match is impossible + if (len(b) - len(a)) * _MOVE_COST > max_cost: + return max_cost + 1 + + # Instead of producing the whole traditional len(a)-by-len(b) + # matrix, we can update just one row in place. + # Initialize the buffer row + row = list(range(_MOVE_COST, _MOVE_COST * (len(a) + 1), _MOVE_COST)) + + result = 0 + for bindex in range(len(b)): + bchar = b[bindex] + distance = result = bindex * _MOVE_COST + minimum = sys.maxsize + for index in range(len(a)): + # 1) Previous distance in this row is cost(b[:b_index], a[:index]) + substitute = distance + _substitution_cost(bchar, a[index]) + # 2) cost(b[:b_index], a[:index+1]) from previous row + distance = row[index] + # 3) existing result is cost(b[:b_index+1], a[index]) + + insert_delete = min(result, distance) + _MOVE_COST + result = min(insert_delete, substitute) + + # cost(b[:b_index+1], a[:index+1]) + row[index] = result + if result < minimum: + minimum = result + if minimum > max_cost: + # Everything in this row is too big, so bail early. + return max_cost + 1 + return result diff --git a/Lib/turtle.py b/Lib/turtle.py index d5e715efec9..6abf9f7f65a 100644 --- a/Lib/turtle.py +++ b/Lib/turtle.py @@ -596,7 +596,6 @@ class TurtleScreenBase(object): item = self.cv.create_text(x-1, -y, text = txt, anchor = anchor[align], fill = pencolor, font = font) x0, y0, x1, y1 = self.cv.bbox(item) - self.cv.update() return item, x1-1 ## def _dot(self, pos, size, color): @@ -2863,10 +2862,10 @@ class RawTurtle(TPen, TNavigator): >>> turtle.stamp() >>> turtle.fd(50) """ - warnings.warn("turtle.RawTurtle.settiltangle() is deprecated since " - "Python 3.1 and scheduled for removal in Python 3.13." - "Use tiltangle() instead.", - DeprecationWarning) + warnings._deprecated("turtle.RawTurtle.settiltangle()", + "{name!r} is deprecated since Python 3.1 and scheduled " + "for removal in Python {remove}. Use tiltangle() instead.", + remove=(3, 13)) self.tiltangle(angle) def tiltangle(self, angle=None): @@ -3419,6 +3418,7 @@ class RawTurtle(TPen, TNavigator): """ item, end = self.screen._write(self._position, txt, align, font, self._pencolor) + self._update() self.items.append(item) if self.undobuffer: self.undobuffer.push(("wri", item)) diff --git a/Lib/turtledemo/clock.py b/Lib/turtledemo/clock.py index 62c8851606b..9f8585bd11e 100755 --- a/Lib/turtledemo/clock.py +++ b/Lib/turtledemo/clock.py @@ -109,7 +109,6 @@ def tick(): writer.write(datum(t), align="center", font=("Courier", 14, "bold")) writer.forward(85) - tracer(True) second_hand.setheading(6*sekunde) # or here minute_hand.setheading(6*minute) hour_hand.setheading(30*stunde) diff --git a/Lib/types.py b/Lib/types.py index ce1c28d5625..aa8a1c84722 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -52,17 +52,14 @@ ModuleType = type(sys) try: raise TypeError -except TypeError: - tb = sys.exc_info()[2] - TracebackType = type(tb) - FrameType = type(tb.tb_frame) - tb = None; del tb +except TypeError as exc: + TracebackType = type(exc.__traceback__) + FrameType = type(exc.__traceback__.tb_frame) -# For Jython, the following two types are identical GetSetDescriptorType = type(FunctionType.__code__) MemberDescriptorType = type(FunctionType.__globals__) -del sys, _f, _g, _C, _c, _ag # Not for export +del sys, _f, _g, _C, _c, _ag, _cell_factory # Not for export # Provide a PEP 3115 compliant mechanism for class creation diff --git a/Lib/typing.py b/Lib/typing.py index 031aa24eaf4..bdf51bb5f41 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -5,7 +5,7 @@ At large scale, the structure of the module is following: * Imports and exports, all public names should be explicitly added to __all__. * Internal helper functions: these should never be used in code outside this module. * _SpecialForm and its instances (special forms): - Any, NoReturn, ClassVar, Union, Optional, Concatenate + Any, NoReturn, Never, ClassVar, Union, Optional, Concatenate, Unpack * Classes whose instances can be type arguments in addition to types: ForwardRef, TypeVar and ParamSpec * The core of internal generics API: _GenericAlias and _VariadicGenericAlias, the latter is @@ -21,6 +21,7 @@ At large scale, the structure of the module is following: from abc import abstractmethod, ABCMeta import collections +from collections import defaultdict import collections.abc import contextlib import functools @@ -56,6 +57,7 @@ __all__ = [ 'Tuple', 'Type', 'TypeVar', + 'TypeVarTuple', 'Union', # ABCs (from collections.abc). @@ -117,24 +119,36 @@ __all__ = [ # One-off things. 'AnyStr', + 'assert_type', + 'assert_never', 'cast', + 'clear_overloads', + 'dataclass_transform', 'final', 'get_args', 'get_origin', + 'get_overloads', 'get_type_hints', 'is_typeddict', + 'LiteralString', + 'Never', 'NewType', 'no_type_check', 'no_type_check_decorator', 'NoReturn', + 'NotRequired', 'overload', 'ParamSpecArgs', 'ParamSpecKwargs', + 'Required', + 'reveal_type', 'runtime_checkable', + 'Self', 'Text', 'TYPE_CHECKING', 'TypeAlias', 'TypeGuard', + 'Unpack', ] # The pseudo-submodules 're' and 'io' are part of the public @@ -142,16 +156,16 @@ __all__ = [ # legitimate imports of those modules. -def _type_convert(arg, module=None): +def _type_convert(arg, module=None, *, allow_special_forms=False): """For converting None to type(None), and strings to ForwardRef.""" if arg is None: return type(None) if isinstance(arg, str): - return ForwardRef(arg, module=module) + return ForwardRef(arg, module=module, is_class=allow_special_forms) return arg -def _type_check(arg, msg, is_argument=True, module=None, *, is_class=False): +def _type_check(arg, msg, is_argument=True, module=None, *, allow_special_forms=False): """Check that the argument is a type, and return it (internal helper). As a special case, accept None and return type(None) instead. Also wrap strings @@ -164,22 +178,22 @@ def _type_check(arg, msg, is_argument=True, module=None, *, is_class=False): We append the repr() of the actual value (truncated to 100 chars). """ invalid_generic_forms = (Generic, Protocol) - if not is_class: + if not allow_special_forms: invalid_generic_forms += (ClassVar,) if is_argument: invalid_generic_forms += (Final,) - arg = _type_convert(arg, module=module) + arg = _type_convert(arg, module=module, allow_special_forms=allow_special_forms) if (isinstance(arg, _GenericAlias) and arg.__origin__ in invalid_generic_forms): raise TypeError(f"{arg} is not valid as type argument") - if arg in (Any, NoReturn, Final): + if arg in (Any, LiteralString, NoReturn, Never, Self, TypeAlias): + return arg + if allow_special_forms and arg in (ClassVar, Final): return arg if isinstance(arg, _SpecialForm) or arg in (Generic, Protocol): raise TypeError(f"Plain {arg} is not valid as type argument") - if isinstance(arg, (type, TypeVar, ForwardRef, types.UnionType, ParamSpec)): - return arg - if not callable(arg): + if type(arg) is tuple: raise TypeError(f"{msg} Got {arg!r:.100}.") return arg @@ -189,6 +203,24 @@ def _is_param_expr(arg): (tuple, list, ParamSpec, _ConcatenateGenericAlias)) +def _should_unflatten_callable_args(typ, args): + """Internal helper for munging collections.abc.Callable's __args__. + + The canonical representation for a Callable's __args__ flattens the + argument types, see https://bugs.python.org/issue42195. For example: + + collections.abc.Callable[[int, int], str].__args__ == (int, int, str) + collections.abc.Callable[ParamSpec, str].__args__ == (ParamSpec, str) + + As a result, if we need to reconstruct the Callable from its __args__, + we need to unflatten it. + """ + return ( + typ.__origin__ is collections.abc.Callable + and not (len(args) == 2 and _is_param_expr(args[0])) + ) + + def _type_repr(obj): """Return the repr() of an object, special-casing types (internal helper). @@ -210,21 +242,25 @@ def _type_repr(obj): return repr(obj) -def _collect_type_vars(types_, typevar_types=None): - """Collect all type variable contained - in types in order of first appearance (lexicographic order). For example:: +def _collect_parameters(args): + """Collect all type variables and parameter specifications in args + in order of first appearance (lexicographic order). For example:: - _collect_type_vars((T, List[S, T])) == (T, S) + _collect_parameters((T, Callable[P, T])) == (T, P) """ - if typevar_types is None: - typevar_types = TypeVar - tvars = [] - for t in types_: - if isinstance(t, typevar_types) and t not in tvars: - tvars.append(t) - if isinstance(t, (_GenericAlias, GenericAlias, types.UnionType)): - tvars.extend([t for t in t.__parameters__ if t not in tvars]) - return tuple(tvars) + parameters = [] + for t in args: + # We don't want __parameters__ descriptor of a bare Python class. + if isinstance(t, type): + continue + if hasattr(t, '__typing_subst__'): + if t not in parameters: + parameters.append(t) + else: + for x in getattr(t, '__parameters__', ()): + if x not in parameters: + parameters.append(x) + return tuple(parameters) def _check_generic(cls, parameters, elen): @@ -238,24 +274,15 @@ def _check_generic(cls, parameters, elen): raise TypeError(f"Too {'many' if alen > elen else 'few'} arguments for {cls};" f" actual {alen}, expected {elen}") -def _prepare_paramspec_params(cls, params): - """Prepares the parameters for a Generic containing ParamSpec - variables (internal helper). - """ - # Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612. - if (len(cls.__parameters__) == 1 - and params and not _is_param_expr(params[0])): - assert isinstance(cls.__parameters__[0], ParamSpec) - return (params,) - else: - _check_generic(cls, params, len(cls.__parameters__)) - _params = [] - # Convert lists to tuples to help other libraries cache the results. - for p, tvar in zip(params, cls.__parameters__): - if isinstance(tvar, ParamSpec) and isinstance(p, list): - p = tuple(p) - _params.append(p) - return tuple(_params) +def _unpack_args(args): + newargs = [] + for arg in args: + subargs = getattr(arg, '__typing_unpacked_tuple_args__', None) + if subargs is not None and not (subargs and subargs[-1] is ...): + newargs.extend(subargs) + else: + newargs.append(arg) + return newargs def _deduplicate(params): # Weed out strict duplicates, preserving the first of each occurrence. @@ -280,8 +307,6 @@ def _remove_dups_flatten(parameters): for p in parameters: if isinstance(p, (_UnionGenericAlias, types.UnionType)): params.extend(p.__args__) - elif isinstance(p, tuple) and len(p) > 0 and p[0] is Union: - params.extend(p[1:]) else: params.append(p) @@ -300,6 +325,7 @@ def _flatten_literal_params(parameters): _cleanups = [] +_caches = {} def _tp_cache(func=None, /, *, typed=False): @@ -307,13 +333,20 @@ def _tp_cache(func=None, /, *, typed=False): original function for non-hashable arguments. """ def decorator(func): - cached = functools.lru_cache(typed=typed)(func) - _cleanups.append(cached.cache_clear) + # The callback 'inner' references the newly created lru_cache + # indirectly by performing a lookup in the global '_caches' dictionary. + # This breaks a reference that can be problematic when combined with + # C API extensions that leak references to types. See GH-98253. + + cache = functools.lru_cache(typed=typed)(func) + _caches[func] = cache + _cleanups.append(cache.cache_clear) + del cache @functools.wraps(func) def inner(*args, **kwds): try: - return cached(*args, **kwds) + return _caches[func](*args, **kwds) except TypeError: pass # All real errors (not unhashable args) are raised below. return func(*args, **kwds) @@ -327,12 +360,24 @@ def _tp_cache(func=None, /, *, typed=False): def _eval_type(t, globalns, localns, recursive_guard=frozenset()): """Evaluate all forward references in the given type t. For use of globalns and localns see the docstring for get_type_hints(). - recursive_guard is used to prevent prevent infinite recursion - with recursive ForwardRef. + recursive_guard is used to prevent infinite recursion with a recursive + ForwardRef. """ if isinstance(t, ForwardRef): return t._evaluate(globalns, localns, recursive_guard) if isinstance(t, (_GenericAlias, GenericAlias, types.UnionType)): + if isinstance(t, GenericAlias): + args = tuple( + ForwardRef(arg) if isinstance(arg, str) else arg + for arg in t.__args__ + ) + is_unpacked = t.__unpacked__ + if _should_unflatten_callable_args(t, args): + t = t.__origin__[(args[:-1], args[-1])] + else: + t = t.__origin__[args] + if is_unpacked: + t = Unpack[t] ev_args = tuple(_eval_type(a, globalns, localns, recursive_guard) for a in t.__args__) if ev_args == t.__args__: return t @@ -350,7 +395,7 @@ class _Final: __slots__ = ('__weakref__',) - def __init_subclass__(self, /, *args, **kwds): + def __init_subclass__(cls, /, *args, **kwds): if '_root' not in kwds: raise TypeError("Cannot subclass special typing classes") @@ -365,9 +410,25 @@ class _Immutable: return self +class _NotIterable: + """Mixin to prevent iteration, without being compatible with Iterable. + + That is, we could do: + def __iter__(self): raise TypeError() + But this would make users of this mixin duck type-compatible with + collections.abc.Iterable - isinstance(foo, Iterable) would be True. + + Luckily, we can instead prevent iteration by setting __iter__ to None, which + is treated specially. + """ + + __slots__ = () + __iter__ = None + + # Internal indicator of special typing constructs. # See __doc__ instance attribute for specific docs. -class _SpecialForm(_Final, _root=True): +class _SpecialForm(_Final, _NotIterable, _root=True): __slots__ = ('_name', '__doc__', '_getitem') def __init__(self, getitem): @@ -417,8 +478,19 @@ class _LiteralSpecialForm(_SpecialForm, _root=True): return self._getitem(self, *parameters) -@_SpecialForm -def Any(self, parameters): +class _AnyMeta(type): + def __instancecheck__(self, obj): + if self is Any: + raise TypeError("typing.Any cannot be used with isinstance()") + return super().__instancecheck__(obj) + + def __repr__(self): + if self is Any: + return "typing.Any" + return super().__repr__() # respect to subclasses + + +class Any(metaclass=_AnyMeta): """Special type indicating an unconstrained type. - Any is compatible with every type. @@ -427,9 +499,13 @@ def Any(self, parameters): Note that all the above statements are true from the point of view of static type checkers. At runtime, Any should not be used with instance - or class checks. + checks. """ - raise TypeError(f"{self} is not subscriptable") + def __new__(cls, *args, **kwargs): + if cls is Any: + raise TypeError("Any cannot be instantiated") + return super().__new__(cls, *args, **kwargs) + @_SpecialForm def NoReturn(self, parameters): @@ -441,11 +517,91 @@ def NoReturn(self, parameters): def stop() -> NoReturn: raise Exception('no way') - This type is invalid in other positions, e.g., ``List[NoReturn]`` - will fail in static type checkers. + NoReturn can also be used as a bottom type, a type that + has no values. Starting in Python 3.11, the Never type should + be used for this concept instead. Type checkers should treat the two + equivalently. + """ raise TypeError(f"{self} is not subscriptable") +# This is semantically identical to NoReturn, but it is implemented +# separately so that type checkers can distinguish between the two +# if they want. +@_SpecialForm +def Never(self, parameters): + """The bottom type, a type that has no members. + + This can be used to define a function that should never be + called, or a function that never returns:: + + from typing import Never + + def never_call_me(arg: Never) -> None: + pass + + def int_or_str(arg: int | str) -> None: + never_call_me(arg) # type checker error + match arg: + case int(): + print("It's an int") + case str(): + print("It's a str") + case _: + never_call_me(arg) # ok, arg is of type Never + + """ + raise TypeError(f"{self} is not subscriptable") + + +@_SpecialForm +def Self(self, parameters): + """Used to spell the type of "self" in classes. + + Example:: + + from typing import Self + + class Foo: + def return_self(self) -> Self: + ... + return self + + This is especially useful for: + - classmethods that are used as alternative constructors + - annotating an `__enter__` method which returns self + """ + raise TypeError(f"{self} is not subscriptable") + + +@_SpecialForm +def LiteralString(self, parameters): + """Represents an arbitrary literal string. + + Example:: + + from typing import LiteralString + + def run_query(sql: LiteralString) -> ... + ... + + def caller(arbitrary_string: str, literal_string: LiteralString) -> None: + run_query("SELECT * FROM students") # ok + run_query(literal_string) # ok + run_query("SELECT * FROM " + literal_string) # ok + run_query(arbitrary_string) # type checker error + run_query( # type checker error + f"SELECT * FROM students WHERE name = {arbitrary_string}" + ) + + Only string literals and other LiteralStrings are compatible + with LiteralString. This provides a tool to help prevent + security issues such as SQL injection. + + """ + raise TypeError(f"{self} is not subscriptable") + + @_SpecialForm def ClassVar(self, parameters): """Special type construct to mark class variables. @@ -602,12 +758,13 @@ def Concatenate(self, parameters): raise TypeError("Cannot take a Concatenate of no types.") if not isinstance(parameters, tuple): parameters = (parameters,) - if not isinstance(parameters[-1], ParamSpec): + if not (parameters[-1] is ... or isinstance(parameters[-1], ParamSpec)): raise TypeError("The last parameter to Concatenate should be a " - "ParamSpec variable.") + "ParamSpec variable or ellipsis.") msg = "Concatenate[arg, ...]: each arg must be a type." - parameters = tuple(_type_check(p, msg) for p in parameters) - return _ConcatenateGenericAlias(self, parameters) + parameters = (*(_type_check(p, msg) for p in parameters[:-1]), parameters[-1]) + return _ConcatenateGenericAlias(self, parameters, + _paramspec_tvars=True) @_SpecialForm @@ -669,10 +826,19 @@ class ForwardRef(_Final, _root=True): def __init__(self, arg, is_argument=True, module=None, *, is_class=False): if not isinstance(arg, str): raise TypeError(f"Forward reference must be a string -- got {arg!r}") + + # If we do `def f(*args: *Ts)`, then we'll have `arg = '*Ts'`. + # Unfortunately, this isn't a valid expression on its own, so we + # do the unpacking manually. + if arg[0] == '*': + arg_to_compile = f'({arg},)[0]' # E.g. (*Ts,)[0] or (*tuple[int, int],)[0] + else: + arg_to_compile = arg try: - code = compile(arg, '', 'eval') + code = compile(arg_to_compile, '', 'eval') except SyntaxError: raise SyntaxError(f"Forward reference must be an expression -- got {arg!r}") + self.__forward_arg__ = arg self.__forward_code__ = code self.__forward_evaluated__ = False @@ -699,7 +865,7 @@ class ForwardRef(_Final, _root=True): eval(self.__forward_code__, globalns, localns), "Forward references must evaluate to types.", is_argument=self.__forward_is_argument__, - is_class=self.__forward_is_class__, + allow_special_forms=self.__forward_is_class__, ) self.__forward_value__ = _eval_type( type_, globalns, localns, recursive_guard | {self.__forward_arg__} @@ -713,10 +879,11 @@ class ForwardRef(_Final, _root=True): if self.__forward_evaluated__ and other.__forward_evaluated__: return (self.__forward_arg__ == other.__forward_arg__ and self.__forward_value__ == other.__forward_value__) - return self.__forward_arg__ == other.__forward_arg__ + return (self.__forward_arg__ == other.__forward_arg__ and + self.__forward_module__ == other.__forward_module__) def __hash__(self): - return hash(self.__forward_arg__) + return hash((self.__forward_arg__, self.__forward_module__)) def __or__(self, other): return Union[self, other] @@ -725,10 +892,37 @@ class ForwardRef(_Final, _root=True): return Union[other, self] def __repr__(self): - return f'ForwardRef({self.__forward_arg__!r})' + if self.__forward_module__ is None: + module_repr = '' + else: + module_repr = f', module={self.__forward_module__!r}' + return f'ForwardRef({self.__forward_arg__!r}{module_repr})' -class _TypeVarLike: - """Mixin for TypeVar-like types (TypeVar and ParamSpec).""" + +def _is_unpacked_typevartuple(x: Any) -> bool: + return ((not isinstance(x, type)) and + getattr(x, '__typing_is_unpacked_typevartuple__', False)) + + +def _is_typevar_like(x: Any) -> bool: + return isinstance(x, (TypeVar, ParamSpec)) or _is_unpacked_typevartuple(x) + + +class _PickleUsingNameMixin: + """Mixin enabling pickling based on self.__name__.""" + + def __reduce__(self): + return self.__name__ + + +class _BoundVarianceMixin: + """Mixin giving __init__ bound and variance arguments. + + This is used by TypeVar and ParamSpec, which both employ the notions of + a type 'bound' (restricting type arguments to be a subtype of some + specified type) and type 'variance' (determining subtype relations between + generic types). + """ def __init__(self, bound, covariant, contravariant): """Used to setup TypeVars and ParamSpec's bound, covariant and contravariant attributes. @@ -757,11 +951,12 @@ class _TypeVarLike: prefix = '~' return prefix + self.__name__ - def __reduce__(self): - return self.__name__ + def __mro_entries__(self, bases): + raise TypeError(f"Cannot subclass an instance of {type(self).__name__}") -class TypeVar( _Final, _Immutable, _TypeVarLike, _root=True): +class TypeVar(_Final, _Immutable, _BoundVarianceMixin, _PickleUsingNameMixin, + _root=True): """Type variable. Usage:: @@ -805,9 +1000,6 @@ class TypeVar( _Final, _Immutable, _TypeVarLike, _root=True): Note that only type variables defined in global scope can be pickled. """ - __slots__ = ('__name__', '__bound__', '__constraints__', - '__covariant__', '__contravariant__', '__dict__') - def __init__(self, name, *constraints, bound=None, covariant=False, contravariant=False): self.__name__ = name @@ -822,6 +1014,96 @@ class TypeVar( _Final, _Immutable, _TypeVarLike, _root=True): if def_mod != 'typing': self.__module__ = def_mod + def __typing_subst__(self, arg): + msg = "Parameters to generic types must be types." + arg = _type_check(arg, msg, is_argument=True) + if ((isinstance(arg, _GenericAlias) and arg.__origin__ is Unpack) or + (isinstance(arg, GenericAlias) and getattr(arg, '__unpacked__', False))): + raise TypeError(f"{arg} is not valid as type argument") + return arg + + +class TypeVarTuple(_Final, _Immutable, _PickleUsingNameMixin, _root=True): + """Type variable tuple. + + Usage: + + Ts = TypeVarTuple('Ts') # Can be given any name + + Just as a TypeVar (type variable) is a placeholder for a single type, + a TypeVarTuple is a placeholder for an *arbitrary* number of types. For + example, if we define a generic class using a TypeVarTuple: + + class C(Generic[*Ts]): ... + + Then we can parameterize that class with an arbitrary number of type + arguments: + + C[int] # Fine + C[int, str] # Also fine + C[()] # Even this is fine + + For more details, see PEP 646. + + Note that only TypeVarTuples defined in global scope can be pickled. + """ + + def __init__(self, name): + self.__name__ = name + + # Used for pickling. + def_mod = _caller() + if def_mod != 'typing': + self.__module__ = def_mod + + def __iter__(self): + yield Unpack[self] + + def __repr__(self): + return self.__name__ + + def __typing_subst__(self, arg): + raise TypeError("Substitution of bare TypeVarTuple is not supported") + + def __typing_prepare_subst__(self, alias, args): + params = alias.__parameters__ + typevartuple_index = params.index(self) + for param in params[typevartuple_index + 1:]: + if isinstance(param, TypeVarTuple): + raise TypeError(f"More than one TypeVarTuple parameter in {alias}") + + alen = len(args) + plen = len(params) + left = typevartuple_index + right = plen - typevartuple_index - 1 + var_tuple_index = None + fillarg = None + for k, arg in enumerate(args): + if not isinstance(arg, type): + subargs = getattr(arg, '__typing_unpacked_tuple_args__', None) + if subargs and len(subargs) == 2 and subargs[-1] is ...: + if var_tuple_index is not None: + raise TypeError("More than one unpacked arbitrary-length tuple argument") + var_tuple_index = k + fillarg = subargs[0] + if var_tuple_index is not None: + left = min(left, var_tuple_index) + right = min(right, alen - var_tuple_index - 1) + elif left + right > alen: + raise TypeError(f"Too few arguments for {alias};" + f" actual {alen}, expected at least {plen-1}") + + return ( + *args[:left], + *([fillarg]*(typevartuple_index - left)), + tuple(args[left: alen - right]), + *([fillarg]*(plen - right - left - typevartuple_index - 1)), + *args[alen - right:], + ) + + def __mro_entries__(self, bases): + raise TypeError(f"Cannot subclass an instance of {type(self).__name__}") + class ParamSpecArgs(_Final, _Immutable, _root=True): """The args for a ParamSpec object. @@ -841,6 +1123,14 @@ class ParamSpecArgs(_Final, _Immutable, _root=True): def __repr__(self): return f"{self.__origin__.__name__}.args" + def __eq__(self, other): + if not isinstance(other, ParamSpecArgs): + return NotImplemented + return self.__origin__ == other.__origin__ + + def __mro_entries__(self, bases): + raise TypeError(f"Cannot subclass an instance of {type(self).__name__}") + class ParamSpecKwargs(_Final, _Immutable, _root=True): """The kwargs for a ParamSpec object. @@ -860,8 +1150,17 @@ class ParamSpecKwargs(_Final, _Immutable, _root=True): def __repr__(self): return f"{self.__origin__.__name__}.kwargs" + def __eq__(self, other): + if not isinstance(other, ParamSpecKwargs): + return NotImplemented + return self.__origin__ == other.__origin__ -class ParamSpec(_Final, _Immutable, _TypeVarLike, _root=True): + def __mro_entries__(self, bases): + raise TypeError(f"Cannot subclass an instance of {type(self).__name__}") + + +class ParamSpec(_Final, _Immutable, _BoundVarianceMixin, _PickleUsingNameMixin, + _root=True): """Parameter specification variable. Usage:: @@ -872,7 +1171,7 @@ class ParamSpec(_Final, _Immutable, _TypeVarLike, _root=True): type checkers. They are used to forward the parameter types of one callable to another callable, a pattern commonly found in higher order functions and decorators. They are only valid when used in ``Concatenate``, - or s the first argument to ``Callable``, or as parameters for user-defined + or as the first argument to ``Callable``, or as parameters for user-defined Generics. See class Generic for more information on generic types. An example for annotating a decorator:: @@ -898,7 +1197,7 @@ class ParamSpec(_Final, _Immutable, _TypeVarLike, _root=True): Parameter specification variables can be introspected. e.g.: - P.__name__ == 'T' + P.__name__ == 'P' P.__bound__ == None P.__covariant__ == False P.__contravariant__ == False @@ -907,9 +1206,6 @@ class ParamSpec(_Final, _Immutable, _TypeVarLike, _root=True): be pickled. """ - __slots__ = ('__name__', '__bound__', '__covariant__', '__contravariant__', - '__dict__') - @property def args(self): return ParamSpecArgs(self) @@ -925,6 +1221,27 @@ class ParamSpec(_Final, _Immutable, _TypeVarLike, _root=True): if def_mod != 'typing': self.__module__ = def_mod + def __typing_subst__(self, arg): + if isinstance(arg, (list, tuple)): + arg = tuple(_type_check(a, "Expected a type.") for a in arg) + elif not _is_param_expr(arg): + raise TypeError(f"Expected a list of types, an ellipsis, " + f"ParamSpec, or Concatenate. Got {arg}") + return arg + + def __typing_prepare_subst__(self, alias, args): + params = alias.__parameters__ + i = params.index(self) + if i >= len(args): + raise TypeError(f"Too few arguments for {alias}") + # Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612. + if len(params) == 1 and not _is_param_expr(args[0]): + assert i == 0 + args = (args,) + # Convert lists to tuples to help other libraries cache the results. + elif isinstance(args[i], list): + args = (*args[:i], tuple(args[i]), *args[i+1:]) + return args def _is_dunder(attr): return attr.startswith('__') and attr.endswith('__') @@ -972,14 +1289,14 @@ class _BaseGenericAlias(_Final, _root=True): return self._name or self.__origin__.__name__ # We are careful for copy and pickle. - # Also for simplicity we just don't relay all dunder names + # Also for simplicity we don't relay any dunder names if '__origin__' in self.__dict__ and not _is_dunder(attr): return getattr(self.__origin__, attr) raise AttributeError(attr) def __setattr__(self, attr, val): if _is_dunder(attr) or attr in {'_name', '_inst', '_nparams', - '_typevar_types', '_paramspec_tvars'}: + '_paramspec_tvars'}: super().__setattr__(attr, val) else: setattr(self.__origin__, attr, val) @@ -991,6 +1308,10 @@ class _BaseGenericAlias(_Final, _root=True): raise TypeError("Subscripted generics cannot be used with" " class and instance checks") + def __dir__(self): + return list(set(super().__dir__() + + [attr for attr in dir(self.__origin__) if not _is_dunder(attr)])) + # Special typing constructs Union, Optional, Generic, Callable and Tuple # use three special attributes for internal bookkeeping of generic types: @@ -1004,17 +1325,39 @@ class _BaseGenericAlias(_Final, _root=True): class _GenericAlias(_BaseGenericAlias, _root=True): - def __init__(self, origin, params, *, inst=True, name=None, - _typevar_types=TypeVar, + # The type of parameterized generics. + # + # That is, for example, `type(List[int])` is `_GenericAlias`. + # + # Objects which are instances of this class include: + # * Parameterized container types, e.g. `Tuple[int]`, `List[int]`. + # * Note that native container types, e.g. `tuple`, `list`, use + # `types.GenericAlias` instead. + # * Parameterized classes: + # T = TypeVar('T') + # class C(Generic[T]): pass + # # C[int] is a _GenericAlias + # * `Callable` aliases, generic `Callable` aliases, and + # parameterized `Callable` aliases: + # T = TypeVar('T') + # # _CallableGenericAlias inherits from _GenericAlias. + # A = Callable[[], None] # _CallableGenericAlias + # B = Callable[[T], None] # _CallableGenericAlias + # C = B[int] # _CallableGenericAlias + # * Parameterized `Final`, `ClassVar` and `TypeGuard`: + # # All _GenericAlias + # Final[int] + # ClassVar[float] + # TypeVar[bool] + + def __init__(self, origin, args, *, inst=True, name=None, _paramspec_tvars=False): super().__init__(origin, inst=inst, name=name) - if not isinstance(params, tuple): - params = (params,) + if not isinstance(args, tuple): + args = (args,) self.__args__ = tuple(... if a is _TypingEllipsis else - () if a is _TypingEmpty else - a for a in params) - self.__parameters__ = _collect_type_vars(params, typevar_types=_typevar_types) - self._typevar_types = _typevar_types + a for a in args) + self.__parameters__ = _collect_parameters(args) self._paramspec_tvars = _paramspec_tvars if not name: self.__module__ = origin.__module__ @@ -1035,51 +1378,130 @@ class _GenericAlias(_BaseGenericAlias, _root=True): return Union[left, self] @_tp_cache - def __getitem__(self, params): + def __getitem__(self, args): + # Parameterizes an already-parameterized object. + # + # For example, we arrive here doing something like: + # T1 = TypeVar('T1') + # T2 = TypeVar('T2') + # T3 = TypeVar('T3') + # class A(Generic[T1]): pass + # B = A[T2] # B is a _GenericAlias + # C = B[T3] # Invokes _GenericAlias.__getitem__ + # + # We also arrive here when parameterizing a generic `Callable` alias: + # T = TypeVar('T') + # C = Callable[[T], None] + # C[int] # Invokes _GenericAlias.__getitem__ + if self.__origin__ in (Generic, Protocol): # Can't subscript Generic[...] or Protocol[...]. raise TypeError(f"Cannot subscript already-subscripted {self}") - if not isinstance(params, tuple): - params = (params,) - params = tuple(_type_convert(p) for p in params) - if (self._paramspec_tvars - and any(isinstance(t, ParamSpec) for t in self.__parameters__)): - params = _prepare_paramspec_params(self, params) - else: - _check_generic(self, params, len(self.__parameters__)) + if not self.__parameters__: + raise TypeError(f"{self} is not a generic class") + + # Preprocess `args`. + if not isinstance(args, tuple): + args = (args,) + args = tuple(_type_convert(p) for p in args) + args = _unpack_args(args) + new_args = self._determine_new_args(args) + r = self.copy_with(new_args) + return r + + def _determine_new_args(self, args): + # Determines new __args__ for __getitem__. + # + # For example, suppose we had: + # T1 = TypeVar('T1') + # T2 = TypeVar('T2') + # class A(Generic[T1, T2]): pass + # T3 = TypeVar('T3') + # B = A[int, T3] + # C = B[str] + # `B.__args__` is `(int, T3)`, so `C.__args__` should be `(int, str)`. + # Unfortunately, this is harder than it looks, because if `T3` is + # anything more exotic than a plain `TypeVar`, we need to consider + # edge cases. + + params = self.__parameters__ + # In the example above, this would be {T3: str} + for param in params: + prepare = getattr(param, '__typing_prepare_subst__', None) + if prepare is not None: + args = prepare(self, args) + alen = len(args) + plen = len(params) + if alen != plen: + raise TypeError(f"Too {'many' if alen > plen else 'few'} arguments for {self};" + f" actual {alen}, expected {plen}") + new_arg_by_param = dict(zip(params, args)) - subst = dict(zip(self.__parameters__, params)) new_args = [] - for arg in self.__args__: - if isinstance(arg, self._typevar_types): - if isinstance(arg, ParamSpec): - arg = subst[arg] - if not _is_param_expr(arg): - raise TypeError(f"Expected a list of types, an ellipsis, " - f"ParamSpec, or Concatenate. Got {arg}") - else: - arg = subst[arg] - elif isinstance(arg, (_GenericAlias, GenericAlias, types.UnionType)): - subparams = arg.__parameters__ - if subparams: - subargs = tuple(subst[x] for x in subparams) - arg = arg[subargs] - # Required to flatten out the args for CallableGenericAlias - if self.__origin__ == collections.abc.Callable and isinstance(arg, tuple): - new_args.extend(arg) - else: - new_args.append(arg) - return self.copy_with(tuple(new_args)) + for old_arg in self.__args__: - def copy_with(self, params): - return self.__class__(self.__origin__, params, name=self._name, inst=self._inst) + if isinstance(old_arg, type): + new_args.append(old_arg) + continue + + substfunc = getattr(old_arg, '__typing_subst__', None) + if substfunc: + new_arg = substfunc(new_arg_by_param[old_arg]) + else: + subparams = getattr(old_arg, '__parameters__', ()) + if not subparams: + new_arg = old_arg + else: + subargs = [] + for x in subparams: + if isinstance(x, TypeVarTuple): + subargs.extend(new_arg_by_param[x]) + else: + subargs.append(new_arg_by_param[x]) + new_arg = old_arg[tuple(subargs)] + + if self.__origin__ == collections.abc.Callable and isinstance(new_arg, tuple): + # Consider the following `Callable`. + # C = Callable[[int], str] + # Here, `C.__args__` should be (int, str) - NOT ([int], str). + # That means that if we had something like... + # P = ParamSpec('P') + # T = TypeVar('T') + # C = Callable[P, T] + # D = C[[int, str], float] + # ...we need to be careful; `new_args` should end up as + # `(int, str, float)` rather than `([int, str], float)`. + new_args.extend(new_arg) + elif _is_unpacked_typevartuple(old_arg): + # Consider the following `_GenericAlias`, `B`: + # class A(Generic[*Ts]): ... + # B = A[T, *Ts] + # If we then do: + # B[float, int, str] + # The `new_arg` corresponding to `T` will be `float`, and the + # `new_arg` corresponding to `*Ts` will be `(int, str)`. We + # should join all these types together in a flat list + # `(float, int, str)` - so again, we should `extend`. + new_args.extend(new_arg) + else: + new_args.append(new_arg) + + return tuple(new_args) + + def copy_with(self, args): + return self.__class__(self.__origin__, args, name=self._name, inst=self._inst, + _paramspec_tvars=self._paramspec_tvars) def __repr__(self): if self._name: name = 'typing.' + self._name else: name = _type_repr(self.__origin__) - args = ", ".join([_type_repr(a) for a in self.__args__]) + if self.__args__: + args = ", ".join([_type_repr(a) for a in self.__args__]) + else: + # To ensure the repr is eval-able. + args = "()" return f'{name}[{args}]' def __reduce__(self): @@ -1107,12 +1529,15 @@ class _GenericAlias(_BaseGenericAlias, _root=True): return () return (self.__origin__,) + def __iter__(self): + yield Unpack[self] + # _nparams is the number of accepted parameters, e.g. 0 for Hashable, # 1 for List and 2 for Dict. It may be -1 if variable number of # parameters are accepted (needs custom __getitem__). -class _SpecialGenericAlias(_BaseGenericAlias, _root=True): +class _SpecialGenericAlias(_NotIterable, _BaseGenericAlias, _root=True): def __init__(self, origin, nparams, *, inst=True, name=None): if name is None: name = origin.__name__ @@ -1155,7 +1580,7 @@ class _SpecialGenericAlias(_BaseGenericAlias, _root=True): def __ror__(self, left): return Union[left, self] -class _CallableGenericAlias(_GenericAlias, _root=True): +class _CallableGenericAlias(_NotIterable, _GenericAlias, _root=True): def __repr__(self): assert self._name == 'Callable' args = self.__args__ @@ -1176,7 +1601,6 @@ class _CallableType(_SpecialGenericAlias, _root=True): def copy_with(self, params): return _CallableGenericAlias(self.__origin__, params, name=self._name, inst=self._inst, - _typevar_types=(TypeVar, ParamSpec), _paramspec_tvars=True) def __getitem__(self, params): @@ -1210,20 +1634,18 @@ class _CallableType(_SpecialGenericAlias, _root=True): class _TupleType(_SpecialGenericAlias, _root=True): @_tp_cache def __getitem__(self, params): - if params == (): - return self.copy_with((_TypingEmpty,)) if not isinstance(params, tuple): params = (params,) - if len(params) == 2 and params[1] is ...: + if len(params) >= 2 and params[-1] is ...: msg = "Tuple[t, ...]: t must be a type." - p = _type_check(params[0], msg) - return self.copy_with((p, _TypingEllipsis)) + params = tuple(_type_check(p, msg) for p in params[:-1]) + return self.copy_with((*params, _TypingEllipsis)) msg = "Tuple[t0, t1, ...]: each t must be a type." params = tuple(_type_check(p, msg) for p in params) return self.copy_with(params) -class _UnionGenericAlias(_GenericAlias, _root=True): +class _UnionGenericAlias(_NotIterable, _GenericAlias, _root=True): def copy_with(self, params): return Union[params] @@ -1274,10 +1696,75 @@ class _LiteralGenericAlias(_GenericAlias, _root=True): class _ConcatenateGenericAlias(_GenericAlias, _root=True): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs, - _typevar_types=(TypeVar, ParamSpec), - _paramspec_tvars=True) + def copy_with(self, params): + if isinstance(params[-1], (list, tuple)): + return (*params[:-1], *params[-1]) + if isinstance(params[-1], _ConcatenateGenericAlias): + params = (*params[:-1], *params[-1].__args__) + return super().copy_with(params) + + +@_SpecialForm +def Unpack(self, parameters): + """Type unpack operator. + + The type unpack operator takes the child types from some container type, + such as `tuple[int, str]` or a `TypeVarTuple`, and 'pulls them out'. For + example: + + # For some generic class `Foo`: + Foo[Unpack[tuple[int, str]]] # Equivalent to Foo[int, str] + + Ts = TypeVarTuple('Ts') + # Specifies that `Bar` is generic in an arbitrary number of types. + # (Think of `Ts` as a tuple of an arbitrary number of individual + # `TypeVar`s, which the `Unpack` is 'pulling out' directly into the + # `Generic[]`.) + class Bar(Generic[Unpack[Ts]]): ... + Bar[int] # Valid + Bar[int, str] # Also valid + + From Python 3.11, this can also be done using the `*` operator: + + Foo[*tuple[int, str]] + class Bar(Generic[*Ts]): ... + + Note that there is only some runtime checking of this operator. Not + everything the runtime allows may be accepted by static type checkers. + + For more information, see PEP 646. + """ + item = _type_check(parameters, f'{self} accepts only single type.') + return _UnpackGenericAlias(origin=self, args=(item,)) + + +class _UnpackGenericAlias(_GenericAlias, _root=True): + + def __repr__(self): + # `Unpack` only takes one argument, so __args__ should contain only + # a single item. + return '*' + repr(self.__args__[0]) + + def __getitem__(self, args): + if self.__typing_is_unpacked_typevartuple__: + return args + return super().__getitem__(args) + + @property + def __typing_unpacked_tuple_args__(self): + assert self.__origin__ is Unpack + assert len(self.__args__) == 1 + arg, = self.__args__ + if isinstance(arg, _GenericAlias): + assert arg.__origin__ is tuple + return arg.__args__ + return None + + @property + def __typing_is_unpacked_typevartuple__(self): + assert self.__origin__ is Unpack + assert len(self.__args__) == 1 + return isinstance(self.__args__[0], TypeVarTuple) class Generic: @@ -1305,15 +1792,26 @@ class Generic: @_tp_cache def __class_getitem__(cls, params): + """Parameterizes a generic class. + + At least, parameterizing a generic class is the *main* thing this method + does. For example, for some generic class `Foo`, this is called when we + do `Foo[int]` - there, with `cls=Foo` and `params=int`. + + However, note that this method is also called when defining generic + classes in the first place with `class Foo(Generic[T]): ...`. + """ if not isinstance(params, tuple): params = (params,) - if not params and cls is not Tuple: - raise TypeError( - f"Parameter list to {cls.__qualname__}[...] cannot be empty") + params = tuple(_type_convert(p) for p in params) if cls in (Generic, Protocol): # Generic and Protocol can only be subscripted with unique type variables. - if not all(isinstance(p, (TypeVar, ParamSpec)) for p in params): + if not params: + raise TypeError( + f"Parameter list to {cls.__qualname__}[...] cannot be empty" + ) + if not all(_is_typevar_like(p) for p in params): raise TypeError( f"Parameters to {cls.__name__}[...] must all be type variables " f"or parameter specification variables.") @@ -1322,12 +1820,21 @@ class Generic: f"Parameters to {cls.__name__}[...] must all be unique") else: # Subscripting a regular Generic subclass. - if any(isinstance(t, ParamSpec) for t in cls.__parameters__): - params = _prepare_paramspec_params(cls, params) - else: - _check_generic(cls, params, len(cls.__parameters__)) + for param in cls.__parameters__: + prepare = getattr(param, '__typing_prepare_subst__', None) + if prepare is not None: + params = prepare(cls, params) + _check_generic(cls, params, len(cls.__parameters__)) + + new_args = [] + for param, new_arg in zip(cls.__parameters__, params): + if isinstance(param, TypeVarTuple): + new_args.extend(new_arg) + else: + new_args.append(new_arg) + params = tuple(new_args) + return _GenericAlias(cls, params, - _typevar_types=(TypeVar, ParamSpec), _paramspec_tvars=True) def __init_subclass__(cls, *args, **kwargs): @@ -1336,11 +1843,13 @@ class Generic: if '__orig_bases__' in cls.__dict__: error = Generic in cls.__orig_bases__ else: - error = Generic in cls.__bases__ and cls.__name__ != 'Protocol' + error = (Generic in cls.__bases__ and + cls.__name__ != 'Protocol' and + type(cls) != _TypedDictMeta) if error: raise TypeError("Cannot inherit from plain Generic") if '__orig_bases__' in cls.__dict__: - tvars = _collect_type_vars(cls.__orig_bases__, (TypeVar, ParamSpec)) + tvars = _collect_parameters(cls.__orig_bases__) # Look for Generic[T1, ..., Tn]. # If found, tvars must be a subset of it. # If not found, tvars is it. @@ -1366,13 +1875,6 @@ class Generic: cls.__parameters__ = tuple(tvars) -class _TypingEmpty: - """Internal placeholder for () or []. Used by TupleMeta and CallableMeta - to allow empty list/tuple in specific places, without allowing them - to sneak in where prohibited. - """ - - class _TypingEllipsis: """Internal placeholder for ... (ellipsis).""" @@ -1440,11 +1942,15 @@ def _no_init_or_replace_init(self, *args, **kwargs): def _caller(depth=1, default='__main__'): + try: + return sys._getframemodulename(depth + 1) or default + except AttributeError: # For platforms without _getframemodulename() + pass try: return sys._getframe(depth + 1).f_globals.get('__name__', default) except (AttributeError, ValueError): # For platforms without _getframe() - return None - + pass + return None def _allow_reckless_class_checks(depth=3): """Allow instance and class checks for special stdlib modules. @@ -1587,10 +2093,11 @@ class Protocol(Generic, metaclass=_ProtocolMeta): issubclass(base, Generic) and base._is_protocol): raise TypeError('Protocols can only inherit from other' ' protocols, got %r' % base) - cls.__init__ = _no_init_or_replace_init + if cls.__init__ is Protocol.__init__: + cls.__init__ = _no_init_or_replace_init -class _AnnotatedAlias(_GenericAlias, _root=True): +class _AnnotatedAlias(_NotIterable, _GenericAlias, _root=True): """Runtime representation of an annotated type. At its core 'Annotated[t, dec1, dec2, ...]' is an alias for the type 't' @@ -1602,7 +2109,7 @@ class _AnnotatedAlias(_GenericAlias, _root=True): if isinstance(origin, _AnnotatedAlias): metadata = origin.__metadata__ + metadata origin = origin.__origin__ - super().__init__(origin, origin) + super().__init__(origin, origin, name='Annotated') self.__metadata__ = metadata def copy_with(self, params): @@ -1635,6 +2142,9 @@ class _AnnotatedAlias(_GenericAlias, _root=True): return 'Annotated' return super().__getattr__(attr) + def __mro_entries__(self, bases): + return (self.__origin__,) + class Annotated: """Add context specific metadata to a type. @@ -1665,6 +2175,17 @@ class Annotated: OptimizedList = Annotated[List[T], runtime.Optimize()] OptimizedList[int] == Annotated[List[int], runtime.Optimize()] + + - Annotated cannot be used with an unpacked TypeVarTuple:: + + Annotated[*Ts, Ann1] # NOT valid + + This would be equivalent to + + Annotated[T1, T2, T3, ..., Ann1] + + where T1, T2 etc. are TypeVars, which would be invalid, because + only one type should be passed to Annotated. """ __slots__ = () @@ -1678,8 +2199,11 @@ class Annotated: raise TypeError("Annotated[...] should be used " "with at least two arguments (a type and an " "annotation).") + if _is_unpacked_typevartuple(params[0]): + raise TypeError("Annotated[...] should not be used with an " + "unpacked TypeVarTuple") msg = "Annotated[t, ...]: t must be a type." - origin = _type_check(params[0], msg) + origin = _type_check(params[0], msg, allow_special_forms=True) metadata = tuple(params[1:]) return _AnnotatedAlias(origin, metadata) @@ -1725,24 +2249,20 @@ def cast(typ, val): return val -def _get_defaults(func): - """Internal helper to extract the default arguments, by name.""" - try: - code = func.__code__ - except AttributeError: - # Some built-in functions don't have __code__, __defaults__, etc. - return {} - pos_count = code.co_argcount - arg_names = code.co_varnames - arg_names = arg_names[:pos_count] - defaults = func.__defaults__ or () - kwdefaults = func.__kwdefaults__ - res = dict(kwdefaults) if kwdefaults else {} - pos_offset = pos_count - len(defaults) - for name, value in zip(arg_names[pos_offset:], defaults): - assert name not in res - res[name] = value - return res +def assert_type(val, typ, /): + """Ask a static type checker to confirm that the value is of the given type. + + When the type checker encounters a call to assert_type(), it + emits an error if the value is not of the specified type:: + + def greet(name: str) -> None: + assert_type(name, str) # ok + assert_type(name, int) # type checker error + + At runtime this returns the first argument unchanged and otherwise + does nothing. + """ + return val _allowed_types = (types.FunctionType, types.BuiltinFunctionType, @@ -1754,8 +2274,7 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False): """Return type hints for an object. This is often the same as obj.__annotations__, but it handles - forward references encoded as string literals, adds Optional[t] if a - default value equal to None is set and recursively replaces all + forward references encoded as string literals and recursively replaces all 'Annotated[T, ...]' with 'T' (unless 'include_extras=True'). The argument may be a module, class, method, or function. The annotations @@ -1835,7 +2354,6 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False): else: raise TypeError('{!r} is not a module, class, method, ' 'or function.'.format(obj)) - defaults = _get_defaults(obj) hints = dict(hints) for name, value in hints.items(): if value is None: @@ -1848,10 +2366,7 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False): is_argument=not isinstance(obj, types.ModuleType), is_class=False, ) - value = _eval_type(value, globalns, localns) - if name in defaults and defaults[name] is None: - value = Optional[value] - hints[name] = value + hints[name] = _eval_type(value, globalns, localns) return hints if include_extras else {k: _strip_annotations(t) for k, t in hints.items()} @@ -1860,6 +2375,8 @@ def _strip_annotations(t): """ if isinstance(t, _AnnotatedAlias): return _strip_annotations(t.__origin__) + if hasattr(t, "__origin__") and t.__origin__ in (Required, NotRequired): + return _strip_annotations(t.__args__[0]) if isinstance(t, _GenericAlias): stripped_args = tuple(_strip_annotations(a) for a in t.__args__) if stripped_args == t.__args__: @@ -1921,8 +2438,7 @@ def get_args(tp): return (tp.__origin__,) + tp.__metadata__ if isinstance(tp, (_GenericAlias, GenericAlias)): res = tp.__args__ - if (tp.__origin__ is collections.abc.Callable - and not (len(res) == 2 and _is_param_expr(res[0]))): + if _should_unflatten_callable_args(tp, res): res = (list(res[:-1]), res[-1]) return res if isinstance(tp, types.UnionType): @@ -1944,6 +2460,35 @@ def is_typeddict(tp): return isinstance(tp, _TypedDictMeta) +_ASSERT_NEVER_REPR_MAX_LENGTH = 100 + + +def assert_never(arg: Never, /) -> Never: + """Statically assert that a line of code is unreachable. + + Example:: + + def int_or_str(arg: int | str) -> None: + match arg: + case int(): + print("It's an int") + case str(): + print("It's a str") + case _: + assert_never(arg) + + If a type checker finds that a call to assert_never() is + reachable, it will emit an error. + + At runtime, this throws an exception when called. + + """ + value = repr(arg) + if len(value) > _ASSERT_NEVER_REPR_MAX_LENGTH: + value = value[:_ASSERT_NEVER_REPR_MAX_LENGTH] + '...' + raise AssertionError(f"Expected code to be unreachable, but got: {value}") + + def no_type_check(arg): """Decorator to indicate that annotations are not type hints. @@ -1954,13 +2499,23 @@ def no_type_check(arg): This mutates the function(s) or class(es) in place. """ if isinstance(arg, type): - arg_attrs = arg.__dict__.copy() - for attr, val in arg.__dict__.items(): - if val in arg.__bases__ + (arg,): - arg_attrs.pop(attr) - for obj in arg_attrs.values(): + for key in dir(arg): + obj = getattr(arg, key) + if ( + not hasattr(obj, '__qualname__') + or obj.__qualname__ != f'{arg.__qualname__}.{obj.__name__}' + or getattr(obj, '__module__', None) != arg.__module__ + ): + # We only modify objects that are defined in this type directly. + # If classes / methods are nested in multiple layers, + # we will modify them when processing their direct holders. + continue + # Instance, class, and static methods: if isinstance(obj, types.FunctionType): obj.__no_type_check__ = True + if isinstance(obj, types.MethodType): + obj.__func__.__no_type_check__ = True + # Nested types: if isinstance(obj, type): no_type_check(obj) try: @@ -1995,6 +2550,10 @@ def _overload_dummy(*args, **kwds): "by an implementation that is not @overload-ed.") +# {module: {qualname: {firstlineno: func}}} +_overload_registry = defaultdict(functools.partial(defaultdict, dict)) + + def overload(func): """Decorator for overloaded functions/methods. @@ -2020,10 +2579,37 @@ def overload(func): def utf8(value: str) -> bytes: ... def utf8(value): # implementation goes here + + The overloads for a function can be retrieved at runtime using the + get_overloads() function. """ + # classmethod and staticmethod + f = getattr(func, "__func__", func) + try: + _overload_registry[f.__module__][f.__qualname__][f.__code__.co_firstlineno] = func + except AttributeError: + # Not a normal function; ignore. + pass return _overload_dummy +def get_overloads(func): + """Return all defined overloads for *func* as a sequence.""" + # classmethod and staticmethod + f = getattr(func, "__func__", func) + if f.__module__ not in _overload_registry: + return [] + mod_dict = _overload_registry[f.__module__] + if f.__qualname__ not in mod_dict: + return [] + return list(mod_dict[f.__qualname__].values()) + + +def clear_overloads(): + """Clear all overloads in the registry.""" + _overload_registry.clear() + + def final(f): """A decorator to indicate final methods and final classes. @@ -2045,8 +2631,17 @@ def final(f): class Other(Leaf): # Error reported by type checker ... - There is no runtime checking of these properties. + There is no runtime checking of these properties. The decorator + sets the ``__final__`` attribute to ``True`` on the decorated object + to allow runtime introspection. """ + try: + f.__final__ = True + except (AttributeError, TypeError): + # Skip the attribute silently if it is not writable. + # AttributeError happens if the object has __slots__ or a + # read-only property, TypeError if it's a builtin class. + pass return f @@ -2245,7 +2840,12 @@ _special = frozenset({'__module__', '__name__', '__annotations__'}) class NamedTupleMeta(type): def __new__(cls, typename, bases, ns): - assert bases[0] is _NamedTuple + assert _NamedTuple in bases + for base in bases: + if base is not _NamedTuple and base is not Generic: + raise TypeError( + 'can only inherit from a NamedTuple type and Generic') + bases = tuple(tuple if base is _NamedTuple else base for base in bases) types = ns.get('__annotations__', {}) default_names = [] for field_name in types: @@ -2259,12 +2859,18 @@ class NamedTupleMeta(type): nm_tpl = _make_nmtuple(typename, types.items(), defaults=[ns[n] for n in default_names], module=ns['__module__']) + nm_tpl.__bases__ = bases + if Generic in bases: + class_getitem = Generic.__class_getitem__.__func__ + nm_tpl.__class_getitem__ = classmethod(class_getitem) # update from user namespace without overriding special namedtuple attributes for key in ns: if key in _prohibited: raise AttributeError("Cannot overwrite NamedTuple attribute " + key) elif key not in _special and key not in nm_tpl._fields: setattr(nm_tpl, key, ns[key]) + if Generic in bases: + nm_tpl.__init_subclass__() return nm_tpl @@ -2302,9 +2908,7 @@ def NamedTuple(typename, fields=None, /, **kwargs): _NamedTuple = type.__new__(NamedTupleMeta, 'NamedTuple', (), {}) def _namedtuple_mro_entries(bases): - if len(bases) > 1: - raise TypeError("Multiple inheritance with NamedTuple is not supported") - assert bases[0] is NamedTuple + assert NamedTuple in bases return (_NamedTuple,) NamedTuple.__mro_entries__ = _namedtuple_mro_entries @@ -2320,14 +2924,19 @@ class _TypedDictMeta(type): Subclasses and instances of TypedDict return actual dictionaries. """ for base in bases: - if type(base) is not _TypedDictMeta: + if type(base) is not _TypedDictMeta and base is not Generic: raise TypeError('cannot inherit from both a TypedDict type ' 'and a non-TypedDict base class') - tp_dict = type.__new__(_TypedDictMeta, name, (dict,), ns) + + if any(issubclass(b, Generic) for b in bases): + generic_base = (Generic,) + else: + generic_base = () + + tp_dict = type.__new__(_TypedDictMeta, name, (*generic_base, dict), ns) annotations = {} own_annotations = ns.get('__annotations__', {}) - own_annotation_keys = set(own_annotations.keys()) msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type" own_annotations = { n: _type_check(tp, msg, module=tp_dict.__module__) @@ -2342,10 +2951,22 @@ class _TypedDictMeta(type): optional_keys.update(base.__dict__.get('__optional_keys__', ())) annotations.update(own_annotations) - if total: - required_keys.update(own_annotation_keys) - else: - optional_keys.update(own_annotation_keys) + for annotation_key, annotation_type in own_annotations.items(): + annotation_origin = get_origin(annotation_type) + if annotation_origin is Annotated: + annotation_args = get_args(annotation_type) + if annotation_args: + annotation_type = annotation_args[0] + annotation_origin = get_origin(annotation_type) + + if annotation_origin is Required: + required_keys.add(annotation_key) + elif annotation_origin is NotRequired: + optional_keys.add(annotation_key) + elif total: + required_keys.add(annotation_key) + else: + optional_keys.add(annotation_key) tp_dict.__annotations__ = annotations tp_dict.__required_keys__ = frozenset(required_keys) @@ -2384,9 +3005,8 @@ def TypedDict(typename, fields=None, /, *, total=True, **kwargs): The type info can be accessed via the Point2D.__annotations__ dict, and the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets. - TypedDict supports two additional equivalent forms:: + TypedDict supports an additional equivalent form:: - Point2D = TypedDict('Point2D', x=int, y=int, label=str) Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) By default, all keys must be present in a TypedDict. It is possible @@ -2402,14 +3022,22 @@ def TypedDict(typename, fields=None, /, *, total=True, **kwargs): the total argument. True is the default, and makes all items defined in the class body be required. - The class syntax is only supported in Python 3.6+, while two other - syntax forms work for Python 2.7 and 3.2+ + The class syntax is only supported in Python 3.6+, while the other + syntax form works for Python 2.7 and 3.2+ """ if fields is None: fields = kwargs elif kwargs: raise TypeError("TypedDict takes either a dict or keyword arguments," " but not both") + if kwargs: + warnings.warn( + "The kwargs-based syntax for TypedDict definitions is deprecated " + "in Python 3.11, will be removed in Python 3.13, and may not be " + "understood by third-party type checkers.", + DeprecationWarning, + stacklevel=2, + ) ns = {'__annotations__': dict(fields)} module = _caller() @@ -2423,11 +3051,50 @@ _TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {}) TypedDict.__mro_entries__ = lambda bases: (_TypedDict,) +@_SpecialForm +def Required(self, parameters): + """A special typing construct to mark a key of a total=False TypedDict + as required. For example: + + class Movie(TypedDict, total=False): + title: Required[str] + year: int + + m = Movie( + title='The Matrix', # typechecker error if key is omitted + year=1999, + ) + + There is no runtime checking that a required key is actually provided + when instantiating a related TypedDict. + """ + item = _type_check(parameters, f'{self._name} accepts only a single type.') + return _GenericAlias(self, (item,)) + + +@_SpecialForm +def NotRequired(self, parameters): + """A special typing construct to mark a key of a TypedDict as + potentially missing. For example: + + class Movie(TypedDict): + title: str + year: NotRequired[int] + + m = Movie( + title='The Matrix', # typechecker error if key is omitted + year=1999, + ) + """ + item = _type_check(parameters, f'{self._name} accepts only a single type.') + return _GenericAlias(self, (item,)) + + class NewType: """NewType creates simple unique types with almost zero runtime overhead. NewType(name, tp) is considered a subtype of tp by static type checkers. At runtime, NewType(name, tp) returns - a dummy function that simply returns its argument. Usage:: + a dummy callable that simply returns its argument. Usage:: UserId = NewType('UserId', int) @@ -2454,6 +3121,21 @@ class NewType: if def_mod != 'typing': self.__module__ = def_mod + def __mro_entries__(self, bases): + # We defined __mro_entries__ to get a better error message + # if a user attempts to subclass a NewType instance. bpo-46170 + superclass_name = self.__name__ + + class Dummy: + def __init_subclass__(cls): + subclass_name = cls.__name__ + raise TypeError( + f"Cannot subclass an instance of NewType. Perhaps you were looking for: " + f"`{subclass_name} = NewType({subclass_name!r}, {superclass_name})`" + ) + + return (Dummy,) + def __repr__(self): return f'{self.__module__}.{self.__qualname__}' @@ -2661,3 +3343,108 @@ class re(metaclass=_DeprecatedType): re.__name__ = __name__ + '.re' sys.modules[re.__name__] = re + + +def reveal_type(obj: T, /) -> T: + """Reveal the inferred type of a variable. + + When a static type checker encounters a call to ``reveal_type()``, + it will emit the inferred type of the argument:: + + x: int = 1 + reveal_type(x) + + Running a static type checker (e.g., ``mypy``) on this example + will produce output similar to 'Revealed type is "builtins.int"'. + + At runtime, the function prints the runtime type of the + argument and returns it unchanged. + + """ + print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr) + return obj + + +def dataclass_transform( + *, + eq_default: bool = True, + order_default: bool = False, + kw_only_default: bool = False, + frozen_default: bool = False, + field_specifiers: tuple[type[Any] | Callable[..., Any], ...] = (), + **kwargs: Any, +) -> Callable[[T], T]: + """Decorator that marks a function, class, or metaclass as providing + dataclass-like behavior. + + Example usage with a decorator function: + + T = TypeVar("T") + + @dataclass_transform() + def create_model(cls: type[T]) -> type[T]: + ... + return cls + + @create_model + class CustomerModel: + id: int + name: str + + On a base class: + + @dataclass_transform() + class ModelBase: ... + + class CustomerModel(ModelBase): + id: int + name: str + + On a metaclass: + + @dataclass_transform() + class ModelMeta(type): ... + + class ModelBase(metaclass=ModelMeta): ... + + class CustomerModel(ModelBase): + id: int + name: str + + The ``CustomerModel`` classes defined above will + be treated by type checkers similarly to classes created with + ``@dataclasses.dataclass``. + For example, type checkers will assume these classes have + ``__init__`` methods that accept ``id`` and ``name``. + + The arguments to this decorator can be used to customize this behavior: + - ``eq_default`` indicates whether the ``eq`` parameter is assumed to be + ``True`` or ``False`` if it is omitted by the caller. + - ``order_default`` indicates whether the ``order`` parameter is + assumed to be True or False if it is omitted by the caller. + - ``kw_only_default`` indicates whether the ``kw_only`` parameter is + assumed to be True or False if it is omitted by the caller. + - ``frozen_default`` indicates whether the ``frozen`` parameter is + assumed to be True or False if it is omitted by the caller. + - ``field_specifiers`` specifies a static list of supported classes + or functions that describe fields, similar to ``dataclasses.field()``. + - Arbitrary other keyword arguments are accepted in order to allow for + possible future extensions. + + At runtime, this decorator records its arguments in the + ``__dataclass_transform__`` attribute on the decorated object. + It has no other runtime effect. + + See PEP 681 for more details. + """ + def decorator(cls_or_fn): + cls_or_fn.__dataclass_transform__ = { + "eq_default": eq_default, + "order_default": order_default, + "kw_only_default": kw_only_default, + "frozen_default": frozen_default, + "field_specifiers": field_specifiers, + "kwargs": kwargs, + } + return cls_or_fn + return decorator diff --git a/Lib/unittest/__init__.py b/Lib/unittest/__init__.py index 540433d3b3b..5bcbf834840 100644 --- a/Lib/unittest/__init__.py +++ b/Lib/unittest/__init__.py @@ -49,7 +49,7 @@ __all__ = ['TestResult', 'TestCase', 'IsolatedAsyncioTestCase', 'TestSuite', 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', 'expectedFailure', 'TextTestResult', 'installHandler', 'registerResult', 'removeResult', 'removeHandler', - 'addModuleCleanup'] + 'addModuleCleanup', 'doModuleCleanups', 'enterModuleContext'] # Expose obsolete functions for backwards compatibility # bpo-5846: Deprecated in Python 3.11, scheduled for removal in Python 3.13. @@ -59,7 +59,8 @@ __unittest = True from .result import TestResult from .case import (addModuleCleanup, TestCase, FunctionTestCase, SkipTest, skip, - skipIf, skipUnless, expectedFailure) + skipIf, skipUnless, expectedFailure, doModuleCleanups, + enterModuleContext) from .suite import BaseTestSuite, TestSuite from .loader import TestLoader, defaultTestLoader from .main import TestProgram, main @@ -69,16 +70,6 @@ from .signals import installHandler, registerResult, removeResult, removeHandler from .loader import makeSuite, getTestCaseNames, findTestCases -# There are no tests here, so don't try to run anything discovered from -# introspecting the symbols (e.g. FunctionTestCase). Instead, all our -# tests come from within unittest.test. -def load_tests(loader, tests, pattern): - import os.path - # top level directory cached on loader instance - this_dir = os.path.dirname(__file__) - return loader.discover(start_dir=this_dir, pattern=pattern) - - # Lazy import of IsolatedAsyncioTestCase from .async_case # It imports asyncio, which is relatively heavy, but most tests # do not need it. diff --git a/Lib/unittest/async_case.py b/Lib/unittest/async_case.py index d8bfaf6b67e..bd2a4711560 100644 --- a/Lib/unittest/async_case.py +++ b/Lib/unittest/async_case.py @@ -1,11 +1,11 @@ import asyncio +import contextvars import inspect import warnings from .case import TestCase - class IsolatedAsyncioTestCase(TestCase): # Names intentionally have a long prefix # to reduce a chance of clashing with user-defined attributes @@ -34,8 +34,8 @@ class IsolatedAsyncioTestCase(TestCase): def __init__(self, methodName='runTest'): super().__init__(methodName) - self._asyncioTestLoop = None - self._asyncioCallsQueue = None + self._asyncioRunner = None + self._asyncioTestContext = contextvars.copy_context() async def asyncSetUp(self): pass @@ -58,115 +58,85 @@ class IsolatedAsyncioTestCase(TestCase): # 3. Regular "def func()" that returns awaitable object self.addCleanup(*(func, *args), **kwargs) + async def enterAsyncContext(self, cm): + """Enters the supplied asynchronous context manager. + + If successful, also adds its __aexit__ method as a cleanup + function and returns the result of the __aenter__ method. + """ + # We look up the special methods on the type to match the with + # statement. + cls = type(cm) + try: + enter = cls.__aenter__ + exit = cls.__aexit__ + except AttributeError: + raise TypeError(f"'{cls.__module__}.{cls.__qualname__}' object does " + f"not support the asynchronous context manager protocol" + ) from None + result = await enter(cm) + self.addAsyncCleanup(exit, cm, None, None, None) + return result + def _callSetUp(self): - self.setUp() + # Force loop to be initialized and set as the current loop + # so that setUp functions can use get_event_loop() and get the + # correct loop instance. + self._asyncioRunner.get_loop() + self._asyncioTestContext.run(self.setUp) self._callAsync(self.asyncSetUp) def _callTestMethod(self, method): if self._callMaybeAsync(method) is not None: - warnings.warn(f'It is deprecated to return a value!=None from a ' + warnings.warn(f'It is deprecated to return a value that is not None from a ' f'test case ({method})', DeprecationWarning, stacklevel=4) def _callTearDown(self): self._callAsync(self.asyncTearDown) - self.tearDown() + self._asyncioTestContext.run(self.tearDown) def _callCleanup(self, function, *args, **kwargs): self._callMaybeAsync(function, *args, **kwargs) def _callAsync(self, func, /, *args, **kwargs): - assert self._asyncioTestLoop is not None, 'asyncio test loop is not initialized' - ret = func(*args, **kwargs) - assert inspect.isawaitable(ret), f'{func!r} returned non-awaitable' - fut = self._asyncioTestLoop.create_future() - self._asyncioCallsQueue.put_nowait((fut, ret)) - return self._asyncioTestLoop.run_until_complete(fut) + assert self._asyncioRunner is not None, 'asyncio runner is not initialized' + assert inspect.iscoroutinefunction(func), f'{func!r} is not an async function' + return self._asyncioRunner.run( + func(*args, **kwargs), + context=self._asyncioTestContext + ) def _callMaybeAsync(self, func, /, *args, **kwargs): - assert self._asyncioTestLoop is not None, 'asyncio test loop is not initialized' - ret = func(*args, **kwargs) - if inspect.isawaitable(ret): - fut = self._asyncioTestLoop.create_future() - self._asyncioCallsQueue.put_nowait((fut, ret)) - return self._asyncioTestLoop.run_until_complete(fut) + assert self._asyncioRunner is not None, 'asyncio runner is not initialized' + if inspect.iscoroutinefunction(func): + return self._asyncioRunner.run( + func(*args, **kwargs), + context=self._asyncioTestContext, + ) else: - return ret + return self._asyncioTestContext.run(func, *args, **kwargs) - async def _asyncioLoopRunner(self, fut): - self._asyncioCallsQueue = queue = asyncio.Queue() - fut.set_result(None) - while True: - query = await queue.get() - queue.task_done() - if query is None: - return - fut, awaitable = query - try: - ret = await awaitable - if not fut.cancelled(): - fut.set_result(ret) - except (SystemExit, KeyboardInterrupt): - raise - except (BaseException, asyncio.CancelledError) as ex: - if not fut.cancelled(): - fut.set_exception(ex) + def _setupAsyncioRunner(self): + assert self._asyncioRunner is None, 'asyncio runner is already initialized' + runner = asyncio.Runner(debug=True) + self._asyncioRunner = runner - def _setupAsyncioLoop(self): - assert self._asyncioTestLoop is None, 'asyncio test loop already initialized' - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - loop.set_debug(True) - self._asyncioTestLoop = loop - fut = loop.create_future() - self._asyncioCallsTask = loop.create_task(self._asyncioLoopRunner(fut)) - loop.run_until_complete(fut) - - def _tearDownAsyncioLoop(self): - assert self._asyncioTestLoop is not None, 'asyncio test loop is not initialized' - loop = self._asyncioTestLoop - self._asyncioTestLoop = None - self._asyncioCallsQueue.put_nowait(None) - loop.run_until_complete(self._asyncioCallsQueue.join()) - - try: - # cancel all tasks - to_cancel = asyncio.all_tasks(loop) - if not to_cancel: - return - - for task in to_cancel: - task.cancel() - - loop.run_until_complete( - asyncio.gather(*to_cancel, return_exceptions=True)) - - for task in to_cancel: - if task.cancelled(): - continue - if task.exception() is not None: - loop.call_exception_handler({ - 'message': 'unhandled exception during test shutdown', - 'exception': task.exception(), - 'task': task, - }) - # shutdown asyncgens - loop.run_until_complete(loop.shutdown_asyncgens()) - finally: - asyncio.set_event_loop(None) - loop.close() + def _tearDownAsyncioRunner(self): + runner = self._asyncioRunner + runner.close() def run(self, result=None): - self._setupAsyncioLoop() + self._setupAsyncioRunner() try: return super().run(result) finally: - self._tearDownAsyncioLoop() + self._tearDownAsyncioRunner() def debug(self): - self._setupAsyncioLoop() + self._setupAsyncioRunner() super().debug() - self._tearDownAsyncioLoop() + self._tearDownAsyncioRunner() def __del__(self): - if self._asyncioTestLoop is not None: - self._tearDownAsyncioLoop() + if self._asyncioRunner is not None: + self._tearDownAsyncioRunner() diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index f1067652cc8..5167c5f843f 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -102,12 +102,31 @@ def _id(obj): return obj +def _enter_context(cm, addcleanup): + # We look up the special methods on the type to match the with + # statement. + cls = type(cm) + try: + enter = cls.__enter__ + exit = cls.__exit__ + except AttributeError: + raise TypeError(f"'{cls.__module__}.{cls.__qualname__}' object does " + f"not support the context manager protocol") from None + result = enter(cm) + addcleanup(exit, cm, None, None, None) + return result + + _module_cleanups = [] def addModuleCleanup(function, /, *args, **kwargs): """Same as addCleanup, except the cleanup items are called even if setUpModule fails (unlike tearDownModule).""" _module_cleanups.append((function, args, kwargs)) +def enterModuleContext(cm): + """Same as enterContext, but module-wide.""" + return _enter_context(cm, addModuleCleanup) + def doModuleCleanups(): """Execute all module cleanup functions. Normally called for you after @@ -365,11 +384,11 @@ class TestCase(object): # of difflib. See #11763. _diffThreshold = 2**16 - # Attribute used by TestSuite for classSetUp - - _classSetupFailed = False - - _class_cleanups = [] + def __init_subclass__(cls, *args, **kwargs): + # Attribute used by TestSuite for classSetUp + cls._classSetupFailed = False + cls._class_cleanups = [] + super().__init_subclass__(*args, **kwargs) def __init__(self, methodName='runTest'): """Create an instance of the class that will use the named test @@ -426,12 +445,25 @@ class TestCase(object): Cleanup items are called even if setUp fails (unlike tearDown).""" self._cleanups.append((function, args, kwargs)) + def enterContext(self, cm): + """Enters the supplied context manager. + + If successful, also adds its __exit__ method as a cleanup + function and returns the result of the __enter__ method. + """ + return _enter_context(cm, self.addCleanup) + @classmethod def addClassCleanup(cls, function, /, *args, **kwargs): """Same as addCleanup, except the cleanup items are called even if setUpClass fails (unlike tearDownClass).""" cls._class_cleanups.append((function, args, kwargs)) + @classmethod + def enterClassContext(cls, cm): + """Same as enterContext, but class-wide.""" + return _enter_context(cm, cls.addClassCleanup) + def setUp(self): "Hook method for setting up the test fixture before exercising it." pass @@ -478,7 +510,7 @@ class TestCase(object): return hash((type(self), self._testMethodName)) def __str__(self): - return "%s (%s)" % (self._testMethodName, strclass(self.__class__)) + return "%s (%s.%s)" % (self._testMethodName, strclass(self.__class__), self._testMethodName) def __repr__(self): return "<%s testMethod=%s>" % \ @@ -545,7 +577,7 @@ class TestCase(object): def _callTestMethod(self, method): if method() is not None: - warnings.warn(f'It is deprecated to return a value!=None from a ' + warnings.warn(f'It is deprecated to return a value that is not None from a ' f'test case ({method})', DeprecationWarning, stacklevel=3) def _callTearDown(self): diff --git a/Lib/unittest/loader.py b/Lib/unittest/loader.py index 5951f3f754e..80d4fbdd8e3 100644 --- a/Lib/unittest/loader.py +++ b/Lib/unittest/loader.py @@ -57,9 +57,7 @@ def _make_skipped_test(methodname, exception, suiteClass): TestClass = type("ModuleSkipped", (case.TestCase,), attrs) return suiteClass((TestClass(methodname),)) -def _jython_aware_splitext(path): - if path.lower().endswith('$py.class'): - return path[:-9] +def _splitext(path): return os.path.splitext(path)[0] @@ -264,8 +262,6 @@ class TestLoader(object): self._top_level_dir = top_level_dir is_not_importable = False - is_namespace = False - tests = [] if os.path.isdir(os.path.abspath(start_dir)): start_dir = os.path.abspath(start_dir) if start_dir != top_level_dir: @@ -281,50 +277,25 @@ class TestLoader(object): top_part = start_dir.split('.')[0] try: start_dir = os.path.abspath( - os.path.dirname((the_module.__file__))) + os.path.dirname((the_module.__file__))) except AttributeError: - # look for namespace packages - try: - spec = the_module.__spec__ - except AttributeError: - spec = None - - if spec and spec.loader is None: - if spec.submodule_search_locations is not None: - is_namespace = True - - for path in the_module.__path__: - if (not set_implicit_top and - not path.startswith(top_level_dir)): - continue - self._top_level_dir = \ - (path.split(the_module.__name__ - .replace(".", os.path.sep))[0]) - tests.extend(self._find_tests(path, - pattern, - namespace=True)) - elif the_module.__name__ in sys.builtin_module_names: + if the_module.__name__ in sys.builtin_module_names: # builtin module raise TypeError('Can not use builtin modules ' 'as dotted module names') from None else: raise TypeError( - 'don\'t know how to discover from {!r}' - .format(the_module)) from None + f"don't know how to discover from {the_module!r}" + ) from None if set_implicit_top: - if not is_namespace: - self._top_level_dir = \ - self._get_directory_containing_module(top_part) - sys.path.remove(top_level_dir) - else: - sys.path.remove(top_level_dir) + self._top_level_dir = self._get_directory_containing_module(top_part) + sys.path.remove(top_level_dir) if is_not_importable: raise ImportError('Start directory is not importable: %r' % start_dir) - if not is_namespace: - tests = list(self._find_tests(start_dir, pattern)) + tests = list(self._find_tests(start_dir, pattern)) return self.suiteClass(tests) def _get_directory_containing_module(self, module_name): @@ -342,7 +313,7 @@ class TestLoader(object): def _get_name_from_path(self, path): if path == self._top_level_dir: return '.' - path = _jython_aware_splitext(os.path.normpath(path)) + path = _splitext(os.path.normpath(path)) _relpath = os.path.relpath(path, self._top_level_dir) assert not os.path.isabs(_relpath), "Path must be within the project" @@ -359,7 +330,7 @@ class TestLoader(object): # override this method to use alternative matching strategy return fnmatch(path, pattern) - def _find_tests(self, start_dir, pattern, namespace=False): + def _find_tests(self, start_dir, pattern): """Used by discovery. Yields test suites it loads.""" # Handle the __init__ in this package name = self._get_name_from_path(start_dir) @@ -368,8 +339,7 @@ class TestLoader(object): if name != '.' and name not in self._loading_packages: # name is in self._loading_packages while we have called into # loadTestsFromModule with name. - tests, should_recurse = self._find_test_path( - start_dir, pattern, namespace) + tests, should_recurse = self._find_test_path(start_dir, pattern) if tests is not None: yield tests if not should_recurse: @@ -380,8 +350,7 @@ class TestLoader(object): paths = sorted(os.listdir(start_dir)) for path in paths: full_path = os.path.join(start_dir, path) - tests, should_recurse = self._find_test_path( - full_path, pattern, namespace) + tests, should_recurse = self._find_test_path(full_path, pattern) if tests is not None: yield tests if should_recurse: @@ -389,11 +358,11 @@ class TestLoader(object): name = self._get_name_from_path(full_path) self._loading_packages.add(name) try: - yield from self._find_tests(full_path, pattern, namespace) + yield from self._find_tests(full_path, pattern) finally: self._loading_packages.discard(name) - def _find_test_path(self, full_path, pattern, namespace=False): + def _find_test_path(self, full_path, pattern): """Used by discovery. Loads tests from a single file, or a directories' __init__.py when @@ -422,13 +391,13 @@ class TestLoader(object): else: mod_file = os.path.abspath( getattr(module, '__file__', full_path)) - realpath = _jython_aware_splitext( + realpath = _splitext( os.path.realpath(mod_file)) - fullpath_noext = _jython_aware_splitext( + fullpath_noext = _splitext( os.path.realpath(full_path)) if realpath.lower() != fullpath_noext.lower(): module_dir = os.path.dirname(realpath) - mod_name = _jython_aware_splitext( + mod_name = _splitext( os.path.basename(full_path)) expected_dir = os.path.dirname(full_path) msg = ("%r module incorrectly imported from %r. Expected " @@ -437,8 +406,7 @@ class TestLoader(object): msg % (mod_name, module_dir, expected_dir)) return self.loadTestsFromModule(module, pattern=pattern), False elif os.path.isdir(full_path): - if (not namespace and - not os.path.isfile(os.path.join(full_path, '__init__.py'))): + if not os.path.isfile(os.path.join(full_path, '__init__.py')): return None, False load_tests = None diff --git a/Lib/unittest/main.py b/Lib/unittest/main.py index e62469aa2a1..046fbd3a45d 100644 --- a/Lib/unittest/main.py +++ b/Lib/unittest/main.py @@ -3,6 +3,7 @@ import sys import argparse import os +import warnings from . import loader, runner from .signals import installHandler @@ -39,7 +40,7 @@ def _convert_name(name): name = rel_path # on Windows both '\' and '/' are used as path # separators. Better to replace both than rely on os.path.sep - return name[:-3].replace('\\', '.').replace('/', '.') + return os.path.normpath(name)[:-3].replace('\\', '.').replace('/', '.') return name def _convert_names(names): @@ -101,6 +102,8 @@ class TestProgram(object): self.runTests() def usageExit(self, msg=None): + warnings.warn("TestProgram.usageExit() is deprecated and will be" + " removed in Python 3.13", DeprecationWarning) if msg: print(msg) if self._discovery_parser is None: diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 9f99a5aa5bc..0f93cb53c3d 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -35,6 +35,7 @@ from asyncio import iscoroutinefunction from types import CodeType, ModuleType, MethodType from unittest.util import safe_repr from functools import wraps, partial +from threading import RLock class InvalidSpecError(Exception): @@ -402,15 +403,26 @@ class Base(object): class NonCallableMock(Base): """A non-callable version of `Mock`""" - def __new__(cls, /, *args, **kw): + # Store a mutex as a class attribute in order to protect concurrent access + # to mock attributes. Using a class attribute allows all NonCallableMock + # instances to share the mutex for simplicity. + # + # See https://github.com/python/cpython/issues/98624 for why this is + # necessary. + _lock = RLock() + + def __new__( + cls, spec=None, wraps=None, name=None, spec_set=None, + parent=None, _spec_state=None, _new_name='', _new_parent=None, + _spec_as_instance=False, _eat_self=None, unsafe=False, **kwargs + ): # every instance has its own class # so we can create magic methods on the # class without stomping on other mocks bases = (cls,) if not issubclass(cls, AsyncMockMixin): # Check if spec is an async object or function - bound_args = _MOCK_SIG.bind_partial(cls, *args, **kw).arguments - spec_arg = bound_args.get('spec_set', bound_args.get('spec')) + spec_arg = spec_set or spec if spec_arg is not None and _is_async_obj(spec_arg): bases = (AsyncMockMixin, cls) new = type(cls.__name__, bases, {'__doc__': cls.__doc__}) @@ -489,14 +501,13 @@ class NonCallableMock(Base): def _mock_add_spec(self, spec, spec_set, _spec_as_instance=False, _eat_self=False): + if _is_instance_mock(spec): + raise InvalidSpecError(f'Cannot spec a Mock object. [object={spec!r}]') + _spec_class = None _spec_signature = None _spec_asyncs = [] - for attr in dir(spec): - if iscoroutinefunction(getattr(spec, attr, None)): - _spec_asyncs.append(attr) - if spec is not None and not _is_list(spec): if isinstance(spec, type): _spec_class = spec @@ -506,7 +517,13 @@ class NonCallableMock(Base): _spec_as_instance, _eat_self) _spec_signature = res and res[1] - spec = dir(spec) + spec_list = dir(spec) + + for attr in spec_list: + if iscoroutinefunction(getattr(spec, attr, None)): + _spec_asyncs.append(attr) + + spec = spec_list __dict__ = self.__dict__ __dict__['_spec_class'] = _spec_class @@ -635,41 +652,42 @@ class NonCallableMock(Base): raise AttributeError("Mock object has no attribute %r" % name) elif _is_magic(name): raise AttributeError(name) - if not self._mock_unsafe: - if name.startswith(('assert', 'assret', 'asert', 'aseert', 'assrt')): + if not self._mock_unsafe and (not self._mock_methods or name not in self._mock_methods): + if name.startswith(('assert', 'assret', 'asert', 'aseert', 'assrt')) or name in _ATTRIB_DENY_LIST: raise AttributeError( f"{name!r} is not a valid assertion. Use a spec " f"for the mock if {name!r} is meant to be an attribute.") - result = self._mock_children.get(name) - if result is _deleted: - raise AttributeError(name) - elif result is None: - wraps = None - if self._mock_wraps is not None: - # XXXX should we get the attribute without triggering code - # execution? - wraps = getattr(self._mock_wraps, name) + with NonCallableMock._lock: + result = self._mock_children.get(name) + if result is _deleted: + raise AttributeError(name) + elif result is None: + wraps = None + if self._mock_wraps is not None: + # XXXX should we get the attribute without triggering code + # execution? + wraps = getattr(self._mock_wraps, name) - result = self._get_child_mock( - parent=self, name=name, wraps=wraps, _new_name=name, - _new_parent=self - ) - self._mock_children[name] = result - - elif isinstance(result, _SpecState): - try: - result = create_autospec( - result.spec, result.spec_set, result.instance, - result.parent, result.name + result = self._get_child_mock( + parent=self, name=name, wraps=wraps, _new_name=name, + _new_parent=self ) - except InvalidSpecError: - target_name = self.__dict__['_mock_name'] or self - raise InvalidSpecError( - f'Cannot autospec attr {name!r} from target ' - f'{target_name!r} as it has already been mocked out. ' - f'[target={self!r}, attr={result.spec!r}]') - self._mock_children[name] = result + self._mock_children[name] = result + + elif isinstance(result, _SpecState): + try: + result = create_autospec( + result.spec, result.spec_set, result.instance, + result.parent, result.name + ) + except InvalidSpecError: + target_name = self.__dict__['_mock_name'] or self + raise InvalidSpecError( + f'Cannot autospec attr {name!r} from target ' + f'{target_name!r} as it has already been mocked out. ' + f'[target={self!r}, attr={result.spec!r}]') + self._mock_children[name] = result return result @@ -1001,15 +1019,15 @@ class NonCallableMock(Base): For non-callable mocks the callable variant will be used (rather than any custom subclass).""" - _new_name = kw.get("_new_name") - if _new_name in self.__dict__['_spec_asyncs']: - return AsyncMock(**kw) - if self._mock_sealed: attribute = f".{kw['name']}" if "name" in kw else "()" mock_name = self._extract_mock_name() + attribute raise AttributeError(mock_name) + _new_name = kw.get("_new_name") + if _new_name in self.__dict__['_spec_asyncs']: + return AsyncMock(**kw) + _type = type(self) if issubclass(_type, MagicMock) and _new_name in _async_method_magics: # Any asynchronous magic becomes an AsyncMock @@ -1044,7 +1062,12 @@ class NonCallableMock(Base): return f"\n{prefix}: {safe_repr(self.mock_calls)}." -_MOCK_SIG = inspect.signature(NonCallableMock.__init__) +# Denylist for forbidden attribute names in safe mode +_ATTRIB_DENY_LIST = frozenset({ + name.removeprefix("assert_") + for name in dir(NonCallableMock) + if name.startswith("assert_") +}) class _AnyComparer(list): @@ -1216,9 +1239,11 @@ class Mock(CallableMixin, NonCallableMock): `return_value` attribute. * `unsafe`: By default, accessing any attribute whose name starts with - *assert*, *assret*, *asert*, *aseert* or *assrt* will raise an - AttributeError. Passing `unsafe=True` will allow access to - these attributes. + *assert*, *assret*, *asert*, *aseert*, or *assrt* raises an AttributeError. + Additionally, an AttributeError is raised when accessing + attributes that match the name of an assertion method without the prefix + `assert_`, e.g. accessing `called_once` instead of `assert_called_once`. + Passing `unsafe=True` will allow access to these attributes. * `wraps`: Item for the mock object to wrap. If `wraps` is not None then calling the Mock will pass the call through to the wrapped object @@ -1589,9 +1614,9 @@ class _patch(object): def _get_target(target): try: target, attribute = target.rsplit('.', 1) - except (TypeError, ValueError): - raise TypeError("Need a valid target to patch. You supplied: %r" % - (target,)) + except (TypeError, ValueError, AttributeError): + raise TypeError( + f"Need a valid target to patch. You supplied: {target!r}") return partial(pkgutil.resolve_name, target), attribute @@ -1796,6 +1821,12 @@ class _patch_dict(object): def __call__(self, f): if isinstance(f, type): return self.decorate_class(f) + if inspect.iscoroutinefunction(f): + return self.decorate_async_callable(f) + return self.decorate_callable(f) + + + def decorate_callable(self, f): @wraps(f) def _inner(*args, **kw): self._patch_dict() @@ -1807,6 +1838,18 @@ class _patch_dict(object): return _inner + def decorate_async_callable(self, f): + @wraps(f) + async def _inner(*args, **kw): + self._patch_dict() + try: + return await f(*args, **kw) + finally: + self._unpatch_dict() + + return _inner + + def decorate_class(self, klass): for attr in dir(klass): attr_value = getattr(klass, attr) @@ -1940,7 +1983,7 @@ right = ' '.join('r%s' % n for n in numerics.split()) _non_defaults = { '__get__', '__set__', '__delete__', '__reversed__', '__missing__', '__reduce__', '__reduce_ex__', '__getinitargs__', '__getnewargs__', - '__getstate__', '__setstate__', '__getformat__', '__setformat__', + '__getstate__', '__setstate__', '__getformat__', '__repr__', '__dir__', '__subclasses__', '__format__', '__getnewargs_ex__', } @@ -2107,10 +2150,8 @@ class NonCallableMagicMock(MagicMixin, NonCallableMock): class AsyncMagicMixin(MagicMixin): - def __init__(self, /, *args, **kw): - self._mock_set_magics() # make magic work for kwargs in init - _safe_super(AsyncMagicMixin, self).__init__(*args, **kw) - self._mock_set_magics() # fix magic broken by upper level init + pass + class MagicMock(MagicMixin, Mock): """ @@ -2152,6 +2193,10 @@ class MagicProxy(Base): return self.create_mock() +_CODE_ATTRS = dir(CodeType) +_CODE_SIG = inspect.signature(partial(CodeType.__init__, None)) + + class AsyncMockMixin(Base): await_count = _delegating_property('await_count') await_args = _delegating_property('await_args') @@ -2169,9 +2214,23 @@ class AsyncMockMixin(Base): self.__dict__['_mock_await_count'] = 0 self.__dict__['_mock_await_args'] = None self.__dict__['_mock_await_args_list'] = _CallList() - code_mock = NonCallableMock(spec_set=CodeType) - code_mock.co_flags = inspect.CO_COROUTINE + code_mock = NonCallableMock(spec_set=_CODE_ATTRS) + code_mock.__dict__["_spec_class"] = CodeType + code_mock.__dict__["_spec_signature"] = _CODE_SIG + code_mock.co_flags = ( + inspect.CO_COROUTINE + + inspect.CO_VARARGS + + inspect.CO_VARKEYWORDS + ) + code_mock.co_argcount = 0 + code_mock.co_varnames = ('args', 'kwargs') + code_mock.co_posonlyargcount = 0 + code_mock.co_kwonlyargcount = 0 self.__dict__['__code__'] = code_mock + self.__dict__['__name__'] = 'AsyncMock' + self.__dict__['__defaults__'] = tuple() + self.__dict__['__kwdefaults__'] = {} + self.__dict__['__annotations__'] = None async def _execute_mock_call(self, /, *args, **kwargs): # This is nearly just like super(), except for special handling @@ -2728,6 +2787,7 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None, _new_parent=parent, **kwargs) mock._mock_children[entry] = new + new.return_value = child_klass() _check_signature(original, new, skipfirst=skipfirst) # so functions created with _set_signature become instance attributes, @@ -2789,6 +2849,7 @@ FunctionTypes = ( file_spec = None +open_spec = None def _to_stream(read_data): @@ -2845,8 +2906,12 @@ def mock_open(mock=None, read_data=''): import _io file_spec = list(set(dir(_io.TextIOWrapper)).union(set(dir(_io.BytesIO)))) + global open_spec + if open_spec is None: + import _io + open_spec = list(set(dir(_io.open))) if mock is None: - mock = MagicMock(name='open', spec=open) + mock = MagicMock(name='open', spec=open_spec) handle = MagicMock(spec=file_spec) handle.__enter__.return_value = handle diff --git a/Lib/unittest/result.py b/Lib/unittest/result.py index ce7468e3148..5ca4c23238b 100644 --- a/Lib/unittest/result.py +++ b/Lib/unittest/result.py @@ -173,18 +173,10 @@ class TestResult(object): def _exc_info_to_string(self, err, test): """Converts a sys.exc_info()-style tuple of values into a string.""" exctype, value, tb = err - # Skip test runner traceback levels - while tb and self._is_relevant_tb_level(tb): - tb = tb.tb_next - - if exctype is test.failureException: - # Skip assert*() traceback levels - length = self._count_relevant_tb_levels(tb) - else: - length = None + tb = self._clean_tracebacks(exctype, value, tb, test) tb_e = traceback.TracebackException( exctype, value, tb, - limit=length, capture_locals=self.tb_locals, compact=True) + capture_locals=self.tb_locals, compact=True) msgLines = list(tb_e.format()) if self.buffer: @@ -200,16 +192,51 @@ class TestResult(object): msgLines.append(STDERR_LINE % error) return ''.join(msgLines) + def _clean_tracebacks(self, exctype, value, tb, test): + ret = None + first = True + excs = [(exctype, value, tb)] + seen = {id(value)} # Detect loops in chained exceptions. + while excs: + (exctype, value, tb) = excs.pop() + # Skip test runner traceback levels + while tb and self._is_relevant_tb_level(tb): + tb = tb.tb_next + + # Skip assert*() traceback levels + if exctype is test.failureException: + self._remove_unittest_tb_frames(tb) + + if first: + ret = tb + first = False + else: + value.__traceback__ = tb + + if value is not None: + for c in (value.__cause__, value.__context__): + if c is not None and id(c) not in seen: + excs.append((type(c), c, c.__traceback__)) + seen.add(id(c)) + return ret def _is_relevant_tb_level(self, tb): return '__unittest' in tb.tb_frame.f_globals - def _count_relevant_tb_levels(self, tb): - length = 0 + def _remove_unittest_tb_frames(self, tb): + '''Truncates usercode tb at the first unittest frame. + + If the first frame of the traceback is in user code, + the prefix up to the first unittest frame is returned. + If the first frame is already in the unittest module, + the traceback is not modified. + ''' + prev = None while tb and not self._is_relevant_tb_level(tb): - length += 1 + prev = tb tb = tb.tb_next - return length + if prev is not None: + prev.tb_next = None def __repr__(self): return ("<%s run=%i errors=%i failures=%i>" % diff --git a/Lib/unittest/runner.py b/Lib/unittest/runner.py index b51def8882f..6678adb6a7d 100644 --- a/Lib/unittest/runner.py +++ b/Lib/unittest/runner.py @@ -68,6 +68,7 @@ class TextTestResult(result.TestResult): self.stream.write(self.getDescription(test)) self.stream.write(" ... ") self.stream.writeln(status) + self.stream.flush() self._newline = True def addSubTest(self, test, subtest, err): @@ -121,6 +122,7 @@ class TextTestResult(result.TestResult): super(TextTestResult, self).addExpectedFailure(test, err) if self.showAll: self.stream.writeln("expected failure") + self.stream.flush() elif self.dots: self.stream.write("x") self.stream.flush() @@ -129,6 +131,7 @@ class TextTestResult(result.TestResult): super(TextTestResult, self).addUnexpectedSuccess(test) if self.showAll: self.stream.writeln("unexpected success") + self.stream.flush() elif self.dots: self.stream.write("u") self.stream.flush() @@ -136,8 +139,15 @@ class TextTestResult(result.TestResult): def printErrors(self): if self.dots or self.showAll: self.stream.writeln() + self.stream.flush() self.printErrorList('ERROR', self.errors) self.printErrorList('FAIL', self.failures) + unexpectedSuccesses = getattr(self, 'unexpectedSuccesses', ()) + if unexpectedSuccesses: + self.stream.writeln(self.separator1) + for test in unexpectedSuccesses: + self.stream.writeln(f"UNEXPECTED SUCCESS: {self.getDescription(test)}") + self.stream.flush() def printErrorList(self, flavour, errors): for test, err in errors: @@ -145,6 +155,7 @@ class TextTestResult(result.TestResult): self.stream.writeln("%s: %s" % (flavour,self.getDescription(test))) self.stream.writeln(self.separator2) self.stream.writeln("%s" % err) + self.stream.flush() class TextTestRunner(object): @@ -239,4 +250,5 @@ class TextTestRunner(object): self.stream.writeln(" (%s)" % (", ".join(infos),)) else: self.stream.write("\n") + self.stream.flush() return result diff --git a/Lib/unittest/test/__init__.py b/Lib/unittest/test/__init__.py deleted file mode 100644 index cdae8a74427..00000000000 --- a/Lib/unittest/test/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -import os -import sys -import unittest - - -here = os.path.dirname(__file__) -loader = unittest.defaultTestLoader - -def suite(): - suite = unittest.TestSuite() - for fn in os.listdir(here): - if fn.startswith("test") and fn.endswith(".py"): - modname = "unittest.test." + fn[:-3] - __import__(modname) - module = sys.modules[modname] - suite.addTest(loader.loadTestsFromModule(module)) - suite.addTest(loader.loadTestsFromName('unittest.test.testmock')) - return suite - - -if __name__ == "__main__": - unittest.main(defaultTest="suite") diff --git a/Lib/unittest/test/__main__.py b/Lib/unittest/test/__main__.py deleted file mode 100644 index 44d0591e847..00000000000 --- a/Lib/unittest/test/__main__.py +++ /dev/null @@ -1,18 +0,0 @@ -import os -import unittest - - -def load_tests(loader, standard_tests, pattern): - # top level directory cached on loader instance - this_dir = os.path.dirname(__file__) - pattern = pattern or "test_*.py" - # We are inside unittest.test, so the top-level is two notches up - top_level_dir = os.path.dirname(os.path.dirname(this_dir)) - package_tests = loader.discover(start_dir=this_dir, pattern=pattern, - top_level_dir=top_level_dir) - standard_tests.addTests(package_tests) - return standard_tests - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/unittest/test/testmock/__init__.py b/Lib/unittest/test/testmock/__init__.py deleted file mode 100644 index 87d7ae994d5..00000000000 --- a/Lib/unittest/test/testmock/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -import os -import sys -import unittest - - -here = os.path.dirname(__file__) -loader = unittest.defaultTestLoader - -def load_tests(*args): - suite = unittest.TestSuite() - for fn in os.listdir(here): - if fn.startswith("test") and fn.endswith(".py"): - modname = "unittest.test.testmock." + fn[:-3] - __import__(modname) - module = sys.modules[modname] - suite.addTest(loader.loadTestsFromModule(module)) - return suite diff --git a/Lib/urllib/error.py b/Lib/urllib/error.py index 8cd901f13f8..feec0e7f848 100644 --- a/Lib/urllib/error.py +++ b/Lib/urllib/error.py @@ -10,7 +10,7 @@ responses, with a status code, headers, and a body. In some contexts, an application may want to handle an exception like a regular response. """ - +import io import urllib.response __all__ = ['URLError', 'HTTPError', 'ContentTooShortError'] @@ -42,12 +42,9 @@ class HTTPError(URLError, urllib.response.addinfourl): self.hdrs = hdrs self.fp = fp self.filename = url - # The addinfourl classes depend on fp being a valid file - # object. In some cases, the HTTPError may not have a valid - # file object. If this happens, the simplest workaround is to - # not initialize the base classes. - if fp is not None: - self.__super_init(fp, hdrs, url, code) + if fp is None: + fp = io.StringIO() + self.__super_init(fp, hdrs, url, code) def __str__(self): return 'HTTP Error %s: %s' % (self.code, self.msg) diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index bf16d0f42e5..5f95c5ff7f9 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -29,8 +29,8 @@ test_urlparse.py provides a good indicator of parsing behavior. from collections import namedtuple import functools +import math import re -import sys import types import warnings @@ -167,12 +167,11 @@ class _NetlocResultMixinBase(object): def port(self): port = self._hostinfo[1] if port is not None: - try: - port = int(port, 10) - except ValueError: - message = f'Port could not be cast to integer value as {port!r}' - raise ValueError(message) from None - if not ( 0 <= port <= 65535): + if port.isdigit() and port.isascii(): + port = int(port) + else: + raise ValueError(f"Port could not be cast to integer value as {port!r}") + if not (0 <= port <= 65535): raise ValueError("Port out of range 0-65535") return port @@ -461,7 +460,7 @@ def urlsplit(url, scheme='', allow_fragments=True): allow_fragments = bool(allow_fragments) netloc = query = fragment = '' i = url.find(':') - if i > 0: + if i > 0 and url[0].isascii() and url[0].isalpha(): for c in url[:i]: if c not in scheme_chars: break @@ -601,6 +600,9 @@ _hextobyte = None def unquote_to_bytes(string): """unquote_to_bytes('abc%20def') -> b'abc def'.""" + return bytes(_unquote_impl(string)) + +def _unquote_impl(string: bytes | bytearray | str) -> bytes | bytearray: # Note: strings are encoded as UTF-8. This is only an issue if it contains # unescaped non-ASCII characters, which URIs should not. if not string: @@ -612,8 +614,8 @@ def unquote_to_bytes(string): bits = string.split(b'%') if len(bits) == 1: return string - res = [bits[0]] - append = res.append + res = bytearray(bits[0]) + append = res.extend # Delay the initialization of the table to not waste memory # if the function is never called global _hextobyte @@ -627,10 +629,20 @@ def unquote_to_bytes(string): except KeyError: append(b'%') append(item) - return b''.join(res) + return res _asciire = re.compile('([\x00-\x7f]+)') +def _generate_unquoted_parts(string, encoding, errors): + previous_match_end = 0 + for ascii_match in _asciire.finditer(string): + start, end = ascii_match.span() + yield string[previous_match_end:start] # Non-ASCII + # The ascii_match[1] group == string[start:end]. + yield _unquote_impl(ascii_match[1]).decode(encoding, errors) + previous_match_end = end + yield string[previous_match_end:] # Non-ASCII tail + def unquote(string, encoding='utf-8', errors='replace'): """Replace %xx escapes by their single-character equivalent. The optional encoding and errors parameters specify how to decode percent-encoded @@ -642,21 +654,16 @@ def unquote(string, encoding='utf-8', errors='replace'): unquote('abc%20def') -> 'abc def'. """ if isinstance(string, bytes): - return unquote_to_bytes(string).decode(encoding, errors) + return _unquote_impl(string).decode(encoding, errors) if '%' not in string: + # Is it a string-like object? string.split return string if encoding is None: encoding = 'utf-8' if errors is None: errors = 'replace' - bits = _asciire.split(string) - res = [bits[0]] - append = res.append - for i in range(1, len(bits), 2): - append(unquote_to_bytes(bits[i]).decode(encoding, errors)) - append(bits[i + 1]) - return ''.join(res) + return ''.join(_generate_unquoted_parts(string, encoding, errors)) def parse_qs(qs, keep_blank_values=False, strict_parsing=False, @@ -740,12 +747,13 @@ def parse_qsl(qs, keep_blank_values=False, strict_parsing=False, # is less than max_num_fields. This prevents a memory exhaustion DOS # attack via post bodies with many fields. if max_num_fields is not None: - num_fields = 1 + qs.count(separator) + num_fields = 1 + qs.count(separator) if qs else 0 if max_num_fields < num_fields: raise ValueError('Max number of fields exceeded') r = [] - for name_value in qs.split(separator): + query_args = qs.split(separator) if qs else [] + for name_value in query_args: if not name_value and not strict_parsing: continue nv = name_value.split('=', 1) @@ -906,7 +914,14 @@ def quote_from_bytes(bs, safe='/'): if not bs.rstrip(_ALWAYS_SAFE_BYTES + safe): return bs.decode() quoter = _byte_quoter_factory(safe) - return ''.join([quoter(char) for char in bs]) + if (bs_len := len(bs)) < 200_000: + return ''.join(map(quoter, bs)) + else: + # This saves memory - https://github.com/python/cpython/issues/95865 + chunk_size = math.isqrt(bs_len) + chunks = [''.join(map(quoter, bs[i:i+chunk_size])) + for i in range(0, bs_len, chunk_size)] + return ''.join(chunks) def urlencode(query, doseq=False, safe='', encoding=None, errors=None, quote_via=quote_plus): @@ -939,10 +954,9 @@ def urlencode(query, doseq=False, safe='', encoding=None, errors=None, # but that's a minor nit. Since the original implementation # allowed empty dicts that type of behavior probably should be # preserved for consistency - except TypeError: - ty, va, tb = sys.exc_info() + except TypeError as err: raise TypeError("not a valid non-string sequence " - "or mapping object").with_traceback(tb) + "or mapping object") from err l = [] if not doseq: @@ -1125,15 +1139,15 @@ def splitnport(host, defport=-1): def _splitnport(host, defport=-1): """Split host and port, returning numeric port. Return given default port if no ':' found; defaults to -1. - Return numerical port if a valid number are found after ':'. + Return numerical port if a valid number is found after ':'. Return None if ':' but not a valid number.""" host, delim, port = host.rpartition(':') if not delim: host = port elif port: - try: + if port.isdigit() and port.isascii(): nport = int(port) - except ValueError: + else: nport = None return host, nport return host, defport diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index fd6fc36aee0..151034e6a81 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -88,7 +88,6 @@ import hashlib import http.client import io import os -import posixpath import re import socket import string @@ -266,10 +265,7 @@ def urlretrieve(url, filename=None, reporthook=None, data=None): if reporthook: reporthook(blocknum, bs, size) - while True: - block = fp.read(bs) - if not block: - break + while block := fp.read(bs): read += len(block) tfp.write(block) blocknum += 1 @@ -889,10 +885,10 @@ class HTTPPasswordMgr: return True if base[0] != test[0]: return False - common = posixpath.commonprefix((base[1], test[1])) - if len(common) == len(base[1]): - return True - return False + prefix = base[1] + if prefix[-1:] != '/': + prefix += '/' + return test[1].startswith(prefix) class HTTPPasswordMgrWithDefaultRealm(HTTPPasswordMgr): @@ -1384,12 +1380,16 @@ if hasattr(http.client, 'HTTPSConnection'): def __init__(self, debuglevel=0, context=None, check_hostname=None): AbstractHTTPHandler.__init__(self, debuglevel) + if context is None: + http_version = http.client.HTTPSConnection._http_vsn + context = http.client._create_https_context(http_version) + if check_hostname is not None: + context.check_hostname = check_hostname self._context = context - self._check_hostname = check_hostname def https_open(self, req): return self.do_open(http.client.HTTPSConnection, req, - context=self._context, check_hostname=self._check_hostname) + context=self._context) https_request = AbstractHTTPHandler.do_request_ @@ -1579,8 +1579,7 @@ class FTPHandler(BaseHandler): headers = email.message_from_string(headers) return addinfourl(fp, headers, req.full_url) except ftplib.all_errors as exp: - exc = URLError('ftp error: %r' % exp) - raise exc.with_traceback(sys.exc_info()[2]) + raise URLError(exp) from exp def connect_ftp(self, user, passwd, host, port, dirs, timeout): return ftpwrapper(user, passwd, host, port, dirs, timeout, @@ -1791,7 +1790,7 @@ class URLopener: except (HTTPError, URLError): raise except OSError as msg: - raise OSError('socket error', msg).with_traceback(sys.exc_info()[2]) + raise OSError('socket error', msg) from msg def open_unknown(self, fullurl, data=None): """Overridable interface to open unknown URL type.""" @@ -1845,10 +1844,7 @@ class URLopener: size = int(headers["Content-Length"]) if reporthook: reporthook(blocknum, bs, size) - while 1: - block = fp.read(bs) - if not block: - break + while block := fp.read(bs): read += len(block) tfp.write(block) blocknum += 1 @@ -1988,9 +1984,17 @@ class URLopener: if _have_ssl: def _https_connection(self, host): - return http.client.HTTPSConnection(host, - key_file=self.key_file, - cert_file=self.cert_file) + if self.key_file or self.cert_file: + http_version = http.client.HTTPSConnection._http_vsn + context = http.client._create_https_context(http_version) + context.load_cert_chain(self.cert_file, self.key_file) + # cert and key file means the user wants to authenticate. + # enable TLS 1.3 PHA implicitly even for custom contexts. + if context.post_handshake_auth is not None: + context.post_handshake_auth = True + else: + context = None + return http.client.HTTPSConnection(host, context=context) def open_https(self, url, data=None): """Use HTTPS protocol.""" @@ -2093,7 +2097,7 @@ class URLopener: headers = email.message_from_string(headers) return addinfourl(fp, headers, "ftp:" + url) except ftperrors() as exp: - raise URLError('ftp error %r' % exp).with_traceback(sys.exc_info()[2]) + raise URLError(f'ftp error: {exp}') from exp def open_data(self, url, data=None): """Use "data" URL.""" @@ -2443,8 +2447,7 @@ class ftpwrapper: conn, retrlen = self.ftp.ntransfercmd(cmd) except ftplib.error_perm as reason: if str(reason)[:3] != '550': - raise URLError('ftp error: %r' % reason).with_traceback( - sys.exc_info()[2]) + raise URLError(f'ftp error: {reason}') from reason if not conn: # Set transfer mode to ASCII! self.ftp.voidcmd('TYPE A') @@ -2499,28 +2502,34 @@ def getproxies_environment(): this seems to be the standard convention. If you need a different way, you can pass a proxies dictionary to the [Fancy]URLopener constructor. - """ - proxies = {} # in order to prefer lowercase variables, process environment in # two passes: first matches any, second pass matches lowercase only - for name, value in os.environ.items(): - name = name.lower() - if value and name[-6:] == '_proxy': - proxies[name[:-6]] = value + + # select only environment variables which end in (after making lowercase) _proxy + proxies = {} + environment = [] + for name in os.environ.keys(): + # fast screen underscore position before more expensive case-folding + if len(name) > 5 and name[-6] == "_" and name[-5:].lower() == "proxy": + value = os.environ[name] + proxy_name = name[:-6].lower() + environment.append((name, value, proxy_name)) + if value: + proxies[proxy_name] = value # CVE-2016-1000110 - If we are running as CGI script, forget HTTP_PROXY # (non-all-lowercase) as it may be set from the web server by a "Proxy:" # header from the client # If "proxy" is lowercase, it will still be used thanks to the next block if 'REQUEST_METHOD' in os.environ: proxies.pop('http', None) - for name, value in os.environ.items(): + for name, value, proxy_name in environment: + # not case-folded, checking here for lower-case env vars only if name[-6:] == '_proxy': - name = name.lower() if value: - proxies[name[:-6]] = value + proxies[proxy_name] = value else: - proxies.pop(name[:-6], None) + proxies.pop(proxy_name, None) return proxies def proxy_bypass_environment(host, proxies=None): @@ -2681,22 +2690,26 @@ elif os.name == 'nt': # Returned as Unicode but problems if not converted to ASCII proxyServer = str(winreg.QueryValueEx(internetSettings, 'ProxyServer')[0]) - if '=' in proxyServer: - # Per-protocol settings - for p in proxyServer.split(';'): - protocol, address = p.split('=', 1) - # See if address has a type:// prefix - if not re.match('(?:[^/:]+)://', address): - address = '%s://%s' % (protocol, address) - proxies[protocol] = address - else: - # Use one setting for all protocols - if proxyServer[:5] == 'http:': - proxies['http'] = proxyServer - else: - proxies['http'] = 'http://%s' % proxyServer - proxies['https'] = 'https://%s' % proxyServer - proxies['ftp'] = 'ftp://%s' % proxyServer + if '=' not in proxyServer and ';' not in proxyServer: + # Use one setting for all protocols. + proxyServer = 'http={0};https={0};ftp={0}'.format(proxyServer) + for p in proxyServer.split(';'): + protocol, address = p.split('=', 1) + # See if address has a type:// prefix + if not re.match('(?:[^/:]+)://', address): + # Add type:// prefix to address without specifying type + if protocol in ('http', 'https', 'ftp'): + # The default proxy type of Windows is HTTP + address = 'http://' + address + elif protocol == 'socks': + address = 'socks://' + address + proxies[protocol] = address + # Use SOCKS proxy for HTTP(S) protocols + if proxies.get('socks'): + # The default SOCKS proxy type of Windows is SOCKS4 + address = re.sub(r'^socks://', 'socks4://', proxies['socks']) + proxies['http'] = proxies.get('http') or address + proxies['https'] = proxies.get('https') or address internetSettings.Close() except (OSError, ValueError, TypeError): # Either registry key not found etc, or the value in an diff --git a/Lib/uu.py b/Lib/uu.py index 9f1f37f1a64..6f8805d8c5d 100755 --- a/Lib/uu.py +++ b/Lib/uu.py @@ -33,6 +33,9 @@ decode(in_file [, out_file, mode, quiet]) import binascii import os import sys +import warnings + +warnings._deprecated(__name__, remove=(3, 13)) __all__ = ["Error", "encode", "decode"] diff --git a/Lib/uuid.py b/Lib/uuid.py index f179d68e826..1c5578bf1f0 100644 --- a/Lib/uuid.py +++ b/Lib/uuid.py @@ -371,7 +371,12 @@ def _get_command_stdout(command, *args): # for are actually localized, but in theory some system could do so.) env = dict(os.environ) env['LC_ALL'] = 'C' - proc = subprocess.Popen((executable,) + args, + # Empty strings will be quoted by popen so we should just ommit it + if args != ('',): + command = (executable, *args) + else: + command = (executable,) + proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, env=env) @@ -511,7 +516,7 @@ def _ifconfig_getnode(): mac = _find_mac_near_keyword('ifconfig', args, keywords, lambda i: i+1) if mac: return mac - return None + return None def _ip_getnode(): """Get the hardware address on Unix by running ip.""" @@ -524,6 +529,8 @@ def _ip_getnode(): def _arp_getnode(): """Get the hardware address on Unix by running arp.""" import os, socket + if not hasattr(socket, "gethostbyname"): + return None try: ip_addr = socket.gethostbyname(socket.gethostname()) except OSError: @@ -721,9 +728,62 @@ def uuid5(namespace, name): hash = sha1(namespace.bytes + bytes(name, "utf-8")).digest() return UUID(bytes=hash[:16], version=5) + +def main(): + """Run the uuid command line interface.""" + uuid_funcs = { + "uuid1": uuid1, + "uuid3": uuid3, + "uuid4": uuid4, + "uuid5": uuid5 + } + uuid_namespace_funcs = ("uuid3", "uuid5") + namespaces = { + "@dns": NAMESPACE_DNS, + "@url": NAMESPACE_URL, + "@oid": NAMESPACE_OID, + "@x500": NAMESPACE_X500 + } + + import argparse + parser = argparse.ArgumentParser( + description="Generates a uuid using the selected uuid function.") + parser.add_argument("-u", "--uuid", choices=uuid_funcs.keys(), default="uuid4", + help="The function to use to generate the uuid. " + "By default uuid4 function is used.") + parser.add_argument("-n", "--namespace", + help="The namespace is a UUID, or '@ns' where 'ns' is a " + "well-known predefined UUID addressed by namespace name. " + "Such as @dns, @url, @oid, and @x500. " + "Only required for uuid3/uuid5 functions.") + parser.add_argument("-N", "--name", + help="The name used as part of generating the uuid. " + "Only required for uuid3/uuid5 functions.") + + args = parser.parse_args() + uuid_func = uuid_funcs[args.uuid] + namespace = args.namespace + name = args.name + + if args.uuid in uuid_namespace_funcs: + if not namespace or not name: + parser.error( + "Incorrect number of arguments. " + f"{args.uuid} requires a namespace and a name. " + "Run 'python -m uuid -h' for more information." + ) + namespace = namespaces[namespace] if namespace in namespaces else UUID(namespace) + print(uuid_func(namespace, name)) + else: + print(uuid_func()) + + # The following standard UUIDs are for use with uuid3() or uuid5(). NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8') NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8') NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8') NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8') + +if __name__ == "__main__": + main() diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py index 6f1af294ae6..2f87c62ccba 100644 --- a/Lib/venv/__init__.py +++ b/Lib/venv/__init__.py @@ -51,6 +51,7 @@ class EnvBuilder: self.symlinks = symlinks self.upgrade = upgrade self.with_pip = with_pip + self.orig_prompt = prompt if prompt == '.': # see bpo-38901 prompt = os.path.basename(os.getcwd()) self.prompt = prompt @@ -92,6 +93,15 @@ class EnvBuilder: elif os.path.isdir(fn): shutil.rmtree(fn) + def _venv_path(self, env_dir, name): + vars = { + 'base': env_dir, + 'platbase': env_dir, + 'installed_base': env_dir, + 'installed_platbase': env_dir, + } + return sysconfig.get_path(name, scheme='venv', vars=vars) + def ensure_directories(self, env_dir): """ Create the directories for the environment. @@ -106,6 +116,9 @@ class EnvBuilder: elif os.path.islink(d) or os.path.isfile(d): raise ValueError('Unable to create directory %r' % d) + if os.pathsep in os.fspath(env_dir): + raise ValueError(f'Refusing to create a venv in {env_dir} because ' + f'it contains the PATH separator {os.pathsep}.') if os.path.exists(env_dir) and self.clear: self.clear_directory(env_dir) context = types.SimpleNamespace() @@ -115,22 +128,22 @@ class EnvBuilder: context.prompt = '(%s) ' % prompt create_if_needed(env_dir) executable = sys._base_executable + if not executable: # see gh-96861 + raise ValueError('Unable to determine path to the running ' + 'Python interpreter. Provide an explicit path or ' + 'check that your PATH environment variable is ' + 'correctly set.') dirname, exename = os.path.split(os.path.abspath(executable)) context.executable = executable context.python_dir = dirname context.python_exe = exename - if sys.platform == 'win32': - binname = 'Scripts' - incpath = 'Include' - libpath = os.path.join(env_dir, 'Lib', 'site-packages') - else: - binname = 'bin' - incpath = 'include' - libpath = os.path.join(env_dir, 'lib', - 'python%d.%d' % sys.version_info[:2], - 'site-packages') - context.inc_path = path = os.path.join(env_dir, incpath) - create_if_needed(path) + binpath = self._venv_path(env_dir, 'scripts') + incpath = self._venv_path(env_dir, 'include') + libpath = self._venv_path(env_dir, 'purelib') + + context.inc_path = incpath + create_if_needed(incpath) + context.lib_path = libpath create_if_needed(libpath) # Issue 21197: create lib64 as a symlink to lib on 64-bit non-OS X POSIX if ((sys.maxsize > 2**32) and (os.name == 'posix') and @@ -138,8 +151,8 @@ class EnvBuilder: link_path = os.path.join(env_dir, 'lib64') if not os.path.exists(link_path): # Issue #21643 os.symlink('lib', link_path) - context.bin_path = binpath = os.path.join(env_dir, binname) - context.bin_name = binname + context.bin_path = binpath + context.bin_name = os.path.relpath(binpath, env_dir) context.env_exe = os.path.join(binpath, exename) create_if_needed(binpath) # Assign and update the command to use when launching the newly created @@ -178,6 +191,29 @@ class EnvBuilder: f.write('version = %d.%d.%d\n' % sys.version_info[:3]) if self.prompt is not None: f.write(f'prompt = {self.prompt!r}\n') + f.write('executable = %s\n' % os.path.realpath(sys.executable)) + args = [] + nt = os.name == 'nt' + if nt and self.symlinks: + args.append('--symlinks') + if not nt and not self.symlinks: + args.append('--copies') + if not self.with_pip: + args.append('--without-pip') + if self.system_site_packages: + args.append('--system-site-packages') + if self.clear: + args.append('--clear') + if self.upgrade: + args.append('--upgrade') + if self.upgrade_deps: + args.append('--upgrade-deps') + if self.orig_prompt is not None: + args.append(f'--prompt="{self.orig_prompt}"') + + args.append(context.env_dir) + args = ' '.join(args) + f.write(f'command = {sys.executable} -m venv {args}\n') if os.name != 'nt': def symlink_or_copy(self, src, dst, relative_symlinks_ok=False): @@ -187,7 +223,7 @@ class EnvBuilder: force_copy = not self.symlinks if not force_copy: try: - if not os.path.islink(dst): # can't link to itself! + if not os.path.islink(dst): # can't link to itself! if relative_symlinks_ok: assert os.path.dirname(src) == os.path.dirname(dst) os.symlink(os.path.basename(src), dst) @@ -224,7 +260,7 @@ class EnvBuilder: basename + ext) # Builds or venv's from builds need to remap source file # locations, as we do not put them into Lib/venv/scripts - if sysconfig.is_python_build(True) or not os.path.isfile(srcfn): + if sysconfig.is_python_build() or not os.path.isfile(srcfn): if basename.endswith('_d'): ext = '_d' + ext basename = basename[:-2] @@ -275,7 +311,7 @@ class EnvBuilder: f for f in os.listdir(dirname) if os.path.normcase(os.path.splitext(f)[1]) in ('.exe', '.dll') ] - if sysconfig.is_python_build(True): + if sysconfig.is_python_build(): suffixes = [ f for f in suffixes if os.path.normcase(f).startswith(('python', 'vcruntime')) @@ -290,7 +326,7 @@ class EnvBuilder: if os.path.lexists(src): copier(src, os.path.join(binpath, suffix)) - if sysconfig.is_python_build(True): + if sysconfig.is_python_build(): # copy init.tcl for root, dirs, files in os.walk(context.python_dir): if 'init.tcl' in files: @@ -303,14 +339,25 @@ class EnvBuilder: shutil.copyfile(src, dst) break + def _call_new_python(self, context, *py_args, **kwargs): + """Executes the newly created Python using safe-ish options""" + # gh-98251: We do not want to just use '-I' because that masks + # legitimate user preferences (such as not writing bytecode). All we + # really need is to ensure that the path variables do not overrule + # normal venv handling. + args = [context.env_exec_cmd, *py_args] + kwargs['env'] = env = os.environ.copy() + env['VIRTUAL_ENV'] = context.env_dir + env.pop('PYTHONHOME', None) + env.pop('PYTHONPATH', None) + kwargs['cwd'] = context.env_dir + kwargs['executable'] = context.env_exec_cmd + subprocess.check_output(args, **kwargs) + def _setup_pip(self, context): """Installs or upgrades pip in a virtual environment""" - # We run ensurepip in isolated mode to avoid side effects from - # environment vars, the current directory and anything else - # intended for the global Python environment - cmd = [context.env_exec_cmd, '-Im', 'ensurepip', '--upgrade', - '--default-pip'] - subprocess.check_output(cmd, stderr=subprocess.STDOUT) + self._call_new_python(context, '-m', 'ensurepip', '--upgrade', + '--default-pip', stderr=subprocess.STDOUT) def setup_scripts(self, context): """ @@ -371,11 +418,11 @@ class EnvBuilder: binpath = context.bin_path plen = len(path) for root, dirs, files in os.walk(path): - if root == path: # at top-level, remove irrelevant dirs + if root == path: # at top-level, remove irrelevant dirs for d in dirs[:]: if d not in ('common', os.name): dirs.remove(d) - continue # ignore files in top level + continue # ignore files in top level for f in files: if (os.name == 'nt' and f.startswith('python') and f.endswith(('.exe', '.pdb'))): @@ -409,9 +456,8 @@ class EnvBuilder: logger.debug( f'Upgrading {CORE_VENV_DEPS} packages in {context.bin_path}' ) - cmd = [context.env_exec_cmd, '-m', 'pip', 'install', '--upgrade'] - cmd.extend(CORE_VENV_DEPS) - subprocess.check_call(cmd) + self._call_new_python(context, '-m', 'pip', 'install', '--upgrade', + *CORE_VENV_DEPS) def create(env_dir, system_site_packages=False, clear=False, @@ -422,83 +468,76 @@ def create(env_dir, system_site_packages=False, clear=False, prompt=prompt, upgrade_deps=upgrade_deps) builder.create(env_dir) -def main(args=None): - compatible = True - if sys.version_info < (3, 3): - compatible = False - elif not hasattr(sys, 'base_prefix'): - compatible = False - if not compatible: - raise ValueError('This script is only for use with Python >= 3.3') - else: - import argparse - parser = argparse.ArgumentParser(prog=__name__, - description='Creates virtual Python ' - 'environments in one or ' - 'more target ' - 'directories.', - epilog='Once an environment has been ' - 'created, you may wish to ' - 'activate it, e.g. by ' - 'sourcing an activate script ' - 'in its bin directory.') - parser.add_argument('dirs', metavar='ENV_DIR', nargs='+', - help='A directory to create the environment in.') - parser.add_argument('--system-site-packages', default=False, - action='store_true', dest='system_site', - help='Give the virtual environment access to the ' - 'system site-packages dir.') - if os.name == 'nt': - use_symlinks = False - else: - use_symlinks = True - group = parser.add_mutually_exclusive_group() - group.add_argument('--symlinks', default=use_symlinks, - action='store_true', dest='symlinks', - help='Try to use symlinks rather than copies, ' - 'when symlinks are not the default for ' - 'the platform.') - group.add_argument('--copies', default=not use_symlinks, - action='store_false', dest='symlinks', - help='Try to use copies rather than symlinks, ' - 'even when symlinks are the default for ' - 'the platform.') - parser.add_argument('--clear', default=False, action='store_true', - dest='clear', help='Delete the contents of the ' - 'environment directory if it ' - 'already exists, before ' - 'environment creation.') - parser.add_argument('--upgrade', default=False, action='store_true', - dest='upgrade', help='Upgrade the environment ' - 'directory to use this version ' - 'of Python, assuming Python ' - 'has been upgraded in-place.') - parser.add_argument('--without-pip', dest='with_pip', - default=True, action='store_false', - help='Skips installing or upgrading pip in the ' - 'virtual environment (pip is bootstrapped ' - 'by default)') - parser.add_argument('--prompt', - help='Provides an alternative prompt prefix for ' - 'this environment.') - parser.add_argument('--upgrade-deps', default=False, action='store_true', - dest='upgrade_deps', - help='Upgrade core dependencies: {} to the latest ' - 'version in PyPI'.format( - ' '.join(CORE_VENV_DEPS))) - options = parser.parse_args(args) - if options.upgrade and options.clear: - raise ValueError('you cannot supply --upgrade and --clear together.') - builder = EnvBuilder(system_site_packages=options.system_site, - clear=options.clear, - symlinks=options.symlinks, - upgrade=options.upgrade, - with_pip=options.with_pip, - prompt=options.prompt, - upgrade_deps=options.upgrade_deps) - for d in options.dirs: - builder.create(d) +def main(args=None): + import argparse + + parser = argparse.ArgumentParser(prog=__name__, + description='Creates virtual Python ' + 'environments in one or ' + 'more target ' + 'directories.', + epilog='Once an environment has been ' + 'created, you may wish to ' + 'activate it, e.g. by ' + 'sourcing an activate script ' + 'in its bin directory.') + parser.add_argument('dirs', metavar='ENV_DIR', nargs='+', + help='A directory to create the environment in.') + parser.add_argument('--system-site-packages', default=False, + action='store_true', dest='system_site', + help='Give the virtual environment access to the ' + 'system site-packages dir.') + if os.name == 'nt': + use_symlinks = False + else: + use_symlinks = True + group = parser.add_mutually_exclusive_group() + group.add_argument('--symlinks', default=use_symlinks, + action='store_true', dest='symlinks', + help='Try to use symlinks rather than copies, ' + 'when symlinks are not the default for ' + 'the platform.') + group.add_argument('--copies', default=not use_symlinks, + action='store_false', dest='symlinks', + help='Try to use copies rather than symlinks, ' + 'even when symlinks are the default for ' + 'the platform.') + parser.add_argument('--clear', default=False, action='store_true', + dest='clear', help='Delete the contents of the ' + 'environment directory if it ' + 'already exists, before ' + 'environment creation.') + parser.add_argument('--upgrade', default=False, action='store_true', + dest='upgrade', help='Upgrade the environment ' + 'directory to use this version ' + 'of Python, assuming Python ' + 'has been upgraded in-place.') + parser.add_argument('--without-pip', dest='with_pip', + default=True, action='store_false', + help='Skips installing or upgrading pip in the ' + 'virtual environment (pip is bootstrapped ' + 'by default)') + parser.add_argument('--prompt', + help='Provides an alternative prompt prefix for ' + 'this environment.') + parser.add_argument('--upgrade-deps', default=False, action='store_true', + dest='upgrade_deps', + help=f'Upgrade core dependencies: {", ".join(CORE_VENV_DEPS)} ' + 'to the latest version in PyPI') + options = parser.parse_args(args) + if options.upgrade and options.clear: + raise ValueError('you cannot supply --upgrade and --clear together.') + builder = EnvBuilder(system_site_packages=options.system_site, + clear=options.clear, + symlinks=options.symlinks, + upgrade=options.upgrade, + with_pip=options.with_pip, + prompt=options.prompt, + upgrade_deps=options.upgrade_deps) + for d in options.dirs: + builder.create(d) + if __name__ == '__main__': rc = 1 diff --git a/Lib/venv/scripts/posix/activate.fish b/Lib/venv/scripts/posix/activate.fish index e40a1d71489..9aa4446005f 100644 --- a/Lib/venv/scripts/posix/activate.fish +++ b/Lib/venv/scripts/posix/activate.fish @@ -13,10 +13,13 @@ function deactivate -d "Exit virtual environment and return to normal shell env end if test -n "$_OLD_FISH_PROMPT_OVERRIDE" - functions -e fish_prompt set -e _OLD_FISH_PROMPT_OVERRIDE - functions -c _old_fish_prompt fish_prompt - functions -e _old_fish_prompt + # prevents error when using nested fish instances (Issue #93858) + if functions -q _old_fish_prompt + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end end set -e VIRTUAL_ENV diff --git a/Lib/warnings.py b/Lib/warnings.py index 691ccddfa45..98ae708ca34 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -269,22 +269,32 @@ def _getcategory(category): return cat -def _is_internal_frame(frame): - """Signal whether the frame is an internal CPython implementation detail.""" - filename = frame.f_code.co_filename +def _is_internal_filename(filename): return 'importlib' in filename and '_bootstrap' in filename -def _next_external_frame(frame): - """Find the next frame that doesn't involve CPython internals.""" +def _is_filename_to_skip(filename, skip_file_prefixes): + return any(filename.startswith(prefix) for prefix in skip_file_prefixes) + + +def _is_internal_frame(frame): + """Signal whether the frame is an internal CPython implementation detail.""" + return _is_internal_filename(frame.f_code.co_filename) + + +def _next_external_frame(frame, skip_file_prefixes): + """Find the next frame that doesn't involve Python or user internals.""" frame = frame.f_back - while frame is not None and _is_internal_frame(frame): + while frame is not None and ( + _is_internal_filename(filename := frame.f_code.co_filename) or + _is_filename_to_skip(filename, skip_file_prefixes)): frame = frame.f_back return frame # Code typically replaced by _warnings -def warn(message, category=None, stacklevel=1, source=None): +def warn(message, category=None, stacklevel=1, source=None, + *, skip_file_prefixes=()): """Issue a warning, or maybe ignore it or raise an exception.""" # Check if message is already a Warning object if isinstance(message, Warning): @@ -295,6 +305,11 @@ def warn(message, category=None, stacklevel=1, source=None): if not (isinstance(category, type) and issubclass(category, Warning)): raise TypeError("category must be a Warning subclass, " "not '{:s}'".format(type(category).__name__)) + if not isinstance(skip_file_prefixes, tuple): + # The C version demands a tuple for implementation performance. + raise TypeError('skip_file_prefixes must be a tuple of strs.') + if skip_file_prefixes: + stacklevel = max(2, stacklevel) # Get context information try: if stacklevel <= 1 or _is_internal_frame(sys._getframe(1)): @@ -305,7 +320,7 @@ def warn(message, category=None, stacklevel=1, source=None): frame = sys._getframe(1) # Look for one frame less since the above line starts us off. for x in range(stacklevel-1): - frame = _next_external_frame(frame) + frame = _next_external_frame(frame, skip_file_prefixes) if frame is None: raise ValueError except ValueError: @@ -432,9 +447,13 @@ class catch_warnings(object): named 'warnings' and imported under that name. This argument is only useful when testing the warnings module itself. + If the 'action' argument is not None, the remaining arguments are passed + to warnings.simplefilter() as if it were called immediately on entering the + context. """ - def __init__(self, *, record=False, module=None): + def __init__(self, *, record=False, module=None, + action=None, category=Warning, lineno=0, append=False): """Specify whether to record warnings and if an alternative module should be used other than sys.modules['warnings']. @@ -445,6 +464,10 @@ class catch_warnings(object): self._record = record self._module = sys.modules['warnings'] if module is None else module self._entered = False + if action is None: + self._filter = None + else: + self._filter = (action, category, lineno, append) def __repr__(self): args = [] @@ -464,6 +487,8 @@ class catch_warnings(object): self._module._filters_mutated() self._showwarning = self._module.showwarning self._showwarnmsg_impl = self._module._showwarnmsg_impl + if self._filter is not None: + simplefilter(*self._filter) if self._record: log = [] self._module._showwarnmsg_impl = log.append @@ -483,6 +508,27 @@ class catch_warnings(object): self._module._showwarnmsg_impl = self._showwarnmsg_impl +_DEPRECATED_MSG = "{name!r} is deprecated and slated for removal in Python {remove}" + +def _deprecated(name, message=_DEPRECATED_MSG, *, remove, _version=sys.version_info): + """Warn that *name* is deprecated or should be removed. + + RuntimeError is raised if *remove* specifies a major/minor tuple older than + the current Python version or the same version but past the alpha. + + The *message* argument is formatted with *name* and *remove* as a Python + version (e.g. "3.11"). + + """ + remove_formatted = f"{remove[0]}.{remove[1]}" + if (_version[:2] > remove) or (_version[:2] == remove and _version[3] != "alpha"): + msg = f"{name!r} was slated for removal after Python {remove_formatted} alpha" + raise RuntimeError(msg) + else: + msg = message.format(name=name, remove=remove_formatted) + warn(msg, DeprecationWarning, stacklevel=3) + + # Private utility function called by _PyErr_WarnUnawaitedCoroutine def _warn_unawaited_coroutine(coro): msg_lines = [ diff --git a/Lib/wave.py b/Lib/wave.py index b7071198e6b..d5858e5d4b8 100644 --- a/Lib/wave.py +++ b/Lib/wave.py @@ -71,9 +71,7 @@ The close() method is called automatically when the class instance is destroyed. """ -from chunk import Chunk from collections import namedtuple -import audioop import builtins import struct import sys @@ -85,12 +83,138 @@ class Error(Exception): pass WAVE_FORMAT_PCM = 0x0001 +WAVE_FORMAT_EXTENSIBLE = 0xFFFE +# Derived from uuid.UUID("00000001-0000-0010-8000-00aa00389b71").bytes_le +KSDATAFORMAT_SUBTYPE_PCM = b'\x01\x00\x00\x00\x00\x00\x10\x00\x80\x00\x00\xaa\x008\x9bq' _array_fmts = None, 'b', 'h', None, 'i' _wave_params = namedtuple('_wave_params', 'nchannels sampwidth framerate nframes comptype compname') +def _byteswap(data, width): + swapped_data = bytearray(len(data)) + + for i in range(0, len(data), width): + for j in range(width): + swapped_data[i + width - 1 - j] = data[i + j] + + return bytes(swapped_data) + + +class _Chunk: + def __init__(self, file, align=True, bigendian=True, inclheader=False): + import struct + self.closed = False + self.align = align # whether to align to word (2-byte) boundaries + if bigendian: + strflag = '>' + else: + strflag = '<' + self.file = file + self.chunkname = file.read(4) + if len(self.chunkname) < 4: + raise EOFError + try: + self.chunksize = struct.unpack_from(strflag+'L', file.read(4))[0] + except struct.error: + raise EOFError from None + if inclheader: + self.chunksize = self.chunksize - 8 # subtract header + self.size_read = 0 + try: + self.offset = self.file.tell() + except (AttributeError, OSError): + self.seekable = False + else: + self.seekable = True + + def getname(self): + """Return the name (ID) of the current chunk.""" + return self.chunkname + + def close(self): + if not self.closed: + try: + self.skip() + finally: + self.closed = True + + def seek(self, pos, whence=0): + """Seek to specified position into the chunk. + Default position is 0 (start of chunk). + If the file is not seekable, this will result in an error. + """ + + if self.closed: + raise ValueError("I/O operation on closed file") + if not self.seekable: + raise OSError("cannot seek") + if whence == 1: + pos = pos + self.size_read + elif whence == 2: + pos = pos + self.chunksize + if pos < 0 or pos > self.chunksize: + raise RuntimeError + self.file.seek(self.offset + pos, 0) + self.size_read = pos + + def tell(self): + if self.closed: + raise ValueError("I/O operation on closed file") + return self.size_read + + def read(self, size=-1): + """Read at most size bytes from the chunk. + If size is omitted or negative, read until the end + of the chunk. + """ + + if self.closed: + raise ValueError("I/O operation on closed file") + if self.size_read >= self.chunksize: + return b'' + if size < 0: + size = self.chunksize - self.size_read + if size > self.chunksize - self.size_read: + size = self.chunksize - self.size_read + data = self.file.read(size) + self.size_read = self.size_read + len(data) + if self.size_read == self.chunksize and \ + self.align and \ + (self.chunksize & 1): + dummy = self.file.read(1) + self.size_read = self.size_read + len(dummy) + return data + + def skip(self): + """Skip the rest of the chunk. + If you are not interested in the contents of the chunk, + this method should be called so that the file points to + the start of the next chunk. + """ + + if self.closed: + raise ValueError("I/O operation on closed file") + if self.seekable: + try: + n = self.chunksize - self.size_read + # maybe fix alignment + if self.align and (self.chunksize & 1): + n = n + 1 + self.file.seek(n, 1) + self.size_read = self.size_read + n + return + except OSError: + pass + while self.size_read < self.chunksize: + n = min(8192, self.chunksize - self.size_read) + dummy = self.read(n) + if not dummy: + raise EOFError + + + class Wave_read: """Variables used in this class: @@ -125,7 +249,7 @@ class Wave_read: def initfp(self, file): self._convert = None self._soundpos = 0 - self._file = Chunk(file, bigendian = 0) + self._file = _Chunk(file, bigendian = 0) if self._file.getname() != b'RIFF': raise Error('file does not start with RIFF id') if self._file.read(4) != b'WAVE': @@ -135,7 +259,7 @@ class Wave_read: while 1: self._data_seek_needed = 1 try: - chunk = Chunk(self._file, bigendian = 0) + chunk = _Chunk(self._file, bigendian = 0) except EOFError: break chunkname = chunk.getname() @@ -241,7 +365,7 @@ class Wave_read: return b'' data = self._data_chunk.read(nframes * self._framesize) if self._sampwidth != 1 and sys.byteorder == 'big': - data = audioop.byteswap(data, self._sampwidth) + data = _byteswap(data, self._sampwidth) if self._convert and data: data = self._convert(data) self._soundpos = self._soundpos + len(data) // (self._nchannels * self._sampwidth) @@ -256,16 +380,31 @@ class Wave_read: wFormatTag, self._nchannels, self._framerate, dwAvgBytesPerSec, wBlockAlign = struct.unpack_from('=4,"Status must be at least 4 characters" - assert status[:3].isdigit(), "Status message must begin w/3-digit code" - assert status[3]==" ", "Status message must have a space after code" + self._validate_status(status) if __debug__: for name, val in headers: @@ -251,6 +248,14 @@ class BaseHandler: return self.write + def _validate_status(self, status): + if len(status) < 4: + raise AssertionError("Status must be at least 4 characters") + if not status[:3].isdigit(): + raise AssertionError("Status message must begin w/3-digit code") + if status[3] != " ": + raise AssertionError("Status message must have a space after code") + def _convert_string_type(self, value, title): """Convert/check value type.""" if type(value) is str: @@ -470,10 +475,7 @@ class SimpleHandler(BaseHandler): from warnings import warn warn("SimpleHandler.stdout.write() should not do partial writes", DeprecationWarning) - while True: - data = data[result:] - if not data: - break + while data := data[result:]: result = self.stdout.write(data) def _flush(self): diff --git a/Lib/wsgiref/types.py b/Lib/wsgiref/types.py new file mode 100644 index 00000000000..ef0aead5b28 --- /dev/null +++ b/Lib/wsgiref/types.py @@ -0,0 +1,54 @@ +"""WSGI-related types for static type checking""" + +from collections.abc import Callable, Iterable, Iterator +from types import TracebackType +from typing import Any, Protocol, TypeAlias + +__all__ = [ + "StartResponse", + "WSGIEnvironment", + "WSGIApplication", + "InputStream", + "ErrorStream", + "FileWrapper", +] + +_ExcInfo: TypeAlias = tuple[type[BaseException], BaseException, TracebackType] +_OptExcInfo: TypeAlias = _ExcInfo | tuple[None, None, None] + +class StartResponse(Protocol): + """start_response() callable as defined in PEP 3333""" + def __call__( + self, + status: str, + headers: list[tuple[str, str]], + exc_info: _OptExcInfo | None = ..., + /, + ) -> Callable[[bytes], object]: ... + +WSGIEnvironment: TypeAlias = dict[str, Any] +WSGIApplication: TypeAlias = Callable[[WSGIEnvironment, StartResponse], + Iterable[bytes]] + +class InputStream(Protocol): + """WSGI input stream as defined in PEP 3333""" + def read(self, size: int = ..., /) -> bytes: ... + def readline(self, size: int = ..., /) -> bytes: ... + def readlines(self, hint: int = ..., /) -> list[bytes]: ... + def __iter__(self) -> Iterator[bytes]: ... + +class ErrorStream(Protocol): + """WSGI error stream as defined in PEP 3333""" + def flush(self) -> object: ... + def write(self, s: str, /) -> object: ... + def writelines(self, seq: list[str], /) -> object: ... + +class _Readable(Protocol): + def read(self, size: int = ..., /) -> bytes: ... + # Optional: def close(self) -> object: ... + +class FileWrapper(Protocol): + """WSGI file wrapper as defined in PEP 3333""" + def __call__( + self, file: _Readable, block_size: int = ..., /, + ) -> Iterable[bytes]: ... diff --git a/Lib/wsgiref/validate.py b/Lib/wsgiref/validate.py index 6e16578dbb6..1a1853cd63a 100644 --- a/Lib/wsgiref/validate.py +++ b/Lib/wsgiref/validate.py @@ -1,6 +1,6 @@ # (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org) -# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php -# Also licenced under the Apache License, 2.0: http://opensource.org/licenses/apache2.0.php +# Licensed under the MIT license: https://opensource.org/licenses/mit-license.php +# Also licenced under the Apache License, 2.0: https://opensource.org/licenses/apache2.0.php # Licensed to PSF under a Contributor Agreement """ Middleware to check for obedience to the WSGI specification. @@ -214,10 +214,7 @@ class InputWrapper: return lines def __iter__(self): - while 1: - line = self.readline() - if not line: - return + while line := self.readline(): yield line def close(self): diff --git a/Lib/xdrlib.py b/Lib/xdrlib.py index d6e1aeb5272..f8c2c18228d 100644 --- a/Lib/xdrlib.py +++ b/Lib/xdrlib.py @@ -7,6 +7,9 @@ See: RFC 1014 import struct from io import BytesIO from functools import wraps +import warnings + +warnings._deprecated(__name__, remove=(3, 13)) __all__ = ["Error", "Packer", "Unpacker", "ConversionError"] @@ -221,9 +224,7 @@ class Unpacker: def unpack_list(self, unpack_item): list = [] - while 1: - x = self.unpack_uint() - if x == 0: break + while (x := self.unpack_uint()) != 0: if x != 1: raise ConversionError('0 or 1 expected, got %r' % (x,)) item = unpack_item() diff --git a/Lib/xml/dom/expatbuilder.py b/Lib/xml/dom/expatbuilder.py index 199c22d0af3..7dd667bf3fb 100644 --- a/Lib/xml/dom/expatbuilder.py +++ b/Lib/xml/dom/expatbuilder.py @@ -200,10 +200,7 @@ class ExpatBuilder: parser = self.getParser() first_buffer = True try: - while 1: - buffer = file.read(16*1024) - if not buffer: - break + while buffer := file.read(16*1024): parser.Parse(buffer, False) if first_buffer and self.document.documentElement: self._setup_subset(buffer) diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py index d09ef5e7d03..ef8a159833b 100644 --- a/Lib/xml/dom/minidom.py +++ b/Lib/xml/dom/minidom.py @@ -358,6 +358,8 @@ class Attr(Node): self._name = qName self.namespaceURI = namespaceURI self._prefix = prefix + if localName is not None: + self._localName = localName self.childNodes = NodeList() # Add the single child node that represents the value of the attr diff --git a/Lib/xml/etree/ElementPath.py b/Lib/xml/etree/ElementPath.py index cd3c354d081..dc6bd28c031 100644 --- a/Lib/xml/etree/ElementPath.py +++ b/Lib/xml/etree/ElementPath.py @@ -416,6 +416,8 @@ def findall(elem, path, namespaces=None): def findtext(elem, path, default=None, namespaces=None): try: elem = next(iterfind(elem, path, namespaces)) - return elem.text or "" + if elem.text is None: + return "" + return elem.text except StopIteration: return default diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index e9409fd29a1..42574eefd81 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -188,19 +188,6 @@ class Element: """ return self.__class__(tag, attrib) - def copy(self): - """Return copy of current element. - - This creates a shallow copy. Subelements will be shared with the - original tree. - - """ - warnings.warn( - "elem.copy() is deprecated. Use copy.copy(elem) instead.", - DeprecationWarning - ) - return self.__copy__() - def __copy__(self): elem = self.makeelement(self.tag, self.attrib) elem.text = self.text @@ -213,9 +200,10 @@ class Element: def __bool__(self): warnings.warn( - "The behavior of this method will change in future versions. " + "Testing an element's truth value will raise an exception in " + "future versions. " "Use specific 'len(elem)' or 'elem is not None' test instead.", - FutureWarning, stacklevel=2 + DeprecationWarning, stacklevel=2 ) return len(self._children) != 0 # emulate old behaviour, for now @@ -579,10 +567,7 @@ class ElementTree: # it with chunks. self._root = parser._parse_whole(source) return self._root - while True: - data = source.read(65536) - if not data: - break + while data := source.read(65536): parser.feed(data) self._root = parser.close() return self._root @@ -728,16 +713,11 @@ class ElementTree: encoding = "utf-8" else: encoding = "us-ascii" - enc_lower = encoding.lower() - with _get_writer(file_or_filename, enc_lower) as write: + with _get_writer(file_or_filename, encoding) as (write, declared_encoding): if method == "xml" and (xml_declaration or (xml_declaration is None and - enc_lower not in ("utf-8", "us-ascii", "unicode"))): - declared_encoding = encoding - if enc_lower == "unicode": - # Retrieve the default encoding for the xml declaration - import locale - declared_encoding = locale.getpreferredencoding() + encoding.lower() != "unicode" and + declared_encoding.lower() not in ("utf-8", "us-ascii"))): write("\n" % ( declared_encoding,)) if method == "text": @@ -762,19 +742,17 @@ def _get_writer(file_or_filename, encoding): write = file_or_filename.write except AttributeError: # file_or_filename is a file name - if encoding == "unicode": - file = open(file_or_filename, "w") - else: - file = open(file_or_filename, "w", encoding=encoding, - errors="xmlcharrefreplace") - with file: - yield file.write + if encoding.lower() == "unicode": + encoding="utf-8" + with open(file_or_filename, "w", encoding=encoding, + errors="xmlcharrefreplace") as file: + yield file.write, encoding else: # file_or_filename is a file-like object # encoding determines if it is a text or binary writer - if encoding == "unicode": + if encoding.lower() == "unicode": # use a text writer as is - yield write + yield write, getattr(file_or_filename, "encoding", None) or "utf-8" else: # wrap a binary writer with TextIOWrapper with contextlib.ExitStack() as stack: @@ -805,7 +783,7 @@ def _get_writer(file_or_filename, encoding): # Keep the original file open when the TextIOWrapper is # destroyed stack.callback(file.detach) - yield file.write + yield file.write, encoding def _namespaces(elem, default_namespace=None): # identify namespaces used in this tree @@ -918,13 +896,9 @@ def _serialize_xml(write, elem, qnames, namespaces, if elem.tail: write(_escape_cdata(elem.tail)) -HTML_EMPTY = ("area", "base", "basefont", "br", "col", "frame", "hr", - "img", "input", "isindex", "link", "meta", "param") - -try: - HTML_EMPTY = set(HTML_EMPTY) -except NameError: - pass +HTML_EMPTY = {"area", "base", "basefont", "br", "col", "embed", "frame", "hr", + "img", "input", "isindex", "link", "meta", "param", "source", + "track", "wbr"} def _serialize_html(write, elem, qnames, namespaces, **kwargs): tag = elem.tag @@ -1248,8 +1222,14 @@ def iterparse(source, events=None, parser=None): # Use the internal, undocumented _parser argument for now; When the # parser argument of iterparse is removed, this can be killed. pullparser = XMLPullParser(events=events, _parser=parser) - def iterator(): + + def iterator(source): + close_source = False try: + if not hasattr(source, "read"): + source = open(source, "rb") + close_source = True + yield None while True: yield from pullparser.read_events() # load event buffer @@ -1265,16 +1245,12 @@ def iterparse(source, events=None, parser=None): source.close() class IterParseIterator(collections.abc.Iterator): - __next__ = iterator().__next__ + __next__ = iterator(source).__next__ it = IterParseIterator() it.root = None del iterator, IterParseIterator - close_source = False - if not hasattr(source, "read"): - source = open(source, "rb") - close_source = True - + next(it) return it diff --git a/Lib/xml/sax/__init__.py b/Lib/xml/sax/__init__.py index 17b75879eba..b657310207c 100644 --- a/Lib/xml/sax/__init__.py +++ b/Lib/xml/sax/__init__.py @@ -60,11 +60,7 @@ if _false: import os, sys if not sys.flags.ignore_environment and "PY_SAX_PARSER" in os.environ: default_parser_list = os.environ["PY_SAX_PARSER"].split(",") -del os - -_key = "python.xml.sax.parser" -if sys.platform[:4] == "java" and sys.registry.containsKey(_key): - default_parser_list = sys.registry.getProperty(_key).split(",") +del os, sys def make_parser(parser_list=()): @@ -93,15 +89,6 @@ def make_parser(parser_list=()): # --- Internal utility methods used by make_parser -if sys.platform[ : 4] == "java": - def _create_parser(parser_name): - from org.python.core import imp - drv_module = imp.importName(parser_name, 0, globals()) - return drv_module.create_parser() - -else: - def _create_parser(parser_name): - drv_module = __import__(parser_name,{},{},['create_parser']) - return drv_module.create_parser() - -del sys +def _create_parser(parser_name): + drv_module = __import__(parser_name,{},{},['create_parser']) + return drv_module.create_parser() diff --git a/Lib/xml/sax/_exceptions.py b/Lib/xml/sax/_exceptions.py index a9b2ba35c6a..f292dc3a8e5 100644 --- a/Lib/xml/sax/_exceptions.py +++ b/Lib/xml/sax/_exceptions.py @@ -1,8 +1,4 @@ """Different kinds of SAX Exceptions""" -import sys -if sys.platform[:4] == "java": - from java.lang import Exception -del sys # ===== SAXEXCEPTION ===== diff --git a/Lib/xml/sax/expatreader.py b/Lib/xml/sax/expatreader.py index e334ac9fea0..b9ad52692db 100644 --- a/Lib/xml/sax/expatreader.py +++ b/Lib/xml/sax/expatreader.py @@ -12,12 +12,6 @@ from xml.sax.handler import feature_external_ges, feature_external_pes from xml.sax.handler import feature_string_interning from xml.sax.handler import property_xml_string, property_interning_dict -# xml.parsers.expat does not raise ImportError in Jython -import sys -if sys.platform[:4] == "java": - raise SAXReaderNotAvailable("expat not available in Java", None) -del sys - try: from xml.parsers import expat except ImportError: diff --git a/Lib/xml/sax/xmlreader.py b/Lib/xml/sax/xmlreader.py index 716f2284041..e906121d23b 100644 --- a/Lib/xml/sax/xmlreader.py +++ b/Lib/xml/sax/xmlreader.py @@ -120,10 +120,8 @@ class IncrementalParser(XMLReader): file = source.getCharacterStream() if file is None: file = source.getByteStream() - buffer = file.read(self._bufsize) - while buffer: + while buffer := file.read(self._bufsize): self.feed(buffer) - buffer = file.read(self._bufsize) self.close() def feed(self, data): diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py index a614cef6ab2..ea8da766cb5 100644 --- a/Lib/xmlrpc/client.py +++ b/Lib/xmlrpc/client.py @@ -850,9 +850,9 @@ class MultiCallIterator: def __getitem__(self, i): item = self.results[i] - if type(item) == type({}): + if isinstance(item, dict): raise Fault(item['faultCode'], item['faultString']) - elif type(item) == type([]): + elif isinstance(item, list): return item[0] else: raise ValueError("unexpected type in multicall result") @@ -1339,10 +1339,7 @@ class Transport: p, u = self.getparser() - while 1: - data = stream.read(1024) - if not data: - break + while data := stream.read(1024): if self.verbose: print("body:", repr(data)) p.feed(data) diff --git a/Lib/xmlrpc/server.py b/Lib/xmlrpc/server.py index e22e480a829..4dddb1d10e0 100644 --- a/Lib/xmlrpc/server.py +++ b/Lib/xmlrpc/server.py @@ -268,17 +268,11 @@ class SimpleXMLRPCDispatcher: except Fault as fault: response = dumps(fault, allow_none=self.allow_none, encoding=self.encoding) - except: - # report exception back to server - exc_type, exc_value, exc_tb = sys.exc_info() - try: - response = dumps( - Fault(1, "%s:%s" % (exc_type, exc_value)), - encoding=self.encoding, allow_none=self.allow_none, - ) - finally: - # Break reference cycle - exc_type = exc_value = exc_tb = None + except BaseException as exc: + response = dumps( + Fault(1, "%s:%s" % (type(exc), exc)), + encoding=self.encoding, allow_none=self.allow_none, + ) return response.encode(self.encoding, 'xmlcharrefreplace') @@ -368,16 +362,11 @@ class SimpleXMLRPCDispatcher: {'faultCode' : fault.faultCode, 'faultString' : fault.faultString} ) - except: - exc_type, exc_value, exc_tb = sys.exc_info() - try: - results.append( - {'faultCode' : 1, - 'faultString' : "%s:%s" % (exc_type, exc_value)} - ) - finally: - # Break reference cycle - exc_type = exc_value = exc_tb = None + except BaseException as exc: + results.append( + {'faultCode' : 1, + 'faultString' : "%s:%s" % (type(exc), exc)} + ) return results def _dispatch(self, method, params): @@ -634,19 +623,14 @@ class MultiPathXMLRPCServer(SimpleXMLRPCServer): try: response = self.dispatchers[path]._marshaled_dispatch( data, dispatch_method, path) - except: + except BaseException as exc: # report low level exception back to server # (each dispatcher should have handled their own # exceptions) - exc_type, exc_value = sys.exc_info()[:2] - try: - response = dumps( - Fault(1, "%s:%s" % (exc_type, exc_value)), - encoding=self.encoding, allow_none=self.allow_none) - response = response.encode(self.encoding, 'xmlcharrefreplace') - finally: - # Break reference cycle - exc_type = exc_value = None + response = dumps( + Fault(1, "%s:%s" % (type(exc), exc)), + encoding=self.encoding, allow_none=self.allow_none) + response = response.encode(self.encoding, 'xmlcharrefreplace') return response class CGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher): @@ -736,9 +720,7 @@ class ServerHTMLDoc(pydoc.HTMLDoc): r'RFC[- ]?(\d+)|' r'PEP[- ]?(\d+)|' r'(self\.)?((?:\w|\.)+))\b') - while 1: - match = pattern.search(text, here) - if not match: break + while match := pattern.search(text, here): start, end = match.span() results.append(escape(text[here:start])) @@ -747,10 +729,10 @@ class ServerHTMLDoc(pydoc.HTMLDoc): url = escape(all).replace('"', '"') results.append('%s' % (url, url)) elif rfc: - url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc) + url = 'https://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc) results.append('%s' % (url, escape(all))) elif pep: - url = 'https://www.python.org/dev/peps/pep-%04d/' % int(pep) + url = 'https://peps.python.org/pep-%04d/' % int(pep) results.append('%s' % (url, escape(all))) elif text[end:end+1] == '(': results.append(self.namelink(name, methods, funcs, classes)) diff --git a/Lib/zipapp.py b/Lib/zipapp.py index ce77632516c..d8ebfcb6c73 100644 --- a/Lib/zipapp.py +++ b/Lib/zipapp.py @@ -136,7 +136,7 @@ def create_archive(source, target=None, interpreter=None, main=None, compression = (zipfile.ZIP_DEFLATED if compressed else zipfile.ZIP_STORED) with zipfile.ZipFile(fd, 'w', compression=compression) as z: - for child in source.rglob('*'): + for child in sorted(source.rglob('*')): arcname = child.relative_to(source) if filter is None or filter(arcname): z.write(child, arcname.as_posix()) diff --git a/Lib/zipfile.py b/Lib/zipfile/__init__.py similarity index 86% rename from Lib/zipfile.py rename to Lib/zipfile/__init__.py index 8e9325b9343..e1833dd1772 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile/__init__.py @@ -6,17 +6,13 @@ XXX references to utf-8 need further investigation. import binascii import importlib.util import io -import itertools import os -import posixpath import shutil import stat import struct import sys import threading import time -import contextlib -import pathlib try: import zlib # We may need its compression method @@ -553,7 +549,7 @@ class ZipInfo (object): def is_dir(self): """Return True if this archive member is a directory.""" - return self.filename[-1] == '/' + return self.filename.endswith('/') # ZIP encryption uses the CRC32 one-byte primitive for scrambling some @@ -747,7 +743,9 @@ class _SharedFile: self._lock = lock self._writing = writing self.seekable = file.seekable - self.tell = file.tell + + def tell(self): + return self._pos def seek(self, offset, whence=0): with self._lock: @@ -845,6 +843,7 @@ class ZipExtFile(io.BufferedIOBase): self._orig_compress_size = zipinfo.compress_size self._orig_file_size = zipinfo.file_size self._orig_start_crc = self._running_crc + self._orig_crc = self._expected_crc self._seekable = True except AttributeError: pass @@ -1067,17 +1066,17 @@ class ZipExtFile(io.BufferedIOBase): raise ValueError("I/O operation on closed file.") return self._seekable - def seek(self, offset, whence=0): + def seek(self, offset, whence=os.SEEK_SET): if self.closed: raise ValueError("seek on closed file.") if not self._seekable: raise io.UnsupportedOperation("underlying stream is not seekable") curr_pos = self.tell() - if whence == 0: # Seek from start of file + if whence == os.SEEK_SET: new_pos = offset - elif whence == 1: # Seek from current position + elif whence == os.SEEK_CUR: new_pos = curr_pos + offset - elif whence == 2: # Seek from EOF + elif whence == os.SEEK_END: new_pos = self._orig_file_size + offset else: raise ValueError("whence must be os.SEEK_SET (0), " @@ -1092,7 +1091,19 @@ class ZipExtFile(io.BufferedIOBase): read_offset = new_pos - curr_pos buff_offset = read_offset + self._offset - if buff_offset >= 0 and buff_offset < len(self._readbuffer): + # Fast seek uncompressed unencrypted file + if self._compress_type == ZIP_STORED and self._decrypter is None and read_offset > 0: + # disable CRC checking after first seeking - it would be invalid + self._expected_crc = None + # seek actual file taking already buffered data into account + read_offset -= len(self._readbuffer) - self._offset + self._fileobj.seek(read_offset, os.SEEK_CUR) + self._left -= read_offset + read_offset = 0 + # flush read buffer + self._readbuffer = b'' + self._offset = 0 + elif buff_offset >= 0 and buff_offset < len(self._readbuffer): # Just move the _offset index if the new position is in the _readbuffer self._offset = buff_offset read_offset = 0 @@ -1100,6 +1111,7 @@ class ZipExtFile(io.BufferedIOBase): # Position is before the current position. Reset the ZipExtFile self._fileobj.seek(self._orig_compress_start) self._running_crc = self._orig_start_crc + self._expected_crc = self._orig_crc self._compress_left = self._orig_compress_size self._left = self._orig_file_size self._readbuffer = b'' @@ -1147,8 +1159,15 @@ class _ZipWriteFile(io.BufferedIOBase): def write(self, data): if self.closed: raise ValueError('I/O operation on closed file.') - nbytes = len(data) + + # Accept any data that supports the buffer protocol + if isinstance(data, (bytes, bytearray)): + nbytes = len(data) + else: + data = memoryview(data) + nbytes = data.nbytes self._file_size += nbytes + self._crc = crc32(data, self._crc) if self._compressor: data = self._compressor.compress(data) @@ -1183,10 +1202,10 @@ class _ZipWriteFile(io.BufferedIOBase): if not self._zip64: if self._file_size > ZIP64_LIMIT: raise RuntimeError( - 'File size unexpectedly exceeded ZIP64 limit') + 'File size too large, try using force_zip64') if self._compress_size > ZIP64_LIMIT: raise RuntimeError( - 'Compressed size unexpectedly exceeded ZIP64 limit') + 'Compressed size too large, try using force_zip64') # Seek backwards and write file header (which will now include # correct CRC and file sizes) @@ -1231,7 +1250,7 @@ class ZipFile: _windows_illegal_name_trans_table = None def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True, - compresslevel=None, *, strict_timestamps=True): + compresslevel=None, *, strict_timestamps=True, metadata_encoding=None): """Open the ZIP file with mode read 'r', write 'w', exclusive create 'x', or append 'a'.""" if mode not in ('r', 'w', 'x', 'a'): @@ -1250,6 +1269,12 @@ class ZipFile: self.pwd = None self._comment = b'' self._strict_timestamps = strict_timestamps + self.metadata_encoding = metadata_encoding + + # Check that we don't try to write with nonconforming codecs + if self.metadata_encoding and mode != 'r': + raise ValueError( + "metadata_encoding is only supported for reading files") # Check if we were passed a file-like object if isinstance(file, os.PathLike): @@ -1366,6 +1391,8 @@ class ZipFile: print("given, inferred, offset", offset_cd, inferred, concat) # self.start_dir: Position of start of central directory self.start_dir = offset_cd + concat + if self.start_dir < 0: + raise BadZipFile("Bad offset for central directory") fp.seek(self.start_dir, 0) data = fp.read(size_cd) fp = io.BytesIO(data) @@ -1380,13 +1407,13 @@ class ZipFile: if self.debug > 2: print(centdir) filename = fp.read(centdir[_CD_FILENAME_LENGTH]) - flags = centdir[5] + flags = centdir[_CD_FLAG_BITS] if flags & _MASK_UTF_FILENAME: # UTF-8 file names extension filename = filename.decode('utf-8') else: # Historical ZIP filename encoding - filename = filename.decode('cp437') + filename = filename.decode(self.metadata_encoding or 'cp437') # Create ZipInfo instance to store file information x = ZipInfo(filename) x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH]) @@ -1437,7 +1464,10 @@ class ZipFile: file=file) def testzip(self): - """Read all the files and check the CRC.""" + """Read all the files and check the CRC. + + Return None if all files could be read successfully, or the name + of the offending file otherwise.""" chunk_size = 2 ** 20 for zinfo in self.filelist: try: @@ -1549,7 +1579,7 @@ class ZipFile: fname = zef_file.read(fheader[_FH_FILENAME_LENGTH]) if fheader[_FH_EXTRA_FIELD_LENGTH]: - zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) + zef_file.seek(fheader[_FH_EXTRA_FIELD_LENGTH], whence=1) if zinfo.flag_bits & _MASK_COMPRESSED_PATCH: # Zip 2.7: compressed patched data @@ -1563,7 +1593,7 @@ class ZipFile: # UTF-8 filename fname_str = fname.decode("utf-8") else: - fname_str = fname.decode("cp437") + fname_str = fname.decode(self.metadata_encoding or "cp437") if fname_str != zinfo.orig_filename: raise BadZipFile( @@ -1668,8 +1698,8 @@ class ZipFile: table = str.maketrans(illegal, '_' * len(illegal)) cls._windows_illegal_name_trans_table = table arcname = arcname.translate(table) - # remove trailing dots - arcname = (x.rstrip('.') for x in arcname.split(pathsep)) + # remove trailing dots and spaces + arcname = (x.rstrip(' .') for x in arcname.split(pathsep)) # rejoin, removing empty parts. arcname = pathsep.join(x for x in arcname if x) return arcname @@ -1697,6 +1727,9 @@ class ZipFile: # filter illegal characters on Windows arcname = self._sanitize_windows_name(arcname, os.path.sep) + if not arcname: + raise ValueError("Empty filename.") + targetpath = os.path.join(targetpath, arcname) targetpath = os.path.normpath(targetpath) @@ -1757,6 +1790,7 @@ class ZipFile: if zinfo.is_dir(): zinfo.compress_size = 0 zinfo.CRC = 0 + self.mkdir(zinfo) else: if compress_type is not None: zinfo.compress_type = compress_type @@ -1768,23 +1802,6 @@ class ZipFile: else: zinfo._compresslevel = self.compresslevel - if zinfo.is_dir(): - with self._lock: - if self._seekable: - self.fp.seek(self.start_dir) - zinfo.header_offset = self.fp.tell() # Start of header bytes - if zinfo.compress_type == ZIP_LZMA: - # Compressed data includes an end-of-stream (EOS) marker - zinfo.flag_bits |= _MASK_COMPRESS_OPTION_1 - - self._writecheck(zinfo) - self._didModify = True - - self.filelist.append(zinfo) - self.NameToInfo[zinfo.filename] = zinfo - self.fp.write(zinfo.FileHeader(False)) - self.start_dir = self.fp.tell() - else: with open(filename, "rb") as src, self.open(zinfo, 'w') as dest: shutil.copyfileobj(src, dest, 1024*8) @@ -1802,7 +1819,7 @@ class ZipFile: date_time=time.localtime(time.time())[:6]) zinfo.compress_type = self.compression zinfo._compresslevel = self.compresslevel - if zinfo.filename[-1] == '/': + if zinfo.filename.endswith('/'): zinfo.external_attr = 0o40775 << 16 # drwxrwxr-x zinfo.external_attr |= 0x10 # MS-DOS directory flag else: @@ -1829,6 +1846,41 @@ class ZipFile: with self.open(zinfo, mode='w') as dest: dest.write(data) + def mkdir(self, zinfo_or_directory_name, mode=511): + """Creates a directory inside the zip archive.""" + if isinstance(zinfo_or_directory_name, ZipInfo): + zinfo = zinfo_or_directory_name + if not zinfo.is_dir(): + raise ValueError("The given ZipInfo does not describe a directory") + elif isinstance(zinfo_or_directory_name, str): + directory_name = zinfo_or_directory_name + if not directory_name.endswith("/"): + directory_name += "/" + zinfo = ZipInfo(directory_name) + zinfo.compress_size = 0 + zinfo.CRC = 0 + zinfo.external_attr = ((0o40000 | mode) & 0xFFFF) << 16 + zinfo.file_size = 0 + zinfo.external_attr |= 0x10 + else: + raise TypeError("Expected type str or ZipInfo") + + with self._lock: + if self._seekable: + self.fp.seek(self.start_dir) + zinfo.header_offset = self.fp.tell() # Start of header bytes + if zinfo.compress_type == ZIP_LZMA: + # Compressed data includes an end-of-stream (EOS) marker + zinfo.flag_bits |= _MASK_COMPRESS_OPTION_1 + + self._writecheck(zinfo) + self._didModify = True + + self.filelist.append(zinfo) + self.NameToInfo[zinfo.filename] = zinfo + self.fp.write(zinfo.FileHeader(False)) + self.start_dir = self.fp.tell() + def __del__(self): """Call the "close()" method in case the user forgot.""" self.close() @@ -2130,372 +2182,12 @@ class PyZipFile(ZipFile): return (fname, archivename) -def _parents(path): - """ - Given a path with elements separated by - posixpath.sep, generate all parents of that path. +from ._path import ( # noqa: E402 + Path, - >>> list(_parents('b/d')) - ['b'] - >>> list(_parents('/b/d/')) - ['/b'] - >>> list(_parents('b/d/f/')) - ['b/d', 'b'] - >>> list(_parents('b')) - [] - >>> list(_parents('')) - [] - """ - return itertools.islice(_ancestry(path), 1, None) + # used privately for tests + CompleteDirs, # noqa: F401 +) - -def _ancestry(path): - """ - Given a path with elements separated by - posixpath.sep, generate all elements of that path - - >>> list(_ancestry('b/d')) - ['b/d', 'b'] - >>> list(_ancestry('/b/d/')) - ['/b/d', '/b'] - >>> list(_ancestry('b/d/f/')) - ['b/d/f', 'b/d', 'b'] - >>> list(_ancestry('b')) - ['b'] - >>> list(_ancestry('')) - [] - """ - path = path.rstrip(posixpath.sep) - while path and path != posixpath.sep: - yield path - path, tail = posixpath.split(path) - - -_dedupe = dict.fromkeys -"""Deduplicate an iterable in original order""" - - -def _difference(minuend, subtrahend): - """ - Return items in minuend not in subtrahend, retaining order - with O(1) lookup. - """ - return itertools.filterfalse(set(subtrahend).__contains__, minuend) - - -class CompleteDirs(ZipFile): - """ - A ZipFile subclass that ensures that implied directories - are always included in the namelist. - """ - - @staticmethod - def _implied_dirs(names): - parents = itertools.chain.from_iterable(map(_parents, names)) - as_dirs = (p + posixpath.sep for p in parents) - return _dedupe(_difference(as_dirs, names)) - - def namelist(self): - names = super(CompleteDirs, self).namelist() - return names + list(self._implied_dirs(names)) - - def _name_set(self): - return set(self.namelist()) - - def resolve_dir(self, name): - """ - If the name represents a directory, return that name - as a directory (with the trailing slash). - """ - names = self._name_set() - dirname = name + '/' - dir_match = name not in names and dirname in names - return dirname if dir_match else name - - @classmethod - def make(cls, source): - """ - Given a source (filename or zipfile), return an - appropriate CompleteDirs subclass. - """ - if isinstance(source, CompleteDirs): - return source - - if not isinstance(source, ZipFile): - return cls(source) - - # Only allow for FastLookup when supplied zipfile is read-only - if 'r' not in source.mode: - cls = CompleteDirs - - source.__class__ = cls - return source - - -class FastLookup(CompleteDirs): - """ - ZipFile subclass to ensure implicit - dirs exist and are resolved rapidly. - """ - - def namelist(self): - with contextlib.suppress(AttributeError): - return self.__names - self.__names = super(FastLookup, self).namelist() - return self.__names - - def _name_set(self): - with contextlib.suppress(AttributeError): - return self.__lookup - self.__lookup = super(FastLookup, self)._name_set() - return self.__lookup - - -class Path: - """ - A pathlib-compatible interface for zip files. - - Consider a zip file with this structure:: - - . - ├── a.txt - └── b - ├── c.txt - └── d - └── e.txt - - >>> data = io.BytesIO() - >>> zf = ZipFile(data, 'w') - >>> zf.writestr('a.txt', 'content of a') - >>> zf.writestr('b/c.txt', 'content of c') - >>> zf.writestr('b/d/e.txt', 'content of e') - >>> zf.filename = 'mem/abcde.zip' - - Path accepts the zipfile object itself or a filename - - >>> root = Path(zf) - - From there, several path operations are available. - - Directory iteration (including the zip file itself): - - >>> a, b = root.iterdir() - >>> a - Path('mem/abcde.zip', 'a.txt') - >>> b - Path('mem/abcde.zip', 'b/') - - name property: - - >>> b.name - 'b' - - join with divide operator: - - >>> c = b / 'c.txt' - >>> c - Path('mem/abcde.zip', 'b/c.txt') - >>> c.name - 'c.txt' - - Read text: - - >>> c.read_text() - 'content of c' - - existence: - - >>> c.exists() - True - >>> (b / 'missing.txt').exists() - False - - Coercion to string: - - >>> import os - >>> str(c).replace(os.sep, posixpath.sep) - 'mem/abcde.zip/b/c.txt' - - At the root, ``name``, ``filename``, and ``parent`` - resolve to the zipfile. Note these attributes are not - valid and will raise a ``ValueError`` if the zipfile - has no filename. - - >>> root.name - 'abcde.zip' - >>> str(root.filename).replace(os.sep, posixpath.sep) - 'mem/abcde.zip' - >>> str(root.parent) - 'mem' - """ - - __repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})" - - def __init__(self, root, at=""): - """ - Construct a Path from a ZipFile or filename. - - Note: When the source is an existing ZipFile object, - its type (__class__) will be mutated to a - specialized type. If the caller wishes to retain the - original type, the caller should either create a - separate ZipFile object or pass a filename. - """ - self.root = FastLookup.make(root) - self.at = at - - def open(self, mode='r', *args, pwd=None, **kwargs): - """ - Open this entry as text or binary following the semantics - of ``pathlib.Path.open()`` by passing arguments through - to io.TextIOWrapper(). - """ - if self.is_dir(): - raise IsADirectoryError(self) - zip_mode = mode[0] - if not self.exists() and zip_mode == 'r': - raise FileNotFoundError(self) - stream = self.root.open(self.at, zip_mode, pwd=pwd) - if 'b' in mode: - if args or kwargs: - raise ValueError("encoding args invalid for binary operation") - return stream - else: - kwargs["encoding"] = io.text_encoding(kwargs.get("encoding")) - return io.TextIOWrapper(stream, *args, **kwargs) - - @property - def name(self): - return pathlib.Path(self.at).name or self.filename.name - - @property - def suffix(self): - return pathlib.Path(self.at).suffix or self.filename.suffix - - @property - def suffixes(self): - return pathlib.Path(self.at).suffixes or self.filename.suffixes - - @property - def stem(self): - return pathlib.Path(self.at).stem or self.filename.stem - - @property - def filename(self): - return pathlib.Path(self.root.filename).joinpath(self.at) - - def read_text(self, *args, **kwargs): - kwargs["encoding"] = io.text_encoding(kwargs.get("encoding")) - with self.open('r', *args, **kwargs) as strm: - return strm.read() - - def read_bytes(self): - with self.open('rb') as strm: - return strm.read() - - def _is_child(self, path): - return posixpath.dirname(path.at.rstrip("/")) == self.at.rstrip("/") - - def _next(self, at): - return self.__class__(self.root, at) - - def is_dir(self): - return not self.at or self.at.endswith("/") - - def is_file(self): - return self.exists() and not self.is_dir() - - def exists(self): - return self.at in self.root._name_set() - - def iterdir(self): - if not self.is_dir(): - raise ValueError("Can't listdir a file") - subs = map(self._next, self.root.namelist()) - return filter(self._is_child, subs) - - def __str__(self): - return posixpath.join(self.root.filename, self.at) - - def __repr__(self): - return self.__repr.format(self=self) - - def joinpath(self, *other): - next = posixpath.join(self.at, *other) - return self._next(self.root.resolve_dir(next)) - - __truediv__ = joinpath - - @property - def parent(self): - if not self.at: - return self.filename.parent - parent_at = posixpath.dirname(self.at.rstrip('/')) - if parent_at: - parent_at += '/' - return self._next(parent_at) - - -def main(args=None): - import argparse - - description = 'A simple command-line interface for zipfile module.' - parser = argparse.ArgumentParser(description=description) - group = parser.add_mutually_exclusive_group(required=True) - group.add_argument('-l', '--list', metavar='', - help='Show listing of a zipfile') - group.add_argument('-e', '--extract', nargs=2, - metavar=('', ''), - help='Extract zipfile into target dir') - group.add_argument('-c', '--create', nargs='+', - metavar=('', ''), - help='Create zipfile from sources') - group.add_argument('-t', '--test', metavar='', - help='Test if a zipfile is valid') - args = parser.parse_args(args) - - if args.test is not None: - src = args.test - with ZipFile(src, 'r') as zf: - badfile = zf.testzip() - if badfile: - print("The following enclosed file is corrupted: {!r}".format(badfile)) - print("Done testing") - - elif args.list is not None: - src = args.list - with ZipFile(src, 'r') as zf: - zf.printdir() - - elif args.extract is not None: - src, curdir = args.extract - with ZipFile(src, 'r') as zf: - zf.extractall(curdir) - - elif args.create is not None: - zip_name = args.create.pop(0) - files = args.create - - def addToZip(zf, path, zippath): - if os.path.isfile(path): - zf.write(path, zippath, ZIP_DEFLATED) - elif os.path.isdir(path): - if zippath: - zf.write(path, zippath) - for nm in sorted(os.listdir(path)): - addToZip(zf, - os.path.join(path, nm), os.path.join(zippath, nm)) - # else: ignore - - with ZipFile(zip_name, 'w') as zf: - for path in files: - zippath = os.path.basename(path) - if not zippath: - zippath = os.path.basename(os.path.dirname(path)) - if zippath in ('', os.curdir, os.pardir): - zippath = '' - addToZip(zf, path, zippath) - - -if __name__ == "__main__": - main() +# used privately for tests +from .__main__ import main # noqa: F401, E402 diff --git a/Lib/zipfile/__main__.py b/Lib/zipfile/__main__.py new file mode 100644 index 00000000000..a9e5fb1b8d7 --- /dev/null +++ b/Lib/zipfile/__main__.py @@ -0,0 +1,77 @@ +import sys +import os +from . import ZipFile, ZIP_DEFLATED + + +def main(args=None): + import argparse + + description = 'A simple command-line interface for zipfile module.' + parser = argparse.ArgumentParser(description=description) + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('-l', '--list', metavar='', + help='Show listing of a zipfile') + group.add_argument('-e', '--extract', nargs=2, + metavar=('', ''), + help='Extract zipfile into target dir') + group.add_argument('-c', '--create', nargs='+', + metavar=('', ''), + help='Create zipfile from sources') + group.add_argument('-t', '--test', metavar='', + help='Test if a zipfile is valid') + parser.add_argument('--metadata-encoding', metavar='', + help='Specify encoding of member names for -l, -e and -t') + args = parser.parse_args(args) + + encoding = args.metadata_encoding + + if args.test is not None: + src = args.test + with ZipFile(src, 'r', metadata_encoding=encoding) as zf: + badfile = zf.testzip() + if badfile: + print("The following enclosed file is corrupted: {!r}".format(badfile)) + print("Done testing") + + elif args.list is not None: + src = args.list + with ZipFile(src, 'r', metadata_encoding=encoding) as zf: + zf.printdir() + + elif args.extract is not None: + src, curdir = args.extract + with ZipFile(src, 'r', metadata_encoding=encoding) as zf: + zf.extractall(curdir) + + elif args.create is not None: + if encoding: + print("Non-conforming encodings not supported with -c.", + file=sys.stderr) + sys.exit(1) + + zip_name = args.create.pop(0) + files = args.create + + def addToZip(zf, path, zippath): + if os.path.isfile(path): + zf.write(path, zippath, ZIP_DEFLATED) + elif os.path.isdir(path): + if zippath: + zf.write(path, zippath) + for nm in sorted(os.listdir(path)): + addToZip(zf, + os.path.join(path, nm), os.path.join(zippath, nm)) + # else: ignore + + with ZipFile(zip_name, 'w') as zf: + for path in files: + zippath = os.path.basename(path) + if not zippath: + zippath = os.path.basename(os.path.dirname(path)) + if zippath in ('', os.curdir, os.pardir): + zippath = '' + addToZip(zf, path, zippath) + + +if __name__ == "__main__": + main() diff --git a/Lib/zipfile/_path.py b/Lib/zipfile/_path.py new file mode 100644 index 00000000000..7c7a6a0e2c0 --- /dev/null +++ b/Lib/zipfile/_path.py @@ -0,0 +1,338 @@ +import io +import posixpath +import zipfile +import itertools +import contextlib +import pathlib + + +__all__ = ['Path'] + + +def _parents(path): + """ + Given a path with elements separated by + posixpath.sep, generate all parents of that path. + + >>> list(_parents('b/d')) + ['b'] + >>> list(_parents('/b/d/')) + ['/b'] + >>> list(_parents('b/d/f/')) + ['b/d', 'b'] + >>> list(_parents('b')) + [] + >>> list(_parents('')) + [] + """ + return itertools.islice(_ancestry(path), 1, None) + + +def _ancestry(path): + """ + Given a path with elements separated by + posixpath.sep, generate all elements of that path + + >>> list(_ancestry('b/d')) + ['b/d', 'b'] + >>> list(_ancestry('/b/d/')) + ['/b/d', '/b'] + >>> list(_ancestry('b/d/f/')) + ['b/d/f', 'b/d', 'b'] + >>> list(_ancestry('b')) + ['b'] + >>> list(_ancestry('')) + [] + """ + path = path.rstrip(posixpath.sep) + while path and path != posixpath.sep: + yield path + path, tail = posixpath.split(path) + + +_dedupe = dict.fromkeys +"""Deduplicate an iterable in original order""" + + +def _difference(minuend, subtrahend): + """ + Return items in minuend not in subtrahend, retaining order + with O(1) lookup. + """ + return itertools.filterfalse(set(subtrahend).__contains__, minuend) + + +class InitializedState: + """ + Mix-in to save the initialization state for pickling. + """ + + def __init__(self, *args, **kwargs): + self.__args = args + self.__kwargs = kwargs + super().__init__(*args, **kwargs) + + def __getstate__(self): + return self.__args, self.__kwargs + + def __setstate__(self, state): + args, kwargs = state + super().__init__(*args, **kwargs) + + +class CompleteDirs(InitializedState, zipfile.ZipFile): + """ + A ZipFile subclass that ensures that implied directories + are always included in the namelist. + """ + + @staticmethod + def _implied_dirs(names): + parents = itertools.chain.from_iterable(map(_parents, names)) + as_dirs = (p + posixpath.sep for p in parents) + return _dedupe(_difference(as_dirs, names)) + + def namelist(self): + names = super(CompleteDirs, self).namelist() + return names + list(self._implied_dirs(names)) + + def _name_set(self): + return set(self.namelist()) + + def resolve_dir(self, name): + """ + If the name represents a directory, return that name + as a directory (with the trailing slash). + """ + names = self._name_set() + dirname = name + '/' + dir_match = name not in names and dirname in names + return dirname if dir_match else name + + @classmethod + def make(cls, source): + """ + Given a source (filename or zipfile), return an + appropriate CompleteDirs subclass. + """ + if isinstance(source, CompleteDirs): + return source + + if not isinstance(source, zipfile.ZipFile): + return cls(source) + + # Only allow for FastLookup when supplied zipfile is read-only + if 'r' not in source.mode: + cls = CompleteDirs + + source.__class__ = cls + return source + + +class FastLookup(CompleteDirs): + """ + ZipFile subclass to ensure implicit + dirs exist and are resolved rapidly. + """ + + def namelist(self): + with contextlib.suppress(AttributeError): + return self.__names + self.__names = super(FastLookup, self).namelist() + return self.__names + + def _name_set(self): + with contextlib.suppress(AttributeError): + return self.__lookup + self.__lookup = super(FastLookup, self)._name_set() + return self.__lookup + + +def _extract_text_encoding(encoding=None, *args, **kwargs): + # stacklevel=3 so that the caller of the caller see any warning. + return io.text_encoding(encoding, 3), args, kwargs + + +class Path: + """ + A pathlib-compatible interface for zip files. + + Consider a zip file with this structure:: + + . + ├── a.txt + └── b + ├── c.txt + └── d + └── e.txt + + >>> data = io.BytesIO() + >>> zf = ZipFile(data, 'w') + >>> zf.writestr('a.txt', 'content of a') + >>> zf.writestr('b/c.txt', 'content of c') + >>> zf.writestr('b/d/e.txt', 'content of e') + >>> zf.filename = 'mem/abcde.zip' + + Path accepts the zipfile object itself or a filename + + >>> root = Path(zf) + + From there, several path operations are available. + + Directory iteration (including the zip file itself): + + >>> a, b = root.iterdir() + >>> a + Path('mem/abcde.zip', 'a.txt') + >>> b + Path('mem/abcde.zip', 'b/') + + name property: + + >>> b.name + 'b' + + join with divide operator: + + >>> c = b / 'c.txt' + >>> c + Path('mem/abcde.zip', 'b/c.txt') + >>> c.name + 'c.txt' + + Read text: + + >>> c.read_text() + 'content of c' + + existence: + + >>> c.exists() + True + >>> (b / 'missing.txt').exists() + False + + Coercion to string: + + >>> import os + >>> str(c).replace(os.sep, posixpath.sep) + 'mem/abcde.zip/b/c.txt' + + At the root, ``name``, ``filename``, and ``parent`` + resolve to the zipfile. Note these attributes are not + valid and will raise a ``ValueError`` if the zipfile + has no filename. + + >>> root.name + 'abcde.zip' + >>> str(root.filename).replace(os.sep, posixpath.sep) + 'mem/abcde.zip' + >>> str(root.parent) + 'mem' + """ + + __repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})" + + def __init__(self, root, at=""): + """ + Construct a Path from a ZipFile or filename. + + Note: When the source is an existing ZipFile object, + its type (__class__) will be mutated to a + specialized type. If the caller wishes to retain the + original type, the caller should either create a + separate ZipFile object or pass a filename. + """ + self.root = FastLookup.make(root) + self.at = at + + def open(self, mode='r', *args, pwd=None, **kwargs): + """ + Open this entry as text or binary following the semantics + of ``pathlib.Path.open()`` by passing arguments through + to io.TextIOWrapper(). + """ + if self.is_dir(): + raise IsADirectoryError(self) + zip_mode = mode[0] + if not self.exists() and zip_mode == 'r': + raise FileNotFoundError(self) + stream = self.root.open(self.at, zip_mode, pwd=pwd) + if 'b' in mode: + if args or kwargs: + raise ValueError("encoding args invalid for binary operation") + return stream + # Text mode: + encoding, args, kwargs = _extract_text_encoding(*args, **kwargs) + return io.TextIOWrapper(stream, encoding, *args, **kwargs) + + @property + def name(self): + return pathlib.Path(self.at).name or self.filename.name + + @property + def suffix(self): + return pathlib.Path(self.at).suffix or self.filename.suffix + + @property + def suffixes(self): + return pathlib.Path(self.at).suffixes or self.filename.suffixes + + @property + def stem(self): + return pathlib.Path(self.at).stem or self.filename.stem + + @property + def filename(self): + return pathlib.Path(self.root.filename).joinpath(self.at) + + def read_text(self, *args, **kwargs): + encoding, args, kwargs = _extract_text_encoding(*args, **kwargs) + with self.open('r', encoding, *args, **kwargs) as strm: + return strm.read() + + def read_bytes(self): + with self.open('rb') as strm: + return strm.read() + + def _is_child(self, path): + return posixpath.dirname(path.at.rstrip("/")) == self.at.rstrip("/") + + def _next(self, at): + return self.__class__(self.root, at) + + def is_dir(self): + return not self.at or self.at.endswith("/") + + def is_file(self): + return self.exists() and not self.is_dir() + + def exists(self): + return self.at in self.root._name_set() + + def iterdir(self): + if not self.is_dir(): + raise ValueError("Can't listdir a file") + subs = map(self._next, self.root.namelist()) + return filter(self._is_child, subs) + + def __str__(self): + return posixpath.join(self.root.filename, self.at) + + def __repr__(self): + return self.__repr.format(self=self) + + def joinpath(self, *other): + next = posixpath.join(self.at, *other) + return self._next(self.root.resolve_dir(next)) + + __truediv__ = joinpath + + @property + def parent(self): + if not self.at: + return self.filename.parent + parent_at = posixpath.dirname(self.at.rstrip('/')) + if parent_at: + parent_at += '/' + return self._next(parent_at) diff --git a/Lib/zipimport.py b/Lib/zipimport.py index 25eaee9c0f2..a7333a4c490 100644 --- a/Lib/zipimport.py +++ b/Lib/zipimport.py @@ -63,8 +63,7 @@ class zipimporter(_bootstrap_external._LoaderBasics): # if found, or else read it from the archive. def __init__(self, path): if not isinstance(path, str): - import os - path = os.fsdecode(path) + raise TypeError(f"expected str, not {type(path)!r}") if not path: raise ZipImportError('archive path is empty', path=path) if alt_path_sep: @@ -102,64 +101,6 @@ class zipimporter(_bootstrap_external._LoaderBasics): self.prefix += path_sep - # Check whether we can satisfy the import of the module named by - # 'fullname', or whether it could be a portion of a namespace - # package. Return self if we can load it, a string containing the - # full path if it's a possible namespace portion, None if we - # can't load it. - def find_loader(self, fullname, path=None): - """find_loader(fullname, path=None) -> self, str or None. - - Search for a module specified by 'fullname'. 'fullname' must be the - fully qualified (dotted) module name. It returns the zipimporter - instance itself if the module was found, a string containing the - full path name if it's possibly a portion of a namespace package, - or None otherwise. The optional 'path' argument is ignored -- it's - there for compatibility with the importer protocol. - - Deprecated since Python 3.10. Use find_spec() instead. - """ - _warnings.warn("zipimporter.find_loader() is deprecated and slated for " - "removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - mi = _get_module_info(self, fullname) - if mi is not None: - # This is a module or package. - return self, [] - - # Not a module or regular package. See if this is a directory, and - # therefore possibly a portion of a namespace package. - - # We're only interested in the last path component of fullname - # earlier components are recorded in self.prefix. - modpath = _get_module_path(self, fullname) - if _is_dir(self, modpath): - # This is possibly a portion of a namespace - # package. Return the string representing its path, - # without a trailing separator. - return None, [f'{self.archive}{path_sep}{modpath}'] - - return None, [] - - - # Check whether we can satisfy the import of the module named by - # 'fullname'. Return self if we can, None if we can't. - def find_module(self, fullname, path=None): - """find_module(fullname, path=None) -> self or None. - - Search for a module specified by 'fullname'. 'fullname' must be the - fully qualified (dotted) module name. It returns the zipimporter - instance itself if the module was found, or None if it wasn't. - The optional 'path' argument is ignored -- it's there for compatibility - with the importer protocol. - - Deprecated since Python 3.10. Use find_spec() instead. - """ - _warnings.warn("zipimporter.find_module() is deprecated and slated for " - "removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - return self.find_loader(fullname, path)[0] - def find_spec(self, fullname, target=None): """Create a ModuleSpec for the specified module. @@ -406,114 +347,121 @@ def _read_directory(archive): raise ZipImportError(f"can't open Zip file: {archive!r}", path=archive) with fp: + # GH-87235: On macOS all file descriptors for /dev/fd/N share the same + # file offset, reset the file offset after scanning the zipfile diretory + # to not cause problems when some runs 'python3 /dev/fd/9 9 header_offset: - raise ZipImportError(f'bad local header offset: {archive!r}', path=archive) - file_offset += arc_offset - - try: - name = fp.read(name_size) - except OSError: raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) - if len(name) != name_size: - raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) - # On Windows, calling fseek to skip over the fields we don't use is - # slower than reading the data because fseek flushes stdio's - # internal buffers. See issue #8745. - try: - if len(fp.read(header_size - name_size)) != header_size - name_size: - raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) - except OSError: - raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) - - if flags & 0x800: - # UTF-8 file names extension - name = name.decode() - else: - # Historical ZIP filename encoding + if buffer[:4] != STRING_END_ARCHIVE: + # Bad: End of Central Dir signature + # Check if there's a comment. try: - name = name.decode('ascii') - except UnicodeDecodeError: - name = name.decode('latin1').translate(cp437_table) + fp.seek(0, 2) + file_size = fp.tell() + except OSError: + raise ZipImportError(f"can't read Zip file: {archive!r}", + path=archive) + max_comment_start = max(file_size - MAX_COMMENT_LEN - + END_CENTRAL_DIR_SIZE, 0) + try: + fp.seek(max_comment_start) + data = fp.read() + except OSError: + raise ZipImportError(f"can't read Zip file: {archive!r}", + path=archive) + pos = data.rfind(STRING_END_ARCHIVE) + if pos < 0: + raise ZipImportError(f'not a Zip file: {archive!r}', + path=archive) + buffer = data[pos:pos+END_CENTRAL_DIR_SIZE] + if len(buffer) != END_CENTRAL_DIR_SIZE: + raise ZipImportError(f"corrupt Zip file: {archive!r}", + path=archive) + header_position = file_size - len(data) + pos - name = name.replace('/', path_sep) - path = _bootstrap_external._path_join(archive, name) - t = (path, compress, data_size, file_size, file_offset, time, date, crc) - files[name] = t - count += 1 + header_size = _unpack_uint32(buffer[12:16]) + header_offset = _unpack_uint32(buffer[16:20]) + if header_position < header_size: + raise ZipImportError(f'bad central directory size: {archive!r}', path=archive) + if header_position < header_offset: + raise ZipImportError(f'bad central directory offset: {archive!r}', path=archive) + header_position -= header_size + arc_offset = header_position - header_offset + if arc_offset < 0: + raise ZipImportError(f'bad central directory size or offset: {archive!r}', path=archive) + + files = {} + # Start of Central Directory + count = 0 + try: + fp.seek(header_position) + except OSError: + raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) + while True: + buffer = fp.read(46) + if len(buffer) < 4: + raise EOFError('EOF read where not expected') + # Start of file header + if buffer[:4] != b'PK\x01\x02': + break # Bad: Central Dir File Header + if len(buffer) != 46: + raise EOFError('EOF read where not expected') + flags = _unpack_uint16(buffer[8:10]) + compress = _unpack_uint16(buffer[10:12]) + time = _unpack_uint16(buffer[12:14]) + date = _unpack_uint16(buffer[14:16]) + crc = _unpack_uint32(buffer[16:20]) + data_size = _unpack_uint32(buffer[20:24]) + file_size = _unpack_uint32(buffer[24:28]) + name_size = _unpack_uint16(buffer[28:30]) + extra_size = _unpack_uint16(buffer[30:32]) + comment_size = _unpack_uint16(buffer[32:34]) + file_offset = _unpack_uint32(buffer[42:46]) + header_size = name_size + extra_size + comment_size + if file_offset > header_offset: + raise ZipImportError(f'bad local header offset: {archive!r}', path=archive) + file_offset += arc_offset + + try: + name = fp.read(name_size) + except OSError: + raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) + if len(name) != name_size: + raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) + # On Windows, calling fseek to skip over the fields we don't use is + # slower than reading the data because fseek flushes stdio's + # internal buffers. See issue #8745. + try: + if len(fp.read(header_size - name_size)) != header_size - name_size: + raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) + except OSError: + raise ZipImportError(f"can't read Zip file: {archive!r}", path=archive) + + if flags & 0x800: + # UTF-8 file names extension + name = name.decode() + else: + # Historical ZIP filename encoding + try: + name = name.decode('ascii') + except UnicodeDecodeError: + name = name.decode('latin1').translate(cp437_table) + + name = name.replace('/', path_sep) + path = _bootstrap_external._path_join(archive, name) + t = (path, compress, data_size, file_size, file_offset, time, date, crc) + files[name] = t + count += 1 + finally: + fp.seek(start_offset) _bootstrap._verbose_message('zipimport: found {} names in {!r}', count, archive) return files diff --git a/Lib/zoneinfo/_common.py b/Lib/zoneinfo/_common.py index 4c24f01bd7b..98cdfe37ca6 100644 --- a/Lib/zoneinfo/_common.py +++ b/Lib/zoneinfo/_common.py @@ -2,14 +2,14 @@ import struct def load_tzdata(key): - import importlib.resources + from importlib import resources components = key.split("/") package_name = ".".join(["tzdata.zoneinfo"] + components[:-1]) resource_name = components[-1] try: - return importlib.resources.open_binary(package_name, resource_name) + return resources.files(package_name).joinpath(resource_name).open("rb") except (ImportError, FileNotFoundError, UnicodeEncodeError): # There are three types of exception that can be raised that all amount # to "we cannot find this key": diff --git a/Lib/zoneinfo/_tzpath.py b/Lib/zoneinfo/_tzpath.py index 672560b9514..4985dce2dc3 100644 --- a/Lib/zoneinfo/_tzpath.py +++ b/Lib/zoneinfo/_tzpath.py @@ -118,7 +118,7 @@ def available_timezones(): # Start with loading from the tzdata package if it exists: this has a # pre-assembled list of zones that only requires opening one file. try: - with resources.open_text("tzdata", "zones") as f: + with resources.files("tzdata").joinpath("zones").open("r") as f: for zone in f: zone = zone.strip() if zone: diff --git a/Mac/BuildScript/0001-Darwin-platform-allows-to-build-on-releases-before-Y.patch b/Mac/BuildScript/0001-Darwin-platform-allows-to-build-on-releases-before-Y.patch deleted file mode 100644 index 51ccdc2267e..00000000000 --- a/Mac/BuildScript/0001-Darwin-platform-allows-to-build-on-releases-before-Y.patch +++ /dev/null @@ -1,59 +0,0 @@ -From cef404f1e7a598166cbc2fd2e0048f7e2d752ad5 Mon Sep 17 00:00:00 2001 -From: David Carlier -Date: Tue, 24 Aug 2021 22:40:14 +0100 -Subject: [PATCH] Darwin platform allows to build on releases before - Yosemite/ios 8. - -issue #16407 #16408 ---- - crypto/rand/rand_unix.c | 5 +---- - include/crypto/rand.h | 10 ++++++++++ - 2 files changed, 11 insertions(+), 4 deletions(-) - -diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c -index 43f1069d15..0f4525106a 100644 ---- a/crypto/rand/rand_unix.c -+++ b/crypto/rand/rand_unix.c -@@ -34,9 +34,6 @@ - #if defined(__OpenBSD__) - # include - #endif --#if defined(__APPLE__) --# include --#endif - - #if defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) - # include -@@ -381,7 +378,7 @@ static ssize_t syscall_random(void *buf, size_t buflen) - if (errno != ENOSYS) - return -1; - } --# elif defined(__APPLE__) -+# elif defined(OPENSSL_APPLE_CRYPTO_RANDOM) - if (CCRandomGenerateBytes(buf, buflen) == kCCSuccess) - return (ssize_t)buflen; - -diff --git a/include/crypto/rand.h b/include/crypto/rand.h -index 5350d3a931..674f840fd1 100644 ---- a/include/crypto/rand.h -+++ b/include/crypto/rand.h -@@ -20,6 +20,16 @@ - - # include - -+# if defined(__APPLE__) && !defined(OPENSSL_NO_APPLE_CRYPTO_RANDOM) -+# include -+# if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000) || \ -+ (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) -+# define OPENSSL_APPLE_CRYPTO_RANDOM 1 -+# include -+# include -+# endif -+# endif -+ - /* forward declaration */ - typedef struct rand_pool_st RAND_POOL; - --- -2.33.0 - diff --git a/Mac/BuildScript/bpo-44828-filedialog-crash-monterey-8612rc1.patch b/Mac/BuildScript/bpo-44828-filedialog-crash-monterey-8612rc1.patch deleted file mode 100644 index e70e2c35dc1..00000000000 --- a/Mac/BuildScript/bpo-44828-filedialog-crash-monterey-8612rc1.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- tk8.6.12/macosx/tkMacOSXDialog.c 2021-10-29 17:08:23.000000000 +0000 -+++ tk8.6.12-patched/macosx/tkMacOSXDialog.c 2021-11-02 19:04:59.000000000 +0000 -@@ -379,6 +379,7 @@ - [NSApp tkFilePanelDidEnd:panel - returnCode:modalReturnCode - contextInfo:callbackInfo ]; -+ [parent endSheet:panel]; - } - } else { - modalReturnCode = [panel runModal]; diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 1f6fcafc6f9..cf97b5558c2 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -203,7 +203,7 @@ def internalTk(): # Do we use 8.6.8 when building our own copy # of Tcl/Tk or a modern version. -# We use the old version when buildin on +# We use the old version when building on # old versions of macOS due to build issues. def useOldTk(): return getBuildTuple() < (10, 15) @@ -246,10 +246,9 @@ def library_recipes(): result.extend([ dict( - name="OpenSSL 1.1.1l", - url="https://www.openssl.org/source/openssl-1.1.1l.tar.gz", - checksum='ac0d4387f3ba0ad741b0580dd45f6ff3', - patches=['0001-Darwin-platform-allows-to-build-on-releases-before-Y.patch'], + name="OpenSSL 1.1.1s", + url="https://www.openssl.org/source/openssl-1.1.1s.tar.gz", + checksum='c5ac01e760ee6ff0dab61d6b2bbd30146724d063eb322180c6f18a6f74e4b6aa', buildrecipe=build_universal_openssl, configure=None, install=None, @@ -265,17 +264,18 @@ def library_recipes(): tk_patches = ['tk868_on_10_8_10_9.patch'] else: - tcl_tk_ver='8.6.12rc1' - tcl_checksum='82fd1637c0f7d4b76cb909f8abc373ec' + tcl_tk_ver='8.6.12' + tcl_checksum='87ea890821d2221f2ab5157bc5eb885f' - tk_checksum='d63c3b91b86cd8b6fa54e83ef2c5153e' - tk_patches = ['bpo-44828-filedialog-crash-monterey-8612rc1.patch'] + tk_checksum='1d6dcf6120356e3d211e056dff5e462a' + tk_patches = [ ] + base_url = "https://prdownloads.sourceforge.net/tcl/{what}{version}-src.tar.gz" result.extend([ dict( name="Tcl %s"%(tcl_tk_ver,), - url="ftp://ftp.tcl.tk/pub/tcl//tcl8_6/tcl%s-src.tar.gz"%(tcl_tk_ver,), + url=base_url.format(what="tcl", version=tcl_tk_ver), checksum=tcl_checksum, buildDir="unix", configure_pre=[ @@ -292,7 +292,7 @@ def library_recipes(): ), dict( name="Tk %s"%(tcl_tk_ver,), - url="ftp://ftp.tcl.tk/pub/tcl//tcl8_6/tk%s-src.tar.gz"%(tcl_tk_ver,), + url=base_url.format(what="tk", version=tcl_tk_ver), checksum=tk_checksum, patches=tk_patches, buildDir="unix", @@ -359,14 +359,13 @@ def library_recipes(): ), ), dict( - name="SQLite 3.36.0", - url="https://sqlite.org/2021/sqlite-autoconf-3360000.tar.gz", - checksum='f5752052fc5b8e1b539af86a3671eac7', + name="SQLite 3.39.4", + url="https://sqlite.org/2022/sqlite-autoconf-3390400.tar.gz", + checksum="44b7e6691b0954086f717a6c43b622a5", extra_cflags=('-Os ' '-DSQLITE_ENABLE_FTS5 ' '-DSQLITE_ENABLE_FTS4 ' '-DSQLITE_ENABLE_FTS3_PARENTHESIS ' - '-DSQLITE_ENABLE_JSON1 ' '-DSQLITE_ENABLE_RTREE ' '-DSQLITE_OMIT_AUTOINIT ' '-DSQLITE_TCL=0 ' @@ -798,10 +797,16 @@ def verifyThirdPartyFile(url, checksum, fname): print("Downloading %s"%(name,)) downloadURL(url, fname) print("Archive for %s stored as %s"%(name, fname)) + if len(checksum) == 32: + algo = 'md5' + elif len(checksum) == 64: + algo = 'sha256' + else: + raise ValueError(checksum) if os.system( - 'MD5=$(openssl md5 %s) ; test "${MD5##*= }" = "%s"' - % (shellQuote(fname), checksum) ): - fatal('MD5 checksum mismatch for file %s' % fname) + 'CHECKSUM=$(openssl %s %s) ; test "${CHECKSUM##*= }" = "%s"' + % (algo, shellQuote(fname), checksum) ): + fatal('%s checksum mismatch for file %s' % (algo, fname)) def build_universal_openssl(basedir, archList): """ @@ -1158,11 +1163,11 @@ def buildPython(): (' ', '--without-ensurepip ')[PYTHON_3], (' ', "--with-openssl='%s/libraries/usr/local'"%( shellQuote(WORKDIR)[1:-1],))[PYTHON_3], - (' ', "--with-tcltk-includes='-I%s/libraries/usr/local/include'"%( - shellQuote(WORKDIR)[1:-1],))[internalTk()], - (' ', "--with-tcltk-libs='-L%s/libraries/usr/local/lib -ltcl8.6 -ltk8.6'"%( - shellQuote(WORKDIR)[1:-1],))[internalTk()], (' ', "--enable-optimizations --with-lto")[compilerCanOptimize()], + (' ', "TCLTK_CFLAGS='-I%s/libraries/usr/local/include'"%( + shellQuote(WORKDIR)[1:-1],))[internalTk()], + (' ', "TCLTK_LIBS='-L%s/libraries/usr/local/lib -ltcl8.6 -ltk8.6'"%( + shellQuote(WORKDIR)[1:-1],))[internalTk()], shellQuote(WORKDIR)[1:-1], shellQuote(WORKDIR)[1:-1])) @@ -1353,7 +1358,7 @@ def buildPython(): build_time_vars = l_dict['build_time_vars'] vars = {} for k, v in build_time_vars.items(): - if type(v) == type(''): + if isinstance(v, str): for p in (include_path, lib_path): v = v.replace(' ' + p, '') v = v.replace(p + ' ', '') diff --git a/Mac/BuildScript/resources/License.rtf b/Mac/BuildScript/resources/License.rtf index 7fe7e66f4c0..1255d1ce48e 100644 --- a/Mac/BuildScript/resources/License.rtf +++ b/Mac/BuildScript/resources/License.rtf @@ -12,13 +12,13 @@ HISTORY OF THE SOFTWARE\ \f1\b0 \ulnone \ -Python was created in the early 1990s by Guido van Rossum at Stichting Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands as a successor of a language called ABC. Guido remains Python's principal author, although it includes many contributions from others.\ +Python was created in the early 1990s by Guido van Rossum at Stichting Mathematisch Centrum (CWI, see https://www.cwi.nl) in the Netherlands as a successor of a language called ABC. Guido remains Python's principal author, although it includes many contributions from others.\ \ -In 1995, Guido continued his work on Python at the Corporation for National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) in Reston, Virginia where he released several versions of the software.\ +In 1995, Guido continued his work on Python at the Corporation for National Research Initiatives (CNRI, see https://www.cnri.reston.va.us) in Reston, Virginia where he released several versions of the software.\ \ -In May 2000, Guido and the Python core development team moved to BeOpen.com to form the BeOpen PythonLabs team. In October of the same year, the PythonLabs team moved to Digital Creations (now Zope Corporation, see http://www.zope.org). In 2001, the Python Software Foundation (PSF, see https://www.python.org/psf/) was formed, a non-profit organization created specifically to own Python-related Intellectual Property. Zope Corporation is a sponsoring member of the PSF.\ +In May 2000, Guido and the Python core development team moved to BeOpen.com to form the BeOpen PythonLabs team. In October of the same year, the PythonLabs team moved to Digital Creations (now Zope Corporation, see https://www.zope.dev). In 2001, the Python Software Foundation (PSF, see https://www.python.org/psf/) was formed, a non-profit organization created specifically to own Python-related Intellectual Property. Zope Corporation is a sponsoring member of the PSF.\ \ -All Python releases are Open Source (see http://www.opensource.org for the Open Source Definition). Historically, most, but not all, Python releases have also been GPL-compatible; the table below summarizes the various releases.\ +All Python releases are Open Source (see https://opensource.org for the Open Source Definition). Historically, most, but not all, Python releases have also been GPL-compatible; the table below summarizes the various releases.\ \ \f2\b Release Derived Year Owner GPL-\ diff --git a/Mac/BuildScript/resources/ReadMe.rtf b/Mac/BuildScript/resources/ReadMe.rtf index 2a954083bf1..dbe8c520a7c 100644 --- a/Mac/BuildScript/resources/ReadMe.rtf +++ b/Mac/BuildScript/resources/ReadMe.rtf @@ -1,4 +1,4 @@ -{\rtf1\ansi\ansicpg1252\cocoartf2580 +{\rtf1\ansi\ansicpg1252\cocoartf2639 \cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fswiss\fcharset0 Helvetica-Oblique; \f3\fmodern\fcharset0 CourierNewPSMT;\f4\fmodern\fcharset0 Courier;} {\colortbl;\red255\green255\blue255;} @@ -11,7 +11,7 @@ \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\partightenfactor0 \f1\b \cf0 NOTE: -\f0\b0 This is an alpha preview of Python 3.11.0, the next feature release of Python 3. It is not intended for production use.\ +\f0\b0 This is an alpha preview of Python 3.12.0, the next feature release of Python 3. It is not intended for production use.\ \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 \cf0 \ \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 @@ -26,7 +26,7 @@ This package includes its own private copy of OpenSSL 1.1.1. The trust certifi \f0\i0 command line utility are not used as defaults by the Python \f3 ssl \f0 module. A sample command script is included in -\f3 /Applications/Python 3.9 +\f3 /Applications/Python 3.11 \f0 to install a curated bundle of default root certificates from the third-party \f3 certifi \f0 package ({\field{\*\fldinst{HYPERLINK "https://pypi.org/project/certifi/"}}{\fldrslt https://pypi.org/project/certifi/}}). Double-click on diff --git a/Mac/BuildScript/resources/Welcome.rtf b/Mac/BuildScript/resources/Welcome.rtf index e6ccfcb3fce..7819241b618 100644 --- a/Mac/BuildScript/resources/Welcome.rtf +++ b/Mac/BuildScript/resources/Welcome.rtf @@ -1,4 +1,4 @@ -{\rtf1\ansi\ansicpg1252\cocoartf2580 +{\rtf1\ansi\ansicpg1252\cocoartf2639 \cocoascreenfonts1\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fmodern\fcharset0 CourierNewPSMT; } {\colortbl;\red255\green255\blue255;} @@ -26,5 +26,5 @@ At the end of this install, click on \ \f1\b NOTE: -\f0\b0 This is an alpha test preview of Python 3.11.0, the next feature release of Python 3. It is not intended for production use.\ +\f0\b0 This is an alpha test preview of Python 3.12.0, the next feature release of Python 3. It is not intended for production use.\ } \ No newline at end of file diff --git a/Mac/BuildScript/scripts/postflight.framework b/Mac/BuildScript/scripts/postflight.framework index 0f2e52c4ca1..a63909358f1 100755 --- a/Mac/BuildScript/scripts/postflight.framework +++ b/Mac/BuildScript/scripts/postflight.framework @@ -8,12 +8,12 @@ FWK="/Library/Frameworks/Python.framework/Versions/@PYVER@" "${FWK}/bin/python@PYVER@" -E -s -Wi \ "${FWK}/lib/python${PYVER}/compileall.py" -q -j0 \ - -f -x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \ + -f -x 'bad_coding|badsyntax|site-packages|test/test_lib2to3/data' \ "${FWK}/lib/python${PYVER}" "${FWK}/bin/python@PYVER@" -E -s -Wi -O \ "${FWK}/lib/python${PYVER}/compileall.py" -q -j0 \ - -f -x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \ + -f -x 'bad_coding|badsyntax|site-packages|test/test_lib2to3/data' \ "${FWK}/lib/python${PYVER}" "${FWK}/bin/python@PYVER@" -E -s -Wi \ diff --git a/Mac/Extras.install.py b/Mac/Extras.install.py index ab1af71dfd8..41bfa53d616 100644 --- a/Mac/Extras.install.py +++ b/Mac/Extras.install.py @@ -9,10 +9,9 @@ verbose = 1 debug = 0 def isclean(name): - if name == 'CVS': return 0 - if name == '.cvsignore': return 0 - if name == '.DS_store': return 0 - if name == '.svn': return 0 + if name in ('CVS', '.cvsignore', '.svn'): + return 0 + if name.lower() == '.ds_store': return 0 if name.endswith('~'): return 0 if name.endswith('.BAK'): return 0 if name.endswith('.pyc'): return 0 diff --git a/Mac/IDLE/IDLE.app/Contents/Info.plist b/Mac/IDLE/IDLE.app/Contents/Info.plist index f6b5cfe8d54..fea06d46324 100644 --- a/Mac/IDLE/IDLE.app/Contents/Info.plist +++ b/Mac/IDLE/IDLE.app/Contents/Info.plist @@ -10,6 +10,7 @@ CFBundleTypeExtensions py + pyi pyw CFBundleTypeIconFile @@ -36,7 +37,7 @@ CFBundleExecutable IDLE CFBundleGetInfoString - %version%, © 2001-2021 Python Software Foundation + %version%, © 2001-2023 Python Software Foundation CFBundleIconFile IDLE.icns CFBundleIdentifier diff --git a/Mac/PythonLauncher/Info.plist.in b/Mac/PythonLauncher/Info.plist.in index 3d8bc3e4154..b7cddac0729 100644 --- a/Mac/PythonLauncher/Info.plist.in +++ b/Mac/PythonLauncher/Info.plist.in @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - English + en CFBundleDocumentTypes @@ -39,8 +39,10 @@ CFBundleExecutable Python Launcher + NSHumanReadableCopyright + Copyright © 2001-2023 Python Software Foundation CFBundleGetInfoString - %VERSION%, © 2001-2021 Python Software Foundation + %VERSION%, © 2001-2023 Python Software Foundation CFBundleIconFile PythonLauncher.icns CFBundleIdentifier @@ -61,5 +63,7 @@ MainMenu NSPrincipalClass NSApplication + NSAppleEventsUsageDescription + Python Launcher uses Apple events to launch your Python script in a Terminal window. diff --git a/Mac/PythonLauncher/doscript.m b/Mac/PythonLauncher/doscript.m index cbb783ba3e8..f07326bce46 100644 --- a/Mac/PythonLauncher/doscript.m +++ b/Mac/PythonLauncher/doscript.m @@ -19,7 +19,7 @@ doscript(const char *command) AEDesc desc; OSStatus err; - [[NSWorkspace sharedWorkspace] launchApplication:@"/Applications/Utilities/Terminal.app/"]; + [[NSWorkspace sharedWorkspace] launchApplication:@"Terminal.app"]; // Build event err = AEBuildAppleEvent(kAECoreSuite, kAEDoScript, diff --git a/Mac/README.rst b/Mac/README.rst index 7476639d0ff..e32566d5475 100644 --- a/Mac/README.rst +++ b/Mac/README.rst @@ -10,6 +10,19 @@ Python on macOS README This document provides a quick overview of some macOS specific features in the Python distribution. +Compilers for building on macOS +=============================== + +The core developers primarily test builds on macOS with Apple's compiler tools, +either Xcode or the Command Line Tools. For these we only support building with +a compiler that includes an SDK that targets the OS on the build machine, that is +the version of Xcode that shipped with the OS version or one newer. + +For example, for macOS 12 we support Xcode 13 and Xcode 14 (or the corresponding +Command Line Tools). + +Building with other compilers, such as GCC, likely works, but is not actively supported. + macOS specific arguments to configure ===================================== @@ -334,9 +347,9 @@ The configure script sometimes emits warnings like the one below:: configure: WARNING: libintl.h: section "Present But Cannot Be Compiled" configure: WARNING: libintl.h: proceeding with the preprocessor's result configure: WARNING: libintl.h: in the future, the compiler will take precedence - configure: WARNING: ## --------------------------------------- ## - configure: WARNING: ## Report this to https://bugs.python.org/ ## - configure: WARNING: ## --------------------------------------- ## + configure: WARNING: ## -------------------------------------------------------- ## + configure: WARNING: ## Report this to https://github.com/python/cpython/issues/ ## + configure: WARNING: ## -------------------------------------------------------- ## This almost always means you are trying to build a universal binary for Python and have libraries in ``/usr/local`` that don't contain the required diff --git a/Mac/Resources/app/Info.plist.in b/Mac/Resources/app/Info.plist.in index 2c801332332..4ec828ff176 100644 --- a/Mac/Resources/app/Info.plist.in +++ b/Mac/Resources/app/Info.plist.in @@ -20,7 +20,7 @@ CFBundleExecutable Python CFBundleGetInfoString - %version%, (c) 2001-2020 Python Software Foundation. + %version%, (c) 2001-2023 Python Software Foundation. CFBundleHelpBookFolder Documentation @@ -37,7 +37,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - %version%, (c) 2001-2021 Python Software Foundation. + %version%, (c) 2001-2023 Python Software Foundation. CFBundleName Python CFBundlePackageType @@ -55,7 +55,7 @@ NSAppleScriptEnabled NSHumanReadableCopyright - (c) 2001-2020 Python Software Foundation. + (c) 2001-2023 Python Software Foundation. NSHighResolutionCapable diff --git a/Mac/Resources/framework/Info.plist.in b/Mac/Resources/framework/Info.plist.in index 863b45238fe..e131c205ef0 100644 --- a/Mac/Resources/framework/Info.plist.in +++ b/Mac/Resources/framework/Info.plist.in @@ -17,9 +17,9 @@ CFBundlePackageType FMWK CFBundleShortVersionString - %VERSION%, (c) 2001-2021 Python Software Foundation. + %VERSION%, (c) 2001-2023 Python Software Foundation. CFBundleLongVersionString - %VERSION%, (c) 2001-2021 Python Software Foundation. + %VERSION%, (c) 2001-2023 Python Software Foundation. CFBundleSignature ???? CFBundleVersion diff --git a/Makefile.pre.in b/Makefile.pre.in index d52f7362079..618bb7b5f73 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -36,10 +36,8 @@ abs_builddir= @abs_builddir@ CC= @CC@ CXX= @CXX@ -MAINCC= @MAINCC@ LINKCC= @LINKCC@ AR= @AR@ -READELF= @READELF@ SOABI= @SOABI@ LDVERSION= @LDVERSION@ LIBPYTHON= @LIBPYTHON@ @@ -55,6 +53,8 @@ DTRACE= @DTRACE@ DFLAGS= @DFLAGS@ DTRACE_HEADERS= @DTRACE_HEADERS@ DTRACE_OBJS= @DTRACE_OBJS@ +DSYMUTIL= @DSYMUTIL@ +DSYMUTIL_PATH= @DSYMUTIL_PATH@ GNULD= @GNULD@ @@ -90,6 +90,9 @@ CONFIGURE_CFLAGS_NODIST=@CFLAGS_NODIST@ # Use it when a linker flag should _not_ be part of the distutils LDFLAGS # once Python is installed (bpo-35257) CONFIGURE_LDFLAGS_NODIST=@LDFLAGS_NODIST@ +# LDFLAGS_NOLTO is an extra flag to disable lto. It is used to speed up building +# of _bootstrap_python and _freeze_module tools, which don't need LTO. +CONFIGURE_LDFLAGS_NOLTO=@LDFLAGS_NOLTO@ CONFIGURE_CPPFLAGS= @CPPFLAGS@ CONFIGURE_LDFLAGS= @LDFLAGS@ # Avoid assigning CFLAGS, LDFLAGS, etc. so users can use them on the @@ -103,6 +106,7 @@ PY_CFLAGS_NODIST=$(CONFIGURE_CFLAGS_NODIST) $(CFLAGS_NODIST) -I$(srcdir)/Include PY_CPPFLAGS= $(BASECPPFLAGS) -I. -I$(srcdir)/Include $(CONFIGURE_CPPFLAGS) $(CPPFLAGS) PY_LDFLAGS= $(CONFIGURE_LDFLAGS) $(LDFLAGS) PY_LDFLAGS_NODIST=$(CONFIGURE_LDFLAGS_NODIST) $(LDFLAGS_NODIST) +PY_LDFLAGS_NOLTO=$(PY_LDFLAGS) $(CONFIGURE_LDFLAGS_NOLTO) $(LDFLAGS_NODIST) NO_AS_NEEDED= @NO_AS_NEEDED@ CCSHARED= @CCSHARED@ # LINKFORSHARED are the flags passed to the $(CC) command that links @@ -146,6 +150,8 @@ CONFINCLUDEDIR= $(exec_prefix)/include PLATLIBDIR= @PLATLIBDIR@ SCRIPTDIR= $(prefix)/$(PLATLIBDIR) ABIFLAGS= @ABIFLAGS@ +# executable name for shebangs +EXENAME= $(BINDIR)/python$(LDVERSION)$(EXE) # Variable used by ensurepip WHEEL_PKG_DIR= @WHEEL_PKG_DIR@ @@ -192,9 +198,6 @@ LIPO_32BIT_FLAGS=@LIPO_32BIT_FLAGS@ # Flags to lipo to produce an intel-64-only universal executable LIPO_INTEL64_FLAGS=@LIPO_INTEL64_FLAGS@ -# Options to enable prebinding (for fast startup prior to Mac OS X 10.3) -OTHER_LIBTOOL_OPT=@OTHER_LIBTOOL_OPT@ - # Environment to run shared python without installed libraries RUNSHARED= @RUNSHARED@ @@ -205,12 +208,6 @@ ENSUREPIP= @ENSUREPIP@ LIBMPDEC_A= Modules/_decimal/libmpdec/libmpdec.a LIBEXPAT_A= Modules/expat/libexpat.a -# OpenSSL options for setup.py so sysconfig can pick up AC_SUBST() vars. -OPENSSL_INCLUDES=@OPENSSL_INCLUDES@ -OPENSSL_LIBS=@OPENSSL_LIBS@ -OPENSSL_LDFLAGS=@OPENSSL_LDFLAGS@ -OPENSSL_RPATH=@OPENSSL_RPATH@ - # Module state, compiler flags and linker flags # Empty CFLAGS and LDFLAGS are omitted. # states: @@ -218,7 +215,7 @@ OPENSSL_RPATH=@OPENSSL_RPATH@ # * missing: build dependency is missing # * disabled: module is disabled # * n/a: module is not available on the current platform -# MODULE_EGG=yes # yes, missing, disabled, n/a +# MODULE_EGG_STATE=yes # yes, missing, disabled, n/a # MODULE_EGG_CFLAGS= # MODULE_EGG_LDFLAGS= @MODULE_BLOCK@ @@ -242,6 +239,10 @@ SRCDIRS= @SRCDIRS@ # Other subdirectories SUBDIRSTOO= Include Lib Misc +# assets for Emscripten browser builds +WASM_ASSETS_DIR=.$(prefix) +WASM_STDLIB=$(WASM_ASSETS_DIR)/lib/python$(VERSION)/os.py + # Files and directories to be distributed CONFIGFILES= configure configure.ac acconfig.h pyconfig.h.in Makefile.pre.in DISTFILES= README.rst ChangeLog $(CONFIGFILES) @@ -257,6 +258,7 @@ DLLLIBRARY= @DLLLIBRARY@ LDLIBRARYDIR= @LDLIBRARYDIR@ INSTSONAME= @INSTSONAME@ LIBRARY_DEPS= @LIBRARY_DEPS@ +LINK_PYTHON_DEPS=@LINK_PYTHON_DEPS@ PY_ENABLE_SHARED= @PY_ENABLE_SHARED@ STATIC_LIBPYTHON= @STATIC_LIBPYTHON@ @@ -275,19 +277,29 @@ LIBOBJS= @LIBOBJS@ PYTHON= python$(EXE) BUILDPYTHON= python$(BUILDEXE) -BOOTSTRAP= _bootstrap_python + +HOSTRUNNER= @HOSTRUNNER@ PYTHON_FOR_REGEN?=@PYTHON_FOR_REGEN@ -UPDATE_FILE=$(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/update_file.py +UPDATE_FILE=$(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/update_file.py PYTHON_FOR_BUILD=@PYTHON_FOR_BUILD@ +# Single-platform builds depend on $(BUILDPYTHON). Cross builds use an +# external "build Python" and have an empty PYTHON_FOR_BUILD_DEPS. +PYTHON_FOR_BUILD_DEPS=@PYTHON_FOR_BUILD_DEPS@ + +# Single-platform builds use Programs/_freeze_module.c for bootstrapping and +# ./_bootstrap_python Programs/_freeze_module.py for remaining modules +# Cross builds use an external "build Python" for all modules. +PYTHON_FOR_FREEZE=@PYTHON_FOR_FREEZE@ +FREEZE_MODULE_BOOTSTRAP=@FREEZE_MODULE_BOOTSTRAP@ +FREEZE_MODULE_BOOTSTRAP_DEPS=@FREEZE_MODULE_BOOTSTRAP_DEPS@ +FREEZE_MODULE=@FREEZE_MODULE@ +FREEZE_MODULE_DEPS=@FREEZE_MODULE_DEPS@ + _PYTHON_HOST_PLATFORM=@_PYTHON_HOST_PLATFORM@ BUILD_GNU_TYPE= @build@ HOST_GNU_TYPE= @host@ -# Tcl and Tk config info from --with-tcltk-includes and -libs options -TCLTK_INCLUDES= @TCLTK_INCLUDES@ -TCLTK_LIBS= @TCLTK_LIBS@ - # The task to run while instrumented when building the profile-opt target. # To speed up profile generation, we don't run the full unit test suite # by default. The default is "-m test --pgo". To run more tests, use @@ -297,7 +309,8 @@ PROFILE_TASK= @PROFILE_TASK@ # report files for gcov / lcov coverage report COVERAGE_INFO= $(abs_builddir)/coverage.info COVERAGE_REPORT=$(abs_builddir)/lcov-report -COVERAGE_REPORT_OPTIONS=--no-branch-coverage --title "CPython lcov report" +COVERAGE_LCOV_OPTIONS=--rc lcov_branch_coverage=1 +COVERAGE_REPORT_OPTIONS=--rc lcov_branch_coverage=1 --branch-coverage --title "CPython $(VERSION) LCOV report [commit $(shell $(GITVERSION))]" # === Definitions added by makesetup === @@ -307,7 +320,6 @@ COVERAGE_REPORT_OPTIONS=--no-branch-coverage --title "CPython lcov report" # Modules MODULE_OBJS= \ Modules/config.o \ - Modules/getpath.o \ Modules/main.o \ Modules/gcmodule.o @@ -322,10 +334,6 @@ IO_OBJS= \ Modules/_io/bytesio.o \ Modules/_io/stringio.o -########################################################################## - -LIBFFI_INCLUDEDIR= @LIBFFI_INCLUDEDIR@ - ########################################################################## # Parser @@ -378,11 +386,13 @@ PYTHON_OBJS= \ Python/getcopyright.o \ Python/getplatform.o \ Python/getversion.o \ + Python/ceval_gil.o \ Python/hamt.o \ Python/hashtable.o \ Python/import.o \ Python/importdl.o \ Python/initconfig.o \ + Python/intrinsics.o \ Python/marshal.o \ Python/modsupport.o \ Python/mysnprintf.o \ @@ -413,17 +423,18 @@ PYTHON_OBJS= \ Python/formatter_unicode.o \ Python/fileutils.o \ Python/suggestions.o \ + Python/perf_trampoline.o \ Python/$(DYNLOADFILE) \ $(LIBOBJS) \ $(MACHDEP_OBJS) \ - $(DTRACE_OBJS) + $(DTRACE_OBJS) \ + @PLATFORM_OBJS@ ########################################################################## # Objects OBJECT_OBJS= \ Objects/abstract.o \ - Objects/accu.o \ Objects/boolobject.o \ Objects/bytes_methods.o \ Objects/bytearrayobject.o \ @@ -465,31 +476,10 @@ OBJECT_OBJS= \ Objects/unicodeobject.o \ Objects/unicodectype.o \ Objects/unionobject.o \ - Objects/weakrefobject.o + Objects/weakrefobject.o \ + @PERF_TRAMPOLINE_OBJ@ -# DEEPFREEZE_OBJS is auto-generated by Tools/scripts/freeze_modules.py. -DEEPFREEZE_OBJS = \ - Python/deepfreeze/importlib._bootstrap.o \ - Python/deepfreeze/importlib._bootstrap_external.o \ - Python/deepfreeze/zipimport.o \ - Python/deepfreeze/abc.o \ - Python/deepfreeze/codecs.o \ - Python/deepfreeze/io.o \ - Python/deepfreeze/_collections_abc.o \ - Python/deepfreeze/_sitebuiltins.o \ - Python/deepfreeze/genericpath.o \ - Python/deepfreeze/ntpath.o \ - Python/deepfreeze/posixpath.o \ - Python/deepfreeze/os.o \ - Python/deepfreeze/site.o \ - Python/deepfreeze/stat.o \ - Python/deepfreeze/__hello__.o \ - Python/deepfreeze/__phello__.o \ - Python/deepfreeze/__phello__.ham.o \ - Python/deepfreeze/__phello__.ham.eggs.o \ - Python/deepfreeze/__phello__.spam.o \ - Python/deepfreeze/frozen_only.o -# End DEEPFREEZE_OBJS +DEEPFREEZE_OBJS = Python/deepfreeze/deepfreeze.o ########################################################################## # objects that get linked into the Python library @@ -504,8 +494,11 @@ LIBRARY_OBJS_OMIT_FROZEN= \ LIBRARY_OBJS= \ $(LIBRARY_OBJS_OMIT_FROZEN) \ $(DEEPFREEZE_OBJS) \ + Modules/getpath.o \ Python/frozen.o +LINK_PYTHON_OBJS=@LINK_PYTHON_OBJS@ + ########################################################################## # DTrace @@ -583,12 +576,17 @@ LIBEXPAT_HEADERS= \ # Default target all: @DEF_MAKE_ALL_RULE@ -build_all: check-clean-src $(BUILDPYTHON) oldsharedmods sharedmods gdbhooks \ - Programs/_testembed python-config +build_all: check-clean-src $(BUILDPYTHON) platform sharedmods \ + gdbhooks Programs/_testembed scripts checksharedmods rundsymutil +build_wasm: check-clean-src $(BUILDPYTHON) platform sharedmods \ + python-config checksharedmods # Check that the source is clean when building out of source. check-clean-src: - @if test -n "$(VPATH)" -a -f "$(srcdir)/Programs/python.o"; then \ + @if test -n "$(VPATH)" -a \( \ + -f "$(srcdir)/Programs/python.o" \ + -o -f "$(srcdir)\Python/frozen_modules/importlib._bootstrap.h" \ + \); then \ echo "Error: The source directory ($(srcdir)) is not clean" ; \ echo "Building Python out of the source tree (in $(abs_builddir)) requires a clean source tree ($(abs_srcdir))" ; \ echo "Try to run: make -C \"$(srcdir)\" clean" ; \ @@ -644,31 +642,39 @@ profile-opt: profile-run-stamp -rm -f profile-clean-stamp $(MAKE) @DEF_MAKE_RULE@ CFLAGS_NODIST="$(CFLAGS_NODIST) $(PGO_PROF_USE_FLAG)" LDFLAGS_NODIST="$(LDFLAGS_NODIST)" +bolt-opt: @PREBOLT_RULE@ + rm -f *.fdata + @LLVM_BOLT@ ./$(BUILDPYTHON) -instrument -instrumentation-file-append-pid -instrumentation-file=$(abspath $(BUILDPYTHON).bolt) -o $(BUILDPYTHON).bolt_inst + ./$(BUILDPYTHON).bolt_inst $(PROFILE_TASK) || true + @MERGE_FDATA@ $(BUILDPYTHON).*.fdata > $(BUILDPYTHON).fdata + @LLVM_BOLT@ ./$(BUILDPYTHON) -o $(BUILDPYTHON).bolt -data=$(BUILDPYTHON).fdata -update-debug-sections -reorder-blocks=ext-tsp -reorder-functions=hfsort+ -split-functions=3 -icf=1 -inline-all -split-eh -reorder-functions-use-hot-size -peepholes=all -jump-tables=aggressive -inline-ap -indirect-call-promotion=all -dyno-stats -use-gnu-stack -frame-opt=hot + rm -f *.fdata + rm -f $(BUILDPYTHON).bolt_inst + mv $(BUILDPYTHON).bolt $(BUILDPYTHON) + # Compile and run with gcov .PHONY=coverage coverage-lcov coverage-report coverage: @echo "Building with support for coverage checking:" $(MAKE) clean - $(MAKE) @DEF_MAKE_RULE@ CFLAGS="$(CFLAGS) -O0 -pg --coverage" LIBS="$(LIBS) --coverage" + $(MAKE) @DEF_MAKE_RULE@ CFLAGS="$(CFLAGS) -O0 -pg --coverage" LDFLAGS="$(LDFLAGS) --coverage" coverage-lcov: @echo "Creating Coverage HTML report with LCOV:" @rm -f $(COVERAGE_INFO) @rm -rf $(COVERAGE_REPORT) - @lcov --capture --directory $(abs_builddir) \ + @lcov $(COVERAGE_LCOV_OPTIONS) --capture \ + --directory $(abs_builddir) \ --base-directory $(realpath $(abs_builddir)) \ --path $(realpath $(abs_srcdir)) \ --output-file $(COVERAGE_INFO) @ # remove 3rd party modules, system headers and internal files with @ # debug, test or dummy functions. - @lcov --remove $(COVERAGE_INFO) \ + @lcov $(COVERAGE_LCOV_OPTIONS) --remove $(COVERAGE_INFO) \ '*/Modules/_blake2/impl/*' \ '*/Modules/_ctypes/libffi*/*' \ '*/Modules/_decimal/libmpdec/*' \ - '*/Modules/_sha3/kcp/*' \ '*/Modules/expat/*' \ - '*/Modules/zlib/*' \ - '*/Include/*' \ '*/Modules/xx*.c' \ '*/Python/pyfpe.c' \ '*/Python/pystrcmp.c' \ @@ -676,7 +682,8 @@ coverage-lcov: '/usr/local/include/*' \ '/usr/lib/gcc/*' \ --output-file $(COVERAGE_INFO) - @genhtml $(COVERAGE_INFO) --output-directory $(COVERAGE_REPORT) \ + @genhtml $(COVERAGE_INFO) \ + --output-directory $(COVERAGE_REPORT) \ $(COVERAGE_REPORT_OPTIONS) @echo @echo "lcov report at $(COVERAGE_REPORT)/index.html" @@ -695,12 +702,13 @@ coverage-report: regen-token regen-frozen .PHONY=clinic clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c $(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py --make --srcdir $(srcdir) + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_global_objects.py # Build the interpreter -$(BUILDPYTHON): Programs/python.o $(LIBRARY_DEPS) - $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) +$(BUILDPYTHON): Programs/python.o $(LINK_PYTHON_DEPS) + $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) -platform: $(BUILDPYTHON) pybuilddir.txt +platform: $(PYTHON_FOR_BUILD_DEPS) pybuilddir.txt $(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print("%s-%d.%d" % (get_platform(), *sys.version_info[:2]))' >platform # Create build directory and generate the sysconfig build-time data there. @@ -710,9 +718,9 @@ platform: $(BUILDPYTHON) pybuilddir.txt # problems by creating a dummy pybuilddir.txt just to allow interpreter # initialization to succeed. It will be overwritten by generate-posix-vars # or removed in case of failure. -pybuilddir.txt: $(BOOTSTRAP) +pybuilddir.txt: $(PYTHON_FOR_BUILD_DEPS) @echo "none" > ./pybuilddir.txt - ./$(BOOTSTRAP) -S -m sysconfig --generate-posix-vars ;\ + $(RUNSHARED) $(PYTHON_FOR_BUILD) -S -m sysconfig --generate-posix-vars ;\ if test $$? -ne 0 ; then \ echo "generate-posix-vars failed" ; \ rm -f ./pybuilddir.txt ; \ @@ -724,24 +732,6 @@ $(srcdir)/Modules/_blake2/blake2s_impl.c: $(srcdir)/Modules/_blake2/blake2b_impl $(PYTHON_FOR_REGEN) $(srcdir)/Modules/_blake2/blake2b2s.py $(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py -f $@ -# Build the shared modules -# Under GNU make, MAKEFLAGS are sorted and normalized; the 's' for -# -s, --silent or --quiet is always the first char. -# Under BSD make, MAKEFLAGS might be " -s -v x=y". -# Ignore macros passed by GNU make, passed after -- -sharedmods: $(BUILDPYTHON) pybuilddir.txt @LIBMPDEC_INTERNAL@ @LIBEXPAT_INTERNAL@ - @case "`echo X $$MAKEFLAGS | sed 's/^X //;s/ -- .*//'`" in \ - *\ -s*|s*) quiet="-q";; \ - *) quiet="";; \ - esac; \ - echo "$(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ - _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ - $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build"; \ - $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ - _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ - $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build - - # Build static library $(LIBRARY): $(LIBRARY_OBJS) -rm -f $@ @@ -811,13 +801,27 @@ $(DLLLIBRARY) libpython$(LDVERSION).dll.a: $(LIBRARY_OBJS) else true; \ fi +# wasm32-emscripten browser build +# wasm assets directory is relative to current build dir, e.g. "./usr/local". +# --preload-file turns a relative asset path into an absolute path. + +.PHONY: wasm_stdlib +wasm_stdlib: $(WASM_STDLIB) +$(WASM_STDLIB): $(srcdir)/Lib/*.py $(srcdir)/Lib/*/*.py \ + $(srcdir)/Tools/wasm/wasm_assets.py \ + Makefile pybuilddir.txt Modules/Setup.local + $(PYTHON_FOR_BUILD) $(srcdir)/Tools/wasm/wasm_assets.py \ + --buildroot . --prefix $(prefix) + +python.html: $(srcdir)/Tools/wasm/python.html python.worker.js + @cp $(srcdir)/Tools/wasm/python.html $@ + +python.worker.js: $(srcdir)/Tools/wasm/python.worker.js + @cp $(srcdir)/Tools/wasm/python.worker.js $@ + ########################################################################## # Build static libmpdec.a -LIBMPDEC_CFLAGS=$(PY_STDMODULE_CFLAGS) $(CCSHARED) @LIBMPDEC_CFLAGS@ - -# for setup.py -DECIMAL_CFLAGS=@LIBMPDEC_CFLAGS@ -DECIMAL_LDFLAGS=@LIBMPDEC_LDFLAGS@ +LIBMPDEC_CFLAGS=@LIBMPDEC_CFLAGS@ $(PY_STDMODULE_CFLAGS) $(CCSHARED) # "%.o: %c" is not portable Modules/_decimal/libmpdec/basearith.o: $(srcdir)/Modules/_decimal/libmpdec/basearith.c $(LIBMPDEC_HEADERS) $(PYTHON_HEADERS) @@ -871,11 +875,7 @@ $(LIBMPDEC_A): $(LIBMPDEC_OBJS) ########################################################################## # Build static libexpat.a -LIBEXPAT_CFLAGS=$(PY_STDMODULE_CFLAGS) $(CCSHARED) @LIBEXPAT_CFLAGS@ - -# for setup.py -EXPAT_CFLAGS=@LIBEXPAT_CFLAGS@ -EXPAT_LDFLAGS=@LIBEXPAT_LDFLAGS@ +LIBEXPAT_CFLAGS=@LIBEXPAT_CFLAGS@ $(PY_STDMODULE_CFLAGS) $(CCSHARED) Modules/expat/xmlparse.o: $(srcdir)/Modules/expat/xmlparse.c $(LIBEXPAT_HEADERS) $(PYTHON_HEADERS) $(CC) -c $(LIBEXPAT_CFLAGS) -o $@ $(srcdir)/Modules/expat/xmlparse.c @@ -893,7 +893,7 @@ $(LIBEXPAT_A): $(LIBEXPAT_OBJS) # create relative links from build/lib.platform/egg.so to Modules/egg.so # pybuilddir.txt is created too late. We cannot use it in Makefile # targets. ln --relative is not portable. -oldsharedmods: $(SHAREDMODS) pybuilddir.txt +sharedmods: $(SHAREDMODS) pybuilddir.txt @target=`cat pybuilddir.txt`; \ $(MKDIR_P) $$target; \ for mod in X $(SHAREDMODS); do \ @@ -902,10 +902,33 @@ oldsharedmods: $(SHAREDMODS) pybuilddir.txt fi; \ done +# dependency on BUILDPYTHON ensures that the target is run last +checksharedmods: sharedmods $(PYTHON_FOR_BUILD_DEPS) $(BUILDPYTHON) + @$(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/Tools/build/check_extension_modules.py + +rundsymutil: sharedmods $(PYTHON_FOR_BUILD_DEPS) $(BUILDPYTHON) + @if [ ! -z $(DSYMUTIL) ] ; then \ + echo $(DSYMUTIL_PATH) $(BUILDPYTHON); \ + $(DSYMUTIL_PATH) $(BUILDPYTHON); \ + if test -f $(LDLIBRARY); then \ + echo $(DSYMUTIL_PATH) $(LDLIBRARY); \ + $(DSYMUTIL_PATH) $(LDLIBRARY); \ + fi; \ + for mod in X $(SHAREDMODS); do \ + if test $$mod != X; then \ + echo $(DSYMUTIL_PATH) $$mod; \ + $(DSYMUTIL_PATH) $$mod; \ + fi; \ + done \ + fi + Modules/Setup.local: @# Create empty Setup.local when file was deleted by user echo "# Edit this file for local setup changes" > $@ +Modules/Setup.bootstrap: $(srcdir)/Modules/Setup.bootstrap.in config.status + ./config.status $@ + Modules/Setup.stdlib: $(srcdir)/Modules/Setup.stdlib.in config.status ./config.status $@ @@ -914,12 +937,13 @@ Makefile Modules/config.c: Makefile.pre \ $(MAKESETUP) \ $(srcdir)/Modules/Setup \ Modules/Setup.local \ - $(srcdir)/Modules/Setup.bootstrap \ + Modules/Setup.bootstrap \ Modules/Setup.stdlib $(SHELL) $(MAKESETUP) -c $(srcdir)/Modules/config.c.in \ -s Modules \ Modules/Setup.local \ - $(srcdir)/Modules/Setup.bootstrap \ + Modules/Setup.stdlib \ + Modules/Setup.bootstrap \ $(srcdir)/Modules/Setup @mv config.c Modules @echo "The Makefile was updated, you may need to re-run make." @@ -931,8 +955,19 @@ regen-test-frozenmain: $(BUILDPYTHON) # using Programs/freeze_test_frozenmain.py $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Programs/freeze_test_frozenmain.py Programs/test_frozenmain.h -Programs/_testembed: Programs/_testembed.o $(LIBRARY_DEPS) - $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) +.PHONY: regen-test-levenshtein +regen-test-levenshtein: + # Regenerate Lib/test/levenshtein_examples.json + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_levenshtein_examples.py $(srcdir)/Lib/test/levenshtein_examples.json + +.PHONY: regen-re +regen-re: $(BUILDPYTHON) + # Regenerate Lib/re/_casefix.py + # using Tools/build/generate_re_casefix.py + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/generate_re_casefix.py $(srcdir)/Lib/re/_casefix.py + +Programs/_testembed: Programs/_testembed.o $(LINK_PYTHON_DEPS) + $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) ############################################################################ # "Bootstrap Python" used to run deepfreeze.py @@ -942,154 +977,41 @@ BOOTSTRAP_HEADERS = \ Python/frozen_modules/importlib._bootstrap_external.h \ Python/frozen_modules/zipimport.h -Python/bootstrap_frozen.o: Python/bootstrap_frozen.c Include/cpython/import.h $(BOOTSTRAP_HEADERS) +Programs/_bootstrap_python.o: Programs/_bootstrap_python.c $(BOOTSTRAP_HEADERS) $(PYTHON_HEADERS) -$(BOOTSTRAP): $(LIBRARY_OBJS_OMIT_FROZEN) \ - Python/bootstrap_frozen.o Programs/python.o - $(LINKCC) $(PY_CORE_LDFLAGS) -o $@ $(LIBRARY_OBJS_OMIT_FROZEN) \ - Python/bootstrap_frozen.o \ - Programs/python.o \ - $(LIBS) $(MODLIBS) $(SYSLIBS) +_bootstrap_python: $(LIBRARY_OBJS_OMIT_FROZEN) Programs/_bootstrap_python.o Modules/getpath.o Modules/Setup.local + $(LINKCC) $(PY_LDFLAGS_NOLTO) -o $@ $(LIBRARY_OBJS_OMIT_FROZEN) \ + Programs/_bootstrap_python.o Modules/getpath.o $(LIBS) $(MODLIBS) $(SYSLIBS) -############################################################################ -# Deepfreeze targets - -.PHONY: regen-deepfreeze -regen-deepfreeze: $(DEEPFREEZE_OBJS) - -DEEPFREEZE_DEPS = \ - $(BOOTSTRAP) \ - pybuilddir.txt \ - $(srcdir)/Tools/scripts/deepfreeze.py - -# BEGIN: deepfreeze modules - -Python/deepfreeze/importlib._bootstrap.c: $(srcdir)/Lib/importlib/_bootstrap.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/importlib._bootstrap.c from Lib/importlib/_bootstrap.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/importlib/_bootstrap.py -m importlib._bootstrap -o Python/deepfreeze/importlib._bootstrap.c - -Python/deepfreeze/importlib._bootstrap_external.c: $(srcdir)/Lib/importlib/_bootstrap_external.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/importlib._bootstrap_external.c from Lib/importlib/_bootstrap_external.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/importlib/_bootstrap_external.py -m importlib._bootstrap_external -o Python/deepfreeze/importlib._bootstrap_external.c - -Python/deepfreeze/zipimport.c: $(srcdir)/Lib/zipimport.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/zipimport.c from Lib/zipimport.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/zipimport.py -m zipimport -o Python/deepfreeze/zipimport.c - -Python/deepfreeze/abc.c: $(srcdir)/Lib/abc.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/abc.c from Lib/abc.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/abc.py -m abc -o Python/deepfreeze/abc.c - -Python/deepfreeze/codecs.c: $(srcdir)/Lib/codecs.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/codecs.c from Lib/codecs.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/codecs.py -m codecs -o Python/deepfreeze/codecs.c - -Python/deepfreeze/io.c: $(srcdir)/Lib/io.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/io.c from Lib/io.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/io.py -m io -o Python/deepfreeze/io.c - -Python/deepfreeze/_collections_abc.c: $(srcdir)/Lib/_collections_abc.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/_collections_abc.c from Lib/_collections_abc.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/_collections_abc.py -m _collections_abc -o Python/deepfreeze/_collections_abc.c - -Python/deepfreeze/_sitebuiltins.c: $(srcdir)/Lib/_sitebuiltins.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/_sitebuiltins.c from Lib/_sitebuiltins.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/_sitebuiltins.py -m _sitebuiltins -o Python/deepfreeze/_sitebuiltins.c - -Python/deepfreeze/genericpath.c: $(srcdir)/Lib/genericpath.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/genericpath.c from Lib/genericpath.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/genericpath.py -m genericpath -o Python/deepfreeze/genericpath.c - -Python/deepfreeze/ntpath.c: $(srcdir)/Lib/ntpath.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/ntpath.c from Lib/ntpath.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/ntpath.py -m ntpath -o Python/deepfreeze/ntpath.c - -Python/deepfreeze/posixpath.c: $(srcdir)/Lib/posixpath.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/posixpath.c from Lib/posixpath.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/posixpath.py -m posixpath -o Python/deepfreeze/posixpath.c - -Python/deepfreeze/os.c: $(srcdir)/Lib/os.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/os.c from Lib/os.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/os.py -m os -o Python/deepfreeze/os.c - -Python/deepfreeze/site.c: $(srcdir)/Lib/site.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/site.c from Lib/site.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/site.py -m site -o Python/deepfreeze/site.c - -Python/deepfreeze/stat.c: $(srcdir)/Lib/stat.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/stat.c from Lib/stat.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/stat.py -m stat -o Python/deepfreeze/stat.c - -Python/deepfreeze/__hello__.c: $(srcdir)/Lib/__hello__.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/__hello__.c from Lib/__hello__.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/__hello__.py -m __hello__ -o Python/deepfreeze/__hello__.c - -Python/deepfreeze/__phello__.c: $(srcdir)/Lib/__phello__/__init__.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/__phello__.c from Lib/__phello__/__init__.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/__phello__/__init__.py -m __phello__ -o Python/deepfreeze/__phello__.c - -Python/deepfreeze/__phello__.ham.c: $(srcdir)/Lib/__phello__/ham/__init__.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/__phello__.ham.c from Lib/__phello__/ham/__init__.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/__phello__/ham/__init__.py -m __phello__.ham -o Python/deepfreeze/__phello__.ham.c - -Python/deepfreeze/__phello__.ham.eggs.c: $(srcdir)/Lib/__phello__/ham/eggs.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/__phello__.ham.eggs.c from Lib/__phello__/ham/eggs.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/__phello__/ham/eggs.py -m __phello__.ham.eggs -o Python/deepfreeze/__phello__.ham.eggs.c - -Python/deepfreeze/__phello__.spam.c: $(srcdir)/Lib/__phello__/spam.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/__phello__.spam.c from Lib/__phello__/spam.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Lib/__phello__/spam.py -m __phello__.spam -o Python/deepfreeze/__phello__.spam.c - -Python/deepfreeze/frozen_only.c: $(srcdir)/Tools/freeze/flag.py $(DEEPFREEZE_DEPS) - @echo "Deepfreezing Python/deepfreeze/frozen_only.c from Tools/freeze/flag.py" - @./$(BOOTSTRAP) \ - $(srcdir)/Tools/scripts/deepfreeze.py \ - $(srcdir)/Tools/freeze/flag.py -m frozen_only -o Python/deepfreeze/frozen_only.c - -# END: deepfreeze modules ############################################################################ # frozen modules (including importlib) +# +# Freezing is a multi step process. It works differently for standard builds +# and cross builds. Standard builds use Programs/_freeze_module and +# _bootstrap_python for freezing and deepfreezing, so users can build Python +# without an existing Python installation. Cross builds cannot execute +# compiled binaries and therefore rely on an external build Python +# interpreter. The build interpreter must have same version and same bytecode +# as the host (target) binary. +# +# Standard build process: +# 1) compile minimal core objects for Py_Compile*() and PyMarshal_Write*(). +# 2) build Programs/_freeze_module binary. +# 3) create frozen module headers for importlib and getpath. +# 4) build _bootstrap_python binary. +# 5) create remaining frozen module headers with +# ``./_bootstrap_python Programs/_freeze_module.py``. The pure Python +# script is used to test the cross compile code path. +# 6) deepfreeze modules with _bootstrap_python +# +# Cross compile process: +# 1) create all frozen module headers with external build Python and +# Programs/_freeze_module.py script. +# 2) deepfreeze modules with external build Python. +# -# FROZEN_FILES_* are auto-generated by Tools/scripts/freeze_modules.py. +# FROZEN_FILES_* are auto-generated by Tools/build/freeze_modules.py. FROZEN_FILES_IN = \ Lib/importlib/_bootstrap.py \ Lib/importlib/_bootstrap_external.py \ @@ -1105,6 +1027,9 @@ FROZEN_FILES_IN = \ Lib/os.py \ Lib/site.py \ Lib/stat.py \ + Lib/importlib/util.py \ + Lib/importlib/machinery.py \ + Lib/runpy.py \ Lib/__hello__.py \ Lib/__phello__/__init__.py \ Lib/__phello__/ham/__init__.py \ @@ -1127,6 +1052,9 @@ FROZEN_FILES_OUT = \ Python/frozen_modules/os.h \ Python/frozen_modules/site.h \ Python/frozen_modules/stat.h \ + Python/frozen_modules/importlib.util.h \ + Python/frozen_modules/importlib.machinery.h \ + Python/frozen_modules/runpy.h \ Python/frozen_modules/__hello__.h \ Python/frozen_modules/__phello__.h \ Python/frozen_modules/__phello__.ham.h \ @@ -1137,98 +1065,170 @@ FROZEN_FILES_OUT = \ Programs/_freeze_module.o: Programs/_freeze_module.c Makefile -Programs/_freeze_module: Programs/_freeze_module.o $(LIBRARY_OBJS_OMIT_FROZEN) - $(LINKCC) $(PY_CORE_LDFLAGS) -o $@ Programs/_freeze_module.o $(LIBRARY_OBJS_OMIT_FROZEN) $(LIBS) $(MODLIBS) $(SYSLIBS) +Modules/getpath_noop.o: $(srcdir)/Modules/getpath_noop.c Makefile + +Programs/_freeze_module: Programs/_freeze_module.o Modules/getpath_noop.o $(LIBRARY_OBJS_OMIT_FROZEN) + $(LINKCC) $(PY_CORE_LDFLAGS) -o $@ Programs/_freeze_module.o Modules/getpath_noop.o $(LIBRARY_OBJS_OMIT_FROZEN) $(LIBS) $(MODLIBS) $(SYSLIBS) + +# We manually freeze getpath.py rather than through freeze_modules +Python/frozen_modules/getpath.h: Modules/getpath.py $(FREEZE_MODULE_BOOTSTRAP_DEPS) + $(FREEZE_MODULE_BOOTSTRAP) getpath $(srcdir)/Modules/getpath.py Python/frozen_modules/getpath.h # BEGIN: freezing modules -Python/frozen_modules/importlib._bootstrap.h: Programs/_freeze_module Lib/importlib/_bootstrap.py - Programs/_freeze_module importlib._bootstrap $(srcdir)/Lib/importlib/_bootstrap.py $(srcdir)/Python/frozen_modules/importlib._bootstrap.h +Python/frozen_modules/importlib._bootstrap.h: Lib/importlib/_bootstrap.py $(FREEZE_MODULE_BOOTSTRAP_DEPS) + $(FREEZE_MODULE_BOOTSTRAP) importlib._bootstrap $(srcdir)/Lib/importlib/_bootstrap.py Python/frozen_modules/importlib._bootstrap.h -Python/frozen_modules/importlib._bootstrap_external.h: Programs/_freeze_module Lib/importlib/_bootstrap_external.py - Programs/_freeze_module importlib._bootstrap_external $(srcdir)/Lib/importlib/_bootstrap_external.py $(srcdir)/Python/frozen_modules/importlib._bootstrap_external.h +Python/frozen_modules/importlib._bootstrap_external.h: Lib/importlib/_bootstrap_external.py $(FREEZE_MODULE_BOOTSTRAP_DEPS) + $(FREEZE_MODULE_BOOTSTRAP) importlib._bootstrap_external $(srcdir)/Lib/importlib/_bootstrap_external.py Python/frozen_modules/importlib._bootstrap_external.h -Python/frozen_modules/zipimport.h: Programs/_freeze_module Lib/zipimport.py - Programs/_freeze_module zipimport $(srcdir)/Lib/zipimport.py $(srcdir)/Python/frozen_modules/zipimport.h +Python/frozen_modules/zipimport.h: Lib/zipimport.py $(FREEZE_MODULE_BOOTSTRAP_DEPS) + $(FREEZE_MODULE_BOOTSTRAP) zipimport $(srcdir)/Lib/zipimport.py Python/frozen_modules/zipimport.h -Python/frozen_modules/abc.h: Programs/_freeze_module Lib/abc.py - Programs/_freeze_module abc $(srcdir)/Lib/abc.py $(srcdir)/Python/frozen_modules/abc.h +Python/frozen_modules/abc.h: Lib/abc.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) abc $(srcdir)/Lib/abc.py Python/frozen_modules/abc.h -Python/frozen_modules/codecs.h: Programs/_freeze_module Lib/codecs.py - Programs/_freeze_module codecs $(srcdir)/Lib/codecs.py $(srcdir)/Python/frozen_modules/codecs.h +Python/frozen_modules/codecs.h: Lib/codecs.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) codecs $(srcdir)/Lib/codecs.py Python/frozen_modules/codecs.h -Python/frozen_modules/io.h: Programs/_freeze_module Lib/io.py - Programs/_freeze_module io $(srcdir)/Lib/io.py $(srcdir)/Python/frozen_modules/io.h +Python/frozen_modules/io.h: Lib/io.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) io $(srcdir)/Lib/io.py Python/frozen_modules/io.h -Python/frozen_modules/_collections_abc.h: Programs/_freeze_module Lib/_collections_abc.py - Programs/_freeze_module _collections_abc $(srcdir)/Lib/_collections_abc.py $(srcdir)/Python/frozen_modules/_collections_abc.h +Python/frozen_modules/_collections_abc.h: Lib/_collections_abc.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) _collections_abc $(srcdir)/Lib/_collections_abc.py Python/frozen_modules/_collections_abc.h -Python/frozen_modules/_sitebuiltins.h: Programs/_freeze_module Lib/_sitebuiltins.py - Programs/_freeze_module _sitebuiltins $(srcdir)/Lib/_sitebuiltins.py $(srcdir)/Python/frozen_modules/_sitebuiltins.h +Python/frozen_modules/_sitebuiltins.h: Lib/_sitebuiltins.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) _sitebuiltins $(srcdir)/Lib/_sitebuiltins.py Python/frozen_modules/_sitebuiltins.h -Python/frozen_modules/genericpath.h: Programs/_freeze_module Lib/genericpath.py - Programs/_freeze_module genericpath $(srcdir)/Lib/genericpath.py $(srcdir)/Python/frozen_modules/genericpath.h +Python/frozen_modules/genericpath.h: Lib/genericpath.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) genericpath $(srcdir)/Lib/genericpath.py Python/frozen_modules/genericpath.h -Python/frozen_modules/ntpath.h: Programs/_freeze_module Lib/ntpath.py - Programs/_freeze_module ntpath $(srcdir)/Lib/ntpath.py $(srcdir)/Python/frozen_modules/ntpath.h +Python/frozen_modules/ntpath.h: Lib/ntpath.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) ntpath $(srcdir)/Lib/ntpath.py Python/frozen_modules/ntpath.h -Python/frozen_modules/posixpath.h: Programs/_freeze_module Lib/posixpath.py - Programs/_freeze_module posixpath $(srcdir)/Lib/posixpath.py $(srcdir)/Python/frozen_modules/posixpath.h +Python/frozen_modules/posixpath.h: Lib/posixpath.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) posixpath $(srcdir)/Lib/posixpath.py Python/frozen_modules/posixpath.h -Python/frozen_modules/os.h: Programs/_freeze_module Lib/os.py - Programs/_freeze_module os $(srcdir)/Lib/os.py $(srcdir)/Python/frozen_modules/os.h +Python/frozen_modules/os.h: Lib/os.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) os $(srcdir)/Lib/os.py Python/frozen_modules/os.h -Python/frozen_modules/site.h: Programs/_freeze_module Lib/site.py - Programs/_freeze_module site $(srcdir)/Lib/site.py $(srcdir)/Python/frozen_modules/site.h +Python/frozen_modules/site.h: Lib/site.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) site $(srcdir)/Lib/site.py Python/frozen_modules/site.h -Python/frozen_modules/stat.h: Programs/_freeze_module Lib/stat.py - Programs/_freeze_module stat $(srcdir)/Lib/stat.py $(srcdir)/Python/frozen_modules/stat.h +Python/frozen_modules/stat.h: Lib/stat.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) stat $(srcdir)/Lib/stat.py Python/frozen_modules/stat.h -Python/frozen_modules/__hello__.h: Programs/_freeze_module Lib/__hello__.py - Programs/_freeze_module __hello__ $(srcdir)/Lib/__hello__.py $(srcdir)/Python/frozen_modules/__hello__.h +Python/frozen_modules/importlib.util.h: Lib/importlib/util.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) importlib.util $(srcdir)/Lib/importlib/util.py Python/frozen_modules/importlib.util.h -Python/frozen_modules/__phello__.h: Programs/_freeze_module Lib/__phello__/__init__.py - Programs/_freeze_module __phello__ $(srcdir)/Lib/__phello__/__init__.py $(srcdir)/Python/frozen_modules/__phello__.h +Python/frozen_modules/importlib.machinery.h: Lib/importlib/machinery.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) importlib.machinery $(srcdir)/Lib/importlib/machinery.py Python/frozen_modules/importlib.machinery.h -Python/frozen_modules/__phello__.ham.h: Programs/_freeze_module Lib/__phello__/ham/__init__.py - Programs/_freeze_module __phello__.ham $(srcdir)/Lib/__phello__/ham/__init__.py $(srcdir)/Python/frozen_modules/__phello__.ham.h +Python/frozen_modules/runpy.h: Lib/runpy.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) runpy $(srcdir)/Lib/runpy.py Python/frozen_modules/runpy.h -Python/frozen_modules/__phello__.ham.eggs.h: Programs/_freeze_module Lib/__phello__/ham/eggs.py - Programs/_freeze_module __phello__.ham.eggs $(srcdir)/Lib/__phello__/ham/eggs.py $(srcdir)/Python/frozen_modules/__phello__.ham.eggs.h +Python/frozen_modules/__hello__.h: Lib/__hello__.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) __hello__ $(srcdir)/Lib/__hello__.py Python/frozen_modules/__hello__.h -Python/frozen_modules/__phello__.spam.h: Programs/_freeze_module Lib/__phello__/spam.py - Programs/_freeze_module __phello__.spam $(srcdir)/Lib/__phello__/spam.py $(srcdir)/Python/frozen_modules/__phello__.spam.h +Python/frozen_modules/__phello__.h: Lib/__phello__/__init__.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) __phello__ $(srcdir)/Lib/__phello__/__init__.py Python/frozen_modules/__phello__.h -Python/frozen_modules/frozen_only.h: Programs/_freeze_module Tools/freeze/flag.py - Programs/_freeze_module frozen_only $(srcdir)/Tools/freeze/flag.py $(srcdir)/Python/frozen_modules/frozen_only.h +Python/frozen_modules/__phello__.ham.h: Lib/__phello__/ham/__init__.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) __phello__.ham $(srcdir)/Lib/__phello__/ham/__init__.py Python/frozen_modules/__phello__.ham.h + +Python/frozen_modules/__phello__.ham.eggs.h: Lib/__phello__/ham/eggs.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) __phello__.ham.eggs $(srcdir)/Lib/__phello__/ham/eggs.py Python/frozen_modules/__phello__.ham.eggs.h + +Python/frozen_modules/__phello__.spam.h: Lib/__phello__/spam.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) __phello__.spam $(srcdir)/Lib/__phello__/spam.py Python/frozen_modules/__phello__.spam.h + +Python/frozen_modules/frozen_only.h: Tools/freeze/flag.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) frozen_only $(srcdir)/Tools/freeze/flag.py Python/frozen_modules/frozen_only.h # END: freezing modules -Tools/scripts/freeze_modules.py: Programs/_freeze_module +Tools/build/freeze_modules.py: $(FREEZE_MODULE) .PHONY: regen-frozen -regen-frozen: Tools/scripts/freeze_modules.py $(FROZEN_FILES_IN) - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/freeze_modules.py +regen-frozen: Tools/build/freeze_modules.py $(FROZEN_FILES_IN) + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/freeze_modules.py @echo "The Makefile was updated, you may need to re-run make." +############################################################################ +# Deepfreeze targets + +.PHONY: regen-deepfreeze +regen-deepfreeze: $(DEEPFREEZE_OBJS) + +DEEPFREEZE_DEPS=$(srcdir)/Tools/build/deepfreeze.py $(FREEZE_MODULE_DEPS) $(FROZEN_FILES_OUT) + +# BEGIN: deepfreeze modules +Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS) + $(PYTHON_FOR_FREEZE) $(srcdir)/Tools/build/deepfreeze.py \ + Python/frozen_modules/importlib._bootstrap.h:importlib._bootstrap \ + Python/frozen_modules/importlib._bootstrap_external.h:importlib._bootstrap_external \ + Python/frozen_modules/zipimport.h:zipimport \ + Python/frozen_modules/abc.h:abc \ + Python/frozen_modules/codecs.h:codecs \ + Python/frozen_modules/io.h:io \ + Python/frozen_modules/_collections_abc.h:_collections_abc \ + Python/frozen_modules/_sitebuiltins.h:_sitebuiltins \ + Python/frozen_modules/genericpath.h:genericpath \ + Python/frozen_modules/ntpath.h:ntpath \ + Python/frozen_modules/posixpath.h:posixpath \ + Python/frozen_modules/os.h:os \ + Python/frozen_modules/site.h:site \ + Python/frozen_modules/stat.h:stat \ + Python/frozen_modules/importlib.util.h:importlib.util \ + Python/frozen_modules/importlib.machinery.h:importlib.machinery \ + Python/frozen_modules/runpy.h:runpy \ + Python/frozen_modules/__hello__.h:__hello__ \ + Python/frozen_modules/__phello__.h:__phello__ \ + Python/frozen_modules/__phello__.ham.h:__phello__.ham \ + Python/frozen_modules/__phello__.ham.eggs.h:__phello__.ham.eggs \ + Python/frozen_modules/__phello__.spam.h:__phello__.spam \ + Python/frozen_modules/frozen_only.h:frozen_only \ + -o Python/deepfreeze/deepfreeze.c +# END: deepfreeze modules + @echo "Note: Deepfreeze may have added some global objects," + @echo " so run 'make regen-global-objects' if necessary." + # We keep this renamed target around for folks with muscle memory. .PHONY: regen-importlib regen-importlib: regen-frozen +############################################################################ +# Global objects + +.PHONY: regen-global-objects +regen-global-objects: $(srcdir)/Tools/build/generate_global_objects.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_global_objects.py + @echo "Note: Global objects can be added or removed by other tools (e.g. deepfreeze), " + @echo " so be sure to re-run regen-global-objects after those tools." + ############################################################################ # ABI +regen-abidump: all + @$(MKDIR_P) $(srcdir)/Doc/data/ + abidw "libpython$(LDVERSION).so" --no-architecture --out-file $(srcdir)/Doc/data/python$(LDVERSION).abi.new + @$(UPDATE_FILE) --create $(srcdir)/Doc/data/python$(LDVERSION).abi $(srcdir)/Doc/data/python$(LDVERSION).abi.new + +check-abidump: all + abidiff $(srcdir)/Doc/data/python$(LDVERSION).abi "libpython$(LDVERSION).so" --drop-private-types --no-architecture --no-added-syms + regen-limited-abi: all - $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/stable_abi.py --generate-all $(srcdir)/Misc/stable_abi.txt + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/stable_abi.py --generate-all $(srcdir)/Misc/stable_abi.toml ############################################################################ # Regenerate all generated files -regen-all: regen-opcode regen-opcode-targets regen-typeslots \ - regen-token regen-ast regen-keyword regen-frozen clinic \ - regen-pegen-metaparser regen-pegen regen-test-frozenmain +regen-all: regen-cases regen-opcode regen-opcode-targets regen-typeslots \ + regen-token regen-ast regen-keyword regen-sre regen-frozen clinic \ + regen-pegen-metaparser regen-pegen regen-test-frozenmain \ + regen-test-levenshtein regen-global-objects @echo - @echo "Note: make regen-stdlib-module-names and autoconf should be run manually" + @echo "Note: make regen-stdlib-module-names and make regen-configure should be run manually" ############################################################################ # Special rules for object files @@ -1246,21 +1246,23 @@ Modules/getbuildinfo.o: $(PARSER_OBJS) \ -DGITBRANCH="\"`LC_ALL=C $(GITBRANCH)`\"" \ -o $@ $(srcdir)/Modules/getbuildinfo.c -Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile +Modules/getpath.o: $(srcdir)/Modules/getpath.c Python/frozen_modules/getpath.h Makefile $(PYTHON_HEADERS) $(CC) -c $(PY_CORE_CFLAGS) -DPYTHONPATH='"$(PYTHONPATH)"' \ -DPREFIX='"$(prefix)"' \ -DEXEC_PREFIX='"$(exec_prefix)"' \ -DVERSION='"$(VERSION)"' \ -DVPATH='"$(VPATH)"' \ + -DPLATLIBDIR='"$(PLATLIBDIR)"' \ + -DPYTHONFRAMEWORK='"$(PYTHONFRAMEWORK)"' \ -o $@ $(srcdir)/Modules/getpath.c Programs/python.o: $(srcdir)/Programs/python.c - $(MAINCC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/python.c + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/python.c Programs/_testembed.o: $(srcdir)/Programs/_testembed.c Programs/test_frozenmain.h - $(MAINCC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/_testembed.c + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/_testembed.c -Modules/_sre.o: $(srcdir)/Modules/_sre.c $(srcdir)/Modules/sre.h $(srcdir)/Modules/sre_constants.h $(srcdir)/Modules/sre_lib.h +Modules/_sre/sre.o: $(srcdir)/Modules/_sre/sre.c $(srcdir)/Modules/_sre/sre.h $(srcdir)/Modules/_sre/sre_constants.h $(srcdir)/Modules/_sre/sre_lib.h Modules/posixmodule.o: $(srcdir)/Modules/posixmodule.c $(srcdir)/Modules/posixmodule.h @@ -1286,11 +1288,6 @@ Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile $(srcdir)/Include/pydt $(MULTIARCH_CPPFLAGS) \ -o $@ $(srcdir)/Python/sysmodule.c -Python/initconfig.o: $(srcdir)/Python/initconfig.c - $(CC) -c $(PY_CORE_CFLAGS) \ - -DPLATLIBDIR='"$(PLATLIBDIR)"' \ - -o $@ $(srcdir)/Python/initconfig.c - $(IO_OBJS): $(IO_H) .PHONY: regen-pegen-metaparser @@ -1332,32 +1329,34 @@ regen-ast: .PHONY: regen-opcode regen-opcode: # Regenerate Include/opcode.h from Lib/opcode.py - # using Tools/scripts/generate_opcode_h.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_opcode_h.py \ + # using Tools/build/generate_opcode_h.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_opcode_h.py \ $(srcdir)/Lib/opcode.py \ - $(srcdir)/Include/opcode.h.new + $(srcdir)/Include/opcode.h.new \ + $(srcdir)/Include/internal/pycore_opcode.h.new $(UPDATE_FILE) $(srcdir)/Include/opcode.h $(srcdir)/Include/opcode.h.new + $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_opcode.h $(srcdir)/Include/internal/pycore_opcode.h.new .PHONY: regen-token regen-token: # Regenerate Doc/library/token-list.inc from Grammar/Tokens - # using Tools/scripts/generate_token.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_token.py rst \ + # using Tools/build/generate_token.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_token.py rst \ $(srcdir)/Grammar/Tokens \ $(srcdir)/Doc/library/token-list.inc - # Regenerate Include/token.h from Grammar/Tokens - # using Tools/scripts/generate_token.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_token.py h \ + # Regenerate Include/internal/pycore_token.h from Grammar/Tokens + # using Tools/build/generate_token.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_token.py h \ $(srcdir)/Grammar/Tokens \ - $(srcdir)/Include/token.h + $(srcdir)/Include/internal/pycore_token.h # Regenerate Parser/token.c from Grammar/Tokens - # using Tools/scripts/generate_token.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_token.py c \ + # using Tools/build/generate_token.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_token.py c \ $(srcdir)/Grammar/Tokens \ $(srcdir)/Parser/token.c # Regenerate Lib/token.py from Grammar/Tokens - # using Tools/scripts/generate_token.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_token.py py \ + # using Tools/build/generate_token.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_token.py py \ $(srcdir)/Grammar/Tokens \ $(srcdir)/Lib/token.py @@ -1372,14 +1371,22 @@ regen-keyword: $(UPDATE_FILE) $(srcdir)/Lib/keyword.py $(srcdir)/Lib/keyword.py.new .PHONY: regen-stdlib-module-names -regen-stdlib-module-names: build_all Programs/_testembed +regen-stdlib-module-names: all Programs/_testembed # Regenerate Python/stdlib_module_names.h - # using Tools/scripts/generate_stdlib_module_names.py + # using Tools/build/generate_stdlib_module_names.py $(RUNSHARED) ./$(BUILDPYTHON) \ - $(srcdir)/Tools/scripts/generate_stdlib_module_names.py \ + $(srcdir)/Tools/build/generate_stdlib_module_names.py \ > $(srcdir)/Python/stdlib_module_names.h.new $(UPDATE_FILE) $(srcdir)/Python/stdlib_module_names.h $(srcdir)/Python/stdlib_module_names.h.new +regen-sre: + # Regenerate Modules/_sre/sre_constants.h and Modules/_sre/sre_targets.h + # from Lib/re/_constants.py using Tools/build/generate_sre_constants.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_sre_constants.py \ + $(srcdir)/Lib/re/_constants.py \ + $(srcdir)/Modules/_sre/sre_constants.h \ + $(srcdir)/Modules/_sre/sre_targets.h + Python/compile.o Python/symtable.o Python/ast_unparse.o Python/ast.o Python/future.o: $(srcdir)/Include/internal/pycore_ast.h Python/getplatform.o: $(srcdir)/Python/getplatform.c @@ -1417,8 +1424,7 @@ UNICODE_DEPS = \ $(srcdir)/Objects/stringlib/ucs2lib.h \ $(srcdir)/Objects/stringlib/ucs4lib.h \ $(srcdir)/Objects/stringlib/undef.h \ - $(srcdir)/Objects/stringlib/unicode_format.h \ - $(srcdir)/Objects/stringlib/unicodedefs.h + $(srcdir)/Objects/stringlib/unicode_format.h Objects/bytes_methods.o: $(srcdir)/Objects/bytes_methods.c $(BYTESTR_DEPS) Objects/bytesobject.o: $(srcdir)/Objects/bytesobject.c $(BYTESTR_DEPS) @@ -1437,8 +1443,32 @@ regen-opcode-targets: $(srcdir)/Python/opcode_targets.h.new $(UPDATE_FILE) $(srcdir)/Python/opcode_targets.h $(srcdir)/Python/opcode_targets.h.new -Python/ceval.o: $(srcdir)/Python/opcode_targets.h $(srcdir)/Python/ceval_gil.h \ - $(srcdir)/Python/condvar.h +.PHONY: regen-cases +regen-cases: + # Regenerate Python/generated_cases.c.h from Python/bytecodes.c + # using Tools/cases_generator/generate_cases.py + PYTHONPATH=$(srcdir)/Tools/cases_generator \ + $(PYTHON_FOR_REGEN) \ + $(srcdir)/Tools/cases_generator/generate_cases.py \ + -i $(srcdir)/Python/bytecodes.c \ + -o $(srcdir)/Python/generated_cases.c.h.new + $(UPDATE_FILE) $(srcdir)/Python/generated_cases.c.h $(srcdir)/Python/generated_cases.c.h.new + # Regenerate Python/opcode_metadata.h from Python/bytecodes.c + # using Tools/cases_generator/generate_cases.py --metadata + PYTHONPATH=$(srcdir)/Tools/cases_generator \ + $(PYTHON_FOR_REGEN) \ + $(srcdir)/Tools/cases_generator/generate_cases.py \ + --metadata \ + -i $(srcdir)/Python/bytecodes.c \ + -o $(srcdir)/Python/opcode_metadata.h.new + $(UPDATE_FILE) $(srcdir)/Python/opcode_metadata.h $(srcdir)/Python/opcode_metadata.h.new + +Python/ceval.o: \ + $(srcdir)/Python/ceval_macros.h \ + $(srcdir)/Python/condvar.h \ + $(srcdir)/Python/generated_cases.c.h \ + $(srcdir)/Python/opcode_metadata.h \ + $(srcdir)/Python/opcode_targets.h Python/frozen.o: $(FROZEN_FILES_OUT) @@ -1481,7 +1511,6 @@ PYTHON_HEADERS= \ $(srcdir)/Include/bytearrayobject.h \ $(srcdir)/Include/bytesobject.h \ $(srcdir)/Include/ceval.h \ - $(srcdir)/Include/code.h \ $(srcdir)/Include/codecs.h \ $(srcdir)/Include/compile.h \ $(srcdir)/Include/complexobject.h \ @@ -1510,6 +1539,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/osdefs.h \ $(srcdir)/Include/osmodule.h \ $(srcdir)/Include/patchlevel.h \ + $(srcdir)/Include/pybuffer.h \ $(srcdir)/Include/pycapsule.h \ $(srcdir)/Include/pydtrace.h \ $(srcdir)/Include/pyerrors.h \ @@ -1522,17 +1552,18 @@ PYTHON_HEADERS= \ $(srcdir)/Include/pymem.h \ $(srcdir)/Include/pyport.h \ $(srcdir)/Include/pystate.h \ + $(srcdir)/Include/pystats.h \ $(srcdir)/Include/pystrcmp.h \ $(srcdir)/Include/pystrtod.h \ $(srcdir)/Include/pythonrun.h \ $(srcdir)/Include/pythread.h \ + $(srcdir)/Include/pytypedefs.h \ $(srcdir)/Include/rangeobject.h \ $(srcdir)/Include/setobject.h \ $(srcdir)/Include/sliceobject.h \ $(srcdir)/Include/structmember.h \ $(srcdir)/Include/structseq.h \ $(srcdir)/Include/sysmodule.h \ - $(srcdir)/Include/token.h \ $(srcdir)/Include/traceback.h \ $(srcdir)/Include/tracemalloc.h \ $(srcdir)/Include/tupleobject.h \ @@ -1551,7 +1582,9 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/classobject.h \ $(srcdir)/Include/cpython/code.h \ $(srcdir)/Include/cpython/compile.h \ + $(srcdir)/Include/cpython/complexobject.h \ $(srcdir)/Include/cpython/context.h \ + $(srcdir)/Include/cpython/descrobject.h \ $(srcdir)/Include/cpython/dictobject.h \ $(srcdir)/Include/cpython/fileobject.h \ $(srcdir)/Include/cpython/fileutils.h \ @@ -1564,20 +1597,26 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/listobject.h \ $(srcdir)/Include/cpython/longintrepr.h \ $(srcdir)/Include/cpython/longobject.h \ + $(srcdir)/Include/cpython/memoryobject.h \ $(srcdir)/Include/cpython/methodobject.h \ + $(srcdir)/Include/cpython/modsupport.h \ $(srcdir)/Include/cpython/object.h \ $(srcdir)/Include/cpython/objimpl.h \ $(srcdir)/Include/cpython/odictobject.h \ $(srcdir)/Include/cpython/picklebufobject.h \ + $(srcdir)/Include/cpython/pthread_stubs.h \ $(srcdir)/Include/cpython/pyctype.h \ $(srcdir)/Include/cpython/pydebug.h \ $(srcdir)/Include/cpython/pyerrors.h \ $(srcdir)/Include/cpython/pyfpe.h \ + $(srcdir)/Include/cpython/pyframe.h \ $(srcdir)/Include/cpython/pylifecycle.h \ $(srcdir)/Include/cpython/pymem.h \ $(srcdir)/Include/cpython/pystate.h \ $(srcdir)/Include/cpython/pythonrun.h \ + $(srcdir)/Include/cpython/pythread.h \ $(srcdir)/Include/cpython/pytime.h \ + $(srcdir)/Include/cpython/setobject.h \ $(srcdir)/Include/cpython/sysmodule.h \ $(srcdir)/Include/cpython/traceback.h \ $(srcdir)/Include/cpython/tupleobject.h \ @@ -1586,7 +1625,6 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/weakrefobject.h \ \ $(srcdir)/Include/internal/pycore_abstract.h \ - $(srcdir)/Include/internal/pycore_accu.h \ $(srcdir)/Include/internal/pycore_asdl.h \ $(srcdir)/Include/internal/pycore_ast.h \ $(srcdir)/Include/internal/pycore_ast_state.h \ @@ -1594,48 +1632,76 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_atomic_funcs.h \ $(srcdir)/Include/internal/pycore_bitutils.h \ $(srcdir)/Include/internal/pycore_bytes_methods.h \ + $(srcdir)/Include/internal/pycore_bytesobject.h \ $(srcdir)/Include/internal/pycore_call.h \ $(srcdir)/Include/internal/pycore_ceval.h \ + $(srcdir)/Include/internal/pycore_ceval_state.h \ $(srcdir)/Include/internal/pycore_code.h \ $(srcdir)/Include/internal/pycore_compile.h \ $(srcdir)/Include/internal/pycore_condvar.h \ $(srcdir)/Include/internal/pycore_context.h \ $(srcdir)/Include/internal/pycore_dict.h \ + $(srcdir)/Include/internal/pycore_dict_state.h \ + $(srcdir)/Include/internal/pycore_descrobject.h \ $(srcdir)/Include/internal/pycore_dtoa.h \ + $(srcdir)/Include/internal/pycore_exceptions.h \ + $(srcdir)/Include/internal/pycore_faulthandler.h \ $(srcdir)/Include/internal/pycore_fileutils.h \ $(srcdir)/Include/internal/pycore_floatobject.h \ $(srcdir)/Include/internal/pycore_format.h \ + $(srcdir)/Include/internal/pycore_frame.h \ + $(srcdir)/Include/internal/pycore_function.h \ + $(srcdir)/Include/internal/pycore_genobject.h \ $(srcdir)/Include/internal/pycore_getopt.h \ $(srcdir)/Include/internal/pycore_gil.h \ + $(srcdir)/Include/internal/pycore_global_objects.h \ + $(srcdir)/Include/internal/pycore_global_objects_fini_generated.h \ $(srcdir)/Include/internal/pycore_hamt.h \ $(srcdir)/Include/internal/pycore_hashtable.h \ $(srcdir)/Include/internal/pycore_import.h \ $(srcdir)/Include/internal/pycore_initconfig.h \ $(srcdir)/Include/internal/pycore_interp.h \ $(srcdir)/Include/internal/pycore_interpreteridobject.h \ + $(srcdir)/Include/internal/pycore_intrinsics.h \ $(srcdir)/Include/internal/pycore_list.h \ $(srcdir)/Include/internal/pycore_long.h \ $(srcdir)/Include/internal/pycore_moduleobject.h \ $(srcdir)/Include/internal/pycore_namespace.h \ $(srcdir)/Include/internal/pycore_object.h \ + $(srcdir)/Include/internal/pycore_obmalloc.h \ + $(srcdir)/Include/internal/pycore_obmalloc_init.h \ $(srcdir)/Include/internal/pycore_pathconfig.h \ $(srcdir)/Include/internal/pycore_pyarena.h \ $(srcdir)/Include/internal/pycore_pyerrors.h \ $(srcdir)/Include/internal/pycore_pyhash.h \ $(srcdir)/Include/internal/pycore_pylifecycle.h \ $(srcdir)/Include/internal/pycore_pymem.h \ + $(srcdir)/Include/internal/pycore_pymem_init.h \ $(srcdir)/Include/internal/pycore_pystate.h \ + $(srcdir)/Include/internal/pycore_pythread.h \ + $(srcdir)/Include/internal/pycore_range.h \ $(srcdir)/Include/internal/pycore_runtime.h \ + $(srcdir)/Include/internal/pycore_runtime_init_generated.h \ + $(srcdir)/Include/internal/pycore_runtime_init.h \ + $(srcdir)/Include/internal/pycore_signal.h \ + $(srcdir)/Include/internal/pycore_sliceobject.h \ $(srcdir)/Include/internal/pycore_strhex.h \ $(srcdir)/Include/internal/pycore_structseq.h \ $(srcdir)/Include/internal/pycore_symtable.h \ $(srcdir)/Include/internal/pycore_sysmodule.h \ + $(srcdir)/Include/internal/pycore_time.h \ + $(srcdir)/Include/internal/pycore_token.h \ $(srcdir)/Include/internal/pycore_traceback.h \ + $(srcdir)/Include/internal/pycore_tracemalloc.h \ $(srcdir)/Include/internal/pycore_tuple.h \ + $(srcdir)/Include/internal/pycore_typeobject.h \ $(srcdir)/Include/internal/pycore_ucnhash.h \ $(srcdir)/Include/internal/pycore_unionobject.h \ + $(srcdir)/Include/internal/pycore_unicodeobject.h \ + $(srcdir)/Include/internal/pycore_unicodeobject_generated.h \ $(srcdir)/Include/internal/pycore_warnings.h \ $(DTRACE_HEADERS) \ + @PLATFORM_HEADERS@ \ \ $(srcdir)/Python/stdlib_module_names.h @@ -1645,7 +1711,7 @@ $(LIBRARY_OBJS) $(MODOBJS) Programs/python.o: $(PYTHON_HEADERS) ###################################################################### TESTOPTS= $(EXTRATESTOPTS) -TESTPYTHON= $(RUNSHARED) ./$(BUILDPYTHON) $(TESTPYTHONOPTS) +TESTPYTHON= $(RUNSHARED) $(PYTHON_FOR_BUILD) $(TESTPYTHONOPTS) TESTRUNNER= $(TESTPYTHON) $(srcdir)/Tools/scripts/run_tests.py TESTTIMEOUT= 1200 @@ -1653,12 +1719,12 @@ TESTTIMEOUT= 1200 # Remove "test_python_*" directories of previous failed test jobs. # Pass TESTOPTS options because it can contain --tempdir option. -cleantest: build_all +cleantest: all $(TESTRUNNER) $(TESTOPTS) --cleanup # Run a basic set of regression tests. # This excludes some tests that are particularly resource-intensive. -test: @DEF_MAKE_RULE@ platform +test: all $(TESTRUNNER) $(TESTOPTS) # Run the full test suite twice - once without .pyc files, and once with. @@ -1668,7 +1734,7 @@ test: @DEF_MAKE_RULE@ platform # the bytecode read from a .pyc file had the bug, sometimes the directly # generated bytecode. This is sometimes a very shy bug needing a lot of # sample data. -testall: @DEF_MAKE_RULE@ platform +testall: all -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f $(TESTPYTHON) -E $(srcdir)/Lib/compileall.py -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f @@ -1677,7 +1743,7 @@ testall: @DEF_MAKE_RULE@ platform # Run the test suite for both architectures in a Universal build on OSX. # Must be run on an Intel box. -testuniversal: @DEF_MAKE_RULE@ platform +testuniversal: all @if [ `arch` != 'i386' ]; then \ echo "This can only be used on OSX/i386" ;\ exit 1 ;\ @@ -1688,14 +1754,18 @@ testuniversal: @DEF_MAKE_RULE@ platform # Like testall, but with only one pass and without multiple processes. # Run an optional script to include information about the build environment. -buildbottest: build_all platform +buildbottest: all -@if which pybuildbot.identify >/dev/null 2>&1; then \ pybuildbot.identify "CC='$(CC)'" "CXX='$(CXX)'"; \ fi $(TESTRUNNER) -j 1 -u all -W --slowest --fail-env-changed --timeout=$(TESTTIMEOUT) $(TESTOPTS) -pythoninfo: build_all - $(RUNSHARED) ./$(BUILDPYTHON) -m test.pythoninfo +# Like testall, but run Python tests with HOSTRUNNER directly. +hostrunnertest: all + $(RUNSHARED) $(HOSTRUNNER) ./$(BUILDPYTHON) -m test -u all $(TESTOPTS) + +pythoninfo: all + $(RUNSHARED) $(HOSTRUNNER) ./$(BUILDPYTHON) -m test.pythoninfo QUICKTESTOPTS= $(TESTOPTS) -x test_subprocess test_io test_lib2to3 \ test_multibytecodec test_urllib2_localnet test_itertools \ @@ -1703,17 +1773,21 @@ QUICKTESTOPTS= $(TESTOPTS) -x test_subprocess test_io test_lib2to3 \ test_multiprocessing_forkserver \ test_mailbox test_nntplib test_socket test_poll \ test_select test_zipfile test_concurrent_futures -quicktest: @DEF_MAKE_RULE@ platform +quicktest: all $(TESTRUNNER) $(QUICKTESTOPTS) # SSL tests .PHONY: multisslcompile multissltest -multisslcompile: build_all +multisslcompile: all $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/ssl/multissltests.py --steps=modules -multissltest: build_all +multissltest: all $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/ssl/multissltests.py +# All install targets use the "all" target as synchronization point to +# prevent race conditions with PGO builds. PGO builds use recursive make, +# which can lead to two parallel `./python setup.py build` processes that +# step on each others toes. install: @FRAMEWORKINSTALLFIRST@ commoninstall bininstall maninstall @FRAMEWORKINSTALLLAST@ if test "x$(ENSUREPIP)" != "xno" ; then \ case $(ENSUREPIP) in \ @@ -1736,20 +1810,25 @@ altinstall: commoninstall commoninstall: check-clean-src @FRAMEWORKALTINSTALLFIRST@ \ altbininstall libinstall inclinstall libainstall \ - sharedinstall oldsharedinstall altmaninstall \ + sharedinstall altmaninstall \ @FRAMEWORKALTINSTALLLAST@ # Install shared libraries enabled by Setup DESTDIRS= $(exec_prefix) $(LIBDIR) $(BINLIBDEST) $(DESTSHARED) -oldsharedinstall: $(DESTSHARED) $(SHAREDMODS) +sharedinstall: $(DESTSHARED) all @for i in X $(SHAREDMODS); do \ if test $$i != X; then \ echo $(INSTALL_SHARED) $$i $(DESTSHARED)/`basename $$i`; \ $(INSTALL_SHARED) $$i $(DESTDIR)$(DESTSHARED)/`basename $$i`; \ + if test -d "$$i.dSYM"; then \ + echo $(DSYMUTIL_PATH) $(DESTDIR)$(DESTSHARED)/`basename $$i`; \ + $(DSYMUTIL_PATH) $(DESTDIR)$(DESTSHARED)/`basename $$i`; \ + fi; \ fi; \ done + $(DESTSHARED): @for i in $(DESTDIRS); \ do \ @@ -1810,6 +1889,23 @@ altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@ -output $(DESTDIR)$(BINDIR)/python$(VERSION)-intel64$(EXE) \ $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE); \ fi + # Install macOS debug information (if available) + if test -d "$(BUILDPYTHON).dSYM"; then \ + echo $(DSYMUTIL_PATH) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \ + $(DSYMUTIL_PATH) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \ + fi + if test "$(PYTHONFRAMEWORKDIR)" = "no-framework" ; then \ + if test -d "$(LDLIBRARY).dSYM"; then \ + echo $(DSYMUTIL_PATH) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \ + $(DSYMUTIL_PATH) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \ + fi \ + else \ + if test -d "$(LDLIBRARY).dSYM"; then \ + echo $(DSYMUTIL_PATH) $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(INSTSONAME); \ + $(DSYMUTIL_PATH) $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(INSTSONAME); \ + fi \ + fi + bininstall: altbininstall if test ! -d $(DESTDIR)$(LIBPC); then \ @@ -1877,22 +1973,23 @@ LIBSUBDIRS= asyncio \ ctypes ctypes/macholib \ curses \ dbm \ - distutils distutils/command \ email email/mime \ encodings \ ensurepip ensurepip/_bundled \ html \ http \ idlelib idlelib/Icons \ - importlib importlib/metadata \ + importlib importlib/resources importlib/metadata \ json \ lib2to3 lib2to3/fixes lib2to3/pgen2 \ logging \ multiprocessing multiprocessing/dummy \ pydoc_data \ + re \ site-packages \ sqlite3 \ tkinter \ + tomllib \ turtledemo \ unittest \ urllib \ @@ -1900,15 +1997,10 @@ LIBSUBDIRS= asyncio \ wsgiref \ $(XMLLIBSUBDIRS) \ xmlrpc \ + zipfile \ zoneinfo \ __phello__ -TESTSUBDIRS= ctypes/test \ - distutils/tests \ - idlelib/idle_test \ - lib2to3/tests \ - lib2to3/tests/data \ - lib2to3/tests/data/fixers \ - lib2to3/tests/data/fixers/myfixes \ +TESTSUBDIRS= idlelib/idle_test \ test test/audiodata \ test/capath test/cjkencodings \ test/data test/decimaltestdata \ @@ -1917,6 +2009,7 @@ TESTSUBDIRS= ctypes/test \ test/libregrtest test/sndhdrdata \ test/subprocessdata test/support \ test/test_asyncio \ + test/test_ctypes \ test/test_email test/test_email/data \ test/test_import \ test/test_import/data \ @@ -1930,15 +2023,6 @@ TESTSUBDIRS= ctypes/test \ test/test_importlib \ test/test_importlib/builtin \ test/test_importlib/data \ - test/test_importlib/data01 \ - test/test_importlib/data01/subdirectory \ - test/test_importlib/data02 \ - test/test_importlib/data02/one \ - test/test_importlib/data02/two \ - test/test_importlib/data03 \ - test/test_importlib/data03/namespace \ - test/test_importlib/data03/namespace/portion1 \ - test/test_importlib/data03/namespace/portion2 \ test/test_importlib/extension \ test/test_importlib/frozen \ test/test_importlib/import_ \ @@ -1962,26 +2046,43 @@ TESTSUBDIRS= ctypes/test \ test/test_importlib/namespace_pkgs/project3 \ test/test_importlib/namespace_pkgs/project3/parent \ test/test_importlib/namespace_pkgs/project3/parent/child \ - test/test_importlib/namespacedata01 \ test/test_importlib/partial \ test/test_importlib/resources \ + test/test_importlib/resources/data01 \ + test/test_importlib/resources/data01/subdirectory \ + test/test_importlib/resources/data02 \ + test/test_importlib/resources/data02/one \ + test/test_importlib/resources/data02/two \ + test/test_importlib/resources/data03 \ + test/test_importlib/resources/data03/namespace \ + test/test_importlib/resources/data03/namespace/portion1 \ + test/test_importlib/resources/data03/namespace/portion2 \ + test/test_importlib/resources/namespacedata01 \ + test/test_importlib/resources/zipdata01 \ + test/test_importlib/resources/zipdata02 \ test/test_importlib/source \ - test/test_importlib/zipdata01 \ - test/test_importlib/zipdata02 \ test/test_json \ + test/test_lib2to3 \ + test/test_lib2to3/data \ + test/test_lib2to3/data/fixers \ + test/test_lib2to3/data/fixers/myfixes \ test/test_peg_generator \ + test/test_tkinter \ test/test_tools \ + test/test_ttk \ test/test_warnings test/test_warnings/data \ + test/test_zipfile \ test/test_zoneinfo test/test_zoneinfo/data \ + test/test_unittest test/test_unittest/testmock \ test/tracedmodules \ + test/typinganndata \ test/xmltestdata test/xmltestdata/c14n-20 \ - test/ziptestdata \ - tkinter/test tkinter/test/test_tkinter \ - tkinter/test/test_ttk \ - unittest/test unittest/test/testmock + test/ziptestdata + +COMPILEALL_OPTS=-j0 TEST_MODULES=@TEST_MODULES@ -libinstall: build_all $(srcdir)/Modules/xxmodule.c +libinstall: all $(srcdir)/Modules/xxmodule.c @for i in $(SCRIPTDIR) $(LIBDEST); \ do \ if test ! -d $(DESTDIR)$$i; then \ @@ -2049,36 +2150,15 @@ libinstall: build_all $(srcdir)/Modules/xxmodule.c $(INSTALL_DATA) `cat pybuilddir.txt`/_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).py \ $(DESTDIR)$(LIBDEST); \ $(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt - if test -d $(DESTDIR)$(LIBDEST)/distutils/tests; then \ - $(INSTALL_DATA) $(srcdir)/Modules/xxmodule.c \ - $(DESTDIR)$(LIBDEST)/distutils/tests ; \ - fi - -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ + @ # Build PYC files for the 3 optimization levels (0, 1, 2) + -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ $(PYTHON_FOR_BUILD) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \ - -j0 -d $(LIBDEST) -f \ - -x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \ - $(DESTDIR)$(LIBDEST) - -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ - $(PYTHON_FOR_BUILD) -Wi -O $(DESTDIR)$(LIBDEST)/compileall.py \ - -j0 -d $(LIBDEST) -f \ - -x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \ - $(DESTDIR)$(LIBDEST) - -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ - $(PYTHON_FOR_BUILD) -Wi -OO $(DESTDIR)$(LIBDEST)/compileall.py \ - -j0 -d $(LIBDEST) -f \ - -x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \ + -o 0 -o 1 -o 2 $(COMPILEALL_OPTS) -d $(LIBDEST) -f \ + -x 'bad_coding|badsyntax|site-packages|test/test_lib2to3/data' \ $(DESTDIR)$(LIBDEST) -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ $(PYTHON_FOR_BUILD) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \ - -j0 -d $(LIBDEST)/site-packages -f \ - -x badsyntax $(DESTDIR)$(LIBDEST)/site-packages - -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ - $(PYTHON_FOR_BUILD) -Wi -O $(DESTDIR)$(LIBDEST)/compileall.py \ - -j0 -d $(LIBDEST)/site-packages -f \ - -x badsyntax $(DESTDIR)$(LIBDEST)/site-packages - -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ - $(PYTHON_FOR_BUILD) -Wi -OO $(DESTDIR)$(LIBDEST)/compileall.py \ - -j0 -d $(LIBDEST)/site-packages -f \ + -o 0 -o 1 -o 2 $(COMPILEALL_OPTS) -d $(LIBDEST)/site-packages -f \ -x badsyntax $(DESTDIR)$(LIBDEST)/site-packages -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ $(PYTHON_FOR_BUILD) -m lib2to3.pgen2.driver $(DESTDIR)$(LIBDEST)/lib2to3/Grammar.txt @@ -2090,7 +2170,7 @@ libinstall: build_all $(srcdir)/Modules/xxmodule.c python-config: $(srcdir)/Misc/python-config.in Misc/python-config.sh @ # Substitution happens here, as the completely-expanded BINDIR @ # is not available in configure - sed -e "s,@EXENAME@,$(BINDIR)/python$(LDVERSION)$(EXE)," < $(srcdir)/Misc/python-config.in >python-config.py + sed -e "s,@EXENAME@,$(EXENAME)," < $(srcdir)/Misc/python-config.in >python-config.py @ # Replace makefile compat. variable references with shell script compat. ones; $(VAR) -> ${VAR} LC_ALL=C sed -e 's,\$$(\([A-Za-z0-9_]*\)),\$$\{\1\},g' < Misc/python-config.sh >python-config @ # On Darwin, always use the python version of the script, the shell @@ -2100,6 +2180,29 @@ python-config: $(srcdir)/Misc/python-config.in Misc/python-config.sh cp python-config.py python-config; \ fi +# macOS' make seems to ignore a dependency on a +# "$(BUILD_SCRIPTS_DIR): $(MKDIR_P) $@" rule. +BUILD_SCRIPTS_DIR=build/scripts-$(VERSION) +SCRIPT_2TO3=$(BUILD_SCRIPTS_DIR)/2to3-$(VERSION) +SCRIPT_IDLE=$(BUILD_SCRIPTS_DIR)/idle$(VERSION) +SCRIPT_PYDOC=$(BUILD_SCRIPTS_DIR)/pydoc$(VERSION) + +$(SCRIPT_2TO3): $(srcdir)/Tools/scripts/2to3 + @$(MKDIR_P) $(BUILD_SCRIPTS_DIR) + sed -e "s,/usr/bin/env python3,$(EXENAME)," < $(srcdir)/Tools/scripts/2to3 > $@ + @chmod +x $@ + +$(SCRIPT_IDLE): $(srcdir)/Tools/scripts/idle3 + @$(MKDIR_P) $(BUILD_SCRIPTS_DIR) + sed -e "s,/usr/bin/env python3,$(EXENAME)," < $(srcdir)/Tools/scripts/idle3 > $@ + @chmod +x $@ + +$(SCRIPT_PYDOC): $(srcdir)/Tools/scripts/pydoc3 + @$(MKDIR_P) $(BUILD_SCRIPTS_DIR) + sed -e "s,/usr/bin/env python3,$(EXENAME)," < $(srcdir)/Tools/scripts/pydoc3 > $@ + @chmod +x $@ + +scripts: $(SCRIPT_2TO3) $(SCRIPT_IDLE) $(SCRIPT_PYDOC) python-config # Install the include files INCLDIRSTOMAKE=$(INCLUDEDIR) $(CONFINCLUDEDIR) $(INCLUDEPY) $(CONFINCLUDEPY) @@ -2146,7 +2249,7 @@ LIBPL= @LIBPL@ # pkgconfig directory LIBPC= $(LIBDIR)/pkgconfig -libainstall: @DEF_MAKE_RULE@ python-config +libainstall: all scripts @for i in $(LIBDIR) $(LIBPL) $(LIBPC) $(BINDIR); \ do \ if test ! -d $(DESTDIR)$$i; then \ @@ -2173,7 +2276,7 @@ libainstall: @DEF_MAKE_RULE@ python-config $(INSTALL_DATA) $(srcdir)/Modules/config.c.in $(DESTDIR)$(LIBPL)/config.c.in $(INSTALL_DATA) Makefile $(DESTDIR)$(LIBPL)/Makefile $(INSTALL_DATA) $(srcdir)/Modules/Setup $(DESTDIR)$(LIBPL)/Setup - $(INSTALL_DATA) $(srcdir)/Modules/Setup.bootstrap $(DESTDIR)$(LIBPL)/Setup.bootstrap + $(INSTALL_DATA) Modules/Setup.bootstrap $(DESTDIR)$(LIBPL)/Setup.bootstrap $(INSTALL_DATA) Modules/Setup.stdlib $(DESTDIR)$(LIBPL)/Setup.stdlib $(INSTALL_DATA) Modules/Setup.local $(DESTDIR)$(LIBPL)/Setup.local $(INSTALL_DATA) Misc/python.pc $(DESTDIR)$(LIBPC)/python-$(VERSION).pc @@ -2182,6 +2285,9 @@ libainstall: @DEF_MAKE_RULE@ python-config $(INSTALL_SCRIPT) $(srcdir)/install-sh $(DESTDIR)$(LIBPL)/install-sh $(INSTALL_SCRIPT) python-config.py $(DESTDIR)$(LIBPL)/python-config.py $(INSTALL_SCRIPT) python-config $(DESTDIR)$(BINDIR)/python$(LDVERSION)-config + $(INSTALL_SCRIPT) $(SCRIPT_2TO3) $(DESTDIR)$(BINDIR)/2to3-$(VERSION) + $(INSTALL_SCRIPT) $(SCRIPT_IDLE) $(DESTDIR)$(BINDIR)/idle$(VERSION) + $(INSTALL_SCRIPT) $(SCRIPT_PYDOC) $(DESTDIR)$(BINDIR)/pydoc$(VERSION) @if [ -s Modules/python.exp -a \ "`echo $(MACHDEP) | sed 's/^\(...\).*/\1/'`" = "aix" ]; then \ echo; echo "Installing support files for building shared extension modules on AIX:"; \ @@ -2198,17 +2304,6 @@ libainstall: @DEF_MAKE_RULE@ python-config else true; \ fi -# Install the dynamically loadable modules -# This goes into $(exec_prefix) -sharedinstall: sharedmods - $(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/setup.py install \ - --prefix=$(prefix) \ - --install-scripts=$(BINDIR) \ - --install-platlib=$(DESTSHARED) \ - --root=$(DESTDIR)/ - -rm $(DESTDIR)$(DESTSHARED)/_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).py - -rm -r $(DESTDIR)$(DESTSHARED)/__pycache__ - # Here are a couple of targets for MacOSX again, to install a full # framework-based Python. frameworkinstall installs everything, the # subtargets install specific parts. Much of the actual work is offloaded to @@ -2293,6 +2388,9 @@ config.status: $(srcdir)/configure .PRECIOUS: config.status $(BUILDPYTHON) Makefile Makefile.pre +Python/asm_trampoline.o: $(srcdir)/Python/asm_trampoline.S + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $< + # Some make's put the object file in the current directory .c.o: $(CC) -c $(PY_CORE_CFLAGS) -o $@ $< @@ -2306,7 +2404,7 @@ Python/dtoa.o: Python/dtoa.c # Run reindent on the library reindent: - ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/reindent.py -r $(srcdir)/Lib + ./$(BUILDPYTHON) $(srcdir)/Tools/patchcheck/reindent.py -r $(srcdir)/Lib # Rerun configure with the same options as it was run last time, # provided the config.status script exists @@ -2317,10 +2415,16 @@ recheck: # Regenerate configure and pyconfig.h.in .PHONY: autoconf autoconf: - # Regenerate the configure script from configure.ac using autoconf - (cd $(srcdir); autoconf -Wall) - # Regenerate pyconfig.h.in from configure.ac using autoheader - (cd $(srcdir); autoheader -Wall) + (cd $(srcdir); autoreconf -ivf -Werror) + +.PHONY: regen-configure +regen-configure: + @if command -v podman >/dev/null; then RUNTIME="podman"; else RUNTIME="docker"; fi; \ + if ! command -v $$RUNTIME; then echo "$@ needs either Podman or Docker container runtime." >&2; exit 1; fi; \ + if command -v selinuxenabled >/dev/null && selinuxenabled; then OPT=":Z"; fi; \ + CMD="$$RUNTIME run --rm --pull=always -v $(abs_srcdir):/src$$OPT quay.io/tiran/cpython_autoconf:269"; \ + echo $$CMD; \ + $$CMD || exit $? # Create a tags file for vi tags:: @@ -2352,8 +2456,7 @@ rmtestturds: -rm -f gb-18030-2000.xml docclean: - -rm -rf Doc/build - -rm -rf Doc/tools/sphinx Doc/tools/pygments Doc/tools/docutils + $(MAKE) -C $(srcdir)/Doc clean # like the 'clean' target but retain the profile guided optimization (PGO) # data. The PGO data is only valid if source code remains unchanged. @@ -2361,14 +2464,21 @@ clean-retain-profile: pycremoval find . -name '*.[oa]' -exec rm -f {} ';' find . -name '*.s[ol]' -exec rm -f {} ';' find . -name '*.so.[0-9]*.[0-9]*' -exec rm -f {} ';' + find . -name '*.lto' -exec rm -f {} ';' + find . -name '*.wasm' -exec rm -f {} ';' find . -name '*.lst' -exec rm -f {} ';' find build -name 'fficonfig.h' -exec rm -f {} ';' || true find build -name '*.py' -exec rm -f {} ';' || true find build -name '*.py[co]' -exec rm -f {} ';' || true -rm -f pybuilddir.txt -rm -f Lib/lib2to3/*Grammar*.pickle - -rm -f Programs/_testembed Programs/_freeze_module $(BOOTSTRAP) + -rm -f _bootstrap_python + -rm -f python.html python*.js python.data python*.symbols python*.map + -rm -f $(WASM_STDLIB) + -rm -f Programs/_testembed Programs/_freeze_module -rm -f Python/deepfreeze/*.[co] + -rm -f Python/frozen_modules/*.h + -rm -f Python/frozen_modules/MANIFEST -find build -type f -a ! -name '*.gc??' -exec rm -f {} ';' -rm -f Include/pydtrace_probes.h -rm -f profile-gen-stamp @@ -2398,16 +2508,15 @@ clobber: clean # Make things extra clean, before making a distribution: # remove all generated files, even Makefile[.pre] # Keep configure and Python-ast.[ch], it's possible they can't be generated -distclean: clobber +distclean: clobber docclean for file in $(srcdir)/Lib/test/data/* ; do \ if test "$$file" != "$(srcdir)/Lib/test/data/README"; then rm "$$file"; fi; \ done -rm -f core Makefile Makefile.pre config.status Modules/Setup.local \ - Modules/Setup.stdlib Modules/ld_so_aix Modules/python.exp Misc/python.pc \ + Modules/Setup.bootstrap Modules/Setup.stdlib \ + Modules/ld_so_aix Modules/python.exp Misc/python.pc \ Misc/python-embed.pc Misc/python-config.sh -rm -f python*-gdb.py - -rm -f Python/frozen_modules/*.h - -rm -f Python/frozen_modules/MANIFEST # Issue #28258: set LC_ALL to avoid issues with Estonian locale. # Expansion is performed here by shell (spawned by make) itself before # arguments are passed to find. So LC_ALL=C must be set as a separate @@ -2419,8 +2528,8 @@ distclean: clobber -exec rm -f {} ';' # Check that all symbols exported by libpython start with "Py" or "_Py" -smelly: @DEF_MAKE_RULE@ - $(RUNSHARED) ./$(BUILDPYTHON) Tools/scripts/smelly.py +smelly: all + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/smelly.py # Find files with funny names funny: @@ -2454,49 +2563,61 @@ funny: -o -print # Perform some verification checks on any modified files. -patchcheck: @DEF_MAKE_RULE@ - $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/patchcheck.py +patchcheck: all + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/patchcheck/patchcheck.py check-limited-abi: all - $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/stable_abi.py --all $(srcdir)/Misc/stable_abi.txt + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/stable_abi.py --all $(srcdir)/Misc/stable_abi.toml + +.PHONY: update-config +update-config: + curl -sL -o config.guess 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' + curl -sL -o config.sub 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' + chmod +x config.guess config.sub # Dependencies Python/thread.o: @THREADHEADERS@ $(srcdir)/Python/condvar.h # Declare targets that aren't real files -.PHONY: all build_all sharedmods check-clean-src oldsharedmods test quicktest -.PHONY: install altinstall oldsharedinstall bininstall altbininstall -.PHONY: maninstall libinstall inclinstall libainstall sharedinstall +.PHONY: all build_all build_wasm check-clean-src +.PHONY: sharedmods checksharedmods test quicktest rundsymutil +.PHONY: install altinstall sharedinstall bininstall altbininstall +.PHONY: maninstall libinstall inclinstall libainstall .PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure .PHONY: frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools .PHONY: frameworkaltinstallunixtools recheck clean clobber distclean .PHONY: smelly funny patchcheck touch altmaninstall commoninstall .PHONY: clean-retain-profile profile-removal run_profile_task .PHONY: build_all_generate_profile build_all_merge_profile -.PHONY: gdbhooks +.PHONY: gdbhooks scripts ########################################################################## -# Module dependencies +# Module dependencies and platform-specific files + +# force rebuild when header file or module build flavor (static/shared) is changed +MODULE_DEPS_STATIC=Modules/config.c +MODULE_DEPS_SHARED=$(MODULE_DEPS_STATIC) $(EXPORTSYMS) MODULE_CMATH_DEPS=$(srcdir)/Modules/_math.h MODULE_MATH_DEPS=$(srcdir)/Modules/_math.h -MODULE_PYEXPAT_DEPS=$(LIBEXPAT_HEADERS) @LIBEXPAT_INTERNAL@ +MODULE_PYEXPAT_DEPS=@LIBEXPAT_INTERNAL@ MODULE_UNICODEDATA_DEPS=$(srcdir)/Modules/unicodedata_db.h $(srcdir)/Modules/unicodename_db.h -MODULE__BLAKE2_DEPS=$(srcdir)/Modules/_blake2/impl/blake2-config.h $(srcdir)/Modules/_blake2/impl/blake2-dispatch.c $(srcdir)/Modules/_blake2/impl/blake2-impl.h $(srcdir)/Modules/_blake2/impl/blake2-kat.h $(srcdir)/Modules/_blake2/impl/blake2.h $(srcdir)/Modules/_blake2/impl/blake2b-load-sse2.h $(srcdir)/Modules/_blake2/impl/blake2b-load-sse41.h $(srcdir)/Modules/_blake2/impl/blake2b-ref.c $(srcdir)/Modules/_blake2/impl/blake2b-round.h $(srcdir)/Modules/_blake2/impl/blake2b-test.c $(srcdir)/Modules/_blake2/impl/blake2b.c $(srcdir)/Modules/_blake2/impl/blake2bp-test.c $(srcdir)/Modules/_blake2/impl/blake2bp.c $(srcdir)/Modules/_blake2/impl/blake2s-load-sse2.h $(srcdir)/Modules/_blake2/impl/blake2s-load-sse41.h $(srcdir)/Modules/_blake2/impl/blake2s-load-xop.h $(srcdir)/Modules/_blake2/impl/blake2s-ref.c $(srcdir)/Modules/_blake2/impl/blake2s-round.h $(srcdir)/Modules/_blake2/impl/blake2s-test.c $(srcdir)/Modules/_blake2/impl/blake2s.c $(srcdir)/Modules/_blake2/impl/blake2sp-test.c $(srcdir)/Modules/_blake2/impl/blake2sp.c $(srcdir)/Modules/hashlib.h +MODULE__BLAKE2_DEPS=$(srcdir)/Modules/_blake2/impl/blake2-config.h $(srcdir)/Modules/_blake2/impl/blake2-impl.h $(srcdir)/Modules/_blake2/impl/blake2.h $(srcdir)/Modules/_blake2/impl/blake2b-load-sse2.h $(srcdir)/Modules/_blake2/impl/blake2b-load-sse41.h $(srcdir)/Modules/_blake2/impl/blake2b-ref.c $(srcdir)/Modules/_blake2/impl/blake2b-round.h $(srcdir)/Modules/_blake2/impl/blake2b.c $(srcdir)/Modules/_blake2/impl/blake2s-load-sse2.h $(srcdir)/Modules/_blake2/impl/blake2s-load-sse41.h $(srcdir)/Modules/_blake2/impl/blake2s-load-xop.h $(srcdir)/Modules/_blake2/impl/blake2s-ref.c $(srcdir)/Modules/_blake2/impl/blake2s-round.h $(srcdir)/Modules/_blake2/impl/blake2s.c $(srcdir)/Modules/_blake2/blake2module.h $(srcdir)/Modules/hashlib.h MODULE__CTYPES_DEPS=$(srcdir)/Modules/_ctypes/ctypes.h -MODULE__DECIMAL_DEPS=$(srcdir)/Modules/_decimal/docstrings.h $(LIBMPDEC_HEADERS) @LIBMPDEC_INTERNAL@ -MODULE__ELEMENTTREE_DEPS=$(srcdir)/Modules/pyexpat.c $(LIBEXPAT_HEADERS) @LIBEXPAT_INTERNAL@ +MODULE__CTYPES_MALLOC_CLOSURE=@MODULE__CTYPES_MALLOC_CLOSURE@ +MODULE__DECIMAL_DEPS=$(srcdir)/Modules/_decimal/docstrings.h @LIBMPDEC_INTERNAL@ +MODULE__ELEMENTTREE_DEPS=$(srcdir)/Modules/pyexpat.c @LIBEXPAT_INTERNAL@ MODULE__HASHLIB_DEPS=$(srcdir)/Modules/hashlib.h MODULE__IO_DEPS=$(srcdir)/Modules/_io/_iomodule.h MODULE__MD5_DEPS=$(srcdir)/Modules/hashlib.h MODULE__SHA1_DEPS=$(srcdir)/Modules/hashlib.h MODULE__SHA256_DEPS=$(srcdir)/Modules/hashlib.h -MODULE__SHA3_DEPS=$(srcdir)/Modules/_sha3/kcp/KeccakHash.c $(srcdir)/Modules/_sha3/kcp/KeccakHash.h $(srcdir)/Modules/_sha3/kcp/KeccakP-1600-64.macros $(srcdir)/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h $(srcdir)/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h $(srcdir)/Modules/_sha3/kcp/KeccakP-1600-SnP.h $(srcdir)/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c $(srcdir)/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h $(srcdir)/Modules/_sha3/kcp/KeccakP-1600-opt64.c $(srcdir)/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros $(srcdir)/Modules/_sha3/kcp/KeccakSponge.c $(srcdir)/Modules/_sha3/kcp/KeccakSponge.h $(srcdir)/Modules/_sha3/kcp/KeccakSponge.inc $(srcdir)/Modules/_sha3/kcp/PlSnP-Fallback.inc $(srcdir)/Modules/_sha3/kcp/SnP-Relaned.h $(srcdir)/Modules/_sha3/kcp/align.h $(srcdir)/Modules/hashlib.h +MODULE__SHA3_DEPS=$(srcdir)/Modules/_sha3/sha3.c $(srcdir)/Modules/_sha3/sha3.h $(srcdir)/Modules/hashlib.h MODULE__SHA512_DEPS=$(srcdir)/Modules/hashlib.h -MODULE__SOCKET_DEPS=$(srcdir)/Modules/socketmodule.h +MODULE__SOCKET_DEPS=$(srcdir)/Modules/socketmodule.h $(srcdir)/Modules/addrinfo.h $(srcdir)/Modules/getaddrinfo.c $(srcdir)/Modules/getnameinfo.c MODULE__SSL_DEPS=$(srcdir)/Modules/_ssl.h $(srcdir)/Modules/_ssl/cert.c $(srcdir)/Modules/_ssl/debughelpers.c $(srcdir)/Modules/_ssl/misc.c $(srcdir)/Modules/_ssl_data.h $(srcdir)/Modules/_ssl_data_111.h $(srcdir)/Modules/_ssl_data_300.h $(srcdir)/Modules/socketmodule.h -MODULE__TESTCAPI_DEPS=$(srcdir)/Modules/testcapi_long.h +MODULE__TESTCAPI_DEPS=$(srcdir)/Modules/_testcapi/testcapi_long.h $(srcdir)/Modules/_testcapi/parts.h MODULE__SQLITE3_DEPS=$(srcdir)/Modules/_sqlite/connection.h $(srcdir)/Modules/_sqlite/cursor.h $(srcdir)/Modules/_sqlite/microprotocols.h $(srcdir)/Modules/_sqlite/module.h $(srcdir)/Modules/_sqlite/prepare_protocol.h $(srcdir)/Modules/_sqlite/row.h $(srcdir)/Modules/_sqlite/util.h # IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/Misc/ACKS b/Misc/ACKS index 204293fa50d..74abcebe21e 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -190,6 +190,7 @@ Paul Boddie Matthew Boedicker Robin Boerdijk Andra Bogildea +Matt Bogosian Nikolay Bogoychev David Bolen Wouter Bolsterlee @@ -197,6 +198,7 @@ Gawain Bolton Carl Friedrich Bolz-Tereick Forest Bond Gregory Bond +David Bonner Angelin Booz Médéric Boquien Matias Bordese @@ -295,6 +297,7 @@ Michael Cetrulo Dave Chambers Pascal Chambon Nicholas Chammas +Ofey Chan John Chandler Hye-Shik Chang Jeffrey Chang @@ -312,6 +315,7 @@ Nicolas Chauvat Jerry Chen Michael Chermside Ingrid Cheung +Adam Chhina Terry Chia Albert Chin-A-Young Adal Chiriliuc @@ -341,6 +345,7 @@ Hervé Coatanhay Riccardo Coccioli Nick Coghlan Josh Cogliati +Noam Cohen Dave Cole Terrence Cole Benjamin Collar @@ -400,6 +405,7 @@ Lars Damerow Evan Dandrea Eric Daniel Scott David Daniels +Derzsi Dániel Lawrence D'Anna Ben Darnell Kushal Das @@ -428,6 +434,7 @@ Caleb Deveraux Catherine Devlin Scott Dial Alon Diamant +Lital Natan Toby Dickenson Mark Dickinson Jack Diederich @@ -513,6 +520,7 @@ Daniel Evers evilzero Winston Ewert Greg Ewing +Sam Ezeh Martijn Faassen Clovis Fabricio Andreas Faerber @@ -544,6 +552,7 @@ Nils Fischbeck Frederik Fix Tom Flanagan Matt Fleming +Sean Fleming Hernán Martínez Foffani Benjamin Fogle Artem Fokin @@ -603,6 +612,7 @@ Marius Gedminas Jan-Philip Gehrcke Thomas Gellekum Gabriel Genellina +Philip Georgi Christos Georgiou Elazar (×לעזר) Gershuni Ben Gertzfield @@ -631,11 +641,13 @@ Tiago Gonçalves Chris Gonnerman Shelley Gooch David Goodger +MichaÅ‚ Górny Elliot Gorokhovsky Hans de Graaff Tim Graham Kim Gräsman Alex Grönholm +Thomas Grainger Nathaniel Gray Eddy De Greef Duane Griffin @@ -679,6 +691,7 @@ Anders Hammarquist Mark Hammond Harald Hanche-Olsen Manus Hand +Andreas Hangauer Milton L. Hankins Carl Bordum Hansen Stephen Hansen @@ -735,6 +748,7 @@ Aaron Hill Joel Hillacre Richie Hindle Konrad Hinsen +Richard Hoberecht David Hobley Tim Hochberg Benjamin Hodgson @@ -748,6 +762,7 @@ Albert Hofkamp Chris Hogan Tomas Hoger Jonathan Hogg +Vladyslav Hoi Kamilla Holanda Steve Holden Akintayo Holder @@ -820,6 +835,7 @@ Ben Jackson Paul Jackson Manuel Jacob David Jacobs +Jeffrey C. Jacobs Kevin Jacobs Kjetil Jacobsen Shantanu Jain @@ -909,6 +925,7 @@ Sanyam Khurana Tyler Kieft Mads Kiilerich Jason Killen +Derek D. Kim Jan Kim Taek Joo Kim Sam Kimbrel @@ -926,6 +943,7 @@ Ron Klatchko Reid Kleckner Carsten Klein Bastian Kleineidam +Joel Klimont Bob Kline Matthias Klose Jeremy Kloth @@ -981,9 +999,11 @@ Toshio Kuratomi Ilia Kurenkov Vladimir Kushnir Erno Kuusela +Kabir Kwatra Ross Lagerwall Cameron Laird Loïc Lajeanne +Alexander Lakeev David Lam Thomas Lamb Valerie Lambert @@ -1034,7 +1054,7 @@ Robert Lehmann Petri Lehtinen Luke Kenneth Casson Leighton John Leitch -Tshepang Lekhonkhobe +Tshepang Mbambo Marc-André Lemburg Mateusz Lenik John Lenton @@ -1053,6 +1073,7 @@ Robert Li Xuanji Li Zekun Li Zheao Li +Eli Libman Dan Lidral-Porter Robert van Liere Ross Light @@ -1117,6 +1138,7 @@ Vincent Marchetti David Marek Doug Marien Sven Marnach +John Marshall Alex Martelli Dennis MÃ¥rtensson Anthony Martin @@ -1164,6 +1186,7 @@ Dimitri Merejkowsky Brian Merrell Bruce Merry Alexis Métaireau +Carey Metcalfe Luke Mewburn Carl Meyer Kyle Meyer @@ -1191,9 +1214,11 @@ Julien Miotte Andrii V. Mishkovskyi Dom Mitchell Dustin J. Mitchell +Gideon Mitchell Tim Mitchell Zubin Mithra Florian Mladitsch +Kevin Modzelewski Doug Moen Jakub Molinski Juliette Monsel @@ -1216,6 +1241,7 @@ Alessandro Moura Pablo Mouzo Mher Movsisyan Ruslan Mstoi +Marc Mueller Valentina Mukhamedzhanova Michael Mulich Sape Mullender @@ -1289,6 +1315,7 @@ Ken Jin Ooi Piet van Oostrum Tomas Oppelstrup Jason Orendorff +Yan "yyyyyyyan" Orestes Bastien Orivel orlnub123 Douglas Orr @@ -1297,6 +1324,7 @@ Michele Orrù Tomáš Orsava Oleg Oshmyan Denis Osipov +Itamar Ostricher Denis S. Otkidach Peter Otten Michael Otteneder @@ -1329,6 +1357,7 @@ William Park Claude Paroz Heikki Partanen Harri Pasanen +Jeremiah Gabriel Pascual Gaël Pasgrimaud Feanil Patel Ashish Nitin Patil @@ -1397,6 +1426,7 @@ John Popplewell Matheus Vieira Portela Davin Potts Guillaume Pratte +Pedro Pregueiro Florian Preinstorfer Alex Prengère Amrit Prem @@ -1415,10 +1445,12 @@ Pierre Quentel Brian Quinlan Anders Qvist Thomas Rachel +Domenico Ragusa Ram Rachum Jeffrey Rackauckas Jérôme Radix Burton Radons +Kirill (python273) R. Abhilash Raj Shorya Raj Ajith Ramachandran @@ -1439,6 +1471,7 @@ Edward K. Ream Chris Rebert Marc Recht John Redford +Kalyan Reddy Terry J. Reedy Gareth Rees John Reese @@ -1533,6 +1566,7 @@ Patrick Sabin Sébastien Sablé Amit Saha Suman Saha +Koki Saito Hajime Saitou George Sakkis Victor Salgado @@ -1571,6 +1605,7 @@ Ed Schouten Scott Schram Robin Schreiber Chad J. Schroeder +Simon-Martin Schroeder Christian Schubert Sam Schulenburg Andreas Schwab @@ -1597,6 +1632,7 @@ Silas Sewell Ian Seyer Dmitry Shachnev Anish Shah +Jaineel Shah Daniel Shahaf Hui Shang Geoff Shannon @@ -1672,6 +1708,7 @@ Evgeny Sologubov Cody Somerville Anthony Sottile Edoardo Spadolini +Tom Sparrow Geoffrey Spear Clay Spence Stefan Sperling @@ -1693,6 +1730,7 @@ Anthony Starks David Steele Oliver Steele Greg Stein +Itai Steinherz Marek Stepniowski Baruch Sterin Chris Stern @@ -1871,9 +1909,12 @@ Wojtek Walczak Charles Waldman Richard Walker Larry Wall +Jacob Walls Kevin Walzer Rodrigo Steinmuller Wanderley Dingyuan Wang +Edward C Wang +Jiahua Wang Ke Wang Liang-Bo Wang Greg Ward @@ -1886,6 +1927,7 @@ Colin Watson David Watson Aaron Watters Alex Waygood +Russel Webber Henrik Weber Leon Weber Steve Weber @@ -1956,6 +1998,7 @@ Gordon Worley Darren Worrall Thomas Wouters Daniel Wozniak +Simon Wrede Marcin Niemira Wei Wu Heiko Wundram @@ -1963,10 +2006,12 @@ Doug Wyatt Xiang Zhang Robert Xiao Florent Xicluna +Xinhang Xu Arnon Yaari Alakshendra Yadav Hirokazu Yamamoto Masayuki Yamamoto +Jingchen Ye Ka-Ping Yee Chi Hsuan Yen Jason Yeo @@ -1982,6 +2027,8 @@ Masazumi Yoshikawa Arnaud Ysmal Bernard Yue Moshe Zadka +Bader Zaidan +Yair Zak Elias Zamaria Milan Zamazal Artur Zaprzala @@ -1994,6 +2041,7 @@ Yuxiao Zeng Uwe Zessin Cheng Zhang George Zhang +Charlie Zhao Kai Zhu Tarek Ziadé Jelle Zijlstra diff --git a/Misc/HISTORY b/Misc/HISTORY index 570638869f9..e66b695f21c 100644 --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -19610,7 +19610,7 @@ durable way. For example, some people say they're confused by that the Open Source Initiative's entry for the Python Software Foundation License:: - http://www.opensource.org/licenses/PythonSoftFoundation.php + https://opensource.org/licenses/PythonSoftFoundation.php says "Python 2.1.1" all over it, wondering whether it applies only to Python 2.1.1. @@ -21790,7 +21790,7 @@ Library x == y is False, and x != y is True. This is akin to the change made for mixed-type comparisons of datetime objects in 2.3a2; more info about the rationale is in the NEWS entry for that. See also SF bug - report . + report . - On Unix platforms, if os.listdir() is called with a Unicode argument, it now returns Unicode strings. (This behavior was added earlier @@ -22025,7 +22025,7 @@ Extension modules now. today() and now() now round system timestamps to the closest - microsecond . This repairs an + microsecond . This repairs an irritation most likely seen on Windows systems. In dt.astimezone(tz), if tz.utcoffset(dt) returns a duration, @@ -22080,7 +22080,7 @@ Extension modules datetime.fromtimestamp(): Like datetime.now() above, this had less than useful behavior when the optional tinzo argument was specified. See - also SF bug report . + also SF bug report . date and datetime comparison: In order to prevent comparison from falling back to the default compare-object-addresses strategy, these @@ -22139,10 +22139,10 @@ Library dependent path modules (e.g. ntpath.py) rather than os.py, so these variables are now available via os.path. They continue to be available from the os module. - (see ). + (see ). - array.array was added to the types repr.py knows about (see - ). + ). - The new pickletools.py contains lots of documentation about pickle internals, and supplies some helpers for working with pickles, such as @@ -22527,7 +22527,7 @@ Core and builtins potential drawback is that list.sort() may require temp space of len(list)*2 bytes (``*4`` on a 64-bit machine). It's therefore possible for list.sort() to raise MemoryError now, even if a comparison function - does not. See for full details. + does not. See for full details. - All standard iterators now ensure that, once StopIteration has been raised, all future calls to next() on the same iterator will also diff --git a/Misc/NEWS.d/3.10.0a1.rst b/Misc/NEWS.d/3.10.0a1.rst index 1c1c2d54e8c..47181166264 100644 --- a/Misc/NEWS.d/3.10.0a1.rst +++ b/Misc/NEWS.d/3.10.0a1.rst @@ -2204,7 +2204,7 @@ Handle cases where the ``end_lineno`` is ``None`` on .. nonce: zwl5Hc .. section: Library -:mod:`distutils` upload creates SHA2-256 and Blake2b-256 digests. MD5 +``distutils`` upload creates SHA2-256 and Blake2b-256 digests. MD5 digests is skipped if platform blocks MD5. .. diff --git a/Misc/NEWS.d/3.10.0a3.rst b/Misc/NEWS.d/3.10.0a3.rst index 4f182e8e3f1..699a0dd9e8d 100644 --- a/Misc/NEWS.d/3.10.0a3.rst +++ b/Misc/NEWS.d/3.10.0a3.rst @@ -763,7 +763,7 @@ as a positional-only argument. .. nonce: qLkNh8 .. section: Library -Enum: fix regression involving inheriting a multiply-inherited enum +Enum: fix regression involving inheriting a multiply inherited enum .. diff --git a/Misc/NEWS.d/3.10.0a4.rst b/Misc/NEWS.d/3.10.0a4.rst index beac530fcb2..95f9319668d 100644 --- a/Misc/NEWS.d/3.10.0a4.rst +++ b/Misc/NEWS.d/3.10.0a4.rst @@ -446,7 +446,7 @@ In ``importlib.metadata``: - ``EntryPoint`` objects now expose a ``.dist`` object referencing the ``Distribution`` when constructed from a ``Distribution``. - Add support for package discovery under package normalization rules. - The object returned by ``metadata()`` now has a -formally-defined protocol called ``PackageMetadata`` with declared support +formally defined protocol called ``PackageMetadata`` with declared support for the ``.get_all()`` method. - Synced with importlib_metadata 3.3. .. diff --git a/Misc/NEWS.d/3.10.0a6.rst b/Misc/NEWS.d/3.10.0a6.rst index a4ee9ae098b..803df6f51ce 100644 --- a/Misc/NEWS.d/3.10.0a6.rst +++ b/Misc/NEWS.d/3.10.0a6.rst @@ -232,7 +232,7 @@ now result in :exc:`MemoryError`. Patch by Erlend E. Aasland. .. section: Library Fix segfault in :meth:`sqlite3.Connection.backup` if no argument was -provided. The regression was introduced by GH-23838. Patch by Erlend E. +provided. The regression was introduced by PR 23838. Patch by Erlend E. Aasland. .. diff --git a/Misc/NEWS.d/3.10.0a7.rst b/Misc/NEWS.d/3.10.0a7.rst index aa332631292..286d0a8a7e9 100644 --- a/Misc/NEWS.d/3.10.0a7.rst +++ b/Misc/NEWS.d/3.10.0a7.rst @@ -574,7 +574,7 @@ raised. Patch by Erlend E. Aasland. .. nonce: t9XEkQ .. section: Library -Fix a regression introduced in GH-24562, where an empty bytestring was +Fix a regression introduced in PR 24562, where an empty bytestring was fetched as ``None`` instead of ``b''`` in :mod:`sqlite3`. Patch by Mariusz Felisiak. @@ -855,7 +855,7 @@ Aasland. .. nonce: iIeiLg .. section: IDLE -Document that IDLE can fail on Unix either from misconfigured IP masquerage +Document that IDLE can fail on Unix either from misconfigured IP masquerade rules or failure displaying complex colored (non-ascii) characters. .. diff --git a/Misc/NEWS.d/3.10.0b1.rst b/Misc/NEWS.d/3.10.0b1.rst index e4391a1ee38..f29fc6632db 100644 --- a/Misc/NEWS.d/3.10.0b1.rst +++ b/Misc/NEWS.d/3.10.0b1.rst @@ -941,7 +941,7 @@ result from ``entry_points()`` as deprecated. .. -.. bpo: 47383 +.. gh: 47383 .. date: 2021-04-08-19-32-26 .. nonce: YI1hdL .. section: Library @@ -1001,7 +1001,7 @@ some :mod:`dataclasses`. Fix :mod:`sqlite3` regression for zero-sized blobs with converters, where ``b""`` was returned instead of ``None``. The regression was introduced by -GH-24723. Patch by Erlend E. Aasland. +PR 24723. Patch by Erlend E. Aasland. .. @@ -1142,7 +1142,7 @@ name>`` instead of ``SQL logic error``. Patch by Erlend E. Aasland. .. nonce: GK9a0l .. section: Library -Install schemes in :mod:`distutils.command.install` are now loaded from +Install schemes in ``distutils.command.install`` are now loaded from :mod:`sysconfig`. .. @@ -1152,7 +1152,7 @@ Install schemes in :mod:`distutils.command.install` are now loaded from .. nonce: SenEje .. section: Library -:mod:`distutils.sysconfig` has been merged to :mod:`sysconfig`. +``distutils.sysconfig`` has been merged to :mod:`sysconfig`. .. @@ -1673,7 +1673,8 @@ zips together prompts from the sidebar with lines from the selected text. .. nonce: 3EFl1H .. section: IDLE -Fix reference leak in test_squeezer. Patch by Pablo Galindo +Fix reference leak in test_sidebar and test_squeezer. +Patches by Terry Jan Reedy and Pablo Galindo .. diff --git a/Misc/NEWS.d/3.11.0a1.rst b/Misc/NEWS.d/3.11.0a1.rst index 28b81b75266..7670e482ede 100644 --- a/Misc/NEWS.d/3.11.0a1.rst +++ b/Misc/NEWS.d/3.11.0a1.rst @@ -1140,7 +1140,7 @@ blocks. Patch by Pablo Galindo. Constructors of subclasses of some builtin classes (e.g. :class:`tuple`, :class:`list`, :class:`frozenset`) no longer accept arbitrary keyword -arguments. Subclass of :class:`set` can now define a ``__new__()`` method +arguments. [reverted in 3.11a4] Subclass of :class:`set` can now define a ``__new__()`` method with additional keyword parameters without overriding also ``__init__()``. .. @@ -1445,7 +1445,7 @@ asynchronous. .. nonce: NOwcDJ .. section: Library -Fix clang rpath issue in :mod:`distutils`. The UnixCCompiler now uses +Fix clang rpath issue in ``distutils``. The UnixCCompiler now uses correct clang option to add a runtime library directory (rpath) to a shared library. @@ -1597,7 +1597,7 @@ use map function instead of genexpr in capwords. .. section: Library Fix typo: ``importlib.find_loader`` is really slated for removal in Python -3.12 not 3.10, like the others in GH-25169. +3.12 not 3.10, like the others in PR 25169. Patch by Hugo van Kemenade. @@ -2798,7 +2798,7 @@ documentation for deprecations. .. nonce: rvyf2v .. section: Library -Restore back :func:`parse_makefile` in :mod:`distutils.sysconfig` because it +Restore back :func:`parse_makefile` in ``distutils.sysconfig`` because it behaves differently than the similar implementation in :mod:`sysconfig`. .. diff --git a/Misc/NEWS.d/3.11.0a2.rst b/Misc/NEWS.d/3.11.0a2.rst index 1f742a29ebc..225bd61e90d 100644 --- a/Misc/NEWS.d/3.11.0a2.rst +++ b/Misc/NEWS.d/3.11.0a2.rst @@ -618,7 +618,7 @@ Removed from the :mod:`inspect` module: use the :func:`inspect.signature` function and :class:`Signature` object directly. -* the undocumented ``Signature.from_callable`` and ``Signature.from_function`` +* the undocumented ``Signature.from_builtin`` and ``Signature.from_function`` functions, deprecated since Python 3.5; use the :meth:`Signature.from_callable() ` method instead. @@ -702,16 +702,6 @@ details. Patch by Jochem Schulenklopper. .. -.. bpo: 10572 -.. date: 2021-01-07-01-25-38 -.. nonce: gEEZ9z -.. section: Library - -Move :mod:`sqlite3` tests to ``/Lib/test/test_sqlite3``. Patch by Erlend E. -Aasland. - -.. - .. bpo: 41374 .. date: 2020-07-27-19-21-05 .. nonce: cd-kFL @@ -956,6 +946,16 @@ use a stricter regular expression. Patch by Victor Stinner. .. +.. bpo: 10572 +.. date: 2021-01-07-01-25-38 +.. nonce: gEEZ9z +.. section: Tests + +Rename :mod:`sqlite3` tests from ``test_sqlite`` to ``test_sqlite3``, and +relocate them to ``Lib/test/test_sqlite3``. Patch by Erlend E. Aasland. + +.. + .. bpo: 43158 .. date: 2021-11-01-12-51-46 .. nonce: fghS6w diff --git a/Misc/NEWS.d/3.11.0a3.rst b/Misc/NEWS.d/3.11.0a3.rst new file mode 100644 index 00000000000..42653190499 --- /dev/null +++ b/Misc/NEWS.d/3.11.0a3.rst @@ -0,0 +1,1277 @@ +.. bpo: 46009 +.. date: 2021-12-08-11-06-53 +.. nonce: cL8pH0 +.. release date: 2021-12-08 +.. section: Core and Builtins + +Restore behavior from 3.9 and earlier when sending non-None to newly started +generator. In 3.9 this did not affect the state of the generator. In 3.10.0 +and 3.10.1 ``gen_func().send(0)`` is equivalent to +``gen_func().throw(TypeError(...)`` which exhausts the generator. In 3.10.2 +onward, the behavior has been reverted to that of 3.9. + +.. + +.. bpo: 46004 +.. date: 2021-12-07-11-24-24 +.. nonce: TTEU1p +.. section: Core and Builtins + +Fix the :exc:`SyntaxError` location for errors involving for loops with +invalid targets. Patch by Pablo Galindo + +.. + +.. bpo: 45711 +.. date: 2021-12-05-17-36-08 +.. nonce: 3TmTSw +.. section: Core and Builtins + +:c:func:`_PyErr_ChainStackItem` no longer normalizes ``exc_info`` (including +setting the traceback on the exception instance) because ``exc_info`` is +always normalized. + +.. + +.. bpo: 45607 +.. date: 2021-12-01-15-38-04 +.. nonce: JhuF8b +.. section: Core and Builtins + +The ``__note__`` field was added to :exc:`BaseException`. It is ``None`` by +default but can be set to a string which is added to the exception's +traceback. + +.. + +.. bpo: 45947 +.. date: 2021-12-01-14-06-36 +.. nonce: 1XPPm_ +.. section: Core and Builtins + +Place pointers to dict and values immediately before GC header. This reduces +number of dependent memory loads to access either dict or values from 3 to +1. + +.. + +.. bpo: 45915 +.. date: 2021-11-28-11-25-08 +.. nonce: TSGcLF +.. section: Core and Builtins + +``is_valid_fd`` now uses faster ``fcntl(fd, F_GETFD)`` on Linux, macOS, and +Windows. + +.. + +.. bpo: 44530 +.. date: 2021-11-26-23-26-25 +.. nonce: EZ0gel +.. section: Core and Builtins + +Reverts a change to the ``code.__new__`` :ref:`audit event ` +from an earlier prerelease. + +.. + +.. bpo: 42268 +.. date: 2021-11-26-22-31-22 +.. nonce: 3wl-09 +.. section: Core and Builtins + +Fail the configure step if the selected compiler doesn't support memory +sanitizer. Patch by Pablo Galindo + +.. + +.. bpo: 45711 +.. date: 2021-11-25-17-51-29 +.. nonce: D2igmz +.. section: Core and Builtins + +The three values of ``exc_info`` are now always consistent with each other. +In particular, the ``type`` and ``traceback`` fields are now derived from +the exception instance. This impacts the return values of +:func:`sys.exc_info` and :c:func:`PyErr_GetExcInfo()` if the exception +instance is modified while the exception is handled, as well as +:c:func:`PyErr_SetExcInfo()`, which now ignores the ``type`` and +``traceback`` arguments provided to it. + +.. + +.. bpo: 45727 +.. date: 2021-11-24-18-24-49 +.. nonce: _xVbbo +.. section: Core and Builtins + +Refine the custom syntax error that suggests that a comma may be missing to +trigger only when the expressions are detected between parentheses or +brackets. Patch by Pablo Galindo + +.. + +.. bpo: 45885 +.. date: 2021-11-23-21-01-56 +.. nonce: 3IxeCX +.. section: Core and Builtins + +Specialized the ``COMPARE_OP`` opcode using the PEP 659 machinery. + +.. + +.. bpo: 45786 +.. date: 2021-11-23-15-25-00 +.. nonce: UdEciD +.. section: Core and Builtins + +Allocate space for the interpreter frame in the frame object, to avoid an +additional allocation when the frame object outlives the frame activation. + +.. + +.. bpo: 45614 +.. date: 2021-11-23-12-06-41 +.. nonce: fIekgI +.. section: Core and Builtins + +Fix :mod:`traceback` display for exceptions with invalid module name. + +.. + +.. bpo: 45813 +.. date: 2021-11-22-11-28-13 +.. nonce: ZMaWE2 +.. section: Core and Builtins + +Fix crash when calling coro.cr_frame.clear() after coroutine has been freed. + +.. + +.. bpo: 45811 +.. date: 2021-11-20-02-25-06 +.. nonce: B-1Gsr +.. section: Core and Builtins + +Improve the tokenizer errors when encountering invisible control characters +in the parser. Patch by Pablo Galindo + +.. + +.. bpo: 45848 +.. date: 2021-11-19-22-57-42 +.. nonce: HgVBJ5 +.. section: Core and Builtins + +Allow the parser to obtain error lines directly from encoded files. Patch by +Pablo Galindo + +.. + +.. bpo: 45709 +.. date: 2021-11-19-13-17-47 +.. nonce: H_t7ut +.. section: Core and Builtins + +Restore behavior from 3.10 when tracing an exception raised within a with +statement. + +.. + +.. bpo: 44525 +.. date: 2021-11-18-10-02-02 +.. nonce: M4xwn_ +.. section: Core and Builtins + +Adds new :opcode:`COPY_FREE_VARS` opcode, to make copying of free variables +from function to frame explicit. Helps optimization of calls to Python +function. + +.. + +.. bpo: 45829 +.. date: 2021-11-17-10-14-35 +.. nonce: 5Cf6fY +.. section: Core and Builtins + +Specialize :opcode:`BINARY_SUBSCR` for classes with a ``__getitem__`` method +implemented in Python + +.. + +.. bpo: 45826 +.. date: 2021-11-17-08-05-27 +.. nonce: OERoTm +.. section: Core and Builtins + +Fixed a crash when calling ``.with_traceback(None)`` on ``NameError``. This +occurs internally in ``unittest.TestCase.assertRaises()``. + +.. + +.. bpo: 45822 +.. date: 2021-11-16-19-41-04 +.. nonce: OT6ueS +.. section: Core and Builtins + +Fixed a bug in the parser that was causing it to not respect :pep:`263` +coding cookies when no flags are provided. Patch by Pablo Galindo + +.. + +.. bpo: 45820 +.. date: 2021-11-16-19-00-27 +.. nonce: 2X6Psr +.. section: Core and Builtins + +Fix a segfault when the parser fails without reading any input. Patch by +Pablo Galindo + +.. + +.. bpo: 45636 +.. date: 2021-11-15-13-32-54 +.. nonce: RDlTdL +.. section: Core and Builtins + +Simplify the implementation of :opcode:`BINARY_OP` by indexing into an array +of function pointers (rather than switching on the oparg). + +.. + +.. bpo: 42540 +.. date: 2021-11-15-12-08-27 +.. nonce: V2w107 +.. section: Core and Builtins + +Fix crash when :func:`os.fork` is called with an active non-default memory +allocator. + +.. + +.. bpo: 45738 +.. date: 2021-11-14-00-14-45 +.. nonce: e0cgKd +.. section: Core and Builtins + +Fix computation of error location for invalid continuation characters in the +parser. Patch by Pablo Galindo. + +.. + +.. bpo: 45636 +.. date: 2021-11-11-19-11-57 +.. nonce: 2fyIVm +.. section: Core and Builtins + +Remove an existing "fast path" for old-style string formatting, since it no +longer appears to have any measurable impact. + +.. + +.. bpo: 45753 +.. date: 2021-11-11-17-14-21 +.. nonce: nEBFcC +.. section: Core and Builtins + +Make recursion checks a bit more efficient by tracking amount of calls left +before overflow. + +.. + +.. bpo: 45773 +.. date: 2021-11-09-13-01-35 +.. nonce: POU8A4 +.. section: Core and Builtins + +Fix a compiler hang when attempting to optimize certain jump patterns. + +.. + +.. bpo: 45764 +.. date: 2021-11-09-12-19-22 +.. nonce: 8RLhWL +.. section: Core and Builtins + +The parser now gives a better error message when leaving out the opening +parenthesis ``(`` after a ``def``-statement:: + + >>> def f: + File "", line 1 + def f: + ^ + SyntaxError: expected '(' + +.. + +.. bpo: 45609 +.. date: 2021-10-27-21-00-49 +.. nonce: L1GKPX +.. section: Core and Builtins + +Specialized the ``STORE_SUBSCR`` opcode using the PEP 659 machinery. + +.. + +.. bpo: 45636 +.. date: 2021-10-27-15-14-31 +.. nonce: K2X7QS +.. section: Core and Builtins + +Replace all numeric ``BINARY_*`` and ``INPLACE_*`` instructions with a +single :opcode:`BINARY_OP` implementation. + +.. + +.. bpo: 45582 +.. date: 2021-10-23-00-39-31 +.. nonce: YONPuo +.. section: Core and Builtins + +Path calculation (known as ``getpath``) has been reimplemented as a frozen +Python module. This should have no visible impact, but may affect +calculation of all paths referenced in :mod:`sys` and :mod:`sysconfig`. + +.. + +.. bpo: 45450 +.. date: 2021-10-12-18-22-44 +.. nonce: d9a-bX +.. section: Core and Builtins + +Improve the syntax error message for parenthesized arguments. Patch by Pablo +Galindo. + +.. + +.. bpo: 27946 +.. date: 2021-12-04-20-08-42 +.. nonce: -Vuarf +.. section: Library + +Fix possible crash when getting an attribute of +class:`xml.etree.ElementTree.Element` simultaneously with replacing the +``attrib`` dict. + +.. + +.. bpo: 45711 +.. date: 2021-12-02-17-22-06 +.. nonce: D6jsdv +.. section: Library + +Make :mod:`asyncio` normalize exceptions as soon as they are captured with +:c:func:`PyErr_Fetch`, and before they are stored as an exc_info triplet. +This brings :mod:`asyncio` in line with the rest of the codebase, where an +exc_info triplet is always normalized. + +.. + +.. bpo: 23819 +.. date: 2021-12-02-14-37-30 +.. nonce: An6vkT +.. section: Library + +Replaced asserts with exceptions in asyncio, patch by Kumar Aditya. + +.. + +.. bpo: 13236 +.. date: 2021-11-30-13-52-02 +.. nonce: FmJIkO +.. section: Library + +:class:`unittest.TextTestResult` and :class:`unittest.TextTestRunner` flush +now the output stream more often. + +.. + +.. bpo: 45917 +.. date: 2021-11-28-17-24-11 +.. nonce: J5TIrd +.. section: Library + +Added :func:`math.exp2`:, which returns 2 raised to the power of x. + +.. + +.. bpo: 37658 +.. date: 2021-11-28-15-30-34 +.. nonce: 8Hno7d +.. section: Library + +Fix issue when on certain conditions ``asyncio.wait_for()`` may allow a +coroutine to complete successfully, but fail to return the result, +potentially causing memory leaks or other issues. + +.. + +.. bpo: 45876 +.. date: 2021-11-23-15-36-56 +.. nonce: NO8Yaj +.. section: Library + +Improve the accuracy of stdev() and pstdev() in the statistics module. When +the inputs are floats or fractions, the output is a correctly rounded float + +.. + +.. bpo: 44649 +.. date: 2021-11-21-20-50-42 +.. nonce: E8M936 +.. section: Library + +Handle dataclass(slots=True) with a field that has default a default value, +but for which init=False. + +.. + +.. bpo: 45803 +.. date: 2021-11-20-17-04-25 +.. nonce: wSgFOy +.. section: Library + +Added missing kw_only parameter to dataclasses.make_dataclass(). + +.. + +.. bpo: 45837 +.. date: 2021-11-18-13-13-19 +.. nonce: aGyr1I +.. section: Library + +The :meth:`turtle.RawTurtle.settiltangle` is deprecated since Python 3.1, it +now emits a deprecation warning and will be removed in Python 3.13. + +Use :meth:`turtle.RawTurtle.tiltangle` instead. + +:meth:`turtle.RawTurtle.tiltangle` was earlier incorrectly marked as +deprecated, its docstring has been corrected. + +Patch by Hugo van Kemenade. + +.. + +.. bpo: 45831 +.. date: 2021-11-17-19-25-37 +.. nonce: 9-TojK +.. section: Library + +:mod:`faulthandler` can now write ASCII-only strings (like filenames and +function names) with a single write() syscall when dumping a traceback. It +reduces the risk of getting an unreadable dump when two threads or two +processes dump a traceback to the same file (like stderr) at the same time. +Patch by Victor Stinner. + +.. + +.. bpo: 45828 +.. date: 2021-11-17-11-40-21 +.. nonce: kQU35U +.. section: Library + +:mod:`sqlite` C callbacks now use unraisable exceptions if callback +tracebacks are enabled. Patch by Erlend E. Aasland. + +.. + +.. bpo: 41735 +.. date: 2021-11-16-18-13-49 +.. nonce: D72UY1 +.. section: Library + +Fix thread lock in ``zlib.Decompress.flush()`` method before +``PyObject_GetBuffer``. + +.. + +.. bpo: 45235 +.. date: 2021-11-11-13-03-17 +.. nonce: 8ZbkHa +.. section: Library + +Reverted an argparse bugfix that caused regression in the handling of +default arguments for subparsers. This prevented leaf level arguments from +taking precedence over root level arguments. + +.. + +.. bpo: 45754 +.. date: 2021-11-09-15-48-38 +.. nonce: c-JDto +.. section: Library + +Fix a regression in Python 3.11a1 and 3.11a2 where :mod:`sqlite3` +incorrectly would use ``SQLITE_LIMIT_LENGTH`` when checking SQL statement +lengths. Now, ``SQLITE_LIMIT_SQL_LENGTH`` is used. Patch by Erlend E. +Aasland. + +.. + +.. bpo: 45766 +.. date: 2021-11-09-09-18-06 +.. nonce: dvbcMf +.. section: Library + +Added *proportional* option to :meth:`statistics.linear_regression`. + +.. + +.. bpo: 45765 +.. date: 2021-11-09-09-04-19 +.. nonce: JVobxK +.. section: Library + +In importlib.metadata, fix distribution discovery for an empty path. + +.. + +.. bpo: 45757 +.. date: 2021-11-08-23-22-14 +.. nonce: MHZHt3 +.. section: Library + +Fix bug where :mod:`dis` produced an incorrect oparg when +:opcode:`EXTENDED_ARG` is followed by an opcode that does not use its +argument. + +.. + +.. bpo: 45644 +.. date: 2021-11-06-17-47-46 +.. nonce: ZMqHD_ +.. section: Library + +In-place JSON file formatting using ``python3 -m json.tool infile infile`` +now works correctly, previously it left the file empty. Patch by Chris +Wesseling. + +.. + +.. bpo: 45703 +.. date: 2021-11-03-13-41-49 +.. nonce: 35AagL +.. section: Library + +When a namespace package is imported before another module from the same +namespace is created/installed in a different :data:`sys.path` location +while the program is running, calling the +:func:`importlib.invalidate_caches` function will now also guarantee the new +module is noticed. + +.. + +.. bpo: 45535 +.. date: 2021-10-29-16-28-06 +.. nonce: n8NiOE +.. section: Library + +Improve output of ``dir()`` with Enums. + +.. + +.. bpo: 45664 +.. date: 2021-10-28-23-40-54 +.. nonce: 7dqtxQ +.. section: Library + +Fix :func:`types.resolve_bases` and :func:`types.new_class` for +:class:`types.GenericAlias` instance as a base. + +.. + +.. bpo: 45663 +.. date: 2021-10-28-23-11-59 +.. nonce: J90N5R +.. section: Library + +Fix :func:`dataclasses.is_dataclass` for dataclasses which are subclasses of +:class:`types.GenericAlias`. + +.. + +.. bpo: 45662 +.. date: 2021-10-28-22-58-14 +.. nonce: sJd7Ir +.. section: Library + +Fix the repr of :data:`dataclasses.InitVar` with a type alias to the +built-in class, e.g. ``InitVar[list[int]]``. + +.. + +.. bpo: 43137 +.. date: 2021-10-25-12-51-02 +.. nonce: apo7jY +.. section: Library + +Launch GNOME web browsers via gio tool instead of obsolete gvfs-open + +.. + +.. bpo: 45429 +.. date: 2021-10-25-01-22-49 +.. nonce: VaEyN9 +.. section: Library + +On Windows, :func:`time.sleep` now uses a waitable timer which supports +high-resolution timers. Patch by Dong-hee Na and Eryk Sun. + +.. + +.. bpo: 37295 +.. date: 2021-10-18-16-08-55 +.. nonce: wBEWH2 +.. section: Library + +Optimize :func:`math.comb` and :func:`math.perm`. + +.. + +.. bpo: 45514 +.. date: 2021-10-18-14-25-35 +.. nonce: YmlzIl +.. section: Library + +Deprecated legacy functions in :mod:`importlib.resources`. + +.. + +.. bpo: 45507 +.. date: 2021-10-18-14-00-01 +.. nonce: lDotNV +.. section: Library + +Add tests for truncated/missing trailers in gzip.decompress implementation. + +.. + +.. bpo: 45359 +.. date: 2021-10-03-22-27-35 +.. nonce: LX_uxe +.. section: Library + +Implement :pep:`585` for :class:`graphlib.TopologicalSorter`. + +.. + +.. bpo: 44733 +.. date: 2021-07-26-13-33-37 +.. nonce: 88LrP1 +.. section: Library + +Add ``max_tasks_per_child`` to +:class:`concurrent.futures.ProcessPoolExecutor`. This allows users to +specify the maximum number of tasks a single process should execute before +the process needs to be restarted. + +.. + +.. bpo: 28806 +.. date: 2021-05-24-13-48-34 +.. nonce: PkNw5D +.. section: Library + +Improve netrc library. netrc file no longer needs to contain all tokens. And +if the login name is anonymous, security check is no longer need. + +.. + +.. bpo: 43498 +.. date: 2021-04-20-14-14-16 +.. nonce: L_Hq-8 +.. section: Library + +Avoid a possible *"RuntimeError: dictionary changed size during iteration"* +when adjusting the process count of :class:`ProcessPoolExecutor`. + +.. + +.. bpo: 42158 +.. date: 2020-11-10-17-46-12 +.. nonce: OhxAiH +.. section: Library + +Add MIME types for N-quads, N-triples, Notation3 and TriG to ``mimetypes``. + +.. + +.. bpo: 30533 +.. date: 2020-06-16-18-00-56 +.. nonce: StL57t +.. section: Library + +Add :func:`inspect.getmembers_static` , it return all members without +triggering dynamic lookup via the descriptor protocol. Patch by Weipeng +Hong. + +.. + +.. bpo: 42238 +.. date: 2021-11-20-02-46-39 +.. nonce: hlfMIc +.. section: Documentation + +``make -C Doc suspicious`` will be removed soon in favor of ``make -C Doc +check``, mark it as deprecated. + +.. + +.. bpo: 45840 +.. date: 2021-11-19-02-02-32 +.. nonce: A51B2S +.. section: Documentation + +Improve cross-references in the documentation for the data model. + +.. + +.. bpo: 45640 +.. date: 2021-11-18-16-44-12 +.. nonce: lSpc2A +.. section: Documentation + +Properly marked-up grammar tokens in the documentation are now clickable and +take you to the definition of a given piece of grammar. Patch by Arthur +Milchior. + +.. + +.. bpo: 45788 +.. date: 2021-11-18-00-07-40 +.. nonce: qibUoB +.. section: Documentation + +Link doc for sys.prefix to sysconfig doc on installation paths. + +.. + +.. bpo: 45772 +.. date: 2021-11-09-13-10-55 +.. nonce: EdrM3t +.. section: Documentation + +``socket.socket`` documentation is corrected to a class from a function. + +.. + +.. bpo: 45392 +.. date: 2021-11-06-10-54-17 +.. nonce: JZnVOz +.. section: Documentation + +Update the docstring of the :class:`type` built-in to remove a redundant +line and to mention keyword arguments for the constructor. + +.. + +.. bpo: 45250 +.. date: 2021-10-22-12-09-18 +.. nonce: Iit5-Y +.. section: Documentation + +Update the documentation to note that CPython does not consistently require +iterators to define ``__iter__``. + +.. + +.. bpo: 25381 +.. date: 2021-06-21-17-51-51 +.. nonce: 7Kn-_H +.. section: Documentation + +In the extending chapter of the extending doc, update a paragraph about the +global variables containing exception information. + +.. + +.. bpo: 43905 +.. date: 2021-05-24-05-00-12 +.. nonce: tBIndE +.. section: Documentation + +Expanded :func:`~dataclasses.astuple` and :func:`~dataclasses.asdict` docs, +warning about deepcopy being applied and providing a workaround. + +.. + +.. bpo: 45695 +.. date: 2021-12-03-14-19-16 +.. nonce: QKBn2E +.. section: Tests + +Out-of-tree builds with a read-only source directory are now tested by CI. + +.. + +.. bpo: 19460 +.. date: 2021-11-28-15-25-02 +.. nonce: lr0aWs +.. section: Tests + +Add new Test for ``Lib/email/mime/nonmultipart.py::MIMENonMultipart``. + +.. + +.. bpo: 45835 +.. date: 2021-11-17-14-28-08 +.. nonce: Mgyhjx +.. section: Tests + +Fix race condition in test_queue tests with multiple "feeder" threads. + +.. + +.. bpo: 45783 +.. date: 2021-11-11-13-56-00 +.. nonce: 8k1Rng +.. section: Tests + +The test for the freeze tool now handles file moves and deletions. + +.. + +.. bpo: 45745 +.. date: 2021-11-10-12-01-28 +.. nonce: wX5B3K +.. section: Tests + +Remove the ``--findleaks`` command line option of regrtest: use the +``--fail-env-changed`` option instead. Since Python 3.7, it was a deprecated +alias to the ``--fail-env-changed`` option. + +.. + +.. bpo: 45701 +.. date: 2021-10-31-10-58-45 +.. nonce: r0LAUL +.. section: Tests + +Add tests with ``tuple`` type with :func:`functools.lru_cache` to +``test_functools``. + +.. + +.. bpo: 44035 +.. date: 2021-12-06-09-31-27 +.. nonce: BiO4XC +.. section: Build + +CI now verifies that autoconf files have been regenerated with a current and +unpatched autoconf package. + +.. + +.. bpo: 45950 +.. date: 2021-12-01-17-28-39 +.. nonce: eEVLoz +.. section: Build + +The build system now uses a :program:`_bootstrap_python` interpreter for +freezing and deepfreezing again. To speed up build process the build tools +:program:`_bootstrap_python` and :program:`_freeze_module` are no longer +build with LTO. + +.. + +.. bpo: 45881 +.. date: 2021-11-29-16-32-55 +.. nonce: 7597J6 +.. section: Build + +The :program:`configure` script now accepts ``--with-build-python`` and +``--with-freeze-module`` options to make cross compiling easier. + +.. + +.. bpo: 40280 +.. date: 2021-11-29-14-37-29 +.. nonce: UlTMR8 +.. section: Build + +Emscripten platform now uses ``.wasm`` suffix by default. + +.. + +.. bpo: 40280 +.. date: 2021-11-29-11-24-45 +.. nonce: Knx7d7 +.. section: Build + +Disable unusable core extension modules on WASM/Emscripten targets. + +.. + +.. bpo: 40280 +.. date: 2021-11-26-14-09-04 +.. nonce: ZLpwQf +.. section: Build + +``configure`` now checks for socket ``shutdown`` function. The check makes +it possible to disable ``SYS_shutdown`` with ``ac_cv_func_shutdown=no`` in +CONFIG_SITE. + +.. + +.. bpo: 40280 +.. date: 2021-11-26-09-10-19 +.. nonce: xmiMJl +.. section: Build + +``configure`` now checks for functions ``fork1, getegid, geteuid, getgid, +getppid, getuid, opendir, pipe, system, wait, ttyname``. + +.. + +.. bpo: 33393 +.. date: 2021-11-25-20-26-06 +.. nonce: 24YNtM +.. section: Build + +Update ``config.guess`` to 2021-06-03 and ``config.sub`` to 2021-08-14. +``Makefile`` now has an ``update-config`` target to make updating more +convenient. + +.. + +.. bpo: 45866 +.. date: 2021-11-25-13-53-36 +.. nonce: ZH1W8N +.. section: Build + +``make regen-all`` now produces the same output when run from a directory +other than the source tree: when building Python out of the source tree. +pegen now strips directory of the "generated by pygen from " +header Patch by Victor Stinner. + +.. + +.. bpo: 40280 +.. date: 2021-11-25-10-55-03 +.. nonce: E9-gsQ +.. section: Build + +``configure`` now accepts machine ``wasm32`` or ``wasm64`` and OS ``wasi`` +or ``emscripten`` for cross building, e.g. ``wasm32-unknown-emscripten``, +``wasm32-wasi``, or ``wasm32-unknown-wasi``. + +.. + +.. bpo: 41498 +.. date: 2021-11-25-09-15-04 +.. nonce: qAk5eo +.. section: Build + +Python now compiles on platforms without ``sigset_t``. Several functions in +:mod:`signal` are not available when ``sigset_t`` is missing. + +Based on patch by Roman Yurchak for pyodide. + +.. + +.. bpo: 45881 +.. date: 2021-11-24-17-14-06 +.. nonce: GTXXLk +.. section: Build + +``setup.py`` now uses ``CC`` from environment first to discover multiarch +and cross compile paths. + +.. + +.. bpo: 45886 +.. date: 2021-11-23-23-37-49 +.. nonce: _Ulnh- +.. section: Build + +The ``_freeze_module`` program path can now be overridden on the command +line, e.g. ``make FREEZE_MODULE=../x86_64/Program/_freeze_module``. + +.. + +.. bpo: 45873 +.. date: 2021-11-23-04-28-40 +.. nonce: 9dldZ4 +.. section: Build + +Get rid of the ``_bootstrap_python`` build step. The deepfreeze.py script is +now run using ``$(PYTHON_FOR_REGEN)`` which can be Python 3.7 or newer (on +Windows, 3.8 or newer). + +.. + +.. bpo: 45847 +.. date: 2021-11-19-17-57-57 +.. nonce: 9phcpd +.. section: Build + +Port builtin hashlib extensions to ``PY_STDLIB_MOD`` macro and ``addext()``. + +.. + +.. bpo: 45723 +.. date: 2021-11-19-15-42-27 +.. nonce: vwIJWI +.. section: Build + +Add ``autoconf`` helpers for saving and restoring environment variables: + +* ``SAVE_ENV``: Save ``$CFLAGS``, ``$LDFLAGS``, ``$LIBS``, and + ``$CPPFLAGS``. +* ``RESTORE_ENV``: Restore ``$CFLAGS``, ``$LDFLAGS``, ``$LIBS``, and + ``$CPPFLAGS``. +* ``WITH_SAVE_ENV([SCRIPT])``: Run ``SCRIPT`` wrapped with ``SAVE_ENV`` and + ``RESTORE_ENV``. + +Patch by Erlend E. Aasland. + +.. + +.. bpo: 45573 +.. date: 2021-11-18-13-31-02 +.. nonce: LCjGB8 +.. section: Build + +Mandatory core modules, that are required to bootstrap Python, are now in +``Modules/Setup.bootstrap``. + +.. + +.. bpo: 45573 +.. date: 2021-11-18-12-18-43 +.. nonce: xsMZzn +.. section: Build + +``configure`` now creates ``Modules/Setup.stdlib`` with conditionally +enabled/disabled extension module lines. The file is not used, yet. + +.. + +.. bpo: 45573 +.. date: 2021-11-17-19-02-51 +.. nonce: GMNdun +.. section: Build + +``configure`` now uses a unified format to set state, compiler flags, and +linker flags in Makefile. The new macro ``PY_STDLIB_MOD`` sets three +variables that are consumed by ``Modules/Setup`` and ``setup.py``. + +.. + +.. bpo: 45816 +.. date: 2021-11-16-14-44-06 +.. nonce: nbdmVK +.. section: Build + +Python now supports building with Visual Studio 2022 (MSVC v143, VS Version +17.0). Patch by Jeremiah Vivian. + +.. + +.. bpo: 45800 +.. date: 2021-11-13-16-40-05 +.. nonce: 5Hz6nr +.. section: Build + +Settings for :mod:`pyexpat` C extension are now detected by ``configure``. +The bundled ``expat`` library is built in ``Makefile``. + +.. + +.. bpo: 45798 +.. date: 2021-11-13-10-18-22 +.. nonce: IraaTs +.. section: Build + +Settings for :mod:`decimal` internal C extension are now detected by +``configure``. The bundled ``libmpdec`` library is built in ``Makefile``. + +.. + +.. bpo: 45723 +.. date: 2021-11-10-16-13-02 +.. nonce: B5gCB1 +.. section: Build + +:program:`configure` has a new option ``--with-pkg-config`` to disable or +require pkg-config. + +.. + +.. bpo: 45774 +.. date: 2021-11-09-23-30-12 +.. nonce: Mwm3ZR +.. section: Build + +The build dependencies for :mod:`sqlite3` are now detected by ``configure`` +and ``pkg-config``. Patch by Erlend E. Aasland. + +.. + +.. bpo: 45763 +.. date: 2021-11-09-10-15-33 +.. nonce: gP-vrX +.. section: Build + +The build dependencies for :mod:`zlib`, :mod:`bz2`, and :mod:`lzma` are now +detected by ``configure``. + +.. + +.. bpo: 45747 +.. date: 2021-11-08-11-31-48 +.. nonce: AODmk_ +.. section: Build + +gdbm and dbm build dependencies are now detected by ``configure``. + +.. + +.. bpo: 45743 +.. date: 2021-11-08-08-58-06 +.. nonce: fZ8CTi +.. section: Build + +On macOS, the build system no longer passes ``search_paths_first`` to the +linker. The flag has been the default since Xcode 4 / macOS 10.6. + +.. + +.. bpo: 45723 +.. date: 2021-11-07-10-45-40 +.. nonce: AreusF +.. section: Build + +``configure.ac`` is now compatible with autoconf 2.71. Deprecated checks +``STDC_HEADERS`` and ``AC_HEADER_TIME`` have been removed. + +.. + +.. bpo: 45723 +.. date: 2021-11-07-10-36-12 +.. nonce: JNwKSG +.. section: Build + +``configure`` now prints a warning when pkg-config is missing. + +.. + +.. bpo: 45731 +.. date: 2021-11-05-20-56-29 +.. nonce: 9SDnDf +.. section: Build + +``configure --enable-loadable-sqlite-extensions`` is now handled by new +``PY_SQLITE_ENABLE_LOAD_EXTENSION`` macro instead of logic in setup.py. + +.. + +.. bpo: 45723 +.. date: 2021-11-05-15-09-49 +.. nonce: gfSxur +.. section: Build + +configure.ac now uses custom helper macros and ``AC_CACHE_CHECK`` to +simplify and speed up configure runs. + +.. + +.. bpo: 45696 +.. date: 2021-11-03-00-19-50 +.. nonce: eKs46f +.. section: Build + +Skip the marshal step for frozen modules by generating C code that produces +a set of ready-to-use code objects. This speeds up startup time by another +10% or more. + +.. + +.. bpo: 45561 +.. date: 2021-10-21-14-38-30 +.. nonce: PVqhZE +.. section: Build + +Run smelly.py tool from $(srcdir). + +.. + +.. bpo: 46105 +.. date: 2021-12-08-16-36-20 +.. nonce: t1mJ6Q +.. section: Windows + +Fixed calculation of :data:`sys.path` in a venv on Windows. + +.. + +.. bpo: 45901 +.. date: 2021-11-26-18-17-41 +.. nonce: c5IBqM +.. section: Windows + +When installed through the Microsoft Store and set as the default app for +:file:`*.py` files, command line arguments will now be passed to Python when +invoking a script without explicitly launching Python (that is, ``script.py +args`` rather than ``python script.py args``). + +.. + +.. bpo: 45616 +.. date: 2021-11-23-11-44-42 +.. nonce: K52PLZ +.. section: Windows + +Fix Python Launcher's ability to distinguish between versions 3.1 and 3.10 +when either one is explicitly requested. Previously, 3.1 would be used if +3.10 was requested but not installed, and 3.10 would be used if 3.1 was +requested but 3.10 was installed. + +.. + +.. bpo: 45850 +.. date: 2021-11-20-00-06-59 +.. nonce: q9lofz +.. section: Windows + +Implement changes to build with deep-frozen modules on Windows. Note that we +now require Python 3.10 as the "bootstrap" or "host" Python. + +.. + +.. bpo: 45732 +.. date: 2021-11-08-21-53-11 +.. nonce: idl5kx +.. section: Windows + +Updates bundled Tcl/Tk to 8.6.12. + +.. + +.. bpo: 45720 +.. date: 2021-11-05-01-05-46 +.. nonce: 47Nc5I +.. section: Windows + +Internal reference to :file:`shlwapi.dll` was dropped to help improve +startup time. This DLL will no longer be loaded at the start of every Python +process. + +.. + +.. bpo: 45732 +.. date: 2021-12-05-23-52-03 +.. nonce: -BWrnh +.. section: macOS + +Update python.org macOS installer to use Tcl/Tk 8.6.12. + +.. + +.. bpo: 39026 +.. date: 2021-11-09-15-42-11 +.. nonce: sUnYWn +.. section: C API + +Fix Python.h to build C extensions with Xcode: remove a relative include +from ``Include/cpython/pystate.h``. diff --git a/Misc/NEWS.d/3.11.0a4.rst b/Misc/NEWS.d/3.11.0a4.rst new file mode 100644 index 00000000000..bcb6e8b7bdd --- /dev/null +++ b/Misc/NEWS.d/3.11.0a4.rst @@ -0,0 +1,1177 @@ +.. bpo: 46070 +.. date: 2022-01-13-17-58-56 +.. nonce: q8IGth +.. release date: 2022-01-13 +.. section: Core and Builtins + +:c:func:`Py_EndInterpreter` now explicitly untracks all objects currently +tracked by the GC. Previously, if an object was used later by another +interpreter, calling :c:func:`PyObject_GC_UnTrack` on the object crashed if +the previous or the next object of the :c:type:`PyGC_Head` structure became +a dangling pointer. Patch by Victor Stinner. + +.. + +.. bpo: 46347 +.. date: 2022-01-11-13-57-00 +.. nonce: Gd8M-S +.. section: Core and Builtins + +Fix memory leak in PyEval_EvalCodeEx. + +.. + +.. bpo: 46339 +.. date: 2022-01-11-11-50-19 +.. nonce: OVumDZ +.. section: Core and Builtins + +Fix a crash in the parser when retrieving the error text for multi-line +f-strings expressions that do not start in the first line of the string. +Patch by Pablo Galindo + +.. + +.. bpo: 46331 +.. date: 2022-01-10-16-21-54 +.. nonce: h1AC-i +.. section: Core and Builtins + +Do not set line number of instruction storing doc-string. Fixes regression +introduced in 3.11 alpha. + +.. + +.. bpo: 46314 +.. date: 2022-01-10-12-34-17 +.. nonce: jId9Ky +.. section: Core and Builtins + +Remove spurious "call" event when creating a lambda function that was +accidentally introduced in 3.11a4. + +.. + +.. bpo: 46289 +.. date: 2022-01-07-23-32-03 +.. nonce: NnjpVc +.. section: Core and Builtins + +ASDL declaration of ``FormattedValue`` has changed to reflect ``conversion`` +field is not optional. + +.. + +.. bpo: 46297 +.. date: 2022-01-07-22-13-59 +.. nonce: 83ThTl +.. section: Core and Builtins + +Fixed an interpreter crash on bootup with multiple PythonPaths set in the +Windows registry. Patch by Derzsi Dániel. + +.. + +.. bpo: 46237 +.. date: 2022-01-07-19-33-05 +.. nonce: 9A6Hpq +.. section: Core and Builtins + +Fix the line number of tokenizer errors inside f-strings. Patch by Pablo +Galindo. + +.. + +.. bpo: 46263 +.. date: 2022-01-06-10-54-07 +.. nonce: 60dRZb +.. section: Core and Builtins + +We always expect the "use_frozen_modules" config to be set, now that +getpath.c was rewritten in pure Python and the logic improved. + +.. + +.. bpo: 46006 +.. date: 2022-01-05-17-13-47 +.. nonce: hdH5Vn +.. section: Core and Builtins + +Fix a regression when a type method like ``__init__()`` is modified in a +subinterpreter. Fix a regression in ``_PyUnicode_EqualToASCIIId()`` and type +``update_slot()``. Revert the change which made the Unicode dictionary of +interned strings compatible with subinterpreters: the internal interned +dictionary is shared again by all interpreters. Patch by Victor Stinner. + +.. + +.. bpo: 45923 +.. date: 2022-01-04-14-08-10 +.. nonce: rBp7r1 +.. section: Core and Builtins + +Add RESUME opcode. This is a logical no-op. It is emitted by the compiler +anywhere a Python function can be entered. It is used by the interpreter to +perform tracing and optimizer checks. + +.. + +.. bpo: 46208 +.. date: 2022-01-04-01-53-35 +.. nonce: i00Vz5 +.. section: Core and Builtins + +Fix the regression of os.path.normpath("A/../../B") not returning expected +"../B" but "B". + +.. + +.. bpo: 46240 +.. date: 2022-01-03-23-31-25 +.. nonce: 8lGjeK +.. section: Core and Builtins + +Correct the error message for unclosed parentheses when the tokenizer +doesn't reach the end of the source when the error is reported. Patch by +Pablo Galindo + +.. + +.. bpo: 46009 +.. date: 2022-01-03-11-36-34 +.. nonce: QZGrov +.. section: Core and Builtins + +Remove the ``GEN_START`` opcode. + +.. + +.. bpo: 46235 +.. date: 2022-01-02-23-55-13 +.. nonce: gUjp2v +.. section: Core and Builtins + +Certain sequence multiplication operations like ``[0] * 1_000`` are now +faster due to reference-counting optimizations. Patch by Dennis Sweeney. + +.. + +.. bpo: 46221 +.. date: 2022-01-01-14-23-57 +.. nonce: 7oGp-I +.. section: Core and Builtins + +:opcode:`PREP_RERAISE_STAR` no longer pushes ``lasti`` to the stack. + +.. + +.. bpo: 46202 +.. date: 2021-12-30-11-06-27 +.. nonce: IKx4v6 +.. section: Core and Builtins + +Remove :opcode:`POP_EXCEPT_AND_RERAISE` and replace it by an equivalent +sequence of other opcodes. + +.. + +.. bpo: 46085 +.. date: 2021-12-30-00-23-41 +.. nonce: bDuJqu +.. section: Core and Builtins + +Fix iterator cache mechanism of :class:`OrderedDict`. + +.. + +.. bpo: 46055 +.. date: 2021-12-24-20-21-45 +.. nonce: R0QMVQ +.. section: Core and Builtins + +Speed up shifting operation involving integers less than +:c:macro:`PyLong_BASE`. Patch by Xinhang Xu. + +.. + +.. bpo: 46110 +.. date: 2021-12-18-02-37-07 +.. nonce: B6hAfu +.. section: Core and Builtins + +Add a maximum recursion check to the PEG parser to avoid stack overflow. +Patch by Pablo Galindo + +.. + +.. bpo: 46107 +.. date: 2021-12-16-23-27-05 +.. nonce: 7q5an0 +.. section: Core and Builtins + +Fix bug where :meth:`ExceptionGroup.split` and +:meth:`ExceptionGroup.subgroup` did not copy the exception group's +``__note__`` field to the parts. + +.. + +.. bpo: 45711 +.. date: 2021-12-15-15-17-04 +.. nonce: QK4QrB +.. section: Core and Builtins + +The interpreter state's representation of handled exceptions (a.k.a +exc_info, or _PyErr_StackItem) now has only the ``exc_value`` field, +``exc_type`` and ``exc_traceback`` have been removed as their values can be +derived from ``exc_value``. + +.. + +.. bpo: 44525 +.. date: 2021-12-13-17-12-16 +.. nonce: 4-FiSf +.. section: Core and Builtins + +Replace the four call bytecode instructions which one pre-call instruction +and two call instructions. + +Removes ``CALL_FUNCTION``, ``CALL_FUNCTION_KW``, ``CALL_METHOD`` and +``CALL_METHOD_KW``. + +Adds ``CALL_NO_KW`` and ``CALL_KW`` call instructions, and +``PRECALL_METHOD`` prefix for pairing with ``LOAD_METHOD``. + +.. + +.. bpo: 46039 +.. date: 2021-12-13-17-01-13 +.. nonce: TrCBbF +.. section: Core and Builtins + +Remove the ``YIELD_FROM`` instruction and replace it with the ``SEND`` +instruction which performs the same operation, but without the loop. + +.. + +.. bpo: 45635 +.. date: 2021-12-12-15-52-41 +.. nonce: ADVaPT +.. section: Core and Builtins + +The code called from :c:func:`_PyErr_Display` was refactored to improve +error handling. It now exits immediately upon an unrecoverable error. + +.. + +.. bpo: 46054 +.. date: 2021-12-12-05-30-21 +.. nonce: 2P-foG +.. section: Core and Builtins + +Fix parser error when parsing non-utf8 characters in source files. Patch by +Pablo Galindo. + +.. + +.. bpo: 46042 +.. date: 2021-12-11-17-40-34 +.. nonce: aqYxku +.. section: Core and Builtins + +Improve the location of the caret in :exc:`SyntaxError` exceptions emitted +by the symbol table. Patch by Pablo Galindo. + +.. + +.. bpo: 46049 +.. date: 2021-12-11-13-49-19 +.. nonce: 9dNto2 +.. section: Core and Builtins + +Ensure :file:`._pth` files work as intended on platforms other than Windows. + +.. + +.. bpo: 46048 +.. date: 2021-12-11-13-14-42 +.. nonce: _-OGD9 +.. section: Core and Builtins + +Fixes parsing of :file:`._pth` files on startup so that single-character +paths are correctly read. + +.. + +.. bpo: 37971 +.. date: 2021-12-10-13-42-17 +.. nonce: 6BC1Tx +.. section: Core and Builtins + +Fix a bug where the line numbers given in a traceback when a decorator +application raised an exception were wrong. + +.. + +.. bpo: 46031 +.. date: 2021-12-10-09-10-32 +.. nonce: rM7JOX +.. section: Core and Builtins + +Add :opcode:`POP_JUMP_IF_NOT_NONE` and :opcode:`POP_JUMP_IF_NONE` opcodes to +speed up conditional jumps. + +.. + +.. bpo: 45654 +.. date: 2021-12-09-11-57-43 +.. nonce: MZc7ei +.. section: Core and Builtins + +Deepfreeze :mod:`runpy`, patch by Kumar Aditya. + +.. + +.. bpo: 46025 +.. date: 2021-12-09-11-41-35 +.. nonce: pkEvW9 +.. section: Core and Builtins + +Fix a crash in the :mod:`atexit` module involving functions that unregister +themselves before raising exceptions. Patch by Pablo Galindo. + +.. + +.. bpo: 46000 +.. date: 2021-12-07-11-42-44 +.. nonce: v_ru3k +.. section: Core and Builtins + +Improve compatibility of the :mod:`curses` module with NetBSD curses. + +.. + +.. bpo: 44525 +.. date: 2021-12-07-11-04-21 +.. nonce: 6OWCgr +.. section: Core and Builtins + +Specialize the CALL_FUNCTION instruction for calls to builtin types with a +single argument. Speeds up ``range(x)``, ``list(x)``, and specifically +``type(obj)``. + +.. + +.. bpo: 42918 +.. date: 2021-12-06-15-32-12 +.. nonce: Czpgtg +.. section: Core and Builtins + +Fix bug where the built-in :func:`compile` function did not always raise a +:exc:`SyntaxError` when passed multiple statements in 'single' mode. Patch +by Weipeng Hong. + +.. + +.. bpo: 45953 +.. date: 2021-12-01-11-54-27 +.. nonce: 2znR0E +.. section: Core and Builtins + +The main interpreter in _PyRuntimeState.interpreters is now statically +allocated (as part of _PyRuntime). Likewise for the initial thread state of +each interpreter. This means less allocation during runtime init, as well +as better memory locality for these key state objects. + +.. + +.. bpo: 45292 +.. date: 2021-11-22-13-05-32 +.. nonce: pfEouJ +.. section: Core and Builtins + +Complete the :pep:`654` implementation: add ``except*``. + +.. + +.. bpo: 43413 +.. date: 2021-05-30-16-37-47 +.. nonce: vYFPPC1 +.. section: Core and Builtins + +Revert changes in ``set.__init__``. Subclass of :class:`set` needs to define +a ``__init__()`` method if it defines a ``__new__()`` method with additional +keyword parameters. + +.. + +.. bpo: 43931 +.. date: 2021-04-24-15-39-23 +.. nonce: zpChDi +.. section: Core and Builtins + +Added the :c:data:`Py_Version` constant which bears the same value as +:c:macro:`PY_VERSION_HEX`. Patch by Gabriele N. Tornetta. + +.. + +.. bpo: 46342 +.. date: 2022-01-11-04-28-09 +.. nonce: 5QVEH1 +.. section: Library + +The ``@typing.final`` decorator now sets the ``__final__`` attribute on the +decorated object to allow runtime introspection. Patch by Jelle Zijlstra. + +.. + +.. bpo: 46328 +.. date: 2022-01-10-11-53-15 +.. nonce: 6i9Wvq +.. section: Library + +Added the :meth:`sys.exception` method which returns the active exception +instance. + +.. + +.. bpo: 46307 +.. date: 2022-01-10-07-51-43 +.. nonce: SKvOIY +.. section: Library + +Add :meth:`string.Template.is_valid` and +:meth:`string.Template.get_identifiers` methods. + +.. + +.. bpo: 46306 +.. date: 2022-01-08-13-53-25 +.. nonce: 1_es8z +.. section: Library + +Assume that :class:`types.CodeType` always has +:attr:`types.CodeType.co_firstlineno` in :mod:`doctest`. + +.. + +.. bpo: 40479 +.. date: 2022-01-07-15-20-19 +.. nonce: EKfr3F +.. section: Library + +Fix :mod:`hashlib` *usedforsecurity* option to work correctly with OpenSSL +3.0.0 in FIPS mode. + +.. + +.. bpo: 46070 +.. date: 2022-01-07-13-51-22 +.. nonce: -axLUW +.. section: Library + +Fix possible segfault when importing the :mod:`asyncio` module from +different sub-interpreters in parallel. Patch by Erlend E. Aasland. + +.. + +.. bpo: 46244 +.. date: 2022-01-06-21-31-14 +.. nonce: hjyfJj +.. section: Library + +Removed ``__slots__`` from :class:`typing.ParamSpec` and +:class:`typing.TypeVar`. They served no purpose. Patch by Arie Bovenberg. + +.. + +.. bpo: 46278 +.. date: 2022-01-06-13-38-00 +.. nonce: wILA80 +.. section: Library + +Reflect ``context`` argument in ``AbstractEventLoop.call_*()`` methods. Loop +implementations already support it. + +.. + +.. bpo: 46269 +.. date: 2022-01-05-18-16-13 +.. nonce: K16Z1S +.. section: Library + +Remove special-casing of ``__new__`` in :meth:`enum.Enum.__dir__`. + +.. + +.. bpo: 46266 +.. date: 2022-01-05-12-48-18 +.. nonce: ACQCgX +.. section: Library + +Improve day constants in :mod:`calendar`. + +Now all constants (`MONDAY` ... `SUNDAY`) are documented, tested, and added +to ``__all__``. + +.. + +.. bpo: 46257 +.. date: 2022-01-04-11-04-20 +.. nonce: _o2ADe +.. section: Library + +Optimized the mean, variance, and stdev functions in the statistics module. +If the input is an iterator, it is consumed in a single pass rather than +eating memory by conversion to a list. The single pass algorithm is about +twice as fast as the previous two pass code. + +.. + +.. bpo: 41011 +.. date: 2022-01-03-21-03-50 +.. nonce: uULmGi +.. section: Library + +Added two new variables to *pyvenv.cfg* which is generated by :mod:`venv` +module: *executable* for the executable and *command* for the command line +used to create the environment. + +.. + +.. bpo: 46239 +.. date: 2022-01-03-12-59-20 +.. nonce: ySVSEy +.. section: Library + +Improve error message when importing :mod:`asyncio.windows_events` on +non-Windows. + +.. + +.. bpo: 46238 +.. date: 2022-01-03-12-19-10 +.. nonce: lANhCi +.. section: Library + +Reuse ``_winapi`` constants in ``asyncio.windows_events``. + +.. + +.. bpo: 46222 +.. date: 2022-01-01-17-34-32 +.. nonce: s2fzZU +.. section: Library + +Adding ``SF_NOCACHE`` sendfile constant for FreeBSD for the posixmodule. + +.. + +.. bpo: 37295 +.. date: 2021-12-27-15-52-28 +.. nonce: s3LPo0 +.. section: Library + +Add fast path for ``0 <= k <= n <= 67`` for :func:`math.comb`. + +.. + +.. bpo: 46176 +.. date: 2021-12-25-11-11-21 +.. nonce: EOY9wd +.. section: Library + +Adding the ``MAP_STACK`` constant for the mmap module. + +.. + +.. bpo: 43424 +.. date: 2021-12-23-14-36-58 +.. nonce: d9x2JZ +.. section: Library + +Deprecate :attr:`webbrowser.MacOSXOSAScript._name` and use ``name`` instead. + +.. + +.. bpo: 45321 +.. date: 2021-12-19-00-00-48 +.. nonce: OyuhaY +.. section: Library + +Added missing error codes to module ``xml.parsers.expat.errors``. + +.. + +.. bpo: 46125 +.. date: 2021-12-18-18-29-07 +.. nonce: LLmcox +.. section: Library + +Refactor tests to test traversable API directly. Includes changes from +importlib 5.4.0. + +.. + +.. bpo: 46118 +.. date: 2021-12-17-16-27-44 +.. nonce: euAy0E +.. section: Library + +Moved importlib.resources and its related functionality to a package. + +.. + +.. bpo: 37578 +.. date: 2021-12-17-13-22-37 +.. nonce: _tluuR +.. section: Library + +Add *include_hidden* parameter to :func:`~glob.glob` and :func:`~glob.iglob` +to match hidden files and directories when using special characters like +``*``, ``**``, ``?`` and ``[]``. + +.. + +.. bpo: 20369 +.. date: 2021-12-17-12-06-40 +.. nonce: zzLuBz +.. section: Library + +:func:`concurrent.futures.wait` no longer blocks forever when given +duplicate Futures. Patch by Kumar Aditya. + +.. + +.. bpo: 46105 +.. date: 2021-12-16-14-30-36 +.. nonce: pprB1K +.. section: Library + +Honor spec when generating requirement specs with urls and extras +(importlib_metadata 4.8.3). + +.. + +.. bpo: 44893 +.. date: 2021-12-16-13-54-55 +.. nonce: I7aLiW +.. section: Library + +EntryPoint objects are no longer tuples. Recommended means to access is by +attribute ('.name', '.group') or accessor ('.load()'). Access by index is +deprecated and will raise deprecation warning. + +.. + +.. bpo: 22815 +.. date: 2021-12-16-12-54-21 +.. nonce: 0NRH8s +.. section: Library + +Print unexpected successes together with failures and errors in summary in +:class:`unittest.TextTestResult`. + +.. + +.. bpo: 22047 +.. date: 2021-12-15-19-24-54 +.. nonce: gBV4vT +.. section: Library + +Calling :meth:`add_argument_group` on an argument group is deprecated. +Calling :meth:`add_argument_group` or :meth:`add_mutually_exclusive_group` +on a mutually exclusive group is deprecated. + +These features were never supported and do not always work correctly. The +functions exist on the API by accident through inheritance and will be +removed in the future. + +.. + +.. bpo: 26952 +.. date: 2021-12-14-13-18-45 +.. nonce: hjhISq +.. section: Library + +:mod:`argparse` raises :exc:`ValueError` with clear message when trying to +render usage for an empty mutually exclusive group. Previously it raised a +cryptic :exc:`IndexError`. + +.. + +.. bpo: 45615 +.. date: 2021-12-13-15-51-16 +.. nonce: hVx83Q +.. section: Library + +Functions in the :mod:`traceback` module raise :exc:`TypeError` rather than +:exc:`AttributeError` when an exception argument is not of type +:exc:`BaseException`. + +.. + +.. bpo: 16594 +.. date: 2021-12-12-13-41-47 +.. nonce: yfC7L4 +.. section: Library + +Add allow allow_reuse_port flag in socketserver. + +.. + +.. bpo: 27718 +.. date: 2021-12-11-22-51-30 +.. nonce: MgQiGl +.. section: Library + +Fix help for the :mod:`signal` module. Some functions (e.g. ``signal()`` and +``getsignal()``) were omitted. + +.. + +.. bpo: 46032 +.. date: 2021-12-11-15-45-07 +.. nonce: HmciLT +.. section: Library + +The ``registry()`` method of :func:`functools.singledispatch` functions +checks now the first argument or the first parameter annotation and raises a +TypeError if it is not supported. Previously unsupported "types" were +ignored (e.g. ``typing.List[int]``) or caused an error at calling time (e.g. +``list[int]``). + +.. + +.. bpo: 46014 +.. date: 2021-12-10-03-13-57 +.. nonce: 3xYdST +.. section: Library + +Add ability to use ``typing.Union`` and ``types.UnionType`` as dispatch +argument to ``functools.singledispatch``. Patch provided by Yurii Karabas. + +.. + +.. bpo: 27062 +.. date: 2021-12-09-11-50-32 +.. nonce: R5vii6 +.. section: Library + +Add :attr:`__all__` to :mod:`inspect`, patch by Kumar Aditya. + +.. + +.. bpo: 46018 +.. date: 2021-12-09-00-44-42 +.. nonce: hkTI7v +.. section: Library + +Ensure that :func:`math.expm1` does not raise on underflow. + +.. + +.. bpo: 46016 +.. date: 2021-12-08-19-15-03 +.. nonce: s9PuyF +.. section: Library + +Adding :attr:`F_DUP2FD` and :attr:`F_DUP2FD_CLOEXEC` constants from FreeBSD +into the fcntl module. + +.. + +.. bpo: 45755 +.. date: 2021-12-07-21-55-22 +.. nonce: bRqKGa +.. section: Library + +:mod:`typing` generic aliases now reveal the class attributes of the +original generic class when passed to ``dir()``. This was the behavior up to +Python 3.6, but was changed in 3.7-3.9. + +.. + +.. bpo: 45874 +.. date: 2021-12-02-11-55-45 +.. nonce: dtJIsN +.. section: Library + +The empty query string, consisting of no query arguments, is now handled +correctly in ``urllib.parse.parse_qsl``. This caused problems before when +strict parsing was enabled. + +.. + +.. bpo: 44674 +.. date: 2021-11-29-19-37-20 +.. nonce: NijWLt +.. section: Library + +Change how dataclasses disallows mutable default values. It used to use a +list of known types (list, dict, set). Now it disallows unhashable objects +to be defaults. It's using unhashability as a proxy for mutability. Patch +by Eric V. Smith, idea by Raymond Hettinger. + +.. + +.. bpo: 23882 +.. date: 2021-11-24-19-09-14 +.. nonce: _tctCv +.. section: Library + +Remove namespace package (PEP 420) support from unittest discovery. It was +introduced in Python 3.4 but has been broken since Python 3.7. + +.. + +.. bpo: 25066 +.. date: 2021-11-24-12-25-42 +.. nonce: YIcIkn +.. section: Library + +Added a :meth:`__repr__` method to :class:`multiprocessing.Event` objects, +patch by Kumar Aditya. + +.. + +.. bpo: 45643 +.. date: 2021-10-28-11-40-59 +.. nonce: jeiPiX +.. section: Library + +Added :data:`signal.SIGSTKFLT` on platforms where this signal is defined. + +.. + +.. bpo: 44092 +.. date: 2021-05-19-12-35-49 +.. nonce: hiSlI5 +.. section: Library + +Fetch across rollback no longer raises :exc:`~sqlite3.InterfaceError`. +Instead we leave it to the SQLite library to handle these cases. Patch by +Erlend E. Aasland. + +.. + +.. bpo: 42413 +.. date: 2020-11-26-10-23-46 +.. nonce: HFikOl +.. section: Library + +Replace ``concurrent.futures.TimeoutError`` and ``asyncio.TimeoutError`` +with builtin :exc:`TimeoutError`, keep these names as deprecated aliases. + +.. + +.. bpo: 46196 +.. date: 2021-12-30-19-12-24 +.. nonce: UvQ8Sq +.. section: Documentation + +Document method :meth:`cmd.Cmd.columnize`. + +.. + +.. bpo: 46120 +.. date: 2021-12-21-12-45-57 +.. nonce: PE0DmJ +.. section: Documentation + +State that ``|`` is preferred for readability over ``Union`` in the +:mod:`typing` docs. + +.. + +.. bpo: 46109 +.. date: 2021-12-16-21-13-55 +.. nonce: 0-RNzu +.. section: Documentation + +Extracted ``importlib.resources`` and ``importlib.resources.abc`` +documentation into separate files. + +.. + +.. bpo: 19737 +.. date: 2021-11-28-22-43-21 +.. nonce: cOOubB +.. section: Documentation + +Update the documentation for the :func:`globals` function. + +.. + +.. bpo: 46296 +.. date: 2022-01-08-00-00-38 +.. nonce: vqxgTm +.. section: Tests + +Add a test case for :mod:`enum` with ``_use_args_ == True`` and +``_member_type_ == object``. + +.. + +.. bpo: 46205 +.. date: 2022-01-07-14-06-12 +.. nonce: dnc2OC +.. section: Tests + +Fix hang in runtest_mp due to race condition + +.. + +.. bpo: 46263 +.. date: 2022-01-06-15-45-34 +.. nonce: bJXek6 +.. section: Tests + +Fix test_capi on FreeBSD 14-dev: instruct jemalloc to not fill freed memory +with junk byte. + +.. + +.. bpo: 46262 +.. date: 2022-01-05-01-38-45 +.. nonce: MhiLWP +.. section: Tests + +Cover ``ValueError`` path in tests for :meth:`enum.Flag._missing_`. + +.. + +.. bpo: 46150 +.. date: 2021-12-23-13-42-15 +.. nonce: RhtADs +.. section: Tests + +Now ``fakename`` in ``test_pathlib.PosixPathTest.test_expanduser`` is +checked to be non-existent. + +.. + +.. bpo: 46129 +.. date: 2021-12-19-12-20-57 +.. nonce: I3MunH +.. section: Tests + +Rewrite ``asyncio.locks`` tests with +:class:`unittest.IsolatedAsyncioTestCase` usage. + +.. + +.. bpo: 23819 +.. date: 2021-12-19-08-44-32 +.. nonce: 9ueiII +.. section: Tests + +Fixed :mod:`asyncio` tests in python optimized mode. Patch by Kumar Aditya. + +.. + +.. bpo: 46114 +.. date: 2021-12-17-14-46-19 +.. nonce: 9iyZ_9 +.. section: Tests + +Fix test case for OpenSSL 3.0.1 version. OpenSSL 3.0 uses ``0xMNN00PP0L``. + +.. + +.. bpo: 44133 +.. date: 2022-01-12-13-42-16 +.. nonce: NgyNAh +.. section: Build + +When Python is configured with :option:`--without-static-libpython`, the +Python static library (libpython.a) is no longer built. Patch by Victor +Stinner. + +.. + +.. bpo: 44133 +.. date: 2022-01-12-13-34-52 +.. nonce: HYCNXb +.. section: Build + +When Python is built without :option:`--enable-shared`, the ``python`` +program is now linked to object files, rather than being linked to the +Python static library (libpython.a), to make sure that all symbols are +exported. Previously, the linker omitted some symbols like the +:c:func:`Py_FrozenMain` function. Patch by Victor Stinner. + +.. + +.. bpo: 40280 +.. date: 2022-01-12-10-22-23 +.. nonce: 5maBz8 +.. section: Build + +The ``configure`` script has a new option ``--with-emscripten-target`` to +select browser or node as Emscripten build target. + +.. + +.. bpo: 46315 +.. date: 2022-01-09-15-48-49 +.. nonce: NdCRLu +.. section: Build + +Added and fixed ``#ifdef HAVE_FEATURE`` checks for functionality that is not +available on WASI platform. + +.. + +.. bpo: 45723 +.. date: 2022-01-07-08-33-45 +.. nonce: uq2nBU +.. section: Build + +Fixed a regression in ``configure`` check for :func:`select.epoll`. + +.. + +.. bpo: 46263 +.. date: 2022-01-05-02-58-10 +.. nonce: xiv8NU +.. section: Build + +``configure`` no longer sets ``MULTIARCH`` on FreeBSD platforms. + +.. + +.. bpo: 46106 +.. date: 2021-12-20-07-10-41 +.. nonce: 5qcv3L +.. section: Build + +Updated OpenSSL to 1.1.1m in Windows builds, macOS installer builds, and CI. +Patch by Kumar Aditya. + +.. + +.. bpo: 46088 +.. date: 2021-12-16-14-18-07 +.. nonce: 8UUuAd +.. section: Build + +Automatically detect or install bootstrap Python runtime when building from +Visual Studio. + +.. + +.. bpo: 46072 +.. date: 2021-12-15-10-37-44 +.. nonce: GgeAU3 +.. section: Build + +Add a --with-pystats configure option to turn on internal statistics +gathering. + +.. + +.. bpo: 40280 +.. date: 2021-12-13-21-03-52 +.. nonce: b7NG4Y +.. section: Build + +A new directory ``Tools/wasm`` contains WebAssembly-related helpers like +``config.site`` override for wasm32-emscripten, wasm assets generator to +bundle the stdlib, and a README. + +.. + +.. bpo: 46023 +.. date: 2021-12-09-10-25-11 +.. nonce: PLpNB6 +.. section: Build + +:program:`makesetup` no longer builds extensions that have been marked as +*disabled*. This allows users to disable modules in ``Modules/Setup.local``. + +.. + +.. bpo: 45949 +.. date: 2021-12-02-23-21-18 +.. nonce: OTSo9X +.. section: Build + +Use pure Python ``freeze_module`` for all but importlib bootstrap files. +``--with-freeze-module`` :program:`configure` option is no longer needed for +cross builds. + +.. + +.. bpo: 46217 +.. date: 2022-01-07-22-55-11 +.. nonce: tgJEsB +.. section: Windows + +Removed parameter that is unsupported on Windows 8.1 and early Windows 10 +and may have caused build or runtime failures. + +.. + +.. bpo: 40477 +.. date: 2022-01-02-21-56-53 +.. nonce: W3nnM6 +.. section: macOS + +The Python Launcher app for macOS now properly launches scripts and, if +necessary, the Terminal app when running on recent macOS releases. + +.. + +.. bpo: 46236 +.. date: 2022-01-05-10-16-16 +.. nonce: pcmVQw +.. section: C API + +Fix a bug in :c:func:`PyFunction_GetAnnotations` that caused it to return a +``tuple`` instead of a ``dict``. + +.. + +.. bpo: 46140 +.. date: 2021-12-21-22-56-36 +.. nonce: dvXkYK +.. section: C API + +:c:func:`PyBuffer_GetPointer`, :c:func:`PyBuffer_FromContiguous`, +:c:func:`PyBuffer_ToContiguous` and :c:func:`PyMemoryView_FromBuffer` now +take buffer info by ``const Py_buffer *`` instead of ``Py_buffer *``, as +they do not need mutability. :c:func:`PyBuffer_FromContiguous` also now +takes the source buffer as ``const void *``, and similarly +:c:func:`PyBuffer_GetPointer` takes the strides as ``const Py_ssize_t *``. + +.. + +.. bpo: 45855 +.. date: 2021-12-12-10-09-02 +.. nonce: MVsTDj +.. section: C API + +Document that the *no_block* argument to :c:func:`PyCapsule_Import` is a +no-op now. + +.. + +.. bpo: 45855 +.. date: 2021-12-11-08-41-36 +.. nonce: Lq2_gR +.. section: C API + +Replaced deprecated usage of :c:func:`PyImport_ImportModuleNoBlock` with +:c:func:`PyImport_ImportModule` in stdlib modules. Patch by Kumar Aditya. + +.. + +.. bpo: 46007 +.. date: 2021-12-08-12-41-51 +.. nonce: sMgDLz +.. section: C API + +The :c:func:`PyUnicode_CHECK_INTERNED` macro has been excluded from the +limited C API. It was never usable there, because it used internal +structures which are not available in the limited C API. Patch by Victor +Stinner. diff --git a/Misc/NEWS.d/3.11.0a5.rst b/Misc/NEWS.d/3.11.0a5.rst new file mode 100644 index 00000000000..c28078da8d8 --- /dev/null +++ b/Misc/NEWS.d/3.11.0a5.rst @@ -0,0 +1,986 @@ +.. bpo: 45773 +.. date: 2022-02-01-14-30-56 +.. nonce: Up77LD +.. release date: 2022-02-03 +.. section: Core and Builtins + +Remove two invalid "peephole" optimizations from the bytecode compiler. + +.. + +.. bpo: 46564 +.. date: 2022-02-01-10-23-21 +.. nonce: 6Xc2_H +.. section: Core and Builtins + +Do not create frame objects when creating :class:`super` object. Patch by +Kumar Aditya. + +.. + +.. bpo: 45885 +.. date: 2022-02-01-01-17-28 +.. nonce: CjyNf_ +.. section: Core and Builtins + +Added more fined-grained specialization failure stats regarding the +``COMPARE_OP`` bytecode. + +.. + +.. bpo: 44977 +.. date: 2022-01-30-18-23-08 +.. nonce: BQV_zS +.. section: Core and Builtins + +The delegation of :func:`int` to :meth:`__trunc__` is now deprecated. +Calling ``int(a)`` when ``type(a)`` implements :meth:`__trunc__` but not +:meth:`__int__` or :meth:`__index__` now raises a :exc:`DeprecationWarning`. + +.. + +.. bpo: 46458 +.. date: 2022-01-27-10-49-34 +.. nonce: 5Gm3Gv +.. section: Core and Builtins + +Reorder code emitted by the compiler for a :keyword:`try`-:keyword:`except` +block so that the :keyword:`else` block's code immediately follows the +:keyword:`try` body (without a jump). This is more optimal for the happy +path. + +.. + +.. bpo: 46527 +.. date: 2022-01-25-19-34-55 +.. nonce: mQLNPk +.. section: Core and Builtins + +Allow passing ``iterable`` as a keyword argument to :func:`enumerate` again. +Patch by Jelle Zijlstra. + +.. + +.. bpo: 46528 +.. date: 2022-01-25-17-40-07 +.. nonce: 2Qmni9 +.. section: Core and Builtins + +Replace several stack manipulation instructions (``DUP_TOP``, +``DUP_TOP_TWO``, ``ROT_TWO``, ``ROT_THREE``, ``ROT_FOUR``, and ``ROT_N``) +with new :opcode:`COPY` and :opcode:`SWAP` instructions. + +.. + +.. bpo: 46329 +.. date: 2022-01-25-11-44-17 +.. nonce: SEhynE +.. section: Core and Builtins + +Use two or three bytecodes to implement most calls. + +Calls without named arguments are implemented as a sequence of two +instructions: ``PRECALL; CALL``. Calls with named arguments are implemented +as a sequence of three instructions: ``PRECALL; KW_NAMES; CALL``. There are +two different ``PRECALL`` instructions: ``PRECALL_FUNTION`` and +``PRECALL_METHOD``. The latter pairs with ``LOAD_METHOD``. + +This partition into pre-call and call allows better specialization, and thus +better performance ultimately. + +There is no change in semantics. + +.. + +.. bpo: 46503 +.. date: 2022-01-24-21-24-41 +.. nonce: 4UrPsE +.. section: Core and Builtins + +Fix an assert when parsing some invalid \N escape sequences in f-strings. + +.. + +.. bpo: 46431 +.. date: 2022-01-24-16-58-01 +.. nonce: N6mKAx +.. section: Core and Builtins + +Improve error message on invalid calls to +:meth:`BaseExceptionGroup.__new__`. + +.. + +.. bpo: 46476 +.. date: 2022-01-24-15-39-34 +.. nonce: cvP1Mr +.. section: Core and Builtins + +Fix memory leak in code objects generated by deepfreeze. Patch by Kumar +Aditya. + +.. + +.. bpo: 46481 +.. date: 2022-01-23-06-56-33 +.. nonce: X_FfnB +.. section: Core and Builtins + +Speed up calls to :meth:`weakref.ref.__call__` by using the :pep:`590` +``vectorcall`` calling convention. Patch by Dong-hee Na. + +.. + +.. bpo: 46417 +.. date: 2022-01-22-14-39-23 +.. nonce: 3U5SfN +.. section: Core and Builtins + +Fix a race condition on setting a type ``__bases__`` attribute: the internal +function ``add_subclass()`` now gets the ``PyTypeObject.tp_subclasses`` +member after calling :c:func:`PyWeakref_NewRef` which can trigger a garbage +collection which can indirectly modify ``PyTypeObject.tp_subclasses``. Patch +by Victor Stinner. + +.. + +.. bpo: 46417 +.. date: 2022-01-21-12-24-14 +.. nonce: i3IqMf +.. section: Core and Builtins + +``python -X showrefcount`` now shows the total reference count after +clearing and destroyed the main Python interpreter. Previously, it was shown +before. Patch by Victor Stinner. + +.. + +.. bpo: 43683 +.. date: 2022-01-20-17-13-49 +.. nonce: BqQ26Z +.. section: Core and Builtins + +Add ASYNC_GEN_WRAP opcode to wrap the value to be yielded in async +generators. Removes the need to special case async generators in the +``YIELD_VALUE`` instruction. + +.. + +.. bpo: 46407 +.. date: 2022-01-17-23-12-01 +.. nonce: 2_5a7R +.. section: Core and Builtins + +Optimize some modulo operations in ``Objects/longobject.c``. Patch by +Jeremiah Vivian. + +.. + +.. bpo: 46409 +.. date: 2022-01-17-12-57-27 +.. nonce: HouS6m +.. section: Core and Builtins + +Add new ``RETURN_GENERATOR`` bytecode to make generators. Simplifies calling +Python functions in the VM, as they no longer any need to special case +generator functions. + +Also add ``JUMP_NO_INTERRUPT`` bytecode that acts like ``JUMP_ABSOLUTE``, +but does not check for interrupts. + +.. + +.. bpo: 46406 +.. date: 2022-01-16-15-40-11 +.. nonce: g0mke- +.. section: Core and Builtins + +The integer division ``//`` implementation has been optimized to better let +the compiler understand its constraints. It can be 20% faster on the amd64 +platform when dividing an int by a value smaller than ``2**30``. + +.. + +.. bpo: 46383 +.. date: 2022-01-14-20-55-34 +.. nonce: v8MTl4 +.. section: Core and Builtins + +Fix invalid signature of ``_zoneinfo``'s ``module_free`` function to resolve +a crash on wasm32-emscripten platform. + +.. + +.. bpo: 46361 +.. date: 2022-01-12-17-15-17 +.. nonce: mgI_j_ +.. section: Core and Builtins + +Ensure that "small" integers created by :meth:`int.from_bytes` and +:class:`decimal.Decimal` are properly cached. + +.. + +.. bpo: 46161 +.. date: 2021-12-23-12-32-45 +.. nonce: EljBmu +.. section: Core and Builtins + +Fix the class building error when the arguments are constants and +CALL_FUNCTION_EX is used. + +.. + +.. bpo: 46028 +.. date: 2021-12-16-15-04-58 +.. nonce: zfWacB +.. section: Core and Builtins + +Fixes calculation of :data:`sys._base_executable` when inside a virtual +environment that uses symlinks with different binary names than the base +environment provides. + +.. + +.. bpo: 46091 +.. date: 2021-12-16-00-24-00 +.. nonce: rJ_e_e +.. section: Core and Builtins + +Correctly calculate indentation levels for lines with whitespace character +that are ended by line continuation characters. Patch by Pablo Galindo + +.. + +.. bpo: 30512 +.. date: 2021-12-12-00-49-19 +.. nonce: nU9E9V +.. section: Core and Builtins + +Add CAN Socket support for NetBSD. + +.. + +.. bpo: 46045 +.. date: 2021-12-11-11-36-48 +.. nonce: sfThay +.. section: Core and Builtins + +Do not use POSIX semaphores on NetBSD + +.. + +.. bpo: 44024 +.. date: 2021-05-04-21-55-49 +.. nonce: M9m8Qd +.. section: Core and Builtins + +Improve the exc:`TypeError` message for non-string second arguments passed +to the built-in functions :func:`getattr` and :func:`hasattr`. Patch by Géry +Ogam. + +.. + +.. bpo: 46624 +.. date: 2022-02-03-12-07-41 +.. nonce: f_Qqh0 +.. section: Library + +Restore support for non-integer arguments of :func:`random.randrange` and +:func:`random.randint`. + +.. + +.. bpo: 46591 +.. date: 2022-01-31-15-40-38 +.. nonce: prBD1M +.. section: Library + +Make the IDLE doc URL on the About IDLE dialog clickable. + +.. + +.. bpo: 46565 +.. date: 2022-01-28-19-48-31 +.. nonce: bpZXO4 +.. section: Library + +Remove loop variables that are leaking into modules' namespaces. + +.. + +.. bpo: 46553 +.. date: 2022-01-28-08-47-53 +.. nonce: f7Uc96 +.. section: Library + +In :func:`typing.get_type_hints`, support evaluating bare stringified +``ClassVar`` annotations. Patch by Gregory Beauregard. + +.. + +.. bpo: 46544 +.. date: 2022-01-27-13-30-02 +.. nonce: oFDVWj +.. section: Library + +Don't leak ``x`` & ``uspace`` intermediate vars in +:class:`textwrap.TextWrapper`. + +.. + +.. bpo: 46487 +.. date: 2022-01-27-12-24-38 +.. nonce: UDkN2z +.. section: Library + +Add the ``get_write_buffer_limits`` method to +:class:`asyncio.transports.WriteTransport` and to the SSL transport. + +.. + +.. bpo: 45173 +.. date: 2022-01-27-11-16-59 +.. nonce: wreRF2 +.. section: Library + +Note the configparser deprecations will be removed in Python 3.12. + +.. + +.. bpo: 45162 +.. date: 2022-01-26-23-58-48 +.. nonce: 4Jmg_j +.. section: Library + +The deprecated :mod:`unittest` APIs removed in 3.11a1 have been temporarily +restored to be removed in 3.12 while cleanups in external projects go in. + +.. + +.. bpo: 46539 +.. date: 2022-01-26-20-36-30 +.. nonce: 23iW1d +.. section: Library + +In :func:`typing.get_type_hints`, support evaluating stringified +``ClassVar`` and ``Final`` annotations inside ``Annotated``. Patch by +Gregory Beauregard. + +.. + +.. bpo: 46510 +.. date: 2022-01-25-10-59-41 +.. nonce: PM5svI +.. section: Library + +Add missing test for :class:`types.TracebackType` and +:class:`types.FrameType`. Calculate them directly from the caught exception +without calling :func:`sys.exc_info`. + +.. + +.. bpo: 46491 +.. date: 2022-01-24-23-55-30 +.. nonce: jmIKHo +.. section: Library + +Allow :data:`typing.Annotated` to wrap :data:`typing.Final` and +:data:`typing.ClassVar`. Patch by Gregory Beauregard. + +.. + +.. bpo: 46483 +.. date: 2022-01-24-13-00-09 +.. nonce: 9XnmKp +.. section: Library + +Remove :meth:`~object.__class_getitem__` from :class:`pathlib.PurePath` as +this class was not supposed to be generic. + +.. + +.. bpo: 46436 +.. date: 2022-01-23-19-37-00 +.. nonce: Biz1p9 +.. section: Library + +Fix command-line option ``-d``/``--directory`` in module :mod:`http.server` +which is ignored when combined with command-line option ``--cgi``. Patch by +Géry Ogam. + +.. + +.. bpo: 41403 +.. date: 2022-01-23-18-04-45 +.. nonce: SgoHqV +.. section: Library + +Make :meth:`mock.patch` raise a :exc:`TypeError` with a relevant error +message on invalid arg. Previously it allowed a cryptic +:exc:`AttributeError` to escape. + +.. + +.. bpo: 46474 +.. date: 2022-01-22-14-49-10 +.. nonce: eKQhvx +.. section: Library + +In ``importlib.metadata.EntryPoint.pattern``, avoid potential REDoS by +limiting ambiguity in consecutive whitespace. + +.. + +.. bpo: 46474 +.. date: 2022-01-22-14-45-46 +.. nonce: 2DUC62 +.. section: Library + +Removed private method from ``importlib.metadata.Path``. Sync with +importlib_metadata 4.10.0. + +.. + +.. bpo: 46470 +.. date: 2022-01-22-13-17-35 +.. nonce: MnNhgU +.. section: Library + +Remove unused branch from ``typing._remove_dups_flatten`` + +.. + +.. bpo: 46469 +.. date: 2022-01-22-05-05-08 +.. nonce: plUab5 +.. section: Library + +:mod:`asyncio` generic classes now return :class:`types.GenericAlias` in +``__class_getitem__`` instead of the same class. + +.. + +.. bpo: 41906 +.. date: 2022-01-21-18-19-45 +.. nonce: YBaquj +.. section: Library + +Support passing filter instances in the ``filters`` values of ``handlers`` +and ``loggers`` in the dictionary passed to +:func:`logging.config.dictConfig`. + +.. + +.. bpo: 46422 +.. date: 2022-01-20-10-35-50 +.. nonce: 1UAEHL +.. section: Library + +Use ``dis.Positions`` in ``dis.Instruction`` instead of a regular ``tuple``. + +.. + +.. bpo: 46434 +.. date: 2022-01-20-10-35-10 +.. nonce: geS-aP +.. section: Library + +:mod:`pdb` now gracefully handles ``help`` when :attr:`__doc__` is missing, +for example when run with pregenerated optimized ``.pyc`` files. + +.. + +.. bpo: 43869 +.. date: 2022-01-18-17-24-21 +.. nonce: NayN12 +.. section: Library + +Python uses the same time Epoch on all platforms. Add an explicit unit test +to ensure that it's the case. Patch by Victor Stinner. + +.. + +.. bpo: 46414 +.. date: 2022-01-17-10-00-02 +.. nonce: Ld0b_y +.. section: Library + +Add :func:`typing.reveal_type`. Patch by Jelle Zijlstra. + +.. + +.. bpo: 40280 +.. date: 2022-01-16-14-07-14 +.. nonce: LtFHfF +.. section: Library + +:mod:`subprocess` now imports Windows-specific imports when ``msvcrt`` +module is available, and POSIX-specific imports on all other platforms. This +gives a clean exception when ``_posixsubprocess`` is not available (e.g. +Emscripten browser target). + +.. + +.. bpo: 40066 +.. date: 2022-01-13-11-41-24 +.. nonce: 1QuVli +.. section: Library + +``IntEnum``, ``IntFlag``, and ``StrEnum`` use the mixed-in type for their +``str()`` and ``format()`` output. + +.. + +.. bpo: 46316 +.. date: 2022-01-09-15-04-56 +.. nonce: AMTyd0 +.. section: Library + +Optimize :meth:`pathlib.Path.iterdir` by removing an unnecessary check for +special entries. + +.. + +.. bpo: 29688 +.. date: 2022-01-05-03-21-21 +.. nonce: W06bSH +.. section: Library + +Document :meth:`pathlib.Path.absolute` (which has always existed). + +.. + +.. bpo: 43012 +.. date: 2022-01-05-03-09-29 +.. nonce: RVhLIL +.. section: Library + +The pathlib module's obsolete and internal ``_Accessor`` class has been +removed to prepare the terrain for upcoming enhancements to the module. + +.. + +.. bpo: 46258 +.. date: 2022-01-04-18-05-25 +.. nonce: DYgwRo +.. section: Library + +Speed up :func:`math.isqrt` for small positive integers by replacing two +division steps with a lookup table. + +.. + +.. bpo: 46242 +.. date: 2022-01-03-16-25-06 +.. nonce: f4l_CL +.. section: Library + +Improve error message when creating a new :class:`enum.Enum` type +subclassing an existing ``Enum`` with ``_member_names_`` using +:meth:`enum.Enum.__call__`. + +.. + +.. bpo: 43118 +.. date: 2021-12-29-14-42-09 +.. nonce: BoVi_5 +.. section: Library + +Fix a bug in :func:`inspect.signature` that was causing it to fail on some +subclasses of classes with a ``__text_signature__`` referencing module +globals. Patch by Weipeng Hong. + +.. + +.. bpo: 26552 +.. date: 2021-12-29-13-42-55 +.. nonce: 1BqeAn +.. section: Library + +Fixed case where failing :func:`asyncio.ensure_future` did not close the +coroutine. Patch by Kumar Aditya. + +.. + +.. bpo: 21987 +.. date: 2021-12-28-11-55-10 +.. nonce: avBK-p +.. section: Library + +Fix an issue with :meth:`tarfile.TarFile.getmember` getting a directory name +with a trailing slash. + +.. + +.. bpo: 46124 +.. date: 2021-12-18-18-41-30 +.. nonce: ESPrb7 +.. section: Library + +Update :mod:`zoneinfo` to rely on importlib.resources traversable API. + +.. + +.. bpo: 46103 +.. date: 2021-12-16-23-42-54 +.. nonce: LMnZAN +.. section: Library + +Now :func:`inspect.getmembers` only gets :attr:`__bases__` attribute from +class type. Patch by Weipeng Hong. + +.. + +.. bpo: 46080 +.. date: 2021-12-15-06-29-00 +.. nonce: AuQpLt +.. section: Library + +Fix exception in argparse help text generation if a +:class:`argparse.BooleanOptionalAction` argument's default is +``argparse.SUPPRESS`` and it has ``help`` specified. Patch by Felix +Fontein. + +.. + +.. bpo: 44791 +.. date: 2021-07-31-23-18-50 +.. nonce: 4jFdpO +.. section: Library + +Fix substitution of :class:`~typing.ParamSpec` in +:data:`~typing.Concatenate` with different parameter expressions. +Substitution with a list of types returns now a tuple of types. Substitution +with ``Concatenate`` returns now a ``Concatenate`` with concatenated lists +of arguments. + +.. + +.. bpo: 46463 +.. date: 2022-01-21-21-33-48 +.. nonce: fBbdTG +.. section: Documentation + +Fixes :file:`escape4chm.py` script used when building the CHM documentation +file + +.. + +.. bpo: 43478 +.. date: 2022-02-03-00-21-32 +.. nonce: 0nfcam +.. section: Tests + +Mocks can no longer be provided as the specs for other Mocks. As a result, +an already-mocked object cannot be passed to `mock.Mock()`. This can uncover +bugs in tests since these Mock-derived Mocks will always pass certain tests +(e.g. isinstance) and builtin assert functions (e.g. +assert_called_once_with) will unconditionally pass. + +.. + +.. bpo: 46616 +.. date: 2022-02-02-18-14-38 +.. nonce: URvBtE +.. section: Tests + +Ensures ``test_importlib.test_windows`` cleans up registry keys after +completion. + +.. + +.. bpo: 44359 +.. date: 2022-02-02-02-24-04 +.. nonce: kPPSmN +.. section: Tests + +test_ftplib now silently ignores socket errors to prevent logging unhandled +threading exceptions. Patch by Victor Stinner. + +.. + +.. bpo: 46600 +.. date: 2022-02-01-17-13-53 +.. nonce: FMCk8Z +.. section: Tests + +Fix test_gdb.test_pycfunction() for Python built with ``clang -Og``. +Tolerate inlined functions in the gdb traceback. Patch by Victor Stinner. + +.. + +.. bpo: 46542 +.. date: 2022-01-31-17-34-13 +.. nonce: RTMm1T +.. section: Tests + +Fix a Python crash in test_lib2to3 when using Python built in debug mode: +limit the recursion limit. Patch by Victor Stinner. + +.. + +.. bpo: 46576 +.. date: 2022-01-29-12-37-53 +.. nonce: -prRaV +.. section: Tests + +test_peg_generator now disables compiler optimization when testing +compilation of its own C extensions to significantly speed up the testing on +non-debug builds of CPython. + +.. + +.. bpo: 46542 +.. date: 2022-01-28-01-17-10 +.. nonce: xRLTdj +.. section: Tests + +Fix ``test_json`` tests checking for :exc:`RecursionError`: modify these +tests to use ``support.infinite_recursion()``. Patch by Victor Stinner. + +.. + +.. bpo: 13886 +.. date: 2022-01-17-13-10-04 +.. nonce: 5mZH4b +.. section: Tests + +Skip test_builtin PTY tests on non-ASCII characters if the readline module +is loaded. The readline module changes input() behavior, but test_builtin is +not intented to test the readline module. Patch by Victor Stinner. + +.. + +.. bpo: 40280 +.. date: 2022-01-16-14-11-57 +.. nonce: fNnFfx +.. section: Tests + +Add :func:`test.support.requires_fork` decorators to mark tests that require +a working :func:`os.fork`. + +.. + +.. bpo: 40280 +.. date: 2022-01-14-23-22-41 +.. nonce: nHLWoD +.. section: Tests + +Add :func:`test.support.requires_subprocess` decorator to mark tests which +require working :mod:`subprocess` module or ``os.spawn*``. The +wasm32-emscripten platform has no support for processes. + +.. + +.. bpo: 46126 +.. date: 2021-12-18-22-23-50 +.. nonce: 0LH3Yb +.. section: Tests + +Disable 'descriptions' when running tests internally. + +.. + +.. bpo: 46602 +.. date: 2022-02-02-02-06-07 +.. nonce: 8GaOZ2 +.. section: Build + +Tidied up configure.ac so that conftest.c is truncated rather than appended. +This assists in the case where the 'rm' of conftest.c fails to happen +between tests. Downstream issues such as a clobbered SOABI can result. + +.. + +.. bpo: 46600 +.. date: 2022-02-01-14-07-37 +.. nonce: NNLnfj +.. section: Build + +Fix the test checking if the C compiler supports ``-Og`` option in the +``./configure`` script to also use ``-Og`` on clang which supports it. Patch +by Victor Stinner. + +.. + +.. bpo: 38472 +.. date: 2022-01-26-22-59-12 +.. nonce: RxfLho +.. section: Build + +Fix GCC detection in setup.py when cross-compiling. The C compiler is now +run with LC_ALL=C. Previously, the detection failed with a German locale. + +.. + +.. bpo: 46513 +.. date: 2022-01-25-12-32-37 +.. nonce: mPm9B4 +.. section: Build + +:program:`configure` no longer uses ``AC_C_CHAR_UNSIGNED`` macro and +``pyconfig.h`` no longer defines reserved symbol ``__CHAR_UNSIGNED__``. + +.. + +.. bpo: 46471 +.. date: 2022-01-22-11-06-23 +.. nonce: 03snrE +.. section: Build + +Use global singletons for single byte bytes objects in deepfreeze. + +.. + +.. bpo: 46443 +.. date: 2022-01-20-05-27-07 +.. nonce: udCVII +.. section: Build + +Deepfreeze now uses cached small integers as it saves some space for common +small integers. + +.. + +.. bpo: 46429 +.. date: 2022-01-19-04-36-15 +.. nonce: y0OtVL +.. section: Build + +Merge all deep-frozen files into one for space savings. Patch by Kumar +Aditya. + +.. + +.. bpo: 45569 +.. date: 2022-01-09-11-24-54 +.. nonce: zCIENy +.. section: Build + +The build now defaults to using 30-bit digits for Python integers. +Previously either 15-bit or 30-bit digits would be selected, depending on +the platform. 15-bit digits may still be selected using the +``--enable-big-digits=15`` option to the ``configure`` script, or by +defining ``PYLONG_BITS_IN_DIGIT`` in ``pyconfig.h``. + +.. + +.. bpo: 45925 +.. date: 2022-01-08-12-43-31 +.. nonce: 38F3NO +.. section: Build + +Update Windows installer to use SQLite 3.37.2. + +.. + +.. bpo: 43112 +.. date: 2021-02-10-17-54-04 +.. nonce: H5Lat6 +.. section: Build + +Detect musl libc as a separate SOABI (tagged as ``linux-musl``). + +.. + +.. bpo: 33125 +.. date: 2022-01-25-14-48-39 +.. nonce: 5WyY_J +.. section: Windows + +The traditional EXE/MSI based installer for Windows is now available for +ARM64 + +.. + +.. bpo: 46362 +.. date: 2022-01-13-22-31-09 +.. nonce: f2cuEb +.. section: Windows + +os.path.abspath("C:\CON") is now fixed to return "\\.\CON", not the same +path. The regression was true of all legacy DOS devices such as COM1, LPT1, +or NUL. + +.. + +.. bpo: 44934 +.. date: 2021-09-01-10-48-11 +.. nonce: W1xPATH +.. section: Windows + +The installer now offers a command-line only option to add the installation +directory to the end of :envvar:`PATH` instead of at the start. + +.. + +.. bpo: 45925 +.. date: 2022-01-26-12-04-09 +.. nonce: yBSiYO +.. section: macOS + +Update macOS installer to SQLite 3.37.2. + +.. + +.. bpo: 45296 +.. date: 2022-01-26-19-33-55 +.. nonce: LzZKdU +.. section: IDLE + +Clarify close, quit, and exit in IDLE. In the File menu, 'Close' and 'Exit' +are now 'Close Window' (the current one) and 'Exit' is now 'Exit IDLE' (by +closing all windows). In Shell, 'quit()' and 'exit()' mean 'close Shell'. +If there are no other windows, this also exits IDLE. + +.. + +.. bpo: 40170 +.. date: 2022-01-27-02-51-22 +.. nonce: uPolek +.. section: C API + +Remove the ``PyHeapType_GET_MEMBERS()`` macro. It was exposed in the public +C API by mistake, it must only be used by Python internally. Use the +``PyTypeObject.tp_members`` member instead. Patch by Victor Stinner. + +.. + +.. bpo: 40170 +.. date: 2022-01-27-02-37-18 +.. nonce: XxQB0i +.. section: C API + +Move _Py_GetAllocatedBlocks() and _PyObject_DebugMallocStats() private +functions to the internal C API. Patch by Victor Stinner. + +.. + +.. bpo: 46433 +.. date: 2022-01-19-16-51-54 +.. nonce: Er9ApS +.. section: C API + +The internal function _PyType_GetModuleByDef now correctly handles +inheritance patterns involving static types. + +.. + +.. bpo: 45459 +.. date: 2021-10-18-16-54-24 +.. nonce: Y1pEZs +.. section: C API + +:c:type:`Py_buffer` and various ``Py_buffer`` related functions are now part +of the limited API and stable ABI. + +.. + +.. bpo: 14916 +.. date: 2020-09-11-02-50-41 +.. nonce: QN1Y03 +.. section: C API + +Fixed bug in the tokenizer that prevented ``PyRun_InteractiveOne`` from +parsing from the provided FD. diff --git a/Misc/NEWS.d/3.11.0a6.rst b/Misc/NEWS.d/3.11.0a6.rst new file mode 100644 index 00000000000..68b80e46690 --- /dev/null +++ b/Misc/NEWS.d/3.11.0a6.rst @@ -0,0 +1,1206 @@ +.. bpo: 46940 +.. date: 2022-03-06-20-16-13 +.. nonce: _X47Hx +.. release date: 2022-03-07 +.. section: Core and Builtins + +Avoid overriding :exc:`AttributeError` metadata information for nested +attribute access calls. Patch by Pablo Galindo. + +.. + +.. bpo: 46927 +.. date: 2022-03-05-12-23-58 +.. nonce: URbHBi +.. section: Core and Builtins + +Include the type's name in the error message for subscripting non-generic +types. + +.. + +.. bpo: 46921 +.. date: 2022-03-05-00-43-22 +.. nonce: tyuPeB +.. section: Core and Builtins + +Support vectorcall for ``super()``. Patch by Ken Jin. + +.. + +.. bpo: 46841 +.. date: 2022-03-03-14-31-53 +.. nonce: agf-3X +.. section: Core and Builtins + +Fix incorrect handling of inline cache entries when specializing +:opcode:`BINARY_OP`. + +.. + +.. bpo: 46841 +.. date: 2022-03-03-12-36-15 +.. nonce: apPev2 +.. section: Core and Builtins + +Use an oparg to simplify the construction of helpful error messages in +:opcode:`GET_AWAITABLE`. + +.. + +.. bpo: 46903 +.. date: 2022-03-03-12-02-41 +.. nonce: OzgaFZ +.. section: Core and Builtins + +Make sure that str subclasses can be used as attribute names for instances +with virtual dictionaries. Fixes regression in 3.11alpha + +.. + +.. bpo: 46841 +.. date: 2022-03-03-10-46-13 +.. nonce: 7CkuZx +.. section: Core and Builtins + +Add more detailed specialization failure stats for :opcode:`COMPARE_OP` +followed by :opcode:`EXTENDED_ARG`. + +.. + +.. bpo: 46891 +.. date: 2022-03-02-15-04-08 +.. nonce: aIAgTD +.. section: Core and Builtins + +Fix bug introduced during 3.11alpha where subclasses of ``types.ModuleType`` +with ``__slots__`` were not initialized correctly, resulting in an +interpreter crash. + +.. + +.. bpo: 46841 +.. date: 2022-03-01-17-47-58 +.. nonce: inYQlU +.. section: Core and Builtins + +Use inline caching for :opcode:`LOAD_ATTR`, :opcode:`LOAD_METHOD`, and +:opcode:`STORE_ATTR`. + +.. + +.. bpo: 46841 +.. date: 2022-02-28-15-46-36 +.. nonce: MDQoty +.. section: Core and Builtins + +Use inline cache for :opcode:`BINARY_SUBSCR`. + +.. + +.. bpo: 46841 +.. date: 2022-02-28-12-01-04 +.. nonce: r60AMJ +.. section: Core and Builtins + +Use inline caching for :opcode:`COMPARE_OP`. + +.. + +.. bpo: 46864 +.. date: 2022-02-26-19-26-36 +.. nonce: EmLgFp +.. section: Core and Builtins + +Deprecate ``PyBytesObject.ob_shash``. It will be removed in Python 3.13. + +.. + +.. bpo: 46841 +.. date: 2022-02-25-15-18-40 +.. nonce: tmLpgC +.. section: Core and Builtins + +Use inline caching for :opcode:`UNPACK_SEQUENCE`. + +.. + +.. bpo: 46845 +.. date: 2022-02-25-14-57-21 +.. nonce: TUvaMG +.. section: Core and Builtins + +Reduces dict size by removing hash value from hash table when all inserted +keys are Unicode. For example, ``sys.getsizeof(dict.fromkeys("abcdefg"))`` +becomes 272 bytes from 352 bytes on 64bit platform. + +.. + +.. bpo: 46841 +.. date: 2022-02-25-13-18-18 +.. nonce: 86QiQu +.. section: Core and Builtins + +Use inline cache for :opcode:`LOAD_GLOBAL`. + +.. + +.. bpo: 46852 +.. date: 2022-02-25-02-01-42 +.. nonce: _3zg8D +.. section: Core and Builtins + +Rename the private undocumented ``float.__set_format__()`` method to +``float.__setformat__()`` to fix a typo introduced in Python 3.7. The method +is only used by test_float. Patch by Victor Stinner. + +.. + +.. bpo: 46852 +.. date: 2022-02-25-01-42-45 +.. nonce: nkRDvV +.. section: Core and Builtins + +Remove the undocumented private ``float.__set_format__()`` method, +previously known as ``float.__setformat__()`` in Python 3.7. Its docstring +said: "You probably don't want to use this function. It exists mainly to be +used in Python's test suite." Patch by Victor Stinner. + +.. + +.. bpo: 40116 +.. date: 2022-02-24-16-34-17 +.. nonce: AeVGG2 +.. section: Core and Builtins + +Fix regression that dict.update(other) may don't respect iterate order of +other when other is key sharing dict. + +.. + +.. bpo: 46712 +.. date: 2022-02-24-07-50-43 +.. nonce: pw7vQV +.. section: Core and Builtins + +Share global string identifiers in deep-frozen modules. + +.. + +.. bpo: 46430 +.. date: 2022-02-24-07-33-29 +.. nonce: c91TAg +.. section: Core and Builtins + +Fix memory leak in interned strings of deep-frozen modules. + +.. + +.. bpo: 46841 +.. date: 2022-02-23-18-17-30 +.. nonce: fns8HB +.. section: Core and Builtins + +Store :opcode:`BINARY_OP` caches inline using a new :opcode:`CACHE` +instruction. + +.. + +.. bpo: 45107 +.. date: 2022-02-23-15-26-02 +.. nonce: axcgHn +.. section: Core and Builtins + +Specialize ``LOAD_METHOD`` for instances with a dict. + +.. + +.. bpo: 44337 +.. date: 2022-02-22-17-19-45 +.. nonce: XA-egu +.. section: Core and Builtins + +Reduce the memory usage of specialized :opcode:`LOAD_ATTR` and +:opcode:`STORE_ATTR` instructions. + +.. + +.. bpo: 46729 +.. date: 2022-02-22-17-18-36 +.. nonce: ZwGTFq +.. section: Core and Builtins + +Add number of sub-exceptions to :meth:`BaseException.__str__`. + +.. + +.. bpo: 45885 +.. date: 2022-02-22-15-48-32 +.. nonce: W2vkaI +.. section: Core and Builtins + +Don't un-adapt :opcode:`COMPARE_OP` when collecting specialization stats. + +.. + +.. bpo: 46329 +.. date: 2022-02-22-14-03-56 +.. nonce: RX_AzJ +.. section: Core and Builtins + +Fix specialization stats gathering for :opcode:`PRECALL` instructions. + +.. + +.. bpo: 46794 +.. date: 2022-02-22-12-07-53 +.. nonce: 6WvJ9o +.. section: Core and Builtins + +Bump up the libexpat version into 2.4.6 + +.. + +.. bpo: 46823 +.. date: 2022-02-22-05-14-25 +.. nonce: z9NZC9 +.. section: Core and Builtins + +Implement a specialized combined opcode +``LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE``. Patch by Dennis Sweeney. + +.. + +.. bpo: 46820 +.. date: 2022-02-21-21-55-23 +.. nonce: 4RfUZh +.. section: Core and Builtins + +Fix parsing a numeric literal immediately (without spaces) followed by "not +in" keywords, like in ``1not in x``. Now the parser only emits a warning, +not a syntax error. + +.. + +.. bpo: 46329 +.. date: 2022-02-21-10-29-20 +.. nonce: cbkt7u +.. section: Core and Builtins + +Move ``KW_NAMES`` before ``PRECALL`` instruction in call sequence. Change +``operand`` of ``CALL`` to match ``PRECALL`` for easier specialization. + +.. + +.. bpo: 46808 +.. date: 2022-02-20-23-10-14 +.. nonce: vouNSF +.. section: Core and Builtins + +Remove the ``NEXT_BLOCK`` macro from compile.c, and make the compiler +automatically generate implicit blocks when they are needed. + +.. + +.. bpo: 46329 +.. date: 2022-02-16-13-15-16 +.. nonce: 8aIuz9 +.. section: Core and Builtins + +Add ``PUSH_NULL`` instruction. This is used as a prefix when evaluating a +callable, so that the stack has the same shape for methods and other calls. +``PRECALL_FUNCTION`` and ``PRECALL_METHOD`` are merged into a single +``PRECALL`` instruction. + +There is no change in semantics. + +.. + +.. bpo: 46762 +.. date: 2022-02-15-20-26-46 +.. nonce: 1H7vab +.. section: Core and Builtins + +Fix an assert failure in debug builds when a '<', '>', or '=' is the last +character in an f-string that's missing a closing right brace. + +.. + +.. bpo: 46730 +.. date: 2022-02-14-21-04-43 +.. nonce: rYJ1w5 +.. section: Core and Builtins + +Message of AttributeError caused by getting, setting or deleting a property +without the corresponding function now mentions that the attribute is in +fact a property and also specifies type of the class that it belongs to. + +.. + +.. bpo: 46724 +.. date: 2022-02-14-14-44-06 +.. nonce: jym_K6 +.. section: Core and Builtins + +Make sure that all backwards jumps use the ``JUMP_ABSOLUTE`` instruction, +rather than ``JUMP_FORWARD`` with an argument of ``(2**32)+offset``. + +.. + +.. bpo: 46732 +.. date: 2022-02-12-11-16-40 +.. nonce: 3Z_qxd +.. section: Core and Builtins + +Correct the docstring for the :meth:`__bool__` method. Patch by Jelle +Zijlstra. + +.. + +.. bpo: 46072 +.. date: 2022-02-11-13-47-58 +.. nonce: PDS6Ke +.. section: Core and Builtins + +Add more detailed specialization failure statistics for :opcode:`BINARY_OP`. + +.. + +.. bpo: 46707 +.. date: 2022-02-10-03-13-18 +.. nonce: xeSEh0 +.. section: Core and Builtins + +Avoid potential exponential backtracking when producing some syntax errors +involving lots of brackets. Patch by Pablo Galindo. + +.. + +.. bpo: 46323 +.. date: 2022-02-10-02-29-12 +.. nonce: HK_cs0 +.. section: Core and Builtins + +:mod:`ctypes` now allocates memory on the stack instead of on the heap to +pass arguments while calling a Python callback function. Patch by Dong-hee +Na. + +.. + +.. bpo: 45923 +.. date: 2022-02-09-20-21-43 +.. nonce: tJ4gDX +.. section: Core and Builtins + +Add a quickened form of :opcode:`RESUME` that skips quickening checks. + +.. + +.. bpo: 46702 +.. date: 2022-02-09-16-36-11 +.. nonce: LcaEuC +.. section: Core and Builtins + +Specialize :opcode:`UNPACK_SEQUENCE` for :class:`tuple` and :class:`list` +unpackings. + +.. + +.. bpo: 46072 +.. date: 2022-02-07-14-38-54 +.. nonce: 6ebLyN +.. section: Core and Builtins + +Opcode pair stats are now gathered with ``--enable-pystats``. Defining +``DYNAMIC_EXECUTION_PROFILE`` or ``DXPAIRS`` no longer has any effect. + +.. + +.. bpo: 46675 +.. date: 2022-02-07-14-33-45 +.. nonce: ZPbdMp +.. section: Core and Builtins + +Allow more than 16 items in a split dict before it is combined. The limit is +now 254. + +.. + +.. bpo: 40479 +.. date: 2022-02-06-23-08-30 +.. nonce: zED3Zu +.. section: Core and Builtins + +Add a missing call to ``va_end()`` in ``Modules/_hashopenssl.c``. + +.. + +.. bpo: 46323 +.. date: 2022-02-05-14-46-21 +.. nonce: FC1OJg +.. section: Core and Builtins + +Use :c:func:`PyObject_Vectorcall` while calling ctypes callback function. +Patch by Dong-hee Na. + +.. + +.. bpo: 46615 +.. date: 2022-02-04-04-33-18 +.. nonce: puArY9 +.. section: Core and Builtins + +When iterating over sets internally in ``setobject.c``, acquire strong +references to the resulting items from the set. This prevents crashes in +corner-cases of various set operations where the set gets mutated. + +.. + +.. bpo: 45828 +.. date: 2022-01-27-14-20-18 +.. nonce: kzk4fl +.. section: Core and Builtins + +The bytecode compiler now attempts to apply runtime stack manipulations at +compile-time (whenever it is feasible to do so). + +.. + +.. bpo: 30496 +.. date: 2022-01-09-11-59-04 +.. nonce: KvuuGT +.. section: Core and Builtins + +Fixed a minor portability issue in the implementation of +:c:func:`PyLong_FromLong`, and added a fast path for single-digit integers +to :c:func:`PyLong_FromLongLong`. + +.. + +.. bpo: 25707 +.. date: 2022-03-05-09-43-53 +.. nonce: gTlclP +.. section: Library + +Fixed a file leak in :func:`xml.etree.ElementTree.iterparse` when the +iterator is not exhausted. Patch by Jacob Walls. + +.. + +.. bpo: 46877 +.. date: 2022-03-03-06-58-52 +.. nonce: BKgjpD +.. section: Library + +Export :func:`unittest.doModuleCleanups` in :mod:`unittest`. Patch by Kumar +Aditya. + +.. + +.. bpo: 46848 +.. date: 2022-03-01-01-16-13 +.. nonce: BB01Fr +.. section: Library + +For performance, use the optimized string-searching implementations from +:meth:`~bytes.find` and :meth:`~bytes.rfind` for :meth:`~mmap.find` and +:meth:`~mmap.rfind`. + +.. + +.. bpo: 46736 +.. date: 2022-02-24-01-49-38 +.. nonce: NJcoWO +.. section: Library + +:class:`~http.server.SimpleHTTPRequestHandler` now uses HTML5 grammar. Patch +by Dong-hee Na. + +.. + +.. bpo: 44886 +.. date: 2022-02-23-00-55-59 +.. nonce: I40Mbr +.. section: Library + +Inherit asyncio proactor datagram transport from +:class:`asyncio.DatagramTransport`. + +.. + +.. bpo: 46827 +.. date: 2022-02-22-15-08-30 +.. nonce: hvj38S +.. section: Library + +Support UDP sockets in :meth:`asyncio.loop.sock_connect` for selector-based +event loops. Patch by Thomas Grainger. + +.. + +.. bpo: 46811 +.. date: 2022-02-20-21-03-31 +.. nonce: 8BxgdQ +.. section: Library + +Make test suite support Expat >=2.4.5 + +.. + +.. bpo: 46252 +.. date: 2022-02-20-12-59-46 +.. nonce: KG1SqA +.. section: Library + +Raise :exc:`TypeError` if :class:`ssl.SSLSocket` is passed to +transport-based APIs. + +.. + +.. bpo: 46784 +.. date: 2022-02-18-22-10-30 +.. nonce: SVOQJx +.. section: Library + +Fix libexpat symbols collisions with user dynamically loaded or statically +linked libexpat in embedded Python. + +.. + +.. bpo: 46786 +.. date: 2022-02-18-12-10-26 +.. nonce: P0xRvS +.. section: Library + +The HTML serialisation in xml.etree.ElementTree now writes ``embed``, +``source``, ``track`` and ``wbr`` as empty tags, as defined in HTML 5. + +.. + +.. bpo: 39327 +.. date: 2022-02-17-13-10-50 +.. nonce: ytIT7Z +.. section: Library + +:func:`shutil.rmtree` can now work with VirtualBox shared folders when +running from the guest operating-system. + +.. + +.. bpo: 45390 +.. date: 2022-02-17-11-00-16 +.. nonce: sVhG6M +.. section: Library + +Propagate :exc:`asyncio.CancelledError` message from inner task to outer +awaiter. + +.. + +.. bpo: 46756 +.. date: 2022-02-15-11-57-53 +.. nonce: AigSPi +.. section: Library + +Fix a bug in :meth:`urllib.request.HTTPPasswordMgr.find_user_password` and +:meth:`urllib.request.HTTPPasswordMgrWithPriorAuth.is_authenticated` which +allowed to bypass authorization. For example, access to URI +``example.org/foobar`` was allowed if the user was authorized for URI +``example.org/foo``. + +.. + +.. bpo: 46737 +.. date: 2022-02-15-07-39-43 +.. nonce: 6Pnblt +.. section: Library + +:func:`random.gauss` and :func:`random.normalvariate` now have default +arguments. + +.. + +.. bpo: 46752 +.. date: 2022-02-14-21-21-49 +.. nonce: m6ldTm +.. section: Library + +Add task groups to asyncio (structured concurrency, inspired by Trio's +nurseries). This also introduces a change to task cancellation, where a +cancelled task can't be cancelled again until it calls .uncancel(). + +.. + +.. bpo: 46724 +.. date: 2022-02-11-20-41-17 +.. nonce: eU52_N +.. section: Library + +Fix :mod:`dis` behavior on negative jump offsets. + +.. + +.. bpo: 46333 +.. date: 2022-02-11-20-01-49 +.. nonce: PMTBY9 +.. section: Library + +The :meth:`__repr__` method of :class:`typing.ForwardRef` now includes the +``module`` parameter of :class:`typing.ForwardRef` when it is set. + +.. + +.. bpo: 46643 +.. date: 2022-02-09-22-40-11 +.. nonce: aBlIx1 +.. section: Library + +In :func:`typing.get_type_hints`, support evaluating stringified +``ParamSpecArgs`` and ``ParamSpecKwargs`` annotations. Patch by Gregory +Beauregard. + +.. + +.. bpo: 45863 +.. date: 2022-02-09-00-53-23 +.. nonce: zqQXVv +.. section: Library + +When the :mod:`tarfile` module creates a pax format archive, it will put an +integer representation of timestamps in the ustar header (if possible) for +the benefit of older unarchivers, in addition to the existing full-precision +timestamps in the pax extended header. + +.. + +.. bpo: 46066 +.. date: 2022-02-08-16-42-20 +.. nonce: m32Hl0 +.. section: Library + +Deprecate kwargs-based syntax for :class:`typing.TypedDict` definitions. It +had confusing semantics when specifying totality, and was largely unused. +Patch by Jingchen Ye. + +.. + +.. bpo: 46676 +.. date: 2022-02-07-19-20-42 +.. nonce: 3Aws1o +.. section: Library + +Make :data:`typing.ParamSpec` args and kwargs equal to themselves. Patch by +Gregory Beauregard. + +.. + +.. bpo: 46323 +.. date: 2022-02-07-13-27-59 +.. nonce: 7UENAj +.. section: Library + +``ctypes.CFUNCTYPE()`` and ``ctypes.WINFUNCTYPE()`` now fail to create the +type if its ``_argtypes_`` member contains too many arguments. Previously, +the error was only raised when calling a function. Patch by Victor Stinner. + +.. + +.. bpo: 46672 +.. date: 2022-02-07-13-15-16 +.. nonce: 4swIjx +.. section: Library + +Fix ``NameError`` in :func:`asyncio.gather` when initial type check fails. + +.. + +.. bpo: 46659 +.. date: 2022-02-06-19-13-02 +.. nonce: q-vNL9 +.. section: Library + +The :class:`calendar.LocaleTextCalendar` and +:class:`calendar.LocaleHTMLCalendar` classes now use +:func:`locale.getlocale`, instead of using :func:`locale.getdefaultlocale`, +if no locale is specified. Patch by Victor Stinner. + +.. + +.. bpo: 46659 +.. date: 2022-02-06-17-57-45 +.. nonce: zTmkoQ +.. section: Library + +The :func:`locale.getdefaultlocale` function is deprecated and will be +removed in Python 3.13. Use :func:`locale.setlocale`, +:func:`locale.getpreferredencoding(False) ` and +:func:`locale.getlocale` functions instead. Patch by Victor Stinner. + +.. + +.. bpo: 46655 +.. date: 2022-02-06-08-54-03 +.. nonce: DiLzYv +.. section: Library + +In :func:`typing.get_type_hints`, support evaluating bare stringified +``TypeAlias`` annotations. Patch by Gregory Beauregard. + +.. + +.. bpo: 45948 +.. date: 2022-02-05-18-22-05 +.. nonce: w4mCnE +.. section: Library + +Fixed a discrepancy in the C implementation of the +:mod:`xml.etree.ElementTree` module. Now, instantiating an +:class:`xml.etree.ElementTree.XMLParser` with a ``target=None`` keyword +provides a default :class:`xml.etree.ElementTree.TreeBuilder` target as the +Python implementation does. + +.. + +.. bpo: 46626 +.. date: 2022-02-03-10-22-42 +.. nonce: r2e-n_ +.. section: Library + +Expose Linux's ``IP_BIND_ADDRESS_NO_PORT`` option in :mod:`socket`. + +.. + +.. bpo: 46521 +.. date: 2022-02-01-19-34-28 +.. nonce: IMUIrs +.. section: Library + +Fix a bug in the :mod:`codeop` module that was incorrectly identifying +invalid code involving string quotes as valid code. + +.. + +.. bpo: 46571 +.. date: 2022-02-01-11-21-34 +.. nonce: L40xUJ +.. section: Library + +Improve :func:`typing.no_type_check`. + +Now it does not modify external classes and functions. We also now correctly +mark classmethods as not to be type checked. + +.. + +.. bpo: 46400 +.. date: 2022-01-30-15-16-12 +.. nonce: vweUiO +.. section: Library + +expat: Update libexpat from 2.4.1 to 2.4.4 + +.. + +.. bpo: 46556 +.. date: 2022-01-27-23-20-30 +.. nonce: tlpAgS +.. section: Library + +Deprecate undocumented support for using a :class:`pathlib.Path` object as a +context manager. + +.. + +.. bpo: 46534 +.. date: 2022-01-26-18-06-08 +.. nonce: vhzUM4 +.. section: Library + +Implement :pep:`673` :class:`typing.Self`. Patch by James Hilton-Balfe. + +.. + +.. bpo: 46522 +.. date: 2022-01-25-15-31-04 +.. nonce: tYAlX4 +.. section: Library + +Make various module ``__getattr__`` AttributeErrors more closely match a +typical AttributeError + +.. + +.. bpo: 46475 +.. date: 2022-01-23-15-35-07 +.. nonce: UCe18S +.. section: Library + +Add :data:`typing.Never` and :func:`typing.assert_never`. Patch by Jelle +Zijlstra. + +.. + +.. bpo: 46333 +.. date: 2022-01-11-15-54-15 +.. nonce: B1faiF +.. section: Library + +The :meth:`__eq__` and :meth:`__hash__` methods of +:class:`typing.ForwardRef` now honor the ``module`` parameter of +:class:`typing.ForwardRef`. Forward references from different modules are +now differentiated. + +.. + +.. bpo: 46246 +.. date: 2022-01-07-13-27-53 +.. nonce: CTLx32 +.. section: Library + +Add missing ``__slots__`` to ``importlib.metadata.DeprecatedList``. Patch by +Arie Bovenberg. + +.. + +.. bpo: 46232 +.. date: 2022-01-03-09-46-44 +.. nonce: s0KlyI +.. section: Library + +The :mod:`ssl` module now handles certificates with bit strings in DN +correctly. + +.. + +.. bpo: 46195 +.. date: 2021-12-30-21-38-51 +.. nonce: jFKGq_ +.. section: Library + +:func:`typing.get_type_hints` no longer adds ``Optional`` to parameters with +``None`` as a default. This aligns to changes to PEP 484 in +https://github.com/python/peps/pull/689 + +.. + +.. bpo: 31369 +.. date: 2021-12-27-18-28-44 +.. nonce: b9yM94 +.. section: Library + +Add :class:`~re.RegexFlag` to ``re.__all__`` and documented it. Add +:data:`~re.RegexFlag.NOFLAG` to indicate no flags being set. + +.. + +.. bpo: 45898 +.. date: 2021-11-26-10-46-09 +.. nonce: UIfhsb +.. section: Library + +:mod:`ctypes` no longer defines ``ffi_type_*`` symbols in ``cfield.c``. The +symbols have been provided by libffi for over a decade. + +.. + +.. bpo: 44953 +.. date: 2021-08-19-09-29-43 +.. nonce: 27ZyUd +.. section: Library + +Calling ``operator.itemgetter`` objects and ``operator.attrgetter`` objects +is now faster due to use of the vectorcall calling convention. + +.. + +.. bpo: 44289 +.. date: 2021-06-02-19-47-46 +.. nonce: xC5kuV +.. section: Library + +Fix an issue with :meth:`~tarfile.is_tarfile` method when using *fileobj* +argument: position in the *fileobj* was advanced forward which made it +unreadable with :meth:`tarfile.TarFile.open`. + +.. + +.. bpo: 44011 +.. date: 2021-05-02-23-44-21 +.. nonce: hd8iUO +.. section: Library + +Reimplement SSL/TLS support in asyncio, borrow the implementation from +uvloop library. + +.. + +.. bpo: 41086 +.. date: 2020-06-23-01-50-24 +.. nonce: YnOvpS +.. section: Library + +Make the :class:`configparser.ConfigParser` constructor raise +:exc:`TypeError` if the ``interpolation`` parameter is not of type +:class:`configparser.Interpolation` + +.. + +.. bpo: 29418 +.. date: 2020-03-31-20-53-11 +.. nonce: 8Qa9cQ +.. section: Library + +Implement :func:`inspect.ismethodwrapper` and fix :func:`inspect.isroutine` +for cases where methodwrapper is given. Patch by Hakan Çelik. + +.. + +.. bpo: 14156 +.. date: 2019-05-07-14-25-45 +.. nonce: 0FaHXE +.. section: Library + +argparse.FileType now supports an argument of '-' in binary mode, returning +the .buffer attribute of sys.stdin/sys.stdout as appropriate. Modes +including 'x' and 'a' are treated equivalently to 'w' when argument is '-'. +Patch contributed by Josh Rosenberg + +.. + +.. bpo: 42238 +.. date: 2022-02-03-11-24-59 +.. nonce: yJcMa8 +.. section: Documentation + +``Doc/tools/rstlint.py`` has moved to its own repository and is now packaged +on PyPI as ``sphinx-lint``. + +.. + +.. bpo: 46913 +.. date: 2022-03-03-17-36-24 +.. nonce: vxETIE +.. section: Tests + +Fix test_faulthandler.test_sigfpe() if Python is built with undefined +behavior sanitizer (UBSAN): disable UBSAN on the faulthandler_sigfpe() +function. Patch by Victor Stinner. + +.. + +.. bpo: 46760 +.. date: 2022-02-16-10-38-18 +.. nonce: O3ovJo +.. section: Tests + +Remove bytecode offsets from expected values in test.test_dis module. +Reduces the obstacles to modifying the VM or compiler. + +.. + +.. bpo: 46708 +.. date: 2022-02-10-14-33-47 +.. nonce: avLfCb +.. section: Tests + +Prevent default asyncio event loop policy modification warning after +``test_asyncio`` execution. + +.. + +.. bpo: 46678 +.. date: 2022-02-07-12-40-45 +.. nonce: zfOrgL +.. section: Tests + +The function ``make_legacy_pyc`` in ``Lib/test/support/import_helper.py`` no +longer fails when ``PYTHONPYCACHEPREFIX`` is set to a directory on a +different device from where tempfiles are stored. + +.. + +.. bpo: 46623 +.. date: 2022-02-03-09-45-26 +.. nonce: vxzuhV +.. section: Tests + +Skip test_pair() and test_speech128() of test_zlib on s390x since they fail +if zlib uses the s390x hardware accelerator. Patch by Victor Stinner. + +.. + +.. bpo: 46860 +.. date: 2022-02-25-16-19-40 +.. nonce: jfciLG +.. section: Build + +Respect `--with-suffix` when building on case-insensitive file systems. + +.. + +.. bpo: 46656 +.. date: 2022-02-25-00-51-16 +.. nonce: MD783M +.. section: Build + +Building Python now requires a C11 compiler. Optional C11 features are not +required. +Patch by Victor Stinner. + +.. + +.. bpo: 46656 +.. date: 2022-02-06-14-04-20 +.. nonce: ajJjkh +.. section: Build + +Building Python now requires support for floating point Not-a-Number (NaN): +remove the ``Py_NO_NAN`` macro. Patch by by Victor Stinner. + +.. + +.. bpo: 46640 +.. date: 2022-02-04-21-26-50 +.. nonce: HXUmQp +.. section: Build + +Building Python now requires a C99 ```` header file providing a +``NAN`` constant, or the ``__builtin_nan()`` built-in function. Patch by +Victor Stinner. + +.. + +.. bpo: 46608 +.. date: 2022-02-02-11-26-46 +.. nonce: cXH9po +.. section: Build + +Exclude marshalled-frozen data if deep-freezing to save 300 KB disk space. +This includes adding a new ``is_package`` field to :c:struct:`_frozen`. +Patch by Kumar Aditya. + +.. + +.. bpo: 40280 +.. date: 2022-01-31-15-15-08 +.. nonce: r1AYNW +.. section: Build + +Fix wasm32-emscripten test failures and platform issues. - Disable syscalls +that are not supported or don't work, e.g. wait, getrusage, prlimit, +mkfifo, mknod, setres[gu]id, setgroups. - Use fd_count to cound open fds. - +Add more checks for subprocess and fork. - Add workarounds for missing +_multiprocessing and failing socket.accept(). - Enable bzip2. - Disable +large file support. - Disable signal.alarm. + +.. + +.. bpo: 46430 +.. date: 2022-01-19-11-08-32 +.. nonce: k403m_ +.. section: Build + +Intern strings in deep-frozen modules. Patch by Kumar Aditya. + +.. + +.. bpo: 46744 +.. date: 2022-03-04-00-24-55 +.. nonce: tneWFr +.. section: Windows + +The default all users install directory for ARM64 is now under the native +``Program Files`` folder, rather than ``Program Files (Arm)`` which is +intended for ARM (32-bit) files. + +.. + +.. bpo: 46567 +.. date: 2022-02-25-01-22-31 +.. nonce: 37WEue +.. section: Windows + +Adds Tcl and Tk support for Windows ARM64. This also adds IDLE to the +installation. + +.. + +.. bpo: 46638 +.. date: 2022-02-04-18-02-33 +.. nonce: mSJOSX +.. section: Windows + +Ensures registry virtualization is consistently disabled. For 3.10 and +earlier, it remains enabled (some registry writes are protected), while for +3.11 and later it is disabled (registry modifications affect all +applications). + +.. + +.. bpo: 46630 +.. date: 2022-02-03-15-47-53 +.. nonce: tREOjo +.. section: IDLE + +Make query dialogs on Windows start with a cursor in the entry box. + +.. + +.. bpo: 45447 +.. date: 2021-10-14-16-55-03 +.. nonce: FhiH5P +.. section: IDLE + +Apply IDLE syntax highlighting to `.pyi` files. Patch by Alex Waygood and +Terry Jan Reedy. + +.. + +.. bpo: 46748 +.. date: 2022-02-24-13-13-16 +.. nonce: aG1zb3 +.. section: C API + +Python's public headers no longer import ````, leaving code that +embedd/extends Python free to define ``bool``, ``true`` and ``false``. + +.. + +.. bpo: 46836 +.. date: 2022-02-23-16-13-17 +.. nonce: ZYyPF_ +.. section: C API + +Move the :c:type:`PyFrameObject` type definition (``struct _frame``) to the +internal C API ``pycore_frame.h`` header file. Patch by Victor Stinner. + +.. + +.. bpo: 45459 +.. date: 2022-02-07-18-47-00 +.. nonce: 0FCWM8 +.. section: C API + +Rename ``Include/buffer.h`` header file to ``Include/pybuffer.h`` to avoid +conflits with projects having an existing ``buffer.h`` header file. Patch by +Victor Stinner. + +.. + +.. bpo: 45412 +.. date: 2022-02-06-20-14-21 +.. nonce: XJVaGW +.. section: C API + +Remove the ``HAVE_PY_SET_53BIT_PRECISION`` macro (moved to the internal C +API). Patch by Victor Stinner. + +.. + +.. bpo: 46613 +.. date: 2022-02-02-17-58-49 +.. nonce: __ZdpH +.. section: C API + +Added function :c:func:`PyType_GetModuleByDef`, which allows accesss to +module state when a method's defining class is not available. diff --git a/Misc/NEWS.d/3.11.0a7.rst b/Misc/NEWS.d/3.11.0a7.rst new file mode 100644 index 00000000000..8e7ccd4d677 --- /dev/null +++ b/Misc/NEWS.d/3.11.0a7.rst @@ -0,0 +1,1614 @@ +.. bpo: 47212 +.. date: 2022-04-05-11-29-21 +.. nonce: leF4pz +.. release date: 2022-04-05 +.. section: Core and Builtins + +Raise :exc:`IndentationError` instead of :exc:`SyntaxError` for a bare +``except`` with no following indent. Improve :exc:`SyntaxError` locations +for an un-parenthesized generator used as arguments. Patch by Matthieu +Dartiailh. + +.. + +.. bpo: 47186 +.. date: 2022-04-04-17-41-10 +.. nonce: aQWoSh +.. section: Core and Builtins + +Replace :opcode:`JUMP_IF_NOT_EG_MATCH` by :opcode:`CHECK_EG_MATCH` + jump. + +.. + +.. bpo: 47176 +.. date: 2022-04-02-14-32-21 +.. nonce: kTygYI +.. section: Core and Builtins + +Emscripten builds cannot handle signals in the usual way due to platform +limitations. Python can now handle signals. To use, set +Module.Py_EmscriptenSignalBuffer to be a single byte SharedArrayBuffer and +set Py_EMSCRIPTEN_SIGNAL_HANDLING to 1. Writing a number into the +SharedArrayBuffer will cause the corresponding signal to be raised into the +Python thread. + +.. + +.. bpo: 47186 +.. date: 2022-04-01-11-53-59 +.. nonce: RBCPk8 +.. section: Core and Builtins + +Replace :opcode:`JUMP_IF_NOT_EXC_MATCH` by :opcode:`CHECK_EXC_MATCH` + jump. + +.. + +.. bpo: 47120 +.. date: 2022-03-31-21-43-57 +.. nonce: NgxQbA +.. section: Core and Builtins + +Replace the absolute jump opcode :opcode:`JUMP_NO_INTERRUPT` by the relative +:opcode:`JUMP_BACKWARD_NO_INTERRUPT`. + +.. + +.. bpo: 46841 +.. date: 2022-03-31-15-57-42 +.. nonce: U-25Z6 +.. section: Core and Builtins + +Avoid unnecessary allocations when comparing code objects. + +.. + +.. bpo: 47182 +.. date: 2022-03-31-15-37-02 +.. nonce: e_4SsC +.. section: Core and Builtins + +Fix a crash when using a named unicode character like ``"\N{digit nine}"`` +after the main interpreter has been initialized a second time. + +.. + +.. bpo: 47162 +.. date: 2022-03-30-13-13-25 +.. nonce: yDJMUm +.. section: Core and Builtins + +WebAssembly cannot deal with bad function pointer casts (different count or +types of arguments). Python can now use call trampolines to mitigate the +problem. Define :c:macro:`PY_CALL_TRAMPOLINE` to enable call trampolines. + +.. + +.. bpo: 46775 +.. date: 2022-03-30-02-36-25 +.. nonce: e3Oxqf +.. section: Core and Builtins + +Some Windows system error codes(>= 10000) are now mapped into the correct +errno and may now raise a subclass of :exc:`OSError`. Patch by Dong-hee Na. + +.. + +.. bpo: 47129 +.. date: 2022-03-26-16-35-57 +.. nonce: hDg2Vt +.. section: Core and Builtins + +Improve error messages in f-string syntax errors concerning empty +expressions. + +.. + +.. bpo: 47117 +.. date: 2022-03-26-15-45-57 +.. nonce: 60W6GQ +.. section: Core and Builtins + +Fix a crash if we fail to decode characters in interactive mode if the +tokenizer buffers are uninitialized. Patch by Pablo Galindo. + +.. + +.. bpo: 47127 +.. date: 2022-03-26-12-21-53 +.. nonce: Mh86RB +.. section: Core and Builtins + +Speed up calls to c functions with keyword arguments by 25% with +specialization. Patch by Kumar Aditya. + +.. + +.. bpo: 47120 +.. date: 2022-03-25-21-51-10 +.. nonce: 9YJ-Xw +.. section: Core and Builtins + +Replaced :opcode:`JUMP_ABSOLUTE` by the relative jump +:opcode:`JUMP_BACKWARD`. + +.. + +.. bpo: 42197 +.. date: 2022-03-22-15-12-28 +.. nonce: SwrrFO +.. section: Core and Builtins + +:c:func:`PyFrame_FastToLocalsWithError` and :c:func:`PyFrame_LocalsToFast` +are no longer called during profiling nor tracing. C code can access the +``f_locals`` attribute of :c:type:`PyFrameObject` by calling +:c:func:`PyFrame_GetLocals`. + +.. + +.. bpo: 47070 +.. date: 2022-03-19-21-50-59 +.. nonce: wPcsQh +.. section: Core and Builtins + +Improve performance of ``array_inplace_repeat`` by reducing the number of +invocations of ``memcpy``. Refactor the ``repeat`` and inplace ``repeat`` +methods of ``array``, ``bytes``, ``bytearray`` and ``unicodeobject`` to use +the common ``_PyBytes_Repeat``. + +.. + +.. bpo: 47053 +.. date: 2022-03-17-22-47-29 +.. nonce: QAXk8Q +.. section: Core and Builtins + +Reduce de-optimization in the specialized ``BINARY_OP_INPLACE_ADD_UNICODE`` +opcode. + +.. + +.. bpo: 47045 +.. date: 2022-03-17-16-25-57 +.. nonce: xQgHul +.. section: Core and Builtins + +Remove the ``f_state`` field from the _PyInterpreterFrame struct. Add the +``owner`` field to the _PyInterpreterFrame struct to make ownership explicit +to simplify clearing and deallocing frames and generators. + +.. + +.. bpo: 46968 +.. date: 2022-03-17-14-22-23 +.. nonce: 4gz4NA +.. section: Core and Builtins + +Check for the existence of the "sys/auxv.h" header in :mod:`faulthandler` to +avoid compilation problems in systems where this header doesn't exist. Patch +by Pablo Galindo + +.. + +.. bpo: 46329 +.. date: 2022-03-16-12-19-25 +.. nonce: 9oS0HT +.. section: Core and Builtins + +Use low bit of ``LOAD_GLOBAL`` to indicate whether to push a ``NULL`` before +the global. Helps streamline the call sequence a bit. + +.. + +.. bpo: 46841 +.. date: 2022-03-16-11-05-35 +.. nonce: yUoIHg +.. section: Core and Builtins + +Quicken bytecode in-place by storing it as part of the corresponding +``PyCodeObject``. + +.. + +.. bpo: 47012 +.. date: 2022-03-14-11-15-11 +.. nonce: 5L6NoE +.. section: Core and Builtins + +Speed up iteration of :class:`bytes` and :class:`bytearray` by 30%. Patch by +Kumar Aditya. + +.. + +.. bpo: 47009 +.. date: 2022-03-14-09-45-10 +.. nonce: ZI05b5 +.. section: Core and Builtins + +Improved the performance of :meth:`list.append()` and list comprehensions by +optimizing for the common case, where no resize is needed. Patch by Dennis +Sweeney. + +.. + +.. bpo: 47005 +.. date: 2022-03-13-21-04-20 +.. nonce: OHBfCc +.. section: Core and Builtins + +Improve performance of ``bytearray_repeat`` and ``bytearray_irepeat`` by +reducing the number of invocations of ``memcpy``. + +.. + +.. bpo: 46829 +.. date: 2022-03-12-21-07-21 +.. nonce: cpGoPV +.. section: Core and Builtins + +Deprecate passing a message into :meth:`asyncio.Future.cancel` and +:meth:`asyncio.Task.cancel` + +.. + +.. bpo: 46993 +.. date: 2022-03-12-09-44-31 +.. nonce: -13hGo +.. section: Core and Builtins + +Speed up :class:`bytearray` creation from :class:`list` and :class:`tuple` +by 40%. Patch by Kumar Aditya. + +.. + +.. bpo: 39829 +.. date: 2022-03-11-09-39-01 +.. nonce: mlW3Su +.. section: Core and Builtins + +Removed the ``__len__()`` call when initializing a list and moved +initializing to ``list_extend``. Patch by Jeremiah Pascual. + +.. + +.. bpo: 46944 +.. date: 2022-03-08-10-50-42 +.. nonce: cnaIK3 +.. section: Core and Builtins + +Speed up throwing exception in generator with :const:`METH_FASTCALL` calling +convention. Patch by Kumar Aditya. + +.. + +.. bpo: 46841 +.. date: 2022-03-07-15-54-39 +.. nonce: 7wG92r +.. section: Core and Builtins + +Modify :opcode:`STORE_SUBSCR` to use an inline cache entry (rather than its +oparg) as an adaptive counter. + +.. + +.. bpo: 46841 +.. date: 2022-03-06-10-37-36 +.. nonce: O12Pba +.. section: Core and Builtins + +Use inline caching for :opcode:`PRECALL` and :opcode:`CALL`, and remove the +internal machinery for managing the (now unused) non-inline caches. + +.. + +.. bpo: 46881 +.. date: 2022-03-03-09-08-17 +.. nonce: ckD4tT +.. section: Core and Builtins + +Statically allocate and initialize the latin1 characters. + +.. + +.. bpo: 46838 +.. date: 2022-02-25-22-42-30 +.. nonce: RB6kEy +.. section: Core and Builtins + +Improve syntax errors for incorrect function definitions. Patch by Pablo +Galindo + +.. + +.. bpo: 43721 +.. date: 2022-02-01-10-05-27 +.. nonce: -1XAIo +.. section: Core and Builtins + +Fix docstrings of :attr:`~property.getter`, :attr:`~property.setter`, and +:attr:`~property.deleter` to clarify that they create a new copy of the +property. + +.. + +.. bpo: 43224 +.. date: 2022-01-20-16-48-09 +.. nonce: WDihrT +.. section: Core and Builtins + +Make grammar changes required for PEP 646. + +.. + +.. bpo: 47208 +.. date: 2022-04-04-08-54-31 +.. nonce: cOh9xZ +.. section: Library + +Allow vendors to override :const:`CTYPES_MAX_ARGCOUNT`. + +.. + +.. bpo: 23689 +.. date: 2022-04-03-13-19-08 +.. nonce: TFSc3E +.. section: Library + +:mod:`re` module: fix memory leak when a match is terminated by a signal or +memory allocation failure. Patch by Ma Lin. + +.. + +.. bpo: 47167 +.. date: 2022-03-30-18-35-50 +.. nonce: nCNHsB +.. section: Library + +Allow overriding a future compliance check in :class:`asyncio.Task`. + +.. + +.. bpo: 47151 +.. date: 2022-03-30-01-17-43 +.. nonce: z-nQkR +.. section: Library + +When subprocess tries to use vfork, it now falls back to fork if vfork +returns an error. This allows use in situations where vfork isn't allowed by +the OS kernel. + +.. + +.. bpo: 47152 +.. date: 2022-03-29-19-14-53 +.. nonce: 5rl5ZK +.. section: Library + +Convert the :mod:`re` module into a package. Deprecate modules +``sre_compile``, ``sre_constants`` and ``sre_parse``. + +.. + +.. bpo: 4833 +.. date: 2022-03-28-20-16-37 +.. nonce: 2vSUE5 +.. section: Library + +Add :meth:`ZipFile.mkdir` + +.. + +.. bpo: 27929 +.. date: 2022-03-28-13-35-50 +.. nonce: j5mAmV +.. section: Library + +Fix :meth:`asyncio.loop.sock_connect` to only resolve names for +:const:`socket.AF_INET` or :const:`socket.AF_INET6` families. Resolution may +not make sense for other families, like :const:`socket.AF_BLUETOOTH` and +:const:`socket.AF_UNIX`. + +.. + +.. bpo: 14265 +.. date: 2022-03-27-10-41-24 +.. nonce: OBMlAi +.. section: Library + +Adds the fully qualified test name to unittest output + +.. + +.. bpo: 47061 +.. date: 2022-03-26-13-14-43 +.. nonce: QLxbC6 +.. section: Library + +Deprecate the aifc module. + +.. + +.. bpo: 39622 +.. date: 2022-03-25-01-27-25 +.. nonce: ieBIMp +.. section: Library + +Handle Ctrl+C in asyncio programs to interrupt the main task. + +.. + +.. bpo: 47101 +.. date: 2022-03-23-15-31-02 +.. nonce: rVSld- +.. section: Library + +:const:`hashlib.algorithms_available` now lists only algorithms that are +provided by activated crypto providers on OpenSSL 3.0. Legacy algorithms are +not listed unless the legacy provider has been loaded into the default OSSL +context. + +.. + +.. bpo: 47099 +.. date: 2022-03-23-14-16-38 +.. nonce: 2raait +.. section: Library + +All :exc:`URLError` exception messages raised in +:class:`urllib.request.URLopener` now contain a colon between ``ftp error`` +and the rest of the message. Previously, +:func:`~urllib.request.URLopener.open_ftp` missed the colon. Patch by Oleg +Iarygin. + +.. + +.. bpo: 47099 +.. date: 2022-03-23-13-55-41 +.. nonce: P6quRP +.. section: Library + +Exception chaining is changed from +:func:`Exception.with_traceback`/:func:`sys.exc_info` to :pep:`3134`. Patch +by Oleg Iarygin. + +.. + +.. bpo: 47095 +.. date: 2022-03-23-12-07-26 +.. nonce: P3YTrh +.. section: Library + +:mod:`hashlib`'s internal ``_blake2`` module now prefers ``libb2`` from +https://www.blake2.net/ over Python's vendored copy of blake2. + +.. + +.. bpo: 47098 +.. date: 2022-03-23-10-07-41 +.. nonce: 7AN_qp +.. section: Library + +The Keccak Code Package for :mod:`hashlib`'s internal ``_sha3`` module has +been replaced with tiny_sha3. The module is used as fallback when Python is +built without OpenSSL. + +.. + +.. bpo: 47088 +.. date: 2022-03-22-19-18-31 +.. nonce: JM1kNI +.. section: Library + +Implement :data:`typing.LiteralString`, part of :pep:`675`. Patch by Jelle +Zijlstra. + +.. + +.. bpo: 42885 +.. date: 2022-03-21-08-32-19 +.. nonce: LCnTTp +.. section: Library + +Optimize :func:`re.search`, :func:`re.split`, :func:`re.findall`, +:func:`re.finditer` and :func:`re.sub` for regular expressions starting with +``\A`` or ``^``. + +.. + +.. bpo: 23691 +.. date: 2022-03-20-22-13-24 +.. nonce: Nc2TrW +.. section: Library + +Protect the :func:`re.finditer` iterator from re-entering. + +.. + +.. bpo: 47067 +.. date: 2022-03-20-17-15-56 +.. nonce: XXLnje +.. section: Library + +Optimize calling ``GenericAlias`` objects by using :pep:`590` ``vectorcall`` +and by replacing ``PyObject_SetAttrString`` with ``PyObject_SetAttr``. + +.. + +.. bpo: 28080 +.. date: 2022-03-20-15-54-41 +.. nonce: kn35Vk +.. section: Library + +Add the *metadata_encoding* parameter in the :class:`zipfile.ZipFile` +constructor and the ``--metadata-encoding`` option in the :mod:`zipfile` CLI +to allow reading zipfiles using non-standard codecs to encode the filenames +within the archive. + +.. + +.. bpo: 47000 +.. date: 2022-03-20-13-00-08 +.. nonce: p8HpG0 +.. section: Library + +Make :func:`io.text_encoding` returns "utf-8" when UTF-8 mode is enabled. + +.. + +.. bpo: 42369 +.. date: 2022-03-19-19-56-04 +.. nonce: Ok828t +.. section: Library + +Fix thread safety of :meth:`zipfile._SharedFile.tell` to avoid a +"zipfile.BadZipFile: Bad CRC-32 for file" exception when reading a +:class:`ZipFile` from multiple threads. + +.. + +.. bpo: 38256 +.. date: 2022-03-19-15-54-41 +.. nonce: FoMbjE +.. section: Library + +Fix :func:`binascii.crc32` when it is compiled to use zlib'c crc32 to work +properly on inputs 4+GiB in length instead of returning the wrong result. +The workaround prior to this was to always feed the function data in +increments smaller than 4GiB or to just call the zlib module function. + +We also have :func:`binascii.crc32` release the GIL when computing on larger +inputs as :func:`zlib.crc32` and :mod:`hashlib` do. + +This also boosts performance on Windows as it now uses the zlib crc32 +implementation for :func:`binascii.crc32` for a 2-3x speedup. + +That the stdlib has a crc32 API in two modules is a known historical oddity. +This moves us closer to a single implementation behind them. + +.. + +.. bpo: 47066 +.. date: 2022-03-19-14-12-23 +.. nonce: we3YFx +.. section: Library + +Global inline flags (e.g. ``(?i)``) can now only be used at the start of the +regular expressions. Using them not at the start of expression was +deprecated since Python 3.6. + +.. + +.. bpo: 39394 +.. date: 2022-03-19-13-38-29 +.. nonce: 7j6WL6 +.. section: Library + +A warning about inline flags not at the start of the regular expression now +contains the position of the flag. + +.. + +.. bpo: 433030 +.. date: 2022-03-19-08-42-57 +.. nonce: UTwRX7 +.. section: Library + +Add support of atomic grouping (``(?>...)``) and possessive quantifiers +(``*+``, ``++``, ``?+``, ``{m,n}+``) in :mod:`regular expressions `. + +.. + +.. bpo: 47062 +.. date: 2022-03-18-22-46-18 +.. nonce: RNc99_ +.. section: Library + +Implement :class:`asyncio.Runner` context manager. + +.. + +.. bpo: 46382 +.. date: 2022-03-18-17-25-57 +.. nonce: zQUJ66 +.. section: Library + +:func:`~dataclasses.dataclass` ``slots=True`` now correctly omits slots +already defined in base classes. Patch by Arie Bovenberg. + +.. + +.. bpo: 47057 +.. date: 2022-03-18-14-22-38 +.. nonce: n-IHbt +.. section: Library + +Use FASTCALL convention for ``FutureIter.throw()`` + +.. + +.. bpo: 47061 +.. date: 2022-03-18-13-30-40 +.. nonce: etLHK5 +.. section: Library + +Deprecate the various modules listed by :pep:`594`: + +aifc, asynchat, asyncore, audioop, cgi, cgitb, chunk, crypt, imghdr, msilib, +nntplib, nis, ossaudiodev, pipes, smtpd, sndhdr, spwd, sunau, telnetlib, uu, +xdrlib + +.. + +.. bpo: 34790 +.. date: 2022-03-17-19-38-40 +.. nonce: zQIiVJ +.. section: Library + +Remove passing coroutine objects to :func:`asyncio.wait`. + +.. + +.. bpo: 47039 +.. date: 2022-03-17-01-54-13 +.. nonce: 0Yxv0K +.. section: Library + +Normalize ``repr()`` of asyncio future and task objects. + +.. + +.. bpo: 2604 +.. date: 2022-03-16-18-25-19 +.. nonce: jeopdL +.. section: Library + +Fix bug where doctests using globals would fail when run multiple times. + +.. + +.. bpo: 45150 +.. date: 2022-03-16-11-52-52 +.. nonce: kYbIME +.. section: Library + +Add :func:`hashlib.file_digest` helper for efficient hashing of file object. + +.. + +.. bpo: 34861 +.. date: 2022-03-16-08-49-12 +.. nonce: p8ugVg +.. section: Library + +Made cumtime the default sorting key for cProfile + +.. + +.. bpo: 45997 +.. date: 2022-03-15-18-32-12 +.. nonce: 4n2aVU +.. section: Library + +Fix :class:`asyncio.Semaphore` re-aquiring FIFO order. + +.. + +.. bpo: 47022 +.. date: 2022-03-15-09-29-52 +.. nonce: uaEDcI +.. section: Library + +The :mod:`asynchat`, :mod:`asyncore` and :mod:`smtpd` modules have been +deprecated since at least Python 3.6. Their documentation and deprecation +warnings and have now been updated to note they will removed in Python 3.12 +(:pep:`594`). + +.. + +.. bpo: 43253 +.. date: 2022-03-15-07-53-45 +.. nonce: rjdLFj +.. section: Library + +Fix a crash when closing transports where the underlying socket handle is +already invalid on the Proactor event loop. + +.. + +.. bpo: 40280 +.. date: 2022-03-14-09-26-42 +.. nonce: 2-k8TV +.. section: Library + +:func:`select.select` now passes ``NULL`` to ``select`` for each empty +fdset. + +.. + +.. bpo: 47004 +.. date: 2022-03-13-15-04-05 +.. nonce: SyYpxd +.. section: Library + +Apply bugfixes from importlib_metadata 4.11.3, including bugfix for +EntryPoint.extras, which was returning match objects and not the extras +strings. + +.. + +.. bpo: 46998 +.. date: 2022-03-13-08-52-58 +.. nonce: cHh-9O +.. section: Library + +Allow subclassing of :class:`typing.Any`. Patch by Shantanu Jain. + +.. + +.. bpo: 46995 +.. date: 2022-03-12-13-50-42 +.. nonce: 2kdNDg +.. section: Library + +Deprecate missing :meth:`asyncio.Task.set_name` for third-party task +implementations, schedule making it mandatory in Python 3.13. + +.. + +.. bpo: 46994 +.. date: 2022-03-12-12-34-13 +.. nonce: d7hPdz +.. section: Library + +Accept explicit contextvars.Context in :func:`asyncio.create_task` and +:meth:`asyncio.loop.create_task`. + +.. + +.. bpo: 46981 +.. date: 2022-03-12-11-30-42 +.. nonce: ltWCxH +.. section: Library + +``typing.get_args(typing.Tuple[()])`` now returns ``()`` instead of +``((),)``. + +.. + +.. bpo: 46968 +.. date: 2022-03-11-17-56-25 +.. nonce: pPVvNo +.. section: Library + +Add ``os.sysconf_names['SC_MINSIGSTKSZ']``. + +.. + +.. bpo: 46985 +.. date: 2022-03-11-13-34-16 +.. nonce: BgoMr2 +.. section: Library + +Upgrade pip wheel bundled with ensurepip (pip 22.0.4) + +.. + +.. bpo: 46968 +.. date: 2022-03-10-14-51-11 +.. nonce: ym2QxL +.. section: Library + +:mod:`faulthandler`: On Linux 5.14 and newer, dynamically determine size of +signal handler stack size CPython allocates using +``getauxval(AT_MINSIGSTKSZ)``. This changes allows for Python extension's +request to Linux kernel to use AMX_TILE instruction set on Sapphire Rapids +Xeon processor to succeed, unblocking use of the ISA in frameworks. + +.. + +.. bpo: 46917 +.. date: 2022-03-10-14-47-16 +.. nonce: s19zcy +.. section: Library + +The :data:`math.nan` value is now always available. Patch by Victor Stinner. + +.. + +.. bpo: 46955 +.. date: 2022-03-08-22-41-59 +.. nonce: IOoonN +.. section: Library + +Expose :class:`asyncio.base_events.Server` as :class:`asyncio.Server`. Patch +by Stefan Zabka. + +.. + +.. bpo: 23325 +.. date: 2022-03-08-11-34-06 +.. nonce: 3VQnfo +.. section: Library + +The :mod:`signal` module no longer assumes that :const:`~signal.SIG_IGN` and +:const:`~signal.SIG_DFL` are small int singletons. + +.. + +.. bpo: 46932 +.. date: 2022-03-07-20-20-34 +.. nonce: xbarAs +.. section: Library + +Update bundled libexpat to 2.4.7 + +.. + +.. bpo: 46933 +.. date: 2022-03-05-21-51-31 +.. nonce: 6yzWtb +.. section: Library + +The :mod:`pwd` module is now optional. :func:`os.path.expanduser` returns +the path when the :mod:`pwd` module is not available. + +.. + +.. bpo: 40059 +.. date: 2022-02-23-01-11-08 +.. nonce: Iwc9UH +.. section: Library + +:pep:`680`, the :mod:`tomllib` module. Adds support for parsing TOML. + +.. + +.. bpo: 464471 +.. date: 2022-02-21-11-41-23 +.. nonce: fL06TV +.. section: Library + +:func:`asyncio.timeout` and :func:`asyncio.timeout_at` context managers +added. Patch by Tin Tvrtković and Andrew Svetlov. + +.. + +.. bpo: 46805 +.. date: 2022-02-20-23-03-32 +.. nonce: HZ8xWG +.. section: Library + +Added raw datagram socket functions for asyncio: +:meth:`~asyncio.AbstractEventLoop.sock_sendto`, +:meth:`~asyncio.AbstractEventLoop.sock_recvfrom` and +:meth:`~asyncio.AbstractEventLoop.sock_recvfrom_into`. + +.. + +.. bpo: 46644 +.. date: 2022-02-05-22-14-44 +.. nonce: P--1Cz +.. section: Library + +No longer require valid typeforms to be callable. This allows +:data:`typing.Annotated` to wrap :data:`typing.ParamSpecArgs` and +:data:`dataclasses.InitVar`. Patch by Gregory Beauregard. + +.. + +.. bpo: 46581 +.. date: 2022-02-01-11-32-47 +.. nonce: t7Zw65 +.. section: Library + +Brings :class:`ParamSpec` propagation for :class:`GenericAlias` in line with +:class:`Concatenate` (and others). + +.. + +.. bpo: 45413 +.. date: 2022-01-31-15-19-38 +.. nonce: 1vaS0V +.. section: Library + +Define *posix_venv* and *nt_venv* :ref:`sysconfig installation schemes +` to be used for bootstrapping new virtual environments. +Add *venv* sysconfig installation scheme to get the appropriate one of the +above. The schemes are identical to the pre-existing *posix_prefix* and *nt* +install schemes. The :mod:`venv` module now uses the *venv* scheme to create +new virtual environments instead of hardcoding the paths depending only on +the platform. Downstream Python distributors customizing the *posix_prefix* +or *nt* install scheme in a way that is not compatible with the install +scheme used in virtual environments are encouraged not to customize the +*venv* schemes. When Python itself runs in a virtual environment, +:func:`sysconfig.get_default_scheme` and +:func:`sysconfig.get_preferred_scheme` with ``key="prefix"`` returns *venv*. + +.. + +.. bpo: 43224 +.. date: 2022-01-30-22-05-53 +.. nonce: E-eT22 +.. section: Library + +Implement support for PEP 646 in typing.py. + +.. + +.. bpo: 43224 +.. date: 2022-01-30-20-32-40 +.. nonce: zqrQsj +.. section: Library + +Allow unpacking types.GenericAlias objects, e.g. ``*tuple[int, str]``. + +.. + +.. bpo: 46557 +.. date: 2022-01-28-01-23-25 +.. nonce: XSbhyQ +.. section: Library + +Warnings captured by the logging module are now logged without a format +string to prevent systems that group logs by the msg argument from grouping +captured warnings together. + +.. + +.. bpo: 41370 +.. date: 2022-01-27-11-54-16 +.. nonce: gYxCPE +.. section: Library + +:func:`typing.get_type_hints` now supports evaluating strings as forward +references in :ref:`PEP 585 generic aliases `. + +.. + +.. bpo: 46607 +.. date: 2022-01-26-18-30-34 +.. nonce: xnhT4a +.. section: Library + +Add :exc:`DeprecationWarning` to :class:`LegacyInterpolation`, deprecated in +the docstring since Python 3.2. Will be removed in Python 3.13. Use +:class:`BasicInterpolation` or :class:`ExtendedInterpolation` instead. + +.. + +.. bpo: 26120 +.. date: 2022-01-25-15-45-04 +.. nonce: YzrBMO +.. section: Library + +:mod:`pydoc` now excludes __future__ imports from the module's data items. + +.. + +.. bpo: 46480 +.. date: 2022-01-23-16-33-07 +.. nonce: E4jHlh +.. section: Library + +Add :func:`typing.assert_type`. Patch by Jelle Zijlstra. + +.. + +.. bpo: 46421 +.. date: 2022-01-18-01-29-38 +.. nonce: 9LdmNr +.. section: Library + +Fix a unittest issue where if the command was invoked as ``python -m +unittest`` and the filename(s) began with a dot (.), a ``ValueError`` is +returned. + +.. + +.. bpo: 46245 +.. date: 2022-01-03-20-12-14 +.. nonce: 3w4RlA +.. section: Library + +Add optional parameter *dir_fd* in :func:`shutil.rmtree`. + +.. + +.. bpo: 22859 +.. date: 2021-12-29-19-37-49 +.. nonce: AixHW7 +.. section: Library + +:meth:`~unittest.TestProgram.usageExit` is marked deprecated, to be removed +in 3.13. + +.. + +.. bpo: 46170 +.. date: 2021-12-26-14-45-51 +.. nonce: AQ7kSM +.. section: Library + +Improve the error message when you try to subclass an instance of +:class:`typing.NewType`. + +.. + +.. bpo: 40296 +.. date: 2021-12-25-14-13-14 +.. nonce: p0YVGB +.. section: Library + +Fix supporting generic aliases in :mod:`pydoc`. + +.. + +.. bpo: 20392 +.. date: 2021-12-22-12-02-27 +.. nonce: CLAFIp +.. section: Library + +Fix inconsistency with uppercase file extensions in +:meth:`MimeTypes.guess_type`. Patch by Kumar Aditya. + +.. + +.. bpo: 46030 +.. date: 2021-12-10-07-07-47 +.. nonce: UN349J +.. section: Library + +Add ``LOCAL_CREDS``, ``LOCAL_CREDS_PERSISTENT`` and ``SCM_CREDS2`` FreeBSD +constants to the socket module. + +.. + +.. bpo: 44439 +.. date: 2021-11-08-20-27-41 +.. nonce: I_8qro +.. section: Library + +Fix ``.write()`` method of a member file in ``ZipFile``, when the input data +is an object that supports the buffer protocol, the file length may be +wrong. + +.. + +.. bpo: 45171 +.. date: 2021-09-11-16-06-54 +.. nonce: ec597j +.. section: Library + +Fix handling of the ``stacklevel`` argument to logging functions in the +:mod:`logging` module so that it is consistent across all logging functions +and, as advertised, similar to the ``stacklevel`` argument used in +:meth:`~warnings.warn`. + +.. + +.. bpo: 24959 +.. date: 2021-09-06-15-46-53 +.. nonce: UVFgiO +.. section: Library + +Fix bug where :mod:`unittest` sometimes drops frames from tracebacks of +exceptions raised in tests. + +.. + +.. bpo: 44859 +.. date: 2021-08-10-00-05-53 +.. nonce: 9e9_3V +.. section: Library + +Raise more accurate and :pep:`249` compatible exceptions in :mod:`sqlite3`. + +* Raise :exc:`~sqlite3.InterfaceError` instead of + :exc:`~sqlite3.ProgrammingError` for ``SQLITE_MISUSE`` errors. +* Don't overwrite :exc:`BufferError` with :exc:`ValueError` when conversion to + BLOB fails. +* Raise :exc:`~sqlite3.ProgrammingError` instead of :exc:`~sqlite3.Warning` if + user tries to :meth:`~sqlite3.Cursor.execute()` more than one SQL statement. +* Raise :exc:`~sqlite3.ProgrammingError` instead of :exc:`ValueError` if an SQL + query contains null characters. + +.. + +.. bpo: 44493 +.. date: 2021-07-26-10-46-49 +.. nonce: xp3CRH +.. section: Library + +Add missing terminated NUL in sockaddr_un's length + +This was potentially observable when using non-abstract AF_UNIX datagram +sockets to processes written in another programming language. + +.. + +.. bpo: 41930 +.. date: 2021-06-17-00-02-58 +.. nonce: JS6fsd +.. section: Library + +Add :meth:`~sqlite3.Connection.serialize` and +:meth:`~sqlite3.Connection.deserialize` support to :mod:`sqlite3`. Patch by +Erlend E. Aasland. + +.. + +.. bpo: 33178 +.. date: 2021-04-20-16-48-07 +.. nonce: kSnWwb +.. section: Library + +Added :class:`ctypes.BigEndianUnion` and :class:`ctypes.LittleEndianUnion` +classes, as originally documented in the library docs but not yet +implemented. + +.. + +.. bpo: 43352 +.. date: 2021-03-31-15-22-45 +.. nonce: nSjMuE +.. section: Library + +Add an Barrier object in synchronization primitives of *asyncio* Lib in +order to be consistant with Barrier from *threading* and *multiprocessing* +libs* + +.. + +.. bpo: 35859 +.. date: 2019-03-14-09-08-25 +.. nonce: 8lFdLe +.. section: Library + +:mod:`re` module, fix a few bugs about capturing group. In rare cases, +capturing group gets an incorrect string. Patch by Ma Lin. + +.. + +.. bpo: 45099 +.. date: 2022-03-29-13-25-49 +.. nonce: dagdhx +.. section: Documentation + +Document internal :mod:`asyncio` API. + +.. + +.. bpo: 47126 +.. date: 2022-03-26-12-20-16 +.. nonce: p6_Ovm +.. section: Documentation + +Update PEP URLs to :pep:`676`'s new canonical form. + +.. + +.. bpo: 47040 +.. date: 2022-03-17-13-35-28 +.. nonce: 4Dn48U +.. section: Documentation + +Clarified the old Python versions compatiblity note of +:func:`binascii.crc32` / :func:`zlib.adler32` / :func:`zlib.crc32` +functions. + +.. + +.. bpo: 46033 +.. date: 2022-01-03-18-50-39 +.. nonce: 7WeF0f +.. section: Documentation + +Clarify ``for`` statement execution in its doc. + +.. + +.. bpo: 45790 +.. date: 2021-11-12-11-03-55 +.. nonce: 6yuhe8 +.. section: Documentation + +Adjust inaccurate phrasing in :doc:`../extending/newtypes_tutorial` about +the ``ob_base`` field and the macros used to access its contents. + +.. + +.. bpo: 42340 +.. date: 2020-11-12-21-26-31 +.. nonce: apumUL +.. section: Documentation + +Document that in some circumstances :exc:`KeyboardInterrupt` may cause the +code to enter an inconsistent state. Provided a sample workaround to avoid +it if needed. + +.. + +.. bpo: 41233 +.. date: 2020-07-07-22-54-51 +.. nonce: lyUJ8L +.. section: Documentation + +Link the errnos referenced in ``Doc/library/exceptions.rst`` to their +respective section in ``Doc/library/errno.rst``, and vice versa. Previously +this was only done for EINTR and InterruptedError. Patch by Yan "yyyyyyyan" +Orestes. + +.. + +.. bpo: 47205 +.. date: 2022-04-03-14-38-21 +.. nonce: hbbTnh +.. section: Tests + +Skip test for :func:`~os.sched_getaffinity` and +:func:`~os.sched_setaffinity` error case on FreeBSD. + +.. + +.. bpo: 46126 +.. date: 2022-03-26-11-41-19 +.. nonce: q14Ioy +.. section: Tests + +Restore 'descriptions' when running tests internally. + +.. + +.. bpo: 47104 +.. date: 2022-03-23-22-45-51 +.. nonce: _esUq8 +.. section: Tests + +Rewrite :func:`asyncio.to_thread` tests to use +:class:`unittest.IsolatedAsyncioTestCase`. + +.. + +.. bpo: 40280 +.. date: 2022-03-19-10-25-04 +.. nonce: wBRSel +.. section: Tests + +The test suite is now passing on the Emscripten platform. All fork, socket, +and subprocess-based tests are skipped. + +.. + +.. bpo: 47037 +.. date: 2022-03-16-21-29-30 +.. nonce: xcrLpJ +.. section: Tests + +Skip ``strftime("%4Y")`` feature test on Windows. It can cause an assertion +error in debug builds. + +.. + +.. bpo: 46587 +.. date: 2022-03-14-17-10-35 +.. nonce: ASDsJX +.. section: Tests + +Skip tests if platform's ``strftime`` does not support non-portable glibc +extensions. + +.. + +.. bpo: 47015 +.. date: 2022-03-13-23-43-40 +.. nonce: FjmCsz +.. section: Tests + +A test case for :func:`os.sendfile` is converted from deprecated +:mod:`asyncore` (see :pep:`594`) to :mod:`asyncio`. Patch by Oleg Iarygin. + +.. + +.. bpo: 40280 +.. date: 2022-04-02-17-52-38 +.. nonce: U8Dd0H +.. section: Build + +Add configure option :option:`--enable-wasm-dynamic-linking` to enable +``dlopen`` and MAIN_MODULE / SIDE_MODULE on ``wasm32-emscripten``. + +.. + +.. bpo: 46023 +.. date: 2022-04-01-16-12-53 +.. nonce: 1Z1OcC +.. section: Build + +``makesetup`` now detects and skips all duplicated module definitions. The +first entry wins. + +.. + +.. bpo: 40280 +.. date: 2022-03-24-12-12-35 +.. nonce: eAQWrM +.. section: Build + +Add SOABI ``wasm32-emscripten`` for Emscripten and ``wasm32-wasi`` for WASI +on 32bit WASM as well as ``wasm64`` counter parts. + +.. + +.. bpo: 47032 +.. date: 2022-03-16-00-37-40 +.. nonce: tsS9KE +.. section: Build + +Ensure Windows install builds fail correctly with a non-zero exit code when +part of the build fails. + +.. + +.. bpo: 47024 +.. date: 2022-03-15-09-28-55 +.. nonce: t7-dcu +.. section: Build + +Update OpenSSL to 1.1.1n for macOS installers and all Windows builds. + +.. + +.. bpo: 46996 +.. date: 2022-03-12-18-09-31 +.. nonce: SygzVz +.. section: Build + +The :mod:`tkinter` package now requires Tcl/Tk version 8.5.12 or newer. + +.. + +.. bpo: 46973 +.. date: 2022-03-10-14-30-39 +.. nonce: _LEvnc +.. section: Build + +Add ``regen-configure`` make target to regenerate configure script with +Christian's container image ``quay.io/tiran/cpython_autoconf:269``. + +.. + +.. bpo: 46917 +.. date: 2022-03-10-09-37-05 +.. nonce: fry4aK +.. section: Build + +Building Python now requires support of IEEE 754 floating point numbers. +Patch by Victor Stinner. + +.. + +.. bpo: 45774 +.. date: 2022-03-04-21-24-02 +.. nonce: 9AhC0r +.. section: Build + +``configure`` now verifies that all SQLite C APIs needed for the +:mod:`sqlite3` extension module are found. + +.. + +.. bpo: 47194 +.. date: 2022-04-01-14-57-40 +.. nonce: IB0XL4 +.. section: Windows + +Update ``zlib`` to v1.2.12 to resolve CVE-2018-25032. + +.. + +.. bpo: 47171 +.. date: 2022-03-30-19-55-00 +.. nonce: MbqCWn +.. section: Windows + +Enables installing the :file:`py.exe` launcher on Windows ARM64. + +.. + +.. bpo: 46566 +.. date: 2022-03-23-12-51-46 +.. nonce: 4x4a7e +.. section: Windows + +Upgraded :ref:`launcher` to support a new ``-V:company/tag`` argument for +full :pep:`514` support and to detect ARM64 installs. The ``-64`` suffix on +arguments is deprecated, but still selects any non-32-bit install. Setting +:envvar:`PYLAUNCHER_ALLOW_INSTALL` and specifying a version that is not +installed will attempt to install the requested version from the Microsoft +Store. + +.. + +.. bpo: 47086 +.. date: 2022-03-21-20-45-01 +.. nonce: bIuKlF +.. section: Windows + +The installer for Windows now includes documentation as loose HTML files +rather than a single compiled :file:`.chm` file. + +.. + +.. bpo: 46907 +.. date: 2022-03-13-11-18-41 +.. nonce: YLzxBM +.. section: Windows + +Update Windows installer to use SQLite 3.38.1. + +.. + +.. bpo: 44549 +.. date: 2022-03-07-17-46-40 +.. nonce: SPrGS9 +.. section: Windows + +Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and +CVE-2019-12900 + +.. + +.. bpo: 46948 +.. date: 2022-03-07-16-34-11 +.. nonce: Ufd4tG +.. section: Windows + +Prevent CVE-2022-26488 by ensuring the Add to PATH option in the Windows +installer uses the correct path when being repaired. + +.. + +.. bpo: 46890 +.. date: 2022-03-17-09-55-02 +.. nonce: GX-3OO +.. section: macOS + +Fix a regression in the setting of ``sys._base_executable`` in framework +builds, and thereby fix a regression in :mod:`venv` virtual environments +with such builds. + +.. + +.. bpo: 46907 +.. date: 2022-03-13-11-11-31 +.. nonce: Ql0z1E +.. section: macOS + +Update macOS installer to SQLite 3.38.1. + +.. + +.. bpo: 40280 +.. date: 2022-04-03-11-47-45 +.. nonce: Q_IJik +.. section: Tools/Demos + +Replace Emscripten's limited shell with Katie Bell's browser-ui REPL from +python-wasm project. + +.. + +.. bpo: 40421 +.. date: 2022-03-25-13-40-46 +.. nonce: wJREl2 +.. section: C API + +Add ``PyFrame_GetBuiltins``, ``PyFrame_GetGenerator`` and +``PyFrame_GetGlobals`` C-API functions to access frame object attributes +safely from C code. + +.. + +.. bpo: 46850 +.. date: 2022-03-22-16-59-34 +.. nonce: lmEKLy +.. section: C API + +Move the private ``_PyFrameEvalFunction`` type, and private +``_PyInterpreterState_GetEvalFrameFunc()`` and +``_PyInterpreterState_SetEvalFrameFunc()`` functions to the internal C API. +The ``_PyFrameEvalFunction`` callback function type now uses the +``_PyInterpreterFrame`` type which is part of the internal C API. Patch by +Victor Stinner. + +.. + +.. bpo: 46850 +.. date: 2022-03-22-16-48-02 +.. nonce: 7M5dO7 +.. section: C API + +Move the private undocumented ``_PyEval_EvalFrameDefault()`` function to the +internal C API. The function now uses the ``_PyInterpreterFrame`` type which +is part of the internal C API. Patch by Victor Stinner. + +.. + +.. bpo: 46850 +.. date: 2022-03-21-02-26-27 +.. nonce: hU3c-O +.. section: C API + +Remove the private undocumented function ``_PyEval_CallTracing()`` from the +C API. Call the public :func:`sys.call_tracing` function instead. Patch by +Victor Stinner. + +.. + +.. bpo: 46850 +.. date: 2022-03-21-01-30-14 +.. nonce: Tfxde5 +.. section: C API + +Remove the private undocumented function +``_PyEval_GetCoroutineOriginTrackingDepth()`` from the C API. Call the +public :func:`sys.get_coroutine_origin_tracking_depth` function instead. +Patch by Victor Stinner. + +.. + +.. bpo: 46850 +.. date: 2022-03-21-00-41-29 +.. nonce: rOt771 +.. section: C API + +Remove the following private undocumented functions from the C API: + +* ``_PyEval_GetAsyncGenFirstiter()`` +* ``_PyEval_GetAsyncGenFinalizer()`` +* ``_PyEval_SetAsyncGenFirstiter()`` +* ``_PyEval_SetAsyncGenFinalizer()`` + +Call the public :func:`sys.get_asyncgen_hooks` and +:func:`sys.set_asyncgen_hooks` functions instead. Patch by Victor Stinner. + +.. + +.. bpo: 46987 +.. date: 2022-03-12-18-37-06 +.. nonce: LWcwyN +.. section: C API + +Remove private functions ``_PySys_GetObjectId()`` and +``_PySys_SetObjectId()``. Patch by Dong-hee Na. + +.. + +.. bpo: 46906 +.. date: 2022-03-03-11-12-33 +.. nonce: -olyBI +.. section: C API + +Add new functions to pack and unpack C double (serialize and deserialize): +:c:func:`PyFloat_Pack2`, :c:func:`PyFloat_Pack4`, :c:func:`PyFloat_Pack8`, +:c:func:`PyFloat_Unpack2`, :c:func:`PyFloat_Unpack4` and +:c:func:`PyFloat_Unpack8`. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/3.11.0b1.rst b/Misc/NEWS.d/3.11.0b1.rst new file mode 100644 index 00000000000..d8c2ec0a799 --- /dev/null +++ b/Misc/NEWS.d/3.11.0b1.rst @@ -0,0 +1,2146 @@ +.. date: 2022-05-04-14-32-24 +.. gh-issue: 57684 +.. nonce: HrlDrM +.. release date: 2022-05-06 +.. section: Security + +Add the :option:`-P` command line option and the :envvar:`PYTHONSAFEPATH` +environment variable to not prepend a potentially unsafe path to +:data:`sys.path`. Patch by Victor Stinner. + +.. + +.. date: 2022-05-06-02-29-53 +.. gh-issue: 89519 +.. nonce: 4OfkRE +.. section: Core and Builtins + +Chaining classmethod descriptors (introduced in bpo-19072) is deprecated. It +can no longer be used to wrap other descriptors such as property(). The +core design of this feature was flawed, and it caused a number of downstream +problems. + +.. + +.. date: 2022-05-05-20-05-41 +.. gh-issue: 92345 +.. nonce: lnN_RA +.. section: Core and Builtins + +``pymain_run_python()`` now imports ``readline`` and ``rlcompleter`` before +sys.path is extended to include the current working directory of an +interactive interpreter. Non-interactive interpreters are not affected. + +.. + +.. bpo: 43857 +.. date: 2022-05-04-11-37-20 +.. nonce: WuX8p3 +.. section: Core and Builtins + +Improve the :exc:`AttributeError` message when deleting a missing attribute. +Patch by Géry Ogam. + +.. + +.. date: 2022-05-03-14-55-40 +.. gh-issue: 92245 +.. nonce: G17-5i +.. section: Core and Builtins + +Make sure that PEP 523 is respected in all cases. In 3.11a7, specialization +may have prevented Python-to-Python calls respecting PEP 523. + +.. + +.. date: 2022-05-02-17-12-49 +.. gh-issue: 92203 +.. nonce: -igcjS +.. section: Core and Builtins + +Add a closure keyword-only parameter to exec(). It can only be specified +when exec-ing a code object that uses free variables. When specified, it +must be a tuple, with exactly the number of cell variables referenced by the +code object. closure has a default value of None, and it must be None if the +code object doesn't refer to any free variables. + +.. + +.. date: 2022-05-02-12-40-18 +.. gh-issue: 91173 +.. nonce: k_Dr6z +.. section: Core and Builtins + +Disable frozen modules in debug builds. Patch by Kumar Aditya. + +.. + +.. date: 2022-05-01-16-40-07 +.. gh-issue: 92114 +.. nonce: 5xTlLt +.. section: Core and Builtins + +Improve error message when subscript a type with ``__class_getitem__`` set +to ``None``. + +.. + +.. date: 2022-05-01-10-58-38 +.. gh-issue: 92112 +.. nonce: lLJemu +.. section: Core and Builtins + +Fix crash triggered by an evil custom ``mro()`` on a metaclass. + +.. + +.. date: 2022-04-30-04-26-01 +.. gh-issue: 92063 +.. nonce: vHnhf6 +.. section: Core and Builtins + +The ``PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS`` instruction now ensures +methods are called only on objects of the correct type. + +.. + +.. date: 2022-04-29-02-50-41 +.. gh-issue: 92031 +.. nonce: 2PpaIN +.. section: Core and Builtins + +Deoptimize statically allocated code objects during ``Py_FINALIZE()`` so +that future ``_PyCode_Quicken`` calls always start with unquickened code. + +.. + +.. date: 2022-04-28-23-37-30 +.. gh-issue: 92036 +.. nonce: GZJAC9 +.. section: Core and Builtins + +Fix a crash in subinterpreters related to the garbage collector. When a +subinterpreter is deleted, untrack all objects tracked by its GC. To prevent +a crash in deallocator functions expecting objects to be tracked by the GC, +leak a strong reference to these objects on purpose, so they are never +deleted and their deallocator functions are not called. Patch by Victor +Stinner. + +.. + +.. date: 2022-04-28-20-19-49 +.. gh-issue: 92032 +.. nonce: ef-UfM +.. section: Core and Builtins + +The interpreter can now autocomplete soft keywords, as of now ``match``, +``case``, and ``_`` (wildcard pattern) from :pep:`634`. + +.. + +.. date: 2022-04-27-10-36-43 +.. gh-issue: 87999 +.. nonce: YSPHfO +.. section: Core and Builtins + +The warning emitted by the Python parser for a numeric literal immediately +followed by keyword has been changed from deprecation warning to syntax +warning. + +.. + +.. date: 2022-04-26-05-05-32 +.. gh-issue: 91869 +.. nonce: ELbTXl +.. section: Core and Builtins + +Fix an issue where specialized opcodes with extended arguments could produce +incorrect tracing output or lead to assertion failures. + +.. + +.. date: 2022-04-23-22-08-34 +.. gh-issue: 91603 +.. nonce: GcWEkK +.. section: Core and Builtins + +Speed up :class:`types.UnionType` instantiation. Based on patch provided by +Yurii Karabas. + +.. + +.. date: 2022-04-21-16-15-24 +.. gh-issue: 89373 +.. nonce: A1jgLx +.. section: Core and Builtins + +If Python is built in debug mode, Python now ensures that deallocator +functions leave the current exception unchanged. Patch by Victor Stinner. + +.. + +.. date: 2022-04-20-14-43-37 +.. gh-issue: 91632 +.. nonce: cvUhsZ +.. section: Core and Builtins + +Fix a minor memory leak at exit: release the memory of the +:class:`generic_alias_iterator` type. Patch by Dong-hee Na. + +.. + +.. date: 2022-04-18-20-25-01 +.. gh-issue: 81548 +.. nonce: n3VYgp +.. section: Core and Builtins + +Octal escapes with value larger than ``0o377`` now produce a +:exc:`DeprecationWarning`. In a future Python version they will be a +:exc:`SyntaxWarning` and eventually a :exc:`SyntaxError`. + +.. + +.. bpo: 43950 +.. date: 2022-04-18-15-22-56 +.. nonce: qrTvWL +.. section: Core and Builtins + +Use a single compact table for line starts, ends and column offsets. Reduces +memory consumption for location info by half + +.. + +.. date: 2022-04-18-07-23-48 +.. gh-issue: 91102 +.. nonce: vm-6g1 +.. section: Core and Builtins + +Use Argument Clinic for :class:`EncodingMap`. Patch by Oleg Iarygin. + +.. + +.. date: 2022-04-18-02-45-40 +.. gh-issue: 91636 +.. nonce: 6DFdy_ +.. section: Core and Builtins + +Fixed a crash in a garbage-collection edge-case, in which a +``PyFunction_Type.tp_clear`` function could leave a python function object +in an inconsistent state. + +.. + +.. date: 2022-04-17-11-03-45 +.. gh-issue: 91603 +.. nonce: hYw1Lv +.. section: Core and Builtins + +Speed up :func:`isinstance` and :func:`issubclass` checks for +:class:`types.UnionType`. Patch by Yurii Karabas. + +.. + +.. date: 2022-04-17-02-55-38 +.. gh-issue: 91625 +.. nonce: 80CrC7 +.. section: Core and Builtins + +Fixed a bug in which adaptive opcodes ignored any preceding +``EXTENDED_ARG``\ s on specialization failure. + +.. + +.. date: 2022-04-16-21-54-31 +.. gh-issue: 78607 +.. nonce: _Y7bMm +.. section: Core and Builtins + +The LLTRACE special build now looks for the name ``__lltrace__`` defined in +module globals, rather than the name ``__ltrace__``, which had been +introduced as a typo. + +.. + +.. date: 2022-04-15-16-57-23 +.. gh-issue: 91576 +.. nonce: adoDj_ +.. section: Core and Builtins + +Speed up iteration of ascii strings by 50%. Patch by Kumar Aditya. + +.. + +.. date: 2022-04-13-22-03-04 +.. gh-issue: 89279 +.. nonce: -jAVxZ +.. section: Core and Builtins + +Improve interpreter performance on Windows by inlining a few specific +macros. + +.. + +.. date: 2022-04-13-11-15-09 +.. gh-issue: 91502 +.. nonce: 11YXHQ +.. section: Core and Builtins + +Add a new :c:func:`_PyFrame_IsEntryFrame` API function, to check if a +:c:type:`PyFrameObject` is an entry frame. Patch by Pablo Galindo. + +.. + +.. date: 2022-04-13-07-14-30 +.. gh-issue: 91266 +.. nonce: 6Vkzzt +.. section: Core and Builtins + +Refactor the ``bytearray`` strip methods ``strip``, ``lstrip`` and +``rstrip`` to use a common implementation. + +.. + +.. date: 2022-04-12-11-56-23 +.. gh-issue: 91479 +.. nonce: -dyGJX +.. section: Core and Builtins + +Replaced the ``__note__`` field of :exc:`BaseException` (added in an earlier +version of 3.11) with the final design of :pep:`678`. Namely, +:exc:`BaseException` gets an :meth:`add_note` method, and its ``__notes__`` +field is created when necessary. + +.. + +.. date: 2022-04-12-09-40-57 +.. gh-issue: 46055 +.. nonce: IPb1HA +.. section: Core and Builtins + +Speed up right shift of negative integers, by removing unnecessary creation +of temporaries. Original patch by Xinhang Xu, reworked by Mark Dickinson. + +.. + +.. date: 2022-04-12-00-44-14 +.. gh-issue: 91462 +.. nonce: t8oxyd +.. section: Core and Builtins + +Make the interpreter's low-level tracing (lltrace) feature output more +readable by displaying opcode names (rather than just numbers), and by +displaying stack contents before each opcode. + +.. + +.. date: 2022-04-11-18-44-19 +.. gh-issue: 89455 +.. nonce: d0qMYd +.. section: Core and Builtins + +Fixed an uninitialized bool value in the traceback printing code path that +was introduced by the initial bpo-45292 exception groups work. + +.. + +.. date: 2022-04-10-22-57-27 +.. gh-issue: 91421 +.. nonce: dHhv6U +.. section: Core and Builtins + +Fix a potential integer overflow in _Py_DecodeUTF8Ex. + +.. + +.. date: 2022-04-10-18-47-21 +.. gh-issue: 91428 +.. nonce: ZewV-M +.. section: Core and Builtins + +Add ``static const char *const _PyOpcode_OpName[256] = {...};`` to +``opcode.h`` for debug builds to assist in debugging the Python interpreter. +It is now more convenient to make various forms of debugging output more +human-readable by including opcode names rather than just the corresponding +decimal digits. + +.. + +.. bpo: 47120 +.. date: 2022-04-06-22-50-31 +.. nonce: mbfHs5 +.. section: Core and Builtins + +Make :opcode:`POP_JUMP_IF_TRUE`, :opcode:`POP_JUMP_IF_FALSE`, +:opcode:`POP_JUMP_IF_NONE` and :opcode:`POP_JUMP_IF_NOT_NONE` virtual, +mapping to new relative jump opcodes. + +.. + +.. bpo: 45317 +.. date: 2022-04-04-15-12-38 +.. nonce: UDLOt8 +.. section: Core and Builtins + +Add internal documentation explaining design of new (for 3.11) frame stack. + +.. + +.. bpo: 47197 +.. date: 2022-04-03-17-21-04 +.. nonce: Ji_c30 +.. section: Core and Builtins + +ctypes used to mishandle ``void`` return types, so that for instance a +function declared like ``ctypes.CFUNCTYPE(None, ctypes.c_int)`` would be +called with signature ``int f(int)`` instead of ``void f(int)``. Wasm +targets require function pointers to be called with the correct signatures +so this led to crashes. The problem is now fixed. + +.. + +.. bpo: 47120 +.. date: 2022-03-31-14-33-48 +.. nonce: 6S_uoU +.. section: Core and Builtins + +Make opcodes :opcode:`JUMP_IF_TRUE_OR_POP` and +:opcode:`JUMP_IF_FALSE_OR_POP` relative rather than absolute. + +.. + +.. bpo: 47177 +.. date: 2022-03-31-01-30-03 +.. nonce: fQqaov +.. section: Core and Builtins + +Replace the ``f_lasti`` member of the internal ``_PyInterpreterFrame`` +structure with a ``prev_instr`` pointer, which reduces overhead in the main +interpreter loop. The ``f_lasti`` attribute of Python-layer frame objects is +preserved for backward-compatibility. + +.. + +.. bpo: 46961 +.. date: 2022-03-13-08-23-17 +.. nonce: SgGCkG +.. section: Core and Builtins + +Integer mod/remainder operations, including the three-argument form of +:func:`pow`, now consistently return ints from the global small integer +cache when applicable. + +.. + +.. bpo: 46962 +.. date: 2022-03-08-21-59-57 +.. nonce: UomDfz +.. section: Core and Builtins + +Classes and functions that unconditionally declared their docstrings +ignoring the `--without-doc-strings` compilation flag no longer do so. + +The classes affected are :class:`ctypes.UnionType`, +:class:`pickle.PickleBuffer`, :class:`testcapi.RecursingInfinitelyError`, +and :class:`types.GenericAlias`. + +The functions affected are 24 methods in :mod:`ctypes`. + +Patch by Oleg Iarygin. + +.. + +.. bpo: 46942 +.. date: 2022-03-07-11-51-51 +.. nonce: 57obVi +.. section: Core and Builtins + +Use Argument Clinic for the :class:`types.MethodType` constructor. Patch by +Oleg Iarygin. + +.. + +.. bpo: 46764 +.. date: 2022-02-16-03-23-38 +.. nonce: wEY4bS +.. section: Core and Builtins + +Fix wrapping bound methods with @classmethod + +.. + +.. bpo: 43464 +.. date: 2022-02-13-21-53-29 +.. nonce: yupHjd +.. section: Core and Builtins + +Optimize :meth:`set.intersection` for non-set arguments. + +.. + +.. bpo: 46721 +.. date: 2022-02-11-17-16-30 +.. nonce: JkHaLF +.. section: Core and Builtins + +Optimize :meth:`set.issuperset` for non-set argument. + +.. + +.. bpo: 46509 +.. date: 2022-01-25-05-39-38 +.. nonce: ljrqrc +.. section: Core and Builtins + +Add type-specialized versions of the ``Py_DECREF()``, and use them for +``float``, ``int``, ``str``, ``bool``, and ``None`` to avoid pointer-chasing +at runtime where types are known at C compile time. + +.. + +.. bpo: 46045 +.. date: 2021-12-11-11-36-48 +.. nonce: sfThay +.. section: Core and Builtins + +Do not use POSIX semaphores on NetBSD + +.. + +.. bpo: 36819 +.. date: 2021-09-28-10-58-30 +.. nonce: cyV50C +.. section: Core and Builtins + +Fix crashes in built-in encoders with error handlers that return position +less or equal than the starting position of non-encodable characters. + +.. + +.. bpo: 34093 +.. date: 2018-07-14-16-58-00 +.. nonce: WaVD-f +.. section: Core and Builtins + +``marshal.dumps()`` uses ``FLAG_REF`` for all interned strings. This makes +output more deterministic and helps reproducible build. + +.. + +.. bpo: 26579 +.. date: 2017-07-23-11-28-45 +.. nonce: lpCY8R +.. section: Core and Builtins + +Added ``object.__getstate__`` which provides the default implementation of +the ``__getstate__()`` method. + +Copying and pickling instances of subclasses of builtin types bytearray, +set, frozenset, collections.OrderedDict, collections.deque, weakref.WeakSet, +and datetime.tzinfo now copies and pickles instance attributes implemented +as slots. + +.. + +.. date: 2022-05-06-13-53-10 +.. gh-issue: 87901 +.. nonce: NnkUVr +.. section: Library + +Add the *encoding* parameter to :func:`os.popen`. + +.. + +.. date: 2022-05-06-09-48-07 +.. gh-issue: 90997 +.. nonce: 4PmCgX +.. section: Library + +Fix an issue where :mod:`dis` utilities may interpret populated inline cache +entries as valid instructions. + +.. + +.. date: 2022-05-05-22-46-52 +.. gh-issue: 92332 +.. nonce: Fv9CJx +.. section: Library + +Deprecate :class:`typing.Text` (removal of the class is currently not +planned). Patch by Alex Waygood. + +.. + +.. gh: 78157 +.. date: 2022-05-05-20-40-45 +.. nonce: IA_9na +.. section: Library + +Deprecate nested classes in enum definitions becoming members -- in 3.13 +they will be normal classes; add `member` and `nonmember` functions to allow +control over results now. + +.. + +.. date: 2022-05-05-19-25-09 +.. gh-issue: 92356 +.. nonce: uvxWdu +.. section: Library + +Fixed a performance regression in ctypes function calls. + +.. + +.. date: 2022-05-05-17-35-01 +.. gh-issue: 90997 +.. nonce: UV5_s0 +.. section: Library + +Show the actual named values stored in inline caches when +``show_caches=True`` is passed to :mod:`dis` utilities. + +.. + +.. date: 2022-05-04-11-54-37 +.. gh-issue: 92301 +.. nonce: eqjoYX +.. section: Library + +Prefer ``close_range()`` to iterating over procfs for file descriptor +closing in :mod:`subprocess` for better performance. + +.. + +.. date: 2022-05-03-19-06-38 +.. gh-issue: 67248 +.. nonce: DK61Go +.. section: Library + +Sort the miscellaneous topics in Cmd.do_help() + +.. + +.. date: 2022-05-03-17-33-46 +.. gh-issue: 92210 +.. nonce: csDOQM +.. section: Library + +Port ``socket.__init__`` to Argument Clinic. Patch by Cinder. + +.. + +.. date: 2022-05-03-12-11-27 +.. gh-issue: 80010 +.. nonce: yG54RE +.. section: Library + +Add support for generalized ISO 8601 parsing to +:meth:`datetime.datetime.fromisoformat`, :meth:`datetime.date.fromisoformat` +and :meth:`datetime.time.fromisoformat`. Patch by Paul Ganssle. + +.. + +.. date: 2022-05-02-23-08-02 +.. gh-issue: 92118 +.. nonce: 9Mm9g4 +.. section: Library + +Fix a 3.11 regression in :func:`~contextlib.contextmanager`, which caused it +to propagate exceptions with incorrect tracebacks. + +.. + +.. date: 2022-05-02-18-19-46 +.. gh-issue: 90887 +.. nonce: zQsmfp +.. section: Library + +Adding ``COPYFILE_STAT``, ``COPYFILE_ACL`` and ``COPYFILE_XATTR`` constants +for :func:`os.fcopyfile` available in macOs. + +.. + +.. date: 2022-05-02-09-09-47 +.. gh-issue: 91215 +.. nonce: l1p7CJ +.. section: Library + +For @dataclass, add weakref_slot. Default is False. If True, and if +slots=True, add a slot named "__weakref__", which will allow instances to be +weakref'd. Contributed by Eric V. Smith + +.. + +.. date: 2022-05-02-03-56-50 +.. gh-issue: 85984 +.. nonce: RBivvc +.. section: Library + +New function os.login_tty() for Unix. + +.. + +.. date: 2022-05-01-21-45-41 +.. gh-issue: 92128 +.. nonce: Di7VbE +.. section: Library + +Add :meth:`~object.__class_getitem__` to :class:`logging.LoggerAdapter` and +:class:`logging.StreamHandler`, allowing them to be parameterized at +runtime. Patch by Alex Waygood. + +.. + +.. date: 2022-04-30-10-53-10 +.. gh-issue: 92049 +.. nonce: 5SEKoh +.. section: Library + +Forbid pickling constants ``re._constants.SUCCESS`` etc. Previously, +pickling did not fail, but the result could not be unpickled. + +.. + +.. date: 2022-04-29-18-15-23 +.. gh-issue: 92062 +.. nonce: X2c_Rj +.. section: Library + +:class:`inspect.Parameter` now raises :exc:`ValueError` if ``name`` is a +keyword, in addition to the existing check that it is an identifier. + +.. + +.. date: 2022-04-29-16-41-08 +.. gh-issue: 87390 +.. nonce: 3LNNCv +.. section: Library + +Add an ``__unpacked__`` attribute to :class:`types.GenericAlias`. Patch by +Jelle Zijlstra. + +.. + +.. date: 2022-04-28-18-45-58 +.. gh-issue: 88089 +.. nonce: hu9kRk +.. section: Library + +Add support for generic :class:`typing.NamedTuple`. + +.. + +.. date: 2022-04-27-19-45-58 +.. gh-issue: 91996 +.. nonce: YEEIzk +.. section: Library + +New http.HTTPMethod enum to represent all the available HTTP request methods +in a convenient way + +.. + +.. date: 2022-04-27-18-30-00 +.. gh-issue: 91984 +.. nonce: LxAB11 +.. section: Library + +Modified test strings in test_argparse.py to not contain trailing spaces +before end of line. + +.. + +.. date: 2022-04-27-18-04-24 +.. gh-issue: 91952 +.. nonce: 9A4RXx +.. section: Library + +Add ``encoding="locale"`` support to :meth:`TextIOWrapper.reconfigure`. + +.. + +.. date: 2022-04-27-13-30-26 +.. gh-issue: 91954 +.. nonce: cC7ga_ +.. section: Library + +Add *encoding* and *errors* arguments to :func:`subprocess.getoutput` and +:func:`subprocess.getstatusoutput`. + +.. + +.. bpo: 47029 +.. date: 2022-04-26-19-01-13 +.. nonce: qkT42X +.. section: Library + +Always close the read end of the pipe used by :class:`multiprocessing.Queue` +*after* the last write of buffered data to the write end of the pipe to +avoid :exc:`BrokenPipeError` at garbage collection and at +:meth:`multiprocessing.Queue.close` calls. Patch by Géry Ogam. + +.. + +.. date: 2022-04-26-18-02-44 +.. gh-issue: 91928 +.. nonce: V0YveU +.. section: Library + +Add `datetime.UTC` alias for `datetime.timezone.utc`. + +Patch by Kabir Kwatra. + +.. + +.. date: 2022-04-26-09-09-07 +.. gh-issue: 68966 +.. nonce: roapI2 +.. section: Library + +The :mod:`mailcap` module is now deprecated and will be removed in Python +3.13. See :pep:`594` for the rationale and the :mod:`mimetypes` module for +an alternative. Patch by Victor Stinner. + +.. + +.. date: 2022-04-25-21-33-48 +.. gh-issue: 91401 +.. nonce: _Jo4Bu +.. section: Library + +Provide a way to disable :mod:`subprocess` use of ``vfork()`` just in case +it is ever needed and document the existing mechanism for ``posix_spawn()``. + +.. + +.. date: 2022-04-25-18-30-20 +.. gh-issue: 64783 +.. nonce: HFtERN +.. section: Library + +Fix :data:`signal.NSIG` value on FreeBSD to accept signal numbers greater +than 32, like :data:`signal.SIGRTMIN` and :data:`signal.SIGRTMAX`. Patch by +Victor Stinner. + +.. + +.. date: 2022-04-25-14-18-01 +.. gh-issue: 91910 +.. nonce: kY-JR0 +.. section: Library + +Add missing f prefix to f-strings in error messages from the +:mod:`multiprocessing` and :mod:`asyncio` modules. + +.. + +.. date: 2022-04-23-08-06-36 +.. gh-issue: 91860 +.. nonce: ityDjK +.. section: Library + +Add :func:`typing.dataclass_transform`, implementing :pep:`681`. Patch by +Jelle Zijlstra. + +.. + +.. date: 2022-04-23-03-24-00 +.. gh-issue: 91832 +.. nonce: TyLi65 +.. section: Library + +Add ``required`` attribute to :class:`argparse.Action` repr output. + +.. + +.. date: 2022-04-22-19-11-31 +.. gh-issue: 91827 +.. nonce: 6P3gOI +.. section: Library + +In the :mod:`tkinter` module add method ``info_patchlevel()`` which returns +the exact version of the Tcl library as a named tuple similar to +:data:`sys.version_info`. + +.. + +.. date: 2022-04-22-13-01-20 +.. gh-issue: 84461 +.. nonce: rsCiTH +.. section: Library + +Add :option:`--enable-wasm-pthreads` to enable pthreads support for WASM +builds. ``Emscripten/node`` no longer has threading enabled by default. +Include additional file systems. + +.. + +.. date: 2022-04-22-08-25-18 +.. gh-issue: 91821 +.. nonce: XwMkj0 +.. section: Library + +Fix unstable ``test_from_tuple`` test in ``test_decimal.py``. + +.. + +.. date: 2022-04-21-21-06-54 +.. gh-issue: 91217 +.. nonce: 2cVma_ +.. section: Library + +Deprecate the xdrlib module. + +.. + +.. date: 2022-04-21-21-04-08 +.. gh-issue: 91217 +.. nonce: BZVEki +.. section: Library + +Deprecate the uu module. + +.. + +.. date: 2022-04-21-19-46-03 +.. gh-issue: 91760 +.. nonce: zDtv1E +.. section: Library + +More strict rules will be applied for numerical group references and group +names in regular expressions. For now, a deprecation warning is emitted for +group references and group names which will be errors in future Python +versions. + +.. + +.. date: 2022-04-21-11-57-23 +.. gh-issue: 84461 +.. nonce: S7dbt4 +.. section: Library + +Add provisional :data:`sys._emscripten_info` named tuple with build-time and +run-time information about Emscripten platform. + +.. + +.. date: 2022-04-20-18-47-27 +.. gh-issue: 90623 +.. nonce: 5fROpX +.. section: Library + +:func:`signal.raise_signal` and :func:`os.kill` now check immediately for +pending signals. Patch by Victor Stinner. + +.. + +.. date: 2022-04-20-09-49-33 +.. gh-issue: 91734 +.. nonce: 4Dj4Gy +.. section: Library + +Fix OSS audio support on Solaris. + +.. + +.. date: 2022-04-19-19-50-10 +.. gh-issue: 90633 +.. nonce: Youov0 +.. section: Library + +Include the passed value in the exception thrown by +:func:`typing.assert_never`. Patch by Jelle Zijlstra. + +.. + +.. date: 2022-04-19-17-30-17 +.. gh-issue: 91700 +.. nonce: MRJi6m +.. section: Library + +Compilation of regular expression containing a conditional expression +``(?(group)...)`` now raises an appropriate :exc:`re.error` if the group +number refers to not defined group. Previously an internal RuntimeError was +raised. + +.. + +.. date: 2022-04-19-15-30-06 +.. gh-issue: 91231 +.. nonce: AWy4Cs +.. section: Library + +Add an optional keyword *shutdown_timeout* parameter to the +:class:`multiprocessing.BaseManager` constructor. Kill the process if +terminate() takes longer than the timeout. Patch by Victor Stinner. + +.. + +.. date: 2022-04-18-18-55-21 +.. gh-issue: 91621 +.. nonce: ACNlda +.. section: Library + +Fix :func:`typing.get_type_hints` for :class:`collections.abc.Callable`. +Patch by Shantanu Jain. + +.. + +.. date: 2022-04-18-16-31-33 +.. gh-issue: 90568 +.. nonce: 9kiU7o +.. section: Library + +Parsing ``\N`` escapes of Unicode Named Character Sequences in a +:mod:`regular expression ` raises now :exc:`re.error` instead of +``TypeError``. + +.. + +.. date: 2022-04-18-15-23-24 +.. gh-issue: 91670 +.. nonce: 6eyChw +.. section: Library + +Remove deprecated ``SO`` config variable in :mod:`sysconfig`. + +.. + +.. date: 2022-04-17-12-41-52 +.. gh-issue: 91217 +.. nonce: 3wnHSX +.. section: Library + +Deprecate the telnetlib module. + +.. + +.. date: 2022-04-17-12-38-31 +.. gh-issue: 91217 +.. nonce: 55714p +.. section: Library + +Deprecate the sunau module. + +.. + +.. date: 2022-04-17-12-32-40 +.. gh-issue: 91217 +.. nonce: ms49Rg +.. section: Library + +Deprecate the spwd module. + +.. + +.. date: 2022-04-17-12-27-46 +.. gh-issue: 91217 +.. nonce: tNDWtK +.. section: Library + +Deprecate the sndhdr module, as well as inline needed functionality for +``email.mime.MIMEAudio``. + +.. + +.. date: 2022-04-17-12-27-25 +.. gh-issue: 91616 +.. nonce: gSQg69 +.. section: Library + +:mod:`re` module, fix :meth:`~re.Pattern.fullmatch` mismatch when using +Atomic Grouping or Possessive Quantifiers. + +.. + +.. date: 2022-04-17-12-07-50 +.. gh-issue: 91217 +.. nonce: TIvrsq +.. section: Library + +Deprecate the 'pipes' module. + +.. + +.. date: 2022-04-17-11-56-17 +.. gh-issue: 91217 +.. nonce: McJre3 +.. section: Library + +Deprecate the ossaudiodev module. + +.. + +.. bpo: 47256 +.. date: 2022-04-16-11-39-59 +.. nonce: 1cygyd +.. section: Library + +:mod:`re` module, limit the maximum capturing group to 1,073,741,823 in +64-bit build, this increases the depth of backtracking. + +.. + +.. date: 2022-04-16-09-33-14 +.. gh-issue: 91217 +.. nonce: nt9JFs +.. section: Library + +Deprecate the nis module. + +.. + +.. date: 2022-04-16-05-12-13 +.. gh-issue: 91595 +.. nonce: CocJBv +.. section: Library + +Fix the comparison of character and integer inside +:func:`Tools.gdb.libpython.write_repr`. Patch by Yu Liu. + +.. + +.. date: 2022-04-15-20-56-31 +.. gh-issue: 74166 +.. nonce: 70KlvL +.. section: Library + +Add option to raise all errors from :meth:`~socket.create_connection` in an +:exc:`ExceptionGroup` when it fails to create a connection. The default +remains to raise only the last error that had occurred when multiple +addresses were tried. + +.. + +.. date: 2022-04-15-19-34-02 +.. gh-issue: 91487 +.. nonce: 2aqguF +.. section: Library + +Optimize asyncio UDP speed, over 100 times faster when transferring a large +file. + +.. + +.. date: 2022-04-15-18-38-21 +.. gh-issue: 91575 +.. nonce: fSyAxS +.. section: Library + +Update case-insensitive matching in the :mod:`re` module to the latest +Unicode version. + +.. + +.. date: 2022-04-15-18-32-38 +.. gh-issue: 90622 +.. nonce: WQjFDe +.. section: Library + +In ``concurrent.futures.process.ProcessPoolExecutor`` disallow the "fork" +multiprocessing start method when the new ``max_tasks_per_child`` feature is +used as the mix of threads+fork can hang the child processes. Default to +using the safe "spawn" start method in that circumstance if no +``mp_context`` was supplied. + +.. + +.. date: 2022-04-15-17-06-09 +.. gh-issue: 89022 +.. nonce: DgdQCa +.. section: Library + +In :mod:`sqlite3`, ``SQLITE_MISUSE`` result codes are now mapped to +:exc:`~sqlite3.InterfaceError` instead of :exc:`~sqlite3.ProgrammingError`. +Also, more accurate exceptions are raised when binding parameters fail. +Patch by Erlend E. Aasland. + +.. + +.. date: 2022-04-14-18-06-00 +.. gh-issue: 91526 +.. nonce: cwfhSB +.. section: Library + +Stop calling ``os.device_encoding(file.fileno())`` in +:class:`TextIOWrapper`. It was complex, never documented, and didn't work +for most cases. (Patch by Inada Naoki.) + +.. + +.. date: 2022-04-14-13-11-37 +.. gh-issue: 88116 +.. nonce: j_SybE +.. section: Library + +Change the frame-related functions in the :mod:`inspect` module to return a +regular object (that is backwards compatible with the old tuple-like +interface) that include the extended :pep:`657` position information (end +line number, column and end column). The affected functions are: +:func:`inspect.getframeinfo`, :func:`inspect.getouterframes`, +:func:`inspect.getinnerframes`, :func:`inspect.stack` and +:func:`inspect.trace`. Patch by Pablo Galindo. + +.. + +.. date: 2022-04-14-01-00-31 +.. gh-issue: 69093 +.. nonce: bmlMwI +.. section: Library + +Add indexing and slicing support to :class:`sqlite3.Blob`. Patch by Aviv +Palivoda and Erlend E. Aasland. + +.. + +.. date: 2022-04-14-00-59-01 +.. gh-issue: 69093 +.. nonce: bmlMwI +.. section: Library + +Add :term:`context manager` support to :class:`sqlite3.Blob`. Patch by Aviv +Palivoda and Erlend E. Aasland. + +.. + +.. date: 2022-04-12-20-19-10 +.. gh-issue: 91217 +.. nonce: acd4h9 +.. section: Library + +Deprecate nntplib. + +.. + +.. date: 2022-04-12-19-42-20 +.. gh-issue: 91217 +.. nonce: b9_Rz9 +.. section: Library + +Deprecate msilib. + +.. + +.. date: 2022-04-12-19-08-13 +.. gh-issue: 91404 +.. nonce: zjqYHo +.. section: Library + +Improve the performance of :mod:`re` matching by using computed gotos (or +"threaded code") on supported platforms and removing expensive pointer +indirections. + +.. + +.. date: 2022-04-11-17-04-38 +.. gh-issue: 91217 +.. nonce: QVDLOq +.. section: Library + +Deprecate the imghdr module. + +.. + +.. date: 2022-04-11-16-13-26 +.. gh-issue: 91217 +.. nonce: 2rf8rc +.. section: Library + +Deprecate the crypt module. + +.. + +.. date: 2022-04-11-13-07-30 +.. gh-issue: 91276 +.. nonce: Vttu15 +.. section: Library + +Make space for longer opcodes in :mod:`dis` output. + +.. + +.. bpo: 47000 +.. date: 2022-04-10-17-50-18 +.. nonce: JlQkFx +.. section: Library + +Make :class:`TextIOWrapper` uses locale encoding when ``encoding="locale"`` +is specified even in UTF-8 mode. + +.. + +.. date: 2022-04-10-17-12-23 +.. gh-issue: 91230 +.. nonce: T1d_fG +.. section: Library + +:func:`warnings.catch_warnings` now accepts arguments for +:func:`warnings.simplefilter`, providing a more concise way to locally +ignore warnings or convert them to errors. + +.. + +.. date: 2022-04-10-11-11-33 +.. gh-issue: 91217 +.. nonce: K82AuH +.. section: Library + +Deprecate the chunk module. + +.. + +.. gh: 91498 +.. date: 2022-04-10-08-39-44 +.. nonce: 8oII92 +.. section: Library + +Add the ``TCP_CONNECTION_INFO`` option (available on macOS) to +:mod:`socket`. + +.. + +.. bpo: 47260 +.. date: 2022-04-08-14-30-53 +.. nonce: TtcNxI +.. section: Library + +Fix ``os.closerange()`` potentially being a no-op in a Linux seccomp +sandbox. + +.. + +.. bpo: 47087 +.. date: 2022-04-08-08-55-36 +.. nonce: Q5C3EI +.. section: Library + +Implement ``typing.Required`` and ``typing.NotRequired`` (:pep:`655`). Patch +by David Foster and Jelle Zijlstra. + +.. + +.. bpo: 47061 +.. date: 2022-04-07-20-32-47 +.. nonce: TOufgh +.. section: Library + +Deprecate cgi and cgitb. + +.. + +.. bpo: 47061 +.. date: 2022-04-06-18-01-28 +.. nonce: qoVTR9 +.. section: Library + +Deprecate audioop. + +.. + +.. bpo: 47000 +.. date: 2022-04-06-11-54-53 +.. nonce: 2nmAR1 +.. section: Library + +Add :func:`locale.getencoding` to get the current locale encoding. It is +similar to ``locale.getpreferredencoding(False)`` but ignores the +:ref:`Python UTF-8 Mode `. + +.. + +.. bpo: 42012 +.. date: 2022-04-05-17-18-13 +.. nonce: zMocQz +.. section: Library + +Add :mod:`wsgiref.types`, containing WSGI-specific types for static type +checking. + +.. + +.. bpo: 47227 +.. date: 2022-04-05-15-53-58 +.. nonce: 1HWdp9 +.. section: Library + +Suppress expression chaining for more :mod:`re` parsing errors. + +.. + +.. bpo: 47211 +.. date: 2022-04-04-11-58-07 +.. nonce: W4GFkB +.. section: Library + +Remove undocumented and never working function ``re.template()`` and flag +``re.TEMPLATE``. +This was later reverted in 3.11.0b2 and deprecated instead. + +.. + +.. bpo: 47135 +.. date: 2022-04-01-21-44-00 +.. nonce: TvkKB- +.. section: Library + +:meth:`decimal.localcontext` now accepts context attributes via keyword +arguments + +.. + +.. bpo: 43323 +.. date: 2022-03-27-12-40-16 +.. nonce: 9mFPuI +.. section: Library + +Fix errors in the :mod:`email` module if the charset itself contains +undecodable/unencodable characters. + +.. + +.. bpo: 46841 +.. date: 2022-03-25-22-18-45 +.. nonce: NUEsXW +.. section: Library + +Disassembly of quickened code. + +.. + +.. bpo: 46681 +.. date: 2022-03-21-13-50-07 +.. nonce: RRhopn +.. section: Library + +Forward gzip.compress() compresslevel to zlib. + +.. + +.. bpo: 45100 +.. date: 2022-03-06-18-15-32 +.. nonce: B_lHu0 +.. section: Library + +Add :func:`typing.get_overloads` and :func:`typing.clear_overloads`. Patch +by Jelle Zijlstra. + +.. + +.. bpo: 44807 +.. date: 2022-03-02-04-25-58 +.. nonce: gHNC9J +.. section: Library + +:class:`typing.Protocol` no longer silently replaces :meth:`__init__` +methods defined on subclasses. Patch by Adrian Garcia Badaracco. + +.. + +.. bpo: 46787 +.. date: 2022-02-18-20-09-29 +.. nonce: juwWc0 +.. section: Library + +Fix :class:`concurrent.futures.ProcessPoolExecutor` exception memory leak + +.. + +.. bpo: 46720 +.. date: 2022-02-11-23-11-35 +.. nonce: nY8spB +.. section: Library + +Add support for path-like objects to :func:`multiprocessing.set_executable` +for Windows to be on a par with Unix-like systems. Patch by Géry Ogam. + +.. + +.. bpo: 46696 +.. date: 2022-02-09-21-40-02 +.. nonce: nPXRno +.. section: Library + +Add ``SO_INCOMING_CPU`` constant to :mod:`socket`. + +.. + +.. bpo: 46053 +.. date: 2022-02-06-12-59-32 +.. nonce: sHFo3S +.. section: Library + +Fix OSS audio support on NetBSD. + +.. + +.. bpo: 45639 +.. date: 2022-02-02-04-51-39 +.. nonce: N8XrGO +.. section: Library + +``image/avif`` and ``image/webp`` were added to :mod:`mimetypes`. + +.. + +.. bpo: 46285 +.. date: 2022-01-29-00-23-00 +.. nonce: pt84qm +.. section: Library + +Add command-line option ``-p``/``--protocol`` to module :mod:`http.server` +which specifies the HTTP version to which the server is conformant (HTTP/1.1 +conformant servers can now be run from the command-line interface of module +:mod:`http.server`). Patch by Géry Ogam. + +.. + +.. bpo: 44791 +.. date: 2022-01-27-14-46-15 +.. nonce: tR1JFG +.. section: Library + +Accept ellipsis as the last argument of :data:`typing.Concatenate`. + +.. + +.. bpo: 46547 +.. date: 2022-01-27-14-41-55 +.. nonce: JMyYz9 +.. section: Library + +Remove variables leaking into ``pydoc.Helper`` class namespace. + +.. + +.. bpo: 46415 +.. date: 2022-01-17-16-53-30 +.. nonce: 6wSYg- +.. section: Library + +Fix ipaddress.ip_{address,interface,network} raising TypeError instead of +ValueError if given invalid tuple as address parameter. + +.. + +.. bpo: 46075 +.. date: 2021-12-14-21-19-04 +.. nonce: KDtcU- +.. section: Library + +``CookieJar`` with ``DefaultCookiePolicy`` now can process cookies from +localhost with domain=localhost explicitly specified in Set-Cookie header. + +.. + +.. bpo: 45995 +.. date: 2021-12-14-13-15-41 +.. nonce: Am9pNL +.. section: Library + +Add a "z" option to the string formatting specification that coerces +negative zero floating-point values to positive zero after rounding to the +format precision. Contributed by John Belmonte. + +.. + +.. bpo: 26175 +.. date: 2021-11-14-01-35-04 +.. nonce: LNlOfI +.. section: Library + +Fully implement the :class:`io.BufferedIOBase` or :class:`io.TextIOBase` +interface for :class:`tempfile.SpooledTemporaryFile` objects. This lets them +work correctly with higher-level layers (like compression modules). Patch by +Carey Metcalfe. + +.. + +.. bpo: 45138 +.. date: 2021-09-08-16-21-03 +.. nonce: yghUrK +.. section: Library + +Fix a regression in the :mod:`sqlite3` trace callback where bound parameters +were not expanded in the passed statement string. The regression was +introduced in Python 3.10 by :issue:`40318`. Patch by Erlend E. Aasland. + +.. + +.. bpo: 44863 +.. date: 2021-09-03-07-56-48 +.. nonce: udgz95 +.. section: Library + +Allow :class:`~typing.TypedDict` subclasses to also include +:class:`~typing.Generic` as a base class in class based syntax. Thereby +allowing the user to define a generic ``TypedDict``, just like a +user-defined generic but with ``TypedDict`` semantics. + +.. + +.. bpo: 44587 +.. date: 2021-08-17-21-41-39 +.. nonce: 57OKSz +.. section: Library + +Fix BooleanOptionalAction to not automatically add a default string. If a +default string is desired, use a formatter to add it. + +.. + +.. bpo: 43827 +.. date: 2021-04-16-17-32-44 +.. nonce: uJaXdP +.. section: Library + +All positional-or-keyword parameters to ``ABCMeta.__new__`` are now +positional-only to avoid conflicts with keyword arguments to be passed to +:meth:`__init_subclass__`. + +.. + +.. bpo: 43218 +.. date: 2021-02-14-20-55-53 +.. nonce: VZv2M4 +.. section: Library + +Prevent creation of a venv whose path contains the PATH separator. This +could affect the usage of the activate script. Patch by Dustin Rodrigues. + +.. + +.. bpo: 38435 +.. date: 2020-12-24-19-11-53 +.. nonce: rEHTAR +.. section: Library + +Add a ``process_group`` parameter to :class:`subprocess.Popen` to help move +more things off of the unsafe ``preexec_fn`` parameter. + +.. + +.. bpo: 42066 +.. date: 2020-10-19-08-50-41 +.. nonce: DsB-R6 +.. section: Library + +Fix cookies getting sorted in :func:`CookieJar.__iter__` which is an extra +behavior and not mentioned in RFC 2965 or Netscape cookie protocol. Now the +cookies in ``CookieJar`` follows the order of the ``Set-Cookie`` header. +Patch by Iman Kermani. + +.. + +.. bpo: 40617 +.. date: 2020-05-24-23-52-03 +.. nonce: lycF9q +.. section: Library + +Add :meth:`~sqlite3.Connection.create_window_function` to +:class:`sqlite3.Connection` for creating aggregate window functions. Patch +by Erlend E. Aasland. + +.. + +.. bpo: 40676 +.. date: 2020-05-19-01-40-51 +.. nonce: yJfq1J +.. section: Library + +Convert :mod:`csv` to use Argument Clinic for :func:`csv.field_size_limit`, +:func:`csv.get_dialect`, :func:`csv.unregister_dialect` and +:func:`csv.list_dialects`. + +.. + +.. bpo: 39716 +.. date: 2020-02-22-12-02-11 +.. nonce: z2WhDQ +.. section: Library + +Raise an ArgumentError when the same subparser name is added twice to an +`argparse.ArgumentParser`. This is consistent with the (default) behavior +when the same option string is added twice to an ArgumentParser. + +.. + +.. bpo: 36073 +.. date: 2019-06-22-11-01-45 +.. nonce: ED8mB9 +.. section: Library + +Raise :exc:`~sqlite3.ProgrammingError` instead of segfaulting on recursive +usage of cursors in :mod:`sqlite3` converters. Patch by Sergey Fedoseev. + +.. + +.. bpo: 34975 +.. date: 2019-05-06-23-36-34 +.. nonce: eb49jr +.. section: Library + +Adds a ``start_tls()`` method to :class:`~asyncio.streams.StreamWriter`, +which upgrades the connection with TLS using the given +:class:`~ssl.SSLContext`. + +.. + +.. bpo: 22276 +.. date: 2018-11-11-04-41-11 +.. nonce: Tt19TW +.. section: Library + +:class:`~pathlib.Path` methods :meth:`~pathlib.Path.glob` and +:meth:`~pathlib.Path.rglob` return only directories if *pattern* ends with a +pathname components separator (``/`` or :data:`~os.sep`). Patch by Eisuke +Kawashima. + +.. + +.. bpo: 24905 +.. date: 2018-04-18-16-15-55 +.. nonce: jYqjYx +.. section: Library + +Add :meth:`~sqlite3.Connection.blobopen` to :class:`sqlite3.Connection`. +:class:`sqlite3.Blob` allows incremental I/O operations on blobs. Patch by +Aviv Palivoda and Erlend E. Aasland. + +.. + +.. date: 2022-04-24-22-09-31 +.. gh-issue: 91888 +.. nonce: kTjJLx +.. section: Documentation + +Add a new `gh` role to the documentation to link to GitHub issues. + +.. + +.. date: 2022-04-23-00-22-54 +.. gh-issue: 91783 +.. nonce: N09dRR +.. section: Documentation + +Document security issues concerning the use of the function +:meth:`shutil.unpack_archive` + +.. + +.. date: 2022-04-19-20-16-00 +.. gh-issue: 91547 +.. nonce: LsNWER +.. section: Documentation + +Remove "Undocumented modules" page. + +.. + +.. date: 2022-04-17-03-19-51 +.. gh-issue: 91298 +.. nonce: NT9qHi +.. section: Documentation + +In ``importlib.resources.abc``, refined the documentation of the Traversable +Protocol, applying changes from importlib_resources 5.7.1. + +.. + +.. bpo: 44347 +.. date: 2022-04-10-20-28-20 +.. nonce: Q1m3DM +.. section: Documentation + +Clarify the meaning of *dirs_exist_ok*, a kwarg of :func:`shutil.copytree`. + +.. + +.. bpo: 36329 +.. date: 2022-04-06-11-53-41 +.. nonce: EVtAtK +.. section: Documentation + +Remove 'make -C Doc serve' in favour of 'make -C Doc htmlview' + +.. + +.. bpo: 47189 +.. date: 2022-04-01-23-56-13 +.. nonce: Nss0Y3 +.. section: Documentation + +Add a What's New in Python 3.11 entry for the Faster CPython project. +Documentation by Ken Jin and Kumar Aditya. + +.. + +.. bpo: 38668 +.. date: 2022-04-01-09-28-31 +.. nonce: j4mrqW +.. section: Documentation + +Update the introduction to documentation for :mod:`os.path` to remove +warnings that became irrelevant after the implementations of :pep:`383` and +:pep:`529`. + +.. + +.. bpo: 47115 +.. date: 2022-03-30-17-08-12 +.. nonce: R3wt3i +.. section: Documentation + +The documentation now lists which members of C structs are part of the +:ref:`Limited API/Stable ABI `. + +.. + +.. bpo: 46962 +.. date: 2022-03-08-22-10-38 +.. nonce: FIVe9I +.. section: Documentation + +All docstrings in code snippets are now wrapped into :func:`PyDoc_STR` to +follow the guideline of `PEP 7's Documentation Strings paragraph +`_. Patch +by Oleg Iarygin. + +.. + +.. bpo: 26792 +.. date: 2022-01-23-20-44-53 +.. nonce: dQ1v1W +.. section: Documentation + +Improve the docstrings of :func:`runpy.run_module` and +:func:`runpy.run_path`. Original patch by Andrew Brezovsky. + +.. + +.. date: 2022-05-02-20-57-04 +.. gh-issue: 92169 +.. nonce: Xi4NGV +.. section: Tests + +Use ``warnings_helper.import_deprecated()`` to import deprecated modules +uniformly in tests. Patch by Hugo van Kemenade. + +.. + +.. date: 2022-05-02-20-15-54 +.. gh-issue: 84461 +.. nonce: DhxllI +.. section: Tests + +When multiprocessing is enabled, libregrtest can now use a Python executable +other than :code:`sys.executable` via the ``--python`` flag. + +.. + +.. date: 2022-04-25-11-16-36 +.. gh-issue: 91904 +.. nonce: 13Uvrz +.. section: Tests + +Fix initialization of :envvar:`PYTHONREGRTEST_UNICODE_GUARD` which prevented +running regression tests on non-UTF-8 locale. + +.. + +.. date: 2022-04-22-19-00-00 +.. gh-issue: 91752 +.. nonce: Ji27dd +.. section: Tests + +Added @requires_zlib to test.test_tools.test_freeze.TestFreeze. + +.. + +.. date: 2022-04-16-17-54-05 +.. gh-issue: 91607 +.. nonce: FnXjtW +.. section: Tests + +Fix ``test_concurrent_futures`` to test the correct multiprocessing start +method context in several cases where the test logic mixed this up. + +.. + +.. bpo: 40280 +.. date: 2022-04-06-10-16-27 +.. nonce: KT5Apg +.. section: Tests + +Threading tests are now skipped on WASM targets without pthread support. + +.. + +.. bpo: 47109 +.. date: 2022-03-24-13-35-01 +.. nonce: FjKQCE +.. section: Tests + +Test for :mod:`ctypes.macholib.dyld`, :mod:`ctypes.macholib.dylib`, and +:mod:`ctypes.macholib.framework` are brought from manual pre-:mod:`unittest` +times to :mod:`ctypes.test` location and structure. Patch by Oleg Iarygin. + +.. + +.. bpo: 29890 +.. date: 2022-01-24-21-31-09 +.. nonce: zEG-ra +.. section: Tests + +Add tests for :class:`ipaddress.IPv4Interface` and +:class:`ipaddress.IPv6Interface` construction with tuple arguments. Original +patch and tests by louisom. + +.. + +.. date: 2022-05-03-03-36-47 +.. gh-issue: 89452 +.. nonce: NIY0fF +.. section: Build + +gdbm-compat is now preferred over ndbm if both are available on the system. +This allows avoiding the problematic ndbm.h on macOS. + +.. + +.. date: 2022-04-20-11-14-51 +.. gh-issue: 91731 +.. nonce: zRoPcJ +.. section: Build + +Python is now built with ``-std=c11`` compiler option, rather than +``-std=c99``. Patch by Victor Stinner. + +.. + +.. bpo: 47152 +.. date: 2022-04-10-16-33-31 +.. nonce: TLkxKm +.. section: Build + +Add script and make target for generating ``sre_constants.h``. + +.. + +.. bpo: 47103 +.. date: 2022-03-23-20-01-16 +.. nonce: b4-00F +.. section: Build + +Windows ``PGInstrument`` builds now copy a required DLL into the output +directory, making it easier to run the profile stage of a PGO build. + +.. + +.. bpo: 46907 +.. date: 2022-04-27-19-36-56 +.. nonce: lfurlP +.. section: Windows + +Update Windows installer to use SQLite 3.38.3. + +.. + +.. bpo: 47239 +.. date: 2022-04-06-15-16-37 +.. nonce: B1HP7i +.. section: Windows + +Fixed --list and --list-paths output for :ref:`launcher` when used in an +active virtual environment. + +.. + +.. bpo: 46907 +.. date: 2022-03-28-07-01-31 +.. nonce: Ou3G6Z +.. section: Windows + +Update Windows installer to use SQLite 3.38.2. + +.. + +.. bpo: 46785 +.. date: 2022-03-13-20-35-41 +.. nonce: Pnknyl +.. section: Windows + +Fix race condition between :func:`os.stat` and unlinking a file on Windows, +by using errors codes returned by ``FindFirstFileW()`` when appropriate in +``win32_xstat_impl``. + +.. + +.. bpo: 40859 +.. date: 2020-06-04-10-42-04 +.. nonce: isKSw7 +.. section: Windows + +Update Windows build to use xz-5.2.5 + +.. + +.. bpo: 46907 +.. date: 2022-05-05-06-21-39 +.. nonce: dkgFPk +.. section: macOS + +Update macOS installer to SQLite 3.38.4. + +.. + +.. date: 2022-04-20-14-26-14 +.. gh-issue: 91583 +.. nonce: 200qI0 +.. section: Tools/Demos + +Fix regression in the code generated by Argument Clinic for functions with +the ``defining_class`` parameter. + +.. + +.. date: 2022-04-18-12-52-16 +.. gh-issue: 91575 +.. nonce: fK1TEh +.. section: Tools/Demos + +Add script ``Tools/scripts/generate_re_casefix.py`` and the make target +``regen-re`` for generating additional data for case-insensitive matching +according to the current Unicode version. + +.. + +.. date: 2022-04-14-18-11-46 +.. gh-issue: 91551 +.. nonce: l_nNT- +.. section: Tools/Demos + +Remove the ancient Pynche color editor. It has moved to +https://gitlab.com/warsaw/pynche + +.. + +.. date: 2022-05-06-04-55-17 +.. gh-issue: 88279 +.. nonce: 3mQ54t +.. section: C API + +Deprecate the C functions: :c:func:`PySys_SetArgv`, +:c:func:`PySys_SetArgvEx`, :c:func:`PySys_SetPath`. Patch by Victor Stinner. + +.. + +.. date: 2022-05-03-20-08-35 +.. gh-issue: 92154 +.. nonce: IqMcAJ +.. section: C API + +Added the :c:func:`PyCode_GetCode` function. This function does the +equivalent of the Python code ``getattr(code_object, 'co_code')``. + +.. + +.. date: 2022-05-02-12-39-33 +.. gh-issue: 92173 +.. nonce: len2Is +.. section: C API + +Fix the ``closure`` argument to :c:func:`PyEval_EvalCodeEx`. + +.. + +.. date: 2022-04-26-16-51-31 +.. gh-issue: 91320 +.. nonce: QDHmTv +.. section: C API + +Fix C++ compiler warnings about "old-style cast" (``g++ -Wold-style-cast``) +in the Python C API. Use C++ ``reinterpret_cast<>`` and ``static_cast<>`` +casts when the Python C API is used in C++. Patch by Victor Stinner. + +.. + +.. date: 2022-04-21-23-11-35 +.. gh-issue: 80527 +.. nonce: Cx-95G +.. section: C API + +Mark functions as deprecated by :pep:`623`: :c:func:`PyUnicode_AS_DATA`, +:c:func:`PyUnicode_AS_UNICODE`, :c:func:`PyUnicode_GET_DATA_SIZE`, +:c:func:`PyUnicode_GET_SIZE`. Patch by Victor Stinner. + +.. + +.. date: 2022-04-21-01-48-22 +.. gh-issue: 91768 +.. nonce: x_aKzv +.. section: C API + +:c:func:`Py_REFCNT`, :c:func:`Py_TYPE`, :c:func:`Py_SIZE` and +:c:func:`Py_IS_TYPE` functions argument type is now ``PyObject*``, rather +than ``const PyObject*``. Patch by Victor Stinner. + +.. + +.. date: 2022-04-19-17-05-39 +.. gh-issue: 91020 +.. nonce: BVJ8F3 +.. section: C API + +Add ``PyBytes_Type.tp_alloc`` to initialize ``PyBytesObject.ob_shash`` for +bytes subclasses. + +.. + +.. bpo: 40421 +.. date: 2022-04-08-11-29-36 +.. nonce: H0ORmT +.. section: C API + +Add ``PyFrame_GetLasti`` C-API function to access frame object's ``f_lasti`` +attribute safely from C code. + +.. + +.. bpo: 35134 +.. date: 2022-04-07-00-53-51 +.. nonce: zSjIzk +.. section: C API + +Remove the ``Include/code.h`` header file. C extensions should only include +the main ```` header file. Patch by Victor Stinner. + +.. + +.. bpo: 47169 +.. date: 2022-04-06-16-54-39 +.. nonce: EGzX4B +.. section: C API + +:c:func:`PyOS_CheckStack` is now exported in the Stable ABI on Windows. + +.. + +.. bpo: 47169 +.. date: 2022-04-06-16-29-14 +.. nonce: wVv2bT +.. section: C API + +:c:func:`PyThread_get_thread_native_id` is excluded from the stable ABI on +platforms where it doesn't exist (like Solaris). + +.. + +.. bpo: 46343 +.. date: 2022-01-11-12-52-37 +.. nonce: JQJWhZ +.. section: C API + +Added :c:func:`PyErr_GetHandledException` and +:c:func:`PyErr_SetHandledException` as simpler alternatives to +:c:func:`PyErr_GetExcInfo` and :c:func:`PyErr_SetExcInfo`. + +They are included in the stable ABI. diff --git a/Misc/NEWS.d/3.12.0a1.rst b/Misc/NEWS.d/3.12.0a1.rst new file mode 100644 index 00000000000..2a943fe481a --- /dev/null +++ b/Misc/NEWS.d/3.12.0a1.rst @@ -0,0 +1,6194 @@ +.. date: 2022-09-28-17-09-37 +.. gh-issue: 97616 +.. nonce: K1e3Xs +.. release date: 2022-10-25 +.. section: Security + +Fix multiplying a list by an integer (``list *= int``): detect the integer +overflow when the new allocated length is close to the maximum size. Issue +reported by Jordan Limor. Patch by Victor Stinner. + +.. + +.. date: 2022-09-07-10-42-00 +.. gh-issue: 97514 +.. nonce: Yggdsl +.. section: Security + +On Linux the :mod:`multiprocessing` module returns to using filesystem +backed unix domain sockets for communication with the *forkserver* process +instead of the Linux abstract socket namespace. Only code that chooses to +use the :ref:`"forkserver" start method ` is +affected. + +Abstract sockets have no permissions and could allow any user on the system +in the same `network namespace +`_ (often +the whole system) to inject code into the multiprocessing *forkserver* +process. This was a potential privilege escalation. Filesystem based socket +permissions restrict this to the *forkserver* process user as was the +default in Python 3.8 and earlier. + +This prevents Linux `CVE-2022-42919 +`_. + +.. + +.. date: 2022-06-15-20-09-23 +.. gh-issue: 87389 +.. nonce: QVaC3f +.. section: Security + +:mod:`http.server`: Fix an open redirection vulnerability in the HTTP server +when an URI path starts with ``//``. Vulnerability discovered, and initial +fix proposed, by Hamza Avvan. + +.. + +.. date: 2022-06-03-12-52-53 +.. gh-issue: 79096 +.. nonce: YVoxgC +.. section: Security + +LWPCookieJar and MozillaCookieJar create files with file mode 600 instead of +644 (Microsoft Windows is not affected) + +.. + +.. date: 2022-05-19-08-53-07 +.. gh-issue: 92888 +.. nonce: TLtR9W +.. section: Security + +Fix ``memoryview`` use after free when accessing the backing buffer in +certain cases. + +.. + +.. date: 2022-04-27-18-25-30 +.. gh-issue: 68966 +.. nonce: gjS8zs +.. section: Security + +The deprecated mailcap module now refuses to inject unsafe text (filenames, +MIME types, parameters) into shell commands. Instead of using such text, it +will warn and act as if a match was not found (or for test commands, as if +the test failed). + +.. + +.. date: 2022-10-19-23-48-46 +.. gh-issue: 98374 +.. nonce: eOBh8M +.. section: Core and Builtins + +Suppress ImportError for invalid query for help() command. Patch by Dong-hee +Na. + +.. + +.. date: 2022-10-19-20-53-38 +.. gh-issue: 98461 +.. nonce: iNmPDV +.. section: Core and Builtins + +Fix source location in bytecode for list, set and dict comprehensions as +well as generator expressions. + +.. + +.. date: 2022-10-19-18-03-28 +.. gh-issue: 98354 +.. nonce: GRGta3 +.. section: Core and Builtins + +Added unicode check for ``name`` attribute of ``spec`` argument passed in +:func:`_imp.create_builtin` function. + +.. + +.. date: 2022-10-18-16-17-44 +.. gh-issue: 98398 +.. nonce: x4rYK_ +.. section: Core and Builtins + +Fix source location of 'assert' bytecodes. + +.. + +.. date: 2022-10-18-14-11-32 +.. gh-issue: 98390 +.. nonce: H1sxJu +.. section: Core and Builtins + +Fix location of sub-expressions of boolean expressions, by reducing their +scope to that of the sub-expression. + +.. + +.. date: 2022-10-13-23-23-01 +.. gh-issue: 98254 +.. nonce: bC8IKt +.. section: Core and Builtins + +Modules from the standard library are now potentially suggested as part of +the error messages displayed by the interpreter when an :exc:`NameError` is +raised to the top level. Patch by Pablo Galindo + +.. + +.. date: 2022-10-06-23-13-34 +.. gh-issue: 97997 +.. nonce: JQaJKF +.. section: Core and Builtins + +Add running column offset to the tokenizer state to avoid calculating AST +column information with pointer arithmetic. + +.. + +.. date: 2022-10-06-20-41-29 +.. gh-issue: 97973 +.. nonce: gB-xWi +.. section: Core and Builtins + +Modify the tokenizer to return all necessary information the parser needs to +set location information in the AST nodes, so that the parser does not have +to calculate those doing pointer arithmetic. + +.. + +.. date: 2022-10-06-15-45-57 +.. gh-issue: 96078 +.. nonce: fS-6mU +.. section: Core and Builtins + +:func:`os.sched_yield` now release the GIL while calling sched_yield(2). +Patch by Dong-hee Na. + +.. + +.. date: 2022-10-06-14-14-28 +.. gh-issue: 97955 +.. nonce: Nq5VXD +.. section: Core and Builtins + +Migrate :mod:`zoneinfo` to Argument Clinic. + +.. + +.. date: 2022-10-06-06-36-29 +.. gh-issue: 97912 +.. nonce: jGRJpa +.. section: Core and Builtins + +The compiler now avoids quadratic behavior when finding which instructions +should use the :opcode:`LOAD_FAST_CHECK` opcode. + +.. + +.. date: 2022-10-06-02-11-34 +.. gh-issue: 97002 +.. nonce: Zvsk71 +.. section: Core and Builtins + +Fix an issue where several frame objects could be backed by the same +interpreter frame, possibly leading to corrupted memory and hard crashes of +the interpreter. + +.. + +.. date: 2022-10-05-17-02-22 +.. gh-issue: 97943 +.. nonce: LYAWlE +.. section: Core and Builtins + +Bugfix: :func:`PyFunction_GetAnnotations` should return a borrowed +reference. It was returning a new reference. + +.. + +.. date: 2022-10-05-11-37-15 +.. gh-issue: 97922 +.. nonce: Zu9Bge +.. section: Core and Builtins + +The Garbage Collector now runs only on the eval breaker mechanism of the +Python bytecode evaluation loop instead on object allocations. The GC can +also run when :c:func:`PyErr_CheckSignals` is called so C extensions that +need to run for a long time without executing any Python code also have a +chance to execute the GC periodically. + +.. + +.. date: 2022-10-05-00-37-27 +.. gh-issue: 65961 +.. nonce: z0Ys0y +.. section: Core and Builtins + +When ``__package__`` is different than ``__spec__.parent``, raise a +``DeprecationWarning`` instead of ``ImportWarning``. + +Also remove ``importlib.util.set_package()`` which was scheduled for +removal. + +.. + +.. date: 2022-10-04-17-02-18 +.. gh-issue: 97850 +.. nonce: E3QTRA +.. section: Core and Builtins + +Long deprecated, ``module_repr()`` should now be completely eradicated. + +.. + +.. date: 2022-10-04-14-04-40 +.. gh-issue: 86298 +.. nonce: QVM7G1 +.. section: Core and Builtins + +In cases where ``warnings.warn_explicit()`` consults the module's loader, an +``DeprecationWarning`` is issued when ``m.__loader__`` differs from +``m.__spec__.loader``. + +.. + +.. date: 2022-10-04-02-00-10 +.. gh-issue: 97779 +.. nonce: f3N1hI +.. section: Core and Builtins + +Ensure that all Python frame objects are backed by "complete" frames. + +.. + +.. date: 2022-10-03-16-12-39 +.. gh-issue: 91052 +.. nonce: MsYL9d +.. section: Core and Builtins + +Add API for subscribing to modification events on selected dictionaries. + +.. + +.. date: 2022-10-03-13-35-48 +.. gh-issue: 97752 +.. nonce: 0xTjJY +.. section: Core and Builtins + +Fix possible data corruption or crashes when accessing the ``f_back`` member +of newly-created generator or coroutine frames. + +.. + +.. date: 2022-10-01-08-55-09 +.. gh-issue: 97591 +.. nonce: pw6kkH +.. section: Core and Builtins + +Fixed a missing incref/decref pair in ``Exception.__setstate__()``. Patch by +Ofey Chan. + +.. + +.. date: 2022-09-30-13-26-58 +.. gh-issue: 97670 +.. nonce: n61vMR +.. section: Core and Builtins + +Remove the :func:`sys.getdxp` function and the +``Tools/scripts/analyze_dxp.py`` script. DXP stands for "dynamic execution +pairs". They were related to ``DYNAMIC_EXECUTION_PROFILE`` and ``DXPAIRS`` +macros which have been removed in Python 3.11. Python can now be built with +:option:`./configure --enable-pystats <--enable-pystats>` to gather +statistics on Python opcodes. Patch by Victor Stinner. + +.. + +.. date: 2022-09-29-15-19-29 +.. gh-issue: 94526 +.. nonce: wq5m6T +.. section: Core and Builtins + +Fix the Python path configuration used to initialized :data:`sys.path` at +Python startup. Paths are no longer encoded to UTF-8/strict to avoid +encoding errors if it contains surrogate characters (bytes paths are decoded +with the surrogateescape error handler). Patch by Victor Stinner. + +.. + +.. date: 2022-09-27-11-59-13 +.. gh-issue: 96670 +.. nonce: XrBBit +.. section: Core and Builtins + +The parser now raises :exc:`SyntaxError` when parsing source code containing +null bytes. Patch by Pablo Galindo + +.. + +.. date: 2022-09-21-16-06-37 +.. gh-issue: 96975 +.. nonce: BmE0XY +.. section: Core and Builtins + +Fix a crash occurring when :c:func:`PyEval_GetFrame` is called while the +topmost Python frame is in a partially-initialized state. + +.. + +.. date: 2022-09-21-14-38-31 +.. gh-issue: 96848 +.. nonce: WuoLzU +.. section: Core and Builtins + +Fix command line parsing: reject :option:`-X int_max_str_digits <-X>` option +with no value (invalid) when the :envvar:`PYTHONINTMAXSTRDIGITS` environment +variable is set to a valid limit. Patch by Victor Stinner. + +.. + +.. date: 2022-09-20-11-06-45 +.. gh-issue: 95921 +.. nonce: dkcRQn +.. section: Core and Builtins + +Fix overly-broad source position information for chained comparisons used as +branching conditions. + +.. + +.. date: 2022-09-19-03-35-01 +.. gh-issue: 96821 +.. nonce: izK6JA +.. section: Core and Builtins + +Fix undefined behaviour in ``audioop.c``. + +.. + +.. date: 2022-09-18-08-47-40 +.. gh-issue: 96821 +.. nonce: Co2iOq +.. section: Core and Builtins + +Fix undefined behaviour in ``_testcapimodule.c``. + +.. + +.. date: 2022-09-16-19-02-40 +.. gh-issue: 95778 +.. nonce: cJmnst +.. section: Core and Builtins + +When :exc:`ValueError` is raised if an integer is larger than the limit, +mention the :func:`sys.set_int_max_str_digits` function in the error +message. Patch by Victor Stinner. + +.. + +.. date: 2022-09-16-16-54-35 +.. gh-issue: 96387 +.. nonce: GRzewg +.. section: Core and Builtins + +At Python exit, sometimes a thread holding the GIL can wait forever for a +thread (usually a daemon thread) which requested to drop the GIL, whereas +the thread already exited. To fix the race condition, the thread which +requested the GIL drop now resets its request before exiting. Issue +discovered and analyzed by Mingliang ZHAO. Patch by Victor Stinner. + +.. + +.. date: 2022-09-16-12-36-13 +.. gh-issue: 96864 +.. nonce: PLU3i8 +.. section: Core and Builtins + +Fix a possible assertion failure, fatal error, or :exc:`SystemError` if a +line tracing event raises an exception while opcode tracing is enabled. + +.. + +.. date: 2022-09-13-21-45-07 +.. gh-issue: 95778 +.. nonce: Oll4_5 +.. section: Core and Builtins + +The ``PyLong_FromString`` function was refactored to make it more +maintainable and extensible. + +.. + +.. date: 2022-09-13-12-06-46 +.. gh-issue: 96678 +.. nonce: NqGFyb +.. section: Core and Builtins + +Fix undefined behaviour in C code of null pointer arithmetic. + +.. + +.. date: 2022-09-12-16-58-22 +.. gh-issue: 96754 +.. nonce: 0GRme5 +.. section: Core and Builtins + +Make sure that all frame objects created are created from valid interpreter +frames. Prevents the possibility of invalid frames in backtraces and signal +handlers. + +.. + +.. date: 2022-09-12-15-15-04 +.. gh-issue: 90997 +.. nonce: sZO8c9 +.. section: Core and Builtins + +Improve the performance of reading and writing inline bytecode caches on +some platforms. + +.. + +.. date: 2022-09-11-12-43-43 +.. gh-issue: 96751 +.. nonce: anRT6a +.. section: Core and Builtins + +Remove dead code from ``CALL_FUNCTION_EX`` opcode. + +.. + +.. date: 2022-09-11-00-37-50 +.. gh-issue: 90751 +.. nonce: VE8-zf +.. section: Core and Builtins + +:class:`memoryview` now supports half-floats. Patch by Dong-hee Na and +Antoine Pitrou. + +.. + +.. date: 2022-09-09-13-13-27 +.. gh-issue: 96678 +.. nonce: vMxi9F +.. section: Core and Builtins + +Fix case of undefined behavior in ceval.c + +.. + +.. date: 2022-09-08-20-58-10 +.. gh-issue: 64373 +.. nonce: AfCi36 +.. section: Core and Builtins + +Convert :mod:`_functools` to argument clinic. + +.. + +.. date: 2022-09-07-13-38-37 +.. gh-issue: 96641 +.. nonce: wky0Fc +.. section: Core and Builtins + +Do not expose ``KeyWrapper`` in :mod:`_functools`. + +.. + +.. date: 2022-09-07-12-02-11 +.. gh-issue: 96636 +.. nonce: YvN-K6 +.. section: Core and Builtins + +Ensure that tracing, ``sys.setrace()``, is turned on immediately. In +pre-release versions of 3.11, some tracing events might have been lost when +turning on tracing in a ``__del__`` method or interrupt. + +.. + +.. date: 2022-09-06-16-54-49 +.. gh-issue: 96572 +.. nonce: 8DRsaW +.. section: Core and Builtins + +Fix use after free in trace refs build mode. Patch by Kumar Aditya. + +.. + +.. date: 2022-09-06-16-22-13 +.. gh-issue: 96611 +.. nonce: 14wIX8 +.. section: Core and Builtins + +When loading a file with invalid UTF-8 inside a multi-line string, a correct +SyntaxError is emitted. + +.. + +.. date: 2022-09-06-14-26-36 +.. gh-issue: 96612 +.. nonce: P4ZbeY +.. section: Core and Builtins + +Make sure that incomplete frames do not show up in tracemalloc traces. + +.. + +.. date: 2022-09-06-11-19-03 +.. gh-issue: 90230 +.. nonce: YOtzs5 +.. section: Core and Builtins + +Fix compiler warnings and test failures when building with +``--enable-pystats``. + +.. + +.. date: 2022-09-05-19-20-44 +.. gh-issue: 96587 +.. nonce: bVxhX2 +.. section: Core and Builtins + +Correctly raise ``SyntaxError`` on exception groups (:pep:`654`) on python +versions prior to 3.11 + +.. + +.. date: 2022-09-05-16-43-44 +.. gh-issue: 96569 +.. nonce: 9lmTCC +.. section: Core and Builtins + +Remove two cases of undefined behavoir, by adding NULL checks. + +.. + +.. date: 2022-09-05-15-07-25 +.. gh-issue: 96582 +.. nonce: HEsL5s +.. section: Core and Builtins + +Fix possible ``NULL`` pointer dereference in ``_PyThread_CurrentFrames``. +Patch by Kumar Aditya. + +.. + +.. date: 2022-09-05-09-56-32 +.. gh-issue: 91079 +.. nonce: H4-DdU +.. section: Core and Builtins + +Separate Python recursion checking from C recursion checking which reduces +the chance of C stack overflow and allows the recursion limit to be +increased safely. + +.. + +.. date: 2022-09-02-16-47-52 +.. gh-issue: 93911 +.. nonce: vF-GWe +.. section: Core and Builtins + +Fix an issue that could prevent :opcode:`LOAD_ATTR` from specializing +properly when accessing properties. + +.. + +.. date: 2022-08-31-18-46-13 +.. gh-issue: 96348 +.. nonce: xzCoTP +.. section: Core and Builtins + +Emit a DeprecationWarning when :meth:`~generator.throw`, +:meth:`~coroutine.throw` or :meth:`~agen.athrow` are called with more than +one argument. + +.. + +.. date: 2022-08-29-13-06-58 +.. gh-issue: 95196 +.. nonce: eGRR4b +.. section: Core and Builtins + +Disable incorrect pickling of the C implemented classmethod descriptors. + +.. + +.. date: 2022-08-29-00-37-21 +.. gh-issue: 96364 +.. nonce: c-IVyb +.. section: Core and Builtins + +Fix text signatures of ``list.__getitem__`` and ``dict.__getitem__``. + +.. + +.. date: 2022-08-28-10-51-19 +.. gh-issue: 96352 +.. nonce: jTLD2d +.. section: Core and Builtins + +Fix :exc:`AttributeError` missing ``name`` and ``obj`` attributes in +:meth:`object.__getattribute__`. Patch by Philip Georgi. + +.. + +.. date: 2022-08-26-18-46-32 +.. gh-issue: 93554 +.. nonce: QEaCcK +.. section: Core and Builtins + +Change the jump opcodes so that all conditional jumps are forward jumps. +Backward jumps are converted by the assembler into a conditional forward +jump whose target is the fallthrough block (and with a reversed condition), +followed by an unconditional backward jump. For example: + +``POP_JUMP_IF_TRUE BACKWARD_TARGET`` becomes ``POP_JUMP_IF_FALSE NEXT_BLOCK; +JUMP BACKWARD_TARGET``. + +All the directed conditional jump opcodes were removed: +``POP_JUMP_FORWARD_IF_TRUE``, ``POP_JUMP_BACKWARD_IF_TRUE``, +``POP_JUMP_FORWARD_IF_FALSE``, ``POP_JUMP_BACKWARD_IF_FALSE``, +``POP_JUMP_FORWARD_IF_NONE``, ``POP_JUMP_BACKWARD_IF_NONE``, +``POP_JUMP_FORWARD_IF_NOT_NONE``, ``POP_JUMP_BACKWARD_IF_NOT_NONE``. + +The corresponding opcodes without direction are no longer +pseudo-instructions, and they implement the forward conditional jumps. + +.. + +.. date: 2022-08-25-10-19-34 +.. gh-issue: 96268 +.. nonce: AbYrLB +.. section: Core and Builtins + +Loading a file with invalid UTF-8 will now report the broken character at +the correct location. + +.. + +.. date: 2022-08-24-14-30-26 +.. gh-issue: 96237 +.. nonce: msif5f +.. section: Core and Builtins + +The internal field ``_PyInterpreterFrame.f_func`` is renamed to +``_PyInterpreterFrame.f_funcobj`` and may be any object. The ``f_globals`` +and ``f_builtin`` fields may hold junk values. + +It is safest to treat the ``_PyInterpreterFrame`` struct as opaque. + +.. + +.. date: 2022-08-22-21-33-28 +.. gh-issue: 96187 +.. nonce: W_6SRG +.. section: Core and Builtins + +Fixed a bug that caused ``_PyCode_GetExtra`` to return garbage for negative +indexes. Patch by Pablo Galindo + +.. + +.. date: 2022-08-20-18-36-40 +.. gh-issue: 96143 +.. nonce: nh3GFM +.. section: Core and Builtins + +Add a new ``-X perf`` Python command line option as well as +:func:`sys.activate_stack_trampoline` and +:func:`sys.deactivate_stack_trampoline` function in the :mod:`sys` module +that allows to set/unset the interpreter in a way that the Linux ``perf`` +profiler can detect Python calls. The new +:func:`sys.is_stack_trampoline_active` function allows to query the state of +the perf trampoline. Design by Pablo Galindo. Patch by Pablo Galindo and +Christian Heimes with contributions from Gregory P. Smith [Google] and Mark +Shannon. + +.. + +.. date: 2022-08-19-06-51-17 +.. gh-issue: 96071 +.. nonce: mVgPAo +.. section: Core and Builtins + +Fix a deadlock in :c:func:`PyGILState_Ensure` when allocating new thread +state. Patch by Kumar Aditya. + +.. + +.. date: 2022-08-18-13-47-59 +.. gh-issue: 96046 +.. nonce: 5Hqbka +.. section: Core and Builtins + +:c:func:`PyType_Ready` now initializes ``ht_cached_keys`` and performs +additional checks to ensure that type objects are properly configured. This +avoids crashes in 3rd party packages that don't use regular API to create +new types. + +.. + +.. date: 2022-08-15-21-08-11 +.. gh-issue: 96005 +.. nonce: 6eoc8k +.. section: Core and Builtins + +On WASI :data:`~errno.ENOTCAPABLE` is now mapped to :exc:`PermissionError`. +The :mod:`errno` modules exposes the new error number. ``getpath.py`` now +ignores :exc:`PermissionError` when it cannot open landmark files +``pybuilddir.txt`` and ``pyenv.cfg``. + +.. + +.. date: 2022-08-15-20-52-41 +.. gh-issue: 93678 +.. nonce: X7GuIJ +.. section: Core and Builtins + +Added test a harness for direct unit tests of the compiler's optimization +stage. The ``_testinternalcapi.optimize_cfg()`` function runs the optimiser +on a sequence of instructions. The ``CfgOptimizationTestCase`` class in +``test.support`` has utilities for invoking the optimizer and checking the +output. + +.. + +.. date: 2022-08-15-12-41-14 +.. gh-issue: 95245 +.. nonce: N4gOUV +.. section: Core and Builtins + +Reduces the size of a "simple" Python object from 8 to 6 words by moving the +weakreflist pointer into the pre-header directly before the object's +dict/values pointer. + +.. + +.. date: 2022-08-15-11-58-05 +.. gh-issue: 90997 +.. nonce: bWwV8Q +.. section: Core and Builtins + +Compile virtual :keyword:`try`/:keyword:`except` blocks to handle exceptions +raised during :meth:`~generator.close` or :meth:`~generator.throw` calls +through a suspended frame. + +.. + +.. date: 2022-08-14-10-04-44 +.. gh-issue: 95977 +.. nonce: gCTZb9 +.. section: Core and Builtins + +Optimized calling :meth:`~object.__get__` with vectorcall. Patch by Kumar +Aditya. + +.. + +.. date: 2022-08-12-18-13-49 +.. gh-issue: 91210 +.. nonce: AWMSLj +.. section: Core and Builtins + +Improve error message when a parameter without a default value follows one +with a default value, and show the same message, even when the +non-default/default sequence is preceded by positional-only parameters. + +.. + +.. date: 2022-08-12-13-04-25 +.. gh-issue: 95922 +.. nonce: YNCtyX +.. section: Core and Builtins + +Fixed bug where the compiler's ``eliminate_empty_basic_blocks`` function +ignores the last block of the code unit. + +.. + +.. date: 2022-08-11-11-01-56 +.. gh-issue: 95818 +.. nonce: iClLdl +.. section: Core and Builtins + +Skip over incomplete frames in :c:func:`PyThreadState_GetFrame`. + +.. + +.. date: 2022-08-11-09-19-55 +.. gh-issue: 95876 +.. nonce: YpQfoV +.. section: Core and Builtins + +Fix format string in ``_PyPegen_raise_error_known_location`` that can lead +to memory corruption on some 64bit systems. The function was building a +tuple with ``i`` (int) instead of ``n`` (Py_ssize_t) for Py_ssize_t +arguments. + +.. + +.. date: 2022-08-04-18-46-54 +.. gh-issue: 95605 +.. nonce: FbpCoG +.. section: Core and Builtins + +Fix misleading contents of error message when converting an all-whitespace +string to :class:`float`. + +.. + +.. date: 2022-07-31-13-23-12 +.. gh-issue: 95150 +.. nonce: 67FXVo +.. section: Core and Builtins + +Update code object hashing and equality to consider all debugging and +exception handling tables. This fixes an issue where certain non-identical +code objects could be "deduplicated" during compilation. + +.. + +.. date: 2022-07-31-03-22-58 +.. gh-issue: 91146 +.. nonce: Y2Hziy +.. section: Core and Builtins + +Reduce allocation size of :class:`list` from :meth:`str.split` and +:meth:`str.rsplit`. Patch by Dong-hee Na and Inada Naoki. + +.. + +.. date: 2022-07-28-19-07-06 +.. gh-issue: 87092 +.. nonce: 73IPS1 +.. section: Core and Builtins + +Create a 'jump target label' abstraction in the compiler so that the +compiler's codegen stage does not work directly with basic blocks. This +prepares the code for changes to the underlying CFG generation mechanism. + +.. + +.. date: 2022-07-28-08-33-31 +.. gh-issue: 95355 +.. nonce: yN4XVk +.. section: Core and Builtins + +``_PyPegen_Parser_New`` now properly detects token memory allocation errors. +Patch by Honglin Zhu. + +.. + +.. date: 2022-07-27-14-21-57 +.. gh-issue: 90081 +.. nonce: HVAS5x +.. section: Core and Builtins + +Run Python code in tracer/profiler function at full speed. Fixes slowdown in +earlier versions of 3.11. + +.. + +.. date: 2022-07-27-14-05-07 +.. gh-issue: 95324 +.. nonce: 28Q5u7 +.. section: Core and Builtins + +Emit a warning in debug mode if an object does not call +:c:func:`PyObject_GC_UnTrack` before deallocation. Patch by Pablo Galindo. + +.. + +.. date: 2022-07-26-12-59-03 +.. gh-issue: 95245 +.. nonce: GHWczn +.. section: Core and Builtins + +Merge managed dict and values pointer into a single tagged pointer to save +one word in the pre-header. + +.. + +.. date: 2022-07-26-09-31-12 +.. gh-issue: 93678 +.. nonce: W8vvgT +.. section: Core and Builtins + +Add cfg_builder struct and refactor the relevant code so that a cfg can be +constructed without an instance of the compiler struct. + +.. + +.. date: 2022-07-24-00-27-47 +.. gh-issue: 95185 +.. nonce: ghYTZx +.. section: Core and Builtins + +Prevented crashes in the AST constructor when compiling some absurdly long +expressions like ``"+0"*1000000``. :exc:`RecursionError` is now raised +instead. Patch by Pablo Galindo + +.. + +.. date: 2022-07-23-19-16-25 +.. gh-issue: 93351 +.. nonce: 0Jyvu- +.. section: Core and Builtins + +:class:`ast.AST` node positions are now validated when provided to +:func:`compile` and other related functions. If invalid positions are +detected, a :exc:`ValueError` will be raised. + +.. + +.. date: 2022-07-22-12-53-34 +.. gh-issue: 94438 +.. nonce: hNqACc +.. section: Core and Builtins + +Fix an issue that caused extended opcode arguments and some conditional pops +to be ignored when calculating valid jump targets for assignments to the +``f_lineno`` attribute of frame objects. In some cases, this could cause +inconsistent internal state, resulting in a hard crash of the interpreter. + +.. + +.. date: 2022-07-21-19-19-20 +.. gh-issue: 95060 +.. nonce: 4xdT1f +.. section: Core and Builtins + +Undocumented ``PyCode_Addr2Location`` function now properly returns when +``addrq`` argument is less than zero. + +.. + +.. date: 2022-07-21-17-54-52 +.. gh-issue: 95113 +.. nonce: NnSLpT +.. section: Core and Builtins + +Replace all ``EXTENDED_ARG_QUICK`` instructions with basic +:opcode:`EXTENDED_ARG` instructions in unquickened code. Consumers of +non-adaptive bytecode should be able to handle extended arguments the same +way they were handled in CPython 3.10 and older. + +.. + +.. date: 2022-07-20-13-46-01 +.. gh-issue: 91409 +.. nonce: dhL8Zo +.. section: Core and Builtins + +Fix incorrect source location info caused by certain optimizations in the +bytecode compiler. + +.. + +.. date: 2022-07-20-09-04-55 +.. gh-issue: 95023 +.. nonce: bs-xd7 +.. section: Core and Builtins + +Implement :func:`os.setns` and :func:`os.unshare` for Linux. Patch by Noam +Cohen. + +.. + +.. date: 2022-07-19-16-30-59 +.. gh-issue: 94036 +.. nonce: _6Utkm +.. section: Core and Builtins + +Fix incorrect source location info for some multi-line attribute accesses +and method calls. + +.. + +.. date: 2022-07-19-09-41-55 +.. gh-issue: 94938 +.. nonce: xYBlM7 +.. section: Core and Builtins + +Fix error detection in some builtin functions when keyword argument name is +an instance of a str subclass with overloaded ``__eq__`` and ``__hash__``. +Previously it could cause SystemError or other undesired behavior. + +.. + +.. date: 2022-07-19-04-34-56 +.. gh-issue: 94996 +.. nonce: dV564A +.. section: Core and Builtins + +:func:`ast.parse` will no longer parse function definitions with +positional-only params when passed ``feature_version`` less than ``(3, 8)``. +Patch by Shantanu Jain. + +.. + +.. date: 2022-07-18-14-19-21 +.. gh-issue: 94739 +.. nonce: NQJQi7 +.. section: Core and Builtins + +Allow jumping within, out of, and across exception handlers in the debugger. + +.. + +.. date: 2022-07-18-05-10-29 +.. gh-issue: 94949 +.. nonce: OsZ7_s +.. section: Core and Builtins + +:func:`ast.parse` will no longer parse parenthesized context managers when +passed ``feature_version`` less than ``(3, 9)``. Patch by Shantanu Jain. + +.. + +.. date: 2022-07-18-04-48-34 +.. gh-issue: 94947 +.. nonce: df9gUw +.. section: Core and Builtins + +:func:`ast.parse` will no longer parse assignment expressions when passed +``feature_version`` less than ``(3, 8)``. Patch by Shantanu Jain. + +.. + +.. date: 2022-07-17-15-54-29 +.. gh-issue: 91256 +.. nonce: z7i7Q5 +.. section: Core and Builtins + +Ensures the program name is known for help text during interpreter startup. + +.. + +.. date: 2022-07-16-08-14-17 +.. gh-issue: 94869 +.. nonce: eRwMsX +.. section: Core and Builtins + +Fix the column offsets for some expressions in multi-line f-strings +:mod:`ast` nodes. Patch by Pablo Galindo. + +.. + +.. date: 2022-07-15-22-47-44 +.. gh-issue: 94893 +.. nonce: YiJYcW +.. section: Core and Builtins + +Fix an issue where frame object manipulations could corrupt inline bytecode +caches. + +.. + +.. date: 2022-07-15-22-16-08 +.. gh-issue: 94822 +.. nonce: zRRzBN +.. section: Core and Builtins + +Fix an issue where lookups of metaclass descriptors may be ignored when an +identically-named attribute also exists on the class itself. + +.. + +.. date: 2022-07-15-16-15-04 +.. gh-issue: 91153 +.. nonce: HiBmtt +.. section: Core and Builtins + +Fix an issue where a :class:`bytearray` item assignment could crash if it's +resized by the new value's :meth:`__index__` method. + +.. + +.. date: 2022-07-14-10-07-53 +.. gh-issue: 90699 +.. nonce: x3aG9m +.. section: Core and Builtins + +Fix reference counting bug in :meth:`bool.__repr__`. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-08-16-44-11 +.. gh-issue: 94694 +.. nonce: VkL2CM +.. section: Core and Builtins + +Fix an issue that could cause code with multi-line method lookups to have +misleading or incorrect column offset information. In some cases (when +compiling a hand-built AST) this could have resulted in a hard crash of the +interpreter. + +.. + +.. date: 2022-07-08-11-44-45 +.. gh-issue: 93252 +.. nonce: i2358c +.. section: Core and Builtins + +Fix an issue that caused internal frames to outlive failed Python function +calls, possibly resulting in memory leaks or hard interpreter crashes. + +.. + +.. date: 2022-07-07-21-13-25 +.. gh-issue: 94215 +.. nonce: _Sv9Ms +.. section: Core and Builtins + +Fix an issue where exceptions raised by line-tracing events would cause +frames to be left in an invalid state, possibly resulting in a hard crash of +the interpreter. + +.. + +.. date: 2022-07-06-14-02-26 +.. gh-issue: 92228 +.. nonce: 44Cbly +.. section: Core and Builtins + +Disable the compiler's inline-small-exit-blocks optimization for exit blocks +that are associated with source code lines. This fixes a bug where the +debugger cannot tell where an exception handler ends and the following code +block begins. + +.. + +.. date: 2022-07-01-20-00-19 +.. gh-issue: 94485 +.. nonce: mo5st7 +.. section: Core and Builtins + +Line number of a module's ``RESUME`` instruction is set to 0 as specified in +:pep:`626`. + +.. + +.. date: 2022-06-30-15-07-26 +.. gh-issue: 94438 +.. nonce: btzHSk +.. section: Core and Builtins + +Account for instructions that can push NULL to the stack when setting line +number in a frame. Prevents some (unlikely) crashes. + +.. + +.. date: 2022-06-29-22-18-36 +.. gh-issue: 91719 +.. nonce: 3APYYI +.. section: Core and Builtins + +Reload ``opcode`` when raising ``unknown opcode error`` in the interpreter +main loop, for C compilers to generate dispatching code independently. + +.. + +.. date: 2022-06-29-15-45-04 +.. gh-issue: 94329 +.. nonce: olUQyk +.. section: Core and Builtins + +Compile and run code with unpacking of extremely large sequences (1000s of +elements). Such code failed to compile. It now compiles and runs correctly. + +.. + +.. date: 2022-06-28-14-20-36 +.. gh-issue: 94360 +.. nonce: DiEnen +.. section: Core and Builtins + +Fixed a tokenizer crash when reading encoded files with syntax errors from +``stdin`` with non utf-8 encoded text. Patch by Pablo Galindo + +.. + +.. date: 2022-06-28-12-41-17 +.. gh-issue: 88116 +.. nonce: A7fEl_ +.. section: Core and Builtins + +Fix an issue when reading line numbers from code objects if the encoded line +numbers are close to ``INT_MIN``. Patch by Pablo Galindo + +.. + +.. date: 2022-06-28-10-08-06 +.. gh-issue: 94262 +.. nonce: m-HWUZ +.. section: Core and Builtins + +Don't create frame objects for incomplete frames. Prevents the creation of +generators and closures from being observable to Python and C extensions, +restoring the behavior of 3.10 and earlier. + +.. + +.. date: 2022-06-26-14-37-03 +.. gh-issue: 94192 +.. nonce: ab7tn7 +.. section: Core and Builtins + +Fix error for dictionary literals with invalid expression as value. + +.. + +.. date: 2022-06-25-10-19-43 +.. gh-issue: 87995 +.. nonce: aMDHnp +.. section: Core and Builtins + +:class:`types.MappingProxyType` instances are now hashable if the underlying +mapping is hashable. + +.. + +.. date: 2022-06-24-14-06-20 +.. gh-issue: 93883 +.. nonce: 8jVQQ4 +.. section: Core and Builtins + +Revise the display strategy of traceback enhanced error locations. The +indicators are only shown when the location doesn't span the whole line. + +.. + +.. date: 2022-06-23-12-10-39 +.. gh-issue: 94163 +.. nonce: SqAfQq +.. section: Core and Builtins + +Add :opcode:`BINARY_SLICE` and :opcode:`STORE_SLICE` instructions for more +efficient handling and better specialization of slicing operations, where +the slice is explicit in the source code. + +.. + +.. date: 2022-06-20-13-48-57 +.. gh-issue: 94021 +.. nonce: o78q3G +.. section: Core and Builtins + +Fix unreachable code warning in ``Python/specialize.c``. + +.. + +.. date: 2022-06-18-17-00-33 +.. gh-issue: 93911 +.. nonce: y286of +.. section: Core and Builtins + +Specialize ``LOAD_ATTR`` for objects with custom ``__getattribute__``. + +.. + +.. date: 2022-06-17-16-30-24 +.. gh-issue: 93955 +.. nonce: LmiAe9 +.. section: Core and Builtins + +Improve performance of attribute lookups on objects with custom +``__getattribute__`` and ``__getattr__``. Patch by Ken Jin. + +.. + +.. date: 2022-06-16-16-53-22 +.. gh-issue: 93911 +.. nonce: RDwIiK +.. section: Core and Builtins + +Specialize ``LOAD_ATTR`` for ``property()`` attributes. + +.. + +.. date: 2022-06-15-16-45-53 +.. gh-issue: 93678 +.. nonce: 1I_ZT3 +.. section: Core and Builtins + +Refactor compiler optimisation code so that it no longer needs the ``struct +assembler`` and ``struct compiler`` passed around. Instead, each function +takes the CFG and other data that it actually needs. This will make it +possible to test this code directly. + +.. + +.. date: 2022-06-15-11-16-13 +.. gh-issue: 93841 +.. nonce: 06zqX3 +.. section: Core and Builtins + +When built with ``-enable-pystats``, ``sys._stats_on()``, +``sys._stats_off()``, ``sys._stats_clear()`` and ``sys._stats_dump()`` +functions have been added to enable gathering stats for parts of programs. + +.. + +.. date: 2022-06-13-13-55-34 +.. gh-issue: 93516 +.. nonce: HILrDl +.. section: Core and Builtins + +Store offset of first traceable instruction in code object to avoid having +to recompute it for each instruction when tracing. + +.. + +.. date: 2022-06-13-10-48-09 +.. gh-issue: 93516 +.. nonce: yJSait +.. section: Core and Builtins + +Lazily create a table mapping bytecode offsets to line numbers to speed up +calculation of line numbers when tracing. + +.. + +.. date: 2022-06-12-19-31-56 +.. gh-issue: 89828 +.. nonce: bq02M7 +.. section: Core and Builtins + +:class:`types.GenericAlias` no longer relays the ``__class__`` attribute. +For example, ``isinstance(list[int], type)`` no longer returns ``True``. + +.. + +.. date: 2022-06-10-16-57-35 +.. gh-issue: 93678 +.. nonce: 1WBnHt +.. section: Core and Builtins + +Refactor the compiler to reduce boilerplate and repetition. + +.. + +.. date: 2022-06-10-12-03-17 +.. gh-issue: 93671 +.. nonce: idkQqG +.. section: Core and Builtins + +Fix some exponential backtrace case happening with deeply nested sequence +patterns in match statements. Patch by Pablo Galindo + +.. + +.. date: 2022-06-10-10-31-18 +.. gh-issue: 93662 +.. nonce: -7RSC1 +.. section: Core and Builtins + +Make sure that the end column offsets are correct in multi-line method +calls. Previously, the end column could precede the column offset. + +.. + +.. date: 2022-06-09-19-19-02 +.. gh-issue: 93461 +.. nonce: 5DqP1e +.. section: Core and Builtins + +:func:`importlib.invalidate_caches` now drops entries from +:data:`sys.path_importer_cache` with a relative path as name. This solves a +caching issue when a process changes its current working directory. + +``FileFinder`` no longer inserts a dot in the path, e.g. ``/egg/./spam`` is +now ``/egg/spam``. + +.. + +.. date: 2022-06-09-09-08-29 +.. gh-issue: 93621 +.. nonce: -_Pn1d +.. section: Core and Builtins + +Change order of bytecode instructions emitted for :keyword:`with` and +:keyword:`async with` to reduce the number of entries in the exception +table. + +.. + +.. date: 2022-06-06-14-28-24 +.. gh-issue: 93533 +.. nonce: lnC0CC +.. section: Core and Builtins + +Reduce the size of the inline cache for ``LOAD_METHOD`` by 2 bytes. + +.. + +.. date: 2022-06-02-23-00-08 +.. gh-issue: 93444 +.. nonce: m63DIs +.. section: Core and Builtins + +Removed redundant fields from the compiler's basicblock struct: +``b_nofallthrough``, ``b_exit``, ``b_return``. They can be easily calculated +from the opcode of the last instruction of the block. + +.. + +.. date: 2022-06-02-08-28-55 +.. gh-issue: 93429 +.. nonce: DZTWHx +.. section: Core and Builtins + +``LOAD_METHOD`` instruction has been removed. It was merged back into +``LOAD_ATTR``. + +.. + +.. date: 2022-06-01-17-47-40 +.. gh-issue: 93418 +.. nonce: 24dJuc +.. section: Core and Builtins + +Fixed an assert where an f-string has an equal sign '=' following an +expression, but there's no trailing brace. For example, f"{i=". + +.. + +.. date: 2022-05-31-16-36-30 +.. gh-issue: 93382 +.. nonce: Jf6gAj +.. section: Core and Builtins + +Cache the result of :c:func:`PyCode_GetCode` function to restore the O(1) +lookup of the :attr:`~types.CodeType.co_code` attribute. + +.. + +.. date: 2022-05-30-19-00-38 +.. gh-issue: 93359 +.. nonce: zXV3A0 +.. section: Core and Builtins + +Ensure that custom :mod:`ast` nodes without explicit end positions can be +compiled. Patch by Pablo Galindo. + +.. + +.. date: 2022-05-30-15-51-11 +.. gh-issue: 93356 +.. nonce: l5wnzW +.. section: Core and Builtins + +Code for exception handlers is emitted at the end of the code unit's +bytecode. This avoids one jump when no exception is raised. + +.. + +.. date: 2022-05-30-15-35-42 +.. gh-issue: 93354 +.. nonce: RZk8gs +.. section: Core and Builtins + +Use exponential backoff for specialization counters in the interpreter. Can +reduce the number of failed specializations significantly and avoid slowdown +for those parts of a program that are not suitable for specialization. + +.. + +.. date: 2022-05-30-14-50-03 +.. gh-issue: 93283 +.. nonce: XDO2ZQ +.. section: Core and Builtins + +Improve error message for invalid syntax of conversion character in f-string +expressions. + +.. + +.. date: 2022-05-30-10-22-46 +.. gh-issue: 93345 +.. nonce: gi1A4L +.. section: Core and Builtins + +Fix a crash in substitution of a ``TypeVar`` in nested generic alias after +``TypeVarTuple``. + +.. + +.. date: 2022-05-25-21-56-25 +.. gh-issue: 93223 +.. nonce: gTOGVZ +.. section: Core and Builtins + +When a bytecode instruction jumps to an unconditional jump instruction, the +first instruction can often be optimized to target the unconditional jump's +target directly. For tracing reasons, this would previously only occur if +both instructions have the same line number. This also now occurs if the +unconditional jump is artificial, i.e., if it has no associated line number. + +.. + +.. date: 2022-05-25-12-30-12 +.. gh-issue: 84694 +.. nonce: 5sjy2w +.. section: Core and Builtins + +The ``--experimental-isolated-subinterpreters`` configure option and +``EXPERIMENTAL_ISOLATED_SUBINTERPRETERS`` macro have been removed. + +.. + +.. date: 2022-05-25-04-07-22 +.. gh-issue: 91924 +.. nonce: -UyO4q +.. section: Core and Builtins + +Fix ``__lltrace__`` debug feature if the stdout encoding is not UTF-8. Patch +by Victor Stinner. + +.. + +.. date: 2022-05-24-14-35-48 +.. gh-issue: 93040 +.. nonce: 9X6Ofu +.. section: Core and Builtins + +Wraps unused parameters in ``Objects/obmalloc.c`` with ``Py_UNUSED``. + +.. + +.. date: 2022-05-23-18-36-07 +.. gh-issue: 93143 +.. nonce: X1Yqxm +.. section: Core and Builtins + +Avoid ``NULL`` checks for uninitialized local variables by determining at +compile time which variables must be initialized. + +.. + +.. date: 2022-05-22-02-37-50 +.. gh-issue: 93061 +.. nonce: r70Imp +.. section: Core and Builtins + +Backward jumps after ``async for`` loops are no longer given dubious line +numbers. + +.. + +.. date: 2022-05-21-23-21-37 +.. gh-issue: 93065 +.. nonce: 5I18WC +.. section: Core and Builtins + +Fix contextvars HAMT implementation to handle iteration over deep trees. + +The bug was discovered and fixed by Eli Libman. See +`MagicStack/immutables#84 +`_ for more details. + +.. + +.. date: 2022-05-20-13-32-24 +.. gh-issue: 93012 +.. nonce: e9B-pv +.. section: Core and Builtins + +Added the new function :c:func:`PyType_FromMetaclass`, which generalizes the +existing :c:func:`PyType_FromModuleAndSpec` using an additional metaclass +argument. This is useful for language binding tools, where it can be used to +intercept type-related operations like subclassing or static attribute +access by specifying a metaclass with custom slots. + +Importantly, :c:func:`PyType_FromMetaclass` is available in the Limited API, +which provides a path towards migrating more binding tools onto the Stable +ABI. + +.. + +.. date: 2022-05-20-09-25-34 +.. gh-issue: 93021 +.. nonce: k3Aji2 +.. section: Core and Builtins + +Fix the :attr:`__text_signature__` for :meth:`__get__` methods implemented +in C. Patch by Jelle Zijlstra. + +.. + +.. date: 2022-05-19-15-29-53 +.. gh-issue: 89914 +.. nonce: 8bAffH +.. section: Core and Builtins + +The operand of the ``YIELD_VALUE`` instruction is set to the stack depth. +This is done to help frame handling on ``yield`` and may assist debuggers. + +.. + +.. date: 2022-05-19-13-25-50 +.. gh-issue: 92955 +.. nonce: kmNV33 +.. section: Core and Builtins + +Fix memory leak in code object's lines and positions iterators as they were +not finalized at exit. Patch by Kumar Aditya. + +.. + +.. date: 2022-05-18-18-34-45 +.. gh-issue: 92930 +.. nonce: kpYPOb +.. section: Core and Builtins + +Fixed a crash in ``_pickle.c`` from mutating collections during +``__reduce__`` or ``persistent_id``. + +.. + +.. date: 2022-05-18-12-55-35 +.. gh-issue: 90690 +.. nonce: TKuoTa +.. section: Core and Builtins + +The PRECALL instruction has been removed. It offered only a small advantage +for specialization and is not needed in the vast majority of cases. + +.. + +.. date: 2022-05-18-08-32-33 +.. gh-issue: 92914 +.. nonce: tJUeTD +.. section: Core and Builtins + +Always round the allocated size for lists up to the nearest even number. + +.. + +.. date: 2022-05-17-20-41-43 +.. gh-issue: 92858 +.. nonce: eIXJTn +.. section: Core and Builtins + +Improve error message for some suites with syntax error before ':' + +.. + +.. date: 2022-05-15-15-25-05 +.. gh-issue: 90473 +.. nonce: MoPHYW +.. section: Core and Builtins + +Decrease default recursion limit on WASI to address limited call stack size. + +.. + +.. date: 2022-05-14-13-22-11 +.. gh-issue: 92804 +.. nonce: rAqpI2 +.. section: Core and Builtins + +Fix memory leak in ``memoryview`` iterator as it was not finalized at exit. +Patch by Kumar Aditya. + +.. + +.. date: 2022-05-13-12-36-10 +.. gh-issue: 92777 +.. nonce: Odo4vP +.. section: Core and Builtins + +Specialize ``LOAD_METHOD`` for objects with lazy dictionaries. Patch by Ken +Jin. + +.. + +.. date: 2022-05-13-00-57-18 +.. gh-issue: 92658 +.. nonce: YdhFE2 +.. section: Core and Builtins + +Add support for connecting and binding to Hyper-V sockets on Windows Hyper-V +hosts and guests. + +.. + +.. date: 2022-05-12-13-23-19 +.. gh-issue: 92236 +.. nonce: sDRzUe +.. section: Core and Builtins + +Remove spurious "LINE" event when starting a generator or coroutine, visible +tracing functions implemented in C. + +.. + +.. date: 2022-05-11-09-16-54 +.. gh-issue: 91102 +.. nonce: lenv9h +.. section: Core and Builtins + +:meth:`_warnings.warn_explicit` is ported to Argument Clinic. + +.. + +.. date: 2022-05-10-11-34-35 +.. gh-issue: 92619 +.. nonce: u0V0lY +.. section: Core and Builtins + +Make the compiler duplicate an exit block only if none of its instructions +have a lineno (previously only the first instruction in the block was +checked, leading to unnecessarily duplicated blocks). + +.. + +.. date: 2022-05-08-19-43-31 +.. gh-issue: 88750 +.. nonce: 1BjJg- +.. section: Core and Builtins + +The deprecated debug build only ``PYTHONTHREADDEBUG`` environment variable +no longer does anything. + +.. + +.. date: 2022-05-03-20-12-18 +.. gh-issue: 92261 +.. nonce: aigLnb +.. section: Core and Builtins + +Fix hang when trying to iterate over a ``typing.Union``. + +.. + +.. date: 2022-04-24-02-22-10 +.. gh-issue: 91432 +.. nonce: YPJAK6 +.. section: Core and Builtins + +Specialized the :opcode:`FOR_ITER` opcode using the PEP 659 machinery + +.. + +.. date: 2022-04-16-15-37-55 +.. gh-issue: 91399 +.. nonce: trLbK6 +.. section: Core and Builtins + +Removed duplicate '{0, 0, 0, 0, 0, 0}' entry in 'Objects/unicodetype_db.h'. + +.. + +.. date: 2022-04-15-22-12-53 +.. gh-issue: 91578 +.. nonce: rDOtyK +.. section: Core and Builtins + +Updates the error message for abstract class. + +.. + +.. bpo: 47091 +.. date: 2022-03-22-13-12-27 +.. nonce: tJcy-P +.. section: Core and Builtins + +Improve performance of repetition of :class:`list` and :class:`tuple` by +using ``memcpy`` to copy data and performing the reference increments in one +step. + +.. + +.. bpo: 46142 +.. date: 2022-01-02-14-53-59 +.. nonce: WayjgT +.. section: Core and Builtins + +Make ``--help`` output shorter by moving some info to the new ``--help-env`` +and ``--help-xoptions`` command-line options. Also add ``--help-all`` option +to print complete usage. + +.. + +.. bpo: 42316 +.. date: 2020-11-15-02-08-43 +.. nonce: LqdkWK +.. section: Core and Builtins + +Document some places where an assignment expression needs parentheses. + +.. + +.. date: 2022-10-23-18-30-39 +.. gh-issue: 89237 +.. nonce: kBui30 +.. section: Library + +Fix hang on Windows in ``subprocess.wait_closed()`` in :mod:`asyncio` with +:class:`~asyncio.ProactorEventLoop`. Patch by Kumar Aditya. + +.. + +.. date: 2022-10-19-09-29-12 +.. gh-issue: 97928 +.. nonce: xj3im7 +.. section: Library + +:meth:`tkinter.Text.count` raises now an exception for options starting with +"-" instead of silently ignoring them. + +.. + +.. date: 2022-10-18-15-41-37 +.. gh-issue: 98393 +.. nonce: vhPu4L +.. section: Library + +The :mod:`os` module no longer accepts bytes-like paths, like +:class:`bytearray` and :class:`memoryview` types: only the exact +:class:`bytes` type is accepted for bytes strings. Patch by Victor Stinner. + +.. + +.. date: 2022-10-17-12-49-02 +.. gh-issue: 98363 +.. nonce: aFmSP- +.. section: Library + +Added itertools.batched() to batch data into lists of a given length with +the last list possibly being shorter than the others. + +.. + +.. date: 2022-10-16-15-31-50 +.. gh-issue: 98331 +.. nonce: Y5kPOX +.. section: Library + +Update the bundled copies of pip and setuptools to versions 22.3 and 65.5.0 +respectively. + +.. + +.. date: 2022-10-16-06-18-59 +.. gh-issue: 98307 +.. nonce: b2_CDu +.. section: Library + +A :meth:`~logging.handlers.SysLogHandler.createSocket` method was added to +:class:`~logging.handlers.SysLogHandler`. + +.. + +.. date: 2022-10-14-19-57-37 +.. gh-issue: 96035 +.. nonce: 0xcX-p +.. section: Library + +Fix bug in :func:`urllib.parse.urlparse` that causes certain port numbers +containing whitespace, underscores, plus and minus signs, or non-ASCII +digits to be incorrectly accepted. + +.. + +.. date: 2022-10-14-12-29-05 +.. gh-issue: 98257 +.. nonce: aMSMs2 +.. section: Library + +Make :func:`sys.setprofile` and :func:`sys.settrace` functions reentrant. +They can no long fail with: ``RuntimeError("Cannot install a trace function +while another trace function is being installed")``. Patch by Victor +Stinner. + +.. + +.. date: 2022-10-14-11-46-31 +.. gh-issue: 98251 +.. nonce: Uxc9al +.. section: Library + +Allow :mod:`venv` to pass along :envvar:`PYTHON*` variables to ``ensurepip`` +and ``pip`` when they do not impact path resolution + +.. + +.. date: 2022-10-12-11-20-54 +.. gh-issue: 94597 +.. nonce: GYJZlb +.. section: Library + +Deprecated :meth:`asyncio.AbstractEventLoopPolicy.get_child_watcher` and +:meth:`asyncio.AbstractEventLoopPolicy.set_child_watcher` methods to be +removed in Python 3.14. Patch by Kumar Aditya. + +.. + +.. date: 2022-10-12-10-00-40 +.. gh-issue: 98178 +.. nonce: hspH51 +.. section: Library + +On macOS, fix a crash in :func:`syslog.syslog` in multi-threaded +applications. On macOS, the libc ``syslog()`` function is not thread-safe, +so :func:`syslog.syslog` no longer releases the GIL to call it. Patch by +Victor Stinner. + +.. + +.. date: 2022-10-10-09-52-21 +.. gh-issue: 44098 +.. nonce: okcqJt +.. section: Library + +Release the GIL when creating :class:`mmap.mmap` objects on Unix. + +.. + +.. date: 2022-10-09-12-12-38 +.. gh-issue: 87730 +.. nonce: ClgP3f +.. section: Library + +Wrap network errors consistently in urllib FTP support, so the test suite +doesn't fail when a network is available but the public internet is not +reachable. + +.. + +.. date: 2022-10-08-06-59-46 +.. gh-issue: 94597 +.. nonce: TsS0oT +.. section: Library + +The child watcher classes :class:`~asyncio.MultiLoopChildWatcher`, +:class:`~asyncio.FastChildWatcher` and :class:`~asyncio.SafeChildWatcher` +are deprecated and will be removed in Python 3.14. Patch by Kumar Aditya. + +.. + +.. date: 2022-10-07-09-52-37 +.. gh-issue: 98023 +.. nonce: aliEcl +.. section: Library + +Change default child watcher to :class:`~asyncio.PidfdChildWatcher` on Linux +systems which supports it. Patch by Kumar Aditya. + +.. + +.. date: 2022-10-06-23-42-00 +.. gh-issue: 90985 +.. nonce: s280JY +.. section: Library + +Earlier in 3.11 we deprecated ``asyncio.Task.cancel("message")``. We +realized we were too harsh, and have undeprecated it. + +.. + +.. date: 2022-10-06-17-59-22 +.. gh-issue: 65961 +.. nonce: SXlQnI +.. section: Library + +Do not rely solely on ``__cached__`` on modules; code will also support +``__spec__.cached``. + +.. + +.. date: 2022-10-05-20-52-17 +.. gh-issue: 97646 +.. nonce: Q4fVww +.. section: Library + +Replace deprecated ``application/javascript`` with ``text/javascript`` in +:mod:`mimetypes`. See :rfc:`9239`. Patch by Noam Cohen. + +.. + +.. date: 2022-10-05-16-10-24 +.. gh-issue: 97930 +.. nonce: NPSrzE +.. section: Library + +Apply changes from importlib_resources 5.8 and 5.9: ``Traversable.joinpath`` +provides a concrete implementation. ``as_file`` now supports directories of +resources. + +.. + +.. date: 2022-10-05-11-40-02 +.. gh-issue: 97850 +.. nonce: NzdREm +.. section: Library + +Remove deprecated :func:`importlib.utils.set_loader` and +:func:`importlib.utils.module_for_loader` from :mod:`importlib.utils`. + +.. + +.. date: 2022-10-04-21-21-41 +.. gh-issue: 97837 +.. nonce: 19q-eg +.. section: Library + +Change deprecate warning message in :mod:`unittest` from + +``It is deprecated to return a value!=None`` + +to + +``It is deprecated to return a value that is not None from a test case`` + +.. + +.. date: 2022-10-04-07-55-19 +.. gh-issue: 97825 +.. nonce: mNdv1l +.. section: Library + +Fixes :exc:`AttributeError` when :meth:`subprocess.check_output` is used +with argument ``input=None`` and either of the arguments *encoding* or +*errors* are used. + +.. + +.. date: 2022-10-04-00-43-43 +.. gh-issue: 97008 +.. nonce: 3rjtt6 +.. section: Library + +:exc:`NameError` and :exc:`AttributeError` spelling suggestions provided +since :gh:`82711` are now also emitted by the pure Python :mod:`traceback` +module. Tests for those suggestions now exercise both implementations to +ensure they are equivalent. Patch by Carl Friedrich Bolz-Tereick and Åukasz +Langa. + +.. + +.. date: 2022-10-03-14-42-13 +.. gh-issue: 97799 +.. nonce: Y1iJvf +.. section: Library + +:mod:`dataclass` now uses :func:`inspect.get_annotations` to examine the +annotations on class objects. + +.. + +.. date: 2022-10-03-13-25-19 +.. gh-issue: 97781 +.. nonce: gCLLef +.. section: Library + +Removed deprecated interfaces in ``importlib.metadata`` (entry points +accessed as dictionary, implicit dictionary construction of sequence of +``EntryPoint`` objects, mutablility of ``EntryPoints`` result, access of +entry point by index). ``entry_points`` now has a simpler, more +straightforward API (returning ``EntryPoints``). + +.. + +.. date: 2022-09-30-15-56-20 +.. gh-issue: 96827 +.. nonce: lzy1iw +.. section: Library + +Avoid spurious tracebacks from :mod:`asyncio` when default executor cleanup +is delayed until after the event loop is closed (e.g. as the result of a +keyboard interrupt). + +.. + +.. date: 2022-09-30-09-22-37 +.. gh-issue: 95534 +.. nonce: ndEfPj +.. section: Library + +:meth:`gzip.GzipFile.read` reads 10% faster. + +.. + +.. date: 2022-09-29-23-22-24 +.. gh-issue: 97592 +.. nonce: tpJg_J +.. section: Library + +Avoid a crash in the C version of +:meth:`asyncio.Future.remove_done_callback` when an evil argument is passed. + +.. + +.. date: 2022-09-29-08-15-55 +.. gh-issue: 97639 +.. nonce: JSjWYW +.. section: Library + +Remove ``tokenize.NL`` check from :mod:`tabnanny`. + +.. + +.. date: 2022-09-25-23-24-52 +.. gh-issue: 97545 +.. nonce: HZLSNt +.. section: Library + +Make Semaphore run faster. + +.. + +.. date: 2022-09-25-20-42-33 +.. gh-issue: 73588 +.. nonce: uVtjEA +.. section: Library + +Fix generation of the default name of :class:`tkinter.Checkbutton`. +Previously, checkbuttons in different parent widgets could have the same +short name and share the same state if arguments "name" and "variable" are +not specified. Now they are globally unique. + +.. + +.. date: 2022-09-24-18-56-23 +.. gh-issue: 96865 +.. nonce: o9WUkW +.. section: Library + +fix Flag to use boundary CONFORM + +This restores previous Flag behavior of allowing flags with non-sequential +values to be combined; e.g. + +class Skip(Flag): TWO = 2 EIGHT = 8 + +Skip.TWO | Skip.EIGHT -> + +.. + +.. date: 2022-09-22-14-35-02 +.. gh-issue: 97005 +.. nonce: yf21Q7 +.. section: Library + +Update bundled libexpat to 2.4.9 + +.. + +.. date: 2022-09-22-11-50-29 +.. gh-issue: 85760 +.. nonce: DETTPd +.. section: Library + +Fix race condition in :mod:`asyncio` where +:meth:`~asyncio.SubprocessProtocol.process_exited` called before the +:meth:`~asyncio.SubprocessProtocol.pipe_data_received` leading to +inconsistent output. Patch by Kumar Aditya. + +.. + +.. date: 2022-09-18-04-51-30 +.. gh-issue: 96704 +.. nonce: DmamRX +.. section: Library + +Pass the correct ``contextvars.Context`` when a ``asyncio`` exception +handler is called on behalf of a task or callback handle. This adds a new +``Task`` method, ``get_context``, and also a new ``Handle`` method with the +same name. If this method is not found on a task object (perhaps because it +is a third-party library that does not yet provide this method), the context +prevailing at the time the exception handler is called is used. + +.. + +.. date: 2022-09-17-13-15-10 +.. gh-issue: 96819 +.. nonce: 6RfqM7 +.. section: Library + +Fixed check in :mod:`multiprocessing.resource_tracker` that guarantees that +the length of a write to a pipe is not greater than ``PIPE_BUF``. + +.. + +.. date: 2022-09-16-07-53-29 +.. gh-issue: 95865 +.. nonce: oHjX0A +.. section: Library + +Reduce :func:`urllib.parse.quote_from_bytes` memory use on large values. + +Contributed by Dennis Sweeney. + +.. + +.. date: 2022-09-15-00-37-33 +.. gh-issue: 96741 +.. nonce: 4b6czN +.. section: Library + +Corrected type annotation for dataclass attribute +``pstats.FunctionProfile.ncalls`` to be ``str``. + +.. + +.. date: 2022-09-13-15-12-31 +.. gh-issue: 96734 +.. nonce: G08vjz +.. section: Library + +Update :mod:`unicodedata` database to Unicode 15.0.0. + +.. + +.. date: 2022-09-10-16-46-16 +.. gh-issue: 96735 +.. nonce: 0YzJuG +.. section: Library + +Fix undefined behaviour in :func:`struct.unpack`. + +.. + +.. date: 2022-09-08-20-12-48 +.. gh-issue: 46412 +.. nonce: r_cfTh +.. section: Library + +Improve performance of ``bool(db)`` for large ndb/gdb databases. Previously +this would call ``len(db)`` which would iterate over all keys -- the answer +(empty or not) is known after the first key. + +.. + +.. date: 2022-09-07-22-49-37 +.. gh-issue: 96652 +.. nonce: YqOKxI +.. section: Library + +Fix the faulthandler implementation of ``faulthandler.register(signal, +chain=True)`` if the ``sigaction()`` function is not available: don't call +the previous signal handler if it's NULL. Patch by Victor Stinner. + +.. + +.. date: 2022-09-04-12-32-52 +.. gh-issue: 68163 +.. nonce: h6TJCc +.. section: Library + +Correct conversion of :class:`numbers.Rational`'s to :class:`float`. + +.. + +.. date: 2022-09-03-18-39-05 +.. gh-issue: 96538 +.. nonce: W156-D +.. section: Library + +Speed up ``bisect.bisect()`` functions by taking advantage of +type-stability. + +.. + +.. date: 2022-09-01-13-54-38 +.. gh-issue: 96465 +.. nonce: 0IJmrH +.. section: Library + +Fraction hashes are now cached. + +.. + +.. date: 2022-08-31-11-10-21 +.. gh-issue: 96079 +.. nonce: uqrXdJ +.. section: Library + +In :mod:`typing`, fix missing field ``name`` and incorrect ``__module__`` in +_AnnotatedAlias. + +.. + +.. date: 2022-08-30-12-32-00 +.. gh-issue: 96415 +.. nonce: 6W7ORH +.. section: Library + +Remove ``types._cell_factory`` from module namespace. + +.. + +.. date: 2022-08-30-11-46-36 +.. gh-issue: 95987 +.. nonce: CV7_u4 +.. section: Library + +Fix ``repr`` of ``Any`` subclasses. + +.. + +.. date: 2022-08-29-16-54-36 +.. gh-issue: 96388 +.. nonce: dCpJcu +.. section: Library + +Work around missing socket functions in :class:`~socket.socket`'s +``__repr__``. + +.. + +.. date: 2022-08-29-15-28-39 +.. gh-issue: 96385 +.. nonce: uLRTsf +.. section: Library + +Fix ``TypeVarTuple.__typing_prepare_subst__``. ``TypeError`` was not raised +when using more than one ``TypeVarTuple``, like ``[*T, *V]`` in type alias +substitutions. + +.. + +.. date: 2022-08-29-12-49-30 +.. gh-issue: 96142 +.. nonce: PdCMez +.. section: Library + +Add ``match_args``, ``kw_only``, ``slots``, and ``weakref_slot`` to +``_DataclassParams``. + +.. + +.. date: 2022-08-29-12-35-28 +.. gh-issue: 96073 +.. nonce: WaGstf +.. section: Library + +In :mod:`inspect`, fix overeager replacement of "``typing.``" in formatting +annotations. + +.. + +.. date: 2022-08-29-07-04-03 +.. gh-issue: 89258 +.. nonce: ri7ncj +.. section: Library + +Added a :meth:`~logging.Logger.getChildren` method to +:class:`logging.Logger`, to get the immediate child loggers of a logger. + +.. + +.. date: 2022-08-27-23-16-09 +.. gh-issue: 96346 +.. nonce: jJX14I +.. section: Library + +Use double caching for compiled RE patterns. + +.. + +.. date: 2022-08-27-21-26-52 +.. gh-issue: 96349 +.. nonce: XyYLlO +.. section: Library + +Fixed a minor performance regression in :func:`threading.Event.__init__` + +.. + +.. date: 2022-08-27-14-38-49 +.. gh-issue: 90467 +.. nonce: VOOB0p +.. section: Library + +Fix :class:`asyncio.streams.StreamReaderProtocol` to keep a strong reference +to the created task, so that it's not garbage collected + +.. + +.. date: 2022-08-23-13-30-30 +.. gh-issue: 96172 +.. nonce: 7WTHer +.. section: Library + +Fix a bug in ``unicodedata``: ``east_asian_width`` used to return the wrong +value for unassigned characters; and for yet unassigned, but reserved +characters. + +.. + +.. date: 2022-08-22-18-42-17 +.. gh-issue: 96159 +.. nonce: 3bFU39 +.. section: Library + +Fix a performance regression in logging TimedRotatingFileHandler. Only check +for special files when the rollover time has passed. + +.. + +.. date: 2022-08-22-13-54-20 +.. gh-issue: 96175 +.. nonce: bH7zGU +.. section: Library + +Fix unused ``localName`` parameter in the ``Attr`` class in +:mod:`xml.dom.minidom`. + +.. + +.. date: 2022-08-20-12-56-15 +.. gh-issue: 96145 +.. nonce: 8ah3pE +.. section: Library + +Add AttrDict to JSON module for use with object_hook. + +.. + +.. date: 2022-08-20-10-31-01 +.. gh-issue: 96052 +.. nonce: a6FhaD +.. section: Library + +Fix handling compiler warnings (SyntaxWarning and DeprecationWarning) in +:func:`codeop.compile_command` when checking for incomplete input. +Previously it emitted warnings and raised a SyntaxError. Now it always +returns ``None`` for incomplete input without emitting any warnings. + +.. + +.. date: 2022-08-19-18-21-01 +.. gh-issue: 96125 +.. nonce: ODcF1Y +.. section: Library + +Fix incorrect condition that causes ``sys.thread_info.name`` to be wrong on +pthread platforms. + +.. + +.. date: 2022-08-19-10-19-32 +.. gh-issue: 96019 +.. nonce: b7uAVP +.. section: Library + +Fix a bug in the ``makeunicodedata.py`` script leading to about 13 KiB of +space saving in the ``unicodedata`` module, specifically the character +decomposition data. + +.. + +.. date: 2022-08-18-14-53-53 +.. gh-issue: 95463 +.. nonce: GpP05c +.. section: Library + +Remove an incompatible change from :issue:`28080` that caused a regression +that ignored the utf8 in ``ZipInfo.flag_bits``. Patch by Pablo Galindo. + +.. + +.. date: 2022-08-14-18-59-54 +.. gh-issue: 69142 +.. nonce: 6is5Pq +.. section: Library + +Add ``%:z`` strftime format code (generates tzoffset with colons as +separator), see :ref:`strftime-strptime-behavior`. + +.. + +.. date: 2022-08-11-18-52-17 +.. gh-issue: 95899 +.. nonce: _Bi4uG +.. section: Library + +Fix :class:`asyncio.Runner` to call :func:`asyncio.set_event_loop` only once +to avoid calling :meth:`~asyncio.AbstractChildWatcher.attach_loop` multiple +times on child watchers. Patch by Kumar Aditya. + +.. + +.. date: 2022-08-11-18-22-29 +.. gh-issue: 95736 +.. nonce: LzRZXe +.. section: Library + +Fix :class:`unittest.IsolatedAsyncioTestCase` to set event loop before +calling setup functions. Patch by Kumar Aditya. + +.. + +.. date: 2022-08-11-03-16-48 +.. gh-issue: 95865 +.. nonce: 0IOkFP +.. section: Library + +Speed up :func:`urllib.parse.quote_from_bytes` by replacing a list +comprehension with ``map()``. + +.. + +.. date: 2022-08-10-17-34-07 +.. gh-issue: 95861 +.. nonce: qv-T5s +.. section: Library + +Add support for computing Spearman's correlation coefficient to the existing +statistics.correlation() function. + +.. + +.. date: 2022-08-10-11-54-04 +.. gh-issue: 95804 +.. nonce: i5FCFK +.. section: Library + +Fix ``logging`` shutdown handler so it respects +``MemoryHandler.flushOnClose``. + +.. + +.. date: 2022-08-08-01-42-11 +.. gh-issue: 95704 +.. nonce: MOPFfX +.. section: Library + +When a task catches :exc:`asyncio.CancelledError` and raises some other +error, the other error should generally not silently be suppressed. + +.. + +.. date: 2022-08-07-14-56-23 +.. gh-issue: 95149 +.. nonce: U0c6Ib +.. section: Library + +The :class:`HTTPStatus ` enum offers a couple of properties +to indicate the HTTP status category e.g. ``HTTPStatus.OK.is_success``. + +.. + +.. date: 2022-08-03-21-01-17 +.. gh-issue: 95609 +.. nonce: xxyjyX +.. section: Library + +Update bundled pip to 22.2.2. + +.. + +.. date: 2022-08-03-16-52-32 +.. gh-issue: 95289 +.. nonce: FMnHlV +.. section: Library + +Fix :class:`asyncio.TaskGroup` to propagate exception when +:exc:`asyncio.CancelledError` was replaced with another exception by a +context manger. Patch by Kumar Aditya and Guido van Rossum. + +.. + +.. date: 2022-07-29-20-58-37 +.. gh-issue: 94909 +.. nonce: YjMusj +.. section: Library + +Fix incorrect joining of relative Windows paths with drives in +:class:`pathlib.PurePath` initializer. + +.. + +.. date: 2022-07-28-17-14-38 +.. gh-issue: 95385 +.. nonce: 6YlsDI +.. section: Library + +Faster ``json.dumps()`` when sorting of keys is not requested (default). + +.. + +.. date: 2022-07-27-19-47-51 +.. gh-issue: 83901 +.. nonce: OSw06c +.. section: Library + +Improve :meth:`Signature.bind ` error message for +missing keyword-only arguments. + +.. + +.. date: 2022-07-27-19-43-07 +.. gh-issue: 95339 +.. nonce: NuVQ68 +.. section: Library + +Update bundled pip to 22.2.1. + +.. + +.. date: 2022-07-27-11-35-45 +.. gh-issue: 95045 +.. nonce: iysT-Q +.. section: Library + +Fix GC crash when deallocating ``_lsprof.Profiler`` by untracking it before +calling any callbacks. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-25-15-45-06 +.. gh-issue: 95231 +.. nonce: i807-g +.. section: Library + +Fail gracefully if :data:`~errno.EPERM` or :data:`~errno.ENOSYS` is raised +when loading :mod:`crypt` methods. This may happen when trying to load +``MD5`` on a Linux kernel with :abbr:`FIPS (Federal Information Processing +Standard)` enabled. + +.. + +.. date: 2022-07-24-18-00-42 +.. gh-issue: 95097 +.. nonce: lu5qNf +.. section: Library + +Fix :func:`asyncio.run` for :class:`asyncio.Task` implementations without +:meth:`~asyncio.Task.uncancel` method. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-24-12-59-02 +.. gh-issue: 95087 +.. nonce: VvqXkN +.. section: Library + +Fix IndexError in parsing invalid date in the :mod:`email` module. + +.. + +.. date: 2022-07-24-12-00-06 +.. gh-issue: 95199 +.. nonce: -5A64k +.. section: Library + +Upgrade bundled setuptools to 63.2.0. + +.. + +.. date: 2022-07-24-09-15-35 +.. gh-issue: 95194 +.. nonce: ERVmqG +.. section: Library + +Upgrade bundled pip to 22.2. + +.. + +.. date: 2022-07-23-10-50-05 +.. gh-issue: 93899 +.. nonce: VT34A5 +.. section: Library + +Fix check for existence of :data:`os.EFD_CLOEXEC`, :data:`os.EFD_NONBLOCK` +and :data:`os.EFD_SEMAPHORE` flags on older kernel versions where these +flags are not present. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-23-10-42-05 +.. gh-issue: 95166 +.. nonce: xw6p3C +.. section: Library + +Fix :meth:`concurrent.futures.Executor.map` to cancel the currently waiting +on future on an error - e.g. TimeoutError or KeyboardInterrupt. + +.. + +.. date: 2022-07-22-21-18-17 +.. gh-issue: 95132 +.. nonce: n9anlw +.. section: Library + +Fix a :mod:`sqlite3` regression where ``*args`` and ``**kwds`` were +incorrectly relayed from :py:func:`~sqlite3.connect` to the +:class:`~sqlite3.Connection` factory. The regression was introduced in +3.11a1 with PR 24421 (:gh:`85128`). Patch by Erlend E. Aasland.` + +.. + +.. date: 2022-07-22-17-19-57 +.. gh-issue: 93157 +.. nonce: RXByAk +.. section: Library + +Fix :mod:`fileinput` module didn't support ``errors`` option when +``inplace`` is true. + +.. + +.. date: 2022-07-22-09-09-08 +.. gh-issue: 91212 +.. nonce: 53O8Ab +.. section: Library + +Fixed flickering of the turtle window when the tracer is turned off. Patch +by Shin-myoung-serp. + +.. + +.. date: 2022-07-22-00-58-49 +.. gh-issue: 95077 +.. nonce: 4Z6CNC +.. section: Library + +Add deprecation warning for enum ``member.member`` access (e.g. +``Color.RED.BLUE``). + +.. + +.. date: 2022-07-21-22-59-22 +.. gh-issue: 95109 +.. nonce: usxA9r +.. section: Library + +Ensure that timeouts scheduled with :class:`asyncio.Timeout` that have +already expired are delivered promptly. + +.. + +.. date: 2022-07-21-19-55-49 +.. gh-issue: 95105 +.. nonce: BIX2Km +.. section: Library + +:meth:`wsgiref.types.InputStream.__iter__` should return +``Iterator[bytes]``, not ``Iterable[bytes]``. Patch by Shantanu Jain. + +.. + +.. date: 2022-07-20-22-49-48 +.. gh-issue: 95066 +.. nonce: TuCu0E +.. section: Library + +Replaced assert with exception in :func:`ast.parse`, when +``feature_version`` has an invalid major version. Patch by Shantanu Jain. + +.. + +.. date: 2022-07-20-00-23-58 +.. gh-issue: 77617 +.. nonce: XGaqSQ +.. section: Library + +Add :mod:`sqlite3` :ref:`command-line interface `. Patch by +Erlend Aasland. + +.. + +.. date: 2022-07-19-15-37-11 +.. gh-issue: 95005 +.. nonce: iRmZ74 +.. section: Library + +Replace :c:expr:`_PyAccu` with :c:expr:`_PyUnicodeWriter` in JSON encoder +and StringIO and remove the :c:expr:`_PyAccu` implementation. + +.. + +.. date: 2022-07-17-22-31-32 +.. gh-issue: 90085 +.. nonce: c4FWcS +.. section: Library + +Remove ``-c/--clock`` and ``-t/--time`` CLI options of :mod:`timeit`. The +options had been deprecated since Python 3.3 and the functionality was +removed in Python 3.7. Patch by Shantanu Jain. + +.. + +.. date: 2022-07-15-08-13-51 +.. gh-issue: 94857 +.. nonce: 9_KvZJ +.. section: Library + +Fix refleak in ``_io.TextIOWrapper.reconfigure``. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-14-00-43-52 +.. gh-issue: 94821 +.. nonce: e17ghU +.. section: Library + +Fix binding of unix socket to empty address on Linux to use an available +address from the abstract namespace, instead of "\0". + +.. + +.. date: 2022-07-11-10-41-48 +.. gh-issue: 94736 +.. nonce: EbsgeK +.. section: Library + +Fix crash when deallocating an instance of a subclass of +``_multiprocessing.SemLock``. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-09-15-17-02 +.. gh-issue: 81620 +.. nonce: L0O_bV +.. section: Library + +Add random.binomialvariate(). + +.. + +.. date: 2022-07-09-08-55-04 +.. gh-issue: 74116 +.. nonce: 0XwYC1 +.. section: Library + +Allow :meth:`asyncio.StreamWriter.drain` to be awaited concurrently by +multiple tasks. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-08-17-49-12 +.. gh-issue: 87822 +.. nonce: F9dzkf +.. section: Library + +When called with ``capture_locals=True``, the :mod:`traceback` module +functions swallow exceptions raised from calls to ``repr()`` on local +variables of frames. This is in order to prioritize the original exception +over rendering errors. An indication of the failure is printed in place of +the missing value. (Patch by Simon-Martin Schroeder). + +.. + +.. date: 2022-07-08-08-39-35 +.. gh-issue: 88050 +.. nonce: 0aOC_m +.. section: Library + +Fix :mod:`asyncio` subprocess transport to kill process cleanly when process +is blocked and avoid ``RuntimeError`` when loop is closed. Patch by Kumar +Aditya. + +.. + +.. date: 2022-07-07-15-46-55 +.. gh-issue: 94637 +.. nonce: IYEiUM +.. section: Library + +:meth:`SSLContext.set_default_verify_paths` now releases the GIL around +``SSL_CTX_set_default_verify_paths`` call. The function call performs I/O +and CPU intensive work. + +.. + +.. date: 2022-07-06-22-41-51 +.. gh-issue: 94309 +.. nonce: _XswsX +.. section: Library + +Deprecate aliases :class:`typing.Hashable` and :class:`typing.Sized` + +.. + +.. date: 2022-07-06-21-24-03 +.. gh-issue: 92546 +.. nonce: s5Upkh +.. section: Library + +An undocumented ``python -m pprint`` benchmark is moved into ``pprint`` +suite of pyperformance. Patch by Oleg Iarygin. + +.. + +.. date: 2022-07-06-16-01-08 +.. gh-issue: 94607 +.. nonce: Q6RYfz +.. section: Library + +Fix subclassing complex generics with type variables in :mod:`typing`. +Previously an error message saying ``Some type variables ... are not listed +in Generic[...]`` was shown. :mod:`typing` no longer populates +``__parameters__`` with the ``__parameters__`` of a Python class. + +.. + +.. date: 2022-07-06-14-57-33 +.. gh-issue: 94619 +.. nonce: PRqKVX +.. section: Library + +Remove the long-deprecated ``module_repr()`` from :mod:`importlib`. + +.. + +.. date: 2022-07-06-14-45-12 +.. gh-issue: 93910 +.. nonce: iZcp67 +.. section: Library + +The ability to access the other values of an enum on an enum (e.g. +``Color.RED.BLUE``) has been restored in order to fix a performance +regression. + +.. + +.. date: 2022-07-06-06-02-02 +.. gh-issue: 93896 +.. nonce: vIgWGr +.. section: Library + +Fix :func:`asyncio.run` and :class:`unittest.IsolatedAsyncioTestCase` to +always the set event loop as it was done in Python 3.10 and earlier. Patch +by Kumar Aditya. + +.. + +.. date: 2022-07-05-17-22-00 +.. gh-issue: 94343 +.. nonce: kf4H5r +.. section: Library + +Allow setting the attributes of ``reprlib.Repr`` during object +initialization + +.. + +.. date: 2022-07-03-16-41-03 +.. gh-issue: 94382 +.. nonce: zuVZeM +.. section: Library + +Port static types of ``_multiprocessing`` module to heap types. Patch by +Kumar Aditya. + +.. + +.. date: 2022-07-03-16-26-35 +.. gh-issue: 78724 +.. nonce: XNiJzf +.. section: Library + +Fix crash in :class:`struct.Struct` when it was not completely initialized +by initializing it in :meth:`~object.__new__``. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-02-19-46-30 +.. gh-issue: 94510 +.. nonce: xOatDC +.. section: Library + +Re-entrant calls to :func:`sys.setprofile` and :func:`sys.settrace` now +raise :exc:`RuntimeError`. Patch by Pablo Galindo. + +.. + +.. date: 2022-06-29-09-48-37 +.. gh-issue: 92336 +.. nonce: otA6c6 +.. section: Library + +Fix bug where :meth:`linecache.getline` fails on bad files with +:exc:`UnicodeDecodeError` or :exc:`SyntaxError`. It now returns an empty +string as per the documentation. + +.. + +.. date: 2022-06-29-04-42-56 +.. gh-issue: 94398 +.. nonce: YOq_bJ +.. section: Library + +Once a :class:`asyncio.TaskGroup` has started shutting down (i.e., at least +one task has failed and the task group has started cancelling the remaining +tasks), it should not be possible to add new tasks to the task group. + +.. + +.. date: 2022-06-28-14-41-22 +.. gh-issue: 94383 +.. nonce: CXnquo +.. section: Library + +:mod:`xml.etree`: Remove the ``ElementTree.Element.copy()`` method of the +pure Python implementation, deprecated in Python 3.10, use the +:func:`copy.copy` function instead. The C implementation of :mod:`xml.etree` +has no ``copy()`` method, only a ``__copy__()`` method. Patch by Victor +Stinner. + +.. + +.. date: 2022-06-28-14-29-21 +.. gh-issue: 94379 +.. nonce: RrgKfh +.. section: Library + +:mod:`zipimport`: Remove ``find_loader()`` and ``find_module()`` methods, +deprecated in Python 3.10: use the ``find_spec()`` method instead. See +:pep:`451` for the rationale. Patch by Victor Stinner. + +.. + +.. date: 2022-06-28-00-24-48 +.. gh-issue: 94352 +.. nonce: JY1Ayt +.. section: Library + +:func:`shlex.split`: Passing ``None`` for *s* argument now raises an +exception, rather than reading :data:`sys.stdin`. The feature was deprecated +in Python 3.9. Patch by Victor Stinner. + +.. + +.. date: 2022-06-27-10-33-18 +.. gh-issue: 94318 +.. nonce: jR4_QV +.. section: Library + +Strip trailing spaces in :mod:`pydoc` text output. + +.. + +.. date: 2022-06-26-10-59-15 +.. gh-issue: 89988 +.. nonce: K8rnmt +.. section: Library + +Fix memory leak in :class:`pickle.Pickler` when looking up +:attr:`dispatch_table`. Patch by Kumar Aditya. + +.. + +.. date: 2022-06-25-23-44-44 +.. gh-issue: 90016 +.. nonce: EB409s +.. section: Library + +Deprecate :mod:`sqlite3` :ref:`default adapters and converters +`. Patch by Erlend E. Aasland. + +.. + +.. date: 2022-06-25-16-27-02 +.. gh-issue: 94254 +.. nonce: beP16v +.. section: Library + +Fixed types of :mod:`struct` module to be immutable. Patch by Kumar Aditya. + +.. + +.. date: 2022-06-25-13-38-53 +.. gh-issue: 93259 +.. nonce: FAGw-2 +.. section: Library + +Now raise ``ValueError`` when ``None`` or an empty string are passed to +``Distribution.from_name`` (and other callers). + +.. + +.. date: 2022-06-25-09-12-23 +.. gh-issue: 74696 +.. nonce: fxC9ua +.. section: Library + +:func:`shutil.make_archive` now passes the *root_dir* argument to custom +archivers which support it. + +.. + +.. date: 2022-06-24-20-00-57 +.. gh-issue: 94216 +.. nonce: hxnQPu +.. section: Library + +The :mod:`dis` module now has the opcodes for pseudo instructions (those +which are used by the compiler during code generation but then removed or +replaced by real opcodes before the final bytecode is emitted). + +.. + +.. date: 2022-06-24-19-40-40 +.. gh-issue: 93096 +.. nonce: 3RlK2d +.. section: Library + +Removed undocumented ``python -m codecs``. Use ``python -m unittest +test.test_codecs.EncodedFileTest`` instead. + +.. + +.. date: 2022-06-24-19-23-59 +.. gh-issue: 94207 +.. nonce: VhS1eS +.. section: Library + +Made :class:`_struct.Struct` GC-tracked in order to fix a reference leak in +the :mod:`_struct` module. + +.. + +.. date: 2022-06-24-19-16-09 +.. gh-issue: 93096 +.. nonce: r1_oIc +.. section: Library + +Removed undocumented ``-t`` argument of ``python -m base64``. Use ``python +-m unittest test.test_base64.LegacyBase64TestCase.test_encodebytes`` +instead. + +.. + +.. date: 2022-06-24-18-20-42 +.. gh-issue: 94226 +.. nonce: 8ZL4Fm +.. section: Library + +Remove the :func:`locale.format` function, deprecated in Python 3.7: use +:func:`locale.format_string` instead. Patch by Victor Stinner. + +.. + +.. date: 2022-06-24-17-11-33 +.. gh-issue: 94199 +.. nonce: 7releN +.. section: Library + +Remove the :func:`ssl.match_hostname` function. The +:func:`ssl.match_hostname` was deprecated in Python 3.7. OpenSSL performs +hostname matching since Python 3.7, Python no longer uses the +:func:`ssl.match_hostname` function. Patch by Victor Stinner. + +.. + +.. date: 2022-06-24-14-25-26 +.. gh-issue: 94214 +.. nonce: 03pXR5 +.. section: Library + +Document the ``context`` object used in the ``venv.EnvBuilder`` class, and +add the new environment's library path to it. + +.. + +.. date: 2022-06-24-10-39-56 +.. gh-issue: 94199 +.. nonce: MIuckY +.. section: Library + +Remove the :func:`ssl.wrap_socket` function, deprecated in Python 3.7: +instead, create a :class:`ssl.SSLContext` object and call its +:class:`ssl.SSLContext.wrap_socket` method. Any package that still uses +:func:`ssl.wrap_socket` is broken and insecure. The function neither sends a +SNI TLS extension nor validates server hostname. Code is subject to `CWE-295 +`_: Improper Certificate +Validation. Patch by Victor Stinner. + +.. + +.. date: 2022-06-24-10-29-19 +.. gh-issue: 94199 +.. nonce: pfehmz +.. section: Library + +Remove the :func:`ssl.RAND_pseudo_bytes` function, deprecated in Python 3.6: +use :func:`os.urandom` or :func:`ssl.RAND_bytes` instead. Patch by Victor +Stinner. + +.. + +.. date: 2022-06-24-10-18-59 +.. gh-issue: 94199 +.. nonce: kYOo8g +.. section: Library + +:mod:`hashlib`: Remove the pure Python implementation of +:func:`hashlib.pbkdf2_hmac()`, deprecated in Python 3.10. Python 3.10 and +newer requires OpenSSL 1.1.1 (:pep:`644`): this OpenSSL version provides a C +implementation of :func:`~hashlib.pbkdf2_hmac()` which is faster. Patch by +Victor Stinner. + +.. + +.. date: 2022-06-24-09-41-41 +.. gh-issue: 94196 +.. nonce: r2KyfS +.. section: Library + +:mod:`gzip`: Remove the ``filename`` attribute of :class:`gzip.GzipFile`, +deprecated since Python 2.6, use the :attr:`~gzip.GzipFile.name` attribute +instead. In write mode, the ``filename`` attribute added ``'.gz'`` file +extension if it was not present. Patch by Victor Stinner. + +.. + +.. date: 2022-06-24-08-49-47 +.. gh-issue: 94182 +.. nonce: Wknau0 +.. section: Library + +run the :class:`asyncio.PidfdChildWatcher` on the running loop, this allows +event loops to run subprocesses when there is no default event loop running +on the main thread + +.. + +.. date: 2022-06-23-14-35-10 +.. gh-issue: 94169 +.. nonce: jeba90 +.. section: Library + +Remove ``io.OpenWrapper`` and ``_pyio.OpenWrapper``, deprecated in Python +3.10: just use :func:`open` instead. The :func:`open` (:func:`io.open`) +function is a built-in function. Since Python 3.10, :func:`_pyio.open` is +also a static method. Patch by Victor Stinner. + +.. + +.. date: 2022-06-23-13-12-05 +.. gh-issue: 91742 +.. nonce: sNytVX +.. section: Library + +Fix :mod:`pdb` crash after jump caused by a null pointer dereference. Patch +by Kumar Aditya. + +.. + +.. date: 2022-06-22-11-16-11 +.. gh-issue: 94101 +.. nonce: V9vDG8 +.. section: Library + +Manual instantiation of :class:`ssl.SSLSession` objects is no longer allowed +as it lead to misconfigured instances that crashed the interpreter when +attributes where accessed on them. + +.. + +.. date: 2022-06-21-11-40-31 +.. gh-issue: 84753 +.. nonce: FW1pxO +.. section: Library + +:func:`inspect.iscoroutinefunction`, :func:`inspect.isgeneratorfunction`, +and :func:`inspect.isasyncgenfunction` now properly return ``True`` for +duck-typed function-like objects like instances of +:class:`unittest.mock.AsyncMock`. + +This makes :func:`inspect.iscoroutinefunction` consistent with the behavior +of :func:`asyncio.iscoroutinefunction`. Patch by Mehdi ABAAKOUK. + +.. + +.. date: 2022-06-20-23-14-43 +.. gh-issue: 94028 +.. nonce: UofEcX +.. section: Library + +Fix a regression in the :mod:`sqlite3` where statement objects were not +properly cleared and reset after use in cursor iters. The regression was +introduced by PR 27884 in Python 3.11a1. Patch by Erlend E. Aasland. + +.. + +.. date: 2022-06-18-15-06-54 +.. gh-issue: 93973 +.. nonce: 4y6UQT +.. section: Library + +Add keyword argument ``all_errors`` to ``asyncio.create_connection`` so that +multiple connection errors can be raised as an ``ExceptionGroup``. + +.. + +.. date: 2022-06-17-16-00-55 +.. gh-issue: 93963 +.. nonce: 8YYZ-2 +.. section: Library + +Officially deprecate from ``importlib.abc`` classes moved to +``importlib.resources.abc``. + +.. + +.. date: 2022-06-17-12-02-30 +.. gh-issue: 93858 +.. nonce: R49ARc +.. section: Library + +Prevent error when activating venv in nested fish instances. + +.. + +.. date: 2022-06-16-11-16-53 +.. gh-issue: 93820 +.. nonce: 00X0Y5 +.. section: Library + +Pickle :class:`enum.Flag` by name. + +.. + +.. date: 2022-06-16-09-24-50 +.. gh-issue: 93847 +.. nonce: kuv8bN +.. section: Library + +Fix repr of enum of generic aliases. + +.. + +.. date: 2022-06-15-21-35-11 +.. gh-issue: 91404 +.. nonce: 39TZzW +.. section: Library + +Revert the :mod:`re` memory leak when a match is terminated by a signal or +memory allocation failure as the implemented fix caused a major performance +regression. + +.. + +.. date: 2022-06-15-21-28-16 +.. gh-issue: 83499 +.. nonce: u3DQJ- +.. section: Library + +Fix double closing of file description in :mod:`tempfile`. + +.. + +.. date: 2022-06-15-21-20-02 +.. gh-issue: 93820 +.. nonce: FAMLY8 +.. section: Library + +Fixed a regression when :func:`copy.copy`-ing :class:`enum.Flag` with +multiple flag members. + +.. + +.. date: 2022-06-11-13-32-17 +.. gh-issue: 79512 +.. nonce: A1KTDr +.. section: Library + +Fixed names and ``__module__`` value of :mod:`weakref` classes +:class:`~weakref.ReferenceType`, :class:`~weakref.ProxyType`, +:class:`~weakref.CallableProxyType`. It makes them pickleable. + +.. + +.. date: 2022-06-09-17-15-26 +.. gh-issue: 91389 +.. nonce: OE4vS5 +.. section: Library + +Fix an issue where :mod:`dis` utilities could report missing or incorrect +position information in the presence of ``CACHE`` entries. + +.. + +.. date: 2022-06-09-14-44-21 +.. gh-issue: 93626 +.. nonce: sfghs46 +.. section: Library + +Set ``__future__.annotations`` to have a ``None`` mandatoryRelease to +indicate that it is currently 'TBD'. + +.. + +.. date: 2022-06-09-10-12-55 +.. gh-issue: 90473 +.. nonce: 683m_C +.. section: Library + +Emscripten and WASI have no home directory and cannot provide :pep:`370` +user site directory. + +.. + +.. date: 2022-06-08-20-11-02 +.. gh-issue: 90494 +.. nonce: LIZT85 +.. section: Library + +:func:`copy.copy` and :func:`copy.deepcopy` now always raise a TypeError if +``__reduce__()`` returns a tuple with length 6 instead of silently ignore +the 6th item or produce incorrect result. + +.. + +.. date: 2022-06-07-14-53-46 +.. gh-issue: 90549 +.. nonce: T4FMKY +.. section: Library + +Fix a multiprocessing bug where a global named resource (such as a +semaphore) could leak when a child process is spawned (as opposed to +forked). + +.. + +.. date: 2022-06-06-13-19-43 +.. gh-issue: 93521 +.. nonce: _vE8m9 +.. section: Library + +Fixed a case where dataclasses would try to add ``__weakref__`` into the +``__slots__`` for a dataclass that specified ``weakref_slot=True`` when it +was already defined in one of its bases. This resulted in a ``TypeError`` +upon the new class being created. + +.. + +.. date: 2022-06-06-12-58-27 +.. gh-issue: 79579 +.. nonce: e8rB-M +.. section: Library + +:mod:`sqlite3` now correctly detects DML queries with leading comments. +Patch by Erlend E. Aasland. + +.. + +.. date: 2022-06-05-22-22-42 +.. gh-issue: 93421 +.. nonce: 43UO_8 +.. section: Library + +Update :data:`sqlite3.Cursor.rowcount` when a DML statement has run to +completion. This fixes the row count for SQL queries like ``UPDATE ... +RETURNING``. Patch by Erlend E. Aasland. + +.. + +.. date: 2022-06-04-00-11-54 +.. gh-issue: 93475 +.. nonce: vffFw1 +.. section: Library + +Expose ``FICLONE`` and ``FICLONERANGE`` constants in :mod:`fcntl`. Patch by +Illia Volochii. + +.. + +.. date: 2022-06-03-22-13-28 +.. gh-issue: 93370 +.. nonce: tjfu9L +.. section: Library + +Deprecate :data:`sqlite3.version` and :data:`sqlite3.version_info`. + +.. + +.. date: 2022-06-02-08-40-58 +.. gh-issue: 91810 +.. nonce: Gtk44w +.. section: Library + +Suppress writing an XML declaration in open files in ``ElementTree.write()`` +with ``encoding='unicode'`` and ``xml_declaration=None``. + +.. + +.. date: 2022-06-01-11-24-13 +.. gh-issue: 91162 +.. nonce: NxvU_u +.. section: Library + +Support splitting of unpacked arbitrary-length tuple over ``TypeVar`` and +``TypeVarTuple`` parameters. For example: + +* ``A[T, *Ts][*tuple[int, ...]]`` -> ``A[int, *tuple[int, ...]]`` +* ``A[*Ts, T][*tuple[int, ...]]`` -> ``A[*tuple[int, ...], int]`` + +.. + +.. date: 2022-05-31-14-58-40 +.. gh-issue: 93353 +.. nonce: 9Hvm6o +.. section: Library + +Fix the :func:`importlib.resources.as_file` context manager to remove the +temporary file if destroyed late during Python finalization: keep a local +reference to the :func:`os.remove` function. Patch by Victor Stinner. + +.. + +.. date: 2022-05-30-21-42-50 +.. gh-issue: 83658 +.. nonce: 01Ntx0 +.. section: Library + +Make :class:`multiprocessing.Pool` raise an exception if +``maxtasksperchild`` is not ``None`` or a positive int. + +.. + +.. date: 2022-05-28-08-02-55 +.. gh-issue: 93312 +.. nonce: HY0Uzj +.. section: Library + +Add :data:`os.PIDFD_NONBLOCK` flag to open a file descriptor for a process +with :func:`os.pidfd_open` in non-blocking mode. Patch by Kumar Aditya. + +.. + +.. date: 2022-05-27-22-17-11 +.. gh-issue: 88123 +.. nonce: mkYl5q +.. section: Library + +Implement Enum __contains__ that returns True or False to replace the +deprecated behaviour that would sometimes raise a TypeError. + +.. + +.. date: 2022-05-27-13-18-18 +.. gh-issue: 93297 +.. nonce: e2zuHz +.. section: Library + +Make asyncio task groups prevent child tasks from being GCed + +.. + +.. date: 2022-05-27-10-52-06 +.. gh-issue: 85308 +.. nonce: K6r-tJ +.. section: Library + +Changed :class:`argparse.ArgumentParser` to use :term:`filesystem encoding +and error handler` instead of default text encoding to read arguments from +file (e.g. ``fromfile_prefix_chars`` option). This change affects Windows; +argument file should be encoded with UTF-8 instead of ANSI Codepage. + +.. + +.. date: 2022-05-26-23-10-55 +.. gh-issue: 93156 +.. nonce: 4XfDVN +.. section: Library + +Accessing the :attr:`pathlib.PurePath.parents` sequence of an absolute path +using negative index values produced incorrect results. + +.. + +.. date: 2022-05-26-09-24-41 +.. gh-issue: 93162 +.. nonce: W1VuhU +.. section: Library + +Add the ability for :func:`logging.config.dictConfig` to usefully configure +:class:`~logging.handlers.QueueHandler` and +:class:`~logging.handlers.QueueListener` as a pair, and add +:func:`logging.getHandlerByName` and :func:`logging.getHandlerNames` APIs to +allow access to handlers by name. + +.. + +.. date: 2022-05-26-08-41-34 +.. gh-issue: 93243 +.. nonce: uw6x5z +.. section: Library + +The :mod:`smtpd` module was removed per the schedule in :pep:`594`. + +.. + +.. date: 2022-05-25-22-09-38 +.. gh-issue: 92886 +.. nonce: ylwDSc +.. section: Library + +Replace ``assert`` statements with ``raise AssertionError()`` in +:class:`~wsgiref.BaseHandler` so that the tested behaviour is maintained +running with optimizations ``(-O)``. + +.. + +.. date: 2022-05-25-15-57-39 +.. gh-issue: 90155 +.. nonce: YMstB5 +.. section: Library + +Fix broken :class:`asyncio.Semaphore` when acquire is cancelled. + +.. + +.. date: 2022-05-25-02-45-41 +.. gh-issue: 90817 +.. nonce: yxANgU +.. section: Library + +The :func:`locale.resetlocale` function is deprecated and will be removed in +Python 3.13. Use ``locale.setlocale(locale.LC_ALL, "")`` instead. Patch by +Victor Stinner. + +.. + +.. date: 2022-05-25-00-21-28 +.. gh-issue: 91513 +.. nonce: 9VyCT4 +.. section: Library + +Added ``taskName`` attribute to :mod:`logging` module for use with +:mod:`asyncio` tasks. + +.. + +.. date: 2022-05-24-11-19-04 +.. gh-issue: 74696 +.. nonce: -cnf-A +.. section: Library + +:func:`shutil.make_archive` no longer temporarily changes the current +working directory during creation of standard ``.zip`` or tar archives. + +.. + +.. date: 2022-05-24-10-59-02 +.. gh-issue: 92728 +.. nonce: zxTifq +.. section: Library + +The :func:`re.template` function and the corresponding :const:`re.TEMPLATE` +and :const:`re.T` flags are restored after they were removed in 3.11.0b1, +but they are now deprecated, so they might be removed from Python 3.13. + +.. + +.. date: 2022-05-22-23-46-18 +.. gh-issue: 93033 +.. nonce: wZfiL- +.. section: Library + +Search in some strings (platform dependent i.e [U+0xFFFF, U+0x0100] on +Windows or [U+0xFFFFFFFF, U+0x00010000] on Linux 64-bit) are now up to 10 +times faster. + +.. + +.. date: 2022-05-22-16-08-01 +.. gh-issue: 89973 +.. nonce: jc-Q4g +.. section: Library + +Fix :exc:`re.error` raised in :mod:`fnmatch` if the pattern contains a +character range with upper bound lower than lower bound (e.g. ``[c-a]``). +Now such ranges are interpreted as empty ranges. + +.. + +.. date: 2022-05-21-13-16-16 +.. gh-issue: 93044 +.. nonce: eJ_XkZ +.. section: Library + +No longer convert the database argument of :func:`sqlite3.connect` to bytes +before passing it to the factory. + +.. + +.. date: 2022-05-20-15-52-43 +.. gh-issue: 93010 +.. nonce: WF-cAc +.. section: Library + +In a very special case, the email package tried to append the nonexistent +``InvalidHeaderError`` to the defect list. It should have been +``InvalidHeaderDefect``. + +.. + +.. date: 2022-05-19-22-34-42 +.. gh-issue: 92986 +.. nonce: e6uKxj +.. section: Library + +Fix :func:`ast.unparse` when ``ImportFrom.level`` is None + +.. + +.. date: 2022-05-19-17-49-58 +.. gh-issue: 92932 +.. nonce: o2peTh +.. section: Library + +Now :func:`~dis.dis` and :func:`~dis.get_instructions` handle operand values +for instructions prefixed by ``EXTENDED_ARG_QUICK``. Patch by Sam Gross and +Dong-hee Na. + +.. + +.. date: 2022-05-19-13-33-18 +.. gh-issue: 92675 +.. nonce: ZeerMZ +.. section: Library + +Fix :func:`venv.ensure_directories` to accept :class:`pathlib.Path` +arguments in addition to :class:`str` paths. Patch by David Foster. + +.. + +.. date: 2022-05-18-21-04-09 +.. gh-issue: 87901 +.. nonce: lnf041 +.. section: Library + +Removed the ``encoding`` argument from :func:`os.popen` that was added in +3.11b1. + +.. + +.. date: 2022-05-18-17-18-41 +.. gh-issue: 91922 +.. nonce: DwWIsJ +.. section: Library + +Fix function :func:`sqlite.connect` and the :class:`sqlite.Connection` +constructor on non-UTF-8 locales. Also, they now support bytes paths +non-decodable with the current FS encoding. + +.. + +.. date: 2022-05-17-06-27-39 +.. gh-issue: 92869 +.. nonce: t8oBkw +.. section: Library + +Added :class:`~ctypes.c_time_t` to :mod:`ctypes`, which has the same size as +the :c:type:`time_t` type in C. + +.. + +.. date: 2022-05-16-14-35-39 +.. gh-issue: 92839 +.. nonce: owSMyo +.. section: Library + +Fixed crash resulting from calling bisect.insort() or bisect.insort_left() +with the key argument not equal to None. + +.. + +.. date: 2022-05-14-11-41-23 +.. gh-issue: 90473 +.. nonce: kPdOZl +.. section: Library + +:mod:`subprocess` now fails early on Emscripten and WASI platforms to work +around missing :func:`os.pipe` on WASI. + +.. + +.. date: 2022-05-14-09-01-38 +.. gh-issue: 89325 +.. nonce: ys-2BZ +.. section: Library + +Removed many old deprecated :mod:`unittest` features: +:class:`~unittest.TestCase` method aliases, undocumented and broken +:class:`~unittest.TestCase` method ``assertDictContainsSubset``, +undocumented :meth:`TestLoader.loadTestsFromModule +` parameter *use_load_tests*, and +an underscored alias of the :class:`~unittest.TextTestResult` class. + +.. + +.. date: 2022-05-12-15-19-00 +.. gh-issue: 92734 +.. nonce: d0wjDt +.. section: Library + +Allow multi-element reprs emitted by :mod:`reprlib` to be pretty-printed +using configurable indentation. + +.. + +.. date: 2022-05-11-19-33-27 +.. gh-issue: 92671 +.. nonce: KE4v6a +.. section: Library + +Fixed :func:`ast.unparse` for empty tuples in the assignment target context. + +.. + +.. date: 2022-05-11-14-34-09 +.. gh-issue: 91581 +.. nonce: glkou2 +.. section: Library + +:meth:`~datetime.datetime.utcfromtimestamp` no longer attempts to resolve +``fold`` in the pure Python implementation, since the fold is never 1 in +UTC. In addition to being slightly faster in the common case, this also +prevents some errors when the timestamp is close to :attr:`datetime.min +`. Patch by Paul Ganssle. + +.. + +.. date: 2022-05-11-10-06-31 +.. gh-issue: 86388 +.. nonce: 7ivUtT +.. section: Library + +Removed randrange() functionality deprecated since Python 3.10. Formerly, +randrange(10.0) losslessly converted to randrange(10). Now, it raises a +TypeError. Also, the exception raised for non-integral values such as +randrange(10.5) or randrange('10') has been changed from ValueError to +TypeError. + +.. + +.. date: 2022-05-10-16-30-40 +.. gh-issue: 90385 +.. nonce: 1_wBRQ +.. section: Library + +Add :meth:`pathlib.Path.walk` as an alternative to :func:`os.walk`. + +.. + +.. date: 2022-05-10-07-57-27 +.. gh-issue: 92550 +.. nonce: Rk_UzM +.. section: Library + +Fix :meth:`pathlib.Path.rglob` for empty pattern. + +.. + +.. date: 2022-05-09-22-27-11 +.. gh-issue: 92591 +.. nonce: V7RCk2 +.. section: Library + +Allow :mod:`logging` filters to return a :class:`logging.LogRecord` instance +so that filters attached to :class:`logging.Handler`\ s can enrich records +without side effects on other handlers. + +.. + +.. date: 2022-05-09-21-31-41 +.. gh-issue: 92445 +.. nonce: tJosdm +.. section: Library + +Fix a bug in :mod:`argparse` where ``nargs="*"`` would raise an error +instead of returning an empty list when 0 arguments were supplied if choice +was also defined in ``parser.add_argument``. + +.. + +.. date: 2022-05-09-11-55-04 +.. gh-issue: 92547 +.. nonce: CzVZft +.. section: Library + +Remove undocumented :mod:`sqlite3` features deprecated in Python 3.10: + +* ``sqlite3.enable_shared_cache()`` +* ``sqlite3.OptimizedUnicode`` + +Patch by Erlend E. Aasland. + +.. + +.. date: 2022-05-09-09-28-02 +.. gh-issue: 92530 +.. nonce: M4Q1RS +.. section: Library + +Fix an issue that occurred after interrupting +:func:`threading.Condition.notify`. + +.. + +.. date: 2022-05-09-01-27-25 +.. gh-issue: 92531 +.. nonce: vV7S_O +.. section: Library + +The statistics.median_grouped() function now always return a float. +Formerly, it did not convert the input type when for sequences of length +one. + +.. + +.. date: 2022-05-08-19-21-14 +.. gh-issue: 84131 +.. nonce: rG5kI7 +.. section: Library + +The :class:`pathlib.Path` deprecated method ``link_to`` has been removed. +Use 3.10's :meth:`~pathlib.Path.hardlink_to` method instead as its semantics +are consistent with that of :meth:`~pathlib.Path.symlink_to`. + +.. + +.. date: 2022-05-08-18-51-14 +.. gh-issue: 89336 +.. nonce: TL6ip7 +.. section: Library + +Removed :mod:`configparser` module APIs: the ``SafeConfigParser`` class +alias, the ``ParsingError.filename`` property and parameter, and the +``ConfigParser.readfp`` method, all of which were deprecated since Python +3.2. + +.. + +.. date: 2022-05-06-13-00-57 +.. gh-issue: 92391 +.. nonce: s-Lase +.. section: Library + +Add :meth:`~object.__class_getitem__` to :class:`csv.DictReader` and +:class:`csv.DictWriter`, allowing them to be parameterized at runtime. Patch +by Marc Mueller. + +.. + +.. date: 2022-04-26-18-37-24 +.. gh-issue: 91968 +.. nonce: fuuH1_ +.. section: Library + +Add ``SO_RTABLE`` and ``SO_USER_COOKIE`` constants to :mod:`socket`. + +.. + +.. date: 2022-04-25-10-23-01 +.. gh-issue: 91810 +.. nonce: DOHa6B +.. section: Library + +:class:`~xml.etree.ElementTree.ElementTree` method +:meth:`~xml.etree.ElementTree.ElementTree.write` and function +:func:`~xml.etree.ElementTree.tostring` now use the text file's encoding +("UTF-8" if not available) instead of locale encoding in XML declaration +when ``encoding="unicode"`` is specified. + +.. + +.. date: 2022-04-24-22-26-45 +.. gh-issue: 81790 +.. nonce: M5Rvpm +.. section: Library + +:func:`os.path.splitdrive` now understands DOS device paths with UNC links +(beginning ``\\?\UNC\``). Contributed by Barney Gale. + +.. + +.. date: 2022-04-21-19-14-29 +.. gh-issue: 91760 +.. nonce: 54AR-m +.. section: Library + +Apply more strict rules for numerical group references and group names in +regular expressions. Only sequence of ASCII digits is now accepted as a +numerical reference. The group name in bytes patterns and replacement +strings can now only contain ASCII letters and digits and underscore. + +.. + +.. date: 2022-04-15-22-07-36 +.. gh-issue: 90622 +.. nonce: 0C6l8h +.. section: Library + +Worker processes for :class:`concurrent.futures.ProcessPoolExecutor` are no +longer spawned on demand (a feature added in 3.9) when the multiprocessing +context start method is ``"fork"`` as that can lead to deadlocks in the +child processes due to a fork happening while threads are running. + +.. + +.. date: 2022-04-15-17-38-55 +.. gh-issue: 91577 +.. nonce: Ah7cLL +.. section: Library + +Move imports in :class:`~multiprocessing.SharedMemory` methods to module +level so that they can be executed late in python finalization. + +.. + +.. date: 2022-04-15-13-16-25 +.. gh-issue: 91581 +.. nonce: 9OGsrN +.. section: Library + +Remove an unhandled error case in the C implementation of calls to +:meth:`datetime.fromtimestamp ` with no +time zone (i.e. getting a local time from an epoch timestamp). This should +have no user-facing effect other than giving a possibly more accurate error +message when called with timestamps that fall on 10000-01-01 in the local +time. Patch by Paul Ganssle. + +.. + +.. date: 2022-04-15-11-29-38 +.. gh-issue: 91539 +.. nonce: 7WgVuA +.. section: Library + +Improve performance of ``urllib.request.getproxies_environment`` when there +are many environment variables + +.. + +.. date: 2022-04-14-08-37-16 +.. gh-issue: 91524 +.. nonce: g8PiIu +.. section: Library + +Speed up the regular expression substitution (functions :func:`re.sub` and +:func:`re.subn` and corresponding :class:`re.Pattern` methods) for +replacement strings containing group references by 2--3 times. + +.. + +.. date: 2022-04-12-18-05-40 +.. gh-issue: 91447 +.. nonce: N_Fs4H +.. section: Library + +Fix findtext in the xml module to only give an empty string when the text +attribute is set to None. + +.. + +.. date: 2022-04-11-16-55-41 +.. gh-issue: 91456 +.. nonce: DK3KKl +.. section: Library + +Deprecate current default auto() behavior: In 3.13 the default will be for +for auto() to always return the largest member value incremented by 1, and +to raise if incompatible value types are used. + +.. + +.. bpo: 47231 +.. date: 2022-04-08-22-12-11 +.. nonce: lvyglt +.. section: Library + +Fixed an issue with inconsistent trailing slashes in tarfile longname +directories. + +.. + +.. bpo: 39064 +.. date: 2022-04-03-19-40-09 +.. nonce: 76PbIz +.. section: Library + +:class:`zipfile.ZipFile` now raises :exc:`zipfile.BadZipFile` instead of +``ValueError`` when reading a corrupt zip file in which the central +directory offset is negative. + +.. + +.. bpo: 41287 +.. date: 2022-04-03-11-25-02 +.. nonce: 8CTdwf +.. section: Library + +Fix handling of the ``doc`` argument in subclasses of :func:`property`. + +.. + +.. date: 2022-04-01-12-35-44 +.. gh-issue: 90005 +.. nonce: pvaLHQ +.. section: Library + +:mod:`ctypes` dependency ``libffi`` is now detected with ``pkg-config``. + +.. + +.. bpo: 32547 +.. date: 2022-04-01-09-43-54 +.. nonce: NIUiNC +.. section: Library + +The constructors for :class:`~csv.DictWriter` and :class:`~csv.DictReader` +now coerce the ``fieldnames`` argument to a :class:`list` if it is an +iterator. + +.. + +.. bpo: 35540 +.. date: 2022-03-22-18-28-55 +.. nonce: nyijX9 +.. section: Library + +Fix :func:`dataclasses.asdict` crash when :class:`collections.defaultdict` +is present in the attributes. + +.. + +.. bpo: 47063 +.. date: 2022-03-19-04-41-42 +.. nonce: nwRfUo +.. section: Library + +Add an index_pages parameter to support using non-default index page names. + +.. + +.. bpo: 47025 +.. date: 2022-03-16-14-24-14 +.. nonce: qtT3CE +.. section: Library + +Drop support for :class:`bytes` on :attr:`sys.path`. + +.. + +.. bpo: 46951 +.. date: 2022-03-08-04-46-44 +.. nonce: SWAz97 +.. section: Library + +Order the contents of zipapp archives, to make builds more reproducible. + +.. + +.. bpo: 42777 +.. date: 2022-02-21-01-37-00 +.. nonce: nWK3E6 +.. section: Library + +Implement :meth:`pathlib.Path.is_mount` for Windows paths. + +.. + +.. bpo: 46755 +.. date: 2022-02-15-12-40-48 +.. nonce: zePJfx +.. section: Library + +In :class:`QueueHandler`, clear ``stack_info`` from :class:`LogRecord` to +prevent stack trace from being written twice. + +.. + +.. bpo: 45393 +.. date: 2022-02-09-23-44-27 +.. nonce: 9v5Y8U +.. section: Library + +Fix the formatting for ``await x`` and ``not x`` in the operator precedence +table when using the :func:`help` system. + +.. + +.. bpo: 46642 +.. date: 2022-02-05-18-46-54 +.. nonce: YI6nHQ +.. section: Library + +Improve error message when trying to subclass an instance of +:data:`typing.TypeVar`, :data:`typing.ParamSpec`, +:data:`typing.TypeVarTuple`, etc. Based on patch by Gregory Beauregard. + +.. + +.. bpo: 46364 +.. date: 2022-01-14-10-49-20 +.. nonce: SzhlU9 +.. section: Library + +Restrict use of sockets instead of pipes for stdin of subprocesses created +by :mod:`asyncio` to AIX platform only. + +.. + +.. bpo: 28249 +.. date: 2022-01-09-14-23-00 +.. nonce: 4dzB80 +.. section: Library + +Set :attr:`doctest.DocTest.lineno` to ``None`` when object does not have +:attr:`__doc__`. + +.. + +.. bpo: 46197 +.. date: 2022-01-03-15-07-06 +.. nonce: Z0djv6 +.. section: Library + +Fix :mod:`ensurepip` environment isolation for subprocess running ``pip``. + +.. + +.. bpo: 45924 +.. date: 2021-12-27-15-32-15 +.. nonce: 0ZpHX2 +.. section: Library + +Fix :mod:`asyncio` incorrect traceback when future's exception is raised +multiple times. Patch by Kumar Aditya. + +.. + +.. bpo: 45046 +.. date: 2021-08-29-19-59-16 +.. nonce: eGq0NC +.. section: Library + +Add support of context managers in :mod:`unittest`: methods +:meth:`~unittest.TestCase.enterContext` and +:meth:`~unittest.TestCase.enterClassContext` of class +:class:`~unittest.TestCase`, method +:meth:`~unittest.IsolatedAsyncioTestCase.enterAsyncContext` of class +:class:`~unittest.IsolatedAsyncioTestCase` and function +:func:`unittest.enterModuleContext`. + +.. + +.. bpo: 44173 +.. date: 2021-08-27-18-07-35 +.. nonce: oW92Ev +.. section: Library + +Enable fast seeking of uncompressed unencrypted :class:`zipfile.ZipExtFile` + +.. + +.. bpo: 42627 +.. date: 2021-05-22-07-58-59 +.. nonce: EejtD0 +.. section: Library + +Fix incorrect parsing of Windows registry proxy settings + +.. + +.. bpo: 42047 +.. date: 2020-10-15-18-37-12 +.. nonce: XDdoSF +.. section: Library + +Add :func:`threading.get_native_id` support for DragonFly BSD. Patch by +David Carlier. + +.. + +.. bpo: 14243 +.. date: 2020-09-28-04-56-04 +.. nonce: YECnxv +.. section: Library + +The :class:`tempfile.NamedTemporaryFile` function has a new optional +parameter *delete_on_close* + +.. + +.. bpo: 41246 +.. date: 2020-07-08-20-32-13 +.. nonce: 2trYf3 +.. section: Library + +Give the same callback function for when the overlapped operation is done to +the functions ``recv``, ``recv_into``, ``recvfrom``, ``sendto``, ``send`` +and ``sendfile`` inside ``IocpProactor``. + +.. + +.. bpo: 39264 +.. date: 2020-01-09-01-57-12 +.. nonce: GsBL9- +.. section: Library + +Fixed :meth:`collections.UserDict.get` to not call :meth:`__missing__` when +a value is not found. This matches the behavior of :class:`dict`. Patch by +Bar Harel. + +.. + +.. bpo: 38693 +.. date: 2019-11-04-22-21-27 +.. nonce: w_OAov +.. section: Library + +:mod:`importlib` now uses f-strings internally instead of ``str.format``. + +.. + +.. bpo: 38267 +.. date: 2019-09-25-00-37-51 +.. nonce: X9Jb5V +.. section: Library + +Add *timeout* parameter to :meth:`asyncio.loop.shutdown_default_executor`. +The default value is ``None``, which means the executor will be given an +unlimited amount of time. When called from :class:`asyncio.Runner` or +:func:`asyncio.run`, the default timeout is 5 minutes. + +.. + +.. bpo: 34828 +.. date: 2018-09-28-22-18-03 +.. nonce: 5Zyi_S +.. section: Library + +:meth:`sqlite3.Connection.iterdump` now handles databases that use +``AUTOINCREMENT`` in one or more tables. + +.. + +.. bpo: 32990 +.. date: 2018-09-23-07-47-29 +.. nonce: 2FVVTU +.. section: Library + +Support reading wave files with the ``WAVE_FORMAT_EXTENSIBLE`` format in the +:mod:`wave` module. + +.. + +.. bpo: 26253 +.. date: 2017-07-31-13-35-28 +.. nonce: 8v_sCs +.. section: Library + +Allow adjustable compression level for tarfile streams in +:func:`tarfile.open`. + +.. + +.. date: 2022-10-16-17-34-45 +.. gh-issue: 85525 +.. nonce: DvkD0v +.. section: Documentation + +Remove extra row + +.. + +.. date: 2022-10-11-09-40-50 +.. gh-issue: 86404 +.. nonce: dEAb8W +.. section: Documentation + +Deprecated tools ``make suspicious`` and ``rstlint.py`` are now removed. +They have been replaced by `spinx-lint +`_. + +.. + +.. date: 2022-10-02-10-58-52 +.. gh-issue: 97741 +.. nonce: 39l023 +.. section: Documentation + +Fix ``!`` in c domain ref target syntax via a ``conf.py`` patch, so it works +as intended to disable ref target resolution. + +.. + +.. date: 2022-09-01-17-03-04 +.. gh-issue: 96432 +.. nonce: 1EJ1-4 +.. section: Documentation + +Fraction literals now support whitespace around the forward slash, +``Fraction('2 / 3')``. + +.. + +.. date: 2022-08-19-17-07-45 +.. gh-issue: 96098 +.. nonce: nDp43u +.. section: Documentation + +Improve discoverability of the higher level concurrent.futures module by +providing clearer links from the lower level threading and multiprocessing +modules. + +.. + +.. date: 2022-08-13-20-34-51 +.. gh-issue: 95957 +.. nonce: W9ZZAx +.. section: Documentation + +What's New 3.11 now has instructions for how to provide compiler and linker +flags for Tcl/Tk and OpenSSL on RHEL 7 and CentOS 7. + +.. + +.. date: 2022-08-12-01-12-52 +.. gh-issue: 95588 +.. nonce: PA0FI7 +.. section: Documentation + +Clarified the conflicting advice given in the :mod:`ast` documentation about +:func:`ast.literal_eval` being "safe" for use on untrusted input while at +the same time warning that it can crash the process. The latter statement is +true and is deemed unfixable without a large amount of work unsuitable for a +bugfix. So we keep the warning and no longer claim that ``literal_eval`` is +safe. + +.. + +.. date: 2022-08-03-13-35-08 +.. gh-issue: 91207 +.. nonce: eJ4pPf +.. section: Documentation + +Fix stylesheet not working in Windows CHM htmlhelp docs and add warning that +they are deprecated. Contributed by C.A.M. Gerlach. + +.. + +.. date: 2022-07-30-00-23-11 +.. gh-issue: 95454 +.. nonce: we7AFm +.. section: Documentation + +Replaced incorrectly written true/false values in documentiation. Patch by +Robert O'Shea + +.. + +.. date: 2022-07-29-23-02-19 +.. gh-issue: 95451 +.. nonce: -tgB93 +.. section: Documentation + +Update library documentation with :ref:`availability information +` on WebAssembly platforms ``wasm32-emscripten`` and +``wasm32-wasi``. + +.. + +.. date: 2022-07-29-09-04-02 +.. gh-issue: 95415 +.. nonce: LKTyw6 +.. section: Documentation + +Use consistent syntax for platform availability. The directive now supports +a content body and emits a warning when it encounters an unknown platform. + +.. + +.. date: 2022-07-07-08-42-05 +.. gh-issue: 94321 +.. nonce: pmCIPb +.. section: Documentation + +Document the :pep:`246` style protocol type +:class:`sqlite3.PrepareProtocol`. + +.. + +.. date: 2022-06-19-18-18-22 +.. gh-issue: 86128 +.. nonce: 39DDTD +.. section: Documentation + +Document a limitation in ThreadPoolExecutor where its exit handler is +executed before any handlers in atexit. + +.. + +.. date: 2022-06-16-10-10-59 +.. gh-issue: 61162 +.. nonce: 1ypkG8 +.. section: Documentation + +Clarify :mod:`sqlite3` behavior when +:ref:`sqlite3-connection-context-manager`. + +.. + +.. date: 2022-06-15-12-12-49 +.. gh-issue: 87260 +.. nonce: epyI7D +.. section: Documentation + +Align :mod:`sqlite3` argument specs with the actual implementation. + +.. + +.. date: 2022-05-29-21-22-54 +.. gh-issue: 86986 +.. nonce: lFXw8j +.. section: Documentation + +The minimum Sphinx version required to build the documentation is now 3.2. + +.. + +.. date: 2022-05-26-14-51-25 +.. gh-issue: 88831 +.. nonce: 5Cccr5 +.. section: Documentation + +Augmented documentation of asyncio.create_task(). Clarified the need to keep +strong references to tasks and added a code snippet detailing how to to +this. + +.. + +.. date: 2022-05-26-11-33-23 +.. gh-issue: 86438 +.. nonce: kEGGmK +.. section: Documentation + +Clarify that :option:`-W` and :envvar:`PYTHONWARNINGS` are matched literally +and case-insensitively, rather than as regular expressions, in +:mod:`warnings`. + +.. + +.. date: 2022-05-20-18-42-10 +.. gh-issue: 93031 +.. nonce: c2RdJe +.. section: Documentation + +Update tutorial introduction output to use 3.10+ SyntaxError invalid range. + +.. + +.. date: 2022-05-18-23-58-26 +.. gh-issue: 92240 +.. nonce: bHvYiz +.. section: Documentation + +Added release dates for "What's New in Python 3.X" for 3.0, 3.1, 3.2, 3.8 +and 3.10 + +.. + +.. bpo: 47161 +.. date: 2022-03-30-17-56-01 +.. nonce: gesHfS +.. section: Documentation + +Document that :class:`pathlib.PurePath` does not collapse initial double +slashes because they denote UNC paths. + +.. + +.. bpo: 40838 +.. date: 2022-01-13-16-03-15 +.. nonce: k3NVCf +.. section: Documentation + +Document that :func:`inspect.getdoc`, :func:`inspect.getmodule`, and +:func:`inspect.getsourcefile` might return ``None``. + +.. + +.. bpo: 43689 +.. date: 2021-04-01-08-09-34 +.. nonce: mqCfLe +.. section: Documentation + +The ``Differ`` documentation now also mentions other whitespace characters, +which make it harder to understand the diff output. + +.. + +.. bpo: 38056 +.. date: 2019-09-12-08-28-17 +.. nonce: 6ktYkc +.. section: Documentation + +Overhaul the :ref:`error-handlers` documentation in :mod:`codecs`. + +.. + +.. bpo: 13553 +.. date: 2017-12-10-19-13-39 +.. nonce: gQbZs4 +.. section: Documentation + +Document tkinter.Tk args. + +.. + +.. date: 2022-10-20-17-49-50 +.. gh-issue: 95027 +.. nonce: viRpJB +.. section: Tests + +On Windows, when the Python test suite is run with the ``-jN`` option, the +ANSI code page is now used as the encoding for the stdout temporary file, +rather than using UTF-8 which can lead to decoding errors. Patch by Victor +Stinner. + +.. + +.. date: 2022-09-08-18-31-26 +.. gh-issue: 96624 +.. nonce: 5cANM1 +.. section: Tests + +Fixed the failure of repeated runs of ``test.test_unittest`` caused by side +effects in ``test_dotted_but_module_not_loaded``. + +.. + +.. date: 2022-08-22-14-59-42 +.. gh-issue: 95243 +.. nonce: DeD66V +.. section: Tests + +Mitigate the inherent race condition from using find_unused_port() in +testSockName() by trying to find an unused port a few times before failing. +Patch by Ross Burton. + +.. + +.. date: 2022-08-05-09-57-43 +.. gh-issue: 95573 +.. nonce: edMdQB +.. section: Tests + +:source:`Lib/test/test_asyncio/test_ssl.py` exposed a bug in the macOS +kernel where intense concurrent load on non-blocking sockets occasionally +causes :const:`errno.ENOBUFS` ("No buffer space available") to be emitted. +FB11063974 filed with Apple, in the mean time as a workaround buffer size +used in tests on macOS is decreased to avoid intermittent failures. Patch +by Fantix King. + +.. + +.. date: 2022-07-26-15-22-19 +.. gh-issue: 95280 +.. nonce: h8HvbP +.. section: Tests + +Fix problem with ``test_ssl`` ``test_get_ciphers`` on systems that require +perfect forward secrecy (PFS) ciphers. + +.. + +.. date: 2022-07-24-20-19-05 +.. gh-issue: 95212 +.. nonce: fHiU4e +.. section: Tests + +Make multiprocessing test case ``test_shared_memory_recreate`` +parallel-safe. + +.. + +.. date: 2022-07-24-17-24-42 +.. gh-issue: 95218 +.. nonce: zfBLtu +.. section: Tests + +Move tests for importlib.resources into test_importlib.resources. + +.. + +.. date: 2022-07-24-16-28-31 +.. gh-issue: 93963 +.. nonce: UB9azu +.. section: Tests + +Updated tests to use preferred location for ``importlib.resources`` ABCs. + +.. + +.. date: 2022-07-08-12-22-00 +.. gh-issue: 94675 +.. nonce: IiTs5f +.. section: Tests + +Add a regression test for :mod:`re` exponentional slowdown when using +rjsmin. + +.. + +.. date: 2022-07-05-17-53-13 +.. gh-issue: 91330 +.. nonce: Qys5IL +.. section: Tests + +Added more tests for :mod:`dataclasses` to cover behavior with data +descriptor-based fields. + +.. + +.. date: 2022-06-27-21-27-20 +.. gh-issue: 94208 +.. nonce: VR6HX- +.. section: Tests + +``test_ssl`` is now checking for supported TLS version and protocols in more +tests. + +.. + +.. date: 2022-06-27-08-53-40 +.. gh-issue: 94315 +.. nonce: MoZT9t +.. section: Tests + +Tests now check for DAC override capability instead of relying on +:func:`os.geteuid`. + +.. + +.. date: 2022-06-21-17-37-46 +.. gh-issue: 54781 +.. nonce: BjVAVg +.. section: Tests + +Rename test_tk to test_tkinter, and rename test_ttk_guionly to test_ttk. +Patch by Victor Stinner. + +.. + +.. date: 2022-06-20-23-04-52 +.. gh-issue: 93839 +.. nonce: OE3Ybk +.. section: Tests + +Move ``Lib/ctypes/test/`` to ``Lib/test/test_ctypes/``. Patch by Victor +Stinner. + +.. + +.. date: 2022-06-17-15-20-09 +.. gh-issue: 93951 +.. nonce: CW1Vv4 +.. section: Tests + +In test_bdb.StateTestCase.test_skip, avoid including auxiliary importers. + +.. + +.. date: 2022-06-17-13-55-11 +.. gh-issue: 93957 +.. nonce: X4ovYV +.. section: Tests + +Provide nicer error reporting from subprocesses in +test_venv.EnsurePipTest.test_with_pip. + +.. + +.. date: 2022-06-17-13-27-21 +.. gh-issue: 93884 +.. nonce: 5pvPvl +.. section: Tests + +Add test cases for :c:func:`PyNumber_ToBase` that take a large number or a +non-int object as parameter. + +.. + +.. date: 2022-06-16-21-38-18 +.. gh-issue: 93852 +.. nonce: U_Hl6s +.. section: Tests + +test_asyncio, test_logging, test_socket and test_socketserver now create +AF_UNIX domains in the current directory to no longer fail with +``OSError("AF_UNIX path too long")`` if the temporary directory (the +:envvar:`TMPDIR` environment variable) is too long. Patch by Victor Stinner. + +.. + +.. date: 2022-06-16-17-50-58 +.. gh-issue: 93353 +.. nonce: JdpATx +.. section: Tests + +regrtest now checks if a test leaks temporary files or directories if run +with -jN option. Patch by Victor Stinner. + +.. + +.. date: 2022-06-10-21-18-14 +.. gh-issue: 84461 +.. nonce: 9TAb26 +.. section: Tests + +``run_tests.py`` now handles cross compiling env vars correctly and pass +``HOSTRUNNER`` to regression tests. + +.. + +.. date: 2022-06-08-22-32-56 +.. gh-issue: 93616 +.. nonce: e5Kkx2 +.. section: Tests + +``test_modulefinder`` now creates a temporary directory in +``ModuleFinderTest.setUp()`` instead of module scope. + +.. + +.. date: 2022-06-08-14-17-59 +.. gh-issue: 93575 +.. nonce: Xb2LNB +.. section: Tests + +Fix issue with test_unicode test_raiseMemError. The test case now use +``test.support.calcobjsize`` to calculate size of PyUnicode structs. +:func:`sys.getsizeof` may return different size when string has UTF-8 +memory. + +.. + +.. date: 2022-06-05-10-16-45 +.. gh-issue: 90473 +.. nonce: QMu7A8 +.. section: Tests + +WASI does not have a ``chmod(2)`` syscall. :func:`os.chmod` is now a dummy +function on WASI. Skip all tests that depend on working :func:`os.chmod`. + +.. + +.. date: 2022-06-04-12-05-31 +.. gh-issue: 90473 +.. nonce: RSpjF7 +.. section: Tests + +Skip tests on WASI that require symlinks with absolute paths. + +.. + +.. date: 2022-06-03-16-26-04 +.. gh-issue: 57539 +.. nonce: HxWgYO +.. section: Tests + +Increase calendar test coverage for +:meth:`calendar.LocaleTextCalendar.formatweekday`. + +.. + +.. date: 2022-06-03-14-18-37 +.. gh-issue: 90473 +.. nonce: 7iXVRK +.. section: Tests + +Skip symlink tests on WASI. wasmtime uses ``openat2(2)`` with +``RESOLVE_BENEATH`` flag, which prevents symlinks with absolute paths. + +.. + +.. date: 2022-06-03-12-22-44 +.. gh-issue: 89858 +.. nonce: ftBvjE +.. section: Tests + +Fix ``test_embed`` for out-of-tree builds. Patch by Kumar Aditya. + +.. + +.. date: 2022-05-25-23-07-15 +.. gh-issue: 92886 +.. nonce: Aki63_ +.. section: Tests + +Fixing tests that fail when running with optimizations (``-O``) in +``test_imaplib.py``. + +.. + +.. date: 2022-05-25-23-00-35 +.. gh-issue: 92886 +.. nonce: Y-vrWj +.. section: Tests + +Fixing tests that fail when running with optimizations (``-O``) in +``test_zipimport.py`` + +.. + +.. date: 2022-05-25-22-53-30 +.. gh-issue: 92886 +.. nonce: mIfdtz +.. section: Tests + +Fixing tests that fail when running with optimizations (``-O``) in +``test_py_compile.py`` + +.. + +.. date: 2022-05-25-22-43-11 +.. gh-issue: 92886 +.. nonce: 9HQb9e +.. section: Tests + +Fixing tests that fail when running with optimizations (``-O``) in +``test_sys_settrace.py``. + +.. + +.. date: 2022-05-25-22-34-10 +.. gh-issue: 92886 +.. nonce: 1Lkt8S +.. section: Tests + +Fixing tests that fail when running with optimizations (``-O``) in +``_test_multiprocessing.py`` + +.. + +.. date: 2022-05-12-05-51-06 +.. gh-issue: 92670 +.. nonce: 7L43Z_ +.. section: Tests + +Skip ``test_shutil.TestCopy.test_copyfile_nonexistent_dir`` test on AIX as +the test uses a trailing slash to force the OS consider the path as a +directory, but on AIX the trailing slash has no effect and is considered as +a file. + +.. + +.. date: 2022-05-08-15-40-41 +.. gh-issue: 92514 +.. nonce: Xbf5JY +.. section: Tests + +Remove unused ``test.support.BasicTestRunner``. Patch by Jelle Zijlstra. + +.. + +.. bpo: 47016 +.. date: 2022-03-14-23-28-17 +.. nonce: K-t2QX +.. section: Tests + +Create a GitHub Actions workflow for verifying bundled pip and setuptools. +Patch by Illia Volochii and Adam Turner. + +.. + +.. date: 2022-09-20-12-43-44 +.. gh-issue: 96761 +.. nonce: IF29kR +.. section: Build + +Fix the build process of clang compiler for :program:`_bootstrap_python` if +LTO optimization is applied. Patch by Matthias Görgens and Dong-hee Na. + +.. + +.. date: 2022-09-17-11-19-24 +.. gh-issue: 96883 +.. nonce: p_gr62 +.. section: Build + +``wasm32-emscripten`` builds for browsers now include +:mod:`concurrent.futures` for :mod:`asyncio` and :mod:`unittest.mock`. + +.. + +.. date: 2022-09-12-18-34-51 +.. gh-issue: 85936 +.. nonce: tX4VCU +.. section: Build + +CPython now uses the ThinLTO option as the default policy if the Clang +compiler accepts the flag. Patch by Dong-hee Na. + +.. + +.. date: 2022-09-11-14-23-49 +.. gh-issue: 96729 +.. nonce: W4uBWL +.. section: Build + +Ensure that Windows releases built with ``Tools\msi\buildrelease.bat`` are +upgradable to and from official Python releases. + +.. + +.. date: 2022-08-26-11-50-03 +.. gh-issue: 96269 +.. nonce: x_J5h0 +.. section: Build + +Shared module targets now depend on new ``MODULE_DEPS`` variable, which +includes ``EXPORTSYMS``. This fixes a build order issue on unsupported AIX +platform. + +.. + +.. date: 2022-08-26-11-09-11 +.. gh-issue: 84461 +.. nonce: Nsdn_R +.. section: Build + +``wasm32-emscripten`` platform no longer builds :mod:`resource` module, +:func:`~os.getresuid`, :func:`~os.getresgid`, and their setters. The APIs +are stubs and not functional. + +.. + +.. date: 2022-08-15-10-56-07 +.. gh-issue: 95973 +.. nonce: Bsswsc +.. section: Build + +Add a new ``--with-dsymutil`` configure option to to link debug information +in macOS. Patch by Pablo Galindo. + +.. + +.. date: 2022-08-12-13-06-03 +.. gh-issue: 90536 +.. nonce: qMpF6p +.. section: Build + +Use the BOLT post-link optimizer to improve performance, particularly on +medium-to-large applications. + +.. + +.. date: 2022-08-04-15-29-35 +.. gh-issue: 93744 +.. nonce: svRuqm +.. section: Build + +Remove the ``configure --with-cxx-main`` build option: it didn't work for +many years. Remove the ``MAINCC`` variable from ``configure`` and +``Makefile``. Patch by Victor Stinner. + +.. + +.. date: 2022-07-26-18-13-34 +.. gh-issue: 94801 +.. nonce: 9fREfy +.. section: Build + +Fix a regression in ``configure`` script that caused some header checks to +ignore custom ``CPPFLAGS``. The regression was introduced in :gh:`94802`. + +.. + +.. date: 2022-07-25-09-48-43 +.. gh-issue: 95145 +.. nonce: ZNS3dj +.. section: Build + +wasm32-wasi builds no longer depend on WASIX's pthread stubs. Python now has +its own stubbed pthread API. + +.. + +.. date: 2022-07-25-08-59-35 +.. gh-issue: 95174 +.. nonce: g8woUW +.. section: Build + +Python now detects missing ``dup`` function in WASI and works around some +missing :mod:`errno`, :mod:`select`, and :mod:`socket` constants. + +.. + +.. date: 2022-07-23-21-39-09 +.. gh-issue: 95174 +.. nonce: 7cYMZR +.. section: Build + +Python now skips missing :mod:`socket` functions and methods on WASI. WASI +can only create sockets from existing fd / accept and has no netdb. + +.. + +.. date: 2022-07-21-09-17-01 +.. gh-issue: 95085 +.. nonce: E9x2S_ +.. section: Build + +Platforms ``wasm32-unknown-emscripten`` and ``wasm32-unknown-wasi`` have +been promoted to :pep:`11` tier 3 platform support. + +.. + +.. date: 2022-07-14-11-13-26 +.. gh-issue: 94847 +.. nonce: s3Kr5p +.. section: Build + +Fixed ``_decimal`` module build issue on GCC when compiling with LTO and +pydebug. Debug builds no longer force inlining of functions. + +.. + +.. date: 2022-07-14-02-45-44 +.. gh-issue: 94841 +.. nonce: lLRTdf +.. section: Build + +Fix the possible performance regression of :c:func:`PyObject_Free` compiled +with MSVC version 1932. + +.. + +.. date: 2022-07-13-10-13-10 +.. gh-issue: 94801 +.. nonce: 3xUB24 +.. section: Build + +``configure`` now uses custom flags like ``ZLIB_CFLAGS`` and ``ZLIB_LIBS`` +when searching for headers and libraries. + +.. + +.. date: 2022-07-12-13-39-18 +.. gh-issue: 94773 +.. nonce: koHKm5 +.. section: Build + +``deepfreeze.py`` now supports code object with frozensets that contain +incompatible, unsortable types. + +.. + +.. date: 2022-07-08-10-28-23 +.. gh-issue: 94682 +.. nonce: ZtGt_0 +.. section: Build + +Build and test with OpenSSL 1.1.1q + +.. + +.. date: 2022-06-30-17-18-23 +.. gh-issue: 90005 +.. nonce: EIOOla +.. section: Build + +Dependencies of :mod:`readline` and :mod:`curses` module are now detected in +``configure`` script with ``pkg-config``. Only ``ncurses`` / ``ncursesw`` +are detected automatically. The old ``curses`` library is not configured +automatically. Workaround for missing ``termcap`` or ``tinfo`` library has +been removed. + +.. + +.. date: 2022-06-30-17-00-54 +.. gh-issue: 90005 +.. nonce: iiq5qD +.. section: Build + +Fix building ``_ctypes`` extension without ``pkg-config``. + +.. + +.. date: 2022-06-30-09-57-39 +.. gh-issue: 90005 +.. nonce: 9-pQyR +.. section: Build + +``_dbm`` module dependencies are now detected by configure. + +.. + +.. date: 2022-06-29-08-58-31 +.. gh-issue: 94404 +.. nonce: 3MadM6 +.. section: Build + +``makesetup`` now works around an issue with sed on macOS and uses correct +CFLAGS for object files that end up in a shared extension. Module CFLAGS are +used before PY_STDMODULE_CFLAGS to avoid clashes with system headers. + +.. + +.. date: 2022-06-28-09-42-10 +.. gh-issue: 93939 +.. nonce: _VWxKW +.. section: Build + +C extension modules are now built by ``configure`` and ``make`` instead of +``distutils`` and ``setup.py``. + +.. + +.. date: 2022-06-27-11-57-15 +.. gh-issue: 93939 +.. nonce: rv7s8W +.. section: Build + +The ``2to3``, ``idle``, and ``pydoc`` scripts are now generated and +installed by ``Makefile`` instead of ``setup.py``. + +.. + +.. date: 2022-06-25-23-25-47 +.. gh-issue: 94280 +.. nonce: YhEyW_ +.. section: Build + +Updated pegen regeneration script on Windows to find and use Python 3.9 or +higher. Prior to this, pegen regeneration already required 3.9 or higher, +but the script may have used lower versions of Python. + +.. + +.. date: 2022-06-08-14-28-03 +.. gh-issue: 93584 +.. nonce: 0xfHOK +.. section: Build + +Address race condition in ``Makefile`` when installing a PGO build. All +``test`` and ``install`` targets now depend on ``all`` target. + +.. + +.. date: 2022-06-04-12-53-53 +.. gh-issue: 93491 +.. nonce: ehM211 +.. section: Build + +``configure`` now detects and reports :pep:`11` support tiers. + +.. + +.. date: 2022-05-31-18-04-58 +.. gh-issue: 69093 +.. nonce: 6lSa0C +.. section: Build + +Fix ``Modules/Setup.stdlib.in`` rule for ``_sqlite3`` extension. + +.. + +.. date: 2022-05-25-13-56-00 +.. gh-issue: 93207 +.. nonce: B9Rubf +.. section: Build + +``va_start()`` with two parameters, like ``va_start(args, format),`` is now +required to build Python. ``va_start()`` is no longer called with a single +parameter. Patch by Kumar Aditya. + +.. + +.. date: 2022-05-25-05-46-00 +.. gh-issue: 93202 +.. nonce: T37jtj +.. section: Build + +Python now always use the ``%zu`` and ``%zd`` printf formats to format a +``size_t`` or ``Py_ssize_t`` number. Building Python 3.12 requires a C11 +compiler, so these printf formats are now always supported. Patch by Victor +Stinner. + +.. + +.. date: 2022-05-12-10-19-15 +.. gh-issue: 90473 +.. nonce: -syvqK +.. section: Build + +Disable pymalloc and increase stack size on ``wasm32-wasi``. + +.. + +.. bpo: 34449 +.. date: 2018-08-21-11-10-18 +.. nonce: Z3qm3c +.. section: Build + +Drop invalid compiler switch ``-fPIC`` for HP aCC on HP-UX. Patch by Michael +Osipov. + +.. + +.. date: 2022-10-19-20-00-28 +.. gh-issue: 98360 +.. nonce: O2m6YG +.. section: Windows + +Fixes :mod:`multiprocessing` spawning child processes on Windows from a +virtual environment to ensure that child processes that also use +:mod:`multiprocessing` to spawn more children will recognize that they are +in a virtual environment. + +.. + +.. date: 2022-10-19-19-35-37 +.. gh-issue: 98414 +.. nonce: FbHZuS +.. section: Windows + +Fix :file:`py.exe` launcher handling of ``-V:/`` option when +default preferences have been set in environment variables or configuration +files. + +.. + +.. date: 2022-10-02-11-59-23 +.. gh-issue: 97728 +.. nonce: dIdlPE +.. section: Windows + +Fix possible crashes caused by the use of uninitialized variables when pass +invalid arguments in :func:`os.system` on Windows and in Windows-specific +modules (like ``winreg``). + +.. + +.. date: 2022-09-29-23-08-49 +.. gh-issue: 90989 +.. nonce: no89Q2 +.. section: Windows + +Made :ref:`launcher` install per-user by default (unless an all users +install already exists), and clarify some text in the installer. + +.. + +.. date: 2022-09-29-22-27-04 +.. gh-issue: 97649 +.. nonce: bI7OQU +.. section: Windows + +The ``Tools`` directory is no longer installed on Windows + +.. + +.. date: 2022-09-23-15-40-04 +.. gh-issue: 96965 +.. nonce: CsnEGs +.. section: Windows + +Update libffi to 3.4.3 + +.. + +.. date: 2022-09-07-00-11-33 +.. gh-issue: 96577 +.. nonce: kV4K_1 +.. section: Windows + +Fixes a potential buffer overrun in :mod:`msilib`. + +.. + +.. date: 2022-09-05-18-32-47 +.. gh-issue: 96559 +.. nonce: 561sUd +.. section: Windows + +Fixes the Windows launcher not using the compatible interpretation of +default tags found in configuration files when no tag was passed to the +command. + +.. + +.. date: 2022-08-30-12-01-51 +.. gh-issue: 94781 +.. nonce: OxO-Gr +.. section: Windows + +Fix :file:`pcbuild.proj` to clean previous instances of output files in +``Python\deepfreeze`` and ``Python\frozen_modules`` directories on Windows. +Patch by Charlie Zhao. + +.. + +.. date: 2022-08-26-00-11-18 +.. gh-issue: 89545 +.. nonce: zmJMY_ +.. section: Windows + +Updates :mod:`platform` code getting the Windows version to use native +Windows Management Instrumentation (WMI) queries to determine OS version, +type, and architecture. + +.. + +.. date: 2022-08-10-22-46-48 +.. gh-issue: 95733 +.. nonce: 2_urOp +.. section: Windows + +Make certain requirements of the Windows Store package optional to allow +installing on earlier updates of Windows. + +.. + +.. date: 2022-08-04-18-47-54 +.. gh-issue: 95656 +.. nonce: VJ1d13 +.. section: Windows + +Enable the :meth:`~sqlite3.Connection.enable_load_extension` :mod:`sqlite3` +API. + +.. + +.. date: 2022-08-04-01-12-27 +.. gh-issue: 95587 +.. nonce: Fvdv5q +.. section: Windows + +Fixes some issues where the Windows installer would incorrectly detect +certain features of an existing install when upgrading. + +.. + +.. date: 2022-08-03-00-49-46 +.. gh-issue: 94399 +.. nonce: KvxHc0 +.. section: Windows + +Restores the behaviour of :ref:`launcher` for ``/usr/bin/env`` shebang +lines, which will now search :envvar:`PATH` for an executable matching the +given command. If none is found, the usual search process is used. + +.. + +.. date: 2022-07-30-14-18-33 +.. gh-issue: 95445 +.. nonce: mjrTaq +.. section: Windows + +Fixes the unsuccessful removal of the HTML document directory when +uninstalling with Windows msi. + +.. + +.. date: 2022-07-28-20-21-38 +.. gh-issue: 95359 +.. nonce: ywMrgu +.. section: Windows + +Fix :ref:`launcher` handling of :file:`py.ini` commands (it was incorrectly +expecting a ``py_`` prefix on keys) and crashes when reading per-user +configuration file. + +.. + +.. date: 2022-07-26-20-33-12 +.. gh-issue: 95285 +.. nonce: w6fa22 +.. section: Windows + +Fix :ref:`launcher` handling of command lines where it is only passed a +short executable name. + +.. + +.. date: 2022-07-16-16-18-32 +.. gh-issue: 90844 +.. nonce: vwITT3 +.. section: Windows + +Allow virtual environments to correctly launch when they have spaces in the +path. + +.. + +.. date: 2022-07-12-20-45-43 +.. gh-issue: 94772 +.. nonce: uNMmdG +.. section: Windows + +Fix incorrect handling of shebang lines in py.exe launcher + +.. + +.. date: 2022-06-20-22-32-14 +.. gh-issue: 94018 +.. nonce: bycC3A +.. section: Windows + +:mod:`zipfile` will now remove trailing spaces from path components when +extracting files on Windows. + +.. + +.. date: 2022-06-15-01-03-52 +.. gh-issue: 93824 +.. nonce: mR4mxu +.. section: Windows + +Drag and drop of files onto Python files in Windows Explorer has been +enabled for Windows ARM64. + +.. + +.. date: 2022-05-28-19-36-13 +.. gh-issue: 43414 +.. nonce: NGMJ3g +.. section: Windows + +:func:`os.get_terminal_size` now attempts to read the size from any provided +handle, rather than only supporting file descriptors 0, 1 and 2. + +.. + +.. date: 2022-05-19-21-44-25 +.. gh-issue: 92817 +.. nonce: Jrf-Kv +.. section: Windows + +Ensures that :file:`py.exe` will prefer an active virtual environment over +default tags specified with environment variables or through a +:file:`py.ini` file. + +.. + +.. date: 2022-05-19-14-01-30 +.. gh-issue: 92984 +.. nonce: Dsxnlr +.. section: Windows + +Explicitly disable incremental linking for non-Debug builds + +.. + +.. date: 2022-05-16-11-45-06 +.. gh-issue: 92841 +.. nonce: NQx107 +.. section: Windows + +:mod:`asyncio` no longer throws ``RuntimeError: Event loop is closed`` on +interpreter exit after asynchronous socket activity. Patch by Oleg Iarygin. + +.. + +.. bpo: 46907 +.. date: 2022-05-05-06-27-59 +.. nonce: IW-uvT +.. section: Windows + +Update Windows installer to use SQLite 3.38.4. + +.. + +.. date: 2022-04-12-18-35-20 +.. gh-issue: 91061 +.. nonce: x40hSK +.. section: Windows + +Accept os.PathLike for the argument to winsound.PlaySound + +.. + +.. bpo: 42658 +.. date: 2022-03-20-15-47-35 +.. nonce: 16eXtb +.. section: Windows + +Support native Windows case-insensitive path comparisons by using +``LCMapStringEx`` instead of :func:`str.lower` in :func:`ntpath.normcase`. +Add ``LCMapStringEx`` to the :mod:`_winapi` module. + +.. + +.. bpo: 38704 +.. date: 2020-01-10-23-33-03 +.. nonce: 2Idtdn +.. section: Windows + +Prevent installation on unsupported Windows versions. + +.. + +.. date: 2022-10-05-15-26-58 +.. gh-issue: 97897 +.. nonce: Rf-C6u +.. section: macOS + +The macOS 13 SDK includes support for the ``mkfifoat`` and ``mknodat`` +system calls. Using the ``dir_fd`` option with either :func:`os.mkfifo` or +:func:`os.mknod` could result in a segfault if cpython is built with the +macOS 13 SDK but run on an earlier version of macOS. Prevent this by adding +runtime support for detection of these system calls ("weaklinking") as is +done for other newer syscalls on macOS. + +.. + +.. date: 2022-10-15-21-20-40 +.. gh-issue: 97527 +.. nonce: otAHJM +.. section: IDLE + +Fix a bug in the previous bugfix that caused IDLE to not start when run with +3.10.8, 3.12.0a1, and at least Microsoft Python 3.10.2288.0 installed +without the Lib/test package. 3.11.0 was never affected. + +.. + +.. date: 2022-08-04-20-07-51 +.. gh-issue: 65802 +.. nonce: xnThWe +.. section: IDLE + +Document handling of extensions in Save As dialogs. + +.. + +.. date: 2022-08-01-23-31-48 +.. gh-issue: 95191 +.. nonce: U7vryB +.. section: IDLE + +Include prompts when saving Shell (interactive input and output). + +.. + +.. date: 2022-07-31-22-15-14 +.. gh-issue: 95511 +.. nonce: WX6PmB +.. section: IDLE + +Fix the Shell context menu copy-with-prompts bug of copying an extra line +when one selects whole lines. + +.. + +.. date: 2022-07-30-15-10-39 +.. gh-issue: 95471 +.. nonce: z3scVG +.. section: IDLE + +In the Edit menu, move ``Select All`` and add a new separator. + +.. + +.. date: 2022-07-29-11-08-52 +.. gh-issue: 95411 +.. nonce: dazlqH +.. section: IDLE + +Enable using IDLE's module browser with .pyw files. + +.. + +.. date: 2022-07-28-18-56-57 +.. gh-issue: 89610 +.. nonce: hcosiM +.. section: IDLE + +Add .pyi as a recognized extension for IDLE on macOS. This allows opening +stub files by double clicking on them in the Finder. + +.. + +.. date: 2022-10-07-22-06-11 +.. gh-issue: 68686 +.. nonce: 6KNIQ4 +.. section: Tools/Demos + +Remove ptags and eptags scripts. + +.. + +.. date: 2022-09-30-18-35-11 +.. gh-issue: 97681 +.. nonce: -KO1Ba +.. section: Tools/Demos + +Remove the ``Tools/demo/`` directory which contained old demo scripts. A +copy can be found in the `old-demos project +`_. Patch by Victor Stinner. + +.. + +.. date: 2022-09-30-14-30-12 +.. gh-issue: 97669 +.. nonce: gvbgcg +.. section: Tools/Demos + +Remove outdated example scripts of the ``Tools/scripts/`` directory. A copy +can be found in the `old-demos project +`_. Patch by Victor Stinner. + +.. + +.. date: 2022-08-29-17-25-13 +.. gh-issue: 95853 +.. nonce: Ce17cT +.. section: Tools/Demos + +The ``wasm_build.py`` script now pre-builds Emscripten ports, checks for +broken EMSDK versions, and warns about pkg-config env vars. + +.. + +.. date: 2022-08-10-17-08-43 +.. gh-issue: 95853 +.. nonce: HCjC2m +.. section: Tools/Demos + +The new tool ``Tools/wasm/wasm_builder.py`` automates configure, compile, +and test steps for building CPython on WebAssembly platforms. + +.. + +.. date: 2022-08-05-23-25-59 +.. gh-issue: 95731 +.. nonce: N2KohU +.. section: Tools/Demos + +Fix handling of module docstrings in :file:`Tools/i18n/pygettext.py`. + +.. + +.. date: 2022-07-04-10-02-02 +.. gh-issue: 93939 +.. nonce: U6sW6H +.. section: Tools/Demos + +Add script ``Tools/scripts/check_modules.py`` to check and validate builtin +and shared extension modules. The script also handles ``Modules/Setup`` and +will eventually replace ``setup.py``. + +.. + +.. date: 2022-07-04-01-37-42 +.. gh-issue: 94538 +.. nonce: 1rgy1Y +.. section: Tools/Demos + +Fix Argument Clinic output to custom file destinations. Patch by Erlend E. +Aasland. + +.. + +.. date: 2022-06-29-22-47-11 +.. gh-issue: 94430 +.. nonce: hdov8L +.. section: Tools/Demos + +Allow parameters named ``module`` and ``self`` with custom C names in +Argument Clinic. Patch by Erlend E. Aasland + +.. + +.. date: 2022-06-19-14-56-33 +.. gh-issue: 86087 +.. nonce: R8MkRy +.. section: Tools/Demos + +The ``Tools/scripts/parseentities.py`` script used to parse HTML4 entities +has been removed. + +.. + +.. date: 2022-10-18-16-16-27 +.. gh-issue: 98393 +.. nonce: 55u4BF +.. section: C API + +The :c:func:`PyUnicode_FSDecoder` function no longer accepts bytes-like +paths, like :class:`bytearray` and :class:`memoryview` types: only the exact +:class:`bytes` type is accepted for bytes strings. Patch by Victor Stinner. + +.. + +.. date: 2022-10-05-10-43-32 +.. gh-issue: 91051 +.. nonce: ODDRsQ +.. section: C API + +Add :c:func:`PyType_Watch` and related APIs to allow callbacks on +:c:func:`PyType_Modified`. + +.. + +.. date: 2022-10-03-20-33-24 +.. gh-issue: 95756 +.. nonce: SSmXlG +.. section: C API + +Lazily create and cache ``co_`` attributes for better performance for code +getters. + +.. + +.. date: 2022-09-20-01-04-57 +.. gh-issue: 96512 +.. nonce: msZTjF +.. section: C API + +Configuration for the :ref:`integer string conversion length limitation +` now lives in the PyConfig C API struct. + +.. + +.. date: 2022-08-16-16-54-42 +.. gh-issue: 95589 +.. nonce: 6xE1ar +.. section: C API + +Extensions classes that set ``tp_dictoffset`` and ``tp_weaklistoffset`` lose +the support for multiple inheritance, but are now safe. Extension classes +should use :const:`Py_TPFLAGS_MANAGED_DICT` and +:const:`Py_TPFLAGS_MANAGED_WEAKREF` instead. + +.. + +.. date: 2022-08-08-14-36-31 +.. gh-issue: 95781 +.. nonce: W_G8YW +.. section: C API + +An unrecognized format character in :c:func:`PyUnicode_FromFormat` and +:c:func:`PyUnicode_FromFormatV` now sets a :exc:`SystemError`. In previous +versions it caused all the rest of the format string to be copied as-is to +the result string, and any extra arguments discarded. + +.. + +.. date: 2022-08-03-14-39-08 +.. gh-issue: 92678 +.. nonce: ozFTEx +.. section: C API + +Restore the 3.10 behavior for multiple inheritance of C extension classes +that store their dictionary at the end of the struct. + +.. + +.. date: 2022-08-03-13-01-57 +.. gh-issue: 92678 +.. nonce: DLwONN +.. section: C API + +Support C extensions using managed dictionaries by setting the +``Py_TPFLAGS_MANAGED_DICT`` flag. + +.. + +.. date: 2022-08-01-16-21-39 +.. gh-issue: 93274 +.. nonce: QoDHEu +.. section: C API + +API for implementing vectorcall (:c:data:`Py_TPFLAGS_HAVE_VECTORCALL`, +:c:func:`PyVectorcall_NARGS` and :c:func:`PyVectorcall_Call`) was added to +the limited API and stable ABI. + +.. + +.. date: 2022-07-31-21-58-27 +.. gh-issue: 95504 +.. nonce: wy7B1F +.. section: C API + +Fix sign placement when specifying width or precision in +:c:func:`PyUnicode_FromFormat` and :c:func:`PyUnicode_FromFormatV`. Patch by +Philip Georgi. + +.. + +.. date: 2022-07-29-15-24-45 +.. gh-issue: 93012 +.. nonce: -DdGEy +.. section: C API + +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 +makes vectorcall safe to use with mutable types (i.e. heap types without the +:const:`immutable ` flag). Mutable types that do +not override :c:member:`~PyTypeObject.tp_call` now inherit the +:const:`Py_TPFLAGS_HAVE_VECTORCALL` flag. + +.. + +.. date: 2022-07-29-10-41-59 +.. gh-issue: 95388 +.. nonce: aiRSgr +.. section: C API + +Creating :c:data:`immutable types ` with mutable +bases is deprecated and is planned to be disabled in Python 3.14. + +.. + +.. date: 2022-07-25-15-54-27 +.. gh-issue: 92678 +.. nonce: ziZpxz +.. section: C API + +Adds unstable C-API functions ``_PyObject_VisitManagedDict`` and +``_PyObject_ClearManagedDict`` to allow C extensions to allow the VM to +manage their object's dictionaries. + +.. + +.. date: 2022-07-19-22-37-40 +.. gh-issue: 94936 +.. nonce: LGlmKv +.. section: C API + +Added :c:func:`PyCode_GetVarnames`, :c:func:`PyCode_GetCellvars` and +:c:func:`PyCode_GetFreevars` for accessing ``co_varnames``, ``co_cellvars`` +and ``co_freevars`` respectively via the C API. + +.. + +.. date: 2022-07-17-18-21-40 +.. gh-issue: 94930 +.. nonce: gPFGDL +.. section: C API + +Fix ``SystemError`` raised when :c:func:`PyArg_ParseTupleAndKeywords` is +used with ``#`` in ``(...)`` but without ``PY_SSIZE_T_CLEAN`` defined. + +.. + +.. date: 2022-07-12-17-39-32 +.. gh-issue: 94731 +.. nonce: 9CPJNU +.. section: C API + +Python again uses C-style casts for most casting operations when compiled +with C++. This may trigger compiler warnings, if they are enabled with e.g. +``-Wold-style-cast`` or ``-Wzero-as-null-pointer-constant`` options for +``g++``. + +.. + +.. date: 2022-06-17-13-41-38 +.. gh-issue: 93937 +.. nonce: uKVTEh +.. section: C API + +The following frame functions and type are now directly available with +``#include ``, it's no longer needed to add ``#include +``: + +* :c:func:`PyFrame_Check` +* :c:func:`PyFrame_GetBack` +* :c:func:`PyFrame_GetBuiltins` +* :c:func:`PyFrame_GetGenerator` +* :c:func:`PyFrame_GetGlobals` +* :c:func:`PyFrame_GetLasti` +* :c:func:`PyFrame_GetLocals` +* :c:type:`PyFrame_Type` + +Patch by Victor Stinner. + +.. + +.. date: 2022-06-13-21-37-31 +.. gh-issue: 91321 +.. nonce: DgJFvS +.. section: C API + +Fix the compatibility of the Python C API with C++ older than C++11. Patch +by Victor Stinner. + +.. + +.. date: 2022-06-10-23-41-48 +.. gh-issue: 91731 +.. nonce: fhYUQG +.. section: C API + +Avoid defining the ``static_assert`` when compiling with C++ 11, where this +is a keyword and redefining it can lead to undefined behavior. Patch by +Pablo Galindo + +.. + +.. date: 2022-06-10-16-50-27 +.. gh-issue: 89546 +.. nonce: mX1f10 +.. section: C API + +:c:func:`PyType_FromMetaclass` (and other ``PyType_From*`` functions) now +check that offsets and the base class's +:c:member:`~PyTypeObject.tp_basicsize` fit in the new class's +``tp_basicsize``. + +.. + +.. date: 2022-06-06-16-04-14 +.. gh-issue: 93503 +.. nonce: MHJTu8 +.. section: C API + +Add two new public functions to the public C-API, +:c:func:`PyEval_SetProfileAllThreads` and +:c:func:`PyEval_SetTraceAllThreads`, that allow to set tracing and profiling +functions in all running threads in addition to the calling one. Also, two +analogous functions to the :mod:`threading` module +(:func:`threading.setprofile_all_threads` and +:func:`threading.settrace_all_threads`) that allow to do the same from +Python. Patch by Pablo Galindo + +.. + +.. date: 2022-06-04-13-15-41 +.. gh-issue: 93442 +.. nonce: 4M4NDb +.. section: C API + +Add C++ overloads for _Py_CAST_impl() to handle 0/NULL. This will allow C++ +extensions that pass 0 or NULL to macros using _Py_CAST() to continue to +compile. + +.. + +.. date: 2022-06-03-14-54-41 +.. gh-issue: 93466 +.. nonce: DDtH0X +.. section: C API + +Slot IDs in PyType_Spec may not be repeated. The documentation was updated +to mention this. For some cases of repeated slots, PyType_FromSpec and +related functions will now raise an exception. + +.. + +.. date: 2022-05-23-15-22-18 +.. gh-issue: 92898 +.. nonce: Qjc9d3 +.. section: C API + +Fix C++ compiler warnings when casting function arguments to ``PyObject*``. +Patch by Serge Guelton. + +.. + +.. date: 2022-05-23-13-33-18 +.. gh-issue: 93103 +.. nonce: ooD3Eb +.. section: C API + +Deprecate global configuration variables, like +:c:var:`Py_IgnoreEnvironmentFlag`, in the documentation: the +:c:func:`Py_InitializeFromConfig` API should be instead. Patch by Victor +Stinner. + +.. + +.. date: 2022-05-23-12-31-04 +.. gh-issue: 77782 +.. nonce: ugC8dn +.. section: C API + +Deprecate global configuration variable like +:c:var:`Py_IgnoreEnvironmentFlag`: the :c:func:`Py_InitializeFromConfig` API +should be instead. Patch by Victor Stinner. + +.. + +.. date: 2022-05-19-18-05-51 +.. gh-issue: 92913 +.. nonce: Ass1Hv +.. section: C API + +Ensures changes to :c:member:`PyConfig.module_search_paths` are ignored +unless :c:member:`PyConfig.module_search_paths_set` is set + +.. + +.. date: 2022-05-13-18-17-48 +.. gh-issue: 92781 +.. nonce: TVDr3- +.. section: C API + +Avoid mixing declarations and code in the C API to fix the compiler warning: +"ISO C90 forbids mixed declarations and code" +[-Werror=declaration-after-statement]. Patch by Victor Stinner. + +.. + +.. date: 2022-05-11-02-33-10 +.. gh-issue: 92651 +.. nonce: FIXLf0 +.. section: C API + +Remove the ``token.h`` header file. There was never any public tokenizer C +API. The ``token.h`` header file was only designed to be used by Python +internals. Patch by Victor Stinner. + +.. + +.. date: 2022-05-10-12-35-42 +.. gh-issue: 92536 +.. nonce: cAoRCZ +.. section: C API + +Remove legacy Unicode APIs based on ``Py_UNICODE*``. + +.. + +.. date: 2022-05-09-23-16-38 +.. gh-issue: 85858 +.. nonce: VIcNDL +.. section: C API + +Remove the ``PyUnicode_InternImmortal()`` function and the +``SSTATE_INTERNED_IMMORTAL`` macro. Patch by Victor Stinner. + +.. + +.. date: 2022-05-03-19-35-37 +.. gh-issue: 92193 +.. nonce: 61VoFL +.. section: C API + +Add new function :c:func:`PyFunction_SetVectorcall` to the C API which sets +the vectorcall field of a given :c:type:`PyFunctionObject`. + +Warning: extensions using this API must preserve the behavior of the +unaltered function! + +.. + +.. date: 2022-04-13-16-10-55 +.. gh-issue: 59121 +.. nonce: -B7mKp +.. section: C API + +Fixed an assert that prevented ``PyRun_InteractiveOne`` from providing +tracebacks when parsing from the provided FD. + +.. + +.. bpo: 45383 +.. date: 2021-10-05-21-59-43 +.. nonce: TVClgf +.. section: C API + +The :c:func:`PyType_FromSpec` API will now find and use a metaclass based on +the provided bases. An error will be raised if there is a metaclass +conflict. diff --git a/Misc/NEWS.d/3.12.0a2.rst b/Misc/NEWS.d/3.12.0a2.rst new file mode 100644 index 00000000000..318f3f71f11 --- /dev/null +++ b/Misc/NEWS.d/3.12.0a2.rst @@ -0,0 +1,1102 @@ +.. date: 2022-11-04-09-29-36 +.. gh-issue: 98433 +.. nonce: l76c5G +.. release date: 2022-11-14 +.. section: Security + +The IDNA codec decoder used on DNS hostnames by :mod:`socket` or +:mod:`asyncio` related name resolution functions no longer involves a +quadratic algorithm. This prevents a potential CPU denial of service if an +out-of-spec excessive length hostname involving bidirectional characters +were decoded. Some protocols such as :mod:`urllib` http ``3xx`` redirects +potentially allow for an attacker to supply such a name. + +Individual labels within an IDNA encoded DNS name will now raise an error +early during IDNA decoding if they are longer than 1024 unicode characters +given that each decoded DNS label must be 63 or fewer characters and the +entire decoded DNS name is limited to 255. Only an application presenting a +hostname or label consisting primarily of :rfc:`3454` section 3.1 "Nothing" +characters to be removed would run into of this new limit. See also +:rfc:`5894` section 6 and :rfc:`3491`. + +.. + +.. date: 2022-10-26-21-04-23 +.. gh-issue: 98739 +.. nonce: keBWcY +.. section: Security + +Update bundled libexpat to 2.5.0 + +.. + +.. date: 2022-11-11-14-48-17 +.. gh-issue: 81057 +.. nonce: ik4iOv +.. section: Core and Builtins + +The docs clearly say that ``PyImport_Inittab``, +:c:func:`PyImport_AppendInittab`, and :c:func:`PyImport_ExtendInittab` +should not be used after :c:func:`Py_Initialize` has been called. We now +enforce this for the two functions. Additionally, the runtime now uses an +internal copy of ``PyImport_Inittab``, to guard against modification. + +.. + +.. date: 2022-11-09-12-07-24 +.. gh-issue: 99298 +.. nonce: NeArAJ +.. section: Core and Builtins + +Fix an issue that could potentially cause incorrect error handling for some +bytecode instructions. + +.. + +.. date: 2022-11-08-17-47-10 +.. gh-issue: 99254 +.. nonce: RSvyFt +.. section: Core and Builtins + +The compiler now removes all unused constants from code objects (except the +first one, which may be a docstring). + +.. + +.. date: 2022-11-08-16-35-25 +.. gh-issue: 99205 +.. nonce: 2YOoFT +.. section: Core and Builtins + +Fix an issue that prevented :c:type:`PyThreadState` and +:c:type:`PyInterpreterState` memory from being freed properly. + +.. + +.. date: 2022-11-07-14-16-59 +.. gh-issue: 81057 +.. nonce: 3uKlLQ +.. section: Core and Builtins + +The 18 global C variables holding the state of the allocators have been +moved to ``_PyRuntimeState``. This is a strictly internal change with no +change in behavior. + +.. + +.. date: 2022-11-07-10-29-41 +.. gh-issue: 99181 +.. nonce: bfG4bI +.. section: Core and Builtins + +Fix failure in :keyword:`except* ` with unhashable exceptions. + +.. + +.. date: 2022-11-07-08-17-12 +.. gh-issue: 99204 +.. nonce: Mf4hMD +.. section: Core and Builtins + +Fix calculation of :data:`sys._base_executable` when inside a POSIX virtual +environment using copies of the python binary when the base installation +does not provide the executable name used by the venv. Calculation will fall +back to alternative names ("python", "python."). + +.. + +.. date: 2022-11-06-22-59-02 +.. gh-issue: 96055 +.. nonce: TmQuJn +.. section: Core and Builtins + +Update :mod:`faulthandler` to emit an error message with the proper +unexpected signal number. Patch by Dong-hee Na. + +.. + +.. date: 2022-11-06-13-25-01 +.. gh-issue: 99153 +.. nonce: uE3CVL +.. section: Core and Builtins + +Fix location of :exc:`SyntaxError` for a :keyword:`try` block with both +:keyword:`except` and :keyword:`except* `. + +.. + +.. date: 2022-11-06-00-47-11 +.. gh-issue: 98686 +.. nonce: DBDy6U +.. section: Core and Builtins + +Merge the adaptive opcode logic into each instruction's unquickened variant, +and merge the logic in ``EXTENDED_ARG_QUICK`` into :opcode:`EXTENDED_ARG`. +With these changes, the quickening that happens at code object creation is +now only responsible for initializing warmup counters and inserting +superinstructions. + +.. + +.. date: 2022-11-06-00-17-58 +.. gh-issue: 99103 +.. nonce: bFA9BX +.. section: Core and Builtins + +Fix the error reporting positions of specialized traceback anchors when the +source line contains Unicode characters. + +.. + +.. date: 2022-11-05-18-36-27 +.. gh-issue: 99139 +.. nonce: cI9vV1 +.. section: Core and Builtins + +Improve the error suggestion for :exc:`NameError` exceptions for instances. +Now if a :exc:`NameError` is raised in a method and the instance has an +attribute that's exactly equal to the name in the exception, the suggestion +will include ``self.`` instead of the closest match in the method +scope. Patch by Pablo Galindo + +.. + +.. date: 2022-11-03-13-11-17 +.. gh-issue: 98401 +.. nonce: CBS4nv +.. section: Core and Builtins + +Octal escapes with value larger than ``0o377`` (ex: ``"\477"``), deprecated +in Python 3.11, now produce a :exc:`SyntaxWarning`, instead of +:exc:`DeprecationWarning`. In a future Python version they will be +eventually a :exc:`SyntaxError`. Patch by Victor Stinner. + +.. + +.. date: 2022-11-02-17-02-06 +.. gh-issue: 98401 +.. nonce: y-dbVW +.. section: Core and Builtins + +A backslash-character pair that is not a valid escape sequence now generates +a :exc:`SyntaxWarning`, instead of :exc:`DeprecationWarning`. For example, +``re.compile("\d+\.\d+")`` now emits a :exc:`SyntaxWarning` (``"\d"`` is an +invalid escape sequence), use raw strings for regular expression: +``re.compile(r"\d+\.\d+")``. In a future Python version, :exc:`SyntaxError` +will eventually be raised, instead of :exc:`SyntaxWarning`. Patch by Victor +Stinner. + +.. + +.. date: 2022-11-02-14-42-35 +.. gh-issue: 96793 +.. nonce: q0Oi74 +.. section: Core and Builtins + +Handle StopIteration and StopAsyncIteration raised in generator or +coroutines in the bytecode, rather than in wrapping C code. + +.. + +.. date: 2022-10-31-22-55-34 +.. gh-issue: 98931 +.. nonce: AoWZ-4 +.. section: Core and Builtins + +Improve the :exc:`SyntaxError` error message when the user types ``import x +from y`` instead of ``from y import x``. Patch by Pablo Galindo + +.. + +.. date: 2022-10-31-21-01-35 +.. gh-issue: 98852 +.. nonce: MYaRN6 +.. section: Core and Builtins + +Fix subscription of type aliases containing bare generic types or types like +:class:`~typing.TypeVar`: for example ``tuple[A, T][int]`` and +``tuple[TypeVar, T][int]``, where ``A`` is a generic type, and ``T`` is a +type variable. + +.. + +.. date: 2022-10-31-18-03-10 +.. gh-issue: 98925 +.. nonce: zpdjVd +.. section: Core and Builtins + +Lower the recursion depth for marshal on WASI to support (in-development) +wasmtime 2.0. + +.. + +.. date: 2022-10-28-14-52-55 +.. gh-issue: 98783 +.. nonce: iG0kMs +.. section: Core and Builtins + +Fix multiple crashes in debug mode when ``str`` subclasses are used instead +of ``str`` itself. + +.. + +.. date: 2022-10-28-13-59-51 +.. gh-issue: 98811 +.. nonce: XQypJa +.. section: Core and Builtins + +Use complete source locations to simplify detection of ``__future__`` +imports which are not at the beginning of the file. Also corrects the offset +in the exception raised in one case, which was off by one and impeded +highlighting. + +.. + +.. date: 2022-10-28-09-42-51 +.. gh-issue: 96793 +.. nonce: ucBfWO +.. section: Core and Builtins + +Add specialization of :opcode:`FOR_ITER` for generators. Saves multiple +layers of dispatch and checking to get from the :opcode:`FOR_ITER` +instruction in the caller to the :opcode:`RESUME` in the generator. + +.. + +.. date: 2022-10-27-16-42-16 +.. gh-issue: 98762 +.. nonce: Eb2kzg +.. section: Core and Builtins + +Fix source locations of :keyword:`match` sub-patterns. + +.. + +.. date: 2022-10-24-10-30-30 +.. gh-issue: 98586 +.. nonce: Tha5Iy +.. section: Core and Builtins + +Added the methods :c:func:`PyObject_Vectorcall` and +:c:func:`PyObject_VectorcallMethod` to the :ref:`Limited API ` along +with the auxiliary macro constant :const:`PY_VECTORCALL_ARGUMENTS_OFFSET`. + +The availability of these functions enables more efficient :PEP:`590` vector +calls from binary extension modules that avoid argument boxing/unboxing +overheads. + +.. + +.. date: 2022-10-21-11-28-53 +.. gh-issue: 99257 +.. nonce: nmcuf- +.. section: Core and Builtins + +Fix an issue where member descriptors (such as those for +:attr:`~object.__slots__`) could behave incorrectly or crash instead of +raising a :exc:`TypeError` when accessed via an instance of an invalid type. + +.. + +.. date: 2022-10-19-23-54-43 +.. gh-issue: 93143 +.. nonce: 1wCYub +.. section: Core and Builtins + +Rather than changing :attr:`~types.CodeType.co_code`, the interpreter will +now display a :exc:`RuntimeWarning` and assign :const:`None` to any fast +locals that are left unbound after jumps or :keyword:`del` statements +executed while tracing. + +.. + +.. date: 2022-10-19-15-59-08 +.. gh-issue: 96421 +.. nonce: e22y3r +.. section: Core and Builtins + +When calling into Python code from C code, through +:c:func:`PyEval_EvalFrameEx` or a related C-API function, a shim frame in +inserted into the call stack. This occurs in the +``_PyEval_EvalFrameDefault()`` function. The extra frame should be invisible +to all Python and most C extensions, but out-of-process profilers and +debuggers need to be aware of it. These shim frames can be detected by +checking ``frame->owner == FRAME_OWNED_BY_CSTACK``. + +Extensions implementing their own interpreters using PEP 523 need to be +aware of this shim frame and the changes to the semantics of +:opcode:`RETURN_VALUE`, :opcode:`YIELD_VALUE`, and +:opcode:`RETURN_GENERATOR`, which now clear the frame. + +.. + +.. date: 2022-10-19-01-01-08 +.. gh-issue: 98415 +.. nonce: ZS2eWh +.. section: Core and Builtins + +Fix detection of MAC addresses for :mod:`uuid` on certain OSs. Patch by +Chaim Sanders + +.. + +.. date: 2022-10-16-13-26-46 +.. gh-issue: 98686 +.. nonce: D9Gu_Q +.. section: Core and Builtins + +Quicken all code objects, and specialize adaptive bytecode instructions more +aggressively. + +.. + +.. date: 2022-10-15-23-15-14 +.. gh-issue: 92119 +.. nonce: PMSwwG +.. section: Core and Builtins + +Print exception class name instead of its string representation when raising +errors from :mod:`ctypes` calls. + +.. + +.. date: 2022-10-15-22-25-20 +.. gh-issue: 91058 +.. nonce: Uo2kW- +.. section: Core and Builtins + +:exc:`ImportError` raised from failed ``from import `` now +include suggestions for the value of ```` based on the available names +in ````. Patch by Pablo Galindo + +.. + +.. date: 2022-09-13-14-07-06 +.. gh-issue: 96793 +.. nonce: 7DLRSm +.. section: Core and Builtins + +The :opcode:`FOR_ITER` now leaves the iterator on the stack on termination +of the loop. This is to assist specialization of loops for generators. + +.. + +.. date: 2022-09-09-16-32-58 +.. gh-issue: 90716 +.. nonce: z4yuYq +.. section: Core and Builtins + +Add _pylong.py module. It includes asymptotically faster algorithms that +can be used for operations on integers with many digits. It is used by +longobject.c to speed up some operations. + +.. + +.. date: 2022-07-30-14-10-27 +.. gh-issue: 95389 +.. nonce: nSGEkG +.. section: Core and Builtins + +Expose :data:`~socket.ETH_P_ALL` and some of the :ref:`ETHERTYPE_* constants +` in :mod:`socket`. Patch by Noam Cohen. + +.. + +.. date: 2022-06-10-16-37-44 +.. gh-issue: 93696 +.. nonce: 65BI2R +.. section: Core and Builtins + +Allow :mod:`pdb` to locate source for frozen modules in the standard +library. + +.. + +.. date: 2022-11-12-15-45-51 +.. gh-issue: 99418 +.. nonce: FxfAXS +.. section: Library + +Fix bug in :func:`urllib.parse.urlparse` that causes URL schemes that begin +with a digit, a plus sign, or a minus sign to be parsed incorrectly. + +.. + +.. date: 2022-11-11-18-23-41 +.. gh-issue: 94597 +.. nonce: m6vMDK +.. section: Library + +Deprecate :class:`asyncio.AbstractChildWatcher` to be removed in Python +3.14. Patch by Kumar Aditya. + +.. + +.. date: 2022-11-10-11-51-39 +.. gh-issue: 99305 +.. nonce: 6LzQc3 +.. section: Library + +Improve performance of :func:`secrets.token_hex`. + +.. + +.. date: 2022-11-09-20-48-42 +.. gh-issue: 74044 +.. nonce: zBj26K +.. section: Library + +Fixed bug where :func:`inspect.signature` reported incorrect arguments for +decorated methods. + +.. + +.. date: 2022-11-09-12-16-35 +.. gh-issue: 99275 +.. nonce: klOqoL +.. section: Library + +Fix ``SystemError`` in :mod:`ctypes` when exception was not set during +``__initsubclass__``. + +.. + +.. date: 2022-11-09-08-40-52 +.. gh-issue: 99277 +.. nonce: J1P44O +.. section: Library + +Remove older version of ``_SSLProtocolTransport.get_write_buffer_limits`` in +:mod:`!asyncio.sslproto` + +.. + +.. date: 2022-11-08-11-15-37 +.. gh-issue: 99248 +.. nonce: 1vt8xI +.. section: Library + +fix negative numbers failing in verify() + +.. + +.. date: 2022-11-06-12-44-51 +.. gh-issue: 99155 +.. nonce: vLZOzi +.. section: Library + +Fix :class:`statistics.NormalDist` pickle with ``0`` and ``1`` protocols. + +.. + +.. date: 2022-11-05-23-16-15 +.. gh-issue: 93464 +.. nonce: ucd4vP +.. section: Library + +``enum.auto()`` is now correctly activated when combined with other +assignment values. E.g. ``ONE = auto(), 'some text'`` will now evaluate as +``(1, 'some text')``. + +.. + +.. date: 2022-11-05-17-16-40 +.. gh-issue: 99134 +.. nonce: Msgspf +.. section: Library + +Update the bundled copy of pip to version 22.3.1. + +.. + +.. date: 2022-11-03-15-28-07 +.. gh-issue: 92584 +.. nonce: m5ctkm +.. section: Library + +Remove the ``distutils`` package. It was deprecated in Python 3.10 by +:pep:`632` "Deprecate distutils module". For projects still using +``distutils`` and cannot be updated to something else, the ``setuptools`` +project can be installed: it still provides ``distutils``. Patch by Victor +Stinner. + +.. + +.. date: 2022-11-02-18-27-13 +.. gh-issue: 98999 +.. nonce: Ai2KDh +.. section: Library + +Now :mod:`_pyio` is consistent with :mod:`_io` in raising ``ValueError`` +when executing methods over closed buffers. + +.. + +.. date: 2022-11-02-05-54-02 +.. gh-issue: 83004 +.. nonce: 0v8iyw +.. section: Library + +Clean up refleak on failed module initialisation in :mod:`_zoneinfo` + +.. + +.. date: 2022-11-02-05-53-25 +.. gh-issue: 83004 +.. nonce: qc_KHr +.. section: Library + +Clean up refleaks on failed module initialisation in in :mod:`_pickle` + +.. + +.. date: 2022-11-02-05-52-36 +.. gh-issue: 83004 +.. nonce: LBl79O +.. section: Library + +Clean up refleak on failed module initialisation in :mod:`_io`. + +.. + +.. date: 2022-10-31-12-34-03 +.. gh-issue: 98897 +.. nonce: rgNn4x +.. section: Library + +Fix memory leak in :func:`math.dist` when both points don't have the same +dimension. Patch by Kumar Aditya. + +.. + +.. date: 2022-10-30-22-42-48 +.. gh-issue: 98878 +.. nonce: fgrykp +.. section: Library + +Use the frame bound builtins when offering a name suggestion in +:mod:`traceback` to prevent crashing when ``__builtins__`` is not a dict. + +.. + +.. date: 2022-10-30-15-26-33 +.. gh-issue: 98139 +.. nonce: qtm-9T +.. section: Library + +In :mod:`importlib._bootstrap`, enhance namespace package repr to ``. + +.. + +.. date: 2022-10-29-09-42-20 +.. gh-issue: 90352 +.. nonce: t8QEPt +.. section: Library + +Fix ``_SelectorDatagramTransport`` to inherit from +:class:`~asyncio.DatagramTransport` in :mod:`asyncio`. Patch by Kumar +Aditya. + +.. + +.. date: 2022-10-29-03-40-18 +.. gh-issue: 98793 +.. nonce: WSPB4A +.. section: Library + +Fix argument typechecks in :func:`!_overlapped.WSAConnect` and +:func:`!_overlapped.Overlapped.WSASendTo` functions. + +.. + +.. date: 2022-10-28-23-44-17 +.. gh-issue: 98744 +.. nonce: sGHDWm +.. section: Library + +Prevent crashing in :mod:`traceback` when retrieving the byte-offset for +some source files that contain certain unicode characters. + +.. + +.. date: 2022-10-27-12-56-38 +.. gh-issue: 98740 +.. nonce: ZoqqGM +.. section: Library + +Fix internal error in the :mod:`re` module which in very rare circumstances +prevented compilation of a regular expression containing a :ref:`conditional +expression ` without the "else" branch. + +.. + +.. date: 2022-10-26-07-51-55 +.. gh-issue: 98703 +.. nonce: 0hW773 +.. section: Library + +Fix :meth:`asyncio.StreamWriter.drain` to call ``protocol.connection_lost`` +callback only once on Windows. + +.. + +.. date: 2022-10-25-20-17-34 +.. gh-issue: 98624 +.. nonce: YQUPFy +.. section: Library + +Add a mutex to unittest.mock.NonCallableMock to protect concurrent access to +mock attributes. + +.. + +.. date: 2022-10-25-07-00-31 +.. gh-issue: 98658 +.. nonce: nGABW9 +.. section: Library + +The :class:`array.array` class now supports subscripting, making it a +:term:`generic type`. + +.. + +.. date: 2022-10-15-10-43-45 +.. gh-issue: 98284 +.. nonce: SaVHTd +.. section: Library + +Improved :class:`TypeError` message for undefined abstract methods of a +:class:`abc.ABC` instance. The names of the missing methods are surrounded +by single-quotes to highlight them. + +.. + +.. date: 2022-10-10-07-07-31 +.. gh-issue: 96151 +.. nonce: K9fwoq +.. section: Library + +Allow ``BUILTINS`` to be a valid field name for frozen dataclasses. + +.. + +.. date: 2022-10-08-19-39-27 +.. gh-issue: 98086 +.. nonce: y---WC +.. section: Library + +Make sure ``patch.dict()`` can be applied on async functions. + +.. + +.. date: 2022-09-05-17-08-56 +.. gh-issue: 72719 +.. nonce: jUpzF3 +.. section: Library + +Remove modules :mod:`asyncore` and :mod:`asynchat`, which were deprecated by +:pep:`594`. + +.. + +.. date: 2022-08-23-03-13-18 +.. gh-issue: 96192 +.. nonce: TJywOF +.. section: Library + +Fix handling of ``bytes`` :term:`path-like objects ` in +:func:`os.ismount()`. + +.. + +.. date: 2022-06-23-15-36-49 +.. gh-issue: 94172 +.. nonce: DzQk0s +.. section: Library + +:mod:`ftplib`: Remove the ``FTP_TLS.ssl_version`` class attribute: use the +*context* parameter instead. Patch by Victor Stinner + +.. + +.. date: 2022-06-23-15-31-49 +.. gh-issue: 94172 +.. nonce: AXE2IZ +.. section: Library + +Remove the *keyfile* and *certfile* parameters from the +:mod:`ftplib`, :mod:`imaplib`, :mod:`poplib` and :mod:`smtplib` modules, +and the *key_file*, *cert_file* and *check_hostname* parameters from the +:mod:`http.client` module, +all deprecated since Python 3.6. Use the *context* +parameter (*ssl_context* in :mod:`imaplib`) instead. Patch by Victor +Stinner. + +.. + +.. date: 2022-06-14-22-46-05 +.. gh-issue: 83638 +.. nonce: 73xfGK +.. section: Library + +Add the :attr:`~sqlite3.Connection.autocommit` attribute to +:class:`sqlite3.Connection` and the *autocommit* parameter to +:func:`sqlite3.connect` to control :pep:`249`-compliant :ref:`transaction +handling `. Patch by Erlend E. +Aasland. + +.. + +.. date: 2022-05-08-08-47-32 +.. gh-issue: 92452 +.. nonce: 3pNHe6 +.. section: Library + +Fixed a race condition that could cause :func:`sysconfig.get_config_var` to +incorrectly return :const:`None` in multi-threaded programs. + +.. + +.. date: 2022-05-03-11-32-29 +.. gh-issue: 91803 +.. nonce: pI4Juv +.. section: Library + +Fix an error when using a method of objects mocked with +:func:`unittest.mock.create_autospec` after it was sealed with +:func:`unittest.mock.seal` function. + +.. + +.. bpo: 38523 +.. date: 2020-10-23-22-20-52 +.. nonce: CrkxLh +.. section: Library + +:func:`shutil.copytree` now applies the *ignore_dangling_symlinks* argument +recursively. + +.. + +.. bpo: 40358 +.. date: 2020-04-30-02-15-08 +.. nonce: A4ygqe +.. section: Library + +Add walk_up argument in :meth:`pathlib.PurePath.relative_to`. + +.. + +.. bpo: 36267 +.. date: 2019-09-03-15-45-19 +.. nonce: z42Ex7 +.. section: Library + +Fix IndexError in :class:`argparse.ArgumentParser` when a ``store_true`` +action is given an explicit argument. + +.. + +.. date: 2022-10-29-02-33-46 +.. gh-issue: 98832 +.. nonce: DudEIH +.. section: Documentation + +Changes wording of docstring for :func:`pathlib.Path.iterdir`. + +.. + +.. date: 2022-10-06-13-00-28 +.. gh-issue: 97966 +.. nonce: fz7kFg +.. section: Documentation + +Update uname docs to clarify the special nature of the platform attribute +and to indicate when it became late-bound. + +.. + +.. date: 2022-10-31-14-47-49 +.. gh-issue: 98903 +.. nonce: 7KinCV +.. section: Tests + +The Python test suite now fails wit exit code 4 if no tests ran. It should +help detecting typos in test names and test methods. + +.. + +.. date: 2022-10-26-15-19-20 +.. gh-issue: 98713 +.. nonce: Lnu32R +.. section: Tests + +Fix a bug in the :mod:`typing` tests where a test relying on +CPython-specific implementation details was not decorated with +``@cpython_only`` and was not skipped on other implementations. + +.. + +.. date: 2022-10-15-07-46-48 +.. gh-issue: 87390 +.. nonce: asR-Zo +.. section: Tests + +Add tests for star-unpacking with PEP 646, and some other miscellaneous PEP +646 tests. + +.. + +.. date: 2022-10-12-14-57-06 +.. gh-issue: 96853 +.. nonce: ANe-bw +.. section: Tests + +Added explicit coverage of ``Py_Initialize`` (and hence ``Py_InitializeEx``) +back to the embedding tests (all other embedding tests migrated to +``Py_InitializeFromConfig`` in Python 3.11) + +.. + +.. bpo: 34272 +.. date: 2018-07-29-15-59-51 +.. nonce: lVX2uR +.. section: Tests + +Some C API tests were moved into the new Lib/test/test_capi/ directory. + +.. + +.. date: 2022-11-04-02-58-10 +.. gh-issue: 99086 +.. nonce: DV_4Br +.. section: Build + +Fix ``-Wimplicit-int`` compiler warning in :program:`configure` check for +``PTHREAD_SCOPE_SYSTEM``. + +.. + +.. date: 2022-11-02-19-25-07 +.. gh-issue: 99016 +.. nonce: R05NkD +.. section: Build + +Fix build with ``PYTHON_FOR_REGEN=python3.8``. + +.. + +.. date: 2022-11-02-18-45-35 +.. gh-issue: 97731 +.. nonce: zKpTlj +.. section: Build + +Specify the full path to the source location for ``make docclean`` (needed +for cross-builds). + +.. + +.. date: 2022-11-02-10-56-40 +.. gh-issue: 98949 +.. nonce: 3SRD8C +.. section: Build + +Drop unused build dependency on ``readelf``. + +.. + +.. date: 2022-11-01-21-45-58 +.. gh-issue: 98989 +.. nonce: tMxbdB +.. section: Build + +Use ``python3.11``, if available, for regeneration and freezing. + +.. + +.. date: 2022-10-28-22-24-26 +.. gh-issue: 98831 +.. nonce: IXRCRX +.. section: Build + +Add new tooling, in ``Tools/cases_generator``, to generate the interpreter +switch statement from a list of opcode definitions. This only affects +adding, modifying or removing instruction definitions. The instruction +definitions now live in ``Python/bytecodes.c``, in the form of a `custom DSL +(under development) +`__. +The tooling reads this file and writes ``Python/generated_cases.c.h``, which +is then included by ``Python/ceval.c`` to provide most of the cases of the +main interpreter switch. + +.. + +.. date: 2022-10-28-18-53-40 +.. gh-issue: 98817 +.. nonce: oPqrtt +.. section: Build + +Remove PCbuild/lib.pyproj: it's not used for anything, is only a minor +convenience for Visual Studio users (who probably mostly don't even know +about it), and it takes a lot of maintenance effort to keep updated. + +.. + +.. date: 2022-10-27-19-47-31 +.. gh-issue: 98776 +.. nonce: lt_UOG +.. section: Build + +Fix ``make regen-test-levenshtein`` for out-of-tree builds. + +.. + +.. date: 2022-10-26-12-37-52 +.. gh-issue: 98707 +.. nonce: eVXGEx +.. section: Build + +Don't use vendored ``libmpdec`` headers if :option:`--with-system-libmpdec` +is passed to :program:`configure`. Don't use vendored ``libexpat`` headers +if :option:`--with-system-expat` is passed to :program:`!configure`. + +.. + +.. date: 2022-11-01-11-07-33 +.. gh-issue: 98689 +.. nonce: 0f6e_N +.. section: Windows + +Update Windows builds to zlib v1.2.13. v1.2.12 has CVE-2022-37434, but the +vulnerable ``inflateGetHeader`` API is not used by Python. + +.. + +.. date: 2022-11-01-00-37-13 +.. gh-issue: 98790 +.. nonce: fpaPAx +.. section: Windows + +Assumes that a missing ``DLLs`` directory means that standard extension +modules are in the executable's directory. + +.. + +.. date: 2022-10-27-20-30-16 +.. gh-issue: 98745 +.. nonce: v06p4r +.. section: Windows + +Update :file:`py.exe` launcher to install 3.11 by default and 3.12 on +request. + +.. + +.. date: 2022-10-26-17-43-09 +.. gh-issue: 98692 +.. nonce: bOopfZ +.. section: Windows + +Fix the :ref:`launcher` ignoring unrecognized shebang lines instead of +treating them as local paths + +.. + +.. date: 2022-10-25-10-34-17 +.. gh-issue: 94328 +.. nonce: 19NhdU +.. section: Windows + +Update Windows installer to use SQLite 3.39.4. + +.. + +.. date: 2022-10-25-10-32-23 +.. gh-issue: 94328 +.. nonce: W3YNC_ +.. section: macOS + +Update macOS installer to SQLite 3.39.4. + +.. + +.. date: 2022-11-04-16-13-35 +.. gh-issue: 98724 +.. nonce: p0urWO +.. section: C API + +The :c:macro:`Py_CLEAR`, :c:macro:`Py_SETREF` and :c:macro:`Py_XSETREF` +macros now only evaluate their argument once. If the argument has side +effects, these side effects are no longer duplicated. Patch by Victor +Stinner. + +.. + +.. date: 2022-11-03-17-46-41 +.. gh-issue: 98978 +.. nonce: KJjBvv +.. section: C API + +Fix use-after-free in ``Py_SetPythonHome(NULL)``, +``Py_SetProgramName(NULL)`` and ``_Py_SetProgramFullPath(NULL)`` function +calls. Issue reported by Benedikt Reinartz. Patch by Victor Stinner. + +.. + +.. date: 2022-10-25-17-50-43 +.. gh-issue: 98410 +.. nonce: NSXYfm +.. section: C API + +Add ``getbufferproc`` and ``releasebufferproc`` to the stable API. + +.. + +.. date: 2022-10-24-12-09-17 +.. gh-issue: 98610 +.. nonce: PLX2Np +.. section: C API + +Some configurable capabilities of sub-interpreters have changed. They always +allow subprocesses (:mod:`subprocess`) now, whereas before subprocesses +could be optionally disaallowed for a sub-interpreter. Instead +:func:`os.exec` can now be disallowed. Disallowing daemon threads is now +supported. Disallowing all threads is still allowed, but is never done by +default. Note that the optional restrictions are only available through +``_Py_NewInterpreterFromConfig()``, which isn't a public API. They do not +affect the main interpreter, nor :c:func:`Py_NewInterpreter`. + +.. + +.. date: 2022-10-24-11-26-55 +.. gh-issue: 98608 +.. nonce: _Q2lNV +.. section: C API + +A ``_PyInterpreterConfig`` has been added and ``_Py_NewInterpreter()`` has +been renamed to ``_Py_NewInterpreterFromConfig()``. The +"isolated_subinterpreters" argument is now a granular config that captures +the previous behavior. Note that this is all "private" API. + +.. + +.. date: 2022-10-16-15-00-25 +.. gh-issue: 96853 +.. nonce: V0wiXP +.. section: C API + +``Py_InitializeEx`` now correctly calls ``PyConfig_Clear`` after +initializing the interpreter (the omission didn't cause a memory leak only +because none of the dynamically allocated config fields are populated by the +wrapper function) + +.. + +.. date: 2022-08-05-15-26-12 +.. gh-issue: 91248 +.. nonce: ujirJJ +.. section: C API + +Add :c:func:`PyFrame_GetVar` and :c:func:`PyFrame_GetVarString` functions to +get a frame variable by its name. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/3.12.0a3.rst b/Misc/NEWS.d/3.12.0a3.rst new file mode 100644 index 00000000000..3d1e43350d1 --- /dev/null +++ b/Misc/NEWS.d/3.12.0a3.rst @@ -0,0 +1,836 @@ +.. date: 2022-12-05-01-39-10 +.. gh-issue: 100001 +.. nonce: uD05Fc +.. release date: 2022-12-06 +.. section: Security + +``python -m http.server`` no longer allows terminal control characters sent +within a garbage request to be printed to the stderr server log. + +This is done by changing the :mod:`http.server` +:class:`BaseHTTPRequestHandler` ``.log_message`` method to replace control +characters with a ``\xHH`` hex escape before printing. + +.. + +.. date: 2022-11-11-12-50-28 +.. gh-issue: 87604 +.. nonce: OtwH5L +.. section: Security + +Avoid publishing list of active per-interpreter audit hooks via the +:mod:`gc` module + +.. + +.. date: 2022-11-30-11-09-40 +.. gh-issue: 99891 +.. nonce: 9VomwB +.. section: Core and Builtins + +Fix a bug in the tokenizer that could cause infinite recursion when showing +syntax warnings that happen in the first line of the source. Patch by Pablo +Galindo + +.. + +.. date: 2022-11-27-13-50-13 +.. gh-issue: 91054 +.. nonce: oox_kW +.. section: Core and Builtins + +Add :c:func:`PyCode_AddWatcher` and :c:func:`PyCode_ClearWatcher` APIs to +register callbacks to receive notification on creation and destruction of +code objects. + +.. + +.. date: 2022-11-26-04-00-41 +.. gh-issue: 99729 +.. nonce: A3ovwQ +.. section: Core and Builtins + +Fix an issue that could cause frames to be visible to Python code as they +are being torn down, possibly leading to memory corruption or hard crashes +of the interpreter. + +.. + +.. date: 2022-11-23-18-16-18 +.. gh-issue: 99708 +.. nonce: 7MuaiR +.. section: Core and Builtins + +Fix bug where compiler crashes on an if expression with an empty body block. + +.. + +.. date: 2022-11-21-11-27-14 +.. gh-issue: 99578 +.. nonce: DcKoBJ +.. section: Core and Builtins + +Fix a reference bug in :func:`_imp.create_builtin()` after the creation of +the first sub-interpreter for modules ``builtins`` and ``sys``. Patch by +Victor Stinner. + +.. + +.. date: 2022-11-19-22-27-52 +.. gh-issue: 99581 +.. nonce: yKYPbf +.. section: Core and Builtins + +Fixed a bug that was causing a buffer overflow if the tokenizer copies a +line missing the newline caracter from a file that is as long as the +available tokenizer buffer. Patch by Pablo galindo + +.. + +.. date: 2022-11-18-11-24-25 +.. gh-issue: 99553 +.. nonce: F64h-n +.. section: Core and Builtins + +Fix bug where an :exc:`ExceptionGroup` subclass can wrap a +:exc:`BaseException`. + +.. + +.. date: 2022-11-16-21-35-30 +.. gh-issue: 99547 +.. nonce: p_c_bp +.. section: Core and Builtins + +Add a function to os.path to check if a path is a junction: isjunction. Add +similar functionality to pathlib.Path as is_junction. + +.. + +.. date: 2022-11-12-01-39-57 +.. gh-issue: 99370 +.. nonce: _cu32j +.. section: Core and Builtins + +Fix zip path for venv created from a non-installed python on POSIX +platforms. + +.. + +.. date: 2022-11-11-14-04-01 +.. gh-issue: 99377 +.. nonce: -CJvWn +.. section: Core and Builtins + +Add audit events for thread creation and clear operations. + +.. + +.. date: 2022-11-10-17-09-16 +.. gh-issue: 98686 +.. nonce: bmAKwr +.. section: Core and Builtins + +Remove the ``BINARY_OP_GENERIC`` and ``COMPARE_OP_GENERIC`` +"specializations". + +.. + +.. date: 2022-11-10-16-53-40 +.. gh-issue: 99298 +.. nonce: HqRJES +.. section: Core and Builtins + +Remove the remaining error paths for attribute specializations, and refuse +to specialize attribute accesses on types that haven't had +:c:func:`PyType_Ready` called on them yet. + +.. + +.. date: 2022-11-05-22-26-35 +.. gh-issue: 99127 +.. nonce: Btk7ih +.. section: Core and Builtins + +Allow some features of :mod:`syslog` to the main interpreter only. Patch by +Dong-hee Na. + +.. + +.. date: 2022-10-05-11-44-52 +.. gh-issue: 91053 +.. nonce: f5Bo3p +.. section: Core and Builtins + +Optimizing interpreters and JIT compilers may need to invalidate internal +metadata when functions are modified. This change adds the ability to +provide a callback that will be invoked each time a function is created, +modified, or destroyed. + +.. + +.. date: 2022-09-17-17-08-01 +.. gh-issue: 90994 +.. nonce: f0H2Yd +.. section: Core and Builtins + +Improve error messages when there's a syntax error with call arguments. The +following three cases are covered: - No value is assigned to a named +argument, eg ``foo(a=)``. - A value is assigned to a star argument, eg +``foo(*args=[0])``. - A value is assigned to a double-star keyword argument, +eg ``foo(**kwarg={'a': 0})``. + +.. + +.. bpo: 45026 +.. date: 2021-08-29-15-55-19 +.. nonce: z7nTA3 +.. section: Core and Builtins + +Optimize the :class:`range` object iterator. It is now smaller, faster +iteration of ranges containing large numbers. Smaller pickles, faster +unpickling. + +.. + +.. bpo: 31718 +.. date: 2020-02-23-23-48-15 +.. nonce: sXko5e +.. section: Core and Builtins + +Raise :exc:`ValueError` instead of :exc:`SystemError` when methods of +uninitialized :class:`io.IncrementalNewlineDecoder` objects are called. +Patch by Oren Milman. + +.. + +.. bpo: 38031 +.. date: 2019-09-04-19-09-49 +.. nonce: Yq4L72 +.. section: Core and Builtins + +Fix a possible assertion failure in :class:`io.FileIO` when the opener +returns an invalid file descriptor. + +.. + +.. date: 2022-12-05-13-40-15 +.. gh-issue: 100001 +.. nonce: 78ReYp +.. section: Library + +Also \ escape \s in the http.server BaseHTTPRequestHandler.log_message so +that it is technically possible to parse the line and reconstruct what the +original data was. Without this a \xHH is ambiguious as to if it is a hex +replacement we put in or the characters r"\x" came through in the original +request line. + +.. + +.. date: 2022-12-03-05-58-48 +.. gh-issue: 99957 +.. nonce: jLYYgN +.. section: Library + +Add ``frozen_default`` parameter to :func:`typing.dataclass_transform`. + +.. + +.. date: 2022-11-22-19-31-26 +.. gh-issue: 79033 +.. nonce: MW6kHq +.. section: Library + +Fix :func:`asyncio.Server.wait_closed` to actually do what the docs promise +-- wait for all existing connections to complete, after closing the server. + +.. + +.. date: 2022-11-21-17-56-18 +.. gh-issue: 51524 +.. nonce: nTykx8 +.. section: Library + +Fix bug when calling trace.CoverageResults with valid infile. + +.. + +.. date: 2022-11-21-13-49-03 +.. gh-issue: 99645 +.. nonce: 9w1QKq +.. section: Library + +Fix a bug in handling class cleanups in :class:`unittest.TestCase`. Now +``addClassCleanup()`` uses separate lists for different ``TestCase`` +subclasses, and ``doClassCleanups()`` only cleans up the particular class. + +.. + +.. date: 2022-11-21-10-45-54 +.. gh-issue: 99508 +.. nonce: QqVbby +.. section: Library + +Fix ``TypeError`` in ``Lib/importlib/_bootstrap_external.py`` while calling +``_imp.source_hash()``. + +.. + +.. date: 2022-11-17-10-56-47 +.. gh-issue: 66285 +.. nonce: KvjlaB +.. section: Library + +Fix :mod:`asyncio` to not share event loop and signal wakeupfd in forked +processes. Patch by Kumar Aditya. + +.. + +.. date: 2022-11-15-10-55-24 +.. gh-issue: 97001 +.. nonce: KeQuVF +.. section: Library + +Release the GIL when calling termios APIs to avoid blocking threads. + +.. + +.. date: 2022-11-15-04-08-25 +.. gh-issue: 92647 +.. nonce: cZcjnJ +.. section: Library + +Use final status of an enum to determine lookup or creation branch of +functional API. + +.. + +.. date: 2022-11-14-08-21-56 +.. gh-issue: 99388 +.. nonce: UWSlwp +.. section: Library + +Add *loop_factory* parameter to :func:`asyncio.run` to allow specifying a +custom event loop factory. Patch by Kumar Aditya. + +.. + +.. date: 2022-11-13-02-06-56 +.. gh-issue: 99341 +.. nonce: 8-OlwB +.. section: Library + +Fix :func:`ast.increment_lineno` to also cover :class:`ast.TypeIgnore` when +changing line numbers. + +.. + +.. date: 2022-11-12-12-15-30 +.. gh-issue: 99382 +.. nonce: dKg_rW +.. section: Library + +Check the number of arguments in substitution in user generics containing a +:class:`~typing.TypeVarTuple` and one or more :class:`~typing.TypeVar`. + +.. + +.. date: 2022-11-12-12-10-23 +.. gh-issue: 99379 +.. nonce: bcGhxF +.. section: Library + +Fix substitution of :class:`~typing.ParamSpec` followed by +:class:`~typing.TypeVarTuple` in generic aliases. + +.. + +.. date: 2022-11-12-12-08-34 +.. gh-issue: 99344 +.. nonce: 7M_u8G +.. section: Library + +Fix substitution of :class:`~typing.TypeVarTuple` and +:class:`~typing.ParamSpec` together in user generics. + +.. + +.. date: 2022-11-09-12-36-12 +.. gh-issue: 99284 +.. nonce: 9p4J2l +.. section: Library + +Remove ``_use_broken_old_ctypes_structure_semantics_`` old untested and +undocumented hack from :mod:`ctypes`. + +.. + +.. date: 2022-11-09-03-34-29 +.. gh-issue: 99201 +.. nonce: lDJ7xI +.. section: Library + +Fix :exc:`IndexError` when initializing the config variables on Windows if +``HAVE_DYNAMIC_LOADING`` is not set. + +.. + +.. date: 2022-11-08-15-54-43 +.. gh-issue: 99240 +.. nonce: MhYwcz +.. section: Library + +Fix double-free bug in Argument Clinic ``str_converter`` by extracting +memory clean up to a new ``post_parsing`` section. + +.. + +.. date: 2022-11-08-11-18-51 +.. gh-issue: 64490 +.. nonce: VcBgrN +.. section: Library + +Fix refcount error when arguments are packed to tuple in Argument Clinic. + +.. + +.. date: 2022-11-02-23-47-07 +.. gh-issue: 99029 +.. nonce: 7uCiIB +.. section: Library + +:meth:`pathlib.PurePath.relative_to()` now treats naked Windows drive paths +as relative. This brings its behaviour in line with other parts of pathlib. + +.. + +.. date: 2022-10-24-11-01-05 +.. gh-issue: 98253 +.. nonce: HVd5v4 +.. section: Library + +The implementation of the typing module is now more resilient to reference +leaks in binary extension modules. + +Previously, a reference leak in a typed C API-based extension module could +leak internals of the typing module, which could in turn introduce leaks in +essentially any other package with typed function signatures. Although the +typing package is not the original source of the problem, such non-local +dependences exacerbate debugging of large-scale projects, and the +implementation was therefore changed to reduce harm by providing better +isolation. + +.. + +.. date: 2022-10-19-18-31-53 +.. gh-issue: 98458 +.. nonce: vwyq7O +.. section: Library + +Fix infinite loop in unittest when a self-referencing chained exception is +raised + +.. + +.. date: 2022-10-19-13-37-23 +.. gh-issue: 93453 +.. nonce: wTB_sH +.. section: Library + +:func:`asyncio.get_event_loop` and many other :mod:`asyncio` functions like +:func:`asyncio.ensure_future`, :func:`asyncio.shield` or +:func:`asyncio.gather`, and also the +:meth:`~asyncio.BaseDefaultEventLoopPolicy.get_event_loop` method of +:class:`asyncio.BaseDefaultEventLoopPolicy` now raise a :exc:`RuntimeError` +if called when there is no running event loop and the current event loop was +not set. Previously they implicitly created and set a new current event +loop. :exc:`DeprecationWarning` is no longer emitted if there is no running +event loop but the current event loop was set. + +.. + +.. date: 2022-10-16-18-52-00 +.. gh-issue: 97966 +.. nonce: humlhz +.. section: Library + +On ``uname_result``, restored expectation that ``_fields`` and ``_asdict`` +would include all six properties including ``processor``. + +.. + +.. date: 2022-10-13-22-13-54 +.. gh-issue: 98248 +.. nonce: lwyygy +.. section: Library + +Provide informative error messages in :func:`struct.pack` when its integral +arguments are not in range. + +.. + +.. date: 2022-10-08-19-20-33 +.. gh-issue: 98108 +.. nonce: WUObqM +.. section: Library + +``zipfile.Path`` is now pickleable if its initialization parameters were +pickleable (e.g. for file system paths). + +.. + +.. date: 2022-10-08-15-41-00 +.. gh-issue: 98098 +.. nonce: DugpWi +.. section: Library + +Created packages from zipfile and test_zipfile modules, separating +``zipfile.Path`` functionality. + +.. + +.. date: 2022-10-02-12-38-22 +.. gh-issue: 82836 +.. nonce: OvYLmC +.. section: Library + +Fix :attr:`~ipaddress.IPv4Address.is_private` properties in the +:mod:`ipaddress` module. Previously non-private networks (0.0.0.0/0) would +return True from this method; now they correctly return False. + +.. + +.. date: 2022-09-14-21-56-15 +.. gh-issue: 96828 +.. nonce: ZoOY5G +.. section: Library + +Add an :data:`~ssl.OP_ENABLE_KTLS` option for enabling the use of the kernel +TLS (kTLS). Patch by Illia Volochii. + +.. + +.. date: 2022-08-06-12-18-07 +.. gh-issue: 88863 +.. nonce: NnqsuJ +.. section: Library + +To avoid apparent memory leaks when :func:`asyncio.open_connection` raises, +break reference cycles generated by local exception and future instances +(which has exception instance as its member var). Patch by Dong Uk, Kang. + +.. + +.. date: 2022-04-23-03-46-37 +.. gh-issue: 91078 +.. nonce: 87-hkp +.. section: Library + +:meth:`TarFile.next` now returns ``None`` when called on an empty tarfile. + +.. + +.. bpo: 47220 +.. date: 2022-04-04-22-54-11 +.. nonce: L9jYu4 +.. section: Library + +Document the optional *callback* parameter of :class:`WeakMethod`. Patch by +Géry Ogam. + +.. + +.. bpo: 44817 +.. date: 2021-08-03-05-31-00 +.. nonce: wOW_Qn +.. section: Library + +Ignore WinError 53 (ERROR_BAD_NETPATH), 65 (ERROR_NETWORK_ACCESS_DENIED) and +161 (ERROR_BAD_PATHNAME) when using ntpath.realpath(). + +.. + +.. bpo: 41260 +.. date: 2020-08-02-23-46-22 +.. nonce: Q2BNzY +.. section: Library + +Rename the *fmt* parameter of the pure Python implementation of +:meth:`datetime.date.strftime` to *format*. + +.. + +.. bpo: 15999 +.. date: 2019-08-30-10-48-53 +.. nonce: QqsRRi +.. section: Library + +All built-in functions now accept arguments of any type instead of just +``bool`` and ``int`` for boolean parameters. + +.. + +.. date: 2022-12-02-17-08-08 +.. gh-issue: 99931 +.. nonce: wC46hE +.. section: Documentation + +Use `sphinxext-opengraph `__ to +generate `OpenGraph metadata `__. + +.. + +.. date: 2022-11-26-21-43-05 +.. gh-issue: 89682 +.. nonce: DhKoTM +.. section: Documentation + +Reworded docstring of the default ``__contains__`` to clarify that it +returns a :class:`bool`. + +.. + +.. date: 2022-11-26-15-51-23 +.. gh-issue: 88330 +.. nonce: B_wFq8 +.. section: Documentation + +Improved the description of what a resource is in importlib.resources docs. + +.. + +.. date: 2022-11-16-12-52-23 +.. gh-issue: 92892 +.. nonce: TS-P0j +.. section: Documentation + +Document that calling variadic functions with ctypes requires special care +on macOS/arm64 (and possibly other platforms). + +.. + +.. bpo: 41825 +.. date: 2020-09-22-12-32-16 +.. nonce: npcaCb +.. section: Documentation + +Restructured the documentation for the :func:`os.wait* ` family of +functions, and improved the docs for :func:`os.waitid` with more explanation +of the possible argument constants. + +.. + +.. date: 2022-12-05-16-12-56 +.. gh-issue: 99892 +.. nonce: sz_eW8 +.. section: Tests + +Skip test_normalization() of test_unicodedata if it fails to download +NormalizationTest.txt file from pythontest.net. Patch by Victor Stinner. + +.. + +.. date: 2022-12-01-18-55-18 +.. gh-issue: 99934 +.. nonce: Ox3Fqf +.. section: Tests + +Correct test_marsh on (32 bit) x86: test_deterministic sets was failing. + +.. + +.. date: 2022-11-23-18-32-16 +.. gh-issue: 99741 +.. nonce: q4R7NH +.. section: Tests + +We've implemented multi-phase init (PEP 489/630/687) for the internal (for +testing) _xxsubinterpreters module. + +.. + +.. date: 2022-11-21-19-21-30 +.. gh-issue: 99659 +.. nonce: 4gP0nm +.. section: Tests + +Optional big memory tests in ``test_sqlite3`` now catch the correct +:exc:`sqlite.DataError` exception type in case of too large strings and/or +blobs passed. + +.. + +.. date: 2022-11-19-13-34-28 +.. gh-issue: 99593 +.. nonce: 8ZfCkj +.. section: Tests + +Cover the Unicode C API with tests. + +.. + +.. date: 2022-08-22-15-49-14 +.. gh-issue: 96002 +.. nonce: 4UE9UE +.. section: Tests + +Add functional test for Argument Clinic. + +.. + +.. date: 2022-11-24-02-58-10 +.. gh-issue: 99086 +.. nonce: DV_4Br +.. section: Build + +Fix ``-Wimplicit-int``, ``-Wstrict-prototypes``, and +``-Wimplicit-function-declaration`` compiler warnings in +:program:`configure` checks. + +.. + +.. date: 2022-11-15-08-40-22 +.. gh-issue: 99337 +.. nonce: 5LoQDE +.. section: Build + +Fix a compilation issue with GCC 12 on macOS. + +.. + +.. date: 2022-11-09-14-42-48 +.. gh-issue: 99289 +.. nonce: X7wFE1 +.. section: Build + +Add a ``COMPILEALL_OPTS`` variable in Makefile to override :mod:`compileall` +options (default: ``-j0``) in ``make install``. Also merged the +``compileall`` commands into a single command building .pyc files for the +all optimization levels (0, 1, 2) at once. Patch by Victor Stinner. + +.. + +.. date: 2022-11-03-08-10-49 +.. gh-issue: 98872 +.. nonce: gdsR8X +.. section: Build + +Fix a possible fd leak in ``Programs/_freeze_module.c`` introduced in Python +3.11. + +.. + +.. date: 2022-10-16-12-49-24 +.. gh-issue: 88226 +.. nonce: BsnQ4k +.. section: Build + +Always define ``TARGET_*`` labels in ``Python/ceval.c``, even if +``USE_COMPUTED_GOTOS`` is disabled. This allows breakpoints to be set at +those labels in (for instance) ``gdb``. + +.. + +.. date: 2022-11-23-17-17-16 +.. gh-issue: 99345 +.. nonce: jOa3-f +.. section: Windows + +Use faster initialization functions to detect install location for Windows +Store package + +.. + +.. date: 2022-11-21-19-50-18 +.. gh-issue: 98629 +.. nonce: tMmB_B +.. section: Windows + +Fix initialization of :data:`sys.version` and ``sys._git`` on Windows + +.. + +.. date: 2022-11-16-19-03-21 +.. gh-issue: 99442 +.. nonce: 6Dgk3Q +.. section: Windows + +Fix handling in :ref:`launcher` when ``argv[0]`` does not include a file +extension. + +.. + +.. bpo: 40882 +.. date: 2020-06-06-15-10-37 +.. nonce: UvNbdj +.. section: Windows + +Fix a memory leak in :class:`multiprocessing.shared_memory.SharedMemory` on +Windows. + +.. + +.. date: 2022-11-25-09-23-20 +.. gh-issue: 87235 +.. nonce: SifjCD +.. section: macOS + +On macOS ``python3 /dev/fd/9 9previous in frameobject.c to fix a segmentation fault when +accessing frames created by :c:func:`PyFrame_New`. + +.. + +.. date: 2022-12-12-00-59-11 +.. gh-issue: 94155 +.. nonce: LWE9y_ +.. section: Core and Builtins + +Improved the hashing algorithm for code objects, mitigating some hash +collisions. + +.. + +.. date: 2022-12-10-20-00-13 +.. gh-issue: 99540 +.. nonce: ZZZHeP +.. section: Core and Builtins + +``None`` now hashes to a constant value. This is not a requirements change. + +.. + +.. date: 2022-12-09-14-27-36 +.. gh-issue: 100143 +.. nonce: 5g9rb4 +.. section: Core and Builtins + +When built with ``--enable-pystats``, stats collection is now off by +default. To enable it early at startup, pass the ``-Xpystats`` flag. Stats +are now always dumped, even if switched off. + +.. + +.. date: 2022-12-09-13-18-42 +.. gh-issue: 100146 +.. nonce: xLVKg0 +.. section: Core and Builtins + +Improve ``BUILD_LIST`` opcode so that it works similarly to the +``BUILD_TUPLE`` opcode, by stealing references from the stack rather than +repeatedly using stack operations to set list elements. Implementation +details are in a new private API :c:func:`_PyList_FromArraySteal`. + +.. + +.. date: 2022-12-08-12-26-34 +.. gh-issue: 100110 +.. nonce: ertac- +.. section: Core and Builtins + +Specialize ``FOR_ITER`` for tuples. + +.. + +.. date: 2022-12-06-22-24-01 +.. gh-issue: 100050 +.. nonce: lcrPqQ +.. section: Core and Builtins + +Honor existing errors obtained when searching for mismatching parentheses in +the tokenizer. Patch by Pablo Galindo + +.. + +.. date: 2022-12-04-00-38-33 +.. gh-issue: 92216 +.. nonce: CJXuWB +.. section: Core and Builtins + +Improve the performance of :func:`hasattr` for type objects with a missing +attribute. + +.. + +.. date: 2022-11-19-01-11-06 +.. gh-issue: 99582 +.. nonce: wvOBVy +.. section: Core and Builtins + +Freeze :mod:`zipimport` module into ``_bootstrap_python``. + +.. + +.. date: 2022-11-16-05-57-24 +.. gh-issue: 99554 +.. nonce: A_Ywd2 +.. section: Core and Builtins + +Pack debugging location tables more efficiently during bytecode compilation. + +.. + +.. date: 2022-10-21-16-10-39 +.. gh-issue: 98522 +.. nonce: s_SixG +.. section: Core and Builtins + +Add an internal version number to code objects, to give better versioning of +inner functions and comprehensions, and thus better specialization of those +functions. This change is invisible to both Python and C extensions. + +.. + +.. date: 2022-07-06-18-44-00 +.. gh-issue: 94603 +.. nonce: Q_03xV +.. section: Core and Builtins + +Improve performance of ``list.pop`` for small lists. + +.. + +.. date: 2022-06-17-08-00-34 +.. gh-issue: 89051 +.. nonce: yP4Na0 +.. section: Core and Builtins + +Add :data:`ssl.OP_LEGACY_SERVER_CONNECT` + +.. + +.. bpo: 32782 +.. date: 2018-02-06-23-21-13 +.. nonce: EJVSfR +.. section: Core and Builtins + +``ctypes`` arrays of length 0 now report a correct itemsize when a +``memoryview`` is constructed from them, rather than always giving a value +of 0. + +.. + +.. date: 2023-01-08-12-10-17 +.. gh-issue: 100833 +.. nonce: f6cT7E +.. section: Library + +Speed up :func:`math.fsum` by removing defensive ``volatile`` qualifiers. + +.. + +.. date: 2023-01-07-15-13-47 +.. gh-issue: 100805 +.. nonce: 05rBz9 +.. section: Library + +Modify :func:`random.choice` implementation to once again work with NumPy +arrays. + +.. + +.. date: 2023-01-06-22-36-27 +.. gh-issue: 100813 +.. nonce: mHRdQn +.. section: Library + +Add :data:`socket.IP_PKTINFO` constant. + +.. + +.. date: 2023-01-06-14-05-15 +.. gh-issue: 100792 +.. nonce: CEOJth +.. section: Library + +Make :meth:`email.message.Message.__contains__` twice as fast. + +.. + +.. date: 2023-01-05-23-04-15 +.. gh-issue: 91851 +.. nonce: AuCzU5 +.. section: Library + +Microoptimizations for :meth:`fractions.Fraction.__round__`, +:meth:`fractions.Fraction.__ceil__` and +:meth:`fractions.Fraction.__floor__`. + +.. + +.. date: 2023-01-04-22-10-31 +.. gh-issue: 90104 +.. nonce: yZk5EX +.. section: Library + +Avoid RecursionError on ``repr`` if a dataclass field definition has a +cyclic reference. + +.. + +.. date: 2023-01-04-12-58-59 +.. gh-issue: 100689 +.. nonce: Ce0ITG +.. section: Library + +Fix crash in :mod:`pyexpat` by statically allocating ``PyExpat_CAPI`` +capsule. + +.. + +.. date: 2023-01-04-09-53-38 +.. gh-issue: 100740 +.. nonce: -j5UjI +.. section: Library + +Fix ``unittest.mock.Mock`` not respecting the spec for attribute names +prefixed with ``assert``. + +.. + +.. date: 2023-01-03-11-06-28 +.. gh-issue: 91219 +.. nonce: s5IFCw +.. section: Library + +Change ``SimpleHTTPRequestHandler`` to support subclassing to provide a +different set of index file names instead of using ``__init__`` parameters. + +.. + +.. date: 2023-01-02-16-59-49 +.. gh-issue: 100690 +.. nonce: 2EgWPS +.. section: Library + +``Mock`` objects which are not unsafe will now raise an ``AttributeError`` +when accessing an attribute that matches the name of an assertion but +without the prefix ``assert_``, e.g. accessing ``called_once`` instead of +``assert_called_once``. This is in addition to this already happening for +accessing attributes with prefixes ``assert``, ``assret``, ``asert``, +``aseert``, and ``assrt``. + +.. + +.. date: 2023-01-01-23-57-00 +.. gh-issue: 89727 +.. nonce: ojedHN +.. section: Library + +Simplify and optimize :func:`os.walk` by using :func:`isinstance` checks to +check the top of the stack. + +.. + +.. date: 2023-01-01-21-54-46 +.. gh-issue: 100485 +.. nonce: geNrHS +.. section: Library + +Add math.sumprod() to compute the sum of products. + +.. + +.. date: 2022-12-30-07-49-08 +.. gh-issue: 86508 +.. nonce: nGZDzC +.. section: Library + +Fix :func:`asyncio.open_connection` to skip binding to local addresses of +different family. Patch by Kumar Aditya. + +.. + +.. date: 2022-12-29-11-45-22 +.. gh-issue: 97930 +.. nonce: hrtmJe +.. section: Library + +``importlib.resources.files`` now accepts a module as an anchor instead of +only accepting packages. If a module is passed, resources are resolved +adjacent to that module (in the same package or at the package root). The +parameter was renamed from ``package`` to ``anchor`` with a compatibility +shim for those passing by keyword. Additionally, the new ``anchor`` +parameter is now optional and will default to the caller's module. + +.. + +.. date: 2022-12-28-17-38-39 +.. gh-issue: 100585 +.. nonce: BiiTlG +.. section: Library + +Fixed a bug where importlib.resources.as_file was leaving file pointers open + +.. + +.. date: 2022-12-28-00-28-43 +.. gh-issue: 100562 +.. nonce: Hic0Z0 +.. section: Library + +Improve performance of :meth:`pathlib.Path.absolute` by nearly 2x. This +comes at the cost of a performance regression in :meth:`pathlib.Path.cwd`, +which is generally used less frequently in user code. + +.. + +.. date: 2022-12-24-16-39-53 +.. gh-issue: 100519 +.. nonce: G_dZLP +.. section: Library + +Small simplification of :func:`http.cookiejar.eff_request_host` that +improves readability and better matches the RFC wording. + +.. + +.. date: 2022-12-24-08-42-05 +.. gh-issue: 100287 +.. nonce: n0oEuG +.. section: Library + +Fix the interaction of :func:`unittest.mock.seal` with +:class:`unittest.mock.AsyncMock`. + +.. + +.. date: 2022-12-24-04-13-54 +.. gh-issue: 100488 +.. nonce: Ut8HbE +.. section: Library + +Add :meth:`Fraction.is_integer` to check whether a +:class:`fractions.Fraction` is an integer. This improves duck type +compatibility with :class:`float` and :class:`int`. + +.. + +.. date: 2022-12-23-21-02-43 +.. gh-issue: 100474 +.. nonce: gppA4U +.. section: Library + +:mod:`http.server` now checks that an index page is actually a regular file +before trying to serve it. This avoids issues with directories named +``index.html``. + +.. + +.. date: 2022-12-20-11-07-30 +.. gh-issue: 100363 +.. nonce: Wo_Beg +.. section: Library + +Speed up :func:`asyncio.get_running_loop` by removing redundant ``getpid`` +checks. Patch by Kumar Aditya. + +.. + +.. date: 2022-12-19-20-54-04 +.. gh-issue: 78878 +.. nonce: JrkYqJ +.. section: Library + +Fix crash when creating an instance of :class:`!_ctypes.CField`. + +.. + +.. date: 2022-12-19-19-30-06 +.. gh-issue: 100348 +.. nonce: o7IAHh +.. section: Library + +Fix ref cycle in :class:`!asyncio._SelectorSocketTransport` by removing +``_read_ready_cb`` in ``close``. + +.. + +.. date: 2022-12-19-12-18-28 +.. gh-issue: 100344 +.. nonce: lfCqpE +.. section: Library + +Provide C implementation for :func:`asyncio.current_task` for a 4x-6x +speedup. + +.. + +.. date: 2022-12-15-18-28-13 +.. gh-issue: 100272 +.. nonce: D1O9Ey +.. section: Library + +Fix JSON serialization of OrderedDict. It now preserves the order of keys. + +.. + +.. date: 2022-12-14-17-37-01 +.. gh-issue: 83076 +.. nonce: NaYzWT +.. section: Library + +Instantiation of ``Mock()`` and ``AsyncMock()`` is now 3.8x faster. + +.. + +.. date: 2022-12-14-11-45-38 +.. gh-issue: 100234 +.. nonce: kn6yWV +.. section: Library + +Set a default value of 1.0 for the ``lambd`` parameter in +random.expovariate(). + +.. + +.. date: 2022-12-13-17-29-09 +.. gh-issue: 100228 +.. nonce: bgtzMV +.. section: Library + +A :exc:`DeprecationWarning` may be raised when :func:`os.fork()` or +:func:`os.forkpty()` is called from multi-threaded processes. Forking with +threads is unsafe and can cause deadlocks, crashes and subtle problems. Lack +of a warning does not indicate that the fork call was actually safe, as +Python may not be aware of all threads. + +.. + +.. date: 2022-12-10-20-52-28 +.. gh-issue: 100039 +.. nonce: zDqjT4 +.. section: Library + +Improve signatures for enums and flags. + +.. + +.. date: 2022-12-10-08-36-07 +.. gh-issue: 100133 +.. nonce: g-zQlp +.. section: Library + +Fix regression in :mod:`asyncio` where a subprocess would sometimes lose +data received from pipe. + +.. + +.. bpo: 44592 +.. date: 2022-12-09-10-35-36 +.. nonce: z-P3oe +.. section: Library + +Fixes inconsistent handling of case sensitivity of *extrasaction* arg in +:class:`csv.DictWriter`. + +.. + +.. date: 2022-12-08-06-18-06 +.. gh-issue: 100098 +.. nonce: uBvPlp +.. section: Library + +Fix ``tuple`` subclasses being cast to ``tuple`` when used as enum values. + +.. + +.. date: 2022-12-04-16-12-04 +.. gh-issue: 85432 +.. nonce: l_ehmI +.. section: Library + +Rename the *fmt* parameter of the pure-Python implementation of +:meth:`datetime.time.strftime` to *format*. Rename the *t* parameter of +:meth:`datetime.datetime.fromtimestamp` to *timestamp*. These changes mean +the parameter names in the pure-Python implementation now match the +parameter names in the C implementation. Patch by Alex Waygood. + +.. + +.. date: 2022-12-03-20-06-16 +.. gh-issue: 98778 +.. nonce: t5U9uc +.. section: Library + +Update :exc:`~urllib.error.HTTPError` to be initialized properly, even if +the ``fp`` is ``None``. Patch by Dong-hee Na. + +.. + +.. date: 2022-12-01-15-44-58 +.. gh-issue: 99925 +.. nonce: x4y6pF +.. section: Library + +Unify error messages in JSON serialization between +``json.dumps(float('nan'), allow_nan=False)`` and ``json.dumps(float('nan'), +allow_nan=False, indent=)``. Now both include the representation +of the value that could not be serialized. + +.. + +.. date: 2022-11-29-20-44-54 +.. gh-issue: 89727 +.. nonce: UJZjkk +.. section: Library + +Fix issue with :func:`os.walk` where a :exc:`RecursionError` would occur on +deep directory structures by adjusting the implementation of :func:`os.walk` +to be iterative instead of recursive. + +.. + +.. date: 2022-11-23-23-58-45 +.. gh-issue: 94943 +.. nonce: Oog0Zo +.. section: Library + +Add :ref:`enum-dataclass-support` to the :class:`~enum.Enum` +:meth:`~enum.Enum.__repr__`. When inheriting from a +:class:`~dataclasses.dataclass`, only show the field names in the value +section of the member :func:`repr`, and not the dataclass' class name. + +.. + +.. date: 2022-11-21-16-24-01 +.. gh-issue: 83035 +.. nonce: qZIujU +.. section: Library + +Fix :func:`inspect.getsource` handling of decorator calls with nested +parentheses. + +.. + +.. date: 2022-11-20-11-59-54 +.. gh-issue: 99576 +.. nonce: ZD7jU6 +.. section: Library + +Fix ``.save()`` method for ``LWPCookieJar`` and ``MozillaCookieJar``: saved +file was not truncated on repeated save. + +.. + +.. date: 2022-11-17-10-02-18 +.. gh-issue: 94912 +.. nonce: G2aa-E +.. section: Library + +Add :func:`inspect.markcoroutinefunction` decorator which manually marks a +function as a coroutine for the benefit of :func:`iscoroutinefunction`. + +.. + +.. date: 2022-11-15-18-45-01 +.. gh-issue: 99509 +.. nonce: FLK0xU +.. section: Library + +Add :pep:`585` support for :class:`multiprocessing.queues.Queue`. + +.. + +.. date: 2022-11-14-19-58-36 +.. gh-issue: 99482 +.. nonce: XmZyUr +.. section: Library + +Remove ``Jython`` partial compatibility code from several stdlib modules. + +.. + +.. date: 2022-11-13-15-32-19 +.. gh-issue: 99433 +.. nonce: Ys6y0A +.. section: Library + +Fix :mod:`doctest` failure on :class:`types.MethodWrapperType` in modules. + +.. + +.. date: 2022-10-28-07-24-34 +.. gh-issue: 85267 +.. nonce: xUy_Wm +.. section: Library + +Several improvements to :func:`inspect.signature`'s handling of +``__text_signature``. - Fixes a case where :func:`inspect.signature` dropped +parameters - Fixes a case where :func:`inspect.signature` raised +:exc:`tokenize.TokenError` - Allows :func:`inspect.signature` to understand +defaults involving binary operations of constants - +:func:`inspect.signature` is documented as only raising :exc:`TypeError` or +:exc:`ValueError`, but sometimes raised :exc:`RuntimeError`. These cases now +raise :exc:`ValueError` - Removed a dead code path + +.. + +.. date: 2022-10-24-07-31-11 +.. gh-issue: 91166 +.. nonce: -IG06R +.. section: Library + +:mod:`asyncio` is optimized to avoid excessive copying when writing to +socket and use :meth:`~socket.socket.sendmsg` if the platform supports it. +Patch by Kumar Aditya. + +.. + +.. date: 2022-10-07-18-16-00 +.. gh-issue: 98030 +.. nonce: 2oQCZy +.. section: Library + +Add missing TCP socket options from Linux: ``TCP_MD5SIG``, +``TCP_THIN_LINEAR_TIMEOUTS``, ``TCP_THIN_DUPACK``, ``TCP_REPAIR``, +``TCP_REPAIR_QUEUE``, ``TCP_QUEUE_SEQ``, ``TCP_REPAIR_OPTIONS``, +``TCP_TIMESTAMP``, ``TCP_CC_INFO``, ``TCP_SAVE_SYN``, ``TCP_SAVED_SYN``, +``TCP_REPAIR_WINDOW``, ``TCP_FASTOPEN_CONNECT``, ``TCP_ULP``, +``TCP_MD5SIG_EXT``, ``TCP_FASTOPEN_KEY``, ``TCP_FASTOPEN_NO_COOKIE``, +``TCP_ZEROCOPY_RECEIVE``, ``TCP_INQ``, ``TCP_TX_DELAY``. + +.. + +.. date: 2022-09-16-08-21-46 +.. gh-issue: 88500 +.. nonce: jQ0pCc +.. section: Library + +Reduced the memory usage of :func:`urllib.parse.unquote` and +:func:`urllib.parse.unquote_to_bytes` on large values. + +.. + +.. date: 2022-08-27-10-35-50 +.. gh-issue: 96127 +.. nonce: 8RdLre +.. section: Library + +``inspect.signature`` was raising ``TypeError`` on call with mock objects. +Now it correctly returns ``(*args, **kwargs)`` as infered signature. + +.. + +.. date: 2022-08-11-10-02-19 +.. gh-issue: 95882 +.. nonce: FsUr72 +.. section: Library + +Fix a 3.11 regression in :func:`~contextlib.asynccontextmanager`, which +caused it to propagate exceptions with incorrect tracebacks and fix a 3.11 +regression in :func:`~contextlib.contextmanager`, which caused it to +propagate exceptions with incorrect tracebacks for :exc:`StopIteration`. + +.. + +.. date: 2022-07-01-00-01-22 +.. gh-issue: 78707 +.. nonce: fHGSuM +.. section: Library + +Deprecate passing more than one positional argument to +:meth:`pathlib.PurePath.relative_to` and +:meth:`~pathlib.PurePath.is_relative_to`. + +.. + +.. date: 2022-05-06-01-53-34 +.. gh-issue: 92122 +.. nonce: 96Lf2p +.. section: Library + +Fix reStructuredText syntax errors in docstrings in the :mod:`enum` module. + +.. + +.. date: 2022-04-23-08-12-14 +.. gh-issue: 91851 +.. nonce: Jd47V6 +.. section: Library + +Optimize the :class:`~fractions.Fraction` arithmetics for small components. + +.. + +.. bpo: 24132 +.. date: 2022-03-05-02-14-09 +.. nonce: W6iORO +.. section: Library + +Make :class:`pathlib.PurePath` and :class:`~pathlib.Path` subclassable +(private to start). Previously, attempting to instantiate a subclass +resulted in an :exc:`AttributeError` being raised. Patch by Barney Gale. + +.. + +.. bpo: 40447 +.. date: 2020-05-03-12-55-55 +.. nonce: oKR0Lj +.. section: Library + +Accept :class:`os.PathLike` (such as :class:`pathlib.Path`) in the +``stripdir`` arguments of :meth:`compileall.compile_file` and +:meth:`compileall.compile_dir`. + +.. + +.. bpo: 36880 +.. date: 2019-05-13-11-37-30 +.. nonce: ZgBgH0 +.. section: Library + +Fix a reference counting issue when a :mod:`ctypes` callback with return +type :class:`~ctypes.py_object` returns ``None``, which could cause crashes. + +.. + +.. date: 2022-12-30-00-42-23 +.. gh-issue: 100616 +.. nonce: eu80ij +.. section: Documentation + +Document existing ``attr`` parameter to :func:`curses.window.vline` function +in :mod:`curses`. + +.. + +.. date: 2022-12-23-21-42-26 +.. gh-issue: 100472 +.. nonce: NNixfO +.. section: Documentation + +Remove claim in documentation that the ``stripdir``, ``prependdir`` and +``limit_sl_dest`` parameters of :func:`compileall.compile_dir` and +:func:`compileall.compile_file` could be :class:`bytes`. + +.. + +.. bpo: 25377 +.. date: 2020-06-17-14-47-48 +.. nonce: CTxC6o +.. section: Documentation + +Clarify use of octal format of mode argument in help(os.chmod) as well as +help(os.fchmod) + +.. + +.. date: 2022-12-23-13-29-55 +.. gh-issue: 100454 +.. nonce: 3no0cW +.. section: Tests + +Start running SSL tests with OpenSSL 3.1.0-beta1. + +.. + +.. date: 2022-12-08-00-03-37 +.. gh-issue: 100086 +.. nonce: 1zYpto +.. section: Tests + +The Python test runner (libregrtest) now logs Python build information like +"debug" vs "release" build, or LTO and PGO optimizations. Patch by Victor +Stinner. + +.. + +.. date: 2022-06-16-13-26-31 +.. gh-issue: 93018 +.. nonce: wvNx76 +.. section: Tests + +Make two tests forgiving towards host system libexpat with backported +security fixes applied. + +.. + +.. date: 2022-12-26-15-07-48 +.. gh-issue: 100540 +.. nonce: l6ToSY +.. section: Build + +Removed the ``--with-system-ffi`` ``configure`` option; ``libffi`` must now +always be supplied by the system on all non-Windows platforms. The option +has had no effect on non-Darwin platforms for several releases, and in 3.11 +only had the non-obvious effect of invoking ``pkg-config`` to find +``libffi`` and never setting ``-DUSING_APPLE_OS_LIBFFI``. Now on Darwin +platforms ``configure`` will first check for the OS ``libffi`` and then fall +back to the same processing as other platforms if it is not found. + +.. + +.. date: 2022-12-08-14-00-04 +.. gh-issue: 88267 +.. nonce: MqtRbm +.. section: Build + +Avoid exporting Python symbols in linked Windows applications when the core +is built as static. + +.. + +.. bpo: 41916 +.. date: 2022-03-04-10-47-23 +.. nonce: 1d2GLU +.. section: Build + +Allow override of ac_cv_cxx_thread so that cross compiled python can set +-pthread for CXX. + +.. + +.. date: 2023-01-09-23-03-57 +.. gh-issue: 100180 +.. nonce: b5phrg +.. section: Windows + +Update Windows installer to OpenSSL 1.1.1s + +.. + +.. date: 2022-12-20-18-36-17 +.. gh-issue: 99191 +.. nonce: 0cfRja +.. section: Windows + +Use ``_MSVC_LANG >= 202002L`` instead of less-precise ``_MSC_VER >=1929`` to +more accurately test for C++20 support in :file:`PC/_wmimodule.cpp`. + +.. + +.. date: 2022-12-09-22-47-42 +.. gh-issue: 79218 +.. nonce: Yiot2e +.. section: Windows + +Define ``MS_WIN64`` for Mingw-w64 64bit, fix cython compilation failure. + +.. + +.. date: 2022-12-06-11-16-46 +.. gh-issue: 99941 +.. nonce: GmUQ6o +.. section: Windows + +Ensure that :func:`asyncio.Protocol.data_received` receives an immutable +:class:`bytes` object (as documented), instead of :class:`bytearray`. + +.. + +.. bpo: 43984 +.. date: 2021-05-02-15-29-33 +.. nonce: U92jiv +.. section: Windows + +:meth:`winreg.SetValueEx` now leaves the target value untouched in the case +of conversion errors. Previously, ``-1`` would be written in case of such +errors. + +.. + +.. bpo: 34816 +.. date: 2021-04-08-00-36-37 +.. nonce: 4Xe0id +.. section: Windows + +``hasattr(ctypes.windll, 'nonexistant')`` now returns ``False`` instead of +raising :exc:`OSError`. + +.. + +.. date: 2023-01-09-22-04-21 +.. gh-issue: 100180 +.. nonce: WVhCny +.. section: macOS + +Update macOS installer to OpenSSL 1.1.1s + +.. + +.. date: 2022-12-26-14-52-37 +.. gh-issue: 100540 +.. nonce: kYZLtX +.. section: macOS + +Removed obsolete ``dlfcn.h`` shim from the ``_ctypes`` extension module, +which has not been necessary since Mac OS X 10.2. + +.. + +.. bpo: 45256 +.. date: 2022-12-29-19-22-11 +.. nonce: a0ee_H +.. section: Tools/Demos + +Fix a bug that caused an :exc:`AttributeError` to be raised in +``python-gdb.py`` when ``py-locals`` is used without a frame. + +.. + +.. date: 2022-12-19-10-08-53 +.. gh-issue: 100342 +.. nonce: qDFlQG +.. section: Tools/Demos + +Add missing ``NULL`` check for possible allocation failure in ``*args`` +parsing in Argument Clinic. + +.. + +.. date: 2022-12-02-09-31-19 +.. gh-issue: 99947 +.. nonce: Ski7OC +.. section: C API + +Raising SystemError on import will now have its cause be set to the original +unexpected exception. + +.. + +.. date: 2022-11-30-16-39-22 +.. gh-issue: 99240 +.. nonce: 67nAX- +.. section: C API + +In argument parsing, after deallocating newly allocated memory, reset its +pointer to NULL. + +.. + +.. date: 2022-11-04-16-13-35 +.. gh-issue: 98724 +.. nonce: p0urWO +.. section: C API + +The :c:macro:`Py_CLEAR`, :c:macro:`Py_SETREF` and :c:macro:`Py_XSETREF` +macros now only evaluate their arguments once. If an argument has side +effects, these side effects are no longer duplicated. Patch by Victor +Stinner. diff --git a/Misc/NEWS.d/3.5.0a1.rst b/Misc/NEWS.d/3.5.0a1.rst index 97bdef6c932..96e59206cb1 100644 --- a/Misc/NEWS.d/3.5.0a1.rst +++ b/Misc/NEWS.d/3.5.0a1.rst @@ -3034,7 +3034,7 @@ by Phil Elson. .. nonce: LK_5S1 .. section: Library -os.read() now uses a :c:func:`Py_ssize_t` type instead of :c:type:`int` for +os.read() now uses a :c:func:`Py_ssize_t` type instead of :c:expr:`int` for the size to support reading more than 2 GB at once. On Windows, the size is truncated to INT_MAX. As any call to os.read(), the OS may read less bytes than the number of requested bytes. diff --git a/Misc/NEWS.d/3.5.1rc1.rst b/Misc/NEWS.d/3.5.1rc1.rst index d06817ccb95..dc247ce2096 100644 --- a/Misc/NEWS.d/3.5.1rc1.rst +++ b/Misc/NEWS.d/3.5.1rc1.rst @@ -900,7 +900,7 @@ Kurenkov. .. nonce: QhQ9RD .. section: Library -Fixed functools.singledispatch on classes with falsy metaclasses. Patch by +Fixed functools.singledispatch on classes with false metaclasses. Patch by Ethan Furman. .. diff --git a/Misc/NEWS.d/3.5.2rc1.rst b/Misc/NEWS.d/3.5.2rc1.rst index d891fa0880d..01fcd866a89 100644 --- a/Misc/NEWS.d/3.5.2rc1.rst +++ b/Misc/NEWS.d/3.5.2rc1.rst @@ -1,7 +1,73 @@ +.. bpo: 26556 +.. date: 9636 +.. nonce: v5j2uL +.. release date: 2016-06-12 +.. original section: Library +.. section: Security + +Update expat to 2.1.1, fixes CVE-2015-1283. + +.. + +.. bpo: 0 +.. date: 9635 +.. nonce: E4ochz +.. original section: Library +.. section: Security + +Fix TLS stripping vulnerability in smtplib, CVE-2016-0772. Reported by Team +Oststrom + +.. + +.. bpo: 26839 +.. date: 9629 +.. nonce: yVvy7R +.. original section: Library +.. section: Security + +On Linux, :func:`os.urandom` now calls ``getrandom()`` with +``GRND_NONBLOCK`` to fall back on reading ``/dev/urandom`` if the urandom +entropy pool is not initialized yet. Patch written by Colm Buckley. + +.. + +.. bpo: 26657 +.. date: 9597 +.. nonce: C_-XFg +.. original section: Library +.. section: Security + +Fix directory traversal vulnerability with http.server on Windows. This +fixes a regression that was introduced in 3.3.4rc1 and 3.4.0rc1. Based on +patch by Philipp Hagemeister. + +.. + +.. bpo: 26313 +.. date: 9581 +.. nonce: LjZAjy +.. original section: Library +.. section: Security + +ssl.py _load_windows_store_certs fails if windows cert store is empty. Patch +by Baji. + +.. + +.. bpo: 25939 +.. date: 9561 +.. nonce: X49Fqd +.. original section: Library +.. section: Security + +On Windows open the cert store readonly in ssl.enum_certificates. + +.. + .. bpo: 27066 .. date: 9673 .. nonce: SNExZi -.. release date: 2016-06-12 .. section: Core and Builtins Fixed SystemError if a custom opener (for open()) returns a negative number @@ -373,27 +439,6 @@ PendingDeprecationWarning. .. -.. bpo: 26556 -.. date: 9636 -.. nonce: v5j2uL -.. original section: Library -.. section: Security - -Update expat to 2.1.1, fixes CVE-2015-1283. - -.. - -.. bpo: 0 -.. date: 9635 -.. nonce: E4ochz -.. original section: Library -.. section: Security - -Fix TLS stripping vulnerability in smtplib, CVE-2016-0772. Reported by Team -Oststrom - -.. - .. bpo: 21386 .. date: 9634 .. nonce: DjV72U @@ -449,18 +494,6 @@ build information. .. -.. bpo: 26839 -.. date: 9629 -.. nonce: yVvy7R -.. original section: Library -.. section: Security - -On Linux, :func:`os.urandom` now calls ``getrandom()`` with -``GRND_NONBLOCK`` to fall back on reading ``/dev/urandom`` if the urandom -entropy pool is not initialized yet. Patch written by Colm Buckley. - -.. - .. bpo: 27164 .. date: 9628 .. nonce: 6wmjx2 @@ -776,18 +809,6 @@ limits for multibyte character encodings like utf-8. .. -.. bpo: 26657 -.. date: 9597 -.. nonce: C_-XFg -.. original section: Library -.. section: Security - -Fix directory traversal vulnerability with http.server on Windows. This -fixes a regression that was introduced in 3.3.4rc1 and 3.4.0rc1. Based on -patch by Philipp Hagemeister. - -.. - .. bpo: 26717 .. date: 9596 .. nonce: jngTdu @@ -937,17 +958,6 @@ Peter Inglesby. .. -.. bpo: 26313 -.. date: 9581 -.. nonce: LjZAjy -.. original section: Library -.. section: Security - -ssl.py _load_windows_store_certs fails if windows cert store is empty. Patch -by Baji. - -.. - .. bpo: 26569 .. date: 9580 .. nonce: EX8vF1 @@ -1136,16 +1146,6 @@ socket) when verify_request() returns false. Patch by Aviv Palivoda. .. -.. bpo: 25939 -.. date: 9561 -.. nonce: X49Fqd -.. original section: Library -.. section: Security - -On Windows open the cert store readonly in ssl.enum_certificates. - -.. - .. bpo: 25995 .. date: 9560 .. nonce: NfcimP @@ -2154,6 +2154,16 @@ Excludes venv from library when generating embeddable distro. .. +.. bpo: 17500 +.. date: 9453 +.. nonce: QTZbRV +.. section: Windows + +Remove unused and outdated icons. (See also: +https://github.com/python/pythondotorg/issues/945) + +.. + .. bpo: 26799 .. date: 9457 .. nonce: gK2VXX @@ -2191,13 +2201,3 @@ Teo. .. section: Tools/Demos Fix variable name typo in Argument Clinic. - -.. - -.. bpo: 17500 -.. date: 9453 -.. nonce: QTZbRV -.. section: Windows - -Remove unused and outdated icons. (See also: -https://github.com/python/pythondotorg/issues/945) diff --git a/Misc/NEWS.d/3.5.3rc1.rst b/Misc/NEWS.d/3.5.3rc1.rst index 037cfe41651..bf4ef9302c9 100644 --- a/Misc/NEWS.d/3.5.3rc1.rst +++ b/Misc/NEWS.d/3.5.3rc1.rst @@ -1,7 +1,29 @@ +.. release date: 2017-01-02 +.. bpo: 27278 +.. date: 9755 +.. nonce: y_HkGw +.. original section: Library +.. section: Security + +Fix os.urandom() implementation using getrandom() on Linux. Truncate size +to INT_MAX and loop until we collected enough random bytes, instead of +casting a directly Py_ssize_t to int. + +.. + +.. bpo: 22636 +.. date: 9753 +.. nonce: 3fQW_g +.. original section: Library +.. section: Security + +Avoid shell injection problems with ctypes.util.find_library(). + +.. + .. bpo: 29073 .. date: 9898 .. nonce: EFpHQ7 -.. release date: 2017-01-02 .. section: Core and Builtins bytearray formatting no longer truncates on first null byte. @@ -810,7 +832,7 @@ In the traceback module, restore the formatting of exception messages like .. nonce: 3UhyPo .. section: Library -Allow falsy values to be used for msg parameter of subTest(). +Allow false values to be used for msg parameter of subTest(). .. @@ -1406,18 +1428,6 @@ issue25782. .. -.. bpo: 27278 -.. date: 9755 -.. nonce: y_HkGw -.. original section: Library -.. section: Security - -Fix os.urandom() implementation using getrandom() on Linux. Truncate size -to INT_MAX and loop until we collected enough random bytes, instead of -casting a directly Py_ssize_t to int. - -.. - .. bpo: 26386 .. date: 9754 .. nonce: 9L3Ut4 @@ -1427,16 +1437,6 @@ Fixed ttk.TreeView selection operations with item id's containing spaces. .. -.. bpo: 22636 -.. date: 9753 -.. nonce: 3fQW_g -.. original section: Library -.. section: Security - -Avoid shell injection problems with ctypes.util.find_library(). - -.. - .. bpo: 16182 .. date: 9752 .. nonce: RgFXyr diff --git a/Misc/NEWS.d/3.6.0a1.rst b/Misc/NEWS.d/3.6.0a1.rst index 3fa356c56d9..53f09b3dfe3 100644 --- a/Misc/NEWS.d/3.6.0a1.rst +++ b/Misc/NEWS.d/3.6.0a1.rst @@ -1,7 +1,40 @@ +.. release date: 2016-05-16 +.. bpo: 26657 +.. date: 9135 +.. nonce: C_-XFg +.. original section: Library +.. section: Security + +Fix directory traversal vulnerability with http.server on Windows. This +fixes a regression that was introduced in 3.3.4rc1 and 3.4.0rc1. Based on +patch by Philipp Hagemeister. + +.. + +.. bpo: 26313 +.. date: 9102 +.. nonce: LjZAjy +.. original section: Library +.. section: Security + +ssl.py _load_windows_store_certs fails if windows cert store is empty. Patch +by Baji. + +.. + +.. bpo: 25939 +.. date: 9076 +.. nonce: X49Fqd +.. original section: Library +.. section: Security + +On Windows open the cert store readonly in ssl.enum_certificates. + +.. + .. bpo: 20041 .. date: 9253 .. nonce: TypyGp -.. release date: 2016-05-16 .. section: Core and Builtins Fixed TypeError when frame.f_trace is set to None. Patch by Xavier de Gaye. @@ -1198,18 +1231,6 @@ limits for multibyte character encodings like utf-8. .. -.. bpo: 26657 -.. date: 9135 -.. nonce: C_-XFg -.. original section: Library -.. section: Security - -Fix directory traversal vulnerability with http.server on Windows. This -fixes a regression that was introduced in 3.3.4rc1 and 3.4.0rc1. Based on -patch by Philipp Hagemeister. - -.. - .. bpo: 26717 .. date: 9134 .. nonce: jngTdu @@ -1532,17 +1553,6 @@ tracemalloc to get the traceback where source object was allocated. .. -.. bpo: 26313 -.. date: 9102 -.. nonce: LjZAjy -.. original section: Library -.. section: Security - -ssl.py _load_windows_store_certs fails if windows cert store is empty. Patch -by Baji. - -.. - .. bpo: 26569 .. date: 9101 .. nonce: EX8vF1 @@ -1793,16 +1803,6 @@ handle_error() method, and will now to stop a single-threaded server. .. -.. bpo: 25939 -.. date: 9076 -.. nonce: X49Fqd -.. original section: Library -.. section: Security - -On Windows open the cert store readonly in ssl.enum_certificates. - -.. - .. bpo: 25995 .. date: 9075 .. nonce: NfcimP diff --git a/Misc/NEWS.d/3.6.0a2.rst b/Misc/NEWS.d/3.6.0a2.rst index fa050dec27f..1b336d7bc51 100644 --- a/Misc/NEWS.d/3.6.0a2.rst +++ b/Misc/NEWS.d/3.6.0a2.rst @@ -1,7 +1,40 @@ +.. release date: 2016-06-13 +.. bpo: 26556 +.. date: 9316 +.. nonce: v5j2uL +.. original section: Library +.. section: Security + +Update expat to 2.1.1, fixes CVE-2015-1283. + +.. + +.. bpo: 0 +.. date: 9315 +.. nonce: PHOAdg +.. original section: Library +.. section: Security + +Fix TLS stripping vulnerability in smtplib, CVE-2016-0772. Reported by Team +Oststrom. + +.. + +.. bpo: 26839 +.. date: 9303 +.. nonce: yVvy7R +.. original section: Library +.. section: Security + +On Linux, :func:`os.urandom` now calls ``getrandom()`` with +``GRND_NONBLOCK`` to fall back on reading ``/dev/urandom`` if the urandom +entropy pool is not initialized yet. Patch written by Colm Buckley. + +.. + .. bpo: 27095 .. date: 9332 .. nonce: 92UoyH -.. release date: 2016-06-13 .. section: Core and Builtins Simplified MAKE_FUNCTION and removed MAKE_CLOSURE opcodes. Patch by Demur @@ -159,27 +192,6 @@ Rees. .. -.. bpo: 26556 -.. date: 9316 -.. nonce: v5j2uL -.. original section: Library -.. section: Security - -Update expat to 2.1.1, fixes CVE-2015-1283. - -.. - -.. bpo: 0 -.. date: 9315 -.. nonce: PHOAdg -.. original section: Library -.. section: Security - -Fix TLS stripping vulnerability in smtplib, CVE-2016-0772. Reported by Team -Oststrom. - -.. - .. bpo: 21386 .. date: 9314 .. nonce: DjV72U @@ -294,18 +306,6 @@ build information. .. -.. bpo: 26839 -.. date: 9303 -.. nonce: yVvy7R -.. original section: Library -.. section: Security - -On Linux, :func:`os.urandom` now calls ``getrandom()`` with -``GRND_NONBLOCK`` to fall back on reading ``/dev/urandom`` if the urandom -entropy pool is not initialized yet. Patch written by Colm Buckley. - -.. - .. bpo: 23883 .. date: 9302 .. nonce: tsZUiM @@ -735,6 +735,16 @@ default when used interactively. .. +.. bpo: 17500 +.. date: 9257 +.. nonce: QTZbRV +.. section: Windows + +Remove unused and outdated icons. (See also: +https://github.com/python/pythondotorg/issues/945) + +.. + .. bpo: 27229 .. date: 9259 .. nonce: C2NDch @@ -755,16 +765,6 @@ Update OS X 10.5+ 32-bit-only installer to build and link with OpenSSL .. -.. bpo: 17500 -.. date: 9257 -.. nonce: QTZbRV -.. section: Windows - -Remove unused and outdated icons. (See also: -https://github.com/python/pythondotorg/issues/945) - -.. - .. bpo: 27186 .. date: 9256 .. nonce: Ll8R-t diff --git a/Misc/NEWS.d/3.6.0a3.rst b/Misc/NEWS.d/3.6.0a3.rst index 4b0000b0e79..62892b59ded 100644 --- a/Misc/NEWS.d/3.6.0a3.rst +++ b/Misc/NEWS.d/3.6.0a3.rst @@ -1,7 +1,29 @@ +.. release date: 2016-07-11 +.. bpo: 27278 +.. date: 9361 +.. nonce: y_HkGw +.. original section: Library +.. section: Security + +Fix os.urandom() implementation using getrandom() on Linux. Truncate size +to INT_MAX and loop until we collected enough random bytes, instead of +casting a directly Py_ssize_t to int. + +.. + +.. bpo: 22636 +.. date: 9357 +.. nonce: 3fQW_g +.. original section: Library +.. section: Security + +Avoid shell injection problems with ctypes.util.find_library(). + +.. + .. bpo: 27473 .. date: 9385 .. nonce: _nOtTA -.. release date: 2016-07-11 .. section: Core and Builtins Fixed possible integer overflow in bytes and bytearray concatenations. @@ -248,18 +270,6 @@ issue25782. .. -.. bpo: 27278 -.. date: 9361 -.. nonce: y_HkGw -.. original section: Library -.. section: Security - -Fix os.urandom() implementation using getrandom() on Linux. Truncate size -to INT_MAX and loop until we collected enough random bytes, instead of -casting a directly Py_ssize_t to int. - -.. - .. bpo: 16864 .. date: 9360 .. nonce: W7tJDa @@ -289,16 +299,6 @@ env var PAGER). .. -.. bpo: 22636 -.. date: 9357 -.. nonce: 3fQW_g -.. original section: Library -.. section: Security - -Avoid shell injection problems with ctypes.util.find_library(). - -.. - .. bpo: 16182 .. date: 9356 .. nonce: RgFXyr diff --git a/Misc/NEWS.d/3.6.0b2.rst b/Misc/NEWS.d/3.6.0b2.rst index 627465e887b..9413c6e0191 100644 --- a/Misc/NEWS.d/3.6.0b2.rst +++ b/Misc/NEWS.d/3.6.0b2.rst @@ -460,7 +460,7 @@ In the traceback module, restore the formatting of exception messages like .. nonce: 3UhyPo .. section: Library -Allow falsy values to be used for msg parameter of subTest(). +Allow false values to be used for msg parameter of subTest(). .. diff --git a/Misc/NEWS.d/3.6.2rc1.rst b/Misc/NEWS.d/3.6.2rc1.rst index 20cabb05fa3..cdf4c3d541c 100644 --- a/Misc/NEWS.d/3.6.2rc1.rst +++ b/Misc/NEWS.d/3.6.2rc1.rst @@ -1,7 +1,19 @@ +.. release date: 2017-06-17 +.. bpo: 29591 +.. date: 9966 +.. nonce: ExKblw +.. original section: Library +.. section: Security + +Update expat copy from 2.1.1 to 2.2.0 to get fixes of CVE-2016-0718 and +CVE-2016-4472. See https://sourceforge.net/p/expat/bugs/537/ for more +information. + +.. + .. bpo: 30682 .. date: 9989 .. nonce: zZm88E -.. release date: 2017-06-17 .. section: Core and Builtins Removed a too-strict assertion that failed for certain f-strings, such as @@ -224,18 +236,6 @@ with misplaced inline modifier. Patch by Roy Williams. .. -.. bpo: 29591 -.. date: 9966 -.. nonce: ExKblw -.. original section: Library -.. section: Security - -Update expat copy from 2.1.1 to 2.2.0 to get fixes of CVE-2016-0718 and -CVE-2016-4472. See https://sourceforge.net/p/expat/bugs/537/ for more -information. - -.. - .. bpo: 24484 .. date: 9965 .. nonce: fNS32j diff --git a/Misc/NEWS.d/3.7.0a1.rst b/Misc/NEWS.d/3.7.0a1.rst index 244bb37e7c6..9bada1b76be 100644 --- a/Misc/NEWS.d/3.7.0a1.rst +++ b/Misc/NEWS.d/3.7.0a1.rst @@ -3149,7 +3149,7 @@ they are finished in multiprocessing.Pool. .. section: Library The mode argument of os.makedirs() no longer affects the file permission -bits of newly-created intermediate-level directories. +bits of newly created intermediate-level directories. .. @@ -4453,7 +4453,7 @@ In the traceback module, restore the formatting of exception messages like .. nonce: 3UhyPo .. section: Library -Allow falsy values to be used for msg parameter of subTest(). +Allow false values to be used for msg parameter of subTest(). .. diff --git a/Misc/NEWS.d/3.7.0a3.rst b/Misc/NEWS.d/3.7.0a3.rst index 067720efa51..6576c1fadbf 100644 --- a/Misc/NEWS.d/3.7.0a3.rst +++ b/Misc/NEWS.d/3.7.0a3.rst @@ -288,7 +288,7 @@ by Nir Soffer. .. -.. bpo: 321010 +.. bpo: 32101 .. date: 2017-11-29-00-42-47 .. nonce: -axD5l .. section: Library diff --git a/Misc/NEWS.d/3.8.0a1.rst b/Misc/NEWS.d/3.8.0a1.rst index 5cd3fa32105..991bbc12867 100644 --- a/Misc/NEWS.d/3.8.0a1.rst +++ b/Misc/NEWS.d/3.8.0a1.rst @@ -17,7 +17,7 @@ malicious or buggy certificate can result into segfault. Vulnerability .. section: Security The :option:`-I` command line option (run Python in isolated mode) is now -also copied by the :mod:`multiprocessing` and :mod:`distutils` modules when +also copied by the :mod:`multiprocessing` and ``distutils`` modules when spawning child processes. Previously, only :option:`-E` and :option:`-s` options (enabled by :option:`-I`) were copied. @@ -361,7 +361,7 @@ the "n" formatter. .. nonce: gjm1LO .. section: Core and Builtins -Fix a possible segfault involving a newly-created coroutine. Patch by +Fix a possible segfault involving a newly created coroutine. Patch by Zackery Spytz. .. @@ -2270,7 +2270,7 @@ last release was in 2000. Mac OS 9 last release was in 2001. .. nonce: laV_IE .. section: Library -:func:`~distutils.utils.check_environ` of :mod:`distutils.utils` now catches +:func:`~distutils.utils.check_environ` of ``distutils.utils`` now catches :exc:`KeyError` on calling :func:`pwd.getpwuid`: don't create the ``HOME`` environment variable in this case. @@ -3070,7 +3070,7 @@ Add deprecation warning when `loop` is used in methods: `asyncio.sleep`, .. nonce: Pr3-iG .. section: Library -ZIP files created by :mod:`distutils` will now include entries for +ZIP files created by ``distutils`` will now include entries for directories. .. @@ -3720,7 +3720,7 @@ Deprecate passing non-ThreadPoolExecutor instances to .. section: Library Restore ``msilib.Win64`` to preserve backwards compatibility since it's -already used by :mod:`distutils`' ``bdist_msi`` command. +already used by ``distutils``' ``bdist_msi`` command. .. @@ -4617,7 +4617,7 @@ Based on patch by c-fos. .. section: Library Remove HMAC default to md5 marked for removal in 3.8 (removal originally -planned in 3.6, bump to 3.8 in gh-7062). +planned in 3.6, bump to 3.8 in PR 7062). .. diff --git a/Misc/NEWS.d/3.8.0a2.rst b/Misc/NEWS.d/3.8.0a2.rst index 1c0abab4c47..223126145c7 100644 --- a/Misc/NEWS.d/3.8.0a2.rst +++ b/Misc/NEWS.d/3.8.0a2.rst @@ -356,7 +356,7 @@ Add *headers* optional keyword-only parameter to .. section: Library Fix C implementation of pickle.loads to use importlib's locking mechanisms, -and thereby avoid using partially-loaded modules. Patch by Tim Burgess. +and thereby avoid using partially loaded modules. Patch by Tim Burgess. .. diff --git a/Misc/NEWS.d/3.8.0a4.rst b/Misc/NEWS.d/3.8.0a4.rst index fc952fa9dcc..9841195210c 100644 --- a/Misc/NEWS.d/3.8.0a4.rst +++ b/Misc/NEWS.d/3.8.0a4.rst @@ -338,7 +338,7 @@ unexpected cache miss. .. nonce: MW1TLt .. section: Library -Fix :mod:`distutils.sysconfig` if :data:`sys.executable` is ``None`` or an +Fix ``distutils.sysconfig`` if :data:`sys.executable` is ``None`` or an empty string: use :func:`os.getcwd` to initialize ``project_base``. Fix also the distutils build command: don't use :data:`sys.executable` if it is ``None`` or an empty string. @@ -350,7 +350,7 @@ also the distutils build command: don't use :data:`sys.executable` if it is .. nonce: Fg4EXb .. section: Library -:func:`shutil.which` and :func:`distutils.spawn.find_executable` now use +:func:`shutil.which` and ``distutils.spawn.find_executable`` now use ``os.confstr("CS_PATH")`` if available instead of :data:`os.defpath`, if the ``PATH`` environment variable is not set. Moreover, don't use ``os.confstr("CS_PATH")`` nor :data:`os.defpath` if the ``PATH`` environment @@ -1354,7 +1354,7 @@ the function is called twice. .. nonce: pz-DIR .. section: C API -:c:macro:`PyDoc_VAR(name)` and :c:macro:`PyDoc_STRVAR(name,str)` now create +:c:expr:`PyDoc_VAR(name)` and :c:expr:`PyDoc_STRVAR(name,str)` now create ``static const char name[]`` instead of ``static char name[]``. Patch by Inada Naoki. diff --git a/Misc/NEWS.d/3.9.0a1.rst b/Misc/NEWS.d/3.9.0a1.rst index a9b6694c133..63362058383 100644 --- a/Misc/NEWS.d/3.9.0a1.rst +++ b/Misc/NEWS.d/3.9.0a1.rst @@ -1335,7 +1335,7 @@ module on POSIX systems. .. nonce: 9TWMlz .. section: Library -Revert GH-15522, which introduces a regression in +Revert PR 15522, which introduces a regression in :meth:`mimetypes.guess_type` due to improper handling of filenames as urls. .. @@ -1510,7 +1510,7 @@ asynchronous magic methods on a MagicMock now return an AsyncMock. .. section: Library Update the *length* parameter of :func:`os.pread` to accept -:c:type:`Py_ssize_t` instead of :c:type:`int`. +:c:type:`Py_ssize_t` instead of :c:expr:`int`. .. @@ -5769,4 +5769,4 @@ Convert posixmodule.c statically allocated types ``DirEntryType`` and .. section: C API Use singular/plural noun in error message when instantiating an abstract -class with non-overriden abstract method(s). +class with non-overridden abstract method(s). diff --git a/Misc/NEWS.d/3.9.0a3.rst b/Misc/NEWS.d/3.9.0a3.rst index 77ccc7453c2..54b61ca3b77 100644 --- a/Misc/NEWS.d/3.9.0a3.rst +++ b/Misc/NEWS.d/3.9.0a3.rst @@ -805,8 +805,7 @@ event loop only if called from the main thread. .. section: Documentation Add an entry for ``__module__`` in the "function" & "method" sections of the -`inspect docs types and members table -`_ +:mod:`inspect` docs' :ref:`inspect-types` table. .. diff --git a/Misc/NEWS.d/3.9.0a5.rst b/Misc/NEWS.d/3.9.0a5.rst index 49a118ad7e4..25342d21d8f 100644 --- a/Misc/NEWS.d/3.9.0a5.rst +++ b/Misc/NEWS.d/3.9.0a5.rst @@ -623,7 +623,7 @@ connections. .. nonce: 5a822c .. section: Library -Reimplement :func:`distutils.spawn.spawn` function with the +Reimplement ``distutils.spawn.spawn`` function with the :mod:`subprocess` module. .. @@ -1022,7 +1022,7 @@ lock-related objects from :mod:`threading`) around 49-day uptime. .. nonce: MnHdYl .. section: Windows -:mod:`distutils` will no longer statically link :file:`vcruntime140.dll` +``distutils`` will no longer statically link :file:`vcruntime140.dll` when a redistributable version is unavailable. All future releases of CPython will include a copy of this DLL to ensure distributed extensions can continue to load. diff --git a/Misc/NEWS.d/3.9.0b1.rst b/Misc/NEWS.d/3.9.0b1.rst index 529be0eba58..a7f52f81a5c 100644 --- a/Misc/NEWS.d/3.9.0b1.rst +++ b/Misc/NEWS.d/3.9.0b1.rst @@ -191,7 +191,7 @@ internal subinterpreters module. .. section: Core and Builtins Improve performance of :c:func:`PyLong_FromDouble` for values that fit into -:c:type:`long`. +:c:expr:`long`. .. diff --git a/Misc/NEWS.d/next/Build/2021-11-03-00-19-50.bpo-45696.eKs46f.rst b/Misc/NEWS.d/next/Build/2021-11-03-00-19-50.bpo-45696.eKs46f.rst deleted file mode 100644 index 6f6996d9fad..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-03-00-19-50.bpo-45696.eKs46f.rst +++ /dev/null @@ -1 +0,0 @@ -Skip the marshal step for frozen modules by generating C code that produces a set of ready-to-use code objects. This speeds up startup time by another 10% or more. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Build/2021-11-05-15-09-49.bpo-45723.gfSxur.rst b/Misc/NEWS.d/next/Build/2021-11-05-15-09-49.bpo-45723.gfSxur.rst deleted file mode 100644 index bd6666aad34..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-05-15-09-49.bpo-45723.gfSxur.rst +++ /dev/null @@ -1,2 +0,0 @@ -configure.ac now uses custom helper macros and ``AC_CACHE_CHECK`` to -simplify and speed up configure runs. diff --git a/Misc/NEWS.d/next/Build/2021-11-05-20-56-29.bpo-45731.9SDnDf.rst b/Misc/NEWS.d/next/Build/2021-11-05-20-56-29.bpo-45731.9SDnDf.rst deleted file mode 100644 index 1e490fac6ee..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-05-20-56-29.bpo-45731.9SDnDf.rst +++ /dev/null @@ -1 +0,0 @@ -``configure --enable-loadable-sqlite-extensions`` is now handled by new ``PY_SQLITE_ENABLE_LOAD_EXTENSION`` macro instead of logic in setup.py. diff --git a/Misc/NEWS.d/next/Build/2021-11-07-10-36-12.bpo-45723.JNwKSG.rst b/Misc/NEWS.d/next/Build/2021-11-07-10-36-12.bpo-45723.JNwKSG.rst deleted file mode 100644 index 0e06560fcba..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-07-10-36-12.bpo-45723.JNwKSG.rst +++ /dev/null @@ -1 +0,0 @@ -``configure`` now prints a warning when pkg-config is missing. diff --git a/Misc/NEWS.d/next/Build/2021-11-07-10-45-40.bpo-45723.AreusF.rst b/Misc/NEWS.d/next/Build/2021-11-07-10-45-40.bpo-45723.AreusF.rst deleted file mode 100644 index 066465edb60..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-07-10-45-40.bpo-45723.AreusF.rst +++ /dev/null @@ -1,2 +0,0 @@ -``configure.ac`` is now compatible with autoconf 2.71. Deprecated checks -``STDC_HEADERS`` and ``AC_HEADER_TIME`` have been removed. diff --git a/Misc/NEWS.d/next/Build/2021-11-08-08-58-06.bpo-45743.fZ8CTi.rst b/Misc/NEWS.d/next/Build/2021-11-08-08-58-06.bpo-45743.fZ8CTi.rst deleted file mode 100644 index 7241bd96371..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-08-08-58-06.bpo-45743.fZ8CTi.rst +++ /dev/null @@ -1,2 +0,0 @@ -On macOS, the build system no longer passes ``search_paths_first`` to the -linker. The flag has been the default since Xcode 4 / macOS 10.6. diff --git a/Misc/NEWS.d/next/Build/2021-11-08-11-31-48.bpo-45747.AODmk_.rst b/Misc/NEWS.d/next/Build/2021-11-08-11-31-48.bpo-45747.AODmk_.rst deleted file mode 100644 index f60b83fd5af..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-08-11-31-48.bpo-45747.AODmk_.rst +++ /dev/null @@ -1 +0,0 @@ -gdbm and dbm build dependencies are now detected by ``configure``. diff --git a/Misc/NEWS.d/next/Build/2021-11-09-10-15-33.bpo-45763.gP-vrX.rst b/Misc/NEWS.d/next/Build/2021-11-09-10-15-33.bpo-45763.gP-vrX.rst deleted file mode 100644 index 1d09ae71256..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-09-10-15-33.bpo-45763.gP-vrX.rst +++ /dev/null @@ -1,2 +0,0 @@ -The build dependencies for :mod:`zlib`, :mod:`bz2`, and :mod:`lzma` are now -detected by ``configure``. diff --git a/Misc/NEWS.d/next/Build/2021-11-09-23-30-12.bpo-45774.Mwm3ZR.rst b/Misc/NEWS.d/next/Build/2021-11-09-23-30-12.bpo-45774.Mwm3ZR.rst deleted file mode 100644 index 09095ab2cf9..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-09-23-30-12.bpo-45774.Mwm3ZR.rst +++ /dev/null @@ -1,2 +0,0 @@ -The build dependencies for :mod:`sqlite3` are now detected by ``configure`` and -``pkg-config``. Patch by Erlend E. Aasland. diff --git a/Misc/NEWS.d/next/Build/2021-11-10-16-13-02.bpo-45723.B5gCB1.rst b/Misc/NEWS.d/next/Build/2021-11-10-16-13-02.bpo-45723.B5gCB1.rst deleted file mode 100644 index 49636183c2c..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-10-16-13-02.bpo-45723.B5gCB1.rst +++ /dev/null @@ -1,2 +0,0 @@ -:program:`configure` has a new option ``--with-pkg-config`` to disable or -require pkg-config. diff --git a/Misc/NEWS.d/next/Build/2021-11-13-10-18-22.bpo-45798.IraaTs.rst b/Misc/NEWS.d/next/Build/2021-11-13-10-18-22.bpo-45798.IraaTs.rst deleted file mode 100644 index 865d8a07f93..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-13-10-18-22.bpo-45798.IraaTs.rst +++ /dev/null @@ -1,2 +0,0 @@ -Settings for :mod:`decimal` internal C extension are now detected by -``configure``. The bundled ``libmpdec`` library is built in ``Makefile``. diff --git a/Misc/NEWS.d/next/Build/2021-11-13-16-40-05.bpo-45800.5Hz6nr.rst b/Misc/NEWS.d/next/Build/2021-11-13-16-40-05.bpo-45800.5Hz6nr.rst deleted file mode 100644 index 8da3fcaebd0..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-13-16-40-05.bpo-45800.5Hz6nr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Settings for :mod:`pyexpat` C extension are now detected by ``configure``. -The bundled ``expat`` library is built in ``Makefile``. diff --git a/Misc/NEWS.d/next/Build/2021-11-17-19-02-51.bpo-45573.GMNdun.rst b/Misc/NEWS.d/next/Build/2021-11-17-19-02-51.bpo-45573.GMNdun.rst deleted file mode 100644 index 688b22c3e48..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-17-19-02-51.bpo-45573.GMNdun.rst +++ /dev/null @@ -1,3 +0,0 @@ -``configure`` now uses a unified format to set state, compiler flags, and -linker flags in Makefile. The new macro ``PY_STDLIB_MOD`` sets three -variables that are consumed by ``Modules/Setup`` and ``setup.py``. diff --git a/Misc/NEWS.d/next/Build/2021-11-18-12-18-43.bpo-45573.xsMZzn.rst b/Misc/NEWS.d/next/Build/2021-11-18-12-18-43.bpo-45573.xsMZzn.rst deleted file mode 100644 index 5dac52e53a7..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-18-12-18-43.bpo-45573.xsMZzn.rst +++ /dev/null @@ -1,2 +0,0 @@ -``configure`` now creates ``Modules/Setup.stdlib`` with conditionally -enabled/disabled extension module lines. The file is not used, yet. diff --git a/Misc/NEWS.d/next/Build/2021-11-18-13-31-02.bpo-45573.LCjGB8.rst b/Misc/NEWS.d/next/Build/2021-11-18-13-31-02.bpo-45573.LCjGB8.rst deleted file mode 100644 index 5f388948fb5..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-18-13-31-02.bpo-45573.LCjGB8.rst +++ /dev/null @@ -1,2 +0,0 @@ -Mandatory core modules, that are required to bootstrap Python, are now in -``Modules/Setup.bootstrap``. diff --git a/Misc/NEWS.d/next/Build/2021-11-19-15-42-27.bpo-45723.vwIJWI.rst b/Misc/NEWS.d/next/Build/2021-11-19-15-42-27.bpo-45723.vwIJWI.rst deleted file mode 100644 index 51e7735d9ca..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-19-15-42-27.bpo-45723.vwIJWI.rst +++ /dev/null @@ -1,10 +0,0 @@ -Add ``autoconf`` helpers for saving and restoring environment variables: - -* ``SAVE_ENV``: Save ``$CFLAGS``, ``$LDFLAGS``, ``$LIBS``, and - ``$CPPFLAGS``. -* ``RESTORE_ENV``: Restore ``$CFLAGS``, ``$LDFLAGS``, ``$LIBS``, and - ``$CPPFLAGS``. -* ``WITH_SAVE_ENV([SCRIPT])``: Run ``SCRIPT`` wrapped with ``SAVE_ENV`` and - ``RESTORE_ENV``. - -Patch by Erlend E. Aasland. diff --git a/Misc/NEWS.d/next/Build/2021-11-19-17-57-57.bpo-45847.9phcpd.rst b/Misc/NEWS.d/next/Build/2021-11-19-17-57-57.bpo-45847.9phcpd.rst deleted file mode 100644 index 05bc9ccdb3a..00000000000 --- a/Misc/NEWS.d/next/Build/2021-11-19-17-57-57.bpo-45847.9phcpd.rst +++ /dev/null @@ -1 +0,0 @@ -Port builtin hashlib extensions to ``PY_STDLIB_MOD`` macro and ``addext()``. diff --git a/Misc/NEWS.d/next/Build/2022-10-25-11-53-55.gh-issue-98636.e0RPAr.rst b/Misc/NEWS.d/next/Build/2022-10-25-11-53-55.gh-issue-98636.e0RPAr.rst new file mode 100644 index 00000000000..26a7cc8acaf --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-10-25-11-53-55.gh-issue-98636.e0RPAr.rst @@ -0,0 +1,2 @@ +Fix a regression in detecting ``gdbm_compat`` library for the ``_gdbm`` +module build. diff --git a/Misc/NEWS.d/next/Build/2023-01-15-11-22-15.gh-issue-101060.0mYk9E.rst b/Misc/NEWS.d/next/Build/2023-01-15-11-22-15.gh-issue-101060.0mYk9E.rst new file mode 100644 index 00000000000..bebbf8c898d --- /dev/null +++ b/Misc/NEWS.d/next/Build/2023-01-15-11-22-15.gh-issue-101060.0mYk9E.rst @@ -0,0 +1,3 @@ +Conditionally add ``-fno-reorder-blocks-and-partition`` in configure. +Effectively fixes ``--enable-bolt`` when using Clang, as this appears to be +a GCC-only flag. diff --git a/Misc/NEWS.d/next/Build/2023-01-17-21-32-51.gh-issue-100340.i9zRGM.rst b/Misc/NEWS.d/next/Build/2023-01-17-21-32-51.gh-issue-100340.i9zRGM.rst new file mode 100644 index 00000000000..3a37f798dc6 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2023-01-17-21-32-51.gh-issue-100340.i9zRGM.rst @@ -0,0 +1,2 @@ +Allows -Wno-int-conversion for wasm-sdk 17 and onwards, thus enables +building WASI builds once against the latest sdk. diff --git a/Misc/NEWS.d/next/Build/2023-01-21-10-31-35.gh-issue-101152.xvM8pL.rst b/Misc/NEWS.d/next/Build/2023-01-21-10-31-35.gh-issue-101152.xvM8pL.rst new file mode 100644 index 00000000000..e35b6178aa4 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2023-01-21-10-31-35.gh-issue-101152.xvM8pL.rst @@ -0,0 +1,3 @@ +In accordance with :PEP:`699`, the ``ma_version_tag`` field in :c:type:`PyDictObject` +is deprecated for extension modules. Accessing this field will generate a compiler +warning at compile time. This field will be removed in Python 3.14. diff --git a/Misc/NEWS.d/next/Build/2023-01-26-19-02-11.gh-issue-77532.cXD8bg.rst b/Misc/NEWS.d/next/Build/2023-01-26-19-02-11.gh-issue-77532.cXD8bg.rst new file mode 100644 index 00000000000..5a746dca2e7 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2023-01-26-19-02-11.gh-issue-77532.cXD8bg.rst @@ -0,0 +1 @@ +Minor fixes to allow building with ``PlatformToolset=ClangCL`` on Windows. diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-10-12-18-22-44.bpo-45450.d9a-bX.rst b/Misc/NEWS.d/next/Core and Builtins/2021-10-12-18-22-44.bpo-45450.d9a-bX.rst deleted file mode 100644 index 78f825f2706..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-10-12-18-22-44.bpo-45450.d9a-bX.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve the syntax error message for parenthesized arguments. Patch by Pablo -Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-10-27-15-14-31.bpo-45636.K2X7QS.rst b/Misc/NEWS.d/next/Core and Builtins/2021-10-27-15-14-31.bpo-45636.K2X7QS.rst deleted file mode 100644 index ca687687e79..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-10-27-15-14-31.bpo-45636.K2X7QS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Replace all numeric ``BINARY_*`` and ``INPLACE_*`` instructions with a single -:opcode:`BINARY_OP` implementation. diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-10-27-21-00-49.bpo-45609.L1GKPX.rst b/Misc/NEWS.d/next/Core and Builtins/2021-10-27-21-00-49.bpo-45609.L1GKPX.rst deleted file mode 100644 index f7df7d4b90e..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-10-27-21-00-49.bpo-45609.L1GKPX.rst +++ /dev/null @@ -1 +0,0 @@ -Specialized the ``STORE_SUBSCR`` opcode using the PEP 659 machinery. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-11-09-12-19-22.bpo-45764.8RLhWL.rst b/Misc/NEWS.d/next/Core and Builtins/2021-11-09-12-19-22.bpo-45764.8RLhWL.rst deleted file mode 100644 index d30b6a4a0e8..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-11-09-12-19-22.bpo-45764.8RLhWL.rst +++ /dev/null @@ -1,9 +0,0 @@ -The parser now gives a better error message when leaving out the opening -parenthesis ``(`` after a ``def``-statement:: - - >>> def f: - File "", line 1 - def f: - ^ - SyntaxError: expected '(' - diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-11-09-13-01-35.bpo-45773.POU8A4.rst b/Misc/NEWS.d/next/Core and Builtins/2021-11-09-13-01-35.bpo-45773.POU8A4.rst deleted file mode 100644 index 2b9ba81be23..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-11-09-13-01-35.bpo-45773.POU8A4.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a compiler hang when attempting to optimize certain jump patterns. diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-11-11-17-14-21.bpo-45753.nEBFcC.rst b/Misc/NEWS.d/next/Core and Builtins/2021-11-11-17-14-21.bpo-45753.nEBFcC.rst deleted file mode 100644 index 327f00d6891..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-11-11-17-14-21.bpo-45753.nEBFcC.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make recursion checks a bit more efficient by tracking amount of calls left -before overflow. diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-11-11-19-11-57.bpo-45636.2fyIVm.rst b/Misc/NEWS.d/next/Core and Builtins/2021-11-11-19-11-57.bpo-45636.2fyIVm.rst deleted file mode 100644 index f705b41fd8c..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-11-11-19-11-57.bpo-45636.2fyIVm.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove an existing "fast path" for old-style string formatting, since -it no longer appears to have any measurable impact. diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-11-14-00-14-45.bpo-45738.e0cgKd.rst b/Misc/NEWS.d/next/Core and Builtins/2021-11-14-00-14-45.bpo-45738.e0cgKd.rst deleted file mode 100644 index b238034323c..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-11-14-00-14-45.bpo-45738.e0cgKd.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix computation of error location for invalid continuation characters in the -parser. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-11-15-12-08-27.bpo-42540.V2w107.rst b/Misc/NEWS.d/next/Core and Builtins/2021-11-15-12-08-27.bpo-42540.V2w107.rst deleted file mode 100644 index 91160598bd3..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-11-15-12-08-27.bpo-42540.V2w107.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix crash when :func:`os.fork` is called with an active non-default -memory allocator. diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-11-15-13-32-54.bpo-45636.RDlTdL.rst b/Misc/NEWS.d/next/Core and Builtins/2021-11-15-13-32-54.bpo-45636.RDlTdL.rst deleted file mode 100644 index 92b1b272f02..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-11-15-13-32-54.bpo-45636.RDlTdL.rst +++ /dev/null @@ -1,2 +0,0 @@ -Simplify the implementation of :opcode:`BINARY_OP` by indexing into an array -of function pointers (rather than switching on the oparg). diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-11-16-19-00-27.bpo-45820.2X6Psr.rst b/Misc/NEWS.d/next/Core and Builtins/2021-11-16-19-00-27.bpo-45820.2X6Psr.rst deleted file mode 100644 index c2ec3d690cd..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-11-16-19-00-27.bpo-45820.2X6Psr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a segfault when the parser fails without reading any input. Patch by -Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-11-16-19-41-04.bpo-45822.OT6ueS.rst b/Misc/NEWS.d/next/Core and Builtins/2021-11-16-19-41-04.bpo-45822.OT6ueS.rst deleted file mode 100644 index 1ac7a8becee..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-11-16-19-41-04.bpo-45822.OT6ueS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed a bug in the parser that was causing it to not respect :pep:`263` -coding cookies when no flags are provided. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-11-17-08-05-27.bpo-45826.OERoTm.rst b/Misc/NEWS.d/next/Core and Builtins/2021-11-17-08-05-27.bpo-45826.OERoTm.rst deleted file mode 100644 index f04373bf2fc..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-11-17-08-05-27.bpo-45826.OERoTm.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed a crash when calling ``.with_traceback(None)`` on ``NameError``. This occurs internally in ``unittest.TestCase.assertRaises()``. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-11-17-10-14-35.bpo-45829.5Cf6fY.rst b/Misc/NEWS.d/next/Core and Builtins/2021-11-17-10-14-35.bpo-45829.5Cf6fY.rst deleted file mode 100644 index ed8bfb99f85..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-11-17-10-14-35.bpo-45829.5Cf6fY.rst +++ /dev/null @@ -1,2 +0,0 @@ -Specialize :opcode:`BINARY_SUBSCR` for classes with a ``__getitem__`` method -implemented in Python diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-11-19-13-17-47.bpo-45709.H_t7ut.rst b/Misc/NEWS.d/next/Core and Builtins/2021-11-19-13-17-47.bpo-45709.H_t7ut.rst deleted file mode 100644 index e3b007048cd..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-11-19-13-17-47.bpo-45709.H_t7ut.rst +++ /dev/null @@ -1,2 +0,0 @@ -Restore behavior from 3.10 when tracing an exception raised within a with -statement. diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-11-19-22-57-42.bpo-45848.HgVBJ5.rst b/Misc/NEWS.d/next/Core and Builtins/2021-11-19-22-57-42.bpo-45848.HgVBJ5.rst deleted file mode 100644 index d9394c9c1f0..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-11-19-22-57-42.bpo-45848.HgVBJ5.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow the parser to obtain error lines directly from encoded files. Patch by -Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-11-20-02-25-06.bpo-45811.B-1Gsr.rst b/Misc/NEWS.d/next/Core and Builtins/2021-11-20-02-25-06.bpo-45811.B-1Gsr.rst deleted file mode 100644 index 4b314144081..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-11-20-02-25-06.bpo-45811.B-1Gsr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve the tokenizer errors when encountering invisible control characters -in the parser. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-01-03-14-33-23.gh-issue-100712.po6xyB.rst b/Misc/NEWS.d/next/Core and Builtins/2023-01-03-14-33-23.gh-issue-100712.po6xyB.rst new file mode 100644 index 00000000000..3ebee0dd2aa --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-01-03-14-33-23.gh-issue-100712.po6xyB.rst @@ -0,0 +1 @@ +Added option to build cpython with specialization disabled, by setting ``ENABLE_SPECIALIZATION=False`` in :mod:`opcode`, followed by ``make regen-all``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-01-03-20-59-20.gh-issue-100726.W9huFl.rst b/Misc/NEWS.d/next/Core and Builtins/2023-01-03-20-59-20.gh-issue-100726.W9huFl.rst new file mode 100644 index 00000000000..2c93098b347 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-01-03-20-59-20.gh-issue-100726.W9huFl.rst @@ -0,0 +1 @@ +Optimize construction of ``range`` object for medium size integers. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-01-06-09-22-21.gh-issue-91351.iq2vZ_.rst b/Misc/NEWS.d/next/Core and Builtins/2023-01-06-09-22-21.gh-issue-91351.iq2vZ_.rst new file mode 100644 index 00000000000..19de1f8d0fb --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-01-06-09-22-21.gh-issue-91351.iq2vZ_.rst @@ -0,0 +1,5 @@ +Fix a case where re-entrant imports could corrupt the import deadlock +detection code and cause a :exc:`KeyError` to be raised out of +:mod:`importlib/_bootstrap`. In addition to the straightforward cases, this +could also happen when garbage collection leads to a warning being emitted -- +as happens when it collects an open socket or file) diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-01-10-14-11-17.gh-issue-100892.qfBVYI.rst b/Misc/NEWS.d/next/Core and Builtins/2023-01-10-14-11-17.gh-issue-100892.qfBVYI.rst new file mode 100644 index 00000000000..f2576becc2f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-01-10-14-11-17.gh-issue-100892.qfBVYI.rst @@ -0,0 +1 @@ +Fix race while iterating over thread states in clearing :class:`threading.local`. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-01-10-16-59-33.gh-issue-100923.ypJAX-.rst b/Misc/NEWS.d/next/Core and Builtins/2023-01-10-16-59-33.gh-issue-100923.ypJAX-.rst new file mode 100644 index 00000000000..b6b3f1d0c58 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-01-10-16-59-33.gh-issue-100923.ypJAX-.rst @@ -0,0 +1,2 @@ +Remove the ``mask`` cache entry for the :opcode:`COMPARE_OP` instruction and +embed the mask into the oparg. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-01-11-22-52-19.gh-issue-100942.ontOy_.rst b/Misc/NEWS.d/next/Core and Builtins/2023-01-11-22-52-19.gh-issue-100942.ontOy_.rst new file mode 100644 index 00000000000..daccea255b1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-01-11-22-52-19.gh-issue-100942.ontOy_.rst @@ -0,0 +1,2 @@ +Fixed segfault in property.getter/setter/deleter that occurred when a property +subclass overrode the ``__new__`` method to return a non-property instance. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-01-12-13-46-49.gh-issue-100982.mJ234s.rst b/Misc/NEWS.d/next/Core and Builtins/2023-01-12-13-46-49.gh-issue-100982.mJ234s.rst new file mode 100644 index 00000000000..4f43e783cd6 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-01-12-13-46-49.gh-issue-100982.mJ234s.rst @@ -0,0 +1,4 @@ +Adds a new :opcode:`COMPARE_AND_BRANCH` instruction. This is a bit more +efficient when performing a comparison immediately followed by a branch, and +restores the design intent of PEP 659 that specializations are local to a +single instruction. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-01-13-12-56-20.gh-issue-100762.YvHaQJ.rst b/Misc/NEWS.d/next/Core and Builtins/2023-01-13-12-56-20.gh-issue-100762.YvHaQJ.rst new file mode 100644 index 00000000000..2f6b121439a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-01-13-12-56-20.gh-issue-100762.YvHaQJ.rst @@ -0,0 +1,3 @@ +Record the (virtual) exception block depth in the oparg of +:opcode:`YIELD_VALUE`. Use this to avoid the expensive ``throw()`` when +closing generators (and coroutines) that can be closed trivially. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-01-14-17-03-08.gh-issue-101037.9ATNuf.rst b/Misc/NEWS.d/next/Core and Builtins/2023-01-14-17-03-08.gh-issue-101037.9ATNuf.rst new file mode 100644 index 00000000000..a48756657a2 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-01-14-17-03-08.gh-issue-101037.9ATNuf.rst @@ -0,0 +1,2 @@ +Fix potential memory underallocation issue for instances of :class:`int` +subclasses with value zero. diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-01-15-03-26-04.gh-issue-101046.g2CM4S.rst b/Misc/NEWS.d/next/Core and Builtins/2023-01-15-03-26-04.gh-issue-101046.g2CM4S.rst new file mode 100644 index 00000000000..f600473620f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-01-15-03-26-04.gh-issue-101046.g2CM4S.rst @@ -0,0 +1,2 @@ +Fix a possible memory leak in the parser when raising :exc:`MemoryError`. +Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Documentation/2021-06-21-17-51-51.bpo-25381.7Kn-_H.rst b/Misc/NEWS.d/next/Documentation/2021-06-21-17-51-51.bpo-25381.7Kn-_H.rst deleted file mode 100644 index f009f880e91..00000000000 --- a/Misc/NEWS.d/next/Documentation/2021-06-21-17-51-51.bpo-25381.7Kn-_H.rst +++ /dev/null @@ -1,2 +0,0 @@ -In the extending chapter of the extending doc, update a paragraph about the -global variables containing exception information. diff --git a/Misc/NEWS.d/next/Documentation/2021-10-22-12-09-18.bpo-45250.Iit5-Y.rst b/Misc/NEWS.d/next/Documentation/2021-10-22-12-09-18.bpo-45250.Iit5-Y.rst deleted file mode 100644 index 0c2bf18b200..00000000000 --- a/Misc/NEWS.d/next/Documentation/2021-10-22-12-09-18.bpo-45250.Iit5-Y.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update the documentation to note that CPython does not consistently -require iterators to define ``__iter__``. diff --git a/Misc/NEWS.d/next/Documentation/2021-11-06-10-54-17.bpo-45392.JZnVOz.rst b/Misc/NEWS.d/next/Documentation/2021-11-06-10-54-17.bpo-45392.JZnVOz.rst deleted file mode 100644 index 09c16578ff4..00000000000 --- a/Misc/NEWS.d/next/Documentation/2021-11-06-10-54-17.bpo-45392.JZnVOz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update the docstring of the :class:`type` built-in to remove a redundant -line and to mention keyword arguments for the constructor. diff --git a/Misc/NEWS.d/next/Documentation/2021-11-09-13-10-55.bpo-45772.EdrM3t.rst b/Misc/NEWS.d/next/Documentation/2021-11-09-13-10-55.bpo-45772.EdrM3t.rst deleted file mode 100644 index 47679521df3..00000000000 --- a/Misc/NEWS.d/next/Documentation/2021-11-09-13-10-55.bpo-45772.EdrM3t.rst +++ /dev/null @@ -1 +0,0 @@ -``socket.socket`` documentation is corrected to a class from a function. diff --git a/Misc/NEWS.d/next/Documentation/2021-11-18-00-07-40.bpo-45788.qibUoB.rst b/Misc/NEWS.d/next/Documentation/2021-11-18-00-07-40.bpo-45788.qibUoB.rst deleted file mode 100644 index 8aa3293673e..00000000000 --- a/Misc/NEWS.d/next/Documentation/2021-11-18-00-07-40.bpo-45788.qibUoB.rst +++ /dev/null @@ -1 +0,0 @@ -Link doc for sys.prefix to sysconfig doc on installation paths. diff --git a/Misc/NEWS.d/next/Documentation/2021-11-18-16-44-12.bpo-45640.lSpc2A.rst b/Misc/NEWS.d/next/Documentation/2021-11-18-16-44-12.bpo-45640.lSpc2A.rst deleted file mode 100644 index 532288df7c7..00000000000 --- a/Misc/NEWS.d/next/Documentation/2021-11-18-16-44-12.bpo-45640.lSpc2A.rst +++ /dev/null @@ -1,3 +0,0 @@ -Properly marked-up grammar tokens in the documentation are now clickable and -take you to the definition of a given piece of grammar. Patch by Arthur -Milchior. diff --git a/Misc/NEWS.d/next/Documentation/2022-06-19-22-04-47.gh-issue-88324.GHhSQ1.rst b/Misc/NEWS.d/next/Documentation/2022-06-19-22-04-47.gh-issue-88324.GHhSQ1.rst new file mode 100644 index 00000000000..6c8d192daa7 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-06-19-22-04-47.gh-issue-88324.GHhSQ1.rst @@ -0,0 +1,3 @@ +Reword :mod:`subprocess` to emphasize default behavior of *stdin*, *stdout*, +and *stderr* arguments. Remove inaccurate statement about child file handle +inheritance. diff --git a/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst b/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst new file mode 100644 index 00000000000..010d775a0d9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-04-18-17-45-03.bpo-29847.Uxtbq0.rst @@ -0,0 +1 @@ +Fix a bug where :class:`pathlib.Path` accepted and ignored keyword arguments. Patch provided by Yurii Karabas. diff --git a/Misc/NEWS.d/next/Library/2020-11-10-17-46-12.bpo-42158.OhxAiH.rst b/Misc/NEWS.d/next/Library/2020-11-10-17-46-12.bpo-42158.OhxAiH.rst deleted file mode 100644 index a71b481219e..00000000000 --- a/Misc/NEWS.d/next/Library/2020-11-10-17-46-12.bpo-42158.OhxAiH.rst +++ /dev/null @@ -1 +0,0 @@ -Add MIME types for N-quads, N-triples, Notation3 and TriG to ``mimetypes``. diff --git a/Misc/NEWS.d/next/Library/2020-11-20-21-06-08.bpo-40077.M-iZq3.rst b/Misc/NEWS.d/next/Library/2020-11-20-21-06-08.bpo-40077.M-iZq3.rst new file mode 100644 index 00000000000..8a74477a4b3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-11-20-21-06-08.bpo-40077.M-iZq3.rst @@ -0,0 +1 @@ +Convert :mod:`elementtree` types to heap types. Patch by Erlend E. Aasland. diff --git a/Misc/NEWS.d/next/Library/2021-05-24-13-48-34.bpo-28806.PkNw5D.rst b/Misc/NEWS.d/next/Library/2021-05-24-13-48-34.bpo-28806.PkNw5D.rst deleted file mode 100644 index 7783845efbc..00000000000 --- a/Misc/NEWS.d/next/Library/2021-05-24-13-48-34.bpo-28806.PkNw5D.rst +++ /dev/null @@ -1 +0,0 @@ -Improve netrc library. netrc file no longer needs to contain all tokens. And if the login name is anonymous, security check is no longer need. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2021-07-26-13-33-37.bpo-44733.88LrP1.rst b/Misc/NEWS.d/next/Library/2021-07-26-13-33-37.bpo-44733.88LrP1.rst deleted file mode 100644 index 666b5f7d0a0..00000000000 --- a/Misc/NEWS.d/next/Library/2021-07-26-13-33-37.bpo-44733.88LrP1.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add ``max_tasks_per_child`` to :class:`concurrent.futures.ProcessPoolExecutor`. -This allows users to specify the maximum number of tasks a single process -should execute before the process needs to be restarted. diff --git a/Misc/NEWS.d/next/Library/2021-10-18-14-00-01.bpo-45507.lDotNV.rst b/Misc/NEWS.d/next/Library/2021-10-18-14-00-01.bpo-45507.lDotNV.rst deleted file mode 100644 index a69ccdaa7e2..00000000000 --- a/Misc/NEWS.d/next/Library/2021-10-18-14-00-01.bpo-45507.lDotNV.rst +++ /dev/null @@ -1 +0,0 @@ -Add tests for truncated/missing trailers in gzip.decompress implementation. diff --git a/Misc/NEWS.d/next/Library/2021-10-25-01-22-49.bpo-45429.VaEyN9.rst b/Misc/NEWS.d/next/Library/2021-10-25-01-22-49.bpo-45429.VaEyN9.rst deleted file mode 100644 index 0a274f1ef8a..00000000000 --- a/Misc/NEWS.d/next/Library/2021-10-25-01-22-49.bpo-45429.VaEyN9.rst +++ /dev/null @@ -1,2 +0,0 @@ -On Windows, :func:`time.sleep` now uses a waitable timer which supports -high-resolution timers. Patch by Dong-hee Na and Eryk Sun. diff --git a/Misc/NEWS.d/next/Library/2021-11-06-17-47-46.bpo-45644.ZMqHD_.rst b/Misc/NEWS.d/next/Library/2021-11-06-17-47-46.bpo-45644.ZMqHD_.rst deleted file mode 100644 index 2cf4eae02c4..00000000000 --- a/Misc/NEWS.d/next/Library/2021-11-06-17-47-46.bpo-45644.ZMqHD_.rst +++ /dev/null @@ -1,3 +0,0 @@ -In-place JSON file formatting using ``python3 -m json.tool infile infile`` -now works correctly, previously it left the file empty. Patch by Chris -Wesseling. diff --git a/Misc/NEWS.d/next/Library/2021-11-08-23-22-14.bpo-45757.MHZHt3.rst b/Misc/NEWS.d/next/Library/2021-11-08-23-22-14.bpo-45757.MHZHt3.rst deleted file mode 100644 index f25638cc68f..00000000000 --- a/Misc/NEWS.d/next/Library/2021-11-08-23-22-14.bpo-45757.MHZHt3.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bug where :mod:`dis` produced an incorrect oparg when :opcode:`EXTENDED_ARG` is followed by an opcode that does not use its argument. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2021-11-09-09-04-19.bpo-45765.JVobxK.rst b/Misc/NEWS.d/next/Library/2021-11-09-09-04-19.bpo-45765.JVobxK.rst deleted file mode 100644 index a1f4a1f7aa9..00000000000 --- a/Misc/NEWS.d/next/Library/2021-11-09-09-04-19.bpo-45765.JVobxK.rst +++ /dev/null @@ -1 +0,0 @@ -In importlib.metadata, fix distribution discovery for an empty path. diff --git a/Misc/NEWS.d/next/Library/2021-11-09-09-18-06.bpo-45766.dvbcMf.rst b/Misc/NEWS.d/next/Library/2021-11-09-09-18-06.bpo-45766.dvbcMf.rst deleted file mode 100644 index b2e9c7e2f04..00000000000 --- a/Misc/NEWS.d/next/Library/2021-11-09-09-18-06.bpo-45766.dvbcMf.rst +++ /dev/null @@ -1 +0,0 @@ -Added *proportional* option to :meth:`statistics.linear_regression`. diff --git a/Misc/NEWS.d/next/Library/2021-11-09-15-48-38.bpo-45754.c-JDto.rst b/Misc/NEWS.d/next/Library/2021-11-09-15-48-38.bpo-45754.c-JDto.rst deleted file mode 100644 index 196bfc9eb27..00000000000 --- a/Misc/NEWS.d/next/Library/2021-11-09-15-48-38.bpo-45754.c-JDto.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a regression in Python 3.11a1 and 3.11a2 where :mod:`sqlite3` -incorrectly would use ``SQLITE_LIMIT_LENGTH`` when checking SQL statement -lengths. Now, ``SQLITE_LIMIT_SQL_LENGTH`` is used. Patch by Erlend E. Aasland. diff --git a/Misc/NEWS.d/next/Library/2021-11-11-12-59-10.bpo-28533.68mMZa.rst b/Misc/NEWS.d/next/Library/2021-11-11-12-59-10.bpo-28533.68mMZa.rst deleted file mode 100644 index 49243815e31..00000000000 --- a/Misc/NEWS.d/next/Library/2021-11-11-12-59-10.bpo-28533.68mMZa.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove the ``asyncore`` and ``asynchat`` modules, deprecated in Python 3.6: -use the :mod:`asyncio` module instead. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2021-11-11-12-59-49.bpo-28533.LvIFCQ.rst b/Misc/NEWS.d/next/Library/2021-11-11-12-59-49.bpo-28533.LvIFCQ.rst deleted file mode 100644 index 67fb3686b1d..00000000000 --- a/Misc/NEWS.d/next/Library/2021-11-11-12-59-49.bpo-28533.LvIFCQ.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove the ``smtpd`` module, deprecated in Python 3.6: the `aiosmtpd -`__ module can be used instead, it is based -on asyncio. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2021-11-11-13-03-17.bpo-45235.8ZbkHa.rst b/Misc/NEWS.d/next/Library/2021-11-11-13-03-17.bpo-45235.8ZbkHa.rst deleted file mode 100644 index f73589ccc88..00000000000 --- a/Misc/NEWS.d/next/Library/2021-11-11-13-03-17.bpo-45235.8ZbkHa.rst +++ /dev/null @@ -1,3 +0,0 @@ -Reverted an argparse bugfix that caused regression in the handling of -default arguments for subparsers. This prevented leaf level arguments from -taking precedence over root level arguments. diff --git a/Misc/NEWS.d/next/Library/2021-11-17-19-25-37.bpo-45831.9-TojK.rst b/Misc/NEWS.d/next/Library/2021-11-17-19-25-37.bpo-45831.9-TojK.rst deleted file mode 100644 index 049449ff0a4..00000000000 --- a/Misc/NEWS.d/next/Library/2021-11-17-19-25-37.bpo-45831.9-TojK.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`faulthandler` can now write ASCII-only strings (like filenames and -function names) with a single write() syscall when dumping a traceback. It -reduces the risk of getting an unreadable dump when two threads or two -processes dump a traceback to the same file (like stderr) at the same time. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2021-11-18-13-13-19.bpo-45837.aGyr1I.rst b/Misc/NEWS.d/next/Library/2021-11-18-13-13-19.bpo-45837.aGyr1I.rst deleted file mode 100644 index 771465be597..00000000000 --- a/Misc/NEWS.d/next/Library/2021-11-18-13-13-19.bpo-45837.aGyr1I.rst +++ /dev/null @@ -1,9 +0,0 @@ -The :meth:`turtle.RawTurtle.settiltangle` is deprecated since Python 3.1, -it now emits a deprecation warning and will be removed in Python 3.13. - -Use :meth:`turtle.RawTurtle.tiltangle` instead. - -:meth:`turtle.RawTurtle.tiltangle` was earlier incorrectly marked as deprecated, -its docstring has been corrected. - -Patch by Hugo van Kemenade. diff --git a/Misc/NEWS.d/next/Library/2021-11-20-17-04-25.bpo-45803.wSgFOy.rst b/Misc/NEWS.d/next/Library/2021-11-20-17-04-25.bpo-45803.wSgFOy.rst deleted file mode 100644 index 77479d7db47..00000000000 --- a/Misc/NEWS.d/next/Library/2021-11-20-17-04-25.bpo-45803.wSgFOy.rst +++ /dev/null @@ -1 +0,0 @@ -Added missing kw_only parameter to dataclasses.make_dataclass(). diff --git a/Misc/NEWS.d/next/Library/2022-02-05-12-01-58.bpo-38941.8IhvyG.rst b/Misc/NEWS.d/next/Library/2022-02-05-12-01-58.bpo-38941.8IhvyG.rst new file mode 100644 index 00000000000..5f996042260 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-05-12-01-58.bpo-38941.8IhvyG.rst @@ -0,0 +1,4 @@ +The :mod:`xml.etree.ElementTree` module now emits :exc:`DeprecationWarning` +when testing the truth value of an :class:`xml.etree.ElementTree.Element`. +Before, the Python implementation emitted :exc:`FutureWarning`, and the C +implementation emitted nothing. diff --git a/Misc/NEWS.d/next/Library/2022-07-22-13-38-37.gh-issue-94518._ZP0cz.rst b/Misc/NEWS.d/next/Library/2022-07-22-13-38-37.gh-issue-94518._ZP0cz.rst new file mode 100644 index 00000000000..a9d6d69f7ef --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-07-22-13-38-37.gh-issue-94518._ZP0cz.rst @@ -0,0 +1,2 @@ +``_posixsubprocess`` now initializes all UID and GID variables using a +reserved ``-1`` value instead of a separate flag. Patch by Oleg Iarygin. diff --git a/Misc/NEWS.d/next/Library/2022-09-26-21-18-47.gh-issue-60580.0hBgde.rst b/Misc/NEWS.d/next/Library/2022-09-26-21-18-47.gh-issue-60580.0hBgde.rst new file mode 100644 index 00000000000..630e56cd2f7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-09-26-21-18-47.gh-issue-60580.0hBgde.rst @@ -0,0 +1,3 @@ +:data:`ctypes.wintypes.BYTE` definition changed from +:data:`~ctypes.c_byte` to :data:`~ctypes.c_ubyte` to match Windows +SDK. Patch by Anatoly Techtonik and Oleg Iarygin. diff --git a/Misc/NEWS.d/next/Library/2022-11-14-03-06-03.gh-issue-88597.EYJA-Q.rst b/Misc/NEWS.d/next/Library/2022-11-14-03-06-03.gh-issue-88597.EYJA-Q.rst new file mode 100644 index 00000000000..a98e1ab4d15 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-11-14-03-06-03.gh-issue-88597.EYJA-Q.rst @@ -0,0 +1 @@ +:mod:`uuid` now has a command line interface. Try ``python -m uuid -h``. diff --git a/Misc/NEWS.d/next/Library/2022-11-15-23-30-39.gh-issue-86682.gK9i1N.rst b/Misc/NEWS.d/next/Library/2022-11-15-23-30-39.gh-issue-86682.gK9i1N.rst new file mode 100644 index 00000000000..64ef42a9a1c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-11-15-23-30-39.gh-issue-86682.gK9i1N.rst @@ -0,0 +1,2 @@ +Ensure runtime-created collections have the correct module name using +the newly added (internal) :func:`sys._getframemodulename`. diff --git a/Misc/NEWS.d/next/Library/2022-11-24-21-52-31.gh-issue-99266.88GcV9.rst b/Misc/NEWS.d/next/Library/2022-11-24-21-52-31.gh-issue-99266.88GcV9.rst new file mode 100644 index 00000000000..97e9569e40a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-11-24-21-52-31.gh-issue-99266.88GcV9.rst @@ -0,0 +1 @@ +Preserve more detailed error messages in :mod:`ctypes`. diff --git a/Misc/NEWS.d/next/Library/2022-12-10-15-30-17.gh-issue-67790.P9YUZM.rst b/Misc/NEWS.d/next/Library/2022-12-10-15-30-17.gh-issue-67790.P9YUZM.rst new file mode 100644 index 00000000000..ba0db774f8b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-12-10-15-30-17.gh-issue-67790.P9YUZM.rst @@ -0,0 +1,2 @@ +Add float-style formatting support for :class:`fractions.Fraction` +instances. diff --git a/Misc/NEWS.d/next/Library/2022-12-11-14-38-59.gh-issue-99952.IYGLzr.rst b/Misc/NEWS.d/next/Library/2022-12-11-14-38-59.gh-issue-99952.IYGLzr.rst new file mode 100644 index 00000000000..09ec9612495 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-12-11-14-38-59.gh-issue-99952.IYGLzr.rst @@ -0,0 +1,2 @@ +Fix a reference undercounting issue in :class:`ctypes.Structure` with ``from_param()`` +results larger than a C pointer. diff --git a/Misc/NEWS.d/next/Library/2022-12-19-23-19-26.gh-issue-96290.qFjsi6.rst b/Misc/NEWS.d/next/Library/2022-12-19-23-19-26.gh-issue-96290.qFjsi6.rst new file mode 100644 index 00000000000..33f98602bd1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-12-19-23-19-26.gh-issue-96290.qFjsi6.rst @@ -0,0 +1,5 @@ +Fix handling of partial and invalid UNC drives in ``ntpath.splitdrive()``, and in +``ntpath.normpath()`` on non-Windows systems. Paths such as '\\server' and '\\' are now considered +by ``splitdrive()`` to contain only a drive, and consequently are not modified by ``normpath()`` on +non-Windows systems. The behaviour of ``normpath()`` on Windows systems is unaffected, as native +OS APIs are used. Patch by Eryk Sun, with contributions by Barney Gale. diff --git a/Misc/NEWS.d/next/Library/2022-12-21-17-49-50.gh-issue-100160.N0NHRj.rst b/Misc/NEWS.d/next/Library/2022-12-21-17-49-50.gh-issue-100160.N0NHRj.rst new file mode 100644 index 00000000000..d5cc785722d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-12-21-17-49-50.gh-issue-100160.N0NHRj.rst @@ -0,0 +1,3 @@ +Emit a deprecation warning in +:meth:`asyncio.DefaultEventLoopPolicy.get_event_loop` if there is no current +event loop set and it decides to create one. diff --git a/Misc/NEWS.d/next/Library/2023-01-04-14-42-59.gh-issue-100750.iFJs5Y.rst b/Misc/NEWS.d/next/Library/2023-01-04-14-42-59.gh-issue-100750.iFJs5Y.rst new file mode 100644 index 00000000000..be351532822 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-01-04-14-42-59.gh-issue-100750.iFJs5Y.rst @@ -0,0 +1 @@ +pass encoding kwarg to subprocess in platform diff --git a/Misc/NEWS.d/next/Library/2023-01-08-00-12-44.gh-issue-39615.gn4PhB.rst b/Misc/NEWS.d/next/Library/2023-01-08-00-12-44.gh-issue-39615.gn4PhB.rst new file mode 100644 index 00000000000..1d04cc2cd54 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-01-08-00-12-44.gh-issue-39615.gn4PhB.rst @@ -0,0 +1,3 @@ +:func:`warnings.warn` now has the ability to skip stack frames based on code +filename prefix rather than only a numeric ``stacklevel`` via the new +``skip_file_prefixes`` keyword argument. diff --git a/Misc/NEWS.d/next/Library/2023-01-12-01-18-13.gh-issue-100573.KDskqo.rst b/Misc/NEWS.d/next/Library/2023-01-12-01-18-13.gh-issue-100573.KDskqo.rst new file mode 100644 index 00000000000..97b95d18d1e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-01-12-01-18-13.gh-issue-100573.KDskqo.rst @@ -0,0 +1 @@ +Fix a Windows :mod:`asyncio` bug with named pipes where a client doing ``os.stat()`` on the pipe would cause an error in the server that disabled serving future requests. diff --git a/Misc/NEWS.d/next/Library/2023-01-12-21-22-20.gh-issue-101000.wz4Xgc.rst b/Misc/NEWS.d/next/Library/2023-01-12-21-22-20.gh-issue-101000.wz4Xgc.rst new file mode 100644 index 00000000000..2082361c41d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-01-12-21-22-20.gh-issue-101000.wz4Xgc.rst @@ -0,0 +1,3 @@ +Add :func:`os.path.splitroot()`, which splits a path into a 3-item tuple +``(drive, root, tail)``. This new function is used by :mod:`pathlib` to +improve the performance of path construction by up to a third. diff --git a/Misc/NEWS.d/next/Library/2023-01-14-12-58-21.gh-issue-101015.stWFid.rst b/Misc/NEWS.d/next/Library/2023-01-14-12-58-21.gh-issue-101015.stWFid.rst new file mode 100644 index 00000000000..b9d73ff9855 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-01-14-12-58-21.gh-issue-101015.stWFid.rst @@ -0,0 +1,2 @@ +Fix :func:`typing.get_type_hints` on ``'*tuple[...]'`` and ``*tuple[...]``. +It must not drop the ``Unpack`` part. diff --git a/Misc/NEWS.d/next/Library/2023-01-15-09-11-30.gh-issue-94518.jvxtxm.rst b/Misc/NEWS.d/next/Library/2023-01-15-09-11-30.gh-issue-94518.jvxtxm.rst new file mode 100644 index 00000000000..77563090464 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-01-15-09-11-30.gh-issue-94518.jvxtxm.rst @@ -0,0 +1,3 @@ +Group-related variables of ``_posixsubprocess`` module are renamed to +stress that supplimentary group affinity is added to a fork, not +replace the inherited ones. Patch by Oleg Iarygin. diff --git a/Misc/NEWS.d/next/Library/2023-01-16-10-42-58.gh-issue-89381.lM2WL0.rst b/Misc/NEWS.d/next/Library/2023-01-16-10-42-58.gh-issue-89381.lM2WL0.rst new file mode 100644 index 00000000000..7bffe7d226e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-01-16-10-42-58.gh-issue-89381.lM2WL0.rst @@ -0,0 +1 @@ +:func:`~math.log` and :func:`~cmath.log` support default base=None values. diff --git a/Misc/NEWS.d/next/Library/2023-01-18-17-58-50.gh-issue-101144.FHd8Un.rst b/Misc/NEWS.d/next/Library/2023-01-18-17-58-50.gh-issue-101144.FHd8Un.rst new file mode 100644 index 00000000000..29765225994 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-01-18-17-58-50.gh-issue-101144.FHd8Un.rst @@ -0,0 +1,4 @@ +Make :func:`zipfile.Path.open` and :func:`zipfile.Path.read_text` also accept +``encoding`` as a positional argument. This was the behavior in Python 3.9 and +earlier. 3.10 introduced a regression where supplying it as a positional +argument would lead to a :exc:`TypeError`. diff --git a/Misc/NEWS.d/next/Library/2023-01-20-10-46-59.gh-issue-101143.hJo8hu.rst b/Misc/NEWS.d/next/Library/2023-01-20-10-46-59.gh-issue-101143.hJo8hu.rst new file mode 100644 index 00000000000..d14b9e25a69 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-01-20-10-46-59.gh-issue-101143.hJo8hu.rst @@ -0,0 +1,2 @@ +Remove unused references to :class:`~asyncio.TimerHandle` in +``asyncio.base_events.BaseEventLoop._add_callback``. diff --git a/Misc/NEWS.d/next/Library/2023-01-21-16-50-22.gh-issue-100795.NPMZf7.rst b/Misc/NEWS.d/next/Library/2023-01-21-16-50-22.gh-issue-100795.NPMZf7.rst new file mode 100644 index 00000000000..4cb56ea0f0e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-01-21-16-50-22.gh-issue-100795.NPMZf7.rst @@ -0,0 +1,3 @@ +Avoid potential unexpected ``freeaddrinfo`` call (double free) in :mod:`socket` +when when a libc ``getaddrinfo()`` implementation leaves garbage in an output +pointer when returning an error. Original patch by Sergey G. Brester. diff --git a/Misc/NEWS.d/next/Library/2023-01-24-12-53-59.gh-issue-92123.jf6TO5.rst b/Misc/NEWS.d/next/Library/2023-01-24-12-53-59.gh-issue-92123.jf6TO5.rst new file mode 100644 index 00000000000..4b4443a55fd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-01-24-12-53-59.gh-issue-92123.jf6TO5.rst @@ -0,0 +1,2 @@ +Adapt the ``_elementtree`` extension module to multi-phase init (:pep:`489`). +Patches by Erlend E. Aasland. diff --git a/Misc/NEWS.d/next/Library/2023-01-25-18-07-20.gh-issue-101326.KL4SFv.rst b/Misc/NEWS.d/next/Library/2023-01-25-18-07-20.gh-issue-101326.KL4SFv.rst new file mode 100644 index 00000000000..54b69b94309 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-01-25-18-07-20.gh-issue-101326.KL4SFv.rst @@ -0,0 +1 @@ +Fix regression when passing ``None`` as second or third argument to ``FutureIter.throw``. diff --git a/Misc/NEWS.d/next/Tests/2021-10-31-10-58-45.bpo-45701.r0LAUL.rst b/Misc/NEWS.d/next/Tests/2021-10-31-10-58-45.bpo-45701.r0LAUL.rst deleted file mode 100644 index 89106cf0660..00000000000 --- a/Misc/NEWS.d/next/Tests/2021-10-31-10-58-45.bpo-45701.r0LAUL.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add tests with ``tuple`` type with :func:`functools.lru_cache` to -``test_functools``. diff --git a/Misc/NEWS.d/next/Tests/2021-11-10-12-01-28.bpo-45745.wX5B3K.rst b/Misc/NEWS.d/next/Tests/2021-11-10-12-01-28.bpo-45745.wX5B3K.rst deleted file mode 100644 index c3ef6800a03..00000000000 --- a/Misc/NEWS.d/next/Tests/2021-11-10-12-01-28.bpo-45745.wX5B3K.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove the ``--findleaks`` command line option of regrtest: use the -``--fail-env-changed`` option instead. Since Python 3.7, it was a deprecated -alias to the ``--fail-env-changed`` option. diff --git a/Misc/NEWS.d/next/Tests/2021-11-17-14-28-08.bpo-45835.Mgyhjx.rst b/Misc/NEWS.d/next/Tests/2021-11-17-14-28-08.bpo-45835.Mgyhjx.rst deleted file mode 100644 index 6a73b019590..00000000000 --- a/Misc/NEWS.d/next/Tests/2021-11-17-14-28-08.bpo-45835.Mgyhjx.rst +++ /dev/null @@ -1 +0,0 @@ -Fix race condition in test_queue tests with multiple "feeder" threads. diff --git a/Misc/NEWS.d/next/Windows/2021-11-05-01-05-46.bpo-45720.47Nc5I.rst b/Misc/NEWS.d/next/Windows/2021-11-05-01-05-46.bpo-45720.47Nc5I.rst deleted file mode 100644 index 315759b07e1..00000000000 --- a/Misc/NEWS.d/next/Windows/2021-11-05-01-05-46.bpo-45720.47Nc5I.rst +++ /dev/null @@ -1,3 +0,0 @@ -Internal reference to :file:`shlwapi.dll` was dropped to help improve -startup time. This DLL will no longer be loaded at the start of every Python -process. diff --git a/Misc/NEWS.d/next/Windows/2021-11-08-21-53-11.bpo-45732.idl5kx.rst b/Misc/NEWS.d/next/Windows/2021-11-08-21-53-11.bpo-45732.idl5kx.rst deleted file mode 100644 index 563bcd33a40..00000000000 --- a/Misc/NEWS.d/next/Windows/2021-11-08-21-53-11.bpo-45732.idl5kx.rst +++ /dev/null @@ -1 +0,0 @@ -Updates bundled Tcl/Tk to 8.6.12. diff --git a/Misc/NEWS.d/next/Windows/2023-01-11-14-42-11.gh-issue-100247.YfEmSz.rst b/Misc/NEWS.d/next/Windows/2023-01-11-14-42-11.gh-issue-100247.YfEmSz.rst new file mode 100644 index 00000000000..7bfcbd7ddec --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2023-01-11-14-42-11.gh-issue-100247.YfEmSz.rst @@ -0,0 +1,2 @@ +Restores support for the :file:`py.exe` launcher finding shebang commands in +its configuration file using the full command name. diff --git a/Misc/NEWS.d/next/Windows/2023-01-11-16-28-09.gh-issue-100320.2DU2it.rst b/Misc/NEWS.d/next/Windows/2023-01-11-16-28-09.gh-issue-100320.2DU2it.rst new file mode 100644 index 00000000000..c206fc8520a --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2023-01-11-16-28-09.gh-issue-100320.2DU2it.rst @@ -0,0 +1,3 @@ +Ensures the ``PythonPath`` registry key from an install is used when +launching from a different copy of Python that relies on an existing install +to provide a copy of its modules and standard library. diff --git a/Misc/NEWS.d/next/Windows/2023-01-17-18-17-58.gh-issue-82052.mWyysT.rst b/Misc/NEWS.d/next/Windows/2023-01-17-18-17-58.gh-issue-82052.mWyysT.rst new file mode 100644 index 00000000000..4f7ab200b85 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2023-01-17-18-17-58.gh-issue-82052.mWyysT.rst @@ -0,0 +1 @@ +Fixed an issue where writing more than 32K of Unicode output to the console screen in one go can result in mojibake. diff --git a/Misc/NEWS.d/next/Windows/2023-01-18-18-25-18.gh-issue-101135.HF9VlG.rst b/Misc/NEWS.d/next/Windows/2023-01-18-18-25-18.gh-issue-101135.HF9VlG.rst new file mode 100644 index 00000000000..2e6d6371340 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2023-01-18-18-25-18.gh-issue-101135.HF9VlG.rst @@ -0,0 +1,3 @@ +Restore ability to launch older 32-bit versions from the :file:`py.exe` +launcher when both 32-bit and 64-bit installs of the same version are +available. diff --git a/Misc/NEWS.d/next/Windows/2023-01-25-00-23-31.gh-issue-99834.WN41lc.rst b/Misc/NEWS.d/next/Windows/2023-01-25-00-23-31.gh-issue-99834.WN41lc.rst new file mode 100644 index 00000000000..d3894fa4ea3 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2023-01-25-00-23-31.gh-issue-99834.WN41lc.rst @@ -0,0 +1 @@ +Updates bundled copy of Tcl/Tk to 8.6.13.0 diff --git a/Misc/README b/Misc/README index 8e8acbc5b3c..e4dd2005411 100644 --- a/Misc/README +++ b/Misc/README @@ -16,7 +16,6 @@ Porting Mini-FAQ on porting to new platforms python-config.in Python script template for python-config python.man UNIX man page for the python interpreter python.pc.in Package configuration info template for pkg-config -python-wing*.wpr Wing IDE project file README The file you're reading now README.AIX Information about using Python on AIX README.coverity Information about running Coverity's Prevent on Python diff --git a/Misc/README.valgrind b/Misc/README.valgrind index b483b2ea60a..ee9bfdf859d 100644 --- a/Misc/README.valgrind +++ b/Misc/README.valgrind @@ -12,12 +12,9 @@ can be used to force the usage of the malloc() allocator of the C library. If you don't want to read about the details of using Valgrind, there are still two things you must do to suppress the warnings. First, you must use a suppressions file. One is supplied in -Misc/valgrind-python.supp. Second, you must do one of the following: - - * Uncomment Py_USING_MEMORY_DEBUGGER in Objects/obmalloc.c, - then rebuild Python - * Uncomment the lines in Misc/valgrind-python.supp that - suppress the warnings for PyObject_Free and PyObject_Realloc +Misc/valgrind-python.supp. Second, you must uncomment the lines in +Misc/valgrind-python.supp that suppress the warnings for PyObject_Free and +PyObject_Realloc. If you want to use Valgrind more effectively and catch even more memory leaks, you will need to configure python --without-pymalloc. diff --git a/Misc/SpecialBuilds.txt b/Misc/SpecialBuilds.txt index a7cee8098e9..5609928284d 100644 --- a/Misc/SpecialBuilds.txt +++ b/Misc/SpecialBuilds.txt @@ -94,7 +94,7 @@ Compile in support for Low Level TRACE-ing of the main interpreter loop. When this preprocessor symbol is defined, before PyEval_EvalFrame executes a frame's code it checks the frame's global namespace for a variable -"__ltrace__". If such a variable is found, mounds of information about what +"__lltrace__". If such a variable is found, mounds of information about what the interpreter is doing are sprayed to stdout, such as every opcode and opcode argument and values pushed onto and popped off the value stack. diff --git a/Misc/python-wing3.wpr b/Misc/python-wing3.wpr deleted file mode 100755 index abe789412d9..00000000000 --- a/Misc/python-wing3.wpr +++ /dev/null @@ -1,13 +0,0 @@ -#!wing -#!version=3.0 -################################################################## -# Wing IDE project file # -################################################################## -[project attributes] -proj.directory-list = [{'dirloc': loc('..'), - 'excludes': [u'Lib/__pycache__'], - 'filter': '*', - 'include_hidden': False, - 'recursive': True, - 'watch_for_changes': True}] -proj.file-type = 'shared' diff --git a/Misc/python-wing4.wpr b/Misc/python-wing4.wpr deleted file mode 100755 index 7adfdbdacf7..00000000000 --- a/Misc/python-wing4.wpr +++ /dev/null @@ -1,18 +0,0 @@ -#!wing -#!version=4.0 -################################################################## -# Wing IDE project file # -################################################################## -[project attributes] -proj.directory-list = [{'dirloc': loc('..'), - 'excludes': [u'.hg', - u'Lib/unittest/__pycache__', - u'Lib/unittest/test/__pycache__', - u'Lib/__pycache__', - u'build', - u'Doc/build'], - 'filter': '*', - 'include_hidden': False, - 'recursive': True, - 'watch_for_changes': True}] -proj.file-type = 'shared' diff --git a/Misc/python-wing5.wpr b/Misc/python-wing5.wpr deleted file mode 100755 index 0e1ae635438..00000000000 --- a/Misc/python-wing5.wpr +++ /dev/null @@ -1,18 +0,0 @@ -#!wing -#!version=5.0 -################################################################## -# Wing IDE project file # -################################################################## -[project attributes] -proj.directory-list = [{'dirloc': loc('..'), - 'excludes': [u'.hg', - u'Lib/unittest/__pycache__', - u'Lib/unittest/test/__pycache__', - u'Lib/__pycache__', - u'build', - u'Doc/build'], - 'filter': '*', - 'include_hidden': False, - 'recursive': True, - 'watch_for_changes': True}] -proj.file-type = 'shared' diff --git a/Misc/python.man b/Misc/python.man index 45a49271d4d..bf7cf767d16 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -43,6 +43,9 @@ python \- an interpreted, interactive, object-oriented programming language .B \-OO ] [ +.B \-P +] +[ .B \-s ] [ @@ -66,10 +69,10 @@ python \- an interpreted, interactive, object-oriented programming language .B \-x ] [ -[ .B \-X .I option ] +[ .B \-? ] .br @@ -81,6 +84,19 @@ python \- an interpreted, interactive, object-oriented programming language | .I never ] +.br + [ +.B \--help +] +[ +.B \--help-env +] +[ +.B \--help-xoptions +] +[ +.B \--help-all +] .br [ .B \-c @@ -146,6 +162,16 @@ the behavior of the interpreter. .B \-h ", " \-? ", "\-\-help Prints the usage for the interpreter executable and exits. .TP +.B "\-\-help\-env" +Prints help about Python-specific environment variables and exits. +.TP +.B "\-\-help\-xoptions" +Prints help about implementation-specific \fB\-X\fP options and exits. +.TP +.TP +.B "\-\-help\-all" +Prints complete usage information and exits. +.TP .B \-i When a script is passed as first argument or the \fB\-c\fP option is used, enter interactive mode after executing the script or the @@ -154,7 +180,7 @@ useful to inspect global variables or a stack trace when a script raises an exception. .TP .B \-I -Run Python in isolated mode. This also implies \fB\-E\fP and \fB\-s\fP. In +Run Python in isolated mode. This also implies \fB\-E\fP, \fB\-P\fP and \fB\-s\fP. In isolated mode sys.path contains neither the script's directory nor the user's site-packages directory. All PYTHON* environment variables are ignored, too. Further restrictions may be imposed to prevent the user from injecting @@ -177,6 +203,11 @@ adding .opt-1 before the .pyc extension. Do \fB-O\fP and also discard docstrings; change the filename for compiled (bytecode) files by adding .opt-2 before the .pyc extension. .TP +.B \-P +Don't automatically prepend a potentially unsafe path to \fBsys.path\fP such +as the current directory, the script's directory or an empty string. See also the +\fBPYTHONSAFEPATH\fP environment variable. +.TP .B \-q Do not print the version and copyright messages. These messages are also suppressed in non-interactive mode. @@ -279,7 +310,7 @@ a regular expression on the warning message. .TP .BI "\-X " option -Set implementation specific option. The following options are available: +Set implementation-specific option. The following options are available: -X faulthandler: enable faulthandler @@ -302,7 +333,8 @@ Set implementation specific option. The following options are available: more verbose than the default if the code is correct: new warnings are only emitted when an issue is detected. Effect of the developer mode: * Add default warning filter, as -W default - * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function + * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() + C function * Enable the faulthandler module to dump the Python traceback on a crash * Enable asyncio debug mode * Set the dev_mode attribute of sys.flags to True @@ -313,7 +345,23 @@ Set implementation specific option. The following options are available: otherwise activate automatically). See PYTHONUTF8 for more details -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the - given directory instead of to the code tree. + given directory instead of to the code tree. + + -X warn_default_encoding: enable opt-in EncodingWarning for 'encoding=None' + + -X no_debug_ranges: disable the inclusion of the tables mapping extra location + information (end line, start column offset and end column offset) to every + instruction in code objects. This is useful when smaller code objects and pyc + files are desired as well as suppressing the extra visual location indicators + when the interpreter displays tracebacks. + + -X frozen_modules=[on|off]: whether or not frozen modules should be used. + The default is "on" (or "off" if you are running a local build). + + -X int_max_str_digits=number: limit the size of int<->str conversions. + This helps avoid denial of service attacks when parsing untrusted data. + The default is sys.int_info.default_max_str_digits. 0 disables. + .TP .B \-x Skip the first line of the source. This is intended for a DOS @@ -398,6 +446,10 @@ needed for developing Python extensions and embedding the interpreter. .RE .SH ENVIRONMENT VARIABLES +.IP PYTHONSAFEPATH +If this is set to a non-empty string, don't automatically prepend a potentially +unsafe path to \fBsys.path\fP such as the current directory, the script's +directory or an empty string. See also the \fB\-P\fP option. .IP PYTHONHOME Change the location of the standard Python libraries. By default, the libraries are searched in ${prefix}/lib/python and @@ -483,6 +535,11 @@ values. The integer must be a decimal number in the range [0,4294967295]. Specifying the value 0 will disable hash randomization. +.IP PYTHONINTMAXSTRDIGITS +Limit the maximum digit characters in an int value +when converting from a string and when converting an int back to a str. +A value of 0 disables the limit. Conversions to or from bases 2, 4, 8, +16, and 32 are never limited. .IP PYTHONMALLOC Set the Python memory allocators and/or install debug hooks. The available memory allocators are @@ -548,9 +605,6 @@ can be set to the callable of your debugger of choice. Setting these variables only has an effect in a debug build of Python, that is, if Python was configured with the \fB\--with-pydebug\fP build option. -.IP PYTHONTHREADDEBUG -If this environment variable is set, Python will print threading debug info. -The feature is deprecated in Python 3.10 and will be removed in Python 3.12. .IP PYTHONDUMPREFS If this environment variable is set, Python will dump objects and reference counts still alive after shutting down the interpreter. diff --git a/Misc/rhel7/README.md b/Misc/rhel7/README.md new file mode 100644 index 00000000000..8642e7c678f --- /dev/null +++ b/Misc/rhel7/README.md @@ -0,0 +1,19 @@ +# pkg-config overrides for RHEL 7 and CentOS 7 + +RHEL 7 and CentOS 7 do not provide pkg-config `.pc` files for Tcl/Tk. The + OpenSSL 1.1.1 pkg-config file is named `openssl11.pc` and not picked up + by Python's `configure` script. + +To build Python with system Tcl/Tk libs and OpenSSL 1.1 package, first +install the developer packages and the `pkgconfig` package with `pkg-config` +command. + +```shell +sudo yum install pkgconfig 'tcl-devel >= 8.5.12' 'tk-devel >= 8.5.12' openssl11-devel +``` + +The run `configure` with `PKG_CONFIG_PATH` environment variable. + +```shell +PKG_CONFIG_PATH=Misc/rhel7 ./configure -C +``` diff --git a/Misc/rhel7/openssl.pc b/Misc/rhel7/openssl.pc new file mode 100644 index 00000000000..ffccd36cc30 --- /dev/null +++ b/Misc/rhel7/openssl.pc @@ -0,0 +1,3 @@ +Name: OpenSSL +Version: 1.1.1k +Requires: libssl11 libcrypto11 diff --git a/Misc/rhel7/tcl.pc b/Misc/rhel7/tcl.pc new file mode 100644 index 00000000000..922eb512640 --- /dev/null +++ b/Misc/rhel7/tcl.pc @@ -0,0 +1,4 @@ +Name: Tool Command Language +Version: 8.5.12 +Libs: -ltcl8.5 -ltclstub8.5 +# Libs.private: -ldl -lz -lpthread -lm diff --git a/Misc/rhel7/tk.pc b/Misc/rhel7/tk.pc new file mode 100644 index 00000000000..67cebb27f79 --- /dev/null +++ b/Misc/rhel7/tk.pc @@ -0,0 +1,5 @@ +Name: The Tk Toolkit +Version: 8.5.12 +Requires: tcl >= 8.5.12 +Libs: -ltk8.5 -ltkstub8.5 +# Libs.private: -lXft -lfontconfig -lfreetype -lfontconfig -lX11 diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml new file mode 100644 index 00000000000..c716f403d63 --- /dev/null +++ b/Misc/stable_abi.toml @@ -0,0 +1,2388 @@ +# This file lists the contents of the Limited API and Stable ABI. +# Please append new items at the end. + +# The syntax of this file is not fixed. +# It is designed to be read only by Tools/build/stable_abi.py, which can change +# without notice. + +# For the history of the stable ABI prior to this file, +# see the history of PC/python3dll.c and before that, PC/python3.def, +# and PC/pythonXYstub.def + + +# The current format is TOML. + +# There are these kinds of top-level "items": +# - struct: A C struct. See `struct_abi_kind` for how much of the struct is +# exposed. +# - function: A function that must be kept available (and exported, i.e. not +# converted to a macro). +# - const: A simple value, defined with `#define`. +# - macro: A preprocessor macro more complex than a simple `const` value. +# - data: An exported object, which must continue to be available but its exact +# value may change. +# - typedef: A C typedef which is used in other definitions in the limited API. +# Its size/layout/signature must not change. +# - feature_macro: Other items may be conditional on whether this macro +# is defined or not. + +# Each top-level item can have details defined for it: +# - added: The version in which the item was added to the stable ABI. +# - ifdef: The item is only available if the given feature_macro is defined. +# - abi_only: If present, the item is not part of the Limited API, but it *is* +# part of the stable ABI. The item will not show up in user-facing docs. +# Typically used for: +# - private functions called by public macros, e.g. _Py_BuildValue_SizeT +# - items that were part of the limited API in the past, and must remain part +# of the stable ABI. +# - a combination of the above (functions that were called by macros that +# were public in the past) +# - struct_abi_kind: for `struct`, defines how much of the struct is exposed: +# - 'full-abi': All of the struct is part of the ABI, including the size +# (users may define arrays of these structs). +# Typically used for initalization, rather than at runtime. +# - 'opaque': No members are part of the ABI, nor is the size. The Limited +# API only handles these via pointers. The C definition should be +# incomplete (opaque). +# - 'members': Only specific members are part of the stable ABI. +# The struct's size may change, so it can't be used in arrays. +# Do not add new structs of this kind without an extremely good reason. +# - members: For `struct` with struct_abi_kind = 'members', a list of the +# exposed members. +# - doc: for `feature_macro`, the blurb added in documentation +# - windows: for `feature_macro`, this macro is defined on Windows. +# (This info is used to generate the DLL manifest and needs to be available +# on all platforms.) + +# Removing items from this file is generally not allowed, and additions should +# be considered with that in mind. See the devguide for exact rules: +# https://devguide.python.org/c-api/#limited-api + +# User-facing docs are at: +# https://docs.python.org/3/c-api/stable.html#stable + + +# Feature macros for optional functionality: + +[feature_macro.MS_WINDOWS] + doc = 'on Windows' + windows = true +[feature_macro.HAVE_FORK] + doc = 'on platforms with fork()' +[feature_macro.USE_STACKCHECK] + doc = 'on platforms with USE_STACKCHECK' + windows = 'maybe' +[feature_macro.PY_HAVE_THREAD_NATIVE_ID] + doc = 'on platforms with native thread IDs' + windows = true +[feature_macro.Py_REF_DEBUG] + doc = 'when Python is compiled in debug mode (with Py_REF_DEBUG)' + windows = 'maybe' + + +# Mentioned in PEP 384: + +[struct.PyObject] + added = '3.2' + members = ['ob_refcnt', 'ob_type'] + struct_abi_kind = 'members' +[struct.PyVarObject] + added = '3.2' + members = ['ob_base', 'ob_size'] + struct_abi_kind = 'members' +[struct.PyMethodDef] + added = '3.2' + struct_abi_kind = 'full-abi' +[struct.PyMemberDef] + added = '3.2' # Before 3.12, PyMemberDef required #include "structmember.h" + struct_abi_kind = 'full-abi' +[struct.PyGetSetDef] + added = '3.2' + struct_abi_kind = 'full-abi' +[struct.PyModuleDef_Base] + added = '3.2' + struct_abi_kind = 'full-abi' +[struct.PyModuleDef] + added = '3.2' + struct_abi_kind = 'full-abi' +[struct.PyStructSequence_Field] + added = '3.2' + struct_abi_kind = 'full-abi' +[struct.PyStructSequence_Desc] + added = '3.2' + struct_abi_kind = 'full-abi' +[struct.PyType_Slot] + added = '3.2' + struct_abi_kind = 'full-abi' +[struct.PyType_Spec] + added = '3.2' + struct_abi_kind = 'full-abi' +[struct.PyThreadState] + added = '3.2' + struct_abi_kind = 'opaque' +[struct.PyInterpreterState] + added = '3.2' + struct_abi_kind = 'opaque' +[struct.PyFrameObject] + added = '3.2' + struct_abi_kind = 'opaque' +[struct.symtable] + added = '3.2' + struct_abi_kind = 'opaque' +[struct.PyWeakReference] + added = '3.2' + struct_abi_kind = 'opaque' +[struct.PyLongObject] + added = '3.2' + struct_abi_kind = 'opaque' +[struct.PyTypeObject] + added = '3.2' + struct_abi_kind = 'opaque' + +[function.PyType_FromSpec] + added = '3.2' + +[const.Py_tp_dealloc] + added = '3.2' +[const.Py_tp_getattr] + added = '3.2' +[const.Py_tp_setattr] + added = '3.2' +[const.Py_tp_repr] + added = '3.2' +[const.Py_tp_hash] + added = '3.2' +[const.Py_tp_call] + added = '3.2' +[const.Py_tp_str] + added = '3.2' +[const.Py_tp_getattro] + added = '3.2' +[const.Py_tp_setattro] + added = '3.2' +[const.Py_tp_doc] + added = '3.2' +[const.Py_tp_traverse] + added = '3.2' +[const.Py_tp_clear] + added = '3.2' +[const.Py_tp_richcompare] + added = '3.2' +[const.Py_tp_iter] + added = '3.2' +[const.Py_tp_iternext] + added = '3.2' +[const.Py_tp_methods] + added = '3.2' +[const.Py_tp_base] + added = '3.2' +[const.Py_tp_descr_get] + added = '3.2' +[const.Py_tp_descr_set] + added = '3.2' +[const.Py_tp_init] + added = '3.2' +[const.Py_tp_alloc] + added = '3.2' +[const.Py_tp_new] + added = '3.2' +[const.Py_tp_members] + added = '3.2' +[const.Py_tp_getset] + added = '3.2' +[const.Py_tp_free] + added = '3.2' +[const.Py_tp_is_gc] + added = '3.2' +[const.Py_tp_bases] + added = '3.2' +[const.Py_tp_del] + added = '3.2' +[const.Py_nb_add] + added = '3.2' +[const.Py_nb_subtract] + added = '3.2' +[const.Py_nb_multiply] + added = '3.2' +[const.Py_nb_remainder] + added = '3.2' +[const.Py_nb_divmod] + added = '3.2' +[const.Py_nb_power] + added = '3.2' +[const.Py_nb_negative] + added = '3.2' +[const.Py_nb_positive] + added = '3.2' +[const.Py_nb_absolute] + added = '3.2' +[const.Py_nb_bool] + added = '3.2' +[const.Py_nb_invert] + added = '3.2' +[const.Py_nb_lshift] + added = '3.2' +[const.Py_nb_rshift] + added = '3.2' +[const.Py_nb_and] + added = '3.2' +[const.Py_nb_xor] + added = '3.2' +[const.Py_nb_or] + added = '3.2' +[const.Py_nb_int] + added = '3.2' +[const.Py_nb_float] + added = '3.2' +[const.Py_nb_inplace_add] + added = '3.2' +[const.Py_nb_inplace_subtract] + added = '3.2' +[const.Py_nb_inplace_multiply] + added = '3.2' +[const.Py_nb_inplace_remainder] + added = '3.2' +[const.Py_nb_inplace_power] + added = '3.2' +[const.Py_nb_inplace_lshift] + added = '3.2' +[const.Py_nb_inplace_rshift] + added = '3.2' +[const.Py_nb_inplace_and] + added = '3.2' +[const.Py_nb_inplace_xor] + added = '3.2' +[const.Py_nb_inplace_or] + added = '3.2' +[const.Py_nb_floor_divide] + added = '3.2' +[const.Py_nb_true_divide] + added = '3.2' +[const.Py_nb_inplace_floor_divide] + added = '3.2' +[const.Py_nb_inplace_true_divide] + added = '3.2' +[const.Py_nb_index] + added = '3.2' +[const.Py_sq_length] + added = '3.2' +[const.Py_sq_concat] + added = '3.2' +[const.Py_sq_repeat] + added = '3.2' +[const.Py_sq_item] + added = '3.2' +[const.Py_sq_ass_item] + added = '3.2' +[const.Py_sq_contains] + added = '3.2' +[const.Py_sq_inplace_concat] + added = '3.2' +[const.Py_sq_inplace_repeat] + added = '3.2' +[const.Py_mp_length] + added = '3.2' +[const.Py_mp_subscript] + added = '3.2' +[const.Py_mp_ass_subscript] + added = '3.2' + +[typedef.Py_uintptr_t] + added = '3.2' +[typedef.Py_intptr_t] + added = '3.2' +[typedef.Py_ssize_t] + added = '3.2' +[typedef.unaryfunc] + added = '3.2' +[typedef.binaryfunc] + added = '3.2' +[typedef.ternaryfunc] + added = '3.2' +[typedef.inquiry] + added = '3.2' +[typedef.lenfunc] + added = '3.2' +[typedef.ssizeargfunc] + added = '3.2' +[typedef.ssizessizeargfunc] + added = '3.2' +[typedef.ssizeobjargproc] + added = '3.2' +[typedef.ssizessizeobjargproc] + added = '3.2' +[typedef.objobjargproc] + added = '3.2' +[typedef.objobjproc] + added = '3.2' +[typedef.visitproc] + added = '3.2' +[typedef.traverseproc] + added = '3.2' +[typedef.destructor] + added = '3.2' +[typedef.getattrfunc] + added = '3.2' +[typedef.getattrofunc] + added = '3.2' +[typedef.setattrfunc] + added = '3.2' +[typedef.setattrofunc] + added = '3.2' +[typedef.reprfunc] + added = '3.2' +[typedef.hashfunc] + added = '3.2' +[typedef.richcmpfunc] + added = '3.2' +[typedef.getiterfunc] + added = '3.2' +[typedef.iternextfunc] + added = '3.2' +[typedef.descrgetfunc] + added = '3.2' +[typedef.descrsetfunc] + added = '3.2' +[typedef.initproc] + added = '3.2' +[typedef.newfunc] + added = '3.2' +[typedef.allocfunc] + added = '3.2' +[typedef.PyCFunction] + added = '3.2' +[typedef.PyCFunctionWithKeywords] + added = '3.2' +[typedef.PyCapsule_Destructor] + added = '3.2' +[typedef.getter] + added = '3.2' +[typedef.setter] + added = '3.2' +[typedef.PyOS_sighandler_t] + added = '3.2' +[typedef.PyGILState_STATE] + added = '3.2' +[typedef.Py_UCS4] + added = '3.2' + +[macro.Py_BEGIN_ALLOW_THREADS] + added = '3.2' +[macro.Py_BLOCK_THREADS] + added = '3.2' +[macro.Py_UNBLOCK_THREADS] + added = '3.2' +[macro.Py_END_ALLOW_THREADS] + added = '3.2' + +# The following were added in PC/python3.def in the initial stable ABI commit, +# 4d0d471a8031de90a2b1ce99c4ac4780e60b3bc9, +# and later amendments in 3.2: +# 0d012f284be829c6217f60523db0e1671b7db9d9 +# c83bc3c1fbed14d27a5de3032e24d2cf006a7c4b + +[function.PyArg_Parse] + added = '3.2' +[function.PyArg_ParseTuple] + added = '3.2' +[function.PyArg_ParseTupleAndKeywords] + added = '3.2' +[function.PyArg_UnpackTuple] + added = '3.2' +[function.PyArg_VaParse] + added = '3.2' +[function.PyArg_VaParseTupleAndKeywords] + added = '3.2' +[function.PyArg_ValidateKeywordArguments] + added = '3.2' +[data.PyBaseObject_Type] + added = '3.2' +[function.PyBool_FromLong] + added = '3.2' +[data.PyBool_Type] + added = '3.2' +[data.PyByteArrayIter_Type] + added = '3.2' +[function.PyByteArray_AsString] + added = '3.2' +[function.PyByteArray_Concat] + added = '3.2' +[function.PyByteArray_FromObject] + added = '3.2' +[function.PyByteArray_FromStringAndSize] + added = '3.2' +[function.PyByteArray_Resize] + added = '3.2' +[function.PyByteArray_Size] + added = '3.2' +[data.PyByteArray_Type] + added = '3.2' +[data.PyBytesIter_Type] + added = '3.2' +[function.PyBytes_AsString] + added = '3.2' +[function.PyBytes_AsStringAndSize] + added = '3.2' +[function.PyBytes_Concat] + added = '3.2' +[function.PyBytes_ConcatAndDel] + added = '3.2' +[function.PyBytes_DecodeEscape] + added = '3.2' +[function.PyBytes_FromFormat] + added = '3.2' +[function.PyBytes_FromFormatV] + added = '3.2' +[function.PyBytes_FromObject] + added = '3.2' +[function.PyBytes_FromString] + added = '3.2' +[function.PyBytes_FromStringAndSize] + added = '3.2' +[function.PyBytes_Repr] + added = '3.2' +[function.PyBytes_Size] + added = '3.2' +[data.PyBytes_Type] + added = '3.2' +[function.PyCFunction_Call] + added = '3.2' +[function.PyCFunction_GetFlags] + added = '3.2' +[function.PyCFunction_GetFunction] + added = '3.2' +[function.PyCFunction_GetSelf] + added = '3.2' +[function.PyCFunction_NewEx] + added = '3.2' +[data.PyCFunction_Type] + added = '3.2' +[function.PyCallIter_New] + added = '3.2' +[data.PyCallIter_Type] + added = '3.2' +[function.PyCallable_Check] + added = '3.2' +[function.PyCapsule_GetContext] + added = '3.2' +[function.PyCapsule_GetDestructor] + added = '3.2' +[function.PyCapsule_GetName] + added = '3.2' +[function.PyCapsule_GetPointer] + added = '3.2' +[function.PyCapsule_Import] + added = '3.2' +[function.PyCapsule_IsValid] + added = '3.2' +[function.PyCapsule_New] + added = '3.2' +[function.PyCapsule_SetContext] + added = '3.2' +[function.PyCapsule_SetDestructor] + added = '3.2' +[function.PyCapsule_SetName] + added = '3.2' +[function.PyCapsule_SetPointer] + added = '3.2' +[data.PyCapsule_Type] + added = '3.2' +[data.PyClassMethodDescr_Type] + added = '3.2' +[function.PyCodec_BackslashReplaceErrors] + added = '3.2' +[function.PyCodec_Decode] + added = '3.2' +[function.PyCodec_Decoder] + added = '3.2' +[function.PyCodec_Encode] + added = '3.2' +[function.PyCodec_Encoder] + added = '3.2' +[function.PyCodec_IgnoreErrors] + added = '3.2' +[function.PyCodec_IncrementalDecoder] + added = '3.2' +[function.PyCodec_IncrementalEncoder] + added = '3.2' +[function.PyCodec_KnownEncoding] + added = '3.2' +[function.PyCodec_LookupError] + added = '3.2' +[function.PyCodec_Register] + added = '3.2' +[function.PyCodec_RegisterError] + added = '3.2' +[function.PyCodec_ReplaceErrors] + added = '3.2' +[function.PyCodec_StreamReader] + added = '3.2' +[function.PyCodec_StreamWriter] + added = '3.2' +[function.PyCodec_StrictErrors] + added = '3.2' +[function.PyCodec_XMLCharRefReplaceErrors] + added = '3.2' +[function.PyComplex_FromDoubles] + added = '3.2' +[function.PyComplex_ImagAsDouble] + added = '3.2' +[function.PyComplex_RealAsDouble] + added = '3.2' +[data.PyComplex_Type] + added = '3.2' +[function.PyDescr_NewClassMethod] + added = '3.2' +[function.PyDescr_NewGetSet] + added = '3.2' +[function.PyDescr_NewMember] + added = '3.2' +[function.PyDescr_NewMethod] + added = '3.2' +[data.PyDictItems_Type] + added = '3.2' +[data.PyDictIterItem_Type] + added = '3.2' +[data.PyDictIterKey_Type] + added = '3.2' +[data.PyDictIterValue_Type] + added = '3.2' +[data.PyDictKeys_Type] + added = '3.2' +[function.PyDictProxy_New] + added = '3.2' +[data.PyDictProxy_Type] + added = '3.2' +[data.PyDictValues_Type] + added = '3.2' +[function.PyDict_Clear] + added = '3.2' +[function.PyDict_Contains] + added = '3.2' +[function.PyDict_Copy] + added = '3.2' +[function.PyDict_DelItem] + added = '3.2' +[function.PyDict_DelItemString] + added = '3.2' +[function.PyDict_GetItem] + added = '3.2' +[function.PyDict_GetItemString] + added = '3.2' +[function.PyDict_GetItemWithError] + added = '3.2' +[function.PyDict_Items] + added = '3.2' +[function.PyDict_Keys] + added = '3.2' +[function.PyDict_Merge] + added = '3.2' +[function.PyDict_MergeFromSeq2] + added = '3.2' +[function.PyDict_New] + added = '3.2' +[function.PyDict_Next] + added = '3.2' +[function.PyDict_SetItem] + added = '3.2' +[function.PyDict_SetItemString] + added = '3.2' +[function.PyDict_Size] + added = '3.2' +[data.PyDict_Type] + added = '3.2' +[function.PyDict_Update] + added = '3.2' +[function.PyDict_Values] + added = '3.2' +[data.PyEllipsis_Type] + added = '3.2' +[data.PyEnum_Type] + added = '3.2' +[function.PyErr_BadArgument] + added = '3.2' +[function.PyErr_BadInternalCall] + added = '3.2' +[function.PyErr_CheckSignals] + added = '3.2' +[function.PyErr_Clear] + added = '3.2' +[function.PyErr_Display] + added = '3.2' +[function.PyErr_ExceptionMatches] + added = '3.2' +[function.PyErr_Fetch] + added = '3.2' +[function.PyErr_Format] + added = '3.2' +[function.PyErr_GivenExceptionMatches] + added = '3.2' +[function.PyErr_NewException] + added = '3.2' +[function.PyErr_NewExceptionWithDoc] + added = '3.2' +[function.PyErr_NoMemory] + added = '3.2' +[function.PyErr_NormalizeException] + added = '3.2' +[function.PyErr_Occurred] + added = '3.2' +[function.PyErr_Print] + added = '3.2' +[function.PyErr_PrintEx] + added = '3.2' +[function.PyErr_ProgramText] + added = '3.2' +[function.PyErr_Restore] + added = '3.2' +[function.PyErr_SetFromErrno] + added = '3.2' +[function.PyErr_SetFromErrnoWithFilename] + added = '3.2' +[function.PyErr_SetFromErrnoWithFilenameObject] + added = '3.2' +[function.PyErr_SetInterrupt] + added = '3.2' +[function.PyErr_SetNone] + added = '3.2' +[function.PyErr_SetObject] + added = '3.2' +[function.PyErr_SetString] + added = '3.2' +[function.PyErr_SyntaxLocation] + added = '3.2' +[function.PyErr_WarnEx] + added = '3.2' +[function.PyErr_WarnExplicit] + added = '3.2' +[function.PyErr_WarnFormat] + added = '3.2' +[function.PyErr_WriteUnraisable] + added = '3.2' +[function.PyEval_AcquireLock] + added = '3.2' +[function.PyEval_AcquireThread] + added = '3.2' +[function.PyEval_CallFunction] + added = '3.2' +[function.PyEval_CallMethod] + added = '3.2' +[function.PyEval_CallObjectWithKeywords] + added = '3.2' +[function.PyEval_EvalCode] + added = '3.2' +[function.PyEval_EvalCodeEx] + added = '3.2' +[function.PyEval_EvalFrame] + added = '3.2' +[function.PyEval_EvalFrameEx] + added = '3.2' +[function.PyEval_GetBuiltins] + added = '3.2' +[function.PyEval_GetFrame] + added = '3.2' +[function.PyEval_GetFuncDesc] + added = '3.2' +[function.PyEval_GetFuncName] + added = '3.2' +[function.PyEval_GetGlobals] + added = '3.2' +[function.PyEval_GetLocals] + added = '3.2' +[function.PyEval_InitThreads] + added = '3.2' +[function.PyEval_ReleaseLock] + added = '3.2' +[function.PyEval_ReleaseThread] + added = '3.2' +[function.PyEval_RestoreThread] + added = '3.2' +[function.PyEval_SaveThread] + added = '3.2' +[function.PyEval_ThreadsInitialized] + added = '3.2' +[data.PyExc_ArithmeticError] + added = '3.2' +[data.PyExc_AssertionError] + added = '3.2' +[data.PyExc_AttributeError] + added = '3.2' +[data.PyExc_BaseException] + added = '3.2' +[data.PyExc_BaseExceptionGroup] + added = '3.11' +[data.PyExc_BufferError] + added = '3.2' +[data.PyExc_BytesWarning] + added = '3.2' +[data.PyExc_DeprecationWarning] + added = '3.2' +[data.PyExc_EOFError] + added = '3.2' +[data.PyExc_EnvironmentError] + added = '3.2' +[data.PyExc_Exception] + added = '3.2' +[data.PyExc_FloatingPointError] + added = '3.2' +[data.PyExc_FutureWarning] + added = '3.2' +[data.PyExc_GeneratorExit] + added = '3.2' +[data.PyExc_IOError] + added = '3.2' +[data.PyExc_ImportError] + added = '3.2' +[data.PyExc_ImportWarning] + added = '3.2' +[data.PyExc_IndentationError] + added = '3.2' +[data.PyExc_IndexError] + added = '3.2' +[data.PyExc_KeyError] + added = '3.2' +[data.PyExc_KeyboardInterrupt] + added = '3.2' +[data.PyExc_LookupError] + added = '3.2' +[data.PyExc_MemoryError] + added = '3.2' +[data.PyExc_NameError] + added = '3.2' +[data.PyExc_NotImplementedError] + added = '3.2' +[data.PyExc_OSError] + added = '3.2' +[data.PyExc_OverflowError] + added = '3.2' +[data.PyExc_PendingDeprecationWarning] + added = '3.2' +[data.PyExc_ReferenceError] + added = '3.2' +[data.PyExc_RuntimeError] + added = '3.2' +[data.PyExc_RuntimeWarning] + added = '3.2' +[data.PyExc_StopIteration] + added = '3.2' +[data.PyExc_SyntaxError] + added = '3.2' +[data.PyExc_SyntaxWarning] + added = '3.2' +[data.PyExc_SystemError] + added = '3.2' +[data.PyExc_SystemExit] + added = '3.2' +[data.PyExc_TabError] + added = '3.2' +[data.PyExc_TypeError] + added = '3.2' +[data.PyExc_UnboundLocalError] + added = '3.2' +[data.PyExc_UnicodeDecodeError] + added = '3.2' +[data.PyExc_UnicodeEncodeError] + added = '3.2' +[data.PyExc_UnicodeError] + added = '3.2' +[data.PyExc_UnicodeTranslateError] + added = '3.2' +[data.PyExc_UnicodeWarning] + added = '3.2' +[data.PyExc_UserWarning] + added = '3.2' +[data.PyExc_ValueError] + added = '3.2' +[data.PyExc_Warning] + added = '3.2' +[data.PyExc_ZeroDivisionError] + added = '3.2' +[function.PyException_GetCause] + added = '3.2' +[function.PyException_GetContext] + added = '3.2' +[function.PyException_GetTraceback] + added = '3.2' +[function.PyException_SetCause] + added = '3.2' +[function.PyException_SetContext] + added = '3.2' +[function.PyException_SetTraceback] + added = '3.2' +[function.PyFile_FromFd] + added = '3.2' +[function.PyFile_GetLine] + added = '3.2' +[function.PyFile_WriteObject] + added = '3.2' +[function.PyFile_WriteString] + added = '3.2' +[data.PyFilter_Type] + added = '3.2' +[function.PyFloat_AsDouble] + added = '3.2' +[function.PyFloat_FromDouble] + added = '3.2' +[function.PyFloat_FromString] + added = '3.2' +[function.PyFloat_GetInfo] + added = '3.2' +[function.PyFloat_GetMax] + added = '3.2' +[function.PyFloat_GetMin] + added = '3.2' +[data.PyFloat_Type] + added = '3.2' +[function.PyFrozenSet_New] + added = '3.2' +[data.PyFrozenSet_Type] + added = '3.2' +[function.PyGC_Collect] + added = '3.2' +[function.PyGILState_Ensure] + added = '3.2' +[function.PyGILState_GetThisThreadState] + added = '3.2' +[function.PyGILState_Release] + added = '3.2' +[data.PyGetSetDescr_Type] + added = '3.2' +[function.PyImport_AddModule] + added = '3.2' +[function.PyImport_AppendInittab] + added = '3.2' +[function.PyImport_ExecCodeModule] + added = '3.2' +[function.PyImport_ExecCodeModuleEx] + added = '3.2' +[function.PyImport_ExecCodeModuleWithPathnames] + added = '3.2' +[function.PyImport_GetImporter] + added = '3.2' +[function.PyImport_GetMagicNumber] + added = '3.2' +[function.PyImport_GetMagicTag] + added = '3.2' +[function.PyImport_GetModuleDict] + added = '3.2' +[function.PyImport_Import] + added = '3.2' +[function.PyImport_ImportFrozenModule] + added = '3.2' +[function.PyImport_ImportModule] + added = '3.2' +[function.PyImport_ImportModuleLevel] + added = '3.2' +[function.PyImport_ImportModuleNoBlock] + added = '3.2' +[function.PyImport_ReloadModule] + added = '3.2' +[function.PyInterpreterState_Clear] + added = '3.2' +[function.PyInterpreterState_Delete] + added = '3.2' +[function.PyInterpreterState_New] + added = '3.2' +[function.PyIter_Next] + added = '3.2' +[data.PyListIter_Type] + added = '3.2' +[data.PyListRevIter_Type] + added = '3.2' +[function.PyList_Append] + added = '3.2' +[function.PyList_AsTuple] + added = '3.2' +[function.PyList_GetItem] + added = '3.2' +[function.PyList_GetSlice] + added = '3.2' +[function.PyList_Insert] + added = '3.2' +[function.PyList_New] + added = '3.2' +[function.PyList_Reverse] + added = '3.2' +[function.PyList_SetItem] + added = '3.2' +[function.PyList_SetSlice] + added = '3.2' +[function.PyList_Size] + added = '3.2' +[function.PyList_Sort] + added = '3.2' +[data.PyList_Type] + added = '3.2' +[data.PyLongRangeIter_Type] + added = '3.2' +[function.PyLong_AsDouble] + added = '3.2' +[function.PyLong_AsLong] + added = '3.2' +[function.PyLong_AsLongAndOverflow] + added = '3.2' +[function.PyLong_AsLongLong] + added = '3.2' +[function.PyLong_AsLongLongAndOverflow] + added = '3.2' +[function.PyLong_AsSize_t] + added = '3.2' +[function.PyLong_AsSsize_t] + added = '3.2' +[function.PyLong_AsUnsignedLong] + added = '3.2' +[function.PyLong_AsUnsignedLongLong] + added = '3.2' +[function.PyLong_AsUnsignedLongLongMask] + added = '3.2' +[function.PyLong_AsUnsignedLongMask] + added = '3.2' +[function.PyLong_AsVoidPtr] + added = '3.2' +[function.PyLong_FromDouble] + added = '3.2' +[function.PyLong_FromLong] + added = '3.2' +[function.PyLong_FromLongLong] + added = '3.2' +[function.PyLong_FromSize_t] + added = '3.2' +[function.PyLong_FromSsize_t] + added = '3.2' +[function.PyLong_FromString] + added = '3.2' +[function.PyLong_FromUnsignedLong] + added = '3.2' +[function.PyLong_FromUnsignedLongLong] + added = '3.2' +[function.PyLong_FromVoidPtr] + added = '3.2' +[function.PyLong_GetInfo] + added = '3.2' +[data.PyLong_Type] + added = '3.2' +[data.PyMap_Type] + added = '3.2' +[function.PyMapping_Check] + added = '3.2' +[function.PyMapping_GetItemString] + added = '3.2' +[function.PyMapping_HasKey] + added = '3.2' +[function.PyMapping_HasKeyString] + added = '3.2' +[function.PyMapping_Items] + added = '3.2' +[function.PyMapping_Keys] + added = '3.2' +[function.PyMapping_Length] + added = '3.2' +[function.PyMapping_SetItemString] + added = '3.2' +[function.PyMapping_Size] + added = '3.2' +[function.PyMapping_Values] + added = '3.2' +[function.PyMem_Free] + added = '3.2' +[function.PyMem_Malloc] + added = '3.2' +[function.PyMem_Realloc] + added = '3.2' +[data.PyMemberDescr_Type] + added = '3.2' +[function.PyMemoryView_FromObject] + added = '3.2' +[function.PyMemoryView_GetContiguous] + added = '3.2' +[data.PyMemoryView_Type] + added = '3.2' +[data.PyMethodDescr_Type] + added = '3.2' +[function.PyModule_AddIntConstant] + added = '3.2' +[function.PyModule_AddObject] + added = '3.2' +[function.PyModule_AddStringConstant] + added = '3.2' +[function.PyModule_Create2] + added = '3.2' +[function.PyModule_GetDef] + added = '3.2' +[function.PyModule_GetDict] + added = '3.2' +[function.PyModule_GetFilename] + added = '3.2' +[function.PyModule_GetFilenameObject] + added = '3.2' +[function.PyModule_GetName] + added = '3.2' +[function.PyModule_GetState] + added = '3.2' +[function.PyModule_New] + added = '3.2' +[data.PyModule_Type] + added = '3.2' +[function.PyNumber_Absolute] + added = '3.2' +[function.PyNumber_Add] + added = '3.2' +[function.PyNumber_And] + added = '3.2' +[function.PyNumber_AsSsize_t] + added = '3.2' +[function.PyNumber_Check] + added = '3.2' +[function.PyNumber_Divmod] + added = '3.2' +[function.PyNumber_Float] + added = '3.2' +[function.PyNumber_FloorDivide] + added = '3.2' +[function.PyNumber_InPlaceAdd] + added = '3.2' +[function.PyNumber_InPlaceAnd] + added = '3.2' +[function.PyNumber_InPlaceFloorDivide] + added = '3.2' +[function.PyNumber_InPlaceLshift] + added = '3.2' +[function.PyNumber_InPlaceMultiply] + added = '3.2' +[function.PyNumber_InPlaceOr] + added = '3.2' +[function.PyNumber_InPlacePower] + added = '3.2' +[function.PyNumber_InPlaceRemainder] + added = '3.2' +[function.PyNumber_InPlaceRshift] + added = '3.2' +[function.PyNumber_InPlaceSubtract] + added = '3.2' +[function.PyNumber_InPlaceTrueDivide] + added = '3.2' +[function.PyNumber_InPlaceXor] + added = '3.2' +[function.PyNumber_Index] + added = '3.2' +[function.PyNumber_Invert] + added = '3.2' +[function.PyNumber_Long] + added = '3.2' +[function.PyNumber_Lshift] + added = '3.2' +[function.PyNumber_Multiply] + added = '3.2' +[function.PyNumber_Negative] + added = '3.2' +[function.PyNumber_Or] + added = '3.2' +[function.PyNumber_Positive] + added = '3.2' +[function.PyNumber_Power] + added = '3.2' +[function.PyNumber_Remainder] + added = '3.2' +[function.PyNumber_Rshift] + added = '3.2' +[function.PyNumber_Subtract] + added = '3.2' +[function.PyNumber_ToBase] + added = '3.2' +[function.PyNumber_TrueDivide] + added = '3.2' +[function.PyNumber_Xor] + added = '3.2' +[function.PyOS_AfterFork] + added = '3.2' + ifdef = 'HAVE_FORK' +[data.PyOS_InputHook] + added = '3.2' +[function.PyOS_InterruptOccurred] + added = '3.2' +[function.PyOS_double_to_string] + added = '3.2' +[function.PyOS_getsig] + added = '3.2' +[function.PyOS_mystricmp] + added = '3.2' +[function.PyOS_mystrnicmp] + added = '3.2' +[function.PyOS_setsig] + added = '3.2' +[function.PyOS_snprintf] + added = '3.2' +[function.PyOS_string_to_double] + added = '3.2' +[function.PyOS_strtol] + added = '3.2' +[function.PyOS_strtoul] + added = '3.2' +[function.PyOS_vsnprintf] + added = '3.2' +[function.PyObject_ASCII] + added = '3.2' +[function.PyObject_AsFileDescriptor] + added = '3.2' +[function.PyObject_Bytes] + added = '3.2' +[function.PyObject_Call] + added = '3.2' +[function.PyObject_CallFunction] + added = '3.2' +[function.PyObject_CallFunctionObjArgs] + added = '3.2' +[function.PyObject_CallMethod] + added = '3.2' +[function.PyObject_CallMethodObjArgs] + added = '3.2' +[function.PyObject_CallObject] + added = '3.2' +[function.PyObject_ClearWeakRefs] + added = '3.2' +[function.PyObject_DelItem] + added = '3.2' +[function.PyObject_DelItemString] + added = '3.2' +[function.PyObject_Dir] + added = '3.2' +[function.PyObject_Format] + added = '3.2' +[function.PyObject_Free] + added = '3.2' +[function.PyObject_GC_Del] + added = '3.2' +[function.PyObject_GC_Track] + added = '3.2' +[function.PyObject_GC_UnTrack] + added = '3.2' +[function.PyObject_GenericGetAttr] + added = '3.2' +[function.PyObject_GenericSetAttr] + added = '3.2' +[function.PyObject_GetAttr] + added = '3.2' +[function.PyObject_GetAttrString] + added = '3.2' +[function.PyObject_GetItem] + added = '3.2' +[function.PyObject_GetIter] + added = '3.2' +[function.PyObject_HasAttr] + added = '3.2' +[function.PyObject_HasAttrString] + added = '3.2' +[function.PyObject_Hash] + added = '3.2' +[function.PyObject_HashNotImplemented] + added = '3.2' +[function.PyObject_Init] + added = '3.2' +[function.PyObject_InitVar] + added = '3.2' +[function.PyObject_IsInstance] + added = '3.2' +[function.PyObject_IsSubclass] + added = '3.2' +[function.PyObject_IsTrue] + added = '3.2' +[function.PyObject_Length] + added = '3.2' +[function.PyObject_Malloc] + added = '3.2' +[function.PyObject_Not] + added = '3.2' +[function.PyObject_Realloc] + added = '3.2' +[function.PyObject_Repr] + added = '3.2' +[function.PyObject_RichCompare] + added = '3.2' +[function.PyObject_RichCompareBool] + added = '3.2' +[function.PyObject_SelfIter] + added = '3.2' +[function.PyObject_SetAttr] + added = '3.2' +[function.PyObject_SetAttrString] + added = '3.2' +[function.PyObject_SetItem] + added = '3.2' +[function.PyObject_Size] + added = '3.2' +[function.PyObject_Str] + added = '3.2' +[function.PyObject_Type] + added = '3.2' +[data.PyProperty_Type] + added = '3.2' +[data.PyRangeIter_Type] + added = '3.2' +[data.PyRange_Type] + added = '3.2' +[data.PyReversed_Type] + added = '3.2' +[function.PySeqIter_New] + added = '3.2' +[data.PySeqIter_Type] + added = '3.2' +[function.PySequence_Check] + added = '3.2' +[function.PySequence_Concat] + added = '3.2' +[function.PySequence_Contains] + added = '3.2' +[function.PySequence_Count] + added = '3.2' +[function.PySequence_DelItem] + added = '3.2' +[function.PySequence_DelSlice] + added = '3.2' +[function.PySequence_Fast] + added = '3.2' +[function.PySequence_GetItem] + added = '3.2' +[function.PySequence_GetSlice] + added = '3.2' +[function.PySequence_In] + added = '3.2' +[function.PySequence_InPlaceConcat] + added = '3.2' +[function.PySequence_InPlaceRepeat] + added = '3.2' +[function.PySequence_Index] + added = '3.2' +[function.PySequence_Length] + added = '3.2' +[function.PySequence_List] + added = '3.2' +[function.PySequence_Repeat] + added = '3.2' +[function.PySequence_SetItem] + added = '3.2' +[function.PySequence_SetSlice] + added = '3.2' +[function.PySequence_Size] + added = '3.2' +[function.PySequence_Tuple] + added = '3.2' +[data.PySetIter_Type] + added = '3.2' +[function.PySet_Add] + added = '3.2' +[function.PySet_Clear] + added = '3.2' +[function.PySet_Contains] + added = '3.2' +[function.PySet_Discard] + added = '3.2' +[function.PySet_New] + added = '3.2' +[function.PySet_Pop] + added = '3.2' +[function.PySet_Size] + added = '3.2' +[data.PySet_Type] + added = '3.2' +[function.PySlice_GetIndices] + added = '3.2' +[function.PySlice_GetIndicesEx] + added = '3.2' +[function.PySlice_New] + added = '3.2' +[data.PySlice_Type] + added = '3.2' +[function.PyState_FindModule] + added = '3.2' +[function.PyStructSequence_GetItem] + added = '3.2' +[function.PyStructSequence_New] + added = '3.2' +[function.PyStructSequence_NewType] + added = '3.2' +[function.PyStructSequence_SetItem] + added = '3.2' +[data.PySuper_Type] + added = '3.2' +[function.PySys_AddWarnOption] + added = '3.2' +[function.PySys_AddWarnOptionUnicode] + added = '3.2' +[function.PySys_FormatStderr] + added = '3.2' +[function.PySys_FormatStdout] + added = '3.2' +[function.PySys_GetObject] + added = '3.2' +[function.PySys_HasWarnOptions] + added = '3.2' +[function.PySys_ResetWarnOptions] + added = '3.2' +[function.PySys_SetArgv] + added = '3.2' +[function.PySys_SetArgvEx] + added = '3.2' +[function.PySys_SetObject] + added = '3.2' +[function.PySys_SetPath] + added = '3.2' +[function.PySys_WriteStderr] + added = '3.2' +[function.PySys_WriteStdout] + added = '3.2' +[function.PyThreadState_Clear] + added = '3.2' +[function.PyThreadState_Delete] + added = '3.2' +[function.PyThreadState_DeleteCurrent] + added = '3.2' + abi_only = true +[function.PyThreadState_Get] + added = '3.2' +[function.PyThreadState_GetDict] + added = '3.2' +[function.PyThreadState_New] + added = '3.2' +[function.PyThreadState_SetAsyncExc] + added = '3.2' +[function.PyThreadState_Swap] + added = '3.2' +[function.PyTraceBack_Here] + added = '3.2' +[function.PyTraceBack_Print] + added = '3.2' +[data.PyTraceBack_Type] + added = '3.2' +[data.PyTupleIter_Type] + added = '3.2' +[function.PyTuple_GetItem] + added = '3.2' +[function.PyTuple_GetSlice] + added = '3.2' +[function.PyTuple_New] + added = '3.2' +[function.PyTuple_Pack] + added = '3.2' +[function.PyTuple_SetItem] + added = '3.2' +[function.PyTuple_Size] + added = '3.2' +[data.PyTuple_Type] + added = '3.2' +[function.PyType_ClearCache] + added = '3.2' +[function.PyType_GenericAlloc] + added = '3.2' +[function.PyType_GenericNew] + added = '3.2' +[function.PyType_GetFlags] + added = '3.2' +[function.PyType_IsSubtype] + added = '3.2' +[function.PyType_Modified] + added = '3.2' +[function.PyType_Ready] + added = '3.2' +[data.PyType_Type] + added = '3.2' +[function.PyUnicodeDecodeError_Create] + added = '3.2' +[function.PyUnicodeDecodeError_GetEncoding] + added = '3.2' +[function.PyUnicodeDecodeError_GetEnd] + added = '3.2' +[function.PyUnicodeDecodeError_GetObject] + added = '3.2' +[function.PyUnicodeDecodeError_GetReason] + added = '3.2' +[function.PyUnicodeDecodeError_GetStart] + added = '3.2' +[function.PyUnicodeDecodeError_SetEnd] + added = '3.2' +[function.PyUnicodeDecodeError_SetReason] + added = '3.2' +[function.PyUnicodeDecodeError_SetStart] + added = '3.2' +[function.PyUnicodeEncodeError_GetEncoding] + added = '3.2' +[function.PyUnicodeEncodeError_GetEnd] + added = '3.2' +[function.PyUnicodeEncodeError_GetObject] + added = '3.2' +[function.PyUnicodeEncodeError_GetReason] + added = '3.2' +[function.PyUnicodeEncodeError_GetStart] + added = '3.2' +[function.PyUnicodeEncodeError_SetEnd] + added = '3.2' +[function.PyUnicodeEncodeError_SetReason] + added = '3.2' +[function.PyUnicodeEncodeError_SetStart] + added = '3.2' +[data.PyUnicodeIter_Type] + added = '3.2' +[function.PyUnicodeTranslateError_GetEnd] + added = '3.2' +[function.PyUnicodeTranslateError_GetObject] + added = '3.2' +[function.PyUnicodeTranslateError_GetReason] + added = '3.2' +[function.PyUnicodeTranslateError_GetStart] + added = '3.2' +[function.PyUnicodeTranslateError_SetEnd] + added = '3.2' +[function.PyUnicodeTranslateError_SetReason] + added = '3.2' +[function.PyUnicodeTranslateError_SetStart] + added = '3.2' +[function.PyUnicode_Append] + added = '3.2' +[function.PyUnicode_AppendAndDel] + added = '3.2' +[function.PyUnicode_AsASCIIString] + added = '3.2' +[function.PyUnicode_AsCharmapString] + added = '3.2' +[function.PyUnicode_AsDecodedObject] + added = '3.2' +[function.PyUnicode_AsDecodedUnicode] + added = '3.2' +[function.PyUnicode_AsEncodedObject] + added = '3.2' +[function.PyUnicode_AsEncodedString] + added = '3.2' +[function.PyUnicode_AsEncodedUnicode] + added = '3.2' +[function.PyUnicode_AsLatin1String] + added = '3.2' +[function.PyUnicode_AsRawUnicodeEscapeString] + added = '3.2' +[function.PyUnicode_AsUTF16String] + added = '3.2' +[function.PyUnicode_AsUTF32String] + added = '3.2' +[function.PyUnicode_AsUTF8String] + added = '3.2' +[function.PyUnicode_AsUnicodeEscapeString] + added = '3.2' +[function.PyUnicode_AsWideChar] + added = '3.2' +[function.PyUnicode_Compare] + added = '3.2' +[function.PyUnicode_Concat] + added = '3.2' +[function.PyUnicode_Contains] + added = '3.2' +[function.PyUnicode_Count] + added = '3.2' +[function.PyUnicode_Decode] + added = '3.2' +[function.PyUnicode_DecodeASCII] + added = '3.2' +[function.PyUnicode_DecodeCharmap] + added = '3.2' +[function.PyUnicode_DecodeFSDefault] + added = '3.2' +[function.PyUnicode_DecodeFSDefaultAndSize] + added = '3.2' +[function.PyUnicode_DecodeLatin1] + added = '3.2' +[function.PyUnicode_DecodeRawUnicodeEscape] + added = '3.2' +[function.PyUnicode_DecodeUTF16] + added = '3.2' +[function.PyUnicode_DecodeUTF16Stateful] + added = '3.2' +[function.PyUnicode_DecodeUTF32] + added = '3.2' +[function.PyUnicode_DecodeUTF32Stateful] + added = '3.2' +[function.PyUnicode_DecodeUTF8] + added = '3.2' +[function.PyUnicode_DecodeUTF8Stateful] + added = '3.2' +[function.PyUnicode_DecodeUnicodeEscape] + added = '3.2' +[function.PyUnicode_FSConverter] + added = '3.2' +[function.PyUnicode_FSDecoder] + added = '3.2' +[function.PyUnicode_Find] + added = '3.2' +[function.PyUnicode_Format] + added = '3.2' +[function.PyUnicode_FromEncodedObject] + added = '3.2' +[function.PyUnicode_FromFormat] + added = '3.2' +[function.PyUnicode_FromFormatV] + added = '3.2' +[function.PyUnicode_FromObject] + added = '3.2' +[function.PyUnicode_FromOrdinal] + added = '3.2' +[function.PyUnicode_FromString] + added = '3.2' +[function.PyUnicode_FromStringAndSize] + added = '3.2' +[function.PyUnicode_FromWideChar] + added = '3.2' +[function.PyUnicode_GetDefaultEncoding] + added = '3.2' +[function.PyUnicode_GetSize] + added = '3.2' + abi_only = true +[function.PyUnicode_IsIdentifier] + added = '3.2' +[function.PyUnicode_Join] + added = '3.2' +[function.PyUnicode_Partition] + added = '3.2' +[function.PyUnicode_RPartition] + added = '3.2' +[function.PyUnicode_RSplit] + added = '3.2' +[function.PyUnicode_Replace] + added = '3.2' +[function.PyUnicode_Resize] + added = '3.2' +[function.PyUnicode_RichCompare] + added = '3.2' +[function.PyUnicode_Split] + added = '3.2' +[function.PyUnicode_Splitlines] + added = '3.2' +[function.PyUnicode_Tailmatch] + added = '3.2' +[function.PyUnicode_Translate] + added = '3.2' +[function.PyUnicode_BuildEncodingMap] + added = '3.2' +[function.PyUnicode_CompareWithASCIIString] + added = '3.2' +[function.PyUnicode_DecodeUTF7] + added = '3.2' +[function.PyUnicode_DecodeUTF7Stateful] + added = '3.2' +[function.PyUnicode_EncodeFSDefault] + added = '3.2' +[function.PyUnicode_InternFromString] + added = '3.2' +[function.PyUnicode_InternImmortal] + added = '3.2' + abi_only = true +[function.PyUnicode_InternInPlace] + added = '3.2' +[data.PyUnicode_Type] + added = '3.2' +[function.PyWeakref_GetObject] + added = '3.2' +[function.PyWeakref_NewProxy] + added = '3.2' +[function.PyWeakref_NewRef] + added = '3.2' +[data.PyWrapperDescr_Type] + added = '3.2' +[function.PyWrapper_New] + added = '3.2' +[data.PyZip_Type] + added = '3.2' +[function.Py_AddPendingCall] + added = '3.2' +[function.Py_AtExit] + added = '3.2' +[function.Py_BuildValue] + added = '3.2' +[function.Py_CompileString] + added = '3.2' +[function.Py_DecRef] + added = '3.2' +[function.Py_EndInterpreter] + added = '3.2' +[function.Py_Exit] + added = '3.2' +[function.Py_FatalError] + added = '3.2' +[data.Py_FileSystemDefaultEncoding] + added = '3.2' +[function.Py_Finalize] + added = '3.2' +[function.Py_GetBuildInfo] + added = '3.2' +[function.Py_GetCompiler] + added = '3.2' +[function.Py_GetCopyright] + added = '3.2' +[function.Py_GetExecPrefix] + added = '3.2' +[function.Py_GetPath] + added = '3.2' +[function.Py_GetPlatform] + added = '3.2' +[function.Py_GetPrefix] + added = '3.2' +[function.Py_GetProgramFullPath] + added = '3.2' +[function.Py_GetProgramName] + added = '3.2' +[function.Py_GetPythonHome] + added = '3.2' +[function.Py_GetRecursionLimit] + added = '3.2' +[function.Py_GetVersion] + added = '3.2' +[data.Py_HasFileSystemDefaultEncoding] + added = '3.2' +[function.Py_IncRef] + added = '3.2' +[function.Py_Initialize] + added = '3.2' +[function.Py_InitializeEx] + added = '3.2' +[function.Py_IsInitialized] + added = '3.2' +[function.Py_Main] + added = '3.2' +[function.Py_MakePendingCalls] + added = '3.2' +[function.Py_NewInterpreter] + added = '3.2' +[function.Py_ReprEnter] + added = '3.2' +[function.Py_ReprLeave] + added = '3.2' +[function.Py_SetProgramName] + added = '3.2' +[function.Py_SetPythonHome] + added = '3.2' +[function.Py_SetRecursionLimit] + added = '3.2' +[function.Py_VaBuildValue] + added = '3.2' + +[function._PyErr_BadInternalCall] + added = '3.2' + abi_only = true +[function._PyObject_CallFunction_SizeT] + added = '3.2' + abi_only = true +[function._PyObject_CallMethod_SizeT] + added = '3.2' + abi_only = true +[function._PyObject_GC_New] + added = '3.2' + abi_only = true +[function._PyObject_GC_NewVar] + added = '3.2' + abi_only = true +[function._PyObject_GC_Resize] + added = '3.2' + abi_only = true +[function._PyObject_New] + added = '3.2' + abi_only = true +[function._PyObject_NewVar] + added = '3.2' + abi_only = true +[function._PyState_AddModule] + added = '3.2' + abi_only = true +[function._PyThreadState_Init] + added = '3.2' + abi_only = true +[function._PyThreadState_Prealloc] + added = '3.2' + abi_only = true +[data._PyWeakref_CallableProxyType] + added = '3.2' + abi_only = true +[data._PyWeakref_ProxyType] + added = '3.2' + abi_only = true +[data._PyWeakref_RefType] + added = '3.2' + abi_only = true +[function._Py_BuildValue_SizeT] + added = '3.2' + abi_only = true +[function._Py_CheckRecursiveCall] + added = '3.2' + abi_only = true +[function._Py_Dealloc] + added = '3.2' + abi_only = true +[data._Py_EllipsisObject] + added = '3.2' + abi_only = true +[data._Py_FalseStruct] + added = '3.2' + abi_only = true +[data._Py_NoneStruct] + added = '3.2' + abi_only = true +[data._Py_NotImplementedStruct] + added = '3.2' + abi_only = true +[data._Py_SwappedOp] + added = '3.2' + abi_only = true +[data._Py_TrueStruct] + added = '3.2' + abi_only = true +[function._Py_VaBuildValue_SizeT] + added = '3.2' + abi_only = true + +# Old buffer protocol support (deprecated) + +[function.PyObject_AsCharBuffer] + added = '3.2' +[function.PyObject_AsReadBuffer] + added = '3.2' +[function.PyObject_AsWriteBuffer] + added = '3.2' +[function.PyObject_CheckReadBuffer] + added = '3.2' + +# Flags are implicitly part of the ABI: + +[const.Py_TPFLAGS_DEFAULT] + added = '3.2' +[const.Py_TPFLAGS_BASETYPE] + added = '3.2' +[const.Py_TPFLAGS_HAVE_GC] + added = '3.2' + +[const.METH_VARARGS] + added = '3.2' +[const.METH_NOARGS] + added = '3.2' +[const.METH_O] + added = '3.2' +[const.METH_CLASS] + added = '3.2' +[const.METH_STATIC] + added = '3.2' +[const.METH_COEXIST] + added = '3.2' +# METH_STACKLESS is undocumented +# METH_FASTCALL is not part of limited API. + +# The following are defined in private headers, but historically +# they were exported as part of the stable ABI. +[function.PyMarshal_ReadObjectFromString] + added = '3.2' + abi_only = true +[function.PyMarshal_WriteObjectToString] + added = '3.2' + abi_only = true +[function.PyMember_GetOne] + added = '3.2' # Before 3.12, available in "structmember.h" +[function.PyMember_SetOne] + added = '3.2' # Before 3.12, available in "structmember.h" + +# TLS api is deprecated; superseded by TSS API + +[function.PyThread_ReInitTLS] + added = '3.2' +[function.PyThread_create_key] + added = '3.2' +[function.PyThread_delete_key] + added = '3.2' +[function.PyThread_set_key_value] + added = '3.2' +[function.PyThread_get_key_value] + added = '3.2' +[function.PyThread_delete_key_value] + added = '3.2' +[function.PyThread_acquire_lock] + added = '3.2' +[function.PyThread_acquire_lock_timed] + added = '3.2' +[function.PyThread_allocate_lock] + added = '3.2' +[function.PyThread_exit_thread] + added = '3.2' +[function.PyThread_free_lock] + added = '3.2' +[function.PyThread_get_stacksize] + added = '3.2' +[function.PyThread_get_thread_ident] + added = '3.2' +[function.PyThread_get_thread_native_id] + added = '3.2' + ifdef = 'PY_HAVE_THREAD_NATIVE_ID' +[function.PyThread_init_thread] + added = '3.2' +[function.PyThread_release_lock] + added = '3.2' +[function.PyThread_set_stacksize] + added = '3.2' +[function.PyThread_start_new_thread] + added = '3.2' + +# The following were added in PC/python3.def in Python 3.3: +# 7800f75827b1be557be16f3b18f5170fbf9fae08 +# 9c56409d3353b8cd4cfc19e0467bbe23fd34fc92 +# 75aeaa9b18667219bbacbc58ba6efecccef9dfbd + +[function.PyState_AddModule] + added = '3.3' +[function.PyState_RemoveModule] + added = '3.3' +[function.PyType_FromSpecWithBases] + added = '3.3' +[function._PyArg_Parse_SizeT] + added = '3.3' + abi_only = true +[function._PyArg_ParseTuple_SizeT] + added = '3.3' + abi_only = true +[function._PyArg_ParseTupleAndKeywords_SizeT] + added = '3.3' + abi_only = true +[function._PyArg_VaParse_SizeT] + added = '3.3' + abi_only = true +[function._PyArg_VaParseTupleAndKeywords_SizeT] + added = '3.3' + abi_only = true +[function.PyThread_GetInfo] + added = '3.3' + +# The following were added in PC/python3.def in Python 3.4: +# 3ba3a3ee56c142e93d6bbe20ff6bf939212a30f0 + +[function.PyCFunction_New] + added = '3.4' +[function.PyType_GetSlot] + added = '3.4' + +# The following were added in PC/python3.def in Python 3.5: +# 11d7b1423fc44d764eba7065ea5eba58ed748b21 +# f3b73ad51da3097d7915796fdc62608b1ab90c0a + +[function.PyErr_FormatV] + added = '3.5' +[function.PyModuleDef_Init] + added = '3.5' +[data.PyModuleDef_Type] + added = '3.5' + +# New slots in 3.5: +# d51374ed78a3e3145911a16cdf3b9b84b3ba7d15 - Matrix multiplication (PEP 465) +# 7544508f0245173bff5866aa1598c8f6cce1fc5f - Async iterators (PEP 492) +# 0969a9f8abcf98bb43ea77b1dd050426adcfb4f7 - tp_finalize + +[const.Py_nb_matrix_multiply] + added = '3.5' +[const.Py_nb_inplace_matrix_multiply] + added = '3.5' +[const.Py_am_await] + added = '3.5' +[const.Py_am_aiter] + added = '3.5' +[const.Py_am_anext] + added = '3.5' +[const.Py_tp_finalize] + added = '3.5' + +# The following were added in PC/python3.def in Python 3.6: + +[function.Py_FinalizeEx] + added = '3.6' + +[function.PyOS_FSPath] + added = '3.6' +[function.PyErr_ResourceWarning] + added = '3.6' +[function.PyErr_SetImportErrorSubclass] + added = '3.6' +[data.PyExc_ModuleNotFoundError] + added = '3.6' + +# The following were added in PC/python3.def in Python 3.6.1 and 3.5.3/3.5.4: + +[function.PyCodec_NameReplaceErrors] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyErr_GetExcInfo] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyErr_SetExcInfo] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyErr_SetFromErrnoWithFilenameObjects] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyErr_SetImportError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyErr_SyntaxLocationEx] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_BlockingIOError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_BrokenPipeError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_ChildProcessError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_ConnectionAbortedError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_ConnectionError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_ConnectionRefusedError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_ConnectionResetError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_FileExistsError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_FileNotFoundError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_InterruptedError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_IsADirectoryError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_NotADirectoryError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_PermissionError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_ProcessLookupError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_RecursionError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_ResourceWarning] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_StopAsyncIteration] + added = '3.7' # (and 3.6.1 and 3.5.3) +[data.PyExc_TimeoutError] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyImport_AddModuleObject] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyImport_ExecCodeModuleObject] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyImport_ImportFrozenModuleObject] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyImport_ImportModuleLevelObject] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyMem_Calloc] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyMemoryView_FromMemory] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyModule_AddFunctions] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyModule_ExecDef] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyModule_FromDefAndSpec2] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyModule_GetNameObject] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyModule_NewObject] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyModule_SetDocString] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyNumber_InPlaceMatrixMultiply] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyNumber_MatrixMultiply] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyObject_Calloc] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyObject_GenericSetDict] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PySys_AddXOption] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PySys_GetXOptions] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyUnicode_AsUCS4] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyUnicode_AsUCS4Copy] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyUnicode_AsWideCharString] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyUnicode_DecodeLocale] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyUnicode_DecodeLocaleAndSize] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyUnicode_EncodeLocale] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyUnicode_FindChar] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyUnicode_GetLength] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyUnicode_ReadChar] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyUnicode_Substring] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyUnicode_WriteChar] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.Py_DecodeLocale] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.Py_EncodeLocale] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.Py_SetPath] + added = '3.7' # (and 3.6.1 and 3.5.3) +[function.PyErr_SetExcFromWindowsErr] + added = '3.7' # (and 3.6.1 and 3.5.3) + ifdef = 'MS_WINDOWS' +[function.PyErr_SetExcFromWindowsErrWithFilename] + added = '3.7' # (and 3.6.1 and 3.5.3) + ifdef = 'MS_WINDOWS' +[function.PyErr_SetExcFromWindowsErrWithFilenameObject] + added = '3.7' # (and 3.6.1 and 3.5.3) + ifdef = 'MS_WINDOWS' +[function.PyErr_SetExcFromWindowsErrWithFilenameObjects] + added = '3.7' # (and 3.6.1 and 3.5.3) + ifdef = 'MS_WINDOWS' +[function.PyErr_SetFromWindowsErr] + added = '3.7' # (and 3.6.1 and 3.5.3) + ifdef = 'MS_WINDOWS' +[function.PyErr_SetFromWindowsErrWithFilename] + added = '3.7' # (and 3.6.1 and 3.5.3) + ifdef = 'MS_WINDOWS' +[data.PyExc_WindowsError] + added = '3.7' # (and 3.6.1 and 3.5.3) + ifdef = 'MS_WINDOWS' +[function.PyOS_CheckStack] + added = '3.7' # (and 3.6.1 and 3.5.3) + ifdef = 'USE_STACKCHECK' +[function.PyUnicode_AsMBCSString] + added = '3.7' # (and 3.6.1 and 3.5.3) + ifdef = 'MS_WINDOWS' +[function.PyUnicode_DecodeCodePageStateful] + added = '3.7' # (and 3.6.1 and 3.5.3) + ifdef = 'MS_WINDOWS' +[function.PyUnicode_DecodeMBCS] + added = '3.7' # (and 3.6.1 and 3.5.3) + ifdef = 'MS_WINDOWS' +[function.PyUnicode_DecodeMBCSStateful] + added = '3.7' # (and 3.6.1 and 3.5.3) + ifdef = 'MS_WINDOWS' +[function.PyUnicode_EncodeCodePage] + added = '3.7' # (and 3.6.1 and 3.5.3) + ifdef = 'MS_WINDOWS' + +# 3.5.4: +[function.PySlice_AdjustIndices] + added = '3.7' # (and 3.6.1 and 3.5.4) +[function.PySlice_Unpack] + added = '3.7' # (and 3.6.1 and 3.5.4) + +# The following were added in PC/python3.def in Python 3.7: + +[function.PyInterpreterState_GetID] + added = '3.7' +[function.PyThread_tss_alloc] + added = '3.7' +[function.PyThread_tss_create] + added = '3.7' +[function.PyThread_tss_delete] + added = '3.7' +[function.PyThread_tss_free] + added = '3.7' +[function.PyThread_tss_get] + added = '3.7' +[function.PyThread_tss_is_created] + added = '3.7' +[function.PyThread_tss_set] + added = '3.7' +[function.PyOS_BeforeFork] + added = '3.7' + ifdef = 'HAVE_FORK' +[function.PyOS_AfterFork_Parent] + added = '3.7' + ifdef = 'HAVE_FORK' +[function.PyOS_AfterFork_Child] + added = '3.7' + ifdef = 'HAVE_FORK' + +# New method flags in 3.7 (PEP 590): + +[const.METH_FASTCALL] + added = '3.7' +[const.METH_METHOD] + added = '3.7' + +# The following were added in PC/python3.def in Python 3.8: + +[function.PyImport_GetModule] + added = '3.8' +[data.Py_UTF8Mode] + added = '3.8' +[function.PyExceptionClass_Name] + added = '3.8' +[function.PyIndex_Check] + added = '3.8' +[function.PyIter_Check] + added = '3.8' +[data.PyDictRevIterItem_Type] + added = '3.8' +[data.PyDictRevIterKey_Type] + added = '3.8' +[data.PyDictRevIterValue_Type] + added = '3.8' +[function.PyInterpreterState_GetDict] + added = '3.8' +[function.Py_BytesMain] + added = '3.8' + +# New type flag (PEP 590): + +[const.Py_TPFLAGS_METHOD_DESCRIPTOR] + added = '3.8' + +# The following were added in PC/python3.def in Python 3.9: + +[function.Py_EnterRecursiveCall] + added = '3.9' +[function.Py_LeaveRecursiveCall] + added = '3.9' +[function.Py_GenericAlias] + added = '3.9' +[data.Py_GenericAliasType] + added = '3.9' +[function.PyCMethod_New] + added = '3.9' +[function.PyInterpreterState_Get] + added = '3.9' +[function.PyObject_GC_IsFinalized] + added = '3.9' +[function.PyObject_GC_IsTracked] + added = '3.9' + +# The following were added in PC/python3.def in Python 3.10: + +[function.Py_GetArgcArgv] + added = '3.10' + abi_only = true +[function.PyIter_Send] + added = '3.10' +[function.PyUnicode_AsUTF8AndSize] + added = '3.10' +[function.PyObject_GenericGetDict] + added = '3.10' +[function.Py_NewRef] + added = '3.10' +[function.Py_XNewRef] + added = '3.10' +[function.PyModule_AddType] + added = '3.10' +[function.PyType_FromModuleAndSpec] + added = '3.10' +[function.PyType_GetModule] + added = '3.10' +[function.PyType_GetModuleState] + added = '3.10' +[function.PyFrame_GetLineNumber] + added = '3.10' +[function.PyFrame_GetCode] + added = '3.10' +[function.PyObject_CallNoArgs] + added = '3.10' +[function.PyThreadState_GetFrame] + added = '3.10' +[function.PyThreadState_GetID] + added = '3.10' +[function.PyThreadState_GetInterpreter] + added = '3.10' +[function.PyModule_AddObjectRef] + added = '3.10' +[data.Py_FileSystemDefaultEncodeErrors] + added = '3.10' +[function.PyCodec_Unregister] + added = '3.10' +[function.PyErr_SetInterruptEx] + added = '3.10' +[function.Py_Is] + added = '3.10' +[function.Py_IsTrue] + added = '3.10' +[function.Py_IsFalse] + added = '3.10' +[function.Py_IsNone] + added = '3.10' +[function._Py_IncRef] + added = '3.10' + abi_only = true +[function._Py_DecRef] + added = '3.10' + abi_only = true +[function.PyAIter_Check] + added = '3.10' +[function.PyObject_GetAIter] + added = '3.10' +[data.PyExc_EncodingWarning] + added = '3.10' + +# Support for Stable ABI in debug builds + +[data._Py_RefTotal] + added = '3.10' + ifdef = 'Py_REF_DEBUG' + abi_only = true +[function._Py_NegativeRefcount] + added = '3.10' + ifdef = 'Py_REF_DEBUG' + abi_only = true + +# New slots in 3.10: + +[const.Py_am_send] + added = '3.10' + + +# New GC control functions in Py3.10 (https://bugs.python.org/issue28254) + +[function.PyGC_Disable] + added = '3.10' +[function.PyGC_Enable] + added = '3.10' +[function.PyGC_IsEnabled] + added = '3.10' + +# Add new C API in Python 3.11 + +[function.PyType_GetName] + added = '3.11' +[function.PyType_GetQualName] + added = '3.11' +[data.PyStructSequence_UnnamedField] + added = '3.11' + +# Add stable Py_buffer API in Python 3.11 (https://bugs.python.org/issue45459) +[struct.Py_buffer] + added = '3.11' + struct_abi_kind = 'full-abi' +[function.PyObject_CheckBuffer] + added = '3.11' +[function.PyObject_GetBuffer] + added = '3.11' +[function.PyBuffer_GetPointer] + added = '3.11' +[function.PyBuffer_SizeFromFormat] + added = '3.11' +[function.PyBuffer_ToContiguous] + added = '3.11' +[function.PyBuffer_FromContiguous] + added = '3.11' +[function.PyObject_CopyData] + added = '3.11' +[function.PyBuffer_IsContiguous] + added = '3.11' +[function.PyBuffer_FillContiguousStrides] + added = '3.11' +[function.PyBuffer_FillInfo] + added = '3.11' +[function.PyBuffer_Release] + added = '3.11' +[function.PyMemoryView_FromBuffer] + added = '3.11' + +# Constants for Py_buffer API added to this list in Python 3.11.1 (https://github.com/python/cpython/issues/98680) +# (they were available with 3.11.0) +[const.PyBUF_MAX_NDIM] + added = '3.11' +[const.PyBUF_SIMPLE] + added = '3.11' +[const.PyBUF_WRITABLE] + added = '3.11' +[const.PyBUF_FORMAT] + added = '3.11' +[const.PyBUF_ND] + added = '3.11' +[const.PyBUF_STRIDES] + added = '3.11' +[const.PyBUF_C_CONTIGUOUS] + added = '3.11' +[const.PyBUF_F_CONTIGUOUS] + added = '3.11' +[const.PyBUF_ANY_CONTIGUOUS] + added = '3.11' +[const.PyBUF_INDIRECT] + added = '3.11' +[const.PyBUF_CONTIG] + added = '3.11' +[const.PyBUF_CONTIG_RO] + added = '3.11' +[const.PyBUF_STRIDED] + added = '3.11' +[const.PyBUF_STRIDED_RO] + added = '3.11' +[const.PyBUF_RECORDS] + added = '3.11' +[const.PyBUF_RECORDS_RO] + added = '3.11' +[const.PyBUF_FULL] + added = '3.11' +[const.PyBUF_FULL_RO] + added = '3.11' +[const.PyBUF_READ] + added = '3.11' +[const.PyBUF_WRITE] + added = '3.11' + + +# (Detailed comments aren't really needed for further entries: from here on +# we can use version control logs.) + +[data.Py_Version] + added = '3.11' +[function.PyErr_GetHandledException] + added = '3.11' +[function.PyErr_SetHandledException] + added = '3.11' + +[function.PyType_FromMetaclass] + added = '3.12' +[const.Py_TPFLAGS_HAVE_VECTORCALL] + added = '3.12' +[function.PyVectorcall_NARGS] + added = '3.12' +[function.PyVectorcall_Call] + added = '3.12' +[typedef.vectorcallfunc] + added = '3.12' +[function.PyObject_Vectorcall] + added = '3.12' +[function.PyObject_VectorcallMethod] + added = '3.12' +[macro.PY_VECTORCALL_ARGUMENTS_OFFSET] + added = '3.12' +[typedef.getbufferproc] + added = '3.12' +[typedef.releasebufferproc] + added = '3.12' + +[const.Py_T_BYTE] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_SHORT] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_INT] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_LONG] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_LONGLONG] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_UBYTE] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_UINT] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_USHORT] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_ULONG] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_ULONGLONG] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_PYSSIZET] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_FLOAT] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_DOUBLE] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_BOOL] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_STRING] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_STRING_INPLACE] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_CHAR] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_OBJECT_EX] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_READONLY] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_AUDIT_READ] + added = '3.12' # Before 3.12, available in "structmember.h" diff --git a/Misc/stable_abi.txt b/Misc/stable_abi.txt deleted file mode 100644 index 9f5a85bdec4..00000000000 --- a/Misc/stable_abi.txt +++ /dev/null @@ -1,2158 +0,0 @@ -# This file lists the contents of the Limited API and Stable ABI. -# Please append new items at the end. - -# The syntax of this file is not fixed. -# It is designed to be read only by Tools/stable_abi.py, which can change -# without notice. - -# For the history of the stable ABI prior to this file, -# see the history of PC/python3dll.c and before that, PC/python3.def, -# and PC/pythonXYstub.def - - -# Mentioned in PEP 384: - -struct PyObject - added 3.2 -struct PyVarObject - added 3.2 -struct PyMethodDef - added 3.2 -struct PyMemberDef - added 3.2 -struct PyGetSetDef - added 3.2 -struct PyModuleDef_Base - added 3.2 -struct PyModuleDef - added 3.2 -struct PyStructSequence_Field - added 3.2 -struct PyStructSequence_Desc - added 3.2 -struct PyType_Slot - added 3.2 -struct PyType_Spec - added 3.2 -struct PyThreadState - added 3.2 -struct PyInterpreterState - added 3.2 -struct PyFrameObject - added 3.2 -struct symtable - added 3.2 -struct PyWeakReference - added 3.2 -struct PyLongObject - added 3.2 -struct PyTypeObject - added 3.2 - -function PyType_FromSpec - added 3.2 - -const Py_tp_dealloc - added 3.2 -const Py_tp_getattr - added 3.2 -const Py_tp_setattr - added 3.2 -const Py_tp_repr - added 3.2 -const Py_tp_hash - added 3.2 -const Py_tp_call - added 3.2 -const Py_tp_str - added 3.2 -const Py_tp_getattro - added 3.2 -const Py_tp_setattro - added 3.2 -const Py_tp_doc - added 3.2 -const Py_tp_traverse - added 3.2 -const Py_tp_clear - added 3.2 -const Py_tp_richcompare - added 3.2 -const Py_tp_iter - added 3.2 -const Py_tp_iternext - added 3.2 -const Py_tp_methods - added 3.2 -const Py_tp_base - added 3.2 -const Py_tp_descr_get - added 3.2 -const Py_tp_descr_set - added 3.2 -const Py_tp_init - added 3.2 -const Py_tp_alloc - added 3.2 -const Py_tp_new - added 3.2 -const Py_tp_members - added 3.2 -const Py_tp_getset - added 3.2 -const Py_tp_free - added 3.2 -const Py_tp_is_gc - added 3.2 -const Py_tp_bases - added 3.2 -const Py_tp_del - added 3.2 -const Py_nb_add - added 3.2 -const Py_nb_subtract - added 3.2 -const Py_nb_multiply - added 3.2 -const Py_nb_remainder - added 3.2 -const Py_nb_divmod - added 3.2 -const Py_nb_power - added 3.2 -const Py_nb_negative - added 3.2 -const Py_nb_positive - added 3.2 -const Py_nb_absolute - added 3.2 -const Py_nb_bool - added 3.2 -const Py_nb_invert - added 3.2 -const Py_nb_lshift - added 3.2 -const Py_nb_rshift - added 3.2 -const Py_nb_and - added 3.2 -const Py_nb_xor - added 3.2 -const Py_nb_or - added 3.2 -const Py_nb_int - added 3.2 -const Py_nb_float - added 3.2 -const Py_nb_inplace_add - added 3.2 -const Py_nb_inplace_subtract - added 3.2 -const Py_nb_inplace_multiply - added 3.2 -const Py_nb_inplace_remainder - added 3.2 -const Py_nb_inplace_power - added 3.2 -const Py_nb_inplace_lshift - added 3.2 -const Py_nb_inplace_rshift - added 3.2 -const Py_nb_inplace_and - added 3.2 -const Py_nb_inplace_xor - added 3.2 -const Py_nb_inplace_or - added 3.2 -const Py_nb_floor_divide - added 3.2 -const Py_nb_true_divide - added 3.2 -const Py_nb_inplace_floor_divide - added 3.2 -const Py_nb_inplace_true_divide - added 3.2 -const Py_nb_index - added 3.2 -const Py_sq_length - added 3.2 -const Py_sq_concat - added 3.2 -const Py_sq_repeat - added 3.2 -const Py_sq_item - added 3.2 -const Py_sq_ass_item - added 3.2 -const Py_sq_contains - added 3.2 -const Py_sq_inplace_concat - added 3.2 -const Py_sq_inplace_repeat - added 3.2 -const Py_mp_length - added 3.2 -const Py_mp_subscript - added 3.2 -const Py_mp_ass_subscript - added 3.2 - -typedef Py_uintptr_t - added 3.2 -typedef Py_intptr_t - added 3.2 -typedef Py_ssize_t - added 3.2 -typedef unaryfunc - added 3.2 -typedef binaryfunc - added 3.2 -typedef ternaryfunc - added 3.2 -typedef inquiry - added 3.2 -typedef lenfunc - added 3.2 -typedef ssizeargfunc - added 3.2 -typedef ssizessizeargfunc - added 3.2 -typedef ssizeobjargproc - added 3.2 -typedef ssizessizeobjargproc - added 3.2 -typedef objobjargproc - added 3.2 -typedef objobjproc - added 3.2 -typedef visitproc - added 3.2 -typedef traverseproc - added 3.2 -typedef destructor - added 3.2 -typedef getattrfunc - added 3.2 -typedef getattrofunc - added 3.2 -typedef setattrfunc - added 3.2 -typedef setattrofunc - added 3.2 -typedef reprfunc - added 3.2 -typedef hashfunc - added 3.2 -typedef richcmpfunc - added 3.2 -typedef getiterfunc - added 3.2 -typedef iternextfunc - added 3.2 -typedef descrgetfunc - added 3.2 -typedef descrsetfunc - added 3.2 -typedef initproc - added 3.2 -typedef newfunc - added 3.2 -typedef allocfunc - added 3.2 -struct PyCFunction - added 3.2 -struct PyCFunctionWithKeywords - added 3.2 -struct PyCapsule_Destructor - added 3.2 -typedef getter - added 3.2 -typedef setter - added 3.2 -typedef PyOS_sighandler_t - added 3.2 -typedef PyGILState_STATE - added 3.2 -typedef Py_UCS4 - added 3.2 - -macro Py_BEGIN_ALLOW_THREADS - added 3.2 -macro Py_BLOCK_THREADS - added 3.2 -macro Py_UNBLOCK_THREADS - added 3.2 -macro Py_END_ALLOW_THREADS - added 3.2 - -# The following were added in PC/python3.def in the initial stable ABI commit, -# 4d0d471a8031de90a2b1ce99c4ac4780e60b3bc9, -# and later amendments in 3.2: -# 0d012f284be829c6217f60523db0e1671b7db9d9 -# c83bc3c1fbed14d27a5de3032e24d2cf006a7c4b - -function PyArg_Parse - added 3.2 -function PyArg_ParseTuple - added 3.2 -function PyArg_ParseTupleAndKeywords - added 3.2 -function PyArg_UnpackTuple - added 3.2 -function PyArg_VaParse - added 3.2 -function PyArg_VaParseTupleAndKeywords - added 3.2 -function PyArg_ValidateKeywordArguments - added 3.2 -data PyBaseObject_Type - added 3.2 -function PyBool_FromLong - added 3.2 -data PyBool_Type - added 3.2 -data PyByteArrayIter_Type - added 3.2 -function PyByteArray_AsString - added 3.2 -function PyByteArray_Concat - added 3.2 -function PyByteArray_FromObject - added 3.2 -function PyByteArray_FromStringAndSize - added 3.2 -function PyByteArray_Resize - added 3.2 -function PyByteArray_Size - added 3.2 -data PyByteArray_Type - added 3.2 -data PyBytesIter_Type - added 3.2 -function PyBytes_AsString - added 3.2 -function PyBytes_AsStringAndSize - added 3.2 -function PyBytes_Concat - added 3.2 -function PyBytes_ConcatAndDel - added 3.2 -function PyBytes_DecodeEscape - added 3.2 -function PyBytes_FromFormat - added 3.2 -function PyBytes_FromFormatV - added 3.2 -function PyBytes_FromObject - added 3.2 -function PyBytes_FromString - added 3.2 -function PyBytes_FromStringAndSize - added 3.2 -function PyBytes_Repr - added 3.2 -function PyBytes_Size - added 3.2 -data PyBytes_Type - added 3.2 -function PyCFunction_Call - added 3.2 -function PyCFunction_GetFlags - added 3.2 -function PyCFunction_GetFunction - added 3.2 -function PyCFunction_GetSelf - added 3.2 -function PyCFunction_NewEx - added 3.2 -data PyCFunction_Type - added 3.2 -function PyCallIter_New - added 3.2 -data PyCallIter_Type - added 3.2 -function PyCallable_Check - added 3.2 -function PyCapsule_GetContext - added 3.2 -function PyCapsule_GetDestructor - added 3.2 -function PyCapsule_GetName - added 3.2 -function PyCapsule_GetPointer - added 3.2 -function PyCapsule_Import - added 3.2 -function PyCapsule_IsValid - added 3.2 -function PyCapsule_New - added 3.2 -function PyCapsule_SetContext - added 3.2 -function PyCapsule_SetDestructor - added 3.2 -function PyCapsule_SetName - added 3.2 -function PyCapsule_SetPointer - added 3.2 -data PyCapsule_Type - added 3.2 -data PyClassMethodDescr_Type - added 3.2 -function PyCodec_BackslashReplaceErrors - added 3.2 -function PyCodec_Decode - added 3.2 -function PyCodec_Decoder - added 3.2 -function PyCodec_Encode - added 3.2 -function PyCodec_Encoder - added 3.2 -function PyCodec_IgnoreErrors - added 3.2 -function PyCodec_IncrementalDecoder - added 3.2 -function PyCodec_IncrementalEncoder - added 3.2 -function PyCodec_KnownEncoding - added 3.2 -function PyCodec_LookupError - added 3.2 -function PyCodec_Register - added 3.2 -function PyCodec_RegisterError - added 3.2 -function PyCodec_ReplaceErrors - added 3.2 -function PyCodec_StreamReader - added 3.2 -function PyCodec_StreamWriter - added 3.2 -function PyCodec_StrictErrors - added 3.2 -function PyCodec_XMLCharRefReplaceErrors - added 3.2 -function PyComplex_FromDoubles - added 3.2 -function PyComplex_ImagAsDouble - added 3.2 -function PyComplex_RealAsDouble - added 3.2 -data PyComplex_Type - added 3.2 -function PyDescr_NewClassMethod - added 3.2 -function PyDescr_NewGetSet - added 3.2 -function PyDescr_NewMember - added 3.2 -function PyDescr_NewMethod - added 3.2 -data PyDictItems_Type - added 3.2 -data PyDictIterItem_Type - added 3.2 -data PyDictIterKey_Type - added 3.2 -data PyDictIterValue_Type - added 3.2 -data PyDictKeys_Type - added 3.2 -function PyDictProxy_New - added 3.2 -data PyDictProxy_Type - added 3.2 -data PyDictValues_Type - added 3.2 -function PyDict_Clear - added 3.2 -function PyDict_Contains - added 3.2 -function PyDict_Copy - added 3.2 -function PyDict_DelItem - added 3.2 -function PyDict_DelItemString - added 3.2 -function PyDict_GetItem - added 3.2 -function PyDict_GetItemString - added 3.2 -function PyDict_GetItemWithError - added 3.2 -function PyDict_Items - added 3.2 -function PyDict_Keys - added 3.2 -function PyDict_Merge - added 3.2 -function PyDict_MergeFromSeq2 - added 3.2 -function PyDict_New - added 3.2 -function PyDict_Next - added 3.2 -function PyDict_SetItem - added 3.2 -function PyDict_SetItemString - added 3.2 -function PyDict_Size - added 3.2 -data PyDict_Type - added 3.2 -function PyDict_Update - added 3.2 -function PyDict_Values - added 3.2 -data PyEllipsis_Type - added 3.2 -data PyEnum_Type - added 3.2 -function PyErr_BadArgument - added 3.2 -function PyErr_BadInternalCall - added 3.2 -function PyErr_CheckSignals - added 3.2 -function PyErr_Clear - added 3.2 -function PyErr_Display - added 3.2 -function PyErr_ExceptionMatches - added 3.2 -function PyErr_Fetch - added 3.2 -function PyErr_Format - added 3.2 -function PyErr_GivenExceptionMatches - added 3.2 -function PyErr_NewException - added 3.2 -function PyErr_NewExceptionWithDoc - added 3.2 -function PyErr_NoMemory - added 3.2 -function PyErr_NormalizeException - added 3.2 -function PyErr_Occurred - added 3.2 -function PyErr_Print - added 3.2 -function PyErr_PrintEx - added 3.2 -function PyErr_ProgramText - added 3.2 -function PyErr_Restore - added 3.2 -function PyErr_SetFromErrno - added 3.2 -function PyErr_SetFromErrnoWithFilename - added 3.2 -function PyErr_SetFromErrnoWithFilenameObject - added 3.2 -function PyErr_SetInterrupt - added 3.2 -function PyErr_SetNone - added 3.2 -function PyErr_SetObject - added 3.2 -function PyErr_SetString - added 3.2 -function PyErr_SyntaxLocation - added 3.2 -function PyErr_WarnEx - added 3.2 -function PyErr_WarnExplicit - added 3.2 -function PyErr_WarnFormat - added 3.2 -function PyErr_WriteUnraisable - added 3.2 -function PyEval_AcquireLock - added 3.2 -function PyEval_AcquireThread - added 3.2 -function PyEval_CallFunction - added 3.2 -function PyEval_CallMethod - added 3.2 -function PyEval_CallObjectWithKeywords - added 3.2 -function PyEval_EvalCode - added 3.2 -function PyEval_EvalCodeEx - added 3.2 -function PyEval_EvalFrame - added 3.2 -function PyEval_EvalFrameEx - added 3.2 -function PyEval_GetBuiltins - added 3.2 -function PyEval_GetFrame - added 3.2 -function PyEval_GetFuncDesc - added 3.2 -function PyEval_GetFuncName - added 3.2 -function PyEval_GetGlobals - added 3.2 -function PyEval_GetLocals - added 3.2 -function PyEval_InitThreads - added 3.2 -function PyEval_ReleaseLock - added 3.2 -function PyEval_ReleaseThread - added 3.2 -function PyEval_RestoreThread - added 3.2 -function PyEval_SaveThread - added 3.2 -function PyEval_ThreadsInitialized - added 3.2 -data PyExc_ArithmeticError - added 3.2 -data PyExc_AssertionError - added 3.2 -data PyExc_AttributeError - added 3.2 -data PyExc_BaseException - added 3.2 -data PyExc_BaseExceptionGroup - added 3.11 -data PyExc_BufferError - added 3.2 -data PyExc_BytesWarning - added 3.2 -data PyExc_DeprecationWarning - added 3.2 -data PyExc_EOFError - added 3.2 -data PyExc_EnvironmentError - added 3.2 -data PyExc_Exception - added 3.2 -data PyExc_FloatingPointError - added 3.2 -data PyExc_FutureWarning - added 3.2 -data PyExc_GeneratorExit - added 3.2 -data PyExc_IOError - added 3.2 -data PyExc_ImportError - added 3.2 -data PyExc_ImportWarning - added 3.2 -data PyExc_IndentationError - added 3.2 -data PyExc_IndexError - added 3.2 -data PyExc_KeyError - added 3.2 -data PyExc_KeyboardInterrupt - added 3.2 -data PyExc_LookupError - added 3.2 -data PyExc_MemoryError - added 3.2 -data PyExc_NameError - added 3.2 -data PyExc_NotImplementedError - added 3.2 -data PyExc_OSError - added 3.2 -data PyExc_OverflowError - added 3.2 -data PyExc_PendingDeprecationWarning - added 3.2 -data PyExc_ReferenceError - added 3.2 -data PyExc_RuntimeError - added 3.2 -data PyExc_RuntimeWarning - added 3.2 -data PyExc_StopIteration - added 3.2 -data PyExc_SyntaxError - added 3.2 -data PyExc_SyntaxWarning - added 3.2 -data PyExc_SystemError - added 3.2 -data PyExc_SystemExit - added 3.2 -data PyExc_TabError - added 3.2 -data PyExc_TypeError - added 3.2 -data PyExc_UnboundLocalError - added 3.2 -data PyExc_UnicodeDecodeError - added 3.2 -data PyExc_UnicodeEncodeError - added 3.2 -data PyExc_UnicodeError - added 3.2 -data PyExc_UnicodeTranslateError - added 3.2 -data PyExc_UnicodeWarning - added 3.2 -data PyExc_UserWarning - added 3.2 -data PyExc_ValueError - added 3.2 -data PyExc_Warning - added 3.2 -data PyExc_ZeroDivisionError - added 3.2 -function PyException_GetCause - added 3.2 -function PyException_GetContext - added 3.2 -function PyException_GetTraceback - added 3.2 -function PyException_SetCause - added 3.2 -function PyException_SetContext - added 3.2 -function PyException_SetTraceback - added 3.2 -function PyFile_FromFd - added 3.2 -function PyFile_GetLine - added 3.2 -function PyFile_WriteObject - added 3.2 -function PyFile_WriteString - added 3.2 -data PyFilter_Type - added 3.2 -function PyFloat_AsDouble - added 3.2 -function PyFloat_FromDouble - added 3.2 -function PyFloat_FromString - added 3.2 -function PyFloat_GetInfo - added 3.2 -function PyFloat_GetMax - added 3.2 -function PyFloat_GetMin - added 3.2 -data PyFloat_Type - added 3.2 -function PyFrozenSet_New - added 3.2 -data PyFrozenSet_Type - added 3.2 -function PyGC_Collect - added 3.2 -function PyGILState_Ensure - added 3.2 -function PyGILState_GetThisThreadState - added 3.2 -function PyGILState_Release - added 3.2 -data PyGetSetDescr_Type - added 3.2 -function PyImport_AddModule - added 3.2 -function PyImport_AppendInittab - added 3.2 -function PyImport_ExecCodeModule - added 3.2 -function PyImport_ExecCodeModuleEx - added 3.2 -function PyImport_ExecCodeModuleWithPathnames - added 3.2 -function PyImport_GetImporter - added 3.2 -function PyImport_GetMagicNumber - added 3.2 -function PyImport_GetMagicTag - added 3.2 -function PyImport_GetModuleDict - added 3.2 -function PyImport_Import - added 3.2 -function PyImport_ImportFrozenModule - added 3.2 -function PyImport_ImportModule - added 3.2 -function PyImport_ImportModuleLevel - added 3.2 -function PyImport_ImportModuleNoBlock - added 3.2 -function PyImport_ReloadModule - added 3.2 -function PyInterpreterState_Clear - added 3.2 -function PyInterpreterState_Delete - added 3.2 -function PyInterpreterState_New - added 3.2 -function PyIter_Next - added 3.2 -data PyListIter_Type - added 3.2 -data PyListRevIter_Type - added 3.2 -function PyList_Append - added 3.2 -function PyList_AsTuple - added 3.2 -function PyList_GetItem - added 3.2 -function PyList_GetSlice - added 3.2 -function PyList_Insert - added 3.2 -function PyList_New - added 3.2 -function PyList_Reverse - added 3.2 -function PyList_SetItem - added 3.2 -function PyList_SetSlice - added 3.2 -function PyList_Size - added 3.2 -function PyList_Sort - added 3.2 -data PyList_Type - added 3.2 -data PyLongRangeIter_Type - added 3.2 -function PyLong_AsDouble - added 3.2 -function PyLong_AsLong - added 3.2 -function PyLong_AsLongAndOverflow - added 3.2 -function PyLong_AsLongLong - added 3.2 -function PyLong_AsLongLongAndOverflow - added 3.2 -function PyLong_AsSize_t - added 3.2 -function PyLong_AsSsize_t - added 3.2 -function PyLong_AsUnsignedLong - added 3.2 -function PyLong_AsUnsignedLongLong - added 3.2 -function PyLong_AsUnsignedLongLongMask - added 3.2 -function PyLong_AsUnsignedLongMask - added 3.2 -function PyLong_AsVoidPtr - added 3.2 -function PyLong_FromDouble - added 3.2 -function PyLong_FromLong - added 3.2 -function PyLong_FromLongLong - added 3.2 -function PyLong_FromSize_t - added 3.2 -function PyLong_FromSsize_t - added 3.2 -function PyLong_FromString - added 3.2 -function PyLong_FromUnsignedLong - added 3.2 -function PyLong_FromUnsignedLongLong - added 3.2 -function PyLong_FromVoidPtr - added 3.2 -function PyLong_GetInfo - added 3.2 -data PyLong_Type - added 3.2 -data PyMap_Type - added 3.2 -function PyMapping_Check - added 3.2 -function PyMapping_GetItemString - added 3.2 -function PyMapping_HasKey - added 3.2 -function PyMapping_HasKeyString - added 3.2 -function PyMapping_Items - added 3.2 -function PyMapping_Keys - added 3.2 -function PyMapping_Length - added 3.2 -function PyMapping_SetItemString - added 3.2 -function PyMapping_Size - added 3.2 -function PyMapping_Values - added 3.2 -function PyMem_Free - added 3.2 -function PyMem_Malloc - added 3.2 -function PyMem_Realloc - added 3.2 -data PyMemberDescr_Type - added 3.2 -function PyMemoryView_FromObject - added 3.2 -function PyMemoryView_GetContiguous - added 3.2 -data PyMemoryView_Type - added 3.2 -data PyMethodDescr_Type - added 3.2 -function PyModule_AddIntConstant - added 3.2 -function PyModule_AddObject - added 3.2 -function PyModule_AddStringConstant - added 3.2 -function PyModule_Create2 - added 3.2 -function PyModule_GetDef - added 3.2 -function PyModule_GetDict - added 3.2 -function PyModule_GetFilename - added 3.2 -function PyModule_GetFilenameObject - added 3.2 -function PyModule_GetName - added 3.2 -function PyModule_GetState - added 3.2 -function PyModule_New - added 3.2 -data PyModule_Type - added 3.2 -function PyNumber_Absolute - added 3.2 -function PyNumber_Add - added 3.2 -function PyNumber_And - added 3.2 -function PyNumber_AsSsize_t - added 3.2 -function PyNumber_Check - added 3.2 -function PyNumber_Divmod - added 3.2 -function PyNumber_Float - added 3.2 -function PyNumber_FloorDivide - added 3.2 -function PyNumber_InPlaceAdd - added 3.2 -function PyNumber_InPlaceAnd - added 3.2 -function PyNumber_InPlaceFloorDivide - added 3.2 -function PyNumber_InPlaceLshift - added 3.2 -function PyNumber_InPlaceMultiply - added 3.2 -function PyNumber_InPlaceOr - added 3.2 -function PyNumber_InPlacePower - added 3.2 -function PyNumber_InPlaceRemainder - added 3.2 -function PyNumber_InPlaceRshift - added 3.2 -function PyNumber_InPlaceSubtract - added 3.2 -function PyNumber_InPlaceTrueDivide - added 3.2 -function PyNumber_InPlaceXor - added 3.2 -function PyNumber_Index - added 3.2 -function PyNumber_Invert - added 3.2 -function PyNumber_Long - added 3.2 -function PyNumber_Lshift - added 3.2 -function PyNumber_Multiply - added 3.2 -function PyNumber_Negative - added 3.2 -function PyNumber_Or - added 3.2 -function PyNumber_Positive - added 3.2 -function PyNumber_Power - added 3.2 -function PyNumber_Remainder - added 3.2 -function PyNumber_Rshift - added 3.2 -function PyNumber_Subtract - added 3.2 -function PyNumber_ToBase - added 3.2 -function PyNumber_TrueDivide - added 3.2 -function PyNumber_Xor - added 3.2 -function PyOS_AfterFork - added 3.2 - ifdef HAVE_FORK -data PyOS_InputHook - added 3.2 -function PyOS_InterruptOccurred - added 3.2 -function PyOS_double_to_string - added 3.2 -function PyOS_getsig - added 3.2 -function PyOS_mystricmp - added 3.2 -function PyOS_mystrnicmp - added 3.2 -function PyOS_setsig - added 3.2 -function PyOS_snprintf - added 3.2 -function PyOS_string_to_double - added 3.2 -function PyOS_strtol - added 3.2 -function PyOS_strtoul - added 3.2 -function PyOS_vsnprintf - added 3.2 -function PyObject_ASCII - added 3.2 -function PyObject_AsFileDescriptor - added 3.2 -function PyObject_Bytes - added 3.2 -function PyObject_Call - added 3.2 -function PyObject_CallFunction - added 3.2 -function PyObject_CallFunctionObjArgs - added 3.2 -function PyObject_CallMethod - added 3.2 -function PyObject_CallMethodObjArgs - added 3.2 -function PyObject_CallObject - added 3.2 -function PyObject_ClearWeakRefs - added 3.2 -function PyObject_DelItem - added 3.2 -function PyObject_DelItemString - added 3.2 -function PyObject_Dir - added 3.2 -function PyObject_Format - added 3.2 -function PyObject_Free - added 3.2 -function PyObject_GC_Del - added 3.2 -function PyObject_GC_Track - added 3.2 -function PyObject_GC_UnTrack - added 3.2 -function PyObject_GenericGetAttr - added 3.2 -function PyObject_GenericSetAttr - added 3.2 -function PyObject_GetAttr - added 3.2 -function PyObject_GetAttrString - added 3.2 -function PyObject_GetItem - added 3.2 -function PyObject_GetIter - added 3.2 -function PyObject_HasAttr - added 3.2 -function PyObject_HasAttrString - added 3.2 -function PyObject_Hash - added 3.2 -function PyObject_HashNotImplemented - added 3.2 -function PyObject_Init - added 3.2 -function PyObject_InitVar - added 3.2 -function PyObject_IsInstance - added 3.2 -function PyObject_IsSubclass - added 3.2 -function PyObject_IsTrue - added 3.2 -function PyObject_Length - added 3.2 -function PyObject_Malloc - added 3.2 -function PyObject_Not - added 3.2 -function PyObject_Realloc - added 3.2 -function PyObject_Repr - added 3.2 -function PyObject_RichCompare - added 3.2 -function PyObject_RichCompareBool - added 3.2 -function PyObject_SelfIter - added 3.2 -function PyObject_SetAttr - added 3.2 -function PyObject_SetAttrString - added 3.2 -function PyObject_SetItem - added 3.2 -function PyObject_Size - added 3.2 -function PyObject_Str - added 3.2 -function PyObject_Type - added 3.2 -data PyProperty_Type - added 3.2 -data PyRangeIter_Type - added 3.2 -data PyRange_Type - added 3.2 -data PyReversed_Type - added 3.2 -function PySeqIter_New - added 3.2 -data PySeqIter_Type - added 3.2 -function PySequence_Check - added 3.2 -function PySequence_Concat - added 3.2 -function PySequence_Contains - added 3.2 -function PySequence_Count - added 3.2 -function PySequence_DelItem - added 3.2 -function PySequence_DelSlice - added 3.2 -function PySequence_Fast - added 3.2 -function PySequence_GetItem - added 3.2 -function PySequence_GetSlice - added 3.2 -function PySequence_In - added 3.2 -function PySequence_InPlaceConcat - added 3.2 -function PySequence_InPlaceRepeat - added 3.2 -function PySequence_Index - added 3.2 -function PySequence_Length - added 3.2 -function PySequence_List - added 3.2 -function PySequence_Repeat - added 3.2 -function PySequence_SetItem - added 3.2 -function PySequence_SetSlice - added 3.2 -function PySequence_Size - added 3.2 -function PySequence_Tuple - added 3.2 -data PySetIter_Type - added 3.2 -function PySet_Add - added 3.2 -function PySet_Clear - added 3.2 -function PySet_Contains - added 3.2 -function PySet_Discard - added 3.2 -function PySet_New - added 3.2 -function PySet_Pop - added 3.2 -function PySet_Size - added 3.2 -data PySet_Type - added 3.2 -function PySlice_GetIndices - added 3.2 -function PySlice_GetIndicesEx - added 3.2 -function PySlice_New - added 3.2 -data PySlice_Type - added 3.2 -function PyState_FindModule - added 3.2 -function PyStructSequence_GetItem - added 3.2 -function PyStructSequence_New - added 3.2 -function PyStructSequence_NewType - added 3.2 -function PyStructSequence_SetItem - added 3.2 -data PySuper_Type - added 3.2 -function PySys_AddWarnOption - added 3.2 -function PySys_AddWarnOptionUnicode - added 3.2 -function PySys_FormatStderr - added 3.2 -function PySys_FormatStdout - added 3.2 -function PySys_GetObject - added 3.2 -function PySys_HasWarnOptions - added 3.2 -function PySys_ResetWarnOptions - added 3.2 -function PySys_SetArgv - added 3.2 -function PySys_SetArgvEx - added 3.2 -function PySys_SetObject - added 3.2 -function PySys_SetPath - added 3.2 -function PySys_WriteStderr - added 3.2 -function PySys_WriteStdout - added 3.2 -function PyThreadState_Clear - added 3.2 -function PyThreadState_Delete - added 3.2 -function PyThreadState_DeleteCurrent - added 3.2 - abi_only -function PyThreadState_Get - added 3.2 -function PyThreadState_GetDict - added 3.2 -function PyThreadState_New - added 3.2 -function PyThreadState_SetAsyncExc - added 3.2 -function PyThreadState_Swap - added 3.2 -function PyTraceBack_Here - added 3.2 -function PyTraceBack_Print - added 3.2 -data PyTraceBack_Type - added 3.2 -data PyTupleIter_Type - added 3.2 -function PyTuple_GetItem - added 3.2 -function PyTuple_GetSlice - added 3.2 -function PyTuple_New - added 3.2 -function PyTuple_Pack - added 3.2 -function PyTuple_SetItem - added 3.2 -function PyTuple_Size - added 3.2 -data PyTuple_Type - added 3.2 -function PyType_ClearCache - added 3.2 -function PyType_GenericAlloc - added 3.2 -function PyType_GenericNew - added 3.2 -function PyType_GetFlags - added 3.2 -function PyType_IsSubtype - added 3.2 -function PyType_Modified - added 3.2 -function PyType_Ready - added 3.2 -data PyType_Type - added 3.2 -function PyUnicodeDecodeError_Create - added 3.2 -function PyUnicodeDecodeError_GetEncoding - added 3.2 -function PyUnicodeDecodeError_GetEnd - added 3.2 -function PyUnicodeDecodeError_GetObject - added 3.2 -function PyUnicodeDecodeError_GetReason - added 3.2 -function PyUnicodeDecodeError_GetStart - added 3.2 -function PyUnicodeDecodeError_SetEnd - added 3.2 -function PyUnicodeDecodeError_SetReason - added 3.2 -function PyUnicodeDecodeError_SetStart - added 3.2 -function PyUnicodeEncodeError_GetEncoding - added 3.2 -function PyUnicodeEncodeError_GetEnd - added 3.2 -function PyUnicodeEncodeError_GetObject - added 3.2 -function PyUnicodeEncodeError_GetReason - added 3.2 -function PyUnicodeEncodeError_GetStart - added 3.2 -function PyUnicodeEncodeError_SetEnd - added 3.2 -function PyUnicodeEncodeError_SetReason - added 3.2 -function PyUnicodeEncodeError_SetStart - added 3.2 -data PyUnicodeIter_Type - added 3.2 -function PyUnicodeTranslateError_GetEnd - added 3.2 -function PyUnicodeTranslateError_GetObject - added 3.2 -function PyUnicodeTranslateError_GetReason - added 3.2 -function PyUnicodeTranslateError_GetStart - added 3.2 -function PyUnicodeTranslateError_SetEnd - added 3.2 -function PyUnicodeTranslateError_SetReason - added 3.2 -function PyUnicodeTranslateError_SetStart - added 3.2 -function PyUnicode_Append - added 3.2 -function PyUnicode_AppendAndDel - added 3.2 -function PyUnicode_AsASCIIString - added 3.2 -function PyUnicode_AsCharmapString - added 3.2 -function PyUnicode_AsDecodedObject - added 3.2 -function PyUnicode_AsDecodedUnicode - added 3.2 -function PyUnicode_AsEncodedObject - added 3.2 -function PyUnicode_AsEncodedString - added 3.2 -function PyUnicode_AsEncodedUnicode - added 3.2 -function PyUnicode_AsLatin1String - added 3.2 -function PyUnicode_AsRawUnicodeEscapeString - added 3.2 -function PyUnicode_AsUTF16String - added 3.2 -function PyUnicode_AsUTF32String - added 3.2 -function PyUnicode_AsUTF8String - added 3.2 -function PyUnicode_AsUnicodeEscapeString - added 3.2 -function PyUnicode_AsWideChar - added 3.2 -function PyUnicode_Compare - added 3.2 -function PyUnicode_Concat - added 3.2 -function PyUnicode_Contains - added 3.2 -function PyUnicode_Count - added 3.2 -function PyUnicode_Decode - added 3.2 -function PyUnicode_DecodeASCII - added 3.2 -function PyUnicode_DecodeCharmap - added 3.2 -function PyUnicode_DecodeFSDefault - added 3.2 -function PyUnicode_DecodeFSDefaultAndSize - added 3.2 -function PyUnicode_DecodeLatin1 - added 3.2 -function PyUnicode_DecodeRawUnicodeEscape - added 3.2 -function PyUnicode_DecodeUTF16 - added 3.2 -function PyUnicode_DecodeUTF16Stateful - added 3.2 -function PyUnicode_DecodeUTF32 - added 3.2 -function PyUnicode_DecodeUTF32Stateful - added 3.2 -function PyUnicode_DecodeUTF8 - added 3.2 -function PyUnicode_DecodeUTF8Stateful - added 3.2 -function PyUnicode_DecodeUnicodeEscape - added 3.2 -function PyUnicode_FSConverter - added 3.2 -function PyUnicode_FSDecoder - added 3.2 -function PyUnicode_Find - added 3.2 -function PyUnicode_Format - added 3.2 -function PyUnicode_FromEncodedObject - added 3.2 -function PyUnicode_FromFormat - added 3.2 -function PyUnicode_FromFormatV - added 3.2 -function PyUnicode_FromObject - added 3.2 -function PyUnicode_FromOrdinal - added 3.2 -function PyUnicode_FromString - added 3.2 -function PyUnicode_FromStringAndSize - added 3.2 -function PyUnicode_FromWideChar - added 3.2 -function PyUnicode_GetDefaultEncoding - added 3.2 -function PyUnicode_GetSize - added 3.2 -function PyUnicode_IsIdentifier - added 3.2 -function PyUnicode_Join - added 3.2 -function PyUnicode_Partition - added 3.2 -function PyUnicode_RPartition - added 3.2 -function PyUnicode_RSplit - added 3.2 -function PyUnicode_Replace - added 3.2 -function PyUnicode_Resize - added 3.2 -function PyUnicode_RichCompare - added 3.2 -function PyUnicode_Split - added 3.2 -function PyUnicode_Splitlines - added 3.2 -function PyUnicode_Tailmatch - added 3.2 -function PyUnicode_Translate - added 3.2 -function PyUnicode_BuildEncodingMap - added 3.2 -function PyUnicode_CompareWithASCIIString - added 3.2 -function PyUnicode_DecodeUTF7 - added 3.2 -function PyUnicode_DecodeUTF7Stateful - added 3.2 -function PyUnicode_EncodeFSDefault - added 3.2 -function PyUnicode_InternFromString - added 3.2 -function PyUnicode_InternImmortal - added 3.2 -function PyUnicode_InternInPlace - added 3.2 -data PyUnicode_Type - added 3.2 -function PyWeakref_GetObject - added 3.2 -function PyWeakref_NewProxy - added 3.2 -function PyWeakref_NewRef - added 3.2 -data PyWrapperDescr_Type - added 3.2 -function PyWrapper_New - added 3.2 -data PyZip_Type - added 3.2 -function Py_AddPendingCall - added 3.2 -function Py_AtExit - added 3.2 -function Py_BuildValue - added 3.2 -function Py_CompileString - added 3.2 -function Py_DecRef - added 3.2 -function Py_EndInterpreter - added 3.2 -function Py_Exit - added 3.2 -function Py_FatalError - added 3.2 -data Py_FileSystemDefaultEncoding - added 3.2 -function Py_Finalize - added 3.2 -function Py_GetBuildInfo - added 3.2 -function Py_GetCompiler - added 3.2 -function Py_GetCopyright - added 3.2 -function Py_GetExecPrefix - added 3.2 -function Py_GetPath - added 3.2 -function Py_GetPlatform - added 3.2 -function Py_GetPrefix - added 3.2 -function Py_GetProgramFullPath - added 3.2 -function Py_GetProgramName - added 3.2 -function Py_GetPythonHome - added 3.2 -function Py_GetRecursionLimit - added 3.2 -function Py_GetVersion - added 3.2 -data Py_HasFileSystemDefaultEncoding - added 3.2 -function Py_IncRef - added 3.2 -function Py_Initialize - added 3.2 -function Py_InitializeEx - added 3.2 -function Py_IsInitialized - added 3.2 -function Py_Main - added 3.2 -function Py_MakePendingCalls - added 3.2 -function Py_NewInterpreter - added 3.2 -function Py_ReprEnter - added 3.2 -function Py_ReprLeave - added 3.2 -function Py_SetProgramName - added 3.2 -function Py_SetPythonHome - added 3.2 -function Py_SetRecursionLimit - added 3.2 -function Py_VaBuildValue - added 3.2 - -function _PyErr_BadInternalCall - added 3.2 - abi_only -function _PyObject_CallFunction_SizeT - added 3.2 - abi_only -function _PyObject_CallMethod_SizeT - added 3.2 - abi_only -function _PyObject_GC_Malloc - added 3.2 - abi_only -function _PyObject_GC_New - added 3.2 - abi_only -function _PyObject_GC_NewVar - added 3.2 - abi_only -function _PyObject_GC_Resize - added 3.2 - abi_only -function _PyObject_New - added 3.2 - abi_only -function _PyObject_NewVar - added 3.2 - abi_only -function _PyState_AddModule - added 3.2 - abi_only -function _PyThreadState_Init - added 3.2 - abi_only -function _PyThreadState_Prealloc - added 3.2 - abi_only -data _PyWeakref_CallableProxyType - added 3.2 - abi_only -data _PyWeakref_ProxyType - added 3.2 - abi_only -data _PyWeakref_RefType - added 3.2 - abi_only -function _Py_BuildValue_SizeT - added 3.2 - abi_only -function _Py_CheckRecursiveCall - added 3.2 - abi_only -function _Py_Dealloc - added 3.2 - abi_only -data _Py_EllipsisObject - added 3.2 - abi_only -data _Py_FalseStruct - added 3.2 - abi_only -data _Py_NoneStruct - added 3.2 - abi_only -data _Py_NotImplementedStruct - added 3.2 - abi_only -data _Py_SwappedOp - added 3.2 - abi_only -data _Py_TrueStruct - added 3.2 - abi_only -function _Py_VaBuildValue_SizeT - added 3.2 - abi_only - -# Old buffer protocol support (deprecated) - -function PyObject_AsCharBuffer - added 3.2 -function PyObject_AsReadBuffer - added 3.2 -function PyObject_AsWriteBuffer - added 3.2 -function PyObject_CheckReadBuffer - added 3.2 - -# Flags are implicitly part of the ABI: - -const Py_TPFLAGS_DEFAULT - added 3.2 -const Py_TPFLAGS_BASETYPE - added 3.2 -const Py_TPFLAGS_HAVE_GC - added 3.2 - -const METH_VARARGS - added 3.2 -const METH_NOARGS - added 3.2 -const METH_O - added 3.2 -const METH_CLASS - added 3.2 -const METH_STATIC - added 3.2 -const METH_COEXIST - added 3.2 -# METH_STACKLESS is undocumented -# METH_FASTCALL is not part of limited API. - -# The following are defined in private headers, but historically -# they were exported as part of the stable ABI. -function PyMarshal_ReadObjectFromString - added 3.2 - abi_only -function PyMarshal_WriteObjectToString - added 3.2 - abi_only -function PyMember_GetOne - added 3.2 - abi_only -function PyMember_SetOne - added 3.2 - abi_only - -# TLS api is deprecated; superseded by TSS API - -function PyThread_ReInitTLS - added 3.2 -function PyThread_create_key - added 3.2 -function PyThread_delete_key - added 3.2 -function PyThread_set_key_value - added 3.2 -function PyThread_get_key_value - added 3.2 -function PyThread_delete_key_value - added 3.2 -function PyThread_acquire_lock - added 3.2 -function PyThread_acquire_lock_timed - added 3.2 -function PyThread_allocate_lock - added 3.2 -function PyThread_exit_thread - added 3.2 -function PyThread_free_lock - added 3.2 -function PyThread_get_stacksize - added 3.2 -function PyThread_get_thread_ident - added 3.2 -function PyThread_get_thread_native_id - added 3.2 -function PyThread_init_thread - added 3.2 -function PyThread_release_lock - added 3.2 -function PyThread_set_stacksize - added 3.2 -function PyThread_start_new_thread - added 3.2 - -# The following were added in PC/python3.def in Python 3.3: -# 7800f75827b1be557be16f3b18f5170fbf9fae08 -# 9c56409d3353b8cd4cfc19e0467bbe23fd34fc92 -# 75aeaa9b18667219bbacbc58ba6efecccef9dfbd - -function PyState_AddModule - added 3.3 -function PyState_RemoveModule - added 3.3 -function PyType_FromSpecWithBases - added 3.3 -function _PyArg_Parse_SizeT - added 3.3 - abi_only -function _PyArg_ParseTuple_SizeT - added 3.3 - abi_only -function _PyArg_ParseTupleAndKeywords_SizeT - added 3.3 - abi_only -function _PyArg_VaParse_SizeT - added 3.3 - abi_only -function _PyArg_VaParseTupleAndKeywords_SizeT - added 3.3 - abi_only -function PyThread_GetInfo - added 3.3 - -# The following were added in PC/python3.def in Python 3.4: -# 3ba3a3ee56c142e93d6bbe20ff6bf939212a30f0 - -function PyCFunction_New - added 3.4 -function PyType_GetSlot - added 3.4 - -# The following were added in PC/python3.def in Python 3.5: -# 11d7b1423fc44d764eba7065ea5eba58ed748b21 -# f3b73ad51da3097d7915796fdc62608b1ab90c0a - -function PyErr_FormatV - added 3.5 -function PyModuleDef_Init - added 3.5 -data PyModuleDef_Type - added 3.5 - -# New slots in 3.5: -# d51374ed78a3e3145911a16cdf3b9b84b3ba7d15 - Matrix multiplication (PEP 465) -# 7544508f0245173bff5866aa1598c8f6cce1fc5f - Async iterators (PEP 492) -# 0969a9f8abcf98bb43ea77b1dd050426adcfb4f7 - tp_finalize - -const Py_nb_matrix_multiply - added 3.5 -const Py_nb_inplace_matrix_multiply - added 3.5 -const Py_am_await - added 3.5 -const Py_am_aiter - added 3.5 -const Py_am_anext - added 3.5 -const Py_tp_finalize - added 3.5 - -# The following were added in PC/python3.def in Python 3.6: - -function Py_FinalizeEx - added 3.6 - -function PyOS_FSPath - added 3.6 -function PyErr_ResourceWarning - added 3.6 -function PyErr_SetImportErrorSubclass - added 3.6 -data PyExc_ModuleNotFoundError - added 3.6 - -# The following were added in PC/python3.def in Python 3.6.1 and 3.5.3/3.5.4: - -function PyCodec_NameReplaceErrors - added 3.7 # (and 3.6.1 and 3.5.3) -function PyErr_GetExcInfo - added 3.7 # (and 3.6.1 and 3.5.3) -function PyErr_SetExcInfo - added 3.7 # (and 3.6.1 and 3.5.3) -function PyErr_SetFromErrnoWithFilenameObjects - added 3.7 # (and 3.6.1 and 3.5.3) -function PyErr_SetImportError - added 3.7 # (and 3.6.1 and 3.5.3) -function PyErr_SyntaxLocationEx - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_BlockingIOError - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_BrokenPipeError - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_ChildProcessError - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_ConnectionAbortedError - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_ConnectionError - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_ConnectionRefusedError - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_ConnectionResetError - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_FileExistsError - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_FileNotFoundError - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_InterruptedError - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_IsADirectoryError - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_NotADirectoryError - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_PermissionError - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_ProcessLookupError - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_RecursionError - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_ResourceWarning - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_StopAsyncIteration - added 3.7 # (and 3.6.1 and 3.5.3) -data PyExc_TimeoutError - added 3.7 # (and 3.6.1 and 3.5.3) -function PyImport_AddModuleObject - added 3.7 # (and 3.6.1 and 3.5.3) -function PyImport_ExecCodeModuleObject - added 3.7 # (and 3.6.1 and 3.5.3) -function PyImport_ImportFrozenModuleObject - added 3.7 # (and 3.6.1 and 3.5.3) -function PyImport_ImportModuleLevelObject - added 3.7 # (and 3.6.1 and 3.5.3) -function PyMem_Calloc - added 3.7 # (and 3.6.1 and 3.5.3) -function PyMemoryView_FromMemory - added 3.7 # (and 3.6.1 and 3.5.3) -function PyModule_AddFunctions - added 3.7 # (and 3.6.1 and 3.5.3) -function PyModule_ExecDef - added 3.7 # (and 3.6.1 and 3.5.3) -function PyModule_FromDefAndSpec2 - added 3.7 # (and 3.6.1 and 3.5.3) -function PyModule_GetNameObject - added 3.7 # (and 3.6.1 and 3.5.3) -function PyModule_NewObject - added 3.7 # (and 3.6.1 and 3.5.3) -function PyModule_SetDocString - added 3.7 # (and 3.6.1 and 3.5.3) -function PyNumber_InPlaceMatrixMultiply - added 3.7 # (and 3.6.1 and 3.5.3) -function PyNumber_MatrixMultiply - added 3.7 # (and 3.6.1 and 3.5.3) -function PyObject_Calloc - added 3.7 # (and 3.6.1 and 3.5.3) -function PyObject_GenericSetDict - added 3.7 # (and 3.6.1 and 3.5.3) -function PySys_AddXOption - added 3.7 # (and 3.6.1 and 3.5.3) -function PySys_GetXOptions - added 3.7 # (and 3.6.1 and 3.5.3) -function PyUnicode_AsUCS4 - added 3.7 # (and 3.6.1 and 3.5.3) -function PyUnicode_AsUCS4Copy - added 3.7 # (and 3.6.1 and 3.5.3) -function PyUnicode_AsWideCharString - added 3.7 # (and 3.6.1 and 3.5.3) -function PyUnicode_DecodeLocale - added 3.7 # (and 3.6.1 and 3.5.3) -function PyUnicode_DecodeLocaleAndSize - added 3.7 # (and 3.6.1 and 3.5.3) -function PyUnicode_EncodeLocale - added 3.7 # (and 3.6.1 and 3.5.3) -function PyUnicode_FindChar - added 3.7 # (and 3.6.1 and 3.5.3) -function PyUnicode_GetLength - added 3.7 # (and 3.6.1 and 3.5.3) -function PyUnicode_ReadChar - added 3.7 # (and 3.6.1 and 3.5.3) -function PyUnicode_Substring - added 3.7 # (and 3.6.1 and 3.5.3) -function PyUnicode_WriteChar - added 3.7 # (and 3.6.1 and 3.5.3) -function Py_DecodeLocale - added 3.7 # (and 3.6.1 and 3.5.3) -function Py_EncodeLocale - added 3.7 # (and 3.6.1 and 3.5.3) -function Py_SetPath - added 3.7 # (and 3.6.1 and 3.5.3) -function PyErr_SetExcFromWindowsErr - added 3.7 # (and 3.6.1 and 3.5.3) - ifdef MS_WINDOWS -function PyErr_SetExcFromWindowsErrWithFilename - added 3.7 # (and 3.6.1 and 3.5.3) - ifdef MS_WINDOWS -function PyErr_SetExcFromWindowsErrWithFilenameObject - added 3.7 # (and 3.6.1 and 3.5.3) - ifdef MS_WINDOWS -function PyErr_SetExcFromWindowsErrWithFilenameObjects - added 3.7 # (and 3.6.1 and 3.5.3) - ifdef MS_WINDOWS -function PyErr_SetFromWindowsErr - added 3.7 # (and 3.6.1 and 3.5.3) - ifdef MS_WINDOWS -function PyErr_SetFromWindowsErrWithFilename - added 3.7 # (and 3.6.1 and 3.5.3) - ifdef MS_WINDOWS -data PyExc_WindowsError - added 3.7 # (and 3.6.1 and 3.5.3) - ifdef MS_WINDOWS -function PyOS_CheckStack - added 3.7 # (and 3.6.1 and 3.5.3) - ifdef USE_STACKCHECK -function PyUnicode_AsMBCSString - added 3.7 # (and 3.6.1 and 3.5.3) - ifdef MS_WINDOWS -function PyUnicode_DecodeCodePageStateful - added 3.7 # (and 3.6.1 and 3.5.3) - ifdef MS_WINDOWS -function PyUnicode_DecodeMBCS - added 3.7 # (and 3.6.1 and 3.5.3) - ifdef MS_WINDOWS -function PyUnicode_DecodeMBCSStateful - added 3.7 # (and 3.6.1 and 3.5.3) - ifdef MS_WINDOWS -function PyUnicode_EncodeCodePage - added 3.7 # (and 3.6.1 and 3.5.3) - ifdef MS_WINDOWS - -# 3.5.4: -function PySlice_AdjustIndices - added 3.7 # (and 3.6.1 and 3.5.4) -function PySlice_Unpack - added 3.7 # (and 3.6.1 and 3.5.4) - -# The following were added in PC/python3.def in Python 3.7: - -function PyInterpreterState_GetID - added 3.7 -function PyThread_tss_alloc - added 3.7 -function PyThread_tss_create - added 3.7 -function PyThread_tss_delete - added 3.7 -function PyThread_tss_free - added 3.7 -function PyThread_tss_get - added 3.7 -function PyThread_tss_is_created - added 3.7 -function PyThread_tss_set - added 3.7 -function PyOS_BeforeFork - added 3.7 - ifdef HAVE_FORK -function PyOS_AfterFork_Parent - added 3.7 - ifdef HAVE_FORK -function PyOS_AfterFork_Child - added 3.7 - ifdef HAVE_FORK - -# New method flags in 3.7 (PEP 590): - -const METH_FASTCALL - added 3.7 -const METH_METHOD - added 3.7 - -# The following were added in PC/python3.def in Python 3.8: - -function PyImport_GetModule - added 3.8 -data Py_UTF8Mode - added 3.8 -function PyExceptionClass_Name - added 3.8 -function PyIndex_Check - added 3.8 -function PyIter_Check - added 3.8 -data PyDictRevIterItem_Type - added 3.8 -data PyDictRevIterKey_Type - added 3.8 -data PyDictRevIterValue_Type - added 3.8 -function PyInterpreterState_GetDict - added 3.8 -function Py_BytesMain - added 3.8 - -# New type flag (PEP 590): - -const Py_TPFLAGS_METHOD_DESCRIPTOR - added 3.8 - -# The following were added in PC/python3.def in Python 3.9: - -function Py_EnterRecursiveCall - added 3.9 -function Py_LeaveRecursiveCall - added 3.9 -function Py_GenericAlias - added 3.9 -data Py_GenericAliasType - added 3.9 -function PyCMethod_New - added 3.9 # Windows: 3.10 & 3.9.2 -- https://bugs.python.org/issue43155 -function PyInterpreterState_Get - added 3.9 -function PyObject_GC_IsFinalized - added 3.9 -function PyObject_GC_IsTracked - added 3.9 - -# The following were added in PC/python3.def in Python 3.10: - -function Py_GetArgcArgv - added 3.10 - abi_only -function PyIter_Send - added 3.10 -function PyUnicode_AsUTF8AndSize - added 3.10 -function PyObject_GenericGetDict - added 3.10 -function Py_NewRef - added 3.10 -function Py_XNewRef - added 3.10 -function PyModule_AddType - added 3.10 -function PyType_FromModuleAndSpec - added 3.10 -function PyType_GetModule - added 3.10 -function PyType_GetModuleState - added 3.10 -function PyFrame_GetLineNumber - added 3.10 -function PyFrame_GetCode - added 3.10 -function PyObject_CallNoArgs - added 3.10 -function PyThreadState_GetFrame - added 3.10 -function PyThreadState_GetID - added 3.10 -function PyThreadState_GetInterpreter - added 3.10 -function PyModule_AddObjectRef - added 3.10 -data Py_FileSystemDefaultEncodeErrors - added 3.10 -function PyCodec_Unregister - added 3.10 -function PyErr_SetInterruptEx - added 3.10 -function Py_Is - added 3.10 -function Py_IsTrue - added 3.10 -function Py_IsFalse - added 3.10 -function Py_IsNone - added 3.10 -function _Py_IncRef - added 3.10 - abi_only -function _Py_DecRef - added 3.10 - abi_only -function PyAIter_Check - added 3.10 -function PyObject_GetAIter - added 3.10 -data PyExc_EncodingWarning - added 3.10 - -# Support for Stable ABI in debug builds - -data _Py_RefTotal - added 3.10 - abi_only - ifdef Py_REF_DEBUG -function _Py_NegativeRefcount - added 3.10 - abi_only - ifdef Py_REF_DEBUG - -# New slots in 3.10: - -const Py_am_send - added 3.10 - - -# New GC control functions in Py3.10 (https://bugs.python.org/issue28254) - -function PyGC_Disable - added 3.10 -function PyGC_Enable - added 3.10 -function PyGC_IsEnabled - added 3.10 - -# Add new C API in Python 3.11 - -function PyType_GetName - added 3.11 -function PyType_GetQualName - added 3.11 -data PyStructSequence_UnnamedField - added 3.11 - -# (Detailed comments aren't really needed for further entries: from here on -# we can use version control logs.) diff --git a/Modules/Setup b/Modules/Setup index d3647ecb995..e3a82975b5f 100644 --- a/Modules/Setup +++ b/Modules/Setup @@ -275,7 +275,7 @@ PYTHONPATH=$(COREPYTHONPATH) #xx xxmodule.c #xxlimited xxlimited.c #xxlimited_35 xxlimited_35.c -xxsubtype xxsubtype.c # Required for the test suite to pass! +#xxsubtype xxsubtype.c # Testing @@ -291,6 +291,7 @@ xxsubtype xxsubtype.c # Required for the test suite to pass! #_testcapi _testcapimodule.c #_testimportmultiple _testimportmultiple.c #_testmultiphase _testmultiphase.c +#_testsinglephase _testsinglephase.c # --- # Uncommenting the following line tells makesetup that all following modules diff --git a/Modules/Setup.bootstrap b/Modules/Setup.bootstrap.in similarity index 93% rename from Modules/Setup.bootstrap rename to Modules/Setup.bootstrap.in index d543f087b89..e3e9b96b063 100644 --- a/Modules/Setup.bootstrap +++ b/Modules/Setup.bootstrap.in @@ -3,6 +3,7 @@ # --- # Built-in modules required to get a functioning interpreter; # cannot be built as shared! +*static* # module C APIs are used in core atexit atexitmodule.c @@ -17,7 +18,7 @@ _collections _collectionsmodule.c errno errnomodule.c _io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c itertools itertoolsmodule.c -_sre _sre.c +_sre _sre/sre.c _thread _threadmodule.c time timemodule.c _weakref _weakref.c @@ -31,4 +32,4 @@ _stat _stat.c _symtable symtablemodule.c # for systems without $HOME env, used by site._getuserbase() -pwd pwdmodule.c +@MODULE_PWD_TRUE@pwd pwdmodule.c diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in index 5e28a72d7a1..d64752e8ca9 100644 --- a/Modules/Setup.stdlib.in +++ b/Modules/Setup.stdlib.in @@ -22,8 +22,8 @@ # Build modules statically or as shared extensions -*shared* -# *static* +# *shared* / *static* +*@MODULE_BUILDTYPE@* ############################################################################ @@ -32,6 +32,7 @@ @MODULE__ASYNCIO_TRUE@_asyncio _asynciomodule.c @MODULE__BISECT_TRUE@_bisect _bisectmodule.c @MODULE__CONTEXTVARS_TRUE@_contextvars _contextvarsmodule.c +@MODULE__CSV_TRUE@_csv _csv.c @MODULE__HEAPQ_TRUE@_heapq _heapqmodule.c @MODULE__JSON_TRUE@_json _json.c @MODULE__LSPROF_TRUE@_lsprof _lsprof.c rotatingtree.c @@ -39,10 +40,13 @@ @MODULE__PICKLE_TRUE@_pickle _pickle.c @MODULE__QUEUE_TRUE@_queue _queuemodule.c @MODULE__RANDOM_TRUE@_random _randommodule.c +@MODULE__STRUCT_TRUE@_struct _struct.c @MODULE__TYPING_TRUE@_typing _typingmodule.c +@MODULE__XXSUBINTERPRETERS_TRUE@_xxsubinterpreters _xxsubinterpretersmodule.c @MODULE__ZONEINFO_TRUE@_zoneinfo _zoneinfo.c # needs libm +@MODULE_AUDIOOP_TRUE@audioop audioop.c @MODULE_MATH_TRUE@math mathmodule.c @MODULE_CMATH_TRUE@cmath cmathmodule.c @MODULE__STATISTICS_TRUE@_statistics _statisticsmodule.c @@ -55,6 +59,22 @@ # with ./configure --with-system-libmpdec @MODULE__DECIMAL_TRUE@_decimal _decimal/_decimal.c +# compression libs and binascii (optional CRC32 from zlib) +# bindings need -lbz2, -lz, or -llzma, respectively +@MODULE_BINASCII_TRUE@binascii binascii.c +@MODULE__BZ2_TRUE@_bz2 _bz2module.c +@MODULE__LZMA_TRUE@_lzma _lzmamodule.c +@MODULE_ZLIB_TRUE@zlib zlibmodule.c + +# dbm/gdbm +# dbm needs either libndbm, libgdbm_compat, or libdb 5.x +@MODULE__DBM_TRUE@_dbm _dbmmodule.c +# gdbm module needs -lgdbm +@MODULE__GDBM_TRUE@_gdbm _gdbmmodule.c + +# needs -lreadline or -ledit, sometimes termcap, termlib, or tinfo +@MODULE_READLINE_TRUE@readline readline.c + # hashing builtins, can be disabled with --without-builtin-hashlib-hashes @MODULE__MD5_TRUE@_md5 md5module.c @MODULE__SHA1_TRUE@_sha1 sha1module.c @@ -87,21 +107,53 @@ # Modules with some UNIX dependencies # +# needs -lcrypt on some systems +@MODULE__CRYPT_TRUE@_crypt _cryptmodule.c +@MODULE_FCNTL_TRUE@fcntl fcntlmodule.c @MODULE_GRP_TRUE@grp grpmodule.c +@MODULE_MMAP_TRUE@mmap mmapmodule.c +# FreeBSD: nis/yp APIs are in libc +# Linux: glibc has deprecated SUN RPC, APIs are in libnsl and libtirpc (bpo-32521) +@MODULE_NIS_TRUE@nis nismodule.c # needs sys/soundcard.h or linux/soundcard.h (Linux, FreeBSD) @MODULE_OSSAUDIODEV_TRUE@ossaudiodev ossaudiodev.c +@MODULE__POSIXSUBPROCESS_TRUE@_posixsubprocess _posixsubprocess.c @MODULE_RESOURCE_TRUE@resource resource.c +@MODULE_SELECT_TRUE@select selectmodule.c +@MODULE__SOCKET_TRUE@_socket socketmodule.c # AIX has shadow passwords, but does not provide getspent API @MODULE_SPWD_TRUE@spwd spwdmodule.c @MODULE_SYSLOG_TRUE@syslog syslogmodule.c @MODULE_TERMIOS_TRUE@termios termios.c +# multiprocessing +@MODULE__POSIXSHMEM_TRUE@_posixshmem _multiprocessing/posixshmem.c +@MODULE__MULTIPROCESSING_TRUE@_multiprocessing _multiprocessing/multiprocessing.c _multiprocessing/semaphore.c + ############################################################################ # Modules with third party dependencies # -@MODULE__SQLITE3_TRUE@_sqlite3 _sqlite/connection.c _sqlite/cursor.c _sqlite/microprotocols.c _sqlite/module.c _sqlite/prepare_protocol.c _sqlite/row.c _sqlite/statement.c _sqlite/util.c +# needs -lffi and -ldl +@MODULE__CTYPES_TRUE@_ctypes _ctypes/_ctypes.c _ctypes/callbacks.c _ctypes/callproc.c _ctypes/stgdict.c _ctypes/cfield.c @MODULE__CTYPES_MALLOC_CLOSURE@ + +# needs -lncurses[w], sometimes -ltermcap/tinfo +@MODULE__CURSES_TRUE@_curses _cursesmodule.c +# needs -lncurses[w] and -lpanel[w] +@MODULE__CURSES_PANEL_TRUE@_curses_panel _curses_panel.c + +@MODULE__SQLITE3_TRUE@_sqlite3 _sqlite/blob.c _sqlite/connection.c _sqlite/cursor.c _sqlite/microprotocols.c _sqlite/module.c _sqlite/prepare_protocol.c _sqlite/row.c _sqlite/statement.c _sqlite/util.c + +# needs -lssl and -lcrypt +@MODULE__SSL_TRUE@_ssl _ssl.c +# needs -lcrypt +@MODULE__HASHLIB_TRUE@_hashlib _hashopenssl.c + +# Linux: -luuid, BSD/AIX: libc's uuid_create() +@MODULE__UUID_TRUE@_uuid _uuidmodule.c + +@MODULE__TKINTER_TRUE@_tkinter _tkinter.c tkappinit.c ############################################################################ # macOS specific modules @@ -113,13 +165,20 @@ ############################################################################ # Test modules +@MODULE_XXSUBTYPE_TRUE@xxsubtype xxsubtype.c @MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c @MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c @MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c +@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/unicode.c _testcapi/getargs.c _testcapi/pytime.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/structmember.c +@MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c # Some testing modules MUST be built as shared libraries. *shared* -@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c @MODULE__TESTIMPORTMULTIPLE_TRUE@_testimportmultiple _testimportmultiple.c @MODULE__TESTMULTIPHASE_TRUE@_testmultiphase _testmultiphase.c +@MODULE__TESTMULTIPHASE_TRUE@_testsinglephase _testsinglephase.c @MODULE__CTYPES_TEST_TRUE@_ctypes_test _ctypes/_ctypes_test.c + +# Limited API template modules; must be built as shared modules. +@MODULE_XXLIMITED_TRUE@xxlimited xxlimited.c +@MODULE_XXLIMITED_35_TRUE@xxlimited_35 xxlimited_35.c diff --git a/Modules/_abc.c b/Modules/_abc.c index b7465c379dd..e146d4fd0ca 100644 --- a/Modules/_abc.c +++ b/Modules/_abc.c @@ -5,6 +5,8 @@ #include "Python.h" #include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_object.h" // _PyType_GetSubclasses() +#include "pycore_runtime.h" // _Py_ID() #include "clinic/_abc.c.h" /*[clinic input] @@ -15,15 +17,6 @@ module _abc PyDoc_STRVAR(_abc__doc__, "Module contains faster C implementation of abc.ABCMeta"); -_Py_IDENTIFIER(__abstractmethods__); -_Py_IDENTIFIER(__class__); -_Py_IDENTIFIER(__dict__); -_Py_IDENTIFIER(__abc_tpflags__); -_Py_IDENTIFIER(__bases__); -_Py_IDENTIFIER(_abc_impl); -_Py_IDENTIFIER(__subclasscheck__); -_Py_IDENTIFIER(__subclasshook__); - typedef struct { PyTypeObject *_abc_data_type; unsigned long long abc_invalidation_counter; @@ -70,6 +63,7 @@ abc_data_clear(_abc_data *self) static void abc_data_dealloc(_abc_data *self) { + PyObject_GC_UnTrack(self); PyTypeObject *tp = Py_TYPE(self); (void)abc_data_clear(self); tp->tp_free(self); @@ -121,7 +115,7 @@ static _abc_data * _get_impl(PyObject *module, PyObject *self) { _abcmodule_state *state = get_abc_state(module); - PyObject *impl = _PyObject_GetAttrId(self, &PyId__abc_impl); + PyObject *impl = PyObject_GetAttr(self, &_Py_ID(_abc_impl)); if (impl == NULL) { return NULL; } @@ -310,7 +304,7 @@ compute_abstract_methods(PyObject *self) PyObject *ns = NULL, *items = NULL, *bases = NULL; // Py_XDECREF()ed on error. /* Stage 1: direct abstract methods. */ - ns = _PyObject_GetAttrId(self, &PyId___dict__); + ns = PyObject_GetAttr(self, &_Py_ID(__dict__)); if (!ns) { goto error; } @@ -354,7 +348,7 @@ compute_abstract_methods(PyObject *self) } /* Stage 2: inherited abstract methods. */ - bases = _PyObject_GetAttrId(self, &PyId___bases__); + bases = PyObject_GetAttr(self, &_Py_ID(__bases__)); if (!bases) { goto error; } @@ -367,8 +361,8 @@ compute_abstract_methods(PyObject *self) PyObject *item = PyTuple_GET_ITEM(bases, pos); // borrowed PyObject *base_abstracts, *iter; - if (_PyObject_LookupAttrId(item, &PyId___abstractmethods__, - &base_abstracts) < 0) { + if (_PyObject_LookupAttr(item, &_Py_ID(__abstractmethods__), + &base_abstracts) < 0) { goto error; } if (base_abstracts == NULL) { @@ -408,7 +402,7 @@ compute_abstract_methods(PyObject *self) } } - if (_PyObject_SetAttrId(self, &PyId___abstractmethods__, abstracts) < 0) { + if (PyObject_SetAttr(self, &_Py_ID(__abstractmethods__), abstracts) < 0) { goto error; } @@ -447,7 +441,7 @@ _abc__abc_init(PyObject *module, PyObject *self) if (data == NULL) { return NULL; } - if (_PyObject_SetAttrId(self, &PyId__abc_impl, data) < 0) { + if (PyObject_SetAttr(self, &_Py_ID(_abc_impl), data) < 0) { Py_DECREF(data); return NULL; } @@ -458,7 +452,8 @@ _abc__abc_init(PyObject *module, PyObject *self) * their special status w.r.t. pattern matching. */ if (PyType_Check(self)) { PyTypeObject *cls = (PyTypeObject *)self; - PyObject *flags = _PyDict_GetItemIdWithError(cls->tp_dict, &PyId___abc_tpflags__); + PyObject *flags = PyDict_GetItemWithError(cls->tp_dict, + &_Py_ID(__abc_tpflags__)); if (flags == NULL) { if (PyErr_Occurred()) { return NULL; @@ -476,7 +471,7 @@ _abc__abc_init(PyObject *module, PyObject *self) } ((PyTypeObject *)self)->tp_flags |= (val & COLLECTION_FLAGS); } - if (_PyDict_DelItemId(cls->tp_dict, &PyId___abc_tpflags__) < 0) { + if (PyDict_DelItem(cls->tp_dict, &_Py_ID(__abc_tpflags__)) < 0) { return NULL; } } @@ -493,21 +488,20 @@ set_collection_flag_recursive(PyTypeObject *child, unsigned long flag) { return; } + child->tp_flags &= ~COLLECTION_FLAGS; child->tp_flags |= flag; - PyObject *grandchildren = child->tp_subclasses; + + PyObject *grandchildren = _PyType_GetSubclasses(child); if (grandchildren == NULL) { return; } - assert(PyDict_CheckExact(grandchildren)); - Py_ssize_t i = 0; - while (PyDict_Next(grandchildren, &i, NULL, &grandchildren)) { - assert(PyWeakref_CheckRef(grandchildren)); - PyObject *grandchild = PyWeakref_GET_OBJECT(grandchildren); - if (PyType_Check(grandchild)) { - set_collection_flag_recursive((PyTypeObject *)grandchild, flag); - } + + for (Py_ssize_t i = 0; i < PyList_GET_SIZE(grandchildren); i++) { + PyObject *grandchild = PyList_GET_ITEM(grandchildren, i); + set_collection_flag_recursive((PyTypeObject *)grandchild, flag); } + Py_DECREF(grandchildren); } /*[clinic input] @@ -530,8 +524,7 @@ _abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass) } int result = PyObject_IsSubclass(subclass, self); if (result > 0) { - Py_INCREF(subclass); - return subclass; /* Already a subclass. */ + return Py_NewRef(subclass); /* Already a subclass. */ } if (result < 0) { return NULL; @@ -567,8 +560,7 @@ _abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass) set_collection_flag_recursive((PyTypeObject *)subclass, collection_flag); } } - Py_INCREF(subclass); - return subclass; + return Py_NewRef(subclass); } @@ -593,7 +585,7 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self, return NULL; } - subclass = _PyObject_GetAttrId(instance, &PyId___class__); + subclass = PyObject_GetAttr(instance, &_Py_ID(__class__)); if (subclass == NULL) { Py_DECREF(impl); return NULL; @@ -604,8 +596,7 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self, goto end; } if (incache > 0) { - result = Py_True; - Py_INCREF(result); + result = Py_NewRef(Py_True); goto end; } subtype = (PyObject *)Py_TYPE(instance); @@ -616,31 +607,29 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self, goto end; } if (incache > 0) { - result = Py_False; - Py_INCREF(result); + result = Py_NewRef(Py_False); goto end; } } /* Fall back to the subclass check. */ - result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__, - subclass); + result = PyObject_CallMethodOneArg(self, &_Py_ID(__subclasscheck__), + subclass); goto end; } - result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__, - subclass); + result = PyObject_CallMethodOneArg(self, &_Py_ID(__subclasscheck__), + subclass); if (result == NULL) { goto end; } switch (PyObject_IsTrue(result)) { case -1: - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); break; case 0: Py_DECREF(result); - result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__, - subtype); + result = PyObject_CallMethodOneArg(self, &_Py_ID(__subclasscheck__), + subtype); break; case 1: // Nothing to do. break; @@ -723,8 +712,8 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self, } /* 3. Check the subclass hook. */ - ok = _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId___subclasshook__, - subclass); + ok = PyObject_CallMethodOneArg( + (PyObject *)self, &_Py_ID(__subclasshook__), subclass); if (ok == NULL) { goto end; } @@ -808,8 +797,7 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self, end: Py_DECREF(impl); Py_XDECREF(subclasses); - Py_XINCREF(result); - return result; + return Py_XNewRef(result); } @@ -848,8 +836,7 @@ subclasscheck_check_registry(_abc_data *impl, PyObject *subclass, Py_ssize_t i = 0; while (_PySet_NextEntry(impl->_abc_registry, &pos, &key, &hash)) { - Py_INCREF(key); - copy[i++] = key; + copy[i++] = Py_NewRef(key); } assert(i == registry_size); diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index df6644ba248..055dded0543 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -5,6 +5,9 @@ #include "Python.h" #include "pycore_pyerrors.h" // _PyErr_ClearExcState() #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_runtime_init.h" // _Py_ID() +#include "pycore_moduleobject.h" // _PyModule_GetState() +#include "structmember.h" // PyMemberDef #include // offsetof() @@ -14,46 +17,80 @@ module _asyncio /*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fd17862aa989c69]*/ -/* identifiers used from some functions */ -_Py_IDENTIFIER(__asyncio_running_event_loop__); -_Py_IDENTIFIER(_asyncio_future_blocking); -_Py_IDENTIFIER(add_done_callback); -_Py_IDENTIFIER(call_soon); -_Py_IDENTIFIER(cancel); -_Py_IDENTIFIER(get_event_loop); -_Py_IDENTIFIER(throw); - - /* State of the _asyncio module */ -static PyObject *asyncio_mod; -static PyObject *traceback_extract_stack; -static PyObject *asyncio_get_event_loop_policy; -static PyObject *asyncio_future_repr_info_func; -static PyObject *asyncio_iscoroutine_func; -static PyObject *asyncio_task_get_stack_func; -static PyObject *asyncio_task_print_stack_func; -static PyObject *asyncio_task_repr_info_func; -static PyObject *asyncio_InvalidStateError; -static PyObject *asyncio_CancelledError; -static PyObject *context_kwname; -static int module_initialized; +typedef struct { + PyTypeObject *FutureIterType; + PyTypeObject *TaskStepMethWrapper_Type; + PyTypeObject *FutureType; + PyTypeObject *TaskType; -static PyObject *cached_running_holder; -static volatile uint64_t cached_running_holder_tsid; + PyObject *asyncio_mod; + PyObject *context_kwname; -/* Counter for autogenerated Task names */ -static uint64_t task_name_counter = 0; + /* Dictionary containing tasks that are currently active in + all running event loops. {EventLoop: Task} */ + PyObject *current_tasks; -/* WeakSet containing all alive tasks. */ -static PyObject *all_tasks; + /* WeakSet containing all alive tasks. */ + PyObject *all_tasks; -/* Dictionary containing tasks that are currently active in - all running event loops. {EventLoop: Task} */ -static PyObject *current_tasks; + /* An isinstance type cache for the 'is_coroutine()' function. */ + PyObject *iscoroutine_typecache; -/* An isinstance type cache for the 'is_coroutine()' function. */ -static PyObject *iscoroutine_typecache; + /* Imports from asyncio.events. */ + PyObject *asyncio_get_event_loop_policy; + /* Imports from asyncio.base_futures. */ + PyObject *asyncio_future_repr_func; + + /* Imports from asyncio.exceptions. */ + PyObject *asyncio_CancelledError; + PyObject *asyncio_InvalidStateError; + + /* Imports from asyncio.base_tasks. */ + PyObject *asyncio_task_get_stack_func; + PyObject *asyncio_task_print_stack_func; + PyObject *asyncio_task_repr_func; + + /* Imports from asyncio.coroutines. */ + PyObject *asyncio_iscoroutine_func; + + /* Imports from traceback. */ + PyObject *traceback_extract_stack; + + PyObject *cached_running_loop; // Borrowed reference + volatile uint64_t cached_running_loop_tsid; + + /* Counter for autogenerated Task names */ + uint64_t task_name_counter; +} asyncio_state; + +static inline asyncio_state * +get_asyncio_state(PyObject *mod) +{ + asyncio_state *state = _PyModule_GetState(mod); + assert(state != NULL); + return state; +} + +static inline asyncio_state * +get_asyncio_state_by_cls(PyTypeObject *cls) +{ + asyncio_state *state = (asyncio_state *)PyType_GetModuleState(cls); + assert(state != NULL); + return state; +} + +static struct PyModuleDef _asynciomodule; + +static inline asyncio_state * +get_asyncio_state_by_def(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject *mod = PyType_GetModuleByDef(tp, &_asynciomodule); + assert(mod != NULL); + return get_asyncio_state(mod); +} typedef enum { STATE_PENDING, @@ -68,6 +105,7 @@ typedef enum { PyObject *prefix##_context0; \ PyObject *prefix##_callbacks; \ PyObject *prefix##_exception; \ + PyObject *prefix##_exception_tb; \ PyObject *prefix##_result; \ PyObject *prefix##_source_tb; \ PyObject *prefix##_cancel_msg; \ @@ -76,7 +114,7 @@ typedef enum { int prefix##_blocking; \ PyObject *dict; \ PyObject *prefix##_weakreflist; \ - _PyErr_StackItem prefix##_cancelled_exc_state; + PyObject *prefix##_cancelled_exc; typedef struct { FutureObj_HEAD(fut) @@ -90,6 +128,7 @@ typedef struct { PyObject *task_context; int task_must_cancel; int task_log_destroy_pending; + int task_num_cancels_requested; } TaskObj; typedef struct { @@ -98,25 +137,12 @@ typedef struct { PyObject *sw_arg; } TaskStepMethWrapper; -typedef struct { - PyObject_HEAD - PyObject *rl_loop; -#if defined(HAVE_GETPID) && !defined(MS_WINDOWS) - pid_t rl_pid; -#endif -} PyRunningLoopHolder; +#define Future_CheckExact(state, obj) Py_IS_TYPE(obj, state->FutureType) +#define Task_CheckExact(state, obj) Py_IS_TYPE(obj, state->TaskType) -static PyTypeObject FutureType; -static PyTypeObject TaskType; -static PyTypeObject PyRunningLoopHolder_Type; - - -#define Future_CheckExact(obj) Py_IS_TYPE(obj, &FutureType) -#define Task_CheckExact(obj) Py_IS_TYPE(obj, &TaskType) - -#define Future_Check(obj) PyObject_TypeCheck(obj, &FutureType) -#define Task_Check(obj) PyObject_TypeCheck(obj, &TaskType) +#define Future_Check(state, obj) PyObject_TypeCheck(obj, state->FutureType) +#define Task_Check(state, obj) PyObject_TypeCheck(obj, state->TaskType) #include "clinic/_asynciomodule.c.h" @@ -130,11 +156,9 @@ class _asyncio.Future "FutureObj *" "&Future_Type" /* Get FutureIter from Future */ static PyObject * future_new_iter(PyObject *); -static PyRunningLoopHolder * new_running_loop_holder(PyObject *); - static int -_is_coroutine(PyObject *coro) +_is_coroutine(asyncio_state *state, PyObject *coro) { /* 'coro' is not a native coroutine, call asyncio.iscoroutine() to check if it's another coroutine flavour. @@ -142,7 +166,7 @@ _is_coroutine(PyObject *coro) Do this check after 'future_init()'; in case we need to raise an error, __del__ needs a properly initialized object. */ - PyObject *res = PyObject_CallOneArg(asyncio_iscoroutine_func, coro); + PyObject *res = PyObject_CallOneArg(state->asyncio_iscoroutine_func, coro); if (res == NULL) { return -1; } @@ -153,12 +177,12 @@ _is_coroutine(PyObject *coro) return is_res_true; } - if (PySet_GET_SIZE(iscoroutine_typecache) < 100) { + if (PySet_GET_SIZE(state->iscoroutine_typecache) < 100) { /* Just in case we don't want to cache more than 100 positive types. That shouldn't ever happen, unless someone stressing the system on purpose. */ - if (PySet_Add(iscoroutine_typecache, (PyObject*) Py_TYPE(coro))) { + if (PySet_Add(state->iscoroutine_typecache, (PyObject*) Py_TYPE(coro))) { return -1; } } @@ -168,7 +192,7 @@ _is_coroutine(PyObject *coro) static inline int -is_coroutine(PyObject *coro) +is_coroutine(asyncio_state *state, PyObject *coro) { if (PyCoro_CheckExact(coro)) { return 1; @@ -184,10 +208,10 @@ is_coroutine(PyObject *coro) a pure-Python function in 99.9% cases. */ int has_it = PySet_Contains( - iscoroutine_typecache, (PyObject*) Py_TYPE(coro)); + state->iscoroutine_typecache, (PyObject*) Py_TYPE(coro)); if (has_it == 0) { /* type(coro) is not in iscoroutine_typecache */ - return _is_coroutine(coro); + return _is_coroutine(state, coro); } /* either an error has occurred or @@ -198,21 +222,18 @@ is_coroutine(PyObject *coro) static PyObject * -get_future_loop(PyObject *fut) +get_future_loop(asyncio_state *state, PyObject *fut) { /* Implementation of `asyncio.futures._get_loop` */ - _Py_IDENTIFIER(get_loop); - _Py_IDENTIFIER(_loop); PyObject *getloop; - if (Future_CheckExact(fut) || Task_CheckExact(fut)) { + if (Future_CheckExact(state, fut) || Task_CheckExact(state, fut)) { PyObject *loop = ((FutureObj *)fut)->fut_loop; - Py_INCREF(loop); - return loop; + return Py_NewRef(loop); } - if (_PyObject_LookupAttrId(fut, &PyId_get_loop, &getloop) < 0) { + if (_PyObject_LookupAttr(fut, &_Py_ID(get_loop), &getloop) < 0) { return NULL; } if (getloop != NULL) { @@ -221,20 +242,22 @@ get_future_loop(PyObject *fut) return res; } - return _PyObject_GetAttrId(fut, &PyId__loop); + return PyObject_GetAttr(fut, &_Py_ID(_loop)); } static int -get_running_loop(PyObject **loop) +get_running_loop(asyncio_state *state, PyObject **loop) { PyObject *rl; PyThreadState *ts = _PyThreadState_GET(); uint64_t ts_id = PyThreadState_GetID(ts); - if (ts_id == cached_running_holder_tsid && cached_running_holder != NULL) { + if (state->cached_running_loop_tsid == ts_id && + state->cached_running_loop != NULL) + { // Fast path, check the cache. - rl = cached_running_holder; // borrowed + rl = state->cached_running_loop; } else { PyObject *ts_dict = _PyThreadState_GetDict(ts); // borrowed @@ -242,8 +265,8 @@ get_running_loop(PyObject **loop) goto not_found; } - rl = _PyDict_GetItemIdWithError( - ts_dict, &PyId___asyncio_running_event_loop__); // borrowed + rl = PyDict_GetItemWithError( + ts_dict, &_Py_ID(__asyncio_running_event_loop__)); // borrowed if (rl == NULL) { if (PyErr_Occurred()) { goto error; @@ -253,28 +276,16 @@ get_running_loop(PyObject **loop) } } - cached_running_holder = rl; // borrowed - cached_running_holder_tsid = ts_id; + state->cached_running_loop = rl; + state->cached_running_loop_tsid = ts_id; } - assert(Py_IS_TYPE(rl, &PyRunningLoopHolder_Type)); - PyObject *running_loop = ((PyRunningLoopHolder *)rl)->rl_loop; - if (running_loop == Py_None) { + if (rl == Py_None) { goto not_found; } -#if defined(HAVE_GETPID) && !defined(MS_WINDOWS) - /* On Windows there is no getpid, but there is also no os.fork(), - so there is no need for this check. - */ - if (getpid() != ((PyRunningLoopHolder *)rl)->rl_pid) { - goto not_found; - } -#endif - - Py_INCREF(running_loop); - *loop = running_loop; + *loop = Py_NewRef(rl); return 0; not_found: @@ -288,7 +299,7 @@ error: static int -set_running_loop(PyObject *loop) +set_running_loop(asyncio_state *state, PyObject *loop) { PyObject *ts_dict = NULL; @@ -302,73 +313,59 @@ set_running_loop(PyObject *loop) PyExc_RuntimeError, "thread-local storage is not available"); return -1; } - - PyRunningLoopHolder *rl = new_running_loop_holder(loop); - if (rl == NULL) { - return -1; - } - - if (_PyDict_SetItemId( - ts_dict, &PyId___asyncio_running_event_loop__, (PyObject *)rl) < 0) + if (PyDict_SetItem( + ts_dict, &_Py_ID(__asyncio_running_event_loop__), loop) < 0) { - Py_DECREF(rl); // will cleanup loop & current_pid return -1; } - Py_DECREF(rl); - cached_running_holder = (PyObject *)rl; - cached_running_holder_tsid = PyThreadState_GetID(tstate); + state->cached_running_loop = loop; // borrowed, kept alive by ts_dict + state->cached_running_loop_tsid = PyThreadState_GetID(tstate); return 0; } static PyObject * -get_event_loop(int stacklevel) +get_event_loop(asyncio_state *state) { PyObject *loop; PyObject *policy; - if (get_running_loop(&loop)) { + if (get_running_loop(state, &loop)) { return NULL; } if (loop != NULL) { return loop; } - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "There is no current event loop", - stacklevel)) - { - return NULL; - } - - policy = PyObject_CallNoArgs(asyncio_get_event_loop_policy); + policy = PyObject_CallNoArgs(state->asyncio_get_event_loop_policy); if (policy == NULL) { return NULL; } - loop = _PyObject_CallMethodIdNoArgs(policy, &PyId_get_event_loop); + loop = PyObject_CallMethodNoArgs(policy, &_Py_ID(get_event_loop)); Py_DECREF(policy); return loop; } static int -call_soon(PyObject *loop, PyObject *func, PyObject *arg, PyObject *ctx) +call_soon(asyncio_state *state, PyObject *loop, PyObject *func, PyObject *arg, + PyObject *ctx) { PyObject *handle; PyObject *stack[3]; Py_ssize_t nargs; if (ctx == NULL) { - handle = _PyObject_CallMethodIdObjArgs( - loop, &PyId_call_soon, func, arg, NULL); + handle = PyObject_CallMethodObjArgs( + loop, &_Py_ID(call_soon), func, arg, NULL); } else { /* Use FASTCALL to pass a keyword-only argument to call_soon */ - PyObject *callable = _PyObject_GetAttrId(loop, &PyId_call_soon); + PyObject *callable = PyObject_GetAttr(loop, &_Py_ID(call_soon)); if (callable == NULL) { return -1; } @@ -381,8 +378,9 @@ call_soon(PyObject *loop, PyObject *func, PyObject *arg, PyObject *ctx) nargs++; } stack[nargs] = (PyObject *)ctx; - - handle = PyObject_Vectorcall(callable, stack, nargs, context_kwname); + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, callable); + handle = PyObject_Vectorcall(callable, stack, nargs, + state->context_kwname); Py_DECREF(callable); } @@ -413,17 +411,18 @@ future_ensure_alive(FutureObj *fut) } -#define ENSURE_FUTURE_ALIVE(fut) \ - do { \ - assert(Future_Check(fut) || Task_Check(fut)); \ - if (future_ensure_alive((FutureObj*)fut)) { \ - return NULL; \ - } \ +#define ENSURE_FUTURE_ALIVE(state, fut) \ + do { \ + assert(Future_Check(state, fut) || Task_Check(state, fut)); \ + (void)state; \ + if (future_ensure_alive((FutureObj*)fut)) { \ + return NULL; \ + } \ } while(0); static int -future_schedule_callbacks(FutureObj *fut) +future_schedule_callbacks(asyncio_state *state, FutureObj *fut) { Py_ssize_t len; Py_ssize_t i; @@ -431,7 +430,7 @@ future_schedule_callbacks(FutureObj *fut) if (fut->fut_callback0 != NULL) { /* There's a 1st callback */ - int ret = call_soon( + int ret = call_soon(state, fut->fut_loop, fut->fut_callback0, (PyObject *)fut, fut->fut_context0); @@ -465,7 +464,7 @@ future_schedule_callbacks(FutureObj *fut) PyObject *cb = PyTuple_GET_ITEM(cb_tup, 0); PyObject *ctx = PyTuple_GET_ITEM(cb_tup, 1); - if (call_soon(fut->fut_loop, cb, (PyObject *)fut, ctx)) { + if (call_soon(state, fut->fut_loop, cb, (PyObject *)fut, ctx)) { /* If an error occurs in pure-Python implementation, all callbacks are cleared. */ Py_CLEAR(fut->fut_callbacks); @@ -483,7 +482,6 @@ future_init(FutureObj *fut, PyObject *loop) { PyObject *res; int is_true; - _Py_IDENTIFIER(get_debug); // Same to FutureObj_clear() but not clearing fut->dict Py_CLEAR(fut->fut_loop); @@ -492,16 +490,18 @@ future_init(FutureObj *fut, PyObject *loop) Py_CLEAR(fut->fut_callbacks); Py_CLEAR(fut->fut_result); Py_CLEAR(fut->fut_exception); + Py_CLEAR(fut->fut_exception_tb); Py_CLEAR(fut->fut_source_tb); Py_CLEAR(fut->fut_cancel_msg); - _PyErr_ClearExcState(&fut->fut_cancelled_exc_state); + Py_CLEAR(fut->fut_cancelled_exc); fut->fut_state = STATE_PENDING; fut->fut_log_tb = 0; fut->fut_blocking = 0; if (loop == Py_None) { - loop = get_event_loop(1); + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); + loop = get_event_loop(state); if (loop == NULL) { return -1; } @@ -511,7 +511,7 @@ future_init(FutureObj *fut, PyObject *loop) } fut->fut_loop = loop; - res = _PyObject_CallMethodIdNoArgs(fut->fut_loop, &PyId_get_debug); + res = PyObject_CallMethodNoArgs(fut->fut_loop, &_Py_ID(get_debug)); if (res == NULL) { return -1; } @@ -527,7 +527,8 @@ future_init(FutureObj *fut, PyObject *loop) method, which is called during the interpreter shutdown and the traceback module is already unloaded. */ - fut->fut_source_tb = PyObject_CallNoArgs(traceback_extract_stack); + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); + fut->fut_source_tb = PyObject_CallNoArgs(state->traceback_extract_stack); if (fut->fut_source_tb == NULL) { return -1; } @@ -537,35 +538,34 @@ future_init(FutureObj *fut, PyObject *loop) } static PyObject * -future_set_result(FutureObj *fut, PyObject *res) +future_set_result(asyncio_state *state, FutureObj *fut, PyObject *res) { if (future_ensure_alive(fut)) { return NULL; } if (fut->fut_state != STATE_PENDING) { - PyErr_SetString(asyncio_InvalidStateError, "invalid state"); + PyErr_SetString(state->asyncio_InvalidStateError, "invalid state"); return NULL; } assert(!fut->fut_result); - Py_INCREF(res); - fut->fut_result = res; + fut->fut_result = Py_NewRef(res); fut->fut_state = STATE_FINISHED; - if (future_schedule_callbacks(fut) == -1) { + if (future_schedule_callbacks(state, fut) == -1) { return NULL; } Py_RETURN_NONE; } static PyObject * -future_set_exception(FutureObj *fut, PyObject *exc) +future_set_exception(asyncio_state *state, FutureObj *fut, PyObject *exc) { PyObject *exc_val = NULL; if (fut->fut_state != STATE_PENDING) { - PyErr_SetString(asyncio_InvalidStateError, "invalid state"); + PyErr_SetString(state->asyncio_InvalidStateError, "invalid state"); return NULL; } @@ -576,13 +576,12 @@ future_set_exception(FutureObj *fut, PyObject *exc) } if (fut->fut_state != STATE_PENDING) { Py_DECREF(exc_val); - PyErr_SetString(asyncio_InvalidStateError, "invalid state"); + PyErr_SetString(state->asyncio_InvalidStateError, "invalid state"); return NULL; } } else { - exc_val = exc; - Py_INCREF(exc_val); + exc_val = Py_NewRef(exc); } if (!PyExceptionInstance_Check(exc_val)) { Py_DECREF(exc_val); @@ -598,10 +597,12 @@ future_set_exception(FutureObj *fut, PyObject *exc) } assert(!fut->fut_exception); + assert(!fut->fut_exception_tb); fut->fut_exception = exc_val; + fut->fut_exception_tb = PyException_GetTraceback(exc_val); fut->fut_state = STATE_FINISHED; - if (future_schedule_callbacks(fut) == -1) { + if (future_schedule_callbacks(state, fut) == -1) { return NULL; } @@ -610,54 +611,70 @@ future_set_exception(FutureObj *fut, PyObject *exc) } static PyObject * -create_cancelled_error(PyObject *msg) +create_cancelled_error(asyncio_state *state, FutureObj *fut) { PyObject *exc; + if (fut->fut_cancelled_exc != NULL) { + /* transfer ownership */ + exc = fut->fut_cancelled_exc; + fut->fut_cancelled_exc = NULL; + return exc; + } + PyObject *msg = fut->fut_cancel_msg; if (msg == NULL || msg == Py_None) { - exc = PyObject_CallNoArgs(asyncio_CancelledError); + exc = PyObject_CallNoArgs(state->asyncio_CancelledError); } else { - exc = PyObject_CallOneArg(asyncio_CancelledError, msg); + exc = PyObject_CallOneArg(state->asyncio_CancelledError, msg); } return exc; } static void -future_set_cancelled_error(FutureObj *fut) +future_set_cancelled_error(asyncio_state *state, FutureObj *fut) { - PyObject *exc = create_cancelled_error(fut->fut_cancel_msg); - PyErr_SetObject(asyncio_CancelledError, exc); + PyObject *exc = create_cancelled_error(state, fut); + if (exc == NULL) { + return; + } + PyErr_SetObject(state->asyncio_CancelledError, exc); Py_DECREF(exc); - - _PyErr_ChainStackItem(&fut->fut_cancelled_exc_state); } static int -future_get_result(FutureObj *fut, PyObject **result) +future_get_result(asyncio_state *state, FutureObj *fut, PyObject **result) { if (fut->fut_state == STATE_CANCELLED) { - future_set_cancelled_error(fut); + future_set_cancelled_error(state, fut); return -1; } if (fut->fut_state != STATE_FINISHED) { - PyErr_SetString(asyncio_InvalidStateError, "Result is not set."); + PyErr_SetString(state->asyncio_InvalidStateError, + "Result is not set."); return -1; } fut->fut_log_tb = 0; if (fut->fut_exception != NULL) { - Py_INCREF(fut->fut_exception); - *result = fut->fut_exception; + PyObject *tb = fut->fut_exception_tb; + if (tb == NULL) { + tb = Py_None; + } + if (PyException_SetTraceback(fut->fut_exception, tb) < 0) { + return -1; + } + *result = Py_NewRef(fut->fut_exception); + Py_CLEAR(fut->fut_exception_tb); return 1; } - Py_INCREF(fut->fut_result); - *result = fut->fut_result; + *result = Py_NewRef(fut->fut_result); return 0; } static PyObject * -future_add_done_callback(FutureObj *fut, PyObject *arg, PyObject *ctx) +future_add_done_callback(asyncio_state *state, FutureObj *fut, PyObject *arg, + PyObject *ctx) { if (!future_is_alive(fut)) { PyErr_SetString(PyExc_RuntimeError, "uninitialized Future object"); @@ -667,7 +684,7 @@ future_add_done_callback(FutureObj *fut, PyObject *arg, PyObject *ctx) if (fut->fut_state != STATE_PENDING) { /* The future is done/cancelled, so schedule the callback right away. */ - if (call_soon(fut->fut_loop, arg, (PyObject*) fut, ctx)) { + if (call_soon(state, fut->fut_loop, arg, (PyObject*) fut, ctx)) { return NULL; } } @@ -694,10 +711,8 @@ future_add_done_callback(FutureObj *fut, PyObject *arg, PyObject *ctx) */ if (fut->fut_callbacks == NULL && fut->fut_callback0 == NULL) { - Py_INCREF(arg); - fut->fut_callback0 = arg; - Py_INCREF(ctx); - fut->fut_context0 = ctx; + fut->fut_callback0 = Py_NewRef(arg); + fut->fut_context0 = Py_NewRef(ctx); } else { PyObject *tup = PyTuple_New(2); @@ -733,7 +748,7 @@ future_add_done_callback(FutureObj *fut, PyObject *arg, PyObject *ctx) } static PyObject * -future_cancel(FutureObj *fut, PyObject *msg) +future_cancel(asyncio_state *state, FutureObj *fut, PyObject *msg) { fut->fut_log_tb = 0; @@ -745,7 +760,7 @@ future_cancel(FutureObj *fut, PyObject *msg) Py_XINCREF(msg); Py_XSETREF(fut->fut_cancel_msg, msg); - if (future_schedule_callbacks(fut) == -1) { + if (future_schedule_callbacks(state, fut) == -1) { return NULL; } @@ -789,9 +804,10 @@ FutureObj_clear(FutureObj *fut) Py_CLEAR(fut->fut_callbacks); Py_CLEAR(fut->fut_result); Py_CLEAR(fut->fut_exception); + Py_CLEAR(fut->fut_exception_tb); Py_CLEAR(fut->fut_source_tb); Py_CLEAR(fut->fut_cancel_msg); - _PyErr_ClearExcState(&fut->fut_cancelled_exc_state); + Py_CLEAR(fut->fut_cancelled_exc); Py_CLEAR(fut->dict); return 0; } @@ -799,21 +815,18 @@ FutureObj_clear(FutureObj *fut) static int FutureObj_traverse(FutureObj *fut, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(fut)); Py_VISIT(fut->fut_loop); Py_VISIT(fut->fut_callback0); Py_VISIT(fut->fut_context0); Py_VISIT(fut->fut_callbacks); Py_VISIT(fut->fut_result); Py_VISIT(fut->fut_exception); + Py_VISIT(fut->fut_exception_tb); Py_VISIT(fut->fut_source_tb); Py_VISIT(fut->fut_cancel_msg); + Py_VISIT(fut->fut_cancelled_exc); Py_VISIT(fut->dict); - - _PyErr_StackItem *exc_state = &fut->fut_cancelled_exc_state; - Py_VISIT(exc_state->exc_type); - Py_VISIT(exc_state->exc_value); - Py_VISIT(exc_state->exc_traceback); - return 0; } @@ -831,15 +844,16 @@ static PyObject * _asyncio_Future_result_impl(FutureObj *self) /*[clinic end generated code: output=f35f940936a4b1e5 input=49ecf9cf5ec50dc5]*/ { + asyncio_state *state = get_asyncio_state_by_def((PyObject *)self); PyObject *result; if (!future_is_alive(self)) { - PyErr_SetString(asyncio_InvalidStateError, + PyErr_SetString(state->asyncio_InvalidStateError, "Future object is not initialized."); return NULL; } - int res = future_get_result(self, &result); + int res = future_get_result(state, self, &result); if (res == -1) { return NULL; @@ -859,6 +873,9 @@ _asyncio_Future_result_impl(FutureObj *self) /*[clinic input] _asyncio.Future.exception + cls: defining_class + / + Return the exception that was set on this future. The exception (or None if no exception was set) is returned only if @@ -868,29 +885,32 @@ InvalidStateError. [clinic start generated code]*/ static PyObject * -_asyncio_Future_exception_impl(FutureObj *self) -/*[clinic end generated code: output=88b20d4f855e0710 input=733547a70c841c68]*/ +_asyncio_Future_exception_impl(FutureObj *self, PyTypeObject *cls) +/*[clinic end generated code: output=ce75576b187c905b input=3faf15c22acdb60d]*/ { if (!future_is_alive(self)) { - PyErr_SetString(asyncio_InvalidStateError, + asyncio_state *state = get_asyncio_state_by_cls(cls); + PyErr_SetString(state->asyncio_InvalidStateError, "Future object is not initialized."); return NULL; } if (self->fut_state == STATE_CANCELLED) { - future_set_cancelled_error(self); + asyncio_state *state = get_asyncio_state_by_cls(cls); + future_set_cancelled_error(state, self); return NULL; } if (self->fut_state != STATE_FINISHED) { - PyErr_SetString(asyncio_InvalidStateError, "Exception is not set."); + asyncio_state *state = get_asyncio_state_by_cls(cls); + PyErr_SetString(state->asyncio_InvalidStateError, + "Exception is not set."); return NULL; } if (self->fut_exception != NULL) { self->fut_log_tb = 0; - Py_INCREF(self->fut_exception); - return self->fut_exception; + return Py_NewRef(self->fut_exception); } Py_RETURN_NONE; @@ -899,6 +919,7 @@ _asyncio_Future_exception_impl(FutureObj *self) /*[clinic input] _asyncio.Future.set_result + cls: defining_class result: object / @@ -909,16 +930,19 @@ InvalidStateError. [clinic start generated code]*/ static PyObject * -_asyncio_Future_set_result(FutureObj *self, PyObject *result) -/*[clinic end generated code: output=1ec2e6bcccd6f2ce input=8b75172c2a7b05f1]*/ +_asyncio_Future_set_result_impl(FutureObj *self, PyTypeObject *cls, + PyObject *result) +/*[clinic end generated code: output=99afbbe78f99c32d input=d5a41c1e353acc2e]*/ { - ENSURE_FUTURE_ALIVE(self) - return future_set_result(self, result); + asyncio_state *state = get_asyncio_state_by_cls(cls); + ENSURE_FUTURE_ALIVE(state, self) + return future_set_result(state, self, result); } /*[clinic input] _asyncio.Future.set_exception + cls: defining_class exception: object / @@ -929,16 +953,19 @@ InvalidStateError. [clinic start generated code]*/ static PyObject * -_asyncio_Future_set_exception(FutureObj *self, PyObject *exception) -/*[clinic end generated code: output=f1c1b0cd321be360 input=e45b7d7aa71cc66d]*/ +_asyncio_Future_set_exception_impl(FutureObj *self, PyTypeObject *cls, + PyObject *exception) +/*[clinic end generated code: output=0a5e8b5a52f058d6 input=a245cd49d3df939b]*/ { - ENSURE_FUTURE_ALIVE(self) - return future_set_exception(self, exception); + asyncio_state *state = get_asyncio_state_by_cls(cls); + ENSURE_FUTURE_ALIVE(state, self) + return future_set_exception(state, self, exception); } /*[clinic input] _asyncio.Future.add_done_callback + cls: defining_class fn: object / * @@ -952,25 +979,27 @@ scheduled with call_soon. [clinic start generated code]*/ static PyObject * -_asyncio_Future_add_done_callback_impl(FutureObj *self, PyObject *fn, - PyObject *context) -/*[clinic end generated code: output=7ce635bbc9554c1e input=15ab0693a96e9533]*/ +_asyncio_Future_add_done_callback_impl(FutureObj *self, PyTypeObject *cls, + PyObject *fn, PyObject *context) +/*[clinic end generated code: output=922e9a4cbd601167 input=599261c521458cc2]*/ { + asyncio_state *state = get_asyncio_state_by_cls(cls); if (context == NULL) { context = PyContext_CopyCurrent(); if (context == NULL) { return NULL; } - PyObject *res = future_add_done_callback(self, fn, context); + PyObject *res = future_add_done_callback(state, self, fn, context); Py_DECREF(context); return res; } - return future_add_done_callback(self, fn, context); + return future_add_done_callback(state, self, fn, context); } /*[clinic input] _asyncio.Future.remove_done_callback + cls: defining_class fn: object / @@ -980,14 +1009,16 @@ Returns the number of callbacks removed. [clinic start generated code]*/ static PyObject * -_asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn) -/*[clinic end generated code: output=5ab1fb52b24ef31f input=0a43280a149d505b]*/ +_asyncio_Future_remove_done_callback_impl(FutureObj *self, PyTypeObject *cls, + PyObject *fn) +/*[clinic end generated code: output=2da35ccabfe41b98 input=c7518709b86fc747]*/ { PyObject *newlist; Py_ssize_t len, i, j=0; Py_ssize_t cleared_callback0 = 0; - ENSURE_FUTURE_ALIVE(self) + asyncio_state *state = get_asyncio_state_by_cls(cls); + ENSURE_FUTURE_ALIVE(state, self) if (self->fut_callback0 != NULL) { int cmp = PyObject_RichCompareBool(self->fut_callback0, fn, Py_EQ); @@ -1033,7 +1064,11 @@ _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn) return NULL; } - for (i = 0; i < PyList_GET_SIZE(self->fut_callbacks); i++) { + // Beware: PyObject_RichCompareBool below may change fut_callbacks. + // See GH-97592. + for (i = 0; + self->fut_callbacks != NULL && i < PyList_GET_SIZE(self->fut_callbacks); + i++) { int ret; PyObject *item = PyList_GET_ITEM(self->fut_callbacks, i); Py_INCREF(item); @@ -1052,7 +1087,8 @@ _asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn) } } - if (j == 0) { + // Note: fut_callbacks may have been cleared. + if (j == 0 || self->fut_callbacks == NULL) { Py_CLEAR(self->fut_callbacks); Py_DECREF(newlist); return PyLong_FromSsize_t(len + cleared_callback0); @@ -1079,6 +1115,8 @@ fail: /*[clinic input] _asyncio.Future.cancel + cls: defining_class + / msg: object = None Cancel the future and schedule callbacks. @@ -1089,11 +1127,13 @@ return True. [clinic start generated code]*/ static PyObject * -_asyncio_Future_cancel_impl(FutureObj *self, PyObject *msg) -/*[clinic end generated code: output=3edebbc668e5aba3 input=925eb545251f2c5a]*/ +_asyncio_Future_cancel_impl(FutureObj *self, PyTypeObject *cls, + PyObject *msg) +/*[clinic end generated code: output=074956f35904b034 input=bba8f8b786941a94]*/ { - ENSURE_FUTURE_ALIVE(self) - return future_cancel(self, msg); + asyncio_state *state = get_asyncio_state_by_cls(cls); + ENSURE_FUTURE_ALIVE(state, self) + return future_cancel(state, self, msg); } /*[clinic input] @@ -1138,16 +1178,19 @@ _asyncio_Future_done_impl(FutureObj *self) /*[clinic input] _asyncio.Future.get_loop + cls: defining_class + / + Return the event loop the Future is bound to. [clinic start generated code]*/ static PyObject * -_asyncio_Future_get_loop_impl(FutureObj *self) -/*[clinic end generated code: output=119b6ea0c9816c3f input=cba48c2136c79d1f]*/ +_asyncio_Future_get_loop_impl(FutureObj *self, PyTypeObject *cls) +/*[clinic end generated code: output=f50ea6c374d9ee97 input=163c2c498b45a1f0]*/ { - ENSURE_FUTURE_ALIVE(self) - Py_INCREF(self->fut_loop); - return self->fut_loop; + asyncio_state *state = get_asyncio_state_by_cls(cls); + ENSURE_FUTURE_ALIVE(state, self) + return Py_NewRef(self->fut_loop); } static PyObject * @@ -1183,7 +1226,8 @@ FutureObj_set_blocking(FutureObj *fut, PyObject *val, void *Py_UNUSED(ignored)) static PyObject * FutureObj_get_log_traceback(FutureObj *fut, void *Py_UNUSED(ignored)) { - ENSURE_FUTURE_ALIVE(fut) + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); + ENSURE_FUTURE_ALIVE(state, fut) if (fut->fut_log_tb) { Py_RETURN_TRUE; } @@ -1218,24 +1262,23 @@ FutureObj_get_loop(FutureObj *fut, void *Py_UNUSED(ignored)) if (!future_is_alive(fut)) { Py_RETURN_NONE; } - Py_INCREF(fut->fut_loop); - return fut->fut_loop; + return Py_NewRef(fut->fut_loop); } static PyObject * FutureObj_get_callbacks(FutureObj *fut, void *Py_UNUSED(ignored)) { + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); Py_ssize_t i; - ENSURE_FUTURE_ALIVE(fut) + ENSURE_FUTURE_ALIVE(state, fut) if (fut->fut_callback0 == NULL) { if (fut->fut_callbacks == NULL) { Py_RETURN_NONE; } - Py_INCREF(fut->fut_callbacks); - return fut->fut_callbacks; + return Py_NewRef(fut->fut_callbacks); } Py_ssize_t len = 1; @@ -1277,23 +1320,23 @@ FutureObj_get_callbacks(FutureObj *fut, void *Py_UNUSED(ignored)) static PyObject * FutureObj_get_result(FutureObj *fut, void *Py_UNUSED(ignored)) { - ENSURE_FUTURE_ALIVE(fut) + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); + ENSURE_FUTURE_ALIVE(state, fut) if (fut->fut_result == NULL) { Py_RETURN_NONE; } - Py_INCREF(fut->fut_result); - return fut->fut_result; + return Py_NewRef(fut->fut_result); } static PyObject * FutureObj_get_exception(FutureObj *fut, void *Py_UNUSED(ignored)) { - ENSURE_FUTURE_ALIVE(fut) + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); + ENSURE_FUTURE_ALIVE(state, fut) if (fut->fut_exception == NULL) { Py_RETURN_NONE; } - Py_INCREF(fut->fut_exception); - return fut->fut_exception; + return Py_NewRef(fut->fut_exception); } static PyObject * @@ -1302,8 +1345,7 @@ FutureObj_get_source_traceback(FutureObj *fut, void *Py_UNUSED(ignored)) if (!future_is_alive(fut) || fut->fut_source_tb == NULL) { Py_RETURN_NONE; } - Py_INCREF(fut->fut_source_tb); - return fut->fut_source_tb; + return Py_NewRef(fut->fut_source_tb); } static PyObject * @@ -1312,8 +1354,7 @@ FutureObj_get_cancel_message(FutureObj *fut, void *Py_UNUSED(ignored)) if (fut->fut_cancel_msg == NULL) { Py_RETURN_NONE; } - Py_INCREF(fut->fut_cancel_msg); - return fut->fut_cancel_msg; + return Py_NewRef(fut->fut_cancel_msg); } static int @@ -1332,28 +1373,33 @@ FutureObj_set_cancel_message(FutureObj *fut, PyObject *msg, static PyObject * FutureObj_get_state(FutureObj *fut, void *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(PENDING); - _Py_IDENTIFIER(CANCELLED); - _Py_IDENTIFIER(FINISHED); + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); PyObject *ret = NULL; - ENSURE_FUTURE_ALIVE(fut) + ENSURE_FUTURE_ALIVE(state, fut) switch (fut->fut_state) { case STATE_PENDING: - ret = _PyUnicode_FromId(&PyId_PENDING); + ret = &_Py_ID(PENDING); break; case STATE_CANCELLED: - ret = _PyUnicode_FromId(&PyId_CANCELLED); + ret = &_Py_ID(CANCELLED); break; case STATE_FINISHED: - ret = _PyUnicode_FromId(&PyId_FINISHED); + ret = &_Py_ID(FINISHED); break; default: assert (0); } - Py_XINCREF(ret); - return ret; + return Py_XNewRef(ret); +} + +static PyObject * +FutureObj_repr(FutureObj *fut) +{ + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); + ENSURE_FUTURE_ALIVE(state, fut) + return PyObject_CallOneArg(state->asyncio_future_repr_func, (PyObject *)fut); } /*[clinic input] @@ -1369,66 +1415,13 @@ static PyObject * _asyncio_Future__make_cancelled_error_impl(FutureObj *self) /*[clinic end generated code: output=a5df276f6c1213de input=ac6effe4ba795ecc]*/ { - PyObject *exc = create_cancelled_error(self->fut_cancel_msg); - _PyErr_StackItem *exc_state = &self->fut_cancelled_exc_state; - - if (exc_state->exc_value) { - PyException_SetContext(exc, Py_NewRef(exc_state->exc_value)); - _PyErr_ClearExcState(exc_state); - } - else { - assert(exc_state->exc_type == NULL); - assert(exc_state->exc_traceback == NULL); - } - - return exc; -} - -/*[clinic input] -_asyncio.Future._repr_info -[clinic start generated code]*/ - -static PyObject * -_asyncio_Future__repr_info_impl(FutureObj *self) -/*[clinic end generated code: output=fa69e901bd176cfb input=f21504d8e2ae1ca2]*/ -{ - return PyObject_CallOneArg(asyncio_future_repr_info_func, (PyObject *)self); -} - -static PyObject * -FutureObj_repr(FutureObj *fut) -{ - _Py_IDENTIFIER(_repr_info); - - ENSURE_FUTURE_ALIVE(fut) - - PyObject *rinfo = _PyObject_CallMethodIdNoArgs((PyObject*)fut, - &PyId__repr_info); - if (rinfo == NULL) { - return NULL; - } - - PyObject *rinfo_s = PyUnicode_Join(NULL, rinfo); - Py_DECREF(rinfo); - if (rinfo_s == NULL) { - return NULL; - } - - PyObject *rstr = PyUnicode_FromFormat("<%s %U>", - _PyType_Name(Py_TYPE(fut)), rinfo_s); - Py_DECREF(rinfo_s); - return rstr; + asyncio_state *state = get_asyncio_state_by_def((PyObject *)self); + return create_cancelled_error(state, self); } static void FutureObj_finalize(FutureObj *fut) { - _Py_IDENTIFIER(call_exception_handler); - _Py_IDENTIFIER(message); - _Py_IDENTIFIER(exception); - _Py_IDENTIFIER(future); - _Py_IDENTIFIER(source_traceback); - PyObject *error_type, *error_value, *error_traceback; PyObject *context; PyObject *message = NULL; @@ -1454,19 +1447,19 @@ FutureObj_finalize(FutureObj *fut) goto finally; } - if (_PyDict_SetItemId(context, &PyId_message, message) < 0 || - _PyDict_SetItemId(context, &PyId_exception, fut->fut_exception) < 0 || - _PyDict_SetItemId(context, &PyId_future, (PyObject*)fut) < 0) { + if (PyDict_SetItem(context, &_Py_ID(message), message) < 0 || + PyDict_SetItem(context, &_Py_ID(exception), fut->fut_exception) < 0 || + PyDict_SetItem(context, &_Py_ID(future), (PyObject*)fut) < 0) { goto finally; } if (fut->fut_source_tb != NULL) { - if (_PyDict_SetItemId(context, &PyId_source_traceback, + if (PyDict_SetItem(context, &_Py_ID(source_traceback), fut->fut_source_tb) < 0) { goto finally; } } - func = _PyObject_GetAttrId(fut->fut_loop, &PyId_call_exception_handler); + func = PyObject_GetAttr(fut->fut_loop, &_Py_ID(call_exception_handler)); if (func != NULL) { PyObject *res = PyObject_CallOneArg(func, context); if (res == NULL) { @@ -1486,20 +1479,6 @@ finally: PyErr_Restore(error_type, error_value, error_traceback); } -static PyObject * -future_cls_getitem(PyObject *cls, PyObject *type) -{ - Py_INCREF(cls); - return cls; -} - -static PyAsyncMethods FutureType_as_async = { - (unaryfunc)future_new_iter, /* am_await */ - 0, /* am_aiter */ - 0, /* am_anext */ - 0, /* am_send */ -}; - static PyMethodDef FutureType_methods[] = { _ASYNCIO_FUTURE_RESULT_METHODDEF _ASYNCIO_FUTURE_EXCEPTION_METHODDEF @@ -1512,11 +1491,16 @@ static PyMethodDef FutureType_methods[] = { _ASYNCIO_FUTURE_DONE_METHODDEF _ASYNCIO_FUTURE_GET_LOOP_METHODDEF _ASYNCIO_FUTURE__MAKE_CANCELLED_ERROR_METHODDEF - _ASYNCIO_FUTURE__REPR_INFO_METHODDEF - {"__class_getitem__", future_cls_getitem, METH_O|METH_CLASS, NULL}, + {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, {NULL, NULL} /* Sentinel */ }; +static PyMemberDef FutureType_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(FutureObj, fut_weakreflist), READONLY}, + {"__dictoffset__", T_PYSSIZET, offsetof(FutureObj, dict), READONLY}, + {NULL}, +}; + #define FUTURE_COMMON_GETSETLIST \ {"_state", (getter)FutureObj_get_state, NULL, NULL}, \ {"_asyncio_future_blocking", (getter)FutureObj_get_blocking, \ @@ -1539,25 +1523,31 @@ static PyGetSetDef FutureType_getsetlist[] = { static void FutureObj_dealloc(PyObject *self); -static PyTypeObject FutureType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_asyncio.Future", - sizeof(FutureObj), /* tp_basicsize */ - .tp_dealloc = FutureObj_dealloc, - .tp_as_async = &FutureType_as_async, - .tp_repr = (reprfunc)FutureObj_repr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, - .tp_doc = _asyncio_Future___init____doc__, - .tp_traverse = (traverseproc)FutureObj_traverse, - .tp_clear = (inquiry)FutureObj_clear, - .tp_weaklistoffset = offsetof(FutureObj, fut_weakreflist), - .tp_iter = (getiterfunc)future_new_iter, - .tp_methods = FutureType_methods, - .tp_getset = FutureType_getsetlist, - .tp_dictoffset = offsetof(FutureObj, dict), - .tp_init = (initproc)_asyncio_Future___init__, - .tp_new = PyType_GenericNew, - .tp_finalize = (destructor)FutureObj_finalize, +static PyType_Slot Future_slots[] = { + {Py_tp_dealloc, FutureObj_dealloc}, + {Py_tp_repr, (reprfunc)FutureObj_repr}, + {Py_tp_doc, (void *)_asyncio_Future___init____doc__}, + {Py_tp_traverse, (traverseproc)FutureObj_traverse}, + {Py_tp_clear, (inquiry)FutureObj_clear}, + {Py_tp_iter, (getiterfunc)future_new_iter}, + {Py_tp_methods, FutureType_methods}, + {Py_tp_members, FutureType_members}, + {Py_tp_getset, FutureType_getsetlist}, + {Py_tp_init, (initproc)_asyncio_Future___init__}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_finalize, (destructor)FutureObj_finalize}, + + // async slots + {Py_am_await, (unaryfunc)future_new_iter}, + {0, NULL}, +}; + +static PyType_Spec Future_spec = { + .name = "_asyncio.Future", + .basicsize = sizeof(FutureObj), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = Future_slots, }; static void @@ -1565,16 +1555,12 @@ FutureObj_dealloc(PyObject *self) { FutureObj *fut = (FutureObj *)self; - if (Future_CheckExact(fut)) { - /* When fut is subclass of Future, finalizer is called from - * subtype_dealloc. - */ - if (PyObject_CallFinalizerFromDealloc(self) < 0) { - // resurrected. - return; - } + if (PyObject_CallFinalizerFromDealloc(self) < 0) { + // resurrected. + return; } + PyTypeObject *tp = Py_TYPE(fut); PyObject_GC_UnTrack(self); if (fut->fut_weakreflist != NULL) { @@ -1582,7 +1568,8 @@ FutureObj_dealloc(PyObject *self) } (void)FutureObj_clear(fut); - Py_TYPE(fut)->tp_free(fut); + tp->tp_free(fut); + Py_DECREF(tp); } @@ -1602,8 +1589,9 @@ static Py_ssize_t fi_freelist_len = 0; static void FutureIter_dealloc(futureiterobject *it) { + PyTypeObject *tp = Py_TYPE(it); PyObject_GC_UnTrack(it); - Py_CLEAR(it->future); + tp->tp_clear((PyObject *)it); if (fi_freelist_len < FI_FREELIST_MAXLEN) { fi_freelist_len++; @@ -1612,6 +1600,7 @@ FutureIter_dealloc(futureiterobject *it) } else { PyObject_GC_Del(it); + Py_DECREF(tp); } } @@ -1633,8 +1622,7 @@ FutureIter_am_send(futureiterobject *it, if (fut->fut_state == STATE_PENDING) { if (!fut->fut_blocking) { fut->fut_blocking = 1; - Py_INCREF(fut); - *result = (PyObject *)fut; + *result = Py_NewRef(fut); return PYGEN_NEXT; } PyErr_SetString(PyExc_RuntimeError, @@ -1682,16 +1670,34 @@ FutureIter_send(futureiterobject *self, PyObject *unused) } static PyObject * -FutureIter_throw(futureiterobject *self, PyObject *args) +FutureIter_throw(futureiterobject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *type, *val = NULL, *tb = NULL; - if (!PyArg_ParseTuple(args, "O|OO", &type, &val, &tb)) + if (!_PyArg_CheckPositional("throw", nargs, 1, 3)) { return NULL; + } + if (nargs > 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "the (type, exc, tb) signature of throw() is deprecated, " + "use the single-arg signature instead.", + 1) < 0) { + return NULL; + } + } + + type = args[0]; + if (nargs == 3) { + val = args[1]; + tb = args[2]; + } + else if (nargs == 2) { + val = args[1]; + } if (val == Py_None) { val = NULL; } - if (tb == Py_None) { + if (tb == Py_None ) { tb = NULL; } else if (tb != NULL && !PyTraceBack_Check(tb)) { PyErr_SetString(PyExc_TypeError, "throw() third argument must be a traceback"); @@ -1737,48 +1743,55 @@ FutureIter_throw(futureiterobject *self, PyObject *args) return NULL; } +static int +FutureIter_clear(futureiterobject *it) +{ + Py_CLEAR(it->future); + return 0; +} + static PyObject * FutureIter_close(futureiterobject *self, PyObject *arg) { - Py_CLEAR(self->future); + (void)FutureIter_clear(self); Py_RETURN_NONE; } static int FutureIter_traverse(futureiterobject *it, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(it)); Py_VISIT(it->future); return 0; } static PyMethodDef FutureIter_methods[] = { {"send", (PyCFunction)FutureIter_send, METH_O, NULL}, - {"throw", (PyCFunction)FutureIter_throw, METH_VARARGS, NULL}, + {"throw", _PyCFunction_CAST(FutureIter_throw), METH_FASTCALL, NULL}, {"close", (PyCFunction)FutureIter_close, METH_NOARGS, NULL}, {NULL, NULL} /* Sentinel */ }; -static PyAsyncMethods FutureIterType_as_async = { - 0, /* am_await */ - 0, /* am_aiter */ - 0, /* am_anext */ - (sendfunc)FutureIter_am_send, /* am_send */ +static PyType_Slot FutureIter_slots[] = { + {Py_tp_dealloc, (destructor)FutureIter_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, (traverseproc)FutureIter_traverse}, + {Py_tp_clear, FutureIter_clear}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)FutureIter_iternext}, + {Py_tp_methods, FutureIter_methods}, + + // async methods + {Py_am_send, (sendfunc)FutureIter_am_send}, + {0, NULL}, }; - -static PyTypeObject FutureIterType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_asyncio.FutureIter", - .tp_basicsize = sizeof(futureiterobject), - .tp_itemsize = 0, - .tp_dealloc = (destructor)FutureIter_dealloc, - .tp_as_async = &FutureIterType_as_async, - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_traverse = (traverseproc)FutureIter_traverse, - .tp_iter = PyObject_SelfIter, - .tp_iternext = (iternextfunc)FutureIter_iternext, - .tp_methods = FutureIter_methods, +static PyType_Spec FutureIter_spec = { + .name = "_asyncio.FutureIter", + .basicsize = sizeof(futureiterobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = FutureIter_slots, }; static PyObject * @@ -1786,12 +1799,13 @@ future_new_iter(PyObject *fut) { futureiterobject *it; - if (!PyObject_TypeCheck(fut, &FutureType)) { + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); + if (!Future_Check(state, fut)) { PyErr_BadInternalCall(); return NULL; } - ENSURE_FUTURE_ALIVE(fut) + ENSURE_FUTURE_ALIVE(state, fut) if (fi_freelist_len) { fi_freelist_len--; @@ -1801,14 +1815,13 @@ future_new_iter(PyObject *fut) _Py_NewReference((PyObject*) it); } else { - it = PyObject_GC_New(futureiterobject, &FutureIterType); + it = PyObject_GC_New(futureiterobject, state->FutureIterType); if (it == NULL) { return NULL; } } - Py_INCREF(fut); - it->future = (FutureObj*)fut; + it->future = (FutureObj*)Py_NewRef(fut); PyObject_GC_Track(it); return (PyObject*)it; } @@ -1822,9 +1835,9 @@ class _asyncio.Task "TaskObj *" "&Task_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=719dcef0fcc03b37]*/ -static int task_call_step_soon(TaskObj *, PyObject *); +static int task_call_step_soon(asyncio_state *state, TaskObj *, PyObject *); static PyObject * task_wakeup(TaskObj *, PyObject *); -static PyObject * task_step(TaskObj *, PyObject *); +static PyObject * task_step(asyncio_state *, TaskObj *, PyObject *); /* ----- Task._step wrapper */ @@ -1839,9 +1852,11 @@ TaskStepMethWrapper_clear(TaskStepMethWrapper *o) static void TaskStepMethWrapper_dealloc(TaskStepMethWrapper *o) { + PyTypeObject *tp = Py_TYPE(o); PyObject_GC_UnTrack(o); (void)TaskStepMethWrapper_clear(o); Py_TYPE(o)->tp_free(o); + Py_DECREF(tp); } static PyObject * @@ -1856,13 +1871,15 @@ TaskStepMethWrapper_call(TaskStepMethWrapper *o, PyErr_SetString(PyExc_TypeError, "function takes no positional arguments"); return NULL; } - return task_step(o->sw_task, o->sw_arg); + asyncio_state *state = get_asyncio_state_by_def((PyObject *)o); + return task_step(state, o->sw_task, o->sw_arg); } static int TaskStepMethWrapper_traverse(TaskStepMethWrapper *o, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(o)); Py_VISIT(o->sw_task); Py_VISIT(o->sw_arg); return 0; @@ -1872,8 +1889,7 @@ static PyObject * TaskStepMethWrapper_get___self__(TaskStepMethWrapper *o, void *Py_UNUSED(ignored)) { if (o->sw_task) { - Py_INCREF(o->sw_task); - return (PyObject*)o->sw_task; + return Py_NewRef(o->sw_task); } Py_RETURN_NONE; } @@ -1883,34 +1899,36 @@ static PyGetSetDef TaskStepMethWrapper_getsetlist[] = { {NULL} /* Sentinel */ }; -static PyTypeObject TaskStepMethWrapper_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "TaskStepMethWrapper", - .tp_basicsize = sizeof(TaskStepMethWrapper), - .tp_itemsize = 0, - .tp_getset = TaskStepMethWrapper_getsetlist, - .tp_dealloc = (destructor)TaskStepMethWrapper_dealloc, - .tp_call = (ternaryfunc)TaskStepMethWrapper_call, - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_traverse = (traverseproc)TaskStepMethWrapper_traverse, - .tp_clear = (inquiry)TaskStepMethWrapper_clear, +static PyType_Slot TaskStepMethWrapper_slots[] = { + {Py_tp_getset, TaskStepMethWrapper_getsetlist}, + {Py_tp_dealloc, (destructor)TaskStepMethWrapper_dealloc}, + {Py_tp_call, (ternaryfunc)TaskStepMethWrapper_call}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, (traverseproc)TaskStepMethWrapper_traverse}, + {Py_tp_clear, (inquiry)TaskStepMethWrapper_clear}, + {0, NULL}, +}; + +static PyType_Spec TaskStepMethWrapper_spec = { + .name = "_asyncio.TaskStepMethWrapper", + .basicsize = sizeof(TaskStepMethWrapper), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = TaskStepMethWrapper_slots, }; static PyObject * TaskStepMethWrapper_new(TaskObj *task, PyObject *arg) { + asyncio_state *state = get_asyncio_state_by_def((PyObject *)task); TaskStepMethWrapper *o; - o = PyObject_GC_New(TaskStepMethWrapper, &TaskStepMethWrapper_Type); + o = PyObject_GC_New(TaskStepMethWrapper, state->TaskStepMethWrapper_Type); if (o == NULL) { return NULL; } - Py_INCREF(task); - o->sw_task = task; - - Py_XINCREF(arg); - o->sw_arg = arg; + o->sw_task = (TaskObj*)Py_NewRef(task); + o->sw_arg = Py_XNewRef(arg); PyObject_GC_Track(o); return (PyObject*) o; @@ -1928,12 +1946,10 @@ static PyMethodDef TaskWakeupDef = { /* ----- Task introspection helpers */ static int -register_task(PyObject *task) +register_task(asyncio_state *state, PyObject *task) { - _Py_IDENTIFIER(add); - - PyObject *res = _PyObject_CallMethodIdOneArg(all_tasks, - &PyId_add, task); + PyObject *res = PyObject_CallMethodOneArg(state->all_tasks, + &_Py_ID(add), task); if (res == NULL) { return -1; } @@ -1943,12 +1959,10 @@ register_task(PyObject *task) static int -unregister_task(PyObject *task) +unregister_task(asyncio_state *state, PyObject *task) { - _Py_IDENTIFIER(discard); - - PyObject *res = _PyObject_CallMethodIdOneArg(all_tasks, - &PyId_discard, task); + PyObject *res = PyObject_CallMethodOneArg(state->all_tasks, + &_Py_ID(discard), task); if (res == NULL) { return -1; } @@ -1958,7 +1972,7 @@ unregister_task(PyObject *task) static int -enter_task(PyObject *loop, PyObject *task) +enter_task(asyncio_state *state, PyObject *loop, PyObject *task) { PyObject *item; Py_hash_t hash; @@ -1966,7 +1980,7 @@ enter_task(PyObject *loop, PyObject *task) if (hash == -1) { return -1; } - item = _PyDict_GetItem_KnownHash(current_tasks, loop, hash); + item = _PyDict_GetItem_KnownHash(state->current_tasks, loop, hash); if (item != NULL) { Py_INCREF(item); PyErr_Format( @@ -1980,12 +1994,12 @@ enter_task(PyObject *loop, PyObject *task) if (PyErr_Occurred()) { return -1; } - return _PyDict_SetItem_KnownHash(current_tasks, loop, task, hash); + return _PyDict_SetItem_KnownHash(state->current_tasks, loop, task, hash); } static int -leave_task(PyObject *loop, PyObject *task) +leave_task(asyncio_state *state, PyObject *loop, PyObject *task) /*[clinic end generated code: output=0ebf6db4b858fb41 input=51296a46313d1ad8]*/ { PyObject *item; @@ -1994,7 +2008,7 @@ leave_task(PyObject *loop, PyObject *task) if (hash == -1) { return -1; } - item = _PyDict_GetItem_KnownHash(current_tasks, loop, hash); + item = _PyDict_GetItem_KnownHash(state->current_tasks, loop, hash); if (item != task) { if (item == NULL) { /* Not entered, replace with None */ @@ -2006,7 +2020,7 @@ leave_task(PyObject *loop, PyObject *task) task, item, NULL); return -1; } - return _PyDict_DelItem_KnownHash(current_tasks, loop, hash); + return _PyDict_DelItem_KnownHash(state->current_tasks, loop, hash); } /* ----- Task */ @@ -2018,20 +2032,23 @@ _asyncio.Task.__init__ * loop: object = None name: object = None + context: object = None A coroutine wrapped in a Future. [clinic start generated code]*/ static int _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop, - PyObject *name) -/*[clinic end generated code: output=88b12b83d570df50 input=352a3137fe60091d]*/ + PyObject *name, PyObject *context) +/*[clinic end generated code: output=49ac96fe33d0e5c7 input=924522490c8ce825]*/ + { if (future_init((FutureObj*)self, loop)) { return -1; } - int is_coro = is_coroutine(coro); + asyncio_state *state = get_asyncio_state_by_def((PyObject *)self); + int is_coro = is_coroutine(state, coro); if (is_coro == -1) { return -1; } @@ -2043,19 +2060,25 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop, return -1; } - Py_XSETREF(self->task_context, PyContext_CopyCurrent()); - if (self->task_context == NULL) { - return -1; + if (context == Py_None) { + Py_XSETREF(self->task_context, PyContext_CopyCurrent()); + if (self->task_context == NULL) { + return -1; + } + } else { + self->task_context = Py_NewRef(context); } Py_CLEAR(self->task_fut_waiter); self->task_must_cancel = 0; self->task_log_destroy_pending = 1; + self->task_num_cancels_requested = 0; Py_INCREF(coro); Py_XSETREF(self->task_coro, coro); if (name == Py_None) { - name = PyUnicode_FromFormat("Task-%" PRIu64, ++task_name_counter); + name = PyUnicode_FromFormat("Task-%" PRIu64, + ++state->task_name_counter); } else if (!PyUnicode_CheckExact(name)) { name = PyObject_Str(name); } else { @@ -2066,10 +2089,10 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop, return -1; } - if (task_call_step_soon(self, NULL)) { + if (task_call_step_soon(state, self, NULL)) { return -1; } - return register_task((PyObject*)self); + return register_task(state, (PyObject*)self); } static int @@ -2086,11 +2109,23 @@ TaskObj_clear(TaskObj *task) static int TaskObj_traverse(TaskObj *task, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(task)); Py_VISIT(task->task_context); Py_VISIT(task->task_coro); Py_VISIT(task->task_name); Py_VISIT(task->task_fut_waiter); - (void)FutureObj_traverse((FutureObj*) task, visit, arg); + FutureObj *fut = (FutureObj *)task; + Py_VISIT(fut->fut_loop); + Py_VISIT(fut->fut_callback0); + Py_VISIT(fut->fut_context0); + Py_VISIT(fut->fut_callbacks); + Py_VISIT(fut->fut_result); + Py_VISIT(fut->fut_exception); + Py_VISIT(fut->fut_exception_tb); + Py_VISIT(fut->fut_source_tb); + Py_VISIT(fut->fut_cancel_msg); + Py_VISIT(fut->fut_cancelled_exc); + Py_VISIT(fut->dict); return 0; } @@ -2135,8 +2170,7 @@ static PyObject * TaskObj_get_coro(TaskObj *task, void *Py_UNUSED(ignored)) { if (task->task_coro) { - Py_INCREF(task->task_coro); - return task->task_coro; + return Py_NewRef(task->task_coro); } Py_RETURN_NONE; @@ -2146,13 +2180,21 @@ static PyObject * TaskObj_get_fut_waiter(TaskObj *task, void *Py_UNUSED(ignored)) { if (task->task_fut_waiter) { - Py_INCREF(task->task_fut_waiter); - return task->task_fut_waiter; + return Py_NewRef(task->task_fut_waiter); } Py_RETURN_NONE; } +static PyObject * +TaskObj_repr(TaskObj *task) +{ + asyncio_state *state = get_asyncio_state_by_def((PyObject *)task); + return PyObject_CallOneArg(state->asyncio_task_repr_func, + (PyObject *)task); +} + + /*[clinic input] _asyncio.Task._make_cancelled_error @@ -2171,17 +2213,6 @@ _asyncio_Task__make_cancelled_error_impl(TaskObj *self) } -/*[clinic input] -_asyncio.Task._repr_info -[clinic start generated code]*/ - -static PyObject * -_asyncio_Task__repr_info_impl(TaskObj *self) -/*[clinic end generated code: output=6a490eb66d5ba34b input=3c6d051ed3ddec8b]*/ -{ - return PyObject_CallOneArg(asyncio_task_repr_info_func, (PyObject *)self); -} - /*[clinic input] _asyncio.Task.cancel @@ -2205,11 +2236,13 @@ not return True (unless the task was already cancelled). A task will be marked as cancelled when the wrapped coroutine terminates with a CancelledError exception (even if cancel() was not called). + +This also increases the task's count of cancellation requests. [clinic start generated code]*/ static PyObject * _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg) -/*[clinic end generated code: output=c66b60d41c74f9f1 input=f4ff8e8ffc5f1c00]*/ +/*[clinic end generated code: output=c66b60d41c74f9f1 input=7bb51bf25974c783]*/ { self->task_log_tb = 0; @@ -2217,12 +2250,21 @@ _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg) Py_RETURN_FALSE; } + self->task_num_cancels_requested += 1; + + // These three lines are controversial. See discussion starting at + // https://github.com/python/cpython/pull/31394#issuecomment-1053545331 + // and corresponding code in tasks.py. + // if (self->task_num_cancels_requested > 1) { + // Py_RETURN_FALSE; + // } + if (self->task_fut_waiter) { PyObject *res; int is_true; - res = _PyObject_CallMethodIdOneArg(self->task_fut_waiter, - &PyId_cancel, msg); + res = PyObject_CallMethodOneArg(self->task_fut_waiter, + &_Py_ID(cancel), msg); if (res == NULL) { return NULL; } @@ -2244,9 +2286,50 @@ _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg) Py_RETURN_TRUE; } +/*[clinic input] +_asyncio.Task.cancelling + +Return the count of the task's cancellation requests. + +This count is incremented when .cancel() is called +and may be decremented using .uncancel(). +[clinic start generated code]*/ + +static PyObject * +_asyncio_Task_cancelling_impl(TaskObj *self) +/*[clinic end generated code: output=803b3af96f917d7e input=b625224d310cbb17]*/ +/*[clinic end generated code]*/ +{ + return PyLong_FromLong(self->task_num_cancels_requested); +} + +/*[clinic input] +_asyncio.Task.uncancel + +Decrement the task's count of cancellation requests. + +This should be used by tasks that catch CancelledError +and wish to continue indefinitely until they are cancelled again. + +Returns the remaining number of cancellation requests. +[clinic start generated code]*/ + +static PyObject * +_asyncio_Task_uncancel_impl(TaskObj *self) +/*[clinic end generated code: output=58184d236a817d3c input=68f81a4b90b46be2]*/ +/*[clinic end generated code]*/ +{ + if (self->task_num_cancels_requested > 0) { + self->task_num_cancels_requested -= 1; + } + return PyLong_FromLong(self->task_num_cancels_requested); +} + /*[clinic input] _asyncio.Task.get_stack + cls: defining_class + / * limit: object = None @@ -2272,16 +2355,20 @@ returned for a suspended coroutine. [clinic start generated code]*/ static PyObject * -_asyncio_Task_get_stack_impl(TaskObj *self, PyObject *limit) -/*[clinic end generated code: output=c9aeeeebd1e18118 input=05b323d42b809b90]*/ +_asyncio_Task_get_stack_impl(TaskObj *self, PyTypeObject *cls, + PyObject *limit) +/*[clinic end generated code: output=6774dfc10d3857fa input=8e01c9b2618ae953]*/ { + asyncio_state *state = get_asyncio_state_by_cls(cls); return PyObject_CallFunctionObjArgs( - asyncio_task_get_stack_func, self, limit, NULL); + state->asyncio_task_get_stack_func, self, limit, NULL); } /*[clinic input] _asyncio.Task.print_stack + cls: defining_class + / * limit: object = None file: object = None @@ -2296,12 +2383,13 @@ to sys.stderr. [clinic start generated code]*/ static PyObject * -_asyncio_Task_print_stack_impl(TaskObj *self, PyObject *limit, - PyObject *file) -/*[clinic end generated code: output=7339e10314cd3f4d input=1a0352913b7fcd92]*/ +_asyncio_Task_print_stack_impl(TaskObj *self, PyTypeObject *cls, + PyObject *limit, PyObject *file) +/*[clinic end generated code: output=b38affe9289ec826 input=150b35ba2d3a7dee]*/ { + asyncio_state *state = get_asyncio_state_by_cls(cls); return PyObject_CallFunctionObjArgs( - asyncio_task_print_stack_func, self, limit, file, NULL); + state->asyncio_task_print_stack_func, self, limit, file, NULL); } /*[clinic input] @@ -2344,8 +2432,18 @@ static PyObject * _asyncio_Task_get_coro_impl(TaskObj *self) /*[clinic end generated code: output=bcac27c8cc6c8073 input=d2e8606c42a7b403]*/ { - Py_INCREF(self->task_coro); - return self->task_coro; + return Py_NewRef(self->task_coro); +} + +/*[clinic input] +_asyncio.Task.get_context +[clinic start generated code]*/ + +static PyObject * +_asyncio_Task_get_context_impl(TaskObj *self) +/*[clinic end generated code: output=6996f53d3dc01aef input=87c0b209b8fceeeb]*/ +{ + return Py_NewRef(self->task_context); } /*[clinic input] @@ -2357,8 +2455,7 @@ _asyncio_Task_get_name_impl(TaskObj *self) /*[clinic end generated code: output=0ecf1570c3b37a8f input=a4a6595d12f4f0f8]*/ { if (self->task_name) { - Py_INCREF(self->task_name); - return self->task_name; + return Py_NewRef(self->task_name); } Py_RETURN_NONE; @@ -2391,11 +2488,6 @@ _asyncio_Task_set_name(TaskObj *self, PyObject *value) static void TaskObj_finalize(TaskObj *task) { - _Py_IDENTIFIER(call_exception_handler); - _Py_IDENTIFIER(task); - _Py_IDENTIFIER(message); - _Py_IDENTIFIER(source_traceback); - PyObject *context; PyObject *message = NULL; PyObject *func; @@ -2418,21 +2510,21 @@ TaskObj_finalize(TaskObj *task) goto finally; } - if (_PyDict_SetItemId(context, &PyId_message, message) < 0 || - _PyDict_SetItemId(context, &PyId_task, (PyObject*)task) < 0) + if (PyDict_SetItem(context, &_Py_ID(message), message) < 0 || + PyDict_SetItem(context, &_Py_ID(task), (PyObject*)task) < 0) { goto finally; } if (task->task_source_tb != NULL) { - if (_PyDict_SetItemId(context, &PyId_source_traceback, + if (PyDict_SetItem(context, &_Py_ID(source_traceback), task->task_source_tb) < 0) { goto finally; } } - func = _PyObject_GetAttrId(task->task_loop, &PyId_call_exception_handler); + func = PyObject_GetAttr(task->task_loop, &_Py_ID(call_exception_handler)); if (func != NULL) { PyObject *res = PyObject_CallOneArg(func, context); if (res == NULL) { @@ -2455,13 +2547,6 @@ done: FutureObj_finalize((FutureObj*)task); } -static PyObject * -task_cls_getitem(PyObject *cls, PyObject *type) -{ - Py_INCREF(cls); - return cls; -} - static void TaskObj_dealloc(PyObject *); /* Needs Task_CheckExact */ static PyMethodDef TaskType_methods[] = { @@ -2474,17 +2559,25 @@ static PyMethodDef TaskType_methods[] = { _ASYNCIO_TASK_SET_RESULT_METHODDEF _ASYNCIO_TASK_SET_EXCEPTION_METHODDEF _ASYNCIO_TASK_CANCEL_METHODDEF + _ASYNCIO_TASK_CANCELLING_METHODDEF + _ASYNCIO_TASK_UNCANCEL_METHODDEF _ASYNCIO_TASK_GET_STACK_METHODDEF _ASYNCIO_TASK_PRINT_STACK_METHODDEF _ASYNCIO_TASK__MAKE_CANCELLED_ERROR_METHODDEF - _ASYNCIO_TASK__REPR_INFO_METHODDEF _ASYNCIO_TASK_GET_NAME_METHODDEF _ASYNCIO_TASK_SET_NAME_METHODDEF _ASYNCIO_TASK_GET_CORO_METHODDEF - {"__class_getitem__", task_cls_getitem, METH_O|METH_CLASS, NULL}, + _ASYNCIO_TASK_GET_CONTEXT_METHODDEF + {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, {NULL, NULL} /* Sentinel */ }; +static PyMemberDef TaskType_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(TaskObj, task_weakreflist), READONLY}, + {"__dictoffset__", T_PYSSIZET, offsetof(TaskObj, dict), READONLY}, + {NULL}, +}; + static PyGetSetDef TaskType_getsetlist[] = { FUTURE_COMMON_GETSETLIST {"_log_destroy_pending", (getter)TaskObj_get_log_destroy_pending, @@ -2495,26 +2588,31 @@ static PyGetSetDef TaskType_getsetlist[] = { {NULL} /* Sentinel */ }; -static PyTypeObject TaskType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_asyncio.Task", - sizeof(TaskObj), /* tp_basicsize */ - .tp_base = &FutureType, - .tp_dealloc = TaskObj_dealloc, - .tp_as_async = &FutureType_as_async, - .tp_repr = (reprfunc)FutureObj_repr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, - .tp_doc = _asyncio_Task___init____doc__, - .tp_traverse = (traverseproc)TaskObj_traverse, - .tp_clear = (inquiry)TaskObj_clear, - .tp_weaklistoffset = offsetof(TaskObj, task_weakreflist), - .tp_iter = (getiterfunc)future_new_iter, - .tp_methods = TaskType_methods, - .tp_getset = TaskType_getsetlist, - .tp_dictoffset = offsetof(TaskObj, dict), - .tp_init = (initproc)_asyncio_Task___init__, - .tp_new = PyType_GenericNew, - .tp_finalize = (destructor)TaskObj_finalize, +static PyType_Slot Task_slots[] = { + {Py_tp_dealloc, TaskObj_dealloc}, + {Py_tp_repr, (reprfunc)TaskObj_repr}, + {Py_tp_doc, (void *)_asyncio_Task___init____doc__}, + {Py_tp_traverse, (traverseproc)TaskObj_traverse}, + {Py_tp_clear, (inquiry)TaskObj_clear}, + {Py_tp_iter, (getiterfunc)future_new_iter}, + {Py_tp_methods, TaskType_methods}, + {Py_tp_members, TaskType_members}, + {Py_tp_getset, TaskType_getsetlist}, + {Py_tp_init, (initproc)_asyncio_Task___init__}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_finalize, (destructor)TaskObj_finalize}, + + // async slots + {Py_am_await, (unaryfunc)future_new_iter}, + {0, NULL}, +}; + +static PyType_Spec Task_spec = { + .name = "_asyncio.Task", + .basicsize = sizeof(TaskObj), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = Task_slots, }; static void @@ -2522,16 +2620,12 @@ TaskObj_dealloc(PyObject *self) { TaskObj *task = (TaskObj *)self; - if (Task_CheckExact(self)) { - /* When fut is subclass of Task, finalizer is called from - * subtype_dealloc. - */ - if (PyObject_CallFinalizerFromDealloc(self) < 0) { - // resurrected. - return; - } + if (PyObject_CallFinalizerFromDealloc(self) < 0) { + // resurrected. + return; } + PyTypeObject *tp = Py_TYPE(task); PyObject_GC_UnTrack(self); if (task->task_weakreflist != NULL) { @@ -2539,33 +2633,31 @@ TaskObj_dealloc(PyObject *self) } (void)TaskObj_clear(task); - Py_TYPE(task)->tp_free(task); + tp->tp_free(task); + Py_DECREF(tp); } static int -task_call_step_soon(TaskObj *task, PyObject *arg) +task_call_step_soon(asyncio_state *state, TaskObj *task, PyObject *arg) { PyObject *cb = TaskStepMethWrapper_new(task, arg); if (cb == NULL) { return -1; } - int ret = call_soon(task->task_loop, cb, NULL, task->task_context); + int ret = call_soon(state, task->task_loop, cb, NULL, task->task_context); Py_DECREF(cb); return ret; } static PyObject * -task_set_error_soon(TaskObj *task, PyObject *et, const char *format, ...) +task_set_error_soon(asyncio_state *state, TaskObj *task, PyObject *et, + const char *format, ...) { PyObject* msg; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif msg = PyUnicode_FromFormatV(format, vargs); va_end(vargs); @@ -2579,7 +2671,7 @@ task_set_error_soon(TaskObj *task, PyObject *et, const char *format, ...) return NULL; } - if (task_call_step_soon(task, e) == -1) { + if (task_call_step_soon(state, task, e) == -1) { Py_DECREF(e); return NULL; } @@ -2603,7 +2695,7 @@ gen_status_from_result(PyObject **result) } static PyObject * -task_step_impl(TaskObj *task, PyObject *exc) +task_step_impl(asyncio_state *state, TaskObj *task, PyObject *exc) { int res; int clear_exc = 0; @@ -2612,7 +2704,7 @@ task_step_impl(TaskObj *task, PyObject *exc) PyObject *o; if (task->task_state != STATE_PENDING) { - PyErr_Format(asyncio_InvalidStateError, + PyErr_Format(state->asyncio_InvalidStateError, "_step(): already done: %R %R", task, exc ? exc : Py_None); @@ -2624,7 +2716,7 @@ task_step_impl(TaskObj *task, PyObject *exc) if (exc) { /* Check if exc is a CancelledError */ - res = PyObject_IsInstance(exc, asyncio_CancelledError); + res = PyObject_IsInstance(exc, state->asyncio_CancelledError); if (res == -1) { /* An error occurred, abort */ goto fail; @@ -2637,7 +2729,7 @@ task_step_impl(TaskObj *task, PyObject *exc) if (!exc) { /* exc was not a CancelledError */ - exc = create_cancelled_error(task->task_cancel_msg); + exc = create_cancelled_error(state, (FutureObj*)task); if (!exc) { goto fail; @@ -2665,7 +2757,7 @@ task_step_impl(TaskObj *task, PyObject *exc) gen_status = PyIter_Send(coro, Py_None, &result); } else { - result = _PyObject_CallMethodIdOneArg(coro, &PyId_throw, exc); + result = PyObject_CallMethodOneArg(coro, &_Py_ID(throw), exc); gen_status = gen_status_from_result(&result); if (clear_exc) { /* We created 'exc' during this call */ @@ -2680,49 +2772,53 @@ task_step_impl(TaskObj *task, PyObject *exc) /* The error is StopIteration and that means that the underlying coroutine has resolved */ - PyObject *res; + PyObject *tmp; if (task->task_must_cancel) { // Task is cancelled right before coro stops. task->task_must_cancel = 0; - res = future_cancel((FutureObj*)task, task->task_cancel_msg); + tmp = future_cancel(state, (FutureObj*)task, + task->task_cancel_msg); } else { - res = future_set_result((FutureObj*)task, result); + tmp = future_set_result(state, (FutureObj*)task, result); } Py_DECREF(result); - if (res == NULL) { + if (tmp == NULL) { return NULL; } - Py_DECREF(res); + Py_DECREF(tmp); Py_RETURN_NONE; } - if (PyErr_ExceptionMatches(asyncio_CancelledError)) { + if (PyErr_ExceptionMatches(state->asyncio_CancelledError)) { /* CancelledError */ PyErr_Fetch(&et, &ev, &tb); + assert(et); + PyErr_NormalizeException(&et, &ev, &tb); + if (tb != NULL) { + PyException_SetTraceback(ev, tb); + Py_DECREF(tb); + } + Py_XDECREF(et); FutureObj *fut = (FutureObj*)task; - _PyErr_StackItem *exc_state = &fut->fut_cancelled_exc_state; - exc_state->exc_type = et; - exc_state->exc_value = ev; - exc_state->exc_traceback = tb; + /* transfer ownership */ + fut->fut_cancelled_exc = ev; - return future_cancel(fut, NULL); + return future_cancel(state, fut, NULL); } /* Some other exception; pop it and call Task.set_exception() */ PyErr_Fetch(&et, &ev, &tb); - assert(et); - if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) { - PyErr_NormalizeException(&et, &ev, &tb); - } + PyErr_NormalizeException(&et, &ev, &tb); if (tb != NULL) { PyException_SetTraceback(ev, tb); } - o = future_set_exception((FutureObj*)task, ev); + + o = future_set_exception(state, (FutureObj*)task, ev); if (!o) { /* An exception in Task.set_exception() */ Py_DECREF(et); @@ -2754,9 +2850,9 @@ task_step_impl(TaskObj *task, PyObject *exc) } /* Check if `result` is FutureObj or TaskObj (and not a subclass) */ - if (Future_CheckExact(result) || Task_CheckExact(result)) { + if (Future_CheckExact(state, result) || Task_CheckExact(state, result)) { PyObject *wrapper; - PyObject *res; + PyObject *tmp; FutureObj *fut = (FutureObj*)result; /* Check if `result` future is attached to a different loop */ @@ -2775,13 +2871,13 @@ task_step_impl(TaskObj *task, PyObject *exc) if (wrapper == NULL) { goto fail; } - res = future_add_done_callback( + tmp = future_add_done_callback(state, (FutureObj*)result, wrapper, task->task_context); Py_DECREF(wrapper); - if (res == NULL) { + if (tmp == NULL) { goto fail; } - Py_DECREF(res); + Py_DECREF(tmp); /* task._fut_waiter = result */ task->task_fut_waiter = result; /* no incref is necessary */ @@ -2789,7 +2885,7 @@ task_step_impl(TaskObj *task, PyObject *exc) if (task->task_must_cancel) { PyObject *r; int is_true; - r = _PyObject_CallMethodIdOneArg(result, &PyId_cancel, + r = PyObject_CallMethodOneArg(result, &_Py_ID(cancel), task->task_cancel_msg); if (r == NULL) { return NULL; @@ -2810,20 +2906,20 @@ task_step_impl(TaskObj *task, PyObject *exc) /* Check if `result` is None */ if (result == Py_None) { /* Bare yield relinquishes control for one event loop iteration. */ - if (task_call_step_soon(task, NULL)) { + if (task_call_step_soon(state, task, NULL)) { goto fail; } return result; } /* Check if `result` is a Future-compatible object */ - if (_PyObject_LookupAttrId(result, &PyId__asyncio_future_blocking, &o) < 0) { + if (_PyObject_LookupAttr(result, &_Py_ID(_asyncio_future_blocking), &o) < 0) { goto fail; } if (o != NULL && o != Py_None) { /* `result` is a Future-compatible object */ PyObject *wrapper; - PyObject *res; + PyObject *tmp; int blocking = PyObject_IsTrue(o); Py_DECREF(o); @@ -2832,7 +2928,7 @@ task_step_impl(TaskObj *task, PyObject *exc) } /* Check if `result` future is attached to a different loop */ - PyObject *oloop = get_future_loop(result); + PyObject *oloop = get_future_loop(state, result); if (oloop == NULL) { goto fail; } @@ -2847,8 +2943,8 @@ task_step_impl(TaskObj *task, PyObject *exc) } /* result._asyncio_future_blocking = False */ - if (_PyObject_SetAttrId( - result, &PyId__asyncio_future_blocking, Py_False) == -1) { + if (PyObject_SetAttr( + result, &_Py_ID(_asyncio_future_blocking), Py_False) == -1) { goto fail; } @@ -2858,8 +2954,8 @@ task_step_impl(TaskObj *task, PyObject *exc) } /* result.add_done_callback(task._wakeup) */ - PyObject *add_cb = _PyObject_GetAttrId( - result, &PyId_add_done_callback); + PyObject *add_cb = PyObject_GetAttr( + result, &_Py_ID(add_done_callback)); if (add_cb == NULL) { Py_DECREF(wrapper); goto fail; @@ -2867,13 +2963,14 @@ task_step_impl(TaskObj *task, PyObject *exc) PyObject *stack[2]; stack[0] = wrapper; stack[1] = (PyObject *)task->task_context; - res = PyObject_Vectorcall(add_cb, stack, 1, context_kwname); + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, add_cb); + tmp = PyObject_Vectorcall(add_cb, stack, 1, state->context_kwname); Py_DECREF(add_cb); Py_DECREF(wrapper); - if (res == NULL) { + if (tmp == NULL) { goto fail; } - Py_DECREF(res); + Py_DECREF(tmp); /* task._fut_waiter = result */ task->task_fut_waiter = result; /* no incref is necessary */ @@ -2881,7 +2978,7 @@ task_step_impl(TaskObj *task, PyObject *exc) if (task->task_must_cancel) { PyObject *r; int is_true; - r = _PyObject_CallMethodIdOneArg(result, &PyId_cancel, + r = PyObject_CallMethodOneArg(result, &_Py_ID(cancel), task->task_cancel_msg); if (r == NULL) { return NULL; @@ -2908,7 +3005,7 @@ task_step_impl(TaskObj *task, PyObject *exc) if (res) { /* `result` is a generator */ o = task_set_error_soon( - task, PyExc_RuntimeError, + state, task, PyExc_RuntimeError, "yield was used instead of yield from for " "generator in task %R with %R", task, result); Py_DECREF(result); @@ -2917,20 +3014,20 @@ task_step_impl(TaskObj *task, PyObject *exc) /* The `result` is none of the above */ o = task_set_error_soon( - task, PyExc_RuntimeError, "Task got bad yield: %R", result); + state, task, PyExc_RuntimeError, "Task got bad yield: %R", result); Py_DECREF(result); return o; self_await: o = task_set_error_soon( - task, PyExc_RuntimeError, + state, task, PyExc_RuntimeError, "Task cannot await on itself: %R", task); Py_DECREF(result); return o; yield_insteadof_yf: o = task_set_error_soon( - task, PyExc_RuntimeError, + state, task, PyExc_RuntimeError, "yield was used instead of yield from " "in task %R with %R", task, result); @@ -2939,7 +3036,7 @@ yield_insteadof_yf: different_loop: o = task_set_error_soon( - task, PyExc_RuntimeError, + state, task, PyExc_RuntimeError, "Task %R got Future %R attached to a different loop", task, result); Py_DECREF(result); @@ -2951,25 +3048,25 @@ fail: } static PyObject * -task_step(TaskObj *task, PyObject *exc) +task_step(asyncio_state *state, TaskObj *task, PyObject *exc) { PyObject *res; - if (enter_task(task->task_loop, (PyObject*)task) < 0) { + if (enter_task(state, task->task_loop, (PyObject*)task) < 0) { return NULL; } - res = task_step_impl(task, exc); + res = task_step_impl(state, task, exc); if (res == NULL) { PyObject *et, *ev, *tb; PyErr_Fetch(&et, &ev, &tb); - leave_task(task->task_loop, (PyObject*)task); - _PyErr_ChainExceptions(et, ev, tb); + leave_task(state, task->task_loop, (PyObject*)task); + _PyErr_ChainExceptions(et, ev, tb); /* Normalizes (et, ev, tb) */ return NULL; } else { - if (leave_task(task->task_loop, (PyObject*)task) < 0) { + if (leave_task(state, task->task_loop, (PyObject*)task) < 0) { Py_DECREF(res); return NULL; } @@ -2986,9 +3083,10 @@ task_wakeup(TaskObj *task, PyObject *o) PyObject *result; assert(o); - if (Future_CheckExact(o) || Task_CheckExact(o)) { + asyncio_state *state = get_asyncio_state_by_def((PyObject *)task); + if (Future_CheckExact(state, o) || Task_CheckExact(state, o)) { PyObject *fut_result = NULL; - int res = future_get_result((FutureObj*)o, &fut_result); + int res = future_get_result(state, (FutureObj*)o, &fut_result); switch(res) { case -1: @@ -2996,10 +3094,10 @@ task_wakeup(TaskObj *task, PyObject *o) break; /* exception raised */ case 0: Py_DECREF(fut_result); - return task_step(task, NULL); + return task_step(state, task, NULL); default: assert(res == 1); - result = task_step(task, fut_result); + result = task_step(state, task, fut_result); Py_DECREF(fut_result); return result; } @@ -3008,17 +3106,19 @@ task_wakeup(TaskObj *task, PyObject *o) PyObject *fut_result = PyObject_CallMethod(o, "result", NULL); if (fut_result != NULL) { Py_DECREF(fut_result); - return task_step(task, NULL); + return task_step(state, task, NULL); } /* exception raised */ } PyErr_Fetch(&et, &ev, &tb); - if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) { - PyErr_NormalizeException(&et, &ev, &tb); + assert(et); + PyErr_NormalizeException(&et, &ev, &tb); + if (tb != NULL) { + PyException_SetTraceback(ev, tb); } - result = task_step(task, ev); + result = task_step(state, task, ev); Py_DECREF(et); Py_XDECREF(tb); @@ -3046,7 +3146,8 @@ _asyncio__get_running_loop_impl(PyObject *module) /*[clinic end generated code: output=b4390af721411a0a input=0a21627e25a4bd43]*/ { PyObject *loop; - if (get_running_loop(&loop)) { + asyncio_state *state = get_asyncio_state(module); + if (get_running_loop(state, &loop)) { return NULL; } if (loop == NULL) { @@ -3071,7 +3172,8 @@ static PyObject * _asyncio__set_running_loop(PyObject *module, PyObject *loop) /*[clinic end generated code: output=ae56bf7a28ca189a input=4c9720233d606604]*/ { - if (set_running_loop(loop)) { + asyncio_state *state = get_asyncio_state(module); + if (set_running_loop(state, loop)) { return NULL; } Py_RETURN_NONE; @@ -3094,19 +3196,8 @@ static PyObject * _asyncio_get_event_loop_impl(PyObject *module) /*[clinic end generated code: output=2a2d8b2f824c648b input=9364bf2916c8655d]*/ { - return get_event_loop(1); -} - -/*[clinic input] -_asyncio._get_event_loop - stacklevel: int = 3 -[clinic start generated code]*/ - -static PyObject * -_asyncio__get_event_loop_impl(PyObject *module, int stacklevel) -/*[clinic end generated code: output=9c1d6d3c802e67c9 input=d17aebbd686f711d]*/ -{ - return get_event_loop(stacklevel-1); + asyncio_state *state = get_asyncio_state(module); + return get_event_loop(state); } /*[clinic input] @@ -3122,7 +3213,8 @@ _asyncio_get_running_loop_impl(PyObject *module) /*[clinic end generated code: output=c247b5f9e529530e input=2a3bf02ba39f173d]*/ { PyObject *loop; - if (get_running_loop(&loop)) { + asyncio_state *state = get_asyncio_state(module); + if (get_running_loop(state, &loop)) { return NULL; } if (loop == NULL) { @@ -3147,7 +3239,8 @@ static PyObject * _asyncio__register_task_impl(PyObject *module, PyObject *task) /*[clinic end generated code: output=8672dadd69a7d4e2 input=21075aaea14dfbad]*/ { - if (register_task(task) < 0) { + asyncio_state *state = get_asyncio_state(module); + if (register_task(state, task) < 0) { return NULL; } Py_RETURN_NONE; @@ -3168,7 +3261,8 @@ static PyObject * _asyncio__unregister_task_impl(PyObject *module, PyObject *task) /*[clinic end generated code: output=6e5585706d568a46 input=28fb98c3975f7bdc]*/ { - if (unregister_task(task) < 0) { + asyncio_state *state = get_asyncio_state(module); + if (unregister_task(state, task) < 0) { return NULL; } Py_RETURN_NONE; @@ -3192,7 +3286,8 @@ static PyObject * _asyncio__enter_task_impl(PyObject *module, PyObject *loop, PyObject *task) /*[clinic end generated code: output=a22611c858035b73 input=de1b06dca70d8737]*/ { - if (enter_task(loop, task) < 0) { + asyncio_state *state = get_asyncio_state(module); + if (enter_task(state, loop, task) < 0) { return NULL; } Py_RETURN_NONE; @@ -3216,57 +3311,52 @@ static PyObject * _asyncio__leave_task_impl(PyObject *module, PyObject *loop, PyObject *task) /*[clinic end generated code: output=0ebf6db4b858fb41 input=51296a46313d1ad8]*/ { - if (leave_task(loop, task) < 0) { + asyncio_state *state = get_asyncio_state(module); + if (leave_task(state, loop, task) < 0) { return NULL; } Py_RETURN_NONE; } -/*********************** PyRunningLoopHolder ********************/ +/*[clinic input] +_asyncio.current_task + loop: object = None -static PyRunningLoopHolder * -new_running_loop_holder(PyObject *loop) +Return a currently executed task. + +[clinic start generated code]*/ + +static PyObject * +_asyncio_current_task_impl(PyObject *module, PyObject *loop) +/*[clinic end generated code: output=fe15ac331a7f981a input=58910f61a5627112]*/ { - PyRunningLoopHolder *rl = PyObject_New( - PyRunningLoopHolder, &PyRunningLoopHolder_Type); - if (rl == NULL) { + PyObject *ret; + asyncio_state *state = get_asyncio_state(module); + + if (loop == Py_None) { + loop = _asyncio_get_running_loop_impl(module); + if (loop == NULL) { + return NULL; + } + } else { + Py_INCREF(loop); + } + + ret = PyDict_GetItemWithError(state->current_tasks, loop); + Py_DECREF(loop); + if (ret == NULL && PyErr_Occurred()) { return NULL; } - -#if defined(HAVE_GETPID) && !defined(MS_WINDOWS) - rl->rl_pid = getpid(); -#endif - - Py_INCREF(loop); - rl->rl_loop = loop; - - return rl; -} - - -static void -PyRunningLoopHolder_tp_dealloc(PyRunningLoopHolder *rl) -{ - if (cached_running_holder == (PyObject *)rl) { - cached_running_holder = NULL; + else if (ret == NULL) { + Py_RETURN_NONE; } - Py_CLEAR(rl->rl_loop); - PyObject_Free(rl); + Py_INCREF(ret); + return ret; } -static PyTypeObject PyRunningLoopHolder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_RunningLoopHolder", - sizeof(PyRunningLoopHolder), - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_dealloc = (destructor)PyRunningLoopHolder_tp_dealloc, -}; - - /*********************** Module **************************/ @@ -3289,61 +3379,104 @@ module_free_freelists(void) fi_freelist = NULL; } - -static void -module_free(void *m) +static int +module_traverse(PyObject *mod, visitproc visit, void *arg) { - Py_CLEAR(asyncio_mod); - Py_CLEAR(traceback_extract_stack); - Py_CLEAR(asyncio_future_repr_info_func); - Py_CLEAR(asyncio_get_event_loop_policy); - Py_CLEAR(asyncio_iscoroutine_func); - Py_CLEAR(asyncio_task_get_stack_func); - Py_CLEAR(asyncio_task_print_stack_func); - Py_CLEAR(asyncio_task_repr_info_func); - Py_CLEAR(asyncio_InvalidStateError); - Py_CLEAR(asyncio_CancelledError); + asyncio_state *state = get_asyncio_state(mod); - Py_CLEAR(all_tasks); - Py_CLEAR(current_tasks); - Py_CLEAR(iscoroutine_typecache); + Py_VISIT(state->FutureIterType); + Py_VISIT(state->TaskStepMethWrapper_Type); + Py_VISIT(state->FutureType); + Py_VISIT(state->TaskType); - Py_CLEAR(context_kwname); + Py_VISIT(state->asyncio_mod); + Py_VISIT(state->traceback_extract_stack); + Py_VISIT(state->asyncio_future_repr_func); + Py_VISIT(state->asyncio_get_event_loop_policy); + Py_VISIT(state->asyncio_iscoroutine_func); + Py_VISIT(state->asyncio_task_get_stack_func); + Py_VISIT(state->asyncio_task_print_stack_func); + Py_VISIT(state->asyncio_task_repr_func); + Py_VISIT(state->asyncio_InvalidStateError); + Py_VISIT(state->asyncio_CancelledError); - module_free_freelists(); + Py_VISIT(state->all_tasks); + Py_VISIT(state->current_tasks); + Py_VISIT(state->iscoroutine_typecache); - module_initialized = 0; + Py_VISIT(state->context_kwname); + + // Visit freelist. + PyObject *next = (PyObject*) fi_freelist; + while (next != NULL) { + PyObject *current = next; + Py_VISIT(current); + next = (PyObject*) ((futureiterobject*) current)->future; + } + return 0; } static int -module_init(void) +module_clear(PyObject *mod) +{ + asyncio_state *state = get_asyncio_state(mod); + + Py_CLEAR(state->FutureIterType); + Py_CLEAR(state->TaskStepMethWrapper_Type); + Py_CLEAR(state->FutureType); + Py_CLEAR(state->TaskType); + + Py_CLEAR(state->asyncio_mod); + Py_CLEAR(state->traceback_extract_stack); + Py_CLEAR(state->asyncio_future_repr_func); + Py_CLEAR(state->asyncio_get_event_loop_policy); + Py_CLEAR(state->asyncio_iscoroutine_func); + Py_CLEAR(state->asyncio_task_get_stack_func); + Py_CLEAR(state->asyncio_task_print_stack_func); + Py_CLEAR(state->asyncio_task_repr_func); + Py_CLEAR(state->asyncio_InvalidStateError); + Py_CLEAR(state->asyncio_CancelledError); + + Py_CLEAR(state->all_tasks); + Py_CLEAR(state->current_tasks); + Py_CLEAR(state->iscoroutine_typecache); + + Py_CLEAR(state->context_kwname); + + module_free_freelists(); + + return 0; +} + +static void +module_free(void *mod) +{ + (void)module_clear((PyObject *)mod); +} + +static int +module_init(asyncio_state *state) { PyObject *module = NULL; - asyncio_mod = PyImport_ImportModule("asyncio"); - if (asyncio_mod == NULL) { - goto fail; - } - if (module_initialized != 0) { - return 0; - } - else { - module_initialized = 1; - } - - current_tasks = PyDict_New(); - if (current_tasks == NULL) { + state->asyncio_mod = PyImport_ImportModule("asyncio"); + if (state->asyncio_mod == NULL) { goto fail; } - iscoroutine_typecache = PySet_New(NULL); - if (iscoroutine_typecache == NULL) { + state->current_tasks = PyDict_New(); + if (state->current_tasks == NULL) { + goto fail; + } + + state->iscoroutine_typecache = PySet_New(NULL); + if (state->iscoroutine_typecache == NULL) { goto fail; } - context_kwname = Py_BuildValue("(s)", "context"); - if (context_kwname == NULL) { + state->context_kwname = Py_BuildValue("(s)", "context"); + if (state->context_kwname == NULL) { goto fail; } @@ -3361,32 +3494,32 @@ module_init(void) } WITH_MOD("asyncio.events") - GET_MOD_ATTR(asyncio_get_event_loop_policy, "get_event_loop_policy") + GET_MOD_ATTR(state->asyncio_get_event_loop_policy, "get_event_loop_policy") WITH_MOD("asyncio.base_futures") - GET_MOD_ATTR(asyncio_future_repr_info_func, "_future_repr_info") + GET_MOD_ATTR(state->asyncio_future_repr_func, "_future_repr") WITH_MOD("asyncio.exceptions") - GET_MOD_ATTR(asyncio_InvalidStateError, "InvalidStateError") - GET_MOD_ATTR(asyncio_CancelledError, "CancelledError") + GET_MOD_ATTR(state->asyncio_InvalidStateError, "InvalidStateError") + GET_MOD_ATTR(state->asyncio_CancelledError, "CancelledError") WITH_MOD("asyncio.base_tasks") - GET_MOD_ATTR(asyncio_task_repr_info_func, "_task_repr_info") - GET_MOD_ATTR(asyncio_task_get_stack_func, "_task_get_stack") - GET_MOD_ATTR(asyncio_task_print_stack_func, "_task_print_stack") + GET_MOD_ATTR(state->asyncio_task_repr_func, "_task_repr") + GET_MOD_ATTR(state->asyncio_task_get_stack_func, "_task_get_stack") + GET_MOD_ATTR(state->asyncio_task_print_stack_func, "_task_print_stack") WITH_MOD("asyncio.coroutines") - GET_MOD_ATTR(asyncio_iscoroutine_func, "iscoroutine") + GET_MOD_ATTR(state->asyncio_iscoroutine_func, "iscoroutine") WITH_MOD("traceback") - GET_MOD_ATTR(traceback_extract_stack, "extract_stack") + GET_MOD_ATTR(state->traceback_extract_stack, "extract_stack") PyObject *weak_set; WITH_MOD("weakref") GET_MOD_ATTR(weak_set, "WeakSet"); - all_tasks = PyObject_CallNoArgs(weak_set); + state->all_tasks = PyObject_CallNoArgs(weak_set); Py_CLEAR(weak_set); - if (all_tasks == NULL) { + if (state->all_tasks == NULL) { goto fail; } @@ -3395,7 +3528,6 @@ module_init(void) fail: Py_CLEAR(module); - module_free(NULL); return -1; #undef WITH_MOD @@ -3405,8 +3537,8 @@ fail: PyDoc_STRVAR(module_doc, "Accelerator module for asyncio"); static PyMethodDef asyncio_methods[] = { + _ASYNCIO_CURRENT_TASK_METHODDEF _ASYNCIO_GET_EVENT_LOOP_METHODDEF - _ASYNCIO__GET_EVENT_LOOP_METHODDEF _ASYNCIO_GET_RUNNING_LOOP_METHODDEF _ASYNCIO__GET_RUNNING_LOOP_METHODDEF _ASYNCIO__SET_RUNNING_LOOP_METHODDEF @@ -3417,64 +3549,70 @@ static PyMethodDef asyncio_methods[] = { {NULL, NULL} }; -static struct PyModuleDef _asynciomodule = { - PyModuleDef_HEAD_INIT, /* m_base */ - "_asyncio", /* m_name */ - module_doc, /* m_doc */ - -1, /* m_size */ - asyncio_methods, /* m_methods */ - NULL, /* m_slots */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - (freefunc)module_free /* m_free */ +static int +module_exec(PyObject *mod) +{ + asyncio_state *state = get_asyncio_state(mod); + +#define CREATE_TYPE(m, tp, spec, base) \ + do { \ + tp = (PyTypeObject *)PyType_FromMetaclass(NULL, m, spec, \ + (PyObject *)base); \ + if (tp == NULL) { \ + return -1; \ + } \ + } while (0) + + CREATE_TYPE(mod, state->TaskStepMethWrapper_Type, &TaskStepMethWrapper_spec, NULL); + CREATE_TYPE(mod, state->FutureIterType, &FutureIter_spec, NULL); + CREATE_TYPE(mod, state->FutureType, &Future_spec, NULL); + CREATE_TYPE(mod, state->TaskType, &Task_spec, state->FutureType); + +#undef CREATE_TYPE + + if (PyModule_AddType(mod, state->FutureType) < 0) { + return -1; + } + + if (PyModule_AddType(mod, state->TaskType) < 0) { + return -1; + } + // Must be done after types are added to avoid a circular dependency + if (module_init(state) < 0) { + return -1; + } + + if (PyModule_AddObjectRef(mod, "_all_tasks", state->all_tasks) < 0) { + return -1; + } + + if (PyModule_AddObjectRef(mod, "_current_tasks", state->current_tasks) < 0) { + return -1; + } + + + return 0; +} + +static struct PyModuleDef_Slot module_slots[] = { + {Py_mod_exec, module_exec}, + {0, NULL}, }; +static struct PyModuleDef _asynciomodule = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_asyncio", + .m_doc = module_doc, + .m_size = sizeof(asyncio_state), + .m_methods = asyncio_methods, + .m_slots = module_slots, + .m_traverse = module_traverse, + .m_clear = module_clear, + .m_free = (freefunc)module_free, +}; PyMODINIT_FUNC PyInit__asyncio(void) { - if (module_init() < 0) { - return NULL; - } - if (PyType_Ready(&FutureIterType) < 0) { - return NULL; - } - if (PyType_Ready(&TaskStepMethWrapper_Type) < 0) { - return NULL; - } - if (PyType_Ready(&PyRunningLoopHolder_Type) < 0) { - return NULL; - } - - PyObject *m = PyModule_Create(&_asynciomodule); - if (m == NULL) { - return NULL; - } - - /* FutureType and TaskType are made ready by PyModule_AddType() calls below. */ - if (PyModule_AddType(m, &FutureType) < 0) { - Py_DECREF(m); - return NULL; - } - - if (PyModule_AddType(m, &TaskType) < 0) { - Py_DECREF(m); - return NULL; - } - - Py_INCREF(all_tasks); - if (PyModule_AddObject(m, "_all_tasks", all_tasks) < 0) { - Py_DECREF(all_tasks); - Py_DECREF(m); - return NULL; - } - - Py_INCREF(current_tasks); - if (PyModule_AddObject(m, "_current_tasks", current_tasks) < 0) { - Py_DECREF(current_tasks); - Py_DECREF(m); - return NULL; - } - - return m; + return PyModuleDef_Init(&_asynciomodule); } diff --git a/Modules/_bisectmodule.c b/Modules/_bisectmodule.c index 26c4b9bfb26..9ceb3ae46fe 100644 --- a/Modules/_bisectmodule.c +++ b/Modules/_bisectmodule.c @@ -13,7 +13,37 @@ module _bisect #include "clinic/_bisectmodule.c.h" -_Py_IDENTIFIER(insert); +typedef struct { + PyObject *str_insert; +} bisect_state; + +static inline bisect_state* +get_bisect_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (bisect_state *)state; +} + +static ssizeargfunc +get_sq_item(PyObject *s) +{ + // The parts of PySequence_GetItem that we only need to do once + PyTypeObject *tp = Py_TYPE(s); + PySequenceMethods *m = tp->tp_as_sequence; + if (m && m->sq_item) { + return m->sq_item; + } + const char *msg; + if (tp->tp_as_mapping && tp->tp_as_mapping->mp_subscript) { + msg = "%.200s is not a sequence"; + } + else { + msg = "'%.200s' object does not support indexing"; + } + PyErr_Format(PyExc_TypeError, msg, tp->tp_name); + return NULL; +} static inline Py_ssize_t internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi, @@ -32,32 +62,86 @@ internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t if (hi < 0) return -1; } + ssizeargfunc sq_item = get_sq_item(list); + if (sq_item == NULL) { + return -1; + } + if (Py_EnterRecursiveCall("in _bisect.bisect_right") < 0) { + return -1; + } + PyTypeObject *tp = Py_TYPE(item); + richcmpfunc compare = tp->tp_richcompare; while (lo < hi) { /* The (size_t)cast ensures that the addition and subsequent division are performed as unsigned operations, avoiding difficulties from signed overflow. (See issue 13496.) */ mid = ((size_t)lo + hi) / 2; - litem = PySequence_GetItem(list, mid); - if (litem == NULL) - return -1; + assert(mid >= 0); + // PySequence_GetItem, but we already checked the types. + litem = sq_item(list, mid); + assert((PyErr_Occurred() == NULL) ^ (litem == NULL)); + if (litem == NULL) { + goto error; + } if (key != Py_None) { PyObject *newitem = PyObject_CallOneArg(key, litem); if (newitem == NULL) { - Py_DECREF(litem); - return -1; + goto error; } Py_SETREF(litem, newitem); } - res = PyObject_RichCompareBool(item, litem, Py_LT); + /* if item < key(list[mid]): + * hi = mid + * else: + * lo = mid + 1 + */ + if (compare != NULL && Py_IS_TYPE(litem, tp)) { + // A fast path for comparing objects of the same type + PyObject *res_obj = compare(item, litem, Py_LT); + if (res_obj == Py_True) { + Py_DECREF(res_obj); + Py_DECREF(litem); + hi = mid; + continue; + } + if (res_obj == Py_False) { + Py_DECREF(res_obj); + Py_DECREF(litem); + lo = mid + 1; + continue; + } + if (res_obj == NULL) { + goto error; + } + if (res_obj == Py_NotImplemented) { + Py_DECREF(res_obj); + compare = NULL; + res = PyObject_RichCompareBool(item, litem, Py_LT); + } + else { + res = PyObject_IsTrue(res_obj); + Py_DECREF(res_obj); + } + } + else { + // A default path for comparing arbitrary objects + res = PyObject_RichCompareBool(item, litem, Py_LT); + } + if (res < 0) { + goto error; + } Py_DECREF(litem); - if (res < 0) - return -1; if (res) hi = mid; else lo = mid + 1; } + Py_LeaveRecursiveCall(); return lo; +error: + Py_LeaveRecursiveCall(); + Py_XDECREF(litem); + return -1; } /*[clinic input] @@ -118,7 +202,7 @@ _bisect_insort_right_impl(PyObject *module, PyObject *a, PyObject *x, index = internal_bisect_right(a, x, lo, hi, key); } else { key_x = PyObject_CallOneArg(key, x); - if (x == NULL) { + if (key_x == NULL) { return NULL; } index = internal_bisect_right(a, key_x, lo, hi, key); @@ -131,7 +215,8 @@ _bisect_insort_right_impl(PyObject *module, PyObject *a, PyObject *x, return NULL; } else { - result = _PyObject_CallMethodId(a, &PyId_insert, "nO", index, x); + bisect_state *state = get_bisect_state(module); + result = _PyObject_CallMethod(a, state->str_insert, "nO", index, x); if (result == NULL) return NULL; Py_DECREF(result); @@ -157,32 +242,86 @@ internal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t h if (hi < 0) return -1; } + ssizeargfunc sq_item = get_sq_item(list); + if (sq_item == NULL) { + return -1; + } + if (Py_EnterRecursiveCall("in _bisect.bisect_left") < 0) { + return -1; + } + PyTypeObject *tp = Py_TYPE(item); + richcmpfunc compare = tp->tp_richcompare; while (lo < hi) { /* The (size_t)cast ensures that the addition and subsequent division are performed as unsigned operations, avoiding difficulties from signed overflow. (See issue 13496.) */ mid = ((size_t)lo + hi) / 2; - litem = PySequence_GetItem(list, mid); - if (litem == NULL) - return -1; + assert(mid >= 0); + // PySequence_GetItem, but we already checked the types. + litem = sq_item(list, mid); + assert((PyErr_Occurred() == NULL) ^ (litem == NULL)); + if (litem == NULL) { + goto error; + } if (key != Py_None) { PyObject *newitem = PyObject_CallOneArg(key, litem); if (newitem == NULL) { - Py_DECREF(litem); - return -1; + goto error; } Py_SETREF(litem, newitem); } - res = PyObject_RichCompareBool(litem, item, Py_LT); + /* if key(list[mid]) < item: + * lo = mid + 1 + * else: + * hi = mid + */ + if (compare != NULL && Py_IS_TYPE(litem, tp)) { + // A fast path for comparing objects of the same type + PyObject *res_obj = compare(litem, item, Py_LT); + if (res_obj == Py_True) { + Py_DECREF(res_obj); + Py_DECREF(litem); + lo = mid + 1; + continue; + } + if (res_obj == Py_False) { + Py_DECREF(res_obj); + Py_DECREF(litem); + hi = mid; + continue; + } + if (res_obj == NULL) { + goto error; + } + if (res_obj == Py_NotImplemented) { + Py_DECREF(res_obj); + compare = NULL; + res = PyObject_RichCompareBool(litem, item, Py_LT); + } + else { + res = PyObject_IsTrue(res_obj); + Py_DECREF(res_obj); + } + } + else { + // A default path for comparing arbitrary objects + res = PyObject_RichCompareBool(litem, item, Py_LT); + } + if (res < 0) { + goto error; + } Py_DECREF(litem); - if (res < 0) - return -1; if (res) lo = mid + 1; else hi = mid; } + Py_LeaveRecursiveCall(); return lo; +error: + Py_LeaveRecursiveCall(); + Py_XDECREF(litem); + return -1; } @@ -245,7 +384,7 @@ _bisect_insort_left_impl(PyObject *module, PyObject *a, PyObject *x, index = internal_bisect_left(a, x, lo, hi, key); } else { key_x = PyObject_CallOneArg(key, x); - if (x == NULL) { + if (key_x == NULL) { return NULL; } index = internal_bisect_left(a, key_x, lo, hi, key); @@ -257,7 +396,8 @@ _bisect_insort_left_impl(PyObject *module, PyObject *a, PyObject *x, if (PyList_Insert(a, index, x) < 0) return NULL; } else { - result = _PyObject_CallMethodId(a, &PyId_insert, "nO", index, x); + bisect_state *state = get_bisect_state(module); + result = _PyObject_CallMethod(a, state->str_insert, "nO", index, x); if (result == NULL) return NULL; Py_DECREF(result); @@ -282,13 +422,45 @@ having to sort the list after each insertion. For long lists of items with\n\ expensive comparison operations, this can be an improvement over the more\n\ common approach.\n"); +static int +bisect_clear(PyObject *module) +{ + bisect_state *state = get_bisect_state(module); + Py_CLEAR(state->str_insert); + return 0; +} + +static void +bisect_free(void *module) +{ + bisect_clear((PyObject *)module); +} + +static int +bisect_modexec(PyObject *m) +{ + bisect_state *state = get_bisect_state(m); + state->str_insert = PyUnicode_InternFromString("insert"); + if (state->str_insert == NULL) { + return -1; + } + return 0; +} + +static PyModuleDef_Slot bisect_slots[] = { + {Py_mod_exec, bisect_modexec}, + {0, NULL} +}; static struct PyModuleDef _bisectmodule = { PyModuleDef_HEAD_INIT, .m_name = "_bisect", + .m_size = sizeof(bisect_state), .m_doc = module_doc, .m_methods = bisect_methods, - .m_size = 0 + .m_slots = bisect_slots, + .m_clear = bisect_clear, + .m_free = bisect_free, }; PyMODINIT_FUNC diff --git a/Modules/_blake2/blake2b_impl.c b/Modules/_blake2/blake2b_impl.c index e1421dd8ff8..c2cac98c752 100644 --- a/Modules/_blake2/blake2b_impl.c +++ b/Modules/_blake2/blake2b_impl.c @@ -21,14 +21,9 @@ #include "pycore_strhex.h" // _Py_strhex() #include "../hashlib.h" -#include "blake2ns.h" - -#define HAVE_BLAKE2B 1 -#define BLAKE2_LOCAL_INLINE(type) Py_LOCAL_INLINE(type) - -#include "impl/blake2.h" -#include "impl/blake2-impl.h" /* for secure_zero_memory() and store48() */ +#include "blake2module.h" +#ifndef HAVE_LIBB2 /* pure SSE2 implementation is very slow, so only use the more optimized SSSE3+ * https://bugs.python.org/issue31834 */ #if defined(__SSSE3__) || defined(__SSE4_1__) || defined(__AVX__) || defined(__XOP__) @@ -36,10 +31,13 @@ #else #include "impl/blake2b-ref.c" #endif +#endif // !HAVE_LIBB2 +#define HAVE_BLAKE2B 1 extern PyType_Spec blake2b_type_spec; + typedef struct { PyObject_HEAD blake2b_param param; diff --git a/Modules/_blake2/blake2module.c b/Modules/_blake2/blake2module.c index 3b6bba277a3..44d783b40d0 100644 --- a/Modules/_blake2/blake2module.c +++ b/Modules/_blake2/blake2module.c @@ -13,8 +13,7 @@ #endif #include "Python.h" - -#include "impl/blake2.h" +#include "blake2module.h" extern PyType_Spec blake2b_type_spec; extern PyType_Spec blake2s_type_spec; diff --git a/Modules/_blake2/blake2ns.h b/Modules/_blake2/blake2module.h similarity index 77% rename from Modules/_blake2/blake2ns.h rename to Modules/_blake2/blake2module.h index 53bce8e0fcd..aa8f281178e 100644 --- a/Modules/_blake2/blake2ns.h +++ b/Modules/_blake2/blake2module.h @@ -1,9 +1,13 @@ -/* Prefix all public blake2 symbols with PyBlake2_ - */ +#ifndef Py_BLAKE2MODULE_H +#define Py_BLAKE2MODULE_H -#ifndef Py_BLAKE2_NS -#define Py_BLAKE2_NS +#ifdef HAVE_LIBB2 +#include +#else +// use vendored copy of blake2 + +// Prefix all public blake2 symbols with PyBlake2_ #define blake2b PyBlake2_blake2b #define blake2b_compress PyBlake2_blake2b_compress #define blake2b_final PyBlake2_blake2b_final @@ -29,4 +33,11 @@ #define blake2sp_init_key PyBlake2_blake2sp_init_key #define blake2sp_update PyBlake2_blake2sp_update -#endif /* Py_BLAKE2_NS */ +#include "impl/blake2.h" + +#endif // HAVE_LIBB2 + +// for secure_zero_memory(), store32(), store48(), and store64() +#include "impl/blake2-impl.h" + +#endif // Py_BLAKE2MODULE_H diff --git a/Modules/_blake2/blake2s_impl.c b/Modules/_blake2/blake2s_impl.c index 763c0178e6b..1c47328ece1 100644 --- a/Modules/_blake2/blake2s_impl.c +++ b/Modules/_blake2/blake2s_impl.c @@ -18,17 +18,12 @@ #endif #include "Python.h" -#include "pycore_strhex.h" // _Py_strhex() +#include "pycore_strhex.h" // _Py_strhex() #include "../hashlib.h" -#include "blake2ns.h" - -#define HAVE_BLAKE2S 1 -#define BLAKE2_LOCAL_INLINE(type) Py_LOCAL_INLINE(type) - -#include "impl/blake2.h" -#include "impl/blake2-impl.h" /* for secure_zero_memory() and store48() */ +#include "blake2module.h" +#ifndef HAVE_LIBB2 /* pure SSE2 implementation is very slow, so only use the more optimized SSSE3+ * https://bugs.python.org/issue31834 */ #if defined(__SSSE3__) || defined(__SSE4_1__) || defined(__AVX__) || defined(__XOP__) @@ -36,9 +31,13 @@ #else #include "impl/blake2s-ref.c" #endif +#endif // !HAVE_LIBB2 + +#define HAVE_BLAKE2S 1 extern PyType_Spec blake2s_type_spec; + typedef struct { PyObject_HEAD blake2s_param param; diff --git a/Modules/_blake2/clinic/blake2b_impl.c.h b/Modules/_blake2/clinic/blake2b_impl.c.h index 4e74e0885cf..99b0f098cc2 100644 --- a/Modules/_blake2/clinic/blake2b_impl.c.h +++ b/Modules/_blake2/clinic/blake2b_impl.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(py_blake2b_new__doc__, "blake2b(data=b\'\', /, *, digest_size=_blake2.blake2b.MAX_DIGEST_SIZE,\n" " key=b\'\', salt=b\'\', person=b\'\', fanout=1, depth=1, leaf_size=0,\n" @@ -22,8 +28,31 @@ static PyObject * py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 12 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(digest_size), &_Py_ID(key), &_Py_ID(salt), &_Py_ID(person), &_Py_ID(fanout), &_Py_ID(depth), &_Py_ID(leaf_size), &_Py_ID(node_offset), &_Py_ID(node_depth), &_Py_ID(inner_size), &_Py_ID(last_node), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "blake2b", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "blake2b", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[13]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -247,4 +276,4 @@ _blake2_blake2b_hexdigest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2b_hexdigest_impl(self); } -/*[clinic end generated code: output=10eb47aba77f192d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=996b4fe396824797 input=a9049054013a1b77]*/ diff --git a/Modules/_blake2/clinic/blake2s_impl.c.h b/Modules/_blake2/clinic/blake2s_impl.c.h index 0f0d9835fbf..9b821fbcd62 100644 --- a/Modules/_blake2/clinic/blake2s_impl.c.h +++ b/Modules/_blake2/clinic/blake2s_impl.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(py_blake2s_new__doc__, "blake2s(data=b\'\', /, *, digest_size=_blake2.blake2s.MAX_DIGEST_SIZE,\n" " key=b\'\', salt=b\'\', person=b\'\', fanout=1, depth=1, leaf_size=0,\n" @@ -22,8 +28,31 @@ static PyObject * py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 12 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(digest_size), &_Py_ID(key), &_Py_ID(salt), &_Py_ID(person), &_Py_ID(fanout), &_Py_ID(depth), &_Py_ID(leaf_size), &_Py_ID(node_offset), &_Py_ID(node_depth), &_Py_ID(inner_size), &_Py_ID(last_node), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "blake2s", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "blake2s", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[13]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -247,4 +276,4 @@ _blake2_blake2s_hexdigest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2s_hexdigest_impl(self); } -/*[clinic end generated code: output=f7ee8092ed67e9c7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bd0fb7639e450618 input=a9049054013a1b77]*/ diff --git a/Modules/_blake2/impl/blake2-dispatch.c b/Modules/_blake2/impl/blake2-dispatch.c deleted file mode 100644 index 96bb3408bb1..00000000000 --- a/Modules/_blake2/impl/blake2-dispatch.c +++ /dev/null @@ -1,577 +0,0 @@ -/* - BLAKE2 reference source code package - optimized C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ -#include -#if defined(WIN32) -#include -#endif -#include "blake2.h" - -#if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64) -#define HAVE_X86 -#endif - -typedef enum -{ - NONE = 0, -#if defined(HAVE_X86) - SSE2 = 1, - SSSE3 = 2, - SSE41 = 3, - AVX = 4, - XOP = 5, - /* AVX2 = 6, */ -#endif -} cpu_feature_t; - -static const char feature_names[][8] = -{ - "none", -#if defined(HAVE_X86) - "sse2", - "ssse3", - "sse41", - "avx", - "xop", - /* "avx2" */ -#endif -}; - -#if defined(HAVE_X86) - -#if defined(__GNUC__) -static inline void cpuid( uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx ) -{ - __asm__ __volatile__( -#if defined(__i386__) /* This is needed for -fPIC to work on i386 */ - "movl %%ebx, %%esi\n\t" -#endif - "cpuid\n\t" -#if defined(__i386__) - "xchgl %%ebx, %%esi\n\t" - : "=a"( *eax ), "=S"( *ebx ), "=c"( *ecx ), "=d"( *edx ) : "a"( *eax ) ); -#else - : "=a"( *eax ), "=b"( *ebx ), "=c"( *ecx ), "=d"( *edx ) : "a"( *eax ) ); -#endif -} - -static inline uint64_t xgetbv(uint32_t xcr) -{ - uint32_t a, d; - __asm__ __volatile__( - "xgetbv" - : "=a"(a),"=d"(d) - : "c"(xcr) - ); - return ((uint64_t)d << 32) | a; -} - -#elif defined(_MSC_VER) -#include -static inline void cpuid( uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx ) -{ - int regs[4]; - __cpuid( regs, *eax ); - *eax = regs[0]; - *ebx = regs[1]; - *ecx = regs[2]; - *edx = regs[3]; -} -#else -#error "Don't know how to call cpuid on this compiler!" -#endif - -#endif /* HAVE_X86 */ - -static inline cpu_feature_t get_cpu_features( void ) -{ -#if defined(HAVE_X86) - static volatile int initialized = 0; - static cpu_feature_t feature = NONE; // Safe default - uint32_t eax, ecx, edx, ebx; - - if( initialized ) - return feature; - - eax = 1; - cpuid( &eax, &ebx, &ecx, &edx ); - - if( 1 & ( edx >> 26 ) ) - feature = SSE2; - - if( 1 & ( ecx >> 9 ) ) - feature = SSSE3; - - if( 1 & ( ecx >> 19 ) ) - feature = SSE41; - -#if defined(WIN32) /* Work around the fact that Windows <7 does NOT support AVX... */ - if( IsProcessorFeaturePresent(17) ) /* Some environments don't know about PF_XSAVE_ENABLED */ -#endif - { - /* check for AVX and OSXSAVE bits */ - if( 1 & ( ecx >> 28 ) & (ecx >> 27) ) { -#if !defined(WIN32) /* Already checked for this in WIN32 */ - if( (xgetbv(0) & 6) == 6 ) /* XCR0 */ -#endif - feature = AVX; - } - - - eax = 0x80000001; - cpuid( &eax, &ebx, &ecx, &edx ); - - if( 1 & ( ecx >> 11 ) ) - feature = XOP; - } - - /* For future architectures */ - /* - eax = 7; ecx = 0; - cpuid(&eax, &ebx, &ecx, &edx); - - if(1&(ebx >> 5)) - feature = AVX2; - */ - /* fprintf( stderr, "Using %s engine\n", feature_names[feature] ); */ - initialized = 1; - return feature; -#else - return NONE; -#endif -} - - - -#if defined(__cplusplus) -extern "C" { -#endif - int blake2b_init_ref( blake2b_state *S, size_t outlen ); - int blake2b_init_key_ref( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2b_init_param_ref( blake2b_state *S, const blake2b_param *P ); - int blake2b_update_ref( blake2b_state *S, const uint8_t *in, size_t inlen ); - int blake2b_final_ref( blake2b_state *S, uint8_t *out, size_t outlen ); - int blake2b_ref( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - -#if defined(HAVE_X86) - - int blake2b_init_sse2( blake2b_state *S, size_t outlen ); - int blake2b_init_key_sse2( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2b_init_param_sse2( blake2b_state *S, const blake2b_param *P ); - int blake2b_update_sse2( blake2b_state *S, const uint8_t *in, size_t inlen ); - int blake2b_final_sse2( blake2b_state *S, uint8_t *out, size_t outlen ); - int blake2b_sse2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2b_init_ssse3( blake2b_state *S, size_t outlen ); - int blake2b_init_key_ssse3( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2b_init_param_ssse3( blake2b_state *S, const blake2b_param *P ); - int blake2b_update_ssse3( blake2b_state *S, const uint8_t *in, size_t inlen ); - int blake2b_final_ssse3( blake2b_state *S, uint8_t *out, size_t outlen ); - int blake2b_ssse3( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2b_init_sse41( blake2b_state *S, size_t outlen ); - int blake2b_init_key_sse41( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2b_init_param_sse41( blake2b_state *S, const blake2b_param *P ); - int blake2b_update_sse41( blake2b_state *S, const uint8_t *in, size_t inlen ); - int blake2b_final_sse41( blake2b_state *S, uint8_t *out, size_t outlen ); - int blake2b_sse41( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2b_init_avx( blake2b_state *S, size_t outlen ); - int blake2b_init_key_avx( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2b_init_param_avx( blake2b_state *S, const blake2b_param *P ); - int blake2b_update_avx( blake2b_state *S, const uint8_t *in, size_t inlen ); - int blake2b_final_avx( blake2b_state *S, uint8_t *out, size_t outlen ); - int blake2b_avx( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2b_init_xop( blake2b_state *S, size_t outlen ); - int blake2b_init_key_xop( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2b_init_param_xop( blake2b_state *S, const blake2b_param *P ); - int blake2b_update_xop( blake2b_state *S, const uint8_t *in, size_t inlen ); - int blake2b_final_xop( blake2b_state *S, uint8_t *out, size_t outlen ); - int blake2b_xop( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - -#endif /* HAVE_X86 */ - - int blake2s_init_ref( blake2s_state *S, size_t outlen ); - int blake2s_init_key_ref( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2s_init_param_ref( blake2s_state *S, const blake2s_param *P ); - int blake2s_update_ref( blake2s_state *S, const uint8_t *in, size_t inlen ); - int blake2s_final_ref( blake2s_state *S, uint8_t *out, size_t outlen ); - int blake2s_ref( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - -#if defined(HAVE_X86) - - int blake2s_init_sse2( blake2s_state *S, size_t outlen ); - int blake2s_init_key_sse2( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2s_init_param_sse2( blake2s_state *S, const blake2s_param *P ); - int blake2s_update_sse2( blake2s_state *S, const uint8_t *in, size_t inlen ); - int blake2s_final_sse2( blake2s_state *S, uint8_t *out, size_t outlen ); - int blake2s_sse2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2s_init_ssse3( blake2s_state *S, size_t outlen ); - int blake2s_init_key_ssse3( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2s_init_param_ssse3( blake2s_state *S, const blake2s_param *P ); - int blake2s_update_ssse3( blake2s_state *S, const uint8_t *in, size_t inlen ); - int blake2s_final_ssse3( blake2s_state *S, uint8_t *out, size_t outlen ); - int blake2s_ssse3( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2s_init_sse41( blake2s_state *S, size_t outlen ); - int blake2s_init_key_sse41( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2s_init_param_sse41( blake2s_state *S, const blake2s_param *P ); - int blake2s_update_sse41( blake2s_state *S, const uint8_t *in, size_t inlen ); - int blake2s_final_sse41( blake2s_state *S, uint8_t *out, size_t outlen ); - int blake2s_sse41( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2s_init_avx( blake2s_state *S, size_t outlen ); - int blake2s_init_key_avx( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2s_init_param_avx( blake2s_state *S, const blake2s_param *P ); - int blake2s_update_avx( blake2s_state *S, const uint8_t *in, size_t inlen ); - int blake2s_final_avx( blake2s_state *S, uint8_t *out, size_t outlen ); - int blake2s_avx( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2s_init_xop( blake2s_state *S, size_t outlen ); - int blake2s_init_key_xop( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2s_init_param_xop( blake2s_state *S, const blake2s_param *P ); - int blake2s_update_xop( blake2s_state *S, const uint8_t *in, size_t inlen ); - int blake2s_final_xop( blake2s_state *S, uint8_t *out, size_t outlen ); - int blake2s_xop( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - -#endif /* HAVE_X86 */ - -#if defined(__cplusplus) -} -#endif - -typedef int ( *blake2b_init_fn )( blake2b_state *, size_t ); -typedef int ( *blake2b_init_key_fn )( blake2b_state *, size_t, const void *, size_t ); -typedef int ( *blake2b_init_param_fn )( blake2b_state *, const blake2b_param * ); -typedef int ( *blake2b_update_fn )( blake2b_state *, const uint8_t *, size_t ); -typedef int ( *blake2b_final_fn )( blake2b_state *, uint8_t *, size_t ); -typedef int ( *blake2b_fn )( uint8_t *, const void *, const void *, size_t, size_t, size_t ); - -typedef int ( *blake2s_init_fn )( blake2s_state *, size_t ); -typedef int ( *blake2s_init_key_fn )( blake2s_state *, size_t, const void *, size_t ); -typedef int ( *blake2s_init_param_fn )( blake2s_state *, const blake2s_param * ); -typedef int ( *blake2s_update_fn )( blake2s_state *, const uint8_t *, size_t ); -typedef int ( *blake2s_final_fn )( blake2s_state *, uint8_t *, size_t ); -typedef int ( *blake2s_fn )( uint8_t *, const void *, const void *, size_t, size_t, size_t ); - -static const blake2b_init_fn blake2b_init_table[] = -{ - blake2b_init_ref, -#if defined(HAVE_X86) - blake2b_init_sse2, - blake2b_init_ssse3, - blake2b_init_sse41, - blake2b_init_avx, - blake2b_init_xop -#endif -}; - -static const blake2b_init_key_fn blake2b_init_key_table[] = -{ - blake2b_init_key_ref, -#if defined(HAVE_X86) - blake2b_init_key_sse2, - blake2b_init_key_ssse3, - blake2b_init_key_sse41, - blake2b_init_key_avx, - blake2b_init_key_xop -#endif -}; - -static const blake2b_init_param_fn blake2b_init_param_table[] = -{ - blake2b_init_param_ref, -#if defined(HAVE_X86) - blake2b_init_param_sse2, - blake2b_init_param_ssse3, - blake2b_init_param_sse41, - blake2b_init_param_avx, - blake2b_init_param_xop -#endif -}; - -static const blake2b_update_fn blake2b_update_table[] = -{ - blake2b_update_ref, -#if defined(HAVE_X86) - blake2b_update_sse2, - blake2b_update_ssse3, - blake2b_update_sse41, - blake2b_update_avx, - blake2b_update_xop -#endif -}; - -static const blake2b_final_fn blake2b_final_table[] = -{ - blake2b_final_ref, -#if defined(HAVE_X86) - blake2b_final_sse2, - blake2b_final_ssse3, - blake2b_final_sse41, - blake2b_final_avx, - blake2b_final_xop -#endif -}; - -static const blake2b_fn blake2b_table[] = -{ - blake2b_ref, -#if defined(HAVE_X86) - blake2b_sse2, - blake2b_ssse3, - blake2b_sse41, - blake2b_avx, - blake2b_xop -#endif -}; - -static const blake2s_init_fn blake2s_init_table[] = -{ - blake2s_init_ref, -#if defined(HAVE_X86) - blake2s_init_sse2, - blake2s_init_ssse3, - blake2s_init_sse41, - blake2s_init_avx, - blake2s_init_xop -#endif -}; - -static const blake2s_init_key_fn blake2s_init_key_table[] = -{ - blake2s_init_key_ref, -#if defined(HAVE_X86) - blake2s_init_key_sse2, - blake2s_init_key_ssse3, - blake2s_init_key_sse41, - blake2s_init_key_avx, - blake2s_init_key_xop -#endif -}; - -static const blake2s_init_param_fn blake2s_init_param_table[] = -{ - blake2s_init_param_ref, -#if defined(HAVE_X86) - blake2s_init_param_sse2, - blake2s_init_param_ssse3, - blake2s_init_param_sse41, - blake2s_init_param_avx, - blake2s_init_param_xop -#endif -}; - -static const blake2s_update_fn blake2s_update_table[] = -{ - blake2s_update_ref, -#if defined(HAVE_X86) - blake2s_update_sse2, - blake2s_update_ssse3, - blake2s_update_sse41, - blake2s_update_avx, - blake2s_update_xop -#endif -}; - -static const blake2s_final_fn blake2s_final_table[] = -{ - blake2s_final_ref, -#if defined(HAVE_X86) - blake2s_final_sse2, - blake2s_final_ssse3, - blake2s_final_sse41, - blake2s_final_avx, - blake2s_final_xop -#endif -}; - -static const blake2s_fn blake2s_table[] = -{ - blake2s_ref, -#if defined(HAVE_X86) - blake2s_sse2, - blake2s_ssse3, - blake2s_sse41, - blake2s_avx, - blake2s_xop -#endif -}; - -#if defined(__cplusplus) -extern "C" { -#endif - int blake2b_init_dispatch( blake2b_state *S, size_t outlen ); - int blake2b_init_key_dispatch( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2b_init_param_dispatch( blake2b_state *S, const blake2b_param *P ); - int blake2b_update_dispatch( blake2b_state *S, const uint8_t *in, size_t inlen ); - int blake2b_final_dispatch( blake2b_state *S, uint8_t *out, size_t outlen ); - int blake2b_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2s_init_dispatch( blake2s_state *S, size_t outlen ); - int blake2s_init_key_dispatch( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2s_init_param_dispatch( blake2s_state *S, const blake2s_param *P ); - int blake2s_update_dispatch( blake2s_state *S, const uint8_t *in, size_t inlen ); - int blake2s_final_dispatch( blake2s_state *S, uint8_t *out, size_t outlen ); - int blake2s_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); -#if defined(__cplusplus) -} -#endif - -static blake2b_init_fn blake2b_init_ptr = blake2b_init_dispatch; -static blake2b_init_key_fn blake2b_init_key_ptr = blake2b_init_key_dispatch; -static blake2b_init_param_fn blake2b_init_param_ptr = blake2b_init_param_dispatch; -static blake2b_update_fn blake2b_update_ptr = blake2b_update_dispatch; -static blake2b_final_fn blake2b_final_ptr = blake2b_final_dispatch; -static blake2b_fn blake2b_ptr = blake2b_dispatch; - -static blake2s_init_fn blake2s_init_ptr = blake2s_init_dispatch; -static blake2s_init_key_fn blake2s_init_key_ptr = blake2s_init_key_dispatch; -static blake2s_init_param_fn blake2s_init_param_ptr = blake2s_init_param_dispatch; -static blake2s_update_fn blake2s_update_ptr = blake2s_update_dispatch; -static blake2s_final_fn blake2s_final_ptr = blake2s_final_dispatch; -static blake2s_fn blake2s_ptr = blake2s_dispatch; - -int blake2b_init_dispatch( blake2b_state *S, size_t outlen ) -{ - blake2b_init_ptr = blake2b_init_table[get_cpu_features()]; - return blake2b_init_ptr( S, outlen ); -} - -int blake2b_init_key_dispatch( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) -{ - blake2b_init_key_ptr = blake2b_init_key_table[get_cpu_features()]; - return blake2b_init_key_ptr( S, outlen, key, keylen ); -} - -int blake2b_init_param_dispatch( blake2b_state *S, const blake2b_param *P ) -{ - blake2b_init_param_ptr = blake2b_init_param_table[get_cpu_features()]; - return blake2b_init_param_ptr( S, P ); -} - -int blake2b_update_dispatch( blake2b_state *S, const uint8_t *in, size_t inlen ) -{ - blake2b_update_ptr = blake2b_update_table[get_cpu_features()]; - return blake2b_update_ptr( S, in, inlen ); -} - -int blake2b_final_dispatch( blake2b_state *S, uint8_t *out, size_t outlen ) -{ - blake2b_final_ptr = blake2b_final_table[get_cpu_features()]; - return blake2b_final_ptr( S, out, outlen ); -} - -int blake2b_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) -{ - blake2b_ptr = blake2b_table[get_cpu_features()]; - return blake2b_ptr( out, in, key, outlen, inlen, keylen ); -} - -BLAKE2_API int blake2b_init( blake2b_state *S, size_t outlen ) -{ - return blake2b_init_ptr( S, outlen ); -} - -BLAKE2_API int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) -{ - return blake2b_init_key_ptr( S, outlen, key, keylen ); -} - -BLAKE2_API int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) -{ - return blake2b_init_param_ptr( S, P ); -} - -BLAKE2_API int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen ) -{ - return blake2b_update_ptr( S, in, inlen ); -} - -BLAKE2_API int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen ) -{ - return blake2b_final_ptr( S, out, outlen ); -} - -BLAKE2_API int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) -{ - return blake2b_ptr( out, in, key, outlen, inlen, keylen ); -} - -int blake2s_init_dispatch( blake2s_state *S, size_t outlen ) -{ - blake2s_init_ptr = blake2s_init_table[get_cpu_features()]; - return blake2s_init_ptr( S, outlen ); -} - -int blake2s_init_key_dispatch( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) -{ - blake2s_init_key_ptr = blake2s_init_key_table[get_cpu_features()]; - return blake2s_init_key_ptr( S, outlen, key, keylen ); -} - -int blake2s_init_param_dispatch( blake2s_state *S, const blake2s_param *P ) -{ - blake2s_init_param_ptr = blake2s_init_param_table[get_cpu_features()]; - return blake2s_init_param_ptr( S, P ); -} - -int blake2s_update_dispatch( blake2s_state *S, const uint8_t *in, size_t inlen ) -{ - blake2s_update_ptr = blake2s_update_table[get_cpu_features()]; - return blake2s_update_ptr( S, in, inlen ); -} - -int blake2s_final_dispatch( blake2s_state *S, uint8_t *out, size_t outlen ) -{ - blake2s_final_ptr = blake2s_final_table[get_cpu_features()]; - return blake2s_final_ptr( S, out, outlen ); -} - -int blake2s_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) -{ - blake2s_ptr = blake2s_table[get_cpu_features()]; - return blake2s_ptr( out, in, key, outlen, inlen, keylen ); -} - -BLAKE2_API int blake2s_init( blake2s_state *S, size_t outlen ) -{ - return blake2s_init_ptr( S, outlen ); -} - -BLAKE2_API int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) -{ - return blake2s_init_key_ptr( S, outlen, key, keylen ); -} - -BLAKE2_API int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) -{ - return blake2s_init_param_ptr( S, P ); -} - -BLAKE2_API int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ) -{ - return blake2s_update_ptr( S, in, inlen ); -} - -BLAKE2_API int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen ) -{ - return blake2s_final_ptr( S, out, outlen ); -} - -BLAKE2_API int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) -{ - return blake2s_ptr( out, in, key, outlen, inlen, keylen ); -} - diff --git a/Modules/_blake2/impl/blake2-kat.h b/Modules/_blake2/impl/blake2-kat.h deleted file mode 100644 index 3d2072763aa..00000000000 --- a/Modules/_blake2/impl/blake2-kat.h +++ /dev/null @@ -1,16467 +0,0 @@ -/* - BLAKE2 reference source code package - optimized C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ -#pragma once -#ifndef __BLAKE2_KAT_H__ -#define __BLAKE2_KAT_H__ - - -#include - -#define KAT_LENGTH 256 - - - -static const uint8_t blake2s_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = -{ - { - 0x69, 0x21, 0x7A, 0x30, 0x79, 0x90, 0x80, 0x94, - 0xE1, 0x11, 0x21, 0xD0, 0x42, 0x35, 0x4A, 0x7C, - 0x1F, 0x55, 0xB6, 0x48, 0x2C, 0xA1, 0xA5, 0x1E, - 0x1B, 0x25, 0x0D, 0xFD, 0x1E, 0xD0, 0xEE, 0xF9 - }, - { - 0xE3, 0x4D, 0x74, 0xDB, 0xAF, 0x4F, 0xF4, 0xC6, - 0xAB, 0xD8, 0x71, 0xCC, 0x22, 0x04, 0x51, 0xD2, - 0xEA, 0x26, 0x48, 0x84, 0x6C, 0x77, 0x57, 0xFB, - 0xAA, 0xC8, 0x2F, 0xE5, 0x1A, 0xD6, 0x4B, 0xEA - }, - { - 0xDD, 0xAD, 0x9A, 0xB1, 0x5D, 0xAC, 0x45, 0x49, - 0xBA, 0x42, 0xF4, 0x9D, 0x26, 0x24, 0x96, 0xBE, - 0xF6, 0xC0, 0xBA, 0xE1, 0xDD, 0x34, 0x2A, 0x88, - 0x08, 0xF8, 0xEA, 0x26, 0x7C, 0x6E, 0x21, 0x0C - }, - { - 0xE8, 0xF9, 0x1C, 0x6E, 0xF2, 0x32, 0xA0, 0x41, - 0x45, 0x2A, 0xB0, 0xE1, 0x49, 0x07, 0x0C, 0xDD, - 0x7D, 0xD1, 0x76, 0x9E, 0x75, 0xB3, 0xA5, 0x92, - 0x1B, 0xE3, 0x78, 0x76, 0xC4, 0x5C, 0x99, 0x00 - }, - { - 0x0C, 0xC7, 0x0E, 0x00, 0x34, 0x8B, 0x86, 0xBA, - 0x29, 0x44, 0xD0, 0xC3, 0x20, 0x38, 0xB2, 0x5C, - 0x55, 0x58, 0x4F, 0x90, 0xDF, 0x23, 0x04, 0xF5, - 0x5F, 0xA3, 0x32, 0xAF, 0x5F, 0xB0, 0x1E, 0x20 - }, - { - 0xEC, 0x19, 0x64, 0x19, 0x10, 0x87, 0xA4, 0xFE, - 0x9D, 0xF1, 0xC7, 0x95, 0x34, 0x2A, 0x02, 0xFF, - 0xC1, 0x91, 0xA5, 0xB2, 0x51, 0x76, 0x48, 0x56, - 0xAE, 0x5B, 0x8B, 0x57, 0x69, 0xF0, 0xC6, 0xCD - }, - { - 0xE1, 0xFA, 0x51, 0x61, 0x8D, 0x7D, 0xF4, 0xEB, - 0x70, 0xCF, 0x0D, 0x5A, 0x9E, 0x90, 0x6F, 0x80, - 0x6E, 0x9D, 0x19, 0xF7, 0xF4, 0xF0, 0x1E, 0x3B, - 0x62, 0x12, 0x88, 0xE4, 0x12, 0x04, 0x05, 0xD6 - }, - { - 0x59, 0x80, 0x01, 0xFA, 0xFB, 0xE8, 0xF9, 0x4E, - 0xC6, 0x6D, 0xC8, 0x27, 0xD0, 0x12, 0xCF, 0xCB, - 0xBA, 0x22, 0x28, 0x56, 0x9F, 0x44, 0x8E, 0x89, - 0xEA, 0x22, 0x08, 0xC8, 0xBF, 0x76, 0x92, 0x93 - }, - { - 0xC7, 0xE8, 0x87, 0xB5, 0x46, 0x62, 0x36, 0x35, - 0xE9, 0x3E, 0x04, 0x95, 0x59, 0x8F, 0x17, 0x26, - 0x82, 0x19, 0x96, 0xC2, 0x37, 0x77, 0x05, 0xB9, - 0x3A, 0x1F, 0x63, 0x6F, 0x87, 0x2B, 0xFA, 0x2D - }, - { - 0xC3, 0x15, 0xA4, 0x37, 0xDD, 0x28, 0x06, 0x2A, - 0x77, 0x0D, 0x48, 0x19, 0x67, 0x13, 0x6B, 0x1B, - 0x5E, 0xB8, 0x8B, 0x21, 0xEE, 0x53, 0xD0, 0x32, - 0x9C, 0x58, 0x97, 0x12, 0x6E, 0x9D, 0xB0, 0x2C - }, - { - 0xBB, 0x47, 0x3D, 0xED, 0xDC, 0x05, 0x5F, 0xEA, - 0x62, 0x28, 0xF2, 0x07, 0xDA, 0x57, 0x53, 0x47, - 0xBB, 0x00, 0x40, 0x4C, 0xD3, 0x49, 0xD3, 0x8C, - 0x18, 0x02, 0x63, 0x07, 0xA2, 0x24, 0xCB, 0xFF - }, - { - 0x68, 0x7E, 0x18, 0x73, 0xA8, 0x27, 0x75, 0x91, - 0xBB, 0x33, 0xD9, 0xAD, 0xF9, 0xA1, 0x39, 0x12, - 0xEF, 0xEF, 0xE5, 0x57, 0xCA, 0xFC, 0x39, 0xA7, - 0x95, 0x26, 0x23, 0xE4, 0x72, 0x55, 0xF1, 0x6D - }, - { - 0x1A, 0xC7, 0xBA, 0x75, 0x4D, 0x6E, 0x2F, 0x94, - 0xE0, 0xE8, 0x6C, 0x46, 0xBF, 0xB2, 0x62, 0xAB, - 0xBB, 0x74, 0xF4, 0x50, 0xEF, 0x45, 0x6D, 0x6B, - 0x4D, 0x97, 0xAA, 0x80, 0xCE, 0x6D, 0xA7, 0x67 - }, - { - 0x01, 0x2C, 0x97, 0x80, 0x96, 0x14, 0x81, 0x6B, - 0x5D, 0x94, 0x94, 0x47, 0x7D, 0x4B, 0x68, 0x7D, - 0x15, 0xB9, 0x6E, 0xB6, 0x9C, 0x0E, 0x80, 0x74, - 0xA8, 0x51, 0x6F, 0x31, 0x22, 0x4B, 0x5C, 0x98 - }, - { - 0x91, 0xFF, 0xD2, 0x6C, 0xFA, 0x4D, 0xA5, 0x13, - 0x4C, 0x7E, 0xA2, 0x62, 0xF7, 0x88, 0x9C, 0x32, - 0x9F, 0x61, 0xF6, 0xA6, 0x57, 0x22, 0x5C, 0xC2, - 0x12, 0xF4, 0x00, 0x56, 0xD9, 0x86, 0xB3, 0xF4 - }, - { - 0xD9, 0x7C, 0x82, 0x8D, 0x81, 0x82, 0xA7, 0x21, - 0x80, 0xA0, 0x6A, 0x78, 0x26, 0x83, 0x30, 0x67, - 0x3F, 0x7C, 0x4E, 0x06, 0x35, 0x94, 0x7C, 0x04, - 0xC0, 0x23, 0x23, 0xFD, 0x45, 0xC0, 0xA5, 0x2D - }, - { - 0xEF, 0xC0, 0x4C, 0xDC, 0x39, 0x1C, 0x7E, 0x91, - 0x19, 0xBD, 0x38, 0x66, 0x8A, 0x53, 0x4E, 0x65, - 0xFE, 0x31, 0x03, 0x6D, 0x6A, 0x62, 0x11, 0x2E, - 0x44, 0xEB, 0xEB, 0x11, 0xF9, 0xC5, 0x70, 0x80 - }, - { - 0x99, 0x2C, 0xF5, 0xC0, 0x53, 0x44, 0x2A, 0x5F, - 0xBC, 0x4F, 0xAF, 0x58, 0x3E, 0x04, 0xE5, 0x0B, - 0xB7, 0x0D, 0x2F, 0x39, 0xFB, 0xB6, 0xA5, 0x03, - 0xF8, 0x9E, 0x56, 0xA6, 0x3E, 0x18, 0x57, 0x8A - }, - { - 0x38, 0x64, 0x0E, 0x9F, 0x21, 0x98, 0x3E, 0x67, - 0xB5, 0x39, 0xCA, 0xCC, 0xAE, 0x5E, 0xCF, 0x61, - 0x5A, 0xE2, 0x76, 0x4F, 0x75, 0xA0, 0x9C, 0x9C, - 0x59, 0xB7, 0x64, 0x83, 0xC1, 0xFB, 0xC7, 0x35 - }, - { - 0x21, 0x3D, 0xD3, 0x4C, 0x7E, 0xFE, 0x4F, 0xB2, - 0x7A, 0x6B, 0x35, 0xF6, 0xB4, 0x00, 0x0D, 0x1F, - 0xE0, 0x32, 0x81, 0xAF, 0x3C, 0x72, 0x3E, 0x5C, - 0x9F, 0x94, 0x74, 0x7A, 0x5F, 0x31, 0xCD, 0x3B - }, - { - 0xEC, 0x24, 0x6E, 0xEE, 0xB9, 0xCE, 0xD3, 0xF7, - 0xAD, 0x33, 0xED, 0x28, 0x66, 0x0D, 0xD9, 0xBB, - 0x07, 0x32, 0x51, 0x3D, 0xB4, 0xE2, 0xFA, 0x27, - 0x8B, 0x60, 0xCD, 0xE3, 0x68, 0x2A, 0x4C, 0xCD - }, - { - 0xAC, 0x9B, 0x61, 0xD4, 0x46, 0x64, 0x8C, 0x30, - 0x05, 0xD7, 0x89, 0x2B, 0xF3, 0xA8, 0x71, 0x9F, - 0x4C, 0x81, 0x81, 0xCF, 0xDC, 0xBC, 0x2B, 0x79, - 0xFE, 0xF1, 0x0A, 0x27, 0x9B, 0x91, 0x10, 0x95 - }, - { - 0x7B, 0xF8, 0xB2, 0x29, 0x59, 0xE3, 0x4E, 0x3A, - 0x43, 0xF7, 0x07, 0x92, 0x23, 0xE8, 0x3A, 0x97, - 0x54, 0x61, 0x7D, 0x39, 0x1E, 0x21, 0x3D, 0xFD, - 0x80, 0x8E, 0x41, 0xB9, 0xBE, 0xAD, 0x4C, 0xE7 - }, - { - 0x68, 0xD4, 0xB5, 0xD4, 0xFA, 0x0E, 0x30, 0x2B, - 0x64, 0xCC, 0xC5, 0xAF, 0x79, 0x29, 0x13, 0xAC, - 0x4C, 0x88, 0xEC, 0x95, 0xC0, 0x7D, 0xDF, 0x40, - 0x69, 0x42, 0x56, 0xEB, 0x88, 0xCE, 0x9F, 0x3D - }, - { - 0xB2, 0xC2, 0x42, 0x0F, 0x05, 0xF9, 0xAB, 0xE3, - 0x63, 0x15, 0x91, 0x93, 0x36, 0xB3, 0x7E, 0x4E, - 0x0F, 0xA3, 0x3F, 0xF7, 0xE7, 0x6A, 0x49, 0x27, - 0x67, 0x00, 0x6F, 0xDB, 0x5D, 0x93, 0x54, 0x62 - }, - { - 0x13, 0x4F, 0x61, 0xBB, 0xD0, 0xBB, 0xB6, 0x9A, - 0xED, 0x53, 0x43, 0x90, 0x45, 0x51, 0xA3, 0xE6, - 0xC1, 0xAA, 0x7D, 0xCD, 0xD7, 0x7E, 0x90, 0x3E, - 0x70, 0x23, 0xEB, 0x7C, 0x60, 0x32, 0x0A, 0xA7 - }, - { - 0x46, 0x93, 0xF9, 0xBF, 0xF7, 0xD4, 0xF3, 0x98, - 0x6A, 0x7D, 0x17, 0x6E, 0x6E, 0x06, 0xF7, 0x2A, - 0xD1, 0x49, 0x0D, 0x80, 0x5C, 0x99, 0xE2, 0x53, - 0x47, 0xB8, 0xDE, 0x77, 0xB4, 0xDB, 0x6D, 0x9B - }, - { - 0x85, 0x3E, 0x26, 0xF7, 0x41, 0x95, 0x3B, 0x0F, - 0xD5, 0xBD, 0xB4, 0x24, 0xE8, 0xAB, 0x9E, 0x8B, - 0x37, 0x50, 0xEA, 0xA8, 0xEF, 0x61, 0xE4, 0x79, - 0x02, 0xC9, 0x1E, 0x55, 0x4E, 0x9C, 0x73, 0xB9 - }, - { - 0xF7, 0xDE, 0x53, 0x63, 0x61, 0xAB, 0xAA, 0x0E, - 0x15, 0x81, 0x56, 0xCF, 0x0E, 0xA4, 0xF6, 0x3A, - 0x99, 0xB5, 0xE4, 0x05, 0x4F, 0x8F, 0xA4, 0xC9, - 0xD4, 0x5F, 0x62, 0x85, 0xCA, 0xD5, 0x56, 0x94 - }, - { - 0x4C, 0x23, 0x06, 0x08, 0x86, 0x0A, 0x99, 0xAE, - 0x8D, 0x7B, 0xD5, 0xC2, 0xCC, 0x17, 0xFA, 0x52, - 0x09, 0x6B, 0x9A, 0x61, 0xBE, 0xDB, 0x17, 0xCB, - 0x76, 0x17, 0x86, 0x4A, 0xD2, 0x9C, 0xA7, 0xA6 - }, - { - 0xAE, 0xB9, 0x20, 0xEA, 0x87, 0x95, 0x2D, 0xAD, - 0xB1, 0xFB, 0x75, 0x92, 0x91, 0xE3, 0x38, 0x81, - 0x39, 0xA8, 0x72, 0x86, 0x50, 0x01, 0x88, 0x6E, - 0xD8, 0x47, 0x52, 0xE9, 0x3C, 0x25, 0x0C, 0x2A - }, - { - 0xAB, 0xA4, 0xAD, 0x9B, 0x48, 0x0B, 0x9D, 0xF3, - 0xD0, 0x8C, 0xA5, 0xE8, 0x7B, 0x0C, 0x24, 0x40, - 0xD4, 0xE4, 0xEA, 0x21, 0x22, 0x4C, 0x2E, 0xB4, - 0x2C, 0xBA, 0xE4, 0x69, 0xD0, 0x89, 0xB9, 0x31 - }, - { - 0x05, 0x82, 0x56, 0x07, 0xD7, 0xFD, 0xF2, 0xD8, - 0x2E, 0xF4, 0xC3, 0xC8, 0xC2, 0xAE, 0xA9, 0x61, - 0xAD, 0x98, 0xD6, 0x0E, 0xDF, 0xF7, 0xD0, 0x18, - 0x98, 0x3E, 0x21, 0x20, 0x4C, 0x0D, 0x93, 0xD1 - }, - { - 0xA7, 0x42, 0xF8, 0xB6, 0xAF, 0x82, 0xD8, 0xA6, - 0xCA, 0x23, 0x57, 0xC5, 0xF1, 0xCF, 0x91, 0xDE, - 0xFB, 0xD0, 0x66, 0x26, 0x7D, 0x75, 0xC0, 0x48, - 0xB3, 0x52, 0x36, 0x65, 0x85, 0x02, 0x59, 0x62 - }, - { - 0x2B, 0xCA, 0xC8, 0x95, 0x99, 0x00, 0x0B, 0x42, - 0xC9, 0x5A, 0xE2, 0x38, 0x35, 0xA7, 0x13, 0x70, - 0x4E, 0xD7, 0x97, 0x89, 0xC8, 0x4F, 0xEF, 0x14, - 0x9A, 0x87, 0x4F, 0xF7, 0x33, 0xF0, 0x17, 0xA2 - }, - { - 0xAC, 0x1E, 0xD0, 0x7D, 0x04, 0x8F, 0x10, 0x5A, - 0x9E, 0x5B, 0x7A, 0xB8, 0x5B, 0x09, 0xA4, 0x92, - 0xD5, 0xBA, 0xFF, 0x14, 0xB8, 0xBF, 0xB0, 0xE9, - 0xFD, 0x78, 0x94, 0x86, 0xEE, 0xA2, 0xB9, 0x74 - }, - { - 0xE4, 0x8D, 0x0E, 0xCF, 0xAF, 0x49, 0x7D, 0x5B, - 0x27, 0xC2, 0x5D, 0x99, 0xE1, 0x56, 0xCB, 0x05, - 0x79, 0xD4, 0x40, 0xD6, 0xE3, 0x1F, 0xB6, 0x24, - 0x73, 0x69, 0x6D, 0xBF, 0x95, 0xE0, 0x10, 0xE4 - }, - { - 0x12, 0xA9, 0x1F, 0xAD, 0xF8, 0xB2, 0x16, 0x44, - 0xFD, 0x0F, 0x93, 0x4F, 0x3C, 0x4A, 0x8F, 0x62, - 0xBA, 0x86, 0x2F, 0xFD, 0x20, 0xE8, 0xE9, 0x61, - 0x15, 0x4C, 0x15, 0xC1, 0x38, 0x84, 0xED, 0x3D - }, - { - 0x7C, 0xBE, 0xE9, 0x6E, 0x13, 0x98, 0x97, 0xDC, - 0x98, 0xFB, 0xEF, 0x3B, 0xE8, 0x1A, 0xD4, 0xD9, - 0x64, 0xD2, 0x35, 0xCB, 0x12, 0x14, 0x1F, 0xB6, - 0x67, 0x27, 0xE6, 0xE5, 0xDF, 0x73, 0xA8, 0x78 - }, - { - 0xEB, 0xF6, 0x6A, 0xBB, 0x59, 0x7A, 0xE5, 0x72, - 0xA7, 0x29, 0x7C, 0xB0, 0x87, 0x1E, 0x35, 0x5A, - 0xCC, 0xAF, 0xAD, 0x83, 0x77, 0xB8, 0xE7, 0x8B, - 0xF1, 0x64, 0xCE, 0x2A, 0x18, 0xDE, 0x4B, 0xAF - }, - { - 0x71, 0xB9, 0x33, 0xB0, 0x7E, 0x4F, 0xF7, 0x81, - 0x8C, 0xE0, 0x59, 0xD0, 0x08, 0x82, 0x9E, 0x45, - 0x3C, 0x6F, 0xF0, 0x2E, 0xC0, 0xA7, 0xDB, 0x39, - 0x3F, 0xC2, 0xD8, 0x70, 0xF3, 0x7A, 0x72, 0x86 - }, - { - 0x7C, 0xF7, 0xC5, 0x13, 0x31, 0x22, 0x0B, 0x8D, - 0x3E, 0xBA, 0xED, 0x9C, 0x29, 0x39, 0x8A, 0x16, - 0xD9, 0x81, 0x56, 0xE2, 0x61, 0x3C, 0xB0, 0x88, - 0xF2, 0xB0, 0xE0, 0x8A, 0x1B, 0xE4, 0xCF, 0x4F - }, - { - 0x3E, 0x41, 0xA1, 0x08, 0xE0, 0xF6, 0x4A, 0xD2, - 0x76, 0xB9, 0x79, 0xE1, 0xCE, 0x06, 0x82, 0x79, - 0xE1, 0x6F, 0x7B, 0xC7, 0xE4, 0xAA, 0x1D, 0x21, - 0x1E, 0x17, 0xB8, 0x11, 0x61, 0xDF, 0x16, 0x02 - }, - { - 0x88, 0x65, 0x02, 0xA8, 0x2A, 0xB4, 0x7B, 0xA8, - 0xD8, 0x67, 0x10, 0xAA, 0x9D, 0xE3, 0xD4, 0x6E, - 0xA6, 0x5C, 0x47, 0xAF, 0x6E, 0xE8, 0xDE, 0x45, - 0x0C, 0xCE, 0xB8, 0xB1, 0x1B, 0x04, 0x5F, 0x50 - }, - { - 0xC0, 0x21, 0xBC, 0x5F, 0x09, 0x54, 0xFE, 0xE9, - 0x4F, 0x46, 0xEA, 0x09, 0x48, 0x7E, 0x10, 0xA8, - 0x48, 0x40, 0xD0, 0x2F, 0x64, 0x81, 0x0B, 0xC0, - 0x8D, 0x9E, 0x55, 0x1F, 0x7D, 0x41, 0x68, 0x14 - }, - { - 0x20, 0x30, 0x51, 0x6E, 0x8A, 0x5F, 0xE1, 0x9A, - 0xE7, 0x9C, 0x33, 0x6F, 0xCE, 0x26, 0x38, 0x2A, - 0x74, 0x9D, 0x3F, 0xD0, 0xEC, 0x91, 0xE5, 0x37, - 0xD4, 0xBD, 0x23, 0x58, 0xC1, 0x2D, 0xFB, 0x22 - }, - { - 0x55, 0x66, 0x98, 0xDA, 0xC8, 0x31, 0x7F, 0xD3, - 0x6D, 0xFB, 0xDF, 0x25, 0xA7, 0x9C, 0xB1, 0x12, - 0xD5, 0x42, 0x58, 0x60, 0x60, 0x5C, 0xBA, 0xF5, - 0x07, 0xF2, 0x3B, 0xF7, 0xE9, 0xF4, 0x2A, 0xFE - }, - { - 0x2F, 0x86, 0x7B, 0xA6, 0x77, 0x73, 0xFD, 0xC3, - 0xE9, 0x2F, 0xCE, 0xD9, 0x9A, 0x64, 0x09, 0xAD, - 0x39, 0xD0, 0xB8, 0x80, 0xFD, 0xE8, 0xF1, 0x09, - 0xA8, 0x17, 0x30, 0xC4, 0x45, 0x1D, 0x01, 0x78 - }, - { - 0x17, 0x2E, 0xC2, 0x18, 0xF1, 0x19, 0xDF, 0xAE, - 0x98, 0x89, 0x6D, 0xFF, 0x29, 0xDD, 0x98, 0x76, - 0xC9, 0x4A, 0xF8, 0x74, 0x17, 0xF9, 0xAE, 0x4C, - 0x70, 0x14, 0xBB, 0x4E, 0x4B, 0x96, 0xAF, 0xC7 - }, - { - 0x3F, 0x85, 0x81, 0x4A, 0x18, 0x19, 0x5F, 0x87, - 0x9A, 0xA9, 0x62, 0xF9, 0x5D, 0x26, 0xBD, 0x82, - 0xA2, 0x78, 0xF2, 0xB8, 0x23, 0x20, 0x21, 0x8F, - 0x6B, 0x3B, 0xD6, 0xF7, 0xF6, 0x67, 0xA6, 0xD9 - }, - { - 0x1B, 0x61, 0x8F, 0xBA, 0xA5, 0x66, 0xB3, 0xD4, - 0x98, 0xC1, 0x2E, 0x98, 0x2C, 0x9E, 0xC5, 0x2E, - 0x4D, 0xA8, 0x5A, 0x8C, 0x54, 0xF3, 0x8F, 0x34, - 0xC0, 0x90, 0x39, 0x4F, 0x23, 0xC1, 0x84, 0xC1 - }, - { - 0x0C, 0x75, 0x8F, 0xB5, 0x69, 0x2F, 0xFD, 0x41, - 0xA3, 0x57, 0x5D, 0x0A, 0xF0, 0x0C, 0xC7, 0xFB, - 0xF2, 0xCB, 0xE5, 0x90, 0x5A, 0x58, 0x32, 0x3A, - 0x88, 0xAE, 0x42, 0x44, 0xF6, 0xE4, 0xC9, 0x93 - }, - { - 0xA9, 0x31, 0x36, 0x0C, 0xAD, 0x62, 0x8C, 0x7F, - 0x12, 0xA6, 0xC1, 0xC4, 0xB7, 0x53, 0xB0, 0xF4, - 0x06, 0x2A, 0xEF, 0x3C, 0xE6, 0x5A, 0x1A, 0xE3, - 0xF1, 0x93, 0x69, 0xDA, 0xDF, 0x3A, 0xE2, 0x3D - }, - { - 0xCB, 0xAC, 0x7D, 0x77, 0x3B, 0x1E, 0x3B, 0x3C, - 0x66, 0x91, 0xD7, 0xAB, 0xB7, 0xE9, 0xDF, 0x04, - 0x5C, 0x8B, 0xA1, 0x92, 0x68, 0xDE, 0xD1, 0x53, - 0x20, 0x7F, 0x5E, 0x80, 0x43, 0x52, 0xEC, 0x5D - }, - { - 0x23, 0xA1, 0x96, 0xD3, 0x80, 0x2E, 0xD3, 0xC1, - 0xB3, 0x84, 0x01, 0x9A, 0x82, 0x32, 0x58, 0x40, - 0xD3, 0x2F, 0x71, 0x95, 0x0C, 0x45, 0x80, 0xB0, - 0x34, 0x45, 0xE0, 0x89, 0x8E, 0x14, 0x05, 0x3C - }, - { - 0xF4, 0x49, 0x54, 0x70, 0xF2, 0x26, 0xC8, 0xC2, - 0x14, 0xBE, 0x08, 0xFD, 0xFA, 0xD4, 0xBC, 0x4A, - 0x2A, 0x9D, 0xBE, 0xA9, 0x13, 0x6A, 0x21, 0x0D, - 0xF0, 0xD4, 0xB6, 0x49, 0x29, 0xE6, 0xFC, 0x14 - }, - { - 0xE2, 0x90, 0xDD, 0x27, 0x0B, 0x46, 0x7F, 0x34, - 0xAB, 0x1C, 0x00, 0x2D, 0x34, 0x0F, 0xA0, 0x16, - 0x25, 0x7F, 0xF1, 0x9E, 0x58, 0x33, 0xFD, 0xBB, - 0xF2, 0xCB, 0x40, 0x1C, 0x3B, 0x28, 0x17, 0xDE - }, - { - 0x9F, 0xC7, 0xB5, 0xDE, 0xD3, 0xC1, 0x50, 0x42, - 0xB2, 0xA6, 0x58, 0x2D, 0xC3, 0x9B, 0xE0, 0x16, - 0xD2, 0x4A, 0x68, 0x2D, 0x5E, 0x61, 0xAD, 0x1E, - 0xFF, 0x9C, 0x63, 0x30, 0x98, 0x48, 0xF7, 0x06 - }, - { - 0x8C, 0xCA, 0x67, 0xA3, 0x6D, 0x17, 0xD5, 0xE6, - 0x34, 0x1C, 0xB5, 0x92, 0xFD, 0x7B, 0xEF, 0x99, - 0x26, 0xC9, 0xE3, 0xAA, 0x10, 0x27, 0xEA, 0x11, - 0xA7, 0xD8, 0xBD, 0x26, 0x0B, 0x57, 0x6E, 0x04 - }, - { - 0x40, 0x93, 0x92, 0xF5, 0x60, 0xF8, 0x68, 0x31, - 0xDA, 0x43, 0x73, 0xEE, 0x5E, 0x00, 0x74, 0x26, - 0x05, 0x95, 0xD7, 0xBC, 0x24, 0x18, 0x3B, 0x60, - 0xED, 0x70, 0x0D, 0x45, 0x83, 0xD3, 0xF6, 0xF0 - }, - { - 0x28, 0x02, 0x16, 0x5D, 0xE0, 0x90, 0x91, 0x55, - 0x46, 0xF3, 0x39, 0x8C, 0xD8, 0x49, 0x16, 0x4A, - 0x19, 0xF9, 0x2A, 0xDB, 0xC3, 0x61, 0xAD, 0xC9, - 0x9B, 0x0F, 0x20, 0xC8, 0xEA, 0x07, 0x10, 0x54 - }, - { - 0xAD, 0x83, 0x91, 0x68, 0xD9, 0xF8, 0xA4, 0xBE, - 0x95, 0xBA, 0x9E, 0xF9, 0xA6, 0x92, 0xF0, 0x72, - 0x56, 0xAE, 0x43, 0xFE, 0x6F, 0x98, 0x64, 0xE2, - 0x90, 0x69, 0x1B, 0x02, 0x56, 0xCE, 0x50, 0xA9 - }, - { - 0x75, 0xFD, 0xAA, 0x50, 0x38, 0xC2, 0x84, 0xB8, - 0x6D, 0x6E, 0x8A, 0xFF, 0xE8, 0xB2, 0x80, 0x7E, - 0x46, 0x7B, 0x86, 0x60, 0x0E, 0x79, 0xAF, 0x36, - 0x89, 0xFB, 0xC0, 0x63, 0x28, 0xCB, 0xF8, 0x94 - }, - { - 0xE5, 0x7C, 0xB7, 0x94, 0x87, 0xDD, 0x57, 0x90, - 0x24, 0x32, 0xB2, 0x50, 0x73, 0x38, 0x13, 0xBD, - 0x96, 0xA8, 0x4E, 0xFC, 0xE5, 0x9F, 0x65, 0x0F, - 0xAC, 0x26, 0xE6, 0x69, 0x6A, 0xEF, 0xAF, 0xC3 - }, - { - 0x56, 0xF3, 0x4E, 0x8B, 0x96, 0x55, 0x7E, 0x90, - 0xC1, 0xF2, 0x4B, 0x52, 0xD0, 0xC8, 0x9D, 0x51, - 0x08, 0x6A, 0xCF, 0x1B, 0x00, 0xF6, 0x34, 0xCF, - 0x1D, 0xDE, 0x92, 0x33, 0xB8, 0xEA, 0xAA, 0x3E - }, - { - 0x1B, 0x53, 0xEE, 0x94, 0xAA, 0xF3, 0x4E, 0x4B, - 0x15, 0x9D, 0x48, 0xDE, 0x35, 0x2C, 0x7F, 0x06, - 0x61, 0xD0, 0xA4, 0x0E, 0xDF, 0xF9, 0x5A, 0x0B, - 0x16, 0x39, 0xB4, 0x09, 0x0E, 0x97, 0x44, 0x72 - }, - { - 0x05, 0x70, 0x5E, 0x2A, 0x81, 0x75, 0x7C, 0x14, - 0xBD, 0x38, 0x3E, 0xA9, 0x8D, 0xDA, 0x54, 0x4E, - 0xB1, 0x0E, 0x6B, 0xC0, 0x7B, 0xAE, 0x43, 0x5E, - 0x25, 0x18, 0xDB, 0xE1, 0x33, 0x52, 0x53, 0x75 - }, - { - 0xD8, 0xB2, 0x86, 0x6E, 0x8A, 0x30, 0x9D, 0xB5, - 0x3E, 0x52, 0x9E, 0xC3, 0x29, 0x11, 0xD8, 0x2F, - 0x5C, 0xA1, 0x6C, 0xFF, 0x76, 0x21, 0x68, 0x91, - 0xA9, 0x67, 0x6A, 0xA3, 0x1A, 0xAA, 0x6C, 0x42 - }, - { - 0xF5, 0x04, 0x1C, 0x24, 0x12, 0x70, 0xEB, 0x04, - 0xC7, 0x1E, 0xC2, 0xC9, 0x5D, 0x4C, 0x38, 0xD8, - 0x03, 0xB1, 0x23, 0x7B, 0x0F, 0x29, 0xFD, 0x4D, - 0xB3, 0xEB, 0x39, 0x76, 0x69, 0xE8, 0x86, 0x99 - }, - { - 0x9A, 0x4C, 0xE0, 0x77, 0xC3, 0x49, 0x32, 0x2F, - 0x59, 0x5E, 0x0E, 0xE7, 0x9E, 0xD0, 0xDA, 0x5F, - 0xAB, 0x66, 0x75, 0x2C, 0xBF, 0xEF, 0x8F, 0x87, - 0xD0, 0xE9, 0xD0, 0x72, 0x3C, 0x75, 0x30, 0xDD - }, - { - 0x65, 0x7B, 0x09, 0xF3, 0xD0, 0xF5, 0x2B, 0x5B, - 0x8F, 0x2F, 0x97, 0x16, 0x3A, 0x0E, 0xDF, 0x0C, - 0x04, 0xF0, 0x75, 0x40, 0x8A, 0x07, 0xBB, 0xEB, - 0x3A, 0x41, 0x01, 0xA8, 0x91, 0x99, 0x0D, 0x62 - }, - { - 0x1E, 0x3F, 0x7B, 0xD5, 0xA5, 0x8F, 0xA5, 0x33, - 0x34, 0x4A, 0xA8, 0xED, 0x3A, 0xC1, 0x22, 0xBB, - 0x9E, 0x70, 0xD4, 0xEF, 0x50, 0xD0, 0x04, 0x53, - 0x08, 0x21, 0x94, 0x8F, 0x5F, 0xE6, 0x31, 0x5A - }, - { - 0x80, 0xDC, 0xCF, 0x3F, 0xD8, 0x3D, 0xFD, 0x0D, - 0x35, 0xAA, 0x28, 0x58, 0x59, 0x22, 0xAB, 0x89, - 0xD5, 0x31, 0x39, 0x97, 0x67, 0x3E, 0xAF, 0x90, - 0x5C, 0xEA, 0x9C, 0x0B, 0x22, 0x5C, 0x7B, 0x5F - }, - { - 0x8A, 0x0D, 0x0F, 0xBF, 0x63, 0x77, 0xD8, 0x3B, - 0xB0, 0x8B, 0x51, 0x4B, 0x4B, 0x1C, 0x43, 0xAC, - 0xC9, 0x5D, 0x75, 0x17, 0x14, 0xF8, 0x92, 0x56, - 0x45, 0xCB, 0x6B, 0xC8, 0x56, 0xCA, 0x15, 0x0A - }, - { - 0x9F, 0xA5, 0xB4, 0x87, 0x73, 0x8A, 0xD2, 0x84, - 0x4C, 0xC6, 0x34, 0x8A, 0x90, 0x19, 0x18, 0xF6, - 0x59, 0xA3, 0xB8, 0x9E, 0x9C, 0x0D, 0xFE, 0xEA, - 0xD3, 0x0D, 0xD9, 0x4B, 0xCF, 0x42, 0xEF, 0x8E - }, - { - 0x80, 0x83, 0x2C, 0x4A, 0x16, 0x77, 0xF5, 0xEA, - 0x25, 0x60, 0xF6, 0x68, 0xE9, 0x35, 0x4D, 0xD3, - 0x69, 0x97, 0xF0, 0x37, 0x28, 0xCF, 0xA5, 0x5E, - 0x1B, 0x38, 0x33, 0x7C, 0x0C, 0x9E, 0xF8, 0x18 - }, - { - 0xAB, 0x37, 0xDD, 0xB6, 0x83, 0x13, 0x7E, 0x74, - 0x08, 0x0D, 0x02, 0x6B, 0x59, 0x0B, 0x96, 0xAE, - 0x9B, 0xB4, 0x47, 0x72, 0x2F, 0x30, 0x5A, 0x5A, - 0xC5, 0x70, 0xEC, 0x1D, 0xF9, 0xB1, 0x74, 0x3C - }, - { - 0x3E, 0xE7, 0x35, 0xA6, 0x94, 0xC2, 0x55, 0x9B, - 0x69, 0x3A, 0xA6, 0x86, 0x29, 0x36, 0x1E, 0x15, - 0xD1, 0x22, 0x65, 0xAD, 0x6A, 0x3D, 0xED, 0xF4, - 0x88, 0xB0, 0xB0, 0x0F, 0xAC, 0x97, 0x54, 0xBA - }, - { - 0xD6, 0xFC, 0xD2, 0x32, 0x19, 0xB6, 0x47, 0xE4, - 0xCB, 0xD5, 0xEB, 0x2D, 0x0A, 0xD0, 0x1E, 0xC8, - 0x83, 0x8A, 0x4B, 0x29, 0x01, 0xFC, 0x32, 0x5C, - 0xC3, 0x70, 0x19, 0x81, 0xCA, 0x6C, 0x88, 0x8B - }, - { - 0x05, 0x20, 0xEC, 0x2F, 0x5B, 0xF7, 0xA7, 0x55, - 0xDA, 0xCB, 0x50, 0xC6, 0xBF, 0x23, 0x3E, 0x35, - 0x15, 0x43, 0x47, 0x63, 0xDB, 0x01, 0x39, 0xCC, - 0xD9, 0xFA, 0xEF, 0xBB, 0x82, 0x07, 0x61, 0x2D - }, - { - 0xAF, 0xF3, 0xB7, 0x5F, 0x3F, 0x58, 0x12, 0x64, - 0xD7, 0x66, 0x16, 0x62, 0xB9, 0x2F, 0x5A, 0xD3, - 0x7C, 0x1D, 0x32, 0xBD, 0x45, 0xFF, 0x81, 0xA4, - 0xED, 0x8A, 0xDC, 0x9E, 0xF3, 0x0D, 0xD9, 0x89 - }, - { - 0xD0, 0xDD, 0x65, 0x0B, 0xEF, 0xD3, 0xBA, 0x63, - 0xDC, 0x25, 0x10, 0x2C, 0x62, 0x7C, 0x92, 0x1B, - 0x9C, 0xBE, 0xB0, 0xB1, 0x30, 0x68, 0x69, 0x35, - 0xB5, 0xC9, 0x27, 0xCB, 0x7C, 0xCD, 0x5E, 0x3B - }, - { - 0xE1, 0x14, 0x98, 0x16, 0xB1, 0x0A, 0x85, 0x14, - 0xFB, 0x3E, 0x2C, 0xAB, 0x2C, 0x08, 0xBE, 0xE9, - 0xF7, 0x3C, 0xE7, 0x62, 0x21, 0x70, 0x12, 0x46, - 0xA5, 0x89, 0xBB, 0xB6, 0x73, 0x02, 0xD8, 0xA9 - }, - { - 0x7D, 0xA3, 0xF4, 0x41, 0xDE, 0x90, 0x54, 0x31, - 0x7E, 0x72, 0xB5, 0xDB, 0xF9, 0x79, 0xDA, 0x01, - 0xE6, 0xBC, 0xEE, 0xBB, 0x84, 0x78, 0xEA, 0xE6, - 0xA2, 0x28, 0x49, 0xD9, 0x02, 0x92, 0x63, 0x5C - }, - { - 0x12, 0x30, 0xB1, 0xFC, 0x8A, 0x7D, 0x92, 0x15, - 0xED, 0xC2, 0xD4, 0xA2, 0xDE, 0xCB, 0xDD, 0x0A, - 0x6E, 0x21, 0x6C, 0x92, 0x42, 0x78, 0xC9, 0x1F, - 0xC5, 0xD1, 0x0E, 0x7D, 0x60, 0x19, 0x2D, 0x94 - }, - { - 0x57, 0x50, 0xD7, 0x16, 0xB4, 0x80, 0x8F, 0x75, - 0x1F, 0xEB, 0xC3, 0x88, 0x06, 0xBA, 0x17, 0x0B, - 0xF6, 0xD5, 0x19, 0x9A, 0x78, 0x16, 0xBE, 0x51, - 0x4E, 0x3F, 0x93, 0x2F, 0xBE, 0x0C, 0xB8, 0x71 - }, - { - 0x6F, 0xC5, 0x9B, 0x2F, 0x10, 0xFE, 0xBA, 0x95, - 0x4A, 0xA6, 0x82, 0x0B, 0x3C, 0xA9, 0x87, 0xEE, - 0x81, 0xD5, 0xCC, 0x1D, 0xA3, 0xC6, 0x3C, 0xE8, - 0x27, 0x30, 0x1C, 0x56, 0x9D, 0xFB, 0x39, 0xCE - }, - { - 0xC7, 0xC3, 0xFE, 0x1E, 0xEB, 0xDC, 0x7B, 0x5A, - 0x93, 0x93, 0x26, 0xE8, 0xDD, 0xB8, 0x3E, 0x8B, - 0xF2, 0xB7, 0x80, 0xB6, 0x56, 0x78, 0xCB, 0x62, - 0xF2, 0x08, 0xB0, 0x40, 0xAB, 0xDD, 0x35, 0xE2 - }, - { - 0x0C, 0x75, 0xC1, 0xA1, 0x5C, 0xF3, 0x4A, 0x31, - 0x4E, 0xE4, 0x78, 0xF4, 0xA5, 0xCE, 0x0B, 0x8A, - 0x6B, 0x36, 0x52, 0x8E, 0xF7, 0xA8, 0x20, 0x69, - 0x6C, 0x3E, 0x42, 0x46, 0xC5, 0xA1, 0x58, 0x64 - }, - { - 0x21, 0x6D, 0xC1, 0x2A, 0x10, 0x85, 0x69, 0xA3, - 0xC7, 0xCD, 0xDE, 0x4A, 0xED, 0x43, 0xA6, 0xC3, - 0x30, 0x13, 0x9D, 0xDA, 0x3C, 0xCC, 0x4A, 0x10, - 0x89, 0x05, 0xDB, 0x38, 0x61, 0x89, 0x90, 0x50 - }, - { - 0xA5, 0x7B, 0xE6, 0xAE, 0x67, 0x56, 0xF2, 0x8B, - 0x02, 0xF5, 0x9D, 0xAD, 0xF7, 0xE0, 0xD7, 0xD8, - 0x80, 0x7F, 0x10, 0xFA, 0x15, 0xCE, 0xD1, 0xAD, - 0x35, 0x85, 0x52, 0x1A, 0x1D, 0x99, 0x5A, 0x89 - }, - { - 0x81, 0x6A, 0xEF, 0x87, 0x59, 0x53, 0x71, 0x6C, - 0xD7, 0xA5, 0x81, 0xF7, 0x32, 0xF5, 0x3D, 0xD4, - 0x35, 0xDA, 0xB6, 0x6D, 0x09, 0xC3, 0x61, 0xD2, - 0xD6, 0x59, 0x2D, 0xE1, 0x77, 0x55, 0xD8, 0xA8 - }, - { - 0x9A, 0x76, 0x89, 0x32, 0x26, 0x69, 0x3B, 0x6E, - 0xA9, 0x7E, 0x6A, 0x73, 0x8F, 0x9D, 0x10, 0xFB, - 0x3D, 0x0B, 0x43, 0xAE, 0x0E, 0x8B, 0x7D, 0x81, - 0x23, 0xEA, 0x76, 0xCE, 0x97, 0x98, 0x9C, 0x7E - }, - { - 0x8D, 0xAE, 0xDB, 0x9A, 0x27, 0x15, 0x29, 0xDB, - 0xB7, 0xDC, 0x3B, 0x60, 0x7F, 0xE5, 0xEB, 0x2D, - 0x32, 0x11, 0x77, 0x07, 0x58, 0xDD, 0x3B, 0x0A, - 0x35, 0x93, 0xD2, 0xD7, 0x95, 0x4E, 0x2D, 0x5B - }, - { - 0x16, 0xDB, 0xC0, 0xAA, 0x5D, 0xD2, 0xC7, 0x74, - 0xF5, 0x05, 0x10, 0x0F, 0x73, 0x37, 0x86, 0xD8, - 0xA1, 0x75, 0xFC, 0xBB, 0xB5, 0x9C, 0x43, 0xE1, - 0xFB, 0xFF, 0x3E, 0x1E, 0xAF, 0x31, 0xCB, 0x4A - }, - { - 0x86, 0x06, 0xCB, 0x89, 0x9C, 0x6A, 0xEA, 0xF5, - 0x1B, 0x9D, 0xB0, 0xFE, 0x49, 0x24, 0xA9, 0xFD, - 0x5D, 0xAB, 0xC1, 0x9F, 0x88, 0x26, 0xF2, 0xBC, - 0x1C, 0x1D, 0x7D, 0xA1, 0x4D, 0x2C, 0x2C, 0x99 - }, - { - 0x84, 0x79, 0x73, 0x1A, 0xED, 0xA5, 0x7B, 0xD3, - 0x7E, 0xAD, 0xB5, 0x1A, 0x50, 0x7E, 0x30, 0x7F, - 0x3B, 0xD9, 0x5E, 0x69, 0xDB, 0xCA, 0x94, 0xF3, - 0xBC, 0x21, 0x72, 0x60, 0x66, 0xAD, 0x6D, 0xFD - }, - { - 0x58, 0x47, 0x3A, 0x9E, 0xA8, 0x2E, 0xFA, 0x3F, - 0x3B, 0x3D, 0x8F, 0xC8, 0x3E, 0xD8, 0x86, 0x31, - 0x27, 0xB3, 0x3A, 0xE8, 0xDE, 0xAE, 0x63, 0x07, - 0x20, 0x1E, 0xDB, 0x6D, 0xDE, 0x61, 0xDE, 0x29 - }, - { - 0x9A, 0x92, 0x55, 0xD5, 0x3A, 0xF1, 0x16, 0xDE, - 0x8B, 0xA2, 0x7C, 0xE3, 0x5B, 0x4C, 0x7E, 0x15, - 0x64, 0x06, 0x57, 0xA0, 0xFC, 0xB8, 0x88, 0xC7, - 0x0D, 0x95, 0x43, 0x1D, 0xAC, 0xD8, 0xF8, 0x30 - }, - { - 0x9E, 0xB0, 0x5F, 0xFB, 0xA3, 0x9F, 0xD8, 0x59, - 0x6A, 0x45, 0x49, 0x3E, 0x18, 0xD2, 0x51, 0x0B, - 0xF3, 0xEF, 0x06, 0x5C, 0x51, 0xD6, 0xE1, 0x3A, - 0xBE, 0x66, 0xAA, 0x57, 0xE0, 0x5C, 0xFD, 0xB7 - }, - { - 0x81, 0xDC, 0xC3, 0xA5, 0x05, 0xEA, 0xCE, 0x3F, - 0x87, 0x9D, 0x8F, 0x70, 0x27, 0x76, 0x77, 0x0F, - 0x9D, 0xF5, 0x0E, 0x52, 0x1D, 0x14, 0x28, 0xA8, - 0x5D, 0xAF, 0x04, 0xF9, 0xAD, 0x21, 0x50, 0xE0 - }, - { - 0xE3, 0xE3, 0xC4, 0xAA, 0x3A, 0xCB, 0xBC, 0x85, - 0x33, 0x2A, 0xF9, 0xD5, 0x64, 0xBC, 0x24, 0x16, - 0x5E, 0x16, 0x87, 0xF6, 0xB1, 0xAD, 0xCB, 0xFA, - 0xE7, 0x7A, 0x8F, 0x03, 0xC7, 0x2A, 0xC2, 0x8C - }, - { - 0x67, 0x46, 0xC8, 0x0B, 0x4E, 0xB5, 0x6A, 0xEA, - 0x45, 0xE6, 0x4E, 0x72, 0x89, 0xBB, 0xA3, 0xED, - 0xBF, 0x45, 0xEC, 0xF8, 0x20, 0x64, 0x81, 0xFF, - 0x63, 0x02, 0x12, 0x29, 0x84, 0xCD, 0x52, 0x6A - }, - { - 0x2B, 0x62, 0x8E, 0x52, 0x76, 0x4D, 0x7D, 0x62, - 0xC0, 0x86, 0x8B, 0x21, 0x23, 0x57, 0xCD, 0xD1, - 0x2D, 0x91, 0x49, 0x82, 0x2F, 0x4E, 0x98, 0x45, - 0xD9, 0x18, 0xA0, 0x8D, 0x1A, 0xE9, 0x90, 0xC0 - }, - { - 0xE4, 0xBF, 0xE8, 0x0D, 0x58, 0xC9, 0x19, 0x94, - 0x61, 0x39, 0x09, 0xDC, 0x4B, 0x1A, 0x12, 0x49, - 0x68, 0x96, 0xC0, 0x04, 0xAF, 0x7B, 0x57, 0x01, - 0x48, 0x3D, 0xE4, 0x5D, 0x28, 0x23, 0xD7, 0x8E - }, - { - 0xEB, 0xB4, 0xBA, 0x15, 0x0C, 0xEF, 0x27, 0x34, - 0x34, 0x5B, 0x5D, 0x64, 0x1B, 0xBE, 0xD0, 0x3A, - 0x21, 0xEA, 0xFA, 0xE9, 0x33, 0xC9, 0x9E, 0x00, - 0x92, 0x12, 0xEF, 0x04, 0x57, 0x4A, 0x85, 0x30 - }, - { - 0x39, 0x66, 0xEC, 0x73, 0xB1, 0x54, 0xAC, 0xC6, - 0x97, 0xAC, 0x5C, 0xF5, 0xB2, 0x4B, 0x40, 0xBD, - 0xB0, 0xDB, 0x9E, 0x39, 0x88, 0x36, 0xD7, 0x6D, - 0x4B, 0x88, 0x0E, 0x3B, 0x2A, 0xF1, 0xAA, 0x27 - }, - { - 0xEF, 0x7E, 0x48, 0x31, 0xB3, 0xA8, 0x46, 0x36, - 0x51, 0x8D, 0x6E, 0x4B, 0xFC, 0xE6, 0x4A, 0x43, - 0xDB, 0x2A, 0x5D, 0xDA, 0x9C, 0xCA, 0x2B, 0x44, - 0xF3, 0x90, 0x33, 0xBD, 0xC4, 0x0D, 0x62, 0x43 - }, - { - 0x7A, 0xBF, 0x6A, 0xCF, 0x5C, 0x8E, 0x54, 0x9D, - 0xDB, 0xB1, 0x5A, 0xE8, 0xD8, 0xB3, 0x88, 0xC1, - 0xC1, 0x97, 0xE6, 0x98, 0x73, 0x7C, 0x97, 0x85, - 0x50, 0x1E, 0xD1, 0xF9, 0x49, 0x30, 0xB7, 0xD9 - }, - { - 0x88, 0x01, 0x8D, 0xED, 0x66, 0x81, 0x3F, 0x0C, - 0xA9, 0x5D, 0xEF, 0x47, 0x4C, 0x63, 0x06, 0x92, - 0x01, 0x99, 0x67, 0xB9, 0xE3, 0x68, 0x88, 0xDA, - 0xDD, 0x94, 0x12, 0x47, 0x19, 0xB6, 0x82, 0xF6 - }, - { - 0x39, 0x30, 0x87, 0x6B, 0x9F, 0xC7, 0x52, 0x90, - 0x36, 0xB0, 0x08, 0xB1, 0xB8, 0xBB, 0x99, 0x75, - 0x22, 0xA4, 0x41, 0x63, 0x5A, 0x0C, 0x25, 0xEC, - 0x02, 0xFB, 0x6D, 0x90, 0x26, 0xE5, 0x5A, 0x97 - }, - { - 0x0A, 0x40, 0x49, 0xD5, 0x7E, 0x83, 0x3B, 0x56, - 0x95, 0xFA, 0xC9, 0x3D, 0xD1, 0xFB, 0xEF, 0x31, - 0x66, 0xB4, 0x4B, 0x12, 0xAD, 0x11, 0x24, 0x86, - 0x62, 0x38, 0x3A, 0xE0, 0x51, 0xE1, 0x58, 0x27 - }, - { - 0x81, 0xDC, 0xC0, 0x67, 0x8B, 0xB6, 0xA7, 0x65, - 0xE4, 0x8C, 0x32, 0x09, 0x65, 0x4F, 0xE9, 0x00, - 0x89, 0xCE, 0x44, 0xFF, 0x56, 0x18, 0x47, 0x7E, - 0x39, 0xAB, 0x28, 0x64, 0x76, 0xDF, 0x05, 0x2B - }, - { - 0xE6, 0x9B, 0x3A, 0x36, 0xA4, 0x46, 0x19, 0x12, - 0xDC, 0x08, 0x34, 0x6B, 0x11, 0xDD, 0xCB, 0x9D, - 0xB7, 0x96, 0xF8, 0x85, 0xFD, 0x01, 0x93, 0x6E, - 0x66, 0x2F, 0xE2, 0x92, 0x97, 0xB0, 0x99, 0xA4 - }, - { - 0x5A, 0xC6, 0x50, 0x3B, 0x0D, 0x8D, 0xA6, 0x91, - 0x76, 0x46, 0xE6, 0xDC, 0xC8, 0x7E, 0xDC, 0x58, - 0xE9, 0x42, 0x45, 0x32, 0x4C, 0xC2, 0x04, 0xF4, - 0xDD, 0x4A, 0xF0, 0x15, 0x63, 0xAC, 0xD4, 0x27 - }, - { - 0xDF, 0x6D, 0xDA, 0x21, 0x35, 0x9A, 0x30, 0xBC, - 0x27, 0x17, 0x80, 0x97, 0x1C, 0x1A, 0xBD, 0x56, - 0xA6, 0xEF, 0x16, 0x7E, 0x48, 0x08, 0x87, 0x88, - 0x8E, 0x73, 0xA8, 0x6D, 0x3B, 0xF6, 0x05, 0xE9 - }, - { - 0xE8, 0xE6, 0xE4, 0x70, 0x71, 0xE7, 0xB7, 0xDF, - 0x25, 0x80, 0xF2, 0x25, 0xCF, 0xBB, 0xED, 0xF8, - 0x4C, 0xE6, 0x77, 0x46, 0x62, 0x66, 0x28, 0xD3, - 0x30, 0x97, 0xE4, 0xB7, 0xDC, 0x57, 0x11, 0x07 - }, - { - 0x53, 0xE4, 0x0E, 0xAD, 0x62, 0x05, 0x1E, 0x19, - 0xCB, 0x9B, 0xA8, 0x13, 0x3E, 0x3E, 0x5C, 0x1C, - 0xE0, 0x0D, 0xDC, 0xAD, 0x8A, 0xCF, 0x34, 0x2A, - 0x22, 0x43, 0x60, 0xB0, 0xAC, 0xC1, 0x47, 0x77 - }, - { - 0x9C, 0xCD, 0x53, 0xFE, 0x80, 0xBE, 0x78, 0x6A, - 0xA9, 0x84, 0x63, 0x84, 0x62, 0xFB, 0x28, 0xAF, - 0xDF, 0x12, 0x2B, 0x34, 0xD7, 0x8F, 0x46, 0x87, - 0xEC, 0x63, 0x2B, 0xB1, 0x9D, 0xE2, 0x37, 0x1A - }, - { - 0xCB, 0xD4, 0x80, 0x52, 0xC4, 0x8D, 0x78, 0x84, - 0x66, 0xA3, 0xE8, 0x11, 0x8C, 0x56, 0xC9, 0x7F, - 0xE1, 0x46, 0xE5, 0x54, 0x6F, 0xAA, 0xF9, 0x3E, - 0x2B, 0xC3, 0xC4, 0x7E, 0x45, 0x93, 0x97, 0x53 - }, - { - 0x25, 0x68, 0x83, 0xB1, 0x4E, 0x2A, 0xF4, 0x4D, - 0xAD, 0xB2, 0x8E, 0x1B, 0x34, 0xB2, 0xAC, 0x0F, - 0x0F, 0x4C, 0x91, 0xC3, 0x4E, 0xC9, 0x16, 0x9E, - 0x29, 0x03, 0x61, 0x58, 0xAC, 0xAA, 0x95, 0xB9 - }, - { - 0x44, 0x71, 0xB9, 0x1A, 0xB4, 0x2D, 0xB7, 0xC4, - 0xDD, 0x84, 0x90, 0xAB, 0x95, 0xA2, 0xEE, 0x8D, - 0x04, 0xE3, 0xEF, 0x5C, 0x3D, 0x6F, 0xC7, 0x1A, - 0xC7, 0x4B, 0x2B, 0x26, 0x91, 0x4D, 0x16, 0x41 - }, - { - 0xA5, 0xEB, 0x08, 0x03, 0x8F, 0x8F, 0x11, 0x55, - 0xED, 0x86, 0xE6, 0x31, 0x90, 0x6F, 0xC1, 0x30, - 0x95, 0xF6, 0xBB, 0xA4, 0x1D, 0xE5, 0xD4, 0xE7, - 0x95, 0x75, 0x8E, 0xC8, 0xC8, 0xDF, 0x8A, 0xF1 - }, - { - 0xDC, 0x1D, 0xB6, 0x4E, 0xD8, 0xB4, 0x8A, 0x91, - 0x0E, 0x06, 0x0A, 0x6B, 0x86, 0x63, 0x74, 0xC5, - 0x78, 0x78, 0x4E, 0x9A, 0xC4, 0x9A, 0xB2, 0x77, - 0x40, 0x92, 0xAC, 0x71, 0x50, 0x19, 0x34, 0xAC - }, - { - 0x28, 0x54, 0x13, 0xB2, 0xF2, 0xEE, 0x87, 0x3D, - 0x34, 0x31, 0x9E, 0xE0, 0xBB, 0xFB, 0xB9, 0x0F, - 0x32, 0xDA, 0x43, 0x4C, 0xC8, 0x7E, 0x3D, 0xB5, - 0xED, 0x12, 0x1B, 0xB3, 0x98, 0xED, 0x96, 0x4B - }, - { - 0x02, 0x16, 0xE0, 0xF8, 0x1F, 0x75, 0x0F, 0x26, - 0xF1, 0x99, 0x8B, 0xC3, 0x93, 0x4E, 0x3E, 0x12, - 0x4C, 0x99, 0x45, 0xE6, 0x85, 0xA6, 0x0B, 0x25, - 0xE8, 0xFB, 0xD9, 0x62, 0x5A, 0xB6, 0xB5, 0x99 - }, - { - 0x38, 0xC4, 0x10, 0xF5, 0xB9, 0xD4, 0x07, 0x20, - 0x50, 0x75, 0x5B, 0x31, 0xDC, 0xA8, 0x9F, 0xD5, - 0x39, 0x5C, 0x67, 0x85, 0xEE, 0xB3, 0xD7, 0x90, - 0xF3, 0x20, 0xFF, 0x94, 0x1C, 0x5A, 0x93, 0xBF - }, - { - 0xF1, 0x84, 0x17, 0xB3, 0x9D, 0x61, 0x7A, 0xB1, - 0xC1, 0x8F, 0xDF, 0x91, 0xEB, 0xD0, 0xFC, 0x6D, - 0x55, 0x16, 0xBB, 0x34, 0xCF, 0x39, 0x36, 0x40, - 0x37, 0xBC, 0xE8, 0x1F, 0xA0, 0x4C, 0xEC, 0xB1 - }, - { - 0x1F, 0xA8, 0x77, 0xDE, 0x67, 0x25, 0x9D, 0x19, - 0x86, 0x3A, 0x2A, 0x34, 0xBC, 0xC6, 0x96, 0x2A, - 0x2B, 0x25, 0xFC, 0xBF, 0x5C, 0xBE, 0xCD, 0x7E, - 0xDE, 0x8F, 0x1F, 0xA3, 0x66, 0x88, 0xA7, 0x96 - }, - { - 0x5B, 0xD1, 0x69, 0xE6, 0x7C, 0x82, 0xC2, 0xC2, - 0xE9, 0x8E, 0xF7, 0x00, 0x8B, 0xDF, 0x26, 0x1F, - 0x2D, 0xDF, 0x30, 0xB1, 0xC0, 0x0F, 0x9E, 0x7F, - 0x27, 0x5B, 0xB3, 0xE8, 0xA2, 0x8D, 0xC9, 0xA2 - }, - { - 0xC8, 0x0A, 0xBE, 0xEB, 0xB6, 0x69, 0xAD, 0x5D, - 0xEE, 0xB5, 0xF5, 0xEC, 0x8E, 0xA6, 0xB7, 0xA0, - 0x5D, 0xDF, 0x7D, 0x31, 0xEC, 0x4C, 0x0A, 0x2E, - 0xE2, 0x0B, 0x0B, 0x98, 0xCA, 0xEC, 0x67, 0x46 - }, - { - 0xE7, 0x6D, 0x3F, 0xBD, 0xA5, 0xBA, 0x37, 0x4E, - 0x6B, 0xF8, 0xE5, 0x0F, 0xAD, 0xC3, 0xBB, 0xB9, - 0xBA, 0x5C, 0x20, 0x6E, 0xBD, 0xEC, 0x89, 0xA3, - 0xA5, 0x4C, 0xF3, 0xDD, 0x84, 0xA0, 0x70, 0x16 - }, - { - 0x7B, 0xBA, 0x9D, 0xC5, 0xB5, 0xDB, 0x20, 0x71, - 0xD1, 0x77, 0x52, 0xB1, 0x04, 0x4C, 0x1E, 0xCE, - 0xD9, 0x6A, 0xAF, 0x2D, 0xD4, 0x6E, 0x9B, 0x43, - 0x37, 0x50, 0xE8, 0xEA, 0x0D, 0xCC, 0x18, 0x70 - }, - { - 0xF2, 0x9B, 0x1B, 0x1A, 0xB9, 0xBA, 0xB1, 0x63, - 0x01, 0x8E, 0xE3, 0xDA, 0x15, 0x23, 0x2C, 0xCA, - 0x78, 0xEC, 0x52, 0xDB, 0xC3, 0x4E, 0xDA, 0x5B, - 0x82, 0x2E, 0xC1, 0xD8, 0x0F, 0xC2, 0x1B, 0xD0 - }, - { - 0x9E, 0xE3, 0xE3, 0xE7, 0xE9, 0x00, 0xF1, 0xE1, - 0x1D, 0x30, 0x8C, 0x4B, 0x2B, 0x30, 0x76, 0xD2, - 0x72, 0xCF, 0x70, 0x12, 0x4F, 0x9F, 0x51, 0xE1, - 0xDA, 0x60, 0xF3, 0x78, 0x46, 0xCD, 0xD2, 0xF4 - }, - { - 0x70, 0xEA, 0x3B, 0x01, 0x76, 0x92, 0x7D, 0x90, - 0x96, 0xA1, 0x85, 0x08, 0xCD, 0x12, 0x3A, 0x29, - 0x03, 0x25, 0x92, 0x0A, 0x9D, 0x00, 0xA8, 0x9B, - 0x5D, 0xE0, 0x42, 0x73, 0xFB, 0xC7, 0x6B, 0x85 - }, - { - 0x67, 0xDE, 0x25, 0xC0, 0x2A, 0x4A, 0xAB, 0xA2, - 0x3B, 0xDC, 0x97, 0x3C, 0x8B, 0xB0, 0xB5, 0x79, - 0x6D, 0x47, 0xCC, 0x06, 0x59, 0xD4, 0x3D, 0xFF, - 0x1F, 0x97, 0xDE, 0x17, 0x49, 0x63, 0xB6, 0x8E - }, - { - 0xB2, 0x16, 0x8E, 0x4E, 0x0F, 0x18, 0xB0, 0xE6, - 0x41, 0x00, 0xB5, 0x17, 0xED, 0x95, 0x25, 0x7D, - 0x73, 0xF0, 0x62, 0x0D, 0xF8, 0x85, 0xC1, 0x3D, - 0x2E, 0xCF, 0x79, 0x36, 0x7B, 0x38, 0x4C, 0xEE - }, - { - 0x2E, 0x7D, 0xEC, 0x24, 0x28, 0x85, 0x3B, 0x2C, - 0x71, 0x76, 0x07, 0x45, 0x54, 0x1F, 0x7A, 0xFE, - 0x98, 0x25, 0xB5, 0xDD, 0x77, 0xDF, 0x06, 0x51, - 0x1D, 0x84, 0x41, 0xA9, 0x4B, 0xAC, 0xC9, 0x27 - }, - { - 0xCA, 0x9F, 0xFA, 0xC4, 0xC4, 0x3F, 0x0B, 0x48, - 0x46, 0x1D, 0xC5, 0xC2, 0x63, 0xBE, 0xA3, 0xF6, - 0xF0, 0x06, 0x11, 0xCE, 0xAC, 0xAB, 0xF6, 0xF8, - 0x95, 0xBA, 0x2B, 0x01, 0x01, 0xDB, 0xB6, 0x8D - }, - { - 0x74, 0x10, 0xD4, 0x2D, 0x8F, 0xD1, 0xD5, 0xE9, - 0xD2, 0xF5, 0x81, 0x5C, 0xB9, 0x34, 0x17, 0x99, - 0x88, 0x28, 0xEF, 0x3C, 0x42, 0x30, 0xBF, 0xBD, - 0x41, 0x2D, 0xF0, 0xA4, 0xA7, 0xA2, 0x50, 0x7A - }, - { - 0x50, 0x10, 0xF6, 0x84, 0x51, 0x6D, 0xCC, 0xD0, - 0xB6, 0xEE, 0x08, 0x52, 0xC2, 0x51, 0x2B, 0x4D, - 0xC0, 0x06, 0x6C, 0xF0, 0xD5, 0x6F, 0x35, 0x30, - 0x29, 0x78, 0xDB, 0x8A, 0xE3, 0x2C, 0x6A, 0x81 - }, - { - 0xAC, 0xAA, 0xB5, 0x85, 0xF7, 0xB7, 0x9B, 0x71, - 0x99, 0x35, 0xCE, 0xB8, 0x95, 0x23, 0xDD, 0xC5, - 0x48, 0x27, 0xF7, 0x5C, 0x56, 0x88, 0x38, 0x56, - 0x15, 0x4A, 0x56, 0xCD, 0xCD, 0x5E, 0xE9, 0x88 - }, - { - 0x66, 0x6D, 0xE5, 0xD1, 0x44, 0x0F, 0xEE, 0x73, - 0x31, 0xAA, 0xF0, 0x12, 0x3A, 0x62, 0xEF, 0x2D, - 0x8B, 0xA5, 0x74, 0x53, 0xA0, 0x76, 0x96, 0x35, - 0xAC, 0x6C, 0xD0, 0x1E, 0x63, 0x3F, 0x77, 0x12 - }, - { - 0xA6, 0xF9, 0x86, 0x58, 0xF6, 0xEA, 0xBA, 0xF9, - 0x02, 0xD8, 0xB3, 0x87, 0x1A, 0x4B, 0x10, 0x1D, - 0x16, 0x19, 0x6E, 0x8A, 0x4B, 0x24, 0x1E, 0x15, - 0x58, 0xFE, 0x29, 0x96, 0x6E, 0x10, 0x3E, 0x8D - }, - { - 0x89, 0x15, 0x46, 0xA8, 0xB2, 0x9F, 0x30, 0x47, - 0xDD, 0xCF, 0xE5, 0xB0, 0x0E, 0x45, 0xFD, 0x55, - 0x75, 0x63, 0x73, 0x10, 0x5E, 0xA8, 0x63, 0x7D, - 0xFC, 0xFF, 0x54, 0x7B, 0x6E, 0xA9, 0x53, 0x5F - }, - { - 0x18, 0xDF, 0xBC, 0x1A, 0xC5, 0xD2, 0x5B, 0x07, - 0x61, 0x13, 0x7D, 0xBD, 0x22, 0xC1, 0x7C, 0x82, - 0x9D, 0x0F, 0x0E, 0xF1, 0xD8, 0x23, 0x44, 0xE9, - 0xC8, 0x9C, 0x28, 0x66, 0x94, 0xDA, 0x24, 0xE8 - }, - { - 0xB5, 0x4B, 0x9B, 0x67, 0xF8, 0xFE, 0xD5, 0x4B, - 0xBF, 0x5A, 0x26, 0x66, 0xDB, 0xDF, 0x4B, 0x23, - 0xCF, 0xF1, 0xD1, 0xB6, 0xF4, 0xAF, 0xC9, 0x85, - 0xB2, 0xE6, 0xD3, 0x30, 0x5A, 0x9F, 0xF8, 0x0F - }, - { - 0x7D, 0xB4, 0x42, 0xE1, 0x32, 0xBA, 0x59, 0xBC, - 0x12, 0x89, 0xAA, 0x98, 0xB0, 0xD3, 0xE8, 0x06, - 0x00, 0x4F, 0x8E, 0xC1, 0x28, 0x11, 0xAF, 0x1E, - 0x2E, 0x33, 0xC6, 0x9B, 0xFD, 0xE7, 0x29, 0xE1 - }, - { - 0x25, 0x0F, 0x37, 0xCD, 0xC1, 0x5E, 0x81, 0x7D, - 0x2F, 0x16, 0x0D, 0x99, 0x56, 0xC7, 0x1F, 0xE3, - 0xEB, 0x5D, 0xB7, 0x45, 0x56, 0xE4, 0xAD, 0xF9, - 0xA4, 0xFF, 0xAF, 0xBA, 0x74, 0x01, 0x03, 0x96 - }, - { - 0x4A, 0xB8, 0xA3, 0xDD, 0x1D, 0xDF, 0x8A, 0xD4, - 0x3D, 0xAB, 0x13, 0xA2, 0x7F, 0x66, 0xA6, 0x54, - 0x4F, 0x29, 0x05, 0x97, 0xFA, 0x96, 0x04, 0x0E, - 0x0E, 0x1D, 0xB9, 0x26, 0x3A, 0xA4, 0x79, 0xF8 - }, - { - 0xEE, 0x61, 0x72, 0x7A, 0x07, 0x66, 0xDF, 0x93, - 0x9C, 0xCD, 0xC8, 0x60, 0x33, 0x40, 0x44, 0xC7, - 0x9A, 0x3C, 0x9B, 0x15, 0x62, 0x00, 0xBC, 0x3A, - 0xA3, 0x29, 0x73, 0x48, 0x3D, 0x83, 0x41, 0xAE - }, - { - 0x3F, 0x68, 0xC7, 0xEC, 0x63, 0xAC, 0x11, 0xEB, - 0xB9, 0x8F, 0x94, 0xB3, 0x39, 0xB0, 0x5C, 0x10, - 0x49, 0x84, 0xFD, 0xA5, 0x01, 0x03, 0x06, 0x01, - 0x44, 0xE5, 0xA2, 0xBF, 0xCC, 0xC9, 0xDA, 0x95 - }, - { - 0x05, 0x6F, 0x29, 0x81, 0x6B, 0x8A, 0xF8, 0xF5, - 0x66, 0x82, 0xBC, 0x4D, 0x7C, 0xF0, 0x94, 0x11, - 0x1D, 0xA7, 0x73, 0x3E, 0x72, 0x6C, 0xD1, 0x3D, - 0x6B, 0x3E, 0x8E, 0xA0, 0x3E, 0x92, 0xA0, 0xD5 - }, - { - 0xF5, 0xEC, 0x43, 0xA2, 0x8A, 0xCB, 0xEF, 0xF1, - 0xF3, 0x31, 0x8A, 0x5B, 0xCA, 0xC7, 0xC6, 0x6D, - 0xDB, 0x52, 0x30, 0xB7, 0x9D, 0xB2, 0xD1, 0x05, - 0xBC, 0xBE, 0x15, 0xF3, 0xC1, 0x14, 0x8D, 0x69 - }, - { - 0x2A, 0x69, 0x60, 0xAD, 0x1D, 0x8D, 0xD5, 0x47, - 0x55, 0x5C, 0xFB, 0xD5, 0xE4, 0x60, 0x0F, 0x1E, - 0xAA, 0x1C, 0x8E, 0xDA, 0x34, 0xDE, 0x03, 0x74, - 0xEC, 0x4A, 0x26, 0xEA, 0xAA, 0xA3, 0x3B, 0x4E - }, - { - 0xDC, 0xC1, 0xEA, 0x7B, 0xAA, 0xB9, 0x33, 0x84, - 0xF7, 0x6B, 0x79, 0x68, 0x66, 0x19, 0x97, 0x54, - 0x74, 0x2F, 0x7B, 0x96, 0xD6, 0xB4, 0xC1, 0x20, - 0x16, 0x5C, 0x04, 0xA6, 0xC4, 0xF5, 0xCE, 0x10 - }, - { - 0x13, 0xD5, 0xDF, 0x17, 0x92, 0x21, 0x37, 0x9C, - 0x6A, 0x78, 0xC0, 0x7C, 0x79, 0x3F, 0xF5, 0x34, - 0x87, 0xCA, 0xE6, 0xBF, 0x9F, 0xE8, 0x82, 0x54, - 0x1A, 0xB0, 0xE7, 0x35, 0xE3, 0xEA, 0xDA, 0x3B - }, - { - 0x8C, 0x59, 0xE4, 0x40, 0x76, 0x41, 0xA0, 0x1E, - 0x8F, 0xF9, 0x1F, 0x99, 0x80, 0xDC, 0x23, 0x6F, - 0x4E, 0xCD, 0x6F, 0xCF, 0x52, 0x58, 0x9A, 0x09, - 0x9A, 0x96, 0x16, 0x33, 0x96, 0x77, 0x14, 0xE1 - }, - { - 0x83, 0x3B, 0x1A, 0xC6, 0xA2, 0x51, 0xFD, 0x08, - 0xFD, 0x6D, 0x90, 0x8F, 0xEA, 0x2A, 0x4E, 0xE1, - 0xE0, 0x40, 0xBC, 0xA9, 0x3F, 0xC1, 0xA3, 0x8E, - 0xC3, 0x82, 0x0E, 0x0C, 0x10, 0xBD, 0x82, 0xEA - }, - { - 0xA2, 0x44, 0xF9, 0x27, 0xF3, 0xB4, 0x0B, 0x8F, - 0x6C, 0x39, 0x15, 0x70, 0xC7, 0x65, 0x41, 0x8F, - 0x2F, 0x6E, 0x70, 0x8E, 0xAC, 0x90, 0x06, 0xC5, - 0x1A, 0x7F, 0xEF, 0xF4, 0xAF, 0x3B, 0x2B, 0x9E - }, - { - 0x3D, 0x99, 0xED, 0x95, 0x50, 0xCF, 0x11, 0x96, - 0xE6, 0xC4, 0xD2, 0x0C, 0x25, 0x96, 0x20, 0xF8, - 0x58, 0xC3, 0xD7, 0x03, 0x37, 0x4C, 0x12, 0x8C, - 0xE7, 0xB5, 0x90, 0x31, 0x0C, 0x83, 0x04, 0x6D - }, - { - 0x2B, 0x35, 0xC4, 0x7D, 0x7B, 0x87, 0x76, 0x1F, - 0x0A, 0xE4, 0x3A, 0xC5, 0x6A, 0xC2, 0x7B, 0x9F, - 0x25, 0x83, 0x03, 0x67, 0xB5, 0x95, 0xBE, 0x8C, - 0x24, 0x0E, 0x94, 0x60, 0x0C, 0x6E, 0x33, 0x12 - }, - { - 0x5D, 0x11, 0xED, 0x37, 0xD2, 0x4D, 0xC7, 0x67, - 0x30, 0x5C, 0xB7, 0xE1, 0x46, 0x7D, 0x87, 0xC0, - 0x65, 0xAC, 0x4B, 0xC8, 0xA4, 0x26, 0xDE, 0x38, - 0x99, 0x1F, 0xF5, 0x9A, 0xA8, 0x73, 0x5D, 0x02 - }, - { - 0xB8, 0x36, 0x47, 0x8E, 0x1C, 0xA0, 0x64, 0x0D, - 0xCE, 0x6F, 0xD9, 0x10, 0xA5, 0x09, 0x62, 0x72, - 0xC8, 0x33, 0x09, 0x90, 0xCD, 0x97, 0x86, 0x4A, - 0xC2, 0xBF, 0x14, 0xEF, 0x6B, 0x23, 0x91, 0x4A - }, - { - 0x91, 0x00, 0xF9, 0x46, 0xD6, 0xCC, 0xDE, 0x3A, - 0x59, 0x7F, 0x90, 0xD3, 0x9F, 0xC1, 0x21, 0x5B, - 0xAD, 0xDC, 0x74, 0x13, 0x64, 0x3D, 0x85, 0xC2, - 0x1C, 0x3E, 0xEE, 0x5D, 0x2D, 0xD3, 0x28, 0x94 - }, - { - 0xDA, 0x70, 0xEE, 0xDD, 0x23, 0xE6, 0x63, 0xAA, - 0x1A, 0x74, 0xB9, 0x76, 0x69, 0x35, 0xB4, 0x79, - 0x22, 0x2A, 0x72, 0xAF, 0xBA, 0x5C, 0x79, 0x51, - 0x58, 0xDA, 0xD4, 0x1A, 0x3B, 0xD7, 0x7E, 0x40 - }, - { - 0xF0, 0x67, 0xED, 0x6A, 0x0D, 0xBD, 0x43, 0xAA, - 0x0A, 0x92, 0x54, 0xE6, 0x9F, 0xD6, 0x6B, 0xDD, - 0x8A, 0xCB, 0x87, 0xDE, 0x93, 0x6C, 0x25, 0x8C, - 0xFB, 0x02, 0x28, 0x5F, 0x2C, 0x11, 0xFA, 0x79 - }, - { - 0x71, 0x5C, 0x99, 0xC7, 0xD5, 0x75, 0x80, 0xCF, - 0x97, 0x53, 0xB4, 0xC1, 0xD7, 0x95, 0xE4, 0x5A, - 0x83, 0xFB, 0xB2, 0x28, 0xC0, 0xD3, 0x6F, 0xBE, - 0x20, 0xFA, 0xF3, 0x9B, 0xDD, 0x6D, 0x4E, 0x85 - }, - { - 0xE4, 0x57, 0xD6, 0xAD, 0x1E, 0x67, 0xCB, 0x9B, - 0xBD, 0x17, 0xCB, 0xD6, 0x98, 0xFA, 0x6D, 0x7D, - 0xAE, 0x0C, 0x9B, 0x7A, 0xD6, 0xCB, 0xD6, 0x53, - 0x96, 0x34, 0xE3, 0x2A, 0x71, 0x9C, 0x84, 0x92 - }, - { - 0xEC, 0xE3, 0xEA, 0x81, 0x03, 0xE0, 0x24, 0x83, - 0xC6, 0x4A, 0x70, 0xA4, 0xBD, 0xCE, 0xE8, 0xCE, - 0xB6, 0x27, 0x8F, 0x25, 0x33, 0xF3, 0xF4, 0x8D, - 0xBE, 0xED, 0xFB, 0xA9, 0x45, 0x31, 0xD4, 0xAE - }, - { - 0x38, 0x8A, 0xA5, 0xD3, 0x66, 0x7A, 0x97, 0xC6, - 0x8D, 0x3D, 0x56, 0xF8, 0xF3, 0xEE, 0x8D, 0x3D, - 0x36, 0x09, 0x1F, 0x17, 0xFE, 0x5D, 0x1B, 0x0D, - 0x5D, 0x84, 0xC9, 0x3B, 0x2F, 0xFE, 0x40, 0xBD - }, - { - 0x8B, 0x6B, 0x31, 0xB9, 0xAD, 0x7C, 0x3D, 0x5C, - 0xD8, 0x4B, 0xF9, 0x89, 0x47, 0xB9, 0xCD, 0xB5, - 0x9D, 0xF8, 0xA2, 0x5F, 0xF7, 0x38, 0x10, 0x10, - 0x13, 0xBE, 0x4F, 0xD6, 0x5E, 0x1D, 0xD1, 0xA3 - }, - { - 0x06, 0x62, 0x91, 0xF6, 0xBB, 0xD2, 0x5F, 0x3C, - 0x85, 0x3D, 0xB7, 0xD8, 0xB9, 0x5C, 0x9A, 0x1C, - 0xFB, 0x9B, 0xF1, 0xC1, 0xC9, 0x9F, 0xB9, 0x5A, - 0x9B, 0x78, 0x69, 0xD9, 0x0F, 0x1C, 0x29, 0x03 - }, - { - 0xA7, 0x07, 0xEF, 0xBC, 0xCD, 0xCE, 0xED, 0x42, - 0x96, 0x7A, 0x66, 0xF5, 0x53, 0x9B, 0x93, 0xED, - 0x75, 0x60, 0xD4, 0x67, 0x30, 0x40, 0x16, 0xC4, - 0x78, 0x0D, 0x77, 0x55, 0xA5, 0x65, 0xD4, 0xC4 - }, - { - 0x38, 0xC5, 0x3D, 0xFB, 0x70, 0xBE, 0x7E, 0x79, - 0x2B, 0x07, 0xA6, 0xA3, 0x5B, 0x8A, 0x6A, 0x0A, - 0xBA, 0x02, 0xC5, 0xC5, 0xF3, 0x8B, 0xAF, 0x5C, - 0x82, 0x3F, 0xDF, 0xD9, 0xE4, 0x2D, 0x65, 0x7E - }, - { - 0xF2, 0x91, 0x13, 0x86, 0x50, 0x1D, 0x9A, 0xB9, - 0xD7, 0x20, 0xCF, 0x8A, 0xD1, 0x05, 0x03, 0xD5, - 0x63, 0x4B, 0xF4, 0xB7, 0xD1, 0x2B, 0x56, 0xDF, - 0xB7, 0x4F, 0xEC, 0xC6, 0xE4, 0x09, 0x3F, 0x68 - }, - { - 0xC6, 0xF2, 0xBD, 0xD5, 0x2B, 0x81, 0xE6, 0xE4, - 0xF6, 0x59, 0x5A, 0xBD, 0x4D, 0x7F, 0xB3, 0x1F, - 0x65, 0x11, 0x69, 0xD0, 0x0F, 0xF3, 0x26, 0x92, - 0x6B, 0x34, 0x94, 0x7B, 0x28, 0xA8, 0x39, 0x59 - }, - { - 0x29, 0x3D, 0x94, 0xB1, 0x8C, 0x98, 0xBB, 0x32, - 0x23, 0x36, 0x6B, 0x8C, 0xE7, 0x4C, 0x28, 0xFB, - 0xDF, 0x28, 0xE1, 0xF8, 0x4A, 0x33, 0x50, 0xB0, - 0xEB, 0x2D, 0x18, 0x04, 0xA5, 0x77, 0x57, 0x9B - }, - { - 0x2C, 0x2F, 0xA5, 0xC0, 0xB5, 0x15, 0x33, 0x16, - 0x5B, 0xC3, 0x75, 0xC2, 0x2E, 0x27, 0x81, 0x76, - 0x82, 0x70, 0xA3, 0x83, 0x98, 0x5D, 0x13, 0xBD, - 0x6B, 0x67, 0xB6, 0xFD, 0x67, 0xF8, 0x89, 0xEB - }, - { - 0xCA, 0xA0, 0x9B, 0x82, 0xB7, 0x25, 0x62, 0xE4, - 0x3F, 0x4B, 0x22, 0x75, 0xC0, 0x91, 0x91, 0x8E, - 0x62, 0x4D, 0x91, 0x16, 0x61, 0xCC, 0x81, 0x1B, - 0xB5, 0xFA, 0xEC, 0x51, 0xF6, 0x08, 0x8E, 0xF7 - }, - { - 0x24, 0x76, 0x1E, 0x45, 0xE6, 0x74, 0x39, 0x53, - 0x79, 0xFB, 0x17, 0x72, 0x9C, 0x78, 0xCB, 0x93, - 0x9E, 0x6F, 0x74, 0xC5, 0xDF, 0xFB, 0x9C, 0x96, - 0x1F, 0x49, 0x59, 0x82, 0xC3, 0xED, 0x1F, 0xE3 - }, - { - 0x55, 0xB7, 0x0A, 0x82, 0x13, 0x1E, 0xC9, 0x48, - 0x88, 0xD7, 0xAB, 0x54, 0xA7, 0xC5, 0x15, 0x25, - 0x5C, 0x39, 0x38, 0xBB, 0x10, 0xBC, 0x78, 0x4D, - 0xC9, 0xB6, 0x7F, 0x07, 0x6E, 0x34, 0x1A, 0x73 - }, - { - 0x6A, 0xB9, 0x05, 0x7B, 0x97, 0x7E, 0xBC, 0x3C, - 0xA4, 0xD4, 0xCE, 0x74, 0x50, 0x6C, 0x25, 0xCC, - 0xCD, 0xC5, 0x66, 0x49, 0x7C, 0x45, 0x0B, 0x54, - 0x15, 0xA3, 0x94, 0x86, 0xF8, 0x65, 0x7A, 0x03 - }, - { - 0x24, 0x06, 0x6D, 0xEE, 0xE0, 0xEC, 0xEE, 0x15, - 0xA4, 0x5F, 0x0A, 0x32, 0x6D, 0x0F, 0x8D, 0xBC, - 0x79, 0x76, 0x1E, 0xBB, 0x93, 0xCF, 0x8C, 0x03, - 0x77, 0xAF, 0x44, 0x09, 0x78, 0xFC, 0xF9, 0x94 - }, - { - 0x20, 0x00, 0x0D, 0x3F, 0x66, 0xBA, 0x76, 0x86, - 0x0D, 0x5A, 0x95, 0x06, 0x88, 0xB9, 0xAA, 0x0D, - 0x76, 0xCF, 0xEA, 0x59, 0xB0, 0x05, 0xD8, 0x59, - 0x91, 0x4B, 0x1A, 0x46, 0x65, 0x3A, 0x93, 0x9B - }, - { - 0xB9, 0x2D, 0xAA, 0x79, 0x60, 0x3E, 0x3B, 0xDB, - 0xC3, 0xBF, 0xE0, 0xF4, 0x19, 0xE4, 0x09, 0xB2, - 0xEA, 0x10, 0xDC, 0x43, 0x5B, 0xEE, 0xFE, 0x29, - 0x59, 0xDA, 0x16, 0x89, 0x5D, 0x5D, 0xCA, 0x1C - }, - { - 0xE9, 0x47, 0x94, 0x87, 0x05, 0xB2, 0x06, 0xD5, - 0x72, 0xB0, 0xE8, 0xF6, 0x2F, 0x66, 0xA6, 0x55, - 0x1C, 0xBD, 0x6B, 0xC3, 0x05, 0xD2, 0x6C, 0xE7, - 0x53, 0x9A, 0x12, 0xF9, 0xAA, 0xDF, 0x75, 0x71 - }, - { - 0x3D, 0x67, 0xC1, 0xB3, 0xF9, 0xB2, 0x39, 0x10, - 0xE3, 0xD3, 0x5E, 0x6B, 0x0F, 0x2C, 0xCF, 0x44, - 0xA0, 0xB5, 0x40, 0xA4, 0x5C, 0x18, 0xBA, 0x3C, - 0x36, 0x26, 0x4D, 0xD4, 0x8E, 0x96, 0xAF, 0x6A - }, - { - 0xC7, 0x55, 0x8B, 0xAB, 0xDA, 0x04, 0xBC, 0xCB, - 0x76, 0x4D, 0x0B, 0xBF, 0x33, 0x58, 0x42, 0x51, - 0x41, 0x90, 0x2D, 0x22, 0x39, 0x1D, 0x9F, 0x8C, - 0x59, 0x15, 0x9F, 0xEC, 0x9E, 0x49, 0xB1, 0x51 - }, - { - 0x0B, 0x73, 0x2B, 0xB0, 0x35, 0x67, 0x5A, 0x50, - 0xFF, 0x58, 0xF2, 0xC2, 0x42, 0xE4, 0x71, 0x0A, - 0xEC, 0xE6, 0x46, 0x70, 0x07, 0x9C, 0x13, 0x04, - 0x4C, 0x79, 0xC9, 0xB7, 0x49, 0x1F, 0x70, 0x00 - }, - { - 0xD1, 0x20, 0xB5, 0xEF, 0x6D, 0x57, 0xEB, 0xF0, - 0x6E, 0xAF, 0x96, 0xBC, 0x93, 0x3C, 0x96, 0x7B, - 0x16, 0xCB, 0xE6, 0xE2, 0xBF, 0x00, 0x74, 0x1C, - 0x30, 0xAA, 0x1C, 0x54, 0xBA, 0x64, 0x80, 0x1F - }, - { - 0x58, 0xD2, 0x12, 0xAD, 0x6F, 0x58, 0xAE, 0xF0, - 0xF8, 0x01, 0x16, 0xB4, 0x41, 0xE5, 0x7F, 0x61, - 0x95, 0xBF, 0xEF, 0x26, 0xB6, 0x14, 0x63, 0xED, - 0xEC, 0x11, 0x83, 0xCD, 0xB0, 0x4F, 0xE7, 0x6D - }, - { - 0xB8, 0x83, 0x6F, 0x51, 0xD1, 0xE2, 0x9B, 0xDF, - 0xDB, 0xA3, 0x25, 0x56, 0x53, 0x60, 0x26, 0x8B, - 0x8F, 0xAD, 0x62, 0x74, 0x73, 0xED, 0xEC, 0xEF, - 0x7E, 0xAE, 0xFE, 0xE8, 0x37, 0xC7, 0x40, 0x03 - }, - { - 0xC5, 0x47, 0xA3, 0xC1, 0x24, 0xAE, 0x56, 0x85, - 0xFF, 0xA7, 0xB8, 0xED, 0xAF, 0x96, 0xEC, 0x86, - 0xF8, 0xB2, 0xD0, 0xD5, 0x0C, 0xEE, 0x8B, 0xE3, - 0xB1, 0xF0, 0xC7, 0x67, 0x63, 0x06, 0x9D, 0x9C - }, - { - 0x5D, 0x16, 0x8B, 0x76, 0x9A, 0x2F, 0x67, 0x85, - 0x3D, 0x62, 0x95, 0xF7, 0x56, 0x8B, 0xE4, 0x0B, - 0xB7, 0xA1, 0x6B, 0x8D, 0x65, 0xBA, 0x87, 0x63, - 0x5D, 0x19, 0x78, 0xD2, 0xAB, 0x11, 0xBA, 0x2A - }, - { - 0xA2, 0xF6, 0x75, 0xDC, 0x73, 0x02, 0x63, 0x8C, - 0xB6, 0x02, 0x01, 0x06, 0x4C, 0xA5, 0x50, 0x77, - 0x71, 0x4D, 0x71, 0xFE, 0x09, 0x6A, 0x31, 0x5F, - 0x2F, 0xE7, 0x40, 0x12, 0x77, 0xCA, 0xA5, 0xAF - }, - { - 0xC8, 0xAA, 0xB5, 0xCD, 0x01, 0x60, 0xAE, 0x78, - 0xCD, 0x2E, 0x8A, 0xC5, 0xFB, 0x0E, 0x09, 0x3C, - 0xDB, 0x5C, 0x4B, 0x60, 0x52, 0xA0, 0xA9, 0x7B, - 0xB0, 0x42, 0x16, 0x82, 0x6F, 0xA7, 0xA4, 0x37 - }, - { - 0xFF, 0x68, 0xCA, 0x40, 0x35, 0xBF, 0xEB, 0x43, - 0xFB, 0xF1, 0x45, 0xFD, 0xDD, 0x5E, 0x43, 0xF1, - 0xCE, 0xA5, 0x4F, 0x11, 0xF7, 0xBE, 0xE1, 0x30, - 0x58, 0xF0, 0x27, 0x32, 0x9A, 0x4A, 0x5F, 0xA4 - }, - { - 0x1D, 0x4E, 0x54, 0x87, 0xAE, 0x3C, 0x74, 0x0F, - 0x2B, 0xA6, 0xE5, 0x41, 0xAC, 0x91, 0xBC, 0x2B, - 0xFC, 0xD2, 0x99, 0x9C, 0x51, 0x8D, 0x80, 0x7B, - 0x42, 0x67, 0x48, 0x80, 0x3A, 0x35, 0x0F, 0xD4 - }, - { - 0x6D, 0x24, 0x4E, 0x1A, 0x06, 0xCE, 0x4E, 0xF5, - 0x78, 0xDD, 0x0F, 0x63, 0xAF, 0xF0, 0x93, 0x67, - 0x06, 0x73, 0x51, 0x19, 0xCA, 0x9C, 0x8D, 0x22, - 0xD8, 0x6C, 0x80, 0x14, 0x14, 0xAB, 0x97, 0x41 - }, - { - 0xDE, 0xCF, 0x73, 0x29, 0xDB, 0xCC, 0x82, 0x7B, - 0x8F, 0xC5, 0x24, 0xC9, 0x43, 0x1E, 0x89, 0x98, - 0x02, 0x9E, 0xCE, 0x12, 0xCE, 0x93, 0xB7, 0xB2, - 0xF3, 0xE7, 0x69, 0xA9, 0x41, 0xFB, 0x8C, 0xEA - }, - { - 0x2F, 0xAF, 0xCC, 0x0F, 0x2E, 0x63, 0xCB, 0xD0, - 0x77, 0x55, 0xBE, 0x7B, 0x75, 0xEC, 0xEA, 0x0A, - 0xDF, 0xF9, 0xAA, 0x5E, 0xDE, 0x2A, 0x52, 0xFD, - 0xAB, 0x4D, 0xFD, 0x03, 0x74, 0xCD, 0x48, 0x3F - }, - { - 0xAA, 0x85, 0x01, 0x0D, 0xD4, 0x6A, 0x54, 0x6B, - 0x53, 0x5E, 0xF4, 0xCF, 0x5F, 0x07, 0xD6, 0x51, - 0x61, 0xE8, 0x98, 0x28, 0xF3, 0xA7, 0x7D, 0xB7, - 0xB9, 0xB5, 0x6F, 0x0D, 0xF5, 0x9A, 0xAE, 0x45 - }, - { - 0x07, 0xE8, 0xE1, 0xEE, 0x73, 0x2C, 0xB0, 0xD3, - 0x56, 0xC9, 0xC0, 0xD1, 0x06, 0x9C, 0x89, 0xD1, - 0x7A, 0xDF, 0x6A, 0x9A, 0x33, 0x4F, 0x74, 0x5E, - 0xC7, 0x86, 0x73, 0x32, 0x54, 0x8C, 0xA8, 0xE9 - }, - { - 0x0E, 0x01, 0xE8, 0x1C, 0xAD, 0xA8, 0x16, 0x2B, - 0xFD, 0x5F, 0x8A, 0x8C, 0x81, 0x8A, 0x6C, 0x69, - 0xFE, 0xDF, 0x02, 0xCE, 0xB5, 0x20, 0x85, 0x23, - 0xCB, 0xE5, 0x31, 0x3B, 0x89, 0xCA, 0x10, 0x53 - }, - { - 0x6B, 0xB6, 0xC6, 0x47, 0x26, 0x55, 0x08, 0x43, - 0x99, 0x85, 0x2E, 0x00, 0x24, 0x9F, 0x8C, 0xB2, - 0x47, 0x89, 0x6D, 0x39, 0x2B, 0x02, 0xD7, 0x3B, - 0x7F, 0x0D, 0xD8, 0x18, 0xE1, 0xE2, 0x9B, 0x07 - }, - { - 0x42, 0xD4, 0x63, 0x6E, 0x20, 0x60, 0xF0, 0x8F, - 0x41, 0xC8, 0x82, 0xE7, 0x6B, 0x39, 0x6B, 0x11, - 0x2E, 0xF6, 0x27, 0xCC, 0x24, 0xC4, 0x3D, 0xD5, - 0xF8, 0x3A, 0x1D, 0x1A, 0x7E, 0xAD, 0x71, 0x1A - }, - { - 0x48, 0x58, 0xC9, 0xA1, 0x88, 0xB0, 0x23, 0x4F, - 0xB9, 0xA8, 0xD4, 0x7D, 0x0B, 0x41, 0x33, 0x65, - 0x0A, 0x03, 0x0B, 0xD0, 0x61, 0x1B, 0x87, 0xC3, - 0x89, 0x2E, 0x94, 0x95, 0x1F, 0x8D, 0xF8, 0x52 - }, - { - 0x3F, 0xAB, 0x3E, 0x36, 0x98, 0x8D, 0x44, 0x5A, - 0x51, 0xC8, 0x78, 0x3E, 0x53, 0x1B, 0xE3, 0xA0, - 0x2B, 0xE4, 0x0C, 0xD0, 0x47, 0x96, 0xCF, 0xB6, - 0x1D, 0x40, 0x34, 0x74, 0x42, 0xD3, 0xF7, 0x94 - }, - { - 0xEB, 0xAB, 0xC4, 0x96, 0x36, 0xBD, 0x43, 0x3D, - 0x2E, 0xC8, 0xF0, 0xE5, 0x18, 0x73, 0x2E, 0xF8, - 0xFA, 0x21, 0xD4, 0xD0, 0x71, 0xCC, 0x3B, 0xC4, - 0x6C, 0xD7, 0x9F, 0xA3, 0x8A, 0x28, 0xB8, 0x10 - }, - { - 0xA1, 0xD0, 0x34, 0x35, 0x23, 0xB8, 0x93, 0xFC, - 0xA8, 0x4F, 0x47, 0xFE, 0xB4, 0xA6, 0x4D, 0x35, - 0x0A, 0x17, 0xD8, 0xEE, 0xF5, 0x49, 0x7E, 0xCE, - 0x69, 0x7D, 0x02, 0xD7, 0x91, 0x78, 0xB5, 0x91 - }, - { - 0x26, 0x2E, 0xBF, 0xD9, 0x13, 0x0B, 0x7D, 0x28, - 0x76, 0x0D, 0x08, 0xEF, 0x8B, 0xFD, 0x3B, 0x86, - 0xCD, 0xD3, 0xB2, 0x11, 0x3D, 0x2C, 0xAE, 0xF7, - 0xEA, 0x95, 0x1A, 0x30, 0x3D, 0xFA, 0x38, 0x46 - }, - { - 0xF7, 0x61, 0x58, 0xED, 0xD5, 0x0A, 0x15, 0x4F, - 0xA7, 0x82, 0x03, 0xED, 0x23, 0x62, 0x93, 0x2F, - 0xCB, 0x82, 0x53, 0xAA, 0xE3, 0x78, 0x90, 0x3E, - 0xDE, 0xD1, 0xE0, 0x3F, 0x70, 0x21, 0xA2, 0x57 - }, - { - 0x26, 0x17, 0x8E, 0x95, 0x0A, 0xC7, 0x22, 0xF6, - 0x7A, 0xE5, 0x6E, 0x57, 0x1B, 0x28, 0x4C, 0x02, - 0x07, 0x68, 0x4A, 0x63, 0x34, 0xA1, 0x77, 0x48, - 0xA9, 0x4D, 0x26, 0x0B, 0xC5, 0xF5, 0x52, 0x74 - }, - { - 0xC3, 0x78, 0xD1, 0xE4, 0x93, 0xB4, 0x0E, 0xF1, - 0x1F, 0xE6, 0xA1, 0x5D, 0x9C, 0x27, 0x37, 0xA3, - 0x78, 0x09, 0x63, 0x4C, 0x5A, 0xBA, 0xD5, 0xB3, - 0x3D, 0x7E, 0x39, 0x3B, 0x4A, 0xE0, 0x5D, 0x03 - }, - { - 0x98, 0x4B, 0xD8, 0x37, 0x91, 0x01, 0xBE, 0x8F, - 0xD8, 0x06, 0x12, 0xD8, 0xEA, 0x29, 0x59, 0xA7, - 0x86, 0x5E, 0xC9, 0x71, 0x85, 0x23, 0x55, 0x01, - 0x07, 0xAE, 0x39, 0x38, 0xDF, 0x32, 0x01, 0x1B - }, - { - 0xC6, 0xF2, 0x5A, 0x81, 0x2A, 0x14, 0x48, 0x58, - 0xAC, 0x5C, 0xED, 0x37, 0xA9, 0x3A, 0x9F, 0x47, - 0x59, 0xBA, 0x0B, 0x1C, 0x0F, 0xDC, 0x43, 0x1D, - 0xCE, 0x35, 0xF9, 0xEC, 0x1F, 0x1F, 0x4A, 0x99 - }, - { - 0x92, 0x4C, 0x75, 0xC9, 0x44, 0x24, 0xFF, 0x75, - 0xE7, 0x4B, 0x8B, 0x4E, 0x94, 0x35, 0x89, 0x58, - 0xB0, 0x27, 0xB1, 0x71, 0xDF, 0x5E, 0x57, 0x89, - 0x9A, 0xD0, 0xD4, 0xDA, 0xC3, 0x73, 0x53, 0xB6 - }, - { - 0x0A, 0xF3, 0x58, 0x92, 0xA6, 0x3F, 0x45, 0x93, - 0x1F, 0x68, 0x46, 0xED, 0x19, 0x03, 0x61, 0xCD, - 0x07, 0x30, 0x89, 0xE0, 0x77, 0x16, 0x57, 0x14, - 0xB5, 0x0B, 0x81, 0xA2, 0xE3, 0xDD, 0x9B, 0xA1 - }, - { - 0xCC, 0x80, 0xCE, 0xFB, 0x26, 0xC3, 0xB2, 0xB0, - 0xDA, 0xEF, 0x23, 0x3E, 0x60, 0x6D, 0x5F, 0xFC, - 0x80, 0xFA, 0x17, 0x42, 0x7D, 0x18, 0xE3, 0x04, - 0x89, 0x67, 0x3E, 0x06, 0xEF, 0x4B, 0x87, 0xF7 - }, - { - 0xC2, 0xF8, 0xC8, 0x11, 0x74, 0x47, 0xF3, 0x97, - 0x8B, 0x08, 0x18, 0xDC, 0xF6, 0xF7, 0x01, 0x16, - 0xAC, 0x56, 0xFD, 0x18, 0x4D, 0xD1, 0x27, 0x84, - 0x94, 0xE1, 0x03, 0xFC, 0x6D, 0x74, 0xA8, 0x87 - }, - { - 0xBD, 0xEC, 0xF6, 0xBF, 0xC1, 0xBA, 0x0D, 0xF6, - 0xE8, 0x62, 0xC8, 0x31, 0x99, 0x22, 0x07, 0x79, - 0x6A, 0xCC, 0x79, 0x79, 0x68, 0x35, 0x88, 0x28, - 0xC0, 0x6E, 0x7A, 0x51, 0xE0, 0x90, 0x09, 0x8F - }, - { - 0x24, 0xD1, 0xA2, 0x6E, 0x3D, 0xAB, 0x02, 0xFE, - 0x45, 0x72, 0xD2, 0xAA, 0x7D, 0xBD, 0x3E, 0xC3, - 0x0F, 0x06, 0x93, 0xDB, 0x26, 0xF2, 0x73, 0xD0, - 0xAB, 0x2C, 0xB0, 0xC1, 0x3B, 0x5E, 0x64, 0x51 - }, - { - 0xEC, 0x56, 0xF5, 0x8B, 0x09, 0x29, 0x9A, 0x30, - 0x0B, 0x14, 0x05, 0x65, 0xD7, 0xD3, 0xE6, 0x87, - 0x82, 0xB6, 0xE2, 0xFB, 0xEB, 0x4B, 0x7E, 0xA9, - 0x7A, 0xC0, 0x57, 0x98, 0x90, 0x61, 0xDD, 0x3F - }, - { - 0x11, 0xA4, 0x37, 0xC1, 0xAB, 0xA3, 0xC1, 0x19, - 0xDD, 0xFA, 0xB3, 0x1B, 0x3E, 0x8C, 0x84, 0x1D, - 0xEE, 0xEB, 0x91, 0x3E, 0xF5, 0x7F, 0x7E, 0x48, - 0xF2, 0xC9, 0xCF, 0x5A, 0x28, 0xFA, 0x42, 0xBC - }, - { - 0x53, 0xC7, 0xE6, 0x11, 0x4B, 0x85, 0x0A, 0x2C, - 0xB4, 0x96, 0xC9, 0xB3, 0xC6, 0x9A, 0x62, 0x3E, - 0xAE, 0xA2, 0xCB, 0x1D, 0x33, 0xDD, 0x81, 0x7E, - 0x47, 0x65, 0xED, 0xAA, 0x68, 0x23, 0xC2, 0x28 - }, - { - 0x15, 0x4C, 0x3E, 0x96, 0xFE, 0xE5, 0xDB, 0x14, - 0xF8, 0x77, 0x3E, 0x18, 0xAF, 0x14, 0x85, 0x79, - 0x13, 0x50, 0x9D, 0xA9, 0x99, 0xB4, 0x6C, 0xDD, - 0x3D, 0x4C, 0x16, 0x97, 0x60, 0xC8, 0x3A, 0xD2 - }, - { - 0x40, 0xB9, 0x91, 0x6F, 0x09, 0x3E, 0x02, 0x7A, - 0x87, 0x86, 0x64, 0x18, 0x18, 0x92, 0x06, 0x20, - 0x47, 0x2F, 0xBC, 0xF6, 0x8F, 0x70, 0x1D, 0x1B, - 0x68, 0x06, 0x32, 0xE6, 0x99, 0x6B, 0xDE, 0xD3 - }, - { - 0x24, 0xC4, 0xCB, 0xBA, 0x07, 0x11, 0x98, 0x31, - 0xA7, 0x26, 0xB0, 0x53, 0x05, 0xD9, 0x6D, 0xA0, - 0x2F, 0xF8, 0xB1, 0x48, 0xF0, 0xDA, 0x44, 0x0F, - 0xE2, 0x33, 0xBC, 0xAA, 0x32, 0xC7, 0x2F, 0x6F - }, - { - 0x5D, 0x20, 0x15, 0x10, 0x25, 0x00, 0x20, 0xB7, - 0x83, 0x68, 0x96, 0x88, 0xAB, 0xBF, 0x8E, 0xCF, - 0x25, 0x94, 0xA9, 0x6A, 0x08, 0xF2, 0xBF, 0xEC, - 0x6C, 0xE0, 0x57, 0x44, 0x65, 0xDD, 0xED, 0x71 - }, - { - 0x04, 0x3B, 0x97, 0xE3, 0x36, 0xEE, 0x6F, 0xDB, - 0xBE, 0x2B, 0x50, 0xF2, 0x2A, 0xF8, 0x32, 0x75, - 0xA4, 0x08, 0x48, 0x05, 0xD2, 0xD5, 0x64, 0x59, - 0x62, 0x45, 0x4B, 0x6C, 0x9B, 0x80, 0x53, 0xA0 - }, - { - 0x56, 0x48, 0x35, 0xCB, 0xAE, 0xA7, 0x74, 0x94, - 0x85, 0x68, 0xBE, 0x36, 0xCF, 0x52, 0xFC, 0xDD, - 0x83, 0x93, 0x4E, 0xB0, 0xA2, 0x75, 0x12, 0xDB, - 0xE3, 0xE2, 0xDB, 0x47, 0xB9, 0xE6, 0x63, 0x5A - }, - { - 0xF2, 0x1C, 0x33, 0xF4, 0x7B, 0xDE, 0x40, 0xA2, - 0xA1, 0x01, 0xC9, 0xCD, 0xE8, 0x02, 0x7A, 0xAF, - 0x61, 0xA3, 0x13, 0x7D, 0xE2, 0x42, 0x2B, 0x30, - 0x03, 0x5A, 0x04, 0xC2, 0x70, 0x89, 0x41, 0x83 - }, - { - 0x9D, 0xB0, 0xEF, 0x74, 0xE6, 0x6C, 0xBB, 0x84, - 0x2E, 0xB0, 0xE0, 0x73, 0x43, 0xA0, 0x3C, 0x5C, - 0x56, 0x7E, 0x37, 0x2B, 0x3F, 0x23, 0xB9, 0x43, - 0xC7, 0x88, 0xA4, 0xF2, 0x50, 0xF6, 0x78, 0x91 - }, - { - 0xAB, 0x8D, 0x08, 0x65, 0x5F, 0xF1, 0xD3, 0xFE, - 0x87, 0x58, 0xD5, 0x62, 0x23, 0x5F, 0xD2, 0x3E, - 0x7C, 0xF9, 0xDC, 0xAA, 0xD6, 0x58, 0x87, 0x2A, - 0x49, 0xE5, 0xD3, 0x18, 0x3B, 0x6C, 0xCE, 0xBD - }, - { - 0x6F, 0x27, 0xF7, 0x7E, 0x7B, 0xCF, 0x46, 0xA1, - 0xE9, 0x63, 0xAD, 0xE0, 0x30, 0x97, 0x33, 0x54, - 0x30, 0x31, 0xDC, 0xCD, 0xD4, 0x7C, 0xAA, 0xC1, - 0x74, 0xD7, 0xD2, 0x7C, 0xE8, 0x07, 0x7E, 0x8B - }, - { - 0xE3, 0xCD, 0x54, 0xDA, 0x7E, 0x44, 0x4C, 0xAA, - 0x62, 0x07, 0x56, 0x95, 0x25, 0xA6, 0x70, 0xEB, - 0xAE, 0x12, 0x78, 0xDE, 0x4E, 0x3F, 0xE2, 0x68, - 0x4B, 0x3E, 0x33, 0xF5, 0xEF, 0x90, 0xCC, 0x1B - }, - { - 0xB2, 0xC3, 0xE3, 0x3A, 0x51, 0xD2, 0x2C, 0x4C, - 0x08, 0xFC, 0x09, 0x89, 0xC8, 0x73, 0xC9, 0xCC, - 0x41, 0x50, 0x57, 0x9B, 0x1E, 0x61, 0x63, 0xFA, - 0x69, 0x4A, 0xD5, 0x1D, 0x53, 0xD7, 0x12, 0xDC - }, - { - 0xBE, 0x7F, 0xDA, 0x98, 0x3E, 0x13, 0x18, 0x9B, - 0x4C, 0x77, 0xE0, 0xA8, 0x09, 0x20, 0xB6, 0xE0, - 0xE0, 0xEA, 0x80, 0xC3, 0xB8, 0x4D, 0xBE, 0x7E, - 0x71, 0x17, 0xD2, 0x53, 0xF4, 0x81, 0x12, 0xF4 - }, - { - 0xB6, 0x00, 0x8C, 0x28, 0xFA, 0xE0, 0x8A, 0xA4, - 0x27, 0xE5, 0xBD, 0x3A, 0xAD, 0x36, 0xF1, 0x00, - 0x21, 0xF1, 0x6C, 0x77, 0xCF, 0xEA, 0xBE, 0xD0, - 0x7F, 0x97, 0xCC, 0x7D, 0xC1, 0xF1, 0x28, 0x4A - }, - { - 0x6E, 0x4E, 0x67, 0x60, 0xC5, 0x38, 0xF2, 0xE9, - 0x7B, 0x3A, 0xDB, 0xFB, 0xBC, 0xDE, 0x57, 0xF8, - 0x96, 0x6B, 0x7E, 0xA8, 0xFC, 0xB5, 0xBF, 0x7E, - 0xFE, 0xC9, 0x13, 0xFD, 0x2A, 0x2B, 0x0C, 0x55 - }, - { - 0x4A, 0xE5, 0x1F, 0xD1, 0x83, 0x4A, 0xA5, 0xBD, - 0x9A, 0x6F, 0x7E, 0xC3, 0x9F, 0xC6, 0x63, 0x33, - 0x8D, 0xC5, 0xD2, 0xE2, 0x07, 0x61, 0x56, 0x6D, - 0x90, 0xCC, 0x68, 0xB1, 0xCB, 0x87, 0x5E, 0xD8 - }, - { - 0xB6, 0x73, 0xAA, 0xD7, 0x5A, 0xB1, 0xFD, 0xB5, - 0x40, 0x1A, 0xBF, 0xA1, 0xBF, 0x89, 0xF3, 0xAD, - 0xD2, 0xEB, 0xC4, 0x68, 0xDF, 0x36, 0x24, 0xA4, - 0x78, 0xF4, 0xFE, 0x85, 0x9D, 0x8D, 0x55, 0xE2 - }, - { - 0x13, 0xC9, 0x47, 0x1A, 0x98, 0x55, 0x91, 0x35, - 0x39, 0x83, 0x66, 0x60, 0x39, 0x8D, 0xA0, 0xF3, - 0xF9, 0x9A, 0xDA, 0x08, 0x47, 0x9C, 0x69, 0xD1, - 0xB7, 0xFC, 0xAA, 0x34, 0x61, 0xDD, 0x7E, 0x59 - }, - { - 0x2C, 0x11, 0xF4, 0xA7, 0xF9, 0x9A, 0x1D, 0x23, - 0xA5, 0x8B, 0xB6, 0x36, 0x35, 0x0F, 0xE8, 0x49, - 0xF2, 0x9C, 0xBA, 0xC1, 0xB2, 0xA1, 0x11, 0x2D, - 0x9F, 0x1E, 0xD5, 0xBC, 0x5B, 0x31, 0x3C, 0xCD - }, - { - 0xC7, 0xD3, 0xC0, 0x70, 0x6B, 0x11, 0xAE, 0x74, - 0x1C, 0x05, 0xA1, 0xEF, 0x15, 0x0D, 0xD6, 0x5B, - 0x54, 0x94, 0xD6, 0xD5, 0x4C, 0x9A, 0x86, 0xE2, - 0x61, 0x78, 0x54, 0xE6, 0xAE, 0xEE, 0xBB, 0xD9 - }, - { - 0x19, 0x4E, 0x10, 0xC9, 0x38, 0x93, 0xAF, 0xA0, - 0x64, 0xC3, 0xAC, 0x04, 0xC0, 0xDD, 0x80, 0x8D, - 0x79, 0x1C, 0x3D, 0x4B, 0x75, 0x56, 0xE8, 0x9D, - 0x8D, 0x9C, 0xB2, 0x25, 0xC4, 0xB3, 0x33, 0x39 - }, - { - 0x6F, 0xC4, 0x98, 0x8B, 0x8F, 0x78, 0x54, 0x6B, - 0x16, 0x88, 0x99, 0x18, 0x45, 0x90, 0x8F, 0x13, - 0x4B, 0x6A, 0x48, 0x2E, 0x69, 0x94, 0xB3, 0xD4, - 0x83, 0x17, 0xBF, 0x08, 0xDB, 0x29, 0x21, 0x85 - }, - { - 0x56, 0x65, 0xBE, 0xB8, 0xB0, 0x95, 0x55, 0x25, - 0x81, 0x3B, 0x59, 0x81, 0xCD, 0x14, 0x2E, 0xD4, - 0xD0, 0x3F, 0xBA, 0x38, 0xA6, 0xF3, 0xE5, 0xAD, - 0x26, 0x8E, 0x0C, 0xC2, 0x70, 0xD1, 0xCD, 0x11 - }, - { - 0xB8, 0x83, 0xD6, 0x8F, 0x5F, 0xE5, 0x19, 0x36, - 0x43, 0x1B, 0xA4, 0x25, 0x67, 0x38, 0x05, 0x3B, - 0x1D, 0x04, 0x26, 0xD4, 0xCB, 0x64, 0xB1, 0x6E, - 0x83, 0xBA, 0xDC, 0x5E, 0x9F, 0xBE, 0x3B, 0x81 - }, - { - 0x53, 0xE7, 0xB2, 0x7E, 0xA5, 0x9C, 0x2F, 0x6D, - 0xBB, 0x50, 0x76, 0x9E, 0x43, 0x55, 0x4D, 0xF3, - 0x5A, 0xF8, 0x9F, 0x48, 0x22, 0xD0, 0x46, 0x6B, - 0x00, 0x7D, 0xD6, 0xF6, 0xDE, 0xAF, 0xFF, 0x02 - }, - { - 0x1F, 0x1A, 0x02, 0x29, 0xD4, 0x64, 0x0F, 0x01, - 0x90, 0x15, 0x88, 0xD9, 0xDE, 0xC2, 0x2D, 0x13, - 0xFC, 0x3E, 0xB3, 0x4A, 0x61, 0xB3, 0x29, 0x38, - 0xEF, 0xBF, 0x53, 0x34, 0xB2, 0x80, 0x0A, 0xFA - }, - { - 0xC2, 0xB4, 0x05, 0xAF, 0xA0, 0xFA, 0x66, 0x68, - 0x85, 0x2A, 0xEE, 0x4D, 0x88, 0x04, 0x08, 0x53, - 0xFA, 0xB8, 0x00, 0xE7, 0x2B, 0x57, 0x58, 0x14, - 0x18, 0xE5, 0x50, 0x6F, 0x21, 0x4C, 0x7D, 0x1F - }, - { - 0xC0, 0x8A, 0xA1, 0xC2, 0x86, 0xD7, 0x09, 0xFD, - 0xC7, 0x47, 0x37, 0x44, 0x97, 0x71, 0x88, 0xC8, - 0x95, 0xBA, 0x01, 0x10, 0x14, 0x24, 0x7E, 0x4E, - 0xFA, 0x8D, 0x07, 0xE7, 0x8F, 0xEC, 0x69, 0x5C - }, - { - 0xF0, 0x3F, 0x57, 0x89, 0xD3, 0x33, 0x6B, 0x80, - 0xD0, 0x02, 0xD5, 0x9F, 0xDF, 0x91, 0x8B, 0xDB, - 0x77, 0x5B, 0x00, 0x95, 0x6E, 0xD5, 0x52, 0x8E, - 0x86, 0xAA, 0x99, 0x4A, 0xCB, 0x38, 0xFE, 0x2D - }, -}; - - - - -static const uint8_t blake2s_keyed_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = -{ - { - 0x48, 0xA8, 0x99, 0x7D, 0xA4, 0x07, 0x87, 0x6B, - 0x3D, 0x79, 0xC0, 0xD9, 0x23, 0x25, 0xAD, 0x3B, - 0x89, 0xCB, 0xB7, 0x54, 0xD8, 0x6A, 0xB7, 0x1A, - 0xEE, 0x04, 0x7A, 0xD3, 0x45, 0xFD, 0x2C, 0x49 - }, - { - 0x40, 0xD1, 0x5F, 0xEE, 0x7C, 0x32, 0x88, 0x30, - 0x16, 0x6A, 0xC3, 0xF9, 0x18, 0x65, 0x0F, 0x80, - 0x7E, 0x7E, 0x01, 0xE1, 0x77, 0x25, 0x8C, 0xDC, - 0x0A, 0x39, 0xB1, 0x1F, 0x59, 0x80, 0x66, 0xF1 - }, - { - 0x6B, 0xB7, 0x13, 0x00, 0x64, 0x4C, 0xD3, 0x99, - 0x1B, 0x26, 0xCC, 0xD4, 0xD2, 0x74, 0xAC, 0xD1, - 0xAD, 0xEA, 0xB8, 0xB1, 0xD7, 0x91, 0x45, 0x46, - 0xC1, 0x19, 0x8B, 0xBE, 0x9F, 0xC9, 0xD8, 0x03 - }, - { - 0x1D, 0x22, 0x0D, 0xBE, 0x2E, 0xE1, 0x34, 0x66, - 0x1F, 0xDF, 0x6D, 0x9E, 0x74, 0xB4, 0x17, 0x04, - 0x71, 0x05, 0x56, 0xF2, 0xF6, 0xE5, 0xA0, 0x91, - 0xB2, 0x27, 0x69, 0x74, 0x45, 0xDB, 0xEA, 0x6B - }, - { - 0xF6, 0xC3, 0xFB, 0xAD, 0xB4, 0xCC, 0x68, 0x7A, - 0x00, 0x64, 0xA5, 0xBE, 0x6E, 0x79, 0x1B, 0xEC, - 0x63, 0xB8, 0x68, 0xAD, 0x62, 0xFB, 0xA6, 0x1B, - 0x37, 0x57, 0xEF, 0x9C, 0xA5, 0x2E, 0x05, 0xB2 - }, - { - 0x49, 0xC1, 0xF2, 0x11, 0x88, 0xDF, 0xD7, 0x69, - 0xAE, 0xA0, 0xE9, 0x11, 0xDD, 0x6B, 0x41, 0xF1, - 0x4D, 0xAB, 0x10, 0x9D, 0x2B, 0x85, 0x97, 0x7A, - 0xA3, 0x08, 0x8B, 0x5C, 0x70, 0x7E, 0x85, 0x98 - }, - { - 0xFD, 0xD8, 0x99, 0x3D, 0xCD, 0x43, 0xF6, 0x96, - 0xD4, 0x4F, 0x3C, 0xEA, 0x0F, 0xF3, 0x53, 0x45, - 0x23, 0x4E, 0xC8, 0xEE, 0x08, 0x3E, 0xB3, 0xCA, - 0xDA, 0x01, 0x7C, 0x7F, 0x78, 0xC1, 0x71, 0x43 - }, - { - 0xE6, 0xC8, 0x12, 0x56, 0x37, 0x43, 0x8D, 0x09, - 0x05, 0xB7, 0x49, 0xF4, 0x65, 0x60, 0xAC, 0x89, - 0xFD, 0x47, 0x1C, 0xF8, 0x69, 0x2E, 0x28, 0xFA, - 0xB9, 0x82, 0xF7, 0x3F, 0x01, 0x9B, 0x83, 0xA9 - }, - { - 0x19, 0xFC, 0x8C, 0xA6, 0x97, 0x9D, 0x60, 0xE6, - 0xED, 0xD3, 0xB4, 0x54, 0x1E, 0x2F, 0x96, 0x7C, - 0xED, 0x74, 0x0D, 0xF6, 0xEC, 0x1E, 0xAE, 0xBB, - 0xFE, 0x81, 0x38, 0x32, 0xE9, 0x6B, 0x29, 0x74 - }, - { - 0xA6, 0xAD, 0x77, 0x7C, 0xE8, 0x81, 0xB5, 0x2B, - 0xB5, 0xA4, 0x42, 0x1A, 0xB6, 0xCD, 0xD2, 0xDF, - 0xBA, 0x13, 0xE9, 0x63, 0x65, 0x2D, 0x4D, 0x6D, - 0x12, 0x2A, 0xEE, 0x46, 0x54, 0x8C, 0x14, 0xA7 - }, - { - 0xF5, 0xC4, 0xB2, 0xBA, 0x1A, 0x00, 0x78, 0x1B, - 0x13, 0xAB, 0xA0, 0x42, 0x52, 0x42, 0xC6, 0x9C, - 0xB1, 0x55, 0x2F, 0x3F, 0x71, 0xA9, 0xA3, 0xBB, - 0x22, 0xB4, 0xA6, 0xB4, 0x27, 0x7B, 0x46, 0xDD - }, - { - 0xE3, 0x3C, 0x4C, 0x9B, 0xD0, 0xCC, 0x7E, 0x45, - 0xC8, 0x0E, 0x65, 0xC7, 0x7F, 0xA5, 0x99, 0x7F, - 0xEC, 0x70, 0x02, 0x73, 0x85, 0x41, 0x50, 0x9E, - 0x68, 0xA9, 0x42, 0x38, 0x91, 0xE8, 0x22, 0xA3 - }, - { - 0xFB, 0xA1, 0x61, 0x69, 0xB2, 0xC3, 0xEE, 0x10, - 0x5B, 0xE6, 0xE1, 0xE6, 0x50, 0xE5, 0xCB, 0xF4, - 0x07, 0x46, 0xB6, 0x75, 0x3D, 0x03, 0x6A, 0xB5, - 0x51, 0x79, 0x01, 0x4A, 0xD7, 0xEF, 0x66, 0x51 - }, - { - 0xF5, 0xC4, 0xBE, 0xC6, 0xD6, 0x2F, 0xC6, 0x08, - 0xBF, 0x41, 0xCC, 0x11, 0x5F, 0x16, 0xD6, 0x1C, - 0x7E, 0xFD, 0x3F, 0xF6, 0xC6, 0x56, 0x92, 0xBB, - 0xE0, 0xAF, 0xFF, 0xB1, 0xFE, 0xDE, 0x74, 0x75 - }, - { - 0xA4, 0x86, 0x2E, 0x76, 0xDB, 0x84, 0x7F, 0x05, - 0xBA, 0x17, 0xED, 0xE5, 0xDA, 0x4E, 0x7F, 0x91, - 0xB5, 0x92, 0x5C, 0xF1, 0xAD, 0x4B, 0xA1, 0x27, - 0x32, 0xC3, 0x99, 0x57, 0x42, 0xA5, 0xCD, 0x6E - }, - { - 0x65, 0xF4, 0xB8, 0x60, 0xCD, 0x15, 0xB3, 0x8E, - 0xF8, 0x14, 0xA1, 0xA8, 0x04, 0x31, 0x4A, 0x55, - 0xBE, 0x95, 0x3C, 0xAA, 0x65, 0xFD, 0x75, 0x8A, - 0xD9, 0x89, 0xFF, 0x34, 0xA4, 0x1C, 0x1E, 0xEA - }, - { - 0x19, 0xBA, 0x23, 0x4F, 0x0A, 0x4F, 0x38, 0x63, - 0x7D, 0x18, 0x39, 0xF9, 0xD9, 0xF7, 0x6A, 0xD9, - 0x1C, 0x85, 0x22, 0x30, 0x71, 0x43, 0xC9, 0x7D, - 0x5F, 0x93, 0xF6, 0x92, 0x74, 0xCE, 0xC9, 0xA7 - }, - { - 0x1A, 0x67, 0x18, 0x6C, 0xA4, 0xA5, 0xCB, 0x8E, - 0x65, 0xFC, 0xA0, 0xE2, 0xEC, 0xBC, 0x5D, 0xDC, - 0x14, 0xAE, 0x38, 0x1B, 0xB8, 0xBF, 0xFE, 0xB9, - 0xE0, 0xA1, 0x03, 0x44, 0x9E, 0x3E, 0xF0, 0x3C - }, - { - 0xAF, 0xBE, 0xA3, 0x17, 0xB5, 0xA2, 0xE8, 0x9C, - 0x0B, 0xD9, 0x0C, 0xCF, 0x5D, 0x7F, 0xD0, 0xED, - 0x57, 0xFE, 0x58, 0x5E, 0x4B, 0xE3, 0x27, 0x1B, - 0x0A, 0x6B, 0xF0, 0xF5, 0x78, 0x6B, 0x0F, 0x26 - }, - { - 0xF1, 0xB0, 0x15, 0x58, 0xCE, 0x54, 0x12, 0x62, - 0xF5, 0xEC, 0x34, 0x29, 0x9D, 0x6F, 0xB4, 0x09, - 0x00, 0x09, 0xE3, 0x43, 0x4B, 0xE2, 0xF4, 0x91, - 0x05, 0xCF, 0x46, 0xAF, 0x4D, 0x2D, 0x41, 0x24 - }, - { - 0x13, 0xA0, 0xA0, 0xC8, 0x63, 0x35, 0x63, 0x5E, - 0xAA, 0x74, 0xCA, 0x2D, 0x5D, 0x48, 0x8C, 0x79, - 0x7B, 0xBB, 0x4F, 0x47, 0xDC, 0x07, 0x10, 0x50, - 0x15, 0xED, 0x6A, 0x1F, 0x33, 0x09, 0xEF, 0xCE - }, - { - 0x15, 0x80, 0xAF, 0xEE, 0xBE, 0xBB, 0x34, 0x6F, - 0x94, 0xD5, 0x9F, 0xE6, 0x2D, 0xA0, 0xB7, 0x92, - 0x37, 0xEA, 0xD7, 0xB1, 0x49, 0x1F, 0x56, 0x67, - 0xA9, 0x0E, 0x45, 0xED, 0xF6, 0xCA, 0x8B, 0x03 - }, - { - 0x20, 0xBE, 0x1A, 0x87, 0x5B, 0x38, 0xC5, 0x73, - 0xDD, 0x7F, 0xAA, 0xA0, 0xDE, 0x48, 0x9D, 0x65, - 0x5C, 0x11, 0xEF, 0xB6, 0xA5, 0x52, 0x69, 0x8E, - 0x07, 0xA2, 0xD3, 0x31, 0xB5, 0xF6, 0x55, 0xC3 - }, - { - 0xBE, 0x1F, 0xE3, 0xC4, 0xC0, 0x40, 0x18, 0xC5, - 0x4C, 0x4A, 0x0F, 0x6B, 0x9A, 0x2E, 0xD3, 0xC5, - 0x3A, 0xBE, 0x3A, 0x9F, 0x76, 0xB4, 0xD2, 0x6D, - 0xE5, 0x6F, 0xC9, 0xAE, 0x95, 0x05, 0x9A, 0x99 - }, - { - 0xE3, 0xE3, 0xAC, 0xE5, 0x37, 0xEB, 0x3E, 0xDD, - 0x84, 0x63, 0xD9, 0xAD, 0x35, 0x82, 0xE1, 0x3C, - 0xF8, 0x65, 0x33, 0xFF, 0xDE, 0x43, 0xD6, 0x68, - 0xDD, 0x2E, 0x93, 0xBB, 0xDB, 0xD7, 0x19, 0x5A - }, - { - 0x11, 0x0C, 0x50, 0xC0, 0xBF, 0x2C, 0x6E, 0x7A, - 0xEB, 0x7E, 0x43, 0x5D, 0x92, 0xD1, 0x32, 0xAB, - 0x66, 0x55, 0x16, 0x8E, 0x78, 0xA2, 0xDE, 0xCD, - 0xEC, 0x33, 0x30, 0x77, 0x76, 0x84, 0xD9, 0xC1 - }, - { - 0xE9, 0xBA, 0x8F, 0x50, 0x5C, 0x9C, 0x80, 0xC0, - 0x86, 0x66, 0xA7, 0x01, 0xF3, 0x36, 0x7E, 0x6C, - 0xC6, 0x65, 0xF3, 0x4B, 0x22, 0xE7, 0x3C, 0x3C, - 0x04, 0x17, 0xEB, 0x1C, 0x22, 0x06, 0x08, 0x2F - }, - { - 0x26, 0xCD, 0x66, 0xFC, 0xA0, 0x23, 0x79, 0xC7, - 0x6D, 0xF1, 0x23, 0x17, 0x05, 0x2B, 0xCA, 0xFD, - 0x6C, 0xD8, 0xC3, 0xA7, 0xB8, 0x90, 0xD8, 0x05, - 0xF3, 0x6C, 0x49, 0x98, 0x97, 0x82, 0x43, 0x3A - }, - { - 0x21, 0x3F, 0x35, 0x96, 0xD6, 0xE3, 0xA5, 0xD0, - 0xE9, 0x93, 0x2C, 0xD2, 0x15, 0x91, 0x46, 0x01, - 0x5E, 0x2A, 0xBC, 0x94, 0x9F, 0x47, 0x29, 0xEE, - 0x26, 0x32, 0xFE, 0x1E, 0xDB, 0x78, 0xD3, 0x37 - }, - { - 0x10, 0x15, 0xD7, 0x01, 0x08, 0xE0, 0x3B, 0xE1, - 0xC7, 0x02, 0xFE, 0x97, 0x25, 0x36, 0x07, 0xD1, - 0x4A, 0xEE, 0x59, 0x1F, 0x24, 0x13, 0xEA, 0x67, - 0x87, 0x42, 0x7B, 0x64, 0x59, 0xFF, 0x21, 0x9A - }, - { - 0x3C, 0xA9, 0x89, 0xDE, 0x10, 0xCF, 0xE6, 0x09, - 0x90, 0x94, 0x72, 0xC8, 0xD3, 0x56, 0x10, 0x80, - 0x5B, 0x2F, 0x97, 0x77, 0x34, 0xCF, 0x65, 0x2C, - 0xC6, 0x4B, 0x3B, 0xFC, 0x88, 0x2D, 0x5D, 0x89 - }, - { - 0xB6, 0x15, 0x6F, 0x72, 0xD3, 0x80, 0xEE, 0x9E, - 0xA6, 0xAC, 0xD1, 0x90, 0x46, 0x4F, 0x23, 0x07, - 0xA5, 0xC1, 0x79, 0xEF, 0x01, 0xFD, 0x71, 0xF9, - 0x9F, 0x2D, 0x0F, 0x7A, 0x57, 0x36, 0x0A, 0xEA - }, - { - 0xC0, 0x3B, 0xC6, 0x42, 0xB2, 0x09, 0x59, 0xCB, - 0xE1, 0x33, 0xA0, 0x30, 0x3E, 0x0C, 0x1A, 0xBF, - 0xF3, 0xE3, 0x1E, 0xC8, 0xE1, 0xA3, 0x28, 0xEC, - 0x85, 0x65, 0xC3, 0x6D, 0xEC, 0xFF, 0x52, 0x65 - }, - { - 0x2C, 0x3E, 0x08, 0x17, 0x6F, 0x76, 0x0C, 0x62, - 0x64, 0xC3, 0xA2, 0xCD, 0x66, 0xFE, 0xC6, 0xC3, - 0xD7, 0x8D, 0xE4, 0x3F, 0xC1, 0x92, 0x45, 0x7B, - 0x2A, 0x4A, 0x66, 0x0A, 0x1E, 0x0E, 0xB2, 0x2B - }, - { - 0xF7, 0x38, 0xC0, 0x2F, 0x3C, 0x1B, 0x19, 0x0C, - 0x51, 0x2B, 0x1A, 0x32, 0xDE, 0xAB, 0xF3, 0x53, - 0x72, 0x8E, 0x0E, 0x9A, 0xB0, 0x34, 0x49, 0x0E, - 0x3C, 0x34, 0x09, 0x94, 0x6A, 0x97, 0xAE, 0xEC - }, - { - 0x8B, 0x18, 0x80, 0xDF, 0x30, 0x1C, 0xC9, 0x63, - 0x41, 0x88, 0x11, 0x08, 0x89, 0x64, 0x83, 0x92, - 0x87, 0xFF, 0x7F, 0xE3, 0x1C, 0x49, 0xEA, 0x6E, - 0xBD, 0x9E, 0x48, 0xBD, 0xEE, 0xE4, 0x97, 0xC5 - }, - { - 0x1E, 0x75, 0xCB, 0x21, 0xC6, 0x09, 0x89, 0x02, - 0x03, 0x75, 0xF1, 0xA7, 0xA2, 0x42, 0x83, 0x9F, - 0x0B, 0x0B, 0x68, 0x97, 0x3A, 0x4C, 0x2A, 0x05, - 0xCF, 0x75, 0x55, 0xED, 0x5A, 0xAE, 0xC4, 0xC1 - }, - { - 0x62, 0xBF, 0x8A, 0x9C, 0x32, 0xA5, 0xBC, 0xCF, - 0x29, 0x0B, 0x6C, 0x47, 0x4D, 0x75, 0xB2, 0xA2, - 0xA4, 0x09, 0x3F, 0x1A, 0x9E, 0x27, 0x13, 0x94, - 0x33, 0xA8, 0xF2, 0xB3, 0xBC, 0xE7, 0xB8, 0xD7 - }, - { - 0x16, 0x6C, 0x83, 0x50, 0xD3, 0x17, 0x3B, 0x5E, - 0x70, 0x2B, 0x78, 0x3D, 0xFD, 0x33, 0xC6, 0x6E, - 0xE0, 0x43, 0x27, 0x42, 0xE9, 0xB9, 0x2B, 0x99, - 0x7F, 0xD2, 0x3C, 0x60, 0xDC, 0x67, 0x56, 0xCA - }, - { - 0x04, 0x4A, 0x14, 0xD8, 0x22, 0xA9, 0x0C, 0xAC, - 0xF2, 0xF5, 0xA1, 0x01, 0x42, 0x8A, 0xDC, 0x8F, - 0x41, 0x09, 0x38, 0x6C, 0xCB, 0x15, 0x8B, 0xF9, - 0x05, 0xC8, 0x61, 0x8B, 0x8E, 0xE2, 0x4E, 0xC3 - }, - { - 0x38, 0x7D, 0x39, 0x7E, 0xA4, 0x3A, 0x99, 0x4B, - 0xE8, 0x4D, 0x2D, 0x54, 0x4A, 0xFB, 0xE4, 0x81, - 0xA2, 0x00, 0x0F, 0x55, 0x25, 0x26, 0x96, 0xBB, - 0xA2, 0xC5, 0x0C, 0x8E, 0xBD, 0x10, 0x13, 0x47 - }, - { - 0x56, 0xF8, 0xCC, 0xF1, 0xF8, 0x64, 0x09, 0xB4, - 0x6C, 0xE3, 0x61, 0x66, 0xAE, 0x91, 0x65, 0x13, - 0x84, 0x41, 0x57, 0x75, 0x89, 0xDB, 0x08, 0xCB, - 0xC5, 0xF6, 0x6C, 0xA2, 0x97, 0x43, 0xB9, 0xFD - }, - { - 0x97, 0x06, 0xC0, 0x92, 0xB0, 0x4D, 0x91, 0xF5, - 0x3D, 0xFF, 0x91, 0xFA, 0x37, 0xB7, 0x49, 0x3D, - 0x28, 0xB5, 0x76, 0xB5, 0xD7, 0x10, 0x46, 0x9D, - 0xF7, 0x94, 0x01, 0x66, 0x22, 0x36, 0xFC, 0x03 - }, - { - 0x87, 0x79, 0x68, 0x68, 0x6C, 0x06, 0x8C, 0xE2, - 0xF7, 0xE2, 0xAD, 0xCF, 0xF6, 0x8B, 0xF8, 0x74, - 0x8E, 0xDF, 0x3C, 0xF8, 0x62, 0xCF, 0xB4, 0xD3, - 0x94, 0x7A, 0x31, 0x06, 0x95, 0x80, 0x54, 0xE3 - }, - { - 0x88, 0x17, 0xE5, 0x71, 0x98, 0x79, 0xAC, 0xF7, - 0x02, 0x47, 0x87, 0xEC, 0xCD, 0xB2, 0x71, 0x03, - 0x55, 0x66, 0xCF, 0xA3, 0x33, 0xE0, 0x49, 0x40, - 0x7C, 0x01, 0x78, 0xCC, 0xC5, 0x7A, 0x5B, 0x9F - }, - { - 0x89, 0x38, 0x24, 0x9E, 0x4B, 0x50, 0xCA, 0xDA, - 0xCC, 0xDF, 0x5B, 0x18, 0x62, 0x13, 0x26, 0xCB, - 0xB1, 0x52, 0x53, 0xE3, 0x3A, 0x20, 0xF5, 0x63, - 0x6E, 0x99, 0x5D, 0x72, 0x47, 0x8D, 0xE4, 0x72 - }, - { - 0xF1, 0x64, 0xAB, 0xBA, 0x49, 0x63, 0xA4, 0x4D, - 0x10, 0x72, 0x57, 0xE3, 0x23, 0x2D, 0x90, 0xAC, - 0xA5, 0xE6, 0x6A, 0x14, 0x08, 0x24, 0x8C, 0x51, - 0x74, 0x1E, 0x99, 0x1D, 0xB5, 0x22, 0x77, 0x56 - }, - { - 0xD0, 0x55, 0x63, 0xE2, 0xB1, 0xCB, 0xA0, 0xC4, - 0xA2, 0xA1, 0xE8, 0xBD, 0xE3, 0xA1, 0xA0, 0xD9, - 0xF5, 0xB4, 0x0C, 0x85, 0xA0, 0x70, 0xD6, 0xF5, - 0xFB, 0x21, 0x06, 0x6E, 0xAD, 0x5D, 0x06, 0x01 - }, - { - 0x03, 0xFB, 0xB1, 0x63, 0x84, 0xF0, 0xA3, 0x86, - 0x6F, 0x4C, 0x31, 0x17, 0x87, 0x76, 0x66, 0xEF, - 0xBF, 0x12, 0x45, 0x97, 0x56, 0x4B, 0x29, 0x3D, - 0x4A, 0xAB, 0x0D, 0x26, 0x9F, 0xAB, 0xDD, 0xFA - }, - { - 0x5F, 0xA8, 0x48, 0x6A, 0xC0, 0xE5, 0x29, 0x64, - 0xD1, 0x88, 0x1B, 0xBE, 0x33, 0x8E, 0xB5, 0x4B, - 0xE2, 0xF7, 0x19, 0x54, 0x92, 0x24, 0x89, 0x20, - 0x57, 0xB4, 0xDA, 0x04, 0xBA, 0x8B, 0x34, 0x75 - }, - { - 0xCD, 0xFA, 0xBC, 0xEE, 0x46, 0x91, 0x11, 0x11, - 0x23, 0x6A, 0x31, 0x70, 0x8B, 0x25, 0x39, 0xD7, - 0x1F, 0xC2, 0x11, 0xD9, 0xB0, 0x9C, 0x0D, 0x85, - 0x30, 0xA1, 0x1E, 0x1D, 0xBF, 0x6E, 0xED, 0x01 - }, - { - 0x4F, 0x82, 0xDE, 0x03, 0xB9, 0x50, 0x47, 0x93, - 0xB8, 0x2A, 0x07, 0xA0, 0xBD, 0xCD, 0xFF, 0x31, - 0x4D, 0x75, 0x9E, 0x7B, 0x62, 0xD2, 0x6B, 0x78, - 0x49, 0x46, 0xB0, 0xD3, 0x6F, 0x91, 0x6F, 0x52 - }, - { - 0x25, 0x9E, 0xC7, 0xF1, 0x73, 0xBC, 0xC7, 0x6A, - 0x09, 0x94, 0xC9, 0x67, 0xB4, 0xF5, 0xF0, 0x24, - 0xC5, 0x60, 0x57, 0xFB, 0x79, 0xC9, 0x65, 0xC4, - 0xFA, 0xE4, 0x18, 0x75, 0xF0, 0x6A, 0x0E, 0x4C - }, - { - 0x19, 0x3C, 0xC8, 0xE7, 0xC3, 0xE0, 0x8B, 0xB3, - 0x0F, 0x54, 0x37, 0xAA, 0x27, 0xAD, 0xE1, 0xF1, - 0x42, 0x36, 0x9B, 0x24, 0x6A, 0x67, 0x5B, 0x23, - 0x83, 0xE6, 0xDA, 0x9B, 0x49, 0xA9, 0x80, 0x9E - }, - { - 0x5C, 0x10, 0x89, 0x6F, 0x0E, 0x28, 0x56, 0xB2, - 0xA2, 0xEE, 0xE0, 0xFE, 0x4A, 0x2C, 0x16, 0x33, - 0x56, 0x5D, 0x18, 0xF0, 0xE9, 0x3E, 0x1F, 0xAB, - 0x26, 0xC3, 0x73, 0xE8, 0xF8, 0x29, 0x65, 0x4D - }, - { - 0xF1, 0x60, 0x12, 0xD9, 0x3F, 0x28, 0x85, 0x1A, - 0x1E, 0xB9, 0x89, 0xF5, 0xD0, 0xB4, 0x3F, 0x3F, - 0x39, 0xCA, 0x73, 0xC9, 0xA6, 0x2D, 0x51, 0x81, - 0xBF, 0xF2, 0x37, 0x53, 0x6B, 0xD3, 0x48, 0xC3 - }, - { - 0x29, 0x66, 0xB3, 0xCF, 0xAE, 0x1E, 0x44, 0xEA, - 0x99, 0x6D, 0xC5, 0xD6, 0x86, 0xCF, 0x25, 0xFA, - 0x05, 0x3F, 0xB6, 0xF6, 0x72, 0x01, 0xB9, 0xE4, - 0x6E, 0xAD, 0xE8, 0x5D, 0x0A, 0xD6, 0xB8, 0x06 - }, - { - 0xDD, 0xB8, 0x78, 0x24, 0x85, 0xE9, 0x00, 0xBC, - 0x60, 0xBC, 0xF4, 0xC3, 0x3A, 0x6F, 0xD5, 0x85, - 0x68, 0x0C, 0xC6, 0x83, 0xD5, 0x16, 0xEF, 0xA0, - 0x3E, 0xB9, 0x98, 0x5F, 0xAD, 0x87, 0x15, 0xFB - }, - { - 0x4C, 0x4D, 0x6E, 0x71, 0xAE, 0xA0, 0x57, 0x86, - 0x41, 0x31, 0x48, 0xFC, 0x7A, 0x78, 0x6B, 0x0E, - 0xCA, 0xF5, 0x82, 0xCF, 0xF1, 0x20, 0x9F, 0x5A, - 0x80, 0x9F, 0xBA, 0x85, 0x04, 0xCE, 0x66, 0x2C - }, - { - 0xFB, 0x4C, 0x5E, 0x86, 0xD7, 0xB2, 0x22, 0x9B, - 0x99, 0xB8, 0xBA, 0x6D, 0x94, 0xC2, 0x47, 0xEF, - 0x96, 0x4A, 0xA3, 0xA2, 0xBA, 0xE8, 0xED, 0xC7, - 0x75, 0x69, 0xF2, 0x8D, 0xBB, 0xFF, 0x2D, 0x4E - }, - { - 0xE9, 0x4F, 0x52, 0x6D, 0xE9, 0x01, 0x96, 0x33, - 0xEC, 0xD5, 0x4A, 0xC6, 0x12, 0x0F, 0x23, 0x95, - 0x8D, 0x77, 0x18, 0xF1, 0xE7, 0x71, 0x7B, 0xF3, - 0x29, 0x21, 0x1A, 0x4F, 0xAE, 0xED, 0x4E, 0x6D - }, - { - 0xCB, 0xD6, 0x66, 0x0A, 0x10, 0xDB, 0x3F, 0x23, - 0xF7, 0xA0, 0x3D, 0x4B, 0x9D, 0x40, 0x44, 0xC7, - 0x93, 0x2B, 0x28, 0x01, 0xAC, 0x89, 0xD6, 0x0B, - 0xC9, 0xEB, 0x92, 0xD6, 0x5A, 0x46, 0xC2, 0xA0 - }, - { - 0x88, 0x18, 0xBB, 0xD3, 0xDB, 0x4D, 0xC1, 0x23, - 0xB2, 0x5C, 0xBB, 0xA5, 0xF5, 0x4C, 0x2B, 0xC4, - 0xB3, 0xFC, 0xF9, 0xBF, 0x7D, 0x7A, 0x77, 0x09, - 0xF4, 0xAE, 0x58, 0x8B, 0x26, 0x7C, 0x4E, 0xCE - }, - { - 0xC6, 0x53, 0x82, 0x51, 0x3F, 0x07, 0x46, 0x0D, - 0xA3, 0x98, 0x33, 0xCB, 0x66, 0x6C, 0x5E, 0xD8, - 0x2E, 0x61, 0xB9, 0xE9, 0x98, 0xF4, 0xB0, 0xC4, - 0x28, 0x7C, 0xEE, 0x56, 0xC3, 0xCC, 0x9B, 0xCD - }, - { - 0x89, 0x75, 0xB0, 0x57, 0x7F, 0xD3, 0x55, 0x66, - 0xD7, 0x50, 0xB3, 0x62, 0xB0, 0x89, 0x7A, 0x26, - 0xC3, 0x99, 0x13, 0x6D, 0xF0, 0x7B, 0xAB, 0xAB, - 0xBD, 0xE6, 0x20, 0x3F, 0xF2, 0x95, 0x4E, 0xD4 - }, - { - 0x21, 0xFE, 0x0C, 0xEB, 0x00, 0x52, 0xBE, 0x7F, - 0xB0, 0xF0, 0x04, 0x18, 0x7C, 0xAC, 0xD7, 0xDE, - 0x67, 0xFA, 0x6E, 0xB0, 0x93, 0x8D, 0x92, 0x76, - 0x77, 0xF2, 0x39, 0x8C, 0x13, 0x23, 0x17, 0xA8 - }, - { - 0x2E, 0xF7, 0x3F, 0x3C, 0x26, 0xF1, 0x2D, 0x93, - 0x88, 0x9F, 0x3C, 0x78, 0xB6, 0xA6, 0x6C, 0x1D, - 0x52, 0xB6, 0x49, 0xDC, 0x9E, 0x85, 0x6E, 0x2C, - 0x17, 0x2E, 0xA7, 0xC5, 0x8A, 0xC2, 0xB5, 0xE3 - }, - { - 0x38, 0x8A, 0x3C, 0xD5, 0x6D, 0x73, 0x86, 0x7A, - 0xBB, 0x5F, 0x84, 0x01, 0x49, 0x2B, 0x6E, 0x26, - 0x81, 0xEB, 0x69, 0x85, 0x1E, 0x76, 0x7F, 0xD8, - 0x42, 0x10, 0xA5, 0x60, 0x76, 0xFB, 0x3D, 0xD3 - }, - { - 0xAF, 0x53, 0x3E, 0x02, 0x2F, 0xC9, 0x43, 0x9E, - 0x4E, 0x3C, 0xB8, 0x38, 0xEC, 0xD1, 0x86, 0x92, - 0x23, 0x2A, 0xDF, 0x6F, 0xE9, 0x83, 0x95, 0x26, - 0xD3, 0xC3, 0xDD, 0x1B, 0x71, 0x91, 0x0B, 0x1A - }, - { - 0x75, 0x1C, 0x09, 0xD4, 0x1A, 0x93, 0x43, 0x88, - 0x2A, 0x81, 0xCD, 0x13, 0xEE, 0x40, 0x81, 0x8D, - 0x12, 0xEB, 0x44, 0xC6, 0xC7, 0xF4, 0x0D, 0xF1, - 0x6E, 0x4A, 0xEA, 0x8F, 0xAB, 0x91, 0x97, 0x2A - }, - { - 0x5B, 0x73, 0xDD, 0xB6, 0x8D, 0x9D, 0x2B, 0x0A, - 0xA2, 0x65, 0xA0, 0x79, 0x88, 0xD6, 0xB8, 0x8A, - 0xE9, 0xAA, 0xC5, 0x82, 0xAF, 0x83, 0x03, 0x2F, - 0x8A, 0x9B, 0x21, 0xA2, 0xE1, 0xB7, 0xBF, 0x18 - }, - { - 0x3D, 0xA2, 0x91, 0x26, 0xC7, 0xC5, 0xD7, 0xF4, - 0x3E, 0x64, 0x24, 0x2A, 0x79, 0xFE, 0xAA, 0x4E, - 0xF3, 0x45, 0x9C, 0xDE, 0xCC, 0xC8, 0x98, 0xED, - 0x59, 0xA9, 0x7F, 0x6E, 0xC9, 0x3B, 0x9D, 0xAB - }, - { - 0x56, 0x6D, 0xC9, 0x20, 0x29, 0x3D, 0xA5, 0xCB, - 0x4F, 0xE0, 0xAA, 0x8A, 0xBD, 0xA8, 0xBB, 0xF5, - 0x6F, 0x55, 0x23, 0x13, 0xBF, 0xF1, 0x90, 0x46, - 0x64, 0x1E, 0x36, 0x15, 0xC1, 0xE3, 0xED, 0x3F - }, - { - 0x41, 0x15, 0xBE, 0xA0, 0x2F, 0x73, 0xF9, 0x7F, - 0x62, 0x9E, 0x5C, 0x55, 0x90, 0x72, 0x0C, 0x01, - 0xE7, 0xE4, 0x49, 0xAE, 0x2A, 0x66, 0x97, 0xD4, - 0xD2, 0x78, 0x33, 0x21, 0x30, 0x36, 0x92, 0xF9 - }, - { - 0x4C, 0xE0, 0x8F, 0x47, 0x62, 0x46, 0x8A, 0x76, - 0x70, 0x01, 0x21, 0x64, 0x87, 0x8D, 0x68, 0x34, - 0x0C, 0x52, 0xA3, 0x5E, 0x66, 0xC1, 0x88, 0x4D, - 0x5C, 0x86, 0x48, 0x89, 0xAB, 0xC9, 0x66, 0x77 - }, - { - 0x81, 0xEA, 0x0B, 0x78, 0x04, 0x12, 0x4E, 0x0C, - 0x22, 0xEA, 0x5F, 0xC7, 0x11, 0x04, 0xA2, 0xAF, - 0xCB, 0x52, 0xA1, 0xFA, 0x81, 0x6F, 0x3E, 0xCB, - 0x7D, 0xCB, 0x5D, 0x9D, 0xEA, 0x17, 0x86, 0xD0 - }, - { - 0xFE, 0x36, 0x27, 0x33, 0xB0, 0x5F, 0x6B, 0xED, - 0xAF, 0x93, 0x79, 0xD7, 0xF7, 0x93, 0x6E, 0xDE, - 0x20, 0x9B, 0x1F, 0x83, 0x23, 0xC3, 0x92, 0x25, - 0x49, 0xD9, 0xE7, 0x36, 0x81, 0xB5, 0xDB, 0x7B - }, - { - 0xEF, 0xF3, 0x7D, 0x30, 0xDF, 0xD2, 0x03, 0x59, - 0xBE, 0x4E, 0x73, 0xFD, 0xF4, 0x0D, 0x27, 0x73, - 0x4B, 0x3D, 0xF9, 0x0A, 0x97, 0xA5, 0x5E, 0xD7, - 0x45, 0x29, 0x72, 0x94, 0xCA, 0x85, 0xD0, 0x9F - }, - { - 0x17, 0x2F, 0xFC, 0x67, 0x15, 0x3D, 0x12, 0xE0, - 0xCA, 0x76, 0xA8, 0xB6, 0xCD, 0x5D, 0x47, 0x31, - 0x88, 0x5B, 0x39, 0xCE, 0x0C, 0xAC, 0x93, 0xA8, - 0x97, 0x2A, 0x18, 0x00, 0x6C, 0x8B, 0x8B, 0xAF - }, - { - 0xC4, 0x79, 0x57, 0xF1, 0xCC, 0x88, 0xE8, 0x3E, - 0xF9, 0x44, 0x58, 0x39, 0x70, 0x9A, 0x48, 0x0A, - 0x03, 0x6B, 0xED, 0x5F, 0x88, 0xAC, 0x0F, 0xCC, - 0x8E, 0x1E, 0x70, 0x3F, 0xFA, 0xAC, 0x13, 0x2C - }, - { - 0x30, 0xF3, 0x54, 0x83, 0x70, 0xCF, 0xDC, 0xED, - 0xA5, 0xC3, 0x7B, 0x56, 0x9B, 0x61, 0x75, 0xE7, - 0x99, 0xEE, 0xF1, 0xA6, 0x2A, 0xAA, 0x94, 0x32, - 0x45, 0xAE, 0x76, 0x69, 0xC2, 0x27, 0xA7, 0xB5 - }, - { - 0xC9, 0x5D, 0xCB, 0x3C, 0xF1, 0xF2, 0x7D, 0x0E, - 0xEF, 0x2F, 0x25, 0xD2, 0x41, 0x38, 0x70, 0x90, - 0x4A, 0x87, 0x7C, 0x4A, 0x56, 0xC2, 0xDE, 0x1E, - 0x83, 0xE2, 0xBC, 0x2A, 0xE2, 0xE4, 0x68, 0x21 - }, - { - 0xD5, 0xD0, 0xB5, 0xD7, 0x05, 0x43, 0x4C, 0xD4, - 0x6B, 0x18, 0x57, 0x49, 0xF6, 0x6B, 0xFB, 0x58, - 0x36, 0xDC, 0xDF, 0x6E, 0xE5, 0x49, 0xA2, 0xB7, - 0xA4, 0xAE, 0xE7, 0xF5, 0x80, 0x07, 0xCA, 0xAF - }, - { - 0xBB, 0xC1, 0x24, 0xA7, 0x12, 0xF1, 0x5D, 0x07, - 0xC3, 0x00, 0xE0, 0x5B, 0x66, 0x83, 0x89, 0xA4, - 0x39, 0xC9, 0x17, 0x77, 0xF7, 0x21, 0xF8, 0x32, - 0x0C, 0x1C, 0x90, 0x78, 0x06, 0x6D, 0x2C, 0x7E - }, - { - 0xA4, 0x51, 0xB4, 0x8C, 0x35, 0xA6, 0xC7, 0x85, - 0x4C, 0xFA, 0xAE, 0x60, 0x26, 0x2E, 0x76, 0x99, - 0x08, 0x16, 0x38, 0x2A, 0xC0, 0x66, 0x7E, 0x5A, - 0x5C, 0x9E, 0x1B, 0x46, 0xC4, 0x34, 0x2D, 0xDF - }, - { - 0xB0, 0xD1, 0x50, 0xFB, 0x55, 0xE7, 0x78, 0xD0, - 0x11, 0x47, 0xF0, 0xB5, 0xD8, 0x9D, 0x99, 0xEC, - 0xB2, 0x0F, 0xF0, 0x7E, 0x5E, 0x67, 0x60, 0xD6, - 0xB6, 0x45, 0xEB, 0x5B, 0x65, 0x4C, 0x62, 0x2B - }, - { - 0x34, 0xF7, 0x37, 0xC0, 0xAB, 0x21, 0x99, 0x51, - 0xEE, 0xE8, 0x9A, 0x9F, 0x8D, 0xAC, 0x29, 0x9C, - 0x9D, 0x4C, 0x38, 0xF3, 0x3F, 0xA4, 0x94, 0xC5, - 0xC6, 0xEE, 0xFC, 0x92, 0xB6, 0xDB, 0x08, 0xBC - }, - { - 0x1A, 0x62, 0xCC, 0x3A, 0x00, 0x80, 0x0D, 0xCB, - 0xD9, 0x98, 0x91, 0x08, 0x0C, 0x1E, 0x09, 0x84, - 0x58, 0x19, 0x3A, 0x8C, 0xC9, 0xF9, 0x70, 0xEA, - 0x99, 0xFB, 0xEF, 0xF0, 0x03, 0x18, 0xC2, 0x89 - }, - { - 0xCF, 0xCE, 0x55, 0xEB, 0xAF, 0xC8, 0x40, 0xD7, - 0xAE, 0x48, 0x28, 0x1C, 0x7F, 0xD5, 0x7E, 0xC8, - 0xB4, 0x82, 0xD4, 0xB7, 0x04, 0x43, 0x74, 0x95, - 0x49, 0x5A, 0xC4, 0x14, 0xCF, 0x4A, 0x37, 0x4B - }, - { - 0x67, 0x46, 0xFA, 0xCF, 0x71, 0x14, 0x6D, 0x99, - 0x9D, 0xAB, 0xD0, 0x5D, 0x09, 0x3A, 0xE5, 0x86, - 0x64, 0x8D, 0x1E, 0xE2, 0x8E, 0x72, 0x61, 0x7B, - 0x99, 0xD0, 0xF0, 0x08, 0x6E, 0x1E, 0x45, 0xBF - }, - { - 0x57, 0x1C, 0xED, 0x28, 0x3B, 0x3F, 0x23, 0xB4, - 0xE7, 0x50, 0xBF, 0x12, 0xA2, 0xCA, 0xF1, 0x78, - 0x18, 0x47, 0xBD, 0x89, 0x0E, 0x43, 0x60, 0x3C, - 0xDC, 0x59, 0x76, 0x10, 0x2B, 0x7B, 0xB1, 0x1B - }, - { - 0xCF, 0xCB, 0x76, 0x5B, 0x04, 0x8E, 0x35, 0x02, - 0x2C, 0x5D, 0x08, 0x9D, 0x26, 0xE8, 0x5A, 0x36, - 0xB0, 0x05, 0xA2, 0xB8, 0x04, 0x93, 0xD0, 0x3A, - 0x14, 0x4E, 0x09, 0xF4, 0x09, 0xB6, 0xAF, 0xD1 - }, - { - 0x40, 0x50, 0xC7, 0xA2, 0x77, 0x05, 0xBB, 0x27, - 0xF4, 0x20, 0x89, 0xB2, 0x99, 0xF3, 0xCB, 0xE5, - 0x05, 0x4E, 0xAD, 0x68, 0x72, 0x7E, 0x8E, 0xF9, - 0x31, 0x8C, 0xE6, 0xF2, 0x5C, 0xD6, 0xF3, 0x1D - }, - { - 0x18, 0x40, 0x70, 0xBD, 0x5D, 0x26, 0x5F, 0xBD, - 0xC1, 0x42, 0xCD, 0x1C, 0x5C, 0xD0, 0xD7, 0xE4, - 0x14, 0xE7, 0x03, 0x69, 0xA2, 0x66, 0xD6, 0x27, - 0xC8, 0xFB, 0xA8, 0x4F, 0xA5, 0xE8, 0x4C, 0x34 - }, - { - 0x9E, 0xDD, 0xA9, 0xA4, 0x44, 0x39, 0x02, 0xA9, - 0x58, 0x8C, 0x0D, 0x0C, 0xCC, 0x62, 0xB9, 0x30, - 0x21, 0x84, 0x79, 0xA6, 0x84, 0x1E, 0x6F, 0xE7, - 0xD4, 0x30, 0x03, 0xF0, 0x4B, 0x1F, 0xD6, 0x43 - }, - { - 0xE4, 0x12, 0xFE, 0xEF, 0x79, 0x08, 0x32, 0x4A, - 0x6D, 0xA1, 0x84, 0x16, 0x29, 0xF3, 0x5D, 0x3D, - 0x35, 0x86, 0x42, 0x01, 0x93, 0x10, 0xEC, 0x57, - 0xC6, 0x14, 0x83, 0x6B, 0x63, 0xD3, 0x07, 0x63 - }, - { - 0x1A, 0x2B, 0x8E, 0xDF, 0xF3, 0xF9, 0xAC, 0xC1, - 0x55, 0x4F, 0xCB, 0xAE, 0x3C, 0xF1, 0xD6, 0x29, - 0x8C, 0x64, 0x62, 0xE2, 0x2E, 0x5E, 0xB0, 0x25, - 0x96, 0x84, 0xF8, 0x35, 0x01, 0x2B, 0xD1, 0x3F - }, - { - 0x28, 0x8C, 0x4A, 0xD9, 0xB9, 0x40, 0x97, 0x62, - 0xEA, 0x07, 0xC2, 0x4A, 0x41, 0xF0, 0x4F, 0x69, - 0xA7, 0xD7, 0x4B, 0xEE, 0x2D, 0x95, 0x43, 0x53, - 0x74, 0xBD, 0xE9, 0x46, 0xD7, 0x24, 0x1C, 0x7B - }, - { - 0x80, 0x56, 0x91, 0xBB, 0x28, 0x67, 0x48, 0xCF, - 0xB5, 0x91, 0xD3, 0xAE, 0xBE, 0x7E, 0x6F, 0x4E, - 0x4D, 0xC6, 0xE2, 0x80, 0x8C, 0x65, 0x14, 0x3C, - 0xC0, 0x04, 0xE4, 0xEB, 0x6F, 0xD0, 0x9D, 0x43 - }, - { - 0xD4, 0xAC, 0x8D, 0x3A, 0x0A, 0xFC, 0x6C, 0xFA, - 0x7B, 0x46, 0x0A, 0xE3, 0x00, 0x1B, 0xAE, 0xB3, - 0x6D, 0xAD, 0xB3, 0x7D, 0xA0, 0x7D, 0x2E, 0x8A, - 0xC9, 0x18, 0x22, 0xDF, 0x34, 0x8A, 0xED, 0x3D - }, - { - 0xC3, 0x76, 0x61, 0x70, 0x14, 0xD2, 0x01, 0x58, - 0xBC, 0xED, 0x3D, 0x3B, 0xA5, 0x52, 0xB6, 0xEC, - 0xCF, 0x84, 0xE6, 0x2A, 0xA3, 0xEB, 0x65, 0x0E, - 0x90, 0x02, 0x9C, 0x84, 0xD1, 0x3E, 0xEA, 0x69 - }, - { - 0xC4, 0x1F, 0x09, 0xF4, 0x3C, 0xEC, 0xAE, 0x72, - 0x93, 0xD6, 0x00, 0x7C, 0xA0, 0xA3, 0x57, 0x08, - 0x7D, 0x5A, 0xE5, 0x9B, 0xE5, 0x00, 0xC1, 0xCD, - 0x5B, 0x28, 0x9E, 0xE8, 0x10, 0xC7, 0xB0, 0x82 - }, - { - 0x03, 0xD1, 0xCE, 0xD1, 0xFB, 0xA5, 0xC3, 0x91, - 0x55, 0xC4, 0x4B, 0x77, 0x65, 0xCB, 0x76, 0x0C, - 0x78, 0x70, 0x8D, 0xCF, 0xC8, 0x0B, 0x0B, 0xD8, - 0xAD, 0xE3, 0xA5, 0x6D, 0xA8, 0x83, 0x0B, 0x29 - }, - { - 0x09, 0xBD, 0xE6, 0xF1, 0x52, 0x21, 0x8D, 0xC9, - 0x2C, 0x41, 0xD7, 0xF4, 0x53, 0x87, 0xE6, 0x3E, - 0x58, 0x69, 0xD8, 0x07, 0xEC, 0x70, 0xB8, 0x21, - 0x40, 0x5D, 0xBD, 0x88, 0x4B, 0x7F, 0xCF, 0x4B - }, - { - 0x71, 0xC9, 0x03, 0x6E, 0x18, 0x17, 0x9B, 0x90, - 0xB3, 0x7D, 0x39, 0xE9, 0xF0, 0x5E, 0xB8, 0x9C, - 0xC5, 0xFC, 0x34, 0x1F, 0xD7, 0xC4, 0x77, 0xD0, - 0xD7, 0x49, 0x32, 0x85, 0xFA, 0xCA, 0x08, 0xA4 - }, - { - 0x59, 0x16, 0x83, 0x3E, 0xBB, 0x05, 0xCD, 0x91, - 0x9C, 0xA7, 0xFE, 0x83, 0xB6, 0x92, 0xD3, 0x20, - 0x5B, 0xEF, 0x72, 0x39, 0x2B, 0x2C, 0xF6, 0xBB, - 0x0A, 0x6D, 0x43, 0xF9, 0x94, 0xF9, 0x5F, 0x11 - }, - { - 0xF6, 0x3A, 0xAB, 0x3E, 0xC6, 0x41, 0xB3, 0xB0, - 0x24, 0x96, 0x4C, 0x2B, 0x43, 0x7C, 0x04, 0xF6, - 0x04, 0x3C, 0x4C, 0x7E, 0x02, 0x79, 0x23, 0x99, - 0x95, 0x40, 0x19, 0x58, 0xF8, 0x6B, 0xBE, 0x54 - }, - { - 0xF1, 0x72, 0xB1, 0x80, 0xBF, 0xB0, 0x97, 0x40, - 0x49, 0x31, 0x20, 0xB6, 0x32, 0x6C, 0xBD, 0xC5, - 0x61, 0xE4, 0x77, 0xDE, 0xF9, 0xBB, 0xCF, 0xD2, - 0x8C, 0xC8, 0xC1, 0xC5, 0xE3, 0x37, 0x9A, 0x31 - }, - { - 0xCB, 0x9B, 0x89, 0xCC, 0x18, 0x38, 0x1D, 0xD9, - 0x14, 0x1A, 0xDE, 0x58, 0x86, 0x54, 0xD4, 0xE6, - 0xA2, 0x31, 0xD5, 0xBF, 0x49, 0xD4, 0xD5, 0x9A, - 0xC2, 0x7D, 0x86, 0x9C, 0xBE, 0x10, 0x0C, 0xF3 - }, - { - 0x7B, 0xD8, 0x81, 0x50, 0x46, 0xFD, 0xD8, 0x10, - 0xA9, 0x23, 0xE1, 0x98, 0x4A, 0xAE, 0xBD, 0xCD, - 0xF8, 0x4D, 0x87, 0xC8, 0x99, 0x2D, 0x68, 0xB5, - 0xEE, 0xB4, 0x60, 0xF9, 0x3E, 0xB3, 0xC8, 0xD7 - }, - { - 0x60, 0x7B, 0xE6, 0x68, 0x62, 0xFD, 0x08, 0xEE, - 0x5B, 0x19, 0xFA, 0xCA, 0xC0, 0x9D, 0xFD, 0xBC, - 0xD4, 0x0C, 0x31, 0x21, 0x01, 0xD6, 0x6E, 0x6E, - 0xBD, 0x2B, 0x84, 0x1F, 0x1B, 0x9A, 0x93, 0x25 - }, - { - 0x9F, 0xE0, 0x3B, 0xBE, 0x69, 0xAB, 0x18, 0x34, - 0xF5, 0x21, 0x9B, 0x0D, 0xA8, 0x8A, 0x08, 0xB3, - 0x0A, 0x66, 0xC5, 0x91, 0x3F, 0x01, 0x51, 0x96, - 0x3C, 0x36, 0x05, 0x60, 0xDB, 0x03, 0x87, 0xB3 - }, - { - 0x90, 0xA8, 0x35, 0x85, 0x71, 0x7B, 0x75, 0xF0, - 0xE9, 0xB7, 0x25, 0xE0, 0x55, 0xEE, 0xEE, 0xB9, - 0xE7, 0xA0, 0x28, 0xEA, 0x7E, 0x6C, 0xBC, 0x07, - 0xB2, 0x09, 0x17, 0xEC, 0x03, 0x63, 0xE3, 0x8C - }, - { - 0x33, 0x6E, 0xA0, 0x53, 0x0F, 0x4A, 0x74, 0x69, - 0x12, 0x6E, 0x02, 0x18, 0x58, 0x7E, 0xBB, 0xDE, - 0x33, 0x58, 0xA0, 0xB3, 0x1C, 0x29, 0xD2, 0x00, - 0xF7, 0xDC, 0x7E, 0xB1, 0x5C, 0x6A, 0xAD, 0xD8 - }, - { - 0xA7, 0x9E, 0x76, 0xDC, 0x0A, 0xBC, 0xA4, 0x39, - 0x6F, 0x07, 0x47, 0xCD, 0x7B, 0x74, 0x8D, 0xF9, - 0x13, 0x00, 0x76, 0x26, 0xB1, 0xD6, 0x59, 0xDA, - 0x0C, 0x1F, 0x78, 0xB9, 0x30, 0x3D, 0x01, 0xA3 - }, - { - 0x44, 0xE7, 0x8A, 0x77, 0x37, 0x56, 0xE0, 0x95, - 0x15, 0x19, 0x50, 0x4D, 0x70, 0x38, 0xD2, 0x8D, - 0x02, 0x13, 0xA3, 0x7E, 0x0C, 0xE3, 0x75, 0x37, - 0x17, 0x57, 0xBC, 0x99, 0x63, 0x11, 0xE3, 0xB8 - }, - { - 0x77, 0xAC, 0x01, 0x2A, 0x3F, 0x75, 0x4D, 0xCF, - 0xEA, 0xB5, 0xEB, 0x99, 0x6B, 0xE9, 0xCD, 0x2D, - 0x1F, 0x96, 0x11, 0x1B, 0x6E, 0x49, 0xF3, 0x99, - 0x4D, 0xF1, 0x81, 0xF2, 0x85, 0x69, 0xD8, 0x25 - }, - { - 0xCE, 0x5A, 0x10, 0xDB, 0x6F, 0xCC, 0xDA, 0xF1, - 0x40, 0xAA, 0xA4, 0xDE, 0xD6, 0x25, 0x0A, 0x9C, - 0x06, 0xE9, 0x22, 0x2B, 0xC9, 0xF9, 0xF3, 0x65, - 0x8A, 0x4A, 0xFF, 0x93, 0x5F, 0x2B, 0x9F, 0x3A - }, - { - 0xEC, 0xC2, 0x03, 0xA7, 0xFE, 0x2B, 0xE4, 0xAB, - 0xD5, 0x5B, 0xB5, 0x3E, 0x6E, 0x67, 0x35, 0x72, - 0xE0, 0x07, 0x8D, 0xA8, 0xCD, 0x37, 0x5E, 0xF4, - 0x30, 0xCC, 0x97, 0xF9, 0xF8, 0x00, 0x83, 0xAF - }, - { - 0x14, 0xA5, 0x18, 0x6D, 0xE9, 0xD7, 0xA1, 0x8B, - 0x04, 0x12, 0xB8, 0x56, 0x3E, 0x51, 0xCC, 0x54, - 0x33, 0x84, 0x0B, 0x4A, 0x12, 0x9A, 0x8F, 0xF9, - 0x63, 0xB3, 0x3A, 0x3C, 0x4A, 0xFE, 0x8E, 0xBB - }, - { - 0x13, 0xF8, 0xEF, 0x95, 0xCB, 0x86, 0xE6, 0xA6, - 0x38, 0x93, 0x1C, 0x8E, 0x10, 0x76, 0x73, 0xEB, - 0x76, 0xBA, 0x10, 0xD7, 0xC2, 0xCD, 0x70, 0xB9, - 0xD9, 0x92, 0x0B, 0xBE, 0xED, 0x92, 0x94, 0x09 - }, - { - 0x0B, 0x33, 0x8F, 0x4E, 0xE1, 0x2F, 0x2D, 0xFC, - 0xB7, 0x87, 0x13, 0x37, 0x79, 0x41, 0xE0, 0xB0, - 0x63, 0x21, 0x52, 0x58, 0x1D, 0x13, 0x32, 0x51, - 0x6E, 0x4A, 0x2C, 0xAB, 0x19, 0x42, 0xCC, 0xA4 - }, - { - 0xEA, 0xAB, 0x0E, 0xC3, 0x7B, 0x3B, 0x8A, 0xB7, - 0x96, 0xE9, 0xF5, 0x72, 0x38, 0xDE, 0x14, 0xA2, - 0x64, 0xA0, 0x76, 0xF3, 0x88, 0x7D, 0x86, 0xE2, - 0x9B, 0xB5, 0x90, 0x6D, 0xB5, 0xA0, 0x0E, 0x02 - }, - { - 0x23, 0xCB, 0x68, 0xB8, 0xC0, 0xE6, 0xDC, 0x26, - 0xDC, 0x27, 0x76, 0x6D, 0xDC, 0x0A, 0x13, 0xA9, - 0x94, 0x38, 0xFD, 0x55, 0x61, 0x7A, 0xA4, 0x09, - 0x5D, 0x8F, 0x96, 0x97, 0x20, 0xC8, 0x72, 0xDF - }, - { - 0x09, 0x1D, 0x8E, 0xE3, 0x0D, 0x6F, 0x29, 0x68, - 0xD4, 0x6B, 0x68, 0x7D, 0xD6, 0x52, 0x92, 0x66, - 0x57, 0x42, 0xDE, 0x0B, 0xB8, 0x3D, 0xCC, 0x00, - 0x04, 0xC7, 0x2C, 0xE1, 0x00, 0x07, 0xA5, 0x49 - }, - { - 0x7F, 0x50, 0x7A, 0xBC, 0x6D, 0x19, 0xBA, 0x00, - 0xC0, 0x65, 0xA8, 0x76, 0xEC, 0x56, 0x57, 0x86, - 0x88, 0x82, 0xD1, 0x8A, 0x22, 0x1B, 0xC4, 0x6C, - 0x7A, 0x69, 0x12, 0x54, 0x1F, 0x5B, 0xC7, 0xBA - }, - { - 0xA0, 0x60, 0x7C, 0x24, 0xE1, 0x4E, 0x8C, 0x22, - 0x3D, 0xB0, 0xD7, 0x0B, 0x4D, 0x30, 0xEE, 0x88, - 0x01, 0x4D, 0x60, 0x3F, 0x43, 0x7E, 0x9E, 0x02, - 0xAA, 0x7D, 0xAF, 0xA3, 0xCD, 0xFB, 0xAD, 0x94 - }, - { - 0xDD, 0xBF, 0xEA, 0x75, 0xCC, 0x46, 0x78, 0x82, - 0xEB, 0x34, 0x83, 0xCE, 0x5E, 0x2E, 0x75, 0x6A, - 0x4F, 0x47, 0x01, 0xB7, 0x6B, 0x44, 0x55, 0x19, - 0xE8, 0x9F, 0x22, 0xD6, 0x0F, 0xA8, 0x6E, 0x06 - }, - { - 0x0C, 0x31, 0x1F, 0x38, 0xC3, 0x5A, 0x4F, 0xB9, - 0x0D, 0x65, 0x1C, 0x28, 0x9D, 0x48, 0x68, 0x56, - 0xCD, 0x14, 0x13, 0xDF, 0x9B, 0x06, 0x77, 0xF5, - 0x3E, 0xCE, 0x2C, 0xD9, 0xE4, 0x77, 0xC6, 0x0A - }, - { - 0x46, 0xA7, 0x3A, 0x8D, 0xD3, 0xE7, 0x0F, 0x59, - 0xD3, 0x94, 0x2C, 0x01, 0xDF, 0x59, 0x9D, 0xEF, - 0x78, 0x3C, 0x9D, 0xA8, 0x2F, 0xD8, 0x32, 0x22, - 0xCD, 0x66, 0x2B, 0x53, 0xDC, 0xE7, 0xDB, 0xDF - }, - { - 0xAD, 0x03, 0x8F, 0xF9, 0xB1, 0x4D, 0xE8, 0x4A, - 0x80, 0x1E, 0x4E, 0x62, 0x1C, 0xE5, 0xDF, 0x02, - 0x9D, 0xD9, 0x35, 0x20, 0xD0, 0xC2, 0xFA, 0x38, - 0xBF, 0xF1, 0x76, 0xA8, 0xB1, 0xD1, 0x69, 0x8C - }, - { - 0xAB, 0x70, 0xC5, 0xDF, 0xBD, 0x1E, 0xA8, 0x17, - 0xFE, 0xD0, 0xCD, 0x06, 0x72, 0x93, 0xAB, 0xF3, - 0x19, 0xE5, 0xD7, 0x90, 0x1C, 0x21, 0x41, 0xD5, - 0xD9, 0x9B, 0x23, 0xF0, 0x3A, 0x38, 0xE7, 0x48 - }, - { - 0x1F, 0xFF, 0xDA, 0x67, 0x93, 0x2B, 0x73, 0xC8, - 0xEC, 0xAF, 0x00, 0x9A, 0x34, 0x91, 0xA0, 0x26, - 0x95, 0x3B, 0xAB, 0xFE, 0x1F, 0x66, 0x3B, 0x06, - 0x97, 0xC3, 0xC4, 0xAE, 0x8B, 0x2E, 0x7D, 0xCB - }, - { - 0xB0, 0xD2, 0xCC, 0x19, 0x47, 0x2D, 0xD5, 0x7F, - 0x2B, 0x17, 0xEF, 0xC0, 0x3C, 0x8D, 0x58, 0xC2, - 0x28, 0x3D, 0xBB, 0x19, 0xDA, 0x57, 0x2F, 0x77, - 0x55, 0x85, 0x5A, 0xA9, 0x79, 0x43, 0x17, 0xA0 - }, - { - 0xA0, 0xD1, 0x9A, 0x6E, 0xE3, 0x39, 0x79, 0xC3, - 0x25, 0x51, 0x0E, 0x27, 0x66, 0x22, 0xDF, 0x41, - 0xF7, 0x15, 0x83, 0xD0, 0x75, 0x01, 0xB8, 0x70, - 0x71, 0x12, 0x9A, 0x0A, 0xD9, 0x47, 0x32, 0xA5 - }, - { - 0x72, 0x46, 0x42, 0xA7, 0x03, 0x2D, 0x10, 0x62, - 0xB8, 0x9E, 0x52, 0xBE, 0xA3, 0x4B, 0x75, 0xDF, - 0x7D, 0x8F, 0xE7, 0x72, 0xD9, 0xFE, 0x3C, 0x93, - 0xDD, 0xF3, 0xC4, 0x54, 0x5A, 0xB5, 0xA9, 0x9B - }, - { - 0xAD, 0xE5, 0xEA, 0xA7, 0xE6, 0x1F, 0x67, 0x2D, - 0x58, 0x7E, 0xA0, 0x3D, 0xAE, 0x7D, 0x7B, 0x55, - 0x22, 0x9C, 0x01, 0xD0, 0x6B, 0xC0, 0xA5, 0x70, - 0x14, 0x36, 0xCB, 0xD1, 0x83, 0x66, 0xA6, 0x26 - }, - { - 0x01, 0x3B, 0x31, 0xEB, 0xD2, 0x28, 0xFC, 0xDD, - 0xA5, 0x1F, 0xAB, 0xB0, 0x3B, 0xB0, 0x2D, 0x60, - 0xAC, 0x20, 0xCA, 0x21, 0x5A, 0xAF, 0xA8, 0x3B, - 0xDD, 0x85, 0x5E, 0x37, 0x55, 0xA3, 0x5F, 0x0B - }, - { - 0x33, 0x2E, 0xD4, 0x0B, 0xB1, 0x0D, 0xDE, 0x3C, - 0x95, 0x4A, 0x75, 0xD7, 0xB8, 0x99, 0x9D, 0x4B, - 0x26, 0xA1, 0xC0, 0x63, 0xC1, 0xDC, 0x6E, 0x32, - 0xC1, 0xD9, 0x1B, 0xAB, 0x7B, 0xBB, 0x7D, 0x16 - }, - { - 0xC7, 0xA1, 0x97, 0xB3, 0xA0, 0x5B, 0x56, 0x6B, - 0xCC, 0x9F, 0xAC, 0xD2, 0x0E, 0x44, 0x1D, 0x6F, - 0x6C, 0x28, 0x60, 0xAC, 0x96, 0x51, 0xCD, 0x51, - 0xD6, 0xB9, 0xD2, 0xCD, 0xEE, 0xEA, 0x03, 0x90 - }, - { - 0xBD, 0x9C, 0xF6, 0x4E, 0xA8, 0x95, 0x3C, 0x03, - 0x71, 0x08, 0xE6, 0xF6, 0x54, 0x91, 0x4F, 0x39, - 0x58, 0xB6, 0x8E, 0x29, 0xC1, 0x67, 0x00, 0xDC, - 0x18, 0x4D, 0x94, 0xA2, 0x17, 0x08, 0xFF, 0x60 - }, - { - 0x88, 0x35, 0xB0, 0xAC, 0x02, 0x11, 0x51, 0xDF, - 0x71, 0x64, 0x74, 0xCE, 0x27, 0xCE, 0x4D, 0x3C, - 0x15, 0xF0, 0xB2, 0xDA, 0xB4, 0x80, 0x03, 0xCF, - 0x3F, 0x3E, 0xFD, 0x09, 0x45, 0x10, 0x6B, 0x9A - }, - { - 0x3B, 0xFE, 0xFA, 0x33, 0x01, 0xAA, 0x55, 0xC0, - 0x80, 0x19, 0x0C, 0xFF, 0xDA, 0x8E, 0xAE, 0x51, - 0xD9, 0xAF, 0x48, 0x8B, 0x4C, 0x1F, 0x24, 0xC3, - 0xD9, 0xA7, 0x52, 0x42, 0xFD, 0x8E, 0xA0, 0x1D - }, - { - 0x08, 0x28, 0x4D, 0x14, 0x99, 0x3C, 0xD4, 0x7D, - 0x53, 0xEB, 0xAE, 0xCF, 0x0D, 0xF0, 0x47, 0x8C, - 0xC1, 0x82, 0xC8, 0x9C, 0x00, 0xE1, 0x85, 0x9C, - 0x84, 0x85, 0x16, 0x86, 0xDD, 0xF2, 0xC1, 0xB7 - }, - { - 0x1E, 0xD7, 0xEF, 0x9F, 0x04, 0xC2, 0xAC, 0x8D, - 0xB6, 0xA8, 0x64, 0xDB, 0x13, 0x10, 0x87, 0xF2, - 0x70, 0x65, 0x09, 0x8E, 0x69, 0xC3, 0xFE, 0x78, - 0x71, 0x8D, 0x9B, 0x94, 0x7F, 0x4A, 0x39, 0xD0 - }, - { - 0xC1, 0x61, 0xF2, 0xDC, 0xD5, 0x7E, 0x9C, 0x14, - 0x39, 0xB3, 0x1A, 0x9D, 0xD4, 0x3D, 0x8F, 0x3D, - 0x7D, 0xD8, 0xF0, 0xEB, 0x7C, 0xFA, 0xC6, 0xFB, - 0x25, 0xA0, 0xF2, 0x8E, 0x30, 0x6F, 0x06, 0x61 - }, - { - 0xC0, 0x19, 0x69, 0xAD, 0x34, 0xC5, 0x2C, 0xAF, - 0x3D, 0xC4, 0xD8, 0x0D, 0x19, 0x73, 0x5C, 0x29, - 0x73, 0x1A, 0xC6, 0xE7, 0xA9, 0x20, 0x85, 0xAB, - 0x92, 0x50, 0xC4, 0x8D, 0xEA, 0x48, 0xA3, 0xFC - }, - { - 0x17, 0x20, 0xB3, 0x65, 0x56, 0x19, 0xD2, 0xA5, - 0x2B, 0x35, 0x21, 0xAE, 0x0E, 0x49, 0xE3, 0x45, - 0xCB, 0x33, 0x89, 0xEB, 0xD6, 0x20, 0x8A, 0xCA, - 0xF9, 0xF1, 0x3F, 0xDA, 0xCC, 0xA8, 0xBE, 0x49 - }, - { - 0x75, 0x62, 0x88, 0x36, 0x1C, 0x83, 0xE2, 0x4C, - 0x61, 0x7C, 0xF9, 0x5C, 0x90, 0x5B, 0x22, 0xD0, - 0x17, 0xCD, 0xC8, 0x6F, 0x0B, 0xF1, 0xD6, 0x58, - 0xF4, 0x75, 0x6C, 0x73, 0x79, 0x87, 0x3B, 0x7F - }, - { - 0xE7, 0xD0, 0xED, 0xA3, 0x45, 0x26, 0x93, 0xB7, - 0x52, 0xAB, 0xCD, 0xA1, 0xB5, 0x5E, 0x27, 0x6F, - 0x82, 0x69, 0x8F, 0x5F, 0x16, 0x05, 0x40, 0x3E, - 0xFF, 0x83, 0x0B, 0xEA, 0x00, 0x71, 0xA3, 0x94 - }, - { - 0x2C, 0x82, 0xEC, 0xAA, 0x6B, 0x84, 0x80, 0x3E, - 0x04, 0x4A, 0xF6, 0x31, 0x18, 0xAF, 0xE5, 0x44, - 0x68, 0x7C, 0xB6, 0xE6, 0xC7, 0xDF, 0x49, 0xED, - 0x76, 0x2D, 0xFD, 0x7C, 0x86, 0x93, 0xA1, 0xBC - }, - { - 0x61, 0x36, 0xCB, 0xF4, 0xB4, 0x41, 0x05, 0x6F, - 0xA1, 0xE2, 0x72, 0x24, 0x98, 0x12, 0x5D, 0x6D, - 0xED, 0x45, 0xE1, 0x7B, 0x52, 0x14, 0x39, 0x59, - 0xC7, 0xF4, 0xD4, 0xE3, 0x95, 0x21, 0x8A, 0xC2 - }, - { - 0x72, 0x1D, 0x32, 0x45, 0xAA, 0xFE, 0xF2, 0x7F, - 0x6A, 0x62, 0x4F, 0x47, 0x95, 0x4B, 0x6C, 0x25, - 0x50, 0x79, 0x52, 0x6F, 0xFA, 0x25, 0xE9, 0xFF, - 0x77, 0xE5, 0xDC, 0xFF, 0x47, 0x3B, 0x15, 0x97 - }, - { - 0x9D, 0xD2, 0xFB, 0xD8, 0xCE, 0xF1, 0x6C, 0x35, - 0x3C, 0x0A, 0xC2, 0x11, 0x91, 0xD5, 0x09, 0xEB, - 0x28, 0xDD, 0x9E, 0x3E, 0x0D, 0x8C, 0xEA, 0x5D, - 0x26, 0xCA, 0x83, 0x93, 0x93, 0x85, 0x1C, 0x3A - }, - { - 0xB2, 0x39, 0x4C, 0xEA, 0xCD, 0xEB, 0xF2, 0x1B, - 0xF9, 0xDF, 0x2C, 0xED, 0x98, 0xE5, 0x8F, 0x1C, - 0x3A, 0x4B, 0xBB, 0xFF, 0x66, 0x0D, 0xD9, 0x00, - 0xF6, 0x22, 0x02, 0xD6, 0x78, 0x5C, 0xC4, 0x6E - }, - { - 0x57, 0x08, 0x9F, 0x22, 0x27, 0x49, 0xAD, 0x78, - 0x71, 0x76, 0x5F, 0x06, 0x2B, 0x11, 0x4F, 0x43, - 0xBA, 0x20, 0xEC, 0x56, 0x42, 0x2A, 0x8B, 0x1E, - 0x3F, 0x87, 0x19, 0x2C, 0x0E, 0xA7, 0x18, 0xC6 - }, - { - 0xE4, 0x9A, 0x94, 0x59, 0x96, 0x1C, 0xD3, 0x3C, - 0xDF, 0x4A, 0xAE, 0x1B, 0x10, 0x78, 0xA5, 0xDE, - 0xA7, 0xC0, 0x40, 0xE0, 0xFE, 0xA3, 0x40, 0xC9, - 0x3A, 0x72, 0x48, 0x72, 0xFC, 0x4A, 0xF8, 0x06 - }, - { - 0xED, 0xE6, 0x7F, 0x72, 0x0E, 0xFF, 0xD2, 0xCA, - 0x9C, 0x88, 0x99, 0x41, 0x52, 0xD0, 0x20, 0x1D, - 0xEE, 0x6B, 0x0A, 0x2D, 0x2C, 0x07, 0x7A, 0xCA, - 0x6D, 0xAE, 0x29, 0xF7, 0x3F, 0x8B, 0x63, 0x09 - }, - { - 0xE0, 0xF4, 0x34, 0xBF, 0x22, 0xE3, 0x08, 0x80, - 0x39, 0xC2, 0x1F, 0x71, 0x9F, 0xFC, 0x67, 0xF0, - 0xF2, 0xCB, 0x5E, 0x98, 0xA7, 0xA0, 0x19, 0x4C, - 0x76, 0xE9, 0x6B, 0xF4, 0xE8, 0xE1, 0x7E, 0x61 - }, - { - 0x27, 0x7C, 0x04, 0xE2, 0x85, 0x34, 0x84, 0xA4, - 0xEB, 0xA9, 0x10, 0xAD, 0x33, 0x6D, 0x01, 0xB4, - 0x77, 0xB6, 0x7C, 0xC2, 0x00, 0xC5, 0x9F, 0x3C, - 0x8D, 0x77, 0xEE, 0xF8, 0x49, 0x4F, 0x29, 0xCD - }, - { - 0x15, 0x6D, 0x57, 0x47, 0xD0, 0xC9, 0x9C, 0x7F, - 0x27, 0x09, 0x7D, 0x7B, 0x7E, 0x00, 0x2B, 0x2E, - 0x18, 0x5C, 0xB7, 0x2D, 0x8D, 0xD7, 0xEB, 0x42, - 0x4A, 0x03, 0x21, 0x52, 0x81, 0x61, 0x21, 0x9F - }, - { - 0x20, 0xDD, 0xD1, 0xED, 0x9B, 0x1C, 0xA8, 0x03, - 0x94, 0x6D, 0x64, 0xA8, 0x3A, 0xE4, 0x65, 0x9D, - 0xA6, 0x7F, 0xBA, 0x7A, 0x1A, 0x3E, 0xDD, 0xB1, - 0xE1, 0x03, 0xC0, 0xF5, 0xE0, 0x3E, 0x3A, 0x2C - }, - { - 0xF0, 0xAF, 0x60, 0x4D, 0x3D, 0xAB, 0xBF, 0x9A, - 0x0F, 0x2A, 0x7D, 0x3D, 0xDA, 0x6B, 0xD3, 0x8B, - 0xBA, 0x72, 0xC6, 0xD0, 0x9B, 0xE4, 0x94, 0xFC, - 0xEF, 0x71, 0x3F, 0xF1, 0x01, 0x89, 0xB6, 0xE6 - }, - { - 0x98, 0x02, 0xBB, 0x87, 0xDE, 0xF4, 0xCC, 0x10, - 0xC4, 0xA5, 0xFD, 0x49, 0xAA, 0x58, 0xDF, 0xE2, - 0xF3, 0xFD, 0xDB, 0x46, 0xB4, 0x70, 0x88, 0x14, - 0xEA, 0xD8, 0x1D, 0x23, 0xBA, 0x95, 0x13, 0x9B - }, - { - 0x4F, 0x8C, 0xE1, 0xE5, 0x1D, 0x2F, 0xE7, 0xF2, - 0x40, 0x43, 0xA9, 0x04, 0xD8, 0x98, 0xEB, 0xFC, - 0x91, 0x97, 0x54, 0x18, 0x75, 0x34, 0x13, 0xAA, - 0x09, 0x9B, 0x79, 0x5E, 0xCB, 0x35, 0xCE, 0xDB - }, - { - 0xBD, 0xDC, 0x65, 0x14, 0xD7, 0xEE, 0x6A, 0xCE, - 0x0A, 0x4A, 0xC1, 0xD0, 0xE0, 0x68, 0x11, 0x22, - 0x88, 0xCB, 0xCF, 0x56, 0x04, 0x54, 0x64, 0x27, - 0x05, 0x63, 0x01, 0x77, 0xCB, 0xA6, 0x08, 0xBD - }, - { - 0xD6, 0x35, 0x99, 0x4F, 0x62, 0x91, 0x51, 0x7B, - 0x02, 0x81, 0xFF, 0xDD, 0x49, 0x6A, 0xFA, 0x86, - 0x27, 0x12, 0xE5, 0xB3, 0xC4, 0xE5, 0x2E, 0x4C, - 0xD5, 0xFD, 0xAE, 0x8C, 0x0E, 0x72, 0xFB, 0x08 - }, - { - 0x87, 0x8D, 0x9C, 0xA6, 0x00, 0xCF, 0x87, 0xE7, - 0x69, 0xCC, 0x30, 0x5C, 0x1B, 0x35, 0x25, 0x51, - 0x86, 0x61, 0x5A, 0x73, 0xA0, 0xDA, 0x61, 0x3B, - 0x5F, 0x1C, 0x98, 0xDB, 0xF8, 0x12, 0x83, 0xEA - }, - { - 0xA6, 0x4E, 0xBE, 0x5D, 0xC1, 0x85, 0xDE, 0x9F, - 0xDD, 0xE7, 0x60, 0x7B, 0x69, 0x98, 0x70, 0x2E, - 0xB2, 0x34, 0x56, 0x18, 0x49, 0x57, 0x30, 0x7D, - 0x2F, 0xA7, 0x2E, 0x87, 0xA4, 0x77, 0x02, 0xD6 - }, - { - 0xCE, 0x50, 0xEA, 0xB7, 0xB5, 0xEB, 0x52, 0xBD, - 0xC9, 0xAD, 0x8E, 0x5A, 0x48, 0x0A, 0xB7, 0x80, - 0xCA, 0x93, 0x20, 0xE4, 0x43, 0x60, 0xB1, 0xFE, - 0x37, 0xE0, 0x3F, 0x2F, 0x7A, 0xD7, 0xDE, 0x01 - }, - { - 0xEE, 0xDD, 0xB7, 0xC0, 0xDB, 0x6E, 0x30, 0xAB, - 0xE6, 0x6D, 0x79, 0xE3, 0x27, 0x51, 0x1E, 0x61, - 0xFC, 0xEB, 0xBC, 0x29, 0xF1, 0x59, 0xB4, 0x0A, - 0x86, 0xB0, 0x46, 0xEC, 0xF0, 0x51, 0x38, 0x23 - }, - { - 0x78, 0x7F, 0xC9, 0x34, 0x40, 0xC1, 0xEC, 0x96, - 0xB5, 0xAD, 0x01, 0xC1, 0x6C, 0xF7, 0x79, 0x16, - 0xA1, 0x40, 0x5F, 0x94, 0x26, 0x35, 0x6E, 0xC9, - 0x21, 0xD8, 0xDF, 0xF3, 0xEA, 0x63, 0xB7, 0xE0 - }, - { - 0x7F, 0x0D, 0x5E, 0xAB, 0x47, 0xEE, 0xFD, 0xA6, - 0x96, 0xC0, 0xBF, 0x0F, 0xBF, 0x86, 0xAB, 0x21, - 0x6F, 0xCE, 0x46, 0x1E, 0x93, 0x03, 0xAB, 0xA6, - 0xAC, 0x37, 0x41, 0x20, 0xE8, 0x90, 0xE8, 0xDF - }, - { - 0xB6, 0x80, 0x04, 0xB4, 0x2F, 0x14, 0xAD, 0x02, - 0x9F, 0x4C, 0x2E, 0x03, 0xB1, 0xD5, 0xEB, 0x76, - 0xD5, 0x71, 0x60, 0xE2, 0x64, 0x76, 0xD2, 0x11, - 0x31, 0xBE, 0xF2, 0x0A, 0xDA, 0x7D, 0x27, 0xF4 - }, - { - 0xB0, 0xC4, 0xEB, 0x18, 0xAE, 0x25, 0x0B, 0x51, - 0xA4, 0x13, 0x82, 0xEA, 0xD9, 0x2D, 0x0D, 0xC7, - 0x45, 0x5F, 0x93, 0x79, 0xFC, 0x98, 0x84, 0x42, - 0x8E, 0x47, 0x70, 0x60, 0x8D, 0xB0, 0xFA, 0xEC - }, - { - 0xF9, 0x2B, 0x7A, 0x87, 0x0C, 0x05, 0x9F, 0x4D, - 0x46, 0x46, 0x4C, 0x82, 0x4E, 0xC9, 0x63, 0x55, - 0x14, 0x0B, 0xDC, 0xE6, 0x81, 0x32, 0x2C, 0xC3, - 0xA9, 0x92, 0xFF, 0x10, 0x3E, 0x3F, 0xEA, 0x52 - }, - { - 0x53, 0x64, 0x31, 0x26, 0x14, 0x81, 0x33, 0x98, - 0xCC, 0x52, 0x5D, 0x4C, 0x4E, 0x14, 0x6E, 0xDE, - 0xB3, 0x71, 0x26, 0x5F, 0xBA, 0x19, 0x13, 0x3A, - 0x2C, 0x3D, 0x21, 0x59, 0x29, 0x8A, 0x17, 0x42 - }, - { - 0xF6, 0x62, 0x0E, 0x68, 0xD3, 0x7F, 0xB2, 0xAF, - 0x50, 0x00, 0xFC, 0x28, 0xE2, 0x3B, 0x83, 0x22, - 0x97, 0xEC, 0xD8, 0xBC, 0xE9, 0x9E, 0x8B, 0xE4, - 0xD0, 0x4E, 0x85, 0x30, 0x9E, 0x3D, 0x33, 0x74 - }, - { - 0x53, 0x16, 0xA2, 0x79, 0x69, 0xD7, 0xFE, 0x04, - 0xFF, 0x27, 0xB2, 0x83, 0x96, 0x1B, 0xFF, 0xC3, - 0xBF, 0x5D, 0xFB, 0x32, 0xFB, 0x6A, 0x89, 0xD1, - 0x01, 0xC6, 0xC3, 0xB1, 0x93, 0x7C, 0x28, 0x71 - }, - { - 0x81, 0xD1, 0x66, 0x4F, 0xDF, 0x3C, 0xB3, 0x3C, - 0x24, 0xEE, 0xBA, 0xC0, 0xBD, 0x64, 0x24, 0x4B, - 0x77, 0xC4, 0xAB, 0xEA, 0x90, 0xBB, 0xE8, 0xB5, - 0xEE, 0x0B, 0x2A, 0xAF, 0xCF, 0x2D, 0x6A, 0x53 - }, - { - 0x34, 0x57, 0x82, 0xF2, 0x95, 0xB0, 0x88, 0x03, - 0x52, 0xE9, 0x24, 0xA0, 0x46, 0x7B, 0x5F, 0xBC, - 0x3E, 0x8F, 0x3B, 0xFB, 0xC3, 0xC7, 0xE4, 0x8B, - 0x67, 0x09, 0x1F, 0xB5, 0xE8, 0x0A, 0x94, 0x42 - }, - { - 0x79, 0x41, 0x11, 0xEA, 0x6C, 0xD6, 0x5E, 0x31, - 0x1F, 0x74, 0xEE, 0x41, 0xD4, 0x76, 0xCB, 0x63, - 0x2C, 0xE1, 0xE4, 0xB0, 0x51, 0xDC, 0x1D, 0x9E, - 0x9D, 0x06, 0x1A, 0x19, 0xE1, 0xD0, 0xBB, 0x49 - }, - { - 0x2A, 0x85, 0xDA, 0xF6, 0x13, 0x88, 0x16, 0xB9, - 0x9B, 0xF8, 0xD0, 0x8B, 0xA2, 0x11, 0x4B, 0x7A, - 0xB0, 0x79, 0x75, 0xA7, 0x84, 0x20, 0xC1, 0xA3, - 0xB0, 0x6A, 0x77, 0x7C, 0x22, 0xDD, 0x8B, 0xCB - }, - { - 0x89, 0xB0, 0xD5, 0xF2, 0x89, 0xEC, 0x16, 0x40, - 0x1A, 0x06, 0x9A, 0x96, 0x0D, 0x0B, 0x09, 0x3E, - 0x62, 0x5D, 0xA3, 0xCF, 0x41, 0xEE, 0x29, 0xB5, - 0x9B, 0x93, 0x0C, 0x58, 0x20, 0x14, 0x54, 0x55 - }, - { - 0xD0, 0xFD, 0xCB, 0x54, 0x39, 0x43, 0xFC, 0x27, - 0xD2, 0x08, 0x64, 0xF5, 0x21, 0x81, 0x47, 0x1B, - 0x94, 0x2C, 0xC7, 0x7C, 0xA6, 0x75, 0xBC, 0xB3, - 0x0D, 0xF3, 0x1D, 0x35, 0x8E, 0xF7, 0xB1, 0xEB - }, - { - 0xB1, 0x7E, 0xA8, 0xD7, 0x70, 0x63, 0xC7, 0x09, - 0xD4, 0xDC, 0x6B, 0x87, 0x94, 0x13, 0xC3, 0x43, - 0xE3, 0x79, 0x0E, 0x9E, 0x62, 0xCA, 0x85, 0xB7, - 0x90, 0x0B, 0x08, 0x6F, 0x6B, 0x75, 0xC6, 0x72 - }, - { - 0xE7, 0x1A, 0x3E, 0x2C, 0x27, 0x4D, 0xB8, 0x42, - 0xD9, 0x21, 0x14, 0xF2, 0x17, 0xE2, 0xC0, 0xEA, - 0xC8, 0xB4, 0x50, 0x93, 0xFD, 0xFD, 0x9D, 0xF4, - 0xCA, 0x71, 0x62, 0x39, 0x48, 0x62, 0xD5, 0x01 - }, - { - 0xC0, 0x47, 0x67, 0x59, 0xAB, 0x7A, 0xA3, 0x33, - 0x23, 0x4F, 0x6B, 0x44, 0xF5, 0xFD, 0x85, 0x83, - 0x90, 0xEC, 0x23, 0x69, 0x4C, 0x62, 0x2C, 0xB9, - 0x86, 0xE7, 0x69, 0xC7, 0x8E, 0xDD, 0x73, 0x3E - }, - { - 0x9A, 0xB8, 0xEA, 0xBB, 0x14, 0x16, 0x43, 0x4D, - 0x85, 0x39, 0x13, 0x41, 0xD5, 0x69, 0x93, 0xC5, - 0x54, 0x58, 0x16, 0x7D, 0x44, 0x18, 0xB1, 0x9A, - 0x0F, 0x2A, 0xD8, 0xB7, 0x9A, 0x83, 0xA7, 0x5B - }, - { - 0x79, 0x92, 0xD0, 0xBB, 0xB1, 0x5E, 0x23, 0x82, - 0x6F, 0x44, 0x3E, 0x00, 0x50, 0x5D, 0x68, 0xD3, - 0xED, 0x73, 0x72, 0x99, 0x5A, 0x5C, 0x3E, 0x49, - 0x86, 0x54, 0x10, 0x2F, 0xBC, 0xD0, 0x96, 0x4E - }, - { - 0xC0, 0x21, 0xB3, 0x00, 0x85, 0x15, 0x14, 0x35, - 0xDF, 0x33, 0xB0, 0x07, 0xCC, 0xEC, 0xC6, 0x9D, - 0xF1, 0x26, 0x9F, 0x39, 0xBA, 0x25, 0x09, 0x2B, - 0xED, 0x59, 0xD9, 0x32, 0xAC, 0x0F, 0xDC, 0x28 - }, - { - 0x91, 0xA2, 0x5E, 0xC0, 0xEC, 0x0D, 0x9A, 0x56, - 0x7F, 0x89, 0xC4, 0xBF, 0xE1, 0xA6, 0x5A, 0x0E, - 0x43, 0x2D, 0x07, 0x06, 0x4B, 0x41, 0x90, 0xE2, - 0x7D, 0xFB, 0x81, 0x90, 0x1F, 0xD3, 0x13, 0x9B - }, - { - 0x59, 0x50, 0xD3, 0x9A, 0x23, 0xE1, 0x54, 0x5F, - 0x30, 0x12, 0x70, 0xAA, 0x1A, 0x12, 0xF2, 0xE6, - 0xC4, 0x53, 0x77, 0x6E, 0x4D, 0x63, 0x55, 0xDE, - 0x42, 0x5C, 0xC1, 0x53, 0xF9, 0x81, 0x88, 0x67 - }, - { - 0xD7, 0x9F, 0x14, 0x72, 0x0C, 0x61, 0x0A, 0xF1, - 0x79, 0xA3, 0x76, 0x5D, 0x4B, 0x7C, 0x09, 0x68, - 0xF9, 0x77, 0x96, 0x2D, 0xBF, 0x65, 0x5B, 0x52, - 0x12, 0x72, 0xB6, 0xF1, 0xE1, 0x94, 0x48, 0x8E - }, - { - 0xE9, 0x53, 0x1B, 0xFC, 0x8B, 0x02, 0x99, 0x5A, - 0xEA, 0xA7, 0x5B, 0xA2, 0x70, 0x31, 0xFA, 0xDB, - 0xCB, 0xF4, 0xA0, 0xDA, 0xB8, 0x96, 0x1D, 0x92, - 0x96, 0xCD, 0x7E, 0x84, 0xD2, 0x5D, 0x60, 0x06 - }, - { - 0x34, 0xE9, 0xC2, 0x6A, 0x01, 0xD7, 0xF1, 0x61, - 0x81, 0xB4, 0x54, 0xA9, 0xD1, 0x62, 0x3C, 0x23, - 0x3C, 0xB9, 0x9D, 0x31, 0xC6, 0x94, 0x65, 0x6E, - 0x94, 0x13, 0xAC, 0xA3, 0xE9, 0x18, 0x69, 0x2F - }, - { - 0xD9, 0xD7, 0x42, 0x2F, 0x43, 0x7B, 0xD4, 0x39, - 0xDD, 0xD4, 0xD8, 0x83, 0xDA, 0xE2, 0xA0, 0x83, - 0x50, 0x17, 0x34, 0x14, 0xBE, 0x78, 0x15, 0x51, - 0x33, 0xFF, 0xF1, 0x96, 0x4C, 0x3D, 0x79, 0x72 - }, - { - 0x4A, 0xEE, 0x0C, 0x7A, 0xAF, 0x07, 0x54, 0x14, - 0xFF, 0x17, 0x93, 0xEA, 0xD7, 0xEA, 0xCA, 0x60, - 0x17, 0x75, 0xC6, 0x15, 0xDB, 0xD6, 0x0B, 0x64, - 0x0B, 0x0A, 0x9F, 0x0C, 0xE5, 0x05, 0xD4, 0x35 - }, - { - 0x6B, 0xFD, 0xD1, 0x54, 0x59, 0xC8, 0x3B, 0x99, - 0xF0, 0x96, 0xBF, 0xB4, 0x9E, 0xE8, 0x7B, 0x06, - 0x3D, 0x69, 0xC1, 0x97, 0x4C, 0x69, 0x28, 0xAC, - 0xFC, 0xFB, 0x40, 0x99, 0xF8, 0xC4, 0xEF, 0x67 - }, - { - 0x9F, 0xD1, 0xC4, 0x08, 0xFD, 0x75, 0xC3, 0x36, - 0x19, 0x3A, 0x2A, 0x14, 0xD9, 0x4F, 0x6A, 0xF5, - 0xAD, 0xF0, 0x50, 0xB8, 0x03, 0x87, 0xB4, 0xB0, - 0x10, 0xFB, 0x29, 0xF4, 0xCC, 0x72, 0x70, 0x7C - }, - { - 0x13, 0xC8, 0x84, 0x80, 0xA5, 0xD0, 0x0D, 0x6C, - 0x8C, 0x7A, 0xD2, 0x11, 0x0D, 0x76, 0xA8, 0x2D, - 0x9B, 0x70, 0xF4, 0xFA, 0x66, 0x96, 0xD4, 0xE5, - 0xDD, 0x42, 0xA0, 0x66, 0xDC, 0xAF, 0x99, 0x20 - }, - { - 0x82, 0x0E, 0x72, 0x5E, 0xE2, 0x5F, 0xE8, 0xFD, - 0x3A, 0x8D, 0x5A, 0xBE, 0x4C, 0x46, 0xC3, 0xBA, - 0x88, 0x9D, 0xE6, 0xFA, 0x91, 0x91, 0xAA, 0x22, - 0xBA, 0x67, 0xD5, 0x70, 0x54, 0x21, 0x54, 0x2B - }, - { - 0x32, 0xD9, 0x3A, 0x0E, 0xB0, 0x2F, 0x42, 0xFB, - 0xBC, 0xAF, 0x2B, 0xAD, 0x00, 0x85, 0xB2, 0x82, - 0xE4, 0x60, 0x46, 0xA4, 0xDF, 0x7A, 0xD1, 0x06, - 0x57, 0xC9, 0xD6, 0x47, 0x63, 0x75, 0xB9, 0x3E - }, - { - 0xAD, 0xC5, 0x18, 0x79, 0x05, 0xB1, 0x66, 0x9C, - 0xD8, 0xEC, 0x9C, 0x72, 0x1E, 0x19, 0x53, 0x78, - 0x6B, 0x9D, 0x89, 0xA9, 0xBA, 0xE3, 0x07, 0x80, - 0xF1, 0xE1, 0xEA, 0xB2, 0x4A, 0x00, 0x52, 0x3C - }, - { - 0xE9, 0x07, 0x56, 0xFF, 0x7F, 0x9A, 0xD8, 0x10, - 0xB2, 0x39, 0xA1, 0x0C, 0xED, 0x2C, 0xF9, 0xB2, - 0x28, 0x43, 0x54, 0xC1, 0xF8, 0xC7, 0xE0, 0xAC, - 0xCC, 0x24, 0x61, 0xDC, 0x79, 0x6D, 0x6E, 0x89 - }, - { - 0x12, 0x51, 0xF7, 0x6E, 0x56, 0x97, 0x84, 0x81, - 0x87, 0x53, 0x59, 0x80, 0x1D, 0xB5, 0x89, 0xA0, - 0xB2, 0x2F, 0x86, 0xD8, 0xD6, 0x34, 0xDC, 0x04, - 0x50, 0x6F, 0x32, 0x2E, 0xD7, 0x8F, 0x17, 0xE8 - }, - { - 0x3A, 0xFA, 0x89, 0x9F, 0xD9, 0x80, 0xE7, 0x3E, - 0xCB, 0x7F, 0x4D, 0x8B, 0x8F, 0x29, 0x1D, 0xC9, - 0xAF, 0x79, 0x6B, 0xC6, 0x5D, 0x27, 0xF9, 0x74, - 0xC6, 0xF1, 0x93, 0xC9, 0x19, 0x1A, 0x09, 0xFD - }, - { - 0xAA, 0x30, 0x5B, 0xE2, 0x6E, 0x5D, 0xED, 0xDC, - 0x3C, 0x10, 0x10, 0xCB, 0xC2, 0x13, 0xF9, 0x5F, - 0x05, 0x1C, 0x78, 0x5C, 0x5B, 0x43, 0x1E, 0x6A, - 0x7C, 0xD0, 0x48, 0xF1, 0x61, 0x78, 0x75, 0x28 - }, - { - 0x8E, 0xA1, 0x88, 0x4F, 0xF3, 0x2E, 0x9D, 0x10, - 0xF0, 0x39, 0xB4, 0x07, 0xD0, 0xD4, 0x4E, 0x7E, - 0x67, 0x0A, 0xBD, 0x88, 0x4A, 0xEE, 0xE0, 0xFB, - 0x75, 0x7A, 0xE9, 0x4E, 0xAA, 0x97, 0x37, 0x3D - }, - { - 0xD4, 0x82, 0xB2, 0x15, 0x5D, 0x4D, 0xEC, 0x6B, - 0x47, 0x36, 0xA1, 0xF1, 0x61, 0x7B, 0x53, 0xAA, - 0xA3, 0x73, 0x10, 0x27, 0x7D, 0x3F, 0xEF, 0x0C, - 0x37, 0xAD, 0x41, 0x76, 0x8F, 0xC2, 0x35, 0xB4 - }, - { - 0x4D, 0x41, 0x39, 0x71, 0x38, 0x7E, 0x7A, 0x88, - 0x98, 0xA8, 0xDC, 0x2A, 0x27, 0x50, 0x07, 0x78, - 0x53, 0x9E, 0xA2, 0x14, 0xA2, 0xDF, 0xE9, 0xB3, - 0xD7, 0xE8, 0xEB, 0xDC, 0xE5, 0xCF, 0x3D, 0xB3 - }, - { - 0x69, 0x6E, 0x5D, 0x46, 0xE6, 0xC5, 0x7E, 0x87, - 0x96, 0xE4, 0x73, 0x5D, 0x08, 0x91, 0x6E, 0x0B, - 0x79, 0x29, 0xB3, 0xCF, 0x29, 0x8C, 0x29, 0x6D, - 0x22, 0xE9, 0xD3, 0x01, 0x96, 0x53, 0x37, 0x1C - }, - { - 0x1F, 0x56, 0x47, 0xC1, 0xD3, 0xB0, 0x88, 0x22, - 0x88, 0x85, 0x86, 0x5C, 0x89, 0x40, 0x90, 0x8B, - 0xF4, 0x0D, 0x1A, 0x82, 0x72, 0x82, 0x19, 0x73, - 0xB1, 0x60, 0x00, 0x8E, 0x7A, 0x3C, 0xE2, 0xEB - }, - { - 0xB6, 0xE7, 0x6C, 0x33, 0x0F, 0x02, 0x1A, 0x5B, - 0xDA, 0x65, 0x87, 0x50, 0x10, 0xB0, 0xED, 0xF0, - 0x91, 0x26, 0xC0, 0xF5, 0x10, 0xEA, 0x84, 0x90, - 0x48, 0x19, 0x20, 0x03, 0xAE, 0xF4, 0xC6, 0x1C - }, - { - 0x3C, 0xD9, 0x52, 0xA0, 0xBE, 0xAD, 0xA4, 0x1A, - 0xBB, 0x42, 0x4C, 0xE4, 0x7F, 0x94, 0xB4, 0x2B, - 0xE6, 0x4E, 0x1F, 0xFB, 0x0F, 0xD0, 0x78, 0x22, - 0x76, 0x80, 0x79, 0x46, 0xD0, 0xD0, 0xBC, 0x55 - }, - { - 0x98, 0xD9, 0x26, 0x77, 0x43, 0x9B, 0x41, 0xB7, - 0xBB, 0x51, 0x33, 0x12, 0xAF, 0xB9, 0x2B, 0xCC, - 0x8E, 0xE9, 0x68, 0xB2, 0xE3, 0xB2, 0x38, 0xCE, - 0xCB, 0x9B, 0x0F, 0x34, 0xC9, 0xBB, 0x63, 0xD0 - }, - { - 0xEC, 0xBC, 0xA2, 0xCF, 0x08, 0xAE, 0x57, 0xD5, - 0x17, 0xAD, 0x16, 0x15, 0x8A, 0x32, 0xBF, 0xA7, - 0xDC, 0x03, 0x82, 0xEA, 0xED, 0xA1, 0x28, 0xE9, - 0x18, 0x86, 0x73, 0x4C, 0x24, 0xA0, 0xB2, 0x9D - }, - { - 0x94, 0x2C, 0xC7, 0xC0, 0xB5, 0x2E, 0x2B, 0x16, - 0xA4, 0xB8, 0x9F, 0xA4, 0xFC, 0x7E, 0x0B, 0xF6, - 0x09, 0xE2, 0x9A, 0x08, 0xC1, 0xA8, 0x54, 0x34, - 0x52, 0xB7, 0x7C, 0x7B, 0xFD, 0x11, 0xBB, 0x28 - }, - { - 0x8A, 0x06, 0x5D, 0x8B, 0x61, 0xA0, 0xDF, 0xFB, - 0x17, 0x0D, 0x56, 0x27, 0x73, 0x5A, 0x76, 0xB0, - 0xE9, 0x50, 0x60, 0x37, 0x80, 0x8C, 0xBA, 0x16, - 0xC3, 0x45, 0x00, 0x7C, 0x9F, 0x79, 0xCF, 0x8F - }, - { - 0x1B, 0x9F, 0xA1, 0x97, 0x14, 0x65, 0x9C, 0x78, - 0xFF, 0x41, 0x38, 0x71, 0x84, 0x92, 0x15, 0x36, - 0x10, 0x29, 0xAC, 0x80, 0x2B, 0x1C, 0xBC, 0xD5, - 0x4E, 0x40, 0x8B, 0xD8, 0x72, 0x87, 0xF8, 0x1F - }, - { - 0x8D, 0xAB, 0x07, 0x1B, 0xCD, 0x6C, 0x72, 0x92, - 0xA9, 0xEF, 0x72, 0x7B, 0x4A, 0xE0, 0xD8, 0x67, - 0x13, 0x30, 0x1D, 0xA8, 0x61, 0x8D, 0x9A, 0x48, - 0xAD, 0xCE, 0x55, 0xF3, 0x03, 0xA8, 0x69, 0xA1 - }, - { - 0x82, 0x53, 0xE3, 0xE7, 0xC7, 0xB6, 0x84, 0xB9, - 0xCB, 0x2B, 0xEB, 0x01, 0x4C, 0xE3, 0x30, 0xFF, - 0x3D, 0x99, 0xD1, 0x7A, 0xBB, 0xDB, 0xAB, 0xE4, - 0xF4, 0xD6, 0x74, 0xDE, 0xD5, 0x3F, 0xFC, 0x6B - }, - { - 0xF1, 0x95, 0xF3, 0x21, 0xE9, 0xE3, 0xD6, 0xBD, - 0x7D, 0x07, 0x45, 0x04, 0xDD, 0x2A, 0xB0, 0xE6, - 0x24, 0x1F, 0x92, 0xE7, 0x84, 0xB1, 0xAA, 0x27, - 0x1F, 0xF6, 0x48, 0xB1, 0xCA, 0xB6, 0xD7, 0xF6 - }, - { - 0x27, 0xE4, 0xCC, 0x72, 0x09, 0x0F, 0x24, 0x12, - 0x66, 0x47, 0x6A, 0x7C, 0x09, 0x49, 0x5F, 0x2D, - 0xB1, 0x53, 0xD5, 0xBC, 0xBD, 0x76, 0x19, 0x03, - 0xEF, 0x79, 0x27, 0x5E, 0xC5, 0x6B, 0x2E, 0xD8 - }, - { - 0x89, 0x9C, 0x24, 0x05, 0x78, 0x8E, 0x25, 0xB9, - 0x9A, 0x18, 0x46, 0x35, 0x5E, 0x64, 0x6D, 0x77, - 0xCF, 0x40, 0x00, 0x83, 0x41, 0x5F, 0x7D, 0xC5, - 0xAF, 0xE6, 0x9D, 0x6E, 0x17, 0xC0, 0x00, 0x23 - }, - { - 0xA5, 0x9B, 0x78, 0xC4, 0x90, 0x57, 0x44, 0x07, - 0x6B, 0xFE, 0xE8, 0x94, 0xDE, 0x70, 0x7D, 0x4F, - 0x12, 0x0B, 0x5C, 0x68, 0x93, 0xEA, 0x04, 0x00, - 0x29, 0x7D, 0x0B, 0xB8, 0x34, 0x72, 0x76, 0x32 - }, - { - 0x59, 0xDC, 0x78, 0xB1, 0x05, 0x64, 0x97, 0x07, - 0xA2, 0xBB, 0x44, 0x19, 0xC4, 0x8F, 0x00, 0x54, - 0x00, 0xD3, 0x97, 0x3D, 0xE3, 0x73, 0x66, 0x10, - 0x23, 0x04, 0x35, 0xB1, 0x04, 0x24, 0xB2, 0x4F - }, - { - 0xC0, 0x14, 0x9D, 0x1D, 0x7E, 0x7A, 0x63, 0x53, - 0xA6, 0xD9, 0x06, 0xEF, 0xE7, 0x28, 0xF2, 0xF3, - 0x29, 0xFE, 0x14, 0xA4, 0x14, 0x9A, 0x3E, 0xA7, - 0x76, 0x09, 0xBC, 0x42, 0xB9, 0x75, 0xDD, 0xFA - }, - { - 0xA3, 0x2F, 0x24, 0x14, 0x74, 0xA6, 0xC1, 0x69, - 0x32, 0xE9, 0x24, 0x3B, 0xE0, 0xCF, 0x09, 0xBC, - 0xDC, 0x7E, 0x0C, 0xA0, 0xE7, 0xA6, 0xA1, 0xB9, - 0xB1, 0xA0, 0xF0, 0x1E, 0x41, 0x50, 0x23, 0x77 - }, - { - 0xB2, 0x39, 0xB2, 0xE4, 0xF8, 0x18, 0x41, 0x36, - 0x1C, 0x13, 0x39, 0xF6, 0x8E, 0x2C, 0x35, 0x9F, - 0x92, 0x9A, 0xF9, 0xAD, 0x9F, 0x34, 0xE0, 0x1A, - 0xAB, 0x46, 0x31, 0xAD, 0x6D, 0x55, 0x00, 0xB0 - }, - { - 0x85, 0xFB, 0x41, 0x9C, 0x70, 0x02, 0xA3, 0xE0, - 0xB4, 0xB6, 0xEA, 0x09, 0x3B, 0x4C, 0x1A, 0xC6, - 0x93, 0x66, 0x45, 0xB6, 0x5D, 0xAC, 0x5A, 0xC1, - 0x5A, 0x85, 0x28, 0xB7, 0xB9, 0x4C, 0x17, 0x54 - }, - { - 0x96, 0x19, 0x72, 0x06, 0x25, 0xF1, 0x90, 0xB9, - 0x3A, 0x3F, 0xAD, 0x18, 0x6A, 0xB3, 0x14, 0x18, - 0x96, 0x33, 0xC0, 0xD3, 0xA0, 0x1E, 0x6F, 0x9B, - 0xC8, 0xC4, 0xA8, 0xF8, 0x2F, 0x38, 0x3D, 0xBF - }, - { - 0x7D, 0x62, 0x0D, 0x90, 0xFE, 0x69, 0xFA, 0x46, - 0x9A, 0x65, 0x38, 0x38, 0x89, 0x70, 0xA1, 0xAA, - 0x09, 0xBB, 0x48, 0xA2, 0xD5, 0x9B, 0x34, 0x7B, - 0x97, 0xE8, 0xCE, 0x71, 0xF4, 0x8C, 0x7F, 0x46 - }, - { - 0x29, 0x43, 0x83, 0x56, 0x85, 0x96, 0xFB, 0x37, - 0xC7, 0x5B, 0xBA, 0xCD, 0x97, 0x9C, 0x5F, 0xF6, - 0xF2, 0x0A, 0x55, 0x6B, 0xF8, 0x87, 0x9C, 0xC7, - 0x29, 0x24, 0x85, 0x5D, 0xF9, 0xB8, 0x24, 0x0E - }, - { - 0x16, 0xB1, 0x8A, 0xB3, 0x14, 0x35, 0x9C, 0x2B, - 0x83, 0x3C, 0x1C, 0x69, 0x86, 0xD4, 0x8C, 0x55, - 0xA9, 0xFC, 0x97, 0xCD, 0xE9, 0xA3, 0xC1, 0xF1, - 0x0A, 0x31, 0x77, 0x14, 0x0F, 0x73, 0xF7, 0x38 - }, - { - 0x8C, 0xBB, 0xDD, 0x14, 0xBC, 0x33, 0xF0, 0x4C, - 0xF4, 0x58, 0x13, 0xE4, 0xA1, 0x53, 0xA2, 0x73, - 0xD3, 0x6A, 0xDA, 0xD5, 0xCE, 0x71, 0xF4, 0x99, - 0xEE, 0xB8, 0x7F, 0xB8, 0xAC, 0x63, 0xB7, 0x29 - }, - { - 0x69, 0xC9, 0xA4, 0x98, 0xDB, 0x17, 0x4E, 0xCA, - 0xEF, 0xCC, 0x5A, 0x3A, 0xC9, 0xFD, 0xED, 0xF0, - 0xF8, 0x13, 0xA5, 0xBE, 0xC7, 0x27, 0xF1, 0xE7, - 0x75, 0xBA, 0xBD, 0xEC, 0x77, 0x18, 0x81, 0x6E - }, - { - 0xB4, 0x62, 0xC3, 0xBE, 0x40, 0x44, 0x8F, 0x1D, - 0x4F, 0x80, 0x62, 0x62, 0x54, 0xE5, 0x35, 0xB0, - 0x8B, 0xC9, 0xCD, 0xCF, 0xF5, 0x99, 0xA7, 0x68, - 0x57, 0x8D, 0x4B, 0x28, 0x81, 0xA8, 0xE3, 0xF0 - }, - { - 0x55, 0x3E, 0x9D, 0x9C, 0x5F, 0x36, 0x0A, 0xC0, - 0xB7, 0x4A, 0x7D, 0x44, 0xE5, 0xA3, 0x91, 0xDA, - 0xD4, 0xCE, 0xD0, 0x3E, 0x0C, 0x24, 0x18, 0x3B, - 0x7E, 0x8E, 0xCA, 0xBD, 0xF1, 0x71, 0x5A, 0x64 - }, - { - 0x7A, 0x7C, 0x55, 0xA5, 0x6F, 0xA9, 0xAE, 0x51, - 0xE6, 0x55, 0xE0, 0x19, 0x75, 0xD8, 0xA6, 0xFF, - 0x4A, 0xE9, 0xE4, 0xB4, 0x86, 0xFC, 0xBE, 0x4E, - 0xAC, 0x04, 0x45, 0x88, 0xF2, 0x45, 0xEB, 0xEA - }, - { - 0x2A, 0xFD, 0xF3, 0xC8, 0x2A, 0xBC, 0x48, 0x67, - 0xF5, 0xDE, 0x11, 0x12, 0x86, 0xC2, 0xB3, 0xBE, - 0x7D, 0x6E, 0x48, 0x65, 0x7B, 0xA9, 0x23, 0xCF, - 0xBF, 0x10, 0x1A, 0x6D, 0xFC, 0xF9, 0xDB, 0x9A - }, - { - 0x41, 0x03, 0x7D, 0x2E, 0xDC, 0xDC, 0xE0, 0xC4, - 0x9B, 0x7F, 0xB4, 0xA6, 0xAA, 0x09, 0x99, 0xCA, - 0x66, 0x97, 0x6C, 0x74, 0x83, 0xAF, 0xE6, 0x31, - 0xD4, 0xED, 0xA2, 0x83, 0x14, 0x4F, 0x6D, 0xFC - }, - { - 0xC4, 0x46, 0x6F, 0x84, 0x97, 0xCA, 0x2E, 0xEB, - 0x45, 0x83, 0xA0, 0xB0, 0x8E, 0x9D, 0x9A, 0xC7, - 0x43, 0x95, 0x70, 0x9F, 0xDA, 0x10, 0x9D, 0x24, - 0xF2, 0xE4, 0x46, 0x21, 0x96, 0x77, 0x9C, 0x5D - }, - { - 0x75, 0xF6, 0x09, 0x33, 0x8A, 0xA6, 0x7D, 0x96, - 0x9A, 0x2A, 0xE2, 0xA2, 0x36, 0x2B, 0x2D, 0xA9, - 0xD7, 0x7C, 0x69, 0x5D, 0xFD, 0x1D, 0xF7, 0x22, - 0x4A, 0x69, 0x01, 0xDB, 0x93, 0x2C, 0x33, 0x64 - }, - { - 0x68, 0x60, 0x6C, 0xEB, 0x98, 0x9D, 0x54, 0x88, - 0xFC, 0x7C, 0xF6, 0x49, 0xF3, 0xD7, 0xC2, 0x72, - 0xEF, 0x05, 0x5D, 0xA1, 0xA9, 0x3F, 0xAE, 0xCD, - 0x55, 0xFE, 0x06, 0xF6, 0x96, 0x70, 0x98, 0xCA - }, - { - 0x44, 0x34, 0x6B, 0xDE, 0xB7, 0xE0, 0x52, 0xF6, - 0x25, 0x50, 0x48, 0xF0, 0xD9, 0xB4, 0x2C, 0x42, - 0x5B, 0xAB, 0x9C, 0x3D, 0xD2, 0x41, 0x68, 0x21, - 0x2C, 0x3E, 0xCF, 0x1E, 0xBF, 0x34, 0xE6, 0xAE - }, - { - 0x8E, 0x9C, 0xF6, 0xE1, 0xF3, 0x66, 0x47, 0x1F, - 0x2A, 0xC7, 0xD2, 0xEE, 0x9B, 0x5E, 0x62, 0x66, - 0xFD, 0xA7, 0x1F, 0x8F, 0x2E, 0x41, 0x09, 0xF2, - 0x23, 0x7E, 0xD5, 0xF8, 0x81, 0x3F, 0xC7, 0x18 - }, - { - 0x84, 0xBB, 0xEB, 0x84, 0x06, 0xD2, 0x50, 0x95, - 0x1F, 0x8C, 0x1B, 0x3E, 0x86, 0xA7, 0xC0, 0x10, - 0x08, 0x29, 0x21, 0x83, 0x3D, 0xFD, 0x95, 0x55, - 0xA2, 0xF9, 0x09, 0xB1, 0x08, 0x6E, 0xB4, 0xB8 - }, - { - 0xEE, 0x66, 0x6F, 0x3E, 0xEF, 0x0F, 0x7E, 0x2A, - 0x9C, 0x22, 0x29, 0x58, 0xC9, 0x7E, 0xAF, 0x35, - 0xF5, 0x1C, 0xED, 0x39, 0x3D, 0x71, 0x44, 0x85, - 0xAB, 0x09, 0xA0, 0x69, 0x34, 0x0F, 0xDF, 0x88 - }, - { - 0xC1, 0x53, 0xD3, 0x4A, 0x65, 0xC4, 0x7B, 0x4A, - 0x62, 0xC5, 0xCA, 0xCF, 0x24, 0x01, 0x09, 0x75, - 0xD0, 0x35, 0x6B, 0x2F, 0x32, 0xC8, 0xF5, 0xDA, - 0x53, 0x0D, 0x33, 0x88, 0x16, 0xAD, 0x5D, 0xE6 - }, - { - 0x9F, 0xC5, 0x45, 0x01, 0x09, 0xE1, 0xB7, 0x79, - 0xF6, 0xC7, 0xAE, 0x79, 0xD5, 0x6C, 0x27, 0x63, - 0x5C, 0x8D, 0xD4, 0x26, 0xC5, 0xA9, 0xD5, 0x4E, - 0x25, 0x78, 0xDB, 0x98, 0x9B, 0x8C, 0x3B, 0x4E - }, - { - 0xD1, 0x2B, 0xF3, 0x73, 0x2E, 0xF4, 0xAF, 0x5C, - 0x22, 0xFA, 0x90, 0x35, 0x6A, 0xF8, 0xFC, 0x50, - 0xFC, 0xB4, 0x0F, 0x8F, 0x2E, 0xA5, 0xC8, 0x59, - 0x47, 0x37, 0xA3, 0xB3, 0xD5, 0xAB, 0xDB, 0xD7 - }, - { - 0x11, 0x03, 0x0B, 0x92, 0x89, 0xBB, 0xA5, 0xAF, - 0x65, 0x26, 0x06, 0x72, 0xAB, 0x6F, 0xEE, 0x88, - 0xB8, 0x74, 0x20, 0xAC, 0xEF, 0x4A, 0x17, 0x89, - 0xA2, 0x07, 0x3B, 0x7E, 0xC2, 0xF2, 0xA0, 0x9E - }, - { - 0x69, 0xCB, 0x19, 0x2B, 0x84, 0x44, 0x00, 0x5C, - 0x8C, 0x0C, 0xEB, 0x12, 0xC8, 0x46, 0x86, 0x07, - 0x68, 0x18, 0x8C, 0xDA, 0x0A, 0xEC, 0x27, 0xA9, - 0xC8, 0xA5, 0x5C, 0xDE, 0xE2, 0x12, 0x36, 0x32 - }, - { - 0xDB, 0x44, 0x4C, 0x15, 0x59, 0x7B, 0x5F, 0x1A, - 0x03, 0xD1, 0xF9, 0xED, 0xD1, 0x6E, 0x4A, 0x9F, - 0x43, 0xA6, 0x67, 0xCC, 0x27, 0x51, 0x75, 0xDF, - 0xA2, 0xB7, 0x04, 0xE3, 0xBB, 0x1A, 0x9B, 0x83 - }, - { - 0x3F, 0xB7, 0x35, 0x06, 0x1A, 0xBC, 0x51, 0x9D, - 0xFE, 0x97, 0x9E, 0x54, 0xC1, 0xEE, 0x5B, 0xFA, - 0xD0, 0xA9, 0xD8, 0x58, 0xB3, 0x31, 0x5B, 0xAD, - 0x34, 0xBD, 0xE9, 0x99, 0xEF, 0xD7, 0x24, 0xDD - }, -}; - - - - -static const uint8_t blake2b_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = -{ - { - 0x78, 0x6A, 0x02, 0xF7, 0x42, 0x01, 0x59, 0x03, - 0xC6, 0xC6, 0xFD, 0x85, 0x25, 0x52, 0xD2, 0x72, - 0x91, 0x2F, 0x47, 0x40, 0xE1, 0x58, 0x47, 0x61, - 0x8A, 0x86, 0xE2, 0x17, 0xF7, 0x1F, 0x54, 0x19, - 0xD2, 0x5E, 0x10, 0x31, 0xAF, 0xEE, 0x58, 0x53, - 0x13, 0x89, 0x64, 0x44, 0x93, 0x4E, 0xB0, 0x4B, - 0x90, 0x3A, 0x68, 0x5B, 0x14, 0x48, 0xB7, 0x55, - 0xD5, 0x6F, 0x70, 0x1A, 0xFE, 0x9B, 0xE2, 0xCE - }, - { - 0x2F, 0xA3, 0xF6, 0x86, 0xDF, 0x87, 0x69, 0x95, - 0x16, 0x7E, 0x7C, 0x2E, 0x5D, 0x74, 0xC4, 0xC7, - 0xB6, 0xE4, 0x8F, 0x80, 0x68, 0xFE, 0x0E, 0x44, - 0x20, 0x83, 0x44, 0xD4, 0x80, 0xF7, 0x90, 0x4C, - 0x36, 0x96, 0x3E, 0x44, 0x11, 0x5F, 0xE3, 0xEB, - 0x2A, 0x3A, 0xC8, 0x69, 0x4C, 0x28, 0xBC, 0xB4, - 0xF5, 0xA0, 0xF3, 0x27, 0x6F, 0x2E, 0x79, 0x48, - 0x7D, 0x82, 0x19, 0x05, 0x7A, 0x50, 0x6E, 0x4B - }, - { - 0x1C, 0x08, 0x79, 0x8D, 0xC6, 0x41, 0xAB, 0xA9, - 0xDE, 0xE4, 0x35, 0xE2, 0x25, 0x19, 0xA4, 0x72, - 0x9A, 0x09, 0xB2, 0xBF, 0xE0, 0xFF, 0x00, 0xEF, - 0x2D, 0xCD, 0x8E, 0xD6, 0xF8, 0xA0, 0x7D, 0x15, - 0xEA, 0xF4, 0xAE, 0xE5, 0x2B, 0xBF, 0x18, 0xAB, - 0x56, 0x08, 0xA6, 0x19, 0x0F, 0x70, 0xB9, 0x04, - 0x86, 0xC8, 0xA7, 0xD4, 0x87, 0x37, 0x10, 0xB1, - 0x11, 0x5D, 0x3D, 0xEB, 0xBB, 0x43, 0x27, 0xB5 - }, - { - 0x40, 0xA3, 0x74, 0x72, 0x73, 0x02, 0xD9, 0xA4, - 0x76, 0x9C, 0x17, 0xB5, 0xF4, 0x09, 0xFF, 0x32, - 0xF5, 0x8A, 0xA2, 0x4F, 0xF1, 0x22, 0xD7, 0x60, - 0x3E, 0x4F, 0xDA, 0x15, 0x09, 0xE9, 0x19, 0xD4, - 0x10, 0x7A, 0x52, 0xC5, 0x75, 0x70, 0xA6, 0xD9, - 0x4E, 0x50, 0x96, 0x7A, 0xEA, 0x57, 0x3B, 0x11, - 0xF8, 0x6F, 0x47, 0x3F, 0x53, 0x75, 0x65, 0xC6, - 0x6F, 0x70, 0x39, 0x83, 0x0A, 0x85, 0xD1, 0x86 - }, - { - 0x77, 0xDD, 0xF4, 0xB1, 0x44, 0x25, 0xEB, 0x3D, - 0x05, 0x3C, 0x1E, 0x84, 0xE3, 0x46, 0x9D, 0x92, - 0xC4, 0xCD, 0x91, 0x0E, 0xD2, 0x0F, 0x92, 0x03, - 0x5E, 0x0C, 0x99, 0xD8, 0xA7, 0xA8, 0x6C, 0xEC, - 0xAF, 0x69, 0xF9, 0x66, 0x3C, 0x20, 0xA7, 0xAA, - 0x23, 0x0B, 0xC8, 0x2F, 0x60, 0xD2, 0x2F, 0xB4, - 0xA0, 0x0B, 0x09, 0xD3, 0xEB, 0x8F, 0xC6, 0x5E, - 0xF5, 0x47, 0xFE, 0x63, 0xC8, 0xD3, 0xDD, 0xCE - }, - { - 0xCB, 0xAA, 0x0B, 0xA7, 0xD4, 0x82, 0xB1, 0xF3, - 0x01, 0x10, 0x9A, 0xE4, 0x10, 0x51, 0x99, 0x1A, - 0x32, 0x89, 0xBC, 0x11, 0x98, 0x00, 0x5A, 0xF2, - 0x26, 0xC5, 0xE4, 0xF1, 0x03, 0xB6, 0x65, 0x79, - 0xF4, 0x61, 0x36, 0x10, 0x44, 0xC8, 0xBA, 0x34, - 0x39, 0xFF, 0x12, 0xC5, 0x15, 0xFB, 0x29, 0xC5, - 0x21, 0x61, 0xB7, 0xEB, 0x9C, 0x28, 0x37, 0xB7, - 0x6A, 0x5D, 0xC3, 0x3F, 0x7C, 0xB2, 0xE2, 0xE8 - }, - { - 0xF9, 0x5D, 0x45, 0xCF, 0x69, 0xAF, 0x5C, 0x20, - 0x23, 0xBD, 0xB5, 0x05, 0x82, 0x1E, 0x62, 0xE8, - 0x5D, 0x7C, 0xAE, 0xDF, 0x7B, 0xED, 0xA1, 0x2C, - 0x02, 0x48, 0x77, 0x5B, 0x0C, 0x88, 0x20, 0x5E, - 0xEB, 0x35, 0xAF, 0x3A, 0x90, 0x81, 0x6F, 0x66, - 0x08, 0xCE, 0x7D, 0xD4, 0x4E, 0xC2, 0x8D, 0xB1, - 0x14, 0x06, 0x14, 0xE1, 0xDD, 0xEB, 0xF3, 0xAA, - 0x9C, 0xD1, 0x84, 0x3E, 0x0F, 0xAD, 0x2C, 0x36 - }, - { - 0x8F, 0x94, 0x5B, 0xA7, 0x00, 0xF2, 0x53, 0x0E, - 0x5C, 0x2A, 0x7D, 0xF7, 0xD5, 0xDC, 0xE0, 0xF8, - 0x3F, 0x9E, 0xFC, 0x78, 0xC0, 0x73, 0xFE, 0x71, - 0xAE, 0x1F, 0x88, 0x20, 0x4A, 0x4F, 0xD1, 0xCF, - 0x70, 0xA0, 0x73, 0xF5, 0xD1, 0xF9, 0x42, 0xED, - 0x62, 0x3A, 0xA1, 0x6E, 0x90, 0xA8, 0x71, 0x24, - 0x6C, 0x90, 0xC4, 0x5B, 0x62, 0x1B, 0x34, 0x01, - 0xA5, 0xDD, 0xBD, 0x9D, 0xF6, 0x26, 0x41, 0x65 - }, - { - 0xE9, 0x98, 0xE0, 0xDC, 0x03, 0xEC, 0x30, 0xEB, - 0x99, 0xBB, 0x6B, 0xFA, 0xAF, 0x66, 0x18, 0xAC, - 0xC6, 0x20, 0x32, 0x0D, 0x72, 0x20, 0xB3, 0xAF, - 0x2B, 0x23, 0xD1, 0x12, 0xD8, 0xE9, 0xCB, 0x12, - 0x62, 0xF3, 0xC0, 0xD6, 0x0D, 0x18, 0x3B, 0x1E, - 0xE7, 0xF0, 0x96, 0xD1, 0x2D, 0xAE, 0x42, 0xC9, - 0x58, 0x41, 0x86, 0x00, 0x21, 0x4D, 0x04, 0xF5, - 0xED, 0x6F, 0x5E, 0x71, 0x8B, 0xE3, 0x55, 0x66 - }, - { - 0x6A, 0x9A, 0x09, 0x0C, 0x61, 0xB3, 0x41, 0x0A, - 0xED, 0xE7, 0xEC, 0x91, 0x38, 0x14, 0x6C, 0xEB, - 0x2C, 0x69, 0x66, 0x2F, 0x46, 0x0C, 0x3D, 0xA5, - 0x3C, 0x65, 0x15, 0xC1, 0xEB, 0x31, 0xF4, 0x1C, - 0xA3, 0xD2, 0x80, 0xE5, 0x67, 0x88, 0x2F, 0x95, - 0xCF, 0x66, 0x4A, 0x94, 0x14, 0x7D, 0x78, 0xF4, - 0x2C, 0xFC, 0x71, 0x4A, 0x40, 0xD2, 0x2E, 0xF1, - 0x94, 0x70, 0xE0, 0x53, 0x49, 0x35, 0x08, 0xA2 - }, - { - 0x29, 0x10, 0x25, 0x11, 0xD7, 0x49, 0xDB, 0x3C, - 0xC9, 0xB4, 0xE3, 0x35, 0xFA, 0x1F, 0x5E, 0x8F, - 0xAC, 0xA8, 0x42, 0x1D, 0x55, 0x8F, 0x6A, 0x3F, - 0x33, 0x21, 0xD5, 0x0D, 0x04, 0x4A, 0x24, 0x8B, - 0xA5, 0x95, 0xCF, 0xC3, 0xEF, 0xD3, 0xD2, 0xAD, - 0xC9, 0x73, 0x34, 0xDA, 0x73, 0x24, 0x13, 0xF5, - 0xCB, 0xF4, 0x75, 0x1C, 0x36, 0x2B, 0xA1, 0xD5, - 0x38, 0x62, 0xAC, 0x1E, 0x8D, 0xAB, 0xEE, 0xE8 - }, - { - 0xC9, 0x7A, 0x47, 0x79, 0xD4, 0x7E, 0x6F, 0x77, - 0x72, 0x9B, 0x59, 0x17, 0xD0, 0x13, 0x8A, 0xBB, - 0x35, 0x98, 0x0A, 0xB6, 0x41, 0xBD, 0x73, 0xA8, - 0x85, 0x9E, 0xB1, 0xAC, 0x98, 0xC0, 0x53, 0x62, - 0xED, 0x7D, 0x60, 0x8F, 0x2E, 0x95, 0x87, 0xD6, - 0xBA, 0x9E, 0x27, 0x1D, 0x34, 0x31, 0x25, 0xD4, - 0x0D, 0x93, 0x3A, 0x8E, 0xD0, 0x4E, 0xC1, 0xFE, - 0x75, 0xEC, 0x40, 0x7C, 0x7A, 0x53, 0xC3, 0x4E - }, - { - 0x10, 0xF0, 0xDC, 0x91, 0xB9, 0xF8, 0x45, 0xFB, - 0x95, 0xFA, 0xD6, 0x86, 0x0E, 0x6C, 0xE1, 0xAD, - 0xFA, 0x00, 0x2C, 0x7F, 0xC3, 0x27, 0x11, 0x6D, - 0x44, 0xD0, 0x47, 0xCD, 0x7D, 0x58, 0x70, 0xD7, - 0x72, 0xBB, 0x12, 0xB5, 0xFA, 0xC0, 0x0E, 0x02, - 0xB0, 0x8A, 0xC2, 0xA0, 0x17, 0x4D, 0x04, 0x46, - 0xC3, 0x6A, 0xB3, 0x5F, 0x14, 0xCA, 0x31, 0x89, - 0x4C, 0xD6, 0x1C, 0x78, 0xC8, 0x49, 0xB4, 0x8A - }, - { - 0xDE, 0xA9, 0x10, 0x1C, 0xAC, 0x62, 0xB8, 0xF6, - 0xA3, 0xC6, 0x50, 0xF9, 0x0E, 0xEA, 0x5B, 0xFA, - 0xE2, 0x65, 0x3A, 0x4E, 0xAF, 0xD6, 0x3A, 0x6D, - 0x1F, 0x0F, 0x13, 0x2D, 0xB9, 0xE4, 0xF2, 0xB1, - 0xB6, 0x62, 0x43, 0x2E, 0xC8, 0x5B, 0x17, 0xBC, - 0xAC, 0x41, 0xE7, 0x75, 0x63, 0x78, 0x81, 0xF6, - 0xAA, 0xB3, 0x8D, 0xD6, 0x6D, 0xCB, 0xD0, 0x80, - 0xF0, 0x99, 0x0A, 0x7A, 0x6E, 0x98, 0x54, 0xFE - }, - { - 0x44, 0x1F, 0xFA, 0xA0, 0x8C, 0xD7, 0x9D, 0xFF, - 0x4A, 0xFC, 0x9B, 0x9E, 0x5B, 0x56, 0x20, 0xEE, - 0xC0, 0x86, 0x73, 0x0C, 0x25, 0xF6, 0x61, 0xB1, - 0xD6, 0xFB, 0xFB, 0xD1, 0xCE, 0xC3, 0x14, 0x8D, - 0xD7, 0x22, 0x58, 0xC6, 0x56, 0x41, 0xF2, 0xFC, - 0xA5, 0xEB, 0x15, 0x5F, 0xAD, 0xBC, 0xAB, 0xB1, - 0x3C, 0x6E, 0x21, 0xDC, 0x11, 0xFA, 0xF7, 0x2C, - 0x2A, 0x28, 0x1B, 0x7D, 0x56, 0x14, 0x5F, 0x19 - }, - { - 0x44, 0x4B, 0x24, 0x0F, 0xE3, 0xED, 0x86, 0xD0, - 0xE2, 0xEF, 0x4C, 0xE7, 0xD8, 0x51, 0xED, 0xDE, - 0x22, 0x15, 0x55, 0x82, 0xAA, 0x09, 0x14, 0x79, - 0x7B, 0x72, 0x6C, 0xD0, 0x58, 0xB6, 0xF4, 0x59, - 0x32, 0xE0, 0xE1, 0x29, 0x51, 0x68, 0x76, 0x52, - 0x7B, 0x1D, 0xD8, 0x8F, 0xC6, 0x6D, 0x71, 0x19, - 0xF4, 0xAB, 0x3B, 0xED, 0x93, 0xA6, 0x1A, 0x0E, - 0x2D, 0x2D, 0x2A, 0xEA, 0xC3, 0x36, 0xD9, 0x58 - }, - { - 0xBF, 0xBA, 0xBB, 0xEF, 0x45, 0x55, 0x4C, 0xCF, - 0xA0, 0xDC, 0x83, 0x75, 0x2A, 0x19, 0xCC, 0x35, - 0xD5, 0x92, 0x09, 0x56, 0xB3, 0x01, 0xD5, 0x58, - 0xD7, 0x72, 0x28, 0x2B, 0xC8, 0x67, 0x00, 0x91, - 0x68, 0xE9, 0xE9, 0x86, 0x06, 0xBB, 0x5B, 0xA7, - 0x3A, 0x38, 0x5D, 0xE5, 0x74, 0x92, 0x28, 0xC9, - 0x25, 0xA8, 0x50, 0x19, 0xB7, 0x1F, 0x72, 0xFE, - 0x29, 0xB3, 0xCD, 0x37, 0xCA, 0x52, 0xEF, 0xE6 - }, - { - 0x9C, 0x4D, 0x0C, 0x3E, 0x1C, 0xDB, 0xBF, 0x48, - 0x5B, 0xEC, 0x86, 0xF4, 0x1C, 0xEC, 0x7C, 0x98, - 0x37, 0x3F, 0x0E, 0x09, 0xF3, 0x92, 0x84, 0x9A, - 0xAA, 0x22, 0x9E, 0xBF, 0xBF, 0x39, 0x7B, 0x22, - 0x08, 0x55, 0x29, 0xCB, 0x7E, 0xF3, 0x9F, 0x9C, - 0x7C, 0x22, 0x22, 0xA5, 0x14, 0x18, 0x2B, 0x1E, - 0xFF, 0xAA, 0x17, 0x8C, 0xC3, 0x68, 0x7B, 0x1B, - 0x2B, 0x6C, 0xBC, 0xB6, 0xFD, 0xEB, 0x96, 0xF8 - }, - { - 0x47, 0x71, 0x76, 0xB3, 0xBF, 0xCB, 0xAD, 0xD7, - 0x65, 0x7C, 0x23, 0xC2, 0x46, 0x25, 0xE4, 0xD0, - 0xD6, 0x74, 0xD1, 0x86, 0x8F, 0x00, 0x60, 0x06, - 0x39, 0x8A, 0xF9, 0x7A, 0xA4, 0x18, 0x77, 0xC8, - 0xE7, 0x0D, 0x3D, 0x14, 0xC3, 0xBB, 0xC9, 0xBB, - 0xCD, 0xCE, 0xA8, 0x01, 0xBD, 0x0E, 0x15, 0x99, - 0xAF, 0x1F, 0x3E, 0xEC, 0x67, 0x40, 0x51, 0x70, - 0xF4, 0xE2, 0x6C, 0x96, 0x4A, 0x57, 0xA8, 0xB7 - }, - { - 0xA7, 0x8C, 0x49, 0x0E, 0xDA, 0x31, 0x73, 0xBB, - 0x3F, 0x10, 0xDE, 0xE5, 0x2F, 0x11, 0x0F, 0xB1, - 0xC0, 0x8E, 0x03, 0x02, 0x23, 0x0B, 0x85, 0xDD, - 0xD7, 0xC1, 0x12, 0x57, 0xD9, 0x2D, 0xE1, 0x48, - 0x78, 0x5E, 0xF0, 0x0C, 0x03, 0x9C, 0x0B, 0xB8, - 0xEB, 0x98, 0x08, 0xA3, 0x5B, 0x2D, 0x8C, 0x08, - 0x0F, 0x57, 0x28, 0x59, 0x71, 0x4C, 0x9D, 0x40, - 0x69, 0xC5, 0xBC, 0xAF, 0x09, 0x0E, 0x89, 0x8E - }, - { - 0x58, 0xD0, 0x23, 0x39, 0x7B, 0xEB, 0x5B, 0x41, - 0x45, 0xCB, 0x22, 0x55, 0xB0, 0x7D, 0x74, 0x29, - 0x0B, 0x36, 0xD9, 0xFD, 0x1E, 0x59, 0x4A, 0xFB, - 0xD8, 0xEE, 0xA4, 0x7C, 0x20, 0x5B, 0x2E, 0xFB, - 0xFE, 0x6F, 0x46, 0x19, 0x0F, 0xAF, 0x95, 0xAF, - 0x50, 0x4A, 0xB0, 0x72, 0xE3, 0x6F, 0x6C, 0x85, - 0xD7, 0x67, 0xA3, 0x21, 0xBF, 0xD7, 0xF2, 0x26, - 0x87, 0xA4, 0xAB, 0xBF, 0x49, 0x4A, 0x68, 0x9C - }, - { - 0x40, 0x01, 0xEC, 0x74, 0xD5, 0xA4, 0x6F, 0xD2, - 0x9C, 0x2C, 0x3C, 0xDB, 0xE5, 0xD1, 0xB9, 0xF2, - 0x0E, 0x51, 0xA9, 0x41, 0xBE, 0x98, 0xD2, 0xA4, - 0xE1, 0xE2, 0xFB, 0xF8, 0x66, 0xA6, 0x72, 0x12, - 0x1D, 0xB6, 0xF8, 0x1A, 0x51, 0x4C, 0xFD, 0x10, - 0xE7, 0x35, 0x8D, 0x57, 0x1B, 0xDB, 0xA4, 0x8E, - 0x4C, 0xE7, 0x08, 0xB9, 0xD1, 0x24, 0x89, 0x4B, - 0xC0, 0xB5, 0xED, 0x55, 0x49, 0x35, 0xF7, 0x3A - }, - { - 0xCC, 0xD1, 0xB2, 0x2D, 0xAB, 0x65, 0x11, 0x22, - 0x5D, 0x24, 0x01, 0xEA, 0x2D, 0x86, 0x25, 0xD2, - 0x06, 0xA1, 0x24, 0x73, 0xCC, 0x73, 0x2B, 0x61, - 0x5E, 0x56, 0x40, 0xCE, 0xFF, 0xF0, 0xA4, 0xAD, - 0xF9, 0x71, 0xB0, 0xE8, 0x27, 0xA6, 0x19, 0xE0, - 0xA8, 0x0F, 0x5D, 0xB9, 0xCC, 0xD0, 0x96, 0x23, - 0x29, 0x01, 0x0D, 0x07, 0xE3, 0x4A, 0x20, 0x64, - 0xE7, 0x31, 0xC5, 0x20, 0x81, 0x7B, 0x21, 0x83 - }, - { - 0xB4, 0xA0, 0xA9, 0xE3, 0x57, 0x4E, 0xDB, 0x9E, - 0x1E, 0x72, 0xAA, 0x31, 0xE3, 0x9C, 0xC5, 0xF3, - 0x0D, 0xBF, 0x94, 0x3F, 0x8C, 0xAB, 0xC4, 0x08, - 0x44, 0x96, 0x54, 0xA3, 0x91, 0x31, 0xE6, 0x6D, - 0x71, 0x8A, 0x18, 0x81, 0x91, 0x43, 0xE3, 0xEA, - 0x96, 0xB4, 0xA1, 0x89, 0x59, 0x88, 0xA1, 0xC0, - 0x05, 0x6C, 0xF2, 0xB6, 0xE0, 0x4F, 0x9A, 0xC1, - 0x9D, 0x65, 0x73, 0x83, 0xC2, 0x91, 0x0C, 0x44 - }, - { - 0x44, 0x7B, 0xEC, 0xAB, 0x16, 0x63, 0x06, 0x08, - 0xD3, 0x9F, 0x4F, 0x05, 0x8B, 0x16, 0xF7, 0xAF, - 0x95, 0xB8, 0x5A, 0x76, 0xAA, 0x0F, 0xA7, 0xCE, - 0xA2, 0xB8, 0x07, 0x55, 0xFB, 0x76, 0xE9, 0xC8, - 0x04, 0xF2, 0xCA, 0x78, 0xF0, 0x26, 0x43, 0xC9, - 0x15, 0xFB, 0xF2, 0xFC, 0xE5, 0xE1, 0x9D, 0xE8, - 0x60, 0x00, 0xDE, 0x03, 0xB1, 0x88, 0x61, 0x81, - 0x5A, 0x83, 0x12, 0x60, 0x71, 0xF8, 0xA3, 0x7B - }, - { - 0x54, 0xE6, 0xDA, 0xB9, 0x97, 0x73, 0x80, 0xA5, - 0x66, 0x58, 0x22, 0xDB, 0x93, 0x37, 0x4E, 0xDA, - 0x52, 0x8D, 0x9B, 0xEB, 0x62, 0x6F, 0x9B, 0x94, - 0x02, 0x70, 0x71, 0xCB, 0x26, 0x67, 0x5E, 0x11, - 0x2B, 0x4A, 0x7F, 0xEC, 0x94, 0x1E, 0xE6, 0x0A, - 0x81, 0xE4, 0xD2, 0xEA, 0x3F, 0xF7, 0xBC, 0x52, - 0xCF, 0xC4, 0x5D, 0xFB, 0xFE, 0x73, 0x5A, 0x1C, - 0x64, 0x6B, 0x2C, 0xF6, 0xD6, 0xA4, 0x9B, 0x62 - }, - { - 0x3E, 0xA6, 0x26, 0x25, 0x94, 0x9E, 0x36, 0x46, - 0x70, 0x4D, 0x7E, 0x3C, 0x90, 0x6F, 0x82, 0xF6, - 0xC0, 0x28, 0xF5, 0x40, 0xF5, 0xF7, 0x2A, 0x79, - 0x4B, 0x0C, 0x57, 0xBF, 0x97, 0xB7, 0x64, 0x9B, - 0xFE, 0xB9, 0x0B, 0x01, 0xD3, 0xCA, 0x3E, 0x82, - 0x9D, 0xE2, 0x1B, 0x38, 0x26, 0xE6, 0xF8, 0x70, - 0x14, 0xD3, 0xC7, 0x73, 0x50, 0xCB, 0x5A, 0x15, - 0xFF, 0x5D, 0x46, 0x8A, 0x81, 0xBE, 0xC1, 0x60 - }, - { - 0x21, 0x3C, 0xFE, 0x14, 0x5C, 0x54, 0xA3, 0x36, - 0x91, 0x56, 0x99, 0x80, 0xE5, 0x93, 0x8C, 0x88, - 0x83, 0xA4, 0x6D, 0x84, 0xD1, 0x49, 0xC8, 0xFF, - 0x1A, 0x67, 0xCD, 0x28, 0x7B, 0x4D, 0x49, 0xC6, - 0xDA, 0x69, 0xD3, 0xA0, 0x35, 0x44, 0x3D, 0xB0, - 0x85, 0x98, 0x3D, 0x0E, 0xFE, 0x63, 0x70, 0x6B, - 0xD5, 0xB6, 0xF1, 0x5A, 0x7D, 0xA4, 0x59, 0xE8, - 0xD5, 0x0A, 0x19, 0x09, 0x3D, 0xB5, 0x5E, 0x80 - }, - { - 0x57, 0x16, 0xC4, 0xA3, 0x8F, 0x38, 0xDB, 0x10, - 0x4E, 0x49, 0x4A, 0x0A, 0x27, 0xCB, 0xE8, 0x9A, - 0x26, 0xA6, 0xBB, 0x6F, 0x49, 0x9E, 0xC0, 0x1C, - 0x8C, 0x01, 0xAA, 0x7C, 0xB8, 0x84, 0x97, 0xE7, - 0x51, 0x48, 0xCD, 0x6E, 0xEE, 0x12, 0xA7, 0x16, - 0x8B, 0x6F, 0x78, 0xAB, 0x74, 0xE4, 0xBE, 0x74, - 0x92, 0x51, 0xA1, 0xA7, 0x4C, 0x38, 0xC8, 0x6D, - 0x61, 0x29, 0x17, 0x7E, 0x28, 0x89, 0xE0, 0xB6 - }, - { - 0x03, 0x04, 0x60, 0xA9, 0x8B, 0xDF, 0x9F, 0xF1, - 0x7C, 0xD9, 0x64, 0x04, 0xF2, 0x8F, 0xC3, 0x04, - 0xF2, 0xB7, 0xC0, 0x4E, 0xAA, 0xDE, 0x53, 0x67, - 0x7F, 0xD2, 0x8F, 0x78, 0x8C, 0xA2, 0x21, 0x86, - 0xB8, 0xBC, 0x80, 0xDD, 0x21, 0xD1, 0x7F, 0x85, - 0x49, 0xC7, 0x11, 0xAF, 0xF0, 0xE5, 0x14, 0xE1, - 0x9D, 0x4E, 0x15, 0xF5, 0x99, 0x02, 0x52, 0xA0, - 0x3E, 0x08, 0x2F, 0x28, 0xDC, 0x20, 0x52, 0xF6 - }, - { - 0x19, 0xE7, 0xF1, 0xCC, 0xEE, 0x88, 0xA1, 0x06, - 0x72, 0x33, 0x3E, 0x39, 0x0C, 0xF2, 0x20, 0x13, - 0xA8, 0xC7, 0x34, 0xC6, 0xCB, 0x9E, 0xAB, 0x41, - 0xF1, 0x7C, 0x3C, 0x80, 0x32, 0xA2, 0xE4, 0xAC, - 0xA0, 0x56, 0x9E, 0xA3, 0x6F, 0x08, 0x60, 0xC7, - 0xA1, 0xAF, 0x28, 0xFA, 0x47, 0x68, 0x40, 0xD6, - 0x60, 0x11, 0x16, 0x88, 0x59, 0x33, 0x4A, 0x9E, - 0x4E, 0xF9, 0xCC, 0x2E, 0x61, 0xA0, 0xE2, 0x9E - }, - { - 0x29, 0xF8, 0xB8, 0xC7, 0x8C, 0x80, 0xF2, 0xFC, - 0xB4, 0xBD, 0xF7, 0x82, 0x5E, 0xD9, 0x0A, 0x70, - 0xD6, 0x25, 0xFF, 0x78, 0x5D, 0x26, 0x26, 0x77, - 0xE2, 0x50, 0xC0, 0x4F, 0x37, 0x20, 0xC8, 0x88, - 0xD0, 0x3F, 0x80, 0x45, 0xE4, 0xED, 0xF3, 0xF5, - 0x28, 0x5B, 0xD3, 0x9D, 0x92, 0x8A, 0x10, 0xA7, - 0xD0, 0xA5, 0xDF, 0x00, 0xB8, 0x48, 0x4A, 0xC2, - 0x86, 0x81, 0x42, 0xA1, 0xE8, 0xBE, 0xA3, 0x51 - }, - { - 0x5C, 0x52, 0x92, 0x0A, 0x72, 0x63, 0xE3, 0x9D, - 0x57, 0x92, 0x0C, 0xA0, 0xCB, 0x75, 0x2A, 0xC6, - 0xD7, 0x9A, 0x04, 0xFE, 0xF8, 0xA7, 0xA2, 0x16, - 0xA1, 0xEC, 0xB7, 0x11, 0x5C, 0xE0, 0x6D, 0x89, - 0xFD, 0x7D, 0x73, 0x5B, 0xD6, 0xF4, 0x27, 0x25, - 0x55, 0xDB, 0xA2, 0x2C, 0x2D, 0x1C, 0x96, 0xE6, - 0x35, 0x23, 0x22, 0xC6, 0x2C, 0x56, 0x30, 0xFD, - 0xE0, 0xF4, 0x77, 0x7A, 0x76, 0xC3, 0xDE, 0x2C - }, - { - 0x83, 0xB0, 0x98, 0xF2, 0x62, 0x25, 0x1B, 0xF6, - 0x60, 0x06, 0x4A, 0x9D, 0x35, 0x11, 0xCE, 0x76, - 0x87, 0xA0, 0x9E, 0x6D, 0xFB, 0xB8, 0x78, 0x29, - 0x9C, 0x30, 0xE9, 0x3D, 0xFB, 0x43, 0xA9, 0x31, - 0x4D, 0xB9, 0xA6, 0x00, 0x33, 0x7D, 0xB2, 0x6E, - 0xBE, 0xED, 0xAF, 0x22, 0x56, 0xA9, 0x6D, 0xAB, - 0xE9, 0xB2, 0x9E, 0x75, 0x73, 0xAD, 0x11, 0xC3, - 0x52, 0x3D, 0x87, 0x4D, 0xDE, 0x5B, 0xE7, 0xED - }, - { - 0x94, 0x47, 0xD9, 0x8A, 0xA5, 0xC9, 0x33, 0x13, - 0x52, 0xF4, 0x3D, 0x3E, 0x56, 0xD0, 0xA9, 0xA9, - 0xF9, 0x58, 0x18, 0x65, 0x99, 0x8E, 0x28, 0x85, - 0xCC, 0x56, 0xDD, 0x0A, 0x0B, 0xD5, 0xA7, 0xB5, - 0x05, 0x95, 0xBD, 0x10, 0xF7, 0x52, 0x9B, 0xCD, - 0x31, 0xF3, 0x7D, 0xC1, 0x6A, 0x14, 0x65, 0xD5, - 0x94, 0x07, 0x96, 0x67, 0xDA, 0x2A, 0x3F, 0xCB, - 0x70, 0x40, 0x14, 0x98, 0x83, 0x7C, 0xED, 0xEB - }, - { - 0x86, 0x77, 0x32, 0xF2, 0xFE, 0xEB, 0x23, 0x89, - 0x30, 0x97, 0x56, 0x1A, 0xC7, 0x10, 0xA4, 0xBF, - 0xF4, 0x53, 0xBE, 0x9C, 0xFB, 0xED, 0xBA, 0x8B, - 0xA3, 0x24, 0xF9, 0xD3, 0x12, 0xA8, 0x2D, 0x73, - 0x2E, 0x1B, 0x83, 0xB8, 0x29, 0xFD, 0xCD, 0x17, - 0x7B, 0x88, 0x2C, 0xA0, 0xC1, 0xBF, 0x54, 0x4B, - 0x22, 0x3B, 0xE5, 0x29, 0x92, 0x4A, 0x24, 0x6A, - 0x63, 0xCF, 0x05, 0x9B, 0xFD, 0xC5, 0x0A, 0x1B - }, - { - 0xF1, 0x5A, 0xB2, 0x6D, 0x4C, 0xDF, 0xCF, 0x56, - 0xE1, 0x96, 0xBB, 0x6B, 0xA1, 0x70, 0xA8, 0xFC, - 0xCC, 0x41, 0x4D, 0xE9, 0x28, 0x5A, 0xFD, 0x98, - 0xA3, 0xD3, 0xCF, 0x2F, 0xB8, 0x8F, 0xCB, 0xC0, - 0xF1, 0x98, 0x32, 0xAC, 0x43, 0x3A, 0x5B, 0x2C, - 0xC2, 0x39, 0x2A, 0x4C, 0xE3, 0x43, 0x32, 0x98, - 0x7D, 0x8D, 0x2C, 0x2B, 0xEF, 0x6C, 0x34, 0x66, - 0x13, 0x8D, 0xB0, 0xC6, 0xE4, 0x2F, 0xA4, 0x7B - }, - { - 0x28, 0x13, 0x51, 0x6D, 0x68, 0xED, 0x4A, 0x08, - 0xB3, 0x9D, 0x64, 0x8A, 0xA6, 0xAA, 0xCD, 0x81, - 0xE9, 0xD6, 0x55, 0xEC, 0xD5, 0xF0, 0xC1, 0x35, - 0x56, 0xC6, 0x0F, 0xDF, 0x0D, 0x33, 0x3E, 0xA3, - 0x84, 0x64, 0xB3, 0x6C, 0x02, 0xBA, 0xCC, 0xD7, - 0x46, 0xE9, 0x57, 0x5E, 0x96, 0xC6, 0x30, 0x14, - 0xF0, 0x74, 0xAE, 0x34, 0xA0, 0xA2, 0x5B, 0x32, - 0x0F, 0x0F, 0xBE, 0xDD, 0x6A, 0xCF, 0x76, 0x65 - }, - { - 0xD3, 0x25, 0x9A, 0xFC, 0xA8, 0xA4, 0x89, 0x62, - 0xFA, 0x89, 0x2E, 0x14, 0x5A, 0xCF, 0x54, 0x7F, - 0x26, 0x92, 0x3A, 0xE8, 0xD4, 0x92, 0x4C, 0x8A, - 0x53, 0x15, 0x81, 0x52, 0x6B, 0x04, 0xB4, 0x4C, - 0x7A, 0xF8, 0x3C, 0x64, 0x3E, 0xF5, 0xA0, 0xBC, - 0x28, 0x2D, 0x36, 0xF3, 0xFB, 0x04, 0xC8, 0x4E, - 0x28, 0xB3, 0x51, 0xF4, 0x0C, 0x74, 0xB6, 0x9D, - 0xC7, 0x84, 0x0B, 0xC7, 0x17, 0xB6, 0xF1, 0x5F - }, - { - 0xF1, 0x4B, 0x06, 0x1A, 0xE3, 0x59, 0xFA, 0x31, - 0xB9, 0x89, 0xE3, 0x03, 0x32, 0xBF, 0xE8, 0xDE, - 0x8C, 0xC8, 0xCD, 0xB5, 0x68, 0xE1, 0x4B, 0xE2, - 0x14, 0xA2, 0x22, 0x3B, 0x84, 0xCA, 0xAB, 0x74, - 0x19, 0x54, 0x9E, 0xCF, 0xCC, 0x96, 0xCE, 0x2A, - 0xCE, 0xC1, 0x19, 0x48, 0x5D, 0x87, 0xD1, 0x57, - 0xD3, 0xA8, 0x73, 0x4F, 0xC4, 0x26, 0x59, 0x7D, - 0x64, 0xF3, 0x65, 0x70, 0xCE, 0xAF, 0x22, 0x4D - }, - { - 0x55, 0xE7, 0x0B, 0x01, 0xD1, 0xFB, 0xF8, 0xB2, - 0x3B, 0x57, 0xFB, 0x62, 0xE2, 0x6C, 0x2C, 0xE5, - 0x4F, 0x13, 0xF8, 0xFA, 0x24, 0x64, 0xE6, 0xEB, - 0x98, 0xD1, 0x6A, 0x61, 0x17, 0x02, 0x6D, 0x8B, - 0x90, 0x81, 0x90, 0x12, 0x49, 0x6D, 0x40, 0x71, - 0xEB, 0xE2, 0xE5, 0x95, 0x57, 0xEC, 0xE3, 0x51, - 0x9A, 0x7A, 0xA4, 0x58, 0x02, 0xF9, 0x61, 0x53, - 0x74, 0x87, 0x73, 0x32, 0xB7, 0x34, 0x90, 0xB3 - }, - { - 0x25, 0x26, 0x1E, 0xB2, 0x96, 0x97, 0x1D, 0x6E, - 0x4A, 0x71, 0xB2, 0x92, 0x8E, 0x64, 0x83, 0x9C, - 0x67, 0xD4, 0x22, 0x87, 0x2B, 0xF9, 0xF3, 0xC3, - 0x19, 0x93, 0x61, 0x52, 0x22, 0xDE, 0x9F, 0x8F, - 0x0B, 0x2C, 0x4B, 0xE8, 0x54, 0x85, 0x59, 0xB4, - 0xB3, 0x54, 0xE7, 0x36, 0x41, 0x6E, 0x32, 0x18, - 0xD4, 0xE8, 0xA1, 0xE2, 0x19, 0xA4, 0xA6, 0xD4, - 0x3E, 0x1A, 0x9A, 0x52, 0x1D, 0x0E, 0x75, 0xFC - }, - { - 0x08, 0x30, 0x7F, 0x34, 0x7C, 0x41, 0x29, 0x4E, - 0x34, 0xBB, 0x54, 0xCB, 0x42, 0xB1, 0x52, 0x2D, - 0x22, 0xF8, 0x24, 0xF7, 0xB6, 0xE5, 0xDB, 0x50, - 0xFD, 0xA0, 0x96, 0x79, 0x8E, 0x18, 0x1A, 0x8F, - 0x02, 0x6F, 0xA2, 0x7B, 0x4A, 0xE4, 0x5D, 0x52, - 0xA6, 0x2C, 0xAF, 0x9D, 0x51, 0x98, 0xE2, 0x4A, - 0x49, 0x13, 0xC6, 0x67, 0x17, 0x75, 0xB2, 0xD7, - 0x23, 0xC1, 0x23, 0x9B, 0xFB, 0xF0, 0x16, 0xD7 - }, - { - 0x1E, 0x5C, 0x62, 0xE7, 0xE9, 0xBF, 0xA1, 0xB1, - 0x18, 0x74, 0x7A, 0x2D, 0xE0, 0x8B, 0x3C, 0xA1, - 0x01, 0x12, 0xAF, 0x96, 0xA4, 0x6E, 0x4B, 0x22, - 0xC3, 0xFC, 0x06, 0xF9, 0xBF, 0xEE, 0x4E, 0xB5, - 0xC4, 0x9E, 0x05, 0x7A, 0x4A, 0x48, 0x86, 0x23, - 0x43, 0x24, 0x57, 0x25, 0x76, 0xBB, 0x9B, 0x5E, - 0xCF, 0xDE, 0x0D, 0x99, 0xB0, 0xDE, 0x4F, 0x98, - 0xEC, 0x16, 0xE4, 0xD1, 0xB8, 0x5F, 0xA9, 0x47 - }, - { - 0xC7, 0x4A, 0x77, 0x39, 0x5F, 0xB8, 0xBC, 0x12, - 0x64, 0x47, 0x45, 0x48, 0x38, 0xE5, 0x61, 0xE9, - 0x62, 0x85, 0x3D, 0xC7, 0xEB, 0x49, 0xA1, 0xE3, - 0xCB, 0x67, 0xC3, 0xD0, 0x85, 0x1F, 0x3E, 0x39, - 0x51, 0x7B, 0xE8, 0xC3, 0x50, 0xAC, 0x91, 0x09, - 0x03, 0xD4, 0x9C, 0xD2, 0xBF, 0xDF, 0x54, 0x5C, - 0x99, 0x31, 0x6D, 0x03, 0x46, 0x17, 0x0B, 0x73, - 0x9F, 0x0A, 0xDD, 0x5D, 0x53, 0x3C, 0x2C, 0xFC - }, - { - 0x0D, 0xD5, 0x7B, 0x42, 0x3C, 0xC0, 0x1E, 0xB2, - 0x86, 0x13, 0x91, 0xEB, 0x88, 0x6A, 0x0D, 0x17, - 0x07, 0x9B, 0x93, 0x3F, 0xC7, 0x6E, 0xB3, 0xFC, - 0x08, 0xA1, 0x9F, 0x8A, 0x74, 0x95, 0x2C, 0xB6, - 0x8F, 0x6B, 0xCD, 0xC6, 0x44, 0xF7, 0x73, 0x70, - 0x96, 0x6E, 0x4D, 0x13, 0xE8, 0x05, 0x60, 0xBC, - 0xF0, 0x82, 0xEF, 0x04, 0x79, 0xD4, 0x8F, 0xBB, - 0xAB, 0x4D, 0xF0, 0x3B, 0x53, 0xA4, 0xE1, 0x78 - }, - { - 0x4D, 0x8D, 0xC3, 0x92, 0x3E, 0xDC, 0xCD, 0xFC, - 0xE7, 0x00, 0x72, 0x39, 0x8B, 0x8A, 0x3D, 0xA5, - 0xC3, 0x1F, 0xCB, 0x3E, 0xE3, 0xB6, 0x45, 0xC8, - 0x5F, 0x71, 0x7C, 0xBA, 0xEB, 0x4B, 0x67, 0x3A, - 0x19, 0x39, 0x44, 0x25, 0xA5, 0x85, 0xBF, 0xB4, - 0x64, 0xD9, 0x2F, 0x15, 0x97, 0xD0, 0xB7, 0x54, - 0xD1, 0x63, 0xF9, 0x7C, 0xED, 0x34, 0x3B, 0x25, - 0xDB, 0x5A, 0x70, 0xEF, 0x48, 0xEB, 0xB3, 0x4F - }, - { - 0xF0, 0xA5, 0x05, 0x53, 0xE4, 0xDF, 0xB0, 0xC4, - 0xE3, 0xE3, 0xD3, 0xBA, 0x82, 0x03, 0x48, 0x57, - 0xE3, 0xB1, 0xE5, 0x09, 0x18, 0xF5, 0xB8, 0xA7, - 0xD6, 0x98, 0xE1, 0x0D, 0x24, 0x2B, 0x0F, 0xB5, - 0x44, 0xAF, 0x6C, 0x92, 0xD0, 0xC3, 0xAA, 0xF9, - 0x93, 0x22, 0x20, 0x41, 0x61, 0x17, 0xB4, 0xE7, - 0x8E, 0xCB, 0x8A, 0x8F, 0x43, 0x0E, 0x13, 0xB8, - 0x2A, 0x59, 0x15, 0x29, 0x0A, 0x58, 0x19, 0xC5 - }, - { - 0xB1, 0x55, 0x43, 0xF3, 0xF7, 0x36, 0x08, 0x66, - 0x27, 0xCC, 0x53, 0x65, 0xE7, 0xE8, 0x98, 0x8C, - 0x2E, 0xF1, 0x55, 0xC0, 0xFD, 0x4F, 0x42, 0x89, - 0x61, 0xB0, 0x0D, 0x15, 0x26, 0xF0, 0x4D, 0x6D, - 0x6A, 0x65, 0x8B, 0x4B, 0x8E, 0xD3, 0x2C, 0x5D, - 0x86, 0x21, 0xE7, 0xF4, 0xF8, 0xE8, 0xA9, 0x33, - 0xD9, 0xEC, 0xC9, 0xDD, 0x1B, 0x83, 0x33, 0xCB, - 0xE2, 0x8C, 0xFC, 0x37, 0xD9, 0x71, 0x9E, 0x1C - }, - { - 0x7B, 0x4F, 0xA1, 0x58, 0xE4, 0x15, 0xFE, 0xF0, - 0x23, 0x24, 0x72, 0x64, 0xCB, 0xBE, 0x15, 0xD1, - 0x6D, 0x91, 0xA4, 0x44, 0x24, 0xA8, 0xDB, 0x70, - 0x7E, 0xB1, 0xE2, 0x03, 0x3C, 0x30, 0xE9, 0xE1, - 0xE7, 0xC8, 0xC0, 0x86, 0x45, 0x95, 0xD2, 0xCB, - 0x8C, 0x58, 0x0E, 0xB4, 0x7E, 0x9D, 0x16, 0xAB, - 0xBD, 0x7E, 0x44, 0xE8, 0x24, 0xF7, 0xCE, 0xDB, - 0x7D, 0xEF, 0x57, 0x13, 0x0E, 0x52, 0xCF, 0xE9 - }, - { - 0x60, 0x42, 0x4F, 0xF2, 0x32, 0x34, 0xC3, 0x4D, - 0xC9, 0x68, 0x7A, 0xD5, 0x02, 0x86, 0x93, 0x72, - 0xCC, 0x31, 0xA5, 0x93, 0x80, 0x18, 0x6B, 0xC2, - 0x36, 0x1C, 0x83, 0x5D, 0x97, 0x2F, 0x49, 0x66, - 0x6E, 0xB1, 0xAC, 0x69, 0x62, 0x9D, 0xE6, 0x46, - 0xF0, 0x3F, 0x9B, 0x4D, 0xB9, 0xE2, 0xAC, 0xE0, - 0x93, 0xFB, 0xFD, 0xF8, 0xF2, 0x0A, 0xB5, 0xF9, - 0x85, 0x41, 0x97, 0x8B, 0xE8, 0xEF, 0x54, 0x9F - }, - { - 0x74, 0x06, 0x01, 0x8C, 0xE7, 0x04, 0xD8, 0x4F, - 0x5E, 0xB9, 0xC7, 0x9F, 0xEA, 0x97, 0xDA, 0x34, - 0x56, 0x99, 0x46, 0x8A, 0x35, 0x0E, 0xE0, 0xB2, - 0xD0, 0xF3, 0xA4, 0xBF, 0x20, 0x70, 0x30, 0x4E, - 0xA8, 0x62, 0xD7, 0x2A, 0x51, 0xC5, 0x7D, 0x30, - 0x64, 0x94, 0x72, 0x86, 0xF5, 0x31, 0xE0, 0xEA, - 0xF7, 0x56, 0x37, 0x02, 0x26, 0x2E, 0x6C, 0x72, - 0x4A, 0xBF, 0x5E, 0xD8, 0xC8, 0x39, 0x8D, 0x17 - }, - { - 0x14, 0xEF, 0x5C, 0x6D, 0x64, 0x7B, 0x3B, 0xD1, - 0xE6, 0xE3, 0x20, 0x06, 0xC2, 0x31, 0x19, 0x98, - 0x10, 0xDE, 0x5C, 0x4D, 0xC8, 0x8E, 0x70, 0x24, - 0x02, 0x73, 0xB0, 0xEA, 0x18, 0xE6, 0x51, 0xA3, - 0xEB, 0x4F, 0x5C, 0xA3, 0x11, 0x4B, 0x8A, 0x56, - 0x71, 0x69, 0x69, 0xC7, 0xCD, 0xA2, 0x7E, 0x0C, - 0x8D, 0xB8, 0x32, 0xAD, 0x5E, 0x89, 0xA2, 0xDC, - 0x6C, 0xB0, 0xAD, 0xBE, 0x7D, 0x93, 0xAB, 0xD1 - }, - { - 0x38, 0xCF, 0x6C, 0x24, 0xE3, 0xE0, 0x8B, 0xCF, - 0x1F, 0x6C, 0xF3, 0xD1, 0xB1, 0xF6, 0x5B, 0x90, - 0x52, 0x39, 0xA3, 0x11, 0x80, 0x33, 0x24, 0x9E, - 0x44, 0x81, 0x13, 0xEC, 0x63, 0x2E, 0xA6, 0xDC, - 0x34, 0x6F, 0xEE, 0xB2, 0x57, 0x1C, 0x38, 0xBD, - 0x9A, 0x73, 0x98, 0xB2, 0x22, 0x12, 0x80, 0x32, - 0x80, 0x02, 0xB2, 0x3E, 0x1A, 0x45, 0xAD, 0xAF, - 0xFE, 0x66, 0xD9, 0x3F, 0x65, 0x64, 0xEA, 0xA2 - }, - { - 0x6C, 0xD7, 0x20, 0x8A, 0x4B, 0xC7, 0xE7, 0xE5, - 0x62, 0x01, 0xBB, 0xBA, 0x02, 0xA0, 0xF4, 0x89, - 0xCD, 0x38, 0x4A, 0xBE, 0x40, 0xAF, 0xD4, 0x22, - 0x2F, 0x15, 0x8B, 0x3D, 0x98, 0x6E, 0xE7, 0x2A, - 0x54, 0xC5, 0x0F, 0xB6, 0x4F, 0xD4, 0xED, 0x25, - 0x30, 0xED, 0xA2, 0xC8, 0xAF, 0x29, 0x28, 0xA0, - 0xDA, 0x6D, 0x4F, 0x83, 0x0A, 0xE1, 0xC9, 0xDB, - 0x46, 0x9D, 0xFD, 0x97, 0x0F, 0x12, 0xA5, 0x6F - }, - { - 0x65, 0x98, 0x58, 0xF0, 0xB5, 0xC9, 0xED, 0xAB, - 0x5B, 0x94, 0xFD, 0x73, 0x2F, 0x6E, 0x6B, 0x17, - 0xC5, 0x1C, 0xC0, 0x96, 0x10, 0x4F, 0x09, 0xBE, - 0xB3, 0xAF, 0xC3, 0xAA, 0x46, 0x7C, 0x2E, 0xCF, - 0x88, 0x5C, 0x4C, 0x65, 0x41, 0xEF, 0xFA, 0x90, - 0x23, 0xD3, 0xB5, 0x73, 0x8A, 0xE5, 0xA1, 0x4D, - 0x86, 0x7E, 0x15, 0xDB, 0x06, 0xFE, 0x1F, 0x9D, - 0x11, 0x27, 0xB7, 0x7E, 0x1A, 0xAB, 0xB5, 0x16 - }, - { - 0x26, 0xCC, 0xA0, 0x12, 0x6F, 0x5D, 0x1A, 0x81, - 0x3C, 0x62, 0xE5, 0xC7, 0x10, 0x01, 0xC0, 0x46, - 0xF9, 0xC9, 0x20, 0x95, 0x70, 0x45, 0x50, 0xBE, - 0x58, 0x73, 0xA4, 0x95, 0xA9, 0x99, 0xAD, 0x01, - 0x0A, 0x4F, 0x79, 0x49, 0x1F, 0x24, 0xF2, 0x86, - 0x50, 0x0A, 0xDC, 0xE1, 0xA1, 0x37, 0xBC, 0x20, - 0x84, 0xE4, 0x94, 0x9F, 0x5B, 0x72, 0x94, 0xCE, - 0xFE, 0x51, 0xEC, 0xAF, 0xF8, 0xE9, 0x5C, 0xBA - }, - { - 0x41, 0x47, 0xC1, 0xF5, 0x51, 0x72, 0x78, 0x8C, - 0x55, 0x67, 0xC5, 0x61, 0xFE, 0xEF, 0x87, 0x6F, - 0x62, 0x1F, 0xFF, 0x1C, 0xE8, 0x77, 0x86, 0xB8, - 0x46, 0x76, 0x37, 0xE7, 0x0D, 0xFB, 0xCD, 0x0D, - 0xBD, 0xB6, 0x41, 0x5C, 0xB6, 0x00, 0x95, 0x4A, - 0xB9, 0xC0, 0x4C, 0x0E, 0x45, 0x7E, 0x62, 0x5B, - 0x40, 0x72, 0x22, 0xC0, 0xFE, 0x1A, 0xE2, 0x1B, - 0x21, 0x43, 0x68, 0x8A, 0xDA, 0x94, 0xDC, 0x58 - }, - { - 0x5B, 0x1B, 0xF1, 0x54, 0xC6, 0x2A, 0x8A, 0xF6, - 0xE9, 0x3D, 0x35, 0xF1, 0x8F, 0x7F, 0x90, 0xAB, - 0xB1, 0x6A, 0x6E, 0xF0, 0xE8, 0xD1, 0xAE, 0xCD, - 0x11, 0x8B, 0xF7, 0x01, 0x67, 0xBA, 0xB2, 0xAF, - 0x08, 0x93, 0x5C, 0x6F, 0xDC, 0x06, 0x63, 0xCE, - 0x74, 0x48, 0x2D, 0x17, 0xA8, 0xE5, 0x4B, 0x54, - 0x6D, 0x1C, 0x29, 0x66, 0x31, 0xC6, 0x5F, 0x3B, - 0x52, 0x2A, 0x51, 0x58, 0x39, 0xD4, 0x3D, 0x71 - }, - { - 0x9F, 0x60, 0x04, 0x19, 0xA4, 0xE8, 0xF4, 0xFB, - 0x83, 0x4C, 0x24, 0xB0, 0xF7, 0xFC, 0x13, 0xBF, - 0x4E, 0x27, 0x9D, 0x98, 0xE8, 0xA3, 0xC7, 0x65, - 0xEE, 0x93, 0x49, 0x17, 0x40, 0x3E, 0x3A, 0x66, - 0x09, 0x71, 0x82, 0xEA, 0x21, 0x45, 0x3C, 0xB6, - 0x3E, 0xBB, 0xE8, 0xB7, 0x3A, 0x9C, 0x21, 0x67, - 0x59, 0x64, 0x46, 0x43, 0x8C, 0x57, 0x62, 0x7F, - 0x33, 0x0B, 0xAD, 0xD4, 0xF5, 0x69, 0xF7, 0xD6 - }, - { - 0x45, 0x7E, 0xF6, 0x46, 0x6A, 0x89, 0x24, 0xFD, - 0x80, 0x11, 0xA3, 0x44, 0x71, 0xA5, 0xA1, 0xAC, - 0x8C, 0xCD, 0x9B, 0xD0, 0xD0, 0x7A, 0x97, 0x41, - 0x4A, 0xC9, 0x43, 0x02, 0x1C, 0xE4, 0xB9, 0xE4, - 0xB9, 0xC8, 0xDB, 0x0A, 0x28, 0xF0, 0x16, 0xED, - 0x43, 0xB1, 0x54, 0x24, 0x81, 0x99, 0x00, 0x22, - 0x14, 0x7B, 0x31, 0x3E, 0x19, 0x46, 0x71, 0x13, - 0x1E, 0x70, 0x8D, 0xD4, 0x3A, 0x3E, 0xD7, 0xDC - }, - { - 0x99, 0x97, 0xB2, 0x19, 0x4D, 0x9A, 0xF6, 0xDF, - 0xCB, 0x91, 0x43, 0xF4, 0x1C, 0x0E, 0xD8, 0x3D, - 0x3A, 0x3F, 0x43, 0x88, 0x36, 0x11, 0x03, 0xD3, - 0x8C, 0x2A, 0x49, 0xB2, 0x80, 0xA5, 0x81, 0x21, - 0x27, 0x15, 0xFD, 0x90, 0x8D, 0x41, 0xC6, 0x51, - 0xF5, 0xC7, 0x15, 0xCA, 0x38, 0xC0, 0xCE, 0x28, - 0x30, 0xA3, 0x7E, 0x00, 0xE5, 0x08, 0xCE, 0xD1, - 0xBC, 0xDC, 0x32, 0x0E, 0x5E, 0x4D, 0x1E, 0x2E - }, - { - 0x5C, 0x6B, 0xBF, 0x16, 0xBA, 0xA1, 0x80, 0xF9, - 0x86, 0xBD, 0x40, 0xA1, 0x28, 0x7E, 0xD4, 0xC5, - 0x49, 0x77, 0x0E, 0x72, 0x84, 0x85, 0x8F, 0xC4, - 0x7B, 0xC2, 0x1A, 0xB9, 0x5E, 0xBB, 0xF3, 0x37, - 0x4B, 0x4E, 0xE3, 0xFD, 0x9F, 0x2A, 0xF6, 0x0F, - 0x33, 0x95, 0x22, 0x1B, 0x2A, 0xCC, 0x76, 0xF2, - 0xD3, 0x4C, 0x13, 0x29, 0x54, 0x04, 0x9F, 0x8A, - 0x3A, 0x99, 0x6F, 0x1E, 0x32, 0xEC, 0x84, 0xE5 - }, - { - 0xD1, 0x0B, 0xF9, 0xA1, 0x5B, 0x1C, 0x9F, 0xC8, - 0xD4, 0x1F, 0x89, 0xBB, 0x14, 0x0B, 0xF0, 0xBE, - 0x08, 0xD2, 0xF3, 0x66, 0x61, 0x76, 0xD1, 0x3B, - 0xAA, 0xC4, 0xD3, 0x81, 0x35, 0x8A, 0xD0, 0x74, - 0xC9, 0xD4, 0x74, 0x8C, 0x30, 0x05, 0x20, 0xEB, - 0x02, 0x6D, 0xAE, 0xAE, 0xA7, 0xC5, 0xB1, 0x58, - 0x89, 0x2F, 0xDE, 0x4E, 0x8E, 0xC1, 0x7D, 0xC9, - 0x98, 0xDC, 0xD5, 0x07, 0xDF, 0x26, 0xEB, 0x63 - }, - { - 0x2F, 0xC6, 0xE6, 0x9F, 0xA2, 0x6A, 0x89, 0xA5, - 0xED, 0x26, 0x90, 0x92, 0xCB, 0x9B, 0x2A, 0x44, - 0x9A, 0x44, 0x09, 0xA7, 0xA4, 0x40, 0x11, 0xEE, - 0xCA, 0xD1, 0x3D, 0x7C, 0x4B, 0x04, 0x56, 0x60, - 0x2D, 0x40, 0x2F, 0xA5, 0x84, 0x4F, 0x1A, 0x7A, - 0x75, 0x81, 0x36, 0xCE, 0x3D, 0x5D, 0x8D, 0x0E, - 0x8B, 0x86, 0x92, 0x1F, 0xFF, 0xF4, 0xF6, 0x92, - 0xDD, 0x95, 0xBD, 0xC8, 0xE5, 0xFF, 0x00, 0x52 - }, - { - 0xFC, 0xBE, 0x8B, 0xE7, 0xDC, 0xB4, 0x9A, 0x32, - 0xDB, 0xDF, 0x23, 0x94, 0x59, 0xE2, 0x63, 0x08, - 0xB8, 0x4D, 0xFF, 0x1E, 0xA4, 0x80, 0xDF, 0x8D, - 0x10, 0x4E, 0xEF, 0xF3, 0x4B, 0x46, 0xFA, 0xE9, - 0x86, 0x27, 0xB4, 0x50, 0xC2, 0x26, 0x7D, 0x48, - 0xC0, 0x94, 0x6A, 0x69, 0x7C, 0x5B, 0x59, 0x53, - 0x14, 0x52, 0xAC, 0x04, 0x84, 0xF1, 0xC8, 0x4E, - 0x3A, 0x33, 0xD0, 0xC3, 0x39, 0xBB, 0x2E, 0x28 - }, - { - 0xA1, 0x90, 0x93, 0xA6, 0xE3, 0xBC, 0xF5, 0x95, - 0x2F, 0x85, 0x0F, 0x20, 0x30, 0xF6, 0x9B, 0x96, - 0x06, 0xF1, 0x47, 0xF9, 0x0B, 0x8B, 0xAE, 0xE3, - 0x36, 0x2D, 0xA7, 0x1D, 0x9F, 0x35, 0xB4, 0x4E, - 0xF9, 0xD8, 0xF0, 0xA7, 0x71, 0x2B, 0xA1, 0x87, - 0x7F, 0xDD, 0xCD, 0x2D, 0x8E, 0xA8, 0xF1, 0xE5, - 0xA7, 0x73, 0xD0, 0xB7, 0x45, 0xD4, 0x72, 0x56, - 0x05, 0x98, 0x3A, 0x2D, 0xE9, 0x01, 0xF8, 0x03 - }, - { - 0x3C, 0x20, 0x06, 0x42, 0x3F, 0x73, 0xE2, 0x68, - 0xFA, 0x59, 0xD2, 0x92, 0x03, 0x77, 0xEB, 0x29, - 0xA4, 0xF9, 0xA8, 0xB4, 0x62, 0xBE, 0x15, 0x98, - 0x3E, 0xE3, 0xB8, 0x5A, 0xE8, 0xA7, 0x8E, 0x99, - 0x26, 0x33, 0x58, 0x1A, 0x90, 0x99, 0x89, 0x3B, - 0x63, 0xDB, 0x30, 0x24, 0x1C, 0x34, 0xF6, 0x43, - 0x02, 0x7D, 0xC8, 0x78, 0x27, 0x9A, 0xF5, 0x85, - 0x0D, 0x7E, 0x2D, 0x4A, 0x26, 0x53, 0x07, 0x3A - }, - { - 0xD0, 0xF2, 0xF2, 0xE3, 0x78, 0x76, 0x53, 0xF7, - 0x7C, 0xCE, 0x2F, 0xA2, 0x48, 0x35, 0x78, 0x5B, - 0xBD, 0x0C, 0x43, 0x3F, 0xC7, 0x79, 0x46, 0x5A, - 0x11, 0x51, 0x49, 0x90, 0x5A, 0x9D, 0xD1, 0xCB, - 0x82, 0x7A, 0x62, 0x85, 0x06, 0xD4, 0x57, 0xFC, - 0xF1, 0x24, 0xA0, 0xC2, 0xAE, 0xF9, 0xCE, 0x2D, - 0x2A, 0x0A, 0x0F, 0x63, 0x54, 0x55, 0x70, 0xD8, - 0x66, 0x7F, 0xF9, 0xE2, 0xEB, 0xA0, 0x73, 0x34 - }, - { - 0x78, 0xA9, 0xFC, 0x04, 0x8E, 0x25, 0xC6, 0xDC, - 0xB5, 0xDE, 0x45, 0x66, 0x7D, 0xE8, 0xFF, 0xDD, - 0x3A, 0x93, 0x71, 0x11, 0x41, 0xD5, 0x94, 0xE9, - 0xFA, 0x62, 0xA9, 0x59, 0x47, 0x5D, 0xA6, 0x07, - 0x5E, 0xA8, 0xF0, 0x91, 0x6E, 0x84, 0xE4, 0x5A, - 0xD9, 0x11, 0xB7, 0x54, 0x67, 0x07, 0x7E, 0xE5, - 0x2D, 0x2C, 0x9A, 0xEB, 0xF4, 0xD5, 0x8F, 0x20, - 0xCE, 0x4A, 0x3A, 0x00, 0x45, 0x8B, 0x05, 0xD4 - }, - { - 0x45, 0x81, 0x3F, 0x44, 0x17, 0x69, 0xAB, 0x6E, - 0xD3, 0x7D, 0x34, 0x9F, 0xF6, 0xE7, 0x22, 0x67, - 0xD7, 0x6A, 0xE6, 0xBB, 0x3E, 0x3C, 0x61, 0x2E, - 0xC0, 0x5C, 0x6E, 0x02, 0xA1, 0x2A, 0xF5, 0xA3, - 0x7C, 0x91, 0x8B, 0x52, 0xBF, 0x74, 0x26, 0x7C, - 0x3F, 0x6A, 0x3F, 0x18, 0x3A, 0x80, 0x64, 0xFF, - 0x84, 0xC0, 0x7B, 0x19, 0x3D, 0x08, 0x06, 0x67, - 0x89, 0xA0, 0x1A, 0xCC, 0xDB, 0x6F, 0x93, 0x40 - }, - { - 0x95, 0x6D, 0xA1, 0xC6, 0x8D, 0x83, 0xA7, 0xB8, - 0x81, 0xE0, 0x1B, 0x9A, 0x96, 0x6C, 0x3C, 0x0B, - 0xF2, 0x7F, 0x68, 0x60, 0x6A, 0x8B, 0x71, 0xD4, - 0x57, 0xBD, 0x01, 0x6D, 0x4C, 0x41, 0xDD, 0x8A, - 0x38, 0x0C, 0x70, 0x9A, 0x29, 0x6C, 0xB4, 0xC6, - 0x54, 0x47, 0x92, 0x92, 0x0F, 0xD7, 0x88, 0x83, - 0x57, 0x71, 0xA0, 0x7D, 0x4A, 0x16, 0xFB, 0x52, - 0xED, 0x48, 0x05, 0x03, 0x31, 0xDC, 0x4C, 0x8B - }, - { - 0xDF, 0x18, 0x6C, 0x2D, 0xC0, 0x9C, 0xAA, 0x48, - 0xE1, 0x4E, 0x94, 0x2F, 0x75, 0xDE, 0x5A, 0xC1, - 0xB7, 0xA2, 0x1E, 0x4F, 0x9F, 0x07, 0x2A, 0x5B, - 0x37, 0x1E, 0x09, 0xE0, 0x73, 0x45, 0xB0, 0x74, - 0x0C, 0x76, 0x17, 0x7B, 0x01, 0x27, 0x88, 0x08, - 0xFE, 0xC0, 0x25, 0xED, 0xED, 0x98, 0x22, 0xC1, - 0x22, 0xAF, 0xD1, 0xC6, 0x3E, 0x6F, 0x0C, 0xE2, - 0xE3, 0x26, 0x31, 0x04, 0x10, 0x63, 0x14, 0x5C - }, - { - 0x87, 0x47, 0x56, 0x40, 0x96, 0x6A, 0x9F, 0xDC, - 0xD6, 0xD3, 0xA3, 0xB5, 0xA2, 0xCC, 0xA5, 0xC0, - 0x8F, 0x0D, 0x88, 0x2B, 0x10, 0x24, 0x3C, 0x0E, - 0xC1, 0xBF, 0x3C, 0x6B, 0x1C, 0x37, 0xF2, 0xCD, - 0x32, 0x12, 0xF1, 0x9A, 0x05, 0x78, 0x64, 0x47, - 0x7D, 0x5E, 0xAF, 0x8F, 0xAE, 0xD7, 0x3F, 0x29, - 0x37, 0xC7, 0x68, 0xA0, 0xAF, 0x41, 0x5E, 0x84, - 0xBB, 0xCE, 0x6B, 0xD7, 0xDE, 0x23, 0xB6, 0x60 - }, - { - 0xC3, 0xB5, 0x73, 0xBB, 0xE1, 0x09, 0x49, 0xA0, - 0xFB, 0xD4, 0xFF, 0x88, 0x4C, 0x44, 0x6F, 0x22, - 0x29, 0xB7, 0x69, 0x02, 0xF9, 0xDF, 0xDB, 0xB8, - 0xA0, 0x35, 0x3D, 0xA5, 0xC8, 0x3C, 0xA1, 0x4E, - 0x81, 0x51, 0xBB, 0xAA, 0xC8, 0x2F, 0xD1, 0x57, - 0x6A, 0x00, 0x9A, 0xDC, 0x6F, 0x19, 0x35, 0xCF, - 0x26, 0xED, 0xD4, 0xF1, 0xFB, 0x8D, 0xA4, 0x83, - 0xE6, 0xC5, 0xCD, 0x9D, 0x89, 0x23, 0xAD, 0xC3 - }, - { - 0xB0, 0x9D, 0x8D, 0x0B, 0xBA, 0x8A, 0x72, 0x86, - 0xE4, 0x35, 0x68, 0xF7, 0x90, 0x75, 0x50, 0xE4, - 0x20, 0x36, 0xD6, 0x74, 0xE3, 0xC8, 0xFC, 0x34, - 0xD8, 0xCA, 0x46, 0xF7, 0x71, 0xD6, 0x46, 0x6B, - 0x70, 0xFB, 0x60, 0x58, 0x75, 0xF6, 0xA8, 0x63, - 0xC8, 0x77, 0xD1, 0x2F, 0x07, 0x06, 0x3F, 0xDC, - 0x2E, 0x90, 0xCC, 0xD4, 0x59, 0xB1, 0x91, 0x0D, - 0xCD, 0x52, 0xD8, 0xF1, 0x0B, 0x2B, 0x0A, 0x15 - }, - { - 0xAF, 0x3A, 0x22, 0xBF, 0x75, 0xB2, 0x1A, 0xBF, - 0xB0, 0xAC, 0xD5, 0x44, 0x22, 0xBA, 0x1B, 0x73, - 0x00, 0xA9, 0x52, 0xEF, 0xF0, 0x2E, 0xBE, 0xB6, - 0x5B, 0x5C, 0x23, 0x44, 0x71, 0xA9, 0x8D, 0xF3, - 0x2F, 0x4F, 0x96, 0x43, 0xCE, 0x19, 0x04, 0x10, - 0x8A, 0x16, 0x87, 0x67, 0x92, 0x42, 0x80, 0xBD, - 0x76, 0xC8, 0x3F, 0x8C, 0x82, 0xD9, 0xA7, 0x9D, - 0x92, 0x59, 0xB1, 0x95, 0x36, 0x2A, 0x2A, 0x04 - }, - { - 0xBF, 0x4F, 0xF2, 0x22, 0x1B, 0x7E, 0x69, 0x57, - 0xA7, 0x24, 0xCD, 0x96, 0x4A, 0xA3, 0xD5, 0xD0, - 0xD9, 0x94, 0x1F, 0x54, 0x04, 0x13, 0x75, 0x2F, - 0x46, 0x99, 0xD8, 0x10, 0x1B, 0x3E, 0x53, 0x75, - 0x08, 0xBF, 0x09, 0xF8, 0x50, 0x8B, 0x31, 0x77, - 0x36, 0xFF, 0xD2, 0x65, 0xF2, 0x84, 0x7A, 0xA7, - 0xD8, 0x4B, 0xD2, 0xD9, 0x75, 0x69, 0xC4, 0x9D, - 0x63, 0x2A, 0xED, 0x99, 0x45, 0xE5, 0xFA, 0x5E - }, - { - 0x9C, 0x6B, 0x6B, 0x78, 0x19, 0x9B, 0x1B, 0xDA, - 0xCB, 0x43, 0x00, 0xE3, 0x14, 0x79, 0xFA, 0x62, - 0x2A, 0x6B, 0x5B, 0xC8, 0x0D, 0x46, 0x78, 0xA6, - 0x07, 0x8F, 0x88, 0xA8, 0x26, 0x8C, 0xD7, 0x20, - 0x6A, 0x27, 0x99, 0xE8, 0xD4, 0x62, 0x1A, 0x46, - 0x4E, 0xF6, 0xB4, 0x3D, 0xD8, 0xAD, 0xFF, 0xE9, - 0x7C, 0xAF, 0x22, 0x1B, 0x22, 0xB6, 0xB8, 0x77, - 0x8B, 0x14, 0x9A, 0x82, 0x2A, 0xEF, 0xBB, 0x09 - }, - { - 0x89, 0x06, 0x56, 0xF0, 0x9C, 0x99, 0xD2, 0x80, - 0xB5, 0xEC, 0xB3, 0x81, 0xF5, 0x64, 0x27, 0xB8, - 0x13, 0x75, 0x1B, 0xC6, 0x52, 0xC7, 0x82, 0x80, - 0x78, 0xB2, 0x3A, 0x4A, 0xF8, 0x3B, 0x4E, 0x3A, - 0x61, 0xFD, 0xBA, 0xC6, 0x1F, 0x89, 0xBE, 0xE8, - 0x4E, 0xA6, 0xBE, 0xE7, 0x60, 0xC0, 0x47, 0xF2, - 0x5C, 0x6B, 0x0A, 0x20, 0x1C, 0x69, 0xA3, 0x8F, - 0xD6, 0xFD, 0x97, 0x1A, 0xF1, 0x85, 0x88, 0xBB - }, - { - 0x31, 0xA0, 0x46, 0xF7, 0x88, 0x2F, 0xFE, 0x6F, - 0x83, 0xCE, 0x47, 0x2E, 0x9A, 0x07, 0x01, 0x83, - 0x2E, 0xC7, 0xB3, 0xF7, 0x6F, 0xBC, 0xFD, 0x1D, - 0xF6, 0x0F, 0xE3, 0xEA, 0x48, 0xFD, 0xE1, 0x65, - 0x12, 0x54, 0x24, 0x7C, 0x3F, 0xD9, 0x5E, 0x10, - 0x0F, 0x91, 0x72, 0x73, 0x1E, 0x17, 0xFD, 0x52, - 0x97, 0xC1, 0x1F, 0x4B, 0xB3, 0x28, 0x36, 0x3C, - 0xA3, 0x61, 0x62, 0x4A, 0x81, 0xAF, 0x79, 0x7C - }, - { - 0x27, 0xA6, 0x0B, 0x2D, 0x00, 0xE7, 0xA6, 0x71, - 0xD4, 0x7D, 0x0A, 0xEC, 0x2A, 0x68, 0x6A, 0x0A, - 0xC0, 0x4B, 0x52, 0xF4, 0x0A, 0xB6, 0x62, 0x90, - 0x28, 0xEB, 0x7D, 0x13, 0xF4, 0xBA, 0xA9, 0x9A, - 0xC0, 0xFE, 0x46, 0xEE, 0x6C, 0x81, 0x49, 0x44, - 0xF2, 0xF4, 0xB4, 0xD2, 0x0E, 0x93, 0x78, 0xE4, - 0x84, 0x7E, 0xA4, 0x4C, 0x13, 0x17, 0x80, 0x91, - 0xE2, 0x77, 0xB8, 0x7E, 0xA7, 0xA5, 0x57, 0x11 - }, - { - 0x8B, 0x5C, 0xCE, 0xF1, 0x94, 0x16, 0x2C, 0x1F, - 0x19, 0xD6, 0x8F, 0x91, 0xE0, 0xB0, 0x92, 0x8F, - 0x28, 0x9E, 0xC5, 0x28, 0x37, 0x20, 0x84, 0x0C, - 0x2F, 0x73, 0xD2, 0x53, 0x11, 0x12, 0x38, 0xDC, - 0xFE, 0x94, 0xAF, 0x2B, 0x59, 0xC2, 0xC1, 0xCA, - 0x25, 0x91, 0x90, 0x1A, 0x7B, 0xC0, 0x60, 0xE7, - 0x45, 0x9B, 0x6C, 0x47, 0xDF, 0x0F, 0x71, 0x70, - 0x1A, 0x35, 0xCC, 0x0A, 0xA8, 0x31, 0xB5, 0xB6 - }, - { - 0x57, 0xAB, 0x6C, 0x4B, 0x22, 0x29, 0xAE, 0xB3, - 0xB7, 0x04, 0x76, 0xD8, 0x03, 0xCD, 0x63, 0x81, - 0x2F, 0x10, 0x7C, 0xE6, 0xDA, 0x17, 0xFE, 0xD9, - 0xB1, 0x78, 0x75, 0xE8, 0xF8, 0x6C, 0x72, 0x4F, - 0x49, 0xE0, 0x24, 0xCB, 0xF3, 0xA1, 0xB8, 0xB1, - 0x19, 0xC5, 0x03, 0x57, 0x65, 0x2B, 0x81, 0x87, - 0x9D, 0x2A, 0xDE, 0x2D, 0x58, 0x8B, 0x9E, 0x4F, - 0x7C, 0xED, 0xBA, 0x0E, 0x46, 0x44, 0xC9, 0xEE - }, - { - 0x01, 0x90, 0xA8, 0xDA, 0xC3, 0x20, 0xA7, 0x39, - 0xF3, 0x22, 0xE1, 0x57, 0x31, 0xAA, 0x14, 0x0D, - 0xDA, 0xF5, 0xBE, 0xD2, 0x94, 0xD5, 0xC8, 0x2E, - 0x54, 0xFE, 0xF2, 0x9F, 0x21, 0x4E, 0x18, 0xAA, - 0xFA, 0xA8, 0x4F, 0x8B, 0xE9, 0x9A, 0xF6, 0x29, - 0x50, 0x26, 0x6B, 0x8F, 0x90, 0x1F, 0x15, 0xDD, - 0x4C, 0x5D, 0x35, 0x51, 0x6F, 0xC3, 0x5B, 0x4C, - 0xAB, 0x2E, 0x96, 0xE4, 0x69, 0x5B, 0xBE, 0x1C - }, - { - 0xD1, 0x4D, 0x7C, 0x4C, 0x41, 0x5E, 0xEB, 0x0E, - 0x10, 0xB1, 0x59, 0x22, 0x4B, 0xEA, 0x12, 0x7E, - 0xBD, 0x84, 0xF9, 0x59, 0x1C, 0x70, 0x2A, 0x33, - 0x0F, 0x5B, 0xB7, 0xBB, 0x7A, 0xA4, 0x4E, 0xA3, - 0x9D, 0xE6, 0xED, 0x01, 0xF1, 0x8D, 0xA7, 0xAD, - 0xF4, 0x0C, 0xFB, 0x97, 0xC5, 0xD1, 0x52, 0xC2, - 0x75, 0x28, 0x82, 0x4B, 0x21, 0xE2, 0x39, 0x52, - 0x6A, 0xF8, 0xF3, 0x6B, 0x21, 0x4E, 0x0C, 0xFB - }, - { - 0xBE, 0x28, 0xC4, 0xBE, 0x70, 0x69, 0x70, 0x48, - 0x8F, 0xAC, 0x7D, 0x29, 0xC3, 0xBD, 0x5C, 0x4E, - 0x98, 0x60, 0x85, 0xC4, 0xC3, 0x33, 0x2F, 0x1F, - 0x3F, 0xD3, 0x09, 0x73, 0xDB, 0x61, 0x41, 0x64, - 0xBA, 0x2F, 0x31, 0xA7, 0x88, 0x75, 0xFF, 0xDC, - 0x15, 0x03, 0x25, 0xC8, 0x83, 0x27, 0xA9, 0x44, - 0x3E, 0xD0, 0x4F, 0xDF, 0xE5, 0xBE, 0x93, 0x87, - 0x6D, 0x16, 0x28, 0x56, 0x0C, 0x76, 0x4A, 0x80 - }, - { - 0x03, 0x1D, 0xA1, 0x06, 0x9E, 0x3A, 0x2E, 0x9C, - 0x33, 0x82, 0xE4, 0x36, 0xFF, 0xD7, 0x9D, 0xF7, - 0x4B, 0x1C, 0xA6, 0xA8, 0xAD, 0xB2, 0xDE, 0xAB, - 0xE6, 0x76, 0xAB, 0x45, 0x99, 0x4C, 0xBC, 0x05, - 0x4F, 0x03, 0x7D, 0x2F, 0x0E, 0xAC, 0xE8, 0x58, - 0xD3, 0x2C, 0x14, 0xE2, 0xD1, 0xC8, 0xB4, 0x60, - 0x77, 0x30, 0x8E, 0x3B, 0xDC, 0x2C, 0x1B, 0x53, - 0x17, 0x2E, 0xCF, 0x7A, 0x8C, 0x14, 0xE3, 0x49 - }, - { - 0x46, 0x65, 0xCE, 0xF8, 0xBA, 0x4D, 0xB4, 0xD0, - 0xAC, 0xB1, 0x18, 0xF2, 0x98, 0x7F, 0x0B, 0xB0, - 0x9F, 0x8F, 0x86, 0xAA, 0x44, 0x5A, 0xA3, 0xD5, - 0xFC, 0x9A, 0x8B, 0x34, 0x68, 0x64, 0x78, 0x74, - 0x89, 0xE8, 0xFC, 0xEC, 0xC1, 0x25, 0xD1, 0x7E, - 0x9B, 0x56, 0xE1, 0x29, 0x88, 0xEA, 0xC5, 0xEC, - 0xC7, 0x28, 0x68, 0x83, 0xDB, 0x06, 0x61, 0xB8, - 0xFF, 0x05, 0xDA, 0x2A, 0xFF, 0xF3, 0x0F, 0xE4 - }, - { - 0x63, 0xB7, 0x03, 0x2E, 0x5F, 0x93, 0x0C, 0xC9, - 0x93, 0x95, 0x17, 0xF9, 0xE9, 0x86, 0x81, 0x6C, - 0xFB, 0xEC, 0x2B, 0xE5, 0x9B, 0x95, 0x68, 0xB1, - 0x3F, 0x2E, 0xAD, 0x05, 0xBA, 0xE7, 0x77, 0x7C, - 0xAB, 0x62, 0x0C, 0x66, 0x59, 0x40, 0x4F, 0x74, - 0x09, 0xE4, 0x19, 0x9A, 0x3B, 0xE5, 0xF7, 0x86, - 0x5A, 0xA7, 0xCB, 0xDF, 0x8C, 0x42, 0x53, 0xF7, - 0xE8, 0x21, 0x9B, 0x1B, 0xD5, 0xF4, 0x6F, 0xEA - }, - { - 0x9F, 0x09, 0xBF, 0x09, 0x3A, 0x2B, 0x0F, 0xF8, - 0xC2, 0x63, 0x4B, 0x49, 0xE3, 0x7F, 0x1B, 0x21, - 0x35, 0xB4, 0x47, 0xAA, 0x91, 0x44, 0xC9, 0x78, - 0x7D, 0xBF, 0xD9, 0x21, 0x29, 0x31, 0x6C, 0x99, - 0xE8, 0x8A, 0xAB, 0x8A, 0x21, 0xFD, 0xEF, 0x23, - 0x72, 0xD1, 0x18, 0x9A, 0xEC, 0x50, 0x0F, 0x95, - 0x77, 0x5F, 0x1F, 0x92, 0xBF, 0xB4, 0x55, 0x45, - 0xE4, 0x25, 0x9F, 0xB9, 0xB7, 0xB0, 0x2D, 0x14 - }, - { - 0xF9, 0xF8, 0x49, 0x3C, 0x68, 0x08, 0x88, 0x07, - 0xDF, 0x7F, 0x6A, 0x26, 0x93, 0xD6, 0x4E, 0xA5, - 0x9F, 0x03, 0xE9, 0xE0, 0x5A, 0x22, 0x3E, 0x68, - 0x52, 0x4C, 0xA3, 0x21, 0x95, 0xA4, 0x73, 0x4B, - 0x65, 0x4F, 0xCE, 0xA4, 0xD2, 0x73, 0x4C, 0x86, - 0x6C, 0xF9, 0x5C, 0x88, 0x9F, 0xB1, 0x0C, 0x49, - 0x15, 0x9B, 0xE2, 0xF5, 0x04, 0x3D, 0xC9, 0x8B, - 0xB5, 0x5E, 0x02, 0xEF, 0x7B, 0xDC, 0xB0, 0x82 - }, - { - 0x3C, 0x9A, 0x73, 0x59, 0xAB, 0x4F, 0xEB, 0xCE, - 0x07, 0xB2, 0x0A, 0xC4, 0x47, 0xB0, 0x6A, 0x24, - 0x0B, 0x7F, 0xE1, 0xDA, 0xE5, 0x43, 0x9C, 0x49, - 0xB6, 0x0B, 0x58, 0x19, 0xF7, 0x81, 0x2E, 0x4C, - 0x17, 0x24, 0x06, 0xC1, 0xAA, 0xC3, 0x16, 0x71, - 0x3C, 0xF0, 0xDD, 0xED, 0x10, 0x38, 0x07, 0x72, - 0x58, 0xE2, 0xEF, 0xF5, 0xB3, 0x39, 0x13, 0xD9, - 0xD9, 0x5C, 0xAE, 0xB4, 0xE6, 0xC6, 0xB9, 0x70 - }, - { - 0xAD, 0x6A, 0xAB, 0x80, 0x84, 0x51, 0x0E, 0x82, - 0x2C, 0xFC, 0xE8, 0x62, 0x5D, 0x62, 0xCF, 0x4D, - 0xE6, 0x55, 0xF4, 0x76, 0x38, 0x84, 0xC7, 0x1E, - 0x80, 0xBA, 0xB9, 0xAC, 0x9D, 0x53, 0x18, 0xDB, - 0xA4, 0xA6, 0x03, 0x3E, 0xD2, 0x90, 0x84, 0xE6, - 0x52, 0x16, 0xC0, 0x31, 0x60, 0x6C, 0xA1, 0x76, - 0x15, 0xDC, 0xFE, 0x3B, 0xA1, 0x1D, 0x26, 0x85, - 0x1A, 0xE0, 0x99, 0x9C, 0xA6, 0xE2, 0x32, 0xCF - }, - { - 0x15, 0x6E, 0x9E, 0x62, 0x61, 0x37, 0x4C, 0x9D, - 0xC8, 0x84, 0xF3, 0x6E, 0x70, 0xF0, 0xFE, 0x1A, - 0xB9, 0x29, 0x79, 0x97, 0xB8, 0x36, 0xFA, 0x7D, - 0x17, 0x0A, 0x9C, 0x9E, 0xBF, 0x57, 0x5B, 0x88, - 0x1E, 0x7B, 0xCE, 0xA4, 0x4D, 0x6C, 0x02, 0x48, - 0xD3, 0x55, 0x97, 0x90, 0x71, 0x54, 0x82, 0x89, - 0x55, 0xBE, 0x19, 0x13, 0x58, 0x52, 0xF9, 0x22, - 0x88, 0x15, 0xEC, 0xA0, 0x24, 0xA8, 0xAD, 0xFB - }, - { - 0x42, 0x15, 0x40, 0x76, 0x33, 0xF4, 0xCC, 0xA9, - 0xB6, 0x78, 0x8B, 0xE9, 0x3E, 0x6A, 0xA3, 0xD9, - 0x63, 0xC7, 0xD6, 0xCE, 0x4B, 0x14, 0x72, 0x47, - 0x09, 0x9F, 0x46, 0xA3, 0xAC, 0xB5, 0x00, 0xA3, - 0x00, 0x38, 0xCB, 0x3E, 0x78, 0x8C, 0x3D, 0x29, - 0xF1, 0x32, 0xAD, 0x84, 0x4E, 0x80, 0xE9, 0xE9, - 0x92, 0x51, 0xF6, 0xDB, 0x96, 0xAC, 0xD8, 0xA0, - 0x91, 0xCF, 0xC7, 0x70, 0xAF, 0x53, 0x84, 0x7B - }, - { - 0x1C, 0x07, 0x7E, 0x27, 0x9D, 0xE6, 0x54, 0x85, - 0x23, 0x50, 0x2B, 0x6D, 0xF8, 0x00, 0xFF, 0xDA, - 0xB5, 0xE2, 0xC3, 0xE9, 0x44, 0x2E, 0xB8, 0x38, - 0xF5, 0x8C, 0x29, 0x5F, 0x3B, 0x14, 0x7C, 0xEF, - 0x9D, 0x70, 0x1C, 0x41, 0xC3, 0x21, 0x28, 0x3F, - 0x00, 0xC7, 0x1A, 0xFF, 0xA0, 0x61, 0x93, 0x10, - 0x39, 0x91, 0x26, 0x29, 0x5B, 0x78, 0xDD, 0x4D, - 0x1A, 0x74, 0x57, 0x2E, 0xF9, 0xED, 0x51, 0x35 - }, - { - 0xF0, 0x7A, 0x55, 0x5F, 0x49, 0xFE, 0x48, 0x1C, - 0xF4, 0xCD, 0x0A, 0x87, 0xB7, 0x1B, 0x82, 0xE4, - 0xA9, 0x50, 0x64, 0xD0, 0x66, 0x77, 0xFD, 0xD9, - 0x0A, 0x0E, 0xB5, 0x98, 0x87, 0x7B, 0xA1, 0xC8, - 0x3D, 0x46, 0x77, 0xB3, 0x93, 0xC3, 0xA3, 0xB6, - 0x66, 0x1C, 0x42, 0x1F, 0x5B, 0x12, 0xCB, 0x99, - 0xD2, 0x03, 0x76, 0xBA, 0x72, 0x75, 0xC2, 0xF3, - 0xA8, 0xF5, 0xA9, 0xB7, 0x82, 0x17, 0x20, 0xDA - }, - { - 0xB5, 0x91, 0x1B, 0x38, 0x0D, 0x20, 0xC7, 0xB0, - 0x43, 0x23, 0xE4, 0x02, 0x6B, 0x38, 0xE2, 0x00, - 0xF5, 0x34, 0x25, 0x92, 0x33, 0xB5, 0x81, 0xE0, - 0x2C, 0x1E, 0x3E, 0x2D, 0x84, 0x38, 0xD6, 0xC6, - 0x6D, 0x5A, 0x4E, 0xB2, 0x01, 0xD5, 0xA8, 0xB7, - 0x50, 0x72, 0xC4, 0xEC, 0x29, 0x10, 0x63, 0x34, - 0xDA, 0x70, 0xBC, 0x79, 0x52, 0x1B, 0x0C, 0xED, - 0x2C, 0xFD, 0x53, 0x3F, 0x5F, 0xF8, 0x4F, 0x95 - }, - { - 0x01, 0xF0, 0x70, 0xA0, 0x9B, 0xAE, 0x91, 0x12, - 0x96, 0x36, 0x1F, 0x91, 0xAA, 0x0E, 0x8E, 0x0D, - 0x09, 0xA7, 0x72, 0x54, 0x78, 0x53, 0x6D, 0x9D, - 0x48, 0xC5, 0xFE, 0x1E, 0x5E, 0x7C, 0x3C, 0x5B, - 0x9B, 0x9D, 0x6E, 0xB0, 0x77, 0x96, 0xF6, 0xDA, - 0x57, 0xAE, 0x56, 0x2A, 0x7D, 0x70, 0xE8, 0x82, - 0xE3, 0x7A, 0xDF, 0xDE, 0x83, 0xF0, 0xC4, 0x33, - 0xC2, 0xCD, 0x36, 0x35, 0x36, 0xBB, 0x22, 0xC8 - }, - { - 0x6F, 0x79, 0x3E, 0xB4, 0x37, 0x4A, 0x48, 0xB0, - 0x77, 0x5A, 0xCA, 0xF9, 0xAD, 0xCF, 0x8E, 0x45, - 0xE5, 0x42, 0x70, 0xC9, 0x47, 0x5F, 0x00, 0x4A, - 0xD8, 0xD5, 0x97, 0x3E, 0x2A, 0xCA, 0x52, 0x74, - 0x7F, 0xF4, 0xED, 0x04, 0xAE, 0x96, 0x72, 0x75, - 0xB9, 0xF9, 0xEB, 0x0E, 0x1F, 0xF7, 0x5F, 0xB4, - 0xF7, 0x94, 0xFA, 0x8B, 0xE9, 0xAD, 0xD7, 0xA4, - 0x13, 0x04, 0x86, 0x8D, 0x10, 0x3F, 0xAB, 0x10 - }, - { - 0x96, 0x5F, 0x20, 0xF1, 0x39, 0x76, 0x5F, 0xCC, - 0x4C, 0xE4, 0xBA, 0x37, 0x94, 0x67, 0x58, 0x63, - 0xCA, 0xC2, 0x4D, 0xB4, 0x72, 0xCD, 0x2B, 0x79, - 0x9D, 0x03, 0x5B, 0xCE, 0x3D, 0xBE, 0xA5, 0x02, - 0xDA, 0x7B, 0x52, 0x48, 0x65, 0xF6, 0xB8, 0x11, - 0xD8, 0xC5, 0x82, 0x8D, 0x3A, 0x88, 0x96, 0x46, - 0xFE, 0x64, 0xA3, 0x80, 0xDA, 0x1A, 0xA7, 0xC7, - 0x04, 0x4E, 0x9F, 0x24, 0x5D, 0xCE, 0xD1, 0x28 - }, - { - 0xEC, 0x29, 0x5B, 0x57, 0x83, 0x60, 0x12, 0x44, - 0xC3, 0x0E, 0x46, 0x41, 0xE3, 0xB4, 0x5B, 0xE2, - 0x22, 0xC4, 0xDC, 0xE7, 0x7A, 0x58, 0x70, 0x0F, - 0x53, 0xBC, 0x8E, 0xC5, 0x2A, 0x94, 0x16, 0x90, - 0xB4, 0xD0, 0xB0, 0x87, 0xFB, 0x6F, 0xCB, 0x3F, - 0x39, 0x83, 0x2B, 0x9D, 0xE8, 0xF7, 0x5E, 0xC2, - 0x0B, 0xD4, 0x30, 0x79, 0x81, 0x17, 0x49, 0xCD, - 0xC9, 0x07, 0xED, 0xB9, 0x41, 0x57, 0xD1, 0x80 - }, - { - 0x61, 0xC7, 0x2F, 0x8C, 0xCC, 0x91, 0xDB, 0xB5, - 0x4C, 0xA6, 0x75, 0x0B, 0xC4, 0x89, 0x67, 0x2D, - 0xE0, 0x9F, 0xAE, 0xDB, 0x8F, 0xDD, 0x4F, 0x94, - 0xFF, 0x23, 0x20, 0x90, 0x9A, 0x30, 0x3F, 0x5D, - 0x5A, 0x98, 0x48, 0x1C, 0x0B, 0xC1, 0xA6, 0x25, - 0x41, 0x9F, 0xB4, 0xDE, 0xBF, 0xBF, 0x7F, 0x8A, - 0x53, 0xBB, 0x07, 0xEC, 0x3D, 0x98, 0x5E, 0x8E, - 0xA1, 0x1E, 0x72, 0xD5, 0x59, 0x94, 0x07, 0x80 - }, - { - 0xAF, 0xD8, 0x14, 0x5B, 0x25, 0x9E, 0xEF, 0xC8, - 0xD1, 0x26, 0x20, 0xC3, 0xC5, 0xB0, 0x3E, 0x1E, - 0xD8, 0xFD, 0x2C, 0xCE, 0xFE, 0x03, 0x65, 0x07, - 0x8C, 0x80, 0xFD, 0x42, 0xC1, 0x77, 0x0E, 0x28, - 0xB4, 0x49, 0x48, 0xF2, 0x7E, 0x65, 0xA1, 0x88, - 0x66, 0x90, 0x11, 0x0D, 0xB8, 0x14, 0x39, 0x7B, - 0x68, 0xE4, 0x3D, 0x80, 0xD1, 0xBA, 0x16, 0xDF, - 0xA3, 0x58, 0xE7, 0x39, 0xC8, 0x98, 0xCF, 0xA3 - }, - { - 0x55, 0x2F, 0xC7, 0x89, 0x3C, 0xF1, 0xCE, 0x93, - 0x3A, 0xDA, 0x35, 0xC0, 0xDA, 0x98, 0x84, 0x4E, - 0x41, 0x54, 0x5E, 0x24, 0x4C, 0x31, 0x57, 0xA1, - 0x42, 0x8D, 0x7B, 0x4C, 0x21, 0xF9, 0xCD, 0x7E, - 0x40, 0x71, 0xAE, 0xD7, 0x7B, 0x7C, 0xA9, 0xF1, - 0xC3, 0x8F, 0xBA, 0x32, 0x23, 0x74, 0x12, 0xEF, - 0x21, 0xA3, 0x42, 0x74, 0x2E, 0xC8, 0x32, 0x43, - 0x78, 0xF2, 0x1E, 0x50, 0x7F, 0xAF, 0xDD, 0x88 - }, - { - 0x46, 0x7A, 0x33, 0xFB, 0xAD, 0xF5, 0xEB, 0xC5, - 0x25, 0x96, 0xEF, 0x86, 0xAA, 0xAE, 0xFC, 0x6F, - 0xAB, 0xA8, 0xEE, 0x65, 0x1B, 0x1C, 0xE0, 0x4D, - 0xE3, 0x68, 0xA0, 0x3A, 0x5A, 0x90, 0x40, 0xEF, - 0x28, 0x35, 0xE0, 0x0A, 0xDB, 0x09, 0xAB, 0xB3, - 0xFB, 0xD2, 0xBC, 0xE8, 0x18, 0xA2, 0x41, 0x3D, - 0x0B, 0x02, 0x53, 0xB5, 0xBD, 0xA4, 0xFC, 0x5B, - 0x2F, 0x6F, 0x85, 0xF3, 0xFD, 0x5B, 0x55, 0xF2 - }, - { - 0x22, 0xEF, 0xF8, 0xE6, 0xDD, 0x52, 0x36, 0xF5, - 0xF5, 0x7D, 0x94, 0xED, 0xE8, 0x74, 0xD6, 0xC9, - 0x42, 0x8E, 0x8F, 0x5D, 0x56, 0x6F, 0x17, 0xCD, - 0x6D, 0x18, 0x48, 0xCD, 0x75, 0x2F, 0xE1, 0x3C, - 0x65, 0x5C, 0xB1, 0x0F, 0xBA, 0xAF, 0xF7, 0x68, - 0x72, 0xF2, 0xBF, 0x2D, 0xA9, 0x9E, 0x15, 0xDC, - 0x62, 0x40, 0x75, 0xE1, 0xEC, 0x2F, 0x58, 0xA3, - 0xF6, 0x40, 0x72, 0x12, 0x18, 0x38, 0x56, 0x9E - }, - { - 0x9C, 0xEC, 0x6B, 0xBF, 0x62, 0xC4, 0xBC, 0xE4, - 0x13, 0x8A, 0xBA, 0xE1, 0xCB, 0xEC, 0x8D, 0xAD, - 0x31, 0x95, 0x04, 0x44, 0xE9, 0x03, 0x21, 0xB1, - 0x34, 0x71, 0x96, 0x83, 0x4C, 0x11, 0x4B, 0x86, - 0x4A, 0xF3, 0xF3, 0xCC, 0x35, 0x08, 0xF8, 0x37, - 0x51, 0xFF, 0xB4, 0xED, 0xA7, 0xC8, 0x4D, 0x14, - 0x07, 0x34, 0xBB, 0x42, 0x63, 0xC3, 0x62, 0x5C, - 0x00, 0xF0, 0x4F, 0x4C, 0x80, 0x68, 0x98, 0x1B - }, - { - 0xA8, 0xB6, 0x0F, 0xA4, 0xFC, 0x24, 0x42, 0xF6, - 0xF1, 0x51, 0x4A, 0xD7, 0x40, 0x26, 0x26, 0x92, - 0x0C, 0xC7, 0xC2, 0xC9, 0xF7, 0x21, 0x24, 0xB8, - 0xCB, 0xA8, 0xEE, 0x2C, 0xB7, 0xC4, 0x58, 0x6F, - 0x65, 0x8A, 0x44, 0x10, 0xCF, 0xFC, 0xC0, 0xAB, - 0x88, 0x34, 0x39, 0x55, 0xE0, 0x94, 0xC6, 0xAF, - 0x0D, 0x20, 0xD0, 0xC7, 0x14, 0xFB, 0x0A, 0x98, - 0x8F, 0x54, 0x3F, 0x30, 0x0F, 0x58, 0xD3, 0x89 - }, - { - 0x82, 0x71, 0xCC, 0x45, 0xDF, 0xA5, 0xE4, 0x17, - 0x0E, 0x84, 0x7E, 0x86, 0x30, 0xB9, 0x52, 0xCF, - 0x9C, 0x2A, 0xA7, 0x77, 0xD0, 0x6F, 0x26, 0xA7, - 0x58, 0x5B, 0x83, 0x81, 0xF1, 0x88, 0xDA, 0xCC, - 0x73, 0x37, 0x39, 0x1C, 0xFC, 0xC9, 0x4B, 0x05, - 0x3D, 0xC4, 0xEC, 0x29, 0xCC, 0x17, 0xF0, 0x77, - 0x87, 0x04, 0x28, 0xF1, 0xAC, 0x23, 0xFD, 0xDD, - 0xA1, 0x65, 0xEF, 0x5A, 0x3F, 0x15, 0x5F, 0x39 - }, - { - 0xBF, 0x23, 0xC0, 0xC2, 0x5C, 0x80, 0x60, 0xE4, - 0xF6, 0x99, 0x5F, 0x16, 0x23, 0xA3, 0xBE, 0xBE, - 0xCA, 0xA9, 0x6E, 0x30, 0x86, 0x80, 0x00, 0x0A, - 0x8A, 0xA3, 0xCD, 0x56, 0xBB, 0x1A, 0x6D, 0xA0, - 0x99, 0xE1, 0x0D, 0x92, 0x31, 0xB3, 0x7F, 0x45, - 0x19, 0xB2, 0xEF, 0xD2, 0xC2, 0x4D, 0xE7, 0x2F, - 0x31, 0xA5, 0xF1, 0x95, 0x35, 0x24, 0x1B, 0x4A, - 0x59, 0xFA, 0x3C, 0x03, 0xCE, 0xB7, 0x90, 0xE7 - }, - { - 0x87, 0x7F, 0xD6, 0x52, 0xC0, 0x52, 0x81, 0x00, - 0x9C, 0x0A, 0x52, 0x50, 0xE7, 0xA3, 0xA6, 0x71, - 0xF8, 0xB1, 0x8C, 0x10, 0x88, 0x17, 0xFE, 0x4A, - 0x87, 0x4D, 0xE2, 0x2D, 0xA8, 0xE4, 0x5D, 0xB1, - 0x19, 0x58, 0xA6, 0x00, 0xC5, 0xF6, 0x2E, 0x67, - 0xD3, 0x6C, 0xBF, 0x84, 0x47, 0x4C, 0xF2, 0x44, - 0xA9, 0xC2, 0xB0, 0x3A, 0x9F, 0xB9, 0xDC, 0x71, - 0x1C, 0xD1, 0xA2, 0xCA, 0xB6, 0xF3, 0xFA, 0xE0 - }, - { - 0x29, 0xDF, 0x4D, 0x87, 0xEA, 0x44, 0x4B, 0xAF, - 0x5B, 0xCD, 0xF5, 0xF4, 0xE4, 0x15, 0x79, 0xE2, - 0x8A, 0x67, 0xDE, 0x84, 0x14, 0x9F, 0x06, 0xC0, - 0x3F, 0x11, 0x0E, 0xA8, 0x4F, 0x57, 0x2A, 0x9F, - 0x67, 0x6A, 0xDD, 0xD0, 0x4C, 0x48, 0x78, 0xF4, - 0x9C, 0x5C, 0x00, 0xAC, 0xCD, 0xA4, 0x41, 0xB1, - 0xA3, 0x87, 0xCA, 0xCE, 0xB2, 0xE9, 0x93, 0xBB, - 0x7A, 0x10, 0xCD, 0x8C, 0x2D, 0x67, 0x17, 0xE1 - }, - { - 0x71, 0x0D, 0xAC, 0xB1, 0x66, 0x84, 0x46, 0x39, - 0xCD, 0x7B, 0x63, 0x7C, 0x27, 0x42, 0x09, 0x42, - 0x4E, 0x24, 0x49, 0xDC, 0x35, 0xD7, 0x90, 0xBB, - 0xFA, 0x4F, 0x76, 0x17, 0x70, 0x54, 0xA3, 0x6B, - 0x3B, 0x76, 0xFA, 0xC0, 0xCA, 0x6E, 0x61, 0xDF, - 0x1E, 0x68, 0x70, 0x00, 0x67, 0x8A, 0xC0, 0x74, - 0x6D, 0xF7, 0x5D, 0x0A, 0x39, 0x54, 0x89, 0x76, - 0x81, 0xFD, 0x39, 0x3A, 0x15, 0x5A, 0x1B, 0xB4 - }, - { - 0xC1, 0xD5, 0xF9, 0x3B, 0x8D, 0xEA, 0x1F, 0x25, - 0x71, 0xBA, 0xBC, 0xCB, 0xC0, 0x17, 0x64, 0x54, - 0x1A, 0x0C, 0xDA, 0x87, 0xE4, 0x44, 0xD6, 0x73, - 0xC5, 0x09, 0x66, 0xCA, 0x55, 0x9C, 0x33, 0x35, - 0x4B, 0x3A, 0xCB, 0x26, 0xE5, 0xD5, 0x78, 0x1F, - 0xFB, 0x28, 0x84, 0x7A, 0x4B, 0x47, 0x54, 0xD7, - 0x70, 0x08, 0xC6, 0x2A, 0x83, 0x58, 0x35, 0xF5, - 0x00, 0xDE, 0xA7, 0xC3, 0xB5, 0x8B, 0xDA, 0xE2 - }, - { - 0xA4, 0x1E, 0x41, 0x27, 0x1C, 0xDA, 0xB8, 0xAF, - 0x4D, 0x72, 0xB1, 0x04, 0xBF, 0xB2, 0xAD, 0x04, - 0x1A, 0xC4, 0xDF, 0x14, 0x67, 0x7D, 0xA6, 0x71, - 0xD8, 0x56, 0x40, 0xC4, 0xB1, 0x87, 0xF5, 0x0C, - 0x2B, 0x66, 0x51, 0x3C, 0x46, 0x19, 0xFB, 0xD5, - 0xD5, 0xDC, 0x4F, 0xE6, 0x5D, 0xD3, 0x7B, 0x90, - 0x42, 0xE9, 0x84, 0x8D, 0xDA, 0x55, 0x6A, 0x50, - 0x4C, 0xAA, 0x2B, 0x1C, 0x6A, 0xFE, 0x47, 0x30 - }, - { - 0xE7, 0xBC, 0xBA, 0xCD, 0xC3, 0x79, 0xC4, 0x3D, - 0x81, 0xEB, 0xAD, 0xCB, 0x37, 0x78, 0x15, 0x52, - 0xFC, 0x1D, 0x75, 0x3E, 0x8C, 0xF3, 0x10, 0xD9, - 0x68, 0x39, 0x2D, 0x06, 0xC9, 0x1F, 0x1D, 0x64, - 0xCC, 0x9E, 0x90, 0xCE, 0x1D, 0x22, 0xC3, 0x2D, - 0x27, 0x7F, 0xC6, 0xCD, 0xA4, 0x33, 0xA4, 0xD4, - 0x42, 0xC7, 0x62, 0xE9, 0xEA, 0xCF, 0x2C, 0x25, - 0x9F, 0x32, 0xD6, 0x4C, 0xF9, 0xDA, 0x3A, 0x22 - }, - { - 0x51, 0x75, 0x5B, 0x4A, 0xC5, 0x45, 0x6B, 0x13, - 0x21, 0x8A, 0x19, 0xC5, 0xB9, 0x24, 0x2F, 0x57, - 0xC4, 0xA9, 0x81, 0xE4, 0xD4, 0xEC, 0xDC, 0xE0, - 0x9A, 0x31, 0x93, 0x36, 0x2B, 0x80, 0x8A, 0x57, - 0x93, 0x45, 0xD4, 0x88, 0x1C, 0x26, 0x07, 0xA5, - 0x65, 0x34, 0xDD, 0x7F, 0x21, 0x95, 0x6A, 0xFF, - 0x72, 0xC2, 0xF4, 0x17, 0x3A, 0x6E, 0x7B, 0x6C, - 0xC2, 0x21, 0x2B, 0xA0, 0xE3, 0xDA, 0xEE, 0x1F - }, - { - 0xDC, 0xC2, 0xC4, 0xBE, 0xB9, 0xC1, 0xF2, 0x60, - 0x7B, 0x78, 0x6C, 0x20, 0xC6, 0x31, 0x97, 0x23, - 0x47, 0x03, 0x4C, 0x1C, 0xC0, 0x2F, 0xCC, 0x7D, - 0x02, 0xFF, 0x01, 0x09, 0x9C, 0xFE, 0x1C, 0x69, - 0x89, 0x84, 0x0A, 0xC2, 0x13, 0x92, 0x36, 0x29, - 0x11, 0x3A, 0xA8, 0xBA, 0xD7, 0x13, 0xCC, 0xF0, - 0xFE, 0x4C, 0xE1, 0x32, 0x64, 0xFB, 0x32, 0xB8, - 0xB0, 0xFE, 0x37, 0x2D, 0xA3, 0x82, 0x54, 0x4A - }, - { - 0x3D, 0x55, 0x17, 0x6A, 0xCE, 0xA4, 0xA7, 0xE3, - 0xA6, 0x5F, 0xFA, 0x9F, 0xB1, 0x0A, 0x7A, 0x17, - 0x67, 0x19, 0x9C, 0xF0, 0x77, 0xCE, 0xE9, 0xF7, - 0x15, 0x32, 0xD6, 0x7C, 0xD7, 0xC7, 0x3C, 0x9F, - 0x93, 0xCF, 0xC3, 0x7C, 0xCD, 0xCC, 0x1F, 0xDE, - 0xF5, 0x0A, 0xAD, 0x46, 0xA5, 0x04, 0xA6, 0x50, - 0xD2, 0x98, 0xD5, 0x97, 0xA3, 0xA9, 0xFA, 0x95, - 0xC6, 0xC4, 0x0C, 0xB7, 0x1F, 0xA5, 0xE7, 0x25 - }, - { - 0xD0, 0x77, 0x13, 0xC0, 0x05, 0xDE, 0x96, 0xDD, - 0x21, 0xD2, 0xEB, 0x8B, 0xBE, 0xCA, 0x66, 0x74, - 0x6E, 0xA5, 0x1A, 0x31, 0xAE, 0x92, 0x2A, 0x3E, - 0x74, 0x86, 0x48, 0x89, 0x54, 0x0A, 0x48, 0xDB, - 0x27, 0xD7, 0xE4, 0xC9, 0x03, 0x11, 0x63, 0x8B, - 0x22, 0x4B, 0xF0, 0x20, 0x1B, 0x50, 0x18, 0x91, - 0x75, 0x48, 0x48, 0x11, 0x3C, 0x26, 0x61, 0x08, - 0xD0, 0xAD, 0xB1, 0x3D, 0xB7, 0x19, 0x09, 0xC7 - }, - { - 0x58, 0x98, 0x3C, 0x21, 0x43, 0x3D, 0x95, 0x0C, - 0xAA, 0x23, 0xE4, 0xBC, 0x18, 0x54, 0x3B, 0x8E, - 0x60, 0x1C, 0x20, 0x43, 0x18, 0x53, 0x21, 0x52, - 0xDA, 0xF5, 0xE1, 0x59, 0xA0, 0xCD, 0x14, 0x80, - 0x18, 0x3D, 0x29, 0x28, 0x5C, 0x05, 0xF1, 0x29, - 0xCB, 0x0C, 0xC3, 0x16, 0x46, 0x87, 0x92, 0x80, - 0x86, 0xFF, 0xE3, 0x80, 0x15, 0x8D, 0xF1, 0xD3, - 0x94, 0xC6, 0xAC, 0x0D, 0x42, 0x88, 0xBC, 0xA8 - }, - { - 0x81, 0x00, 0xA8, 0xDC, 0x52, 0x8D, 0x2B, 0x68, - 0x2A, 0xB4, 0x25, 0x08, 0x01, 0xBA, 0x33, 0xF0, - 0x2A, 0x3E, 0x94, 0xC5, 0x4D, 0xAC, 0x0A, 0xE1, - 0x48, 0x2A, 0xA2, 0x1F, 0x51, 0xEF, 0x3A, 0x82, - 0xF3, 0x80, 0x7E, 0x6F, 0xAC, 0xB0, 0xAE, 0xB0, - 0x59, 0x47, 0xBF, 0x7A, 0xA2, 0xAD, 0xCB, 0x03, - 0x43, 0x56, 0xF9, 0x0F, 0xA4, 0x56, 0x0E, 0xDE, - 0x02, 0x20, 0x1A, 0x37, 0xE4, 0x11, 0xEC, 0x1A - }, - { - 0x07, 0x02, 0x5F, 0x1B, 0xB6, 0xC7, 0x84, 0xF3, - 0xFE, 0x49, 0xDE, 0x5C, 0x14, 0xB9, 0x36, 0xA5, - 0xAC, 0xAC, 0xAC, 0xAA, 0xB3, 0x3F, 0x6A, 0xC4, - 0xD0, 0xE0, 0x0A, 0xB6, 0xA1, 0x24, 0x83, 0xD6, - 0xBE, 0xC0, 0x0B, 0x4F, 0xE6, 0x7C, 0x7C, 0xA5, - 0xCC, 0x50, 0x8C, 0x2A, 0x53, 0xEF, 0xB5, 0xBF, - 0xA5, 0x39, 0x87, 0x69, 0xD8, 0x43, 0xFF, 0x0D, - 0x9E, 0x8B, 0x14, 0xD3, 0x6A, 0x01, 0xA7, 0x7F - }, - { - 0xBA, 0x6A, 0xEF, 0xD9, 0x72, 0xB6, 0x18, 0x6E, - 0x02, 0x7A, 0x76, 0x27, 0x3A, 0x4A, 0x72, 0x33, - 0x21, 0xA3, 0xF5, 0x80, 0xCF, 0xA8, 0x94, 0xDA, - 0x5A, 0x9C, 0xE8, 0xE7, 0x21, 0xC8, 0x28, 0x55, - 0x2C, 0x64, 0xDA, 0xCE, 0xE3, 0xA7, 0xFD, 0x2D, - 0x74, 0x3B, 0x5C, 0x35, 0xAD, 0x0C, 0x8E, 0xFA, - 0x71, 0xF8, 0xCE, 0x99, 0xBF, 0x96, 0x33, 0x47, - 0x10, 0xE2, 0xC2, 0x34, 0x6E, 0x8F, 0x3C, 0x52 - }, - { - 0xE0, 0x72, 0x1E, 0x02, 0x51, 0x7A, 0xED, 0xFA, - 0x4E, 0x7E, 0x9B, 0xA5, 0x03, 0xE0, 0x25, 0xFD, - 0x46, 0xE7, 0x14, 0x56, 0x6D, 0xC8, 0x89, 0xA8, - 0x4C, 0xBF, 0xE5, 0x6A, 0x55, 0xDF, 0xBE, 0x2F, - 0xC4, 0x93, 0x8A, 0xC4, 0x12, 0x05, 0x88, 0x33, - 0x5D, 0xEA, 0xC8, 0xEF, 0x3F, 0xA2, 0x29, 0xAD, - 0xC9, 0x64, 0x7F, 0x54, 0xAD, 0x2E, 0x34, 0x72, - 0x23, 0x4F, 0x9B, 0x34, 0xEF, 0xC4, 0x65, 0x43 - }, - { - 0xB6, 0x29, 0x26, 0x69, 0xCC, 0xD3, 0x8D, 0x5F, - 0x01, 0xCA, 0xAE, 0x96, 0xBA, 0x27, 0x2C, 0x76, - 0xA8, 0x79, 0xA4, 0x57, 0x43, 0xAF, 0xA0, 0x72, - 0x5D, 0x83, 0xB9, 0xEB, 0xB2, 0x66, 0x65, 0xB7, - 0x31, 0xF1, 0x84, 0x8C, 0x52, 0xF1, 0x19, 0x72, - 0xB6, 0x64, 0x4F, 0x55, 0x4C, 0x06, 0x4F, 0xA9, - 0x07, 0x80, 0xDB, 0xBB, 0xF3, 0xA8, 0x9D, 0x4F, - 0xC3, 0x1F, 0x67, 0xDF, 0x3E, 0x58, 0x57, 0xEF - }, - { - 0x23, 0x19, 0xE3, 0x78, 0x9C, 0x47, 0xE2, 0xDA, - 0xA5, 0xFE, 0x80, 0x7F, 0x61, 0xBE, 0xC2, 0xA1, - 0xA6, 0x53, 0x7F, 0xA0, 0x3F, 0x19, 0xFF, 0x32, - 0xE8, 0x7E, 0xEC, 0xBF, 0xD6, 0x4B, 0x7E, 0x0E, - 0x8C, 0xCF, 0xF4, 0x39, 0xAC, 0x33, 0x3B, 0x04, - 0x0F, 0x19, 0xB0, 0xC4, 0xDD, 0xD1, 0x1A, 0x61, - 0xE2, 0x4A, 0xC1, 0xFE, 0x0F, 0x10, 0xA0, 0x39, - 0x80, 0x6C, 0x5D, 0xCC, 0x0D, 0xA3, 0xD1, 0x15 - }, - { - 0xF5, 0x97, 0x11, 0xD4, 0x4A, 0x03, 0x1D, 0x5F, - 0x97, 0xA9, 0x41, 0x3C, 0x06, 0x5D, 0x1E, 0x61, - 0x4C, 0x41, 0x7E, 0xDE, 0x99, 0x85, 0x90, 0x32, - 0x5F, 0x49, 0xBA, 0xD2, 0xFD, 0x44, 0x4D, 0x3E, - 0x44, 0x18, 0xBE, 0x19, 0xAE, 0xC4, 0xE1, 0x14, - 0x49, 0xAC, 0x1A, 0x57, 0x20, 0x78, 0x98, 0xBC, - 0x57, 0xD7, 0x6A, 0x1B, 0xCF, 0x35, 0x66, 0x29, - 0x2C, 0x20, 0xC6, 0x83, 0xA5, 0xC4, 0x64, 0x8F - }, - { - 0xDF, 0x0A, 0x9D, 0x0C, 0x21, 0x28, 0x43, 0xA6, - 0xA9, 0x34, 0xE3, 0x90, 0x2B, 0x2D, 0xD3, 0x0D, - 0x17, 0xFB, 0xA5, 0xF9, 0x69, 0xD2, 0x03, 0x0B, - 0x12, 0xA5, 0x46, 0xD8, 0xA6, 0xA4, 0x5E, 0x80, - 0xCF, 0x56, 0x35, 0xF0, 0x71, 0xF0, 0x45, 0x2E, - 0x9C, 0x91, 0x92, 0x75, 0xDA, 0x99, 0xBE, 0xD5, - 0x1E, 0xB1, 0x17, 0x3C, 0x1A, 0xF0, 0x51, 0x87, - 0x26, 0xB7, 0x5B, 0x0E, 0xC3, 0xBA, 0xE2, 0xB5 - }, - { - 0xA3, 0xEB, 0x6E, 0x6C, 0x7B, 0xF2, 0xFB, 0x8B, - 0x28, 0xBF, 0xE8, 0xB1, 0x5E, 0x15, 0xBB, 0x50, - 0x0F, 0x78, 0x1E, 0xCC, 0x86, 0xF7, 0x78, 0xC3, - 0xA4, 0xE6, 0x55, 0xFC, 0x58, 0x69, 0xBF, 0x28, - 0x46, 0xA2, 0x45, 0xD4, 0xE3, 0x3B, 0x7B, 0x14, - 0x43, 0x6A, 0x17, 0xE6, 0x3B, 0xE7, 0x9B, 0x36, - 0x65, 0x5C, 0x22, 0x6A, 0x50, 0xFF, 0xBC, 0x71, - 0x24, 0x20, 0x7B, 0x02, 0x02, 0x34, 0x2D, 0xB5 - }, - { - 0x56, 0xD4, 0xCB, 0xCD, 0x07, 0x05, 0x63, 0x42, - 0x6A, 0x01, 0x70, 0x69, 0x42, 0x5C, 0x2C, 0xD2, - 0xAE, 0x54, 0x06, 0x68, 0x28, 0x7A, 0x5F, 0xB9, - 0xDA, 0xC4, 0x32, 0xEB, 0x8A, 0xB1, 0xA3, 0x53, - 0xA3, 0x0F, 0x2F, 0xE1, 0xF4, 0x0D, 0x83, 0x33, - 0x3A, 0xFE, 0x69, 0x6A, 0x26, 0x77, 0x95, 0x40, - 0x8A, 0x92, 0xFE, 0x7D, 0xA0, 0x7A, 0x0C, 0x18, - 0x14, 0xCF, 0x77, 0xF3, 0x6E, 0x10, 0x5E, 0xE8 - }, - { - 0xE5, 0x9B, 0x99, 0x87, 0xD4, 0x28, 0xB3, 0xED, - 0xA3, 0x7D, 0x80, 0xAB, 0xDB, 0x16, 0xCD, 0x2B, - 0x0A, 0xEF, 0x67, 0x4C, 0x2B, 0x1D, 0xDA, 0x44, - 0x32, 0xEA, 0x91, 0xEE, 0x6C, 0x93, 0x5C, 0x68, - 0x4B, 0x48, 0xB4, 0x42, 0x8A, 0x8C, 0xC7, 0x40, - 0xE5, 0x79, 0xA3, 0x0D, 0xEF, 0xF3, 0x5A, 0x80, - 0x30, 0x13, 0x82, 0x0D, 0xD2, 0x3F, 0x14, 0xAE, - 0x1D, 0x84, 0x13, 0xB5, 0xC8, 0x67, 0x2A, 0xEC - }, - { - 0xCD, 0x9F, 0xCC, 0x99, 0xF9, 0x9D, 0x4C, 0xC1, - 0x6D, 0x03, 0x19, 0x00, 0xB2, 0xA7, 0x36, 0xE1, - 0x50, 0x8D, 0xB4, 0xB5, 0x86, 0x81, 0x4E, 0x63, - 0x45, 0x85, 0x7F, 0x35, 0x4A, 0x70, 0xCC, 0xEC, - 0xB1, 0xDF, 0x3B, 0x50, 0xA1, 0x9A, 0xDA, 0xF4, - 0x3C, 0x27, 0x8E, 0xFA, 0x42, 0x3F, 0xF4, 0xBB, - 0x6C, 0x52, 0x3E, 0xC7, 0xFD, 0x78, 0x59, 0xB9, - 0x7B, 0x16, 0x8A, 0x7E, 0xBF, 0xF8, 0x46, 0x7C - }, - { - 0x06, 0x02, 0x18, 0x5D, 0x8C, 0x3A, 0x78, 0x73, - 0x8B, 0x99, 0x16, 0x4B, 0x8B, 0xC6, 0xFF, 0xB2, - 0x1C, 0x7D, 0xEB, 0xEB, 0xBF, 0x80, 0x63, 0x72, - 0xE0, 0xDA, 0x44, 0xD1, 0x21, 0x54, 0x55, 0x97, - 0xB9, 0xC6, 0x62, 0xA2, 0x55, 0xDC, 0x31, 0x54, - 0x2C, 0xF9, 0x95, 0xEC, 0xBE, 0x6A, 0x50, 0xFB, - 0x5E, 0x6E, 0x0E, 0xE4, 0xEF, 0x24, 0x0F, 0xE5, - 0x57, 0xED, 0xED, 0x11, 0x88, 0x08, 0x7E, 0x86 - }, - { - 0xC0, 0x8A, 0xFA, 0x5B, 0x92, 0x7B, 0xF0, 0x80, - 0x97, 0xAF, 0xC5, 0xFF, 0xF9, 0xCA, 0x4E, 0x78, - 0x00, 0x12, 0x5C, 0x1F, 0x52, 0xF2, 0xAF, 0x35, - 0x53, 0xFA, 0x2B, 0x89, 0xE1, 0xE3, 0x01, 0x5C, - 0x4F, 0x87, 0xD5, 0xE0, 0xA4, 0x89, 0x56, 0xAD, - 0x31, 0x45, 0x0B, 0x08, 0x3D, 0xAD, 0x14, 0x7F, - 0xFB, 0x5E, 0xC0, 0x34, 0x34, 0xA2, 0x68, 0x30, - 0xCF, 0x37, 0xD1, 0x03, 0xAB, 0x50, 0xC5, 0xDA - }, - { - 0x36, 0xF1, 0xE1, 0xC1, 0x1D, 0x6E, 0xF6, 0xBC, - 0x3B, 0x53, 0x6D, 0x50, 0x5D, 0x54, 0x4A, 0x87, - 0x15, 0x22, 0xC5, 0xC2, 0xA2, 0x53, 0x06, 0x7E, - 0xC9, 0x93, 0x3B, 0x6E, 0xC2, 0x54, 0x64, 0xDA, - 0xF9, 0x85, 0x52, 0x5F, 0x5B, 0x95, 0x60, 0xA1, - 0x6D, 0x89, 0x02, 0x59, 0xAC, 0x1B, 0xB5, 0xCC, - 0x67, 0xC0, 0xC4, 0x69, 0xCD, 0xE1, 0x33, 0xDE, - 0xF0, 0x00, 0xEA, 0x1D, 0x68, 0x6F, 0x4F, 0x5D - }, - { - 0xBF, 0x2A, 0xB2, 0xE2, 0x47, 0x0F, 0x54, 0x38, - 0xC3, 0xB6, 0x89, 0xE6, 0x6E, 0x76, 0x86, 0xFF, - 0xFA, 0x0C, 0xB1, 0xE1, 0x79, 0x8A, 0xD3, 0xA8, - 0x6F, 0xF9, 0x90, 0x75, 0xBF, 0x61, 0x38, 0xE3, - 0x3D, 0x9C, 0x0C, 0xE5, 0x9A, 0xFB, 0x24, 0xAC, - 0x67, 0xA0, 0x2A, 0xF3, 0x44, 0x28, 0x19, 0x1A, - 0x9A, 0x0A, 0x60, 0x41, 0xC0, 0x74, 0x71, 0xB7, - 0xC3, 0xB1, 0xA7, 0x52, 0xD6, 0xFC, 0x0B, 0x8B - }, - { - 0xD4, 0x00, 0x60, 0x1F, 0x97, 0x28, 0xCC, 0xC4, - 0xC9, 0x23, 0x42, 0xD9, 0x78, 0x7D, 0x8D, 0x28, - 0xAB, 0x32, 0x3A, 0xF3, 0x75, 0xCA, 0x56, 0x24, - 0xB4, 0xBB, 0x91, 0xD1, 0x72, 0x71, 0xFB, 0xAE, - 0x86, 0x2E, 0x41, 0x3B, 0xE7, 0x3F, 0x1F, 0x68, - 0xE6, 0x15, 0xB8, 0xC5, 0xC3, 0x91, 0xBE, 0x0D, - 0xBD, 0x91, 0x44, 0x74, 0x6E, 0xB3, 0x39, 0xAD, - 0x54, 0x15, 0x47, 0xBA, 0x9C, 0x46, 0x8A, 0x17 - }, - { - 0x79, 0xFE, 0x2F, 0xE1, 0x57, 0xEB, 0x85, 0xA0, - 0x38, 0xAB, 0xB8, 0xEB, 0xBC, 0x64, 0x77, 0x31, - 0xD2, 0xC8, 0x3F, 0x51, 0xB0, 0xAC, 0x6E, 0xE1, - 0x4A, 0xA2, 0x84, 0xCB, 0x6A, 0x35, 0x49, 0xA4, - 0xDC, 0xCE, 0xB3, 0x00, 0x74, 0x0A, 0x82, 0x5F, - 0x52, 0xF5, 0xFB, 0x30, 0xB0, 0x3B, 0x8C, 0x4D, - 0x8B, 0x0F, 0x4A, 0xA6, 0x7A, 0x63, 0xF4, 0xA9, - 0x4E, 0x33, 0x03, 0xC4, 0xED, 0xA4, 0xC0, 0x2B - }, - { - 0x75, 0x35, 0x13, 0x13, 0xB5, 0x2A, 0x85, 0x29, - 0x29, 0x8D, 0x8C, 0x18, 0x6B, 0x17, 0x68, 0x66, - 0x6D, 0xCC, 0xA8, 0x59, 0x53, 0x17, 0xD7, 0xA4, - 0x81, 0x6E, 0xB8, 0x8C, 0x06, 0x20, 0x20, 0xC0, - 0xC8, 0xEF, 0xC5, 0x54, 0xBB, 0x34, 0x1B, 0x64, - 0x68, 0x8D, 0xB5, 0xCC, 0xAF, 0xC3, 0x5F, 0x3C, - 0x3C, 0xD0, 0x9D, 0x65, 0x64, 0xB3, 0x6D, 0x7B, - 0x04, 0xA2, 0x48, 0xE1, 0x46, 0x98, 0x0D, 0x4B - }, - { - 0xE3, 0x12, 0x8B, 0x1D, 0x31, 0x1D, 0x02, 0x17, - 0x9D, 0x7F, 0x25, 0xF9, 0x7A, 0x5A, 0x8B, 0xEE, - 0x2C, 0xC8, 0xC8, 0x63, 0x03, 0x64, 0x4F, 0xCD, - 0x66, 0x4E, 0x15, 0x7D, 0x1F, 0xEF, 0x00, 0xF2, - 0x3E, 0x46, 0xF9, 0xA5, 0xE8, 0xE5, 0xC8, 0x90, - 0xCE, 0x56, 0x5B, 0xB6, 0xAB, 0xD4, 0x30, 0x2C, - 0xE0, 0x64, 0x69, 0xD5, 0x2A, 0x5B, 0xD5, 0x3E, - 0x1C, 0x5A, 0x54, 0xD0, 0x46, 0x49, 0xDC, 0x03 - }, - { - 0xC2, 0x38, 0x2A, 0x72, 0xD2, 0xD3, 0xAC, 0xE9, - 0xD5, 0x93, 0x3D, 0x00, 0xB6, 0x08, 0x27, 0xED, - 0x38, 0x0C, 0xDA, 0x08, 0xD0, 0xBA, 0x5F, 0x6D, - 0xD4, 0x1E, 0x29, 0xEE, 0x6D, 0xBE, 0x8E, 0xCB, - 0x92, 0x35, 0xF0, 0x6B, 0xE9, 0x5D, 0x83, 0xB6, - 0x81, 0x6A, 0x2F, 0xB7, 0xA5, 0xAD, 0x47, 0x03, - 0x5E, 0x8A, 0x4B, 0x69, 0xA4, 0x88, 0x4B, 0x99, - 0xE4, 0xBE, 0xCE, 0x58, 0xCA, 0xB2, 0x5D, 0x44 - }, - { - 0x6B, 0x1C, 0x69, 0x46, 0x0B, 0xBD, 0x50, 0xAC, - 0x2E, 0xD6, 0xF3, 0x2E, 0x6E, 0x88, 0x7C, 0xFE, - 0xD4, 0x07, 0xD4, 0x7D, 0xCF, 0x0A, 0xAA, 0x60, - 0x38, 0x7F, 0xE3, 0x20, 0xD7, 0x80, 0xBD, 0x03, - 0xEA, 0xB6, 0xD7, 0xBA, 0xEB, 0x2A, 0x07, 0xD1, - 0x0C, 0xD5, 0x52, 0xA3, 0x00, 0x34, 0x13, 0x54, - 0xEA, 0x9A, 0x5F, 0x03, 0x18, 0x3A, 0x62, 0x3F, - 0x92, 0xA2, 0xD4, 0xD9, 0xF0, 0x09, 0x26, 0xAF - }, - { - 0x6C, 0xDA, 0x20, 0x6C, 0x80, 0xCD, 0xC9, 0xC4, - 0x4B, 0xA9, 0x90, 0xE0, 0x32, 0x8C, 0x31, 0x4F, - 0x81, 0x9B, 0x14, 0x2D, 0x00, 0x63, 0x04, 0x04, - 0xC4, 0x8C, 0x05, 0xDC, 0x76, 0xD1, 0xB0, 0x0C, - 0xE4, 0xD7, 0x2F, 0xC6, 0xA4, 0x8E, 0x14, 0x69, - 0xDD, 0xEF, 0x60, 0x94, 0x12, 0xC3, 0x64, 0x82, - 0x08, 0x54, 0x21, 0x4B, 0x48, 0x69, 0xAF, 0x09, - 0x0F, 0x00, 0xD3, 0xC1, 0xBA, 0x44, 0x3E, 0x1B - }, - { - 0x7F, 0xFC, 0x8C, 0x26, 0xFB, 0xD6, 0xA0, 0xF7, - 0xA6, 0x09, 0xE6, 0xE1, 0x93, 0x9F, 0x6A, 0x9E, - 0xDF, 0x1B, 0x0B, 0x06, 0x66, 0x41, 0xFB, 0x76, - 0xC4, 0xF9, 0x60, 0x2E, 0xD7, 0x48, 0xD1, 0x16, - 0x02, 0x49, 0x6B, 0x35, 0x35, 0x5B, 0x1A, 0xA2, - 0x55, 0x85, 0x0A, 0x50, 0x9D, 0x2F, 0x8E, 0xE1, - 0x8C, 0x8F, 0x3E, 0x1D, 0x7D, 0xCB, 0xC3, 0x7A, - 0x13, 0x65, 0x98, 0xF5, 0x6A, 0x59, 0xED, 0x17 - }, - { - 0x70, 0xDE, 0x1F, 0x08, 0xDD, 0x4E, 0x09, 0xD5, - 0xFC, 0x15, 0x1F, 0x17, 0xFC, 0x99, 0x1A, 0x23, - 0xAB, 0xFC, 0x05, 0x10, 0x42, 0x90, 0xD5, 0x04, - 0x68, 0x88, 0x2E, 0xFA, 0xF5, 0x82, 0xB6, 0xEC, - 0x2F, 0x14, 0xF5, 0x77, 0xC0, 0xD6, 0x8C, 0x3A, - 0xD0, 0x66, 0x26, 0x91, 0x6E, 0x3C, 0x86, 0xE6, - 0xDA, 0xAB, 0x6C, 0x53, 0xE5, 0x16, 0x3E, 0x82, - 0xB6, 0xBD, 0x0C, 0xE4, 0x9F, 0xC0, 0xD8, 0xDF - }, - { - 0x4F, 0x81, 0x93, 0x57, 0x56, 0xED, 0x35, 0xEE, - 0x20, 0x58, 0xEE, 0x0C, 0x6A, 0x61, 0x10, 0xD6, - 0xFA, 0xC5, 0xCB, 0x6A, 0x4F, 0x46, 0xAA, 0x94, - 0x11, 0x60, 0x3F, 0x99, 0x96, 0x58, 0x23, 0xB6, - 0xDA, 0x48, 0x38, 0x27, 0x6C, 0x5C, 0x06, 0xBC, - 0x78, 0x80, 0xE3, 0x76, 0xD9, 0x27, 0x58, 0x36, - 0x9E, 0xE7, 0x30, 0x5B, 0xCE, 0xC8, 0xD3, 0xCF, - 0xD2, 0x8C, 0xCA, 0xBB, 0x7B, 0x4F, 0x05, 0x79 - }, - { - 0xAB, 0xCB, 0x61, 0xCB, 0x36, 0x83, 0xD1, 0x8F, - 0x27, 0xAD, 0x52, 0x79, 0x08, 0xED, 0x2D, 0x32, - 0xA0, 0x42, 0x6C, 0xB7, 0xBB, 0x4B, 0xF1, 0x80, - 0x61, 0x90, 0x3A, 0x7D, 0xC4, 0x2E, 0x7E, 0x76, - 0xF9, 0x82, 0x38, 0x23, 0x04, 0xD1, 0x8A, 0xF8, - 0xC8, 0x0D, 0x91, 0xDD, 0x58, 0xDD, 0x47, 0xAF, - 0x76, 0xF8, 0xE2, 0xC3, 0x6E, 0x28, 0xAF, 0x24, - 0x76, 0xB4, 0xBC, 0xCF, 0x82, 0xE8, 0x9F, 0xDF - }, - { - 0x02, 0xD2, 0x61, 0xAD, 0x56, 0xA5, 0x26, 0x33, - 0x1B, 0x64, 0x3D, 0xD2, 0x18, 0x6D, 0xE9, 0xA8, - 0x2E, 0x72, 0xA5, 0x82, 0x23, 0xCD, 0x1E, 0x72, - 0x36, 0x86, 0xC5, 0x3D, 0x86, 0x9B, 0x83, 0xB9, - 0x46, 0x32, 0xB7, 0xB6, 0x47, 0xAB, 0x2A, 0xFC, - 0x0D, 0x52, 0x2E, 0x29, 0xDA, 0x3A, 0x56, 0x15, - 0xB7, 0x41, 0xD8, 0x28, 0x52, 0xE0, 0xDF, 0x41, - 0xB6, 0x60, 0x07, 0xDB, 0xCB, 0xA9, 0x05, 0x43 - }, - { - 0xC5, 0x83, 0x27, 0x41, 0xFA, 0x30, 0xC5, 0x43, - 0x68, 0x23, 0x01, 0x53, 0x83, 0xD2, 0x97, 0xFF, - 0x4C, 0x4A, 0x5D, 0x72, 0x76, 0xC3, 0xF9, 0x02, - 0x12, 0x20, 0x66, 0xE0, 0x4B, 0xE5, 0x43, 0x1B, - 0x1A, 0x85, 0xFA, 0xF7, 0x3B, 0x91, 0x84, 0x34, - 0xF9, 0x30, 0x09, 0x63, 0xD1, 0xDE, 0xA9, 0xE8, - 0xAC, 0x39, 0x24, 0xEF, 0x49, 0x02, 0x26, 0xED, - 0xEE, 0xA5, 0xF7, 0x43, 0xE4, 0x10, 0x66, 0x9F - }, - { - 0xCF, 0xAE, 0xAB, 0x26, 0x8C, 0xD0, 0x75, 0xA5, - 0xA6, 0xAE, 0xD5, 0x15, 0x02, 0x3A, 0x03, 0x2D, - 0x54, 0xF2, 0xF2, 0xFF, 0x73, 0x3C, 0xE0, 0xCB, - 0xC7, 0x8D, 0xB5, 0x1D, 0xB4, 0x50, 0x4D, 0x67, - 0x59, 0x23, 0xF8, 0x27, 0x46, 0xD6, 0x59, 0x46, - 0x06, 0xAD, 0x5D, 0x67, 0x73, 0x4B, 0x11, 0xA6, - 0x7C, 0xC6, 0xA4, 0x68, 0xC2, 0x03, 0x2E, 0x43, - 0xCA, 0x1A, 0x94, 0xC6, 0x27, 0x3A, 0x98, 0x5E - }, - { - 0x86, 0x08, 0x50, 0xF9, 0x2E, 0xB2, 0x68, 0x27, - 0x2B, 0x67, 0xD1, 0x33, 0x60, 0x9B, 0xD6, 0x4E, - 0x34, 0xF6, 0x1B, 0xF0, 0x3F, 0x4C, 0x17, 0x38, - 0x64, 0x5C, 0x17, 0xFE, 0xC8, 0x18, 0x46, 0x5D, - 0x7E, 0xCD, 0x2B, 0xE2, 0x90, 0x76, 0x41, 0x13, - 0x00, 0x25, 0xFD, 0xA7, 0x94, 0x70, 0xAB, 0x73, - 0x16, 0x46, 0xE7, 0xF6, 0x94, 0x40, 0xE8, 0x36, - 0x7E, 0xA7, 0x6A, 0xC4, 0xCE, 0xE8, 0xA1, 0xDF - }, - { - 0x84, 0xB1, 0x54, 0xED, 0x29, 0xBB, 0xED, 0xEF, - 0xA6, 0x48, 0x28, 0x68, 0x39, 0x04, 0x6F, 0x4B, - 0x5A, 0xA3, 0x44, 0x30, 0xE2, 0xD6, 0x7F, 0x74, - 0x96, 0xE4, 0xC3, 0x9F, 0x2C, 0x7E, 0xA7, 0x89, - 0x95, 0xF6, 0x9E, 0x12, 0x92, 0x20, 0x00, 0x16, - 0xF1, 0x6A, 0xC3, 0xB3, 0x77, 0x00, 0xE6, 0xC7, - 0xE7, 0x86, 0x1A, 0xFC, 0x39, 0x6B, 0x64, 0xA5, - 0x9A, 0x1D, 0xBF, 0x47, 0xA5, 0x5C, 0x4B, 0xBC - }, - { - 0xAE, 0xEE, 0xC2, 0x60, 0xA5, 0xD8, 0xEF, 0xF5, - 0xCC, 0xAB, 0x8B, 0x95, 0xDA, 0x43, 0x5A, 0x63, - 0xED, 0x7A, 0x21, 0xEA, 0x7F, 0xC7, 0x55, 0x94, - 0x13, 0xFD, 0x61, 0x7E, 0x33, 0x60, 0x9F, 0x8C, - 0x29, 0x0E, 0x64, 0xBB, 0xAC, 0xC5, 0x28, 0xF6, - 0xC0, 0x80, 0x26, 0x22, 0x88, 0xB0, 0xF0, 0xA3, - 0x21, 0x9B, 0xE2, 0x23, 0xC9, 0x91, 0xBE, 0xE9, - 0x2E, 0x72, 0x34, 0x95, 0x93, 0xE6, 0x76, 0x38 - }, - { - 0x8A, 0xD7, 0x8A, 0x9F, 0x26, 0x60, 0x1D, 0x12, - 0x7E, 0x8D, 0x2F, 0x2F, 0x97, 0x6E, 0x63, 0xD1, - 0x9A, 0x05, 0x4A, 0x17, 0xDC, 0xF5, 0x9E, 0x0F, - 0x01, 0x3A, 0xB5, 0x4A, 0x68, 0x87, 0xBB, 0xDF, - 0xFD, 0xE7, 0xAA, 0xAE, 0x11, 0x7E, 0x0F, 0xBF, - 0x32, 0x71, 0x01, 0x65, 0x95, 0xB9, 0xD9, 0xC7, - 0x12, 0xC0, 0x1B, 0x2C, 0x53, 0xE9, 0x65, 0x5A, - 0x38, 0x2B, 0xC4, 0x52, 0x2E, 0x61, 0x66, 0x45 - }, - { - 0x89, 0x34, 0x15, 0x9D, 0xAD, 0xE1, 0xAC, 0x74, - 0x14, 0x7D, 0xFA, 0x28, 0x2C, 0x75, 0x95, 0x4F, - 0xCE, 0xF4, 0x43, 0xEF, 0x25, 0xF8, 0x0D, 0xFE, - 0x9F, 0xB6, 0xEA, 0x63, 0x3B, 0x85, 0x45, 0x11, - 0x1D, 0x08, 0xB3, 0x4E, 0xF4, 0x3F, 0xFF, 0x17, - 0x02, 0x6C, 0x79, 0x64, 0xF5, 0xDE, 0xAC, 0x6D, - 0x2B, 0x3C, 0x29, 0xDA, 0xCF, 0x27, 0x47, 0xF0, - 0x22, 0xDF, 0x59, 0x67, 0xDF, 0xDC, 0x1A, 0x0A - }, - { - 0xCD, 0x36, 0xDD, 0x0B, 0x24, 0x06, 0x14, 0xCF, - 0x2F, 0xA2, 0xB9, 0xE9, 0x59, 0x67, 0x9D, 0xCD, - 0xD7, 0x2E, 0xC0, 0xCD, 0x58, 0xA4, 0x3D, 0xA3, - 0x79, 0x0A, 0x92, 0xF6, 0xCD, 0xEB, 0x9E, 0x1E, - 0x79, 0x5E, 0x47, 0x8A, 0x0A, 0x47, 0xD3, 0x71, - 0x10, 0x0D, 0x34, 0x0C, 0x5C, 0xED, 0xCD, 0xBB, - 0xC9, 0xE6, 0x8B, 0x3F, 0x46, 0x08, 0x18, 0xE5, - 0xBD, 0xFF, 0x7B, 0x4C, 0xDA, 0x4C, 0x27, 0x44 - }, - { - 0x00, 0xDF, 0x4E, 0x09, 0x9B, 0x80, 0x71, 0x37, - 0xA8, 0x59, 0x90, 0xF4, 0x9D, 0x3A, 0x94, 0x31, - 0x5E, 0x5A, 0x5F, 0x7F, 0x7A, 0x60, 0x76, 0xB3, - 0x03, 0xE9, 0x6B, 0x05, 0x6F, 0xB9, 0x38, 0x00, - 0x11, 0x1F, 0x47, 0x96, 0x28, 0xE2, 0xF8, 0xDB, - 0x59, 0xAE, 0xB6, 0xAC, 0x70, 0xC3, 0xB6, 0x1F, - 0x51, 0xF9, 0xB4, 0x6E, 0x80, 0xFF, 0xDE, 0xAE, - 0x25, 0xEB, 0xDD, 0xB4, 0xAF, 0x6C, 0xB4, 0xEE - }, - { - 0x2B, 0x9C, 0x95, 0x5E, 0x6C, 0xAE, 0xD4, 0xB7, - 0xC9, 0xE2, 0x46, 0xB8, 0x6F, 0x9A, 0x17, 0x26, - 0xE8, 0x10, 0xC5, 0x9D, 0x12, 0x6C, 0xEE, 0x66, - 0xED, 0x71, 0xBF, 0x01, 0x5B, 0x83, 0x55, 0x8A, - 0x4B, 0x6D, 0x84, 0xD1, 0x8D, 0xC3, 0xFF, 0x46, - 0x20, 0xC2, 0xFF, 0xB7, 0x22, 0x35, 0x9F, 0xDE, - 0xF8, 0x5B, 0xA0, 0xD4, 0xE2, 0xD2, 0x2E, 0xCB, - 0xE0, 0xED, 0x78, 0x4F, 0x99, 0xAF, 0xE5, 0x87 - }, - { - 0x18, 0x1D, 0xF0, 0xA2, 0x61, 0xA2, 0xF7, 0xD2, - 0x9E, 0xA5, 0xA1, 0x57, 0x72, 0x71, 0x51, 0x05, - 0xD4, 0x50, 0xA4, 0xB6, 0xC2, 0x36, 0xF6, 0x99, - 0xF4, 0x62, 0xD6, 0x0C, 0xA7, 0x64, 0x87, 0xFE, - 0xED, 0xFC, 0x9F, 0x5E, 0xB9, 0x2D, 0xF8, 0x38, - 0xE8, 0xFB, 0x5D, 0xC3, 0x69, 0x4E, 0x84, 0xC5, - 0xE0, 0xF4, 0xA1, 0x0B, 0x76, 0x1F, 0x50, 0x67, - 0x62, 0xBE, 0x05, 0x2C, 0x74, 0x5A, 0x6E, 0xE8 - }, - { - 0x21, 0xFB, 0x20, 0x34, 0x58, 0xBF, 0x3A, 0x7E, - 0x9A, 0x80, 0x43, 0x9F, 0x9A, 0x90, 0x28, 0x99, - 0xCD, 0x5D, 0xE0, 0x13, 0x9D, 0xFD, 0x56, 0xF7, - 0x11, 0x0C, 0x9D, 0xEC, 0x84, 0x37, 0xB2, 0x6B, - 0xDA, 0x63, 0xDE, 0x2F, 0x56, 0x59, 0x26, 0xD8, - 0x5E, 0xDB, 0x1D, 0x6C, 0x68, 0x25, 0x66, 0x97, - 0x43, 0xDD, 0x99, 0x92, 0x65, 0x3D, 0x13, 0x97, - 0x95, 0x44, 0xD5, 0xDC, 0x82, 0x28, 0xBF, 0xAA - }, - { - 0xEF, 0x02, 0x1F, 0x29, 0xC5, 0xFF, 0xB8, 0x30, - 0xE6, 0x4B, 0x9A, 0xA9, 0x05, 0x8D, 0xD6, 0x60, - 0xFD, 0x2F, 0xCB, 0x81, 0xC4, 0x97, 0xA7, 0xE6, - 0x98, 0xBC, 0xFB, 0xF5, 0x9D, 0xE5, 0xAD, 0x4A, - 0x86, 0xFF, 0x93, 0xC1, 0x0A, 0x4B, 0x9D, 0x1A, - 0xE5, 0x77, 0x47, 0x25, 0xF9, 0x07, 0x2D, 0xCD, - 0xE9, 0xE1, 0xF1, 0x99, 0xBA, 0xB9, 0x1F, 0x8B, - 0xFF, 0x92, 0x18, 0x64, 0xAA, 0x50, 0x2E, 0xEE - }, - { - 0xB3, 0xCF, 0xDA, 0x40, 0x52, 0x6B, 0x7F, 0x1D, - 0x37, 0x56, 0x9B, 0xDF, 0xCD, 0xF9, 0x11, 0xE5, - 0xA6, 0xEF, 0xE6, 0xB2, 0xEC, 0x90, 0xA0, 0x45, - 0x4C, 0x47, 0xB2, 0xC0, 0x46, 0xBF, 0x13, 0x0F, - 0xC3, 0xB3, 0x52, 0xB3, 0x4D, 0xF4, 0x81, 0x3D, - 0x48, 0xD3, 0x3A, 0xB8, 0xE2, 0x69, 0xB6, 0x9B, - 0x07, 0x56, 0x76, 0xCB, 0x6D, 0x00, 0xA8, 0xDC, - 0xF9, 0xE1, 0xF9, 0x67, 0xEC, 0x19, 0x1B, 0x2C - }, - { - 0xB4, 0xC6, 0xC3, 0xB2, 0x67, 0x07, 0x1E, 0xEF, - 0xB9, 0xC8, 0xC7, 0x2E, 0x0E, 0x2B, 0x94, 0x12, - 0x93, 0x64, 0x1F, 0x86, 0x73, 0xCB, 0x70, 0xC1, - 0xCC, 0x26, 0xAD, 0x1E, 0x73, 0xCF, 0x14, 0x17, - 0x55, 0x86, 0x0A, 0xD1, 0x9B, 0x34, 0xC2, 0xF3, - 0x4E, 0xD3, 0x5B, 0xB5, 0x2E, 0xC4, 0x50, 0x7C, - 0xC1, 0xFE, 0x59, 0x04, 0x77, 0x43, 0xA5, 0xF0, - 0xC6, 0xFE, 0xBD, 0xE6, 0x25, 0xE2, 0x60, 0x91 - }, - { - 0x57, 0xA3, 0x4F, 0x2B, 0xCC, 0xA6, 0x0D, 0x4B, - 0x85, 0x10, 0x3B, 0x83, 0x0C, 0x9D, 0x79, 0x52, - 0xA4, 0x16, 0xBE, 0x52, 0x63, 0xAE, 0x42, 0x9C, - 0x9E, 0x5E, 0x53, 0xFE, 0x85, 0x90, 0xA8, 0xF7, - 0x8E, 0xC6, 0x5A, 0x51, 0x10, 0x9E, 0xA8, 0x5D, - 0xCD, 0xF7, 0xB6, 0x22, 0x3F, 0x9F, 0x2B, 0x34, - 0x05, 0x39, 0xFA, 0xD8, 0x19, 0x23, 0xDB, 0xF8, - 0xED, 0xAB, 0xF9, 0x51, 0x29, 0xE4, 0xDF, 0xF6 - }, - { - 0x9C, 0xF4, 0x66, 0x62, 0xFC, 0xD6, 0x1A, 0x23, - 0x22, 0x77, 0xB6, 0x85, 0x66, 0x3B, 0x8B, 0x5D, - 0xA8, 0x32, 0xDF, 0xD9, 0xA3, 0xB8, 0xCC, 0xFE, - 0xEC, 0x99, 0x3E, 0xC6, 0xAC, 0x41, 0x5A, 0xD0, - 0x7E, 0x04, 0x8A, 0xDF, 0xE4, 0x14, 0xDF, 0x27, - 0x27, 0x70, 0xDB, 0xA8, 0x67, 0xDA, 0x5C, 0x12, - 0x24, 0xC6, 0xFD, 0x0A, 0xA0, 0xC2, 0x18, 0x7D, - 0x42, 0x6A, 0xC6, 0x47, 0xE9, 0x88, 0x73, 0x61 - }, - { - 0x5C, 0xE1, 0x04, 0x2A, 0xB4, 0xD5, 0x42, 0xC2, - 0xF9, 0xEE, 0x9D, 0x17, 0x26, 0x2A, 0xF8, 0x16, - 0x40, 0x98, 0x93, 0x5B, 0xEF, 0x17, 0x3D, 0x0E, - 0x18, 0x48, 0x9B, 0x04, 0x84, 0x17, 0x46, 0xCD, - 0x2F, 0x2D, 0xF8, 0x66, 0xBD, 0x7D, 0xA6, 0xE5, - 0xEF, 0x90, 0x24, 0xC6, 0x48, 0x02, 0x3E, 0xC7, - 0x23, 0xAB, 0x9C, 0x62, 0xFD, 0x80, 0x28, 0x57, - 0x39, 0xD8, 0x4F, 0x15, 0xD2, 0xAB, 0x51, 0x5A - }, - { - 0x84, 0x88, 0x39, 0x6B, 0xD4, 0xA8, 0x72, 0x9B, - 0x7A, 0x47, 0x31, 0x78, 0xF2, 0x32, 0xDA, 0xDF, - 0x3F, 0x0F, 0x8E, 0x22, 0x67, 0x8B, 0xA5, 0xA4, - 0x3E, 0x04, 0x1E, 0x72, 0xDA, 0x1E, 0x2C, 0xF8, - 0x21, 0x94, 0xC3, 0x07, 0x20, 0x7A, 0x54, 0xCB, - 0x81, 0x56, 0x29, 0x33, 0x39, 0xEA, 0xEC, 0x69, - 0x3F, 0xF6, 0x6B, 0xFC, 0xD5, 0xEF, 0xC6, 0x5E, - 0x95, 0xE4, 0xEC, 0xAF, 0x54, 0x53, 0x0A, 0xBD - }, - { - 0xF5, 0x98, 0xDA, 0x90, 0x1C, 0x38, 0x35, 0xBC, - 0xA5, 0x60, 0x77, 0x90, 0x37, 0xDF, 0xDE, 0x9F, - 0x0C, 0x51, 0xDC, 0x61, 0xC0, 0xB7, 0x60, 0xFC, - 0x15, 0x22, 0xD7, 0xB4, 0x70, 0xEE, 0x63, 0xF5, - 0xBD, 0xC6, 0x49, 0x84, 0x76, 0xE8, 0x60, 0x49, - 0xAD, 0x86, 0xE4, 0xE2, 0x1A, 0xF2, 0x85, 0x4A, - 0x98, 0x4C, 0xC9, 0x05, 0x42, 0x7D, 0x2F, 0x17, - 0xF6, 0x6B, 0x1F, 0x41, 0xC3, 0xDA, 0x6F, 0x61 - }, - { - 0x5F, 0x93, 0x26, 0x97, 0x98, 0xCF, 0x02, 0x13, - 0x21, 0x07, 0x33, 0x76, 0x60, 0xA8, 0xD7, 0xA1, - 0x77, 0x35, 0x4C, 0x02, 0x12, 0xEB, 0x93, 0xE5, - 0x55, 0xE7, 0xC3, 0x7A, 0x08, 0xAE, 0xF3, 0xD8, - 0xDC, 0xE0, 0x12, 0x17, 0x01, 0x1C, 0xD9, 0x65, - 0xC0, 0x4D, 0xD2, 0xC1, 0x05, 0xF2, 0xE2, 0xB6, - 0xCA, 0xE5, 0xE4, 0xE6, 0xBC, 0xAF, 0x09, 0xDF, - 0xBE, 0xE3, 0xE0, 0xA6, 0xA6, 0x35, 0x7C, 0x37 - }, - { - 0x0E, 0xCF, 0x58, 0x1D, 0x47, 0xBA, 0xC9, 0x23, - 0x09, 0x86, 0xFA, 0xAB, 0xD7, 0x0C, 0x2F, 0x5B, - 0x80, 0xE9, 0x10, 0x66, 0xF0, 0xEC, 0x55, 0xA8, - 0x42, 0x93, 0x78, 0x82, 0x28, 0x6D, 0x2C, 0xA0, - 0x07, 0xBB, 0x4E, 0x97, 0x3B, 0x0B, 0x09, 0x1D, - 0x52, 0x16, 0x7F, 0xF7, 0xC4, 0x00, 0x9C, 0x7A, - 0xB4, 0xAD, 0x38, 0xFF, 0xF1, 0xDC, 0xEA, 0xCD, - 0xB7, 0xBE, 0x81, 0xEF, 0x4A, 0x45, 0x29, 0x52 - }, - { - 0x5A, 0xEC, 0xA8, 0xAB, 0xE1, 0x52, 0x85, 0x82, - 0xB2, 0xA3, 0x07, 0xB4, 0x00, 0x95, 0x85, 0x49, - 0x8A, 0x3D, 0x46, 0x7C, 0xA6, 0x10, 0x1C, 0xB0, - 0xC5, 0x12, 0x6F, 0x99, 0x76, 0x05, 0x6E, 0x9F, - 0xFC, 0x12, 0x3C, 0xC2, 0x0C, 0x30, 0x2B, 0x2A, - 0x73, 0x7F, 0x49, 0x2C, 0x75, 0xD2, 0x1F, 0x01, - 0x51, 0x2C, 0x90, 0xCA, 0x05, 0x41, 0xDF, 0xA5, - 0x6E, 0x95, 0x0A, 0x32, 0x1D, 0xCB, 0x28, 0xD8 - }, - { - 0x73, 0x2F, 0xBF, 0x8F, 0x1C, 0xB2, 0xB8, 0x32, - 0x92, 0x63, 0xED, 0xE2, 0x78, 0x58, 0xFE, 0x46, - 0xF8, 0xD3, 0x35, 0x4D, 0x37, 0x6B, 0xCD, 0xA0, - 0x54, 0x8E, 0x7C, 0xE1, 0xFA, 0x9D, 0xD1, 0x1F, - 0x85, 0xEB, 0x66, 0x1F, 0xE9, 0x50, 0xB5, 0x43, - 0xAA, 0x63, 0x5C, 0xA4, 0xD3, 0xF0, 0x4E, 0xDE, - 0x5B, 0x32, 0xD6, 0xB6, 0x56, 0xE5, 0xCE, 0x1C, - 0x44, 0xD3, 0x5C, 0x4A, 0x6C, 0x56, 0xCF, 0xF8 - }, - { - 0xD5, 0xE9, 0x38, 0x73, 0x5D, 0x63, 0x78, 0x8C, - 0x80, 0x10, 0x0A, 0xEF, 0xD1, 0x86, 0x48, 0xD1, - 0x8C, 0xF2, 0x72, 0xF6, 0x9F, 0x20, 0xFF, 0x24, - 0xCF, 0xE2, 0x89, 0x5C, 0x08, 0x8A, 0xD0, 0x8B, - 0x01, 0x04, 0xDA, 0x16, 0x72, 0xA4, 0xEB, 0x26, - 0xFC, 0x52, 0x54, 0x5C, 0xC7, 0xD7, 0xA0, 0x1B, - 0x26, 0x6C, 0xF5, 0x46, 0xC4, 0x03, 0xC4, 0x5B, - 0xD1, 0x29, 0xEB, 0x41, 0xBD, 0xD9, 0x20, 0x0B - }, - { - 0x65, 0xA2, 0x45, 0xB4, 0x93, 0x52, 0xEE, 0x29, - 0x7D, 0x91, 0xAF, 0x8C, 0x8B, 0xE0, 0x05, 0x28, - 0xAC, 0x6E, 0x04, 0x6D, 0xD8, 0x3A, 0xC7, 0xBD, - 0x46, 0x5A, 0x98, 0x81, 0x6D, 0xD6, 0x8F, 0x3E, - 0x00, 0xE1, 0xAE, 0x8F, 0x89, 0x53, 0x27, 0xA7, - 0xE9, 0xA8, 0xC9, 0x32, 0x65, 0x98, 0x37, 0x9A, - 0x29, 0xC9, 0xFC, 0x91, 0xEC, 0x0C, 0x6E, 0xEF, - 0x08, 0xF3, 0xE2, 0xB2, 0x16, 0xC1, 0x10, 0x08 - }, - { - 0xC9, 0x56, 0x54, 0xB6, 0x30, 0x19, 0x13, 0x0A, - 0xB4, 0x5D, 0xD0, 0xFB, 0x49, 0x41, 0xB9, 0x8A, - 0xEB, 0x3A, 0xF2, 0xA1, 0x23, 0x91, 0x3E, 0xCA, - 0x2C, 0xE9, 0x9B, 0x3E, 0x97, 0x41, 0x0A, 0x7B, - 0xF8, 0x66, 0x1C, 0xC7, 0xFB, 0xAA, 0x2B, 0xC1, - 0xCF, 0x2B, 0x13, 0x11, 0x3B, 0x1E, 0xD4, 0x0A, - 0x01, 0x18, 0xB8, 0x8E, 0x5F, 0xFF, 0xC3, 0x54, - 0x27, 0x59, 0xEA, 0x00, 0x7E, 0xD4, 0xC5, 0x8D - }, - { - 0x1E, 0xB2, 0x62, 0xF3, 0x8F, 0xA4, 0x94, 0x43, - 0x1F, 0x01, 0x7D, 0xAD, 0x44, 0xC0, 0xDF, 0xB6, - 0x93, 0x24, 0xAC, 0x03, 0x2F, 0x04, 0xB6, 0x57, - 0xFC, 0x91, 0xA8, 0x86, 0x47, 0xBB, 0x74, 0x76, - 0x0F, 0x24, 0xE7, 0xC9, 0x56, 0x51, 0x4F, 0x0C, - 0xF0, 0x02, 0x99, 0x0B, 0x18, 0x2C, 0x16, 0x42, - 0xB9, 0xB2, 0x42, 0x6E, 0x96, 0xA6, 0x11, 0x87, - 0xE4, 0xE0, 0x12, 0xF0, 0x0E, 0x21, 0x7D, 0x84 - }, - { - 0x3B, 0x95, 0x5A, 0xEE, 0xBF, 0xA5, 0x15, 0x1A, - 0xC1, 0xAB, 0x8E, 0x3F, 0x5C, 0xC1, 0xE3, 0x76, - 0x70, 0x84, 0xC8, 0x42, 0xA5, 0x75, 0xD3, 0x62, - 0x69, 0x83, 0x6E, 0x97, 0x35, 0x3D, 0x41, 0x62, - 0x2B, 0x73, 0x1D, 0xDD, 0xCD, 0x5F, 0x26, 0x95, - 0x50, 0xA3, 0xA5, 0xB8, 0x7B, 0xE1, 0xE9, 0x03, - 0x26, 0x34, 0x0B, 0x6E, 0x0E, 0x62, 0x55, 0x58, - 0x15, 0xD9, 0x60, 0x05, 0x97, 0xAC, 0x6E, 0xF9 - }, - { - 0x68, 0x28, 0x9F, 0x66, 0x05, 0x47, 0x3B, 0xA0, - 0xE4, 0xF2, 0x41, 0xBA, 0xF7, 0x47, 0x7A, 0x98, - 0x85, 0x42, 0x6A, 0x85, 0x8F, 0x19, 0xEF, 0x2A, - 0x18, 0xB0, 0xD4, 0x0E, 0xF8, 0xE4, 0x12, 0x82, - 0xED, 0x55, 0x26, 0xB5, 0x19, 0x79, 0x9E, 0x27, - 0x0F, 0x13, 0x88, 0x13, 0x27, 0x91, 0x82, 0x78, - 0x75, 0x57, 0x11, 0x07, 0x1D, 0x85, 0x11, 0xFE, - 0x96, 0x3E, 0x3B, 0x56, 0x06, 0xAA, 0x37, 0x16 - }, - { - 0x80, 0xA3, 0x37, 0x87, 0x54, 0x26, 0x12, 0xC3, - 0x8F, 0x6B, 0xCD, 0x7C, 0xD8, 0x6C, 0xAB, 0x46, - 0x02, 0x27, 0x50, 0x9B, 0x1C, 0xBA, 0xD5, 0xEC, - 0x40, 0x8A, 0x91, 0x41, 0x3D, 0x51, 0x15, 0x5A, - 0x04, 0x76, 0xDA, 0xDB, 0xF3, 0xA2, 0x51, 0x8E, - 0x4A, 0x6E, 0x77, 0xCC, 0x34, 0x66, 0x22, 0xE3, - 0x47, 0xA4, 0x69, 0xBF, 0x8B, 0xAA, 0x5F, 0x04, - 0xEB, 0x2D, 0x98, 0x70, 0x53, 0x55, 0xD0, 0x63 - }, - { - 0x34, 0x62, 0x9B, 0xC6, 0xD8, 0x31, 0x39, 0x1C, - 0x4C, 0xDF, 0x8A, 0xF1, 0xB4, 0xB7, 0xB6, 0xB8, - 0xE8, 0xEE, 0x17, 0xCF, 0x98, 0xC7, 0x0E, 0x5D, - 0xD5, 0x86, 0xCD, 0x99, 0xF1, 0x4B, 0x11, 0xDF, - 0x94, 0x51, 0x66, 0x23, 0x6A, 0x95, 0x71, 0xE6, - 0xD5, 0x91, 0xBB, 0x83, 0xEE, 0x4D, 0x16, 0x4D, - 0x46, 0xF6, 0xB9, 0xD8, 0xEF, 0x86, 0xFF, 0x86, - 0x5A, 0x81, 0xBF, 0xB9, 0x1B, 0x00, 0x42, 0x4B - }, - { - 0x8B, 0x7C, 0xC3, 0x39, 0x16, 0x38, 0x63, 0xBB, - 0x43, 0x83, 0xE5, 0x42, 0xB0, 0xEF, 0x0E, 0x7C, - 0xF3, 0x6B, 0x84, 0xAD, 0x93, 0x2C, 0xDF, 0x5A, - 0x80, 0x41, 0x9E, 0xC9, 0xAD, 0x69, 0x2E, 0x7A, - 0x7E, 0x78, 0x4D, 0x2C, 0x7C, 0xB3, 0x79, 0x6A, - 0x18, 0xB8, 0xF8, 0x00, 0x03, 0x5F, 0x3A, 0xA0, - 0x6C, 0x82, 0x41, 0x00, 0x61, 0x11, 0x20, 0xA7, - 0xBD, 0xEB, 0x35, 0x61, 0x8C, 0xCB, 0x81, 0xB7 - }, - { - 0x4F, 0x08, 0x4E, 0x49, 0x39, 0xDD, 0x5A, 0x7F, - 0x5A, 0x65, 0x8F, 0xAD, 0x58, 0xA1, 0x8A, 0x15, - 0xC2, 0x5C, 0x32, 0xEC, 0x1C, 0x7F, 0xD5, 0xC5, - 0xC6, 0xC3, 0xE8, 0x92, 0xB3, 0x97, 0x1A, 0xEA, - 0xAC, 0x30, 0x83, 0x04, 0xEF, 0x17, 0xB1, 0xC4, - 0x72, 0x39, 0xEA, 0x4B, 0xB3, 0x98, 0xB3, 0xFD, - 0x6D, 0x45, 0x28, 0xD8, 0xDE, 0x8E, 0x76, 0x8A, - 0xE0, 0xF1, 0xA5, 0xA5, 0xC6, 0xB5, 0xC2, 0x97 - }, - { - 0x48, 0xF4, 0x07, 0xA1, 0xAF, 0x5B, 0x80, 0x09, - 0xB2, 0x05, 0x17, 0x42, 0xE8, 0xCF, 0x5C, 0xD5, - 0x65, 0x66, 0x69, 0xE7, 0xD7, 0x22, 0xEE, 0x8E, - 0x7B, 0xD2, 0x02, 0x06, 0x08, 0x49, 0x44, 0x21, - 0x68, 0xD8, 0xFA, 0xCC, 0x11, 0x7C, 0x01, 0x2B, - 0xFB, 0x7B, 0xF4, 0x49, 0xD9, 0x9B, 0xEF, 0xFF, - 0x6A, 0x34, 0xAE, 0xA2, 0x03, 0xF1, 0xD8, 0xD3, - 0x52, 0x72, 0x2B, 0xE5, 0x01, 0x4E, 0xC8, 0x18 - }, - { - 0xA6, 0xAA, 0x82, 0xCD, 0x1E, 0x42, 0x6F, 0x9A, - 0x73, 0xBF, 0xA3, 0x9A, 0x29, 0x03, 0x78, 0x76, - 0x11, 0x46, 0x55, 0xB8, 0xC2, 0x2D, 0x6D, 0x3F, - 0xF8, 0xB6, 0x38, 0xAE, 0x7D, 0xEA, 0x6B, 0x17, - 0x84, 0x3E, 0x09, 0xE5, 0x2E, 0xB6, 0x6F, 0xA1, - 0xE4, 0x75, 0xE4, 0xA8, 0xA3, 0xDE, 0x42, 0x9B, - 0x7D, 0x0F, 0x4A, 0x77, 0x6F, 0xCB, 0x8B, 0xDC, - 0x9B, 0x9F, 0xED, 0xE7, 0xD5, 0x2E, 0x81, 0x5F - }, - { - 0x58, 0x17, 0x02, 0x7D, 0x6B, 0xDD, 0x00, 0xC5, - 0xDD, 0x10, 0xAC, 0x59, 0x3C, 0xD5, 0x60, 0x37, - 0x22, 0x70, 0x77, 0x5A, 0x18, 0x52, 0x6D, 0x7E, - 0x6F, 0x13, 0x87, 0x2A, 0x2E, 0x20, 0xEA, 0xB6, - 0x64, 0x62, 0x5B, 0xE7, 0x16, 0x8A, 0xC4, 0xBD, - 0x7C, 0x9E, 0x0C, 0xE7, 0xFC, 0x40, 0x99, 0xE0, - 0xF4, 0x84, 0x42, 0xE2, 0xC7, 0x67, 0x19, 0x1C, - 0x6E, 0x12, 0x84, 0xE9, 0xB2, 0xCC, 0xEA, 0x8C - }, - { - 0x08, 0xE4, 0x10, 0x28, 0x34, 0x0A, 0x45, 0xC7, - 0x4E, 0x40, 0x52, 0xB3, 0xA8, 0xD6, 0x38, 0x9E, - 0x22, 0xE0, 0x43, 0xA1, 0xAD, 0xAB, 0x5E, 0x28, - 0xD9, 0x76, 0x19, 0x45, 0x0D, 0x72, 0x34, 0x69, - 0xB6, 0x20, 0xCA, 0xA5, 0x19, 0xB8, 0x1C, 0x14, - 0x52, 0x38, 0x54, 0xF6, 0x19, 0xFD, 0x30, 0x27, - 0xE3, 0x84, 0x7B, 0xD0, 0x32, 0x76, 0xE6, 0x06, - 0x04, 0xA8, 0x0D, 0xDB, 0x4D, 0xE8, 0x76, 0xD6 - }, - { - 0x13, 0x0B, 0x84, 0x20, 0x53, 0x7E, 0xB0, 0x7D, - 0x72, 0xAB, 0xDA, 0x07, 0xC8, 0x5A, 0xCB, 0xD8, - 0xB9, 0xA4, 0x4F, 0x16, 0x32, 0x1D, 0xD0, 0x42, - 0x21, 0x45, 0xF8, 0x09, 0x67, 0x3D, 0x30, 0xF2, - 0xB5, 0x32, 0x13, 0x26, 0xE2, 0xBF, 0xF3, 0x17, - 0xEF, 0x3F, 0xEF, 0x98, 0x3C, 0x51, 0xC4, 0xF8, - 0xAB, 0x24, 0xA3, 0x25, 0xD2, 0x98, 0xE3, 0x4A, - 0xFC, 0xE5, 0x69, 0xA8, 0x25, 0x55, 0x77, 0x4C - }, - { - 0xAC, 0x49, 0xB8, 0x44, 0xAF, 0xAA, 0x01, 0x2E, - 0x31, 0xC4, 0x74, 0xCA, 0x26, 0x36, 0x48, 0x84, - 0x4F, 0xD2, 0xF6, 0x30, 0x79, 0x92, 0xC2, 0xF7, - 0x52, 0xAC, 0xA0, 0x2C, 0x38, 0x28, 0x96, 0x51, - 0x75, 0x79, 0x4D, 0xEE, 0xE2, 0xD2, 0xEE, 0x95, - 0xC6, 0x1C, 0xD2, 0x84, 0xF6, 0xB5, 0xA2, 0xD7, - 0x5E, 0x2E, 0xF2, 0xB2, 0x9E, 0xE8, 0x14, 0x9E, - 0x77, 0xFB, 0x81, 0x44, 0x7B, 0x2F, 0xD0, 0x4B - }, - { - 0xB9, 0xD7, 0xCA, 0x81, 0xCC, 0x60, 0xBB, 0x95, - 0x78, 0xE4, 0x40, 0x24, 0xE5, 0xA0, 0xA0, 0xBE, - 0x80, 0xF2, 0x73, 0x36, 0xA6, 0xA9, 0xF4, 0xE5, - 0x3D, 0xF3, 0x99, 0x9C, 0xB1, 0x91, 0x28, 0x0B, - 0x09, 0x0E, 0x2A, 0xC2, 0xD2, 0x9C, 0x5B, 0xAA, - 0xD9, 0xD7, 0x14, 0x15, 0xBD, 0xC1, 0x29, 0xE6, - 0x9A, 0xA2, 0x66, 0x7A, 0xF6, 0xA7, 0xFD, 0x5E, - 0x18, 0x9F, 0xCC, 0xDC, 0xEE, 0x81, 0x73, 0x40 - }, - { - 0xA7, 0x55, 0xE1, 0x13, 0x38, 0x65, 0x72, 0xC7, - 0x5C, 0xED, 0x61, 0xD7, 0x19, 0x70, 0x60, 0x70, - 0xB9, 0x14, 0x60, 0x48, 0xE4, 0x2A, 0x9F, 0x8C, - 0xD3, 0x56, 0x67, 0xA0, 0x88, 0xB4, 0x2F, 0x08, - 0x80, 0x8A, 0xBD, 0xF7, 0x7E, 0x61, 0x8A, 0xBD, - 0x95, 0x9A, 0xFC, 0x75, 0x73, 0x79, 0xCA, 0x2C, - 0x00, 0xBC, 0xC1, 0xA4, 0x83, 0x90, 0xFA, 0x2B, - 0xFF, 0x61, 0x8B, 0x1E, 0x00, 0x78, 0xA6, 0x13 - }, - { - 0xA7, 0x3C, 0x7D, 0xEB, 0xED, 0x32, 0x6F, 0x1C, - 0x0D, 0xB0, 0x79, 0x5E, 0xE7, 0xD6, 0xE3, 0x94, - 0x68, 0x94, 0xB8, 0x26, 0xB1, 0xF8, 0x10, 0x1C, - 0x56, 0xC8, 0x23, 0xBA, 0x17, 0x16, 0x83, 0x12, - 0xE7, 0xF5, 0x3F, 0xC7, 0xDB, 0xE5, 0x2C, 0x3E, - 0x11, 0xE6, 0x98, 0x52, 0xC4, 0x04, 0x85, 0xE2, - 0xEF, 0x18, 0x24, 0x77, 0x86, 0x2E, 0xA6, 0xA3, - 0x4E, 0xC1, 0x36, 0xE2, 0xDF, 0xEE, 0xA6, 0xF4 - }, - { - 0x6C, 0xB8, 0xF9, 0xD5, 0x2C, 0x56, 0xD8, 0x2C, - 0xAC, 0x28, 0xF3, 0x9E, 0xA1, 0x59, 0x3E, 0x8B, - 0xB2, 0x50, 0x62, 0x93, 0xAC, 0x0D, 0x68, 0x37, - 0x6A, 0x17, 0x09, 0xB6, 0x2A, 0x46, 0xDF, 0x14, - 0xA4, 0xAE, 0x64, 0xB2, 0xD8, 0xFA, 0xB7, 0x67, - 0x33, 0xA1, 0xCE, 0xD2, 0xD5, 0x48, 0xE3, 0xF3, - 0xC6, 0xFC, 0xB4, 0x9D, 0x40, 0xC3, 0xD5, 0x80, - 0x8E, 0x44, 0x9C, 0xD8, 0x3D, 0x1C, 0x2A, 0xA2 - }, - { - 0x68, 0x3F, 0xA2, 0xB2, 0x36, 0x9A, 0x10, 0x16, - 0x2C, 0x1C, 0x1C, 0x7B, 0x24, 0xBC, 0x97, 0x0E, - 0xE6, 0x7D, 0xA2, 0x20, 0x56, 0x4F, 0x32, 0x20, - 0x3F, 0x62, 0x56, 0x96, 0xC0, 0x35, 0x2A, 0x0B, - 0x9A, 0xD9, 0x66, 0x24, 0x36, 0x2D, 0x95, 0x2D, - 0x84, 0x46, 0x3C, 0x11, 0x06, 0xA2, 0xDB, 0xA7, - 0xA0, 0x92, 0x59, 0x98, 0x84, 0xB3, 0x5A, 0x0B, - 0x89, 0xC8, 0xF1, 0xB6, 0xA9, 0xB5, 0xA6, 0x1E - }, - { - 0xAA, 0xD9, 0xAD, 0x44, 0x61, 0x01, 0x18, 0xB7, - 0x7D, 0x50, 0x8A, 0xEB, 0x1B, 0xBC, 0xD1, 0xC1, - 0xB7, 0xD0, 0x17, 0x13, 0x97, 0xFB, 0x51, 0x0A, - 0x40, 0x1B, 0xBC, 0x0E, 0xC3, 0x46, 0x23, 0x67, - 0x0D, 0x86, 0xA2, 0xDC, 0x3C, 0x8F, 0x3A, 0xB5, - 0xA2, 0x04, 0x4D, 0xF7, 0x30, 0x25, 0x67, 0x27, - 0x54, 0x5F, 0x08, 0x60, 0xCE, 0x21, 0xA1, 0xEA, - 0xC7, 0x17, 0xDF, 0xC4, 0x8F, 0x5D, 0x22, 0x8E - }, - { - 0xC4, 0x25, 0x78, 0xDE, 0x23, 0xB4, 0xC9, 0x87, - 0xD5, 0xE1, 0xAC, 0x4D, 0x68, 0x9E, 0xD5, 0xDE, - 0x4B, 0x04, 0x17, 0xF9, 0x70, 0x4B, 0xC6, 0xBC, - 0xE9, 0x69, 0xFA, 0x13, 0x47, 0x15, 0x85, 0xD6, - 0x2C, 0x2C, 0xB1, 0x21, 0x2A, 0x94, 0x4F, 0x39, - 0x7F, 0xC9, 0xCA, 0x2C, 0x37, 0x47, 0xC3, 0xBE, - 0xB6, 0x94, 0xEC, 0x4C, 0x5B, 0xE6, 0x88, 0x28, - 0xDD, 0xA5, 0x3E, 0xF4, 0x3F, 0xAE, 0xC6, 0xC0 - }, - { - 0x47, 0x0F, 0x00, 0x84, 0x1E, 0xE8, 0x24, 0x4E, - 0x63, 0xED, 0x2C, 0x7E, 0xA3, 0x0E, 0x2E, 0x41, - 0x98, 0x97, 0xC1, 0x97, 0x46, 0x2E, 0xCC, 0xCE, - 0xCF, 0x71, 0x3B, 0x42, 0xA5, 0x06, 0x5F, 0xFF, - 0x59, 0x14, 0xBC, 0x9B, 0x79, 0xAF, 0xFE, 0x8F, - 0x6B, 0x65, 0x78, 0x75, 0xE7, 0x89, 0xAE, 0x21, - 0x3B, 0xD9, 0x14, 0xCD, 0x35, 0xBD, 0x17, 0x4D, - 0x46, 0xE9, 0xD1, 0x8B, 0xD8, 0x43, 0x77, 0x3D - }, - { - 0x34, 0xFC, 0x42, 0x13, 0x73, 0x0F, 0x47, 0xA5, - 0xE9, 0xA3, 0x58, 0x0F, 0x64, 0x3E, 0x12, 0x94, - 0x5C, 0xFC, 0xB3, 0x1B, 0xF2, 0x06, 0xF6, 0xAD, - 0x45, 0x0C, 0xE5, 0x28, 0xDA, 0x3F, 0xA4, 0x32, - 0xE0, 0x05, 0xD6, 0xB0, 0xEC, 0xCE, 0x10, 0xDC, - 0xA7, 0xC5, 0x99, 0x5F, 0x6A, 0xAC, 0xC5, 0x15, - 0x0E, 0x1B, 0x00, 0x9E, 0x19, 0x75, 0x1E, 0x83, - 0x09, 0xF8, 0x85, 0x95, 0x31, 0x84, 0x43, 0x74 - }, - { - 0xFB, 0x3C, 0x1F, 0x0F, 0x56, 0xA5, 0x6F, 0x8E, - 0x31, 0x6F, 0xDF, 0x5D, 0x85, 0x3C, 0x8C, 0x87, - 0x2C, 0x39, 0x63, 0x5D, 0x08, 0x36, 0x34, 0xC3, - 0x90, 0x4F, 0xC3, 0xAC, 0x07, 0xD1, 0xB5, 0x78, - 0xE8, 0x5F, 0xF0, 0xE4, 0x80, 0xE9, 0x2D, 0x44, - 0xAD, 0xE3, 0x3B, 0x62, 0xE8, 0x93, 0xEE, 0x32, - 0x34, 0x3E, 0x79, 0xDD, 0xF6, 0xEF, 0x29, 0x2E, - 0x89, 0xB5, 0x82, 0xD3, 0x12, 0x50, 0x23, 0x14 - }, - { - 0xC7, 0xC9, 0x7F, 0xC6, 0x5D, 0xD2, 0xB9, 0xE3, - 0xD3, 0xD6, 0x07, 0xD3, 0x15, 0x98, 0xD3, 0xF8, - 0x42, 0x61, 0xE9, 0x91, 0x92, 0x51, 0xE9, 0xC8, - 0xE5, 0x7B, 0xB5, 0xF8, 0x29, 0x37, 0x7D, 0x5F, - 0x73, 0xEA, 0xBB, 0xED, 0x55, 0xC6, 0xC3, 0x81, - 0x18, 0x0F, 0x29, 0xAD, 0x02, 0xE5, 0xBE, 0x79, - 0x7F, 0xFE, 0xC7, 0xE5, 0x7B, 0xDE, 0xCB, 0xC5, - 0x0A, 0xD3, 0xD0, 0x62, 0xF0, 0x99, 0x3A, 0xB0 - }, - { - 0xA5, 0x7A, 0x49, 0xCD, 0xBE, 0x67, 0xAE, 0x7D, - 0x9F, 0x79, 0x7B, 0xB5, 0xCC, 0x7E, 0xFC, 0x2D, - 0xF0, 0x7F, 0x4E, 0x1B, 0x15, 0x95, 0x5F, 0x85, - 0xDA, 0xE7, 0x4B, 0x76, 0xE2, 0xEC, 0xB8, 0x5A, - 0xFB, 0x6C, 0xD9, 0xEE, 0xED, 0x88, 0x88, 0xD5, - 0xCA, 0x3E, 0xC5, 0xAB, 0x65, 0xD2, 0x7A, 0x7B, - 0x19, 0xE5, 0x78, 0x47, 0x57, 0x60, 0xA0, 0x45, - 0xAC, 0x3C, 0x92, 0xE1, 0x3A, 0x93, 0x8E, 0x77 - }, - { - 0xC7, 0x14, 0x3F, 0xCE, 0x96, 0x14, 0xA1, 0x7F, - 0xD6, 0x53, 0xAE, 0xB1, 0x40, 0x72, 0x6D, 0xC9, - 0xC3, 0xDB, 0xB1, 0xDE, 0x6C, 0xC5, 0x81, 0xB2, - 0x72, 0x68, 0x97, 0xEC, 0x24, 0xB7, 0xA5, 0x03, - 0x59, 0xAD, 0x49, 0x22, 0x43, 0xBE, 0x66, 0xD9, - 0xED, 0xD8, 0xC9, 0x33, 0xB5, 0xB8, 0x0E, 0x0B, - 0x91, 0xBB, 0x61, 0xEA, 0x98, 0x05, 0x60, 0x06, - 0x51, 0x69, 0x76, 0xFA, 0xE8, 0xD9, 0x9A, 0x35 - }, - { - 0x65, 0xBB, 0x58, 0xD0, 0x7F, 0x93, 0x7E, 0x2D, - 0x3C, 0x7E, 0x65, 0x38, 0x5F, 0x9C, 0x54, 0x73, - 0x0B, 0x70, 0x41, 0x05, 0xCC, 0xDB, 0x69, 0x1F, - 0x6E, 0x14, 0x6D, 0x4E, 0xE8, 0xF6, 0xC0, 0x86, - 0xF4, 0x95, 0x11, 0x03, 0x51, 0x10, 0xA9, 0xAD, - 0x60, 0x31, 0xFD, 0xCE, 0xB9, 0x43, 0xE0, 0xF9, - 0x61, 0x3B, 0xCB, 0x27, 0x6D, 0xD4, 0x0F, 0x06, - 0x24, 0xEF, 0x0F, 0x92, 0x4F, 0x80, 0x97, 0x83 - }, - { - 0xE5, 0x40, 0x27, 0x7F, 0x68, 0x3B, 0x11, 0x86, - 0xDD, 0x3B, 0x5B, 0x3F, 0x61, 0x43, 0x33, 0x96, - 0x58, 0x1A, 0x35, 0xFE, 0xB1, 0x20, 0x02, 0xBE, - 0x8C, 0x6A, 0x62, 0x31, 0xFC, 0x40, 0xFF, 0xA7, - 0x0F, 0x08, 0x08, 0x1B, 0xC5, 0x8B, 0x2D, 0x94, - 0xF7, 0x64, 0x95, 0x43, 0x61, 0x4A, 0x43, 0x5F, - 0xAA, 0x2D, 0x62, 0x11, 0x0E, 0x13, 0xDA, 0xBC, - 0x7B, 0x86, 0x62, 0x9B, 0x63, 0xAF, 0x9C, 0x24 - }, - { - 0x41, 0x85, 0x00, 0x87, 0x8C, 0x5F, 0xBC, 0xB5, - 0x84, 0xC4, 0x32, 0xF4, 0x28, 0x5E, 0x05, 0xE4, - 0x9F, 0x2E, 0x3E, 0x07, 0x53, 0x99, 0xA0, 0xDB, - 0xFC, 0xF8, 0x74, 0xEB, 0xF8, 0xC0, 0x3D, 0x02, - 0xBF, 0x16, 0xBC, 0x69, 0x89, 0xD1, 0x61, 0xC7, - 0x7C, 0xA0, 0x78, 0x6B, 0x05, 0x05, 0x3C, 0x6C, - 0x70, 0x94, 0x33, 0x71, 0x23, 0x19, 0x19, 0x21, - 0x28, 0x83, 0x5C, 0xF0, 0xB6, 0x60, 0x59, 0x5B - }, - { - 0x88, 0x90, 0x90, 0xDB, 0xB1, 0x94, 0x4B, 0xDC, - 0x94, 0x33, 0xEE, 0x5E, 0xF1, 0x01, 0x0C, 0x7A, - 0x4A, 0x24, 0xA8, 0xE7, 0x1E, 0xCE, 0xA8, 0xE1, - 0x2A, 0x31, 0x31, 0x8C, 0xE4, 0x9D, 0xCA, 0xB0, - 0xAC, 0xA5, 0xC3, 0x80, 0x23, 0x34, 0xAA, 0xB2, - 0xCC, 0x84, 0xB1, 0x4C, 0x6B, 0x93, 0x21, 0xFE, - 0x58, 0x6B, 0xF3, 0xF8, 0x76, 0xF1, 0x9C, 0xD4, - 0x06, 0xEB, 0x11, 0x27, 0xFB, 0x94, 0x48, 0x01 - }, - { - 0x53, 0xB6, 0xA2, 0x89, 0x10, 0xAA, 0x92, 0xE2, - 0x7E, 0x53, 0x6F, 0xB5, 0x49, 0xCF, 0x9B, 0x99, - 0x18, 0x79, 0x10, 0x60, 0x89, 0x8E, 0x0B, 0x9F, - 0xE1, 0x83, 0x57, 0x7F, 0xF4, 0x3B, 0x5E, 0x9C, - 0x76, 0x89, 0xC7, 0x45, 0xB3, 0x2E, 0x41, 0x22, - 0x69, 0x83, 0x7C, 0x31, 0xB8, 0x9E, 0x6C, 0xC1, - 0x2B, 0xF7, 0x6E, 0x13, 0xCA, 0xD3, 0x66, 0xB7, - 0x4E, 0xCE, 0x48, 0xBB, 0x85, 0xFD, 0x09, 0xE9 - }, - { - 0x7C, 0x09, 0x20, 0x80, 0xC6, 0xA8, 0x0D, 0x67, - 0x24, 0x09, 0xD0, 0x81, 0xD3, 0xD1, 0x77, 0x10, - 0x6B, 0xCD, 0x63, 0x56, 0x77, 0x85, 0x14, 0x07, - 0x19, 0x49, 0x09, 0x50, 0xAE, 0x07, 0xAE, 0x8F, - 0xCA, 0xAB, 0xBA, 0xAA, 0xB3, 0x30, 0xCF, 0xBC, - 0xF7, 0x37, 0x44, 0x82, 0xC2, 0x20, 0xAF, 0x2E, - 0xAD, 0xEE, 0xB7, 0x3D, 0xCB, 0xB3, 0x5E, 0xD8, - 0x23, 0x34, 0x4E, 0x14, 0x4E, 0x7D, 0x48, 0x99 - }, - { - 0x9C, 0xCD, 0xE5, 0x66, 0xD2, 0x40, 0x05, 0x09, - 0x18, 0x11, 0x11, 0xF3, 0x2D, 0xDE, 0x4C, 0xD6, - 0x32, 0x09, 0xFE, 0x59, 0xA3, 0x0C, 0x11, 0x45, - 0x46, 0xAD, 0x27, 0x76, 0xD8, 0x89, 0xA4, 0x1B, - 0xAD, 0x8F, 0xA1, 0xBB, 0x46, 0x8C, 0xB2, 0xF9, - 0xD4, 0x2C, 0xA9, 0x92, 0x8A, 0x77, 0x70, 0xFE, - 0xF8, 0xE8, 0xBA, 0x4D, 0x0C, 0x81, 0x2D, 0x9A, - 0x1E, 0x75, 0xC3, 0xD8, 0xD2, 0xCC, 0xD7, 0x5A - }, - { - 0x6E, 0x29, 0x3B, 0xF5, 0xD0, 0x3F, 0xE4, 0x39, - 0x77, 0xCF, 0xE3, 0xF5, 0x7C, 0xCD, 0xB3, 0xAE, - 0x28, 0x2A, 0x85, 0x45, 0x5D, 0xCA, 0x33, 0xF3, - 0x7F, 0x4B, 0x74, 0xF8, 0x39, 0x8C, 0xC6, 0x12, - 0x43, 0x3D, 0x75, 0x5C, 0xBE, 0xC4, 0x12, 0xF8, - 0xF8, 0x2A, 0x3B, 0xD3, 0xBC, 0x4A, 0x27, 0x8F, - 0x7E, 0xCD, 0x0D, 0xFA, 0x9B, 0xBD, 0xC4, 0x0B, - 0xE7, 0xA7, 0x87, 0xC8, 0xF1, 0x59, 0xB2, 0xDF - }, - { - 0xC5, 0x65, 0x46, 0xFB, 0x21, 0x78, 0x45, 0x6F, - 0x33, 0x61, 0x64, 0xC1, 0x8B, 0x90, 0xDE, 0xFF, - 0xC8, 0x3A, 0xE2, 0xB5, 0xA3, 0xAC, 0xA7, 0x7B, - 0x68, 0x84, 0xD3, 0x6D, 0x2C, 0x1D, 0xB3, 0x95, - 0x01, 0xB3, 0xE6, 0x5E, 0x36, 0xC7, 0x58, 0xC6, - 0x6E, 0x31, 0x88, 0x45, 0x1F, 0xDB, 0x35, 0x15, - 0xEE, 0x16, 0x2C, 0x00, 0x1F, 0x06, 0xC3, 0xE8, - 0xCB, 0x57, 0x3A, 0xDF, 0x30, 0xF7, 0xA1, 0x01 - }, - { - 0x6F, 0x82, 0xF8, 0x9F, 0x29, 0x9E, 0xBC, 0xA2, - 0xFE, 0x01, 0x4B, 0x59, 0xBF, 0xFE, 0x1A, 0xA8, - 0x4E, 0x88, 0xB1, 0x91, 0x5F, 0xE2, 0x56, 0xAF, - 0xB6, 0x46, 0xFD, 0x84, 0x48, 0xAF, 0x2B, 0x88, - 0x91, 0xA7, 0xFA, 0xB3, 0x7A, 0x4E, 0xA6, 0xF9, - 0xA5, 0x0E, 0x6C, 0x31, 0x70, 0x39, 0xD8, 0xCF, - 0x87, 0x8F, 0x4C, 0x8E, 0x1A, 0x0D, 0xD4, 0x64, - 0xF0, 0xB4, 0xD6, 0xFF, 0x1C, 0x7E, 0xA8, 0x53 - }, - { - 0x2B, 0x85, 0x99, 0xFF, 0x9C, 0x3D, 0x61, 0x98, - 0x63, 0x7A, 0xD5, 0x1E, 0x57, 0xD1, 0x99, 0x8B, - 0x0D, 0x75, 0x31, 0x3F, 0xE2, 0xDD, 0x61, 0xA5, - 0x33, 0xC9, 0x64, 0xA6, 0xDD, 0x96, 0x07, 0xC6, - 0xF7, 0x23, 0xE9, 0x45, 0x2C, 0xE4, 0x6E, 0x01, - 0x4B, 0x1C, 0x1D, 0x6D, 0xE7, 0x7B, 0xA5, 0xB8, - 0x8C, 0x91, 0x4D, 0x1C, 0x59, 0x7B, 0xF1, 0xEA, - 0xE1, 0x34, 0x74, 0xB4, 0x29, 0x0E, 0x89, 0xB2 - }, - { - 0x08, 0xBF, 0x34, 0x6D, 0x38, 0xE1, 0xDF, 0x06, - 0xC8, 0x26, 0x0E, 0xDB, 0x1D, 0xA7, 0x55, 0x79, - 0x27, 0x59, 0x48, 0xD5, 0xC0, 0xA0, 0xAA, 0x9E, - 0xD2, 0x88, 0x6F, 0x88, 0x56, 0xDE, 0x54, 0x17, - 0xA1, 0x56, 0x99, 0x87, 0x58, 0xF5, 0xB1, 0x7E, - 0x52, 0xF1, 0x01, 0xCA, 0x95, 0x7A, 0x71, 0x13, - 0x74, 0x73, 0xDF, 0xD1, 0x8D, 0x7D, 0x20, 0x9C, - 0x4C, 0x10, 0xD9, 0x23, 0x3C, 0x93, 0x69, 0x1D - }, - { - 0x6D, 0xF2, 0x15, 0x6D, 0x77, 0x31, 0x14, 0xD3, - 0x10, 0xB6, 0x3D, 0xB9, 0xEE, 0x53, 0x50, 0xD7, - 0x7E, 0x6B, 0xCF, 0x25, 0xB0, 0x5F, 0xCD, 0x91, - 0x0F, 0x9B, 0x31, 0xBC, 0x42, 0xBB, 0x13, 0xFE, - 0x82, 0x25, 0xEB, 0xCB, 0x2A, 0x23, 0xA6, 0x22, - 0x80, 0x77, 0x7B, 0x6B, 0xF7, 0x4E, 0x2C, 0xD0, - 0x91, 0x7C, 0x76, 0x40, 0xB4, 0x3D, 0xEF, 0xE4, - 0x68, 0xCD, 0x1E, 0x18, 0xC9, 0x43, 0xC6, 0x6A - }, - { - 0x7C, 0x70, 0x38, 0xBC, 0x13, 0xA9, 0x11, 0x51, - 0x82, 0x8A, 0x5B, 0xA8, 0x2B, 0x4A, 0x96, 0x04, - 0x0F, 0x25, 0x8A, 0x4D, 0xFB, 0x1B, 0x13, 0x73, - 0xF0, 0xD3, 0x59, 0x16, 0x8A, 0xFB, 0x05, 0x17, - 0xA2, 0x0B, 0x28, 0xA1, 0x2D, 0x36, 0x44, 0x04, - 0x6B, 0xE6, 0x6B, 0x8D, 0x08, 0xD8, 0xAE, 0x7F, - 0x6A, 0x92, 0x3E, 0xA1, 0xC0, 0x01, 0x87, 0xC6, - 0xD1, 0x1D, 0xC5, 0x02, 0xBA, 0xC7, 0x13, 0x05 - }, - { - 0xBC, 0xD1, 0xB3, 0x0D, 0x80, 0x8F, 0xB7, 0x39, - 0xB9, 0x87, 0xCB, 0xF1, 0x54, 0xBE, 0xA0, 0x0D, - 0xA9, 0xD4, 0x03, 0x80, 0xB8, 0x61, 0xD4, 0xC1, - 0xD6, 0x37, 0x71, 0x22, 0xDA, 0xDD, 0x61, 0xC0, - 0xE5, 0x90, 0x18, 0xB7, 0x19, 0x41, 0xCF, 0xB6, - 0x2E, 0x00, 0xDC, 0xD7, 0x0A, 0xEB, 0x9A, 0xBF, - 0x04, 0x73, 0xE8, 0x0F, 0x0A, 0x7E, 0xCA, 0x6B, - 0x6D, 0xEA, 0x24, 0x6A, 0xB2, 0x29, 0xDD, 0x2B - }, - { - 0x7E, 0xD4, 0x46, 0x8D, 0x96, 0x85, 0x30, 0xFE, - 0x7A, 0xB2, 0xC3, 0x35, 0x40, 0xB2, 0x6D, 0x8C, - 0x3B, 0xD3, 0xED, 0x44, 0xB3, 0x4F, 0xBE, 0x8C, - 0x2A, 0x9D, 0x7F, 0x80, 0x5B, 0x5A, 0xDA, 0x0E, - 0xA2, 0x52, 0xEE, 0xAD, 0xE4, 0xFC, 0xE9, 0x7F, - 0x89, 0x72, 0x8A, 0xD8, 0x5B, 0xC8, 0xBB, 0x24, - 0x30, 0xB1, 0xBE, 0xF2, 0xCD, 0xDD, 0x32, 0xC8, - 0x44, 0x6E, 0x59, 0xB8, 0xE8, 0xBA, 0x3C, 0x67 - }, - { - 0x6D, 0x30, 0xB7, 0xC6, 0xCE, 0x8A, 0x32, 0x36, - 0xC0, 0xCA, 0x2F, 0x8D, 0x72, 0x8B, 0x10, 0x88, - 0xCA, 0x06, 0x98, 0x3A, 0x80, 0x43, 0xE6, 0x21, - 0xD5, 0xDC, 0xF0, 0xC5, 0x37, 0xD1, 0x3B, 0x08, - 0x79, 0x1E, 0xDE, 0xB0, 0x1A, 0x3C, 0xF0, 0x94, - 0x3E, 0xC1, 0xC8, 0x90, 0xAB, 0x6E, 0x29, 0xB1, - 0x46, 0xA2, 0x36, 0xCD, 0x46, 0xBC, 0xB9, 0xD9, - 0x3B, 0xF5, 0x16, 0xFB, 0x67, 0xC6, 0x3F, 0xE5 - }, - { - 0x97, 0xFE, 0x03, 0xCE, 0xF3, 0x14, 0x38, 0x50, - 0x89, 0x11, 0xBD, 0xED, 0x97, 0x59, 0x80, 0xA6, - 0x60, 0x29, 0x30, 0x5D, 0xC5, 0xE3, 0xFA, 0x8A, - 0xD1, 0xB4, 0xFB, 0x22, 0xFC, 0xDF, 0x5A, 0x19, - 0xA7, 0x33, 0x32, 0x03, 0x27, 0xD8, 0xF7, 0x1C, - 0xCF, 0x49, 0x6C, 0xB3, 0xA4, 0x4A, 0x77, 0xAF, - 0x56, 0xE3, 0xDD, 0xE7, 0x3D, 0x3A, 0x5F, 0x17, - 0x68, 0x96, 0xCC, 0x57, 0xC9, 0xA5, 0xAD, 0x99 - }, - { - 0x78, 0x5A, 0x9D, 0x0F, 0xBD, 0x21, 0x13, 0x6D, - 0xBC, 0xE8, 0xFA, 0x7E, 0xAF, 0xD6, 0x3C, 0x9D, - 0xAD, 0x22, 0x00, 0x52, 0x97, 0x84, 0x16, 0xB3, - 0x1D, 0x97, 0x53, 0xEA, 0xA1, 0x49, 0x09, 0x78, - 0x47, 0xED, 0x9B, 0x30, 0xA6, 0x5C, 0x70, 0x50, - 0x7E, 0xFF, 0x01, 0x87, 0x91, 0x49, 0xED, 0x5C, - 0xF0, 0x47, 0x1D, 0x37, 0x79, 0x8E, 0xDC, 0x05, - 0xAB, 0xD5, 0x6A, 0xD4, 0xA2, 0xCC, 0xCB, 0x1D - }, - { - 0xAD, 0x40, 0x8D, 0x2A, 0xBD, 0xDF, 0xD3, 0x7B, - 0x3B, 0xF3, 0x47, 0x94, 0xC1, 0xA3, 0x37, 0x1D, - 0x92, 0x8E, 0xD7, 0xFC, 0x8D, 0x96, 0x62, 0x25, - 0x33, 0x35, 0x84, 0xC5, 0x66, 0x58, 0x17, 0x83, - 0x2A, 0x37, 0xC0, 0x7F, 0x0D, 0xC7, 0xCB, 0x5A, - 0xA8, 0x74, 0xCD, 0x7D, 0x20, 0xFE, 0x8F, 0xAB, - 0x8E, 0xAB, 0xCB, 0x9B, 0x33, 0xD2, 0xE0, 0x84, - 0x1F, 0x6E, 0x20, 0x09, 0x60, 0x89, 0x9D, 0x95 - }, - { - 0x97, 0x66, 0x8F, 0x74, 0x5B, 0x60, 0x32, 0xFC, - 0x81, 0x5D, 0x95, 0x79, 0x32, 0x27, 0x69, 0xDC, - 0xCD, 0x95, 0x01, 0xA5, 0x08, 0x00, 0x29, 0xB8, - 0xAE, 0x82, 0x6B, 0xEF, 0xB6, 0x74, 0x23, 0x31, - 0xBD, 0x9F, 0x76, 0xEF, 0xEB, 0x3E, 0x2B, 0x8E, - 0x81, 0xA9, 0x78, 0x6B, 0x28, 0x2F, 0x50, 0x68, - 0xA3, 0xA2, 0x42, 0x46, 0x97, 0xA7, 0x7C, 0x41, - 0x87, 0x6B, 0x7E, 0x75, 0x3F, 0x4C, 0x77, 0x67 - }, - { - 0x26, 0xBB, 0x98, 0x5F, 0x47, 0xE7, 0xFE, 0xE0, - 0xCF, 0xD2, 0x52, 0xD4, 0xEF, 0x96, 0xBE, 0xD4, - 0x2B, 0x9C, 0x37, 0x0C, 0x1C, 0x6A, 0x3E, 0x8C, - 0x9E, 0xB0, 0x4E, 0xF7, 0xF7, 0x81, 0x8B, 0x83, - 0x3A, 0x0D, 0x1F, 0x04, 0x3E, 0xBA, 0xFB, 0x91, - 0x1D, 0xC7, 0x79, 0xE0, 0x27, 0x40, 0xA0, 0x2A, - 0x44, 0xD3, 0xA1, 0xEA, 0x45, 0xED, 0x4A, 0xD5, - 0x5E, 0x68, 0x6C, 0x92, 0x7C, 0xAF, 0xE9, 0x7E - }, - { - 0x5B, 0xFE, 0x2B, 0x1D, 0xCF, 0x7F, 0xE9, 0xB9, - 0x50, 0x88, 0xAC, 0xED, 0xB5, 0x75, 0xC1, 0x90, - 0x16, 0xC7, 0x43, 0xB2, 0xE7, 0x63, 0xBF, 0x58, - 0x51, 0xAC, 0x40, 0x7C, 0x9E, 0xDA, 0x43, 0x71, - 0x5E, 0xDF, 0xA4, 0x8B, 0x48, 0x25, 0x49, 0x2C, - 0x51, 0x79, 0x59, 0x3F, 0xFF, 0x21, 0x35, 0x1B, - 0x76, 0xE8, 0xB7, 0xE0, 0x34, 0xE4, 0xC5, 0x3C, - 0x79, 0xF6, 0x1F, 0x29, 0xC4, 0x79, 0xBD, 0x08 - }, - { - 0xC7, 0x65, 0x09, 0xEF, 0x72, 0xF4, 0xA6, 0xF9, - 0xC9, 0xC4, 0x06, 0x18, 0xED, 0x52, 0xB2, 0x08, - 0x4F, 0x83, 0x50, 0x22, 0x32, 0xE0, 0xAC, 0x8B, - 0xDA, 0xF3, 0x26, 0x43, 0x68, 0xE4, 0xD0, 0x18, - 0x0F, 0x68, 0x54, 0xC4, 0xAB, 0xF4, 0xF6, 0x50, - 0x9C, 0x79, 0xCA, 0xAF, 0xC4, 0x4C, 0xF3, 0x19, - 0x4A, 0xFC, 0x57, 0xBD, 0x07, 0x7B, 0xD7, 0xB3, - 0xC9, 0xBD, 0xA3, 0xD4, 0xB8, 0x77, 0x58, 0x16 - }, - { - 0xD6, 0x6F, 0x2B, 0xEA, 0xB9, 0x90, 0xE3, 0x54, - 0xCC, 0xB9, 0x10, 0xE4, 0xE9, 0xC7, 0xAC, 0x61, - 0x8C, 0x7B, 0x63, 0xEF, 0x29, 0x2A, 0x96, 0xB5, - 0x52, 0x34, 0x1D, 0xE7, 0x8D, 0xC4, 0x6D, 0x3E, - 0xC8, 0xCF, 0xAB, 0xC6, 0x99, 0xB5, 0x0A, 0xF4, - 0x1F, 0xDA, 0x39, 0xCF, 0x1B, 0x01, 0x73, 0x66, - 0x09, 0x23, 0x51, 0x0A, 0xD6, 0x7F, 0xAE, 0xDE, - 0xF5, 0x20, 0x7C, 0xFF, 0xE8, 0x64, 0x1D, 0x20 - }, - { - 0x7D, 0x8F, 0x06, 0x72, 0x99, 0x2B, 0x79, 0xBE, - 0x3A, 0x36, 0x4D, 0x8E, 0x59, 0x04, 0xF4, 0xAB, - 0x71, 0x3B, 0xBC, 0x8A, 0xB0, 0x1B, 0x4F, 0x30, - 0x9A, 0xD8, 0xCC, 0xF2, 0x23, 0xCE, 0x10, 0x34, - 0xA8, 0x60, 0xDC, 0xB0, 0xB0, 0x05, 0x50, 0x61, - 0x2C, 0xC2, 0xFA, 0x17, 0xF2, 0x96, 0x9E, 0x18, - 0xF2, 0x2E, 0x14, 0x27, 0xD2, 0x54, 0xB4, 0xA8, - 0x2B, 0x3A, 0x03, 0xA3, 0xEB, 0x39, 0x4A, 0xDF - }, - { - 0xA5, 0x6D, 0x67, 0x25, 0xBF, 0xB3, 0xDE, 0x47, - 0xC1, 0x41, 0x4A, 0xDF, 0x25, 0xFC, 0x8F, 0x0F, - 0xC9, 0x84, 0x6F, 0x69, 0x87, 0x72, 0x2B, 0xC0, - 0x63, 0x66, 0xD5, 0xCA, 0x4E, 0x89, 0x72, 0x29, - 0x25, 0xEB, 0xBC, 0x88, 0x14, 0x18, 0x84, 0x40, - 0x75, 0x39, 0x7A, 0x0C, 0xA8, 0x98, 0x42, 0xC7, - 0xB9, 0xE9, 0xE0, 0x7E, 0x1D, 0x9D, 0x18, 0x3E, - 0xBE, 0xB3, 0x9E, 0x12, 0x0B, 0x48, 0x3B, 0xF7 - }, - { - 0xAF, 0x5E, 0x03, 0xD7, 0xFE, 0x60, 0xC6, 0x7E, - 0x10, 0x31, 0x33, 0x44, 0x43, 0x4E, 0x79, 0x48, - 0x5A, 0x03, 0xA7, 0x58, 0xD6, 0xDC, 0xE9, 0x85, - 0x57, 0x47, 0x45, 0x76, 0x3C, 0x1C, 0x5C, 0x77, - 0xD4, 0xFB, 0x3E, 0x6F, 0xB1, 0x22, 0x30, 0x36, - 0x83, 0x70, 0x99, 0x3B, 0xF9, 0x0F, 0xEE, 0xD0, - 0xC5, 0xD1, 0x60, 0x75, 0x24, 0x56, 0x2D, 0x7C, - 0x09, 0xC0, 0xC2, 0x10, 0xED, 0x39, 0x3D, 0x7C - }, - { - 0x7A, 0x20, 0x54, 0x0C, 0xC0, 0x7B, 0xF7, 0x2B, - 0x58, 0x24, 0x21, 0xFC, 0x34, 0x2E, 0x82, 0xF5, - 0x21, 0x34, 0xB6, 0x98, 0x41, 0xEC, 0x28, 0xED, - 0x18, 0x9E, 0x2E, 0xA6, 0xA2, 0x9D, 0xD2, 0xF8, - 0x2A, 0x64, 0x03, 0x52, 0xD2, 0x22, 0xB5, 0x2F, - 0x29, 0x11, 0xDC, 0x72, 0xA7, 0xDA, 0xB3, 0x1C, - 0xAA, 0xDD, 0x80, 0xC6, 0x11, 0x8F, 0x13, 0xC5, - 0x6B, 0x2A, 0x1E, 0x43, 0x73, 0xBE, 0x0E, 0xA3 - }, - { - 0x48, 0x6F, 0x02, 0xC6, 0x3E, 0x54, 0x67, 0xEA, - 0x1F, 0xDD, 0xE7, 0xE8, 0x2B, 0xFA, 0xCC, 0x2C, - 0x1B, 0xA5, 0xD6, 0x36, 0xD9, 0xF3, 0xD0, 0x8B, - 0x21, 0x0D, 0xA3, 0xF3, 0x72, 0xF7, 0x06, 0xEC, - 0x21, 0x8C, 0xC1, 0x7F, 0xF6, 0x0A, 0xEF, 0x70, - 0x3B, 0xBE, 0x0C, 0x15, 0xC3, 0x8A, 0xE5, 0x5D, - 0x28, 0x6A, 0x68, 0x4F, 0x86, 0x4C, 0x78, 0x21, - 0x1C, 0xCA, 0xB4, 0x17, 0x8C, 0x92, 0xAD, 0xBA - }, - { - 0x1C, 0x7A, 0x5C, 0x1D, 0xED, 0xCD, 0x04, 0xA9, - 0x21, 0x78, 0x8F, 0x7E, 0xB2, 0x33, 0x61, 0xCA, - 0x19, 0x53, 0xB0, 0x4B, 0x9C, 0x7A, 0xEC, 0x35, - 0xD6, 0x5E, 0xA3, 0xE4, 0x99, 0x6D, 0xB2, 0x6F, - 0x28, 0x12, 0x78, 0xEA, 0x4A, 0xE6, 0x66, 0xAD, - 0x81, 0x02, 0x7D, 0x98, 0xAF, 0x57, 0x26, 0x2C, - 0xDB, 0xFA, 0x4C, 0x08, 0x5F, 0x42, 0x10, 0x56, - 0x8C, 0x7E, 0x15, 0xEE, 0xC7, 0x80, 0x51, 0x14 - }, - { - 0x9C, 0xE3, 0xFA, 0x9A, 0x86, 0x0B, 0xDB, 0xD5, - 0x37, 0x8F, 0xD6, 0xD7, 0xB8, 0xB6, 0x71, 0xC6, - 0xCB, 0x76, 0x92, 0x91, 0x0C, 0xE8, 0xF9, 0xB6, - 0xCB, 0x41, 0x22, 0xCB, 0xCB, 0xE6, 0xAC, 0x06, - 0xCA, 0x04, 0x22, 0xCE, 0xF1, 0x22, 0x59, 0x35, - 0x05, 0x3B, 0x7D, 0x19, 0x3A, 0x81, 0xB9, 0xE9, - 0x72, 0xEB, 0x85, 0xA1, 0xD3, 0x07, 0x4F, 0x14, - 0xCB, 0xB5, 0xEC, 0x9F, 0x05, 0x73, 0x89, 0x2D - }, - { - 0xA9, 0x11, 0x87, 0xBE, 0x5C, 0x37, 0x1C, 0x42, - 0x65, 0xC1, 0x74, 0xFD, 0x46, 0x53, 0xB8, 0xAB, - 0x70, 0x85, 0x51, 0xF8, 0x3D, 0x1F, 0xEE, 0x1C, - 0xC1, 0x47, 0x95, 0x81, 0xBC, 0x00, 0x6D, 0x6F, - 0xB7, 0x8F, 0xCC, 0x9A, 0x5D, 0xEE, 0x1D, 0xB3, - 0x66, 0x6F, 0x50, 0x8F, 0x97, 0x80, 0xA3, 0x75, - 0x93, 0xEB, 0xCC, 0xCF, 0x5F, 0xBE, 0xD3, 0x96, - 0x67, 0xDC, 0x63, 0x61, 0xE9, 0x21, 0xF7, 0x79 - }, - { - 0x46, 0x25, 0x76, 0x7D, 0x7B, 0x1D, 0x3D, 0x3E, - 0xD2, 0xFB, 0xC6, 0x74, 0xAF, 0x14, 0xE0, 0x24, - 0x41, 0x52, 0xF2, 0xA4, 0x02, 0x1F, 0xCF, 0x33, - 0x11, 0x50, 0x5D, 0x89, 0xBD, 0x81, 0xE2, 0xF9, - 0xF9, 0xA5, 0x00, 0xC3, 0xB1, 0x99, 0x91, 0x4D, - 0xB4, 0x95, 0x00, 0xB3, 0xC9, 0x8D, 0x03, 0xEA, - 0x93, 0x28, 0x67, 0x51, 0xA6, 0x86, 0xA3, 0xB8, - 0x75, 0xDA, 0xAB, 0x0C, 0xCD, 0x63, 0xB4, 0x4F - }, - { - 0x43, 0xDF, 0xDF, 0xE1, 0xB0, 0x14, 0xFE, 0xD3, - 0xA2, 0xAC, 0xAB, 0xB7, 0xF3, 0xE9, 0xA1, 0x82, - 0xF2, 0xAA, 0x18, 0x01, 0x9D, 0x27, 0xE3, 0xE6, - 0xCD, 0xCF, 0x31, 0xA1, 0x5B, 0x42, 0x8E, 0x91, - 0xE7, 0xB0, 0x8C, 0xF5, 0xE5, 0xC3, 0x76, 0xFC, - 0xE2, 0xD8, 0xA2, 0x8F, 0xF8, 0x5A, 0xB0, 0xA0, - 0xA1, 0x65, 0x6E, 0xDB, 0x4A, 0x0A, 0x91, 0x53, - 0x26, 0x20, 0x09, 0x6D, 0x9A, 0x5A, 0x65, 0x2D - }, - { - 0x27, 0x9E, 0x32, 0x02, 0xBE, 0x39, 0x89, 0xBA, - 0x31, 0x12, 0x77, 0x25, 0x85, 0x17, 0x74, 0x87, - 0xE4, 0xFE, 0x3E, 0xE3, 0xEA, 0xB4, 0x9C, 0x2F, - 0x7F, 0xA7, 0xFE, 0x87, 0xCF, 0xE7, 0xB8, 0x0D, - 0x3E, 0x03, 0x55, 0xED, 0xFF, 0x6D, 0x03, 0x1E, - 0x6C, 0x96, 0xC7, 0x95, 0xDB, 0x1C, 0x6F, 0x04, - 0x18, 0x80, 0xEC, 0x38, 0x24, 0xDE, 0xFA, 0xCF, - 0x92, 0x63, 0x82, 0x0A, 0x8E, 0x73, 0x27, 0xDE - }, - { - 0xEA, 0x2D, 0x06, 0x6A, 0xC2, 0x29, 0xD4, 0xD4, - 0xB6, 0x16, 0xA8, 0xBE, 0xDE, 0xC7, 0x34, 0x32, - 0x52, 0x24, 0xE4, 0xB4, 0xE5, 0x8F, 0x1A, 0xE6, - 0xDA, 0xD7, 0xE4, 0x0C, 0x2D, 0xA2, 0x91, 0x96, - 0xC3, 0xB1, 0xEA, 0x95, 0x71, 0xDA, 0xCC, 0x81, - 0xE8, 0x73, 0x28, 0xCA, 0xA0, 0x21, 0x1E, 0x09, - 0x02, 0x7B, 0x05, 0x24, 0xAA, 0x3F, 0x4A, 0x84, - 0x99, 0x17, 0xB3, 0x58, 0x67, 0x47, 0xEB, 0xBB - }, - { - 0x49, 0xF0, 0x14, 0xF5, 0xC6, 0x18, 0x22, 0xC8, - 0x99, 0xAB, 0x5C, 0xAE, 0x51, 0xBE, 0x40, 0x44, - 0xA4, 0x49, 0x5E, 0x77, 0x7D, 0xEB, 0x7D, 0xA9, - 0xB6, 0xD8, 0x49, 0x0E, 0xFB, 0xB8, 0x75, 0x30, - 0xAD, 0xF2, 0x93, 0xDA, 0xF0, 0x79, 0xF9, 0x4C, - 0x33, 0xB7, 0x04, 0x4E, 0xF6, 0x2E, 0x2E, 0x5B, - 0xB3, 0xEB, 0x11, 0xE1, 0x73, 0x04, 0xF8, 0x45, - 0x3E, 0xE6, 0xCE, 0x24, 0xF0, 0x33, 0xDD, 0xB0 - }, - { - 0x92, 0x33, 0x49, 0x03, 0x44, 0xE5, 0xB0, 0xDC, - 0x59, 0x12, 0x67, 0x1B, 0x7A, 0xE5, 0x4C, 0xEE, - 0x77, 0x30, 0xDB, 0xE1, 0xF4, 0xC7, 0xD9, 0x2A, - 0x4D, 0x3E, 0x3A, 0xAB, 0x50, 0x57, 0x17, 0x08, - 0xDB, 0x51, 0xDC, 0xF9, 0xC2, 0x94, 0x45, 0x91, - 0xDB, 0x65, 0x1D, 0xB3, 0x2D, 0x22, 0x93, 0x5B, - 0x86, 0x94, 0x49, 0x69, 0xBE, 0x77, 0xD5, 0xB5, - 0xFE, 0xAE, 0x6C, 0x38, 0x40, 0xA8, 0xDB, 0x26 - }, - { - 0xB6, 0xE7, 0x5E, 0x6F, 0x4C, 0x7F, 0x45, 0x3B, - 0x74, 0x65, 0xD2, 0x5B, 0x5A, 0xC8, 0xC7, 0x19, - 0x69, 0x02, 0xEA, 0xA9, 0x53, 0x87, 0x52, 0x28, - 0xC8, 0x63, 0x4E, 0x16, 0xE2, 0xAE, 0x1F, 0x38, - 0xBC, 0x32, 0x75, 0x30, 0x43, 0x35, 0xF5, 0x98, - 0x9E, 0xCC, 0xC1, 0xE3, 0x41, 0x67, 0xD4, 0xE6, - 0x8D, 0x77, 0x19, 0x96, 0x8F, 0xBA, 0x8E, 0x2F, - 0xE6, 0x79, 0x47, 0xC3, 0x5C, 0x48, 0xE8, 0x06 - }, - { - 0xCC, 0x14, 0xCA, 0x66, 0x5A, 0xF1, 0x48, 0x3E, - 0xFB, 0xC3, 0xAF, 0x80, 0x08, 0x0E, 0x65, 0x0D, - 0x50, 0x46, 0xA3, 0x93, 0x2F, 0x4F, 0x51, 0xF3, - 0xFE, 0x90, 0xA0, 0x70, 0x5E, 0xC2, 0x51, 0x04, - 0xAD, 0xF0, 0x78, 0x39, 0x26, 0x5D, 0xC5, 0x1D, - 0x43, 0x40, 0x14, 0x11, 0x24, 0x6E, 0x47, 0x4F, - 0x0D, 0x5E, 0x56, 0x37, 0xAF, 0x94, 0x76, 0x72, - 0x83, 0xD5, 0x3E, 0x06, 0x17, 0xE9, 0x81, 0xF4 - }, - { - 0x23, 0x0A, 0x1C, 0x85, 0x7C, 0xB2, 0xE7, 0x85, - 0x2E, 0x41, 0xB6, 0x47, 0xE9, 0x0E, 0x45, 0x85, - 0xD2, 0xD8, 0x81, 0xE1, 0x73, 0x4D, 0xC3, 0x89, - 0x55, 0x35, 0x6E, 0x8D, 0xD7, 0xBF, 0xF3, 0x90, - 0x53, 0x09, 0x2C, 0x6B, 0x38, 0xE2, 0x36, 0xE1, - 0x89, 0x95, 0x25, 0x64, 0x70, 0x73, 0xDD, 0xDF, - 0x68, 0x95, 0xD6, 0x42, 0x06, 0x32, 0x5E, 0x76, - 0x47, 0xF2, 0x75, 0x56, 0x7B, 0x25, 0x59, 0x09 - }, - { - 0xCB, 0xB6, 0x53, 0x21, 0xAC, 0x43, 0x6E, 0x2F, - 0xFD, 0xAB, 0x29, 0x36, 0x35, 0x9C, 0xE4, 0x90, - 0x23, 0xF7, 0xDE, 0xE7, 0x61, 0x4E, 0xF2, 0x8D, - 0x17, 0x3C, 0x3D, 0x27, 0xC5, 0xD1, 0xBF, 0xFA, - 0x51, 0x55, 0x3D, 0x43, 0x3F, 0x8E, 0xE3, 0xC9, - 0xE4, 0x9C, 0x05, 0xA2, 0xB8, 0x83, 0xCC, 0xE9, - 0x54, 0xC9, 0xA8, 0x09, 0x3B, 0x80, 0x61, 0x2A, - 0x0C, 0xDD, 0x47, 0x32, 0xE0, 0x41, 0xF9, 0x95 - }, - { - 0x3E, 0x7E, 0x57, 0x00, 0x74, 0x33, 0x72, 0x75, - 0xEF, 0xB5, 0x13, 0x15, 0x58, 0x80, 0x34, 0xC3, - 0xCF, 0x0D, 0xDD, 0xCA, 0x20, 0xB4, 0x61, 0x2E, - 0x0B, 0xD5, 0xB8, 0x81, 0xE7, 0xE5, 0x47, 0x6D, - 0x31, 0x9C, 0xE4, 0xFE, 0x9F, 0x19, 0x18, 0x6E, - 0x4C, 0x08, 0x26, 0xF4, 0x4F, 0x13, 0x1E, 0xB0, - 0x48, 0xE6, 0x5B, 0xE2, 0x42, 0xB1, 0x17, 0x2C, - 0x63, 0xBA, 0xDB, 0x12, 0x3A, 0xB0, 0xCB, 0xE8 - }, - { - 0xD3, 0x2E, 0x9E, 0xC0, 0x2D, 0x38, 0xD4, 0xE1, - 0xB8, 0x24, 0x9D, 0xF8, 0xDC, 0xB0, 0x0C, 0x5B, - 0x9C, 0x68, 0xEB, 0x89, 0x22, 0x67, 0x2E, 0x35, - 0x05, 0x39, 0x3B, 0x6A, 0x21, 0x0B, 0xA5, 0x6F, - 0x94, 0x96, 0xE5, 0xEE, 0x04, 0x90, 0xEF, 0x38, - 0x7C, 0x3C, 0xDE, 0xC0, 0x61, 0xF0, 0x6B, 0xC0, - 0x38, 0x2D, 0x93, 0x04, 0xCA, 0xFB, 0xB8, 0xE0, - 0xCD, 0x33, 0xD5, 0x70, 0x29, 0xE6, 0x2D, 0xF2 - }, - { - 0x8C, 0x15, 0x12, 0x46, 0x60, 0x89, 0xF0, 0x5B, - 0x37, 0x75, 0xC2, 0x62, 0xB6, 0x2D, 0x22, 0xB8, - 0x38, 0x54, 0xA8, 0x32, 0x18, 0x13, 0x0B, 0x4E, - 0xC9, 0x1B, 0x3C, 0xCB, 0xD2, 0x93, 0xD2, 0xA5, - 0x43, 0x02, 0xCE, 0xCA, 0xAB, 0x9B, 0x10, 0x0C, - 0x68, 0xD1, 0xE6, 0xDD, 0xC8, 0xF0, 0x7C, 0xDD, - 0xBD, 0xFE, 0x6F, 0xDA, 0xAA, 0xF0, 0x99, 0xCC, - 0x09, 0xD6, 0xB7, 0x25, 0x87, 0x9C, 0x63, 0x69 - }, - { - 0x91, 0xA7, 0xF6, 0x1C, 0x97, 0xC2, 0x91, 0x1E, - 0x4C, 0x81, 0x2E, 0xF7, 0x1D, 0x78, 0x0A, 0xD8, - 0xFA, 0x78, 0x87, 0x94, 0x56, 0x1D, 0x08, 0x30, - 0x3F, 0xD1, 0xC1, 0xCB, 0x60, 0x8A, 0x46, 0xA1, - 0x25, 0x63, 0x08, 0x6E, 0xC5, 0xB3, 0x9D, 0x47, - 0x1A, 0xED, 0x94, 0xFB, 0x0F, 0x6C, 0x67, 0x8A, - 0x43, 0xB8, 0x79, 0x29, 0x32, 0xF9, 0x02, 0x8D, - 0x77, 0x2A, 0x22, 0x76, 0x8E, 0xA2, 0x3A, 0x9B - }, - { - 0x4F, 0x6B, 0xB2, 0x22, 0xA3, 0x95, 0xE8, 0xB1, - 0x8F, 0x6B, 0xA1, 0x55, 0x47, 0x7A, 0xED, 0x3F, - 0x07, 0x29, 0xAC, 0x9E, 0x83, 0xE1, 0x6D, 0x31, - 0xA2, 0xA8, 0xBC, 0x65, 0x54, 0x22, 0xB8, 0x37, - 0xC8, 0x91, 0xC6, 0x19, 0x9E, 0x6F, 0x0D, 0x75, - 0x79, 0x9E, 0x3B, 0x69, 0x15, 0x25, 0xC5, 0x81, - 0x95, 0x35, 0x17, 0xF2, 0x52, 0xC4, 0xB9, 0xE3, - 0xA2, 0x7A, 0x28, 0xFB, 0xAF, 0x49, 0x64, 0x4C - }, - { - 0x5D, 0x06, 0xC0, 0x7E, 0x7A, 0x64, 0x6C, 0x41, - 0x3A, 0x50, 0x1C, 0x3F, 0x4B, 0xB2, 0xFC, 0x38, - 0x12, 0x7D, 0xE7, 0x50, 0x9B, 0x70, 0x77, 0xC4, - 0xD9, 0xB5, 0x61, 0x32, 0x01, 0xC1, 0xAA, 0x02, - 0xFD, 0x5F, 0x79, 0xD2, 0x74, 0x59, 0x15, 0xDD, - 0x57, 0xFB, 0xCB, 0x4C, 0xE0, 0x86, 0x95, 0xF6, - 0xEF, 0xC0, 0xCB, 0x3D, 0x2D, 0x33, 0x0E, 0x19, - 0xB4, 0xB0, 0xE6, 0x00, 0x4E, 0xA6, 0x47, 0x1E - }, - { - 0xB9, 0x67, 0x56, 0xE5, 0x79, 0x09, 0x96, 0x8F, - 0x14, 0xB7, 0x96, 0xA5, 0xD3, 0x0F, 0x4C, 0x9D, - 0x67, 0x14, 0x72, 0xCF, 0x82, 0xC8, 0xCF, 0xB2, - 0xCA, 0xCA, 0x7A, 0xC7, 0xA4, 0x4C, 0xA0, 0xA1, - 0x4C, 0x98, 0x42, 0xD0, 0x0C, 0x82, 0xE3, 0x37, - 0x50, 0x2C, 0x94, 0xD5, 0x96, 0x0A, 0xCA, 0x4C, - 0x49, 0x2E, 0xA7, 0xB0, 0xDF, 0x91, 0x9D, 0xDF, - 0x1A, 0xAD, 0xA2, 0xA2, 0x75, 0xBB, 0x10, 0xD4 - }, - { - 0xFF, 0x0A, 0x01, 0x5E, 0x98, 0xDB, 0x9C, 0x99, - 0xF0, 0x39, 0x77, 0x71, 0x0A, 0xAC, 0x3E, 0x65, - 0x8C, 0x0D, 0x89, 0x6F, 0x6D, 0x71, 0xD6, 0x18, - 0xBA, 0x79, 0xDC, 0x6C, 0xF7, 0x2A, 0xC7, 0x5B, - 0x7C, 0x03, 0x8E, 0xB6, 0x86, 0x2D, 0xED, 0xE4, - 0x54, 0x3E, 0x14, 0x54, 0x13, 0xA6, 0x36, 0x8D, - 0x69, 0xF5, 0x72, 0x2C, 0x82, 0x7B, 0xA3, 0xEF, - 0x25, 0xB6, 0xAE, 0x64, 0x40, 0xD3, 0x92, 0x76 - }, - { - 0x5B, 0x21, 0xC5, 0xFD, 0x88, 0x68, 0x36, 0x76, - 0x12, 0x47, 0x4F, 0xA2, 0xE7, 0x0E, 0x9C, 0xFA, - 0x22, 0x01, 0xFF, 0xEE, 0xE8, 0xFA, 0xFA, 0xB5, - 0x79, 0x7A, 0xD5, 0x8F, 0xEF, 0xA1, 0x7C, 0x9B, - 0x5B, 0x10, 0x7D, 0xA4, 0xA3, 0xDB, 0x63, 0x20, - 0xBA, 0xAF, 0x2C, 0x86, 0x17, 0xD5, 0xA5, 0x1D, - 0xF9, 0x14, 0xAE, 0x88, 0xDA, 0x38, 0x67, 0xC2, - 0xD4, 0x1F, 0x0C, 0xC1, 0x4F, 0xA6, 0x79, 0x28 - }, -}; - - - - -static const uint8_t blake2b_keyed_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = -{ - { - 0x10, 0xEB, 0xB6, 0x77, 0x00, 0xB1, 0x86, 0x8E, - 0xFB, 0x44, 0x17, 0x98, 0x7A, 0xCF, 0x46, 0x90, - 0xAE, 0x9D, 0x97, 0x2F, 0xB7, 0xA5, 0x90, 0xC2, - 0xF0, 0x28, 0x71, 0x79, 0x9A, 0xAA, 0x47, 0x86, - 0xB5, 0xE9, 0x96, 0xE8, 0xF0, 0xF4, 0xEB, 0x98, - 0x1F, 0xC2, 0x14, 0xB0, 0x05, 0xF4, 0x2D, 0x2F, - 0xF4, 0x23, 0x34, 0x99, 0x39, 0x16, 0x53, 0xDF, - 0x7A, 0xEF, 0xCB, 0xC1, 0x3F, 0xC5, 0x15, 0x68 - }, - { - 0x96, 0x1F, 0x6D, 0xD1, 0xE4, 0xDD, 0x30, 0xF6, - 0x39, 0x01, 0x69, 0x0C, 0x51, 0x2E, 0x78, 0xE4, - 0xB4, 0x5E, 0x47, 0x42, 0xED, 0x19, 0x7C, 0x3C, - 0x5E, 0x45, 0xC5, 0x49, 0xFD, 0x25, 0xF2, 0xE4, - 0x18, 0x7B, 0x0B, 0xC9, 0xFE, 0x30, 0x49, 0x2B, - 0x16, 0xB0, 0xD0, 0xBC, 0x4E, 0xF9, 0xB0, 0xF3, - 0x4C, 0x70, 0x03, 0xFA, 0xC0, 0x9A, 0x5E, 0xF1, - 0x53, 0x2E, 0x69, 0x43, 0x02, 0x34, 0xCE, 0xBD - }, - { - 0xDA, 0x2C, 0xFB, 0xE2, 0xD8, 0x40, 0x9A, 0x0F, - 0x38, 0x02, 0x61, 0x13, 0x88, 0x4F, 0x84, 0xB5, - 0x01, 0x56, 0x37, 0x1A, 0xE3, 0x04, 0xC4, 0x43, - 0x01, 0x73, 0xD0, 0x8A, 0x99, 0xD9, 0xFB, 0x1B, - 0x98, 0x31, 0x64, 0xA3, 0x77, 0x07, 0x06, 0xD5, - 0x37, 0xF4, 0x9E, 0x0C, 0x91, 0x6D, 0x9F, 0x32, - 0xB9, 0x5C, 0xC3, 0x7A, 0x95, 0xB9, 0x9D, 0x85, - 0x74, 0x36, 0xF0, 0x23, 0x2C, 0x88, 0xA9, 0x65 - }, - { - 0x33, 0xD0, 0x82, 0x5D, 0xDD, 0xF7, 0xAD, 0xA9, - 0x9B, 0x0E, 0x7E, 0x30, 0x71, 0x04, 0xAD, 0x07, - 0xCA, 0x9C, 0xFD, 0x96, 0x92, 0x21, 0x4F, 0x15, - 0x61, 0x35, 0x63, 0x15, 0xE7, 0x84, 0xF3, 0xE5, - 0xA1, 0x7E, 0x36, 0x4A, 0xE9, 0xDB, 0xB1, 0x4C, - 0xB2, 0x03, 0x6D, 0xF9, 0x32, 0xB7, 0x7F, 0x4B, - 0x29, 0x27, 0x61, 0x36, 0x5F, 0xB3, 0x28, 0xDE, - 0x7A, 0xFD, 0xC6, 0xD8, 0x99, 0x8F, 0x5F, 0xC1 - }, - { - 0xBE, 0xAA, 0x5A, 0x3D, 0x08, 0xF3, 0x80, 0x71, - 0x43, 0xCF, 0x62, 0x1D, 0x95, 0xCD, 0x69, 0x05, - 0x14, 0xD0, 0xB4, 0x9E, 0xFF, 0xF9, 0xC9, 0x1D, - 0x24, 0xB5, 0x92, 0x41, 0xEC, 0x0E, 0xEF, 0xA5, - 0xF6, 0x01, 0x96, 0xD4, 0x07, 0x04, 0x8B, 0xBA, - 0x8D, 0x21, 0x46, 0x82, 0x8E, 0xBC, 0xB0, 0x48, - 0x8D, 0x88, 0x42, 0xFD, 0x56, 0xBB, 0x4F, 0x6D, - 0xF8, 0xE1, 0x9C, 0x4B, 0x4D, 0xAA, 0xB8, 0xAC - }, - { - 0x09, 0x80, 0x84, 0xB5, 0x1F, 0xD1, 0x3D, 0xEA, - 0xE5, 0xF4, 0x32, 0x0D, 0xE9, 0x4A, 0x68, 0x8E, - 0xE0, 0x7B, 0xAE, 0xA2, 0x80, 0x04, 0x86, 0x68, - 0x9A, 0x86, 0x36, 0x11, 0x7B, 0x46, 0xC1, 0xF4, - 0xC1, 0xF6, 0xAF, 0x7F, 0x74, 0xAE, 0x7C, 0x85, - 0x76, 0x00, 0x45, 0x6A, 0x58, 0xA3, 0xAF, 0x25, - 0x1D, 0xC4, 0x72, 0x3A, 0x64, 0xCC, 0x7C, 0x0A, - 0x5A, 0xB6, 0xD9, 0xCA, 0xC9, 0x1C, 0x20, 0xBB - }, - { - 0x60, 0x44, 0x54, 0x0D, 0x56, 0x08, 0x53, 0xEB, - 0x1C, 0x57, 0xDF, 0x00, 0x77, 0xDD, 0x38, 0x10, - 0x94, 0x78, 0x1C, 0xDB, 0x90, 0x73, 0xE5, 0xB1, - 0xB3, 0xD3, 0xF6, 0xC7, 0x82, 0x9E, 0x12, 0x06, - 0x6B, 0xBA, 0xCA, 0x96, 0xD9, 0x89, 0xA6, 0x90, - 0xDE, 0x72, 0xCA, 0x31, 0x33, 0xA8, 0x36, 0x52, - 0xBA, 0x28, 0x4A, 0x6D, 0x62, 0x94, 0x2B, 0x27, - 0x1F, 0xFA, 0x26, 0x20, 0xC9, 0xE7, 0x5B, 0x1F - }, - { - 0x7A, 0x8C, 0xFE, 0x9B, 0x90, 0xF7, 0x5F, 0x7E, - 0xCB, 0x3A, 0xCC, 0x05, 0x3A, 0xAE, 0xD6, 0x19, - 0x31, 0x12, 0xB6, 0xF6, 0xA4, 0xAE, 0xEB, 0x3F, - 0x65, 0xD3, 0xDE, 0x54, 0x19, 0x42, 0xDE, 0xB9, - 0xE2, 0x22, 0x81, 0x52, 0xA3, 0xC4, 0xBB, 0xBE, - 0x72, 0xFC, 0x3B, 0x12, 0x62, 0x95, 0x28, 0xCF, - 0xBB, 0x09, 0xFE, 0x63, 0x0F, 0x04, 0x74, 0x33, - 0x9F, 0x54, 0xAB, 0xF4, 0x53, 0xE2, 0xED, 0x52 - }, - { - 0x38, 0x0B, 0xEA, 0xF6, 0xEA, 0x7C, 0xC9, 0x36, - 0x5E, 0x27, 0x0E, 0xF0, 0xE6, 0xF3, 0xA6, 0x4F, - 0xB9, 0x02, 0xAC, 0xAE, 0x51, 0xDD, 0x55, 0x12, - 0xF8, 0x42, 0x59, 0xAD, 0x2C, 0x91, 0xF4, 0xBC, - 0x41, 0x08, 0xDB, 0x73, 0x19, 0x2A, 0x5B, 0xBF, - 0xB0, 0xCB, 0xCF, 0x71, 0xE4, 0x6C, 0x3E, 0x21, - 0xAE, 0xE1, 0xC5, 0xE8, 0x60, 0xDC, 0x96, 0xE8, - 0xEB, 0x0B, 0x7B, 0x84, 0x26, 0xE6, 0xAB, 0xE9 - }, - { - 0x60, 0xFE, 0x3C, 0x45, 0x35, 0xE1, 0xB5, 0x9D, - 0x9A, 0x61, 0xEA, 0x85, 0x00, 0xBF, 0xAC, 0x41, - 0xA6, 0x9D, 0xFF, 0xB1, 0xCE, 0xAD, 0xD9, 0xAC, - 0xA3, 0x23, 0xE9, 0xA6, 0x25, 0xB6, 0x4D, 0xA5, - 0x76, 0x3B, 0xAD, 0x72, 0x26, 0xDA, 0x02, 0xB9, - 0xC8, 0xC4, 0xF1, 0xA5, 0xDE, 0x14, 0x0A, 0xC5, - 0xA6, 0xC1, 0x12, 0x4E, 0x4F, 0x71, 0x8C, 0xE0, - 0xB2, 0x8E, 0xA4, 0x73, 0x93, 0xAA, 0x66, 0x37 - }, - { - 0x4F, 0xE1, 0x81, 0xF5, 0x4A, 0xD6, 0x3A, 0x29, - 0x83, 0xFE, 0xAA, 0xF7, 0x7D, 0x1E, 0x72, 0x35, - 0xC2, 0xBE, 0xB1, 0x7F, 0xA3, 0x28, 0xB6, 0xD9, - 0x50, 0x5B, 0xDA, 0x32, 0x7D, 0xF1, 0x9F, 0xC3, - 0x7F, 0x02, 0xC4, 0xB6, 0xF0, 0x36, 0x8C, 0xE2, - 0x31, 0x47, 0x31, 0x3A, 0x8E, 0x57, 0x38, 0xB5, - 0xFA, 0x2A, 0x95, 0xB2, 0x9D, 0xE1, 0xC7, 0xF8, - 0x26, 0x4E, 0xB7, 0x7B, 0x69, 0xF5, 0x85, 0xCD - }, - { - 0xF2, 0x28, 0x77, 0x3C, 0xE3, 0xF3, 0xA4, 0x2B, - 0x5F, 0x14, 0x4D, 0x63, 0x23, 0x7A, 0x72, 0xD9, - 0x96, 0x93, 0xAD, 0xB8, 0x83, 0x7D, 0x0E, 0x11, - 0x2A, 0x8A, 0x0F, 0x8F, 0xFF, 0xF2, 0xC3, 0x62, - 0x85, 0x7A, 0xC4, 0x9C, 0x11, 0xEC, 0x74, 0x0D, - 0x15, 0x00, 0x74, 0x9D, 0xAC, 0x9B, 0x1F, 0x45, - 0x48, 0x10, 0x8B, 0xF3, 0x15, 0x57, 0x94, 0xDC, - 0xC9, 0xE4, 0x08, 0x28, 0x49, 0xE2, 0xB8, 0x5B - }, - { - 0x96, 0x24, 0x52, 0xA8, 0x45, 0x5C, 0xC5, 0x6C, - 0x85, 0x11, 0x31, 0x7E, 0x3B, 0x1F, 0x3B, 0x2C, - 0x37, 0xDF, 0x75, 0xF5, 0x88, 0xE9, 0x43, 0x25, - 0xFD, 0xD7, 0x70, 0x70, 0x35, 0x9C, 0xF6, 0x3A, - 0x9A, 0xE6, 0xE9, 0x30, 0x93, 0x6F, 0xDF, 0x8E, - 0x1E, 0x08, 0xFF, 0xCA, 0x44, 0x0C, 0xFB, 0x72, - 0xC2, 0x8F, 0x06, 0xD8, 0x9A, 0x21, 0x51, 0xD1, - 0xC4, 0x6C, 0xD5, 0xB2, 0x68, 0xEF, 0x85, 0x63 - }, - { - 0x43, 0xD4, 0x4B, 0xFA, 0x18, 0x76, 0x8C, 0x59, - 0x89, 0x6B, 0xF7, 0xED, 0x17, 0x65, 0xCB, 0x2D, - 0x14, 0xAF, 0x8C, 0x26, 0x02, 0x66, 0x03, 0x90, - 0x99, 0xB2, 0x5A, 0x60, 0x3E, 0x4D, 0xDC, 0x50, - 0x39, 0xD6, 0xEF, 0x3A, 0x91, 0x84, 0x7D, 0x10, - 0x88, 0xD4, 0x01, 0xC0, 0xC7, 0xE8, 0x47, 0x78, - 0x1A, 0x8A, 0x59, 0x0D, 0x33, 0xA3, 0xC6, 0xCB, - 0x4D, 0xF0, 0xFA, 0xB1, 0xC2, 0xF2, 0x23, 0x55 - }, - { - 0xDC, 0xFF, 0xA9, 0xD5, 0x8C, 0x2A, 0x4C, 0xA2, - 0xCD, 0xBB, 0x0C, 0x7A, 0xA4, 0xC4, 0xC1, 0xD4, - 0x51, 0x65, 0x19, 0x00, 0x89, 0xF4, 0xE9, 0x83, - 0xBB, 0x1C, 0x2C, 0xAB, 0x4A, 0xAE, 0xFF, 0x1F, - 0xA2, 0xB5, 0xEE, 0x51, 0x6F, 0xEC, 0xD7, 0x80, - 0x54, 0x02, 0x40, 0xBF, 0x37, 0xE5, 0x6C, 0x8B, - 0xCC, 0xA7, 0xFA, 0xB9, 0x80, 0xE1, 0xE6, 0x1C, - 0x94, 0x00, 0xD8, 0xA9, 0xA5, 0xB1, 0x4A, 0xC6 - }, - { - 0x6F, 0xBF, 0x31, 0xB4, 0x5A, 0xB0, 0xC0, 0xB8, - 0xDA, 0xD1, 0xC0, 0xF5, 0xF4, 0x06, 0x13, 0x79, - 0x91, 0x2D, 0xDE, 0x5A, 0xA9, 0x22, 0x09, 0x9A, - 0x03, 0x0B, 0x72, 0x5C, 0x73, 0x34, 0x6C, 0x52, - 0x42, 0x91, 0xAD, 0xEF, 0x89, 0xD2, 0xF6, 0xFD, - 0x8D, 0xFC, 0xDA, 0x6D, 0x07, 0xDA, 0xD8, 0x11, - 0xA9, 0x31, 0x45, 0x36, 0xC2, 0x91, 0x5E, 0xD4, - 0x5D, 0xA3, 0x49, 0x47, 0xE8, 0x3D, 0xE3, 0x4E - }, - { - 0xA0, 0xC6, 0x5B, 0xDD, 0xDE, 0x8A, 0xDE, 0xF5, - 0x72, 0x82, 0xB0, 0x4B, 0x11, 0xE7, 0xBC, 0x8A, - 0xAB, 0x10, 0x5B, 0x99, 0x23, 0x1B, 0x75, 0x0C, - 0x02, 0x1F, 0x4A, 0x73, 0x5C, 0xB1, 0xBC, 0xFA, - 0xB8, 0x75, 0x53, 0xBB, 0xA3, 0xAB, 0xB0, 0xC3, - 0xE6, 0x4A, 0x0B, 0x69, 0x55, 0x28, 0x51, 0x85, - 0xA0, 0xBD, 0x35, 0xFB, 0x8C, 0xFD, 0xE5, 0x57, - 0x32, 0x9B, 0xEB, 0xB1, 0xF6, 0x29, 0xEE, 0x93 - }, - { - 0xF9, 0x9D, 0x81, 0x55, 0x50, 0x55, 0x8E, 0x81, - 0xEC, 0xA2, 0xF9, 0x67, 0x18, 0xAE, 0xD1, 0x0D, - 0x86, 0xF3, 0xF1, 0xCF, 0xB6, 0x75, 0xCC, 0xE0, - 0x6B, 0x0E, 0xFF, 0x02, 0xF6, 0x17, 0xC5, 0xA4, - 0x2C, 0x5A, 0xA7, 0x60, 0x27, 0x0F, 0x26, 0x79, - 0xDA, 0x26, 0x77, 0xC5, 0xAE, 0xB9, 0x4F, 0x11, - 0x42, 0x27, 0x7F, 0x21, 0xC7, 0xF7, 0x9F, 0x3C, - 0x4F, 0x0C, 0xCE, 0x4E, 0xD8, 0xEE, 0x62, 0xB1 - }, - { - 0x95, 0x39, 0x1D, 0xA8, 0xFC, 0x7B, 0x91, 0x7A, - 0x20, 0x44, 0xB3, 0xD6, 0xF5, 0x37, 0x4E, 0x1C, - 0xA0, 0x72, 0xB4, 0x14, 0x54, 0xD5, 0x72, 0xC7, - 0x35, 0x6C, 0x05, 0xFD, 0x4B, 0xC1, 0xE0, 0xF4, - 0x0B, 0x8B, 0xB8, 0xB4, 0xA9, 0xF6, 0xBC, 0xE9, - 0xBE, 0x2C, 0x46, 0x23, 0xC3, 0x99, 0xB0, 0xDC, - 0xA0, 0xDA, 0xB0, 0x5C, 0xB7, 0x28, 0x1B, 0x71, - 0xA2, 0x1B, 0x0E, 0xBC, 0xD9, 0xE5, 0x56, 0x70 - }, - { - 0x04, 0xB9, 0xCD, 0x3D, 0x20, 0xD2, 0x21, 0xC0, - 0x9A, 0xC8, 0x69, 0x13, 0xD3, 0xDC, 0x63, 0x04, - 0x19, 0x89, 0xA9, 0xA1, 0xE6, 0x94, 0xF1, 0xE6, - 0x39, 0xA3, 0xBA, 0x7E, 0x45, 0x18, 0x40, 0xF7, - 0x50, 0xC2, 0xFC, 0x19, 0x1D, 0x56, 0xAD, 0x61, - 0xF2, 0xE7, 0x93, 0x6B, 0xC0, 0xAC, 0x8E, 0x09, - 0x4B, 0x60, 0xCA, 0xEE, 0xD8, 0x78, 0xC1, 0x87, - 0x99, 0x04, 0x54, 0x02, 0xD6, 0x1C, 0xEA, 0xF9 - }, - { - 0xEC, 0x0E, 0x0E, 0xF7, 0x07, 0xE4, 0xED, 0x6C, - 0x0C, 0x66, 0xF9, 0xE0, 0x89, 0xE4, 0x95, 0x4B, - 0x05, 0x80, 0x30, 0xD2, 0xDD, 0x86, 0x39, 0x8F, - 0xE8, 0x40, 0x59, 0x63, 0x1F, 0x9E, 0xE5, 0x91, - 0xD9, 0xD7, 0x73, 0x75, 0x35, 0x51, 0x49, 0x17, - 0x8C, 0x0C, 0xF8, 0xF8, 0xE7, 0xC4, 0x9E, 0xD2, - 0xA5, 0xE4, 0xF9, 0x54, 0x88, 0xA2, 0x24, 0x70, - 0x67, 0xC2, 0x08, 0x51, 0x0F, 0xAD, 0xC4, 0x4C - }, - { - 0x9A, 0x37, 0xCC, 0xE2, 0x73, 0xB7, 0x9C, 0x09, - 0x91, 0x36, 0x77, 0x51, 0x0E, 0xAF, 0x76, 0x88, - 0xE8, 0x9B, 0x33, 0x14, 0xD3, 0x53, 0x2F, 0xD2, - 0x76, 0x4C, 0x39, 0xDE, 0x02, 0x2A, 0x29, 0x45, - 0xB5, 0x71, 0x0D, 0x13, 0x51, 0x7A, 0xF8, 0xDD, - 0xC0, 0x31, 0x66, 0x24, 0xE7, 0x3B, 0xEC, 0x1C, - 0xE6, 0x7D, 0xF1, 0x52, 0x28, 0x30, 0x20, 0x36, - 0xF3, 0x30, 0xAB, 0x0C, 0xB4, 0xD2, 0x18, 0xDD - }, - { - 0x4C, 0xF9, 0xBB, 0x8F, 0xB3, 0xD4, 0xDE, 0x8B, - 0x38, 0xB2, 0xF2, 0x62, 0xD3, 0xC4, 0x0F, 0x46, - 0xDF, 0xE7, 0x47, 0xE8, 0xFC, 0x0A, 0x41, 0x4C, - 0x19, 0x3D, 0x9F, 0xCF, 0x75, 0x31, 0x06, 0xCE, - 0x47, 0xA1, 0x8F, 0x17, 0x2F, 0x12, 0xE8, 0xA2, - 0xF1, 0xC2, 0x67, 0x26, 0x54, 0x53, 0x58, 0xE5, - 0xEE, 0x28, 0xC9, 0xE2, 0x21, 0x3A, 0x87, 0x87, - 0xAA, 0xFB, 0xC5, 0x16, 0xD2, 0x34, 0x31, 0x52 - }, - { - 0x64, 0xE0, 0xC6, 0x3A, 0xF9, 0xC8, 0x08, 0xFD, - 0x89, 0x31, 0x37, 0x12, 0x98, 0x67, 0xFD, 0x91, - 0x93, 0x9D, 0x53, 0xF2, 0xAF, 0x04, 0xBE, 0x4F, - 0xA2, 0x68, 0x00, 0x61, 0x00, 0x06, 0x9B, 0x2D, - 0x69, 0xDA, 0xA5, 0xC5, 0xD8, 0xED, 0x7F, 0xDD, - 0xCB, 0x2A, 0x70, 0xEE, 0xEC, 0xDF, 0x2B, 0x10, - 0x5D, 0xD4, 0x6A, 0x1E, 0x3B, 0x73, 0x11, 0x72, - 0x8F, 0x63, 0x9A, 0xB4, 0x89, 0x32, 0x6B, 0xC9 - }, - { - 0x5E, 0x9C, 0x93, 0x15, 0x8D, 0x65, 0x9B, 0x2D, - 0xEF, 0x06, 0xB0, 0xC3, 0xC7, 0x56, 0x50, 0x45, - 0x54, 0x26, 0x62, 0xD6, 0xEE, 0xE8, 0xA9, 0x6A, - 0x89, 0xB7, 0x8A, 0xDE, 0x09, 0xFE, 0x8B, 0x3D, - 0xCC, 0x09, 0x6D, 0x4F, 0xE4, 0x88, 0x15, 0xD8, - 0x8D, 0x8F, 0x82, 0x62, 0x01, 0x56, 0x60, 0x2A, - 0xF5, 0x41, 0x95, 0x5E, 0x1F, 0x6C, 0xA3, 0x0D, - 0xCE, 0x14, 0xE2, 0x54, 0xC3, 0x26, 0xB8, 0x8F - }, - { - 0x77, 0x75, 0xDF, 0xF8, 0x89, 0x45, 0x8D, 0xD1, - 0x1A, 0xEF, 0x41, 0x72, 0x76, 0x85, 0x3E, 0x21, - 0x33, 0x5E, 0xB8, 0x8E, 0x4D, 0xEC, 0x9C, 0xFB, - 0x4E, 0x9E, 0xDB, 0x49, 0x82, 0x00, 0x88, 0x55, - 0x1A, 0x2C, 0xA6, 0x03, 0x39, 0xF1, 0x20, 0x66, - 0x10, 0x11, 0x69, 0xF0, 0xDF, 0xE8, 0x4B, 0x09, - 0x8F, 0xDD, 0xB1, 0x48, 0xD9, 0xDA, 0x6B, 0x3D, - 0x61, 0x3D, 0xF2, 0x63, 0x88, 0x9A, 0xD6, 0x4B - }, - { - 0xF0, 0xD2, 0x80, 0x5A, 0xFB, 0xB9, 0x1F, 0x74, - 0x39, 0x51, 0x35, 0x1A, 0x6D, 0x02, 0x4F, 0x93, - 0x53, 0xA2, 0x3C, 0x7C, 0xE1, 0xFC, 0x2B, 0x05, - 0x1B, 0x3A, 0x8B, 0x96, 0x8C, 0x23, 0x3F, 0x46, - 0xF5, 0x0F, 0x80, 0x6E, 0xCB, 0x15, 0x68, 0xFF, - 0xAA, 0x0B, 0x60, 0x66, 0x1E, 0x33, 0x4B, 0x21, - 0xDD, 0xE0, 0x4F, 0x8F, 0xA1, 0x55, 0xAC, 0x74, - 0x0E, 0xEB, 0x42, 0xE2, 0x0B, 0x60, 0xD7, 0x64 - }, - { - 0x86, 0xA2, 0xAF, 0x31, 0x6E, 0x7D, 0x77, 0x54, - 0x20, 0x1B, 0x94, 0x2E, 0x27, 0x53, 0x64, 0xAC, - 0x12, 0xEA, 0x89, 0x62, 0xAB, 0x5B, 0xD8, 0xD7, - 0xFB, 0x27, 0x6D, 0xC5, 0xFB, 0xFF, 0xC8, 0xF9, - 0xA2, 0x8C, 0xAE, 0x4E, 0x48, 0x67, 0xDF, 0x67, - 0x80, 0xD9, 0xB7, 0x25, 0x24, 0x16, 0x09, 0x27, - 0xC8, 0x55, 0xDA, 0x5B, 0x60, 0x78, 0xE0, 0xB5, - 0x54, 0xAA, 0x91, 0xE3, 0x1C, 0xB9, 0xCA, 0x1D - }, - { - 0x10, 0xBD, 0xF0, 0xCA, 0xA0, 0x80, 0x27, 0x05, - 0xE7, 0x06, 0x36, 0x9B, 0xAF, 0x8A, 0x3F, 0x79, - 0xD7, 0x2C, 0x0A, 0x03, 0xA8, 0x06, 0x75, 0xA7, - 0xBB, 0xB0, 0x0B, 0xE3, 0xA4, 0x5E, 0x51, 0x64, - 0x24, 0xD1, 0xEE, 0x88, 0xEF, 0xB5, 0x6F, 0x6D, - 0x57, 0x77, 0x54, 0x5A, 0xE6, 0xE2, 0x77, 0x65, - 0xC3, 0xA8, 0xF5, 0xE4, 0x93, 0xFC, 0x30, 0x89, - 0x15, 0x63, 0x89, 0x33, 0xA1, 0xDF, 0xEE, 0x55 - }, - { - 0xB0, 0x17, 0x81, 0x09, 0x2B, 0x17, 0x48, 0x45, - 0x9E, 0x2E, 0x4E, 0xC1, 0x78, 0x69, 0x66, 0x27, - 0xBF, 0x4E, 0xBA, 0xFE, 0xBB, 0xA7, 0x74, 0xEC, - 0xF0, 0x18, 0xB7, 0x9A, 0x68, 0xAE, 0xB8, 0x49, - 0x17, 0xBF, 0x0B, 0x84, 0xBB, 0x79, 0xD1, 0x7B, - 0x74, 0x31, 0x51, 0x14, 0x4C, 0xD6, 0x6B, 0x7B, - 0x33, 0xA4, 0xB9, 0xE5, 0x2C, 0x76, 0xC4, 0xE1, - 0x12, 0x05, 0x0F, 0xF5, 0x38, 0x5B, 0x7F, 0x0B - }, - { - 0xC6, 0xDB, 0xC6, 0x1D, 0xEC, 0x6E, 0xAE, 0xAC, - 0x81, 0xE3, 0xD5, 0xF7, 0x55, 0x20, 0x3C, 0x8E, - 0x22, 0x05, 0x51, 0x53, 0x4A, 0x0B, 0x2F, 0xD1, - 0x05, 0xA9, 0x18, 0x89, 0x94, 0x5A, 0x63, 0x85, - 0x50, 0x20, 0x4F, 0x44, 0x09, 0x3D, 0xD9, 0x98, - 0xC0, 0x76, 0x20, 0x5D, 0xFF, 0xAD, 0x70, 0x3A, - 0x0E, 0x5C, 0xD3, 0xC7, 0xF4, 0x38, 0xA7, 0xE6, - 0x34, 0xCD, 0x59, 0xFE, 0xDE, 0xDB, 0x53, 0x9E - }, - { - 0xEB, 0xA5, 0x1A, 0xCF, 0xFB, 0x4C, 0xEA, 0x31, - 0xDB, 0x4B, 0x8D, 0x87, 0xE9, 0xBF, 0x7D, 0xD4, - 0x8F, 0xE9, 0x7B, 0x02, 0x53, 0xAE, 0x67, 0xAA, - 0x58, 0x0F, 0x9A, 0xC4, 0xA9, 0xD9, 0x41, 0xF2, - 0xBE, 0xA5, 0x18, 0xEE, 0x28, 0x68, 0x18, 0xCC, - 0x9F, 0x63, 0x3F, 0x2A, 0x3B, 0x9F, 0xB6, 0x8E, - 0x59, 0x4B, 0x48, 0xCD, 0xD6, 0xD5, 0x15, 0xBF, - 0x1D, 0x52, 0xBA, 0x6C, 0x85, 0xA2, 0x03, 0xA7 - }, - { - 0x86, 0x22, 0x1F, 0x3A, 0xDA, 0x52, 0x03, 0x7B, - 0x72, 0x22, 0x4F, 0x10, 0x5D, 0x79, 0x99, 0x23, - 0x1C, 0x5E, 0x55, 0x34, 0xD0, 0x3D, 0xA9, 0xD9, - 0xC0, 0xA1, 0x2A, 0xCB, 0x68, 0x46, 0x0C, 0xD3, - 0x75, 0xDA, 0xF8, 0xE2, 0x43, 0x86, 0x28, 0x6F, - 0x96, 0x68, 0xF7, 0x23, 0x26, 0xDB, 0xF9, 0x9B, - 0xA0, 0x94, 0x39, 0x24, 0x37, 0xD3, 0x98, 0xE9, - 0x5B, 0xB8, 0x16, 0x1D, 0x71, 0x7F, 0x89, 0x91 - }, - { - 0x55, 0x95, 0xE0, 0x5C, 0x13, 0xA7, 0xEC, 0x4D, - 0xC8, 0xF4, 0x1F, 0xB7, 0x0C, 0xB5, 0x0A, 0x71, - 0xBC, 0xE1, 0x7C, 0x02, 0x4F, 0xF6, 0xDE, 0x7A, - 0xF6, 0x18, 0xD0, 0xCC, 0x4E, 0x9C, 0x32, 0xD9, - 0x57, 0x0D, 0x6D, 0x3E, 0xA4, 0x5B, 0x86, 0x52, - 0x54, 0x91, 0x03, 0x0C, 0x0D, 0x8F, 0x2B, 0x18, - 0x36, 0xD5, 0x77, 0x8C, 0x1C, 0xE7, 0x35, 0xC1, - 0x77, 0x07, 0xDF, 0x36, 0x4D, 0x05, 0x43, 0x47 - }, - { - 0xCE, 0x0F, 0x4F, 0x6A, 0xCA, 0x89, 0x59, 0x0A, - 0x37, 0xFE, 0x03, 0x4D, 0xD7, 0x4D, 0xD5, 0xFA, - 0x65, 0xEB, 0x1C, 0xBD, 0x0A, 0x41, 0x50, 0x8A, - 0xAD, 0xDC, 0x09, 0x35, 0x1A, 0x3C, 0xEA, 0x6D, - 0x18, 0xCB, 0x21, 0x89, 0xC5, 0x4B, 0x70, 0x0C, - 0x00, 0x9F, 0x4C, 0xBF, 0x05, 0x21, 0xC7, 0xEA, - 0x01, 0xBE, 0x61, 0xC5, 0xAE, 0x09, 0xCB, 0x54, - 0xF2, 0x7B, 0xC1, 0xB4, 0x4D, 0x65, 0x8C, 0x82 - }, - { - 0x7E, 0xE8, 0x0B, 0x06, 0xA2, 0x15, 0xA3, 0xBC, - 0xA9, 0x70, 0xC7, 0x7C, 0xDA, 0x87, 0x61, 0x82, - 0x2B, 0xC1, 0x03, 0xD4, 0x4F, 0xA4, 0xB3, 0x3F, - 0x4D, 0x07, 0xDC, 0xB9, 0x97, 0xE3, 0x6D, 0x55, - 0x29, 0x8B, 0xCE, 0xAE, 0x12, 0x24, 0x1B, 0x3F, - 0xA0, 0x7F, 0xA6, 0x3B, 0xE5, 0x57, 0x60, 0x68, - 0xDA, 0x38, 0x7B, 0x8D, 0x58, 0x59, 0xAE, 0xAB, - 0x70, 0x13, 0x69, 0x84, 0x8B, 0x17, 0x6D, 0x42 - }, - { - 0x94, 0x0A, 0x84, 0xB6, 0xA8, 0x4D, 0x10, 0x9A, - 0xAB, 0x20, 0x8C, 0x02, 0x4C, 0x6C, 0xE9, 0x64, - 0x76, 0x76, 0xBA, 0x0A, 0xAA, 0x11, 0xF8, 0x6D, - 0xBB, 0x70, 0x18, 0xF9, 0xFD, 0x22, 0x20, 0xA6, - 0xD9, 0x01, 0xA9, 0x02, 0x7F, 0x9A, 0xBC, 0xF9, - 0x35, 0x37, 0x27, 0x27, 0xCB, 0xF0, 0x9E, 0xBD, - 0x61, 0xA2, 0xA2, 0xEE, 0xB8, 0x76, 0x53, 0xE8, - 0xEC, 0xAD, 0x1B, 0xAB, 0x85, 0xDC, 0x83, 0x27 - }, - { - 0x20, 0x20, 0xB7, 0x82, 0x64, 0xA8, 0x2D, 0x9F, - 0x41, 0x51, 0x14, 0x1A, 0xDB, 0xA8, 0xD4, 0x4B, - 0xF2, 0x0C, 0x5E, 0xC0, 0x62, 0xEE, 0xE9, 0xB5, - 0x95, 0xA1, 0x1F, 0x9E, 0x84, 0x90, 0x1B, 0xF1, - 0x48, 0xF2, 0x98, 0xE0, 0xC9, 0xF8, 0x77, 0x7D, - 0xCD, 0xBC, 0x7C, 0xC4, 0x67, 0x0A, 0xAC, 0x35, - 0x6C, 0xC2, 0xAD, 0x8C, 0xCB, 0x16, 0x29, 0xF1, - 0x6F, 0x6A, 0x76, 0xBC, 0xEF, 0xBE, 0xE7, 0x60 - }, - { - 0xD1, 0xB8, 0x97, 0xB0, 0xE0, 0x75, 0xBA, 0x68, - 0xAB, 0x57, 0x2A, 0xDF, 0x9D, 0x9C, 0x43, 0x66, - 0x63, 0xE4, 0x3E, 0xB3, 0xD8, 0xE6, 0x2D, 0x92, - 0xFC, 0x49, 0xC9, 0xBE, 0x21, 0x4E, 0x6F, 0x27, - 0x87, 0x3F, 0xE2, 0x15, 0xA6, 0x51, 0x70, 0xE6, - 0xBE, 0xA9, 0x02, 0x40, 0x8A, 0x25, 0xB4, 0x95, - 0x06, 0xF4, 0x7B, 0xAB, 0xD0, 0x7C, 0xEC, 0xF7, - 0x11, 0x3E, 0xC1, 0x0C, 0x5D, 0xD3, 0x12, 0x52 - }, - { - 0xB1, 0x4D, 0x0C, 0x62, 0xAB, 0xFA, 0x46, 0x9A, - 0x35, 0x71, 0x77, 0xE5, 0x94, 0xC1, 0x0C, 0x19, - 0x42, 0x43, 0xED, 0x20, 0x25, 0xAB, 0x8A, 0xA5, - 0xAD, 0x2F, 0xA4, 0x1A, 0xD3, 0x18, 0xE0, 0xFF, - 0x48, 0xCD, 0x5E, 0x60, 0xBE, 0xC0, 0x7B, 0x13, - 0x63, 0x4A, 0x71, 0x1D, 0x23, 0x26, 0xE4, 0x88, - 0xA9, 0x85, 0xF3, 0x1E, 0x31, 0x15, 0x33, 0x99, - 0xE7, 0x30, 0x88, 0xEF, 0xC8, 0x6A, 0x5C, 0x55 - }, - { - 0x41, 0x69, 0xC5, 0xCC, 0x80, 0x8D, 0x26, 0x97, - 0xDC, 0x2A, 0x82, 0x43, 0x0D, 0xC2, 0x3E, 0x3C, - 0xD3, 0x56, 0xDC, 0x70, 0xA9, 0x45, 0x66, 0x81, - 0x05, 0x02, 0xB8, 0xD6, 0x55, 0xB3, 0x9A, 0xBF, - 0x9E, 0x7F, 0x90, 0x2F, 0xE7, 0x17, 0xE0, 0x38, - 0x92, 0x19, 0x85, 0x9E, 0x19, 0x45, 0xDF, 0x1A, - 0xF6, 0xAD, 0xA4, 0x2E, 0x4C, 0xCD, 0xA5, 0x5A, - 0x19, 0x7B, 0x71, 0x00, 0xA3, 0x0C, 0x30, 0xA1 - }, - { - 0x25, 0x8A, 0x4E, 0xDB, 0x11, 0x3D, 0x66, 0xC8, - 0x39, 0xC8, 0xB1, 0xC9, 0x1F, 0x15, 0xF3, 0x5A, - 0xDE, 0x60, 0x9F, 0x11, 0xCD, 0x7F, 0x86, 0x81, - 0xA4, 0x04, 0x5B, 0x9F, 0xEF, 0x7B, 0x0B, 0x24, - 0xC8, 0x2C, 0xDA, 0x06, 0xA5, 0xF2, 0x06, 0x7B, - 0x36, 0x88, 0x25, 0xE3, 0x91, 0x4E, 0x53, 0xD6, - 0x94, 0x8E, 0xDE, 0x92, 0xEF, 0xD6, 0xE8, 0x38, - 0x7F, 0xA2, 0xE5, 0x37, 0x23, 0x9B, 0x5B, 0xEE - }, - { - 0x79, 0xD2, 0xD8, 0x69, 0x6D, 0x30, 0xF3, 0x0F, - 0xB3, 0x46, 0x57, 0x76, 0x11, 0x71, 0xA1, 0x1E, - 0x6C, 0x3F, 0x1E, 0x64, 0xCB, 0xE7, 0xBE, 0xBE, - 0xE1, 0x59, 0xCB, 0x95, 0xBF, 0xAF, 0x81, 0x2B, - 0x4F, 0x41, 0x1E, 0x2F, 0x26, 0xD9, 0xC4, 0x21, - 0xDC, 0x2C, 0x28, 0x4A, 0x33, 0x42, 0xD8, 0x23, - 0xEC, 0x29, 0x38, 0x49, 0xE4, 0x2D, 0x1E, 0x46, - 0xB0, 0xA4, 0xAC, 0x1E, 0x3C, 0x86, 0xAB, 0xAA - }, - { - 0x8B, 0x94, 0x36, 0x01, 0x0D, 0xC5, 0xDE, 0xE9, - 0x92, 0xAE, 0x38, 0xAE, 0xA9, 0x7F, 0x2C, 0xD6, - 0x3B, 0x94, 0x6D, 0x94, 0xFE, 0xDD, 0x2E, 0xC9, - 0x67, 0x1D, 0xCD, 0xE3, 0xBD, 0x4C, 0xE9, 0x56, - 0x4D, 0x55, 0x5C, 0x66, 0xC1, 0x5B, 0xB2, 0xB9, - 0x00, 0xDF, 0x72, 0xED, 0xB6, 0xB8, 0x91, 0xEB, - 0xCA, 0xDF, 0xEF, 0xF6, 0x3C, 0x9E, 0xA4, 0x03, - 0x6A, 0x99, 0x8B, 0xE7, 0x97, 0x39, 0x81, 0xE7 - }, - { - 0xC8, 0xF6, 0x8E, 0x69, 0x6E, 0xD2, 0x82, 0x42, - 0xBF, 0x99, 0x7F, 0x5B, 0x3B, 0x34, 0x95, 0x95, - 0x08, 0xE4, 0x2D, 0x61, 0x38, 0x10, 0xF1, 0xE2, - 0xA4, 0x35, 0xC9, 0x6E, 0xD2, 0xFF, 0x56, 0x0C, - 0x70, 0x22, 0xF3, 0x61, 0xA9, 0x23, 0x4B, 0x98, - 0x37, 0xFE, 0xEE, 0x90, 0xBF, 0x47, 0x92, 0x2E, - 0xE0, 0xFD, 0x5F, 0x8D, 0xDF, 0x82, 0x37, 0x18, - 0xD8, 0x6D, 0x1E, 0x16, 0xC6, 0x09, 0x00, 0x71 - }, - { - 0xB0, 0x2D, 0x3E, 0xEE, 0x48, 0x60, 0xD5, 0x86, - 0x8B, 0x2C, 0x39, 0xCE, 0x39, 0xBF, 0xE8, 0x10, - 0x11, 0x29, 0x05, 0x64, 0xDD, 0x67, 0x8C, 0x85, - 0xE8, 0x78, 0x3F, 0x29, 0x30, 0x2D, 0xFC, 0x13, - 0x99, 0xBA, 0x95, 0xB6, 0xB5, 0x3C, 0xD9, 0xEB, - 0xBF, 0x40, 0x0C, 0xCA, 0x1D, 0xB0, 0xAB, 0x67, - 0xE1, 0x9A, 0x32, 0x5F, 0x2D, 0x11, 0x58, 0x12, - 0xD2, 0x5D, 0x00, 0x97, 0x8A, 0xD1, 0xBC, 0xA4 - }, - { - 0x76, 0x93, 0xEA, 0x73, 0xAF, 0x3A, 0xC4, 0xDA, - 0xD2, 0x1C, 0xA0, 0xD8, 0xDA, 0x85, 0xB3, 0x11, - 0x8A, 0x7D, 0x1C, 0x60, 0x24, 0xCF, 0xAF, 0x55, - 0x76, 0x99, 0x86, 0x82, 0x17, 0xBC, 0x0C, 0x2F, - 0x44, 0xA1, 0x99, 0xBC, 0x6C, 0x0E, 0xDD, 0x51, - 0x97, 0x98, 0xBA, 0x05, 0xBD, 0x5B, 0x1B, 0x44, - 0x84, 0x34, 0x6A, 0x47, 0xC2, 0xCA, 0xDF, 0x6B, - 0xF3, 0x0B, 0x78, 0x5C, 0xC8, 0x8B, 0x2B, 0xAF - }, - { - 0xA0, 0xE5, 0xC1, 0xC0, 0x03, 0x1C, 0x02, 0xE4, - 0x8B, 0x7F, 0x09, 0xA5, 0xE8, 0x96, 0xEE, 0x9A, - 0xEF, 0x2F, 0x17, 0xFC, 0x9E, 0x18, 0xE9, 0x97, - 0xD7, 0xF6, 0xCA, 0xC7, 0xAE, 0x31, 0x64, 0x22, - 0xC2, 0xB1, 0xE7, 0x79, 0x84, 0xE5, 0xF3, 0xA7, - 0x3C, 0xB4, 0x5D, 0xEE, 0xD5, 0xD3, 0xF8, 0x46, - 0x00, 0x10, 0x5E, 0x6E, 0xE3, 0x8F, 0x2D, 0x09, - 0x0C, 0x7D, 0x04, 0x42, 0xEA, 0x34, 0xC4, 0x6D - }, - { - 0x41, 0xDA, 0xA6, 0xAD, 0xCF, 0xDB, 0x69, 0xF1, - 0x44, 0x0C, 0x37, 0xB5, 0x96, 0x44, 0x01, 0x65, - 0xC1, 0x5A, 0xDA, 0x59, 0x68, 0x13, 0xE2, 0xE2, - 0x2F, 0x06, 0x0F, 0xCD, 0x55, 0x1F, 0x24, 0xDE, - 0xE8, 0xE0, 0x4B, 0xA6, 0x89, 0x03, 0x87, 0x88, - 0x6C, 0xEE, 0xC4, 0xA7, 0xA0, 0xD7, 0xFC, 0x6B, - 0x44, 0x50, 0x63, 0x92, 0xEC, 0x38, 0x22, 0xC0, - 0xD8, 0xC1, 0xAC, 0xFC, 0x7D, 0x5A, 0xEB, 0xE8 - }, - { - 0x14, 0xD4, 0xD4, 0x0D, 0x59, 0x84, 0xD8, 0x4C, - 0x5C, 0xF7, 0x52, 0x3B, 0x77, 0x98, 0xB2, 0x54, - 0xE2, 0x75, 0xA3, 0xA8, 0xCC, 0x0A, 0x1B, 0xD0, - 0x6E, 0xBC, 0x0B, 0xEE, 0x72, 0x68, 0x56, 0xAC, - 0xC3, 0xCB, 0xF5, 0x16, 0xFF, 0x66, 0x7C, 0xDA, - 0x20, 0x58, 0xAD, 0x5C, 0x34, 0x12, 0x25, 0x44, - 0x60, 0xA8, 0x2C, 0x92, 0x18, 0x70, 0x41, 0x36, - 0x3C, 0xC7, 0x7A, 0x4D, 0xC2, 0x15, 0xE4, 0x87 - }, - { - 0xD0, 0xE7, 0xA1, 0xE2, 0xB9, 0xA4, 0x47, 0xFE, - 0xE8, 0x3E, 0x22, 0x77, 0xE9, 0xFF, 0x80, 0x10, - 0xC2, 0xF3, 0x75, 0xAE, 0x12, 0xFA, 0x7A, 0xAA, - 0x8C, 0xA5, 0xA6, 0x31, 0x78, 0x68, 0xA2, 0x6A, - 0x36, 0x7A, 0x0B, 0x69, 0xFB, 0xC1, 0xCF, 0x32, - 0xA5, 0x5D, 0x34, 0xEB, 0x37, 0x06, 0x63, 0x01, - 0x6F, 0x3D, 0x21, 0x10, 0x23, 0x0E, 0xBA, 0x75, - 0x40, 0x28, 0xA5, 0x6F, 0x54, 0xAC, 0xF5, 0x7C - }, - { - 0xE7, 0x71, 0xAA, 0x8D, 0xB5, 0xA3, 0xE0, 0x43, - 0xE8, 0x17, 0x8F, 0x39, 0xA0, 0x85, 0x7B, 0xA0, - 0x4A, 0x3F, 0x18, 0xE4, 0xAA, 0x05, 0x74, 0x3C, - 0xF8, 0xD2, 0x22, 0xB0, 0xB0, 0x95, 0x82, 0x53, - 0x50, 0xBA, 0x42, 0x2F, 0x63, 0x38, 0x2A, 0x23, - 0xD9, 0x2E, 0x41, 0x49, 0x07, 0x4E, 0x81, 0x6A, - 0x36, 0xC1, 0xCD, 0x28, 0x28, 0x4D, 0x14, 0x62, - 0x67, 0x94, 0x0B, 0x31, 0xF8, 0x81, 0x8E, 0xA2 - }, - { - 0xFE, 0xB4, 0xFD, 0x6F, 0x9E, 0x87, 0xA5, 0x6B, - 0xEF, 0x39, 0x8B, 0x32, 0x84, 0xD2, 0xBD, 0xA5, - 0xB5, 0xB0, 0xE1, 0x66, 0x58, 0x3A, 0x66, 0xB6, - 0x1E, 0x53, 0x84, 0x57, 0xFF, 0x05, 0x84, 0x87, - 0x2C, 0x21, 0xA3, 0x29, 0x62, 0xB9, 0x92, 0x8F, - 0xFA, 0xB5, 0x8D, 0xE4, 0xAF, 0x2E, 0xDD, 0x4E, - 0x15, 0xD8, 0xB3, 0x55, 0x70, 0x52, 0x32, 0x07, - 0xFF, 0x4E, 0x2A, 0x5A, 0xA7, 0x75, 0x4C, 0xAA - }, - { - 0x46, 0x2F, 0x17, 0xBF, 0x00, 0x5F, 0xB1, 0xC1, - 0xB9, 0xE6, 0x71, 0x77, 0x9F, 0x66, 0x52, 0x09, - 0xEC, 0x28, 0x73, 0xE3, 0xE4, 0x11, 0xF9, 0x8D, - 0xAB, 0xF2, 0x40, 0xA1, 0xD5, 0xEC, 0x3F, 0x95, - 0xCE, 0x67, 0x96, 0xB6, 0xFC, 0x23, 0xFE, 0x17, - 0x19, 0x03, 0xB5, 0x02, 0x02, 0x34, 0x67, 0xDE, - 0xC7, 0x27, 0x3F, 0xF7, 0x48, 0x79, 0xB9, 0x29, - 0x67, 0xA2, 0xA4, 0x3A, 0x5A, 0x18, 0x3D, 0x33 - }, - { - 0xD3, 0x33, 0x81, 0x93, 0xB6, 0x45, 0x53, 0xDB, - 0xD3, 0x8D, 0x14, 0x4B, 0xEA, 0x71, 0xC5, 0x91, - 0x5B, 0xB1, 0x10, 0xE2, 0xD8, 0x81, 0x80, 0xDB, - 0xC5, 0xDB, 0x36, 0x4F, 0xD6, 0x17, 0x1D, 0xF3, - 0x17, 0xFC, 0x72, 0x68, 0x83, 0x1B, 0x5A, 0xEF, - 0x75, 0xE4, 0x34, 0x2B, 0x2F, 0xAD, 0x87, 0x97, - 0xBA, 0x39, 0xED, 0xDC, 0xEF, 0x80, 0xE6, 0xEC, - 0x08, 0x15, 0x93, 0x50, 0xB1, 0xAD, 0x69, 0x6D - }, - { - 0xE1, 0x59, 0x0D, 0x58, 0x5A, 0x3D, 0x39, 0xF7, - 0xCB, 0x59, 0x9A, 0xBD, 0x47, 0x90, 0x70, 0x96, - 0x64, 0x09, 0xA6, 0x84, 0x6D, 0x43, 0x77, 0xAC, - 0xF4, 0x47, 0x1D, 0x06, 0x5D, 0x5D, 0xB9, 0x41, - 0x29, 0xCC, 0x9B, 0xE9, 0x25, 0x73, 0xB0, 0x5E, - 0xD2, 0x26, 0xBE, 0x1E, 0x9B, 0x7C, 0xB0, 0xCA, - 0xBE, 0x87, 0x91, 0x85, 0x89, 0xF8, 0x0D, 0xAD, - 0xD4, 0xEF, 0x5E, 0xF2, 0x5A, 0x93, 0xD2, 0x8E - }, - { - 0xF8, 0xF3, 0x72, 0x6A, 0xC5, 0xA2, 0x6C, 0xC8, - 0x01, 0x32, 0x49, 0x3A, 0x6F, 0xED, 0xCB, 0x0E, - 0x60, 0x76, 0x0C, 0x09, 0xCF, 0xC8, 0x4C, 0xAD, - 0x17, 0x81, 0x75, 0x98, 0x68, 0x19, 0x66, 0x5E, - 0x76, 0x84, 0x2D, 0x7B, 0x9F, 0xED, 0xF7, 0x6D, - 0xDD, 0xEB, 0xF5, 0xD3, 0xF5, 0x6F, 0xAA, 0xAD, - 0x44, 0x77, 0x58, 0x7A, 0xF2, 0x16, 0x06, 0xD3, - 0x96, 0xAE, 0x57, 0x0D, 0x8E, 0x71, 0x9A, 0xF2 - }, - { - 0x30, 0x18, 0x60, 0x55, 0xC0, 0x79, 0x49, 0x94, - 0x81, 0x83, 0xC8, 0x50, 0xE9, 0xA7, 0x56, 0xCC, - 0x09, 0x93, 0x7E, 0x24, 0x7D, 0x9D, 0x92, 0x8E, - 0x86, 0x9E, 0x20, 0xBA, 0xFC, 0x3C, 0xD9, 0x72, - 0x17, 0x19, 0xD3, 0x4E, 0x04, 0xA0, 0x89, 0x9B, - 0x92, 0xC7, 0x36, 0x08, 0x45, 0x50, 0x18, 0x68, - 0x86, 0xEF, 0xBA, 0x2E, 0x79, 0x0D, 0x8B, 0xE6, - 0xEB, 0xF0, 0x40, 0xB2, 0x09, 0xC4, 0x39, 0xA4 - }, - { - 0xF3, 0xC4, 0x27, 0x6C, 0xB8, 0x63, 0x63, 0x77, - 0x12, 0xC2, 0x41, 0xC4, 0x44, 0xC5, 0xCC, 0x1E, - 0x35, 0x54, 0xE0, 0xFD, 0xDB, 0x17, 0x4D, 0x03, - 0x58, 0x19, 0xDD, 0x83, 0xEB, 0x70, 0x0B, 0x4C, - 0xE8, 0x8D, 0xF3, 0xAB, 0x38, 0x41, 0xBA, 0x02, - 0x08, 0x5E, 0x1A, 0x99, 0xB4, 0xE1, 0x73, 0x10, - 0xC5, 0x34, 0x10, 0x75, 0xC0, 0x45, 0x8B, 0xA3, - 0x76, 0xC9, 0x5A, 0x68, 0x18, 0xFB, 0xB3, 0xE2 - }, - { - 0x0A, 0xA0, 0x07, 0xC4, 0xDD, 0x9D, 0x58, 0x32, - 0x39, 0x30, 0x40, 0xA1, 0x58, 0x3C, 0x93, 0x0B, - 0xCA, 0x7D, 0xC5, 0xE7, 0x7E, 0xA5, 0x3A, 0xDD, - 0x7E, 0x2B, 0x3F, 0x7C, 0x8E, 0x23, 0x13, 0x68, - 0x04, 0x35, 0x20, 0xD4, 0xA3, 0xEF, 0x53, 0xC9, - 0x69, 0xB6, 0xBB, 0xFD, 0x02, 0x59, 0x46, 0xF6, - 0x32, 0xBD, 0x7F, 0x76, 0x5D, 0x53, 0xC2, 0x10, - 0x03, 0xB8, 0xF9, 0x83, 0xF7, 0x5E, 0x2A, 0x6A - }, - { - 0x08, 0xE9, 0x46, 0x47, 0x20, 0x53, 0x3B, 0x23, - 0xA0, 0x4E, 0xC2, 0x4F, 0x7A, 0xE8, 0xC1, 0x03, - 0x14, 0x5F, 0x76, 0x53, 0x87, 0xD7, 0x38, 0x77, - 0x7D, 0x3D, 0x34, 0x34, 0x77, 0xFD, 0x1C, 0x58, - 0xDB, 0x05, 0x21, 0x42, 0xCA, 0xB7, 0x54, 0xEA, - 0x67, 0x43, 0x78, 0xE1, 0x87, 0x66, 0xC5, 0x35, - 0x42, 0xF7, 0x19, 0x70, 0x17, 0x1C, 0xC4, 0xF8, - 0x16, 0x94, 0x24, 0x6B, 0x71, 0x7D, 0x75, 0x64 - }, - { - 0xD3, 0x7F, 0xF7, 0xAD, 0x29, 0x79, 0x93, 0xE7, - 0xEC, 0x21, 0xE0, 0xF1, 0xB4, 0xB5, 0xAE, 0x71, - 0x9C, 0xDC, 0x83, 0xC5, 0xDB, 0x68, 0x75, 0x27, - 0xF2, 0x75, 0x16, 0xCB, 0xFF, 0xA8, 0x22, 0x88, - 0x8A, 0x68, 0x10, 0xEE, 0x5C, 0x1C, 0xA7, 0xBF, - 0xE3, 0x32, 0x11, 0x19, 0xBE, 0x1A, 0xB7, 0xBF, - 0xA0, 0xA5, 0x02, 0x67, 0x1C, 0x83, 0x29, 0x49, - 0x4D, 0xF7, 0xAD, 0x6F, 0x52, 0x2D, 0x44, 0x0F - }, - { - 0xDD, 0x90, 0x42, 0xF6, 0xE4, 0x64, 0xDC, 0xF8, - 0x6B, 0x12, 0x62, 0xF6, 0xAC, 0xCF, 0xAF, 0xBD, - 0x8C, 0xFD, 0x90, 0x2E, 0xD3, 0xED, 0x89, 0xAB, - 0xF7, 0x8F, 0xFA, 0x48, 0x2D, 0xBD, 0xEE, 0xB6, - 0x96, 0x98, 0x42, 0x39, 0x4C, 0x9A, 0x11, 0x68, - 0xAE, 0x3D, 0x48, 0x1A, 0x01, 0x78, 0x42, 0xF6, - 0x60, 0x00, 0x2D, 0x42, 0x44, 0x7C, 0x6B, 0x22, - 0xF7, 0xB7, 0x2F, 0x21, 0xAA, 0xE0, 0x21, 0xC9 - }, - { - 0xBD, 0x96, 0x5B, 0xF3, 0x1E, 0x87, 0xD7, 0x03, - 0x27, 0x53, 0x6F, 0x2A, 0x34, 0x1C, 0xEB, 0xC4, - 0x76, 0x8E, 0xCA, 0x27, 0x5F, 0xA0, 0x5E, 0xF9, - 0x8F, 0x7F, 0x1B, 0x71, 0xA0, 0x35, 0x12, 0x98, - 0xDE, 0x00, 0x6F, 0xBA, 0x73, 0xFE, 0x67, 0x33, - 0xED, 0x01, 0xD7, 0x58, 0x01, 0xB4, 0xA9, 0x28, - 0xE5, 0x42, 0x31, 0xB3, 0x8E, 0x38, 0xC5, 0x62, - 0xB2, 0xE3, 0x3E, 0xA1, 0x28, 0x49, 0x92, 0xFA - }, - { - 0x65, 0x67, 0x6D, 0x80, 0x06, 0x17, 0x97, 0x2F, - 0xBD, 0x87, 0xE4, 0xB9, 0x51, 0x4E, 0x1C, 0x67, - 0x40, 0x2B, 0x7A, 0x33, 0x10, 0x96, 0xD3, 0xBF, - 0xAC, 0x22, 0xF1, 0xAB, 0xB9, 0x53, 0x74, 0xAB, - 0xC9, 0x42, 0xF1, 0x6E, 0x9A, 0xB0, 0xEA, 0xD3, - 0x3B, 0x87, 0xC9, 0x19, 0x68, 0xA6, 0xE5, 0x09, - 0xE1, 0x19, 0xFF, 0x07, 0x78, 0x7B, 0x3E, 0xF4, - 0x83, 0xE1, 0xDC, 0xDC, 0xCF, 0x6E, 0x30, 0x22 - }, - { - 0x93, 0x9F, 0xA1, 0x89, 0x69, 0x9C, 0x5D, 0x2C, - 0x81, 0xDD, 0xD1, 0xFF, 0xC1, 0xFA, 0x20, 0x7C, - 0x97, 0x0B, 0x6A, 0x36, 0x85, 0xBB, 0x29, 0xCE, - 0x1D, 0x3E, 0x99, 0xD4, 0x2F, 0x2F, 0x74, 0x42, - 0xDA, 0x53, 0xE9, 0x5A, 0x72, 0x90, 0x73, 0x14, - 0xF4, 0x58, 0x83, 0x99, 0xA3, 0xFF, 0x5B, 0x0A, - 0x92, 0xBE, 0xB3, 0xF6, 0xBE, 0x26, 0x94, 0xF9, - 0xF8, 0x6E, 0xCF, 0x29, 0x52, 0xD5, 0xB4, 0x1C - }, - { - 0xC5, 0x16, 0x54, 0x17, 0x01, 0x86, 0x3F, 0x91, - 0x00, 0x5F, 0x31, 0x41, 0x08, 0xCE, 0xEC, 0xE3, - 0xC6, 0x43, 0xE0, 0x4F, 0xC8, 0xC4, 0x2F, 0xD2, - 0xFF, 0x55, 0x62, 0x20, 0xE6, 0x16, 0xAA, 0xA6, - 0xA4, 0x8A, 0xEB, 0x97, 0xA8, 0x4B, 0xAD, 0x74, - 0x78, 0x2E, 0x8D, 0xFF, 0x96, 0xA1, 0xA2, 0xFA, - 0x94, 0x93, 0x39, 0xD7, 0x22, 0xED, 0xCA, 0xA3, - 0x2B, 0x57, 0x06, 0x70, 0x41, 0xDF, 0x88, 0xCC - }, - { - 0x98, 0x7F, 0xD6, 0xE0, 0xD6, 0x85, 0x7C, 0x55, - 0x3E, 0xAE, 0xBB, 0x3D, 0x34, 0x97, 0x0A, 0x2C, - 0x2F, 0x6E, 0x89, 0xA3, 0x54, 0x8F, 0x49, 0x25, - 0x21, 0x72, 0x2B, 0x80, 0xA1, 0xC2, 0x1A, 0x15, - 0x38, 0x92, 0x34, 0x6D, 0x2C, 0xBA, 0x64, 0x44, - 0x21, 0x2D, 0x56, 0xDA, 0x9A, 0x26, 0xE3, 0x24, - 0xDC, 0xCB, 0xC0, 0xDC, 0xDE, 0x85, 0xD4, 0xD2, - 0xEE, 0x43, 0x99, 0xEE, 0xC5, 0xA6, 0x4E, 0x8F - }, - { - 0xAE, 0x56, 0xDE, 0xB1, 0xC2, 0x32, 0x8D, 0x9C, - 0x40, 0x17, 0x70, 0x6B, 0xCE, 0x6E, 0x99, 0xD4, - 0x13, 0x49, 0x05, 0x3B, 0xA9, 0xD3, 0x36, 0xD6, - 0x77, 0xC4, 0xC2, 0x7D, 0x9F, 0xD5, 0x0A, 0xE6, - 0xAE, 0xE1, 0x7E, 0x85, 0x31, 0x54, 0xE1, 0xF4, - 0xFE, 0x76, 0x72, 0x34, 0x6D, 0xA2, 0xEA, 0xA3, - 0x1E, 0xEA, 0x53, 0xFC, 0xF2, 0x4A, 0x22, 0x80, - 0x4F, 0x11, 0xD0, 0x3D, 0xA6, 0xAB, 0xFC, 0x2B - }, - { - 0x49, 0xD6, 0xA6, 0x08, 0xC9, 0xBD, 0xE4, 0x49, - 0x18, 0x70, 0x49, 0x85, 0x72, 0xAC, 0x31, 0xAA, - 0xC3, 0xFA, 0x40, 0x93, 0x8B, 0x38, 0xA7, 0x81, - 0x8F, 0x72, 0x38, 0x3E, 0xB0, 0x40, 0xAD, 0x39, - 0x53, 0x2B, 0xC0, 0x65, 0x71, 0xE1, 0x3D, 0x76, - 0x7E, 0x69, 0x45, 0xAB, 0x77, 0xC0, 0xBD, 0xC3, - 0xB0, 0x28, 0x42, 0x53, 0x34, 0x3F, 0x9F, 0x6C, - 0x12, 0x44, 0xEB, 0xF2, 0xFF, 0x0D, 0xF8, 0x66 - }, - { - 0xDA, 0x58, 0x2A, 0xD8, 0xC5, 0x37, 0x0B, 0x44, - 0x69, 0xAF, 0x86, 0x2A, 0xA6, 0x46, 0x7A, 0x22, - 0x93, 0xB2, 0xB2, 0x8B, 0xD8, 0x0A, 0xE0, 0xE9, - 0x1F, 0x42, 0x5A, 0xD3, 0xD4, 0x72, 0x49, 0xFD, - 0xF9, 0x88, 0x25, 0xCC, 0x86, 0xF1, 0x40, 0x28, - 0xC3, 0x30, 0x8C, 0x98, 0x04, 0xC7, 0x8B, 0xFE, - 0xEE, 0xEE, 0x46, 0x14, 0x44, 0xCE, 0x24, 0x36, - 0x87, 0xE1, 0xA5, 0x05, 0x22, 0x45, 0x6A, 0x1D - }, - { - 0xD5, 0x26, 0x6A, 0xA3, 0x33, 0x11, 0x94, 0xAE, - 0xF8, 0x52, 0xEE, 0xD8, 0x6D, 0x7B, 0x5B, 0x26, - 0x33, 0xA0, 0xAF, 0x1C, 0x73, 0x59, 0x06, 0xF2, - 0xE1, 0x32, 0x79, 0xF1, 0x49, 0x31, 0xA9, 0xFC, - 0x3B, 0x0E, 0xAC, 0x5C, 0xE9, 0x24, 0x52, 0x73, - 0xBD, 0x1A, 0xA9, 0x29, 0x05, 0xAB, 0xE1, 0x62, - 0x78, 0xEF, 0x7E, 0xFD, 0x47, 0x69, 0x47, 0x89, - 0xA7, 0x28, 0x3B, 0x77, 0xDA, 0x3C, 0x70, 0xF8 - }, - { - 0x29, 0x62, 0x73, 0x4C, 0x28, 0x25, 0x21, 0x86, - 0xA9, 0xA1, 0x11, 0x1C, 0x73, 0x2A, 0xD4, 0xDE, - 0x45, 0x06, 0xD4, 0xB4, 0x48, 0x09, 0x16, 0x30, - 0x3E, 0xB7, 0x99, 0x1D, 0x65, 0x9C, 0xCD, 0xA0, - 0x7A, 0x99, 0x11, 0x91, 0x4B, 0xC7, 0x5C, 0x41, - 0x8A, 0xB7, 0xA4, 0x54, 0x17, 0x57, 0xAD, 0x05, - 0x47, 0x96, 0xE2, 0x67, 0x97, 0xFE, 0xAF, 0x36, - 0xE9, 0xF6, 0xAD, 0x43, 0xF1, 0x4B, 0x35, 0xA4 - }, - { - 0xE8, 0xB7, 0x9E, 0xC5, 0xD0, 0x6E, 0x11, 0x1B, - 0xDF, 0xAF, 0xD7, 0x1E, 0x9F, 0x57, 0x60, 0xF0, - 0x0A, 0xC8, 0xAC, 0x5D, 0x8B, 0xF7, 0x68, 0xF9, - 0xFF, 0x6F, 0x08, 0xB8, 0xF0, 0x26, 0x09, 0x6B, - 0x1C, 0xC3, 0xA4, 0xC9, 0x73, 0x33, 0x30, 0x19, - 0xF1, 0xE3, 0x55, 0x3E, 0x77, 0xDA, 0x3F, 0x98, - 0xCB, 0x9F, 0x54, 0x2E, 0x0A, 0x90, 0xE5, 0xF8, - 0xA9, 0x40, 0xCC, 0x58, 0xE5, 0x98, 0x44, 0xB3 - }, - { - 0xDF, 0xB3, 0x20, 0xC4, 0x4F, 0x9D, 0x41, 0xD1, - 0xEF, 0xDC, 0xC0, 0x15, 0xF0, 0x8D, 0xD5, 0x53, - 0x9E, 0x52, 0x6E, 0x39, 0xC8, 0x7D, 0x50, 0x9A, - 0xE6, 0x81, 0x2A, 0x96, 0x9E, 0x54, 0x31, 0xBF, - 0x4F, 0xA7, 0xD9, 0x1F, 0xFD, 0x03, 0xB9, 0x81, - 0xE0, 0xD5, 0x44, 0xCF, 0x72, 0xD7, 0xB1, 0xC0, - 0x37, 0x4F, 0x88, 0x01, 0x48, 0x2E, 0x6D, 0xEA, - 0x2E, 0xF9, 0x03, 0x87, 0x7E, 0xBA, 0x67, 0x5E - }, - { - 0xD8, 0x86, 0x75, 0x11, 0x8F, 0xDB, 0x55, 0xA5, - 0xFB, 0x36, 0x5A, 0xC2, 0xAF, 0x1D, 0x21, 0x7B, - 0xF5, 0x26, 0xCE, 0x1E, 0xE9, 0xC9, 0x4B, 0x2F, - 0x00, 0x90, 0xB2, 0xC5, 0x8A, 0x06, 0xCA, 0x58, - 0x18, 0x7D, 0x7F, 0xE5, 0x7C, 0x7B, 0xED, 0x9D, - 0x26, 0xFC, 0xA0, 0x67, 0xB4, 0x11, 0x0E, 0xEF, - 0xCD, 0x9A, 0x0A, 0x34, 0x5D, 0xE8, 0x72, 0xAB, - 0xE2, 0x0D, 0xE3, 0x68, 0x00, 0x1B, 0x07, 0x45 - }, - { - 0xB8, 0x93, 0xF2, 0xFC, 0x41, 0xF7, 0xB0, 0xDD, - 0x6E, 0x2F, 0x6A, 0xA2, 0xE0, 0x37, 0x0C, 0x0C, - 0xFF, 0x7D, 0xF0, 0x9E, 0x3A, 0xCF, 0xCC, 0x0E, - 0x92, 0x0B, 0x6E, 0x6F, 0xAD, 0x0E, 0xF7, 0x47, - 0xC4, 0x06, 0x68, 0x41, 0x7D, 0x34, 0x2B, 0x80, - 0xD2, 0x35, 0x1E, 0x8C, 0x17, 0x5F, 0x20, 0x89, - 0x7A, 0x06, 0x2E, 0x97, 0x65, 0xE6, 0xC6, 0x7B, - 0x53, 0x9B, 0x6B, 0xA8, 0xB9, 0x17, 0x05, 0x45 - }, - { - 0x6C, 0x67, 0xEC, 0x56, 0x97, 0xAC, 0xCD, 0x23, - 0x5C, 0x59, 0xB4, 0x86, 0xD7, 0xB7, 0x0B, 0xAE, - 0xED, 0xCB, 0xD4, 0xAA, 0x64, 0xEB, 0xD4, 0xEE, - 0xF3, 0xC7, 0xEA, 0xC1, 0x89, 0x56, 0x1A, 0x72, - 0x62, 0x50, 0xAE, 0xC4, 0xD4, 0x8C, 0xAD, 0xCA, - 0xFB, 0xBE, 0x2C, 0xE3, 0xC1, 0x6C, 0xE2, 0xD6, - 0x91, 0xA8, 0xCC, 0xE0, 0x6E, 0x88, 0x79, 0x55, - 0x6D, 0x44, 0x83, 0xED, 0x71, 0x65, 0xC0, 0x63 - }, - { - 0xF1, 0xAA, 0x2B, 0x04, 0x4F, 0x8F, 0x0C, 0x63, - 0x8A, 0x3F, 0x36, 0x2E, 0x67, 0x7B, 0x5D, 0x89, - 0x1D, 0x6F, 0xD2, 0xAB, 0x07, 0x65, 0xF6, 0xEE, - 0x1E, 0x49, 0x87, 0xDE, 0x05, 0x7E, 0xAD, 0x35, - 0x78, 0x83, 0xD9, 0xB4, 0x05, 0xB9, 0xD6, 0x09, - 0xEE, 0xA1, 0xB8, 0x69, 0xD9, 0x7F, 0xB1, 0x6D, - 0x9B, 0x51, 0x01, 0x7C, 0x55, 0x3F, 0x3B, 0x93, - 0xC0, 0xA1, 0xE0, 0xF1, 0x29, 0x6F, 0xED, 0xCD - }, - { - 0xCB, 0xAA, 0x25, 0x95, 0x72, 0xD4, 0xAE, 0xBF, - 0xC1, 0x91, 0x7A, 0xCD, 0xDC, 0x58, 0x2B, 0x9F, - 0x8D, 0xFA, 0xA9, 0x28, 0xA1, 0x98, 0xCA, 0x7A, - 0xCD, 0x0F, 0x2A, 0xA7, 0x6A, 0x13, 0x4A, 0x90, - 0x25, 0x2E, 0x62, 0x98, 0xA6, 0x5B, 0x08, 0x18, - 0x6A, 0x35, 0x0D, 0x5B, 0x76, 0x26, 0x69, 0x9F, - 0x8C, 0xB7, 0x21, 0xA3, 0xEA, 0x59, 0x21, 0xB7, - 0x53, 0xAE, 0x3A, 0x2D, 0xCE, 0x24, 0xBA, 0x3A - }, - { - 0xFA, 0x15, 0x49, 0xC9, 0x79, 0x6C, 0xD4, 0xD3, - 0x03, 0xDC, 0xF4, 0x52, 0xC1, 0xFB, 0xD5, 0x74, - 0x4F, 0xD9, 0xB9, 0xB4, 0x70, 0x03, 0xD9, 0x20, - 0xB9, 0x2D, 0xE3, 0x48, 0x39, 0xD0, 0x7E, 0xF2, - 0xA2, 0x9D, 0xED, 0x68, 0xF6, 0xFC, 0x9E, 0x6C, - 0x45, 0xE0, 0x71, 0xA2, 0xE4, 0x8B, 0xD5, 0x0C, - 0x50, 0x84, 0xE9, 0x6B, 0x65, 0x7D, 0xD0, 0x40, - 0x40, 0x45, 0xA1, 0xDD, 0xEF, 0xE2, 0x82, 0xED - }, - { - 0x5C, 0xF2, 0xAC, 0x89, 0x7A, 0xB4, 0x44, 0xDC, - 0xB5, 0xC8, 0xD8, 0x7C, 0x49, 0x5D, 0xBD, 0xB3, - 0x4E, 0x18, 0x38, 0xB6, 0xB6, 0x29, 0x42, 0x7C, - 0xAA, 0x51, 0x70, 0x2A, 0xD0, 0xF9, 0x68, 0x85, - 0x25, 0xF1, 0x3B, 0xEC, 0x50, 0x3A, 0x3C, 0x3A, - 0x2C, 0x80, 0xA6, 0x5E, 0x0B, 0x57, 0x15, 0xE8, - 0xAF, 0xAB, 0x00, 0xFF, 0xA5, 0x6E, 0xC4, 0x55, - 0xA4, 0x9A, 0x1A, 0xD3, 0x0A, 0xA2, 0x4F, 0xCD - }, - { - 0x9A, 0xAF, 0x80, 0x20, 0x7B, 0xAC, 0xE1, 0x7B, - 0xB7, 0xAB, 0x14, 0x57, 0x57, 0xD5, 0x69, 0x6B, - 0xDE, 0x32, 0x40, 0x6E, 0xF2, 0x2B, 0x44, 0x29, - 0x2E, 0xF6, 0x5D, 0x45, 0x19, 0xC3, 0xBB, 0x2A, - 0xD4, 0x1A, 0x59, 0xB6, 0x2C, 0xC3, 0xE9, 0x4B, - 0x6F, 0xA9, 0x6D, 0x32, 0xA7, 0xFA, 0xAD, 0xAE, - 0x28, 0xAF, 0x7D, 0x35, 0x09, 0x72, 0x19, 0xAA, - 0x3F, 0xD8, 0xCD, 0xA3, 0x1E, 0x40, 0xC2, 0x75 - }, - { - 0xAF, 0x88, 0xB1, 0x63, 0x40, 0x2C, 0x86, 0x74, - 0x5C, 0xB6, 0x50, 0xC2, 0x98, 0x8F, 0xB9, 0x52, - 0x11, 0xB9, 0x4B, 0x03, 0xEF, 0x29, 0x0E, 0xED, - 0x96, 0x62, 0x03, 0x42, 0x41, 0xFD, 0x51, 0xCF, - 0x39, 0x8F, 0x80, 0x73, 0xE3, 0x69, 0x35, 0x4C, - 0x43, 0xEA, 0xE1, 0x05, 0x2F, 0x9B, 0x63, 0xB0, - 0x81, 0x91, 0xCA, 0xA1, 0x38, 0xAA, 0x54, 0xFE, - 0xA8, 0x89, 0xCC, 0x70, 0x24, 0x23, 0x68, 0x97 - }, - { - 0x48, 0xFA, 0x7D, 0x64, 0xE1, 0xCE, 0xEE, 0x27, - 0xB9, 0x86, 0x4D, 0xB5, 0xAD, 0xA4, 0xB5, 0x3D, - 0x00, 0xC9, 0xBC, 0x76, 0x26, 0x55, 0x58, 0x13, - 0xD3, 0xCD, 0x67, 0x30, 0xAB, 0x3C, 0xC0, 0x6F, - 0xF3, 0x42, 0xD7, 0x27, 0x90, 0x5E, 0x33, 0x17, - 0x1B, 0xDE, 0x6E, 0x84, 0x76, 0xE7, 0x7F, 0xB1, - 0x72, 0x08, 0x61, 0xE9, 0x4B, 0x73, 0xA2, 0xC5, - 0x38, 0xD2, 0x54, 0x74, 0x62, 0x85, 0xF4, 0x30 - }, - { - 0x0E, 0x6F, 0xD9, 0x7A, 0x85, 0xE9, 0x04, 0xF8, - 0x7B, 0xFE, 0x85, 0xBB, 0xEB, 0x34, 0xF6, 0x9E, - 0x1F, 0x18, 0x10, 0x5C, 0xF4, 0xED, 0x4F, 0x87, - 0xAE, 0xC3, 0x6C, 0x6E, 0x8B, 0x5F, 0x68, 0xBD, - 0x2A, 0x6F, 0x3D, 0xC8, 0xA9, 0xEC, 0xB2, 0xB6, - 0x1D, 0xB4, 0xEE, 0xDB, 0x6B, 0x2E, 0xA1, 0x0B, - 0xF9, 0xCB, 0x02, 0x51, 0xFB, 0x0F, 0x8B, 0x34, - 0x4A, 0xBF, 0x7F, 0x36, 0x6B, 0x6D, 0xE5, 0xAB - }, - { - 0x06, 0x62, 0x2D, 0xA5, 0x78, 0x71, 0x76, 0x28, - 0x7F, 0xDC, 0x8F, 0xED, 0x44, 0x0B, 0xAD, 0x18, - 0x7D, 0x83, 0x00, 0x99, 0xC9, 0x4E, 0x6D, 0x04, - 0xC8, 0xE9, 0xC9, 0x54, 0xCD, 0xA7, 0x0C, 0x8B, - 0xB9, 0xE1, 0xFC, 0x4A, 0x6D, 0x0B, 0xAA, 0x83, - 0x1B, 0x9B, 0x78, 0xEF, 0x66, 0x48, 0x68, 0x1A, - 0x48, 0x67, 0xA1, 0x1D, 0xA9, 0x3E, 0xE3, 0x6E, - 0x5E, 0x6A, 0x37, 0xD8, 0x7F, 0xC6, 0x3F, 0x6F - }, - { - 0x1D, 0xA6, 0x77, 0x2B, 0x58, 0xFA, 0xBF, 0x9C, - 0x61, 0xF6, 0x8D, 0x41, 0x2C, 0x82, 0xF1, 0x82, - 0xC0, 0x23, 0x6D, 0x7D, 0x57, 0x5E, 0xF0, 0xB5, - 0x8D, 0xD2, 0x24, 0x58, 0xD6, 0x43, 0xCD, 0x1D, - 0xFC, 0x93, 0xB0, 0x38, 0x71, 0xC3, 0x16, 0xD8, - 0x43, 0x0D, 0x31, 0x29, 0x95, 0xD4, 0x19, 0x7F, - 0x08, 0x74, 0xC9, 0x91, 0x72, 0xBA, 0x00, 0x4A, - 0x01, 0xEE, 0x29, 0x5A, 0xBA, 0xC2, 0x4E, 0x46 - }, - { - 0x3C, 0xD2, 0xD9, 0x32, 0x0B, 0x7B, 0x1D, 0x5F, - 0xB9, 0xAA, 0xB9, 0x51, 0xA7, 0x60, 0x23, 0xFA, - 0x66, 0x7B, 0xE1, 0x4A, 0x91, 0x24, 0xE3, 0x94, - 0x51, 0x39, 0x18, 0xA3, 0xF4, 0x40, 0x96, 0xAE, - 0x49, 0x04, 0xBA, 0x0F, 0xFC, 0x15, 0x0B, 0x63, - 0xBC, 0x7A, 0xB1, 0xEE, 0xB9, 0xA6, 0xE2, 0x57, - 0xE5, 0xC8, 0xF0, 0x00, 0xA7, 0x03, 0x94, 0xA5, - 0xAF, 0xD8, 0x42, 0x71, 0x5D, 0xE1, 0x5F, 0x29 - }, - { - 0x04, 0xCD, 0xC1, 0x4F, 0x74, 0x34, 0xE0, 0xB4, - 0xBE, 0x70, 0xCB, 0x41, 0xDB, 0x4C, 0x77, 0x9A, - 0x88, 0xEA, 0xEF, 0x6A, 0xCC, 0xEB, 0xCB, 0x41, - 0xF2, 0xD4, 0x2F, 0xFF, 0xE7, 0xF3, 0x2A, 0x8E, - 0x28, 0x1B, 0x5C, 0x10, 0x3A, 0x27, 0x02, 0x1D, - 0x0D, 0x08, 0x36, 0x22, 0x50, 0x75, 0x3C, 0xDF, - 0x70, 0x29, 0x21, 0x95, 0xA5, 0x3A, 0x48, 0x72, - 0x8C, 0xEB, 0x58, 0x44, 0xC2, 0xD9, 0x8B, 0xAB - }, - { - 0x90, 0x71, 0xB7, 0xA8, 0xA0, 0x75, 0xD0, 0x09, - 0x5B, 0x8F, 0xB3, 0xAE, 0x51, 0x13, 0x78, 0x57, - 0x35, 0xAB, 0x98, 0xE2, 0xB5, 0x2F, 0xAF, 0x91, - 0xD5, 0xB8, 0x9E, 0x44, 0xAA, 0xC5, 0xB5, 0xD4, - 0xEB, 0xBF, 0x91, 0x22, 0x3B, 0x0F, 0xF4, 0xC7, - 0x19, 0x05, 0xDA, 0x55, 0x34, 0x2E, 0x64, 0x65, - 0x5D, 0x6E, 0xF8, 0xC8, 0x9A, 0x47, 0x68, 0xC3, - 0xF9, 0x3A, 0x6D, 0xC0, 0x36, 0x6B, 0x5B, 0xC8 - }, - { - 0xEB, 0xB3, 0x02, 0x40, 0xDD, 0x96, 0xC7, 0xBC, - 0x8D, 0x0A, 0xBE, 0x49, 0xAA, 0x4E, 0xDC, 0xBB, - 0x4A, 0xFD, 0xC5, 0x1F, 0xF9, 0xAA, 0xF7, 0x20, - 0xD3, 0xF9, 0xE7, 0xFB, 0xB0, 0xF9, 0xC6, 0xD6, - 0x57, 0x13, 0x50, 0x50, 0x17, 0x69, 0xFC, 0x4E, - 0xBD, 0x0B, 0x21, 0x41, 0x24, 0x7F, 0xF4, 0x00, - 0xD4, 0xFD, 0x4B, 0xE4, 0x14, 0xED, 0xF3, 0x77, - 0x57, 0xBB, 0x90, 0xA3, 0x2A, 0xC5, 0xC6, 0x5A - }, - { - 0x85, 0x32, 0xC5, 0x8B, 0xF3, 0xC8, 0x01, 0x5D, - 0x9D, 0x1C, 0xBE, 0x00, 0xEE, 0xF1, 0xF5, 0x08, - 0x2F, 0x8F, 0x36, 0x32, 0xFB, 0xE9, 0xF1, 0xED, - 0x4F, 0x9D, 0xFB, 0x1F, 0xA7, 0x9E, 0x82, 0x83, - 0x06, 0x6D, 0x77, 0xC4, 0x4C, 0x4A, 0xF9, 0x43, - 0xD7, 0x6B, 0x30, 0x03, 0x64, 0xAE, 0xCB, 0xD0, - 0x64, 0x8C, 0x8A, 0x89, 0x39, 0xBD, 0x20, 0x41, - 0x23, 0xF4, 0xB5, 0x62, 0x60, 0x42, 0x2D, 0xEC - }, - { - 0xFE, 0x98, 0x46, 0xD6, 0x4F, 0x7C, 0x77, 0x08, - 0x69, 0x6F, 0x84, 0x0E, 0x2D, 0x76, 0xCB, 0x44, - 0x08, 0xB6, 0x59, 0x5C, 0x2F, 0x81, 0xEC, 0x6A, - 0x28, 0xA7, 0xF2, 0xF2, 0x0C, 0xB8, 0x8C, 0xFE, - 0x6A, 0xC0, 0xB9, 0xE9, 0xB8, 0x24, 0x4F, 0x08, - 0xBD, 0x70, 0x95, 0xC3, 0x50, 0xC1, 0xD0, 0x84, - 0x2F, 0x64, 0xFB, 0x01, 0xBB, 0x7F, 0x53, 0x2D, - 0xFC, 0xD4, 0x73, 0x71, 0xB0, 0xAE, 0xEB, 0x79 - }, - { - 0x28, 0xF1, 0x7E, 0xA6, 0xFB, 0x6C, 0x42, 0x09, - 0x2D, 0xC2, 0x64, 0x25, 0x7E, 0x29, 0x74, 0x63, - 0x21, 0xFB, 0x5B, 0xDA, 0xEA, 0x98, 0x73, 0xC2, - 0xA7, 0xFA, 0x9D, 0x8F, 0x53, 0x81, 0x8E, 0x89, - 0x9E, 0x16, 0x1B, 0xC7, 0x7D, 0xFE, 0x80, 0x90, - 0xAF, 0xD8, 0x2B, 0xF2, 0x26, 0x6C, 0x5C, 0x1B, - 0xC9, 0x30, 0xA8, 0xD1, 0x54, 0x76, 0x24, 0x43, - 0x9E, 0x66, 0x2E, 0xF6, 0x95, 0xF2, 0x6F, 0x24 - }, - { - 0xEC, 0x6B, 0x7D, 0x7F, 0x03, 0x0D, 0x48, 0x50, - 0xAC, 0xAE, 0x3C, 0xB6, 0x15, 0xC2, 0x1D, 0xD2, - 0x52, 0x06, 0xD6, 0x3E, 0x84, 0xD1, 0xDB, 0x8D, - 0x95, 0x73, 0x70, 0x73, 0x7B, 0xA0, 0xE9, 0x84, - 0x67, 0xEA, 0x0C, 0xE2, 0x74, 0xC6, 0x61, 0x99, - 0x90, 0x1E, 0xAE, 0xC1, 0x8A, 0x08, 0x52, 0x57, - 0x15, 0xF5, 0x3B, 0xFD, 0xB0, 0xAA, 0xCB, 0x61, - 0x3D, 0x34, 0x2E, 0xBD, 0xCE, 0xED, 0xDC, 0x3B - }, - { - 0xB4, 0x03, 0xD3, 0x69, 0x1C, 0x03, 0xB0, 0xD3, - 0x41, 0x8D, 0xF3, 0x27, 0xD5, 0x86, 0x0D, 0x34, - 0xBB, 0xFC, 0xC4, 0x51, 0x9B, 0xFB, 0xCE, 0x36, - 0xBF, 0x33, 0xB2, 0x08, 0x38, 0x5F, 0xAD, 0xB9, - 0x18, 0x6B, 0xC7, 0x8A, 0x76, 0xC4, 0x89, 0xD8, - 0x9F, 0xD5, 0x7E, 0x7D, 0xC7, 0x54, 0x12, 0xD2, - 0x3B, 0xCD, 0x1D, 0xAE, 0x84, 0x70, 0xCE, 0x92, - 0x74, 0x75, 0x4B, 0xB8, 0x58, 0x5B, 0x13, 0xC5 - }, - { - 0x31, 0xFC, 0x79, 0x73, 0x8B, 0x87, 0x72, 0xB3, - 0xF5, 0x5C, 0xD8, 0x17, 0x88, 0x13, 0xB3, 0xB5, - 0x2D, 0x0D, 0xB5, 0xA4, 0x19, 0xD3, 0x0B, 0xA9, - 0x49, 0x5C, 0x4B, 0x9D, 0xA0, 0x21, 0x9F, 0xAC, - 0x6D, 0xF8, 0xE7, 0xC2, 0x3A, 0x81, 0x15, 0x51, - 0xA6, 0x2B, 0x82, 0x7F, 0x25, 0x6E, 0xCD, 0xB8, - 0x12, 0x4A, 0xC8, 0xA6, 0x79, 0x2C, 0xCF, 0xEC, - 0xC3, 0xB3, 0x01, 0x27, 0x22, 0xE9, 0x44, 0x63 - }, - { - 0xBB, 0x20, 0x39, 0xEC, 0x28, 0x70, 0x91, 0xBC, - 0xC9, 0x64, 0x2F, 0xC9, 0x00, 0x49, 0xE7, 0x37, - 0x32, 0xE0, 0x2E, 0x57, 0x7E, 0x28, 0x62, 0xB3, - 0x22, 0x16, 0xAE, 0x9B, 0xED, 0xCD, 0x73, 0x0C, - 0x4C, 0x28, 0x4E, 0xF3, 0x96, 0x8C, 0x36, 0x8B, - 0x7D, 0x37, 0x58, 0x4F, 0x97, 0xBD, 0x4B, 0x4D, - 0xC6, 0xEF, 0x61, 0x27, 0xAC, 0xFE, 0x2E, 0x6A, - 0xE2, 0x50, 0x91, 0x24, 0xE6, 0x6C, 0x8A, 0xF4 - }, - { - 0xF5, 0x3D, 0x68, 0xD1, 0x3F, 0x45, 0xED, 0xFC, - 0xB9, 0xBD, 0x41, 0x5E, 0x28, 0x31, 0xE9, 0x38, - 0x35, 0x0D, 0x53, 0x80, 0xD3, 0x43, 0x22, 0x78, - 0xFC, 0x1C, 0x0C, 0x38, 0x1F, 0xCB, 0x7C, 0x65, - 0xC8, 0x2D, 0xAF, 0xE0, 0x51, 0xD8, 0xC8, 0xB0, - 0xD4, 0x4E, 0x09, 0x74, 0xA0, 0xE5, 0x9E, 0xC7, - 0xBF, 0x7E, 0xD0, 0x45, 0x9F, 0x86, 0xE9, 0x6F, - 0x32, 0x9F, 0xC7, 0x97, 0x52, 0x51, 0x0F, 0xD3 - }, - { - 0x8D, 0x56, 0x8C, 0x79, 0x84, 0xF0, 0xEC, 0xDF, - 0x76, 0x40, 0xFB, 0xC4, 0x83, 0xB5, 0xD8, 0xC9, - 0xF8, 0x66, 0x34, 0xF6, 0xF4, 0x32, 0x91, 0x84, - 0x1B, 0x30, 0x9A, 0x35, 0x0A, 0xB9, 0xC1, 0x13, - 0x7D, 0x24, 0x06, 0x6B, 0x09, 0xDA, 0x99, 0x44, - 0xBA, 0xC5, 0x4D, 0x5B, 0xB6, 0x58, 0x0D, 0x83, - 0x60, 0x47, 0xAA, 0xC7, 0x4A, 0xB7, 0x24, 0xB8, - 0x87, 0xEB, 0xF9, 0x3D, 0x4B, 0x32, 0xEC, 0xA9 - }, - { - 0xC0, 0xB6, 0x5C, 0xE5, 0xA9, 0x6F, 0xF7, 0x74, - 0xC4, 0x56, 0xCA, 0xC3, 0xB5, 0xF2, 0xC4, 0xCD, - 0x35, 0x9B, 0x4F, 0xF5, 0x3E, 0xF9, 0x3A, 0x3D, - 0xA0, 0x77, 0x8B, 0xE4, 0x90, 0x0D, 0x1E, 0x8D, - 0xA1, 0x60, 0x1E, 0x76, 0x9E, 0x8F, 0x1B, 0x02, - 0xD2, 0xA2, 0xF8, 0xC5, 0xB9, 0xFA, 0x10, 0xB4, - 0x4F, 0x1C, 0x18, 0x69, 0x85, 0x46, 0x8F, 0xEE, - 0xB0, 0x08, 0x73, 0x02, 0x83, 0xA6, 0x65, 0x7D - }, - { - 0x49, 0x00, 0xBB, 0xA6, 0xF5, 0xFB, 0x10, 0x3E, - 0xCE, 0x8E, 0xC9, 0x6A, 0xDA, 0x13, 0xA5, 0xC3, - 0xC8, 0x54, 0x88, 0xE0, 0x55, 0x51, 0xDA, 0x6B, - 0x6B, 0x33, 0xD9, 0x88, 0xE6, 0x11, 0xEC, 0x0F, - 0xE2, 0xE3, 0xC2, 0xAA, 0x48, 0xEA, 0x6A, 0xE8, - 0x98, 0x6A, 0x3A, 0x23, 0x1B, 0x22, 0x3C, 0x5D, - 0x27, 0xCE, 0xC2, 0xEA, 0xDD, 0xE9, 0x1C, 0xE0, - 0x79, 0x81, 0xEE, 0x65, 0x28, 0x62, 0xD1, 0xE4 - }, - { - 0xC7, 0xF5, 0xC3, 0x7C, 0x72, 0x85, 0xF9, 0x27, - 0xF7, 0x64, 0x43, 0x41, 0x4D, 0x43, 0x57, 0xFF, - 0x78, 0x96, 0x47, 0xD7, 0xA0, 0x05, 0xA5, 0xA7, - 0x87, 0xE0, 0x3C, 0x34, 0x6B, 0x57, 0xF4, 0x9F, - 0x21, 0xB6, 0x4F, 0xA9, 0xCF, 0x4B, 0x7E, 0x45, - 0x57, 0x3E, 0x23, 0x04, 0x90, 0x17, 0x56, 0x71, - 0x21, 0xA9, 0xC3, 0xD4, 0xB2, 0xB7, 0x3E, 0xC5, - 0xE9, 0x41, 0x35, 0x77, 0x52, 0x5D, 0xB4, 0x5A - }, - { - 0xEC, 0x70, 0x96, 0x33, 0x07, 0x36, 0xFD, 0xB2, - 0xD6, 0x4B, 0x56, 0x53, 0xE7, 0x47, 0x5D, 0xA7, - 0x46, 0xC2, 0x3A, 0x46, 0x13, 0xA8, 0x26, 0x87, - 0xA2, 0x80, 0x62, 0xD3, 0x23, 0x63, 0x64, 0x28, - 0x4A, 0xC0, 0x17, 0x20, 0xFF, 0xB4, 0x06, 0xCF, - 0xE2, 0x65, 0xC0, 0xDF, 0x62, 0x6A, 0x18, 0x8C, - 0x9E, 0x59, 0x63, 0xAC, 0xE5, 0xD3, 0xD5, 0xBB, - 0x36, 0x3E, 0x32, 0xC3, 0x8C, 0x21, 0x90, 0xA6 - }, - { - 0x82, 0xE7, 0x44, 0xC7, 0x5F, 0x46, 0x49, 0xEC, - 0x52, 0xB8, 0x07, 0x71, 0xA7, 0x7D, 0x47, 0x5A, - 0x3B, 0xC0, 0x91, 0x98, 0x95, 0x56, 0x96, 0x0E, - 0x27, 0x6A, 0x5F, 0x9E, 0xAD, 0x92, 0xA0, 0x3F, - 0x71, 0x87, 0x42, 0xCD, 0xCF, 0xEA, 0xEE, 0x5C, - 0xB8, 0x5C, 0x44, 0xAF, 0x19, 0x8A, 0xDC, 0x43, - 0xA4, 0xA4, 0x28, 0xF5, 0xF0, 0xC2, 0xDD, 0xB0, - 0xBE, 0x36, 0x05, 0x9F, 0x06, 0xD7, 0xDF, 0x73 - }, - { - 0x28, 0x34, 0xB7, 0xA7, 0x17, 0x0F, 0x1F, 0x5B, - 0x68, 0x55, 0x9A, 0xB7, 0x8C, 0x10, 0x50, 0xEC, - 0x21, 0xC9, 0x19, 0x74, 0x0B, 0x78, 0x4A, 0x90, - 0x72, 0xF6, 0xE5, 0xD6, 0x9F, 0x82, 0x8D, 0x70, - 0xC9, 0x19, 0xC5, 0x03, 0x9F, 0xB1, 0x48, 0xE3, - 0x9E, 0x2C, 0x8A, 0x52, 0x11, 0x83, 0x78, 0xB0, - 0x64, 0xCA, 0x8D, 0x50, 0x01, 0xCD, 0x10, 0xA5, - 0x47, 0x83, 0x87, 0xB9, 0x66, 0x71, 0x5E, 0xD6 - }, - { - 0x16, 0xB4, 0xAD, 0xA8, 0x83, 0xF7, 0x2F, 0x85, - 0x3B, 0xB7, 0xEF, 0x25, 0x3E, 0xFC, 0xAB, 0x0C, - 0x3E, 0x21, 0x61, 0x68, 0x7A, 0xD6, 0x15, 0x43, - 0xA0, 0xD2, 0x82, 0x4F, 0x91, 0xC1, 0xF8, 0x13, - 0x47, 0xD8, 0x6B, 0xE7, 0x09, 0xB1, 0x69, 0x96, - 0xE1, 0x7F, 0x2D, 0xD4, 0x86, 0x92, 0x7B, 0x02, - 0x88, 0xAD, 0x38, 0xD1, 0x30, 0x63, 0xC4, 0xA9, - 0x67, 0x2C, 0x39, 0x39, 0x7D, 0x37, 0x89, 0xB6 - }, - { - 0x78, 0xD0, 0x48, 0xF3, 0xA6, 0x9D, 0x8B, 0x54, - 0xAE, 0x0E, 0xD6, 0x3A, 0x57, 0x3A, 0xE3, 0x50, - 0xD8, 0x9F, 0x7C, 0x6C, 0xF1, 0xF3, 0x68, 0x89, - 0x30, 0xDE, 0x89, 0x9A, 0xFA, 0x03, 0x76, 0x97, - 0x62, 0x9B, 0x31, 0x4E, 0x5C, 0xD3, 0x03, 0xAA, - 0x62, 0xFE, 0xEA, 0x72, 0xA2, 0x5B, 0xF4, 0x2B, - 0x30, 0x4B, 0x6C, 0x6B, 0xCB, 0x27, 0xFA, 0xE2, - 0x1C, 0x16, 0xD9, 0x25, 0xE1, 0xFB, 0xDA, 0xC3 - }, - { - 0x0F, 0x74, 0x6A, 0x48, 0x74, 0x92, 0x87, 0xAD, - 0xA7, 0x7A, 0x82, 0x96, 0x1F, 0x05, 0xA4, 0xDA, - 0x4A, 0xBD, 0xB7, 0xD7, 0x7B, 0x12, 0x20, 0xF8, - 0x36, 0xD0, 0x9E, 0xC8, 0x14, 0x35, 0x9C, 0x0E, - 0xC0, 0x23, 0x9B, 0x8C, 0x7B, 0x9F, 0xF9, 0xE0, - 0x2F, 0x56, 0x9D, 0x1B, 0x30, 0x1E, 0xF6, 0x7C, - 0x46, 0x12, 0xD1, 0xDE, 0x4F, 0x73, 0x0F, 0x81, - 0xC1, 0x2C, 0x40, 0xCC, 0x06, 0x3C, 0x5C, 0xAA - }, - { - 0xF0, 0xFC, 0x85, 0x9D, 0x3B, 0xD1, 0x95, 0xFB, - 0xDC, 0x2D, 0x59, 0x1E, 0x4C, 0xDA, 0xC1, 0x51, - 0x79, 0xEC, 0x0F, 0x1D, 0xC8, 0x21, 0xC1, 0x1D, - 0xF1, 0xF0, 0xC1, 0xD2, 0x6E, 0x62, 0x60, 0xAA, - 0xA6, 0x5B, 0x79, 0xFA, 0xFA, 0xCA, 0xFD, 0x7D, - 0x3A, 0xD6, 0x1E, 0x60, 0x0F, 0x25, 0x09, 0x05, - 0xF5, 0x87, 0x8C, 0x87, 0x45, 0x28, 0x97, 0x64, - 0x7A, 0x35, 0xB9, 0x95, 0xBC, 0xAD, 0xC3, 0xA3 - }, - { - 0x26, 0x20, 0xF6, 0x87, 0xE8, 0x62, 0x5F, 0x6A, - 0x41, 0x24, 0x60, 0xB4, 0x2E, 0x2C, 0xEF, 0x67, - 0x63, 0x42, 0x08, 0xCE, 0x10, 0xA0, 0xCB, 0xD4, - 0xDF, 0xF7, 0x04, 0x4A, 0x41, 0xB7, 0x88, 0x00, - 0x77, 0xE9, 0xF8, 0xDC, 0x3B, 0x8D, 0x12, 0x16, - 0xD3, 0x37, 0x6A, 0x21, 0xE0, 0x15, 0xB5, 0x8F, - 0xB2, 0x79, 0xB5, 0x21, 0xD8, 0x3F, 0x93, 0x88, - 0xC7, 0x38, 0x2C, 0x85, 0x05, 0x59, 0x0B, 0x9B - }, - { - 0x22, 0x7E, 0x3A, 0xED, 0x8D, 0x2C, 0xB1, 0x0B, - 0x91, 0x8F, 0xCB, 0x04, 0xF9, 0xDE, 0x3E, 0x6D, - 0x0A, 0x57, 0xE0, 0x84, 0x76, 0xD9, 0x37, 0x59, - 0xCD, 0x7B, 0x2E, 0xD5, 0x4A, 0x1C, 0xBF, 0x02, - 0x39, 0xC5, 0x28, 0xFB, 0x04, 0xBB, 0xF2, 0x88, - 0x25, 0x3E, 0x60, 0x1D, 0x3B, 0xC3, 0x8B, 0x21, - 0x79, 0x4A, 0xFE, 0xF9, 0x0B, 0x17, 0x09, 0x4A, - 0x18, 0x2C, 0xAC, 0x55, 0x77, 0x45, 0xE7, 0x5F - }, - { - 0x1A, 0x92, 0x99, 0x01, 0xB0, 0x9C, 0x25, 0xF2, - 0x7D, 0x6B, 0x35, 0xBE, 0x7B, 0x2F, 0x1C, 0x47, - 0x45, 0x13, 0x1F, 0xDE, 0xBC, 0xA7, 0xF3, 0xE2, - 0x45, 0x19, 0x26, 0x72, 0x04, 0x34, 0xE0, 0xDB, - 0x6E, 0x74, 0xFD, 0x69, 0x3A, 0xD2, 0x9B, 0x77, - 0x7D, 0xC3, 0x35, 0x5C, 0x59, 0x2A, 0x36, 0x1C, - 0x48, 0x73, 0xB0, 0x11, 0x33, 0xA5, 0x7C, 0x2E, - 0x3B, 0x70, 0x75, 0xCB, 0xDB, 0x86, 0xF4, 0xFC - }, - { - 0x5F, 0xD7, 0x96, 0x8B, 0xC2, 0xFE, 0x34, 0xF2, - 0x20, 0xB5, 0xE3, 0xDC, 0x5A, 0xF9, 0x57, 0x17, - 0x42, 0xD7, 0x3B, 0x7D, 0x60, 0x81, 0x9F, 0x28, - 0x88, 0xB6, 0x29, 0x07, 0x2B, 0x96, 0xA9, 0xD8, - 0xAB, 0x2D, 0x91, 0xB8, 0x2D, 0x0A, 0x9A, 0xAB, - 0xA6, 0x1B, 0xBD, 0x39, 0x95, 0x81, 0x32, 0xFC, - 0xC4, 0x25, 0x70, 0x23, 0xD1, 0xEC, 0xA5, 0x91, - 0xB3, 0x05, 0x4E, 0x2D, 0xC8, 0x1C, 0x82, 0x00 - }, - { - 0xDF, 0xCC, 0xE8, 0xCF, 0x32, 0x87, 0x0C, 0xC6, - 0xA5, 0x03, 0xEA, 0xDA, 0xFC, 0x87, 0xFD, 0x6F, - 0x78, 0x91, 0x8B, 0x9B, 0x4D, 0x07, 0x37, 0xDB, - 0x68, 0x10, 0xBE, 0x99, 0x6B, 0x54, 0x97, 0xE7, - 0xE5, 0xCC, 0x80, 0xE3, 0x12, 0xF6, 0x1E, 0x71, - 0xFF, 0x3E, 0x96, 0x24, 0x43, 0x60, 0x73, 0x15, - 0x64, 0x03, 0xF7, 0x35, 0xF5, 0x6B, 0x0B, 0x01, - 0x84, 0x5C, 0x18, 0xF6, 0xCA, 0xF7, 0x72, 0xE6 - }, - { - 0x02, 0xF7, 0xEF, 0x3A, 0x9C, 0xE0, 0xFF, 0xF9, - 0x60, 0xF6, 0x70, 0x32, 0xB2, 0x96, 0xEF, 0xCA, - 0x30, 0x61, 0xF4, 0x93, 0x4D, 0x69, 0x07, 0x49, - 0xF2, 0xD0, 0x1C, 0x35, 0xC8, 0x1C, 0x14, 0xF3, - 0x9A, 0x67, 0xFA, 0x35, 0x0B, 0xC8, 0xA0, 0x35, - 0x9B, 0xF1, 0x72, 0x4B, 0xFF, 0xC3, 0xBC, 0xA6, - 0xD7, 0xC7, 0xBB, 0xA4, 0x79, 0x1F, 0xD5, 0x22, - 0xA3, 0xAD, 0x35, 0x3C, 0x02, 0xEC, 0x5A, 0xA8 - }, - { - 0x64, 0xBE, 0x5C, 0x6A, 0xBA, 0x65, 0xD5, 0x94, - 0x84, 0x4A, 0xE7, 0x8B, 0xB0, 0x22, 0xE5, 0xBE, - 0xBE, 0x12, 0x7F, 0xD6, 0xB6, 0xFF, 0xA5, 0xA1, - 0x37, 0x03, 0x85, 0x5A, 0xB6, 0x3B, 0x62, 0x4D, - 0xCD, 0x1A, 0x36, 0x3F, 0x99, 0x20, 0x3F, 0x63, - 0x2E, 0xC3, 0x86, 0xF3, 0xEA, 0x76, 0x7F, 0xC9, - 0x92, 0xE8, 0xED, 0x96, 0x86, 0x58, 0x6A, 0xA2, - 0x75, 0x55, 0xA8, 0x59, 0x9D, 0x5B, 0x80, 0x8F - }, - { - 0xF7, 0x85, 0x85, 0x50, 0x5C, 0x4E, 0xAA, 0x54, - 0xA8, 0xB5, 0xBE, 0x70, 0xA6, 0x1E, 0x73, 0x5E, - 0x0F, 0xF9, 0x7A, 0xF9, 0x44, 0xDD, 0xB3, 0x00, - 0x1E, 0x35, 0xD8, 0x6C, 0x4E, 0x21, 0x99, 0xD9, - 0x76, 0x10, 0x4B, 0x6A, 0xE3, 0x17, 0x50, 0xA3, - 0x6A, 0x72, 0x6E, 0xD2, 0x85, 0x06, 0x4F, 0x59, - 0x81, 0xB5, 0x03, 0x88, 0x9F, 0xEF, 0x82, 0x2F, - 0xCD, 0xC2, 0x89, 0x8D, 0xDD, 0xB7, 0x88, 0x9A - }, - { - 0xE4, 0xB5, 0x56, 0x60, 0x33, 0x86, 0x95, 0x72, - 0xED, 0xFD, 0x87, 0x47, 0x9A, 0x5B, 0xB7, 0x3C, - 0x80, 0xE8, 0x75, 0x9B, 0x91, 0x23, 0x28, 0x79, - 0xD9, 0x6B, 0x1D, 0xDA, 0x36, 0xC0, 0x12, 0x07, - 0x6E, 0xE5, 0xA2, 0xED, 0x7A, 0xE2, 0xDE, 0x63, - 0xEF, 0x84, 0x06, 0xA0, 0x6A, 0xEA, 0x82, 0xC1, - 0x88, 0x03, 0x1B, 0x56, 0x0B, 0xEA, 0xFB, 0x58, - 0x3F, 0xB3, 0xDE, 0x9E, 0x57, 0x95, 0x2A, 0x7E - }, - { - 0xE1, 0xB3, 0xE7, 0xED, 0x86, 0x7F, 0x6C, 0x94, - 0x84, 0xA2, 0xA9, 0x7F, 0x77, 0x15, 0xF2, 0x5E, - 0x25, 0x29, 0x4E, 0x99, 0x2E, 0x41, 0xF6, 0xA7, - 0xC1, 0x61, 0xFF, 0xC2, 0xAD, 0xC6, 0xDA, 0xAE, - 0xB7, 0x11, 0x31, 0x02, 0xD5, 0xE6, 0x09, 0x02, - 0x87, 0xFE, 0x6A, 0xD9, 0x4C, 0xE5, 0xD6, 0xB7, - 0x39, 0xC6, 0xCA, 0x24, 0x0B, 0x05, 0xC7, 0x6F, - 0xB7, 0x3F, 0x25, 0xDD, 0x02, 0x4B, 0xF9, 0x35 - }, - { - 0x85, 0xFD, 0x08, 0x5F, 0xDC, 0x12, 0xA0, 0x80, - 0x98, 0x3D, 0xF0, 0x7B, 0xD7, 0x01, 0x2B, 0x0D, - 0x40, 0x2A, 0x0F, 0x40, 0x43, 0xFC, 0xB2, 0x77, - 0x5A, 0xDF, 0x0B, 0xAD, 0x17, 0x4F, 0x9B, 0x08, - 0xD1, 0x67, 0x6E, 0x47, 0x69, 0x85, 0x78, 0x5C, - 0x0A, 0x5D, 0xCC, 0x41, 0xDB, 0xFF, 0x6D, 0x95, - 0xEF, 0x4D, 0x66, 0xA3, 0xFB, 0xDC, 0x4A, 0x74, - 0xB8, 0x2B, 0xA5, 0x2D, 0xA0, 0x51, 0x2B, 0x74 - }, - { - 0xAE, 0xD8, 0xFA, 0x76, 0x4B, 0x0F, 0xBF, 0xF8, - 0x21, 0xE0, 0x52, 0x33, 0xD2, 0xF7, 0xB0, 0x90, - 0x0E, 0xC4, 0x4D, 0x82, 0x6F, 0x95, 0xE9, 0x3C, - 0x34, 0x3C, 0x1B, 0xC3, 0xBA, 0x5A, 0x24, 0x37, - 0x4B, 0x1D, 0x61, 0x6E, 0x7E, 0x7A, 0xBA, 0x45, - 0x3A, 0x0A, 0xDA, 0x5E, 0x4F, 0xAB, 0x53, 0x82, - 0x40, 0x9E, 0x0D, 0x42, 0xCE, 0x9C, 0x2B, 0xC7, - 0xFB, 0x39, 0xA9, 0x9C, 0x34, 0x0C, 0x20, 0xF0 - }, - { - 0x7B, 0xA3, 0xB2, 0xE2, 0x97, 0x23, 0x35, 0x22, - 0xEE, 0xB3, 0x43, 0xBD, 0x3E, 0xBC, 0xFD, 0x83, - 0x5A, 0x04, 0x00, 0x77, 0x35, 0xE8, 0x7F, 0x0C, - 0xA3, 0x00, 0xCB, 0xEE, 0x6D, 0x41, 0x65, 0x65, - 0x16, 0x21, 0x71, 0x58, 0x1E, 0x40, 0x20, 0xFF, - 0x4C, 0xF1, 0x76, 0x45, 0x0F, 0x12, 0x91, 0xEA, - 0x22, 0x85, 0xCB, 0x9E, 0xBF, 0xFE, 0x4C, 0x56, - 0x66, 0x06, 0x27, 0x68, 0x51, 0x45, 0x05, 0x1C - }, - { - 0xDE, 0x74, 0x8B, 0xCF, 0x89, 0xEC, 0x88, 0x08, - 0x47, 0x21, 0xE1, 0x6B, 0x85, 0xF3, 0x0A, 0xDB, - 0x1A, 0x61, 0x34, 0xD6, 0x64, 0xB5, 0x84, 0x35, - 0x69, 0xBA, 0xBC, 0x5B, 0xBD, 0x1A, 0x15, 0xCA, - 0x9B, 0x61, 0x80, 0x3C, 0x90, 0x1A, 0x4F, 0xEF, - 0x32, 0x96, 0x5A, 0x17, 0x49, 0xC9, 0xF3, 0xA4, - 0xE2, 0x43, 0xE1, 0x73, 0x93, 0x9D, 0xC5, 0xA8, - 0xDC, 0x49, 0x5C, 0x67, 0x1A, 0xB5, 0x21, 0x45 - }, - { - 0xAA, 0xF4, 0xD2, 0xBD, 0xF2, 0x00, 0xA9, 0x19, - 0x70, 0x6D, 0x98, 0x42, 0xDC, 0xE1, 0x6C, 0x98, - 0x14, 0x0D, 0x34, 0xBC, 0x43, 0x3D, 0xF3, 0x20, - 0xAB, 0xA9, 0xBD, 0x42, 0x9E, 0x54, 0x9A, 0xA7, - 0xA3, 0x39, 0x76, 0x52, 0xA4, 0xD7, 0x68, 0x27, - 0x77, 0x86, 0xCF, 0x99, 0x3C, 0xDE, 0x23, 0x38, - 0x67, 0x3E, 0xD2, 0xE6, 0xB6, 0x6C, 0x96, 0x1F, - 0xEF, 0xB8, 0x2C, 0xD2, 0x0C, 0x93, 0x33, 0x8F - }, - { - 0xC4, 0x08, 0x21, 0x89, 0x68, 0xB7, 0x88, 0xBF, - 0x86, 0x4F, 0x09, 0x97, 0xE6, 0xBC, 0x4C, 0x3D, - 0xBA, 0x68, 0xB2, 0x76, 0xE2, 0x12, 0x5A, 0x48, - 0x43, 0x29, 0x60, 0x52, 0xFF, 0x93, 0xBF, 0x57, - 0x67, 0xB8, 0xCD, 0xCE, 0x71, 0x31, 0xF0, 0x87, - 0x64, 0x30, 0xC1, 0x16, 0x5F, 0xEC, 0x6C, 0x4F, - 0x47, 0xAD, 0xAA, 0x4F, 0xD8, 0xBC, 0xFA, 0xCE, - 0xF4, 0x63, 0xB5, 0xD3, 0xD0, 0xFA, 0x61, 0xA0 - }, - { - 0x76, 0xD2, 0xD8, 0x19, 0xC9, 0x2B, 0xCE, 0x55, - 0xFA, 0x8E, 0x09, 0x2A, 0xB1, 0xBF, 0x9B, 0x9E, - 0xAB, 0x23, 0x7A, 0x25, 0x26, 0x79, 0x86, 0xCA, - 0xCF, 0x2B, 0x8E, 0xE1, 0x4D, 0x21, 0x4D, 0x73, - 0x0D, 0xC9, 0xA5, 0xAA, 0x2D, 0x7B, 0x59, 0x6E, - 0x86, 0xA1, 0xFD, 0x8F, 0xA0, 0x80, 0x4C, 0x77, - 0x40, 0x2D, 0x2F, 0xCD, 0x45, 0x08, 0x36, 0x88, - 0xB2, 0x18, 0xB1, 0xCD, 0xFA, 0x0D, 0xCB, 0xCB - }, - { - 0x72, 0x06, 0x5E, 0xE4, 0xDD, 0x91, 0xC2, 0xD8, - 0x50, 0x9F, 0xA1, 0xFC, 0x28, 0xA3, 0x7C, 0x7F, - 0xC9, 0xFA, 0x7D, 0x5B, 0x3F, 0x8A, 0xD3, 0xD0, - 0xD7, 0xA2, 0x56, 0x26, 0xB5, 0x7B, 0x1B, 0x44, - 0x78, 0x8D, 0x4C, 0xAF, 0x80, 0x62, 0x90, 0x42, - 0x5F, 0x98, 0x90, 0xA3, 0xA2, 0xA3, 0x5A, 0x90, - 0x5A, 0xB4, 0xB3, 0x7A, 0xCF, 0xD0, 0xDA, 0x6E, - 0x45, 0x17, 0xB2, 0x52, 0x5C, 0x96, 0x51, 0xE4 - }, - { - 0x64, 0x47, 0x5D, 0xFE, 0x76, 0x00, 0xD7, 0x17, - 0x1B, 0xEA, 0x0B, 0x39, 0x4E, 0x27, 0xC9, 0xB0, - 0x0D, 0x8E, 0x74, 0xDD, 0x1E, 0x41, 0x6A, 0x79, - 0x47, 0x36, 0x82, 0xAD, 0x3D, 0xFD, 0xBB, 0x70, - 0x66, 0x31, 0x55, 0x80, 0x55, 0xCF, 0xC8, 0xA4, - 0x0E, 0x07, 0xBD, 0x01, 0x5A, 0x45, 0x40, 0xDC, - 0xDE, 0xA1, 0x58, 0x83, 0xCB, 0xBF, 0x31, 0x41, - 0x2D, 0xF1, 0xDE, 0x1C, 0xD4, 0x15, 0x2B, 0x91 - }, - { - 0x12, 0xCD, 0x16, 0x74, 0xA4, 0x48, 0x8A, 0x5D, - 0x7C, 0x2B, 0x31, 0x60, 0xD2, 0xE2, 0xC4, 0xB5, - 0x83, 0x71, 0xBE, 0xDA, 0xD7, 0x93, 0x41, 0x8D, - 0x6F, 0x19, 0xC6, 0xEE, 0x38, 0x5D, 0x70, 0xB3, - 0xE0, 0x67, 0x39, 0x36, 0x9D, 0x4D, 0xF9, 0x10, - 0xED, 0xB0, 0xB0, 0xA5, 0x4C, 0xBF, 0xF4, 0x3D, - 0x54, 0x54, 0x4C, 0xD3, 0x7A, 0xB3, 0xA0, 0x6C, - 0xFA, 0x0A, 0x3D, 0xDA, 0xC8, 0xB6, 0x6C, 0x89 - }, - { - 0x60, 0x75, 0x69, 0x66, 0x47, 0x9D, 0xED, 0xC6, - 0xDD, 0x4B, 0xCF, 0xF8, 0xEA, 0x7D, 0x1D, 0x4C, - 0xE4, 0xD4, 0xAF, 0x2E, 0x7B, 0x09, 0x7E, 0x32, - 0xE3, 0x76, 0x35, 0x18, 0x44, 0x11, 0x47, 0xCC, - 0x12, 0xB3, 0xC0, 0xEE, 0x6D, 0x2E, 0xCA, 0xBF, - 0x11, 0x98, 0xCE, 0xC9, 0x2E, 0x86, 0xA3, 0x61, - 0x6F, 0xBA, 0x4F, 0x4E, 0x87, 0x2F, 0x58, 0x25, - 0x33, 0x0A, 0xDB, 0xB4, 0xC1, 0xDE, 0xE4, 0x44 - }, - { - 0xA7, 0x80, 0x3B, 0xCB, 0x71, 0xBC, 0x1D, 0x0F, - 0x43, 0x83, 0xDD, 0xE1, 0xE0, 0x61, 0x2E, 0x04, - 0xF8, 0x72, 0xB7, 0x15, 0xAD, 0x30, 0x81, 0x5C, - 0x22, 0x49, 0xCF, 0x34, 0xAB, 0xB8, 0xB0, 0x24, - 0x91, 0x5C, 0xB2, 0xFC, 0x9F, 0x4E, 0x7C, 0xC4, - 0xC8, 0xCF, 0xD4, 0x5B, 0xE2, 0xD5, 0xA9, 0x1E, - 0xAB, 0x09, 0x41, 0xC7, 0xD2, 0x70, 0xE2, 0xDA, - 0x4C, 0xA4, 0xA9, 0xF7, 0xAC, 0x68, 0x66, 0x3A - }, - { - 0xB8, 0x4E, 0xF6, 0xA7, 0x22, 0x9A, 0x34, 0xA7, - 0x50, 0xD9, 0xA9, 0x8E, 0xE2, 0x52, 0x98, 0x71, - 0x81, 0x6B, 0x87, 0xFB, 0xE3, 0xBC, 0x45, 0xB4, - 0x5F, 0xA5, 0xAE, 0x82, 0xD5, 0x14, 0x15, 0x40, - 0x21, 0x11, 0x65, 0xC3, 0xC5, 0xD7, 0xA7, 0x47, - 0x6B, 0xA5, 0xA4, 0xAA, 0x06, 0xD6, 0x64, 0x76, - 0xF0, 0xD9, 0xDC, 0x49, 0xA3, 0xF1, 0xEE, 0x72, - 0xC3, 0xAC, 0xAB, 0xD4, 0x98, 0x96, 0x74, 0x14 - }, - { - 0xFA, 0xE4, 0xB6, 0xD8, 0xEF, 0xC3, 0xF8, 0xC8, - 0xE6, 0x4D, 0x00, 0x1D, 0xAB, 0xEC, 0x3A, 0x21, - 0xF5, 0x44, 0xE8, 0x27, 0x14, 0x74, 0x52, 0x51, - 0xB2, 0xB4, 0xB3, 0x93, 0xF2, 0xF4, 0x3E, 0x0D, - 0xA3, 0xD4, 0x03, 0xC6, 0x4D, 0xB9, 0x5A, 0x2C, - 0xB6, 0xE2, 0x3E, 0xBB, 0x7B, 0x9E, 0x94, 0xCD, - 0xD5, 0xDD, 0xAC, 0x54, 0xF0, 0x7C, 0x4A, 0x61, - 0xBD, 0x3C, 0xB1, 0x0A, 0xA6, 0xF9, 0x3B, 0x49 - }, - { - 0x34, 0xF7, 0x28, 0x66, 0x05, 0xA1, 0x22, 0x36, - 0x95, 0x40, 0x14, 0x1D, 0xED, 0x79, 0xB8, 0x95, - 0x72, 0x55, 0xDA, 0x2D, 0x41, 0x55, 0xAB, 0xBF, - 0x5A, 0x8D, 0xBB, 0x89, 0xC8, 0xEB, 0x7E, 0xDE, - 0x8E, 0xEE, 0xF1, 0xDA, 0xA4, 0x6D, 0xC2, 0x9D, - 0x75, 0x1D, 0x04, 0x5D, 0xC3, 0xB1, 0xD6, 0x58, - 0xBB, 0x64, 0xB8, 0x0F, 0xF8, 0x58, 0x9E, 0xDD, - 0xB3, 0x82, 0x4B, 0x13, 0xDA, 0x23, 0x5A, 0x6B - }, - { - 0x3B, 0x3B, 0x48, 0x43, 0x4B, 0xE2, 0x7B, 0x9E, - 0xAB, 0xAB, 0xBA, 0x43, 0xBF, 0x6B, 0x35, 0xF1, - 0x4B, 0x30, 0xF6, 0xA8, 0x8D, 0xC2, 0xE7, 0x50, - 0xC3, 0x58, 0x47, 0x0D, 0x6B, 0x3A, 0xA3, 0xC1, - 0x8E, 0x47, 0xDB, 0x40, 0x17, 0xFA, 0x55, 0x10, - 0x6D, 0x82, 0x52, 0xF0, 0x16, 0x37, 0x1A, 0x00, - 0xF5, 0xF8, 0xB0, 0x70, 0xB7, 0x4B, 0xA5, 0xF2, - 0x3C, 0xFF, 0xC5, 0x51, 0x1C, 0x9F, 0x09, 0xF0 - }, - { - 0xBA, 0x28, 0x9E, 0xBD, 0x65, 0x62, 0xC4, 0x8C, - 0x3E, 0x10, 0xA8, 0xAD, 0x6C, 0xE0, 0x2E, 0x73, - 0x43, 0x3D, 0x1E, 0x93, 0xD7, 0xC9, 0x27, 0x9D, - 0x4D, 0x60, 0xA7, 0xE8, 0x79, 0xEE, 0x11, 0xF4, - 0x41, 0xA0, 0x00, 0xF4, 0x8E, 0xD9, 0xF7, 0xC4, - 0xED, 0x87, 0xA4, 0x51, 0x36, 0xD7, 0xDC, 0xCD, - 0xCA, 0x48, 0x21, 0x09, 0xC7, 0x8A, 0x51, 0x06, - 0x2B, 0x3B, 0xA4, 0x04, 0x4A, 0xDA, 0x24, 0x69 - }, - { - 0x02, 0x29, 0x39, 0xE2, 0x38, 0x6C, 0x5A, 0x37, - 0x04, 0x98, 0x56, 0xC8, 0x50, 0xA2, 0xBB, 0x10, - 0xA1, 0x3D, 0xFE, 0xA4, 0x21, 0x2B, 0x4C, 0x73, - 0x2A, 0x88, 0x40, 0xA9, 0xFF, 0xA5, 0xFA, 0xF5, - 0x48, 0x75, 0xC5, 0x44, 0x88, 0x16, 0xB2, 0x78, - 0x5A, 0x00, 0x7D, 0xA8, 0xA8, 0xD2, 0xBC, 0x7D, - 0x71, 0xA5, 0x4E, 0x4E, 0x65, 0x71, 0xF1, 0x0B, - 0x60, 0x0C, 0xBD, 0xB2, 0x5D, 0x13, 0xED, 0xE3 - }, - { - 0xE6, 0xFE, 0xC1, 0x9D, 0x89, 0xCE, 0x87, 0x17, - 0xB1, 0xA0, 0x87, 0x02, 0x46, 0x70, 0xFE, 0x02, - 0x6F, 0x6C, 0x7C, 0xBD, 0xA1, 0x1C, 0xAE, 0xF9, - 0x59, 0xBB, 0x2D, 0x35, 0x1B, 0xF8, 0x56, 0xF8, - 0x05, 0x5D, 0x1C, 0x0E, 0xBD, 0xAA, 0xA9, 0xD1, - 0xB1, 0x78, 0x86, 0xFC, 0x2C, 0x56, 0x2B, 0x5E, - 0x99, 0x64, 0x2F, 0xC0, 0x64, 0x71, 0x0C, 0x0D, - 0x34, 0x88, 0xA0, 0x2B, 0x5E, 0xD7, 0xF6, 0xFD - }, - { - 0x94, 0xC9, 0x6F, 0x02, 0xA8, 0xF5, 0x76, 0xAC, - 0xA3, 0x2B, 0xA6, 0x1C, 0x2B, 0x20, 0x6F, 0x90, - 0x72, 0x85, 0xD9, 0x29, 0x9B, 0x83, 0xAC, 0x17, - 0x5C, 0x20, 0x9A, 0x8D, 0x43, 0xD5, 0x3B, 0xFE, - 0x68, 0x3D, 0xD1, 0xD8, 0x3E, 0x75, 0x49, 0xCB, - 0x90, 0x6C, 0x28, 0xF5, 0x9A, 0xB7, 0xC4, 0x6F, - 0x87, 0x51, 0x36, 0x6A, 0x28, 0xC3, 0x9D, 0xD5, - 0xFE, 0x26, 0x93, 0xC9, 0x01, 0x96, 0x66, 0xC8 - }, - { - 0x31, 0xA0, 0xCD, 0x21, 0x5E, 0xBD, 0x2C, 0xB6, - 0x1D, 0xE5, 0xB9, 0xED, 0xC9, 0x1E, 0x61, 0x95, - 0xE3, 0x1C, 0x59, 0xA5, 0x64, 0x8D, 0x5C, 0x9F, - 0x73, 0x7E, 0x12, 0x5B, 0x26, 0x05, 0x70, 0x8F, - 0x2E, 0x32, 0x5A, 0xB3, 0x38, 0x1C, 0x8D, 0xCE, - 0x1A, 0x3E, 0x95, 0x88, 0x86, 0xF1, 0xEC, 0xDC, - 0x60, 0x31, 0x8F, 0x88, 0x2C, 0xFE, 0x20, 0xA2, - 0x41, 0x91, 0x35, 0x2E, 0x61, 0x7B, 0x0F, 0x21 - }, - { - 0x91, 0xAB, 0x50, 0x4A, 0x52, 0x2D, 0xCE, 0x78, - 0x77, 0x9F, 0x4C, 0x6C, 0x6B, 0xA2, 0xE6, 0xB6, - 0xDB, 0x55, 0x65, 0xC7, 0x6D, 0x3E, 0x7E, 0x7C, - 0x92, 0x0C, 0xAF, 0x7F, 0x75, 0x7E, 0xF9, 0xDB, - 0x7C, 0x8F, 0xCF, 0x10, 0xE5, 0x7F, 0x03, 0x37, - 0x9E, 0xA9, 0xBF, 0x75, 0xEB, 0x59, 0x89, 0x5D, - 0x96, 0xE1, 0x49, 0x80, 0x0B, 0x6A, 0xAE, 0x01, - 0xDB, 0x77, 0x8B, 0xB9, 0x0A, 0xFB, 0xC9, 0x89 - }, - { - 0xD8, 0x5C, 0xAB, 0xC6, 0xBD, 0x5B, 0x1A, 0x01, - 0xA5, 0xAF, 0xD8, 0xC6, 0x73, 0x47, 0x40, 0xDA, - 0x9F, 0xD1, 0xC1, 0xAC, 0xC6, 0xDB, 0x29, 0xBF, - 0xC8, 0xA2, 0xE5, 0xB6, 0x68, 0xB0, 0x28, 0xB6, - 0xB3, 0x15, 0x4B, 0xFB, 0x87, 0x03, 0xFA, 0x31, - 0x80, 0x25, 0x1D, 0x58, 0x9A, 0xD3, 0x80, 0x40, - 0xCE, 0xB7, 0x07, 0xC4, 0xBA, 0xD1, 0xB5, 0x34, - 0x3C, 0xB4, 0x26, 0xB6, 0x1E, 0xAA, 0x49, 0xC1 - }, - { - 0xD6, 0x2E, 0xFB, 0xEC, 0x2C, 0xA9, 0xC1, 0xF8, - 0xBD, 0x66, 0xCE, 0x8B, 0x3F, 0x6A, 0x89, 0x8C, - 0xB3, 0xF7, 0x56, 0x6B, 0xA6, 0x56, 0x8C, 0x61, - 0x8A, 0xD1, 0xFE, 0xB2, 0xB6, 0x5B, 0x76, 0xC3, - 0xCE, 0x1D, 0xD2, 0x0F, 0x73, 0x95, 0x37, 0x2F, - 0xAF, 0x28, 0x42, 0x7F, 0x61, 0xC9, 0x27, 0x80, - 0x49, 0xCF, 0x01, 0x40, 0xDF, 0x43, 0x4F, 0x56, - 0x33, 0x04, 0x8C, 0x86, 0xB8, 0x1E, 0x03, 0x99 - }, - { - 0x7C, 0x8F, 0xDC, 0x61, 0x75, 0x43, 0x9E, 0x2C, - 0x3D, 0xB1, 0x5B, 0xAF, 0xA7, 0xFB, 0x06, 0x14, - 0x3A, 0x6A, 0x23, 0xBC, 0x90, 0xF4, 0x49, 0xE7, - 0x9D, 0xEE, 0xF7, 0x3C, 0x3D, 0x49, 0x2A, 0x67, - 0x17, 0x15, 0xC1, 0x93, 0xB6, 0xFE, 0xA9, 0xF0, - 0x36, 0x05, 0x0B, 0x94, 0x60, 0x69, 0x85, 0x6B, - 0x89, 0x7E, 0x08, 0xC0, 0x07, 0x68, 0xF5, 0xEE, - 0x5D, 0xDC, 0xF7, 0x0B, 0x7C, 0xD6, 0xD0, 0xE0 - }, - { - 0x58, 0x60, 0x2E, 0xE7, 0x46, 0x8E, 0x6B, 0xC9, - 0xDF, 0x21, 0xBD, 0x51, 0xB2, 0x3C, 0x00, 0x5F, - 0x72, 0xD6, 0xCB, 0x01, 0x3F, 0x0A, 0x1B, 0x48, - 0xCB, 0xEC, 0x5E, 0xCA, 0x29, 0x92, 0x99, 0xF9, - 0x7F, 0x09, 0xF5, 0x4A, 0x9A, 0x01, 0x48, 0x3E, - 0xAE, 0xB3, 0x15, 0xA6, 0x47, 0x8B, 0xAD, 0x37, - 0xBA, 0x47, 0xCA, 0x13, 0x47, 0xC7, 0xC8, 0xFC, - 0x9E, 0x66, 0x95, 0x59, 0x2C, 0x91, 0xD7, 0x23 - }, - { - 0x27, 0xF5, 0xB7, 0x9E, 0xD2, 0x56, 0xB0, 0x50, - 0x99, 0x3D, 0x79, 0x34, 0x96, 0xED, 0xF4, 0x80, - 0x7C, 0x1D, 0x85, 0xA7, 0xB0, 0xA6, 0x7C, 0x9C, - 0x4F, 0xA9, 0x98, 0x60, 0x75, 0x0B, 0x0A, 0xE6, - 0x69, 0x89, 0x67, 0x0A, 0x8F, 0xFD, 0x78, 0x56, - 0xD7, 0xCE, 0x41, 0x15, 0x99, 0xE5, 0x8C, 0x4D, - 0x77, 0xB2, 0x32, 0xA6, 0x2B, 0xEF, 0x64, 0xD1, - 0x52, 0x75, 0xBE, 0x46, 0xA6, 0x82, 0x35, 0xFF - }, - { - 0x39, 0x57, 0xA9, 0x76, 0xB9, 0xF1, 0x88, 0x7B, - 0xF0, 0x04, 0xA8, 0xDC, 0xA9, 0x42, 0xC9, 0x2D, - 0x2B, 0x37, 0xEA, 0x52, 0x60, 0x0F, 0x25, 0xE0, - 0xC9, 0xBC, 0x57, 0x07, 0xD0, 0x27, 0x9C, 0x00, - 0xC6, 0xE8, 0x5A, 0x83, 0x9B, 0x0D, 0x2D, 0x8E, - 0xB5, 0x9C, 0x51, 0xD9, 0x47, 0x88, 0xEB, 0xE6, - 0x24, 0x74, 0xA7, 0x91, 0xCA, 0xDF, 0x52, 0xCC, - 0xCF, 0x20, 0xF5, 0x07, 0x0B, 0x65, 0x73, 0xFC - }, - { - 0xEA, 0xA2, 0x37, 0x6D, 0x55, 0x38, 0x0B, 0xF7, - 0x72, 0xEC, 0xCA, 0x9C, 0xB0, 0xAA, 0x46, 0x68, - 0xC9, 0x5C, 0x70, 0x71, 0x62, 0xFA, 0x86, 0xD5, - 0x18, 0xC8, 0xCE, 0x0C, 0xA9, 0xBF, 0x73, 0x62, - 0xB9, 0xF2, 0xA0, 0xAD, 0xC3, 0xFF, 0x59, 0x92, - 0x2D, 0xF9, 0x21, 0xB9, 0x45, 0x67, 0xE8, 0x1E, - 0x45, 0x2F, 0x6C, 0x1A, 0x07, 0xFC, 0x81, 0x7C, - 0xEB, 0xE9, 0x96, 0x04, 0xB3, 0x50, 0x5D, 0x38 - }, - { - 0xC1, 0xE2, 0xC7, 0x8B, 0x6B, 0x27, 0x34, 0xE2, - 0x48, 0x0E, 0xC5, 0x50, 0x43, 0x4C, 0xB5, 0xD6, - 0x13, 0x11, 0x1A, 0xDC, 0xC2, 0x1D, 0x47, 0x55, - 0x45, 0xC3, 0xB1, 0xB7, 0xE6, 0xFF, 0x12, 0x44, - 0x44, 0x76, 0xE5, 0xC0, 0x55, 0x13, 0x2E, 0x22, - 0x29, 0xDC, 0x0F, 0x80, 0x70, 0x44, 0xBB, 0x91, - 0x9B, 0x1A, 0x56, 0x62, 0xDD, 0x38, 0xA9, 0xEE, - 0x65, 0xE2, 0x43, 0xA3, 0x91, 0x1A, 0xED, 0x1A - }, - { - 0x8A, 0xB4, 0x87, 0x13, 0x38, 0x9D, 0xD0, 0xFC, - 0xF9, 0xF9, 0x65, 0xD3, 0xCE, 0x66, 0xB1, 0xE5, - 0x59, 0xA1, 0xF8, 0xC5, 0x87, 0x41, 0xD6, 0x76, - 0x83, 0xCD, 0x97, 0x13, 0x54, 0xF4, 0x52, 0xE6, - 0x2D, 0x02, 0x07, 0xA6, 0x5E, 0x43, 0x6C, 0x5D, - 0x5D, 0x8F, 0x8E, 0xE7, 0x1C, 0x6A, 0xBF, 0xE5, - 0x0E, 0x66, 0x90, 0x04, 0xC3, 0x02, 0xB3, 0x1A, - 0x7E, 0xA8, 0x31, 0x1D, 0x4A, 0x91, 0x60, 0x51 - }, - { - 0x24, 0xCE, 0x0A, 0xDD, 0xAA, 0x4C, 0x65, 0x03, - 0x8B, 0xD1, 0xB1, 0xC0, 0xF1, 0x45, 0x2A, 0x0B, - 0x12, 0x87, 0x77, 0xAA, 0xBC, 0x94, 0xA2, 0x9D, - 0xF2, 0xFD, 0x6C, 0x7E, 0x2F, 0x85, 0xF8, 0xAB, - 0x9A, 0xC7, 0xEF, 0xF5, 0x16, 0xB0, 0xE0, 0xA8, - 0x25, 0xC8, 0x4A, 0x24, 0xCF, 0xE4, 0x92, 0xEA, - 0xAD, 0x0A, 0x63, 0x08, 0xE4, 0x6D, 0xD4, 0x2F, - 0xE8, 0x33, 0x3A, 0xB9, 0x71, 0xBB, 0x30, 0xCA - }, - { - 0x51, 0x54, 0xF9, 0x29, 0xEE, 0x03, 0x04, 0x5B, - 0x6B, 0x0C, 0x00, 0x04, 0xFA, 0x77, 0x8E, 0xDE, - 0xE1, 0xD1, 0x39, 0x89, 0x32, 0x67, 0xCC, 0x84, - 0x82, 0x5A, 0xD7, 0xB3, 0x6C, 0x63, 0xDE, 0x32, - 0x79, 0x8E, 0x4A, 0x16, 0x6D, 0x24, 0x68, 0x65, - 0x61, 0x35, 0x4F, 0x63, 0xB0, 0x07, 0x09, 0xA1, - 0x36, 0x4B, 0x3C, 0x24, 0x1D, 0xE3, 0xFE, 0xBF, - 0x07, 0x54, 0x04, 0x58, 0x97, 0x46, 0x7C, 0xD4 - }, - { - 0xE7, 0x4E, 0x90, 0x79, 0x20, 0xFD, 0x87, 0xBD, - 0x5A, 0xD6, 0x36, 0xDD, 0x11, 0x08, 0x5E, 0x50, - 0xEE, 0x70, 0x45, 0x9C, 0x44, 0x3E, 0x1C, 0xE5, - 0x80, 0x9A, 0xF2, 0xBC, 0x2E, 0xBA, 0x39, 0xF9, - 0xE6, 0xD7, 0x12, 0x8E, 0x0E, 0x37, 0x12, 0xC3, - 0x16, 0xDA, 0x06, 0xF4, 0x70, 0x5D, 0x78, 0xA4, - 0x83, 0x8E, 0x28, 0x12, 0x1D, 0x43, 0x44, 0xA2, - 0xC7, 0x9C, 0x5E, 0x0D, 0xB3, 0x07, 0xA6, 0x77 - }, - { - 0xBF, 0x91, 0xA2, 0x23, 0x34, 0xBA, 0xC2, 0x0F, - 0x3F, 0xD8, 0x06, 0x63, 0xB3, 0xCD, 0x06, 0xC4, - 0xE8, 0x80, 0x2F, 0x30, 0xE6, 0xB5, 0x9F, 0x90, - 0xD3, 0x03, 0x5C, 0xC9, 0x79, 0x8A, 0x21, 0x7E, - 0xD5, 0xA3, 0x1A, 0xBB, 0xDA, 0x7F, 0xA6, 0x84, - 0x28, 0x27, 0xBD, 0xF2, 0xA7, 0xA1, 0xC2, 0x1F, - 0x6F, 0xCF, 0xCC, 0xBB, 0x54, 0xC6, 0xC5, 0x29, - 0x26, 0xF3, 0x2D, 0xA8, 0x16, 0x26, 0x9B, 0xE1 - }, - { - 0xD9, 0xD5, 0xC7, 0x4B, 0xE5, 0x12, 0x1B, 0x0B, - 0xD7, 0x42, 0xF2, 0x6B, 0xFF, 0xB8, 0xC8, 0x9F, - 0x89, 0x17, 0x1F, 0x3F, 0x93, 0x49, 0x13, 0x49, - 0x2B, 0x09, 0x03, 0xC2, 0x71, 0xBB, 0xE2, 0xB3, - 0x39, 0x5E, 0xF2, 0x59, 0x66, 0x9B, 0xEF, 0x43, - 0xB5, 0x7F, 0x7F, 0xCC, 0x30, 0x27, 0xDB, 0x01, - 0x82, 0x3F, 0x6B, 0xAE, 0xE6, 0x6E, 0x4F, 0x9F, - 0xEA, 0xD4, 0xD6, 0x72, 0x6C, 0x74, 0x1F, 0xCE - }, - { - 0x50, 0xC8, 0xB8, 0xCF, 0x34, 0xCD, 0x87, 0x9F, - 0x80, 0xE2, 0xFA, 0xAB, 0x32, 0x30, 0xB0, 0xC0, - 0xE1, 0xCC, 0x3E, 0x9D, 0xCA, 0xDE, 0xB1, 0xB9, - 0xD9, 0x7A, 0xB9, 0x23, 0x41, 0x5D, 0xD9, 0xA1, - 0xFE, 0x38, 0xAD, 0xDD, 0x5C, 0x11, 0x75, 0x6C, - 0x67, 0x99, 0x0B, 0x25, 0x6E, 0x95, 0xAD, 0x6D, - 0x8F, 0x9F, 0xED, 0xCE, 0x10, 0xBF, 0x1C, 0x90, - 0x67, 0x9C, 0xDE, 0x0E, 0xCF, 0x1B, 0xE3, 0x47 - }, - { - 0x0A, 0x38, 0x6E, 0x7C, 0xD5, 0xDD, 0x9B, 0x77, - 0xA0, 0x35, 0xE0, 0x9F, 0xE6, 0xFE, 0xE2, 0xC8, - 0xCE, 0x61, 0xB5, 0x38, 0x3C, 0x87, 0xEA, 0x43, - 0x20, 0x50, 0x59, 0xC5, 0xE4, 0xCD, 0x4F, 0x44, - 0x08, 0x31, 0x9B, 0xB0, 0xA8, 0x23, 0x60, 0xF6, - 0xA5, 0x8E, 0x6C, 0x9C, 0xE3, 0xF4, 0x87, 0xC4, - 0x46, 0x06, 0x3B, 0xF8, 0x13, 0xBC, 0x6B, 0xA5, - 0x35, 0xE1, 0x7F, 0xC1, 0x82, 0x6C, 0xFC, 0x91 - }, - { - 0x1F, 0x14, 0x59, 0xCB, 0x6B, 0x61, 0xCB, 0xAC, - 0x5F, 0x0E, 0xFE, 0x8F, 0xC4, 0x87, 0x53, 0x8F, - 0x42, 0x54, 0x89, 0x87, 0xFC, 0xD5, 0x62, 0x21, - 0xCF, 0xA7, 0xBE, 0xB2, 0x25, 0x04, 0x76, 0x9E, - 0x79, 0x2C, 0x45, 0xAD, 0xFB, 0x1D, 0x6B, 0x3D, - 0x60, 0xD7, 0xB7, 0x49, 0xC8, 0xA7, 0x5B, 0x0B, - 0xDF, 0x14, 0xE8, 0xEA, 0x72, 0x1B, 0x95, 0xDC, - 0xA5, 0x38, 0xCA, 0x6E, 0x25, 0x71, 0x12, 0x09 - }, - { - 0xE5, 0x8B, 0x38, 0x36, 0xB7, 0xD8, 0xFE, 0xDB, - 0xB5, 0x0C, 0xA5, 0x72, 0x5C, 0x65, 0x71, 0xE7, - 0x4C, 0x07, 0x85, 0xE9, 0x78, 0x21, 0xDA, 0xB8, - 0xB6, 0x29, 0x8C, 0x10, 0xE4, 0xC0, 0x79, 0xD4, - 0xA6, 0xCD, 0xF2, 0x2F, 0x0F, 0xED, 0xB5, 0x50, - 0x32, 0x92, 0x5C, 0x16, 0x74, 0x81, 0x15, 0xF0, - 0x1A, 0x10, 0x5E, 0x77, 0xE0, 0x0C, 0xEE, 0x3D, - 0x07, 0x92, 0x4D, 0xC0, 0xD8, 0xF9, 0x06, 0x59 - }, - { - 0xB9, 0x29, 0xCC, 0x65, 0x05, 0xF0, 0x20, 0x15, - 0x86, 0x72, 0xDE, 0xDA, 0x56, 0xD0, 0xDB, 0x08, - 0x1A, 0x2E, 0xE3, 0x4C, 0x00, 0xC1, 0x10, 0x00, - 0x29, 0xBD, 0xF8, 0xEA, 0x98, 0x03, 0x4F, 0xA4, - 0xBF, 0x3E, 0x86, 0x55, 0xEC, 0x69, 0x7F, 0xE3, - 0x6F, 0x40, 0x55, 0x3C, 0x5B, 0xB4, 0x68, 0x01, - 0x64, 0x4A, 0x62, 0x7D, 0x33, 0x42, 0xF4, 0xFC, - 0x92, 0xB6, 0x1F, 0x03, 0x29, 0x0F, 0xB3, 0x81 - }, - { - 0x72, 0xD3, 0x53, 0x99, 0x4B, 0x49, 0xD3, 0xE0, - 0x31, 0x53, 0x92, 0x9A, 0x1E, 0x4D, 0x4F, 0x18, - 0x8E, 0xE5, 0x8A, 0xB9, 0xE7, 0x2E, 0xE8, 0xE5, - 0x12, 0xF2, 0x9B, 0xC7, 0x73, 0x91, 0x38, 0x19, - 0xCE, 0x05, 0x7D, 0xDD, 0x70, 0x02, 0xC0, 0x43, - 0x3E, 0xE0, 0xA1, 0x61, 0x14, 0xE3, 0xD1, 0x56, - 0xDD, 0x2C, 0x4A, 0x7E, 0x80, 0xEE, 0x53, 0x37, - 0x8B, 0x86, 0x70, 0xF2, 0x3E, 0x33, 0xEF, 0x56 - }, - { - 0xC7, 0x0E, 0xF9, 0xBF, 0xD7, 0x75, 0xD4, 0x08, - 0x17, 0x67, 0x37, 0xA0, 0x73, 0x6D, 0x68, 0x51, - 0x7C, 0xE1, 0xAA, 0xAD, 0x7E, 0x81, 0xA9, 0x3C, - 0x8C, 0x1E, 0xD9, 0x67, 0xEA, 0x21, 0x4F, 0x56, - 0xC8, 0xA3, 0x77, 0xB1, 0x76, 0x3E, 0x67, 0x66, - 0x15, 0xB6, 0x0F, 0x39, 0x88, 0x24, 0x1E, 0xAE, - 0x6E, 0xAB, 0x96, 0x85, 0xA5, 0x12, 0x49, 0x29, - 0xD2, 0x81, 0x88, 0xF2, 0x9E, 0xAB, 0x06, 0xF7 - }, - { - 0xC2, 0x30, 0xF0, 0x80, 0x26, 0x79, 0xCB, 0x33, - 0x82, 0x2E, 0xF8, 0xB3, 0xB2, 0x1B, 0xF7, 0xA9, - 0xA2, 0x89, 0x42, 0x09, 0x29, 0x01, 0xD7, 0xDA, - 0xC3, 0x76, 0x03, 0x00, 0x83, 0x10, 0x26, 0xCF, - 0x35, 0x4C, 0x92, 0x32, 0xDF, 0x3E, 0x08, 0x4D, - 0x99, 0x03, 0x13, 0x0C, 0x60, 0x1F, 0x63, 0xC1, - 0xF4, 0xA4, 0xA4, 0xB8, 0x10, 0x6E, 0x46, 0x8C, - 0xD4, 0x43, 0xBB, 0xE5, 0xA7, 0x34, 0xF4, 0x5F - }, - { - 0x6F, 0x43, 0x09, 0x4C, 0xAF, 0xB5, 0xEB, 0xF1, - 0xF7, 0xA4, 0x93, 0x7E, 0xC5, 0x0F, 0x56, 0xA4, - 0xC9, 0xDA, 0x30, 0x3C, 0xBB, 0x55, 0xAC, 0x1F, - 0x27, 0xF1, 0xF1, 0x97, 0x6C, 0xD9, 0x6B, 0xED, - 0xA9, 0x46, 0x4F, 0x0E, 0x7B, 0x9C, 0x54, 0x62, - 0x0B, 0x8A, 0x9F, 0xBA, 0x98, 0x31, 0x64, 0xB8, - 0xBE, 0x35, 0x78, 0x42, 0x5A, 0x02, 0x4F, 0x5F, - 0xE1, 0x99, 0xC3, 0x63, 0x56, 0xB8, 0x89, 0x72 - }, - { - 0x37, 0x45, 0x27, 0x3F, 0x4C, 0x38, 0x22, 0x5D, - 0xB2, 0x33, 0x73, 0x81, 0x87, 0x1A, 0x0C, 0x6A, - 0xAF, 0xD3, 0xAF, 0x9B, 0x01, 0x8C, 0x88, 0xAA, - 0x02, 0x02, 0x58, 0x50, 0xA5, 0xDC, 0x3A, 0x42, - 0xA1, 0xA3, 0xE0, 0x3E, 0x56, 0xCB, 0xF1, 0xB0, - 0x87, 0x6D, 0x63, 0xA4, 0x41, 0xF1, 0xD2, 0x85, - 0x6A, 0x39, 0xB8, 0x80, 0x1E, 0xB5, 0xAF, 0x32, - 0x52, 0x01, 0xC4, 0x15, 0xD6, 0x5E, 0x97, 0xFE - }, - { - 0xC5, 0x0C, 0x44, 0xCC, 0xA3, 0xEC, 0x3E, 0xDA, - 0xAE, 0x77, 0x9A, 0x7E, 0x17, 0x94, 0x50, 0xEB, - 0xDD, 0xA2, 0xF9, 0x70, 0x67, 0xC6, 0x90, 0xAA, - 0x6C, 0x5A, 0x4A, 0xC7, 0xC3, 0x01, 0x39, 0xBB, - 0x27, 0xC0, 0xDF, 0x4D, 0xB3, 0x22, 0x0E, 0x63, - 0xCB, 0x11, 0x0D, 0x64, 0xF3, 0x7F, 0xFE, 0x07, - 0x8D, 0xB7, 0x26, 0x53, 0xE2, 0xDA, 0xAC, 0xF9, - 0x3A, 0xE3, 0xF0, 0xA2, 0xD1, 0xA7, 0xEB, 0x2E - }, - { - 0x8A, 0xEF, 0x26, 0x3E, 0x38, 0x5C, 0xBC, 0x61, - 0xE1, 0x9B, 0x28, 0x91, 0x42, 0x43, 0x26, 0x2A, - 0xF5, 0xAF, 0xE8, 0x72, 0x6A, 0xF3, 0xCE, 0x39, - 0xA7, 0x9C, 0x27, 0x02, 0x8C, 0xF3, 0xEC, 0xD3, - 0xF8, 0xD2, 0xDF, 0xD9, 0xCF, 0xC9, 0xAD, 0x91, - 0xB5, 0x8F, 0x6F, 0x20, 0x77, 0x8F, 0xD5, 0xF0, - 0x28, 0x94, 0xA3, 0xD9, 0x1C, 0x7D, 0x57, 0xD1, - 0xE4, 0xB8, 0x66, 0xA7, 0xF3, 0x64, 0xB6, 0xBE - }, - { - 0x28, 0x69, 0x61, 0x41, 0xDE, 0x6E, 0x2D, 0x9B, - 0xCB, 0x32, 0x35, 0x57, 0x8A, 0x66, 0x16, 0x6C, - 0x14, 0x48, 0xD3, 0xE9, 0x05, 0xA1, 0xB4, 0x82, - 0xD4, 0x23, 0xBE, 0x4B, 0xC5, 0x36, 0x9B, 0xC8, - 0xC7, 0x4D, 0xAE, 0x0A, 0xCC, 0x9C, 0xC1, 0x23, - 0xE1, 0xD8, 0xDD, 0xCE, 0x9F, 0x97, 0x91, 0x7E, - 0x8C, 0x01, 0x9C, 0x55, 0x2D, 0xA3, 0x2D, 0x39, - 0xD2, 0x21, 0x9B, 0x9A, 0xBF, 0x0F, 0xA8, 0xC8 - }, - { - 0x2F, 0xB9, 0xEB, 0x20, 0x85, 0x83, 0x01, 0x81, - 0x90, 0x3A, 0x9D, 0xAF, 0xE3, 0xDB, 0x42, 0x8E, - 0xE1, 0x5B, 0xE7, 0x66, 0x22, 0x24, 0xEF, 0xD6, - 0x43, 0x37, 0x1F, 0xB2, 0x56, 0x46, 0xAE, 0xE7, - 0x16, 0xE5, 0x31, 0xEC, 0xA6, 0x9B, 0x2B, 0xDC, - 0x82, 0x33, 0xF1, 0xA8, 0x08, 0x1F, 0xA4, 0x3D, - 0xA1, 0x50, 0x03, 0x02, 0x97, 0x5A, 0x77, 0xF4, - 0x2F, 0xA5, 0x92, 0x13, 0x67, 0x10, 0xE9, 0xDC - }, - { - 0x66, 0xF9, 0xA7, 0x14, 0x3F, 0x7A, 0x33, 0x14, - 0xA6, 0x69, 0xBF, 0x2E, 0x24, 0xBB, 0xB3, 0x50, - 0x14, 0x26, 0x1D, 0x63, 0x9F, 0x49, 0x5B, 0x6C, - 0x9C, 0x1F, 0x10, 0x4F, 0xE8, 0xE3, 0x20, 0xAC, - 0xA6, 0x0D, 0x45, 0x50, 0xD6, 0x9D, 0x52, 0xED, - 0xBD, 0x5A, 0x3C, 0xDE, 0xB4, 0x01, 0x4A, 0xE6, - 0x5B, 0x1D, 0x87, 0xAA, 0x77, 0x0B, 0x69, 0xAE, - 0x5C, 0x15, 0xF4, 0x33, 0x0B, 0x0B, 0x0A, 0xD8 - }, - { - 0xF4, 0xC4, 0xDD, 0x1D, 0x59, 0x4C, 0x35, 0x65, - 0xE3, 0xE2, 0x5C, 0xA4, 0x3D, 0xAD, 0x82, 0xF6, - 0x2A, 0xBE, 0xA4, 0x83, 0x5E, 0xD4, 0xCD, 0x81, - 0x1B, 0xCD, 0x97, 0x5E, 0x46, 0x27, 0x98, 0x28, - 0xD4, 0x4D, 0x4C, 0x62, 0xC3, 0x67, 0x9F, 0x1B, - 0x7F, 0x7B, 0x9D, 0xD4, 0x57, 0x1D, 0x7B, 0x49, - 0x55, 0x73, 0x47, 0xB8, 0xC5, 0x46, 0x0C, 0xBD, - 0xC1, 0xBE, 0xF6, 0x90, 0xFB, 0x2A, 0x08, 0xC0 - }, - { - 0x8F, 0x1D, 0xC9, 0x64, 0x9C, 0x3A, 0x84, 0x55, - 0x1F, 0x8F, 0x6E, 0x91, 0xCA, 0xC6, 0x82, 0x42, - 0xA4, 0x3B, 0x1F, 0x8F, 0x32, 0x8E, 0xE9, 0x22, - 0x80, 0x25, 0x73, 0x87, 0xFA, 0x75, 0x59, 0xAA, - 0x6D, 0xB1, 0x2E, 0x4A, 0xEA, 0xDC, 0x2D, 0x26, - 0x09, 0x91, 0x78, 0x74, 0x9C, 0x68, 0x64, 0xB3, - 0x57, 0xF3, 0xF8, 0x3B, 0x2F, 0xB3, 0xEF, 0xA8, - 0xD2, 0xA8, 0xDB, 0x05, 0x6B, 0xED, 0x6B, 0xCC - }, - { - 0x31, 0x39, 0xC1, 0xA7, 0xF9, 0x7A, 0xFD, 0x16, - 0x75, 0xD4, 0x60, 0xEB, 0xBC, 0x07, 0xF2, 0x72, - 0x8A, 0xA1, 0x50, 0xDF, 0x84, 0x96, 0x24, 0x51, - 0x1E, 0xE0, 0x4B, 0x74, 0x3B, 0xA0, 0xA8, 0x33, - 0x09, 0x2F, 0x18, 0xC1, 0x2D, 0xC9, 0x1B, 0x4D, - 0xD2, 0x43, 0xF3, 0x33, 0x40, 0x2F, 0x59, 0xFE, - 0x28, 0xAB, 0xDB, 0xBB, 0xAE, 0x30, 0x1E, 0x7B, - 0x65, 0x9C, 0x7A, 0x26, 0xD5, 0xC0, 0xF9, 0x79 - }, - { - 0x06, 0xF9, 0x4A, 0x29, 0x96, 0x15, 0x8A, 0x81, - 0x9F, 0xE3, 0x4C, 0x40, 0xDE, 0x3C, 0xF0, 0x37, - 0x9F, 0xD9, 0xFB, 0x85, 0xB3, 0xE3, 0x63, 0xBA, - 0x39, 0x26, 0xA0, 0xE7, 0xD9, 0x60, 0xE3, 0xF4, - 0xC2, 0xE0, 0xC7, 0x0C, 0x7C, 0xE0, 0xCC, 0xB2, - 0xA6, 0x4F, 0xC2, 0x98, 0x69, 0xF6, 0xE7, 0xAB, - 0x12, 0xBD, 0x4D, 0x3F, 0x14, 0xFC, 0xE9, 0x43, - 0x27, 0x90, 0x27, 0xE7, 0x85, 0xFB, 0x5C, 0x29 - }, - { - 0xC2, 0x9C, 0x39, 0x9E, 0xF3, 0xEE, 0xE8, 0x96, - 0x1E, 0x87, 0x56, 0x5C, 0x1C, 0xE2, 0x63, 0x92, - 0x5F, 0xC3, 0xD0, 0xCE, 0x26, 0x7D, 0x13, 0xE4, - 0x8D, 0xD9, 0xE7, 0x32, 0xEE, 0x67, 0xB0, 0xF6, - 0x9F, 0xAD, 0x56, 0x40, 0x1B, 0x0F, 0x10, 0xFC, - 0xAA, 0xC1, 0x19, 0x20, 0x10, 0x46, 0xCC, 0xA2, - 0x8C, 0x5B, 0x14, 0xAB, 0xDE, 0xA3, 0x21, 0x2A, - 0xE6, 0x55, 0x62, 0xF7, 0xF1, 0x38, 0xDB, 0x3D - }, - { - 0x4C, 0xEC, 0x4C, 0x9D, 0xF5, 0x2E, 0xEF, 0x05, - 0xC3, 0xF6, 0xFA, 0xAA, 0x97, 0x91, 0xBC, 0x74, - 0x45, 0x93, 0x71, 0x83, 0x22, 0x4E, 0xCC, 0x37, - 0xA1, 0xE5, 0x8D, 0x01, 0x32, 0xD3, 0x56, 0x17, - 0x53, 0x1D, 0x7E, 0x79, 0x5F, 0x52, 0xAF, 0x7B, - 0x1E, 0xB9, 0xD1, 0x47, 0xDE, 0x12, 0x92, 0xD3, - 0x45, 0xFE, 0x34, 0x18, 0x23, 0xF8, 0xE6, 0xBC, - 0x1E, 0x5B, 0xAD, 0xCA, 0x5C, 0x65, 0x61, 0x08 - }, - { - 0x89, 0x8B, 0xFB, 0xAE, 0x93, 0xB3, 0xE1, 0x8D, - 0x00, 0x69, 0x7E, 0xAB, 0x7D, 0x97, 0x04, 0xFA, - 0x36, 0xEC, 0x33, 0x9D, 0x07, 0x61, 0x31, 0xCE, - 0xFD, 0xF3, 0x0E, 0xDB, 0xE8, 0xD9, 0xCC, 0x81, - 0xC3, 0xA8, 0x0B, 0x12, 0x96, 0x59, 0xB1, 0x63, - 0xA3, 0x23, 0xBA, 0xB9, 0x79, 0x3D, 0x4F, 0xEE, - 0xD9, 0x2D, 0x54, 0xDA, 0xE9, 0x66, 0xC7, 0x75, - 0x29, 0x76, 0x4A, 0x09, 0xBE, 0x88, 0xDB, 0x45 - }, - { - 0xEE, 0x9B, 0xD0, 0x46, 0x9D, 0x3A, 0xAF, 0x4F, - 0x14, 0x03, 0x5B, 0xE4, 0x8A, 0x2C, 0x3B, 0x84, - 0xD9, 0xB4, 0xB1, 0xFF, 0xF1, 0xD9, 0x45, 0xE1, - 0xF1, 0xC1, 0xD3, 0x89, 0x80, 0xA9, 0x51, 0xBE, - 0x19, 0x7B, 0x25, 0xFE, 0x22, 0xC7, 0x31, 0xF2, - 0x0A, 0xEA, 0xCC, 0x93, 0x0B, 0xA9, 0xC4, 0xA1, - 0xF4, 0x76, 0x22, 0x27, 0x61, 0x7A, 0xD3, 0x50, - 0xFD, 0xAB, 0xB4, 0xE8, 0x02, 0x73, 0xA0, 0xF4 - }, - { - 0x3D, 0x4D, 0x31, 0x13, 0x30, 0x05, 0x81, 0xCD, - 0x96, 0xAC, 0xBF, 0x09, 0x1C, 0x3D, 0x0F, 0x3C, - 0x31, 0x01, 0x38, 0xCD, 0x69, 0x79, 0xE6, 0x02, - 0x6C, 0xDE, 0x62, 0x3E, 0x2D, 0xD1, 0xB2, 0x4D, - 0x4A, 0x86, 0x38, 0xBE, 0xD1, 0x07, 0x33, 0x44, - 0x78, 0x3A, 0xD0, 0x64, 0x9C, 0xC6, 0x30, 0x5C, - 0xCE, 0xC0, 0x4B, 0xEB, 0x49, 0xF3, 0x1C, 0x63, - 0x30, 0x88, 0xA9, 0x9B, 0x65, 0x13, 0x02, 0x67 - }, - { - 0x95, 0xC0, 0x59, 0x1A, 0xD9, 0x1F, 0x92, 0x1A, - 0xC7, 0xBE, 0x6D, 0x9C, 0xE3, 0x7E, 0x06, 0x63, - 0xED, 0x80, 0x11, 0xC1, 0xCF, 0xD6, 0xD0, 0x16, - 0x2A, 0x55, 0x72, 0xE9, 0x43, 0x68, 0xBA, 0xC0, - 0x20, 0x24, 0x48, 0x5E, 0x6A, 0x39, 0x85, 0x4A, - 0xA4, 0x6F, 0xE3, 0x8E, 0x97, 0xD6, 0xC6, 0xB1, - 0x94, 0x7C, 0xD2, 0x72, 0xD8, 0x6B, 0x06, 0xBB, - 0x5B, 0x2F, 0x78, 0xB9, 0xB6, 0x8D, 0x55, 0x9D - }, - { - 0x22, 0x7B, 0x79, 0xDE, 0xD3, 0x68, 0x15, 0x3B, - 0xF4, 0x6C, 0x0A, 0x3C, 0xA9, 0x78, 0xBF, 0xDB, - 0xEF, 0x31, 0xF3, 0x02, 0x4A, 0x56, 0x65, 0x84, - 0x24, 0x68, 0x49, 0x0B, 0x0F, 0xF7, 0x48, 0xAE, - 0x04, 0xE7, 0x83, 0x2E, 0xD4, 0xC9, 0xF4, 0x9D, - 0xE9, 0xB1, 0x70, 0x67, 0x09, 0xD6, 0x23, 0xE5, - 0xC8, 0xC1, 0x5E, 0x3C, 0xAE, 0xCA, 0xE8, 0xD5, - 0xE4, 0x33, 0x43, 0x0F, 0xF7, 0x2F, 0x20, 0xEB - }, - { - 0x5D, 0x34, 0xF3, 0x95, 0x2F, 0x01, 0x05, 0xEE, - 0xF8, 0x8A, 0xE8, 0xB6, 0x4C, 0x6C, 0xE9, 0x5E, - 0xBF, 0xAD, 0xE0, 0xE0, 0x2C, 0x69, 0xB0, 0x87, - 0x62, 0xA8, 0x71, 0x2D, 0x2E, 0x49, 0x11, 0xAD, - 0x3F, 0x94, 0x1F, 0xC4, 0x03, 0x4D, 0xC9, 0xB2, - 0xE4, 0x79, 0xFD, 0xBC, 0xD2, 0x79, 0xB9, 0x02, - 0xFA, 0xF5, 0xD8, 0x38, 0xBB, 0x2E, 0x0C, 0x64, - 0x95, 0xD3, 0x72, 0xB5, 0xB7, 0x02, 0x98, 0x13 - }, - { - 0x7F, 0x93, 0x9B, 0xF8, 0x35, 0x3A, 0xBC, 0xE4, - 0x9E, 0x77, 0xF1, 0x4F, 0x37, 0x50, 0xAF, 0x20, - 0xB7, 0xB0, 0x39, 0x02, 0xE1, 0xA1, 0xE7, 0xFB, - 0x6A, 0xAF, 0x76, 0xD0, 0x25, 0x9C, 0xD4, 0x01, - 0xA8, 0x31, 0x90, 0xF1, 0x56, 0x40, 0xE7, 0x4F, - 0x3E, 0x6C, 0x5A, 0x90, 0xE8, 0x39, 0xC7, 0x82, - 0x1F, 0x64, 0x74, 0x75, 0x7F, 0x75, 0xC7, 0xBF, - 0x90, 0x02, 0x08, 0x4D, 0xDC, 0x7A, 0x62, 0xDC - }, - { - 0x06, 0x2B, 0x61, 0xA2, 0xF9, 0xA3, 0x3A, 0x71, - 0xD7, 0xD0, 0xA0, 0x61, 0x19, 0x64, 0x4C, 0x70, - 0xB0, 0x71, 0x6A, 0x50, 0x4D, 0xE7, 0xE5, 0xE1, - 0xBE, 0x49, 0xBD, 0x7B, 0x86, 0xE7, 0xED, 0x68, - 0x17, 0x71, 0x4F, 0x9F, 0x0F, 0xC3, 0x13, 0xD0, - 0x61, 0x29, 0x59, 0x7E, 0x9A, 0x22, 0x35, 0xEC, - 0x85, 0x21, 0xDE, 0x36, 0xF7, 0x29, 0x0A, 0x90, - 0xCC, 0xFC, 0x1F, 0xFA, 0x6D, 0x0A, 0xEE, 0x29 - }, - { - 0xF2, 0x9E, 0x01, 0xEE, 0xAE, 0x64, 0x31, 0x1E, - 0xB7, 0xF1, 0xC6, 0x42, 0x2F, 0x94, 0x6B, 0xF7, - 0xBE, 0xA3, 0x63, 0x79, 0x52, 0x3E, 0x7B, 0x2B, - 0xBA, 0xBA, 0x7D, 0x1D, 0x34, 0xA2, 0x2D, 0x5E, - 0xA5, 0xF1, 0xC5, 0xA0, 0x9D, 0x5C, 0xE1, 0xFE, - 0x68, 0x2C, 0xCE, 0xD9, 0xA4, 0x79, 0x8D, 0x1A, - 0x05, 0xB4, 0x6C, 0xD7, 0x2D, 0xFF, 0x5C, 0x1B, - 0x35, 0x54, 0x40, 0xB2, 0xA2, 0xD4, 0x76, 0xBC - }, - { - 0xEC, 0x38, 0xCD, 0x3B, 0xBA, 0xB3, 0xEF, 0x35, - 0xD7, 0xCB, 0x6D, 0x5C, 0x91, 0x42, 0x98, 0x35, - 0x1D, 0x8A, 0x9D, 0xC9, 0x7F, 0xCE, 0xE0, 0x51, - 0xA8, 0xA0, 0x2F, 0x58, 0xE3, 0xED, 0x61, 0x84, - 0xD0, 0xB7, 0x81, 0x0A, 0x56, 0x15, 0x41, 0x1A, - 0xB1, 0xB9, 0x52, 0x09, 0xC3, 0xC8, 0x10, 0x11, - 0x4F, 0xDE, 0xB2, 0x24, 0x52, 0x08, 0x4E, 0x77, - 0xF3, 0xF8, 0x47, 0xC6, 0xDB, 0xAA, 0xFE, 0x16 - }, - { - 0xC2, 0xAE, 0xF5, 0xE0, 0xCA, 0x43, 0xE8, 0x26, - 0x41, 0x56, 0x5B, 0x8C, 0xB9, 0x43, 0xAA, 0x8B, - 0xA5, 0x35, 0x50, 0xCA, 0xEF, 0x79, 0x3B, 0x65, - 0x32, 0xFA, 0xFA, 0xD9, 0x4B, 0x81, 0x60, 0x82, - 0xF0, 0x11, 0x3A, 0x3E, 0xA2, 0xF6, 0x36, 0x08, - 0xAB, 0x40, 0x43, 0x7E, 0xCC, 0x0F, 0x02, 0x29, - 0xCB, 0x8F, 0xA2, 0x24, 0xDC, 0xF1, 0xC4, 0x78, - 0xA6, 0x7D, 0x9B, 0x64, 0x16, 0x2B, 0x92, 0xD1 - }, - { - 0x15, 0xF5, 0x34, 0xEF, 0xFF, 0x71, 0x05, 0xCD, - 0x1C, 0x25, 0x4D, 0x07, 0x4E, 0x27, 0xD5, 0x89, - 0x8B, 0x89, 0x31, 0x3B, 0x7D, 0x36, 0x6D, 0xC2, - 0xD7, 0xD8, 0x71, 0x13, 0xFA, 0x7D, 0x53, 0xAA, - 0xE1, 0x3F, 0x6D, 0xBA, 0x48, 0x7A, 0xD8, 0x10, - 0x3D, 0x5E, 0x85, 0x4C, 0x91, 0xFD, 0xB6, 0xE1, - 0xE7, 0x4B, 0x2E, 0xF6, 0xD1, 0x43, 0x17, 0x69, - 0xC3, 0x07, 0x67, 0xDD, 0xE0, 0x67, 0xA3, 0x5C - }, - { - 0x89, 0xAC, 0xBC, 0xA0, 0xB1, 0x69, 0x89, 0x7A, - 0x0A, 0x27, 0x14, 0xC2, 0xDF, 0x8C, 0x95, 0xB5, - 0xB7, 0x9C, 0xB6, 0x93, 0x90, 0x14, 0x2B, 0x7D, - 0x60, 0x18, 0xBB, 0x3E, 0x30, 0x76, 0xB0, 0x99, - 0xB7, 0x9A, 0x96, 0x41, 0x52, 0xA9, 0xD9, 0x12, - 0xB1, 0xB8, 0x64, 0x12, 0xB7, 0xE3, 0x72, 0xE9, - 0xCE, 0xCA, 0xD7, 0xF2, 0x5D, 0x4C, 0xBA, 0xB8, - 0xA3, 0x17, 0xBE, 0x36, 0x49, 0x2A, 0x67, 0xD7 - }, - { - 0xE3, 0xC0, 0x73, 0x91, 0x90, 0xED, 0x84, 0x9C, - 0x9C, 0x96, 0x2F, 0xD9, 0xDB, 0xB5, 0x5E, 0x20, - 0x7E, 0x62, 0x4F, 0xCA, 0xC1, 0xEB, 0x41, 0x76, - 0x91, 0x51, 0x54, 0x99, 0xEE, 0xA8, 0xD8, 0x26, - 0x7B, 0x7E, 0x8F, 0x12, 0x87, 0xA6, 0x36, 0x33, - 0xAF, 0x50, 0x11, 0xFD, 0xE8, 0xC4, 0xDD, 0xF5, - 0x5B, 0xFD, 0xF7, 0x22, 0xED, 0xF8, 0x88, 0x31, - 0x41, 0x4F, 0x2C, 0xFA, 0xED, 0x59, 0xCB, 0x9A - }, - { - 0x8D, 0x6C, 0xF8, 0x7C, 0x08, 0x38, 0x0D, 0x2D, - 0x15, 0x06, 0xEE, 0xE4, 0x6F, 0xD4, 0x22, 0x2D, - 0x21, 0xD8, 0xC0, 0x4E, 0x58, 0x5F, 0xBF, 0xD0, - 0x82, 0x69, 0xC9, 0x8F, 0x70, 0x28, 0x33, 0xA1, - 0x56, 0x32, 0x6A, 0x07, 0x24, 0x65, 0x64, 0x00, - 0xEE, 0x09, 0x35, 0x1D, 0x57, 0xB4, 0x40, 0x17, - 0x5E, 0x2A, 0x5D, 0xE9, 0x3C, 0xC5, 0xF8, 0x0D, - 0xB6, 0xDA, 0xF8, 0x35, 0x76, 0xCF, 0x75, 0xFA - }, - { - 0xDA, 0x24, 0xBE, 0xDE, 0x38, 0x36, 0x66, 0xD5, - 0x63, 0xEE, 0xED, 0x37, 0xF6, 0x31, 0x9B, 0xAF, - 0x20, 0xD5, 0xC7, 0x5D, 0x16, 0x35, 0xA6, 0xBA, - 0x5E, 0xF4, 0xCF, 0xA1, 0xAC, 0x95, 0x48, 0x7E, - 0x96, 0xF8, 0xC0, 0x8A, 0xF6, 0x00, 0xAA, 0xB8, - 0x7C, 0x98, 0x6E, 0xBA, 0xD4, 0x9F, 0xC7, 0x0A, - 0x58, 0xB4, 0x89, 0x0B, 0x9C, 0x87, 0x6E, 0x09, - 0x10, 0x16, 0xDA, 0xF4, 0x9E, 0x1D, 0x32, 0x2E - }, - { - 0xF9, 0xD1, 0xD1, 0xB1, 0xE8, 0x7E, 0xA7, 0xAE, - 0x75, 0x3A, 0x02, 0x97, 0x50, 0xCC, 0x1C, 0xF3, - 0xD0, 0x15, 0x7D, 0x41, 0x80, 0x5E, 0x24, 0x5C, - 0x56, 0x17, 0xBB, 0x93, 0x4E, 0x73, 0x2F, 0x0A, - 0xE3, 0x18, 0x0B, 0x78, 0xE0, 0x5B, 0xFE, 0x76, - 0xC7, 0xC3, 0x05, 0x1E, 0x3E, 0x3A, 0xC7, 0x8B, - 0x9B, 0x50, 0xC0, 0x51, 0x42, 0x65, 0x7E, 0x1E, - 0x03, 0x21, 0x5D, 0x6E, 0xC7, 0xBF, 0xD0, 0xFC - }, - { - 0x11, 0xB7, 0xBC, 0x16, 0x68, 0x03, 0x20, 0x48, - 0xAA, 0x43, 0x34, 0x3D, 0xE4, 0x76, 0x39, 0x5E, - 0x81, 0x4B, 0xBB, 0xC2, 0x23, 0x67, 0x8D, 0xB9, - 0x51, 0xA1, 0xB0, 0x3A, 0x02, 0x1E, 0xFA, 0xC9, - 0x48, 0xCF, 0xBE, 0x21, 0x5F, 0x97, 0xFE, 0x9A, - 0x72, 0xA2, 0xF6, 0xBC, 0x03, 0x9E, 0x39, 0x56, - 0xBF, 0xA4, 0x17, 0xC1, 0xA9, 0xF1, 0x0D, 0x6D, - 0x7B, 0xA5, 0xD3, 0xD3, 0x2F, 0xF3, 0x23, 0xE5 - }, - { - 0xB8, 0xD9, 0x00, 0x0E, 0x4F, 0xC2, 0xB0, 0x66, - 0xED, 0xB9, 0x1A, 0xFE, 0xE8, 0xE7, 0xEB, 0x0F, - 0x24, 0xE3, 0xA2, 0x01, 0xDB, 0x8B, 0x67, 0x93, - 0xC0, 0x60, 0x85, 0x81, 0xE6, 0x28, 0xED, 0x0B, - 0xCC, 0x4E, 0x5A, 0xA6, 0x78, 0x79, 0x92, 0xA4, - 0xBC, 0xC4, 0x4E, 0x28, 0x80, 0x93, 0xE6, 0x3E, - 0xE8, 0x3A, 0xBD, 0x0B, 0xC3, 0xEC, 0x6D, 0x09, - 0x34, 0xA6, 0x74, 0xA4, 0xDA, 0x13, 0x83, 0x8A - }, - { - 0xCE, 0x32, 0x5E, 0x29, 0x4F, 0x9B, 0x67, 0x19, - 0xD6, 0xB6, 0x12, 0x78, 0x27, 0x6A, 0xE0, 0x6A, - 0x25, 0x64, 0xC0, 0x3B, 0xB0, 0xB7, 0x83, 0xFA, - 0xFE, 0x78, 0x5B, 0xDF, 0x89, 0xC7, 0xD5, 0xAC, - 0xD8, 0x3E, 0x78, 0x75, 0x6D, 0x30, 0x1B, 0x44, - 0x56, 0x99, 0x02, 0x4E, 0xAE, 0xB7, 0x7B, 0x54, - 0xD4, 0x77, 0x33, 0x6E, 0xC2, 0xA4, 0xF3, 0x32, - 0xF2, 0xB3, 0xF8, 0x87, 0x65, 0xDD, 0xB0, 0xC3 - }, - { - 0x29, 0xAC, 0xC3, 0x0E, 0x96, 0x03, 0xAE, 0x2F, - 0xCC, 0xF9, 0x0B, 0xF9, 0x7E, 0x6C, 0xC4, 0x63, - 0xEB, 0xE2, 0x8C, 0x1B, 0x2F, 0x9B, 0x4B, 0x76, - 0x5E, 0x70, 0x53, 0x7C, 0x25, 0xC7, 0x02, 0xA2, - 0x9D, 0xCB, 0xFB, 0xF1, 0x4C, 0x99, 0xC5, 0x43, - 0x45, 0xBA, 0x2B, 0x51, 0xF1, 0x7B, 0x77, 0xB5, - 0xF1, 0x5D, 0xB9, 0x2B, 0xBA, 0xD8, 0xFA, 0x95, - 0xC4, 0x71, 0xF5, 0xD0, 0x70, 0xA1, 0x37, 0xCC - }, - { - 0x33, 0x79, 0xCB, 0xAA, 0xE5, 0x62, 0xA8, 0x7B, - 0x4C, 0x04, 0x25, 0x55, 0x0F, 0xFD, 0xD6, 0xBF, - 0xE1, 0x20, 0x3F, 0x0D, 0x66, 0x6C, 0xC7, 0xEA, - 0x09, 0x5B, 0xE4, 0x07, 0xA5, 0xDF, 0xE6, 0x1E, - 0xE9, 0x14, 0x41, 0xCD, 0x51, 0x54, 0xB3, 0xE5, - 0x3B, 0x4F, 0x5F, 0xB3, 0x1A, 0xD4, 0xC7, 0xA9, - 0xAD, 0x5C, 0x7A, 0xF4, 0xAE, 0x67, 0x9A, 0xA5, - 0x1A, 0x54, 0x00, 0x3A, 0x54, 0xCA, 0x6B, 0x2D - }, - { - 0x30, 0x95, 0xA3, 0x49, 0xD2, 0x45, 0x70, 0x8C, - 0x7C, 0xF5, 0x50, 0x11, 0x87, 0x03, 0xD7, 0x30, - 0x2C, 0x27, 0xB6, 0x0A, 0xF5, 0xD4, 0xE6, 0x7F, - 0xC9, 0x78, 0xF8, 0xA4, 0xE6, 0x09, 0x53, 0xC7, - 0xA0, 0x4F, 0x92, 0xFC, 0xF4, 0x1A, 0xEE, 0x64, - 0x32, 0x1C, 0xCB, 0x70, 0x7A, 0x89, 0x58, 0x51, - 0x55, 0x2B, 0x1E, 0x37, 0xB0, 0x0B, 0xC5, 0xE6, - 0xB7, 0x2F, 0xA5, 0xBC, 0xEF, 0x9E, 0x3F, 0xFF - }, - { - 0x07, 0x26, 0x2D, 0x73, 0x8B, 0x09, 0x32, 0x1F, - 0x4D, 0xBC, 0xCE, 0xC4, 0xBB, 0x26, 0xF4, 0x8C, - 0xB0, 0xF0, 0xED, 0x24, 0x6C, 0xE0, 0xB3, 0x1B, - 0x9A, 0x6E, 0x7B, 0xC6, 0x83, 0x04, 0x9F, 0x1F, - 0x3E, 0x55, 0x45, 0xF2, 0x8C, 0xE9, 0x32, 0xDD, - 0x98, 0x5C, 0x5A, 0xB0, 0xF4, 0x3B, 0xD6, 0xDE, - 0x07, 0x70, 0x56, 0x0A, 0xF3, 0x29, 0x06, 0x5E, - 0xD2, 0xE4, 0x9D, 0x34, 0x62, 0x4C, 0x2C, 0xBB - }, - { - 0xB6, 0x40, 0x5E, 0xCA, 0x8E, 0xE3, 0x31, 0x6C, - 0x87, 0x06, 0x1C, 0xC6, 0xEC, 0x18, 0xDB, 0xA5, - 0x3E, 0x6C, 0x25, 0x0C, 0x63, 0xBA, 0x1F, 0x3B, - 0xAE, 0x9E, 0x55, 0xDD, 0x34, 0x98, 0x03, 0x6A, - 0xF0, 0x8C, 0xD2, 0x72, 0xAA, 0x24, 0xD7, 0x13, - 0xC6, 0x02, 0x0D, 0x77, 0xAB, 0x2F, 0x39, 0x19, - 0xAF, 0x1A, 0x32, 0xF3, 0x07, 0x42, 0x06, 0x18, - 0xAB, 0x97, 0xE7, 0x39, 0x53, 0x99, 0x4F, 0xB4 - }, - { - 0x7E, 0xE6, 0x82, 0xF6, 0x31, 0x48, 0xEE, 0x45, - 0xF6, 0xE5, 0x31, 0x5D, 0xA8, 0x1E, 0x5C, 0x6E, - 0x55, 0x7C, 0x2C, 0x34, 0x64, 0x1F, 0xC5, 0x09, - 0xC7, 0xA5, 0x70, 0x10, 0x88, 0xC3, 0x8A, 0x74, - 0x75, 0x61, 0x68, 0xE2, 0xCD, 0x8D, 0x35, 0x1E, - 0x88, 0xFD, 0x1A, 0x45, 0x1F, 0x36, 0x0A, 0x01, - 0xF5, 0xB2, 0x58, 0x0F, 0x9B, 0x5A, 0x2E, 0x8C, - 0xFC, 0x13, 0x8F, 0x3D, 0xD5, 0x9A, 0x3F, 0xFC - }, - { - 0x1D, 0x26, 0x3C, 0x17, 0x9D, 0x6B, 0x26, 0x8F, - 0x6F, 0xA0, 0x16, 0xF3, 0xA4, 0xF2, 0x9E, 0x94, - 0x38, 0x91, 0x12, 0x5E, 0xD8, 0x59, 0x3C, 0x81, - 0x25, 0x60, 0x59, 0xF5, 0xA7, 0xB4, 0x4A, 0xF2, - 0xDC, 0xB2, 0x03, 0x0D, 0x17, 0x5C, 0x00, 0xE6, - 0x2E, 0xCA, 0xF7, 0xEE, 0x96, 0x68, 0x2A, 0xA0, - 0x7A, 0xB2, 0x0A, 0x61, 0x10, 0x24, 0xA2, 0x85, - 0x32, 0xB1, 0xC2, 0x5B, 0x86, 0x65, 0x79, 0x02 - }, - { - 0x10, 0x6D, 0x13, 0x2C, 0xBD, 0xB4, 0xCD, 0x25, - 0x97, 0x81, 0x28, 0x46, 0xE2, 0xBC, 0x1B, 0xF7, - 0x32, 0xFE, 0xC5, 0xF0, 0xA5, 0xF6, 0x5D, 0xBB, - 0x39, 0xEC, 0x4E, 0x6D, 0xC6, 0x4A, 0xB2, 0xCE, - 0x6D, 0x24, 0x63, 0x0D, 0x0F, 0x15, 0xA8, 0x05, - 0xC3, 0x54, 0x00, 0x25, 0xD8, 0x4A, 0xFA, 0x98, - 0xE3, 0x67, 0x03, 0xC3, 0xDB, 0xEE, 0x71, 0x3E, - 0x72, 0xDD, 0xE8, 0x46, 0x5B, 0xC1, 0xBE, 0x7E - }, - { - 0x0E, 0x79, 0x96, 0x82, 0x26, 0x65, 0x06, 0x67, - 0xA8, 0xD8, 0x62, 0xEA, 0x8D, 0xA4, 0x89, 0x1A, - 0xF5, 0x6A, 0x4E, 0x3A, 0x8B, 0x6D, 0x17, 0x50, - 0xE3, 0x94, 0xF0, 0xDE, 0xA7, 0x6D, 0x64, 0x0D, - 0x85, 0x07, 0x7B, 0xCE, 0xC2, 0xCC, 0x86, 0x88, - 0x6E, 0x50, 0x67, 0x51, 0xB4, 0xF6, 0xA5, 0x83, - 0x8F, 0x7F, 0x0B, 0x5F, 0xEF, 0x76, 0x5D, 0x9D, - 0xC9, 0x0D, 0xCD, 0xCB, 0xAF, 0x07, 0x9F, 0x08 - }, - { - 0x52, 0x11, 0x56, 0xA8, 0x2A, 0xB0, 0xC4, 0xE5, - 0x66, 0xE5, 0x84, 0x4D, 0x5E, 0x31, 0xAD, 0x9A, - 0xAF, 0x14, 0x4B, 0xBD, 0x5A, 0x46, 0x4F, 0xDC, - 0xA3, 0x4D, 0xBD, 0x57, 0x17, 0xE8, 0xFF, 0x71, - 0x1D, 0x3F, 0xFE, 0xBB, 0xFA, 0x08, 0x5D, 0x67, - 0xFE, 0x99, 0x6A, 0x34, 0xF6, 0xD3, 0xE4, 0xE6, - 0x0B, 0x13, 0x96, 0xBF, 0x4B, 0x16, 0x10, 0xC2, - 0x63, 0xBD, 0xBB, 0x83, 0x4D, 0x56, 0x08, 0x16 - }, - { - 0x1A, 0xBA, 0x88, 0xBE, 0xFC, 0x55, 0xBC, 0x25, - 0xEF, 0xBC, 0xE0, 0x2D, 0xB8, 0xB9, 0x93, 0x3E, - 0x46, 0xF5, 0x76, 0x61, 0xBA, 0xEA, 0xBE, 0xB2, - 0x1C, 0xC2, 0x57, 0x4D, 0x2A, 0x51, 0x8A, 0x3C, - 0xBA, 0x5D, 0xC5, 0xA3, 0x8E, 0x49, 0x71, 0x34, - 0x40, 0xB2, 0x5F, 0x9C, 0x74, 0x4E, 0x75, 0xF6, - 0xB8, 0x5C, 0x9D, 0x8F, 0x46, 0x81, 0xF6, 0x76, - 0x16, 0x0F, 0x61, 0x05, 0x35, 0x7B, 0x84, 0x06 - }, - { - 0x5A, 0x99, 0x49, 0xFC, 0xB2, 0xC4, 0x73, 0xCD, - 0xA9, 0x68, 0xAC, 0x1B, 0x5D, 0x08, 0x56, 0x6D, - 0xC2, 0xD8, 0x16, 0xD9, 0x60, 0xF5, 0x7E, 0x63, - 0xB8, 0x98, 0xFA, 0x70, 0x1C, 0xF8, 0xEB, 0xD3, - 0xF5, 0x9B, 0x12, 0x4D, 0x95, 0xBF, 0xBB, 0xED, - 0xC5, 0xF1, 0xCF, 0x0E, 0x17, 0xD5, 0xEA, 0xED, - 0x0C, 0x02, 0xC5, 0x0B, 0x69, 0xD8, 0xA4, 0x02, - 0xCA, 0xBC, 0xCA, 0x44, 0x33, 0xB5, 0x1F, 0xD4 - }, - { - 0xB0, 0xCE, 0xAD, 0x09, 0x80, 0x7C, 0x67, 0x2A, - 0xF2, 0xEB, 0x2B, 0x0F, 0x06, 0xDD, 0xE4, 0x6C, - 0xF5, 0x37, 0x0E, 0x15, 0xA4, 0x09, 0x6B, 0x1A, - 0x7D, 0x7C, 0xBB, 0x36, 0xEC, 0x31, 0xC2, 0x05, - 0xFB, 0xEF, 0xCA, 0x00, 0xB7, 0xA4, 0x16, 0x2F, - 0xA8, 0x9F, 0xB4, 0xFB, 0x3E, 0xB7, 0x8D, 0x79, - 0x77, 0x0C, 0x23, 0xF4, 0x4E, 0x72, 0x06, 0x66, - 0x4C, 0xE3, 0xCD, 0x93, 0x1C, 0x29, 0x1E, 0x5D - }, - { - 0xBB, 0x66, 0x64, 0x93, 0x1E, 0xC9, 0x70, 0x44, - 0xE4, 0x5B, 0x2A, 0xE4, 0x20, 0xAE, 0x1C, 0x55, - 0x1A, 0x88, 0x74, 0xBC, 0x93, 0x7D, 0x08, 0xE9, - 0x69, 0x39, 0x9C, 0x39, 0x64, 0xEB, 0xDB, 0xA8, - 0x34, 0x6C, 0xDD, 0x5D, 0x09, 0xCA, 0xAF, 0xE4, - 0xC2, 0x8B, 0xA7, 0xEC, 0x78, 0x81, 0x91, 0xCE, - 0xCA, 0x65, 0xDD, 0xD6, 0xF9, 0x5F, 0x18, 0x58, - 0x3E, 0x04, 0x0D, 0x0F, 0x30, 0xD0, 0x36, 0x4D - }, - { - 0x65, 0xBC, 0x77, 0x0A, 0x5F, 0xAA, 0x37, 0x92, - 0x36, 0x98, 0x03, 0x68, 0x3E, 0x84, 0x4B, 0x0B, - 0xE7, 0xEE, 0x96, 0xF2, 0x9F, 0x6D, 0x6A, 0x35, - 0x56, 0x80, 0x06, 0xBD, 0x55, 0x90, 0xF9, 0xA4, - 0xEF, 0x63, 0x9B, 0x7A, 0x80, 0x61, 0xC7, 0xB0, - 0x42, 0x4B, 0x66, 0xB6, 0x0A, 0xC3, 0x4A, 0xF3, - 0x11, 0x99, 0x05, 0xF3, 0x3A, 0x9D, 0x8C, 0x3A, - 0xE1, 0x83, 0x82, 0xCA, 0x9B, 0x68, 0x99, 0x00 - }, - { - 0xEA, 0x9B, 0x4D, 0xCA, 0x33, 0x33, 0x36, 0xAA, - 0xF8, 0x39, 0xA4, 0x5C, 0x6E, 0xAA, 0x48, 0xB8, - 0xCB, 0x4C, 0x7D, 0xDA, 0xBF, 0xFE, 0xA4, 0xF6, - 0x43, 0xD6, 0x35, 0x7E, 0xA6, 0x62, 0x8A, 0x48, - 0x0A, 0x5B, 0x45, 0xF2, 0xB0, 0x52, 0xC1, 0xB0, - 0x7D, 0x1F, 0xED, 0xCA, 0x91, 0x8B, 0x6F, 0x11, - 0x39, 0xD8, 0x0F, 0x74, 0xC2, 0x45, 0x10, 0xDC, - 0xBA, 0xA4, 0xBE, 0x70, 0xEA, 0xCC, 0x1B, 0x06 - }, - { - 0xE6, 0x34, 0x2F, 0xB4, 0xA7, 0x80, 0xAD, 0x97, - 0x5D, 0x0E, 0x24, 0xBC, 0xE1, 0x49, 0x98, 0x9B, - 0x91, 0xD3, 0x60, 0x55, 0x7E, 0x87, 0x99, 0x4F, - 0x6B, 0x45, 0x7B, 0x89, 0x55, 0x75, 0xCC, 0x02, - 0xD0, 0xC1, 0x5B, 0xAD, 0x3C, 0xE7, 0x57, 0x7F, - 0x4C, 0x63, 0x92, 0x7F, 0xF1, 0x3F, 0x3E, 0x38, - 0x1F, 0xF7, 0xE7, 0x2B, 0xDB, 0xE7, 0x45, 0x32, - 0x48, 0x44, 0xA9, 0xD2, 0x7E, 0x3F, 0x1C, 0x01 - }, - { - 0x3E, 0x20, 0x9C, 0x9B, 0x33, 0xE8, 0xE4, 0x61, - 0x17, 0x8A, 0xB4, 0x6B, 0x1C, 0x64, 0xB4, 0x9A, - 0x07, 0xFB, 0x74, 0x5F, 0x1C, 0x8B, 0xC9, 0x5F, - 0xBF, 0xB9, 0x4C, 0x6B, 0x87, 0xC6, 0x95, 0x16, - 0x65, 0x1B, 0x26, 0x4E, 0xF9, 0x80, 0x93, 0x7F, - 0xAD, 0x41, 0x23, 0x8B, 0x91, 0xDD, 0xC0, 0x11, - 0xA5, 0xDD, 0x77, 0x7C, 0x7E, 0xFD, 0x44, 0x94, - 0xB4, 0xB6, 0xEC, 0xD3, 0xA9, 0xC2, 0x2A, 0xC0 - }, - { - 0xFD, 0x6A, 0x3D, 0x5B, 0x18, 0x75, 0xD8, 0x04, - 0x86, 0xD6, 0xE6, 0x96, 0x94, 0xA5, 0x6D, 0xBB, - 0x04, 0xA9, 0x9A, 0x4D, 0x05, 0x1F, 0x15, 0xDB, - 0x26, 0x89, 0x77, 0x6B, 0xA1, 0xC4, 0x88, 0x2E, - 0x6D, 0x46, 0x2A, 0x60, 0x3B, 0x70, 0x15, 0xDC, - 0x9F, 0x4B, 0x74, 0x50, 0xF0, 0x53, 0x94, 0x30, - 0x3B, 0x86, 0x52, 0xCF, 0xB4, 0x04, 0xA2, 0x66, - 0x96, 0x2C, 0x41, 0xBA, 0xE6, 0xE1, 0x8A, 0x94 - }, - { - 0x95, 0x1E, 0x27, 0x51, 0x7E, 0x6B, 0xAD, 0x9E, - 0x41, 0x95, 0xFC, 0x86, 0x71, 0xDE, 0xE3, 0xE7, - 0xE9, 0xBE, 0x69, 0xCE, 0xE1, 0x42, 0x2C, 0xB9, - 0xFE, 0xCF, 0xCE, 0x0D, 0xBA, 0x87, 0x5F, 0x7B, - 0x31, 0x0B, 0x93, 0xEE, 0x3A, 0x3D, 0x55, 0x8F, - 0x94, 0x1F, 0x63, 0x5F, 0x66, 0x8F, 0xF8, 0x32, - 0xD2, 0xC1, 0xD0, 0x33, 0xC5, 0xE2, 0xF0, 0x99, - 0x7E, 0x4C, 0x66, 0xF1, 0x47, 0x34, 0x4E, 0x02 - }, - { - 0x8E, 0xBA, 0x2F, 0x87, 0x4F, 0x1A, 0xE8, 0x40, - 0x41, 0x90, 0x3C, 0x7C, 0x42, 0x53, 0xC8, 0x22, - 0x92, 0x53, 0x0F, 0xC8, 0x50, 0x95, 0x50, 0xBF, - 0xDC, 0x34, 0xC9, 0x5C, 0x7E, 0x28, 0x89, 0xD5, - 0x65, 0x0B, 0x0A, 0xD8, 0xCB, 0x98, 0x8E, 0x5C, - 0x48, 0x94, 0xCB, 0x87, 0xFB, 0xFB, 0xB1, 0x96, - 0x12, 0xEA, 0x93, 0xCC, 0xC4, 0xC5, 0xCA, 0xD1, - 0x71, 0x58, 0xB9, 0x76, 0x34, 0x64, 0xB4, 0x92 - }, - { - 0x16, 0xF7, 0x12, 0xEA, 0xA1, 0xB7, 0xC6, 0x35, - 0x47, 0x19, 0xA8, 0xE7, 0xDB, 0xDF, 0xAF, 0x55, - 0xE4, 0x06, 0x3A, 0x4D, 0x27, 0x7D, 0x94, 0x75, - 0x50, 0x01, 0x9B, 0x38, 0xDF, 0xB5, 0x64, 0x83, - 0x09, 0x11, 0x05, 0x7D, 0x50, 0x50, 0x61, 0x36, - 0xE2, 0x39, 0x4C, 0x3B, 0x28, 0x94, 0x5C, 0xC9, - 0x64, 0x96, 0x7D, 0x54, 0xE3, 0x00, 0x0C, 0x21, - 0x81, 0x62, 0x6C, 0xFB, 0x9B, 0x73, 0xEF, 0xD2 - }, - { - 0xC3, 0x96, 0x39, 0xE7, 0xD5, 0xC7, 0xFB, 0x8C, - 0xDD, 0x0F, 0xD3, 0xE6, 0xA5, 0x20, 0x96, 0x03, - 0x94, 0x37, 0x12, 0x2F, 0x21, 0xC7, 0x8F, 0x16, - 0x79, 0xCE, 0xA9, 0xD7, 0x8A, 0x73, 0x4C, 0x56, - 0xEC, 0xBE, 0xB2, 0x86, 0x54, 0xB4, 0xF1, 0x8E, - 0x34, 0x2C, 0x33, 0x1F, 0x6F, 0x72, 0x29, 0xEC, - 0x4B, 0x4B, 0xC2, 0x81, 0xB2, 0xD8, 0x0A, 0x6E, - 0xB5, 0x00, 0x43, 0xF3, 0x17, 0x96, 0xC8, 0x8C - }, - { - 0x72, 0xD0, 0x81, 0xAF, 0x99, 0xF8, 0xA1, 0x73, - 0xDC, 0xC9, 0xA0, 0xAC, 0x4E, 0xB3, 0x55, 0x74, - 0x05, 0x63, 0x9A, 0x29, 0x08, 0x4B, 0x54, 0xA4, - 0x01, 0x72, 0x91, 0x2A, 0x2F, 0x8A, 0x39, 0x51, - 0x29, 0xD5, 0x53, 0x6F, 0x09, 0x18, 0xE9, 0x02, - 0xF9, 0xE8, 0xFA, 0x60, 0x00, 0x99, 0x5F, 0x41, - 0x68, 0xDD, 0xC5, 0xF8, 0x93, 0x01, 0x1B, 0xE6, - 0xA0, 0xDB, 0xC9, 0xB8, 0xA1, 0xA3, 0xF5, 0xBB - }, - { - 0xC1, 0x1A, 0xA8, 0x1E, 0x5E, 0xFD, 0x24, 0xD5, - 0xFC, 0x27, 0xEE, 0x58, 0x6C, 0xFD, 0x88, 0x47, - 0xFB, 0xB0, 0xE2, 0x76, 0x01, 0xCC, 0xEC, 0xE5, - 0xEC, 0xCA, 0x01, 0x98, 0xE3, 0xC7, 0x76, 0x53, - 0x93, 0xBB, 0x74, 0x45, 0x7C, 0x7E, 0x7A, 0x27, - 0xEB, 0x91, 0x70, 0x35, 0x0E, 0x1F, 0xB5, 0x38, - 0x57, 0x17, 0x75, 0x06, 0xBE, 0x3E, 0x76, 0x2C, - 0xC0, 0xF1, 0x4D, 0x8C, 0x3A, 0xFE, 0x90, 0x77 - }, - { - 0xC2, 0x8F, 0x21, 0x50, 0xB4, 0x52, 0xE6, 0xC0, - 0xC4, 0x24, 0xBC, 0xDE, 0x6F, 0x8D, 0x72, 0x00, - 0x7F, 0x93, 0x10, 0xFE, 0xD7, 0xF2, 0xF8, 0x7D, - 0xE0, 0xDB, 0xB6, 0x4F, 0x44, 0x79, 0xD6, 0xC1, - 0x44, 0x1B, 0xA6, 0x6F, 0x44, 0xB2, 0xAC, 0xCE, - 0xE6, 0x16, 0x09, 0x17, 0x7E, 0xD3, 0x40, 0x12, - 0x8B, 0x40, 0x7E, 0xCE, 0xC7, 0xC6, 0x4B, 0xBE, - 0x50, 0xD6, 0x3D, 0x22, 0xD8, 0x62, 0x77, 0x27 - }, - { - 0xF6, 0x3D, 0x88, 0x12, 0x28, 0x77, 0xEC, 0x30, - 0xB8, 0xC8, 0xB0, 0x0D, 0x22, 0xE8, 0x90, 0x00, - 0xA9, 0x66, 0x42, 0x61, 0x12, 0xBD, 0x44, 0x16, - 0x6E, 0x2F, 0x52, 0x5B, 0x76, 0x9C, 0xCB, 0xE9, - 0xB2, 0x86, 0xD4, 0x37, 0xA0, 0x12, 0x91, 0x30, - 0xDD, 0xE1, 0xA8, 0x6C, 0x43, 0xE0, 0x4B, 0xED, - 0xB5, 0x94, 0xE6, 0x71, 0xD9, 0x82, 0x83, 0xAF, - 0xE6, 0x4C, 0xE3, 0x31, 0xDE, 0x98, 0x28, 0xFD - }, - { - 0x34, 0x8B, 0x05, 0x32, 0x88, 0x0B, 0x88, 0xA6, - 0x61, 0x4A, 0x8D, 0x74, 0x08, 0xC3, 0xF9, 0x13, - 0x35, 0x7F, 0xBB, 0x60, 0xE9, 0x95, 0xC6, 0x02, - 0x05, 0xBE, 0x91, 0x39, 0xE7, 0x49, 0x98, 0xAE, - 0xDE, 0x7F, 0x45, 0x81, 0xE4, 0x2F, 0x6B, 0x52, - 0x69, 0x8F, 0x7F, 0xA1, 0x21, 0x97, 0x08, 0xC1, - 0x44, 0x98, 0x06, 0x7F, 0xD1, 0xE0, 0x95, 0x02, - 0xDE, 0x83, 0xA7, 0x7D, 0xD2, 0x81, 0x15, 0x0C - }, - { - 0x51, 0x33, 0xDC, 0x8B, 0xEF, 0x72, 0x53, 0x59, - 0xDF, 0xF5, 0x97, 0x92, 0xD8, 0x5E, 0xAF, 0x75, - 0xB7, 0xE1, 0xDC, 0xD1, 0x97, 0x8B, 0x01, 0xC3, - 0x5B, 0x1B, 0x85, 0xFC, 0xEB, 0xC6, 0x33, 0x88, - 0xAD, 0x99, 0xA1, 0x7B, 0x63, 0x46, 0xA2, 0x17, - 0xDC, 0x1A, 0x96, 0x22, 0xEB, 0xD1, 0x22, 0xEC, - 0xF6, 0x91, 0x3C, 0x4D, 0x31, 0xA6, 0xB5, 0x2A, - 0x69, 0x5B, 0x86, 0xAF, 0x00, 0xD7, 0x41, 0xA0 - }, - { - 0x27, 0x53, 0xC4, 0xC0, 0xE9, 0x8E, 0xCA, 0xD8, - 0x06, 0xE8, 0x87, 0x80, 0xEC, 0x27, 0xFC, 0xCD, - 0x0F, 0x5C, 0x1A, 0xB5, 0x47, 0xF9, 0xE4, 0xBF, - 0x16, 0x59, 0xD1, 0x92, 0xC2, 0x3A, 0xA2, 0xCC, - 0x97, 0x1B, 0x58, 0xB6, 0x80, 0x25, 0x80, 0xBA, - 0xEF, 0x8A, 0xDC, 0x3B, 0x77, 0x6E, 0xF7, 0x08, - 0x6B, 0x25, 0x45, 0xC2, 0x98, 0x7F, 0x34, 0x8E, - 0xE3, 0x71, 0x9C, 0xDE, 0xF2, 0x58, 0xC4, 0x03 - }, - { - 0xB1, 0x66, 0x35, 0x73, 0xCE, 0x4B, 0x9D, 0x8C, - 0xAE, 0xFC, 0x86, 0x50, 0x12, 0xF3, 0xE3, 0x97, - 0x14, 0xB9, 0x89, 0x8A, 0x5D, 0xA6, 0xCE, 0x17, - 0xC2, 0x5A, 0x6A, 0x47, 0x93, 0x1A, 0x9D, 0xDB, - 0x9B, 0xBE, 0x98, 0xAD, 0xAA, 0x55, 0x3B, 0xEE, - 0xD4, 0x36, 0xE8, 0x95, 0x78, 0x45, 0x54, 0x16, - 0xC2, 0xA5, 0x2A, 0x52, 0x5C, 0xF2, 0x86, 0x2B, - 0x8D, 0x1D, 0x49, 0xA2, 0x53, 0x1B, 0x73, 0x91 - }, - { - 0x64, 0xF5, 0x8B, 0xD6, 0xBF, 0xC8, 0x56, 0xF5, - 0xE8, 0x73, 0xB2, 0xA2, 0x95, 0x6E, 0xA0, 0xED, - 0xA0, 0xD6, 0xDB, 0x0D, 0xA3, 0x9C, 0x8C, 0x7F, - 0xC6, 0x7C, 0x9F, 0x9F, 0xEE, 0xFC, 0xFF, 0x30, - 0x72, 0xCD, 0xF9, 0xE6, 0xEA, 0x37, 0xF6, 0x9A, - 0x44, 0xF0, 0xC6, 0x1A, 0xA0, 0xDA, 0x36, 0x93, - 0xC2, 0xDB, 0x5B, 0x54, 0x96, 0x0C, 0x02, 0x81, - 0xA0, 0x88, 0x15, 0x1D, 0xB4, 0x2B, 0x11, 0xE8 - }, - { - 0x07, 0x64, 0xC7, 0xBE, 0x28, 0x12, 0x5D, 0x90, - 0x65, 0xC4, 0xB9, 0x8A, 0x69, 0xD6, 0x0A, 0xED, - 0xE7, 0x03, 0x54, 0x7C, 0x66, 0xA1, 0x2E, 0x17, - 0xE1, 0xC6, 0x18, 0x99, 0x41, 0x32, 0xF5, 0xEF, - 0x82, 0x48, 0x2C, 0x1E, 0x3F, 0xE3, 0x14, 0x6C, - 0xC6, 0x53, 0x76, 0xCC, 0x10, 0x9F, 0x01, 0x38, - 0xED, 0x9A, 0x80, 0xE4, 0x9F, 0x1F, 0x3C, 0x7D, - 0x61, 0x0D, 0x2F, 0x24, 0x32, 0xF2, 0x06, 0x05 - }, - { - 0xF7, 0x48, 0x78, 0x43, 0x98, 0xA2, 0xFF, 0x03, - 0xEB, 0xEB, 0x07, 0xE1, 0x55, 0xE6, 0x61, 0x16, - 0xA8, 0x39, 0x74, 0x1A, 0x33, 0x6E, 0x32, 0xDA, - 0x71, 0xEC, 0x69, 0x60, 0x01, 0xF0, 0xAD, 0x1B, - 0x25, 0xCD, 0x48, 0xC6, 0x9C, 0xFC, 0xA7, 0x26, - 0x5E, 0xCA, 0x1D, 0xD7, 0x19, 0x04, 0xA0, 0xCE, - 0x74, 0x8A, 0xC4, 0x12, 0x4F, 0x35, 0x71, 0x07, - 0x6D, 0xFA, 0x71, 0x16, 0xA9, 0xCF, 0x00, 0xE9 - }, - { - 0x3F, 0x0D, 0xBC, 0x01, 0x86, 0xBC, 0xEB, 0x6B, - 0x78, 0x5B, 0xA7, 0x8D, 0x2A, 0x2A, 0x01, 0x3C, - 0x91, 0x0B, 0xE1, 0x57, 0xBD, 0xAF, 0xFA, 0xE8, - 0x1B, 0xB6, 0x66, 0x3B, 0x1A, 0x73, 0x72, 0x2F, - 0x7F, 0x12, 0x28, 0x79, 0x5F, 0x3E, 0xCA, 0xDA, - 0x87, 0xCF, 0x6E, 0xF0, 0x07, 0x84, 0x74, 0xAF, - 0x73, 0xF3, 0x1E, 0xCA, 0x0C, 0xC2, 0x00, 0xED, - 0x97, 0x5B, 0x68, 0x93, 0xF7, 0x61, 0xCB, 0x6D - }, - { - 0xD4, 0x76, 0x2C, 0xD4, 0x59, 0x98, 0x76, 0xCA, - 0x75, 0xB2, 0xB8, 0xFE, 0x24, 0x99, 0x44, 0xDB, - 0xD2, 0x7A, 0xCE, 0x74, 0x1F, 0xDA, 0xB9, 0x36, - 0x16, 0xCB, 0xC6, 0xE4, 0x25, 0x46, 0x0F, 0xEB, - 0x51, 0xD4, 0xE7, 0xAD, 0xCC, 0x38, 0x18, 0x0E, - 0x7F, 0xC4, 0x7C, 0x89, 0x02, 0x4A, 0x7F, 0x56, - 0x19, 0x1A, 0xDB, 0x87, 0x8D, 0xFD, 0xE4, 0xEA, - 0xD6, 0x22, 0x23, 0xF5, 0xA2, 0x61, 0x0E, 0xFE - }, - { - 0xCD, 0x36, 0xB3, 0xD5, 0xB4, 0xC9, 0x1B, 0x90, - 0xFC, 0xBB, 0xA7, 0x95, 0x13, 0xCF, 0xEE, 0x19, - 0x07, 0xD8, 0x64, 0x5A, 0x16, 0x2A, 0xFD, 0x0C, - 0xD4, 0xCF, 0x41, 0x92, 0xD4, 0xA5, 0xF4, 0xC8, - 0x92, 0x18, 0x3A, 0x8E, 0xAC, 0xDB, 0x2B, 0x6B, - 0x6A, 0x9D, 0x9A, 0xA8, 0xC1, 0x1A, 0xC1, 0xB2, - 0x61, 0xB3, 0x80, 0xDB, 0xEE, 0x24, 0xCA, 0x46, - 0x8F, 0x1B, 0xFD, 0x04, 0x3C, 0x58, 0xEE, 0xFE - }, - { - 0x98, 0x59, 0x34, 0x52, 0x28, 0x16, 0x61, 0xA5, - 0x3C, 0x48, 0xA9, 0xD8, 0xCD, 0x79, 0x08, 0x26, - 0xC1, 0xA1, 0xCE, 0x56, 0x77, 0x38, 0x05, 0x3D, - 0x0B, 0xEE, 0x4A, 0x91, 0xA3, 0xD5, 0xBD, 0x92, - 0xEE, 0xFD, 0xBA, 0xBE, 0xBE, 0x32, 0x04, 0xF2, - 0x03, 0x1C, 0xA5, 0xF7, 0x81, 0xBD, 0xA9, 0x9E, - 0xF5, 0xD8, 0xAE, 0x56, 0xE5, 0xB0, 0x4A, 0x9E, - 0x1E, 0xCD, 0x21, 0xB0, 0xEB, 0x05, 0xD3, 0xE1 - }, - { - 0x77, 0x1F, 0x57, 0xDD, 0x27, 0x75, 0xCC, 0xDA, - 0xB5, 0x59, 0x21, 0xD3, 0xE8, 0xE3, 0x0C, 0xCF, - 0x48, 0x4D, 0x61, 0xFE, 0x1C, 0x1B, 0x9C, 0x2A, - 0xE8, 0x19, 0xD0, 0xFB, 0x2A, 0x12, 0xFA, 0xB9, - 0xBE, 0x70, 0xC4, 0xA7, 0xA1, 0x38, 0xDA, 0x84, - 0xE8, 0x28, 0x04, 0x35, 0xDA, 0xAD, 0xE5, 0xBB, - 0xE6, 0x6A, 0xF0, 0x83, 0x6A, 0x15, 0x4F, 0x81, - 0x7F, 0xB1, 0x7F, 0x33, 0x97, 0xE7, 0x25, 0xA3 - }, - { - 0xC6, 0x08, 0x97, 0xC6, 0xF8, 0x28, 0xE2, 0x1F, - 0x16, 0xFB, 0xB5, 0xF1, 0x5B, 0x32, 0x3F, 0x87, - 0xB6, 0xC8, 0x95, 0x5E, 0xAB, 0xF1, 0xD3, 0x80, - 0x61, 0xF7, 0x07, 0xF6, 0x08, 0xAB, 0xDD, 0x99, - 0x3F, 0xAC, 0x30, 0x70, 0x63, 0x3E, 0x28, 0x6C, - 0xF8, 0x33, 0x9C, 0xE2, 0x95, 0xDD, 0x35, 0x2D, - 0xF4, 0xB4, 0xB4, 0x0B, 0x2F, 0x29, 0xDA, 0x1D, - 0xD5, 0x0B, 0x3A, 0x05, 0xD0, 0x79, 0xE6, 0xBB - }, - { - 0x82, 0x10, 0xCD, 0x2C, 0x2D, 0x3B, 0x13, 0x5C, - 0x2C, 0xF0, 0x7F, 0xA0, 0xD1, 0x43, 0x3C, 0xD7, - 0x71, 0xF3, 0x25, 0xD0, 0x75, 0xC6, 0x46, 0x9D, - 0x9C, 0x7F, 0x1B, 0xA0, 0x94, 0x3C, 0xD4, 0xAB, - 0x09, 0x80, 0x8C, 0xAB, 0xF4, 0xAC, 0xB9, 0xCE, - 0x5B, 0xB8, 0x8B, 0x49, 0x89, 0x29, 0xB4, 0xB8, - 0x47, 0xF6, 0x81, 0xAD, 0x2C, 0x49, 0x0D, 0x04, - 0x2D, 0xB2, 0xAE, 0xC9, 0x42, 0x14, 0xB0, 0x6B - }, - { - 0x1D, 0x4E, 0xDF, 0xFF, 0xD8, 0xFD, 0x80, 0xF7, - 0xE4, 0x10, 0x78, 0x40, 0xFA, 0x3A, 0xA3, 0x1E, - 0x32, 0x59, 0x84, 0x91, 0xE4, 0xAF, 0x70, 0x13, - 0xC1, 0x97, 0xA6, 0x5B, 0x7F, 0x36, 0xDD, 0x3A, - 0xC4, 0xB4, 0x78, 0x45, 0x61, 0x11, 0xCD, 0x43, - 0x09, 0xD9, 0x24, 0x35, 0x10, 0x78, 0x2F, 0xA3, - 0x1B, 0x7C, 0x4C, 0x95, 0xFA, 0x95, 0x15, 0x20, - 0xD0, 0x20, 0xEB, 0x7E, 0x5C, 0x36, 0xE4, 0xEF - }, - { - 0xAF, 0x8E, 0x6E, 0x91, 0xFA, 0xB4, 0x6C, 0xE4, - 0x87, 0x3E, 0x1A, 0x50, 0xA8, 0xEF, 0x44, 0x8C, - 0xC2, 0x91, 0x21, 0xF7, 0xF7, 0x4D, 0xEE, 0xF3, - 0x4A, 0x71, 0xEF, 0x89, 0xCC, 0x00, 0xD9, 0x27, - 0x4B, 0xC6, 0xC2, 0x45, 0x4B, 0xBB, 0x32, 0x30, - 0xD8, 0xB2, 0xEC, 0x94, 0xC6, 0x2B, 0x1D, 0xEC, - 0x85, 0xF3, 0x59, 0x3B, 0xFA, 0x30, 0xEA, 0x6F, - 0x7A, 0x44, 0xD7, 0xC0, 0x94, 0x65, 0xA2, 0x53 - }, - { - 0x29, 0xFD, 0x38, 0x4E, 0xD4, 0x90, 0x6F, 0x2D, - 0x13, 0xAA, 0x9F, 0xE7, 0xAF, 0x90, 0x59, 0x90, - 0x93, 0x8B, 0xED, 0x80, 0x7F, 0x18, 0x32, 0x45, - 0x4A, 0x37, 0x2A, 0xB4, 0x12, 0xEE, 0xA1, 0xF5, - 0x62, 0x5A, 0x1F, 0xCC, 0x9A, 0xC8, 0x34, 0x3B, - 0x7C, 0x67, 0xC5, 0xAB, 0xA6, 0xE0, 0xB1, 0xCC, - 0x46, 0x44, 0x65, 0x49, 0x13, 0x69, 0x2C, 0x6B, - 0x39, 0xEB, 0x91, 0x87, 0xCE, 0xAC, 0xD3, 0xEC - }, - { - 0xA2, 0x68, 0xC7, 0x88, 0x5D, 0x98, 0x74, 0xA5, - 0x1C, 0x44, 0xDF, 0xFE, 0xD8, 0xEA, 0x53, 0xE9, - 0x4F, 0x78, 0x45, 0x6E, 0x0B, 0x2E, 0xD9, 0x9F, - 0xF5, 0xA3, 0x92, 0x47, 0x60, 0x81, 0x38, 0x26, - 0xD9, 0x60, 0xA1, 0x5E, 0xDB, 0xED, 0xBB, 0x5D, - 0xE5, 0x22, 0x6B, 0xA4, 0xB0, 0x74, 0xE7, 0x1B, - 0x05, 0xC5, 0x5B, 0x97, 0x56, 0xBB, 0x79, 0xE5, - 0x5C, 0x02, 0x75, 0x4C, 0x2C, 0x7B, 0x6C, 0x8A - }, - { - 0x0C, 0xF8, 0x54, 0x54, 0x88, 0xD5, 0x6A, 0x86, - 0x81, 0x7C, 0xD7, 0xEC, 0xB1, 0x0F, 0x71, 0x16, - 0xB7, 0xEA, 0x53, 0x0A, 0x45, 0xB6, 0xEA, 0x49, - 0x7B, 0x6C, 0x72, 0xC9, 0x97, 0xE0, 0x9E, 0x3D, - 0x0D, 0xA8, 0x69, 0x8F, 0x46, 0xBB, 0x00, 0x6F, - 0xC9, 0x77, 0xC2, 0xCD, 0x3D, 0x11, 0x77, 0x46, - 0x3A, 0xC9, 0x05, 0x7F, 0xDD, 0x16, 0x62, 0xC8, - 0x5D, 0x0C, 0x12, 0x64, 0x43, 0xC1, 0x04, 0x73 - }, - { - 0xB3, 0x96, 0x14, 0x26, 0x8F, 0xDD, 0x87, 0x81, - 0x51, 0x5E, 0x2C, 0xFE, 0xBF, 0x89, 0xB4, 0xD5, - 0x40, 0x2B, 0xAB, 0x10, 0xC2, 0x26, 0xE6, 0x34, - 0x4E, 0x6B, 0x9A, 0xE0, 0x00, 0xFB, 0x0D, 0x6C, - 0x79, 0xCB, 0x2F, 0x3E, 0xC8, 0x0E, 0x80, 0xEA, - 0xEB, 0x19, 0x80, 0xD2, 0xF8, 0x69, 0x89, 0x16, - 0xBD, 0x2E, 0x9F, 0x74, 0x72, 0x36, 0x65, 0x51, - 0x16, 0x64, 0x9C, 0xD3, 0xCA, 0x23, 0xA8, 0x37 - }, - { - 0x74, 0xBE, 0xF0, 0x92, 0xFC, 0x6F, 0x1E, 0x5D, - 0xBA, 0x36, 0x63, 0xA3, 0xFB, 0x00, 0x3B, 0x2A, - 0x5B, 0xA2, 0x57, 0x49, 0x65, 0x36, 0xD9, 0x9F, - 0x62, 0xB9, 0xD7, 0x3F, 0x8F, 0x9E, 0xB3, 0xCE, - 0x9F, 0xF3, 0xEE, 0xC7, 0x09, 0xEB, 0x88, 0x36, - 0x55, 0xEC, 0x9E, 0xB8, 0x96, 0xB9, 0x12, 0x8F, - 0x2A, 0xFC, 0x89, 0xCF, 0x7D, 0x1A, 0xB5, 0x8A, - 0x72, 0xF4, 0xA3, 0xBF, 0x03, 0x4D, 0x2B, 0x4A - }, - { - 0x3A, 0x98, 0x8D, 0x38, 0xD7, 0x56, 0x11, 0xF3, - 0xEF, 0x38, 0xB8, 0x77, 0x49, 0x80, 0xB3, 0x3E, - 0x57, 0x3B, 0x6C, 0x57, 0xBE, 0xE0, 0x46, 0x9B, - 0xA5, 0xEE, 0xD9, 0xB4, 0x4F, 0x29, 0x94, 0x5E, - 0x73, 0x47, 0x96, 0x7F, 0xBA, 0x2C, 0x16, 0x2E, - 0x1C, 0x3B, 0xE7, 0xF3, 0x10, 0xF2, 0xF7, 0x5E, - 0xE2, 0x38, 0x1E, 0x7B, 0xFD, 0x6B, 0x3F, 0x0B, - 0xAE, 0xA8, 0xD9, 0x5D, 0xFB, 0x1D, 0xAF, 0xB1 - }, - { - 0x58, 0xAE, 0xDF, 0xCE, 0x6F, 0x67, 0xDD, 0xC8, - 0x5A, 0x28, 0xC9, 0x92, 0xF1, 0xC0, 0xBD, 0x09, - 0x69, 0xF0, 0x41, 0xE6, 0x6F, 0x1E, 0xE8, 0x80, - 0x20, 0xA1, 0x25, 0xCB, 0xFC, 0xFE, 0xBC, 0xD6, - 0x17, 0x09, 0xC9, 0xC4, 0xEB, 0xA1, 0x92, 0xC1, - 0x5E, 0x69, 0xF0, 0x20, 0xD4, 0x62, 0x48, 0x60, - 0x19, 0xFA, 0x8D, 0xEA, 0x0C, 0xD7, 0xA4, 0x29, - 0x21, 0xA1, 0x9D, 0x2F, 0xE5, 0x46, 0xD4, 0x3D - }, - { - 0x93, 0x47, 0xBD, 0x29, 0x14, 0x73, 0xE6, 0xB4, - 0xE3, 0x68, 0x43, 0x7B, 0x8E, 0x56, 0x1E, 0x06, - 0x5F, 0x64, 0x9A, 0x6D, 0x8A, 0xDA, 0x47, 0x9A, - 0xD0, 0x9B, 0x19, 0x99, 0xA8, 0xF2, 0x6B, 0x91, - 0xCF, 0x61, 0x20, 0xFD, 0x3B, 0xFE, 0x01, 0x4E, - 0x83, 0xF2, 0x3A, 0xCF, 0xA4, 0xC0, 0xAD, 0x7B, - 0x37, 0x12, 0xB2, 0xC3, 0xC0, 0x73, 0x32, 0x70, - 0x66, 0x31, 0x12, 0xCC, 0xD9, 0x28, 0x5C, 0xD9 - }, - { - 0xB3, 0x21, 0x63, 0xE7, 0xC5, 0xDB, 0xB5, 0xF5, - 0x1F, 0xDC, 0x11, 0xD2, 0xEA, 0xC8, 0x75, 0xEF, - 0xBB, 0xCB, 0x7E, 0x76, 0x99, 0x09, 0x0A, 0x7E, - 0x7F, 0xF8, 0xA8, 0xD5, 0x07, 0x95, 0xAF, 0x5D, - 0x74, 0xD9, 0xFF, 0x98, 0x54, 0x3E, 0xF8, 0xCD, - 0xF8, 0x9A, 0xC1, 0x3D, 0x04, 0x85, 0x27, 0x87, - 0x56, 0xE0, 0xEF, 0x00, 0xC8, 0x17, 0x74, 0x56, - 0x61, 0xE1, 0xD5, 0x9F, 0xE3, 0x8E, 0x75, 0x37 - }, - { - 0x10, 0x85, 0xD7, 0x83, 0x07, 0xB1, 0xC4, 0xB0, - 0x08, 0xC5, 0x7A, 0x2E, 0x7E, 0x5B, 0x23, 0x46, - 0x58, 0xA0, 0xA8, 0x2E, 0x4F, 0xF1, 0xE4, 0xAA, - 0xAC, 0x72, 0xB3, 0x12, 0xFD, 0xA0, 0xFE, 0x27, - 0xD2, 0x33, 0xBC, 0x5B, 0x10, 0xE9, 0xCC, 0x17, - 0xFD, 0xC7, 0x69, 0x7B, 0x54, 0x0C, 0x7D, 0x95, - 0xEB, 0x21, 0x5A, 0x19, 0xA1, 0xA0, 0xE2, 0x0E, - 0x1A, 0xBF, 0xA1, 0x26, 0xEF, 0xD5, 0x68, 0xC7 - }, - { - 0x4E, 0x5C, 0x73, 0x4C, 0x7D, 0xDE, 0x01, 0x1D, - 0x83, 0xEA, 0xC2, 0xB7, 0x34, 0x7B, 0x37, 0x35, - 0x94, 0xF9, 0x2D, 0x70, 0x91, 0xB9, 0xCA, 0x34, - 0xCB, 0x9C, 0x6F, 0x39, 0xBD, 0xF5, 0xA8, 0xD2, - 0xF1, 0x34, 0x37, 0x9E, 0x16, 0xD8, 0x22, 0xF6, - 0x52, 0x21, 0x70, 0xCC, 0xF2, 0xDD, 0xD5, 0x5C, - 0x84, 0xB9, 0xE6, 0xC6, 0x4F, 0xC9, 0x27, 0xAC, - 0x4C, 0xF8, 0xDF, 0xB2, 0xA1, 0x77, 0x01, 0xF2 - }, - { - 0x69, 0x5D, 0x83, 0xBD, 0x99, 0x0A, 0x11, 0x17, - 0xB3, 0xD0, 0xCE, 0x06, 0xCC, 0x88, 0x80, 0x27, - 0xD1, 0x2A, 0x05, 0x4C, 0x26, 0x77, 0xFD, 0x82, - 0xF0, 0xD4, 0xFB, 0xFC, 0x93, 0x57, 0x55, 0x23, - 0xE7, 0x99, 0x1A, 0x5E, 0x35, 0xA3, 0x75, 0x2E, - 0x9B, 0x70, 0xCE, 0x62, 0x99, 0x2E, 0x26, 0x8A, - 0x87, 0x77, 0x44, 0xCD, 0xD4, 0x35, 0xF5, 0xF1, - 0x30, 0x86, 0x9C, 0x9A, 0x20, 0x74, 0xB3, 0x38 - }, - { - 0xA6, 0x21, 0x37, 0x43, 0x56, 0x8E, 0x3B, 0x31, - 0x58, 0xB9, 0x18, 0x43, 0x01, 0xF3, 0x69, 0x08, - 0x47, 0x55, 0x4C, 0x68, 0x45, 0x7C, 0xB4, 0x0F, - 0xC9, 0xA4, 0xB8, 0xCF, 0xD8, 0xD4, 0xA1, 0x18, - 0xC3, 0x01, 0xA0, 0x77, 0x37, 0xAE, 0xDA, 0x0F, - 0x92, 0x9C, 0x68, 0x91, 0x3C, 0x5F, 0x51, 0xC8, - 0x03, 0x94, 0xF5, 0x3B, 0xFF, 0x1C, 0x3E, 0x83, - 0xB2, 0xE4, 0x0C, 0xA9, 0x7E, 0xBA, 0x9E, 0x15 - }, - { - 0xD4, 0x44, 0xBF, 0xA2, 0x36, 0x2A, 0x96, 0xDF, - 0x21, 0x3D, 0x07, 0x0E, 0x33, 0xFA, 0x84, 0x1F, - 0x51, 0x33, 0x4E, 0x4E, 0x76, 0x86, 0x6B, 0x81, - 0x39, 0xE8, 0xAF, 0x3B, 0xB3, 0x39, 0x8B, 0xE2, - 0xDF, 0xAD, 0xDC, 0xBC, 0x56, 0xB9, 0x14, 0x6D, - 0xE9, 0xF6, 0x81, 0x18, 0xDC, 0x58, 0x29, 0xE7, - 0x4B, 0x0C, 0x28, 0xD7, 0x71, 0x19, 0x07, 0xB1, - 0x21, 0xF9, 0x16, 0x1C, 0xB9, 0x2B, 0x69, 0xA9 - }, - { - 0x14, 0x27, 0x09, 0xD6, 0x2E, 0x28, 0xFC, 0xCC, - 0xD0, 0xAF, 0x97, 0xFA, 0xD0, 0xF8, 0x46, 0x5B, - 0x97, 0x1E, 0x82, 0x20, 0x1D, 0xC5, 0x10, 0x70, - 0xFA, 0xA0, 0x37, 0x2A, 0xA4, 0x3E, 0x92, 0x48, - 0x4B, 0xE1, 0xC1, 0xE7, 0x3B, 0xA1, 0x09, 0x06, - 0xD5, 0xD1, 0x85, 0x3D, 0xB6, 0xA4, 0x10, 0x6E, - 0x0A, 0x7B, 0xF9, 0x80, 0x0D, 0x37, 0x3D, 0x6D, - 0xEE, 0x2D, 0x46, 0xD6, 0x2E, 0xF2, 0xA4, 0x61 - }, -}; - - - - -static const uint8_t blake2sp_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = -{ - { - 0xDD, 0x0E, 0x89, 0x17, 0x76, 0x93, 0x3F, 0x43, - 0xC7, 0xD0, 0x32, 0xB0, 0x8A, 0x91, 0x7E, 0x25, - 0x74, 0x1F, 0x8A, 0xA9, 0xA1, 0x2C, 0x12, 0xE1, - 0xCA, 0xC8, 0x80, 0x15, 0x00, 0xF2, 0xCA, 0x4F - }, - { - 0xA6, 0xB9, 0xEE, 0xCC, 0x25, 0x22, 0x7A, 0xD7, - 0x88, 0xC9, 0x9D, 0x3F, 0x23, 0x6D, 0xEB, 0xC8, - 0xDA, 0x40, 0x88, 0x49, 0xE9, 0xA5, 0x17, 0x89, - 0x78, 0x72, 0x7A, 0x81, 0x45, 0x7F, 0x72, 0x39 - }, - { - 0xDA, 0xCA, 0xDE, 0xCE, 0x7A, 0x8E, 0x6B, 0xF3, - 0xAB, 0xFE, 0x32, 0x4C, 0xA6, 0x95, 0x43, 0x69, - 0x84, 0xB8, 0x19, 0x5D, 0x29, 0xF6, 0xBB, 0xD8, - 0x96, 0xE4, 0x1E, 0x18, 0xE2, 0x1C, 0x91, 0x45 - }, - { - 0xED, 0x14, 0x41, 0x3B, 0x40, 0xDA, 0x68, 0x9F, - 0x1F, 0x7F, 0xED, 0x2B, 0x08, 0xDF, 0xF4, 0x5B, - 0x80, 0x92, 0xDB, 0x5E, 0xC2, 0xC3, 0x61, 0x0E, - 0x02, 0x72, 0x4D, 0x20, 0x2F, 0x42, 0x3C, 0x46 - }, - { - 0x9B, 0x8A, 0x52, 0x7B, 0x52, 0x72, 0x25, 0x0A, - 0x1E, 0xC3, 0x97, 0x38, 0x8F, 0x04, 0x09, 0x14, - 0x95, 0x48, 0x06, 0xE7, 0x94, 0xDB, 0x04, 0xB7, - 0x0A, 0x46, 0x11, 0xBC, 0x59, 0x58, 0x6A, 0x83 - }, - { - 0x2B, 0xB6, 0x33, 0x37, 0x29, 0x00, 0x0B, 0xE3, - 0xD5, 0xA2, 0x1B, 0x98, 0xF8, 0xE7, 0xEA, 0xD0, - 0x77, 0xF1, 0x51, 0xA5, 0x39, 0x39, 0x19, 0xEB, - 0x67, 0xC8, 0x76, 0xEE, 0x00, 0xBB, 0xBB, 0x04 - }, - { - 0x63, 0xC0, 0x14, 0x08, 0x15, 0x4A, 0xD1, 0x9D, - 0x7F, 0xB7, 0x39, 0xF3, 0x11, 0x78, 0x17, 0x80, - 0x46, 0x2C, 0xF2, 0xEE, 0xCC, 0xE6, 0x0F, 0x06, - 0x4E, 0x85, 0x34, 0x87, 0xC2, 0x72, 0xE3, 0xEB - }, - { - 0x3D, 0x05, 0x1A, 0x11, 0x76, 0x01, 0x9C, 0xA3, - 0x7B, 0xF3, 0x3D, 0x60, 0x42, 0x7F, 0x8D, 0x9D, - 0x1C, 0x3A, 0xBD, 0x59, 0x82, 0x97, 0xCF, 0xB4, - 0x23, 0x5F, 0x74, 0x7D, 0x7C, 0x7C, 0x7F, 0xEC - }, - { - 0x39, 0x1E, 0xA9, 0x12, 0xDF, 0x4D, 0x4D, 0x79, - 0xA4, 0x64, 0x6D, 0x9D, 0xA2, 0x54, 0x9A, 0x44, - 0x6D, 0x22, 0x40, 0xF6, 0x24, 0x15, 0xD0, 0x70, - 0xA2, 0xE0, 0x93, 0x99, 0x2B, 0x47, 0x1F, 0xBA - }, - { - 0x32, 0x46, 0x40, 0x44, 0x0E, 0xA5, 0xC3, 0x08, - 0x2D, 0xDC, 0x30, 0x9E, 0x78, 0x09, 0xD7, 0x41, - 0xD6, 0xCC, 0x1B, 0x2D, 0x49, 0x0F, 0xF8, 0xC0, - 0x52, 0x12, 0x8A, 0x6E, 0xEB, 0x40, 0x9D, 0x62 - }, - { - 0xAB, 0x85, 0x5E, 0x6F, 0xA3, 0x9A, 0x5E, 0x8F, - 0xC9, 0x0E, 0xAC, 0xB9, 0x99, 0xC7, 0xF7, 0x8A, - 0xE7, 0x1E, 0x59, 0xC3, 0xD9, 0x7D, 0x60, 0xAF, - 0xE5, 0x17, 0xD5, 0x87, 0x92, 0x3B, 0x77, 0x11 - }, - { - 0x2A, 0x39, 0xDA, 0x45, 0x86, 0xEF, 0xC4, 0x77, - 0x85, 0xA7, 0xA8, 0xDA, 0x85, 0x68, 0x3A, 0x51, - 0x72, 0x4C, 0xDE, 0xF5, 0x41, 0x3B, 0x35, 0x6D, - 0xC4, 0xFB, 0x50, 0x05, 0x13, 0xF8, 0xFA, 0x2E - }, - { - 0x8A, 0x00, 0x57, 0xC1, 0xF7, 0x8A, 0xD6, 0x21, - 0x45, 0x55, 0xC0, 0x67, 0x07, 0x33, 0xE2, 0x9A, - 0x4C, 0x7E, 0x95, 0x62, 0x27, 0x66, 0x0E, 0xFE, - 0xB1, 0xD7, 0xFC, 0x79, 0xF5, 0x8E, 0xC6, 0xF2 - }, - { - 0x07, 0x64, 0xB0, 0x01, 0x7F, 0x5B, 0xD9, 0x51, - 0xF0, 0x1D, 0x9F, 0xDF, 0x95, 0xC0, 0xCB, 0x41, - 0x38, 0x98, 0x5D, 0x84, 0x79, 0x9C, 0xD4, 0x29, - 0x84, 0xE2, 0x5B, 0x51, 0x28, 0x00, 0xE7, 0x3C - }, - { - 0xCC, 0x02, 0x49, 0x56, 0x93, 0xC8, 0xE1, 0x84, - 0xAD, 0x2E, 0xD0, 0x9D, 0x53, 0x3D, 0xC3, 0x3B, - 0x76, 0xA7, 0x78, 0x3D, 0x62, 0x07, 0xFC, 0xAC, - 0xCB, 0x64, 0xF3, 0xED, 0x2C, 0x6D, 0x66, 0xE0 - }, - { - 0xC0, 0xDF, 0x49, 0xC2, 0x06, 0xA3, 0x42, 0x88, - 0x14, 0x32, 0x16, 0x84, 0x7D, 0xF3, 0x34, 0xD4, - 0x56, 0x9D, 0xAD, 0x73, 0xC2, 0xB1, 0xFF, 0x62, - 0x84, 0x88, 0x4F, 0xD3, 0x89, 0x41, 0xFB, 0x95 - }, - { - 0xB9, 0x19, 0x45, 0x19, 0xE4, 0x97, 0x8A, 0x9D, - 0xC8, 0x93, 0xB2, 0x8B, 0xD8, 0x08, 0xCD, 0xFA, - 0xBB, 0x1B, 0xD5, 0x10, 0xD8, 0x62, 0xB3, 0x17, - 0x1F, 0xF6, 0xE0, 0x17, 0xA4, 0x1B, 0x80, 0x4C - }, - { - 0xBB, 0xA9, 0x27, 0xAC, 0xF1, 0x1B, 0xEB, 0xD3, - 0x62, 0xA3, 0xA3, 0xEB, 0x78, 0xC4, 0xBB, 0x65, - 0xE6, 0x02, 0xA8, 0x70, 0x9F, 0xCE, 0xF3, 0x8D, - 0xC6, 0xC8, 0xB7, 0xBD, 0xA6, 0x64, 0xC3, 0x2C - }, - { - 0xEC, 0xB4, 0x90, 0x0A, 0x63, 0x92, 0x4E, 0x72, - 0x0D, 0x40, 0xF2, 0xD2, 0xB1, 0x4D, 0x1B, 0xB3, - 0x9C, 0x37, 0x01, 0xAD, 0x73, 0x46, 0xBD, 0x0B, - 0x67, 0x23, 0x42, 0x70, 0xBF, 0xBE, 0x7E, 0x70 - }, - { - 0xF8, 0x31, 0x5A, 0x21, 0xB2, 0x5E, 0x6B, 0xA8, - 0xBF, 0x59, 0xB1, 0x7B, 0x05, 0x91, 0x3B, 0x8C, - 0xA4, 0x65, 0x9F, 0x1C, 0xD8, 0x38, 0xFC, 0xC7, - 0x73, 0xC9, 0xEB, 0x12, 0xE7, 0x00, 0x4E, 0x09 - }, - { - 0x4B, 0x77, 0xAF, 0x67, 0xA9, 0x23, 0x2B, 0xF1, - 0x18, 0x4E, 0x57, 0x81, 0x82, 0x94, 0x03, 0x1E, - 0x55, 0xF1, 0xF8, 0x53, 0xC9, 0x4D, 0xBA, 0xB5, - 0x57, 0x75, 0x47, 0x33, 0x0D, 0x65, 0xAA, 0x61 - }, - { - 0x76, 0x85, 0x68, 0x39, 0x0F, 0xD2, 0xB8, 0x70, - 0x94, 0x11, 0x4E, 0xD4, 0xCF, 0x72, 0x3E, 0xA3, - 0x20, 0xFE, 0x97, 0x7B, 0x53, 0x18, 0x03, 0x05, - 0xC3, 0x84, 0x33, 0x54, 0x79, 0xF0, 0xB5, 0x9B - }, - { - 0xA4, 0x31, 0xCB, 0x27, 0x0F, 0x3E, 0x2C, 0x9B, - 0x7A, 0x95, 0x93, 0xB1, 0x55, 0xCC, 0xEC, 0xFF, - 0x5B, 0x5C, 0x4A, 0x2D, 0xCD, 0x5D, 0x6B, 0xB1, - 0xC4, 0x85, 0xAA, 0x28, 0x69, 0x97, 0xF9, 0x15 - }, - { - 0xD6, 0x91, 0xFA, 0x6A, 0x79, 0x0B, 0x1A, 0x51, - 0x79, 0x80, 0x08, 0x7F, 0x50, 0xB0, 0x3D, 0xED, - 0x8C, 0x6E, 0xD4, 0x86, 0xD0, 0x84, 0x22, 0x1C, - 0x82, 0x7D, 0x9B, 0xD9, 0x22, 0xBE, 0xB8, 0xC0 - }, - { - 0x8F, 0x97, 0x8A, 0x49, 0x32, 0xF4, 0x45, 0x98, - 0x13, 0xE8, 0xFE, 0x15, 0x68, 0x6E, 0x4E, 0xFA, - 0x25, 0xC2, 0xC5, 0xFF, 0x5A, 0x3A, 0x4F, 0x8C, - 0x9B, 0x14, 0x96, 0x5D, 0x2F, 0x0B, 0xE4, 0x61 - }, - { - 0x1E, 0xFB, 0xD0, 0xC1, 0x31, 0x44, 0x91, 0x42, - 0xF2, 0x29, 0x5F, 0x2D, 0x42, 0x41, 0x1D, 0xFE, - 0x0F, 0x48, 0xD4, 0xAC, 0xAE, 0x76, 0x2D, 0x8D, - 0xF6, 0x7A, 0x57, 0x0B, 0xF7, 0xB1, 0xDC, 0xD5 - }, - { - 0xD5, 0x3B, 0xA9, 0x33, 0x46, 0x14, 0x3A, 0xB8, - 0xE0, 0xD3, 0xD1, 0xBF, 0x27, 0x27, 0x06, 0xD1, - 0x69, 0xE6, 0x6C, 0x69, 0xC7, 0xB8, 0xF4, 0xA5, - 0xE8, 0x2F, 0xEF, 0x44, 0x07, 0x02, 0xBC, 0xF2 - }, - { - 0xF7, 0x1A, 0x3E, 0xC0, 0x1A, 0xA3, 0x82, 0xEA, - 0x76, 0x99, 0x2B, 0x43, 0x0A, 0x7F, 0x42, 0xC7, - 0xAD, 0x2A, 0x86, 0xAE, 0xA9, 0xC1, 0x9E, 0x76, - 0xCD, 0x17, 0x32, 0xEC, 0x68, 0x30, 0xDE, 0x6F - }, - { - 0x80, 0xA6, 0xAB, 0x7B, 0x71, 0x04, 0x64, 0xF9, - 0x3E, 0x6C, 0xBA, 0x96, 0x86, 0x4A, 0xA6, 0x40, - 0x9B, 0xCA, 0xFC, 0x1B, 0xF4, 0xB3, 0x2A, 0x30, - 0x93, 0x72, 0xE8, 0x57, 0xE8, 0x04, 0x06, 0x8C - }, - { - 0xDB, 0xDE, 0x81, 0xE5, 0x1A, 0x52, 0x17, 0x4B, - 0x10, 0x14, 0x90, 0x1B, 0x53, 0xBE, 0xF8, 0x8D, - 0xE9, 0x3B, 0x29, 0xE2, 0x74, 0x34, 0x7E, 0x8E, - 0x9A, 0x7B, 0x03, 0x74, 0x56, 0x62, 0x9F, 0x35 - }, - { - 0x75, 0xF2, 0x74, 0x46, 0x6B, 0x1A, 0x2D, 0x0F, - 0xD8, 0x45, 0xBB, 0xB5, 0x7C, 0x38, 0xC9, 0x89, - 0x51, 0x6E, 0x15, 0x68, 0x32, 0x0A, 0xB5, 0x17, - 0xB1, 0x63, 0xEA, 0xF7, 0x09, 0x23, 0x4C, 0xC7 - }, - { - 0xAF, 0xE1, 0xA0, 0x59, 0x1C, 0x49, 0x1D, 0x41, - 0x6E, 0xB6, 0x4F, 0x62, 0x86, 0xF3, 0xBA, 0x29, - 0xD4, 0xC9, 0x99, 0x82, 0x14, 0xA3, 0x83, 0x1C, - 0x39, 0x01, 0x4A, 0xC0, 0x30, 0x55, 0x79, 0x45 - }, - { - 0x67, 0xFF, 0x6A, 0xCD, 0xBE, 0x8A, 0x99, 0xA1, - 0x66, 0xA5, 0xD9, 0xCF, 0x32, 0x13, 0x65, 0x06, - 0xB5, 0x48, 0xD6, 0xC9, 0x47, 0xC2, 0x4C, 0x69, - 0x9C, 0xEA, 0x3A, 0xFD, 0x92, 0xAD, 0xFA, 0xCA - }, - { - 0xBF, 0xB4, 0xD0, 0xC7, 0x11, 0x20, 0x75, 0x26, - 0x2C, 0x2D, 0xD2, 0x48, 0xF3, 0x34, 0xB2, 0xEF, - 0x15, 0x40, 0x08, 0x7E, 0xCC, 0x73, 0x82, 0xBC, - 0x2A, 0x27, 0x25, 0x75, 0xC5, 0x00, 0x9F, 0x70 - }, - { - 0x17, 0xC9, 0x4B, 0x9C, 0x53, 0x72, 0x43, 0xF2, - 0x33, 0x5B, 0x86, 0x39, 0x49, 0xB2, 0xB9, 0x1C, - 0x98, 0xA6, 0x95, 0x6D, 0x7C, 0x10, 0xAA, 0x98, - 0x99, 0x59, 0xA8, 0x0F, 0x91, 0x0C, 0x25, 0x22 - }, - { - 0xF6, 0x33, 0x8F, 0x43, 0x4D, 0x31, 0x94, 0x10, - 0x19, 0x6D, 0x95, 0x19, 0xAB, 0xCA, 0xEF, 0xF7, - 0xD5, 0x54, 0x39, 0xFD, 0x2A, 0xA5, 0xBA, 0xBF, - 0x7A, 0x7E, 0x79, 0x13, 0xB2, 0x94, 0xED, 0x4D - }, - { - 0x08, 0xEF, 0x7D, 0x65, 0xF9, 0xBB, 0xF3, 0xDA, - 0x1F, 0x78, 0x84, 0xAE, 0x9B, 0x75, 0x90, 0x1F, - 0xD8, 0x52, 0x95, 0x66, 0x2A, 0x6E, 0xA7, 0x1D, - 0xE0, 0x8B, 0xEE, 0x38, 0x34, 0x57, 0x62, 0x78 - }, - { - 0x16, 0x47, 0xEC, 0xC2, 0xBA, 0x13, 0xF8, 0xB9, - 0x3B, 0x2F, 0xBC, 0xDC, 0x4E, 0x8F, 0x1D, 0xFA, - 0x47, 0xFE, 0x3B, 0xE1, 0x2A, 0xAA, 0x0E, 0x45, - 0x9B, 0x0E, 0x5A, 0x87, 0xF3, 0xA6, 0x9B, 0xB0 - }, - { - 0xFF, 0x92, 0x7A, 0x71, 0x78, 0x81, 0xF6, 0xFD, - 0x8E, 0xD8, 0xBF, 0x5D, 0x5E, 0x35, 0xBD, 0x80, - 0x16, 0x15, 0x73, 0xE5, 0x82, 0x94, 0x04, 0xC3, - 0x2D, 0x2A, 0x27, 0x6A, 0x01, 0xF4, 0xB9, 0x06 - }, - { - 0xC8, 0xCA, 0xF1, 0x36, 0xFF, 0x20, 0x9C, 0x82, - 0xE0, 0x24, 0x0C, 0x1E, 0x62, 0xA3, 0xBC, 0x7E, - 0x9C, 0xAC, 0x87, 0x3B, 0x01, 0x1C, 0xF7, 0xC5, - 0xE6, 0x7E, 0xC1, 0x87, 0xA5, 0xFB, 0xCD, 0x96 - }, - { - 0xD9, 0xAC, 0xC7, 0x3E, 0x3F, 0x42, 0x1E, 0x18, - 0x83, 0xB5, 0xED, 0x53, 0xD8, 0x2A, 0x9A, 0xEC, - 0x8F, 0x5D, 0xC9, 0x80, 0xC4, 0x2B, 0xCA, 0xEB, - 0x0E, 0x7D, 0x89, 0x76, 0xA3, 0x38, 0xEF, 0x51 - }, - { - 0x9F, 0x17, 0x3F, 0xCF, 0x08, 0xA5, 0x36, 0x21, - 0x93, 0xF3, 0x52, 0xC8, 0x25, 0x6A, 0xE5, 0x34, - 0xAE, 0x9C, 0xE7, 0xBF, 0xA4, 0xBC, 0x09, 0xFA, - 0xC9, 0x00, 0x98, 0xF9, 0x8A, 0x71, 0x62, 0x94 - }, - { - 0x0A, 0x72, 0x45, 0x79, 0xDC, 0x80, 0xBC, 0x0C, - 0x90, 0x04, 0xE5, 0x1B, 0xE7, 0xEF, 0xF3, 0xAF, - 0xA5, 0x30, 0x75, 0xAB, 0x4A, 0x32, 0x55, 0x77, - 0x33, 0x58, 0x6E, 0x82, 0x0F, 0xD3, 0x64, 0x23 - }, - { - 0x38, 0xF7, 0xC3, 0x40, 0xF4, 0xB1, 0x59, 0xB1, - 0xE5, 0x94, 0xF6, 0xEB, 0x83, 0x28, 0x49, 0x17, - 0xB7, 0xAA, 0x19, 0xC7, 0x4F, 0x57, 0x11, 0x7A, - 0x4E, 0x08, 0xCF, 0x7C, 0x4E, 0x32, 0xA2, 0x3C - }, - { - 0x1C, 0x67, 0x4B, 0xE2, 0x57, 0xE9, 0xB3, 0x31, - 0x34, 0xD4, 0x16, 0x8F, 0x15, 0x2F, 0x8B, 0x63, - 0xDF, 0xD7, 0x80, 0xC9, 0x7D, 0xC4, 0xDC, 0x37, - 0xAC, 0x26, 0xCC, 0x0A, 0xEF, 0xB7, 0x9C, 0x1A - }, - { - 0x2F, 0x0C, 0x59, 0x76, 0x16, 0xD5, 0x75, 0x17, - 0x14, 0xA5, 0xFB, 0x4E, 0xBF, 0x3C, 0x48, 0x1A, - 0x96, 0xC3, 0xAD, 0x14, 0x5E, 0xBD, 0xE0, 0x65, - 0x09, 0xF3, 0xA2, 0xE5, 0xF2, 0xC1, 0x3F, 0xC8 - }, - { - 0xFD, 0xDC, 0x69, 0xE0, 0xC9, 0x83, 0xCD, 0x82, - 0x83, 0xED, 0x81, 0x88, 0xBE, 0xC4, 0xE5, 0xF4, - 0x1D, 0xEA, 0x3D, 0x01, 0xB9, 0xE7, 0x4C, 0x4B, - 0xAF, 0x73, 0x41, 0xD8, 0xB4, 0xBF, 0x55, 0x3D - }, - { - 0x24, 0xD0, 0x83, 0xCB, 0xA0, 0x38, 0xC8, 0x7E, - 0x9A, 0xCB, 0x86, 0x81, 0x82, 0x02, 0x08, 0xB7, - 0x5C, 0xB3, 0x29, 0x3A, 0x96, 0xC9, 0xEF, 0xA7, - 0x5D, 0x2C, 0x63, 0xF1, 0x6B, 0x85, 0xFE, 0x1E - }, - { - 0x7F, 0x6A, 0x64, 0x9C, 0xCA, 0x89, 0xB2, 0x53, - 0xFF, 0xBD, 0x20, 0xC0, 0x16, 0x98, 0x01, 0x00, - 0xA8, 0x7C, 0x16, 0x81, 0x09, 0x62, 0x8F, 0xCC, - 0x66, 0x52, 0x5D, 0x8B, 0xAA, 0xFE, 0x50, 0x5F - }, - { - 0x6D, 0xA3, 0x73, 0xB4, 0xC1, 0x87, 0x92, 0xB3, - 0x20, 0x9A, 0xDD, 0x15, 0xA5, 0x07, 0x4A, 0x1D, - 0x70, 0xC1, 0x0B, 0xB3, 0x94, 0x80, 0xCA, 0x3F, - 0xE5, 0xC4, 0x39, 0xD9, 0x5F, 0xC2, 0x86, 0xCA - }, - { - 0x27, 0x0A, 0xFF, 0xA6, 0x42, 0x6F, 0x1A, 0x51, - 0x5C, 0x9B, 0x76, 0xDF, 0xC2, 0x7D, 0x18, 0x1F, - 0xC2, 0xFD, 0x57, 0xD0, 0x82, 0xA3, 0xBA, 0x2C, - 0x1E, 0xEF, 0x07, 0x15, 0x33, 0xA6, 0xDF, 0xB7 - }, - { - 0xC2, 0x2E, 0x15, 0xCF, 0xC5, 0xA3, 0xD1, 0x4B, - 0x64, 0xD1, 0x31, 0xF3, 0x5F, 0xB3, 0x5D, 0xD5, - 0xE6, 0xC5, 0x7D, 0xC4, 0xAF, 0xC5, 0x52, 0x27, - 0x75, 0x01, 0xEC, 0xA7, 0x64, 0xDA, 0x74, 0xBF - }, - { - 0xAD, 0x68, 0x3E, 0x96, 0xB8, 0xAC, 0x65, 0x8C, - 0x4F, 0x3F, 0x10, 0xAD, 0x22, 0xD9, 0x9B, 0x07, - 0xCB, 0x5E, 0xF9, 0xE3, 0x1C, 0xBE, 0x11, 0xE7, - 0xF7, 0xDC, 0x29, 0xF2, 0xAE, 0xE5, 0x02, 0x4C - }, - { - 0x78, 0xD3, 0xCE, 0xDA, 0x1C, 0xE0, 0x52, 0x93, - 0xF4, 0x30, 0xF6, 0x16, 0x7B, 0x33, 0xC9, 0x9F, - 0x0B, 0x1D, 0x6D, 0xAD, 0xE5, 0x21, 0x43, 0xC2, - 0x92, 0x55, 0x77, 0xC0, 0xBA, 0x82, 0x53, 0xEB - }, - { - 0xE0, 0x06, 0x45, 0x63, 0x44, 0xF9, 0x0F, 0x50, - 0x1C, 0x25, 0x81, 0x3F, 0x9B, 0xE2, 0xA3, 0xF4, - 0x0B, 0x98, 0x74, 0xFA, 0x05, 0x63, 0x98, 0x1C, - 0xD4, 0x56, 0xEE, 0x8D, 0x44, 0x80, 0x7C, 0x93 - }, - { - 0x39, 0x08, 0xE8, 0xD5, 0x47, 0xC0, 0xAF, 0xB1, - 0x13, 0x49, 0x49, 0x46, 0x63, 0x04, 0xA1, 0x45, - 0x02, 0x7E, 0x6B, 0xB7, 0xA7, 0x4D, 0xD1, 0xC1, - 0x62, 0xCD, 0xF0, 0xBC, 0xF7, 0x72, 0x37, 0xE8 - }, - { - 0x1B, 0x6C, 0x87, 0xA3, 0x48, 0x38, 0xC7, 0xCD, - 0x5F, 0xD0, 0x89, 0x14, 0x22, 0x4E, 0x90, 0xC2, - 0x2A, 0xBF, 0x5A, 0x97, 0xB1, 0x06, 0x46, 0xD9, - 0x8C, 0x49, 0x16, 0xD3, 0xA8, 0x93, 0x9E, 0x62 - }, - { - 0xB0, 0xD3, 0x8F, 0x82, 0xF2, 0x48, 0x91, 0x69, - 0x52, 0xB3, 0x16, 0xB6, 0xD3, 0x6D, 0x9E, 0x02, - 0x2D, 0xF6, 0xEE, 0xCC, 0x26, 0xC7, 0x62, 0xA6, - 0x55, 0xCF, 0x5F, 0x0A, 0xE6, 0x49, 0xE2, 0xBD - }, - { - 0x8D, 0x66, 0xFC, 0x9C, 0xED, 0xA5, 0xED, 0xDF, - 0xB1, 0xE0, 0x4D, 0x09, 0x6C, 0xA7, 0x0E, 0xF5, - 0x06, 0x50, 0xFB, 0x87, 0xCC, 0x6A, 0x9F, 0xFB, - 0xB3, 0xD2, 0x0B, 0xCE, 0x7B, 0x5A, 0x60, 0x74 - }, - { - 0x06, 0x43, 0x54, 0xE8, 0xE1, 0x1C, 0xF7, 0x13, - 0xB2, 0xC7, 0x2B, 0xA6, 0x7A, 0xC7, 0xD7, 0x6E, - 0x41, 0xBA, 0x61, 0xDB, 0x9C, 0x2D, 0xEA, 0x52, - 0x2E, 0x0B, 0xDA, 0x17, 0xCB, 0xA5, 0xE3, 0x92 - }, - { - 0xC8, 0xEF, 0x5F, 0x49, 0x8B, 0xD1, 0xBC, 0x70, - 0x7F, 0xBC, 0x7B, 0x5C, 0xBC, 0x2D, 0xFF, 0x04, - 0x93, 0x14, 0x4A, 0xC5, 0x27, 0x86, 0xDB, 0x3C, - 0x79, 0x3E, 0xF4, 0xAE, 0x8A, 0x83, 0x88, 0x47 - }, - { - 0x8A, 0x23, 0x97, 0xDF, 0x31, 0xE7, 0xF0, 0xCC, - 0x29, 0x0D, 0xA9, 0xA8, 0xBB, 0xE4, 0xF5, 0xF7, - 0xA3, 0xA1, 0x37, 0x50, 0x73, 0x0D, 0xB6, 0x2D, - 0xC2, 0x54, 0x0F, 0xDB, 0xD6, 0x18, 0x85, 0x89 - }, - { - 0xF1, 0x2D, 0x0B, 0x13, 0xC6, 0xAD, 0xFB, 0x3B, - 0xE5, 0x0A, 0x51, 0xEB, 0x6B, 0xAF, 0x65, 0xAB, - 0xFB, 0x17, 0x00, 0xBA, 0xA8, 0x7E, 0x52, 0x7D, - 0xBE, 0x3E, 0x67, 0x5A, 0x7A, 0x99, 0x46, 0x61 - }, - { - 0x10, 0x24, 0xC9, 0x40, 0xBE, 0x73, 0x41, 0x44, - 0x9B, 0x50, 0x10, 0x52, 0x2B, 0x50, 0x9F, 0x65, - 0xBB, 0xDC, 0x12, 0x87, 0xB4, 0x55, 0xC2, 0xBB, - 0x7F, 0x72, 0xB2, 0xC9, 0x2F, 0xD0, 0xD1, 0x89 - }, - { - 0x52, 0x60, 0x3B, 0x6C, 0xBF, 0xAD, 0x49, 0x66, - 0xCB, 0x04, 0x4C, 0xB2, 0x67, 0x56, 0x83, 0x85, - 0xCF, 0x35, 0xF2, 0x1E, 0x6C, 0x45, 0xCF, 0x30, - 0xAE, 0xD1, 0x98, 0x32, 0xCB, 0x51, 0xE9, 0xF5 - }, - { - 0xFF, 0xF2, 0x4D, 0x3C, 0xC7, 0x29, 0xD3, 0x95, - 0xDA, 0xF9, 0x78, 0xB0, 0x15, 0x73, 0x06, 0xCB, - 0x49, 0x57, 0x97, 0xE6, 0xC8, 0xDC, 0xA1, 0x73, - 0x1D, 0x2F, 0x6F, 0x81, 0xB8, 0x49, 0xBA, 0xAE - }, - { - 0x41, 0xEE, 0xE9, 0x0D, 0x47, 0xEC, 0x27, 0x72, - 0xCD, 0x35, 0x2D, 0xFD, 0x67, 0xE0, 0x60, 0x5F, - 0xBD, 0xFC, 0x5F, 0xD6, 0xD8, 0x26, 0x45, 0x1E, - 0x3D, 0x06, 0x4D, 0x38, 0x28, 0xBD, 0x3B, 0xAE - }, - { - 0x30, 0x0B, 0x6B, 0x36, 0xE5, 0x9F, 0x85, 0x1D, - 0xDD, 0xC2, 0x9B, 0xFA, 0x93, 0x08, 0x25, 0x20, - 0xCD, 0x77, 0xC5, 0x1E, 0x00, 0x7E, 0x00, 0xD2, - 0xD7, 0x8B, 0x26, 0xF4, 0xAF, 0x96, 0x15, 0x32 - }, - { - 0x9E, 0xF3, 0x03, 0x14, 0x83, 0x4E, 0x40, 0x1C, - 0x87, 0x1A, 0x20, 0x04, 0xE3, 0x8D, 0x5C, 0xE3, - 0x2E, 0xD2, 0x8E, 0x11, 0x37, 0xF1, 0x97, 0x0F, - 0x4F, 0x43, 0x78, 0xC7, 0x37, 0x06, 0x76, 0x3D - }, - { - 0x3F, 0xBD, 0xCD, 0xE7, 0xB6, 0x43, 0x04, 0x02, - 0x5E, 0xC0, 0x58, 0x26, 0x09, 0x03, 0x1E, 0xC2, - 0x66, 0xD5, 0x0F, 0x56, 0x83, 0x5A, 0xE0, 0xCB, - 0x72, 0xD8, 0xCD, 0xB4, 0xCF, 0xAF, 0x44, 0x19 - }, - { - 0xE9, 0x0E, 0xAD, 0x3B, 0x98, 0x2B, 0x43, 0x5B, - 0x66, 0x36, 0x6A, 0x49, 0x6C, 0x3F, 0x8A, 0xE6, - 0x5B, 0x17, 0x61, 0x37, 0x00, 0xF5, 0x47, 0x67, - 0x3F, 0x62, 0x15, 0x35, 0x41, 0x91, 0x28, 0x64 - }, - { - 0xAB, 0xE3, 0x54, 0x7B, 0x33, 0x6D, 0x6E, 0x24, - 0x0D, 0x7F, 0xE6, 0x82, 0xD7, 0x4B, 0x9C, 0xC7, - 0xE8, 0xD7, 0xF9, 0xB5, 0x66, 0x48, 0x58, 0xB9, - 0x4D, 0xF5, 0x9E, 0x9F, 0xC3, 0x30, 0xD9, 0xE5 - }, - { - 0xB2, 0x99, 0x64, 0x20, 0x95, 0xB8, 0x28, 0x6C, - 0x52, 0x1C, 0xDB, 0x21, 0xED, 0x0F, 0xE0, 0x57, - 0x27, 0x80, 0x21, 0xBB, 0x40, 0x38, 0xEB, 0x5A, - 0x3D, 0x79, 0x54, 0x2F, 0x5D, 0x75, 0x1F, 0x54 - }, - { - 0xE4, 0xD7, 0x58, 0x35, 0x9F, 0x08, 0x67, 0x93, - 0xA8, 0x37, 0x54, 0xAC, 0xA6, 0x96, 0x8C, 0x3E, - 0x9F, 0xD9, 0x4B, 0x40, 0x49, 0x7F, 0x2E, 0xC2, - 0x24, 0xA2, 0x91, 0x60, 0x63, 0xA2, 0x14, 0xA3 - }, - { - 0x59, 0xA3, 0x04, 0xFC, 0x03, 0xAB, 0x75, 0xD5, - 0x57, 0xDB, 0x04, 0xEB, 0xD0, 0x2D, 0xD4, 0xC6, - 0xB8, 0x10, 0xA1, 0x38, 0xBB, 0xFE, 0xEA, 0x5D, - 0xFC, 0xEE, 0xAA, 0x2B, 0x75, 0xB0, 0x64, 0x91 - }, - { - 0x39, 0x95, 0x10, 0x22, 0x15, 0xF5, 0xFE, 0x92, - 0x10, 0xEB, 0x30, 0xD9, 0x52, 0xD8, 0xC9, 0x19, - 0x58, 0x9E, 0x71, 0x45, 0xFC, 0xD4, 0x95, 0xEA, - 0x78, 0xD0, 0x2B, 0x9C, 0x14, 0x8F, 0xAF, 0x09 - }, - { - 0x47, 0x2E, 0xE7, 0x11, 0x56, 0x35, 0x06, 0xA5, - 0xF0, 0x08, 0x3F, 0xE8, 0x2B, 0x08, 0xB9, 0x92, - 0x3C, 0xF6, 0xC8, 0x40, 0x4D, 0x0C, 0xBA, 0xCB, - 0xF8, 0x48, 0x64, 0xF6, 0x48, 0x54, 0x2A, 0xC0 - }, - { - 0x68, 0xFD, 0xB8, 0x2A, 0xDA, 0xE7, 0x9B, 0xEF, - 0x59, 0x0A, 0xBA, 0x62, 0xD7, 0xAC, 0x55, 0x32, - 0x12, 0x06, 0x1C, 0x36, 0xE3, 0x6F, 0x12, 0xC0, - 0xEF, 0xA2, 0x9A, 0x17, 0x62, 0xDE, 0x3B, 0x6A - }, - { - 0x75, 0x85, 0xC0, 0x77, 0x33, 0x83, 0xF1, 0x74, - 0xFD, 0x66, 0x65, 0x49, 0xA8, 0x35, 0x2B, 0x30, - 0x5B, 0xF6, 0x85, 0x5B, 0xC9, 0x8B, 0xEA, 0x28, - 0xC3, 0x91, 0xB3, 0xC0, 0x34, 0xDA, 0x5A, 0x5A - }, - { - 0xAC, 0xC5, 0x75, 0xFE, 0x2C, 0xD7, 0xBA, 0x2A, - 0x31, 0xFC, 0x7D, 0x67, 0x0A, 0x92, 0x34, 0xAF, - 0x68, 0x50, 0x33, 0x86, 0xE9, 0x59, 0x07, 0x3D, - 0x16, 0xA8, 0x1B, 0x33, 0xB9, 0x22, 0xB5, 0x0E - }, - { - 0x9E, 0xC7, 0xD2, 0x99, 0x59, 0x43, 0xD3, 0x9D, - 0x6B, 0x97, 0x14, 0x93, 0xB8, 0x97, 0xA0, 0xEE, - 0x2D, 0x33, 0x92, 0xA7, 0x2D, 0xB8, 0x75, 0xC2, - 0x40, 0x5D, 0x35, 0x71, 0x78, 0xFB, 0x69, 0x11 - }, - { - 0x2D, 0x7E, 0xF1, 0x94, 0x01, 0x42, 0x5A, 0xBA, - 0x45, 0x0E, 0x82, 0xD3, 0x6D, 0x0F, 0xE7, 0xB2, - 0x08, 0x5E, 0xA0, 0xAF, 0x60, 0x45, 0xA5, 0x99, - 0x4C, 0xF4, 0x31, 0xEA, 0x59, 0x93, 0x9C, 0xC9 - }, - { - 0xF3, 0x2F, 0xD8, 0x55, 0xF0, 0x11, 0xC7, 0x18, - 0x02, 0x7F, 0x2E, 0xBE, 0x37, 0x7D, 0x69, 0x39, - 0xF1, 0x23, 0x70, 0xCA, 0xFF, 0x15, 0x1C, 0x1E, - 0x5A, 0xCE, 0x43, 0x8D, 0x70, 0x3C, 0x6D, 0x9F - }, - { - 0xB2, 0xBD, 0x83, 0xD2, 0x31, 0x0D, 0x3D, 0x7B, - 0x1D, 0x2D, 0x5A, 0xAF, 0x43, 0x59, 0xFA, 0xE2, - 0x86, 0x12, 0x96, 0x27, 0x19, 0xFD, 0xDE, 0x4D, - 0xDA, 0xF6, 0x9E, 0x78, 0x20, 0xF3, 0x3F, 0x61 - }, - { - 0x1A, 0x7A, 0x9D, 0x0F, 0x44, 0xDD, 0xFA, 0x7F, - 0xC2, 0xF4, 0x77, 0x0C, 0xAD, 0x74, 0x22, 0xFA, - 0x6C, 0x4E, 0x37, 0xE6, 0xCB, 0x03, 0x6D, 0x89, - 0x9E, 0x10, 0x27, 0x50, 0xE5, 0x94, 0xFF, 0xCD - }, - { - 0xDC, 0x69, 0xF6, 0x14, 0x1C, 0x8E, 0x10, 0x3F, - 0xF6, 0x1F, 0x62, 0x98, 0xA2, 0xC4, 0x4F, 0x52, - 0xD1, 0x47, 0x36, 0x6D, 0xDB, 0xD9, 0xC7, 0x9C, - 0xC3, 0x08, 0xFE, 0x84, 0x33, 0x6A, 0x95, 0x64 - }, - { - 0xE3, 0x4E, 0xD4, 0x17, 0xB0, 0x79, 0x1D, 0x9A, - 0x77, 0xEE, 0x1E, 0x50, 0xCC, 0x2C, 0x20, 0x7E, - 0x54, 0x0C, 0x77, 0x14, 0x04, 0x21, 0xC4, 0x6C, - 0xE0, 0x86, 0x28, 0x78, 0xAA, 0xEB, 0x27, 0x09 - }, - { - 0x21, 0x74, 0x42, 0x5C, 0x8C, 0xCA, 0xE3, 0x98, - 0xC4, 0xFF, 0x06, 0xF8, 0x48, 0x99, 0x1C, 0x5E, - 0x9B, 0xC0, 0xF3, 0x46, 0x11, 0x11, 0x70, 0x6F, - 0xB9, 0x5D, 0x0B, 0xE1, 0xC6, 0x8E, 0x47, 0x60 - }, - { - 0x18, 0x94, 0x58, 0x2A, 0x8A, 0x25, 0xFE, 0x8F, - 0x84, 0x7A, 0x4A, 0x03, 0x25, 0x74, 0xB7, 0x7B, - 0x8B, 0x36, 0xBF, 0x19, 0x99, 0x75, 0x26, 0xBB, - 0x4B, 0xC8, 0x5F, 0x38, 0x24, 0x53, 0x7F, 0xEB - }, - { - 0x17, 0xED, 0x18, 0x8A, 0xE3, 0xC9, 0x53, 0xD6, - 0x55, 0x44, 0x59, 0x83, 0xB8, 0x32, 0x5B, 0xAF, - 0xFF, 0x32, 0xE2, 0x22, 0xB2, 0xDF, 0xEB, 0x16, - 0xE8, 0x61, 0x7A, 0xBF, 0x86, 0xEE, 0x7C, 0xC5 - }, - { - 0xF1, 0x48, 0x9A, 0xD1, 0xC3, 0x54, 0xCD, 0xE9, - 0x78, 0x92, 0x37, 0xEA, 0x6D, 0xBF, 0x67, 0xFC, - 0x1E, 0x44, 0xD1, 0xAC, 0xC8, 0xDC, 0x66, 0xAD, - 0x83, 0x87, 0x27, 0xF4, 0x7D, 0x9A, 0x91, 0xFE - }, - { - 0x36, 0x7F, 0x22, 0x16, 0x5B, 0x8B, 0x66, 0xE9, - 0x7F, 0x66, 0x70, 0xF3, 0x4E, 0xBA, 0x27, 0x49, - 0xD2, 0x64, 0x3B, 0x21, 0xBE, 0xAD, 0xAD, 0xFE, - 0xFE, 0xA2, 0x57, 0x4B, 0x7C, 0x9B, 0x21, 0x96 - }, - { - 0x3D, 0x8D, 0xFE, 0xA1, 0x7E, 0xEA, 0x5D, 0x64, - 0x5A, 0xC1, 0xD4, 0x1A, 0x5B, 0x59, 0x22, 0x6C, - 0x48, 0x6C, 0x36, 0xBD, 0x77, 0xED, 0x44, 0xBB, - 0x34, 0x91, 0x70, 0xD0, 0x80, 0xE3, 0x0E, 0x68 - }, - { - 0x41, 0x15, 0xF8, 0x9E, 0x0B, 0x3B, 0x5C, 0x8F, - 0x61, 0x22, 0xC0, 0x25, 0x00, 0x17, 0x1D, 0xCF, - 0xFB, 0xCE, 0xA4, 0x66, 0x2A, 0x8C, 0x5F, 0x8C, - 0x1C, 0x01, 0xA9, 0xCA, 0x7B, 0x10, 0x27, 0xBB - }, - { - 0xED, 0x6E, 0x91, 0x0B, 0x96, 0x02, 0x55, 0xD7, - 0xD7, 0x92, 0xEB, 0xE6, 0x7F, 0x26, 0x0A, 0x14, - 0x3C, 0xFA, 0xC1, 0x05, 0x1D, 0xFC, 0x05, 0x90, - 0x25, 0xEE, 0x0C, 0x1B, 0xFC, 0xBC, 0x56, 0x81 - }, - { - 0x55, 0x8F, 0xA8, 0xAF, 0xA1, 0x2B, 0xBE, 0xE5, - 0x4A, 0xF7, 0x8F, 0x6B, 0x74, 0x45, 0xF9, 0x96, - 0x65, 0xD4, 0xE3, 0x56, 0xBC, 0x07, 0xD3, 0xEF, - 0xFD, 0x8F, 0xD6, 0x5A, 0xB9, 0xC7, 0x47, 0x16 - }, - { - 0x5B, 0x60, 0x12, 0x76, 0x20, 0x53, 0xB8, 0x73, - 0x4A, 0xF0, 0xE5, 0x55, 0xE6, 0xA2, 0xBB, 0x4F, - 0xD4, 0x84, 0x0A, 0xF3, 0xB0, 0x4F, 0xCF, 0x63, - 0x50, 0xA2, 0xB8, 0xA5, 0x1B, 0x67, 0x96, 0xAD - }, - { - 0xAB, 0x7A, 0xCC, 0xA5, 0xD7, 0x77, 0x10, 0xBA, - 0xD3, 0x7B, 0xA0, 0xFF, 0x4C, 0xEA, 0xE2, 0x7E, - 0x84, 0x71, 0x79, 0xF7, 0xFD, 0x7A, 0xEC, 0x88, - 0x69, 0xC6, 0x49, 0xB3, 0x3F, 0x8D, 0x25, 0x77 - }, - { - 0xFF, 0x77, 0x30, 0xB4, 0x74, 0xEC, 0x21, 0x45, - 0xA9, 0x2D, 0xD1, 0xCF, 0xFE, 0x45, 0xC3, 0x42, - 0xC6, 0xFD, 0x6B, 0xAC, 0x58, 0x0F, 0xF9, 0x5A, - 0x75, 0xED, 0xA3, 0xBF, 0x90, 0xEB, 0x4F, 0x01 - }, - { - 0xD1, 0x0F, 0x06, 0x1D, 0x5B, 0x9C, 0xB4, 0x4E, - 0xE0, 0x78, 0xA9, 0x6B, 0x33, 0x18, 0x57, 0x9E, - 0x5E, 0xF5, 0x0A, 0xEF, 0x3E, 0xD9, 0x6E, 0x4F, - 0x62, 0x14, 0x9B, 0x2E, 0x9F, 0x7C, 0x66, 0x0C - }, - { - 0x67, 0xD2, 0x2B, 0x8E, 0xDF, 0x20, 0x01, 0xD8, - 0x64, 0x22, 0x13, 0x6A, 0xC6, 0x51, 0x6C, 0xF3, - 0x9F, 0x7F, 0xC6, 0xA7, 0x02, 0x98, 0x92, 0xFD, - 0x75, 0xC9, 0x87, 0x90, 0x96, 0x4A, 0x72, 0x0B - }, - { - 0x7A, 0x5E, 0xC5, 0xBA, 0x76, 0x25, 0x9B, 0x07, - 0xB4, 0xDA, 0x03, 0xF3, 0x81, 0xFE, 0x7B, 0xEA, - 0x48, 0x65, 0xC8, 0x6C, 0x42, 0x4A, 0xBA, 0xA0, - 0xDD, 0x1E, 0xCF, 0x74, 0xF8, 0x7D, 0x2A, 0xC0 - }, - { - 0xE0, 0xFF, 0x60, 0xD6, 0x90, 0x29, 0xE6, 0xBD, - 0x1C, 0x15, 0x95, 0x3E, 0x91, 0x50, 0x9C, 0x0C, - 0x59, 0xED, 0x5D, 0xA5, 0x00, 0x01, 0x99, 0xF2, - 0x16, 0xD2, 0x9F, 0x96, 0x07, 0x9C, 0x2F, 0xEF - }, - { - 0xFC, 0x13, 0xEA, 0xD8, 0x41, 0x01, 0x8F, 0x59, - 0x90, 0x3B, 0x40, 0xF2, 0x02, 0x0C, 0x66, 0x38, - 0xA6, 0x6A, 0x54, 0xC3, 0xA3, 0x38, 0x41, 0x4D, - 0x97, 0xA5, 0xC3, 0x94, 0xF3, 0x26, 0x6F, 0x33 - }, - { - 0x0C, 0x2F, 0x62, 0xB8, 0x98, 0xFB, 0x2F, 0x63, - 0x61, 0x7E, 0x78, 0x73, 0x45, 0x26, 0x3C, 0xB9, - 0xCF, 0x60, 0x65, 0x4B, 0x55, 0x3B, 0x20, 0x3E, - 0xE4, 0x9D, 0xCB, 0xB8, 0xF2, 0xA6, 0xAF, 0xAC - }, - { - 0xD7, 0xD6, 0xCB, 0x55, 0x2A, 0xEB, 0x36, 0xEB, - 0x96, 0xB1, 0xD5, 0xE0, 0x52, 0xF8, 0xD9, 0x21, - 0xC3, 0x24, 0x5A, 0x97, 0x0D, 0x0B, 0xC8, 0x41, - 0x0C, 0xD6, 0x5E, 0xA1, 0x04, 0xC8, 0xE7, 0x79 - }, - { - 0xB7, 0x14, 0x1F, 0x30, 0x5E, 0xFD, 0xFE, 0xE5, - 0x56, 0xBD, 0x13, 0xE0, 0x40, 0x0D, 0x1E, 0x8C, - 0xFD, 0x65, 0x48, 0xBF, 0x81, 0xEE, 0x5D, 0x15, - 0x32, 0x7E, 0x49, 0x95, 0xCA, 0x8A, 0xD6, 0xFD - }, - { - 0xB6, 0xB6, 0x38, 0xD2, 0x2B, 0x7A, 0x12, 0x82, - 0x53, 0x74, 0xF7, 0x03, 0x48, 0xD7, 0x44, 0x8D, - 0x4E, 0x7D, 0x90, 0x8C, 0xF6, 0xE7, 0xBB, 0xEF, - 0x8C, 0x93, 0xEF, 0x67, 0x9B, 0x2A, 0x54, 0x78 - }, - { - 0x0D, 0xF4, 0x58, 0x56, 0x41, 0xFA, 0x09, 0xF6, - 0xCB, 0xA4, 0xCC, 0x16, 0x5A, 0x10, 0xAD, 0xDE, - 0x34, 0xF8, 0x0D, 0x42, 0x5A, 0x70, 0xDB, 0x67, - 0xE2, 0xFD, 0x23, 0x7B, 0x62, 0x7F, 0x43, 0x8A - }, - { - 0x10, 0x6B, 0x2B, 0x35, 0x4D, 0x95, 0xAC, 0xEC, - 0xD0, 0xD9, 0x58, 0x8F, 0xBC, 0x23, 0x1F, 0x8B, - 0xEA, 0x2E, 0x94, 0xEA, 0x66, 0x2D, 0xDD, 0x3F, - 0x13, 0x9E, 0x1B, 0x67, 0x87, 0x46, 0x1E, 0xED - }, - { - 0xAE, 0x5C, 0x69, 0xEE, 0xFE, 0x90, 0x89, 0xB2, - 0x9C, 0x6C, 0x1A, 0x23, 0x70, 0xD2, 0x05, 0x52, - 0xBA, 0x40, 0xC3, 0xD5, 0xE3, 0x71, 0x3C, 0x12, - 0xDE, 0xFC, 0xAE, 0x99, 0x7F, 0x43, 0x3E, 0xCD - }, - { - 0x1A, 0xAE, 0xF5, 0x5D, 0x4F, 0xA8, 0x92, 0xB6, - 0x35, 0xFB, 0x2A, 0x7A, 0x25, 0xF9, 0xA8, 0xE0, - 0x3B, 0x9F, 0xFB, 0x08, 0x2A, 0xE9, 0xC0, 0x7C, - 0x20, 0x42, 0xA0, 0x49, 0xC6, 0x51, 0x5E, 0x45 - }, - { - 0x29, 0x7D, 0xAA, 0xC4, 0xD5, 0x4D, 0xC4, 0x1C, - 0x83, 0xE3, 0x23, 0x94, 0x59, 0x9F, 0x17, 0x1C, - 0xDA, 0xA9, 0xDD, 0xB7, 0x17, 0x26, 0xDA, 0x4E, - 0xCE, 0x3C, 0xCF, 0x95, 0xC1, 0x1F, 0x56, 0xDF - }, - { - 0x2C, 0x45, 0xAC, 0xF4, 0x91, 0xEC, 0x2F, 0x4B, - 0x7E, 0x30, 0x9E, 0x7E, 0xDD, 0x81, 0x5B, 0xE5, - 0xA5, 0x4C, 0x44, 0x58, 0xD1, 0xA5, 0x7C, 0x4F, - 0x9B, 0x76, 0x3B, 0x0C, 0x67, 0x18, 0xD4, 0x3E - }, - { - 0x2F, 0x92, 0xF9, 0x01, 0x70, 0xD3, 0xAE, 0x95, - 0xAB, 0xFA, 0xC3, 0xA6, 0x98, 0x9A, 0x2A, 0x60, - 0xCB, 0x28, 0xB8, 0x58, 0x78, 0x2B, 0xE7, 0xEA, - 0x17, 0x9B, 0x48, 0xA7, 0x27, 0x6D, 0xD8, 0x60 - }, - { - 0xB4, 0x01, 0xE8, 0x4B, 0x15, 0xAC, 0xC4, 0x70, - 0x93, 0x6D, 0x6E, 0x37, 0xF7, 0x88, 0x83, 0x33, - 0x09, 0x27, 0x31, 0x13, 0x3B, 0x25, 0x1B, 0xEA, - 0x22, 0x16, 0x58, 0xCA, 0x19, 0xA7, 0x56, 0x69 - }, - { - 0xF8, 0xB3, 0x40, 0xD2, 0xB9, 0xB3, 0x3D, 0x43, - 0xA0, 0xA6, 0x6F, 0x34, 0x97, 0x82, 0x0A, 0xFA, - 0xAE, 0xE4, 0x34, 0xC4, 0xE3, 0xC0, 0xC1, 0x7E, - 0x89, 0x8B, 0x83, 0x01, 0xC5, 0x7A, 0x26, 0xBD - }, - { - 0x56, 0x6D, 0xA2, 0x83, 0x99, 0x03, 0x89, 0x13, - 0x8A, 0xA6, 0xF2, 0xAA, 0xA3, 0xB9, 0xE4, 0x0C, - 0xBF, 0x90, 0x84, 0x0E, 0xC7, 0x62, 0xBD, 0x96, - 0xB7, 0xE3, 0x3A, 0x31, 0x13, 0xB1, 0x01, 0x08 - }, - { - 0x34, 0x06, 0x72, 0xB7, 0x04, 0x67, 0x60, 0x42, - 0xC9, 0xBF, 0x3F, 0x33, 0x7B, 0xA7, 0x9F, 0x11, - 0x33, 0x6A, 0xEB, 0xB5, 0xEC, 0x5D, 0x31, 0xDF, - 0x54, 0xEB, 0x6A, 0xD3, 0xB0, 0x43, 0x04, 0x42 - }, - { - 0x50, 0x50, 0xB7, 0x3B, 0x93, 0x16, 0xEE, 0xA2, - 0xF1, 0x49, 0xBF, 0xFD, 0x22, 0xAE, 0xE3, 0x84, - 0xDC, 0x54, 0x03, 0xB1, 0x8E, 0x16, 0xFA, 0x88, - 0x82, 0x5E, 0x18, 0x16, 0x09, 0x49, 0x6F, 0xD2 - }, - { - 0x13, 0x65, 0xCC, 0x6F, 0xB9, 0x26, 0x0E, 0x86, - 0x88, 0x9B, 0x3A, 0xFB, 0xD1, 0xC8, 0xBC, 0x12, - 0x92, 0x31, 0x97, 0x71, 0x5D, 0xB2, 0x66, 0xCC, - 0x7A, 0x01, 0xCA, 0x57, 0x15, 0x9F, 0x75, 0x96 - }, - { - 0x29, 0x46, 0x6F, 0x51, 0xC0, 0x11, 0xFD, 0x10, - 0x18, 0x14, 0x94, 0xA9, 0x37, 0x9B, 0x61, 0x59, - 0xB8, 0x08, 0xAE, 0x0F, 0xCB, 0x01, 0x61, 0xF8, - 0xF0, 0x79, 0x09, 0xFF, 0x04, 0x1B, 0x19, 0x65 - }, - { - 0x65, 0x91, 0xA3, 0xC3, 0xC7, 0x67, 0xB3, 0x8D, - 0x80, 0x5E, 0xD3, 0xF7, 0xEB, 0x67, 0x63, 0xE8, - 0xB3, 0xD2, 0xD6, 0x42, 0xE7, 0x30, 0x77, 0x45, - 0xCD, 0x34, 0x18, 0xEF, 0xF6, 0x9A, 0x19, 0xED - }, - { - 0x1D, 0x84, 0xB0, 0x4B, 0x13, 0x38, 0xB0, 0xD2, - 0xE3, 0xC9, 0x8F, 0x7A, 0xEA, 0x3E, 0x98, 0xEF, - 0xFC, 0x53, 0x0A, 0x50, 0x44, 0xB9, 0x3B, 0x96, - 0xC6, 0x7E, 0xE3, 0x79, 0xD6, 0x2E, 0x81, 0x5F - }, - { - 0x6F, 0xA2, 0x95, 0x27, 0x25, 0x32, 0xE9, 0x83, - 0xE1, 0x66, 0xB1, 0x2E, 0x49, 0x99, 0xC0, 0x52, - 0xF8, 0x9D, 0x9F, 0x30, 0xAE, 0x14, 0x81, 0xF3, - 0xD6, 0x0E, 0xAE, 0x85, 0xF8, 0xEE, 0x17, 0x8A - }, - { - 0x4E, 0xD8, 0xCA, 0xA9, 0x8E, 0xC3, 0x9F, 0x6A, - 0x62, 0x9F, 0x9A, 0x65, 0x4A, 0x44, 0x7E, 0x7E, - 0x3E, 0x4F, 0xAE, 0xEC, 0xF3, 0x4D, 0xCF, 0x65, - 0x8D, 0x2D, 0x4B, 0x98, 0xB7, 0xA2, 0xEC, 0x1A - }, - { - 0xCF, 0xAB, 0x82, 0x99, 0xA0, 0xDA, 0x0C, 0x2A, - 0x7E, 0x8F, 0xF5, 0x4D, 0x0A, 0x67, 0x6D, 0x14, - 0x1A, 0xB2, 0x6B, 0xC0, 0x01, 0x2E, 0x5F, 0x66, - 0x8E, 0x85, 0xD8, 0x14, 0xBC, 0x98, 0x88, 0xB0 - }, - { - 0xA6, 0x26, 0x54, 0x3C, 0x27, 0x1F, 0xCC, 0xC3, - 0xE4, 0x45, 0x0B, 0x48, 0xD6, 0x6B, 0xC9, 0xCB, - 0xDE, 0xB2, 0x5E, 0x5D, 0x07, 0x7A, 0x62, 0x13, - 0xCD, 0x90, 0xCB, 0xBD, 0x0F, 0xD2, 0x20, 0x76 - }, - { - 0x05, 0xCF, 0x3A, 0x90, 0x04, 0x91, 0x16, 0xDC, - 0x60, 0xEF, 0xC3, 0x15, 0x36, 0xAA, 0xA3, 0xD1, - 0x67, 0x76, 0x29, 0x94, 0x89, 0x28, 0x76, 0xDC, - 0xB7, 0xEF, 0x3F, 0xBE, 0xCD, 0x74, 0x49, 0xC0 - }, - { - 0xCC, 0xD6, 0x1C, 0x92, 0x6C, 0xC1, 0xE5, 0xE9, - 0x12, 0x8C, 0x02, 0x1C, 0x0C, 0x6E, 0x92, 0xAE, - 0xFC, 0x4F, 0xFB, 0xDE, 0x39, 0x4D, 0xD6, 0xF3, - 0xB7, 0xD8, 0x7A, 0x8C, 0xED, 0x89, 0x60, 0x14 - }, - { - 0x3F, 0xFA, 0x4F, 0x6D, 0xAF, 0xA5, 0x7F, 0x1C, - 0x50, 0xF1, 0xAF, 0xA4, 0xF8, 0x12, 0x92, 0xAE, - 0x71, 0xA0, 0x6F, 0xE4, 0xF8, 0xFF, 0x46, 0xC5, - 0x1D, 0x32, 0xFF, 0x26, 0x13, 0x48, 0x9F, 0x2B - }, - { - 0x19, 0xD3, 0x92, 0x1C, 0xFC, 0x0F, 0x1A, 0x2B, - 0xB8, 0x13, 0xB3, 0xDF, 0xA9, 0x6D, 0xF9, 0x0E, - 0x2C, 0x6B, 0x87, 0xD7, 0x8E, 0x92, 0x38, 0xF8, - 0x5B, 0xBC, 0x77, 0xAE, 0x9A, 0x73, 0xF9, 0x8F - }, - { - 0xF5, 0xC9, 0x16, 0xFF, 0x2B, 0xAD, 0xDE, 0x3E, - 0x29, 0xA5, 0xF9, 0x40, 0x23, 0x3E, 0xA3, 0x40, - 0x07, 0xD8, 0xF1, 0x82, 0xA4, 0x8A, 0x80, 0x8B, - 0x46, 0xBB, 0x80, 0x58, 0x00, 0x3F, 0x19, 0x03 - }, - { - 0x6B, 0xA0, 0x7A, 0x1A, 0xF7, 0x58, 0xE6, 0x82, - 0xD3, 0xE0, 0x9A, 0xDD, 0x2D, 0x3D, 0xCD, 0xF3, - 0x5D, 0x95, 0x53, 0xF6, 0x79, 0x98, 0x54, 0xA2, - 0x7E, 0x53, 0x60, 0x63, 0xC5, 0x7F, 0x81, 0xA5 - }, - { - 0xB7, 0x83, 0x78, 0xFB, 0x44, 0x6C, 0x54, 0x4B, - 0x04, 0xD4, 0xA1, 0x52, 0xAC, 0x49, 0x57, 0x31, - 0x61, 0xB3, 0xDD, 0xEB, 0xF6, 0x93, 0x86, 0x77, - 0x0A, 0x55, 0xA7, 0xD4, 0x7B, 0x88, 0x0E, 0x5D - }, - { - 0xB5, 0x19, 0x53, 0x8F, 0xE1, 0x62, 0x6F, 0x0C, - 0x59, 0x59, 0x45, 0xAD, 0xA5, 0x8A, 0x34, 0x4F, - 0xAA, 0xC0, 0x06, 0x17, 0x61, 0xCC, 0x9D, 0x4A, - 0x84, 0x14, 0x19, 0xBD, 0x32, 0xEE, 0xC0, 0xD9 - }, - { - 0x96, 0xE4, 0x88, 0xB0, 0x27, 0x89, 0x64, 0x13, - 0xF4, 0x03, 0x4B, 0x03, 0x54, 0xF4, 0x84, 0x84, - 0xF6, 0xCF, 0xC1, 0x0F, 0x8E, 0xC5, 0x7B, 0x02, - 0x6F, 0xD2, 0x1A, 0x3B, 0x88, 0x36, 0x1A, 0x74 - }, - { - 0x77, 0x0C, 0x8A, 0x5F, 0x47, 0xBF, 0xD7, 0x69, - 0xCE, 0xD3, 0x5A, 0x71, 0xAF, 0xC3, 0xCA, 0x1F, - 0xF4, 0xC1, 0xF1, 0xE7, 0xCC, 0x3D, 0x23, 0x56, - 0xDE, 0x94, 0x50, 0x04, 0x36, 0x8D, 0x81, 0x45 - }, - { - 0x6D, 0xF9, 0xD8, 0xD0, 0xD3, 0xA8, 0xD9, 0x8C, - 0x83, 0x50, 0xD7, 0x16, 0x2B, 0xD1, 0x55, 0x79, - 0xD5, 0x70, 0x7A, 0xDD, 0x76, 0x11, 0xA0, 0x0E, - 0xEB, 0x6C, 0xA5, 0x74, 0x3E, 0xD7, 0x8C, 0xB7 - }, - { - 0x4F, 0x0F, 0xE8, 0xFC, 0x17, 0x90, 0x15, 0x91, - 0xCF, 0x34, 0x87, 0x30, 0xE1, 0x87, 0xDE, 0x52, - 0x3D, 0x6D, 0x75, 0x68, 0xC1, 0xFB, 0xD8, 0x24, - 0x85, 0x91, 0x39, 0x85, 0xEB, 0x67, 0x97, 0x1C - }, - { - 0x0E, 0xF3, 0xBB, 0x35, 0xCF, 0x37, 0x2B, 0xD9, - 0x4E, 0x3F, 0x80, 0xEE, 0xCE, 0xBD, 0x50, 0xEF, - 0x0D, 0x03, 0x08, 0xE0, 0x1E, 0x0E, 0xD6, 0xDE, - 0x0F, 0x5A, 0x8A, 0x8C, 0x81, 0x8A, 0x00, 0x74 - }, - { - 0xC0, 0x38, 0xD3, 0xE8, 0x09, 0xA5, 0xE3, 0xA5, - 0x8D, 0xB2, 0xF9, 0x1C, 0x15, 0xAE, 0x12, 0x43, - 0x95, 0x78, 0xF7, 0x54, 0x85, 0xCD, 0x84, 0xF5, - 0x56, 0xC6, 0x97, 0x1E, 0x8E, 0x25, 0x06, 0x20 - }, - { - 0xCE, 0x39, 0x9A, 0x0F, 0x08, 0x27, 0x7D, 0x8D, - 0x48, 0x16, 0x09, 0x50, 0x60, 0xEB, 0xBF, 0x33, - 0xDA, 0x01, 0x6F, 0xB4, 0x3A, 0x6C, 0x35, 0x6D, - 0x5A, 0x3F, 0xE4, 0xBB, 0x57, 0x4C, 0x5E, 0x7B - }, - { - 0x86, 0x9F, 0x7E, 0x31, 0x6B, 0x19, 0x4F, 0x95, - 0x31, 0xBC, 0xAF, 0x33, 0xF7, 0x91, 0x3F, 0x1B, - 0x9C, 0xFC, 0x6B, 0xB5, 0xDC, 0xF8, 0x6B, 0x69, - 0x2B, 0xF8, 0xCA, 0xB2, 0x9B, 0x8A, 0xA9, 0x6F - }, - { - 0x32, 0x7D, 0xFA, 0x46, 0x44, 0x59, 0xD9, 0xE4, - 0x8F, 0x5E, 0x55, 0xC7, 0xF5, 0xBA, 0xA6, 0x8F, - 0xC4, 0xA2, 0x5A, 0xD6, 0x22, 0xBC, 0x7B, 0xF0, - 0x1A, 0xCA, 0x82, 0xFD, 0x5E, 0x72, 0x31, 0x4C - }, - { - 0xE0, 0x0D, 0xAD, 0x31, 0x51, 0xB9, 0x08, 0x5E, - 0xAE, 0x78, 0x69, 0x84, 0xFE, 0x20, 0x73, 0x52, - 0x32, 0xB7, 0xFF, 0x7F, 0x1B, 0x1D, 0xB7, 0x96, - 0x1F, 0xD0, 0xD0, 0xE0, 0xF6, 0x05, 0xDB, 0x9A - }, - { - 0x07, 0x6F, 0x64, 0x45, 0x20, 0xD0, 0xB4, 0x73, - 0x2D, 0x6C, 0x53, 0x1C, 0x93, 0x49, 0x08, 0x90, - 0x26, 0x93, 0x6D, 0x99, 0x82, 0x04, 0x61, 0xDA, - 0x87, 0x74, 0x9A, 0x52, 0x0F, 0xBE, 0x90, 0xCE - }, - { - 0xB4, 0x41, 0x4C, 0xA1, 0x37, 0x3B, 0xE4, 0x6F, - 0x15, 0xCE, 0xA6, 0xB1, 0x25, 0x5A, 0x7D, 0x18, - 0x86, 0xC6, 0xFD, 0xB0, 0x8E, 0xD5, 0xAF, 0x96, - 0x57, 0xD5, 0xAA, 0xC3, 0x17, 0xDE, 0x3A, 0x29 - }, - { - 0x8D, 0x1A, 0xB0, 0x26, 0x3D, 0xAB, 0x7B, 0x86, - 0xEC, 0xEE, 0x21, 0x91, 0x62, 0xD9, 0x99, 0xA0, - 0x12, 0x45, 0x57, 0x22, 0x69, 0xDE, 0x31, 0x10, - 0x0E, 0x5D, 0x88, 0xFC, 0x1B, 0x1E, 0xAA, 0x69 - }, - { - 0xB4, 0x8D, 0x1C, 0x1F, 0x83, 0x92, 0x4A, 0x02, - 0xA2, 0x3E, 0x5E, 0x0F, 0x97, 0x1E, 0x16, 0xE8, - 0x7F, 0xC4, 0x88, 0x48, 0x53, 0x83, 0x34, 0x85, - 0x19, 0x1A, 0x2B, 0x60, 0x72, 0x2F, 0xE2, 0x69 - }, - { - 0xF2, 0xED, 0xD5, 0xF7, 0x50, 0xA2, 0x0A, 0x54, - 0x1D, 0x3F, 0x6B, 0xD5, 0xDF, 0x80, 0x83, 0x8F, - 0x11, 0x82, 0x5B, 0x25, 0xA9, 0x8F, 0x3D, 0xA5, - 0xE1, 0x52, 0x3B, 0xFF, 0x81, 0x3B, 0xB5, 0x60 - }, - { - 0x07, 0x16, 0x60, 0x04, 0xEF, 0x88, 0xE1, 0x61, - 0x4E, 0xBD, 0xC8, 0x87, 0xDF, 0xC7, 0xDA, 0x42, - 0xEB, 0xCD, 0xA0, 0x2D, 0x92, 0xC1, 0x2F, 0x18, - 0xD1, 0x18, 0x6C, 0xE3, 0xC9, 0x87, 0x10, 0xE4 - }, - { - 0x69, 0xF8, 0x3A, 0xA1, 0x01, 0xD6, 0x9B, 0x8F, - 0x12, 0x20, 0xDC, 0x1C, 0x53, 0x8D, 0x89, 0x34, - 0x45, 0x84, 0x20, 0xBE, 0x33, 0x5F, 0xEB, 0x46, - 0xFF, 0xC4, 0x7A, 0x2C, 0x8E, 0x2E, 0x6A, 0x8A - }, - { - 0xE1, 0x46, 0x9F, 0x16, 0xC6, 0xFC, 0xA1, 0x51, - 0x19, 0xA2, 0x72, 0xE5, 0x85, 0xC7, 0xF5, 0x04, - 0x21, 0xBC, 0x8A, 0x41, 0x4C, 0x86, 0x4F, 0xC7, - 0x6B, 0x01, 0x04, 0x8D, 0x4C, 0x6F, 0xC5, 0xD2 - }, - { - 0x67, 0x63, 0x34, 0x3A, 0x1C, 0x80, 0xF1, 0x92, - 0x83, 0xA8, 0x0A, 0xF8, 0x54, 0xE7, 0xE9, 0x06, - 0x5C, 0x2A, 0x83, 0x49, 0xEF, 0x11, 0xF1, 0x1B, - 0xFB, 0x76, 0xBA, 0x9F, 0x97, 0x04, 0x85, 0x39 - }, - { - 0x1A, 0xE3, 0xA0, 0xB8, 0xB2, 0xC7, 0x88, 0x5B, - 0xA3, 0x18, 0xAD, 0x6F, 0xD4, 0x49, 0xFC, 0x4D, - 0x7F, 0x84, 0x04, 0xB5, 0x9C, 0xF3, 0x27, 0x5F, - 0xCD, 0xEA, 0x13, 0x56, 0x34, 0x25, 0x77, 0x2D - }, - { - 0x3A, 0x71, 0x18, 0x4C, 0xBE, 0x8E, 0xB5, 0x8E, - 0x68, 0x12, 0xBA, 0x7A, 0x7A, 0x1D, 0xCA, 0x0C, - 0xA2, 0x8E, 0xEC, 0x63, 0x78, 0x2F, 0x2E, 0x6E, - 0x3C, 0x0B, 0x87, 0x07, 0x3F, 0x53, 0x3F, 0xFD - }, - { - 0x18, 0x4C, 0xCF, 0x2A, 0x52, 0xF3, 0x88, 0xC9, - 0xF8, 0x97, 0xA8, 0x57, 0xFE, 0x7C, 0xCE, 0xC2, - 0x95, 0x99, 0x11, 0xA8, 0xD1, 0xE0, 0x9E, 0xE8, - 0x80, 0x4D, 0x8D, 0x5D, 0x50, 0x8D, 0xD9, 0x18 - }, - { - 0xA6, 0x6D, 0x40, 0x9A, 0xF7, 0xAF, 0xD7, 0x5B, - 0xE8, 0x31, 0xDD, 0x49, 0x8C, 0x19, 0x6E, 0xF1, - 0x2C, 0x73, 0xC3, 0x11, 0x29, 0xEC, 0x02, 0xD5, - 0xF1, 0x2A, 0xB0, 0x2A, 0x2C, 0x63, 0xA2, 0x5E - }, - { - 0x58, 0xB3, 0x74, 0x97, 0xFC, 0xF0, 0xBE, 0x0E, - 0x0C, 0xF1, 0x73, 0x40, 0x45, 0xC2, 0x95, 0xB2, - 0x86, 0xC7, 0x6A, 0x7C, 0x04, 0x8E, 0x87, 0xC5, - 0x40, 0x28, 0xED, 0x36, 0x91, 0x5B, 0x5D, 0xF3 - }, - { - 0x2C, 0x73, 0x33, 0x54, 0x0A, 0x83, 0x2D, 0x64, - 0x45, 0x6E, 0x43, 0x05, 0x8C, 0x50, 0xD9, 0x3C, - 0x93, 0x2A, 0xD9, 0xB1, 0x8B, 0x3F, 0xC3, 0xA0, - 0x59, 0x92, 0x07, 0xCD, 0xA3, 0xB3, 0xC7, 0xA6 - }, - { - 0x3D, 0xC0, 0x62, 0xFF, 0xB5, 0x7D, 0x83, 0x5F, - 0xE3, 0xAA, 0x40, 0x94, 0x66, 0x82, 0x2F, 0x91, - 0x86, 0x91, 0x84, 0x23, 0x94, 0x75, 0x05, 0x16, - 0x5F, 0xDC, 0xDF, 0xB7, 0x30, 0x6F, 0x72, 0x59 - }, - { - 0x89, 0x20, 0x48, 0x44, 0xAC, 0xB9, 0x2F, 0x35, - 0x3B, 0xFC, 0x89, 0xA3, 0xCE, 0x8A, 0x98, 0x17, - 0x21, 0x9C, 0x10, 0x13, 0x85, 0xC5, 0x93, 0xCF, - 0x60, 0xE0, 0xBE, 0xFA, 0x96, 0x38, 0xE1, 0x4E - }, - { - 0x78, 0x2B, 0xA9, 0x02, 0xE9, 0x12, 0x32, 0x94, - 0x1C, 0x78, 0xC4, 0x9C, 0xD9, 0x77, 0x1A, 0x5D, - 0x99, 0x92, 0xF9, 0xB0, 0x7D, 0x9C, 0x0A, 0x2D, - 0xF8, 0x2D, 0x38, 0x5D, 0x15, 0xC4, 0x2B, 0xB3 - }, - { - 0x0D, 0xC3, 0xFF, 0x7D, 0xF0, 0xDF, 0xC0, 0x23, - 0x76, 0x3D, 0x76, 0x34, 0xE1, 0x8D, 0xA2, 0x73, - 0x93, 0xFC, 0x9F, 0xDB, 0x1C, 0x15, 0x46, 0x46, - 0x86, 0x10, 0x75, 0xF0, 0xA8, 0x7D, 0x0E, 0x90 - }, - { - 0xB9, 0x5C, 0x65, 0xFB, 0x6F, 0x25, 0x4E, 0xDB, - 0xDE, 0x8C, 0x03, 0x7D, 0x5C, 0x8B, 0x20, 0x39, - 0x34, 0x0F, 0x4A, 0xC2, 0xB0, 0x23, 0xA6, 0xAA, - 0x28, 0xA8, 0xFC, 0xD2, 0xD2, 0x68, 0x9C, 0xF4 - }, - { - 0x87, 0xE8, 0xF5, 0x15, 0x72, 0xA5, 0xD6, 0xA2, - 0x39, 0xF8, 0x5B, 0xC5, 0x3E, 0x11, 0x74, 0xE1, - 0x5B, 0xE1, 0x2F, 0xCD, 0xF1, 0x51, 0xA0, 0xB9, - 0xA2, 0xB4, 0x36, 0x40, 0xCA, 0xF7, 0x4C, 0x1D - }, - { - 0x2A, 0x6F, 0x3E, 0x46, 0x2C, 0x40, 0x5C, 0x35, - 0x4F, 0xE8, 0x0F, 0xCC, 0xCE, 0xD1, 0xC9, 0xBE, - 0x44, 0x32, 0x5D, 0x29, 0xE0, 0x7D, 0xA3, 0x09, - 0x60, 0xB6, 0x25, 0xA7, 0x6E, 0xA4, 0x2F, 0x83 - }, - { - 0x20, 0xB4, 0x6C, 0x8F, 0xBF, 0xCA, 0x97, 0x45, - 0x32, 0x62, 0x46, 0x0F, 0x84, 0x98, 0xA7, 0xE2, - 0xAF, 0x15, 0xAC, 0x79, 0xB5, 0x9D, 0xDF, 0xB0, - 0x27, 0xBB, 0x52, 0xF2, 0xD6, 0x8E, 0x8F, 0x51 - }, - { - 0x31, 0xB0, 0x76, 0x3C, 0xB9, 0xBA, 0x92, 0x40, - 0x3D, 0xCA, 0x1A, 0xBD, 0xD7, 0x34, 0x2D, 0x7D, - 0xE9, 0x4C, 0x58, 0x1E, 0x76, 0xF7, 0xC9, 0xA6, - 0x1E, 0x51, 0x59, 0x28, 0xE1, 0x0B, 0x4E, 0x77 - }, - { - 0xE1, 0x91, 0xE1, 0x17, 0x06, 0x3C, 0xFA, 0xC9, - 0x64, 0x2C, 0xD9, 0x3C, 0xB4, 0x2B, 0x39, 0xED, - 0xDD, 0x9E, 0x4A, 0xB6, 0x5F, 0x1D, 0x03, 0x97, - 0xE3, 0xE1, 0x7D, 0xD0, 0x4C, 0xAB, 0x11, 0x80 - }, - { - 0x22, 0x5A, 0x20, 0x21, 0x07, 0xA7, 0x47, 0x03, - 0xE0, 0x41, 0xC6, 0xCC, 0xA4, 0xEA, 0xCF, 0x4F, - 0x21, 0xEE, 0xA6, 0xF2, 0x2A, 0x14, 0x6D, 0x8D, - 0xA2, 0xAB, 0x8C, 0xF6, 0x19, 0x72, 0x29, 0xA5 - }, - { - 0xEF, 0xC4, 0x83, 0x6B, 0xE4, 0xAC, 0x3E, 0x97, - 0x91, 0xD2, 0xEC, 0x62, 0x22, 0x6E, 0x7D, 0xF6, - 0x41, 0x18, 0xF4, 0x56, 0x5C, 0x19, 0xE6, 0xC9, - 0xE8, 0x40, 0x63, 0xF5, 0x66, 0x1C, 0x7B, 0x2F - }, - { - 0x3A, 0x76, 0xB0, 0x15, 0x2C, 0x0E, 0x1D, 0x1F, - 0xD7, 0xAC, 0x9D, 0x91, 0xA2, 0x8A, 0x18, 0xE1, - 0xA4, 0xC0, 0x60, 0x80, 0xF2, 0xB7, 0xEC, 0xEF, - 0xB6, 0xEF, 0xFE, 0x28, 0xB8, 0xCF, 0xC7, 0x65 - }, - { - 0x0D, 0x46, 0xAD, 0x03, 0x90, 0x70, 0x11, 0x58, - 0x28, 0xF9, 0x4E, 0xB6, 0xB7, 0x29, 0x63, 0xE6, - 0x0A, 0x7D, 0x2D, 0xB7, 0xCA, 0x89, 0x91, 0xD2, - 0x25, 0xC3, 0x87, 0x7B, 0x14, 0x9B, 0x0A, 0x8A - }, - { - 0xE4, 0x4C, 0xFC, 0x42, 0x11, 0x8F, 0x09, 0x6B, - 0xFC, 0x51, 0x52, 0x1C, 0xB1, 0x8D, 0x5D, 0x65, - 0x25, 0x58, 0x6B, 0x98, 0x9F, 0x4E, 0xE2, 0xB8, - 0x28, 0xC5, 0x19, 0x9F, 0xEA, 0xB9, 0x4B, 0x82 - }, - { - 0x6D, 0x4B, 0xD2, 0xE0, 0x73, 0xEC, 0x49, 0x66, - 0x84, 0x7F, 0x5C, 0xBE, 0x88, 0xDD, 0xFA, 0xBA, - 0x2B, 0xE4, 0xCA, 0xF2, 0xF3, 0x33, 0x55, 0x2B, - 0x85, 0x53, 0xDA, 0x53, 0x34, 0x87, 0xC2, 0x5B - }, - { - 0xBB, 0xC4, 0x6D, 0xB4, 0x37, 0xD1, 0x07, 0xC9, - 0x67, 0xCA, 0x6D, 0x91, 0x45, 0x5B, 0xBD, 0xFE, - 0x05, 0x21, 0x18, 0xAB, 0xD1, 0xD0, 0x69, 0xF0, - 0x43, 0x59, 0x48, 0x7E, 0x13, 0xAE, 0xA0, 0xE1 - }, - { - 0xB9, 0x74, 0xC1, 0x4D, 0xB7, 0xD3, 0x17, 0x4D, - 0xD0, 0x60, 0x84, 0xBB, 0x30, 0x31, 0x08, 0xB2, - 0xF0, 0xDA, 0xF5, 0x0E, 0xCC, 0xC3, 0x29, 0x35, - 0x43, 0x79, 0x5C, 0x96, 0x36, 0xC6, 0x24, 0x82 - }, - { - 0x0E, 0xEE, 0x23, 0x5B, 0x06, 0x93, 0x6A, 0xED, - 0x71, 0x73, 0xC8, 0xC1, 0x9A, 0xA7, 0xC2, 0x17, - 0xB9, 0xEE, 0xDA, 0xEB, 0x1A, 0x88, 0xF3, 0x05, - 0x52, 0xE9, 0x22, 0x51, 0x45, 0x14, 0x9E, 0x82 - }, - { - 0x36, 0xD0, 0x89, 0xE0, 0x25, 0xB5, 0x68, 0x69, - 0x37, 0x74, 0x28, 0x25, 0xE6, 0xEE, 0x3D, 0x83, - 0xE7, 0xD7, 0xA5, 0x0C, 0x82, 0x3C, 0x82, 0x88, - 0x34, 0x60, 0xF3, 0x85, 0x14, 0x7D, 0xC1, 0x7B - }, - { - 0x77, 0xEE, 0x4F, 0xFC, 0x9F, 0x5D, 0xD6, 0x05, - 0x47, 0x0D, 0xC0, 0xE7, 0x4D, 0x6B, 0x17, 0xC5, - 0x13, 0x0D, 0x8B, 0x73, 0x91, 0x3F, 0x36, 0xD5, - 0xF8, 0x78, 0x7E, 0x61, 0x9A, 0x94, 0x7C, 0xA0 - }, - { - 0x0F, 0xE6, 0xC2, 0xAB, 0x75, 0x42, 0x33, 0x36, - 0x0D, 0x68, 0xB9, 0xAC, 0x80, 0xCD, 0x61, 0x18, - 0x4B, 0xFA, 0xA7, 0xD3, 0x56, 0x29, 0x41, 0x80, - 0x02, 0x5F, 0xE4, 0x06, 0x39, 0xC7, 0x6C, 0x36 - }, - { - 0x99, 0x60, 0x88, 0xC7, 0x94, 0x56, 0xEC, 0xDD, - 0xA1, 0xFB, 0xC0, 0x2E, 0xE1, 0xBA, 0x42, 0xD9, - 0x1D, 0x85, 0x8C, 0x31, 0x0A, 0x5A, 0x8B, 0x46, - 0x74, 0xFE, 0x6A, 0x7C, 0x14, 0x44, 0x14, 0xA1 - }, - { - 0x9E, 0x33, 0x8A, 0xED, 0x0B, 0xC7, 0x1C, 0x0C, - 0x97, 0xF1, 0x98, 0x55, 0xBF, 0x49, 0x17, 0x4F, - 0x70, 0xA9, 0xD7, 0x70, 0x14, 0x87, 0x36, 0x63, - 0x21, 0x34, 0x27, 0x50, 0x2B, 0xD8, 0x5D, 0x9F - }, - { - 0x4A, 0x84, 0x3D, 0x26, 0xAD, 0xEC, 0x52, 0x0E, - 0x4B, 0x5D, 0xBF, 0x01, 0x45, 0xCC, 0x4F, 0x50, - 0x24, 0xFA, 0xFC, 0xDC, 0x20, 0x25, 0x82, 0x4A, - 0x8C, 0x64, 0x65, 0x06, 0x17, 0x68, 0x7E, 0xE7 - }, - { - 0xC9, 0x16, 0x78, 0xC4, 0xA6, 0x4E, 0x2F, 0xA4, - 0xB7, 0x4D, 0xE6, 0x1A, 0xD0, 0xC0, 0x6F, 0xF0, - 0x6B, 0x5D, 0x67, 0x2F, 0xA7, 0xC6, 0x87, 0x7A, - 0x40, 0x14, 0xCE, 0x9E, 0x91, 0xBE, 0x38, 0xD7 - }, - { - 0xFF, 0x77, 0x77, 0x40, 0x5D, 0x32, 0x7A, 0xDB, - 0x58, 0x30, 0x1C, 0x71, 0x1E, 0xCD, 0xC2, 0xBC, - 0xE1, 0xBF, 0xA8, 0x29, 0xFF, 0xC9, 0xB1, 0x17, - 0xF2, 0x1A, 0x2B, 0x19, 0x8D, 0x0D, 0x68, 0x84 - }, - { - 0x0A, 0x8D, 0xDA, 0xF1, 0x72, 0x8C, 0x5C, 0xD9, - 0x3A, 0x25, 0x5D, 0x56, 0x23, 0xC3, 0xDA, 0xDA, - 0x2D, 0x3D, 0x05, 0x71, 0xBF, 0x14, 0x38, 0xAD, - 0xC8, 0xC9, 0x64, 0xA9, 0xAA, 0xD1, 0x18, 0xCB - }, - { - 0xC1, 0x33, 0xAB, 0xBD, 0x0D, 0x2D, 0x80, 0x8A, - 0x67, 0xB6, 0x74, 0x5B, 0x4B, 0x36, 0x50, 0xB4, - 0xA6, 0x4D, 0xC2, 0x76, 0xCF, 0x98, 0xE3, 0x03, - 0x57, 0xB6, 0xAB, 0xD5, 0xC1, 0xD2, 0x2A, 0x9B - }, - { - 0xC5, 0x9E, 0xE5, 0xC1, 0x96, 0xBA, 0x3C, 0xFE, - 0xF9, 0x40, 0x87, 0x79, 0x82, 0x07, 0xBD, 0xCE, - 0xF1, 0x39, 0xCE, 0x2C, 0xF7, 0x8D, 0xCE, 0xD6, - 0x19, 0x8F, 0x0F, 0xA3, 0xA4, 0x09, 0x13, 0x1C - }, - { - 0xC7, 0xFD, 0xAD, 0xE5, 0x9C, 0x46, 0x99, 0x38, - 0x5E, 0xBA, 0x59, 0xE7, 0x56, 0xC2, 0xB1, 0x71, - 0xB0, 0x23, 0xDE, 0xAE, 0x08, 0x2E, 0x5A, 0x6E, - 0x3B, 0xFB, 0xDC, 0x10, 0x73, 0xA3, 0x20, 0x03 - }, - { - 0x97, 0x53, 0x27, 0xC5, 0xF4, 0xDE, 0xC6, 0x41, - 0x4B, 0x6E, 0x00, 0xCB, 0x04, 0x23, 0x37, 0xB8, - 0xD2, 0xA6, 0x56, 0x46, 0x37, 0xA7, 0x44, 0x2A, - 0xEC, 0x7B, 0xE8, 0xF8, 0xC8, 0x9A, 0x2F, 0x1C - }, - { - 0xA2, 0xF7, 0x24, 0x6D, 0xF4, 0xA2, 0x4E, 0xFB, - 0xAC, 0xD3, 0xFD, 0x60, 0x68, 0x3A, 0xBC, 0x86, - 0x8B, 0xEF, 0x25, 0x32, 0x70, 0x52, 0xCF, 0x2F, - 0x1D, 0x93, 0xEC, 0xE4, 0xFF, 0xCD, 0x73, 0xC6 - }, - { - 0x49, 0x7F, 0xB2, 0xAC, 0xAC, 0xF1, 0x23, 0xF3, - 0x59, 0x5E, 0x40, 0xFC, 0x51, 0xA7, 0xBD, 0x24, - 0x45, 0x8B, 0xBC, 0xBA, 0x4A, 0x29, 0x40, 0xA5, - 0xCB, 0x03, 0xD6, 0x08, 0xFB, 0xDF, 0x28, 0x25 - }, - { - 0x0E, 0x97, 0xD2, 0x27, 0x93, 0xCE, 0x6F, 0x28, - 0x3D, 0x5C, 0x74, 0x0D, 0x30, 0x8A, 0x27, 0xAD, - 0x7C, 0x3B, 0x0D, 0x9A, 0xFC, 0xD3, 0xD9, 0xE9, - 0xB9, 0xCA, 0xC5, 0x6B, 0x10, 0x29, 0x0C, 0x8F - }, - { - 0x66, 0x30, 0xB3, 0x56, 0x18, 0xE7, 0x00, 0xD9, - 0x10, 0x68, 0x38, 0x93, 0x79, 0x5E, 0xF7, 0x0B, - 0xF0, 0x7E, 0xB1, 0x56, 0xF5, 0x5F, 0xFE, 0x3B, - 0x69, 0xAD, 0x88, 0xA4, 0xB8, 0xB0, 0xBF, 0xA1 - }, - { - 0x02, 0xF7, 0x42, 0xC6, 0xE9, 0x52, 0x78, 0x12, - 0x1A, 0x05, 0xE4, 0x42, 0x05, 0x44, 0x4F, 0xC5, - 0xEA, 0x6A, 0xF5, 0xE7, 0x41, 0xC5, 0x35, 0xBC, - 0x2C, 0xBC, 0x3B, 0x23, 0x5A, 0x2E, 0xA2, 0xB0 - }, - { - 0x46, 0x22, 0xF3, 0x6E, 0xB8, 0x98, 0x38, 0x3F, - 0x60, 0xD5, 0xBE, 0xD8, 0x09, 0xAC, 0x5C, 0x47, - 0x45, 0xC5, 0xD6, 0xAB, 0x84, 0xBC, 0xAD, 0xF7, - 0x9C, 0xF2, 0xA9, 0x6D, 0x4E, 0xC8, 0x88, 0x18 - }, - { - 0xCC, 0xD1, 0x1F, 0xAA, 0xA0, 0x58, 0x1E, 0xC3, - 0x2C, 0x3A, 0x40, 0x3F, 0x92, 0xEF, 0x43, 0xD5, - 0xDC, 0xF1, 0x95, 0xC1, 0xA1, 0x01, 0xDB, 0xFD, - 0x49, 0x5D, 0xBB, 0x4D, 0xCE, 0x80, 0x69, 0xE0 - }, - { - 0x06, 0x02, 0x4D, 0x6B, 0x07, 0xE0, 0x00, 0xBC, - 0xE6, 0x13, 0x47, 0x0A, 0x28, 0x80, 0x51, 0x9B, - 0x8B, 0xE4, 0xA3, 0x6B, 0xF3, 0x3C, 0x99, 0xC9, - 0x17, 0x89, 0x3E, 0xC7, 0x5D, 0xD9, 0x0F, 0xE3 - }, - { - 0xD9, 0x3A, 0xF9, 0x47, 0xB1, 0x46, 0x3A, 0x81, - 0x7D, 0xB4, 0x41, 0xA4, 0x74, 0x58, 0x8D, 0x6F, - 0x99, 0x6D, 0x24, 0x39, 0x83, 0xE8, 0x3C, 0x7E, - 0xEE, 0x90, 0xE1, 0xEF, 0xA4, 0x40, 0xD9, 0xBA - }, - { - 0x94, 0x89, 0x89, 0x45, 0xA7, 0xDB, 0x25, 0x9E, - 0x1B, 0x2E, 0x7C, 0xBE, 0xA4, 0x8A, 0xA0, 0xC6, - 0xD6, 0x57, 0x0D, 0x18, 0x17, 0x9F, 0x06, 0x18, - 0x47, 0x1C, 0x88, 0xF3, 0xEC, 0x3B, 0x0F, 0xC3 - }, - { - 0x4C, 0x2D, 0x93, 0x52, 0x56, 0x39, 0x2A, 0xA2, - 0xBE, 0x6E, 0x10, 0x78, 0xC0, 0x59, 0x38, 0x15, - 0xAB, 0xEF, 0x46, 0x9D, 0xE9, 0x69, 0xB5, 0x7B, - 0x88, 0x1B, 0x93, 0xAF, 0x55, 0x84, 0x65, 0xFA - }, - { - 0xAA, 0xC7, 0xBE, 0x16, 0xE5, 0x2F, 0x79, 0x0E, - 0x4F, 0xF7, 0x0B, 0x24, 0x01, 0x5C, 0xB1, 0x1B, - 0x40, 0x61, 0x6E, 0x94, 0xDB, 0x13, 0x88, 0x2B, - 0x41, 0xD3, 0xDD, 0x8C, 0x8C, 0x19, 0x52, 0xB7 - }, - { - 0x04, 0x34, 0xB4, 0x7C, 0x0E, 0xE7, 0xE6, 0xF5, - 0x39, 0x06, 0x79, 0x9A, 0x43, 0x20, 0x9D, 0x3F, - 0xC3, 0x7D, 0x3F, 0xD1, 0xF7, 0x45, 0x55, 0xDE, - 0x67, 0xAB, 0xAC, 0xB9, 0x51, 0xB0, 0x06, 0xF4 - }, - { - 0x04, 0x42, 0xFB, 0xDD, 0x5B, 0x58, 0x49, 0x6E, - 0xC7, 0x81, 0x59, 0xCC, 0xAA, 0x88, 0x7C, 0x88, - 0xA8, 0x61, 0xFC, 0xCA, 0x70, 0xE7, 0xAB, 0xC9, - 0x76, 0xF2, 0x4C, 0x11, 0x58, 0x8B, 0xE6, 0xEE - }, - { - 0xA7, 0x3E, 0x68, 0xBB, 0x18, 0xB0, 0x07, 0x64, - 0x8E, 0x76, 0xB5, 0x52, 0x8D, 0x1E, 0x50, 0xE7, - 0xFA, 0x65, 0x4D, 0xA3, 0x97, 0x0E, 0xC3, 0x49, - 0xBF, 0x59, 0x1A, 0x30, 0xD9, 0x32, 0xC8, 0xF6 - }, - { - 0x84, 0x9C, 0xF8, 0x73, 0x16, 0x2B, 0xA7, 0x2C, - 0x4B, 0x80, 0x08, 0xE6, 0x8F, 0x93, 0x2F, 0xB3, - 0xA0, 0x15, 0xA7, 0x4F, 0xCF, 0x95, 0x71, 0x98, - 0xD5, 0x6A, 0x0D, 0xC4, 0x62, 0x5A, 0x74, 0xF5 - }, - { - 0xA6, 0xDE, 0xC6, 0xFC, 0x89, 0x49, 0x34, 0x9C, - 0x4E, 0x9A, 0x9C, 0x62, 0x36, 0x87, 0xFB, 0xA4, - 0xC9, 0xB2, 0x75, 0xBD, 0xB2, 0x30, 0x50, 0x9B, - 0x72, 0xE3, 0xD6, 0x71, 0x19, 0x14, 0xE2, 0xD8 - }, - { - 0x58, 0xAF, 0xC2, 0xB2, 0x4A, 0x19, 0xFD, 0xBF, - 0x76, 0xA0, 0x9B, 0x70, 0xB1, 0xE3, 0xB7, 0x7F, - 0xCB, 0xD4, 0x06, 0x50, 0x01, 0xD9, 0x63, 0x66, - 0x40, 0xEB, 0x5A, 0x26, 0x28, 0xF4, 0x42, 0xCC - }, - { - 0x47, 0x3A, 0x43, 0xAA, 0x1D, 0x6A, 0x02, 0x87, - 0x67, 0x43, 0x2A, 0x83, 0x0A, 0xD1, 0x22, 0x1E, - 0x02, 0x9C, 0x58, 0x9A, 0xF9, 0xFD, 0x4D, 0x68, - 0xD5, 0x6C, 0x4F, 0xB8, 0x20, 0x25, 0x93, 0x52 - }, - { - 0xA0, 0xAE, 0xB4, 0xA5, 0xAD, 0x89, 0x9A, 0xF2, - 0xE2, 0x91, 0xB2, 0xE7, 0x9D, 0xBB, 0x6B, 0x0B, - 0xF5, 0x6B, 0x58, 0x44, 0x67, 0x6B, 0x95, 0x5D, - 0x94, 0x5B, 0x6C, 0x4A, 0xE1, 0xC0, 0x1E, 0xED - }, - { - 0xCF, 0xC3, 0x02, 0x9A, 0x9E, 0xEB, 0x15, 0x22, - 0x22, 0xD9, 0x66, 0x53, 0x49, 0x2E, 0x46, 0xCA, - 0x64, 0xCA, 0x4F, 0x0D, 0x64, 0x68, 0x30, 0x28, - 0xD3, 0xAE, 0xE5, 0xA4, 0x9C, 0xB4, 0x71, 0x63 - }, - { - 0x74, 0x67, 0xCF, 0x77, 0x61, 0xCD, 0x9F, 0x55, - 0x61, 0x8D, 0x30, 0xC9, 0xD8, 0xC5, 0xB4, 0x1E, - 0x47, 0x01, 0x51, 0x0C, 0x7D, 0x16, 0xAB, 0x4E, - 0x5D, 0x89, 0xA5, 0xD7, 0x71, 0x46, 0xB0, 0x92 - }, - { - 0xC0, 0x16, 0xD8, 0x42, 0x4E, 0x53, 0x1E, 0xFC, - 0x57, 0x37, 0xC0, 0x3F, 0xC9, 0x0A, 0x5E, 0xFC, - 0x9F, 0x90, 0x22, 0xE4, 0xD5, 0xBA, 0x3B, 0x06, - 0x95, 0xF7, 0xAE, 0x53, 0x82, 0x60, 0xC2, 0xEE - }, - { - 0x5D, 0x38, 0x11, 0x89, 0xE6, 0x00, 0x0F, 0xC1, - 0x17, 0xC7, 0x1F, 0x59, 0xF7, 0x86, 0xFB, 0x4B, - 0x79, 0xFD, 0xD4, 0xEC, 0x5D, 0x4C, 0xD3, 0x0A, - 0xAC, 0x21, 0x57, 0xF7, 0x5D, 0xEA, 0xD7, 0x78 - }, - { - 0x7C, 0x9C, 0xDD, 0x15, 0xC4, 0xC9, 0xAB, 0xCA, - 0xCB, 0xFE, 0x6F, 0x66, 0x4A, 0x7F, 0x5F, 0x8B, - 0x2E, 0x25, 0x91, 0x83, 0x29, 0x1A, 0xE5, 0xCC, - 0x91, 0x30, 0xA0, 0xB2, 0x41, 0xE5, 0x73, 0x7F - }, - { - 0xB8, 0x81, 0x31, 0x72, 0xF5, 0x21, 0x8A, 0xC3, - 0xEB, 0x68, 0x7B, 0xC4, 0xAF, 0xAF, 0xF8, 0x3F, - 0xBC, 0xA4, 0xE9, 0xC1, 0xA4, 0x62, 0x96, 0x33, - 0x01, 0xDD, 0x44, 0x59, 0x85, 0x01, 0x50, 0xA2 - }, - { - 0xE3, 0xD1, 0x30, 0xE3, 0x6A, 0x02, 0x8E, 0xA8, - 0x0C, 0x57, 0xA2, 0xAA, 0x48, 0x19, 0xFD, 0x34, - 0xE4, 0xDB, 0xBE, 0xB1, 0x4A, 0x49, 0x58, 0x94, - 0xB1, 0x5A, 0x87, 0x87, 0xDB, 0x1A, 0x9F, 0x9C - }, - { - 0xFF, 0xF1, 0xB4, 0x40, 0x0F, 0x48, 0x9E, 0x07, - 0xD2, 0x23, 0x51, 0xC1, 0xF0, 0x95, 0x65, 0xE2, - 0x65, 0xB6, 0x8A, 0xD2, 0x9F, 0x63, 0x29, 0x87, - 0x9E, 0x6B, 0x5F, 0x7F, 0x6B, 0x41, 0x93, 0x50 - }, - { - 0x55, 0x9E, 0xD5, 0xBB, 0x3E, 0x5F, 0x39, 0x85, - 0xFB, 0x57, 0x82, 0x28, 0xBF, 0x8C, 0x0F, 0x0B, - 0x17, 0x3F, 0x8D, 0x11, 0x53, 0xFA, 0xEB, 0x9F, - 0xEC, 0x75, 0x6F, 0xFD, 0x18, 0xA8, 0x72, 0x38 - }, - { - 0x88, 0x13, 0x12, 0x53, 0x01, 0x4D, 0x23, 0xC5, - 0xE3, 0x8E, 0x78, 0xBD, 0xA1, 0x94, 0x55, 0xD8, - 0xA0, 0x23, 0xBD, 0x7A, 0x7E, 0x72, 0x74, 0x57, - 0xA1, 0x52, 0xA8, 0x1D, 0x0B, 0x17, 0x18, 0xA7 - }, - { - 0xF4, 0xD3, 0xFA, 0xE7, 0xCD, 0xE6, 0xBB, 0x66, - 0x71, 0x5A, 0x19, 0x8F, 0xA4, 0x8D, 0x21, 0x0C, - 0x10, 0xF8, 0xDF, 0x32, 0x04, 0xAE, 0x5E, 0x33, - 0xA6, 0x02, 0x46, 0x7F, 0x1B, 0x62, 0x26, 0x85 - }, - { - 0xE6, 0x2B, 0x62, 0x2A, 0xC8, 0xA2, 0x13, 0x66, - 0xBF, 0x2D, 0xED, 0x30, 0xF4, 0x08, 0x2A, 0x53, - 0xE7, 0x7A, 0x9A, 0xA6, 0x96, 0xB1, 0xF3, 0xEE, - 0x8C, 0xFE, 0x99, 0xC5, 0x93, 0x12, 0xD9, 0xC7 - }, - { - 0x3D, 0x39, 0xFF, 0xA8, 0x55, 0x12, 0xC3, 0xC8, - 0x89, 0x0D, 0x4B, 0xDF, 0x31, 0x88, 0x9C, 0xA6, - 0x6E, 0x5C, 0xEC, 0xB6, 0x3C, 0xFE, 0xED, 0x57, - 0xB9, 0x26, 0x37, 0x08, 0xE7, 0x4C, 0x55, 0x0B - }, - { - 0xB1, 0x70, 0x3B, 0x8A, 0x00, 0xE2, 0x61, 0x24, - 0x97, 0xD1, 0x1C, 0x64, 0x9D, 0x15, 0x0A, 0x6C, - 0x96, 0x3B, 0xF4, 0xFD, 0x38, 0xFE, 0xB1, 0xC3, - 0x81, 0xFE, 0x0D, 0x9B, 0x04, 0xC0, 0x2B, 0x22 - }, - { - 0x12, 0xFB, 0xAD, 0x9D, 0x37, 0x82, 0x81, 0x2D, - 0x71, 0x17, 0x9A, 0x50, 0xFB, 0xD9, 0xB4, 0x56, - 0x6C, 0x7B, 0x06, 0xF5, 0xD7, 0x7C, 0x6F, 0x32, - 0x97, 0x17, 0xFB, 0x4A, 0xE2, 0xC5, 0xB4, 0xEC - }, - { - 0x76, 0x8B, 0x65, 0x9A, 0x82, 0x4B, 0x43, 0xF9, - 0xCA, 0x56, 0x60, 0xB9, 0xDD, 0xF0, 0x5F, 0x8B, - 0xA2, 0xBC, 0x49, 0x93, 0x86, 0x6B, 0x7C, 0x9B, - 0xE6, 0x87, 0x91, 0xF5, 0xB2, 0x46, 0x44, 0xB3 - }, - { - 0xC0, 0x20, 0x4E, 0x23, 0xCA, 0x86, 0xBE, 0x20, - 0x5E, 0xED, 0x0C, 0xC3, 0xDD, 0x72, 0x25, 0xCE, - 0x5F, 0xFE, 0x1E, 0xE1, 0x2D, 0xAC, 0xB9, 0x3C, - 0x5D, 0x06, 0x29, 0xB7, 0x69, 0x9C, 0xD7, 0x33 - }, - { - 0xF4, 0x32, 0x96, 0x96, 0x1F, 0x8E, 0xAE, 0xCC, - 0xD8, 0x54, 0x41, 0x3D, 0xC5, 0xAD, 0xDA, 0x62, - 0x39, 0x3A, 0x34, 0x46, 0x27, 0xE8, 0x6C, 0x06, - 0x6E, 0x79, 0x07, 0x55, 0x00, 0x40, 0x74, 0x4F - }, - { - 0x82, 0xF4, 0x46, 0x9E, 0x80, 0x78, 0x90, 0x21, - 0xC6, 0x1D, 0xB7, 0xE3, 0x2F, 0x36, 0xAC, 0xBE, - 0x59, 0x1A, 0x64, 0xF2, 0x60, 0x59, 0x26, 0x57, - 0x70, 0xAE, 0x65, 0x8D, 0x62, 0xBD, 0xE7, 0xEF - }, - { - 0x2A, 0x85, 0x67, 0x1A, 0x55, 0xC8, 0x9F, 0xA1, - 0x56, 0xE2, 0x96, 0xF7, 0x5D, 0xF1, 0xC7, 0xDB, - 0xAB, 0x17, 0x8E, 0xBB, 0xA6, 0x52, 0x04, 0xA7, - 0xE8, 0x17, 0x8C, 0x91, 0x6A, 0xD0, 0x87, 0xF8 - }, - { - 0x33, 0xE2, 0x45, 0x00, 0x28, 0x08, 0xF6, 0x93, - 0x4B, 0x9B, 0xE3, 0xA6, 0xFA, 0x8E, 0x86, 0x70, - 0xC9, 0x0B, 0xAA, 0x62, 0x57, 0x17, 0xB9, 0x20, - 0x1E, 0xB9, 0xB9, 0xDD, 0x91, 0x2F, 0x5C, 0xE2 - }, - { - 0x58, 0xEE, 0x5E, 0x79, 0x91, 0x84, 0xAD, 0x9D, - 0xA9, 0xA1, 0x7C, 0x5B, 0x46, 0xA4, 0x81, 0x0E, - 0x28, 0xBD, 0xD0, 0x8C, 0x35, 0x81, 0x63, 0x4C, - 0x83, 0x50, 0x30, 0x53, 0x9B, 0x79, 0x54, 0x4D - }, - { - 0x26, 0xD8, 0xFA, 0x08, 0xDB, 0x30, 0x8E, 0xDF, - 0x2F, 0x96, 0xF8, 0x2A, 0xF6, 0xB6, 0x0C, 0x17, - 0xD8, 0xF1, 0xFF, 0x85, 0x8C, 0x52, 0xF2, 0xD0, - 0xF3, 0x83, 0x10, 0x78, 0x12, 0x75, 0x26, 0xA3 - }, - { - 0x25, 0xA5, 0x8D, 0xF4, 0x03, 0x92, 0x47, 0xA2, - 0x2F, 0x68, 0xFF, 0x2B, 0x71, 0x76, 0x6B, 0x7B, - 0x56, 0x00, 0xDD, 0xF4, 0x01, 0xD9, 0x9F, 0xF2, - 0xC1, 0x95, 0x5A, 0xE7, 0xBB, 0x43, 0xE5, 0x6A - }, - { - 0xBE, 0x43, 0xE8, 0x68, 0x61, 0x60, 0xE9, 0x07, - 0xBA, 0x54, 0x7D, 0x5A, 0x87, 0x9D, 0x10, 0xF7, - 0x88, 0xAF, 0xC8, 0x42, 0xB8, 0xEB, 0xB9, 0xF3, - 0xF7, 0x88, 0x53, 0x25, 0x15, 0x91, 0x2A, 0xE4 - }, - { - 0xAA, 0x4A, 0xCB, 0x95, 0xD8, 0x79, 0x19, 0x2A, - 0x69, 0x08, 0xE8, 0x8A, 0xE3, 0xD6, 0x58, 0x9F, - 0x4E, 0x3E, 0xB3, 0xD4, 0xE0, 0x3A, 0x80, 0x6C, - 0xCD, 0xB9, 0xB5, 0xD6, 0xA9, 0x58, 0x6F, 0xDF - }, - { - 0x84, 0x66, 0xD5, 0xE4, 0x4C, 0xE9, 0x5B, 0x4F, - 0xA1, 0x79, 0x99, 0x24, 0x44, 0xB8, 0xC2, 0x48, - 0x5B, 0x88, 0x64, 0x48, 0xA6, 0xDC, 0xCF, 0xCF, - 0x0B, 0xC3, 0x0B, 0xC5, 0xF0, 0xF5, 0x6B, 0x01 - }, - { - 0x00, 0x56, 0xD7, 0xE0, 0xAC, 0x33, 0x35, 0x57, - 0x83, 0x65, 0x9B, 0x38, 0xEC, 0x8B, 0xEC, 0xCB, - 0xF7, 0x83, 0x93, 0x99, 0x67, 0xFE, 0x37, 0xAE, - 0xAC, 0xF3, 0x69, 0xDD, 0xB6, 0x70, 0xAD, 0xA0 - }, - { - 0x90, 0x4F, 0x42, 0xF3, 0x45, 0x53, 0x0A, 0xC8, - 0xA3, 0x52, 0xD0, 0x9B, 0x68, 0x72, 0xC5, 0xBC, - 0xA3, 0x66, 0x1A, 0xBC, 0xA6, 0xCA, 0x64, 0xC8, - 0x09, 0x9F, 0x2F, 0xB6, 0x86, 0x7C, 0x30, 0xFE - }, - { - 0xA8, 0xC3, 0xBF, 0x46, 0xF0, 0xB8, 0x8B, 0xBD, - 0x16, 0xFD, 0xA4, 0xA8, 0xB5, 0xCA, 0x81, 0xF5, - 0x24, 0x35, 0x20, 0xC3, 0x85, 0xD3, 0x8C, 0x0B, - 0x4D, 0x23, 0x52, 0xAB, 0x34, 0xEA, 0x35, 0xE6 - }, - { - 0x8D, 0x33, 0x17, 0xFC, 0x60, 0x6E, 0x56, 0x6D, - 0x30, 0x2E, 0xDA, 0xB5, 0x5E, 0x80, 0x16, 0x11, - 0xD8, 0xC1, 0x3F, 0x4A, 0x9A, 0x19, 0xD1, 0x85, - 0x97, 0x8D, 0xEF, 0x72, 0x83, 0x9C, 0xDA, 0xA3 - }, - { - 0x97, 0x38, 0x80, 0x11, 0xF5, 0x7A, 0x49, 0x86, - 0x90, 0xEC, 0x79, 0x88, 0xEF, 0xF9, 0x03, 0xFF, - 0x9B, 0x23, 0x58, 0xF5, 0xB6, 0x1B, 0xAA, 0x20, - 0xF7, 0x32, 0x90, 0xD6, 0x29, 0x6C, 0x1C, 0x0B - }, - { - 0xCF, 0xB8, 0x0C, 0xAB, 0x89, 0x90, 0x95, 0x08, - 0x09, 0x12, 0x3F, 0xBF, 0x85, 0xE9, 0x76, 0x45, - 0x47, 0x08, 0xE0, 0xAF, 0xED, 0x69, 0x8E, 0x33, - 0x52, 0xA3, 0x16, 0x35, 0x90, 0x9D, 0xB3, 0xE5 - }, - { - 0x0D, 0xAA, 0xCA, 0x55, 0x13, 0x2A, 0x23, 0x5B, - 0x83, 0x1A, 0x5E, 0xFF, 0x4E, 0xA4, 0x67, 0xCD, - 0x10, 0xAF, 0x44, 0x20, 0x08, 0x47, 0x73, 0x5A, - 0x1F, 0xFD, 0x51, 0xFA, 0x37, 0xEA, 0xA2, 0xA2 - }, - { - 0x69, 0xB2, 0x14, 0x97, 0xEB, 0xB8, 0x24, 0xBA, - 0x66, 0x53, 0x68, 0x18, 0x88, 0x25, 0xE6, 0xF6, - 0xF1, 0x4C, 0xF2, 0xC3, 0xF7, 0xB5, 0x53, 0x0B, - 0xB3, 0x4F, 0xA6, 0x58, 0xEE, 0xD9, 0xA7, 0x39 - }, - { - 0xB9, 0xA1, 0x9F, 0x50, 0x9B, 0xE0, 0x3F, 0xBC, - 0x40, 0xE2, 0x43, 0xA5, 0x8A, 0x3D, 0xED, 0x11, - 0xF0, 0xD5, 0x1F, 0x80, 0xE3, 0xE2, 0x9A, 0x50, - 0x56, 0x44, 0xCC, 0x05, 0x74, 0x38, 0x14, 0xEC - }, - { - 0xC4, 0xBC, 0xB2, 0x00, 0x25, 0x55, 0xD5, 0x44, - 0xFD, 0x0B, 0x02, 0x77, 0x06, 0x23, 0x89, 0x1E, - 0x70, 0xEE, 0xEC, 0x77, 0x44, 0x86, 0x5D, 0xD6, - 0x45, 0x5A, 0xD6, 0x65, 0xCC, 0x82, 0xE8, 0x61 - }, - { - 0x91, 0x2D, 0x24, 0xDC, 0x3D, 0x69, 0x23, 0xA4, - 0x83, 0xC2, 0x63, 0xEB, 0xA8, 0x1B, 0x7A, 0x87, - 0x97, 0xF2, 0x3C, 0xBF, 0x2F, 0x78, 0xB5, 0x1E, - 0x22, 0x26, 0x63, 0x9F, 0x84, 0xA5, 0x90, 0x47 - }, - { - 0x56, 0x82, 0x7A, 0x18, 0x88, 0x3A, 0xFD, 0xF9, - 0xCE, 0xEC, 0x56, 0x2B, 0x20, 0x66, 0xD8, 0xAC, - 0xB2, 0xC1, 0x95, 0x05, 0xEC, 0xE6, 0xF7, 0xA8, - 0x3E, 0x9F, 0x33, 0x46, 0xCB, 0xB8, 0x28, 0xC9 - }, - { - 0x25, 0x1D, 0x8D, 0x09, 0xFC, 0x48, 0xDD, 0x1D, - 0x6A, 0xF8, 0xFF, 0xDF, 0x39, 0x50, 0x91, 0xA4, - 0x6E, 0x05, 0xB8, 0xB7, 0xC5, 0xEC, 0x0C, 0x79, - 0xB6, 0x8A, 0x89, 0x04, 0xC8, 0x27, 0xBD, 0xEA - }, - { - 0xC2, 0xD1, 0x4D, 0x69, 0xFD, 0x0B, 0xBD, 0x1C, - 0x0F, 0xE8, 0xC8, 0x45, 0xD5, 0xFD, 0x6A, 0x8F, - 0x74, 0x01, 0x51, 0xB1, 0xD8, 0xEB, 0x4D, 0x26, - 0x36, 0x4B, 0xB0, 0x2D, 0xAE, 0x0C, 0x13, 0xBC - }, - { - 0x2E, 0x5F, 0xE2, 0x1F, 0x8F, 0x1B, 0x63, 0x97, - 0xA3, 0x8A, 0x60, 0x3D, 0x60, 0xB6, 0xF5, 0x3C, - 0x3B, 0x5D, 0xB2, 0x0A, 0xA5, 0x6C, 0x6D, 0x44, - 0xBE, 0xBD, 0x48, 0x28, 0xCE, 0x28, 0xF9, 0x0F - }, - { - 0x25, 0x05, 0x9F, 0x10, 0x60, 0x5E, 0x67, 0xAD, - 0xFE, 0x68, 0x13, 0x50, 0x66, 0x6E, 0x15, 0xAE, - 0x97, 0x6A, 0x5A, 0x57, 0x1C, 0x13, 0xCF, 0x5B, - 0xC8, 0x05, 0x3F, 0x43, 0x0E, 0x12, 0x0A, 0x52 - }, -}; - - - - -static const uint8_t blake2sp_keyed_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = -{ - { - 0x71, 0x5C, 0xB1, 0x38, 0x95, 0xAE, 0xB6, 0x78, - 0xF6, 0x12, 0x41, 0x60, 0xBF, 0xF2, 0x14, 0x65, - 0xB3, 0x0F, 0x4F, 0x68, 0x74, 0x19, 0x3F, 0xC8, - 0x51, 0xB4, 0x62, 0x10, 0x43, 0xF0, 0x9C, 0xC6 - }, - { - 0x40, 0x57, 0x8F, 0xFA, 0x52, 0xBF, 0x51, 0xAE, - 0x18, 0x66, 0xF4, 0x28, 0x4D, 0x3A, 0x15, 0x7F, - 0xC1, 0xBC, 0xD3, 0x6A, 0xC1, 0x3C, 0xBD, 0xCB, - 0x03, 0x77, 0xE4, 0xD0, 0xCD, 0x0B, 0x66, 0x03 - }, - { - 0x67, 0xE3, 0x09, 0x75, 0x45, 0xBA, 0xD7, 0xE8, - 0x52, 0xD7, 0x4D, 0x4E, 0xB5, 0x48, 0xEC, 0xA7, - 0xC2, 0x19, 0xC2, 0x02, 0xA7, 0xD0, 0x88, 0xDB, - 0x0E, 0xFE, 0xAC, 0x0E, 0xAC, 0x30, 0x42, 0x49 - }, - { - 0x8D, 0xBC, 0xC0, 0x58, 0x9A, 0x3D, 0x17, 0x29, - 0x6A, 0x7A, 0x58, 0xE2, 0xF1, 0xEF, 0xF0, 0xE2, - 0xAA, 0x42, 0x10, 0xB5, 0x8D, 0x1F, 0x88, 0xB8, - 0x6D, 0x7B, 0xA5, 0xF2, 0x9D, 0xD3, 0xB5, 0x83 - }, - { - 0xA9, 0xA9, 0x65, 0x2C, 0x8C, 0x67, 0x75, 0x94, - 0xC8, 0x72, 0x12, 0xD8, 0x9D, 0x5A, 0x75, 0xFB, - 0x31, 0xEF, 0x4F, 0x47, 0xC6, 0x58, 0x2C, 0xDE, - 0x5F, 0x1E, 0xF6, 0x6B, 0xD4, 0x94, 0x53, 0x3A - }, - { - 0x05, 0xA7, 0x18, 0x0E, 0x59, 0x50, 0x54, 0x73, - 0x99, 0x48, 0xC5, 0xE3, 0x38, 0xC9, 0x5F, 0xE0, - 0xB7, 0xFC, 0x61, 0xAC, 0x58, 0xA7, 0x35, 0x74, - 0x74, 0x56, 0x33, 0xBB, 0xC1, 0xF7, 0x70, 0x31 - }, - { - 0x81, 0x4D, 0xE8, 0x31, 0x53, 0xB8, 0xD7, 0x5D, - 0xFA, 0xDE, 0x29, 0xFD, 0x39, 0xAC, 0x72, 0xDD, - 0x09, 0xCA, 0x0F, 0x9B, 0xC8, 0xB7, 0xAB, 0x6A, - 0x06, 0xBA, 0xEE, 0x7D, 0xD0, 0xF9, 0xF0, 0x83 - }, - { - 0xDF, 0xD4, 0x19, 0x44, 0x91, 0x29, 0xFF, 0x60, - 0x4F, 0x0A, 0x14, 0x8B, 0x4C, 0x7D, 0x68, 0xF1, - 0x17, 0x4F, 0x7D, 0x0F, 0x8C, 0x8D, 0x2C, 0xE7, - 0x7F, 0x44, 0x8F, 0xD3, 0x41, 0x9C, 0x6F, 0xB0 - }, - { - 0xB9, 0xED, 0x22, 0xE7, 0xDD, 0x8D, 0xD1, 0x4E, - 0xE8, 0xC9, 0x5B, 0x20, 0xE7, 0x63, 0x2E, 0x85, - 0x53, 0xA2, 0x68, 0xD9, 0xFF, 0x86, 0x33, 0xED, - 0x3C, 0x21, 0xD1, 0xB8, 0xC9, 0xA7, 0x0B, 0xE1 - }, - { - 0x95, 0xF0, 0x31, 0x67, 0x1A, 0x4E, 0x3C, 0x54, - 0x44, 0x1C, 0xEE, 0x9D, 0xBE, 0xF4, 0xB7, 0xAC, - 0xA4, 0x46, 0x18, 0xA3, 0xA3, 0x33, 0xAD, 0x74, - 0x06, 0xD1, 0x97, 0xAC, 0x5B, 0xA0, 0x79, 0x1A - }, - { - 0xE2, 0x92, 0x5B, 0x9D, 0x5C, 0xA0, 0xFF, 0x62, - 0x88, 0xC5, 0xEA, 0x1A, 0xF2, 0xD2, 0x2B, 0x0A, - 0x6B, 0x79, 0xE2, 0xDA, 0xE0, 0x8B, 0xFD, 0x36, - 0xC3, 0xBE, 0x10, 0xBB, 0x8D, 0x71, 0xD8, 0x39 - }, - { - 0x16, 0x24, 0x9C, 0x74, 0x4E, 0x49, 0x51, 0x45, - 0x1D, 0x4C, 0x89, 0x4F, 0xB5, 0x9A, 0x3E, 0xCB, - 0x3F, 0xBF, 0xB7, 0xA4, 0x5F, 0x96, 0xF8, 0x5D, - 0x15, 0x80, 0xAC, 0x0B, 0x84, 0x2D, 0x96, 0xDA - }, - { - 0x43, 0x2B, 0xC9, 0x1C, 0x52, 0xAC, 0xEB, 0x9D, - 0xAE, 0xD8, 0x83, 0x28, 0x81, 0x64, 0x86, 0x50, - 0xC1, 0xB8, 0x1D, 0x11, 0x7A, 0xBD, 0x68, 0xE0, - 0x84, 0x51, 0x50, 0x8A, 0x63, 0xBE, 0x00, 0x81 - }, - { - 0xCD, 0xE8, 0x20, 0x2B, 0xCF, 0xA3, 0xF3, 0xE9, - 0x5D, 0x79, 0xBA, 0xCC, 0x16, 0x5D, 0x52, 0x70, - 0x0E, 0xF7, 0x1D, 0x87, 0x4A, 0x3C, 0x63, 0x7E, - 0x63, 0x4F, 0x64, 0x44, 0x73, 0x72, 0x0D, 0x6B - }, - { - 0x16, 0x21, 0x62, 0x1F, 0x5C, 0x3E, 0xE4, 0x46, - 0x89, 0x9D, 0x3C, 0x8A, 0xAE, 0x49, 0x17, 0xB1, - 0xE6, 0xDB, 0x4A, 0x0E, 0xD0, 0x42, 0x31, 0x5F, - 0xB2, 0xC1, 0x74, 0x82, 0x5E, 0x0A, 0x18, 0x19 - }, - { - 0x33, 0x6E, 0x8E, 0xBC, 0x71, 0xE2, 0x09, 0x5C, - 0x27, 0xF8, 0x64, 0xA3, 0x12, 0x1E, 0xFD, 0x0F, - 0xAA, 0x7A, 0x41, 0x28, 0x57, 0x25, 0xA5, 0x92, - 0xF6, 0x1B, 0xED, 0xED, 0x9D, 0xDE, 0x86, 0xED - }, - { - 0x07, 0x9B, 0xE0, 0x41, 0x0E, 0x78, 0x9B, 0x36, - 0xEE, 0x7F, 0x55, 0xC1, 0x9F, 0xAA, 0xC6, 0x91, - 0x65, 0x6E, 0xB0, 0x52, 0x1F, 0x42, 0x94, 0x9B, - 0x84, 0xEE, 0x29, 0xFE, 0x2A, 0x0E, 0x7F, 0x36 - }, - { - 0x17, 0x27, 0x0C, 0x4F, 0x34, 0x88, 0x08, 0x2D, - 0x9F, 0xF9, 0x93, 0x7E, 0xAB, 0x3C, 0xA9, 0x9C, - 0x97, 0xC5, 0xB4, 0x59, 0x61, 0x47, 0x37, 0x2D, - 0xD4, 0xE9, 0x8A, 0xCF, 0x13, 0xDB, 0x28, 0x10 - }, - { - 0x18, 0x3C, 0x38, 0x75, 0x4D, 0x03, 0x41, 0xCE, - 0x07, 0xC1, 0x7A, 0x6C, 0xB6, 0xC2, 0xFD, 0x8B, - 0xBC, 0xC1, 0x40, 0x4F, 0xDD, 0x01, 0x41, 0x99, - 0xC7, 0x8B, 0xE1, 0xA9, 0x75, 0x59, 0xA9, 0x28 - }, - { - 0x6E, 0x52, 0xD7, 0x28, 0xA4, 0x05, 0xA6, 0xE1, - 0xF8, 0x75, 0x87, 0xBB, 0xC2, 0xAC, 0x91, 0xC5, - 0xC0, 0x9B, 0x2D, 0x82, 0x8A, 0xC8, 0x1E, 0x5C, - 0x4A, 0x81, 0xD0, 0x3D, 0xD4, 0xAA, 0x8D, 0x5C - }, - { - 0xF4, 0xE0, 0x8E, 0x05, 0x9B, 0x74, 0x14, 0x4B, - 0xF9, 0x48, 0x14, 0x6D, 0x14, 0xA2, 0xC8, 0x1E, - 0x46, 0xDC, 0x15, 0xFF, 0x26, 0xEB, 0x52, 0x34, - 0x4C, 0xDD, 0x47, 0x4A, 0xBE, 0xA1, 0x4B, 0xC0 - }, - { - 0x0F, 0x2E, 0x0A, 0x10, 0x0E, 0xD8, 0xA1, 0x17, - 0x85, 0x96, 0x2A, 0xD4, 0x59, 0x6A, 0xF9, 0x55, - 0xE3, 0x0B, 0x9A, 0xEF, 0x93, 0x0A, 0x24, 0x8D, - 0xA9, 0x32, 0x2B, 0x70, 0x2D, 0x4B, 0x68, 0x72 - }, - { - 0x51, 0x90, 0xFC, 0xC7, 0x32, 0xF4, 0x04, 0xAA, - 0xD4, 0x36, 0x4A, 0xC7, 0x96, 0x0C, 0xFD, 0x5B, - 0x4E, 0x34, 0x86, 0x29, 0xC3, 0x72, 0xEE, 0xB3, - 0x25, 0xB5, 0xC6, 0xC7, 0xCB, 0xCE, 0x59, 0xAB - }, - { - 0xC0, 0xC4, 0xCB, 0x86, 0xEA, 0x25, 0xEA, 0x95, - 0x7E, 0xEC, 0x5B, 0x22, 0xD2, 0x55, 0x0A, 0x16, - 0x49, 0xE6, 0xDF, 0xFA, 0x31, 0x6B, 0xB8, 0xF4, - 0xC9, 0x1B, 0x8F, 0xF7, 0xA2, 0x4B, 0x25, 0x31 - }, - { - 0x2C, 0x9E, 0xDA, 0x13, 0x5A, 0x30, 0xAE, 0xCA, - 0xF3, 0xAC, 0xB3, 0xD2, 0x3A, 0x30, 0x35, 0xFB, - 0xAB, 0xBA, 0x98, 0x33, 0x31, 0x65, 0xD8, 0x7F, - 0xCB, 0xF8, 0xFE, 0x10, 0x33, 0x6E, 0xCF, 0x20 - }, - { - 0x3C, 0xD6, 0x69, 0xE8, 0xD5, 0x62, 0x62, 0xA2, - 0x37, 0x13, 0x67, 0x22, 0x4D, 0xAE, 0x6D, 0x75, - 0x9E, 0xE1, 0x52, 0xC3, 0x15, 0x33, 0xB2, 0x63, - 0xFA, 0x2E, 0x64, 0x92, 0x08, 0x77, 0xB2, 0xA7 - }, - { - 0x18, 0xA9, 0xA0, 0xC2, 0xD0, 0xEA, 0x6C, 0x3B, - 0xB3, 0x32, 0x83, 0x0F, 0x89, 0x18, 0xB0, 0x68, - 0x4F, 0x5D, 0x39, 0x94, 0xDF, 0x48, 0x67, 0x46, - 0x2D, 0xD0, 0x6E, 0xF0, 0x86, 0x24, 0x24, 0xCC - }, - { - 0x73, 0x90, 0xEA, 0x41, 0x04, 0xA9, 0xF4, 0xEE, - 0xA9, 0x0F, 0x81, 0xE2, 0x6A, 0x12, 0x9D, 0xCF, - 0x9F, 0x4A, 0xF3, 0x83, 0x52, 0xD9, 0xCB, 0x6A, - 0x81, 0x2C, 0xC8, 0x05, 0x69, 0x09, 0x05, 0x0E - }, - { - 0xE4, 0x9E, 0x01, 0x14, 0xC6, 0x29, 0xB4, 0x94, - 0xB1, 0x1E, 0xA9, 0x8E, 0xCD, 0x40, 0x32, 0x73, - 0x1F, 0x15, 0x3B, 0x46, 0x50, 0xAC, 0xAC, 0xD7, - 0xE0, 0xF6, 0xE7, 0xDE, 0x3D, 0xF0, 0x19, 0x77 - }, - { - 0x27, 0xC5, 0x70, 0x2B, 0xE1, 0x04, 0xB3, 0xA9, - 0x4F, 0xC4, 0x34, 0x23, 0xAE, 0xEE, 0x83, 0xAC, - 0x3C, 0xA7, 0x3B, 0x7F, 0x87, 0x83, 0x9A, 0x6B, - 0x2E, 0x29, 0x60, 0x79, 0x03, 0xB7, 0xF2, 0x87 - }, - { - 0x81, 0xD2, 0xE1, 0x2E, 0xB2, 0xF4, 0x27, 0x60, - 0xC6, 0xE3, 0xBA, 0xA7, 0x8F, 0x84, 0x07, 0x3A, - 0xE6, 0xF5, 0x61, 0x60, 0x70, 0xFE, 0x25, 0xBE, - 0xDE, 0x7C, 0x7C, 0x82, 0x48, 0xAB, 0x1F, 0xBA - }, - { - 0xFA, 0xB2, 0x35, 0xD5, 0x93, 0x48, 0xAB, 0x8C, - 0xE4, 0x9B, 0xEC, 0x77, 0xC0, 0xF1, 0x93, 0x28, - 0xFD, 0x04, 0x5D, 0xFD, 0x60, 0x8A, 0x53, 0x03, - 0x36, 0xDF, 0x4F, 0x94, 0xE1, 0x72, 0xA5, 0xC8 - }, - { - 0x8A, 0xAA, 0x8D, 0x80, 0x5C, 0x58, 0x88, 0x1F, - 0xF3, 0x79, 0xFB, 0xD4, 0x2C, 0x6B, 0xF6, 0xF1, - 0x4C, 0x6C, 0x73, 0xDF, 0x80, 0x71, 0xB3, 0xB2, - 0x28, 0x98, 0x11, 0x09, 0xCC, 0xC0, 0x15, 0xF9 - }, - { - 0x91, 0xFD, 0xD2, 0x62, 0x20, 0x39, 0x16, 0x39, - 0x47, 0x40, 0x95, 0x2B, 0xCE, 0x72, 0xB6, 0x4B, - 0xAB, 0xB6, 0xF7, 0x21, 0x34, 0x4D, 0xEE, 0x82, - 0x50, 0xBF, 0x0E, 0x46, 0xF1, 0xBA, 0x18, 0x8F - }, - { - 0xF7, 0xE5, 0x7B, 0x8F, 0x85, 0xF4, 0x7D, 0x59, - 0x03, 0xAD, 0x4C, 0xCB, 0x8A, 0xF6, 0x2A, 0x3E, - 0x85, 0x8A, 0xAB, 0x2B, 0x8C, 0xC2, 0x26, 0x49, - 0x4F, 0x7B, 0x00, 0xBE, 0xDB, 0xF5, 0xB0, 0xD0 - }, - { - 0xF7, 0x6F, 0x21, 0xAD, 0xDA, 0xE9, 0x6A, 0x96, - 0x46, 0xFC, 0x06, 0xF9, 0xBF, 0x52, 0xAE, 0x08, - 0x48, 0xF1, 0x8C, 0x35, 0x26, 0xB1, 0x29, 0xE1, - 0x5B, 0x2C, 0x35, 0x5E, 0x2E, 0x79, 0xE5, 0xDA - }, - { - 0x8A, 0xEB, 0x1C, 0x79, 0x5F, 0x34, 0x90, 0x01, - 0x5E, 0xF4, 0xCD, 0x61, 0xA2, 0x80, 0x7B, 0x23, - 0x0E, 0xFD, 0xC8, 0x46, 0x01, 0x73, 0xDA, 0xD0, - 0x26, 0xA4, 0xA0, 0xFC, 0xC2, 0xFB, 0xF2, 0x2A - }, - { - 0xC5, 0x64, 0xFF, 0xC6, 0x23, 0x07, 0x77, 0x65, - 0xBB, 0x97, 0x87, 0x58, 0x56, 0x54, 0xCE, 0x74, - 0x5D, 0xBD, 0x10, 0x8C, 0xEF, 0x24, 0x8A, 0xB0, - 0x0A, 0xD1, 0xA2, 0x64, 0x7D, 0x99, 0x03, 0x87 - }, - { - 0xFE, 0x89, 0x42, 0xA3, 0xE5, 0xF5, 0xE8, 0xCD, - 0x70, 0x51, 0x04, 0xF8, 0x82, 0x10, 0x72, 0x6E, - 0x53, 0xDD, 0x7E, 0xB3, 0xF9, 0xA2, 0x02, 0xBF, - 0x93, 0x14, 0xB3, 0xB9, 0x06, 0x5E, 0xB7, 0x12 - }, - { - 0xDC, 0x29, 0x53, 0x59, 0xD4, 0x36, 0xEE, 0xA7, - 0x80, 0x84, 0xE7, 0xB0, 0x77, 0xFE, 0x09, 0xB1, - 0x9C, 0x5B, 0xF3, 0xD2, 0xA7, 0x96, 0xDA, 0xB0, - 0x19, 0xE4, 0x20, 0x05, 0x99, 0xFD, 0x82, 0x02 - }, - { - 0x70, 0xB3, 0xF7, 0x2F, 0x74, 0x90, 0x32, 0xE2, - 0x5E, 0x38, 0x3B, 0x96, 0x43, 0x78, 0xEA, 0x1C, - 0x54, 0x3E, 0x9C, 0x15, 0xDE, 0x3A, 0x27, 0xD8, - 0x6D, 0x2A, 0x9D, 0x22, 0x31, 0xEF, 0xF4, 0x8A - }, - { - 0x79, 0x82, 0xB5, 0x4C, 0x08, 0xDB, 0x2B, 0xFB, - 0x6F, 0x45, 0xF3, 0x5B, 0xC3, 0x23, 0xBC, 0x09, - 0x37, 0x79, 0xB6, 0xBB, 0x0E, 0x3E, 0xEA, 0x3E, - 0x8C, 0x98, 0xB1, 0xDE, 0x99, 0xD3, 0xC5, 0x5E - }, - { - 0x75, 0xE4, 0x16, 0x22, 0x57, 0x01, 0x4B, 0xED, - 0xCC, 0x05, 0xC2, 0x94, 0x4D, 0xCE, 0x0D, 0xF0, - 0xC3, 0x5E, 0xBA, 0x13, 0x19, 0x54, 0x06, 0x4F, - 0x6E, 0x4E, 0x09, 0x5F, 0xD0, 0x84, 0x45, 0xEE - }, - { - 0x4A, 0x12, 0x9E, 0xA6, 0xCD, 0xBA, 0xBC, 0x2D, - 0x39, 0x24, 0x79, 0x37, 0x2F, 0x97, 0x5B, 0x9C, - 0xF5, 0xA1, 0xB7, 0xDE, 0xB6, 0x9A, 0x32, 0x66, - 0xF0, 0x3E, 0xBC, 0x6D, 0x11, 0x13, 0x93, 0xC4 - }, - { - 0x8F, 0xED, 0x70, 0xF2, 0x79, 0x55, 0xDC, 0x8A, - 0xD9, 0xF1, 0xB7, 0xB3, 0xF6, 0xF5, 0xDF, 0xBD, - 0x96, 0x2A, 0x33, 0x59, 0x2B, 0x42, 0xDE, 0x85, - 0x6D, 0x42, 0x1E, 0x29, 0x12, 0xBA, 0xB8, 0x6B - }, - { - 0xE2, 0xF2, 0x06, 0x60, 0x37, 0x6F, 0x2B, 0x18, - 0x39, 0x66, 0x7C, 0xBF, 0xE5, 0xE1, 0x6E, 0xF0, - 0x75, 0xAC, 0x39, 0x43, 0x64, 0x4F, 0x35, 0x32, - 0x28, 0x2F, 0x8B, 0xB0, 0x72, 0x3B, 0x99, 0x86 - }, - { - 0xAB, 0xF8, 0x4C, 0x91, 0x3A, 0x83, 0xDF, 0x98, - 0xC7, 0x00, 0x29, 0x81, 0x9C, 0x06, 0x5F, 0x6D, - 0x6D, 0xE4, 0xF6, 0xD4, 0x3A, 0xBF, 0x60, 0x0D, - 0xAD, 0xE0, 0x35, 0xB2, 0x3B, 0xED, 0x7B, 0xAA - }, - { - 0x45, 0x9C, 0x15, 0xD4, 0x85, 0x6C, 0x7E, 0xCF, - 0x82, 0x62, 0x03, 0x51, 0xC3, 0xC1, 0xC7, 0x6C, - 0x40, 0x3F, 0x3E, 0x97, 0x07, 0x74, 0x13, 0x87, - 0xE2, 0x99, 0x07, 0x3F, 0xB1, 0x70, 0x4B, 0x2B - }, - { - 0x9A, 0xB9, 0x12, 0xED, 0xA0, 0x76, 0x8A, 0xBD, - 0xF8, 0x26, 0xB6, 0xE0, 0x5D, 0x0D, 0x73, 0x58, - 0x39, 0xE6, 0xA5, 0xF0, 0x2E, 0x04, 0xC4, 0xCC, - 0x75, 0x65, 0x0B, 0x2C, 0x8C, 0xAB, 0x67, 0x49 - }, - { - 0x47, 0x40, 0xEB, 0xEC, 0xAC, 0x90, 0x03, 0x1B, - 0xB7, 0xE6, 0x8E, 0x51, 0xC5, 0x53, 0x91, 0xAF, - 0xB1, 0x89, 0xB3, 0x17, 0xF2, 0xDE, 0x55, 0x87, - 0x66, 0xF7, 0x8F, 0x5C, 0xB7, 0x1F, 0x81, 0xB6 - }, - { - 0x3C, 0xC4, 0x7F, 0x0E, 0xF6, 0x48, 0x21, 0x58, - 0x7C, 0x93, 0x7C, 0xDD, 0xBA, 0x85, 0xC9, 0x93, - 0xD3, 0xCE, 0x2D, 0xD0, 0xCE, 0xD4, 0x0D, 0x3B, - 0xE3, 0x3C, 0xB7, 0xDC, 0x7E, 0xDA, 0xBC, 0xF1 - }, - { - 0x9F, 0x47, 0x6A, 0x22, 0xDB, 0x54, 0xD6, 0xBB, - 0x9B, 0xEF, 0xDB, 0x26, 0x0C, 0x66, 0x57, 0x8A, - 0xE1, 0xD8, 0xA5, 0xF8, 0x7D, 0x3D, 0x8C, 0x01, - 0x7F, 0xDB, 0x74, 0x75, 0x08, 0x0F, 0xA8, 0xE1 - }, - { - 0x8B, 0x68, 0xC6, 0xFB, 0x07, 0x06, 0xA7, 0x95, - 0xF3, 0xA8, 0x39, 0xD6, 0xFE, 0x25, 0xFD, 0x4A, - 0xA7, 0xF9, 0x2E, 0x66, 0x4F, 0x76, 0x2D, 0x61, - 0x53, 0x81, 0xBC, 0x85, 0x9A, 0xFA, 0x29, 0x2C - }, - { - 0xF6, 0x40, 0xD2, 0x25, 0xA6, 0xBC, 0xD2, 0xFC, - 0x8A, 0xCC, 0xAF, 0xBE, 0xD5, 0xA8, 0x4B, 0x5B, - 0xBB, 0x5D, 0x8A, 0xE5, 0xDB, 0x06, 0xA1, 0x0B, - 0x6D, 0x9D, 0x93, 0x16, 0x0B, 0x39, 0x2E, 0xE0 - }, - { - 0x70, 0x48, 0x60, 0xA7, 0xF5, 0xBA, 0x68, 0xDB, - 0x27, 0x03, 0x1C, 0x15, 0xF2, 0x25, 0x50, 0x0D, - 0x69, 0x2A, 0xB2, 0x47, 0x53, 0x42, 0x81, 0xC4, - 0xF6, 0x84, 0xF6, 0xC6, 0xC8, 0xCD, 0x88, 0xC7 - }, - { - 0xC1, 0xA7, 0x5B, 0xDD, 0xA1, 0x2B, 0x8B, 0x2A, - 0xB1, 0xB9, 0x24, 0x84, 0x38, 0x58, 0x18, 0x3A, - 0x09, 0xD2, 0x02, 0x42, 0x1F, 0xDB, 0xCD, 0xF0, - 0xE6, 0x3E, 0xAE, 0x46, 0xF3, 0x7D, 0x91, 0xED - }, - { - 0x9A, 0x8C, 0xAB, 0x7A, 0x5F, 0x2E, 0x57, 0x62, - 0x21, 0xA6, 0xA8, 0x5E, 0x5F, 0xDD, 0xEE, 0x75, - 0x67, 0x8E, 0x06, 0x53, 0x24, 0xA6, 0x1D, 0xB0, - 0x3A, 0x39, 0x26, 0x1D, 0xDF, 0x75, 0xE3, 0xF4 - }, - { - 0x05, 0xC2, 0xB2, 0x6B, 0x03, 0xCE, 0x6C, 0xA5, - 0x87, 0x1B, 0xE0, 0xDE, 0x84, 0xEE, 0x27, 0x86, - 0xA7, 0x9B, 0xCD, 0x9F, 0x30, 0x03, 0x3E, 0x81, - 0x9B, 0x4A, 0x87, 0xCC, 0xA2, 0x7A, 0xFC, 0x6A - }, - { - 0xB0, 0xB0, 0x99, 0x3C, 0x6D, 0x0C, 0x6E, 0xD5, - 0xC3, 0x59, 0x04, 0x80, 0xF8, 0x65, 0xF4, 0x67, - 0xF4, 0x33, 0x1A, 0x58, 0xDD, 0x8E, 0x47, 0xBD, - 0x98, 0xEB, 0xBC, 0xDB, 0x8E, 0xB4, 0xF9, 0x4D - }, - { - 0xE5, 0x7C, 0x10, 0x3C, 0xF7, 0xB6, 0xBB, 0xEB, - 0x8A, 0x0D, 0xC8, 0xF0, 0x48, 0x62, 0x5C, 0x3F, - 0x4C, 0xE4, 0xF1, 0xA5, 0xAD, 0x4D, 0x07, 0x9C, - 0x11, 0x87, 0xBF, 0xE9, 0xEE, 0x3B, 0x8A, 0x5F - }, - { - 0xF1, 0x00, 0x23, 0xE1, 0x5F, 0x3B, 0x72, 0xB7, - 0x38, 0xAD, 0x61, 0xAE, 0x65, 0xAB, 0x9A, 0x07, - 0xE7, 0x77, 0x4E, 0x2D, 0x7A, 0xB0, 0x2D, 0xBA, - 0x4E, 0x0C, 0xAF, 0x56, 0x02, 0xC8, 0x01, 0x78 - }, - { - 0x9A, 0x8F, 0xB3, 0xB5, 0x38, 0xC1, 0xD6, 0xC4, - 0x50, 0x51, 0xFA, 0x9E, 0xD9, 0xB0, 0x7D, 0x3E, - 0x89, 0xB4, 0x43, 0x03, 0x30, 0x01, 0x4A, 0x1E, - 0xFA, 0x28, 0x23, 0xC0, 0x82, 0x3C, 0xF2, 0x37 - }, - { - 0x30, 0x75, 0xC5, 0xBC, 0x7C, 0x3A, 0xD7, 0xE3, - 0x92, 0x01, 0x01, 0xBC, 0x68, 0x99, 0xC5, 0x8E, - 0xA7, 0x01, 0x67, 0xA7, 0x77, 0x2C, 0xA2, 0x8E, - 0x38, 0xE2, 0xC1, 0xB0, 0xD3, 0x25, 0xE5, 0xA0 - }, - { - 0xE8, 0x55, 0x94, 0x70, 0x0E, 0x39, 0x22, 0xA1, - 0xE8, 0xE4, 0x1E, 0xB8, 0xB0, 0x64, 0xE7, 0xAC, - 0x6D, 0x94, 0x9D, 0x13, 0xB5, 0xA3, 0x45, 0x23, - 0xE5, 0xA6, 0xBE, 0xAC, 0x03, 0xC8, 0xAB, 0x29 - }, - { - 0x1D, 0x37, 0x01, 0xA5, 0x66, 0x1B, 0xD3, 0x1A, - 0xB2, 0x05, 0x62, 0xBD, 0x07, 0xB7, 0x4D, 0xD1, - 0x9A, 0xC8, 0xF3, 0x52, 0x4B, 0x73, 0xCE, 0x7B, - 0xC9, 0x96, 0xB7, 0x88, 0xAF, 0xD2, 0xF3, 0x17 - }, - { - 0x87, 0x4E, 0x19, 0x38, 0x03, 0x3D, 0x7D, 0x38, - 0x35, 0x97, 0xA2, 0xA6, 0x5F, 0x58, 0xB5, 0x54, - 0xE4, 0x11, 0x06, 0xF6, 0xD1, 0xD5, 0x0E, 0x9B, - 0xA0, 0xEB, 0x68, 0x5F, 0x6B, 0x6D, 0xA0, 0x71 - }, - { - 0x93, 0xF2, 0xF3, 0xD6, 0x9B, 0x2D, 0x36, 0x52, - 0x95, 0x56, 0xEC, 0xCA, 0xF9, 0xF9, 0x9A, 0xDB, - 0xE8, 0x95, 0xE1, 0x57, 0x22, 0x31, 0xE6, 0x49, - 0xB5, 0x05, 0x84, 0xB5, 0xD7, 0xD0, 0x8A, 0xF8 - }, - { - 0x06, 0xE0, 0x6D, 0x61, 0x0F, 0x2E, 0xEB, 0xBA, - 0x36, 0x76, 0x82, 0x3E, 0x77, 0x44, 0xD7, 0x51, - 0xAF, 0xF7, 0x30, 0x76, 0xED, 0x65, 0xF3, 0xCF, - 0xF5, 0xE7, 0x2F, 0xD2, 0x27, 0x99, 0x9C, 0x77 - }, - { - 0x8D, 0xF7, 0x57, 0xB3, 0xA1, 0xE0, 0xF4, 0x80, - 0xFA, 0x76, 0xC7, 0xF3, 0x58, 0xED, 0x03, 0x98, - 0xBE, 0x3F, 0x2A, 0x8F, 0x7B, 0x90, 0xEA, 0x8C, - 0x80, 0x75, 0x99, 0xDE, 0xDA, 0x1D, 0x05, 0x34 - }, - { - 0xEE, 0xC9, 0xC5, 0xC6, 0x3C, 0xC5, 0x16, 0x9D, - 0x96, 0x7B, 0xB1, 0x62, 0x4E, 0x9E, 0xE5, 0xCE, - 0xD9, 0x28, 0x97, 0x73, 0x6E, 0xFB, 0xD1, 0x57, - 0x54, 0x8D, 0x82, 0xE8, 0x7C, 0xC7, 0x2F, 0x25 - }, - { - 0xCC, 0x2B, 0x58, 0x32, 0xAD, 0x27, 0x2C, 0xC5, - 0x5C, 0x10, 0xD4, 0xF8, 0xC7, 0xF8, 0xBB, 0x38, - 0xE6, 0xE4, 0xEB, 0x92, 0x2F, 0x93, 0x86, 0x83, - 0x0F, 0x90, 0xB1, 0xE3, 0xDA, 0x39, 0x37, 0xD5 - }, - { - 0x36, 0x89, 0x85, 0xD5, 0x38, 0x7C, 0x0B, 0xFC, - 0x92, 0x8A, 0xC2, 0x54, 0xFA, 0x6D, 0x16, 0x67, - 0x3E, 0x70, 0x94, 0x75, 0x66, 0x96, 0x1B, 0x5F, - 0xB3, 0x32, 0x5A, 0x58, 0x8A, 0xB3, 0x17, 0x3A - }, - { - 0xF1, 0xE4, 0x42, 0xAF, 0xB8, 0x72, 0x15, 0x1F, - 0x81, 0x34, 0x95, 0x6C, 0x54, 0x8A, 0xE3, 0x24, - 0x0D, 0x07, 0xE6, 0xE3, 0x38, 0xD4, 0xA7, 0xA6, - 0xAF, 0x8D, 0xA4, 0x11, 0x9A, 0xB0, 0xE2, 0xB0 - }, - { - 0xB0, 0x12, 0xC7, 0x54, 0x6A, 0x39, 0xC4, 0x0C, - 0xAD, 0xEC, 0xE4, 0xE0, 0x4E, 0x7F, 0x33, 0xC5, - 0x93, 0xAD, 0x18, 0x2E, 0xBC, 0x5A, 0x46, 0xD2, - 0xDB, 0xF4, 0xAD, 0x1A, 0x92, 0xF5, 0x9E, 0x7B - }, - { - 0x6C, 0x60, 0x97, 0xCD, 0x20, 0x33, 0x09, 0x6B, - 0x4D, 0xF3, 0x17, 0xDE, 0x8A, 0x90, 0x8B, 0x7D, - 0x0C, 0x72, 0x94, 0x39, 0x0C, 0x5A, 0x39, 0x9C, - 0x30, 0x1B, 0xF2, 0xA2, 0x65, 0x2E, 0x82, 0x62 - }, - { - 0xBA, 0x83, 0xFE, 0xB5, 0x10, 0xB4, 0x9A, 0xDE, - 0x4F, 0xAE, 0xFB, 0xE9, 0x42, 0x78, 0x1E, 0xAF, - 0xD4, 0x1A, 0xD5, 0xD4, 0x36, 0x88, 0x85, 0x31, - 0xB6, 0x88, 0x59, 0xF2, 0x2C, 0x2D, 0x16, 0x4A - }, - { - 0x5A, 0x06, 0x9E, 0x43, 0x92, 0x19, 0x5A, 0xC9, - 0xD2, 0x84, 0xA4, 0x7F, 0x3B, 0xD8, 0x54, 0xAF, - 0x8F, 0xD0, 0xD7, 0xFD, 0xC3, 0x48, 0x3D, 0x2C, - 0x5F, 0x34, 0x24, 0xCC, 0xFD, 0xA1, 0x5C, 0x8E - }, - { - 0x7E, 0x88, 0xD6, 0x4B, 0xBB, 0xE2, 0x02, 0x4F, - 0x44, 0x54, 0xBA, 0x13, 0x98, 0xB3, 0xD8, 0x65, - 0x2D, 0xCE, 0xC8, 0x20, 0xB1, 0x4C, 0x3B, 0x0A, - 0xBF, 0xBF, 0x0F, 0x4F, 0x33, 0x06, 0xBB, 0x5E - }, - { - 0xF8, 0x74, 0x2F, 0xF4, 0x6D, 0xFD, 0xF3, 0xEC, - 0x82, 0x64, 0xF9, 0x94, 0x5B, 0x20, 0x41, 0x94, - 0x62, 0xF0, 0x69, 0xE8, 0x33, 0xC5, 0x94, 0xEC, - 0x80, 0xFF, 0xAC, 0x5E, 0x7E, 0x51, 0x34, 0xF9 - }, - { - 0xD3, 0xE0, 0xB7, 0x38, 0xD2, 0xE9, 0x2F, 0x3C, - 0x47, 0xC7, 0x94, 0x66, 0x66, 0x09, 0xC0, 0xF5, - 0x50, 0x4F, 0x67, 0xEC, 0x4E, 0x76, 0x0E, 0xEE, - 0xCC, 0xF8, 0x64, 0x4E, 0x68, 0x33, 0x34, 0x11 - }, - { - 0x0C, 0x90, 0xCE, 0x10, 0xED, 0xF0, 0xCE, 0x1D, - 0x47, 0xEE, 0xB5, 0x0B, 0x5B, 0x7A, 0xFF, 0x8E, - 0xE8, 0xA4, 0x3B, 0x64, 0xA8, 0x89, 0xC1, 0xC6, - 0xC6, 0xB8, 0xE3, 0x1A, 0x3C, 0xFC, 0x45, 0xEE - }, - { - 0x83, 0x91, 0x7A, 0xC1, 0xCD, 0xAD, 0xE8, 0xF0, - 0xE3, 0xBF, 0x42, 0x6F, 0xEA, 0xC1, 0x38, 0x8B, - 0x3F, 0xCB, 0xE3, 0xE1, 0xBF, 0x98, 0x79, 0x8C, - 0x81, 0x58, 0xBF, 0x75, 0x8E, 0x8D, 0x5D, 0x4E - }, - { - 0xDC, 0x8E, 0xB0, 0xC0, 0x13, 0xFA, 0x9D, 0x06, - 0x4E, 0xE3, 0x76, 0x23, 0x36, 0x9F, 0xB3, 0x94, - 0xAF, 0x97, 0x4B, 0x1A, 0xAC, 0x82, 0x40, 0x5B, - 0x88, 0x97, 0x6C, 0xD8, 0xFC, 0xA1, 0x25, 0x30 - }, - { - 0x9A, 0xF4, 0xFC, 0x92, 0xEA, 0x8D, 0x6B, 0x5F, - 0xE7, 0x99, 0x0E, 0x3A, 0x02, 0x70, 0x1E, 0xC2, - 0x2B, 0x2D, 0xFD, 0x71, 0x00, 0xB9, 0x0D, 0x05, - 0x51, 0x86, 0x94, 0x17, 0x95, 0x5E, 0x44, 0xC8 - }, - { - 0xC7, 0x22, 0xCE, 0xC1, 0x31, 0xBA, 0xA1, 0x63, - 0xF4, 0x7E, 0x4B, 0x33, 0x9E, 0x1F, 0xB9, 0xB4, - 0xAC, 0xA2, 0x48, 0xC4, 0x75, 0x93, 0x45, 0xEA, - 0xDB, 0xD6, 0xC6, 0xA7, 0xDD, 0xB5, 0x04, 0x77 - }, - { - 0x18, 0x37, 0xB1, 0x20, 0xD4, 0xE4, 0x04, 0x6C, - 0x6D, 0xE8, 0xCC, 0xAF, 0x09, 0xF1, 0xCA, 0xF3, - 0x02, 0xAD, 0x56, 0x23, 0x4E, 0x6B, 0x42, 0x2C, - 0xE9, 0x0A, 0x61, 0xBF, 0x06, 0xAE, 0xE4, 0x3D - }, - { - 0x87, 0xAC, 0x9D, 0x0F, 0x8A, 0x0B, 0x11, 0xBF, - 0xED, 0xD6, 0x99, 0x1A, 0x6D, 0xAF, 0x34, 0xC8, - 0xAA, 0x5D, 0x7E, 0x8A, 0xE1, 0xB9, 0xDF, 0x4A, - 0xF7, 0x38, 0x00, 0x5F, 0xE7, 0x8C, 0xE9, 0x3C - }, - { - 0xE2, 0x1F, 0xB6, 0x68, 0xEB, 0xB8, 0xBF, 0x2D, - 0x82, 0x08, 0x6D, 0xED, 0xCB, 0x3A, 0x53, 0x71, - 0xC2, 0xC4, 0x6F, 0xA1, 0xAC, 0x11, 0xD2, 0xE2, - 0xC5, 0x66, 0xD1, 0x4A, 0xD3, 0xC3, 0x65, 0x3F - }, - { - 0x5A, 0x9A, 0x69, 0x81, 0x5E, 0x4D, 0x3E, 0xB7, - 0x72, 0xED, 0x90, 0x8F, 0xE6, 0x58, 0xCE, 0x50, - 0x87, 0x31, 0x0E, 0xC1, 0xD5, 0x0C, 0xB9, 0x4F, - 0x56, 0x28, 0x33, 0x9A, 0x61, 0xDC, 0xD9, 0xEE - }, - { - 0xAA, 0xC2, 0x85, 0xF1, 0x20, 0x8F, 0x70, 0xA6, - 0x47, 0x97, 0xD0, 0xA9, 0x40, 0x0D, 0xA6, 0x46, - 0x53, 0x30, 0x18, 0x38, 0xFE, 0xF6, 0x69, 0x0B, - 0x87, 0xCD, 0xA9, 0x15, 0x9E, 0xE0, 0x7E, 0xF4 - }, - { - 0x05, 0x64, 0x3C, 0x1C, 0x6F, 0x26, 0x59, 0x25, - 0xA6, 0x50, 0x93, 0xF9, 0xDE, 0x8A, 0x19, 0x1C, - 0x4F, 0x6F, 0xD1, 0x41, 0x8F, 0xBF, 0x66, 0xBE, - 0x80, 0x59, 0xA9, 0x1B, 0xA8, 0xDC, 0xDA, 0x61 - }, - { - 0x1C, 0x6C, 0xDE, 0x5B, 0x78, 0x10, 0x3C, 0x9E, - 0x6F, 0x04, 0x6D, 0xFE, 0x30, 0xF5, 0x12, 0x1C, - 0xF9, 0xD4, 0x03, 0x9E, 0xFE, 0x22, 0x25, 0x40, - 0xA4, 0x1B, 0xBC, 0x06, 0xE4, 0x69, 0xFE, 0xB6 - }, - { - 0xB4, 0x9B, 0xB4, 0x6D, 0x1B, 0x19, 0x3B, 0x04, - 0x5E, 0x74, 0x12, 0x05, 0x9F, 0xE7, 0x2D, 0x55, - 0x25, 0x52, 0xA8, 0xFB, 0x6C, 0x36, 0x41, 0x07, - 0x23, 0xDC, 0x7D, 0x05, 0xFC, 0xCE, 0xDE, 0xD3 - }, - { - 0xB6, 0x12, 0xD3, 0xD2, 0x1F, 0xC4, 0xDE, 0x3C, - 0x79, 0x1A, 0xF7, 0x35, 0xE5, 0x9F, 0xB7, 0x17, - 0xD8, 0x39, 0x72, 0x3B, 0x42, 0x50, 0x8E, 0x9E, - 0xBF, 0x78, 0x06, 0xD9, 0x3E, 0x9C, 0x83, 0x7F - }, - { - 0x7C, 0x33, 0x90, 0xA3, 0xE5, 0xCB, 0x27, 0xD1, - 0x86, 0x8B, 0xA4, 0x55, 0xCF, 0xEB, 0x32, 0x22, - 0xFD, 0xE2, 0x7B, 0xCD, 0xA4, 0xBF, 0x24, 0x8E, - 0x3D, 0x29, 0xCF, 0x1F, 0x34, 0x32, 0x9F, 0x25 - }, - { - 0xBD, 0x42, 0xEE, 0xA7, 0xB3, 0x54, 0x86, 0xCD, - 0xD0, 0x90, 0x7C, 0xB4, 0x71, 0x2E, 0xDE, 0x2F, - 0x4D, 0xEE, 0xCC, 0xBC, 0xA1, 0x91, 0x60, 0x38, - 0x65, 0xA1, 0xCC, 0x80, 0x9F, 0x12, 0xB4, 0x46 - }, - { - 0xD1, 0xDD, 0x62, 0x01, 0x74, 0x0C, 0xFA, 0xAD, - 0x53, 0xCE, 0xCC, 0xB7, 0x56, 0xB1, 0x10, 0xF3, - 0xD5, 0x0F, 0x81, 0x7B, 0x43, 0xD7, 0x55, 0x95, - 0x57, 0xE5, 0x7A, 0xAD, 0x14, 0x3A, 0x85, 0xD9 - }, - { - 0x58, 0x29, 0x64, 0x3C, 0x1B, 0x10, 0xE1, 0xC8, - 0xCC, 0xF2, 0x0C, 0x9B, 0x4A, 0xF8, 0x21, 0xEA, - 0x05, 0x2D, 0x7F, 0x0F, 0x7C, 0x22, 0xF7, 0x38, - 0x0B, 0xBB, 0xCF, 0xAF, 0xB9, 0x77, 0xE2, 0x1F - }, - { - 0xFC, 0x4C, 0xF2, 0xA7, 0xFB, 0xE0, 0xB1, 0xE8, - 0xAE, 0xFB, 0xE4, 0xB4, 0xB7, 0x9E, 0xD8, 0x4E, - 0xC9, 0x7B, 0x03, 0x4F, 0x51, 0xB4, 0xE9, 0x7F, - 0x76, 0x0B, 0x20, 0x63, 0x97, 0x65, 0xB9, 0x33 - }, - { - 0x4D, 0x7C, 0x3B, 0x34, 0x38, 0xA0, 0xBD, 0xA2, - 0x8E, 0x7A, 0x96, 0xE4, 0x20, 0x27, 0xD8, 0x13, - 0xE8, 0x8A, 0xE6, 0x28, 0x85, 0x49, 0x98, 0x33, - 0xD3, 0xC5, 0xF6, 0x35, 0x9E, 0xF7, 0xED, 0xBC - }, - { - 0x34, 0xCB, 0xD3, 0x20, 0x68, 0xEF, 0x7E, 0x82, - 0x09, 0x9E, 0x58, 0x0B, 0xF9, 0xE2, 0x64, 0x23, - 0xE9, 0x81, 0xE3, 0x1B, 0x1B, 0xBC, 0xE6, 0x1A, - 0xEA, 0xB1, 0x4C, 0x32, 0xA2, 0x73, 0xE4, 0xCB - }, - { - 0xA0, 0x5D, 0xDA, 0x7D, 0x0D, 0xA9, 0xE0, 0x94, - 0xAE, 0x22, 0x53, 0x3F, 0x79, 0xE7, 0xDC, 0xCD, - 0x26, 0xB1, 0x75, 0x7C, 0xEF, 0xB9, 0x5B, 0xCF, - 0x62, 0xC4, 0xFF, 0x9C, 0x26, 0x92, 0xE1, 0xC0 - }, - { - 0x22, 0x4C, 0xCF, 0xFA, 0x7C, 0xCA, 0x4C, 0xE3, - 0x4A, 0xFD, 0x47, 0xF6, 0x2A, 0xDE, 0x53, 0xC5, - 0xE8, 0x48, 0x9B, 0x04, 0xAC, 0x9C, 0x41, 0xF7, - 0xFA, 0xD0, 0xC8, 0xED, 0xEB, 0x89, 0xE9, 0x41 - }, - { - 0x6B, 0xC6, 0x07, 0x64, 0x83, 0xAA, 0x11, 0xC0, - 0x7F, 0xBA, 0x55, 0xC0, 0xF9, 0xA1, 0xB5, 0xDA, - 0x87, 0xEC, 0xBF, 0xFE, 0xA7, 0x55, 0x98, 0xCC, - 0x31, 0x8A, 0x51, 0x4C, 0xEC, 0x7B, 0x3B, 0x6A - }, - { - 0x9A, 0x03, 0x60, 0xE2, 0x3A, 0x22, 0xF4, 0xF7, - 0x6C, 0x0E, 0x95, 0x28, 0xDA, 0xFD, 0x12, 0x9B, - 0xB4, 0x67, 0x5F, 0xB8, 0x8D, 0x44, 0xEA, 0xF8, - 0x57, 0x77, 0x30, 0x0C, 0xEC, 0x9B, 0xCC, 0x79 - }, - { - 0x79, 0x01, 0x99, 0xB4, 0xCA, 0x90, 0xDE, 0xDC, - 0xCF, 0xE3, 0x24, 0x74, 0xE8, 0x5B, 0x17, 0x4F, - 0x06, 0x9E, 0x35, 0x42, 0xBE, 0x31, 0x04, 0xC1, - 0x12, 0x5C, 0x2F, 0xDB, 0xD6, 0x9D, 0x32, 0xC7 - }, - { - 0x55, 0x83, 0x99, 0x25, 0x83, 0x4C, 0xA3, 0xE8, - 0x25, 0xE9, 0x92, 0x41, 0x87, 0x4D, 0x16, 0xD6, - 0xC2, 0x62, 0x36, 0x29, 0xC4, 0xC2, 0xAD, 0xDD, - 0xF0, 0xDB, 0xA0, 0x1E, 0x6C, 0xE8, 0xA0, 0xDC - }, - { - 0x61, 0x5F, 0xF8, 0x46, 0xD9, 0x93, 0x00, 0x7D, - 0x38, 0xDE, 0x1A, 0xEC, 0xB3, 0x17, 0x82, 0x89, - 0xDE, 0xD0, 0x9E, 0x6B, 0xB5, 0xCB, 0xD6, 0x0F, - 0x69, 0xC6, 0xAA, 0x36, 0x38, 0x30, 0x20, 0xF7 - }, - { - 0xF0, 0xE4, 0x0B, 0x4E, 0xD4, 0x0D, 0x34, 0x85, - 0x1E, 0x72, 0xB4, 0xEE, 0x4D, 0x00, 0xEA, 0x6A, - 0x40, 0xEA, 0x1C, 0x1B, 0xF9, 0xE5, 0xC2, 0x69, - 0x71, 0x0C, 0x9D, 0x51, 0xCB, 0xB8, 0xA3, 0xC9 - }, - { - 0x0B, 0x07, 0xB2, 0x33, 0x3B, 0x08, 0xD0, 0x8C, - 0x11, 0xCA, 0x34, 0xAB, 0x44, 0x9B, 0x71, 0xD2, - 0x9A, 0x0F, 0x43, 0xE1, 0xF7, 0x78, 0xE0, 0x73, - 0xE7, 0x90, 0x06, 0xCC, 0xB7, 0x30, 0xED, 0x62 - }, - { - 0xD1, 0xF4, 0xC2, 0x9D, 0x9F, 0x23, 0xEA, 0x35, - 0xEC, 0x40, 0x35, 0xB3, 0x77, 0xD5, 0x06, 0x53, - 0x8E, 0x72, 0x8B, 0xC7, 0x39, 0xC1, 0x45, 0x96, - 0x80, 0xCF, 0x1C, 0xC6, 0x94, 0x24, 0x92, 0x4D - }, - { - 0x12, 0x79, 0xCF, 0x6F, 0x66, 0x9F, 0x92, 0xF6, - 0xBF, 0xC2, 0x5D, 0x60, 0x5B, 0x94, 0x40, 0xC7, - 0xDC, 0xCB, 0xD2, 0x5D, 0xF2, 0x8D, 0xC7, 0x35, - 0x3A, 0xBC, 0x1C, 0x05, 0x30, 0x40, 0x5D, 0xC4 - }, - { - 0x1F, 0xA0, 0xAF, 0x00, 0x77, 0x5D, 0xC2, 0xCE, - 0x76, 0x50, 0x6D, 0x32, 0x80, 0xF4, 0x72, 0xD2, - 0xF6, 0xFF, 0x97, 0xA2, 0x15, 0x1F, 0xAA, 0x82, - 0x79, 0x42, 0xFE, 0xA4, 0x4A, 0xD0, 0xBA, 0x1F - }, - { - 0x3E, 0x1A, 0xD5, 0x4A, 0x5F, 0x83, 0x5B, 0x98, - 0x3B, 0xD2, 0xAA, 0xB0, 0xED, 0x2A, 0x4C, 0x0B, - 0xDD, 0x72, 0x16, 0x20, 0x9C, 0x36, 0xA7, 0x9E, - 0x9E, 0x2A, 0xAB, 0xB9, 0x9F, 0xAF, 0x35, 0x12 - }, - { - 0xC6, 0xED, 0x39, 0xE2, 0xD8, 0xB6, 0x36, 0xEC, - 0xCB, 0xA2, 0x45, 0xEF, 0x4E, 0x88, 0x64, 0xF4, - 0xCD, 0x94, 0x6B, 0xE2, 0x16, 0xB9, 0xBE, 0x48, - 0x30, 0x3E, 0x08, 0xB9, 0x2D, 0xD0, 0x94, 0x34 - }, - { - 0xE2, 0x47, 0x36, 0xC1, 0x3E, 0xCB, 0x9F, 0x36, - 0xA0, 0xD8, 0x29, 0xD4, 0x79, 0x8D, 0x76, 0x99, - 0xC1, 0x4C, 0xC6, 0x5B, 0x6D, 0xC4, 0x4E, 0xD6, - 0xF1, 0x0C, 0xD4, 0x85, 0x3D, 0x6E, 0x07, 0x57 - }, - { - 0x38, 0x9B, 0xE8, 0x80, 0x52, 0xA3, 0x81, 0x27, - 0x2C, 0x6D, 0xF7, 0x41, 0xA8, 0x8A, 0xD3, 0x49, - 0xB7, 0x12, 0x71, 0x84, 0x35, 0x48, 0x0A, 0x81, - 0x90, 0xB7, 0x04, 0x77, 0x1D, 0x2D, 0xE6, 0x37 - }, - { - 0x88, 0x9F, 0x2D, 0x57, 0x8A, 0x5D, 0xAE, 0xFD, - 0x34, 0x1C, 0x21, 0x09, 0x84, 0xE1, 0x26, 0xD1, - 0xD9, 0x6D, 0xA2, 0xDE, 0xE3, 0xC8, 0x1F, 0x7A, - 0x60, 0x80, 0xBF, 0x84, 0x56, 0x9B, 0x31, 0x14 - }, - { - 0xE9, 0x36, 0x09, 0x5B, 0x9B, 0x98, 0x2F, 0xFC, - 0x85, 0x6D, 0x2F, 0x52, 0x76, 0xA4, 0xE5, 0x29, - 0xEC, 0x73, 0x95, 0xDA, 0x31, 0x6D, 0x62, 0x87, - 0x02, 0xFB, 0x28, 0x1A, 0xDA, 0x6F, 0x38, 0x99 - }, - { - 0xEF, 0x89, 0xCE, 0x1D, 0x6F, 0x8B, 0x48, 0xEA, - 0x5C, 0xD6, 0xAE, 0xAB, 0x6A, 0x83, 0xD0, 0xCC, - 0x98, 0xC9, 0xA3, 0xA2, 0x07, 0xA1, 0x08, 0x57, - 0x32, 0xF0, 0x47, 0xD9, 0x40, 0x38, 0xC2, 0x88 - }, - { - 0xF9, 0x25, 0x01, 0x6D, 0x79, 0xF2, 0xAC, 0xA8, - 0xC4, 0x9E, 0xDF, 0xCD, 0x66, 0x21, 0xD5, 0xBE, - 0x3C, 0x8C, 0xEC, 0x61, 0xBD, 0x58, 0x71, 0xD8, - 0xC1, 0xD3, 0xA5, 0x65, 0xF3, 0x5E, 0x0C, 0x9F - }, - { - 0x63, 0xE8, 0x63, 0x4B, 0x75, 0x7A, 0x38, 0xF9, - 0x2B, 0x92, 0xFD, 0x23, 0x89, 0x3B, 0xA2, 0x99, - 0x85, 0x3A, 0x86, 0x13, 0x67, 0x9F, 0xDF, 0x7E, - 0x05, 0x11, 0x09, 0x5C, 0x0F, 0x04, 0x7B, 0xCA - }, - { - 0xCF, 0x2C, 0xCA, 0x07, 0x72, 0xB7, 0x05, 0xEB, - 0x57, 0xD2, 0x89, 0x43, 0xF8, 0x3D, 0x35, 0x3F, - 0xE2, 0x91, 0xE5, 0xB3, 0x77, 0x78, 0x0B, 0x37, - 0x4C, 0x8B, 0xA4, 0x66, 0x58, 0x30, 0xBE, 0x87 - }, - { - 0x46, 0xDF, 0x5B, 0x87, 0xC8, 0x0E, 0x7E, 0x40, - 0x74, 0xAE, 0xE6, 0x85, 0x59, 0x42, 0x47, 0x42, - 0x84, 0x5B, 0x9B, 0x35, 0x0F, 0x51, 0xBA, 0x55, - 0xB0, 0x74, 0xBB, 0xAE, 0x4C, 0x62, 0x6A, 0xAB - }, - { - 0x65, 0x8A, 0xA4, 0xF9, 0xD2, 0xBC, 0xBD, 0x4F, - 0x7F, 0x8E, 0xB6, 0x3E, 0x68, 0xF5, 0x36, 0x7E, - 0xDB, 0xC5, 0x00, 0xA0, 0xB1, 0xFB, 0xB4, 0x1E, - 0x9D, 0xF1, 0x41, 0xBC, 0xBA, 0x8F, 0xCD, 0x53 - }, - { - 0xEE, 0x80, 0x55, 0x50, 0x08, 0xA7, 0x16, 0x55, - 0xE0, 0x81, 0x09, 0x2B, 0xBA, 0x6F, 0x67, 0x0E, - 0xD9, 0x8A, 0xF9, 0xA0, 0x9F, 0xB5, 0xAF, 0xB9, - 0x4C, 0xBC, 0x5C, 0x75, 0x48, 0x14, 0xDB, 0x4F - }, - { - 0x2C, 0x5F, 0x9D, 0x04, 0x82, 0x20, 0xB0, 0x41, - 0xB6, 0xD4, 0x52, 0x4B, 0x44, 0x90, 0xCF, 0x8C, - 0x66, 0xFC, 0xB8, 0xE1, 0x4B, 0x0D, 0x64, 0x88, - 0x7A, 0xA1, 0xE4, 0x76, 0x1A, 0x60, 0x2B, 0x39 - }, - { - 0x44, 0xCB, 0x63, 0x11, 0xD0, 0x75, 0x0B, 0x7E, - 0x33, 0xF7, 0x33, 0x3A, 0xA7, 0x8A, 0xAC, 0xA9, - 0xC3, 0x4A, 0xD5, 0xF7, 0x9C, 0x1B, 0x15, 0x91, - 0xEC, 0x33, 0x95, 0x1E, 0x69, 0xC4, 0xC4, 0x61 - }, - { - 0x0C, 0x6C, 0xE3, 0x2A, 0x3E, 0xA0, 0x56, 0x12, - 0xC5, 0xF8, 0x09, 0x0F, 0x6A, 0x7E, 0x87, 0xF5, - 0xAB, 0x30, 0xE4, 0x1B, 0x70, 0x7D, 0xCB, 0xE5, - 0x41, 0x55, 0x62, 0x0A, 0xD7, 0x70, 0xA3, 0x40 - }, - { - 0xC6, 0x59, 0x38, 0xDD, 0x3A, 0x05, 0x3C, 0x72, - 0x9C, 0xF5, 0xB7, 0xC8, 0x9F, 0x39, 0x0B, 0xFE, - 0xBB, 0x51, 0x12, 0x76, 0x6B, 0xB0, 0x0A, 0xA5, - 0xFA, 0x31, 0x64, 0xDF, 0xDF, 0x3B, 0x56, 0x47 - }, - { - 0x7D, 0xE7, 0xF0, 0xD5, 0x9A, 0x90, 0x39, 0xAF, - 0xF3, 0xAA, 0xF3, 0x2C, 0x3E, 0xE5, 0x2E, 0x79, - 0x17, 0x53, 0x57, 0x29, 0x06, 0x21, 0x68, 0xD2, - 0x49, 0x0B, 0x6B, 0x6C, 0xE2, 0x44, 0xB3, 0x80 - }, - { - 0x89, 0x58, 0x98, 0xF5, 0x3A, 0x8F, 0x39, 0xE4, - 0x24, 0x10, 0xDA, 0x77, 0xB6, 0xC4, 0x81, 0x5B, - 0x0B, 0xB2, 0x39, 0x5E, 0x39, 0x22, 0xF5, 0xBE, - 0xD0, 0xE1, 0xFB, 0xF2, 0xA4, 0xC6, 0xDF, 0xEB - }, - { - 0xC9, 0x05, 0xA8, 0x49, 0x84, 0x34, 0x8A, 0x64, - 0xDB, 0x1F, 0x54, 0x20, 0x83, 0x74, 0x8A, 0xD9, - 0x0A, 0x4B, 0xAD, 0x98, 0x33, 0xCB, 0x6D, 0xA3, - 0x87, 0x29, 0x34, 0x31, 0xF1, 0x9E, 0x7C, 0x9C - }, - { - 0xED, 0x37, 0xD1, 0xA4, 0xD0, 0x6C, 0x90, 0xD1, - 0x95, 0x78, 0x48, 0x66, 0x7E, 0x95, 0x48, 0xFE, - 0xBB, 0x5D, 0x42, 0x3E, 0xAB, 0x4F, 0x56, 0x78, - 0x5C, 0xC4, 0xB5, 0x41, 0x6B, 0x78, 0x00, 0x08 - }, - { - 0x0B, 0xC6, 0x5D, 0x99, 0x97, 0xFB, 0x73, 0x4A, - 0x56, 0x1F, 0xB1, 0xE9, 0xF8, 0xC0, 0x95, 0x8A, - 0x02, 0xC7, 0xA4, 0xDB, 0xD0, 0x96, 0xEB, 0xEF, - 0x1A, 0x17, 0x51, 0xAE, 0xD9, 0x59, 0xEE, 0xD7 - }, - { - 0x7C, 0x5F, 0x43, 0x2E, 0xB8, 0xB7, 0x35, 0x2A, - 0x94, 0x94, 0xDE, 0xA4, 0xD5, 0x3C, 0x21, 0x38, - 0x70, 0x31, 0xCE, 0x70, 0xE8, 0x5D, 0x94, 0x08, - 0xFC, 0x6F, 0x8C, 0xD9, 0x8A, 0x6A, 0xAA, 0x1E - }, - { - 0xB8, 0xBF, 0x8E, 0x2C, 0x34, 0xE0, 0x33, 0x98, - 0x36, 0x39, 0x90, 0x9E, 0xAA, 0x37, 0x64, 0x0D, - 0x87, 0x7B, 0x04, 0x8F, 0xE2, 0x99, 0xB4, 0x70, - 0xAF, 0x2D, 0x0B, 0xA8, 0x2A, 0x5F, 0x14, 0xC0 - }, - { - 0x88, 0xA9, 0xDD, 0x13, 0xD5, 0xDA, 0xDB, 0xDE, - 0xE6, 0xBF, 0xF7, 0xEE, 0x1E, 0xF8, 0xC7, 0x1C, - 0xC1, 0x93, 0xAA, 0x4B, 0xF3, 0xE8, 0x4F, 0x8F, - 0xE8, 0x0C, 0xB0, 0x75, 0x68, 0x3C, 0x07, 0x79 - }, - { - 0x9A, 0xED, 0xB8, 0x87, 0x6D, 0xD2, 0x1C, 0x8C, - 0x84, 0xD2, 0xE7, 0x02, 0xA1, 0x36, 0x25, 0x98, - 0x04, 0x62, 0xF6, 0x8B, 0xF0, 0xA1, 0xB7, 0x25, - 0x4A, 0xD8, 0x06, 0xC3, 0x84, 0x03, 0xC9, 0xDE - }, - { - 0xD0, 0x97, 0x57, 0x3D, 0xF2, 0xD6, 0xB2, 0x48, - 0x9A, 0x47, 0x94, 0x84, 0x86, 0x98, 0x00, 0xA1, - 0xF8, 0x33, 0xEA, 0x16, 0x9E, 0xFF, 0x32, 0xAE, - 0x3C, 0xE6, 0x3A, 0x20, 0x79, 0x54, 0x8D, 0x78 - }, - { - 0xD1, 0x8F, 0x27, 0xA3, 0xE5, 0x55, 0xD7, 0xF9, - 0x1A, 0x00, 0x7C, 0x67, 0xAC, 0xEE, 0xDE, 0x39, - 0x1F, 0x75, 0xA6, 0x1F, 0xA4, 0x2A, 0x0B, 0x45, - 0x66, 0xEB, 0x58, 0x2C, 0xA0, 0x5E, 0xBC, 0xE7 - }, - { - 0xDF, 0x1D, 0xAA, 0x90, 0xB1, 0x70, 0x23, 0x13, - 0xE6, 0xA5, 0x90, 0x1C, 0x7A, 0xFC, 0x5E, 0xD9, - 0x65, 0x77, 0x17, 0xA7, 0x15, 0xFA, 0x53, 0xA4, - 0x18, 0x9E, 0xC1, 0xE5, 0xDF, 0x29, 0x3A, 0x68 - }, - { - 0x04, 0xE3, 0xA4, 0x96, 0xB6, 0x69, 0x96, 0xC6, - 0x6E, 0x32, 0x91, 0x9E, 0xD1, 0xF9, 0x4C, 0x36, - 0xEE, 0xBB, 0xF2, 0x40, 0x63, 0x3A, 0x2F, 0x73, - 0x98, 0x45, 0xF0, 0x29, 0x5D, 0x34, 0xAF, 0xBA - }, - { - 0x8C, 0x45, 0xD8, 0x8C, 0x4E, 0x9C, 0x9D, 0x0C, - 0x8C, 0x67, 0x7F, 0xE4, 0x8F, 0xA5, 0x44, 0x9B, - 0xA3, 0x01, 0x78, 0xD4, 0x0A, 0xF0, 0xF0, 0x21, - 0x79, 0x21, 0xC6, 0x2E, 0x4B, 0x60, 0xCD, 0xD3 - }, - { - 0xE1, 0x49, 0xA6, 0xB1, 0x3B, 0xDE, 0xDE, 0xA2, - 0xEE, 0xEE, 0x00, 0x9C, 0xE9, 0x44, 0x5E, 0x8D, - 0xCF, 0x76, 0xB7, 0x6E, 0x55, 0xA5, 0x01, 0xD8, - 0xF5, 0xB4, 0x3F, 0xF8, 0x96, 0x79, 0x6A, 0xD1 - }, - { - 0xA8, 0x37, 0xC4, 0xC7, 0xC6, 0xF5, 0xCF, 0xB9, - 0x9E, 0x10, 0x85, 0xFD, 0x43, 0x28, 0x7A, 0x41, - 0x05, 0xCB, 0x28, 0xB7, 0x6F, 0xC3, 0x8B, 0x60, - 0x55, 0xC5, 0xDC, 0xFF, 0x78, 0xB8, 0x25, 0x65 - }, - { - 0x42, 0x41, 0x1F, 0x28, 0x78, 0x0B, 0x4F, 0x16, - 0x38, 0x54, 0x0B, 0x87, 0x05, 0x21, 0xEC, 0x45, - 0xBC, 0xEB, 0x1E, 0x0C, 0x71, 0x31, 0xF7, 0xE1, - 0xC4, 0x67, 0x2E, 0x43, 0x6C, 0x88, 0xC8, 0xE9 - }, - { - 0x34, 0xB4, 0xE8, 0x76, 0x76, 0x94, 0x71, 0xDF, - 0x55, 0x2E, 0x55, 0x22, 0xCE, 0xA7, 0x84, 0xFA, - 0x53, 0xAC, 0x61, 0xBE, 0xDE, 0x8C, 0xFE, 0x29, - 0x14, 0x09, 0xE6, 0x8B, 0x69, 0xE8, 0x77, 0x6F - }, - { - 0x8F, 0x31, 0xD6, 0x37, 0xA9, 0x1D, 0xBD, 0x0E, - 0xCB, 0x0B, 0xA0, 0xE6, 0x94, 0xBE, 0xC1, 0x44, - 0x76, 0x58, 0xCE, 0x6C, 0x27, 0xEA, 0x9B, 0x95, - 0xFF, 0x36, 0x70, 0x1C, 0xAF, 0x36, 0xF0, 0x01 - }, - { - 0xB5, 0xC8, 0x95, 0xEB, 0x07, 0x1E, 0x3D, 0x38, - 0x52, 0x8D, 0x47, 0x5D, 0x3B, 0xB0, 0xBA, 0x88, - 0xB7, 0x17, 0x95, 0xE4, 0x0A, 0x98, 0x2E, 0x2A, - 0xC2, 0xD8, 0x44, 0x22, 0xA0, 0xF2, 0x68, 0x5D - }, - { - 0xE9, 0x06, 0x25, 0x7C, 0x41, 0x9D, 0x94, 0x1E, - 0xD2, 0xB8, 0xA9, 0xC1, 0x27, 0x81, 0xDB, 0x97, - 0x59, 0xA3, 0xFC, 0xF3, 0xDC, 0x7C, 0xDB, 0x03, - 0x15, 0x99, 0xE1, 0x08, 0x6B, 0x67, 0x2F, 0x10 - }, - { - 0x98, 0xAD, 0x24, 0x39, 0x7C, 0x6E, 0xAE, 0x4C, - 0xF7, 0x3E, 0xA8, 0xBB, 0xEF, 0x5A, 0x0B, 0x74, - 0xD2, 0x1A, 0xD1, 0x5F, 0x33, 0x92, 0x0F, 0x44, - 0x07, 0x0A, 0x98, 0xBD, 0xF5, 0x3D, 0x0B, 0x3A - }, - { - 0xDD, 0x51, 0x0C, 0xA5, 0x5B, 0x11, 0x70, 0xF9, - 0xCE, 0xFD, 0xBB, 0x16, 0xFC, 0x14, 0x52, 0x62, - 0xAA, 0x36, 0x3A, 0x87, 0x0A, 0x01, 0xE1, 0xBC, - 0x4F, 0xBE, 0x40, 0x23, 0x4B, 0x4B, 0x6F, 0x2F - }, - { - 0xF2, 0xD8, 0xD9, 0x31, 0xB9, 0x2E, 0x1C, 0xB6, - 0x98, 0xE5, 0x6E, 0xD0, 0x28, 0x19, 0xEA, 0x11, - 0xD2, 0x66, 0x19, 0xB8, 0x3A, 0x62, 0x09, 0xAD, - 0x67, 0x22, 0x53, 0x68, 0xFE, 0x11, 0x95, 0x71 - }, - { - 0xE4, 0x63, 0x70, 0x55, 0xDB, 0x91, 0xF9, 0x43, - 0x7C, 0xF4, 0x60, 0xEF, 0x40, 0xB5, 0x14, 0x5F, - 0x69, 0x98, 0x26, 0x6A, 0x5E, 0x74, 0xE9, 0x6A, - 0x00, 0x78, 0x2C, 0x62, 0xCF, 0x30, 0xCF, 0x1C - }, - { - 0x35, 0x63, 0x53, 0x0A, 0x89, 0xD3, 0x2B, 0x75, - 0xF7, 0x8D, 0x83, 0xE9, 0x87, 0x2A, 0xD4, 0xC5, - 0x75, 0xF5, 0x20, 0x39, 0x9D, 0x65, 0x03, 0x5D, - 0xED, 0x99, 0xE5, 0xEE, 0xC5, 0x80, 0x71, 0x50 - }, - { - 0x8E, 0x79, 0xF9, 0x2C, 0x86, 0x5B, 0xEB, 0x3E, - 0x1C, 0xDB, 0xF0, 0x8F, 0x75, 0x4A, 0x26, 0x06, - 0xE8, 0x53, 0x49, 0x05, 0x3D, 0x66, 0xD6, 0x16, - 0x02, 0x4A, 0x81, 0x3F, 0xCA, 0x54, 0x1A, 0x4D - }, - { - 0x86, 0x42, 0x26, 0xF2, 0x83, 0x9C, 0x76, 0xB1, - 0xD5, 0xF7, 0xC1, 0x3D, 0x98, 0xC2, 0xA5, 0x15, - 0x8C, 0x2A, 0xBB, 0x71, 0xD9, 0xD8, 0xF0, 0xFA, - 0x1F, 0x7C, 0x3F, 0x74, 0x68, 0x00, 0x16, 0x03 - }, - { - 0xD3, 0xE3, 0xF5, 0xB8, 0xCE, 0xEB, 0xB1, 0x11, - 0x84, 0x80, 0x35, 0x35, 0x90, 0x0B, 0x6E, 0xED, - 0xDA, 0x60, 0x6E, 0xEB, 0x36, 0x97, 0x51, 0xA7, - 0xCD, 0xA3, 0x6C, 0xA3, 0x02, 0x29, 0xFB, 0x02 - }, - { - 0x8C, 0x7D, 0x6B, 0x98, 0x72, 0x69, 0x16, 0x90, - 0x31, 0xF7, 0x1F, 0xD7, 0xE4, 0xC4, 0x45, 0x01, - 0x2D, 0x3E, 0x6A, 0x3C, 0x88, 0x09, 0xF6, 0x47, - 0x9B, 0xD6, 0x67, 0xCF, 0x31, 0x1E, 0x27, 0x6E - }, - { - 0xB9, 0x04, 0xB5, 0x71, 0x1B, 0xF1, 0x9E, 0x85, - 0x32, 0xF7, 0xAD, 0x64, 0x27, 0x41, 0x0A, 0x62, - 0xA1, 0xF7, 0x7F, 0x77, 0xB9, 0xB6, 0xD7, 0x1D, - 0x2F, 0xC4, 0x3B, 0xC9, 0x0F, 0x73, 0x23, 0x5A - }, - { - 0x45, 0x36, 0x63, 0x43, 0x15, 0xC8, 0x67, 0x28, - 0xF5, 0xAB, 0x74, 0x49, 0xEB, 0x2D, 0x04, 0x02, - 0x0E, 0x9E, 0xAE, 0x8D, 0xD6, 0x79, 0x55, 0x00, - 0xE9, 0xEC, 0x9A, 0x00, 0x66, 0x38, 0x6E, 0x69 - }, - { - 0xFD, 0x5E, 0x49, 0xFE, 0xD4, 0x9D, 0xC4, 0x4B, - 0xDE, 0x89, 0xF4, 0x60, 0xA9, 0x50, 0x19, 0x1E, - 0xBB, 0x06, 0x7C, 0x69, 0x8A, 0x3F, 0x21, 0xEA, - 0x14, 0x30, 0x8C, 0x74, 0x13, 0xB9, 0x16, 0x81 - }, - { - 0x31, 0xF0, 0x1D, 0x03, 0x0B, 0x9B, 0x22, 0xD0, - 0x0A, 0x0F, 0x71, 0xED, 0x2C, 0xEB, 0x5D, 0x2D, - 0xC8, 0x1A, 0xF2, 0xC2, 0x4B, 0xF5, 0x67, 0x0F, - 0xDE, 0x19, 0xA6, 0x85, 0xE8, 0xD1, 0x39, 0x2E - }, - { - 0x5F, 0x84, 0xD9, 0xDE, 0x28, 0x4B, 0x1E, 0x4F, - 0x67, 0x8E, 0x31, 0xAB, 0x6A, 0x76, 0xF5, 0x66, - 0x1B, 0x5A, 0xEA, 0xA7, 0x68, 0x53, 0x93, 0x84, - 0xAA, 0x38, 0xF9, 0xE4, 0x9C, 0xCE, 0x6E, 0x6E - }, - { - 0xB2, 0x07, 0x9E, 0x59, 0x97, 0xA4, 0xEA, 0xD3, - 0xA7, 0x1F, 0xEF, 0xC0, 0x2F, 0x90, 0xA7, 0x48, - 0x3A, 0x10, 0xFD, 0x2E, 0x6F, 0x31, 0xBD, 0xA9, - 0xD2, 0x08, 0x44, 0x85, 0xCC, 0x01, 0x6B, 0xBD - }, - { - 0xE0, 0xF8, 0x4D, 0x7F, 0x52, 0x5B, 0x6F, 0xED, - 0x79, 0x1F, 0x77, 0x28, 0x9A, 0xE5, 0x8F, 0x7D, - 0x50, 0xA2, 0x94, 0x32, 0xD4, 0x2C, 0x25, 0xC1, - 0xE8, 0x39, 0x29, 0xB8, 0x38, 0x89, 0x1D, 0x79 - }, - { - 0x70, 0x46, 0x96, 0x90, 0x95, 0x6D, 0x79, 0x18, - 0xAC, 0xE7, 0xBA, 0x5F, 0x41, 0x30, 0x2D, 0xA1, - 0x38, 0xC9, 0xB5, 0x6E, 0xCD, 0x41, 0x55, 0x44, - 0xFA, 0xCE, 0x8D, 0x99, 0x8C, 0x21, 0xAB, 0xEB - }, - { - 0x45, 0xC9, 0x1A, 0x62, 0x24, 0x9B, 0x39, 0xCD, - 0xA9, 0x4E, 0x50, 0x82, 0x95, 0xBE, 0xC7, 0x66, - 0x71, 0x19, 0x44, 0x77, 0x65, 0xEF, 0x80, 0xEF, - 0xA8, 0x2D, 0x1E, 0x92, 0xD5, 0x70, 0x67, 0xD8 - }, - { - 0x1D, 0x9E, 0x00, 0x73, 0xEE, 0xD0, 0x73, 0x15, - 0x54, 0xC3, 0xBE, 0xAA, 0x47, 0x46, 0x0D, 0x51, - 0x1A, 0xD2, 0x61, 0xDD, 0x4D, 0x4A, 0x3B, 0xED, - 0x9D, 0x8D, 0x20, 0x2F, 0x22, 0xF2, 0x15, 0x89 - }, - { - 0x40, 0x82, 0x62, 0x73, 0x6D, 0x8A, 0xEC, 0x0B, - 0x84, 0x7D, 0xBA, 0x25, 0x02, 0x58, 0x60, 0x8A, - 0x43, 0x45, 0xA6, 0x3A, 0x1E, 0xB1, 0x95, 0xE5, - 0xC7, 0xAE, 0x2E, 0xE8, 0x74, 0xC3, 0x4D, 0xA8 - }, - { - 0x23, 0xD2, 0xB7, 0x04, 0x39, 0x46, 0x99, 0x49, - 0x98, 0x23, 0x90, 0x53, 0x8D, 0x7E, 0x5A, 0xDE, - 0x9F, 0x18, 0xC8, 0xE3, 0xBB, 0xF6, 0x60, 0x5A, - 0xFC, 0xF4, 0x9B, 0x00, 0xC0, 0x61, 0xE8, 0x37 - }, - { - 0x23, 0x2F, 0xB1, 0x87, 0xD2, 0x71, 0xBE, 0xA9, - 0x12, 0xEF, 0xD4, 0x07, 0xFF, 0xE0, 0x80, 0x56, - 0xD6, 0xA4, 0x2E, 0x53, 0x21, 0xEC, 0x79, 0x2D, - 0xF3, 0xD5, 0x84, 0xA9, 0x4F, 0x63, 0x0A, 0xB2 - }, - { - 0x13, 0x8E, 0x19, 0x44, 0xE4, 0xB5, 0x4D, 0xE8, - 0x68, 0x1D, 0x7E, 0x48, 0xC4, 0xF0, 0x81, 0x48, - 0xE4, 0x0A, 0x56, 0x7E, 0x5C, 0xAD, 0x94, 0x6A, - 0x6A, 0xF4, 0xE8, 0xD5, 0xD2, 0x6F, 0x75, 0xC7 - }, - { - 0x80, 0xC1, 0x51, 0x32, 0x5F, 0xBF, 0xC6, 0x78, - 0xB7, 0xBE, 0x4E, 0x40, 0xB3, 0x0F, 0x29, 0xFE, - 0x31, 0xCD, 0xBE, 0x1C, 0x84, 0x12, 0x6E, 0x00, - 0x6D, 0xF3, 0xC1, 0x85, 0x24, 0xBD, 0x2D, 0x6C - }, - { - 0xA6, 0x42, 0x26, 0x73, 0x01, 0x66, 0x9D, 0xF2, - 0x61, 0xB8, 0x39, 0xF8, 0x73, 0x65, 0x76, 0x29, - 0x05, 0xFF, 0x32, 0x0A, 0x0A, 0x2F, 0xC4, 0xBD, - 0xC4, 0x8E, 0x5A, 0x8E, 0x15, 0xD1, 0x32, 0x33 - }, - { - 0x0F, 0x8B, 0x10, 0x99, 0x38, 0x60, 0x93, 0x7A, - 0x74, 0xCC, 0x2D, 0xE4, 0x0A, 0x27, 0x31, 0xDD, - 0x99, 0x54, 0xB6, 0x54, 0xBB, 0x94, 0xC3, 0x4E, - 0x87, 0x66, 0x52, 0xE9, 0x8D, 0x4B, 0xBD, 0x16 - }, - { - 0xE6, 0x34, 0xA5, 0x85, 0x12, 0x49, 0x32, 0x73, - 0x26, 0x0F, 0x10, 0xD4, 0x49, 0x53, 0xCD, 0x99, - 0x8E, 0x34, 0xCB, 0x82, 0x81, 0xC4, 0x1B, 0xF4, - 0x2E, 0x0A, 0xE2, 0xF2, 0x5C, 0xBD, 0x1F, 0x75 - }, - { - 0xBD, 0xE6, 0xAF, 0x9B, 0xAF, 0x3C, 0x07, 0xE9, - 0x54, 0x23, 0xCA, 0xB5, 0x04, 0xDE, 0xE7, 0x0E, - 0xDC, 0xC3, 0x31, 0x8B, 0x22, 0xDD, 0x1E, 0xB6, - 0xFD, 0x85, 0xBE, 0x44, 0x7A, 0xC9, 0xF2, 0x09 - }, - { - 0x91, 0x4B, 0x37, 0xAB, 0x5B, 0x8C, 0xFD, 0xE6, - 0xA4, 0x80, 0x46, 0x6A, 0x0D, 0x82, 0x43, 0x2C, - 0x7D, 0x76, 0x32, 0x8E, 0x9A, 0x88, 0xEF, 0x5B, - 0x4F, 0x52, 0x42, 0x9F, 0x7A, 0x3F, 0xFC, 0x7D - }, - { - 0x55, 0xBE, 0x66, 0xE9, 0xA5, 0xAA, 0x67, 0x1A, - 0x23, 0x88, 0x2E, 0xF3, 0xE7, 0xD9, 0xD3, 0x6E, - 0xA9, 0x54, 0x87, 0xDC, 0x71, 0xB7, 0x25, 0xA5, - 0xAD, 0x4B, 0x79, 0x8A, 0x87, 0x91, 0x43, 0xD0 - }, - { - 0x3F, 0xD0, 0x45, 0x89, 0x4B, 0x83, 0x6E, 0x44, - 0xE9, 0xCA, 0x75, 0xFB, 0xE3, 0xEA, 0xDC, 0x48, - 0x6C, 0xBB, 0xD0, 0xD8, 0xCE, 0xE1, 0xB3, 0xCF, - 0x14, 0xF7, 0x6E, 0x7F, 0x1E, 0x77, 0xAE, 0xF3 - }, - { - 0xCE, 0x60, 0x34, 0x3D, 0xC4, 0x87, 0x4B, 0x66, - 0x04, 0xE1, 0xFB, 0x23, 0x1E, 0x37, 0xEC, 0x1E, - 0xEC, 0x3F, 0x06, 0x56, 0x6E, 0x42, 0x8A, 0xE7, - 0x64, 0xEF, 0xFF, 0xA2, 0x30, 0xAD, 0xD4, 0x85 - }, - { - 0xE3, 0x8C, 0x9D, 0xF0, 0x24, 0xDE, 0x21, 0x53, - 0xD2, 0x26, 0x73, 0x8A, 0x0E, 0x5B, 0xA9, 0xB8, - 0xC6, 0x78, 0x4D, 0xAC, 0xA6, 0x5C, 0x22, 0xA7, - 0x62, 0x8E, 0xB5, 0x8E, 0xA0, 0xD4, 0x95, 0xA7 - }, - { - 0x8D, 0xFE, 0xC0, 0xD4, 0xF3, 0x65, 0x8A, 0x20, - 0xA0, 0xBA, 0xD6, 0x6F, 0x21, 0x60, 0x83, 0x2B, - 0x16, 0x4E, 0x70, 0x0A, 0x21, 0xEC, 0x5A, 0x01, - 0x65, 0xC3, 0x67, 0x72, 0xB2, 0x08, 0x61, 0x11 - }, - { - 0x44, 0x01, 0xB5, 0x0E, 0x09, 0x86, 0x5F, 0x42, - 0x38, 0x24, 0x3B, 0x82, 0x25, 0xCA, 0x40, 0xA0, - 0x8D, 0xBB, 0x46, 0x85, 0xF5, 0xF8, 0x62, 0xFB, - 0xDD, 0x72, 0x98, 0x04, 0x31, 0xA8, 0x5D, 0x3F - }, - { - 0x86, 0x68, 0x94, 0x27, 0x88, 0xC4, 0xCE, 0x8A, - 0x33, 0x19, 0x0F, 0xFC, 0xFA, 0xD1, 0xC6, 0x78, - 0xC4, 0xFA, 0x41, 0xE9, 0x94, 0x17, 0x09, 0x4E, - 0x24, 0x0F, 0x4A, 0x43, 0xF3, 0x87, 0xA3, 0xB6 - }, - { - 0xA7, 0x28, 0x8D, 0x5E, 0x09, 0x80, 0x9B, 0x69, - 0x69, 0x84, 0xEC, 0xD5, 0x32, 0x6C, 0xDD, 0x84, - 0xFB, 0xE3, 0x5F, 0xCF, 0x67, 0x23, 0x5D, 0x81, - 0x1C, 0x82, 0x00, 0x25, 0x36, 0xA3, 0xC5, 0xE1 - }, - { - 0x8E, 0x92, 0x5C, 0x3C, 0x14, 0x6B, 0xAC, 0xF3, - 0x35, 0x1E, 0xC5, 0x32, 0x41, 0xAC, 0xE5, 0xF7, - 0x3E, 0x8F, 0xC9, 0xBD, 0x8C, 0x61, 0xCA, 0xD9, - 0x7F, 0xD7, 0x72, 0xB0, 0x7E, 0x1B, 0x83, 0x73 - }, - { - 0xC7, 0xEB, 0x9E, 0x6D, 0xED, 0x2F, 0x99, 0x3D, - 0x48, 0xB0, 0x17, 0x0D, 0xA2, 0x7C, 0x5B, 0x75, - 0x3B, 0x12, 0x17, 0x6B, 0xE1, 0x26, 0xC7, 0xBA, - 0x2D, 0x6A, 0xF8, 0x5F, 0x85, 0x93, 0xB7, 0x52 - }, - { - 0xCA, 0x27, 0xF1, 0x6F, 0x94, 0xE4, 0xEC, 0x0E, - 0x62, 0x8E, 0x7F, 0x8A, 0xEF, 0xC6, 0x65, 0x7B, - 0xED, 0xC9, 0x37, 0x42, 0x96, 0x59, 0x40, 0xAE, - 0x78, 0x6A, 0x73, 0xB5, 0xFD, 0x59, 0x3B, 0x97 - }, - { - 0x8C, 0x21, 0xE6, 0x56, 0x8B, 0xC6, 0xDC, 0x00, - 0xE3, 0xD6, 0xEB, 0xC0, 0x9E, 0xA9, 0xC2, 0xCE, - 0x00, 0x6C, 0xD3, 0x11, 0xD3, 0xB3, 0xE9, 0xCC, - 0x9D, 0x8D, 0xDB, 0xFB, 0x3C, 0x5A, 0x77, 0x76 - }, - { - 0x52, 0x56, 0x66, 0x96, 0x8B, 0x3B, 0x7D, 0x00, - 0x7B, 0xB9, 0x26, 0xB6, 0xEF, 0xDC, 0x7E, 0x21, - 0x2A, 0x31, 0x15, 0x4C, 0x9A, 0xE1, 0x8D, 0x43, - 0xEE, 0x0E, 0xB7, 0xE6, 0xB1, 0xA9, 0x38, 0xD3 - }, - { - 0xE0, 0x9A, 0x4F, 0xA5, 0xC2, 0x8B, 0xDC, 0xD7, - 0xC8, 0x39, 0x84, 0x0E, 0x0A, 0x38, 0x3E, 0x4F, - 0x7A, 0x10, 0x2D, 0x0B, 0x1B, 0xC8, 0x49, 0xC9, - 0x49, 0x62, 0x7C, 0x41, 0x00, 0xC1, 0x7D, 0xD3 - }, - { - 0xC1, 0x9F, 0x3E, 0x29, 0x5D, 0xB2, 0xFC, 0x0E, - 0x74, 0x81, 0xC4, 0xF1, 0x6A, 0xF0, 0x11, 0x55, - 0xDD, 0xB0, 0xD7, 0xD1, 0x38, 0x3D, 0x4A, 0x1F, - 0xF1, 0x69, 0x9D, 0xB7, 0x11, 0x77, 0x34, 0x0C - }, - { - 0x76, 0x9E, 0x67, 0x8C, 0x0A, 0x09, 0x09, 0xA2, - 0x02, 0x1C, 0x4D, 0xC2, 0x6B, 0x1A, 0x3C, 0x9B, - 0xC5, 0x57, 0xAD, 0xB2, 0x1A, 0x50, 0x83, 0x4C, - 0xDC, 0x5C, 0x92, 0x93, 0xF7, 0x53, 0x65, 0xF8 - }, - { - 0xB6, 0x48, 0x74, 0xAD, 0xAB, 0x6B, 0xCB, 0x85, - 0xB9, 0x4B, 0xD9, 0xA6, 0xC5, 0x65, 0xD0, 0xD2, - 0xBC, 0x35, 0x44, 0x5D, 0x75, 0x28, 0xBC, 0x85, - 0xB4, 0x1F, 0xDC, 0x79, 0xDC, 0x76, 0xE3, 0x4F - }, - { - 0xFA, 0xF2, 0x50, 0xDE, 0x15, 0x82, 0x0F, 0x7F, - 0xC6, 0x10, 0xDD, 0x53, 0xEE, 0xAE, 0x44, 0x60, - 0x1C, 0x3E, 0xFF, 0xA3, 0xAC, 0xCD, 0x08, 0x8E, - 0xB6, 0x69, 0x05, 0xBB, 0x26, 0x53, 0xBE, 0x8C - }, - { - 0x1E, 0x20, 0x38, 0x73, 0x9B, 0x2C, 0x01, 0x8B, - 0x0E, 0x9E, 0x0E, 0x1E, 0x52, 0x2F, 0xD9, 0x65, - 0x12, 0x87, 0xEE, 0x6E, 0x36, 0x65, 0x91, 0x9B, - 0x24, 0xC2, 0x12, 0x4F, 0x0C, 0x1A, 0x3F, 0x3A - }, - { - 0x5F, 0xEC, 0x3A, 0xA0, 0x08, 0x61, 0xDE, 0x1A, - 0xC5, 0xDA, 0xB3, 0xC1, 0x37, 0x06, 0x5D, 0x1E, - 0x01, 0xBB, 0x03, 0xF6, 0x9D, 0xCC, 0x7D, 0x1C, - 0xF7, 0xCA, 0x4F, 0x43, 0x56, 0xAE, 0xC9, 0xA3 - }, - { - 0x44, 0x51, 0xFE, 0x6B, 0xBE, 0xF3, 0x93, 0x43, - 0x91, 0x92, 0x44, 0xC5, 0x1D, 0xAE, 0x1E, 0xA9, - 0xA9, 0x54, 0xCF, 0x2C, 0x09, 0x66, 0xAB, 0x04, - 0x5B, 0x15, 0x52, 0x1E, 0xCF, 0x35, 0x00, 0x81 - }, - { - 0x8C, 0x62, 0x2F, 0xA2, 0x16, 0x0E, 0x8E, 0x99, - 0x18, 0x13, 0xF1, 0x80, 0xBF, 0xEC, 0x0B, 0x43, - 0x1C, 0x6D, 0xBF, 0xA2, 0x95, 0x6D, 0x91, 0x75, - 0x81, 0x6A, 0x23, 0xC3, 0x82, 0xC4, 0xF2, 0x00 - }, - { - 0x81, 0x7D, 0x5C, 0x8F, 0x92, 0xE7, 0xB5, 0xCA, - 0x57, 0xF5, 0xE1, 0x63, 0x90, 0x16, 0xAD, 0x57, - 0x60, 0xE4, 0x46, 0xD6, 0xE9, 0xCA, 0xA7, 0x49, - 0x84, 0x14, 0xAC, 0xE8, 0x22, 0x80, 0xB5, 0xCD - }, - { - 0xA6, 0xA1, 0xAD, 0x58, 0xCE, 0xE5, 0x4E, 0x69, - 0xCB, 0xBC, 0xAA, 0x87, 0xDF, 0x07, 0xA6, 0x70, - 0x7E, 0xB2, 0x24, 0x73, 0x9C, 0x21, 0x76, 0x13, - 0x46, 0x0A, 0xB4, 0x54, 0xB4, 0x59, 0xCA, 0x9C - }, - { - 0x63, 0xB8, 0x47, 0x27, 0x52, 0x26, 0x60, 0x5B, - 0xE6, 0x76, 0x81, 0x25, 0x8F, 0x7D, 0x00, 0xBB, - 0xB3, 0x07, 0xC6, 0x6F, 0x19, 0x59, 0xBF, 0x2E, - 0x46, 0x7A, 0x41, 0xAE, 0xE7, 0x14, 0xE5, 0x5C - }, - { - 0xFE, 0x52, 0xEB, 0xE5, 0xCF, 0xCF, 0xE6, 0xA2, - 0x29, 0x7B, 0x53, 0x9F, 0xA3, 0xDA, 0xDB, 0xD6, - 0xEB, 0xD2, 0x01, 0xAA, 0x2C, 0xA1, 0x35, 0x63, - 0xE3, 0xD7, 0xF1, 0x4D, 0x15, 0xAB, 0xFF, 0x63 - }, - { - 0xB7, 0xBE, 0xF9, 0xFA, 0x5A, 0x3D, 0x10, 0x42, - 0x62, 0x46, 0xB5, 0xF6, 0x58, 0xC0, 0x8F, 0xDF, - 0x80, 0x66, 0xEA, 0xA3, 0xE5, 0x5A, 0x2F, 0x7D, - 0xA1, 0x59, 0x1E, 0x05, 0xC8, 0x7D, 0xF8, 0xC7 - }, - { - 0xDE, 0xD1, 0xD6, 0xCA, 0xA9, 0xF8, 0xF3, 0xBD, - 0xA9, 0x2C, 0xEA, 0x7F, 0x65, 0x49, 0xB1, 0xFB, - 0x86, 0xA2, 0x21, 0x14, 0x78, 0xC4, 0xEC, 0x28, - 0x9B, 0x83, 0x7E, 0xFC, 0x2B, 0x5C, 0x27, 0xD7 - }, - { - 0x9F, 0x30, 0x00, 0x8A, 0x2E, 0xB0, 0x50, 0xF1, - 0x8E, 0x56, 0xA7, 0x6B, 0xE9, 0x20, 0x91, 0xB2, - 0xFD, 0xC1, 0x64, 0xD5, 0x6E, 0x32, 0xC8, 0x7D, - 0xD6, 0x4C, 0x9E, 0x3A, 0x61, 0x10, 0x41, 0xB1 - }, - { - 0x01, 0x0B, 0x6A, 0x3B, 0x11, 0x86, 0x00, 0x88, - 0xF0, 0xAB, 0xC8, 0x0A, 0x89, 0x72, 0xCB, 0xBC, - 0x32, 0x9D, 0x52, 0x75, 0x34, 0x29, 0x50, 0xEB, - 0x9A, 0x04, 0x5A, 0xFD, 0xC8, 0xBB, 0xED, 0x24 - }, - { - 0x0C, 0xD2, 0x10, 0xAA, 0xC1, 0x1F, 0x1C, 0x1C, - 0xED, 0x49, 0x7F, 0x67, 0x3E, 0x53, 0xDB, 0x68, - 0xC3, 0xEC, 0x36, 0x07, 0xF0, 0xC5, 0x78, 0x7D, - 0xDC, 0x60, 0xA3, 0x55, 0xDF, 0xE5, 0x6C, 0x25 - }, - { - 0x0E, 0x56, 0xFD, 0x01, 0xDA, 0x3B, 0x4F, 0x8B, - 0xE2, 0xC9, 0x90, 0x55, 0x2A, 0xAC, 0x8D, 0x1E, - 0x8D, 0xA2, 0x09, 0xBC, 0xF4, 0xAA, 0xD4, 0xFF, - 0xB5, 0x42, 0x7F, 0xD6, 0x31, 0x72, 0x46, 0x3E - }, - { - 0xD6, 0xD5, 0xCD, 0xB1, 0x14, 0x40, 0xE3, 0x4A, - 0xCA, 0x3A, 0x2F, 0xCF, 0x30, 0xF5, 0x9E, 0x08, - 0xB1, 0x1A, 0x2A, 0x3D, 0xE5, 0x39, 0xE3, 0xE6, - 0x51, 0x3E, 0xD7, 0x8A, 0x4F, 0xEE, 0x51, 0x3B - }, - { - 0xAA, 0x35, 0xAC, 0x90, 0x68, 0x06, 0x70, 0xC7, - 0x32, 0xED, 0x1E, 0xF3, 0x7E, 0x8C, 0xBA, 0xAE, - 0x49, 0xA4, 0xD8, 0x8E, 0xCF, 0x4D, 0xF2, 0xB6, - 0x89, 0xA0, 0xF1, 0x01, 0xB7, 0x56, 0xAE, 0x47 - }, - { - 0x27, 0x8E, 0x56, 0x12, 0x88, 0x72, 0x26, 0x30, - 0xE2, 0x6A, 0x5F, 0xC9, 0x54, 0xBF, 0x2D, 0xCD, - 0x6A, 0x65, 0x81, 0x67, 0x39, 0xAB, 0xEE, 0x7B, - 0xE1, 0x43, 0x07, 0xA9, 0x61, 0x74, 0xE5, 0xB0 - }, - { - 0xAB, 0x4B, 0x2C, 0xA1, 0xA2, 0xB3, 0x49, 0x98, - 0x15, 0x24, 0xB6, 0x15, 0x54, 0x62, 0xF0, 0xFF, - 0x10, 0x60, 0xBF, 0x9B, 0xFA, 0x07, 0xFB, 0x9E, - 0xC6, 0x9C, 0xA4, 0x71, 0x64, 0x5B, 0x6A, 0x18 - }, - { - 0x18, 0xA9, 0xBB, 0xEC, 0x3C, 0x8E, 0x1F, 0x8E, - 0xE9, 0x57, 0x12, 0x97, 0xA9, 0x34, 0x36, 0xDE, - 0x42, 0x7C, 0xD2, 0x70, 0xEC, 0x69, 0xDF, 0xE8, - 0x88, 0xDB, 0x7D, 0xBF, 0x10, 0xB6, 0x49, 0x93 - }, - { - 0xBA, 0xFC, 0x7E, 0x43, 0xD2, 0x65, 0xA1, 0x73, - 0x02, 0x1A, 0x9D, 0x9E, 0x58, 0x3D, 0x60, 0xED, - 0x42, 0xA8, 0x03, 0xFA, 0xCD, 0x6B, 0x83, 0x60, - 0xDE, 0x1F, 0x91, 0x68, 0x35, 0x38, 0x9B, 0xF0 - }, - { - 0xA5, 0xB6, 0x7B, 0xE9, 0x50, 0xFB, 0xC2, 0xF0, - 0xDD, 0x32, 0x3A, 0x79, 0xA1, 0x9E, 0x3E, 0xD1, - 0xF4, 0xAE, 0x4B, 0xA7, 0x89, 0x4F, 0x93, 0x0E, - 0xA5, 0xEF, 0x73, 0x4D, 0xE7, 0xDB, 0x83, 0xAE - }, - { - 0xBF, 0x1E, 0x65, 0xF3, 0xCD, 0x84, 0x98, 0x88, - 0x4D, 0x9D, 0x5C, 0x19, 0xEB, 0xF7, 0xB9, 0x16, - 0x06, 0x76, 0x37, 0x60, 0x4E, 0x26, 0xDB, 0xE2, - 0xB7, 0x28, 0x8E, 0xCB, 0x11, 0x42, 0x60, 0x68 - }, - { - 0xC3, 0x34, 0x2C, 0xF9, 0xCB, 0xBF, 0x29, 0xD4, - 0x06, 0xD7, 0x89, 0x5D, 0xD4, 0xD9, 0x54, 0x8D, - 0x4A, 0xC7, 0x8B, 0x4D, 0x00, 0xE9, 0xB6, 0x3E, - 0x20, 0x3E, 0x5E, 0x19, 0xE9, 0x97, 0x46, 0x20 - }, - { - 0x1C, 0x0B, 0xE6, 0x02, 0x77, 0x43, 0x4B, 0x0E, - 0x00, 0x4B, 0x7B, 0x38, 0x8A, 0x37, 0x55, 0x9F, - 0x84, 0xB3, 0x0C, 0x6C, 0xF8, 0x60, 0x0F, 0x52, - 0x8B, 0xFC, 0xD3, 0x3C, 0xAF, 0x52, 0xCB, 0x1E - }, - { - 0x73, 0x95, 0x45, 0x30, 0xD0, 0x3F, 0x10, 0xBE, - 0xF5, 0x2A, 0xD5, 0xBC, 0x7F, 0xB4, 0xC0, 0x76, - 0xF8, 0x3F, 0x63, 0x31, 0xC8, 0xBD, 0x1E, 0xEE, - 0xC3, 0x88, 0x7F, 0x4A, 0xA2, 0x06, 0x92, 0x40 - }, - { - 0x69, 0xC1, 0x1E, 0xE0, 0x49, 0x44, 0xDE, 0xA9, - 0x85, 0xAC, 0x9F, 0x13, 0x96, 0x0E, 0x73, 0x98, - 0x0E, 0x1B, 0xB0, 0xE3, 0x09, 0xF4, 0x38, 0x4A, - 0x16, 0x76, 0xF8, 0xEF, 0xAB, 0x38, 0x42, 0x88 - }, - { - 0x36, 0xFB, 0x8F, 0xDE, 0x0E, 0xC2, 0x8C, 0xE8, - 0x53, 0xFB, 0x71, 0x75, 0xC1, 0xB7, 0x9D, 0xA3, - 0xB5, 0xE8, 0xC3, 0x91, 0x86, 0xE7, 0x8A, 0xAE, - 0xCE, 0x54, 0x64, 0xDB, 0xD9, 0xFE, 0x2A, 0xA2 - }, - { - 0x6B, 0xB2, 0xA0, 0x9D, 0xFC, 0xAF, 0x96, 0x96, - 0x2D, 0xE0, 0x0C, 0x8A, 0x08, 0x2D, 0x6D, 0xF9, - 0x32, 0x2B, 0x49, 0x66, 0xAE, 0x8D, 0x2E, 0xCF, - 0x73, 0x24, 0x11, 0xA7, 0x6A, 0x1A, 0x0E, 0xE6 - }, - { - 0x74, 0x12, 0xE7, 0xDD, 0x1B, 0xF1, 0xAA, 0x93, - 0x97, 0x41, 0x1B, 0xBA, 0x4D, 0x3E, 0x02, 0x76, - 0xD2, 0xE7, 0xA1, 0xA2, 0x9A, 0x24, 0x77, 0x15, - 0x7A, 0xD6, 0x03, 0x60, 0xD3, 0x3D, 0x4E, 0x76 - }, - { - 0xDD, 0xDE, 0xAF, 0xCF, 0xC7, 0x23, 0x21, 0xC8, - 0x49, 0xFB, 0x25, 0x94, 0x7A, 0xB4, 0x2C, 0x1A, - 0xF2, 0xA5, 0xE4, 0x3F, 0xEF, 0x68, 0x1B, 0xE4, - 0x2C, 0x7E, 0xAF, 0x36, 0x60, 0x08, 0x0A, 0xD3 - }, - { - 0x9D, 0xEF, 0xEB, 0xAD, 0xBD, 0xCB, 0x0A, 0x0E, - 0x7F, 0xF9, 0x92, 0xF9, 0x47, 0xCE, 0xD3, 0xD0, - 0xA4, 0xC8, 0x99, 0xE6, 0x4F, 0xE7, 0x73, 0x60, - 0xE8, 0x1E, 0x1F, 0x0E, 0x97, 0xF8, 0xC1, 0xA2 - }, - { - 0x84, 0x4C, 0x59, 0xFB, 0xE6, 0x47, 0x6F, 0xD1, - 0x89, 0x23, 0x99, 0x54, 0xF1, 0x7E, 0x36, 0xE1, - 0xF6, 0x9E, 0x24, 0xAA, 0xED, 0x5D, 0x5C, 0x8B, - 0x84, 0x05, 0xEF, 0x2A, 0x83, 0x0C, 0xC2, 0xA0 - }, - { - 0xFF, 0x3F, 0xAF, 0xB6, 0x77, 0x86, 0xE0, 0x1A, - 0x0C, 0x38, 0xEA, 0xDF, 0x99, 0xC4, 0xCA, 0xE8, - 0x02, 0x9D, 0xA8, 0xCF, 0x29, 0x87, 0x5F, 0xC4, - 0x19, 0xBF, 0x68, 0x00, 0x09, 0xB3, 0xBD, 0xB3 - }, - { - 0xCA, 0x67, 0x60, 0xF3, 0x45, 0x67, 0x8F, 0x30, - 0xA2, 0x8D, 0x62, 0x82, 0x94, 0x27, 0x2A, 0x19, - 0xE3, 0x07, 0x2E, 0xBC, 0x61, 0xB1, 0x9F, 0xF1, - 0x3B, 0x31, 0x89, 0x73, 0xE9, 0x7C, 0x27, 0x38 - }, - { - 0xC0, 0x8E, 0x1A, 0x90, 0x47, 0xC5, 0x05, 0x26, - 0x4A, 0x16, 0x44, 0x7C, 0x9E, 0xD9, 0x81, 0xA7, - 0x19, 0xD3, 0x81, 0xF2, 0x8E, 0x60, 0x5F, 0xD7, - 0xCA, 0xA9, 0xE8, 0xBD, 0xBB, 0x42, 0x99, 0x6A - }, - { - 0xF1, 0x73, 0xBA, 0x9D, 0x45, 0x84, 0xCD, 0x12, - 0x60, 0x50, 0xC6, 0x9F, 0xC2, 0x19, 0xA9, 0x19, - 0x0A, 0x0B, 0xF0, 0xAE, 0xCE, 0xCB, 0xE6, 0x11, - 0xBE, 0xED, 0x19, 0x3D, 0xA6, 0xCA, 0x4D, 0xE7 - }, - { - 0xB1, 0x84, 0x87, 0x65, 0x20, 0xDE, 0xD8, 0xBD, - 0x7D, 0xE2, 0x5E, 0xAE, 0xFB, 0xD3, 0xE0, 0x36, - 0x88, 0xC3, 0xBE, 0x39, 0xC1, 0x9F, 0xB7, 0x3E, - 0x1F, 0x0E, 0xCC, 0xAC, 0x7C, 0xC0, 0xF0, 0x14 - }, - { - 0x90, 0x25, 0xDB, 0x07, 0x58, 0xBD, 0xFB, 0x48, - 0xF0, 0x66, 0x7E, 0xBD, 0x7E, 0x12, 0x02, 0x46, - 0x59, 0x8F, 0xED, 0x01, 0xC2, 0x58, 0x76, 0x4F, - 0xA0, 0xFA, 0xE3, 0x34, 0xA2, 0xA0, 0x0A, 0x97 - }, - { - 0xE8, 0x3D, 0x80, 0x86, 0xFA, 0xBC, 0x46, 0x0D, - 0x5E, 0xFC, 0x45, 0x9F, 0x95, 0xA2, 0x68, 0xF5, - 0xDC, 0x4A, 0xC2, 0x84, 0x09, 0x3C, 0x24, 0x7C, - 0xA6, 0xEC, 0x84, 0x1A, 0xD6, 0x18, 0x3F, 0xE1 - }, - { - 0xCC, 0x9D, 0xF4, 0x1D, 0x35, 0xAA, 0x75, 0x92, - 0x8C, 0x18, 0x5F, 0x73, 0x93, 0x66, 0x61, 0x10, - 0xB8, 0x0F, 0x09, 0x86, 0xA2, 0x21, 0xC3, 0x70, - 0xF4, 0x5C, 0x2E, 0xB9, 0x01, 0x6C, 0x9A, 0x3B - }, - { - 0x92, 0xF9, 0xA5, 0x94, 0x95, 0x45, 0x90, 0xFA, - 0x81, 0x98, 0x17, 0xE5, 0xD1, 0xC2, 0x8A, 0xAB, - 0x2B, 0x1C, 0xC5, 0x04, 0xD8, 0x6D, 0xBA, 0x44, - 0x36, 0x76, 0xBD, 0xF8, 0x66, 0x79, 0x68, 0x11 - }, - { - 0x72, 0x95, 0x62, 0xA1, 0xE0, 0x7B, 0x0E, 0x26, - 0x05, 0x49, 0x48, 0x09, 0xBD, 0x48, 0x0F, 0x15, - 0x37, 0xCE, 0xA1, 0x0D, 0xCA, 0xD4, 0x3E, 0xF9, - 0xF6, 0x8C, 0x66, 0xE8, 0x25, 0xDC, 0x46, 0xB1 - }, - { - 0x26, 0xF1, 0x60, 0xAB, 0x96, 0xF5, 0x58, 0x20, - 0x45, 0x14, 0x6E, 0xAF, 0xF2, 0xE2, 0xA8, 0xD4, - 0xDA, 0xB2, 0x98, 0xB4, 0xC5, 0x7E, 0x11, 0x7C, - 0xDF, 0xC5, 0xD0, 0x25, 0xC9, 0x2A, 0x22, 0x68 - }, - { - 0x87, 0xEB, 0xE7, 0x21, 0x38, 0x38, 0x73, 0xD2, - 0x47, 0xF8, 0x61, 0x82, 0xE3, 0xF5, 0x99, 0xA7, - 0x63, 0x4F, 0xCA, 0xEC, 0x5E, 0x07, 0xB1, 0xE8, - 0x3E, 0xBB, 0x79, 0x62, 0x5B, 0xA3, 0x54, 0xE6 - }, - { - 0xE0, 0x8D, 0x38, 0x9F, 0x75, 0x69, 0x4A, 0xDC, - 0x99, 0x6C, 0x22, 0xF5, 0x5D, 0x4F, 0x85, 0x9F, - 0xFD, 0x0C, 0x13, 0x19, 0xFF, 0x9C, 0xED, 0xF7, - 0x8C, 0x31, 0xBE, 0x84, 0xB6, 0xF2, 0x1A, 0xBC - }, - { - 0x13, 0x63, 0xE2, 0x29, 0x13, 0xC6, 0xE1, 0x8E, - 0x7A, 0xA6, 0x5B, 0x83, 0xE7, 0x51, 0xC8, 0xA2, - 0xC6, 0x1B, 0x0F, 0x30, 0x71, 0x55, 0x86, 0x5A, - 0x57, 0xDB, 0xA5, 0x69, 0xA9, 0x9C, 0x7B, 0x0E - }, - { - 0x88, 0x78, 0x08, 0x8E, 0xB2, 0xD1, 0xF6, 0xD0, - 0xBB, 0x48, 0x1B, 0x4B, 0xB1, 0x87, 0xDA, 0x04, - 0xBC, 0xD8, 0xC2, 0xC6, 0x39, 0xF0, 0x05, 0xB0, - 0x80, 0x54, 0xCC, 0x41, 0x75, 0x39, 0x05, 0xFB - }, - { - 0x04, 0x18, 0xD6, 0x0D, 0x05, 0xB4, 0xE1, 0x24, - 0x64, 0x6E, 0xE5, 0x0E, 0x77, 0x49, 0xA1, 0xD2, - 0x09, 0x45, 0x7B, 0xC5, 0x43, 0xE3, 0xCC, 0x11, - 0x30, 0x27, 0x4A, 0xEA, 0x0F, 0x7B, 0xF3, 0xC1 - }, - { - 0x7A, 0x39, 0x7E, 0x50, 0x3F, 0x29, 0x3B, 0xC4, - 0x2D, 0x5F, 0x7E, 0xF5, 0xEC, 0x37, 0x87, 0x24, - 0x60, 0xA4, 0xF5, 0xB5, 0xCC, 0xDE, 0x77, 0xFB, - 0x4D, 0x47, 0xAC, 0x06, 0x81, 0xE5, 0xA0, 0x49 - }, - { - 0x5C, 0x0D, 0x29, 0x83, 0xE7, 0x2A, 0x6D, 0xD4, - 0xE6, 0x52, 0xD7, 0x23, 0xC1, 0xDF, 0xC1, 0x2B, - 0x41, 0x4C, 0x87, 0x3D, 0x4A, 0xB4, 0xA0, 0xA1, - 0x50, 0x40, 0x8E, 0xB3, 0x43, 0x47, 0xE9, 0x95 - }, - { - 0x56, 0x23, 0x36, 0x54, 0x53, 0xC0, 0x49, 0x89, - 0xC7, 0xCF, 0x33, 0x63, 0x5E, 0x0F, 0xC4, 0xCD, - 0xDD, 0x68, 0x6F, 0xC9, 0x5A, 0x33, 0xDF, 0xED, - 0xCF, 0x33, 0x35, 0x79, 0x4C, 0x7D, 0xC3, 0x44 - }, - { - 0x11, 0xF6, 0xDA, 0xD1, 0x88, 0x02, 0x8F, 0xDF, - 0x13, 0x78, 0xA2, 0x56, 0xE4, 0x57, 0x0E, 0x90, - 0x63, 0x10, 0x7B, 0x8F, 0x79, 0xDC, 0x66, 0x3F, - 0xA5, 0x55, 0x6F, 0x56, 0xFD, 0x44, 0xA0, 0xF0 - }, - { - 0x0E, 0xD8, 0x16, 0x17, 0x97, 0xEC, 0xEE, 0x88, - 0x1E, 0x7D, 0x0E, 0x3F, 0x4C, 0x5F, 0xB8, 0x39, - 0xC8, 0x4E, 0xB7, 0xA9, 0x24, 0x26, 0x57, 0xCC, - 0x48, 0x30, 0x68, 0x07, 0xB3, 0x2B, 0xEF, 0xDE - }, - { - 0x73, 0x66, 0x67, 0xC9, 0x36, 0x4C, 0xE1, 0x2D, - 0xB8, 0xF6, 0xB1, 0x43, 0xC6, 0xC1, 0x78, 0xCD, - 0xEF, 0x1E, 0x14, 0x45, 0xBC, 0x5A, 0x2F, 0x26, - 0x34, 0xF0, 0x8E, 0x99, 0x32, 0x27, 0x3C, 0xAA - }, - { - 0xE1, 0x5F, 0x36, 0x8B, 0x44, 0x06, 0xC1, 0xF6, - 0x55, 0x57, 0xC8, 0x35, 0x5C, 0xBE, 0x69, 0x4B, - 0x63, 0x3E, 0x26, 0xF1, 0x55, 0xF5, 0x2B, 0x7D, - 0xA9, 0x4C, 0xFB, 0x23, 0xFD, 0x4A, 0x5D, 0x96 - }, - { - 0x43, 0x7A, 0xB2, 0xD7, 0x4F, 0x50, 0xCA, 0x86, - 0xCC, 0x3D, 0xE9, 0xBE, 0x70, 0xE4, 0x55, 0x48, - 0x25, 0xE3, 0x3D, 0x82, 0x4B, 0x3A, 0x49, 0x23, - 0x62, 0xE2, 0xE9, 0xD6, 0x11, 0xBC, 0x57, 0x9D - }, - { - 0x2B, 0x91, 0x58, 0xC7, 0x22, 0x89, 0x8E, 0x52, - 0x6D, 0x2C, 0xDD, 0x3F, 0xC0, 0x88, 0xE9, 0xFF, - 0xA7, 0x9A, 0x9B, 0x73, 0xB7, 0xD2, 0xD2, 0x4B, - 0xC4, 0x78, 0xE2, 0x1C, 0xDB, 0x3B, 0x67, 0x63 - }, - { - 0x0C, 0x8A, 0x36, 0x59, 0x7D, 0x74, 0x61, 0xC6, - 0x3A, 0x94, 0x73, 0x28, 0x21, 0xC9, 0x41, 0x85, - 0x6C, 0x66, 0x83, 0x76, 0x60, 0x6C, 0x86, 0xA5, - 0x2D, 0xE0, 0xEE, 0x41, 0x04, 0xC6, 0x15, 0xDB - }, -}; - - - - -static const uint8_t blake2bp_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = -{ - { - 0xB5, 0xEF, 0x81, 0x1A, 0x80, 0x38, 0xF7, 0x0B, - 0x62, 0x8F, 0xA8, 0xB2, 0x94, 0xDA, 0xAE, 0x74, - 0x92, 0xB1, 0xEB, 0xE3, 0x43, 0xA8, 0x0E, 0xAA, - 0xBB, 0xF1, 0xF6, 0xAE, 0x66, 0x4D, 0xD6, 0x7B, - 0x9D, 0x90, 0xB0, 0x12, 0x07, 0x91, 0xEA, 0xB8, - 0x1D, 0xC9, 0x69, 0x85, 0xF2, 0x88, 0x49, 0xF6, - 0xA3, 0x05, 0x18, 0x6A, 0x85, 0x50, 0x1B, 0x40, - 0x51, 0x14, 0xBF, 0xA6, 0x78, 0xDF, 0x93, 0x80 - }, - { - 0xA1, 0x39, 0x28, 0x0E, 0x72, 0x75, 0x7B, 0x72, - 0x3E, 0x64, 0x73, 0xD5, 0xBE, 0x59, 0xF3, 0x6E, - 0x9D, 0x50, 0xFC, 0x5C, 0xD7, 0xD4, 0x58, 0x5C, - 0xBC, 0x09, 0x80, 0x48, 0x95, 0xA3, 0x6C, 0x52, - 0x12, 0x42, 0xFB, 0x27, 0x89, 0xF8, 0x5C, 0xB9, - 0xE3, 0x54, 0x91, 0xF3, 0x1D, 0x4A, 0x69, 0x52, - 0xF9, 0xD8, 0xE0, 0x97, 0xAE, 0xF9, 0x4F, 0xA1, - 0xCA, 0x0B, 0x12, 0x52, 0x57, 0x21, 0xF0, 0x3D - }, - { - 0xEF, 0x8C, 0xDA, 0x96, 0x35, 0xD5, 0x06, 0x3A, - 0xF8, 0x11, 0x15, 0xDA, 0x3C, 0x52, 0x32, 0x5A, - 0x86, 0xE8, 0x40, 0x74, 0xF9, 0xF7, 0x24, 0xB7, - 0xCB, 0xD0, 0xB0, 0x85, 0x6F, 0xF0, 0x01, 0x77, - 0xCD, 0xD2, 0x83, 0xC2, 0x98, 0x32, 0x6C, 0xD0, - 0x91, 0x77, 0x54, 0xC5, 0x24, 0x1F, 0x14, 0x80, - 0xFB, 0x50, 0x9C, 0xF2, 0xD2, 0xC4, 0x49, 0x81, - 0x80, 0x77, 0xAE, 0x35, 0xFC, 0x33, 0x07, 0x37 - }, - { - 0x8C, 0xF9, 0x33, 0xA2, 0xD3, 0x61, 0xA3, 0xE6, - 0xA1, 0x36, 0xDB, 0xE4, 0xA0, 0x1E, 0x79, 0x03, - 0x79, 0x7A, 0xD6, 0xCE, 0x76, 0x6E, 0x2B, 0x91, - 0xB9, 0xB4, 0xA4, 0x03, 0x51, 0x27, 0xD6, 0x5F, - 0x4B, 0xE8, 0x65, 0x50, 0x11, 0x94, 0x18, 0xE2, - 0x2D, 0xA0, 0x0F, 0xD0, 0x6B, 0xF2, 0xB2, 0x75, - 0x96, 0xB3, 0x7F, 0x06, 0xBE, 0x0A, 0x15, 0x4A, - 0xAF, 0x7E, 0xCA, 0x54, 0xC4, 0x52, 0x0B, 0x97 - }, - { - 0x24, 0xDC, 0x1E, 0x6D, 0xC4, 0xE5, 0x1A, 0x3A, - 0x3C, 0x8D, 0xA6, 0x7A, 0xAC, 0xB4, 0xC5, 0x41, - 0xE4, 0x18, 0x18, 0xD1, 0x80, 0xE5, 0xBB, 0x69, - 0x75, 0x3D, 0xBB, 0xFF, 0x2F, 0x44, 0xD0, 0xE7, - 0xDA, 0x83, 0x03, 0x86, 0xBF, 0xC8, 0x3B, 0x27, - 0xA5, 0x9D, 0xBB, 0x62, 0xB9, 0x64, 0xFC, 0x8E, - 0xA6, 0xCB, 0xDF, 0x30, 0x49, 0xBF, 0xF8, 0x1F, - 0x24, 0xF3, 0x48, 0xDB, 0x4E, 0xFD, 0x0D, 0x07 - }, - { - 0xBC, 0x23, 0xF5, 0xAB, 0xDF, 0xFD, 0x6A, 0x32, - 0xA5, 0xD4, 0x08, 0x11, 0x26, 0x2E, 0xD4, 0x47, - 0x9E, 0xF7, 0x0B, 0x42, 0x33, 0xCA, 0x20, 0x5B, - 0xC5, 0xB9, 0xBF, 0x85, 0x96, 0x73, 0x19, 0x82, - 0xD0, 0x41, 0x69, 0xA9, 0x04, 0xDD, 0x43, 0xB0, - 0xE0, 0xF9, 0x48, 0x99, 0xF7, 0x33, 0x02, 0x2D, - 0x24, 0xD8, 0x4F, 0xAD, 0x0A, 0x99, 0x16, 0x00, - 0xF1, 0x97, 0x9B, 0x27, 0x2A, 0xD6, 0x20, 0x73 - }, - { - 0xEF, 0x10, 0x7F, 0xCD, 0x0D, 0x92, 0xD8, 0x4E, - 0xF5, 0xEF, 0x94, 0x63, 0xE6, 0xE9, 0x62, 0x41, - 0x25, 0x45, 0x29, 0xD2, 0xB9, 0x7F, 0xDB, 0xE5, - 0x64, 0x19, 0x07, 0x0A, 0xDB, 0xC7, 0xD5, 0x70, - 0x6F, 0xEB, 0x8F, 0x44, 0x95, 0x79, 0x81, 0x9E, - 0xD4, 0xBE, 0x61, 0x97, 0x85, 0xFF, 0xFA, 0xAF, - 0x0D, 0x97, 0x89, 0xCF, 0xE7, 0x26, 0x24, 0x9A, - 0xB0, 0x8C, 0x94, 0x68, 0xCB, 0x5F, 0xDE, 0x22 - }, - { - 0x23, 0x1F, 0xBF, 0xB7, 0xA1, 0xDD, 0xC5, 0xB7, - 0x49, 0x33, 0xA2, 0x85, 0xA4, 0x22, 0x4C, 0x04, - 0x9C, 0xBA, 0x14, 0x85, 0xCE, 0x35, 0x64, 0x0D, - 0x9C, 0x51, 0x6E, 0xD7, 0x8E, 0xAA, 0x22, 0x6D, - 0x36, 0xF6, 0x5B, 0x25, 0x89, 0xB8, 0x26, 0xC4, - 0x59, 0xFA, 0x6A, 0x91, 0xC4, 0x26, 0xFD, 0x2A, - 0x8A, 0xB4, 0x61, 0xC9, 0x76, 0x7E, 0x7B, 0xDD, - 0x99, 0x6B, 0xEF, 0x5A, 0x78, 0xF4, 0x81, 0xB7 - }, - { - 0x3A, 0x83, 0x1F, 0x2D, 0xA9, 0x69, 0xB9, 0xB7, - 0x36, 0x0E, 0x74, 0xEE, 0x53, 0xB5, 0x18, 0x98, - 0x0A, 0x5E, 0xBC, 0xDF, 0xD4, 0xEE, 0x23, 0xED, - 0x80, 0x5C, 0x26, 0x39, 0x4D, 0x18, 0x24, 0x20, - 0x8D, 0x7E, 0x8F, 0x63, 0x27, 0xD4, 0xEC, 0x87, - 0x97, 0x9C, 0xE4, 0xAF, 0x8A, 0xB0, 0x97, 0xD6, - 0x9E, 0x26, 0x1C, 0xA3, 0x2D, 0xB0, 0xEE, 0xFD, - 0xBC, 0x18, 0xD1, 0x63, 0x77, 0xA6, 0xBD, 0x20 - }, - { - 0x83, 0x49, 0xA2, 0x0F, 0xDD, 0xBA, 0xE1, 0xD8, - 0x47, 0x2B, 0x67, 0xF0, 0x34, 0x7A, 0xA0, 0xFD, - 0x40, 0x4D, 0x65, 0xC6, 0xFA, 0x14, 0x72, 0xB3, - 0x10, 0x39, 0x0D, 0x75, 0x65, 0xBA, 0x6B, 0xC1, - 0x02, 0x60, 0xD3, 0xDC, 0xE6, 0xA1, 0x4F, 0x4D, - 0xD9, 0xB8, 0xB3, 0xE0, 0xA0, 0xC4, 0x7F, 0x6D, - 0xB7, 0xE7, 0x10, 0x0A, 0x7A, 0x9B, 0x64, 0xA8, - 0x44, 0xF0, 0x10, 0x64, 0xD0, 0x79, 0x05, 0xC5 - }, - { - 0x23, 0x9A, 0xE3, 0xD6, 0x85, 0x9C, 0x7C, 0x97, - 0x2A, 0x5D, 0xC8, 0xB9, 0xC5, 0x5A, 0xEB, 0x93, - 0x85, 0x90, 0xCF, 0xB8, 0x55, 0x2A, 0xA3, 0x05, - 0xA6, 0xF6, 0xF3, 0x1F, 0xFA, 0x95, 0xA8, 0x40, - 0xF4, 0xEC, 0x36, 0xF6, 0xFB, 0x8F, 0x83, 0xB6, - 0x9C, 0x1D, 0xA9, 0x81, 0xFC, 0x9B, 0xA1, 0x63, - 0x60, 0xDB, 0x0F, 0x4F, 0x7C, 0x68, 0xEB, 0x54, - 0x3E, 0xD5, 0x8B, 0x28, 0x75, 0x6A, 0x1E, 0x0D - }, - { - 0x7C, 0x56, 0x73, 0x28, 0x63, 0x08, 0x40, 0x8F, - 0xBC, 0x62, 0x24, 0x0E, 0x07, 0x47, 0x28, 0xB2, - 0x7A, 0x57, 0x5C, 0xAD, 0x2A, 0x15, 0x6E, 0x00, - 0xB5, 0xC0, 0x8B, 0x21, 0x8D, 0x88, 0x87, 0x79, - 0x1E, 0x47, 0xBF, 0x10, 0xB0, 0xBC, 0x61, 0xA5, - 0x82, 0x54, 0x5A, 0x24, 0x69, 0x63, 0x9C, 0xE6, - 0x28, 0xC4, 0x0F, 0x20, 0xEA, 0x8B, 0x84, 0x9C, - 0xD0, 0x05, 0x44, 0x5F, 0x29, 0xA0, 0x8C, 0xCE - }, - { - 0xDD, 0x07, 0x7E, 0x76, 0x9E, 0x0D, 0xEF, 0x78, - 0xDD, 0x7A, 0xAD, 0xD5, 0x7D, 0x58, 0x42, 0x1B, - 0xDA, 0x3A, 0x1A, 0x4E, 0x69, 0x72, 0x05, 0x9F, - 0x8E, 0x64, 0x9C, 0xD6, 0xBC, 0xA4, 0x4A, 0x13, - 0xAB, 0x71, 0xEB, 0x53, 0x5D, 0x24, 0x49, 0x22, - 0x94, 0x84, 0x65, 0xD7, 0x3B, 0xD6, 0x4E, 0xFB, - 0x09, 0x10, 0x46, 0x94, 0x90, 0x66, 0x65, 0x36, - 0x03, 0x57, 0x5A, 0x2E, 0x89, 0x1E, 0xBD, 0x54 - }, - { - 0xB3, 0x6C, 0xEF, 0x28, 0x53, 0x2B, 0x40, 0xD8, - 0x17, 0x86, 0x28, 0xF0, 0xFA, 0xB5, 0xE5, 0xB4, - 0xA1, 0xDE, 0xC0, 0xC0, 0xE9, 0x11, 0xD7, 0x27, - 0xBF, 0x09, 0x49, 0x0F, 0x5E, 0x8D, 0x9F, 0xAC, - 0x57, 0x21, 0x3F, 0xD2, 0xA2, 0xD1, 0x2E, 0xD3, - 0xD7, 0x7A, 0x41, 0xF5, 0xE2, 0xFE, 0xCC, 0x40, - 0xE4, 0xEE, 0xCA, 0x16, 0x12, 0xF5, 0x1C, 0x45, - 0x23, 0x31, 0xAE, 0x93, 0x96, 0x62, 0x35, 0xBC - }, - { - 0xDE, 0x73, 0x7D, 0xBC, 0x61, 0x2E, 0xBD, 0x31, - 0xBC, 0x49, 0xA2, 0xD7, 0xC6, 0x44, 0xD4, 0xB1, - 0x37, 0x81, 0x74, 0x19, 0x42, 0x1C, 0x32, 0xF4, - 0xE7, 0x51, 0x14, 0xD8, 0x99, 0xE3, 0x13, 0x1D, - 0x45, 0xCA, 0x54, 0x51, 0x24, 0x8F, 0x24, 0x16, - 0x9F, 0xBF, 0x17, 0xEE, 0x60, 0xA9, 0xB7, 0x07, - 0x98, 0xA4, 0xB9, 0x37, 0xCE, 0xA6, 0x27, 0x95, - 0x28, 0x96, 0x39, 0xD1, 0x8F, 0xCD, 0x89, 0xE4 - }, - { - 0xB4, 0xC1, 0xBB, 0xCB, 0xBC, 0xCD, 0xFC, 0xE4, - 0xD2, 0xBE, 0x9D, 0xCD, 0xB9, 0x83, 0xC1, 0xB0, - 0x20, 0xC5, 0xF7, 0x20, 0xDA, 0x5B, 0xEC, 0xF4, - 0xCB, 0x2A, 0x9A, 0x3D, 0x1B, 0x8D, 0x23, 0xCE, - 0xA7, 0xA9, 0xF5, 0xFD, 0x70, 0xD3, 0x74, 0x0E, - 0xCD, 0x67, 0xCE, 0x7D, 0x1E, 0x9C, 0x5E, 0x31, - 0xA3, 0x30, 0x2D, 0xF6, 0x6A, 0x9B, 0x5D, 0x54, - 0x30, 0x44, 0x90, 0xFB, 0xE1, 0xC4, 0xA8, 0xB9 - }, - { - 0xB1, 0xD6, 0x5E, 0x70, 0xC6, 0x9B, 0xA7, 0xE3, - 0xA7, 0x28, 0xE8, 0xB6, 0x44, 0x94, 0x93, 0xF2, - 0x37, 0x51, 0x0B, 0x23, 0xB6, 0xE7, 0x7D, 0x95, - 0x84, 0xD0, 0x5F, 0xF4, 0xD3, 0xF0, 0x87, 0x80, - 0x92, 0x9D, 0x74, 0xFA, 0x5B, 0xED, 0x9B, 0x75, - 0xD4, 0xD6, 0xD1, 0xCA, 0x91, 0xAB, 0x8D, 0x26, - 0x37, 0xDC, 0x2E, 0x79, 0xBA, 0x0F, 0xE0, 0x59, - 0x4A, 0xCD, 0x68, 0xFB, 0x3C, 0xC6, 0x60, 0xB9 - }, - { - 0xDA, 0x79, 0xF7, 0x29, 0xEA, 0xB9, 0x8C, 0x04, - 0xF3, 0x7F, 0xCC, 0x85, 0x4B, 0x69, 0xA8, 0x4E, - 0x46, 0x7D, 0xEA, 0x1E, 0x77, 0x82, 0xE7, 0xAF, - 0x02, 0xCB, 0x44, 0xA4, 0x9D, 0x21, 0x0D, 0x25, - 0x23, 0x68, 0x3D, 0x42, 0x0A, 0xC1, 0xDE, 0xC8, - 0xAD, 0x1F, 0xB4, 0x0E, 0x65, 0xAB, 0x3F, 0xE2, - 0x51, 0xA8, 0x51, 0xE2, 0x83, 0xD8, 0x58, 0x38, - 0x08, 0x42, 0x61, 0x30, 0x1E, 0xCD, 0x08, 0x9B - }, - { - 0x71, 0x40, 0x40, 0x40, 0x39, 0x21, 0xAE, 0x55, - 0x48, 0xA2, 0x03, 0x39, 0xD6, 0x9E, 0x09, 0x3F, - 0x60, 0x9A, 0xA9, 0x9C, 0x22, 0xDB, 0x72, 0x59, - 0x1D, 0x1E, 0xF4, 0xFC, 0xB0, 0xAF, 0x01, 0x61, - 0x73, 0xE5, 0x77, 0xD8, 0xC1, 0xA3, 0x06, 0x3B, - 0x44, 0x3A, 0x0E, 0x48, 0xF3, 0x13, 0xCF, 0x2E, - 0x0F, 0x9B, 0x0C, 0x2E, 0xF9, 0x6A, 0x96, 0xC4, - 0x24, 0x32, 0x2C, 0xCC, 0x0C, 0xD5, 0x30, 0x4C - }, - { - 0x8B, 0x2E, 0x8C, 0x3F, 0x0E, 0x3C, 0x31, 0x9B, - 0xA6, 0x7E, 0x86, 0x01, 0x4B, 0xDA, 0x68, 0x3E, - 0x53, 0x57, 0xA0, 0x40, 0x37, 0xB4, 0x56, 0x32, - 0x86, 0xAC, 0x89, 0xCD, 0xDB, 0x7E, 0xE0, 0x4C, - 0xF6, 0x67, 0x5F, 0x9A, 0xB6, 0x1F, 0xC8, 0x33, - 0x2D, 0x21, 0x8D, 0x2B, 0xCA, 0x97, 0x15, 0xE7, - 0xDB, 0xE5, 0x83, 0x72, 0xD1, 0xEE, 0xBF, 0x6B, - 0xC2, 0x94, 0x84, 0x71, 0xCF, 0xCE, 0xBB, 0x77 - }, - { - 0x32, 0xEE, 0x95, 0x49, 0xD4, 0xE3, 0x2F, 0x4B, - 0xE9, 0xC5, 0x00, 0xBD, 0x85, 0x43, 0xAF, 0xD0, - 0xB6, 0x97, 0x82, 0xD0, 0xB3, 0xFF, 0x7E, 0xD4, - 0x7A, 0x88, 0x1A, 0x0E, 0x49, 0x1F, 0x37, 0x65, - 0x0A, 0x21, 0xB2, 0x6C, 0x3F, 0x5D, 0x0A, 0x64, - 0xE0, 0x90, 0x58, 0xB3, 0x00, 0x4A, 0x23, 0x68, - 0xB9, 0x50, 0xE4, 0x72, 0x30, 0xC2, 0x29, 0x66, - 0xD3, 0xF7, 0x9D, 0xA7, 0xBA, 0xA0, 0xB8, 0x7F - }, - { - 0xCA, 0xE7, 0xF2, 0x92, 0x71, 0x37, 0x82, 0xC4, - 0x71, 0xFE, 0x31, 0x78, 0xA9, 0x42, 0x0C, 0xD4, - 0xC1, 0x1F, 0xCD, 0x3F, 0x6D, 0xBE, 0x5D, 0x15, - 0xC8, 0x4A, 0xB7, 0x35, 0x3C, 0x73, 0x9E, 0xF0, - 0x64, 0x16, 0x39, 0xA2, 0xF9, 0x2A, 0xED, 0x31, - 0xC5, 0x6A, 0x20, 0x21, 0xCC, 0x5E, 0x58, 0xCB, - 0xEA, 0xD3, 0x74, 0xE2, 0xDC, 0x8A, 0x0D, 0xBC, - 0xE5, 0x45, 0x0F, 0xE7, 0xA0, 0x18, 0xCF, 0xA4 - }, - { - 0xF1, 0x7F, 0xEF, 0xAE, 0xAE, 0x7D, 0x40, 0xCD, - 0x88, 0x5D, 0xAC, 0x0B, 0xC3, 0x50, 0xC0, 0x27, - 0x36, 0x68, 0xEA, 0x02, 0x22, 0xDF, 0x5C, 0x75, - 0x69, 0x4F, 0x5C, 0xB3, 0xA3, 0x21, 0x51, 0x9F, - 0x6E, 0x0E, 0xC4, 0x3B, 0xA0, 0xC8, 0x59, 0x3D, - 0xC7, 0x34, 0x13, 0x41, 0xE5, 0x19, 0x48, 0x8F, - 0x20, 0xAB, 0xD5, 0xB8, 0x12, 0x4D, 0xFA, 0xCE, - 0xA5, 0xCD, 0xE0, 0x96, 0x5B, 0x69, 0x70, 0xF9 - }, - { - 0xE2, 0xCF, 0x86, 0xDD, 0xC8, 0x42, 0x4E, 0xE5, - 0x47, 0xEB, 0x72, 0x45, 0xB7, 0x32, 0x5E, 0x02, - 0xF2, 0xE3, 0xAC, 0x01, 0x3C, 0x8D, 0x38, 0x6B, - 0x3D, 0x2E, 0x09, 0x20, 0x8A, 0x9B, 0xCC, 0x0B, - 0x44, 0xC4, 0xC4, 0x38, 0xEA, 0xAF, 0x52, 0xD2, - 0x07, 0x7E, 0x91, 0x77, 0xEB, 0x8E, 0xE1, 0xD5, - 0x90, 0x75, 0xB5, 0x25, 0x92, 0x20, 0x20, 0x62, - 0x22, 0x93, 0x54, 0xBF, 0x23, 0xC9, 0x62, 0x39 - }, - { - 0x38, 0xF2, 0x6A, 0x11, 0x02, 0xCB, 0x16, 0x2D, - 0x35, 0x1F, 0x84, 0x3B, 0x3C, 0x49, 0xF6, 0xFF, - 0x85, 0x44, 0x16, 0x33, 0xB6, 0x70, 0x4A, 0x28, - 0x6A, 0xF8, 0x1C, 0xCB, 0xAE, 0x5A, 0x67, 0xD3, - 0x01, 0x5C, 0xC0, 0xEF, 0xAF, 0xB7, 0x05, 0x7D, - 0xC2, 0xB2, 0x8D, 0x67, 0x66, 0xE8, 0x2A, 0x06, - 0x8A, 0x4C, 0x0B, 0x52, 0x4B, 0x66, 0xD0, 0xA6, - 0x32, 0x77, 0x5D, 0x93, 0x06, 0x15, 0x75, 0xF9 - }, - { - 0xA2, 0xC4, 0x30, 0x2D, 0xAC, 0xA7, 0xA7, 0xC6, - 0x32, 0xF6, 0x76, 0x30, 0x4E, 0x62, 0x75, 0xC1, - 0xC1, 0xF0, 0xDB, 0xFE, 0x38, 0xDC, 0x57, 0x1C, - 0xB2, 0x3E, 0x1F, 0x7B, 0xA5, 0xDC, 0x18, 0x18, - 0x0F, 0xC4, 0x8A, 0x01, 0x5F, 0x92, 0x7C, 0x89, - 0x96, 0x7C, 0x1E, 0x10, 0x4E, 0x66, 0xF5, 0xEA, - 0x5B, 0x2D, 0xD3, 0x1D, 0x78, 0x1C, 0x38, 0x49, - 0xBF, 0xC6, 0x49, 0x22, 0x0C, 0x38, 0x5C, 0x82 - }, - { - 0xC1, 0x9C, 0x6B, 0x3F, 0xB5, 0x35, 0x2B, 0xB3, - 0x94, 0xC2, 0x68, 0x46, 0x52, 0x3C, 0x25, 0xE8, - 0x26, 0x5D, 0x50, 0x5F, 0x50, 0x1F, 0x96, 0x03, - 0xA4, 0xF8, 0xBD, 0x55, 0x38, 0x6C, 0xF4, 0xCC, - 0x9F, 0x4D, 0x71, 0xF3, 0x8F, 0xF4, 0x45, 0xF4, - 0xEF, 0xC8, 0x30, 0x98, 0xD4, 0x79, 0x69, 0x33, - 0x4E, 0x79, 0xA2, 0xBC, 0xB4, 0x02, 0x6B, 0xC6, - 0x3B, 0x79, 0x59, 0xDE, 0xDB, 0x62, 0xB7, 0xBD - }, - { - 0x1F, 0x4A, 0xB9, 0x84, 0x0A, 0x1C, 0xFA, 0x8F, - 0xE6, 0xC5, 0x62, 0x2D, 0x9B, 0x53, 0x8B, 0xEC, - 0xB8, 0x80, 0x7A, 0x87, 0x78, 0xB6, 0x9D, 0x93, - 0x05, 0xF9, 0x08, 0x57, 0x65, 0x73, 0xB2, 0x0C, - 0xA3, 0x70, 0x4E, 0x89, 0x12, 0x97, 0x26, 0xD5, - 0x02, 0xE1, 0x98, 0x58, 0x8D, 0x07, 0x26, 0x68, - 0xBF, 0x03, 0x63, 0x0B, 0x5B, 0x5A, 0x92, 0x32, - 0xFF, 0x39, 0x25, 0x27, 0x24, 0x9D, 0xF9, 0x9B - }, - { - 0xFE, 0x03, 0x17, 0x7B, 0x58, 0xB4, 0x88, 0x83, - 0xA8, 0x6D, 0x42, 0x68, 0x33, 0x4B, 0x95, 0x91, - 0xD9, 0xFB, 0xD8, 0xBF, 0x7C, 0xC2, 0xAA, 0xCC, - 0x50, 0x25, 0xEF, 0x47, 0x6B, 0x45, 0x33, 0xBA, - 0x7B, 0xD7, 0x81, 0xDF, 0x01, 0x11, 0x47, 0xB3, - 0xCF, 0x51, 0x1D, 0x8B, 0x3D, 0xCD, 0x8C, 0x78, - 0x0D, 0x30, 0xD7, 0xDA, 0x71, 0x8C, 0x22, 0x44, - 0x23, 0x19, 0x81, 0x7B, 0xE3, 0x18, 0x6B, 0xC5 - }, - { - 0xF4, 0xC3, 0xB0, 0x59, 0x10, 0x5B, 0x6A, 0xA5, - 0xFE, 0x78, 0x84, 0x3A, 0x07, 0xD9, 0x4F, 0x71, - 0x20, 0x62, 0xCB, 0x5A, 0x4D, 0xD6, 0x05, 0x9F, - 0x97, 0x90, 0x4D, 0x0C, 0x57, 0x97, 0x3B, 0xA8, - 0xDF, 0x71, 0xD1, 0x5A, 0x51, 0x1A, 0x06, 0x68, - 0x64, 0xFE, 0x45, 0x5E, 0xDC, 0x9E, 0x5F, 0x16, - 0x52, 0x4C, 0xEC, 0x7E, 0xE2, 0x48, 0xEE, 0x3E, - 0xC9, 0x29, 0x06, 0x3B, 0xD1, 0x07, 0x98, 0xDA - }, - { - 0x57, 0xA1, 0x6F, 0x96, 0x4B, 0x18, 0x1B, 0x12, - 0x03, 0xA5, 0x80, 0x3B, 0x73, 0x81, 0x7D, 0x77, - 0x44, 0x83, 0x82, 0x6C, 0xEA, 0x11, 0x3B, 0x9C, - 0xCF, 0xCF, 0x0E, 0xB8, 0x7C, 0xB2, 0x30, 0x64, - 0x28, 0x49, 0x62, 0xD8, 0x47, 0xBB, 0x1F, 0xAE, - 0x8C, 0xBF, 0x5C, 0xC6, 0x3B, 0x3C, 0xEA, 0xA1, - 0x24, 0x1E, 0xA4, 0x2C, 0x63, 0xF8, 0x98, 0x01, - 0x1F, 0xC4, 0xDB, 0xCA, 0xE6, 0xF5, 0xE8, 0xC5 - }, - { - 0x79, 0x52, 0xFC, 0x83, 0xAC, 0xF1, 0x3A, 0x95, - 0xCA, 0x9C, 0x27, 0xA2, 0x15, 0x6D, 0x9C, 0x1B, - 0x63, 0x00, 0xB0, 0xEF, 0x79, 0x0F, 0x57, 0x2B, - 0xC3, 0x94, 0xC6, 0x77, 0xF7, 0xC1, 0x46, 0x29, - 0xEB, 0xD8, 0xE7, 0xD5, 0xD7, 0xC7, 0xF1, 0xA5, - 0xEB, 0xBD, 0xC3, 0x90, 0xCC, 0x08, 0xCD, 0x58, - 0xC2, 0x00, 0x89, 0x00, 0xCB, 0x55, 0xEB, 0x05, - 0xE4, 0x44, 0xA6, 0x8C, 0x3B, 0x39, 0x3E, 0x60 - }, - { - 0x2C, 0x22, 0x40, 0xD6, 0xB5, 0x41, 0xF4, 0x29, - 0x4F, 0xF9, 0x76, 0x79, 0x1D, 0x35, 0xE6, 0xA2, - 0xD4, 0x92, 0xF5, 0x7A, 0x91, 0x5F, 0xBA, 0xC5, - 0x83, 0x26, 0x60, 0xC1, 0x0E, 0x9C, 0x96, 0x46, - 0x5C, 0x7B, 0xD5, 0xFC, 0xA7, 0x51, 0xBF, 0x68, - 0xE2, 0x67, 0x3A, 0x63, 0x8E, 0x3A, 0xF7, 0x35, - 0xB0, 0x20, 0x91, 0xD7, 0x5D, 0x1A, 0x7F, 0x89, - 0xE3, 0xF7, 0x61, 0xC5, 0xDF, 0x82, 0x1A, 0x6B - }, - { - 0x59, 0xDC, 0x84, 0x6D, 0x34, 0x05, 0xCC, 0xD8, - 0x06, 0xF8, 0xFA, 0x20, 0xC8, 0x96, 0x9E, 0xF6, - 0x8A, 0x43, 0x85, 0xEF, 0x6C, 0x27, 0x4E, 0xEE, - 0x6D, 0xC0, 0x69, 0x2C, 0x3E, 0xCF, 0xB1, 0xA8, - 0x34, 0xCE, 0x64, 0x43, 0x76, 0xC5, 0x2B, 0x80, - 0x42, 0x1B, 0xAE, 0x94, 0xD6, 0xC7, 0xFD, 0xCC, - 0xA5, 0xA8, 0xF1, 0x85, 0x9C, 0x45, 0xA1, 0x0C, - 0x4E, 0xB2, 0x74, 0x82, 0x6F, 0x1F, 0x08, 0x9F - }, - { - 0xB7, 0x52, 0x96, 0x27, 0x07, 0xA1, 0x7B, 0x66, - 0x4F, 0xAE, 0xB3, 0x13, 0xE2, 0xB9, 0x52, 0xDC, - 0x03, 0xE7, 0x4A, 0x7E, 0x94, 0x47, 0x09, 0x8A, - 0xA6, 0xD4, 0xEA, 0x5B, 0xD2, 0x87, 0xD0, 0x7A, - 0x12, 0x25, 0xEC, 0xED, 0xA9, 0x81, 0x15, 0x70, - 0x58, 0x0A, 0x51, 0x2B, 0x2B, 0x20, 0xB3, 0xFC, - 0xFC, 0xA7, 0x0B, 0x44, 0xF6, 0x45, 0x4E, 0xF3, - 0xC3, 0x52, 0x4C, 0xCA, 0x6B, 0x69, 0x47, 0x5B - }, - { - 0xDA, 0x0D, 0x8E, 0x54, 0x61, 0xF8, 0x10, 0x24, - 0xEF, 0xFE, 0xED, 0x5D, 0x70, 0x76, 0xA0, 0x4F, - 0xED, 0xED, 0xAC, 0x57, 0xE7, 0xC9, 0x8A, 0x59, - 0x45, 0xBF, 0xDE, 0x66, 0x75, 0x58, 0x18, 0x85, - 0x1B, 0xE1, 0x13, 0x6B, 0x71, 0xF4, 0x33, 0xA5, - 0x6B, 0xDA, 0x18, 0x41, 0xAE, 0x71, 0x39, 0x2C, - 0x4B, 0x82, 0x90, 0x82, 0x63, 0x59, 0xF5, 0x87, - 0x22, 0x3C, 0x3E, 0xF7, 0x37, 0xFF, 0x73, 0x2A - }, - { - 0xED, 0xB8, 0x6A, 0x23, 0x7C, 0x6F, 0x13, 0x7D, - 0xFB, 0xB3, 0x47, 0x01, 0x1E, 0xDB, 0x4C, 0x6E, - 0x86, 0x1F, 0x4D, 0x58, 0x14, 0x60, 0x85, 0x46, - 0x34, 0x41, 0x04, 0x2F, 0xA3, 0x63, 0x16, 0xF1, - 0xFA, 0xF8, 0x87, 0x11, 0xBB, 0x0F, 0x18, 0x11, - 0xDF, 0xBB, 0xBF, 0xA7, 0xB5, 0x1F, 0x9C, 0xE2, - 0xD4, 0x96, 0x05, 0x24, 0x3E, 0xD0, 0x16, 0xCB, - 0xAD, 0x68, 0x85, 0xEA, 0xE2, 0x03, 0x67, 0x4F - }, - { - 0xE6, 0xD8, 0xE0, 0xFB, 0xAA, 0x29, 0xDB, 0xEB, - 0x60, 0xF3, 0xC7, 0xF9, 0x85, 0xBA, 0xD7, 0x54, - 0xD7, 0x21, 0xAA, 0xC6, 0x3D, 0xA6, 0xF4, 0x49, - 0x0C, 0x9D, 0x7E, 0xA2, 0x31, 0xD2, 0x62, 0x2F, - 0xDF, 0xDE, 0xF1, 0x48, 0xD0, 0xCA, 0x44, 0x2B, - 0x8D, 0x59, 0xCF, 0x3E, 0x4F, 0x98, 0x35, 0xCB, - 0xC2, 0x40, 0xAF, 0x40, 0xFB, 0xA6, 0x3A, 0x2E, - 0xA5, 0xA2, 0x35, 0xD4, 0x6E, 0xEA, 0x6E, 0xAC - }, - { - 0xD4, 0xE4, 0x63, 0xC4, 0x88, 0x29, 0x87, 0xEB, - 0x44, 0xA5, 0xED, 0x0C, 0x82, 0x1D, 0x68, 0xB0, - 0xFE, 0xF9, 0x9D, 0x6F, 0x53, 0xA5, 0x7B, 0xF3, - 0x19, 0xBD, 0xAC, 0x25, 0xAC, 0x38, 0xEB, 0x0B, - 0x23, 0xE1, 0x13, 0x8C, 0x00, 0x12, 0xF5, 0xF3, - 0x83, 0x46, 0xA1, 0xDE, 0x9D, 0x4A, 0x99, 0x2A, - 0x64, 0xB9, 0x42, 0x83, 0x4A, 0x85, 0x6E, 0xFB, - 0xAA, 0x06, 0x20, 0xBD, 0xA2, 0x9F, 0x6A, 0x86 - }, - { - 0x42, 0xD8, 0x10, 0xD0, 0x1C, 0x2D, 0xA2, 0x47, - 0x35, 0xF0, 0x4A, 0x5E, 0x90, 0x13, 0x38, 0xFD, - 0xFC, 0x2D, 0xE1, 0x71, 0x5F, 0xF6, 0x64, 0x3A, - 0x37, 0x2F, 0x88, 0x0E, 0x6C, 0x5C, 0x6C, 0x13, - 0xD2, 0xB3, 0xAD, 0x70, 0x77, 0x46, 0x9D, 0x64, - 0x33, 0x54, 0x05, 0x4D, 0x32, 0xDD, 0x80, 0x49, - 0xEA, 0x63, 0x73, 0x2B, 0x57, 0x45, 0xBD, 0xB2, - 0x3B, 0xE2, 0xB5, 0x8E, 0x48, 0xC1, 0x01, 0x3A - }, - { - 0xCF, 0xBF, 0x54, 0x30, 0x07, 0x6F, 0x82, 0x5A, - 0x3B, 0xBB, 0x88, 0xC1, 0xBC, 0x0A, 0xEF, 0x61, - 0x25, 0x9E, 0x8F, 0x4D, 0x5F, 0xA3, 0x3C, 0x39, - 0x82, 0x50, 0x62, 0xF1, 0x5D, 0x19, 0xFD, 0x4A, - 0x01, 0x82, 0xCD, 0x97, 0x36, 0xD2, 0xAE, 0xC9, - 0x74, 0x9C, 0xCF, 0x83, 0x18, 0x6C, 0x35, 0x74, - 0xAB, 0x94, 0x42, 0x65, 0x40, 0x66, 0x0A, 0x9D, - 0xB8, 0xC3, 0xAA, 0xBB, 0xCB, 0xDD, 0x9D, 0x0F - }, - { - 0x6C, 0x24, 0x34, 0xA1, 0xAF, 0xA1, 0x57, 0xAC, - 0xCC, 0x34, 0xA5, 0xC4, 0x87, 0x2D, 0xFF, 0x69, - 0xFE, 0x7F, 0x31, 0x96, 0xCB, 0x1A, 0x75, 0x0C, - 0x54, 0x1D, 0x8B, 0x73, 0x92, 0x28, 0x88, 0xBA, - 0xBE, 0x89, 0xB1, 0xC3, 0x82, 0x02, 0x21, 0x86, - 0x20, 0xD8, 0x8D, 0x77, 0xDA, 0xD9, 0xDF, 0xBA, - 0xB3, 0xFB, 0xF7, 0x40, 0xB2, 0xD1, 0xD8, 0xF3, - 0x7E, 0xAD, 0x25, 0x8E, 0x2E, 0xF1, 0x06, 0x52 - }, - { - 0x48, 0xB7, 0x26, 0x8A, 0xA4, 0x34, 0x2F, 0xAB, - 0x02, 0x1D, 0x14, 0x72, 0xE9, 0x25, 0x7F, 0x76, - 0x58, 0x5C, 0xC5, 0x68, 0x10, 0xC8, 0xF2, 0xA6, - 0xE1, 0xD4, 0xA8, 0x94, 0x6B, 0x77, 0x71, 0x42, - 0xD4, 0x4A, 0xE5, 0x13, 0xA8, 0x80, 0x9F, 0x2D, - 0x6D, 0xC7, 0x26, 0x30, 0x5F, 0x79, 0x44, 0x60, - 0x4D, 0x95, 0x2D, 0x4A, 0x9F, 0x08, 0x5C, 0x5C, - 0x10, 0x50, 0xBA, 0xFD, 0xD2, 0x1D, 0x1E, 0x60 - }, - { - 0xCE, 0xCF, 0xCE, 0x4B, 0x12, 0xC6, 0xCF, 0x53, - 0xD1, 0xB1, 0xB2, 0xD4, 0x18, 0xA4, 0x93, 0xE3, - 0xF4, 0x29, 0x17, 0x03, 0x21, 0xE8, 0x1A, 0xA2, - 0x52, 0x63, 0xAA, 0xA7, 0x15, 0xD5, 0xCA, 0x38, - 0x9F, 0x65, 0xC3, 0xAC, 0xF9, 0x9B, 0x18, 0x0E, - 0x44, 0x6B, 0x50, 0xE6, 0x01, 0xFC, 0xBF, 0x44, - 0x61, 0xD0, 0x42, 0x6A, 0x85, 0x92, 0xA0, 0x77, - 0x42, 0x20, 0x18, 0x57, 0x12, 0x5F, 0x71, 0xEE - }, - { - 0x38, 0x5A, 0x75, 0x22, 0x42, 0xEB, 0x9E, 0xD5, - 0x6B, 0x07, 0x4B, 0x70, 0x2C, 0x91, 0xE7, 0x5A, - 0xEC, 0x0B, 0xE9, 0x06, 0x4B, 0xD9, 0xCF, 0x88, - 0x03, 0x04, 0xC2, 0x13, 0x27, 0x0C, 0xB2, 0xEA, - 0xE8, 0xE2, 0x1D, 0x9A, 0xE8, 0xC6, 0x08, 0x15, - 0x19, 0xF7, 0x5D, 0xFA, 0xBB, 0x00, 0x3B, 0x24, - 0x32, 0xB0, 0x47, 0x55, 0xB8, 0xC3, 0x2C, 0x97, - 0xAC, 0x29, 0x14, 0xE8, 0xBF, 0x45, 0xB2, 0x34 - }, - { - 0xD8, 0x9A, 0x12, 0x4A, 0x9B, 0x95, 0x8B, 0xA2, - 0x3D, 0x09, 0x20, 0x7A, 0xCF, 0xA6, 0x2A, 0x33, - 0xB8, 0x70, 0x89, 0xB2, 0x86, 0xE8, 0x43, 0x8B, - 0xDC, 0x01, 0xE2, 0x33, 0xAB, 0x2A, 0x86, 0x30, - 0xA1, 0xEE, 0xB6, 0xB2, 0xB9, 0xBA, 0x6B, 0x7D, - 0x21, 0x00, 0x10, 0x77, 0x33, 0xDE, 0xAF, 0x4C, - 0x20, 0x47, 0x8C, 0x26, 0xF2, 0x49, 0xC6, 0x89, - 0xC5, 0x26, 0x84, 0x73, 0xE2, 0xE9, 0xFA, 0x60 - }, - { - 0x43, 0xDE, 0x10, 0x92, 0xFF, 0x9F, 0xF5, 0x28, - 0x20, 0x6C, 0x6F, 0xCF, 0x81, 0x32, 0x2E, 0xAD, - 0x3D, 0x22, 0xEA, 0xA4, 0xC8, 0x54, 0x52, 0x15, - 0x77, 0xDF, 0x33, 0x62, 0x47, 0x49, 0x5C, 0xE1, - 0x72, 0xFC, 0x87, 0x39, 0x95, 0x30, 0x0B, 0x21, - 0xB9, 0x46, 0x10, 0xC9, 0xD2, 0xF6, 0x33, 0xB5, - 0x33, 0xBD, 0xE4, 0x56, 0x8C, 0xA0, 0x9C, 0x38, - 0x0E, 0x84, 0x68, 0xFE, 0x6A, 0xD8, 0xD8, 0x1D - }, - { - 0x86, 0x8B, 0x60, 0x11, 0x99, 0xEF, 0x00, 0x0B, - 0x70, 0x5C, 0xD6, 0x4D, 0x39, 0x30, 0x26, 0x2A, - 0x5A, 0xB9, 0x10, 0xE3, 0x4E, 0x2D, 0x78, 0xE8, - 0x58, 0x7B, 0x4E, 0x01, 0x0D, 0x37, 0x6D, 0xD4, - 0xA0, 0x0D, 0xE4, 0x48, 0x67, 0xD0, 0xE9, 0x33, - 0xEE, 0x39, 0xA1, 0xFA, 0x91, 0x47, 0xD4, 0x99, - 0xD1, 0x84, 0xF3, 0xA9, 0xCF, 0x35, 0x4F, 0x2D, - 0x3C, 0x51, 0x14, 0x6F, 0xF7, 0x15, 0x2D, 0x68 - }, - { - 0x15, 0x17, 0xF8, 0xF0, 0x44, 0x2F, 0x0D, 0x50, - 0xBB, 0xC0, 0xAA, 0xB6, 0x84, 0x6F, 0xDC, 0xE3, - 0xB7, 0x0F, 0xAE, 0xA4, 0xBB, 0x51, 0x13, 0xAC, - 0xB2, 0x3A, 0xBE, 0x10, 0x1D, 0x99, 0xA4, 0x0A, - 0x1B, 0x76, 0xC1, 0xE8, 0xDC, 0x2E, 0xA1, 0x93, - 0x62, 0x94, 0x82, 0x3A, 0xD8, 0x35, 0x4C, 0x11, - 0xE2, 0xE9, 0x6C, 0x67, 0x12, 0xBE, 0x4C, 0xF7, - 0x7C, 0x58, 0x3F, 0xD0, 0x6B, 0x5E, 0x5C, 0x55 - }, - { - 0xAF, 0x4C, 0x6C, 0x67, 0xC5, 0xCA, 0x38, 0x38, - 0x73, 0x48, 0xCA, 0x3E, 0xC2, 0xBE, 0xD7, 0xFB, - 0xA8, 0xC2, 0xB3, 0xD2, 0x2D, 0xE1, 0x48, 0xD0, - 0x8A, 0x61, 0x8C, 0x29, 0x70, 0x23, 0xFB, 0x7B, - 0x6D, 0x2C, 0x15, 0x3D, 0x5E, 0xFC, 0xD1, 0x68, - 0x89, 0x99, 0x91, 0x0B, 0x20, 0xE1, 0xEA, 0xC7, - 0xC1, 0x00, 0xA2, 0xC5, 0xA6, 0xC1, 0xAC, 0xF5, - 0xE9, 0x8F, 0x14, 0x3B, 0x41, 0xDC, 0x8A, 0x12 - }, - { - 0xA2, 0xAD, 0x94, 0x24, 0x3B, 0x8E, 0xEA, 0x68, - 0xF5, 0xFA, 0xDD, 0x69, 0x08, 0xAD, 0xB0, 0xDA, - 0xCD, 0xAA, 0x6A, 0x6D, 0x24, 0xC2, 0x50, 0xD3, - 0x39, 0x40, 0x3D, 0xBA, 0x82, 0x31, 0xBD, 0x51, - 0xE8, 0x87, 0xCB, 0x5B, 0x1B, 0x7B, 0xDE, 0x27, - 0x74, 0xC6, 0xB0, 0x8A, 0xCC, 0xE0, 0xF7, 0x49, - 0x56, 0x48, 0xDA, 0x3B, 0xEB, 0xC7, 0xB1, 0xC2, - 0x82, 0x15, 0x08, 0xC4, 0xD3, 0x82, 0xF7, 0x30 - }, - { - 0x28, 0xF8, 0x8C, 0xDB, 0xE9, 0x03, 0xAD, 0x63, - 0xA0, 0x23, 0x31, 0xDE, 0x1A, 0x32, 0xAF, 0x6D, - 0xBB, 0xA8, 0x2D, 0x7F, 0xC0, 0x79, 0x87, 0x02, - 0x72, 0x49, 0x33, 0xDA, 0x77, 0x38, 0x07, 0xBC, - 0x80, 0x42, 0x78, 0x13, 0x47, 0x81, 0xF1, 0x26, - 0x23, 0x32, 0x20, 0xE3, 0x07, 0x92, 0x81, 0x31, - 0xB2, 0x47, 0x10, 0xB4, 0x67, 0x4E, 0xD7, 0x05, - 0x11, 0x2F, 0x95, 0xD1, 0xAA, 0x37, 0xA2, 0xDC - }, - { - 0x5B, 0xB2, 0x92, 0x65, 0xE2, 0x46, 0xB8, 0x84, - 0xFF, 0x40, 0x91, 0x4F, 0xFA, 0x93, 0xD9, 0xA1, - 0x2E, 0xDC, 0x19, 0xEE, 0xE9, 0xCC, 0x8A, 0x83, - 0x63, 0x1D, 0x68, 0xBD, 0x46, 0xAA, 0xD3, 0x35, - 0x4B, 0xA6, 0x67, 0x4B, 0x91, 0x3F, 0x4F, 0x82, - 0x3E, 0x79, 0x1F, 0x0C, 0xB1, 0x9E, 0xA6, 0xA6, - 0x7C, 0x6E, 0x32, 0xE9, 0xBE, 0x0D, 0x0F, 0xF5, - 0x76, 0x0F, 0x16, 0xDD, 0x75, 0xA8, 0x7B, 0x5D - }, - { - 0xBF, 0x3C, 0x06, 0xDC, 0x6D, 0x94, 0xE3, 0x85, - 0x9A, 0x4D, 0xAA, 0x50, 0xEC, 0xA1, 0xAF, 0x53, - 0x57, 0xE3, 0x45, 0x79, 0xE5, 0x99, 0xF8, 0x20, - 0x49, 0xE1, 0xCC, 0xA7, 0xA7, 0xD4, 0xF3, 0x3F, - 0xEA, 0x44, 0x3B, 0x44, 0x69, 0x1B, 0xD4, 0x36, - 0x88, 0xF5, 0x55, 0x05, 0x31, 0xCF, 0x22, 0xB7, - 0x12, 0x77, 0x89, 0x0B, 0xFF, 0xAE, 0x1E, 0xCE, - 0x78, 0x3F, 0x56, 0x63, 0xA1, 0xC4, 0xD7, 0x1A - }, - { - 0xC9, 0x0D, 0xF5, 0x32, 0xF2, 0xF1, 0x49, 0x3A, - 0x11, 0x55, 0xBE, 0x8C, 0x2A, 0x44, 0x00, 0x92, - 0x20, 0x49, 0x97, 0x4E, 0x7D, 0x4F, 0x4B, 0x54, - 0xF8, 0x20, 0xC2, 0x26, 0x9D, 0x3B, 0x16, 0x1B, - 0x6E, 0x88, 0xEB, 0x77, 0x6B, 0x85, 0x9B, 0x89, - 0xB8, 0x56, 0x7F, 0xBC, 0x55, 0x0C, 0x4F, 0x54, - 0xAA, 0xD2, 0x7A, 0x16, 0x10, 0x65, 0x6D, 0x62, - 0x5C, 0x32, 0x7F, 0x66, 0x5D, 0xCA, 0x70, 0x7C - }, - { - 0x3D, 0x39, 0xEE, 0xCC, 0x9E, 0x90, 0x42, 0x36, - 0xDC, 0x85, 0x7B, 0xA4, 0x9D, 0x55, 0xD3, 0xBA, - 0xD7, 0x65, 0x72, 0xA9, 0x1A, 0x75, 0x95, 0x03, - 0x37, 0x6B, 0x77, 0x08, 0xD6, 0x2D, 0x5A, 0x78, - 0x5C, 0x23, 0x06, 0x80, 0x59, 0xCF, 0x68, 0x89, - 0x7F, 0x23, 0xEE, 0xC5, 0x07, 0x21, 0x9B, 0x0A, - 0x02, 0xED, 0xA2, 0xD8, 0xBC, 0x94, 0xFA, 0x69, - 0x89, 0xA5, 0x14, 0x82, 0x22, 0x03, 0xC8, 0xD1 - }, - { - 0xE0, 0x8C, 0x54, 0xD9, 0x98, 0xF9, 0x2B, 0x7A, - 0x54, 0xA2, 0x4C, 0xA6, 0xAE, 0xB1, 0x53, 0xA6, - 0x4F, 0x9C, 0x9F, 0x1F, 0xC3, 0x36, 0x58, 0xB3, - 0xED, 0xAC, 0x2C, 0x4B, 0xB5, 0x26, 0x31, 0x58, - 0xDA, 0xDF, 0x00, 0xD3, 0x51, 0x9A, 0x11, 0x9A, - 0x56, 0x14, 0xC7, 0xF3, 0x79, 0x40, 0xE5, 0x5D, - 0x13, 0xCC, 0xE4, 0x66, 0xCB, 0x71, 0xA4, 0x07, - 0xC3, 0x9F, 0xC5, 0x1E, 0x1E, 0xFE, 0x18, 0xDA - }, - { - 0x74, 0x76, 0x76, 0x07, 0x04, 0x1D, 0xD4, 0xB7, - 0xC5, 0x6B, 0x18, 0x9E, 0xE8, 0xF2, 0x77, 0x31, - 0xA5, 0x16, 0x72, 0x23, 0xEB, 0x7A, 0xF9, 0xB9, - 0x39, 0xE1, 0x18, 0xF8, 0x7D, 0x80, 0xB4, 0x9E, - 0xA8, 0xD0, 0xD0, 0x1F, 0x74, 0xF3, 0x98, 0xB1, - 0x72, 0xA8, 0xAD, 0x0D, 0xBF, 0x99, 0x41, 0x4F, - 0x08, 0xD2, 0xB7, 0xD8, 0xD7, 0x52, 0x16, 0xA1, - 0x82, 0x25, 0x27, 0x3D, 0x8D, 0x7F, 0xD0, 0x5D - }, - { - 0xFE, 0xE8, 0x9A, 0x92, 0xCC, 0xF9, 0xF1, 0xEB, - 0x08, 0x4A, 0xAB, 0xA9, 0x54, 0x97, 0xEF, 0x0F, - 0x30, 0x13, 0x4C, 0x19, 0x1C, 0xF9, 0x0A, 0x49, - 0xD2, 0x2C, 0x7D, 0x2F, 0x66, 0x14, 0x99, 0x3C, - 0xBE, 0x1A, 0x4B, 0x65, 0x13, 0xED, 0xC1, 0x53, - 0x86, 0x8A, 0x3D, 0x56, 0x2B, 0x5B, 0x02, 0x26, - 0xBA, 0x8E, 0x1B, 0x0D, 0xCB, 0x69, 0xED, 0x45, - 0xAF, 0x47, 0xCE, 0x4F, 0x86, 0xBA, 0x47, 0x4A - }, - { - 0xCD, 0xAE, 0x94, 0xB6, 0xD1, 0xD8, 0x35, 0xF6, - 0xC7, 0x4C, 0x76, 0xEC, 0x3A, 0x2D, 0xB6, 0x5B, - 0xBD, 0xFA, 0xE1, 0x9D, 0x7B, 0x05, 0x0D, 0xC9, - 0x5D, 0x65, 0x87, 0x33, 0xB8, 0xB2, 0x2C, 0x6F, - 0x9E, 0x0B, 0x63, 0xCC, 0x90, 0x5A, 0x29, 0xEA, - 0x88, 0x78, 0xCA, 0x39, 0x45, 0x56, 0xB3, 0x67, - 0x3C, 0x62, 0x79, 0x15, 0x46, 0xA9, 0xA1, 0xF0, - 0xD1, 0x56, 0x5F, 0xAD, 0xC5, 0x35, 0x36, 0xC1 - }, - { - 0xC7, 0x22, 0x8B, 0x6F, 0x00, 0x00, 0x17, 0xD2, - 0xBE, 0x4B, 0xF2, 0xAE, 0x48, 0xAD, 0xDB, 0x78, - 0x5E, 0x27, 0x35, 0xBF, 0x3C, 0x61, 0x4D, 0x3C, - 0x34, 0x23, 0x1F, 0x1D, 0x0C, 0x88, 0x7D, 0x3A, - 0x8E, 0x88, 0x88, 0x0B, 0x67, 0xAD, 0x3B, 0x2F, - 0x65, 0x23, 0xDD, 0x67, 0x19, 0x34, 0x2C, 0xD4, - 0xF0, 0x59, 0x35, 0xD2, 0xE5, 0x26, 0x7F, 0x36, - 0x80, 0xE7, 0x73, 0xBD, 0x5E, 0xAD, 0xFE, 0x1D - }, - { - 0x12, 0x27, 0x44, 0xFE, 0x3F, 0xFF, 0x9A, 0x05, - 0x5F, 0x0F, 0x3B, 0xDE, 0x01, 0xEB, 0x2F, 0x44, - 0x6B, 0x0C, 0xDA, 0xF3, 0xAE, 0xD7, 0x2C, 0xAA, - 0x29, 0x40, 0x74, 0x19, 0x20, 0x12, 0x0A, 0x96, - 0x4F, 0xCF, 0xF8, 0x70, 0x99, 0xB0, 0x8E, 0xF3, - 0x34, 0x96, 0xE3, 0x99, 0x03, 0x2A, 0x82, 0xDA, - 0xAD, 0x4F, 0xED, 0x30, 0x31, 0x17, 0x2F, 0x77, - 0x47, 0x92, 0x58, 0xFA, 0x39, 0xDB, 0x92, 0xFD - }, - { - 0x1F, 0xB4, 0xE3, 0x67, 0xEA, 0xB6, 0x42, 0xB7, - 0x2E, 0x43, 0xAD, 0x4A, 0xBD, 0xFC, 0xAD, 0x74, - 0x62, 0x0C, 0x3F, 0x6C, 0x63, 0xA8, 0x91, 0x31, - 0x28, 0xD2, 0x22, 0x6E, 0xB1, 0x92, 0xF9, 0x99, - 0x2E, 0xB9, 0xC8, 0xF7, 0x6A, 0xE2, 0x06, 0xD3, - 0xF5, 0xDE, 0xC7, 0x26, 0xA5, 0xA6, 0x86, 0xB4, - 0xAE, 0x37, 0xB5, 0x57, 0xAB, 0x57, 0xF9, 0x56, - 0x48, 0x53, 0x34, 0xF7, 0x3D, 0xCE, 0x02, 0xE0 - }, - { - 0x04, 0x25, 0xCA, 0xAA, 0x92, 0x3B, 0x47, 0xB3, - 0x50, 0x45, 0xEB, 0x50, 0x82, 0x9C, 0x04, 0x8B, - 0xC8, 0x90, 0x44, 0x4A, 0xFE, 0xEF, 0xC0, 0xAF, - 0xC9, 0xD1, 0x87, 0x7B, 0x82, 0x1E, 0x04, 0x3C, - 0x9C, 0x7B, 0x9D, 0x6D, 0xC3, 0x3F, 0xBB, 0xDF, - 0xA5, 0x37, 0xC1, 0xEC, 0xE3, 0x11, 0x96, 0x5B, - 0x2F, 0xEE, 0x89, 0x82, 0xBC, 0x46, 0xA2, 0xA7, - 0x50, 0xBF, 0xC7, 0x1D, 0x79, 0xDB, 0xEA, 0x04 - }, - { - 0x6B, 0x9D, 0x86, 0xF1, 0x5C, 0x09, 0x0A, 0x00, - 0xFC, 0x3D, 0x90, 0x7F, 0x90, 0x6C, 0x5E, 0xB7, - 0x92, 0x65, 0xE5, 0x8B, 0x88, 0xEB, 0x64, 0x29, - 0x4B, 0x4C, 0xC4, 0xE2, 0xB8, 0x9B, 0x1A, 0x7C, - 0x5E, 0xE3, 0x12, 0x7E, 0xD2, 0x1B, 0x45, 0x68, - 0x62, 0xDE, 0x6B, 0x2A, 0xBD, 0xA5, 0x9E, 0xAA, - 0xCF, 0x2D, 0xCB, 0xE9, 0x22, 0xCA, 0x75, 0x5E, - 0x40, 0x73, 0x5B, 0xE8, 0x1D, 0x9C, 0x88, 0xA5 - }, - { - 0x14, 0x6A, 0x18, 0x7A, 0x99, 0xE8, 0xA2, 0xD2, - 0x33, 0xE0, 0xEB, 0x37, 0x3D, 0x43, 0x7B, 0x02, - 0xBF, 0xA8, 0xD6, 0x51, 0x5B, 0x3C, 0xA1, 0xDE, - 0x48, 0xA6, 0xB6, 0xAC, 0xF7, 0x43, 0x7E, 0xB7, - 0xE7, 0xAC, 0x3F, 0x2D, 0x19, 0xEF, 0x3B, 0xB9, - 0xB8, 0x33, 0xCC, 0x57, 0x61, 0xDB, 0xA2, 0x2D, - 0x1A, 0xD0, 0x60, 0xBE, 0x76, 0xCD, 0xCB, 0x81, - 0x2D, 0x64, 0xD5, 0x78, 0xE9, 0x89, 0xA5, 0xA4 - }, - { - 0x25, 0x75, 0x4C, 0xA6, 0x66, 0x9C, 0x48, 0x70, - 0x84, 0x03, 0x88, 0xEA, 0x64, 0xE9, 0x5B, 0xD2, - 0xE0, 0x81, 0x0D, 0x36, 0x3C, 0x4C, 0xF6, 0xA1, - 0x6E, 0xA1, 0xBD, 0x06, 0x68, 0x6A, 0x93, 0xC8, - 0xA1, 0x25, 0xF2, 0x30, 0x22, 0x9D, 0x94, 0x84, - 0x85, 0xE1, 0xA8, 0x2D, 0xE4, 0x82, 0x00, 0x35, - 0x8F, 0x3E, 0x02, 0xB5, 0x05, 0xDA, 0xBC, 0x4F, - 0x13, 0x9C, 0x03, 0x79, 0xDC, 0x2B, 0x30, 0x80 - }, - { - 0x0E, 0x26, 0xCB, 0xC7, 0x8D, 0xC7, 0x54, 0xEC, - 0xA0, 0x6C, 0xF8, 0xCB, 0x31, 0xFC, 0xBA, 0xBB, - 0x18, 0x88, 0x92, 0xC1, 0x04, 0x50, 0x89, 0x05, - 0x49, 0xB2, 0xD4, 0x03, 0xA2, 0xA3, 0xC4, 0x57, - 0x70, 0x01, 0xF7, 0x4A, 0x76, 0xBD, 0x38, 0x99, - 0x0D, 0x75, 0x5B, 0xAE, 0x05, 0x26, 0x64, 0x83, - 0x29, 0xF6, 0x35, 0x45, 0xED, 0x16, 0x99, 0x5C, - 0xB1, 0xE6, 0x34, 0x3F, 0x18, 0x9F, 0x8E, 0x6F - }, - { - 0x58, 0xE7, 0x98, 0x0B, 0x8B, 0x1A, 0x0B, 0x88, - 0xDA, 0x9D, 0xA8, 0x64, 0x0F, 0x2B, 0x96, 0xE3, - 0xE0, 0x48, 0x36, 0x61, 0x30, 0xC2, 0x66, 0x21, - 0x7D, 0xDC, 0x79, 0x53, 0x50, 0x8F, 0x4A, 0x40, - 0xD1, 0x67, 0x4D, 0xAB, 0xD3, 0x92, 0x89, 0xE3, - 0xF1, 0x0C, 0x61, 0x19, 0x68, 0xCC, 0xD1, 0xE9, - 0xCC, 0xC1, 0x8C, 0xAD, 0xC7, 0x77, 0x4A, 0x99, - 0x7D, 0xD1, 0xFA, 0x94, 0xE8, 0x35, 0x47, 0x07 - }, - { - 0x69, 0x6F, 0xB8, 0x47, 0x63, 0xE0, 0x23, 0x58, - 0x4B, 0x35, 0x90, 0x7A, 0x8B, 0x8A, 0xAA, 0x9E, - 0x0E, 0x78, 0x6F, 0x2C, 0xA5, 0x91, 0x45, 0x41, - 0x91, 0x58, 0x48, 0xFB, 0x6D, 0xDA, 0xB8, 0xD3, - 0xD2, 0xEA, 0xB6, 0x00, 0xC1, 0x38, 0xCE, 0x67, - 0x17, 0xB0, 0xC7, 0x02, 0x59, 0xD3, 0x19, 0x3E, - 0xA1, 0x56, 0x95, 0xC8, 0x50, 0x53, 0x7F, 0x2C, - 0x70, 0x6C, 0xA4, 0xAF, 0x15, 0x8E, 0x95, 0x7E - }, - { - 0x23, 0xDE, 0x6E, 0x73, 0x07, 0x9C, 0x8C, 0x20, - 0x47, 0xA7, 0x84, 0x6A, 0x83, 0xCC, 0xAC, 0xAB, - 0xD3, 0x71, 0x16, 0x3B, 0x7B, 0x6D, 0x54, 0xEB, - 0x03, 0x2B, 0xC4, 0x9B, 0x66, 0x97, 0x42, 0xBE, - 0x71, 0x7B, 0x99, 0xDA, 0x12, 0xC6, 0x46, 0xAD, - 0x52, 0x57, 0x06, 0xF2, 0x22, 0xE1, 0xDF, 0x4A, - 0x91, 0xDD, 0x0C, 0xC6, 0x4D, 0xF1, 0x82, 0xDA, - 0x00, 0x73, 0x1D, 0x43, 0x9C, 0x46, 0xF8, 0xD2 - }, - { - 0xBB, 0x74, 0xF3, 0x6A, 0x9D, 0xB6, 0x96, 0xC9, - 0x33, 0x35, 0xE6, 0xC4, 0x6A, 0xAB, 0x58, 0xDB, - 0x10, 0xCB, 0x07, 0xEA, 0x4F, 0x1B, 0x71, 0x93, - 0x63, 0x05, 0x22, 0x83, 0x90, 0x95, 0x94, 0x78, - 0xF8, 0x73, 0x4E, 0x21, 0x54, 0x90, 0xE9, 0xAE, - 0x2A, 0x3E, 0xC8, 0xF7, 0xF7, 0x67, 0x33, 0xAE, - 0x3F, 0x8B, 0x9A, 0x3F, 0xD7, 0xC4, 0x06, 0xC6, - 0xCA, 0xC7, 0x09, 0x97, 0x5C, 0x40, 0xF8, 0x56 - }, - { - 0xEC, 0x63, 0x04, 0xD3, 0x8E, 0x23, 0x2C, 0x09, - 0x6A, 0xB5, 0x86, 0xCA, 0xDF, 0x27, 0x02, 0x6D, - 0xC5, 0xE5, 0x32, 0x17, 0xD0, 0xE8, 0xB0, 0xC6, - 0x0A, 0xDA, 0xAE, 0x22, 0xF4, 0xE8, 0xC2, 0x2D, - 0x30, 0xBC, 0x51, 0x77, 0xF1, 0xC8, 0x3A, 0xCD, - 0x92, 0x5E, 0x02, 0xA2, 0xDA, 0x89, 0x59, 0x5F, - 0xC1, 0x06, 0x09, 0x0E, 0x2E, 0x53, 0xED, 0xB3, - 0x1C, 0xDB, 0x76, 0xFF, 0x37, 0xEB, 0x61, 0x80 - }, - { - 0x92, 0xF9, 0xFC, 0x6B, 0xC5, 0x9A, 0x54, 0x3F, - 0x0D, 0xC9, 0xA1, 0x79, 0x8F, 0xB1, 0xE5, 0xD5, - 0x23, 0x47, 0x4E, 0x48, 0xFF, 0x3E, 0x29, 0x49, - 0x7F, 0x72, 0x80, 0xD1, 0xC4, 0x08, 0xC8, 0x66, - 0x33, 0x48, 0xFE, 0x2A, 0xF7, 0x8F, 0x6C, 0x4E, - 0x5E, 0xF5, 0xC0, 0xA0, 0x17, 0xF3, 0xD3, 0xF2, - 0x15, 0xEC, 0xDD, 0x7A, 0x40, 0x0A, 0xC5, 0x77, - 0x3B, 0x9E, 0x25, 0x60, 0x68, 0x84, 0x5A, 0x92 - }, - { - 0x4A, 0x25, 0xB5, 0x62, 0xF2, 0xFA, 0x01, 0xDD, - 0xEE, 0x7E, 0xA2, 0xE9, 0xFB, 0xF5, 0x2F, 0x8C, - 0x75, 0x6D, 0x28, 0xDB, 0x4A, 0x8B, 0xF7, 0x0E, - 0x74, 0x0E, 0x90, 0x27, 0x42, 0x6E, 0x51, 0x63, - 0x9D, 0xF8, 0x78, 0x8D, 0x13, 0x38, 0x56, 0x85, - 0x8D, 0x01, 0xFD, 0xDB, 0xDD, 0x5B, 0x98, 0x79, - 0x44, 0xC3, 0x00, 0xDC, 0x7F, 0x82, 0x41, 0xFB, - 0xCE, 0xFA, 0x4F, 0x12, 0x94, 0x8A, 0xFE, 0xAE - }, - { - 0x34, 0x21, 0x2D, 0xD9, 0xF0, 0x65, 0x1F, 0x81, - 0x80, 0x9A, 0x14, 0xED, 0xBC, 0xF7, 0xF3, 0xAC, - 0xDE, 0xDE, 0x78, 0x72, 0xC7, 0xA4, 0x84, 0x7B, - 0xEA, 0x9F, 0x7A, 0xB7, 0x59, 0x73, 0x82, 0x47, - 0x7A, 0x4C, 0xB8, 0x47, 0x9A, 0x27, 0x63, 0x21, - 0x23, 0x5E, 0x90, 0x21, 0x57, 0x94, 0x46, 0xA4, - 0x38, 0x8A, 0x99, 0xE5, 0x60, 0xA3, 0x90, 0x7A, - 0xEE, 0xF2, 0xB4, 0x38, 0xFE, 0x6B, 0x90, 0xC4 - }, - { - 0xD6, 0x2C, 0xF7, 0xAB, 0xBC, 0x7D, 0x7B, 0xCD, - 0x5B, 0xEB, 0x1E, 0xE4, 0x8C, 0x43, 0xB8, 0x04, - 0xFD, 0x0D, 0xB4, 0x55, 0xE7, 0xF4, 0xFE, 0xBB, - 0xCF, 0xF1, 0x4B, 0x05, 0xBE, 0x90, 0x47, 0xE2, - 0x7E, 0x51, 0x8D, 0x6D, 0x3A, 0x6A, 0xDA, 0x4D, - 0x58, 0x63, 0xB7, 0xEC, 0x7F, 0x84, 0x92, 0x45, - 0x89, 0x40, 0xAC, 0x6B, 0xDD, 0xB5, 0x06, 0x59, - 0x2C, 0xCB, 0xC8, 0x96, 0xAF, 0xBB, 0x77, 0xA3 - }, - { - 0x33, 0xA3, 0xA2, 0x63, 0x6F, 0x91, 0x98, 0xD3, - 0x7A, 0x5F, 0xF1, 0xBF, 0xF9, 0xEB, 0x10, 0x02, - 0x4B, 0x28, 0x46, 0x80, 0x39, 0xF4, 0x91, 0x40, - 0x2D, 0x39, 0xB7, 0x08, 0xC5, 0x5D, 0x27, 0xE5, - 0xE8, 0xDF, 0x5E, 0x3E, 0x19, 0x49, 0x95, 0x82, - 0x35, 0xCA, 0xD9, 0x80, 0x74, 0x20, 0x96, 0xF2, - 0x77, 0x9A, 0x1D, 0x71, 0xDA, 0xD5, 0x8F, 0xAF, - 0xA3, 0xCD, 0x02, 0xCB, 0x5E, 0xAA, 0x98, 0xC5 - }, - { - 0xB7, 0xA3, 0x89, 0x90, 0xE6, 0xF4, 0x56, 0x4A, - 0xA3, 0xD9, 0x3A, 0x79, 0x37, 0x10, 0x0C, 0x29, - 0xF9, 0x40, 0xAF, 0xF7, 0xCB, 0x20, 0x86, 0x5A, - 0x1C, 0x21, 0x89, 0x81, 0xA5, 0x42, 0x04, 0x86, - 0x08, 0x17, 0x81, 0xF8, 0xD5, 0x0C, 0x86, 0x62, - 0x5C, 0xC5, 0xD7, 0x6D, 0x0F, 0x5C, 0xCC, 0x4E, - 0xB6, 0x5D, 0x43, 0x66, 0x09, 0x62, 0x4F, 0x21, - 0xD0, 0x53, 0x39, 0xAB, 0x0C, 0xF7, 0x9F, 0x4C - }, - { - 0x9D, 0x66, 0x5A, 0x3F, 0xDD, 0x10, 0x45, 0x9E, - 0x77, 0xF0, 0x3A, 0xC8, 0xC0, 0xE2, 0x39, 0x01, - 0x94, 0x89, 0x69, 0x3C, 0xC9, 0x31, 0x5A, 0xA3, - 0xFF, 0x11, 0x29, 0x11, 0xD2, 0xAC, 0xF0, 0xB7, - 0xD2, 0x76, 0xAC, 0x76, 0x9B, 0xED, 0xFD, 0x85, - 0x2D, 0x28, 0x89, 0xDD, 0x12, 0xDB, 0x91, 0x39, - 0x8B, 0x01, 0xC4, 0xF4, 0xA5, 0xDA, 0x27, 0x80, - 0xB1, 0xDE, 0xFE, 0x0D, 0x95, 0xB6, 0x32, 0x70 - }, - { - 0x70, 0xFB, 0x9E, 0xFD, 0x5B, 0xCA, 0x7F, 0x19, - 0xB6, 0xE3, 0x1D, 0x64, 0x0D, 0xCF, 0x88, 0xD7, - 0x7E, 0x76, 0x8A, 0xE2, 0x27, 0xEC, 0xB3, 0xFD, - 0x6B, 0x47, 0x13, 0x78, 0x94, 0xF5, 0x49, 0xBF, - 0x1C, 0xF0, 0x6E, 0x5D, 0xB4, 0x54, 0x60, 0x44, - 0xDD, 0x9F, 0x46, 0x5C, 0x9C, 0x85, 0xF7, 0x28, - 0x4F, 0xE5, 0x4D, 0x2B, 0x71, 0x52, 0x69, 0x9B, - 0xE4, 0xBD, 0x55, 0x5A, 0x90, 0x9A, 0x88, 0xA9 - }, - { - 0x7A, 0xFD, 0xB0, 0x19, 0x30, 0x87, 0xE0, 0xC9, - 0xF8, 0xB4, 0xDD, 0x8B, 0x48, 0xD9, 0xF2, 0x0A, - 0xCE, 0x27, 0x13, 0xAF, 0xC7, 0x1B, 0xCC, 0x93, - 0x82, 0xB5, 0x42, 0x90, 0xAE, 0xBF, 0xFE, 0xB2, - 0xD1, 0x38, 0xF4, 0xDC, 0xF0, 0x28, 0xF9, 0xC4, - 0x3C, 0xC1, 0x80, 0x89, 0x84, 0x77, 0xA3, 0x9E, - 0x3F, 0x53, 0xA8, 0xD1, 0xBF, 0x67, 0xCE, 0xB6, - 0x08, 0x26, 0x1F, 0xAE, 0x6D, 0xDB, 0x1A, 0xBC - }, - { - 0x05, 0x99, 0x0D, 0x7D, 0x7D, 0xF1, 0xD4, 0x84, - 0xF5, 0xB1, 0xCA, 0xE9, 0xEE, 0x5D, 0xFC, 0xB4, - 0x3F, 0x2C, 0xBE, 0x18, 0x6C, 0x1A, 0x5B, 0x18, - 0x1A, 0x37, 0x31, 0xD4, 0xB1, 0x54, 0x8E, 0xBF, - 0xF5, 0xBF, 0x61, 0xCB, 0x0F, 0x6D, 0x9F, 0xC2, - 0x30, 0xF2, 0x5E, 0x86, 0x78, 0xB7, 0x99, 0xE0, - 0xE8, 0x30, 0x26, 0xA0, 0x86, 0x6B, 0xF0, 0xAC, - 0xAB, 0x08, 0x9E, 0x10, 0x2E, 0x67, 0xAB, 0x6B - }, - { - 0x1A, 0xF7, 0xA5, 0xCE, 0x58, 0x7C, 0x8D, 0x87, - 0xC7, 0xB7, 0x9F, 0xA3, 0xE7, 0x23, 0xD7, 0x4C, - 0xE0, 0x26, 0xB5, 0x28, 0x67, 0x52, 0xFD, 0x0C, - 0x37, 0x42, 0xC6, 0xF0, 0x41, 0x8E, 0xD7, 0x85, - 0x99, 0x0D, 0x21, 0xF2, 0x8D, 0xA8, 0x39, 0xCE, - 0x82, 0x12, 0xED, 0x55, 0x0C, 0x37, 0x3E, 0x6D, - 0x3A, 0x75, 0xD5, 0x5C, 0x31, 0x77, 0x04, 0x41, - 0xEE, 0xAF, 0xF2, 0xD5, 0x0F, 0x6E, 0x61, 0xB6 - }, - { - 0xDD, 0xEE, 0x0C, 0x76, 0xC9, 0xBD, 0xD3, 0x2D, - 0x70, 0x49, 0x35, 0x4C, 0xFC, 0x85, 0xDC, 0x68, - 0x67, 0xE2, 0x49, 0x2E, 0x47, 0xFE, 0xB0, 0x8E, - 0x39, 0x83, 0xD0, 0xB6, 0x78, 0x84, 0x5D, 0x7E, - 0xC6, 0xC9, 0x79, 0x3C, 0x33, 0x26, 0xBF, 0xDC, - 0x1E, 0x11, 0x32, 0x76, 0xD1, 0x77, 0xFE, 0x38, - 0x82, 0x52, 0x04, 0xDD, 0x00, 0x07, 0x39, 0x89, - 0xC0, 0x81, 0xCC, 0x3B, 0x71, 0xC6, 0x8D, 0x5F - }, - { - 0xDE, 0x07, 0x06, 0x48, 0xB3, 0x7C, 0x47, 0xDC, - 0x9F, 0x2F, 0x6D, 0x2A, 0xB2, 0x07, 0x73, 0xCD, - 0x82, 0xFA, 0x57, 0x25, 0xA6, 0x90, 0x0E, 0xB7, - 0x1C, 0xDD, 0xB0, 0xC9, 0xF3, 0x9B, 0x31, 0xDF, - 0x6D, 0x07, 0x73, 0x24, 0x6E, 0x8E, 0xF9, 0x03, - 0x49, 0x67, 0x75, 0x2D, 0xB7, 0xED, 0x22, 0x73, - 0x3F, 0x43, 0x79, 0x94, 0x8D, 0xC3, 0x96, 0xDC, - 0x35, 0xAD, 0xBB, 0xE9, 0xF6, 0x53, 0x77, 0x40 - }, - { - 0xA6, 0x45, 0x6F, 0xBC, 0xFF, 0x9E, 0x3D, 0x5B, - 0x11, 0x6A, 0x0E, 0x33, 0x1A, 0x1F, 0x97, 0x4F, - 0x07, 0x0E, 0x95, 0x56, 0x09, 0x78, 0x1F, 0xA5, - 0x99, 0xD6, 0x08, 0xA3, 0x1D, 0xA7, 0x6A, 0xD8, - 0xAB, 0xFE, 0x34, 0x66, 0x17, 0xC2, 0x57, 0x86, - 0x51, 0x3B, 0x2C, 0x44, 0xBF, 0xE2, 0xCB, 0x45, - 0x7C, 0x43, 0xFA, 0x6F, 0x45, 0x36, 0x1C, 0xA9, - 0xC6, 0x34, 0x13, 0x11, 0xB7, 0xDD, 0xFB, 0xD5 - }, - { - 0x5C, 0x95, 0xD3, 0x82, 0x02, 0x18, 0x91, 0x04, - 0x8B, 0x5E, 0xC8, 0x1C, 0xC8, 0x8E, 0x66, 0xB1, - 0xB4, 0xD8, 0x0A, 0x00, 0xB5, 0xEE, 0x66, 0xB3, - 0xC0, 0x30, 0x77, 0x49, 0xE6, 0xF2, 0x4D, 0x17, - 0x0D, 0x23, 0xFA, 0xCC, 0x8E, 0xB2, 0x53, 0xB3, - 0x56, 0x2B, 0xF8, 0xA4, 0x5C, 0x37, 0x99, 0x0C, - 0xD2, 0xD3, 0xE4, 0x43, 0xB1, 0x8C, 0x68, 0xBB, - 0xCC, 0x6C, 0x83, 0x1D, 0xFD, 0xE2, 0xF8, 0xE5 - }, - { - 0xE3, 0x74, 0x00, 0xDB, 0xD9, 0x21, 0x0F, 0x31, - 0x37, 0xAC, 0xAF, 0x49, 0x24, 0x2F, 0xA1, 0x23, - 0xA0, 0x52, 0x95, 0x8A, 0x4C, 0x0D, 0x98, 0x90, - 0x62, 0x47, 0xD5, 0x35, 0xA3, 0x51, 0xFD, 0x52, - 0x29, 0x6E, 0x70, 0x10, 0x32, 0x5B, 0xDA, 0x84, - 0x1F, 0xA2, 0xAA, 0xB4, 0x47, 0x63, 0x76, 0x3C, - 0x55, 0x04, 0xD7, 0xB3, 0x0C, 0x6D, 0x79, 0xFC, - 0x1D, 0xC8, 0xCF, 0x10, 0x24, 0x46, 0x6D, 0xB0 - }, - { - 0x52, 0x73, 0xA3, 0xA1, 0x3C, 0xF0, 0xEC, 0x72, - 0x00, 0x44, 0x2C, 0xBD, 0x7B, 0x37, 0x44, 0x66, - 0xA7, 0x19, 0x0D, 0xDC, 0xA1, 0x31, 0xD9, 0x63, - 0xF8, 0xF8, 0x39, 0x65, 0xAE, 0xD3, 0xDD, 0x86, - 0xE9, 0xD4, 0x5A, 0xB4, 0x89, 0xB9, 0xC5, 0x62, - 0x47, 0xC9, 0xF2, 0xAA, 0x69, 0xFD, 0x7E, 0x31, - 0x87, 0xB8, 0xFA, 0x0D, 0xAC, 0x77, 0xC4, 0x7C, - 0xB2, 0x95, 0xBA, 0x62, 0x96, 0x78, 0x43, 0x94 - }, - { - 0x2A, 0xDB, 0x93, 0x49, 0xA9, 0xEC, 0x37, 0xFF, - 0x49, 0x62, 0xF4, 0x21, 0x7E, 0x80, 0xEB, 0xDC, - 0xD3, 0x60, 0x96, 0x7B, 0x51, 0x3D, 0x12, 0x02, - 0xD9, 0x98, 0x28, 0x31, 0x15, 0x5D, 0x2F, 0x43, - 0xEB, 0x9A, 0xDD, 0x63, 0xB5, 0xEC, 0x10, 0xD3, - 0xD0, 0x43, 0x0D, 0xC9, 0xCF, 0x76, 0x48, 0x11, - 0x7F, 0xC6, 0x0B, 0xAB, 0xBF, 0x8E, 0xBF, 0x19, - 0xFA, 0xCE, 0xE5, 0x50, 0x45, 0x5B, 0x60, 0xC9 - }, - { - 0xAC, 0xAA, 0xDA, 0x3E, 0x47, 0x37, 0xC6, 0x63, - 0xEB, 0xF0, 0x3C, 0x02, 0x49, 0xCC, 0xA6, 0xF3, - 0x17, 0x9A, 0x03, 0x84, 0xEA, 0x2A, 0xB1, 0x35, - 0xD4, 0xD7, 0xA2, 0xBB, 0x8A, 0x2F, 0x40, 0x53, - 0x9C, 0xDC, 0xE8, 0xA3, 0x76, 0x0F, 0xD1, 0x3D, - 0xEE, 0xEC, 0xD1, 0x60, 0x61, 0x7F, 0x72, 0xDE, - 0x63, 0x75, 0x4E, 0x21, 0x57, 0xCA, 0xDC, 0xF0, - 0x67, 0x32, 0x9C, 0x2A, 0x51, 0x98, 0xF8, 0xE0 - }, - { - 0xEF, 0x15, 0xE6, 0xDB, 0x96, 0xE6, 0xD0, 0xC1, - 0x8C, 0x70, 0xAD, 0xC3, 0xCD, 0xB3, 0x2B, 0x28, - 0x67, 0x74, 0x02, 0xE8, 0xEA, 0x44, 0x11, 0xEA, - 0x2F, 0x34, 0x68, 0xED, 0x93, 0x82, 0xE1, 0x9B, - 0xFE, 0xCA, 0xF5, 0xAC, 0xB8, 0x28, 0xA5, 0x2B, - 0xE1, 0x6B, 0x98, 0x1E, 0x48, 0x7E, 0x5B, 0xB4, - 0xA1, 0x43, 0x08, 0x65, 0x35, 0x8E, 0x97, 0x9F, - 0xB1, 0x07, 0x1F, 0xB9, 0x51, 0x14, 0xFF, 0xDD - }, - { - 0x05, 0x7E, 0xAB, 0x8F, 0xA6, 0x1C, 0x23, 0x09, - 0x67, 0xD9, 0x5D, 0xFB, 0x75, 0x45, 0x57, 0x0E, - 0x34, 0x1A, 0xE3, 0xC6, 0x73, 0x7C, 0x7D, 0xB2, - 0xA2, 0x27, 0xD9, 0x0F, 0xF3, 0x15, 0xD0, 0x98, - 0xD4, 0x76, 0xF7, 0x15, 0x77, 0x9E, 0x67, 0x72, - 0xB4, 0xED, 0x37, 0x54, 0x82, 0x66, 0xE6, 0x59, - 0x8C, 0x6F, 0x09, 0x69, 0x13, 0xC2, 0xFD, 0xD8, - 0xD6, 0xE4, 0x4F, 0xE2, 0xB5, 0x4D, 0x97, 0x80 - }, - { - 0xED, 0xE6, 0x8D, 0x1B, 0x13, 0xE7, 0xEF, 0x78, - 0xD9, 0xC4, 0xEE, 0x10, 0xEC, 0xEB, 0x1D, 0x2A, - 0xEE, 0xC3, 0xB8, 0x15, 0x7F, 0xDB, 0x91, 0x41, - 0x8C, 0x22, 0x19, 0xF6, 0x41, 0x49, 0x74, 0x70, - 0x17, 0xAC, 0xA7, 0xD4, 0x65, 0xB8, 0xB4, 0x7F, - 0xFA, 0x53, 0x64, 0x4B, 0x8B, 0xC6, 0xDA, 0x12, - 0xDD, 0x45, 0xD1, 0x05, 0x5E, 0x47, 0xB4, 0xD8, - 0x39, 0x0E, 0xB2, 0xBD, 0x60, 0x2B, 0xA0, 0x30 - }, - { - 0x27, 0xF8, 0x56, 0xE6, 0x3E, 0xB9, 0x4D, 0x08, - 0xFB, 0xBE, 0x50, 0x22, 0xB0, 0xED, 0xDB, 0xC7, - 0xD8, 0xDB, 0x86, 0x5E, 0xF4, 0xFE, 0xC2, 0x05, - 0x86, 0xDF, 0x3D, 0xD9, 0x02, 0xA0, 0x5B, 0x26, - 0x35, 0x9E, 0x26, 0x7C, 0x78, 0x8D, 0x7C, 0x88, - 0x03, 0x2E, 0x76, 0x6B, 0x11, 0x87, 0x40, 0x20, - 0x0F, 0x49, 0xCB, 0x4D, 0x6E, 0xDB, 0x15, 0x61, - 0xB2, 0xDE, 0x7D, 0xC6, 0x5E, 0xE6, 0x42, 0x3B - }, - { - 0xE9, 0xE9, 0x8D, 0x6D, 0xE0, 0xEF, 0x53, 0xFD, - 0x24, 0x27, 0x66, 0x1E, 0x1A, 0xCF, 0x10, 0x3D, - 0x4C, 0xAA, 0x4D, 0xC6, 0x10, 0x03, 0x62, 0x09, - 0xEC, 0x99, 0x74, 0x19, 0xC1, 0x20, 0x63, 0x1C, - 0x2C, 0x09, 0x4A, 0x8E, 0xE7, 0x82, 0x2D, 0x43, - 0xF8, 0x77, 0x80, 0x11, 0xC6, 0x03, 0x11, 0x1F, - 0x26, 0x28, 0xF8, 0x97, 0xC9, 0xB4, 0x31, 0x31, - 0x54, 0x77, 0x75, 0x6B, 0x03, 0x2E, 0x1F, 0x8D - }, - { - 0x52, 0xEB, 0x1E, 0x6C, 0x8A, 0x54, 0x49, 0x2C, - 0xA7, 0x60, 0xB5, 0x6C, 0xA8, 0x7D, 0xA3, 0xE1, - 0xA9, 0xA6, 0xD8, 0xA4, 0x21, 0x92, 0x19, 0x35, - 0x1D, 0x18, 0x71, 0x5A, 0x9A, 0x2C, 0x26, 0x70, - 0x8B, 0xB7, 0x12, 0xCD, 0xAC, 0x04, 0x34, 0x48, - 0x2E, 0x55, 0x1C, 0xB0, 0x9E, 0x3F, 0x16, 0x33, - 0x8D, 0xE2, 0x9B, 0xE2, 0xC6, 0x67, 0x40, 0xC3, - 0x44, 0xDF, 0x54, 0x88, 0xC5, 0xC2, 0xBB, 0x26 - }, - { - 0x47, 0x3F, 0xA6, 0xC5, 0x1A, 0x48, 0x10, 0x5F, - 0x72, 0x1C, 0x5C, 0xB8, 0xDB, 0xA6, 0x1C, 0x64, - 0xA1, 0xE3, 0xDD, 0xCC, 0xC3, 0x25, 0x0E, 0x68, - 0x22, 0x62, 0xF2, 0x12, 0xC0, 0x1A, 0xB4, 0x87, - 0x4A, 0xFF, 0x68, 0x8F, 0xEA, 0x96, 0x37, 0x73, - 0x9E, 0x2A, 0x25, 0xD2, 0xEE, 0x88, 0xDB, 0xDC, - 0xC4, 0xF0, 0x4D, 0x01, 0x47, 0x9B, 0x30, 0x17, - 0x17, 0x53, 0x3A, 0x64, 0x32, 0xB8, 0x50, 0xCD - }, - { - 0x6B, 0x76, 0x60, 0xD4, 0x10, 0xEA, 0xE5, 0xF3, - 0x5A, 0xD0, 0xAE, 0x85, 0xE6, 0x3D, 0xA4, 0x53, - 0xEB, 0xB0, 0x57, 0xE4, 0x3F, 0x42, 0xE8, 0x42, - 0xCB, 0xF6, 0x25, 0x0D, 0xA6, 0x78, 0x66, 0xB4, - 0x24, 0x0D, 0x57, 0xC8, 0x3B, 0x77, 0x1B, 0x0F, - 0x70, 0x66, 0x3E, 0x17, 0xFB, 0xD9, 0x08, 0x7F, - 0x76, 0xB4, 0xCE, 0x6B, 0xCD, 0x0B, 0x50, 0x2E, - 0x33, 0x74, 0xB1, 0x50, 0x9B, 0xBA, 0x55, 0xA8 - }, - { - 0xA4, 0xD0, 0x8A, 0xCA, 0x7A, 0x9E, 0xA6, 0x43, - 0x99, 0x99, 0xEA, 0x21, 0xE4, 0xCF, 0xE9, 0x86, - 0x9B, 0xB9, 0x0E, 0x3A, 0x01, 0x48, 0x71, 0xAD, - 0x88, 0xED, 0x3A, 0x97, 0xAA, 0x89, 0x15, 0x95, - 0x1C, 0x3F, 0xD0, 0xB3, 0x93, 0x3A, 0x50, 0x85, - 0x88, 0x93, 0x8A, 0xF7, 0x54, 0x49, 0x44, 0xEF, - 0x43, 0xC4, 0x40, 0xAA, 0x8F, 0xF1, 0xE5, 0xA8, - 0x18, 0xA4, 0x66, 0x43, 0x5D, 0xE7, 0x0F, 0xA8 - }, - { - 0x85, 0xE0, 0xE9, 0xB5, 0x0D, 0x2D, 0xB0, 0x22, - 0xC2, 0x39, 0xD7, 0x23, 0x2A, 0xE4, 0x7C, 0x02, - 0x59, 0x22, 0xE4, 0xF0, 0x7E, 0x2A, 0xFC, 0x65, - 0x6C, 0xDC, 0x55, 0x53, 0xA2, 0x7D, 0x95, 0xBF, - 0xA5, 0x8A, 0x57, 0x4D, 0x4E, 0xC3, 0xA9, 0x73, - 0x28, 0x1A, 0x8F, 0x4E, 0x46, 0xA7, 0x1A, 0xB0, - 0x34, 0x1C, 0x25, 0x77, 0x28, 0x74, 0x63, 0xE2, - 0x51, 0x04, 0x4D, 0xB2, 0x39, 0x8D, 0x55, 0xE2 - }, - { - 0x81, 0xA0, 0xD0, 0x24, 0x42, 0x90, 0x51, 0x91, - 0x16, 0x33, 0x70, 0xAE, 0x29, 0xC7, 0xF8, 0x9C, - 0x0F, 0x48, 0xBC, 0x1A, 0x1E, 0xB2, 0x94, 0x70, - 0x47, 0xDA, 0x1C, 0x62, 0x2B, 0x86, 0x77, 0xE9, - 0xEA, 0x9B, 0xEC, 0xED, 0x55, 0xD3, 0x3A, 0xDB, - 0x15, 0x53, 0xBD, 0x58, 0x4A, 0xD2, 0xF8, 0x6A, - 0x62, 0x07, 0xE8, 0x4E, 0x40, 0xE4, 0x60, 0x7E, - 0x11, 0x65, 0x0E, 0xE2, 0x87, 0x9F, 0x4E, 0x0B - }, - { - 0x87, 0x79, 0x0D, 0xF6, 0xCF, 0x73, 0x94, 0x45, - 0x1B, 0xCC, 0x73, 0x0E, 0x53, 0xFC, 0x57, 0xBE, - 0x56, 0x45, 0x22, 0x77, 0x1E, 0x14, 0x43, 0x2A, - 0x80, 0xAB, 0x0B, 0x06, 0xB7, 0xB1, 0xD2, 0x09, - 0xAD, 0x69, 0x89, 0x95, 0x12, 0x53, 0x85, 0xDB, - 0x8B, 0x3C, 0x09, 0x59, 0xB8, 0xA5, 0x33, 0x9E, - 0xDA, 0x0A, 0xE6, 0x78, 0x59, 0xD8, 0x47, 0xF4, - 0x4C, 0x81, 0x59, 0x72, 0x72, 0xCB, 0xF1, 0x95 - }, - { - 0xCC, 0x06, 0x4E, 0xA8, 0x53, 0xDC, 0x01, 0x52, - 0xCC, 0x03, 0xFE, 0xB5, 0xFB, 0x5D, 0xE7, 0x8B, - 0x9B, 0x88, 0xE9, 0x61, 0x55, 0xD5, 0x35, 0x8B, - 0xCE, 0x84, 0xA5, 0x4C, 0x0E, 0x0C, 0x42, 0xFB, - 0xDA, 0x09, 0x2F, 0x22, 0xD0, 0x56, 0xDF, 0x99, - 0x93, 0x26, 0x2E, 0x2B, 0xA4, 0x4A, 0x5B, 0x2D, - 0x53, 0xC3, 0x75, 0x9D, 0x09, 0x45, 0xFE, 0xBA, - 0xA6, 0xFD, 0x51, 0xB8, 0xFF, 0x38, 0xD8, 0x39 - }, - { - 0x7E, 0x51, 0x7F, 0xC3, 0x83, 0xEE, 0x8C, 0x9F, - 0x0A, 0x01, 0x68, 0x1D, 0x39, 0xE7, 0x3B, 0xEB, - 0xA5, 0x96, 0x95, 0x95, 0xCE, 0x77, 0x92, 0x7F, - 0x91, 0x69, 0x1F, 0x33, 0xBB, 0x3E, 0x13, 0x07, - 0xEE, 0x03, 0x61, 0x6C, 0x27, 0xE6, 0x79, 0x51, - 0x86, 0xF6, 0x94, 0x0F, 0xED, 0xD9, 0xD5, 0xC7, - 0xF2, 0x1B, 0x6D, 0x2A, 0xAF, 0x70, 0x29, 0x9C, - 0xDD, 0x83, 0x51, 0x25, 0x05, 0x0A, 0x8B, 0x3C - }, - { - 0x84, 0x5F, 0xCF, 0xA6, 0x7F, 0x6E, 0x06, 0x55, - 0x10, 0xD2, 0x62, 0xF1, 0xDD, 0x69, 0x39, 0xEA, - 0x4C, 0x0A, 0x4A, 0x59, 0xC8, 0xEE, 0x39, 0x77, - 0xDB, 0x70, 0x05, 0xE1, 0xAE, 0xE4, 0x20, 0xBD, - 0x3F, 0x38, 0x26, 0xEC, 0xFE, 0x59, 0x01, 0x5B, - 0x4D, 0xFA, 0x0B, 0xD5, 0xBB, 0xF8, 0xD8, 0xA4, - 0x34, 0x48, 0x5D, 0xC1, 0x1C, 0xB9, 0xCC, 0x85, - 0x97, 0xCB, 0x8C, 0x95, 0x66, 0x11, 0x5F, 0x31 - }, - { - 0x17, 0xCF, 0x2C, 0x23, 0x21, 0x5B, 0xCD, 0xFC, - 0x24, 0x3D, 0x8A, 0x94, 0x5F, 0x3C, 0x5C, 0x25, - 0x1D, 0x27, 0x18, 0xA3, 0xF7, 0x5F, 0xED, 0x6F, - 0x33, 0x20, 0xBC, 0xC6, 0xFD, 0x92, 0x73, 0x86, - 0xD5, 0x6F, 0x87, 0x19, 0xCC, 0xA0, 0x2E, 0xC5, - 0xE9, 0x9C, 0xDA, 0xC4, 0xEA, 0x10, 0x95, 0xB4, - 0x65, 0xBA, 0x9A, 0x29, 0x8B, 0x1D, 0x23, 0x8E, - 0x38, 0xB3, 0xFA, 0x15, 0xE8, 0xB1, 0x4E, 0xE4 - }, - { - 0xD7, 0x89, 0xCE, 0xC7, 0xD7, 0x52, 0x0F, 0x10, - 0xE8, 0xB8, 0xB6, 0xC8, 0x40, 0x95, 0x89, 0xDF, - 0x57, 0xB8, 0x56, 0xB8, 0x24, 0x55, 0x68, 0xF6, - 0x4E, 0x2D, 0x21, 0x83, 0xE3, 0x59, 0xA7, 0x84, - 0xC8, 0xD2, 0x6C, 0xF9, 0xB7, 0x20, 0xF5, 0xDF, - 0x56, 0x7B, 0x01, 0xF3, 0xF4, 0x8D, 0xE6, 0x4D, - 0x4F, 0x0D, 0xB1, 0x56, 0xBE, 0x52, 0x5D, 0x7C, - 0x7A, 0x66, 0x5A, 0xAD, 0xC5, 0x91, 0xF0, 0xB6 - }, - { - 0xB5, 0xE2, 0x46, 0xA9, 0x02, 0x77, 0x10, 0xC0, - 0xB0, 0x55, 0xC7, 0x1F, 0x11, 0x67, 0xE0, 0xEE, - 0x36, 0xEB, 0xC4, 0x32, 0xCF, 0x5D, 0x14, 0x27, - 0x75, 0xA7, 0xAE, 0xCC, 0xCE, 0xA7, 0x83, 0x25, - 0xED, 0x8C, 0x12, 0xF5, 0x0F, 0xBE, 0x64, 0x8A, - 0xDD, 0xF0, 0x59, 0xB8, 0xC0, 0x2A, 0x61, 0x49, - 0x2F, 0x83, 0x57, 0xBE, 0xE1, 0x42, 0xE7, 0xF7, - 0xDE, 0x04, 0x33, 0x78, 0xDB, 0xCF, 0x2D, 0x33 - }, - { - 0xB5, 0x23, 0xFD, 0x77, 0xAB, 0x9E, 0xEE, 0x42, - 0x48, 0x72, 0xBC, 0x2E, 0x83, 0xFC, 0x0A, 0x77, - 0xFF, 0x8A, 0x90, 0xC9, 0xA0, 0xCE, 0x9E, 0x8C, - 0x87, 0x68, 0x0A, 0x0F, 0x62, 0x86, 0x33, 0x1F, - 0x15, 0xC9, 0x3A, 0x2A, 0xFE, 0xCF, 0x75, 0x66, - 0x65, 0x3F, 0x24, 0xD9, 0x30, 0xC3, 0x23, 0x19, - 0x2D, 0x30, 0x43, 0xB9, 0x05, 0x72, 0x1C, 0xBD, - 0xB6, 0x31, 0x11, 0xCA, 0x42, 0xF2, 0x8F, 0x4E - }, - { - 0x43, 0x59, 0xA4, 0x58, 0x76, 0xBF, 0x6A, 0xCC, - 0x0A, 0xEC, 0xE7, 0xB9, 0xB4, 0xB4, 0xA8, 0x38, - 0xB9, 0xDB, 0xA5, 0x77, 0x6A, 0x3B, 0x14, 0xDA, - 0x2F, 0xBA, 0x91, 0x02, 0xE7, 0x8B, 0xF6, 0x48, - 0xFF, 0xB4, 0xD8, 0x67, 0xBA, 0xE8, 0x5F, 0xD9, - 0xB7, 0x13, 0x12, 0xDC, 0x46, 0x02, 0xD0, 0xD4, - 0x9C, 0x90, 0x7B, 0xB9, 0x28, 0x9B, 0x22, 0x95, - 0x96, 0x1E, 0x54, 0x13, 0x81, 0x23, 0xF5, 0x4A - }, - { - 0xD3, 0xF2, 0xC8, 0xE7, 0x4F, 0x34, 0x3A, 0x4E, - 0x71, 0x90, 0xD4, 0x75, 0xCF, 0x9A, 0xF7, 0x54, - 0xEE, 0xD5, 0x57, 0x72, 0x62, 0xB3, 0x5B, 0xD9, - 0xA9, 0xC4, 0x2B, 0x58, 0xCE, 0x88, 0x26, 0x2E, - 0x31, 0x14, 0x91, 0x7F, 0xB9, 0xE6, 0x83, 0xC6, - 0x2D, 0x9F, 0x89, 0x47, 0xB5, 0x8A, 0x29, 0x4D, - 0xA5, 0x06, 0xFB, 0x86, 0xB3, 0xED, 0xF2, 0x5C, - 0xB9, 0xE2, 0xD2, 0xDF, 0x61, 0x1C, 0xD4, 0x48 - }, - { - 0x41, 0xB8, 0x90, 0xF8, 0xE8, 0x45, 0x0D, 0xAD, - 0xB6, 0x95, 0x9A, 0xCC, 0xBA, 0x19, 0x49, 0x17, - 0xE0, 0x2F, 0x30, 0x67, 0x82, 0x1D, 0x4E, 0x99, - 0x5A, 0x37, 0xAC, 0x18, 0xBA, 0x3E, 0x47, 0xC7, - 0x50, 0x6E, 0x7A, 0x3D, 0xD1, 0xE1, 0x12, 0xE6, - 0xEC, 0x41, 0xBE, 0xF5, 0x30, 0x85, 0x11, 0x20, - 0x89, 0x4A, 0x7B, 0x34, 0xB3, 0xDB, 0xCD, 0xAE, - 0x40, 0x73, 0x27, 0xF0, 0xC5, 0x73, 0x6E, 0xDF - }, - { - 0x19, 0xD7, 0x14, 0x4F, 0x0C, 0x85, 0x1E, 0xB8, - 0xB0, 0x53, 0xA3, 0xA4, 0x35, 0x86, 0x52, 0x6D, - 0xC5, 0xC7, 0x73, 0xE4, 0x97, 0x97, 0x51, 0x64, - 0xD1, 0x11, 0x51, 0x36, 0x43, 0x68, 0xDF, 0x24, - 0xBC, 0x44, 0xD5, 0x36, 0x07, 0x23, 0x04, 0xD7, - 0x06, 0x31, 0xA8, 0x40, 0xB6, 0x36, 0xB9, 0x66, - 0xFD, 0x02, 0x8F, 0x61, 0x06, 0x2B, 0xFC, 0x52, - 0x85, 0x67, 0x01, 0x53, 0xA6, 0x36, 0x3A, 0x0A - }, - { - 0xC2, 0x18, 0x4C, 0x1A, 0x81, 0xE9, 0x83, 0xBE, - 0x2C, 0x96, 0xE4, 0xCF, 0xD6, 0x5A, 0xFB, 0xDA, - 0x1A, 0xC6, 0xEF, 0x35, 0x26, 0x6E, 0xE4, 0xB3, - 0xAB, 0x1F, 0xB0, 0x3A, 0xBA, 0xDD, 0xFD, 0xD4, - 0x03, 0xFF, 0xFC, 0xAF, 0xB4, 0xAD, 0xE0, 0xE9, - 0x2D, 0xA3, 0x82, 0xDA, 0x8C, 0x40, 0x22, 0x2E, - 0x10, 0xE9, 0xFD, 0xE8, 0x56, 0xC5, 0x1B, 0xDA, - 0xCD, 0xE7, 0x41, 0xA6, 0x49, 0xF7, 0x33, 0x5D - }, - { - 0x48, 0x8C, 0x0D, 0x65, 0x2E, 0x42, 0xFD, 0x78, - 0xAB, 0x3A, 0x2D, 0xC2, 0x8C, 0xF3, 0xEB, 0x35, - 0xFC, 0xDD, 0xC8, 0xDE, 0xF7, 0xEA, 0xD4, 0x81, - 0x7B, 0xFF, 0xB6, 0x4C, 0x1A, 0xE0, 0xF2, 0x08, - 0xF7, 0x8C, 0xF4, 0x09, 0x76, 0xF7, 0xE2, 0xA2, - 0xCB, 0x2D, 0xD3, 0x0F, 0x1C, 0x99, 0x13, 0x02, - 0x08, 0xCE, 0xB6, 0x92, 0xC6, 0x68, 0x80, 0xD9, - 0x52, 0x8C, 0xD6, 0xD3, 0x8A, 0xD2, 0x9D, 0xB2 - }, - { - 0x51, 0x5B, 0x65, 0xBF, 0x65, 0x68, 0x83, 0x99, - 0x57, 0x5F, 0x0E, 0x06, 0x77, 0xBB, 0x6A, 0x91, - 0x9B, 0x66, 0x33, 0x55, 0x46, 0xD6, 0xCA, 0xE3, - 0x36, 0xF5, 0xC6, 0xFE, 0xAE, 0x5E, 0x2B, 0xF7, - 0x45, 0xE3, 0xA7, 0xB1, 0x3C, 0x32, 0x05, 0xDD, - 0x8B, 0x5B, 0x92, 0xCF, 0x05, 0x3B, 0xE9, 0x69, - 0xDF, 0x71, 0x20, 0xFC, 0xEF, 0x77, 0xE3, 0x89, - 0x5F, 0x56, 0x0F, 0xD2, 0x32, 0xFB, 0x89, 0x50 - }, - { - 0x3F, 0xDB, 0xC7, 0xD6, 0x9F, 0x4B, 0x53, 0xC2, - 0x25, 0x66, 0x3D, 0xA3, 0x0D, 0x80, 0xF7, 0x2E, - 0x54, 0x28, 0x10, 0x44, 0xA2, 0x2B, 0x98, 0x82, - 0xC6, 0x63, 0x8F, 0x55, 0x26, 0x83, 0x4B, 0xD3, - 0x16, 0x01, 0xCA, 0x5E, 0xB2, 0xCC, 0xA4, 0xF5, - 0xFF, 0xCF, 0x67, 0x5D, 0xCB, 0xCF, 0xCA, 0x60, - 0xC8, 0xA3, 0x61, 0x2D, 0x1A, 0xA9, 0xDA, 0xB6, - 0x93, 0xB2, 0x35, 0x60, 0x69, 0x60, 0x3A, 0x0E - }, - { - 0x4F, 0xF6, 0xC3, 0x1A, 0x8F, 0xC0, 0x01, 0xAC, - 0x3B, 0x7A, 0xE0, 0x20, 0xC5, 0xF7, 0xC4, 0x5E, - 0xFB, 0x62, 0x71, 0xA2, 0xD7, 0xCC, 0xAB, 0x87, - 0x13, 0xE5, 0x48, 0xB7, 0x29, 0xF0, 0xFF, 0xF9, - 0xC8, 0x2F, 0xD4, 0xDB, 0x5C, 0xF6, 0x56, 0x43, - 0xD4, 0x07, 0x6A, 0x3F, 0xB1, 0x7B, 0x3E, 0x89, - 0x3C, 0x30, 0x2D, 0xC7, 0x5B, 0x61, 0x22, 0xFF, - 0x86, 0x81, 0xD0, 0x37, 0x12, 0x0E, 0x27, 0x6A - }, - { - 0x43, 0xDF, 0xF2, 0x60, 0xDF, 0xEF, 0x1C, 0xB2, - 0xD6, 0x16, 0x00, 0xE2, 0x40, 0xAA, 0xD6, 0xB7, - 0x20, 0xE5, 0xF4, 0xF8, 0x30, 0x86, 0xE2, 0x6A, - 0x49, 0xA0, 0xCE, 0x3E, 0x0C, 0xA4, 0x4B, 0x9A, - 0x60, 0xFC, 0xF4, 0x6A, 0x8C, 0x3F, 0x1B, 0xB1, - 0xA6, 0xF5, 0x76, 0x2B, 0x66, 0x51, 0x3F, 0xE3, - 0xF7, 0xC5, 0xB0, 0xBC, 0x15, 0x0C, 0x08, 0x49, - 0x1A, 0xCB, 0xC4, 0x36, 0x1C, 0xAB, 0xCF, 0xDF - }, - { - 0xB4, 0xDE, 0xA9, 0x4C, 0x9D, 0x36, 0x75, 0xBE, - 0x05, 0x12, 0xEF, 0xDE, 0xA8, 0x16, 0x38, 0x70, - 0xFE, 0x34, 0x25, 0xDC, 0xD7, 0x61, 0xF3, 0x63, - 0xC4, 0x3A, 0x0C, 0xA5, 0x71, 0x6B, 0x76, 0x54, - 0x06, 0x63, 0xFB, 0x2B, 0xE4, 0x9E, 0x2D, 0xB1, - 0x06, 0x48, 0x5C, 0x9C, 0xDD, 0x3C, 0x16, 0x48, - 0x98, 0xA9, 0x54, 0xB5, 0x87, 0x48, 0xC4, 0x2F, - 0xEA, 0x16, 0xA4, 0x0F, 0xC4, 0x53, 0xD2, 0x10 - }, - { - 0xE5, 0x27, 0x7B, 0x6F, 0x93, 0xEA, 0x1D, 0xE3, - 0xE2, 0xD9, 0xFC, 0xD8, 0xC6, 0x79, 0x79, 0x3C, - 0x6C, 0xCB, 0x8A, 0x3B, 0xE2, 0x6E, 0x8E, 0x31, - 0x14, 0xF3, 0x5D, 0xA4, 0xF2, 0xAC, 0x01, 0x4F, - 0x55, 0xC2, 0xF1, 0x5E, 0x09, 0xE9, 0x4A, 0xA0, - 0x71, 0x29, 0x81, 0x67, 0xA2, 0xFB, 0x9B, 0xE3, - 0x11, 0x70, 0x1F, 0xFB, 0xA9, 0xD3, 0xEE, 0xFF, - 0x8F, 0xFC, 0x79, 0x93, 0xA3, 0xCE, 0xCE, 0x18 - }, - { - 0xF0, 0x95, 0xA7, 0xC6, 0xE2, 0xB9, 0x16, 0x64, - 0x73, 0x4F, 0x3E, 0x23, 0xF1, 0x8E, 0xB2, 0xBA, - 0x9B, 0x00, 0xE7, 0x1F, 0xBF, 0xCB, 0x99, 0x31, - 0xC0, 0xA6, 0x14, 0x79, 0x2A, 0x9D, 0x86, 0x75, - 0x62, 0x2A, 0x87, 0x4C, 0x1B, 0xF5, 0x24, 0x1A, - 0x2A, 0x87, 0x41, 0xED, 0x1C, 0x89, 0x3B, 0xDF, - 0xA8, 0xE2, 0x8C, 0x2E, 0x20, 0xBB, 0x1C, 0x58, - 0xEB, 0x4D, 0xE7, 0xD8, 0x01, 0x11, 0x6C, 0x78 - }, - { - 0xDF, 0xA1, 0xFD, 0x80, 0x3A, 0x1D, 0x4A, 0x3E, - 0x66, 0x1D, 0xF0, 0x1F, 0x49, 0x43, 0xEA, 0x66, - 0x26, 0x0A, 0x18, 0xFE, 0xCE, 0x13, 0x4D, 0x62, - 0xF9, 0x7D, 0xAC, 0xDB, 0x8B, 0x3B, 0xF9, 0xC8, - 0x00, 0xAF, 0xE5, 0x79, 0xCF, 0xD1, 0x3F, 0xC0, - 0x14, 0x8B, 0xDE, 0xFB, 0xFF, 0x4E, 0x76, 0x83, - 0x56, 0x1C, 0x06, 0xA6, 0xF7, 0x22, 0x5E, 0x47, - 0x81, 0x99, 0x3B, 0x4F, 0x4F, 0x2B, 0xCB, 0xFA - }, - { - 0x2B, 0x86, 0xCE, 0xB2, 0x70, 0xF6, 0x90, 0x8D, - 0x8B, 0x16, 0x00, 0x75, 0xEA, 0x7F, 0x57, 0x16, - 0x3A, 0xF5, 0xD5, 0xC6, 0xF8, 0xAA, 0xC5, 0x20, - 0x40, 0xCC, 0x68, 0x7C, 0x17, 0xAB, 0xF3, 0xC7, - 0x78, 0xC1, 0x39, 0x06, 0xE0, 0xE6, 0xF2, 0x9A, - 0x6A, 0xB1, 0x23, 0xDE, 0xEB, 0xCE, 0x39, 0x1F, - 0x90, 0x7D, 0x75, 0xD3, 0xA2, 0xCE, 0xFA, 0x0E, - 0xFC, 0xB8, 0x80, 0xA0, 0xE7, 0x0D, 0x71, 0x96 - }, - { - 0x32, 0x46, 0x6B, 0xCB, 0xDE, 0xD5, 0x38, 0xE5, - 0x68, 0x79, 0x54, 0x30, 0x35, 0x25, 0x36, 0xFE, - 0xB9, 0x19, 0xBF, 0x4D, 0x97, 0xCC, 0x44, 0xAB, - 0x1D, 0x80, 0x50, 0x40, 0xF4, 0xBC, 0x4C, 0x2E, - 0x79, 0x52, 0x72, 0x10, 0x18, 0x95, 0x8B, 0x4E, - 0xE7, 0x83, 0x03, 0x59, 0x0E, 0xF6, 0xAC, 0x45, - 0x0D, 0xF9, 0x2E, 0xC7, 0x7F, 0x47, 0x70, 0x54, - 0xBF, 0xF8, 0x67, 0xB8, 0x89, 0x71, 0xD4, 0x21 - }, - { - 0xEA, 0x64, 0xB0, 0x03, 0xA1, 0x35, 0x76, 0x61, - 0x21, 0xCF, 0xBC, 0xCB, 0xDC, 0x08, 0xDC, 0xA2, - 0x40, 0x29, 0x26, 0xBE, 0x78, 0xCE, 0xA3, 0xD0, - 0xA7, 0x25, 0x3D, 0x9E, 0xC9, 0xE6, 0x3B, 0x8A, - 0xCD, 0xD9, 0x94, 0x55, 0x99, 0x17, 0xE0, 0xE0, - 0x3B, 0x5E, 0x15, 0x5F, 0x94, 0x4D, 0x71, 0x98, - 0xD9, 0x92, 0x45, 0xA7, 0x94, 0xCE, 0x19, 0xC9, - 0xB4, 0xDF, 0x4D, 0xA4, 0xA3, 0x39, 0x93, 0x34 - }, - { - 0x05, 0xAD, 0x0F, 0x27, 0x1F, 0xAF, 0x7E, 0x36, - 0x13, 0x20, 0x51, 0x84, 0x52, 0x81, 0x3F, 0xF9, - 0xFB, 0x99, 0x76, 0xAC, 0x37, 0x80, 0x50, 0xB6, - 0xEE, 0xFB, 0x05, 0xF7, 0x86, 0x7B, 0x57, 0x7B, - 0x8F, 0x14, 0x47, 0x57, 0x94, 0xCF, 0xF6, 0x1B, - 0x2B, 0xC0, 0x62, 0xD3, 0x46, 0xA7, 0xC6, 0x5C, - 0x6E, 0x00, 0x67, 0xC6, 0x0A, 0x37, 0x4A, 0xF7, - 0x94, 0x0F, 0x10, 0xAA, 0x44, 0x9D, 0x5F, 0xB9 - }, - { - 0xB5, 0x45, 0x88, 0x02, 0x94, 0xAF, 0xA1, 0x53, - 0xF8, 0xB9, 0xF4, 0x9C, 0x73, 0xD9, 0x52, 0xB5, - 0xD1, 0x22, 0x8F, 0x1A, 0x1A, 0xB5, 0xEB, 0xCB, - 0x05, 0xFF, 0x79, 0xE5, 0x60, 0xC0, 0x30, 0xF7, - 0x50, 0x0F, 0xE2, 0x56, 0xA4, 0x0B, 0x6A, 0x0E, - 0x6C, 0xB3, 0xD4, 0x2A, 0xCD, 0x4B, 0x98, 0x59, - 0x5C, 0x5B, 0x51, 0xEA, 0xEC, 0x5A, 0xD6, 0x9C, - 0xD4, 0x0F, 0x1F, 0xC1, 0x6D, 0x2D, 0x5F, 0x50 - }, - { - 0xBB, 0xFB, 0x94, 0x77, 0xEC, 0x6A, 0x9F, 0x0C, - 0x25, 0x40, 0x5A, 0xCD, 0x8A, 0x30, 0xD5, 0xDD, - 0x7C, 0x73, 0x57, 0x1F, 0x1D, 0x1A, 0x6E, 0x8C, - 0xE7, 0x2F, 0x8B, 0x9C, 0x94, 0x1C, 0xF7, 0x79, - 0xB7, 0x64, 0x03, 0xAC, 0x7F, 0x04, 0x50, 0x05, - 0x25, 0x84, 0x39, 0x0A, 0x14, 0xEA, 0xA3, 0x7C, - 0x20, 0xB5, 0xBD, 0xB0, 0x38, 0x10, 0x54, 0xA9, - 0xA4, 0x95, 0x34, 0xF8, 0x14, 0x66, 0xBA, 0x9D - }, - { - 0xC8, 0x28, 0x7E, 0x93, 0x3D, 0x95, 0x04, 0xBF, - 0xFD, 0x7B, 0xE2, 0xAC, 0x02, 0x2B, 0x32, 0xF3, - 0xF4, 0x6D, 0x87, 0xA7, 0xA0, 0xE7, 0x9B, 0xB2, - 0xA1, 0xCB, 0xAA, 0xCC, 0x2E, 0x84, 0xCD, 0x70, - 0x84, 0x5D, 0x0D, 0x42, 0x78, 0x48, 0xA6, 0xD7, - 0x88, 0xD3, 0x96, 0x22, 0xE1, 0x0F, 0x43, 0x42, - 0x23, 0x7E, 0xEF, 0xA6, 0xD3, 0xC0, 0x12, 0xDA, - 0xE9, 0x6C, 0xC8, 0xA6, 0x50, 0xCC, 0x2E, 0x30 - }, - { - 0xC4, 0x59, 0x6F, 0xCB, 0x0A, 0x28, 0xD2, 0x4A, - 0xAD, 0x70, 0xCF, 0x18, 0x53, 0xEC, 0x29, 0xDA, - 0xC0, 0xFB, 0x20, 0x2D, 0x8E, 0xC1, 0x40, 0xDA, - 0x30, 0x00, 0x88, 0xBB, 0x85, 0xB9, 0x2C, 0x30, - 0x29, 0x19, 0x46, 0xAD, 0x30, 0x7C, 0x09, 0x6E, - 0x3B, 0x28, 0x66, 0x33, 0x5C, 0x93, 0x17, 0xAF, - 0xE2, 0x8C, 0xAD, 0xAB, 0x5D, 0x62, 0xC3, 0x54, - 0x32, 0x9C, 0x98, 0xD9, 0x93, 0xC5, 0xBE, 0x1C - }, - { - 0xE8, 0x8C, 0x38, 0xE6, 0x7E, 0x8D, 0x19, 0x83, - 0x58, 0x08, 0x85, 0x46, 0x70, 0x77, 0x9E, 0xCA, - 0x60, 0xBA, 0xD8, 0x54, 0xC5, 0x77, 0x87, 0x90, - 0xA0, 0x72, 0x54, 0xA3, 0x0A, 0x14, 0xAE, 0x82, - 0xB6, 0x1B, 0xB1, 0x69, 0x11, 0xFE, 0x57, 0x77, - 0x1D, 0x19, 0xE9, 0xB7, 0xF5, 0x02, 0x3C, 0x0D, - 0x4E, 0x8A, 0x8D, 0x37, 0x2E, 0x3D, 0x85, 0xE4, - 0x3B, 0x03, 0xE5, 0xE0, 0x0E, 0x6E, 0xBA, 0x4B - }, - { - 0x2D, 0x66, 0x3E, 0x03, 0xE6, 0xF3, 0x55, 0x2C, - 0xCD, 0xFB, 0xA4, 0x96, 0xA1, 0x4C, 0xC6, 0x22, - 0x4C, 0xEB, 0x1E, 0xB6, 0x1A, 0xA2, 0x65, 0xE6, - 0xA7, 0xD4, 0xA2, 0x6E, 0x54, 0x10, 0x61, 0x04, - 0xA9, 0x6E, 0x33, 0x09, 0x59, 0xF9, 0x71, 0x3B, - 0x34, 0x87, 0xC1, 0xB9, 0x49, 0x7C, 0xCF, 0x82, - 0x61, 0x1D, 0xBF, 0xA3, 0x4F, 0xF1, 0x1D, 0x31, - 0x33, 0xB5, 0xB5, 0xD1, 0xF1, 0xE4, 0xF8, 0xD0 - }, - { - 0x70, 0x7D, 0x6A, 0x58, 0x42, 0x1B, 0x8F, 0x7E, - 0x44, 0xFF, 0x1F, 0x83, 0x62, 0xBC, 0x70, 0x0F, - 0x71, 0xEF, 0x7C, 0x39, 0x35, 0xE0, 0x76, 0x4B, - 0xD1, 0x4D, 0x39, 0x0C, 0x1C, 0x72, 0x79, 0x2A, - 0xF9, 0xC2, 0xC0, 0x2F, 0xB7, 0x2A, 0x2B, 0x9D, - 0x9A, 0x07, 0x29, 0xCB, 0x3E, 0x99, 0x62, 0x6C, - 0xF0, 0x34, 0xDF, 0x54, 0xB5, 0x06, 0xB5, 0xB1, - 0x64, 0x64, 0xF4, 0x75, 0x86, 0x4F, 0x25, 0x90 - }, - { - 0x9D, 0x88, 0xF8, 0xBA, 0xA4, 0xEB, 0x0F, 0x9A, - 0xB2, 0x29, 0x2E, 0x49, 0x82, 0xAC, 0x80, 0x44, - 0x53, 0x58, 0x22, 0x7D, 0x7F, 0x9C, 0xE7, 0xA4, - 0xA6, 0x29, 0xF1, 0x80, 0xF7, 0x14, 0x1E, 0x08, - 0xFE, 0x63, 0x55, 0xC6, 0x45, 0x21, 0xA6, 0x9B, - 0xA2, 0xBF, 0xBD, 0x1C, 0x4A, 0x3E, 0xA0, 0x48, - 0xD0, 0xBC, 0x8A, 0xB3, 0x70, 0x1F, 0x30, 0xEA, - 0x83, 0xFB, 0xE0, 0x24, 0x74, 0xD8, 0x92, 0xBF - }, - { - 0x65, 0xEA, 0x4D, 0xB0, 0x4A, 0x75, 0x81, 0xC1, - 0x81, 0x94, 0xA8, 0x92, 0x1A, 0xFD, 0xFA, 0x4F, - 0x8D, 0x9A, 0xF6, 0x29, 0xDE, 0xD2, 0x77, 0x2C, - 0x65, 0x8E, 0x08, 0x48, 0x5F, 0x67, 0xAD, 0x2C, - 0xE2, 0x1A, 0x98, 0xCD, 0x29, 0x3F, 0xF2, 0x8D, - 0x4D, 0xFC, 0xDF, 0x65, 0x8C, 0xDC, 0x7A, 0xE6, - 0x70, 0x27, 0x84, 0x8E, 0x71, 0xCC, 0xC1, 0x15, - 0xA3, 0xFF, 0xBA, 0xC4, 0xFA, 0x61, 0xBB, 0x73 - }, - { - 0x0B, 0x4A, 0x68, 0x92, 0x9E, 0x7F, 0x15, 0xCA, - 0x91, 0xBB, 0x44, 0x39, 0xF2, 0x40, 0x37, 0x02, - 0x03, 0x4C, 0xD4, 0x74, 0x8E, 0x46, 0x92, 0x7A, - 0xBA, 0x95, 0xCB, 0xEF, 0x80, 0x04, 0x8B, 0x25, - 0xA6, 0x75, 0x97, 0x0F, 0xAC, 0x33, 0xC8, 0x74, - 0xAB, 0xD3, 0xD8, 0x3A, 0xA0, 0xF3, 0x7B, 0xE2, - 0x30, 0x83, 0x10, 0xE8, 0xDD, 0x79, 0x4F, 0x81, - 0x92, 0x93, 0x0E, 0xD5, 0x6E, 0x70, 0xA8, 0xE4 - }, - { - 0xC1, 0xC5, 0xD8, 0xAC, 0xFE, 0x3F, 0xDE, 0x67, - 0x4E, 0xDD, 0x36, 0x20, 0x15, 0x7A, 0x8B, 0x6B, - 0x4C, 0x8E, 0x67, 0xC6, 0xA7, 0xA9, 0x72, 0x67, - 0x41, 0xD9, 0xC3, 0x05, 0xE2, 0xA5, 0x2A, 0x87, - 0x97, 0xFD, 0xA0, 0xB2, 0xF1, 0x3A, 0xC7, 0x87, - 0x34, 0xDB, 0x2F, 0x4F, 0xC8, 0x3E, 0xF3, 0x24, - 0x14, 0xD9, 0x31, 0xEB, 0xAE, 0xAE, 0xCD, 0x82, - 0x6D, 0x7C, 0x2B, 0xE2, 0x03, 0xBD, 0xC2, 0xD1 - }, - { - 0x2D, 0xAD, 0xC8, 0xC9, 0xF7, 0x42, 0x5A, 0x01, - 0x14, 0x49, 0x12, 0x87, 0xBD, 0xC6, 0x8E, 0xAE, - 0x4F, 0xB6, 0x19, 0x4D, 0x1A, 0x10, 0x9D, 0xB9, - 0xB6, 0xE8, 0xA2, 0xAC, 0x94, 0xD4, 0xE4, 0x40, - 0x90, 0x99, 0x85, 0xC4, 0x29, 0x1F, 0xE8, 0x9F, - 0xD8, 0x28, 0x1F, 0x8F, 0xCE, 0xF6, 0xF6, 0xBC, - 0x32, 0x55, 0x0E, 0x53, 0xCB, 0x7A, 0x49, 0x42, - 0x89, 0x81, 0xE8, 0xD5, 0x3C, 0xF5, 0xA2, 0x12 - }, - { - 0xE5, 0x55, 0xF2, 0xA5, 0x8A, 0xCA, 0xC5, 0x50, - 0x3F, 0x9E, 0x2D, 0x97, 0xB2, 0x46, 0x87, 0x2B, - 0x4C, 0xA7, 0x8B, 0xD5, 0x6D, 0x47, 0xB7, 0x65, - 0xF0, 0x52, 0xAA, 0xB3, 0xDC, 0x77, 0xDB, 0xE9, - 0x93, 0x93, 0x6F, 0x22, 0x52, 0xF0, 0xAB, 0x2E, - 0x01, 0xFB, 0x08, 0x74, 0x72, 0xCC, 0xB5, 0xA1, - 0x21, 0xDD, 0xFF, 0xDE, 0x53, 0x1D, 0x3D, 0xC4, - 0x02, 0x2A, 0x7D, 0x19, 0x56, 0xCE, 0x0E, 0x20 - }, - { - 0x9B, 0x4E, 0xAE, 0x12, 0x95, 0x00, 0x0A, 0xEA, - 0x79, 0x83, 0xEC, 0x3B, 0xCB, 0x48, 0x57, 0xCC, - 0x71, 0x25, 0xFD, 0x73, 0x06, 0x78, 0x7C, 0x63, - 0x13, 0x24, 0x73, 0xCF, 0xE8, 0xF4, 0xEB, 0x45, - 0x31, 0x8A, 0x60, 0xDA, 0xAD, 0x64, 0x6D, 0x63, - 0xA2, 0x7C, 0x4B, 0x9D, 0x1F, 0x50, 0x73, 0x70, - 0x0A, 0x30, 0x57, 0xDE, 0x22, 0xA7, 0xFD, 0xF0, - 0x9A, 0x87, 0xAA, 0xC6, 0x6E, 0xBE, 0x47, 0x58 - }, - { - 0x96, 0x64, 0xAC, 0xC2, 0xDC, 0x72, 0x98, 0xB9, - 0x86, 0x8D, 0xB4, 0x95, 0xEE, 0xBC, 0x6B, 0x59, - 0x65, 0x7D, 0x13, 0x9A, 0x6A, 0xF0, 0x60, 0xA7, - 0x2F, 0xB6, 0x91, 0x24, 0xBD, 0xD3, 0xA6, 0x59, - 0x18, 0x88, 0xF0, 0x35, 0x4F, 0x70, 0x2B, 0x1B, - 0x88, 0x86, 0x84, 0x41, 0x10, 0x58, 0xA3, 0x75, - 0x9F, 0x7F, 0xD3, 0x7F, 0x06, 0xEA, 0xFB, 0x3B, - 0x58, 0xEC, 0xF2, 0x6F, 0x45, 0x53, 0xBE, 0x27 - }, - { - 0xFC, 0x16, 0xE0, 0x92, 0x5A, 0x35, 0xAA, 0xD4, - 0x7A, 0xD6, 0x95, 0x54, 0xB2, 0x57, 0x96, 0xFC, - 0xF9, 0x26, 0x0C, 0xB5, 0x0E, 0x6C, 0xC3, 0x74, - 0x75, 0x35, 0x55, 0x9E, 0x99, 0xC8, 0x58, 0x81, - 0xC7, 0x58, 0x89, 0xAC, 0x79, 0x3A, 0xB7, 0x8B, - 0x88, 0xB0, 0x5F, 0xB1, 0x60, 0x89, 0x56, 0x55, - 0xE4, 0xD6, 0x63, 0xA2, 0xA0, 0x9B, 0xA9, 0xFA, - 0x61, 0x4A, 0x10, 0xC2, 0x29, 0x47, 0x21, 0x0D - }, - { - 0x22, 0x5E, 0x73, 0x41, 0xF8, 0x57, 0x52, 0x4F, - 0x78, 0x90, 0x37, 0x6C, 0x50, 0xE6, 0x35, 0x4B, - 0x16, 0xC1, 0xCD, 0xFB, 0xF5, 0x8F, 0xE5, 0xF3, - 0xA4, 0x03, 0x94, 0x93, 0xB5, 0xDD, 0x40, 0x8D, - 0x79, 0xD4, 0x8C, 0x56, 0xE1, 0xF8, 0x9B, 0x68, - 0x7F, 0xBE, 0x33, 0x62, 0xA7, 0x7F, 0xA7, 0x5A, - 0x54, 0x37, 0x4B, 0x7A, 0x48, 0x5E, 0x91, 0xB1, - 0x89, 0xAF, 0x2E, 0x2F, 0x74, 0x9E, 0x2A, 0xDB - }, - { - 0xA0, 0x7A, 0x4C, 0x02, 0x3A, 0xC7, 0x04, 0xCE, - 0x7C, 0x09, 0xDD, 0x6C, 0x92, 0xC6, 0xF1, 0x84, - 0xF5, 0x3E, 0x8D, 0xD9, 0x6F, 0xE3, 0xBE, 0x9E, - 0x93, 0xC3, 0x9C, 0x53, 0x44, 0x85, 0xB6, 0x4B, - 0x39, 0xD5, 0xBE, 0x7F, 0x7B, 0x71, 0x70, 0x60, - 0x4D, 0xE7, 0x7C, 0xE5, 0xA4, 0x37, 0xA9, 0x8E, - 0x71, 0x2C, 0xC4, 0x4F, 0x19, 0xE2, 0x1D, 0x41, - 0xF0, 0xE6, 0xE3, 0xEC, 0x1E, 0x00, 0xAC, 0x55 - }, - { - 0x62, 0x85, 0x84, 0x63, 0x58, 0x2D, 0x22, 0xE6, - 0x8E, 0x52, 0x27, 0xBF, 0xBA, 0xB5, 0x40, 0x04, - 0x8F, 0x65, 0xED, 0xD6, 0xA6, 0x75, 0x5F, 0x6F, - 0xAB, 0x53, 0xC0, 0x25, 0xB6, 0x63, 0xCA, 0x37, - 0x7A, 0x0E, 0xD5, 0xEF, 0xD6, 0xAF, 0x16, 0x6C, - 0xA5, 0x5A, 0x9C, 0x73, 0x3F, 0xCA, 0x80, 0x5A, - 0xC4, 0xE4, 0x09, 0xCA, 0x56, 0x17, 0x7A, 0xA7, - 0x49, 0x40, 0xDB, 0x9F, 0x40, 0xC3, 0xB9, 0xFF - }, - { - 0xA1, 0xAC, 0x53, 0x9D, 0x1A, 0xBB, 0xC2, 0xB0, - 0x96, 0xFF, 0xAB, 0x81, 0x3B, 0x64, 0x45, 0x7F, - 0xE6, 0xEB, 0x3B, 0x50, 0xFC, 0xD8, 0x89, 0x53, - 0xD0, 0xCD, 0x9F, 0x65, 0x02, 0xF6, 0x89, 0x62, - 0x0A, 0xD4, 0x42, 0xB5, 0x51, 0x70, 0x90, 0xB5, - 0x0C, 0xFF, 0xB9, 0x58, 0x86, 0x6D, 0x7C, 0x16, - 0x1D, 0x8A, 0x7D, 0x75, 0x60, 0xC8, 0x93, 0xE1, - 0xDE, 0xF6, 0xAE, 0xC4, 0x37, 0xAD, 0x6D, 0x06 - }, - { - 0xB5, 0x86, 0xB7, 0x5D, 0xA7, 0x0F, 0x6C, 0xC0, - 0x62, 0x7E, 0xF3, 0xCF, 0x12, 0x37, 0xC9, 0x4B, - 0x12, 0xD0, 0xF7, 0x4D, 0xCB, 0xA2, 0x6A, 0x9E, - 0x7C, 0x7B, 0xC6, 0xC2, 0x1A, 0x33, 0x53, 0x37, - 0xBF, 0x9F, 0x5B, 0x83, 0x0C, 0x63, 0x24, 0xAF, - 0xA6, 0xEF, 0x64, 0x9E, 0x95, 0xAF, 0x87, 0x90, - 0x87, 0x52, 0x34, 0xC6, 0xE6, 0x61, 0xD3, 0xF5, - 0xE9, 0x8C, 0xA0, 0x12, 0xAE, 0x81, 0x48, 0x8A - }, - { - 0x56, 0x68, 0xA2, 0x98, 0x21, 0x37, 0xCB, 0xC6, - 0x22, 0xEF, 0x8D, 0x06, 0xCF, 0x4E, 0x86, 0x16, - 0x8C, 0xDD, 0x4A, 0x89, 0x9C, 0xD4, 0x46, 0x2A, - 0xF6, 0xC3, 0xD4, 0x15, 0x42, 0x61, 0x56, 0xA5, - 0xD8, 0xDD, 0x67, 0xC9, 0x60, 0x4F, 0x31, 0xB5, - 0x7D, 0x6C, 0x9D, 0x59, 0x72, 0x50, 0x45, 0x7E, - 0x4A, 0xB5, 0x2A, 0x58, 0x11, 0x55, 0x42, 0xAC, - 0xF2, 0x7F, 0x92, 0x59, 0x30, 0xF6, 0xA1, 0x12 - }, - { - 0xF2, 0xB1, 0xBD, 0x16, 0xD8, 0x8E, 0x37, 0xF3, - 0xA5, 0x18, 0xD1, 0x93, 0xED, 0x06, 0x1A, 0x1D, - 0xF7, 0xB4, 0x43, 0xA1, 0x8C, 0xE9, 0xF8, 0x44, - 0x45, 0xEF, 0x86, 0xEF, 0xFB, 0xDF, 0xF1, 0x60, - 0x55, 0x02, 0x3C, 0xD4, 0xE7, 0x8D, 0x03, 0x4D, - 0xE4, 0x03, 0x2A, 0x77, 0xDD, 0xC1, 0xD3, 0x43, - 0x52, 0xFE, 0x61, 0x7F, 0x82, 0x56, 0x24, 0x45, - 0x9B, 0xC3, 0x26, 0x9F, 0x70, 0x4F, 0x34, 0x5B - }, - { - 0xF0, 0x85, 0xF3, 0xD8, 0xBD, 0x13, 0x8E, 0x05, - 0x69, 0x24, 0x3F, 0x74, 0x52, 0x3E, 0x87, 0xFF, - 0x37, 0x6F, 0x04, 0xEA, 0xBD, 0x5A, 0x2F, 0x6E, - 0x53, 0xDF, 0x38, 0x99, 0x00, 0x0E, 0x2E, 0x94, - 0xAF, 0x0D, 0x2B, 0xC7, 0x1C, 0x3F, 0x71, 0x10, - 0x25, 0xC5, 0x38, 0xA6, 0xC8, 0xB1, 0x0B, 0x09, - 0x04, 0xDF, 0xC3, 0x46, 0xAD, 0xAD, 0x7E, 0xF3, - 0x6B, 0x1A, 0xE8, 0x8A, 0x6C, 0xFE, 0xAB, 0xBD - }, - { - 0x82, 0x91, 0xA4, 0xAF, 0xD2, 0xE4, 0xB7, 0x16, - 0x61, 0x77, 0x3A, 0x46, 0xB3, 0xD4, 0x45, 0x5A, - 0x8D, 0x33, 0xA7, 0x26, 0xD9, 0xD3, 0x87, 0x30, - 0x83, 0xAB, 0x33, 0x70, 0x20, 0xC2, 0x7B, 0x4D, - 0xD6, 0x43, 0xE2, 0x8C, 0x2F, 0xE4, 0x7A, 0xB2, - 0xFB, 0xF5, 0xD1, 0x40, 0x81, 0xA3, 0xFC, 0x1C, - 0x83, 0x9B, 0x12, 0xEA, 0x31, 0xD1, 0x3C, 0xF4, - 0x9E, 0xEE, 0x97, 0xEF, 0x2E, 0xD7, 0xFA, 0x3E - }, - { - 0xB1, 0x26, 0xAE, 0x46, 0xA7, 0xA4, 0x59, 0x5E, - 0x31, 0x60, 0x7E, 0xF8, 0x07, 0xA5, 0x60, 0x1F, - 0x4E, 0xCD, 0x9E, 0x7D, 0x66, 0xC8, 0x2D, 0xAE, - 0xB9, 0x71, 0x5F, 0x8D, 0xA1, 0xC1, 0x7D, 0x7D, - 0x71, 0xC3, 0xE6, 0x82, 0x50, 0xC9, 0xDC, 0x01, - 0xAC, 0x40, 0xA3, 0x6D, 0x2E, 0x63, 0x8B, 0xEF, - 0x3D, 0x7B, 0xC7, 0x0E, 0xA2, 0xD0, 0xE3, 0x31, - 0xE3, 0xD3, 0x3E, 0x17, 0x04, 0xEB, 0xA9, 0x2D - }, - { - 0x63, 0xB1, 0x4D, 0x8E, 0xD2, 0x47, 0x9C, 0xAA, - 0x17, 0xC3, 0xE4, 0xCF, 0x20, 0x3B, 0x23, 0x3A, - 0x7E, 0x37, 0x3E, 0xDB, 0x0C, 0x2F, 0x19, 0x71, - 0x29, 0xA9, 0xA3, 0x6C, 0x5B, 0x3E, 0x1F, 0x38, - 0x38, 0xF2, 0xE8, 0x2A, 0xC2, 0xC2, 0xAD, 0x9D, - 0x52, 0xB3, 0x35, 0x79, 0x0B, 0xFF, 0x57, 0x73, - 0x04, 0xA3, 0x78, 0xE3, 0x8E, 0xB6, 0xBB, 0x41, - 0x62, 0x03, 0x0C, 0xE2, 0xA8, 0xBA, 0x29, 0x3C - }, - { - 0x34, 0x42, 0x2A, 0x32, 0x29, 0x66, 0x99, 0x28, - 0xC4, 0x90, 0xF5, 0x7B, 0x8E, 0x76, 0x88, 0x52, - 0xE5, 0xB7, 0xC0, 0x0D, 0xCA, 0xD6, 0x0B, 0x01, - 0x2A, 0x5D, 0xB3, 0x9A, 0x2D, 0x59, 0x7C, 0x3D, - 0x0A, 0x63, 0xBE, 0x6A, 0x26, 0x3E, 0xA5, 0x36, - 0x08, 0xB7, 0x06, 0x92, 0xD7, 0x8E, 0x1B, 0x42, - 0x7E, 0xAC, 0xEC, 0x01, 0xF4, 0xBE, 0xE0, 0xBD, - 0xBB, 0x8F, 0x08, 0x81, 0x48, 0x8E, 0xFC, 0x28 - }, - { - 0xE2, 0x6B, 0x7E, 0xD6, 0xB9, 0x07, 0xB5, 0x4C, - 0xA2, 0x65, 0x67, 0xF1, 0x1E, 0xE5, 0xBB, 0x6D, - 0x73, 0x9A, 0x00, 0x08, 0xA5, 0x34, 0x37, 0xAD, - 0x75, 0x90, 0xA3, 0x13, 0x4C, 0xEB, 0x95, 0x19, - 0x6E, 0x49, 0xB3, 0x44, 0x3F, 0x32, 0x49, 0x22, - 0x51, 0x75, 0x23, 0xC0, 0xCD, 0x5A, 0x00, 0xD7, - 0x7E, 0x4C, 0x4D, 0xE7, 0xA0, 0xDE, 0x96, 0x8A, - 0x84, 0xFB, 0x1B, 0x3B, 0xE7, 0xB3, 0xB9, 0x63 - }, - { - 0x26, 0x01, 0x97, 0xCA, 0xFB, 0xF4, 0x56, 0xB4, - 0x11, 0xFA, 0x26, 0xD3, 0x83, 0xD6, 0x4D, 0x61, - 0xE8, 0x1E, 0x5E, 0x52, 0xF8, 0x4C, 0xD9, 0xD5, - 0x73, 0x86, 0xC7, 0x76, 0x23, 0x0C, 0x65, 0xA2, - 0x68, 0x1C, 0xD2, 0xFD, 0xFD, 0x28, 0x67, 0x9F, - 0x67, 0xFE, 0x1B, 0xD7, 0x46, 0x9C, 0xF7, 0x26, - 0x95, 0x85, 0xFC, 0xCB, 0xAE, 0xCC, 0x22, 0xF5, - 0x03, 0xD6, 0xE3, 0xFC, 0x39, 0x30, 0x14, 0x36 - }, - { - 0xCB, 0xD5, 0xAB, 0xE3, 0x7B, 0xCC, 0x4F, 0x9A, - 0x12, 0x70, 0xAD, 0xD0, 0xA5, 0x27, 0x0F, 0x42, - 0x83, 0x9C, 0x7D, 0x24, 0x93, 0x20, 0xD1, 0xF1, - 0xD8, 0x85, 0x53, 0xD0, 0x5F, 0xAF, 0x9A, 0x26, - 0x79, 0xF4, 0x9B, 0x49, 0xC9, 0xE2, 0x0C, 0x1C, - 0x85, 0xC6, 0x29, 0xAA, 0x0F, 0x09, 0x0C, 0xAE, - 0x8F, 0x6E, 0x32, 0xC6, 0xCA, 0xD7, 0x17, 0x21, - 0xFD, 0x06, 0x23, 0xE4, 0xED, 0x25, 0xB2, 0x56 - }, - { - 0x78, 0x0E, 0x31, 0x4F, 0xD6, 0x97, 0xD2, 0xA9, - 0x7D, 0x22, 0x1A, 0x22, 0xC3, 0x90, 0x11, 0xE2, - 0x50, 0x69, 0x16, 0x3C, 0xD0, 0x8F, 0x00, 0x70, - 0xD0, 0x67, 0xE8, 0xCD, 0xB0, 0xBC, 0x86, 0x73, - 0xFD, 0xB0, 0xEC, 0x4F, 0x46, 0xE3, 0x1D, 0x74, - 0x8C, 0xD3, 0xBB, 0x3D, 0x61, 0xB9, 0x01, 0x0A, - 0x66, 0x12, 0xF3, 0x41, 0xD4, 0x71, 0xD9, 0xC5, - 0xA2, 0xDE, 0x6B, 0x6D, 0xD5, 0x38, 0xA6, 0xB5 - }, - { - 0x40, 0x8F, 0x16, 0xCE, 0x86, 0xF8, 0x01, 0xD0, - 0x8B, 0xD0, 0x51, 0x36, 0x4B, 0x3E, 0xCD, 0x9A, - 0x39, 0x45, 0x71, 0x58, 0x88, 0xDF, 0x46, 0x63, - 0x21, 0x9A, 0x19, 0x0B, 0x35, 0x04, 0xE4, 0x61, - 0x8E, 0x7B, 0xF5, 0x51, 0x71, 0x17, 0x8B, 0x04, - 0x00, 0xFB, 0xEB, 0xFA, 0xA0, 0x1F, 0x6E, 0xEA, - 0xB5, 0x4F, 0xF5, 0xE3, 0x1E, 0x6D, 0x7A, 0x55, - 0xB8, 0x4A, 0xDB, 0x9E, 0x03, 0xDF, 0x48, 0x36 - }, - { - 0x0B, 0xF9, 0x88, 0x69, 0xEC, 0x05, 0x80, 0x19, - 0x9C, 0xA3, 0x70, 0x8E, 0xC9, 0xC4, 0x2C, 0x37, - 0x6C, 0x5C, 0x36, 0xE0, 0xFB, 0x74, 0x92, 0x42, - 0x57, 0x23, 0x98, 0xA0, 0xDA, 0x57, 0xF9, 0x8D, - 0x1C, 0x4C, 0xD2, 0x96, 0x3B, 0x37, 0xC3, 0xC6, - 0x5A, 0x10, 0xF1, 0x06, 0xB5, 0x6D, 0xCB, 0x96, - 0xDC, 0xDD, 0x32, 0x57, 0x96, 0x29, 0x7A, 0xDB, - 0xF6, 0xEE, 0x62, 0x70, 0xED, 0xD4, 0x59, 0x2A - }, - { - 0x05, 0x2C, 0x32, 0x98, 0x43, 0x87, 0xB1, 0x93, - 0x0D, 0x3A, 0x96, 0xBE, 0x72, 0x36, 0x85, 0x35, - 0x44, 0x4F, 0x13, 0x07, 0x57, 0xBF, 0x87, 0xE0, - 0x76, 0x2D, 0x8B, 0x1C, 0x4F, 0x65, 0x70, 0xF4, - 0xDC, 0x67, 0x4C, 0x4E, 0x6F, 0x5E, 0x21, 0xAB, - 0xD0, 0xB3, 0x5E, 0x1C, 0xA1, 0x9D, 0xB8, 0x40, - 0x68, 0x8D, 0x1B, 0x6E, 0x9E, 0xC9, 0x1F, 0x37, - 0x30, 0xE8, 0xB2, 0x88, 0x0E, 0xC2, 0xC3, 0xDF - }, - { - 0x4B, 0xB7, 0x14, 0x09, 0xC1, 0x5A, 0x0D, 0x39, - 0x32, 0xC5, 0x99, 0xEF, 0x0F, 0xF3, 0xEF, 0xF5, - 0xC7, 0x60, 0x2D, 0x70, 0x00, 0xCD, 0xA9, 0x74, - 0x08, 0x2C, 0x4A, 0x46, 0x82, 0x24, 0x9A, 0x19, - 0xD4, 0x3A, 0x5C, 0x14, 0xE0, 0xAE, 0xEF, 0x89, - 0x78, 0x21, 0x05, 0x63, 0x80, 0xAF, 0xF2, 0x75, - 0x20, 0x1D, 0x74, 0x59, 0x14, 0x84, 0x96, 0xEA, - 0xE9, 0x42, 0x0E, 0x71, 0x82, 0x88, 0xB4, 0x14 - }, - { - 0x47, 0x95, 0xB2, 0x51, 0xCC, 0x7B, 0x35, 0xE6, - 0x96, 0x92, 0xDB, 0x7F, 0xB4, 0x0E, 0xFD, 0x34, - 0xF2, 0x94, 0xF5, 0x1A, 0xEC, 0x15, 0xD6, 0xC8, - 0x67, 0x3E, 0x59, 0xF2, 0x04, 0xBE, 0xCF, 0x4C, - 0xF9, 0xDF, 0x84, 0x95, 0x23, 0xF1, 0xDB, 0x73, - 0xBE, 0x2A, 0x66, 0xC8, 0x39, 0xD8, 0x01, 0x97, - 0x4D, 0x43, 0x3B, 0x47, 0x80, 0x67, 0x01, 0xA1, - 0x63, 0xA7, 0x94, 0xB2, 0x6A, 0x84, 0x6B, 0x06 - }, - { - 0xDD, 0x50, 0xF9, 0x65, 0xB6, 0x0B, 0xAF, 0x16, - 0x8F, 0x5E, 0xA0, 0x5A, 0xC2, 0x0B, 0x8A, 0x78, - 0xF4, 0x47, 0x5C, 0x18, 0x61, 0x0B, 0x9D, 0x9F, - 0xC2, 0xB7, 0xC3, 0xAD, 0x5C, 0x6F, 0x97, 0xA4, - 0xCF, 0x5E, 0xA4, 0x8E, 0xE4, 0x0A, 0x3C, 0xA2, - 0x29, 0x3C, 0xC4, 0x21, 0x40, 0x82, 0xCF, 0x0F, - 0x8E, 0xC8, 0x95, 0x55, 0x32, 0x69, 0xE1, 0x4D, - 0xA9, 0xBD, 0x1A, 0x19, 0x65, 0x62, 0xCA, 0x59 - }, - { - 0xE0, 0xB5, 0x4B, 0x61, 0x7F, 0x44, 0x92, 0x2C, - 0x7F, 0x61, 0xC6, 0xA5, 0x4C, 0x98, 0xC6, 0x1E, - 0x93, 0x2D, 0xED, 0x1F, 0xA9, 0x34, 0x02, 0x66, - 0xEE, 0xA2, 0x5F, 0x01, 0xE8, 0x18, 0x0D, 0x1D, - 0xDC, 0x6A, 0xD8, 0xDD, 0x6A, 0x0B, 0x8F, 0xAB, - 0x8C, 0x73, 0xAE, 0xBB, 0x97, 0x73, 0x17, 0x1B, - 0xBA, 0x04, 0xA7, 0x81, 0xB1, 0x13, 0x14, 0xD5, - 0xA3, 0x0A, 0x9D, 0x1C, 0x28, 0x12, 0xCA, 0x7C - }, - { - 0x2D, 0xC4, 0xAD, 0x06, 0x89, 0xA4, 0x46, 0x0B, - 0x5B, 0x39, 0x9E, 0x91, 0x1B, 0xDB, 0x41, 0x58, - 0x6A, 0xC8, 0xAD, 0x36, 0x7B, 0x7A, 0xA3, 0x9E, - 0x3E, 0xAE, 0xC8, 0x89, 0x9A, 0x2D, 0x3C, 0xE3, - 0x8E, 0x34, 0xAB, 0x46, 0x08, 0x23, 0x4D, 0x75, - 0xEB, 0x67, 0x37, 0xFE, 0x21, 0x58, 0x24, 0xC2, - 0xA9, 0x78, 0x83, 0x59, 0x6F, 0x6F, 0x18, 0xDD, - 0xEB, 0xBF, 0x16, 0x27, 0xDE, 0xD9, 0x1D, 0x84 - }, - { - 0xF5, 0x6A, 0x11, 0xCB, 0xBF, 0x8A, 0x99, 0x7E, - 0x14, 0x77, 0xEC, 0x76, 0xE5, 0x3C, 0x89, 0x4B, - 0x14, 0x8D, 0x69, 0x25, 0xA4, 0x33, 0x6F, 0x0C, - 0xB7, 0xAA, 0xB9, 0xD8, 0x02, 0xAC, 0x9B, 0x45, - 0x36, 0xF4, 0x80, 0x10, 0x1F, 0x3F, 0x9A, 0x77, - 0xEE, 0xCD, 0xCB, 0xAE, 0x7A, 0xA6, 0xEA, 0x44, - 0x7A, 0x85, 0xDA, 0x90, 0xB5, 0x01, 0xF7, 0xDB, - 0x2E, 0xF8, 0xDD, 0xF5, 0xDE, 0x17, 0x33, 0x63 - }, - { - 0x6E, 0x17, 0x1D, 0x19, 0x6D, 0x0F, 0xC8, 0x2F, - 0xB4, 0x73, 0xE2, 0x9D, 0xA8, 0xF4, 0x0F, 0x37, - 0xEE, 0x97, 0x41, 0xAC, 0x3E, 0xAF, 0x17, 0x5D, - 0xD4, 0x9F, 0xDB, 0x56, 0x53, 0x0D, 0xB5, 0x98, - 0x98, 0xBA, 0xF3, 0xCE, 0xE7, 0x2E, 0xEF, 0x5E, - 0x77, 0x27, 0x6C, 0xAD, 0xAB, 0xCD, 0x75, 0x2C, - 0xA3, 0xA1, 0xB8, 0x64, 0xC1, 0x0A, 0xD2, 0x8D, - 0x27, 0xEA, 0xAD, 0x86, 0xE3, 0xF2, 0x1D, 0x33 - }, - { - 0x95, 0x20, 0x12, 0x33, 0x0D, 0x92, 0xBB, 0x9C, - 0x18, 0x92, 0xF2, 0x5B, 0x7B, 0x5A, 0xA0, 0xFE, - 0xD3, 0xC0, 0x39, 0x8A, 0x17, 0x08, 0x50, 0x9A, - 0x66, 0x14, 0x74, 0xA3, 0xF5, 0xE5, 0x11, 0xD0, - 0x9F, 0x21, 0xC3, 0x00, 0x08, 0x00, 0x2F, 0x10, - 0x42, 0xD8, 0x3D, 0x2F, 0x7B, 0x11, 0x33, 0x6B, - 0x8C, 0x2F, 0xE1, 0xD9, 0x79, 0xC1, 0xE3, 0x86, - 0xE0, 0x20, 0x97, 0x48, 0x9B, 0x2D, 0xFC, 0xF5 - }, - { - 0x2D, 0xCE, 0x47, 0xC3, 0x3A, 0x7E, 0x7F, 0x21, - 0x5D, 0x34, 0xA5, 0x47, 0x1B, 0xCD, 0x11, 0x10, - 0x60, 0x6C, 0x77, 0x13, 0x8F, 0x19, 0xD4, 0x17, - 0x41, 0xED, 0x5D, 0x1B, 0x89, 0xE8, 0xF7, 0xC7, - 0x74, 0xEE, 0xC4, 0xBB, 0xC1, 0x02, 0x76, 0x6E, - 0xA1, 0x53, 0x2F, 0x2E, 0x43, 0x13, 0x4A, 0xD3, - 0x66, 0xBD, 0xCC, 0x27, 0xD1, 0xA0, 0xCC, 0x95, - 0x9E, 0x16, 0x48, 0x65, 0x9E, 0x44, 0xCB, 0xBE - }, - { - 0x7F, 0x06, 0x59, 0x59, 0x7E, 0x7A, 0xD1, 0x22, - 0xD1, 0xC9, 0xED, 0x91, 0x93, 0x0B, 0x07, 0xDE, - 0x40, 0xE2, 0x55, 0x20, 0x1A, 0x33, 0xEB, 0x2B, - 0x31, 0x81, 0x37, 0x6E, 0x36, 0x8D, 0xF7, 0x76, - 0x4C, 0x0C, 0x14, 0xBF, 0x79, 0x9F, 0x16, 0x1B, - 0x9B, 0x00, 0x79, 0x57, 0x8B, 0x47, 0x09, 0x71, - 0x3E, 0x24, 0xE4, 0x2F, 0xE7, 0xDD, 0x71, 0xB5, - 0x09, 0x43, 0xF4, 0x40, 0xE2, 0x3C, 0xD1, 0xBE - }, - { - 0x1E, 0x66, 0xF7, 0xB3, 0x58, 0x80, 0x5D, 0xDD, - 0xFF, 0xC5, 0x82, 0x68, 0x3E, 0x0B, 0xAD, 0x81, - 0x8C, 0x87, 0x34, 0x03, 0xD4, 0xBA, 0x15, 0x06, - 0xB9, 0x2F, 0xB3, 0x20, 0xCA, 0x8C, 0xF9, 0xCE, - 0xE8, 0x15, 0x47, 0x15, 0xD6, 0xDB, 0x6F, 0x04, - 0x09, 0x3D, 0x4B, 0x3F, 0xD8, 0xA6, 0xFC, 0x8E, - 0x7E, 0xDD, 0xEA, 0xF2, 0x79, 0x5B, 0x3D, 0x22, - 0xDE, 0x7C, 0x75, 0xEC, 0xFF, 0x6F, 0x92, 0xAF - }, - { - 0x1F, 0x60, 0xC1, 0x8D, 0xB1, 0x68, 0xD9, 0x0D, - 0x2B, 0x46, 0x60, 0xE7, 0x58, 0xA3, 0xCD, 0x28, - 0x02, 0x3D, 0x4C, 0x0B, 0x84, 0x8B, 0x5E, 0x33, - 0xEA, 0x5C, 0xC1, 0x56, 0x29, 0xFD, 0x35, 0x2E, - 0xAC, 0xB1, 0x4F, 0x05, 0xFD, 0xEC, 0x07, 0xAC, - 0x23, 0xDA, 0x92, 0x04, 0x74, 0x5F, 0xA9, 0x73, - 0xC3, 0x29, 0x55, 0x13, 0x5F, 0x8E, 0xC7, 0x41, - 0x0A, 0x1C, 0xB5, 0x3B, 0xC7, 0x58, 0x06, 0x84 - }, - { - 0xB9, 0xDF, 0x57, 0xB3, 0x45, 0xEE, 0x6F, 0x87, - 0x0E, 0xE0, 0xE6, 0x3C, 0x55, 0x8B, 0x81, 0xC1, - 0xBC, 0x38, 0x42, 0x97, 0x6F, 0xD3, 0xCF, 0xB1, - 0xB5, 0x3B, 0x76, 0x6B, 0xF4, 0x36, 0xD1, 0xD1, - 0x75, 0xF4, 0xD4, 0xC5, 0xF1, 0xBD, 0x8D, 0x7A, - 0xF6, 0x5B, 0x5D, 0x18, 0xA7, 0x2F, 0x95, 0x71, - 0xF2, 0x34, 0x70, 0x19, 0x32, 0xAF, 0xB7, 0xC3, - 0xC9, 0x4A, 0x8C, 0x8F, 0xA0, 0x23, 0xDB, 0x4F - }, - { - 0xD8, 0xC8, 0x24, 0x95, 0xA2, 0xB5, 0xF6, 0x64, - 0x51, 0xF8, 0xC5, 0xB2, 0xE8, 0xA1, 0x73, 0x33, - 0xC2, 0xBE, 0x32, 0x20, 0xCE, 0x06, 0xA8, 0x14, - 0xC2, 0xCE, 0xA9, 0x5C, 0xC8, 0x65, 0x92, 0xAA, - 0x02, 0x15, 0xBF, 0x29, 0x46, 0x14, 0xA3, 0x28, - 0xCF, 0x07, 0x22, 0x2B, 0x73, 0xF9, 0x3F, 0x24, - 0x2A, 0x94, 0x8B, 0xCA, 0xE9, 0x56, 0x5F, 0xC9, - 0x70, 0x57, 0xB5, 0x2E, 0x02, 0x80, 0xEB, 0x82 - }, - { - 0x81, 0x34, 0xCE, 0x66, 0xD9, 0x5C, 0x40, 0x88, - 0xA5, 0x66, 0xD4, 0xE4, 0x35, 0x99, 0x06, 0x9A, - 0xD0, 0x45, 0x53, 0xB0, 0xFE, 0xA3, 0xD7, 0x48, - 0x19, 0xA6, 0xFD, 0x76, 0x6F, 0x43, 0x67, 0x42, - 0xF6, 0xB6, 0xEC, 0xC8, 0x27, 0x93, 0x98, 0x60, - 0x9F, 0x60, 0xB4, 0xE4, 0xBB, 0x44, 0xFD, 0x72, - 0xCD, 0xFB, 0xFF, 0x18, 0xD8, 0x03, 0x8A, 0xA7, - 0x12, 0x30, 0x83, 0x8B, 0x12, 0x6B, 0xC3, 0x00 - }, - { - 0x3D, 0xA8, 0x9F, 0x5C, 0x52, 0xB0, 0x52, 0xE0, - 0x42, 0xE5, 0x11, 0x7B, 0x96, 0x80, 0x6E, 0xDB, - 0x1C, 0x55, 0x22, 0x7E, 0x85, 0x14, 0xB3, 0x9E, - 0x8B, 0x22, 0xBE, 0xA4, 0xC9, 0x53, 0x30, 0x80, - 0xA4, 0xD7, 0xA9, 0x24, 0x92, 0xB7, 0x51, 0x76, - 0x9B, 0x0E, 0x11, 0x9E, 0xF4, 0xDB, 0x2B, 0xB8, - 0x8D, 0x5C, 0x1E, 0x75, 0xB4, 0x03, 0x10, 0x74, - 0xD7, 0xF2, 0x1A, 0x78, 0x01, 0x4A, 0x1F, 0x96 - }, - { - 0x9B, 0xDC, 0xB4, 0x69, 0xC2, 0x66, 0x5D, 0xD8, - 0x46, 0x83, 0xE5, 0x81, 0x01, 0xFD, 0xAE, 0x5C, - 0x88, 0x29, 0x2A, 0x4E, 0x05, 0xC4, 0x00, 0xCA, - 0x08, 0x26, 0xDA, 0x79, 0x38, 0x2B, 0x8A, 0x28, - 0x26, 0xFF, 0x24, 0xFC, 0xD5, 0x56, 0xC9, 0xD5, - 0xB5, 0xAA, 0x89, 0x2F, 0x02, 0xB1, 0x67, 0x04, - 0x77, 0x27, 0x9B, 0xD7, 0x5F, 0x1B, 0x2B, 0x7B, - 0x67, 0x5E, 0xFA, 0xC3, 0x80, 0x60, 0x70, 0x36 - }, - { - 0x6C, 0x77, 0x85, 0x7B, 0x38, 0x53, 0x3E, 0x41, - 0x4A, 0xF7, 0x38, 0x7C, 0x98, 0x56, 0x8D, 0x71, - 0xC8, 0xF0, 0xE3, 0x5E, 0x22, 0xB0, 0x2E, 0x2A, - 0x1C, 0x0D, 0xC6, 0xD5, 0x7E, 0x37, 0xD8, 0x68, - 0x72, 0x5A, 0xD8, 0x23, 0x58, 0x6A, 0x0B, 0xEE, - 0xF3, 0x98, 0x89, 0xCC, 0x31, 0xF1, 0xF7, 0xFA, - 0xD0, 0x96, 0x0A, 0x12, 0x5E, 0x29, 0xDF, 0xEA, - 0x74, 0x55, 0x12, 0xD1, 0x79, 0xE5, 0xF5, 0x89 - }, - { - 0x88, 0xC9, 0x83, 0x3A, 0x6D, 0x44, 0xFC, 0x25, - 0xBB, 0x64, 0xF3, 0xE9, 0x8E, 0x83, 0x8F, 0xB4, - 0xFF, 0x56, 0x48, 0x96, 0xDC, 0xD3, 0x58, 0x3A, - 0x8B, 0x57, 0xC9, 0x46, 0x6E, 0x74, 0x0C, 0x62, - 0x8B, 0x2D, 0x26, 0xEA, 0x14, 0x7C, 0xB3, 0x11, - 0x10, 0xFB, 0xAD, 0xCF, 0x9D, 0x01, 0x08, 0xAC, - 0xCE, 0xBE, 0x04, 0x31, 0x7D, 0x19, 0xFC, 0x03, - 0x66, 0xDE, 0x0C, 0x28, 0xA1, 0xA4, 0x5E, 0x2A - }, - { - 0x0A, 0xAB, 0xB3, 0xA1, 0x78, 0x46, 0x4A, 0x01, - 0x47, 0x64, 0x5F, 0x05, 0x71, 0x2A, 0x0A, 0x15, - 0x55, 0xC5, 0xB9, 0xA3, 0xE9, 0x99, 0xAB, 0x25, - 0x5A, 0xCA, 0x35, 0xC5, 0x03, 0x81, 0xF4, 0x90, - 0x55, 0x1A, 0x40, 0x89, 0x31, 0xAA, 0x6B, 0xE9, - 0xA4, 0xEF, 0x49, 0x7A, 0x16, 0x5B, 0x36, 0x66, - 0x3B, 0x1E, 0x1F, 0x05, 0x13, 0x48, 0x02, 0xB1, - 0x78, 0xB7, 0xC7, 0x04, 0x68, 0xCB, 0x98, 0xE8 - }, - { - 0x58, 0x50, 0xD8, 0x93, 0x70, 0x6B, 0x3B, 0xC2, - 0xDB, 0xBA, 0x9C, 0xFA, 0xB0, 0x28, 0xBE, 0xD8, - 0x19, 0xA2, 0x83, 0x11, 0xD2, 0xD6, 0xF0, 0xCD, - 0x8E, 0x27, 0x2E, 0xE6, 0x77, 0xBC, 0x87, 0x8A, - 0x0C, 0xED, 0x6C, 0x0D, 0xEA, 0x9E, 0x5C, 0xC9, - 0x4B, 0x2B, 0x4F, 0x59, 0x1A, 0x40, 0xEC, 0x9F, - 0xB1, 0x82, 0x22, 0xD6, 0xDE, 0xAC, 0xE1, 0xF9, - 0xC0, 0x83, 0xDC, 0x05, 0xDE, 0x11, 0x7A, 0x53 - }, - { - 0xBE, 0xE6, 0x96, 0xA4, 0x76, 0x4F, 0x94, 0x25, - 0xD9, 0x1B, 0x14, 0x17, 0x38, 0x62, 0x5A, 0x04, - 0x47, 0xA8, 0x22, 0xBB, 0xA7, 0xA8, 0x47, 0x78, - 0xCC, 0x3A, 0x77, 0xA3, 0x86, 0xCB, 0x18, 0x24, - 0x87, 0xDB, 0x51, 0x3B, 0xB8, 0xF3, 0x6F, 0xC2, - 0xF7, 0xE6, 0xD2, 0x89, 0x6E, 0x44, 0x56, 0xA5, - 0x23, 0x46, 0xC4, 0x94, 0x8E, 0x3E, 0xC6, 0x34, - 0xCB, 0xF1, 0x8F, 0x39, 0xC4, 0x46, 0xCB, 0xAB - }, - { - 0x3D, 0x9F, 0x75, 0xD3, 0xE5, 0x0D, 0x9B, 0xA3, - 0xBC, 0xAC, 0x4A, 0x4E, 0x11, 0x6B, 0x9B, 0x30, - 0x8D, 0xC6, 0x45, 0x99, 0xA3, 0x86, 0x4A, 0x9D, - 0xAF, 0xD7, 0x5C, 0xB7, 0x1F, 0x2D, 0xE3, 0x10, - 0x9F, 0x79, 0x56, 0xA7, 0xD2, 0xDD, 0x37, 0x4F, - 0x84, 0x06, 0xD7, 0x7F, 0x79, 0x63, 0x11, 0xE3, - 0xD3, 0x00, 0x89, 0xE5, 0x4D, 0xD6, 0xCE, 0x8A, - 0xBB, 0x02, 0xA8, 0x5A, 0x85, 0xAE, 0x92, 0xE4 - }, - { - 0xEF, 0x39, 0x51, 0x47, 0x5A, 0x16, 0xDF, 0x64, - 0x98, 0x32, 0x24, 0x04, 0x65, 0x30, 0xDC, 0x7C, - 0xB0, 0x53, 0xD2, 0x93, 0x94, 0x75, 0x39, 0x11, - 0xC4, 0x94, 0x99, 0x50, 0xF2, 0x3E, 0x8A, 0x92, - 0xC7, 0x09, 0xF4, 0x63, 0x69, 0xB2, 0x3A, 0x0D, - 0x70, 0x3A, 0x6F, 0x36, 0x49, 0x0F, 0x75, 0xBE, - 0x1E, 0x3E, 0x81, 0x29, 0xA8, 0x29, 0xF3, 0xDC, - 0xD7, 0x2D, 0x0E, 0x55, 0x49, 0x7B, 0x81, 0x33 - }, - { - 0xD4, 0x19, 0x7D, 0x2A, 0x68, 0x5B, 0xCA, 0x6B, - 0xFB, 0xDD, 0x0E, 0x3D, 0x84, 0xC7, 0x48, 0x01, - 0x35, 0x48, 0xBC, 0x84, 0x9F, 0xE6, 0x49, 0xDA, - 0xE7, 0xC4, 0xA2, 0x77, 0xFC, 0xBD, 0x8F, 0x81, - 0x8A, 0x9E, 0xDF, 0xA6, 0xCA, 0x14, 0xD7, 0xFE, - 0xEA, 0x72, 0x6B, 0x23, 0xB4, 0xA3, 0x3A, 0xA8, - 0xA3, 0xF5, 0xA6, 0x61, 0x67, 0x21, 0x5C, 0x61, - 0x48, 0xC0, 0x6B, 0x94, 0xCD, 0x8B, 0xFE, 0x37 - }, - { - 0x7A, 0x24, 0x40, 0x33, 0x35, 0xB8, 0x64, 0x10, - 0xD8, 0xD6, 0x93, 0xF1, 0x63, 0xD6, 0x19, 0x8A, - 0x68, 0x0F, 0x7E, 0x3A, 0xC0, 0x25, 0xEC, 0x44, - 0x74, 0x24, 0x9B, 0x01, 0x16, 0x77, 0xFE, 0x1C, - 0x86, 0x6A, 0xAF, 0x45, 0x3D, 0xB0, 0xE8, 0xF6, - 0x54, 0x33, 0x51, 0x50, 0x86, 0x3A, 0xCE, 0x57, - 0x66, 0x50, 0x80, 0x31, 0x91, 0x27, 0x8E, 0x9D, - 0x4B, 0x54, 0x7A, 0x43, 0x4C, 0x56, 0x54, 0xE2 - }, - { - 0xAF, 0x07, 0xC6, 0x7D, 0x58, 0x74, 0x3A, 0xEB, - 0x18, 0x50, 0xEB, 0x53, 0xB2, 0xDA, 0x78, 0xEC, - 0xF7, 0x09, 0x58, 0x18, 0x32, 0x5B, 0xEB, 0x86, - 0x6F, 0xF3, 0x13, 0xE3, 0x94, 0xC0, 0x07, 0xE0, - 0xC0, 0xB5, 0xA1, 0xCD, 0x7A, 0xE6, 0xBB, 0x37, - 0xCD, 0x27, 0x81, 0xB5, 0x2D, 0x15, 0x4D, 0x18, - 0x86, 0x5D, 0x5E, 0x37, 0xDB, 0xAA, 0x5F, 0x96, - 0x73, 0x9B, 0xF7, 0x69, 0x59, 0x96, 0xAE, 0x30 - }, - { - 0x28, 0xB3, 0xC2, 0x60, 0xFA, 0x7F, 0x23, 0xB9, - 0xCC, 0xAD, 0xD6, 0x15, 0xA1, 0x14, 0x69, 0x49, - 0x8A, 0xDB, 0x18, 0xD7, 0xA9, 0xF6, 0x84, 0xFD, - 0xE4, 0x35, 0xC0, 0x65, 0x33, 0xF5, 0xF5, 0x08, - 0xB2, 0x9B, 0x5E, 0xCD, 0x0E, 0xCD, 0x57, 0x36, - 0x9F, 0x22, 0xF1, 0xC5, 0x4E, 0x61, 0xBE, 0x6C, - 0xD1, 0x04, 0xC8, 0xF7, 0xD3, 0xE1, 0x84, 0x7A, - 0xAD, 0x67, 0x07, 0x3A, 0x47, 0x86, 0xE1, 0xDB - }, - { - 0xD6, 0x43, 0x23, 0x33, 0x25, 0x23, 0x9E, 0x2E, - 0xBD, 0x41, 0x1F, 0x0E, 0x00, 0x23, 0x30, 0x56, - 0x2E, 0xB1, 0xBB, 0x08, 0xE6, 0x88, 0x24, 0xB7, - 0x1B, 0x98, 0x19, 0x9C, 0x76, 0xD5, 0x31, 0x58, - 0xD9, 0x1D, 0xDD, 0x6F, 0x4F, 0x82, 0x61, 0xEC, - 0x1D, 0x72, 0xFC, 0x77, 0xC2, 0xCC, 0x23, 0x7E, - 0xDA, 0x15, 0xF0, 0x25, 0x7C, 0xF0, 0x7B, 0x84, - 0xCF, 0x1F, 0xBD, 0x1D, 0xBA, 0xFA, 0x1D, 0xFC - }, - { - 0x3D, 0x7B, 0x44, 0xCC, 0x82, 0xEF, 0xCA, 0xFC, - 0xAB, 0xA6, 0xB1, 0x91, 0x05, 0x48, 0x95, 0x8C, - 0x18, 0x0A, 0x0E, 0x8D, 0x84, 0xBC, 0x66, 0x3E, - 0x8E, 0xF9, 0x53, 0x3B, 0xD8, 0x0C, 0x4B, 0xBA, - 0xAA, 0x25, 0x5B, 0x19, 0x81, 0xF7, 0x56, 0xEB, - 0x10, 0x79, 0xAD, 0x0F, 0x34, 0x71, 0xA1, 0xFC, - 0x9D, 0x7A, 0x43, 0x23, 0x39, 0x30, 0x3A, 0x57, - 0x81, 0xA3, 0x45, 0x35, 0x30, 0x9E, 0x5A, 0x24 - }, - { - 0xEB, 0x08, 0x12, 0xC9, 0x67, 0x06, 0x46, 0xD5, - 0x63, 0x19, 0x8B, 0x11, 0x7A, 0xAF, 0xC5, 0x6F, - 0xA1, 0xB6, 0x56, 0x0F, 0x88, 0xB5, 0x75, 0x4E, - 0xBF, 0xC3, 0x1B, 0x35, 0x52, 0x16, 0xD8, 0xD7, - 0x4D, 0x34, 0x1E, 0x35, 0xB2, 0x43, 0xBC, 0x93, - 0x8C, 0xF5, 0x46, 0xAF, 0x1F, 0x73, 0xC1, 0xB0, - 0x04, 0x55, 0xDC, 0x06, 0xB2, 0xC6, 0xC5, 0x35, - 0x27, 0x9E, 0x87, 0x67, 0x49, 0x8F, 0x14, 0xE6 - }, - { - 0x7B, 0xBA, 0x7D, 0x73, 0x04, 0x02, 0x1C, 0x75, - 0xB5, 0xD6, 0xCE, 0x66, 0xB4, 0xEF, 0xA5, 0x50, - 0x19, 0xD9, 0x42, 0xD2, 0x08, 0xAF, 0xAC, 0x82, - 0x11, 0xAA, 0x7E, 0x5E, 0x11, 0x1E, 0x27, 0x69, - 0x76, 0x70, 0xE4, 0xEC, 0x91, 0xBA, 0x30, 0x8E, - 0xBD, 0xFB, 0x19, 0x15, 0x4C, 0x3B, 0xAD, 0x05, - 0x26, 0xA6, 0x25, 0x41, 0xAE, 0x5D, 0x43, 0xD0, - 0xF5, 0x47, 0xB9, 0xD9, 0x8E, 0x07, 0x36, 0x60 - }, - { - 0xA8, 0xE2, 0xA9, 0x46, 0x8D, 0xA3, 0xE3, 0x54, - 0x3A, 0x23, 0xA5, 0x78, 0x78, 0x0E, 0x25, 0x62, - 0xC7, 0xCE, 0x57, 0xFD, 0x11, 0x20, 0xE1, 0xC0, - 0x24, 0xD7, 0xEA, 0x32, 0x90, 0x31, 0x70, 0x46, - 0x61, 0x6E, 0x14, 0xCD, 0x0F, 0x15, 0xA8, 0x6B, - 0x99, 0x39, 0x54, 0x9B, 0x14, 0x76, 0x11, 0xB6, - 0xA5, 0x5D, 0x85, 0xAB, 0xC2, 0x5F, 0x63, 0x95, - 0x46, 0xB8, 0x9D, 0xD2, 0x3D, 0x39, 0xA9, 0x85 - }, - { - 0xCE, 0x87, 0x4C, 0xD6, 0xE1, 0x95, 0x8B, 0x9D, - 0x7F, 0x11, 0xFF, 0x44, 0xAB, 0x08, 0x32, 0xE8, - 0x48, 0x70, 0x2C, 0x8F, 0x26, 0x65, 0x6B, 0xA1, - 0x0B, 0xF5, 0x72, 0x0A, 0x7C, 0xAA, 0x1F, 0x59, - 0x08, 0xC9, 0x9A, 0x96, 0x03, 0xA9, 0x8B, 0x41, - 0x6C, 0x57, 0x22, 0x8C, 0x81, 0x9C, 0xEA, 0xF8, - 0x27, 0x01, 0x3B, 0x2E, 0x6D, 0x6B, 0x2D, 0xAE, - 0x59, 0xDF, 0xF1, 0x04, 0xB9, 0x02, 0xC3, 0x1B - }, - { - 0x30, 0xFF, 0xFE, 0x37, 0x21, 0x8D, 0xB1, 0x94, - 0xB2, 0x32, 0x73, 0x49, 0x8F, 0x45, 0x44, 0xD3, - 0x84, 0x14, 0xBE, 0xE4, 0x1B, 0x17, 0x55, 0xA0, - 0xC6, 0xC2, 0xDB, 0xCB, 0x41, 0x19, 0x42, 0xD5, - 0xEC, 0xB9, 0xD4, 0x52, 0x3F, 0xB4, 0x79, 0x4B, - 0xA3, 0x6E, 0x57, 0x9A, 0xF2, 0xF8, 0xDD, 0x85, - 0x19, 0x99, 0x23, 0x31, 0x83, 0xFA, 0xB2, 0x7B, - 0x47, 0xAD, 0xD8, 0x7D, 0xF3, 0x59, 0x14, 0xBB - }, - { - 0xCE, 0xF4, 0x43, 0x1D, 0xCE, 0x9F, 0xF5, 0x5A, - 0x00, 0x30, 0x0E, 0xC8, 0x64, 0x9E, 0x27, 0x58, - 0x36, 0x18, 0x22, 0x43, 0x69, 0xF6, 0x0A, 0x5C, - 0x89, 0x6B, 0x2A, 0x31, 0x10, 0xB0, 0x32, 0xB8, - 0x7C, 0x9E, 0xE4, 0xF2, 0x6C, 0x5F, 0x0B, 0xDB, - 0x50, 0x3E, 0xA7, 0x44, 0x7A, 0x5D, 0xB3, 0xF7, - 0x07, 0xFE, 0x34, 0x10, 0xDA, 0xCD, 0xD7, 0x57, - 0x22, 0x19, 0xBD, 0xEA, 0x8E, 0x17, 0xDC, 0x04 - }, - { - 0x8F, 0xF0, 0xBC, 0xB7, 0x5F, 0x00, 0x61, 0xB5, - 0xF9, 0x09, 0x29, 0x8F, 0x56, 0x9E, 0x45, 0xC7, - 0x5E, 0xD2, 0xD6, 0x4A, 0x81, 0x89, 0xCE, 0xBD, - 0x4E, 0x02, 0x56, 0x6E, 0x1A, 0x1B, 0x8B, 0xE5, - 0x3A, 0x78, 0x32, 0x28, 0x55, 0x8E, 0x28, 0xB5, - 0xF8, 0x7C, 0xCC, 0x2F, 0x42, 0x8F, 0x7F, 0x87, - 0x97, 0x44, 0xB5, 0x25, 0xB2, 0x49, 0x62, 0xB3, - 0x60, 0x4B, 0x12, 0x0F, 0x06, 0x77, 0x9F, 0x2E - }, - { - 0x7F, 0x8D, 0xDF, 0xFB, 0x4D, 0xC1, 0x51, 0x91, - 0xDE, 0x3D, 0xDB, 0xE4, 0xA0, 0xF8, 0x8B, 0x7A, - 0xB0, 0x2D, 0x48, 0xE2, 0x5C, 0xFC, 0x1F, 0xE9, - 0x1D, 0xA5, 0x57, 0xE8, 0x85, 0xD0, 0x12, 0xB8, - 0xF6, 0x55, 0x26, 0xC5, 0xB7, 0xB1, 0x01, 0x3F, - 0xC8, 0x16, 0x58, 0x50, 0x43, 0xA3, 0x45, 0x60, - 0x5A, 0x39, 0xD8, 0xDA, 0xD7, 0x0D, 0x8A, 0x64, - 0x48, 0x51, 0x32, 0x50, 0xAA, 0xC4, 0xF3, 0xD5 - }, - { - 0xB1, 0xFE, 0x8C, 0x68, 0xAE, 0xF6, 0xB4, 0xD4, - 0xB2, 0x33, 0x54, 0xEB, 0x8C, 0x1D, 0x8F, 0x5A, - 0x56, 0xE3, 0x2E, 0x76, 0xB9, 0x6A, 0xC8, 0x44, - 0x3B, 0x2A, 0xB8, 0x35, 0xE4, 0xC8, 0xB6, 0x74, - 0xB3, 0x3E, 0x4C, 0x6C, 0x6D, 0xC1, 0x21, 0xD7, - 0xC2, 0xD3, 0x4B, 0x59, 0xB3, 0x7A, 0x56, 0x8A, - 0x1C, 0x98, 0xD5, 0x00, 0x32, 0x4E, 0x53, 0x08, - 0x87, 0x85, 0xB6, 0xB0, 0x80, 0x63, 0x47, 0xD1 - }, - { - 0x8E, 0x87, 0x34, 0xFC, 0xF9, 0x25, 0x9E, 0xE3, - 0x7F, 0xE9, 0xC6, 0xCD, 0xA2, 0x82, 0xC2, 0xD5, - 0xEB, 0x83, 0xD0, 0xCF, 0x43, 0x9C, 0x86, 0x19, - 0xD4, 0xB0, 0x42, 0xFF, 0x69, 0x96, 0x6B, 0x03, - 0x56, 0x5B, 0xE4, 0xDF, 0x96, 0x39, 0x3F, 0xE6, - 0xBF, 0x35, 0xAF, 0xA1, 0x6E, 0x02, 0x73, 0xB6, - 0xD3, 0x39, 0xC0, 0x09, 0x95, 0xBF, 0x6F, 0x60, - 0xA7, 0x14, 0xEF, 0x18, 0x0E, 0xBB, 0x93, 0x15 - }, - { - 0xAE, 0x15, 0x6D, 0x43, 0xA7, 0x2C, 0x04, 0x29, - 0x42, 0x59, 0x58, 0x78, 0xA7, 0x83, 0x07, 0x97, - 0x60, 0xF5, 0x21, 0xED, 0xB8, 0xB2, 0xC3, 0xD4, - 0x1A, 0x56, 0x6B, 0x7C, 0xF7, 0x4A, 0x4A, 0x08, - 0xEA, 0x0F, 0x11, 0x9D, 0x24, 0x0A, 0x62, 0xEC, - 0x73, 0xB9, 0x50, 0x97, 0x88, 0xFA, 0x3A, 0xED, - 0xF1, 0x20, 0xEE, 0x88, 0xCB, 0x95, 0x1B, 0x69, - 0x3F, 0x8F, 0x7C, 0xAF, 0x8C, 0xBA, 0x37, 0x7F - }, - { - 0x93, 0x30, 0xAA, 0xCA, 0x8C, 0x08, 0x84, 0x46, - 0x58, 0xC2, 0x95, 0x06, 0xB1, 0xC3, 0x42, 0x72, - 0xE2, 0xB3, 0xC7, 0xB4, 0xE7, 0x5E, 0x6F, 0xE9, - 0x9A, 0x01, 0x07, 0xEC, 0x5D, 0xA4, 0x53, 0x0F, - 0xB1, 0xC8, 0x8C, 0xAA, 0x66, 0xDD, 0x9C, 0x47, - 0x1E, 0x01, 0xCA, 0x21, 0xA1, 0x3A, 0x5D, 0x6F, - 0x82, 0x15, 0xDE, 0xD3, 0x14, 0x7E, 0x94, 0xDE, - 0x20, 0x88, 0x57, 0x1F, 0xD1, 0xBF, 0x23, 0xB6 - }, - { - 0xC1, 0x29, 0xF2, 0x2C, 0x50, 0xF5, 0x99, 0x72, - 0x32, 0xE2, 0xB9, 0xF9, 0x3D, 0xFA, 0xA0, 0x0A, - 0xD8, 0xA5, 0x34, 0x29, 0xF9, 0xD1, 0x5B, 0x98, - 0x42, 0xE3, 0xAE, 0x08, 0xD8, 0x49, 0xEB, 0xDD, - 0x45, 0x23, 0x8C, 0x85, 0xF9, 0x2C, 0x6F, 0x91, - 0x7E, 0x0F, 0x8F, 0x6F, 0x94, 0xE2, 0x34, 0xBE, - 0x07, 0x61, 0x68, 0xE0, 0xDF, 0x43, 0xD0, 0x28, - 0x45, 0x52, 0x79, 0xA6, 0xFF, 0x65, 0xDC, 0x84 - }, - { - 0x0E, 0x2B, 0x4B, 0xC2, 0xF6, 0xA7, 0x5B, 0xE4, - 0xB7, 0xC9, 0xD4, 0xB5, 0x3D, 0x10, 0x4D, 0xA0, - 0x65, 0x85, 0x8D, 0x38, 0x7B, 0x34, 0x0B, 0xC1, - 0x63, 0x4F, 0x3A, 0x83, 0x32, 0xD5, 0x4C, 0xAA, - 0x94, 0x30, 0x24, 0xB2, 0x13, 0xDC, 0x8D, 0x4F, - 0x21, 0x9E, 0xC8, 0xE1, 0xDE, 0xCA, 0xC7, 0xD5, - 0xC6, 0xAE, 0x69, 0xC9, 0xEF, 0xD8, 0x81, 0x49, - 0x36, 0x78, 0x38, 0x20, 0x5D, 0x0D, 0xC7, 0xC0 - }, - { - 0x83, 0xB5, 0x43, 0x85, 0x3B, 0x81, 0x42, 0xA8, - 0x3B, 0xEF, 0xF0, 0x73, 0x5F, 0x20, 0x18, 0x91, - 0xE7, 0xFF, 0xC6, 0x7D, 0xBD, 0xCD, 0x21, 0xA4, - 0x22, 0xBB, 0x33, 0x6D, 0xE3, 0x29, 0x72, 0xAE, - 0x03, 0x92, 0x64, 0x6F, 0x68, 0x27, 0xD8, 0x0C, - 0xDA, 0x65, 0x4F, 0xD3, 0xA0, 0x77, 0x4C, 0xD2, - 0xF9, 0x95, 0x51, 0x7C, 0xF0, 0x64, 0xC6, 0x17, - 0xF2, 0x1A, 0x54, 0x27, 0x5F, 0xE5, 0x0C, 0x8D - }, - { - 0x09, 0xBE, 0x15, 0xEB, 0x6A, 0x5C, 0x22, 0x6F, - 0x6D, 0x95, 0x08, 0xCB, 0xA4, 0xA2, 0x51, 0x9F, - 0xBA, 0x17, 0x2A, 0xF8, 0x37, 0x58, 0x27, 0xD7, - 0x54, 0xA7, 0xA1, 0xBC, 0x19, 0x25, 0xD1, 0x3F, - 0x5E, 0x63, 0x43, 0xF3, 0xE1, 0x4D, 0x08, 0xA0, - 0x6E, 0x8D, 0x37, 0xF8, 0xEC, 0x56, 0xFB, 0x43, - 0x8E, 0x62, 0x36, 0x66, 0xB6, 0xFB, 0x0E, 0x23, - 0xFB, 0x50, 0x47, 0x7D, 0x41, 0x1B, 0x0C, 0x3A - }, - { - 0xC3, 0x57, 0x97, 0xE9, 0x83, 0x2D, 0x3E, 0x23, - 0x23, 0x33, 0x5B, 0x8C, 0x19, 0xC5, 0xFA, 0x74, - 0x91, 0x60, 0x2D, 0xBF, 0x6B, 0xEA, 0x77, 0xFA, - 0xEE, 0xC9, 0x51, 0x0B, 0xC2, 0xE8, 0x91, 0xC8, - 0xC3, 0x46, 0x21, 0x99, 0xF6, 0x04, 0x18, 0xD2, - 0xE0, 0xAB, 0xFF, 0xE3, 0x1B, 0x61, 0x3B, 0xB9, - 0x80, 0xEA, 0x32, 0xB7, 0x6C, 0x82, 0x43, 0x8D, - 0x02, 0x5F, 0x67, 0x8C, 0xAF, 0x48, 0x24, 0xA4 - }, - { - 0xCF, 0xC0, 0x57, 0xFD, 0xA7, 0x8A, 0x50, 0x31, - 0x8F, 0x49, 0x78, 0xFF, 0xFF, 0xAF, 0x77, 0x17, - 0x98, 0xE1, 0x2C, 0x3E, 0xA8, 0xC7, 0x98, 0x19, - 0x5B, 0xC5, 0xB4, 0xE6, 0x89, 0x1E, 0x61, 0xAA, - 0x25, 0xF7, 0xAF, 0x4A, 0xA7, 0x28, 0x6A, 0xC8, - 0x50, 0x76, 0x62, 0xC9, 0x07, 0xED, 0x91, 0x3E, - 0xDA, 0x65, 0x8F, 0x63, 0xFC, 0x47, 0x99, 0x7C, - 0x59, 0xB8, 0x59, 0x70, 0xF8, 0x78, 0xCA, 0x18 - }, - { - 0xD8, 0xEB, 0xE0, 0xE6, 0x38, 0xFC, 0x53, 0x5B, - 0x52, 0xCB, 0x0A, 0xFC, 0xE0, 0xF8, 0x2D, 0xDE, - 0x28, 0x57, 0x01, 0xAF, 0xF3, 0x29, 0xA5, 0x4B, - 0xA0, 0x6D, 0xFD, 0x3D, 0x1B, 0x4B, 0x31, 0xF9, - 0xF4, 0xB2, 0x4D, 0x9D, 0x68, 0x36, 0xF1, 0x22, - 0x3D, 0x6D, 0xE6, 0x6B, 0xAE, 0x78, 0x88, 0xFE, - 0xBC, 0x20, 0x40, 0xCF, 0xE9, 0x30, 0xE6, 0x9C, - 0xED, 0x59, 0xDA, 0x6D, 0xA8, 0xA0, 0xA6, 0xA6 - }, - { - 0x16, 0xB8, 0xC5, 0x5C, 0xF2, 0xF1, 0x35, 0xA4, - 0x32, 0x59, 0x0D, 0x2D, 0x4C, 0xFA, 0x38, 0x59, - 0x2F, 0x59, 0x35, 0xF8, 0xE7, 0x1C, 0xE0, 0x8A, - 0x02, 0x06, 0xA0, 0xE5, 0xAB, 0xEA, 0x90, 0xB2, - 0xE1, 0x07, 0xEB, 0x86, 0xB9, 0x18, 0x82, 0x3B, - 0xDD, 0x3B, 0xD2, 0x66, 0x07, 0x22, 0xC8, 0xDB, - 0xFA, 0x66, 0xAB, 0xB9, 0xF8, 0x63, 0x8E, 0x46, - 0x34, 0x02, 0xF6, 0x57, 0xA1, 0x68, 0x64, 0x0A - }, - { - 0x6A, 0x6E, 0x89, 0x38, 0x4F, 0x53, 0x5F, 0x02, - 0x17, 0x6C, 0x48, 0xA9, 0x93, 0xD3, 0x68, 0x7B, - 0x38, 0x9B, 0xFC, 0x03, 0x05, 0x0C, 0x77, 0x70, - 0x86, 0x35, 0x5C, 0x1A, 0x55, 0x59, 0x77, 0x42, - 0xF0, 0xB7, 0x48, 0x34, 0xA7, 0x1D, 0x05, 0x2A, - 0xE8, 0xA8, 0x3D, 0xC3, 0x4A, 0x8F, 0xD7, 0xBA, - 0x5A, 0xA6, 0x9D, 0xBD, 0x61, 0x2A, 0x4C, 0x22, - 0xDF, 0x4F, 0x74, 0xE2, 0x52, 0x8F, 0xB7, 0xA3 - }, - { - 0x1E, 0x40, 0x38, 0xCF, 0xA5, 0x0D, 0x8B, 0x13, - 0xEF, 0x68, 0xBE, 0xC3, 0xB0, 0xFF, 0xD5, 0x62, - 0xA0, 0x7A, 0xD6, 0x34, 0xB5, 0x82, 0x82, 0x57, - 0xDB, 0xA8, 0x73, 0x04, 0xF8, 0x23, 0xA9, 0x00, - 0x49, 0x2A, 0x31, 0x37, 0x19, 0x8B, 0x60, 0x5C, - 0xC7, 0xF7, 0x7C, 0x33, 0xB8, 0xCA, 0x3D, 0x94, - 0x0F, 0xD9, 0xB3, 0x38, 0xCF, 0x6B, 0x7B, 0x36, - 0xE7, 0xD9, 0xD9, 0x27, 0x20, 0x97, 0x93, 0xD0 - }, - { - 0x5B, 0xA6, 0xCD, 0x98, 0x8F, 0xF9, 0xA4, 0x81, - 0x91, 0x42, 0x21, 0x7E, 0xD6, 0x5D, 0x43, 0x7B, - 0x41, 0x3B, 0xA5, 0x02, 0x6B, 0x55, 0x4D, 0x8D, - 0x94, 0xEA, 0x27, 0x02, 0xC0, 0x96, 0xD1, 0x01, - 0x47, 0x75, 0xDB, 0xA2, 0xCA, 0xE9, 0x6F, 0x1E, - 0x2E, 0x72, 0x29, 0xC3, 0x78, 0xF2, 0x0B, 0x03, - 0x89, 0xE1, 0x19, 0x54, 0x7F, 0xDD, 0x35, 0x22, - 0x4A, 0x61, 0x7F, 0xCD, 0xCD, 0x0C, 0xB3, 0xAF - }, - { - 0x2D, 0x20, 0x96, 0x12, 0x30, 0xE2, 0x50, 0xF8, - 0x1D, 0xDC, 0xD2, 0xD2, 0xAB, 0x3E, 0xF0, 0xDA, - 0xCF, 0x96, 0x85, 0x1E, 0xBA, 0xE5, 0x96, 0x34, - 0x47, 0x19, 0x2C, 0xDB, 0x89, 0xE4, 0x8E, 0x84, - 0xF3, 0x96, 0xEC, 0x9A, 0x09, 0x25, 0x27, 0x84, - 0xE1, 0x73, 0xAD, 0xA5, 0x2A, 0x9C, 0x81, 0xAC, - 0xDA, 0xB3, 0xD8, 0xD6, 0x83, 0x80, 0x24, 0x7A, - 0xE9, 0x75, 0x23, 0x9B, 0x01, 0x7D, 0xC1, 0xCE - }, - { - 0x35, 0x38, 0x3E, 0xA7, 0x76, 0x2B, 0x55, 0x31, - 0x0A, 0x7D, 0x57, 0xFB, 0xD5, 0xA5, 0x49, 0x97, - 0x57, 0x9B, 0x0B, 0xA3, 0x9A, 0x4E, 0xB8, 0x87, - 0x94, 0x2B, 0xD1, 0x4F, 0xD8, 0x48, 0x31, 0x88, - 0xE5, 0x00, 0x48, 0x83, 0x8D, 0x6C, 0x02, 0xDC, - 0x75, 0x89, 0x59, 0xA9, 0xF7, 0x4D, 0x83, 0x37, - 0x27, 0x43, 0xE8, 0x64, 0xC6, 0x01, 0xED, 0x70, - 0x40, 0xA9, 0xE8, 0x71, 0x52, 0xD4, 0xCF, 0xFB - }, - { - 0x0B, 0x22, 0x3B, 0x6A, 0x1C, 0x2D, 0x3A, 0xB3, - 0xF9, 0x07, 0x7A, 0x31, 0x7B, 0x7F, 0xE3, 0x2F, - 0x6F, 0x95, 0x7B, 0x7B, 0x17, 0x41, 0xF2, 0x71, - 0x77, 0x71, 0x83, 0x4D, 0x37, 0x96, 0xA1, 0x9B, - 0xA3, 0x62, 0x73, 0xC9, 0xEE, 0xD6, 0x4C, 0x07, - 0xFA, 0x4E, 0x9A, 0xF7, 0xA9, 0x8A, 0xCE, 0x9C, - 0x78, 0x9A, 0x79, 0xA5, 0xA0, 0xF9, 0x4D, 0x04, - 0x05, 0xAA, 0xF0, 0x4A, 0xF3, 0x1E, 0xD7, 0x97 - }, - { - 0x5A, 0x00, 0x7F, 0x58, 0x95, 0x52, 0x4A, 0x5E, - 0x80, 0x37, 0x03, 0x6E, 0x0F, 0x26, 0x39, 0xFD, - 0xA8, 0xC5, 0xC1, 0x51, 0x2D, 0x76, 0xE9, 0xD1, - 0x9B, 0x3D, 0xD2, 0xD5, 0xBA, 0x43, 0xF5, 0x07, - 0x97, 0x41, 0xA4, 0x58, 0x31, 0x3C, 0x5E, 0x02, - 0x40, 0x0C, 0xE0, 0x2C, 0xB6, 0x56, 0x80, 0xBE, - 0x28, 0x2E, 0xAC, 0xD9, 0xA2, 0x54, 0xEF, 0x1C, - 0xDD, 0xEE, 0xBD, 0xCE, 0xE8, 0x5D, 0x41, 0x87 - }, - { - 0xBE, 0x4D, 0xD1, 0xCC, 0xBD, 0xE1, 0x67, 0x00, - 0x04, 0xD0, 0xEF, 0xAB, 0x65, 0x43, 0xE9, 0x1C, - 0x4E, 0x46, 0x64, 0xE5, 0xA2, 0xA8, 0x8B, 0xAC, - 0x6D, 0xD2, 0x7D, 0x27, 0x64, 0x8D, 0x30, 0x2A, - 0x06, 0x5B, 0xE6, 0x07, 0x8B, 0x22, 0xE4, 0xC4, - 0xAB, 0x4F, 0x7F, 0x7C, 0xBF, 0xAF, 0xC1, 0xAD, - 0x86, 0xEC, 0x2A, 0x50, 0x4F, 0xE5, 0x85, 0x17, - 0x66, 0xF7, 0xA3, 0x24, 0x47, 0x57, 0xCB, 0x6F - }, - { - 0x0F, 0xB4, 0x48, 0x3F, 0x96, 0x59, 0x29, 0x6C, - 0xB9, 0x24, 0x5B, 0x57, 0x79, 0x2A, 0x1E, 0x6A, - 0x99, 0xF2, 0x87, 0x90, 0x07, 0x72, 0x87, 0x96, - 0x8A, 0xB3, 0xEF, 0x35, 0x89, 0xE6, 0x90, 0x24, - 0x06, 0xF1, 0xF3, 0x9D, 0xCC, 0xE0, 0x06, 0x1D, - 0xEA, 0x94, 0x0F, 0xC8, 0xC1, 0xC4, 0x9F, 0x4B, - 0x54, 0x5E, 0xED, 0x59, 0xE9, 0x6D, 0xDA, 0xE9, - 0x6A, 0x6C, 0x35, 0xB5, 0x59, 0x3C, 0x29, 0x77 - }, - { - 0x41, 0xD1, 0xFA, 0xDC, 0x60, 0xA4, 0x6C, 0x9A, - 0xD0, 0x12, 0x0A, 0x3F, 0x54, 0xD0, 0x05, 0xF5, - 0xA1, 0x07, 0x5E, 0x2F, 0x71, 0xEE, 0x0D, 0xA6, - 0x18, 0xBA, 0xC1, 0x46, 0x1E, 0xFA, 0xE9, 0x69, - 0xEC, 0xCD, 0x7A, 0xA5, 0x75, 0xC4, 0xCD, 0xAE, - 0x97, 0x1D, 0xED, 0x13, 0xAE, 0x13, 0xC5, 0x06, - 0x87, 0x2C, 0xEC, 0xB5, 0xB2, 0x08, 0xFA, 0x72, - 0xA9, 0x48, 0x40, 0x02, 0x3E, 0xDB, 0x3E, 0xFE - }, - { - 0x2F, 0x7F, 0xDC, 0x1D, 0xA4, 0x4B, 0x6E, 0x5D, - 0x2D, 0xEC, 0xDE, 0x82, 0x1A, 0xAF, 0x4B, 0x49, - 0x16, 0x8C, 0x02, 0xE8, 0xD5, 0xF2, 0x5D, 0x5C, - 0x69, 0x98, 0x71, 0x08, 0x3A, 0xEB, 0xD9, 0x28, - 0xB7, 0x4D, 0xC2, 0x2D, 0xCB, 0xED, 0xFA, 0xBA, - 0x93, 0x16, 0xAE, 0xFC, 0xA8, 0x48, 0xD1, 0x5F, - 0x05, 0x17, 0x32, 0x99, 0x03, 0xD3, 0x4B, 0x83, - 0x70, 0xDD, 0xF9, 0xBD, 0x58, 0xC6, 0xD0, 0xCD - }, - { - 0x88, 0x55, 0x8A, 0x46, 0x4E, 0xE1, 0xA8, 0x80, - 0x3B, 0x23, 0x95, 0xAF, 0x6A, 0x64, 0x90, 0x84, - 0x2B, 0x5C, 0xD4, 0x3D, 0x41, 0xF6, 0xC0, 0x7C, - 0xD6, 0xC5, 0xF8, 0x5F, 0x82, 0xF5, 0x84, 0x32, - 0xA0, 0xB1, 0x62, 0xB4, 0x38, 0xBF, 0x0C, 0xB7, - 0x08, 0x2A, 0x76, 0x73, 0xE2, 0x87, 0xD6, 0xB9, - 0x0F, 0x8D, 0x0D, 0xC8, 0xAA, 0x5C, 0xEB, 0xA3, - 0x6B, 0xFA, 0x77, 0xB1, 0x5B, 0xA0, 0x69, 0x16 - }, - { - 0xEC, 0xC1, 0x49, 0x91, 0x7B, 0x26, 0x63, 0x98, - 0xB6, 0xF3, 0x29, 0x7E, 0x96, 0x96, 0x73, 0xB1, - 0x4E, 0xAE, 0x69, 0xCE, 0x43, 0x67, 0x1F, 0xD3, - 0xC6, 0xC2, 0x15, 0xC7, 0xCF, 0x42, 0xDE, 0xA1, - 0x02, 0xFC, 0x6B, 0xD9, 0x0C, 0x87, 0xDB, 0xD4, - 0x29, 0x02, 0x51, 0x12, 0x9C, 0xC1, 0x9B, 0x38, - 0xCC, 0xF0, 0x0C, 0xBD, 0xB1, 0x6D, 0xD8, 0xDE, - 0x51, 0x58, 0x60, 0x1A, 0x41, 0x6B, 0x1F, 0x00 - }, - { - 0xED, 0x30, 0x12, 0xF8, 0x9D, 0x71, 0xED, 0x13, - 0xBB, 0x82, 0x72, 0xEC, 0xDC, 0x3D, 0x0F, 0x51, - 0xE1, 0x4A, 0x37, 0xC1, 0xEF, 0x77, 0x57, 0x77, - 0x7A, 0xDA, 0x67, 0x12, 0x78, 0x4B, 0xE1, 0x6E, - 0xCF, 0xD3, 0xE6, 0x40, 0x58, 0x30, 0xF5, 0x1D, - 0xB3, 0x3D, 0xCB, 0x85, 0x52, 0x92, 0x93, 0xE2, - 0x3E, 0x47, 0x3A, 0xBF, 0x8C, 0x5C, 0x76, 0x55, - 0xD0, 0xC4, 0xF1, 0x52, 0xD0, 0x48, 0xBA, 0xB2 - }, - { - 0x09, 0x7A, 0x81, 0x19, 0x1E, 0x10, 0x05, 0x67, - 0x6D, 0x6E, 0x22, 0xA9, 0x63, 0x48, 0xFA, 0x4A, - 0x7C, 0x95, 0x61, 0xFD, 0x4D, 0x22, 0x8E, 0xB2, - 0x5F, 0x29, 0x47, 0x56, 0xBB, 0x87, 0xA2, 0xBA, - 0x88, 0x47, 0x5B, 0x03, 0x6F, 0x79, 0xFE, 0x37, - 0x3D, 0x75, 0x40, 0x87, 0x05, 0x52, 0x00, 0x1D, - 0x54, 0x79, 0x5F, 0x25, 0x92, 0x39, 0xBE, 0x6D, - 0x32, 0xC4, 0x87, 0xD1, 0x94, 0x4F, 0x1F, 0xE7 - }, - { - 0x3F, 0xC7, 0x98, 0xE4, 0x69, 0xD3, 0x90, 0x86, - 0xBA, 0x0B, 0xB4, 0x06, 0x3E, 0x80, 0x5F, 0xDF, - 0xB2, 0x20, 0x8D, 0xE4, 0x99, 0x18, 0x41, 0x73, - 0xF9, 0xA2, 0x36, 0x4D, 0x56, 0xBC, 0xD5, 0x63, - 0xED, 0x61, 0x9B, 0xB6, 0x87, 0x32, 0x24, 0x25, - 0x01, 0x4A, 0x1A, 0xAD, 0x3B, 0xCF, 0x50, 0xD2, - 0x2D, 0x83, 0xA9, 0x9D, 0x09, 0x73, 0x0A, 0x92, - 0xEC, 0x65, 0x46, 0xB3, 0xFC, 0x40, 0xA2, 0xC6 - }, - { - 0x69, 0x12, 0xB4, 0xB3, 0x41, 0xC7, 0xDD, 0x70, - 0x68, 0x37, 0x38, 0xBA, 0x0E, 0x7D, 0xEB, 0xBA, - 0xBF, 0xCA, 0x5F, 0x4F, 0xB0, 0x76, 0x0C, 0x84, - 0x97, 0x76, 0xE9, 0x20, 0x75, 0x0B, 0xF1, 0x37, - 0x89, 0xA6, 0x99, 0x97, 0x96, 0x23, 0x4E, 0x9E, - 0x24, 0x07, 0x15, 0xB2, 0x67, 0x67, 0x78, 0x2B, - 0x85, 0xA6, 0x4D, 0x68, 0x0C, 0x6D, 0x4C, 0xD4, - 0x26, 0xAD, 0x72, 0xB2, 0xFC, 0xE0, 0x81, 0xE8 - }, - { - 0xCE, 0xCD, 0x14, 0x01, 0x50, 0x15, 0x7D, 0xC9, - 0x06, 0xC0, 0xFF, 0x7F, 0x87, 0xC0, 0x08, 0x8F, - 0x31, 0x64, 0x80, 0x78, 0x3B, 0x4F, 0xE0, 0xA5, - 0x94, 0x45, 0x10, 0xC6, 0x4A, 0x87, 0xE3, 0xED, - 0x06, 0x67, 0x97, 0xA2, 0x7C, 0xE9, 0xD0, 0xF2, - 0x84, 0xDC, 0xA5, 0x18, 0x44, 0x18, 0x08, 0xAC, - 0x18, 0x29, 0x0A, 0xFD, 0xC0, 0x31, 0x29, 0x4B, - 0x31, 0xAA, 0x8B, 0x4A, 0x9F, 0xCD, 0x78, 0xF8 - }, - { - 0x2A, 0x2B, 0xED, 0x5D, 0x6A, 0xC0, 0x89, 0x28, - 0x11, 0xA4, 0x09, 0xD9, 0xF1, 0xFF, 0x63, 0x03, - 0xCC, 0xF9, 0x55, 0x44, 0x57, 0x46, 0x99, 0xCD, - 0xA7, 0xF7, 0x35, 0x03, 0x01, 0xF6, 0xD0, 0xC4, - 0xE8, 0x6E, 0x63, 0x5C, 0x80, 0x87, 0x56, 0x66, - 0xE2, 0xBB, 0x39, 0x07, 0x51, 0x0D, 0x0E, 0x72, - 0x12, 0x0F, 0x04, 0x86, 0x5E, 0xDC, 0x4C, 0x6C, - 0xEE, 0xCB, 0x44, 0x62, 0xD6, 0xAF, 0x60, 0xFB - }, - { - 0x03, 0x85, 0xAE, 0x9B, 0x73, 0x5D, 0xC5, 0x9F, - 0x30, 0x4D, 0x41, 0x4C, 0xA0, 0x43, 0x74, 0x9A, - 0xB5, 0x1A, 0xB6, 0x65, 0xEE, 0x01, 0xBE, 0x5E, - 0x52, 0xDC, 0xF7, 0x25, 0xEE, 0x7D, 0xFE, 0xFE, - 0xA6, 0xAD, 0x73, 0xF3, 0x35, 0xEE, 0xCF, 0x2A, - 0x51, 0x02, 0xE8, 0x88, 0x07, 0xFD, 0xC7, 0x5A, - 0xE6, 0xDC, 0x49, 0x0D, 0x7B, 0x8B, 0x5F, 0x11, - 0x63, 0x03, 0xEF, 0x60, 0xA5, 0xF1, 0x7C, 0x06 - }, - { - 0x0C, 0xA3, 0xFF, 0x03, 0x89, 0x65, 0xC0, 0x3B, - 0xC6, 0x5B, 0xBE, 0x2D, 0x86, 0x6C, 0xE9, 0xE0, - 0xE4, 0xE7, 0xD0, 0x3D, 0xC7, 0xF8, 0x6B, 0xA5, - 0x65, 0x0F, 0x82, 0xDD, 0xB3, 0xA9, 0xAA, 0x84, - 0x6B, 0x2B, 0x1F, 0x55, 0x3B, 0xD8, 0x9F, 0xB4, - 0xF9, 0xB6, 0x2E, 0x3C, 0x7F, 0xAF, 0x9E, 0xC3, - 0x10, 0x9F, 0xA9, 0x0E, 0xE5, 0x6C, 0x24, 0x63, - 0xE6, 0xEF, 0xD1, 0xAB, 0xAD, 0x8E, 0x28, 0xE6 - }, - { - 0x6D, 0xFD, 0x4F, 0x22, 0x18, 0x4E, 0xD0, 0x91, - 0xFD, 0x5A, 0xBA, 0x03, 0x9F, 0xCD, 0x3D, 0xB9, - 0x22, 0xF5, 0xE5, 0x9B, 0xF8, 0x38, 0xC0, 0x37, - 0x35, 0x7F, 0xAD, 0x93, 0x4B, 0x45, 0x10, 0x60, - 0x3F, 0x43, 0xA7, 0x31, 0x9F, 0xFF, 0xA6, 0x23, - 0x86, 0xF8, 0x78, 0x8F, 0xDF, 0x9D, 0xED, 0x40, - 0xC6, 0x66, 0xB4, 0xBD, 0xCA, 0x86, 0xD9, 0x32, - 0x8F, 0xE5, 0x5A, 0xD8, 0x6B, 0x37, 0x2F, 0xC8 - }, - { - 0xA3, 0x18, 0x97, 0x61, 0x02, 0x74, 0x7D, 0x80, - 0x0F, 0x58, 0x4D, 0xF6, 0x5B, 0xFB, 0x44, 0x3B, - 0x85, 0x6F, 0x00, 0x9E, 0x74, 0xF7, 0x29, 0x46, - 0xD0, 0x07, 0x6C, 0xED, 0xAC, 0x04, 0x37, 0x6F, - 0xAB, 0x97, 0x34, 0x53, 0xAD, 0xAD, 0xC3, 0x10, - 0xF7, 0x20, 0x81, 0xCB, 0xBA, 0x96, 0x26, 0x4F, - 0xFE, 0x2B, 0x21, 0xA3, 0xB1, 0x8B, 0xE9, 0xD8, - 0x8C, 0x42, 0x46, 0xCB, 0xA6, 0xD3, 0x09, 0x01 - }, - { - 0xB5, 0xE6, 0xE4, 0xFC, 0xA0, 0xCF, 0x98, 0x48, - 0xA0, 0x05, 0x89, 0xC6, 0x54, 0x57, 0xDB, 0x68, - 0xB3, 0x25, 0x3A, 0x6E, 0x17, 0x78, 0x85, 0x41, - 0x47, 0x2E, 0x1F, 0xB9, 0x48, 0x17, 0xF8, 0x04, - 0x05, 0x4D, 0x07, 0xA5, 0xD3, 0x2D, 0xFA, 0x0C, - 0xDB, 0x6F, 0xB4, 0x4E, 0xED, 0x50, 0xD2, 0x0E, - 0x5F, 0x22, 0x64, 0x36, 0x11, 0x32, 0xFA, 0x5F, - 0xCF, 0xD6, 0xE1, 0xB3, 0x67, 0xC1, 0xBE, 0x28 - }, - { - 0x2E, 0xA4, 0x57, 0x38, 0x29, 0x25, 0xE0, 0x3C, - 0xF8, 0x11, 0x10, 0x05, 0x0E, 0x63, 0x6A, 0xD6, - 0x78, 0xE0, 0xAA, 0x3C, 0xBC, 0x69, 0x00, 0xBD, - 0xEF, 0x27, 0x8A, 0xAA, 0x18, 0xF2, 0x35, 0xE2, - 0x51, 0x60, 0xA2, 0x0E, 0x23, 0xFE, 0x0E, 0x62, - 0xA8, 0x51, 0x1B, 0x5D, 0xD0, 0x59, 0x2F, 0x79, - 0xCB, 0xC8, 0xEB, 0x7D, 0xEA, 0x64, 0xAC, 0x86, - 0x67, 0x49, 0x43, 0x45, 0xC6, 0x89, 0x2D, 0xD4 - }, - { - 0x96, 0xB3, 0x49, 0x8B, 0xCC, 0xD7, 0x8B, 0x5A, - 0x40, 0x1B, 0x27, 0x38, 0x78, 0x7D, 0x28, 0xA9, - 0x8A, 0x0E, 0xDF, 0xDC, 0x7C, 0x0B, 0x5F, 0xF9, - 0x43, 0xCF, 0xE1, 0xB1, 0x4E, 0x9C, 0xF5, 0xD9, - 0xED, 0x43, 0x10, 0x7D, 0xFB, 0xDD, 0x9E, 0x97, - 0x28, 0xD5, 0xFD, 0xD6, 0xF7, 0x1F, 0xBC, 0x77, - 0x0E, 0xAD, 0xDC, 0x4F, 0x2E, 0x40, 0x9A, 0xBE, - 0x71, 0x92, 0x7B, 0xAE, 0x1F, 0x8F, 0x73, 0xD1 - }, - { - 0xCE, 0x1B, 0xFB, 0x9A, 0xFE, 0xD2, 0x8A, 0xF4, - 0xDC, 0x75, 0x35, 0xAD, 0xEF, 0x71, 0xB8, 0xF1, - 0xB8, 0x0A, 0x8D, 0x72, 0x94, 0xB4, 0x11, 0xFD, - 0x1E, 0xD3, 0x93, 0xCF, 0x23, 0x2D, 0x3A, 0x5C, - 0x5D, 0xF2, 0x3D, 0xBB, 0x1D, 0xB2, 0x6D, 0xDD, - 0xF6, 0xF7, 0x45, 0xF8, 0xBC, 0x24, 0xC3, 0x78, - 0x1F, 0x2D, 0xBB, 0xC8, 0x18, 0xA0, 0x0A, 0xE1, - 0xFB, 0x9D, 0x64, 0x63, 0xE9, 0x5F, 0x29, 0x86 - }, - { - 0xE6, 0x4D, 0x37, 0x35, 0x6B, 0x29, 0x6B, 0x36, - 0x93, 0x0E, 0xAB, 0xE4, 0x54, 0xDB, 0x11, 0xB2, - 0x09, 0x7B, 0x0C, 0x04, 0x0B, 0xED, 0x57, 0x98, - 0x87, 0x8D, 0x38, 0xA8, 0xC4, 0xD1, 0xC6, 0xF3, - 0x26, 0x1F, 0x36, 0xBF, 0xF7, 0x64, 0xE3, 0xB4, - 0xD6, 0x06, 0xB3, 0x17, 0xE5, 0xFF, 0x50, 0x04, - 0x18, 0x45, 0x92, 0xB0, 0xB7, 0xDD, 0xFB, 0x8C, - 0x2F, 0xD8, 0x35, 0x23, 0x26, 0xCD, 0xDD, 0xB1 - }, - { - 0x85, 0xE6, 0xFE, 0x54, 0xE1, 0xE7, 0x60, 0x46, - 0xAF, 0x68, 0xF5, 0xC6, 0x04, 0x4C, 0x1E, 0x3F, - 0xFF, 0x3B, 0xFC, 0xA0, 0xBA, 0xEC, 0xAE, 0xF6, - 0xA1, 0xDF, 0x90, 0x35, 0x0D, 0xF2, 0xB0, 0xBE, - 0xC6, 0xA4, 0x20, 0xEE, 0x8F, 0x49, 0xAD, 0x44, - 0x64, 0xEC, 0x4C, 0x1E, 0x7D, 0x71, 0xF6, 0x67, - 0x61, 0x4A, 0xCE, 0xBD, 0xAD, 0xA3, 0xDF, 0x32, - 0x07, 0x79, 0x07, 0x83, 0x23, 0xF6, 0xA8, 0xAF - }, - { - 0xB1, 0x2F, 0xF1, 0xEB, 0x3B, 0xAB, 0x32, 0x0D, - 0x78, 0x55, 0xB5, 0x49, 0xD7, 0x2B, 0x72, 0x47, - 0x59, 0x91, 0x68, 0x11, 0xCB, 0xCF, 0x3E, 0x1A, - 0x12, 0x82, 0x3F, 0x98, 0xB6, 0x4A, 0xB5, 0xC4, - 0x59, 0x41, 0x61, 0x0F, 0x6B, 0x47, 0x1E, 0x35, - 0xFF, 0x79, 0x28, 0x29, 0xDD, 0x5A, 0xDE, 0x51, - 0x79, 0x12, 0x57, 0x38, 0xF3, 0xF2, 0x37, 0x28, - 0x63, 0x0F, 0x1E, 0xEC, 0x57, 0x77, 0x5A, 0x19 - }, - { - 0xB4, 0xDB, 0xE7, 0x2A, 0x1E, 0x21, 0x69, 0x7A, - 0x47, 0x44, 0xBE, 0x65, 0x00, 0x0C, 0xB1, 0xBA, - 0xD3, 0x7C, 0xE2, 0x14, 0x16, 0xEE, 0x6F, 0xCE, - 0xA8, 0x4E, 0xBA, 0xF1, 0x2A, 0x59, 0xC1, 0x1D, - 0x7C, 0x08, 0x0D, 0xF9, 0x2F, 0xB2, 0xAA, 0x8F, - 0x1C, 0x4E, 0xE8, 0xE2, 0xA2, 0x2D, 0x30, 0xBE, - 0x49, 0x85, 0x82, 0xD7, 0xC5, 0xFB, 0xBA, 0x16, - 0x5A, 0x47, 0x26, 0x89, 0xAF, 0xF6, 0x01, 0xB6 - }, - { - 0x34, 0x82, 0x18, 0xBE, 0x4D, 0xE0, 0x8D, 0xFB, - 0x24, 0x5B, 0xF2, 0x52, 0x86, 0xE3, 0x66, 0x18, - 0x63, 0x1D, 0x3B, 0xDB, 0x58, 0x27, 0xD9, 0xF7, - 0x4F, 0xA0, 0x43, 0x01, 0x66, 0x11, 0x31, 0xA4, - 0xD5, 0x5C, 0x76, 0x09, 0xB1, 0xA6, 0xA0, 0x3B, - 0x85, 0x3F, 0x07, 0x33, 0xE0, 0xAE, 0xC0, 0x26, - 0x16, 0xA0, 0xA4, 0x0E, 0x84, 0x91, 0xF4, 0x94, - 0xD7, 0x6C, 0x15, 0x43, 0xCF, 0xC6, 0x82, 0x14 - }, - { - 0x42, 0x87, 0xE1, 0x9B, 0xAB, 0x1D, 0x4F, 0x75, - 0xE1, 0xD1, 0x97, 0xCB, 0xB4, 0x3F, 0x11, 0x33, - 0x13, 0x07, 0xF2, 0xF7, 0x5B, 0x8D, 0x0D, 0x50, - 0x27, 0x8E, 0xEC, 0x54, 0x09, 0x99, 0xA0, 0x09, - 0xC0, 0x33, 0x73, 0x52, 0x96, 0x07, 0xFD, 0xA6, - 0x05, 0xAA, 0x0F, 0x07, 0x39, 0xE2, 0x0B, 0xD1, - 0xFD, 0xAA, 0x27, 0xD7, 0xC0, 0xCD, 0xC8, 0x28, - 0x4D, 0x98, 0xE6, 0xC7, 0x55, 0xA7, 0x56, 0x2E - }, - { - 0x08, 0x56, 0x0C, 0x99, 0x88, 0xC8, 0xCE, 0x5A, - 0x88, 0x76, 0xA6, 0x00, 0xB6, 0xE5, 0x12, 0xB4, - 0xE2, 0x43, 0xA4, 0xA4, 0x30, 0x0A, 0xD5, 0xAB, - 0x2F, 0xF0, 0x63, 0x7C, 0xC5, 0x6A, 0x04, 0x41, - 0x64, 0x5B, 0x3D, 0xEB, 0x16, 0x84, 0x06, 0x4E, - 0xA4, 0x3B, 0xAE, 0x1C, 0xB6, 0x2D, 0x3B, 0xC4, - 0x15, 0x37, 0xFE, 0x8D, 0x7D, 0xEC, 0xA7, 0x17, - 0x29, 0x37, 0x77, 0x6B, 0xBE, 0xD7, 0x93, 0xA9 - }, - { - 0xB5, 0x36, 0x16, 0x23, 0x94, 0x77, 0x6F, 0xA7, - 0xDD, 0x5E, 0x9F, 0xDD, 0x01, 0x53, 0x0F, 0xDA, - 0x52, 0xBE, 0x1D, 0x39, 0xBD, 0x60, 0x9B, 0x3F, - 0x3B, 0xD0, 0x47, 0x6B, 0x81, 0x60, 0xAA, 0x18, - 0xAB, 0x2D, 0x37, 0xD2, 0x99, 0x16, 0x28, 0xBE, - 0x2F, 0xCC, 0x12, 0x56, 0xCD, 0x48, 0x55, 0x25, - 0xD1, 0xFA, 0x35, 0x6B, 0x04, 0xD3, 0x0E, 0x4A, - 0x0F, 0x9F, 0xFF, 0xC9, 0x93, 0x5C, 0xF4, 0x32 - }, - { - 0x02, 0xAB, 0xC9, 0x71, 0x75, 0xED, 0xB4, 0x7A, - 0x4C, 0xB4, 0xBD, 0x38, 0xD8, 0x2F, 0x86, 0xAA, - 0x09, 0x9C, 0x8B, 0x8F, 0xA8, 0xAB, 0x3F, 0xE1, - 0xCE, 0x10, 0x5A, 0x22, 0xBD, 0x61, 0x65, 0x78, - 0xC6, 0xDD, 0x15, 0x15, 0xDF, 0xB0, 0x39, 0x7E, - 0x1D, 0x9D, 0x06, 0x71, 0x91, 0x6D, 0xE4, 0xB5, - 0x22, 0xE7, 0x4E, 0x63, 0x75, 0x23, 0x68, 0x93, - 0xC8, 0xFD, 0xA6, 0xD2, 0x36, 0xBC, 0x8D, 0xA1 - }, - { - 0x21, 0xE1, 0xEB, 0x73, 0x12, 0x76, 0xA8, 0x35, - 0xA6, 0xDD, 0xEA, 0x71, 0x78, 0xB2, 0x3E, 0xBC, - 0x9A, 0xEC, 0xAA, 0xBC, 0x7C, 0xCD, 0x70, 0x65, - 0x87, 0xD7, 0x1B, 0x85, 0x44, 0x97, 0x93, 0xB0, - 0x7E, 0x7B, 0x17, 0x9A, 0x3D, 0xA7, 0xA5, 0x71, - 0x98, 0x29, 0x97, 0xE8, 0xF5, 0xA6, 0x7F, 0x8C, - 0x93, 0xDA, 0xF1, 0x1A, 0xAA, 0x23, 0xF0, 0x7E, - 0x4D, 0xF7, 0xA1, 0x31, 0x05, 0xA5, 0x42, 0x09 - }, - { - 0x1C, 0xC5, 0x37, 0xD3, 0xE5, 0x0E, 0xD9, 0xFD, - 0xCD, 0xC4, 0xF3, 0xCC, 0xB4, 0x81, 0x93, 0x75, - 0x41, 0x53, 0x04, 0xD8, 0xE5, 0xA6, 0xC0, 0x58, - 0x05, 0xB6, 0xB5, 0xD9, 0xE1, 0xFC, 0x18, 0x25, - 0x68, 0x64, 0xF1, 0x0C, 0xD8, 0x12, 0xF8, 0x48, - 0x01, 0xB8, 0x61, 0x6A, 0x92, 0xB4, 0x07, 0x95, - 0xA1, 0x55, 0x93, 0x24, 0x64, 0xF6, 0x2D, 0xBF, - 0x6E, 0xBD, 0x2F, 0x9A, 0xC3, 0xEE, 0x28, 0x16 - }, - { - 0x6F, 0x6C, 0xD2, 0x60, 0x05, 0xC8, 0xA5, 0x61, - 0xCF, 0xF5, 0x1E, 0x30, 0x1D, 0x1A, 0x06, 0x8F, - 0xC2, 0x8B, 0x9B, 0x65, 0x0D, 0xDD, 0x27, 0xAE, - 0x97, 0xB5, 0x22, 0xDA, 0xE9, 0x63, 0x91, 0x34, - 0xD5, 0xA1, 0x50, 0x58, 0x7B, 0x0A, 0x90, 0x1F, - 0x3B, 0x9A, 0xAB, 0xC7, 0xE3, 0x97, 0x84, 0x98, - 0x4C, 0xC5, 0x85, 0x23, 0x5D, 0x8E, 0x17, 0xCE, - 0x9E, 0x3B, 0x42, 0x10, 0x5B, 0xF9, 0x03, 0x4C - }, - { - 0x69, 0xC1, 0x7C, 0x28, 0x64, 0xC3, 0x37, 0x9F, - 0xAF, 0xB7, 0x14, 0xC0, 0x47, 0x5E, 0x00, 0xCF, - 0x7C, 0x9B, 0x37, 0x7D, 0x57, 0xA8, 0xBC, 0x96, - 0x98, 0xB4, 0xD3, 0x4A, 0x54, 0x85, 0x41, 0x76, - 0xA2, 0xF8, 0xD1, 0x5A, 0xFB, 0x54, 0x77, 0x56, - 0x04, 0x78, 0x73, 0x90, 0xD6, 0x00, 0x74, 0xCD, - 0x4B, 0xCA, 0x69, 0x02, 0xEA, 0x23, 0xD3, 0xAE, - 0x1A, 0xC0, 0x83, 0x40, 0x9F, 0xE3, 0x8A, 0x4D - }, - { - 0x86, 0x69, 0xB0, 0xAD, 0x35, 0x82, 0x9E, 0xDC, - 0x2A, 0x8A, 0x09, 0x85, 0x2B, 0x0E, 0xE9, 0xB3, - 0x90, 0x3B, 0xF6, 0xC1, 0xF8, 0x2F, 0x90, 0xA3, - 0xF0, 0xED, 0x95, 0x24, 0x19, 0x2F, 0x10, 0x91, - 0xFD, 0x64, 0x84, 0xE0, 0x4C, 0x3F, 0xEA, 0x8B, - 0x02, 0x2F, 0x4A, 0x89, 0x50, 0xDB, 0x17, 0xD4, - 0x73, 0x41, 0x45, 0xC0, 0xCE, 0xC5, 0xDC, 0x38, - 0x74, 0x55, 0xC1, 0x26, 0x90, 0x3F, 0x77, 0x66 - }, - { - 0x3F, 0x35, 0xC4, 0x5D, 0x24, 0xFC, 0xFB, 0x4A, - 0xCC, 0xA6, 0x51, 0x07, 0x6C, 0x08, 0x00, 0x0E, - 0x27, 0x9E, 0xBB, 0xFF, 0x37, 0xA1, 0x33, 0x3C, - 0xE1, 0x9F, 0xD5, 0x77, 0x20, 0x2D, 0xBD, 0x24, - 0xB5, 0x8C, 0x51, 0x4E, 0x36, 0xDD, 0x9B, 0xA6, - 0x4A, 0xF4, 0xD7, 0x8E, 0xEA, 0x4E, 0x2D, 0xD1, - 0x3B, 0xC1, 0x8D, 0x79, 0x88, 0x87, 0xDD, 0x97, - 0x13, 0x76, 0xBC, 0xAE, 0x00, 0x87, 0xE1, 0x7E - }, -}; - - - - -static const uint8_t blake2bp_keyed_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = -{ - { - 0x9D, 0x94, 0x61, 0x07, 0x3E, 0x4E, 0xB6, 0x40, - 0xA2, 0x55, 0x35, 0x7B, 0x83, 0x9F, 0x39, 0x4B, - 0x83, 0x8C, 0x6F, 0xF5, 0x7C, 0x9B, 0x68, 0x6A, - 0x3F, 0x76, 0x10, 0x7C, 0x10, 0x66, 0x72, 0x8F, - 0x3C, 0x99, 0x56, 0xBD, 0x78, 0x5C, 0xBC, 0x3B, - 0xF7, 0x9D, 0xC2, 0xAB, 0x57, 0x8C, 0x5A, 0x0C, - 0x06, 0x3B, 0x9D, 0x9C, 0x40, 0x58, 0x48, 0xDE, - 0x1D, 0xBE, 0x82, 0x1C, 0xD0, 0x5C, 0x94, 0x0A - }, - { - 0xFF, 0x8E, 0x90, 0xA3, 0x7B, 0x94, 0x62, 0x39, - 0x32, 0xC5, 0x9F, 0x75, 0x59, 0xF2, 0x60, 0x35, - 0x02, 0x9C, 0x37, 0x67, 0x32, 0xCB, 0x14, 0xD4, - 0x16, 0x02, 0x00, 0x1C, 0xBB, 0x73, 0xAD, 0xB7, - 0x92, 0x93, 0xA2, 0xDB, 0xDA, 0x5F, 0x60, 0x70, - 0x30, 0x25, 0x14, 0x4D, 0x15, 0x8E, 0x27, 0x35, - 0x52, 0x95, 0x96, 0x25, 0x1C, 0x73, 0xC0, 0x34, - 0x5C, 0xA6, 0xFC, 0xCB, 0x1F, 0xB1, 0xE9, 0x7E - }, - { - 0xD6, 0x22, 0x0C, 0xA1, 0x95, 0xA0, 0xF3, 0x56, - 0xA4, 0x79, 0x5E, 0x07, 0x1C, 0xEE, 0x1F, 0x54, - 0x12, 0xEC, 0xD9, 0x5D, 0x8A, 0x5E, 0x01, 0xD7, - 0xC2, 0xB8, 0x67, 0x50, 0xCA, 0x53, 0xD7, 0xF6, - 0x4C, 0x29, 0xCB, 0xB3, 0xD2, 0x89, 0xC6, 0xF4, - 0xEC, 0xC6, 0xC0, 0x1E, 0x3C, 0xA9, 0x33, 0x89, - 0x71, 0x17, 0x03, 0x88, 0xE3, 0xE4, 0x02, 0x28, - 0x47, 0x90, 0x06, 0xD1, 0xBB, 0xEB, 0xAD, 0x51 - }, - { - 0x30, 0x30, 0x2C, 0x3F, 0xC9, 0x99, 0x06, 0x5D, - 0x10, 0xDC, 0x98, 0x2C, 0x8F, 0xEE, 0xF4, 0x1B, - 0xBB, 0x66, 0x42, 0x71, 0x8F, 0x62, 0x4A, 0xF6, - 0xE3, 0xEA, 0xBE, 0xA0, 0x83, 0xE7, 0xFE, 0x78, - 0x53, 0x40, 0xDB, 0x4B, 0x08, 0x97, 0xEF, 0xFF, - 0x39, 0xCE, 0xE1, 0xDC, 0x1E, 0xB7, 0x37, 0xCD, - 0x1E, 0xEA, 0x0F, 0xE7, 0x53, 0x84, 0x98, 0x4E, - 0x7D, 0x8F, 0x44, 0x6F, 0xAA, 0x68, 0x3B, 0x80 - }, - { - 0x32, 0xF3, 0x98, 0xA6, 0x0C, 0x1E, 0x53, 0xF1, - 0xF8, 0x1D, 0x6D, 0x8D, 0xA2, 0xEC, 0x11, 0x75, - 0x42, 0x2D, 0x6B, 0x2C, 0xFA, 0x0C, 0x0E, 0x66, - 0xD8, 0xC4, 0xE7, 0x30, 0xB2, 0x96, 0xA4, 0xB5, - 0x3E, 0x39, 0x2E, 0x39, 0x85, 0x98, 0x22, 0xA1, - 0x45, 0xAE, 0x5F, 0x1A, 0x24, 0xC2, 0x7F, 0x55, - 0x33, 0x9E, 0x2B, 0x4B, 0x44, 0x58, 0xE8, 0xC5, - 0xEB, 0x19, 0xAA, 0x14, 0x20, 0x64, 0x27, 0xAA - }, - { - 0x23, 0x6D, 0xB9, 0x33, 0xF1, 0x8A, 0x9D, 0xBD, - 0x4E, 0x50, 0xB7, 0x29, 0x53, 0x90, 0x65, 0xBD, - 0xA4, 0x20, 0xDF, 0x97, 0xAC, 0x78, 0x0B, 0xE4, - 0x3F, 0x59, 0x10, 0x3C, 0x47, 0x2E, 0x0B, 0xCC, - 0xA6, 0xD4, 0x97, 0x38, 0x97, 0x86, 0xAF, 0x22, - 0xBA, 0x94, 0x30, 0xB7, 0x4D, 0x6F, 0x74, 0xB1, - 0x3F, 0x6F, 0x94, 0x9E, 0x25, 0x6A, 0x14, 0x0A, - 0xA3, 0x4B, 0x47, 0x70, 0x0B, 0x10, 0x03, 0x43 - }, - { - 0x23, 0x8C, 0x9D, 0x08, 0x02, 0x85, 0xE3, 0x54, - 0x35, 0xCB, 0x53, 0x15, 0x5D, 0x9F, 0x79, 0x2C, - 0xA1, 0xBB, 0x27, 0xDE, 0x4F, 0x9B, 0x6C, 0x87, - 0x26, 0xE1, 0x1C, 0x02, 0x8E, 0x7B, 0x87, 0x87, - 0x33, 0x54, 0x91, 0x12, 0xA3, 0x28, 0xB5, 0x0E, - 0x8C, 0xD8, 0xBA, 0x27, 0x87, 0x21, 0x7E, 0x46, - 0xB8, 0x16, 0x8D, 0x57, 0x11, 0x3D, 0xD4, 0x04, - 0xD9, 0x14, 0xE2, 0x9A, 0x6A, 0x54, 0x70, 0xE6 - }, - { - 0x9A, 0x02, 0x1E, 0xBD, 0x50, 0x4A, 0x97, 0x59, - 0x6D, 0x0E, 0x85, 0x04, 0x8A, 0xE1, 0xDA, 0x89, - 0x99, 0xE3, 0xA0, 0x47, 0x01, 0x6F, 0x17, 0xC6, - 0xC5, 0x55, 0x6C, 0x27, 0x31, 0xE9, 0xB1, 0x39, - 0x26, 0x1F, 0x84, 0x3F, 0xAD, 0x6B, 0xD4, 0x3F, - 0x7C, 0x7C, 0x58, 0x7F, 0x69, 0x8D, 0x69, 0xB6, - 0x82, 0xE5, 0x68, 0xB4, 0x42, 0xAC, 0x45, 0x88, - 0x98, 0x57, 0xB7, 0x69, 0x07, 0x34, 0xCD, 0xBB - }, - { - 0x3A, 0xBA, 0x07, 0xAE, 0x98, 0x0E, 0x33, 0x86, - 0x37, 0x47, 0x9D, 0xCA, 0x1E, 0x35, 0x28, 0x00, - 0xF4, 0x58, 0x8E, 0x62, 0xD8, 0x23, 0x36, 0x5A, - 0xA6, 0x9C, 0x5B, 0x25, 0xFC, 0xE1, 0x29, 0x68, - 0xD2, 0x6C, 0x9B, 0xDB, 0xEE, 0x9A, 0x32, 0xBF, - 0xFD, 0x42, 0xE6, 0xB2, 0x2C, 0x81, 0x38, 0xA6, - 0x1C, 0x1F, 0xCE, 0x49, 0xFF, 0xBC, 0x19, 0x0E, - 0x1E, 0x15, 0x16, 0x01, 0x53, 0xCC, 0xB6, 0xB4 - }, - { - 0x77, 0x4C, 0xDF, 0x9A, 0xBB, 0x50, 0x81, 0xFE, - 0x07, 0xEB, 0x57, 0x25, 0xE6, 0x06, 0x9B, 0x8D, - 0x6C, 0x7E, 0x60, 0x04, 0xA2, 0x4D, 0x70, 0xF7, - 0xDF, 0xAB, 0xFC, 0x03, 0x82, 0x5B, 0xBC, 0x3B, - 0x30, 0xE6, 0x20, 0xB6, 0x04, 0x1F, 0x3C, 0xC2, - 0x89, 0x6B, 0x14, 0xAB, 0x66, 0x0A, 0xF7, 0x2E, - 0x24, 0x95, 0x10, 0xAC, 0x2F, 0xE8, 0x10, 0xCC, - 0x77, 0x63, 0xA2, 0xE5, 0xC3, 0xFC, 0xA7, 0xFC - }, - { - 0x9E, 0x08, 0x9F, 0x51, 0x65, 0x7B, 0x29, 0xC2, - 0x66, 0x8E, 0x28, 0x50, 0x52, 0x4E, 0x53, 0xAE, - 0xAA, 0xA7, 0x30, 0x6F, 0x2A, 0xD5, 0xA2, 0x32, - 0xB5, 0xF0, 0x7F, 0x68, 0x8D, 0x8A, 0xB2, 0xB4, - 0x25, 0xDF, 0x7E, 0xA5, 0xBD, 0x3E, 0x9F, 0xFD, - 0x61, 0x68, 0x38, 0x90, 0x15, 0x1D, 0x78, 0xBB, - 0x94, 0x03, 0x11, 0x85, 0xAC, 0xA4, 0x81, 0xE2, - 0x14, 0x0F, 0xE3, 0x79, 0x85, 0x36, 0x76, 0x43 - }, - { - 0xB3, 0x5B, 0xD5, 0x4E, 0x4F, 0x81, 0x69, 0x6B, - 0x4F, 0x22, 0x31, 0x6A, 0x1E, 0x33, 0x7D, 0x98, - 0xD1, 0xC6, 0xB0, 0x61, 0x10, 0x99, 0x87, 0x63, - 0xB5, 0x91, 0x33, 0x35, 0x92, 0x3A, 0x40, 0x76, - 0xCB, 0x80, 0xD6, 0xD8, 0xA5, 0x18, 0x62, 0x91, - 0x13, 0x47, 0x7B, 0x30, 0xA1, 0x32, 0xA6, 0xB2, - 0x7F, 0xC1, 0xEE, 0x79, 0xF6, 0xB2, 0xE0, 0xD3, - 0x5D, 0x5B, 0xC2, 0x97, 0x27, 0x46, 0x3D, 0xB5 - }, - { - 0x12, 0x39, 0x30, 0xD5, 0xA4, 0xB7, 0x3B, 0x49, - 0x1F, 0x50, 0xE5, 0x6E, 0x2B, 0x73, 0x97, 0xA4, - 0x3D, 0x2E, 0x47, 0x87, 0x23, 0x76, 0x02, 0xB6, - 0x6F, 0xE0, 0xA8, 0x47, 0xBD, 0x13, 0xCB, 0xE8, - 0xB3, 0x7D, 0xC7, 0x03, 0xD7, 0xB2, 0xB4, 0xEA, - 0xA8, 0xBF, 0xB9, 0xA5, 0x8A, 0x7D, 0x71, 0x9C, - 0x90, 0x8F, 0x19, 0x66, 0xA2, 0xF1, 0x9F, 0xE6, - 0xEB, 0x1A, 0x78, 0x96, 0x2A, 0xFA, 0x5B, 0xF9 - }, - { - 0x08, 0x9C, 0xBC, 0x7E, 0xE1, 0xB1, 0x2C, 0x0C, - 0xC9, 0xC8, 0x3F, 0xF6, 0x66, 0xFE, 0xC8, 0x02, - 0x6B, 0xB7, 0x1B, 0x90, 0x84, 0x97, 0x9B, 0x0E, - 0xA8, 0xB7, 0x23, 0xBB, 0xBE, 0x8B, 0x00, 0xD4, - 0x10, 0x08, 0xB6, 0x04, 0x99, 0xF2, 0x4F, 0x24, - 0x1B, 0x63, 0x28, 0x1F, 0xE5, 0xB4, 0xD8, 0x89, - 0x66, 0x30, 0x9C, 0x0D, 0x7E, 0x64, 0x66, 0x91, - 0x05, 0xE5, 0x1E, 0x69, 0xD7, 0xAF, 0x8C, 0xE5 - }, - { - 0x6B, 0x3C, 0x67, 0x89, 0x47, 0xF6, 0x12, 0x52, - 0x65, 0x7C, 0x35, 0x49, 0x78, 0xC1, 0x01, 0xB2, - 0xFD, 0xD2, 0x72, 0x9E, 0xC3, 0x49, 0x27, 0xDD, - 0x5E, 0xFF, 0x0A, 0x7C, 0x0A, 0x86, 0x58, 0x26, - 0xE8, 0x33, 0xC3, 0x63, 0x23, 0x21, 0x31, 0xB1, - 0x05, 0x93, 0xBE, 0x1C, 0xCF, 0x6B, 0xA5, 0x4E, - 0xCC, 0x14, 0x31, 0x2F, 0x45, 0xBF, 0xFC, 0x24, - 0x04, 0x62, 0x9F, 0xF8, 0x02, 0x67, 0xF0, 0x94 - }, - { - 0xAA, 0x0C, 0x23, 0xEA, 0x1C, 0x6F, 0xE2, 0xE9, - 0x0A, 0x77, 0x18, 0xEF, 0x4A, 0xA4, 0x75, 0x1F, - 0xF6, 0xBE, 0xB9, 0xD4, 0x61, 0x63, 0x59, 0x5B, - 0x5D, 0x4F, 0xB8, 0x96, 0x00, 0x52, 0x5C, 0x5B, - 0x6C, 0xF1, 0x9E, 0xCD, 0xB2, 0x47, 0x78, 0x72, - 0xA7, 0xA1, 0x2D, 0x40, 0xE5, 0x06, 0x36, 0x08, - 0xE5, 0xF0, 0x00, 0x8E, 0x79, 0x72, 0xA9, 0xC0, - 0x1A, 0x4B, 0xE2, 0xAF, 0xE9, 0x53, 0x2F, 0x9C - }, - { - 0x63, 0x34, 0x7A, 0xB4, 0xCB, 0xB6, 0xF2, 0x89, - 0x52, 0x99, 0x2C, 0x07, 0x9D, 0x18, 0xD4, 0x20, - 0x01, 0xB7, 0xF3, 0xA9, 0xD0, 0xFD, 0x90, 0xB0, - 0xA4, 0x77, 0x1F, 0x69, 0x72, 0xF0, 0xC5, 0x32, - 0x89, 0xC8, 0xAE, 0xE1, 0x43, 0x29, 0x4B, 0x50, - 0xC6, 0x34, 0x12, 0x58, 0x5C, 0xDC, 0xE4, 0xFF, - 0x7B, 0xED, 0x11, 0x2C, 0xD0, 0x3C, 0x9B, 0x1D, - 0xF3, 0xDE, 0xF0, 0xCC, 0x32, 0x0D, 0x6B, 0x70 - }, - { - 0x23, 0x96, 0xC0, 0xCB, 0x9E, 0xDA, 0xAC, 0xA9, - 0xD8, 0xB1, 0x04, 0x65, 0x2C, 0xB7, 0xF1, 0x25, - 0xF1, 0x93, 0x55, 0x1A, 0xE5, 0xD7, 0xBC, 0x94, - 0x63, 0x30, 0x7C, 0x9E, 0x69, 0xCA, 0x7D, 0xA2, - 0x3A, 0x9F, 0xBC, 0xBC, 0xB8, 0x66, 0x69, 0xD5, - 0xBA, 0x63, 0x43, 0x85, 0x93, 0xE1, 0x32, 0xF9, - 0x92, 0xB5, 0x7C, 0x00, 0x17, 0xC8, 0x6D, 0xDB, - 0x9B, 0x47, 0x28, 0x6E, 0xF5, 0xB6, 0x87, 0x18 - }, - { - 0xA9, 0x4B, 0x80, 0x22, 0x57, 0xFD, 0x03, 0x1E, - 0xE6, 0x0F, 0x1B, 0xE1, 0x84, 0x38, 0x3A, 0x76, - 0x32, 0x85, 0x39, 0xF9, 0xD8, 0x06, 0x08, 0x72, - 0xEF, 0x35, 0x73, 0xBE, 0xB6, 0xF2, 0x73, 0x68, - 0x08, 0x95, 0x90, 0xED, 0xBB, 0x21, 0xF4, 0xD8, - 0xF1, 0x81, 0xBA, 0x66, 0x20, 0x75, 0xF9, 0x19, - 0x05, 0x97, 0x4B, 0xEE, 0xEF, 0x1F, 0xC5, 0xCB, - 0x9B, 0xCF, 0xB2, 0x8A, 0xAE, 0x1E, 0x4D, 0xE3 - }, - { - 0x52, 0xC7, 0xD3, 0x39, 0x9A, 0x03, 0x80, 0x04, - 0xBE, 0xA5, 0x2D, 0x3E, 0xA9, 0xE9, 0x1E, 0x25, - 0x44, 0xC8, 0x65, 0x2A, 0xB8, 0xF5, 0x28, 0x5C, - 0x9D, 0x32, 0x18, 0x63, 0x7A, 0x6D, 0x9F, 0xCA, - 0xF0, 0xD9, 0x65, 0xB3, 0x58, 0x8E, 0xE6, 0xD7, - 0x3F, 0xA5, 0x99, 0xDE, 0xCA, 0x1F, 0x41, 0xDE, - 0xD8, 0x02, 0x5B, 0xF7, 0x76, 0x8E, 0x0E, 0x20, - 0x0E, 0x8C, 0xD3, 0xFF, 0x86, 0x8C, 0x38, 0x00 - }, - { - 0xB6, 0x29, 0xF5, 0x71, 0x62, 0x87, 0x6A, 0xDB, - 0x8F, 0xA9, 0x57, 0x2E, 0xBA, 0x4E, 0x1E, 0xCD, - 0x75, 0xA6, 0x56, 0x73, 0x08, 0xDE, 0x90, 0xDB, - 0xB8, 0xFF, 0xDE, 0x77, 0xDE, 0x82, 0x13, 0xA4, - 0xD7, 0xF7, 0xCB, 0x85, 0xAE, 0x1B, 0x71, 0xE6, - 0x45, 0x7B, 0xC4, 0xE8, 0x9C, 0x0D, 0x9D, 0xE2, - 0x41, 0xB6, 0xB9, 0xF3, 0x74, 0xB7, 0x34, 0x19, - 0x4D, 0xB2, 0xB2, 0x67, 0x02, 0xD7, 0xCB, 0x7C - }, - { - 0x72, 0x28, 0x46, 0xDD, 0xAC, 0xAA, 0x94, 0xFD, - 0xE6, 0x63, 0x2A, 0x2D, 0xC7, 0xDC, 0x70, 0x8B, - 0xDF, 0x98, 0x31, 0x1C, 0x9F, 0xB6, 0x3C, 0x61, - 0xE5, 0x25, 0xFD, 0x4B, 0x0D, 0x87, 0xB6, 0x38, - 0x8B, 0x5A, 0xF7, 0x04, 0x20, 0x18, 0xDD, 0xCA, - 0x06, 0x5E, 0x8A, 0x55, 0xBB, 0xFD, 0x68, 0xEE, - 0x61, 0xFC, 0xD3, 0xC6, 0x87, 0x8F, 0x5B, 0x09, - 0xBC, 0xC2, 0x7B, 0xED, 0x61, 0xDD, 0x93, 0xED - }, - { - 0x1C, 0xED, 0x6A, 0x0C, 0x78, 0x9D, 0xDB, 0x29, - 0x56, 0x78, 0xAD, 0x43, 0xA3, 0x22, 0xD8, 0x96, - 0x61, 0x7F, 0xDE, 0x27, 0x5F, 0x13, 0x8C, 0xCC, - 0xFB, 0x13, 0x26, 0xCD, 0x3F, 0x76, 0x09, 0xC2, - 0xAA, 0xA5, 0xEC, 0x10, 0x26, 0x97, 0x17, 0x3E, - 0x12, 0x1A, 0xE1, 0x63, 0x02, 0x4F, 0x42, 0x8C, - 0x98, 0x28, 0x35, 0xB4, 0xFA, 0x6D, 0xA6, 0xD6, - 0x78, 0xAE, 0xB9, 0xEE, 0x10, 0x6A, 0x3F, 0x6C - }, - { - 0xE8, 0x69, 0x14, 0x8C, 0x05, 0x45, 0xB3, 0x58, - 0x0E, 0x39, 0x5A, 0xFD, 0xC7, 0x45, 0xCD, 0x24, - 0x3B, 0x6B, 0x5F, 0xE3, 0xB6, 0x7E, 0x29, 0x43, - 0xF6, 0xF8, 0xD9, 0xF2, 0x4F, 0xFA, 0x40, 0xE8, - 0x81, 0x75, 0x6E, 0x1C, 0x18, 0xD9, 0x2F, 0x3E, - 0xBE, 0x84, 0x55, 0x9B, 0x57, 0xE2, 0xEE, 0x3A, - 0x65, 0xD9, 0xEC, 0xE0, 0x49, 0x72, 0xB3, 0x5D, - 0x4C, 0x4E, 0xBE, 0x78, 0x6C, 0x88, 0xDA, 0x62 - }, - { - 0xDA, 0xDA, 0x15, 0x5E, 0x55, 0x42, 0x32, 0xB1, - 0x6E, 0xCA, 0xD9, 0x31, 0xCB, 0x42, 0xE3, 0x25, - 0xB5, 0x86, 0xDB, 0xF1, 0xCB, 0xD0, 0xCE, 0x38, - 0x14, 0x45, 0x16, 0x6B, 0xD1, 0xBF, 0xA3, 0x32, - 0x49, 0x85, 0xE7, 0x7C, 0x6F, 0x0D, 0x51, 0x2A, - 0x02, 0x6E, 0x09, 0xD4, 0x86, 0x1C, 0x3B, 0xB8, - 0x52, 0x9D, 0x72, 0x02, 0xEA, 0xC1, 0xC0, 0x44, - 0x27, 0x44, 0xD3, 0x7C, 0x7F, 0x5A, 0xB8, 0xAF - }, - { - 0x2D, 0x14, 0x8C, 0x8E, 0x8F, 0x76, 0xFA, 0xAC, - 0x6F, 0x7F, 0x01, 0xF2, 0x03, 0x9E, 0xA0, 0x2A, - 0x42, 0xD9, 0x32, 0x57, 0x94, 0xC2, 0xC7, 0xA0, - 0x0F, 0x83, 0xF4, 0xA7, 0x79, 0x8A, 0xFB, 0xA9, - 0x93, 0xFF, 0x94, 0x91, 0x1E, 0x09, 0x8B, 0x00, - 0x1A, 0x0B, 0xDF, 0xF4, 0xC8, 0x5A, 0x2A, 0x61, - 0x31, 0xE0, 0xCF, 0xE7, 0x0F, 0x1D, 0x2E, 0x07, - 0xAF, 0x02, 0x09, 0xDA, 0x77, 0x96, 0x09, 0x1F - }, - { - 0x99, 0x98, 0x3A, 0x75, 0x9C, 0xCF, 0x9C, 0xAC, - 0xAE, 0x70, 0x2D, 0xCB, 0xFC, 0xDF, 0x72, 0x04, - 0xDD, 0xF0, 0x33, 0x4B, 0xC6, 0x5D, 0xAD, 0x84, - 0x6F, 0x83, 0x1F, 0x9F, 0x9D, 0x8A, 0x45, 0x3F, - 0x0D, 0x24, 0x93, 0x5C, 0x4C, 0x65, 0x7F, 0xFF, - 0x2E, 0xBB, 0xDB, 0xAF, 0x7B, 0xCE, 0x6A, 0xAC, - 0xDB, 0xB8, 0x87, 0x6F, 0x16, 0x04, 0x59, 0xB1, - 0xA4, 0xAA, 0xC9, 0x56, 0x97, 0xE0, 0x0D, 0x98 - }, - { - 0x7E, 0x4A, 0x02, 0x12, 0x6D, 0x75, 0x52, 0xF4, - 0xC9, 0xB9, 0x4D, 0x80, 0xE3, 0xCF, 0x7B, 0x89, - 0x7E, 0x09, 0x84, 0xE4, 0x06, 0xF0, 0x78, 0x13, - 0x5C, 0xF4, 0x56, 0xC0, 0xD5, 0x1E, 0x13, 0x91, - 0xFF, 0x18, 0xA8, 0x8F, 0x93, 0x12, 0x2C, 0x83, - 0x2C, 0xAC, 0x7D, 0x79, 0x6A, 0x6B, 0x42, 0x51, - 0x9B, 0x1D, 0xB4, 0xEA, 0xD8, 0xF4, 0x98, 0x40, - 0xCE, 0xB5, 0x52, 0x33, 0x6B, 0x29, 0xDE, 0x44 - }, - { - 0xD7, 0xE1, 0x6F, 0xD1, 0x59, 0x65, 0x8A, 0xD7, - 0xEE, 0x25, 0x1E, 0x51, 0x7D, 0xCE, 0x5A, 0x29, - 0xF4, 0x6F, 0xD4, 0xB8, 0xD3, 0x19, 0xDB, 0x80, - 0x5F, 0xC2, 0x5A, 0xA6, 0x20, 0x35, 0x0F, 0xF4, - 0x23, 0xAD, 0x8D, 0x05, 0x37, 0xCD, 0x20, 0x69, - 0x43, 0x2E, 0xBF, 0xF2, 0x92, 0x36, 0xF8, 0xC2, - 0xA8, 0xA0, 0x4D, 0x04, 0xB3, 0xB4, 0x8C, 0x59, - 0xA3, 0x55, 0xFC, 0xC6, 0x2D, 0x27, 0xF8, 0xEE - }, - { - 0x0D, 0x45, 0x17, 0xD4, 0xF1, 0xD0, 0x47, 0x30, - 0xC6, 0x91, 0x69, 0x18, 0xA0, 0x4C, 0x9E, 0x90, - 0xCC, 0xA3, 0xAC, 0x1C, 0x63, 0xD6, 0x45, 0x97, - 0x8A, 0x7F, 0x07, 0x03, 0x9F, 0x92, 0x20, 0x64, - 0x7C, 0x25, 0xC0, 0x4E, 0x85, 0xF6, 0xE2, 0x28, - 0x6D, 0x2E, 0x35, 0x46, 0x0D, 0x0B, 0x2C, 0x1E, - 0x25, 0xAF, 0x9D, 0x35, 0x37, 0xEF, 0x33, 0xFD, - 0x7F, 0xE5, 0x1E, 0x2B, 0xA8, 0x76, 0x4B, 0x36 - }, - { - 0x56, 0xB7, 0x2E, 0x51, 0x37, 0xC6, 0x89, 0xB2, - 0x73, 0x66, 0xFB, 0x22, 0xC7, 0xC6, 0x75, 0x44, - 0xF6, 0xBC, 0xE5, 0x76, 0x19, 0x41, 0x31, 0xC5, - 0xBF, 0xAB, 0x1C, 0xF9, 0x3C, 0x2B, 0x51, 0xAA, - 0xA3, 0x03, 0x36, 0x8A, 0xA8, 0x44, 0xD5, 0x8D, - 0xF0, 0xEE, 0x5D, 0x4E, 0x31, 0x9F, 0xCD, 0x8E, - 0xFF, 0xC6, 0x02, 0xCE, 0xE4, 0x35, 0x1B, 0xD2, - 0xF5, 0x51, 0x43, 0x0B, 0x92, 0x11, 0xE7, 0x3C - }, - { - 0xF3, 0x35, 0xCC, 0x22, 0xFF, 0xEA, 0x5A, 0xA5, - 0x9C, 0xDF, 0xC8, 0xF5, 0x02, 0x89, 0xCC, 0x92, - 0x31, 0x9B, 0x8B, 0x14, 0x40, 0x8D, 0x7A, 0x5A, - 0xA1, 0x23, 0x2A, 0xE2, 0x3A, 0xA1, 0xEA, 0x7F, - 0x77, 0x48, 0xCF, 0xEF, 0x03, 0x20, 0x10, 0xF8, - 0x62, 0x6D, 0x93, 0x18, 0xED, 0xBA, 0x98, 0xD4, - 0x16, 0x62, 0x03, 0x35, 0xC9, 0x01, 0xED, 0x02, - 0xEA, 0xBD, 0x27, 0x6A, 0x1B, 0x82, 0x9C, 0x9D - }, - { - 0xA9, 0x9A, 0x3D, 0x10, 0xF9, 0x5B, 0x44, 0x2F, - 0xFF, 0xF7, 0xC4, 0x18, 0xFA, 0x94, 0x9D, 0x48, - 0x30, 0x86, 0x9B, 0x0E, 0x60, 0xEC, 0x8B, 0x97, - 0x2C, 0x30, 0xA3, 0x16, 0x9C, 0x27, 0xBE, 0xB5, - 0xCF, 0x33, 0x05, 0x94, 0xF0, 0x14, 0xB6, 0x6B, - 0x22, 0x00, 0xA7, 0xF0, 0x86, 0xD2, 0xC2, 0xF3, - 0xF9, 0xFD, 0x85, 0x32, 0xA5, 0x71, 0x88, 0x76, - 0xDF, 0xCA, 0x66, 0x1B, 0xA0, 0xF7, 0xB3, 0x6D - }, - { - 0x15, 0x8E, 0x25, 0x70, 0xD0, 0x84, 0xA4, 0x86, - 0x9D, 0x96, 0x93, 0x43, 0xC0, 0x10, 0x86, 0x07, - 0x17, 0xFF, 0x74, 0x11, 0x61, 0x88, 0x17, 0x5F, - 0x2E, 0xD7, 0x4C, 0xD5, 0x78, 0xFA, 0x0D, 0x80, - 0x91, 0xB0, 0x3F, 0xAD, 0x0C, 0x65, 0xCF, 0x59, - 0xAB, 0x91, 0xDD, 0x73, 0xB3, 0x7F, 0xE3, 0xF5, - 0x8A, 0x58, 0xE7, 0xB4, 0x47, 0x9C, 0x87, 0x5A, - 0xCD, 0x63, 0xEC, 0x52, 0x58, 0x12, 0x35, 0x3F - }, - { - 0x7C, 0x49, 0x50, 0x1C, 0x58, 0x08, 0xB1, 0x5C, - 0x0D, 0x31, 0xBD, 0xD5, 0xBB, 0x56, 0x31, 0xD5, - 0x3A, 0xE0, 0x0D, 0xF4, 0x31, 0x02, 0x5F, 0xEA, - 0x51, 0xEB, 0x47, 0x62, 0x54, 0x4E, 0xFD, 0xEE, - 0x97, 0x8A, 0x83, 0x50, 0x8D, 0xEA, 0x6B, 0xFD, - 0x3B, 0x93, 0x1A, 0x0E, 0x95, 0x83, 0xCC, 0xFC, - 0x04, 0x9E, 0xA8, 0x46, 0x44, 0x70, 0x5D, 0x31, - 0x9F, 0xDC, 0x5C, 0x16, 0x3B, 0xF4, 0x82, 0x24 - }, - { - 0xFE, 0xF4, 0x36, 0xB3, 0x5F, 0x71, 0x7D, 0x59, - 0xAC, 0xA1, 0x7E, 0x9B, 0xF5, 0xFF, 0xDA, 0x28, - 0xF5, 0xF4, 0x01, 0x94, 0x3E, 0xFE, 0x93, 0xEB, - 0x58, 0x0F, 0xFB, 0x98, 0xF1, 0x3B, 0xEA, 0x80, - 0x94, 0x69, 0xA3, 0x44, 0xE7, 0x82, 0xA4, 0x43, - 0xC6, 0x4E, 0xB2, 0x5A, 0xD0, 0x9D, 0x8D, 0xE2, - 0x05, 0xFE, 0xE7, 0xD5, 0x63, 0x96, 0x86, 0xA1, - 0x9E, 0x7C, 0x42, 0xB4, 0x0F, 0x70, 0x6A, 0x08 - }, - { - 0x4D, 0x47, 0xA6, 0x7A, 0x5F, 0x8E, 0x17, 0xB7, - 0x22, 0xDF, 0x98, 0x58, 0xAE, 0xB6, 0x7B, 0x99, - 0x56, 0xB4, 0x59, 0x62, 0xEC, 0x35, 0x3D, 0xC2, - 0xE2, 0x7F, 0x0F, 0x50, 0x1C, 0x39, 0x8E, 0x34, - 0x39, 0x7B, 0xEB, 0xE0, 0x2B, 0x54, 0x92, 0x7E, - 0x2D, 0x31, 0xF1, 0x2E, 0xCF, 0x55, 0xE8, 0x82, - 0x69, 0xFA, 0xB5, 0x37, 0x0E, 0x7F, 0xA5, 0x70, - 0x35, 0x26, 0x6F, 0x89, 0xD5, 0xC2, 0x64, 0x41 - }, - { - 0x1B, 0x58, 0xDC, 0x7A, 0xAC, 0x36, 0x3B, 0x00, - 0x44, 0x6E, 0xA8, 0x03, 0xBC, 0xD7, 0x49, 0xC3, - 0xF5, 0xCA, 0xBE, 0xAA, 0xF2, 0x23, 0x99, 0x4C, - 0x0C, 0x3E, 0xCC, 0x1B, 0x28, 0x47, 0x73, 0x44, - 0xD7, 0xBF, 0x97, 0xC0, 0x8A, 0x95, 0x9D, 0x1A, - 0xC2, 0x06, 0x0B, 0x47, 0x27, 0x89, 0x86, 0x92, - 0x91, 0x88, 0xAD, 0x73, 0xDE, 0x67, 0x07, 0x8B, - 0xA6, 0x80, 0x96, 0x3B, 0x9D, 0x3B, 0x12, 0xA4 - }, - { - 0x3C, 0x52, 0x2C, 0x84, 0x3E, 0x69, 0x74, 0xEC, - 0x75, 0x0D, 0xF2, 0x20, 0xD4, 0x1A, 0x00, 0x4A, - 0xC2, 0xAD, 0xF0, 0x94, 0x56, 0xFA, 0x78, 0x7F, - 0x7C, 0x65, 0x43, 0xAB, 0x17, 0x97, 0x9C, 0x77, - 0x7B, 0x3E, 0x79, 0xD1, 0x78, 0x7D, 0xA5, 0xA8, - 0x3F, 0x17, 0x8D, 0xA9, 0xF0, 0x4C, 0xF6, 0xF5, - 0xB2, 0x55, 0xDD, 0xCB, 0x18, 0x74, 0x84, 0x1B, - 0xBF, 0x70, 0x16, 0xE6, 0x13, 0x2B, 0x99, 0x8A - }, - { - 0x5A, 0x4F, 0xEB, 0x8F, 0x70, 0x75, 0xB4, 0xDC, - 0x9C, 0xA1, 0x6C, 0x6F, 0x05, 0xCD, 0x6B, 0x70, - 0x27, 0x48, 0x5F, 0xFE, 0xD9, 0x15, 0x7D, 0x82, - 0x4D, 0x9D, 0x1A, 0x17, 0x20, 0xEE, 0xEE, 0xEA, - 0x3F, 0x6C, 0x12, 0x5F, 0xDA, 0x4B, 0xA4, 0x40, - 0x9D, 0x79, 0x80, 0x49, 0xFD, 0x18, 0x82, 0xC6, - 0x90, 0x28, 0x8F, 0x33, 0x54, 0x7A, 0x3D, 0x8D, - 0x62, 0x60, 0xB6, 0x54, 0x54, 0x88, 0x53, 0xD7 - }, - { - 0xBC, 0xAA, 0x79, 0x36, 0x32, 0x56, 0x9E, 0x2F, - 0x84, 0x17, 0xCC, 0x60, 0x32, 0x53, 0x53, 0x5B, - 0xD7, 0xD8, 0x5F, 0x38, 0x53, 0x19, 0x92, 0x59, - 0x1E, 0x56, 0xC1, 0xA4, 0xB6, 0xF5, 0x8E, 0xE7, - 0xF8, 0x18, 0xFA, 0xE0, 0x27, 0x88, 0x8A, 0x86, - 0x28, 0x43, 0x05, 0x10, 0x1E, 0xC0, 0x46, 0x61, - 0xF5, 0x99, 0x53, 0x47, 0xA4, 0x67, 0xED, 0x8B, - 0x92, 0x79, 0xF1, 0xAC, 0xC2, 0xB4, 0xBB, 0x1F - }, - { - 0x34, 0xAF, 0x91, 0xCC, 0x22, 0xA6, 0x9B, 0xCB, - 0x55, 0xDD, 0xBF, 0x7F, 0x0F, 0x43, 0xEC, 0x56, - 0x48, 0x40, 0x43, 0x32, 0x13, 0xEA, 0x55, 0xD9, - 0xF8, 0x1A, 0xC4, 0x75, 0x20, 0x8D, 0x74, 0x85, - 0x1D, 0xB7, 0x0F, 0xE4, 0x96, 0xAF, 0x9D, 0xA1, - 0xD3, 0x93, 0xEC, 0xF8, 0x78, 0x69, 0x5D, 0xD3, - 0x3F, 0xD5, 0x43, 0x49, 0xA6, 0xF8, 0x24, 0xAE, - 0xED, 0x18, 0x3C, 0xB1, 0xB0, 0x8C, 0x54, 0x85 - }, - { - 0xB8, 0xB7, 0xAD, 0x2E, 0xA2, 0xB6, 0xFA, 0x06, - 0xD0, 0x0B, 0xCD, 0x59, 0x9C, 0x99, 0x71, 0xC5, - 0xB4, 0xE1, 0x65, 0x58, 0xE1, 0x52, 0x12, 0xC9, - 0xBF, 0xD3, 0x73, 0xE4, 0xBC, 0x79, 0x17, 0x05, - 0x26, 0x01, 0xFF, 0xDB, 0x68, 0x01, 0xBE, 0x80, - 0xBA, 0x50, 0x9D, 0xB8, 0x2A, 0x0B, 0x71, 0x95, - 0x92, 0x91, 0x33, 0xAD, 0x53, 0x99, 0x56, 0x06, - 0x52, 0x33, 0xF4, 0x9D, 0x07, 0x1C, 0x84, 0xE4 - }, - { - 0xDC, 0xEE, 0x9C, 0x45, 0xBC, 0x5D, 0x1F, 0xE6, - 0x30, 0xB1, 0x8B, 0x06, 0x3C, 0xE8, 0x2C, 0x38, - 0x57, 0xE3, 0x0D, 0x20, 0xC6, 0x4B, 0x5C, 0xC2, - 0x58, 0x84, 0x94, 0x3E, 0x7A, 0xE9, 0x4E, 0xDF, - 0xF8, 0x50, 0xEB, 0x0E, 0x82, 0x44, 0x02, 0x3D, - 0x3D, 0x07, 0xA8, 0xA0, 0x07, 0x06, 0xF0, 0x58, - 0x2C, 0xC1, 0x02, 0xB6, 0x6C, 0x6D, 0xDA, 0x86, - 0xE8, 0xF2, 0xDF, 0x32, 0x56, 0x59, 0x88, 0x6F - }, - { - 0x04, 0xF6, 0xE8, 0x22, 0xF1, 0x7C, 0xC7, 0xA5, - 0x94, 0x6D, 0xF8, 0x0D, 0x95, 0x8A, 0xEF, 0x06, - 0x5D, 0x87, 0x49, 0x16, 0xE1, 0x03, 0xA6, 0x83, - 0x0C, 0x6E, 0x46, 0xB6, 0x05, 0x59, 0x18, 0x18, - 0x0D, 0x14, 0x52, 0x29, 0x3C, 0x58, 0xA9, 0x74, - 0x9C, 0xBC, 0x8F, 0x0A, 0xC4, 0x08, 0xA9, 0xCA, - 0x89, 0x57, 0x61, 0xCF, 0xC4, 0x51, 0x16, 0x46, - 0x41, 0xA1, 0x79, 0xFB, 0x5C, 0xD8, 0xFE, 0xBC - }, - { - 0x51, 0x1F, 0xDB, 0x7C, 0x88, 0x26, 0x85, 0x35, - 0xE9, 0x7E, 0x4E, 0xD8, 0x92, 0xF3, 0xC0, 0x65, - 0x83, 0x2B, 0x26, 0x59, 0x14, 0xFC, 0x61, 0x07, - 0xA1, 0xD2, 0x7D, 0xBB, 0x7D, 0x51, 0xC3, 0x7E, - 0x95, 0x98, 0x15, 0x06, 0xC1, 0x14, 0x72, 0x44, - 0xD5, 0xBA, 0xE9, 0x0E, 0xE9, 0x0D, 0x08, 0x49, - 0x84, 0xBA, 0xA7, 0x58, 0x7F, 0x41, 0xFF, 0x6F, - 0x4B, 0xA7, 0x22, 0xC8, 0xB9, 0x2A, 0xEB, 0x99 - }, - { - 0x2B, 0xA2, 0xBD, 0x17, 0xE9, 0x26, 0x27, 0x5B, - 0x06, 0x83, 0xB2, 0x36, 0xBF, 0xE3, 0x76, 0x30, - 0x26, 0x6E, 0x37, 0xF4, 0x18, 0x2F, 0x53, 0xA9, - 0x82, 0x34, 0xE9, 0x15, 0xAB, 0x64, 0xC9, 0x59, - 0x96, 0xC6, 0xCB, 0x7A, 0xE8, 0x80, 0xC3, 0xDF, - 0xCB, 0x47, 0xD0, 0x5A, 0xAD, 0xD2, 0x1A, 0xBF, - 0x8E, 0x40, 0xB7, 0x3F, 0x40, 0xF3, 0x98, 0xDC, - 0x5B, 0x02, 0x14, 0x14, 0x57, 0x45, 0x6A, 0x09 - }, - { - 0x9B, 0x66, 0x8D, 0x9B, 0x44, 0x47, 0xE3, 0x76, - 0xF6, 0xC6, 0xCF, 0xA6, 0x8D, 0xBC, 0x79, 0x19, - 0x83, 0x81, 0xAB, 0x60, 0x5F, 0x55, 0xD5, 0xA7, - 0xEF, 0x68, 0x3B, 0xCE, 0xD4, 0x6F, 0x9A, 0xFD, - 0x36, 0x85, 0x41, 0x1A, 0x66, 0xE2, 0x34, 0x6F, - 0x96, 0x07, 0x77, 0xD0, 0xC9, 0x22, 0x71, 0x24, - 0x30, 0xE0, 0x18, 0xBF, 0xAE, 0x86, 0x53, 0x01, - 0x7E, 0xA2, 0x0E, 0xCD, 0x5F, 0x1F, 0x95, 0x6C - }, - { - 0x56, 0x81, 0x02, 0x4F, 0x53, 0x85, 0x88, 0xA0, - 0x1B, 0x2C, 0x83, 0x94, 0xCA, 0xE8, 0x73, 0xC6, - 0xD8, 0x5D, 0x6A, 0xA0, 0x6E, 0xDD, 0xB3, 0xA5, - 0x02, 0x09, 0x6F, 0xC0, 0x82, 0xBB, 0x89, 0xCB, - 0x24, 0x15, 0x31, 0xB3, 0x15, 0x75, 0x0D, 0x31, - 0xBB, 0x0B, 0x63, 0x01, 0x28, 0xD1, 0x9D, 0x11, - 0x39, 0x2B, 0xCF, 0x4B, 0x34, 0x78, 0xD5, 0x23, - 0xD7, 0xD2, 0x13, 0xE4, 0x75, 0x0F, 0x55, 0x92 - }, - { - 0x2A, 0xA9, 0x1B, 0xA6, 0xDE, 0x60, 0x17, 0xF1, - 0x93, 0x0F, 0xC7, 0xD9, 0x6D, 0xCC, 0xD6, 0x70, - 0x74, 0x8B, 0x7E, 0xB1, 0xD0, 0x94, 0xDF, 0xB4, - 0xB3, 0xB1, 0x47, 0x8A, 0x61, 0x2E, 0xBF, 0x03, - 0xDD, 0xD7, 0x21, 0x27, 0x9A, 0x26, 0x6D, 0xE3, - 0x88, 0x45, 0xE6, 0x12, 0xC9, 0x30, 0x98, 0xC2, - 0xEF, 0xFF, 0x34, 0xFE, 0x50, 0x06, 0x17, 0x20, - 0x5B, 0x1D, 0xE2, 0xFE, 0xA1, 0xD8, 0x02, 0x46 - }, - { - 0x82, 0x4D, 0x89, 0xC0, 0x63, 0x7C, 0xE1, 0x78, - 0xB6, 0x30, 0x68, 0x4C, 0x72, 0x9E, 0x26, 0x65, - 0x3F, 0x34, 0xEA, 0xC7, 0xE9, 0x04, 0x12, 0xE9, - 0x63, 0xD3, 0xF1, 0x9D, 0x64, 0x51, 0xE8, 0x25, - 0x85, 0x21, 0x67, 0xC4, 0x8D, 0xF7, 0xCC, 0x55, - 0xB2, 0x57, 0xB2, 0x50, 0xA7, 0x0C, 0x7B, 0xCC, - 0xFA, 0x9A, 0xA1, 0x5C, 0x18, 0x8A, 0xC4, 0x63, - 0x7A, 0x52, 0x22, 0x89, 0xC0, 0x87, 0x6A, 0xD4 - }, - { - 0x87, 0xE4, 0xAE, 0x11, 0xDA, 0x1A, 0x2C, 0xA8, - 0x82, 0x2A, 0xE3, 0x30, 0xDC, 0x97, 0xAB, 0x2E, - 0x47, 0xFF, 0x62, 0x32, 0x30, 0x93, 0xC2, 0xB7, - 0xA6, 0xC0, 0xE2, 0xC1, 0x68, 0x21, 0xCD, 0x7C, - 0xEC, 0x92, 0x18, 0x4D, 0xF4, 0xBB, 0x6E, 0x2B, - 0x62, 0x6A, 0x44, 0x78, 0x03, 0x90, 0x63, 0xAF, - 0xEE, 0xB0, 0xD2, 0x87, 0xF2, 0x42, 0x19, 0x20, - 0x78, 0x98, 0xCC, 0xE7, 0xAD, 0xE0, 0x63, 0x9C - }, - { - 0xDD, 0x7F, 0x2F, 0x44, 0xA4, 0x02, 0xA0, 0x1E, - 0x82, 0x16, 0xB1, 0x03, 0xA4, 0xE7, 0x23, 0x5C, - 0x28, 0x30, 0x31, 0x9D, 0x56, 0xAF, 0x63, 0x9F, - 0x23, 0xC4, 0x8C, 0x27, 0x59, 0xAB, 0xA6, 0xEB, - 0x5E, 0xEE, 0xE3, 0x8C, 0x29, 0x8E, 0xBE, 0x41, - 0x98, 0x26, 0x7A, 0x00, 0xEB, 0x2A, 0x08, 0xD9, - 0x3A, 0x50, 0x37, 0x03, 0x17, 0x1C, 0x77, 0x33, - 0x38, 0x62, 0x10, 0x10, 0x55, 0xBD, 0x7A, 0xD2 - }, - { - 0x4C, 0xB8, 0x46, 0x59, 0x61, 0x93, 0xF7, 0xF2, - 0x78, 0xAA, 0xAA, 0xC5, 0xCC, 0xFF, 0xD5, 0x35, - 0x7A, 0xB0, 0xD1, 0x24, 0x5F, 0x69, 0x79, 0xD1, - 0x41, 0xA4, 0x71, 0xBD, 0xAB, 0x55, 0xE2, 0x38, - 0xB1, 0xAE, 0xD6, 0x7B, 0x73, 0x39, 0x95, 0x04, - 0xB9, 0x7D, 0xF1, 0xA2, 0x5E, 0xB6, 0xFE, 0x27, - 0x2B, 0x5C, 0xD4, 0x96, 0xA7, 0xC8, 0xA0, 0x60, - 0x92, 0x6E, 0x74, 0x04, 0xFD, 0xA0, 0x79, 0x0D - }, - { - 0x6F, 0x44, 0xEC, 0xDA, 0xE1, 0x4E, 0x3B, 0x81, - 0xA1, 0x91, 0x22, 0x03, 0x01, 0x5F, 0x59, 0x18, - 0xEA, 0xC6, 0xFB, 0xF4, 0x96, 0x60, 0x10, 0xF4, - 0x9D, 0x2B, 0xC2, 0xBC, 0xEF, 0xE7, 0xB1, 0xDF, - 0xEC, 0x5C, 0x83, 0x5D, 0x7D, 0x87, 0xA4, 0x43, - 0x71, 0xF1, 0x5A, 0x6C, 0x08, 0x42, 0x52, 0xB9, - 0x34, 0x65, 0x26, 0x42, 0x72, 0xA4, 0x10, 0xD5, - 0x0F, 0x89, 0xA1, 0x17, 0xF3, 0x1A, 0xF4, 0x63 - }, - { - 0x1F, 0x70, 0x5F, 0x6E, 0x9F, 0x07, 0x0D, 0x87, - 0xFD, 0xE8, 0xE2, 0x77, 0x46, 0x74, 0xFA, 0x9B, - 0xF1, 0x20, 0xD2, 0x88, 0xEB, 0x0B, 0xE7, 0xAA, - 0x12, 0x8D, 0xFB, 0x5D, 0x10, 0x11, 0xCE, 0x1F, - 0xDA, 0x99, 0xB2, 0x55, 0x22, 0x66, 0x65, 0xD8, - 0x3F, 0x63, 0x4E, 0x8F, 0xCA, 0xBD, 0xA9, 0xA2, - 0x3C, 0x03, 0x51, 0x5E, 0x9C, 0xFE, 0xCE, 0x6E, - 0x94, 0xA8, 0xEC, 0x92, 0xE4, 0xED, 0xEC, 0xB7 - }, - { - 0x2D, 0x96, 0xC5, 0xB0, 0x15, 0x74, 0x72, 0x2B, - 0x81, 0x7F, 0xEB, 0x48, 0x6C, 0x5F, 0xC9, 0x8F, - 0x5F, 0x84, 0x61, 0xF4, 0xCE, 0xE9, 0x90, 0x5A, - 0xF2, 0x06, 0xD4, 0x72, 0x33, 0x86, 0xD1, 0xC4, - 0xC7, 0xCA, 0xC5, 0x84, 0x00, 0x28, 0xD7, 0xAF, - 0xED, 0x0E, 0x38, 0xAD, 0x13, 0x96, 0x28, 0xEB, - 0x6A, 0xF9, 0x2B, 0x4B, 0x88, 0xEB, 0xF0, 0x9B, - 0x1F, 0xA0, 0x47, 0xFB, 0xE1, 0x0B, 0xC3, 0x1D - }, - { - 0x65, 0xDA, 0x78, 0x0A, 0x0A, 0x37, 0x47, 0x9D, - 0xD8, 0xF4, 0xD6, 0x55, 0x64, 0xF9, 0xA7, 0x08, - 0x9E, 0x42, 0x07, 0xEB, 0x16, 0xAC, 0xA3, 0xF6, - 0x55, 0x31, 0xCF, 0xEE, 0x76, 0x25, 0xBA, 0x13, - 0x80, 0xA4, 0x97, 0xB6, 0x24, 0x72, 0xFC, 0x7E, - 0x00, 0x07, 0xA6, 0xB0, 0x35, 0x61, 0x04, 0x16, - 0xA5, 0xF8, 0x2C, 0x10, 0x82, 0xFA, 0x06, 0x5C, - 0x46, 0xDD, 0xEE, 0x49, 0x40, 0xD1, 0xFC, 0x46 - }, - { - 0x1C, 0x09, 0xA3, 0xB3, 0x80, 0xB8, 0xA7, 0xFC, - 0x33, 0x3F, 0xD2, 0x71, 0x4D, 0xF7, 0x12, 0x9B, - 0x44, 0xA4, 0x67, 0x68, 0xBA, 0xCF, 0x0A, 0x67, - 0xA3, 0x8A, 0x47, 0xB3, 0xAB, 0x31, 0xF5, 0x1B, - 0x05, 0x33, 0xC2, 0xAA, 0x2B, 0x4B, 0x7B, 0xBB, - 0x6A, 0xE5, 0xED, 0xF3, 0xDC, 0xB0, 0xEC, 0xC1, - 0xA2, 0x83, 0xE8, 0x43, 0xF2, 0x90, 0x7B, 0x34, - 0x1F, 0x17, 0x9A, 0xFD, 0x8B, 0x67, 0xDA, 0x90 - }, - { - 0x67, 0x88, 0x8B, 0x83, 0xFA, 0xAF, 0xBB, 0x62, - 0x29, 0x34, 0xB8, 0xD5, 0x59, 0x63, 0xE1, 0x86, - 0x15, 0x3E, 0x59, 0x51, 0x88, 0x7C, 0x7F, 0x4A, - 0x76, 0x35, 0xC7, 0x98, 0xD9, 0xA5, 0x82, 0x94, - 0xBE, 0x26, 0xA3, 0xC5, 0x49, 0xC9, 0xFD, 0x59, - 0x86, 0xAB, 0xD1, 0x9F, 0x40, 0x1E, 0xE2, 0x4E, - 0xDA, 0x36, 0x02, 0x04, 0x2A, 0xD3, 0x83, 0x35, - 0x7A, 0x31, 0x7D, 0x38, 0x07, 0x3B, 0x38, 0xCE - }, - { - 0xB4, 0xF7, 0x99, 0x63, 0xCA, 0x31, 0xBB, 0x62, - 0x26, 0x5D, 0xD9, 0x29, 0xAF, 0x7D, 0x51, 0x27, - 0x2F, 0xA6, 0x63, 0x1D, 0xE7, 0xFA, 0x35, 0xF7, - 0xA6, 0xB0, 0x3F, 0x9F, 0xCF, 0xDB, 0x8E, 0x3B, - 0x5B, 0xAC, 0xE3, 0x35, 0x91, 0xB7, 0xEC, 0x2C, - 0xFA, 0xB4, 0x9C, 0x91, 0xA6, 0xDB, 0x1F, 0xF8, - 0xF6, 0x78, 0x6D, 0x08, 0xF4, 0x4E, 0x80, 0x62, - 0xD2, 0xFF, 0x69, 0x6A, 0x7D, 0x98, 0x41, 0x42 - }, - { - 0x40, 0x84, 0x83, 0x69, 0x7B, 0xB6, 0xF9, 0xD0, - 0x11, 0xA1, 0xF2, 0x9A, 0x23, 0xC2, 0x78, 0xA8, - 0x1D, 0x37, 0x57, 0x8D, 0xCC, 0xCF, 0x42, 0x3B, - 0xDF, 0x48, 0x93, 0x37, 0xF1, 0x82, 0xEA, 0xB7, - 0x9A, 0x50, 0xB0, 0x5F, 0x3D, 0x2C, 0xCC, 0x49, - 0x13, 0x37, 0xC7, 0xE4, 0x1F, 0x30, 0x79, 0x3B, - 0xD2, 0x7D, 0x76, 0x61, 0xC2, 0xE3, 0x04, 0xC9, - 0x46, 0xA5, 0xA4, 0x01, 0xAF, 0x8D, 0x94, 0x6F - }, - { - 0xEE, 0xB5, 0xAD, 0xE1, 0xAB, 0x97, 0xE7, 0x15, - 0x43, 0x43, 0xA4, 0x6E, 0xB4, 0xCD, 0xD2, 0xA7, - 0x73, 0xF3, 0x63, 0x01, 0xED, 0xC6, 0xA1, 0xBC, - 0x1D, 0xD6, 0x48, 0x0E, 0x08, 0xF5, 0x87, 0x65, - 0xCB, 0x93, 0x87, 0x82, 0x92, 0x3B, 0xC0, 0x1F, - 0x8E, 0x0C, 0x61, 0xC6, 0xBE, 0x0D, 0xD1, 0xAB, - 0x4C, 0x18, 0xCB, 0x15, 0xED, 0x52, 0x10, 0x11, - 0x24, 0x05, 0xF1, 0xEA, 0x8F, 0x2E, 0x8C, 0x4E - }, - { - 0x71, 0x4A, 0xD1, 0x85, 0xF1, 0xEE, 0xC4, 0x3F, - 0x46, 0xB6, 0x7E, 0x99, 0x2D, 0x2D, 0x38, 0xBC, - 0x31, 0x49, 0xE3, 0x7D, 0xA7, 0xB4, 0x47, 0x48, - 0xD4, 0xD1, 0x4C, 0x16, 0x1E, 0x08, 0x78, 0x02, - 0x04, 0x42, 0x14, 0x95, 0x79, 0xA8, 0x65, 0xD8, - 0x04, 0xB0, 0x49, 0xCD, 0x01, 0x55, 0xBA, 0x98, - 0x33, 0x78, 0x75, 0x7A, 0x13, 0x88, 0x30, 0x1B, - 0xDC, 0x0F, 0xAE, 0x2C, 0xEA, 0xEA, 0x07, 0xDD - }, - { - 0x22, 0xB8, 0x24, 0x9E, 0xAF, 0x72, 0x29, 0x64, - 0xCE, 0x42, 0x4F, 0x71, 0xA7, 0x4D, 0x03, 0x8F, - 0xF9, 0xB6, 0x15, 0xFB, 0xA5, 0xC7, 0xC2, 0x2C, - 0xB6, 0x27, 0x97, 0xF5, 0x39, 0x82, 0x24, 0xC3, - 0xF0, 0x72, 0xEB, 0xC1, 0xDA, 0xCB, 0xA3, 0x2F, - 0xC6, 0xF6, 0x63, 0x60, 0xB3, 0xE1, 0x65, 0x8D, - 0x0F, 0xA0, 0xDA, 0x1E, 0xD1, 0xC1, 0xDA, 0x66, - 0x2A, 0x20, 0x37, 0xDA, 0x82, 0x3A, 0x33, 0x83 - }, - { - 0xB8, 0xE9, 0x03, 0xE6, 0x91, 0xB9, 0x92, 0x78, - 0x25, 0x28, 0xF8, 0xDB, 0x96, 0x4D, 0x08, 0xE3, - 0xBA, 0xAF, 0xBD, 0x08, 0xBA, 0x60, 0xC7, 0x2A, - 0xEC, 0x0C, 0x28, 0xEC, 0x6B, 0xFE, 0xCA, 0x4B, - 0x2E, 0xC4, 0xC4, 0x6F, 0x22, 0xBF, 0x62, 0x1A, - 0x5D, 0x74, 0xF7, 0x5C, 0x0D, 0x29, 0x69, 0x3E, - 0x56, 0xC5, 0xC5, 0x84, 0xF4, 0x39, 0x9E, 0x94, - 0x2F, 0x3B, 0xD8, 0xD3, 0x86, 0x13, 0xE6, 0x39 - }, - { - 0xD5, 0xB4, 0x66, 0xFF, 0x1F, 0xD6, 0x8C, 0xFA, - 0x8E, 0xDF, 0x0B, 0x68, 0x02, 0x44, 0x8F, 0x30, - 0x2D, 0xCC, 0xDA, 0xF5, 0x66, 0x28, 0x78, 0x6B, - 0x9D, 0xA0, 0xF6, 0x62, 0xFD, 0xA6, 0x90, 0x26, - 0x6B, 0xD4, 0x0A, 0xB6, 0xF0, 0xBE, 0xC0, 0x43, - 0xF1, 0x01, 0x28, 0xB3, 0x3D, 0x05, 0xDB, 0x82, - 0xD4, 0xAB, 0x26, 0x8A, 0x4F, 0x91, 0xAC, 0x42, - 0x86, 0x79, 0x5F, 0xC0, 0xF7, 0xCB, 0x48, 0x5C - }, - { - 0x0A, 0x1E, 0x8C, 0x0A, 0x8C, 0x48, 0xB8, 0x4B, - 0x71, 0xBA, 0x0F, 0xE5, 0x6F, 0xA0, 0x56, 0x09, - 0x8C, 0xA6, 0x92, 0xE9, 0x2F, 0x27, 0x6E, 0x85, - 0xB3, 0x38, 0x26, 0xCD, 0x78, 0x75, 0xFC, 0xF8, - 0x83, 0x85, 0x13, 0x1B, 0x43, 0xDF, 0x74, 0x53, - 0x2E, 0xAA, 0x86, 0xCF, 0x17, 0x1F, 0x50, 0x76, - 0xE6, 0xD1, 0x7B, 0x1C, 0x75, 0xFB, 0xA1, 0xDB, - 0x00, 0x1B, 0x6E, 0x66, 0x97, 0x7C, 0xB8, 0xD7 - }, - { - 0x65, 0xAA, 0x17, 0x99, 0x14, 0x36, 0x93, 0xAB, - 0xD9, 0xCB, 0x21, 0x8D, 0x9B, 0x5E, 0xC6, 0x0C, - 0x0E, 0xDD, 0xB0, 0x67, 0xE6, 0xA3, 0x2F, 0x76, - 0x79, 0x60, 0x10, 0xAC, 0xB1, 0x1A, 0xD0, 0x13, - 0x6C, 0xE4, 0x9F, 0x97, 0x6E, 0x74, 0xF8, 0x95, - 0x04, 0x2F, 0x7C, 0xBF, 0x13, 0xFB, 0x73, 0xD1, - 0x9D, 0xC8, 0x89, 0xD7, 0xE9, 0x03, 0x46, 0x9D, - 0xEB, 0x33, 0x73, 0x1F, 0x24, 0x06, 0xB6, 0x63 - }, - { - 0xDE, 0xB7, 0x12, 0xB9, 0xCC, 0x64, 0xF5, 0x88, - 0x14, 0x86, 0x0B, 0x51, 0xFA, 0x89, 0xAD, 0x8A, - 0x92, 0x6A, 0x69, 0x08, 0xC7, 0x96, 0xDE, 0x55, - 0x7F, 0x90, 0xCF, 0xAD, 0xB0, 0xC6, 0x2C, 0x07, - 0x87, 0x2F, 0x33, 0xFE, 0x18, 0x4E, 0x5E, 0x21, - 0x2A, 0x3C, 0x5C, 0x37, 0x31, 0x74, 0x18, 0x44, - 0x6E, 0xFD, 0x95, 0x61, 0x3F, 0x61, 0x8A, 0x35, - 0xF7, 0xD2, 0x78, 0x9E, 0xFE, 0x0D, 0x96, 0x60 - }, - { - 0xB4, 0x2F, 0x4A, 0x40, 0xB3, 0xC8, 0x8B, 0xCE, - 0xCF, 0xE3, 0x28, 0xC8, 0x46, 0xBF, 0x06, 0x48, - 0xA1, 0x69, 0x90, 0xCA, 0x53, 0x91, 0x95, 0xC0, - 0xC1, 0xDC, 0x8D, 0x70, 0x30, 0x80, 0x67, 0x68, - 0x5A, 0xF6, 0x77, 0xAD, 0x65, 0xAC, 0x0C, 0x7A, - 0x9B, 0xCF, 0xA8, 0xF7, 0xAC, 0xC0, 0xAA, 0xCF, - 0x45, 0xCA, 0x18, 0xAC, 0x83, 0x1F, 0xED, 0x64, - 0x4E, 0xC3, 0xD9, 0x28, 0x31, 0x01, 0xFF, 0xEF - }, - { - 0xED, 0xCF, 0x6C, 0x81, 0xCC, 0xF1, 0x6E, 0x11, - 0xDD, 0xF7, 0x19, 0xA3, 0x3D, 0xD0, 0xE5, 0x34, - 0x9C, 0xAB, 0xAC, 0x5C, 0xFA, 0xE5, 0x97, 0x00, - 0x98, 0x40, 0xE1, 0xC3, 0x93, 0x62, 0xC0, 0xF1, - 0x19, 0x82, 0xFE, 0x2C, 0x27, 0x65, 0x85, 0x9A, - 0x94, 0x26, 0x2D, 0xA2, 0x8D, 0xD3, 0x37, 0x3D, - 0x52, 0x26, 0x93, 0x89, 0x75, 0x11, 0xEB, 0xA5, - 0xE0, 0x7B, 0x8B, 0xC6, 0xB6, 0x06, 0x4D, 0xC0 - }, - { - 0x46, 0xB9, 0x62, 0xD2, 0x28, 0x36, 0x94, 0xD2, - 0x79, 0x75, 0xDC, 0xBF, 0x32, 0x56, 0x4C, 0x9B, - 0x04, 0x03, 0x2B, 0x30, 0xA9, 0x3E, 0x05, 0x8F, - 0xB7, 0x7B, 0x2B, 0x71, 0x8B, 0x4A, 0xD5, 0xFB, - 0x78, 0x9A, 0xB7, 0xD7, 0xAA, 0x90, 0x85, 0x2D, - 0xA2, 0xBF, 0xB6, 0xB3, 0x93, 0xB0, 0x9F, 0x98, - 0xE8, 0x69, 0xB1, 0x6E, 0x41, 0x0E, 0x7D, 0xE2, - 0x30, 0xB1, 0x79, 0xF6, 0x2E, 0xB5, 0x74, 0x71 - }, - { - 0x29, 0x03, 0x6C, 0x3F, 0x53, 0x82, 0xE3, 0x5D, - 0xE7, 0xA6, 0x9F, 0xA7, 0xA6, 0x3E, 0xC7, 0xBD, - 0xCB, 0xC4, 0xE0, 0xCC, 0x5A, 0x7B, 0x64, 0x14, - 0xCF, 0x44, 0xBF, 0x9A, 0x83, 0x83, 0xEF, 0xB5, - 0x97, 0x23, 0x50, 0x6F, 0x0D, 0x51, 0xAD, 0x50, - 0xAC, 0x1E, 0xAC, 0xF7, 0x04, 0x30, 0x8E, 0x8A, - 0xEC, 0xB9, 0x66, 0xF6, 0xAC, 0x94, 0x1D, 0xB1, - 0xCD, 0xE4, 0xB5, 0x9E, 0x84, 0xC1, 0xEB, 0xBA - }, - { - 0x17, 0x3F, 0x8A, 0xB8, 0x93, 0x3E, 0xB0, 0x7C, - 0xC5, 0xFD, 0x6E, 0x4B, 0xCE, 0xBA, 0xE1, 0xFF, - 0x35, 0xC7, 0x87, 0x9B, 0x93, 0x8A, 0x5A, 0x15, - 0x79, 0xEA, 0x02, 0xF3, 0x83, 0x32, 0x48, 0x86, - 0xC7, 0x0E, 0xD9, 0x10, 0x9D, 0xE1, 0x69, 0x0B, - 0x8E, 0xE8, 0x01, 0xBC, 0x95, 0x9B, 0x21, 0xD3, - 0x81, 0x17, 0xEB, 0xB8, 0x4A, 0xB5, 0x6F, 0x88, - 0xF8, 0xA3, 0x72, 0x62, 0x00, 0x2D, 0xD9, 0x8E - }, - { - 0xC6, 0xAF, 0xA6, 0xA1, 0x91, 0x93, 0x1F, 0xD4, - 0x5C, 0x3B, 0xAD, 0xBA, 0x72, 0x6E, 0x68, 0xA9, - 0xBC, 0x73, 0x88, 0xC8, 0xCF, 0x37, 0xAD, 0xEC, - 0x7C, 0x64, 0x56, 0x1C, 0xF4, 0x81, 0xFD, 0x25, - 0x9A, 0x64, 0x6C, 0x8B, 0xD8, 0x43, 0xE7, 0x70, - 0x9E, 0x11, 0xE6, 0x4D, 0xCF, 0xD5, 0xDF, 0xFF, - 0xED, 0x79, 0x23, 0x5C, 0x68, 0x9B, 0x42, 0x00, - 0xFE, 0x7A, 0xC8, 0xDF, 0xDA, 0xDD, 0xEC, 0xE0 - }, - { - 0xA6, 0xDC, 0xCD, 0x8C, 0x19, 0x26, 0x64, 0x88, - 0xBF, 0x77, 0xB9, 0xF2, 0x4B, 0x91, 0x43, 0xDE, - 0xF1, 0xFE, 0xD6, 0x1D, 0x0C, 0x60, 0xB5, 0x00, - 0x0A, 0x52, 0x3F, 0x45, 0x0D, 0xA2, 0x3D, 0x74, - 0xE4, 0xE3, 0xF6, 0xEF, 0x04, 0x09, 0x0D, 0x10, - 0x66, 0xB6, 0xAC, 0xE8, 0x5A, 0xBC, 0x0F, 0x03, - 0x01, 0x73, 0xF5, 0x28, 0x17, 0x72, 0x7C, 0x4E, - 0x40, 0x43, 0x2D, 0xD3, 0x4C, 0x6E, 0xF9, 0xF0 - }, - { - 0xAA, 0xF8, 0x90, 0x8D, 0x54, 0x6E, 0x4F, 0x1E, - 0x31, 0x4C, 0x00, 0xE9, 0xD2, 0xE8, 0x85, 0x5C, - 0xB2, 0x56, 0x44, 0x5A, 0xAE, 0x3E, 0xCA, 0x44, - 0x23, 0x83, 0x22, 0xAE, 0xC7, 0x40, 0x34, 0xA1, - 0x45, 0x8A, 0x29, 0x36, 0x75, 0xDA, 0xD9, 0x49, - 0x40, 0x8D, 0xE5, 0x55, 0x4F, 0x22, 0xD7, 0x34, - 0x54, 0xF3, 0xF0, 0x70, 0x9C, 0xBC, 0xCC, 0x85, - 0xCB, 0x05, 0x3A, 0x6F, 0x50, 0x38, 0x91, 0xA1 - }, - { - 0x52, 0x5F, 0x4A, 0xAB, 0x9C, 0x32, 0x7D, 0x2A, - 0x6A, 0x3C, 0x9D, 0xF8, 0x1F, 0xB7, 0xBE, 0x97, - 0xEE, 0x03, 0xE3, 0xF7, 0xCE, 0x33, 0x21, 0x1C, - 0x47, 0x78, 0x8A, 0xCD, 0x13, 0x46, 0x40, 0xDD, - 0x90, 0xAD, 0x74, 0x99, 0x2D, 0x3D, 0xD6, 0xAC, - 0x80, 0x63, 0x50, 0xF3, 0xBA, 0xBC, 0x7F, 0xE1, - 0x98, 0xA6, 0x1D, 0xB3, 0x2D, 0x4A, 0xD1, 0xD6, - 0x56, 0x9A, 0xE8, 0x41, 0x31, 0x04, 0xDE, 0xA4 - }, - { - 0x2D, 0xAC, 0xCD, 0x88, 0x71, 0x9D, 0x0A, 0x00, - 0xB5, 0x2C, 0x6E, 0xB7, 0x9E, 0x1C, 0xA8, 0xB4, - 0xA1, 0xB4, 0xB4, 0x4F, 0xFA, 0x20, 0x88, 0x9F, - 0x23, 0x63, 0xEF, 0x5C, 0x0D, 0x73, 0x7F, 0x1F, - 0x81, 0xF5, 0x0D, 0xA1, 0xCA, 0xAC, 0x23, 0x1D, - 0x6F, 0xCB, 0x48, 0x89, 0x5E, 0x72, 0x99, 0xB7, - 0x7A, 0xF8, 0x1F, 0x0A, 0xA4, 0xA7, 0x61, 0x8A, - 0xD2, 0x4B, 0x7A, 0xAF, 0xC8, 0xE3, 0xA2, 0xBE - }, - { - 0x7D, 0x28, 0x6F, 0x1F, 0x72, 0x1E, 0xC2, 0xD2, - 0x11, 0x5E, 0xF4, 0xCC, 0xD8, 0x28, 0x58, 0xA4, - 0xD5, 0x12, 0x21, 0x13, 0x55, 0xD4, 0xFC, 0x58, - 0xE5, 0x34, 0xBF, 0xA5, 0x9C, 0x2E, 0x1B, 0xF5, - 0x52, 0xA9, 0x6D, 0xC4, 0xB3, 0xE4, 0x6B, 0x01, - 0x28, 0x65, 0xDA, 0x88, 0x13, 0x4C, 0xF0, 0x4E, - 0x73, 0x1B, 0x19, 0x30, 0x75, 0x9E, 0x15, 0x8F, - 0xF6, 0x20, 0xB6, 0xEC, 0x5A, 0xAF, 0xD0, 0x12 - }, - { - 0x21, 0x82, 0x6B, 0x95, 0x29, 0xC4, 0xBC, 0x51, - 0x91, 0x47, 0xF5, 0xF9, 0xFE, 0x6D, 0xB8, 0x78, - 0x34, 0x52, 0x15, 0xE5, 0x09, 0x4F, 0x4E, 0x99, - 0xB1, 0x31, 0xED, 0x54, 0xE2, 0x49, 0x53, 0xCE, - 0xE9, 0xAD, 0xB7, 0x18, 0xD1, 0x74, 0x3E, 0x6C, - 0x27, 0xFC, 0x94, 0x51, 0x6A, 0x99, 0x22, 0xFB, - 0x97, 0x5A, 0x78, 0x16, 0xB8, 0xAA, 0xB0, 0x21, - 0x12, 0x60, 0x8C, 0x03, 0x2B, 0xF1, 0x38, 0xE3 - }, - { - 0xC1, 0x68, 0x9C, 0x69, 0x8A, 0xB0, 0x65, 0xF6, - 0x2E, 0xEE, 0x65, 0xDD, 0xCA, 0x67, 0x6B, 0xAA, - 0x45, 0xB5, 0x2F, 0x30, 0x8A, 0xFA, 0x80, 0x4A, - 0xB4, 0xAA, 0x6A, 0xB8, 0x4B, 0x7A, 0xC1, 0xAA, - 0x1D, 0xFF, 0x07, 0x17, 0x56, 0x10, 0xB1, 0x2A, - 0xE1, 0x1F, 0x27, 0xB7, 0xC4, 0x30, 0xAF, 0xD5, - 0x75, 0x56, 0xBD, 0x18, 0x1D, 0x02, 0x83, 0x2C, - 0xD8, 0xD0, 0xA5, 0xFD, 0xC3, 0x02, 0x01, 0x24 - }, - { - 0xA1, 0xA6, 0x28, 0x17, 0x47, 0xE3, 0x4D, 0x3E, - 0xDE, 0x5E, 0x93, 0x34, 0x01, 0x74, 0x7C, 0xA7, - 0xF7, 0x66, 0x28, 0xB6, 0x14, 0xC8, 0xA3, 0x94, - 0xF5, 0x02, 0x56, 0x2B, 0xFE, 0xE0, 0xB9, 0x94, - 0xEC, 0xB6, 0x5F, 0xBF, 0xE1, 0xFF, 0x70, 0x67, - 0xDC, 0xB0, 0x1D, 0x02, 0xA9, 0x2B, 0xA4, 0x62, - 0x20, 0x75, 0x87, 0xCE, 0xF7, 0xDC, 0x2C, 0xFD, - 0xB4, 0x58, 0x48, 0x48, 0xAD, 0x55, 0x91, 0x4A - }, - { - 0x00, 0x70, 0xA0, 0x19, 0x0A, 0xA6, 0x96, 0x57, - 0x2D, 0x85, 0x3F, 0x1D, 0x24, 0xAB, 0x63, 0x08, - 0x48, 0xAC, 0x56, 0xAD, 0x5C, 0x2E, 0xBF, 0xCF, - 0xDE, 0x27, 0xD1, 0x11, 0xCD, 0x55, 0x93, 0x9C, - 0x1E, 0x4D, 0x07, 0x87, 0x2D, 0xDE, 0x7C, 0xE7, - 0x8B, 0x53, 0x4B, 0x53, 0x0F, 0x0A, 0x39, 0x6E, - 0x86, 0xAF, 0x9D, 0x57, 0x53, 0x54, 0xB5, 0xD7, - 0xE3, 0x4A, 0xCD, 0xE1, 0x8C, 0xC7, 0x67, 0xAE - }, - { - 0x51, 0xB9, 0xB5, 0xED, 0x19, 0x3F, 0xD4, 0xB1, - 0xA3, 0xA9, 0x2B, 0x46, 0xBD, 0x4B, 0xD1, 0xF6, - 0xEC, 0x6B, 0x38, 0xA6, 0x0F, 0x2D, 0x02, 0x61, - 0xD7, 0x2A, 0xBF, 0xD1, 0x64, 0x36, 0x12, 0x8D, - 0xCB, 0xF2, 0x2C, 0x25, 0xE3, 0xE3, 0xC4, 0x3F, - 0xE4, 0xD2, 0x9D, 0xB9, 0x12, 0x4D, 0x03, 0x33, - 0x30, 0x18, 0x45, 0x92, 0xD2, 0x0C, 0x5B, 0x08, - 0x2C, 0x23, 0x20, 0x64, 0x54, 0xCB, 0x3D, 0xD7 - }, - { - 0x57, 0x8F, 0x24, 0x27, 0x46, 0x91, 0x4E, 0x36, - 0xD0, 0xD9, 0xD4, 0x80, 0x96, 0x89, 0x57, 0x12, - 0x16, 0xA4, 0x3E, 0x47, 0x33, 0x32, 0x39, 0x51, - 0x62, 0x0F, 0x5E, 0xE7, 0x8C, 0xCF, 0xEE, 0x91, - 0x9B, 0xF5, 0x5F, 0x28, 0x7B, 0x45, 0xA7, 0x3D, - 0x44, 0x85, 0xAC, 0x74, 0x22, 0x87, 0x92, 0x39, - 0x65, 0x3B, 0x05, 0x91, 0xC3, 0x6C, 0x86, 0x69, - 0x41, 0xF8, 0xAF, 0xFE, 0x4A, 0xE5, 0x6E, 0x9E - }, - { - 0x94, 0x71, 0x30, 0xEF, 0x0B, 0x94, 0x8E, 0xE0, - 0x45, 0x81, 0xAB, 0xA3, 0xE2, 0xCC, 0x4C, 0xEF, - 0xC3, 0x8C, 0xCE, 0xDC, 0x86, 0x17, 0x92, 0xB7, - 0xB5, 0xDC, 0xD9, 0xD9, 0x36, 0x1C, 0x72, 0x4A, - 0x12, 0x20, 0x03, 0xBF, 0x79, 0x6C, 0xE0, 0x97, - 0x98, 0x00, 0xAD, 0xAB, 0xC7, 0x45, 0x6F, 0x17, - 0x3A, 0xE5, 0x26, 0x93, 0x15, 0xAF, 0xC0, 0x1B, - 0x60, 0x6D, 0xB2, 0x9C, 0x75, 0x50, 0xE8, 0xCA - }, - { - 0xC8, 0x52, 0xE6, 0x77, 0xF7, 0x7B, 0x14, 0xB5, - 0x85, 0xBD, 0x10, 0x2A, 0x0F, 0x14, 0x42, 0x43, - 0x05, 0x9D, 0xAB, 0xEC, 0x7C, 0xB0, 0x1F, 0xFA, - 0x61, 0xDF, 0x19, 0xFC, 0xE8, 0xAB, 0x43, 0x6B, - 0xF5, 0xE2, 0xD5, 0xC7, 0x9A, 0xA2, 0xD7, 0xB6, - 0x77, 0xF6, 0xC3, 0x75, 0xE9, 0x34, 0x3D, 0x34, - 0x2E, 0x4F, 0xF4, 0xE3, 0xAB, 0x00, 0x1B, 0xC7, - 0x98, 0x8C, 0x3C, 0x7A, 0x83, 0xCC, 0xB6, 0x9F - }, - { - 0x01, 0x19, 0x75, 0x26, 0x91, 0x7A, 0xC2, 0xC7, - 0xBC, 0x53, 0x95, 0x19, 0xE6, 0x8B, 0xB2, 0x79, - 0x81, 0x35, 0xF6, 0x03, 0x3E, 0xD5, 0x8F, 0x5C, - 0x45, 0x1E, 0x0C, 0xE9, 0x46, 0xAF, 0xF0, 0xF9, - 0x8D, 0xFD, 0xD1, 0x51, 0x01, 0x73, 0x1A, 0xC1, - 0x66, 0x12, 0x6E, 0xAF, 0xB5, 0xE7, 0xCB, 0xE2, - 0xE2, 0x72, 0xEE, 0x23, 0x3F, 0x34, 0xE5, 0xF3, - 0xF8, 0xEA, 0x3D, 0x2D, 0x12, 0x24, 0x82, 0xFB - }, - { - 0x05, 0x9C, 0x90, 0x85, 0x89, 0x5E, 0xB7, 0x18, - 0x30, 0x4E, 0x2D, 0xDA, 0x78, 0x68, 0x6B, 0xD9, - 0x57, 0x49, 0x81, 0x5A, 0x5E, 0xE9, 0x02, 0x51, - 0x0B, 0x00, 0x9A, 0xF6, 0x92, 0x48, 0xB6, 0xA7, - 0xA7, 0x2F, 0xF8, 0xA6, 0x28, 0xD8, 0x17, 0x73, - 0xE1, 0x1D, 0x5A, 0x1E, 0x7F, 0x69, 0x7A, 0x44, - 0x9B, 0x7A, 0x1E, 0x27, 0x12, 0xD5, 0xCF, 0xAE, - 0x7A, 0xB2, 0x65, 0x07, 0xD1, 0x11, 0x29, 0x18 - }, - { - 0x29, 0x52, 0x43, 0xBD, 0x75, 0x8C, 0xF2, 0x1C, - 0x80, 0x31, 0x25, 0xFC, 0xF3, 0x21, 0xDE, 0x5F, - 0x97, 0x98, 0x7C, 0x8D, 0xB3, 0xBB, 0x3C, 0xB5, - 0x1F, 0xF9, 0x7C, 0x4C, 0xDA, 0xC9, 0xD3, 0xBF, - 0x0A, 0x67, 0xCE, 0xE7, 0xED, 0x35, 0x0A, 0x41, - 0xFD, 0xE6, 0xAB, 0xCC, 0x25, 0x4F, 0xBC, 0x9F, - 0x8E, 0x6B, 0x3E, 0x3C, 0xCE, 0xCB, 0xD0, 0xE4, - 0xA6, 0x40, 0xA2, 0x0F, 0x36, 0x2B, 0xA3, 0xA0 - }, - { - 0xDD, 0x82, 0x32, 0xD2, 0x41, 0x2C, 0xCE, 0xEC, - 0xB5, 0x12, 0x31, 0x91, 0xF6, 0xE9, 0x22, 0x1E, - 0x85, 0x1E, 0xCC, 0xE0, 0xFA, 0xEB, 0xF0, 0x50, - 0x5F, 0x2A, 0xEE, 0xFF, 0x8A, 0x8C, 0x92, 0xD4, - 0x1D, 0xAC, 0xF1, 0x77, 0xBD, 0xAE, 0x27, 0x76, - 0x3E, 0xA4, 0xA8, 0x62, 0x05, 0xEF, 0x76, 0x34, - 0xF7, 0xA6, 0x87, 0xCC, 0x44, 0xBB, 0xBB, 0xDE, - 0xEE, 0x5E, 0x11, 0xE6, 0x5F, 0x9F, 0xBD, 0x69 - }, - { - 0xB0, 0x46, 0xB6, 0x83, 0x71, 0x6D, 0x31, 0xC9, - 0x14, 0xC7, 0x0B, 0x10, 0xF7, 0x64, 0x6D, 0xA3, - 0x1E, 0xFA, 0xB2, 0x23, 0x63, 0x47, 0x45, 0x9C, - 0xF8, 0xFA, 0x2C, 0x09, 0x12, 0x34, 0x31, 0xF7, - 0x28, 0x07, 0xF1, 0x1D, 0x86, 0x7C, 0x37, 0x70, - 0xB1, 0xF0, 0x61, 0xD5, 0x6C, 0xA0, 0xE5, 0xB1, - 0xE8, 0x8A, 0x6B, 0x44, 0xA3, 0x3C, 0xF9, 0x3E, - 0x18, 0xBC, 0xC9, 0xCE, 0xBB, 0xA5, 0xAD, 0xE7 - }, - { - 0x20, 0xE5, 0xA2, 0x55, 0x05, 0x8B, 0xE5, 0x1E, - 0x1A, 0x62, 0x9B, 0x4E, 0xBF, 0x81, 0xE5, 0xCB, - 0xE0, 0x78, 0x1C, 0xB6, 0x7C, 0xA4, 0xE5, 0x7B, - 0xA8, 0x6B, 0x30, 0x88, 0x96, 0xBC, 0xE7, 0x38, - 0x20, 0xEB, 0x08, 0x43, 0x1C, 0xE8, 0xC9, 0xBC, - 0x58, 0x10, 0xCC, 0x8D, 0x8B, 0x9C, 0x9D, 0x6F, - 0xCF, 0x83, 0x4E, 0x42, 0xEA, 0x33, 0xEF, 0x73, - 0xCE, 0xC4, 0x7D, 0x71, 0x3B, 0x6D, 0x8D, 0xFD - }, - { - 0x1E, 0x48, 0x04, 0xF9, 0xC0, 0xB1, 0xE8, 0x2B, - 0x9E, 0xD3, 0x63, 0xBD, 0xE4, 0x47, 0x28, 0xAC, - 0xF7, 0xD0, 0x90, 0xA1, 0xBF, 0xE2, 0xDD, 0xF8, - 0x81, 0x9D, 0x65, 0x92, 0xEF, 0x45, 0x3B, 0x83, - 0x5B, 0xD2, 0xEF, 0xE8, 0xB0, 0x20, 0x6E, 0x29, - 0x25, 0x5B, 0x07, 0xFB, 0x90, 0xC7, 0xD3, 0x0D, - 0x2C, 0x11, 0x48, 0x00, 0xB8, 0x6C, 0xB0, 0xE3, - 0xE0, 0x7D, 0x38, 0x7E, 0x98, 0xCE, 0x95, 0x37 - }, - { - 0x41, 0xC9, 0x53, 0xD8, 0xD2, 0x2A, 0x86, 0xC3, - 0x63, 0x4D, 0xF4, 0x22, 0xB6, 0xDE, 0x4A, 0x4F, - 0x14, 0x96, 0x66, 0xBE, 0x8C, 0x4F, 0x58, 0x1B, - 0x26, 0x23, 0xEE, 0x65, 0xC3, 0x92, 0xA5, 0xC3, - 0x28, 0x36, 0x63, 0x9E, 0xF5, 0x6B, 0x93, 0x68, - 0x62, 0x20, 0xF4, 0x5C, 0xE6, 0x5B, 0x4F, 0xA8, - 0x58, 0x9C, 0x91, 0x25, 0x64, 0x17, 0x90, 0xB6, - 0x92, 0x5F, 0xAA, 0xD9, 0x48, 0xB8, 0xBE, 0x04 - }, - { - 0x8B, 0xFC, 0xA4, 0xC8, 0xDF, 0xE3, 0xFD, 0xE4, - 0x25, 0x7B, 0x75, 0xC3, 0xDB, 0x01, 0x86, 0x2E, - 0xD3, 0x11, 0x67, 0xDE, 0x66, 0xC2, 0xE0, 0x3A, - 0x25, 0x56, 0xC4, 0xF4, 0x6C, 0x9D, 0xFF, 0xC1, - 0xAC, 0x45, 0xF7, 0xBC, 0x59, 0xA6, 0x7A, 0xB9, - 0x36, 0x24, 0xBE, 0xB8, 0x6D, 0xDD, 0x0D, 0x02, - 0x60, 0x3F, 0x0D, 0xCD, 0x03, 0x64, 0xF0, 0xF8, - 0x08, 0x81, 0x9B, 0xE9, 0x6C, 0xD8, 0xD3, 0xB6 - }, - { - 0xF6, 0xBF, 0x59, 0xD8, 0xD4, 0x5A, 0x55, 0x71, - 0x11, 0xA2, 0x36, 0xCB, 0xBA, 0x52, 0x61, 0x9A, - 0xE3, 0xDF, 0xCC, 0x43, 0x16, 0x94, 0x38, 0x43, - 0xAF, 0xD1, 0x28, 0x1B, 0x28, 0x21, 0x4A, 0x4A, - 0x5E, 0x85, 0x1E, 0xF8, 0xC5, 0x4F, 0x50, 0x5E, - 0x3C, 0x4B, 0x60, 0x0E, 0xFF, 0xBE, 0xBB, 0x3E, - 0xAC, 0x17, 0x08, 0x7F, 0x22, 0x27, 0x58, 0x12, - 0x63, 0xF1, 0x7D, 0x7E, 0x5F, 0x68, 0xEA, 0x83 - }, - { - 0x1B, 0xC9, 0xED, 0xE4, 0xD4, 0x1A, 0x4D, 0xF6, - 0xE8, 0xE6, 0xF4, 0x7C, 0x2F, 0x4A, 0xD8, 0x73, - 0x37, 0xB6, 0x9B, 0x19, 0xF7, 0x10, 0xF7, 0x66, - 0xE1, 0xFA, 0xF5, 0xAA, 0x05, 0xA4, 0x3B, 0x66, - 0x45, 0x39, 0x6E, 0x7F, 0xBE, 0xF4, 0x3B, 0xB7, - 0x79, 0x5D, 0x39, 0x40, 0x7B, 0x58, 0x15, 0xB9, - 0x2E, 0xCC, 0x23, 0xA6, 0xC1, 0x24, 0x14, 0x21, - 0x15, 0x3A, 0x55, 0xD5, 0x1F, 0x12, 0xBF, 0xD8 - }, - { - 0x76, 0xB3, 0x8B, 0x36, 0x31, 0x55, 0x5D, 0xBC, - 0xFB, 0x21, 0x21, 0x8F, 0xF9, 0xE4, 0x12, 0xA2, - 0x29, 0x88, 0x9E, 0xF2, 0xCE, 0x8A, 0xD7, 0x05, - 0xE9, 0x0F, 0x96, 0xAA, 0xBB, 0xD5, 0xBE, 0x7E, - 0x53, 0x29, 0xA4, 0x26, 0x53, 0x4C, 0x81, 0x5A, - 0x56, 0x53, 0x77, 0x13, 0x18, 0x72, 0x66, 0x41, - 0x42, 0x4E, 0x3B, 0x88, 0x29, 0x2F, 0xB1, 0xD8, - 0x95, 0x44, 0x40, 0x6A, 0xDE, 0x9B, 0xCC, 0xB5 - }, - { - 0xE5, 0x3F, 0x60, 0x07, 0x40, 0x22, 0x4E, 0x4D, - 0x10, 0xD3, 0x1D, 0x24, 0x38, 0x00, 0x31, 0x43, - 0xAF, 0xDB, 0x43, 0x6E, 0xB1, 0x79, 0x1B, 0x15, - 0x0D, 0xE3, 0x56, 0x76, 0xF0, 0xE3, 0x2F, 0x80, - 0xB0, 0xB6, 0x5F, 0x0A, 0xCF, 0x48, 0x1A, 0x5F, - 0xBF, 0x95, 0x96, 0xC0, 0xCB, 0x0A, 0x27, 0xC7, - 0xAF, 0xC1, 0x1D, 0x1E, 0x2C, 0x4D, 0x54, 0x02, - 0x47, 0x5E, 0x4F, 0xFC, 0xC1, 0xCD, 0xA8, 0x11 - }, - { - 0x62, 0x06, 0xB9, 0x1F, 0xC0, 0xB6, 0xF1, 0x21, - 0x1E, 0x9F, 0xDE, 0xCD, 0xC9, 0xD5, 0x1A, 0x6F, - 0x1E, 0xEE, 0x65, 0x54, 0xB1, 0x38, 0xAD, 0xCD, - 0x4A, 0x82, 0x3D, 0xF0, 0x0D, 0xDE, 0xF6, 0x75, - 0x9A, 0x9B, 0xFD, 0x7A, 0x4E, 0x98, 0x1E, 0x04, - 0x52, 0x36, 0x83, 0x8F, 0x4A, 0xF6, 0x93, 0xF6, - 0x93, 0x77, 0x93, 0x14, 0x84, 0xB3, 0xE8, 0x1E, - 0x3E, 0x3B, 0xC2, 0xCB, 0x7E, 0xF7, 0x9F, 0xE9 - }, - { - 0x76, 0xFD, 0x02, 0xDA, 0xDD, 0x96, 0x3B, 0xC0, - 0x35, 0x39, 0x91, 0x46, 0xCE, 0x42, 0x98, 0x8C, - 0xC0, 0x99, 0xD3, 0xCF, 0x4D, 0x32, 0xDF, 0x5C, - 0x0B, 0xBF, 0x64, 0x10, 0x12, 0x46, 0xB1, 0xC7, - 0x08, 0xD1, 0x67, 0xE2, 0x95, 0x95, 0xD1, 0x1D, - 0x09, 0xB3, 0xF6, 0x34, 0x86, 0xB4, 0x05, 0x26, - 0xAC, 0x1D, 0xFE, 0x31, 0xBC, 0x22, 0xDE, 0xC7, - 0x0B, 0x74, 0x5E, 0x90, 0xE2, 0xEA, 0xAF, 0x5A - }, - { - 0xF0, 0xA1, 0xFB, 0xE3, 0x11, 0x63, 0xE4, 0x21, - 0x01, 0x50, 0x72, 0x18, 0x3D, 0x68, 0xEE, 0x51, - 0x91, 0xA9, 0x9C, 0xFD, 0xA1, 0x69, 0xBA, 0x5A, - 0x19, 0x54, 0xC9, 0xF3, 0x10, 0x7D, 0x4E, 0xCA, - 0x06, 0x3E, 0x13, 0x7A, 0x71, 0x14, 0xD3, 0x97, - 0xC9, 0xDB, 0x67, 0x2B, 0x9F, 0x47, 0x8D, 0x41, - 0xC3, 0x4E, 0x99, 0x1B, 0x06, 0x69, 0xA9, 0x51, - 0x53, 0x92, 0x90, 0xC8, 0xED, 0x65, 0xE4, 0x6A - }, - { - 0x13, 0xC7, 0x2A, 0x6A, 0xA5, 0x71, 0xB1, 0x43, - 0xDC, 0xCF, 0x45, 0xAD, 0xCD, 0x98, 0xEA, 0xE6, - 0x99, 0xA1, 0x54, 0xB1, 0x10, 0xF2, 0x5E, 0x7E, - 0x9E, 0x82, 0xB7, 0x65, 0xB9, 0xA0, 0x89, 0x23, - 0x68, 0x8E, 0x8E, 0x0F, 0xF3, 0x11, 0xA6, 0x8A, - 0x77, 0x1E, 0x14, 0x50, 0x96, 0xD6, 0x07, 0x76, - 0xC6, 0xD6, 0xEE, 0x70, 0xAD, 0x6F, 0x69, 0xFA, - 0x2B, 0x76, 0x77, 0x63, 0x40, 0x55, 0xA0, 0x0E - }, - { - 0x0E, 0x06, 0x2B, 0xFE, 0x81, 0x8E, 0xE1, 0x0F, - 0x33, 0x48, 0x1D, 0xEA, 0x43, 0x02, 0x8B, 0x2C, - 0xFB, 0xB4, 0x9E, 0xC9, 0x5E, 0x0F, 0x75, 0xA9, - 0xE1, 0x6D, 0x40, 0x4B, 0xC5, 0x19, 0xB9, 0xAD, - 0x50, 0xB4, 0xA7, 0x33, 0x69, 0x2C, 0xA5, 0x4E, - 0xFB, 0x68, 0x04, 0x69, 0xED, 0x83, 0xDD, 0xEF, - 0xBD, 0xDD, 0xB1, 0x39, 0x04, 0x2E, 0x0E, 0x1C, - 0x09, 0xC3, 0xEB, 0x79, 0x03, 0xFA, 0x08, 0xDF - }, - { - 0x45, 0x3B, 0xE4, 0xAA, 0xB9, 0xF4, 0x23, 0xB3, - 0x36, 0x52, 0xA0, 0xB5, 0xD0, 0x2A, 0x9A, 0xF8, - 0x55, 0xDD, 0x0D, 0x42, 0xDD, 0x83, 0x11, 0x0B, - 0xA3, 0xBC, 0x4B, 0x39, 0x94, 0xEA, 0x3F, 0x88, - 0x5A, 0x71, 0x30, 0x89, 0x75, 0x08, 0x9B, 0x49, - 0x03, 0xE2, 0xE4, 0xD6, 0xBA, 0x6D, 0xC2, 0xE8, - 0x40, 0x31, 0xFF, 0xE9, 0xC8, 0x56, 0x39, 0x75, - 0xC8, 0x61, 0x6A, 0xCA, 0x07, 0x42, 0xE8, 0x29 - }, - { - 0x53, 0x61, 0xE3, 0xE8, 0x93, 0xDD, 0x36, 0x0B, - 0xCB, 0xF5, 0x1C, 0x79, 0x3E, 0xC0, 0x92, 0xA6, - 0xB0, 0x52, 0x05, 0x4F, 0x5F, 0x00, 0x0B, 0x9F, - 0xCE, 0x50, 0x7B, 0x66, 0x45, 0xF8, 0xD4, 0x70, - 0x13, 0xA8, 0x70, 0x6A, 0x58, 0xD4, 0xB1, 0x06, - 0x29, 0xCC, 0x82, 0xB8, 0xD2, 0xD7, 0x96, 0xFD, - 0xD3, 0x7B, 0x60, 0x8A, 0x58, 0x79, 0x52, 0xD6, - 0x55, 0x3E, 0x01, 0xD1, 0xAF, 0x0E, 0x04, 0xB8 - }, - { - 0x74, 0xB5, 0x67, 0x39, 0xF0, 0x1F, 0x82, 0x09, - 0xA4, 0x04, 0x44, 0xDF, 0x4C, 0xCD, 0xEE, 0xEA, - 0x8F, 0x97, 0xE8, 0xE7, 0x6E, 0xFA, 0x3C, 0x04, - 0x33, 0x7F, 0x69, 0x94, 0x5C, 0x4D, 0x44, 0xC0, - 0x85, 0xF1, 0xF4, 0x78, 0x96, 0x96, 0x36, 0x1E, - 0x3C, 0x97, 0x77, 0x4A, 0x93, 0x5F, 0x86, 0x0D, - 0x67, 0x46, 0x86, 0xDC, 0xBA, 0x3D, 0x45, 0xEC, - 0xD8, 0x63, 0x9A, 0x64, 0xAE, 0xA0, 0x62, 0x1B - }, - { - 0xB4, 0xD3, 0x15, 0x87, 0xB9, 0x2B, 0x53, 0x61, - 0xCD, 0xC2, 0xD3, 0xC4, 0x10, 0x86, 0xC1, 0x55, - 0x3E, 0x7B, 0x55, 0xA1, 0xF6, 0x1E, 0x94, 0xD2, - 0xBC, 0x30, 0xBC, 0x25, 0x1D, 0xAF, 0x8A, 0x5E, - 0xBF, 0xC5, 0x07, 0x09, 0xCC, 0x04, 0xCB, 0xAF, - 0x4B, 0x3B, 0x4D, 0xA2, 0xD2, 0x6B, 0x81, 0x23, - 0x8F, 0xBA, 0x71, 0x8F, 0xA9, 0x17, 0x59, 0xB8, - 0x0B, 0xD3, 0x10, 0x3A, 0xEC, 0x11, 0xE0, 0x6F - }, - { - 0xAA, 0xF6, 0x12, 0x7F, 0x00, 0xA0, 0x3D, 0x96, - 0x40, 0x6B, 0x9F, 0xB4, 0xAC, 0x70, 0x16, 0x0D, - 0xB5, 0x22, 0x42, 0x9B, 0x5C, 0xD9, 0x4E, 0x7F, - 0xA0, 0x30, 0x3A, 0x74, 0x94, 0x78, 0xFE, 0x31, - 0x89, 0xC8, 0xEA, 0x23, 0x93, 0x0A, 0x66, 0x25, - 0x2A, 0x80, 0x26, 0x74, 0xDC, 0xAF, 0x77, 0x00, - 0x46, 0x82, 0x0D, 0xD9, 0x64, 0xC6, 0x6F, 0x0F, - 0x54, 0x75, 0x1A, 0x72, 0xF9, 0x7D, 0x9C, 0x35 - }, - { - 0x2C, 0x30, 0xD4, 0x8D, 0xF9, 0x98, 0x4E, 0x02, - 0xF7, 0x5A, 0x94, 0x54, 0x92, 0x17, 0x18, 0x4D, - 0xD0, 0x2A, 0xAD, 0x3B, 0x57, 0x68, 0x3D, 0x09, - 0xB5, 0xA8, 0xC2, 0xEF, 0x53, 0xA9, 0x6A, 0xFB, - 0x73, 0xFE, 0xB6, 0xF9, 0x14, 0xE2, 0xD8, 0x15, - 0xBB, 0x3B, 0x08, 0x65, 0x43, 0x32, 0xFC, 0xFE, - 0x79, 0xF8, 0x0E, 0xC5, 0xF0, 0x51, 0xDA, 0x10, - 0xD7, 0x21, 0x41, 0x3D, 0xDD, 0xE8, 0xFA, 0x60 - }, - { - 0x92, 0xE2, 0xC5, 0xF7, 0x5D, 0x0C, 0xEA, 0xFC, - 0x81, 0x8F, 0xA7, 0x93, 0x59, 0x39, 0xE4, 0x8B, - 0x91, 0x59, 0x41, 0xEF, 0x73, 0x4D, 0x75, 0x27, - 0x0E, 0xB3, 0x21, 0xBA, 0x20, 0x80, 0xEF, 0x6D, - 0x25, 0x5E, 0x90, 0xEF, 0x96, 0xC6, 0x4C, 0xFF, - 0x1D, 0x8C, 0x18, 0xF3, 0x3C, 0x2E, 0xAB, 0x10, - 0x7F, 0xEF, 0x53, 0xE0, 0xD8, 0xBB, 0x16, 0x05, - 0x16, 0x80, 0x74, 0x80, 0xFC, 0xBA, 0x53, 0x73 - }, - { - 0x6E, 0x03, 0xA9, 0x1E, 0x20, 0x44, 0x46, 0x27, - 0xE3, 0xD2, 0xE2, 0x22, 0x26, 0xCF, 0x47, 0x00, - 0x26, 0x69, 0x44, 0x34, 0xED, 0x64, 0x79, 0x82, - 0x8C, 0xB6, 0xDC, 0x8F, 0x27, 0x96, 0x0A, 0xEE, - 0xE2, 0xF4, 0xAB, 0x87, 0x2A, 0x5C, 0xA2, 0xF7, - 0xF6, 0x52, 0xF7, 0xDC, 0x77, 0xD5, 0xF9, 0x6D, - 0x85, 0x82, 0x8B, 0x8F, 0x9C, 0x2D, 0x6C, 0x23, - 0x9E, 0x79, 0x77, 0x24, 0xA1, 0x31, 0x31, 0xB1 - }, - { - 0xBA, 0x43, 0x2D, 0xB0, 0xA3, 0x31, 0xBB, 0x8C, - 0x39, 0xB1, 0x7B, 0xEE, 0x34, 0x46, 0x2B, 0x26, - 0xDD, 0xB7, 0xAD, 0x91, 0xB6, 0xC7, 0x5A, 0xEC, - 0x27, 0x65, 0xFB, 0xAE, 0x3A, 0x0E, 0x60, 0xEC, - 0x54, 0x6D, 0x45, 0xF8, 0xE5, 0x84, 0x37, 0xB9, - 0xD7, 0x7C, 0x3D, 0x2E, 0x8D, 0x7C, 0xE0, 0x69, - 0x73, 0x15, 0x66, 0x51, 0xD4, 0x08, 0x22, 0x2A, - 0xA2, 0x90, 0xCB, 0x58, 0xCA, 0xBC, 0x0A, 0xE5 - }, - { - 0x83, 0xA0, 0x1E, 0x23, 0xAB, 0x27, 0x7B, 0x1F, - 0xC2, 0x8C, 0xD8, 0xBB, 0x8D, 0xA7, 0xE9, 0x4C, - 0x70, 0xF1, 0xDE, 0xE3, 0x2D, 0x19, 0x55, 0xCE, - 0xE2, 0x50, 0xEE, 0x58, 0x41, 0x9A, 0x1F, 0xEE, - 0x10, 0xA8, 0x99, 0x17, 0x97, 0xCE, 0x3D, 0x20, - 0x93, 0x80, 0xCA, 0x9F, 0x98, 0x93, 0x39, 0xE2, - 0xD8, 0xA8, 0x1C, 0x67, 0xD7, 0x37, 0xD8, 0x28, - 0x8C, 0x7F, 0xAE, 0x46, 0x02, 0x83, 0x4A, 0x8B - }, - { - 0x0E, 0xA3, 0x21, 0x72, 0xCC, 0x19, 0x1D, 0xFC, - 0x13, 0x1C, 0xD8, 0x8A, 0xA0, 0x3F, 0xF4, 0x18, - 0x5C, 0x0B, 0xFA, 0x7B, 0x19, 0x11, 0x12, 0x19, - 0xEE, 0xCB, 0x45, 0xB0, 0xFF, 0x60, 0x4D, 0x3E, - 0xDB, 0x00, 0x55, 0x0A, 0xBB, 0xA1, 0x11, 0x52, - 0x2B, 0x77, 0xAE, 0x61, 0xC9, 0xA8, 0xD6, 0xE9, - 0x4F, 0xCA, 0x9D, 0x96, 0xC3, 0x8D, 0x6B, 0x7C, - 0xCE, 0x27, 0x52, 0xF0, 0xD0, 0xC3, 0x7E, 0x78 - }, - { - 0x54, 0xAD, 0xD6, 0x55, 0x2B, 0x08, 0x85, 0x8B, - 0x23, 0xD6, 0x64, 0x5F, 0x6C, 0xE7, 0x9E, 0x92, - 0xF3, 0x8B, 0x66, 0xAE, 0x91, 0x86, 0x77, 0xE6, - 0xD9, 0x1F, 0x71, 0x87, 0xC4, 0x16, 0x05, 0x24, - 0xDF, 0xA8, 0xD0, 0x1F, 0x00, 0xEA, 0x93, 0xDD, - 0x29, 0x9F, 0x3C, 0xC4, 0x09, 0x01, 0xBD, 0x33, - 0x27, 0xA0, 0xF1, 0x8C, 0xCD, 0x7B, 0x6B, 0x8E, - 0x4E, 0x47, 0xCD, 0x28, 0xCF, 0x83, 0x8F, 0xAB - }, - { - 0xEF, 0x84, 0x74, 0x6D, 0xC2, 0x01, 0x56, 0xB6, - 0x6B, 0xA5, 0xC7, 0x8A, 0x50, 0x83, 0x0A, 0xBD, - 0x2A, 0xEF, 0x90, 0xE6, 0x67, 0xB9, 0x7E, 0xB5, - 0x22, 0x91, 0xBC, 0x86, 0x9D, 0x8A, 0xA2, 0x45, - 0x59, 0xA1, 0x42, 0xC6, 0x8F, 0xEA, 0x2E, 0xF3, - 0x2A, 0xF2, 0x2D, 0xFC, 0xEA, 0x4C, 0x90, 0xB3, - 0xD4, 0x90, 0x8C, 0xC9, 0xEA, 0x5C, 0xFC, 0x4E, - 0x91, 0xBF, 0x11, 0xCE, 0x6A, 0x7E, 0x57, 0x61 - }, - { - 0x5A, 0x1B, 0xF3, 0x81, 0xA0, 0x41, 0x19, 0xF9, - 0x42, 0xE4, 0x63, 0xAB, 0xA2, 0xB1, 0x64, 0x38, - 0x82, 0x46, 0x8A, 0xEC, 0xC1, 0xB1, 0xAA, 0x1E, - 0x7B, 0xCA, 0xAB, 0x3B, 0x47, 0x8F, 0xC5, 0xF0, - 0x56, 0xF1, 0x0D, 0xA9, 0x03, 0x7D, 0x40, 0xFA, - 0x7F, 0x55, 0x70, 0x8E, 0x10, 0x3B, 0xDA, 0x96, - 0x5E, 0x92, 0x0C, 0xF6, 0x7C, 0xE3, 0xAD, 0xF7, - 0xE2, 0x00, 0xE8, 0x61, 0x01, 0x4D, 0xEC, 0xC6 - }, - { - 0xAC, 0xF7, 0x8A, 0xA3, 0x28, 0x45, 0x96, 0xF3, - 0x30, 0xB7, 0xE8, 0x47, 0x51, 0xB9, 0x4C, 0x31, - 0x4C, 0xD8, 0x36, 0x36, 0x27, 0xBA, 0x99, 0x78, - 0x81, 0x30, 0x85, 0x78, 0x87, 0x37, 0x59, 0x89, - 0x5D, 0x13, 0xDF, 0xFF, 0xA5, 0xE5, 0x74, 0x50, - 0x13, 0x61, 0xF0, 0x43, 0xC7, 0x4F, 0x57, 0xD2, - 0xD0, 0xF1, 0x5C, 0x7A, 0x41, 0xC7, 0xC4, 0x5E, - 0x3C, 0x09, 0xAD, 0x89, 0xD6, 0x99, 0xA9, 0x77 - }, - { - 0x18, 0xB3, 0xE9, 0x04, 0x38, 0x44, 0xD4, 0xF3, - 0xA2, 0xD0, 0x21, 0xF5, 0x4C, 0x38, 0xFA, 0xCC, - 0x36, 0x4F, 0x84, 0xBA, 0x10, 0x58, 0xF2, 0x10, - 0x09, 0xFC, 0x37, 0x1D, 0x2E, 0x4F, 0x38, 0xC7, - 0x27, 0x51, 0x8A, 0xAB, 0xA6, 0xA2, 0x9E, 0x0F, - 0xDA, 0xE6, 0xE7, 0x60, 0xA4, 0xF1, 0xA6, 0xD7, - 0x58, 0xEB, 0xE4, 0x2C, 0x2A, 0xFC, 0x9D, 0x2C, - 0xDC, 0x6D, 0xD5, 0x80, 0x77, 0x8C, 0x4B, 0x32 - }, - { - 0x18, 0x96, 0xB2, 0x31, 0x70, 0x33, 0xCF, 0x31, - 0x04, 0x68, 0x73, 0xD8, 0x7F, 0x26, 0xE6, 0xA4, - 0x2A, 0x9D, 0x77, 0x0B, 0xBA, 0xF6, 0xE0, 0x62, - 0xDF, 0x11, 0xF9, 0xB4, 0xA0, 0xEA, 0xB2, 0x75, - 0xAA, 0xB1, 0x2C, 0xAA, 0xC2, 0xD3, 0xF5, 0x29, - 0xEB, 0x20, 0xD0, 0x70, 0xFD, 0x84, 0x4D, 0x86, - 0xD0, 0xA5, 0x71, 0xCD, 0xF6, 0x28, 0x5F, 0x80, - 0xE2, 0x30, 0x8B, 0xB8, 0x2C, 0x6C, 0x5B, 0x3B - }, - { - 0x8C, 0x3D, 0xC4, 0x01, 0x94, 0xAA, 0x02, 0x1F, - 0x3C, 0x4A, 0x1F, 0x9A, 0x05, 0x5E, 0x4D, 0x41, - 0x9E, 0xB3, 0xA2, 0x6D, 0x4C, 0x2F, 0x1A, 0x8C, - 0x7E, 0x18, 0x8B, 0x73, 0x48, 0x13, 0x40, 0x80, - 0xB6, 0x3F, 0x6E, 0x57, 0x0A, 0xD1, 0x1C, 0x28, - 0x78, 0x66, 0x53, 0x55, 0x41, 0x9C, 0x10, 0x20, - 0xDE, 0x4B, 0x65, 0x5E, 0x7A, 0x6C, 0x2C, 0xCD, - 0xE9, 0x07, 0x2C, 0xD4, 0x27, 0xFE, 0x8C, 0x4E - }, - { - 0x70, 0xAE, 0x04, 0x30, 0xD5, 0x45, 0xEC, 0x42, - 0x7F, 0x85, 0x41, 0x21, 0x1D, 0x4F, 0xE0, 0x42, - 0xB9, 0x82, 0x3A, 0xCE, 0xC0, 0x4B, 0x15, 0xC9, - 0x0B, 0x7F, 0x4B, 0x8B, 0xDD, 0x3D, 0xC7, 0x85, - 0x19, 0x90, 0xF3, 0x70, 0xE7, 0x14, 0x16, 0x75, - 0x10, 0x66, 0x49, 0xD3, 0x91, 0x51, 0x09, 0x03, - 0x18, 0x23, 0x1E, 0x4D, 0xED, 0x51, 0x22, 0x5D, - 0x9A, 0x6F, 0xA6, 0xC4, 0x24, 0x69, 0x5D, 0xE2 - }, - { - 0x07, 0x33, 0x6C, 0x42, 0xBD, 0x51, 0x49, 0x0E, - 0xF8, 0x4D, 0xFB, 0xDF, 0xAB, 0x74, 0x66, 0xF6, - 0xB6, 0x39, 0x99, 0xA5, 0xC0, 0x88, 0x72, 0xDF, - 0xED, 0xA0, 0x20, 0x6F, 0xDA, 0x80, 0xB9, 0xA6, - 0x2D, 0xE7, 0x28, 0xE3, 0xE3, 0xC3, 0xFD, 0x6B, - 0x7D, 0x21, 0xA4, 0x38, 0xAA, 0xD1, 0xB8, 0xDD, - 0x22, 0x38, 0x63, 0xC0, 0xD2, 0x6A, 0xCA, 0x27, - 0x79, 0x01, 0x74, 0xD9, 0xD4, 0x42, 0xA6, 0x4C - }, - { - 0x79, 0x26, 0x70, 0x88, 0x59, 0xE6, 0xE2, 0xAB, - 0x68, 0xF6, 0x04, 0xDA, 0x69, 0xA9, 0xFB, 0x50, - 0x87, 0xBB, 0x33, 0xF4, 0xE8, 0xD8, 0x95, 0x73, - 0x0E, 0x30, 0x1A, 0xB2, 0xD7, 0xDF, 0x74, 0x8B, - 0x67, 0xDF, 0x0B, 0x6B, 0x86, 0x22, 0xE5, 0x2D, - 0xD5, 0x7D, 0x8D, 0x3A, 0xD8, 0x7D, 0x58, 0x20, - 0xD4, 0xEC, 0xFD, 0x24, 0x17, 0x8B, 0x2D, 0x2B, - 0x78, 0xD6, 0x4F, 0x4F, 0xBD, 0x38, 0x75, 0x82 - }, - { - 0x92, 0x80, 0xF4, 0xD1, 0x15, 0x70, 0x32, 0xAB, - 0x31, 0x5C, 0x10, 0x0D, 0x63, 0x62, 0x83, 0xFB, - 0xF4, 0xFB, 0xA2, 0xFB, 0xAD, 0x0F, 0x8B, 0xC0, - 0x20, 0x72, 0x1D, 0x76, 0xBC, 0x1C, 0x89, 0x73, - 0xCE, 0xD2, 0x88, 0x71, 0xCC, 0x90, 0x7D, 0xAB, - 0x60, 0xE5, 0x97, 0x56, 0x98, 0x7B, 0x0E, 0x0F, - 0x86, 0x7F, 0xA2, 0xFE, 0x9D, 0x90, 0x41, 0xF2, - 0xC9, 0x61, 0x80, 0x74, 0xE4, 0x4F, 0xE5, 0xE9 - }, - { - 0x55, 0x30, 0xC2, 0xD5, 0x9F, 0x14, 0x48, 0x72, - 0xE9, 0x87, 0xE4, 0xE2, 0x58, 0xA7, 0xD8, 0xC3, - 0x8C, 0xE8, 0x44, 0xE2, 0xCC, 0x2E, 0xED, 0x94, - 0x0F, 0xFC, 0x68, 0x3B, 0x49, 0x88, 0x15, 0xE5, - 0x3A, 0xDB, 0x1F, 0xAA, 0xF5, 0x68, 0x94, 0x61, - 0x22, 0x80, 0x5A, 0xC3, 0xB8, 0xE2, 0xFE, 0xD4, - 0x35, 0xFE, 0xD6, 0x16, 0x2E, 0x76, 0xF5, 0x64, - 0xE5, 0x86, 0xBA, 0x46, 0x44, 0x24, 0xE8, 0x85 - }, - { - 0xDA, 0x85, 0x0A, 0x2F, 0x54, 0xE9, 0x44, 0x89, - 0x17, 0xD0, 0xDC, 0xAA, 0x63, 0x93, 0x7B, 0x95, - 0xA4, 0xDA, 0x1E, 0xAC, 0x8A, 0xF4, 0xDD, 0xF2, - 0x11, 0x3E, 0x5C, 0x8B, 0x0D, 0x4D, 0xB2, 0x66, - 0x9A, 0xF3, 0xC2, 0xAC, 0xB0, 0x80, 0x3D, 0x05, - 0x32, 0x3F, 0x3E, 0xC5, 0x5A, 0xBD, 0x33, 0xBD, - 0xF9, 0xB2, 0xBE, 0x89, 0x0E, 0xE7, 0x9E, 0x7F, - 0x3F, 0xCE, 0x4E, 0x19, 0x86, 0x96, 0xA7, 0xA3 - }, - { - 0xF1, 0x60, 0x95, 0xDD, 0x9F, 0x1E, 0xEB, 0x77, - 0xD5, 0xB9, 0x2F, 0x4B, 0x1F, 0xAC, 0x3A, 0x2C, - 0x5D, 0xA6, 0xAE, 0x5D, 0x0A, 0xB3, 0xF2, 0x54, - 0xE2, 0xA7, 0xFE, 0x52, 0x67, 0x24, 0x11, 0xD0, - 0x1C, 0xFA, 0x6A, 0xC0, 0x5B, 0xF3, 0x9E, 0xF6, - 0x5F, 0x4B, 0x22, 0x26, 0x4B, 0x41, 0xC3, 0xF3, - 0x63, 0x56, 0x3A, 0xBF, 0x0E, 0x92, 0x42, 0x90, - 0xC1, 0xC6, 0x80, 0xB1, 0x8A, 0xA6, 0x5B, 0x44 - }, - { - 0x76, 0xD0, 0x0A, 0x09, 0xC5, 0xBD, 0xD3, 0x9E, - 0xD3, 0x28, 0x71, 0x72, 0x2C, 0xFA, 0x00, 0x47, - 0x67, 0x4B, 0xEC, 0x8D, 0x35, 0x17, 0x5A, 0xF9, - 0x0D, 0x7A, 0xE9, 0x10, 0x74, 0x40, 0xA2, 0xA0, - 0x63, 0x88, 0x56, 0xD8, 0x38, 0x4C, 0x81, 0x7D, - 0x77, 0x2A, 0x4A, 0x59, 0x7A, 0x89, 0x55, 0x49, - 0xC8, 0x48, 0x66, 0x37, 0x56, 0x31, 0xCB, 0xA0, - 0x42, 0xF0, 0xEF, 0x6F, 0xFE, 0xB8, 0x9D, 0x44 - }, - { - 0xA6, 0x51, 0x13, 0x7B, 0x2C, 0x47, 0xFB, 0x79, - 0x51, 0xE7, 0xBD, 0xA7, 0x15, 0x43, 0xA6, 0xEB, - 0xC6, 0x24, 0x2A, 0xCA, 0xB4, 0x34, 0x7D, 0x38, - 0x8B, 0xE8, 0x35, 0x0F, 0x0C, 0x3F, 0xA3, 0xDF, - 0x8D, 0x95, 0x2C, 0x7C, 0x8A, 0x3D, 0xAF, 0x01, - 0xE0, 0x6C, 0x1D, 0xA6, 0x94, 0x96, 0xBB, 0xA8, - 0xDE, 0x62, 0xD8, 0x6B, 0x50, 0x93, 0x25, 0x6F, - 0x77, 0xA1, 0x87, 0xB5, 0x3D, 0xB0, 0x39, 0x88 - }, - { - 0xF3, 0x2F, 0x15, 0x0C, 0x2D, 0x67, 0xC0, 0xC4, - 0x37, 0x40, 0x1B, 0x70, 0xF6, 0x0B, 0x38, 0xF0, - 0xA3, 0xA4, 0x70, 0x59, 0x03, 0x3E, 0x75, 0x05, - 0xE6, 0x9A, 0x1D, 0x30, 0x12, 0x96, 0x03, 0x0B, - 0xC9, 0xB2, 0x95, 0x19, 0xC7, 0xF8, 0xB7, 0xD5, - 0x9A, 0x71, 0xFA, 0xB9, 0x05, 0x57, 0xDC, 0x3D, - 0xC8, 0x23, 0xFA, 0xC9, 0x5B, 0x9E, 0x85, 0xE6, - 0x52, 0x52, 0x8C, 0xBF, 0xB0, 0x1B, 0x11, 0x78 - }, - { - 0x27, 0x02, 0x56, 0x61, 0x36, 0xC4, 0x92, 0xF4, - 0x10, 0x89, 0xB0, 0x60, 0x10, 0x84, 0x60, 0xFA, - 0x30, 0x22, 0xC9, 0xC2, 0x5D, 0x34, 0x3B, 0xCB, - 0xD8, 0xAF, 0x2A, 0xF1, 0x9C, 0x17, 0xEF, 0x4C, - 0xA9, 0xF2, 0x22, 0x4F, 0xE7, 0xC4, 0x70, 0x0A, - 0x10, 0x19, 0x8E, 0xE5, 0x24, 0x8F, 0x30, 0x0B, - 0x54, 0x8E, 0xBF, 0x5C, 0x8E, 0x71, 0x16, 0x32, - 0x0C, 0xC8, 0x93, 0xFF, 0x7E, 0x23, 0x1F, 0xFB - }, - { - 0xFF, 0xE6, 0x87, 0x9F, 0x46, 0xB6, 0x29, 0x2B, - 0x21, 0x96, 0x97, 0x2E, 0x3F, 0xDF, 0x4F, 0xE9, - 0xEA, 0x4A, 0x81, 0x6D, 0x18, 0x07, 0xA3, 0x1C, - 0xAE, 0xAD, 0x6A, 0xAC, 0x5F, 0x06, 0x3C, 0x8F, - 0xE8, 0x77, 0x79, 0x75, 0x59, 0xA7, 0x59, 0xA0, - 0x0F, 0x8B, 0xA8, 0xF6, 0x68, 0xD8, 0x96, 0x8F, - 0xB3, 0x1D, 0x8A, 0x3B, 0x84, 0x57, 0x35, 0x90, - 0x2C, 0x5E, 0x42, 0xE2, 0x89, 0xEE, 0x0B, 0x62 - }, - { - 0x14, 0x48, 0x84, 0x28, 0x68, 0x22, 0xC2, 0x51, - 0x2D, 0x61, 0xB0, 0x46, 0xE6, 0x74, 0xD8, 0x6B, - 0x26, 0x4E, 0x9C, 0xC6, 0x89, 0x3E, 0xFF, 0x36, - 0x73, 0x11, 0x24, 0xF5, 0x9D, 0x1A, 0x82, 0x00, - 0x1E, 0x63, 0xF3, 0xE8, 0x05, 0x1C, 0xFE, 0x52, - 0xE7, 0x59, 0x7E, 0x28, 0x73, 0x8E, 0x3C, 0x3A, - 0x70, 0xF1, 0xBE, 0xD9, 0x68, 0x0E, 0x2C, 0x0E, - 0xF3, 0x72, 0x8B, 0x10, 0xA5, 0x6E, 0xD9, 0x87 - }, - { - 0x17, 0xC3, 0xF1, 0x46, 0xEE, 0x8D, 0xEC, 0x3B, - 0xAF, 0xCB, 0x51, 0xC0, 0xDA, 0x37, 0xF1, 0x78, - 0x71, 0xF2, 0x34, 0xC4, 0xA0, 0xFB, 0x7F, 0xA6, - 0xD0, 0x70, 0x7A, 0x54, 0x3E, 0x3C, 0xBF, 0x3A, - 0xDB, 0x81, 0xE3, 0x0C, 0x1E, 0x0A, 0xE9, 0xE1, - 0xAC, 0xE7, 0x22, 0x3B, 0xDA, 0x99, 0xBD, 0x59, - 0x19, 0xA3, 0xCF, 0xCC, 0x92, 0xC6, 0xA7, 0x55, - 0xE4, 0x56, 0xF0, 0x93, 0x82, 0x3B, 0xD3, 0x3E - }, - { - 0x1B, 0x83, 0x7A, 0xF2, 0x33, 0xA8, 0xA6, 0x8B, - 0xE7, 0x09, 0x52, 0xF7, 0x83, 0xC4, 0x96, 0x1A, - 0x81, 0x52, 0xD1, 0xE0, 0xB0, 0xFA, 0x32, 0x5F, - 0xF0, 0x86, 0xEA, 0x5B, 0x5F, 0x13, 0x12, 0xB8, - 0x9C, 0x42, 0xE0, 0x1B, 0x8C, 0x3A, 0x47, 0x7C, - 0xB5, 0x40, 0xC0, 0x6B, 0x2F, 0x37, 0xEE, 0x0E, - 0x39, 0x24, 0xD7, 0x45, 0xB4, 0xFF, 0x5C, 0x6A, - 0xF7, 0xD6, 0x1E, 0x0E, 0x37, 0xAC, 0x19, 0x31 - }, - { - 0x78, 0x97, 0x88, 0x0C, 0x1E, 0xB0, 0x0F, 0xD2, - 0x56, 0x7A, 0xE8, 0xA5, 0x9E, 0x64, 0x82, 0xAF, - 0xE1, 0x73, 0x49, 0xCF, 0x93, 0x92, 0x4A, 0x91, - 0x5F, 0x8C, 0x59, 0x26, 0x93, 0xD4, 0x52, 0x07, - 0x55, 0x19, 0x68, 0x9D, 0xFC, 0xD2, 0x93, 0xE3, - 0x76, 0x89, 0x7B, 0x3B, 0x0E, 0x03, 0x6F, 0x11, - 0x4F, 0xE8, 0x1E, 0xBC, 0xB3, 0x15, 0x36, 0x71, - 0xBD, 0x23, 0xBC, 0x2B, 0xED, 0x46, 0xF9, 0xC2 - }, - { - 0xCA, 0x7B, 0x6C, 0x77, 0x5D, 0x20, 0x1E, 0x5B, - 0x5A, 0x77, 0x22, 0x61, 0xDE, 0x52, 0x8E, 0x47, - 0x5F, 0x4B, 0xDE, 0x51, 0x76, 0x60, 0x52, 0x9F, - 0x41, 0xBE, 0xEB, 0x15, 0x78, 0xB2, 0x4B, 0xCB, - 0x94, 0xB9, 0x41, 0x0F, 0x9B, 0xF3, 0x36, 0xC1, - 0x09, 0xF9, 0xD4, 0x70, 0x93, 0xA1, 0x0B, 0xA6, - 0xDE, 0xBE, 0x50, 0x43, 0x80, 0xD9, 0xD1, 0x50, - 0x73, 0xBD, 0xD1, 0x11, 0xC8, 0xD1, 0x29, 0xFA - }, - { - 0x57, 0x18, 0xE0, 0xD4, 0x5D, 0xEB, 0xC3, 0x00, - 0x2D, 0x52, 0xB2, 0x2C, 0x52, 0x73, 0x29, 0xAE, - 0x5E, 0xBF, 0x27, 0xE8, 0xFA, 0x9C, 0x8F, 0xEA, - 0xB4, 0x6C, 0x40, 0xBC, 0x64, 0x22, 0xCA, 0x03, - 0x35, 0x30, 0x4C, 0xF9, 0xE7, 0xF1, 0x41, 0xDE, - 0x7F, 0xA6, 0xAD, 0xB6, 0x78, 0x9B, 0xDB, 0xF3, - 0x8D, 0x14, 0xDA, 0xBA, 0x3E, 0x62, 0x97, 0xD2, - 0x5B, 0xF1, 0x7D, 0xE1, 0x70, 0xD6, 0xE3, 0xC8 - }, - { - 0x48, 0xD0, 0xED, 0x24, 0x9F, 0x90, 0x28, 0x41, - 0x99, 0x7C, 0x25, 0x5D, 0xAF, 0x99, 0x08, 0x9C, - 0x9A, 0x31, 0x24, 0x69, 0x8B, 0x16, 0x4A, 0x30, - 0x28, 0x33, 0x0F, 0xDD, 0x4C, 0xEE, 0x41, 0xE1, - 0x68, 0x3F, 0xA4, 0xD9, 0xDC, 0x66, 0xB2, 0xA7, - 0x9C, 0x8A, 0xA4, 0xC8, 0x28, 0x4E, 0x27, 0xBE, - 0xE2, 0xA4, 0x28, 0xA6, 0x71, 0x9D, 0x6E, 0xC6, - 0x55, 0xED, 0x76, 0x9D, 0xCB, 0x62, 0x4E, 0x24 - }, - { - 0x79, 0x4E, 0x0B, 0x64, 0xAC, 0xE1, 0xFE, 0x5A, - 0xE3, 0x79, 0x93, 0x70, 0x68, 0xD8, 0x2D, 0xF0, - 0x48, 0x68, 0x61, 0x6C, 0xAE, 0x0C, 0x17, 0xD3, - 0x05, 0x72, 0xC2, 0x02, 0x4E, 0x77, 0x48, 0x94, - 0xE0, 0x66, 0x8C, 0x47, 0x2D, 0x62, 0x3C, 0x90, - 0x3C, 0xC5, 0x88, 0x5F, 0x17, 0x84, 0x94, 0x51, - 0x10, 0x32, 0x9E, 0xB4, 0x98, 0xA8, 0x95, 0xA9, - 0xE5, 0x9A, 0x75, 0xE5, 0x27, 0x15, 0x8A, 0x5C - }, - { - 0x21, 0x79, 0xAA, 0x82, 0x0E, 0x03, 0xFA, 0x33, - 0xD9, 0xBD, 0xE5, 0x56, 0x8C, 0x26, 0x2E, 0x2D, - 0x34, 0x17, 0xA4, 0x02, 0xE0, 0x7A, 0x59, 0x1F, - 0x9D, 0x55, 0x70, 0x68, 0x2D, 0xB5, 0xF9, 0xBB, - 0xA4, 0xBB, 0x9D, 0x5A, 0x82, 0xEE, 0x5E, 0xFD, - 0xB4, 0xF6, 0x5B, 0xBB, 0xFE, 0xEE, 0x2F, 0x4A, - 0xB9, 0xE4, 0x6C, 0xF2, 0xCE, 0x7E, 0x3B, 0x05, - 0x43, 0x27, 0xA7, 0x18, 0xD3, 0xF1, 0x08, 0x06 - }, - { - 0xB0, 0xA4, 0x8C, 0x6A, 0xDA, 0x54, 0x87, 0x25, - 0x79, 0x9B, 0x59, 0x86, 0xBA, 0xB4, 0x32, 0x69, - 0x79, 0x60, 0x92, 0x24, 0xD8, 0x97, 0x18, 0x4B, - 0x89, 0x97, 0x10, 0x4E, 0x0C, 0x6A, 0x24, 0xB3, - 0xAB, 0xE5, 0x62, 0x16, 0x54, 0x22, 0xA4, 0x5D, - 0x8A, 0xC8, 0x19, 0xB9, 0x9D, 0x37, 0x56, 0xEB, - 0xBB, 0x64, 0xF8, 0x43, 0xE3, 0xE0, 0x93, 0x4D, - 0xEC, 0x48, 0x7A, 0xED, 0x12, 0x13, 0x72, 0x79 - }, - { - 0x84, 0x8D, 0x7F, 0x2E, 0xAD, 0x41, 0x29, 0x1D, - 0x05, 0x38, 0x68, 0x0C, 0x64, 0x9D, 0x07, 0x89, - 0x7E, 0x45, 0xC7, 0x0A, 0x0A, 0xA4, 0xF9, 0x35, - 0x3F, 0x82, 0xC3, 0xF6, 0xFB, 0xB8, 0xE8, 0x48, - 0x9C, 0x75, 0x3E, 0x90, 0xDB, 0xE8, 0x89, 0x00, - 0x41, 0xA1, 0xAE, 0xEF, 0x84, 0xCD, 0x31, 0x36, - 0x43, 0x4F, 0x53, 0x0E, 0x9D, 0xD9, 0xC2, 0x3F, - 0xA5, 0x4F, 0xE1, 0x24, 0xEA, 0xFB, 0x72, 0xAD - }, - { - 0x0E, 0xD1, 0x46, 0x26, 0xEE, 0x6D, 0x0C, 0x8E, - 0xD3, 0xF0, 0xC2, 0x00, 0xC1, 0x29, 0x85, 0x0F, - 0xFF, 0x76, 0x31, 0x8F, 0xFF, 0xA1, 0xDD, 0xD7, - 0xDD, 0x56, 0x3A, 0x01, 0xB7, 0x77, 0x97, 0x06, - 0x86, 0x2B, 0x23, 0x99, 0x59, 0xB6, 0x15, 0xAE, - 0x2E, 0xBE, 0x27, 0xC4, 0x50, 0x37, 0xE6, 0xFF, - 0xAF, 0x99, 0x14, 0xDA, 0x8F, 0xF2, 0x77, 0x2B, - 0xA5, 0xEE, 0x08, 0x11, 0xCD, 0x9E, 0xD5, 0x32 - }, - { - 0x52, 0x03, 0xC0, 0x76, 0x38, 0xC4, 0xB6, 0x5F, - 0x78, 0x43, 0x1E, 0x8B, 0x02, 0xE2, 0x0F, 0x6D, - 0x68, 0x3F, 0x19, 0xFA, 0x8F, 0x83, 0xB5, 0x13, - 0x4C, 0xD0, 0xF4, 0xE4, 0x68, 0xC9, 0x7E, 0xAC, - 0xB5, 0x26, 0x7C, 0x7D, 0x3E, 0xAB, 0x58, 0x3C, - 0xCA, 0xAC, 0xD0, 0xDB, 0xA4, 0xD5, 0x8A, 0xCE, - 0x52, 0x19, 0x3A, 0x51, 0x78, 0xA7, 0xB1, 0x2D, - 0x27, 0x95, 0xF5, 0xFD, 0xE8, 0xA3, 0x7B, 0xB9 - }, - { - 0x48, 0xBE, 0x43, 0xD5, 0xE0, 0x04, 0x36, 0x88, - 0xDF, 0x35, 0x32, 0xF7, 0x12, 0x1A, 0xFF, 0xFA, - 0x16, 0x7D, 0xAB, 0xE4, 0xA4, 0x84, 0xFB, 0x75, - 0xA0, 0x3A, 0xF3, 0x04, 0xA5, 0xC6, 0xF8, 0x25, - 0xF3, 0x6C, 0xEC, 0xCB, 0xBB, 0xC0, 0x75, 0xEE, - 0xF3, 0x20, 0xC4, 0xCD, 0x8D, 0x7E, 0xF8, 0xCB, - 0x49, 0xE6, 0xDD, 0x59, 0x73, 0x37, 0x9E, 0xEC, - 0x4C, 0x23, 0x3C, 0x45, 0x43, 0xD1, 0x32, 0xCE - }, - { - 0xB5, 0x46, 0x4E, 0x6A, 0xBA, 0xF5, 0xD3, 0xD4, - 0x08, 0x3D, 0x1D, 0x7D, 0x2A, 0x8B, 0x0B, 0xAB, - 0x78, 0xB6, 0x17, 0x09, 0x50, 0x0B, 0xBF, 0x77, - 0x82, 0x3F, 0x60, 0x2D, 0x57, 0xD5, 0x13, 0xCA, - 0x9E, 0x9F, 0xFF, 0x65, 0xEF, 0xAA, 0x89, 0x9C, - 0xFE, 0x7B, 0xF8, 0x8A, 0x01, 0x88, 0x82, 0x9C, - 0x24, 0xE4, 0x98, 0xAD, 0x00, 0x23, 0x5A, 0xBE, - 0x8E, 0xEF, 0xA7, 0x19, 0xFA, 0x6A, 0xE6, 0xF6 - }, - { - 0xAF, 0xE5, 0xE5, 0xE8, 0x3F, 0x19, 0xAD, 0xAD, - 0x9E, 0x95, 0x90, 0x3E, 0xA9, 0xB2, 0x98, 0x10, - 0x7D, 0x37, 0xDD, 0x38, 0x63, 0x2C, 0x95, 0x90, - 0xBB, 0xFF, 0xC6, 0x24, 0xD4, 0xDE, 0x95, 0x8C, - 0xB6, 0xB6, 0x1A, 0xF0, 0x80, 0xF0, 0x37, 0xAD, - 0x17, 0xD0, 0x35, 0xB6, 0xBF, 0x58, 0xF7, 0x80, - 0xFA, 0xDF, 0x70, 0xF3, 0xC9, 0x59, 0x66, 0x8A, - 0x1B, 0x47, 0x21, 0x98, 0xA5, 0x9A, 0x8A, 0x00 - }, - { - 0xEF, 0xA2, 0xC7, 0xC8, 0x02, 0xE2, 0x10, 0xD2, - 0xD8, 0x0F, 0xB3, 0x50, 0xB3, 0xC2, 0xCB, 0x31, - 0x56, 0x13, 0x18, 0x11, 0xE7, 0x18, 0xEE, 0xE5, - 0xC9, 0xC6, 0x64, 0x0F, 0x87, 0x68, 0x2A, 0x55, - 0x81, 0x2B, 0x10, 0xF4, 0x03, 0x10, 0xBA, 0xA7, - 0xB8, 0x2B, 0x27, 0x3E, 0xF3, 0xAC, 0xC5, 0x5F, - 0xED, 0xE0, 0xB5, 0xF1, 0x94, 0x9D, 0xE4, 0x29, - 0x3D, 0x91, 0xB5, 0x89, 0xA2, 0x17, 0x5F, 0xF7 - }, - { - 0xD6, 0xC6, 0x2A, 0x61, 0x82, 0x71, 0xF3, 0xBC, - 0xBE, 0x00, 0x79, 0x24, 0xA0, 0xC9, 0x81, 0x2F, - 0x83, 0x17, 0x44, 0x5F, 0xB6, 0xFB, 0x19, 0xEB, - 0x58, 0x9A, 0x62, 0x9F, 0x51, 0x2F, 0xB3, 0x8A, - 0x0B, 0x4E, 0x24, 0x7D, 0xEA, 0x88, 0xC5, 0x6A, - 0x1B, 0xAF, 0x17, 0x88, 0x33, 0x65, 0xB4, 0x36, - 0xF2, 0x84, 0x46, 0xFF, 0x66, 0xEA, 0x43, 0x18, - 0x0B, 0xD0, 0x1E, 0xB5, 0xA6, 0x50, 0x9B, 0xD5 - }, - { - 0x0B, 0x41, 0x16, 0x6B, 0xE6, 0x2F, 0x65, 0xE1, - 0x93, 0xB3, 0xB8, 0x65, 0xE6, 0xC4, 0x7A, 0xAD, - 0x26, 0x0A, 0xF5, 0xFC, 0xEE, 0xC9, 0xAB, 0x44, - 0xAB, 0xAA, 0x46, 0x0A, 0x0C, 0x02, 0x46, 0xB6, - 0xC6, 0x9B, 0x67, 0xD7, 0x1D, 0x3A, 0xDF, 0xEC, - 0x60, 0xDC, 0x8E, 0x77, 0x37, 0x2F, 0x09, 0x49, - 0x52, 0x34, 0x4F, 0xE1, 0x0C, 0x0D, 0x59, 0xEF, - 0xEC, 0x0E, 0x11, 0xC4, 0xA5, 0x16, 0x93, 0x6D - }, - { - 0x79, 0xD5, 0xF9, 0xFF, 0xC0, 0x5E, 0xCF, 0x33, - 0x7D, 0xE9, 0xF1, 0xE0, 0xF1, 0xD8, 0x9B, 0x30, - 0xAC, 0xFE, 0xBB, 0xB8, 0x8A, 0x69, 0x35, 0x86, - 0x78, 0x18, 0xCD, 0x8D, 0x45, 0xDA, 0x3D, 0x25, - 0x18, 0xDE, 0x61, 0xA7, 0xFE, 0x28, 0x75, 0x1B, - 0x61, 0x8F, 0x7A, 0x87, 0x5E, 0x11, 0x89, 0x8F, - 0xFF, 0x74, 0x15, 0x7A, 0xB9, 0x06, 0x81, 0xBD, - 0x53, 0xFA, 0x69, 0x62, 0x67, 0x1E, 0xD9, 0x9D - }, - { - 0xBE, 0xA9, 0x83, 0xD7, 0x6F, 0x24, 0xB1, 0xEE, - 0xDE, 0x1D, 0x06, 0x71, 0x48, 0x05, 0x76, 0x8F, - 0xAA, 0xAD, 0x47, 0x08, 0xC9, 0xA4, 0xFF, 0x9C, - 0xD2, 0x42, 0x2F, 0x70, 0x6B, 0x6F, 0x0C, 0x30, - 0x6D, 0x8B, 0x67, 0xF3, 0x40, 0x89, 0xC6, 0x5E, - 0xD3, 0x88, 0x0C, 0x75, 0xF6, 0x7B, 0xBC, 0x4D, - 0x89, 0xAD, 0x87, 0x12, 0x0A, 0x77, 0xD0, 0xFF, - 0xE4, 0x36, 0xFB, 0x7B, 0x58, 0xB2, 0xCA, 0x41 - }, - { - 0x46, 0x6F, 0xD9, 0x15, 0xEF, 0xD9, 0x50, 0xBC, - 0x96, 0x65, 0x78, 0xCD, 0x92, 0xC6, 0x85, 0x92, - 0x9D, 0x7B, 0x51, 0xA6, 0x3D, 0xB1, 0x42, 0xC7, - 0xB9, 0xA9, 0x3D, 0x16, 0x52, 0x04, 0x95, 0x31, - 0x9B, 0x87, 0xF6, 0x58, 0xE6, 0xAF, 0xDA, 0x1B, - 0x42, 0x77, 0x3E, 0x2D, 0x49, 0xDA, 0x81, 0x45, - 0x94, 0xA5, 0x54, 0x90, 0x89, 0xEF, 0xB1, 0xF3, - 0xAB, 0x5F, 0x15, 0x90, 0xCA, 0x0A, 0x02, 0xAF - }, - { - 0xF6, 0x46, 0x11, 0x13, 0x7A, 0xD2, 0x95, 0x46, - 0x70, 0xEA, 0xEC, 0xD6, 0x26, 0xD2, 0x12, 0xCF, - 0xC5, 0xB9, 0xF6, 0xBB, 0x41, 0xAA, 0xEB, 0xB1, - 0xD7, 0x1E, 0x89, 0x79, 0x2E, 0xB1, 0x31, 0x7A, - 0xED, 0xC6, 0x38, 0x13, 0xFE, 0x63, 0xDE, 0x40, - 0x17, 0x98, 0xDF, 0x75, 0x6C, 0xA1, 0xF2, 0x20, - 0x35, 0xA0, 0xFA, 0xBD, 0x37, 0xFB, 0x11, 0x03, - 0x43, 0x7F, 0x89, 0x1E, 0xAD, 0x5E, 0x64, 0x29 - }, - { - 0x32, 0xE1, 0xF9, 0x38, 0xA2, 0x7F, 0xAA, 0xD8, - 0xAC, 0x4A, 0x13, 0xFD, 0x4F, 0x6A, 0x8B, 0xF3, - 0xDA, 0xBE, 0x4B, 0xC7, 0x2A, 0xF1, 0x1C, 0x8F, - 0x0E, 0x1A, 0x06, 0x56, 0x7E, 0xD7, 0x04, 0xB8, - 0xE7, 0x8E, 0x11, 0x40, 0xA0, 0xC7, 0x72, 0x4E, - 0x3E, 0xFB, 0x70, 0xD2, 0x38, 0x07, 0xCF, 0x38, - 0xE6, 0x27, 0xE3, 0x26, 0xAF, 0xC1, 0x64, 0xCD, - 0xED, 0x52, 0xB4, 0x41, 0x39, 0xFF, 0xB3, 0xF3 - }, - { - 0x48, 0x33, 0xAC, 0x92, 0xE3, 0x02, 0xAC, 0x2B, - 0x67, 0xB0, 0x2B, 0x88, 0x27, 0x14, 0x3B, 0xAD, - 0xA1, 0x5C, 0xED, 0x22, 0x0E, 0x1D, 0x1F, 0x5B, - 0x71, 0x12, 0x0C, 0x51, 0xEE, 0x54, 0xC1, 0x9D, - 0x30, 0x1F, 0x29, 0x60, 0xBD, 0xB5, 0xA2, 0xCE, - 0x27, 0xD4, 0x41, 0xD1, 0x4A, 0xF0, 0x80, 0xCB, - 0x01, 0x0A, 0x8A, 0x23, 0xEE, 0xFF, 0x58, 0x11, - 0xDF, 0xA4, 0x4D, 0x1D, 0x7B, 0x35, 0x8B, 0x48 - }, - { - 0x9A, 0x03, 0x88, 0xCE, 0xE1, 0xAD, 0x01, 0x46, - 0x17, 0x7C, 0x48, 0xB5, 0xA0, 0x8A, 0x2D, 0xB3, - 0xC4, 0x89, 0xE8, 0x4C, 0xE2, 0xAB, 0xA8, 0xC6, - 0x45, 0x11, 0x2A, 0x02, 0x1E, 0x41, 0x1C, 0xF8, - 0x29, 0x12, 0x7F, 0xA2, 0xF1, 0xD1, 0xAE, 0x1B, - 0xAF, 0x3A, 0x33, 0xEA, 0x53, 0x09, 0x84, 0x77, - 0xA7, 0xD1, 0x2B, 0xA7, 0x48, 0xD2, 0xAF, 0x24, - 0xD1, 0x66, 0x02, 0xE9, 0x19, 0x07, 0x76, 0x23 - }, - { - 0xE3, 0xDF, 0x00, 0x74, 0xA9, 0x37, 0x35, 0x13, - 0x0D, 0x99, 0x22, 0xD2, 0xBE, 0x91, 0x6F, 0x35, - 0x34, 0x3D, 0x98, 0x8C, 0xE5, 0x9D, 0x76, 0x97, - 0x15, 0xA9, 0x83, 0xB4, 0xBA, 0x80, 0x7C, 0xE1, - 0xEE, 0x70, 0xA3, 0x13, 0xE5, 0x92, 0x31, 0x58, - 0x4F, 0x55, 0x6E, 0xBB, 0xA1, 0xB9, 0x0B, 0x1B, - 0xB6, 0xA6, 0xC5, 0x81, 0xA4, 0xB4, 0x7C, 0x3F, - 0xF5, 0x21, 0x89, 0x65, 0x2A, 0xAB, 0x36, 0xF5 - }, - { - 0x91, 0x91, 0xCF, 0x46, 0x1B, 0x69, 0x59, 0xBE, - 0xC9, 0x3E, 0xAE, 0x7F, 0xB1, 0xC6, 0xE3, 0x70, - 0x73, 0xD1, 0xA6, 0x15, 0x27, 0xAD, 0x75, 0xD1, - 0x0B, 0x7F, 0x89, 0x49, 0xD9, 0xB8, 0xAF, 0x70, - 0xA2, 0x3A, 0xD1, 0x31, 0x2E, 0xD5, 0x1F, 0x70, - 0xF0, 0xE9, 0xDF, 0x60, 0x1D, 0xDA, 0xE2, 0x38, - 0x90, 0x6C, 0x0F, 0xE3, 0xF7, 0x66, 0xB1, 0x4F, - 0x11, 0x3B, 0x26, 0xBC, 0x85, 0x42, 0xD1, 0xD2 - }, - { - 0x2A, 0x8B, 0xAD, 0xE2, 0x72, 0xEE, 0x7A, 0xC6, - 0x43, 0xC5, 0xE3, 0x71, 0x47, 0xFA, 0xAC, 0x92, - 0xC3, 0x97, 0x0B, 0xD3, 0x86, 0x2F, 0x53, 0x1E, - 0x5D, 0xCE, 0xA5, 0xCE, 0xAC, 0xD1, 0x83, 0x74, - 0x53, 0xAA, 0x49, 0x8D, 0x78, 0x5B, 0x4D, 0x1F, - 0x89, 0xE1, 0xB2, 0xA7, 0x39, 0xCA, 0x4A, 0x38, - 0x49, 0x87, 0x30, 0x27, 0x46, 0xB4, 0xF1, 0x13, - 0x42, 0x43, 0x02, 0xC4, 0xA1, 0xE0, 0xF9, 0xDF - }, - { - 0x32, 0x3E, 0x67, 0x93, 0xC7, 0xDD, 0x9B, 0x4D, - 0x7B, 0xB7, 0xFB, 0xF2, 0x15, 0x31, 0xD3, 0x7F, - 0x72, 0x64, 0x53, 0x2C, 0x58, 0xF1, 0x22, 0x55, - 0x48, 0xD0, 0x6E, 0x69, 0x40, 0xC6, 0x3E, 0x91, - 0x27, 0x09, 0x90, 0xE7, 0xF5, 0x64, 0x32, 0x03, - 0xC9, 0x87, 0x64, 0x7E, 0x5C, 0xF6, 0x61, 0x03, - 0xE7, 0x9B, 0x71, 0x4C, 0x58, 0x1B, 0xD8, 0x77, - 0x2E, 0x19, 0xD0, 0xF0, 0x05, 0xDC, 0x86, 0x33 - }, - { - 0xF9, 0x22, 0x07, 0x6D, 0x29, 0x5D, 0x23, 0xE2, - 0x98, 0x58, 0x30, 0xAA, 0xD2, 0xF2, 0x3F, 0x65, - 0x2F, 0x7F, 0x4D, 0xB4, 0x2C, 0x11, 0x9E, 0xD2, - 0x20, 0xA5, 0x45, 0x14, 0x88, 0xA4, 0x53, 0xF5, - 0x9F, 0xA8, 0xA2, 0xDE, 0x23, 0x03, 0x00, 0x0D, - 0x6B, 0xFD, 0x8C, 0x48, 0x23, 0xA8, 0x5F, 0xAD, - 0xB4, 0xFB, 0x8E, 0x7E, 0xAC, 0x12, 0x2B, 0xF0, - 0x12, 0x47, 0xD7, 0x6F, 0x65, 0x24, 0x7D, 0x45 - }, - { - 0xDC, 0x40, 0x00, 0x95, 0x60, 0x95, 0x92, 0x91, - 0x55, 0x8E, 0xBE, 0x07, 0x20, 0x64, 0xCE, 0x67, - 0x12, 0xC9, 0x21, 0xB5, 0x40, 0x9B, 0x44, 0xE0, - 0x4F, 0x9A, 0x56, 0x5E, 0xEA, 0xDD, 0x39, 0xA7, - 0x71, 0x6E, 0x21, 0xB4, 0x6D, 0xD8, 0x61, 0x65, - 0x17, 0xA2, 0x1A, 0x0C, 0x03, 0x41, 0x9E, 0x94, - 0xDB, 0x82, 0x0A, 0x35, 0x3F, 0x15, 0x2D, 0x10, - 0x83, 0x84, 0xBE, 0x94, 0x70, 0x09, 0x3F, 0x89 - }, - { - 0x7F, 0xA4, 0xBE, 0x91, 0xCA, 0x52, 0x07, 0xFF, - 0x08, 0x7D, 0xE9, 0x2F, 0x1D, 0xB0, 0x9B, 0xF7, - 0x1A, 0x67, 0x87, 0x8B, 0xED, 0x19, 0x3A, 0x5C, - 0x2C, 0xC4, 0xE3, 0x53, 0x23, 0xB8, 0xDF, 0x99, - 0xA2, 0x6E, 0xCB, 0x98, 0x88, 0xD7, 0xB3, 0x4A, - 0x73, 0x9D, 0x64, 0x1A, 0x0E, 0xCD, 0x0A, 0x66, - 0x47, 0xA6, 0xA0, 0x64, 0x26, 0xF3, 0xCC, 0x1F, - 0xEF, 0xDF, 0x90, 0x69, 0x92, 0x2F, 0xAE, 0x4C - }, - { - 0xBA, 0xD3, 0xCD, 0x75, 0x90, 0x5D, 0x7B, 0xFD, - 0xA3, 0x32, 0x2B, 0x44, 0xA7, 0xD3, 0x58, 0x87, - 0x14, 0xD3, 0x33, 0xEE, 0x86, 0x85, 0x5A, 0x87, - 0x27, 0x47, 0xE7, 0x04, 0xF6, 0x11, 0x94, 0x84, - 0xBD, 0xB7, 0xD0, 0x77, 0xFA, 0x08, 0xED, 0xC4, - 0xA7, 0x9D, 0xE0, 0xF4, 0x3F, 0xCA, 0x8D, 0x43, - 0x6E, 0x8A, 0x10, 0x08, 0x57, 0xF5, 0x9B, 0xC7, - 0xB0, 0x55, 0xB9, 0x87, 0xF9, 0x7A, 0xC6, 0xB9 - }, - { - 0xB7, 0xDE, 0xE8, 0xE8, 0x33, 0x9D, 0xB2, 0x97, - 0xFD, 0xAA, 0x3C, 0xA5, 0xC1, 0xDC, 0x19, 0x88, - 0xD9, 0x7F, 0x5F, 0xB6, 0x20, 0x8C, 0x64, 0xDE, - 0xA9, 0x5E, 0x1C, 0x78, 0xF3, 0x37, 0xCE, 0x20, - 0xA2, 0xB4, 0xDF, 0x17, 0xA7, 0xB8, 0x23, 0x6A, - 0x90, 0xD6, 0x28, 0x67, 0x33, 0x16, 0x35, 0x72, - 0xC8, 0x67, 0xD9, 0x3D, 0xE8, 0x9E, 0xF6, 0x2F, - 0xA0, 0x5D, 0xAB, 0x70, 0x7E, 0xC3, 0xA7, 0x70 - }, - { - 0xA0, 0xF7, 0xE9, 0x3C, 0xF3, 0x25, 0x02, 0xB9, - 0xFD, 0x79, 0xEC, 0x20, 0x54, 0x62, 0x07, 0xF3, - 0x31, 0xC5, 0x29, 0x9E, 0xCE, 0xF3, 0x50, 0xD6, - 0x6E, 0xA8, 0x55, 0xC8, 0x7F, 0xBD, 0xDF, 0x18, - 0xE6, 0x91, 0xC2, 0x0D, 0x04, 0x5A, 0x30, 0x8F, - 0x83, 0xF6, 0xCB, 0x8F, 0xCA, 0x69, 0xD7, 0xE2, - 0xB3, 0x9B, 0x34, 0xD2, 0xF8, 0x77, 0x27, 0x6C, - 0x19, 0x6B, 0xF5, 0x14, 0xBA, 0xC6, 0x02, 0x70 - }, - { - 0x6F, 0x50, 0x93, 0xCF, 0xC8, 0x83, 0x00, 0xBF, - 0x68, 0x8E, 0x88, 0x4B, 0x4C, 0x5E, 0xC2, 0xC3, - 0x1A, 0x8C, 0xC2, 0x8D, 0x63, 0x31, 0xAD, 0x7C, - 0xA7, 0x1D, 0x97, 0x60, 0x21, 0x64, 0x82, 0x05, - 0x28, 0x15, 0xD4, 0x4F, 0xC6, 0x9E, 0x18, 0xA8, - 0xDC, 0x8B, 0xD7, 0x1B, 0x31, 0xF2, 0xB5, 0x89, - 0xA7, 0xC0, 0x78, 0x0B, 0x61, 0x99, 0x38, 0x5F, - 0x8D, 0xAE, 0x6C, 0x9B, 0x79, 0x74, 0xC4, 0xCB - }, - { - 0x3C, 0xFF, 0x46, 0xAC, 0x35, 0x46, 0xF6, 0x5A, - 0xD7, 0xA7, 0x20, 0x87, 0x1A, 0xFA, 0x20, 0xA9, - 0x21, 0x6D, 0xDA, 0x5C, 0x45, 0x18, 0x81, 0x56, - 0xA5, 0xBB, 0xED, 0xF2, 0x15, 0x46, 0xD4, 0xBB, - 0x39, 0x40, 0xB2, 0x1A, 0x41, 0xA3, 0x94, 0x03, - 0xE3, 0xCF, 0xD5, 0xE7, 0xA0, 0xE7, 0x90, 0x4D, - 0xA9, 0x5F, 0x4D, 0x8E, 0x0C, 0x5B, 0xF5, 0xB7, - 0x0E, 0xB0, 0x29, 0x55, 0x6E, 0xFD, 0x49, 0x7E - }, - { - 0xAF, 0x66, 0x8A, 0x80, 0x5E, 0x6D, 0x70, 0x4B, - 0x1E, 0x58, 0x1F, 0x1E, 0x8E, 0x3C, 0x00, 0xCF, - 0x4C, 0xF3, 0xE5, 0x46, 0x14, 0x7C, 0x40, 0x6D, - 0x17, 0xCA, 0x97, 0x4D, 0x19, 0xA0, 0x14, 0xC7, - 0x8B, 0x44, 0xE7, 0x2D, 0xDE, 0xEB, 0x65, 0x26, - 0x07, 0xE8, 0x6D, 0x69, 0x02, 0x59, 0xDC, 0xAB, - 0x0D, 0xDA, 0x81, 0xC7, 0x7C, 0x7E, 0xE2, 0x72, - 0x1E, 0x82, 0xBB, 0xB1, 0x39, 0x43, 0x07, 0x1D - }, - { - 0x79, 0xDD, 0xEB, 0x5C, 0x54, 0xDE, 0xD1, 0xE4, - 0x48, 0x40, 0x71, 0xC4, 0x6B, 0xB4, 0x28, 0x02, - 0xD2, 0x3B, 0x3A, 0x08, 0xC1, 0x23, 0x11, 0xBE, - 0x36, 0x3C, 0x7C, 0x7A, 0x02, 0x5A, 0x17, 0x64, - 0xC8, 0xD8, 0x50, 0x69, 0xFD, 0xA8, 0xD5, 0x17, - 0x77, 0x7D, 0x8D, 0xD8, 0x09, 0xE3, 0xD4, 0xA9, - 0x56, 0x04, 0x1A, 0x70, 0x79, 0xF9, 0x16, 0x7B, - 0x0F, 0xE9, 0x71, 0x2E, 0x5F, 0x12, 0x29, 0xF5 - }, - { - 0x99, 0x8E, 0x82, 0xF4, 0x26, 0x3D, 0x53, 0xAE, - 0xDA, 0xC9, 0x39, 0xEB, 0xB6, 0xEB, 0x8B, 0x19, - 0x69, 0x74, 0x6C, 0xB8, 0x15, 0xBD, 0x72, 0x1F, - 0x17, 0xA4, 0x8B, 0xEE, 0x9E, 0xCF, 0xF2, 0xFE, - 0x59, 0x8C, 0x53, 0x9C, 0x41, 0x9A, 0x60, 0xE0, - 0xD5, 0xA0, 0x4F, 0x1C, 0xB5, 0x23, 0xA2, 0xFD, - 0x05, 0x38, 0xBB, 0x17, 0x8E, 0x44, 0x75, 0x8D, - 0x31, 0x59, 0xAB, 0x9E, 0x02, 0x84, 0x01, 0xA3 - }, - { - 0x33, 0x96, 0xCF, 0xD5, 0xCD, 0xE1, 0x4A, 0xEC, - 0x1A, 0xAE, 0xD3, 0xE1, 0x22, 0x52, 0xCF, 0xD6, - 0xE3, 0x42, 0xED, 0x25, 0x5E, 0x8E, 0x9E, 0x1B, - 0xE1, 0x0F, 0x1F, 0x27, 0x38, 0x77, 0xF3, 0x63, - 0x33, 0x81, 0xE3, 0xC9, 0x61, 0xE6, 0x7E, 0xC4, - 0x1E, 0x8F, 0x9E, 0x16, 0x11, 0x0F, 0xC0, 0x3D, - 0xDE, 0x88, 0xBF, 0xC0, 0x96, 0xFC, 0x15, 0x14, - 0x46, 0x1D, 0x70, 0xD0, 0xBE, 0xCE, 0x0A, 0xF6 - }, - { - 0x77, 0x7D, 0x9D, 0xC5, 0x5A, 0x2F, 0x57, 0xA4, - 0x6E, 0xA0, 0x6A, 0x2F, 0x4C, 0xB9, 0x76, 0x0D, - 0x00, 0xD7, 0xA8, 0x62, 0xD0, 0xA2, 0xAA, 0x19, - 0x46, 0x7B, 0x57, 0x0F, 0x7C, 0x7D, 0x5E, 0xA7, - 0x62, 0x9A, 0x95, 0xEB, 0x20, 0x0E, 0x1F, 0x9D, - 0xB0, 0x66, 0x10, 0xCF, 0x8E, 0x30, 0xD5, 0xE6, - 0xAD, 0x0A, 0x7B, 0x63, 0x29, 0x77, 0xFC, 0x21, - 0xBB, 0x17, 0x89, 0x67, 0xF3, 0xB0, 0xE0, 0x9B - }, - { - 0x32, 0xEE, 0x35, 0x7F, 0xC9, 0x16, 0x36, 0xA8, - 0x55, 0xBA, 0x01, 0xA0, 0xB8, 0xDA, 0x6F, 0x35, - 0x53, 0xB1, 0xD5, 0x20, 0xAD, 0xCF, 0xE8, 0xFE, - 0x9D, 0xEB, 0xCC, 0xB2, 0x6C, 0x5C, 0x4C, 0xE8, - 0x50, 0x5B, 0xB1, 0xEF, 0xB5, 0xED, 0x5B, 0xAA, - 0x4C, 0x52, 0x45, 0xB5, 0x0D, 0x74, 0x46, 0x3F, - 0x07, 0x67, 0xB2, 0xC7, 0x83, 0xC4, 0x7A, 0x93, - 0xB0, 0xFD, 0xA6, 0x68, 0x95, 0x69, 0x3C, 0xE6 - }, - { - 0x34, 0x0C, 0x0A, 0x7C, 0xE4, 0x96, 0xFE, 0xBD, - 0xA1, 0x3F, 0xA2, 0x40, 0x7A, 0x21, 0xDC, 0x19, - 0x83, 0x9B, 0xED, 0xAE, 0x1A, 0x08, 0x6A, 0xD0, - 0xFE, 0xD3, 0x91, 0x7D, 0xF9, 0xBF, 0x40, 0x94, - 0x4A, 0x78, 0x7F, 0x64, 0x1E, 0x90, 0xDD, 0xBA, - 0xE0, 0x3A, 0x93, 0x37, 0x72, 0x3E, 0x51, 0x66, - 0x8F, 0xB8, 0x93, 0x77, 0x2C, 0x0F, 0xBD, 0xB3, - 0xEB, 0x7E, 0xF7, 0x90, 0xDF, 0xCB, 0xB9, 0xAB - }, - { - 0xD8, 0x6A, 0x5B, 0xAA, 0x33, 0x65, 0xAB, 0xD8, - 0xF4, 0x42, 0xCD, 0x6E, 0xBB, 0x93, 0x11, 0x38, - 0x19, 0xF0, 0xB4, 0x60, 0x61, 0xE1, 0x34, 0x04, - 0xEF, 0xAA, 0x1A, 0x58, 0xE1, 0xFF, 0x27, 0x2A, - 0xD4, 0xBF, 0xD3, 0x08, 0x15, 0xAD, 0xD8, 0x8A, - 0xD9, 0x8F, 0xCE, 0x9A, 0xF0, 0x18, 0x37, 0x4C, - 0xA6, 0x0D, 0x89, 0x79, 0x0F, 0x71, 0xA6, 0x07, - 0x5F, 0x3D, 0x68, 0xD3, 0x20, 0x21, 0xA9, 0xEB - }, - { - 0xA6, 0x7E, 0x6E, 0xC6, 0x57, 0xC9, 0x5E, 0xAB, - 0x3C, 0x3C, 0x32, 0xE4, 0x1F, 0xBF, 0x39, 0xCF, - 0x20, 0x33, 0xAB, 0x4B, 0xE2, 0xE2, 0xB8, 0x21, - 0x10, 0x4A, 0xDB, 0xE6, 0x9D, 0x16, 0xE9, 0x48, - 0xDC, 0xE4, 0xC4, 0xC6, 0xA3, 0xCF, 0x22, 0x76, - 0x90, 0x1F, 0x7D, 0x4F, 0xFD, 0x69, 0x65, 0x46, - 0x49, 0x88, 0x2C, 0x01, 0x4D, 0x2C, 0x10, 0xA1, - 0x30, 0x2B, 0x79, 0xC6, 0x15, 0x69, 0xCD, 0x36 - }, - { - 0x55, 0xCE, 0x19, 0x2A, 0xE4, 0xB3, 0xEA, 0xF8, - 0x55, 0x59, 0x0E, 0x2D, 0x44, 0xE6, 0x25, 0xD9, - 0xBA, 0x14, 0x6E, 0xB7, 0x50, 0x48, 0xE6, 0xB5, - 0x6E, 0x02, 0x50, 0x31, 0xEF, 0xBA, 0x0B, 0xDA, - 0x8A, 0xAA, 0xFA, 0x04, 0x70, 0xB7, 0xAC, 0x3D, - 0x40, 0x6E, 0x5A, 0xBA, 0x3E, 0x83, 0x2F, 0x27, - 0xA5, 0x07, 0x24, 0x6D, 0x1B, 0x5F, 0x33, 0xDE, - 0xA1, 0xF7, 0x24, 0xE2, 0xB8, 0x1B, 0x0C, 0x98 - }, - { - 0xB3, 0xA2, 0x0C, 0x1F, 0xB0, 0xB4, 0xF0, 0xD3, - 0x77, 0x26, 0xC2, 0x3B, 0x58, 0x77, 0xDD, 0x8E, - 0x72, 0xF6, 0x98, 0x86, 0xE0, 0x9A, 0x8C, 0x68, - 0xCF, 0xC3, 0x01, 0xD2, 0xA3, 0xF2, 0xF9, 0x5C, - 0xEF, 0xCF, 0xAB, 0xB8, 0x88, 0x99, 0x03, 0xC7, - 0x32, 0xF4, 0xE8, 0x14, 0x32, 0xD3, 0xF6, 0x78, - 0xCC, 0xDF, 0xC3, 0x98, 0xAC, 0xD8, 0xA2, 0xF0, - 0x66, 0x41, 0x10, 0x04, 0x50, 0xD8, 0x9F, 0x32 - }, - { - 0xF7, 0x27, 0x2D, 0x93, 0xC7, 0x01, 0x2D, 0x38, - 0xB2, 0x7F, 0x0C, 0x9A, 0xE2, 0x01, 0x79, 0x58, - 0xBB, 0xA6, 0x66, 0xA9, 0xDE, 0x1E, 0x88, 0x12, - 0xE9, 0x74, 0x37, 0xAE, 0xB2, 0xE0, 0x3C, 0x99, - 0x94, 0x38, 0xF0, 0xBE, 0x33, 0x3D, 0x09, 0xAD, - 0xDB, 0xCF, 0xAA, 0xC7, 0xAA, 0x73, 0xF7, 0xB6, - 0xCC, 0xEC, 0x67, 0xDC, 0x07, 0x79, 0x98, 0xDE, - 0xDB, 0x8C, 0x13, 0x32, 0xBA, 0xC0, 0xFB, 0xA8 - }, - { - 0x1F, 0xE7, 0xB3, 0xDE, 0x34, 0xC0, 0x47, 0x9C, - 0xA8, 0x40, 0x5F, 0x3C, 0xBC, 0xD2, 0xDB, 0x64, - 0xBB, 0x18, 0xDB, 0xB2, 0x91, 0xA5, 0xFE, 0xAA, - 0x16, 0xC5, 0x22, 0x8C, 0x93, 0xEE, 0x21, 0xC7, - 0x11, 0xD6, 0x8A, 0x01, 0x0C, 0x2A, 0xE8, 0x80, - 0x05, 0xEB, 0xAC, 0x95, 0x9E, 0x3A, 0x32, 0x24, - 0x52, 0xF8, 0x62, 0xDD, 0xE9, 0x4B, 0xB9, 0x41, - 0x81, 0x3E, 0x52, 0x4D, 0x23, 0x47, 0xFE, 0xEE - }, - { - 0x4E, 0xE1, 0xD3, 0x88, 0x05, 0xC3, 0x22, 0x84, - 0xEC, 0xEB, 0xE9, 0x2E, 0x3D, 0xF6, 0xCD, 0x98, - 0xC7, 0xD6, 0x68, 0x0E, 0xAB, 0x0D, 0x68, 0x66, - 0x4F, 0x96, 0x70, 0x6C, 0x45, 0x63, 0x3B, 0x1E, - 0x26, 0x82, 0x22, 0xAA, 0x5A, 0x52, 0x79, 0xEF, - 0x01, 0xFC, 0x28, 0x54, 0x32, 0xAB, 0xEE, 0xD7, - 0x4B, 0xA3, 0xDF, 0x18, 0x9F, 0x50, 0xA9, 0x89, - 0xD5, 0x8E, 0x71, 0x30, 0x62, 0x2D, 0xAA, 0x59 - }, - { - 0x0E, 0x14, 0x05, 0x87, 0x1C, 0x87, 0xA5, 0xEA, - 0x40, 0x83, 0x42, 0xF3, 0x9D, 0x34, 0x94, 0xF9, - 0x39, 0xF7, 0x3C, 0x22, 0x60, 0xC2, 0xA4, 0x3A, - 0x5C, 0x9F, 0x1B, 0x57, 0x33, 0x0C, 0xCA, 0x40, - 0x93, 0xFC, 0x1F, 0x42, 0xF9, 0x6D, 0x83, 0x00, - 0x56, 0x77, 0x03, 0x7D, 0xB5, 0x1A, 0xEF, 0x26, - 0xF0, 0x54, 0x38, 0x05, 0x7A, 0xE7, 0x9E, 0xD1, - 0x44, 0x64, 0xFD, 0x8E, 0x57, 0xD1, 0x55, 0x86 - }, - { - 0x17, 0xC5, 0xCA, 0xB4, 0x09, 0x10, 0x73, 0x62, - 0x1B, 0x5C, 0x24, 0xC3, 0x36, 0x31, 0x6D, 0x0C, - 0xF6, 0x49, 0xBA, 0x1E, 0xFF, 0xEB, 0xFC, 0x87, - 0xE0, 0x43, 0x9C, 0xDF, 0x57, 0x88, 0x87, 0xB2, - 0x21, 0x65, 0x6D, 0x33, 0x9A, 0x6F, 0xD1, 0x98, - 0xAB, 0xAE, 0xE6, 0x7E, 0xA1, 0x88, 0xDD, 0x66, - 0x56, 0x78, 0x23, 0xFC, 0x22, 0x0C, 0x52, 0xB5, - 0x74, 0x90, 0x25, 0x14, 0x69, 0xD2, 0x5D, 0x8C - }, - { - 0x57, 0xDC, 0x27, 0x97, 0xD1, 0x42, 0x68, 0x1C, - 0x94, 0xFE, 0x48, 0x86, 0x26, 0x98, 0x6E, 0xD4, - 0xB2, 0x67, 0x03, 0xCB, 0xF6, 0xBF, 0xE5, 0x93, - 0x91, 0x64, 0x36, 0x57, 0x06, 0x5B, 0x2D, 0x46, - 0xE4, 0xB1, 0xDD, 0xB3, 0xAA, 0x83, 0x2C, 0x9B, - 0xD4, 0x49, 0x75, 0x5A, 0xC8, 0xB1, 0xBF, 0x93, - 0x68, 0x97, 0xFB, 0xC6, 0xAD, 0xE3, 0x78, 0xF2, - 0xBD, 0x64, 0x93, 0xE4, 0x86, 0xF4, 0x20, 0x29 - }, - { - 0x44, 0x12, 0xDD, 0x6B, 0xED, 0x6D, 0xB2, 0xA8, - 0x03, 0xC2, 0xE0, 0xDF, 0x8F, 0x58, 0x29, 0xE7, - 0xA4, 0xB0, 0x41, 0x78, 0x89, 0x51, 0x0D, 0xF7, - 0xDF, 0xEE, 0x49, 0x57, 0x4A, 0x71, 0xEC, 0x0D, - 0x9E, 0x0D, 0x46, 0x06, 0x50, 0x17, 0xC7, 0x2D, - 0xD9, 0x74, 0x39, 0x33, 0xCA, 0x83, 0x9A, 0x76, - 0x8D, 0xD1, 0x5A, 0xB0, 0xB7, 0xC1, 0x4C, 0x62, - 0x6A, 0x35, 0x41, 0x09, 0x69, 0x01, 0x96, 0xAE - }, - { - 0xD0, 0xEB, 0xC7, 0x71, 0x03, 0x1B, 0x7C, 0x16, - 0x00, 0x21, 0xC9, 0xB6, 0xFB, 0xB2, 0xB6, 0x70, - 0xE3, 0xB4, 0x02, 0x70, 0x02, 0x69, 0x07, 0xA3, - 0x91, 0x63, 0xDB, 0x18, 0x73, 0xEC, 0xC3, 0xB8, - 0x00, 0x11, 0x1D, 0xD7, 0xBF, 0x13, 0x8F, 0x83, - 0xA6, 0x10, 0xDC, 0x04, 0x6D, 0xA2, 0x68, 0xB7, - 0x2B, 0x8C, 0x90, 0x86, 0x92, 0x23, 0x77, 0xDB, - 0xED, 0x73, 0x94, 0x82, 0x43, 0xCA, 0x1E, 0x14 - }, - { - 0x10, 0xC4, 0xBA, 0x31, 0x55, 0x91, 0x69, 0x8D, - 0xFB, 0x91, 0xA5, 0x73, 0x37, 0x63, 0x18, 0x84, - 0xB4, 0x73, 0x8D, 0x9F, 0x59, 0x80, 0x78, 0x51, - 0xA6, 0x79, 0x84, 0x0C, 0xC2, 0x87, 0xAC, 0xE3, - 0x01, 0x1C, 0xCD, 0xC8, 0xF4, 0xA4, 0x85, 0xBB, - 0x19, 0x73, 0x40, 0x4E, 0xF9, 0xEE, 0x9B, 0x9C, - 0xF1, 0xEA, 0xDB, 0xC5, 0x40, 0x74, 0xC6, 0xD1, - 0x13, 0xDE, 0x8F, 0xC9, 0x1D, 0x07, 0x97, 0xEB - }, - { - 0x14, 0x64, 0x34, 0x7B, 0xE3, 0x2C, 0x79, 0x59, - 0x17, 0x2B, 0x74, 0x72, 0xD1, 0x1F, 0xE0, 0x78, - 0x44, 0xA5, 0x2E, 0x2D, 0x3B, 0x2D, 0x05, 0x8C, - 0xC6, 0xBC, 0xC0, 0xA8, 0xA2, 0x75, 0xD6, 0xB8, - 0x2B, 0x2D, 0x62, 0x63, 0x75, 0x5E, 0xAF, 0x2A, - 0x65, 0x88, 0xB6, 0xA1, 0xEB, 0x79, 0x9A, 0xF8, - 0x3A, 0x4C, 0xE7, 0x53, 0xF8, 0xC7, 0x5A, 0x22, - 0x84, 0xD0, 0x28, 0x5B, 0xAB, 0x5F, 0x7C, 0x1C - }, - { - 0xF4, 0x09, 0x23, 0x1E, 0xD1, 0x87, 0xF5, 0xC4, - 0xE8, 0x33, 0xFA, 0x9E, 0x30, 0x42, 0xAC, 0xA6, - 0xC8, 0x58, 0xB0, 0x8B, 0x49, 0x6B, 0x25, 0x31, - 0xF8, 0x4F, 0xD5, 0xCE, 0xA9, 0x3E, 0xCD, 0x06, - 0xDA, 0xFE, 0x0A, 0x10, 0xC3, 0xFF, 0x23, 0x76, - 0xC7, 0x4D, 0xC8, 0x0D, 0xA0, 0x7D, 0xA0, 0x18, - 0x64, 0xFB, 0xF2, 0x68, 0x59, 0x60, 0xB5, 0x40, - 0xB3, 0xA2, 0xE9, 0x42, 0xCB, 0x8D, 0x90, 0x9F - }, - { - 0x39, 0x51, 0x32, 0xC5, 0x80, 0xC3, 0x55, 0xB5, - 0xB0, 0xE2, 0x35, 0x33, 0x6C, 0x8D, 0xC1, 0x08, - 0x5E, 0x59, 0x59, 0x64, 0x04, 0x3D, 0x38, 0x9E, - 0x08, 0x1E, 0xFE, 0x48, 0x5B, 0xA4, 0xC6, 0x37, - 0x72, 0xDB, 0x8D, 0x7E, 0x0F, 0x18, 0x6C, 0x50, - 0x98, 0x2E, 0x12, 0x23, 0xEA, 0x78, 0x5A, 0xDC, - 0x74, 0x0B, 0x0C, 0xF2, 0x18, 0x70, 0x74, 0x58, - 0xB8, 0xB8, 0x03, 0x40, 0x42, 0xF9, 0x23, 0xC2 - }, - { - 0xF9, 0x2A, 0xBA, 0xCA, 0x21, 0x32, 0x29, 0x66, - 0x06, 0x49, 0xEF, 0x2D, 0x8F, 0x88, 0x11, 0x5B, - 0x5B, 0xED, 0x8A, 0xB5, 0xB9, 0xBC, 0xA9, 0xA1, - 0xB4, 0xC5, 0x24, 0x57, 0x03, 0x53, 0x10, 0xC4, - 0x1A, 0x6B, 0xEA, 0x2B, 0x23, 0xB7, 0x91, 0x8B, - 0x5B, 0x8B, 0xF3, 0x8B, 0x52, 0xEA, 0xC6, 0xFF, - 0x3B, 0x62, 0x13, 0xA5, 0x22, 0xF3, 0x81, 0xBE, - 0x7F, 0xF0, 0x90, 0x6D, 0xBA, 0x7B, 0xD0, 0x0C - }, - { - 0xCB, 0xAD, 0xE7, 0xAD, 0x3B, 0x5D, 0xEE, 0x0F, - 0xF1, 0xA4, 0x6B, 0x08, 0x2C, 0xF4, 0xE1, 0xE1, - 0xDC, 0x21, 0x62, 0x0D, 0xD2, 0xCC, 0x0E, 0xDC, - 0x2C, 0x70, 0x7A, 0x21, 0x62, 0xD2, 0x14, 0x99, - 0x69, 0xAB, 0xBB, 0x29, 0xC5, 0x72, 0x0B, 0x04, - 0xBD, 0x15, 0x68, 0xA9, 0x55, 0x61, 0x95, 0xE6, - 0x7F, 0x24, 0x32, 0x2D, 0xD9, 0xAA, 0x4E, 0x83, - 0x65, 0x19, 0x1A, 0xA5, 0xB6, 0xC4, 0x45, 0x79 - }, - { - 0xF5, 0x1B, 0x4A, 0xE4, 0xD4, 0xC5, 0x4A, 0x29, - 0xCF, 0x71, 0x35, 0xA8, 0xFE, 0x1E, 0xAB, 0xD5, - 0xE1, 0xBC, 0xBF, 0x82, 0x08, 0x96, 0x96, 0x7D, - 0xC4, 0x1E, 0x38, 0x49, 0xDA, 0xC2, 0x25, 0x07, - 0x69, 0x42, 0x10, 0xCA, 0x11, 0xC4, 0xEB, 0xF1, - 0xC2, 0x9A, 0x8D, 0x4F, 0x71, 0xB3, 0x0F, 0x76, - 0xC9, 0xB6, 0x01, 0x0A, 0xD9, 0x5B, 0xDF, 0xB0, - 0xDE, 0x83, 0x79, 0x25, 0xF0, 0x61, 0x25, 0x97 - }, - { - 0xCE, 0x38, 0x72, 0x11, 0x5D, 0x83, 0x3B, 0x34, - 0x56, 0xCA, 0x94, 0x2E, 0x6E, 0x38, 0x5F, 0x28, - 0xA9, 0x03, 0xBE, 0xAB, 0xFB, 0x75, 0x3F, 0x8A, - 0xFC, 0xCC, 0x12, 0xF2, 0x58, 0x2C, 0xE1, 0xF3, - 0x62, 0x12, 0xBD, 0x05, 0xE0, 0x5A, 0x46, 0xFC, - 0x88, 0xD3, 0x19, 0x50, 0xB4, 0x91, 0x1A, 0xE5, - 0xDC, 0xD8, 0xFF, 0x7A, 0x0B, 0x50, 0x47, 0x4C, - 0xB4, 0x88, 0xCC, 0xF2, 0xA8, 0x9C, 0xD0, 0xEB - }, - { - 0x9B, 0xB7, 0x4C, 0xBD, 0x47, 0xA6, 0x24, 0xCB, - 0xEA, 0xFC, 0xC1, 0x6D, 0x46, 0x29, 0x47, 0xBB, - 0xEA, 0x13, 0x70, 0xB8, 0x5C, 0x96, 0x1A, 0x40, - 0x7D, 0xF9, 0x86, 0x3E, 0x54, 0xE6, 0xD9, 0xE6, - 0xA8, 0xD2, 0xEF, 0x0C, 0x64, 0x97, 0x20, 0x5E, - 0x5E, 0xB7, 0xC3, 0xE5, 0x9E, 0x69, 0x8D, 0x99, - 0x24, 0x63, 0xCA, 0x9D, 0xD4, 0xCF, 0x28, 0xCF, - 0x9A, 0x2D, 0x4E, 0x30, 0xC1, 0x33, 0xE8, 0x55 - }, - { - 0x72, 0x96, 0x33, 0x82, 0x0B, 0xF0, 0x13, 0xD9, - 0xD2, 0xBD, 0x37, 0x3C, 0xCA, 0xC7, 0xBC, 0x9F, - 0x37, 0x16, 0xF6, 0x9E, 0x16, 0xA4, 0x4E, 0x94, - 0x9C, 0x7A, 0x9A, 0x93, 0xDC, 0xA1, 0x26, 0xBB, - 0x1A, 0xA5, 0x4E, 0x5E, 0x70, 0x40, 0x70, 0x7F, - 0x02, 0x87, 0x6A, 0xFD, 0x02, 0x0A, 0xF4, 0x72, - 0x63, 0x9D, 0x49, 0xF5, 0x42, 0x0D, 0x29, 0x4C, - 0x3A, 0xA3, 0x1D, 0x06, 0x7E, 0x3E, 0x85, 0x75 - }, - { - 0x06, 0x86, 0x1D, 0xB3, 0x07, 0xC6, 0x78, 0x08, - 0x6E, 0x8B, 0x2A, 0xEC, 0xDF, 0x18, 0x29, 0xD2, - 0x88, 0x3D, 0x28, 0xB7, 0x31, 0xAB, 0xD0, 0xF1, - 0xE7, 0x2F, 0x1C, 0xED, 0x6C, 0x7A, 0xD4, 0x17, - 0x2E, 0xCA, 0x63, 0x22, 0xA8, 0x3F, 0xB6, 0xA6, - 0x5A, 0xFA, 0x37, 0xE9, 0x4A, 0x3E, 0x2B, 0xA2, - 0x05, 0xB8, 0x7B, 0xF3, 0x82, 0xD9, 0x15, 0x88, - 0x49, 0x7A, 0x46, 0x50, 0x88, 0x3B, 0xD8, 0x75 - }, - { - 0x35, 0x6E, 0xCE, 0xAF, 0x17, 0x02, 0xB3, 0x70, - 0xF4, 0xAA, 0xB8, 0xEA, 0x82, 0x84, 0x86, 0xF3, - 0x30, 0x13, 0xF7, 0x44, 0xB3, 0x9E, 0x7E, 0xA2, - 0x6C, 0x69, 0x18, 0xD6, 0x0E, 0x1A, 0xBC, 0xF4, - 0x4F, 0xB1, 0x6E, 0xDC, 0xA7, 0x72, 0x0A, 0xCF, - 0xC6, 0xA7, 0x01, 0xBF, 0x1E, 0x2C, 0x35, 0xDD, - 0xBD, 0x69, 0x5A, 0x8D, 0x40, 0x8E, 0x8C, 0x96, - 0x32, 0xE8, 0xCD, 0x27, 0x23, 0x0C, 0xAD, 0x8D - }, - { - 0x48, 0x9A, 0x39, 0xD0, 0xFC, 0x3C, 0xDE, 0xAF, - 0x42, 0x89, 0x2E, 0xD8, 0x03, 0x85, 0xC1, 0x1C, - 0xE2, 0x93, 0xC9, 0x32, 0x21, 0x5B, 0xB2, 0x31, - 0x88, 0x69, 0x2A, 0x86, 0xE6, 0x1B, 0xCA, 0xD9, - 0x2C, 0x2A, 0x1D, 0x11, 0x42, 0x60, 0x1B, 0x1B, - 0xDF, 0x09, 0x82, 0xD1, 0xCD, 0x1E, 0x05, 0xC0, - 0x52, 0xDE, 0x81, 0x9E, 0x64, 0xF2, 0x47, 0xDB, - 0x35, 0x91, 0x5D, 0xD1, 0xDB, 0x79, 0xA3, 0xB5 - }, - { - 0xC0, 0x2F, 0x46, 0x4B, 0x4D, 0xD1, 0x81, 0x17, - 0xE3, 0x0A, 0x8D, 0xB8, 0xEF, 0x1D, 0xA0, 0x67, - 0x13, 0x4B, 0x60, 0x4E, 0xFA, 0x19, 0x51, 0x76, - 0x7E, 0xE6, 0x32, 0xDC, 0x02, 0x4D, 0x64, 0xC0, - 0x0F, 0x24, 0x49, 0xF0, 0x42, 0xDB, 0x3A, 0xEA, - 0x01, 0x74, 0xEB, 0xCD, 0xBB, 0x4F, 0xF5, 0x9D, - 0xAE, 0x75, 0x4F, 0x72, 0x39, 0x46, 0xF1, 0xB9, - 0x0A, 0x77, 0xFD, 0x95, 0x23, 0x69, 0x0B, 0x7B - }, - { - 0xFB, 0x31, 0xE6, 0xDD, 0xB8, 0x6D, 0xBF, 0xF3, - 0x72, 0x64, 0x6D, 0x1E, 0x3A, 0x3F, 0x31, 0xDD, - 0x61, 0x15, 0x9F, 0xC3, 0x93, 0x65, 0x8C, 0x2E, - 0xE9, 0x57, 0x10, 0x3B, 0xF2, 0x11, 0x6B, 0xDE, - 0xF8, 0x2C, 0x33, 0xE8, 0x69, 0xF3, 0xC8, 0x3A, - 0xC3, 0xC2, 0xF6, 0x38, 0x0C, 0xF6, 0x92, 0xF7, - 0xB1, 0xDC, 0xBA, 0xE0, 0xBB, 0x22, 0x7A, 0xD3, - 0x47, 0xE7, 0x54, 0x13, 0x74, 0x66, 0xC6, 0x9F - }, - { - 0x00, 0x60, 0x62, 0xAB, 0xE1, 0x6C, 0x2F, 0xE7, - 0x9A, 0xF8, 0x80, 0x85, 0xE0, 0xB5, 0x82, 0xB1, - 0x06, 0xE7, 0xF7, 0x9F, 0x01, 0xA4, 0x39, 0x46, - 0xC7, 0x8B, 0x19, 0xF9, 0xBD, 0xD7, 0x25, 0x99, - 0x76, 0x36, 0xA3, 0x32, 0xEB, 0x9A, 0x3A, 0xAA, - 0x6D, 0xE0, 0xD4, 0xA8, 0xE9, 0xE2, 0x8E, 0x8C, - 0x77, 0x87, 0x74, 0x22, 0x4C, 0x66, 0x5B, 0xF7, - 0xBC, 0x36, 0x44, 0xFC, 0xE4, 0x11, 0x22, 0x8C - }, - { - 0xD4, 0x4A, 0x6D, 0xB3, 0xDE, 0x9F, 0xD4, 0xE4, - 0xA7, 0xEF, 0x15, 0x5A, 0x01, 0xBC, 0xCB, 0x91, - 0xC1, 0xBC, 0xF1, 0xCB, 0x53, 0x22, 0x56, 0x89, - 0xA7, 0x7A, 0x0D, 0x23, 0xB4, 0xD3, 0x9A, 0x89, - 0xA1, 0x89, 0xF2, 0x89, 0x80, 0xF9, 0x1C, 0x56, - 0xEA, 0xC5, 0x87, 0x9E, 0xAE, 0x93, 0x3C, 0xED, - 0x7F, 0x26, 0x7E, 0x2F, 0x70, 0x40, 0xEB, 0x38, - 0x0F, 0xDB, 0xBF, 0x34, 0xA6, 0xB7, 0xB6, 0x15 - }, - { - 0x5A, 0xFB, 0xFE, 0xA1, 0xDE, 0xDA, 0x5A, 0xEA, - 0xB9, 0x2E, 0x4D, 0x0C, 0x31, 0xD1, 0x6A, 0x9A, - 0x86, 0xBF, 0x7C, 0x75, 0x23, 0x27, 0x4A, 0x05, - 0xC5, 0x05, 0x29, 0xF5, 0xC1, 0x39, 0xDB, 0x10, - 0x93, 0x3A, 0x52, 0xC6, 0x22, 0x9C, 0xD3, 0x11, - 0x08, 0xF0, 0x83, 0xFB, 0x0C, 0x85, 0xCF, 0x52, - 0x83, 0x1B, 0x5A, 0x05, 0xF2, 0x55, 0x0A, 0x77, - 0xB5, 0x70, 0x3C, 0xC6, 0x68, 0x91, 0x2D, 0xBC - }, - { - 0xD1, 0x7F, 0xCA, 0xD4, 0xE0, 0xD8, 0xBD, 0xE2, - 0xED, 0xFD, 0xA1, 0x68, 0xBA, 0x47, 0x10, 0x4B, - 0xBC, 0xA4, 0xD2, 0x6D, 0xA2, 0xD3, 0x1A, 0x07, - 0x0B, 0x0F, 0xBA, 0x0B, 0x26, 0xEE, 0xDD, 0x95, - 0xEE, 0xC1, 0xFC, 0x34, 0xD7, 0x6C, 0xD4, 0xA1, - 0xCB, 0x15, 0xF2, 0x62, 0x16, 0x88, 0xA9, 0xCC, - 0x0E, 0x96, 0x35, 0x8D, 0xE9, 0x93, 0x22, 0x2B, - 0xB3, 0xE3, 0xCD, 0x0B, 0xFD, 0xCB, 0x74, 0x6C - }, - { - 0xBD, 0x6A, 0x59, 0x21, 0x63, 0x37, 0xB4, 0x5D, - 0x6B, 0x71, 0xAE, 0xAC, 0x01, 0x36, 0x6B, 0xFE, - 0x96, 0x60, 0xE0, 0xFB, 0xC2, 0x95, 0x9A, 0xDB, - 0xB6, 0x8D, 0x52, 0x6C, 0x43, 0xD4, 0x8F, 0xFF, - 0xFE, 0x2F, 0xFC, 0x43, 0x05, 0x88, 0xE7, 0x8E, - 0x66, 0x54, 0x6A, 0x3C, 0x70, 0x9B, 0x0A, 0xCE, - 0xA1, 0x7C, 0xBC, 0x5A, 0x21, 0x8C, 0x53, 0xCD, - 0x47, 0xAA, 0x48, 0x71, 0xC1, 0xDD, 0x98, 0x4A - }, - { - 0x83, 0xEA, 0x5A, 0xE1, 0x89, 0x11, 0x45, 0xC4, - 0x1A, 0x7C, 0x6C, 0x87, 0xFE, 0x92, 0x24, 0x87, - 0xF5, 0xD2, 0x82, 0x93, 0x35, 0x69, 0xB7, 0xAE, - 0x0E, 0x34, 0x56, 0x53, 0x38, 0x1E, 0xDE, 0x6D, - 0x4B, 0x16, 0xE1, 0x44, 0xD1, 0xC3, 0xE8, 0xF0, - 0x60, 0x5D, 0xAA, 0x0D, 0xB5, 0x96, 0x5A, 0x7B, - 0x79, 0xD9, 0x1A, 0x8A, 0xFE, 0x11, 0xF1, 0xE0, - 0xBC, 0x54, 0x9A, 0xC0, 0x74, 0xA0, 0x1A, 0xB7 - }, - { - 0x37, 0x50, 0x50, 0xCF, 0x2E, 0x43, 0x0D, 0x0E, - 0x29, 0x87, 0x58, 0x35, 0x20, 0x8E, 0x89, 0x06, - 0xD7, 0x05, 0x2E, 0x47, 0x29, 0x2C, 0x5A, 0x38, - 0xA6, 0x30, 0x82, 0x87, 0x3D, 0x31, 0xD5, 0x83, - 0x13, 0x5C, 0x07, 0xA2, 0x0C, 0x52, 0xD9, 0x5B, - 0x2D, 0x5D, 0xC3, 0xEA, 0xDE, 0x6B, 0xE1, 0x43, - 0xCA, 0x34, 0x38, 0xF4, 0x4D, 0x02, 0x0A, 0xAE, - 0x16, 0x0E, 0xD7, 0x7A, 0xB9, 0x88, 0x4F, 0x7D - }, - { - 0x30, 0x28, 0xB0, 0xE8, 0x24, 0x95, 0x7F, 0xF3, - 0xB3, 0x05, 0xE9, 0x7F, 0xF5, 0x92, 0xAA, 0x8E, - 0xF2, 0x9B, 0x3B, 0xEC, 0x1D, 0xC4, 0x7B, 0x76, - 0x13, 0x3D, 0x10, 0x3F, 0xFE, 0x38, 0x71, 0xBF, - 0x05, 0x12, 0xA2, 0x31, 0xAF, 0xCB, 0x1D, 0xF8, - 0x65, 0x97, 0xEC, 0x5E, 0x46, 0xE9, 0x23, 0xC8, - 0xB9, 0x85, 0xC2, 0x85, 0x08, 0x57, 0xC6, 0x40, - 0x01, 0xB2, 0xC5, 0x51, 0xEA, 0x83, 0x3D, 0x0E - }, - { - 0x08, 0x7C, 0xCB, 0x1E, 0x5B, 0xD1, 0x72, 0x22, - 0xB8, 0xAF, 0x20, 0x6D, 0xD6, 0x39, 0x08, 0xF8, - 0x91, 0x72, 0x97, 0x62, 0x1A, 0x8C, 0xB9, 0x33, - 0x0A, 0xE0, 0xBA, 0x4A, 0xF3, 0xE9, 0xD6, 0x0C, - 0x98, 0xFC, 0xF1, 0xEF, 0xFC, 0xEC, 0x20, 0x13, - 0x6B, 0x4F, 0x91, 0x88, 0x12, 0x6D, 0xFA, 0x04, - 0x4E, 0x1C, 0x1C, 0xCD, 0xA3, 0xCE, 0xD8, 0x73, - 0x73, 0xD9, 0x37, 0x9C, 0xCB, 0xED, 0xBD, 0xB3 - }, - { - 0x7F, 0x17, 0x06, 0x24, 0x98, 0xBF, 0xA2, 0xBB, - 0x58, 0x56, 0xCD, 0x0A, 0x62, 0xC5, 0x68, 0xC5, - 0xC6, 0xB8, 0x97, 0x43, 0x24, 0x74, 0xEF, 0xB2, - 0xE6, 0xA2, 0xEE, 0x18, 0xCA, 0xFF, 0xD2, 0x1E, - 0x1E, 0xF3, 0x0D, 0x06, 0x47, 0x23, 0x85, 0x0F, - 0x79, 0x90, 0xD2, 0x1B, 0xA3, 0x4E, 0x8F, 0x2B, - 0x3B, 0xB0, 0x67, 0x02, 0x3A, 0x77, 0x27, 0x82, - 0x15, 0x8A, 0x27, 0xC6, 0xC4, 0x67, 0xC9, 0x28 - }, - { - 0x6B, 0xA9, 0x86, 0xA9, 0x42, 0x49, 0x7F, 0xD3, - 0x84, 0x62, 0x97, 0x2F, 0x50, 0xA6, 0x19, 0x68, - 0xC0, 0x65, 0x2D, 0xAC, 0x56, 0xCE, 0x9B, 0x9A, - 0xC1, 0xBC, 0x06, 0x1A, 0xB6, 0x34, 0xFE, 0x5A, - 0x77, 0xAC, 0xD0, 0x27, 0x5F, 0x83, 0x96, 0xE3, - 0xC0, 0xBE, 0xF0, 0x12, 0xAE, 0x93, 0xB7, 0x27, - 0x58, 0xB8, 0xD7, 0x67, 0x9C, 0x87, 0xE8, 0x47, - 0xE6, 0x30, 0x17, 0xB5, 0x5A, 0x69, 0xC5, 0xC6 - }, - { - 0x96, 0x7C, 0x81, 0xF5, 0x61, 0x95, 0x18, 0x33, - 0xFA, 0x56, 0x6F, 0x6B, 0x36, 0x07, 0x7E, 0xAD, - 0xB2, 0xA6, 0x15, 0xCC, 0x15, 0xF0, 0xED, 0xBB, - 0xAE, 0x4F, 0x84, 0x4D, 0xDC, 0x8E, 0x9C, 0x1F, - 0xB8, 0x3D, 0x31, 0xA9, 0x3F, 0xCB, 0x17, 0x74, - 0xD7, 0x40, 0xD6, 0x92, 0x08, 0xCA, 0x59, 0x30, - 0xBC, 0xFA, 0xC4, 0xA1, 0xF9, 0x44, 0x46, 0x9F, - 0xEF, 0xD1, 0x9B, 0x6E, 0x93, 0x75, 0xE0, 0xB5 - }, - { - 0xE8, 0xAE, 0xF1, 0x78, 0xE6, 0xDA, 0x3E, 0xF5, - 0xCA, 0xED, 0x65, 0x30, 0xF7, 0xEB, 0x25, 0x60, - 0x82, 0x56, 0xC2, 0x37, 0x7C, 0x4C, 0xF9, 0x6B, - 0x0C, 0xFD, 0x0D, 0x76, 0xEE, 0xB4, 0xBB, 0x86, - 0xEE, 0xFF, 0x7B, 0x7D, 0xF1, 0x58, 0x5C, 0x8D, - 0x7A, 0x20, 0xC0, 0x63, 0x3A, 0x67, 0x90, 0x7F, - 0x6D, 0x28, 0x67, 0xC3, 0x26, 0x4A, 0x91, 0xC0, - 0x51, 0xAB, 0xAE, 0x6E, 0xEA, 0x5A, 0x91, 0xD8 - }, - { - 0x64, 0x81, 0xDC, 0xC8, 0x15, 0x7A, 0xE6, 0x28, - 0xB5, 0xCD, 0x52, 0x6B, 0xAC, 0x8F, 0x93, 0x31, - 0x56, 0xDE, 0xDA, 0xC9, 0x56, 0xA2, 0xB2, 0x2A, - 0x97, 0x4B, 0xF5, 0xF7, 0xEC, 0x2D, 0xB5, 0x80, - 0x6F, 0x53, 0xDD, 0x0E, 0x2D, 0xD5, 0x3D, 0xB8, - 0x7C, 0xD8, 0xF5, 0x8A, 0x58, 0x6F, 0x9B, 0x3C, - 0x5C, 0x52, 0x23, 0x31, 0xA3, 0x11, 0x74, 0xC4, - 0xE7, 0xB9, 0xB6, 0xF7, 0xF0, 0x57, 0xC2, 0x8F - }, - { - 0xA7, 0x1E, 0xA4, 0x5C, 0xE6, 0x61, 0x6A, 0x3D, - 0x2F, 0x0A, 0x59, 0x2D, 0x5D, 0x02, 0x86, 0x93, - 0x2D, 0xA6, 0x3C, 0x6D, 0xB1, 0x1D, 0x59, 0xC6, - 0x69, 0x1C, 0x35, 0xA5, 0x6F, 0x7E, 0xE4, 0xF8, - 0x0B, 0x6F, 0xC3, 0x40, 0xB4, 0xDB, 0xC1, 0x84, - 0x4C, 0x50, 0x40, 0xE6, 0x68, 0xD2, 0x89, 0x2F, - 0x4A, 0x4A, 0xE8, 0x53, 0x3F, 0x1B, 0x67, 0x71, - 0xBC, 0xFC, 0xE7, 0xC3, 0xA2, 0x3E, 0x0D, 0x97 - }, - { - 0x96, 0x93, 0x44, 0x87, 0x70, 0xFE, 0xAE, 0x42, - 0x17, 0x26, 0xEB, 0x20, 0x3B, 0x01, 0xC7, 0x08, - 0x23, 0xD5, 0xF4, 0x4C, 0xC5, 0x21, 0x3E, 0x6A, - 0x68, 0x28, 0x47, 0x29, 0xBD, 0x11, 0x7D, 0x9B, - 0xD1, 0x8F, 0xEC, 0x4A, 0x0A, 0x82, 0x4A, 0x24, - 0x08, 0x0F, 0x29, 0x8B, 0xAC, 0xD2, 0x96, 0xD7, - 0xB4, 0x97, 0x83, 0x8F, 0xBD, 0x7B, 0x0D, 0x57, - 0x5C, 0x52, 0x49, 0x2B, 0x3E, 0x6F, 0x92, 0x6B - }, - { - 0x37, 0xA1, 0x50, 0x66, 0xF2, 0xB9, 0xF9, 0x4C, - 0x24, 0x61, 0x1B, 0xC4, 0x53, 0xED, 0x02, 0x74, - 0x07, 0x8D, 0x1F, 0x70, 0xB2, 0xD3, 0x4C, 0x8B, - 0x96, 0x36, 0x08, 0x48, 0x9D, 0xCB, 0xE8, 0xDF, - 0x44, 0x8E, 0xDD, 0x9C, 0x73, 0x36, 0x2B, 0xB2, - 0xB6, 0x6B, 0xEE, 0xF6, 0x1F, 0xCE, 0x60, 0x10, - 0x6F, 0x70, 0x19, 0xED, 0x37, 0x3C, 0x69, 0x22, - 0x59, 0xD9, 0x55, 0x6A, 0x94, 0x0B, 0x1A, 0x06 - }, - { - 0xBD, 0x44, 0xE7, 0x39, 0xE1, 0xF9, 0xDB, 0x1C, - 0x6B, 0xAF, 0x42, 0xCA, 0x4A, 0x12, 0xAC, 0x09, - 0x9B, 0x96, 0xF6, 0xB3, 0x6C, 0x4B, 0xCB, 0x1B, - 0x72, 0xEE, 0xFF, 0x08, 0xA6, 0x49, 0x68, 0x35, - 0xEC, 0x65, 0x15, 0x0B, 0xE8, 0xFE, 0x16, 0xCB, - 0xE3, 0x27, 0x07, 0xE3, 0x47, 0x54, 0x7D, 0xC5, - 0xA5, 0x83, 0xD2, 0x65, 0x74, 0x6F, 0xA5, 0x95, - 0xC5, 0xE7, 0x73, 0x0F, 0xCF, 0x24, 0x58, 0x1E - }, - { - 0xFA, 0xB2, 0x03, 0x8E, 0x94, 0x98, 0xA1, 0xC3, - 0x9E, 0x05, 0x78, 0xA0, 0xA5, 0xEA, 0x6B, 0x44, - 0xF3, 0xC1, 0xB4, 0x1A, 0xE5, 0x67, 0xF9, 0x91, - 0x4A, 0x95, 0xB1, 0x31, 0xC4, 0x8D, 0x12, 0x1E, - 0xCA, 0xCE, 0xA8, 0x95, 0xA0, 0x9B, 0x1D, 0x4E, - 0x04, 0x42, 0xBE, 0xC9, 0xC5, 0x0C, 0x50, 0xE0, - 0x0A, 0x9F, 0xAF, 0xEF, 0xFA, 0xE0, 0x70, 0x88, - 0x4C, 0x26, 0x25, 0xA8, 0xB1, 0xA2, 0x17, 0x26 - }, - { - 0x05, 0xA1, 0xB7, 0x6B, 0x2F, 0xD5, 0x62, 0x11, - 0xE0, 0xF2, 0xD7, 0x5A, 0x25, 0x16, 0x54, 0xA7, - 0x72, 0xF5, 0x5E, 0x18, 0xCA, 0x02, 0x2A, 0xF5, - 0x2C, 0xB3, 0x30, 0x19, 0x1E, 0x98, 0xA3, 0xB8, - 0xEB, 0x87, 0xE5, 0x11, 0x7B, 0xAE, 0x58, 0x04, - 0x4D, 0x94, 0x4C, 0x1F, 0x18, 0x85, 0x45, 0x12, - 0x25, 0x41, 0x77, 0x35, 0xFC, 0x72, 0xF7, 0x39, - 0x36, 0x69, 0x3C, 0xFF, 0x45, 0x46, 0x9F, 0x8C - }, - { - 0x2A, 0x30, 0xC9, 0x6B, 0xDA, 0xC7, 0x8A, 0x39, - 0x94, 0xEE, 0xCA, 0xA5, 0xA5, 0x3F, 0x82, 0x7F, - 0x58, 0xE1, 0x32, 0x31, 0xA0, 0xD1, 0x13, 0x08, - 0x6C, 0x06, 0xB1, 0xBD, 0xAB, 0xDA, 0x38, 0xD0, - 0x8F, 0x1A, 0xE2, 0x7D, 0xE2, 0x5F, 0xD2, 0x2E, - 0xEA, 0x70, 0xC0, 0x5F, 0x01, 0x32, 0xBF, 0x7A, - 0x50, 0x1C, 0x82, 0xAE, 0x62, 0x15, 0xBF, 0xEF, - 0x3C, 0x01, 0x63, 0x98, 0xBA, 0xF2, 0xCB, 0x62 - }, - { - 0x48, 0xDB, 0x53, 0x76, 0x5B, 0x82, 0xBD, 0x6F, - 0x25, 0x33, 0xEA, 0xE1, 0x7F, 0x67, 0x69, 0xD7, - 0xA4, 0xE3, 0xB2, 0x43, 0x74, 0x60, 0x1C, 0xDD, - 0x8E, 0xC0, 0xCA, 0x3A, 0xAB, 0x30, 0x93, 0xFD, - 0x2B, 0x99, 0x24, 0x38, 0x46, 0x0B, 0xAF, 0x8D, - 0xA5, 0x8F, 0xB9, 0xA8, 0x9B, 0x2C, 0x58, 0xF9, - 0x68, 0xE6, 0x36, 0x17, 0xCB, 0xEB, 0x18, 0x44, - 0xB0, 0x2D, 0x6A, 0x27, 0xC5, 0xB4, 0xAD, 0x41 - }, - { - 0x5C, 0x8B, 0x2E, 0x0E, 0x1B, 0x5C, 0x8F, 0x45, - 0x7D, 0x7F, 0x7B, 0xD9, 0xF0, 0x5A, 0x97, 0xE5, - 0x8D, 0xDA, 0x1D, 0x28, 0xDB, 0x9F, 0x34, 0xD1, - 0xCE, 0x73, 0x25, 0x28, 0xF9, 0x68, 0xBE, 0xDD, - 0x9E, 0x1C, 0xC9, 0x35, 0x2D, 0x0A, 0x5D, 0xF6, - 0x67, 0x29, 0x28, 0xBD, 0xD3, 0xEA, 0x6F, 0x5C, - 0xB0, 0x60, 0x77, 0xCF, 0x3A, 0xD3, 0xA7, 0x6E, - 0x29, 0xB2, 0x2E, 0x82, 0xBA, 0xC6, 0x7B, 0x61 - }, - { - 0x5B, 0x73, 0x91, 0xAA, 0x52, 0xF2, 0x76, 0xFA, - 0xB9, 0xC1, 0x38, 0x77, 0xF1, 0x22, 0x32, 0x70, - 0x84, 0x97, 0xFC, 0x02, 0x8F, 0xAA, 0x17, 0x32, - 0xA5, 0xDB, 0x07, 0x9E, 0x7F, 0xE0, 0x73, 0xED, - 0x0C, 0xC9, 0x52, 0x9C, 0xFC, 0x86, 0x3A, 0x4E, - 0xCB, 0xA4, 0xDC, 0x2F, 0x1E, 0xA9, 0xF6, 0xBD, - 0x69, 0x04, 0xF3, 0xA0, 0xC1, 0x07, 0x19, 0x3C, - 0x5E, 0x71, 0x1C, 0xB9, 0x11, 0xF3, 0x80, 0x25 - }, - { - 0x1D, 0x5A, 0xF7, 0x0F, 0x09, 0xA5, 0xFC, 0x69, - 0x16, 0xEF, 0x59, 0xA3, 0x8A, 0x86, 0x92, 0x6D, - 0xCA, 0xAE, 0x39, 0xA8, 0x95, 0x4D, 0x73, 0xFC, - 0x80, 0xA3, 0x50, 0x75, 0x1A, 0xDD, 0xA3, 0x8C, - 0x9D, 0x59, 0x75, 0x06, 0xDC, 0x05, 0xE1, 0xED, - 0x37, 0xBD, 0x2D, 0xB1, 0x59, 0x0F, 0x99, 0xAA, - 0x29, 0x6A, 0xEA, 0x13, 0xAB, 0x84, 0x43, 0xD5, - 0xA9, 0x23, 0x47, 0xFB, 0x85, 0xFC, 0x81, 0x6D - }, - { - 0x80, 0xE3, 0x70, 0x92, 0x97, 0xD4, 0x41, 0x14, - 0xB9, 0xFB, 0xDF, 0x55, 0x67, 0xF0, 0x5F, 0x33, - 0x00, 0x94, 0xCF, 0x09, 0xF4, 0xC0, 0xEF, 0xCF, - 0xAC, 0x05, 0x09, 0x5C, 0x36, 0x08, 0x10, 0x77, - 0x30, 0xC1, 0xAA, 0x07, 0xFF, 0x23, 0x00, 0x25, - 0x62, 0xC7, 0xE8, 0x41, 0xA9, 0xF5, 0x66, 0x24, - 0xFF, 0xE2, 0xAB, 0xEC, 0x61, 0x1E, 0xB9, 0xE7, - 0x3E, 0x1C, 0xCB, 0xD8, 0xF6, 0x2B, 0x11, 0x49 - }, - { - 0xF9, 0x94, 0x5C, 0x19, 0x06, 0x77, 0x84, 0x61, - 0x94, 0x13, 0x2B, 0x49, 0x6E, 0xC6, 0x01, 0x2C, - 0x08, 0x75, 0x0E, 0x02, 0x5F, 0xD5, 0x52, 0xED, - 0x32, 0x4D, 0x3A, 0x49, 0xD8, 0x63, 0x66, 0xC0, - 0x3D, 0xCC, 0xDE, 0x8D, 0x5B, 0x5A, 0xC9, 0xA4, - 0xBC, 0xB7, 0x19, 0x5E, 0x63, 0xBC, 0xAA, 0x93, - 0x9E, 0x8E, 0xDA, 0x18, 0xF1, 0x16, 0x94, 0xB6, - 0xFA, 0x69, 0x37, 0x39, 0x3B, 0xFF, 0xDB, 0xF4 - }, - { - 0x8D, 0x8F, 0x2E, 0xD9, 0xAE, 0x39, 0x80, 0x9A, - 0xAC, 0xAD, 0x2F, 0xCE, 0xDB, 0xD2, 0xDC, 0xA7, - 0x30, 0xC7, 0x83, 0xE6, 0x2F, 0xF7, 0x0B, 0x8D, - 0x3C, 0x53, 0x62, 0xF0, 0x73, 0xF8, 0x34, 0x67, - 0x19, 0x7D, 0x37, 0x56, 0xB4, 0x45, 0x19, 0x5F, - 0xE7, 0x52, 0x11, 0x73, 0x64, 0xD9, 0x2C, 0xF4, - 0x2C, 0x02, 0x6E, 0x40, 0x9D, 0x5F, 0xF7, 0xA9, - 0x53, 0x3E, 0xAB, 0x78, 0xF1, 0x75, 0x4A, 0x2D - }, - { - 0x3A, 0xC9, 0x9A, 0xC5, 0x3A, 0xC4, 0x9A, 0x56, - 0xFA, 0xA1, 0x86, 0x46, 0xB8, 0xE0, 0x8A, 0x2D, - 0x35, 0xBE, 0x80, 0xDF, 0x3E, 0xFB, 0xBB, 0xA6, - 0xBD, 0xA4, 0xAE, 0x90, 0x2B, 0x8D, 0x3E, 0x17, - 0x0A, 0x7B, 0xE8, 0x60, 0x5C, 0x34, 0xA4, 0xDC, - 0x9A, 0x73, 0x62, 0xB1, 0xC2, 0x01, 0xD7, 0x02, - 0x39, 0x1B, 0xD7, 0xD5, 0x20, 0x7F, 0x95, 0xFA, - 0x39, 0x0C, 0xE3, 0x3C, 0x43, 0x14, 0xD4, 0x11 - }, - { - 0xE4, 0x69, 0x4B, 0xDB, 0x31, 0x01, 0x6F, 0x25, - 0x53, 0x2C, 0x04, 0x3C, 0x5C, 0x63, 0x08, 0xCC, - 0x61, 0x9B, 0x0F, 0x87, 0x16, 0xF0, 0xC2, 0x9E, - 0xEB, 0x9F, 0x34, 0x0F, 0x47, 0xB0, 0x7B, 0x4A, - 0x4C, 0xE0, 0x98, 0x4C, 0x47, 0x24, 0xB1, 0x2A, - 0xB3, 0xD3, 0x2A, 0xF5, 0x16, 0xAD, 0xA2, 0x64, - 0x4C, 0xA6, 0x55, 0x8C, 0x1C, 0xB5, 0x81, 0x5C, - 0x12, 0x12, 0xA9, 0xB5, 0xFA, 0x83, 0x44, 0x12 - }, - { - 0xC6, 0x3C, 0x70, 0x3E, 0x62, 0x10, 0x8A, 0xA0, - 0xED, 0xC6, 0x83, 0xF3, 0x67, 0x8A, 0x00, 0x78, - 0x8F, 0xB1, 0x00, 0xC0, 0x96, 0x0B, 0x4E, 0x98, - 0xB7, 0x6A, 0x48, 0xE4, 0xE5, 0x92, 0x3D, 0x34, - 0x13, 0x44, 0x8D, 0xB8, 0x87, 0x5E, 0x3B, 0xCE, - 0xA7, 0xB6, 0xB8, 0x5D, 0x9E, 0x3E, 0xEA, 0xB7, - 0x2C, 0xD1, 0x50, 0x96, 0xFB, 0xBB, 0x2C, 0xC4, - 0x27, 0x03, 0x17, 0xFC, 0x34, 0xD4, 0x04, 0x71 - }, - { - 0x90, 0x80, 0xB7, 0xE8, 0x41, 0xEF, 0x51, 0x9C, - 0x54, 0x17, 0xE6, 0x90, 0xAA, 0xF4, 0x32, 0x79, - 0x07, 0xA8, 0x3D, 0xBC, 0xB7, 0x38, 0xD0, 0xF7, - 0x30, 0x8B, 0x1D, 0x61, 0x1D, 0xEF, 0x16, 0x9A, - 0x4F, 0x47, 0x42, 0x3E, 0x69, 0x0F, 0x27, 0xA7, - 0xE2, 0x74, 0x1A, 0xE7, 0x86, 0x5D, 0xA2, 0x3C, - 0x5D, 0x3F, 0x13, 0xC3, 0x16, 0x06, 0x3C, 0x7A, - 0xA1, 0xA9, 0x58, 0xE5, 0xBE, 0x83, 0x8F, 0x04 - }, - { - 0x29, 0x8D, 0xF6, 0x46, 0x91, 0x5F, 0x04, 0xD6, - 0x65, 0xE9, 0x67, 0x5E, 0x6A, 0x10, 0x31, 0x87, - 0x0D, 0x28, 0xEB, 0x7A, 0x04, 0x05, 0x66, 0x3E, - 0xAC, 0x3B, 0x10, 0xD1, 0xB4, 0xFA, 0x2E, 0x86, - 0x8E, 0x63, 0x73, 0xA5, 0x86, 0xCD, 0x73, 0xE0, - 0x6D, 0x8E, 0x7A, 0xD7, 0x71, 0xB4, 0xFB, 0x0A, - 0x8B, 0x4F, 0xC2, 0xDC, 0x6C, 0xE0, 0x9C, 0x64, - 0x2E, 0xE8, 0x99, 0x26, 0xFD, 0xC6, 0x52, 0x60 - }, - { - 0x4F, 0x2D, 0xE9, 0xC4, 0xF4, 0x34, 0x8B, 0xDB, - 0x32, 0x3A, 0x66, 0x83, 0x72, 0xE7, 0x71, 0x42, - 0x99, 0xC7, 0x76, 0xF9, 0x60, 0x2F, 0x3A, 0xF8, - 0xFB, 0x77, 0x46, 0xF1, 0x76, 0x86, 0x8D, 0xF3, - 0x54, 0x2B, 0x2F, 0xA6, 0x9E, 0xAE, 0x38, 0xB6, - 0xA2, 0x6A, 0x06, 0xCA, 0x89, 0x42, 0xF8, 0x82, - 0x78, 0xC6, 0x4E, 0x3D, 0x01, 0x7F, 0xEE, 0x67, - 0xA9, 0x4E, 0xA0, 0x23, 0xB2, 0xB5, 0xBE, 0x5F - }, - { - 0x40, 0x18, 0xC5, 0xEE, 0x90, 0x93, 0xA6, 0x81, - 0x11, 0x2F, 0x4C, 0xE1, 0x93, 0xA1, 0xD6, 0x5E, - 0x05, 0x48, 0x72, 0x5F, 0x96, 0xAE, 0x31, 0x53, - 0x87, 0xCD, 0x76, 0x5C, 0x2B, 0x9C, 0x30, 0x68, - 0xAE, 0x4C, 0xBE, 0x5C, 0xD5, 0x40, 0x2C, 0x11, - 0xC5, 0x5A, 0x9D, 0x78, 0x5F, 0xFD, 0xFC, 0x2B, - 0xDE, 0x6E, 0x7A, 0xCF, 0x19, 0x61, 0x74, 0x75, - 0xDA, 0xE0, 0xEB, 0x01, 0x44, 0x56, 0xCE, 0x45 - }, - { - 0x6F, 0xCE, 0x66, 0x75, 0xE8, 0x6D, 0x7E, 0x85, - 0x70, 0x4C, 0x96, 0xC2, 0x95, 0x70, 0x3C, 0xD9, - 0x54, 0x98, 0x59, 0x0E, 0x50, 0x76, 0x4D, 0x23, - 0xD7, 0xA7, 0xA3, 0xA3, 0x22, 0x68, 0xA0, 0xB3, - 0xC9, 0x91, 0xE8, 0xF7, 0x84, 0x87, 0x69, 0x9A, - 0x55, 0x4B, 0x58, 0x1E, 0x33, 0x9C, 0x09, 0xAE, - 0xC9, 0x82, 0xE0, 0xBA, 0xA4, 0x31, 0x87, 0x93, - 0x62, 0x06, 0x35, 0xE1, 0xE2, 0xC8, 0xD9, 0xF2 - }, - { - 0xEB, 0xA9, 0x37, 0x85, 0x91, 0x97, 0xC7, 0xFD, - 0x41, 0x2D, 0xBC, 0x9A, 0xFC, 0x0D, 0x67, 0xCC, - 0x19, 0x81, 0x60, 0xB5, 0xA9, 0xCC, 0xEE, 0x87, - 0xC4, 0x1A, 0x86, 0x64, 0x85, 0x9F, 0x3E, 0xFD, - 0x96, 0x13, 0x66, 0xA8, 0x09, 0xC7, 0xC6, 0xBC, - 0x6F, 0xA8, 0x44, 0x92, 0x68, 0x14, 0xE0, 0xB4, - 0xEF, 0xA3, 0x7E, 0xDE, 0x2C, 0x88, 0x44, 0x26, - 0x8D, 0x7F, 0x35, 0x56, 0xE4, 0x46, 0x58, 0x1D - }, - { - 0x83, 0xF4, 0x33, 0xE4, 0xF1, 0xC5, 0x07, 0x97, - 0x49, 0x3C, 0x58, 0xC2, 0x64, 0xCF, 0xFA, 0x70, - 0xC4, 0xA7, 0xA2, 0x4C, 0x33, 0x4D, 0xBA, 0xA3, - 0xC5, 0x74, 0x89, 0xD9, 0x70, 0xD4, 0x9D, 0x69, - 0x49, 0xFE, 0x45, 0xB7, 0x04, 0xF2, 0x65, 0xEF, - 0xD2, 0xAE, 0xE1, 0xAC, 0x1B, 0x46, 0xF4, 0xAA, - 0x3E, 0x4F, 0xAD, 0x68, 0xB3, 0x79, 0x61, 0xD2, - 0xC7, 0x28, 0x0A, 0xE1, 0x96, 0x72, 0xC8, 0x50 - }, - { - 0xB5, 0x57, 0xEC, 0xE1, 0x22, 0x72, 0x49, 0x3D, - 0xC2, 0x7E, 0x88, 0xA0, 0x5A, 0xDC, 0xD8, 0x61, - 0x87, 0x5A, 0x0C, 0xD0, 0x0B, 0xD6, 0x8A, 0xDC, - 0x3A, 0x30, 0x1D, 0x26, 0x3A, 0x9C, 0xD9, 0x93, - 0xA9, 0x6A, 0xE1, 0x4C, 0xFC, 0xDD, 0xCB, 0x99, - 0x7C, 0xC9, 0x86, 0x23, 0x93, 0x50, 0x50, 0xEA, - 0x43, 0x55, 0x2A, 0x34, 0x11, 0x07, 0x18, 0x7D, - 0xE7, 0x5C, 0x4E, 0xDE, 0xD7, 0xC7, 0x86, 0xBD - }, - { - 0x95, 0x89, 0xC0, 0x81, 0x3B, 0x73, 0x93, 0xDB, - 0xAA, 0xAF, 0xE4, 0x7A, 0xF5, 0xB4, 0x08, 0xB2, - 0x3C, 0x8A, 0x8C, 0x8B, 0xAC, 0x62, 0x55, 0x4B, - 0x8F, 0xA1, 0x32, 0xA3, 0x58, 0xCE, 0x30, 0x83, - 0xB1, 0xD4, 0xE3, 0x97, 0x07, 0xCD, 0x54, 0xA5, - 0x5F, 0x67, 0x3D, 0x48, 0x11, 0x6E, 0xB1, 0xF9, - 0xED, 0x8D, 0xE9, 0xC9, 0x43, 0xCD, 0x2D, 0xE4, - 0x60, 0xA6, 0x8B, 0xDD, 0xF7, 0x1E, 0x98, 0x03 - }, - { - 0xAE, 0x4C, 0xCF, 0x27, 0xAB, 0x00, 0xA4, 0x0C, - 0x36, 0x37, 0xD3, 0xD2, 0xCE, 0x51, 0xA8, 0x3E, - 0xFB, 0xA6, 0x2D, 0x4A, 0x6F, 0xDA, 0xD6, 0x95, - 0x06, 0x3F, 0xBC, 0x60, 0xA2, 0xD8, 0x2E, 0xC5, - 0xA5, 0x4A, 0xCB, 0xE0, 0x9B, 0xA9, 0x38, 0x8F, - 0x49, 0xAA, 0xC2, 0x7C, 0x99, 0x2D, 0x84, 0x63, - 0x20, 0x36, 0xE1, 0xBD, 0xD4, 0xC5, 0x29, 0xBB, - 0xF1, 0x85, 0x1E, 0xAE, 0x0C, 0x6E, 0xA9, 0x02 - }, - { - 0xA3, 0x94, 0x4B, 0x2C, 0x31, 0xCB, 0x49, 0x40, - 0x80, 0xB7, 0xEE, 0x1D, 0xB0, 0x81, 0x68, 0x53, - 0xE4, 0x25, 0xB5, 0x4C, 0x48, 0xD6, 0x31, 0x44, - 0x7E, 0xA5, 0x2C, 0x1D, 0x29, 0x52, 0x07, 0x9B, - 0xD8, 0x8F, 0xAB, 0x9E, 0xD0, 0xB7, 0xD8, 0xC0, - 0xBA, 0xAF, 0x0C, 0x4E, 0xCA, 0x19, 0x10, 0xDB, - 0x6F, 0x98, 0x53, 0x4F, 0x0D, 0x42, 0xE5, 0xEB, - 0xB6, 0xC0, 0xA7, 0x5E, 0xF0, 0xD8, 0xB2, 0xC0 - }, - { - 0xCF, 0xA1, 0xA2, 0x24, 0x68, 0x5A, 0x5F, 0xB2, - 0x01, 0x04, 0x58, 0x20, 0x1C, 0xEB, 0x0C, 0xDA, - 0x21, 0xC8, 0x2B, 0x16, 0x02, 0xDC, 0x41, 0x35, - 0x85, 0xFB, 0xCE, 0x80, 0x97, 0x6F, 0x06, 0x1C, - 0x23, 0x5B, 0x13, 0x67, 0x71, 0x24, 0x98, 0x14, - 0x4A, 0xC1, 0x6A, 0x98, 0x54, 0xF6, 0xFB, 0x32, - 0x3C, 0xBE, 0xB6, 0x23, 0x69, 0xCF, 0x9B, 0x75, - 0x2B, 0x92, 0x52, 0xA2, 0xA7, 0xAC, 0xE1, 0xFD - }, - { - 0xFA, 0x62, 0xC6, 0xCF, 0xC8, 0xF0, 0x79, 0xE5, - 0x8F, 0x3D, 0x3F, 0xEF, 0xD7, 0xC2, 0x24, 0xE7, - 0x1E, 0xBC, 0x69, 0xA9, 0x5B, 0x18, 0x35, 0xCC, - 0xC3, 0x2F, 0x35, 0x07, 0x77, 0x05, 0x11, 0x02, - 0x61, 0x54, 0x92, 0xD6, 0x7F, 0xB6, 0xDE, 0x62, - 0xCF, 0x2A, 0xD5, 0xB1, 0x84, 0x67, 0xFE, 0x87, - 0x15, 0x74, 0x88, 0x82, 0xDB, 0x89, 0xFF, 0x86, - 0xEF, 0xDF, 0x2F, 0x96, 0xF8, 0x13, 0x5E, 0xD2 - }, - { - 0xCC, 0x63, 0x3F, 0xD4, 0xEA, 0x6A, 0xC4, 0x08, - 0xC3, 0x87, 0x57, 0x56, 0xB9, 0x01, 0x28, 0x8A, - 0x1D, 0xE1, 0x91, 0x89, 0x28, 0x32, 0xBE, 0x2E, - 0x90, 0x26, 0xDC, 0x65, 0xC2, 0xFF, 0x00, 0x00, - 0x9F, 0x14, 0x36, 0xDD, 0xFF, 0x42, 0x06, 0x26, - 0x0A, 0x3D, 0x66, 0xEF, 0x61, 0x92, 0x14, 0x3E, - 0x57, 0x2F, 0x1E, 0x4B, 0xB8, 0xE5, 0xA7, 0x4B, - 0x12, 0x05, 0x5E, 0x42, 0x41, 0x1C, 0x18, 0xBC - }, - { - 0x44, 0xD2, 0xBF, 0x7F, 0x36, 0x96, 0xB8, 0x93, - 0x3F, 0x25, 0x5B, 0x9B, 0xE1, 0xA4, 0xA6, 0xAE, - 0x33, 0x16, 0xC2, 0x5D, 0x03, 0x95, 0xF5, 0x90, - 0xB9, 0xB9, 0x89, 0x8F, 0x12, 0x7E, 0x40, 0xD3, - 0xF4, 0x12, 0x4D, 0x7B, 0xDB, 0xC8, 0x72, 0x5F, - 0x00, 0xB0, 0xD2, 0x81, 0x50, 0xFF, 0x05, 0xB4, - 0xA7, 0x9E, 0x5E, 0x04, 0xE3, 0x4A, 0x47, 0xE9, - 0x08, 0x7B, 0x3F, 0x79, 0xD4, 0x13, 0xAB, 0x7F - }, - { - 0x96, 0xFB, 0xCB, 0xB6, 0x0B, 0xD3, 0x13, 0xB8, - 0x84, 0x50, 0x33, 0xE5, 0xBC, 0x05, 0x8A, 0x38, - 0x02, 0x74, 0x38, 0x57, 0x2D, 0x7E, 0x79, 0x57, - 0xF3, 0x68, 0x4F, 0x62, 0x68, 0xAA, 0xDD, 0x3A, - 0xD0, 0x8D, 0x21, 0x76, 0x7E, 0xD6, 0x87, 0x86, - 0x85, 0x33, 0x1B, 0xA9, 0x85, 0x71, 0x48, 0x7E, - 0x12, 0x47, 0x0A, 0xAD, 0x66, 0x93, 0x26, 0x71, - 0x6E, 0x46, 0x66, 0x7F, 0x69, 0xF8, 0xD7, 0xE8 - }, -}; - - - - -#endif - - - diff --git a/Modules/_blake2/impl/blake2b-test.c b/Modules/_blake2/impl/blake2b-test.c deleted file mode 100644 index 9310a273a51..00000000000 --- a/Modules/_blake2/impl/blake2b-test.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - BLAKE2 reference source code package - optimized C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ -#include -#include -#include "blake2.h" -#include "blake2-kat.h" -int main( int argc, char **argv ) -{ - uint8_t key[BLAKE2B_KEYBYTES]; - uint8_t buf[KAT_LENGTH]; - - for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i ) - key[i] = ( uint8_t )i; - - for( size_t i = 0; i < KAT_LENGTH; ++i ) - buf[i] = ( uint8_t )i; - - for( size_t i = 0; i < KAT_LENGTH; ++i ) - { - uint8_t hash[BLAKE2B_OUTBYTES]; - - if( blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 || - 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) - { - puts( "error" ); - return -1; - } - } - - puts( "ok" ); - return 0; -} - diff --git a/Modules/_blake2/impl/blake2bp-test.c b/Modules/_blake2/impl/blake2bp-test.c deleted file mode 100644 index 849666cc1d5..00000000000 --- a/Modules/_blake2/impl/blake2bp-test.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - BLAKE2 reference source code package - optimized C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ -#include -#include -#include "blake2.h" -#include "blake2-kat.h" - -int main( int argc, char **argv ) -{ - uint8_t key[BLAKE2B_KEYBYTES]; - uint8_t buf[KAT_LENGTH]; - - for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i ) - key[i] = ( uint8_t )i; - - for( size_t i = 0; i < KAT_LENGTH; ++i ) - buf[i] = ( uint8_t )i; - - for( size_t i = 0; i < KAT_LENGTH; ++i ) - { - uint8_t hash[BLAKE2B_OUTBYTES]; - - if( blake2bp( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 || - 0 != memcmp( hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES ) ) - { - puts( "error" ); - return -1; - } - } - - puts( "ok" ); - return 0; -} - diff --git a/Modules/_blake2/impl/blake2bp.c b/Modules/_blake2/impl/blake2bp.c deleted file mode 100644 index 45221611710..00000000000 --- a/Modules/_blake2/impl/blake2bp.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - BLAKE2 reference source code package - optimized C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ - -#include -#include -#include -#include - -#if defined(_OPENMP) -#include -#endif - -#include "blake2.h" -#include "blake2-impl.h" - -#define PARALLELISM_DEGREE 4 - -static int blake2bp_init_leaf( blake2b_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset ) -{ - blake2b_param P[1]; - P->digest_length = outlen; - P->key_length = keylen; - P->fanout = PARALLELISM_DEGREE; - P->depth = 2; - store32(&P->leaf_length, 0); - store64(&P->node_offset, offset); - P->node_depth = 0; - P->inner_length = BLAKE2B_OUTBYTES; - memset( P->reserved, 0, sizeof( P->reserved ) ); - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - blake2b_init_param( S, P ); - S->outlen = P->inner_length; - return 0; -} - -static int blake2bp_init_root( blake2b_state *S, uint8_t outlen, uint8_t keylen ) -{ - blake2b_param P[1]; - P->digest_length = outlen; - P->key_length = keylen; - P->fanout = PARALLELISM_DEGREE; - P->depth = 2; - store32(&P->leaf_length, 0); - store64(&P->node_offset, 0); - P->node_depth = 1; - P->inner_length = BLAKE2B_OUTBYTES; - memset( P->reserved, 0, sizeof( P->reserved ) ); - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - blake2b_init_param( S, P ); - S->outlen = P->digest_length; - return 0; -} - - -int blake2bp_init( blake2bp_state *S, size_t outlen ) -{ - if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; - - memset( S->buf, 0, sizeof( S->buf ) ); - S->buflen = 0; - - if( blake2bp_init_root( S->R, ( uint8_t ) outlen, 0 ) < 0 ) - return -1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2bp_init_leaf( S->S[i], ( uint8_t ) outlen, 0, i ) < 0 ) return -1; - - S->R->last_node = 1; - S->S[PARALLELISM_DEGREE - 1]->last_node = 1; - S->outlen = ( uint8_t ) outlen; - return 0; -} - -int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ) -{ - if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; - - if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; - - memset( S->buf, 0, sizeof( S->buf ) ); - S->buflen = 0; - - if( blake2bp_init_root( S->R, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 ) - return -1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2bp_init_leaf( S->S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 ) - return -1; - - S->R->last_node = 1; - S->S[PARALLELISM_DEGREE - 1]->last_node = 1; - S->outlen = ( uint8_t ) outlen; - { - uint8_t block[BLAKE2B_BLOCKBYTES]; - memset( block, 0, BLAKE2B_BLOCKBYTES ); - memcpy( block, key, keylen ); - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES ); - - secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ - } - return 0; -} - - -int blake2bp_update( blake2bp_state *S, const uint8_t *in, size_t inlen ) -{ - size_t left = S->buflen; - size_t fill = sizeof( S->buf ) - left; - - if( left && inlen >= fill ) - { - memcpy( S->buf + left, in, fill ); - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); - - in += fill; - inlen -= fill; - left = 0; - } - -#if defined(_OPENMP) - omp_set_num_threads(PARALLELISM_DEGREE); - #pragma omp parallel shared(S) -#else - for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) -#endif - { -#if defined(_OPENMP) - size_t id__ = ( size_t ) omp_get_thread_num(); -#endif - size_t inlen__ = inlen; - const uint8_t *in__ = ( const uint8_t * )in; - in__ += id__ * BLAKE2B_BLOCKBYTES; - - while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) - { - blake2b_update( S->S[id__], in__, BLAKE2B_BLOCKBYTES ); - in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; - inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; - } - } - - in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ); - inlen %= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; - - if( inlen > 0 ) - memcpy( S->buf + left, in, inlen ); - - S->buflen = ( uint32_t ) left + ( uint32_t ) inlen; - return 0; -} - - - -int blake2bp_final( blake2bp_state *S, uint8_t *out, size_t outlen ) -{ - uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; - - if(S->outlen != outlen) return -1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - { - if( S->buflen > i * BLAKE2B_BLOCKBYTES ) - { - size_t left = S->buflen - i * BLAKE2B_BLOCKBYTES; - - if( left > BLAKE2B_BLOCKBYTES ) left = BLAKE2B_BLOCKBYTES; - - blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, left ); - } - - blake2b_final( S->S[i], hash[i], BLAKE2B_OUTBYTES ); - } - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES ); - - return blake2b_final( S->R, out, outlen ); -} - -int blake2bp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) -{ - uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; - blake2b_state S[PARALLELISM_DEGREE][1]; - blake2b_state FS[1]; - - /* Verify parameters */ - if ( NULL == in && inlen > 0 ) return -1; - - if ( NULL == out ) return -1; - - if ( NULL == key && keylen > 0) return -1; - - if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; - - if( keylen > BLAKE2B_KEYBYTES ) return -1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2bp_init_leaf( S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 ) - return -1; - - S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node - - if( keylen > 0 ) - { - uint8_t block[BLAKE2B_BLOCKBYTES]; - memset( block, 0, BLAKE2B_BLOCKBYTES ); - memcpy( block, key, keylen ); - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES ); - - secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ - } - -#if defined(_OPENMP) - omp_set_num_threads(PARALLELISM_DEGREE); - #pragma omp parallel shared(S,hash) -#else - for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) -#endif - { -#if defined(_OPENMP) - size_t id__ = ( size_t ) omp_get_thread_num(); -#endif - size_t inlen__ = inlen; - const uint8_t *in__ = ( const uint8_t * )in; - in__ += id__ * BLAKE2B_BLOCKBYTES; - - while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) - { - blake2b_update( S[id__], in__, BLAKE2B_BLOCKBYTES ); - in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; - inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; - } - - if( inlen__ > id__ * BLAKE2B_BLOCKBYTES ) - { - const size_t left = inlen__ - id__ * BLAKE2B_BLOCKBYTES; - const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES; - blake2b_update( S[id__], in__, len ); - } - - blake2b_final( S[id__], hash[id__], BLAKE2B_OUTBYTES ); - } - - if( blake2bp_init_root( FS, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 ) - return -1; - - FS->last_node = 1; // Mark as last node - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES ); - - return blake2b_final( FS, out, outlen ); -} - - - diff --git a/Modules/_blake2/impl/blake2s-test.c b/Modules/_blake2/impl/blake2s-test.c deleted file mode 100644 index 5c3f1f189d7..00000000000 --- a/Modules/_blake2/impl/blake2s-test.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - BLAKE2 reference source code package - optimized C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ -#include -#include -#include "blake2.h" -#include "blake2-kat.h" -int main( int argc, char **argv ) -{ - uint8_t key[BLAKE2S_KEYBYTES]; - uint8_t buf[KAT_LENGTH]; - - for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i ) - key[i] = ( uint8_t )i; - - for( size_t i = 0; i < KAT_LENGTH; ++i ) - buf[i] = ( uint8_t )i; - - for( size_t i = 0; i < KAT_LENGTH; ++i ) - { - uint8_t hash[BLAKE2S_OUTBYTES]; - - if( blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 || - 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) - { - puts( "error" ); - return -1; - } - } - - puts( "ok" ); - return 0; -} - diff --git a/Modules/_blake2/impl/blake2sp-test.c b/Modules/_blake2/impl/blake2sp-test.c deleted file mode 100644 index 621e3506cfb..00000000000 --- a/Modules/_blake2/impl/blake2sp-test.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - BLAKE2 reference source code package - optimized C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ -#include -#include -#include "blake2.h" -#include "blake2-kat.h" - -int main( int argc, char **argv ) -{ - uint8_t key[BLAKE2S_KEYBYTES]; - uint8_t buf[KAT_LENGTH]; - - for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i ) - key[i] = ( uint8_t )i; - - for( size_t i = 0; i < KAT_LENGTH; ++i ) - buf[i] = ( uint8_t )i; - - for( size_t i = 0; i < KAT_LENGTH; ++i ) - { - uint8_t hash[BLAKE2S_OUTBYTES]; - if( blake2sp( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 || - 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) ) - { - puts( "error" ); - return -1; - } - } - - puts( "ok" ); - return 0; -} - diff --git a/Modules/_blake2/impl/blake2sp.c b/Modules/_blake2/impl/blake2sp.c deleted file mode 100644 index 2f32bf3a226..00000000000 --- a/Modules/_blake2/impl/blake2sp.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - BLAKE2 reference source code package - optimized C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ - -#include -#include -#include - -#if defined(_OPENMP) -#include -#endif - -#include "blake2.h" -#include "blake2-impl.h" - -#define PARALLELISM_DEGREE 8 - -static int blake2sp_init_leaf( blake2s_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset ) -{ - blake2s_param P[1]; - P->digest_length = outlen; - P->key_length = keylen; - P->fanout = PARALLELISM_DEGREE; - P->depth = 2; - P->leaf_length = 0; - store48( P->node_offset, offset ); - P->node_depth = 0; - P->inner_length = BLAKE2S_OUTBYTES; - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - blake2s_init_param( S, P ); - S->outlen = P->inner_length; - return 0; -} - -static int blake2sp_init_root( blake2s_state *S, uint8_t outlen, uint8_t keylen ) -{ - blake2s_param P[1]; - P->digest_length = outlen; - P->key_length = keylen; - P->fanout = PARALLELISM_DEGREE; - P->depth = 2; - P->leaf_length = 0; - store48( P->node_offset, 0ULL ); - P->node_depth = 1; - P->inner_length = BLAKE2S_OUTBYTES; - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - blake2s_init_param( S, P ); - S->outlen = P->digest_length; - return 0; -} - - -int blake2sp_init( blake2sp_state *S, size_t outlen ) -{ - if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; - - memset( S->buf, 0, sizeof( S->buf ) ); - S->buflen = 0; - - if( blake2sp_init_root( S->R, ( uint8_t ) outlen, 0 ) < 0 ) - return -1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2sp_init_leaf( S->S[i], ( uint8_t ) outlen, 0, i ) < 0 ) return -1; - - S->R->last_node = 1; - S->S[PARALLELISM_DEGREE - 1]->last_node = 1; - S->outlen = ( uint8_t ) outlen; - return 0; -} - -int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ) -{ - if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; - - if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; - - memset( S->buf, 0, sizeof( S->buf ) ); - S->buflen = 0; - - if( blake2sp_init_root( S->R, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 ) - return -1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2sp_init_leaf( S->S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 ) - return -1; - - S->R->last_node = 1; - S->S[PARALLELISM_DEGREE - 1]->last_node = 1; - S->outlen = ( uint8_t ) outlen; - { - uint8_t block[BLAKE2S_BLOCKBYTES]; - memset( block, 0, BLAKE2S_BLOCKBYTES ); - memcpy( block, key, keylen ); - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES ); - - secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ - } - return 0; -} - - -int blake2sp_update( blake2sp_state *S, const uint8_t *in, size_t inlen ) -{ - size_t left = S->buflen; - size_t fill = sizeof( S->buf ) - left; - - if( left && inlen >= fill ) - { - memcpy( S->buf + left, in, fill ); - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); - - in += fill; - inlen -= fill; - left = 0; - } - -#if defined(_OPENMP) - omp_set_num_threads(PARALLELISM_DEGREE); - #pragma omp parallel shared(S) -#else - for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) -#endif - { -#if defined(_OPENMP) - size_t id__ = ( size_t ) omp_get_thread_num(); -#endif - size_t inlen__ = inlen; - const uint8_t *in__ = ( const uint8_t * )in; - in__ += id__ * BLAKE2S_BLOCKBYTES; - - while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) - { - blake2s_update( S->S[id__], in__, BLAKE2S_BLOCKBYTES ); - in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; - inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; - } - } - - in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ); - inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; - - if( inlen > 0 ) - memcpy( S->buf + left, in, inlen ); - - S->buflen = ( uint32_t ) left + ( uint32_t ) inlen; - return 0; -} - - -int blake2sp_final( blake2sp_state *S, uint8_t *out, size_t outlen ) -{ - uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; - - if(S->outlen != outlen) return -1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - { - if( S->buflen > i * BLAKE2S_BLOCKBYTES ) - { - size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES; - - if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES; - - blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left ); - } - - blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES ); - } - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES ); - - blake2s_final( S->R, out, outlen ); - return 0; -} - - -int blake2sp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) -{ - uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; - blake2s_state S[PARALLELISM_DEGREE][1]; - blake2s_state FS[1]; - - /* Verify parameters */ - if ( NULL == in && inlen > 0 ) return -1; - - if ( NULL == out ) return -1; - - if ( NULL == key && keylen > 0 ) return -1; - - if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; - - if( keylen > BLAKE2S_KEYBYTES ) return -1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2sp_init_leaf( S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 ) - return -1; - - S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node - - if( keylen > 0 ) - { - uint8_t block[BLAKE2S_BLOCKBYTES]; - memset( block, 0, BLAKE2S_BLOCKBYTES ); - memcpy( block, key, keylen ); - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES ); - - secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ - } - -#if defined(_OPENMP) - omp_set_num_threads(PARALLELISM_DEGREE); - #pragma omp parallel shared(S,hash) -#else - - for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) -#endif - { -#if defined(_OPENMP) - size_t id__ = ( size_t ) omp_get_thread_num(); -#endif - size_t inlen__ = inlen; - const uint8_t *in__ = ( const uint8_t * )in; - in__ += id__ * BLAKE2S_BLOCKBYTES; - - while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) - { - blake2s_update( S[id__], in__, BLAKE2S_BLOCKBYTES ); - in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; - inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; - } - - if( inlen__ > id__ * BLAKE2S_BLOCKBYTES ) - { - const size_t left = inlen__ - id__ * BLAKE2S_BLOCKBYTES; - const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES; - blake2s_update( S[id__], in__, len ); - } - - blake2s_final( S[id__], hash[id__], BLAKE2S_OUTBYTES ); - } - - if( blake2sp_init_root( FS, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 ) - return -1; - - FS->last_node = 1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES ); - - return blake2s_final( FS, out, outlen ); -} - - - - diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c index 798e9efc628..9304c13fbed 100644 --- a/Modules/_bz2module.c +++ b/Modules/_bz2module.c @@ -81,19 +81,6 @@ OutputBuffer_OnError(_BlocksOutputBuffer *buffer) #define RELEASE_LOCK(obj) PyThread_release_lock((obj)->lock) -typedef struct { - PyTypeObject *bz2_compressor_type; - PyTypeObject *bz2_decompressor_type; -} _bz2_state; - -static inline _bz2_state* -get_bz2_state(PyObject *module) -{ - void *state = PyModule_GetState(module); - assert(state != NULL); - return (_bz2_state *)state; -} - typedef struct { PyObject_HEAD bz_stream bzs; @@ -775,67 +762,40 @@ static PyType_Spec bz2_decompressor_type_spec = { static int _bz2_exec(PyObject *module) { - _bz2_state *state = get_bz2_state(module); - state->bz2_compressor_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, + PyTypeObject *bz2_compressor_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &bz2_compressor_type_spec, NULL); - if (state->bz2_compressor_type == NULL) { + if (bz2_compressor_type == NULL) { + return -1; + } + int rc = PyModule_AddType(module, bz2_compressor_type); + Py_DECREF(bz2_compressor_type); + if (rc < 0) { return -1; } - if (PyModule_AddType(module, state->bz2_compressor_type) < 0) { - return -1; - } - - state->bz2_decompressor_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, + PyTypeObject *bz2_decompressor_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &bz2_decompressor_type_spec, NULL); - if (state->bz2_decompressor_type == NULL) { + if (bz2_decompressor_type == NULL) { return -1; } - - if (PyModule_AddType(module, state->bz2_decompressor_type) < 0) { + rc = PyModule_AddType(module, bz2_decompressor_type); + Py_DECREF(bz2_decompressor_type); + if (rc < 0) { return -1; } return 0; } -static int -_bz2_traverse(PyObject *module, visitproc visit, void *arg) -{ - _bz2_state *state = get_bz2_state(module); - Py_VISIT(state->bz2_compressor_type); - Py_VISIT(state->bz2_decompressor_type); - return 0; -} - -static int -_bz2_clear(PyObject *module) -{ - _bz2_state *state = get_bz2_state(module); - Py_CLEAR(state->bz2_compressor_type); - Py_CLEAR(state->bz2_decompressor_type); - return 0; -} - -static void -_bz2_free(void *module) -{ - _bz2_clear((PyObject *)module); -} - static struct PyModuleDef_Slot _bz2_slots[] = { {Py_mod_exec, _bz2_exec}, {0, NULL} }; static struct PyModuleDef _bz2module = { - PyModuleDef_HEAD_INIT, + .m_base = PyModuleDef_HEAD_INIT, .m_name = "_bz2", - .m_size = sizeof(_bz2_state), .m_slots = _bz2_slots, - .m_traverse = _bz2_traverse, - .m_clear = _bz2_clear, - .m_free = _bz2_free, }; PyMODINIT_FUNC diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c index 50afc097b35..d5035d20600 100644 --- a/Modules/_codecsmodule.c +++ b/Modules/_codecsmodule.c @@ -42,6 +42,7 @@ module _codecs [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=e1390e3da3cb9deb]*/ +#include "pycore_runtime.h" #include "clinic/_codecsmodule.c.h" /* --- Registry ----------------------------------------------------------- */ @@ -255,14 +256,14 @@ _codecs_escape_encode_impl(PyObject *module, PyObject *data, _codecs.utf_7_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_7_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=0cd3a944a32a4089 input=22c395d357815d26]*/ +/*[clinic end generated code: output=0cd3a944a32a4089 input=dbf8c8998102dc7d]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeUTF7Stateful(data->buf, data->len, @@ -275,14 +276,14 @@ _codecs_utf_7_decode_impl(PyObject *module, Py_buffer *data, _codecs.utf_8_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_8_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=10f74dec8d9bb8bf input=f611b3867352ba59]*/ +/*[clinic end generated code: output=10f74dec8d9bb8bf input=ca06bc8a9c970e25]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeUTF8Stateful(data->buf, data->len, @@ -295,14 +296,14 @@ _codecs_utf_8_decode_impl(PyObject *module, Py_buffer *data, _codecs.utf_16_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_16_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=783b442abcbcc2d0 input=191d360bd7309180]*/ +/*[clinic end generated code: output=783b442abcbcc2d0 input=5b0f52071ba6cadc]*/ { int byteorder = 0; /* This is overwritten unless final is true. */ @@ -317,14 +318,14 @@ _codecs_utf_16_decode_impl(PyObject *module, Py_buffer *data, _codecs.utf_16_le_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_16_le_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=899b9e6364379dcd input=c6904fdc27fb4724]*/ +/*[clinic end generated code: output=899b9e6364379dcd input=115bd8c7b783d0bf]*/ { int byteorder = -1; /* This is overwritten unless final is true. */ @@ -339,14 +340,14 @@ _codecs_utf_16_le_decode_impl(PyObject *module, Py_buffer *data, _codecs.utf_16_be_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_16_be_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=49f6465ea07669c8 input=e49012400974649b]*/ +/*[clinic end generated code: output=49f6465ea07669c8 input=63131422b01f9cb4]*/ { int byteorder = 1; /* This is overwritten unless final is true. */ @@ -369,14 +370,14 @@ _codecs.utf_16_ex_decode data: Py_buffer errors: str(accept={str, NoneType}) = None byteorder: int = 0 - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_16_ex_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int byteorder, int final) -/*[clinic end generated code: output=0f385f251ecc1988 input=5a9c19f2e6b6cf0e]*/ +/*[clinic end generated code: output=0f385f251ecc1988 input=f368a51cf384bf4c]*/ { /* This is overwritten unless final is true. */ Py_ssize_t consumed = data->len; @@ -393,14 +394,14 @@ _codecs_utf_16_ex_decode_impl(PyObject *module, Py_buffer *data, _codecs.utf_32_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_32_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=2fc961807f7b145f input=fd7193965627eb58]*/ +/*[clinic end generated code: output=2fc961807f7b145f input=fcdf3658c5e9b5f3]*/ { int byteorder = 0; /* This is overwritten unless final is true. */ @@ -415,14 +416,14 @@ _codecs_utf_32_decode_impl(PyObject *module, Py_buffer *data, _codecs.utf_32_le_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_32_le_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=ec8f46b67a94f3e6 input=9078ec70acfe7613]*/ +/*[clinic end generated code: output=ec8f46b67a94f3e6 input=12220556e885f817]*/ { int byteorder = -1; /* This is overwritten unless final is true. */ @@ -437,14 +438,14 @@ _codecs_utf_32_le_decode_impl(PyObject *module, Py_buffer *data, _codecs.utf_32_be_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_32_be_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=ff82bae862c92c4e input=f1ae1bbbb86648ff]*/ +/*[clinic end generated code: output=ff82bae862c92c4e input=2bc669b4781598db]*/ { int byteorder = 1; /* This is overwritten unless final is true. */ @@ -467,14 +468,14 @@ _codecs.utf_32_ex_decode data: Py_buffer errors: str(accept={str, NoneType}) = None byteorder: int = 0 - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_32_ex_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int byteorder, int final) -/*[clinic end generated code: output=6bfb177dceaf4848 input=e46a73bc859d0bd0]*/ +/*[clinic end generated code: output=6bfb177dceaf4848 input=4a2323d0013620df]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeUTF32Stateful(data->buf, data->len, @@ -489,14 +490,14 @@ _codecs_utf_32_ex_decode_impl(PyObject *module, Py_buffer *data, _codecs.unicode_escape_decode data: Py_buffer(accept={str, buffer}) errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = True + final: bool = True / [clinic start generated code]*/ static PyObject * _codecs_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=b284f97b12c635ee input=6154f039a9f7c639]*/ +/*[clinic end generated code: output=b284f97b12c635ee input=15019f081ffe272b]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = _PyUnicode_DecodeUnicodeEscapeStateful(data->buf, data->len, @@ -509,14 +510,14 @@ _codecs_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, _codecs.raw_unicode_escape_decode data: Py_buffer(accept={str, buffer}) errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = True + final: bool = True / [clinic start generated code]*/ static PyObject * _codecs_raw_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=11dbd96301e2879e input=2d166191beb3235a]*/ +/*[clinic end generated code: output=11dbd96301e2879e input=b93f823aa8c343ad]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = _PyUnicode_DecodeRawUnicodeEscapeStateful(data->buf, data->len, @@ -585,14 +586,14 @@ _codecs_charmap_decode_impl(PyObject *module, Py_buffer *data, _codecs.mbcs_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_mbcs_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=39b65b8598938c4b input=1c1d50f08fa53789]*/ +/*[clinic end generated code: output=39b65b8598938c4b input=f144ad1ed6d8f5a6]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeMBCSStateful(data->buf, data->len, @@ -604,14 +605,14 @@ _codecs_mbcs_decode_impl(PyObject *module, Py_buffer *data, _codecs.oem_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_oem_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=da1617612f3fcad8 input=81b67cba811022e5]*/ +/*[clinic end generated code: output=da1617612f3fcad8 input=629bf87376d211b4]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeCodePageStateful(CP_OEMCP, @@ -624,14 +625,14 @@ _codecs.code_page_decode codepage: int data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_code_page_decode_impl(PyObject *module, int codepage, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=53008ea967da3fff input=c5f58d036cb63575]*/ +/*[clinic end generated code: output=53008ea967da3fff input=6a32589b0658c277]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeCodePageStateful(codepage, diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 4c4e1f762a4..68131f3b54d 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -299,8 +299,7 @@ deque_append_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen) static PyObject * deque_append(dequeobject *deque, PyObject *item) { - Py_INCREF(item); - if (deque_append_internal(deque, item, deque->maxlen) < 0) + if (deque_append_internal(deque, Py_NewRef(item), deque->maxlen) < 0) return NULL; Py_RETURN_NONE; } @@ -336,8 +335,7 @@ deque_appendleft_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen) static PyObject * deque_appendleft(dequeobject *deque, PyObject *item) { - Py_INCREF(item); - if (deque_appendleft_internal(deque, item, deque->maxlen) < 0) + if (deque_appendleft_internal(deque, Py_NewRef(item), deque->maxlen) < 0) return NULL; Py_RETURN_NONE; } @@ -655,14 +653,12 @@ deque_inplace_repeat(dequeobject *deque, Py_ssize_t n) size = Py_SIZE(deque); if (size == 0 || n == 1) { - Py_INCREF(deque); - return (PyObject *)deque; + return Py_NewRef(deque); } if (n <= 0) { deque_clear(deque); - Py_INCREF(deque); - return (PyObject *)deque; + return Py_NewRef(deque); } if (size == 1) { @@ -693,13 +689,11 @@ deque_inplace_repeat(dequeobject *deque, Py_ssize_t n) i += m; while (m--) { deque->rightindex++; - Py_INCREF(item); - deque->rightblock->data[deque->rightindex] = item; + deque->rightblock->data[deque->rightindex] = Py_NewRef(item); } } Py_SET_SIZE(deque, Py_SIZE(deque) + i); - Py_INCREF(deque); - return (PyObject *)deque; + return Py_NewRef(deque); } if ((size_t)size > PY_SSIZE_T_MAX / (size_t)n) { @@ -972,8 +966,7 @@ deque_count(dequeobject *deque, PyObject *v) while (--n >= 0) { CHECK_NOT_END(b); - item = b->data[index]; - Py_INCREF(item); + item = Py_NewRef(b->data[index]); cmp = PyObject_RichCompareBool(item, v, Py_EQ); Py_DECREF(item); if (cmp < 0) @@ -1011,8 +1004,7 @@ deque_contains(dequeobject *deque, PyObject *v) while (--n >= 0) { CHECK_NOT_END(b); - item = b->data[index]; - Py_INCREF(item); + item = Py_NewRef(b->data[index]); cmp = PyObject_RichCompareBool(item, v, Py_EQ); Py_DECREF(item); if (cmp) { @@ -1201,8 +1193,7 @@ deque_item(dequeobject *deque, Py_ssize_t i) } } item = b->data[i]; - Py_INCREF(item); - return item; + return Py_NewRef(item); } static int @@ -1231,8 +1222,7 @@ deque_remove(dequeobject *deque, PyObject *value) int cmp, rv; for (i = 0 ; i < n; i++) { - item = b->data[index]; - Py_INCREF(item); + item = Py_NewRef(b->data[index]); cmp = PyObject_RichCompareBool(item, value, Py_EQ); Py_DECREF(item); if (cmp < 0) { @@ -1266,7 +1256,6 @@ deque_remove(dequeobject *deque, PyObject *value) static int deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v) { - PyObject *old_value; block *b; Py_ssize_t n, len=Py_SIZE(deque), halflen=(len+1)>>1, index=i; @@ -1292,10 +1281,7 @@ deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v) while (--n >= 0) b = b->leftlink; } - Py_INCREF(v); - old_value = b->data[i]; - b->data[i] = v; - Py_DECREF(old_value); + Py_SETREF(b->data[i], Py_NewRef(v)); return 0; } @@ -1347,28 +1333,24 @@ deque_traverse(dequeobject *deque, visitproc visit, void *arg) static PyObject * deque_reduce(dequeobject *deque, PyObject *Py_UNUSED(ignored)) { - PyObject *dict, *it; - _Py_IDENTIFIER(__dict__); + PyObject *state, *it; - if (_PyObject_LookupAttrId((PyObject *)deque, &PyId___dict__, &dict) < 0) { + state = _PyObject_GetState((PyObject *)deque); + if (state == NULL) { return NULL; } - if (dict == NULL) { - dict = Py_None; - Py_INCREF(dict); - } it = PyObject_GetIter((PyObject *)deque); if (it == NULL) { - Py_DECREF(dict); + Py_DECREF(state); return NULL; } if (deque->maxlen < 0) { - return Py_BuildValue("O()NN", Py_TYPE(deque), dict, it); + return Py_BuildValue("O()NN", Py_TYPE(deque), state, it); } else { - return Py_BuildValue("O(()n)NN", Py_TYPE(deque), deque->maxlen, dict, it); + return Py_BuildValue("O(()n)NN", Py_TYPE(deque), deque->maxlen, state, it); } } @@ -1526,26 +1508,18 @@ deque_init(dequeobject *deque, PyObject *args, PyObject *kwdargs) static PyObject * deque_sizeof(dequeobject *deque, void *unused) { - Py_ssize_t res; - Py_ssize_t blocks; - - res = _PyObject_SIZE(Py_TYPE(deque)); + size_t res = _PyObject_SIZE(Py_TYPE(deque)); + size_t blocks; blocks = (size_t)(deque->leftindex + Py_SIZE(deque) + BLOCKLEN - 1) / BLOCKLEN; - assert(deque->leftindex + Py_SIZE(deque) - 1 == - (blocks - 1) * BLOCKLEN + deque->rightindex); + assert(((size_t)deque->leftindex + (size_t)Py_SIZE(deque) - 1) == + ((blocks - 1) * BLOCKLEN + (size_t)deque->rightindex)); res += blocks * sizeof(block); - return PyLong_FromSsize_t(res); + return PyLong_FromSize_t(res); } PyDoc_STRVAR(sizeof_doc, "D.__sizeof__() -- size of D in memory, in bytes"); -static int -deque_bool(dequeobject *deque) -{ - return Py_SIZE(deque) != 0; -} - static PyObject * deque_get_maxlen(dequeobject *deque, void *Py_UNUSED(ignored)) { @@ -1576,20 +1550,6 @@ static PySequenceMethods deque_as_sequence = { (ssizeargfunc)deque_inplace_repeat, /* sq_inplace_repeat */ }; -static PyNumberMethods deque_as_number = { - 0, /* nb_add */ - 0, /* nb_subtract */ - 0, /* nb_multiply */ - 0, /* nb_remainder */ - 0, /* nb_divmod */ - 0, /* nb_power */ - 0, /* nb_negative */ - 0, /* nb_positive */ - 0, /* nb_absolute */ - (inquiry)deque_bool, /* nb_bool */ - 0, /* nb_invert */ - }; - static PyObject *deque_iter(dequeobject *deque); static PyObject *deque_reviter(dequeobject *deque, PyObject *Py_UNUSED(ignored)); PyDoc_STRVAR(reversed_doc, @@ -1612,9 +1572,9 @@ static PyMethodDef deque_methods[] = { METH_O, extend_doc}, {"extendleft", (PyCFunction)deque_extendleft, METH_O, extendleft_doc}, - {"index", (PyCFunction)(void(*)(void))deque_index, + {"index", _PyCFunction_CAST(deque_index), METH_FASTCALL, index_doc}, - {"insert", (PyCFunction)(void(*)(void))deque_insert, + {"insert", _PyCFunction_CAST(deque_insert), METH_FASTCALL, insert_doc}, {"pop", (PyCFunction)deque_pop, METH_NOARGS, pop_doc}, @@ -1628,7 +1588,7 @@ static PyMethodDef deque_methods[] = { METH_NOARGS, reversed_doc}, {"reverse", (PyCFunction)deque_reverse, METH_NOARGS, reverse_doc}, - {"rotate", (PyCFunction)(void(*)(void))deque_rotate, + {"rotate", _PyCFunction_CAST(deque_rotate), METH_FASTCALL, rotate_doc}, {"__sizeof__", (PyCFunction)deque_sizeof, METH_NOARGS, sizeof_doc}, @@ -1654,7 +1614,7 @@ static PyTypeObject deque_type = { 0, /* tp_setattr */ 0, /* tp_as_async */ deque_repr, /* tp_repr */ - &deque_as_number, /* tp_as_number */ + 0, /* tp_as_number */ &deque_as_sequence, /* tp_as_sequence */ 0, /* tp_as_mapping */ PyObject_HashNotImplemented, /* tp_hash */ @@ -1710,8 +1670,7 @@ deque_iter(dequeobject *deque) return NULL; it->b = deque->leftblock; it->index = deque->leftindex; - Py_INCREF(deque); - it->deque = deque; + it->deque = (dequeobject*)Py_NewRef(deque); it->state = deque->state; it->counter = Py_SIZE(deque); PyObject_GC_Track(it); @@ -1758,8 +1717,7 @@ dequeiter_next(dequeiterobject *it) it->b = it->b->rightlink; it->index = 0; } - Py_INCREF(item); - return item; + return Py_NewRef(item); } static PyObject * @@ -1868,8 +1826,7 @@ deque_reviter(dequeobject *deque, PyObject *Py_UNUSED(ignored)) return NULL; it->b = deque->rightblock; it->index = deque->rightindex; - Py_INCREF(deque); - it->deque = deque; + it->deque = (dequeobject*)Py_NewRef(deque); it->state = deque->state; it->counter = Py_SIZE(deque); PyObject_GC_Track(it); @@ -1900,8 +1857,7 @@ dequereviter_next(dequeiterobject *it) it->b = it->b->leftlink; it->index = BLOCKLEN - 1; } - Py_INCREF(item); - return item; + return Py_NewRef(item); } static PyObject * @@ -2064,7 +2020,6 @@ defdict_reduce(defdictobject *dd, PyObject *Py_UNUSED(ignored)) PyObject *items; PyObject *iter; PyObject *result; - _Py_IDENTIFIER(items); if (dd->default_factory == NULL || dd->default_factory == Py_None) args = PyTuple_New(0); @@ -2072,7 +2027,7 @@ defdict_reduce(defdictobject *dd, PyObject *Py_UNUSED(ignored)) args = PyTuple_Pack(1, dd->default_factory); if (args == NULL) return NULL; - items = _PyObject_CallMethodIdNoArgs((PyObject *)dd, &PyId_items); + items = PyObject_CallMethodNoArgs((PyObject *)dd, &_Py_ID(items)); if (items == NULL) { Py_DECREF(args); return NULL; @@ -2228,8 +2183,7 @@ defdict_init(PyObject *self, PyObject *args, PyObject *kwds) } if (newargs == NULL) return -1; - Py_XINCREF(newdefault); - dd->default_factory = newdefault; + dd->default_factory = Py_XNewRef(newdefault); result = PyDict_Type.tp_init(self, newargs, kwds); Py_DECREF(newargs); Py_XDECREF(olddefault); @@ -2310,8 +2264,6 @@ _collections__count_elements_impl(PyObject *module, PyObject *mapping, PyObject *iterable) /*[clinic end generated code: output=7e0c1789636b3d8f input=e79fad04534a0b45]*/ { - _Py_IDENTIFIER(get); - _Py_IDENTIFIER(__setitem__); PyObject *it, *oldval; PyObject *newval = NULL; PyObject *key = NULL; @@ -2329,10 +2281,10 @@ _collections__count_elements_impl(PyObject *module, PyObject *mapping, /* Only take the fast path when get() and __setitem__() * have not been overridden. */ - mapping_get = _PyType_LookupId(Py_TYPE(mapping), &PyId_get); - dict_get = _PyType_LookupId(&PyDict_Type, &PyId_get); - mapping_setitem = _PyType_LookupId(Py_TYPE(mapping), &PyId___setitem__); - dict_setitem = _PyType_LookupId(&PyDict_Type, &PyId___setitem__); + mapping_get = _PyType_Lookup(Py_TYPE(mapping), &_Py_ID(get)); + dict_get = _PyType_Lookup(&PyDict_Type, &_Py_ID(get)); + mapping_setitem = _PyType_Lookup(Py_TYPE(mapping), &_Py_ID(__setitem__)); + dict_setitem = _PyType_Lookup(&PyDict_Type, &_Py_ID(__setitem__)); if (mapping_get != NULL && mapping_get == dict_get && mapping_setitem != NULL && mapping_setitem == dict_setitem && @@ -2356,7 +2308,7 @@ _collections__count_elements_impl(PyObject *module, PyObject *mapping, break; if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) + (hash = _PyASCIIObject_CAST(key)->hash) == -1) { hash = PyObject_Hash(key); if (hash == -1) @@ -2381,7 +2333,7 @@ _collections__count_elements_impl(PyObject *module, PyObject *mapping, } } else { - bound_get = _PyObject_GetAttrId(mapping, &PyId_get); + bound_get = PyObject_GetAttr(mapping, &_Py_ID(get)); if (bound_get == NULL) goto done; @@ -2441,8 +2393,7 @@ tuplegetter_new_impl(PyTypeObject *type, Py_ssize_t index, PyObject *doc) return NULL; } self->index = index; - Py_INCREF(doc); - self->doc = doc; + self->doc = Py_NewRef(doc); return (PyObject *)self; } @@ -2453,13 +2404,11 @@ tuplegetter_descr_get(PyObject *self, PyObject *obj, PyObject *type) PyObject *result; if (obj == NULL) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } if (!PyTuple_Check(obj)) { if (obj == Py_None) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } PyErr_Format(PyExc_TypeError, "descriptor for index '%zd' for tuple subclasses " @@ -2475,8 +2424,7 @@ tuplegetter_descr_get(PyObject *self, PyObject *obj, PyObject *type) } result = PyTuple_GET_ITEM(obj, index); - Py_INCREF(result); - return result; + return Py_NewRef(result); } static int diff --git a/Modules/_csv.c b/Modules/_csv.c index 1c2f504ea5c..bd337084dbf 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -14,6 +14,12 @@ module instead. #include "structmember.h" // PyMemberDef #include +/*[clinic input] +module _csv +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=385118b71aa43706]*/ + +#include "clinic/_csv.c.h" #define NOT_SET ((Py_UCS4)-1) #define EOL ((Py_UCS4)-2) @@ -25,6 +31,7 @@ typedef struct { PyTypeObject *reader_type; PyTypeObject *writer_type; long field_limit; /* max parsed field size */ + PyObject *str_write; } _csvstate; static struct PyModuleDef _csvmodule; @@ -46,6 +53,7 @@ _csv_clear(PyObject *module) Py_CLEAR(module_state->dialect_type); Py_CLEAR(module_state->reader_type); Py_CLEAR(module_state->writer_type); + Py_CLEAR(module_state->str_write); return 0; } @@ -168,8 +176,7 @@ get_char_or_None(Py_UCS4 c) static PyObject * Dialect_get_lineterminator(DialectObj *self, void *Py_UNUSED(ignored)) { - Py_XINCREF(self->lineterminator); - return self->lineterminator; + return Py_XNewRef(self->lineterminator); } static PyObject * @@ -308,8 +315,7 @@ _set_str(const char *name, PyObject **target, PyObject *src, const char *dflt) else { if (PyUnicode_READY(src) == -1) return -1; - Py_INCREF(src); - Py_XSETREF(*target, src); + Py_XSETREF(*target, Py_NewRef(src)); } } return 0; @@ -372,7 +378,7 @@ static char *dialect_kws[] = { static _csvstate * _csv_state_from_type(PyTypeObject *type, const char *name) { - PyObject *module = _PyType_GetModuleByDef(type, &_csvmodule); + PyObject *module = PyType_GetModuleByDef(type, &_csvmodule); if (module == NULL) { return NULL; } @@ -506,8 +512,7 @@ dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto err; } - ret = (PyObject *)self; - Py_INCREF(self); + ret = Py_NewRef(self); err: Py_CLEAR(self); Py_CLEAR(dialect); @@ -696,7 +701,7 @@ parse_process_char(ReaderObj *self, _csvstate *module_state, Py_UCS4 c) self->state = ESCAPED_CHAR; } else if (c == ' ' && dialect->skipinitialspace) - /* ignore space at start of field */ + /* ignore spaces at start of field */ ; else if (c == dialect->delimiter) { /* save empty field */ @@ -860,7 +865,7 @@ Reader_iternext(ReaderObj *self) PyObject *fields = NULL; Py_UCS4 c; Py_ssize_t pos, linelen; - unsigned int kind; + int kind; const void *data; PyObject *lineobj; @@ -1058,7 +1063,7 @@ join_reset(WriterObj *self) * record length. */ static Py_ssize_t -join_append_data(WriterObj *self, unsigned int field_kind, const void *field_data, +join_append_data(WriterObj *self, int field_kind, const void *field_data, Py_ssize_t field_len, int *quoted, int copy_phase) { @@ -1171,7 +1176,7 @@ join_check_rec_size(WriterObj *self, Py_ssize_t rec_len) static int join_append(WriterObj *self, PyObject *field, int quoted) { - unsigned int field_kind = -1; + int field_kind = -1; const void *field_data = NULL; Py_ssize_t field_len = 0; Py_ssize_t rec_len; @@ -1203,7 +1208,7 @@ static int join_append_lineterminator(WriterObj *self) { Py_ssize_t terminator_len, i; - unsigned int term_kind; + int term_kind; const void *term_data; terminator_len = PyUnicode_GET_LENGTH(self->dialect->lineterminator); @@ -1428,7 +1433,6 @@ csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args) PyObject * output_file, * dialect = NULL; _csvstate *module_state = get_csv_state(module); WriterObj * self = PyObject_GC_New(WriterObj, module_state->writer_type); - _Py_IDENTIFIER(write); if (!self) return NULL; @@ -1447,7 +1451,9 @@ csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args) Py_DECREF(self); return NULL; } - if (_PyObject_LookupAttrId(output_file, &PyId_write, &self->write) < 0) { + if (_PyObject_LookupAttr(output_file, + module_state->str_write, + &self->write) < 0) { Py_DECREF(self); return NULL; } @@ -1470,8 +1476,18 @@ csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args) /* * DIALECT REGISTRY */ + +/*[clinic input] +_csv.list_dialects + +Return a list of all known dialect names. + + names = csv.list_dialects() +[clinic start generated code]*/ + static PyObject * -csv_list_dialects(PyObject *module, PyObject *args) +_csv_list_dialects_impl(PyObject *module) +/*[clinic end generated code: output=a5b92b215b006a6d input=8953943eb17d98ab]*/ { return PyDict_Keys(get_csv_state(module)->dialects); } @@ -1503,11 +1519,23 @@ csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs) Py_RETURN_NONE; } + +/*[clinic input] +_csv.unregister_dialect + + name: object + +Delete the name/dialect mapping associated with a string name. + + csv.unregister_dialect(name) +[clinic start generated code]*/ + static PyObject * -csv_unregister_dialect(PyObject *module, PyObject *name_obj) +_csv_unregister_dialect_impl(PyObject *module, PyObject *name) +/*[clinic end generated code: output=0813ebca6c058df4 input=6b5c1557bf60c7e7]*/ { _csvstate *module_state = get_csv_state(module); - if (PyDict_DelItem(module_state->dialects, name_obj) < 0) { + if (PyDict_DelItem(module_state->dialects, name) < 0) { if (PyErr_ExceptionMatches(PyExc_KeyError)) { PyErr_Format(module_state->error_obj, "unknown dialect"); } @@ -1516,21 +1544,42 @@ csv_unregister_dialect(PyObject *module, PyObject *name_obj) Py_RETURN_NONE; } +/*[clinic input] +_csv.get_dialect + + name: object + +Return the dialect instance associated with name. + + dialect = csv.get_dialect(name) +[clinic start generated code]*/ + static PyObject * -csv_get_dialect(PyObject *module, PyObject *name_obj) +_csv_get_dialect_impl(PyObject *module, PyObject *name) +/*[clinic end generated code: output=aa988cd573bebebb input=edf9ddab32e448fb]*/ { - return get_dialect_from_registry(name_obj, get_csv_state(module)); + return get_dialect_from_registry(name, get_csv_state(module)); } +/*[clinic input] +_csv.field_size_limit + + new_limit: object = NULL + +Sets an upper limit on parsed fields. + + csv.field_size_limit([limit]) + +Returns old limit. If limit is not given, no new limit is set and +the old limit is returned +[clinic start generated code]*/ + static PyObject * -csv_field_size_limit(PyObject *module, PyObject *args) +_csv_field_size_limit_impl(PyObject *module, PyObject *new_limit) +/*[clinic end generated code: output=f2799ecd908e250b input=cec70e9226406435]*/ { - PyObject *new_limit = NULL; _csvstate *module_state = get_csv_state(module); long old_limit = module_state->field_limit; - - if (!PyArg_UnpackTuple(args, "field_size_limit", 0, 1, &new_limit)) - return NULL; if (new_limit != NULL) { if (!PyLong_CheckExact(new_limit)) { PyErr_Format(PyExc_TypeError, @@ -1595,9 +1644,9 @@ PyDoc_STRVAR(csv_module_doc, " quoting character. It defaults to '\"'.\n" " * delimiter - specifies a one-character string to use as the\n" " field separator. It defaults to ','.\n" -" * skipinitialspace - specifies how to interpret whitespace which\n" -" immediately follows a delimiter. It defaults to False, which\n" -" means that whitespace immediately following a delimiter is part\n" +" * skipinitialspace - specifies how to interpret spaces which\n" +" immediately follow a delimiter. It defaults to False, which\n" +" means that spaces immediately following a delimiter is part\n" " of the following field.\n" " * lineterminator - specifies the character sequence which should\n" " terminate rows.\n" @@ -1647,44 +1696,21 @@ PyDoc_STRVAR(csv_writer_doc, "\n" "The \"fileobj\" argument can be any object that supports the file API.\n"); -PyDoc_STRVAR(csv_list_dialects_doc, -"Return a list of all know dialect names.\n" -" names = csv.list_dialects()"); - -PyDoc_STRVAR(csv_get_dialect_doc, -"Return the dialect instance associated with name.\n" -" dialect = csv.get_dialect(name)"); - PyDoc_STRVAR(csv_register_dialect_doc, "Create a mapping from a string name to a dialect class.\n" " dialect = csv.register_dialect(name[, dialect[, **fmtparams]])"); -PyDoc_STRVAR(csv_unregister_dialect_doc, -"Delete the name/dialect mapping associated with a string name.\n" -" csv.unregister_dialect(name)"); - -PyDoc_STRVAR(csv_field_size_limit_doc, -"Sets an upper limit on parsed fields.\n" -" csv.field_size_limit([limit])\n" -"\n" -"Returns old limit. If limit is not given, no new limit is set and\n" -"the old limit is returned"); - static struct PyMethodDef csv_methods[] = { - { "reader", (PyCFunction)(void(*)(void))csv_reader, + { "reader", _PyCFunction_CAST(csv_reader), METH_VARARGS | METH_KEYWORDS, csv_reader_doc}, - { "writer", (PyCFunction)(void(*)(void))csv_writer, + { "writer", _PyCFunction_CAST(csv_writer), METH_VARARGS | METH_KEYWORDS, csv_writer_doc}, - { "list_dialects", (PyCFunction)csv_list_dialects, - METH_NOARGS, csv_list_dialects_doc}, - { "register_dialect", (PyCFunction)(void(*)(void))csv_register_dialect, + { "register_dialect", _PyCFunction_CAST(csv_register_dialect), METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc}, - { "unregister_dialect", (PyCFunction)csv_unregister_dialect, - METH_O, csv_unregister_dialect_doc}, - { "get_dialect", (PyCFunction)csv_get_dialect, - METH_O, csv_get_dialect_doc}, - { "field_size_limit", (PyCFunction)csv_field_size_limit, - METH_VARARGS, csv_field_size_limit_doc}, + _CSV_LIST_DIALECTS_METHODDEF + _CSV_UNREGISTER_DIALECT_METHODDEF + _CSV_GET_DIALECT_METHODDEF + _CSV_FIELD_SIZE_LIMIT_METHODDEF { NULL, NULL } }; @@ -1749,6 +1775,10 @@ csv_exec(PyObject *module) { return -1; } + module_state->str_write = PyUnicode_InternFromString("write"); + if (module_state->str_write == NULL) { + return -1; + } return 0; } diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 96078c7726d..8690f2c1b07 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -101,7 +101,6 @@ bytes(cdata) #ifndef Py_BUILD_CORE_BUILTIN # define Py_BUILD_CORE_MODULE 1 #endif - #define PY_SSIZE_T_CLEAN #include "Python.h" @@ -111,6 +110,7 @@ bytes(cdata) #endif #include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_ceval.h" // _Py_EnterRecursiveCall() #include "structmember.h" // PyMemberDef #include @@ -120,7 +120,7 @@ bytes(cdata) #define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0) #endif #else -#include "ctypes_dlfcn.h" +#include #endif #include "ctypes.h" @@ -195,7 +195,7 @@ static PyTypeObject DictRemover_Type = { 0, /* tp_as_buffer */ /* XXX should participate in GC? */ Py_TPFLAGS_DEFAULT, /* tp_flags */ - "deletes a key from a dictionary", /* tp_doc */ + PyDoc_STR("deletes a key from a dictionary"), /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -231,10 +231,8 @@ PyDict_SetItemProxy(PyObject *dict, PyObject *key, PyObject *item) remover = (DictRemoverObject *)obj; assert(remover->key == NULL); assert(remover->dict == NULL); - Py_INCREF(key); - remover->key = key; - Py_INCREF(dict); - remover->dict = dict; + remover->key = Py_NewRef(key); + remover->dict = Py_NewRef(dict); proxy = PyWeakref_NewProxy(item, obj); Py_DECREF(obj); @@ -394,9 +392,9 @@ _ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape, strcat(new_prefix, "("); for (k = 0; k < ndim; ++k) { if (k < ndim-1) { - sprintf(buf, "%"PY_FORMAT_SIZE_T"d,", shape[k]); + sprintf(buf, "%zd,", shape[k]); } else { - sprintf(buf, "%"PY_FORMAT_SIZE_T"d)", shape[k]); + sprintf(buf, "%zd)", shape[k]); } strcat(new_prefix, buf); } @@ -414,6 +412,7 @@ _ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape, typedef struct { PyObject_HEAD void *ptr; + PyObject *keep; // If set, a reference to the original CDataObject. } StructParamObject; @@ -421,6 +420,7 @@ static void StructParam_dealloc(PyObject *myself) { StructParamObject *self = (StructParamObject *)myself; + Py_XDECREF(self->keep); PyMem_Free(self->ptr); Py_TYPE(self)->tp_free(myself); } @@ -468,10 +468,10 @@ StructUnionType_paramfunc(CDataObject *self) StructParamObject *struct_param = (StructParamObject *)obj; struct_param->ptr = ptr; + struct_param->keep = Py_NewRef(self); } else { ptr = self->b_ptr; - obj = (PyObject *)self; - Py_INCREF(obj); + obj = Py_NewRef(self); } parg = PyCArgObject_new(); @@ -496,8 +496,6 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt PyTypeObject *result; PyObject *fields; StgDictObject *dict; - _Py_IDENTIFIER(_abstract_); - _Py_IDENTIFIER(_fields_); /* create the new instance (which is a class, since we are a metatype!) */ @@ -506,7 +504,7 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt return NULL; /* keep this for bw compatibility */ - int r = _PyDict_ContainsId(result->tp_dict, &PyId__abstract_); + int r = PyDict_Contains(result->tp_dict, &_Py_ID(_abstract_)); if (r > 0) return (PyObject *)result; if (r < 0) { @@ -538,9 +536,9 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt dict->paramfunc = StructUnionType_paramfunc; - fields = _PyDict_GetItemIdWithError((PyObject *)dict, &PyId__fields_); + fields = PyDict_GetItemWithError((PyObject *)dict, &_Py_ID(_fields_)); if (fields) { - if (_PyObject_SetAttrId((PyObject *)result, &PyId__fields_, fields) < 0) { + if (PyObject_SetAttr((PyObject *)result, &_Py_ID(_fields_), fields) < 0) { Py_DECREF(result); return NULL; } @@ -578,8 +576,8 @@ UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return StructUnionType_new(type, args, kwds, 0); } -static const char from_address_doc[] = -"C.from_address(integer) -> C instance\naccess a C instance at the specified address"; +PyDoc_STRVAR(from_address_doc, +"C.from_address(integer) -> C instance\naccess a C instance at the specified address"); static PyObject * CDataType_from_address(PyObject *type, PyObject *value) @@ -596,8 +594,8 @@ CDataType_from_address(PyObject *type, PyObject *value) return PyCData_AtAddress(type, buf); } -static const char from_buffer_doc[] = -"C.from_buffer(object, offset=0) -> C instance\ncreate a C instance from a writeable buffer"; +PyDoc_STRVAR(from_buffer_doc, +"C.from_buffer(object, offset=0) -> C instance\ncreate a C instance from a writeable buffer"); static int KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep); @@ -676,8 +674,8 @@ CDataType_from_buffer(PyObject *type, PyObject *args) return result; } -static const char from_buffer_copy_doc[] = -"C.from_buffer_copy(object, offset=0) -> C instance\ncreate a C instance from a readable buffer"; +PyDoc_STRVAR(from_buffer_copy_doc, +"C.from_buffer_copy(object, offset=0) -> C instance\ncreate a C instance from a readable buffer"); static PyObject * GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds); @@ -727,8 +725,8 @@ CDataType_from_buffer_copy(PyObject *type, PyObject *args) return result; } -static const char in_dll_doc[] = -"C.in_dll(dll, name) -> C instance\naccess a C instance in a dll"; +PyDoc_STRVAR(in_dll_doc, +"C.in_dll(dll, name) -> C instance\naccess a C instance in a dll"); static PyObject * CDataType_in_dll(PyObject *type, PyObject *args) @@ -773,7 +771,7 @@ CDataType_in_dll(PyObject *type, PyObject *args) return NULL; } #else - address = (void *)ctypes_dlsym(handle, name); + address = (void *)dlsym(handle, name); if (!address) { #ifdef __CYGWIN__ /* dlerror() isn't very helpful on cygwin */ @@ -781,7 +779,7 @@ CDataType_in_dll(PyObject *type, PyObject *args) "symbol '%s' not found", name); #else - PyErr_SetString(PyExc_ValueError, ctypes_dlerror()); + PyErr_SetString(PyExc_ValueError, dlerror()); #endif return NULL; } @@ -789,20 +787,18 @@ CDataType_in_dll(PyObject *type, PyObject *args) return PyCData_AtAddress(type, address); } -static const char from_param_doc[] = -"Convert a Python object into a function call parameter."; +PyDoc_STRVAR(from_param_doc, +"Convert a Python object into a function call parameter."); static PyObject * CDataType_from_param(PyObject *type, PyObject *value) { - _Py_IDENTIFIER(_as_parameter_); PyObject *as_parameter; int res = PyObject_IsInstance(value, type); if (res == -1) return NULL; if (res) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } if (PyCArg_CheckExact(value)) { PyCArgObject *p = (PyCArgObject *)value; @@ -818,8 +814,7 @@ CDataType_from_param(PyObject *type, PyObject *value) if (res == -1) return NULL; if (res) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } } ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???"; @@ -829,7 +824,7 @@ CDataType_from_param(PyObject *type, PyObject *value) return NULL; } - if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { + if (_PyObject_LookupAttr(value, &_Py_ID(_as_parameter_), &as_parameter) < 0) { return NULL; } if (as_parameter) { @@ -944,7 +939,7 @@ PyTypeObject PyCStructType_Type = { PyCStructType_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "metatype for the CData Objects", /* tp_doc */ + PyDoc_STR("metatype for the CData Objects"), /* tp_doc */ (traverseproc)CDataType_traverse, /* tp_traverse */ (inquiry)CDataType_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -986,7 +981,7 @@ static PyTypeObject UnionType_Type = { UnionType_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "metatype for the CData Objects", /* tp_doc */ + PyDoc_STR("metatype for the CData Objects"), /* tp_doc */ (traverseproc)CDataType_traverse, /* tp_traverse */ (inquiry)CDataType_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -1053,8 +1048,7 @@ PyCPointerType_paramfunc(CDataObject *self) parg->tag = 'P'; parg->pffi_type = &ffi_type_pointer; - Py_INCREF(self); - parg->obj = (PyObject *)self; + parg->obj = Py_NewRef(self); parg->value.p = *(void **)self->b_ptr; return parg; } @@ -1066,7 +1060,7 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) StgDictObject *stgdict; PyObject *proto; PyObject *typedict; - _Py_IDENTIFIER(_type_); + typedict = PyTuple_GetItem(args, 2); if (!typedict) @@ -1086,7 +1080,7 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) stgdict->paramfunc = PyCPointerType_paramfunc; stgdict->flags |= TYPEFLAG_ISPOINTER; - proto = _PyDict_GetItemIdWithError(typedict, &PyId__type_); /* Borrowed ref */ + proto = PyDict_GetItemWithError(typedict, &_Py_ID(_type_)); /* Borrowed ref */ if (proto) { StgDictObject *itemdict; const char *current_format; @@ -1144,7 +1138,7 @@ static PyObject * PyCPointerType_set_type(PyTypeObject *self, PyObject *type) { StgDictObject *dict; - _Py_IDENTIFIER(_type_); + dict = PyType_stgdict((PyObject *)self); if (!dict) { @@ -1156,7 +1150,7 @@ PyCPointerType_set_type(PyTypeObject *self, PyObject *type) if (-1 == PyCPointerType_SetProto(dict, type)) return NULL; - if (-1 == _PyDict_SetItemId((PyObject *)dict, &PyId__type_, type)) + if (-1 == PyDict_SetItem((PyObject *)dict, &_Py_ID(_type_), type)) return NULL; Py_RETURN_NONE; @@ -1171,8 +1165,7 @@ PyCPointerType_from_param(PyObject *type, PyObject *value) if (value == Py_None) { /* ConvParam will convert to a NULL pointer later */ - Py_INCREF(value); - return value; + return Py_NewRef(value); } typedict = PyType_stgdict(type); @@ -1206,8 +1199,7 @@ PyCPointerType_from_param(PyObject *type, PyObject *value) return NULL; } if (ret) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } } return CDataType_from_param(type, value); @@ -1244,7 +1236,7 @@ PyTypeObject PyCPointerType_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "metatype for the Pointer Objects", /* tp_doc */ + PyDoc_STR("metatype for the Pointer Objects"), /* tp_doc */ (traverseproc)CDataType_traverse, /* tp_traverse */ (inquiry)CDataType_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -1417,49 +1409,12 @@ static PyGetSetDef WCharArray_getsets[] = { }; /* - The next three functions copied from Python's typeobject.c. + The next function is copied from Python's typeobject.c. - They are used to attach methods, members, or getsets to a type *after* it + It is used to attach getsets to a type *after* it has been created: Arrays of characters have additional getsets to treat them as strings. */ -/* -static int -add_methods(PyTypeObject *type, PyMethodDef *meth) -{ - PyObject *dict = type->tp_dict; - for (; meth->ml_name != NULL; meth++) { - PyObject *descr; - descr = PyDescr_NewMethod(type, meth); - if (descr == NULL) - return -1; - if (PyDict_SetItemString(dict, meth->ml_name, descr) < 0) { - Py_DECREF(descr); - return -1; - } - Py_DECREF(descr); - } - return 0; -} - -static int -add_members(PyTypeObject *type, PyMemberDef *memb) -{ - PyObject *dict = type->tp_dict; - for (; memb->name != NULL; memb++) { - PyObject *descr; - descr = PyDescr_NewMember(type, memb); - if (descr == NULL) - return -1; - if (PyDict_SetItemString(dict, memb->name, descr) < 0) { - Py_DECREF(descr); - return -1; - } - Py_DECREF(descr); - } - return 0; -} -*/ static int add_getset(PyTypeObject *type, PyGetSetDef *gsp) @@ -1488,16 +1443,13 @@ PyCArrayType_paramfunc(CDataObject *self) p->tag = 'P'; p->pffi_type = &ffi_type_pointer; p->value.p = (char *)self->b_ptr; - Py_INCREF(self); - p->obj = (PyObject *)self; + p->obj = Py_NewRef(self); return p; } static PyObject * PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - _Py_IDENTIFIER(_length_); - _Py_IDENTIFIER(_type_); PyTypeObject *result; StgDictObject *stgdict; StgDictObject *itemdict; @@ -1516,7 +1468,7 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) stgdict = NULL; type_attr = NULL; - if (_PyObject_LookupAttrId((PyObject *)result, &PyId__length_, &length_attr) < 0) { + if (_PyObject_LookupAttr((PyObject *)result, &_Py_ID(_length_), &length_attr) < 0) { goto error; } if (!length_attr) { @@ -1549,7 +1501,7 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) goto error; } - if (_PyObject_LookupAttrId((PyObject *)result, &PyId__type_, &type_attr) < 0) { + if (_PyObject_LookupAttr((PyObject *)result, &_Py_ID(_type_), &type_attr) < 0) { goto error; } if (!type_attr) { @@ -1656,7 +1608,7 @@ PyTypeObject PyCArrayType_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "metatype for the Array Objects", /* tp_doc */ + PyDoc_STR("metatype for the Array Objects"), /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -1694,7 +1646,6 @@ static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdfuzZqQPXOv?g"; static PyObject * c_wchar_p_from_param(PyObject *type, PyObject *value) { - _Py_IDENTIFIER(_as_parameter_); PyObject *as_parameter; int res; if (value == Py_None) { @@ -1720,8 +1671,7 @@ c_wchar_p_from_param(PyObject *type, PyObject *value) if (res == -1) return NULL; if (res) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } if (ArrayObject_Check(value) || PointerObject_Check(value)) { /* c_wchar array instance or pointer(c_wchar(...)) */ @@ -1730,8 +1680,7 @@ c_wchar_p_from_param(PyObject *type, PyObject *value) assert(dt); /* Cannot be NULL for pointer or array objects */ dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } } if (PyCArg_CheckExact(value)) { @@ -1739,12 +1688,11 @@ c_wchar_p_from_param(PyObject *type, PyObject *value) PyCArgObject *a = (PyCArgObject *)value; StgDictObject *dict = PyObject_stgdict(a->obj); if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } } - if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { + if (_PyObject_LookupAttr(value, &_Py_ID(_as_parameter_), &as_parameter) < 0) { return NULL; } if (as_parameter) { @@ -1761,7 +1709,6 @@ c_wchar_p_from_param(PyObject *type, PyObject *value) static PyObject * c_char_p_from_param(PyObject *type, PyObject *value) { - _Py_IDENTIFIER(_as_parameter_); PyObject *as_parameter; int res; if (value == Py_None) { @@ -1787,8 +1734,7 @@ c_char_p_from_param(PyObject *type, PyObject *value) if (res == -1) return NULL; if (res) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } if (ArrayObject_Check(value) || PointerObject_Check(value)) { /* c_char array instance or pointer(c_char(...)) */ @@ -1797,8 +1743,7 @@ c_char_p_from_param(PyObject *type, PyObject *value) assert(dt); /* Cannot be NULL for pointer or array objects */ dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } } if (PyCArg_CheckExact(value)) { @@ -1806,12 +1751,11 @@ c_char_p_from_param(PyObject *type, PyObject *value) PyCArgObject *a = (PyCArgObject *)value; StgDictObject *dict = PyObject_stgdict(a->obj); if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } } - if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { + if (_PyObject_LookupAttr(value, &_Py_ID(_as_parameter_), &as_parameter) < 0) { return NULL; } if (as_parameter) { @@ -1828,7 +1772,6 @@ c_char_p_from_param(PyObject *type, PyObject *value) static PyObject * c_void_p_from_param(PyObject *type, PyObject *value) { - _Py_IDENTIFIER(_as_parameter_); StgDictObject *stgd; PyObject *as_parameter; int res; @@ -1896,22 +1839,19 @@ c_void_p_from_param(PyObject *type, PyObject *value) return NULL; if (res) { /* c_void_p instances */ - Py_INCREF(value); - return value; + return Py_NewRef(value); } /* ctypes array or pointer instance */ if (ArrayObject_Check(value) || PointerObject_Check(value)) { /* Any array or pointer is accepted */ - Py_INCREF(value); - return value; + return Py_NewRef(value); } /* byref(...) */ if (PyCArg_CheckExact(value)) { /* byref(c_xxx()) */ PyCArgObject *a = (PyCArgObject *)value; if (a->tag == 'P') { - Py_INCREF(value); - return value; + return Py_NewRef(value); } } /* function pointer */ @@ -1942,15 +1882,14 @@ c_void_p_from_param(PyObject *type, PyObject *value) return NULL; parg->pffi_type = &ffi_type_pointer; parg->tag = 'Z'; - Py_INCREF(value); - parg->obj = value; + parg->obj = Py_NewRef(value); /* Remember: b_ptr points to where the pointer is stored! */ parg->value.p = *(void **)(((CDataObject *)value)->b_ptr); return (PyObject *)parg; } } - if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { + if (_PyObject_LookupAttr(value, &_Py_ID(_as_parameter_), &as_parameter) < 0) { return NULL; } if (as_parameter) { @@ -2028,8 +1967,7 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject stgdict->setfunc = fmt->setfunc_swapped; stgdict->getfunc = fmt->getfunc_swapped; - Py_INCREF(proto); - stgdict->proto = proto; + stgdict->proto = Py_NewRef(proto); /* replace the class dict by our updated spam dict */ if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) { @@ -2064,8 +2002,7 @@ PyCSimpleType_paramfunc(CDataObject *self) parg->tag = fmt[0]; parg->pffi_type = fd->pffi_type; - Py_INCREF(self); - parg->obj = (PyObject *)self; + parg->obj = Py_NewRef(self); memcpy(&parg->value, self->b_ptr, self->b_size); return parg; } @@ -2073,7 +2010,6 @@ PyCSimpleType_paramfunc(CDataObject *self) static PyObject * PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - _Py_IDENTIFIER(_type_); PyTypeObject *result; StgDictObject *stgdict; PyObject *proto; @@ -2088,7 +2024,7 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (result == NULL) return NULL; - if (_PyObject_LookupAttrId((PyObject *)result, &PyId__type_, &proto) < 0) { + if (_PyObject_LookupAttr((PyObject *)result, &_Py_ID(_type_), &proto) < 0) { return NULL; } if (!proto) { @@ -2258,13 +2194,13 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static PyObject * PyCSimpleType_from_param(PyObject *type, PyObject *value) { - _Py_IDENTIFIER(_as_parameter_); StgDictObject *dict; const char *fmt; PyCArgObject *parg; struct fielddesc *fd; PyObject *as_parameter; int res; + PyObject *exc, *val, *tb; /* If the value is already an instance of the requested type, we can use it as is */ @@ -2272,8 +2208,7 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value) if (res == -1) return NULL; if (res) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } dict = PyType_stgdict(type); @@ -2299,24 +2234,37 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value) parg->obj = fd->setfunc(&parg->value, value, 0); if (parg->obj) return (PyObject *)parg; - PyErr_Clear(); + PyErr_Fetch(&exc, &val, &tb); Py_DECREF(parg); - if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { + if (_PyObject_LookupAttr(value, &_Py_ID(_as_parameter_), &as_parameter) < 0) { + Py_XDECREF(exc); + Py_XDECREF(val); + Py_XDECREF(tb); return NULL; } if (as_parameter) { - if (Py_EnterRecursiveCall("while processing _as_parameter_")) { + if (_Py_EnterRecursiveCall("while processing _as_parameter_")) { Py_DECREF(as_parameter); + Py_XDECREF(exc); + Py_XDECREF(val); + Py_XDECREF(tb); return NULL; } value = PyCSimpleType_from_param(type, as_parameter); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(as_parameter); + Py_XDECREF(exc); + Py_XDECREF(val); + Py_XDECREF(tb); return value; } - PyErr_SetString(PyExc_TypeError, - "wrong type"); + if (exc) { + PyErr_Restore(exc, val, tb); + } + else { + PyErr_SetString(PyExc_TypeError, "wrong type"); + } return NULL; } @@ -2350,7 +2298,7 @@ PyTypeObject PyCSimpleType_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "metatype for the PyCSimpleType Objects", /* tp_doc */ + PyDoc_STR("metatype for the PyCSimpleType Objects"), /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -2379,10 +2327,8 @@ PyTypeObject PyCSimpleType_Type = { static PyObject * converters_from_argtypes(PyObject *ob) { - _Py_IDENTIFIER(from_param); PyObject *converters; Py_ssize_t i; - Py_ssize_t nArgs; ob = PySequence_Tuple(ob); /* new reference */ if (!ob) { @@ -2391,7 +2337,15 @@ converters_from_argtypes(PyObject *ob) return NULL; } - nArgs = PyTuple_GET_SIZE(ob); + Py_ssize_t nArgs = PyTuple_GET_SIZE(ob); + if (nArgs > CTYPES_MAX_ARGCOUNT) { + Py_DECREF(ob); + PyErr_Format(PyExc_ArgError, + "_argtypes_ has too many arguments (%zi), maximum is %i", + nArgs, CTYPES_MAX_ARGCOUNT); + return NULL; + } + converters = PyTuple_New(nArgs); if (!converters) { Py_DECREF(ob); @@ -2452,7 +2406,7 @@ converters_from_argtypes(PyObject *ob) } */ - if (_PyObject_LookupAttrId(tp, &PyId_from_param, &cnv) <= 0) { + if (_PyObject_LookupAttr(tp, &_Py_ID(from_param), &cnv) <= 0) { Py_DECREF(converters); Py_DECREF(ob); if (!PyErr_Occurred()) { @@ -2473,10 +2427,6 @@ make_funcptrtype_dict(StgDictObject *stgdict) { PyObject *ob; PyObject *converters = NULL; - _Py_IDENTIFIER(_flags_); - _Py_IDENTIFIER(_argtypes_); - _Py_IDENTIFIER(_restype_); - _Py_IDENTIFIER(_check_retval_); stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment; stgdict->length = 1; @@ -2485,7 +2435,7 @@ make_funcptrtype_dict(StgDictObject *stgdict) stgdict->getfunc = NULL; stgdict->ffi_type_pointer = ffi_type_pointer; - ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__flags_); + ob = PyDict_GetItemWithError((PyObject *)stgdict, &_Py_ID(_flags_)); if (!ob || !PyLong_Check(ob)) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, @@ -2496,29 +2446,27 @@ make_funcptrtype_dict(StgDictObject *stgdict) stgdict->flags = PyLong_AsUnsignedLongMask(ob) | TYPEFLAG_ISPOINTER; /* _argtypes_ is optional... */ - ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__argtypes_); + ob = PyDict_GetItemWithError((PyObject *)stgdict, &_Py_ID(_argtypes_)); if (ob) { converters = converters_from_argtypes(ob); if (!converters) return -1; - Py_INCREF(ob); - stgdict->argtypes = ob; + stgdict->argtypes = Py_NewRef(ob); stgdict->converters = converters; } else if (PyErr_Occurred()) { return -1; } - ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__restype_); + ob = PyDict_GetItemWithError((PyObject *)stgdict, &_Py_ID(_restype_)); if (ob) { if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) { PyErr_SetString(PyExc_TypeError, "_restype_ must be a type, a callable, or None"); return -1; } - Py_INCREF(ob); - stgdict->restype = ob; - if (_PyObject_LookupAttrId(ob, &PyId__check_retval_, + stgdict->restype = Py_NewRef(ob); + if (_PyObject_LookupAttr(ob, &_Py_ID(_check_retval_), &stgdict->checker) < 0) { return -1; @@ -2535,8 +2483,7 @@ make_funcptrtype_dict(StgDictObject *stgdict) "_errcheck_ must be callable"); return -1; } - Py_INCREF(ob); - stgdict->errcheck = ob; + stgdict->errcheck = Py_NewRef(ob); } else if (PyErr_Occurred()) { return -1; @@ -2556,8 +2503,7 @@ PyCFuncPtrType_paramfunc(CDataObject *self) parg->tag = 'P'; parg->pffi_type = &ffi_type_pointer; - Py_INCREF(self); - parg->obj = (PyObject *)self; + parg->obj = Py_NewRef(self); parg->value.p = *(void **)self->b_ptr; return parg; } @@ -2632,7 +2578,7 @@ PyTypeObject PyCFuncPtrType_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "metatype for C function pointers", /* tp_doc */ + PyDoc_STR("metatype for C function pointers"), /* tp_doc */ (traverseproc)CDataType_traverse, /* tp_traverse */ (inquiry)CDataType_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -2669,8 +2615,7 @@ PyCData_GetContainer(CDataObject *self) if (self->b_objects == NULL) return NULL; } else { - Py_INCREF(Py_None); - self->b_objects = Py_None; + self->b_objects = Py_NewRef(Py_None); } } return self; @@ -2803,29 +2748,45 @@ static PyMemberDef PyCData_members[] = { { NULL }, }; -static int PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags) +/* Find the innermost type of an array type, returning a borrowed reference */ +static PyObject * +PyCData_item_type(PyObject *type) +{ + if (PyCArrayTypeObject_Check(type)) { + StgDictObject *stg_dict; + PyObject *elem_type; + + /* asserts used here as these are all guaranteed by construction */ + stg_dict = PyType_stgdict(type); + assert(stg_dict); + elem_type = stg_dict->proto; + assert(elem_type); + return PyCData_item_type(elem_type); + } + else { + return type; + } +} + +static int +PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags) { CDataObject *self = (CDataObject *)myself; StgDictObject *dict = PyObject_stgdict(myself); - Py_ssize_t i; + PyObject *item_type = PyCData_item_type((PyObject*)Py_TYPE(myself)); + StgDictObject *item_dict = PyType_stgdict(item_type); if (view == NULL) return 0; view->buf = self->b_ptr; - view->obj = myself; - Py_INCREF(myself); + view->obj = Py_NewRef(myself); view->len = self->b_size; view->readonly = 0; /* use default format character if not set */ view->format = dict->format ? dict->format : "B"; view->ndim = dict->ndim; view->shape = dict->shape; - view->itemsize = self->b_size; - if (view->itemsize) { - for (i = 0; i < view->ndim; ++i) { - view->itemsize /= dict->shape[i]; - } - } + view->itemsize = item_dict->size; view->strides = NULL; view->suboffsets = NULL; view->internal = NULL; @@ -2905,8 +2866,7 @@ PyCData_setstate(PyObject *myself, PyObject *args) static PyObject * PyCData_from_outparam(PyObject *self, PyObject *args) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyMethodDef PyCData_methods[] = { @@ -2937,7 +2897,7 @@ PyTypeObject PyCData_Type = { 0, /* tp_setattro */ &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "XXX to be provided", /* tp_doc */ + PyDoc_STR("XXX to be provided"), /* tp_doc */ (traverseproc)PyCData_traverse, /* tp_traverse */ (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -3011,8 +2971,7 @@ PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr) assert(CDataObject_Check(base)); cmem->b_ptr = adr; cmem->b_needsfree = 0; - Py_INCREF(base); - cmem->b_base = (CDataObject *)base; + cmem->b_base = (CDataObject *)Py_NewRef(base); cmem->b_index = index; } else { /* copy contents of adr */ if (-1 == PyCData_MallocBuffer(cmem, dict)) { @@ -3149,8 +3108,7 @@ _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, if (value == NULL) return NULL; - Py_INCREF(value); - return value; + return Py_NewRef(value); } if (PyCPointerTypeObject_Check(type) @@ -3273,8 +3231,7 @@ static PyObject * PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self, void *Py_UNUSED(ignored)) { if (self->errcheck) { - Py_INCREF(self->errcheck); - return self->errcheck; + return Py_NewRef(self->errcheck); } Py_RETURN_NONE; } @@ -3282,7 +3239,6 @@ PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self, void *Py_UNUSED(ignored)) static int PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(_check_retval_); PyObject *checker, *oldchecker; if (ob == NULL) { oldchecker = self->checker; @@ -3296,7 +3252,7 @@ PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ign "restype must be a type, a callable, or None"); return -1; } - if (_PyObject_LookupAttrId(ob, &PyId__check_retval_, &checker) < 0) { + if (_PyObject_LookupAttr(ob, &_Py_ID(_check_retval_), &checker) < 0) { return -1; } oldchecker = self->checker; @@ -3312,14 +3268,12 @@ PyCFuncPtr_get_restype(PyCFuncPtrObject *self, void *Py_UNUSED(ignored)) { StgDictObject *dict; if (self->restype) { - Py_INCREF(self->restype); - return self->restype; + return Py_NewRef(self->restype); } dict = PyObject_stgdict((PyObject *)self); assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */ if (dict->restype) { - Py_INCREF(dict->restype); - return dict->restype; + return Py_NewRef(dict->restype); } else { Py_RETURN_NONE; } @@ -3349,14 +3303,12 @@ PyCFuncPtr_get_argtypes(PyCFuncPtrObject *self, void *Py_UNUSED(ignored)) { StgDictObject *dict; if (self->argtypes) { - Py_INCREF(self->argtypes); - return self->argtypes; + return Py_NewRef(self->argtypes); } dict = PyObject_stgdict((PyObject *)self); assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */ if (dict->argtypes) { - Py_INCREF(dict->argtypes); - return dict->argtypes; + return Py_NewRef(dict->argtypes); } else { Py_RETURN_NONE; } @@ -3625,7 +3577,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } #else - address = (PPROC)ctypes_dlsym(handle, name); + address = (PPROC)dlsym(handle, name); if (!address) { #ifdef __CYGWIN__ /* dlerror() isn't very helpful on cygwin */ @@ -3633,7 +3585,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) "function '%s' not found", name); #else - PyErr_SetString(PyExc_AttributeError, ctypes_dlerror()); + PyErr_SetString(PyExc_AttributeError, dlerror()); #endif Py_DECREF(ftuple); return NULL; @@ -3650,8 +3602,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - Py_XINCREF(paramflags); - self->paramflags = paramflags; + self->paramflags = Py_XNewRef(paramflags); *(void **)self->b_ptr = address; Py_INCREF(dll); @@ -3661,8 +3612,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - Py_INCREF(self); - self->callable = (PyObject *)self; + self->callable = Py_NewRef(self); return (PyObject *)self; } @@ -3687,8 +3637,7 @@ PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds) self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds); self->index = index + 0x1000; - Py_XINCREF(paramflags); - self->paramflags = paramflags; + self->paramflags = Py_XNewRef(paramflags); if (iid_len == sizeof(GUID)) self->iid = iid; return (PyObject *)self; @@ -3786,8 +3735,7 @@ PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - Py_INCREF(callable); - self->callable = callable; + self->callable = Py_NewRef(callable); self->thunk = thunk; *(void **)self->b_ptr = (void *)thunk->pcl_exec; @@ -3835,23 +3783,20 @@ _get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObje if (*pindex < PyTuple_GET_SIZE(inargs)) { v = PyTuple_GET_ITEM(inargs, *pindex); ++*pindex; - Py_INCREF(v); - return v; + return Py_NewRef(v); } if (kwds && name) { v = PyDict_GetItemWithError(kwds, name); if (v) { ++*pindex; - Py_INCREF(v); - return v; + return Py_NewRef(v); } else if (PyErr_Occurred()) { return NULL; } } if (defval) { - Py_INCREF(defval); - return defval; + return Py_NewRef(defval); } /* we can't currently emit a better error message */ if (name) @@ -3906,8 +3851,7 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes, if (self->index) return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs)); #endif - Py_INCREF(inargs); - return inargs; + return Py_NewRef(inargs); } len = PyTuple_GET_SIZE(argtypes); @@ -4090,10 +4034,9 @@ _build_result(PyObject *result, PyObject *callargs, PyTuple_SET_ITEM(tup, index, v); index++; } else if (bit & outmask) { - _Py_IDENTIFIER(__ctypes_from_outparam__); v = PyTuple_GET_ITEM(callargs, i); - v = _PyObject_CallMethodIdNoArgs(v, &PyId___ctypes_from_outparam__); + v = PyObject_CallMethodNoArgs(v, &_Py_ID(__ctypes_from_outparam__)); if (v == NULL || numretvals == 1) { Py_DECREF(callargs); return v; @@ -4335,7 +4278,7 @@ PyTypeObject PyCFuncPtr_Type = { 0, /* tp_setattro */ &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "Function Pointer", /* tp_doc */ + PyDoc_STR("Function Pointer"), /* tp_doc */ (traverseproc)PyCFuncPtr_traverse, /* tp_traverse */ (inquiry)PyCFuncPtr_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -4376,7 +4319,6 @@ _init_pos_args(PyObject *self, PyTypeObject *type, StgDictObject *dict; PyObject *fields; Py_ssize_t i; - _Py_IDENTIFIER(_fields_); if (PyType_stgdict((PyObject *)type->tp_base)) { index = _init_pos_args(self, type->tp_base, @@ -4387,7 +4329,7 @@ _init_pos_args(PyObject *self, PyTypeObject *type, } dict = PyType_stgdict((PyObject *)type); - fields = _PyDict_GetItemIdWithError((PyObject *)dict, &PyId__fields_); + fields = PyDict_GetItemWithError((PyObject *)dict, &_Py_ID(_fields_)); if (fields == NULL) { if (PyErr_Occurred()) { return -1; @@ -4487,7 +4429,7 @@ static PyTypeObject Struct_Type = { 0, /* tp_setattro */ &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "Structure base class", /* tp_doc */ + PyDoc_STR("Structure base class"), /* tp_doc */ (traverseproc)PyCData_traverse, /* tp_traverse */ (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -4529,7 +4471,7 @@ static PyTypeObject Union_Type = { 0, /* tp_setattro */ &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "Union base class", /* tp_doc */ + PyDoc_STR("Union base class"), /* tp_doc */ (traverseproc)PyCData_traverse, /* tp_traverse */ (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -4849,7 +4791,7 @@ PyTypeObject PyCArray_Type = { 0, /* tp_setattro */ &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "XXX to be provided", /* tp_doc */ + PyDoc_STR("XXX to be provided"), /* tp_doc */ (traverseproc)PyCData_traverse, /* tp_traverse */ (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -4996,8 +4938,7 @@ static PyObject * Simple_from_outparm(PyObject *self, PyObject *args) { if (_ctypes_simple_instance((PyObject *)Py_TYPE(self))) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } /* call stgdict->getfunc */ return Simple_get_value((CDataObject *)self, NULL); @@ -5068,7 +5009,7 @@ static PyTypeObject Simple_Type = { 0, /* tp_setattro */ &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "XXX to be provided", /* tp_doc */ + PyDoc_STR("XXX to be provided"), /* tp_doc */ (traverseproc)PyCData_traverse, /* tp_traverse */ (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -5450,7 +5391,7 @@ PyTypeObject PyCPointer_Type = { 0, /* tp_setattro */ &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "XXX to be provided", /* tp_doc */ + PyDoc_STR("XXX to be provided"), /* tp_doc */ (traverseproc)PyCData_traverse, /* tp_traverse */ (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -5477,12 +5418,12 @@ PyTypeObject PyCPointer_Type = { * Module initialization. */ -static const char module_docs[] = -"Create and manipulate C compatible data types in Python."; +PyDoc_STRVAR(_ctypes__doc__, +"Create and manipulate C compatible data types in Python."); #ifdef MS_WIN32 -static const char comerror_doc[] = "Raised when a COM method call failed."; +PyDoc_STRVAR(comerror_doc, "Raised when a COM method call failed."); int comerror_init(PyObject *self, PyObject *args, PyObject *kwds) @@ -5631,8 +5572,7 @@ cast(void *ptr, PyObject *src, PyObject *ctype) if (obj->b_objects == NULL) goto failed; } - Py_XINCREF(obj->b_objects); - result->b_objects = obj->b_objects; + result->b_objects = Py_XNewRef(obj->b_objects); if (result->b_objects && PyDict_CheckExact(result->b_objects)) { PyObject *index; int rc; @@ -5671,7 +5611,7 @@ wstring_at(const wchar_t *ptr, int size) static struct PyModuleDef _ctypesmodule = { PyModuleDef_HEAD_INIT, .m_name = "_ctypes", - .m_doc = module_docs, + .m_doc = _ctypes__doc__, .m_size = -1, .m_methods = _ctypes_module_methods, }; @@ -5810,7 +5750,9 @@ _ctypes_add_objects(PyObject *mod) #endif MOD_ADD("RTLD_LOCAL", PyLong_FromLong(RTLD_LOCAL)); MOD_ADD("RTLD_GLOBAL", PyLong_FromLong(RTLD_GLOBAL)); + MOD_ADD("CTYPES_MAX_ARGCOUNT", PyLong_FromLong(CTYPES_MAX_ARGCOUNT)); MOD_ADD("ArgumentError", Py_NewRef(PyExc_ArgError)); + MOD_ADD("SIZEOF_TIME_T", PyLong_FromSsize_t(SIZEOF_TIME_T)); return 0; #undef MOD_ADD } diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index 770c96c60d1..a8811d03cc9 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -1034,6 +1034,25 @@ EXPORT (HRESULT) KeepObject(IUnknown *punk) #endif +#ifdef MS_WIN32 + +// i38748: c stub for testing stack corruption +// When executing a Python callback with a long and a long long + +typedef long(__stdcall *_test_i38748_funcType)(long, long long); + +EXPORT(long) _test_i38748_runCallback(_test_i38748_funcType callback, int a, int b) { + return callback(a, b); +} + +#endif + +EXPORT(int) +_testfunc_pylist_append(PyObject *list, PyObject *item) +{ + return PyList_Append(list, item); +} + static struct PyModuleDef_Slot _ctypes_test_slots[] = { {0, NULL} }; diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index 0f7789a973e..bc8750091f6 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -8,14 +8,24 @@ # include #endif -#include "pycore_call.h" // _PyObject_CallNoArgs() -#include "frameobject.h" +#include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_runtime.h" // _PyRuntime +#include "pycore_global_objects.h" // _Py_ID() #include +#ifdef MS_WIN32 +# include +#endif + #include #include "ctypes.h" +#ifdef HAVE_ALLOCA_H +/* AIX needs alloca.h for alloca() */ +#include +#endif + /**************************************************************/ static void @@ -72,7 +82,7 @@ PyTypeObject PyCThunk_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "CThunkObject", /* tp_doc */ + PyDoc_STR("CThunkObject"), /* tp_doc */ CThunkObject_traverse, /* tp_traverse */ CThunkObject_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -116,9 +126,7 @@ static void TryAddRef(StgDictObject *dict, CDataObject *obj) { IUnknown *punk; - _Py_IDENTIFIER(_needs_com_addref_); - - int r = _PyDict_ContainsId((PyObject *)dict, &PyId__needs_com_addref_); + int r = PyDict_Contains((PyObject *)dict, &_Py_ID(_needs_com_addref_)); if (r <= 0) { if (r < 0) { PrintError("getting _needs_com_addref_"); @@ -146,47 +154,29 @@ static void _CallPythonObject(void *mem, int flags, void **pArgs) { - Py_ssize_t i; - PyObject *result; - PyObject *arglist = NULL; - Py_ssize_t nArgs; + PyObject *result = NULL; + Py_ssize_t i = 0, j = 0, nargs = 0; PyObject *error_object = NULL; int *space; PyGILState_STATE state = PyGILState_Ensure(); - nArgs = PySequence_Length(converters); - /* Hm. What to return in case of error? - For COM, 0xFFFFFFFF seems better than 0. - */ - if (nArgs < 0) { - PrintError("BUG: PySequence_Length"); - goto Done; - } - - arglist = PyTuple_New(nArgs); - if (!arglist) { - PrintError("PyTuple_New()"); - goto Done; - } - for (i = 0; i < nArgs; ++i) { - /* Note: new reference! */ - PyObject *cnv = PySequence_GetItem(converters, i); + assert(PyTuple_Check(converters)); + nargs = PyTuple_GET_SIZE(converters); + assert(nargs <= CTYPES_MAX_ARGCOUNT); + PyObject **args = alloca(nargs * sizeof(PyObject *)); + PyObject **cnvs = PySequence_Fast_ITEMS(converters); + for (i = 0; i < nargs; i++) { + PyObject *cnv = cnvs[i]; // borrowed ref StgDictObject *dict; - if (cnv) - dict = PyType_stgdict(cnv); - else { - PrintError("Getting argument converter %zd\n", i); - goto Done; - } + dict = PyType_stgdict(cnv); if (dict && dict->getfunc && !_ctypes_simple_instance(cnv)) { PyObject *v = dict->getfunc(*pArgs, dict->size); if (!v) { PrintError("create argument %zd:\n", i); - Py_DECREF(cnv); goto Done; } - PyTuple_SET_ITEM(arglist, i, v); + args[i] = v; /* XXX XXX XX We have the problem that c_byte or c_short have dict->size of 1 resp. 4, but these parameters are pushed as sizeof(int) bytes. @@ -197,17 +187,15 @@ static void _CallPythonObject(void *mem, CDataObject *obj = (CDataObject *)_PyObject_CallNoArgs(cnv); if (!obj) { PrintError("create argument %zd:\n", i); - Py_DECREF(cnv); goto Done; } if (!CDataObject_Check(obj)) { Py_DECREF(obj); - Py_DECREF(cnv); PrintError("unexpected result of create argument %zd:\n", i); goto Done; } memcpy(obj->b_ptr, *pArgs, dict->size); - PyTuple_SET_ITEM(arglist, i, (PyObject *)obj); + args[i] = (PyObject *)obj; #ifdef MS_WIN32 TryAddRef(dict, obj); #endif @@ -215,10 +203,8 @@ static void _CallPythonObject(void *mem, PyErr_SetString(PyExc_TypeError, "cannot build parameter"); PrintError("Parsing argument %zd\n", i); - Py_DECREF(cnv); goto Done; } - Py_DECREF(cnv); /* XXX error handling! */ pArgs++; } @@ -241,7 +227,7 @@ static void _CallPythonObject(void *mem, #endif } - result = PyObject_CallObject(callable, arglist); + result = PyObject_Vectorcall(callable, args, nargs, NULL); if (result == NULL) { _PyErr_WriteUnraisableMsg("on calling ctypes callback function", callable); @@ -289,15 +275,14 @@ static void _CallPythonObject(void *mem, "of ctypes callback function", callable); } - else if (keep == Py_None) { - /* Nothing to keep */ - Py_DECREF(keep); - } else if (setfunc != _ctypes_get_fielddesc("O")->setfunc) { - if (-1 == PyErr_WarnEx(PyExc_RuntimeWarning, - "memory leak in callback function.", - 1)) - { + if (keep == Py_None) { + /* Nothing to keep */ + Py_DECREF(keep); + } + else if (PyErr_WarnEx(PyExc_RuntimeWarning, + "memory leak in callback function.", + 1) == -1) { _PyErr_WriteUnraisableMsg("on converting result " "of ctypes callback function", callable); @@ -308,7 +293,9 @@ static void _CallPythonObject(void *mem, Py_XDECREF(result); Done: - Py_XDECREF(arglist); + for (j = 0; j < i; j++) { + Py_DECREF(args[j]); + } PyGILState_Release(state); } @@ -328,12 +315,12 @@ static void closure_fcn(ffi_cif *cif, args); } -static CThunkObject* CThunkObject_new(Py_ssize_t nArgs) +static CThunkObject* CThunkObject_new(Py_ssize_t nargs) { CThunkObject *p; Py_ssize_t i; - p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nArgs); + p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nargs); if (p == NULL) { return NULL; } @@ -348,7 +335,7 @@ static CThunkObject* CThunkObject_new(Py_ssize_t nArgs) p->setfunc = NULL; p->ffi_restype = NULL; - for (i = 0; i < nArgs + 1; ++i) + for (i = 0; i < nargs + 1; ++i) p->atypes[i] = NULL; PyObject_GC_Track((PyObject *)p); return p; @@ -361,11 +348,12 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, { int result; CThunkObject *p; - Py_ssize_t nArgs, i; + Py_ssize_t nargs, i; ffi_abi cc; - nArgs = PySequence_Size(converters); - p = CThunkObject_new(nArgs); + assert(PyTuple_Check(converters)); + nargs = PyTuple_GET_SIZE(converters); + p = CThunkObject_new(nargs); if (p == NULL) return NULL; @@ -378,17 +366,14 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, } p->flags = flags; - for (i = 0; i < nArgs; ++i) { - PyObject *cnv = PySequence_GetItem(converters, i); - if (cnv == NULL) - goto error; + PyObject **cnvs = PySequence_Fast_ITEMS(converters); + for (i = 0; i < nargs; ++i) { + PyObject *cnv = cnvs[i]; // borrowed ref p->atypes[i] = _ctypes_get_ffi_type(cnv); - Py_DECREF(cnv); } p->atypes[i] = NULL; - Py_INCREF(restype); - p->restype = restype; + p->restype = Py_NewRef(restype); if (restype == Py_None) { p->setfunc = NULL; p->ffi_restype = &ffi_type_void; @@ -409,17 +394,23 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, cc = FFI_STDCALL; #endif result = ffi_prep_cif(&p->cif, cc, - Py_SAFE_DOWNCAST(nArgs, Py_ssize_t, int), - _ctypes_get_ffi_type(restype), + Py_SAFE_DOWNCAST(nargs, Py_ssize_t, int), + p->ffi_restype, &p->atypes[0]); if (result != FFI_OK) { PyErr_Format(PyExc_RuntimeError, "ffi_prep_cif failed with %d", result); goto error; } + + #if HAVE_FFI_PREP_CLOSURE_LOC -# if USING_APPLE_OS_LIBFFI +# ifdef USING_APPLE_OS_LIBFFI +# ifdef HAVE_BUILTIN_AVAILABLE # define HAVE_FFI_PREP_CLOSURE_LOC_RUNTIME __builtin_available(macos 10.15, ios 13, watchos 6, tvos 13, *) +# else +# define HAVE_FFI_PREP_CLOSURE_LOC_RUNTIME (ffi_prep_closure_loc != NULL) +# endif # else # define HAVE_FFI_PREP_CLOSURE_LOC_RUNTIME 1 # endif @@ -430,11 +421,11 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, } else #endif { -#if USING_APPLE_OS_LIBFFI && defined(__arm64__) +#if defined(USING_APPLE_OS_LIBFFI) && defined(__arm64__) PyErr_Format(PyExc_NotImplementedError, "ffi_prep_closure_loc() is missing"); goto error; #else -#if defined(__clang__) || defined(MACOSX) +#if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" #endif @@ -444,7 +435,7 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, #endif result = ffi_prep_closure(p->pcl_write, &p->cif, closure_fcn, p); -#if defined(__clang__) || defined(MACOSX) +#if defined(__clang__) #pragma clang diagnostic pop #endif #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))) @@ -459,10 +450,8 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, goto error; } - Py_INCREF(converters); - p->converters = converters; - Py_INCREF(callable); - p->callable = callable; + p->converters = Py_NewRef(converters); + p->callable = Py_NewRef(callable); return p; error: @@ -483,24 +472,17 @@ static void LoadPython(void) long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { - PyObject *mod, *func, *result; + PyObject *func, *result; long retval; static PyObject *context; if (context == NULL) context = PyUnicode_InternFromString("_ctypes.DllGetClassObject"); - mod = PyImport_ImportModuleNoBlock("ctypes"); - if (!mod) { - PyErr_WriteUnraisable(context ? context : Py_None); - /* There has been a warning before about this already */ - return E_FAIL; - } - - func = PyObject_GetAttrString(mod, "DllGetClassObject"); - Py_DECREF(mod); + func = _PyImport_GetModuleAttrString("ctypes", "DllGetClassObject"); if (!func) { PyErr_WriteUnraisable(context ? context : Py_None); + /* There has been a warning before about this already */ return E_FAIL; } @@ -563,7 +545,7 @@ long Call_CanUnloadNow(void) if (context == NULL) context = PyUnicode_InternFromString("_ctypes.DllCanUnloadNow"); - mod = PyImport_ImportModuleNoBlock("ctypes"); + mod = PyImport_ImportModule("ctypes"); if (!mod) { /* OutputDebugString("Could not import ctypes"); */ /* We assume that this error can only occur when shutting diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index e2204961070..f6d98bbeebc 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -54,6 +54,10 @@ */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" #include "structmember.h" // PyMemberDef @@ -63,7 +67,7 @@ #include #include #else -#include "ctypes_dlfcn.h" +#include #endif #ifdef __APPLE__ @@ -92,8 +96,12 @@ #define DONT_USE_SEH #endif +#include "pycore_runtime.h" // _PyRuntime +#include "pycore_global_objects.h" // _Py_ID() + #define CTYPES_CAPSULE_NAME_PYMEM "_ctypes pymem" + static void pymem_destructor(PyObject *ptr) { void *p = PyCapsule_GetPointer(ptr, CTYPES_CAPSULE_NAME_PYMEM); @@ -278,7 +286,7 @@ static WCHAR *FormatError(DWORD code) #ifndef DONT_USE_SEH static void SetException(DWORD code, EXCEPTION_RECORD *pr) { - if (PySys_Audit("ctypes.seh_exception", "I", code) < 0) { + if (PySys_Audit("ctypes.set_exception", "I", code) < 0) { /* An exception was set by the audit hook */ return; } @@ -664,8 +672,7 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa) if (PyCArg_CheckExact(obj)) { PyCArgObject *carg = (PyCArgObject *)obj; pa->ffi_type = carg->pffi_type; - Py_INCREF(obj); - pa->keep = obj; + pa->keep = Py_NewRef(obj); memcpy(&pa->value, &carg->value, sizeof(pa->value)); return 0; } @@ -695,8 +702,7 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa) if (PyBytes_Check(obj)) { pa->ffi_type = &ffi_type_pointer; pa->value.p = PyBytes_AsString(obj); - Py_INCREF(obj); - pa->keep = obj; + pa->keep = Py_NewRef(obj); return 0; } @@ -714,9 +720,8 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa) } { - _Py_IDENTIFIER(_as_parameter_); PyObject *arg; - if (_PyObject_LookupAttrId(obj, &PyId__as_parameter_, &arg) < 0) { + if (_PyObject_LookupAttr(obj, &_Py_ID(_as_parameter_), &arg) < 0) { return -1; } /* Which types should we exactly allow here? @@ -826,8 +831,12 @@ static int _call_function_pointer(int flags, cc = FFI_STDCALL; #endif -# if USING_APPLE_OS_LIBFFI +# ifdef USING_APPLE_OS_LIBFFI +# ifdef HAVE_BUILTIN_AVAILABLE # define HAVE_FFI_PREP_CIF_VAR_RUNTIME __builtin_available(macos 10.15, ios 13, watchos 6, tvos 13, *) +# else +# define HAVE_FFI_PREP_CIF_VAR_RUNTIME (ffi_prep_cif_var != NULL) +# endif # elif HAVE_FFI_PREP_CIF_VAR # define HAVE_FFI_PREP_CIF_VAR_RUNTIME true # else @@ -1014,7 +1023,10 @@ void _ctypes_extend_error(PyObject *exc_class, const char *fmt, ...) PyErr_Fetch(&tp, &v, &tb); PyErr_NormalizeException(&tp, &v, &tb); - cls_str = PyObject_Str(tp); + if (PyType_Check(tp)) + cls_str = PyType_GetName((PyTypeObject *)tp); + else + cls_str = PyObject_Str(tp); if (cls_str) { PyUnicode_AppendAndDel(&s, cls_str); PyUnicode_AppendAndDel(&s, PyUnicode_FromString(": ")); @@ -1118,14 +1130,6 @@ GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk) #define IS_PASS_BY_REF(x) (x > 8 || !POW2(x)) #endif -/* - * bpo-13097: Max number of arguments _ctypes_callproc will accept. - * - * This limit is enforced for the `alloca()` call in `_ctypes_callproc`, - * to avoid allocating a massive buffer on the stack. - */ -#define CTYPES_MAX_ARGCOUNT 1024 - /* * Requirements, must be ensured by the caller: * - argtuple is tuple of arguments @@ -1168,11 +1172,7 @@ PyObject *_ctypes_callproc(PPROC pProc, return NULL; } - args = (struct argument *)alloca(sizeof(struct argument) * argcount); - if (!args) { - PyErr_NoMemory(); - return NULL; - } + args = alloca(sizeof(struct argument) * argcount); memset(args, 0, sizeof(struct argument) * argcount); argtype_count = argtypes ? PyTuple_GET_SIZE(argtypes) : 0; #ifdef MS_WIN32 @@ -1219,7 +1219,12 @@ PyObject *_ctypes_callproc(PPROC pProc, } } - rtype = _ctypes_get_ffi_type(restype); + if (restype == Py_None) { + rtype = &ffi_type_void; + } else { + rtype = _ctypes_get_ffi_type(restype); + } + resbuf = alloca(max(rtype->size, sizeof(ffi_arg))); #ifdef _Py_MEMORY_SANITIZER @@ -1312,11 +1317,11 @@ _parse_voidp(PyObject *obj, void **address) #ifdef MS_WIN32 -static const char format_error_doc[] = +PyDoc_STRVAR(format_error_doc, "FormatError([integer]) -> string\n\ \n\ Convert a win32 error code into a string. If the error code is not\n\ -given, the return value of a call to GetLastError() is used.\n"; +given, the return value of a call to GetLastError() is used.\n"); static PyObject *format_error(PyObject *self, PyObject *args) { PyObject *result; @@ -1336,13 +1341,13 @@ static PyObject *format_error(PyObject *self, PyObject *args) return result; } -static const char load_library_doc[] = +PyDoc_STRVAR(load_library_doc, "LoadLibrary(name, load_flags) -> handle\n\ \n\ Load an executable (usually a DLL), and return a handle to it.\n\ The handle may be used to locate exported functions in this\n\ module. load_flags are as defined for LoadLibraryEx in the\n\ -Windows API.\n"; +Windows API.\n"); static PyObject *load_library(PyObject *self, PyObject *args) { PyObject *nameobj; @@ -1387,10 +1392,10 @@ static PyObject *load_library(PyObject *self, PyObject *args) #endif } -static const char free_library_doc[] = +PyDoc_STRVAR(free_library_doc, "FreeLibrary(handle) -> void\n\ \n\ -Free the handle of an executable previously loaded by LoadLibrary.\n"; +Free the handle of an executable previously loaded by LoadLibrary.\n"); static PyObject *free_library(PyObject *self, PyObject *args) { void *hMod; @@ -1410,8 +1415,8 @@ static PyObject *free_library(PyObject *self, PyObject *args) Py_RETURN_NONE; } -static const char copy_com_pointer_doc[] = -"CopyComPointer(src, dst) -> HRESULT value\n"; +PyDoc_STRVAR(copy_com_pointer_doc, +"CopyComPointer(src, dst) -> HRESULT value\n"); static PyObject * copy_com_pointer(PyObject *self, PyObject *args) @@ -1444,8 +1449,13 @@ copy_com_pointer(PyObject *self, PyObject *args) #else #ifdef __APPLE__ #ifdef HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH -#define HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH_RUNTIME \ - __builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *) +# ifdef HAVE_BUILTIN_AVAILABLE +# define HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH_RUNTIME \ + __builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *) +# else +# define HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH_RUNTIME \ + (_dyld_shared_cache_contains_path != NULL) +# endif #else // Support the deprecated case of compiling on an older macOS version static void *libsystem_b_handle; @@ -1527,10 +1537,10 @@ static PyObject *py_dl_open(PyObject *self, PyObject *args) if (PySys_Audit("ctypes.dlopen", "O", name) < 0) { return NULL; } - handle = ctypes_dlopen(name_str, mode); + handle = dlopen(name_str, mode); Py_XDECREF(name2); if (!handle) { - const char *errmsg = ctypes_dlerror(); + const char *errmsg = dlerror(); if (!errmsg) errmsg = "dlopen() error"; PyErr_SetString(PyExc_OSError, @@ -1548,7 +1558,7 @@ static PyObject *py_dl_close(PyObject *self, PyObject *args) return NULL; if (dlclose(handle)) { PyErr_SetString(PyExc_OSError, - ctypes_dlerror()); + dlerror()); return NULL; } Py_RETURN_NONE; @@ -1566,10 +1576,10 @@ static PyObject *py_dl_sym(PyObject *self, PyObject *args) if (PySys_Audit("ctypes.dlsym/handle", "O", args) < 0) { return NULL; } - ptr = ctypes_dlsym((void*)handle, name); + ptr = dlsym((void*)handle, name); if (!ptr) { PyErr_SetString(PyExc_OSError, - ctypes_dlerror()); + dlerror()); return NULL; } return PyLong_FromVoidPtr(ptr); @@ -1649,10 +1659,10 @@ call_cdeclfunction(PyObject *self, PyObject *args) /***************************************************************** * functions */ -static const char sizeof_doc[] = +PyDoc_STRVAR(sizeof_doc, "sizeof(C type) -> integer\n" "sizeof(C instance) -> integer\n" -"Return the size in bytes of a C instance"; +"Return the size in bytes of a C instance"); static PyObject * sizeof_func(PyObject *self, PyObject *obj) @@ -1670,10 +1680,10 @@ sizeof_func(PyObject *self, PyObject *obj) return NULL; } -static const char alignment_doc[] = +PyDoc_STRVAR(alignment_doc, "alignment(C type) -> integer\n" "alignment(C instance) -> integer\n" -"Return the alignment requirements of a C instance"; +"Return the alignment requirements of a C instance"); static PyObject * align_func(PyObject *self, PyObject *obj) @@ -1693,10 +1703,10 @@ align_func(PyObject *self, PyObject *obj) return NULL; } -static const char byref_doc[] = +PyDoc_STRVAR(byref_doc, "byref(C instance[, offset=0]) -> byref-object\n" "Return a pointer lookalike to a C instance, only usable\n" -"as function argument"; +"as function argument"); /* * We must return something which can be converted to a parameter, @@ -1731,15 +1741,14 @@ byref(PyObject *self, PyObject *args) parg->tag = 'P'; parg->pffi_type = &ffi_type_pointer; - Py_INCREF(obj); - parg->obj = obj; + parg->obj = Py_NewRef(obj); parg->value.p = (char *)((CDataObject *)obj)->b_ptr + offset; return (PyObject *)parg; } -static const char addressof_doc[] = +PyDoc_STRVAR(addressof_doc, "addressof(C instance) -> integer\n" -"Return the address of the C instance internal buffer"; +"Return the address of the C instance internal buffer"); static PyObject * addressof(PyObject *self, PyObject *obj) @@ -1772,8 +1781,7 @@ My_PyObj_FromPtr(PyObject *self, PyObject *args) if (PySys_Audit("ctypes.PyObj_FromPtr", "(O)", ob) < 0) { return NULL; } - Py_INCREF(ob); - return ob; + return Py_NewRef(ob); } static PyObject * @@ -1850,16 +1858,14 @@ static PyObject * unpickle(PyObject *self, PyObject *args) { PyObject *typ, *state, *meth, *obj, *result; - _Py_IDENTIFIER(__new__); - _Py_IDENTIFIER(__setstate__); if (!PyArg_ParseTuple(args, "OO!", &typ, &PyTuple_Type, &state)) return NULL; - obj = _PyObject_CallMethodIdOneArg(typ, &PyId___new__, typ); + obj = PyObject_CallMethodOneArg(typ, &_Py_ID(__new__), typ); if (obj == NULL) return NULL; - meth = _PyObject_GetAttrId(obj, &PyId___setstate__); + meth = PyObject_GetAttr(obj, &_Py_ID(__setstate__)); if (meth == NULL) { goto error; } @@ -1884,29 +1890,20 @@ POINTER(PyObject *self, PyObject *cls) PyObject *result; PyTypeObject *typ; PyObject *key; - char *buf; result = PyDict_GetItemWithError(_ctypes_ptrtype_cache, cls); if (result) { - Py_INCREF(result); - return result; + return Py_NewRef(result); } else if (PyErr_Occurred()) { return NULL; } if (PyUnicode_CheckExact(cls)) { - const char *name = PyUnicode_AsUTF8(cls); - if (name == NULL) - return NULL; - buf = PyMem_Malloc(strlen(name) + 3 + 1); - if (buf == NULL) - return PyErr_NoMemory(); - sprintf(buf, "LP_%s", name); + PyObject *name = PyUnicode_FromFormat("LP_%U", cls); result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), - "s(O){}", - buf, + "N(O){}", + name, &PyCPointer_Type); - PyMem_Free(buf); if (result == NULL) return result; key = PyLong_FromVoidPtr(result); @@ -1916,20 +1913,15 @@ POINTER(PyObject *self, PyObject *cls) } } else if (PyType_Check(cls)) { typ = (PyTypeObject *)cls; - buf = PyMem_Malloc(strlen(typ->tp_name) + 3 + 1); - if (buf == NULL) - return PyErr_NoMemory(); - sprintf(buf, "LP_%s", typ->tp_name); + PyObject *name = PyUnicode_FromFormat("LP_%s", typ->tp_name); result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), - "s(O){sO}", - buf, + "N(O){sO}", + name, &PyCPointer_Type, "_type_", cls); - PyMem_Free(buf); if (result == NULL) return result; - Py_INCREF(cls); - key = cls; + key = Py_NewRef(cls); } else { PyErr_SetString(PyExc_TypeError, "must be a ctypes type"); return NULL; diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 515b2801820..796a1bec966 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -10,7 +10,6 @@ #include "pycore_bitutils.h" // _Py_bswap32() #include "pycore_call.h" // _PyObject_CallNoArgs() -#include "pycore_floatobject.h" // _PyFloat_Pack8() #include #include "ctypes.h" @@ -31,13 +30,6 @@ static void pymem_destructor(PyObject *ptr) /* PyCField_Type */ -static PyObject * -PyCField_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - CFieldObject *obj; - obj = (CFieldObject *)type->tp_alloc(type, 0); - return (PyObject *)obj; -} /* * Expects the size, index and offset for the current field in *psize and @@ -69,7 +61,7 @@ PyCField_FromDesc(PyObject *desc, Py_ssize_t index, #define CONT_BITFIELD 2 #define EXPAND_BITFIELD 3 - self = (CFieldObject *)_PyObject_CallNoArgs((PyObject *)&PyCField_Type); + self = (CFieldObject *)PyCField_Type.tp_alloc((PyTypeObject *)&PyCField_Type, 0); if (self == NULL) return NULL; dict = PyType_stgdict(desc); @@ -145,8 +137,7 @@ PyCField_FromDesc(PyObject *desc, Py_ssize_t index, self->getfunc = getfunc; self->index = index; - Py_INCREF(proto); - self->proto = proto; + self->proto = Py_NewRef(proto); switch (fieldtype) { case NEW_BITFIELD: @@ -232,8 +223,7 @@ PyCField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type) { CDataObject *src; if (inst == NULL) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } if (!CDataObject_Check(inst)) { PyErr_SetString(PyExc_TypeError, @@ -280,6 +270,7 @@ PyCField_clear(CFieldObject *self) static void PyCField_dealloc(PyObject *self) { + PyObject_GC_UnTrack(self); PyCField_clear((CFieldObject *)self); Py_TYPE(self)->tp_free((PyObject *)self); } @@ -326,7 +317,7 @@ PyTypeObject PyCField_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "Structure/Union member", /* tp_doc */ + PyDoc_STR("Structure/Union member"), /* tp_doc */ (traverseproc)PyCField_traverse, /* tp_traverse */ (inquiry)PyCField_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -343,7 +334,7 @@ PyTypeObject PyCField_Type = { 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - PyCField_new, /* tp_new */ + 0, /* tp_new */ 0, /* tp_free */ }; @@ -1009,10 +1000,10 @@ d_set_sw(void *ptr, PyObject *value, Py_ssize_t size) if (x == -1 && PyErr_Occurred()) return NULL; #ifdef WORDS_BIGENDIAN - if (_PyFloat_Pack8(x, (unsigned char *)ptr, 1)) + if (PyFloat_Pack8(x, ptr, 1)) return NULL; #else - if (_PyFloat_Pack8(x, (unsigned char *)ptr, 0)) + if (PyFloat_Pack8(x, ptr, 0)) return NULL; #endif _RET(value); @@ -1022,9 +1013,9 @@ static PyObject * d_get_sw(void *ptr, Py_ssize_t size) { #ifdef WORDS_BIGENDIAN - return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 1)); + return PyFloat_FromDouble(PyFloat_Unpack8(ptr, 1)); #else - return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 0)); + return PyFloat_FromDouble(PyFloat_Unpack8(ptr, 0)); #endif } @@ -1057,10 +1048,10 @@ f_set_sw(void *ptr, PyObject *value, Py_ssize_t size) if (x == -1 && PyErr_Occurred()) return NULL; #ifdef WORDS_BIGENDIAN - if (_PyFloat_Pack4(x, (unsigned char *)ptr, 1)) + if (PyFloat_Pack4(x, ptr, 1)) return NULL; #else - if (_PyFloat_Pack4(x, (unsigned char *)ptr, 0)) + if (PyFloat_Pack4(x, ptr, 0)) return NULL; #endif _RET(value); @@ -1070,9 +1061,9 @@ static PyObject * f_get_sw(void *ptr, Py_ssize_t size) { #ifdef WORDS_BIGENDIAN - return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 1)); + return PyFloat_FromDouble(PyFloat_Unpack4(ptr, 1)); #else - return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 0)); + return PyFloat_FromDouble(PyFloat_Unpack4(ptr, 0)); #endif } @@ -1097,8 +1088,7 @@ O_get(void *ptr, Py_ssize_t size) "PyObject is NULL"); return NULL; } - Py_INCREF(ob); - return ob; + return Py_NewRef(ob); } static PyObject * @@ -1106,8 +1096,7 @@ O_set(void *ptr, PyObject *value, Py_ssize_t size) { /* Hm, does the memory block need it's own refcount or not? */ *(PyObject **)ptr = value; - Py_INCREF(value); - return value; + return Py_NewRef(value); } @@ -1233,8 +1222,7 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length) return NULL; } - Py_INCREF(value); - return value; + return Py_NewRef(value); } @@ -1292,13 +1280,11 @@ z_set(void *ptr, PyObject *value, Py_ssize_t size) { if (value == Py_None) { *(char **)ptr = NULL; - Py_INCREF(value); - return value; + return Py_NewRef(value); } if (PyBytes_Check(value)) { *(const char **)ptr = PyBytes_AsString(value); - Py_INCREF(value); - return value; + return Py_NewRef(value); } else if (PyLong_Check(value)) { #if SIZEOF_VOID_P == SIZEOF_LONG_LONG *(char **)ptr = (char *)PyLong_AsUnsignedLongLongMask(value); @@ -1334,8 +1320,7 @@ Z_set(void *ptr, PyObject *value, Py_ssize_t size) if (value == Py_None) { *(wchar_t **)ptr = NULL; - Py_INCREF(value); - return value; + return Py_NewRef(value); } if (PyLong_Check(value)) { #if SIZEOF_VOID_P == SIZEOF_LONG_LONG @@ -1481,55 +1466,40 @@ P_get(void *ptr, Py_ssize_t size) } static struct fielddesc formattable[] = { - { 's', s_set, s_get, &ffi_type_pointer}, - { 'b', b_set, b_get, &ffi_type_schar}, - { 'B', B_set, B_get, &ffi_type_uchar}, - { 'c', c_set, c_get, &ffi_type_schar}, - { 'd', d_set, d_get, &ffi_type_double, d_set_sw, d_get_sw}, - { 'g', g_set, g_get, &ffi_type_longdouble}, - { 'f', f_set, f_get, &ffi_type_float, f_set_sw, f_get_sw}, - { 'h', h_set, h_get, &ffi_type_sshort, h_set_sw, h_get_sw}, - { 'H', H_set, H_get, &ffi_type_ushort, H_set_sw, H_get_sw}, - { 'i', i_set, i_get, &ffi_type_sint, i_set_sw, i_get_sw}, - { 'I', I_set, I_get, &ffi_type_uint, I_set_sw, I_get_sw}, -/* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */ -/* As soon as we can get rid of the type codes, this is no longer a problem */ -#if SIZEOF_LONG == 4 - { 'l', l_set, l_get, &ffi_type_sint32, l_set_sw, l_get_sw}, - { 'L', L_set, L_get, &ffi_type_uint32, L_set_sw, L_get_sw}, -#elif SIZEOF_LONG == 8 - { 'l', l_set, l_get, &ffi_type_sint64, l_set_sw, l_get_sw}, - { 'L', L_set, L_get, &ffi_type_uint64, L_set_sw, L_get_sw}, -#else -# error -#endif -#if SIZEOF_LONG_LONG == 8 - { 'q', q_set, q_get, &ffi_type_sint64, q_set_sw, q_get_sw}, - { 'Q', Q_set, Q_get, &ffi_type_uint64, Q_set_sw, Q_get_sw}, -#else -# error -#endif - { 'P', P_set, P_get, &ffi_type_pointer}, - { 'z', z_set, z_get, &ffi_type_pointer}, - { 'u', u_set, u_get, NULL}, /* ffi_type set later */ - { 'U', U_set, U_get, &ffi_type_pointer}, - { 'Z', Z_set, Z_get, &ffi_type_pointer}, + { 's', s_set, s_get, NULL}, + { 'b', b_set, b_get, NULL}, + { 'B', B_set, B_get, NULL}, + { 'c', c_set, c_get, NULL}, + { 'd', d_set, d_get, NULL, d_set_sw, d_get_sw}, + { 'g', g_set, g_get, NULL}, + { 'f', f_set, f_get, NULL, f_set_sw, f_get_sw}, + { 'h', h_set, h_get, NULL, h_set_sw, h_get_sw}, + { 'H', H_set, H_get, NULL, H_set_sw, H_get_sw}, + { 'i', i_set, i_get, NULL, i_set_sw, i_get_sw}, + { 'I', I_set, I_get, NULL, I_set_sw, I_get_sw}, + { 'l', l_set, l_get, NULL, l_set_sw, l_get_sw}, + { 'L', L_set, L_get, NULL, L_set_sw, L_get_sw}, + { 'q', q_set, q_get, NULL, q_set_sw, q_get_sw}, + { 'Q', Q_set, Q_get, NULL, Q_set_sw, Q_get_sw}, + { 'P', P_set, P_get, NULL}, + { 'z', z_set, z_get, NULL}, + { 'u', u_set, u_get, NULL}, + { 'U', U_set, U_get, NULL}, + { 'Z', Z_set, Z_get, NULL}, #ifdef MS_WIN32 - { 'X', BSTR_set, BSTR_get, &ffi_type_pointer}, + { 'X', BSTR_set, BSTR_get, NULL}, #endif - { 'v', vBOOL_set, vBOOL_get, &ffi_type_sshort}, -#if SIZEOF__BOOL == 1 - { '?', bool_set, bool_get, &ffi_type_uchar}, /* Also fallback for no native _Bool support */ -#elif SIZEOF__BOOL == SIZEOF_SHORT - { '?', bool_set, bool_get, &ffi_type_ushort}, -#elif SIZEOF__BOOL == SIZEOF_INT - { '?', bool_set, bool_get, &ffi_type_uint, I_set_sw, I_get_sw}, + { 'v', vBOOL_set, vBOOL_get, NULL}, +#if SIZEOF__BOOL == SIZEOF_INT + { '?', bool_set, bool_get, NULL, I_set_sw, I_get_sw}, #elif SIZEOF__BOOL == SIZEOF_LONG - { '?', bool_set, bool_get, &ffi_type_ulong, L_set_sw, L_get_sw}, + { '?', bool_set, bool_get, NULL, L_set_sw, L_get_sw}, #elif SIZEOF__BOOL == SIZEOF_LONG_LONG - { '?', bool_set, bool_get, &ffi_type_ulong, Q_set_sw, Q_get_sw}, + { '?', bool_set, bool_get, NULL, Q_set_sw, Q_get_sw}, +#else + { '?', bool_set, bool_get, NULL}, #endif /* SIZEOF__BOOL */ - { 'O', O_set, O_get, &ffi_type_pointer}, + { 'O', O_set, O_get, NULL}, { 0, NULL, NULL, NULL}, }; @@ -1538,6 +1508,79 @@ static struct fielddesc formattable[] = { Use '?' as code for BOOL. */ +/* Delayed initialization. Windows cannot statically reference dynamically + loaded addresses from DLLs. */ +void +_ctypes_init_fielddesc(void) +{ + struct fielddesc *fd = formattable; + for (; fd->code; ++fd) { + switch (fd->code) { + case 's': fd->pffi_type = &ffi_type_pointer; break; + case 'b': fd->pffi_type = &ffi_type_schar; break; + case 'B': fd->pffi_type = &ffi_type_uchar; break; + case 'c': fd->pffi_type = &ffi_type_schar; break; + case 'd': fd->pffi_type = &ffi_type_double; break; + case 'g': fd->pffi_type = &ffi_type_longdouble; break; + case 'f': fd->pffi_type = &ffi_type_float; break; + case 'h': fd->pffi_type = &ffi_type_sshort; break; + case 'H': fd->pffi_type = &ffi_type_ushort; break; + case 'i': fd->pffi_type = &ffi_type_sint; break; + case 'I': fd->pffi_type = &ffi_type_uint; break; + /* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */ + /* As soon as we can get rid of the type codes, this is no longer a problem */ + #if SIZEOF_LONG == 4 + case 'l': fd->pffi_type = &ffi_type_sint32; break; + case 'L': fd->pffi_type = &ffi_type_uint32; break; + #elif SIZEOF_LONG == 8 + case 'l': fd->pffi_type = &ffi_type_sint64; break; + case 'L': fd->pffi_type = &ffi_type_uint64; break; + #else + #error + #endif + #if SIZEOF_LONG_LONG == 8 + case 'q': fd->pffi_type = &ffi_type_sint64; break; + case 'Q': fd->pffi_type = &ffi_type_uint64; break; + #else + #error + #endif + case 'P': fd->pffi_type = &ffi_type_pointer; break; + case 'z': fd->pffi_type = &ffi_type_pointer; break; + case 'u': + if (sizeof(wchar_t) == sizeof(short)) + fd->pffi_type = &ffi_type_sshort; + else if (sizeof(wchar_t) == sizeof(int)) + fd->pffi_type = &ffi_type_sint; + else if (sizeof(wchar_t) == sizeof(long)) + fd->pffi_type = &ffi_type_slong; + else + Py_UNREACHABLE(); + break; + case 'U': fd->pffi_type = &ffi_type_pointer; break; + case 'Z': fd->pffi_type = &ffi_type_pointer; break; + #ifdef MS_WIN32 + case 'X': fd->pffi_type = &ffi_type_pointer; break; + #endif + case 'v': fd->pffi_type = &ffi_type_sshort; break; + #if SIZEOF__BOOL == 1 + case '?': fd->pffi_type = &ffi_type_uchar; break; /* Also fallback for no native _Bool support */ + #elif SIZEOF__BOOL == SIZEOF_SHORT + case '?': fd->pffi_type = &ffi_type_ushort; break; + #elif SIZEOF__BOOL == SIZEOF_INT + case '?': fd->pffi_type = &ffi_type_uint; break; + #elif SIZEOF__BOOL == SIZEOF_LONG + case '?': fd->pffi_type = &ffi_type_ulong; break; + #elif SIZEOF__BOOL == SIZEOF_LONG_LONG + case '?': fd->pffi_type = &ffi_type_ulong; break; + #endif /* SIZEOF__BOOL */ + case 'O': fd->pffi_type = &ffi_type_pointer; break; + default: + Py_UNREACHABLE(); + } + } + +} + struct fielddesc * _ctypes_get_fielddesc(const char *fmt) { @@ -1546,12 +1589,7 @@ _ctypes_get_fielddesc(const char *fmt) if (!initialized) { initialized = 1; - if (sizeof(wchar_t) == sizeof(short)) - _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sshort; - else if (sizeof(wchar_t) == sizeof(int)) - _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sint; - else if (sizeof(wchar_t) == sizeof(long)) - _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_slong; + _ctypes_init_fielddesc(); } for (; table->code; ++table) { @@ -1561,77 +1599,4 @@ _ctypes_get_fielddesc(const char *fmt) return NULL; } -typedef struct { char c; char x; } s_char; -typedef struct { char c; short x; } s_short; -typedef struct { char c; int x; } s_int; -typedef struct { char c; long x; } s_long; -typedef struct { char c; float x; } s_float; -typedef struct { char c; double x; } s_double; -typedef struct { char c; long double x; } s_long_double; -typedef struct { char c; char *x; } s_char_p; -typedef struct { char c; void *x; } s_void_p; - -/* -#define CHAR_ALIGN (sizeof(s_char) - sizeof(char)) -#define SHORT_ALIGN (sizeof(s_short) - sizeof(short)) -#define LONG_ALIGN (sizeof(s_long) - sizeof(long)) -*/ -#define INT_ALIGN (sizeof(s_int) - sizeof(int)) -#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float)) -#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double)) -#define LONGDOUBLE_ALIGN (sizeof(s_long_double) - sizeof(long double)) - -/* #define CHAR_P_ALIGN (sizeof(s_char_p) - sizeof(char*)) */ -#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void*)) - -/* -#ifdef HAVE_USABLE_WCHAR_T -typedef struct { char c; wchar_t x; } s_wchar; -typedef struct { char c; wchar_t *x; } s_wchar_p; - -#define WCHAR_ALIGN (sizeof(s_wchar) - sizeof(wchar_t)) -#define WCHAR_P_ALIGN (sizeof(s_wchar_p) - sizeof(wchar_t*)) -#endif -*/ - -typedef struct { char c; long long x; } s_long_long; -#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long)) - -/* from ffi.h: -typedef struct _ffi_type -{ - size_t size; - unsigned short alignment; - unsigned short type; - struct _ffi_type **elements; -} ffi_type; -*/ - -/* align and size are bogus for void, but they must not be zero */ -ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID }; - -ffi_type ffi_type_uint8 = { 1, 1, FFI_TYPE_UINT8 }; -ffi_type ffi_type_sint8 = { 1, 1, FFI_TYPE_SINT8 }; - -ffi_type ffi_type_uint16 = { 2, 2, FFI_TYPE_UINT16 }; -ffi_type ffi_type_sint16 = { 2, 2, FFI_TYPE_SINT16 }; - -ffi_type ffi_type_uint32 = { 4, INT_ALIGN, FFI_TYPE_UINT32 }; -ffi_type ffi_type_sint32 = { 4, INT_ALIGN, FFI_TYPE_SINT32 }; - -ffi_type ffi_type_uint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_UINT64 }; -ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 }; - -ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT }; -ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE }; - -#ifdef ffi_type_longdouble -#undef ffi_type_longdouble -#endif - /* This is already defined on OSX */ -ffi_type ffi_type_longdouble = { sizeof(long double), LONGDOUBLE_ALIGN, - FFI_TYPE_LONGDOUBLE }; - -ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER }; - /*---------------- EOF ----------------*/ diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index 9600ddc7413..a7029b6e6da 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -11,6 +11,27 @@ #define PARAMFLAG_FLCID 0x4 #endif +/* + * bpo-13097: Max number of arguments CFuncPtr._argtypes_ and + * _ctypes_callproc() will accept. + * + * This limit is enforced for the `alloca()` call in `_ctypes_callproc`, + * to avoid allocating a massive buffer on the stack. + */ +#ifndef CTYPES_MAX_ARGCOUNT + #ifdef __EMSCRIPTEN__ + #define CTYPES_MAX_ARGCOUNT 1000 + #else + #define CTYPES_MAX_ARGCOUNT 1024 + #endif +#endif + +#if defined(__has_builtin) +#if __has_builtin(__builtin_available) +#define HAVE_BUILTIN_AVAILABLE 1 +#endif +#endif + typedef struct tagPyCArgObject PyCArgObject; typedef struct tagCDataObject CDataObject; typedef PyObject *(* GETFUNC)(void *, Py_ssize_t size); @@ -362,7 +383,7 @@ PyObject *_ctypes_get_errobj(int **pspace); extern PyObject *ComError; #endif -#if USING_MALLOC_CLOSURE_DOT_C +#ifdef USING_MALLOC_CLOSURE_DOT_C void Py_ffi_closure_free(void *p); void *Py_ffi_closure_alloc(size_t size, void** codeloc); #else diff --git a/Modules/_ctypes/ctypes_dlfcn.h b/Modules/_ctypes/ctypes_dlfcn.h deleted file mode 100644 index 54cdde9a4fd..00000000000 --- a/Modules/_ctypes/ctypes_dlfcn.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _CTYPES_DLFCN_H_ -#define _CTYPES_DLFCN_H_ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef MS_WIN32 - -#include - -#ifndef CTYPES_DARWIN_DLFCN - -#define ctypes_dlsym dlsym -#define ctypes_dlerror dlerror -#define ctypes_dlopen dlopen -#define ctypes_dlclose dlclose -#define ctypes_dladdr dladdr - -#endif /* !CTYPES_DARWIN_DLFCN */ - -#endif /* !MS_WIN32 */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _CTYPES_DLFCN_H_ */ diff --git a/Modules/_ctypes/darwin/LICENSE b/Modules/_ctypes/darwin/LICENSE deleted file mode 100644 index 786fb50258e..00000000000 --- a/Modules/_ctypes/darwin/LICENSE +++ /dev/null @@ -1,31 +0,0 @@ -Copyright (c) 2002 Jorge Acereda & - Peter O'Gorman - -Portions may be copyright others, see the AUTHORS file included with this -distribution. - -Maintained by Peter O'Gorman - -Bug Reports and other queries should go to - - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - diff --git a/Modules/_ctypes/darwin/README b/Modules/_ctypes/darwin/README deleted file mode 100644 index 4d63f3dfa5e..00000000000 --- a/Modules/_ctypes/darwin/README +++ /dev/null @@ -1,95 +0,0 @@ -dlcompat for Darwin -========================= - -This is dlcompat, a small library that emulates the dlopen() -interface on top of Darwin's dyld API. - -dlcompat allows loading a ".dylib" library (as long as the RTLD_LOCAL -flag isn't passed to dlopen()). It can be configured to yield a warning -when trying to close it (dynamic libraries cannot currently be unloaded). - -It automatically searches for modules in several directories when no -absolute path is specified and the module is not found in the current -directory. - -The paths searched are those specified in the environment variables -LD_LIBRARY_PATH and DYLD_LIBRARY_PATH plus /lib, /usr/local/lib and -/usr/lib or the path specified in the environment variable -DYLD_FALLBACK_LIBRARY_PATH. - -In the default install the behavior of dlsym is to automatically prepend -an underscore to passed in symbol names, this allows easier porting of -applications which were written specifically for ELF based lifeforms. - -Installation --------------- -Type: - ./configure - make - sudo make install - -This will compile the source file, generate both a static and shared -library called libdl and install it into /usr/local/lib. The header -file dlfcn.h will be installed in /usr/local/include. - -If you want to place the files somewhere else, run - - make clean - ./configure --prefix= - make - sudo make install - -where is the hierarchy you want to install into, e.g. /usr -for /usr/lib and /usr/include (_NOT_ recommended!). - -To enable debugging output (useful for me), run - - make clean - ./configure --enable-debug - make - sudo make install - -If you want old dlcompat style behavior of not prepending the underscore -on calls to dlsym then type: - - make clean - ./configure --enable-fink - make - sudo make install - -Usage -------- -Software that uses GNU autoconf will likely check for a library called -libdl, that's why I named it that way. For software that doesn't find -the library on its own, you must add a '-ldl' to the appropriate -Makefile (or environment) variable, usually LIBS. - -If you installed dlcompat into a directory other than /usr/local/lib, -you must tell the compiler where to find it. Add '-L/lib' to -LDFLAGS (or CFLAGS) and '-I/include' to CPPFLAGS (or CFLAGS). - -Notes ------ -If you are writing new software and plan to have Mac OX X compatibility you -should look at the dyld api's in /usr/include/mach-o/dyld.h, rather than -using dlcompat, using the native api's is the supported method of loading -dynamically on Mac OS X, if you want an small example, look at dlfcn_simple.c, -which should help get you started. - -Also note that the functions in dlcompat are not thread safe, and while it is not -POSIX spec compliant, it is about as close to compliance as it is going to get though. - -You can always get the latest version from opendarwin cvs: - - cvs -d :pserver:anonymous@anoncvs.opendarwin.org:/cvs/od login - cvs -z3 -d :pserver:anonymous@anoncvs.opendarwin.org:/cvs/od \ - co -d dlcompat proj/dlcompat - - -It is hoped that this library will be useful, and as bug free as possible, if you find -any bugs please let us know about them so they can be fixed. - -Please send bug reports to Peter O'Gorman - -Thanks. - diff --git a/Modules/_ctypes/darwin/README.ctypes b/Modules/_ctypes/darwin/README.ctypes deleted file mode 100644 index 8520b01f49d..00000000000 --- a/Modules/_ctypes/darwin/README.ctypes +++ /dev/null @@ -1,11 +0,0 @@ -The files in this directory are taken from -http://www.opendarwin.org/cgi-bin/cvsweb.cgi/~checkout~/proj/dlcompat/ - -The LICENSE in this directory applies to these files. - -Thomas Heller, Jan 2003 - -These files have been modified so they fall back to the system -dlfcn calls if available in libSystem. - -Bob Ippolito, Feb 2006 diff --git a/Modules/_ctypes/darwin/dlfcn.h b/Modules/_ctypes/darwin/dlfcn.h deleted file mode 100644 index a2afc3eeb84..00000000000 --- a/Modules/_ctypes/darwin/dlfcn.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright (c) 2002 Jorge Acereda & - Peter O'Gorman - -Portions may be copyright others, see the AUTHORS file included with this -distribution. - -Maintained by Peter O'Gorman - -Bug Reports and other queries should go to - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -#ifndef _DLFCN_H_ -#define _DLFCN_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Structure filled in by dladdr(). - */ - -typedef struct dl_info { - const char *dli_fname; /* Pathname of shared object */ - void *dli_fbase; /* Base address of shared object */ - const char *dli_sname; /* Name of nearest symbol */ - void *dli_saddr; /* Address of nearest symbol */ -} Dl_info; - - -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_2 -#warning CTYPES_DARWIN_DLFCN -#define CTYPES_DARWIN_DLFCN -extern void * (*ctypes_dlopen)(const char *path, int mode); -extern void * (*ctypes_dlsym)(void * handle, const char *symbol); -extern const char * (*ctypes_dlerror)(void); -extern int (*ctypes_dlclose)(void * handle); -extern int (*ctypes_dladdr)(const void *, Dl_info *); -#else -extern void * dlopen(const char *path, int mode); -extern void * dlsym(void * handle, const char *symbol); -extern const char * dlerror(void); -extern int dlclose(void * handle); -extern int dladdr(const void *, Dl_info *); -#endif - -#define RTLD_LAZY 0x1 -#define RTLD_NOW 0x2 -#define RTLD_LOCAL 0x4 -#define RTLD_GLOBAL 0x8 -#define RTLD_NOLOAD 0x10 -#define RTLD_NODELETE 0x80 - -/* These are from the Mac OS X 10.4 headers */ -#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */ -#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */ - -#ifdef __cplusplus -} -#endif - -#endif /* _DLFCN_H_ */ diff --git a/Modules/_ctypes/darwin/dlfcn_simple.c b/Modules/_ctypes/darwin/dlfcn_simple.c deleted file mode 100644 index 2b293bb8695..00000000000 --- a/Modules/_ctypes/darwin/dlfcn_simple.c +++ /dev/null @@ -1,272 +0,0 @@ -/* -Copyright (c) 2002 Peter O'Gorman - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - - -/* Just to prove that it isn't that hard to add Mac calls to your code :) - This works with pretty much everything, including kde3 xemacs and the gimp, - I'd guess that it'd work in at least 95% of cases, use this as your starting - point, rather than the mess that is dlfcn.c, assuming that your code does not - require ref counting or symbol lookups in dependent libraries -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "dlfcn.h" - -#ifdef CTYPES_DARWIN_DLFCN - -#define ERR_STR_LEN 256 - -#ifndef MAC_OS_X_VERSION_10_3 -#define MAC_OS_X_VERSION_10_3 1030 -#endif - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 -#define DARWIN_HAS_DLOPEN -extern void * dlopen(const char *path, int mode) __attribute__((weak_import)); -extern void * dlsym(void * handle, const char *symbol) __attribute__((weak_import)); -extern const char * dlerror(void) __attribute__((weak_import)); -extern int dlclose(void * handle) __attribute__((weak_import)); -extern int dladdr(const void *, Dl_info *) __attribute__((weak_import)); -#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 */ - -#ifndef DARWIN_HAS_DLOPEN -#define dlopen darwin_dlopen -#define dlsym darwin_dlsym -#define dlerror darwin_dlerror -#define dlclose darwin_dlclose -#define dladdr darwin_dladdr -#endif - -void * (*ctypes_dlopen)(const char *path, int mode); -void * (*ctypes_dlsym)(void * handle, const char *symbol); -const char * (*ctypes_dlerror)(void); -int (*ctypes_dlclose)(void * handle); -int (*ctypes_dladdr)(const void *, Dl_info *); - -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 -/* Mac OS X 10.3+ has dlopen, so strip all this dead code to avoid warnings */ - -static void *dlsymIntern(void *handle, const char *symbol); - -static const char *error(int setget, const char *str, ...); - -/* Set and get the error string for use by dlerror */ -static const char *error(int setget, const char *str, ...) -{ - static char errstr[ERR_STR_LEN]; - static int err_filled = 0; - const char *retval; - va_list arg; - if (setget == 0) - { - va_start(arg, str); - strncpy(errstr, "dlcompat: ", ERR_STR_LEN); - vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg); - va_end(arg); - err_filled = 1; - retval = NULL; - } - else - { - if (!err_filled) - retval = NULL; - else - retval = errstr; - err_filled = 0; - } - return retval; -} - -/* darwin_dlopen */ -static void *darwin_dlopen(const char *path, int mode) -{ - void *module = 0; - NSObjectFileImage ofi = 0; - NSObjectFileImageReturnCode ofirc; - - /* If we got no path, the app wants the global namespace, use -1 as the marker - in this case */ - if (!path) - return (void *)-1; - - /* Create the object file image, works for things linked with the -bundle arg to ld */ - ofirc = NSCreateObjectFileImageFromFile(path, &ofi); - switch (ofirc) - { - case NSObjectFileImageSuccess: - /* It was okay, so use NSLinkModule to link in the image */ - module = NSLinkModule(ofi, path, - NSLINKMODULE_OPTION_RETURN_ON_ERROR - | (mode & RTLD_GLOBAL) ? 0 : NSLINKMODULE_OPTION_PRIVATE - | (mode & RTLD_LAZY) ? 0 : NSLINKMODULE_OPTION_BINDNOW); - NSDestroyObjectFileImage(ofi); - break; - case NSObjectFileImageInappropriateFile: - /* It may have been a dynamic library rather than a bundle, try to load it */ - module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); - break; - default: - /* God knows what we got */ - error(0, "Can not open \"%s\"", path); - return 0; - } - if (!module) - error(0, "Can not open \"%s\"", path); - return module; - -} - -/* dlsymIntern is used by dlsym to find the symbol */ -static void *dlsymIntern(void *handle, const char *symbol) -{ - NSSymbol nssym = 0; - /* If the handle is -1, if is the app global context */ - if (handle == (void *)-1) - { - /* Global context, use NSLookupAndBindSymbol */ - if (NSIsSymbolNameDefined(symbol)) - { - nssym = NSLookupAndBindSymbol(symbol); - } - - } - /* Now see if the handle is a struch mach_header* or not, use NSLookupSymbol in image - for libraries, and NSLookupSymbolInModule for bundles */ - else - { - /* Check for both possible magic numbers depending on x86/ppc byte order */ - if ((((struct mach_header *)handle)->magic == MH_MAGIC) || - (((struct mach_header *)handle)->magic == MH_CIGAM)) - { - if (NSIsSymbolNameDefinedInImage((struct mach_header *)handle, symbol)) - { - nssym = NSLookupSymbolInImage((struct mach_header *)handle, - symbol, - NSLOOKUPSYMBOLINIMAGE_OPTION_BIND - | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); - } - - } - else - { - nssym = NSLookupSymbolInModule(handle, symbol); - } - } - if (!nssym) - { - error(0, "Symbol \"%s\" Not found", symbol); - return NULL; - } - return NSAddressOfSymbol(nssym); -} - -static const char *darwin_dlerror(void) -{ - return error(1, (char *)NULL); -} - -static int darwin_dlclose(void *handle) -{ - if ((((struct mach_header *)handle)->magic == MH_MAGIC) || - (((struct mach_header *)handle)->magic == MH_CIGAM)) - { - error(0, "Can't remove dynamic libraries on darwin"); - return 0; - } - if (!NSUnLinkModule(handle, 0)) - { - error(0, "unable to unlink module %s", NSNameOfModule(handle)); - return 1; - } - return 0; -} - - -/* dlsym, prepend the underscore and call dlsymIntern */ -static void *darwin_dlsym(void *handle, const char *symbol) -{ - static char undersym[257]; /* Saves calls to malloc(3) */ - int sym_len = strlen(symbol); - void *value = NULL; - char *malloc_sym = NULL; - - if (sym_len < 256) - { - snprintf(undersym, 256, "_%s", symbol); - value = dlsymIntern(handle, undersym); - } - else - { - malloc_sym = malloc(sym_len + 2); - if (malloc_sym) - { - sprintf(malloc_sym, "_%s", symbol); - value = dlsymIntern(handle, malloc_sym); - free(malloc_sym); - } - else - { - error(0, "Unable to allocate memory"); - } - } - return value; -} - -static int darwin_dladdr(const void *handle, Dl_info *info) { - return 0; -} -#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */ - -#if __GNUC__ < 4 -#pragma CALL_ON_LOAD ctypes_dlfcn_init -#else -static void __attribute__ ((constructor)) ctypes_dlfcn_init(void); -static -#endif -void ctypes_dlfcn_init(void) { - if (dlopen != NULL) { - ctypes_dlsym = dlsym; - ctypes_dlopen = dlopen; - ctypes_dlerror = dlerror; - ctypes_dlclose = dlclose; - ctypes_dladdr = dladdr; - } else { -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 - ctypes_dlsym = darwin_dlsym; - ctypes_dlopen = darwin_dlopen; - ctypes_dlerror = darwin_dlerror; - ctypes_dlclose = darwin_dlclose; - ctypes_dladdr = darwin_dladdr; -#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */ - } -} - -#endif /* CTYPES_DARWIN_DLFCN */ diff --git a/Modules/_ctypes/libffi_osx/LICENSE b/Modules/_ctypes/libffi_osx/LICENSE deleted file mode 100644 index f591795152d..00000000000 --- a/Modules/_ctypes/libffi_osx/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -libffi - Copyright (c) 1996-2003 Red Hat, Inc. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -``Software''), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/Modules/_ctypes/libffi_osx/README b/Modules/_ctypes/libffi_osx/README deleted file mode 100644 index 54f00e3ec1f..00000000000 --- a/Modules/_ctypes/libffi_osx/README +++ /dev/null @@ -1,500 +0,0 @@ -This directory contains the libffi package, which is not part of GCC but -shipped with GCC as convenience. - -Status -====== - -libffi-2.00 has not been released yet! This is a development snapshot! - -libffi-1.20 was released on October 5, 1998. Check the libffi web -page for updates: . - - -What is libffi? -=============== - -Compilers for high level languages generate code that follow certain -conventions. These conventions are necessary, in part, for separate -compilation to work. One such convention is the "calling -convention". The "calling convention" is essentially a set of -assumptions made by the compiler about where function arguments will -be found on entry to a function. A "calling convention" also specifies -where the return value for a function is found. - -Some programs may not know at the time of compilation what arguments -are to be passed to a function. For instance, an interpreter may be -told at run-time about the number and types of arguments used to call -a given function. Libffi can be used in such programs to provide a -bridge from the interpreter program to compiled code. - -The libffi library provides a portable, high level programming -interface to various calling conventions. This allows a programmer to -call any function specified by a call interface description at run -time. - -Ffi stands for Foreign Function Interface. A foreign function -interface is the popular name for the interface that allows code -written in one language to call code written in another language. The -libffi library really only provides the lowest, machine dependent -layer of a fully featured foreign function interface. A layer must -exist above libffi that handles type conversions for values passed -between the two languages. - - -Supported Platforms and Prerequisites -===================================== - -Libffi has been ported to: - - SunOS 4.1.3 & Solaris 2.x (SPARC-V8, SPARC-V9) - - Irix 5.3 & 6.2 (System V/o32 & n32) - - Intel x86 - Linux (System V ABI) - - Alpha - Linux and OSF/1 - - m68k - Linux (System V ABI) - - PowerPC - Linux (System V ABI, Darwin, AIX) - - ARM - Linux (System V ABI) - -Libffi has been tested with the egcs 1.0.2 gcc compiler. Chances are -that other versions will work. Libffi has also been built and tested -with the SGI compiler tools. - -On PowerPC, the tests failed (see the note below). - -You must use GNU make to build libffi. SGI's make will not work. -Sun's probably won't either. - -If you port libffi to another platform, please let me know! I assume -that some will be easy (x86 NetBSD), and others will be more difficult -(HP). - - -Installing libffi -================= - -[Note: before actually performing any of these installation steps, - you may wish to read the "Platform Specific Notes" below.] - -First you must configure the distribution for your particular -system. Go to the directory you wish to build libffi in and run the -"configure" program found in the root directory of the libffi source -distribution. - -You may want to tell configure where to install the libffi library and -header files. To do that, use the --prefix configure switch. Libffi -will install under /usr/local by default. - -If you want to enable extra run-time debugging checks use the the ---enable-debug configure switch. This is useful when your program dies -mysteriously while using libffi. - -Another useful configure switch is --enable-purify-safety. Using this -will add some extra code which will suppress certain warnings when you -are using Purify with libffi. Only use this switch when using -Purify, as it will slow down the library. - -Configure has many other options. Use "configure --help" to see them all. - -Once configure has finished, type "make". Note that you must be using -GNU make. SGI's make will not work. Sun's probably won't either. -You can ftp GNU make from prep.ai.mit.edu:/pub/gnu. - -To ensure that libffi is working as advertised, type "make test". - -To install the library and header files, type "make install". - - -Using libffi -============ - - The Basics - ---------- - -Libffi assumes that you have a pointer to the function you wish to -call and that you know the number and types of arguments to pass it, -as well as the return type of the function. - -The first thing you must do is create an ffi_cif object that matches -the signature of the function you wish to call. The cif in ffi_cif -stands for Call InterFace. To prepare a call interface object, use the -following function: - -ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, - unsigned int nargs, - ffi_type *rtype, ffi_type **atypes); - - CIF is a pointer to the call interface object you wish - to initialize. - - ABI is an enum that specifies the calling convention - to use for the call. FFI_DEFAULT_ABI defaults - to the system's native calling convention. Other - ABI's may be used with care. They are system - specific. - - NARGS is the number of arguments this function accepts. - libffi does not yet support vararg functions. - - RTYPE is a pointer to an ffi_type structure that represents - the return type of the function. Ffi_type objects - describe the types of values. libffi provides - ffi_type objects for many of the native C types: - signed int, unsigned int, signed char, unsigned char, - etc. There is also a pointer ffi_type object and - a void ffi_type. Use &ffi_type_void for functions that - don't return values. - - ATYPES is a vector of ffi_type pointers. ARGS must be NARGS long. - If NARGS is 0, this is ignored. - - -ffi_prep_cif will return a status code that you are responsible -for checking. It will be one of the following: - - FFI_OK - All is good. - - FFI_BAD_TYPEDEF - One of the ffi_type objects that ffi_prep_cif - came across is bad. - - -Before making the call, the VALUES vector should be initialized -with pointers to the appropriate argument values. - -To call the function using the initialized ffi_cif, use the -ffi_call function: - -void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues); - - CIF is a pointer to the ffi_cif initialized specifically - for this function. - - FN is a pointer to the function you want to call. - - RVALUE is a pointer to a chunk of memory that is to hold the - result of the function call. Currently, it must be - at least one word in size (except for the n32 version - under Irix 6.x, which must be a pointer to an 8 byte - aligned value (a long long). It must also be at least - word aligned (depending on the return type, and the - system's alignment requirements). If RTYPE is - &ffi_type_void, this is ignored. If RVALUE is NULL, - the return value is discarded. - - AVALUES is a vector of void* that point to the memory locations - holding the argument values for a call. - If NARGS is 0, this is ignored. - - -If you are expecting a return value from FN it will have been stored -at RVALUE. - - - - An Example - ---------- - -Here is a trivial example that calls puts() a few times. - - #include - #include - - int main() - { - ffi_cif cif; - ffi_type *args[1]; - void *values[1]; - char *s; - int rc; - - /* Initialize the argument info vectors */ - args[0] = &ffi_type_uint; - values[0] = &s; - - /* Initialize the cif */ - if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_uint, args) == FFI_OK) - { - s = "Hello World!"; - ffi_call(&cif, puts, &rc, values); - /* rc now holds the result of the call to puts */ - - /* values holds a pointer to the function's arg, so to - call puts() again all we need to do is change the - value of s */ - s = "This is cool!"; - ffi_call(&cif, puts, &rc, values); - } - - return 0; - } - - - - Aggregate Types - --------------- - -Although libffi has no special support for unions or bit-fields, it is -perfectly happy passing structures back and forth. You must first -describe the structure to libffi by creating a new ffi_type object -for it. Here is the definition of ffi_type: - - typedef struct _ffi_type - { - unsigned size; - short alignment; - short type; - struct _ffi_type **elements; - } ffi_type; - -All structures must have type set to FFI_TYPE_STRUCT. You may set -size and alignment to 0. These will be calculated and reset to the -appropriate values by ffi_prep_cif(). - -elements is a NULL terminated array of pointers to ffi_type objects -that describe the type of the structure elements. These may, in turn, -be structure elements. - -The following example initializes a ffi_type object representing the -tm struct from Linux's time.h: - - struct tm { - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; - int tm_wday; - int tm_yday; - int tm_isdst; - /* Those are for future use. */ - long int __tm_gmtoff__; - __const char *__tm_zone__; - }; - - { - ffi_type tm_type; - ffi_type *tm_type_elements[12]; - int i; - - tm_type.size = tm_type.alignment = 0; - tm_type.elements = &tm_type_elements; - - for (i = 0; i < 9; i++) - tm_type_elements[i] = &ffi_type_sint; - - tm_type_elements[9] = &ffi_type_slong; - tm_type_elements[10] = &ffi_type_pointer; - tm_type_elements[11] = NULL; - - /* tm_type can now be used to represent tm argument types and - return types for ffi_prep_cif() */ - } - - - -Platform Specific Notes -======================= - - Intel x86 - --------- - -There are no known problems with the x86 port. - - Sun SPARC - SunOS 4.1.3 & Solaris 2.x - ------------------------------------- - -You must use GNU Make to build libffi on Sun platforms. - - MIPS - Irix 5.3 & 6.x - --------------------- - -Irix 6.2 and better supports three different calling conventions: o32, -n32 and n64. Currently, libffi only supports both o32 and n32 under -Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be -configured for whichever calling convention it was built for. - -By default, the configure script will try to build libffi with the GNU -development tools. To build libffi with the SGI development tools, set -the environment variable CC to either "cc -32" or "cc -n32" before -running configure under Irix 6.x (depending on whether you want an o32 -or n32 library), or just "cc" for Irix 5.3. - -With the n32 calling convention, when returning structures smaller -than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned. -Here's one way of forcing this: - - double struct_storage[2]; - my_small_struct *s = (my_small_struct *) struct_storage; - /* Use s for RVALUE */ - -If you don't do this you are liable to get spurious bus errors. - -"long long" values are not supported yet. - -You must use GNU Make to build libffi on SGI platforms. - - ARM - System V ABI - ------------------ - -The ARM port was performed on a NetWinder running ARM Linux ELF -(2.0.31) and gcc 2.8.1. - - - - PowerPC System V ABI - -------------------- - -There are two `System V ABI's which libffi implements for PowerPC. -They differ only in how small structures are returned from functions. - -In the FFI_SYSV version, structures that are 8 bytes or smaller are -returned in registers. This is what GCC does when it is configured -for solaris, and is what the System V ABI I have (dated September -1995) says. - -In the FFI_GCC_SYSV version, all structures are returned the same way: -by passing a pointer as the first argument to the function. This is -what GCC does when it is configured for linux or a generic sysv -target. - -EGCS 1.0.1 (and probably other versions of EGCS/GCC) also has a -inconsistency with the SysV ABI: When a procedure is called with many -floating-point arguments, some of them get put on the stack. They are -all supposed to be stored in double-precision format, even if they are -only single-precision, but EGCS stores single-precision arguments as -single-precision anyway. This causes one test to fail (the `many -arguments' test). - - -What's With The Cryptic Comments? -================================= - -You might notice a number of cryptic comments in the code, delimited -by /*@ and @*/. These are annotations read by the program LCLint, a -tool for statically checking C programs. You can read all about it at -. - - -History -======= - -1.20 Oct-5-98 - Raffaele Sena produces ARM port. - -1.19 Oct-5-98 - Fixed x86 long double and long long return support. - m68k bug fixes from Andreas Schwab. - Patch for DU assembler compatibility for the Alpha from Richard - Henderson. - -1.18 Apr-17-98 - Bug fixes and MIPS configuration changes. - -1.17 Feb-24-98 - Bug fixes and m68k port from Andreas Schwab. PowerPC port from - Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes. - -1.16 Feb-11-98 - Richard Henderson produces Alpha port. - -1.15 Dec-4-97 - Fixed an n32 ABI bug. New libtool, auto* support. - -1.14 May-13-97 - libtool is now used to generate shared and static libraries. - Fixed a minor portability problem reported by Russ McManus - . - -1.13 Dec-2-96 - Added --enable-purify-safety to keep Purify from complaining - about certain low level code. - Sparc fix for calling functions with < 6 args. - Linux x86 a.out fix. - -1.12 Nov-22-96 - Added missing ffi_type_void, needed for supporting void return - types. Fixed test case for non MIPS machines. Cygnus Support - is now Cygnus Solutions. - -1.11 Oct-30-96 - Added notes about GNU make. - -1.10 Oct-29-96 - Added configuration fix for non GNU compilers. - -1.09 Oct-29-96 - Added --enable-debug configure switch. Clean-ups based on LCLint - feedback. ffi_mips.h is always installed. Many configuration - fixes. Fixed ffitest.c for sparc builds. - -1.08 Oct-15-96 - Fixed n32 problem. Many clean-ups. - -1.07 Oct-14-96 - Gordon Irlam rewrites v8.S again. Bug fixes. - -1.06 Oct-14-96 - Gordon Irlam improved the sparc port. - -1.05 Oct-14-96 - Interface changes based on feedback. - -1.04 Oct-11-96 - Sparc port complete (modulo struct passing bug). - -1.03 Oct-10-96 - Passing struct args, and returning struct values works for - all architectures/calling conventions. Expanded tests. - -1.02 Oct-9-96 - Added SGI n32 support. Fixed bugs in both o32 and Linux support. - Added "make test". - -1.01 Oct-8-96 - Fixed float passing bug in mips version. Restructured some - of the code. Builds cleanly with SGI tools. - -1.00 Oct-7-96 - First release. No public announcement. - - -Authors & Credits -================= - -libffi was written by Anthony Green . - -Portions of libffi were derived from Gianni Mariani's free gencall -library for Silicon Graphics machines. - -The closure mechanism was designed and implemented by Kresten Krab -Thorup. - -The Sparc port was derived from code contributed by the fine folks at -Visible Decisions Inc . Further enhancements were -made by Gordon Irlam at Cygnus Solutions . - -The Alpha port was written by Richard Henderson at Cygnus Solutions. - -Andreas Schwab ported libffi to m68k Linux and provided a number of -bug fixes. - -Geoffrey Keating ported libffi to the PowerPC. - -Raffaele Sena ported libffi to the ARM. - -Jesper Skov and Andrew Haley both did more than their fair share of -stepping through the code and tracking down bugs. - -Thanks also to Tom Tromey for bug fixes and configuration help. - -Thanks to Jim Blandy, who provided some useful feedback on the libffi -interface. - -If you have a problem, or have found a bug, please send a note to -green@cygnus.com. diff --git a/Modules/_ctypes/libffi_osx/README.pyobjc b/Modules/_ctypes/libffi_osx/README.pyobjc deleted file mode 100644 index 405d85fed2d..00000000000 --- a/Modules/_ctypes/libffi_osx/README.pyobjc +++ /dev/null @@ -1,5 +0,0 @@ -This directory contains a slightly modified version of libffi, extracted from -the GCC source-tree. - -The only modifications are those that are necessary to compile libffi using -the Apple provided compiler and outside of the GCC source tree. diff --git a/Modules/_ctypes/libffi_osx/ffi.c b/Modules/_ctypes/libffi_osx/ffi.c deleted file mode 100644 index 1776b795e2f..00000000000 --- a/Modules/_ctypes/libffi_osx/ffi.c +++ /dev/null @@ -1,227 +0,0 @@ -/* ----------------------------------------------------------------------- - prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -#include -#include - -/* Round up to FFI_SIZEOF_ARG. */ -#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG) - -/* Perform machine independent initialization of aggregate type - specifications. */ - -static ffi_status -initialize_aggregate( -/*@out@*/ ffi_type* arg) -{ -/*@-usedef@*/ - ffi_type** ptr; - - if (arg == NULL || arg->elements == NULL || - arg->size != 0 || arg->alignment != 0) - return FFI_BAD_TYPEDEF; - - ptr = &(arg->elements[0]); - - while ((*ptr) != NULL) - { - if (((*ptr)->size == 0) && (initialize_aggregate(*ptr) != FFI_OK)) - return FFI_BAD_TYPEDEF; - - /* Perform a sanity check on the argument type */ - FFI_ASSERT_VALID_TYPE(*ptr); - -#ifdef POWERPC_DARWIN - int curalign = (*ptr)->alignment; - - if (ptr != &(arg->elements[0])) - { - if (curalign > 4 && curalign != 16) - curalign = 4; - } - - arg->size = ALIGN(arg->size, curalign); - arg->size += (*ptr)->size; - arg->alignment = (arg->alignment > curalign) ? - arg->alignment : curalign; -#else - arg->size = ALIGN(arg->size, (*ptr)->alignment); - arg->size += (*ptr)->size; - arg->alignment = (arg->alignment > (*ptr)->alignment) ? - arg->alignment : (*ptr)->alignment; -#endif - - ptr++; - } - - /* Structure size includes tail padding. This is important for - structures that fit in one register on ABIs like the PowerPC64 - Linux ABI that right justify small structs in a register. - It's also needed for nested structure layout, for example - struct A { long a; char b; }; struct B { struct A x; char y; }; - should find y at an offset of 2*sizeof(long) and result in a - total size of 3*sizeof(long). */ - arg->size = ALIGN(arg->size, arg->alignment); - - if (arg->size == 0) - return FFI_BAD_TYPEDEF; - - return FFI_OK; - -/*@=usedef@*/ -} - -#ifndef __CRIS__ -/* The CRIS ABI specifies structure elements to have byte - alignment only, so it completely overrides this functions, - which assumes "natural" alignment and padding. */ - -/* Perform machine independent ffi_cif preparation, then call - machine dependent routine. */ - -#if defined(X86_DARWIN) && !defined __x86_64__ - -static inline bool -struct_on_stack( - int size) -{ - if (size > 8) - return true; - - /* This is not what the ABI says, but is what is really implemented */ - switch (size) - { - case 1: - case 2: - case 4: - case 8: - return false; - - default: - return true; - } -} - -#endif // defined(X86_DARWIN) && !defined __x86_64__ - -// Arguments' ffi_type->alignment must be nonzero. -ffi_status -ffi_prep_cif( -/*@out@*/ /*@partial@*/ ffi_cif* cif, - ffi_abi abi, - unsigned int nargs, -/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type* rtype, -/*@dependent@*/ ffi_type** atypes) -{ - unsigned int bytes = 0; - unsigned int i; - ffi_type** ptr; - - if (cif == NULL) - return FFI_BAD_TYPEDEF; - - if (abi <= FFI_FIRST_ABI || abi > FFI_DEFAULT_ABI) - return FFI_BAD_ABI; - - cif->abi = abi; - cif->arg_types = atypes; - cif->nargs = nargs; - cif->rtype = rtype; - cif->flags = 0; - - /* Initialize the return type if necessary */ - /*@-usedef@*/ - if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) - return FFI_BAD_TYPEDEF; - /*@=usedef@*/ - - /* Perform a sanity check on the return type */ - FFI_ASSERT_VALID_TYPE(cif->rtype); - - /* x86-64 and s390 stack space allocation is handled in prep_machdep. */ -#if !defined M68K && !defined __x86_64__ && !defined S390 && !defined PA - /* Make space for the return structure pointer */ - if (cif->rtype->type == FFI_TYPE_STRUCT -#ifdef SPARC - && (cif->abi != FFI_V9 || cif->rtype->size > 32) -#endif -#ifdef X86_DARWIN - && (struct_on_stack(cif->rtype->size)) -#endif - ) - bytes = STACK_ARG_SIZE(sizeof(void*)); -#endif - - for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) - { - /* Initialize any uninitialized aggregate type definitions */ - if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) - return FFI_BAD_TYPEDEF; - - if ((*ptr)->alignment == 0) - return FFI_BAD_TYPEDEF; - - /* Perform a sanity check on the argument type, do this - check after the initialization. */ - FFI_ASSERT_VALID_TYPE(*ptr); - -#if defined(X86_DARWIN) - { - int align = (*ptr)->alignment; - - if (align > 4) - align = 4; - - if ((align - 1) & bytes) - bytes = ALIGN(bytes, align); - - bytes += STACK_ARG_SIZE((*ptr)->size); - } -#elif !defined __x86_64__ && !defined S390 && !defined PA -#ifdef SPARC - if (((*ptr)->type == FFI_TYPE_STRUCT - && ((*ptr)->size > 16 || cif->abi != FFI_V9)) - || ((*ptr)->type == FFI_TYPE_LONGDOUBLE - && cif->abi != FFI_V9)) - bytes += sizeof(void*); - else -#endif - { - /* Add any padding if necessary */ - if (((*ptr)->alignment - 1) & bytes) - bytes = ALIGN(bytes, (*ptr)->alignment); - - bytes += STACK_ARG_SIZE((*ptr)->size); - } -#endif - } - - cif->bytes = bytes; - - /* Perform machine dependent cif processing */ - return ffi_prep_cif_machdep(cif); -} -#endif /* not __CRIS__ */ diff --git a/Modules/_ctypes/libffi_osx/include/ffi.h b/Modules/_ctypes/libffi_osx/include/ffi.h deleted file mode 100644 index c104a5c8935..00000000000 --- a/Modules/_ctypes/libffi_osx/include/ffi.h +++ /dev/null @@ -1,355 +0,0 @@ -/* -----------------------------------------------------------------*-C-*- - libffi PyOBJC - Copyright (c) 1996-2003 Red Hat, Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------- - The basic API is described in the README file. - - The raw API is designed to bypass some of the argument packing - and unpacking on architectures for which it can be avoided. - - The closure API allows interpreted functions to be packaged up - inside a C function pointer, so that they can be called as C functions, - with no understanding on the client side that they are interpreted. - It can also be used in other cases in which it is necessary to package - up a user specified parameter and a function pointer as a single - function pointer. - - The closure API must be implemented in order to get its functionality, - e.g. for use by gij. Routines are provided to emulate the raw API - if the underlying platform doesn't allow faster implementation. - - More details on the raw and closure API can be found in: - - http://gcc.gnu.org/ml/java/1999-q3/msg00138.html - - and - - http://gcc.gnu.org/ml/java/1999-q3/msg00174.html - -------------------------------------------------------------------- */ - -#ifndef LIBFFI_H -#define LIBFFI_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Specify which architecture libffi is configured for. */ -#ifdef MACOSX -# if defined(__i386__) || defined(__x86_64__) -# define X86_DARWIN -# elif defined(__ppc__) || defined(__ppc64__) -# define POWERPC_DARWIN -# else -# error "Unsupported MacOS X CPU type" -# endif -#else -#error "Unsupported OS type" -#endif - -/* ---- System configuration information --------------------------------- */ - -#include "ffitarget.h" -#include "fficonfig.h" - -#ifndef LIBFFI_ASM - -#include -#include - -/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example). - But we can find it either under the correct ANSI name, or under GNU - C's internal name. */ -#ifdef LONG_LONG_MAX -# define FFI_LONG_LONG_MAX LONG_LONG_MAX -#else -# ifdef LLONG_MAX -# define FFI_LONG_LONG_MAX LLONG_MAX -# else -# ifdef __GNUC__ -# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__ -# endif -# endif -#endif - -#if SCHAR_MAX == 127 -# define ffi_type_uchar ffi_type_uint8 -# define ffi_type_schar ffi_type_sint8 -#else -#error "char size not supported" -#endif - -#if SHRT_MAX == 32767 -# define ffi_type_ushort ffi_type_uint16 -# define ffi_type_sshort ffi_type_sint16 -#elif SHRT_MAX == 2147483647 -# define ffi_type_ushort ffi_type_uint32 -# define ffi_type_sshort ffi_type_sint32 -#else -#error "short size not supported" -#endif - -#if INT_MAX == 32767 -# define ffi_type_uint ffi_type_uint16 -# define ffi_type_sint ffi_type_sint16 -#elif INT_MAX == 2147483647 -# define ffi_type_uint ffi_type_uint32 -# define ffi_type_sint ffi_type_sint32 -#elif INT_MAX == 9223372036854775807 -# define ffi_type_uint ffi_type_uint64 -# define ffi_type_sint ffi_type_sint64 -#else -#error "int size not supported" -#endif - -#define ffi_type_ulong ffi_type_uint64 -#define ffi_type_slong ffi_type_sint64 - -#if LONG_MAX == 2147483647 -# if FFI_LONG_LONG_MAX != 9223372036854775807 -# error "no 64-bit data type supported" -# endif -#elif LONG_MAX != 9223372036854775807 -#error "long size not supported" -#endif - -/* The closure code assumes that this works on pointers, i.e. a size_t - can hold a pointer. */ - -typedef struct _ffi_type { - size_t size; - unsigned short alignment; - unsigned short type; -/*@null@*/ struct _ffi_type** elements; -} ffi_type; - -/* These are defined in types.c */ -extern ffi_type ffi_type_void; -extern ffi_type ffi_type_uint8; -extern ffi_type ffi_type_sint8; -extern ffi_type ffi_type_uint16; -extern ffi_type ffi_type_sint16; -extern ffi_type ffi_type_uint32; -extern ffi_type ffi_type_sint32; -extern ffi_type ffi_type_uint64; -extern ffi_type ffi_type_sint64; -extern ffi_type ffi_type_float; -extern ffi_type ffi_type_double; -extern ffi_type ffi_type_longdouble; -extern ffi_type ffi_type_pointer; - -typedef enum ffi_status { - FFI_OK = 0, - FFI_BAD_TYPEDEF, - FFI_BAD_ABI -} ffi_status; - -typedef unsigned FFI_TYPE; - -typedef struct ffi_cif { - ffi_abi abi; - unsigned nargs; -/*@dependent@*/ ffi_type** arg_types; -/*@dependent@*/ ffi_type* rtype; - unsigned bytes; - unsigned flags; -#ifdef FFI_EXTRA_CIF_FIELDS - FFI_EXTRA_CIF_FIELDS; -#endif -} ffi_cif; - -/* ---- Definitions for the raw API -------------------------------------- */ - -#ifndef FFI_SIZEOF_ARG -# if LONG_MAX == 2147483647 -# define FFI_SIZEOF_ARG 4 -# elif LONG_MAX == 9223372036854775807 -# define FFI_SIZEOF_ARG 8 -# endif -#endif - -typedef union { - ffi_sarg sint; - ffi_arg uint; - float flt; - char data[FFI_SIZEOF_ARG]; - void* ptr; -} ffi_raw; - -void -ffi_raw_call( -/*@dependent@*/ ffi_cif* cif, - void (*fn)(void), -/*@out@*/ void* rvalue, -/*@dependent@*/ ffi_raw* avalue); - -void -ffi_ptrarray_to_raw( - ffi_cif* cif, - void** args, - ffi_raw* raw); - -void -ffi_raw_to_ptrarray( - ffi_cif* cif, - ffi_raw* raw, - void** args); - -size_t -ffi_raw_size( - ffi_cif* cif); - -/* This is analogous to the raw API, except it uses Java parameter - packing, even on 64-bit machines. I.e. on 64-bit machines - longs and doubles are followed by an empty 64-bit word. */ -void -ffi_java_raw_call( -/*@dependent@*/ ffi_cif* cif, - void (*fn)(void), -/*@out@*/ void* rvalue, -/*@dependent@*/ ffi_raw* avalue); - -void -ffi_java_ptrarray_to_raw( - ffi_cif* cif, - void** args, - ffi_raw* raw); - -void -ffi_java_raw_to_ptrarray( - ffi_cif* cif, - ffi_raw* raw, - void** args); - -size_t -ffi_java_raw_size( - ffi_cif* cif); - -/* ---- Definitions for closures ----------------------------------------- */ - -#if FFI_CLOSURES - -typedef struct ffi_closure { - char tramp[FFI_TRAMPOLINE_SIZE]; - ffi_cif* cif; - void (*fun)(ffi_cif*,void*,void**,void*); - void* user_data; -} ffi_closure; - -ffi_status -ffi_prep_closure( - ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void* user_data); - -void ffi_closure_free(void *); -void *ffi_closure_alloc (size_t size, void **code); - -typedef struct ffi_raw_closure { - char tramp[FFI_TRAMPOLINE_SIZE]; - ffi_cif* cif; - -#if !FFI_NATIVE_RAW_API - /* if this is enabled, then a raw closure has the same layout - as a regular closure. We use this to install an intermediate - handler to do the transaltion, void** -> ffi_raw*. */ - void (*translate_args)(ffi_cif*,void*,void**,void*); - void* this_closure; -#endif - - void (*fun)(ffi_cif*,void*,ffi_raw*,void*); - void* user_data; -} ffi_raw_closure; - -ffi_status -ffi_prep_raw_closure( - ffi_raw_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void* user_data); - -ffi_status -ffi_prep_java_raw_closure( - ffi_raw_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void* user_data); - -#endif // FFI_CLOSURES - -/* ---- Public interface definition -------------------------------------- */ - -ffi_status -ffi_prep_cif( -/*@out@*/ /*@partial@*/ ffi_cif* cif, - ffi_abi abi, - unsigned int nargs, -/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type* rtype, -/*@dependent@*/ ffi_type** atypes); - -void -ffi_call( -/*@dependent@*/ ffi_cif* cif, - void (*fn)(void), -/*@out@*/ void* rvalue, -/*@dependent@*/ void** avalue); - -/* Useful for eliminating compiler warnings */ -#define FFI_FN(f) ((void (*)(void))f) - -#endif // #ifndef LIBFFI_ASM -/* ---- Definitions shared with assembly code ---------------------------- */ - -/* If these change, update src/mips/ffitarget.h. */ -#define FFI_TYPE_VOID 0 -#define FFI_TYPE_INT 1 -#define FFI_TYPE_FLOAT 2 -#define FFI_TYPE_DOUBLE 3 - -#ifdef HAVE_LONG_DOUBLE -# define FFI_TYPE_LONGDOUBLE 4 -#else -# define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE -#endif - -#define FFI_TYPE_UINT8 5 -#define FFI_TYPE_SINT8 6 -#define FFI_TYPE_UINT16 7 -#define FFI_TYPE_SINT16 8 -#define FFI_TYPE_UINT32 9 -#define FFI_TYPE_SINT32 10 -#define FFI_TYPE_UINT64 11 -#define FFI_TYPE_SINT64 12 -#define FFI_TYPE_STRUCT 13 -#define FFI_TYPE_POINTER 14 - -/* This should always refer to the last type code (for sanity checks) */ -#define FFI_TYPE_LAST FFI_TYPE_POINTER - -#ifdef __cplusplus -} -#endif - -#endif // #ifndef LIBFFI_H diff --git a/Modules/_ctypes/libffi_osx/include/ffi_common.h b/Modules/_ctypes/libffi_osx/include/ffi_common.h deleted file mode 100644 index 685a3580f4f..00000000000 --- a/Modules/_ctypes/libffi_osx/include/ffi_common.h +++ /dev/null @@ -1,102 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi_common.h - Copyright (c) 1996 Red Hat, Inc. - - Common internal definitions and macros. Only necessary for building - libffi. - ----------------------------------------------------------------------- */ - -#ifndef FFI_COMMON_H -#define FFI_COMMON_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "fficonfig.h" - -/* Do not move this. Some versions of AIX are very picky about where - this is positioned. */ -#ifdef __GNUC__ -# define alloca __builtin_alloca -#else -# if HAVE_ALLOCA_H -# include -# else -# ifdef _AIX -# pragma alloca -# else -# ifndef alloca /* predefined by HP cc +Olibcalls */ -char* alloca(); -# endif -# endif -# endif -#endif - -/* Check for the existence of memcpy. */ -#if STDC_HEADERS -# include -#else -# ifndef HAVE_MEMCPY -# define memcpy(d, s, n) bcopy((s), (d), (n)) -# endif -#endif - -/*#if defined(FFI_DEBUG) -#include -#endif*/ - -#ifdef FFI_DEBUG -#include - -/*@exits@*/ void -ffi_assert( -/*@temp@*/ char* expr, -/*@temp@*/ char* file, - int line); -void -ffi_stop_here(void); -void -ffi_type_test( -/*@temp@*/ /*@out@*/ ffi_type* a, -/*@temp@*/ char* file, - int line); - -# define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__)) -# define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l))) -# define FFI_ASSERT_VALID_TYPE(x) ffi_type_test(x, __FILE__, __LINE__) -#else -# define FFI_ASSERT(x) -# define FFI_ASSERT_AT(x, f, l) -# define FFI_ASSERT_VALID_TYPE(x) -#endif // #ifdef FFI_DEBUG - -#define ALIGN(v, a) (((size_t)(v) + (a) - 1) & ~((a) - 1)) - -/* Perform machine dependent cif processing */ -ffi_status -ffi_prep_cif_machdep( - ffi_cif* cif); - -/* Extended cif, used in callback from assembly routine */ -typedef struct extended_cif { -/*@dependent@*/ ffi_cif* cif; -/*@dependent@*/ void* rvalue; -/*@dependent@*/ void** avalue; -} extended_cif; - -/* Terse sized type definitions. */ -typedef unsigned int UINT8 __attribute__((__mode__(__QI__))); -typedef signed int SINT8 __attribute__((__mode__(__QI__))); -typedef unsigned int UINT16 __attribute__((__mode__(__HI__))); -typedef signed int SINT16 __attribute__((__mode__(__HI__))); -typedef unsigned int UINT32 __attribute__((__mode__(__SI__))); -typedef signed int SINT32 __attribute__((__mode__(__SI__))); -typedef unsigned int UINT64 __attribute__((__mode__(__DI__))); -typedef signed int SINT64 __attribute__((__mode__(__DI__))); -typedef float FLOAT32; - -#ifdef __cplusplus -} -#endif - -#endif // #ifndef FFI_COMMON_H \ No newline at end of file diff --git a/Modules/_ctypes/libffi_osx/include/fficonfig.h b/Modules/_ctypes/libffi_osx/include/fficonfig.h deleted file mode 100644 index 217249071dc..00000000000 --- a/Modules/_ctypes/libffi_osx/include/fficonfig.h +++ /dev/null @@ -1,150 +0,0 @@ -/* Manually created fficonfig.h for Darwin on PowerPC or Intel - - This file is manually generated to do away with the need for autoconf and - therefore make it easier to cross-compile and build fat binaries. - - NOTE: This file was added by PyObjC. -*/ - -#ifndef MACOSX -#error "This file is only supported on Mac OS X" -#endif - -#if defined(__i386__) -# define BYTEORDER 1234 -# undef HOST_WORDS_BIG_ENDIAN -# undef WORDS_BIGENDIAN -# define SIZEOF_DOUBLE 8 -# define HAVE_LONG_DOUBLE 1 -# define SIZEOF_LONG_DOUBLE 16 - -#elif defined(__x86_64__) -# define BYTEORDER 1234 -# undef HOST_WORDS_BIG_ENDIAN -# undef WORDS_BIGENDIAN -# define SIZEOF_DOUBLE 8 -# define HAVE_LONG_DOUBLE 1 -# define SIZEOF_LONG_DOUBLE 16 - -#elif defined(__ppc__) -# define BYTEORDER 4321 -# define HOST_WORDS_BIG_ENDIAN 1 -# define WORDS_BIGENDIAN 1 -# define SIZEOF_DOUBLE 8 -# if __GNUC__ >= 4 -# define HAVE_LONG_DOUBLE 1 -# define SIZEOF_LONG_DOUBLE 16 -# else -# undef HAVE_LONG_DOUBLE -# define SIZEOF_LONG_DOUBLE 8 -# endif - -#elif defined(__ppc64__) -# define BYTEORDER 4321 -# define HOST_WORDS_BIG_ENDIAN 1 -# define WORDS_BIGENDIAN 1 -# define SIZEOF_DOUBLE 8 -# define HAVE_LONG_DOUBLE 1 -# define SIZEOF_LONG_DOUBLE 16 - -#else -#error "Unknown CPU type" -#endif - -/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP - systems. This function is required for `alloca.c' support on those systems. */ -#undef CRAY_STACKSEG_END - -/* Define to 1 if using `alloca.c'. */ -/* #undef C_ALLOCA */ - -/* Define to the flags needed for the .section .eh_frame directive. */ -#define EH_FRAME_FLAGS "aw" - -/* Define this if you want extra debugging. */ -/* #undef FFI_DEBUG */ - -/* Define this is you do not want support for the raw API. */ -#define FFI_NO_RAW_API 1 - -/* Define this if you do not want support for aggregate types. */ -/* #undef FFI_NO_STRUCTS */ - -/* Define to 1 if you have `alloca', as a function or macro. */ -#define HAVE_ALLOCA 1 - -/* Define to 1 if you have and it should be used (not on Ultrix). */ -#define HAVE_ALLOCA_H 1 - -/* Define if your assembler supports .register. */ -/* #undef HAVE_AS_REGISTER_PSEUDO_OP */ - -/* Define if your assembler and linker support unaligned PC relative relocs. */ -/* #undef HAVE_AS_SPARC_UA_PCREL */ - -/* Define to 1 if you have the `memcpy' function. */ -#define HAVE_MEMCPY 1 - -/* Define if mmap with MAP_ANON(YMOUS) works. */ -#define HAVE_MMAP_ANON 1 - -/* Define if mmap of /dev/zero works. */ -/* #undef HAVE_MMAP_DEV_ZERO */ - -/* Define if read-only mmap of a plain file works. */ -#define HAVE_MMAP_FILE 1 - -/* Define if .eh_frame sections should be read-only. */ -/* #undef HAVE_RO_EH_FRAME */ - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - -/* Name of package */ -#define PACKAGE "libffi" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "http://gcc.gnu.org/bugs.html" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "libffi" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "libffi 2.1" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "libffi" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "2.1" - -/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at run-time. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ -/* #undef STACK_DIRECTION */ - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define this if you are using Purify and want to suppress spurious messages. */ -/* #undef USING_PURIFY */ - -/* Version number of package */ -#define VERSION "2.1-pyobjc" - -#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE -# ifdef LIBFFI_ASM -# define FFI_HIDDEN(name) .hidden name -# else -# define FFI_HIDDEN __attribute__((visibility ("hidden"))) -# endif -#else -# ifdef LIBFFI_ASM -# define FFI_HIDDEN(name) -# else -# define FFI_HIDDEN -# endif -#endif \ No newline at end of file diff --git a/Modules/_ctypes/libffi_osx/include/ffitarget.h b/Modules/_ctypes/libffi_osx/include/ffitarget.h deleted file mode 100644 index faaa30de6f6..00000000000 --- a/Modules/_ctypes/libffi_osx/include/ffitarget.h +++ /dev/null @@ -1,13 +0,0 @@ -/* Dispatch to the right ffitarget file. This file is PyObjC specific; in a - normal build, the build environment copies the file to the right location or - sets up the right include flags. We want to do neither because that would - make building fat binaries harder. -*/ - -#if defined(__i386__) || defined(__x86_64__) -#include "x86-ffitarget.h" -#elif defined(__ppc__) || defined(__ppc64__) -#include "ppc-ffitarget.h" -#else -#error "Unsupported CPU type" -#endif \ No newline at end of file diff --git a/Modules/_ctypes/libffi_osx/include/ppc-ffitarget.h b/Modules/_ctypes/libffi_osx/include/ppc-ffitarget.h deleted file mode 100644 index 23184219905..00000000000 --- a/Modules/_ctypes/libffi_osx/include/ppc-ffitarget.h +++ /dev/null @@ -1,104 +0,0 @@ -/* -----------------------------------------------------------------*-C-*- - ppc-ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. - Target configuration macros for PowerPC. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#ifndef LIBFFI_TARGET_H -#define LIBFFI_TARGET_H - -/* ---- System specific configurations ----------------------------------- */ - -#if (defined(POWERPC) && defined(__powerpc64__)) || \ - (defined(POWERPC_DARWIN) && defined(__ppc64__)) -#define POWERPC64 -#endif - -#ifndef LIBFFI_ASM - -typedef unsigned long ffi_arg; -typedef signed long ffi_sarg; - -typedef enum ffi_abi { - FFI_FIRST_ABI = 0, - -#ifdef POWERPC - FFI_SYSV, - FFI_GCC_SYSV, - FFI_LINUX64, -# ifdef POWERPC64 - FFI_DEFAULT_ABI = FFI_LINUX64, -# else - FFI_DEFAULT_ABI = FFI_GCC_SYSV, -# endif -#endif - -#ifdef POWERPC_AIX - FFI_AIX, - FFI_DARWIN, - FFI_DEFAULT_ABI = FFI_AIX, -#endif - -#ifdef POWERPC_DARWIN - FFI_AIX, - FFI_DARWIN, - FFI_DEFAULT_ABI = FFI_DARWIN, -#endif - -#ifdef POWERPC_FREEBSD - FFI_SYSV, - FFI_GCC_SYSV, - FFI_LINUX64, - FFI_DEFAULT_ABI = FFI_SYSV, -#endif - - FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 -} ffi_abi; - -#endif // #ifndef LIBFFI_ASM - -/* ---- Definitions for closures ----------------------------------------- */ - -#define FFI_CLOSURES 1 -#define FFI_NATIVE_RAW_API 0 - -/* Needed for FFI_SYSV small structure returns. */ -#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST) - -#if defined(POWERPC64) /*|| defined(POWERPC_AIX)*/ -# define FFI_TRAMPOLINE_SIZE 48 -#elif defined(POWERPC_AIX) -# define FFI_TRAMPOLINE_SIZE 24 -#else -# define FFI_TRAMPOLINE_SIZE 40 -#endif - -#ifndef LIBFFI_ASM -# if defined(POWERPC_DARWIN) || defined(POWERPC_AIX) -typedef struct ffi_aix_trampoline_struct { - void* code_pointer; /* Pointer to ffi_closure_ASM */ - void* toc; /* TOC */ - void* static_chain; /* Pointer to closure */ -} ffi_aix_trampoline_struct; -# endif -#endif // #ifndef LIBFFI_ASM - -#endif // #ifndef LIBFFI_TARGET_H \ No newline at end of file diff --git a/Modules/_ctypes/libffi_osx/include/x86-ffitarget.h b/Modules/_ctypes/libffi_osx/include/x86-ffitarget.h deleted file mode 100644 index 55c2b6c50cd..00000000000 --- a/Modules/_ctypes/libffi_osx/include/x86-ffitarget.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -----------------------------------------------------------------*-C-*- - x86-ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. - Target configuration macros for x86 and x86-64. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------- */ - -#ifndef LIBFFI_TARGET_H -#define LIBFFI_TARGET_H - -/* ---- System specific configurations ----------------------------------- */ - -#if defined(X86_64) && defined(__i386__) -# undef X86_64 -# define X86 -#endif - -#if defined(__x86_64__) -# ifndef X86_64 -# define X86_64 -# endif -#endif - -/* ---- Generic type definitions ----------------------------------------- */ - -#ifndef LIBFFI_ASM - -typedef unsigned long ffi_arg; -typedef signed long ffi_sarg; - -typedef enum ffi_abi { - FFI_FIRST_ABI = 0, - - /* ---- Intel x86 Win32 ---------- */ -#ifdef X86_WIN32 - FFI_SYSV, - FFI_STDCALL, - /* TODO: Add fastcall support for the sake of completeness */ - FFI_DEFAULT_ABI = FFI_SYSV, -#endif - - /* ---- Intel x86 and AMD x86-64 - */ -#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__)) - FFI_SYSV, - FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */ -# ifdef __i386__ - FFI_DEFAULT_ABI = FFI_SYSV, -# else - FFI_DEFAULT_ABI = FFI_UNIX64, -# endif -#endif - - FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 -} ffi_abi; - -#endif // #ifndef LIBFFI_ASM - -/* ---- Definitions for closures ----------------------------------------- */ - -#define FFI_CLOSURES 1 - -#if defined(X86_64) || (defined(__x86_64__) && defined(X86_DARWIN)) -# define FFI_TRAMPOLINE_SIZE 24 -# define FFI_NATIVE_RAW_API 0 -#else -# define FFI_TRAMPOLINE_SIZE 10 -# define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */ -#endif - -#endif // #ifndef LIBFFI_TARGET_H \ No newline at end of file diff --git a/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.S b/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.S deleted file mode 100644 index f143dbd28c3..00000000000 --- a/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.S +++ /dev/null @@ -1,365 +0,0 @@ -#if defined(__ppc__) || defined(__ppc64__) - -/* ----------------------------------------------------------------------- - ppc-darwin.S - Copyright (c) 2000 John Hornkvist - Copyright (c) 2004 Free Software Foundation, Inc. - - PowerPC Assembly glue. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM - -#include -#include -#include -#include - -.text - .align 2 -.globl _ffi_prep_args - -.text - .align 2 -.globl _ffi_call_DARWIN - -.text - .align 2 -_ffi_call_DARWIN: -LFB0: - mr r12,r8 /* We only need r12 until the call, - so it doesn't have to be saved. */ - -LFB1: - /* Save the old stack pointer as AP. */ - mr r8,r1 - -LCFI0: -#if defined(__ppc64__) - /* Allocate the stack space we need. - r4 (size of input data) - 48 bytes (linkage area) - 40 bytes (saved registers) - 8 bytes (extra FPR) - r4 + 96 bytes total - */ - - addi r4,r4,-96 // Add our overhead. - li r0,-32 // Align to 32 bytes. - and r4,r4,r0 -#endif - stgux r1,r1,r4 // Grow the stack. - mflr r9 - - /* Save registers we use. */ -#if defined(__ppc64__) - std r27,-40(r8) -#endif - stg r28,MODE_CHOICE(-16,-32)(r8) - stg r29,MODE_CHOICE(-12,-24)(r8) - stg r30,MODE_CHOICE(-8,-16)(r8) - stg r31,MODE_CHOICE(-4,-8)(r8) - stg r9,SF_RETURN(r8) /* return address */ -#if !defined(POWERPC_DARWIN) /* TOC unused in OS X */ - stg r2,MODE_CHOICE(20,40)(r1) -#endif - -LCFI1: -#if defined(__ppc64__) - mr r27,r3 // our extended_cif -#endif - /* Save arguments over call. */ - mr r31,r5 /* flags, */ - mr r30,r6 /* rvalue, */ - mr r29,r7 /* function address, */ - mr r28,r8 /* our AP. */ - -LCFI2: - /* Call ffi_prep_args. */ - mr r4,r1 - li r9,0 - mtctr r12 /* r12 holds address of _ffi_prep_args. */ - bctrl -#if !defined(POWERPC_DARWIN) /* TOC unused in OS X */ - lg r2,MODE_CHOICE(20,40)(r1) -#endif - - /* Now do the call. - Set up cr1 with bits 4-7 of the flags. */ - mtcrf 0x40,r31 - - /* Load all those argument registers. - We have set up a nice stack frame, just load it into registers. */ - lg r3,SF_ARG1(r1) - lg r4,SF_ARG2(r1) - lg r5,SF_ARG3(r1) - lg r6,SF_ARG4(r1) - nop - lg r7,SF_ARG5(r1) - lg r8,SF_ARG6(r1) - lg r9,SF_ARG7(r1) - lg r10,SF_ARG8(r1) - - /* Load all the FP registers. */ - bf 6,L2 /* No floats to load. */ -#if defined(__ppc64__) - lfd f1,MODE_CHOICE(-16,-40)-(14*8)(r28) - lfd f2,MODE_CHOICE(-16,-40)-(13*8)(r28) - lfd f3,MODE_CHOICE(-16,-40)-(12*8)(r28) - lfd f4,MODE_CHOICE(-16,-40)-(11*8)(r28) - nop - lfd f5,MODE_CHOICE(-16,-40)-(10*8)(r28) - lfd f6,MODE_CHOICE(-16,-40)-(9*8)(r28) - lfd f7,MODE_CHOICE(-16,-40)-(8*8)(r28) - lfd f8,MODE_CHOICE(-16,-40)-(7*8)(r28) - nop - lfd f9,MODE_CHOICE(-16,-40)-(6*8)(r28) - lfd f10,MODE_CHOICE(-16,-40)-(5*8)(r28) - lfd f11,MODE_CHOICE(-16,-40)-(4*8)(r28) - lfd f12,MODE_CHOICE(-16,-40)-(3*8)(r28) - nop - lfd f13,MODE_CHOICE(-16,-40)-(2*8)(r28) - lfd f14,MODE_CHOICE(-16,-40)-(1*8)(r28) -#elif defined(__ppc__) - lfd f1,MODE_CHOICE(-16,-40)-(13*8)(r28) - lfd f2,MODE_CHOICE(-16,-40)-(12*8)(r28) - lfd f3,MODE_CHOICE(-16,-40)-(11*8)(r28) - lfd f4,MODE_CHOICE(-16,-40)-(10*8)(r28) - nop - lfd f5,MODE_CHOICE(-16,-40)-(9*8)(r28) - lfd f6,MODE_CHOICE(-16,-40)-(8*8)(r28) - lfd f7,MODE_CHOICE(-16,-40)-(7*8)(r28) - lfd f8,MODE_CHOICE(-16,-40)-(6*8)(r28) - nop - lfd f9,MODE_CHOICE(-16,-40)-(5*8)(r28) - lfd f10,MODE_CHOICE(-16,-40)-(4*8)(r28) - lfd f11,MODE_CHOICE(-16,-40)-(3*8)(r28) - lfd f12,MODE_CHOICE(-16,-40)-(2*8)(r28) - nop - lfd f13,MODE_CHOICE(-16,-40)-(1*8)(r28) -#else -#error undefined architecture -#endif - -L2: - mr r12,r29 // Put the target address in r12 as specified. - mtctr r12 // Get the address to call into CTR. - nop - nop - bctrl // Make the call. - - // Deal with the return value. -#if defined(__ppc64__) - mtcrf 0x3,r31 // flags in cr6 and cr7 - bt 27,L(st_return_value) -#elif defined(__ppc__) - mtcrf 0x1,r31 // flags in cr7 -#else -#error undefined architecture -#endif - - bt 30,L(done_return_value) - bt 29,L(fp_return_value) - stg r3,0(r30) -#if defined(__ppc__) - bf 28,L(done_return_value) // Store the second long if necessary. - stg r4,4(r30) -#endif - // Fall through - -L(done_return_value): - lg r1,0(r1) // Restore stack pointer. - // Restore the registers we used. - lg r9,SF_RETURN(r1) // return address - lg r31,MODE_CHOICE(-4,-8)(r1) - mtlr r9 - lg r30,MODE_CHOICE(-8,-16)(r1) - lg r29,MODE_CHOICE(-12,-24)(r1) - lg r28,MODE_CHOICE(-16,-32)(r1) -#if defined(__ppc64__) - ld r27,-40(r1) -#endif - blr - -#if defined(__ppc64__) -L(st_return_value): - // Grow the stack enough to fit the registers. Leave room for 8 args - // to trample the 1st 8 slots in param area. - stgu r1,-SF_ROUND(280)(r1) // 64 + 104 + 48 + 64 - - // Store GPRs - std r3,SF_ARG9(r1) - std r4,SF_ARG10(r1) - std r5,SF_ARG11(r1) - std r6,SF_ARG12(r1) - nop - std r7,SF_ARG13(r1) - std r8,SF_ARG14(r1) - std r9,SF_ARG15(r1) - std r10,SF_ARG16(r1) - - // Store FPRs - nop - bf 26,L(call_struct_to_ram_form) - stfd f1,SF_ARG17(r1) - stfd f2,SF_ARG18(r1) - stfd f3,SF_ARG19(r1) - stfd f4,SF_ARG20(r1) - nop - stfd f5,SF_ARG21(r1) - stfd f6,SF_ARG22(r1) - stfd f7,SF_ARG23(r1) - stfd f8,SF_ARG24(r1) - nop - stfd f9,SF_ARG25(r1) - stfd f10,SF_ARG26(r1) - stfd f11,SF_ARG27(r1) - stfd f12,SF_ARG28(r1) - nop - stfd f13,SF_ARG29(r1) - -L(call_struct_to_ram_form): - ld r3,0(r27) // extended_cif->cif* - ld r3,16(r3) // ffi_cif->rtype* - addi r4,r1,SF_ARG9 // stored GPRs - addi r6,r1,SF_ARG17 // stored FPRs - li r5,0 // GPR size ptr (NULL) - li r7,0 // FPR size ptr (NULL) - li r8,0 // FPR count ptr (NULL) - li r10,0 // struct offset (NULL) - mr r9,r30 // return area - bl Lffi64_struct_to_ram_form$stub - lg r1,0(r1) // Restore stack pointer. - b L(done_return_value) -#endif - -L(fp_return_value): - /* Do we have long double to store? */ - bf 31,L(fd_return_value) - stfd f1,0(r30) - stfd f2,8(r30) - b L(done_return_value) - -L(fd_return_value): - /* Do we have double to store? */ - bf 28,L(float_return_value) - stfd f1,0(r30) - b L(done_return_value) - -L(float_return_value): - /* We only have a float to store. */ - stfs f1,0(r30) - b L(done_return_value) - -LFE1: -/* END(_ffi_call_DARWIN) */ - -/* Provide a null definition of _ffi_call_AIX. */ -.text - .align 2 -.globl _ffi_call_AIX -.text - .align 2 -_ffi_call_AIX: - blr -/* END(_ffi_call_AIX) */ - -.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms -EH_frame1: - .set L$set$0,LECIE1-LSCIE1 - .long L$set$0 ; Length of Common Information Entry -LSCIE1: - .long 0x0 ; CIE Identifier Tag - .byte 0x1 ; CIE Version - .ascii "zR\0" ; CIE Augmentation - .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor - .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor - .byte 0x41 ; CIE RA Column - .byte 0x1 ; uleb128 0x1; Augmentation size - .byte 0x10 ; FDE Encoding (pcrel) - .byte 0xc ; DW_CFA_def_cfa - .byte 0x1 ; uleb128 0x1 - .byte 0x0 ; uleb128 0x0 - .align LOG2_GPR_BYTES -LECIE1: -.globl _ffi_call_DARWIN.eh -_ffi_call_DARWIN.eh: -LSFDE1: - .set L$set$1,LEFDE1-LASFDE1 - .long L$set$1 ; FDE Length - -LASFDE1: - .long LASFDE1-EH_frame1 ; FDE CIE offset - .g_long LFB0-. ; FDE initial location - .set L$set$3,LFE1-LFB0 - .g_long L$set$3 ; FDE address range - .byte 0x0 ; uleb128 0x0; Augmentation size - .byte 0x4 ; DW_CFA_advance_loc4 - .set L$set$4,LCFI0-LFB1 - .long L$set$4 - .byte 0xd ; DW_CFA_def_cfa_register - .byte 0x08 ; uleb128 0x08 - .byte 0x4 ; DW_CFA_advance_loc4 - .set L$set$5,LCFI1-LCFI0 - .long L$set$5 - .byte 0x11 ; DW_CFA_offset_extended_sf - .byte 0x41 ; uleb128 0x41 - .byte 0x7e ; sleb128 -2 - .byte 0x9f ; DW_CFA_offset, column 0x1f - .byte 0x1 ; uleb128 0x1 - .byte 0x9e ; DW_CFA_offset, column 0x1e - .byte 0x2 ; uleb128 0x2 - .byte 0x9d ; DW_CFA_offset, column 0x1d - .byte 0x3 ; uleb128 0x3 - .byte 0x9c ; DW_CFA_offset, column 0x1c - .byte 0x4 ; uleb128 0x4 - .byte 0x4 ; DW_CFA_advance_loc4 - .set L$set$6,LCFI2-LCFI1 - .long L$set$6 - .byte 0xd ; DW_CFA_def_cfa_register - .byte 0x1c ; uleb128 0x1c - .align LOG2_GPR_BYTES -LEFDE1: - -#if defined(__ppc64__) -.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 - .align LOG2_GPR_BYTES - -Lffi64_struct_to_ram_form$stub: - .indirect_symbol _ffi64_struct_to_ram_form - mflr r0 - bcl 20,31,LO$ffi64_struct_to_ram_form - -LO$ffi64_struct_to_ram_form: - mflr r11 - addis r11,r11,ha16(L_ffi64_struct_to_ram_form$lazy_ptr - LO$ffi64_struct_to_ram_form) - mtlr r0 - lgu r12,lo16(L_ffi64_struct_to_ram_form$lazy_ptr - LO$ffi64_struct_to_ram_form)(r11) - mtctr r12 - bctr - -.lazy_symbol_pointer -L_ffi64_struct_to_ram_form$lazy_ptr: - .indirect_symbol _ffi64_struct_to_ram_form - .g_long dyld_stub_binding_helper - -#endif // __ppc64__ -#endif // __ppc__ || __ppc64__ diff --git a/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.h b/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.h deleted file mode 100644 index cf4bd50f93c..00000000000 --- a/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.h +++ /dev/null @@ -1,85 +0,0 @@ -/* ----------------------------------------------------------------------- - ppc-darwin.h - Copyright (c) 2002, 2003, 2004, Free Software Foundation, - Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define L(x) x - -#define SF_ARG9 MODE_CHOICE(56,112) -#define SF_ARG10 MODE_CHOICE(60,120) -#define SF_ARG11 MODE_CHOICE(64,128) -#define SF_ARG12 MODE_CHOICE(68,136) -#define SF_ARG13 MODE_CHOICE(72,144) -#define SF_ARG14 MODE_CHOICE(76,152) -#define SF_ARG15 MODE_CHOICE(80,160) -#define SF_ARG16 MODE_CHOICE(84,168) -#define SF_ARG17 MODE_CHOICE(88,176) -#define SF_ARG18 MODE_CHOICE(92,184) -#define SF_ARG19 MODE_CHOICE(96,192) -#define SF_ARG20 MODE_CHOICE(100,200) -#define SF_ARG21 MODE_CHOICE(104,208) -#define SF_ARG22 MODE_CHOICE(108,216) -#define SF_ARG23 MODE_CHOICE(112,224) -#define SF_ARG24 MODE_CHOICE(116,232) -#define SF_ARG25 MODE_CHOICE(120,240) -#define SF_ARG26 MODE_CHOICE(124,248) -#define SF_ARG27 MODE_CHOICE(128,256) -#define SF_ARG28 MODE_CHOICE(132,264) -#define SF_ARG29 MODE_CHOICE(136,272) - -#define ASM_NEEDS_REGISTERS 4 -#define NUM_GPR_ARG_REGISTERS 8 -#define NUM_FPR_ARG_REGISTERS 13 - -#define FFI_TYPE_1_BYTE(x) ((x) == FFI_TYPE_UINT8 || (x) == FFI_TYPE_SINT8) -#define FFI_TYPE_2_BYTE(x) ((x) == FFI_TYPE_UINT16 || (x) == FFI_TYPE_SINT16) -#define FFI_TYPE_4_BYTE(x) \ - ((x) == FFI_TYPE_UINT32 || (x) == FFI_TYPE_SINT32 ||\ - (x) == FFI_TYPE_INT || (x) == FFI_TYPE_FLOAT) - -#if !defined(LIBFFI_ASM) - -enum { - FLAG_RETURNS_NOTHING = 1 << (31 - 30), // cr7 - FLAG_RETURNS_FP = 1 << (31 - 29), - FLAG_RETURNS_64BITS = 1 << (31 - 28), - FLAG_RETURNS_128BITS = 1 << (31 - 31), - - FLAG_RETURNS_STRUCT = 1 << (31 - 27), // cr6 - FLAG_STRUCT_CONTAINS_FP = 1 << (31 - 26), - - FLAG_ARG_NEEDS_COPY = 1 << (31 - 7), - FLAG_FP_ARGUMENTS = 1 << (31 - 6), // cr1.eq; specified by ABI - FLAG_4_GPR_ARGUMENTS = 1 << (31 - 5), - FLAG_RETVAL_REFERENCE = 1 << (31 - 4) -}; - -#if defined(__ppc64__) -void ffi64_struct_to_ram_form(const ffi_type*, const char*, unsigned int*, - const char*, unsigned int*, unsigned int*, char*, unsigned int*); -void ffi64_struct_to_reg_form(const ffi_type*, const char*, unsigned int*, - unsigned int*, char*, unsigned int*, char*, unsigned int*); -bool ffi64_stret_needs_ptr(const ffi_type* inType, - unsigned short*, unsigned short*); -#endif - -#endif // !defined(LIBFFI_ASM) \ No newline at end of file diff --git a/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin_closure.S b/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin_closure.S deleted file mode 100644 index c3d30c25254..00000000000 --- a/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin_closure.S +++ /dev/null @@ -1,308 +0,0 @@ -#if defined(__ppc__) - -/* ----------------------------------------------------------------------- - ppc-darwin_closure.S - Copyright (c) 2002, 2003, 2004, Free Software Foundation, - Inc. based on ppc_closure.S - - PowerPC Assembly glue. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM - -#include -#include // for FFI_TRAMPOLINE_SIZE -#include -#include - - .file "ppc-darwin_closure.S" -.text - .align LOG2_GPR_BYTES - .globl _ffi_closure_ASM - -.text - .align LOG2_GPR_BYTES - -_ffi_closure_ASM: -LFB1: - mflr r0 // Save return address - stg r0,SF_RETURN(r1) - -LCFI0: - /* 24/48 bytes (Linkage Area) - 32/64 bytes (outgoing parameter area, always reserved) - 104 bytes (13*8 from FPR) - 16/32 bytes (result) - 176/232 total bytes */ - - /* skip over caller save area and keep stack aligned to 16/32. */ - stgu r1,-SF_ROUND(176)(r1) - -LCFI1: - /* We want to build up an area for the parameters passed - in registers. (both floating point and integer) */ - - /* 176/256 bytes (callee stack frame aligned to 16/32) - 24/48 bytes (caller linkage area) - 200/304 (start of caller parameter area aligned to 4/8) - */ - - /* Save GPRs 3 - 10 (aligned to 4/8) - in the parents outgoing area. */ - stg r3,200(r1) - stg r4,204(r1) - stg r5,208(r1) - stg r6,212(r1) - stg r7,216(r1) - stg r8,220(r1) - stg r9,224(r1) - stg r10,228(r1) - - /* Save FPRs 1 - 13. (aligned to 8) */ - stfd f1,56(r1) - stfd f2,64(r1) - stfd f3,72(r1) - stfd f4,80(r1) - stfd f5,88(r1) - stfd f6,96(r1) - stfd f7,104(r1) - stfd f8,112(r1) - stfd f9,120(r1) - stfd f10,128(r1) - stfd f11,136(r1) - stfd f12,144(r1) - stfd f13,152(r1) - - // Set up registers for the routine that actually does the work. - mr r3,r11 // context pointer from the trampoline - addi r4,r1,160 // result storage - addi r5,r1,200 // saved GPRs - addi r6,r1,56 // saved FPRs - bl Lffi_closure_helper_DARWIN$stub - - /* Now r3 contains the return type. Use it to look up in a table - so we know how to deal with each type. */ - addi r5,r1,160 // Copy result storage pointer. - bl Lget_ret_type0_addr // Get pointer to Lret_type0 into LR. - mflr r4 // Move to r4. - slwi r3,r3,4 // Multiply return type by 16. - add r3,r3,r4 // Add contents of table to table address. - mtctr r3 - bctr - -LFE1: -/* Each of the ret_typeX code fragments has to be exactly 16 bytes long - (4 instructions). For cache effectiveness we align to a 16 byte boundary - first. */ - .align 4 - nop - nop - nop - -Lget_ret_type0_addr: - blrl - -/* case FFI_TYPE_VOID */ -Lret_type0: - b Lfinish - nop - nop - nop - -/* case FFI_TYPE_INT */ -Lret_type1: - lwz r3,0(r5) - b Lfinish - nop - nop - -/* case FFI_TYPE_FLOAT */ -Lret_type2: - lfs f1,0(r5) - b Lfinish - nop - nop - -/* case FFI_TYPE_DOUBLE */ -Lret_type3: - lfd f1,0(r5) - b Lfinish - nop - nop - -/* case FFI_TYPE_LONGDOUBLE */ -Lret_type4: - lfd f1,0(r5) - lfd f2,8(r5) - b Lfinish - nop - -/* case FFI_TYPE_UINT8 */ -Lret_type5: - lbz r3,3(r5) - b Lfinish - nop - nop - -/* case FFI_TYPE_SINT8 */ -Lret_type6: - lbz r3,3(r5) - extsb r3,r3 - b Lfinish - nop - -/* case FFI_TYPE_UINT16 */ -Lret_type7: - lhz r3,2(r5) - b Lfinish - nop - nop - -/* case FFI_TYPE_SINT16 */ -Lret_type8: - lha r3,2(r5) - b Lfinish - nop - nop - -/* case FFI_TYPE_UINT32 */ -Lret_type9: // same as Lret_type1 - lwz r3,0(r5) - b Lfinish - nop - nop - -/* case FFI_TYPE_SINT32 */ -Lret_type10: // same as Lret_type1 - lwz r3,0(r5) - b Lfinish - nop - nop - -/* case FFI_TYPE_UINT64 */ -Lret_type11: - lwz r3,0(r5) - lwz r4,4(r5) - b Lfinish - nop - -/* case FFI_TYPE_SINT64 */ -Lret_type12: // same as Lret_type11 - lwz r3,0(r5) - lwz r4,4(r5) - b Lfinish - nop - -/* case FFI_TYPE_STRUCT */ -Lret_type13: - b Lfinish - nop - nop - nop - -/* End 16-byte aligned cases */ -/* case FFI_TYPE_POINTER */ -// This case assumes that FFI_TYPE_POINTER == FFI_TYPE_LAST. If more types -// are added in future, the following code will need to be updated and -// padded to 16 bytes. -Lret_type14: - lg r3,0(r5) - // fall through - -/* case done */ -Lfinish: - addi r1,r1,SF_ROUND(176) // Restore stack pointer. - lg r0,SF_RETURN(r1) // Restore return address. - mtlr r0 // Restore link register. - blr - -/* END(ffi_closure_ASM) */ - -.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support -EH_frame1: - .set L$set$0,LECIE1-LSCIE1 - .long L$set$0 ; Length of Common Information Entry -LSCIE1: - .long 0x0 ; CIE Identifier Tag - .byte 0x1 ; CIE Version - .ascii "zR\0" ; CIE Augmentation - .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor - .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor - .byte 0x41 ; CIE RA Column - .byte 0x1 ; uleb128 0x1; Augmentation size - .byte 0x10 ; FDE Encoding (pcrel) - .byte 0xc ; DW_CFA_def_cfa - .byte 0x1 ; uleb128 0x1 - .byte 0x0 ; uleb128 0x0 - .align LOG2_GPR_BYTES -LECIE1: -.globl _ffi_closure_ASM.eh -_ffi_closure_ASM.eh: -LSFDE1: - .set L$set$1,LEFDE1-LASFDE1 - .long L$set$1 ; FDE Length - -LASFDE1: - .long LASFDE1-EH_frame1 ; FDE CIE offset - .g_long LFB1-. ; FDE initial location - .set L$set$3,LFE1-LFB1 - .g_long L$set$3 ; FDE address range - .byte 0x0 ; uleb128 0x0; Augmentation size - .byte 0x4 ; DW_CFA_advance_loc4 - .set L$set$3,LCFI1-LCFI0 - .long L$set$3 - .byte 0xe ; DW_CFA_def_cfa_offset - .byte 176,1 ; uleb128 176 - .byte 0x4 ; DW_CFA_advance_loc4 - .set L$set$4,LCFI0-LFB1 - .long L$set$4 - .byte 0x11 ; DW_CFA_offset_extended_sf - .byte 0x41 ; uleb128 0x41 - .byte 0x7e ; sleb128 -2 - .align LOG2_GPR_BYTES - -LEFDE1: -.data - .align LOG2_GPR_BYTES -LDFCM0: -.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 - .align LOG2_GPR_BYTES - -Lffi_closure_helper_DARWIN$stub: - .indirect_symbol _ffi_closure_helper_DARWIN - mflr r0 - bcl 20,31,LO$ffi_closure_helper_DARWIN - -LO$ffi_closure_helper_DARWIN: - mflr r11 - addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN) - mtlr r0 - lgu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)(r11) - mtctr r12 - bctr - -.lazy_symbol_pointer -L_ffi_closure_helper_DARWIN$lazy_ptr: - .indirect_symbol _ffi_closure_helper_DARWIN - .g_long dyld_stub_binding_helper - - -#endif // __ppc__ diff --git a/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c b/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c deleted file mode 100644 index 8953d5fda35..00000000000 --- a/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c +++ /dev/null @@ -1,1776 +0,0 @@ -#if defined(__ppc__) || defined(__ppc64__) - -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1998 Geoffrey Keating - - PowerPC Foreign Function Interface - - Darwin ABI support (c) 2001 John Hornkvist - AIX ABI support (c) 2002 Free Software Foundation, Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -#include -#include -#include -#include -#include - -#if 0 -#if defined(POWERPC_DARWIN) -#include // for sys_icache_invalidate() -#endif - -#else - -#pragma weak sys_icache_invalidate -extern void sys_icache_invalidate(void *start, size_t len); - -#endif - - -extern void ffi_closure_ASM(void); - -// The layout of a function descriptor. A C function pointer really -// points to one of these. -typedef struct aix_fd_struct { - void* code_pointer; - void* toc; -} aix_fd; - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments. - - The stack layout we want looks like this: - - | Return address from ffi_call_DARWIN | higher addresses - |--------------------------------------------| - | Previous backchain pointer 4/8 | stack pointer here - |--------------------------------------------|-\ <<< on entry to - | Saved r28-r31 (4/8)*4 | | ffi_call_DARWIN - |--------------------------------------------| | - | Parameters (at least 8*(4/8)=32/64) | | (176) +112 - +288 - |--------------------------------------------| | - | Space for GPR2 4/8 | | - |--------------------------------------------| | stack | - | Reserved (4/8)*2 | | grows | - |--------------------------------------------| | down V - | Space for callee's LR 4/8 | | - |--------------------------------------------| | lower addresses - | Saved CR 4/8 | | - |--------------------------------------------| | stack pointer here - | Current backchain pointer 4/8 | | during - |--------------------------------------------|-/ <<< ffi_call_DARWIN - - Note: ppc64 CR is saved in the low word of a long on the stack. -*/ - -/*@-exportheader@*/ -void -ffi_prep_args( - extended_cif* inEcif, - unsigned *const stack) -/*@=exportheader@*/ -{ - /* Copy the ecif to a local var so we can trample the arg. - BC note: test this with GP later for possible problems... */ - volatile extended_cif* ecif = inEcif; - - const unsigned bytes = ecif->cif->bytes; - const unsigned flags = ecif->cif->flags; - - /* Cast the stack arg from int* to long*. sizeof(long) == 4 in 32-bit mode - and 8 in 64-bit mode. */ - unsigned long *const longStack = (unsigned long *const)stack; - - /* 'stacktop' points at the previous backchain pointer. */ -#if defined(__ppc64__) - // In ppc-darwin.s, an extra 96 bytes is reserved for the linkage area, - // saved registers, and an extra FPR. - unsigned long *const stacktop = - (unsigned long *)(unsigned long)((char*)longStack + bytes + 96); -#elif defined(__ppc__) - unsigned long *const stacktop = longStack + (bytes / sizeof(long)); -#else -#error undefined architecture -#endif - - /* 'fpr_base' points at the space for fpr1, and grows upwards as - we use FPR registers. */ - double* fpr_base = (double*)(stacktop - ASM_NEEDS_REGISTERS) - - NUM_FPR_ARG_REGISTERS; - -#if defined(__ppc64__) - // 64-bit saves an extra register, and uses an extra FPR. Knock fpr_base - // down a couple pegs. - fpr_base -= 2; -#endif - - unsigned int fparg_count = 0; - - /* 'next_arg' grows up as we put parameters in it. */ - unsigned long* next_arg = longStack + 6; /* 6 reserved positions. */ - - int i; - double double_tmp; - void** p_argv = ecif->avalue; - unsigned long gprvalue; - ffi_type** ptr = ecif->cif->arg_types; - - /* Check that everything starts aligned properly. */ - FFI_ASSERT(stack == SF_ROUND(stack)); - FFI_ASSERT(stacktop == SF_ROUND(stacktop)); - FFI_ASSERT(bytes == SF_ROUND(bytes)); - - /* Deal with return values that are actually pass-by-reference. - Rule: - Return values are referenced by r3, so r4 is the first parameter. */ - - if (flags & FLAG_RETVAL_REFERENCE) - *next_arg++ = (unsigned long)(char*)ecif->rvalue; - - /* Now for the arguments. */ - for (i = ecif->cif->nargs; i > 0; i--, ptr++, p_argv++) - { - switch ((*ptr)->type) - { - /* If a floating-point parameter appears before all of the general- - purpose registers are filled, the corresponding GPRs that match - the size of the floating-point parameter are shadowed for the - benefit of vararg and pre-ANSI functions. */ - case FFI_TYPE_FLOAT: - double_tmp = *(float*)*p_argv; - - if (fparg_count < NUM_FPR_ARG_REGISTERS) - *fpr_base++ = double_tmp; - - *(double*)next_arg = double_tmp; - - next_arg++; - fparg_count++; - FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); - - break; - - case FFI_TYPE_DOUBLE: - double_tmp = *(double*)*p_argv; - - if (fparg_count < NUM_FPR_ARG_REGISTERS) - *fpr_base++ = double_tmp; - - *(double*)next_arg = double_tmp; - - next_arg += MODE_CHOICE(2,1); - fparg_count++; - FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); - - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: -#if defined(__ppc64__) - if (fparg_count < NUM_FPR_ARG_REGISTERS) - *(long double*)fpr_base = *(long double*)*p_argv; -#elif defined(__ppc__) - if (fparg_count < NUM_FPR_ARG_REGISTERS - 1) - *(long double*)fpr_base = *(long double*)*p_argv; - else if (fparg_count == NUM_FPR_ARG_REGISTERS - 1) - *(double*)fpr_base = *(double*)*p_argv; -#else -#error undefined architecture -#endif - - *(long double*)next_arg = *(long double*)*p_argv; - fparg_count += 2; - fpr_base += 2; - next_arg += MODE_CHOICE(4,2); - FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); - - break; -#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: -#if defined(__ppc64__) - gprvalue = *(long long*)*p_argv; - goto putgpr; -#elif defined(__ppc__) - *(long long*)next_arg = *(long long*)*p_argv; - next_arg += 2; - break; -#else -#error undefined architecture -#endif - - case FFI_TYPE_POINTER: - gprvalue = *(unsigned long*)*p_argv; - goto putgpr; - - case FFI_TYPE_UINT8: - gprvalue = *(unsigned char*)*p_argv; - goto putgpr; - - case FFI_TYPE_SINT8: - gprvalue = *(signed char*)*p_argv; - goto putgpr; - - case FFI_TYPE_UINT16: - gprvalue = *(unsigned short*)*p_argv; - goto putgpr; - - case FFI_TYPE_SINT16: - gprvalue = *(signed short*)*p_argv; - goto putgpr; - - case FFI_TYPE_STRUCT: - { -#if defined(__ppc64__) - unsigned int gprSize = 0; - unsigned int fprSize = 0; - - ffi64_struct_to_reg_form(*ptr, (char*)*p_argv, NULL, &fparg_count, - (char*)next_arg, &gprSize, (char*)fpr_base, &fprSize); - next_arg += gprSize / sizeof(long); - fpr_base += fprSize / sizeof(double); - -#elif defined(__ppc__) - char* dest_cpy = (char*)next_arg; - - /* Structures that match the basic modes (QI 1 byte, HI 2 bytes, - SI 4 bytes) are aligned as if they were those modes. - Structures with 3 byte in size are padded upwards. */ - unsigned size_al = (*ptr)->size; - - /* If the first member of the struct is a double, then align - the struct to double-word. */ - if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE) - size_al = ALIGN((*ptr)->size, 8); - - if (ecif->cif->abi == FFI_DARWIN) - { - if (size_al < 3) - dest_cpy += 4 - size_al; - } - - memcpy((char*)dest_cpy, (char*)*p_argv, size_al); - next_arg += (size_al + 3) / 4; -#else -#error undefined architecture -#endif - break; - } - - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - gprvalue = *(unsigned*)*p_argv; - -putgpr: - *next_arg++ = gprvalue; - break; - - default: - break; - } - } - - /* Check that we didn't overrun the stack... */ - //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS); - //FFI_ASSERT((unsigned *)fpr_base - // <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); - //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); -} - -#if defined(__ppc64__) - -bool -ffi64_struct_contains_fp( - const ffi_type* inType) -{ - bool containsFP = false; - unsigned int i; - - for (i = 0; inType->elements[i] != NULL && !containsFP; i++) - { - if (inType->elements[i]->type == FFI_TYPE_FLOAT || - inType->elements[i]->type == FFI_TYPE_DOUBLE || - inType->elements[i]->type == FFI_TYPE_LONGDOUBLE) - containsFP = true; - else if (inType->elements[i]->type == FFI_TYPE_STRUCT) - containsFP = ffi64_struct_contains_fp(inType->elements[i]); - } - - return containsFP; -} - -#endif // defined(__ppc64__) - -/* Perform machine dependent cif processing. */ -ffi_status -ffi_prep_cif_machdep( - ffi_cif* cif) -{ - /* All this is for the DARWIN ABI. */ - int i; - ffi_type** ptr; - int intarg_count = 0; - int fparg_count = 0; - unsigned int flags = 0; - unsigned int size_al = 0; - - /* All the machine-independent calculation of cif->bytes will be wrong. - Redo the calculation for DARWIN. */ - - /* Space for the frame pointer, callee's LR, CR, etc, and for - the asm's temp regs. */ - unsigned int bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long); - - /* Return value handling. The rules are as follows: - - 32-bit (or less) integer values are returned in gpr3; - - Structures of size <= 4 bytes also returned in gpr3; - - 64-bit integer values and structures between 5 and 8 bytes are - returned in gpr3 and gpr4; - - Single/double FP values are returned in fpr1; - - Long double FP (if not equivalent to double) values are returned in - fpr1 and fpr2; - - Larger structures values are allocated space and a pointer is passed - as the first argument. */ - switch (cif->rtype->type) - { -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - flags |= FLAG_RETURNS_128BITS; - flags |= FLAG_RETURNS_FP; - break; -#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - - case FFI_TYPE_DOUBLE: - flags |= FLAG_RETURNS_64BITS; - /* Fall through. */ - case FFI_TYPE_FLOAT: - flags |= FLAG_RETURNS_FP; - break; - -#if defined(__ppc64__) - case FFI_TYPE_POINTER: -#endif - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - flags |= FLAG_RETURNS_64BITS; - break; - - case FFI_TYPE_STRUCT: - { -#if defined(__ppc64__) - - if (ffi64_stret_needs_ptr(cif->rtype, NULL, NULL)) - { - flags |= FLAG_RETVAL_REFERENCE; - flags |= FLAG_RETURNS_NOTHING; - intarg_count++; - } - else - { - flags |= FLAG_RETURNS_STRUCT; - - if (ffi64_struct_contains_fp(cif->rtype)) - flags |= FLAG_STRUCT_CONTAINS_FP; - } - -#elif defined(__ppc__) - - flags |= FLAG_RETVAL_REFERENCE; - flags |= FLAG_RETURNS_NOTHING; - intarg_count++; - -#else -#error undefined architecture -#endif - break; - } - - case FFI_TYPE_VOID: - flags |= FLAG_RETURNS_NOTHING; - break; - - default: - /* Returns 32-bit integer, or similar. Nothing to do here. */ - break; - } - - /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the - first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest - goes on the stack. Structures are passed as a pointer to a copy of - the structure. Stuff on the stack needs to keep proper alignment. */ - for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) - { - switch ((*ptr)->type) - { - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - fparg_count++; - /* If this FP arg is going on the stack, it must be - 8-byte-aligned. */ - if (fparg_count > NUM_FPR_ARG_REGISTERS - && intarg_count % 2 != 0) - intarg_count++; - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - fparg_count += 2; - /* If this FP arg is going on the stack, it must be - 8-byte-aligned. */ - - if ( -#if defined(__ppc64__) - fparg_count > NUM_FPR_ARG_REGISTERS + 1 -#elif defined(__ppc__) - fparg_count > NUM_FPR_ARG_REGISTERS -#else -#error undefined architecture -#endif - && intarg_count % 2 != 0) - intarg_count++; - - intarg_count += 2; - break; -#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - /* 'long long' arguments are passed as two words, but - either both words must fit in registers or both go - on the stack. If they go on the stack, they must - be 8-byte-aligned. */ - if (intarg_count == NUM_GPR_ARG_REGISTERS - 1 - || (intarg_count >= NUM_GPR_ARG_REGISTERS - && intarg_count % 2 != 0)) - intarg_count++; - - intarg_count += MODE_CHOICE(2,1); - - break; - - case FFI_TYPE_STRUCT: - size_al = (*ptr)->size; - /* If the first member of the struct is a double, then align - the struct to double-word. */ - if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE) - size_al = ALIGN((*ptr)->size, 8); - -#if defined(__ppc64__) - // Look for FP struct members. - unsigned int j; - - for (j = 0; (*ptr)->elements[j] != NULL; j++) - { - if ((*ptr)->elements[j]->type == FFI_TYPE_FLOAT || - (*ptr)->elements[j]->type == FFI_TYPE_DOUBLE) - { - fparg_count++; - - if (fparg_count > NUM_FPR_ARG_REGISTERS) - intarg_count++; - } - else if ((*ptr)->elements[j]->type == FFI_TYPE_LONGDOUBLE) - { - fparg_count += 2; - - if (fparg_count > NUM_FPR_ARG_REGISTERS + 1) - intarg_count += 2; - } - else - intarg_count++; - } -#elif defined(__ppc__) - intarg_count += (size_al + 3) / 4; -#else -#error undefined architecture -#endif - - break; - - default: - /* Everything else is passed as a 4/8-byte word in a GPR, either - the object itself or a pointer to it. */ - intarg_count++; - break; - } - } - - /* Space for the FPR registers, if needed. */ - if (fparg_count != 0) - { - flags |= FLAG_FP_ARGUMENTS; -#if defined(__ppc64__) - bytes += (NUM_FPR_ARG_REGISTERS + 1) * sizeof(double); -#elif defined(__ppc__) - bytes += NUM_FPR_ARG_REGISTERS * sizeof(double); -#else -#error undefined architecture -#endif - } - - /* Stack space. */ -#if defined(__ppc64__) - if ((intarg_count + fparg_count) > NUM_GPR_ARG_REGISTERS) - bytes += (intarg_count + fparg_count) * sizeof(long); -#elif defined(__ppc__) - if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS) - bytes += (intarg_count + 2 * fparg_count) * sizeof(long); -#else -#error undefined architecture -#endif - else - bytes += NUM_GPR_ARG_REGISTERS * sizeof(long); - - /* The stack space allocated needs to be a multiple of 16/32 bytes. */ - bytes = SF_ROUND(bytes); - - cif->flags = flags; - cif->bytes = bytes; - - return FFI_OK; -} - -/*@-declundef@*/ -/*@-exportheader@*/ -extern void -ffi_call_AIX( -/*@out@*/ extended_cif*, - unsigned, - unsigned, -/*@out@*/ unsigned*, - void (*fn)(void), - void (*fn2)(extended_cif*, unsigned *const)); - -extern void -ffi_call_DARWIN( -/*@out@*/ extended_cif*, - unsigned long, - unsigned, -/*@out@*/ unsigned*, - void (*fn)(void), - void (*fn2)(extended_cif*, unsigned *const)); -/*@=declundef@*/ -/*@=exportheader@*/ - -void -ffi_call( -/*@dependent@*/ ffi_cif* cif, - void (*fn)(void), -/*@out@*/ void* rvalue, -/*@dependent@*/ void** avalue) -{ - extended_cif ecif; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return - value address then we need to make one. */ - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) - { - /*@-sysunrecog@*/ - ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ - } - else - ecif.rvalue = rvalue; - - switch (cif->abi) - { - case FFI_AIX: - /*@-usedef@*/ - ffi_call_AIX(&ecif, -cif->bytes, - cif->flags, ecif.rvalue, fn, ffi_prep_args); - /*@=usedef@*/ - break; - - case FFI_DARWIN: - /*@-usedef@*/ - ffi_call_DARWIN(&ecif, -(long)cif->bytes, - cif->flags, ecif.rvalue, fn, ffi_prep_args); - /*@=usedef@*/ - break; - - default: - FFI_ASSERT(0); - break; - } -} - -/* here I'd like to add the stack frame layout we use in darwin_closure.S - and aix_clsoure.S - - SP previous -> +---------------------------------------+ <--- child frame - | back chain to caller 4 | - +---------------------------------------+ 4 - | saved CR 4 | - +---------------------------------------+ 8 - | saved LR 4 | - +---------------------------------------+ 12 - | reserved for compilers 4 | - +---------------------------------------+ 16 - | reserved for binders 4 | - +---------------------------------------+ 20 - | saved TOC pointer 4 | - +---------------------------------------+ 24 - | always reserved 8*4=32 (previous GPRs)| - | according to the linkage convention | - | from AIX | - +---------------------------------------+ 56 - | our FPR area 13*8=104 | - | f1 | - | . | - | f13 | - +---------------------------------------+ 160 - | result area 8 | - +---------------------------------------+ 168 - | alignement to the next multiple of 16 | -SP current --> +---------------------------------------+ 176 <- parent frame - | back chain to caller 4 | - +---------------------------------------+ 180 - | saved CR 4 | - +---------------------------------------+ 184 - | saved LR 4 | - +---------------------------------------+ 188 - | reserved for compilers 4 | - +---------------------------------------+ 192 - | reserved for binders 4 | - +---------------------------------------+ 196 - | saved TOC pointer 4 | - +---------------------------------------+ 200 - | always reserved 8*4=32 we store our | - | GPRs here | - | r3 | - | . | - | r10 | - +---------------------------------------+ 232 - | overflow part | - +---------------------------------------+ xxx - | ???? | - +---------------------------------------+ xxx -*/ - -#if !defined(POWERPC_DARWIN) - -#define MIN_LINE_SIZE 32 - -static void -flush_icache( - char* addr) -{ -#ifndef _AIX - __asm__ volatile ( - "dcbf 0,%0\n" - "sync\n" - "icbi 0,%0\n" - "sync\n" - "isync" - : : "r" (addr) : "memory"); -#endif -} - -static void -flush_range( - char* addr, - int size) -{ - int i; - - for (i = 0; i < size; i += MIN_LINE_SIZE) - flush_icache(addr + i); - - flush_icache(addr + size - 1); -} - -#endif // !defined(POWERPC_DARWIN) - -ffi_status -ffi_prep_closure( - ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void* user_data) -{ - switch (cif->abi) - { - case FFI_DARWIN: - { - FFI_ASSERT (cif->abi == FFI_DARWIN); - - unsigned int* tramp = (unsigned int*)&closure->tramp[0]; - -#if defined(__ppc64__) - tramp[0] = 0x7c0802a6; // mflr r0 - tramp[1] = 0x429f0005; // bcl 20,31,+0x8 - tramp[2] = 0x7d6802a6; // mflr r11 - tramp[3] = 0x7c0803a6; // mtlr r0 - tramp[4] = 0xe98b0018; // ld r12,24(r11) - tramp[5] = 0x7d8903a6; // mtctr r12 - tramp[6] = 0xe96b0020; // ld r11,32(r11) - tramp[7] = 0x4e800420; // bctr - *(unsigned long*)&tramp[8] = (unsigned long)ffi_closure_ASM; - *(unsigned long*)&tramp[10] = (unsigned long)closure; -#elif defined(__ppc__) - tramp[0] = 0x7c0802a6; // mflr r0 - tramp[1] = 0x429f0005; // bcl 20,31,+0x8 - tramp[2] = 0x7d6802a6; // mflr r11 - tramp[3] = 0x7c0803a6; // mtlr r0 - tramp[4] = 0x818b0018; // lwz r12,24(r11) - tramp[5] = 0x7d8903a6; // mtctr r12 - tramp[6] = 0x816b001c; // lwz r11,28(r11) - tramp[7] = 0x4e800420; // bctr - tramp[8] = (unsigned long)ffi_closure_ASM; - tramp[9] = (unsigned long)closure; -#else -#error undefined architecture -#endif - - closure->cif = cif; - closure->fun = fun; - closure->user_data = user_data; - - // Flush the icache. Only necessary on Darwin. -#if defined(POWERPC_DARWIN) - sys_icache_invalidate(closure->tramp, FFI_TRAMPOLINE_SIZE); -#else - flush_range(closure->tramp, FFI_TRAMPOLINE_SIZE); -#endif - - break; - } - - case FFI_AIX: - { - FFI_ASSERT (cif->abi == FFI_AIX); - - ffi_aix_trampoline_struct* tramp_aix = - (ffi_aix_trampoline_struct*)(closure->tramp); - aix_fd* fd = (aix_fd*)(void*)ffi_closure_ASM; - - tramp_aix->code_pointer = fd->code_pointer; - tramp_aix->toc = fd->toc; - tramp_aix->static_chain = closure; - closure->cif = cif; - closure->fun = fun; - closure->user_data = user_data; - break; - } - - default: - return FFI_BAD_ABI; - } - - return FFI_OK; -} - -#if defined(__ppc__) - typedef double ldbits[2]; - - typedef union - { - ldbits lb; - long double ld; - } ldu; -#endif - -typedef union -{ - float f; - double d; -} ffi_dblfl; - -/* The trampoline invokes ffi_closure_ASM, and on entry, r11 holds the - address of the closure. After storing the registers that could possibly - contain parameters to be passed into the stack frame and setting up space - for a return value, ffi_closure_ASM invokes the following helper function - to do most of the work. */ -int -ffi_closure_helper_DARWIN( - ffi_closure* closure, - void* rvalue, - unsigned long* pgr, - ffi_dblfl* pfr) -{ - /* rvalue is the pointer to space for return value in closure assembly - pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM - pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM. */ - -#if defined(__ppc__) - ldu temp_ld; -#endif - - double temp; - unsigned int i; - unsigned int nf = 0; /* number of FPRs already used. */ - unsigned int ng = 0; /* number of GPRs already used. */ - ffi_cif* cif = closure->cif; - long avn = cif->nargs; - void** avalue = alloca(cif->nargs * sizeof(void*)); - ffi_type** arg_types = cif->arg_types; - - /* Copy the caller's structure return value address so that the closure - returns the data directly to the caller. */ -#if defined(__ppc64__) - if (cif->rtype->type == FFI_TYPE_STRUCT && - ffi64_stret_needs_ptr(cif->rtype, NULL, NULL)) -#elif defined(__ppc__) - if (cif->rtype->type == FFI_TYPE_STRUCT) -#else -#error undefined architecture -#endif - { - rvalue = (void*)*pgr; - pgr++; - ng++; - } - - /* Grab the addresses of the arguments from the stack frame. */ - for (i = 0; i < avn; i++) - { - switch (arg_types[i]->type) - { - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT8: - avalue[i] = (char*)pgr + MODE_CHOICE(3,7); - ng++; - pgr++; - break; - - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT16: - avalue[i] = (char*)pgr + MODE_CHOICE(2,6); - ng++; - pgr++; - break; - -#if defined(__ppc__) - case FFI_TYPE_POINTER: -#endif - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT32: - avalue[i] = (char*)pgr + MODE_CHOICE(0,4); - ng++; - pgr++; - - break; - - case FFI_TYPE_STRUCT: - if (cif->abi == FFI_DARWIN) - { -#if defined(__ppc64__) - unsigned int gprSize = 0; - unsigned int fprSize = 0; - unsigned int savedFPRSize = fprSize; - - avalue[i] = alloca(arg_types[i]->size); - ffi64_struct_to_ram_form(arg_types[i], (const char*)pgr, - &gprSize, (const char*)pfr, &fprSize, &nf, avalue[i], NULL); - - ng += gprSize / sizeof(long); - pgr += gprSize / sizeof(long); - pfr += (fprSize - savedFPRSize) / sizeof(double); - -#elif defined(__ppc__) - /* Structures that match the basic modes (QI 1 byte, HI 2 bytes, - SI 4 bytes) are aligned as if they were those modes. */ - unsigned int size_al = size_al = arg_types[i]->size; - - /* If the first member of the struct is a double, then align - the struct to double-word. */ - if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE) - size_al = ALIGN(arg_types[i]->size, 8); - - if (size_al < 3) - avalue[i] = (void*)pgr + MODE_CHOICE(4,8) - size_al; - else - avalue[i] = (void*)pgr; - - ng += (size_al + 3) / sizeof(long); - pgr += (size_al + 3) / sizeof(long); -#else -#error undefined architecture -#endif - } - - break; - -#if defined(__ppc64__) - case FFI_TYPE_POINTER: -#endif - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - /* Long long ints are passed in 1 or 2 GPRs. */ - avalue[i] = pgr; - ng += MODE_CHOICE(2,1); - pgr += MODE_CHOICE(2,1); - - break; - - case FFI_TYPE_FLOAT: - /* A float value consumes a GPR. - There are 13 64-bit floating point registers. */ - if (nf < NUM_FPR_ARG_REGISTERS) - { - temp = pfr->d; - pfr->f = (float)temp; - avalue[i] = pfr; - pfr++; - } - else - avalue[i] = pgr; - - nf++; - ng++; - pgr++; - break; - - case FFI_TYPE_DOUBLE: - /* A double value consumes one or two GPRs. - There are 13 64bit floating point registers. */ - if (nf < NUM_FPR_ARG_REGISTERS) - { - avalue[i] = pfr; - pfr++; - } - else - avalue[i] = pgr; - - nf++; - ng += MODE_CHOICE(2,1); - pgr += MODE_CHOICE(2,1); - - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - - case FFI_TYPE_LONGDOUBLE: -#if defined(__ppc64__) - if (nf < NUM_FPR_ARG_REGISTERS) - { - avalue[i] = pfr; - pfr += 2; - } -#elif defined(__ppc__) - /* A long double value consumes 2/4 GPRs and 2 FPRs. - There are 13 64bit floating point registers. */ - if (nf < NUM_FPR_ARG_REGISTERS - 1) - { - avalue[i] = pfr; - pfr += 2; - } - /* Here we have the situation where one part of the long double - is stored in fpr13 and the other part is already on the stack. - We use a union to pass the long double to avalue[i]. */ - else if (nf == NUM_FPR_ARG_REGISTERS - 1) - { - memcpy (&temp_ld.lb[0], pfr, sizeof(temp_ld.lb[0])); - memcpy (&temp_ld.lb[1], pgr + 2, sizeof(temp_ld.lb[1])); - avalue[i] = &temp_ld.ld; - } -#else -#error undefined architecture -#endif - else - avalue[i] = pgr; - - nf += 2; - ng += MODE_CHOICE(4,2); - pgr += MODE_CHOICE(4,2); - - break; - -#endif /* FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE */ - - default: - FFI_ASSERT(0); - break; - } - } - - (closure->fun)(cif, rvalue, avalue, closure->user_data); - - /* Tell ffi_closure_ASM to perform return type promotions. */ - return cif->rtype->type; -} - -#if defined(__ppc64__) - -/* ffi64_struct_to_ram_form - - Rebuild a struct's natural layout from buffers of concatenated registers. - Return the number of registers used. - inGPRs[0-7] == r3, inFPRs[0-7] == f1 ... -*/ -void -ffi64_struct_to_ram_form( - const ffi_type* inType, - const char* inGPRs, - unsigned int* ioGPRMarker, - const char* inFPRs, - unsigned int* ioFPRMarker, - unsigned int* ioFPRsUsed, - char* outStruct, // caller-allocated - unsigned int* ioStructMarker) -{ - unsigned int srcGMarker = 0; - unsigned int srcFMarker = 0; - unsigned int savedFMarker = 0; - unsigned int fprsUsed = 0; - unsigned int savedFPRsUsed = 0; - unsigned int destMarker = 0; - - static unsigned int recurseCount = 0; - - if (ioGPRMarker) - srcGMarker = *ioGPRMarker; - - if (ioFPRMarker) - { - srcFMarker = *ioFPRMarker; - savedFMarker = srcFMarker; - } - - if (ioFPRsUsed) - { - fprsUsed = *ioFPRsUsed; - savedFPRsUsed = fprsUsed; - } - - if (ioStructMarker) - destMarker = *ioStructMarker; - - size_t i; - - switch (inType->size) - { - case 1: case 2: case 4: - srcGMarker += 8 - inType->size; - break; - - default: - break; - } - - for (i = 0; inType->elements[i] != NULL; i++) - { - switch (inType->elements[i]->type) - { - case FFI_TYPE_FLOAT: - srcFMarker = ALIGN(srcFMarker, 4); - srcGMarker = ALIGN(srcGMarker, 4); - destMarker = ALIGN(destMarker, 4); - - if (fprsUsed < NUM_FPR_ARG_REGISTERS) - { - *(float*)&outStruct[destMarker] = - (float)*(double*)&inFPRs[srcFMarker]; - srcFMarker += 8; - fprsUsed++; - } - else - *(float*)&outStruct[destMarker] = - (float)*(double*)&inGPRs[srcGMarker]; - - srcGMarker += 4; - destMarker += 4; - - // Skip to next GPR if next element won't fit and we're - // not already at a register boundary. - if (inType->elements[i + 1] != NULL && (destMarker % 8)) - { - if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) && - (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) || - (ALIGN(srcGMarker, 8) - srcGMarker) < 2) && - (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) || - (ALIGN(srcGMarker, 8) - srcGMarker) < 4)) - srcGMarker = ALIGN(srcGMarker, 8); - } - - break; - - case FFI_TYPE_DOUBLE: - srcFMarker = ALIGN(srcFMarker, 8); - destMarker = ALIGN(destMarker, 8); - - if (fprsUsed < NUM_FPR_ARG_REGISTERS) - { - *(double*)&outStruct[destMarker] = - *(double*)&inFPRs[srcFMarker]; - srcFMarker += 8; - fprsUsed++; - } - else - *(double*)&outStruct[destMarker] = - *(double*)&inGPRs[srcGMarker]; - - destMarker += 8; - - // Skip next GPR - srcGMarker += 8; - srcGMarker = ALIGN(srcGMarker, 8); - - break; - - case FFI_TYPE_LONGDOUBLE: - destMarker = ALIGN(destMarker, 16); - - if (fprsUsed < NUM_FPR_ARG_REGISTERS) - { - srcFMarker = ALIGN(srcFMarker, 8); - srcGMarker = ALIGN(srcGMarker, 8); - *(long double*)&outStruct[destMarker] = - *(long double*)&inFPRs[srcFMarker]; - srcFMarker += 16; - fprsUsed += 2; - } - else - { - srcFMarker = ALIGN(srcFMarker, 16); - srcGMarker = ALIGN(srcGMarker, 16); - *(long double*)&outStruct[destMarker] = - *(long double*)&inGPRs[srcGMarker]; - } - - destMarker += 16; - - // Skip next 2 GPRs - srcGMarker += 16; - srcGMarker = ALIGN(srcGMarker, 8); - - break; - - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - { - if (inType->alignment == 1) // chars only - { - if (inType->size == 1) - outStruct[destMarker++] = inGPRs[srcGMarker++]; - else if (inType->size == 2) - { - outStruct[destMarker++] = inGPRs[srcGMarker++]; - outStruct[destMarker++] = inGPRs[srcGMarker++]; - i++; - } - else - { - memcpy(&outStruct[destMarker], - &inGPRs[srcGMarker], inType->size); - srcGMarker += inType->size; - destMarker += inType->size; - i += inType->size - 1; - } - } - else // chars and other stuff - { - outStruct[destMarker++] = inGPRs[srcGMarker++]; - - // Skip to next GPR if next element won't fit and we're - // not already at a register boundary. - if (inType->elements[i + 1] != NULL && (srcGMarker % 8)) - { - if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) && - (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) || - (ALIGN(srcGMarker, 8) - srcGMarker) < 2) && - (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) || - (ALIGN(srcGMarker, 8) - srcGMarker) < 4)) - srcGMarker = ALIGN(srcGMarker, inType->alignment); // was 8 - } - } - - break; - } - - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - srcGMarker = ALIGN(srcGMarker, 2); - destMarker = ALIGN(destMarker, 2); - - *(short*)&outStruct[destMarker] = - *(short*)&inGPRs[srcGMarker]; - srcGMarker += 2; - destMarker += 2; - - break; - - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - srcGMarker = ALIGN(srcGMarker, 4); - destMarker = ALIGN(destMarker, 4); - - *(int*)&outStruct[destMarker] = - *(int*)&inGPRs[srcGMarker]; - srcGMarker += 4; - destMarker += 4; - - break; - - case FFI_TYPE_POINTER: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - srcGMarker = ALIGN(srcGMarker, 8); - destMarker = ALIGN(destMarker, 8); - - *(long long*)&outStruct[destMarker] = - *(long long*)&inGPRs[srcGMarker]; - srcGMarker += 8; - destMarker += 8; - - break; - - case FFI_TYPE_STRUCT: - recurseCount++; - ffi64_struct_to_ram_form(inType->elements[i], inGPRs, - &srcGMarker, inFPRs, &srcFMarker, &fprsUsed, - outStruct, &destMarker); - recurseCount--; - break; - - default: - FFI_ASSERT(0); // unknown element type - break; - } - } - - srcGMarker = ALIGN(srcGMarker, inType->alignment); - - // Take care of the special case for 16-byte structs, but not for - // nested structs. - if (recurseCount == 0 && srcGMarker == 16) - { - *(long double*)&outStruct[0] = *(long double*)&inGPRs[0]; - srcFMarker = savedFMarker; - fprsUsed = savedFPRsUsed; - } - - if (ioGPRMarker) - *ioGPRMarker = ALIGN(srcGMarker, 8); - - if (ioFPRMarker) - *ioFPRMarker = srcFMarker; - - if (ioFPRsUsed) - *ioFPRsUsed = fprsUsed; - - if (ioStructMarker) - *ioStructMarker = ALIGN(destMarker, 8); -} - -/* ffi64_struct_to_reg_form - - Copy a struct's elements into buffers that can be sliced into registers. - Return the sizes of the output buffers in bytes. Pass NULL buffer pointers - to calculate size only. - outGPRs[0-7] == r3, outFPRs[0-7] == f1 ... -*/ -void -ffi64_struct_to_reg_form( - const ffi_type* inType, - const char* inStruct, - unsigned int* ioStructMarker, - unsigned int* ioFPRsUsed, - char* outGPRs, // caller-allocated - unsigned int* ioGPRSize, - char* outFPRs, // caller-allocated - unsigned int* ioFPRSize) -{ - size_t i; - unsigned int srcMarker = 0; - unsigned int destGMarker = 0; - unsigned int destFMarker = 0; - unsigned int savedFMarker = 0; - unsigned int fprsUsed = 0; - unsigned int savedFPRsUsed = 0; - - static unsigned int recurseCount = 0; - - if (ioStructMarker) - srcMarker = *ioStructMarker; - - if (ioFPRsUsed) - { - fprsUsed = *ioFPRsUsed; - savedFPRsUsed = fprsUsed; - } - - if (ioGPRSize) - destGMarker = *ioGPRSize; - - if (ioFPRSize) - { - destFMarker = *ioFPRSize; - savedFMarker = destFMarker; - } - - switch (inType->size) - { - case 1: case 2: case 4: - destGMarker += 8 - inType->size; - break; - - default: - break; - } - - for (i = 0; inType->elements[i] != NULL; i++) - { - switch (inType->elements[i]->type) - { - // Shadow floating-point types in GPRs for vararg and pre-ANSI - // functions. - case FFI_TYPE_FLOAT: - // Nudge markers to next 4/8-byte boundary - srcMarker = ALIGN(srcMarker, 4); - destGMarker = ALIGN(destGMarker, 4); - destFMarker = ALIGN(destFMarker, 8); - - if (fprsUsed < NUM_FPR_ARG_REGISTERS) - { - if (outFPRs != NULL && inStruct != NULL) - *(double*)&outFPRs[destFMarker] = - (double)*(float*)&inStruct[srcMarker]; - - destFMarker += 8; - fprsUsed++; - } - - if (outGPRs != NULL && inStruct != NULL) - *(double*)&outGPRs[destGMarker] = - (double)*(float*)&inStruct[srcMarker]; - - srcMarker += 4; - destGMarker += 4; - - // Skip to next GPR if next element won't fit and we're - // not already at a register boundary. - if (inType->elements[i + 1] != NULL && (srcMarker % 8)) - { - if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) && - (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) || - (ALIGN(destGMarker, 8) - destGMarker) < 2) && - (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) || - (ALIGN(destGMarker, 8) - destGMarker) < 4)) - destGMarker = ALIGN(destGMarker, 8); - } - - break; - - case FFI_TYPE_DOUBLE: - srcMarker = ALIGN(srcMarker, 8); - destFMarker = ALIGN(destFMarker, 8); - - if (fprsUsed < NUM_FPR_ARG_REGISTERS) - { - if (outFPRs != NULL && inStruct != NULL) - *(double*)&outFPRs[destFMarker] = - *(double*)&inStruct[srcMarker]; - - destFMarker += 8; - fprsUsed++; - } - - if (outGPRs != NULL && inStruct != NULL) - *(double*)&outGPRs[destGMarker] = - *(double*)&inStruct[srcMarker]; - - srcMarker += 8; - - // Skip next GPR - destGMarker += 8; - destGMarker = ALIGN(destGMarker, 8); - - break; - - case FFI_TYPE_LONGDOUBLE: - srcMarker = ALIGN(srcMarker, 16); - - if (fprsUsed < NUM_FPR_ARG_REGISTERS) - { - destFMarker = ALIGN(destFMarker, 8); - destGMarker = ALIGN(destGMarker, 8); - - if (outFPRs != NULL && inStruct != NULL) - *(long double*)&outFPRs[destFMarker] = - *(long double*)&inStruct[srcMarker]; - - if (outGPRs != NULL && inStruct != NULL) - *(long double*)&outGPRs[destGMarker] = - *(long double*)&inStruct[srcMarker]; - - destFMarker += 16; - fprsUsed += 2; - } - else - { - destGMarker = ALIGN(destGMarker, 16); - - if (outGPRs != NULL && inStruct != NULL) - *(long double*)&outGPRs[destGMarker] = - *(long double*)&inStruct[srcMarker]; - } - - srcMarker += 16; - destGMarker += 16; // Skip next 2 GPRs - destGMarker = ALIGN(destGMarker, 8); // was 16 - - break; - - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - if (inType->alignment == 1) // bytes only - { - if (inType->size == 1) - { - if (outGPRs != NULL && inStruct != NULL) - outGPRs[destGMarker] = inStruct[srcMarker]; - - srcMarker++; - destGMarker++; - } - else if (inType->size == 2) - { - if (outGPRs != NULL && inStruct != NULL) - { - outGPRs[destGMarker] = inStruct[srcMarker]; - outGPRs[destGMarker + 1] = inStruct[srcMarker + 1]; - } - - srcMarker += 2; - destGMarker += 2; - - i++; - } - else - { - if (outGPRs != NULL && inStruct != NULL) - { - // Avoid memcpy for small chunks. - if (inType->size <= sizeof(long)) - *(long*)&outGPRs[destGMarker] = - *(long*)&inStruct[srcMarker]; - else - memcpy(&outGPRs[destGMarker], - &inStruct[srcMarker], inType->size); - } - - srcMarker += inType->size; - destGMarker += inType->size; - i += inType->size - 1; - } - } - else // bytes and other stuff - { - if (outGPRs != NULL && inStruct != NULL) - outGPRs[destGMarker] = inStruct[srcMarker]; - - srcMarker++; - destGMarker++; - - // Skip to next GPR if next element won't fit and we're - // not already at a register boundary. - if (inType->elements[i + 1] != NULL && (destGMarker % 8)) - { - if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) && - (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) || - (ALIGN(destGMarker, 8) - destGMarker) < 2) && - (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) || - (ALIGN(destGMarker, 8) - destGMarker) < 4)) - destGMarker = ALIGN(destGMarker, inType->alignment); // was 8 - } - } - - break; - - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - srcMarker = ALIGN(srcMarker, 2); - destGMarker = ALIGN(destGMarker, 2); - - if (outGPRs != NULL && inStruct != NULL) - *(short*)&outGPRs[destGMarker] = - *(short*)&inStruct[srcMarker]; - - srcMarker += 2; - destGMarker += 2; - - if (inType->elements[i + 1] == NULL) - destGMarker = ALIGN(destGMarker, inType->alignment); - - break; - - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - srcMarker = ALIGN(srcMarker, 4); - destGMarker = ALIGN(destGMarker, 4); - - if (outGPRs != NULL && inStruct != NULL) - *(int*)&outGPRs[destGMarker] = - *(int*)&inStruct[srcMarker]; - - srcMarker += 4; - destGMarker += 4; - - break; - - case FFI_TYPE_POINTER: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - srcMarker = ALIGN(srcMarker, 8); - destGMarker = ALIGN(destGMarker, 8); - - if (outGPRs != NULL && inStruct != NULL) - *(long long*)&outGPRs[destGMarker] = - *(long long*)&inStruct[srcMarker]; - - srcMarker += 8; - destGMarker += 8; - - if (inType->elements[i + 1] == NULL) - destGMarker = ALIGN(destGMarker, inType->alignment); - - break; - - case FFI_TYPE_STRUCT: - recurseCount++; - ffi64_struct_to_reg_form(inType->elements[i], - inStruct, &srcMarker, &fprsUsed, outGPRs, - &destGMarker, outFPRs, &destFMarker); - recurseCount--; - break; - - default: - FFI_ASSERT(0); - break; - } - } - - destGMarker = ALIGN(destGMarker, inType->alignment); - - // Take care of the special case for 16-byte structs, but not for - // nested structs. - if (recurseCount == 0 && destGMarker == 16) - { - if (outGPRs != NULL && inStruct != NULL) - *(long double*)&outGPRs[0] = *(long double*)&inStruct[0]; - - destFMarker = savedFMarker; - fprsUsed = savedFPRsUsed; - } - - if (ioStructMarker) - *ioStructMarker = ALIGN(srcMarker, 8); - - if (ioFPRsUsed) - *ioFPRsUsed = fprsUsed; - - if (ioGPRSize) - *ioGPRSize = ALIGN(destGMarker, 8); - - if (ioFPRSize) - *ioFPRSize = ALIGN(destFMarker, 8); -} - -/* ffi64_stret_needs_ptr - - Determine whether a returned struct needs a pointer in r3 or can fit - in registers. -*/ - -bool -ffi64_stret_needs_ptr( - const ffi_type* inType, - unsigned short* ioGPRCount, - unsigned short* ioFPRCount) -{ - // Obvious case first- struct is larger than combined FPR size. - if (inType->size > 14 * 8) - return true; - - // Now the struct can physically fit in registers, determine if it - // also fits logically. - bool needsPtr = false; - unsigned short gprsUsed = 0; - unsigned short fprsUsed = 0; - size_t i; - - if (ioGPRCount) - gprsUsed = *ioGPRCount; - - if (ioFPRCount) - fprsUsed = *ioFPRCount; - - for (i = 0; inType->elements[i] != NULL && !needsPtr; i++) - { - switch (inType->elements[i]->type) - { - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - gprsUsed++; - fprsUsed++; - - if (fprsUsed > 13) - needsPtr = true; - - break; - - case FFI_TYPE_LONGDOUBLE: - gprsUsed += 2; - fprsUsed += 2; - - if (fprsUsed > 14) - needsPtr = true; - - break; - - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - { - gprsUsed++; - - if (gprsUsed > 8) - { - needsPtr = true; - break; - } - - if (inType->elements[i + 1] == NULL) // last byte in the struct - break; - - // Count possible contiguous bytes ahead, up to 8. - unsigned short j; - - for (j = 1; j < 8; j++) - { - if (inType->elements[i + j] == NULL || - !FFI_TYPE_1_BYTE(inType->elements[i + j]->type)) - break; - } - - i += j - 1; // allow for i++ before the test condition - - break; - } - - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - case FFI_TYPE_POINTER: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - gprsUsed++; - - if (gprsUsed > 8) - needsPtr = true; - - break; - - case FFI_TYPE_STRUCT: - needsPtr = ffi64_stret_needs_ptr( - inType->elements[i], &gprsUsed, &fprsUsed); - - break; - - default: - FFI_ASSERT(0); - break; - } - } - - if (ioGPRCount) - *ioGPRCount = gprsUsed; - - if (ioFPRCount) - *ioFPRCount = fprsUsed; - - return needsPtr; -} - -/* ffi64_data_size - - Calculate the size in bytes of an ffi type. -*/ - -unsigned int -ffi64_data_size( - const ffi_type* inType) -{ - unsigned int size = 0; - - switch (inType->type) - { - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - size = 1; - break; - - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - size = 2; - break; - - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - case FFI_TYPE_FLOAT: - size = 4; - break; - - case FFI_TYPE_POINTER: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - case FFI_TYPE_DOUBLE: - size = 8; - break; - - case FFI_TYPE_LONGDOUBLE: - size = 16; - break; - - case FFI_TYPE_STRUCT: - ffi64_struct_to_reg_form( - inType, NULL, NULL, NULL, NULL, &size, NULL, NULL); - break; - - case FFI_TYPE_VOID: - break; - - default: - FFI_ASSERT(0); - break; - } - - return size; -} - -#endif /* defined(__ppc64__) */ -#endif /* __ppc__ || __ppc64__ */ diff --git a/Modules/_ctypes/libffi_osx/powerpc/ppc64-darwin_closure.S b/Modules/_ctypes/libffi_osx/powerpc/ppc64-darwin_closure.S deleted file mode 100644 index 7162fa1dda6..00000000000 --- a/Modules/_ctypes/libffi_osx/powerpc/ppc64-darwin_closure.S +++ /dev/null @@ -1,418 +0,0 @@ -#if defined(__ppc64__) - -/* ----------------------------------------------------------------------- - ppc64-darwin_closure.S - Copyright (c) 2002, 2003, 2004, Free Software Foundation, - Inc. based on ppc_closure.S - - PowerPC Assembly glue. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM - -#include -#include // for FFI_TRAMPOLINE_SIZE -#include -#include - - .file "ppc64-darwin_closure.S" -.text - .align LOG2_GPR_BYTES - .globl _ffi_closure_ASM - -.text - .align LOG2_GPR_BYTES - -_ffi_closure_ASM: -LFB1: - mflr r0 - stg r0,SF_RETURN(r1) // save return address - - // Save GPRs 3 - 10 (aligned to 8) in the parents outgoing area. - stg r3,SF_ARG1(r1) - stg r4,SF_ARG2(r1) - stg r5,SF_ARG3(r1) - stg r6,SF_ARG4(r1) - stg r7,SF_ARG5(r1) - stg r8,SF_ARG6(r1) - stg r9,SF_ARG7(r1) - stg r10,SF_ARG8(r1) - -LCFI0: -/* 48 bytes (Linkage Area) - 64 bytes (outgoing parameter area, always reserved) - 112 bytes (14*8 for incoming FPR) - ? bytes (result) - 112 bytes (14*8 for outgoing FPR) - 16 bytes (2 saved registers) - 352 + ? total bytes -*/ - - std r31,-8(r1) // Save registers we use. - std r30,-16(r1) - mr r30,r1 // Save the old SP. - mr r31,r11 // Save the ffi_closure around ffi64_data_size. - - // Calculate the space we need. - stdu r1,-SF_MINSIZE(r1) - ld r3,FFI_TRAMPOLINE_SIZE(r31) // ffi_closure->cif* - ld r3,16(r3) // ffi_cif->rtype* - bl Lffi64_data_size$stub - ld r1,0(r1) - - addi r3,r3,352 // Add our overhead. - neg r3,r3 - li r0,-32 // Align to 32 bytes. - and r3,r3,r0 - stdux r1,r1,r3 // Grow the stack. - - mr r11,r31 // Copy the ffi_closure back. - -LCFI1: - // We want to build up an area for the parameters passed - // in registers. (both floating point and integer) - -/* 320 bytes (callee stack frame aligned to 32) - 48 bytes (caller linkage area) - 368 (start of caller parameter area aligned to 8) -*/ - - // Save FPRs 1 - 14. (aligned to 8) - stfd f1,112(r1) - stfd f2,120(r1) - stfd f3,128(r1) - stfd f4,136(r1) - stfd f5,144(r1) - stfd f6,152(r1) - stfd f7,160(r1) - stfd f8,168(r1) - stfd f9,176(r1) - stfd f10,184(r1) - stfd f11,192(r1) - stfd f12,200(r1) - stfd f13,208(r1) - stfd f14,216(r1) - - // Set up registers for the routine that actually does the work. - mr r3,r11 // context pointer from the trampoline - addi r4,r1,224 // result storage - addi r5,r30,SF_ARG1 // saved GPRs - addi r6,r1,112 // saved FPRs - bl Lffi_closure_helper_DARWIN$stub - - // Look the proper starting point in table - // by using return type as an offset. - addi r5,r1,224 // Get pointer to results area. - bl Lget_ret_type0_addr // Get pointer to Lret_type0 into LR. - mflr r4 // Move to r4. - slwi r3,r3,4 // Now multiply return type by 16. - add r3,r3,r4 // Add contents of table to table address. - mtctr r3 - bctr - -LFE1: - // Each of the ret_typeX code fragments has to be exactly 16 bytes long - // (4 instructions). For cache effectiveness we align to a 16 byte - // boundary first. - .align 4 - nop - nop - nop - -Lget_ret_type0_addr: - blrl - -// case FFI_TYPE_VOID -Lret_type0: - b Lfinish - nop - nop - nop - -// case FFI_TYPE_INT -Lret_type1: - lwz r3,4(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_FLOAT -Lret_type2: - lfs f1,0(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_DOUBLE -Lret_type3: - lfd f1,0(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_LONGDOUBLE -Lret_type4: - lfd f1,0(r5) - lfd f2,8(r5) - b Lfinish - nop - -// case FFI_TYPE_UINT8 -Lret_type5: - lbz r3,7(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_SINT8 -Lret_type6: - lbz r3,7(r5) - extsb r3,r3 - b Lfinish - nop - -// case FFI_TYPE_UINT16 -Lret_type7: - lhz r3,6(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_SINT16 -Lret_type8: - lha r3,6(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_UINT32 -Lret_type9: // same as Lret_type1 - lwz r3,4(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_SINT32 -Lret_type10: // same as Lret_type1 - lwz r3,4(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_UINT64 -Lret_type11: - ld r3,0(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_SINT64 -Lret_type12: // same as Lret_type11 - ld r3,0(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_STRUCT -Lret_type13: - b Lret_struct - nop - nop - nop - -// ** End 16-byte aligned cases ** -// case FFI_TYPE_POINTER -// This case assumes that FFI_TYPE_POINTER == FFI_TYPE_LAST. If more types -// are added in future, the following code will need to be updated and -// padded to 16 bytes. -Lret_type14: - lg r3,0(r5) - b Lfinish - -// copy struct into registers -Lret_struct: - ld r31,FFI_TRAMPOLINE_SIZE(r31) // ffi_closure->cif* - ld r3,16(r31) // ffi_cif->rtype* - ld r31,24(r31) // ffi_cif->flags - mr r4,r5 // copy struct* to 2nd arg - addi r7,r1,SF_ARG9 // GPR return area - addi r9,r30,-16-(14*8) // FPR return area - li r5,0 // struct offset ptr (NULL) - li r6,0 // FPR used count ptr (NULL) - li r8,0 // GPR return area size ptr (NULL) - li r10,0 // FPR return area size ptr (NULL) - bl Lffi64_struct_to_reg_form$stub - - // Load GPRs - ld r3,SF_ARG9(r1) - ld r4,SF_ARG10(r1) - ld r5,SF_ARG11(r1) - ld r6,SF_ARG12(r1) - nop - ld r7,SF_ARG13(r1) - ld r8,SF_ARG14(r1) - ld r9,SF_ARG15(r1) - ld r10,SF_ARG16(r1) - nop - - // Load FPRs - mtcrf 0x2,r31 - bf 26,Lfinish - lfd f1,-16-(14*8)(r30) - lfd f2,-16-(13*8)(r30) - lfd f3,-16-(12*8)(r30) - lfd f4,-16-(11*8)(r30) - nop - lfd f5,-16-(10*8)(r30) - lfd f6,-16-(9*8)(r30) - lfd f7,-16-(8*8)(r30) - lfd f8,-16-(7*8)(r30) - nop - lfd f9,-16-(6*8)(r30) - lfd f10,-16-(5*8)(r30) - lfd f11,-16-(4*8)(r30) - lfd f12,-16-(3*8)(r30) - nop - lfd f13,-16-(2*8)(r30) - lfd f14,-16-(1*8)(r30) - // Fall through - -// case done -Lfinish: - lg r1,0(r1) // Restore stack pointer. - ld r31,-8(r1) // Restore registers we used. - ld r30,-16(r1) - lg r0,SF_RETURN(r1) // Get return address. - mtlr r0 // Reset link register. - blr - -// END(ffi_closure_ASM) - -.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support -EH_frame1: - .set L$set$0,LECIE1-LSCIE1 - .long L$set$0 ; Length of Common Information Entry -LSCIE1: - .long 0x0 ; CIE Identifier Tag - .byte 0x1 ; CIE Version - .ascii "zR\0" ; CIE Augmentation - .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor - .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor - .byte 0x41 ; CIE RA Column - .byte 0x1 ; uleb128 0x1; Augmentation size - .byte 0x10 ; FDE Encoding (pcrel) - .byte 0xc ; DW_CFA_def_cfa - .byte 0x1 ; uleb128 0x1 - .byte 0x0 ; uleb128 0x0 - .align LOG2_GPR_BYTES -LECIE1: -.globl _ffi_closure_ASM.eh -_ffi_closure_ASM.eh: -LSFDE1: - .set L$set$1,LEFDE1-LASFDE1 - .long L$set$1 ; FDE Length - -LASFDE1: - .long LASFDE1-EH_frame1 ; FDE CIE offset - .g_long LFB1-. ; FDE initial location - .set L$set$3,LFE1-LFB1 - .g_long L$set$3 ; FDE address range - .byte 0x0 ; uleb128 0x0; Augmentation size - .byte 0x4 ; DW_CFA_advance_loc4 - .set L$set$3,LCFI1-LCFI0 - .long L$set$3 - .byte 0xe ; DW_CFA_def_cfa_offset - .byte 176,1 ; uleb128 176 - .byte 0x4 ; DW_CFA_advance_loc4 - .set L$set$4,LCFI0-LFB1 - .long L$set$4 - .byte 0x11 ; DW_CFA_offset_extended_sf - .byte 0x41 ; uleb128 0x41 - .byte 0x7e ; sleb128 -2 - .align LOG2_GPR_BYTES - -LEFDE1: -.data - .align LOG2_GPR_BYTES -LDFCM0: -.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 - .align LOG2_GPR_BYTES - -Lffi_closure_helper_DARWIN$stub: - .indirect_symbol _ffi_closure_helper_DARWIN - mflr r0 - bcl 20,31,LO$ffi_closure_helper_DARWIN - -LO$ffi_closure_helper_DARWIN: - mflr r11 - addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN) - mtlr r0 - lgu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)(r11) - mtctr r12 - bctr - -.lazy_symbol_pointer -L_ffi_closure_helper_DARWIN$lazy_ptr: - .indirect_symbol _ffi_closure_helper_DARWIN - .g_long dyld_stub_binding_helper - -.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 - .align LOG2_GPR_BYTES - -Lffi64_struct_to_reg_form$stub: - .indirect_symbol _ffi64_struct_to_reg_form - mflr r0 - bcl 20,31,LO$ffi64_struct_to_reg_form - -LO$ffi64_struct_to_reg_form: - mflr r11 - addis r11,r11,ha16(L_ffi64_struct_to_reg_form$lazy_ptr - LO$ffi64_struct_to_reg_form) - mtlr r0 - lgu r12,lo16(L_ffi64_struct_to_reg_form$lazy_ptr - LO$ffi64_struct_to_reg_form)(r11) - mtctr r12 - bctr - -.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 - .align LOG2_GPR_BYTES - -Lffi64_data_size$stub: - .indirect_symbol _ffi64_data_size - mflr r0 - bcl 20,31,LO$ffi64_data_size - -LO$ffi64_data_size: - mflr r11 - addis r11,r11,ha16(L_ffi64_data_size$lazy_ptr - LO$ffi64_data_size) - mtlr r0 - lgu r12,lo16(L_ffi64_data_size$lazy_ptr - LO$ffi64_data_size)(r11) - mtctr r12 - bctr - -.lazy_symbol_pointer -L_ffi64_struct_to_reg_form$lazy_ptr: - .indirect_symbol _ffi64_struct_to_reg_form - .g_long dyld_stub_binding_helper - -L_ffi64_data_size$lazy_ptr: - .indirect_symbol _ffi64_data_size - .g_long dyld_stub_binding_helper - -#endif // __ppc64__ diff --git a/Modules/_ctypes/libffi_osx/types.c b/Modules/_ctypes/libffi_osx/types.c deleted file mode 100644 index 44806aeeb75..00000000000 --- a/Modules/_ctypes/libffi_osx/types.c +++ /dev/null @@ -1,115 +0,0 @@ -/* ----------------------------------------------------------------------- - types.c - Copyright (c) 1996, 1998 Red Hat, Inc. - - Predefined ffi_types needed by libffi. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -/* Type definitions */ -#define FFI_INTEGRAL_TYPEDEF(n, s, a, t) \ - ffi_type ffi_type_##n = { s, a, t, NULL } -#define FFI_AGGREGATE_TYPEDEF(n, e) \ - ffi_type ffi_type_##n = { 0, 0, FFI_TYPE_STRUCT, e } - -FFI_INTEGRAL_TYPEDEF(uint8, 1, 1, FFI_TYPE_UINT8); -FFI_INTEGRAL_TYPEDEF(sint8, 1, 1, FFI_TYPE_SINT8); -FFI_INTEGRAL_TYPEDEF(uint16, 2, 2, FFI_TYPE_UINT16); -FFI_INTEGRAL_TYPEDEF(sint16, 2, 2, FFI_TYPE_SINT16); -FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32); -FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32); -FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT); - -/* Size and alignment are fake here. They must not be 0. */ -FFI_INTEGRAL_TYPEDEF(void, 1, 1, FFI_TYPE_VOID); - -#if defined ALPHA || defined SPARC64 || defined X86_64 || \ - defined S390X || defined IA64 || defined POWERPC64 -FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER); -#else -FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER); -#endif - -#if defined X86 || defined ARM || defined M68K || defined(X86_DARWIN) - -# ifdef X86_64 - FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); - FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); -# else - FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); - FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); -# endif - -#elif defined(POWERPC_DARWIN) -FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); -#elif defined SH -FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); -#else -FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); -#endif - -#if defined X86 || defined X86_WIN32 || defined M68K || defined(X86_DARWIN) - -# if defined X86_WIN32 || defined X86_64 - FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); -# else - FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); -# endif - -# ifdef X86_DARWIN - FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); -# else - FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE); -# endif - -#elif defined ARM || defined SH || defined POWERPC_AIX -FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE); -#elif defined POWERPC_DARWIN -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); - -# if __GNUC__ >= 4 - FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); -# else - FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE); -# endif - -#elif defined SPARC -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); - -# ifdef SPARC64 - FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); -# else - FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE); -# endif - -#elif defined X86_64 || defined POWERPC64 -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); -#else -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE); -#endif \ No newline at end of file diff --git a/Modules/_ctypes/libffi_osx/x86/darwin64.S b/Modules/_ctypes/libffi_osx/x86/darwin64.S deleted file mode 100644 index 1286d33f83e..00000000000 --- a/Modules/_ctypes/libffi_osx/x86/darwin64.S +++ /dev/null @@ -1,417 +0,0 @@ -/* ----------------------------------------------------------------------- - darwin64.S - Copyright (c) 2006 Free Software Foundation, Inc. - derived from unix64.S - - x86-64 Foreign Function Interface for Darwin. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#ifdef __x86_64__ -#define LIBFFI_ASM -#include -#include - - .file "darwin64.S" -.text - -/* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags, - void *raddr, void (*fnaddr)()); - - Bit o trickiness here -- ARGS+BYTES is the base of the stack frame - for this function. This has been allocated by ffi_call. We also - deallocate some of the stack that has been alloca'd. */ - - .align 3 - .globl _ffi_call_unix64 - -_ffi_call_unix64: -LUW0: - movq (%rsp), %r10 /* Load return address. */ - movq %rdi, %r12 /* Save a copy of the register area. */ - leaq (%rdi, %rsi), %rax /* Find local stack base. */ - movq %rdx, (%rax) /* Save flags. */ - movq %rcx, 8(%rax) /* Save raddr. */ - movq %rbp, 16(%rax) /* Save old frame pointer. */ - movq %r10, 24(%rax) /* Relocate return address. */ - movq %rax, %rbp /* Finalize local stack frame. */ -LUW1: - /* movq %rdi, %r10 // Save a copy of the register area. */ - movq %r12, %r10 - movq %r8, %r11 /* Save a copy of the target fn. */ - movl %r9d, %eax /* Set number of SSE registers. */ - - /* Load up all argument registers. */ - movq (%r10), %rdi - movq 8(%r10), %rsi - movq 16(%r10), %rdx - movq 24(%r10), %rcx - movq 32(%r10), %r8 - movq 40(%r10), %r9 - testl %eax, %eax - jnz Lload_sse -Lret_from_load_sse: - - /* Deallocate the reg arg area. */ - leaq 176(%r10), %rsp - - /* Call the user function. */ - call *%r11 - - /* Deallocate stack arg area; local stack frame in redzone. */ - leaq 24(%rbp), %rsp - - movq 0(%rbp), %rcx /* Reload flags. */ - movq 8(%rbp), %rdi /* Reload raddr. */ - movq 16(%rbp), %rbp /* Reload old frame pointer. */ -LUW2: - - /* The first byte of the flags contains the FFI_TYPE. */ - movzbl %cl, %r10d - leaq Lstore_table(%rip), %r11 - movslq (%r11, %r10, 4), %r10 - addq %r11, %r10 - jmp *%r10 - -Lstore_table: - .long Lst_void-Lstore_table /* FFI_TYPE_VOID */ - .long Lst_sint32-Lstore_table /* FFI_TYPE_INT */ - .long Lst_float-Lstore_table /* FFI_TYPE_FLOAT */ - .long Lst_double-Lstore_table /* FFI_TYPE_DOUBLE */ - .long Lst_ldouble-Lstore_table /* FFI_TYPE_LONGDOUBLE */ - .long Lst_uint8-Lstore_table /* FFI_TYPE_UINT8 */ - .long Lst_sint8-Lstore_table /* FFI_TYPE_SINT8 */ - .long Lst_uint16-Lstore_table /* FFI_TYPE_UINT16 */ - .long Lst_sint16-Lstore_table /* FFI_TYPE_SINT16 */ - .long Lst_uint32-Lstore_table /* FFI_TYPE_UINT32 */ - .long Lst_sint32-Lstore_table /* FFI_TYPE_SINT32 */ - .long Lst_int64-Lstore_table /* FFI_TYPE_UINT64 */ - .long Lst_int64-Lstore_table /* FFI_TYPE_SINT64 */ - .long Lst_struct-Lstore_table /* FFI_TYPE_STRUCT */ - .long Lst_int64-Lstore_table /* FFI_TYPE_POINTER */ - - .text - .align 3 -Lst_void: - ret - .align 3 -Lst_uint8: - movzbq %al, %rax - movq %rax, (%rdi) - ret - .align 3 -Lst_sint8: - movsbq %al, %rax - movq %rax, (%rdi) - ret - .align 3 -Lst_uint16: - movzwq %ax, %rax - movq %rax, (%rdi) - .align 3 -Lst_sint16: - movswq %ax, %rax - movq %rax, (%rdi) - ret - .align 3 -Lst_uint32: - movl %eax, %eax - movq %rax, (%rdi) - .align 3 -Lst_sint32: - cltq - movq %rax, (%rdi) - ret - .align 3 -Lst_int64: - movq %rax, (%rdi) - ret - .align 3 -Lst_float: - movss %xmm0, (%rdi) - ret - .align 3 -Lst_double: - movsd %xmm0, (%rdi) - ret -Lst_ldouble: - fstpt (%rdi) - ret - .align 3 -Lst_struct: - leaq -20(%rsp), %rsi /* Scratch area in redzone. */ - - /* We have to locate the values now, and since we don't want to - write too much data into the user's return value, we spill the - value to a 16 byte scratch area first. Bits 8, 9, and 10 - control where the values are located. Only one of the three - bits will be set; see ffi_prep_cif_machdep for the pattern. */ - movd %xmm0, %r10 - movd %xmm1, %r11 - testl $0x100, %ecx - cmovnz %rax, %rdx - cmovnz %r10, %rax - testl $0x200, %ecx - cmovnz %r10, %rdx - testl $0x400, %ecx - cmovnz %r10, %rax - cmovnz %r11, %rdx - movq %rax, (%rsi) - movq %rdx, 8(%rsi) - - /* Bits 12-31 contain the true size of the structure. Copy from - the scratch area to the true destination. */ - shrl $12, %ecx - rep movsb - ret - - /* Many times we can avoid loading any SSE registers at all. - It's not worth an indirect jump to load the exact set of - SSE registers needed; zero or all is a good compromise. */ - .align 3 -LUW3: -Lload_sse: - movdqa 48(%r10), %xmm0 - movdqa 64(%r10), %xmm1 - movdqa 80(%r10), %xmm2 - movdqa 96(%r10), %xmm3 - movdqa 112(%r10), %xmm4 - movdqa 128(%r10), %xmm5 - movdqa 144(%r10), %xmm6 - movdqa 160(%r10), %xmm7 - jmp Lret_from_load_sse - -LUW4: - .align 3 - .globl _ffi_closure_unix64 - -_ffi_closure_unix64: -LUW5: - /* The carry flag is set by the trampoline iff SSE registers - are used. Don't clobber it before the branch instruction. */ - leaq -200(%rsp), %rsp -LUW6: - movq %rdi, (%rsp) - movq %rsi, 8(%rsp) - movq %rdx, 16(%rsp) - movq %rcx, 24(%rsp) - movq %r8, 32(%rsp) - movq %r9, 40(%rsp) - jc Lsave_sse -Lret_from_save_sse: - - movq %r10, %rdi - leaq 176(%rsp), %rsi - movq %rsp, %rdx - leaq 208(%rsp), %rcx - call _ffi_closure_unix64_inner - - /* Deallocate stack frame early; return value is now in redzone. */ - addq $200, %rsp -LUW7: - - /* The first byte of the return value contains the FFI_TYPE. */ - movzbl %al, %r10d - leaq Lload_table(%rip), %r11 - movslq (%r11, %r10, 4), %r10 - addq %r11, %r10 - jmp *%r10 - -Lload_table: - .long Lld_void-Lload_table /* FFI_TYPE_VOID */ - .long Lld_int32-Lload_table /* FFI_TYPE_INT */ - .long Lld_float-Lload_table /* FFI_TYPE_FLOAT */ - .long Lld_double-Lload_table /* FFI_TYPE_DOUBLE */ - .long Lld_ldouble-Lload_table /* FFI_TYPE_LONGDOUBLE */ - .long Lld_int8-Lload_table /* FFI_TYPE_UINT8 */ - .long Lld_int8-Lload_table /* FFI_TYPE_SINT8 */ - .long Lld_int16-Lload_table /* FFI_TYPE_UINT16 */ - .long Lld_int16-Lload_table /* FFI_TYPE_SINT16 */ - .long Lld_int32-Lload_table /* FFI_TYPE_UINT32 */ - .long Lld_int32-Lload_table /* FFI_TYPE_SINT32 */ - .long Lld_int64-Lload_table /* FFI_TYPE_UINT64 */ - .long Lld_int64-Lload_table /* FFI_TYPE_SINT64 */ - .long Lld_struct-Lload_table /* FFI_TYPE_STRUCT */ - .long Lld_int64-Lload_table /* FFI_TYPE_POINTER */ - - .text - .align 3 -Lld_void: - ret - .align 3 -Lld_int8: - movzbl -24(%rsp), %eax - ret - .align 3 -Lld_int16: - movzwl -24(%rsp), %eax - ret - .align 3 -Lld_int32: - movl -24(%rsp), %eax - ret - .align 3 -Lld_int64: - movq -24(%rsp), %rax - ret - .align 3 -Lld_float: - movss -24(%rsp), %xmm0 - ret - .align 3 -Lld_double: - movsd -24(%rsp), %xmm0 - ret - .align 3 -Lld_ldouble: - fldt -24(%rsp) - ret - .align 3 -Lld_struct: - /* There are four possibilities here, %rax/%rdx, %xmm0/%rax, - %rax/%xmm0, %xmm0/%xmm1. We collapse two by always loading - both rdx and xmm1 with the second word. For the remaining, - bit 8 set means xmm0 gets the second word, and bit 9 means - that rax gets the second word. */ - movq -24(%rsp), %rcx - movq -16(%rsp), %rdx - movq -16(%rsp), %xmm1 - testl $0x100, %eax - cmovnz %rdx, %rcx - movd %rcx, %xmm0 - testl $0x200, %eax - movq -24(%rsp), %rax - cmovnz %rdx, %rax - ret - - /* See the comment above Lload_sse; the same logic applies here. */ - .align 3 -LUW8: -Lsave_sse: - movdqa %xmm0, 48(%rsp) - movdqa %xmm1, 64(%rsp) - movdqa %xmm2, 80(%rsp) - movdqa %xmm3, 96(%rsp) - movdqa %xmm4, 112(%rsp) - movdqa %xmm5, 128(%rsp) - movdqa %xmm6, 144(%rsp) - movdqa %xmm7, 160(%rsp) - jmp Lret_from_save_sse - -LUW9: -.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support -EH_frame1: - .set L$set$0,LECIE1-LSCIE1 /* CIE Length */ - .long L$set$0 -LSCIE1: - .long 0x0 /* CIE Identifier Tag */ - .byte 0x1 /* CIE Version */ - .ascii "zR\0" /* CIE Augmentation */ - .byte 0x1 /* uleb128 0x1; CIE Code Alignment Factor */ - .byte 0x78 /* sleb128 -8; CIE Data Alignment Factor */ - .byte 0x10 /* CIE RA Column */ - .byte 0x1 /* uleb128 0x1; Augmentation size */ - .byte 0x10 /* FDE Encoding (pcrel sdata4) */ - .byte 0xc /* DW_CFA_def_cfa, %rsp offset 8 */ - .byte 0x7 /* uleb128 0x7 */ - .byte 0x8 /* uleb128 0x8 */ - .byte 0x90 /* DW_CFA_offset, column 0x10 */ - .byte 0x1 - .align 3 -LECIE1: - .globl _ffi_call_unix64.eh -_ffi_call_unix64.eh: -LSFDE1: - .set L$set$1,LEFDE1-LASFDE1 /* FDE Length */ - .long L$set$1 -LASFDE1: - .long LASFDE1-EH_frame1 /* FDE CIE offset */ - .quad LUW0-. /* FDE initial location */ - .set L$set$2,LUW4-LUW0 /* FDE address range */ - .quad L$set$2 - .byte 0x0 /* Augmentation size */ - .byte 0x4 /* DW_CFA_advance_loc4 */ - .set L$set$3,LUW1-LUW0 - .long L$set$3 - - /* New stack frame based off rbp. This is an itty bit of unwind - trickery in that the CFA *has* changed. There is no easy way - to describe it correctly on entry to the function. Fortunately, - it doesn't matter too much since at all points we can correctly - unwind back to ffi_call. Note that the location to which we - moved the return address is (the new) CFA-8, so from the - perspective of the unwind info, it hasn't moved. */ - .byte 0xc /* DW_CFA_def_cfa, %rbp offset 32 */ - .byte 0x6 - .byte 0x20 - .byte 0x80+6 /* DW_CFA_offset, %rbp offset 2*-8 */ - .byte 0x2 - .byte 0xa /* DW_CFA_remember_state */ - - .byte 0x4 /* DW_CFA_advance_loc4 */ - .set L$set$4,LUW2-LUW1 - .long L$set$4 - .byte 0xc /* DW_CFA_def_cfa, %rsp offset 8 */ - .byte 0x7 - .byte 0x8 - .byte 0xc0+6 /* DW_CFA_restore, %rbp */ - - .byte 0x4 /* DW_CFA_advance_loc4 */ - .set L$set$5,LUW3-LUW2 - .long L$set$5 - .byte 0xb /* DW_CFA_restore_state */ - - .align 3 -LEFDE1: - .globl _ffi_closure_unix64.eh -_ffi_closure_unix64.eh: -LSFDE3: - .set L$set$6,LEFDE3-LASFDE3 /* FDE Length */ - .long L$set$6 -LASFDE3: - .long LASFDE3-EH_frame1 /* FDE CIE offset */ - .quad LUW5-. /* FDE initial location */ - .set L$set$7,LUW9-LUW5 /* FDE address range */ - .quad L$set$7 - .byte 0x0 /* Augmentation size */ - - .byte 0x4 /* DW_CFA_advance_loc4 */ - .set L$set$8,LUW6-LUW5 - .long L$set$8 - .byte 0xe /* DW_CFA_def_cfa_offset */ - .byte 208,1 /* uleb128 208 */ - .byte 0xa /* DW_CFA_remember_state */ - - .byte 0x4 /* DW_CFA_advance_loc4 */ - .set L$set$9,LUW7-LUW6 - .long L$set$9 - .byte 0xe /* DW_CFA_def_cfa_offset */ - .byte 0x8 - - .byte 0x4 /* DW_CFA_advance_loc4 */ - .set L$set$10,LUW8-LUW7 - .long L$set$10 - .byte 0xb /* DW_CFA_restore_state */ - - .align 3 -LEFDE3: - .subsections_via_symbols - -#endif /* __x86_64__ */ diff --git a/Modules/_ctypes/libffi_osx/x86/x86-darwin.S b/Modules/_ctypes/libffi_osx/x86/x86-darwin.S deleted file mode 100644 index 925a8413166..00000000000 --- a/Modules/_ctypes/libffi_osx/x86/x86-darwin.S +++ /dev/null @@ -1,422 +0,0 @@ -#ifdef __i386__ -/* ----------------------------------------------------------------------- - darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003 Red Hat, Inc. - - X86 Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -/* - * This file is based on sysv.S and then hacked up by Ronald who hasn't done - * assembly programming in 8 years. - */ - -#ifndef __x86_64__ - -#define LIBFFI_ASM -#include -#include - -#ifdef PyObjC_STRICT_DEBUGGING - /* XXX: Debugging of stack alignment, to be removed */ -#define ASSERT_STACK_ALIGNED movdqa -16(%esp), %xmm0 -#else -#define ASSERT_STACK_ALIGNED -#endif - -.text - -.globl _ffi_prep_args - - .align 4 -.globl _ffi_call_SYSV - -_ffi_call_SYSV: -LFB1: - pushl %ebp -LCFI0: - movl %esp,%ebp -LCFI1: - subl $8,%esp - /* Make room for all of the new args. */ - movl 16(%ebp),%ecx - subl %ecx,%esp - - movl %esp,%eax - - /* Place all of the ffi_prep_args in position */ - subl $8,%esp - pushl 12(%ebp) - pushl %eax - call *8(%ebp) - - /* Return stack to previous state and call the function */ - addl $16,%esp - - call *28(%ebp) - - /* Remove the space we pushed for the args */ - movl 16(%ebp),%ecx - addl %ecx,%esp - - /* Load %ecx with the return type code */ - movl 20(%ebp),%ecx - - /* If the return value pointer is NULL, assume no return value. */ - cmpl $0,24(%ebp) - jne Lretint - - /* Even if there is no space for the return value, we are - obliged to handle floating-point values. */ - cmpl $FFI_TYPE_FLOAT,%ecx - jne Lnoretval - fstp %st(0) - - jmp Lepilogue - -Lretint: - cmpl $FFI_TYPE_INT,%ecx - jne Lretfloat - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - movl %eax,0(%ecx) - jmp Lepilogue - -Lretfloat: - cmpl $FFI_TYPE_FLOAT,%ecx - jne Lretdouble - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - fstps (%ecx) - jmp Lepilogue - -Lretdouble: - cmpl $FFI_TYPE_DOUBLE,%ecx - jne Lretlongdouble - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - fstpl (%ecx) - jmp Lepilogue - -Lretlongdouble: - cmpl $FFI_TYPE_LONGDOUBLE,%ecx - jne Lretint64 - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - fstpt (%ecx) - jmp Lepilogue - -Lretint64: - cmpl $FFI_TYPE_SINT64,%ecx - jne Lretstruct1b - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - movl %eax,0(%ecx) - movl %edx,4(%ecx) - jmp Lepilogue - -Lretstruct1b: - cmpl $FFI_TYPE_SINT8,%ecx - jne Lretstruct2b - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - movb %al,0(%ecx) - jmp Lepilogue - -Lretstruct2b: - cmpl $FFI_TYPE_SINT16,%ecx - jne Lretstruct - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - movw %ax,0(%ecx) - jmp Lepilogue - -Lretstruct: - cmpl $FFI_TYPE_STRUCT,%ecx - jne Lnoretval - /* Nothing to do! */ - addl $4,%esp - popl %ebp - ret - -Lnoretval: -Lepilogue: - addl $8,%esp - movl %ebp,%esp - popl %ebp - ret -LFE1: -.ffi_call_SYSV_end: - - .align 4 -FFI_HIDDEN (ffi_closure_SYSV) -.globl _ffi_closure_SYSV - -_ffi_closure_SYSV: -LFB2: - pushl %ebp -LCFI2: - movl %esp, %ebp -LCFI3: - subl $56, %esp - leal -40(%ebp), %edx - movl %edx, -12(%ebp) /* resp */ - leal 8(%ebp), %edx - movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */ - leal -12(%ebp), %edx - movl %edx, (%esp) /* &resp */ - movl %ebx, 8(%esp) -LCFI7: - call L_ffi_closure_SYSV_inner$stub - movl 8(%esp), %ebx - movl -12(%ebp), %ecx - cmpl $FFI_TYPE_INT, %eax - je Lcls_retint - cmpl $FFI_TYPE_FLOAT, %eax - je Lcls_retfloat - cmpl $FFI_TYPE_DOUBLE, %eax - je Lcls_retdouble - cmpl $FFI_TYPE_LONGDOUBLE, %eax - je Lcls_retldouble - cmpl $FFI_TYPE_SINT64, %eax - je Lcls_retllong - cmpl $FFI_TYPE_UINT8, %eax - je Lcls_retstruct1 - cmpl $FFI_TYPE_SINT8, %eax - je Lcls_retstruct1 - cmpl $FFI_TYPE_UINT16, %eax - je Lcls_retstruct2 - cmpl $FFI_TYPE_SINT16, %eax - je Lcls_retstruct2 - cmpl $FFI_TYPE_STRUCT, %eax - je Lcls_retstruct -Lcls_epilogue: - movl %ebp, %esp - popl %ebp - ret -Lcls_retint: - movl (%ecx), %eax - jmp Lcls_epilogue -Lcls_retfloat: - flds (%ecx) - jmp Lcls_epilogue -Lcls_retdouble: - fldl (%ecx) - jmp Lcls_epilogue -Lcls_retldouble: - fldt (%ecx) - jmp Lcls_epilogue -Lcls_retllong: - movl (%ecx), %eax - movl 4(%ecx), %edx - jmp Lcls_epilogue -Lcls_retstruct1: - movsbl (%ecx), %eax - jmp Lcls_epilogue -Lcls_retstruct2: - movswl (%ecx), %eax - jmp Lcls_epilogue -Lcls_retstruct: - lea -8(%ebp),%esp - movl %ebp, %esp - popl %ebp - ret $4 -LFE2: - -#if !FFI_NO_RAW_API - -#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3) -#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4) -#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4) -#define CIF_FLAGS_OFFSET 20 - - .align 4 -FFI_HIDDEN (ffi_closure_raw_SYSV) -.globl _ffi_closure_raw_SYSV - -_ffi_closure_raw_SYSV: -LFB3: - pushl %ebp -LCFI4: - movl %esp, %ebp -LCFI5: - pushl %esi -LCFI6: - subl $36, %esp - movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */ - movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */ - movl %edx, 12(%esp) /* user_data */ - leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */ - movl %edx, 8(%esp) /* raw_args */ - leal -24(%ebp), %edx - movl %edx, 4(%esp) /* &res */ - movl %esi, (%esp) /* cif */ - call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */ - movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */ - cmpl $FFI_TYPE_INT, %eax - je Lrcls_retint - cmpl $FFI_TYPE_FLOAT, %eax - je Lrcls_retfloat - cmpl $FFI_TYPE_DOUBLE, %eax - je Lrcls_retdouble - cmpl $FFI_TYPE_LONGDOUBLE, %eax - je Lrcls_retldouble - cmpl $FFI_TYPE_SINT64, %eax - je Lrcls_retllong -Lrcls_epilogue: - addl $36, %esp - popl %esi - popl %ebp - ret -Lrcls_retint: - movl -24(%ebp), %eax - jmp Lrcls_epilogue -Lrcls_retfloat: - flds -24(%ebp) - jmp Lrcls_epilogue -Lrcls_retdouble: - fldl -24(%ebp) - jmp Lrcls_epilogue -Lrcls_retldouble: - fldt -24(%ebp) - jmp Lrcls_epilogue -Lrcls_retllong: - movl -24(%ebp), %eax - movl -20(%ebp), %edx - jmp Lrcls_epilogue -LFE3: -#endif - -.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5 -L_ffi_closure_SYSV_inner$stub: - .indirect_symbol _ffi_closure_SYSV_inner - hlt ; hlt ; hlt ; hlt ; hlt - - -.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support -EH_frame1: - .set L$set$0,LECIE1-LSCIE1 - .long L$set$0 -LSCIE1: - .long 0x0 - .byte 0x1 - .ascii "zR\0" - .byte 0x1 - .byte 0x7c - .byte 0x8 - .byte 0x1 - .byte 0x10 - .byte 0xc - .byte 0x5 - .byte 0x4 - .byte 0x88 - .byte 0x1 - .align 2 -LECIE1: -.globl _ffi_call_SYSV.eh -_ffi_call_SYSV.eh: -LSFDE1: - .set L$set$1,LEFDE1-LASFDE1 - .long L$set$1 -LASFDE1: - .long LASFDE1-EH_frame1 - .long LFB1-. - .set L$set$2,LFE1-LFB1 - .long L$set$2 - .byte 0x0 - .byte 0x4 - .set L$set$3,LCFI0-LFB1 - .long L$set$3 - .byte 0xe - .byte 0x8 - .byte 0x84 - .byte 0x2 - .byte 0x4 - .set L$set$4,LCFI1-LCFI0 - .long L$set$4 - .byte 0xd - .byte 0x4 - .align 2 -LEFDE1: -.globl _ffi_closure_SYSV.eh -_ffi_closure_SYSV.eh: -LSFDE2: - .set L$set$5,LEFDE2-LASFDE2 - .long L$set$5 -LASFDE2: - .long LASFDE2-EH_frame1 - .long LFB2-. - .set L$set$6,LFE2-LFB2 - .long L$set$6 - .byte 0x0 - .byte 0x4 - .set L$set$7,LCFI2-LFB2 - .long L$set$7 - .byte 0xe - .byte 0x8 - .byte 0x84 - .byte 0x2 - .byte 0x4 - .set L$set$8,LCFI3-LCFI2 - .long L$set$8 - .byte 0xd - .byte 0x4 - .align 2 -LEFDE2: - -#if !FFI_NO_RAW_API - -.globl _ffi_closure_raw_SYSV.eh -_ffi_closure_raw_SYSV.eh: -LSFDE3: - .set L$set$10,LEFDE3-LASFDE3 - .long L$set$10 -LASFDE3: - .long LASFDE3-EH_frame1 - .long LFB3-. - .set L$set$11,LFE3-LFB3 - .long L$set$11 - .byte 0x0 - .byte 0x4 - .set L$set$12,LCFI4-LFB3 - .long L$set$12 - .byte 0xe - .byte 0x8 - .byte 0x84 - .byte 0x2 - .byte 0x4 - .set L$set$13,LCFI5-LCFI4 - .long L$set$13 - .byte 0xd - .byte 0x4 - .byte 0x4 - .set L$set$14,LCFI6-LCFI5 - .long L$set$14 - .byte 0x85 - .byte 0x3 - .align 2 -LEFDE3: - -#endif - -#endif /* ifndef __x86_64__ */ - -#endif /* defined __i386__ */ diff --git a/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c b/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c deleted file mode 100644 index 8e7d0164880..00000000000 --- a/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c +++ /dev/null @@ -1,737 +0,0 @@ -#ifdef __x86_64__ - -/* ----------------------------------------------------------------------- - x86-ffi64.c - Copyright (c) 2002 Bo Thorsen - - x86-64 Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -#include -#include - -#define MAX_GPR_REGS 6 -#define MAX_SSE_REGS 8 - -typedef struct RegisterArgs { - /* Registers for argument passing. */ - UINT64 gpr[MAX_GPR_REGS]; - __int128_t sse[MAX_SSE_REGS]; -} RegisterArgs; - -extern void -ffi_call_unix64( - void* args, - unsigned long bytes, - unsigned flags, - void* raddr, - void (*fnaddr)(void), - unsigned ssecount); - -/* All reference to register classes here is identical to the code in - gcc/config/i386/i386.c. Do *not* change one without the other. */ - -/* Register class used for passing given 64bit part of the argument. - These represent classes as documented by the PS ABI, with the exception - of SSESF, SSEDF classes, that are basically SSE class, just gcc will - use SF or DFmode move instead of DImode to avoid reformating penalties. - - Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves - whenever possible (upper half does contain padding). */ -enum x86_64_reg_class -{ - X86_64_NO_CLASS, - X86_64_INTEGER_CLASS, - X86_64_INTEGERSI_CLASS, - X86_64_SSE_CLASS, - X86_64_SSESF_CLASS, - X86_64_SSEDF_CLASS, - X86_64_SSEUP_CLASS, - X86_64_X87_CLASS, - X86_64_X87UP_CLASS, - X86_64_COMPLEX_X87_CLASS, - X86_64_MEMORY_CLASS -}; - -#define MAX_CLASSES 4 -#define SSE_CLASS_P(X) ((X) >= X86_64_SSE_CLASS && X <= X86_64_SSEUP_CLASS) - -/* x86-64 register passing implementation. See x86-64 ABI for details. Goal - of this code is to classify each 8bytes of incoming argument by the register - class and assign registers accordingly. */ - -/* Return the union class of CLASS1 and CLASS2. - See the x86-64 PS ABI for details. */ -static enum x86_64_reg_class -merge_classes( - enum x86_64_reg_class class1, - enum x86_64_reg_class class2) -{ - /* Rule #1: If both classes are equal, this is the resulting class. */ - if (class1 == class2) - return class1; - - /* Rule #2: If one of the classes is NO_CLASS, the resulting class is - the other class. */ - if (class1 == X86_64_NO_CLASS) - return class2; - - if (class2 == X86_64_NO_CLASS) - return class1; - - /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */ - if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS) - return X86_64_MEMORY_CLASS; - - /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */ - if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS) - || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS)) - return X86_64_INTEGERSI_CLASS; - - if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS - || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS) - return X86_64_INTEGER_CLASS; - - /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class, - MEMORY is used. */ - if (class1 == X86_64_X87_CLASS - || class1 == X86_64_X87UP_CLASS - || class1 == X86_64_COMPLEX_X87_CLASS - || class2 == X86_64_X87_CLASS - || class2 == X86_64_X87UP_CLASS - || class2 == X86_64_COMPLEX_X87_CLASS) - return X86_64_MEMORY_CLASS; - - /* Rule #6: Otherwise class SSE is used. */ - return X86_64_SSE_CLASS; -} - -/* Classify the argument of type TYPE and mode MODE. - CLASSES will be filled by the register class used to pass each word - of the operand. The number of words is returned. In case the parameter - should be passed in memory, 0 is returned. As a special case for zero - sized containers, classes[0] will be NO_CLASS and 1 is returned. - - See the x86-64 PS ABI for details. */ - -static int -classify_argument( - ffi_type* type, - enum x86_64_reg_class classes[], - size_t byte_offset) -{ - switch (type->type) - { - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - case FFI_TYPE_POINTER: -#if 0 - if (byte_offset + type->size <= 4) - classes[0] = X86_64_INTEGERSI_CLASS; - else - classes[0] = X86_64_INTEGER_CLASS; - - return 1; -#else - { - int size = byte_offset + type->size; - - if (size <= 4) - { - classes[0] = X86_64_INTEGERSI_CLASS; - return 1; - } - else if (size <= 8) - { - classes[0] = X86_64_INTEGER_CLASS; - return 1; - } - else if (size <= 12) - { - classes[0] = X86_64_INTEGER_CLASS; - classes[1] = X86_64_INTEGERSI_CLASS; - return 2; - } - else if (size <= 16) - { - classes[0] = classes[1] = X86_64_INTEGERSI_CLASS; - return 2; - } - else - FFI_ASSERT (0); - } -#endif - - case FFI_TYPE_FLOAT: - if (byte_offset == 0) - classes[0] = X86_64_SSESF_CLASS; - else - classes[0] = X86_64_SSE_CLASS; - - return 1; - - case FFI_TYPE_DOUBLE: - classes[0] = X86_64_SSEDF_CLASS; - return 1; - - case FFI_TYPE_LONGDOUBLE: - classes[0] = X86_64_X87_CLASS; - classes[1] = X86_64_X87UP_CLASS; - return 2; - - case FFI_TYPE_STRUCT: - { - ffi_type** ptr; - int i; - enum x86_64_reg_class subclasses[MAX_CLASSES]; - const int UNITS_PER_WORD = 8; - int words = - (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; - - /* If the struct is larger than 16 bytes, pass it on the stack. */ - if (type->size > 16) - return 0; - - for (i = 0; i < words; i++) - classes[i] = X86_64_NO_CLASS; - - /* Merge the fields of structure. */ - for (ptr = type->elements; *ptr != NULL; ptr++) - { - int num, pos; - - byte_offset = ALIGN(byte_offset, (*ptr)->alignment); - - num = classify_argument(*ptr, subclasses, byte_offset % 8); - - if (num == 0) - return 0; - - pos = byte_offset / 8; - - for (i = 0; i < num; i++) - { - classes[i + pos] = - merge_classes(subclasses[i], classes[i + pos]); - } - - byte_offset += (*ptr)->size; - } - - if (words > 2) - { - /* When size > 16 bytes, if the first one isn't - X86_64_SSE_CLASS or any other ones aren't - X86_64_SSEUP_CLASS, everything should be passed in - memory. */ - if (classes[0] != X86_64_SSE_CLASS) - return 0; - - for (i = 1; i < words; i++) - if (classes[i] != X86_64_SSEUP_CLASS) - return 0; - } - - - /* Final merger cleanup. */ - for (i = 0; i < words; i++) - { - /* If one class is MEMORY, everything should be passed in - memory. */ - if (classes[i] == X86_64_MEMORY_CLASS) - return 0; - - /* The X86_64_SSEUP_CLASS should be always preceded by - X86_64_SSE_CLASS. */ - if (classes[i] == X86_64_SSEUP_CLASS - && classes[i - 1] != X86_64_SSE_CLASS - && classes[i - 1] != X86_64_SSEUP_CLASS) - { - FFI_ASSERT(i != 0); - classes[i] = X86_64_SSE_CLASS; - } - - /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */ - if (classes[i] == X86_64_X87UP_CLASS - && classes[i - 1] != X86_64_X87_CLASS) - { - FFI_ASSERT(i != 0); - classes[i] = X86_64_SSE_CLASS; - } - } - - return words; - } - - default: - FFI_ASSERT(0); - } - - return 0; /* Never reached. */ -} - -/* Examine the argument and return set number of register required in each - class. Return zero if parameter should be passed in memory, otherwise - the number of registers. */ -static int -examine_argument( - ffi_type* type, - enum x86_64_reg_class classes[MAX_CLASSES], - _Bool in_return, - int* pngpr, - int* pnsse) -{ - int n = classify_argument(type, classes, 0); - int ngpr = 0; - int nsse = 0; - int i; - - if (n == 0) - return 0; - - for (i = 0; i < n; ++i) - { - switch (classes[i]) - { - case X86_64_INTEGER_CLASS: - case X86_64_INTEGERSI_CLASS: - ngpr++; - break; - - case X86_64_SSE_CLASS: - case X86_64_SSESF_CLASS: - case X86_64_SSEDF_CLASS: - nsse++; - break; - - case X86_64_NO_CLASS: - case X86_64_SSEUP_CLASS: - break; - - case X86_64_X87_CLASS: - case X86_64_X87UP_CLASS: - case X86_64_COMPLEX_X87_CLASS: - return in_return != 0; - - default: - abort(); - } - } - - *pngpr = ngpr; - *pnsse = nsse; - - return n; -} - -/* Perform machine dependent cif processing. */ -ffi_status -ffi_prep_cif_machdep( - ffi_cif* cif) -{ - int gprcount = 0; - int ssecount = 0; - int flags = cif->rtype->type; - int i, avn, n, ngpr, nsse; - enum x86_64_reg_class classes[MAX_CLASSES]; - size_t bytes; - - if (flags != FFI_TYPE_VOID) - { - n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse); - - if (n == 0) - { - /* The return value is passed in memory. A pointer to that - memory is the first argument. Allocate a register for it. */ - gprcount++; - - /* We don't have to do anything in asm for the return. */ - flags = FFI_TYPE_VOID; - } - else if (flags == FFI_TYPE_STRUCT) - { - /* Mark which registers the result appears in. */ - _Bool sse0 = SSE_CLASS_P(classes[0]); - _Bool sse1 = n == 2 && SSE_CLASS_P(classes[1]); - - if (sse0 && !sse1) - flags |= 1 << 8; - else if (!sse0 && sse1) - flags |= 1 << 9; - else if (sse0 && sse1) - flags |= 1 << 10; - - /* Mark the true size of the structure. */ - flags |= cif->rtype->size << 12; - } - } - - /* Go over all arguments and determine the way they should be passed. - If it's in a register and there is space for it, let that be so. If - not, add it's size to the stack byte count. */ - for (bytes = 0, i = 0, avn = cif->nargs; i < avn; i++) - { - if (examine_argument(cif->arg_types[i], classes, 0, &ngpr, &nsse) == 0 - || gprcount + ngpr > MAX_GPR_REGS - || ssecount + nsse > MAX_SSE_REGS) - { - long align = cif->arg_types[i]->alignment; - - if (align < 8) - align = 8; - - bytes = ALIGN(bytes, align); - bytes += cif->arg_types[i]->size; - } - else - { - gprcount += ngpr; - ssecount += nsse; - } - } - - if (ssecount) - flags |= 1 << 11; - - cif->flags = flags; - cif->bytes = bytes; - cif->bytes = ALIGN(bytes,8); - - return FFI_OK; -} - -void -ffi_call( - ffi_cif* cif, - void (*fn)(void), - void* rvalue, - void** avalue) -{ - enum x86_64_reg_class classes[MAX_CLASSES]; - char* stack; - char* argp; - ffi_type** arg_types; - int gprcount, ssecount, ngpr, nsse, i, avn; - _Bool ret_in_memory; - RegisterArgs* reg_args; - - /* Can't call 32-bit mode from 64-bit mode. */ - FFI_ASSERT(cif->abi == FFI_UNIX64); - - /* If the return value is a struct and we don't have a return value - address then we need to make one. Note the setting of flags to - VOID above in ffi_prep_cif_machdep. */ - ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT - && (cif->flags & 0xff) == FFI_TYPE_VOID); - - if (rvalue == NULL && ret_in_memory) - rvalue = alloca (cif->rtype->size); - - /* Allocate the space for the arguments, plus 4 words of temp space. */ - stack = alloca(sizeof(RegisterArgs) + cif->bytes + 4 * 8); - reg_args = (RegisterArgs*)stack; - argp = stack + sizeof(RegisterArgs); - - gprcount = ssecount = 0; - - /* If the return value is passed in memory, add the pointer as the - first integer argument. */ - if (ret_in_memory) - reg_args->gpr[gprcount++] = (long) rvalue; - - avn = cif->nargs; - arg_types = cif->arg_types; - - for (i = 0; i < avn; ++i) - { - size_t size = arg_types[i]->size; - int n; - - n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse); - - if (n == 0 - || gprcount + ngpr > MAX_GPR_REGS - || ssecount + nsse > MAX_SSE_REGS) - { - long align = arg_types[i]->alignment; - - /* Stack arguments are *always* at least 8 byte aligned. */ - if (align < 8) - align = 8; - - /* Pass this argument in memory. */ - argp = (void *) ALIGN (argp, align); - memcpy (argp, avalue[i], size); - argp += size; - } - else - { /* The argument is passed entirely in registers. */ - char *a = (char *) avalue[i]; - int j; - - for (j = 0; j < n; j++, a += 8, size -= 8) - { - switch (classes[j]) - { - case X86_64_INTEGER_CLASS: - case X86_64_INTEGERSI_CLASS: - reg_args->gpr[gprcount] = 0; - switch (arg_types[i]->type) { - case FFI_TYPE_SINT8: - { - int8_t shortval = *(int8_t*)a; - int64_t actval = (int64_t)shortval; - reg_args->gpr[gprcount] = actval; - /*memcpy (®_args->gpr[gprcount], &actval, 8);*/ - break; - } - - case FFI_TYPE_SINT16: - { - int16_t shortval = *(int16_t*)a; - int64_t actval = (int64_t)shortval; - memcpy (®_args->gpr[gprcount], &actval, 8); - break; - } - - case FFI_TYPE_SINT32: - { - int32_t shortval = *(int32_t*)a; - int64_t actval = (int64_t)shortval; - memcpy (®_args->gpr[gprcount], &actval, 8); - break; - } - - case FFI_TYPE_UINT8: - { - u_int8_t shortval = *(u_int8_t*)a; - u_int64_t actval = (u_int64_t)shortval; - /*memcpy (®_args->gpr[gprcount], &actval, 8);*/ - reg_args->gpr[gprcount] = actval; - break; - } - - case FFI_TYPE_UINT16: - { - u_int16_t shortval = *(u_int16_t*)a; - u_int64_t actval = (u_int64_t)shortval; - memcpy (®_args->gpr[gprcount], &actval, 8); - break; - } - - case FFI_TYPE_UINT32: - { - u_int32_t shortval = *(u_int32_t*)a; - u_int64_t actval = (u_int64_t)shortval; - memcpy (®_args->gpr[gprcount], &actval, 8); - break; - } - - default: - //memcpy (®_args->gpr[gprcount], a, size < 8 ? size : 8); - reg_args->gpr[gprcount] = *(int64_t*)a; - } - gprcount++; - break; - - case X86_64_SSE_CLASS: - case X86_64_SSEDF_CLASS: - reg_args->sse[ssecount++] = *(UINT64 *) a; - break; - - case X86_64_SSESF_CLASS: - reg_args->sse[ssecount++] = *(UINT32 *) a; - break; - - default: - abort(); - } - } - } - } - - ffi_call_unix64 (stack, cif->bytes + sizeof(RegisterArgs), - cif->flags, rvalue, fn, ssecount); -} - -extern void ffi_closure_unix64(void); - -ffi_status -ffi_prep_closure( - ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void* user_data) -{ - volatile unsigned short* tramp; - - if (cif->abi != FFI_UNIX64) - return FFI_BAD_ABI; - - tramp = (volatile unsigned short*)&closure->tramp[0]; - - tramp[0] = 0xbb49; /* mov , %r11 */ - *(void* volatile*)&tramp[1] = ffi_closure_unix64; - tramp[5] = 0xba49; /* mov , %r10 */ - *(void* volatile*)&tramp[6] = closure; - - /* Set the carry bit if the function uses any sse registers. - This is clc or stc, together with the first byte of the jmp. */ - tramp[10] = cif->flags & (1 << 11) ? 0x49f9 : 0x49f8; - tramp[11] = 0xe3ff; /* jmp *%r11 */ - - closure->cif = cif; - closure->fun = fun; - closure->user_data = user_data; - - return FFI_OK; -} - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wmissing-prototypes" -int -ffi_closure_unix64_inner( - ffi_closure* closure, - void* rvalue, - RegisterArgs* reg_args, - char* argp) -#pragma clang diagnostic pop -{ - ffi_cif* cif = closure->cif; - void** avalue = alloca(cif->nargs * sizeof(void *)); - ffi_type** arg_types; - long i, avn; - int gprcount = 0; - int ssecount = 0; - int ngpr, nsse; - int ret; - - ret = cif->rtype->type; - - if (ret != FFI_TYPE_VOID) - { - enum x86_64_reg_class classes[MAX_CLASSES]; - int n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse); - - if (n == 0) - { - /* The return value goes in memory. Arrange for the closure - return value to go directly back to the original caller. */ - rvalue = (void *) reg_args->gpr[gprcount++]; - - /* We don't have to do anything in asm for the return. */ - ret = FFI_TYPE_VOID; - } - else if (ret == FFI_TYPE_STRUCT && n == 2) - { - /* Mark which register the second word of the structure goes in. */ - _Bool sse0 = SSE_CLASS_P (classes[0]); - _Bool sse1 = SSE_CLASS_P (classes[1]); - - if (!sse0 && sse1) - ret |= 1 << 8; - else if (sse0 && !sse1) - ret |= 1 << 9; - } - } - - avn = cif->nargs; - arg_types = cif->arg_types; - - for (i = 0; i < avn; ++i) - { - enum x86_64_reg_class classes[MAX_CLASSES]; - int n; - - n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse); - - if (n == 0 - || gprcount + ngpr > MAX_GPR_REGS - || ssecount + nsse > MAX_SSE_REGS) - { - long align = arg_types[i]->alignment; - - /* Stack arguments are *always* at least 8 byte aligned. */ - if (align < 8) - align = 8; - - /* Pass this argument in memory. */ - argp = (void *) ALIGN (argp, align); - avalue[i] = argp; - argp += arg_types[i]->size; - } - -#if !defined(X86_DARWIN) - /* If the argument is in a single register, or two consecutive - registers, then we can use that address directly. */ - else if (n == 1 || (n == 2 && - SSE_CLASS_P (classes[0]) == SSE_CLASS_P (classes[1]))) - { - // The argument is in a single register. - if (SSE_CLASS_P (classes[0])) - { - avalue[i] = ®_args->sse[ssecount]; - ssecount += n; - } - else - { - avalue[i] = ®_args->gpr[gprcount]; - gprcount += n; - } - } -#endif - - /* Otherwise, allocate space to make them consecutive. */ - else - { - char *a = alloca (16); - int j; - - avalue[i] = a; - - for (j = 0; j < n; j++, a += 8) - { - if (SSE_CLASS_P (classes[j])) - memcpy (a, ®_args->sse[ssecount++], 8); - else - memcpy (a, ®_args->gpr[gprcount++], 8); - } - } - } - - /* Invoke the closure. */ - closure->fun (cif, rvalue, avalue, closure->user_data); - - /* Tell assembly how to perform return type promotions. */ - return ret; -} - -#endif /* __x86_64__ */ diff --git a/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c b/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c deleted file mode 100644 index 706ea0f5120..00000000000 --- a/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c +++ /dev/null @@ -1,438 +0,0 @@ -#ifdef __i386__ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc. - Copyright (c) 2002 Ranjit Mathew - Copyright (c) 2002 Bo Thorsen - Copyright (c) 2002 Roger Sayle - - x86 Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -#include - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments */ - -void ffi_prep_args(char *stack, extended_cif *ecif); - -void ffi_prep_args(char *stack, extended_cif *ecif) -{ - register unsigned int i; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - - argp = stack; - - if (ecif->cif->flags == FFI_TYPE_STRUCT) - { - *(void **) argp = ecif->rvalue; - argp += 4; - } - - p_argv = ecif->avalue; - - for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; - i != 0; - i--, p_arg++) - { - size_t z; - - /* Align if necessary */ - if ((sizeof(int) - 1) & (unsigned) argp) - argp = (char *) ALIGN(argp, sizeof(int)); - - z = (*p_arg)->size; - if (z < sizeof(int)) - { - z = sizeof(int); - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); - break; - - case FFI_TYPE_SINT32: - *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv); - break; - - case FFI_TYPE_UINT32: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - break; - - case FFI_TYPE_STRUCT: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - break; - - default: - FFI_ASSERT(0); - } - } - else - { - memcpy(argp, *p_argv, z); - } - p_argv++; - argp += z; - } - - return; -} - -/* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif) -{ - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: -#ifdef X86 - case FFI_TYPE_STRUCT: - case FFI_TYPE_UINT8: - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT8: - case FFI_TYPE_SINT16: -#endif - - case FFI_TYPE_SINT64: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - case FFI_TYPE_LONGDOUBLE: - cif->flags = (unsigned) cif->rtype->type; - break; - - case FFI_TYPE_UINT64: - cif->flags = FFI_TYPE_SINT64; - break; - -#ifndef X86 - case FFI_TYPE_STRUCT: - if (cif->rtype->size == 1) - { - cif->flags = FFI_TYPE_SINT8; /* same as char size */ - } - else if (cif->rtype->size == 2) - { - cif->flags = FFI_TYPE_SINT16; /* same as short size */ - } - else if (cif->rtype->size == 4) - { - cif->flags = FFI_TYPE_INT; /* same as int type */ - } - else if (cif->rtype->size == 8) - { - cif->flags = FFI_TYPE_SINT64; /* same as int64 type */ - } - else - { - cif->flags = FFI_TYPE_STRUCT; - } - break; -#endif - - default: - cif->flags = FFI_TYPE_INT; - break; - } - -#ifdef X86_DARWIN - cif->bytes = (cif->bytes + 15) & ~0xF; -#endif - - return FFI_OK; -} - -extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, - unsigned, unsigned, unsigned *, void (*fn)()); - -#ifdef X86_WIN32 -extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, - unsigned, unsigned, unsigned *, void (*fn)()); - -#endif /* X86_WIN32 */ - -void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) -{ - extended_cif ecif; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ - - if ((rvalue == NULL) && - (cif->flags == FFI_TYPE_STRUCT)) - { - ecif.rvalue = alloca(cif->rtype->size); - } - else - ecif.rvalue = rvalue; - - - switch (cif->abi) - { - case FFI_SYSV: - ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, - fn); - break; -#ifdef X86_WIN32 - case FFI_STDCALL: - ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags, - ecif.rvalue, fn); - break; -#endif /* X86_WIN32 */ - default: - FFI_ASSERT(0); - break; - } -} - - -/** private members **/ - -static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, - void** args, ffi_cif* cif); -void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *) -__attribute__ ((regparm(1))); -unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *) -__attribute__ ((regparm(1))); -void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *) -__attribute__ ((regparm(1))); - -/* This function is jumped to by the trampoline */ - -unsigned int FFI_HIDDEN -ffi_closure_SYSV_inner (closure, respp, args) -ffi_closure *closure; -void **respp; -void *args; -{ - // our various things... - ffi_cif *cif; - void **arg_area; - - cif = closure->cif; - arg_area = (void**) alloca (cif->nargs * sizeof (void*)); - - /* this call will initialize ARG_AREA, such that each - * element in that array points to the corresponding - * value on the stack; and if the function returns - * a structure, it will re-set RESP to point to the - * structure return address. */ - - ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif); - - (closure->fun) (cif, *respp, arg_area, closure->user_data); - - return cif->flags; -} - -static void -ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, - ffi_cif *cif) -{ - register unsigned int i; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - - argp = stack; - - if ( cif->flags == FFI_TYPE_STRUCT ) { - *rvalue = *(void **) argp; - argp += 4; - } - - p_argv = avalue; - - for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) - { - size_t z; - - /* Align if necessary */ - if ((sizeof(int) - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, sizeof(int)); - } - - z = (*p_arg)->size; - - /* because we're little endian, this is what it turns into. */ - - *p_argv = (void*) argp; - - p_argv++; - argp += z; - } - - return; -} - -/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */ - -#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \ -({ unsigned char *__tramp = (unsigned char*)(TRAMP); \ -unsigned int __fun = (unsigned int)(FUN); \ -unsigned int __ctx = (unsigned int)(CTX); \ -unsigned int __dis = __fun - (__ctx + FFI_TRAMPOLINE_SIZE); \ -*(unsigned char*) &__tramp[0] = 0xb8; \ -*(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ -*(unsigned char *) &__tramp[5] = 0xe9; \ -*(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \ -}) - - -/* the cif must already be prep'ed */ -ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data) -{ - if (cif->abi != FFI_SYSV) - return FFI_BAD_ABI; - - FFI_INIT_TRAMPOLINE (&closure->tramp[0], \ - &ffi_closure_SYSV, \ - (void*)closure); - - closure->cif = cif; - closure->user_data = user_data; - closure->fun = fun; - - return FFI_OK; -} - -/* ------- Native raw API support -------------------------------- */ - -#if !FFI_NO_RAW_API - -ffi_status -ffi_prep_raw_closure_loc (ffi_raw_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data, - void *codeloc) -{ - int i; - - FFI_ASSERT (cif->abi == FFI_SYSV); - - // we currently don't support certain kinds of arguments for raw - // closures. This should be implemented by a separate assembly language - // routine, since it would require argument processing, something we - // don't do now for performance. - - for (i = cif->nargs-1; i >= 0; i--) - { - FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT); - FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE); - } - - - FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV, - codeloc); - - closure->cif = cif; - closure->user_data = user_data; - closure->fun = fun; - - return FFI_OK; -} - -static void -ffi_prep_args_raw(char *stack, extended_cif *ecif) -{ - memcpy (stack, ecif->avalue, ecif->cif->bytes); -} - -/* we borrow this routine from libffi (it must be changed, though, to - * actually call the function passed in the first argument. as of - * libffi-1.20, this is not the case.) - */ - -extern void -ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned, - unsigned, unsigned *, void (*fn)()); - -#ifdef X86_WIN32 -extern void -ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned, - unsigned, unsigned *, void (*fn)()); -#endif /* X86_WIN32 */ - -void -ffi_raw_call(ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *fake_avalue) -{ - extended_cif ecif; - void **avalue = (void **)fake_avalue; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ - - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) - { - ecif.rvalue = alloca(cif->rtype->size); - } - else - ecif.rvalue = rvalue; - - - switch (cif->abi) - { - case FFI_SYSV: - ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, - ecif.rvalue, fn); - break; -#ifdef X86_WIN32 - case FFI_STDCALL: - ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, - ecif.rvalue, fn); - break; -#endif /* X86_WIN32 */ - default: - FFI_ASSERT(0); - break; - } -} - -#endif -#endif // __i386__ diff --git a/Modules/_ctypes/malloc_closure.c b/Modules/_ctypes/malloc_closure.c index 788bae6a96c..3a859322772 100644 --- a/Modules/_ctypes/malloc_closure.c +++ b/Modules/_ctypes/malloc_closure.c @@ -1,3 +1,6 @@ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif #include #include #ifdef MS_WIN32 @@ -20,6 +23,7 @@ /* #define MALLOC_CLOSURE_DEBUG */ /* enable for some debugging output */ + /******************************************************************/ typedef union _tagITEM { @@ -91,13 +95,17 @@ static void more_core(void) /* put the item back into the free list */ void Py_ffi_closure_free(void *p) { -#if HAVE_FFI_CLOSURE_ALLOC -#if USING_APPLE_OS_LIBFFI +#ifdef HAVE_FFI_CLOSURE_ALLOC +#ifdef USING_APPLE_OS_LIBFFI +# ifdef HAVE_BUILTIN_AVAILABLE if (__builtin_available(macos 10.15, ios 13, watchos 6, tvos 13, *)) { +# else + if (ffi_closure_free != NULL) { +# endif #endif ffi_closure_free(p); return; -#if USING_APPLE_OS_LIBFFI +#ifdef USING_APPLE_OS_LIBFFI } #endif #endif @@ -109,12 +117,16 @@ void Py_ffi_closure_free(void *p) /* return one item from the free list, allocating more if needed */ void *Py_ffi_closure_alloc(size_t size, void** codeloc) { -#if HAVE_FFI_CLOSURE_ALLOC -#if USING_APPLE_OS_LIBFFI +#ifdef HAVE_FFI_CLOSURE_ALLOC +#ifdef USING_APPLE_OS_LIBFFI +# ifdef HAVE_BUILTIN_AVAILABLE if (__builtin_available(macos 10.15, ios 13, watchos 6, tvos 13, *)) { +# else + if (ffi_closure_alloc != NULL) { +# endif #endif return ffi_closure_alloc(size, codeloc); -#if USING_APPLE_OS_LIBFFI +#ifdef USING_APPLE_OS_LIBFFI } #endif #endif diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index 6c1917b18d4..9a4041fb252 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -257,7 +257,7 @@ MakeFields(PyObject *type, CFieldObject *descr, } continue; } - new_descr = (CFieldObject *)_PyObject_CallNoArgs((PyObject *)&PyCField_Type); + new_descr = (CFieldObject *)PyCField_Type.tp_alloc((PyTypeObject *)&PyCField_Type, 0); if (new_descr == NULL) { Py_DECREF(fdescr); Py_DECREF(fieldlist); @@ -267,8 +267,7 @@ MakeFields(PyObject *type, CFieldObject *descr, new_descr->size = fdescr->size; new_descr->offset = fdescr->offset + offset; new_descr->index = fdescr->index + index; - new_descr->proto = fdescr->proto; - Py_XINCREF(new_descr->proto); + new_descr->proto = Py_XNewRef(fdescr->proto); new_descr->getfunc = fdescr->getfunc; new_descr->setfunc = fdescr->setfunc; @@ -290,12 +289,11 @@ MakeFields(PyObject *type, CFieldObject *descr, static int MakeAnonFields(PyObject *type) { - _Py_IDENTIFIER(_anonymous_); PyObject *anon; PyObject *anon_names; Py_ssize_t i; - if (_PyObject_LookupAttrId(type, &PyId__anonymous_, &anon) < 0) { + if (_PyObject_LookupAttr(type, &_Py_ID(_anonymous_), &anon) < 0) { return -1; } if (anon == NULL) { @@ -346,9 +344,6 @@ MakeAnonFields(PyObject *type) int PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) { - _Py_IDENTIFIER(_swappedbytes_); - _Py_IDENTIFIER(_use_broken_old_ctypes_structure_semantics_); - _Py_IDENTIFIER(_pack_); StgDictObject *stgdict, *basedict; Py_ssize_t len, offset, size, align, i; Py_ssize_t union_size, total_align; @@ -361,18 +356,10 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct int big_endian; int arrays_seen = 0; - /* HACK Alert: I cannot be bothered to fix ctypes.com, so there has to - be a way to use the old, broken semantics: _fields_ are not extended - but replaced in subclasses. - - XXX Remove this in ctypes 1.0! - */ - int use_broken_old_ctypes_semantics; - if (fields == NULL) return 0; - if (_PyObject_LookupAttrId(type, &PyId__swappedbytes_, &tmp) < 0) { + if (_PyObject_LookupAttr(type, &_Py_ID(_swappedbytes_), &tmp) < 0) { return -1; } if (tmp) { @@ -383,20 +370,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct big_endian = PY_BIG_ENDIAN; } - if (_PyObject_LookupAttrId(type, - &PyId__use_broken_old_ctypes_structure_semantics_, &tmp) < 0) - { - return -1; - } - if (tmp) { - Py_DECREF(tmp); - use_broken_old_ctypes_semantics = 1; - } - else { - use_broken_old_ctypes_semantics = 0; - } - - if (_PyObject_LookupAttrId(type, &PyId__pack_, &tmp) < 0) { + if (_PyObject_LookupAttr(type, &_Py_ID(_pack_), &tmp) < 0) { return -1; } if (tmp) { @@ -429,8 +403,11 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct } stgdict = PyType_stgdict(type); - if (!stgdict) + if (!stgdict) { + PyErr_SetString(PyExc_TypeError, + "ctypes state is not initialized"); return -1; + } /* If this structure/union is already marked final we cannot assign _fields_ anymore. */ @@ -456,7 +433,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct if (!isStruct) { stgdict->flags |= TYPEFLAG_HASUNION; } - if (basedict && !use_broken_old_ctypes_semantics) { + if (basedict) { size = offset = basedict->size; align = basedict->align; union_size = 0; @@ -504,7 +481,6 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct if (stgdict->format == NULL) return -1; -#define realdict ((PyObject *)&stgdict->dict) for (i = 0; i < len; ++i) { PyObject *name = NULL, *desc = NULL; PyObject *pair = PySequence_GetItem(fields, i); @@ -635,7 +611,6 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct Py_DECREF(pair); Py_DECREF(prop); } -#undef realdict if (isStruct && !isPacked) { char *ptr = stgdict->format; diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c index 0b328f9665a..2144345de01 100644 --- a/Modules/_curses_panel.c +++ b/Modules/_curses_panel.c @@ -261,8 +261,7 @@ PyCursesPanel_New(_curses_panel_state *state, PANEL *pan, Py_DECREF(po); return NULL; } - po->wo = wo; - Py_INCREF(wo); + po->wo = (PyCursesWindowObject*)Py_NewRef(wo); return (PyObject *)po; } @@ -313,8 +312,7 @@ _curses_panel_panel_above_impl(PyCursesPanelObject *self) "panel_above: can't find Panel Object"); return NULL; } - Py_INCREF(po); - return (PyObject *)po; + return Py_NewRef(po); } /* panel_below(NULL) returns the top panel in the stack. To get @@ -344,8 +342,7 @@ _curses_panel_panel_below_impl(PyCursesPanelObject *self) "panel_below: can't find Panel Object"); return NULL; } - Py_INCREF(po); - return (PyObject *)po; + return Py_NewRef(po); } /*[clinic input] @@ -394,8 +391,7 @@ static PyObject * _curses_panel_panel_window_impl(PyCursesPanelObject *self) /*[clinic end generated code: output=5f05940d4106b4cb input=6067353d2c307901]*/ { - Py_INCREF(self->wo); - return (PyObject *)self->wo; + return Py_NewRef(self->wo); } /*[clinic input] @@ -428,8 +424,7 @@ _curses_panel_panel_replace_impl(PyCursesPanelObject *self, PyErr_SetString(state->PyCursesError, "replace_panel() returned ERR"); return NULL; } - Py_INCREF(win); - Py_SETREF(po->wo, win); + Py_SETREF(po->wo, (PyCursesWindowObject*)Py_NewRef(win)); Py_RETURN_NONE; } @@ -486,8 +481,7 @@ _curses_panel_panel_userptr_impl(PyCursesPanelObject *self, return NULL; } - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } @@ -555,8 +549,7 @@ _curses_panel_bottom_panel_impl(PyObject *module) "panel_above: can't find Panel Object"); return NULL; } - Py_INCREF(po); - return (PyObject *)po; + return Py_NewRef(po); } /*[clinic input] @@ -614,8 +607,7 @@ _curses_panel_top_panel_impl(PyObject *module) "panel_below: can't find Panel Object"); return NULL; } - Py_INCREF(po); - return (PyObject *)po; + return Py_NewRef(po); } /*[clinic input] @@ -670,8 +662,7 @@ _curses_panel_exec(PyObject *mod) state->PyCursesError = PyErr_NewException( "_curses_panel.error", NULL, NULL); - Py_INCREF(state->PyCursesError); - if (PyModule_AddObject(mod, "error", state->PyCursesError) < 0) { + if (PyModule_AddObject(mod, "error", Py_NewRef(state->PyCursesError)) < 0) { Py_DECREF(state->PyCursesError); return -1; } diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 3770a032e97..5691a419a32 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -108,7 +108,7 @@ static const char PyCursesVersion[] = "2.2"; #include "Python.h" #include "pycore_long.h" // _PyLong_GetZero() -#include "pycore_structseq.h" // PyStructSequence_InitType() +#include "pycore_structseq.h" // _PyStructSequence_NewType() #ifdef __hpux #define STRICT_SYSV_CURSES @@ -382,14 +382,14 @@ PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj, return 0; /* check for embedded null bytes */ if (PyBytes_AsStringAndSize(*bytes, &str, NULL) < 0) { + Py_CLEAR(*bytes); return 0; } return 1; #endif } else if (PyBytes_Check(obj)) { - Py_INCREF(obj); - *bytes = obj; + *bytes = Py_NewRef(obj); /* check for embedded null bytes */ if (PyBytes_AsStringAndSize(*bytes, &str, NULL) < 0) { Py_DECREF(obj); @@ -1230,8 +1230,8 @@ PyCursesWindow_ChgAt(PyCursesWindowObject *self, PyObject *args) return NULL; } - color = (short)((attr >> 8) & 0xff); - attr = attr - (color << 8); + color = (short) PAIR_NUMBER(attr); + attr = attr & A_ATTRIBUTES; if (use_xy) { rtn = mvwchgat(self->win,y,x,num,attr,color,NULL); @@ -2175,12 +2175,11 @@ _curses_window_putwin(PyCursesWindowObject *self, PyObject *file) while (1) { char buf[BUFSIZ]; Py_ssize_t n = fread(buf, 1, BUFSIZ, fp); - _Py_IDENTIFIER(write); if (n <= 0) break; Py_DECREF(res); - res = _PyObject_CallMethodId(file, &PyId_write, "y#", buf, n); + res = PyObject_CallMethod(file, "write", "y#", buf, n); if (res == NULL) break; } @@ -2372,7 +2371,7 @@ _curses.window.touchline start: int count: int [ - changed: bool(accept={int}) = True + changed: bool = True ] / @@ -2385,7 +2384,7 @@ as having been changed (changed=True) or unchanged (changed=False). static PyObject * _curses_window_touchline_impl(PyCursesWindowObject *self, int start, int count, int group_right_1, int changed) -/*[clinic end generated code: output=65d05b3f7438c61d input=918ad1cbdadf93ea]*/ +/*[clinic end generated code: output=65d05b3f7438c61d input=a98aa4f79b6be845]*/ { if (!group_right_1) { return PyCursesCheckERR(touchline(self->win, start, count), "touchline"); @@ -2707,7 +2706,7 @@ NoArgTrueFalseFunctionBody(can_change_color) /*[clinic input] _curses.cbreak - flag: bool(accept={int}) = True + flag: bool = True If false, the effect is the same as calling nocbreak(). / @@ -2722,7 +2721,7 @@ Calling first raw() then cbreak() leaves the terminal in cbreak mode. static PyObject * _curses_cbreak_impl(PyObject *module, int flag) -/*[clinic end generated code: output=9f9dee9664769751 input=150be619eb1f1458]*/ +/*[clinic end generated code: output=9f9dee9664769751 input=c7d0bddda93016c1]*/ NoArgOrFlagNoReturnFunctionBody(cbreak, flag) /*[clinic input] @@ -2871,7 +2870,7 @@ NoArgNoReturnFunctionBody(doupdate) /*[clinic input] _curses.echo - flag: bool(accept={int}) = True + flag: bool = True If false, the effect is the same as calling noecho(). / @@ -2882,7 +2881,7 @@ In echo mode, each character input is echoed to the screen as it is entered. static PyObject * _curses_echo_impl(PyObject *module, int flag) -/*[clinic end generated code: output=03acb2ddfa6c8729 input=2e9e891d637eac5d]*/ +/*[clinic end generated code: output=03acb2ddfa6c8729 input=86cd4d5bb1d569c0]*/ NoArgOrFlagNoReturnFunctionBody(echo, flag) /*[clinic input] @@ -3049,7 +3048,6 @@ _curses_getwin(PyObject *module, PyObject *file) PyObject *data; size_t datalen; WINDOW *win; - _Py_IDENTIFIER(read); PyObject *res = NULL; PyCursesInitialised; @@ -3061,7 +3059,7 @@ _curses_getwin(PyObject *module, PyObject *file) if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0) goto error; - data = _PyObject_CallMethodIdNoArgs(file, &PyId_read); + data = PyObject_CallMethod(file, "read", NULL); if (data == NULL) goto error; if (!PyBytes_Check(data)) { @@ -3498,14 +3496,14 @@ _curses_set_tabsize_impl(PyObject *module, int size) /*[clinic input] _curses.intrflush - flag: bool(accept={int}) + flag: bool / [clinic start generated code]*/ static PyObject * _curses_intrflush_impl(PyObject *module, int flag) -/*[clinic end generated code: output=c1986df35e999a0f input=fcba57bb28dfd795]*/ +/*[clinic end generated code: output=c1986df35e999a0f input=c65fe2ef973fe40a]*/ { PyCursesInitialised; @@ -3607,7 +3605,7 @@ NoArgReturnStringFunctionBody(longname) /*[clinic input] _curses.meta - yes: bool(accept={int}) + yes: bool / Enable/disable meta keys. @@ -3618,7 +3616,7 @@ allow only 7-bit characters. static PyObject * _curses_meta_impl(PyObject *module, int yes) -/*[clinic end generated code: output=22f5abda46a605d8 input=af9892e3a74f35db]*/ +/*[clinic end generated code: output=22f5abda46a605d8 input=cfe7da79f51d0e30]*/ { PyCursesInitialised; @@ -3768,7 +3766,7 @@ _curses_newwin_impl(PyObject *module, int nlines, int ncols, /*[clinic input] _curses.nl - flag: bool(accept={int}) = True + flag: bool = True If false, the effect is the same as calling nonl(). / @@ -3780,7 +3778,7 @@ newline into return and line-feed on output. Newline mode is initially on. static PyObject * _curses_nl_impl(PyObject *module, int flag) -/*[clinic end generated code: output=b39cc0ffc9015003 input=cf36a63f7b86e28a]*/ +/*[clinic end generated code: output=b39cc0ffc9015003 input=18e3e9c6e8cfcf6f]*/ NoArgOrFlagNoReturnFunctionBody(nl, flag) /*[clinic input] @@ -3927,7 +3925,7 @@ _curses_putp_impl(PyObject *module, const char *string) /*[clinic input] _curses.qiflush - flag: bool(accept={int}) = True + flag: bool = True If false, the effect is the same as calling noqiflush(). / @@ -3939,7 +3937,7 @@ will be flushed when the INTR, QUIT and SUSP characters are read. static PyObject * _curses_qiflush_impl(PyObject *module, int flag) -/*[clinic end generated code: output=9167e862f760ea30 input=e9e4a389946a0dbc]*/ +/*[clinic end generated code: output=9167e862f760ea30 input=6ec8b3e2b717ec40]*/ { PyCursesInitialised; @@ -3959,9 +3957,7 @@ static int update_lines_cols(void) { PyObject *o; - PyObject *m = PyImport_ImportModuleNoBlock("curses"); - _Py_IDENTIFIER(LINES); - _Py_IDENTIFIER(COLS); + PyObject *m = PyImport_ImportModule("curses"); if (!m) return 0; @@ -3971,13 +3967,12 @@ update_lines_cols(void) Py_DECREF(m); return 0; } - if (_PyObject_SetAttrId(m, &PyId_LINES, o)) { + if (PyObject_SetAttrString(m, "LINES", o)) { Py_DECREF(m); Py_DECREF(o); return 0; } - /* PyId_LINES.object will be initialized here. */ - if (PyDict_SetItem(ModDict, _PyUnicode_FromId(&PyId_LINES), o)) { + if (PyDict_SetItemString(ModDict, "LINES", o)) { Py_DECREF(m); Py_DECREF(o); return 0; @@ -3988,12 +3983,12 @@ update_lines_cols(void) Py_DECREF(m); return 0; } - if (_PyObject_SetAttrId(m, &PyId_COLS, o)) { + if (PyObject_SetAttrString(m, "COLS", o)) { Py_DECREF(m); Py_DECREF(o); return 0; } - if (PyDict_SetItem(ModDict, _PyUnicode_FromId(&PyId_COLS), o)) { + if (PyDict_SetItemString(ModDict, "COLS", o)) { Py_DECREF(m); Py_DECREF(o); return 0; @@ -4023,7 +4018,7 @@ _curses_update_lines_cols_impl(PyObject *module) /*[clinic input] _curses.raw - flag: bool(accept={int}) = True + flag: bool = True If false, the effect is the same as calling noraw(). / @@ -4036,7 +4031,7 @@ curses input functions one by one. static PyObject * _curses_raw_impl(PyObject *module, int flag) -/*[clinic end generated code: output=a750e4b342be015b input=e36d8db27832b848]*/ +/*[clinic end generated code: output=a750e4b342be015b input=4b447701389fb4df]*/ NoArgOrFlagNoReturnFunctionBody(raw, flag) /*[clinic input] @@ -4508,7 +4503,7 @@ _curses_unget_wch(PyObject *module, PyObject *ch) /*[clinic input] _curses.use_env - flag: bool(accept={int}) + flag: bool / Use environment variables LINES and COLUMNS. @@ -4525,7 +4520,7 @@ not set). static PyObject * _curses_use_env_impl(PyObject *module, int flag) -/*[clinic end generated code: output=b2c445e435c0b164 input=1778eb1e9151ea37]*/ +/*[clinic end generated code: output=b2c445e435c0b164 input=06ac30948f2d78e4]*/ { use_env(flag); Py_RETURN_NONE; @@ -4569,8 +4564,6 @@ PyDoc_STRVAR(ncurses_version__doc__, \n\ Ncurses version information as a named tuple."); -static PyTypeObject NcursesVersionType; - static PyStructSequence_Field ncurses_version_fields[] = { {"major", "Major release number"}, {"minor", "Minor release number"}, @@ -4586,12 +4579,12 @@ static PyStructSequence_Desc ncurses_version_desc = { }; static PyObject * -make_ncurses_version(void) +make_ncurses_version(PyTypeObject *type) { PyObject *ncurses_version; int pos = 0; - ncurses_version = PyStructSequence_New(&NcursesVersionType); + ncurses_version = PyStructSequence_New(type); if (ncurses_version == NULL) { return NULL; } @@ -4796,14 +4789,14 @@ PyInit__curses(void) #ifdef NCURSES_VERSION /* ncurses_version */ - if (NcursesVersionType.tp_name == NULL) { - if (_PyStructSequence_InitType(&NcursesVersionType, - &ncurses_version_desc, - Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { - return NULL; - } + PyTypeObject *version_type; + version_type = _PyStructSequence_NewType(&ncurses_version_desc, + Py_TPFLAGS_DISALLOW_INSTANTIATION); + if (version_type == NULL) { + return NULL; } - v = make_ncurses_version(); + v = make_ncurses_version(version_type); + Py_DECREF(version_type); if (v == NULL) { return NULL; } diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 67441eba28f..eda8c5610ba 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -1,5 +1,5 @@ /* C implementation for the date/time type documented at - * http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage + * https://www.zope.dev/Members/fdrake/DateTimeWiki/FrontPage */ /* bpo-35081: Defining this prevents including the C API capsule; @@ -140,10 +140,6 @@ static PyTypeObject PyDateTime_TimeZoneType; static int check_tzinfo_subclass(PyObject *p); -_Py_IDENTIFIER(as_integer_ratio); -_Py_IDENTIFIER(fromutc); -_Py_IDENTIFIER(isoformat); -_Py_IDENTIFIER(strftime); /* --------------------------------------------------------------------------- * Math utilities. @@ -193,8 +189,7 @@ divide_nearest(PyObject *m, PyObject *n) temp = _PyLong_DivmodNear(m, n); if (temp == NULL) return NULL; - result = PyTuple_GET_ITEM(temp, 0); - Py_INCREF(result); + result = Py_NewRef(PyTuple_GET_ITEM(temp, 0)); Py_DECREF(temp); return result; @@ -394,6 +389,39 @@ iso_week1_monday(int year) return week1_monday; } +static int +iso_to_ymd(const int iso_year, const int iso_week, const int iso_day, + int *year, int *month, int *day) { + if (iso_week <= 0 || iso_week >= 53) { + int out_of_range = 1; + if (iso_week == 53) { + // ISO years have 53 weeks in it on years starting with a Thursday + // and on leap years starting on Wednesday + int first_weekday = weekday(iso_year, 1, 1); + if (first_weekday == 3 || (first_weekday == 2 && is_leap(iso_year))) { + out_of_range = 0; + } + } + + if (out_of_range) { + return -2; + } + } + + if (iso_day <= 0 || iso_day >= 8) { + return -3; + } + + // Convert (Y, W, D) to (Y, M, D) in-place + int day_1 = iso_week1_monday(iso_year); + + int day_offset = (iso_week - 1)*7 + iso_day - 1; + + ord_to_ymd(day_1 + day_offset, year, month, day); + return 0; +} + + /* --------------------------------------------------------------------------- * Range checkers. */ @@ -679,6 +707,11 @@ set_date_fields(PyDateTime_Date *self, int y, int m, int d) * String parsing utilities and helper functions */ +static unsigned char +is_digit(const char c) { + return ((unsigned int)(c - '0')) < 10; +} + static const char * parse_digits(const char *ptr, int *var, size_t num_digits) { @@ -695,14 +728,17 @@ parse_digits(const char *ptr, int *var, size_t num_digits) } static int -parse_isoformat_date(const char *dtstr, int *year, int *month, int *day) +parse_isoformat_date(const char *dtstr, const size_t len, int *year, int *month, int *day) { /* Parse the date components of the result of date.isoformat() * * Return codes: * 0: Success * -1: Failed to parse date component - * -2: Failed to parse dateseparator + * -2: Inconsistent date separator usage + * -3: Failed to parse ISO week. + * -4: Failed to parse ISO day. + * -5, -6: Failure in iso_to_ymd */ const char *p = dtstr; p = parse_digits(p, year, 4); @@ -710,8 +746,42 @@ parse_isoformat_date(const char *dtstr, int *year, int *month, int *day) return -1; } - if (*(p++) != '-') { - return -2; + const unsigned char uses_separator = (*p == '-'); + if (uses_separator) { + ++p; + } + + if(*p == 'W') { + // This is an isocalendar-style date string + p++; + int iso_week = 0; + int iso_day = 0; + + p = parse_digits(p, &iso_week, 2); + if (NULL == p) { + return -3; + } + + assert(p > dtstr); + if ((size_t)(p - dtstr) < len) { + if (uses_separator && *(p++) != '-') { + return -2; + } + + p = parse_digits(p, &iso_day, 1); + if (NULL == p) { + return -4; + } + } else { + iso_day = 1; + } + + int rv = iso_to_ymd(*year, iso_week, iso_day, year, month, day); + if (rv) { + return -3 + rv; + } else { + return 0; + } } p = parse_digits(p, month, 2); @@ -719,15 +789,13 @@ parse_isoformat_date(const char *dtstr, int *year, int *month, int *day) return -1; } - if (*(p++) != '-') { + if (uses_separator && *(p++) != '-') { return -2; } - p = parse_digits(p, day, 2); if (p == NULL) { return -1; } - return 0; } @@ -735,11 +803,14 @@ static int parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour, int *minute, int *second, int *microsecond) { + *hour = *minute = *second = *microsecond = 0; const char *p = tstr; const char *p_end = tstr_end; int *vals[3] = {hour, minute, second}; + // This is initialized to satisfy an erroneous compiler warning. + unsigned char has_separator = 1; - // Parse [HH[:MM[:SS]]] + // Parse [HH[:?MM[:?SS]]] for (size_t i = 0; i < 3; ++i) { p = parse_digits(p, vals[i], 2); if (NULL == p) { @@ -747,33 +818,47 @@ parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour, } char c = *(p++); + if (i == 0) { + has_separator = (c == ':'); + } + if (p >= p_end) { return c != '\0'; } - else if (c == ':') { + else if (has_separator && (c == ':')) { continue; } - else if (c == '.') { + else if (c == '.' || c == ',') { break; - } - else { + } else if (!has_separator) { + --p; + } else { return -4; // Malformed time separator } } - // Parse .fff[fff] + // Parse fractional components size_t len_remains = p_end - p; - if (!(len_remains == 6 || len_remains == 3)) { - return -3; + size_t to_parse = len_remains; + if (len_remains >= 6) { + to_parse = 6; } - p = parse_digits(p, microsecond, len_remains); + p = parse_digits(p, microsecond, to_parse); if (NULL == p) { return -3; } - if (len_remains == 3) { - *microsecond *= 1000; + static int correction[] = { + 100000, 10000, 1000, 100, 10 + }; + + if (to_parse < 6) { + *microsecond *= correction[to_parse-1]; + } + + while (is_digit(*p)){ + ++p; // skip truncated digits } // Return 1 if it's not the end of the string @@ -799,7 +884,7 @@ parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute, const char *tzinfo_pos = p; do { - if (*tzinfo_pos == '+' || *tzinfo_pos == '-') { + if (*tzinfo_pos == 'Z' || *tzinfo_pos == '+' || *tzinfo_pos == '-') { break; } } while (++tzinfo_pos < p_end); @@ -821,14 +906,16 @@ parse_isoformat_time(const char *dtstr, size_t dtlen, int *hour, int *minute, } } - // Parse time zone component - // Valid formats are: - // - +HH:MM (len 6) - // - +HH:MM:SS (len 9) - // - +HH:MM:SS.ffffff (len 16) - size_t tzlen = p_end - tzinfo_pos; - if (!(tzlen == 6 || tzlen == 9 || tzlen == 16)) { - return -5; + // Special case UTC / Zulu time. + if (*tzinfo_pos == 'Z') { + *tzoffset = 0; + *tzmicrosecond = 0; + + if (*(tzinfo_pos + 1) != '\0') { + return -5; + } else { + return 1; + } } int tzsign = (*tzinfo_pos == '-') ? -1 : 1; @@ -917,8 +1004,7 @@ new_datetime_ex2(int year, int month, int day, int hour, int minute, DATE_SET_SECOND(self, second); DATE_SET_MICROSECOND(self, usecond); if (aware) { - Py_INCREF(tzinfo); - self->tzinfo = tzinfo; + self->tzinfo = Py_NewRef(tzinfo); } DATE_SET_FOLD(self, fold); } @@ -995,8 +1081,7 @@ new_time_ex2(int hour, int minute, int second, int usecond, TIME_SET_SECOND(self, second); TIME_SET_MICROSECOND(self, usecond); if (aware) { - Py_INCREF(tzinfo); - self->tzinfo = tzinfo; + self->tzinfo = Py_NewRef(tzinfo); } TIME_SET_FOLD(self, fold); } @@ -1077,10 +1162,8 @@ create_timezone(PyObject *offset, PyObject *name) if (self == NULL) { return NULL; } - Py_INCREF(offset); - self->offset = offset; - Py_XINCREF(name); - self->name = name; + self->offset = Py_NewRef(offset); + self->name = Py_XNewRef(name); return (PyObject *)self; } @@ -1094,8 +1177,7 @@ new_timezone(PyObject *offset, PyObject *name) assert(name == NULL || PyUnicode_Check(name)); if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) { - Py_INCREF(PyDateTime_TimeZone_UTC); - return PyDateTime_TimeZone_UTC; + return Py_NewRef(PyDateTime_TimeZone_UTC); } if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0 && @@ -1230,8 +1312,6 @@ static PyObject * call_tzname(PyObject *tzinfo, PyObject *tzinfoarg) { PyObject *result; - _Py_IDENTIFIER(tzname); - assert(tzinfo != NULL); assert(check_tzinfo_subclass(tzinfo) >= 0); assert(tzinfoarg != NULL); @@ -1239,7 +1319,7 @@ call_tzname(PyObject *tzinfo, PyObject *tzinfoarg) if (tzinfo == Py_None) Py_RETURN_NONE; - result = _PyObject_CallMethodIdOneArg(tzinfo, &PyId_tzname, tzinfoarg); + result = PyObject_CallMethodOneArg(tzinfo, &_Py_ID(tzname), tzinfoarg); if (result == NULL || result == Py_None) return result; @@ -1248,8 +1328,7 @@ call_tzname(PyObject *tzinfo, PyObject *tzinfoarg) PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must " "return None or a string, not '%s'", Py_TYPE(result)->tp_name); - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); } return result; @@ -1311,8 +1390,7 @@ tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds) if (rv == 1) { // Create a timezone from offset in seconds (0 returns UTC) if (tzoffset == 0) { - Py_INCREF(PyDateTime_TimeZone_UTC); - return PyDateTime_TimeZone_UTC; + return Py_NewRef(PyDateTime_TimeZone_UTC); } PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1); @@ -1323,8 +1401,7 @@ tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds) Py_DECREF(delta); } else { - tzinfo = Py_None; - Py_INCREF(Py_None); + tzinfo = Py_NewRef(Py_None); } return tzinfo; @@ -1413,13 +1490,33 @@ format_utcoffset(char *buf, size_t buflen, const char *sep, return 0; } +static PyObject * +make_somezreplacement(PyObject *object, char *sep, PyObject *tzinfoarg) +{ + char buf[100]; + PyObject *tzinfo = get_tzinfo_member(object); + + if (tzinfo == Py_None || tzinfo == NULL) { + return PyBytes_FromStringAndSize(NULL, 0); + } + + assert(tzinfoarg != NULL); + if (format_utcoffset(buf, + sizeof(buf), + sep, + tzinfo, + tzinfoarg) < 0) + return NULL; + + return PyBytes_FromStringAndSize(buf, strlen(buf)); +} + static PyObject * make_Zreplacement(PyObject *object, PyObject *tzinfoarg) { PyObject *temp; PyObject *tzinfo = get_tzinfo_member(object); PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0); - _Py_IDENTIFIER(replace); if (Zreplacement == NULL) return NULL; @@ -1441,7 +1538,7 @@ make_Zreplacement(PyObject *object, PyObject *tzinfoarg) * strftime doesn't treat them as format codes. */ Py_DECREF(Zreplacement); - Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%"); + Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%"); Py_DECREF(temp); if (Zreplacement == NULL) return NULL; @@ -1473,7 +1570,7 @@ make_freplacement(PyObject *object) /* I sure don't want to reproduce the strftime code from the time module, * so this imports the module and calls it. All the hair is due to - * giving special meanings to the %z, %Z and %f format codes via a + * giving special meanings to the %z, %:z, %Z and %f format codes via a * preprocessing step on the format string. * tzinfoarg is the argument to pass to the object's tzinfo method, if * needed. @@ -1485,6 +1582,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, PyObject *result = NULL; /* guilty until proved innocent */ PyObject *zreplacement = NULL; /* py string, replacement for %z */ + PyObject *colonzreplacement = NULL; /* py string, replacement for %:z */ PyObject *Zreplacement = NULL; /* py string, replacement for %Z */ PyObject *freplacement = NULL; /* py string, replacement for %f */ @@ -1539,32 +1637,29 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, } /* A % has been seen and ch is the character after it. */ else if (ch == 'z') { + /* %z -> +HHMM */ if (zreplacement == NULL) { - /* format utcoffset */ - char buf[100]; - PyObject *tzinfo = get_tzinfo_member(object); - zreplacement = PyBytes_FromStringAndSize("", 0); - if (zreplacement == NULL) goto Done; - if (tzinfo != Py_None && tzinfo != NULL) { - assert(tzinfoarg != NULL); - if (format_utcoffset(buf, - sizeof(buf), - "", - tzinfo, - tzinfoarg) < 0) - goto Done; - Py_DECREF(zreplacement); - zreplacement = - PyBytes_FromStringAndSize(buf, - strlen(buf)); - if (zreplacement == NULL) - goto Done; - } + zreplacement = make_somezreplacement(object, "", tzinfoarg); + if (zreplacement == NULL) + goto Done; } assert(zreplacement != NULL); + assert(PyBytes_Check(zreplacement)); ptoappend = PyBytes_AS_STRING(zreplacement); ntoappend = PyBytes_GET_SIZE(zreplacement); } + else if (ch == ':' && *pin == 'z' && pin++) { + /* %:z -> +HH:MM */ + if (colonzreplacement == NULL) { + colonzreplacement = make_somezreplacement(object, ":", tzinfoarg); + if (colonzreplacement == NULL) + goto Done; + } + assert(colonzreplacement != NULL); + assert(PyBytes_Check(colonzreplacement)); + ptoappend = PyBytes_AS_STRING(colonzreplacement); + ntoappend = PyBytes_GET_SIZE(colonzreplacement); + } else if (ch == 'Z') { /* format tzname */ if (Zreplacement == NULL) { @@ -1593,7 +1688,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, ntoappend = PyBytes_GET_SIZE(freplacement); } else { - /* percent followed by neither z nor Z */ + /* percent followed by something else */ ptoappend = pin - 2; ntoappend = 2; } @@ -1625,21 +1720,22 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, goto Done; { PyObject *format; - PyObject *time = PyImport_ImportModuleNoBlock("time"); + PyObject *strftime = _PyImport_GetModuleAttrString("time", "strftime"); - if (time == NULL) + if (strftime == NULL) goto Done; format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt)); if (format != NULL) { - result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime, + result = PyObject_CallFunctionObjArgs(strftime, format, timetuple, NULL); Py_DECREF(format); } - Py_DECREF(time); + Py_DECREF(strftime); } Done: Py_XDECREF(freplacement); Py_XDECREF(zreplacement); + Py_XDECREF(colonzreplacement); Py_XDECREF(Zreplacement); Py_XDECREF(newfmt); return result; @@ -1655,12 +1751,10 @@ static PyObject * time_time(void) { PyObject *result = NULL; - PyObject *time = PyImport_ImportModuleNoBlock("time"); + PyObject *time = _PyImport_GetModuleAttrString("time", "time"); if (time != NULL) { - _Py_IDENTIFIER(time); - - result = _PyObject_CallMethodIdNoArgs(time, &PyId_time); + result = PyObject_CallNoArgs(time); Py_DECREF(time); } return result; @@ -1672,31 +1766,21 @@ time_time(void) static PyObject * build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag) { - PyObject *time; + PyObject *struct_time; PyObject *result; - _Py_IDENTIFIER(struct_time); - PyObject *args; - - time = PyImport_ImportModuleNoBlock("time"); - if (time == NULL) { + struct_time = _PyImport_GetModuleAttrString("time", "struct_time"); + if (struct_time == NULL) { return NULL; } - args = Py_BuildValue("iiiiiiiii", + result = PyObject_CallFunction(struct_time, "((iiiiiiiii))", y, m, d, hh, mm, ss, weekday(y, m, d), days_before_month(y, m) + d, dstflag); - if (args == NULL) { - Py_DECREF(time); - return NULL; - } - - result = _PyObject_CallMethodIdOneArg(time, &PyId_struct_time, args); - Py_DECREF(time); - Py_DECREF(args); + Py_DECREF(struct_time); return result; } @@ -1764,8 +1848,7 @@ delta_to_microseconds(PyDateTime_Delta *self) x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */ if (x2 == NULL) goto Done; - Py_DECREF(x1); - x1 = NULL; + Py_SETREF(x1, NULL); /* x2 has days in seconds */ x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */ @@ -1782,8 +1865,7 @@ delta_to_microseconds(PyDateTime_Delta *self) x1 = PyNumber_Multiply(x3, us_per_second); /* us */ if (x1 == NULL) goto Done; - Py_DECREF(x3); - x3 = NULL; + Py_SETREF(x3, NULL); /* x1 has days+seconds in us */ x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self)); @@ -1850,8 +1932,7 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type) goto BadDivmod; } - num = PyTuple_GET_ITEM(tuple, 0); /* leftover seconds */ - Py_INCREF(num); + num = Py_NewRef(PyTuple_GET_ITEM(tuple, 0)); /* leftover seconds */ Py_DECREF(tuple); tuple = checked_divmod(num, seconds_per_day); @@ -1869,8 +1950,7 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type) goto BadDivmod; } - num = PyTuple_GET_ITEM(tuple, 0); /* leftover days */ - Py_INCREF(num); + num = Py_NewRef(PyTuple_GET_ITEM(tuple, 0)); /* leftover days */ d = _PyLong_AsInt(num); if (d == -1 && PyErr_Occurred()) { goto Done; @@ -1918,7 +1998,7 @@ get_float_as_integer_ratio(PyObject *floatobj) PyObject *ratio; assert(floatobj && PyFloat_Check(floatobj)); - ratio = _PyObject_CallMethodIdNoArgs(floatobj, &PyId_as_integer_ratio); + ratio = PyObject_CallMethodNoArgs(floatobj, &_Py_ID(as_integer_ratio)); if (ratio == NULL) { return NULL; } @@ -1955,8 +2035,7 @@ multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, goto error; } temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op)); - Py_DECREF(pyus_in); - pyus_in = NULL; + Py_SETREF(pyus_in, NULL); if (temp == NULL) goto error; pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op)); @@ -2881,8 +2960,6 @@ date_today(PyObject *cls, PyObject *dummy) { PyObject *time; PyObject *result; - _Py_IDENTIFIER(fromtimestamp); - time = time_time(); if (time == NULL) return NULL; @@ -2893,7 +2970,7 @@ date_today(PyObject *cls, PyObject *dummy) * time.time() delivers; if someone were gonzo about optimization, * date.today() could get away with plain C time(). */ - result = _PyObject_CallMethodIdOneArg(cls, &PyId_fromtimestamp, time); + result = PyObject_CallMethodOneArg(cls, &_Py_ID(fromtimestamp), time); Py_DECREF(time); return result; } @@ -2982,8 +3059,8 @@ date_fromisoformat(PyObject *cls, PyObject *dtstr) int year = 0, month = 0, day = 0; int rv; - if (len == 10) { - rv = parse_isoformat_date(dt_ptr, &year, &month, &day); + if (len == 7 || len == 8 || len == 10) { + rv = parse_isoformat_date(dt_ptr, len, &year, &month, &day); } else { rv = -1; @@ -3026,37 +3103,21 @@ date_fromisocalendar(PyObject *cls, PyObject *args, PyObject *kw) return NULL; } - if (week <= 0 || week >= 53) { - int out_of_range = 1; - if (week == 53) { - // ISO years have 53 weeks in it on years starting with a Thursday - // and on leap years starting on Wednesday - int first_weekday = weekday(year, 1, 1); - if (first_weekday == 3 || (first_weekday == 2 && is_leap(year))) { - out_of_range = 0; - } - } + int month; + int rv = iso_to_ymd(year, week, day, &year, &month, &day); - if (out_of_range) { - PyErr_Format(PyExc_ValueError, "Invalid week: %d", week); - return NULL; - } + + if (rv == -2) { + PyErr_Format(PyExc_ValueError, "Invalid week: %d", week); + return NULL; } - if (day <= 0 || day >= 8) { + if (rv == -3) { PyErr_Format(PyExc_ValueError, "Invalid day: %d (range is [1, 7])", day); return NULL; } - // Convert (Y, W, D) to (Y, M, D) in-place - int day_1 = iso_week1_monday(year); - - int month = week; - int day_offset = (month - 1)*7 + day - 1; - - ord_to_ymd(day_1 + day_offset, &year, &month, &day); - return new_date_subclass_ex(year, month, day, cls); } @@ -3160,7 +3221,7 @@ date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) static PyObject * date_str(PyDateTime_Date *self) { - return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat); + return PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(isoformat)); } @@ -3179,14 +3240,13 @@ date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw) PyObject *result; PyObject *tuple; PyObject *format; - _Py_IDENTIFIER(timetuple); static char *keywords[] = {"format", NULL}; if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords, &format)) return NULL; - tuple = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_timetuple); + tuple = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(timetuple)); if (tuple == NULL) return NULL; result = wrap_strftime((PyObject *)self, format, tuple, @@ -3207,7 +3267,7 @@ date_format(PyDateTime_Date *self, PyObject *args) if (PyUnicode_GetLength(format) == 0) return PyObject_Str((PyObject *)self); - return _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId_strftime, + return PyObject_CallMethodOneArg((PyObject *)self, &_Py_ID(strftime), format); } @@ -3272,8 +3332,7 @@ iso_calendar_date_year(PyDateTime_IsoCalendarDate *self, void *unused) if (year == NULL) { return NULL; } - Py_INCREF(year); - return year; + return Py_NewRef(year); } static PyObject * @@ -3283,8 +3342,7 @@ iso_calendar_date_week(PyDateTime_IsoCalendarDate *self, void *unused) if (week == NULL) { return NULL; } - Py_INCREF(week); - return week; + return Py_NewRef(week); } static PyObject * @@ -3294,8 +3352,7 @@ iso_calendar_date_weekday(PyDateTime_IsoCalendarDate *self, void *unused) if (weekday == NULL) { return NULL; } - Py_INCREF(weekday); - return weekday; + return Py_NewRef(weekday); } static PyGetSetDef iso_calendar_date_getset[] = { @@ -3488,9 +3545,9 @@ static PyMethodDef date_methods[] = { {"fromisoformat", (PyCFunction)date_fromisoformat, METH_O | METH_CLASS, - PyDoc_STR("str -> Construct a date from the output of date.isoformat()")}, + PyDoc_STR("str -> Construct a date from a string in ISO 8601 format.")}, - {"fromisocalendar", (PyCFunction)(void(*)(void))date_fromisocalendar, + {"fromisocalendar", _PyCFunction_CAST(date_fromisocalendar), METH_VARARGS | METH_KEYWORDS | METH_CLASS, PyDoc_STR("int, int, int -> Construct a date from the ISO year, week " "number and weekday.\n\n" @@ -3505,7 +3562,7 @@ static PyMethodDef date_methods[] = { {"ctime", (PyCFunction)date_ctime, METH_NOARGS, PyDoc_STR("Return ctime() style string.")}, - {"strftime", (PyCFunction)(void(*)(void))date_strftime, METH_VARARGS | METH_KEYWORDS, + {"strftime", _PyCFunction_CAST(date_strftime), METH_VARARGS | METH_KEYWORDS, PyDoc_STR("format -> strftime() style string.")}, {"__format__", (PyCFunction)date_format, METH_VARARGS, @@ -3533,7 +3590,7 @@ static PyMethodDef date_methods[] = { PyDoc_STR("Return the day of the week represented by the date.\n" "Monday == 0 ... Sunday == 6")}, - {"replace", (PyCFunction)(void(*)(void))date_replace, METH_VARARGS | METH_KEYWORDS, + {"replace", _PyCFunction_CAST(date_replace), METH_VARARGS | METH_KEYWORDS, PyDoc_STR("Return date with new specified fields.")}, {"__reduce__", (PyCFunction)date_reduce, METH_NOARGS, @@ -3735,11 +3792,9 @@ static PyObject * tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *args, *state; - PyObject *getinitargs, *getstate; - _Py_IDENTIFIER(__getinitargs__); - _Py_IDENTIFIER(__getstate__); + PyObject *getinitargs; - if (_PyObject_LookupAttrId(self, &PyId___getinitargs__, &getinitargs) < 0) { + if (_PyObject_LookupAttr(self, &_Py_ID(__getinitargs__), &getinitargs) < 0) { return NULL; } if (getinitargs != NULL) { @@ -3753,34 +3808,13 @@ tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) return NULL; } - if (_PyObject_LookupAttrId(self, &PyId___getstate__, &getstate) < 0) { + state = _PyObject_GetState(self); + if (state == NULL) { Py_DECREF(args); return NULL; } - if (getstate != NULL) { - state = PyObject_CallNoArgs(getstate); - Py_DECREF(getstate); - if (state == NULL) { - Py_DECREF(args); - return NULL; - } - } - else { - PyObject **dictptr; - state = Py_None; - dictptr = _PyObject_GetDictPtr(self); - if (dictptr && *dictptr && PyDict_GET_SIZE(*dictptr)) { - state = *dictptr; - } - Py_INCREF(state); - } - if (state == Py_None) { - Py_DECREF(state); - return Py_BuildValue("(ON)", Py_TYPE(self), args); - } - else - return Py_BuildValue("(ONN)", Py_TYPE(self), args, state); + return Py_BuildValue("(ONN)", Py_TYPE(self), args, state); } static PyMethodDef tzinfo_methods[] = { @@ -3929,8 +3963,7 @@ timezone_str(PyDateTime_TimeZone *self) char sign; if (self->name != NULL) { - Py_INCREF(self->name); - return self->name; + return Py_NewRef(self->name); } if ((PyObject *)self == PyDateTime_TimeZone_UTC || (GET_TD_DAYS(self->offset) == 0 && @@ -3946,8 +3979,7 @@ timezone_str(PyDateTime_TimeZone *self) } else { sign = '+'; - offset = self->offset; - Py_INCREF(offset); + offset = Py_NewRef(self->offset); } /* Offset is not negative here. */ microseconds = GET_TD_MICROSECONDS(offset); @@ -3982,8 +4014,7 @@ timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt) if (_timezone_check_argument(dt, "utcoffset") == -1) return NULL; - Py_INCREF(self->offset); - return self->offset; + return Py_NewRef(self->offset); } static PyObject * @@ -4120,8 +4151,7 @@ static PyObject * time_tzinfo(PyDateTime_Time *self, void *unused) { PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None; - Py_INCREF(result); - return result; + return Py_NewRef(result); } static PyObject * @@ -4166,8 +4196,7 @@ time_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo) me->hashcode = -1; me->hastzinfo = aware; if (aware) { - Py_INCREF(tzinfo); - me->tzinfo = tzinfo; + me->tzinfo = Py_NewRef(tzinfo); } if (pdata[0] & (1 << 7)) { me->data[0] -= 128; @@ -4305,7 +4334,7 @@ time_repr(PyDateTime_Time *self) static PyObject * time_str(PyDateTime_Time *self) { - return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat); + return PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(isoformat)); } static PyObject * @@ -4463,12 +4492,10 @@ time_richcompare(PyObject *self, PyObject *other, int op) result = diff_to_bool(diff, op); } else if (op == Py_EQ) { - result = Py_False; - Py_INCREF(result); + result = Py_NewRef(Py_False); } else if (op == Py_NE) { - result = Py_True; - Py_INCREF(result); + result = Py_NewRef(Py_True); } else { PyErr_SetString(PyExc_TypeError, @@ -4497,8 +4524,7 @@ time_hash(PyDateTime_Time *self) return -1; } else { - self0 = (PyObject *)self; - Py_INCREF(self0); + self0 = Py_NewRef(self); } offset = time_utcoffset(self0, NULL); Py_DECREF(self0); @@ -4585,6 +4611,14 @@ time_fromisoformat(PyObject *cls, PyObject *tstr) { goto invalid_string_error; } + // The spec actually requires that time-only ISO 8601 strings start with + // T, but the extended format allows this to be omitted as long as there + // is no ambiguity with date strings. + if (*p == 'T') { + ++p; + len -= 1; + } + int hour = 0, minute = 0, second = 0, microsecond = 0; int tzoffset, tzimicrosecond = 0; int rv = parse_isoformat_time(p, len, @@ -4665,7 +4699,7 @@ time_reduce(PyDateTime_Time *self, PyObject *arg) static PyMethodDef time_methods[] = { - {"isoformat", (PyCFunction)(void(*)(void))time_isoformat, METH_VARARGS | METH_KEYWORDS, + {"isoformat", _PyCFunction_CAST(time_isoformat), METH_VARARGS | METH_KEYWORDS, PyDoc_STR("Return string in ISO 8601 format, [HH[:MM[:SS[.mmm[uuu]]]]]" "[+HH:MM].\n\n" "The optional argument timespec specifies the number " @@ -4673,7 +4707,7 @@ static PyMethodDef time_methods[] = { "options are 'auto', 'hours', 'minutes',\n'seconds', " "'milliseconds' and 'microseconds'.\n")}, - {"strftime", (PyCFunction)(void(*)(void))time_strftime, METH_VARARGS | METH_KEYWORDS, + {"strftime", _PyCFunction_CAST(time_strftime), METH_VARARGS | METH_KEYWORDS, PyDoc_STR("format -> strftime() style string.")}, {"__format__", (PyCFunction)date_format, METH_VARARGS, @@ -4688,11 +4722,11 @@ static PyMethodDef time_methods[] = { {"dst", (PyCFunction)time_dst, METH_NOARGS, PyDoc_STR("Return self.tzinfo.dst(self).")}, - {"replace", (PyCFunction)(void(*)(void))time_replace, METH_VARARGS | METH_KEYWORDS, + {"replace", _PyCFunction_CAST(time_replace), METH_VARARGS | METH_KEYWORDS, PyDoc_STR("Return time with new specified fields.")}, {"fromisoformat", (PyCFunction)time_fromisoformat, METH_O | METH_CLASS, - PyDoc_STR("string -> time from time.isoformat() output")}, + PyDoc_STR("string -> time from a string in ISO 8601 format")}, {"__reduce_ex__", (PyCFunction)time_reduce_ex, METH_VARARGS, PyDoc_STR("__reduce_ex__(proto) -> (cls, state)")}, @@ -4787,8 +4821,7 @@ static PyObject * datetime_tzinfo(PyDateTime_DateTime *self, void *unused) { PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None; - Py_INCREF(result); - return result; + return Py_NewRef(result); } static PyObject * @@ -4835,8 +4868,7 @@ datetime_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo) me->hashcode = -1; me->hastzinfo = aware; if (aware) { - Py_INCREF(tzinfo); - me->tzinfo = tzinfo; + me->tzinfo = Py_NewRef(tzinfo); } if (pdata[2] & (1 << 7)) { me->data[2] -= 128; @@ -5008,6 +5040,10 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us, result_seconds = utc_to_seconds(year, month, day, hour, minute, second); + if (result_seconds == -1 && PyErr_Occurred()) { + return NULL; + } + /* Probe max_fold_seconds to detect a fold. */ probe_seconds = local(epoch + timet - max_fold_seconds); if (probe_seconds == -1) @@ -5095,7 +5131,9 @@ datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz) tz); if (self != NULL && tz != Py_None) { /* Convert UTC to tzinfo's zone. */ - self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self); + PyObject *res = PyObject_CallMethodOneArg(tz, &_Py_ID(fromutc), self); + Py_DECREF(self); + return res; } return self; } @@ -5131,7 +5169,9 @@ datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) tzinfo); if (self != NULL && tzinfo != Py_None) { /* Convert UTC to tzinfo's zone. */ - self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self); + PyObject *res = PyObject_CallMethodOneArg(tzinfo, &_Py_ID(fromutc), self); + Py_DECREF(self); + return res; } return self; } @@ -5155,17 +5195,16 @@ datetime_strptime(PyObject *cls, PyObject *args) { static PyObject *module = NULL; PyObject *string, *format; - _Py_IDENTIFIER(_strptime_datetime); if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format)) return NULL; if (module == NULL) { - module = PyImport_ImportModuleNoBlock("_strptime"); + module = PyImport_ImportModule("_strptime"); if (module == NULL) return NULL; } - return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime, + return PyObject_CallMethodObjArgs(module, &_Py_ID(_strptime_datetime), cls, string, format, NULL); } @@ -5205,21 +5244,43 @@ datetime_combine(PyObject *cls, PyObject *args, PyObject *kw) static PyObject * _sanitize_isoformat_str(PyObject *dtstr) { + Py_ssize_t len = PyUnicode_GetLength(dtstr); + if (len < 7) { // All valid ISO 8601 strings are at least 7 characters long + return NULL; + } + // `fromisoformat` allows surrogate characters in exactly one position, // the separator; to allow datetime_fromisoformat to make the simplifying // assumption that all valid strings can be encoded in UTF-8, this function // replaces any surrogate character separators with `T`. // // The result of this, if not NULL, returns a new reference - Py_ssize_t len = PyUnicode_GetLength(dtstr); - if (len < 0) { - return NULL; + const void* const unicode_data = PyUnicode_DATA(dtstr); + const int kind = PyUnicode_KIND(dtstr); + + // Depending on the format of the string, the separator can only ever be + // in positions 7, 8 or 10. We'll check each of these for a surrogate and + // if we find one, replace it with `T`. If there is more than one surrogate, + // we don't have to bother sanitizing it, because the function will later + // fail when we try to encode the string as ASCII. + static const size_t potential_separators[3] = {7, 8, 10}; + size_t surrogate_separator = 0; + for(size_t idx = 0; + idx < sizeof(potential_separators) / sizeof(*potential_separators); + ++idx) { + size_t pos = potential_separators[idx]; + if (pos > (size_t)len) { + break; + } + + if(Py_UNICODE_IS_SURROGATE(PyUnicode_READ(kind, unicode_data, pos))) { + surrogate_separator = pos; + break; + } } - if (len <= 10 || - !Py_UNICODE_IS_SURROGATE(PyUnicode_READ_CHAR(dtstr, 10))) { - Py_INCREF(dtstr); - return dtstr; + if (surrogate_separator == 0) { + return Py_NewRef(dtstr); } PyObject *str_out = _PyUnicode_Copy(dtstr); @@ -5227,7 +5288,7 @@ _sanitize_isoformat_str(PyObject *dtstr) return NULL; } - if (PyUnicode_WriteChar(str_out, 10, (Py_UCS4)'T')) { + if (PyUnicode_WriteChar(str_out, surrogate_separator, (Py_UCS4)'T')) { Py_DECREF(str_out); return NULL; } @@ -5235,6 +5296,106 @@ _sanitize_isoformat_str(PyObject *dtstr) return str_out; } + +static Py_ssize_t +_find_isoformat_datetime_separator(const char *dtstr, Py_ssize_t len) { + // The valid date formats can all be distinguished by characters 4 and 5 + // and further narrowed down by character + // which tells us where to look for the separator character. + // Format | As-rendered | Position + // --------------------------------------- + // %Y-%m-%d | YYYY-MM-DD | 10 + // %Y%m%d | YYYYMMDD | 8 + // %Y-W%V | YYYY-Www | 8 + // %YW%V | YYYYWww | 7 + // %Y-W%V-%u | YYYY-Www-d | 10 + // %YW%V%u | YYYYWwwd | 8 + // %Y-%j | YYYY-DDD | 8 + // %Y%j | YYYYDDD | 7 + // + // Note that because we allow *any* character for the separator, in the + // case where character 4 is W, it's not straightforward to determine where + // the separator is — in the case of YYYY-Www-d, you have actual ambiguity, + // e.g. 2020-W01-0000 could be YYYY-Www-D0HH or YYYY-Www-HHMM, when the + // separator character is a number in the former case or a hyphen in the + // latter case. + // + // The case of YYYYWww can be distinguished from YYYYWwwd by tracking ahead + // to either the end of the string or the first non-numeric character — + // since the time components all come in pairs YYYYWww#HH can be + // distinguished from YYYYWwwd#HH by the fact that there will always be an + // odd number of digits before the first non-digit character in the former + // case. + static const char date_separator = '-'; + static const char week_indicator = 'W'; + + if (len == 7) { + return 7; + } + + if (dtstr[4] == date_separator) { + // YYYY-??? + + if (dtstr[5] == week_indicator) { + // YYYY-W?? + + if (len < 8) { + return -1; + } + + if (len > 8 && dtstr[8] == date_separator) { + // YYYY-Www-D (10) or YYYY-Www-HH (8) + if (len == 9) { return -1; } + if (len > 10 && is_digit(dtstr[10])) { + // This is as far as we'll try to go to resolve the + // ambiguity for the moment — if we have YYYY-Www-##, the + // separator is either a hyphen at 8 or a number at 10. + // + // We'll assume it's a hyphen at 8 because it's way more + // likely that someone will use a hyphen as a separator + // than a number, but at this point it's really best effort + // because this is an extension of the spec anyway. + return 8; + } + + return 10; + } else { + // YYYY-Www (8) + return 8; + } + } else { + // YYYY-MM-DD (10) + return 10; + } + } else { + // YYYY??? + if (dtstr[4] == week_indicator) { + // YYYYWww (7) or YYYYWwwd (8) + size_t idx = 7; + for (; idx < (size_t)len; ++idx) { + // Keep going until we run out of digits. + if (!is_digit(dtstr[idx])) { + break; + } + } + + if (idx < 9) { + return idx; + } + + if (idx % 2 == 0) { + // If the index of the last number is even, it's YYYYWww + return 7; + } else { + return 8; + } + } else { + // YYYYMMDD (8) + return 8; + } + } +} + static PyObject * datetime_fromisoformat(PyObject *cls, PyObject *dtstr) { @@ -5246,9 +5407,14 @@ datetime_fromisoformat(PyObject *cls, PyObject *dtstr) return NULL; } + // We only need to sanitize this string if the separator is a surrogate + // character. In the situation where the separator location is ambiguous, + // we don't have to sanitize it anything because that can only happen when + // the separator is either '-' or a number. This should mostly be a noop + // but it makes the reference counting easier if we still sanitize. PyObject *dtstr_clean = _sanitize_isoformat_str(dtstr); if (dtstr_clean == NULL) { - goto error; + goto invalid_string_error; } Py_ssize_t len; @@ -5264,30 +5430,35 @@ datetime_fromisoformat(PyObject *cls, PyObject *dtstr) } } + const Py_ssize_t separator_location = _find_isoformat_datetime_separator( + dt_ptr, len); + + const char *p = dt_ptr; int year = 0, month = 0, day = 0; int hour = 0, minute = 0, second = 0, microsecond = 0; int tzoffset = 0, tzusec = 0; - // date has a fixed length of 10 - int rv = parse_isoformat_date(p, &year, &month, &day); + // date runs up to separator_location + int rv = parse_isoformat_date(p, separator_location, &year, &month, &day); - if (!rv && len > 10) { + if (!rv && len > separator_location) { // In UTF-8, the length of multi-byte characters is encoded in the MSB - if ((p[10] & 0x80) == 0) { - p += 11; + p += separator_location; + if ((p[0] & 0x80) == 0) { + p += 1; } else { - switch (p[10] & 0xf0) { + switch (p[0] & 0xf0) { case 0xe0: - p += 13; + p += 3; break; case 0xf0: - p += 14; + p += 4; break; default: - p += 12; + p += 2; break; } } @@ -5423,9 +5594,8 @@ datetime_subtract(PyObject *left, PyObject *right) int delta_d, delta_s, delta_us; if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) { - offset2 = offset1 = Py_None; - Py_INCREF(offset1); - Py_INCREF(offset2); + offset1 = Py_NewRef(Py_None); + offset2 = Py_NewRef(Py_None); } else { offset1 = datetime_utcoffset(left, NULL); @@ -5539,7 +5709,14 @@ datetime_repr(PyDateTime_DateTime *self) static PyObject * datetime_str(PyDateTime_DateTime *self) { - return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " "); + PyObject *space = PyUnicode_FromString(" "); + if (space == NULL) { + return NULL; + } + PyObject *res = PyObject_CallMethodOneArg((PyObject *)self, + &_Py_ID(isoformat), space); + Py_DECREF(space); + return res; } static PyObject * @@ -5763,12 +5940,10 @@ datetime_richcompare(PyObject *self, PyObject *other, int op) result = diff_to_bool(diff, op); } else if (op == Py_EQ) { - result = Py_False; - Py_INCREF(result); + result = Py_NewRef(Py_False); } else if (op == Py_NE) { - result = Py_True; - Py_INCREF(result); + result = Py_NewRef(Py_True); } else { PyErr_SetString(PyExc_TypeError, @@ -5800,8 +5975,7 @@ datetime_hash(PyDateTime_DateTime *self) return -1; } else { - self0 = (PyObject *)self; - Py_INCREF(self0); + self0 = Py_NewRef(self); } offset = datetime_utcoffset(self0, NULL); Py_DECREF(self0); @@ -6018,15 +6192,13 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) if (self_tzinfo == NULL) return NULL; } else { - self_tzinfo = self->tzinfo; - Py_INCREF(self_tzinfo); + self_tzinfo = Py_NewRef(self->tzinfo); } /* Conversion to self's own time zone is a NOP. */ if (self_tzinfo == tzinfo) { Py_DECREF(self_tzinfo); - Py_INCREF(self); - return self; + return (PyDateTime_DateTime*)Py_NewRef(self); } /* Convert self to UTC. */ @@ -6071,14 +6243,10 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) } else { /* Result is already aware - just replace tzinfo. */ - temp = result->tzinfo; - result->tzinfo = PyDateTime_TimeZone_UTC; - Py_INCREF(result->tzinfo); - Py_DECREF(temp); + Py_SETREF(result->tzinfo, Py_NewRef(PyDateTime_TimeZone_UTC)); } /* Attach new tzinfo and let fromutc() do the rest. */ - temp = result->tzinfo; if (tzinfo == Py_None) { tzinfo = local_timezone(result); if (tzinfo == NULL) { @@ -6088,12 +6256,11 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) } else Py_INCREF(tzinfo); - result->tzinfo = tzinfo; - Py_DECREF(temp); + Py_SETREF(result->tzinfo, tzinfo); temp = (PyObject *)result; result = (PyDateTime_DateTime *) - _PyObject_CallMethodIdOneArg(tzinfo, &PyId_fromutc, temp); + PyObject_CallMethodOneArg(tzinfo, &_Py_ID(fromutc), temp); Py_DECREF(temp); return result; @@ -6243,8 +6410,7 @@ datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) tzinfo = GET_DT_TZINFO(self); if (tzinfo == Py_None) { - utcself = self; - Py_INCREF(utcself); + utcself = (PyDateTime_DateTime*)Py_NewRef(self); } else { PyObject *offset; @@ -6253,8 +6419,7 @@ datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) return NULL; if (offset == Py_None) { Py_DECREF(offset); - utcself = self; - Py_INCREF(utcself); + utcself = (PyDateTime_DateTime*)Py_NewRef(self); } else { utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self, @@ -6329,7 +6494,7 @@ static PyMethodDef datetime_methods[] = { METH_NOARGS | METH_CLASS, PyDoc_STR("Return a new datetime representing UTC day and time.")}, - {"fromtimestamp", (PyCFunction)(void(*)(void))datetime_fromtimestamp, + {"fromtimestamp", _PyCFunction_CAST(datetime_fromtimestamp), METH_VARARGS | METH_KEYWORDS | METH_CLASS, PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")}, @@ -6342,13 +6507,13 @@ static PyMethodDef datetime_methods[] = { PyDoc_STR("string, format -> new datetime parsed from a string " "(like time.strptime()).")}, - {"combine", (PyCFunction)(void(*)(void))datetime_combine, + {"combine", _PyCFunction_CAST(datetime_combine), METH_VARARGS | METH_KEYWORDS | METH_CLASS, PyDoc_STR("date, time -> datetime with same date and time fields")}, {"fromisoformat", (PyCFunction)datetime_fromisoformat, METH_O | METH_CLASS, - PyDoc_STR("string -> datetime from datetime.isoformat() output")}, + PyDoc_STR("string -> datetime from a string in most ISO 8601 formats")}, /* Instance methods: */ @@ -6373,7 +6538,7 @@ static PyMethodDef datetime_methods[] = { {"utctimetuple", (PyCFunction)datetime_utctimetuple, METH_NOARGS, PyDoc_STR("Return UTC time tuple, compatible with time.localtime().")}, - {"isoformat", (PyCFunction)(void(*)(void))datetime_isoformat, METH_VARARGS | METH_KEYWORDS, + {"isoformat", _PyCFunction_CAST(datetime_isoformat), METH_VARARGS | METH_KEYWORDS, PyDoc_STR("[sep] -> string in ISO 8601 format, " "YYYY-MM-DDT[HH[:MM[:SS[.mmm[uuu]]]]][+HH:MM].\n" "sep is used to separate the year from the time, and " @@ -6392,10 +6557,10 @@ static PyMethodDef datetime_methods[] = { {"dst", (PyCFunction)datetime_dst, METH_NOARGS, PyDoc_STR("Return self.tzinfo.dst(self).")}, - {"replace", (PyCFunction)(void(*)(void))datetime_replace, METH_VARARGS | METH_KEYWORDS, + {"replace", _PyCFunction_CAST(datetime_replace), METH_VARARGS | METH_KEYWORDS, PyDoc_STR("Return datetime with new specified fields.")}, - {"astimezone", (PyCFunction)(void(*)(void))datetime_astimezone, METH_VARARGS | METH_KEYWORDS, + {"astimezone", _PyCFunction_CAST(datetime_astimezone), METH_VARARGS | METH_KEYWORDS, PyDoc_STR("tz -> convert to local time in new timezone tz\n")}, {"__reduce_ex__", (PyCFunction)datetime_reduce_ex, METH_VARARGS, @@ -6655,22 +6820,26 @@ _datetime_exec(PyObject *module) return -1; } + if (PyModule_AddObjectRef(module, "UTC", PyDateTime_TimeZone_UTC) < 0) { + return -1; + } + /* A 4-year cycle has an extra leap day over what we'd get from * pasting together 4 single years. */ - Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1); + static_assert(DI4Y == 4 * 365 + 1, "DI4Y"); assert(DI4Y == days_before_year(4+1)); /* Similarly, a 400-year cycle has an extra leap day over what we'd * get from pasting together 4 100-year cycles. */ - Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1); + static_assert(DI400Y == 4 * DI100Y + 1, "DI400Y"); assert(DI400Y == days_before_year(400+1)); /* OTOH, a 100-year cycle has one fewer leap day than we'd get from * pasting together 25 4-year cycles. */ - Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1); + static_assert(DI100Y == 25 * DI4Y - 1, "DI100Y"); assert(DI100Y == days_before_year(100+1)); us_per_ms = PyLong_FromLong(1000); diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index c0371fb3f3b..54376022dcb 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -12,10 +12,7 @@ /* Some Linux systems install gdbm/ndbm.h, but not ndbm.h. This supports * whichever configure was able to locate. */ -#if defined(USE_NDBM) - #include - static const char which_dbm[] = "GNU gdbm"; /* EMX port of GDBM */ -#elif defined(USE_GDBM_COMPAT) +#if defined(USE_GDBM_COMPAT) #ifdef HAVE_GDBM_NDBM_H #include #elif HAVE_GDBM_DASH_NDBM_H @@ -24,6 +21,9 @@ #error "No gdbm/ndbm.h or gdbm-ndbm.h available" #endif static const char which_dbm[] = "GNU gdbm"; +#elif defined(USE_NDBM) + #include + static const char which_dbm[] = "GNU gdbm"; #elif defined(USE_BERKDB) #ifndef DB_DBM_HSEARCH #define DB_DBM_HSEARCH 1 @@ -130,6 +130,37 @@ dbm_length(dbmobject *dp) return dp->di_size; } +static int +dbm_bool(dbmobject *dp) +{ + _dbm_state *state = PyType_GetModuleState(Py_TYPE(dp)); + assert(state != NULL); + + if (dp->di_dbm == NULL) { + PyErr_SetString(state->dbm_error, "DBM object has already been closed"); + return -1; + } + + if (dp->di_size > 0) { + /* Known non-zero size. */ + return 1; + } + if (dp->di_size == 0) { + /* Known zero size. */ + return 0; + } + + /* Unknown size. Ensure DBM object has an entry. */ + datum key = dbm_firstkey(dp->di_dbm); + if (key.dptr == NULL) { + /* Empty. Cache this fact. */ + dp->di_size = 0; + return 0; + } + /* Non-empty. Don't cache the length since we don't know. */ + return 1; +} + static PyObject * dbm_subscript(dbmobject *dp, PyObject *key) { @@ -327,8 +358,7 @@ _dbm_dbm_get_impl(dbmobject *self, PyTypeObject *cls, const char *key, return PyBytes_FromStringAndSize(val.dptr, val.dsize); } - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } /*[clinic input] @@ -388,15 +418,13 @@ _dbm_dbm_setdefault_impl(dbmobject *self, PyTypeObject *cls, const char *key, static PyObject * dbm__enter__(PyObject *self, PyObject *args) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * dbm__exit__(PyObject *self, PyObject *args) { - _Py_IDENTIFIER(close); - return _PyObject_CallMethodIdNoArgs(self, &PyId_close); + return _dbm_dbm_close_impl((dbmobject *)self); } static PyMethodDef dbm_methods[] = { @@ -417,6 +445,7 @@ static PyType_Slot dbmtype_spec_slots[] = { {Py_mp_length, dbm_length}, {Py_mp_subscript, dbm_subscript}, {Py_mp_ass_subscript, dbm_ass_sub}, + {Py_nb_bool, dbm_bool}, {0, 0} }; diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 7fc7315603e..bc97615ffb4 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -116,15 +116,13 @@ static PyTypeObject PyDecContextManager_Type; Py_LOCAL_INLINE(PyObject *) incr_true(void) { - Py_INCREF(Py_True); - return Py_True; + return Py_NewRef(Py_True); } Py_LOCAL_INLINE(PyObject *) incr_false(void) { - Py_INCREF(Py_False); - return Py_False; + return Py_NewRef(Py_False); } @@ -655,8 +653,7 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op) } } - Py_INCREF(res); - return res; + return Py_NewRef(res); } static PyObject * @@ -754,8 +751,7 @@ context_getround(PyObject *self, void *closure UNUSED) { int i = mpd_getround(CTX(self)); - Py_INCREF(round_map[i]); - return round_map[i]; + return Py_NewRef(round_map[i]); } static PyObject * @@ -1122,13 +1118,11 @@ context_getattr(PyObject *self, PyObject *name) if (PyUnicode_Check(name)) { if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) { retval = ((PyDecContextObject *)self)->traps; - Py_INCREF(retval); - return retval; + return Py_NewRef(retval); } if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) { retval = ((PyDecContextObject *)self)->flags; - Py_INCREF(retval); - return retval; + return Py_NewRef(retval); } } @@ -1156,6 +1150,67 @@ context_setattr(PyObject *self, PyObject *name, PyObject *value) return PyObject_GenericSetAttr(self, name, value); } +static int +context_setattrs(PyObject *self, PyObject *prec, PyObject *rounding, + PyObject *emin, PyObject *emax, PyObject *capitals, + PyObject *clamp, PyObject *status, PyObject *traps) { + + int ret; + if (prec != Py_None && context_setprec(self, prec, NULL) < 0) { + return -1; + } + if (rounding != Py_None && context_setround(self, rounding, NULL) < 0) { + return -1; + } + if (emin != Py_None && context_setemin(self, emin, NULL) < 0) { + return -1; + } + if (emax != Py_None && context_setemax(self, emax, NULL) < 0) { + return -1; + } + if (capitals != Py_None && context_setcapitals(self, capitals, NULL) < 0) { + return -1; + } + if (clamp != Py_None && context_setclamp(self, clamp, NULL) < 0) { + return -1; + } + + if (traps != Py_None) { + if (PyList_Check(traps)) { + ret = context_settraps_list(self, traps); + } +#ifdef EXTRA_FUNCTIONALITY + else if (PyLong_Check(traps)) { + ret = context_settraps(self, traps, NULL); + } +#endif + else { + ret = context_settraps_dict(self, traps); + } + if (ret < 0) { + return ret; + } + } + if (status != Py_None) { + if (PyList_Check(status)) { + ret = context_setstatus_list(self, status); + } +#ifdef EXTRA_FUNCTIONALITY + else if (PyLong_Check(status)) { + ret = context_setstatus(self, status, NULL); + } +#endif + else { + ret = context_setstatus_dict(self, status); + } + if (ret < 0) { + return ret; + } + } + + return 0; +} + static PyObject * context_clear_traps(PyObject *self, PyObject *dummy UNUSED) { @@ -1255,7 +1310,6 @@ context_init(PyObject *self, PyObject *args, PyObject *kwds) PyObject *clamp = Py_None; PyObject *status = Py_None; PyObject *traps = Py_None; - int ret; assert(PyTuple_Check(args)); @@ -1267,59 +1321,11 @@ context_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; } - if (prec != Py_None && context_setprec(self, prec, NULL) < 0) { - return -1; - } - if (rounding != Py_None && context_setround(self, rounding, NULL) < 0) { - return -1; - } - if (emin != Py_None && context_setemin(self, emin, NULL) < 0) { - return -1; - } - if (emax != Py_None && context_setemax(self, emax, NULL) < 0) { - return -1; - } - if (capitals != Py_None && context_setcapitals(self, capitals, NULL) < 0) { - return -1; - } - if (clamp != Py_None && context_setclamp(self, clamp, NULL) < 0) { - return -1; - } - - if (traps != Py_None) { - if (PyList_Check(traps)) { - ret = context_settraps_list(self, traps); - } -#ifdef EXTRA_FUNCTIONALITY - else if (PyLong_Check(traps)) { - ret = context_settraps(self, traps, NULL); - } -#endif - else { - ret = context_settraps_dict(self, traps); - } - if (ret < 0) { - return ret; - } - } - if (status != Py_None) { - if (PyList_Check(status)) { - ret = context_setstatus_list(self, status); - } -#ifdef EXTRA_FUNCTIONALITY - else if (PyLong_Check(status)) { - ret = context_setstatus(self, status, NULL); - } -#endif - else { - ret = context_setstatus_dict(self, status); - } - if (ret < 0) { - return ret; - } - } - - return 0; + return context_setattrs( + self, prec, rounding, + emin, emax, capitals, + clamp, status, traps + ); } static PyObject * @@ -1590,8 +1596,7 @@ PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED) return NULL; } - Py_INCREF(context); - return context; + return Py_NewRef(context); } /* Set the thread local context to a new context, decrement old reference */ @@ -1721,13 +1726,28 @@ PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) static PyObject * ctxmanager_new(PyTypeObject *type UNUSED, PyObject *args, PyObject *kwds) { - static char *kwlist[] = {"ctx", NULL}; + static char *kwlist[] = { + "ctx", "prec", "rounding", + "Emin", "Emax", "capitals", + "clamp", "flags", "traps", + NULL + }; PyDecContextManagerObject *self; PyObject *local = Py_None; PyObject *global; + PyObject *prec = Py_None; + PyObject *rounding = Py_None; + PyObject *Emin = Py_None; + PyObject *Emax = Py_None; + PyObject *capitals = Py_None; + PyObject *clamp = Py_None; + PyObject *flags = Py_None; + PyObject *traps = Py_None; + CURRENT_CONTEXT(global); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &local)) { + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOOOOOO", kwlist, &local, + &prec, &rounding, &Emin, &Emax, &capitals, &clamp, &flags, &traps)) { return NULL; } if (local == Py_None) { @@ -1751,8 +1771,18 @@ ctxmanager_new(PyTypeObject *type UNUSED, PyObject *args, PyObject *kwds) Py_DECREF(self); return NULL; } - self->global = global; - Py_INCREF(self->global); + self->global = Py_NewRef(global); + + int ret = context_setattrs( + self->local, prec, rounding, + Emin, Emax, capitals, + clamp, flags, traps + ); + + if (ret < 0) { + Py_DECREF(self); + return NULL; + } return (PyObject *)self; } @@ -1776,8 +1806,7 @@ ctxmanager_set_local(PyDecContextManagerObject *self, PyObject *args UNUSED) } Py_DECREF(ret); - Py_INCREF(self->local); - return self->local; + return Py_NewRef(self->local); } static PyObject * @@ -1880,7 +1909,7 @@ dec_dealloc(PyObject *dec) /******************************************************************************/ Py_LOCAL_INLINE(int) -is_space(enum PyUnicode_Kind kind, const void *data, Py_ssize_t pos) +is_space(int kind, const void *data, Py_ssize_t pos) { Py_UCS4 ch = PyUnicode_READ(kind, data, pos); return Py_UNICODE_ISSPACE(ch); @@ -1895,9 +1924,9 @@ is_space(enum PyUnicode_Kind kind, const void *data, Py_ssize_t pos) Return NULL if malloc fails and an empty string if invalid characters are found. */ static char * -numeric_as_ascii(const PyObject *u, int strip_ws, int ignore_underscores) +numeric_as_ascii(PyObject *u, int strip_ws, int ignore_underscores) { - enum PyUnicode_Kind kind; + int kind; const void *data; Py_UCS4 ch; char *res, *cp; @@ -2009,7 +2038,7 @@ PyDecType_FromCStringExact(PyTypeObject *type, const char *s, /* Return a new PyDecObject or a subtype from a PyUnicodeObject. */ static PyObject * -PyDecType_FromUnicode(PyTypeObject *type, const PyObject *u, +PyDecType_FromUnicode(PyTypeObject *type, PyObject *u, PyObject *context) { PyObject *dec; @@ -2029,7 +2058,7 @@ PyDecType_FromUnicode(PyTypeObject *type, const PyObject *u, * conversion. If the conversion is not exact, fail with InvalidOperation. * Allow leading and trailing whitespace in the input operand. */ static PyObject * -PyDecType_FromUnicodeExactWS(PyTypeObject *type, const PyObject *u, +PyDecType_FromUnicodeExactWS(PyTypeObject *type, PyObject *u, PyObject *context) { PyObject *dec; @@ -2112,7 +2141,7 @@ PyDecType_FromSsizeExact(PyTypeObject *type, mpd_ssize_t v, PyObject *context) /* Convert from a PyLongObject. The context is not modified; flags set during conversion are accumulated in the status parameter. */ static PyObject * -dec_from_long(PyTypeObject *type, const PyObject *v, +dec_from_long(PyTypeObject *type, PyObject *v, const mpd_context_t *ctx, uint32_t *status) { PyObject *dec; @@ -2163,7 +2192,7 @@ dec_from_long(PyTypeObject *type, const PyObject *v, /* Return a new PyDecObject from a PyLongObject. Use the context for conversion. */ static PyObject * -PyDecType_FromLong(PyTypeObject *type, const PyObject *v, PyObject *context) +PyDecType_FromLong(PyTypeObject *type, PyObject *v, PyObject *context) { PyObject *dec; uint32_t status = 0; @@ -2189,7 +2218,7 @@ PyDecType_FromLong(PyTypeObject *type, const PyObject *v, PyObject *context) /* Return a new PyDecObject from a PyLongObject. Use a maximum context for conversion. If the conversion is not exact, set InvalidOperation. */ static PyObject * -PyDecType_FromLongExact(PyTypeObject *type, const PyObject *v, +PyDecType_FromLongExact(PyTypeObject *type, PyObject *v, PyObject *context) { PyObject *dec; @@ -2380,8 +2409,7 @@ PyDecType_FromDecimalExact(PyTypeObject *type, PyObject *v, PyObject *context) uint32_t status = 0; if (type == &PyDec_Type && PyDec_CheckExact(v)) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } dec = PyDecType_New(type); @@ -2402,8 +2430,7 @@ static PyObject * sequence_as_tuple(PyObject *v, PyObject *ex, const char *mesg) { if (PyTuple_Check(v)) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } if (PyList_Check(v)) { return PyList_AsTuple(v); @@ -2825,8 +2852,7 @@ convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context) { if (PyDec_Check(v)) { - *conv = v; - Py_INCREF(v); + *conv = Py_NewRef(v); return 1; } if (PyLong_Check(v)) { @@ -2843,8 +2869,7 @@ convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context) Py_TYPE(v)->tp_name); } else { - Py_INCREF(Py_NotImplemented); - *conv = Py_NotImplemented; + *conv = Py_NewRef(Py_NotImplemented); } return 0; } @@ -3003,8 +3028,7 @@ convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w, *vcmp = v; if (PyDec_Check(w)) { - Py_INCREF(w); - *wcmp = w; + *wcmp = Py_NewRef(w); } else if (PyLong_Check(w)) { *wcmp = PyDec_FromLongExact(w, context); @@ -3036,8 +3060,7 @@ convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w, } } else { - Py_INCREF(Py_NotImplemented); - *wcmp = Py_NotImplemented; + *wcmp = Py_NewRef(Py_NotImplemented); } } else { @@ -3055,8 +3078,7 @@ convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w, } } else { - Py_INCREF(Py_NotImplemented); - *wcmp = Py_NotImplemented; + *wcmp = Py_NewRef(Py_NotImplemented); } } @@ -3183,6 +3205,56 @@ dotsep_as_utf8(const char *s) return utf8; } +/* copy of libmpdec _mpd_round() */ +static void +_mpd_round(mpd_t *result, const mpd_t *a, mpd_ssize_t prec, + const mpd_context_t *ctx, uint32_t *status) +{ + mpd_ssize_t exp = a->exp + a->digits - prec; + + if (prec <= 0) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + if (mpd_isspecial(a) || mpd_iszero(a)) { + mpd_qcopy(result, a, status); + return; + } + + mpd_qrescale_fmt(result, a, exp, ctx, status); + if (result->digits > prec) { + mpd_qrescale_fmt(result, result, exp+1, ctx, status); + } +} + +/* Locate negative zero "z" option within a UTF-8 format spec string. + * Returns pointer to "z", else NULL. + * The portion of the spec we're working with is [[fill]align][sign][z] */ +static const char * +format_spec_z_search(char const *fmt, Py_ssize_t size) { + char const *pos = fmt; + char const *fmt_end = fmt + size; + /* skip over [[fill]align] (fill may be multi-byte character) */ + pos += 1; + while (pos < fmt_end && *pos & 0x80) { + pos += 1; + } + if (pos < fmt_end && strchr("<>=^", *pos) != NULL) { + pos += 1; + } else { + /* fill not present-- skip over [align] */ + pos = fmt; + if (pos < fmt_end && strchr("<>=^", *pos) != NULL) { + pos += 1; + } + } + /* skip over [sign] */ + if (pos < fmt_end && strchr("+- ", *pos) != NULL) { + pos += 1; + } + return pos < fmt_end && *pos == 'z' ? pos : NULL; +} + static int dict_get_item_string(PyObject *dict, const char *key, PyObject **valueobj, const char **valuestr) { @@ -3220,11 +3292,16 @@ dec_format(PyObject *dec, PyObject *args) PyObject *fmtarg; PyObject *context; mpd_spec_t spec; - char *fmt; + char const *fmt; + char *fmt_copy = NULL; char *decstring = NULL; uint32_t status = 0; int replace_fillchar = 0; + int no_neg_0 = 0; Py_ssize_t size; + mpd_t *mpd = MPD(dec); + mpd_uint_t dt[MPD_MINALLOC_MAX]; + mpd_t tmp = {MPD_STATIC|MPD_STATIC_DATA,0,0,0,MPD_MINALLOC_MAX,dt}; CURRENT_CONTEXT(context); @@ -3233,19 +3310,39 @@ dec_format(PyObject *dec, PyObject *args) } if (PyUnicode_Check(fmtarg)) { - fmt = (char *)PyUnicode_AsUTF8AndSize(fmtarg, &size); + fmt = PyUnicode_AsUTF8AndSize(fmtarg, &size); if (fmt == NULL) { return NULL; } + /* NOTE: If https://github.com/python/cpython/pull/29438 lands, the + * format string manipulation below can be eliminated by enhancing + * the forked mpd_parse_fmt_str(). */ if (size > 0 && fmt[0] == '\0') { /* NUL fill character: must be replaced with a valid UTF-8 char before calling mpd_parse_fmt_str(). */ replace_fillchar = 1; - fmt = dec_strdup(fmt, size); - if (fmt == NULL) { + fmt = fmt_copy = dec_strdup(fmt, size); + if (fmt_copy == NULL) { return NULL; } - fmt[0] = '_'; + fmt_copy[0] = '_'; + } + /* Strip 'z' option, which isn't understood by mpd_parse_fmt_str(). + * NOTE: fmt is always null terminated by PyUnicode_AsUTF8AndSize() */ + char const *z_position = format_spec_z_search(fmt, size); + if (z_position != NULL) { + no_neg_0 = 1; + size_t z_index = z_position - fmt; + if (fmt_copy == NULL) { + fmt = fmt_copy = dec_strdup(fmt, size); + if (fmt_copy == NULL) { + return NULL; + } + } + /* Shift characters (including null terminator) left, + overwriting the 'z' option. */ + memmove(fmt_copy + z_index, fmt_copy + z_index + 1, size - z_index); + size -= 1; } } else { @@ -3311,8 +3408,45 @@ dec_format(PyObject *dec, PyObject *args) } } + if (no_neg_0 && mpd_isnegative(mpd) && !mpd_isspecial(mpd)) { + /* Round into a temporary (carefully mirroring the rounding + of mpd_qformat_spec()), and check if the result is negative zero. + If so, clear the sign and format the resulting positive zero. */ + mpd_ssize_t prec; + mpd_qcopy(&tmp, mpd, &status); + if (spec.prec >= 0) { + switch (spec.type) { + case 'f': + mpd_qrescale(&tmp, &tmp, -spec.prec, CTX(context), &status); + break; + case '%': + tmp.exp += 2; + mpd_qrescale(&tmp, &tmp, -spec.prec, CTX(context), &status); + break; + case 'g': + prec = (spec.prec == 0) ? 1 : spec.prec; + if (tmp.digits > prec) { + _mpd_round(&tmp, &tmp, prec, CTX(context), &status); + } + break; + case 'e': + if (!mpd_iszero(&tmp)) { + _mpd_round(&tmp, &tmp, spec.prec+1, CTX(context), &status); + } + break; + } + } + if (status & MPD_Errors) { + PyErr_SetString(PyExc_ValueError, "unexpected error when rounding"); + goto finish; + } + if (mpd_iszero(&tmp)) { + mpd_set_positive(&tmp); + mpd = &tmp; + } + } - decstring = mpd_qformat_spec(MPD(dec), &spec, CTX(context), &status); + decstring = mpd_qformat_spec(mpd, &spec, CTX(context), &status); if (decstring == NULL) { if (status & MPD_Malloc_error) { PyErr_NoMemory(); @@ -3335,7 +3469,7 @@ finish: Py_XDECREF(grouping); Py_XDECREF(sep); Py_XDECREF(dot); - if (replace_fillchar) PyMem_Free(fmt); + if (fmt_copy) PyMem_Free(fmt_copy); if (decstring) mpd_free(decstring); return result; } @@ -3394,6 +3528,13 @@ dec_as_long(PyObject *dec, PyObject *context, int round) return NULL; } + if (n == 1) { + sdigit val = mpd_arith_sign(x) * ob_digit[0]; + mpd_free(ob_digit); + mpd_del(x); + return PyLong_FromLong(val); + } + assert(n > 0); pylong = _PyLong_New(n); if (pylong == NULL) { @@ -4172,15 +4313,13 @@ dec_mpd_adjexp(PyObject *self, PyObject *dummy UNUSED) static PyObject * dec_canonical(PyObject *self, PyObject *dummy UNUSED) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * dec_conjugate(PyObject *self, PyObject *dummy UNUSED) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * @@ -4497,8 +4636,7 @@ dec_complex(PyObject *self, PyObject *dummy UNUSED) static PyObject * dec_copy(PyObject *self, PyObject *dummy UNUSED) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } /* __floor__ */ @@ -4658,13 +4796,11 @@ dec_reduce(PyObject *self, PyObject *dummy UNUSED) static PyObject * dec_sizeof(PyObject *v, PyObject *dummy UNUSED) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(v)); + size_t res = _PyObject_SIZE(Py_TYPE(v)); if (mpd_isdynamic_data(MPD(v))) { - res += MPD(v)->alloc * sizeof(mpd_uint_t); + res += (size_t)MPD(v)->alloc * sizeof(mpd_uint_t); } - return PyLong_FromSsize_t(res); + return PyLong_FromSize_t(res); } /* __trunc__ */ @@ -4681,8 +4817,7 @@ dec_trunc(PyObject *self, PyObject *dummy UNUSED) static PyObject * dec_real(PyObject *self, void *closure UNUSED) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * @@ -4747,30 +4882,30 @@ static PyNumberMethods dec_number_methods = static PyMethodDef dec_methods [] = { /* Unary arithmetic functions, optional context arg */ - { "exp", (PyCFunction)(void(*)(void))dec_mpd_qexp, METH_VARARGS|METH_KEYWORDS, doc_exp }, - { "ln", (PyCFunction)(void(*)(void))dec_mpd_qln, METH_VARARGS|METH_KEYWORDS, doc_ln }, - { "log10", (PyCFunction)(void(*)(void))dec_mpd_qlog10, METH_VARARGS|METH_KEYWORDS, doc_log10 }, - { "next_minus", (PyCFunction)(void(*)(void))dec_mpd_qnext_minus, METH_VARARGS|METH_KEYWORDS, doc_next_minus }, - { "next_plus", (PyCFunction)(void(*)(void))dec_mpd_qnext_plus, METH_VARARGS|METH_KEYWORDS, doc_next_plus }, - { "normalize", (PyCFunction)(void(*)(void))dec_mpd_qreduce, METH_VARARGS|METH_KEYWORDS, doc_normalize }, - { "to_integral", (PyCFunction)(void(*)(void))PyDec_ToIntegralValue, METH_VARARGS|METH_KEYWORDS, doc_to_integral }, - { "to_integral_exact", (PyCFunction)(void(*)(void))PyDec_ToIntegralExact, METH_VARARGS|METH_KEYWORDS, doc_to_integral_exact }, - { "to_integral_value", (PyCFunction)(void(*)(void))PyDec_ToIntegralValue, METH_VARARGS|METH_KEYWORDS, doc_to_integral_value }, - { "sqrt", (PyCFunction)(void(*)(void))dec_mpd_qsqrt, METH_VARARGS|METH_KEYWORDS, doc_sqrt }, + { "exp", _PyCFunction_CAST(dec_mpd_qexp), METH_VARARGS|METH_KEYWORDS, doc_exp }, + { "ln", _PyCFunction_CAST(dec_mpd_qln), METH_VARARGS|METH_KEYWORDS, doc_ln }, + { "log10", _PyCFunction_CAST(dec_mpd_qlog10), METH_VARARGS|METH_KEYWORDS, doc_log10 }, + { "next_minus", _PyCFunction_CAST(dec_mpd_qnext_minus), METH_VARARGS|METH_KEYWORDS, doc_next_minus }, + { "next_plus", _PyCFunction_CAST(dec_mpd_qnext_plus), METH_VARARGS|METH_KEYWORDS, doc_next_plus }, + { "normalize", _PyCFunction_CAST(dec_mpd_qreduce), METH_VARARGS|METH_KEYWORDS, doc_normalize }, + { "to_integral", _PyCFunction_CAST(PyDec_ToIntegralValue), METH_VARARGS|METH_KEYWORDS, doc_to_integral }, + { "to_integral_exact", _PyCFunction_CAST(PyDec_ToIntegralExact), METH_VARARGS|METH_KEYWORDS, doc_to_integral_exact }, + { "to_integral_value", _PyCFunction_CAST(PyDec_ToIntegralValue), METH_VARARGS|METH_KEYWORDS, doc_to_integral_value }, + { "sqrt", _PyCFunction_CAST(dec_mpd_qsqrt), METH_VARARGS|METH_KEYWORDS, doc_sqrt }, /* Binary arithmetic functions, optional context arg */ - { "compare", (PyCFunction)(void(*)(void))dec_mpd_qcompare, METH_VARARGS|METH_KEYWORDS, doc_compare }, - { "compare_signal", (PyCFunction)(void(*)(void))dec_mpd_qcompare_signal, METH_VARARGS|METH_KEYWORDS, doc_compare_signal }, - { "max", (PyCFunction)(void(*)(void))dec_mpd_qmax, METH_VARARGS|METH_KEYWORDS, doc_max }, - { "max_mag", (PyCFunction)(void(*)(void))dec_mpd_qmax_mag, METH_VARARGS|METH_KEYWORDS, doc_max_mag }, - { "min", (PyCFunction)(void(*)(void))dec_mpd_qmin, METH_VARARGS|METH_KEYWORDS, doc_min }, - { "min_mag", (PyCFunction)(void(*)(void))dec_mpd_qmin_mag, METH_VARARGS|METH_KEYWORDS, doc_min_mag }, - { "next_toward", (PyCFunction)(void(*)(void))dec_mpd_qnext_toward, METH_VARARGS|METH_KEYWORDS, doc_next_toward }, - { "quantize", (PyCFunction)(void(*)(void))dec_mpd_qquantize, METH_VARARGS|METH_KEYWORDS, doc_quantize }, - { "remainder_near", (PyCFunction)(void(*)(void))dec_mpd_qrem_near, METH_VARARGS|METH_KEYWORDS, doc_remainder_near }, + { "compare", _PyCFunction_CAST(dec_mpd_qcompare), METH_VARARGS|METH_KEYWORDS, doc_compare }, + { "compare_signal", _PyCFunction_CAST(dec_mpd_qcompare_signal), METH_VARARGS|METH_KEYWORDS, doc_compare_signal }, + { "max", _PyCFunction_CAST(dec_mpd_qmax), METH_VARARGS|METH_KEYWORDS, doc_max }, + { "max_mag", _PyCFunction_CAST(dec_mpd_qmax_mag), METH_VARARGS|METH_KEYWORDS, doc_max_mag }, + { "min", _PyCFunction_CAST(dec_mpd_qmin), METH_VARARGS|METH_KEYWORDS, doc_min }, + { "min_mag", _PyCFunction_CAST(dec_mpd_qmin_mag), METH_VARARGS|METH_KEYWORDS, doc_min_mag }, + { "next_toward", _PyCFunction_CAST(dec_mpd_qnext_toward), METH_VARARGS|METH_KEYWORDS, doc_next_toward }, + { "quantize", _PyCFunction_CAST(dec_mpd_qquantize), METH_VARARGS|METH_KEYWORDS, doc_quantize }, + { "remainder_near", _PyCFunction_CAST(dec_mpd_qrem_near), METH_VARARGS|METH_KEYWORDS, doc_remainder_near }, /* Ternary arithmetic functions, optional context arg */ - { "fma", (PyCFunction)(void(*)(void))dec_mpd_qfma, METH_VARARGS|METH_KEYWORDS, doc_fma }, + { "fma", _PyCFunction_CAST(dec_mpd_qfma), METH_VARARGS|METH_KEYWORDS, doc_fma }, /* Boolean functions, no context arg */ { "is_canonical", dec_mpd_iscanonical, METH_NOARGS, doc_is_canonical }, @@ -4783,8 +4918,8 @@ static PyMethodDef dec_methods [] = { "is_zero", dec_mpd_iszero, METH_NOARGS, doc_is_zero }, /* Boolean functions, optional context arg */ - { "is_normal", (PyCFunction)(void(*)(void))dec_mpd_isnormal, METH_VARARGS|METH_KEYWORDS, doc_is_normal }, - { "is_subnormal", (PyCFunction)(void(*)(void))dec_mpd_issubnormal, METH_VARARGS|METH_KEYWORDS, doc_is_subnormal }, + { "is_normal", _PyCFunction_CAST(dec_mpd_isnormal), METH_VARARGS|METH_KEYWORDS, doc_is_normal }, + { "is_subnormal", _PyCFunction_CAST(dec_mpd_issubnormal), METH_VARARGS|METH_KEYWORDS, doc_is_subnormal }, /* Unary functions, no context arg */ { "adjusted", dec_mpd_adjexp, METH_NOARGS, doc_adjusted }, @@ -4797,24 +4932,24 @@ static PyMethodDef dec_methods [] = { "copy_negate", dec_mpd_qcopy_negate, METH_NOARGS, doc_copy_negate }, /* Unary functions, optional context arg */ - { "logb", (PyCFunction)(void(*)(void))dec_mpd_qlogb, METH_VARARGS|METH_KEYWORDS, doc_logb }, - { "logical_invert", (PyCFunction)(void(*)(void))dec_mpd_qinvert, METH_VARARGS|METH_KEYWORDS, doc_logical_invert }, - { "number_class", (PyCFunction)(void(*)(void))dec_mpd_class, METH_VARARGS|METH_KEYWORDS, doc_number_class }, - { "to_eng_string", (PyCFunction)(void(*)(void))dec_mpd_to_eng, METH_VARARGS|METH_KEYWORDS, doc_to_eng_string }, + { "logb", _PyCFunction_CAST(dec_mpd_qlogb), METH_VARARGS|METH_KEYWORDS, doc_logb }, + { "logical_invert", _PyCFunction_CAST(dec_mpd_qinvert), METH_VARARGS|METH_KEYWORDS, doc_logical_invert }, + { "number_class", _PyCFunction_CAST(dec_mpd_class), METH_VARARGS|METH_KEYWORDS, doc_number_class }, + { "to_eng_string", _PyCFunction_CAST(dec_mpd_to_eng), METH_VARARGS|METH_KEYWORDS, doc_to_eng_string }, /* Binary functions, optional context arg for conversion errors */ - { "compare_total", (PyCFunction)(void(*)(void))dec_mpd_compare_total, METH_VARARGS|METH_KEYWORDS, doc_compare_total }, - { "compare_total_mag", (PyCFunction)(void(*)(void))dec_mpd_compare_total_mag, METH_VARARGS|METH_KEYWORDS, doc_compare_total_mag }, - { "copy_sign", (PyCFunction)(void(*)(void))dec_mpd_qcopy_sign, METH_VARARGS|METH_KEYWORDS, doc_copy_sign }, - { "same_quantum", (PyCFunction)(void(*)(void))dec_mpd_same_quantum, METH_VARARGS|METH_KEYWORDS, doc_same_quantum }, + { "compare_total", _PyCFunction_CAST(dec_mpd_compare_total), METH_VARARGS|METH_KEYWORDS, doc_compare_total }, + { "compare_total_mag", _PyCFunction_CAST(dec_mpd_compare_total_mag), METH_VARARGS|METH_KEYWORDS, doc_compare_total_mag }, + { "copy_sign", _PyCFunction_CAST(dec_mpd_qcopy_sign), METH_VARARGS|METH_KEYWORDS, doc_copy_sign }, + { "same_quantum", _PyCFunction_CAST(dec_mpd_same_quantum), METH_VARARGS|METH_KEYWORDS, doc_same_quantum }, /* Binary functions, optional context arg */ - { "logical_and", (PyCFunction)(void(*)(void))dec_mpd_qand, METH_VARARGS|METH_KEYWORDS, doc_logical_and }, - { "logical_or", (PyCFunction)(void(*)(void))dec_mpd_qor, METH_VARARGS|METH_KEYWORDS, doc_logical_or }, - { "logical_xor", (PyCFunction)(void(*)(void))dec_mpd_qxor, METH_VARARGS|METH_KEYWORDS, doc_logical_xor }, - { "rotate", (PyCFunction)(void(*)(void))dec_mpd_qrotate, METH_VARARGS|METH_KEYWORDS, doc_rotate }, - { "scaleb", (PyCFunction)(void(*)(void))dec_mpd_qscaleb, METH_VARARGS|METH_KEYWORDS, doc_scaleb }, - { "shift", (PyCFunction)(void(*)(void))dec_mpd_qshift, METH_VARARGS|METH_KEYWORDS, doc_shift }, + { "logical_and", _PyCFunction_CAST(dec_mpd_qand), METH_VARARGS|METH_KEYWORDS, doc_logical_and }, + { "logical_or", _PyCFunction_CAST(dec_mpd_qor), METH_VARARGS|METH_KEYWORDS, doc_logical_or }, + { "logical_xor", _PyCFunction_CAST(dec_mpd_qxor), METH_VARARGS|METH_KEYWORDS, doc_logical_xor }, + { "rotate", _PyCFunction_CAST(dec_mpd_qrotate), METH_VARARGS|METH_KEYWORDS, doc_rotate }, + { "scaleb", _PyCFunction_CAST(dec_mpd_qscaleb), METH_VARARGS|METH_KEYWORDS, doc_scaleb }, + { "shift", _PyCFunction_CAST(dec_mpd_qshift), METH_VARARGS|METH_KEYWORDS, doc_shift }, /* Miscellaneous */ { "from_float", dec_from_float, METH_O|METH_CLASS, doc_from_float }, @@ -5227,8 +5362,7 @@ ctx_canonical(PyObject *context UNUSED, PyObject *v) return NULL; } - Py_INCREF(v); - return v; + return Py_NewRef(v); } static PyObject * @@ -5452,7 +5586,7 @@ static PyMethodDef context_methods [] = { "subtract", ctx_mpd_qsub, METH_VARARGS, doc_ctx_subtract }, /* Binary or ternary arithmetic functions */ - { "power", (PyCFunction)(void(*)(void))ctx_mpd_qpow, METH_VARARGS|METH_KEYWORDS, doc_ctx_power }, + { "power", _PyCFunction_CAST(ctx_mpd_qpow), METH_VARARGS|METH_KEYWORDS, doc_ctx_power }, /* Ternary arithmetic functions */ { "fma", ctx_mpd_qfma, METH_VARARGS, doc_ctx_fma }, @@ -5570,7 +5704,7 @@ static PyMethodDef _decimal_methods [] = { { "getcontext", (PyCFunction)PyDec_GetCurrentContext, METH_NOARGS, doc_getcontext}, { "setcontext", (PyCFunction)PyDec_SetCurrentContext, METH_O, doc_setcontext}, - { "localcontext", (PyCFunction)(void(*)(void))ctxmanager_new, METH_VARARGS|METH_KEYWORDS, doc_localcontext}, + { "localcontext", _PyCFunction_CAST(ctxmanager_new), METH_VARARGS|METH_KEYWORDS, doc_localcontext}, #ifdef EXTRA_FUNCTIONALITY { "IEEEContext", (PyCFunction)ieee_context, METH_O, doc_ieee_context}, #endif @@ -5759,23 +5893,17 @@ PyInit__decimal(void) /* Create the module */ ASSIGN_PTR(m, PyModule_Create(&_decimal_module)); - /* Add types to the module */ - Py_INCREF(&PyDec_Type); - CHECK_INT(PyModule_AddObject(m, "Decimal", (PyObject *)&PyDec_Type)); - Py_INCREF(&PyDecContext_Type); + CHECK_INT(PyModule_AddObject(m, "Decimal", Py_NewRef(&PyDec_Type))); CHECK_INT(PyModule_AddObject(m, "Context", - (PyObject *)&PyDecContext_Type)); - Py_INCREF(DecimalTuple); - CHECK_INT(PyModule_AddObject(m, "DecimalTuple", (PyObject *)DecimalTuple)); - + Py_NewRef(&PyDecContext_Type))); + CHECK_INT(PyModule_AddObject(m, "DecimalTuple", Py_NewRef(DecimalTuple))); /* Create top level exception */ ASSIGN_PTR(DecimalException, PyErr_NewException( "decimal.DecimalException", PyExc_ArithmeticError, NULL)); - Py_INCREF(DecimalException); - CHECK_INT(PyModule_AddObject(m, "DecimalException", DecimalException)); + CHECK_INT(PyModule_AddObject(m, "DecimalException", Py_NewRef(DecimalException))); /* Create signal tuple */ ASSIGN_PTR(SignalTuple, PyTuple_New(SIGNAL_MAP_LEN)); @@ -5815,12 +5943,10 @@ PyInit__decimal(void) Py_DECREF(base); /* add to module */ - Py_INCREF(cm->ex); - CHECK_INT(PyModule_AddObject(m, cm->name, cm->ex)); + CHECK_INT(PyModule_AddObject(m, cm->name, Py_NewRef(cm->ex))); /* add to signal tuple */ - Py_INCREF(cm->ex); - PyTuple_SET_ITEM(SignalTuple, i, cm->ex); + PyTuple_SET_ITEM(SignalTuple, i, Py_NewRef(cm->ex)); } /* @@ -5846,45 +5972,38 @@ PyInit__decimal(void) ASSIGN_PTR(cm->ex, PyErr_NewException(cm->fqname, base, NULL)); Py_DECREF(base); - Py_INCREF(cm->ex); - CHECK_INT(PyModule_AddObject(m, cm->name, cm->ex)); + CHECK_INT(PyModule_AddObject(m, cm->name, Py_NewRef(cm->ex))); } /* Init default context template first */ ASSIGN_PTR(default_context_template, PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL)); - Py_INCREF(default_context_template); CHECK_INT(PyModule_AddObject(m, "DefaultContext", - default_context_template)); + Py_NewRef(default_context_template))); #ifndef WITH_DECIMAL_CONTEXTVAR ASSIGN_PTR(tls_context_key, PyUnicode_FromString("___DECIMAL_CTX__")); - Py_INCREF(Py_False); - CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_False)); + CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_NewRef(Py_False))); #else ASSIGN_PTR(current_context_var, PyContextVar_New("decimal_context", NULL)); - Py_INCREF(Py_True); - CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_True)); + CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_NewRef(Py_True))); #endif - Py_INCREF(Py_True); - CHECK_INT(PyModule_AddObject(m, "HAVE_THREADS", Py_True)); + CHECK_INT(PyModule_AddObject(m, "HAVE_THREADS", Py_NewRef(Py_True))); /* Init basic context template */ ASSIGN_PTR(basic_context_template, PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL)); init_basic_context(basic_context_template); - Py_INCREF(basic_context_template); CHECK_INT(PyModule_AddObject(m, "BasicContext", - basic_context_template)); + Py_NewRef(basic_context_template))); /* Init extended context template */ ASSIGN_PTR(extended_context_template, PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL)); init_extended_context(extended_context_template); - Py_INCREF(extended_context_template); CHECK_INT(PyModule_AddObject(m, "ExtendedContext", - extended_context_template)); + Py_NewRef(extended_context_template))); /* Init mpd_ssize_t constants */ @@ -5903,8 +6022,7 @@ PyInit__decimal(void) /* Init string constants */ for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) { ASSIGN_PTR(round_map[i], PyUnicode_InternFromString(mpd_round_string[i])); - Py_INCREF(round_map[i]); - CHECK_INT(PyModule_AddObject(m, mpd_round_string[i], round_map[i])); + CHECK_INT(PyModule_AddObject(m, mpd_round_string[i], Py_NewRef(round_map[i]))); } /* Add specification version number */ diff --git a/Modules/_decimal/docstrings.h b/Modules/_decimal/docstrings.h index f7fd6e79529..a1823cdd32b 100644 --- a/Modules/_decimal/docstrings.h +++ b/Modules/_decimal/docstrings.h @@ -30,7 +30,7 @@ Set a new default context.\n\ \n"); PyDoc_STRVAR(doc_localcontext, -"localcontext($module, /, ctx=None)\n--\n\n\ +"localcontext($module, /, ctx=None, **kwargs)\n--\n\n\ Return a context manager that will set the default context to a copy of ctx\n\ on entry to the with-statement and restore the previous default context when\n\ exiting the with-statement. If no context is specified, a copy of the current\n\ diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c index f1626df46ed..959934bda7a 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.c +++ b/Modules/_decimal/libmpdec/mpdecimal.c @@ -76,6 +76,12 @@ #endif #endif +/* ClangCL claims to support 128-bit int, but doesn't */ +#if defined(__SIZEOF_INT128__) && defined(__clang__) && defined(_MSC_VER) +#undef __SIZEOF_INT128__ +#endif + + #define MPD_NEWTONDIV_CUTOFF 1024L diff --git a/Modules/_decimal/tests/formathelper.py b/Modules/_decimal/tests/formathelper.py index c3daacfb7b4..f4a6a1cebb7 100644 --- a/Modules/_decimal/tests/formathelper.py +++ b/Modules/_decimal/tests/formathelper.py @@ -32,7 +32,7 @@ import os, sys, locale, random import platform, subprocess from test.support.import_helper import import_fresh_module -from distutils.spawn import find_executable +from shutil import which C = import_fresh_module('decimal', fresh=['_decimal']) P = import_fresh_module('decimal', blocked=['_decimal']) @@ -139,7 +139,7 @@ else: with open("/var/lib/locales/supported.d/local") as f: locale_list = [loc.split()[0] for loc in f.readlines() \ if not loc.startswith('#')] - elif find_executable('locale'): + elif which('locale'): locale_list = subprocess.Popen(["locale", "-a"], stdout=subprocess.PIPE).communicate()[0] try: diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index b4528a90b3e..97be89a1671 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -35,17 +35,6 @@ /* -------------------------------------------------------------------- */ -#if 0 -static int memory = 0; -#define ALLOC(size, comment)\ -do { memory += size; printf("%8d - %s\n", memory, comment); } while (0) -#define RELEASE(size, comment)\ -do { memory -= size; printf("%8d - %s\n", memory, comment); } while (0) -#else -#define ALLOC(size, comment) -#define RELEASE(size, comment) -#endif - /* compiler tweaks */ #if defined(_MSC_VER) #define LOCAL(type) static __inline type __fastcall @@ -80,13 +69,6 @@ static void _clear_joined_ptr(PyObject **p) } } -/* Types defined by this extension */ -static PyTypeObject Element_Type; -static PyTypeObject ElementIter_Type; -static PyTypeObject TreeBuilder_Type; -static PyTypeObject XMLParser_Type; - - /* Per-module state; PEP 3121 */ typedef struct { PyObject *parseerror_obj; @@ -94,6 +76,20 @@ typedef struct { PyObject *elementpath_obj; PyObject *comment_factory; PyObject *pi_factory; + /* Interned strings */ + PyObject *str_text; + PyObject *str_tail; + PyObject *str_append; + PyObject *str_find; + PyObject *str_findtext; + PyObject *str_findall; + PyObject *str_iterfind; + PyObject *str_doctype; + /* Types defined by this extension */ + PyTypeObject *Element_Type; + PyTypeObject *ElementIter_Type; + PyTypeObject *TreeBuilder_Type; + PyTypeObject *XMLParser_Type; } elementtreestate; static struct PyModuleDef elementtreemodule; @@ -109,11 +105,21 @@ get_elementtree_state(PyObject *module) return (elementtreestate *)state; } -/* Find the module instance imported in the currently running sub-interpreter - * and get its state. - */ -#define ET_STATE_GLOBAL \ - ((elementtreestate *) PyModule_GetState(PyState_FindModule(&elementtreemodule))) +static inline elementtreestate * +get_elementtree_state_by_cls(PyTypeObject *cls) +{ + void *state = PyType_GetModuleState(cls); + assert(state != NULL); + return (elementtreestate *)state; +} + +static inline elementtreestate * +get_elementtree_state_by_type(PyTypeObject *tp) +{ + PyObject *mod = PyType_GetModuleByDef(tp, &elementtreemodule); + assert(mod != NULL); + return get_elementtree_state(mod); +} static int elementtree_clear(PyObject *m) @@ -124,6 +130,22 @@ elementtree_clear(PyObject *m) Py_CLEAR(st->elementpath_obj); Py_CLEAR(st->comment_factory); Py_CLEAR(st->pi_factory); + + // Interned strings + Py_CLEAR(st->str_append); + Py_CLEAR(st->str_find); + Py_CLEAR(st->str_findall); + Py_CLEAR(st->str_findtext); + Py_CLEAR(st->str_iterfind); + Py_CLEAR(st->str_tail); + Py_CLEAR(st->str_text); + Py_CLEAR(st->str_doctype); + + // Heap types + Py_CLEAR(st->Element_Type); + Py_CLEAR(st->ElementIter_Type); + Py_CLEAR(st->TreeBuilder_Type); + Py_CLEAR(st->XMLParser_Type); return 0; } @@ -136,6 +158,12 @@ elementtree_traverse(PyObject *m, visitproc visit, void *arg) Py_VISIT(st->elementpath_obj); Py_VISIT(st->comment_factory); Py_VISIT(st->pi_factory); + + // Heap types + Py_VISIT(st->Element_Type); + Py_VISIT(st->ElementIter_Type); + Py_VISIT(st->TreeBuilder_Type); + Py_VISIT(st->XMLParser_Type); return 0; } @@ -215,8 +243,8 @@ typedef struct { } ElementObject; -#define Element_CheckExact(op) Py_IS_TYPE(op, &Element_Type) -#define Element_Check(op) PyObject_TypeCheck(op, &Element_Type) +#define Element_CheckExact(st, op) Py_IS_TYPE(op, (st)->Element_Type) +#define Element_Check(st, op) PyObject_TypeCheck(op, (st)->Element_Type) /* -------------------------------------------------------------------- */ @@ -231,8 +259,7 @@ create_extra(ElementObject* self, PyObject* attrib) return -1; } - Py_XINCREF(attrib); - self->extra->attrib = attrib; + self->extra->attrib = Py_XNewRef(attrib); self->extra->length = 0; self->extra->allocated = STATIC_CHILDREN; @@ -280,27 +307,19 @@ clear_extra(ElementObject* self) * tag and attributes. */ LOCAL(PyObject*) -create_new_element(PyObject* tag, PyObject* attrib) +create_new_element(elementtreestate *st, PyObject *tag, PyObject *attrib) { ElementObject* self; - self = PyObject_GC_New(ElementObject, &Element_Type); + self = PyObject_GC_New(ElementObject, st->Element_Type); if (self == NULL) return NULL; self->extra = NULL; - - Py_INCREF(tag); - self->tag = tag; - - Py_INCREF(Py_None); - self->text = Py_None; - - Py_INCREF(Py_None); - self->tail = Py_None; - + self->tag = Py_NewRef(tag); + self->text = Py_NewRef(Py_None); + self->tail = Py_NewRef(Py_None); self->weakreflist = NULL; - ALLOC(sizeof(ElementObject), "create element"); PyObject_GC_Track(self); if (attrib != NULL && !is_empty_dict(attrib)) { @@ -318,15 +337,9 @@ element_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { ElementObject *e = (ElementObject *)type->tp_alloc(type, 0); if (e != NULL) { - Py_INCREF(Py_None); - e->tag = Py_None; - - Py_INCREF(Py_None); - e->text = Py_None; - - Py_INCREF(Py_None); - e->tail = Py_None; - + e->tag = Py_NewRef(Py_None); + e->text = Py_NewRef(Py_None); + e->tail = Py_NewRef(Py_None); e->extra = NULL; e->weakreflist = NULL; } @@ -362,8 +375,7 @@ get_attrib_from_keywords(PyObject *kwds) } attrib = PyDict_Copy(attrib); if (attrib && PyDict_DelItem(kwds, attrib_str) < 0) { - Py_DECREF(attrib); - attrib = NULL; + Py_SETREF(attrib, NULL); } } else if (!PyErr_Occurred()) { @@ -381,11 +393,11 @@ get_attrib_from_keywords(PyObject *kwds) /*[clinic input] module _elementtree -class _elementtree.Element "ElementObject *" "&Element_Type" -class _elementtree.TreeBuilder "TreeBuilderObject *" "&TreeBuilder_Type" -class _elementtree.XMLParser "XMLParserObject *" "&XMLParser_Type" +class _elementtree.Element "ElementObject *" "clinic_state()->Element_Type" +class _elementtree.TreeBuilder "TreeBuilderObject *" "clinic_state()->TreeBuilder_Type" +class _elementtree.XMLParser "XMLParserObject *" "clinic_state()->XMLParser_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=159aa50a54061c22]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6c83ea832d2b0ef1]*/ static int element_init(PyObject *self, PyObject *args, PyObject *kwds) @@ -428,14 +440,10 @@ element_init(PyObject *self, PyObject *args, PyObject *kwds) Py_XDECREF(attrib); /* Replace the objects already pointed to by tag, text and tail. */ - Py_INCREF(tag); - Py_XSETREF(self_elem->tag, tag); + Py_XSETREF(self_elem->tag, Py_NewRef(tag)); - Py_INCREF(Py_None); - _set_joined_ptr(&self_elem->text, Py_None); - - Py_INCREF(Py_None); - _set_joined_ptr(&self_elem->tail, Py_None); + _set_joined_ptr(&self_elem->text, Py_NewRef(Py_None)); + _set_joined_ptr(&self_elem->tail, Py_NewRef(Py_None)); return 0; } @@ -505,11 +513,11 @@ raise_type_error(PyObject *element) } LOCAL(int) -element_add_subelement(ElementObject* self, PyObject* element) +element_add_subelement(elementtreestate *st, ElementObject *self, + PyObject *element) { /* add a child element to a parent */ - - if (!Element_Check(element)) { + if (!Element_Check(st, element)) { raise_type_error(element); return -1; } @@ -517,8 +525,7 @@ element_add_subelement(ElementObject* self, PyObject* element) if (element_resize(self, 1) < 0) return -1; - Py_INCREF(element); - self->extra->children[self->extra->length] = element; + self->extra->children[self->extra->length] = Py_NewRef(element); self->extra->length++; @@ -555,8 +562,7 @@ element_get_text(ElementObject* self) if (!tmp) return NULL; self->text = tmp; - Py_DECREF(res); - res = tmp; + Py_SETREF(res, tmp); } } @@ -577,8 +583,7 @@ element_get_tail(ElementObject* self) if (!tmp) return NULL; self->tail = tmp; - Py_DECREF(res); - res = tmp; + Py_SETREF(res, tmp); } } @@ -590,11 +595,12 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds) { PyObject* elem; + elementtreestate *st = get_elementtree_state(self); ElementObject* parent; PyObject* tag; PyObject* attrib = NULL; if (!PyArg_ParseTuple(args, "O!O|O!:SubElement", - &Element_Type, &parent, &tag, + st->Element_Type, &parent, &tag, &PyDict_Type, &attrib)) { return NULL; } @@ -617,12 +623,12 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds) /* no attrib arg, no kwds, so no attribute */ } - elem = create_new_element(tag, attrib); + elem = create_new_element(st, tag, attrib); Py_XDECREF(attrib); if (elem == NULL) return NULL; - if (element_add_subelement(parent, elem) < 0) { + if (element_add_subelement(st, parent, elem) < 0) { Py_DECREF(elem); return NULL; } @@ -633,6 +639,7 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds) static int element_gc_traverse(ElementObject *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->tag); Py_VISIT(JOIN_OBJ(self->text)); Py_VISIT(JOIN_OBJ(self->tail)); @@ -664,6 +671,8 @@ element_gc_clear(ElementObject *self) static void element_dealloc(ElementObject* self) { + PyTypeObject *tp = Py_TYPE(self); + /* bpo-31095: UnTrack is needed before calling any callbacks */ PyObject_GC_UnTrack(self); Py_TRASHCAN_BEGIN(self, element_dealloc) @@ -675,8 +684,8 @@ element_dealloc(ElementObject* self) */ element_gc_clear(self); - RELEASE(sizeof(ElementObject), "destroy element"); - Py_TYPE(self)->tp_free((PyObject *)self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); Py_TRASHCAN_END } @@ -685,16 +694,19 @@ element_dealloc(ElementObject* self) /*[clinic input] _elementtree.Element.append - subelement: object(subclass_of='&Element_Type') + cls: defining_class + subelement: object(subclass_of='clinic_state()->Element_Type') / [clinic start generated code]*/ static PyObject * -_elementtree_Element_append_impl(ElementObject *self, PyObject *subelement) -/*[clinic end generated code: output=54a884b7cf2295f4 input=3ed648beb5bfa22a]*/ +_elementtree_Element_append_impl(ElementObject *self, PyTypeObject *cls, + PyObject *subelement) +/*[clinic end generated code: output=d00923711ea317fc input=8baf92679f9717b8]*/ { - if (element_add_subelement(self, subelement) < 0) + elementtreestate *st = get_elementtree_state_by_cls(cls); + if (element_add_subelement(st, self, subelement) < 0) return NULL; Py_RETURN_NONE; @@ -711,11 +723,8 @@ _elementtree_Element_clear_impl(ElementObject *self) { clear_extra(self); - Py_INCREF(Py_None); - _set_joined_ptr(&self->text, Py_None); - - Py_INCREF(Py_None); - _set_joined_ptr(&self->tail, Py_None); + _set_joined_ptr(&self->text, Py_NewRef(Py_None)); + _set_joined_ptr(&self->tail, Py_NewRef(Py_None)); Py_RETURN_NONE; } @@ -723,17 +732,21 @@ _elementtree_Element_clear_impl(ElementObject *self) /*[clinic input] _elementtree.Element.__copy__ + cls: defining_class + / + [clinic start generated code]*/ static PyObject * -_elementtree_Element___copy___impl(ElementObject *self) -/*[clinic end generated code: output=2c701ebff7247781 input=ad87aaebe95675bf]*/ +_elementtree_Element___copy___impl(ElementObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=da22894421ff2b36 input=91edb92d9f441213]*/ { Py_ssize_t i; ElementObject* element; + elementtreestate *st = get_elementtree_state_by_cls(cls); element = (ElementObject*) create_new_element( - self->tag, self->extra ? self->extra->attrib : NULL); + st, self->tag, self->extra ? self->extra->attrib : NULL); if (!element) return NULL; @@ -751,8 +764,7 @@ _elementtree_Element___copy___impl(ElementObject *self) } for (i = 0; i < self->extra->length; i++) { - Py_INCREF(self->extra->children[i]); - element->extra->children[i] = self->extra->children[i]; + element->extra->children[i] = Py_NewRef(self->extra->children[i]); } assert(!element->extra->length); @@ -763,7 +775,7 @@ _elementtree_Element___copy___impl(ElementObject *self) } /* Helper for a deep copy. */ -LOCAL(PyObject *) deepcopy(PyObject *, PyObject *); +LOCAL(PyObject *) deepcopy(elementtreestate *, PyObject *, PyObject *); /*[clinic input] _elementtree.Element.__deepcopy__ @@ -785,12 +797,14 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo) PyObject* tail; PyObject* id; - tag = deepcopy(self->tag, memo); + PyTypeObject *tp = Py_TYPE(self); + elementtreestate *st = get_elementtree_state_by_type(tp); + tag = deepcopy(st, self->tag, memo); if (!tag) return NULL; if (self->extra && self->extra->attrib) { - attrib = deepcopy(self->extra->attrib, memo); + attrib = deepcopy(st, self->extra->attrib, memo); if (!attrib) { Py_DECREF(tag); return NULL; @@ -799,7 +813,7 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo) attrib = NULL; } - element = (ElementObject*) create_new_element(tag, attrib); + element = (ElementObject*) create_new_element(st, tag, attrib); Py_DECREF(tag); Py_XDECREF(attrib); @@ -807,12 +821,12 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo) if (!element) return NULL; - text = deepcopy(JOIN_OBJ(self->text), memo); + text = deepcopy(st, JOIN_OBJ(self->text), memo); if (!text) goto error; _set_joined_ptr(&element->text, JOIN_SET(text, JOIN_GET(self->text))); - tail = deepcopy(JOIN_OBJ(self->tail), memo); + tail = deepcopy(st, JOIN_OBJ(self->tail), memo); if (!tail) goto error; _set_joined_ptr(&element->tail, JOIN_SET(tail, JOIN_GET(self->tail))); @@ -823,8 +837,8 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo) goto error; for (i = 0; i < self->extra->length; i++) { - PyObject* child = deepcopy(self->extra->children[i], memo); - if (!child || !Element_Check(child)) { + PyObject* child = deepcopy(st, self->extra->children[i], memo); + if (!child || !Element_Check(st, child)) { if (child) { raise_type_error(child); Py_DECREF(child); @@ -859,16 +873,14 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo) } LOCAL(PyObject *) -deepcopy(PyObject *object, PyObject *memo) +deepcopy(elementtreestate *st, PyObject *object, PyObject *memo) { /* do a deep copy of the given object */ - elementtreestate *st; PyObject *stack[2]; /* Fast paths */ if (object == Py_None || PyUnicode_CheckExact(object)) { - Py_INCREF(object); - return object; + return Py_NewRef(object); } if (Py_REFCNT(object) == 1) { @@ -886,14 +898,13 @@ deepcopy(PyObject *object, PyObject *memo) return PyDict_Copy(object); /* Fall through to general case */ } - else if (Element_CheckExact(object)) { + else if (Element_CheckExact(st, object)) { return _elementtree_Element___deepcopy___impl( (ElementObject *)object, memo); } } /* General case */ - st = ET_STATE_GLOBAL; if (!st->deepcopy_obj) { PyErr_SetString(PyExc_RuntimeError, "deepcopy helper not found"); @@ -907,19 +918,20 @@ deepcopy(PyObject *object, PyObject *memo) /*[clinic input] -_elementtree.Element.__sizeof__ -> Py_ssize_t +_elementtree.Element.__sizeof__ -> size_t [clinic start generated code]*/ -static Py_ssize_t +static size_t _elementtree_Element___sizeof___impl(ElementObject *self) -/*[clinic end generated code: output=bf73867721008000 input=70f4b323d55a17c1]*/ +/*[clinic end generated code: output=baae4e7ae9fe04ec input=54e298c501f3e0d0]*/ { - Py_ssize_t result = _PyObject_SIZE(Py_TYPE(self)); + size_t result = _PyObject_SIZE(Py_TYPE(self)); if (self->extra) { result += sizeof(ElementObjectExtra); - if (self->extra->children != self->extra->_children) - result += sizeof(PyObject*) * self->extra->allocated; + if (self->extra->children != self->extra->_children) { + result += (size_t)self->extra->allocated * sizeof(PyObject*); + } } return result; } @@ -954,14 +966,12 @@ _elementtree_Element___getstate___impl(ElementObject *self) if (!children) return NULL; for (i = 0; i < PyList_GET_SIZE(children); i++) { - PyObject *child = self->extra->children[i]; - Py_INCREF(child); + PyObject *child = Py_NewRef(self->extra->children[i]); PyList_SET_ITEM(children, i, child); } if (self->extra && self->extra->attrib) { - attrib = self->extra->attrib; - Py_INCREF(attrib); + attrib = Py_NewRef(self->extra->attrib); } else { attrib = PyDict_New(); @@ -980,7 +990,8 @@ _elementtree_Element___getstate___impl(ElementObject *self) } static PyObject * -element_setstate_from_attributes(ElementObject *self, +element_setstate_from_attributes(elementtreestate *st, + ElementObject *self, PyObject *tag, PyObject *attrib, PyObject *text, @@ -995,8 +1006,7 @@ element_setstate_from_attributes(ElementObject *self, return NULL; } - Py_INCREF(tag); - Py_XSETREF(self->tag, tag); + Py_XSETREF(self->tag, Py_NewRef(tag)); text = text ? JOIN_SET(text, PyList_CheckExact(text)) : Py_None; Py_INCREF(JOIN_OBJ(text)); @@ -1041,14 +1051,13 @@ element_setstate_from_attributes(ElementObject *self, /* Copy children */ for (i = 0; i < nchildren; i++) { PyObject *child = PyList_GET_ITEM(children, i); - if (!Element_Check(child)) { + if (!Element_Check(st, child)) { raise_type_error(child); self->extra->length = i; dealloc_extra(oldextra); return NULL; } - Py_INCREF(child); - self->extra->children[i] = child; + self->extra->children[i] = Py_NewRef(child); } assert(!self->extra->length); @@ -1061,8 +1070,7 @@ element_setstate_from_attributes(ElementObject *self, } /* Stash attrib. */ - Py_XINCREF(attrib); - Py_XSETREF(self->extra->attrib, attrib); + Py_XSETREF(self->extra->attrib, Py_XNewRef(attrib)); dealloc_extra(oldextra); Py_RETURN_NONE; @@ -1073,7 +1081,8 @@ element_setstate_from_attributes(ElementObject *self, */ static PyObject * -element_setstate_from_Python(ElementObject *self, PyObject *state) +element_setstate_from_Python(elementtreestate *st, ElementObject *self, + PyObject *state) { static char *kwlist[] = {PICKLED_TAG, PICKLED_ATTRIB, PICKLED_TEXT, PICKLED_TAIL, PICKLED_CHILDREN, 0}; @@ -1088,7 +1097,7 @@ element_setstate_from_Python(ElementObject *self, PyObject *state) if (PyArg_ParseTupleAndKeywords(args, state, "|$OOOOO", kwlist, &tag, &attrib, &text, &tail, &children)) - retval = element_setstate_from_attributes(self, tag, attrib, text, + retval = element_setstate_from_attributes(st, self, tag, attrib, text, tail, children); else retval = NULL; @@ -1100,14 +1109,16 @@ element_setstate_from_Python(ElementObject *self, PyObject *state) /*[clinic input] _elementtree.Element.__setstate__ + cls: defining_class state: object / [clinic start generated code]*/ static PyObject * -_elementtree_Element___setstate__(ElementObject *self, PyObject *state) -/*[clinic end generated code: output=ea28bf3491b1f75e input=aaf80abea7c1e3b9]*/ +_elementtree_Element___setstate___impl(ElementObject *self, + PyTypeObject *cls, PyObject *state) +/*[clinic end generated code: output=598bfb5730f71509 input=13830488d35d51f7]*/ { if (!PyDict_CheckExact(state)) { PyErr_Format(PyExc_TypeError, @@ -1115,8 +1126,10 @@ _elementtree_Element___setstate__(ElementObject *self, PyObject *state) state); return NULL; } - else - return element_setstate_from_Python(self, state); + else { + elementtreestate *st = get_elementtree_state_by_cls(cls); + return element_setstate_from_Python(st, self, state); + } } LOCAL(int) @@ -1133,7 +1146,7 @@ checkpath(PyObject* tag) if (PyUnicode_Check(tag)) { const Py_ssize_t len = PyUnicode_GET_LENGTH(tag); const void *data = PyUnicode_DATA(tag); - unsigned int kind = PyUnicode_KIND(tag); + int kind = PyUnicode_KIND(tag); if (len >= 3 && PyUnicode_READ(kind, data, 0) == '{' && ( PyUnicode_READ(kind, data, 1) == '}' || ( PyUnicode_READ(kind, data, 1) == '*' && @@ -1177,14 +1190,16 @@ checkpath(PyObject* tag) /*[clinic input] _elementtree.Element.extend + cls: defining_class elements: object / [clinic start generated code]*/ static PyObject * -_elementtree_Element_extend(ElementObject *self, PyObject *elements) -/*[clinic end generated code: output=f6e67fc2ff529191 input=807bc4f31c69f7c0]*/ +_elementtree_Element_extend_impl(ElementObject *self, PyTypeObject *cls, + PyObject *elements) +/*[clinic end generated code: output=3e86d37fac542216 input=6479b1b5379d09ae]*/ { PyObject* seq; Py_ssize_t i; @@ -1198,10 +1213,10 @@ _elementtree_Element_extend(ElementObject *self, PyObject *elements) return NULL; } + elementtreestate *st = get_elementtree_state_by_cls(cls); for (i = 0; i < PySequence_Fast_GET_SIZE(seq); i++) { - PyObject* element = PySequence_Fast_GET_ITEM(seq, i); - Py_INCREF(element); - if (element_add_subelement(self, element) < 0) { + PyObject* element = Py_NewRef(PySequence_Fast_GET_ITEM(seq, i)); + if (element_add_subelement(st, self, element) < 0) { Py_DECREF(seq); Py_DECREF(element); return NULL; @@ -1217,23 +1232,24 @@ _elementtree_Element_extend(ElementObject *self, PyObject *elements) /*[clinic input] _elementtree.Element.find + cls: defining_class + / path: object namespaces: object = None [clinic start generated code]*/ static PyObject * -_elementtree_Element_find_impl(ElementObject *self, PyObject *path, - PyObject *namespaces) -/*[clinic end generated code: output=41b43f0f0becafae input=359b6985f6489d2e]*/ +_elementtree_Element_find_impl(ElementObject *self, PyTypeObject *cls, + PyObject *path, PyObject *namespaces) +/*[clinic end generated code: output=18f77d393c9fef1b input=94df8a83f956acc6]*/ { Py_ssize_t i; - elementtreestate *st = ET_STATE_GLOBAL; + elementtreestate *st = get_elementtree_state_by_cls(cls); if (checkpath(path) || namespaces != Py_None) { - _Py_IDENTIFIER(find); - return _PyObject_CallMethodIdObjArgs( - st->elementpath_obj, &PyId_find, self, path, namespaces, NULL + return PyObject_CallMethodObjArgs( + st->elementpath_obj, st->str_find, self, path, namespaces, NULL ); } @@ -1243,7 +1259,7 @@ _elementtree_Element_find_impl(ElementObject *self, PyObject *path, for (i = 0; i < self->extra->length; i++) { PyObject* item = self->extra->children[i]; int rc; - assert(Element_Check(item)); + assert(Element_Check(st, item)); Py_INCREF(item); rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); if (rc > 0) @@ -1259,6 +1275,8 @@ _elementtree_Element_find_impl(ElementObject *self, PyObject *path, /*[clinic input] _elementtree.Element.findtext + cls: defining_class + / path: object default: object = None namespaces: object = None @@ -1266,30 +1284,28 @@ _elementtree.Element.findtext [clinic start generated code]*/ static PyObject * -_elementtree_Element_findtext_impl(ElementObject *self, PyObject *path, - PyObject *default_value, +_elementtree_Element_findtext_impl(ElementObject *self, PyTypeObject *cls, + PyObject *path, PyObject *default_value, PyObject *namespaces) -/*[clinic end generated code: output=83b3ba4535d308d2 input=b53a85aa5aa2a916]*/ +/*[clinic end generated code: output=6af7a2d96aac32cb input=32f252099f62a3d2]*/ { Py_ssize_t i; - _Py_IDENTIFIER(findtext); - elementtreestate *st = ET_STATE_GLOBAL; + elementtreestate *st = get_elementtree_state_by_cls(cls); if (checkpath(path) || namespaces != Py_None) - return _PyObject_CallMethodIdObjArgs( - st->elementpath_obj, &PyId_findtext, + return PyObject_CallMethodObjArgs( + st->elementpath_obj, st->str_findtext, self, path, default_value, namespaces, NULL ); if (!self->extra) { - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } for (i = 0; i < self->extra->length; i++) { PyObject *item = self->extra->children[i]; int rc; - assert(Element_Check(item)); + assert(Element_Check(st, item)); Py_INCREF(item); rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); if (rc > 0) { @@ -1307,31 +1323,31 @@ _elementtree_Element_findtext_impl(ElementObject *self, PyObject *path, return NULL; } - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } /*[clinic input] _elementtree.Element.findall + cls: defining_class + / path: object namespaces: object = None [clinic start generated code]*/ static PyObject * -_elementtree_Element_findall_impl(ElementObject *self, PyObject *path, - PyObject *namespaces) -/*[clinic end generated code: output=1a0bd9f5541b711d input=4d9e6505a638550c]*/ +_elementtree_Element_findall_impl(ElementObject *self, PyTypeObject *cls, + PyObject *path, PyObject *namespaces) +/*[clinic end generated code: output=65e39a1208f3b59e input=7aa0db45673fc9a5]*/ { Py_ssize_t i; PyObject* out; - elementtreestate *st = ET_STATE_GLOBAL; + elementtreestate *st = get_elementtree_state_by_cls(cls); if (checkpath(path) || namespaces != Py_None) { - _Py_IDENTIFIER(findall); - return _PyObject_CallMethodIdObjArgs( - st->elementpath_obj, &PyId_findall, self, path, namespaces, NULL + return PyObject_CallMethodObjArgs( + st->elementpath_obj, st->str_findall, self, path, namespaces, NULL ); } @@ -1345,7 +1361,7 @@ _elementtree_Element_findall_impl(ElementObject *self, PyObject *path, for (i = 0; i < self->extra->length; i++) { PyObject* item = self->extra->children[i]; int rc; - assert(Element_Check(item)); + assert(Element_Check(st, item)); Py_INCREF(item); rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); if (rc != 0 && (rc < 0 || PyList_Append(out, item) < 0)) { @@ -1362,22 +1378,23 @@ _elementtree_Element_findall_impl(ElementObject *self, PyObject *path, /*[clinic input] _elementtree.Element.iterfind + cls: defining_class + / path: object namespaces: object = None [clinic start generated code]*/ static PyObject * -_elementtree_Element_iterfind_impl(ElementObject *self, PyObject *path, - PyObject *namespaces) -/*[clinic end generated code: output=ecdd56d63b19d40f input=abb974e350fb65c7]*/ +_elementtree_Element_iterfind_impl(ElementObject *self, PyTypeObject *cls, + PyObject *path, PyObject *namespaces) +/*[clinic end generated code: output=be5c3f697a14e676 input=88766875a5c9a88b]*/ { PyObject* tag = path; - _Py_IDENTIFIER(iterfind); - elementtreestate *st = ET_STATE_GLOBAL; + elementtreestate *st = get_elementtree_state_by_cls(cls); - return _PyObject_CallMethodIdObjArgs( - st->elementpath_obj, &PyId_iterfind, self, tag, namespaces, NULL); + return PyObject_CallMethodObjArgs( + st->elementpath_obj, st->str_iterfind, self, tag, namespaces, NULL); } /*[clinic input] @@ -1393,38 +1410,36 @@ _elementtree_Element_get_impl(ElementObject *self, PyObject *key, PyObject *default_value) /*[clinic end generated code: output=523c614142595d75 input=ee153bbf8cdb246e]*/ { - PyObject* value; - - if (!self->extra || !self->extra->attrib) - value = default_value; - else { - value = PyDict_GetItemWithError(self->extra->attrib, key); - if (!value) { - if (PyErr_Occurred()) { - return NULL; - } - value = default_value; + if (self->extra && self->extra->attrib) { + PyObject *attrib = Py_NewRef(self->extra->attrib); + PyObject *value = Py_XNewRef(PyDict_GetItemWithError(attrib, key)); + Py_DECREF(attrib); + if (value != NULL || PyErr_Occurred()) { + return value; } } - Py_INCREF(value); - return value; + return Py_NewRef(default_value); } static PyObject * -create_elementiter(ElementObject *self, PyObject *tag, int gettext); +create_elementiter(elementtreestate *st, ElementObject *self, PyObject *tag, + int gettext); /*[clinic input] _elementtree.Element.iter + cls: defining_class + / tag: object = None [clinic start generated code]*/ static PyObject * -_elementtree_Element_iter_impl(ElementObject *self, PyObject *tag) -/*[clinic end generated code: output=3f49f9a862941cc5 input=774d5b12e573aedd]*/ +_elementtree_Element_iter_impl(ElementObject *self, PyTypeObject *cls, + PyObject *tag) +/*[clinic end generated code: output=bff29dc5d4566c68 input=f6944c48d3f84c58]*/ { if (PyUnicode_Check(tag)) { if (PyUnicode_READY(tag) < 0) @@ -1437,20 +1452,25 @@ _elementtree_Element_iter_impl(ElementObject *self, PyObject *tag) tag = Py_None; } - return create_elementiter(self, tag, 0); + elementtreestate *st = get_elementtree_state_by_cls(cls); + return create_elementiter(st, self, tag, 0); } /*[clinic input] _elementtree.Element.itertext + cls: defining_class + / + [clinic start generated code]*/ static PyObject * -_elementtree_Element_itertext_impl(ElementObject *self) -/*[clinic end generated code: output=5fa34b2fbcb65df6 input=af8f0e42cb239c89]*/ +_elementtree_Element_itertext_impl(ElementObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=fdeb2a3bca0ae063 input=a1ef1f0fc872a586]*/ { - return create_elementiter(self, Py_None, 1); + elementtreestate *st = get_elementtree_state_by_cls(cls); + return create_elementiter(st, self, Py_None, 1); } @@ -1467,15 +1487,31 @@ element_getitem(PyObject* self_, Py_ssize_t index) return NULL; } - Py_INCREF(self->extra->children[index]); - return self->extra->children[index]; + return Py_NewRef(self->extra->children[index]); +} + +static int +element_bool(PyObject* self_) +{ + ElementObject* self = (ElementObject*) self_; + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Testing an element's truth value will raise an exception " + "in future versions. Use specific 'len(elem)' or " + "'elem is not None' test instead.", + 1) < 0) { + return -1; + }; + if (self->extra ? self->extra->length : 0) { + return 1; + } + return 0; } /*[clinic input] _elementtree.Element.insert index: Py_ssize_t - subelement: object(subclass_of='&Element_Type') + subelement: object(subclass_of='clinic_state()->Element_Type') / [clinic start generated code]*/ @@ -1483,7 +1519,7 @@ _elementtree.Element.insert static PyObject * _elementtree_Element_insert_impl(ElementObject *self, Py_ssize_t index, PyObject *subelement) -/*[clinic end generated code: output=990adfef4d424c0b input=cd6fbfcdab52d7a8]*/ +/*[clinic end generated code: output=990adfef4d424c0b input=9530f4905aa401ca]*/ { Py_ssize_t i; @@ -1506,8 +1542,7 @@ _elementtree_Element_insert_impl(ElementObject *self, Py_ssize_t index, for (i = self->extra->length; i > index; i--) self->extra->children[i] = self->extra->children[i-1]; - Py_INCREF(subelement); - self->extra->children[index] = subelement; + self->extra->children[index] = Py_NewRef(subelement); self->extra->length++; @@ -1556,6 +1591,7 @@ element_length(ElementObject* self) /*[clinic input] _elementtree.Element.makeelement + cls: defining_class tag: object attrib: object(subclass_of='&PyDict_Type') / @@ -1563,9 +1599,9 @@ _elementtree.Element.makeelement [clinic start generated code]*/ static PyObject * -_elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, - PyObject *attrib) -/*[clinic end generated code: output=4109832d5bb789ef input=2279d974529c3861]*/ +_elementtree_Element_makeelement_impl(ElementObject *self, PyTypeObject *cls, + PyObject *tag, PyObject *attrib) +/*[clinic end generated code: output=d50bb17a47077d47 input=589829dab92f26e8]*/ { PyObject* elem; @@ -1573,7 +1609,8 @@ _elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, if (!attrib) return NULL; - elem = create_new_element(tag, attrib); + elementtreestate *st = get_elementtree_state_by_cls(cls); + elem = create_new_element(st, tag, attrib); Py_DECREF(attrib); @@ -1583,14 +1620,14 @@ _elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, /*[clinic input] _elementtree.Element.remove - subelement: object(subclass_of='&Element_Type') + subelement: object(subclass_of='clinic_state()->Element_Type') / [clinic start generated code]*/ static PyObject * _elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement) -/*[clinic end generated code: output=38fe6c07d6d87d1f input=d52fc28ededc0bd8]*/ +/*[clinic end generated code: output=38fe6c07d6d87d1f input=6133e1d05597d5ee]*/ { Py_ssize_t i; int rc; @@ -1704,12 +1741,13 @@ element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item) old = self->extra->children[index]; if (item) { - if (!Element_Check(item)) { + PyTypeObject *tp = Py_TYPE(self); + elementtreestate *st = get_elementtree_state_by_type(tp); + if (!Element_Check(st, item)) { raise_type_error(item); return -1; } - Py_INCREF(item); - self->extra->children[index] = item; + self->extra->children[index] = Py_NewRef(item); } else { self->extra->length--; for (i = index; i < self->extra->length; i++) @@ -1759,8 +1797,7 @@ element_subscr(PyObject* self_, PyObject* item) for (cur = start, i = 0; i < slicelen; cur += step, i++) { - PyObject* item = self->extra->children[cur]; - Py_INCREF(item); + PyObject* item = Py_NewRef(self->extra->children[cur]); PyList_SET_ITEM(list, i, item); } @@ -1903,9 +1940,11 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) } } + PyTypeObject *tp = Py_TYPE(self); + elementtreestate *st = get_elementtree_state_by_type(tp); for (i = 0; i < newlen; i++) { PyObject *element = PySequence_Fast_GET_ITEM(seq, i); - if (!Element_Check(element)) { + if (!Element_Check(st, element)) { raise_type_error(element); Py_DECREF(seq); return -1; @@ -1940,8 +1979,7 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) for (cur = start, i = 0; i < newlen; cur += step, i++) { PyObject* element = PySequence_Fast_GET_ITEM(seq, i); - Py_INCREF(element); - self->extra->children[cur] = element; + self->extra->children[cur] = Py_NewRef(element); } self->extra->length += newlen - slicelen; @@ -1964,24 +2002,21 @@ static PyObject* element_tag_getter(ElementObject *self, void *closure) { PyObject *res = self->tag; - Py_INCREF(res); - return res; + return Py_NewRef(res); } static PyObject* element_text_getter(ElementObject *self, void *closure) { PyObject *res = element_get_text(self); - Py_XINCREF(res); - return res; + return Py_XNewRef(res); } static PyObject* element_tail_getter(ElementObject *self, void *closure) { PyObject *res = element_get_tail(self); - Py_XINCREF(res); - return res; + return Py_XNewRef(res); } static PyObject* @@ -1993,8 +2028,7 @@ element_attrib_getter(ElementObject *self, void *closure) return NULL; } res = element_get_attrib(self); - Py_XINCREF(res); - return res; + return Py_XNewRef(res); } /* macro for setter validation */ @@ -2010,8 +2044,7 @@ static int element_tag_setter(ElementObject *self, PyObject *value, void *closure) { _VALIDATE_ATTR_VALUE(value); - Py_INCREF(value); - Py_SETREF(self->tag, value); + Py_SETREF(self->tag, Py_NewRef(value)); return 0; } @@ -2019,8 +2052,7 @@ static int element_text_setter(ElementObject *self, PyObject *value, void *closure) { _VALIDATE_ATTR_VALUE(value); - Py_INCREF(value); - _set_joined_ptr(&self->text, value); + _set_joined_ptr(&self->text, Py_NewRef(value)); return 0; } @@ -2028,8 +2060,7 @@ static int element_tail_setter(ElementObject *self, PyObject *value, void *closure) { _VALIDATE_ATTR_VALUE(value); - Py_INCREF(value); - _set_joined_ptr(&self->tail, value); + _set_joined_ptr(&self->tail, Py_NewRef(value)); return 0; } @@ -2047,21 +2078,10 @@ element_attrib_setter(ElementObject *self, PyObject *value, void *closure) if (create_extra(self, NULL) < 0) return -1; } - Py_INCREF(value); - Py_XSETREF(self->extra->attrib, value); + Py_XSETREF(self->extra->attrib, Py_NewRef(value)); return 0; } -static PySequenceMethods element_as_sequence = { - (lenfunc) element_length, - 0, /* sq_concat */ - 0, /* sq_repeat */ - element_getitem, - 0, - element_setitem, - 0, -}; - /******************************* Element iterator ****************************/ /* ElementIterObject represents the iteration state over an XML element in @@ -2091,6 +2111,7 @@ typedef struct { static void elementiter_dealloc(ElementIterObject *it) { + PyTypeObject *tp = Py_TYPE(it); Py_ssize_t i = it->parent_stack_used; it->parent_stack_used = 0; /* bpo-31095: UnTrack is needed before calling any callbacks */ @@ -2102,7 +2123,8 @@ elementiter_dealloc(ElementIterObject *it) Py_XDECREF(it->sought_tag); Py_XDECREF(it->root_element); - PyObject_GC_Del(it); + tp->tp_free(it); + Py_DECREF(tp); } static int @@ -2114,6 +2136,7 @@ elementiter_traverse(ElementIterObject *it, visitproc visit, void *arg) Py_VISIT(it->root_element); Py_VISIT(it->sought_tag); + Py_VISIT(Py_TYPE(it)); return 0; } @@ -2134,8 +2157,7 @@ parent_stack_push_new(ElementIterObject *it, ElementObject *parent) it->parent_stack_size = new_size; } item = it->parent_stack + it->parent_stack_used++; - Py_INCREF(parent); - item->parent = parent; + item->parent = (ElementObject*)Py_NewRef(parent); item->child_index = 0; return 0; } @@ -2195,10 +2217,13 @@ elementiter_next(ElementIterObject *it) continue; } - assert(Element_Check(extra->children[child_index])); - elem = (ElementObject *)extra->children[child_index]; +#ifndef NDEBUG + PyTypeObject *tp = Py_TYPE(it); + elementtreestate *st = get_elementtree_state_by_type(tp); + assert(Element_Check(st, extra->children[child_index])); +#endif + elem = (ElementObject *)Py_NewRef(extra->children[child_index]); item->child_index++; - Py_INCREF(elem); } if (parent_stack_push_new(it, elem) < 0) { @@ -2246,67 +2271,39 @@ gettext: return NULL; } +static PyType_Slot elementiter_slots[] = { + {Py_tp_dealloc, elementiter_dealloc}, + {Py_tp_traverse, elementiter_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, elementiter_next}, + {0, NULL}, +}; -static PyTypeObject ElementIter_Type = { - PyVarObject_HEAD_INIT(NULL, 0) +static PyType_Spec elementiter_spec = { /* Using the module's name since the pure-Python implementation does not have such a type. */ - "_elementtree._element_iterator", /* tp_name */ - sizeof(ElementIterObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)elementiter_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)elementiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)elementiter_next, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ + .name = "_elementtree._element_iterator", + .basicsize = sizeof(ElementIterObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), + .slots = elementiter_slots, }; #define INIT_PARENT_STACK_SIZE 8 static PyObject * -create_elementiter(ElementObject *self, PyObject *tag, int gettext) +create_elementiter(elementtreestate *st, ElementObject *self, PyObject *tag, + int gettext) { ElementIterObject *it; - it = PyObject_GC_New(ElementIterObject, &ElementIter_Type); + it = PyObject_GC_New(ElementIterObject, st->ElementIter_Type); if (!it) return NULL; - Py_INCREF(tag); - it->sought_tag = tag; + it->sought_tag = Py_NewRef(tag); it->gettext = gettext; - Py_INCREF(self); - it->root_element = self; + it->root_element = (ElementObject*)Py_NewRef(self); it->parent_stack = PyMem_New(ParentLocator, INIT_PARENT_STACK_SIZE); if (it->parent_stack == NULL) { @@ -2355,9 +2352,10 @@ typedef struct { char insert_comments; char insert_pis; + elementtreestate *state; } TreeBuilderObject; -#define TreeBuilder_CheckExact(op) Py_IS_TYPE((op), &TreeBuilder_Type) +#define TreeBuilder_CheckExact(st, op) Py_IS_TYPE((op), (st)->TreeBuilder_Type) /* -------------------------------------------------------------------- */ /* constructor and destructor */ @@ -2368,12 +2366,8 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) TreeBuilderObject *t = (TreeBuilderObject *)type->tp_alloc(type, 0); if (t != NULL) { t->root = NULL; - - Py_INCREF(Py_None); - t->this = Py_None; - Py_INCREF(Py_None); - t->last = Py_None; - + t->this = Py_NewRef(Py_None); + t->last = Py_NewRef(Py_None); t->data = NULL; t->element_factory = NULL; t->comment_factory = NULL; @@ -2392,6 +2386,7 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) t->start_ns_event_obj = t->end_ns_event_obj = NULL; t->comment_event_obj = t->pi_event_obj = NULL; t->insert_comments = t->insert_pis = 0; + t->state = get_elementtree_state_by_type(type); } return (PyObject *)t; } @@ -2417,19 +2412,17 @@ _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, /*[clinic end generated code: output=8571d4dcadfdf952 input=ae98a94df20b5cc3]*/ { if (element_factory != Py_None) { - Py_INCREF(element_factory); - Py_XSETREF(self->element_factory, element_factory); + Py_XSETREF(self->element_factory, Py_NewRef(element_factory)); } else { Py_CLEAR(self->element_factory); } if (comment_factory == Py_None) { - elementtreestate *st = ET_STATE_GLOBAL; + elementtreestate *st = self->state; comment_factory = st->comment_factory; } if (comment_factory) { - Py_INCREF(comment_factory); - Py_XSETREF(self->comment_factory, comment_factory); + Py_XSETREF(self->comment_factory, Py_NewRef(comment_factory)); self->insert_comments = insert_comments; } else { Py_CLEAR(self->comment_factory); @@ -2437,12 +2430,11 @@ _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, } if (pi_factory == Py_None) { - elementtreestate *st = ET_STATE_GLOBAL; + elementtreestate *st = self->state; pi_factory = st->pi_factory; } if (pi_factory) { - Py_INCREF(pi_factory); - Py_XSETREF(self->pi_factory, pi_factory); + Py_XSETREF(self->pi_factory, Py_NewRef(pi_factory)); self->insert_pis = insert_pis; } else { Py_CLEAR(self->pi_factory); @@ -2455,6 +2447,7 @@ _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, static int treebuilder_gc_traverse(TreeBuilderObject *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->pi_event_obj); Py_VISIT(self->comment_event_obj); Py_VISIT(self->end_ns_event_obj); @@ -2499,9 +2492,11 @@ treebuilder_gc_clear(TreeBuilderObject *self) static void treebuilder_dealloc(TreeBuilderObject *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); treebuilder_gc_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); + tp->tp_free(self); + Py_DECREF(tp); } /* -------------------------------------------------------------------- */ @@ -2524,7 +2519,7 @@ _elementtree__set_factories_impl(PyObject *module, PyObject *comment_factory, PyObject *pi_factory) /*[clinic end generated code: output=813b408adee26535 input=99d17627aea7fb3b]*/ { - elementtreestate *st = ET_STATE_GLOBAL; + elementtreestate *st = get_elementtree_state(module); PyObject *old; if (!PyCallable_Check(comment_factory) && comment_factory != Py_None) { @@ -2545,25 +2540,24 @@ _elementtree__set_factories_impl(PyObject *module, PyObject *comment_factory, if (comment_factory == Py_None) { Py_CLEAR(st->comment_factory); } else { - Py_INCREF(comment_factory); - Py_XSETREF(st->comment_factory, comment_factory); + Py_XSETREF(st->comment_factory, Py_NewRef(comment_factory)); } if (pi_factory == Py_None) { Py_CLEAR(st->pi_factory); } else { - Py_INCREF(pi_factory); - Py_XSETREF(st->pi_factory, pi_factory); + Py_XSETREF(st->pi_factory, Py_NewRef(pi_factory)); } return old; } static int -treebuilder_extend_element_text_or_tail(PyObject *element, PyObject **data, - PyObject **dest, _Py_Identifier *name) +treebuilder_extend_element_text_or_tail(elementtreestate *st, PyObject *element, + PyObject **data, PyObject **dest, + PyObject *name) { /* Fast paths for the "almost always" cases. */ - if (Element_CheckExact(element)) { + if (Element_CheckExact(st, element)) { PyObject *dest_obj = JOIN_OBJ(*dest); if (dest_obj == Py_None) { *dest = JOIN_SET(*data, PyList_CheckExact(*data)); @@ -2584,7 +2578,7 @@ treebuilder_extend_element_text_or_tail(PyObject *element, PyObject **data, { int r; PyObject* joined; - PyObject* previous = _PyObject_GetAttrId(element, name); + PyObject* previous = PyObject_GetAttr(element, name); if (!previous) return -1; joined = list_join(*data); @@ -2603,7 +2597,7 @@ treebuilder_extend_element_text_or_tail(PyObject *element, PyObject **data, Py_DECREF(previous); } - r = _PyObject_SetAttrId(element, name, joined); + r = PyObject_SetAttr(element, name, joined); Py_DECREF(joined); if (r < 0) return -1; @@ -2618,34 +2612,32 @@ treebuilder_flush_data(TreeBuilderObject* self) if (!self->data) { return 0; } - + elementtreestate *st = self->state; if (!self->last_for_tail) { PyObject *element = self->last; - _Py_IDENTIFIER(text); return treebuilder_extend_element_text_or_tail( - element, &self->data, - &((ElementObject *) element)->text, &PyId_text); + st, element, &self->data, + &((ElementObject *) element)->text, st->str_text); } else { PyObject *element = self->last_for_tail; - _Py_IDENTIFIER(tail); return treebuilder_extend_element_text_or_tail( - element, &self->data, - &((ElementObject *) element)->tail, &PyId_tail); + st, element, &self->data, + &((ElementObject *) element)->tail, st->str_tail); } } static int -treebuilder_add_subelement(PyObject *element, PyObject *child) +treebuilder_add_subelement(elementtreestate *st, PyObject *element, + PyObject *child) { - _Py_IDENTIFIER(append); - if (Element_CheckExact(element)) { + if (Element_CheckExact(st, element)) { ElementObject *elem = (ElementObject *) element; - return element_add_subelement(elem, child); + return element_add_subelement(st, elem, child); } else { PyObject *res; - res = _PyObject_CallMethodIdOneArg(element, &PyId_append, child); + res = PyObject_CallMethodOneArg(element, st->str_append, child); if (res == NULL) return -1; Py_DECREF(res); @@ -2680,15 +2672,16 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, { PyObject* node; PyObject* this; - elementtreestate *st = ET_STATE_GLOBAL; + elementtreestate *st = self->state; if (treebuilder_flush_data(self) < 0) { return NULL; } if (!self->element_factory) { - node = create_new_element(tag, attrib); - } else if (attrib == NULL) { + node = create_new_element(st, tag, attrib); + } + else if (attrib == NULL) { attrib = PyDict_New(); if (!attrib) return NULL; @@ -2708,8 +2701,9 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, Py_CLEAR(self->last_for_tail); if (this != Py_None) { - if (treebuilder_add_subelement(this, node) < 0) + if (treebuilder_add_subelement(st, this, node) < 0) { goto error; + } } else { if (self->root) { PyErr_SetString( @@ -2718,8 +2712,7 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, ); goto error; } - Py_INCREF(node); - self->root = node; + self->root = Py_NewRef(node); } if (self->index < PyList_GET_SIZE(self->stack)) { @@ -2732,10 +2725,8 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, } self->index++; - Py_INCREF(node); - Py_SETREF(self->this, node); - Py_INCREF(node); - Py_SETREF(self->last, node); + Py_SETREF(self->this, Py_NewRef(node)); + Py_SETREF(self->last, Py_NewRef(node)); if (treebuilder_append_event(self, self->start_event_obj, node) < 0) goto error; @@ -2756,7 +2747,7 @@ treebuilder_handle_data(TreeBuilderObject* self, PyObject* data) Py_RETURN_NONE; } /* store the first item as is */ - Py_INCREF(data); self->data = data; + self->data = Py_NewRef(data); } else { /* more than one item; use a list to collect items */ if (PyBytes_CheckExact(self->data) && Py_REFCNT(self->data) == 1 && @@ -2775,9 +2766,9 @@ treebuilder_handle_data(TreeBuilderObject* self, PyObject* data) PyObject* list = PyList_New(2); if (!list) return NULL; - PyList_SET_ITEM(list, 0, self->data); - Py_INCREF(data); PyList_SET_ITEM(list, 1, data); - self->data = list; + PyList_SET_ITEM(list, 0, Py_NewRef(self->data)); + PyList_SET_ITEM(list, 1, Py_NewRef(data)); + Py_SETREF(self->data, list); } } @@ -2802,19 +2793,16 @@ treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag) } item = self->last; - self->last = self->this; - Py_INCREF(self->last); + self->last = Py_NewRef(self->this); Py_XSETREF(self->last_for_tail, self->last); self->index--; - self->this = PyList_GET_ITEM(self->stack, self->index); - Py_INCREF(self->this); + self->this = Py_NewRef(PyList_GET_ITEM(self->stack, self->index)); Py_DECREF(item); if (treebuilder_append_event(self, self->end_event_obj, self->last) < 0) return NULL; - Py_INCREF(self->last); - return (PyObject*) self->last; + return Py_NewRef(self->last); } LOCAL(PyObject*) @@ -2834,14 +2822,13 @@ treebuilder_handle_comment(TreeBuilderObject* self, PyObject* text) this = self->this; if (self->insert_comments && this != Py_None) { - if (treebuilder_add_subelement(this, comment) < 0) + if (treebuilder_add_subelement(self->state, this, comment) < 0) { goto error; - Py_INCREF(comment); - Py_XSETREF(self->last_for_tail, comment); + } + Py_XSETREF(self->last_for_tail, Py_NewRef(comment)); } } else { - Py_INCREF(text); - comment = text; + comment = Py_NewRef(text); } if (self->events_append && self->comment_event_obj) { @@ -2875,10 +2862,10 @@ treebuilder_handle_pi(TreeBuilderObject* self, PyObject* target, PyObject* text) this = self->this; if (self->insert_pis && this != Py_None) { - if (treebuilder_add_subelement(this, pi) < 0) + if (treebuilder_add_subelement(self->state, this, pi) < 0) { goto error; - Py_INCREF(pi); - Py_XSETREF(self->last_for_tail, pi); + } + Py_XSETREF(self->last_for_tail, Py_NewRef(pi)); } } else { pi = PyTuple_Pack(2, target, text); @@ -3009,8 +2996,7 @@ treebuilder_done(TreeBuilderObject* self) else res = Py_None; - Py_INCREF(res); - return res; + return Py_NewRef(res); } /*[clinic input] @@ -3079,6 +3065,7 @@ typedef struct { PyObject *handle_close; + elementtreestate *state; } XMLParserObject; /* helpers */ @@ -3098,12 +3085,9 @@ makeuniversal(XMLParserObject* self, const char* string) if (!key) return NULL; - value = PyDict_GetItemWithError(self->names, key); + value = Py_XNewRef(PyDict_GetItemWithError(self->names, key)); - if (value) { - Py_INCREF(value); - } - else if (!PyErr_Occurred()) { + if (value == NULL && !PyErr_Occurred()) { /* new name. convert to universal name, and decode as necessary */ @@ -3128,8 +3112,7 @@ makeuniversal(XMLParserObject* self, const char* string) size++; } else { /* plain name; use key as tag */ - Py_INCREF(key); - tag = key; + tag = Py_NewRef(key); } /* decode universal name */ @@ -3158,11 +3141,10 @@ makeuniversal(XMLParserObject* self, const char* string) * message string is the default for the given error_code. */ static void -expat_set_error(enum XML_Error error_code, Py_ssize_t line, Py_ssize_t column, - const char *message) +expat_set_error(elementtreestate *st, enum XML_Error error_code, + Py_ssize_t line, Py_ssize_t column, const char *message) { PyObject *errmsg, *error, *position, *code; - elementtreestate *st = ET_STATE_GLOBAL; errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd", message ? message : EXPAT(ErrorString)(error_code), @@ -3227,8 +3209,9 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in, value = PyDict_GetItemWithError(self->entity, key); + elementtreestate *st = self->state; if (value) { - if (TreeBuilder_CheckExact(self->target)) + if (TreeBuilder_CheckExact(st, self->target)) res = treebuilder_handle_data( (TreeBuilderObject*) self->target, value ); @@ -3242,6 +3225,7 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in, char message[128] = "undefined entity "; strncat(message, data_in, data_len < 100?data_len:100); expat_set_error( + st, XML_ERROR_UNDEFINED_ENTITY, EXPAT(GetErrorLineNumber)(self->parser), EXPAT(GetErrorColumnNumber)(self->parser), @@ -3300,7 +3284,8 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in, attrib = NULL; } - if (TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = self->state; + if (TreeBuilder_CheckExact(st, self->target)) { /* shortcut */ res = treebuilder_handle_start((TreeBuilderObject*) self->target, tag, attrib); @@ -3338,7 +3323,8 @@ expat_data_handler(XMLParserObject* self, const XML_Char* data_in, if (!data) return; /* parser will look for errors */ - if (TreeBuilder_CheckExact(self->target)) + elementtreestate *st = self->state; + if (TreeBuilder_CheckExact(st, self->target)) /* shortcut */ res = treebuilder_handle_data((TreeBuilderObject*) self->target, data); else if (self->handle_data) @@ -3360,7 +3346,8 @@ expat_end_handler(XMLParserObject* self, const XML_Char* tag_in) if (PyErr_Occurred()) return; - if (TreeBuilder_CheckExact(self->target)) + elementtreestate *st = self->state; + if (TreeBuilder_CheckExact(st, self->target)) /* shortcut */ /* the standard tree builder doesn't look at the end tag */ res = treebuilder_handle_end( @@ -3394,7 +3381,8 @@ expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix_in, if (!prefix_in) prefix_in = ""; - if (TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = self->state; + if (TreeBuilder_CheckExact(st, self->target)) { /* shortcut - TreeBuilder does not actually implement .start_ns() */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; @@ -3444,7 +3432,8 @@ expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in) if (!prefix_in) prefix_in = ""; - if (TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = self->state; + if (TreeBuilder_CheckExact(st, self->target)) { /* shortcut - TreeBuilder does not actually implement .end_ns() */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; @@ -3472,7 +3461,8 @@ expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in) if (PyErr_Occurred()) return; - if (TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = self->state; + if (TreeBuilder_CheckExact(st, self->target)) { /* shortcut */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; @@ -3501,7 +3491,6 @@ expat_start_doctype_handler(XMLParserObject *self, const XML_Char *pubid, int has_internal_subset) { - _Py_IDENTIFIER(doctype); PyObject *doctype_name_obj, *sysid_obj, *pubid_obj; PyObject *res; @@ -3519,8 +3508,7 @@ expat_start_doctype_handler(XMLParserObject *self, return; } } else { - Py_INCREF(Py_None); - sysid_obj = Py_None; + sysid_obj = Py_NewRef(Py_None); } if (pubid) { @@ -3531,10 +3519,10 @@ expat_start_doctype_handler(XMLParserObject *self, return; } } else { - Py_INCREF(Py_None); - pubid_obj = Py_None; + pubid_obj = Py_NewRef(Py_None); } + elementtreestate *st = self->state; /* If the target has a handler for doctype, call it. */ if (self->handle_doctype) { res = PyObject_CallFunctionObjArgs(self->handle_doctype, @@ -3542,7 +3530,7 @@ expat_start_doctype_handler(XMLParserObject *self, sysid_obj, NULL); Py_XDECREF(res); } - else if (_PyObject_LookupAttrId((PyObject *)self, &PyId_doctype, &res) > 0) { + else if (_PyObject_LookupAttr((PyObject *)self, st->str_doctype, &res) > 0) { (void)PyErr_WarnEx(PyExc_RuntimeWarning, "The doctype() method of XMLParser is ignored. " "Define doctype() method on the TreeBuilder target.", @@ -3567,7 +3555,8 @@ expat_pi_handler(XMLParserObject* self, const XML_Char* target_in, if (PyErr_Occurred()) return; - if (TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = self->state; + if (TreeBuilder_CheckExact(st, self->target)) { /* shortcut */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; @@ -3619,6 +3608,7 @@ xmlparser_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->handle_start = self->handle_data = self->handle_end = NULL; self->handle_comment = self->handle_pi = self->handle_close = NULL; self->handle_doctype = NULL; + self->state = get_elementtree_state_by_type(type); } return (PyObject *)self; } @@ -3639,7 +3629,7 @@ ignore_attribute_error(PyObject *value) _elementtree.XMLParser.__init__ * - target: object = NULL + target: object = None encoding: str(accept={str, NoneType}) = None [clinic start generated code]*/ @@ -3647,7 +3637,7 @@ _elementtree.XMLParser.__init__ static int _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, const char *encoding) -/*[clinic end generated code: output=3ae45ec6cdf344e4 input=53e35a829ae043e8]*/ +/*[clinic end generated code: output=3ae45ec6cdf344e4 input=7e716dd6e4f3e439]*/ { self->entity = PyDict_New(); if (!self->entity) @@ -3672,10 +3662,11 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, (unsigned long)_Py_HashSecret.expat.hashsalt); } - if (target) { + if (target != Py_None) { Py_INCREF(target); } else { - target = treebuilder_new(&TreeBuilder_Type, NULL, NULL); + elementtreestate *st = self->state; + target = treebuilder_new(st->TreeBuilder_Type, NULL, NULL); if (!target) { Py_CLEAR(self->entity); Py_CLEAR(self->names); @@ -3767,6 +3758,7 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, static int xmlparser_gc_traverse(XMLParserObject *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->handle_close); Py_VISIT(self->handle_pi); Py_VISIT(self->handle_comment); @@ -3813,9 +3805,11 @@ xmlparser_gc_clear(XMLParserObject *self) static void xmlparser_dealloc(XMLParserObject* self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); xmlparser_gc_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); + tp->tp_free(self); + Py_DECREF(tp); } Py_LOCAL_INLINE(int) @@ -3830,7 +3824,8 @@ _check_xmlparser(XMLParserObject* self) } LOCAL(PyObject*) -expat_parse(XMLParserObject* self, const char* data, int data_len, int final) +expat_parse(elementtreestate *st, XMLParserObject *self, const char *data, + int data_len, int final) { int ok; @@ -3842,6 +3837,7 @@ expat_parse(XMLParserObject* self, const char* data, int data_len, int final) if (!ok) { expat_set_error( + st, EXPAT(GetErrorCode)(self->parser), EXPAT(GetErrorLineNumber)(self->parser), EXPAT(GetErrorColumnNumber)(self->parser), @@ -3869,11 +3865,12 @@ _elementtree_XMLParser_close_impl(XMLParserObject *self) if (!_check_xmlparser(self)) { return NULL; } - res = expat_parse(self, "", 0, 1); + elementtreestate *st = self->state; + res = expat_parse(st, self, "", 0, 1); if (!res) return NULL; - if (TreeBuilder_CheckExact(self->target)) { + if (TreeBuilder_CheckExact(st, self->target)) { Py_DECREF(res); return treebuilder_done((TreeBuilderObject*) self->target); } @@ -3903,6 +3900,7 @@ _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data) if (!_check_xmlparser(self)) { return NULL; } + elementtreestate *st = self->state; if (PyUnicode_Check(data)) { Py_ssize_t data_len; const char *data_ptr = PyUnicode_AsUTF8AndSize(data, &data_len); @@ -3914,7 +3912,8 @@ _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data) } /* Explicitly set UTF-8 encoding. Return code ignored. */ (void)EXPAT(SetEncoding)(self->parser, "utf-8"); - return expat_parse(self, data_ptr, (int)data_len, 0); + + return expat_parse(st, self, data_ptr, (int)data_len, 0); } else { Py_buffer view; @@ -3926,7 +3925,7 @@ _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data) PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); return NULL; } - res = expat_parse(self, view.buf, (int)view.len, 0); + res = expat_parse(st, self, view.buf, (int)view.len, 0); PyBuffer_Release(&view); return res; } @@ -3958,6 +3957,7 @@ _elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file) return NULL; /* read from open file object */ + elementtreestate *st = self->state; for (;;) { buffer = PyObject_CallFunction(reader, "i", 64*1024); @@ -3995,8 +3995,8 @@ _elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file) return NULL; } res = expat_parse( - self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), 0 - ); + st, self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), + 0); Py_DECREF(buffer); @@ -4010,9 +4010,9 @@ _elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file) Py_DECREF(reader); - res = expat_parse(self, "", 0, 1); + res = expat_parse(st, self, "", 0, 1); - if (res && TreeBuilder_CheckExact(self->target)) { + if (res && TreeBuilder_CheckExact(st, self->target)) { Py_DECREF(res); return treebuilder_done((TreeBuilderObject*) self->target); } @@ -4043,7 +4043,8 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self, if (!_check_xmlparser(self)) { return NULL; } - if (!TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = self->state; + if (!TreeBuilder_CheckExact(st, self->target)) { PyErr_SetString( PyExc_TypeError, "event handling only supported for ElementTree.TreeBuilder " @@ -4092,39 +4093,37 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self, return NULL; } - Py_INCREF(event_name_obj); if (strcmp(event_name, "start") == 0) { - Py_XSETREF(target->start_event_obj, event_name_obj); + Py_XSETREF(target->start_event_obj, Py_NewRef(event_name_obj)); } else if (strcmp(event_name, "end") == 0) { - Py_XSETREF(target->end_event_obj, event_name_obj); + Py_XSETREF(target->end_event_obj, Py_NewRef(event_name_obj)); } else if (strcmp(event_name, "start-ns") == 0) { - Py_XSETREF(target->start_ns_event_obj, event_name_obj); + Py_XSETREF(target->start_ns_event_obj, Py_NewRef(event_name_obj)); EXPAT(SetNamespaceDeclHandler)( self->parser, (XML_StartNamespaceDeclHandler) expat_start_ns_handler, (XML_EndNamespaceDeclHandler) expat_end_ns_handler ); } else if (strcmp(event_name, "end-ns") == 0) { - Py_XSETREF(target->end_ns_event_obj, event_name_obj); + Py_XSETREF(target->end_ns_event_obj, Py_NewRef(event_name_obj)); EXPAT(SetNamespaceDeclHandler)( self->parser, (XML_StartNamespaceDeclHandler) expat_start_ns_handler, (XML_EndNamespaceDeclHandler) expat_end_ns_handler ); } else if (strcmp(event_name, "comment") == 0) { - Py_XSETREF(target->comment_event_obj, event_name_obj); + Py_XSETREF(target->comment_event_obj, Py_NewRef(event_name_obj)); EXPAT(SetCommentHandler)( self->parser, (XML_CommentHandler) expat_comment_handler ); } else if (strcmp(event_name, "pi") == 0) { - Py_XSETREF(target->pi_event_obj, event_name_obj); + Py_XSETREF(target->pi_event_obj, Py_NewRef(event_name_obj)); EXPAT(SetProcessingInstructionHandler)( self->parser, (XML_ProcessingInstructionHandler) expat_pi_handler ); } else { - Py_DECREF(event_name_obj); Py_DECREF(events_seq); PyErr_Format(PyExc_ValueError, "unknown event '%s'", event_name); return NULL; @@ -4154,7 +4153,9 @@ static PyGetSetDef xmlparser_getsetlist[] = { {NULL}, }; +#define clinic_state() (get_elementtree_state_by_type(Py_TYPE(self))) #include "clinic/_elementtree.c.h" +#undef clinic_state static PyMethodDef element_methods[] = { @@ -4190,10 +4191,9 @@ static PyMethodDef element_methods[] = { {NULL, NULL} }; -static PyMappingMethods element_as_mapping = { - (lenfunc) element_length, - (binaryfunc) element_subscr, - (objobjargproc) element_ass_subscr, +static struct PyMemberDef element_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(ElementObject, weakreflist), READONLY}, + {NULL}, }; static PyGetSetDef element_getsetlist[] = { @@ -4216,46 +4216,34 @@ static PyGetSetDef element_getsetlist[] = { {NULL}, }; -static PyTypeObject Element_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "xml.etree.ElementTree.Element", sizeof(ElementObject), 0, - /* methods */ - (destructor)element_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)element_repr, /* tp_repr */ - 0, /* tp_as_number */ - &element_as_sequence, /* tp_as_sequence */ - &element_as_mapping, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)element_gc_traverse, /* tp_traverse */ - (inquiry)element_gc_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(ElementObject, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - element_methods, /* tp_methods */ - 0, /* tp_members */ - element_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)element_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - element_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot element_slots[] = { + {Py_tp_dealloc, element_dealloc}, + {Py_tp_repr, element_repr}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, element_gc_traverse}, + {Py_tp_clear, element_gc_clear}, + {Py_tp_methods, element_methods}, + {Py_tp_members, element_members}, + {Py_tp_getset, element_getsetlist}, + {Py_tp_init, element_init}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, element_new}, + {Py_sq_length, element_length}, + {Py_sq_item, element_getitem}, + {Py_sq_ass_item, element_setitem}, + {Py_nb_bool, element_bool}, + {Py_mp_length, element_length}, + {Py_mp_subscript, element_subscr}, + {Py_mp_ass_subscript, element_ass_subscr}, + {0, NULL}, +}; + +static PyType_Spec element_spec = { + .name = "xml.etree.ElementTree.Element", + .basicsize = sizeof(ElementObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = element_slots, }; static PyMethodDef treebuilder_methods[] = { @@ -4268,46 +4256,22 @@ static PyMethodDef treebuilder_methods[] = { {NULL, NULL} }; -static PyTypeObject TreeBuilder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "xml.etree.ElementTree.TreeBuilder", sizeof(TreeBuilderObject), 0, - /* methods */ - (destructor)treebuilder_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)treebuilder_gc_traverse, /* tp_traverse */ - (inquiry)treebuilder_gc_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - treebuilder_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - _elementtree_TreeBuilder___init__, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - treebuilder_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot treebuilder_slots[] = { + {Py_tp_dealloc, treebuilder_dealloc}, + {Py_tp_traverse, treebuilder_gc_traverse}, + {Py_tp_clear, treebuilder_gc_clear}, + {Py_tp_methods, treebuilder_methods}, + {Py_tp_init, _elementtree_TreeBuilder___init__}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, treebuilder_new}, + {0, NULL}, +}; + +static PyType_Spec treebuilder_spec = { + .name = "xml.etree.ElementTree.TreeBuilder", + .basicsize = sizeof(TreeBuilderObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE, + .slots = treebuilder_slots, }; static PyMethodDef xmlparser_methods[] = { @@ -4318,109 +4282,66 @@ static PyMethodDef xmlparser_methods[] = { {NULL, NULL} }; -static PyTypeObject XMLParser_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "xml.etree.ElementTree.XMLParser", sizeof(XMLParserObject), 0, - /* methods */ - (destructor)xmlparser_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)xmlparser_gc_traverse, /* tp_traverse */ - (inquiry)xmlparser_gc_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - xmlparser_methods, /* tp_methods */ - xmlparser_members, /* tp_members */ - xmlparser_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - _elementtree_XMLParser___init__, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - xmlparser_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot xmlparser_slots[] = { + {Py_tp_dealloc, xmlparser_dealloc}, + {Py_tp_traverse, xmlparser_gc_traverse}, + {Py_tp_clear, xmlparser_gc_clear}, + {Py_tp_methods, xmlparser_methods}, + {Py_tp_members, xmlparser_members}, + {Py_tp_getset, xmlparser_getsetlist}, + {Py_tp_init, _elementtree_XMLParser___init__}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, xmlparser_new}, + {0, NULL}, +}; + +static PyType_Spec xmlparser_spec = { + .name = "xml.etree.ElementTree.XMLParser", + .basicsize = sizeof(XMLParserObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = xmlparser_slots, }; /* ==================================================================== */ /* python module interface */ static PyMethodDef _functions[] = { - {"SubElement", (PyCFunction)(void(*)(void)) subelement, METH_VARARGS | METH_KEYWORDS}, + {"SubElement", _PyCFunction_CAST(subelement), METH_VARARGS | METH_KEYWORDS}, _ELEMENTTREE__SET_FACTORIES_METHODDEF {NULL, NULL} }; +#define CREATE_TYPE(module, type, spec) \ +do { \ + if (type != NULL) { \ + break; \ + } \ + type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, NULL); \ + if (type == NULL) { \ + goto error; \ + } \ +} while (0) -static struct PyModuleDef elementtreemodule = { - PyModuleDef_HEAD_INIT, - "_elementtree", - NULL, - sizeof(elementtreestate), - _functions, - NULL, - elementtree_traverse, - elementtree_clear, - elementtree_free -}; - -PyMODINIT_FUNC -PyInit__elementtree(void) +static int +module_exec(PyObject *m) { - PyObject *m, *temp; - elementtreestate *st; - - m = PyState_FindModule(&elementtreemodule); - if (m) { - Py_INCREF(m); - return m; - } + elementtreestate *st = get_elementtree_state(m); /* Initialize object types */ - if (PyType_Ready(&ElementIter_Type) < 0) - return NULL; - if (PyType_Ready(&TreeBuilder_Type) < 0) - return NULL; - if (PyType_Ready(&Element_Type) < 0) - return NULL; - if (PyType_Ready(&XMLParser_Type) < 0) - return NULL; - - m = PyModule_Create(&elementtreemodule); - if (!m) - return NULL; - st = get_elementtree_state(m); - - if (!(temp = PyImport_ImportModule("copy"))) - return NULL; - st->deepcopy_obj = PyObject_GetAttrString(temp, "deepcopy"); - Py_XDECREF(temp); + CREATE_TYPE(m, st->ElementIter_Type, &elementiter_spec); + CREATE_TYPE(m, st->TreeBuilder_Type, &treebuilder_spec); + CREATE_TYPE(m, st->Element_Type, &element_spec); + CREATE_TYPE(m, st->XMLParser_Type, &xmlparser_spec); + st->deepcopy_obj = _PyImport_GetModuleAttrString("copy", "deepcopy"); if (st->deepcopy_obj == NULL) { - return NULL; + goto error; } assert(!PyErr_Occurred()); if (!(st->elementpath_obj = PyImport_ImportModule("xml.etree.ElementPath"))) - return NULL; + goto error; /* link against pyexpat */ expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0); @@ -4433,32 +4354,87 @@ PyInit__elementtree(void) expat_capi->MICRO_VERSION != XML_MICRO_VERSION) { PyErr_SetString(PyExc_ImportError, "pyexpat version is incompatible"); - return NULL; + goto error; } } else { - return NULL; + goto error; } + st->str_append = PyUnicode_InternFromString("append"); + if (st->str_append == NULL) { + goto error; + } + st->str_find = PyUnicode_InternFromString("find"); + if (st->str_find == NULL) { + goto error; + } + st->str_findall = PyUnicode_InternFromString("findall"); + if (st->str_findall == NULL) { + goto error; + } + st->str_findtext = PyUnicode_InternFromString("findtext"); + if (st->str_findtext == NULL) { + goto error; + } + st->str_iterfind = PyUnicode_InternFromString("iterfind"); + if (st->str_iterfind == NULL) { + goto error; + } + st->str_tail = PyUnicode_InternFromString("tail"); + if (st->str_tail == NULL) { + goto error; + } + st->str_text = PyUnicode_InternFromString("text"); + if (st->str_text == NULL) { + goto error; + } + st->str_doctype = PyUnicode_InternFromString("doctype"); + if (st->str_doctype == NULL) { + goto error; + } st->parseerror_obj = PyErr_NewException( "xml.etree.ElementTree.ParseError", PyExc_SyntaxError, NULL ); - Py_INCREF(st->parseerror_obj); - if (PyModule_AddObject(m, "ParseError", st->parseerror_obj) < 0) { - Py_DECREF(st->parseerror_obj); - return NULL; + if (PyModule_AddObjectRef(m, "ParseError", st->parseerror_obj) < 0) { + goto error; } PyTypeObject *types[] = { - &Element_Type, - &TreeBuilder_Type, - &XMLParser_Type + st->Element_Type, + st->TreeBuilder_Type, + st->XMLParser_Type }; for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) { if (PyModule_AddType(m, types[i]) < 0) { - return NULL; + goto error; } } - return m; + return 0; + +error: + return -1; +} + +static struct PyModuleDef_Slot elementtree_slots[] = { + {Py_mod_exec, module_exec}, + {0, NULL}, +}; + +static struct PyModuleDef elementtreemodule = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_elementtree", + .m_size = sizeof(elementtreestate), + .m_methods = _functions, + .m_slots = elementtree_slots, + .m_traverse = elementtree_traverse, + .m_clear = elementtree_clear, + .m_free = elementtree_free, +}; + +PyMODINIT_FUNC +PyInit__elementtree(void) +{ + return PyModuleDef_Init(&elementtreemodule); } diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 1f6b852f6d9..4032ba79374 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -1,5 +1,6 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_dict.h" // _PyDict_Pop_KnownHash() #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_object.h" // _PyObject_GC_TRACK @@ -7,6 +8,13 @@ #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "structmember.h" // PyMemberDef +#include "clinic/_functoolsmodule.c.h" +/*[clinic input] +module _functools +class _functools._lru_cache_wrapper "PyObject *" "&lru_cache_type_spec" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=bece4053896b09c0]*/ + /* _functools module written and maintained by Hye-Shik Chang with adaptations by Raymond Hettinger @@ -51,13 +59,14 @@ partial_call(partialobject *pto, PyObject *args, PyObject *kwargs); static inline _functools_state * get_functools_state_by_type(PyTypeObject *type) { - PyObject *module = _PyType_GetModuleByDef(type, &_functools_module); + PyObject *module = PyType_GetModuleByDef(type, &_functools_module); if (module == NULL) { return NULL; } return get_functools_state(module); } +// Not converted to argument clinic, because of `*args, **kwargs` arguments. static PyObject * partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) { @@ -97,8 +106,7 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) if (pto == NULL) return NULL; - pto->fn = func; - Py_INCREF(func); + pto->fn = Py_NewRef(func); nargs = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX); if (nargs == NULL) { @@ -123,8 +131,7 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) pto->kw = PyDict_New(); } else if (Py_REFCNT(kw) == 1) { - Py_INCREF(kw); - pto->kw = kw; + pto->kw = Py_NewRef(kw); } else { pto->kw = PyDict_Copy(kw); @@ -282,6 +289,7 @@ partial_setvectorcall(partialobject *pto) } +// Not converted to argument clinic, because of `*args, **kwargs` arguments. static PyObject * partial_call(partialobject *pto, PyObject *args, PyObject *kwargs) { @@ -293,8 +301,7 @@ partial_call(partialobject *pto, PyObject *args, PyObject *kwargs) PyObject *kwargs2; if (PyDict_GET_SIZE(pto->kw) == 0) { /* kwargs can be NULL */ - kwargs2 = kwargs; - Py_XINCREF(kwargs2); + kwargs2 = Py_XNewRef(kwargs); } else { /* bpo-27840, bpo-29318: dictionary of keyword parameters must be @@ -454,8 +461,7 @@ partial_setstate(partialobject *pto, PyObject *state) else Py_INCREF(dict); - Py_INCREF(fn); - Py_SETREF(pto->fn, fn); + Py_SETREF(pto->fn, Py_NewRef(fn)); Py_SETREF(pto->args, fnargs); Py_SETREF(pto->kw, kw); Py_XSETREF(pto->dict, dict); @@ -579,10 +585,8 @@ keyobject_call(keyobject *ko, PyObject *args, PyObject *kwds) if (result == NULL) { return NULL; } - Py_INCREF(ko->cmp); - result->cmp = ko->cmp; - Py_INCREF(object); - result->object = object; + result->cmp = Py_NewRef(ko->cmp); + result->object = Py_NewRef(object); PyObject_GC_Track(result); return (PyObject *)result; } @@ -625,33 +629,36 @@ keyobject_richcompare(PyObject *ko, PyObject *other, int op) return answer; } +/*[clinic input] +_functools.cmp_to_key + + mycmp: object + Function that compares two objects. + +Convert a cmp= function into a key= function. +[clinic start generated code]*/ + static PyObject * -functools_cmp_to_key(PyObject *self, PyObject *args, PyObject *kwds) +_functools_cmp_to_key_impl(PyObject *module, PyObject *mycmp) +/*[clinic end generated code: output=71eaad0f4fc81f33 input=d1b76f231c0dfeb3]*/ { - PyObject *cmp; - static char *kwargs[] = {"mycmp", NULL}; keyobject *object; _functools_state *state; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:cmp_to_key", kwargs, &cmp)) - return NULL; - - state = get_functools_state(self); + state = get_functools_state(module); object = PyObject_GC_New(keyobject, state->keyobject_type); if (!object) return NULL; - Py_INCREF(cmp); - object->cmp = cmp; + object->cmp = Py_NewRef(mycmp); object->object = NULL; PyObject_GC_Track(object); return (PyObject *)object; } -PyDoc_STRVAR(functools_cmp_to_key_doc, -"Convert a cmp= function into a key= function."); - /* reduce (used to be a builtin) ********************************************/ +// Not converted to argument clinic, because of `args` in-place modification. +// AC will affect performance. static PyObject * functools_reduce(PyObject *self, PyObject *args) { @@ -824,12 +831,10 @@ lru_cache_make_key(PyObject *kwd_mark, PyObject *args, if (PyUnicode_CheckExact(key) || PyLong_CheckExact(key)) { /* For common scalar keys, save space by dropping the enclosing args tuple */ - Py_INCREF(key); - return key; + return Py_NewRef(key); } } - Py_INCREF(args); - return args; + return Py_NewRef(args); } key_size = PyTuple_GET_SIZE(args); @@ -845,31 +850,25 @@ lru_cache_make_key(PyObject *kwd_mark, PyObject *args, key_pos = 0; for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) { PyObject *item = PyTuple_GET_ITEM(args, pos); - Py_INCREF(item); - PyTuple_SET_ITEM(key, key_pos++, item); + PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(item)); } if (kwds_size) { - Py_INCREF(kwd_mark); - PyTuple_SET_ITEM(key, key_pos++, kwd_mark); + PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(kwd_mark)); for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) { - Py_INCREF(keyword); - PyTuple_SET_ITEM(key, key_pos++, keyword); - Py_INCREF(value); - PyTuple_SET_ITEM(key, key_pos++, value); + PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(keyword)); + PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(value)); } assert(key_pos == PyTuple_GET_SIZE(args) + kwds_size * 2 + 1); } if (typed) { for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) { PyObject *item = (PyObject *)Py_TYPE(PyTuple_GET_ITEM(args, pos)); - Py_INCREF(item); - PyTuple_SET_ITEM(key, key_pos++, item); + PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(item)); } if (kwds_size) { for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) { PyObject *item = (PyObject *)Py_TYPE(value); - Py_INCREF(item); - PyTuple_SET_ITEM(key, key_pos++, item); + PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(item)); } } } @@ -1071,8 +1070,7 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds return NULL; } lru_cache_append_link(self, link); - Py_INCREF(result); /* for return */ - return result; + return Py_NewRef(result); } /* Since the cache is full, we need to evict an old key and add a new key. Rather than free the old link and allocate a new @@ -1217,16 +1215,12 @@ lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw) obj->wrapper = wrapper; obj->typed = typed; obj->cache = cachedict; - Py_INCREF(func); - obj->func = func; + obj->func = Py_NewRef(func); obj->misses = obj->hits = 0; obj->maxsize = maxsize; - Py_INCREF(state->kwd_mark); - obj->kwd_mark = state->kwd_mark; - Py_INCREF(state->lru_list_elem_type); - obj->lru_list_elem_type = state->lru_list_elem_type; - Py_INCREF(cache_info_type); - obj->cache_info_type = cache_info_type; + obj->kwd_mark = Py_NewRef(state->kwd_mark); + obj->lru_list_elem_type = (PyTypeObject*)Py_NewRef(state->lru_list_elem_type); + obj->cache_info_type = Py_NewRef(cache_info_type); obj->dict = NULL; obj->weakreflist = NULL; return (PyObject *)obj; @@ -1249,8 +1243,7 @@ lru_cache_clear_list(lru_list_elem *link) { while (link != NULL) { lru_list_elem *next = link->next; - Py_DECREF(link); - link = next; + Py_SETREF(link, next); } } @@ -1293,31 +1286,46 @@ static PyObject * lru_cache_descr_get(PyObject *self, PyObject *obj, PyObject *type) { if (obj == Py_None || obj == NULL) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } return PyMethod_New(self, obj); } -static PyObject * -lru_cache_cache_info(lru_cache_object *self, PyObject *unused) -{ - if (self->maxsize == -1) { - return PyObject_CallFunction(self->cache_info_type, "nnOn", - self->hits, self->misses, Py_None, - PyDict_GET_SIZE(self->cache)); - } - return PyObject_CallFunction(self->cache_info_type, "nnnn", - self->hits, self->misses, self->maxsize, - PyDict_GET_SIZE(self->cache)); -} +/*[clinic input] +_functools._lru_cache_wrapper.cache_info + +Report cache statistics +[clinic start generated code]*/ static PyObject * -lru_cache_cache_clear(lru_cache_object *self, PyObject *unused) +_functools__lru_cache_wrapper_cache_info_impl(PyObject *self) +/*[clinic end generated code: output=cc796a0b06dbd717 input=f05e5b6ebfe38645]*/ { - lru_list_elem *list = lru_cache_unlink_list(self); - self->hits = self->misses = 0; - PyDict_Clear(self->cache); + lru_cache_object *_self = (lru_cache_object *) self; + if (_self->maxsize == -1) { + return PyObject_CallFunction(_self->cache_info_type, "nnOn", + _self->hits, _self->misses, Py_None, + PyDict_GET_SIZE(_self->cache)); + } + return PyObject_CallFunction(_self->cache_info_type, "nnnn", + _self->hits, _self->misses, _self->maxsize, + PyDict_GET_SIZE(_self->cache)); +} + +/*[clinic input] +_functools._lru_cache_wrapper.cache_clear + +Clear the cache and cache statistics +[clinic start generated code]*/ + +static PyObject * +_functools__lru_cache_wrapper_cache_clear_impl(PyObject *self) +/*[clinic end generated code: output=58423b35efc3e381 input=6ca59dba09b12584]*/ +{ + lru_cache_object *_self = (lru_cache_object *) self; + lru_list_elem *list = lru_cache_unlink_list(_self); + _self->hits = _self->misses = 0; + PyDict_Clear(_self->cache); lru_cache_clear_list(list); Py_RETURN_NONE; } @@ -1331,15 +1339,13 @@ lru_cache_reduce(PyObject *self, PyObject *unused) static PyObject * lru_cache_copy(PyObject *self, PyObject *unused) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * lru_cache_deepcopy(PyObject *self, PyObject *unused) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static int @@ -1381,8 +1387,8 @@ cache_info_type: namedtuple class with the fields:\n\ ); static PyMethodDef lru_cache_methods[] = { - {"cache_info", (PyCFunction)lru_cache_cache_info, METH_NOARGS}, - {"cache_clear", (PyCFunction)lru_cache_cache_clear, METH_NOARGS}, + _FUNCTOOLS__LRU_CACHE_WRAPPER_CACHE_INFO_METHODDEF + _FUNCTOOLS__LRU_CACHE_WRAPPER_CACHE_CLEAR_METHODDEF {"__reduce__", (PyCFunction)lru_cache_reduce, METH_NOARGS}, {"__copy__", (PyCFunction)lru_cache_copy, METH_VARARGS}, {"__deepcopy__", (PyCFunction)lru_cache_deepcopy, METH_VARARGS}, @@ -1432,8 +1438,7 @@ PyDoc_STRVAR(_functools_doc, static PyMethodDef _functools_methods[] = { {"reduce", functools_reduce, METH_VARARGS, functools_reduce_doc}, - {"cmp_to_key", (PyCFunction)(void(*)(void))functools_cmp_to_key, - METH_VARARGS | METH_KEYWORDS, functools_cmp_to_key_doc}, + _FUNCTOOLS_CMP_TO_KEY_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -1471,9 +1476,8 @@ _functools_exec(PyObject *module) if (state->keyobject_type == NULL) { return -1; } - if (PyModule_AddType(module, state->keyobject_type) < 0) { - return -1; - } + // keyobject_type is used only internally. + // So we don't expose it in module namespace. state->lru_list_elem_type = (PyTypeObject *)PyType_FromModuleAndSpec( module, &lru_list_elem_type_spec, NULL); diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index 445500c7ee4..4e8acdefc72 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -162,6 +162,35 @@ gdbm_length(gdbmobject *dp) return dp->di_size; } +static int +gdbm_bool(gdbmobject *dp) +{ + _gdbm_state *state = PyType_GetModuleState(Py_TYPE(dp)); + if (dp->di_dbm == NULL) { + PyErr_SetString(state->gdbm_error, "GDBM object has already been closed"); + return -1; + } + if (dp->di_size > 0) { + /* Known non-zero size. */ + return 1; + } + if (dp->di_size == 0) { + /* Known zero size. */ + return 0; + } + /* Unknown size. Ensure DBM object has an entry. */ + datum key = gdbm_firstkey(dp->di_dbm); + if (key.dptr == NULL) { + /* Empty. Cache this fact. */ + dp->di_size = 0; + return 0; + } + + /* Non-empty. Don't cache the length since we don't know. */ + free(key.dptr); + return 1; +} + // Wrapper function for PyArg_Parse(o, "s#", &d.dptr, &d.size). // This function is needed to support PY_SSIZE_T_CLEAN. // Return 1 on success, same to PyArg_Parse(). @@ -227,8 +256,7 @@ _gdbm_gdbm_get_impl(gdbmobject *self, PyObject *key, PyObject *default_value) res = gdbm_subscript(self, key); if (res == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) { PyErr_Clear(); - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } return res; } @@ -537,15 +565,13 @@ _gdbm_gdbm_sync_impl(gdbmobject *self, PyTypeObject *cls) static PyObject * gdbm__enter__(PyObject *self, PyObject *args) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * gdbm__exit__(PyObject *self, PyObject *args) { - _Py_IDENTIFIER(close); - return _PyObject_CallMethodIdNoArgs(self, &PyId_close); + return _gdbm_gdbm_close_impl((gdbmobject *)self); } static PyMethodDef gdbm_methods[] = { @@ -570,6 +596,7 @@ static PyType_Slot gdbmtype_spec_slots[] = { {Py_mp_length, gdbm_length}, {Py_mp_subscript, gdbm_subscript}, {Py_mp_ass_subscript, gdbm_ass_sub}, + {Py_nb_bool, gdbm_bool}, {Py_tp_doc, (char*)gdbm_object__doc__}, {0, 0} }; @@ -648,7 +675,6 @@ dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, return NULL; } for (flags++; *flags != '\0'; flags++) { - char buf[40]; switch (*flags) { #ifdef GDBM_FAST case 'f': @@ -666,9 +692,8 @@ dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, break; #endif default: - PyOS_snprintf(buf, sizeof(buf), "Flag '%c' is not supported.", - *flags); - PyErr_SetString(state->gdbm_error, buf); + PyErr_Format(state->gdbm_error, + "Flag '%c' is not supported.", (unsigned char)*flags); return NULL; } } diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 12491917832..82398547f9b 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -25,6 +25,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_hashtable.h" #include "hashlib.h" #include "pycore_strhex.h" // _Py_strhex() @@ -49,6 +50,160 @@ #define PY_OPENSSL_HAS_SHAKE 1 #define PY_OPENSSL_HAS_BLAKE2 1 +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#define PY_EVP_MD EVP_MD +#define PY_EVP_MD_fetch(algorithm, properties) EVP_MD_fetch(NULL, algorithm, properties) +#define PY_EVP_MD_up_ref(md) EVP_MD_up_ref(md) +#define PY_EVP_MD_free(md) EVP_MD_free(md) +#else +#define PY_EVP_MD const EVP_MD +#define PY_EVP_MD_fetch(algorithm, properties) EVP_get_digestbyname(algorithm) +#define PY_EVP_MD_up_ref(md) do {} while(0) +#define PY_EVP_MD_free(md) do {} while(0) +#endif + +/* hash alias map and fast lookup + * + * Map between Python's preferred names and OpenSSL internal names. Maintain + * cache of fetched EVP MD objects. The EVP_get_digestbyname() and + * EVP_MD_fetch() API calls have a performance impact. + * + * The py_hashentry_t items are stored in a _Py_hashtable_t with py_name and + * py_alias as keys. + */ + +enum Py_hash_type { + Py_ht_evp, // usedforsecurity=True / default + Py_ht_evp_nosecurity, // usedforsecurity=False + Py_ht_mac, // HMAC + Py_ht_pbkdf2, // PKBDF2 +}; + +typedef struct { + const char *py_name; + const char *py_alias; + const char *ossl_name; + int ossl_nid; + int refcnt; + PY_EVP_MD *evp; + PY_EVP_MD *evp_nosecurity; +} py_hashentry_t; + +#define Py_hash_md5 "md5" +#define Py_hash_sha1 "sha1" +#define Py_hash_sha224 "sha224" +#define Py_hash_sha256 "sha256" +#define Py_hash_sha384 "sha384" +#define Py_hash_sha512 "sha512" +#define Py_hash_sha512_224 "sha512_224" +#define Py_hash_sha512_256 "sha512_256" +#define Py_hash_sha3_224 "sha3_224" +#define Py_hash_sha3_256 "sha3_256" +#define Py_hash_sha3_384 "sha3_384" +#define Py_hash_sha3_512 "sha3_512" +#define Py_hash_shake_128 "shake_128" +#define Py_hash_shake_256 "shake_256" +#define Py_hash_blake2s "blake2s" +#define Py_hash_blake2b "blake2b" + +#define PY_HASH_ENTRY(py_name, py_alias, ossl_name, ossl_nid) \ + {py_name, py_alias, ossl_name, ossl_nid, 0, NULL, NULL} + +static const py_hashentry_t py_hashes[] = { + /* md5 */ + PY_HASH_ENTRY(Py_hash_md5, "MD5", SN_md5, NID_md5), + /* sha1 */ + PY_HASH_ENTRY(Py_hash_sha1, "SHA1", SN_sha1, NID_sha1), + /* sha2 family */ + PY_HASH_ENTRY(Py_hash_sha224, "SHA224", SN_sha224, NID_sha224), + PY_HASH_ENTRY(Py_hash_sha256, "SHA256", SN_sha256, NID_sha256), + PY_HASH_ENTRY(Py_hash_sha384, "SHA384", SN_sha384, NID_sha384), + PY_HASH_ENTRY(Py_hash_sha512, "SHA512", SN_sha512, NID_sha512), + /* truncated sha2 */ + PY_HASH_ENTRY(Py_hash_sha512_224, "SHA512_224", SN_sha512_224, NID_sha512_224), + PY_HASH_ENTRY(Py_hash_sha512_256, "SHA512_256", SN_sha512_256, NID_sha512_256), + /* sha3 */ + PY_HASH_ENTRY(Py_hash_sha3_224, NULL, SN_sha3_224, NID_sha3_224), + PY_HASH_ENTRY(Py_hash_sha3_256, NULL, SN_sha3_256, NID_sha3_256), + PY_HASH_ENTRY(Py_hash_sha3_384, NULL, SN_sha3_384, NID_sha3_384), + PY_HASH_ENTRY(Py_hash_sha3_512, NULL, SN_sha3_512, NID_sha3_512), + /* sha3 shake */ + PY_HASH_ENTRY(Py_hash_shake_128, NULL, SN_shake128, NID_shake128), + PY_HASH_ENTRY(Py_hash_shake_256, NULL, SN_shake256, NID_shake256), + /* blake2 digest */ + PY_HASH_ENTRY(Py_hash_blake2s, "blake2s256", SN_blake2s256, NID_blake2s256), + PY_HASH_ENTRY(Py_hash_blake2b, "blake2b512", SN_blake2b512, NID_blake2b512), + PY_HASH_ENTRY(NULL, NULL, NULL, 0), +}; + +static Py_uhash_t +py_hashentry_t_hash_name(const void *key) { + return _Py_HashBytes(key, strlen((const char *)key)); +} + +static int +py_hashentry_t_compare_name(const void *key1, const void *key2) { + return strcmp((const char *)key1, (const char *)key2) == 0; +} + +static void +py_hashentry_t_destroy_value(void *entry) { + py_hashentry_t *h = (py_hashentry_t *)entry; + if (--(h->refcnt) == 0) { + if (h->evp != NULL) { + PY_EVP_MD_free(h->evp); + h->evp = NULL; + } + if (h->evp_nosecurity != NULL) { + PY_EVP_MD_free(h->evp_nosecurity); + h->evp_nosecurity = NULL; + } + PyMem_Free(entry); + } +} + +static _Py_hashtable_t * +py_hashentry_table_new(void) { + _Py_hashtable_t *ht = _Py_hashtable_new_full( + py_hashentry_t_hash_name, + py_hashentry_t_compare_name, + NULL, + py_hashentry_t_destroy_value, + NULL + ); + if (ht == NULL) { + return NULL; + } + + for (const py_hashentry_t *h = py_hashes; h->py_name != NULL; h++) { + py_hashentry_t *entry = (py_hashentry_t *)PyMem_Malloc(sizeof(py_hashentry_t)); + if (entry == NULL) { + goto error; + } + memcpy(entry, h, sizeof(py_hashentry_t)); + + if (_Py_hashtable_set(ht, (const void*)entry->py_name, (void*)entry) < 0) { + PyMem_Free(entry); + goto error; + } + entry->refcnt = 1; + + if (h->py_alias != NULL) { + if (_Py_hashtable_set(ht, (const void*)entry->py_alias, (void*)entry) < 0) { + PyMem_Free(entry); + goto error; + } + entry->refcnt++; + } + } + + return ht; + error: + _Py_hashtable_destroy(ht); + return NULL; +} + +/* Module state */ static PyModuleDef _hashlibmodule; typedef struct { @@ -59,6 +214,7 @@ typedef struct { #endif PyObject *constructs; PyObject *unsupported_digestmod_error; + _Py_hashtable_t *hashtable; } _hashlibstate; static inline _hashlibstate* @@ -93,16 +249,23 @@ class _hashlib.HMAC "HMACobject *" "((_hashlibstate *)PyModule_GetState(module)) /* LCOV_EXCL_START */ static PyObject * -_setException(PyObject *exc) +_setException(PyObject *exc, const char* altmsg, ...) { - unsigned long errcode; + unsigned long errcode = ERR_peek_last_error(); const char *lib, *func, *reason; + va_list vargs; - errcode = ERR_peek_last_error(); + va_start(vargs, altmsg); if (!errcode) { - PyErr_SetString(exc, "unknown reasons"); + if (altmsg == NULL) { + PyErr_SetString(exc, "no reason supplied"); + } else { + PyErr_FormatV(exc, altmsg, vargs); + } + va_end(vargs); return NULL; } + va_end(vargs); ERR_clear_error(); lib = ERR_lib_error_string(errcode); @@ -127,68 +290,15 @@ py_digest_name(const EVP_MD *md) { int nid = EVP_MD_nid(md); const char *name = NULL; + const py_hashentry_t *h; - /* Hard-coded names for well-known hashing algorithms. - * OpenSSL uses slightly different names algorithms like SHA3. - */ - switch (nid) { - case NID_md5: - name = "md5"; - break; - case NID_sha1: - name = "sha1"; - break; - case NID_sha224: - name ="sha224"; - break; - case NID_sha256: - name ="sha256"; - break; - case NID_sha384: - name ="sha384"; - break; - case NID_sha512: - name ="sha512"; - break; -#ifdef NID_sha512_224 - case NID_sha512_224: - name ="sha512_224"; - break; - case NID_sha512_256: - name ="sha512_256"; - break; -#endif -#ifdef PY_OPENSSL_HAS_SHA3 - case NID_sha3_224: - name ="sha3_224"; - break; - case NID_sha3_256: - name ="sha3_256"; - break; - case NID_sha3_384: - name ="sha3_384"; - break; - case NID_sha3_512: - name ="sha3_512"; - break; -#endif -#ifdef PY_OPENSSL_HAS_SHAKE - case NID_shake128: - name ="shake_128"; - break; - case NID_shake256: - name ="shake_256"; - break; -#endif -#ifdef PY_OPENSSL_HAS_BLAKE2 - case NID_blake2s256: - name ="blake2s"; - break; - case NID_blake2b512: - name ="blake2b"; - break; -#endif - default: + for (h = py_hashes; h->py_name != NULL; h++) { + if (h->ossl_nid == nid) { + name = h->py_name; + break; + } + } + if (name == NULL) { /* Ignore aliased names and only use long, lowercase name. The aliases * pollute the list and OpenSSL appears to have its own definition of * alias as the resulting list still contains duplicate and alternate @@ -197,67 +307,58 @@ py_digest_name(const EVP_MD *md) name = OBJ_nid2ln(nid); if (name == NULL) name = OBJ_nid2sn(nid); - break; } return PyUnicode_FromString(name); } -static const EVP_MD* -py_digest_by_name(const char *name) +/* Get EVP_MD by HID and purpose */ +static PY_EVP_MD* +py_digest_by_name(PyObject *module, const char *name, enum Py_hash_type py_ht) { - const EVP_MD *digest = EVP_get_digestbyname(name); + PY_EVP_MD *digest = NULL; + _hashlibstate *state = get_hashlib_state(module); + py_hashentry_t *entry = (py_hashentry_t *)_Py_hashtable_get( + state->hashtable, (const void*)name + ); - /* OpenSSL uses dash instead of underscore in names of some algorithms - * like SHA3 and SHAKE. Detect different spellings. */ - if (digest == NULL) { - if (0) {} -#ifdef NID_sha512_224 - else if (!strcmp(name, "sha512_224") || !strcmp(name, "SHA512_224")) { - digest = EVP_sha512_224(); + if (entry != NULL) { + switch (py_ht) { + case Py_ht_evp: + case Py_ht_mac: + case Py_ht_pbkdf2: + if (entry->evp == NULL) { + entry->evp = PY_EVP_MD_fetch(entry->ossl_name, NULL); + } + digest = entry->evp; + break; + case Py_ht_evp_nosecurity: + if (entry->evp_nosecurity == NULL) { + entry->evp_nosecurity = PY_EVP_MD_fetch(entry->ossl_name, "-fips"); + } + digest = entry->evp_nosecurity; + break; } - else if (!strcmp(name, "sha512_256") || !strcmp(name, "SHA512_256")) { - digest = EVP_sha512_256(); + if (digest != NULL) { + PY_EVP_MD_up_ref(digest); } -#endif -#ifdef PY_OPENSSL_HAS_SHA3 - /* could be sha3_ or shake_, Python never defined upper case */ - else if (!strcmp(name, "sha3_224")) { - digest = EVP_sha3_224(); + } else { + // Fall back for looking up an unindexed OpenSSL specific name. + switch (py_ht) { + case Py_ht_evp: + case Py_ht_mac: + case Py_ht_pbkdf2: + digest = PY_EVP_MD_fetch(name, NULL); + break; + case Py_ht_evp_nosecurity: + digest = PY_EVP_MD_fetch(name, "-fips"); + break; } - else if (!strcmp(name, "sha3_256")) { - digest = EVP_sha3_256(); - } - else if (!strcmp(name, "sha3_384")) { - digest = EVP_sha3_384(); - } - else if (!strcmp(name, "sha3_512")) { - digest = EVP_sha3_512(); - } -#endif -#ifdef PY_OPENSSL_HAS_SHAKE - else if (!strcmp(name, "shake_128")) { - digest = EVP_shake128(); - } - else if (!strcmp(name, "shake_256")) { - digest = EVP_shake256(); - } -#endif -#ifdef PY_OPENSSL_HAS_BLAKE2 - else if (!strcmp(name, "blake2s256")) { - digest = EVP_blake2s256(); - } - else if (!strcmp(name, "blake2b512")) { - digest = EVP_blake2b512(); - } -#endif } - if (digest == NULL) { - PyErr_Format(PyExc_ValueError, "unsupported hash type %s", name); + _setException(PyExc_ValueError, "unsupported hash type %s", name); return NULL; } - return digest; } @@ -268,9 +369,9 @@ py_digest_by_name(const char *name) * * on error returns NULL with exception set. */ -static const EVP_MD* -py_digest_by_digestmod(PyObject *module, PyObject *digestmod) { - const EVP_MD* evp; +static PY_EVP_MD* +py_digest_by_digestmod(PyObject *module, PyObject *digestmod, enum Py_hash_type py_ht) { + PY_EVP_MD* evp; PyObject *name_obj = NULL; const char *name; @@ -295,7 +396,7 @@ py_digest_by_digestmod(PyObject *module, PyObject *digestmod) { return NULL; } - evp = py_digest_by_name(name); + evp = py_digest_by_name(module, name, py_ht); if (evp == NULL) { return NULL; } @@ -334,7 +435,7 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len) else process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int); if (!EVP_DigestUpdate(self->ctx, (const void*)cp, process)) { - _setException(PyExc_ValueError); + _setException(PyExc_ValueError, NULL); return -1; } len -= process; @@ -385,7 +486,7 @@ EVP_copy_impl(EVPobject *self) if (!locked_EVP_MD_CTX_copy(newobj->ctx, self)) { Py_DECREF(newobj); - return _setException(PyExc_ValueError); + return _setException(PyExc_ValueError, NULL); } return (PyObject *)newobj; } @@ -412,11 +513,11 @@ EVP_digest_impl(EVPobject *self) } if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { - return _setException(PyExc_ValueError); + return _setException(PyExc_ValueError, NULL); } digest_size = EVP_MD_CTX_size(temp_ctx); if (!EVP_DigestFinal(temp_ctx, digest, NULL)) { - _setException(PyExc_ValueError); + _setException(PyExc_ValueError, NULL); return NULL; } @@ -447,11 +548,11 @@ EVP_hexdigest_impl(EVPobject *self) /* Get the raw (binary) digest value */ if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { - return _setException(PyExc_ValueError); + return _setException(PyExc_ValueError, NULL); } digest_size = EVP_MD_CTX_size(temp_ctx); if (!EVP_DigestFinal(temp_ctx, digest, NULL)) { - _setException(PyExc_ValueError); + _setException(PyExc_ValueError, NULL); return NULL; } @@ -627,14 +728,14 @@ EVPXOF_digest_impl(EVPobject *self, Py_ssize_t length) if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { Py_DECREF(retval); EVP_MD_CTX_free(temp_ctx); - return _setException(PyExc_ValueError); + return _setException(PyExc_ValueError, NULL); } if (!EVP_DigestFinalXOF(temp_ctx, (unsigned char*)PyBytes_AS_STRING(retval), length)) { Py_DECREF(retval); EVP_MD_CTX_free(temp_ctx); - _setException(PyExc_ValueError); + _setException(PyExc_ValueError, NULL); return NULL; } @@ -675,12 +776,12 @@ EVPXOF_hexdigest_impl(EVPobject *self, Py_ssize_t length) if (!locked_EVP_MD_CTX_copy(temp_ctx, self)) { PyMem_Free(digest); EVP_MD_CTX_free(temp_ctx); - return _setException(PyExc_ValueError); + return _setException(PyExc_ValueError, NULL); } if (!EVP_DigestFinalXOF(temp_ctx, digest, length)) { PyMem_Free(digest); EVP_MD_CTX_free(temp_ctx); - _setException(PyExc_ValueError); + _setException(PyExc_ValueError, NULL); return NULL; } @@ -748,55 +849,74 @@ static PyType_Spec EVPXOFtype_spec = { #endif -static PyObject * -EVPnew(PyObject *module, const EVP_MD *digest, - const unsigned char *cp, Py_ssize_t len, int usedforsecurity) +static PyObject* +py_evp_fromname(PyObject *module, const char *digestname, PyObject *data_obj, + int usedforsecurity) { - int result = 0; - EVPobject *self; - PyTypeObject *type = get_hashlib_state(module)->EVPtype; + Py_buffer view = { 0 }; + PY_EVP_MD *digest = NULL; + PyTypeObject *type; + EVPobject *self = NULL; - if (!digest) { - PyErr_SetString(PyExc_ValueError, "unsupported hash type"); - return NULL; + if (data_obj != NULL) { + GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); + } + + digest = py_digest_by_name( + module, digestname, usedforsecurity ? Py_ht_evp : Py_ht_evp_nosecurity + ); + if (digest == NULL) { + goto exit; } -#ifdef PY_OPENSSL_HAS_SHAKE if ((EVP_MD_flags(digest) & EVP_MD_FLAG_XOF) == EVP_MD_FLAG_XOF) { type = get_hashlib_state(module)->EVPXOFtype; + } else { + type = get_hashlib_state(module)->EVPtype; } -#endif - if ((self = newEVPobject(type)) == NULL) - return NULL; + self = newEVPobject(type); + if (self == NULL) { + goto exit; + } +#if defined(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) && OPENSSL_VERSION_NUMBER < 0x30000000L + // In OpenSSL 1.1.1 the non FIPS allowed flag is context specific while + // in 3.0.0 it is a different EVP_MD provider. if (!usedforsecurity) { -#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW EVP_MD_CTX_set_flags(self->ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + } #endif + + int result = EVP_DigestInit_ex(self->ctx, digest, NULL); + if (!result) { + _setException(PyExc_ValueError, NULL); + Py_CLEAR(self); + goto exit; } - - if (!EVP_DigestInit_ex(self->ctx, digest, NULL)) { - _setException(PyExc_ValueError); - Py_DECREF(self); - return NULL; - } - - if (cp && len) { - if (len >= HASHLIB_GIL_MINSIZE) { + if (view.buf && view.len) { + if (view.len >= HASHLIB_GIL_MINSIZE) { Py_BEGIN_ALLOW_THREADS - result = EVP_hash(self, cp, len); + result = EVP_hash(self, view.buf, view.len); Py_END_ALLOW_THREADS } else { - result = EVP_hash(self, cp, len); + result = EVP_hash(self, view.buf, view.len); } if (result == -1) { - Py_DECREF(self); - return NULL; + Py_CLEAR(self); + goto exit; } } + exit: + if (data_obj != NULL) { + PyBuffer_Release(&view); + } + if (digest != NULL) { + PY_EVP_MD_free(digest); + } + return (PyObject *)self; } @@ -824,53 +944,14 @@ EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=ddd5053f92dffe90 input=c24554d0337be1b0]*/ { - Py_buffer view = { 0 }; - PyObject *ret_obj = NULL; char *name; - const EVP_MD *digest = NULL; - if (!PyArg_Parse(name_obj, "s", &name)) { PyErr_SetString(PyExc_TypeError, "name must be a string"); return NULL; } - - if (data_obj) - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); - - digest = py_digest_by_name(name); - if (digest == NULL) { - goto exit; - } - - ret_obj = EVPnew(module, digest, - (unsigned char*)view.buf, view.len, - usedforsecurity); - -exit: - if (data_obj) - PyBuffer_Release(&view); - return ret_obj; + return py_evp_fromname(module, name, data_obj, usedforsecurity); } -static PyObject* -EVP_fast_new(PyObject *module, PyObject *data_obj, const EVP_MD *digest, - int usedforsecurity) -{ - Py_buffer view = { 0 }; - PyObject *ret_obj; - - if (data_obj) - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); - - ret_obj = EVPnew(module, digest, - (unsigned char*)view.buf, view.len, - usedforsecurity); - - if (data_obj) - PyBuffer_Release(&view); - - return ret_obj; -} /*[clinic input] _hashlib.openssl_md5 @@ -888,7 +969,7 @@ _hashlib_openssl_md5_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=87b0186440a44f8c input=990e36d5e689b16e]*/ { - return EVP_fast_new(module, data_obj, EVP_md5(), usedforsecurity); + return py_evp_fromname(module, Py_hash_md5, data_obj, usedforsecurity); } @@ -908,7 +989,7 @@ _hashlib_openssl_sha1_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=6813024cf690670d input=948f2f4b6deabc10]*/ { - return EVP_fast_new(module, data_obj, EVP_sha1(), usedforsecurity); + return py_evp_fromname(module, Py_hash_sha1, data_obj, usedforsecurity); } @@ -928,7 +1009,7 @@ _hashlib_openssl_sha224_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=a2dfe7cc4eb14ebb input=f9272821fadca505]*/ { - return EVP_fast_new(module, data_obj, EVP_sha224(), usedforsecurity); + return py_evp_fromname(module, Py_hash_sha224, data_obj, usedforsecurity); } @@ -948,7 +1029,7 @@ _hashlib_openssl_sha256_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=1f874a34870f0a68 input=549fad9d2930d4c5]*/ { - return EVP_fast_new(module, data_obj, EVP_sha256(), usedforsecurity); + return py_evp_fromname(module, Py_hash_sha256, data_obj, usedforsecurity); } @@ -968,7 +1049,7 @@ _hashlib_openssl_sha384_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=58529eff9ca457b2 input=48601a6e3bf14ad7]*/ { - return EVP_fast_new(module, data_obj, EVP_sha384(), usedforsecurity); + return py_evp_fromname(module, Py_hash_sha384, data_obj, usedforsecurity); } @@ -988,7 +1069,7 @@ _hashlib_openssl_sha512_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=2c744c9e4a40d5f6 input=c5c46a2a817aa98f]*/ { - return EVP_fast_new(module, data_obj, EVP_sha512(), usedforsecurity); + return py_evp_fromname(module, Py_hash_sha512, data_obj, usedforsecurity); } @@ -1010,7 +1091,7 @@ _hashlib_openssl_sha3_224_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=144641c1d144b974 input=e3a01b2888916157]*/ { - return EVP_fast_new(module, data_obj, EVP_sha3_224(), usedforsecurity); + return py_evp_fromname(module, Py_hash_sha3_224, data_obj, usedforsecurity); } /*[clinic input] @@ -1029,7 +1110,7 @@ _hashlib_openssl_sha3_256_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=c61f1ab772d06668 input=e2908126c1b6deed]*/ { - return EVP_fast_new(module, data_obj, EVP_sha3_256(), usedforsecurity); + return py_evp_fromname(module, Py_hash_sha3_256, data_obj , usedforsecurity); } /*[clinic input] @@ -1048,7 +1129,7 @@ _hashlib_openssl_sha3_384_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=f68e4846858cf0ee input=ec0edf5c792f8252]*/ { - return EVP_fast_new(module, data_obj, EVP_sha3_384(), usedforsecurity); + return py_evp_fromname(module, Py_hash_sha3_384, data_obj , usedforsecurity); } /*[clinic input] @@ -1067,7 +1148,7 @@ _hashlib_openssl_sha3_512_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=2eede478c159354a input=64e2cc0c094d56f4]*/ { - return EVP_fast_new(module, data_obj, EVP_sha3_512(), usedforsecurity); + return py_evp_fromname(module, Py_hash_sha3_512, data_obj , usedforsecurity); } #endif /* PY_OPENSSL_HAS_SHA3 */ @@ -1088,7 +1169,7 @@ _hashlib_openssl_shake_128_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=bc49cdd8ada1fa97 input=6c9d67440eb33ec8]*/ { - return EVP_fast_new(module, data_obj, EVP_shake128(), usedforsecurity); + return py_evp_fromname(module, Py_hash_shake_128, data_obj , usedforsecurity); } /*[clinic input] @@ -1107,7 +1188,7 @@ _hashlib_openssl_shake_256_impl(PyObject *module, PyObject *data_obj, int usedforsecurity) /*[clinic end generated code: output=358d213be8852df7 input=479cbe9fefd4a9f8]*/ { - return EVP_fast_new(module, data_obj, EVP_shake256(), usedforsecurity); + return py_evp_fromname(module, Py_hash_shake_256, data_obj , usedforsecurity); } #endif /* PY_OPENSSL_HAS_SHAKE */ @@ -1133,9 +1214,8 @@ pbkdf2_hmac_impl(PyObject *module, const char *hash_name, char *key; long dklen; int retval; - const EVP_MD *digest; - digest = py_digest_by_name(hash_name); + PY_EVP_MD *digest = py_digest_by_name(module, hash_name, Py_ht_pbkdf2); if (digest == NULL) { goto end; } @@ -1198,11 +1278,14 @@ pbkdf2_hmac_impl(PyObject *module, const char *hash_name, if (!retval) { Py_CLEAR(key_obj); - _setException(PyExc_ValueError); + _setException(PyExc_ValueError, NULL); goto end; } end: + if (digest != NULL) { + PY_EVP_MD_free(digest); + } return key_obj; } @@ -1301,9 +1384,7 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt, /* let OpenSSL validate the rest */ retval = EVP_PBE_scrypt(NULL, 0, NULL, 0, n, r, p, maxmem, NULL, 0); if (!retval) { - /* sorry, can't do much better */ - PyErr_SetString(PyExc_ValueError, - "Invalid parameter combination for n, r, p, maxmem."); + _setException(PyExc_ValueError, "Invalid parameter combination for n, r, p, maxmem."); return NULL; } @@ -1324,7 +1405,7 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt, if (!retval) { Py_CLEAR(key_obj); - _setException(PyExc_ValueError); + _setException(PyExc_ValueError, NULL); return NULL; } return key_obj; @@ -1352,12 +1433,7 @@ _hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key, unsigned char md[EVP_MAX_MD_SIZE] = {0}; unsigned int md_len = 0; unsigned char *result; - const EVP_MD *evp; - - evp = py_digest_by_digestmod(module, digest); - if (evp == NULL) { - return NULL; - } + PY_EVP_MD *evp; if (key->len > INT_MAX) { PyErr_SetString(PyExc_OverflowError, @@ -1370,6 +1446,11 @@ _hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key, return NULL; } + evp = py_digest_by_digestmod(module, digest, Py_ht_mac); + if (evp == NULL) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS result = HMAC( evp, @@ -1378,9 +1459,10 @@ _hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key, md, &md_len ); Py_END_ALLOW_THREADS + PY_EVP_MD_free(evp); if (result == NULL) { - _setException(PyExc_ValueError); + _setException(PyExc_ValueError, NULL); return NULL; } return PyBytes_FromStringAndSize((const char*)md, md_len); @@ -1407,7 +1489,7 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj, /*[clinic end generated code: output=c20d9e4d9ed6d219 input=5f4071dcc7f34362]*/ { PyTypeObject *type = get_hashlib_state(module)->HMACtype; - const EVP_MD *digest; + PY_EVP_MD *digest; HMAC_CTX *ctx = NULL; HMACobject *self = NULL; int r; @@ -1424,14 +1506,14 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj, return NULL; } - digest = py_digest_by_digestmod(module, digestmod); + digest = py_digest_by_digestmod(module, digestmod, Py_ht_mac); if (digest == NULL) { return NULL; } ctx = HMAC_CTX_new(); if (ctx == NULL) { - _setException(PyExc_ValueError); + _setException(PyExc_ValueError, NULL); goto error; } @@ -1441,8 +1523,9 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj, (int)key->len, digest, NULL /*impl*/); + PY_EVP_MD_free(digest); if (r == 0) { - _setException(PyExc_ValueError); + _setException(PyExc_ValueError, NULL); goto error; } @@ -1512,7 +1595,7 @@ _hmac_update(HMACobject *self, PyObject *obj) PyBuffer_Release(&view); if (r == 0) { - _setException(PyExc_ValueError); + _setException(PyExc_ValueError, NULL); return 0; } return 1; @@ -1532,11 +1615,11 @@ _hashlib_HMAC_copy_impl(HMACobject *self) HMAC_CTX *ctx = HMAC_CTX_new(); if (ctx == NULL) { - return _setException(PyExc_ValueError); + return _setException(PyExc_ValueError, NULL); } if (!locked_HMAC_CTX_copy(ctx, self)) { HMAC_CTX_free(ctx); - return _setException(PyExc_ValueError); + return _setException(PyExc_ValueError, NULL); } retval = (HMACobject *)PyObject_New(HMACobject, Py_TYPE(self)); @@ -1602,13 +1685,13 @@ _hmac_digest(HMACobject *self, unsigned char *buf, unsigned int len) return 0; } if (!locked_HMAC_CTX_copy(temp_ctx, self)) { - _setException(PyExc_ValueError); + _setException(PyExc_ValueError, NULL); return 0; } int r = HMAC_Final(temp_ctx, buf, &len); HMAC_CTX_free(temp_ctx); if (r == 0) { - _setException(PyExc_ValueError); + _setException(PyExc_ValueError, NULL); return 0; } return 1; @@ -1626,7 +1709,7 @@ _hashlib_HMAC_digest_impl(HMACobject *self) unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int digest_size = _hmac_digest_size(self); if (digest_size == 0) { - return _setException(PyExc_ValueError); + return _setException(PyExc_ValueError, NULL); } int r = _hmac_digest(self, digest, digest_size); if (r == 0) { @@ -1651,7 +1734,7 @@ _hashlib_HMAC_hexdigest_impl(HMACobject *self) unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int digest_size = _hmac_digest_size(self); if (digest_size == 0) { - return _setException(PyExc_ValueError); + return _setException(PyExc_ValueError, NULL); } int r = _hmac_digest(self, digest, digest_size); if (r == 0) { @@ -1665,7 +1748,7 @@ _hashlib_hmac_get_digest_size(HMACobject *self, void *closure) { unsigned int digest_size = _hmac_digest_size(self); if (digest_size == 0) { - return _setException(PyExc_ValueError); + return _setException(PyExc_ValueError, NULL); } return PyLong_FromLong(digest_size); } @@ -1675,7 +1758,7 @@ _hashlib_hmac_get_block_size(HMACobject *self, void *closure) { const EVP_MD *md = HMAC_CTX_get_md(self->ctx); if (md == NULL) { - return _setException(PyExc_ValueError); + return _setException(PyExc_ValueError, NULL); } return PyLong_FromLong(EVP_MD_block_size(md)); } @@ -1749,15 +1832,21 @@ typedef struct _internal_name_mapper_state { /* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */ static void +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +_openssl_hash_name_mapper(EVP_MD *md, void *arg) +#else _openssl_hash_name_mapper(const EVP_MD *md, const char *from, const char *to, void *arg) +#endif { _InternalNameMapperState *state = (_InternalNameMapperState *)arg; PyObject *py_name; assert(state != NULL); - if (md == NULL) + // ignore all undefined providers + if ((md == NULL) || (EVP_MD_nid(md) == NID_undef)) { return; + } py_name = py_digest_name(md); if (py_name == NULL) { @@ -1783,7 +1872,12 @@ hashlib_md_meth_names(PyObject *module) return -1; } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + // get algorithms from all activated providers in default context + EVP_MD_do_all_provided(NULL, &_openssl_hash_name_mapper, &state); +#else EVP_MD_do_all(&_openssl_hash_name_mapper, &state); +#endif if (state.error) { Py_DECREF(state.set); @@ -1828,7 +1922,7 @@ _hashlib_get_fips_mode_impl(PyObject *module) // But 0 is also a valid result value. unsigned long errcode = ERR_peek_last_error(); if (errcode) { - _setException(PyExc_ValueError); + _setException(PyExc_ValueError, NULL); return -1; } } @@ -1904,7 +1998,7 @@ _hashlib_compare_digest_impl(PyObject *module, PyObject *a, PyObject *b) PyUnicode_GET_LENGTH(a), PyUnicode_GET_LENGTH(b)); } - /* fallback to buffer interface for bytes, bytesarray and other */ + /* fallback to buffer interface for bytes, bytearray and other */ else { Py_buffer view_a; Py_buffer view_b; @@ -2004,6 +2098,12 @@ hashlib_clear(PyObject *m) #endif Py_CLEAR(state->constructs); Py_CLEAR(state->unsupported_digestmod_error); + + if (state->hashtable != NULL) { + _Py_hashtable_destroy(state->hashtable); + state->hashtable = NULL; + } + return 0; } @@ -2014,6 +2114,19 @@ hashlib_free(void *m) } /* Py_mod_exec functions */ +static int +hashlib_init_hashtable(PyObject *module) +{ + _hashlibstate *state = get_hashlib_state(module); + + state->hashtable = py_hashentry_table_new(); + if (state->hashtable == NULL) { + PyErr_NoMemory(); + return -1; + } + return 0; +} + static int hashlib_init_evptype(PyObject *module) { @@ -2141,6 +2254,7 @@ hashlib_exception(PyObject *module) static PyModuleDef_Slot hashlib_slots[] = { + {Py_mod_exec, hashlib_init_hashtable}, {Py_mod_exec, hashlib_init_evptype}, {Py_mod_exec, hashlib_init_evpxoftype}, {Py_mod_exec, hashlib_init_hmactype}, diff --git a/Modules/_heapqmodule.c b/Modules/_heapqmodule.c index 3dbaaa0a0da..07ddc7b0851 100644 --- a/Modules/_heapqmodule.c +++ b/Modules/_heapqmodule.c @@ -197,8 +197,7 @@ heapreplace_internal(PyObject *heap, PyObject *item, int siftup_func(PyListObjec } returnitem = PyList_GET_ITEM(heap, 0); - Py_INCREF(item); - PyList_SET_ITEM(heap, 0, item); + PyList_SET_ITEM(heap, 0, Py_NewRef(item)); if (siftup_func((PyListObject *)heap, 0)) { Py_DECREF(returnitem); return NULL; @@ -253,8 +252,7 @@ _heapq_heappushpop_impl(PyObject *module, PyObject *heap, PyObject *item) int cmp; if (PyList_GET_SIZE(heap) == 0) { - Py_INCREF(item); - return item; + return Py_NewRef(item); } PyObject* top = PyList_GET_ITEM(heap, 0); @@ -264,8 +262,7 @@ _heapq_heappushpop_impl(PyObject *module, PyObject *heap, PyObject *item) if (cmp < 0) return NULL; if (cmp == 0) { - Py_INCREF(item); - return item; + return Py_NewRef(item); } if (PyList_GET_SIZE(heap) == 0) { @@ -274,8 +271,7 @@ _heapq_heappushpop_impl(PyObject *module, PyObject *heap, PyObject *item) } returnitem = PyList_GET_ITEM(heap, 0); - Py_INCREF(item); - PyList_SET_ITEM(heap, 0, item); + PyList_SET_ITEM(heap, 0, Py_NewRef(item)); if (siftup((PyListObject *)heap, 0)) { Py_DECREF(returnitem); return NULL; @@ -410,8 +406,7 @@ siftdown_max(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) newitem = arr[pos]; while (pos > startpos) { parentpos = (pos - 1) >> 1; - parent = arr[parentpos]; - Py_INCREF(parent); + parent = Py_NewRef(arr[parentpos]); Py_INCREF(newitem); cmp = PyObject_RichCompareBool(parent, newitem, Py_LT); Py_DECREF(parent); diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index b4743fbd5e0..af5950cf66c 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -24,38 +24,6 @@ #include #endif -/* Various interned strings */ - -PyObject *_PyIO_str_close = NULL; -PyObject *_PyIO_str_closed = NULL; -PyObject *_PyIO_str_decode = NULL; -PyObject *_PyIO_str_encode = NULL; -PyObject *_PyIO_str_fileno = NULL; -PyObject *_PyIO_str_flush = NULL; -PyObject *_PyIO_str_getstate = NULL; -PyObject *_PyIO_str_isatty = NULL; -PyObject *_PyIO_str_locale = NULL; -PyObject *_PyIO_str_newlines = NULL; -PyObject *_PyIO_str_nl = NULL; -PyObject *_PyIO_str_peek = NULL; -PyObject *_PyIO_str_read = NULL; -PyObject *_PyIO_str_read1 = NULL; -PyObject *_PyIO_str_readable = NULL; -PyObject *_PyIO_str_readall = NULL; -PyObject *_PyIO_str_readinto = NULL; -PyObject *_PyIO_str_readline = NULL; -PyObject *_PyIO_str_reset = NULL; -PyObject *_PyIO_str_seek = NULL; -PyObject *_PyIO_str_seekable = NULL; -PyObject *_PyIO_str_setstate = NULL; -PyObject *_PyIO_str_tell = NULL; -PyObject *_PyIO_str_truncate = NULL; -PyObject *_PyIO_str_writable = NULL; -PyObject *_PyIO_str_write = NULL; - -PyObject *_PyIO_empty_str = NULL; -PyObject *_PyIO_empty_bytes = NULL; - PyDoc_STRVAR(module_doc, "The io module provides the Python interfaces to stream handling. The\n" "builtin open function is defined in this module.\n" @@ -91,7 +59,7 @@ PyDoc_STRVAR(module_doc, " I/O classes. open() uses the file's blksize (as obtained by os.stat) if\n" " possible.\n" ); - + /* * The main open() function @@ -106,7 +74,7 @@ _io.open encoding: str(accept={str, NoneType}) = None errors: str(accept={str, NoneType}) = None newline: str(accept={str, NoneType}) = None - closefd: bool(accept={int}) = True + closefd: bool = True opener: object = None Open file and return a stream. Raise OSError upon failure. @@ -124,9 +92,9 @@ it already exists), 'x' for creating and writing to a new file, and 'a' for appending (which on some Unix systems, means that all writes append to the end of the file regardless of the current seek position). In text mode, if encoding is not specified the encoding used is platform -dependent: locale.getpreferredencoding(False) is called to get the -current locale encoding. (For reading and writing raw bytes use binary -mode and leave encoding unspecified.) The available modes are: +dependent: locale.getencoding() is called to get the current locale encoding. +(For reading and writing raw bytes use binary mode and leave encoding +unspecified.) The available modes are: ========= =============================================================== Character Meaning @@ -228,7 +196,7 @@ static PyObject * _io_open_impl(PyObject *module, PyObject *file, const char *mode, int buffering, const char *encoding, const char *errors, const char *newline, int closefd, PyObject *opener) -/*[clinic end generated code: output=aefafc4ce2b46dc0 input=1543f4511d2356a5]*/ +/*[clinic end generated code: output=aefafc4ce2b46dc0 input=cd034e7cdfbf4e78]*/ { unsigned i; @@ -236,21 +204,14 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, int text = 0, binary = 0; char rawmode[6], *m; - int line_buffering, is_number; - long isatty = 0; + int line_buffering, is_number, isatty = 0; PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL, *path_or_fd = NULL; - _Py_IDENTIFIER(_blksize); - _Py_IDENTIFIER(isatty); - _Py_IDENTIFIER(mode); - _Py_IDENTIFIER(close); - is_number = PyNumber_Check(file); if (is_number) { - path_or_fd = file; - Py_INCREF(path_or_fd); + path_or_fd = Py_NewRef(file); } else { path_or_fd = PyOS_FSPath(file); if (path_or_fd == NULL) { @@ -372,8 +333,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, goto error; result = raw; - Py_DECREF(path_or_fd); - path_or_fd = NULL; + Py_SETREF(path_or_fd, NULL); modeobj = PyUnicode_FromString(mode); if (modeobj == NULL) @@ -381,12 +341,12 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, /* buffering */ if (buffering < 0) { - PyObject *res = _PyObject_CallMethodIdNoArgs(raw, &PyId_isatty); + PyObject *res = PyObject_CallMethodNoArgs(raw, &_Py_ID(isatty)); if (res == NULL) goto error; - isatty = PyLong_AsLong(res); + isatty = PyObject_IsTrue(res); Py_DECREF(res); - if (isatty == -1 && PyErr_Occurred()) + if (isatty < 0) goto error; } @@ -399,7 +359,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, if (buffering < 0) { PyObject *blksize_obj; - blksize_obj = _PyObject_GetAttrId(raw, &PyId__blksize); + blksize_obj = PyObject_GetAttr(raw, &_Py_ID(_blksize)); if (blksize_obj == NULL) goto error; buffering = PyLong_AsLong(blksize_obj); @@ -466,7 +426,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, result = wrapper; Py_DECREF(buffer); - if (_PyObject_SetAttrId(wrapper, &PyId_mode, modeobj) < 0) + if (PyObject_SetAttr(wrapper, &_Py_ID(mode), modeobj) < 0) goto error; Py_DECREF(modeobj); return result; @@ -475,7 +435,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, if (result != NULL) { PyObject *exc, *val, *tb, *close_result; PyErr_Fetch(&exc, &val, &tb); - close_result = _PyObject_CallMethodIdNoArgs(result, &PyId_close); + close_result = PyObject_CallMethodNoArgs(result, &_Py_ID(close)); _PyErr_ChainExceptions(exc, val, tb); Py_XDECREF(close_result); Py_DECREF(result); @@ -494,8 +454,9 @@ _io.text_encoding A helper function to choose the text encoding. -When encoding is not None, just return it. -Otherwise, return the default text encoding (i.e. "locale"). +When encoding is not None, this function returns it. +Otherwise, this function returns the default text encoding +(i.e. "locale" or "utf-8" depends on UTF-8 mode). This function emits an EncodingWarning if encoding is None and sys.flags.warn_default_encoding is true. @@ -506,7 +467,7 @@ However, please consider using encoding="utf-8" for new APIs. static PyObject * _io_text_encoding_impl(PyObject *module, PyObject *encoding, int stacklevel) -/*[clinic end generated code: output=91b2cfea6934cc0c input=bf70231213e2a7b4]*/ +/*[clinic end generated code: output=91b2cfea6934cc0c input=4999aa8b3d90f3d4]*/ { if (encoding == NULL || encoding == Py_None) { PyInterpreterState *interp = _PyInterpreterState_GET(); @@ -516,11 +477,16 @@ _io_text_encoding_impl(PyObject *module, PyObject *encoding, int stacklevel) return NULL; } } - Py_INCREF(_PyIO_str_locale); - return _PyIO_str_locale; + const PyPreConfig *preconfig = &_PyRuntime.preconfig; + if (preconfig->utf8_mode) { + _Py_DECLARE_STR(utf_8, "utf-8"); + encoding = &_Py_STR(utf_8); + } + else { + encoding = &_Py_ID(locale); + } } - Py_INCREF(encoding); - return encoding; + return Py_NewRef(encoding); } @@ -542,7 +508,7 @@ _io_open_code_impl(PyObject *module, PyObject *path) { return PyFile_OpenCodeObject(path); } - + /* * Private helpers for the io module. */ @@ -666,6 +632,47 @@ struct PyModuleDef _PyIO_Module = { (freefunc)iomodule_free, }; + +static PyTypeObject* static_types[] = { + // Base classes + &PyIOBase_Type, + &PyIncrementalNewlineDecoder_Type, + + // PyIOBase_Type subclasses + &PyBufferedIOBase_Type, + &PyRawIOBase_Type, + &PyTextIOBase_Type, + + // PyBufferedIOBase_Type(PyIOBase_Type) subclasses + &PyBytesIO_Type, + &PyBufferedReader_Type, + &PyBufferedWriter_Type, + &PyBufferedRWPair_Type, + &PyBufferedRandom_Type, + + // PyRawIOBase_Type(PyIOBase_Type) subclasses + &PyFileIO_Type, + &_PyBytesIOBuffer_Type, +#ifdef MS_WINDOWS + &PyWindowsConsoleIO_Type, +#endif + + // PyTextIOBase_Type(PyIOBase_Type) subclasses + &PyStringIO_Type, + &PyTextIOWrapper_Type, +}; + + +void +_PyIO_Fini(void) +{ + for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types) - 1; i >= 0; i--) { + PyTypeObject *exc = static_types[i]; + _PyStaticType_Dealloc(exc); + } +} + + PyMODINIT_FUNC PyInit__io(void) { @@ -676,11 +683,6 @@ PyInit__io(void) state = get_io_state(m); state->initialized = 0; -#define ADD_TYPE(type) \ - if (PyModule_AddType(m, type) < 0) { \ - goto fail; \ - } - /* DEFAULT_BUFFER_SIZE */ if (PyModule_AddIntMacro(m, DEFAULT_BUFFER_SIZE) < 0) goto fail; @@ -691,111 +693,44 @@ PyInit__io(void) "UnsupportedOperation", PyExc_OSError, PyExc_ValueError); if (state->unsupported_operation == NULL) goto fail; - Py_INCREF(state->unsupported_operation); if (PyModule_AddObject(m, "UnsupportedOperation", - state->unsupported_operation) < 0) + Py_NewRef(state->unsupported_operation)) < 0) goto fail; /* BlockingIOError, for compatibility */ - Py_INCREF(PyExc_BlockingIOError); - if (PyModule_AddObject(m, "BlockingIOError", - (PyObject *) PyExc_BlockingIOError) < 0) + if (PyModule_AddObjectRef(m, "BlockingIOError", + (PyObject *) PyExc_BlockingIOError) < 0) { goto fail; + } - /* Concrete base types of the IO ABCs. - (the ABCs themselves are declared through inheritance in io.py) - */ - ADD_TYPE(&PyIOBase_Type); - ADD_TYPE(&PyRawIOBase_Type); - ADD_TYPE(&PyBufferedIOBase_Type); - ADD_TYPE(&PyTextIOBase_Type); - - /* Implementation of concrete IO objects. */ - /* FileIO */ + // Set type base classes PyFileIO_Type.tp_base = &PyRawIOBase_Type; - ADD_TYPE(&PyFileIO_Type); - - /* BytesIO */ PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type; - ADD_TYPE(&PyBytesIO_Type); - if (PyType_Ready(&_PyBytesIOBuffer_Type) < 0) - goto fail; - - /* StringIO */ PyStringIO_Type.tp_base = &PyTextIOBase_Type; - ADD_TYPE(&PyStringIO_Type); - #ifdef MS_WINDOWS - /* WindowsConsoleIO */ PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type; - ADD_TYPE(&PyWindowsConsoleIO_Type); #endif - - /* BufferedReader */ PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type; - ADD_TYPE(&PyBufferedReader_Type); - - /* BufferedWriter */ PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type; - ADD_TYPE(&PyBufferedWriter_Type); - - /* BufferedRWPair */ PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type; - ADD_TYPE(&PyBufferedRWPair_Type); - - /* BufferedRandom */ PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type; - ADD_TYPE(&PyBufferedRandom_Type); - - /* TextIOWrapper */ PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type; - ADD_TYPE(&PyTextIOWrapper_Type); - /* IncrementalNewlineDecoder */ - ADD_TYPE(&PyIncrementalNewlineDecoder_Type); - - /* Interned strings */ -#define ADD_INTERNED(name) \ - if (!_PyIO_str_ ## name && \ - !(_PyIO_str_ ## name = PyUnicode_InternFromString(# name))) \ - goto fail; - - ADD_INTERNED(close) - ADD_INTERNED(closed) - ADD_INTERNED(decode) - ADD_INTERNED(encode) - ADD_INTERNED(fileno) - ADD_INTERNED(flush) - ADD_INTERNED(getstate) - ADD_INTERNED(isatty) - ADD_INTERNED(locale) - ADD_INTERNED(newlines) - ADD_INTERNED(peek) - ADD_INTERNED(read) - ADD_INTERNED(read1) - ADD_INTERNED(readable) - ADD_INTERNED(readall) - ADD_INTERNED(readinto) - ADD_INTERNED(readline) - ADD_INTERNED(reset) - ADD_INTERNED(seek) - ADD_INTERNED(seekable) - ADD_INTERNED(setstate) - ADD_INTERNED(tell) - ADD_INTERNED(truncate) - ADD_INTERNED(write) - ADD_INTERNED(writable) - - if (!_PyIO_str_nl && - !(_PyIO_str_nl = PyUnicode_InternFromString("\n"))) - goto fail; - - if (!_PyIO_empty_str && - !(_PyIO_empty_str = PyUnicode_FromStringAndSize(NULL, 0))) - goto fail; - if (!_PyIO_empty_bytes && - !(_PyIO_empty_bytes = PyBytes_FromStringAndSize(NULL, 0))) - goto fail; + // Add types + for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) { + PyTypeObject *type = static_types[i]; + // Private type not exposed in the _io module + if (type == &_PyBytesIOBuffer_Type) { + if (PyType_Ready(type) < 0) { + goto fail; + } + } + else { + if (PyModule_AddType(m, type) < 0) { + goto fail; + } + } + } state->initialized = 1; diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h index 638797fd357..c260080f0e3 100644 --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -155,33 +155,4 @@ extern _PyIO_State *_PyIO_get_module_state(void); extern char _PyIO_get_console_type(PyObject *); #endif -extern PyObject *_PyIO_str_close; -extern PyObject *_PyIO_str_closed; -extern PyObject *_PyIO_str_decode; -extern PyObject *_PyIO_str_encode; -extern PyObject *_PyIO_str_fileno; -extern PyObject *_PyIO_str_flush; -extern PyObject *_PyIO_str_getstate; -extern PyObject *_PyIO_str_isatty; -extern PyObject *_PyIO_str_newlines; -extern PyObject *_PyIO_str_nl; -extern PyObject *_PyIO_str_peek; -extern PyObject *_PyIO_str_read; -extern PyObject *_PyIO_str_read1; -extern PyObject *_PyIO_str_readable; -extern PyObject *_PyIO_str_readall; -extern PyObject *_PyIO_str_readinto; -extern PyObject *_PyIO_str_readline; -extern PyObject *_PyIO_str_reset; -extern PyObject *_PyIO_str_seek; -extern PyObject *_PyIO_str_seekable; -extern PyObject *_PyIO_str_setstate; -extern PyObject *_PyIO_str_tell; -extern PyObject *_PyIO_str_truncate; -extern PyObject *_PyIO_str_writable; -extern PyObject *_PyIO_str_write; - -extern PyObject *_PyIO_empty_str; -extern PyObject *_PyIO_empty_bytes; - extern Py_EXPORTED_SYMBOL PyTypeObject _PyBytesIOBuffer_Type; diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 28995051abd..ba8969f0bcd 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -25,21 +25,6 @@ class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/ -_Py_IDENTIFIER(close); -_Py_IDENTIFIER(_dealloc_warn); -_Py_IDENTIFIER(flush); -_Py_IDENTIFIER(isatty); -_Py_IDENTIFIER(mode); -_Py_IDENTIFIER(name); -_Py_IDENTIFIER(peek); -_Py_IDENTIFIER(read); -_Py_IDENTIFIER(read1); -_Py_IDENTIFIER(readable); -_Py_IDENTIFIER(readinto); -_Py_IDENTIFIER(readinto1); -_Py_IDENTIFIER(writable); -_Py_IDENTIFIER(write); - /* * BufferedIOBase class, inherits from IOBase. */ @@ -65,9 +50,10 @@ _bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readint Py_ssize_t len; PyObject *data; - data = _PyObject_CallMethodId(self, - readinto1 ? &PyId_read1 : &PyId_read, - "n", buffer->len); + PyObject *attr = readinto1 + ? &_Py_ID(read1) + : &_Py_ID(read); + data = _PyObject_CallMethod(self, attr, "n", buffer->len); if (data == NULL) return NULL; @@ -342,7 +328,7 @@ _enter_buffered_busy(buffered *self) : buffered_closed(self))) #define CHECK_CLOSED(self, error_msg) \ - if (IS_CLOSED(self) & (Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t) == 0)) { \ + if (IS_CLOSED(self) && (Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t) == 0)) { \ PyErr_SetString(PyExc_ValueError, error_msg); \ return NULL; \ } \ @@ -403,12 +389,11 @@ buffered_dealloc(buffered *self) static PyObject * buffered_sizeof(buffered *self, PyObject *Py_UNUSED(ignored)) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)); - if (self->buffer) - res += self->buffer_size; - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(self)); + if (self->buffer) { + res += (size_t)self->buffer_size; + } + return PyLong_FromSize_t(res); } static int @@ -436,8 +421,7 @@ buffered_dealloc_warn(buffered *self, PyObject *source) { if (self->ok && self->raw) { PyObject *r; - r = _PyObject_CallMethodIdOneArg(self->raw, &PyId__dealloc_warn, - source); + r = PyObject_CallMethodOneArg(self->raw, &_Py_ID(_dealloc_warn), source); if (r) Py_DECREF(r); else @@ -458,7 +442,7 @@ static PyObject * buffered_simple_flush(buffered *self, PyObject *args) { CHECK_INITIALIZED(self) - return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_flush); + return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(flush)); } static int @@ -467,7 +451,7 @@ buffered_closed(buffered *self) int closed; PyObject *res; CHECK_INITIALIZED_INT(self) - res = PyObject_GetAttr(self->raw, _PyIO_str_closed); + res = PyObject_GetAttr(self->raw, &_Py_ID(closed)); if (res == NULL) return -1; closed = PyObject_IsTrue(res); @@ -479,7 +463,7 @@ static PyObject * buffered_closed_get(buffered *self, void *context) { CHECK_INITIALIZED(self) - return PyObject_GetAttr(self->raw, _PyIO_str_closed); + return PyObject_GetAttr(self->raw, &_Py_ID(closed)); } static PyObject * @@ -496,8 +480,7 @@ buffered_close(buffered *self, PyObject *args) if (r < 0) goto end; if (r > 0) { - res = Py_None; - Py_INCREF(res); + res = Py_NewRef(Py_None); goto end; } @@ -510,7 +493,7 @@ buffered_close(buffered *self, PyObject *args) } /* flush() will most probably re-take the lock, so drop it first */ LEAVE_BUFFERED(self) - res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); + res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); if (!ENTER_BUFFERED(self)) return NULL; if (res == NULL) @@ -518,7 +501,7 @@ buffered_close(buffered *self, PyObject *args) else Py_DECREF(res); - res = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_close); + res = PyObject_CallMethodNoArgs(self->raw, &_Py_ID(close)); if (self->buffer) { PyMem_Free(self->buffer); @@ -545,7 +528,7 @@ buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored)) { PyObject *raw, *res; CHECK_INITIALIZED(self) - res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); + res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); if (res == NULL) return NULL; Py_DECREF(res); @@ -562,35 +545,35 @@ static PyObject * buffered_seekable(buffered *self, PyObject *Py_UNUSED(ignored)) { CHECK_INITIALIZED(self) - return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_seekable); + return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(seekable)); } static PyObject * buffered_readable(buffered *self, PyObject *Py_UNUSED(ignored)) { CHECK_INITIALIZED(self) - return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_readable); + return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(readable)); } static PyObject * buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored)) { CHECK_INITIALIZED(self) - return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_writable); + return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(writable)); } static PyObject * buffered_name_get(buffered *self, void *context) { CHECK_INITIALIZED(self) - return _PyObject_GetAttrId(self->raw, &PyId_name); + return PyObject_GetAttr(self->raw, &_Py_ID(name)); } static PyObject * buffered_mode_get(buffered *self, void *context) { CHECK_INITIALIZED(self) - return _PyObject_GetAttrId(self->raw, &PyId_mode); + return PyObject_GetAttr(self->raw, &_Py_ID(mode)); } /* Lower-level APIs */ @@ -599,14 +582,14 @@ static PyObject * buffered_fileno(buffered *self, PyObject *Py_UNUSED(ignored)) { CHECK_INITIALIZED(self) - return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_fileno); + return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(fileno)); } static PyObject * buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored)) { CHECK_INITIALIZED(self) - return PyObject_CallMethodNoArgs(self->raw, _PyIO_str_isatty); + return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(isatty)); } /* Forward decls */ @@ -670,7 +653,7 @@ _buffered_raw_tell(buffered *self) { Py_off_t n; PyObject *res; - res = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_tell); + res = PyObject_CallMethodNoArgs(self->raw, &_Py_ID(tell)); if (res == NULL) return -1; n = PyNumber_AsOff_t(res, PyExc_ValueError); @@ -700,7 +683,7 @@ _buffered_raw_seek(buffered *self, Py_off_t target, int whence) Py_DECREF(posobj); return -1; } - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek, + res = PyObject_CallMethodObjArgs(self->raw, &_Py_ID(seek), posobj, whenceobj, NULL); Py_DECREF(posobj); Py_DECREF(whenceobj); @@ -763,26 +746,26 @@ _buffered_init(buffered *self) int _PyIO_trap_eintr(void) { - static PyObject *eintr_int = NULL; PyObject *typ, *val, *tb; PyOSErrorObject *env_err; - - if (eintr_int == NULL) { - eintr_int = PyLong_FromLong(EINTR); - assert(eintr_int != NULL); - } if (!PyErr_ExceptionMatches(PyExc_OSError)) return 0; PyErr_Fetch(&typ, &val, &tb); PyErr_NormalizeException(&typ, &val, &tb); env_err = (PyOSErrorObject *) val; assert(env_err != NULL); - if (env_err->myerrno != NULL && - PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) { - Py_DECREF(typ); - Py_DECREF(val); - Py_XDECREF(tb); - return 1; + if (env_err->myerrno != NULL) { + assert(EINTR > 0 && EINTR < INT_MAX); + assert(PyLong_CheckExact(env_err->myerrno)); + int overflow; + int myerrno = PyLong_AsLongAndOverflow(env_err->myerrno, &overflow); + PyErr_Clear(); + if (myerrno == EINTR) { + Py_DECREF(typ); + Py_DECREF(val); + Py_XDECREF(tb); + return 1; + } } /* This silences any error set by PyObject_RichCompareBool() */ PyErr_Restore(typ, val, tb); @@ -1022,8 +1005,7 @@ _buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1) break; if (n < 0) { if (n == -2) { - Py_INCREF(Py_None); - res = Py_None; + res = Py_NewRef(Py_None); } goto end; } @@ -1167,7 +1149,7 @@ found: Py_CLEAR(res); goto end; } - Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks)); + Py_XSETREF(res, _PyBytes_Join((PyObject *)&_Py_SINGLETON(bytes_empty), chunks)); end: LEAVE_BUFFERED(self) @@ -1326,7 +1308,7 @@ _io__Buffered_truncate_impl(buffered *self, PyObject *pos) } Py_CLEAR(res); - res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_truncate, pos); + res = PyObject_CallMethodOneArg(self->raw, &_Py_ID(truncate), pos); if (res == NULL) goto end; /* Reset cached position */ @@ -1354,7 +1336,7 @@ buffered_iternext(buffered *self) } else { line = PyObject_CallMethodNoArgs((PyObject *)self, - _PyIO_str_readline); + &_Py_ID(readline)); if (line && !PyBytes_Check(line)) { PyErr_Format(PyExc_OSError, "readline() should have returned a bytes object, " @@ -1381,7 +1363,7 @@ buffered_repr(buffered *self) { PyObject *nameobj, *res; - if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) { + if (_PyObject_LookupAttr((PyObject *) self, &_Py_ID(name), &nameobj) < 0) { if (!PyErr_ExceptionMatches(PyExc_ValueError)) { return NULL; } @@ -1437,8 +1419,7 @@ _io_BufferedReader___init___impl(buffered *self, PyObject *raw, if (_PyIOBase_check_readable(raw, Py_True) == NULL) return -1; - Py_INCREF(raw); - Py_XSETREF(self->raw, raw); + Py_XSETREF(self->raw, Py_NewRef(raw)); self->buffer_size = buffer_size; self->readable = 1; self->writable = 0; @@ -1472,7 +1453,7 @@ _bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len) raised (see issue #10956). */ do { - res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_readinto, memobj); + res = PyObject_CallMethodOneArg(self->raw, &_Py_ID(readinto), memobj); } while (res == NULL && _PyIO_trap_eintr()); Py_DECREF(memobj); if (res == NULL) @@ -1545,7 +1526,7 @@ _bufferedreader_read_all(buffered *self) } _bufferedreader_reset_buf(self); - if (_PyObject_LookupAttr(self->raw, _PyIO_str_readall, &readall) < 0) { + if (_PyObject_LookupAttr(self->raw, &_Py_ID(readall), &readall) < 0) { goto cleanup; } if (readall) { @@ -1580,7 +1561,7 @@ _bufferedreader_read_all(buffered *self) } /* Read until EOF or until read() would block. */ - data = PyObject_CallMethodNoArgs(self->raw, _PyIO_str_read); + data = PyObject_CallMethodNoArgs(self->raw, &_Py_ID(read)); if (data == NULL) goto cleanup; if (data != Py_None && !PyBytes_Check(data)) { @@ -1593,7 +1574,7 @@ _bufferedreader_read_all(buffered *self) goto cleanup; } else { - tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks); + tmp = _PyBytes_Join((PyObject *)&_Py_SINGLETON(bytes_empty), chunks); res = tmp; goto cleanup; } @@ -1829,7 +1810,7 @@ _bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len) */ do { errno = 0; - res = PyObject_CallMethodOneArg(self->raw, _PyIO_str_write, memobj); + res = PyObject_CallMethodOneArg(self->raw, &_Py_ID(write), memobj); errnum = errno; } while (res == NULL && _PyIO_trap_eintr()); Py_DECREF(memobj); @@ -2153,7 +2134,7 @@ bufferedrwpair_dealloc(rwpair *self) } static PyObject * -_forward_call(buffered *self, _Py_Identifier *name, PyObject *args) +_forward_call(buffered *self, PyObject *name, PyObject *args) { PyObject *func, *ret; if (self == NULL) { @@ -2162,9 +2143,9 @@ _forward_call(buffered *self, _Py_Identifier *name, PyObject *args) return NULL; } - func = _PyObject_GetAttrId((PyObject *)self, name); + func = PyObject_GetAttr((PyObject *)self, name); if (func == NULL) { - PyErr_SetString(PyExc_AttributeError, name->string); + PyErr_SetObject(PyExc_AttributeError, name); return NULL; } @@ -2176,67 +2157,67 @@ _forward_call(buffered *self, _Py_Identifier *name, PyObject *args) static PyObject * bufferedrwpair_read(rwpair *self, PyObject *args) { - return _forward_call(self->reader, &PyId_read, args); + return _forward_call(self->reader, &_Py_ID(read), args); } static PyObject * bufferedrwpair_peek(rwpair *self, PyObject *args) { - return _forward_call(self->reader, &PyId_peek, args); + return _forward_call(self->reader, &_Py_ID(peek), args); } static PyObject * bufferedrwpair_read1(rwpair *self, PyObject *args) { - return _forward_call(self->reader, &PyId_read1, args); + return _forward_call(self->reader, &_Py_ID(read1), args); } static PyObject * bufferedrwpair_readinto(rwpair *self, PyObject *args) { - return _forward_call(self->reader, &PyId_readinto, args); + return _forward_call(self->reader, &_Py_ID(readinto), args); } static PyObject * bufferedrwpair_readinto1(rwpair *self, PyObject *args) { - return _forward_call(self->reader, &PyId_readinto1, args); + return _forward_call(self->reader, &_Py_ID(readinto1), args); } static PyObject * bufferedrwpair_write(rwpair *self, PyObject *args) { - return _forward_call(self->writer, &PyId_write, args); + return _forward_call(self->writer, &_Py_ID(write), args); } static PyObject * bufferedrwpair_flush(rwpair *self, PyObject *Py_UNUSED(ignored)) { - return _forward_call(self->writer, &PyId_flush, NULL); + return _forward_call(self->writer, &_Py_ID(flush), NULL); } static PyObject * bufferedrwpair_readable(rwpair *self, PyObject *Py_UNUSED(ignored)) { - return _forward_call(self->reader, &PyId_readable, NULL); + return _forward_call(self->reader, &_Py_ID(readable), NULL); } static PyObject * bufferedrwpair_writable(rwpair *self, PyObject *Py_UNUSED(ignored)) { - return _forward_call(self->writer, &PyId_writable, NULL); + return _forward_call(self->writer, &_Py_ID(writable), NULL); } static PyObject * bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored)) { PyObject *exc = NULL, *val, *tb; - PyObject *ret = _forward_call(self->writer, &PyId_close, NULL); + PyObject *ret = _forward_call(self->writer, &_Py_ID(close), NULL); if (ret == NULL) PyErr_Fetch(&exc, &val, &tb); else Py_DECREF(ret); - ret = _forward_call(self->reader, &PyId_close, NULL); + ret = _forward_call(self->reader, &_Py_ID(close), NULL); if (exc != NULL) { _PyErr_ChainExceptions(exc, val, tb); Py_CLEAR(ret); @@ -2247,7 +2228,7 @@ bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored)) static PyObject * bufferedrwpair_isatty(rwpair *self, PyObject *Py_UNUSED(ignored)) { - PyObject *ret = _forward_call(self->writer, &PyId_isatty, NULL); + PyObject *ret = _forward_call(self->writer, &_Py_ID(isatty), NULL); if (ret != Py_False) { /* either True or exception */ @@ -2255,7 +2236,7 @@ bufferedrwpair_isatty(rwpair *self, PyObject *Py_UNUSED(ignored)) } Py_DECREF(ret); - return _forward_call(self->reader, &PyId_isatty, NULL); + return _forward_call(self->reader, &_Py_ID(isatty), NULL); } static PyObject * @@ -2266,7 +2247,7 @@ bufferedrwpair_closed_get(rwpair *self, void *context) "the BufferedRWPair object is being garbage-collected"); return NULL; } - return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed); + return PyObject_GetAttr((PyObject *) self->writer, &_Py_ID(closed)); } diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 930ef7e29db..6698c60355f 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -324,8 +324,7 @@ _io_BytesIO_getbuffer_impl(bytesio *self) buf = (bytesiobuf *) type->tp_alloc(type, 0); if (buf == NULL) return NULL; - Py_INCREF(self); - buf->source = self; + buf->source = (bytesio*)Py_NewRef(self); view = PyMemoryView_FromObject((PyObject *) buf); Py_DECREF(buf); return view; @@ -356,8 +355,7 @@ _io_BytesIO_getvalue_impl(bytesio *self) return NULL; } } - Py_INCREF(self->buf); - return self->buf; + return Py_NewRef(self->buf); } /*[clinic input] @@ -401,8 +399,7 @@ read_bytes(bytesio *self, Py_ssize_t size) self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) && self->exports == 0) { self->pos += size; - Py_INCREF(self->buf); - return self->buf; + return Py_NewRef(self->buf); } output = PyBytes_AS_STRING(self->buf) + self->pos; @@ -791,8 +788,7 @@ bytesio_getstate(bytesio *self, PyObject *Py_UNUSED(ignored)) if (initvalue == NULL) return NULL; if (self->dict == NULL) { - Py_INCREF(Py_None); - dict = Py_None; + dict = Py_NewRef(Py_None); } else { dict = PyDict_Copy(self->dict); @@ -875,8 +871,7 @@ bytesio_setstate(bytesio *self, PyObject *state) return NULL; } else { - Py_INCREF(dict); - self->dict = dict; + self->dict = Py_NewRef(dict); } } @@ -943,8 +938,7 @@ _io_BytesIO___init___impl(bytesio *self, PyObject *initvalue) } if (initvalue && initvalue != Py_None) { if (PyBytes_CheckExact(initvalue)) { - Py_INCREF(initvalue); - Py_XSETREF(self->buf, initvalue); + Py_XSETREF(self->buf, Py_NewRef(initvalue)); self->string_size = PyBytes_GET_SIZE(initvalue); } else { @@ -963,17 +957,15 @@ _io_BytesIO___init___impl(bytesio *self, PyObject *initvalue) static PyObject * bytesio_sizeof(bytesio *self, void *unused) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)); + size_t res = _PyObject_SIZE(Py_TYPE(self)); if (self->buf && !SHARED_BUF(self)) { - Py_ssize_t s = _PySys_GetSizeOf(self->buf); - if (s == -1) { + size_t s = _PySys_GetSizeOf(self->buf); + if (s == (size_t)-1) { return NULL; } res += s; } - return PyLong_FromSsize_t(res); + return PyLong_FromSize_t(res); } static int diff --git a/Modules/_io/clinic/_iomodule.c.h b/Modules/_io/clinic/_iomodule.c.h index d5fb176eb66..4d76e333b0f 100644 --- a/Modules/_io/clinic/_iomodule.c.h +++ b/Modules/_io/clinic/_iomodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io_open__doc__, "open($module, /, file, mode=\'r\', buffering=-1, encoding=None,\n" " errors=None, newline=None, closefd=True, opener=None)\n" @@ -22,9 +28,9 @@ PyDoc_STRVAR(_io_open__doc__, "\'a\' for appending (which on some Unix systems, means that all writes\n" "append to the end of the file regardless of the current seek position).\n" "In text mode, if encoding is not specified the encoding used is platform\n" -"dependent: locale.getpreferredencoding(False) is called to get the\n" -"current locale encoding. (For reading and writing raw bytes use binary\n" -"mode and leave encoding unspecified.) The available modes are:\n" +"dependent: locale.getencoding() is called to get the current locale encoding.\n" +"(For reading and writing raw bytes use binary mode and leave encoding\n" +"unspecified.) The available modes are:\n" "\n" "========= ===============================================================\n" "Character Meaning\n" @@ -122,7 +128,7 @@ PyDoc_STRVAR(_io_open__doc__, "opened in a binary mode."); #define _IO_OPEN_METHODDEF \ - {"open", (PyCFunction)(void(*)(void))_io_open, METH_FASTCALL|METH_KEYWORDS, _io_open__doc__}, + {"open", _PyCFunction_CAST(_io_open), METH_FASTCALL|METH_KEYWORDS, _io_open__doc__}, static PyObject * _io_open_impl(PyObject *module, PyObject *file, const char *mode, @@ -133,8 +139,31 @@ static PyObject * _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 8 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(mode), &_Py_ID(buffering), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(newline), &_Py_ID(closefd), &_Py_ID(opener), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"file", "mode", "buffering", "encoding", "errors", "newline", "closefd", "opener", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "open", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "open", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[8]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *file; @@ -251,8 +280,8 @@ _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw } } if (args[6]) { - closefd = _PyLong_AsInt(args[6]); - if (closefd == -1 && PyErr_Occurred()) { + closefd = PyObject_IsTrue(args[6]); + if (closefd < 0) { goto exit; } if (!--noptargs) { @@ -273,8 +302,9 @@ PyDoc_STRVAR(_io_text_encoding__doc__, "\n" "A helper function to choose the text encoding.\n" "\n" -"When encoding is not None, just return it.\n" -"Otherwise, return the default text encoding (i.e. \"locale\").\n" +"When encoding is not None, this function returns it.\n" +"Otherwise, this function returns the default text encoding\n" +"(i.e. \"locale\" or \"utf-8\" depends on UTF-8 mode).\n" "\n" "This function emits an EncodingWarning if encoding is None and\n" "sys.flags.warn_default_encoding is true.\n" @@ -283,7 +313,7 @@ PyDoc_STRVAR(_io_text_encoding__doc__, "However, please consider using encoding=\"utf-8\" for new APIs."); #define _IO_TEXT_ENCODING_METHODDEF \ - {"text_encoding", (PyCFunction)(void(*)(void))_io_text_encoding, METH_FASTCALL, _io_text_encoding__doc__}, + {"text_encoding", _PyCFunction_CAST(_io_text_encoding), METH_FASTCALL, _io_text_encoding__doc__}, static PyObject * _io_text_encoding_impl(PyObject *module, PyObject *encoding, int stacklevel); @@ -323,7 +353,7 @@ PyDoc_STRVAR(_io_open_code__doc__, "with calling open(path, \'rb\')."); #define _IO_OPEN_CODE_METHODDEF \ - {"open_code", (PyCFunction)(void(*)(void))_io_open_code, METH_FASTCALL|METH_KEYWORDS, _io_open_code__doc__}, + {"open_code", _PyCFunction_CAST(_io_open_code), METH_FASTCALL|METH_KEYWORDS, _io_open_code__doc__}, static PyObject * _io_open_code_impl(PyObject *module, PyObject *path); @@ -332,8 +362,31 @@ static PyObject * _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "open_code", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "open_code", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *path; @@ -354,4 +407,4 @@ _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=6ea315343f6a94ba input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f387eba3f4c0254a input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index 2fd02329dc3..8a8f86b2eea 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io__BufferedIOBase_readinto__doc__, "readinto($self, buffer, /)\n" "--\n" @@ -103,7 +109,7 @@ PyDoc_STRVAR(_io__Buffered_peek__doc__, "\n"); #define _IO__BUFFERED_PEEK_METHODDEF \ - {"peek", (PyCFunction)(void(*)(void))_io__Buffered_peek, METH_FASTCALL, _io__Buffered_peek__doc__}, + {"peek", _PyCFunction_CAST(_io__Buffered_peek), METH_FASTCALL, _io__Buffered_peek__doc__}, static PyObject * _io__Buffered_peek_impl(buffered *self, Py_ssize_t size); @@ -145,7 +151,7 @@ PyDoc_STRVAR(_io__Buffered_read__doc__, "\n"); #define _IO__BUFFERED_READ_METHODDEF \ - {"read", (PyCFunction)(void(*)(void))_io__Buffered_read, METH_FASTCALL, _io__Buffered_read__doc__}, + {"read", _PyCFunction_CAST(_io__Buffered_read), METH_FASTCALL, _io__Buffered_read__doc__}, static PyObject * _io__Buffered_read_impl(buffered *self, Py_ssize_t n); @@ -178,7 +184,7 @@ PyDoc_STRVAR(_io__Buffered_read1__doc__, "\n"); #define _IO__BUFFERED_READ1_METHODDEF \ - {"read1", (PyCFunction)(void(*)(void))_io__Buffered_read1, METH_FASTCALL, _io__Buffered_read1__doc__}, + {"read1", _PyCFunction_CAST(_io__Buffered_read1), METH_FASTCALL, _io__Buffered_read1__doc__}, static PyObject * _io__Buffered_read1_impl(buffered *self, Py_ssize_t n); @@ -294,7 +300,7 @@ PyDoc_STRVAR(_io__Buffered_readline__doc__, "\n"); #define _IO__BUFFERED_READLINE_METHODDEF \ - {"readline", (PyCFunction)(void(*)(void))_io__Buffered_readline, METH_FASTCALL, _io__Buffered_readline__doc__}, + {"readline", _PyCFunction_CAST(_io__Buffered_readline), METH_FASTCALL, _io__Buffered_readline__doc__}, static PyObject * _io__Buffered_readline_impl(buffered *self, Py_ssize_t size); @@ -327,7 +333,7 @@ PyDoc_STRVAR(_io__Buffered_seek__doc__, "\n"); #define _IO__BUFFERED_SEEK_METHODDEF \ - {"seek", (PyCFunction)(void(*)(void))_io__Buffered_seek, METH_FASTCALL, _io__Buffered_seek__doc__}, + {"seek", _PyCFunction_CAST(_io__Buffered_seek), METH_FASTCALL, _io__Buffered_seek__doc__}, static PyObject * _io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence); @@ -363,7 +369,7 @@ PyDoc_STRVAR(_io__Buffered_truncate__doc__, "\n"); #define _IO__BUFFERED_TRUNCATE_METHODDEF \ - {"truncate", (PyCFunction)(void(*)(void))_io__Buffered_truncate, METH_FASTCALL, _io__Buffered_truncate__doc__}, + {"truncate", _PyCFunction_CAST(_io__Buffered_truncate), METH_FASTCALL, _io__Buffered_truncate__doc__}, static PyObject * _io__Buffered_truncate_impl(buffered *self, PyObject *pos); @@ -402,8 +408,31 @@ static int _io_BufferedReader___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(raw), &_Py_ID(buffer_size), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"raw", "buffer_size", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "BufferedReader", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "BufferedReader", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -456,8 +485,31 @@ static int _io_BufferedWriter___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(raw), &_Py_ID(buffer_size), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"raw", "buffer_size", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "BufferedWriter", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "BufferedWriter", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -603,8 +655,31 @@ static int _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(raw), &_Py_ID(buffer_size), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"raw", "buffer_size", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "BufferedRandom", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "BufferedRandom", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -638,4 +713,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=79138a088729b5ee input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ca87adcfff6a810b input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h index 5ea80ae01c1..84b58db6c7a 100644 --- a/Modules/_io/clinic/bytesio.c.h +++ b/Modules/_io/clinic/bytesio.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io_BytesIO_readable__doc__, "readable($self, /)\n" "--\n" @@ -158,7 +164,7 @@ PyDoc_STRVAR(_io_BytesIO_read__doc__, "Return an empty bytes object at EOF."); #define _IO_BYTESIO_READ_METHODDEF \ - {"read", (PyCFunction)(void(*)(void))_io_BytesIO_read, METH_FASTCALL, _io_BytesIO_read__doc__}, + {"read", _PyCFunction_CAST(_io_BytesIO_read), METH_FASTCALL, _io_BytesIO_read__doc__}, static PyObject * _io_BytesIO_read_impl(bytesio *self, Py_ssize_t size); @@ -195,7 +201,7 @@ PyDoc_STRVAR(_io_BytesIO_read1__doc__, "Return an empty bytes object at EOF."); #define _IO_BYTESIO_READ1_METHODDEF \ - {"read1", (PyCFunction)(void(*)(void))_io_BytesIO_read1, METH_FASTCALL, _io_BytesIO_read1__doc__}, + {"read1", _PyCFunction_CAST(_io_BytesIO_read1), METH_FASTCALL, _io_BytesIO_read1__doc__}, static PyObject * _io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size); @@ -233,7 +239,7 @@ PyDoc_STRVAR(_io_BytesIO_readline__doc__, "Return an empty bytes object at EOF."); #define _IO_BYTESIO_READLINE_METHODDEF \ - {"readline", (PyCFunction)(void(*)(void))_io_BytesIO_readline, METH_FASTCALL, _io_BytesIO_readline__doc__}, + {"readline", _PyCFunction_CAST(_io_BytesIO_readline), METH_FASTCALL, _io_BytesIO_readline__doc__}, static PyObject * _io_BytesIO_readline_impl(bytesio *self, Py_ssize_t size); @@ -271,7 +277,7 @@ PyDoc_STRVAR(_io_BytesIO_readlines__doc__, "total number of bytes in the lines returned."); #define _IO_BYTESIO_READLINES_METHODDEF \ - {"readlines", (PyCFunction)(void(*)(void))_io_BytesIO_readlines, METH_FASTCALL, _io_BytesIO_readlines__doc__}, + {"readlines", _PyCFunction_CAST(_io_BytesIO_readlines), METH_FASTCALL, _io_BytesIO_readlines__doc__}, static PyObject * _io_BytesIO_readlines_impl(bytesio *self, PyObject *arg); @@ -347,7 +353,7 @@ PyDoc_STRVAR(_io_BytesIO_truncate__doc__, "The current file position is unchanged. Returns the new size."); #define _IO_BYTESIO_TRUNCATE_METHODDEF \ - {"truncate", (PyCFunction)(void(*)(void))_io_BytesIO_truncate, METH_FASTCALL, _io_BytesIO_truncate__doc__}, + {"truncate", _PyCFunction_CAST(_io_BytesIO_truncate), METH_FASTCALL, _io_BytesIO_truncate__doc__}, static PyObject * _io_BytesIO_truncate_impl(bytesio *self, Py_ssize_t size); @@ -387,7 +393,7 @@ PyDoc_STRVAR(_io_BytesIO_seek__doc__, "Returns the new absolute position."); #define _IO_BYTESIO_SEEK_METHODDEF \ - {"seek", (PyCFunction)(void(*)(void))_io_BytesIO_seek, METH_FASTCALL, _io_BytesIO_seek__doc__}, + {"seek", _PyCFunction_CAST(_io_BytesIO_seek), METH_FASTCALL, _io_BytesIO_seek__doc__}, static PyObject * _io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence); @@ -483,8 +489,31 @@ static int _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(initial_bytes), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"initial_bytes", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "BytesIO", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "BytesIO", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -505,4 +534,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=49a32140eb8c5555 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a44770efbaeb80dd input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/fileio.c.h b/Modules/_io/clinic/fileio.c.h index 9b237c156d3..b6e9bd5b65a 100644 --- a/Modules/_io/clinic/fileio.c.h +++ b/Modules/_io/clinic/fileio.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io_FileIO_close__doc__, "close($self, /)\n" "--\n" @@ -49,8 +55,31 @@ static int _io_FileIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(mode), &_Py_ID(closefd), &_Py_ID(opener), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"file", "mode", "closefd", "opener", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "FileIO", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "FileIO", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -87,8 +116,8 @@ _io_FileIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) } } if (fastargs[2]) { - closefd = _PyLong_AsInt(fastargs[2]); - if (closefd == -1 && PyErr_Occurred()) { + closefd = PyObject_IsTrue(fastargs[2]); + if (closefd < 0) { goto exit; } if (!--noptargs) { @@ -245,7 +274,7 @@ PyDoc_STRVAR(_io_FileIO_read__doc__, "Return an empty bytes object at EOF."); #define _IO_FILEIO_READ_METHODDEF \ - {"read", (PyCFunction)(void(*)(void))_io_FileIO_read, METH_FASTCALL, _io_FileIO_read__doc__}, + {"read", _PyCFunction_CAST(_io_FileIO_read), METH_FASTCALL, _io_FileIO_read__doc__}, static PyObject * _io_FileIO_read_impl(fileio *self, Py_ssize_t size); @@ -327,7 +356,7 @@ PyDoc_STRVAR(_io_FileIO_seek__doc__, "Note that not all file objects are seekable."); #define _IO_FILEIO_SEEK_METHODDEF \ - {"seek", (PyCFunction)(void(*)(void))_io_FileIO_seek, METH_FASTCALL, _io_FileIO_seek__doc__}, + {"seek", _PyCFunction_CAST(_io_FileIO_seek), METH_FASTCALL, _io_FileIO_seek__doc__}, static PyObject * _io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence); @@ -389,7 +418,7 @@ PyDoc_STRVAR(_io_FileIO_truncate__doc__, "The current file position is changed to the value of size."); #define _IO_FILEIO_TRUNCATE_METHODDEF \ - {"truncate", (PyCFunction)(void(*)(void))_io_FileIO_truncate, METH_FASTCALL, _io_FileIO_truncate__doc__}, + {"truncate", _PyCFunction_CAST(_io_FileIO_truncate), METH_FASTCALL, _io_FileIO_truncate__doc__}, static PyObject * _io_FileIO_truncate_impl(fileio *self, PyObject *posobj); @@ -437,4 +466,4 @@ _io_FileIO_isatty(fileio *self, PyObject *Py_UNUSED(ignored)) #ifndef _IO_FILEIO_TRUNCATE_METHODDEF #define _IO_FILEIO_TRUNCATE_METHODDEF #endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */ -/*[clinic end generated code: output=3479912ec0f7e029 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=27f883807a6c29ae input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/iobase.c.h b/Modules/_io/clinic/iobase.c.h index 4fd6e18c4ef..01c035dad26 100644 --- a/Modules/_io/clinic/iobase.c.h +++ b/Modules/_io/clinic/iobase.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io__IOBase_tell__doc__, "tell($self, /)\n" "--\n" @@ -174,7 +180,7 @@ PyDoc_STRVAR(_io__IOBase_readline__doc__, "terminator(s) recognized."); #define _IO__IOBASE_READLINE_METHODDEF \ - {"readline", (PyCFunction)(void(*)(void))_io__IOBase_readline, METH_FASTCALL, _io__IOBase_readline__doc__}, + {"readline", _PyCFunction_CAST(_io__IOBase_readline), METH_FASTCALL, _io__IOBase_readline__doc__}, static PyObject * _io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit); @@ -212,7 +218,7 @@ PyDoc_STRVAR(_io__IOBase_readlines__doc__, "lines so far exceeds hint."); #define _IO__IOBASE_READLINES_METHODDEF \ - {"readlines", (PyCFunction)(void(*)(void))_io__IOBase_readlines, METH_FASTCALL, _io__IOBase_readlines__doc__}, + {"readlines", _PyCFunction_CAST(_io__IOBase_readlines), METH_FASTCALL, _io__IOBase_readlines__doc__}, static PyObject * _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint); @@ -257,7 +263,7 @@ PyDoc_STRVAR(_io__RawIOBase_read__doc__, "\n"); #define _IO__RAWIOBASE_READ_METHODDEF \ - {"read", (PyCFunction)(void(*)(void))_io__RawIOBase_read, METH_FASTCALL, _io__RawIOBase_read__doc__}, + {"read", _PyCFunction_CAST(_io__RawIOBase_read), METH_FASTCALL, _io__RawIOBase_read__doc__}, static PyObject * _io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n); @@ -310,4 +316,4 @@ _io__RawIOBase_readall(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _io__RawIOBase_readall_impl(self); } -/*[clinic end generated code: output=83c1361a7a51ca84 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b7246a2087eb966b input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/stringio.c.h b/Modules/_io/clinic/stringio.c.h index 147ef668a0b..d495dd10c16 100644 --- a/Modules/_io/clinic/stringio.c.h +++ b/Modules/_io/clinic/stringio.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io_StringIO_getvalue__doc__, "getvalue($self, /)\n" "--\n" @@ -48,7 +54,7 @@ PyDoc_STRVAR(_io_StringIO_read__doc__, "is reached. Return an empty string at EOF."); #define _IO_STRINGIO_READ_METHODDEF \ - {"read", (PyCFunction)(void(*)(void))_io_StringIO_read, METH_FASTCALL, _io_StringIO_read__doc__}, + {"read", _PyCFunction_CAST(_io_StringIO_read), METH_FASTCALL, _io_StringIO_read__doc__}, static PyObject * _io_StringIO_read_impl(stringio *self, Py_ssize_t size); @@ -84,7 +90,7 @@ PyDoc_STRVAR(_io_StringIO_readline__doc__, "Returns an empty string if EOF is hit immediately."); #define _IO_STRINGIO_READLINE_METHODDEF \ - {"readline", (PyCFunction)(void(*)(void))_io_StringIO_readline, METH_FASTCALL, _io_StringIO_readline__doc__}, + {"readline", _PyCFunction_CAST(_io_StringIO_readline), METH_FASTCALL, _io_StringIO_readline__doc__}, static PyObject * _io_StringIO_readline_impl(stringio *self, Py_ssize_t size); @@ -122,7 +128,7 @@ PyDoc_STRVAR(_io_StringIO_truncate__doc__, "Returns the new absolute position."); #define _IO_STRINGIO_TRUNCATE_METHODDEF \ - {"truncate", (PyCFunction)(void(*)(void))_io_StringIO_truncate, METH_FASTCALL, _io_StringIO_truncate__doc__}, + {"truncate", _PyCFunction_CAST(_io_StringIO_truncate), METH_FASTCALL, _io_StringIO_truncate__doc__}, static PyObject * _io_StringIO_truncate_impl(stringio *self, Py_ssize_t size); @@ -162,7 +168,7 @@ PyDoc_STRVAR(_io_StringIO_seek__doc__, "Returns the new absolute position."); #define _IO_STRINGIO_SEEK_METHODDEF \ - {"seek", (PyCFunction)(void(*)(void))_io_StringIO_seek, METH_FASTCALL, _io_StringIO_seek__doc__}, + {"seek", _PyCFunction_CAST(_io_StringIO_seek), METH_FASTCALL, _io_StringIO_seek__doc__}, static PyObject * _io_StringIO_seek_impl(stringio *self, Py_ssize_t pos, int whence); @@ -255,8 +261,31 @@ static int _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(initial_value), &_Py_ID(newline), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"initial_value", "newline", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "StringIO", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "StringIO", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -338,4 +367,4 @@ _io_StringIO_seekable(stringio *self, PyObject *Py_UNUSED(ignored)) { return _io_StringIO_seekable_impl(self); } -/*[clinic end generated code: output=eea93dcab10d0a97 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=533f20ae9b773126 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h index 0b047ac0aab..db968e884cc 100644 --- a/Modules/_io/clinic/textio.c.h +++ b/Modules/_io/clinic/textio.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io_IncrementalNewlineDecoder___init____doc__, "IncrementalNewlineDecoder(decoder, translate, errors=\'strict\')\n" "--\n" @@ -24,8 +30,31 @@ static int _io_IncrementalNewlineDecoder___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(decoder), &_Py_ID(translate), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"decoder", "translate", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "IncrementalNewlineDecoder", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "IncrementalNewlineDecoder", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -39,8 +68,8 @@ _io_IncrementalNewlineDecoder___init__(PyObject *self, PyObject *args, PyObject goto exit; } decoder = fastargs[0]; - translate = _PyLong_AsInt(fastargs[1]); - if (translate == -1 && PyErr_Occurred()) { + translate = PyObject_IsTrue(fastargs[1]); + if (translate < 0) { goto exit; } if (!noptargs) { @@ -60,7 +89,7 @@ PyDoc_STRVAR(_io_IncrementalNewlineDecoder_decode__doc__, "\n"); #define _IO_INCREMENTALNEWLINEDECODER_DECODE_METHODDEF \ - {"decode", (PyCFunction)(void(*)(void))_io_IncrementalNewlineDecoder_decode, METH_FASTCALL|METH_KEYWORDS, _io_IncrementalNewlineDecoder_decode__doc__}, + {"decode", _PyCFunction_CAST(_io_IncrementalNewlineDecoder_decode), METH_FASTCALL|METH_KEYWORDS, _io_IncrementalNewlineDecoder_decode__doc__}, static PyObject * _io_IncrementalNewlineDecoder_decode_impl(nldecoder_object *self, @@ -70,8 +99,31 @@ static PyObject * _io_IncrementalNewlineDecoder_decode(nldecoder_object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(input), &_Py_ID(final), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"input", "final", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *input; @@ -85,8 +137,8 @@ _io_IncrementalNewlineDecoder_decode(nldecoder_object *self, PyObject *const *ar if (!noptargs) { goto skip_optional_pos; } - final = _PyLong_AsInt(args[1]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[1]); + if (final < 0) { goto exit; } skip_optional_pos: @@ -146,7 +198,7 @@ PyDoc_STRVAR(_io_TextIOWrapper___init____doc__, "Character and line based layer over a BufferedIOBase object, buffer.\n" "\n" "encoding gives the name of the encoding that the stream will be\n" -"decoded or encoded with. It defaults to locale.getpreferredencoding(False).\n" +"decoded or encoded with. It defaults to locale.getencoding().\n" "\n" "errors determines the strictness of encoding and decoding (see\n" "help(codecs.Codec) or the documentation for codecs.register) and\n" @@ -182,8 +234,31 @@ static int _io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 6 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(buffer), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(newline), &_Py_ID(line_buffering), &_Py_ID(write_through), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"buffer", "encoding", "errors", "newline", "line_buffering", "write_through", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "TextIOWrapper", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "TextIOWrapper", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -256,16 +331,16 @@ _io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) } } if (fastargs[4]) { - line_buffering = _PyLong_AsInt(fastargs[4]); - if (line_buffering == -1 && PyErr_Occurred()) { + line_buffering = PyObject_IsTrue(fastargs[4]); + if (line_buffering < 0) { goto exit; } if (!--noptargs) { goto skip_optional_pos; } } - write_through = _PyLong_AsInt(fastargs[5]); - if (write_through == -1 && PyErr_Occurred()) { + write_through = PyObject_IsTrue(fastargs[5]); + if (write_through < 0) { goto exit; } skip_optional_pos: @@ -285,7 +360,7 @@ PyDoc_STRVAR(_io_TextIOWrapper_reconfigure__doc__, "This also does an implicit stream flush."); #define _IO_TEXTIOWRAPPER_RECONFIGURE_METHODDEF \ - {"reconfigure", (PyCFunction)(void(*)(void))_io_TextIOWrapper_reconfigure, METH_FASTCALL|METH_KEYWORDS, _io_TextIOWrapper_reconfigure__doc__}, + {"reconfigure", _PyCFunction_CAST(_io_TextIOWrapper_reconfigure), METH_FASTCALL|METH_KEYWORDS, _io_TextIOWrapper_reconfigure__doc__}, static PyObject * _io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding, @@ -297,8 +372,31 @@ static PyObject * _io_TextIOWrapper_reconfigure(textio *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(newline), &_Py_ID(line_buffering), &_Py_ID(write_through), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"encoding", "errors", "newline", "line_buffering", "write_through", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "reconfigure", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "reconfigure", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *encoding = Py_None; @@ -400,7 +498,7 @@ PyDoc_STRVAR(_io_TextIOWrapper_read__doc__, "\n"); #define _IO_TEXTIOWRAPPER_READ_METHODDEF \ - {"read", (PyCFunction)(void(*)(void))_io_TextIOWrapper_read, METH_FASTCALL, _io_TextIOWrapper_read__doc__}, + {"read", _PyCFunction_CAST(_io_TextIOWrapper_read), METH_FASTCALL, _io_TextIOWrapper_read__doc__}, static PyObject * _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n); @@ -433,7 +531,7 @@ PyDoc_STRVAR(_io_TextIOWrapper_readline__doc__, "\n"); #define _IO_TEXTIOWRAPPER_READLINE_METHODDEF \ - {"readline", (PyCFunction)(void(*)(void))_io_TextIOWrapper_readline, METH_FASTCALL, _io_TextIOWrapper_readline__doc__}, + {"readline", _PyCFunction_CAST(_io_TextIOWrapper_readline), METH_FASTCALL, _io_TextIOWrapper_readline__doc__}, static PyObject * _io_TextIOWrapper_readline_impl(textio *self, Py_ssize_t size); @@ -475,7 +573,7 @@ PyDoc_STRVAR(_io_TextIOWrapper_seek__doc__, "\n"); #define _IO_TEXTIOWRAPPER_SEEK_METHODDEF \ - {"seek", (PyCFunction)(void(*)(void))_io_TextIOWrapper_seek, METH_FASTCALL, _io_TextIOWrapper_seek__doc__}, + {"seek", _PyCFunction_CAST(_io_TextIOWrapper_seek), METH_FASTCALL, _io_TextIOWrapper_seek__doc__}, static PyObject * _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence); @@ -528,7 +626,7 @@ PyDoc_STRVAR(_io_TextIOWrapper_truncate__doc__, "\n"); #define _IO_TEXTIOWRAPPER_TRUNCATE_METHODDEF \ - {"truncate", (PyCFunction)(void(*)(void))_io_TextIOWrapper_truncate, METH_FASTCALL, _io_TextIOWrapper_truncate__doc__}, + {"truncate", _PyCFunction_CAST(_io_TextIOWrapper_truncate), METH_FASTCALL, _io_TextIOWrapper_truncate__doc__}, static PyObject * _io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos); @@ -671,4 +769,4 @@ _io_TextIOWrapper_close(textio *self, PyObject *Py_UNUSED(ignored)) { return _io_TextIOWrapper_close_impl(self); } -/*[clinic end generated code: output=2604c8f3a45b9a03 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=73f84b13c343b34b input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/winconsoleio.c.h b/Modules/_io/clinic/winconsoleio.c.h index 84e73dcaf70..df834dbde40 100644 --- a/Modules/_io/clinic/winconsoleio.c.h +++ b/Modules/_io/clinic/winconsoleio.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(MS_WINDOWS) PyDoc_STRVAR(_io__WindowsConsoleIO_close__doc__, @@ -48,8 +54,31 @@ static int _io__WindowsConsoleIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(mode), &_Py_ID(closefd), &_Py_ID(opener), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"file", "mode", "closefd", "opener", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_WindowsConsoleIO", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_WindowsConsoleIO", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -86,8 +115,8 @@ _io__WindowsConsoleIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) } } if (fastargs[2]) { - closefd = _PyLong_AsInt(fastargs[2]); - if (closefd == -1 && PyErr_Occurred()) { + closefd = PyObject_IsTrue(fastargs[2]); + if (closefd < 0) { goto exit; } if (!--noptargs) { @@ -249,7 +278,7 @@ PyDoc_STRVAR(_io__WindowsConsoleIO_read__doc__, "Return an empty bytes object at EOF."); #define _IO__WINDOWSCONSOLEIO_READ_METHODDEF \ - {"read", (PyCFunction)(void(*)(void))_io__WindowsConsoleIO_read, METH_FASTCALL, _io__WindowsConsoleIO_read__doc__}, + {"read", _PyCFunction_CAST(_io__WindowsConsoleIO_read), METH_FASTCALL, _io__WindowsConsoleIO_read__doc__}, static PyObject * _io__WindowsConsoleIO_read_impl(winconsoleio *self, Py_ssize_t size); @@ -378,4 +407,4 @@ _io__WindowsConsoleIO_isatty(winconsoleio *self, PyObject *Py_UNUSED(ignored)) #ifndef _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF #define _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF #endif /* !defined(_IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF) */ -/*[clinic end generated code: output=48080572ffee22f5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4920e9068e0cf08a input=a9049054013a1b77]*/ diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index dd215e89399..d1a183cedac 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -72,8 +72,6 @@ typedef struct { PyTypeObject PyFileIO_Type; -_Py_IDENTIFIER(name); - #define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type)) /* Forward declarations */ @@ -146,9 +144,8 @@ _io_FileIO_close_impl(fileio *self) PyObject *res; PyObject *exc, *val, *tb; int rc; - _Py_IDENTIFIER(close); - res = _PyObject_CallMethodIdOneArg((PyObject*)&PyRawIOBase_Type, - &PyId_close, (PyObject *)self); + res = PyObject_CallMethodOneArg((PyObject*)&PyRawIOBase_Type, + &_Py_ID(close), (PyObject *)self); if (!self->closefd) { self->fd = -1; return res; @@ -201,7 +198,7 @@ extern int _Py_open_cloexec_works; _io.FileIO.__init__ file as nameobj: object mode: str = "r" - closefd: bool(accept={int}) = True + closefd: bool = True opener: object = None Open a file. @@ -222,7 +219,7 @@ results in functionality similar to passing None). static int _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, int closefd, PyObject *opener) -/*[clinic end generated code: output=23413f68e6484bbd input=1596c9157a042a39]*/ +/*[clinic end generated code: output=23413f68e6484bbd input=588aac967e0ba74b]*/ { #ifdef MS_WINDOWS Py_UNICODE *widename = NULL; @@ -271,14 +268,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, if (!PyUnicode_FSDecoder(nameobj, &stringobj)) { return -1; } -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - widename = PyUnicode_AsUnicode(stringobj); -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ widename = PyUnicode_AsWideCharString(stringobj, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (widename == NULL) return -1; #else @@ -476,7 +466,7 @@ _Py_COMP_DIAG_POP _setmode(self->fd, O_BINARY); #endif - if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0) + if (PyObject_SetAttr((PyObject *)self, &_Py_ID(name), nameobj) < 0) goto error; if (self->appending) { @@ -495,14 +485,16 @@ _Py_COMP_DIAG_POP ret = -1; if (!fd_is_own) self->fd = -1; - if (self->fd >= 0) + if (self->fd >= 0) { + PyObject *exc, *val, *tb; + PyErr_Fetch(&exc, &val, &tb); internal_close(self); + _PyErr_ChainExceptions(exc, val, tb); + } done: #ifdef MS_WINDOWS -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(widename); -#endif /* USE_UNICODE_WCHAR_CACHE */ #endif Py_CLEAR(stringobj); return ret; @@ -1085,7 +1077,7 @@ fileio_repr(fileio *self) if (self->fd < 0) return PyUnicode_FromFormat("<_io.FileIO [closed]>"); - if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) { + if (_PyObject_LookupAttr((PyObject *) self, &_Py_ID(name), &nameobj) < 0) { return NULL; } if (nameobj == NULL) { diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 5b687b78176..7b9391ec54d 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -34,8 +34,7 @@ typedef struct { } iobase; PyDoc_STRVAR(iobase_doc, - "The abstract base class for all I/O classes, acting on streams of\n" - "bytes. There is no public constructor.\n" + "The abstract base class for all I/O classes.\n" "\n" "This class provides dummy implementations for many methods that\n" "derived classes can override selectively; the default implementations\n" @@ -69,9 +68,6 @@ PyDoc_STRVAR(iobase_doc, of the IOBase object rather than the virtual `closed` attribute as returned by whatever subclass. */ -_Py_IDENTIFIER(__IOBase_closed); -_Py_IDENTIFIER(read); - /* Internal methods */ static PyObject * @@ -114,9 +110,7 @@ static PyObject * _io__IOBase_tell_impl(PyObject *self) /*[clinic end generated code: output=89a1c0807935abe2 input=04e615fec128801f]*/ { - _Py_IDENTIFIER(seek); - - return _PyObject_CallMethodId(self, &PyId_seek, "ii", 0, 1); + return _PyObject_CallMethod(self, &_Py_ID(seek), "ii", 0, 1); } PyDoc_STRVAR(iobase_truncate_doc, @@ -138,7 +132,7 @@ iobase_is_closed(PyObject *self) int ret; /* This gets the derived attribute, which is *not* __IOBase_closed in most cases! */ - ret = _PyObject_LookupAttrId(self, &PyId___IOBase_closed, &res); + ret = _PyObject_LookupAttr(self, &_Py_ID(__IOBase_closed), &res); Py_XDECREF(res); return ret; } @@ -186,7 +180,7 @@ iobase_check_closed(PyObject *self) int closed; /* This gets the derived attribute, which is *not* __IOBase_closed in most cases! */ - closed = _PyObject_LookupAttr(self, _PyIO_str_closed, &res); + closed = _PyObject_LookupAttr(self, &_Py_ID(closed), &res); if (closed > 0) { closed = PyObject_IsTrue(res); Py_DECREF(res); @@ -236,10 +230,10 @@ _io__IOBase_close_impl(PyObject *self) Py_RETURN_NONE; } - res = PyObject_CallMethodNoArgs(self, _PyIO_str_flush); + res = PyObject_CallMethodNoArgs(self, &_Py_ID(flush)); PyErr_Fetch(&exc, &val, &tb); - rc = _PyObject_SetAttrId(self, &PyId___IOBase_closed, Py_True); + rc = PyObject_SetAttr(self, &_Py_ID(__IOBase_closed), Py_True); _PyErr_ChainExceptions(exc, val, tb); if (rc < 0) { Py_CLEAR(res); @@ -260,14 +254,13 @@ iobase_finalize(PyObject *self) PyObject *res; PyObject *error_type, *error_value, *error_traceback; int closed; - _Py_IDENTIFIER(_finalizing); /* Save the current exception, if any. */ PyErr_Fetch(&error_type, &error_value, &error_traceback); /* If `closed` doesn't exist or can't be evaluated as bool, then the object is probably in an unusable state, so ignore. */ - if (_PyObject_LookupAttr(self, _PyIO_str_closed, &res) <= 0) { + if (_PyObject_LookupAttr(self, &_Py_ID(closed), &res) <= 0) { PyErr_Clear(); closed = -1; } @@ -280,9 +273,9 @@ iobase_finalize(PyObject *self) if (closed == 0) { /* Signal close() that it was called as part of the object finalization process. */ - if (_PyObject_SetAttrId(self, &PyId__finalizing, Py_True)) + if (PyObject_SetAttr(self, &_Py_ID(_finalizing), Py_True)) PyErr_Clear(); - res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_close); + res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(close)); /* Silencing I/O errors is bad, but printing spurious tracebacks is equally as bad, and potentially more frequent (because of shutdown issues). */ @@ -383,7 +376,7 @@ _io__IOBase_seekable_impl(PyObject *self) PyObject * _PyIOBase_check_seekable(PyObject *self, PyObject *args) { - PyObject *res = PyObject_CallMethodNoArgs(self, _PyIO_str_seekable); + PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(seekable)); if (res == NULL) return NULL; if (res != Py_True) { @@ -416,7 +409,7 @@ _io__IOBase_readable_impl(PyObject *self) PyObject * _PyIOBase_check_readable(PyObject *self, PyObject *args) { - PyObject *res = PyObject_CallMethodNoArgs(self, _PyIO_str_readable); + PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(readable)); if (res == NULL) return NULL; if (res != Py_True) { @@ -449,7 +442,7 @@ _io__IOBase_writable_impl(PyObject *self) PyObject * _PyIOBase_check_writable(PyObject *self, PyObject *args) { - PyObject *res = PyObject_CallMethodNoArgs(self, _PyIO_str_writable); + PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(writable)); if (res == NULL) return NULL; if (res != Py_True) { @@ -471,14 +464,13 @@ iobase_enter(PyObject *self, PyObject *args) if (iobase_check_closed(self)) return NULL; - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * iobase_exit(PyObject *self, PyObject *args) { - return PyObject_CallMethodNoArgs(self, _PyIO_str_close); + return PyObject_CallMethodNoArgs(self, &_Py_ID(close)); } /* Lower-level APIs */ @@ -542,7 +534,7 @@ _io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit) PyObject *peek, *buffer, *result; Py_ssize_t old_size = -1; - if (_PyObject_LookupAttr(self, _PyIO_str_peek, &peek) < 0) { + if (_PyObject_LookupAttr(self, &_Py_ID(peek), &peek) < 0) { return NULL; } @@ -597,7 +589,7 @@ _io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit) Py_DECREF(readahead); } - b = _PyObject_CallMethodId(self, &PyId_read, "n", nreadahead); + b = _PyObject_CallMethod(self, &_Py_ID(read), "n", nreadahead); if (b == NULL) { /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR occurs so we needn't do it ourselves. */ @@ -649,14 +641,13 @@ iobase_iter(PyObject *self) if (iobase_check_closed(self)) return NULL; - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * iobase_iternext(PyObject *self) { - PyObject *line = PyObject_CallMethodNoArgs(self, _PyIO_str_readline); + PyObject *line = PyObject_CallMethodNoArgs(self, &_Py_ID(readline)); if (line == NULL) return NULL; @@ -697,10 +688,8 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) /* XXX special-casing this made sense in the Python version in order to remove the bytecode interpretation overhead, but it could probably be removed here. */ - _Py_IDENTIFIER(extend); - PyObject *ret = _PyObject_CallMethodIdObjArgs(result, &PyId_extend, - self, NULL); - + PyObject *ret = PyObject_CallMethodObjArgs(result, &_Py_ID(extend), + self, NULL); if (ret == NULL) { goto error; } @@ -784,7 +773,7 @@ _io__IOBase_writelines(PyObject *self, PyObject *lines) res = NULL; do { - res = PyObject_CallMethodObjArgs(self, _PyIO_str_write, line, NULL); + res = PyObject_CallMethodObjArgs(self, &_Py_ID(write), line, NULL); } while (res == NULL && _PyIO_trap_eintr()); Py_DECREF(line); if (res == NULL) { @@ -919,9 +908,7 @@ _io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n) PyObject *b, *res; if (n < 0) { - _Py_IDENTIFIER(readall); - - return _PyObject_CallMethodIdNoArgs(self, &PyId_readall); + return PyObject_CallMethodNoArgs(self, &_Py_ID(readall)); } /* TODO: allocate a bytes object directly instead and manually construct @@ -930,7 +917,7 @@ _io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n) if (b == NULL) return NULL; - res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL); + res = PyObject_CallMethodObjArgs(self, &_Py_ID(readinto), b, NULL); if (res == NULL || res == Py_None) { Py_DECREF(b); return res; @@ -967,8 +954,8 @@ _io__RawIOBase_readall_impl(PyObject *self) return NULL; while (1) { - PyObject *data = _PyObject_CallMethodId(self, &PyId_read, - "i", DEFAULT_BUFFER_SIZE); + PyObject *data = _PyObject_CallMethod(self, &_Py_ID(read), + "i", DEFAULT_BUFFER_SIZE); if (!data) { /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR occurs so we needn't do it ourselves. */ @@ -1004,7 +991,7 @@ _io__RawIOBase_readall_impl(PyObject *self) return NULL; } } - result = _PyBytes_Join(_PyIO_empty_bytes, chunks); + result = _PyBytes_Join((PyObject *)&_Py_SINGLETON(bytes_empty), chunks); Py_DECREF(chunks); return result; } diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index e76152e617b..ae6c3125a2d 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -1,7 +1,6 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" #include // offsetof() -#include "pycore_accu.h" #include "pycore_object.h" #include "_iomodule.h" @@ -27,12 +26,12 @@ typedef struct { /* The stringio object can be in two states: accumulating or realized. In accumulating state, the internal buffer contains nothing and - the contents are given by the embedded _PyAccu structure. + the contents are given by the embedded _PyUnicodeWriter structure. In realized state, the internal buffer is meaningful and the - _PyAccu is destroyed. + _PyUnicodeWriter is destroyed. */ int state; - _PyAccu accu; + _PyUnicodeWriter writer; char ok; /* initialized? */ char closed; @@ -126,12 +125,14 @@ resize_buffer(stringio *self, size_t size) static PyObject * make_intermediate(stringio *self) { - PyObject *intermediate = _PyAccu_Finish(&self->accu); + PyObject *intermediate = _PyUnicodeWriter_Finish(&self->writer); self->state = STATE_REALIZED; if (intermediate == NULL) return NULL; - if (_PyAccu_Init(&self->accu) || - _PyAccu_Accumulate(&self->accu, intermediate)) { + + _PyUnicodeWriter_Init(&self->writer); + self->writer.overallocate = 1; + if (_PyUnicodeWriter_WriteStr(&self->writer, intermediate)) { Py_DECREF(intermediate); return NULL; } @@ -150,7 +151,7 @@ realize(stringio *self) assert(self->state == STATE_ACCUMULATING); self->state = STATE_REALIZED; - intermediate = _PyAccu_Finish(&self->accu); + intermediate = _PyUnicodeWriter_Finish(&self->writer); if (intermediate == NULL) return -1; @@ -187,14 +188,12 @@ write_str(stringio *self, PyObject *obj) self->decoder, obj, 1 /* always final */); } else { - decoded = obj; - Py_INCREF(decoded); + decoded = Py_NewRef(obj); } if (self->writenl) { PyObject *translated = PyUnicode_Replace( - decoded, _PyIO_str_nl, self->writenl, -1); - Py_DECREF(decoded); - decoded = translated; + decoded, &_Py_STR(newline), self->writenl, -1); + Py_SETREF(decoded, translated); } if (decoded == NULL) return -1; @@ -218,7 +217,7 @@ write_str(stringio *self, PyObject *obj) if (self->state == STATE_ACCUMULATING) { if (self->string_size == self->pos) { - if (_PyAccu_Accumulate(&self->accu, decoded)) + if (_PyUnicodeWriter_WriteStr(&self->writer, decoded)) goto fail; goto success; } @@ -409,7 +408,7 @@ stringio_iternext(stringio *self) else { /* XXX is subclassing StringIO really supported? */ line = PyObject_CallMethodNoArgs((PyObject *)self, - _PyIO_str_readline); + &_Py_ID(readline)); if (line && !PyUnicode_Check(line)) { PyErr_Format(PyExc_OSError, "readline() should have returned a str object, " @@ -572,7 +571,7 @@ _io_StringIO_close_impl(stringio *self) /* Free up some memory */ if (resize_buffer(self, 0) < 0) return NULL; - _PyAccu_Destroy(&self->accu); + _PyUnicodeWriter_Dealloc(&self->writer); Py_CLEAR(self->readnl); Py_CLEAR(self->writenl); Py_CLEAR(self->decoder); @@ -602,7 +601,7 @@ stringio_dealloc(stringio *self) PyMem_Free(self->buf); self->buf = NULL; } - _PyAccu_Destroy(&self->accu); + _PyUnicodeWriter_Dealloc(&self->writer); Py_CLEAR(self->readnl); Py_CLEAR(self->writenl); Py_CLEAR(self->decoder); @@ -687,7 +686,7 @@ _io_StringIO___init___impl(stringio *self, PyObject *value, self->ok = 0; - _PyAccu_Destroy(&self->accu); + _PyUnicodeWriter_Dealloc(&self->writer); Py_CLEAR(self->readnl); Py_CLEAR(self->writenl); Py_CLEAR(self->decoder); @@ -709,8 +708,7 @@ _io_StringIO___init___impl(stringio *self, PyObject *value, is pointless for StringIO) */ if (newline != NULL && newline[0] == '\r') { - self->writenl = self->readnl; - Py_INCREF(self->writenl); + self->writenl = Py_NewRef(self->readnl); } if (self->readuniversal) { @@ -742,8 +740,8 @@ _io_StringIO___init___impl(stringio *self, PyObject *value, /* Empty stringio object, we can start by accumulating */ if (resize_buffer(self, 0) < 0) return -1; - if (_PyAccu_Init(&self->accu)) - return -1; + _PyUnicodeWriter_Init(&self->writer); + self->writer.overallocate = 1; self->state = STATE_ACCUMULATING; } self->pos = 0; @@ -822,8 +820,7 @@ stringio_getstate(stringio *self, PyObject *Py_UNUSED(ignored)) if (initvalue == NULL) return NULL; if (self->dict == NULL) { - Py_INCREF(Py_None); - dict = Py_None; + dict = Py_NewRef(Py_None); } else { dict = PyDict_Copy(self->dict); @@ -933,8 +930,7 @@ stringio_setstate(stringio *self, PyObject *state) return NULL; } else { - Py_INCREF(dict); - self->dict = dict; + self->dict = Py_NewRef(dict); } } @@ -964,7 +960,7 @@ stringio_newlines(stringio *self, void *context) CHECK_CLOSED(self); if (self->decoder == NULL) Py_RETURN_NONE; - return PyObject_GetAttr(self->decoder, _PyIO_str_newlines); + return PyObject_GetAttr(self->decoder, &_Py_ID(newlines)); } #include "clinic/stringio.c.h" diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index eb05ae1a16e..32ab8a44c62 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -19,29 +19,9 @@ /*[clinic input] module _io class _io.IncrementalNewlineDecoder "nldecoder_object *" "&PyIncrementalNewlineDecoder_Type" -class _io.TextIOWrapper "textio *" "&TextIOWrapper_TYpe" +class _io.TextIOWrapper "textio *" "&TextIOWrapper_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2097a4fc85670c26]*/ - -_Py_IDENTIFIER(close); -_Py_IDENTIFIER(_dealloc_warn); -_Py_IDENTIFIER(decode); -_Py_IDENTIFIER(fileno); -_Py_IDENTIFIER(flush); -_Py_IDENTIFIER(isatty); -_Py_IDENTIFIER(mode); -_Py_IDENTIFIER(name); -_Py_IDENTIFIER(raw); -_Py_IDENTIFIER(read); -_Py_IDENTIFIER(readable); -_Py_IDENTIFIER(replace); -_Py_IDENTIFIER(reset); -_Py_IDENTIFIER(seek); -_Py_IDENTIFIER(seekable); -_Py_IDENTIFIER(setstate); -_Py_IDENTIFIER(strict); -_Py_IDENTIFIER(tell); -_Py_IDENTIFIER(writable); +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ed072384f8aada2c]*/ /* TextIOBase */ @@ -50,7 +30,7 @@ PyDoc_STRVAR(textiobase_doc, "\n" "This class provides a character and line based interface to stream\n" "I/O. There is no readinto method because Python's character strings\n" - "are immutable. There is no public constructor.\n" + "are immutable.\n" ); static PyObject * @@ -232,7 +212,7 @@ typedef struct { /*[clinic input] _io.IncrementalNewlineDecoder.__init__ decoder: object - translate: int + translate: bool errors: object(c_default="NULL") = "strict" Codec used when reading a file in universal newlines mode. @@ -249,21 +229,18 @@ static int _io_IncrementalNewlineDecoder___init___impl(nldecoder_object *self, PyObject *decoder, int translate, PyObject *errors) -/*[clinic end generated code: output=fbd04d443e764ec2 input=89db6b19c6b126bf]*/ +/*[clinic end generated code: output=fbd04d443e764ec2 input=ed547aa257616b0e]*/ { - self->decoder = decoder; - Py_INCREF(decoder); if (errors == NULL) { - self->errors = _PyUnicode_FromId(&PyId_strict); - if (self->errors == NULL) - return -1; + errors = Py_NewRef(&_Py_ID(strict)); } else { - self->errors = errors; + errors = Py_NewRef(errors); } - Py_INCREF(self->errors); + Py_XSETREF(self->errors, errors); + Py_XSETREF(self->decoder, Py_NewRef(decoder)); self->translate = translate ? 1 : 0; self->seennl = 0; self->pendingcr = 0; @@ -298,6 +275,13 @@ check_decoded(PyObject *decoded) return 0; } +#define CHECK_INITIALIZED_DECODER(self) \ + if (self->errors == NULL) { \ + PyErr_SetString(PyExc_ValueError, \ + "IncrementalNewlineDecoder.__init__() not called"); \ + return NULL; \ + } + #define SEEN_CR 1 #define SEEN_LF 2 #define SEEN_CRLF 4 @@ -311,20 +295,15 @@ _PyIncrementalNewlineDecoder_decode(PyObject *myself, Py_ssize_t output_len; nldecoder_object *self = (nldecoder_object *) myself; - if (self->decoder == NULL) { - PyErr_SetString(PyExc_ValueError, - "IncrementalNewlineDecoder.__init__ not called"); - return NULL; - } + CHECK_INITIALIZED_DECODER(self); /* decode input (with the eventual \r from a previous pass) */ if (self->decoder != Py_None) { output = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_decode, input, final ? Py_True : Py_False, NULL); + &_Py_ID(decode), input, final ? Py_True : Py_False, NULL); } else { - output = input; - Py_INCREF(output); + output = Py_NewRef(input); } if (check_decoded(output) < 0) @@ -345,8 +324,7 @@ _PyIncrementalNewlineDecoder_decode(PyObject *myself, out = PyUnicode_DATA(modified); PyUnicode_WRITE(kind, out, 0, '\r'); memcpy(out + kind, PyUnicode_DATA(output), kind * output_len); - Py_DECREF(output); - output = modified; /* output remains ready */ + Py_SETREF(output, modified); /* output remains ready */ self->pendingcr = 0; output_len++; } @@ -361,8 +339,7 @@ _PyIncrementalNewlineDecoder_decode(PyObject *myself, PyObject *modified = PyUnicode_Substring(output, 0, output_len -1); if (modified == NULL) goto error; - Py_DECREF(output); - output = modified; + Py_SETREF(output, modified); self->pendingcr = 1; } } @@ -507,13 +484,13 @@ _PyIncrementalNewlineDecoder_decode(PyObject *myself, /*[clinic input] _io.IncrementalNewlineDecoder.decode input: object - final: bool(accept={int}) = False + final: bool = False [clinic start generated code]*/ static PyObject * _io_IncrementalNewlineDecoder_decode_impl(nldecoder_object *self, PyObject *input, int final) -/*[clinic end generated code: output=0d486755bb37a66e input=a4ea97f26372d866]*/ +/*[clinic end generated code: output=0d486755bb37a66e input=90e223c70322c5cd]*/ { return _PyIncrementalNewlineDecoder_decode((PyObject *) self, input, final); } @@ -529,9 +506,11 @@ _io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self) PyObject *buffer; unsigned long long flag; + CHECK_INITIALIZED_DECODER(self); + if (self->decoder != Py_None) { PyObject *state = PyObject_CallMethodNoArgs(self->decoder, - _PyIO_str_getstate); + &_Py_ID(getstate)); if (state == NULL) return NULL; if (!PyTuple_Check(state)) { @@ -573,6 +552,8 @@ _io_IncrementalNewlineDecoder_setstate(nldecoder_object *self, PyObject *buffer; unsigned long long flag; + CHECK_INITIALIZED_DECODER(self); + if (!PyTuple_Check(state)) { PyErr_SetString(PyExc_TypeError, "state argument must be a tuple"); return NULL; @@ -586,11 +567,13 @@ _io_IncrementalNewlineDecoder_setstate(nldecoder_object *self, self->pendingcr = (int) (flag & 1); flag >>= 1; - if (self->decoder != Py_None) - return _PyObject_CallMethodId(self->decoder, - &PyId_setstate, "((OK))", buffer, flag); - else + if (self->decoder != Py_None) { + return _PyObject_CallMethod(self->decoder, &_Py_ID(setstate), + "((OK))", buffer, flag); + } + else { Py_RETURN_NONE; + } } /*[clinic input] @@ -601,10 +584,12 @@ static PyObject * _io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self) /*[clinic end generated code: output=32fa40c7462aa8ff input=728678ddaea776df]*/ { + CHECK_INITIALIZED_DECODER(self); + self->seennl = 0; self->pendingcr = 0; if (self->decoder != Py_None) - return PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_reset); + return PyObject_CallMethodNoArgs(self->decoder, &_Py_ID(reset)); else Py_RETURN_NONE; } @@ -612,6 +597,8 @@ _io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self) static PyObject * incrementalnewlinedecoder_newlines_get(nldecoder_object *self, void *context) { + CHECK_INITIALIZED_DECODER(self); + switch (self->seennl) { case SEEN_CR: return PyUnicode_FromString("\r"); @@ -865,7 +852,7 @@ _textiowrapper_set_decoder(textio *self, PyObject *codec_info, PyObject *res; int r; - res = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_readable); + res = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(readable)); if (res == NULL) return -1; @@ -888,8 +875,7 @@ _textiowrapper_set_decoder(textio *self, PyObject *codec_info, self->decoder, self->readtranslate ? Py_True : Py_False, NULL); if (incrementalDecoder == NULL) return -1; - Py_CLEAR(self->decoder); - self->decoder = incrementalDecoder; + Py_XSETREF(self->decoder, incrementalDecoder); } return 0; @@ -903,7 +889,7 @@ _textiowrapper_decode(PyObject *decoder, PyObject *bytes, int eof) if (Py_IS_TYPE(decoder, &PyIncrementalNewlineDecoder_Type)) chars = _PyIncrementalNewlineDecoder_decode(decoder, bytes, eof); else - chars = PyObject_CallMethodObjArgs(decoder, _PyIO_str_decode, bytes, + chars = PyObject_CallMethodObjArgs(decoder, &_Py_ID(decode), bytes, eof ? Py_True : Py_False, NULL); if (check_decoded(chars) < 0) @@ -920,7 +906,7 @@ _textiowrapper_set_encoder(textio *self, PyObject *codec_info, PyObject *res; int r; - res = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_writable); + res = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(writable)); if (res == NULL) return -1; @@ -939,7 +925,7 @@ _textiowrapper_set_encoder(textio *self, PyObject *codec_info, return -1; /* Get the normalized named of the codec */ - if (_PyObject_LookupAttrId(codec_info, &PyId_name, &res) < 0) { + if (_PyObject_LookupAttr(codec_info, &_Py_ID(name), &res) < 0) { return -1; } if (res != NULL && PyUnicode_Check(res)) { @@ -967,7 +953,7 @@ _textiowrapper_fix_encoder_state(textio *self) self->encoding_start_of_stream = 1; PyObject *cookieObj = PyObject_CallMethodNoArgs( - self->buffer, _PyIO_str_tell); + self->buffer, &_Py_ID(tell)); if (cookieObj == NULL) { return -1; } @@ -981,7 +967,7 @@ _textiowrapper_fix_encoder_state(textio *self) if (cmp == 0) { self->encoding_start_of_stream = 0; PyObject *res = PyObject_CallMethodOneArg( - self->encoder, _PyIO_str_setstate, _PyLong_GetZero()); + self->encoder, &_Py_ID(setstate), _PyLong_GetZero()); if (res == NULL) { return -1; } @@ -1037,13 +1023,13 @@ _io.TextIOWrapper.__init__ encoding: str(accept={str, NoneType}) = None errors: object = None newline: str(accept={str, NoneType}) = None - line_buffering: bool(accept={int}) = False - write_through: bool(accept={int}) = False + line_buffering: bool = False + write_through: bool = False Character and line based layer over a BufferedIOBase object, buffer. encoding gives the name of the encoding that the stream will be -decoded or encoded with. It defaults to locale.getpreferredencoding(False). +decoded or encoded with. It defaults to locale.getencoding(). errors determines the strictness of encoding and decoding (see help(codecs.Codec) or the documentation for codecs.register) and @@ -1075,10 +1061,9 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, const char *encoding, PyObject *errors, const char *newline, int line_buffering, int write_through) -/*[clinic end generated code: output=72267c0c01032ed2 input=77d8696d1a1f460b]*/ +/*[clinic end generated code: output=72267c0c01032ed2 input=e6cfaaaf6059d4f5]*/ { PyObject *raw, *codec_info = NULL; - _PyIO_State *state = NULL; PyObject *res; int r; @@ -1094,15 +1079,9 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, } } } - else if (strcmp(encoding, "locale") == 0) { - encoding = NULL; - } if (errors == Py_None) { - errors = _PyUnicode_FromId(&PyId_strict); /* borrowed */ - if (errors == NULL) { - return -1; - } + errors = &_Py_ID(strict); } else if (!PyUnicode_Check(errors)) { // Check 'errors' argument here because Argument Clinic doesn't support @@ -1136,44 +1115,18 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, self->encodefunc = NULL; self->b2cratio = 0.0; - if (encoding == NULL) { - /* Try os.device_encoding(fileno) */ - PyObject *fileno; - state = IO_STATE(); - if (state == NULL) - goto error; - fileno = _PyObject_CallMethodIdNoArgs(buffer, &PyId_fileno); - /* Ignore only AttributeError and UnsupportedOperation */ - if (fileno == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError) || - PyErr_ExceptionMatches(state->unsupported_operation)) { - PyErr_Clear(); - } - else { - goto error; - } - } - else { - int fd = _PyLong_AsInt(fileno); - Py_DECREF(fileno); - if (fd == -1 && PyErr_Occurred()) { - goto error; - } - - self->encoding = _Py_device_encoding(fd); - if (self->encoding == NULL) - goto error; - else if (!PyUnicode_Check(self->encoding)) - Py_CLEAR(self->encoding); - } + if (encoding == NULL && _PyRuntime.preconfig.utf8_mode) { + _Py_DECLARE_STR(utf_8, "utf-8"); + self->encoding = Py_NewRef(&_Py_STR(utf_8)); } - if (encoding == NULL && self->encoding == NULL) { + else if (encoding == NULL || (strcmp(encoding, "locale") == 0)) { self->encoding = _Py_GetLocaleEncodingObject(); if (self->encoding == NULL) { goto error; } assert(PyUnicode_Check(self->encoding)); } + if (self->encoding != NULL) { encoding = PyUnicode_AsUTF8(self->encoding); if (encoding == NULL) @@ -1201,8 +1154,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, * of the partially constructed object (like self->encoding) */ - Py_INCREF(errors); - self->errors = errors; + self->errors = Py_NewRef(errors); self->chunk_size = 8192; self->line_buffering = line_buffering; self->write_through = write_through; @@ -1210,8 +1162,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, goto error; } - self->buffer = buffer; - Py_INCREF(buffer); + self->buffer = Py_NewRef(buffer); /* Build the decoder object */ if (_textiowrapper_set_decoder(self, codec_info, PyUnicode_AsUTF8(errors)) != 0) @@ -1228,7 +1179,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, Py_IS_TYPE(buffer, &PyBufferedWriter_Type) || Py_IS_TYPE(buffer, &PyBufferedRandom_Type)) { - if (_PyObject_LookupAttrId(buffer, &PyId_raw, &raw) < 0) + if (_PyObject_LookupAttr(buffer, &_Py_ID(raw), &raw) < 0) goto error; /* Cache the raw FileIO object to speed up 'closed' checks */ if (raw != NULL) { @@ -1239,7 +1190,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, } } - res = _PyObject_CallMethodIdNoArgs(buffer, &PyId_seekable); + res = PyObject_CallMethodNoArgs(buffer, &_Py_ID(seekable)); if (res == NULL) goto error; r = PyObject_IsTrue(res); @@ -1248,7 +1199,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, goto error; self->seekable = self->telling = r; - r = _PyObject_LookupAttr(buffer, _PyIO_str_read1, &res); + r = _PyObject_LookupAttr(buffer, &_Py_ID(read1), &res); if (r < 0) { goto error; } @@ -1300,16 +1251,25 @@ textiowrapper_change_encoding(textio *self, PyObject *encoding, if (errors == Py_None) { errors = self->errors; } + Py_INCREF(encoding); } - else if (errors == Py_None) { - errors = _PyUnicode_FromId(&PyId_strict); - if (errors == NULL) { - return -1; + else { + if (_PyUnicode_EqualToASCIIString(encoding, "locale")) { + encoding = _Py_GetLocaleEncodingObject(); + if (encoding == NULL) { + return -1; + } + } else { + Py_INCREF(encoding); + } + if (errors == Py_None) { + errors = &_Py_ID(strict); } } const char *c_errors = PyUnicode_AsUTF8(errors); if (c_errors == NULL) { + Py_DECREF(encoding); return -1; } @@ -1317,19 +1277,19 @@ textiowrapper_change_encoding(textio *self, PyObject *encoding, PyObject *codec_info = _PyCodec_LookupTextEncoding( PyUnicode_AsUTF8(encoding), "codecs.open()"); if (codec_info == NULL) { + Py_DECREF(encoding); return -1; } if (_textiowrapper_set_decoder(self, codec_info, c_errors) != 0 || _textiowrapper_set_encoder(self, codec_info, c_errors) != 0) { Py_DECREF(codec_info); + Py_DECREF(encoding); return -1; } Py_DECREF(codec_info); - Py_INCREF(encoding); - Py_INCREF(errors); Py_SETREF(self->encoding, encoding); - Py_SETREF(self->errors, errors); + Py_SETREF(self->errors, Py_NewRef(errors)); return _textiowrapper_fix_encoder_state(self); } @@ -1384,7 +1344,7 @@ _io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding, return NULL; } - PyObject *res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); + PyObject *res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); if (res == NULL) { return NULL; } @@ -1523,7 +1483,7 @@ _io_TextIOWrapper_detach_impl(textio *self) { PyObject *buffer, *res; CHECK_ATTACHED(self); - res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); + res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); if (res == NULL) return NULL; Py_DECREF(res); @@ -1545,8 +1505,7 @@ _textiowrapper_writeflush(textio *self) PyObject *b; if (PyBytes_Check(pending)) { - b = pending; - Py_INCREF(b); + b = Py_NewRef(pending); } else if (PyUnicode_Check(pending)) { assert(PyUnicode_IS_ASCII(pending)); @@ -1595,7 +1554,7 @@ _textiowrapper_writeflush(textio *self) PyObject *ret; do { - ret = PyObject_CallMethodOneArg(self->buffer, _PyIO_str_write, b); + ret = PyObject_CallMethodOneArg(self->buffer, &_Py_ID(write), b); } while (ret == NULL && _PyIO_trap_eintr()); Py_DECREF(b); // NOTE: We cleared buffer but we don't know how many bytes are actually written @@ -1640,8 +1599,8 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text) haslf = 1; if (haslf && self->writetranslate && self->writenl != NULL) { - PyObject *newtext = _PyObject_CallMethodId( - text, &PyId_replace, "ss", "\n", self->writenl); + PyObject *newtext = _PyObject_CallMethod(text, &_Py_ID(replace), + "ss", "\n", self->writenl); Py_DECREF(text); if (newtext == NULL) return NULL; @@ -1661,8 +1620,7 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text) // See bpo-43260 PyUnicode_GET_LENGTH(text) <= self->chunk_size && is_asciicompat_encoding(self->encodefunc)) { - b = text; - Py_INCREF(b); + b = Py_NewRef(text); } else { b = (*self->encodefunc)((PyObject *) self, text); @@ -1670,7 +1628,7 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text) self->encoding_start_of_stream = 0; } else { - b = PyObject_CallMethodOneArg(self->encoder, _PyIO_str_encode, text); + b = PyObject_CallMethodOneArg(self->encoder, &_Py_ID(encode), text); } Py_DECREF(text); @@ -1730,7 +1688,7 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text) } if (needflush) { - ret = PyObject_CallMethodNoArgs(self->buffer, _PyIO_str_flush); + ret = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(flush)); if (ret == NULL) return NULL; Py_DECREF(ret); @@ -1740,7 +1698,7 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text) Py_CLEAR(self->snapshot); if (self->decoder) { - ret = _PyObject_CallMethodIdNoArgs(self->decoder, &PyId_reset); + ret = PyObject_CallMethodNoArgs(self->decoder, &_Py_ID(reset)); if (ret == NULL) return NULL; Py_DECREF(ret); @@ -1784,8 +1742,7 @@ textiowrapper_get_decoded_chars(textio *self, Py_ssize_t n) return NULL; } else { - chars = self->decoded_chars; - Py_INCREF(chars); + chars = Py_NewRef(self->decoded_chars); } self->decoded_chars_used += n; @@ -1821,7 +1778,7 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) * where the decoder's input buffer is empty. */ PyObject *state = PyObject_CallMethodNoArgs(self->decoder, - _PyIO_str_getstate); + &_Py_ID(getstate)); if (state == NULL) return -1; /* Given this, we know there was a valid snapshot point @@ -1862,7 +1819,7 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) goto fail; input_chunk = PyObject_CallMethodOneArg(self->buffer, - (self->has_read1 ? _PyIO_str_read1: _PyIO_str_read), + (self->has_read1 ? &_Py_ID(read1): &_Py_ID(read)), chunk_size); Py_DECREF(chunk_size); if (input_chunk == NULL) @@ -1944,7 +1901,7 @@ _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n) if (n < 0) { /* Read everything */ - PyObject *bytes = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_read); + PyObject *bytes = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(read)); PyObject *decoded; if (bytes == NULL) goto fail; @@ -1954,7 +1911,7 @@ _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n) bytes, 1); else decoded = PyObject_CallMethodObjArgs( - self->decoder, _PyIO_str_decode, bytes, Py_True, NULL); + self->decoder, &_Py_ID(decode), bytes, Py_True, NULL); Py_DECREF(bytes); if (check_decoded(decoded) < 0) goto fail; @@ -2015,7 +1972,8 @@ _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n) if (chunks != NULL) { if (result != NULL && PyList_Append(chunks, result) < 0) goto fail; - Py_XSETREF(result, PyUnicode_Join(_PyIO_empty_str, chunks)); + _Py_DECLARE_STR(empty, ""); + Py_XSETREF(result, PyUnicode_Join(&_Py_STR(empty), chunks)); if (result == NULL) goto fail; Py_CLEAR(chunks); @@ -2181,10 +2139,9 @@ _textiowrapper_readline(textio *self, Py_ssize_t limit) } if (remaining == NULL) { - line = self->decoded_chars; + line = Py_NewRef(self->decoded_chars); start = self->decoded_chars_used; offset_to_buffer = 0; - Py_INCREF(line); } else { assert(self->decoded_chars_used == 0); @@ -2280,14 +2237,13 @@ _textiowrapper_readline(textio *self, Py_ssize_t limit) goto error; Py_DECREF(line); } - line = PyUnicode_Join(_PyIO_empty_str, chunks); + line = PyUnicode_Join(&_Py_STR(empty), chunks); if (line == NULL) goto error; Py_CLEAR(chunks); } if (line == NULL) { - Py_INCREF(_PyIO_empty_str); - line = _PyIO_empty_str; + line = Py_NewRef(&_Py_STR(empty)); } return line; @@ -2404,13 +2360,16 @@ _textiowrapper_decoder_setstate(textio *self, cookie_type *cookie) at start is not (b"", 0) but e.g. (b"", 2) (meaning, in the case of utf-16, that we are expecting a BOM). */ - if (cookie->start_pos == 0 && cookie->dec_flags == 0) - res = PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_reset); - else - res = _PyObject_CallMethodId(self->decoder, &PyId_setstate, - "((yi))", "", cookie->dec_flags); - if (res == NULL) + if (cookie->start_pos == 0 && cookie->dec_flags == 0) { + res = PyObject_CallMethodNoArgs(self->decoder, &_Py_ID(reset)); + } + else { + res = _PyObject_CallMethod(self->decoder, &_Py_ID(setstate), + "((yi))", "", cookie->dec_flags); + } + if (res == NULL) { return -1; + } Py_DECREF(res); return 0; } @@ -2420,11 +2379,11 @@ _textiowrapper_encoder_reset(textio *self, int start_of_stream) { PyObject *res; if (start_of_stream) { - res = PyObject_CallMethodNoArgs(self->encoder, _PyIO_str_reset); + res = PyObject_CallMethodNoArgs(self->encoder, &_Py_ID(reset)); self->encoding_start_of_stream = 1; } else { - res = PyObject_CallMethodOneArg(self->encoder, _PyIO_str_setstate, + res = PyObject_CallMethodOneArg(self->encoder, &_Py_ID(setstate), _PyLong_GetZero()); self->encoding_start_of_stream = 0; } @@ -2487,7 +2446,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) * sync the underlying buffer with the current position. */ Py_DECREF(cookieObj); - cookieObj = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_tell); + cookieObj = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(tell)); if (cookieObj == NULL) goto fail; break; @@ -2503,7 +2462,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) goto fail; } - res = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_flush); + res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); if (res == NULL) goto fail; Py_DECREF(res); @@ -2511,13 +2470,13 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) textiowrapper_set_decoded_chars(self, NULL); Py_CLEAR(self->snapshot); if (self->decoder) { - res = _PyObject_CallMethodIdNoArgs(self->decoder, &PyId_reset); + res = PyObject_CallMethodNoArgs(self->decoder, &_Py_ID(reset)); if (res == NULL) goto fail; Py_DECREF(res); } - res = _PyObject_CallMethodId(self->buffer, &PyId_seek, "ii", 0, 2); + res = _PyObject_CallMethod(self->buffer, &_Py_ID(seek), "ii", 0, 2); Py_CLEAR(cookieObj); if (res == NULL) goto fail; @@ -2551,7 +2510,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) goto fail; } - res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); + res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); if (res == NULL) goto fail; Py_DECREF(res); @@ -2566,7 +2525,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) posobj = PyLong_FromOff_t(cookie.start_pos); if (posobj == NULL) goto fail; - res = PyObject_CallMethodOneArg(self->buffer, _PyIO_str_seek, posobj); + res = PyObject_CallMethodOneArg(self->buffer, &_Py_ID(seek), posobj); Py_DECREF(posobj); if (res == NULL) goto fail; @@ -2583,8 +2542,8 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) if (cookie.chars_to_skip) { /* Just like _read_chunk, feed the decoder and save a snapshot. */ - PyObject *input_chunk = _PyObject_CallMethodId( - self->buffer, &PyId_read, "i", cookie.bytes_to_feed); + PyObject *input_chunk = _PyObject_CallMethod(self->buffer, &_Py_ID(read), + "i", cookie.bytes_to_feed); PyObject *decoded; if (input_chunk == NULL) @@ -2605,7 +2564,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) } Py_XSETREF(self->snapshot, snapshot); - decoded = _PyObject_CallMethodIdObjArgs(self->decoder, &PyId_decode, + decoded = PyObject_CallMethodObjArgs(self->decoder, &_Py_ID(decode), input_chunk, cookie.need_eof ? Py_True : Py_False, NULL); if (check_decoded(decoded) < 0) @@ -2673,12 +2632,12 @@ _io_TextIOWrapper_tell_impl(textio *self) if (_textiowrapper_writeflush(self) < 0) return NULL; - res = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_flush); + res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); if (res == NULL) goto fail; Py_DECREF(res); - posobj = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_tell); + posobj = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(tell)); if (posobj == NULL) goto fail; @@ -2715,14 +2674,14 @@ _io_TextIOWrapper_tell_impl(textio *self) /* Decoder state will be restored at the end */ saved_state = PyObject_CallMethodNoArgs(self->decoder, - _PyIO_str_getstate); + &_Py_ID(getstate)); if (saved_state == NULL) goto fail; #define DECODER_GETSTATE() do { \ PyObject *dec_buffer; \ PyObject *_state = PyObject_CallMethodNoArgs(self->decoder, \ - _PyIO_str_getstate); \ + &_Py_ID(getstate)); \ if (_state == NULL) \ goto fail; \ if (!PyTuple_Check(_state)) { \ @@ -2750,8 +2709,8 @@ _io_TextIOWrapper_tell_impl(textio *self) } while (0) #define DECODER_DECODE(start, len, res) do { \ - PyObject *_decoded = _PyObject_CallMethodId( \ - self->decoder, &PyId_decode, "y#", start, len); \ + PyObject *_decoded = _PyObject_CallMethod( \ + self->decoder, &_Py_ID(decode), "y#", start, len); \ if (check_decoded(_decoded) < 0) \ goto fail; \ res = PyUnicode_GET_LENGTH(_decoded); \ @@ -2832,8 +2791,8 @@ _io_TextIOWrapper_tell_impl(textio *self) } if (input == input_end) { /* We didn't get enough decoded data; signal EOF to get more. */ - PyObject *decoded = _PyObject_CallMethodId( - self->decoder, &PyId_decode, "yO", "", /* final = */ Py_True); + PyObject *decoded = _PyObject_CallMethod( + self->decoder, &_Py_ID(decode), "yO", "", /* final = */ Py_True); if (check_decoded(decoded) < 0) goto fail; chars_decoded += PyUnicode_GET_LENGTH(decoded); @@ -2848,7 +2807,8 @@ _io_TextIOWrapper_tell_impl(textio *self) } finally: - res = _PyObject_CallMethodIdOneArg(self->decoder, &PyId_setstate, saved_state); + res = PyObject_CallMethodOneArg( + self->decoder, &_Py_ID(setstate), saved_state); Py_DECREF(saved_state); if (res == NULL) return NULL; @@ -2862,7 +2822,8 @@ fail: if (saved_state) { PyObject *type, *value, *traceback; PyErr_Fetch(&type, &value, &traceback); - res = _PyObject_CallMethodIdOneArg(self->decoder, &PyId_setstate, saved_state); + res = PyObject_CallMethodOneArg( + self->decoder, &_Py_ID(setstate), saved_state); _PyErr_ChainExceptions(type, value, traceback); Py_DECREF(saved_state); Py_XDECREF(res); @@ -2884,12 +2845,12 @@ _io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos) CHECK_ATTACHED(self) - res = PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); + res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); if (res == NULL) return NULL; Py_DECREF(res); - return PyObject_CallMethodOneArg(self->buffer, _PyIO_str_truncate, pos); + return PyObject_CallMethodOneArg(self->buffer, &_Py_ID(truncate), pos); } static PyObject * @@ -2913,7 +2874,7 @@ textiowrapper_repr(textio *self) } goto error; } - if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) { + if (_PyObject_LookupAttr((PyObject *) self, &_Py_ID(name), &nameobj) < 0) { if (!PyErr_ExceptionMatches(PyExc_ValueError)) { goto error; } @@ -2929,7 +2890,7 @@ textiowrapper_repr(textio *self) if (res == NULL) goto error; } - if (_PyObject_LookupAttrId((PyObject *) self, &PyId_mode, &modeobj) < 0) { + if (_PyObject_LookupAttr((PyObject *) self, &_Py_ID(mode), &modeobj) < 0) { goto error; } if (modeobj != NULL) { @@ -2969,7 +2930,7 @@ _io_TextIOWrapper_fileno_impl(textio *self) /*[clinic end generated code: output=21490a4c3da13e6c input=c488ca83d0069f9b]*/ { CHECK_ATTACHED(self); - return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_fileno); + return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(fileno)); } /*[clinic input] @@ -2981,7 +2942,7 @@ _io_TextIOWrapper_seekable_impl(textio *self) /*[clinic end generated code: output=ab223dbbcffc0f00 input=8b005ca06e1fca13]*/ { CHECK_ATTACHED(self); - return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_seekable); + return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(seekable)); } /*[clinic input] @@ -2993,7 +2954,7 @@ _io_TextIOWrapper_readable_impl(textio *self) /*[clinic end generated code: output=72ff7ba289a8a91b input=0704ea7e01b0d3eb]*/ { CHECK_ATTACHED(self); - return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_readable); + return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(readable)); } /*[clinic input] @@ -3005,7 +2966,7 @@ _io_TextIOWrapper_writable_impl(textio *self) /*[clinic end generated code: output=a728c71790d03200 input=c41740bc9d8636e8]*/ { CHECK_ATTACHED(self); - return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_writable); + return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(writable)); } /*[clinic input] @@ -3017,7 +2978,7 @@ _io_TextIOWrapper_isatty_impl(textio *self) /*[clinic end generated code: output=12be1a35bace882e input=fb68d9f2c99bbfff]*/ { CHECK_ATTACHED(self); - return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_isatty); + return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(isatty)); } /*[clinic input] @@ -3033,7 +2994,7 @@ _io_TextIOWrapper_flush_impl(textio *self) self->telling = self->seekable; if (_textiowrapper_writeflush(self) < 0) return NULL; - return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_flush); + return PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(flush)); } /*[clinic input] @@ -3062,21 +3023,20 @@ _io_TextIOWrapper_close_impl(textio *self) else { PyObject *exc = NULL, *val, *tb; if (self->finalizing) { - res = _PyObject_CallMethodIdOneArg(self->buffer, - &PyId__dealloc_warn, - (PyObject *)self); + res = PyObject_CallMethodOneArg(self->buffer, &_Py_ID(_dealloc_warn), + (PyObject *)self); if (res) Py_DECREF(res); else PyErr_Clear(); } - res = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_flush); + res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); if (res == NULL) PyErr_Fetch(&exc, &val, &tb); else Py_DECREF(res); - res = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_close); + res = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(close)); if (exc != NULL) { _PyErr_ChainExceptions(exc, val, tb); Py_CLEAR(res); @@ -3099,7 +3059,7 @@ textiowrapper_iternext(textio *self) } else { line = PyObject_CallMethodNoArgs((PyObject *)self, - _PyIO_str_readline); + &_Py_ID(readline)); if (line && !PyUnicode_Check(line)) { PyErr_Format(PyExc_OSError, "readline() should have returned a str object, " @@ -3127,14 +3087,14 @@ static PyObject * textiowrapper_name_get(textio *self, void *context) { CHECK_ATTACHED(self); - return _PyObject_GetAttrId(self->buffer, &PyId_name); + return PyObject_GetAttr(self->buffer, &_Py_ID(name)); } static PyObject * textiowrapper_closed_get(textio *self, void *context) { CHECK_ATTACHED(self); - return PyObject_GetAttr(self->buffer, _PyIO_str_closed); + return PyObject_GetAttr(self->buffer, &_Py_ID(closed)); } static PyObject * @@ -3143,7 +3103,7 @@ textiowrapper_newlines_get(textio *self, void *context) PyObject *res; CHECK_ATTACHED(self); if (self->decoder == NULL || - _PyObject_LookupAttr(self->decoder, _PyIO_str_newlines, &res) == 0) + _PyObject_LookupAttr(self->decoder, &_Py_ID(newlines), &res) == 0) { Py_RETURN_NONE; } @@ -3154,8 +3114,7 @@ static PyObject * textiowrapper_errors_get(textio *self, void *context) { CHECK_INITIALIZED(self); - Py_INCREF(self->errors); - return self->errors; + return Py_NewRef(self->errors); } static PyObject * diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index 4002d28fc9b..4f41ab965e2 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -156,8 +156,6 @@ typedef struct { PyTypeObject PyWindowsConsoleIO_Type; -_Py_IDENTIFIER(name); - int _PyWindowsConsoleIO_closed(PyObject *self) { @@ -196,9 +194,8 @@ _io__WindowsConsoleIO_close_impl(winconsoleio *self) PyObject *res; PyObject *exc, *val, *tb; int rc; - _Py_IDENTIFIER(close); - res = _PyObject_CallMethodIdOneArg((PyObject*)&PyRawIOBase_Type, - &PyId_close, (PyObject*)self); + res = PyObject_CallMethodOneArg((PyObject*)&PyRawIOBase_Type, + &_Py_ID(close), (PyObject*)self); if (!self->closefd) { self->fd = -1; return res; @@ -238,7 +235,7 @@ winconsoleio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) _io._WindowsConsoleIO.__init__ file as nameobj: object mode: str = "r" - closefd: bool(accept={int}) = True + closefd: bool = True opener: object = None Open a console buffer by file descriptor. @@ -252,7 +249,7 @@ static int _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, const char *mode, int closefd, PyObject *opener) -/*[clinic end generated code: output=3fd9cbcdd8d95429 input=06ae4b863c63244b]*/ +/*[clinic end generated code: output=3fd9cbcdd8d95429 input=7a3eed6bbe998fd9]*/ { const char *s; wchar_t *name = NULL; @@ -394,7 +391,7 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, self->blksize = DEFAULT_BUFFER_SIZE; memset(self->buf, 0, 4); - if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0) + if (PyObject_SetAttr((PyObject *)self, &_Py_ID(name), nameobj) < 0) goto error; goto done; @@ -957,7 +954,7 @@ _io__WindowsConsoleIO_write_impl(winconsoleio *self, Py_buffer *b) { BOOL res = TRUE; wchar_t *wbuf; - DWORD len, wlen, n = 0; + DWORD len, wlen, orig_len, n = 0; HANDLE handle; if (self->fd == -1) @@ -987,6 +984,21 @@ _io__WindowsConsoleIO_write_impl(winconsoleio *self, Py_buffer *b) have to reduce and recalculate. */ while (wlen > 32766 / sizeof(wchar_t)) { len /= 2; + orig_len = len; + /* Reduce the length until we hit the final byte of a UTF-8 sequence + * (top bit is unset). Fix for github issue 82052. + */ + while (len > 0 && (((char *)b->buf)[len-1] & 0x80) != 0) + --len; + /* If we hit a length of 0, something has gone wrong. This shouldn't + * be possible, as valid UTF-8 can have at most 3 non-final bytes + * before a final one, and our buffer is way longer than that. + * But to be on the safe side, if we hit this issue we just restore + * the original length and let the console API sort it out. + */ + if (len == 0) { + len = orig_len; + } wlen = MultiByteToWideChar(CP_UTF8, 0, b->buf, len, NULL, 0); } Py_END_ALLOW_THREADS diff --git a/Modules/_json.c b/Modules/_json.c index 1c9c50665d4..fa8e2a936d2 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -9,21 +9,11 @@ #endif #include "Python.h" -#include "structmember.h" // PyMemberDef -#include "pycore_accu.h" - -typedef struct { - PyObject *PyScannerType; - PyObject *PyEncoderType; -} _jsonmodulestate; - -static inline _jsonmodulestate* -get_json_state(PyObject *module) -{ - void *state = PyModule_GetState(module); - assert(state != NULL); - return (_jsonmodulestate *)state; -} +#include "pycore_ceval.h" // _Py_EnterRecursiveCall() +#include "pycore_runtime.h" // _PyRuntime +#include "structmember.h" // PyMemberDef +#include "pycore_global_objects.h" // _Py_ID() +#include // bool typedef struct _PyScannerObject { @@ -96,11 +86,11 @@ encoder_dealloc(PyObject *self); static int encoder_clear(PyEncoderObject *self); static int -encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, PyObject *seq, Py_ssize_t indent_level); +encoder_listencode_list(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *seq, Py_ssize_t indent_level); static int -encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, PyObject *obj, Py_ssize_t indent_level); +encoder_listencode_obj(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *obj, Py_ssize_t indent_level); static int -encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, PyObject *dct, Py_ssize_t indent_level); +encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *dct, Py_ssize_t indent_level); static PyObject * _encoded_const(PyObject *obj); static void @@ -316,15 +306,9 @@ static void raise_errmsg(const char *msg, PyObject *s, Py_ssize_t end) { /* Use JSONDecodeError exception to raise a nice looking ValueError subclass */ - _Py_static_string(PyId_decoder, "json.decoder"); - PyObject *decoder = _PyImport_GetModuleId(&PyId_decoder); - if (decoder == NULL) { - return; - } - - _Py_IDENTIFIER(JSONDecodeError); - PyObject *JSONDecodeError = _PyObject_GetAttrId(decoder, &PyId_JSONDecodeError); - Py_DECREF(decoder); + _Py_DECLARE_STR(json_decoder, "json.decoder"); + PyObject *JSONDecodeError = + _PyImport_GetModuleAttr(&_Py_STR(json_decoder), &_Py_ID(JSONDecodeError)); if (JSONDecodeError == NULL) { return; } @@ -572,7 +556,7 @@ py_scanstring(PyObject* Py_UNUSED(self), PyObject *args) Py_ssize_t end; Py_ssize_t next_end = -1; int strict = 1; - if (!PyArg_ParseTuple(args, "On|i:scanstring", &pystr, &end, &strict)) { + if (!PyArg_ParseTuple(args, "On|p:scanstring", &pystr, &end, &strict)) { return NULL; } if (PyUnicode_Check(pystr)) { @@ -725,9 +709,7 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss if (memokey == NULL) { goto bail; } - Py_INCREF(memokey); - Py_DECREF(key); - key = memokey; + Py_SETREF(key, Py_NewRef(memokey)); idx = next_idx; /* skip whitespace between key and : delimiter, read :, skip whitespace */ @@ -1058,19 +1040,19 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ return scanstring_unicode(pystr, idx + 1, s->strict, next_idx_ptr); case '{': /* object */ - if (Py_EnterRecursiveCall(" while decoding a JSON object " - "from a unicode string")) + if (_Py_EnterRecursiveCall(" while decoding a JSON object " + "from a unicode string")) return NULL; res = _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); return res; case '[': /* array */ - if (Py_EnterRecursiveCall(" while decoding a JSON array " - "from a unicode string")) + if (_Py_EnterRecursiveCall(" while decoding a JSON array " + "from a unicode string")) return NULL; res = _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); return res; case 'n': /* null */ @@ -1259,16 +1241,17 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (s == NULL) return NULL; - s->markers = markers; - s->defaultfn = defaultfn; - s->encoder = encoder; - s->indent = indent; - s->key_separator = key_separator; - s->item_separator = item_separator; + s->markers = Py_NewRef(markers); + s->defaultfn = Py_NewRef(defaultfn); + s->encoder = Py_NewRef(encoder); + s->indent = Py_NewRef(indent); + s->key_separator = Py_NewRef(key_separator); + s->item_separator = Py_NewRef(item_separator); s->sort_keys = sort_keys; s->skipkeys = skipkeys; s->allow_nan = allow_nan; s->fast_encode = NULL; + if (PyCFunction_Check(s->encoder)) { PyCFunction f = PyCFunction_GetFunction(s->encoder); if (f == (PyCFunction)py_encode_basestring_ascii || @@ -1277,12 +1260,6 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } - Py_INCREF(s->markers); - Py_INCREF(s->defaultfn); - Py_INCREF(s->encoder); - Py_INCREF(s->indent); - Py_INCREF(s->key_separator); - Py_INCREF(s->item_separator); return (PyObject *)s; } @@ -1291,19 +1268,29 @@ encoder_call(PyEncoderObject *self, PyObject *args, PyObject *kwds) { /* Python callable interface to encode_listencode_obj */ static char *kwlist[] = {"obj", "_current_indent_level", NULL}; - PyObject *obj; + PyObject *obj, *result; Py_ssize_t indent_level; - _PyAccu acc; + _PyUnicodeWriter writer; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:_iterencode", kwlist, &obj, &indent_level)) return NULL; - if (_PyAccu_Init(&acc)) - return NULL; - if (encoder_listencode_obj(self, &acc, obj, indent_level)) { - _PyAccu_Destroy(&acc); + + _PyUnicodeWriter_Init(&writer); + writer.overallocate = 1; + + if (encoder_listencode_obj(self, &writer, obj, indent_level)) { + _PyUnicodeWriter_Dealloc(&writer); return NULL; } - return _PyAccu_FinishAsList(&acc); + + result = PyTuple_New(1); + if (result == NULL || + PyTuple_SetItem(result, 0, _PyUnicodeWriter_Finish(&writer)) < 0) { + Py_XDECREF(result); + return NULL; + } + return result; } static PyObject * @@ -1311,28 +1298,13 @@ _encoded_const(PyObject *obj) { /* Return the JSON string representation of None, True, False */ if (obj == Py_None) { - _Py_static_string(PyId_null, "null"); - PyObject *s_null = _PyUnicode_FromId(&PyId_null); - if (s_null == NULL) { - return NULL; - } - return Py_NewRef(s_null); + return Py_NewRef(&_Py_ID(null)); } else if (obj == Py_True) { - _Py_static_string(PyId_true, "true"); - PyObject *s_true = _PyUnicode_FromId(&PyId_true); - if (s_true == NULL) { - return NULL; - } - return Py_NewRef(s_true); + return Py_NewRef(&_Py_ID(true)); } else if (obj == Py_False) { - _Py_static_string(PyId_false, "false"); - PyObject *s_false = _PyUnicode_FromId(&PyId_false); - if (s_false == NULL) { - return NULL; - } - return Py_NewRef(s_false); + return Py_NewRef(&_Py_ID(false)); } else { PyErr_SetString(PyExc_ValueError, "not a const"); @@ -1347,9 +1319,10 @@ encoder_encode_float(PyEncoderObject *s, PyObject *obj) double i = PyFloat_AS_DOUBLE(obj); if (!Py_IS_FINITE(i)) { if (!s->allow_nan) { - PyErr_SetString( + PyErr_Format( PyExc_ValueError, - "Out of range float values are not JSON compliant" + "Out of range float values are not JSON compliant: %R", + obj ); return NULL; } @@ -1387,59 +1360,61 @@ encoder_encode_string(PyEncoderObject *s, PyObject *obj) } static int -_steal_accumulate(_PyAccu *acc, PyObject *stolen) +_steal_accumulate(_PyUnicodeWriter *writer, PyObject *stolen) { /* Append stolen and then decrement its reference count */ - int rval = _PyAccu_Accumulate(acc, stolen); + int rval = _PyUnicodeWriter_WriteStr(writer, stolen); Py_DECREF(stolen); return rval; } static int -encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, +encoder_listencode_obj(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *obj, Py_ssize_t indent_level) { /* Encode Python object obj to a JSON term */ PyObject *newobj; int rv; - if (obj == Py_None || obj == Py_True || obj == Py_False) { - PyObject *cstr = _encoded_const(obj); - if (cstr == NULL) - return -1; - return _steal_accumulate(acc, cstr); + if (obj == Py_None) { + return _PyUnicodeWriter_WriteASCIIString(writer, "null", 4); } - else if (PyUnicode_Check(obj)) - { + else if (obj == Py_True) { + return _PyUnicodeWriter_WriteASCIIString(writer, "true", 4); + } + else if (obj == Py_False) { + return _PyUnicodeWriter_WriteASCIIString(writer, "false", 5); + } + else if (PyUnicode_Check(obj)) { PyObject *encoded = encoder_encode_string(s, obj); if (encoded == NULL) return -1; - return _steal_accumulate(acc, encoded); + return _steal_accumulate(writer, encoded); } else if (PyLong_Check(obj)) { PyObject *encoded = PyLong_Type.tp_repr(obj); if (encoded == NULL) return -1; - return _steal_accumulate(acc, encoded); + return _steal_accumulate(writer, encoded); } else if (PyFloat_Check(obj)) { PyObject *encoded = encoder_encode_float(s, obj); if (encoded == NULL) return -1; - return _steal_accumulate(acc, encoded); + return _steal_accumulate(writer, encoded); } else if (PyList_Check(obj) || PyTuple_Check(obj)) { - if (Py_EnterRecursiveCall(" while encoding a JSON object")) + if (_Py_EnterRecursiveCall(" while encoding a JSON object")) return -1; - rv = encoder_listencode_list(s, acc, obj, indent_level); - Py_LeaveRecursiveCall(); + rv = encoder_listencode_list(s, writer, obj, indent_level); + _Py_LeaveRecursiveCall(); return rv; } else if (PyDict_Check(obj)) { - if (Py_EnterRecursiveCall(" while encoding a JSON object")) + if (_Py_EnterRecursiveCall(" while encoding a JSON object")) return -1; - rv = encoder_listencode_dict(s, acc, obj, indent_level); - Py_LeaveRecursiveCall(); + rv = encoder_listencode_dict(s, writer, obj, indent_level); + _Py_LeaveRecursiveCall(); return rv; } else { @@ -1467,13 +1442,13 @@ encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, return -1; } - if (Py_EnterRecursiveCall(" while encoding a JSON object")) { + if (_Py_EnterRecursiveCall(" while encoding a JSON object")) { Py_DECREF(newobj); Py_XDECREF(ident); return -1; } - rv = encoder_listencode_obj(s, acc, newobj, indent_level); - Py_LeaveRecursiveCall(); + rv = encoder_listencode_obj(s, writer, newobj, indent_level); + _Py_LeaveRecursiveCall(); Py_DECREF(newobj); if (rv) { @@ -1492,28 +1467,80 @@ encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, } static int -encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, +encoder_encode_key_value(PyEncoderObject *s, _PyUnicodeWriter *writer, bool *first, + PyObject *key, PyObject *value, Py_ssize_t indent_level) +{ + PyObject *keystr = NULL; + PyObject *encoded; + + if (PyUnicode_Check(key)) { + keystr = Py_NewRef(key); + } + else if (PyFloat_Check(key)) { + keystr = encoder_encode_float(s, key); + } + else if (key == Py_True || key == Py_False || key == Py_None) { + /* This must come before the PyLong_Check because + True and False are also 1 and 0.*/ + keystr = _encoded_const(key); + } + else if (PyLong_Check(key)) { + keystr = PyLong_Type.tp_repr(key); + } + else if (s->skipkeys) { + return 0; + } + else { + PyErr_Format(PyExc_TypeError, + "keys must be str, int, float, bool or None, " + "not %.100s", Py_TYPE(key)->tp_name); + return -1; + } + + if (keystr == NULL) { + return -1; + } + + if (*first) { + *first = false; + } + else { + if (_PyUnicodeWriter_WriteStr(writer, s->item_separator) < 0) { + Py_DECREF(keystr); + return -1; + } + } + + encoded = encoder_encode_string(s, keystr); + Py_DECREF(keystr); + if (encoded == NULL) { + return -1; + } + + if (_steal_accumulate(writer, encoded) < 0) { + return -1; + } + if (_PyUnicodeWriter_WriteStr(writer, s->key_separator) < 0) { + return -1; + } + if (encoder_listencode_obj(s, writer, value, indent_level) < 0) { + return -1; + } + return 0; +} + +static int +encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *dct, Py_ssize_t indent_level) { /* Encode Python dict dct a JSON term */ - _Py_static_string(PyId_open_dict, "{"); - _Py_static_string(PyId_close_dict, "}"); - _Py_static_string(PyId_empty_dict, "{}"); - PyObject *open_dict = _PyUnicode_FromId(&PyId_open_dict); // borrowed ref - PyObject *close_dict = _PyUnicode_FromId(&PyId_close_dict); // borrowed ref - PyObject *empty_dict = _PyUnicode_FromId(&PyId_empty_dict); // borrowed ref - PyObject *kstr = NULL; PyObject *ident = NULL; - PyObject *it = NULL; - PyObject *items; - PyObject *item = NULL; - Py_ssize_t idx; + PyObject *items = NULL; + PyObject *key, *value; + bool first = true; - if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) { - return -1; - } if (PyDict_GET_SIZE(dct) == 0) /* Fast path */ - return _PyAccu_Accumulate(acc, empty_dict); + return _PyUnicodeWriter_WriteASCIIString(writer, "{}", 2); if (s->markers != Py_None) { int has_key; @@ -1531,7 +1558,7 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, } } - if (_PyAccu_Accumulate(acc, open_dict)) + if (_PyUnicodeWriter_WriteChar(writer, '{')) goto bail; if (s->indent != Py_None) { @@ -1544,84 +1571,33 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, */ } - items = PyMapping_Items(dct); - if (items == NULL) - goto bail; - if (s->sort_keys && PyList_Sort(items) < 0) { - Py_DECREF(items); - goto bail; - } - it = PyObject_GetIter(items); - Py_DECREF(items); - if (it == NULL) - goto bail; - idx = 0; - while ((item = PyIter_Next(it)) != NULL) { - PyObject *encoded, *key, *value; - if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) { - PyErr_SetString(PyExc_ValueError, "items must return 2-tuples"); + if (s->sort_keys || !PyDict_CheckExact(dct)) { + items = PyMapping_Items(dct); + if (items == NULL || (s->sort_keys && PyList_Sort(items) < 0)) goto bail; - } - key = PyTuple_GET_ITEM(item, 0); - if (PyUnicode_Check(key)) { - Py_INCREF(key); - kstr = key; - } - else if (PyFloat_Check(key)) { - kstr = encoder_encode_float(s, key); - if (kstr == NULL) - goto bail; - } - else if (key == Py_True || key == Py_False || key == Py_None) { - /* This must come before the PyLong_Check because - True and False are also 1 and 0.*/ - kstr = _encoded_const(key); - if (kstr == NULL) - goto bail; - } - else if (PyLong_Check(key)) { - kstr = PyLong_Type.tp_repr(key); - if (kstr == NULL) { + + for (Py_ssize_t i = 0; i < PyList_GET_SIZE(items); i++) { + PyObject *item = PyList_GET_ITEM(items, i); + + if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) { + PyErr_SetString(PyExc_ValueError, "items must return 2-tuples"); goto bail; } - } - else if (s->skipkeys) { - Py_DECREF(item); - continue; - } - else { - PyErr_Format(PyExc_TypeError, - "keys must be str, int, float, bool or None, " - "not %.100s", Py_TYPE(key)->tp_name); - goto bail; - } - if (idx) { - if (_PyAccu_Accumulate(acc, s->item_separator)) + key = PyTuple_GET_ITEM(item, 0); + value = PyTuple_GET_ITEM(item, 1); + if (encoder_encode_key_value(s, writer, &first, key, value, indent_level) < 0) goto bail; } + Py_CLEAR(items); - encoded = encoder_encode_string(s, kstr); - Py_CLEAR(kstr); - if (encoded == NULL) - goto bail; - if (_PyAccu_Accumulate(acc, encoded)) { - Py_DECREF(encoded); - goto bail; + } else { + Py_ssize_t pos = 0; + while (PyDict_Next(dct, &pos, &key, &value)) { + if (encoder_encode_key_value(s, writer, &first, key, value, indent_level) < 0) + goto bail; } - Py_DECREF(encoded); - if (_PyAccu_Accumulate(acc, s->key_separator)) - goto bail; - - value = PyTuple_GET_ITEM(item, 1); - if (encoder_listencode_obj(s, acc, value, indent_level)) - goto bail; - idx += 1; - Py_DECREF(item); } - if (PyErr_Occurred()) - goto bail; - Py_CLEAR(it); if (ident != NULL) { if (PyDict_DelItem(s->markers, ident)) @@ -1634,44 +1610,31 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, yield '\n' + (' ' * (_indent * _current_indent_level)) }*/ - if (_PyAccu_Accumulate(acc, close_dict)) + if (_PyUnicodeWriter_WriteChar(writer, '}')) goto bail; return 0; bail: - Py_XDECREF(it); - Py_XDECREF(item); - Py_XDECREF(kstr); + Py_XDECREF(items); Py_XDECREF(ident); return -1; } - static int -encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, +encoder_listencode_list(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *seq, Py_ssize_t indent_level) { - /* Encode Python list seq to a JSON term */ - _Py_static_string(PyId_open_array, "["); - _Py_static_string(PyId_close_array, "]"); - _Py_static_string(PyId_empty_array, "[]"); - PyObject *open_array = _PyUnicode_FromId(&PyId_open_array); // borrowed ref - PyObject *close_array = _PyUnicode_FromId(&PyId_close_array); // borrowed ref - PyObject *empty_array = _PyUnicode_FromId(&PyId_empty_array); // borrowed ref PyObject *ident = NULL; PyObject *s_fast = NULL; Py_ssize_t i; - if (open_array == NULL || close_array == NULL || empty_array == NULL) { - return -1; - } ident = NULL; s_fast = PySequence_Fast(seq, "_iterencode_list needs a sequence"); if (s_fast == NULL) return -1; if (PySequence_Fast_GET_SIZE(s_fast) == 0) { Py_DECREF(s_fast); - return _PyAccu_Accumulate(acc, empty_array); + return _PyUnicodeWriter_WriteASCIIString(writer, "[]", 2); } if (s->markers != Py_None) { @@ -1690,7 +1653,7 @@ encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, } } - if (_PyAccu_Accumulate(acc, open_array)) + if (_PyUnicodeWriter_WriteChar(writer, '[')) goto bail; if (s->indent != Py_None) { /* TODO: DOES NOT RUN */ @@ -1704,10 +1667,10 @@ encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, for (i = 0; i < PySequence_Fast_GET_SIZE(s_fast); i++) { PyObject *obj = PySequence_Fast_GET_ITEM(s_fast, i); if (i) { - if (_PyAccu_Accumulate(acc, s->item_separator)) + if (_PyUnicodeWriter_WriteStr(writer, s->item_separator)) goto bail; } - if (encoder_listencode_obj(s, acc, obj, indent_level)) + if (encoder_listencode_obj(s, writer, obj, indent_level)) goto bail; } if (ident != NULL) { @@ -1722,7 +1685,7 @@ encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, yield '\n' + (' ' * (_indent * _current_indent_level)) }*/ - if (_PyAccu_Accumulate(acc, close_array)) + if (_PyUnicodeWriter_WriteChar(writer, ']')) goto bail; Py_DECREF(s_fast); return 0; @@ -1813,70 +1776,40 @@ PyDoc_STRVAR(module_doc, static int _json_exec(PyObject *module) { - _jsonmodulestate *state = get_json_state(module); - - state->PyScannerType = PyType_FromSpec(&PyScannerType_spec); - if (state->PyScannerType == NULL) { + PyObject *PyScannerType = PyType_FromSpec(&PyScannerType_spec); + if (PyScannerType == NULL) { return -1; } - Py_INCREF(state->PyScannerType); - if (PyModule_AddObject(module, "make_scanner", state->PyScannerType) < 0) { - Py_DECREF(state->PyScannerType); + int rc = PyModule_AddObjectRef(module, "make_scanner", PyScannerType); + Py_DECREF(PyScannerType); + if (rc < 0) { return -1; } - state->PyEncoderType = PyType_FromSpec(&PyEncoderType_spec); - if (state->PyEncoderType == NULL) { + PyObject *PyEncoderType = PyType_FromSpec(&PyEncoderType_spec); + if (PyEncoderType == NULL) { return -1; } - Py_INCREF(state->PyEncoderType); - if (PyModule_AddObject(module, "make_encoder", state->PyEncoderType) < 0) { - Py_DECREF(state->PyEncoderType); + rc = PyModule_AddObjectRef(module, "make_encoder", PyEncoderType); + Py_DECREF(PyEncoderType); + if (rc < 0) { return -1; } return 0; } -static int -_jsonmodule_traverse(PyObject *module, visitproc visit, void *arg) -{ - _jsonmodulestate *state = get_json_state(module); - Py_VISIT(state->PyScannerType); - Py_VISIT(state->PyEncoderType); - return 0; -} - -static int -_jsonmodule_clear(PyObject *module) -{ - _jsonmodulestate *state = get_json_state(module); - Py_CLEAR(state->PyScannerType); - Py_CLEAR(state->PyEncoderType); - return 0; -} - -static void -_jsonmodule_free(void *module) -{ - _jsonmodule_clear((PyObject *)module); -} - static PyModuleDef_Slot _json_slots[] = { {Py_mod_exec, _json_exec}, {0, NULL} }; static struct PyModuleDef jsonmodule = { - PyModuleDef_HEAD_INIT, - "_json", - module_doc, - sizeof(_jsonmodulestate), - speedups_methods, - _json_slots, - _jsonmodule_traverse, - _jsonmodule_clear, - _jsonmodule_free, + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_json", + .m_doc = module_doc, + .m_methods = speedups_methods, + .m_slots = _json_slots, }; PyMODINIT_FUNC diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index 564f5598edc..23c38e14d99 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -773,14 +773,14 @@ _locale_bind_textdomain_codeset_impl(PyObject *module, const char *domain, /*[clinic input] -_locale._get_locale_encoding +_locale.getencoding Get the current locale encoding. [clinic start generated code]*/ static PyObject * -_locale__get_locale_encoding_impl(PyObject *module) -/*[clinic end generated code: output=e8e2f6f6f184591a input=513d9961d2f45c76]*/ +_locale_getencoding_impl(PyObject *module) +/*[clinic end generated code: output=86b326b971872e46 input=6503d11e5958b360]*/ { return _Py_GetLocaleEncodingObject(); } @@ -811,7 +811,7 @@ static struct PyMethodDef PyLocale_Methods[] = { _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF #endif #endif - _LOCALE__GET_LOCALE_ENCODING_METHODDEF + _LOCALE_GETENCODING_METHODDEF {NULL, NULL} }; diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index ff499aacbab..37170bbea56 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -128,8 +128,7 @@ normalizeUserObj(PyObject *obj) { PyCFunctionObject *fn; if (!PyCFunction_Check(obj)) { - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } /* Replace built-in function objects with a descriptive string because of built-in methods -- keeping a reference to @@ -142,8 +141,7 @@ normalizeUserObj(PyObject *obj) PyObject *modname = NULL; if (mod != NULL) { if (PyUnicode_Check(mod)) { - modname = mod; - Py_INCREF(modname); + modname = Py_NewRef(mod); } else if (PyModule_Check(mod)) { modname = PyModule_GetNameObject(mod); @@ -555,8 +553,7 @@ static int statsForEntry(rotating_node_t *node, void *arg) } } else { - Py_INCREF(Py_None); - collect->sublist = Py_None; + collect->sublist = Py_NewRef(Py_None); } info = PyObject_CallFunction((PyObject*) collect->state->stats_entry_type, @@ -670,7 +667,7 @@ profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) int subcalls = -1; int builtins = -1; static char *kwlist[] = {"subcalls", "builtins", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:enable", + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|pp:enable", kwlist, &subcalls, &builtins)) return NULL; if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0) { @@ -747,10 +744,11 @@ profiler_traverse(ProfilerObject *op, visitproc visit, void *arg) static void profiler_dealloc(ProfilerObject *op) { + PyObject_GC_UnTrack(op); if (op->flags & POF_ENABLED) { PyThreadState *tstate = _PyThreadState_GET(); if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) { - PyErr_WriteUnraisable((PyObject *)op); + _PyErr_WriteUnraisableMsg("When destroying _lsprof profiler", NULL); } } @@ -772,7 +770,7 @@ profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) static char *kwlist[] = {"timer", "timeunit", "subcalls", "builtins", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kw, "|Odii:Profiler", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kw, "|Odpp:Profiler", kwlist, &timer, &timeunit, &subcalls, &builtins)) return -1; @@ -780,14 +778,13 @@ profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) if (setSubcalls(pObj, subcalls) < 0 || setBuiltins(pObj, builtins) < 0) return -1; pObj->externalTimerUnit = timeunit; - Py_XINCREF(timer); - Py_XSETREF(pObj->externalTimer, timer); + Py_XSETREF(pObj->externalTimer, Py_XNewRef(timer)); return 0; } static PyMethodDef profiler_methods[] = { _LSPROF_PROFILER_GETSTATS_METHODDEF - {"enable", (PyCFunction)(void(*)(void))profiler_enable, + {"enable", _PyCFunction_CAST(profiler_enable), METH_VARARGS | METH_KEYWORDS, enable_doc}, {"disable", (PyCFunction)profiler_disable, METH_NOARGS, disable_doc}, diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c index e50f55b75c5..b572d8cd909 100644 --- a/Modules/_lzmamodule.c +++ b/Modules/_lzmamodule.c @@ -430,17 +430,19 @@ parse_filter_chain_spec(_lzma_state *state, lzma_filter filters[], PyObject *fil Python-level filter specifiers (represented as dicts). */ static int -spec_add_field(PyObject *spec, _Py_Identifier *key, unsigned long long value) +spec_add_field(PyObject *spec, const char *key, unsigned long long value) { - int status; - PyObject *value_object; - - value_object = PyLong_FromUnsignedLongLong(value); + PyObject *value_object = PyLong_FromUnsignedLongLong(value); if (value_object == NULL) { return -1; } - - status = _PyDict_SetItemId(spec, key, value_object); + PyObject *key_object = PyUnicode_InternFromString(key); + if (key_object == NULL) { + Py_DECREF(value_object); + return -1; + } + int status = PyDict_SetItem(spec, key_object, value_object); + Py_DECREF(key_object); Py_DECREF(value_object); return status; } @@ -457,8 +459,7 @@ build_filter_spec(const lzma_filter *f) #define ADD_FIELD(SOURCE, FIELD) \ do { \ - _Py_IDENTIFIER(FIELD); \ - if (spec_add_field(spec, &PyId_##FIELD, SOURCE->FIELD) == -1) \ + if (spec_add_field(spec, #FIELD, SOURCE->FIELD) == -1) \ goto error;\ } while (0) diff --git a/Modules/_multiprocessing/clinic/multiprocessing.c.h b/Modules/_multiprocessing/clinic/multiprocessing.c.h index 7096442bd0b..885cd5c2fff 100644 --- a/Modules/_multiprocessing/clinic/multiprocessing.c.h +++ b/Modules/_multiprocessing/clinic/multiprocessing.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(MS_WINDOWS) PyDoc_STRVAR(_multiprocessing_closesocket__doc__, @@ -21,7 +27,8 @@ _multiprocessing_closesocket(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HANDLE handle; - if (!PyArg_Parse(arg, ""F_HANDLE":closesocket", &handle)) { + handle = PyLong_AsVoidPtr(arg); + if (!handle && PyErr_Occurred()) { goto exit; } return_value = _multiprocessing_closesocket_impl(module, handle); @@ -40,7 +47,7 @@ PyDoc_STRVAR(_multiprocessing_recv__doc__, "\n"); #define _MULTIPROCESSING_RECV_METHODDEF \ - {"recv", (PyCFunction)(void(*)(void))_multiprocessing_recv, METH_FASTCALL, _multiprocessing_recv__doc__}, + {"recv", _PyCFunction_CAST(_multiprocessing_recv), METH_FASTCALL, _multiprocessing_recv__doc__}, static PyObject * _multiprocessing_recv_impl(PyObject *module, HANDLE handle, int size); @@ -52,8 +59,15 @@ _multiprocessing_recv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HANDLE handle; int size; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"i:recv", - &handle, &size)) { + if (!_PyArg_CheckPositional("recv", nargs, 2, 2)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + size = _PyLong_AsInt(args[1]); + if (size == -1 && PyErr_Occurred()) { goto exit; } return_value = _multiprocessing_recv_impl(module, handle, size); @@ -72,7 +86,7 @@ PyDoc_STRVAR(_multiprocessing_send__doc__, "\n"); #define _MULTIPROCESSING_SEND_METHODDEF \ - {"send", (PyCFunction)(void(*)(void))_multiprocessing_send, METH_FASTCALL, _multiprocessing_send__doc__}, + {"send", _PyCFunction_CAST(_multiprocessing_send), METH_FASTCALL, _multiprocessing_send__doc__}, static PyObject * _multiprocessing_send_impl(PyObject *module, HANDLE handle, Py_buffer *buf); @@ -84,8 +98,18 @@ _multiprocessing_send(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HANDLE handle; Py_buffer buf = {NULL, NULL}; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*:send", - &handle, &buf)) { + if (!_PyArg_CheckPositional("send", nargs, 2, 2)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &buf, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&buf, 'C')) { + _PyArg_BadArgument("send", "argument 2", "contiguous buffer", args[1]); goto exit; } return_value = _multiprocessing_send_impl(module, handle, &buf); @@ -148,4 +172,4 @@ exit: #ifndef _MULTIPROCESSING_SEND_METHODDEF #define _MULTIPROCESSING_SEND_METHODDEF #endif /* !defined(_MULTIPROCESSING_SEND_METHODDEF) */ -/*[clinic end generated code: output=418191c446cd5751 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4a6afc67c1f5ec85 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/clinic/posixshmem.c.h b/Modules/_multiprocessing/clinic/posixshmem.c.h index 3424b10a569..df2aa29cfe6 100644 --- a/Modules/_multiprocessing/clinic/posixshmem.c.h +++ b/Modules/_multiprocessing/clinic/posixshmem.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(HAVE_SHM_OPEN) PyDoc_STRVAR(_posixshmem_shm_open__doc__, @@ -11,7 +17,7 @@ PyDoc_STRVAR(_posixshmem_shm_open__doc__, "Open a shared memory object. Returns a file descriptor (integer)."); #define _POSIXSHMEM_SHM_OPEN_METHODDEF \ - {"shm_open", (PyCFunction)(void(*)(void))_posixshmem_shm_open, METH_FASTCALL|METH_KEYWORDS, _posixshmem_shm_open__doc__}, + {"shm_open", _PyCFunction_CAST(_posixshmem_shm_open), METH_FASTCALL|METH_KEYWORDS, _posixshmem_shm_open__doc__}, static int _posixshmem_shm_open_impl(PyObject *module, PyObject *path, int flags, @@ -21,8 +27,31 @@ static PyObject * _posixshmem_shm_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(flags), &_Py_ID(mode), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "flags", "mode", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "shm_open", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "shm_open", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *path; @@ -79,7 +108,7 @@ PyDoc_STRVAR(_posixshmem_shm_unlink__doc__, "region."); #define _POSIXSHMEM_SHM_UNLINK_METHODDEF \ - {"shm_unlink", (PyCFunction)(void(*)(void))_posixshmem_shm_unlink, METH_FASTCALL|METH_KEYWORDS, _posixshmem_shm_unlink__doc__}, + {"shm_unlink", _PyCFunction_CAST(_posixshmem_shm_unlink), METH_FASTCALL|METH_KEYWORDS, _posixshmem_shm_unlink__doc__}, static PyObject * _posixshmem_shm_unlink_impl(PyObject *module, PyObject *path); @@ -88,8 +117,31 @@ static PyObject * _posixshmem_shm_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "shm_unlink", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "shm_unlink", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *path; @@ -120,4 +172,4 @@ exit: #ifndef _POSIXSHMEM_SHM_UNLINK_METHODDEF #define _POSIXSHMEM_SHM_UNLINK_METHODDEF #endif /* !defined(_POSIXSHMEM_SHM_UNLINK_METHODDEF) */ -/*[clinic end generated code: output=bca8e78d0f43ef1a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3f6fee283d5fd0e9 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/clinic/semaphore.c.h b/Modules/_multiprocessing/clinic/semaphore.c.h index e1b9309e9f2..35347169bc1 100644 --- a/Modules/_multiprocessing/clinic/semaphore.c.h +++ b/Modules/_multiprocessing/clinic/semaphore.c.h @@ -2,7 +2,13 @@ preserve [clinic start generated code]*/ -#if defined(MS_WINDOWS) +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +#if defined(HAVE_MP_SEMAPHORE) && defined(MS_WINDOWS) PyDoc_STRVAR(_multiprocessing_SemLock_acquire__doc__, "acquire($self, /, block=True, timeout=None)\n" @@ -11,7 +17,7 @@ PyDoc_STRVAR(_multiprocessing_SemLock_acquire__doc__, "Acquire the semaphore/lock."); #define _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF \ - {"acquire", (PyCFunction)(void(*)(void))_multiprocessing_SemLock_acquire, METH_FASTCALL|METH_KEYWORDS, _multiprocessing_SemLock_acquire__doc__}, + {"acquire", _PyCFunction_CAST(_multiprocessing_SemLock_acquire), METH_FASTCALL|METH_KEYWORDS, _multiprocessing_SemLock_acquire__doc__}, static PyObject * _multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, @@ -21,8 +27,31 @@ static PyObject * _multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(block), &_Py_ID(timeout), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"block", "timeout", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "acquire", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "acquire", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int blocking = 1; @@ -36,8 +65,8 @@ _multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ goto skip_optional_pos; } if (args[0]) { - blocking = _PyLong_AsInt(args[0]); - if (blocking == -1 && PyErr_Occurred()) { + blocking = PyObject_IsTrue(args[0]); + if (blocking < 0) { goto exit; } if (!--noptargs) { @@ -52,9 +81,9 @@ exit: return return_value; } -#endif /* defined(MS_WINDOWS) */ +#endif /* defined(HAVE_MP_SEMAPHORE) && defined(MS_WINDOWS) */ -#if defined(MS_WINDOWS) +#if defined(HAVE_MP_SEMAPHORE) && defined(MS_WINDOWS) PyDoc_STRVAR(_multiprocessing_SemLock_release__doc__, "release($self, /)\n" @@ -74,9 +103,9 @@ _multiprocessing_SemLock_release(SemLockObject *self, PyObject *Py_UNUSED(ignore return _multiprocessing_SemLock_release_impl(self); } -#endif /* defined(MS_WINDOWS) */ +#endif /* defined(HAVE_MP_SEMAPHORE) && defined(MS_WINDOWS) */ -#if !defined(MS_WINDOWS) +#if defined(HAVE_MP_SEMAPHORE) && !defined(MS_WINDOWS) PyDoc_STRVAR(_multiprocessing_SemLock_acquire__doc__, "acquire($self, /, block=True, timeout=None)\n" @@ -85,7 +114,7 @@ PyDoc_STRVAR(_multiprocessing_SemLock_acquire__doc__, "Acquire the semaphore/lock."); #define _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF \ - {"acquire", (PyCFunction)(void(*)(void))_multiprocessing_SemLock_acquire, METH_FASTCALL|METH_KEYWORDS, _multiprocessing_SemLock_acquire__doc__}, + {"acquire", _PyCFunction_CAST(_multiprocessing_SemLock_acquire), METH_FASTCALL|METH_KEYWORDS, _multiprocessing_SemLock_acquire__doc__}, static PyObject * _multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, @@ -95,8 +124,31 @@ static PyObject * _multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(block), &_Py_ID(timeout), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"block", "timeout", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "acquire", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "acquire", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int blocking = 1; @@ -110,8 +162,8 @@ _multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ goto skip_optional_pos; } if (args[0]) { - blocking = _PyLong_AsInt(args[0]); - if (blocking == -1 && PyErr_Occurred()) { + blocking = PyObject_IsTrue(args[0]); + if (blocking < 0) { goto exit; } if (!--noptargs) { @@ -126,9 +178,9 @@ exit: return return_value; } -#endif /* !defined(MS_WINDOWS) */ +#endif /* defined(HAVE_MP_SEMAPHORE) && !defined(MS_WINDOWS) */ -#if !defined(MS_WINDOWS) +#if defined(HAVE_MP_SEMAPHORE) && !defined(MS_WINDOWS) PyDoc_STRVAR(_multiprocessing_SemLock_release__doc__, "release($self, /)\n" @@ -148,7 +200,9 @@ _multiprocessing_SemLock_release(SemLockObject *self, PyObject *Py_UNUSED(ignore return _multiprocessing_SemLock_release_impl(self); } -#endif /* !defined(MS_WINDOWS) */ +#endif /* defined(HAVE_MP_SEMAPHORE) && !defined(MS_WINDOWS) */ + +#if defined(HAVE_MP_SEMAPHORE) static PyObject * _multiprocessing_SemLock_impl(PyTypeObject *type, int kind, int value, @@ -158,8 +212,31 @@ static PyObject * _multiprocessing_SemLock(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(kind), &_Py_ID(value), &_Py_ID(maxvalue), &_Py_ID(name), &_Py_ID(unlink), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"kind", "value", "maxvalue", "name", "unlink", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "SemLock", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "SemLock", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -198,8 +275,8 @@ _multiprocessing_SemLock(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - unlink = _PyLong_AsInt(fastargs[4]); - if (unlink == -1 && PyErr_Occurred()) { + unlink = PyObject_IsTrue(fastargs[4]); + if (unlink < 0) { goto exit; } return_value = _multiprocessing_SemLock_impl(type, kind, value, maxvalue, name, unlink); @@ -208,13 +285,17 @@ exit: return return_value; } +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#if defined(HAVE_MP_SEMAPHORE) + PyDoc_STRVAR(_multiprocessing_SemLock__rebuild__doc__, "_rebuild($type, handle, kind, maxvalue, name, /)\n" "--\n" "\n"); #define _MULTIPROCESSING_SEMLOCK__REBUILD_METHODDEF \ - {"_rebuild", (PyCFunction)(void(*)(void))_multiprocessing_SemLock__rebuild, METH_FASTCALL|METH_CLASS, _multiprocessing_SemLock__rebuild__doc__}, + {"_rebuild", _PyCFunction_CAST(_multiprocessing_SemLock__rebuild), METH_FASTCALL|METH_CLASS, _multiprocessing_SemLock__rebuild__doc__}, static PyObject * _multiprocessing_SemLock__rebuild_impl(PyTypeObject *type, SEM_HANDLE handle, @@ -240,6 +321,10 @@ exit: return return_value; } +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#if defined(HAVE_MP_SEMAPHORE) + PyDoc_STRVAR(_multiprocessing_SemLock__count__doc__, "_count($self, /)\n" "--\n" @@ -258,6 +343,10 @@ _multiprocessing_SemLock__count(SemLockObject *self, PyObject *Py_UNUSED(ignored return _multiprocessing_SemLock__count_impl(self); } +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#if defined(HAVE_MP_SEMAPHORE) + PyDoc_STRVAR(_multiprocessing_SemLock__is_mine__doc__, "_is_mine($self, /)\n" "--\n" @@ -276,6 +365,10 @@ _multiprocessing_SemLock__is_mine(SemLockObject *self, PyObject *Py_UNUSED(ignor return _multiprocessing_SemLock__is_mine_impl(self); } +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#if defined(HAVE_MP_SEMAPHORE) + PyDoc_STRVAR(_multiprocessing_SemLock__get_value__doc__, "_get_value($self, /)\n" "--\n" @@ -294,6 +387,10 @@ _multiprocessing_SemLock__get_value(SemLockObject *self, PyObject *Py_UNUSED(ign return _multiprocessing_SemLock__get_value_impl(self); } +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#if defined(HAVE_MP_SEMAPHORE) + PyDoc_STRVAR(_multiprocessing_SemLock__is_zero__doc__, "_is_zero($self, /)\n" "--\n" @@ -312,6 +409,10 @@ _multiprocessing_SemLock__is_zero(SemLockObject *self, PyObject *Py_UNUSED(ignor return _multiprocessing_SemLock__is_zero_impl(self); } +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#if defined(HAVE_MP_SEMAPHORE) + PyDoc_STRVAR(_multiprocessing_SemLock__after_fork__doc__, "_after_fork($self, /)\n" "--\n" @@ -330,6 +431,10 @@ _multiprocessing_SemLock__after_fork(SemLockObject *self, PyObject *Py_UNUSED(ig return _multiprocessing_SemLock__after_fork_impl(self); } +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#if defined(HAVE_MP_SEMAPHORE) + PyDoc_STRVAR(_multiprocessing_SemLock___enter____doc__, "__enter__($self, /)\n" "--\n" @@ -348,6 +453,10 @@ _multiprocessing_SemLock___enter__(SemLockObject *self, PyObject *Py_UNUSED(igno return _multiprocessing_SemLock___enter___impl(self); } +#endif /* defined(HAVE_MP_SEMAPHORE) */ + +#if defined(HAVE_MP_SEMAPHORE) + PyDoc_STRVAR(_multiprocessing_SemLock___exit____doc__, "__exit__($self, exc_type=None, exc_value=None, exc_tb=None, /)\n" "--\n" @@ -355,7 +464,7 @@ PyDoc_STRVAR(_multiprocessing_SemLock___exit____doc__, "Exit the semaphore/lock."); #define _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF \ - {"__exit__", (PyCFunction)(void(*)(void))_multiprocessing_SemLock___exit__, METH_FASTCALL, _multiprocessing_SemLock___exit____doc__}, + {"__exit__", _PyCFunction_CAST(_multiprocessing_SemLock___exit__), METH_FASTCALL, _multiprocessing_SemLock___exit____doc__}, static PyObject * _multiprocessing_SemLock___exit___impl(SemLockObject *self, @@ -392,6 +501,8 @@ exit: return return_value; } +#endif /* defined(HAVE_MP_SEMAPHORE) */ + #ifndef _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF #define _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF #endif /* !defined(_MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF) */ @@ -399,4 +510,36 @@ exit: #ifndef _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF #define _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF #endif /* !defined(_MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF) */ -/*[clinic end generated code: output=e7fd938150601fe5 input=a9049054013a1b77]*/ + +#ifndef _MULTIPROCESSING_SEMLOCK__REBUILD_METHODDEF + #define _MULTIPROCESSING_SEMLOCK__REBUILD_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK__REBUILD_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK__COUNT_METHODDEF + #define _MULTIPROCESSING_SEMLOCK__COUNT_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK__COUNT_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK__IS_MINE_METHODDEF + #define _MULTIPROCESSING_SEMLOCK__IS_MINE_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK__IS_MINE_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK__GET_VALUE_METHODDEF + #define _MULTIPROCESSING_SEMLOCK__GET_VALUE_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK__GET_VALUE_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK__IS_ZERO_METHODDEF + #define _MULTIPROCESSING_SEMLOCK__IS_ZERO_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK__IS_ZERO_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK__AFTER_FORK_METHODDEF + #define _MULTIPROCESSING_SEMLOCK__AFTER_FORK_METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK__AFTER_FORK_METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK___ENTER___METHODDEF + #define _MULTIPROCESSING_SEMLOCK___ENTER___METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK___ENTER___METHODDEF) */ + +#ifndef _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF + #define _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF +#endif /* !defined(_MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF) */ +/*[clinic end generated code: output=dae57a702cc01512 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/multiprocessing.c b/Modules/_multiprocessing/multiprocessing.c index bec23517fca..2463e1e1a8b 100644 --- a/Modules/_multiprocessing/multiprocessing.c +++ b/Modules/_multiprocessing/multiprocessing.c @@ -14,8 +14,16 @@ class HANDLE_converter(CConverter): type = "HANDLE" format_unit = '"F_HANDLE"' + def parse_arg(self, argname, displayname): + return """ + {paramname} = PyLong_AsVoidPtr({argname}); + if (!{paramname} && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.parser_name) + [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=9fad6080b79ace91]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=3e537d244034affb]*/ /*[clinic input] module _multiprocessing @@ -186,36 +194,41 @@ static PyMethodDef module_methods[] = { static int multiprocessing_exec(PyObject *module) { -#if defined(MS_WINDOWS) || \ - (defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)) +#ifdef HAVE_MP_SEMAPHORE - /* Add _PyMp_SemLock type to module */ - if (PyModule_AddType(module, &_PyMp_SemLockType) < 0) { + PyTypeObject *semlock_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &_PyMp_SemLockType_spec, NULL); + + if (semlock_type == NULL) { + return -1; + } + int rc = PyModule_AddType(module, semlock_type); + Py_DECREF(semlock_type); + if (rc < 0) { return -1; } - { - PyObject *py_sem_value_max; - /* Some systems define SEM_VALUE_MAX as an unsigned value that - * causes it to be negative when used as an int (NetBSD). - * - * Issue #28152: Use (0) instead of 0 to fix a warning on dead code - * when using clang -Wunreachable-code. */ - if ((int)(SEM_VALUE_MAX) < (0)) - py_sem_value_max = PyLong_FromLong(INT_MAX); - else - py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX); - - if (py_sem_value_max == NULL) { - return -1; - } - if (PyDict_SetItemString(_PyMp_SemLockType.tp_dict, "SEM_VALUE_MAX", - py_sem_value_max) < 0) { - Py_DECREF(py_sem_value_max); - return -1; - } - Py_DECREF(py_sem_value_max); + PyObject *py_sem_value_max; + /* Some systems define SEM_VALUE_MAX as an unsigned value that + * causes it to be negative when used as an int (NetBSD). + * + * Issue #28152: Use (0) instead of 0 to fix a warning on dead code + * when using clang -Wunreachable-code. */ + if ((int)(SEM_VALUE_MAX) < (0)) { + py_sem_value_max = PyLong_FromLong(INT_MAX); } + else { + py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX); + } + if (py_sem_value_max == NULL) { + return -1; + } + if (PyDict_SetItemString(semlock_type->tp_dict, "SEM_VALUE_MAX", + py_sem_value_max) < 0) { + Py_DECREF(py_sem_value_max); + return -1; + } + Py_DECREF(py_sem_value_max); #endif @@ -269,6 +282,7 @@ static PyModuleDef_Slot multiprocessing_slots[] = { static struct PyModuleDef multiprocessing_module = { PyModuleDef_HEAD_INIT, .m_name = "_multiprocessing", + .m_size = 0, .m_methods = module_methods, .m_slots = multiprocessing_slots, }; diff --git a/Modules/_multiprocessing/multiprocessing.h b/Modules/_multiprocessing/multiprocessing.h index 277963bc157..b595e5a8dd1 100644 --- a/Modules/_multiprocessing/multiprocessing.h +++ b/Modules/_multiprocessing/multiprocessing.h @@ -21,9 +21,11 @@ # endif # define SEM_HANDLE HANDLE # define SEM_VALUE_MAX LONG_MAX +# define HAVE_MP_SEMAPHORE #else # include /* O_CREAT and O_EXCL */ # if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) +# define HAVE_MP_SEMAPHORE # include typedef sem_t *SEM_HANDLE; # endif @@ -87,7 +89,7 @@ PyObject *_PyMp_SetError(PyObject *Type, int num); * Externs - not all will really exist on all platforms */ -extern PyTypeObject _PyMp_SemLockType; +extern PyType_Spec _PyMp_SemLockType_spec; extern PyObject *_PyMp_sem_unlink(const char *name); #endif /* MULTIPROCESSING_H */ diff --git a/Modules/_multiprocessing/semaphore.c b/Modules/_multiprocessing/semaphore.c index 9a2d1f85c92..897b8db7110 100644 --- a/Modules/_multiprocessing/semaphore.c +++ b/Modules/_multiprocessing/semaphore.c @@ -9,6 +9,8 @@ #include "multiprocessing.h" +#ifdef HAVE_MP_SEMAPHORE + enum { RECURSIVE_MUTEX, SEMAPHORE }; typedef struct { @@ -77,7 +79,7 @@ _GetSemaphoreValue(HANDLE handle, long *value) /*[clinic input] _multiprocessing.SemLock.acquire - block as blocking: bool(accept={int}) = True + block as blocking: bool = True timeout as timeout_obj: object = None Acquire the semaphore/lock. @@ -86,7 +88,7 @@ Acquire the semaphore/lock. static PyObject * _multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, PyObject *timeout_obj) -/*[clinic end generated code: output=f9998f0b6b0b0872 input=86f05662cf753eb4]*/ +/*[clinic end generated code: output=f9998f0b6b0b0872 input=e5b45f5cbb775166]*/ { double timeout; DWORD res, full_msecs, nhandles; @@ -293,7 +295,7 @@ sem_timedwait_save(sem_t *sem, struct timespec *deadline, PyThreadState *_save) /*[clinic input] _multiprocessing.SemLock.acquire - block as blocking: bool(accept={int}) = True + block as blocking: bool = True timeout as timeout_obj: object = None Acquire the semaphore/lock. @@ -302,7 +304,7 @@ Acquire the semaphore/lock. static PyObject * _multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, PyObject *timeout_obj) -/*[clinic end generated code: output=f9998f0b6b0b0872 input=86f05662cf753eb4]*/ +/*[clinic end generated code: output=f9998f0b6b0b0872 input=e5b45f5cbb775166]*/ { int res, err = 0; struct timespec deadline = {0}; @@ -452,9 +454,7 @@ static PyObject * newsemlockobject(PyTypeObject *type, SEM_HANDLE handle, int kind, int maxvalue, char *name) { - SemLockObject *self; - - self = PyObject_New(SemLockObject, type); + SemLockObject *self = (SemLockObject *)type->tp_alloc(type, 0); if (!self) return NULL; self->handle = handle; @@ -474,14 +474,14 @@ _multiprocessing.SemLock.__new__ value: int maxvalue: int name: str - unlink: bool(accept={int}) + unlink: bool [clinic start generated code]*/ static PyObject * _multiprocessing_SemLock_impl(PyTypeObject *type, int kind, int value, int maxvalue, const char *name, int unlink) -/*[clinic end generated code: output=30727e38f5f7577a input=b378c3ee27d3a0fa]*/ +/*[clinic end generated code: output=30727e38f5f7577a input=fdaeb69814471c5b]*/ { SEM_HANDLE handle = SEM_FAILED; PyObject *result; @@ -568,10 +568,13 @@ _multiprocessing_SemLock__rebuild_impl(PyTypeObject *type, SEM_HANDLE handle, static void semlock_dealloc(SemLockObject* self) { + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); if (self->handle != SEM_FAILED) SEM_CLOSE(self->handle); PyMem_Free(self->name); - PyObject_Free(self); + tp->tp_free(self); + Py_DECREF(tp); } /*[clinic input] @@ -701,6 +704,13 @@ _multiprocessing_SemLock___exit___impl(SemLockObject *self, return _multiprocessing_SemLock_release_impl(self); } +static int +semlock_traverse(SemLockObject *s, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(s)); + return 0; +} + /* * Semaphore methods */ @@ -739,45 +749,26 @@ static PyMemberDef semlock_members[] = { * Semaphore type */ -PyTypeObject _PyMp_SemLockType = { - PyVarObject_HEAD_INIT(NULL, 0) - /* tp_name */ "_multiprocessing.SemLock", - /* tp_basicsize */ sizeof(SemLockObject), - /* tp_itemsize */ 0, - /* tp_dealloc */ (destructor)semlock_dealloc, - /* tp_vectorcall_offset */ 0, - /* tp_getattr */ 0, - /* tp_setattr */ 0, - /* tp_as_async */ 0, - /* tp_repr */ 0, - /* tp_as_number */ 0, - /* tp_as_sequence */ 0, - /* tp_as_mapping */ 0, - /* tp_hash */ 0, - /* tp_call */ 0, - /* tp_str */ 0, - /* tp_getattro */ 0, - /* tp_setattro */ 0, - /* tp_as_buffer */ 0, - /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - /* tp_doc */ "Semaphore/Mutex type", - /* tp_traverse */ 0, - /* tp_clear */ 0, - /* tp_richcompare */ 0, - /* tp_weaklistoffset */ 0, - /* tp_iter */ 0, - /* tp_iternext */ 0, - /* tp_methods */ semlock_methods, - /* tp_members */ semlock_members, - /* tp_getset */ 0, - /* tp_base */ 0, - /* tp_dict */ 0, - /* tp_descr_get */ 0, - /* tp_descr_set */ 0, - /* tp_dictoffset */ 0, - /* tp_init */ 0, - /* tp_alloc */ 0, - /* tp_new */ _multiprocessing_SemLock, +static PyType_Slot _PyMp_SemLockType_slots[] = { + {Py_tp_dealloc, semlock_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_setattro, PyObject_GenericSetAttr}, + {Py_tp_methods, semlock_methods}, + {Py_tp_members, semlock_members}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, _multiprocessing_SemLock}, + {Py_tp_traverse, semlock_traverse}, + {Py_tp_free, PyObject_GC_Del}, + {Py_tp_doc, (void *)PyDoc_STR("Semaphore/Mutex type")}, + {0, 0}, +}; + +PyType_Spec _PyMp_SemLockType_spec = { + .name = "_multiprocessing.SemLock", + .basicsize = sizeof(SemLockObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), + .slots = _PyMp_SemLockType_slots, }; /* @@ -794,3 +785,5 @@ _PyMp_sem_unlink(const char *name) Py_RETURN_NONE; } + +#endif // HAVE_MP_SEMAPHORE diff --git a/Modules/_opcode.c b/Modules/_opcode.c index 39e30669559..99be9774177 100644 --- a/Modules/_opcode.c +++ b/Modules/_opcode.c @@ -60,12 +60,7 @@ _opcode_stack_effect_impl(PyObject *module, int opcode, PyObject *oparg, "stack_effect: jump must be False, True or None"); return -1; } - if (IS_ARTIFICIAL(opcode)) { - effect = PY_INVALID_STACK_EFFECT; - } - else { - effect = PyCompile_OpcodeStackEffectWithJump(opcode, oparg_int, jump_int); - } + effect = PyCompile_OpcodeStackEffectWithJump(opcode, oparg_int, jump_int); if (effect == PY_INVALID_STACK_EFFECT) { PyErr_SetString(PyExc_ValueError, "invalid opcode or oparg"); @@ -85,7 +80,7 @@ static PyObject * _opcode_get_specialization_stats_impl(PyObject *module) /*[clinic end generated code: output=fcbc32fdfbec5c17 input=e1f60db68d8ce5f6]*/ { -#if COLLECT_SPECIALIZATION_STATS +#ifdef Py_STATS return _Py_GetSpecializationStats(); #else Py_RETURN_NONE; diff --git a/Modules/_operator.c b/Modules/_operator.c index b3a8bef2eae..4f2367150ee 100644 --- a/Modules/_operator.c +++ b/Modules/_operator.c @@ -1,5 +1,7 @@ #include "Python.h" #include "pycore_moduleobject.h" // _PyModule_GetState() +#include "structmember.h" // PyMemberDef +#include "pycore_runtime.h" // _Py_ID() #include "clinic/_operator.c.h" typedef struct { @@ -720,8 +722,7 @@ _operator_is_not_impl(PyObject *module, PyObject *a, PyObject *b) { PyObject *result; result = (a != b) ? Py_True : Py_False; - Py_INCREF(result); - return result; + return Py_NewRef(result); } /* compare_digest **********************************************************/ @@ -729,9 +730,9 @@ _operator_is_not_impl(PyObject *module, PyObject *a, PyObject *b) /* * timing safe compare * - * Returns 1 of the strings are equal. + * Returns 1 if the strings are equal. * In case of len(a) != len(b) the function tries to keep the timing - * dependent on the length of b. CPU cache locally may still alter timing + * dependent on the length of b. CPU cache locality may still alter timing * a bit. */ static int @@ -837,7 +838,7 @@ _operator__compare_digest_impl(PyObject *module, PyObject *a, PyObject *b) PyUnicode_GET_LENGTH(a), PyUnicode_GET_LENGTH(b)); } - /* fallback to buffer interface for bytes, bytesarray and other */ + /* fallback to buffer interface for bytes, bytearray and other */ else { Py_buffer view_a; Py_buffer view_b; @@ -891,7 +892,7 @@ PyDoc_STRVAR(_operator_call__doc__, "Same as obj(*args, **kwargs)."); #define _OPERATOR_CALL_METHODDEF \ - {"call", (PyCFunction)(void(*)(void))_operator_call, METH_FASTCALL | METH_KEYWORDS, _operator_call__doc__}, + {"call", _PyCFunction_CAST(_operator_call), METH_FASTCALL | METH_KEYWORDS, _operator_call__doc__}, static PyObject * _operator_call(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -973,8 +974,15 @@ typedef struct { Py_ssize_t nitems; PyObject *item; Py_ssize_t index; // -1 unless *item* is a single non-negative integer index + vectorcallfunc vectorcall; } itemgetterobject; +// Forward declarations +static PyObject * +itemgetter_vectorcall(PyObject *, PyObject *const *, size_t, PyObject *); +static PyObject * +itemgetter_call_impl(itemgetterobject *, PyObject *); + /* AC 3.5: treats first argument as an iterable, otherwise uses *args */ static PyObject * itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -1001,8 +1009,7 @@ itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - Py_INCREF(item); - ig->item = item; + ig->item = Py_NewRef(item); ig->nitems = nitems; ig->index = -1; if (PyLong_CheckExact(item)) { @@ -1020,6 +1027,7 @@ itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } + ig->vectorcall = (vectorcallfunc)itemgetter_vectorcall; PyObject_GC_Track(ig); return (PyObject *)ig; } @@ -1052,24 +1060,40 @@ itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg) static PyObject * itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw) { - PyObject *obj, *result; - Py_ssize_t i, nitems=ig->nitems; - assert(PyTuple_CheckExact(args)); if (!_PyArg_NoKeywords("itemgetter", kw)) return NULL; if (!_PyArg_CheckPositional("itemgetter", PyTuple_GET_SIZE(args), 1, 1)) return NULL; + return itemgetter_call_impl(ig, PyTuple_GET_ITEM(args, 0)); +} - obj = PyTuple_GET_ITEM(args, 0); +static PyObject * +itemgetter_vectorcall(PyObject *ig, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + if (!_PyArg_NoKwnames("itemgetter", kwnames)) { + return NULL; + } + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (!_PyArg_CheckPositional("itemgetter", nargs, 1, 1)) { + return NULL; + } + return itemgetter_call_impl((itemgetterobject *)ig, args[0]); +} + +static PyObject * +itemgetter_call_impl(itemgetterobject *ig, PyObject *obj) +{ + PyObject *result; + Py_ssize_t i, nitems=ig->nitems; if (nitems == 1) { if (ig->index >= 0 && PyTuple_CheckExact(obj) && ig->index < PyTuple_GET_SIZE(obj)) { result = PyTuple_GET_ITEM(obj, ig->index); - Py_INCREF(result); - return result; + return Py_NewRef(result); } return PyObject_GetItem(obj, ig->item); } @@ -1129,9 +1153,13 @@ static PyMethodDef itemgetter_methods[] = { {NULL} }; +static PyMemberDef itemgetter_members[] = { + {"__vectorcalloffset__", T_PYSSIZET, offsetof(itemgetterobject, vectorcall), READONLY}, + {NULL} /* Sentinel */ +}; + PyDoc_STRVAR(itemgetter_doc, -"itemgetter(item, ...) --> itemgetter object\n\ -\n\ +"itemgetter(item, /, *items)\n--\n\n\ Return a callable object that fetches the given item(s) from its operand.\n\ After f = itemgetter(2), the call f(r) returns r[2].\n\ After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])"); @@ -1143,6 +1171,7 @@ static PyType_Slot itemgetter_type_slots[] = { {Py_tp_traverse, itemgetter_traverse}, {Py_tp_clear, itemgetter_clear}, {Py_tp_methods, itemgetter_methods}, + {Py_tp_members, itemgetter_members}, {Py_tp_new, itemgetter_new}, {Py_tp_getattro, PyObject_GenericGetAttr}, {Py_tp_repr, itemgetter_repr}, @@ -1154,7 +1183,7 @@ static PyType_Spec itemgetter_type_spec = { .basicsize = sizeof(itemgetterobject), .itemsize = 0, .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_IMMUTABLETYPE), + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_VECTORCALL), .slots = itemgetter_type_slots, }; @@ -1164,8 +1193,15 @@ typedef struct { PyObject_HEAD Py_ssize_t nattrs; PyObject *attr; + vectorcallfunc vectorcall; } attrgetterobject; +// Forward declarations +static PyObject * +attrgetter_vectorcall(PyObject *, PyObject *const *, size_t, PyObject *); +static PyObject * +attrgetter_call_impl(attrgetterobject *, PyObject *); + /* AC 3.5: treats first argument as an iterable, otherwise uses *args */ static PyObject * attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -1190,9 +1226,6 @@ attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) /* prepare attr while checking args */ for (idx = 0; idx < nattrs; ++idx) { PyObject *item = PyTuple_GET_ITEM(args, idx); - Py_ssize_t item_len; - const void *data; - unsigned int kind; int dot_count; if (!PyUnicode_Check(item)) { @@ -1205,11 +1238,11 @@ attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_DECREF(attr); return NULL; } - item_len = PyUnicode_GET_LENGTH(item); - kind = PyUnicode_KIND(item); - data = PyUnicode_DATA(item); + Py_ssize_t item_len = PyUnicode_GET_LENGTH(item); + int kind = PyUnicode_KIND(item); + const void *data = PyUnicode_DATA(item); - /* check whethere the string is dotted */ + /* check whether the string is dotted */ dot_count = 0; for (char_idx = 0; char_idx < item_len; ++char_idx) { if (PyUnicode_READ(kind, data, char_idx) == '.') @@ -1275,6 +1308,7 @@ attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ag->attr = attr; ag->nattrs = nattrs; + ag->vectorcall = (vectorcallfunc)attrgetter_vectorcall; PyObject_GC_Track(ag); return (PyObject *)ag; @@ -1341,16 +1375,36 @@ dotted_getattr(PyObject *obj, PyObject *attr) static PyObject * attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw) { - PyObject *obj, *result; - Py_ssize_t i, nattrs=ag->nattrs; - if (!_PyArg_NoKeywords("attrgetter", kw)) return NULL; if (!_PyArg_CheckPositional("attrgetter", PyTuple_GET_SIZE(args), 1, 1)) return NULL; - obj = PyTuple_GET_ITEM(args, 0); - if (ag->nattrs == 1) /* ag->attr is always a tuple */ + return attrgetter_call_impl(ag, PyTuple_GET_ITEM(args, 0)); +} + +static PyObject * +attrgetter_vectorcall(PyObject *ag, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + if (!_PyArg_NoKwnames("attrgetter", kwnames)) { + return NULL; + } + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (!_PyArg_CheckPositional("attrgetter", nargs, 1, 1)) { + return NULL; + } + return attrgetter_call_impl((attrgetterobject *)ag, args[0]); +} + +static PyObject * +attrgetter_call_impl(attrgetterobject *ag, PyObject *obj) +{ + PyObject *result; + Py_ssize_t i, nattrs=ag->nattrs; + + if (ag->nattrs == 1) { + /* ag->attr is always a tuple */ return dotted_getattr(obj, PyTuple_GET_ITEM(ag->attr, 0)); + } assert(PyTuple_Check(ag->attr)); assert(PyTuple_GET_SIZE(ag->attr) == nattrs); @@ -1383,8 +1437,7 @@ dotjoinattr(PyObject *attr, PyObject **attrsep) } return PyUnicode_Join(*attrsep, attr); } else { - Py_INCREF(attr); - return attr; + return Py_NewRef(attr); } } @@ -1459,9 +1512,13 @@ static PyMethodDef attrgetter_methods[] = { {NULL} }; +static PyMemberDef attrgetter_members[] = { + {"__vectorcalloffset__", T_PYSSIZET, offsetof(attrgetterobject, vectorcall), READONLY}, + {NULL} /* Sentinel*/ +}; + PyDoc_STRVAR(attrgetter_doc, -"attrgetter(attr, ...) --> attrgetter object\n\ -\n\ +"attrgetter(attr, /, *attrs)\n--\n\n\ Return a callable object that fetches the given attribute(s) from its operand.\n\ After f = attrgetter('name'), the call f(r) returns r.name.\n\ After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).\n\ @@ -1475,6 +1532,7 @@ static PyType_Slot attrgetter_type_slots[] = { {Py_tp_traverse, attrgetter_traverse}, {Py_tp_clear, attrgetter_clear}, {Py_tp_methods, attrgetter_methods}, + {Py_tp_members, attrgetter_members}, {Py_tp_new, attrgetter_new}, {Py_tp_getattro, PyObject_GenericGetAttr}, {Py_tp_repr, attrgetter_repr}, @@ -1486,7 +1544,7 @@ static PyType_Spec attrgetter_type_spec = { .basicsize = sizeof(attrgetterobject), .itemsize = 0, .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_IMMUTABLETYPE), + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_VECTORCALL), .slots = attrgetter_type_slots, }; @@ -1532,8 +1590,7 @@ methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyUnicode_InternInPlace(&name); mc->name = name; - Py_XINCREF(kwds); - mc->kwds = kwds; + mc->kwds = Py_XNewRef(kwds); mc->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); if (mc->args == NULL) { @@ -1678,27 +1735,19 @@ methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored)) newargs = PyTuple_New(1 + callargcount); if (newargs == NULL) return NULL; - Py_INCREF(mc->name); - PyTuple_SET_ITEM(newargs, 0, mc->name); + PyTuple_SET_ITEM(newargs, 0, Py_NewRef(mc->name)); for (i = 0; i < callargcount; ++i) { PyObject *arg = PyTuple_GET_ITEM(mc->args, i); - Py_INCREF(arg); - PyTuple_SET_ITEM(newargs, i + 1, arg); + PyTuple_SET_ITEM(newargs, i + 1, Py_NewRef(arg)); } return Py_BuildValue("ON", Py_TYPE(mc), newargs); } else { - PyObject *functools; PyObject *partial; PyObject *constructor; PyObject *newargs[2]; - _Py_IDENTIFIER(partial); - functools = PyImport_ImportModule("functools"); - if (!functools) - return NULL; - partial = _PyObject_GetAttrId(functools, &PyId_partial); - Py_DECREF(functools); + partial = _PyImport_GetModuleAttrString("functools", "partial"); if (!partial) return NULL; @@ -1717,8 +1766,7 @@ static PyMethodDef methodcaller_methods[] = { {NULL} }; PyDoc_STRVAR(methodcaller_doc, -"methodcaller(name, ...) --> methodcaller object\n\ -\n\ +"methodcaller(name, /, *args, **kwargs)\n--\n\n\ Return a callable object that calls the given method on its operand.\n\ After f = methodcaller('name'), the call f(r) returns r.name().\n\ After g = methodcaller('name', 'date', foo=1), the call g(r) returns\n\ diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 0d9e57aa90d..1b34977806b 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -9,8 +9,10 @@ #endif #include "Python.h" -#include "pycore_floatobject.h" // _PyFloat_Pack8() +#include "pycore_ceval.h" // _Py_EnterRecursiveCall() #include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_runtime.h" // _Py_ID() +#include "pycore_pystate.h" // _PyThreadState_GET() #include "structmember.h" // PyMemberDef #include // strtol() @@ -35,6 +37,13 @@ enum { DEFAULT_PROTOCOL = 4 }; +#ifdef MS_WINDOWS +// These are already typedefs from windows.h, pulled in via pycore_runtime.h. +#define FLOAT FLOAT_ +#define INT INT_ +#define LONG LONG_ +#endif + /* Pickle opcodes. These must be kept updated with pickle.py. Extensive docs are in pickletools.py. */ enum opcode { @@ -223,11 +232,8 @@ _Pickle_InitState(PickleState *st) { PyObject *copyreg = NULL; PyObject *compat_pickle = NULL; - PyObject *codecs = NULL; - PyObject *functools = NULL; - _Py_IDENTIFIER(getattr); - st->getattr = _PyEval_GetBuiltinId(&PyId_getattr); + st->getattr = _PyEval_GetBuiltin(&_Py_ID(getattr)); if (st->getattr == NULL) goto error; @@ -321,10 +327,7 @@ _Pickle_InitState(PickleState *st) } Py_CLEAR(compat_pickle); - codecs = PyImport_ImportModule("codecs"); - if (codecs == NULL) - goto error; - st->codecs_encode = PyObject_GetAttrString(codecs, "encode"); + st->codecs_encode = _PyImport_GetModuleAttrString("codecs", "encode"); if (st->codecs_encode == NULL) { goto error; } @@ -334,23 +337,16 @@ _Pickle_InitState(PickleState *st) Py_TYPE(st->codecs_encode)->tp_name); goto error; } - Py_CLEAR(codecs); - functools = PyImport_ImportModule("functools"); - if (!functools) - goto error; - st->partial = PyObject_GetAttrString(functools, "partial"); + st->partial = _PyImport_GetModuleAttrString("functools", "partial"); if (!st->partial) goto error; - Py_CLEAR(functools); return 0; error: Py_CLEAR(copyreg); Py_CLEAR(compat_pickle); - Py_CLEAR(codecs); - Py_CLEAR(functools); _Pickle_ClearState(st); return -1; } @@ -373,7 +369,7 @@ _Pickle_FastCall(PyObject *func, PyObject *obj) /* Retrieve and deconstruct a method for avoiding a reference cycle (pickler -> bound method of pickler -> pickler) */ static int -init_method_ref(PyObject *self, _Py_Identifier *name, +init_method_ref(PyObject *self, PyObject *name, PyObject **method_func, PyObject **method_self) { PyObject *func, *func2; @@ -381,7 +377,7 @@ init_method_ref(PyObject *self, _Py_Identifier *name, /* *method_func and *method_self should be consistent. All refcount decrements should be occurred after setting *method_self and *method_func. */ - ret = _PyObject_LookupAttrId(self, name, &func); + ret = _PyObject_LookupAttr(self, name, &func); if (func == NULL) { *method_self = NULL; Py_CLEAR(*method_func); @@ -390,10 +386,9 @@ init_method_ref(PyObject *self, _Py_Identifier *name, if (PyMethod_Check(func) && PyMethod_GET_SELF(func) == self) { /* Deconstruct a bound Python method */ - func2 = PyMethod_GET_FUNCTION(func); - Py_INCREF(func2); *method_self = self; /* borrowed */ - Py_XSETREF(*method_func, func2); + func2 = PyMethod_GET_FUNCTION(func); + Py_XSETREF(*method_func, Py_NewRef(func2)); Py_DECREF(func); return 0; } @@ -412,8 +407,7 @@ reconstruct_method(PyObject *func, PyObject *self) return PyMethod_New(func, self); } else { - Py_INCREF(func); - return func; + return Py_NewRef(func); } } @@ -911,8 +905,7 @@ PyMemoTable_Set(PyMemoTable *self, PyObject *key, Py_ssize_t value) entry->me_value = value; return 0; } - Py_INCREF(key); - entry->me_key = key; + entry->me_key = Py_NewRef(key); entry->me_value = value; self->mt_used++; @@ -957,7 +950,7 @@ _write_size64(char *out, size_t value) { size_t i; - Py_BUILD_ASSERT(sizeof(size_t) <= 8); + static_assert(sizeof(size_t) <= 8, "size_t is larger than 64-bit"); for (i = 0; i < sizeof(size_t); i++) { out[i] = (unsigned char)((value >> (8 * i)) & 0xff); @@ -1175,9 +1168,8 @@ _Pickler_SetProtocol(PicklerObject *self, PyObject *protocol, int fix_imports) static int _Pickler_SetOutputStream(PicklerObject *self, PyObject *file) { - _Py_IDENTIFIER(write); assert(file != NULL); - if (_PyObject_LookupAttrId(file, &PyId_write, &self->write) < 0) { + if (_PyObject_LookupAttr(file, &_Py_ID(write), &self->write) < 0) { return -1; } if (self->write == NULL) { @@ -1201,8 +1193,7 @@ _Pickler_SetBufferCallback(PicklerObject *self, PyObject *buffer_callback) return -1; } - Py_XINCREF(buffer_callback); - self->buffer_callback = buffer_callback; + self->buffer_callback = Py_XNewRef(buffer_callback); return 0; } @@ -1548,9 +1539,8 @@ _Unpickler_MemoPut(UnpicklerObject *self, size_t idx, PyObject *value) return -1; assert(idx < self->memo_size); } - Py_INCREF(value); old_item = self->memo[idx]; - self->memo[idx] = value; + self->memo[idx] = Py_NewRef(value); if (old_item != NULL) { Py_DECREF(old_item); } @@ -1636,20 +1626,15 @@ _Unpickler_New(void) static int _Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file) { - _Py_IDENTIFIER(peek); - _Py_IDENTIFIER(read); - _Py_IDENTIFIER(readinto); - _Py_IDENTIFIER(readline); - /* Optional file methods */ - if (_PyObject_LookupAttrId(file, &PyId_peek, &self->peek) < 0) { + if (_PyObject_LookupAttr(file, &_Py_ID(peek), &self->peek) < 0) { return -1; } - if (_PyObject_LookupAttrId(file, &PyId_readinto, &self->readinto) < 0) { + if (_PyObject_LookupAttr(file, &_Py_ID(readinto), &self->readinto) < 0) { return -1; } - (void)_PyObject_LookupAttrId(file, &PyId_read, &self->read); - (void)_PyObject_LookupAttrId(file, &PyId_readline, &self->readline); + (void)_PyObject_LookupAttr(file, &_Py_ID(read), &self->read); + (void)_PyObject_LookupAttr(file, &_Py_ID(readline), &self->readline); if (!self->readline || !self->read) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, @@ -1809,11 +1794,10 @@ memo_put(PicklerObject *self, PyObject *obj) static PyObject * get_dotted_path(PyObject *obj, PyObject *name) { - _Py_static_string(PyId_dot, "."); PyObject *dotted_path; Py_ssize_t i, n; - - dotted_path = PyUnicode_Split(name, _PyUnicode_FromId(&PyId_dot), -1); + _Py_DECLARE_STR(dot, "."); + dotted_path = PyUnicode_Split(name, &_Py_STR(dot), -1); if (dotted_path == NULL) return NULL; n = PyList_GET_SIZE(dotted_path); @@ -1845,8 +1829,7 @@ get_deep_attribute(PyObject *obj, PyObject *names, PyObject **pparent) n = PyList_GET_SIZE(names); for (i = 0; i < n; i++) { PyObject *name = PyList_GET_ITEM(names, i); - Py_XDECREF(parent); - parent = obj; + Py_XSETREF(parent, obj); (void)_PyObject_LookupAttr(parent, name, &obj); if (obj == NULL) { Py_DECREF(parent); @@ -1914,11 +1897,8 @@ whichmodule(PyObject *global, PyObject *dotted_path) PyObject *module = NULL; Py_ssize_t i; PyObject *modules; - _Py_IDENTIFIER(__module__); - _Py_IDENTIFIER(modules); - _Py_IDENTIFIER(__main__); - if (_PyObject_LookupAttrId(global, &PyId___module__, &module_name) < 0) { + if (_PyObject_LookupAttr(global, &_Py_ID(__module__), &module_name) < 0) { return NULL; } if (module_name) { @@ -1932,7 +1912,8 @@ whichmodule(PyObject *global, PyObject *dotted_path) assert(module_name == NULL); /* Fallback on walking sys.modules */ - modules = _PySys_GetObjectId(&PyId_modules); + PyThreadState *tstate = _PyThreadState_GET(); + modules = _PySys_GetAttr(tstate, &_Py_ID(modules)); if (modules == NULL) { PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules"); return NULL; @@ -1941,8 +1922,7 @@ whichmodule(PyObject *global, PyObject *dotted_path) i = 0; while (PyDict_Next(modules, &i, &module_name, &module)) { if (_checkmodule(module_name, module, global, dotted_path) == 0) { - Py_INCREF(module_name); - return module_name; + return Py_NewRef(module_name); } if (PyErr_Occurred()) { return NULL; @@ -1977,9 +1957,8 @@ whichmodule(PyObject *global, PyObject *dotted_path) } /* If no module is found, use __main__. */ - module_name = _PyUnicode_FromId(&PyId___main__); - Py_XINCREF(module_name); - return module_name; + module_name = &_Py_ID(__main__); + return Py_NewRef(module_name); } /* fast_save_enter() and fast_save_leave() are guards against recursive @@ -2245,7 +2224,7 @@ save_float(PicklerObject *self, PyObject *obj) if (self->bin) { char pdata[9]; pdata[0] = BINFLOAT; - if (_PyFloat_Pack8(x, (unsigned char *)&pdata[1], 0) < 0) + if (PyFloat_Pack8(x, &pdata[1], 0) < 0) return -1; if (_Pickler_Write(self, pdata, 9) < 0) return -1; @@ -2427,13 +2406,12 @@ save_bytes(PicklerObject *self, PyObject *obj) PyUnicode_DecodeLatin1(PyBytes_AS_STRING(obj), PyBytes_GET_SIZE(obj), "strict"); - _Py_IDENTIFIER(latin1); if (unicode_str == NULL) return -1; reduce_value = Py_BuildValue("(O(OO))", st->codecs_encode, unicode_str, - _PyUnicode_FromId(&PyId_latin1)); + &_Py_ID(latin1)); Py_DECREF(unicode_str); } @@ -2581,7 +2559,7 @@ raw_unicode_escape(PyObject *obj) char *p; Py_ssize_t i, size; const void *data; - unsigned int kind; + int kind; _PyBytesWriter writer; if (PyUnicode_READY(obj)) @@ -3008,7 +2986,10 @@ batch_list_exact(PicklerObject *self, PyObject *obj) if (PyList_GET_SIZE(obj) == 1) { item = PyList_GET_ITEM(obj, 0); - if (save(self, item, 0) < 0) + Py_INCREF(item); + int err = save(self, item, 0); + Py_DECREF(item); + if (err < 0) return -1; if (_Pickler_Write(self, &append_op, 1) < 0) return -1; @@ -3023,7 +3004,10 @@ batch_list_exact(PicklerObject *self, PyObject *obj) return -1; while (total < PyList_GET_SIZE(obj)) { item = PyList_GET_ITEM(obj, total); - if (save(self, item, 0) < 0) + Py_INCREF(item); + int err = save(self, item, 0); + Py_DECREF(item); + if (err < 0) return -1; total++; if (++this_batch == BATCHSIZE) @@ -3071,21 +3055,21 @@ save_list(PicklerObject *self, PyObject *obj) if (len != 0) { /* Materialize the list elements. */ if (PyList_CheckExact(obj) && self->proto > 0) { - if (Py_EnterRecursiveCall(" while pickling an object")) + if (_Py_EnterRecursiveCall(" while pickling an object")) goto error; status = batch_list_exact(self, obj); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); } else { PyObject *iter = PyObject_GetIter(obj); if (iter == NULL) goto error; - if (Py_EnterRecursiveCall(" while pickling an object")) { + if (_Py_EnterRecursiveCall(" while pickling an object")) { Py_DECREF(iter); goto error; } status = batch_list(self, iter); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(iter); } } @@ -3261,10 +3245,16 @@ batch_dict_exact(PicklerObject *self, PyObject *obj) /* Special-case len(d) == 1 to save space. */ if (dict_size == 1) { PyDict_Next(obj, &ppos, &key, &value); - if (save(self, key, 0) < 0) - return -1; - if (save(self, value, 0) < 0) - return -1; + Py_INCREF(key); + Py_INCREF(value); + if (save(self, key, 0) < 0) { + goto error; + } + if (save(self, value, 0) < 0) { + goto error; + } + Py_CLEAR(key); + Py_CLEAR(value); if (_Pickler_Write(self, &setitem_op, 1) < 0) return -1; return 0; @@ -3276,10 +3266,16 @@ batch_dict_exact(PicklerObject *self, PyObject *obj) if (_Pickler_Write(self, &mark_op, 1) < 0) return -1; while (PyDict_Next(obj, &ppos, &key, &value)) { - if (save(self, key, 0) < 0) - return -1; - if (save(self, value, 0) < 0) - return -1; + Py_INCREF(key); + Py_INCREF(value); + if (save(self, key, 0) < 0) { + goto error; + } + if (save(self, value, 0) < 0) { + goto error; + } + Py_CLEAR(key); + Py_CLEAR(value); if (++i == BATCHSIZE) break; } @@ -3294,6 +3290,10 @@ batch_dict_exact(PicklerObject *self, PyObject *obj) } while (i == BATCHSIZE); return 0; +error: + Py_XDECREF(key); + Py_XDECREF(value); + return -1; } static int @@ -3330,26 +3330,24 @@ save_dict(PicklerObject *self, PyObject *obj) if (PyDict_CheckExact(obj) && self->proto > 0) { /* We can take certain shortcuts if we know this is a dict and not a dict subclass. */ - if (Py_EnterRecursiveCall(" while pickling an object")) + if (_Py_EnterRecursiveCall(" while pickling an object")) goto error; status = batch_dict_exact(self, obj); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); } else { - _Py_IDENTIFIER(items); - - items = _PyObject_CallMethodIdNoArgs(obj, &PyId_items); + items = PyObject_CallMethodNoArgs(obj, &_Py_ID(items)); if (items == NULL) goto error; iter = PyObject_GetIter(items); Py_DECREF(items); if (iter == NULL) goto error; - if (Py_EnterRecursiveCall(" while pickling an object")) { + if (_Py_EnterRecursiveCall(" while pickling an object")) { Py_DECREF(iter); goto error; } status = batch_dict(self, iter); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(iter); } } @@ -3413,7 +3411,10 @@ save_set(PicklerObject *self, PyObject *obj) if (_Pickler_Write(self, &mark_op, 1) < 0) return -1; while (_PySet_NextEntry(obj, &ppos, &item, &hash)) { - if (save(self, item, 0) < 0) + Py_INCREF(item); + int err = save(self, item, 0); + Py_CLEAR(item); + if (err < 0) return -1; if (++i == BATCHSIZE) break; @@ -3548,10 +3549,8 @@ fix_imports(PyObject **module_name, PyObject **global_name) Py_CLEAR(*module_name); Py_CLEAR(*global_name); - Py_INCREF(fixed_module_name); - Py_INCREF(fixed_global_name); - *module_name = fixed_module_name; - *global_name = fixed_global_name; + *module_name = Py_NewRef(fixed_module_name); + *global_name = Py_NewRef(fixed_global_name); return 0; } else if (PyErr_Occurred()) { @@ -3567,8 +3566,7 @@ fix_imports(PyObject **module_name, PyObject **global_name) Py_TYPE(item)->tp_name); return -1; } - Py_INCREF(item); - Py_XSETREF(*module_name, item); + Py_XSETREF(*module_name, Py_NewRef(item)); } else if (PyErr_Occurred()) { return -1; @@ -3589,20 +3587,17 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name) PyObject *cls; PickleState *st = _Pickle_GetGlobalState(); int status = 0; - _Py_IDENTIFIER(__name__); - _Py_IDENTIFIER(__qualname__); const char global_op = GLOBAL; if (name) { - Py_INCREF(name); - global_name = name; + global_name = Py_NewRef(name); } else { - if (_PyObject_LookupAttrId(obj, &PyId___qualname__, &global_name) < 0) + if (_PyObject_LookupAttr(obj, &_Py_ID(__qualname__), &global_name) < 0) goto error; if (global_name == NULL) { - global_name = _PyObject_GetAttrId(obj, &PyId___name__); + global_name = PyObject_GetAttr(obj, &_Py_ID(__name__)); if (global_name == NULL) goto error; } @@ -3630,8 +3625,8 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name) obj, module_name); goto error; } - lastname = PyList_GET_ITEM(dotted_path, PyList_GET_SIZE(dotted_path)-1); - Py_INCREF(lastname); + lastname = Py_NewRef(PyList_GET_ITEM(dotted_path, + PyList_GET_SIZE(dotted_path) - 1)); cls = get_deep_attribute(module, dotted_path, &parent); Py_CLEAR(dotted_path); if (cls == NULL) { @@ -3721,9 +3716,7 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name) else { gen_global: if (parent == module) { - Py_INCREF(lastname); - Py_DECREF(global_name); - global_name = lastname; + Py_SETREF(global_name, Py_NewRef(lastname)); } if (self->proto >= 4) { const char stack_global_op = STACK_GLOBAL; @@ -3923,11 +3916,9 @@ static PyObject * get_class(PyObject *obj) { PyObject *cls; - _Py_IDENTIFIER(__class__); - if (_PyObject_LookupAttrId(obj, &PyId___class__, &cls) == 0) { - cls = (PyObject *) Py_TYPE(obj); - Py_INCREF(cls); + if (_PyObject_LookupAttr(obj, &_Py_ID(__class__), &cls) == 0) { + cls = Py_NewRef(Py_TYPE(obj)); } return cls; } @@ -4008,18 +3999,14 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) if (self->proto >= 2) { PyObject *name; - _Py_IDENTIFIER(__name__); - if (_PyObject_LookupAttrId(callable, &PyId___name__, &name) < 0) { + if (_PyObject_LookupAttr(callable, &_Py_ID(__name__), &name) < 0) { return -1; } if (name != NULL && PyUnicode_Check(name)) { - _Py_IDENTIFIER(__newobj_ex__); - use_newobj_ex = _PyUnicode_EqualToASCIIId( - name, &PyId___newobj_ex__); + use_newobj_ex = _PyUnicode_Equal(name, &_Py_ID(__newobj_ex__)); if (!use_newobj_ex) { - _Py_IDENTIFIER(__newobj__); - use_newobj = _PyUnicode_EqualToASCIIId(name, &PyId___newobj__); + use_newobj = _PyUnicode_Equal(name, &_Py_ID(__newobj__)); } } Py_XDECREF(name); @@ -4071,24 +4058,21 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) PyObject *newargs; PyObject *cls_new; Py_ssize_t i; - _Py_IDENTIFIER(__new__); newargs = PyTuple_New(PyTuple_GET_SIZE(args) + 2); if (newargs == NULL) return -1; - cls_new = _PyObject_GetAttrId(cls, &PyId___new__); + cls_new = PyObject_GetAttr(cls, &_Py_ID(__new__)); if (cls_new == NULL) { Py_DECREF(newargs); return -1; } PyTuple_SET_ITEM(newargs, 0, cls_new); - Py_INCREF(cls); - PyTuple_SET_ITEM(newargs, 1, cls); + PyTuple_SET_ITEM(newargs, 1, Py_NewRef(cls)); for (i = 0; i < PyTuple_GET_SIZE(args); i++) { PyObject *item = PyTuple_GET_ITEM(args, i); - Py_INCREF(item); - PyTuple_SET_ITEM(newargs, i + 2, item); + PyTuple_SET_ITEM(newargs, i + 2, Py_NewRef(item)); } callable = PyObject_Call(st->partial, newargs, kwargs); @@ -4313,9 +4297,9 @@ save(PicklerObject *self, PyObject *obj, int pers_save) return save_unicode(self, obj); } - /* We're only calling Py_EnterRecursiveCall here so that atomic + /* We're only calling _Py_EnterRecursiveCall here so that atomic types above are pickled faster. */ - if (Py_EnterRecursiveCall(" while pickling an object")) { + if (_Py_EnterRecursiveCall(" while pickling an object")) { return -1; } @@ -4360,8 +4344,7 @@ save(PicklerObject *self, PyObject *obj, int pers_save) if (reduce_value != Py_NotImplemented) { goto reduce; } - Py_DECREF(reduce_value); - reduce_value = NULL; + Py_SETREF(reduce_value, NULL); } if (type == &PyType_Type) { @@ -4404,17 +4387,13 @@ save(PicklerObject *self, PyObject *obj, int pers_save) } } if (reduce_func != NULL) { - Py_INCREF(obj); - reduce_value = _Pickle_FastCall(reduce_func, obj); + reduce_value = _Pickle_FastCall(reduce_func, Py_NewRef(obj)); } else if (PyType_IsSubtype(type, &PyType_Type)) { status = save_global(self, obj, NULL); goto done; } else { - _Py_IDENTIFIER(__reduce__); - _Py_IDENTIFIER(__reduce_ex__); - /* XXX: If the __reduce__ method is defined, __reduce_ex__ is automatically defined as __reduce__. While this is convenient, this make it impossible to know which method was actually called. Of @@ -4424,7 +4403,7 @@ save(PicklerObject *self, PyObject *obj, int pers_save) don't actually have to check for a __reduce__ method. */ /* Check for a __reduce_ex__ method. */ - if (_PyObject_LookupAttrId(obj, &PyId___reduce_ex__, &reduce_func) < 0) { + if (_PyObject_LookupAttr(obj, &_Py_ID(__reduce_ex__), &reduce_func) < 0) { goto error; } if (reduce_func != NULL) { @@ -4436,7 +4415,7 @@ save(PicklerObject *self, PyObject *obj, int pers_save) } else { /* Check for a __reduce__ method. */ - if (_PyObject_LookupAttrId(obj, &PyId___reduce__, &reduce_func) < 0) { + if (_PyObject_LookupAttr(obj, &_Py_ID(__reduce__), &reduce_func) < 0) { goto error; } if (reduce_func != NULL) { @@ -4476,7 +4455,7 @@ save(PicklerObject *self, PyObject *obj, int pers_save) } done: - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_XDECREF(reduce_func); Py_XDECREF(reduce_value); @@ -4489,10 +4468,9 @@ dump(PicklerObject *self, PyObject *obj) const char stop_op = STOP; int status = -1; PyObject *tmp; - _Py_IDENTIFIER(reducer_override); - if (_PyObject_LookupAttrId((PyObject *)self, &PyId_reducer_override, - &tmp) < 0) { + if (_PyObject_LookupAttr((PyObject *)self, &_Py_ID(reducer_override), + &tmp) < 0) { goto error; } /* Cache the reducer_override method, if it exists. */ @@ -4597,26 +4575,25 @@ _pickle_Pickler_dump(PicklerObject *self, PyObject *obj) /*[clinic input] -_pickle.Pickler.__sizeof__ -> Py_ssize_t +_pickle.Pickler.__sizeof__ -> size_t Returns size in memory, in bytes. [clinic start generated code]*/ -static Py_ssize_t +static size_t _pickle_Pickler___sizeof___impl(PicklerObject *self) -/*[clinic end generated code: output=106edb3123f332e1 input=8cbbec9bd5540d42]*/ +/*[clinic end generated code: output=23ad75658d3b59ff input=d8127c8e7012ebd7]*/ { - Py_ssize_t res, s; - - res = _PyObject_SIZE(Py_TYPE(self)); + size_t res = _PyObject_SIZE(Py_TYPE(self)); if (self->memo != NULL) { res += sizeof(PyMemoTable); res += self->memo->mt_allocated * sizeof(PyMemoEntry); } if (self->output_buffer != NULL) { - s = _PySys_GetSizeOf(self->output_buffer); - if (s == -1) + size_t s = _PySys_GetSizeOf(self->output_buffer); + if (s == (size_t)-1) { return -1; + } res += s; } return res; @@ -4727,9 +4704,6 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *buffer_callback) /*[clinic end generated code: output=0abedc50590d259b input=a7c969699bf5dad3]*/ { - _Py_IDENTIFIER(persistent_id); - _Py_IDENTIFIER(dispatch_table); - /* In case of multiple __init__() calls, clear previous content. */ if (self->write != NULL) (void)Pickler_clear(self); @@ -4762,14 +4736,16 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, self->fast_nesting = 0; self->fast_memo = NULL; - if (init_method_ref((PyObject *)self, &PyId_persistent_id, + if (init_method_ref((PyObject *)self, &_Py_ID(persistent_id), &self->pers_func, &self->pers_func_self) < 0) { return -1; } - - if (_PyObject_LookupAttrId((PyObject *)self, - &PyId_dispatch_table, &self->dispatch_table) < 0) { + if (self->dispatch_table != NULL) { + return 0; + } + if (_PyObject_LookupAttr((PyObject *)self, &_Py_ID(dispatch_table), + &self->dispatch_table) < 0) { return -1; } @@ -4873,8 +4849,7 @@ _pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self) return NULL; } PyTuple_SET_ITEM(dict_args, 0, contents); - Py_INCREF((PyObject *)&PyDict_Type); - PyTuple_SET_ITEM(reduce_value, 0, (PyObject *)&PyDict_Type); + PyTuple_SET_ITEM(reduce_value, 0, Py_NewRef(&PyDict_Type)); PyTuple_SET_ITEM(reduce_value, 1, dict_args); return reduce_value; } @@ -4948,8 +4923,7 @@ PicklerMemoProxy_New(PicklerObject *pickler) self = PyObject_GC_New(PicklerMemoProxyObject, &PicklerMemoProxyType); if (self == NULL) return NULL; - Py_INCREF(pickler); - self->pickler = pickler; + self->pickler = (PicklerObject*)Py_NewRef(pickler); PyObject_GC_Track(self); return (PyObject *)self; } @@ -5049,8 +5023,7 @@ Pickler_set_persid(PicklerObject *self, PyObject *value, void *Py_UNUSED(ignored } self->pers_func_self = NULL; - Py_INCREF(value); - Py_XSETREF(self->pers_func, value); + Py_XSETREF(self->pers_func, Py_NewRef(value)); return 0; } @@ -5123,10 +5096,8 @@ static PyTypeObject Pickler_Type = { static PyObject * find_class(UnpicklerObject *self, PyObject *module_name, PyObject *global_name) { - _Py_IDENTIFIER(find_class); - - return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_find_class, - module_name, global_name, NULL); + return PyObject_CallMethodObjArgs((PyObject *)self, &_Py_ID(find_class), + module_name, global_name, NULL); } static Py_ssize_t @@ -5416,7 +5387,7 @@ load_binfloat(UnpicklerObject *self) if (_Unpickler_Read(self, &s, 8) < 0) return -1; - x = _PyFloat_Unpack8((unsigned char *)s, 0); + x = PyFloat_Unpack8(s, 0); if (x == -1.0 && PyErr_Occurred()) return -1; @@ -5813,14 +5784,12 @@ instantiate(PyObject *cls, PyObject *args) into a newly created tuple. */ assert(PyTuple_Check(args)); if (!PyTuple_GET_SIZE(args) && PyType_Check(cls)) { - _Py_IDENTIFIER(__getinitargs__); - _Py_IDENTIFIER(__new__); PyObject *func; - if (_PyObject_LookupAttrId(cls, &PyId___getinitargs__, &func) < 0) { + if (_PyObject_LookupAttr(cls, &_Py_ID(__getinitargs__), &func) < 0) { return NULL; } if (func == NULL) { - return _PyObject_CallMethodIdOneArg(cls, &PyId___new__, cls); + return PyObject_CallMethodOneArg(cls, &_Py_ID(__new__), cls); } Py_DECREF(func); } @@ -6081,7 +6050,7 @@ load_persid(UnpicklerObject *self) else { PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, - "A load persistent id instruction was encountered,\n" + "A load persistent id instruction was encountered, " "but no persistent_load function was specified."); return -1; } @@ -6108,7 +6077,7 @@ load_binpersid(UnpicklerObject *self) else { PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, - "A load persistent id instruction was encountered,\n" + "A load persistent id instruction was encountered, " "but no persistent_load function was specified."); return -1; } @@ -6465,9 +6434,8 @@ do_append(UnpicklerObject *self, Py_ssize_t x) } else { PyObject *extend_func; - _Py_IDENTIFIER(extend); - if (_PyObject_LookupAttrId(list, &PyId_extend, &extend_func) < 0) { + if (_PyObject_LookupAttr(list, &_Py_ID(extend), &extend_func) < 0) { return -1; } if (extend_func != NULL) { @@ -6484,12 +6452,11 @@ do_append(UnpicklerObject *self, Py_ssize_t x) } else { PyObject *append_func; - _Py_IDENTIFIER(append); /* Even if the PEP 307 requires extend() and append() methods, fall back on append() if the object has no extend() method for backward compatibility. */ - append_func = _PyObject_GetAttrId(list, &PyId_append); + append_func = PyObject_GetAttr(list, &_Py_ID(append)); if (append_func == NULL) return -1; for (i = x; i < len; i++) { @@ -6612,9 +6579,8 @@ load_additems(UnpicklerObject *self) } else { PyObject *add_func; - _Py_IDENTIFIER(add); - add_func = _PyObject_GetAttrId(set, &PyId_add); + add_func = PyObject_GetAttr(set, &_Py_ID(add)); if (add_func == NULL) return -1; for (i = mark; i < len; i++) { @@ -6642,7 +6608,6 @@ load_build(UnpicklerObject *self) PyObject *state, *inst, *slotstate; PyObject *setstate; int status = 0; - _Py_IDENTIFIER(__setstate__); /* Stack is ... instance, state. We want to leave instance at * the stack top, possibly mutated via instance.__setstate__(state). @@ -6656,7 +6621,7 @@ load_build(UnpicklerObject *self) inst = self->stack->data[Py_SIZE(self->stack) - 1]; - if (_PyObject_LookupAttrId(inst, &PyId___setstate__, &setstate) < 0) { + if (_PyObject_LookupAttr(inst, &_Py_ID(__setstate__), &setstate) < 0) { Py_DECREF(state); return -1; } @@ -6692,14 +6657,13 @@ load_build(UnpicklerObject *self) PyObject *dict; PyObject *d_key, *d_value; Py_ssize_t i; - _Py_IDENTIFIER(__dict__); if (!PyDict_Check(state)) { PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, "state is not a dictionary"); goto error; } - dict = _PyObject_GetAttrId(inst, &PyId___dict__); + dict = PyObject_GetAttr(inst, &_Py_ID(__dict__)); if (dict == NULL) goto error; @@ -7114,22 +7078,20 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self, /*[clinic input] -_pickle.Unpickler.__sizeof__ -> Py_ssize_t +_pickle.Unpickler.__sizeof__ -> size_t Returns size in memory, in bytes. [clinic start generated code]*/ -static Py_ssize_t +static size_t _pickle_Unpickler___sizeof___impl(UnpicklerObject *self) -/*[clinic end generated code: output=119d9d03ad4c7651 input=13333471fdeedf5e]*/ +/*[clinic end generated code: output=4648d84c228196df input=27180b2b6b524012]*/ { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)); + size_t res = _PyObject_SIZE(Py_TYPE(self)); if (self->memo != NULL) res += self->memo_size * sizeof(PyObject *); if (self->marks != NULL) - res += self->marks_size * sizeof(Py_ssize_t); + res += (size_t)self->marks_size * sizeof(Py_ssize_t); if (self->input_line != NULL) res += strlen(self->input_line) + 1; if (self->encoding != NULL) @@ -7251,8 +7213,6 @@ _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, const char *errors, PyObject *buffers) /*[clinic end generated code: output=09f0192649ea3f85 input=ca4c1faea9553121]*/ { - _Py_IDENTIFIER(persistent_load); - /* In case of multiple __init__() calls, clear previous content. */ if (self->read != NULL) (void)Unpickler_clear(self); @@ -7268,7 +7228,7 @@ _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, self->fix_imports = fix_imports; - if (init_method_ref((PyObject *)self, &PyId_persistent_load, + if (init_method_ref((PyObject *)self, &_Py_ID(persistent_load), &self->pers_func, &self->pers_func_self) < 0) { return -1; @@ -7385,8 +7345,7 @@ _pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self) return NULL; } PyTuple_SET_ITEM(constructor_args, 0, contents); - Py_INCREF((PyObject *)&PyDict_Type); - PyTuple_SET_ITEM(reduce_value, 0, (PyObject *)&PyDict_Type); + PyTuple_SET_ITEM(reduce_value, 0, Py_NewRef(&PyDict_Type)); PyTuple_SET_ITEM(reduce_value, 1, constructor_args); return reduce_value; } @@ -7461,8 +7420,7 @@ UnpicklerMemoProxy_New(UnpicklerObject *unpickler) &UnpicklerMemoProxyType); if (self == NULL) return NULL; - Py_INCREF(unpickler); - self->unpickler = unpickler; + self->unpickler = (UnpicklerObject*)Py_NewRef(unpickler); PyObject_GC_Track(self); return (PyObject *)self; } @@ -7498,8 +7456,7 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored return -1; for (size_t i = 0; i < new_memo_size; i++) { - Py_XINCREF(unpickler->memo[i]); - new_memo[i] = unpickler->memo[i]; + new_memo[i] = Py_XNewRef(unpickler->memo[i]); } } else if (PyDict_Check(obj)) { @@ -7579,8 +7536,7 @@ Unpickler_set_persload(UnpicklerObject *self, PyObject *value, void *Py_UNUSED(i } self->pers_func_self = NULL; - Py_INCREF(value); - Py_XSETREF(self->pers_func, value); + Py_XSETREF(self->pers_func, Py_NewRef(value)); return 0; } @@ -7959,8 +7915,7 @@ PyInit__pickle(void) m = PyState_FindModule(&_picklemodule); if (m) { - Py_INCREF(m); - return m; + return Py_NewRef(m); } if (PyType_Ready(&Pdata_Type) < 0) @@ -8001,16 +7956,15 @@ PyInit__pickle(void) if (st->UnpicklingError == NULL) return NULL; - Py_INCREF(st->PickleError); - if (PyModule_AddObject(m, "PickleError", st->PickleError) < 0) + if (PyModule_AddObjectRef(m, "PickleError", st->PickleError) < 0) { return NULL; - Py_INCREF(st->PicklingError); - if (PyModule_AddObject(m, "PicklingError", st->PicklingError) < 0) + } + if (PyModule_AddObjectRef(m, "PicklingError", st->PicklingError) < 0) { return NULL; - Py_INCREF(st->UnpicklingError); - if (PyModule_AddObject(m, "UnpicklingError", st->UnpicklingError) < 0) + } + if (PyModule_AddObjectRef(m, "UnpicklingError", st->UnpicklingError) < 0) { return NULL; - + } if (_Pickle_InitState(st) < 0) return NULL; diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index de599f8c970..f3ff39215ea 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -210,18 +210,23 @@ safe_get_max_fd(void) } -/* Close all file descriptors in the range from start_fd and higher - * except for those in py_fds_to_keep. If the range defined by - * [start_fd, safe_get_max_fd()) is large this will take a long - * time as it calls close() on EVERY possible fd. +/* Close all file descriptors in the given range except for those in + * py_fds_to_keep by invoking closer on each subrange. * - * It isn't possible to know for sure what the max fd to go up to - * is for processes with the capability of raising their maximum. + * If end_fd == -1, it's guessed via safe_get_max_fd(), but it isn't + * possible to know for sure what the max fd to go up to is for + * processes with the capability of raising their maximum, or in case + * a process opened a high fd and then lowered its maximum. */ -static void -_close_fds_by_brute_force(long start_fd, PyObject *py_fds_to_keep) +static int +_close_range_except(int start_fd, + int end_fd, + PyObject *py_fds_to_keep, + int (*closer)(int, int)) { - long end_fd = safe_get_max_fd(); + if (end_fd == -1) { + end_fd = Py_MIN(safe_get_max_fd(), INT_MAX); + } Py_ssize_t num_fds_to_keep = PyTuple_GET_SIZE(py_fds_to_keep); Py_ssize_t keep_seq_idx; /* As py_fds_to_keep is sorted we can loop through the list closing @@ -231,15 +236,17 @@ _close_fds_by_brute_force(long start_fd, PyObject *py_fds_to_keep) int keep_fd = PyLong_AsLong(py_keep_fd); if (keep_fd < start_fd) continue; - _Py_closerange(start_fd, keep_fd - 1); + if (closer(start_fd, keep_fd - 1) != 0) + return -1; start_fd = keep_fd + 1; } if (start_fd <= end_fd) { - _Py_closerange(start_fd, end_fd); + if (closer(start_fd, end_fd) != 0) + return -1; } + return 0; } - #if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H) /* It doesn't matter if d_name has room for NAME_MAX chars; we're using this * only to read a directory of short file descriptor number names. The kernel @@ -255,6 +262,16 @@ struct linux_dirent64 { char d_name[256]; /* Filename (null-terminated) */ }; +static int +_brute_force_closer(int first, int last) +{ + for (int i = first; i <= last; i++) { + /* Ignore errors */ + (void)close(i); + } + return 0; +} + /* Close all open file descriptors in the range from start_fd and higher * Do not close any in the sorted py_fds_to_keep list. * @@ -278,7 +295,7 @@ _close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep) fd_dir_fd = _Py_open_noraise(FD_DIR, O_RDONLY); if (fd_dir_fd == -1) { /* No way to get a list of open fds. */ - _close_fds_by_brute_force(start_fd, py_fds_to_keep); + _close_range_except(start_fd, -1, py_fds_to_keep, _brute_force_closer); return; } else { char buffer[sizeof(struct linux_dirent64)]; @@ -306,10 +323,16 @@ _close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep) } } -#define _close_open_fds _close_open_fds_safe +#define _close_open_fds_fallback _close_open_fds_safe #else /* NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */ +static int +_unsafe_closer(int first, int last) +{ + _Py_closerange(first, last); + return 0; +} /* Close all open file descriptors from start_fd and higher. * Do not close any in the sorted py_fds_to_keep tuple. @@ -325,7 +348,7 @@ _close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep) * http://womble.decadent.org.uk/readdir_r-advisory.html */ static void -_close_open_fds_maybe_unsafe(long start_fd, PyObject* py_fds_to_keep) +_close_open_fds_maybe_unsafe(int start_fd, PyObject* py_fds_to_keep) { DIR *proc_fd_dir; #ifndef HAVE_DIRFD @@ -348,7 +371,7 @@ _close_open_fds_maybe_unsafe(long start_fd, PyObject* py_fds_to_keep) proc_fd_dir = opendir(FD_DIR); if (!proc_fd_dir) { /* No way to get a list of open fds. */ - _close_fds_by_brute_force(start_fd, py_fds_to_keep); + _close_range_except(start_fd, -1, py_fds_to_keep, _unsafe_closer); } else { struct dirent *dir_entry; #ifdef HAVE_DIRFD @@ -369,16 +392,45 @@ _close_open_fds_maybe_unsafe(long start_fd, PyObject* py_fds_to_keep) } if (errno) { /* readdir error, revert behavior. Highly Unlikely. */ - _close_fds_by_brute_force(start_fd, py_fds_to_keep); + _close_range_except(start_fd, -1, py_fds_to_keep, _unsafe_closer); } closedir(proc_fd_dir); } } -#define _close_open_fds _close_open_fds_maybe_unsafe +#define _close_open_fds_fallback _close_open_fds_maybe_unsafe #endif /* else NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */ +/* We can use close_range() library function only if it's known to be + * async-signal-safe. + * + * On Linux, glibc explicitly documents it to be a thin wrapper over + * the system call, and other C libraries are likely to follow glibc. + */ +#if defined(HAVE_CLOSE_RANGE) && \ + (defined(__linux__) || defined(__FreeBSD__)) +#define HAVE_ASYNC_SAFE_CLOSE_RANGE + +static int +_close_range_closer(int first, int last) +{ + return close_range(first, last, 0); +} +#endif + +static void +_close_open_fds(int start_fd, PyObject* py_fds_to_keep) +{ +#ifdef HAVE_ASYNC_SAFE_CLOSE_RANGE + if (_close_range_except( + start_fd, INT_MAX, py_fds_to_keep, + _close_range_closer) == 0) { + return; + } +#endif + _close_open_fds_fallback(start_fd, py_fds_to_keep); +} #ifdef VFORK_USABLE /* Reset dispositions for all signals to SIG_DFL except for ignored @@ -465,10 +517,10 @@ child_exec(char *const exec_array[], int errread, int errwrite, int errpipe_read, int errpipe_write, int close_fds, int restore_signals, - int call_setsid, - int call_setgid, gid_t gid, - int call_setgroups, size_t groups_size, const gid_t *groups, - int call_setuid, uid_t uid, int child_umask, + int call_setsid, pid_t pgid_to_set, + gid_t gid, + Py_ssize_t extra_group_size, const gid_t *extra_groups, + uid_t uid, int child_umask, const void *child_sigmask, PyObject *py_fds_to_keep, PyObject *preexec_fn, @@ -559,18 +611,25 @@ child_exec(char *const exec_array[], POSIX_CALL(setsid()); #endif +#ifdef HAVE_SETPGID + static_assert(_Py_IS_TYPE_SIGNED(pid_t), "pid_t is unsigned"); + if (pgid_to_set >= 0) { + POSIX_CALL(setpgid(0, pgid_to_set)); + } +#endif + #ifdef HAVE_SETGROUPS - if (call_setgroups) - POSIX_CALL(setgroups(groups_size, groups)); + if (extra_group_size > 0) + POSIX_CALL(setgroups(extra_group_size, extra_groups)); #endif /* HAVE_SETGROUPS */ #ifdef HAVE_SETREGID - if (call_setgid) + if (gid != (gid_t)-1) POSIX_CALL(setregid(gid, gid)); #endif /* HAVE_SETREGID */ #ifdef HAVE_SETREUID - if (call_setuid) + if (uid != (uid_t)-1) POSIX_CALL(setreuid(uid, uid)); #endif /* HAVE_SETREUID */ @@ -664,10 +723,10 @@ do_fork_exec(char *const exec_array[], int errread, int errwrite, int errpipe_read, int errpipe_write, int close_fds, int restore_signals, - int call_setsid, - int call_setgid, gid_t gid, - int call_setgroups, size_t groups_size, const gid_t *groups, - int call_setuid, uid_t uid, int child_umask, + int call_setsid, pid_t pgid_to_set, + gid_t gid, + Py_ssize_t extra_group_size, const gid_t *extra_groups, + uid_t uid, int child_umask, const void *child_sigmask, PyObject *py_fds_to_keep, PyObject *preexec_fn, @@ -679,12 +738,18 @@ do_fork_exec(char *const exec_array[], #ifdef VFORK_USABLE if (child_sigmask) { /* These are checked by our caller; verify them in debug builds. */ - assert(!call_setuid); - assert(!call_setgid); - assert(!call_setgroups); + assert(uid == (uid_t)-1); + assert(gid == (gid_t)-1); + assert(extra_group_size < 0); assert(preexec_fn == Py_None); pid = vfork(); + if (pid == -1) { + /* If vfork() fails, fall back to using fork(). When it isn't + * allowed in a process by the kernel, vfork can return -1 + * with errno EINVAL. https://bugs.python.org/issue47151. */ + pid = fork(); + } } else #endif { @@ -711,9 +776,9 @@ do_fork_exec(char *const exec_array[], child_exec(exec_array, argv, envp, cwd, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, errpipe_read, errpipe_write, - close_fds, restore_signals, call_setsid, - call_setgid, gid, call_setgroups, groups_size, groups, - call_setuid, uid, child_umask, child_sigmask, + close_fds, restore_signals, call_setsid, pgid_to_set, + gid, extra_group_size, extra_groups, + uid, child_umask, child_sigmask, py_fds_to_keep, preexec_fn, preexec_fn_args_tuple); _exit(255); return 0; /* Dead code to avoid a potential compiler warning. */ @@ -728,38 +793,38 @@ subprocess_fork_exec(PyObject *module, PyObject *args) PyObject *env_list, *preexec_fn; PyObject *process_args, *converted_args = NULL, *fast_args = NULL; PyObject *preexec_fn_args_tuple = NULL; - PyObject *groups_list; + PyObject *extra_groups_packed; PyObject *uid_object, *gid_object; int p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite; int errpipe_read, errpipe_write, close_fds, restore_signals; int call_setsid; - int call_setgid = 0, call_setgroups = 0, call_setuid = 0; - uid_t uid; - gid_t gid, *groups = NULL; + pid_t pgid_to_set = -1; + gid_t *extra_groups = NULL; int child_umask; PyObject *cwd_obj, *cwd_obj2 = NULL; const char *cwd; pid_t pid = -1; int need_to_reenable_gc = 0; char *const *exec_array, *const *argv = NULL, *const *envp = NULL; - Py_ssize_t arg_num, num_groups = 0; + Py_ssize_t arg_num, extra_group_size = 0; int need_after_fork = 0; int saved_errno = 0; + int allow_vfork; if (!PyArg_ParseTuple( - args, "OOpO!OOiiiiiiiiiiOOOiO:fork_exec", + args, "OOpO!OOiiiiiiiipp" _Py_PARSE_PID "OOOiOp:fork_exec", &process_args, &executable_list, &close_fds, &PyTuple_Type, &py_fds_to_keep, &cwd_obj, &env_list, &p2cread, &p2cwrite, &c2pread, &c2pwrite, &errread, &errwrite, &errpipe_read, &errpipe_write, - &restore_signals, &call_setsid, - &gid_object, &groups_list, &uid_object, &child_umask, - &preexec_fn)) + &restore_signals, &call_setsid, &pgid_to_set, + &gid_object, &extra_groups_packed, &uid_object, &child_umask, + &preexec_fn, &allow_vfork)) return NULL; - if ((preexec_fn != Py_None) && - (PyInterpreterState_Get() != PyInterpreterState_Main())) { + PyInterpreterState *interp = PyInterpreterState_Get(); + if ((preexec_fn != Py_None) && (interp != PyInterpreterState_Main())) { PyErr_SetString(PyExc_RuntimeError, "preexec_fn not supported within subinterpreters"); return NULL; @@ -774,14 +839,6 @@ subprocess_fork_exec(PyObject *module, PyObject *args) return NULL; } - PyInterpreterState *interp = PyInterpreterState_Get(); - const PyConfig *config = _PyInterpreterState_GetConfig(interp); - if (config->_isolated_interpreter) { - PyErr_SetString(PyExc_RuntimeError, - "subprocess not supported for isolated subinterpreters"); - return NULL; - } - /* We need to call gc.disable() when we'll be calling preexec_fn */ if (preexec_fn != Py_None) { need_to_reenable_gc = PyGC_Disable(); @@ -838,53 +895,54 @@ subprocess_fork_exec(PyObject *module, PyObject *args) cwd = NULL; } - if (groups_list != Py_None) { + if (extra_groups_packed != Py_None) { #ifdef HAVE_SETGROUPS - Py_ssize_t i; - gid_t gid; - - if (!PyList_Check(groups_list)) { + if (!PyList_Check(extra_groups_packed)) { PyErr_SetString(PyExc_TypeError, "setgroups argument must be a list"); goto cleanup; } - num_groups = PySequence_Size(groups_list); + extra_group_size = PySequence_Size(extra_groups_packed); - if (num_groups < 0) + if (extra_group_size < 0) goto cleanup; - if (num_groups > MAX_GROUPS) { - PyErr_SetString(PyExc_ValueError, "too many groups"); + if (extra_group_size > MAX_GROUPS) { + PyErr_SetString(PyExc_ValueError, "too many extra_groups"); goto cleanup; } - if ((groups = PyMem_RawMalloc(num_groups * sizeof(gid_t))) == NULL) { - PyErr_SetString(PyExc_MemoryError, - "failed to allocate memory for group list"); - goto cleanup; + /* Deliberately keep extra_groups == NULL for extra_group_size == 0 */ + if (extra_group_size > 0) { + extra_groups = PyMem_RawMalloc(extra_group_size * sizeof(gid_t)); + if (extra_groups == NULL) { + PyErr_SetString(PyExc_MemoryError, + "failed to allocate memory for group list"); + goto cleanup; + } } - for (i = 0; i < num_groups; i++) { + for (Py_ssize_t i = 0; i < extra_group_size; i++) { PyObject *elem; - elem = PySequence_GetItem(groups_list, i); + elem = PySequence_GetItem(extra_groups_packed, i); if (!elem) goto cleanup; if (!PyLong_Check(elem)) { PyErr_SetString(PyExc_TypeError, - "groups must be integers"); + "extra_groups must be integers"); Py_DECREF(elem); goto cleanup; } else { + gid_t gid; if (!_Py_Gid_Converter(elem, &gid)) { Py_DECREF(elem); PyErr_SetString(PyExc_ValueError, "invalid group id"); goto cleanup; } - groups[i] = gid; + extra_groups[i] = gid; } Py_DECREF(elem); } - call_setgroups = 1; #else /* HAVE_SETGROUPS */ PyErr_BadInternalCall(); @@ -892,26 +950,24 @@ subprocess_fork_exec(PyObject *module, PyObject *args) #endif /* HAVE_SETGROUPS */ } + gid_t gid = (gid_t)-1; if (gid_object != Py_None) { #ifdef HAVE_SETREGID if (!_Py_Gid_Converter(gid_object, &gid)) goto cleanup; - call_setgid = 1; - #else /* HAVE_SETREGID */ PyErr_BadInternalCall(); goto cleanup; #endif /* HAVE_SETREUID */ } + uid_t uid = (uid_t)-1; if (uid_object != Py_None) { #ifdef HAVE_SETREUID if (!_Py_Uid_Converter(uid_object, &uid)) goto cleanup; - call_setuid = 1; - #else /* HAVE_SETREUID */ PyErr_BadInternalCall(); goto cleanup; @@ -934,8 +990,8 @@ subprocess_fork_exec(PyObject *module, PyObject *args) #ifdef VFORK_USABLE /* Use vfork() only if it's safe. See the comment above child_exec(). */ sigset_t old_sigs; - if (preexec_fn == Py_None && - !call_setuid && !call_setgid && !call_setgroups) { + if (preexec_fn == Py_None && allow_vfork && + uid == (uid_t)-1 && gid == (gid_t)-1 && extra_group_size < 0) { /* Block all signals to ensure that no signal handlers are run in the * child process while it shares memory with us. Note that signals * used internally by C libraries won't be blocked by @@ -957,9 +1013,9 @@ subprocess_fork_exec(PyObject *module, PyObject *args) pid = do_fork_exec(exec_array, argv, envp, cwd, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, errpipe_read, errpipe_write, - close_fds, restore_signals, call_setsid, - call_setgid, gid, call_setgroups, num_groups, groups, - call_setuid, uid, child_umask, old_sigmask, + close_fds, restore_signals, call_setsid, pgid_to_set, + gid, extra_group_size, extra_groups, + uid, child_umask, old_sigmask, py_fds_to_keep, preexec_fn, preexec_fn_args_tuple); /* Parent (original) process */ @@ -998,7 +1054,7 @@ cleanup: } Py_XDECREF(preexec_fn_args_tuple); - PyMem_RawFree(groups); + PyMem_RawFree(extra_groups); Py_XDECREF(cwd_obj2); if (envp) _Py_FreeCharPArray(envp); @@ -1022,8 +1078,8 @@ PyDoc_STRVAR(subprocess_fork_exec_doc, "fork_exec(args, executable_list, close_fds, pass_fds, cwd, env,\n\ p2cread, p2cwrite, c2pread, c2pwrite,\n\ errread, errwrite, errpipe_read, errpipe_write,\n\ - restore_signals, call_setsid,\n\ - gid, groups_list, uid,\n\ + restore_signals, call_setsid, pgid_to_set,\n\ + gid, extra_groups, uid,\n\ preexec_fn)\n\ \n\ Forks a child process, closes parent file descriptors as appropriate in the\n\ diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 413387fecc4..af19dd6c198 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -21,7 +21,7 @@ simplequeue_get_state(PyObject *module) } static struct PyModuleDef queuemodule; #define simplequeue_get_state_by_type(type) \ - (simplequeue_get_state(_PyType_GetModuleByDef(type, &queuemodule))) + (simplequeue_get_state(PyType_GetModuleByDef(type, &queuemodule))) typedef struct { PyObject_HEAD diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 5243d5a05e2..95f1e505dd1 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -72,6 +72,7 @@ #include "Python.h" #include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_runtime.h" #ifdef HAVE_PROCESS_H # include // getpid() #endif @@ -99,7 +100,7 @@ get_random_state(PyObject *module) static struct PyModuleDef _randommodule; #define _randomstate_type(type) \ - (get_random_state(_PyType_GetModuleByDef(type, &_randommodule))) + (get_random_state(PyType_GetModuleByDef(type, &_randommodule))) typedef struct { PyObject_HEAD @@ -258,7 +259,11 @@ random_seed_time_pid(RandomObject *self) key[0] = (uint32_t)(now & 0xffffffffU); key[1] = (uint32_t)(now >> 32); +#ifdef HAVE_GETPID key[2] = (uint32_t)getpid(); +#else + key[2] = 0; +#endif now = _PyTime_GetMonotonicClock(); key[3] = (uint32_t)(now & 0xffffffffU); diff --git a/Modules/_scproxy.c b/Modules/_scproxy.c index 4c1f1aa300c..344b66f9aad 100644 --- a/Modules/_scproxy.c +++ b/Modules/_scproxy.c @@ -84,7 +84,7 @@ get_proxy_settings(PyObject* Py_UNUSED(mod), PyObject *Py_UNUSED(ignored)) if (v == NULL) goto error; r = PyDict_SetItemString(result, "exclude_simple", v); - Py_DECREF(v); v = NULL; + Py_SETREF(v, NULL); if (r == -1) goto error; anArray = CFDictionaryGetValue(proxyDict, diff --git a/Modules/_sha3/LICENSE b/Modules/_sha3/LICENSE new file mode 100644 index 00000000000..d2d484d8820 --- /dev/null +++ b/Modules/_sha3/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Markku-Juhani O. Saarinen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/Modules/_sha3/README.txt b/Modules/_sha3/README.txt index e34b1d12f70..b35919b0167 100644 --- a/Modules/_sha3/README.txt +++ b/Modules/_sha3/README.txt @@ -1,11 +1,8 @@ -Keccak Code Package -=================== +tiny_sha3 +========= -The files in kcp are taken from the Keccak Code Package. They have been -slightly to be C89 compatible. The architecture specific header file -KeccakP-1600-SnP.h ha been renamed to KeccakP-1600-SnP-opt32.h or -KeccakP-1600-SnP-opt64.h. - -The 64bit files were generated with generic64lc/libkeccak.a.pack target, the -32bit files with generic32lc/libkeccak.a.pack. +https://github.com/mjosaarinen/tiny_sha3 +commit dcbb3192047c2a721f5f851db591871d428036a9 +- All functions have been converted to static functions. +- sha3() function is commented out. diff --git a/Modules/_sha3/cleanup.py b/Modules/_sha3/cleanup.py deleted file mode 100755 index 4f53681b49e..00000000000 --- a/Modules/_sha3/cleanup.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2012 Christian Heimes (christian@python.org) -# Licensed to PSF under a Contributor Agreement. -# -# cleanup Keccak sources - -import os -import re - -CPP1 = re.compile("^//(.*)") -CPP2 = re.compile(r"\ //(.*)") - -STATICS = ("void ", "int ", "HashReturn ", - "const UINT64 ", "UINT16 ", " int prefix##") - -HERE = os.path.dirname(os.path.abspath(__file__)) -KECCAK = os.path.join(HERE, "kcp") - -def getfiles(): - for name in os.listdir(KECCAK): - name = os.path.join(KECCAK, name) - if os.path.isfile(name): - yield name - -def cleanup(f): - buf = [] - for line in f: - # mark all functions and global data as static - #if line.startswith(STATICS): - # buf.append("static " + line) - # continue - # remove UINT64 typedef, we have our own - if line.startswith("typedef unsigned long long int"): - buf.append("/* %s */\n" % line.strip()) - continue - ## remove #include "brg_endian.h" - if "brg_endian.h" in line: - buf.append("/* %s */\n" % line.strip()) - continue - # transform C++ comments into ANSI C comments - line = CPP1.sub(r"/*\1 */\n", line) - line = CPP2.sub(r" /*\1 */\n", line) - buf.append(line) - return "".join(buf) - -for name in getfiles(): - with open(name) as f: - res = cleanup(f) - with open(name, "w") as f: - f.write(res) diff --git a/Modules/_sha3/clinic/sha3module.c.h b/Modules/_sha3/clinic/sha3module.c.h index 1c79c269391..a0c7c1c043e 100644 --- a/Modules/_sha3/clinic/sha3module.c.h +++ b/Modules/_sha3/clinic/sha3module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(py_sha3_new__doc__, "sha3_224(data=b\'\', /, *, usedforsecurity=True)\n" "--\n" @@ -15,8 +21,31 @@ static PyObject * py_sha3_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha3_224", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha3_224", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -164,4 +193,4 @@ _sha3_shake_128_hexdigest(SHA3object *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=c8a97b34e80def62 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=747c3f34ddd14063 input=a9049054013a1b77]*/ diff --git a/Modules/_sha3/kcp/KeccakHash.c b/Modules/_sha3/kcp/KeccakHash.c deleted file mode 100644 index e09fb43cace..00000000000 --- a/Modules/_sha3/kcp/KeccakHash.c +++ /dev/null @@ -1,82 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#include -#include "KeccakHash.h" - -/* ---------------------------------------------------------------- */ - -HashReturn Keccak_HashInitialize(Keccak_HashInstance *instance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix) -{ - HashReturn result; - - if (delimitedSuffix == 0) - return FAIL; - result = (HashReturn)KeccakWidth1600_SpongeInitialize(&instance->sponge, rate, capacity); - if (result != SUCCESS) - return result; - instance->fixedOutputLength = hashbitlen; - instance->delimitedSuffix = delimitedSuffix; - return SUCCESS; -} - -/* ---------------------------------------------------------------- */ - -HashReturn Keccak_HashUpdate(Keccak_HashInstance *instance, const BitSequence *data, DataLength databitlen) -{ - if ((databitlen % 8) == 0) - return (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8); - else { - HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8); - if (ret == SUCCESS) { - /* The last partial byte is assumed to be aligned on the least significant bits */ - - unsigned char lastByte = data[databitlen/8]; - /* Concatenate the last few bits provided here with those of the suffix */ - - unsigned short delimitedLastBytes = (unsigned short)((unsigned short)lastByte | ((unsigned short)instance->delimitedSuffix << (databitlen % 8))); - if ((delimitedLastBytes & 0xFF00) == 0x0000) { - instance->delimitedSuffix = delimitedLastBytes & 0xFF; - } - else { - unsigned char oneByte[1]; - oneByte[0] = delimitedLastBytes & 0xFF; - ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, oneByte, 1); - instance->delimitedSuffix = (delimitedLastBytes >> 8) & 0xFF; - } - } - return ret; - } -} - -/* ---------------------------------------------------------------- */ - -HashReturn Keccak_HashFinal(Keccak_HashInstance *instance, BitSequence *hashval) -{ - HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorbLastFewBits(&instance->sponge, instance->delimitedSuffix); - if (ret == SUCCESS) - return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, hashval, instance->fixedOutputLength/8); - else - return ret; -} - -/* ---------------------------------------------------------------- */ - -HashReturn Keccak_HashSqueeze(Keccak_HashInstance *instance, BitSequence *data, DataLength databitlen) -{ - if ((databitlen % 8) != 0) - return FAIL; - return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, data, databitlen/8); -} diff --git a/Modules/_sha3/kcp/KeccakHash.h b/Modules/_sha3/kcp/KeccakHash.h deleted file mode 100644 index bbd3dc64a22..00000000000 --- a/Modules/_sha3/kcp/KeccakHash.h +++ /dev/null @@ -1,114 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _KeccakHashInterface_h_ -#define _KeccakHashInterface_h_ - -#ifndef KeccakP1600_excluded - -#include "KeccakSponge.h" -#include - -typedef unsigned char BitSequence; -typedef size_t DataLength; -typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn; - -typedef struct { - KeccakWidth1600_SpongeInstance sponge; - unsigned int fixedOutputLength; - unsigned char delimitedSuffix; -} Keccak_HashInstance; - -/** - * Function to initialize the Keccak[r, c] sponge function instance used in sequential hashing mode. - * @param hashInstance Pointer to the hash instance to be initialized. - * @param rate The value of the rate r. - * @param capacity The value of the capacity c. - * @param hashbitlen The desired number of output bits, - * or 0 for an arbitrarily-long output. - * @param delimitedSuffix Bits that will be automatically appended to the end - * of the input message, as in domain separation. - * This is a byte containing from 0 to 7 bits - * formatted like the @a delimitedData parameter of - * the Keccak_SpongeAbsorbLastFewBits() function. - * @pre One must have r+c=1600 and the rate a multiple of 8 bits in this implementation. - * @return SUCCESS if successful, FAIL otherwise. - */ -HashReturn Keccak_HashInitialize(Keccak_HashInstance *hashInstance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix); - -/** Macro to initialize a SHAKE128 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHAKE128(hashInstance) Keccak_HashInitialize(hashInstance, 1344, 256, 0, 0x1F) - -/** Macro to initialize a SHAKE256 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHAKE256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 0, 0x1F) - -/** Macro to initialize a SHA3-224 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHA3_224(hashInstance) Keccak_HashInitialize(hashInstance, 1152, 448, 224, 0x06) - -/** Macro to initialize a SHA3-256 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHA3_256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 256, 0x06) - -/** Macro to initialize a SHA3-384 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHA3_384(hashInstance) Keccak_HashInitialize(hashInstance, 832, 768, 384, 0x06) - -/** Macro to initialize a SHA3-512 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHA3_512(hashInstance) Keccak_HashInitialize(hashInstance, 576, 1024, 512, 0x06) - -/** - * Function to give input data to be absorbed. - * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). - * @param data Pointer to the input data. - * When @a databitLen is not a multiple of 8, the last bits of data must be - * in the least significant bits of the last byte (little-endian convention). - * @param databitLen The number of input bits provided in the input data. - * @pre In the previous call to Keccak_HashUpdate(), databitlen was a multiple of 8. - * @return SUCCESS if successful, FAIL otherwise. - */ -HashReturn Keccak_HashUpdate(Keccak_HashInstance *hashInstance, const BitSequence *data, DataLength databitlen); - -/** - * Function to call after all input blocks have been input and to get - * output bits if the length was specified when calling Keccak_HashInitialize(). - * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). - * If @a hashbitlen was not 0 in the call to Keccak_HashInitialize(), the number of - * output bits is equal to @a hashbitlen. - * If @a hashbitlen was 0 in the call to Keccak_HashInitialize(), the output bits - * must be extracted using the Keccak_HashSqueeze() function. - * @param state Pointer to the state of the sponge function initialized by Init(). - * @param hashval Pointer to the buffer where to store the output data. - * @return SUCCESS if successful, FAIL otherwise. - */ -HashReturn Keccak_HashFinal(Keccak_HashInstance *hashInstance, BitSequence *hashval); - - /** - * Function to squeeze output data. - * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). - * @param data Pointer to the buffer where to store the output data. - * @param databitlen The number of output bits desired (must be a multiple of 8). - * @pre Keccak_HashFinal() must have been already called. - * @pre @a databitlen is a multiple of 8. - * @return SUCCESS if successful, FAIL otherwise. - */ -HashReturn Keccak_HashSqueeze(Keccak_HashInstance *hashInstance, BitSequence *data, DataLength databitlen); - -#endif - -#endif diff --git a/Modules/_sha3/kcp/KeccakP-1600-64.macros b/Modules/_sha3/kcp/KeccakP-1600-64.macros deleted file mode 100644 index 1f11fe3e79f..00000000000 --- a/Modules/_sha3/kcp/KeccakP-1600-64.macros +++ /dev/null @@ -1,2208 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#define declareABCDE \ - UINT64 Aba, Abe, Abi, Abo, Abu; \ - UINT64 Aga, Age, Agi, Ago, Agu; \ - UINT64 Aka, Ake, Aki, Ako, Aku; \ - UINT64 Ama, Ame, Ami, Amo, Amu; \ - UINT64 Asa, Ase, Asi, Aso, Asu; \ - UINT64 Bba, Bbe, Bbi, Bbo, Bbu; \ - UINT64 Bga, Bge, Bgi, Bgo, Bgu; \ - UINT64 Bka, Bke, Bki, Bko, Bku; \ - UINT64 Bma, Bme, Bmi, Bmo, Bmu; \ - UINT64 Bsa, Bse, Bsi, Bso, Bsu; \ - UINT64 Ca, Ce, Ci, Co, Cu; \ - UINT64 Da, De, Di, Do, Du; \ - UINT64 Eba, Ebe, Ebi, Ebo, Ebu; \ - UINT64 Ega, Ege, Egi, Ego, Egu; \ - UINT64 Eka, Eke, Eki, Eko, Eku; \ - UINT64 Ema, Eme, Emi, Emo, Emu; \ - UINT64 Esa, Ese, Esi, Eso, Esu; \ - -#define prepareTheta \ - Ca = Aba^Aga^Aka^Ama^Asa; \ - Ce = Abe^Age^Ake^Ame^Ase; \ - Ci = Abi^Agi^Aki^Ami^Asi; \ - Co = Abo^Ago^Ako^Amo^Aso; \ - Cu = Abu^Agu^Aku^Amu^Asu; \ - -#ifdef UseBebigokimisa -/* --- Code for round, with prepare-theta (lane complementing pattern 'bebigokimisa') */ - -/* --- 64-bit lanes mapped to 64-bit words */ - -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da = Cu^ROL64(Ce, 1); \ - De = Ca^ROL64(Ci, 1); \ - Di = Ce^ROL64(Co, 1); \ - Do = Ci^ROL64(Cu, 1); \ - Du = Co^ROL64(Ca, 1); \ -\ - A##ba ^= Da; \ - Bba = A##ba; \ - A##ge ^= De; \ - Bbe = ROL64(A##ge, 44); \ - A##ki ^= Di; \ - Bbi = ROL64(A##ki, 43); \ - A##mo ^= Do; \ - Bbo = ROL64(A##mo, 21); \ - A##su ^= Du; \ - Bbu = ROL64(A##su, 14); \ - E##ba = Bba ^( Bbe | Bbi ); \ - E##ba ^= KeccakF1600RoundConstants[i]; \ - Ca = E##ba; \ - E##be = Bbe ^((~Bbi)| Bbo ); \ - Ce = E##be; \ - E##bi = Bbi ^( Bbo & Bbu ); \ - Ci = E##bi; \ - E##bo = Bbo ^( Bbu | Bba ); \ - Co = E##bo; \ - E##bu = Bbu ^( Bba & Bbe ); \ - Cu = E##bu; \ -\ - A##bo ^= Do; \ - Bga = ROL64(A##bo, 28); \ - A##gu ^= Du; \ - Bge = ROL64(A##gu, 20); \ - A##ka ^= Da; \ - Bgi = ROL64(A##ka, 3); \ - A##me ^= De; \ - Bgo = ROL64(A##me, 45); \ - A##si ^= Di; \ - Bgu = ROL64(A##si, 61); \ - E##ga = Bga ^( Bge | Bgi ); \ - Ca ^= E##ga; \ - E##ge = Bge ^( Bgi & Bgo ); \ - Ce ^= E##ge; \ - E##gi = Bgi ^( Bgo |(~Bgu)); \ - Ci ^= E##gi; \ - E##go = Bgo ^( Bgu | Bga ); \ - Co ^= E##go; \ - E##gu = Bgu ^( Bga & Bge ); \ - Cu ^= E##gu; \ -\ - A##be ^= De; \ - Bka = ROL64(A##be, 1); \ - A##gi ^= Di; \ - Bke = ROL64(A##gi, 6); \ - A##ko ^= Do; \ - Bki = ROL64(A##ko, 25); \ - A##mu ^= Du; \ - Bko = ROL64(A##mu, 8); \ - A##sa ^= Da; \ - Bku = ROL64(A##sa, 18); \ - E##ka = Bka ^( Bke | Bki ); \ - Ca ^= E##ka; \ - E##ke = Bke ^( Bki & Bko ); \ - Ce ^= E##ke; \ - E##ki = Bki ^((~Bko)& Bku ); \ - Ci ^= E##ki; \ - E##ko = (~Bko)^( Bku | Bka ); \ - Co ^= E##ko; \ - E##ku = Bku ^( Bka & Bke ); \ - Cu ^= E##ku; \ -\ - A##bu ^= Du; \ - Bma = ROL64(A##bu, 27); \ - A##ga ^= Da; \ - Bme = ROL64(A##ga, 36); \ - A##ke ^= De; \ - Bmi = ROL64(A##ke, 10); \ - A##mi ^= Di; \ - Bmo = ROL64(A##mi, 15); \ - A##so ^= Do; \ - Bmu = ROL64(A##so, 56); \ - E##ma = Bma ^( Bme & Bmi ); \ - Ca ^= E##ma; \ - E##me = Bme ^( Bmi | Bmo ); \ - Ce ^= E##me; \ - E##mi = Bmi ^((~Bmo)| Bmu ); \ - Ci ^= E##mi; \ - E##mo = (~Bmo)^( Bmu & Bma ); \ - Co ^= E##mo; \ - E##mu = Bmu ^( Bma | Bme ); \ - Cu ^= E##mu; \ -\ - A##bi ^= Di; \ - Bsa = ROL64(A##bi, 62); \ - A##go ^= Do; \ - Bse = ROL64(A##go, 55); \ - A##ku ^= Du; \ - Bsi = ROL64(A##ku, 39); \ - A##ma ^= Da; \ - Bso = ROL64(A##ma, 41); \ - A##se ^= De; \ - Bsu = ROL64(A##se, 2); \ - E##sa = Bsa ^((~Bse)& Bsi ); \ - Ca ^= E##sa; \ - E##se = (~Bse)^( Bsi | Bso ); \ - Ce ^= E##se; \ - E##si = Bsi ^( Bso & Bsu ); \ - Ci ^= E##si; \ - E##so = Bso ^( Bsu | Bsa ); \ - Co ^= E##so; \ - E##su = Bsu ^( Bsa & Bse ); \ - Cu ^= E##su; \ -\ - -/* --- Code for round (lane complementing pattern 'bebigokimisa') */ - -/* --- 64-bit lanes mapped to 64-bit words */ - -#define thetaRhoPiChiIota(i, A, E) \ - Da = Cu^ROL64(Ce, 1); \ - De = Ca^ROL64(Ci, 1); \ - Di = Ce^ROL64(Co, 1); \ - Do = Ci^ROL64(Cu, 1); \ - Du = Co^ROL64(Ca, 1); \ -\ - A##ba ^= Da; \ - Bba = A##ba; \ - A##ge ^= De; \ - Bbe = ROL64(A##ge, 44); \ - A##ki ^= Di; \ - Bbi = ROL64(A##ki, 43); \ - A##mo ^= Do; \ - Bbo = ROL64(A##mo, 21); \ - A##su ^= Du; \ - Bbu = ROL64(A##su, 14); \ - E##ba = Bba ^( Bbe | Bbi ); \ - E##ba ^= KeccakF1600RoundConstants[i]; \ - E##be = Bbe ^((~Bbi)| Bbo ); \ - E##bi = Bbi ^( Bbo & Bbu ); \ - E##bo = Bbo ^( Bbu | Bba ); \ - E##bu = Bbu ^( Bba & Bbe ); \ -\ - A##bo ^= Do; \ - Bga = ROL64(A##bo, 28); \ - A##gu ^= Du; \ - Bge = ROL64(A##gu, 20); \ - A##ka ^= Da; \ - Bgi = ROL64(A##ka, 3); \ - A##me ^= De; \ - Bgo = ROL64(A##me, 45); \ - A##si ^= Di; \ - Bgu = ROL64(A##si, 61); \ - E##ga = Bga ^( Bge | Bgi ); \ - E##ge = Bge ^( Bgi & Bgo ); \ - E##gi = Bgi ^( Bgo |(~Bgu)); \ - E##go = Bgo ^( Bgu | Bga ); \ - E##gu = Bgu ^( Bga & Bge ); \ -\ - A##be ^= De; \ - Bka = ROL64(A##be, 1); \ - A##gi ^= Di; \ - Bke = ROL64(A##gi, 6); \ - A##ko ^= Do; \ - Bki = ROL64(A##ko, 25); \ - A##mu ^= Du; \ - Bko = ROL64(A##mu, 8); \ - A##sa ^= Da; \ - Bku = ROL64(A##sa, 18); \ - E##ka = Bka ^( Bke | Bki ); \ - E##ke = Bke ^( Bki & Bko ); \ - E##ki = Bki ^((~Bko)& Bku ); \ - E##ko = (~Bko)^( Bku | Bka ); \ - E##ku = Bku ^( Bka & Bke ); \ -\ - A##bu ^= Du; \ - Bma = ROL64(A##bu, 27); \ - A##ga ^= Da; \ - Bme = ROL64(A##ga, 36); \ - A##ke ^= De; \ - Bmi = ROL64(A##ke, 10); \ - A##mi ^= Di; \ - Bmo = ROL64(A##mi, 15); \ - A##so ^= Do; \ - Bmu = ROL64(A##so, 56); \ - E##ma = Bma ^( Bme & Bmi ); \ - E##me = Bme ^( Bmi | Bmo ); \ - E##mi = Bmi ^((~Bmo)| Bmu ); \ - E##mo = (~Bmo)^( Bmu & Bma ); \ - E##mu = Bmu ^( Bma | Bme ); \ -\ - A##bi ^= Di; \ - Bsa = ROL64(A##bi, 62); \ - A##go ^= Do; \ - Bse = ROL64(A##go, 55); \ - A##ku ^= Du; \ - Bsi = ROL64(A##ku, 39); \ - A##ma ^= Da; \ - Bso = ROL64(A##ma, 41); \ - A##se ^= De; \ - Bsu = ROL64(A##se, 2); \ - E##sa = Bsa ^((~Bse)& Bsi ); \ - E##se = (~Bse)^( Bsi | Bso ); \ - E##si = Bsi ^( Bso & Bsu ); \ - E##so = Bso ^( Bsu | Bsa ); \ - E##su = Bsu ^( Bsa & Bse ); \ -\ - -#else /* UseBebigokimisa */ - -/* --- Code for round, with prepare-theta */ - -/* --- 64-bit lanes mapped to 64-bit words */ - -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da = Cu^ROL64(Ce, 1); \ - De = Ca^ROL64(Ci, 1); \ - Di = Ce^ROL64(Co, 1); \ - Do = Ci^ROL64(Cu, 1); \ - Du = Co^ROL64(Ca, 1); \ -\ - A##ba ^= Da; \ - Bba = A##ba; \ - A##ge ^= De; \ - Bbe = ROL64(A##ge, 44); \ - A##ki ^= Di; \ - Bbi = ROL64(A##ki, 43); \ - A##mo ^= Do; \ - Bbo = ROL64(A##mo, 21); \ - A##su ^= Du; \ - Bbu = ROL64(A##su, 14); \ - E##ba = Bba ^((~Bbe)& Bbi ); \ - E##ba ^= KeccakF1600RoundConstants[i]; \ - Ca = E##ba; \ - E##be = Bbe ^((~Bbi)& Bbo ); \ - Ce = E##be; \ - E##bi = Bbi ^((~Bbo)& Bbu ); \ - Ci = E##bi; \ - E##bo = Bbo ^((~Bbu)& Bba ); \ - Co = E##bo; \ - E##bu = Bbu ^((~Bba)& Bbe ); \ - Cu = E##bu; \ -\ - A##bo ^= Do; \ - Bga = ROL64(A##bo, 28); \ - A##gu ^= Du; \ - Bge = ROL64(A##gu, 20); \ - A##ka ^= Da; \ - Bgi = ROL64(A##ka, 3); \ - A##me ^= De; \ - Bgo = ROL64(A##me, 45); \ - A##si ^= Di; \ - Bgu = ROL64(A##si, 61); \ - E##ga = Bga ^((~Bge)& Bgi ); \ - Ca ^= E##ga; \ - E##ge = Bge ^((~Bgi)& Bgo ); \ - Ce ^= E##ge; \ - E##gi = Bgi ^((~Bgo)& Bgu ); \ - Ci ^= E##gi; \ - E##go = Bgo ^((~Bgu)& Bga ); \ - Co ^= E##go; \ - E##gu = Bgu ^((~Bga)& Bge ); \ - Cu ^= E##gu; \ -\ - A##be ^= De; \ - Bka = ROL64(A##be, 1); \ - A##gi ^= Di; \ - Bke = ROL64(A##gi, 6); \ - A##ko ^= Do; \ - Bki = ROL64(A##ko, 25); \ - A##mu ^= Du; \ - Bko = ROL64(A##mu, 8); \ - A##sa ^= Da; \ - Bku = ROL64(A##sa, 18); \ - E##ka = Bka ^((~Bke)& Bki ); \ - Ca ^= E##ka; \ - E##ke = Bke ^((~Bki)& Bko ); \ - Ce ^= E##ke; \ - E##ki = Bki ^((~Bko)& Bku ); \ - Ci ^= E##ki; \ - E##ko = Bko ^((~Bku)& Bka ); \ - Co ^= E##ko; \ - E##ku = Bku ^((~Bka)& Bke ); \ - Cu ^= E##ku; \ -\ - A##bu ^= Du; \ - Bma = ROL64(A##bu, 27); \ - A##ga ^= Da; \ - Bme = ROL64(A##ga, 36); \ - A##ke ^= De; \ - Bmi = ROL64(A##ke, 10); \ - A##mi ^= Di; \ - Bmo = ROL64(A##mi, 15); \ - A##so ^= Do; \ - Bmu = ROL64(A##so, 56); \ - E##ma = Bma ^((~Bme)& Bmi ); \ - Ca ^= E##ma; \ - E##me = Bme ^((~Bmi)& Bmo ); \ - Ce ^= E##me; \ - E##mi = Bmi ^((~Bmo)& Bmu ); \ - Ci ^= E##mi; \ - E##mo = Bmo ^((~Bmu)& Bma ); \ - Co ^= E##mo; \ - E##mu = Bmu ^((~Bma)& Bme ); \ - Cu ^= E##mu; \ -\ - A##bi ^= Di; \ - Bsa = ROL64(A##bi, 62); \ - A##go ^= Do; \ - Bse = ROL64(A##go, 55); \ - A##ku ^= Du; \ - Bsi = ROL64(A##ku, 39); \ - A##ma ^= Da; \ - Bso = ROL64(A##ma, 41); \ - A##se ^= De; \ - Bsu = ROL64(A##se, 2); \ - E##sa = Bsa ^((~Bse)& Bsi ); \ - Ca ^= E##sa; \ - E##se = Bse ^((~Bsi)& Bso ); \ - Ce ^= E##se; \ - E##si = Bsi ^((~Bso)& Bsu ); \ - Ci ^= E##si; \ - E##so = Bso ^((~Bsu)& Bsa ); \ - Co ^= E##so; \ - E##su = Bsu ^((~Bsa)& Bse ); \ - Cu ^= E##su; \ -\ - -/* --- Code for round */ - -/* --- 64-bit lanes mapped to 64-bit words */ - -#define thetaRhoPiChiIota(i, A, E) \ - Da = Cu^ROL64(Ce, 1); \ - De = Ca^ROL64(Ci, 1); \ - Di = Ce^ROL64(Co, 1); \ - Do = Ci^ROL64(Cu, 1); \ - Du = Co^ROL64(Ca, 1); \ -\ - A##ba ^= Da; \ - Bba = A##ba; \ - A##ge ^= De; \ - Bbe = ROL64(A##ge, 44); \ - A##ki ^= Di; \ - Bbi = ROL64(A##ki, 43); \ - A##mo ^= Do; \ - Bbo = ROL64(A##mo, 21); \ - A##su ^= Du; \ - Bbu = ROL64(A##su, 14); \ - E##ba = Bba ^((~Bbe)& Bbi ); \ - E##ba ^= KeccakF1600RoundConstants[i]; \ - E##be = Bbe ^((~Bbi)& Bbo ); \ - E##bi = Bbi ^((~Bbo)& Bbu ); \ - E##bo = Bbo ^((~Bbu)& Bba ); \ - E##bu = Bbu ^((~Bba)& Bbe ); \ -\ - A##bo ^= Do; \ - Bga = ROL64(A##bo, 28); \ - A##gu ^= Du; \ - Bge = ROL64(A##gu, 20); \ - A##ka ^= Da; \ - Bgi = ROL64(A##ka, 3); \ - A##me ^= De; \ - Bgo = ROL64(A##me, 45); \ - A##si ^= Di; \ - Bgu = ROL64(A##si, 61); \ - E##ga = Bga ^((~Bge)& Bgi ); \ - E##ge = Bge ^((~Bgi)& Bgo ); \ - E##gi = Bgi ^((~Bgo)& Bgu ); \ - E##go = Bgo ^((~Bgu)& Bga ); \ - E##gu = Bgu ^((~Bga)& Bge ); \ -\ - A##be ^= De; \ - Bka = ROL64(A##be, 1); \ - A##gi ^= Di; \ - Bke = ROL64(A##gi, 6); \ - A##ko ^= Do; \ - Bki = ROL64(A##ko, 25); \ - A##mu ^= Du; \ - Bko = ROL64(A##mu, 8); \ - A##sa ^= Da; \ - Bku = ROL64(A##sa, 18); \ - E##ka = Bka ^((~Bke)& Bki ); \ - E##ke = Bke ^((~Bki)& Bko ); \ - E##ki = Bki ^((~Bko)& Bku ); \ - E##ko = Bko ^((~Bku)& Bka ); \ - E##ku = Bku ^((~Bka)& Bke ); \ -\ - A##bu ^= Du; \ - Bma = ROL64(A##bu, 27); \ - A##ga ^= Da; \ - Bme = ROL64(A##ga, 36); \ - A##ke ^= De; \ - Bmi = ROL64(A##ke, 10); \ - A##mi ^= Di; \ - Bmo = ROL64(A##mi, 15); \ - A##so ^= Do; \ - Bmu = ROL64(A##so, 56); \ - E##ma = Bma ^((~Bme)& Bmi ); \ - E##me = Bme ^((~Bmi)& Bmo ); \ - E##mi = Bmi ^((~Bmo)& Bmu ); \ - E##mo = Bmo ^((~Bmu)& Bma ); \ - E##mu = Bmu ^((~Bma)& Bme ); \ -\ - A##bi ^= Di; \ - Bsa = ROL64(A##bi, 62); \ - A##go ^= Do; \ - Bse = ROL64(A##go, 55); \ - A##ku ^= Du; \ - Bsi = ROL64(A##ku, 39); \ - A##ma ^= Da; \ - Bso = ROL64(A##ma, 41); \ - A##se ^= De; \ - Bsu = ROL64(A##se, 2); \ - E##sa = Bsa ^((~Bse)& Bsi ); \ - E##se = Bse ^((~Bsi)& Bso ); \ - E##si = Bsi ^((~Bso)& Bsu ); \ - E##so = Bso ^((~Bsu)& Bsa ); \ - E##su = Bsu ^((~Bsa)& Bse ); \ -\ - -#endif /* UseBebigokimisa */ - - -#define copyFromState(X, state) \ - X##ba = state[ 0]; \ - X##be = state[ 1]; \ - X##bi = state[ 2]; \ - X##bo = state[ 3]; \ - X##bu = state[ 4]; \ - X##ga = state[ 5]; \ - X##ge = state[ 6]; \ - X##gi = state[ 7]; \ - X##go = state[ 8]; \ - X##gu = state[ 9]; \ - X##ka = state[10]; \ - X##ke = state[11]; \ - X##ki = state[12]; \ - X##ko = state[13]; \ - X##ku = state[14]; \ - X##ma = state[15]; \ - X##me = state[16]; \ - X##mi = state[17]; \ - X##mo = state[18]; \ - X##mu = state[19]; \ - X##sa = state[20]; \ - X##se = state[21]; \ - X##si = state[22]; \ - X##so = state[23]; \ - X##su = state[24]; \ - -#define copyToState(state, X) \ - state[ 0] = X##ba; \ - state[ 1] = X##be; \ - state[ 2] = X##bi; \ - state[ 3] = X##bo; \ - state[ 4] = X##bu; \ - state[ 5] = X##ga; \ - state[ 6] = X##ge; \ - state[ 7] = X##gi; \ - state[ 8] = X##go; \ - state[ 9] = X##gu; \ - state[10] = X##ka; \ - state[11] = X##ke; \ - state[12] = X##ki; \ - state[13] = X##ko; \ - state[14] = X##ku; \ - state[15] = X##ma; \ - state[16] = X##me; \ - state[17] = X##mi; \ - state[18] = X##mo; \ - state[19] = X##mu; \ - state[20] = X##sa; \ - state[21] = X##se; \ - state[22] = X##si; \ - state[23] = X##so; \ - state[24] = X##su; \ - -#define copyStateVariables(X, Y) \ - X##ba = Y##ba; \ - X##be = Y##be; \ - X##bi = Y##bi; \ - X##bo = Y##bo; \ - X##bu = Y##bu; \ - X##ga = Y##ga; \ - X##ge = Y##ge; \ - X##gi = Y##gi; \ - X##go = Y##go; \ - X##gu = Y##gu; \ - X##ka = Y##ka; \ - X##ke = Y##ke; \ - X##ki = Y##ki; \ - X##ko = Y##ko; \ - X##ku = Y##ku; \ - X##ma = Y##ma; \ - X##me = Y##me; \ - X##mi = Y##mi; \ - X##mo = Y##mo; \ - X##mu = Y##mu; \ - X##sa = Y##sa; \ - X##se = Y##se; \ - X##si = Y##si; \ - X##so = Y##so; \ - X##su = Y##su; \ - -#define copyFromStateAndAdd(X, state, input, laneCount) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount < 1) { \ - X##ba = state[ 0]; \ - } \ - else { \ - X##ba = state[ 0]^input[ 0]; \ - } \ - X##be = state[ 1]; \ - X##bi = state[ 2]; \ - } \ - else { \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - if (laneCount < 3) { \ - X##bi = state[ 2]; \ - } \ - else { \ - X##bi = state[ 2]^input[ 2]; \ - } \ - } \ - X##bo = state[ 3]; \ - X##bu = state[ 4]; \ - X##ga = state[ 5]; \ - X##ge = state[ 6]; \ - } \ - else { \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - X##bi = state[ 2]^input[ 2]; \ - X##bo = state[ 3]^input[ 3]; \ - if (laneCount < 6) { \ - if (laneCount < 5) { \ - X##bu = state[ 4]; \ - } \ - else { \ - X##bu = state[ 4]^input[ 4]; \ - } \ - X##ga = state[ 5]; \ - X##ge = state[ 6]; \ - } \ - else { \ - X##bu = state[ 4]^input[ 4]; \ - X##ga = state[ 5]^input[ 5]; \ - if (laneCount < 7) { \ - X##ge = state[ 6]; \ - } \ - else { \ - X##ge = state[ 6]^input[ 6]; \ - } \ - } \ - } \ - X##gi = state[ 7]; \ - X##go = state[ 8]; \ - X##gu = state[ 9]; \ - X##ka = state[10]; \ - X##ke = state[11]; \ - X##ki = state[12]; \ - X##ko = state[13]; \ - X##ku = state[14]; \ - } \ - else { \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - X##bi = state[ 2]^input[ 2]; \ - X##bo = state[ 3]^input[ 3]; \ - X##bu = state[ 4]^input[ 4]; \ - X##ga = state[ 5]^input[ 5]; \ - X##ge = state[ 6]^input[ 6]; \ - X##gi = state[ 7]^input[ 7]; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount < 9) { \ - X##go = state[ 8]; \ - } \ - else { \ - X##go = state[ 8]^input[ 8]; \ - } \ - X##gu = state[ 9]; \ - X##ka = state[10]; \ - } \ - else { \ - X##go = state[ 8]^input[ 8]; \ - X##gu = state[ 9]^input[ 9]; \ - if (laneCount < 11) { \ - X##ka = state[10]; \ - } \ - else { \ - X##ka = state[10]^input[10]; \ - } \ - } \ - X##ke = state[11]; \ - X##ki = state[12]; \ - X##ko = state[13]; \ - X##ku = state[14]; \ - } \ - else { \ - X##go = state[ 8]^input[ 8]; \ - X##gu = state[ 9]^input[ 9]; \ - X##ka = state[10]^input[10]; \ - X##ke = state[11]^input[11]; \ - if (laneCount < 14) { \ - if (laneCount < 13) { \ - X##ki = state[12]; \ - } \ - else { \ - X##ki = state[12]^input[12]; \ - } \ - X##ko = state[13]; \ - X##ku = state[14]; \ - } \ - else { \ - X##ki = state[12]^input[12]; \ - X##ko = state[13]^input[13]; \ - if (laneCount < 15) { \ - X##ku = state[14]; \ - } \ - else { \ - X##ku = state[14]^input[14]; \ - } \ - } \ - } \ - } \ - X##ma = state[15]; \ - X##me = state[16]; \ - X##mi = state[17]; \ - X##mo = state[18]; \ - X##mu = state[19]; \ - X##sa = state[20]; \ - X##se = state[21]; \ - X##si = state[22]; \ - X##so = state[23]; \ - X##su = state[24]; \ - } \ - else { \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - X##bi = state[ 2]^input[ 2]; \ - X##bo = state[ 3]^input[ 3]; \ - X##bu = state[ 4]^input[ 4]; \ - X##ga = state[ 5]^input[ 5]; \ - X##ge = state[ 6]^input[ 6]; \ - X##gi = state[ 7]^input[ 7]; \ - X##go = state[ 8]^input[ 8]; \ - X##gu = state[ 9]^input[ 9]; \ - X##ka = state[10]^input[10]; \ - X##ke = state[11]^input[11]; \ - X##ki = state[12]^input[12]; \ - X##ko = state[13]^input[13]; \ - X##ku = state[14]^input[14]; \ - X##ma = state[15]^input[15]; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount < 17) { \ - X##me = state[16]; \ - } \ - else { \ - X##me = state[16]^input[16]; \ - } \ - X##mi = state[17]; \ - X##mo = state[18]; \ - } \ - else { \ - X##me = state[16]^input[16]; \ - X##mi = state[17]^input[17]; \ - if (laneCount < 19) { \ - X##mo = state[18]; \ - } \ - else { \ - X##mo = state[18]^input[18]; \ - } \ - } \ - X##mu = state[19]; \ - X##sa = state[20]; \ - X##se = state[21]; \ - X##si = state[22]; \ - } \ - else { \ - X##me = state[16]^input[16]; \ - X##mi = state[17]^input[17]; \ - X##mo = state[18]^input[18]; \ - X##mu = state[19]^input[19]; \ - if (laneCount < 22) { \ - if (laneCount < 21) { \ - X##sa = state[20]; \ - } \ - else { \ - X##sa = state[20]^input[20]; \ - } \ - X##se = state[21]; \ - X##si = state[22]; \ - } \ - else { \ - X##sa = state[20]^input[20]; \ - X##se = state[21]^input[21]; \ - if (laneCount < 23) { \ - X##si = state[22]; \ - } \ - else { \ - X##si = state[22]^input[22]; \ - } \ - } \ - } \ - X##so = state[23]; \ - X##su = state[24]; \ - } \ - else { \ - X##me = state[16]^input[16]; \ - X##mi = state[17]^input[17]; \ - X##mo = state[18]^input[18]; \ - X##mu = state[19]^input[19]; \ - X##sa = state[20]^input[20]; \ - X##se = state[21]^input[21]; \ - X##si = state[22]^input[22]; \ - X##so = state[23]^input[23]; \ - if (laneCount < 25) { \ - X##su = state[24]; \ - } \ - else { \ - X##su = state[24]^input[24]; \ - } \ - } \ - } - -#define addInput(X, input, laneCount) \ - if (laneCount == 21) { \ - X##ba ^= input[ 0]; \ - X##be ^= input[ 1]; \ - X##bi ^= input[ 2]; \ - X##bo ^= input[ 3]; \ - X##bu ^= input[ 4]; \ - X##ga ^= input[ 5]; \ - X##ge ^= input[ 6]; \ - X##gi ^= input[ 7]; \ - X##go ^= input[ 8]; \ - X##gu ^= input[ 9]; \ - X##ka ^= input[10]; \ - X##ke ^= input[11]; \ - X##ki ^= input[12]; \ - X##ko ^= input[13]; \ - X##ku ^= input[14]; \ - X##ma ^= input[15]; \ - X##me ^= input[16]; \ - X##mi ^= input[17]; \ - X##mo ^= input[18]; \ - X##mu ^= input[19]; \ - X##sa ^= input[20]; \ - } \ - else if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount < 1) { \ - } \ - else { \ - X##ba ^= input[ 0]; \ - } \ - } \ - else { \ - X##ba ^= input[ 0]; \ - X##be ^= input[ 1]; \ - if (laneCount < 3) { \ - } \ - else { \ - X##bi ^= input[ 2]; \ - } \ - } \ - } \ - else { \ - X##ba ^= input[ 0]; \ - X##be ^= input[ 1]; \ - X##bi ^= input[ 2]; \ - X##bo ^= input[ 3]; \ - if (laneCount < 6) { \ - if (laneCount < 5) { \ - } \ - else { \ - X##bu ^= input[ 4]; \ - } \ - } \ - else { \ - X##bu ^= input[ 4]; \ - X##ga ^= input[ 5]; \ - if (laneCount < 7) { \ - } \ - else { \ - X##ge ^= input[ 6]; \ - } \ - } \ - } \ - } \ - else { \ - X##ba ^= input[ 0]; \ - X##be ^= input[ 1]; \ - X##bi ^= input[ 2]; \ - X##bo ^= input[ 3]; \ - X##bu ^= input[ 4]; \ - X##ga ^= input[ 5]; \ - X##ge ^= input[ 6]; \ - X##gi ^= input[ 7]; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount < 9) { \ - } \ - else { \ - X##go ^= input[ 8]; \ - } \ - } \ - else { \ - X##go ^= input[ 8]; \ - X##gu ^= input[ 9]; \ - if (laneCount < 11) { \ - } \ - else { \ - X##ka ^= input[10]; \ - } \ - } \ - } \ - else { \ - X##go ^= input[ 8]; \ - X##gu ^= input[ 9]; \ - X##ka ^= input[10]; \ - X##ke ^= input[11]; \ - if (laneCount < 14) { \ - if (laneCount < 13) { \ - } \ - else { \ - X##ki ^= input[12]; \ - } \ - } \ - else { \ - X##ki ^= input[12]; \ - X##ko ^= input[13]; \ - if (laneCount < 15) { \ - } \ - else { \ - X##ku ^= input[14]; \ - } \ - } \ - } \ - } \ - } \ - else { \ - X##ba ^= input[ 0]; \ - X##be ^= input[ 1]; \ - X##bi ^= input[ 2]; \ - X##bo ^= input[ 3]; \ - X##bu ^= input[ 4]; \ - X##ga ^= input[ 5]; \ - X##ge ^= input[ 6]; \ - X##gi ^= input[ 7]; \ - X##go ^= input[ 8]; \ - X##gu ^= input[ 9]; \ - X##ka ^= input[10]; \ - X##ke ^= input[11]; \ - X##ki ^= input[12]; \ - X##ko ^= input[13]; \ - X##ku ^= input[14]; \ - X##ma ^= input[15]; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount < 17) { \ - } \ - else { \ - X##me ^= input[16]; \ - } \ - } \ - else { \ - X##me ^= input[16]; \ - X##mi ^= input[17]; \ - if (laneCount < 19) { \ - } \ - else { \ - X##mo ^= input[18]; \ - } \ - } \ - } \ - else { \ - X##me ^= input[16]; \ - X##mi ^= input[17]; \ - X##mo ^= input[18]; \ - X##mu ^= input[19]; \ - if (laneCount < 22) { \ - if (laneCount < 21) { \ - } \ - else { \ - X##sa ^= input[20]; \ - } \ - } \ - else { \ - X##sa ^= input[20]; \ - X##se ^= input[21]; \ - if (laneCount < 23) { \ - } \ - else { \ - X##si ^= input[22]; \ - } \ - } \ - } \ - } \ - else { \ - X##me ^= input[16]; \ - X##mi ^= input[17]; \ - X##mo ^= input[18]; \ - X##mu ^= input[19]; \ - X##sa ^= input[20]; \ - X##se ^= input[21]; \ - X##si ^= input[22]; \ - X##so ^= input[23]; \ - if (laneCount < 25) { \ - } \ - else { \ - X##su ^= input[24]; \ - } \ - } \ - } - -#ifdef UseBebigokimisa - -#define copyToStateAndOutput(X, state, output, laneCount) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - state[ 0] = X##ba; \ - if (laneCount >= 1) { \ - output[ 0] = X##ba; \ - } \ - state[ 1] = X##be; \ - state[ 2] = X##bi; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = ~X##be; \ - state[ 2] = X##bi; \ - if (laneCount >= 3) { \ - output[ 2] = ~X##bi; \ - } \ - } \ - state[ 3] = X##bo; \ - state[ 4] = X##bu; \ - state[ 5] = X##ga; \ - state[ 6] = X##ge; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = ~X##be; \ - state[ 2] = X##bi; \ - output[ 2] = ~X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - if (laneCount < 6) { \ - state[ 4] = X##bu; \ - if (laneCount >= 5) { \ - output[ 4] = X##bu; \ - } \ - state[ 5] = X##ga; \ - state[ 6] = X##ge; \ - } \ - else { \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - if (laneCount >= 7) { \ - output[ 6] = X##ge; \ - } \ - } \ - } \ - state[ 7] = X##gi; \ - state[ 8] = X##go; \ - state[ 9] = X##gu; \ - state[10] = X##ka; \ - state[11] = X##ke; \ - state[12] = X##ki; \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = ~X##be; \ - state[ 2] = X##bi; \ - output[ 2] = ~X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - output[ 6] = X##ge; \ - state[ 7] = X##gi; \ - output[ 7] = X##gi; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - state[ 8] = X##go; \ - if (laneCount >= 9) { \ - output[ 8] = ~X##go; \ - } \ - state[ 9] = X##gu; \ - state[10] = X##ka; \ - } \ - else { \ - state[ 8] = X##go; \ - output[ 8] = ~X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - if (laneCount >= 11) { \ - output[10] = X##ka; \ - } \ - } \ - state[11] = X##ke; \ - state[12] = X##ki; \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[ 8] = X##go; \ - output[ 8] = ~X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - output[10] = X##ka; \ - state[11] = X##ke; \ - output[11] = X##ke; \ - if (laneCount < 14) { \ - state[12] = X##ki; \ - if (laneCount >= 13) { \ - output[12] = ~X##ki; \ - } \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[12] = X##ki; \ - output[12] = ~X##ki; \ - state[13] = X##ko; \ - output[13] = X##ko; \ - state[14] = X##ku; \ - if (laneCount >= 15) { \ - output[14] = X##ku; \ - } \ - } \ - } \ - } \ - state[15] = X##ma; \ - state[16] = X##me; \ - state[17] = X##mi; \ - state[18] = X##mo; \ - state[19] = X##mu; \ - state[20] = X##sa; \ - state[21] = X##se; \ - state[22] = X##si; \ - state[23] = X##so; \ - state[24] = X##su; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = ~X##be; \ - state[ 2] = X##bi; \ - output[ 2] = ~X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - output[ 6] = X##ge; \ - state[ 7] = X##gi; \ - output[ 7] = X##gi; \ - state[ 8] = X##go; \ - output[ 8] = ~X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - output[10] = X##ka; \ - state[11] = X##ke; \ - output[11] = X##ke; \ - state[12] = X##ki; \ - output[12] = ~X##ki; \ - state[13] = X##ko; \ - output[13] = X##ko; \ - state[14] = X##ku; \ - output[14] = X##ku; \ - state[15] = X##ma; \ - output[15] = X##ma; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - state[16] = X##me; \ - if (laneCount >= 17) { \ - output[16] = X##me; \ - } \ - state[17] = X##mi; \ - state[18] = X##mo; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = ~X##mi; \ - state[18] = X##mo; \ - if (laneCount >= 19) { \ - output[18] = X##mo; \ - } \ - } \ - state[19] = X##mu; \ - state[20] = X##sa; \ - state[21] = X##se; \ - state[22] = X##si; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = ~X##mi; \ - state[18] = X##mo; \ - output[18] = X##mo; \ - state[19] = X##mu; \ - output[19] = X##mu; \ - if (laneCount < 22) { \ - state[20] = X##sa; \ - if (laneCount >= 21) { \ - output[20] = ~X##sa; \ - } \ - state[21] = X##se; \ - state[22] = X##si; \ - } \ - else { \ - state[20] = X##sa; \ - output[20] = ~X##sa; \ - state[21] = X##se; \ - output[21] = X##se; \ - state[22] = X##si; \ - if (laneCount >= 23) { \ - output[22] = X##si; \ - } \ - } \ - } \ - state[23] = X##so; \ - state[24] = X##su; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = ~X##mi; \ - state[18] = X##mo; \ - output[18] = X##mo; \ - state[19] = X##mu; \ - output[19] = X##mu; \ - state[20] = X##sa; \ - output[20] = ~X##sa; \ - state[21] = X##se; \ - output[21] = X##se; \ - state[22] = X##si; \ - output[22] = X##si; \ - state[23] = X##so; \ - output[23] = X##so; \ - state[24] = X##su; \ - if (laneCount >= 25) { \ - output[24] = X##su; \ - } \ - } \ - } - -#define output(X, output, laneCount) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount >= 1) { \ - output[ 0] = X##ba; \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = ~X##be; \ - if (laneCount >= 3) { \ - output[ 2] = ~X##bi; \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = ~X##be; \ - output[ 2] = ~X##bi; \ - output[ 3] = X##bo; \ - if (laneCount < 6) { \ - if (laneCount >= 5) { \ - output[ 4] = X##bu; \ - } \ - } \ - else { \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - if (laneCount >= 7) { \ - output[ 6] = X##ge; \ - } \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = ~X##be; \ - output[ 2] = ~X##bi; \ - output[ 3] = X##bo; \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - output[ 6] = X##ge; \ - output[ 7] = X##gi; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount >= 9) { \ - output[ 8] = ~X##go; \ - } \ - } \ - else { \ - output[ 8] = ~X##go; \ - output[ 9] = X##gu; \ - if (laneCount >= 11) { \ - output[10] = X##ka; \ - } \ - } \ - } \ - else { \ - output[ 8] = ~X##go; \ - output[ 9] = X##gu; \ - output[10] = X##ka; \ - output[11] = X##ke; \ - if (laneCount < 14) { \ - if (laneCount >= 13) { \ - output[12] = ~X##ki; \ - } \ - } \ - else { \ - output[12] = ~X##ki; \ - output[13] = X##ko; \ - if (laneCount >= 15) { \ - output[14] = X##ku; \ - } \ - } \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = ~X##be; \ - output[ 2] = ~X##bi; \ - output[ 3] = X##bo; \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - output[ 6] = X##ge; \ - output[ 7] = X##gi; \ - output[ 8] = ~X##go; \ - output[ 9] = X##gu; \ - output[10] = X##ka; \ - output[11] = X##ke; \ - output[12] = ~X##ki; \ - output[13] = X##ko; \ - output[14] = X##ku; \ - output[15] = X##ma; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount >= 17) { \ - output[16] = X##me; \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = ~X##mi; \ - if (laneCount >= 19) { \ - output[18] = X##mo; \ - } \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = ~X##mi; \ - output[18] = X##mo; \ - output[19] = X##mu; \ - if (laneCount < 22) { \ - if (laneCount >= 21) { \ - output[20] = ~X##sa; \ - } \ - } \ - else { \ - output[20] = ~X##sa; \ - output[21] = X##se; \ - if (laneCount >= 23) { \ - output[22] = X##si; \ - } \ - } \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = ~X##mi; \ - output[18] = X##mo; \ - output[19] = X##mu; \ - output[20] = ~X##sa; \ - output[21] = X##se; \ - output[22] = X##si; \ - output[23] = X##so; \ - if (laneCount >= 25) { \ - output[24] = X##su; \ - } \ - } \ - } - -#define wrapOne(X, input, output, index, name) \ - X##name ^= input[index]; \ - output[index] = X##name; - -#define wrapOneInvert(X, input, output, index, name) \ - X##name ^= input[index]; \ - output[index] = ~X##name; - -#define unwrapOne(X, input, output, index, name) \ - output[index] = input[index] ^ X##name; \ - X##name ^= output[index]; - -#define unwrapOneInvert(X, input, output, index, name) \ - output[index] = ~(input[index] ^ X##name); \ - X##name ^= output[index]; \ - -#else /* UseBebigokimisa */ - - -#define copyToStateAndOutput(X, state, output, laneCount) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - state[ 0] = X##ba; \ - if (laneCount >= 1) { \ - output[ 0] = X##ba; \ - } \ - state[ 1] = X##be; \ - state[ 2] = X##bi; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = X##be; \ - state[ 2] = X##bi; \ - if (laneCount >= 3) { \ - output[ 2] = X##bi; \ - } \ - } \ - state[ 3] = X##bo; \ - state[ 4] = X##bu; \ - state[ 5] = X##ga; \ - state[ 6] = X##ge; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = X##be; \ - state[ 2] = X##bi; \ - output[ 2] = X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - if (laneCount < 6) { \ - state[ 4] = X##bu; \ - if (laneCount >= 5) { \ - output[ 4] = X##bu; \ - } \ - state[ 5] = X##ga; \ - state[ 6] = X##ge; \ - } \ - else { \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - if (laneCount >= 7) { \ - output[ 6] = X##ge; \ - } \ - } \ - } \ - state[ 7] = X##gi; \ - state[ 8] = X##go; \ - state[ 9] = X##gu; \ - state[10] = X##ka; \ - state[11] = X##ke; \ - state[12] = X##ki; \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = X##be; \ - state[ 2] = X##bi; \ - output[ 2] = X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - output[ 6] = X##ge; \ - state[ 7] = X##gi; \ - output[ 7] = X##gi; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - state[ 8] = X##go; \ - if (laneCount >= 9) { \ - output[ 8] = X##go; \ - } \ - state[ 9] = X##gu; \ - state[10] = X##ka; \ - } \ - else { \ - state[ 8] = X##go; \ - output[ 8] = X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - if (laneCount >= 11) { \ - output[10] = X##ka; \ - } \ - } \ - state[11] = X##ke; \ - state[12] = X##ki; \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[ 8] = X##go; \ - output[ 8] = X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - output[10] = X##ka; \ - state[11] = X##ke; \ - output[11] = X##ke; \ - if (laneCount < 14) { \ - state[12] = X##ki; \ - if (laneCount >= 13) { \ - output[12]= X##ki; \ - } \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[12] = X##ki; \ - output[12]= X##ki; \ - state[13] = X##ko; \ - output[13] = X##ko; \ - state[14] = X##ku; \ - if (laneCount >= 15) { \ - output[14] = X##ku; \ - } \ - } \ - } \ - } \ - state[15] = X##ma; \ - state[16] = X##me; \ - state[17] = X##mi; \ - state[18] = X##mo; \ - state[19] = X##mu; \ - state[20] = X##sa; \ - state[21] = X##se; \ - state[22] = X##si; \ - state[23] = X##so; \ - state[24] = X##su; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = X##be; \ - state[ 2] = X##bi; \ - output[ 2] = X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - output[ 6] = X##ge; \ - state[ 7] = X##gi; \ - output[ 7] = X##gi; \ - state[ 8] = X##go; \ - output[ 8] = X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - output[10] = X##ka; \ - state[11] = X##ke; \ - output[11] = X##ke; \ - state[12] = X##ki; \ - output[12]= X##ki; \ - state[13] = X##ko; \ - output[13] = X##ko; \ - state[14] = X##ku; \ - output[14] = X##ku; \ - state[15] = X##ma; \ - output[15] = X##ma; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - state[16] = X##me; \ - if (laneCount >= 17) { \ - output[16] = X##me; \ - } \ - state[17] = X##mi; \ - state[18] = X##mo; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = X##mi; \ - state[18] = X##mo; \ - if (laneCount >= 19) { \ - output[18] = X##mo; \ - } \ - } \ - state[19] = X##mu; \ - state[20] = X##sa; \ - state[21] = X##se; \ - state[22] = X##si; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = X##mi; \ - state[18] = X##mo; \ - output[18] = X##mo; \ - state[19] = X##mu; \ - output[19] = X##mu; \ - if (laneCount < 22) { \ - state[20] = X##sa; \ - if (laneCount >= 21) { \ - output[20] = X##sa; \ - } \ - state[21] = X##se; \ - state[22] = X##si; \ - } \ - else { \ - state[20] = X##sa; \ - output[20] = X##sa; \ - state[21] = X##se; \ - output[21] = X##se; \ - state[22] = X##si; \ - if (laneCount >= 23) { \ - output[22] = X##si; \ - } \ - } \ - } \ - state[23] = X##so; \ - state[24] = X##su; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = X##mi; \ - state[18] = X##mo; \ - output[18] = X##mo; \ - state[19] = X##mu; \ - output[19] = X##mu; \ - state[20] = X##sa; \ - output[20] = X##sa; \ - state[21] = X##se; \ - output[21] = X##se; \ - state[22] = X##si; \ - output[22] = X##si; \ - state[23] = X##so; \ - output[23] = X##so; \ - state[24] = X##su; \ - if (laneCount >= 25) { \ - output[24] = X##su; \ - } \ - } \ - } - -#define output(X, output, laneCount) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount >= 1) { \ - output[ 0] = X##ba; \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = X##be; \ - if (laneCount >= 3) { \ - output[ 2] = X##bi; \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = X##be; \ - output[ 2] = X##bi; \ - output[ 3] = X##bo; \ - if (laneCount < 6) { \ - if (laneCount >= 5) { \ - output[ 4] = X##bu; \ - } \ - } \ - else { \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - if (laneCount >= 7) { \ - output[ 6] = X##ge; \ - } \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = X##be; \ - output[ 2] = X##bi; \ - output[ 3] = X##bo; \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - output[ 6] = X##ge; \ - output[ 7] = X##gi; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount >= 9) { \ - output[ 8] = X##go; \ - } \ - } \ - else { \ - output[ 8] = X##go; \ - output[ 9] = X##gu; \ - if (laneCount >= 11) { \ - output[10] = X##ka; \ - } \ - } \ - } \ - else { \ - output[ 8] = X##go; \ - output[ 9] = X##gu; \ - output[10] = X##ka; \ - output[11] = X##ke; \ - if (laneCount < 14) { \ - if (laneCount >= 13) { \ - output[12] = X##ki; \ - } \ - } \ - else { \ - output[12] = X##ki; \ - output[13] = X##ko; \ - if (laneCount >= 15) { \ - output[14] = X##ku; \ - } \ - } \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = X##be; \ - output[ 2] = X##bi; \ - output[ 3] = X##bo; \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - output[ 6] = X##ge; \ - output[ 7] = X##gi; \ - output[ 8] = X##go; \ - output[ 9] = X##gu; \ - output[10] = X##ka; \ - output[11] = X##ke; \ - output[12] = X##ki; \ - output[13] = X##ko; \ - output[14] = X##ku; \ - output[15] = X##ma; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount >= 17) { \ - output[16] = X##me; \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = X##mi; \ - if (laneCount >= 19) { \ - output[18] = X##mo; \ - } \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = X##mi; \ - output[18] = X##mo; \ - output[19] = X##mu; \ - if (laneCount < 22) { \ - if (laneCount >= 21) { \ - output[20] = X##sa; \ - } \ - } \ - else { \ - output[20] = X##sa; \ - output[21] = X##se; \ - if (laneCount >= 23) { \ - output[22] = X##si; \ - } \ - } \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = X##mi; \ - output[18] = X##mo; \ - output[19] = X##mu; \ - output[20] = X##sa; \ - output[21] = X##se; \ - output[22] = X##si; \ - output[23] = X##so; \ - if (laneCount >= 25) { \ - output[24] = X##su; \ - } \ - } \ - } - -#define wrapOne(X, input, output, index, name) \ - X##name ^= input[index]; \ - output[index] = X##name; - -#define wrapOneInvert(X, input, output, index, name) \ - X##name ^= input[index]; \ - output[index] = X##name; - -#define unwrapOne(X, input, output, index, name) \ - output[index] = input[index] ^ X##name; \ - X##name ^= output[index]; - -#define unwrapOneInvert(X, input, output, index, name) \ - output[index] = input[index] ^ X##name; \ - X##name ^= output[index]; - -#endif - -#define wrap(X, input, output, laneCount, trailingBits) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount < 1) { \ - X##ba ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 0, ba) \ - X##be ^= trailingBits; \ - } \ - } \ - else { \ - wrapOne(X, input, output, 0, ba) \ - wrapOneInvert(X, input, output, 1, be) \ - if (laneCount < 3) { \ - X##bi ^= trailingBits; \ - } \ - else { \ - wrapOneInvert(X, input, output, 2, bi) \ - X##bo ^= trailingBits; \ - } \ - } \ - } \ - else { \ - wrapOne(X, input, output, 0, ba) \ - wrapOneInvert(X, input, output, 1, be) \ - wrapOneInvert(X, input, output, 2, bi) \ - wrapOne(X, input, output, 3, bo) \ - if (laneCount < 6) { \ - if (laneCount < 5) { \ - X##bu ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 4, bu) \ - X##ga ^= trailingBits; \ - } \ - } \ - else { \ - wrapOne(X, input, output, 4, bu) \ - wrapOne(X, input, output, 5, ga) \ - if (laneCount < 7) { \ - X##ge ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 6, ge) \ - X##gi ^= trailingBits; \ - } \ - } \ - } \ - } \ - else { \ - wrapOne(X, input, output, 0, ba) \ - wrapOneInvert(X, input, output, 1, be) \ - wrapOneInvert(X, input, output, 2, bi) \ - wrapOne(X, input, output, 3, bo) \ - wrapOne(X, input, output, 4, bu) \ - wrapOne(X, input, output, 5, ga) \ - wrapOne(X, input, output, 6, ge) \ - wrapOne(X, input, output, 7, gi) \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount < 9) { \ - X##go ^= trailingBits; \ - } \ - else { \ - wrapOneInvert(X, input, output, 8, go) \ - X##gu ^= trailingBits; \ - } \ - } \ - else { \ - wrapOneInvert(X, input, output, 8, go) \ - wrapOne(X, input, output, 9, gu) \ - if (laneCount < 11) { \ - X##ka ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 10, ka) \ - X##ke ^= trailingBits; \ - } \ - } \ - } \ - else { \ - wrapOneInvert(X, input, output, 8, go) \ - wrapOne(X, input, output, 9, gu) \ - wrapOne(X, input, output, 10, ka) \ - wrapOne(X, input, output, 11, ke) \ - if (laneCount < 14) { \ - if (laneCount < 13) { \ - X##ki ^= trailingBits; \ - } \ - else { \ - wrapOneInvert(X, input, output, 12, ki) \ - X##ko ^= trailingBits; \ - } \ - } \ - else { \ - wrapOneInvert(X, input, output, 12, ki) \ - wrapOne(X, input, output, 13, ko) \ - if (laneCount < 15) { \ - X##ku ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 14, ku) \ - X##ma ^= trailingBits; \ - } \ - } \ - } \ - } \ - } \ - else { \ - wrapOne(X, input, output, 0, ba) \ - wrapOneInvert(X, input, output, 1, be) \ - wrapOneInvert(X, input, output, 2, bi) \ - wrapOne(X, input, output, 3, bo) \ - wrapOne(X, input, output, 4, bu) \ - wrapOne(X, input, output, 5, ga) \ - wrapOne(X, input, output, 6, ge) \ - wrapOne(X, input, output, 7, gi) \ - wrapOneInvert(X, input, output, 8, go) \ - wrapOne(X, input, output, 9, gu) \ - wrapOne(X, input, output, 10, ka) \ - wrapOne(X, input, output, 11, ke) \ - wrapOneInvert(X, input, output, 12, ki) \ - wrapOne(X, input, output, 13, ko) \ - wrapOne(X, input, output, 14, ku) \ - wrapOne(X, input, output, 15, ma) \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount < 17) { \ - X##me ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 16, me) \ - X##mi ^= trailingBits; \ - } \ - } \ - else { \ - wrapOne(X, input, output, 16, me) \ - wrapOneInvert(X, input, output, 17, mi) \ - if (laneCount < 19) { \ - X##mo ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 18, mo) \ - X##mu ^= trailingBits; \ - } \ - } \ - } \ - else { \ - wrapOne(X, input, output, 16, me) \ - wrapOneInvert(X, input, output, 17, mi) \ - wrapOne(X, input, output, 18, mo) \ - wrapOne(X, input, output, 19, mu) \ - if (laneCount < 22) { \ - if (laneCount < 21) { \ - X##sa ^= trailingBits; \ - } \ - else { \ - wrapOneInvert(X, input, output, 20, sa) \ - X##se ^= trailingBits; \ - } \ - } \ - else { \ - wrapOneInvert(X, input, output, 20, sa) \ - wrapOne(X, input, output, 21, se) \ - if (laneCount < 23) { \ - X##si ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 22, si) \ - X##so ^= trailingBits; \ - } \ - } \ - } \ - } \ - else { \ - wrapOne(X, input, output, 16, me) \ - wrapOneInvert(X, input, output, 17, mi) \ - wrapOne(X, input, output, 18, mo) \ - wrapOne(X, input, output, 19, mu) \ - wrapOneInvert(X, input, output, 20, sa) \ - wrapOne(X, input, output, 21, se) \ - wrapOne(X, input, output, 22, si) \ - wrapOne(X, input, output, 23, so) \ - if (laneCount < 25) { \ - X##su ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 24, su) \ - } \ - } \ - } - -#define unwrap(X, input, output, laneCount, trailingBits) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount < 1) { \ - X##ba ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 0, ba) \ - X##be ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 0, ba) \ - unwrapOneInvert(X, input, output, 1, be) \ - if (laneCount < 3) { \ - X##bi ^= trailingBits; \ - } \ - else { \ - unwrapOneInvert(X, input, output, 2, bi) \ - X##bo ^= trailingBits; \ - } \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 0, ba) \ - unwrapOneInvert(X, input, output, 1, be) \ - unwrapOneInvert(X, input, output, 2, bi) \ - unwrapOne(X, input, output, 3, bo) \ - if (laneCount < 6) { \ - if (laneCount < 5) { \ - X##bu ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 4, bu) \ - X##ga ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 4, bu) \ - unwrapOne(X, input, output, 5, ga) \ - if (laneCount < 7) { \ - X##ge ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 6, ge) \ - X##gi ^= trailingBits; \ - } \ - } \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 0, ba) \ - unwrapOneInvert(X, input, output, 1, be) \ - unwrapOneInvert(X, input, output, 2, bi) \ - unwrapOne(X, input, output, 3, bo) \ - unwrapOne(X, input, output, 4, bu) \ - unwrapOne(X, input, output, 5, ga) \ - unwrapOne(X, input, output, 6, ge) \ - unwrapOne(X, input, output, 7, gi) \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount < 9) { \ - X##go ^= trailingBits; \ - } \ - else { \ - unwrapOneInvert(X, input, output, 8, go) \ - X##gu ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOneInvert(X, input, output, 8, go) \ - unwrapOne(X, input, output, 9, gu) \ - if (laneCount < 11) { \ - X##ka ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 10, ka) \ - X##ke ^= trailingBits; \ - } \ - } \ - } \ - else { \ - unwrapOneInvert(X, input, output, 8, go) \ - unwrapOne(X, input, output, 9, gu) \ - unwrapOne(X, input, output, 10, ka) \ - unwrapOne(X, input, output, 11, ke) \ - if (laneCount < 14) { \ - if (laneCount < 13) { \ - X##ki ^= trailingBits; \ - } \ - else { \ - unwrapOneInvert(X, input, output, 12, ki) \ - X##ko ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOneInvert(X, input, output, 12, ki) \ - unwrapOne(X, input, output, 13, ko) \ - if (laneCount < 15) { \ - X##ku ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 14, ku) \ - X##ma ^= trailingBits; \ - } \ - } \ - } \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 0, ba) \ - unwrapOneInvert(X, input, output, 1, be) \ - unwrapOneInvert(X, input, output, 2, bi) \ - unwrapOne(X, input, output, 3, bo) \ - unwrapOne(X, input, output, 4, bu) \ - unwrapOne(X, input, output, 5, ga) \ - unwrapOne(X, input, output, 6, ge) \ - unwrapOne(X, input, output, 7, gi) \ - unwrapOneInvert(X, input, output, 8, go) \ - unwrapOne(X, input, output, 9, gu) \ - unwrapOne(X, input, output, 10, ka) \ - unwrapOne(X, input, output, 11, ke) \ - unwrapOneInvert(X, input, output, 12, ki) \ - unwrapOne(X, input, output, 13, ko) \ - unwrapOne(X, input, output, 14, ku) \ - unwrapOne(X, input, output, 15, ma) \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount < 17) { \ - X##me ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 16, me) \ - X##mi ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 16, me) \ - unwrapOneInvert(X, input, output, 17, mi) \ - if (laneCount < 19) { \ - X##mo ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 18, mo) \ - X##mu ^= trailingBits; \ - } \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 16, me) \ - unwrapOneInvert(X, input, output, 17, mi) \ - unwrapOne(X, input, output, 18, mo) \ - unwrapOne(X, input, output, 19, mu) \ - if (laneCount < 22) { \ - if (laneCount < 21) { \ - X##sa ^= trailingBits; \ - } \ - else { \ - unwrapOneInvert(X, input, output, 20, sa) \ - X##se ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOneInvert(X, input, output, 20, sa) \ - unwrapOne(X, input, output, 21, se) \ - if (laneCount < 23) { \ - X##si ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 22, si) \ - X##so ^= trailingBits; \ - } \ - } \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 16, me) \ - unwrapOneInvert(X, input, output, 17, mi) \ - unwrapOne(X, input, output, 18, mo) \ - unwrapOne(X, input, output, 19, mu) \ - unwrapOneInvert(X, input, output, 20, sa) \ - unwrapOne(X, input, output, 21, se) \ - unwrapOne(X, input, output, 22, si) \ - unwrapOne(X, input, output, 23, so) \ - if (laneCount < 25) { \ - X##su ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 24, su) \ - } \ - } \ - } diff --git a/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h b/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h deleted file mode 100644 index 6cf765e6ce1..00000000000 --- a/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _KeccakP_1600_SnP_h_ -#define _KeccakP_1600_SnP_h_ - -/** For the documentation, see SnP-documentation.h. - */ - -#define KeccakP1600_implementation "in-place 32-bit optimized implementation" -#define KeccakP1600_stateSizeInBytes 200 -#define KeccakP1600_stateAlignment 8 - -#define KeccakP1600_StaticInitialize() -void KeccakP1600_Initialize(void *state); -void KeccakP1600_AddByte(void *state, unsigned char data, unsigned int offset); -void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount); -void KeccakP1600_Permute_12rounds(void *state); -void KeccakP1600_Permute_24rounds(void *state); -void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length); - -#endif diff --git a/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h b/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h deleted file mode 100644 index 889a31a7944..00000000000 --- a/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _KeccakP_1600_SnP_h_ -#define _KeccakP_1600_SnP_h_ - -/** For the documentation, see SnP-documentation.h. - */ - -/* #include "brg_endian.h" */ -#include "KeccakP-1600-opt64-config.h" - -#define KeccakP1600_implementation "generic 64-bit optimized implementation (" KeccakP1600_implementation_config ")" -#define KeccakP1600_stateSizeInBytes 200 -#define KeccakP1600_stateAlignment 8 -#define KeccakF1600_FastLoop_supported - -#include - -#define KeccakP1600_StaticInitialize() -void KeccakP1600_Initialize(void *state); -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) -#define KeccakP1600_AddByte(state, byte, offset) \ - ((unsigned char*)(state))[(offset)] ^= (byte) -#else -void KeccakP1600_AddByte(void *state, unsigned char data, unsigned int offset); -#endif -void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount); -void KeccakP1600_Permute_12rounds(void *state); -void KeccakP1600_Permute_24rounds(void *state); -void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length); -size_t KeccakF1600_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen); - -#endif diff --git a/Modules/_sha3/kcp/KeccakP-1600-SnP.h b/Modules/_sha3/kcp/KeccakP-1600-SnP.h deleted file mode 100644 index 0b23f09a6a4..00000000000 --- a/Modules/_sha3/kcp/KeccakP-1600-SnP.h +++ /dev/null @@ -1,7 +0,0 @@ -#if KeccakOpt == 64 - #include "KeccakP-1600-SnP-opt64.h" -#elif KeccakOpt == 32 - #include "KeccakP-1600-SnP-opt32.h" -#else - #error "No KeccakOpt" -#endif diff --git a/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c b/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c deleted file mode 100644 index a2f9ffea932..00000000000 --- a/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c +++ /dev/null @@ -1,1162 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#include -/* #include "brg_endian.h" */ -#include "KeccakP-1600-SnP.h" -#include "SnP-Relaned.h" - -typedef unsigned char UINT8; -typedef unsigned int UINT32; -/* WARNING: on 8-bit and 16-bit platforms, this should be replaced by: */ - -/*typedef unsigned long UINT32; */ - - -#define ROL32(a, offset) ((((UINT32)a) << (offset)) ^ (((UINT32)a) >> (32-(offset)))) - -/* Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ - -#define prepareToBitInterleaving(low, high, temp, temp0, temp1) \ - temp0 = (low); \ - temp = (temp0 ^ (temp0 >> 1)) & 0x22222222UL; temp0 = temp0 ^ temp ^ (temp << 1); \ - temp = (temp0 ^ (temp0 >> 2)) & 0x0C0C0C0CUL; temp0 = temp0 ^ temp ^ (temp << 2); \ - temp = (temp0 ^ (temp0 >> 4)) & 0x00F000F0UL; temp0 = temp0 ^ temp ^ (temp << 4); \ - temp = (temp0 ^ (temp0 >> 8)) & 0x0000FF00UL; temp0 = temp0 ^ temp ^ (temp << 8); \ - temp1 = (high); \ - temp = (temp1 ^ (temp1 >> 1)) & 0x22222222UL; temp1 = temp1 ^ temp ^ (temp << 1); \ - temp = (temp1 ^ (temp1 >> 2)) & 0x0C0C0C0CUL; temp1 = temp1 ^ temp ^ (temp << 2); \ - temp = (temp1 ^ (temp1 >> 4)) & 0x00F000F0UL; temp1 = temp1 ^ temp ^ (temp << 4); \ - temp = (temp1 ^ (temp1 >> 8)) & 0x0000FF00UL; temp1 = temp1 ^ temp ^ (temp << 8); - -#define toBitInterleavingAndXOR(low, high, even, odd, temp, temp0, temp1) \ - prepareToBitInterleaving(low, high, temp, temp0, temp1) \ - even ^= (temp0 & 0x0000FFFF) | (temp1 << 16); \ - odd ^= (temp0 >> 16) | (temp1 & 0xFFFF0000); - -#define toBitInterleavingAndAND(low, high, even, odd, temp, temp0, temp1) \ - prepareToBitInterleaving(low, high, temp, temp0, temp1) \ - even &= (temp0 & 0x0000FFFF) | (temp1 << 16); \ - odd &= (temp0 >> 16) | (temp1 & 0xFFFF0000); - -#define toBitInterleavingAndSet(low, high, even, odd, temp, temp0, temp1) \ - prepareToBitInterleaving(low, high, temp, temp0, temp1) \ - even = (temp0 & 0x0000FFFF) | (temp1 << 16); \ - odd = (temp0 >> 16) | (temp1 & 0xFFFF0000); - -/* Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ - -#define prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \ - temp0 = (even); \ - temp1 = (odd); \ - temp = (temp0 & 0x0000FFFF) | (temp1 << 16); \ - temp1 = (temp0 >> 16) | (temp1 & 0xFFFF0000); \ - temp0 = temp; \ - temp = (temp0 ^ (temp0 >> 8)) & 0x0000FF00UL; temp0 = temp0 ^ temp ^ (temp << 8); \ - temp = (temp0 ^ (temp0 >> 4)) & 0x00F000F0UL; temp0 = temp0 ^ temp ^ (temp << 4); \ - temp = (temp0 ^ (temp0 >> 2)) & 0x0C0C0C0CUL; temp0 = temp0 ^ temp ^ (temp << 2); \ - temp = (temp0 ^ (temp0 >> 1)) & 0x22222222UL; temp0 = temp0 ^ temp ^ (temp << 1); \ - temp = (temp1 ^ (temp1 >> 8)) & 0x0000FF00UL; temp1 = temp1 ^ temp ^ (temp << 8); \ - temp = (temp1 ^ (temp1 >> 4)) & 0x00F000F0UL; temp1 = temp1 ^ temp ^ (temp << 4); \ - temp = (temp1 ^ (temp1 >> 2)) & 0x0C0C0C0CUL; temp1 = temp1 ^ temp ^ (temp << 2); \ - temp = (temp1 ^ (temp1 >> 1)) & 0x22222222UL; temp1 = temp1 ^ temp ^ (temp << 1); - -#define fromBitInterleaving(even, odd, low, high, temp, temp0, temp1) \ - prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \ - low = temp0; \ - high = temp1; - -#define fromBitInterleavingAndXOR(even, odd, lowIn, highIn, lowOut, highOut, temp, temp0, temp1) \ - prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \ - lowOut = lowIn ^ temp0; \ - highOut = highIn ^ temp1; - -void KeccakP1600_SetBytesInLaneToZero(void *state, unsigned int lanePosition, unsigned int offset, unsigned int length) -{ - UINT8 laneAsBytes[8]; - UINT32 low, high; - UINT32 temp, temp0, temp1; - UINT32 *stateAsHalfLanes = (UINT32*)state; - - memset(laneAsBytes, 0xFF, offset); - memset(laneAsBytes+offset, 0x00, length); - memset(laneAsBytes+offset+length, 0xFF, 8-offset-length); -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - low = *((UINT32*)(laneAsBytes+0)); - high = *((UINT32*)(laneAsBytes+4)); -#else - low = laneAsBytes[0] - | ((UINT32)(laneAsBytes[1]) << 8) - | ((UINT32)(laneAsBytes[2]) << 16) - | ((UINT32)(laneAsBytes[3]) << 24); - high = laneAsBytes[4] - | ((UINT32)(laneAsBytes[5]) << 8) - | ((UINT32)(laneAsBytes[6]) << 16) - | ((UINT32)(laneAsBytes[7]) << 24); -#endif - toBitInterleavingAndAND(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_Initialize(void *state) -{ - memset(state, 0, 200); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset) -{ - unsigned int lanePosition = offset/8; - unsigned int offsetInLane = offset%8; - UINT32 low, high; - UINT32 temp, temp0, temp1; - UINT32 *stateAsHalfLanes = (UINT32*)state; - - if (offsetInLane < 4) { - low = (UINT32)byte << (offsetInLane*8); - high = 0; - } - else { - low = 0; - high = (UINT32)byte << ((offsetInLane-4)*8); - } - toBitInterleavingAndXOR(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_AddBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) -{ - UINT8 laneAsBytes[8]; - UINT32 low, high; - UINT32 temp, temp0, temp1; - UINT32 *stateAsHalfLanes = (UINT32*)state; - - memset(laneAsBytes, 0, 8); - memcpy(laneAsBytes+offset, data, length); -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - low = *((UINT32*)(laneAsBytes+0)); - high = *((UINT32*)(laneAsBytes+4)); -#else - low = laneAsBytes[0] - | ((UINT32)(laneAsBytes[1]) << 8) - | ((UINT32)(laneAsBytes[2]) << 16) - | ((UINT32)(laneAsBytes[3]) << 24); - high = laneAsBytes[4] - | ((UINT32)(laneAsBytes[5]) << 8) - | ((UINT32)(laneAsBytes[6]) << 16) - | ((UINT32)(laneAsBytes[7]) << 24); -#endif - toBitInterleavingAndXOR(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_AddLanes(void *state, const unsigned char *data, unsigned int laneCount) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - const UINT32 * pI = (const UINT32 *)data; - UINT32 * pS = (UINT32*)state; - UINT32 t, x0, x1; - int i; - for (i = laneCount-1; i >= 0; --i) { -#ifdef NO_MISALIGNED_ACCESSES - UINT32 low; - UINT32 high; - memcpy(&low, pI++, 4); - memcpy(&high, pI++, 4); - toBitInterleavingAndXOR(low, high, *(pS++), *(pS++), t, x0, x1); -#else - toBitInterleavingAndXOR(*(pI++), *(pI++), *(pS++), *(pS++), t, x0, x1) -#endif - } -#else - unsigned int lanePosition; - for(lanePosition=0; lanePosition= 0; --i) { -#ifdef NO_MISALIGNED_ACCESSES - UINT32 low; - UINT32 high; - memcpy(&low, pI++, 4); - memcpy(&high, pI++, 4); - toBitInterleavingAndSet(low, high, *(pS++), *(pS++), t, x0, x1); -#else - toBitInterleavingAndSet(*(pI++), *(pI++), *(pS++), *(pS++), t, x0, x1) -#endif - } -#else - unsigned int lanePosition; - for(lanePosition=0; lanePosition> 8) & 0xFF; - laneAsBytes[2] = (low >> 16) & 0xFF; - laneAsBytes[3] = (low >> 24) & 0xFF; - laneAsBytes[4] = high & 0xFF; - laneAsBytes[5] = (high >> 8) & 0xFF; - laneAsBytes[6] = (high >> 16) & 0xFF; - laneAsBytes[7] = (high >> 24) & 0xFF; -#endif - memcpy(data, laneAsBytes+offset, length); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractLanes(const void *state, unsigned char *data, unsigned int laneCount) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - UINT32 * pI = (UINT32 *)data; - const UINT32 * pS = ( const UINT32 *)state; - UINT32 t, x0, x1; - int i; - for (i = laneCount-1; i >= 0; --i) { -#ifdef NO_MISALIGNED_ACCESSES - UINT32 low; - UINT32 high; - fromBitInterleaving(*(pS++), *(pS++), low, high, t, x0, x1); - memcpy(pI++, &low, 4); - memcpy(pI++, &high, 4); -#else - fromBitInterleaving(*(pS++), *(pS++), *(pI++), *(pI++), t, x0, x1) -#endif - } -#else - unsigned int lanePosition; - for(lanePosition=0; lanePosition> 8) & 0xFF; - laneAsBytes[2] = (low >> 16) & 0xFF; - laneAsBytes[3] = (low >> 24) & 0xFF; - laneAsBytes[4] = high & 0xFF; - laneAsBytes[5] = (high >> 8) & 0xFF; - laneAsBytes[6] = (high >> 16) & 0xFF; - laneAsBytes[7] = (high >> 24) & 0xFF; - memcpy(data+lanePosition*8, laneAsBytes, 8); - } -#endif -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) -{ - SnP_ExtractBytes(state, data, offset, length, KeccakP1600_ExtractLanes, KeccakP1600_ExtractBytesInLane, 8); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractAndAddBytesInLane(const void *state, unsigned int lanePosition, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) -{ - UINT32 *stateAsHalfLanes = (UINT32*)state; - UINT32 low, high, temp, temp0, temp1; - UINT8 laneAsBytes[8]; - unsigned int i; - - fromBitInterleaving(stateAsHalfLanes[lanePosition*2], stateAsHalfLanes[lanePosition*2+1], low, high, temp, temp0, temp1); -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - *((UINT32*)(laneAsBytes+0)) = low; - *((UINT32*)(laneAsBytes+4)) = high; -#else - laneAsBytes[0] = low & 0xFF; - laneAsBytes[1] = (low >> 8) & 0xFF; - laneAsBytes[2] = (low >> 16) & 0xFF; - laneAsBytes[3] = (low >> 24) & 0xFF; - laneAsBytes[4] = high & 0xFF; - laneAsBytes[5] = (high >> 8) & 0xFF; - laneAsBytes[6] = (high >> 16) & 0xFF; - laneAsBytes[7] = (high >> 24) & 0xFF; -#endif - for(i=0; i= 0; --i) { -#ifdef NO_MISALIGNED_ACCESSES - UINT32 low; - UINT32 high; - fromBitInterleaving(*(pS++), *(pS++), low, high, t, x0, x1); - *(pO++) = *(pI++) ^ low; - *(pO++) = *(pI++) ^ high; -#else - fromBitInterleavingAndXOR(*(pS++), *(pS++), *(pI++), *(pI++), *(pO++), *(pO++), t, x0, x1) -#endif - } -#else - unsigned int lanePosition; - for(lanePosition=0; lanePosition> 8) & 0xFF; - laneAsBytes[2] = (low >> 16) & 0xFF; - laneAsBytes[3] = (low >> 24) & 0xFF; - laneAsBytes[4] = high & 0xFF; - laneAsBytes[5] = (high >> 8) & 0xFF; - laneAsBytes[6] = (high >> 16) & 0xFF; - laneAsBytes[7] = (high >> 24) & 0xFF; - ((UINT32*)(output+lanePosition*8))[0] = ((UINT32*)(input+lanePosition*8))[0] ^ (*(const UINT32*)(laneAsBytes+0)); - ((UINT32*)(output+lanePosition*8))[1] = ((UINT32*)(input+lanePosition*8))[0] ^ (*(const UINT32*)(laneAsBytes+4)); - } -#endif -} -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) -{ - SnP_ExtractAndAddBytes(state, input, output, offset, length, KeccakP1600_ExtractAndAddLanes, KeccakP1600_ExtractAndAddBytesInLane, 8); -} - -/* ---------------------------------------------------------------- */ - -static const UINT32 KeccakF1600RoundConstants_int2[2*24+1] = -{ - 0x00000001UL, 0x00000000UL, - 0x00000000UL, 0x00000089UL, - 0x00000000UL, 0x8000008bUL, - 0x00000000UL, 0x80008080UL, - 0x00000001UL, 0x0000008bUL, - 0x00000001UL, 0x00008000UL, - 0x00000001UL, 0x80008088UL, - 0x00000001UL, 0x80000082UL, - 0x00000000UL, 0x0000000bUL, - 0x00000000UL, 0x0000000aUL, - 0x00000001UL, 0x00008082UL, - 0x00000000UL, 0x00008003UL, - 0x00000001UL, 0x0000808bUL, - 0x00000001UL, 0x8000000bUL, - 0x00000001UL, 0x8000008aUL, - 0x00000001UL, 0x80000081UL, - 0x00000000UL, 0x80000081UL, - 0x00000000UL, 0x80000008UL, - 0x00000000UL, 0x00000083UL, - 0x00000000UL, 0x80008003UL, - 0x00000001UL, 0x80008088UL, - 0x00000000UL, 0x80000088UL, - 0x00000001UL, 0x00008000UL, - 0x00000000UL, 0x80008082UL, - 0x000000FFUL -}; - -#define KeccakAtoD_round0() \ - Cx = Abu0^Agu0^Aku0^Amu0^Asu0; \ - Du1 = Abe1^Age1^Ake1^Ame1^Ase1; \ - Da0 = Cx^ROL32(Du1, 1); \ - Cz = Abu1^Agu1^Aku1^Amu1^Asu1; \ - Du0 = Abe0^Age0^Ake0^Ame0^Ase0; \ - Da1 = Cz^Du0; \ -\ - Cw = Abi0^Agi0^Aki0^Ami0^Asi0; \ - Do0 = Cw^ROL32(Cz, 1); \ - Cy = Abi1^Agi1^Aki1^Ami1^Asi1; \ - Do1 = Cy^Cx; \ -\ - Cx = Aba0^Aga0^Aka0^Ama0^Asa0; \ - De0 = Cx^ROL32(Cy, 1); \ - Cz = Aba1^Aga1^Aka1^Ama1^Asa1; \ - De1 = Cz^Cw; \ -\ - Cy = Abo1^Ago1^Ako1^Amo1^Aso1; \ - Di0 = Du0^ROL32(Cy, 1); \ - Cw = Abo0^Ago0^Ako0^Amo0^Aso0; \ - Di1 = Du1^Cw; \ -\ - Du0 = Cw^ROL32(Cz, 1); \ - Du1 = Cy^Cx; \ - -#define KeccakAtoD_round1() \ - Cx = Asu0^Agu0^Amu0^Abu1^Aku1; \ - Du1 = Age1^Ame0^Abe0^Ake1^Ase1; \ - Da0 = Cx^ROL32(Du1, 1); \ - Cz = Asu1^Agu1^Amu1^Abu0^Aku0; \ - Du0 = Age0^Ame1^Abe1^Ake0^Ase0; \ - Da1 = Cz^Du0; \ -\ - Cw = Aki1^Asi1^Agi0^Ami1^Abi0; \ - Do0 = Cw^ROL32(Cz, 1); \ - Cy = Aki0^Asi0^Agi1^Ami0^Abi1; \ - Do1 = Cy^Cx; \ -\ - Cx = Aba0^Aka1^Asa0^Aga0^Ama1; \ - De0 = Cx^ROL32(Cy, 1); \ - Cz = Aba1^Aka0^Asa1^Aga1^Ama0; \ - De1 = Cz^Cw; \ -\ - Cy = Amo0^Abo1^Ako0^Aso1^Ago0; \ - Di0 = Du0^ROL32(Cy, 1); \ - Cw = Amo1^Abo0^Ako1^Aso0^Ago1; \ - Di1 = Du1^Cw; \ -\ - Du0 = Cw^ROL32(Cz, 1); \ - Du1 = Cy^Cx; \ - -#define KeccakAtoD_round2() \ - Cx = Aku1^Agu0^Abu1^Asu1^Amu1; \ - Du1 = Ame0^Ake0^Age0^Abe0^Ase1; \ - Da0 = Cx^ROL32(Du1, 1); \ - Cz = Aku0^Agu1^Abu0^Asu0^Amu0; \ - Du0 = Ame1^Ake1^Age1^Abe1^Ase0; \ - Da1 = Cz^Du0; \ -\ - Cw = Agi1^Abi1^Asi1^Ami0^Aki1; \ - Do0 = Cw^ROL32(Cz, 1); \ - Cy = Agi0^Abi0^Asi0^Ami1^Aki0; \ - Do1 = Cy^Cx; \ -\ - Cx = Aba0^Asa1^Ama1^Aka1^Aga1; \ - De0 = Cx^ROL32(Cy, 1); \ - Cz = Aba1^Asa0^Ama0^Aka0^Aga0; \ - De1 = Cz^Cw; \ -\ - Cy = Aso0^Amo0^Ako1^Ago0^Abo0; \ - Di0 = Du0^ROL32(Cy, 1); \ - Cw = Aso1^Amo1^Ako0^Ago1^Abo1; \ - Di1 = Du1^Cw; \ -\ - Du0 = Cw^ROL32(Cz, 1); \ - Du1 = Cy^Cx; \ - -#define KeccakAtoD_round3() \ - Cx = Amu1^Agu0^Asu1^Aku0^Abu0; \ - Du1 = Ake0^Abe1^Ame1^Age0^Ase1; \ - Da0 = Cx^ROL32(Du1, 1); \ - Cz = Amu0^Agu1^Asu0^Aku1^Abu1; \ - Du0 = Ake1^Abe0^Ame0^Age1^Ase0; \ - Da1 = Cz^Du0; \ -\ - Cw = Asi0^Aki0^Abi1^Ami1^Agi1; \ - Do0 = Cw^ROL32(Cz, 1); \ - Cy = Asi1^Aki1^Abi0^Ami0^Agi0; \ - Do1 = Cy^Cx; \ -\ - Cx = Aba0^Ama0^Aga1^Asa1^Aka0; \ - De0 = Cx^ROL32(Cy, 1); \ - Cz = Aba1^Ama1^Aga0^Asa0^Aka1; \ - De1 = Cz^Cw; \ -\ - Cy = Ago1^Aso0^Ako0^Abo0^Amo1; \ - Di0 = Du0^ROL32(Cy, 1); \ - Cw = Ago0^Aso1^Ako1^Abo1^Amo0; \ - Di1 = Du1^Cw; \ -\ - Du0 = Cw^ROL32(Cz, 1); \ - Du1 = Cy^Cx; \ - -void KeccakP1600_Permute_Nrounds(void *state, unsigned int nRounds) -{ - { - UINT32 Da0, De0, Di0, Do0, Du0; - UINT32 Da1, De1, Di1, Do1, Du1; - UINT32 Ca0, Ce0, Ci0, Co0, Cu0; - UINT32 Cx, Cy, Cz, Cw; - #define Ba Ca0 - #define Be Ce0 - #define Bi Ci0 - #define Bo Co0 - #define Bu Cu0 - const UINT32 *pRoundConstants = KeccakF1600RoundConstants_int2+(24-nRounds)*2; - UINT32 *stateAsHalfLanes = (UINT32*)state; - #define Aba0 stateAsHalfLanes[ 0] - #define Aba1 stateAsHalfLanes[ 1] - #define Abe0 stateAsHalfLanes[ 2] - #define Abe1 stateAsHalfLanes[ 3] - #define Abi0 stateAsHalfLanes[ 4] - #define Abi1 stateAsHalfLanes[ 5] - #define Abo0 stateAsHalfLanes[ 6] - #define Abo1 stateAsHalfLanes[ 7] - #define Abu0 stateAsHalfLanes[ 8] - #define Abu1 stateAsHalfLanes[ 9] - #define Aga0 stateAsHalfLanes[10] - #define Aga1 stateAsHalfLanes[11] - #define Age0 stateAsHalfLanes[12] - #define Age1 stateAsHalfLanes[13] - #define Agi0 stateAsHalfLanes[14] - #define Agi1 stateAsHalfLanes[15] - #define Ago0 stateAsHalfLanes[16] - #define Ago1 stateAsHalfLanes[17] - #define Agu0 stateAsHalfLanes[18] - #define Agu1 stateAsHalfLanes[19] - #define Aka0 stateAsHalfLanes[20] - #define Aka1 stateAsHalfLanes[21] - #define Ake0 stateAsHalfLanes[22] - #define Ake1 stateAsHalfLanes[23] - #define Aki0 stateAsHalfLanes[24] - #define Aki1 stateAsHalfLanes[25] - #define Ako0 stateAsHalfLanes[26] - #define Ako1 stateAsHalfLanes[27] - #define Aku0 stateAsHalfLanes[28] - #define Aku1 stateAsHalfLanes[29] - #define Ama0 stateAsHalfLanes[30] - #define Ama1 stateAsHalfLanes[31] - #define Ame0 stateAsHalfLanes[32] - #define Ame1 stateAsHalfLanes[33] - #define Ami0 stateAsHalfLanes[34] - #define Ami1 stateAsHalfLanes[35] - #define Amo0 stateAsHalfLanes[36] - #define Amo1 stateAsHalfLanes[37] - #define Amu0 stateAsHalfLanes[38] - #define Amu1 stateAsHalfLanes[39] - #define Asa0 stateAsHalfLanes[40] - #define Asa1 stateAsHalfLanes[41] - #define Ase0 stateAsHalfLanes[42] - #define Ase1 stateAsHalfLanes[43] - #define Asi0 stateAsHalfLanes[44] - #define Asi1 stateAsHalfLanes[45] - #define Aso0 stateAsHalfLanes[46] - #define Aso1 stateAsHalfLanes[47] - #define Asu0 stateAsHalfLanes[48] - #define Asu1 stateAsHalfLanes[49] - - do - { - /* --- Code for 4 rounds */ - - /* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ - - KeccakAtoD_round0(); - - Ba = (Aba0^Da0); - Be = ROL32((Age0^De0), 22); - Bi = ROL32((Aki1^Di1), 22); - Bo = ROL32((Amo1^Do1), 11); - Bu = ROL32((Asu0^Du0), 7); - Aba0 = Ba ^((~Be)& Bi ); - Aba0 ^= *(pRoundConstants++); - Age0 = Be ^((~Bi)& Bo ); - Aki1 = Bi ^((~Bo)& Bu ); - Amo1 = Bo ^((~Bu)& Ba ); - Asu0 = Bu ^((~Ba)& Be ); - - Ba = (Aba1^Da1); - Be = ROL32((Age1^De1), 22); - Bi = ROL32((Aki0^Di0), 21); - Bo = ROL32((Amo0^Do0), 10); - Bu = ROL32((Asu1^Du1), 7); - Aba1 = Ba ^((~Be)& Bi ); - Aba1 ^= *(pRoundConstants++); - Age1 = Be ^((~Bi)& Bo ); - Aki0 = Bi ^((~Bo)& Bu ); - Amo0 = Bo ^((~Bu)& Ba ); - Asu1 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Aka1^Da1), 2); - Bo = ROL32((Ame1^De1), 23); - Bu = ROL32((Asi1^Di1), 31); - Ba = ROL32((Abo0^Do0), 14); - Be = ROL32((Agu0^Du0), 10); - Aka1 = Ba ^((~Be)& Bi ); - Ame1 = Be ^((~Bi)& Bo ); - Asi1 = Bi ^((~Bo)& Bu ); - Abo0 = Bo ^((~Bu)& Ba ); - Agu0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Aka0^Da0), 1); - Bo = ROL32((Ame0^De0), 22); - Bu = ROL32((Asi0^Di0), 30); - Ba = ROL32((Abo1^Do1), 14); - Be = ROL32((Agu1^Du1), 10); - Aka0 = Ba ^((~Be)& Bi ); - Ame0 = Be ^((~Bi)& Bo ); - Asi0 = Bi ^((~Bo)& Bu ); - Abo1 = Bo ^((~Bu)& Ba ); - Agu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Asa0^Da0), 9); - Ba = ROL32((Abe1^De1), 1); - Be = ROL32((Agi0^Di0), 3); - Bi = ROL32((Ako1^Do1), 13); - Bo = ROL32((Amu0^Du0), 4); - Asa0 = Ba ^((~Be)& Bi ); - Abe1 = Be ^((~Bi)& Bo ); - Agi0 = Bi ^((~Bo)& Bu ); - Ako1 = Bo ^((~Bu)& Ba ); - Amu0 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Asa1^Da1), 9); - Ba = (Abe0^De0); - Be = ROL32((Agi1^Di1), 3); - Bi = ROL32((Ako0^Do0), 12); - Bo = ROL32((Amu1^Du1), 4); - Asa1 = Ba ^((~Be)& Bi ); - Abe0 = Be ^((~Bi)& Bo ); - Agi1 = Bi ^((~Bo)& Bu ); - Ako0 = Bo ^((~Bu)& Ba ); - Amu1 = Bu ^((~Ba)& Be ); - - Be = ROL32((Aga0^Da0), 18); - Bi = ROL32((Ake0^De0), 5); - Bo = ROL32((Ami1^Di1), 8); - Bu = ROL32((Aso0^Do0), 28); - Ba = ROL32((Abu1^Du1), 14); - Aga0 = Ba ^((~Be)& Bi ); - Ake0 = Be ^((~Bi)& Bo ); - Ami1 = Bi ^((~Bo)& Bu ); - Aso0 = Bo ^((~Bu)& Ba ); - Abu1 = Bu ^((~Ba)& Be ); - - Be = ROL32((Aga1^Da1), 18); - Bi = ROL32((Ake1^De1), 5); - Bo = ROL32((Ami0^Di0), 7); - Bu = ROL32((Aso1^Do1), 28); - Ba = ROL32((Abu0^Du0), 13); - Aga1 = Ba ^((~Be)& Bi ); - Ake1 = Be ^((~Bi)& Bo ); - Ami0 = Bi ^((~Bo)& Bu ); - Aso1 = Bo ^((~Bu)& Ba ); - Abu0 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Ama1^Da1), 21); - Bu = ROL32((Ase0^De0), 1); - Ba = ROL32((Abi0^Di0), 31); - Be = ROL32((Ago1^Do1), 28); - Bi = ROL32((Aku1^Du1), 20); - Ama1 = Ba ^((~Be)& Bi ); - Ase0 = Be ^((~Bi)& Bo ); - Abi0 = Bi ^((~Bo)& Bu ); - Ago1 = Bo ^((~Bu)& Ba ); - Aku1 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Ama0^Da0), 20); - Bu = ROL32((Ase1^De1), 1); - Ba = ROL32((Abi1^Di1), 31); - Be = ROL32((Ago0^Do0), 27); - Bi = ROL32((Aku0^Du0), 19); - Ama0 = Ba ^((~Be)& Bi ); - Ase1 = Be ^((~Bi)& Bo ); - Abi1 = Bi ^((~Bo)& Bu ); - Ago0 = Bo ^((~Bu)& Ba ); - Aku0 = Bu ^((~Ba)& Be ); - - KeccakAtoD_round1(); - - Ba = (Aba0^Da0); - Be = ROL32((Ame1^De0), 22); - Bi = ROL32((Agi1^Di1), 22); - Bo = ROL32((Aso1^Do1), 11); - Bu = ROL32((Aku1^Du0), 7); - Aba0 = Ba ^((~Be)& Bi ); - Aba0 ^= *(pRoundConstants++); - Ame1 = Be ^((~Bi)& Bo ); - Agi1 = Bi ^((~Bo)& Bu ); - Aso1 = Bo ^((~Bu)& Ba ); - Aku1 = Bu ^((~Ba)& Be ); - - Ba = (Aba1^Da1); - Be = ROL32((Ame0^De1), 22); - Bi = ROL32((Agi0^Di0), 21); - Bo = ROL32((Aso0^Do0), 10); - Bu = ROL32((Aku0^Du1), 7); - Aba1 = Ba ^((~Be)& Bi ); - Aba1 ^= *(pRoundConstants++); - Ame0 = Be ^((~Bi)& Bo ); - Agi0 = Bi ^((~Bo)& Bu ); - Aso0 = Bo ^((~Bu)& Ba ); - Aku0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Asa1^Da1), 2); - Bo = ROL32((Ake1^De1), 23); - Bu = ROL32((Abi1^Di1), 31); - Ba = ROL32((Amo1^Do0), 14); - Be = ROL32((Agu0^Du0), 10); - Asa1 = Ba ^((~Be)& Bi ); - Ake1 = Be ^((~Bi)& Bo ); - Abi1 = Bi ^((~Bo)& Bu ); - Amo1 = Bo ^((~Bu)& Ba ); - Agu0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Asa0^Da0), 1); - Bo = ROL32((Ake0^De0), 22); - Bu = ROL32((Abi0^Di0), 30); - Ba = ROL32((Amo0^Do1), 14); - Be = ROL32((Agu1^Du1), 10); - Asa0 = Ba ^((~Be)& Bi ); - Ake0 = Be ^((~Bi)& Bo ); - Abi0 = Bi ^((~Bo)& Bu ); - Amo0 = Bo ^((~Bu)& Ba ); - Agu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Ama1^Da0), 9); - Ba = ROL32((Age1^De1), 1); - Be = ROL32((Asi1^Di0), 3); - Bi = ROL32((Ako0^Do1), 13); - Bo = ROL32((Abu1^Du0), 4); - Ama1 = Ba ^((~Be)& Bi ); - Age1 = Be ^((~Bi)& Bo ); - Asi1 = Bi ^((~Bo)& Bu ); - Ako0 = Bo ^((~Bu)& Ba ); - Abu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Ama0^Da1), 9); - Ba = (Age0^De0); - Be = ROL32((Asi0^Di1), 3); - Bi = ROL32((Ako1^Do0), 12); - Bo = ROL32((Abu0^Du1), 4); - Ama0 = Ba ^((~Be)& Bi ); - Age0 = Be ^((~Bi)& Bo ); - Asi0 = Bi ^((~Bo)& Bu ); - Ako1 = Bo ^((~Bu)& Ba ); - Abu0 = Bu ^((~Ba)& Be ); - - Be = ROL32((Aka1^Da0), 18); - Bi = ROL32((Abe1^De0), 5); - Bo = ROL32((Ami0^Di1), 8); - Bu = ROL32((Ago1^Do0), 28); - Ba = ROL32((Asu1^Du1), 14); - Aka1 = Ba ^((~Be)& Bi ); - Abe1 = Be ^((~Bi)& Bo ); - Ami0 = Bi ^((~Bo)& Bu ); - Ago1 = Bo ^((~Bu)& Ba ); - Asu1 = Bu ^((~Ba)& Be ); - - Be = ROL32((Aka0^Da1), 18); - Bi = ROL32((Abe0^De1), 5); - Bo = ROL32((Ami1^Di0), 7); - Bu = ROL32((Ago0^Do1), 28); - Ba = ROL32((Asu0^Du0), 13); - Aka0 = Ba ^((~Be)& Bi ); - Abe0 = Be ^((~Bi)& Bo ); - Ami1 = Bi ^((~Bo)& Bu ); - Ago0 = Bo ^((~Bu)& Ba ); - Asu0 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Aga1^Da1), 21); - Bu = ROL32((Ase0^De0), 1); - Ba = ROL32((Aki1^Di0), 31); - Be = ROL32((Abo1^Do1), 28); - Bi = ROL32((Amu1^Du1), 20); - Aga1 = Ba ^((~Be)& Bi ); - Ase0 = Be ^((~Bi)& Bo ); - Aki1 = Bi ^((~Bo)& Bu ); - Abo1 = Bo ^((~Bu)& Ba ); - Amu1 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Aga0^Da0), 20); - Bu = ROL32((Ase1^De1), 1); - Ba = ROL32((Aki0^Di1), 31); - Be = ROL32((Abo0^Do0), 27); - Bi = ROL32((Amu0^Du0), 19); - Aga0 = Ba ^((~Be)& Bi ); - Ase1 = Be ^((~Bi)& Bo ); - Aki0 = Bi ^((~Bo)& Bu ); - Abo0 = Bo ^((~Bu)& Ba ); - Amu0 = Bu ^((~Ba)& Be ); - - KeccakAtoD_round2(); - - Ba = (Aba0^Da0); - Be = ROL32((Ake1^De0), 22); - Bi = ROL32((Asi0^Di1), 22); - Bo = ROL32((Ago0^Do1), 11); - Bu = ROL32((Amu1^Du0), 7); - Aba0 = Ba ^((~Be)& Bi ); - Aba0 ^= *(pRoundConstants++); - Ake1 = Be ^((~Bi)& Bo ); - Asi0 = Bi ^((~Bo)& Bu ); - Ago0 = Bo ^((~Bu)& Ba ); - Amu1 = Bu ^((~Ba)& Be ); - - Ba = (Aba1^Da1); - Be = ROL32((Ake0^De1), 22); - Bi = ROL32((Asi1^Di0), 21); - Bo = ROL32((Ago1^Do0), 10); - Bu = ROL32((Amu0^Du1), 7); - Aba1 = Ba ^((~Be)& Bi ); - Aba1 ^= *(pRoundConstants++); - Ake0 = Be ^((~Bi)& Bo ); - Asi1 = Bi ^((~Bo)& Bu ); - Ago1 = Bo ^((~Bu)& Ba ); - Amu0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Ama0^Da1), 2); - Bo = ROL32((Abe0^De1), 23); - Bu = ROL32((Aki0^Di1), 31); - Ba = ROL32((Aso1^Do0), 14); - Be = ROL32((Agu0^Du0), 10); - Ama0 = Ba ^((~Be)& Bi ); - Abe0 = Be ^((~Bi)& Bo ); - Aki0 = Bi ^((~Bo)& Bu ); - Aso1 = Bo ^((~Bu)& Ba ); - Agu0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Ama1^Da0), 1); - Bo = ROL32((Abe1^De0), 22); - Bu = ROL32((Aki1^Di0), 30); - Ba = ROL32((Aso0^Do1), 14); - Be = ROL32((Agu1^Du1), 10); - Ama1 = Ba ^((~Be)& Bi ); - Abe1 = Be ^((~Bi)& Bo ); - Aki1 = Bi ^((~Bo)& Bu ); - Aso0 = Bo ^((~Bu)& Ba ); - Agu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Aga1^Da0), 9); - Ba = ROL32((Ame0^De1), 1); - Be = ROL32((Abi1^Di0), 3); - Bi = ROL32((Ako1^Do1), 13); - Bo = ROL32((Asu1^Du0), 4); - Aga1 = Ba ^((~Be)& Bi ); - Ame0 = Be ^((~Bi)& Bo ); - Abi1 = Bi ^((~Bo)& Bu ); - Ako1 = Bo ^((~Bu)& Ba ); - Asu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Aga0^Da1), 9); - Ba = (Ame1^De0); - Be = ROL32((Abi0^Di1), 3); - Bi = ROL32((Ako0^Do0), 12); - Bo = ROL32((Asu0^Du1), 4); - Aga0 = Ba ^((~Be)& Bi ); - Ame1 = Be ^((~Bi)& Bo ); - Abi0 = Bi ^((~Bo)& Bu ); - Ako0 = Bo ^((~Bu)& Ba ); - Asu0 = Bu ^((~Ba)& Be ); - - Be = ROL32((Asa1^Da0), 18); - Bi = ROL32((Age1^De0), 5); - Bo = ROL32((Ami1^Di1), 8); - Bu = ROL32((Abo1^Do0), 28); - Ba = ROL32((Aku0^Du1), 14); - Asa1 = Ba ^((~Be)& Bi ); - Age1 = Be ^((~Bi)& Bo ); - Ami1 = Bi ^((~Bo)& Bu ); - Abo1 = Bo ^((~Bu)& Ba ); - Aku0 = Bu ^((~Ba)& Be ); - - Be = ROL32((Asa0^Da1), 18); - Bi = ROL32((Age0^De1), 5); - Bo = ROL32((Ami0^Di0), 7); - Bu = ROL32((Abo0^Do1), 28); - Ba = ROL32((Aku1^Du0), 13); - Asa0 = Ba ^((~Be)& Bi ); - Age0 = Be ^((~Bi)& Bo ); - Ami0 = Bi ^((~Bo)& Bu ); - Abo0 = Bo ^((~Bu)& Ba ); - Aku1 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Aka0^Da1), 21); - Bu = ROL32((Ase0^De0), 1); - Ba = ROL32((Agi1^Di0), 31); - Be = ROL32((Amo0^Do1), 28); - Bi = ROL32((Abu0^Du1), 20); - Aka0 = Ba ^((~Be)& Bi ); - Ase0 = Be ^((~Bi)& Bo ); - Agi1 = Bi ^((~Bo)& Bu ); - Amo0 = Bo ^((~Bu)& Ba ); - Abu0 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Aka1^Da0), 20); - Bu = ROL32((Ase1^De1), 1); - Ba = ROL32((Agi0^Di1), 31); - Be = ROL32((Amo1^Do0), 27); - Bi = ROL32((Abu1^Du0), 19); - Aka1 = Ba ^((~Be)& Bi ); - Ase1 = Be ^((~Bi)& Bo ); - Agi0 = Bi ^((~Bo)& Bu ); - Amo1 = Bo ^((~Bu)& Ba ); - Abu1 = Bu ^((~Ba)& Be ); - - KeccakAtoD_round3(); - - Ba = (Aba0^Da0); - Be = ROL32((Abe0^De0), 22); - Bi = ROL32((Abi0^Di1), 22); - Bo = ROL32((Abo0^Do1), 11); - Bu = ROL32((Abu0^Du0), 7); - Aba0 = Ba ^((~Be)& Bi ); - Aba0 ^= *(pRoundConstants++); - Abe0 = Be ^((~Bi)& Bo ); - Abi0 = Bi ^((~Bo)& Bu ); - Abo0 = Bo ^((~Bu)& Ba ); - Abu0 = Bu ^((~Ba)& Be ); - - Ba = (Aba1^Da1); - Be = ROL32((Abe1^De1), 22); - Bi = ROL32((Abi1^Di0), 21); - Bo = ROL32((Abo1^Do0), 10); - Bu = ROL32((Abu1^Du1), 7); - Aba1 = Ba ^((~Be)& Bi ); - Aba1 ^= *(pRoundConstants++); - Abe1 = Be ^((~Bi)& Bo ); - Abi1 = Bi ^((~Bo)& Bu ); - Abo1 = Bo ^((~Bu)& Ba ); - Abu1 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Aga0^Da1), 2); - Bo = ROL32((Age0^De1), 23); - Bu = ROL32((Agi0^Di1), 31); - Ba = ROL32((Ago0^Do0), 14); - Be = ROL32((Agu0^Du0), 10); - Aga0 = Ba ^((~Be)& Bi ); - Age0 = Be ^((~Bi)& Bo ); - Agi0 = Bi ^((~Bo)& Bu ); - Ago0 = Bo ^((~Bu)& Ba ); - Agu0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Aga1^Da0), 1); - Bo = ROL32((Age1^De0), 22); - Bu = ROL32((Agi1^Di0), 30); - Ba = ROL32((Ago1^Do1), 14); - Be = ROL32((Agu1^Du1), 10); - Aga1 = Ba ^((~Be)& Bi ); - Age1 = Be ^((~Bi)& Bo ); - Agi1 = Bi ^((~Bo)& Bu ); - Ago1 = Bo ^((~Bu)& Ba ); - Agu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Aka0^Da0), 9); - Ba = ROL32((Ake0^De1), 1); - Be = ROL32((Aki0^Di0), 3); - Bi = ROL32((Ako0^Do1), 13); - Bo = ROL32((Aku0^Du0), 4); - Aka0 = Ba ^((~Be)& Bi ); - Ake0 = Be ^((~Bi)& Bo ); - Aki0 = Bi ^((~Bo)& Bu ); - Ako0 = Bo ^((~Bu)& Ba ); - Aku0 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Aka1^Da1), 9); - Ba = (Ake1^De0); - Be = ROL32((Aki1^Di1), 3); - Bi = ROL32((Ako1^Do0), 12); - Bo = ROL32((Aku1^Du1), 4); - Aka1 = Ba ^((~Be)& Bi ); - Ake1 = Be ^((~Bi)& Bo ); - Aki1 = Bi ^((~Bo)& Bu ); - Ako1 = Bo ^((~Bu)& Ba ); - Aku1 = Bu ^((~Ba)& Be ); - - Be = ROL32((Ama0^Da0), 18); - Bi = ROL32((Ame0^De0), 5); - Bo = ROL32((Ami0^Di1), 8); - Bu = ROL32((Amo0^Do0), 28); - Ba = ROL32((Amu0^Du1), 14); - Ama0 = Ba ^((~Be)& Bi ); - Ame0 = Be ^((~Bi)& Bo ); - Ami0 = Bi ^((~Bo)& Bu ); - Amo0 = Bo ^((~Bu)& Ba ); - Amu0 = Bu ^((~Ba)& Be ); - - Be = ROL32((Ama1^Da1), 18); - Bi = ROL32((Ame1^De1), 5); - Bo = ROL32((Ami1^Di0), 7); - Bu = ROL32((Amo1^Do1), 28); - Ba = ROL32((Amu1^Du0), 13); - Ama1 = Ba ^((~Be)& Bi ); - Ame1 = Be ^((~Bi)& Bo ); - Ami1 = Bi ^((~Bo)& Bu ); - Amo1 = Bo ^((~Bu)& Ba ); - Amu1 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Asa0^Da1), 21); - Bu = ROL32((Ase0^De0), 1); - Ba = ROL32((Asi0^Di0), 31); - Be = ROL32((Aso0^Do1), 28); - Bi = ROL32((Asu0^Du1), 20); - Asa0 = Ba ^((~Be)& Bi ); - Ase0 = Be ^((~Bi)& Bo ); - Asi0 = Bi ^((~Bo)& Bu ); - Aso0 = Bo ^((~Bu)& Ba ); - Asu0 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Asa1^Da0), 20); - Bu = ROL32((Ase1^De1), 1); - Ba = ROL32((Asi1^Di1), 31); - Be = ROL32((Aso1^Do0), 27); - Bi = ROL32((Asu1^Du0), 19); - Asa1 = Ba ^((~Be)& Bi ); - Ase1 = Be ^((~Bi)& Bo ); - Asi1 = Bi ^((~Bo)& Bu ); - Aso1 = Bo ^((~Bu)& Ba ); - Asu1 = Bu ^((~Ba)& Be ); - } - while ( *pRoundConstants != 0xFF ); - - #undef Aba0 - #undef Aba1 - #undef Abe0 - #undef Abe1 - #undef Abi0 - #undef Abi1 - #undef Abo0 - #undef Abo1 - #undef Abu0 - #undef Abu1 - #undef Aga0 - #undef Aga1 - #undef Age0 - #undef Age1 - #undef Agi0 - #undef Agi1 - #undef Ago0 - #undef Ago1 - #undef Agu0 - #undef Agu1 - #undef Aka0 - #undef Aka1 - #undef Ake0 - #undef Ake1 - #undef Aki0 - #undef Aki1 - #undef Ako0 - #undef Ako1 - #undef Aku0 - #undef Aku1 - #undef Ama0 - #undef Ama1 - #undef Ame0 - #undef Ame1 - #undef Ami0 - #undef Ami1 - #undef Amo0 - #undef Amo1 - #undef Amu0 - #undef Amu1 - #undef Asa0 - #undef Asa1 - #undef Ase0 - #undef Ase1 - #undef Asi0 - #undef Asi1 - #undef Aso0 - #undef Aso1 - #undef Asu0 - #undef Asu1 - } -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_Permute_12rounds(void *state) -{ - KeccakP1600_Permute_Nrounds(state, 12); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_Permute_24rounds(void *state) -{ - KeccakP1600_Permute_Nrounds(state, 24); -} diff --git a/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h b/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h deleted file mode 100644 index 9501c64b186..00000000000 --- a/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h +++ /dev/null @@ -1,3 +0,0 @@ -#define KeccakP1600_implementation_config "lane complementing, all rounds unrolled" -#define KeccakP1600_fullUnrolling -#define KeccakP1600_useLaneComplementing diff --git a/Modules/_sha3/kcp/KeccakP-1600-opt64.c b/Modules/_sha3/kcp/KeccakP-1600-opt64.c deleted file mode 100644 index c90010dd925..00000000000 --- a/Modules/_sha3/kcp/KeccakP-1600-opt64.c +++ /dev/null @@ -1,474 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#include -#include -/* #include "brg_endian.h" */ -#include "KeccakP-1600-opt64-config.h" - -#if NOT_PYTHON -typedef unsigned char UINT8; -/* typedef unsigned long long int UINT64; */ -#endif - -#if defined(KeccakP1600_useLaneComplementing) -#define UseBebigokimisa -#endif - -#if defined(_MSC_VER) -#define ROL64(a, offset) _rotl64(a, offset) -#elif defined(KeccakP1600_useSHLD) - #define ROL64(x,N) ({ \ - register UINT64 __out; \ - register UINT64 __in = x; \ - __asm__ ("shld %2,%0,%0" : "=r"(__out) : "0"(__in), "i"(N)); \ - __out; \ - }) -#else -#define ROL64(a, offset) ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) -#endif - -#include "KeccakP-1600-64.macros" -#ifdef KeccakP1600_fullUnrolling -#define FullUnrolling -#else -#define Unrolling KeccakP1600_unrolling -#endif -#include "KeccakP-1600-unrolling.macros" -#include "SnP-Relaned.h" - -static const UINT64 KeccakF1600RoundConstants[24] = { - 0x0000000000000001ULL, - 0x0000000000008082ULL, - 0x800000000000808aULL, - 0x8000000080008000ULL, - 0x000000000000808bULL, - 0x0000000080000001ULL, - 0x8000000080008081ULL, - 0x8000000000008009ULL, - 0x000000000000008aULL, - 0x0000000000000088ULL, - 0x0000000080008009ULL, - 0x000000008000000aULL, - 0x000000008000808bULL, - 0x800000000000008bULL, - 0x8000000000008089ULL, - 0x8000000000008003ULL, - 0x8000000000008002ULL, - 0x8000000000000080ULL, - 0x000000000000800aULL, - 0x800000008000000aULL, - 0x8000000080008081ULL, - 0x8000000000008080ULL, - 0x0000000080000001ULL, - 0x8000000080008008ULL }; - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_Initialize(void *state) -{ - memset(state, 0, 200); -#ifdef KeccakP1600_useLaneComplementing - ((UINT64*)state)[ 1] = ~(UINT64)0; - ((UINT64*)state)[ 2] = ~(UINT64)0; - ((UINT64*)state)[ 8] = ~(UINT64)0; - ((UINT64*)state)[12] = ~(UINT64)0; - ((UINT64*)state)[17] = ~(UINT64)0; - ((UINT64*)state)[20] = ~(UINT64)0; -#endif -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_AddBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - UINT64 lane; - if (length == 0) - return; - if (length == 1) - lane = data[0]; - else { - lane = 0; - memcpy(&lane, data, length); - } - lane <<= offset*8; -#else - UINT64 lane = 0; - unsigned int i; - for(i=0; i>= offset*8; - for(i=0; i>= 8; - } -#endif -} - -/* ---------------------------------------------------------------- */ - -#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) -void fromWordToBytes(UINT8 *bytes, const UINT64 word) -{ - unsigned int i; - - for(i=0; i<(64/8); i++) - bytes[i] = (word >> (8*i)) & 0xFF; -} -#endif - -void KeccakP1600_ExtractLanes(const void *state, unsigned char *data, unsigned int laneCount) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - memcpy(data, state, laneCount*8); -#else - unsigned int i; - - for(i=0; i 1) { - ((UINT64*)data)[ 1] = ~((UINT64*)data)[ 1]; - if (laneCount > 2) { - ((UINT64*)data)[ 2] = ~((UINT64*)data)[ 2]; - if (laneCount > 8) { - ((UINT64*)data)[ 8] = ~((UINT64*)data)[ 8]; - if (laneCount > 12) { - ((UINT64*)data)[12] = ~((UINT64*)data)[12]; - if (laneCount > 17) { - ((UINT64*)data)[17] = ~((UINT64*)data)[17]; - if (laneCount > 20) { - ((UINT64*)data)[20] = ~((UINT64*)data)[20]; - } - } - } - } - } - } -#endif -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) -{ - SnP_ExtractBytes(state, data, offset, length, KeccakP1600_ExtractLanes, KeccakP1600_ExtractBytesInLane, 8); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractAndAddBytesInLane(const void *state, unsigned int lanePosition, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) -{ - UINT64 lane = ((UINT64*)state)[lanePosition]; -#ifdef KeccakP1600_useLaneComplementing - if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) - lane = ~lane; -#endif -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - { - unsigned int i; - UINT64 lane1[1]; - lane1[0] = lane; - for(i=0; i>= offset*8; - for(i=0; i>= 8; - } -#endif -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractAndAddLanes(const void *state, const unsigned char *input, unsigned char *output, unsigned int laneCount) -{ - unsigned int i; -#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) - unsigned char temp[8]; - unsigned int j; -#endif - - for(i=0; i 1) { - ((UINT64*)output)[ 1] = ~((UINT64*)output)[ 1]; - if (laneCount > 2) { - ((UINT64*)output)[ 2] = ~((UINT64*)output)[ 2]; - if (laneCount > 8) { - ((UINT64*)output)[ 8] = ~((UINT64*)output)[ 8]; - if (laneCount > 12) { - ((UINT64*)output)[12] = ~((UINT64*)output)[12]; - if (laneCount > 17) { - ((UINT64*)output)[17] = ~((UINT64*)output)[17]; - if (laneCount > 20) { - ((UINT64*)output)[20] = ~((UINT64*)output)[20]; - } - } - } - } - } - } -#endif -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) -{ - SnP_ExtractAndAddBytes(state, input, output, offset, length, KeccakP1600_ExtractAndAddLanes, KeccakP1600_ExtractAndAddBytesInLane, 8); -} - -/* ---------------------------------------------------------------- */ - -size_t KeccakF1600_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen) -{ - size_t originalDataByteLen = dataByteLen; - declareABCDE - #ifndef KeccakP1600_fullUnrolling - unsigned int i; - #endif - UINT64 *stateAsLanes = (UINT64*)state; - UINT64 *inDataAsLanes = (UINT64*)data; - - copyFromState(A, stateAsLanes) - while(dataByteLen >= laneCount*8) { - addInput(A, inDataAsLanes, laneCount) - rounds24 - inDataAsLanes += laneCount; - dataByteLen -= laneCount*8; - } - copyToState(stateAsLanes, A) - return originalDataByteLen - dataByteLen; -} diff --git a/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros b/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros deleted file mode 100644 index 405ce29724c..00000000000 --- a/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros +++ /dev/null @@ -1,185 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#if (defined(FullUnrolling)) -#define rounds24 \ - prepareTheta \ - thetaRhoPiChiIotaPrepareTheta( 0, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 1, E, A) \ - thetaRhoPiChiIotaPrepareTheta( 2, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 3, E, A) \ - thetaRhoPiChiIotaPrepareTheta( 4, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 5, E, A) \ - thetaRhoPiChiIotaPrepareTheta( 6, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 7, E, A) \ - thetaRhoPiChiIotaPrepareTheta( 8, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 9, E, A) \ - thetaRhoPiChiIotaPrepareTheta(10, A, E) \ - thetaRhoPiChiIotaPrepareTheta(11, E, A) \ - thetaRhoPiChiIotaPrepareTheta(12, A, E) \ - thetaRhoPiChiIotaPrepareTheta(13, E, A) \ - thetaRhoPiChiIotaPrepareTheta(14, A, E) \ - thetaRhoPiChiIotaPrepareTheta(15, E, A) \ - thetaRhoPiChiIotaPrepareTheta(16, A, E) \ - thetaRhoPiChiIotaPrepareTheta(17, E, A) \ - thetaRhoPiChiIotaPrepareTheta(18, A, E) \ - thetaRhoPiChiIotaPrepareTheta(19, E, A) \ - thetaRhoPiChiIotaPrepareTheta(20, A, E) \ - thetaRhoPiChiIotaPrepareTheta(21, E, A) \ - thetaRhoPiChiIotaPrepareTheta(22, A, E) \ - thetaRhoPiChiIota(23, E, A) \ - -#define rounds12 \ - prepareTheta \ - thetaRhoPiChiIotaPrepareTheta(12, A, E) \ - thetaRhoPiChiIotaPrepareTheta(13, E, A) \ - thetaRhoPiChiIotaPrepareTheta(14, A, E) \ - thetaRhoPiChiIotaPrepareTheta(15, E, A) \ - thetaRhoPiChiIotaPrepareTheta(16, A, E) \ - thetaRhoPiChiIotaPrepareTheta(17, E, A) \ - thetaRhoPiChiIotaPrepareTheta(18, A, E) \ - thetaRhoPiChiIotaPrepareTheta(19, E, A) \ - thetaRhoPiChiIotaPrepareTheta(20, A, E) \ - thetaRhoPiChiIotaPrepareTheta(21, E, A) \ - thetaRhoPiChiIotaPrepareTheta(22, A, E) \ - thetaRhoPiChiIota(23, E, A) \ - -#elif (Unrolling == 12) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i+=12) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+ 2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 3, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+ 4, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 5, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+ 6, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 7, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+ 8, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 9, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+10, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+11, E, A) \ - } \ - -#define rounds12 \ - prepareTheta \ - thetaRhoPiChiIotaPrepareTheta(12, A, E) \ - thetaRhoPiChiIotaPrepareTheta(13, E, A) \ - thetaRhoPiChiIotaPrepareTheta(14, A, E) \ - thetaRhoPiChiIotaPrepareTheta(15, E, A) \ - thetaRhoPiChiIotaPrepareTheta(16, A, E) \ - thetaRhoPiChiIotaPrepareTheta(17, E, A) \ - thetaRhoPiChiIotaPrepareTheta(18, A, E) \ - thetaRhoPiChiIotaPrepareTheta(19, E, A) \ - thetaRhoPiChiIotaPrepareTheta(20, A, E) \ - thetaRhoPiChiIotaPrepareTheta(21, E, A) \ - thetaRhoPiChiIotaPrepareTheta(22, A, E) \ - thetaRhoPiChiIota(23, E, A) \ - -#elif (Unrolling == 6) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i+=6) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \ - } \ - -#define rounds12 \ - prepareTheta \ - for(i=12; i<24; i+=6) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \ - } \ - -#elif (Unrolling == 4) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i+=4) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ - } \ - -#define rounds12 \ - prepareTheta \ - for(i=12; i<24; i+=4) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ - } \ - -#elif (Unrolling == 3) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i+=3) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - copyStateVariables(A, E) \ - } \ - -#define rounds12 \ - prepareTheta \ - for(i=12; i<24; i+=3) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - copyStateVariables(A, E) \ - } \ - -#elif (Unrolling == 2) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i+=2) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - } \ - -#define rounds12 \ - prepareTheta \ - for(i=12; i<24; i+=2) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - } \ - -#elif (Unrolling == 1) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i++) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - copyStateVariables(A, E) \ - } \ - -#define rounds12 \ - prepareTheta \ - for(i=12; i<24; i++) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - copyStateVariables(A, E) \ - } \ - -#else -#error "Unrolling is not correctly specified!" -#endif diff --git a/Modules/_sha3/kcp/KeccakSponge.c b/Modules/_sha3/kcp/KeccakSponge.c deleted file mode 100644 index afdb73172f3..00000000000 --- a/Modules/_sha3/kcp/KeccakSponge.c +++ /dev/null @@ -1,92 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#include "KeccakSponge.h" - -#ifdef KeccakReference - #include "displayIntermediateValues.h" -#endif - -#ifndef KeccakP200_excluded - #include "KeccakP-200-SnP.h" - - #define prefix KeccakWidth200 - #define SnP KeccakP200 - #define SnP_width 200 - #define SnP_Permute KeccakP200_Permute_18rounds - #if defined(KeccakF200_FastLoop_supported) - #define SnP_FastLoop_Absorb KeccakF200_FastLoop_Absorb - #endif - #include "KeccakSponge.inc" - #undef prefix - #undef SnP - #undef SnP_width - #undef SnP_Permute - #undef SnP_FastLoop_Absorb -#endif - -#ifndef KeccakP400_excluded - #include "KeccakP-400-SnP.h" - - #define prefix KeccakWidth400 - #define SnP KeccakP400 - #define SnP_width 400 - #define SnP_Permute KeccakP400_Permute_20rounds - #if defined(KeccakF400_FastLoop_supported) - #define SnP_FastLoop_Absorb KeccakF400_FastLoop_Absorb - #endif - #include "KeccakSponge.inc" - #undef prefix - #undef SnP - #undef SnP_width - #undef SnP_Permute - #undef SnP_FastLoop_Absorb -#endif - -#ifndef KeccakP800_excluded - #include "KeccakP-800-SnP.h" - - #define prefix KeccakWidth800 - #define SnP KeccakP800 - #define SnP_width 800 - #define SnP_Permute KeccakP800_Permute_22rounds - #if defined(KeccakF800_FastLoop_supported) - #define SnP_FastLoop_Absorb KeccakF800_FastLoop_Absorb - #endif - #include "KeccakSponge.inc" - #undef prefix - #undef SnP - #undef SnP_width - #undef SnP_Permute - #undef SnP_FastLoop_Absorb -#endif - -#ifndef KeccakP1600_excluded - #include "KeccakP-1600-SnP.h" - - #define prefix KeccakWidth1600 - #define SnP KeccakP1600 - #define SnP_width 1600 - #define SnP_Permute KeccakP1600_Permute_24rounds - #if defined(KeccakF1600_FastLoop_supported) - #define SnP_FastLoop_Absorb KeccakF1600_FastLoop_Absorb - #endif - #include "KeccakSponge.inc" - #undef prefix - #undef SnP - #undef SnP_width - #undef SnP_Permute - #undef SnP_FastLoop_Absorb -#endif diff --git a/Modules/_sha3/kcp/KeccakSponge.h b/Modules/_sha3/kcp/KeccakSponge.h deleted file mode 100644 index 0f4badcac05..00000000000 --- a/Modules/_sha3/kcp/KeccakSponge.h +++ /dev/null @@ -1,172 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _KeccakSponge_h_ -#define _KeccakSponge_h_ - -/** General information - * - * The following type and functions are not actually implemented. Their - * documentation is generic, with the prefix Prefix replaced by - * - KeccakWidth200 for a sponge function based on Keccak-f[200] - * - KeccakWidth400 for a sponge function based on Keccak-f[400] - * - KeccakWidth800 for a sponge function based on Keccak-f[800] - * - KeccakWidth1600 for a sponge function based on Keccak-f[1600] - * - * In all these functions, the rate and capacity must sum to the width of the - * chosen permutation. For instance, to use the sponge function - * Keccak[r=1344, c=256], one must use KeccakWidth1600_Sponge() or a combination - * of KeccakWidth1600_SpongeInitialize(), KeccakWidth1600_SpongeAbsorb(), - * KeccakWidth1600_SpongeAbsorbLastFewBits() and - * KeccakWidth1600_SpongeSqueeze(). - * - * The Prefix_SpongeInstance contains the sponge instance attributes for use - * with the Prefix_Sponge* functions. - * It gathers the state processed by the permutation as well as the rate, - * the position of input/output bytes in the state and the phase - * (absorbing or squeezing). - */ - -#ifdef DontReallyInclude_DocumentationOnly -/** Function to evaluate the sponge function Keccak[r, c] in a single call. - * @param rate The value of the rate r. - * @param capacity The value of the capacity c. - * @param input Pointer to the input message (before the suffix). - * @param inputByteLen The length of the input message in bytes. - * @param suffix Byte containing from 0 to 7 suffix bits - * that must be absorbed after @a input. - * These n bits must be in the least significant bit positions. - * These bits must be delimited with a bit 1 at position n - * (counting from 0=LSB to 7=MSB) and followed by bits 0 - * from position n+1 to position 7. - * Some examples: - * - If no bits are to be absorbed, then @a suffix must be 0x01. - * - If the 2-bit sequence 0,0 is to be absorbed, @a suffix must be 0x04. - * - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a suffix must be 0x32. - * - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a suffix must be 0x8B. - * . - * @param output Pointer to the output buffer. - * @param outputByteLen The desired number of output bytes. - * @pre One must have r+c equal to the supported width of this implementation - * and the rate a multiple of 8 bits (one byte) in this implementation. - * @pre @a suffix ≠ 0x00 - * @return Zero if successful, 1 otherwise. - */ -int Prefix_Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen); - -/** - * Function to initialize the state of the Keccak[r, c] sponge function. - * The phase of the sponge function is set to absorbing. - * @param spongeInstance Pointer to the sponge instance to be initialized. - * @param rate The value of the rate r. - * @param capacity The value of the capacity c. - * @pre One must have r+c equal to the supported width of this implementation - * and the rate a multiple of 8 bits (one byte) in this implementation. - * @return Zero if successful, 1 otherwise. - */ -int Prefix_SpongeInitialize(Prefix_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity); - -/** - * Function to give input data bytes for the sponge function to absorb. - * @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize(). - * @param data Pointer to the input data. - * @param dataByteLen The number of input bytes provided in the input data. - * @pre The sponge function must be in the absorbing phase, - * i.e., Prefix_SpongeSqueeze() or Prefix_SpongeAbsorbLastFewBits() - * must not have been called before. - * @return Zero if successful, 1 otherwise. - */ -int Prefix_SpongeAbsorb(Prefix_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen); - -/** - * Function to give input data bits for the sponge function to absorb - * and then to switch to the squeezing phase. - * @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize(). - * @param delimitedData Byte containing from 0 to 7 trailing bits - * that must be absorbed. - * These n bits must be in the least significant bit positions. - * These bits must be delimited with a bit 1 at position n - * (counting from 0=LSB to 7=MSB) and followed by bits 0 - * from position n+1 to position 7. - * Some examples: - * - If no bits are to be absorbed, then @a delimitedData must be 0x01. - * - If the 2-bit sequence 0,0 is to be absorbed, @a delimitedData must be 0x04. - * - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a delimitedData must be 0x32. - * - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a delimitedData must be 0x8B. - * . - * @pre The sponge function must be in the absorbing phase, - * i.e., Prefix_SpongeSqueeze() or Prefix_SpongeAbsorbLastFewBits() - * must not have been called before. - * @pre @a delimitedData ≠ 0x00 - * @return Zero if successful, 1 otherwise. - */ -int Prefix_SpongeAbsorbLastFewBits(Prefix_SpongeInstance *spongeInstance, unsigned char delimitedData); - -/** - * Function to squeeze output data from the sponge function. - * If the sponge function was in the absorbing phase, this function - * switches it to the squeezing phase - * as if Prefix_SpongeAbsorbLastFewBits(spongeInstance, 0x01) was called. - * @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize(). - * @param data Pointer to the buffer where to store the output data. - * @param dataByteLen The number of output bytes desired. - * @return Zero if successful, 1 otherwise. - */ -int Prefix_SpongeSqueeze(Prefix_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen); -#endif - -#include -#include "align.h" - -#define KCP_DeclareSpongeStructure(prefix, size, alignment) \ - ALIGN(alignment) typedef struct prefix##_SpongeInstanceStruct { \ - unsigned char state[size]; \ - unsigned int rate; \ - unsigned int byteIOIndex; \ - int squeezing; \ - } prefix##_SpongeInstance; - -#define KCP_DeclareSpongeFunctions(prefix) \ - int prefix##_Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen); \ - int prefix##_SpongeInitialize(prefix##_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity); \ - int prefix##_SpongeAbsorb(prefix##_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen); \ - int prefix##_SpongeAbsorbLastFewBits(prefix##_SpongeInstance *spongeInstance, unsigned char delimitedData); \ - int prefix##_SpongeSqueeze(prefix##_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen); - -#ifndef KeccakP200_excluded - #include "KeccakP-200-SnP.h" - KCP_DeclareSpongeStructure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment) - KCP_DeclareSpongeFunctions(KeccakWidth200) -#endif - -#ifndef KeccakP400_excluded - #include "KeccakP-400-SnP.h" - KCP_DeclareSpongeStructure(KeccakWidth400, KeccakP400_stateSizeInBytes, KeccakP400_stateAlignment) - KCP_DeclareSpongeFunctions(KeccakWidth400) -#endif - -#ifndef KeccakP800_excluded - #include "KeccakP-800-SnP.h" - KCP_DeclareSpongeStructure(KeccakWidth800, KeccakP800_stateSizeInBytes, KeccakP800_stateAlignment) - KCP_DeclareSpongeFunctions(KeccakWidth800) -#endif - -#ifndef KeccakP1600_excluded - #include "KeccakP-1600-SnP.h" - KCP_DeclareSpongeStructure(KeccakWidth1600, KeccakP1600_stateSizeInBytes, KeccakP1600_stateAlignment) - KCP_DeclareSpongeFunctions(KeccakWidth1600) -#endif - -#endif diff --git a/Modules/_sha3/kcp/KeccakSponge.inc b/Modules/_sha3/kcp/KeccakSponge.inc deleted file mode 100644 index e10739deafa..00000000000 --- a/Modules/_sha3/kcp/KeccakSponge.inc +++ /dev/null @@ -1,332 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#define JOIN0(a, b) a ## b -#define JOIN(a, b) JOIN0(a, b) - -#define Sponge JOIN(prefix, _Sponge) -#define SpongeInstance JOIN(prefix, _SpongeInstance) -#define SpongeInitialize JOIN(prefix, _SpongeInitialize) -#define SpongeAbsorb JOIN(prefix, _SpongeAbsorb) -#define SpongeAbsorbLastFewBits JOIN(prefix, _SpongeAbsorbLastFewBits) -#define SpongeSqueeze JOIN(prefix, _SpongeSqueeze) - -#define SnP_stateSizeInBytes JOIN(SnP, _stateSizeInBytes) -#define SnP_stateAlignment JOIN(SnP, _stateAlignment) -#define SnP_StaticInitialize JOIN(SnP, _StaticInitialize) -#define SnP_Initialize JOIN(SnP, _Initialize) -#define SnP_AddByte JOIN(SnP, _AddByte) -#define SnP_AddBytes JOIN(SnP, _AddBytes) -#define SnP_ExtractBytes JOIN(SnP, _ExtractBytes) - -int Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen) -{ - ALIGN(SnP_stateAlignment) unsigned char state[SnP_stateSizeInBytes]; - unsigned int partialBlock; - const unsigned char *curInput = input; - unsigned char *curOutput = output; - unsigned int rateInBytes = rate/8; - - if (rate+capacity != SnP_width) - return 1; - if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0)) - return 1; - if (suffix == 0) - return 1; - - /* Initialize the state */ - - SnP_StaticInitialize(); - SnP_Initialize(state); - - /* First, absorb whole blocks */ - -#ifdef SnP_FastLoop_Absorb - if (((rateInBytes % (SnP_width/200)) == 0) && (inputByteLen >= rateInBytes)) { - /* fast lane: whole lane rate */ - - size_t j; - j = SnP_FastLoop_Absorb(state, rateInBytes/(SnP_width/200), curInput, inputByteLen); - curInput += j; - inputByteLen -= j; - } -#endif - while(inputByteLen >= (size_t)rateInBytes) { - #ifdef KeccakReference - displayBytes(1, "Block to be absorbed", curInput, rateInBytes); - #endif - SnP_AddBytes(state, curInput, 0, rateInBytes); - SnP_Permute(state); - curInput += rateInBytes; - inputByteLen -= rateInBytes; - } - - /* Then, absorb what remains */ - - partialBlock = (unsigned int)inputByteLen; - #ifdef KeccakReference - displayBytes(1, "Block to be absorbed (part)", curInput, partialBlock); - #endif - SnP_AddBytes(state, curInput, 0, partialBlock); - - /* Finally, absorb the suffix */ - - #ifdef KeccakReference - { - unsigned char delimitedData1[1]; - delimitedData1[0] = suffix; - displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1); - } - #endif - /* Last few bits, whose delimiter coincides with first bit of padding */ - - SnP_AddByte(state, suffix, partialBlock); - /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */ - - if ((suffix >= 0x80) && (partialBlock == (rateInBytes-1))) - SnP_Permute(state); - /* Second bit of padding */ - - SnP_AddByte(state, 0x80, rateInBytes-1); - #ifdef KeccakReference - { - unsigned char block[SnP_width/8]; - memset(block, 0, SnP_width/8); - block[rateInBytes-1] = 0x80; - displayBytes(1, "Second bit of padding", block, rateInBytes); - } - #endif - SnP_Permute(state); - #ifdef KeccakReference - displayText(1, "--- Switching to squeezing phase ---"); - #endif - - /* First, output whole blocks */ - - while(outputByteLen > (size_t)rateInBytes) { - SnP_ExtractBytes(state, curOutput, 0, rateInBytes); - SnP_Permute(state); - #ifdef KeccakReference - displayBytes(1, "Squeezed block", curOutput, rateInBytes); - #endif - curOutput += rateInBytes; - outputByteLen -= rateInBytes; - } - - /* Finally, output what remains */ - - partialBlock = (unsigned int)outputByteLen; - SnP_ExtractBytes(state, curOutput, 0, partialBlock); - #ifdef KeccakReference - displayBytes(1, "Squeezed block (part)", curOutput, partialBlock); - #endif - - return 0; -} - -/* ---------------------------------------------------------------- */ -/* ---------------------------------------------------------------- */ -/* ---------------------------------------------------------------- */ - -int SpongeInitialize(SpongeInstance *instance, unsigned int rate, unsigned int capacity) -{ - if (rate+capacity != SnP_width) - return 1; - if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0)) - return 1; - SnP_StaticInitialize(); - SnP_Initialize(instance->state); - instance->rate = rate; - instance->byteIOIndex = 0; - instance->squeezing = 0; - - return 0; -} - -/* ---------------------------------------------------------------- */ - -int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dataByteLen) -{ - size_t i, j; - unsigned int partialBlock; - const unsigned char *curData; - unsigned int rateInBytes = instance->rate/8; - - if (instance->squeezing) - return 1; /* Too late for additional input */ - - - i = 0; - curData = data; - while(i < dataByteLen) { - if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) { -#ifdef SnP_FastLoop_Absorb - /* processing full blocks first */ - - if ((rateInBytes % (SnP_width/200)) == 0) { - /* fast lane: whole lane rate */ - - j = SnP_FastLoop_Absorb(instance->state, rateInBytes/(SnP_width/200), curData, dataByteLen - i); - i += j; - curData += j; - } - else { -#endif - for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { - #ifdef KeccakReference - displayBytes(1, "Block to be absorbed", curData, rateInBytes); - #endif - SnP_AddBytes(instance->state, curData, 0, rateInBytes); - SnP_Permute(instance->state); - curData+=rateInBytes; - } - i = dataByteLen - j; -#ifdef SnP_FastLoop_Absorb - } -#endif - } - else { - /* normal lane: using the message queue */ - - partialBlock = (unsigned int)(dataByteLen - i); - if (partialBlock+instance->byteIOIndex > rateInBytes) - partialBlock = rateInBytes-instance->byteIOIndex; - #ifdef KeccakReference - displayBytes(1, "Block to be absorbed (part)", curData, partialBlock); - #endif - i += partialBlock; - - SnP_AddBytes(instance->state, curData, instance->byteIOIndex, partialBlock); - curData += partialBlock; - instance->byteIOIndex += partialBlock; - if (instance->byteIOIndex == rateInBytes) { - SnP_Permute(instance->state); - instance->byteIOIndex = 0; - } - } - } - return 0; -} - -/* ---------------------------------------------------------------- */ - -int SpongeAbsorbLastFewBits(SpongeInstance *instance, unsigned char delimitedData) -{ - unsigned int rateInBytes = instance->rate/8; - - if (delimitedData == 0) - return 1; - if (instance->squeezing) - return 1; /* Too late for additional input */ - - - #ifdef KeccakReference - { - unsigned char delimitedData1[1]; - delimitedData1[0] = delimitedData; - displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1); - } - #endif - /* Last few bits, whose delimiter coincides with first bit of padding */ - - SnP_AddByte(instance->state, delimitedData, instance->byteIOIndex); - /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */ - - if ((delimitedData >= 0x80) && (instance->byteIOIndex == (rateInBytes-1))) - SnP_Permute(instance->state); - /* Second bit of padding */ - - SnP_AddByte(instance->state, 0x80, rateInBytes-1); - #ifdef KeccakReference - { - unsigned char block[SnP_width/8]; - memset(block, 0, SnP_width/8); - block[rateInBytes-1] = 0x80; - displayBytes(1, "Second bit of padding", block, rateInBytes); - } - #endif - SnP_Permute(instance->state); - instance->byteIOIndex = 0; - instance->squeezing = 1; - #ifdef KeccakReference - displayText(1, "--- Switching to squeezing phase ---"); - #endif - return 0; -} - -/* ---------------------------------------------------------------- */ - -int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByteLen) -{ - size_t i, j; - unsigned int partialBlock; - unsigned int rateInBytes = instance->rate/8; - unsigned char *curData; - - if (!instance->squeezing) - SpongeAbsorbLastFewBits(instance, 0x01); - - i = 0; - curData = data; - while(i < dataByteLen) { - if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) { - for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { - SnP_Permute(instance->state); - SnP_ExtractBytes(instance->state, curData, 0, rateInBytes); - #ifdef KeccakReference - displayBytes(1, "Squeezed block", curData, rateInBytes); - #endif - curData+=rateInBytes; - } - i = dataByteLen - j; - } - else { - /* normal lane: using the message queue */ - - if (instance->byteIOIndex == rateInBytes) { - SnP_Permute(instance->state); - instance->byteIOIndex = 0; - } - partialBlock = (unsigned int)(dataByteLen - i); - if (partialBlock+instance->byteIOIndex > rateInBytes) - partialBlock = rateInBytes-instance->byteIOIndex; - i += partialBlock; - - SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock); - #ifdef KeccakReference - displayBytes(1, "Squeezed block (part)", curData, partialBlock); - #endif - curData += partialBlock; - instance->byteIOIndex += partialBlock; - } - } - return 0; -} - -/* ---------------------------------------------------------------- */ - -#undef Sponge -#undef SpongeInstance -#undef SpongeInitialize -#undef SpongeAbsorb -#undef SpongeAbsorbLastFewBits -#undef SpongeSqueeze -#undef SnP_stateSizeInBytes -#undef SnP_stateAlignment -#undef SnP_StaticInitialize -#undef SnP_Initialize -#undef SnP_AddByte -#undef SnP_AddBytes -#undef SnP_ExtractBytes diff --git a/Modules/_sha3/kcp/PlSnP-Fallback.inc b/Modules/_sha3/kcp/PlSnP-Fallback.inc deleted file mode 100644 index 3a9119ab4b6..00000000000 --- a/Modules/_sha3/kcp/PlSnP-Fallback.inc +++ /dev/null @@ -1,257 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -/* expect PlSnP_baseParallelism, PlSnP_targetParallelism */ - -/* expect SnP_stateSizeInBytes, SnP_stateAlignment */ - -/* expect prefix */ - -/* expect SnP_* */ - - -#define JOIN0(a, b) a ## b -#define JOIN(a, b) JOIN0(a, b) - -#define PlSnP_StaticInitialize JOIN(prefix, _StaticInitialize) -#define PlSnP_InitializeAll JOIN(prefix, _InitializeAll) -#define PlSnP_AddByte JOIN(prefix, _AddByte) -#define PlSnP_AddBytes JOIN(prefix, _AddBytes) -#define PlSnP_AddLanesAll JOIN(prefix, _AddLanesAll) -#define PlSnP_OverwriteBytes JOIN(prefix, _OverwriteBytes) -#define PlSnP_OverwriteLanesAll JOIN(prefix, _OverwriteLanesAll) -#define PlSnP_OverwriteWithZeroes JOIN(prefix, _OverwriteWithZeroes) -#define PlSnP_ExtractBytes JOIN(prefix, _ExtractBytes) -#define PlSnP_ExtractLanesAll JOIN(prefix, _ExtractLanesAll) -#define PlSnP_ExtractAndAddBytes JOIN(prefix, _ExtractAndAddBytes) -#define PlSnP_ExtractAndAddLanesAll JOIN(prefix, _ExtractAndAddLanesAll) - -#if (PlSnP_baseParallelism == 1) - #define SnP_stateSizeInBytes JOIN(SnP, _stateSizeInBytes) - #define SnP_stateAlignment JOIN(SnP, _stateAlignment) -#else - #define SnP_stateSizeInBytes JOIN(SnP, _statesSizeInBytes) - #define SnP_stateAlignment JOIN(SnP, _statesAlignment) -#endif -#define PlSnP_factor ((PlSnP_targetParallelism)/(PlSnP_baseParallelism)) -#define SnP_stateOffset (((SnP_stateSizeInBytes+(SnP_stateAlignment-1))/SnP_stateAlignment)*SnP_stateAlignment) -#define stateWithIndex(i) ((unsigned char *)states+((i)*SnP_stateOffset)) - -#define SnP_StaticInitialize JOIN(SnP, _StaticInitialize) -#define SnP_Initialize JOIN(SnP, _Initialize) -#define SnP_InitializeAll JOIN(SnP, _InitializeAll) -#define SnP_AddByte JOIN(SnP, _AddByte) -#define SnP_AddBytes JOIN(SnP, _AddBytes) -#define SnP_AddLanesAll JOIN(SnP, _AddLanesAll) -#define SnP_OverwriteBytes JOIN(SnP, _OverwriteBytes) -#define SnP_OverwriteLanesAll JOIN(SnP, _OverwriteLanesAll) -#define SnP_OverwriteWithZeroes JOIN(SnP, _OverwriteWithZeroes) -#define SnP_ExtractBytes JOIN(SnP, _ExtractBytes) -#define SnP_ExtractLanesAll JOIN(SnP, _ExtractLanesAll) -#define SnP_ExtractAndAddBytes JOIN(SnP, _ExtractAndAddBytes) -#define SnP_ExtractAndAddLanesAll JOIN(SnP, _ExtractAndAddLanesAll) - -void PlSnP_StaticInitialize( void ) -{ - SnP_StaticInitialize(); -} - -void PlSnP_InitializeAll(void *states) -{ - unsigned int i; - - for(i=0; i 0) { \ - unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ - if (_bytesInLane > _sizeLeft) \ - _bytesInLane = _sizeLeft; \ - SnP_AddBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ - _sizeLeft -= _bytesInLane; \ - _lanePosition++; \ - _offsetInLane = 0; \ - _curData += _bytesInLane; \ - } \ - } \ - } - -#define SnP_OverwriteBytes(state, data, offset, length, SnP_OverwriteLanes, SnP_OverwriteBytesInLane, SnP_laneLengthInBytes) \ - { \ - if ((offset) == 0) { \ - SnP_OverwriteLanes(state, data, (length)/SnP_laneLengthInBytes); \ - SnP_OverwriteBytesInLane(state, \ - (length)/SnP_laneLengthInBytes, \ - (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ - 0, \ - (length)%SnP_laneLengthInBytes); \ - } \ - else { \ - unsigned int _sizeLeft = (length); \ - unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ - unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ - const unsigned char *_curData = (data); \ - while(_sizeLeft > 0) { \ - unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ - if (_bytesInLane > _sizeLeft) \ - _bytesInLane = _sizeLeft; \ - SnP_OverwriteBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ - _sizeLeft -= _bytesInLane; \ - _lanePosition++; \ - _offsetInLane = 0; \ - _curData += _bytesInLane; \ - } \ - } \ - } - -#define SnP_ExtractBytes(state, data, offset, length, SnP_ExtractLanes, SnP_ExtractBytesInLane, SnP_laneLengthInBytes) \ - { \ - if ((offset) == 0) { \ - SnP_ExtractLanes(state, data, (length)/SnP_laneLengthInBytes); \ - SnP_ExtractBytesInLane(state, \ - (length)/SnP_laneLengthInBytes, \ - (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ - 0, \ - (length)%SnP_laneLengthInBytes); \ - } \ - else { \ - unsigned int _sizeLeft = (length); \ - unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ - unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ - unsigned char *_curData = (data); \ - while(_sizeLeft > 0) { \ - unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ - if (_bytesInLane > _sizeLeft) \ - _bytesInLane = _sizeLeft; \ - SnP_ExtractBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ - _sizeLeft -= _bytesInLane; \ - _lanePosition++; \ - _offsetInLane = 0; \ - _curData += _bytesInLane; \ - } \ - } \ - } - -#define SnP_ExtractAndAddBytes(state, input, output, offset, length, SnP_ExtractAndAddLanes, SnP_ExtractAndAddBytesInLane, SnP_laneLengthInBytes) \ - { \ - if ((offset) == 0) { \ - SnP_ExtractAndAddLanes(state, input, output, (length)/SnP_laneLengthInBytes); \ - SnP_ExtractAndAddBytesInLane(state, \ - (length)/SnP_laneLengthInBytes, \ - (input)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ - (output)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ - 0, \ - (length)%SnP_laneLengthInBytes); \ - } \ - else { \ - unsigned int _sizeLeft = (length); \ - unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ - unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ - const unsigned char *_curInput = (input); \ - unsigned char *_curOutput = (output); \ - while(_sizeLeft > 0) { \ - unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ - if (_bytesInLane > _sizeLeft) \ - _bytesInLane = _sizeLeft; \ - SnP_ExtractAndAddBytesInLane(state, _lanePosition, _curInput, _curOutput, _offsetInLane, _bytesInLane); \ - _sizeLeft -= _bytesInLane; \ - _lanePosition++; \ - _offsetInLane = 0; \ - _curInput += _bytesInLane; \ - _curOutput += _bytesInLane; \ - } \ - } \ - } - -#endif diff --git a/Modules/_sha3/kcp/align.h b/Modules/_sha3/kcp/align.h deleted file mode 100644 index 6650fe8c3cf..00000000000 --- a/Modules/_sha3/kcp/align.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _align_h_ -#define _align_h_ - -/* on Mac OS-X and possibly others, ALIGN(x) is defined in param.h, and -Werror chokes on the redef. */ - -#ifdef ALIGN -#undef ALIGN -#endif - -#if defined(__GNUC__) -#define ALIGN(x) __attribute__ ((aligned(x))) -#elif defined(_MSC_VER) -#define ALIGN(x) __declspec(align(x)) -#elif defined(__ARMCC_VERSION) -#define ALIGN(x) __align(x) -#else -#define ALIGN(x) -#endif - -#endif diff --git a/Modules/_sha3/sha3.c b/Modules/_sha3/sha3.c new file mode 100644 index 00000000000..e2d3fd7b8ad --- /dev/null +++ b/Modules/_sha3/sha3.c @@ -0,0 +1,193 @@ +// sha3.c +// 19-Nov-11 Markku-Juhani O. Saarinen + +// Revised 07-Aug-15 to match with official release of FIPS PUB 202 "SHA3" +// Revised 03-Sep-15 for portability + OpenSSL - style API + +#include "sha3.h" + +// update the state with given number of rounds + +static void sha3_keccakf(uint64_t st[25]) +{ + // constants + const uint64_t keccakf_rndc[24] = { + 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, + 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, + 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, + 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, + 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, + 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, + 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, + 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 + }; + const int keccakf_rotc[24] = { + 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, + 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 + }; + const int keccakf_piln[24] = { + 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 + }; + + // variables + int i, j, r; + uint64_t t, bc[5]; + +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ + uint8_t *v; + + // endianess conversion. this is redundant on little-endian targets + for (i = 0; i < 25; i++) { + v = (uint8_t *) &st[i]; + st[i] = ((uint64_t) v[0]) | (((uint64_t) v[1]) << 8) | + (((uint64_t) v[2]) << 16) | (((uint64_t) v[3]) << 24) | + (((uint64_t) v[4]) << 32) | (((uint64_t) v[5]) << 40) | + (((uint64_t) v[6]) << 48) | (((uint64_t) v[7]) << 56); + } +#endif + + // actual iteration + for (r = 0; r < KECCAKF_ROUNDS; r++) { + + // Theta + for (i = 0; i < 5; i++) + bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; + + for (i = 0; i < 5; i++) { + t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); + for (j = 0; j < 25; j += 5) + st[j + i] ^= t; + } + + // Rho Pi + t = st[1]; + for (i = 0; i < 24; i++) { + j = keccakf_piln[i]; + bc[0] = st[j]; + st[j] = ROTL64(t, keccakf_rotc[i]); + t = bc[0]; + } + + // Chi + for (j = 0; j < 25; j += 5) { + for (i = 0; i < 5; i++) + bc[i] = st[j + i]; + for (i = 0; i < 5; i++) + st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; + } + + // Iota + st[0] ^= keccakf_rndc[r]; + } + +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ + // endianess conversion. this is redundant on little-endian targets + for (i = 0; i < 25; i++) { + v = (uint8_t *) &st[i]; + t = st[i]; + v[0] = t & 0xFF; + v[1] = (t >> 8) & 0xFF; + v[2] = (t >> 16) & 0xFF; + v[3] = (t >> 24) & 0xFF; + v[4] = (t >> 32) & 0xFF; + v[5] = (t >> 40) & 0xFF; + v[6] = (t >> 48) & 0xFF; + v[7] = (t >> 56) & 0xFF; + } +#endif +} + +// Initialize the context for SHA3 + +static int sha3_init(sha3_ctx_t *c, int mdlen) +{ + int i; + + for (i = 0; i < 25; i++) + c->st.q[i] = 0; + c->mdlen = mdlen; + c->rsiz = 200 - 2 * mdlen; + c->pt = 0; + + return 1; +} + +// update state with more data + +static int sha3_update(sha3_ctx_t *c, const void *data, size_t len) +{ + size_t i; + int j; + + j = c->pt; + for (i = 0; i < len; i++) { + c->st.b[j++] ^= ((const uint8_t *) data)[i]; + if (j >= c->rsiz) { + sha3_keccakf(c->st.q); + j = 0; + } + } + c->pt = j; + + return 1; +} + +// finalize and output a hash + +static int sha3_final(void *md, sha3_ctx_t *c) +{ + int i; + + c->st.b[c->pt] ^= 0x06; + c->st.b[c->rsiz - 1] ^= 0x80; + sha3_keccakf(c->st.q); + + for (i = 0; i < c->mdlen; i++) { + ((uint8_t *) md)[i] = c->st.b[i]; + } + + return 1; +} + +#if 0 +// compute a SHA-3 hash (md) of given byte length from "in" + +void *sha3(const void *in, size_t inlen, void *md, int mdlen) +{ + sha3_ctx_t sha3; + + sha3_init(&sha3, mdlen); + sha3_update(&sha3, in, inlen); + sha3_final(md, &sha3); + + return md; +} +#endif + +// SHAKE128 and SHAKE256 extensible-output functionality + +static void shake_xof(sha3_ctx_t *c) +{ + c->st.b[c->pt] ^= 0x1F; + c->st.b[c->rsiz - 1] ^= 0x80; + sha3_keccakf(c->st.q); + c->pt = 0; +} + +static void shake_out(sha3_ctx_t *c, void *out, size_t len) +{ + size_t i; + int j; + + j = c->pt; + for (i = 0; i < len; i++) { + if (j >= c->rsiz) { + sha3_keccakf(c->st.q); + j = 0; + } + ((uint8_t *) out)[i] = c->st.b[j++]; + } + c->pt = j; +} + diff --git a/Modules/_sha3/sha3.h b/Modules/_sha3/sha3.h new file mode 100644 index 00000000000..f973d6733ec --- /dev/null +++ b/Modules/_sha3/sha3.h @@ -0,0 +1,49 @@ +// sha3.h +// 19-Nov-11 Markku-Juhani O. Saarinen + +#ifndef SHA3_H +#define SHA3_H + +#include +#include + +#ifndef KECCAKF_ROUNDS +#define KECCAKF_ROUNDS 24 +#endif + +#ifndef ROTL64 +#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) +#endif + +// state context +typedef struct { + union { // state: + uint8_t b[200]; // 8-bit bytes + uint64_t q[25]; // 64-bit words + } st; + int pt, rsiz, mdlen; // these don't overflow +} sha3_ctx_t; + +// Compression function. +static void sha3_keccakf(uint64_t st[25]); + +// OpenSSL - like interfece +static int sha3_init(sha3_ctx_t *c, int mdlen); // mdlen = hash output in bytes +static int sha3_update(sha3_ctx_t *c, const void *data, size_t len); +static int sha3_final(void *md, sha3_ctx_t *c); // digest goes to md + +// compute a sha3 hash (md) of given byte length from "in" +#if 0 +static void *sha3(const void *in, size_t inlen, void *md, int mdlen); +#endif + +// SHAKE128 and SHAKE256 extensible-output functions +#define shake128_init(c) sha3_init(c, 16) +#define shake256_init(c) sha3_init(c, 32) +#define shake_update sha3_update + +static void shake_xof(sha3_ctx_t *c); +static void shake_out(sha3_ctx_t *c, void *out, size_t len); + +#endif + diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index bfa96616df0..bd1dd596bdd 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -10,7 +10,7 @@ * Trevor Perrin (trevp@trevp.net) * Gregory P. Smith (greg@krypto.org) * - * Copyright (C) 2012-2016 Christian Heimes (christian@python.org) + * Copyright (C) 2012-2022 Christian Heimes (christian@python.org) * Licensed to PSF under a Contributor Agreement. * */ @@ -23,125 +23,27 @@ #include "pycore_strhex.h" // _Py_strhex() #include "../hashlib.h" -/* ************************************************************************** - * SHA-3 (Keccak) and SHAKE - * - * The code is based on KeccakCodePackage from 2016-04-23 - * commit 647f93079afc4ada3d23737477a6e52511ca41fd - * - * The reference implementation is altered in this points: - * - C++ comments are converted to ANSI C comments. - * - all function names are mangled - * - typedef for UINT64 is commented out. - * - brg_endian.h is removed - * - * *************************************************************************/ - -#ifdef __sparc - /* opt64 uses un-aligned memory access that causes a BUS error with msg - * 'invalid address alignment' on SPARC. */ - #define KeccakOpt 32 -#elif PY_BIG_ENDIAN - /* opt64 is not yet supported on big endian platforms */ - #define KeccakOpt 32 -#elif SIZEOF_VOID_P == 8 - /* opt64 works only on little-endian 64bit platforms with unsigned int64 */ - #define KeccakOpt 64 -#else - /* opt32 is used for the remaining 32 and 64bit platforms */ - #define KeccakOpt 32 -#endif - -#if KeccakOpt == 64 - /* 64bit platforms with unsigned int64 */ - typedef uint64_t UINT64; - typedef unsigned char UINT8; -#endif - -/* replacement for brg_endian.h */ -#define IS_LITTLE_ENDIAN 1234 -#define IS_BIG_ENDIAN 4321 -#if PY_LITTLE_ENDIAN -#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif -#if PY_BIG_ENDIAN -#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#endif - -/* Prevent bus errors on platforms requiring aligned accesses such ARM. */ -#if HAVE_ALIGNED_REQUIRED && !defined(NO_MISALIGNED_ACCESSES) -#define NO_MISALIGNED_ACCESSES -#endif - -/* mangle names */ -#define KeccakF1600_FastLoop_Absorb _PySHA3_KeccakF1600_FastLoop_Absorb -#define Keccak_HashFinal _PySHA3_Keccak_HashFinal -#define Keccak_HashInitialize _PySHA3_Keccak_HashInitialize -#define Keccak_HashSqueeze _PySHA3_Keccak_HashSqueeze -#define Keccak_HashUpdate _PySHA3_Keccak_HashUpdate -#define KeccakP1600_AddBytes _PySHA3_KeccakP1600_AddBytes -#define KeccakP1600_AddBytesInLane _PySHA3_KeccakP1600_AddBytesInLane -#define KeccakP1600_AddLanes _PySHA3_KeccakP1600_AddLanes -#define KeccakP1600_ExtractAndAddBytes _PySHA3_KeccakP1600_ExtractAndAddBytes -#define KeccakP1600_ExtractAndAddBytesInLane _PySHA3_KeccakP1600_ExtractAndAddBytesInLane -#define KeccakP1600_ExtractAndAddLanes _PySHA3_KeccakP1600_ExtractAndAddLanes -#define KeccakP1600_ExtractBytes _PySHA3_KeccakP1600_ExtractBytes -#define KeccakP1600_ExtractBytesInLane _PySHA3_KeccakP1600_ExtractBytesInLane -#define KeccakP1600_ExtractLanes _PySHA3_KeccakP1600_ExtractLanes -#define KeccakP1600_Initialize _PySHA3_KeccakP1600_Initialize -#define KeccakP1600_OverwriteBytes _PySHA3_KeccakP1600_OverwriteBytes -#define KeccakP1600_OverwriteBytesInLane _PySHA3_KeccakP1600_OverwriteBytesInLane -#define KeccakP1600_OverwriteLanes _PySHA3_KeccakP1600_OverwriteLanes -#define KeccakP1600_OverwriteWithZeroes _PySHA3_KeccakP1600_OverwriteWithZeroes -#define KeccakP1600_Permute_12rounds _PySHA3_KeccakP1600_Permute_12rounds -#define KeccakP1600_Permute_24rounds _PySHA3_KeccakP1600_Permute_24rounds -#define KeccakWidth1600_Sponge _PySHA3_KeccakWidth1600_Sponge -#define KeccakWidth1600_SpongeAbsorb _PySHA3_KeccakWidth1600_SpongeAbsorb -#define KeccakWidth1600_SpongeAbsorbLastFewBits _PySHA3_KeccakWidth1600_SpongeAbsorbLastFewBits -#define KeccakWidth1600_SpongeInitialize _PySHA3_KeccakWidth1600_SpongeInitialize -#define KeccakWidth1600_SpongeSqueeze _PySHA3_KeccakWidth1600_SpongeSqueeze -#if KeccakOpt == 32 -#define KeccakP1600_AddByte _PySHA3_KeccakP1600_AddByte -#define KeccakP1600_Permute_Nrounds _PySHA3_KeccakP1600_Permute_Nrounds -#define KeccakP1600_SetBytesInLaneToZero _PySHA3_KeccakP1600_SetBytesInLaneToZero -#endif - -/* we are only interested in KeccakP1600 */ -#define KeccakP200_excluded 1 -#define KeccakP400_excluded 1 -#define KeccakP800_excluded 1 - -/* inline all Keccak dependencies */ -#include "kcp/KeccakHash.h" -#include "kcp/KeccakSponge.h" -#include "kcp/KeccakHash.c" -#include "kcp/KeccakSponge.c" -#if KeccakOpt == 64 - #include "kcp/KeccakP-1600-opt64.c" -#elif KeccakOpt == 32 - #include "kcp/KeccakP-1600-inplace32BI.c" -#endif +#include "sha3.c" #define SHA3_MAX_DIGESTSIZE 64 /* 64 Bytes (512 Bits) for 224 to 512 */ -#define SHA3_LANESIZE (20 * 8) /* ExtractLane needs max uint64_t[20] extra. */ -#define SHA3_state Keccak_HashInstance -#define SHA3_init Keccak_HashInitialize -#define SHA3_process Keccak_HashUpdate -#define SHA3_done Keccak_HashFinal -#define SHA3_squeeze Keccak_HashSqueeze +#define SHA3_LANESIZE 0 +#define SHA3_state sha3_ctx_t +#define SHA3_init sha3_init +#define SHA3_process sha3_update +#define SHA3_done(state, digest) sha3_final(digest, state) +#define SHA3_squeeze(state, out, len) shake_xof(state), shake_out(state, out, len) #define SHA3_copystate(dest, src) memcpy(&(dest), &(src), sizeof(SHA3_state)) +// no optimization +#define KeccakOpt 0 + +typedef enum { SUCCESS = 1, FAIL = 0, BAD_HASHLEN = 2 } HashReturn; + typedef struct { PyTypeObject *sha3_224_type; PyTypeObject *sha3_256_type; PyTypeObject *sha3_384_type; PyTypeObject *sha3_512_type; -#ifdef PY_WITH_KECCAK - PyTypeObject *keccak_224_type; - PyTypeObject *keccak_256_type; - PyTypeObject *keccak_384_type; - PyTypeObject *keccak_512_type; -#endif PyTypeObject *shake_128_type; PyTypeObject *shake_256_type; } SHA3State; @@ -213,27 +115,17 @@ py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity) assert(state != NULL); if (type == state->sha3_224_type) { - res = Keccak_HashInitialize_SHA3_224(&self->hash_state); + res = sha3_init(&self->hash_state, 28); } else if (type == state->sha3_256_type) { - res = Keccak_HashInitialize_SHA3_256(&self->hash_state); + res = sha3_init(&self->hash_state, 32); } else if (type == state->sha3_384_type) { - res = Keccak_HashInitialize_SHA3_384(&self->hash_state); + res = sha3_init(&self->hash_state, 48); } else if (type == state->sha3_512_type) { - res = Keccak_HashInitialize_SHA3_512(&self->hash_state); -#ifdef PY_WITH_KECCAK - } else if (type == state->keccak_224_type) { - res = Keccak_HashInitialize(&self->hash_state, 1152, 448, 224, 0x01); - } else if (type == state->keccak_256_type) { - res = Keccak_HashInitialize(&self->hash_state, 1088, 512, 256, 0x01); - } else if (type == state->keccak_384_type) { - res = Keccak_HashInitialize(&self->hash_state, 832, 768, 384, 0x01); - } else if (type == state->keccak_512_type) { - res = Keccak_HashInitialize(&self->hash_state, 576, 1024, 512, 0x01); -#endif + res = sha3_init(&self->hash_state, 64); } else if (type == state->shake_128_type) { - res = Keccak_HashInitialize_SHAKE128(&self->hash_state); + res = sha3_init(&self->hash_state, 16); } else if (type == state->shake_256_type) { - res = Keccak_HashInitialize_SHAKE256(&self->hash_state); + res = sha3_init(&self->hash_state, 32); } else { PyErr_BadInternalCall(); goto error; @@ -252,11 +144,11 @@ py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity) * thus it's safe to release the GIL without locking the object. */ Py_BEGIN_ALLOW_THREADS - res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); + res = SHA3_process(&self->hash_state, buf.buf, buf.len); Py_END_ALLOW_THREADS } else { - res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); + res = SHA3_process(&self->hash_state, buf.buf, buf.len); } if (res != SUCCESS) { PyErr_SetString(PyExc_RuntimeError, @@ -342,7 +234,7 @@ _sha3_sha3_224_digest_impl(SHA3object *self) return NULL; } return PyBytes_FromStringAndSize((const char *)digest, - self->hash_state.fixedOutputLength / 8); + self->hash_state.mdlen); } @@ -370,7 +262,7 @@ _sha3_sha3_224_hexdigest_impl(SHA3object *self) return NULL; } return _Py_strhex((const char *)digest, - self->hash_state.fixedOutputLength / 8); + self->hash_state.mdlen); } @@ -403,12 +295,12 @@ _sha3_sha3_224_update(SHA3object *self, PyObject *data) if (self->lock) { Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(self->lock, 1); - res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); + res = SHA3_process(&self->hash_state, buf.buf, buf.len); PyThread_release_lock(self->lock); Py_END_ALLOW_THREADS } else { - res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); + res = SHA3_process(&self->hash_state, buf.buf, buf.len); } if (res != SUCCESS) { @@ -435,8 +327,8 @@ static PyMethodDef SHA3_methods[] = { static PyObject * SHA3_get_block_size(SHA3object *self, void *closure) { - int rate = self->hash_state.sponge.rate; - return PyLong_FromLong(rate / 8); + int rate = self->hash_state.rsiz; + return PyLong_FromLong(rate); } @@ -456,16 +348,6 @@ SHA3_get_name(SHA3object *self, void *closure) return PyUnicode_FromString("sha3_384"); } else if (type == state->sha3_512_type) { return PyUnicode_FromString("sha3_512"); -#ifdef PY_WITH_KECCAK - } else if (type == state->keccak_224_type) { - return PyUnicode_FromString("keccak_224"); - } else if (type == state->keccak_256_type) { - return PyUnicode_FromString("keccak_256"); - } else if (type == state->keccak_384_type) { - return PyUnicode_FromString("keccak_384"); - } else if (type == state->keccak_512_type) { - return PyUnicode_FromString("keccak_512"); -#endif } else if (type == state->shake_128_type) { return PyUnicode_FromString("shake_128"); } else if (type == state->shake_256_type) { @@ -480,14 +362,14 @@ SHA3_get_name(SHA3object *self, void *closure) static PyObject * SHA3_get_digest_size(SHA3object *self, void *closure) { - return PyLong_FromLong(self->hash_state.fixedOutputLength / 8); + return PyLong_FromLong(self->hash_state.mdlen); } static PyObject * SHA3_get_capacity_bits(SHA3object *self, void *closure) { - int capacity = 1600 - self->hash_state.sponge.rate; + int capacity = 1600 - self->hash_state.rsiz * 8; return PyLong_FromLong(capacity); } @@ -495,16 +377,14 @@ SHA3_get_capacity_bits(SHA3object *self, void *closure) static PyObject * SHA3_get_rate_bits(SHA3object *self, void *closure) { - unsigned int rate = self->hash_state.sponge.rate; + unsigned int rate = self->hash_state.rsiz * 8; return PyLong_FromLong(rate); } static PyObject * SHA3_get_suffix(SHA3object *self, void *closure) { - unsigned char suffix[2]; - suffix[0] = self->hash_state.delimitedSuffix; - suffix[1] = 0; + unsigned char suffix[2] = {0x06, 0}; return PyBytes_FromStringAndSize((const char *)suffix, 1); } @@ -518,12 +398,12 @@ static PyGetSetDef SHA3_getseters[] = { {NULL} /* Sentinel */ }; -#define SHA3_TYPE_SLOTS(type_slots_obj, type_doc, type_methods) \ +#define SHA3_TYPE_SLOTS(type_slots_obj, type_doc, type_methods, type_getseters) \ static PyType_Slot type_slots_obj[] = { \ {Py_tp_dealloc, SHA3_dealloc}, \ {Py_tp_doc, (char*)type_doc}, \ {Py_tp_methods, type_methods}, \ - {Py_tp_getset, SHA3_getseters}, \ + {Py_tp_getset, type_getseters}, \ {Py_tp_new, py_sha3_new}, \ {0,0} \ } @@ -558,62 +438,23 @@ PyDoc_STRVAR(sha3_512__doc__, \n\ Return a new SHA3 hash object with a hashbit length of 64 bytes."); -#ifdef PY_WITH_KECCAK -PyDoc_STRVAR(keccak_224__doc__, -"keccak_224([data], *, usedforsecurity=True) -> Keccak object\n\ -\n\ -Return a new Keccak hash object with a hashbit length of 28 bytes."); - -PyDoc_STRVAR(keccak_256__doc__, -"keccak_256([data], *, usedforsecurity=True) -> Keccak object\n\ -\n\ -Return a new Keccak hash object with a hashbit length of 32 bytes."); - -PyDoc_STRVAR(keccak_384__doc__, -"keccak_384([data], *, usedforsecurity=True) -> Keccak object\n\ -\n\ -Return a new Keccak hash object with a hashbit length of 48 bytes."); - -PyDoc_STRVAR(keccak_512__doc__, -"keccak_512([data], *, usedforsecurity=True) -> Keccak object\n\ -\n\ -Return a new Keccak hash object with a hashbit length of 64 bytes."); - -#endif - -SHA3_TYPE_SLOTS(sha3_224_slots, sha3_224__doc__, SHA3_methods); +SHA3_TYPE_SLOTS(sha3_224_slots, sha3_224__doc__, SHA3_methods, SHA3_getseters); SHA3_TYPE_SPEC(sha3_224_spec, "sha3_224", sha3_224_slots); -SHA3_TYPE_SLOTS(sha3_256_slots, sha3_256__doc__, SHA3_methods); +SHA3_TYPE_SLOTS(sha3_256_slots, sha3_256__doc__, SHA3_methods, SHA3_getseters); SHA3_TYPE_SPEC(sha3_256_spec, "sha3_256", sha3_256_slots); -SHA3_TYPE_SLOTS(sha3_384_slots, sha3_384__doc__, SHA3_methods); +SHA3_TYPE_SLOTS(sha3_384_slots, sha3_384__doc__, SHA3_methods, SHA3_getseters); SHA3_TYPE_SPEC(sha3_384_spec, "sha3_384", sha3_384_slots); -SHA3_TYPE_SLOTS(sha3_512_slots, sha3_512__doc__, SHA3_methods); +SHA3_TYPE_SLOTS(sha3_512_slots, sha3_512__doc__, SHA3_methods, SHA3_getseters); SHA3_TYPE_SPEC(sha3_512_spec, "sha3_512", sha3_512_slots); -#ifdef PY_WITH_KECCAK -SHA3_TYPE_SLOTS(Keccak_224_slots, keccak_224__doc__, SHA3_methods); -SHA3_TYPE_SPEC(Keccak_224_spec, "keccak_224", Keccak_224_slots); - -SHA3_TYPE_SLOTS(Keccak_256_slots, keccak_256__doc__, SHA3_methods); -SHA3_TYPE_SPEC(Keccak_256_spec, "keccak_256", Keccak_256_slots); - -SHA3_TYPE_SLOTS(Keccak_384_slots, keccak_384__doc__, SHA3_methods); -SHA3_TYPE_SPEC(Keccak_384_spec, "keccak_384", Keccak_384_slots); - -SHA3_TYPE_SLOTS(Keccak_512_slots, keccak_512__doc__, SHA3_methods); -SHA3_TYPE_SPEC(Keccak_512_spec, "keccak_512", Keccak_512_slots); -#endif - - static PyObject * _SHAKE_digest(SHA3object *self, unsigned long digestlen, int hex) { unsigned char *digest = NULL; SHA3_state temp; - int res; PyObject *result = NULL; if (digestlen >= (1 << 29)) { @@ -632,23 +473,13 @@ _SHAKE_digest(SHA3object *self, unsigned long digestlen, int hex) ENTER_HASHLIB(self); SHA3_copystate(temp, self->hash_state); LEAVE_HASHLIB(self); - res = SHA3_done(&temp, NULL); - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 done()"); - goto error; - } - res = SHA3_squeeze(&temp, digest, digestlen * 8); - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Squeeze()"); - return NULL; - } + SHA3_squeeze(&temp, digest, digestlen); if (hex) { result = _Py_strhex((const char *)digest, digestlen); } else { result = PyBytes_FromStringAndSize((const char *)digest, digestlen); } - error: if (digest != NULL) { PyMem_Free(digest); } @@ -689,6 +520,30 @@ _sha3_shake_128_hexdigest_impl(SHA3object *self, unsigned long length) return _SHAKE_digest(self, length, 1); } +static PyObject * +SHAKE_get_digest_size(SHA3object *self, void *closure) +{ + return PyLong_FromLong(0); +} + +static PyObject * +SHAKE_get_suffix(SHA3object *self, void *closure) +{ + unsigned char suffix[2] = {0x1f, 0}; + return PyBytes_FromStringAndSize((const char *)suffix, 1); +} + + +static PyGetSetDef SHAKE_getseters[] = { + {"block_size", (getter)SHA3_get_block_size, NULL, NULL, NULL}, + {"name", (getter)SHA3_get_name, NULL, NULL, NULL}, + {"digest_size", (getter)SHAKE_get_digest_size, NULL, NULL, NULL}, + {"_capacity_bits", (getter)SHA3_get_capacity_bits, NULL, NULL, NULL}, + {"_rate_bits", (getter)SHA3_get_rate_bits, NULL, NULL, NULL}, + {"_suffix", (getter)SHAKE_get_suffix, NULL, NULL, NULL}, + {NULL} /* Sentinel */ +}; + static PyMethodDef SHAKE_methods[] = { _SHA3_SHA3_224_COPY_METHODDEF @@ -708,10 +563,10 @@ PyDoc_STRVAR(shake_256__doc__, \n\ Return a new SHAKE hash object."); -SHA3_TYPE_SLOTS(SHAKE128slots, shake_128__doc__, SHAKE_methods); +SHA3_TYPE_SLOTS(SHAKE128slots, shake_128__doc__, SHAKE_methods, SHAKE_getseters); SHA3_TYPE_SPEC(SHAKE128_spec, "shake_128", SHAKE128slots); -SHA3_TYPE_SLOTS(SHAKE256slots, shake_256__doc__, SHAKE_methods); +SHA3_TYPE_SLOTS(SHAKE256slots, shake_256__doc__, SHAKE_methods, SHAKE_getseters); SHA3_TYPE_SPEC(SHAKE256_spec, "shake_256", SHAKE256slots); @@ -723,12 +578,6 @@ _sha3_traverse(PyObject *module, visitproc visit, void *arg) Py_VISIT(state->sha3_256_type); Py_VISIT(state->sha3_384_type); Py_VISIT(state->sha3_512_type); -#ifdef PY_WITH_KECCAK - Py_VISIT(state->keccak_224_type); - Py_VISIT(state->keccak_256_type); - Py_VISIT(state->keccak_384_type); - Py_VISIT(state->keccak_512_type); -#endif Py_VISIT(state->shake_128_type); Py_VISIT(state->shake_256_type); return 0; @@ -742,12 +591,6 @@ _sha3_clear(PyObject *module) Py_CLEAR(state->sha3_256_type); Py_CLEAR(state->sha3_384_type); Py_CLEAR(state->sha3_512_type); -#ifdef PY_WITH_KECCAK - Py_CLEAR(state->keccak_224_type); - Py_CLEAR(state->keccak_256_type); - Py_CLEAR(state->keccak_384_type); - Py_CLEAR(state->keccak_512_type); -#endif Py_CLEAR(state->shake_128_type); Py_CLEAR(state->shake_256_type); return 0; @@ -780,12 +623,6 @@ _sha3_exec(PyObject *m) init_sha3type(sha3_256_type, sha3_256_spec); init_sha3type(sha3_384_type, sha3_384_spec); init_sha3type(sha3_512_type, sha3_512_spec); -#ifdef PY_WITH_KECCAK - init_sha3type(keccak_224_type, Keccak_224_spec); - init_sha3type(keccak_256_type, Keccak_256_spec); - init_sha3type(keccak_384_type, Keccak_384_spec); - init_sha3type(keccak_512_type, Keccak_512_spec); -#endif init_sha3type(shake_128_type, SHAKE128_spec); init_sha3type(shake_256_type, SHAKE256_spec); #undef init_sha3type @@ -794,7 +631,7 @@ _sha3_exec(PyObject *m) return -1; } if (PyModule_AddStringConstant(m, "implementation", - KeccakP1600_implementation) < 0) { + "tiny_sha3") < 0) { return -1; } diff --git a/Modules/_sqlite/blob.c b/Modules/_sqlite/blob.c new file mode 100644 index 00000000000..76d261baf00 --- /dev/null +++ b/Modules/_sqlite/blob.c @@ -0,0 +1,617 @@ +#include "blob.h" +#include "util.h" + +#define clinic_state() (pysqlite_get_state_by_type(Py_TYPE(self))) +#include "clinic/blob.c.h" +#undef clinic_state + +/*[clinic input] +module _sqlite3 +class _sqlite3.Blob "pysqlite_Blob *" "clinic_state()->BlobType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=908d3e16a45f8da7]*/ + +static void +close_blob(pysqlite_Blob *self) +{ + if (self->blob) { + sqlite3_blob *blob = self->blob; + self->blob = NULL; + + Py_BEGIN_ALLOW_THREADS + sqlite3_blob_close(blob); + Py_END_ALLOW_THREADS + } +} + +static int +blob_traverse(pysqlite_Blob *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->connection); + return 0; +} + +static int +blob_clear(pysqlite_Blob *self) +{ + Py_CLEAR(self->connection); + return 0; +} + +static void +blob_dealloc(pysqlite_Blob *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + + close_blob(self); + + if (self->in_weakreflist != NULL) { + PyObject_ClearWeakRefs((PyObject*)self); + } + tp->tp_clear((PyObject *)self); + tp->tp_free(self); + Py_DECREF(tp); +} + +// Return 1 if the blob object is usable, 0 if not. +static int +check_blob(pysqlite_Blob *self) +{ + if (!pysqlite_check_connection(self->connection) || + !pysqlite_check_thread(self->connection)) { + return 0; + } + if (self->blob == NULL) { + pysqlite_state *state = self->connection->state; + PyErr_SetString(state->ProgrammingError, + "Cannot operate on a closed blob."); + return 0; + } + return 1; +} + + +/*[clinic input] +_sqlite3.Blob.close as blob_close + +Close the blob. +[clinic start generated code]*/ + +static PyObject * +blob_close_impl(pysqlite_Blob *self) +/*[clinic end generated code: output=848accc20a138d1b input=7bc178a402a40bd8]*/ +{ + if (!pysqlite_check_connection(self->connection) || + !pysqlite_check_thread(self->connection)) + { + return NULL; + } + close_blob(self); + Py_RETURN_NONE; +}; + +void +pysqlite_close_all_blobs(pysqlite_Connection *self) +{ + for (int i = 0; i < PyList_GET_SIZE(self->blobs); i++) { + PyObject *weakref = PyList_GET_ITEM(self->blobs, i); + PyObject *blob = PyWeakref_GetObject(weakref); + if (!Py_IsNone(blob)) { + close_blob((pysqlite_Blob *)blob); + } + } +} + +static void +blob_seterror(pysqlite_Blob *self, int rc) +{ + assert(self->connection != NULL); +#if SQLITE_VERSION_NUMBER < 3008008 + // SQLite pre 3.8.8 does not set this blob error on the connection + if (rc == SQLITE_ABORT) { + PyErr_SetString(self->connection->OperationalError, + "Cannot operate on an expired blob handle"); + return; + } +#endif + _pysqlite_seterror(self->connection->state, self->connection->db); +} + +static PyObject * +read_single(pysqlite_Blob *self, Py_ssize_t offset) +{ + unsigned char buf = 0; + int rc; + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_blob_read(self->blob, (void *)&buf, 1, (int)offset); + Py_END_ALLOW_THREADS + + if (rc != SQLITE_OK) { + blob_seterror(self, rc); + return NULL; + } + return PyLong_FromUnsignedLong((unsigned long)buf); +} + +static PyObject * +read_multiple(pysqlite_Blob *self, Py_ssize_t length, Py_ssize_t offset) +{ + assert(length <= sqlite3_blob_bytes(self->blob)); + assert(offset < sqlite3_blob_bytes(self->blob)); + + PyObject *buffer = PyBytes_FromStringAndSize(NULL, length); + if (buffer == NULL) { + return NULL; + } + + char *raw_buffer = PyBytes_AS_STRING(buffer); + int rc; + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_blob_read(self->blob, raw_buffer, (int)length, (int)offset); + Py_END_ALLOW_THREADS + + if (rc != SQLITE_OK) { + Py_DECREF(buffer); + blob_seterror(self, rc); + return NULL; + } + return buffer; +} + + +/*[clinic input] +_sqlite3.Blob.read as blob_read + + length: int = -1 + Read length in bytes. + / + +Read data at the current offset position. + +If the end of the blob is reached, the data up to end of file will be returned. +When length is not specified, or is negative, Blob.read() will read until the +end of the blob. +[clinic start generated code]*/ + +static PyObject * +blob_read_impl(pysqlite_Blob *self, int length) +/*[clinic end generated code: output=1fc99b2541360dde input=f2e4aa4378837250]*/ +{ + if (!check_blob(self)) { + return NULL; + } + + /* Make sure we never read past "EOB". Also read the rest of the blob if a + * negative length is specified. */ + int blob_len = sqlite3_blob_bytes(self->blob); + int max_read_len = blob_len - self->offset; + if (length < 0 || length > max_read_len) { + length = max_read_len; + } + + assert(length >= 0); + if (length == 0) { + return PyBytes_FromStringAndSize(NULL, 0); + } + + PyObject *buffer = read_multiple(self, length, self->offset); + if (buffer == NULL) { + return NULL; + } + self->offset += length; + return buffer; +}; + +static int +inner_write(pysqlite_Blob *self, const void *buf, Py_ssize_t len, + Py_ssize_t offset) +{ + Py_ssize_t blob_len = sqlite3_blob_bytes(self->blob); + Py_ssize_t remaining_len = blob_len - offset; + if (len > remaining_len) { + PyErr_SetString(PyExc_ValueError, "data longer than blob length"); + return -1; + } + + assert(offset <= blob_len); + int rc; + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_blob_write(self->blob, buf, (int)len, (int)offset); + Py_END_ALLOW_THREADS + + if (rc != SQLITE_OK) { + blob_seterror(self, rc); + return -1; + } + return 0; +} + + +/*[clinic input] +_sqlite3.Blob.write as blob_write + + data: Py_buffer + / + +Write data at the current offset. + +This function cannot change the blob length. Writing beyond the end of the +blob will result in an exception being raised. +[clinic start generated code]*/ + +static PyObject * +blob_write_impl(pysqlite_Blob *self, Py_buffer *data) +/*[clinic end generated code: output=b34cf22601b570b2 input=a84712f24a028e6d]*/ +{ + if (!check_blob(self)) { + return NULL; + } + + int rc = inner_write(self, data->buf, data->len, self->offset); + if (rc < 0) { + return NULL; + } + self->offset += (int)data->len; + Py_RETURN_NONE; +} + + +/*[clinic input] +_sqlite3.Blob.seek as blob_seek + + offset: int + origin: int = 0 + / + +Set the current access position to offset. + +The origin argument defaults to os.SEEK_SET (absolute blob positioning). +Other values for origin are os.SEEK_CUR (seek relative to the current position) +and os.SEEK_END (seek relative to the blob's end). +[clinic start generated code]*/ + +static PyObject * +blob_seek_impl(pysqlite_Blob *self, int offset, int origin) +/*[clinic end generated code: output=854c5a0e208547a5 input=5da9a07e55fe6bb6]*/ +{ + if (!check_blob(self)) { + return NULL; + } + + int blob_len = sqlite3_blob_bytes(self->blob); + switch (origin) { + case SEEK_SET: + break; + case SEEK_CUR: + if (offset > INT_MAX - self->offset) { + goto overflow; + } + offset += self->offset; + break; + case SEEK_END: + if (offset > INT_MAX - blob_len) { + goto overflow; + } + offset += blob_len; + break; + default: + PyErr_SetString(PyExc_ValueError, + "'origin' should be os.SEEK_SET, os.SEEK_CUR, or " + "os.SEEK_END"); + return NULL; + } + + if (offset < 0 || offset > blob_len) { + PyErr_SetString(PyExc_ValueError, "offset out of blob range"); + return NULL; + } + + self->offset = offset; + Py_RETURN_NONE; + +overflow: + PyErr_SetString(PyExc_OverflowError, "seek offset results in overflow"); + return NULL; +} + + +/*[clinic input] +_sqlite3.Blob.tell as blob_tell + +Return the current access position for the blob. +[clinic start generated code]*/ + +static PyObject * +blob_tell_impl(pysqlite_Blob *self) +/*[clinic end generated code: output=3d3ba484a90b3a99 input=7e34057aa303612c]*/ +{ + if (!check_blob(self)) { + return NULL; + } + return PyLong_FromLong(self->offset); +} + + +/*[clinic input] +_sqlite3.Blob.__enter__ as blob_enter + +Blob context manager enter. +[clinic start generated code]*/ + +static PyObject * +blob_enter_impl(pysqlite_Blob *self) +/*[clinic end generated code: output=4fd32484b071a6cd input=fe4842c3c582d5a7]*/ +{ + if (!check_blob(self)) { + return NULL; + } + return Py_NewRef(self); +} + + +/*[clinic input] +_sqlite3.Blob.__exit__ as blob_exit + + type: object + val: object + tb: object + / + +Blob context manager exit. +[clinic start generated code]*/ + +static PyObject * +blob_exit_impl(pysqlite_Blob *self, PyObject *type, PyObject *val, + PyObject *tb) +/*[clinic end generated code: output=fc86ceeb2b68c7b2 input=575d9ecea205f35f]*/ +{ + if (!check_blob(self)) { + return NULL; + } + close_blob(self); + Py_RETURN_FALSE; +} + +static Py_ssize_t +blob_length(pysqlite_Blob *self) +{ + if (!check_blob(self)) { + return -1; + } + return sqlite3_blob_bytes(self->blob); +}; + +static Py_ssize_t +get_subscript_index(pysqlite_Blob *self, PyObject *item) +{ + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) { + return -1; + } + int blob_len = sqlite3_blob_bytes(self->blob); + if (i < 0) { + i += blob_len; + } + if (i < 0 || i >= blob_len) { + PyErr_SetString(PyExc_IndexError, "Blob index out of range"); + return -1; + } + return i; +} + +static PyObject * +subscript_index(pysqlite_Blob *self, PyObject *item) +{ + Py_ssize_t i = get_subscript_index(self, item); + if (i < 0) { + return NULL; + } + return read_single(self, i); +} + +static int +get_slice_info(pysqlite_Blob *self, PyObject *item, Py_ssize_t *start, + Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelen) +{ + if (PySlice_Unpack(item, start, stop, step) < 0) { + return -1; + } + int len = sqlite3_blob_bytes(self->blob); + *slicelen = PySlice_AdjustIndices(len, start, stop, *step); + return 0; +} + +static PyObject * +subscript_slice(pysqlite_Blob *self, PyObject *item) +{ + Py_ssize_t start, stop, step, len; + if (get_slice_info(self, item, &start, &stop, &step, &len) < 0) { + return NULL; + } + + if (step == 1) { + return read_multiple(self, len, start); + } + PyObject *blob = read_multiple(self, stop - start, start); + if (blob == NULL) { + return NULL; + } + PyObject *result = PyBytes_FromStringAndSize(NULL, len); + if (result != NULL) { + char *blob_buf = PyBytes_AS_STRING(blob); + char *res_buf = PyBytes_AS_STRING(result); + for (Py_ssize_t i = 0, j = 0; i < len; i++, j += step) { + res_buf[i] = blob_buf[j]; + } + Py_DECREF(blob); + } + return result; +} + +static PyObject * +blob_subscript(pysqlite_Blob *self, PyObject *item) +{ + if (!check_blob(self)) { + return NULL; + } + + if (PyIndex_Check(item)) { + return subscript_index(self, item); + } + if (PySlice_Check(item)) { + return subscript_slice(self, item); + } + + PyErr_SetString(PyExc_TypeError, "Blob indices must be integers"); + return NULL; +} + +static int +ass_subscript_index(pysqlite_Blob *self, PyObject *item, PyObject *value) +{ + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "Blob doesn't support item deletion"); + return -1; + } + if (!PyLong_Check(value)) { + PyErr_Format(PyExc_TypeError, + "'%s' object cannot be interpreted as an integer", + Py_TYPE(value)->tp_name); + return -1; + } + Py_ssize_t i = get_subscript_index(self, item); + if (i < 0) { + return -1; + } + + long val = PyLong_AsLong(value); + if (val == -1 && PyErr_Occurred()) { + PyErr_Clear(); + val = -1; + } + if (val < 0 || val > 255) { + PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); + return -1; + } + // Downcast to avoid endianness problems. + unsigned char byte = (unsigned char)val; + return inner_write(self, (const void *)&byte, 1, i); +} + +static int +ass_subscript_slice(pysqlite_Blob *self, PyObject *item, PyObject *value) +{ + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "Blob doesn't support slice deletion"); + return -1; + } + + Py_ssize_t start, stop, step, len; + if (get_slice_info(self, item, &start, &stop, &step, &len) < 0) { + return -1; + } + + if (len == 0) { + return 0; + } + + Py_buffer vbuf; + if (PyObject_GetBuffer(value, &vbuf, PyBUF_SIMPLE) < 0) { + return -1; + } + + int rc = -1; + if (vbuf.len != len) { + PyErr_SetString(PyExc_IndexError, + "Blob slice assignment is wrong size"); + } + else if (step == 1) { + rc = inner_write(self, vbuf.buf, len, start); + } + else { + PyObject *blob_bytes = read_multiple(self, stop - start, start); + if (blob_bytes != NULL) { + char *blob_buf = PyBytes_AS_STRING(blob_bytes); + for (Py_ssize_t i = 0, j = 0; i < len; i++, j += step) { + blob_buf[j] = ((char *)vbuf.buf)[i]; + } + rc = inner_write(self, blob_buf, stop - start, start); + Py_DECREF(blob_bytes); + } + } + PyBuffer_Release(&vbuf); + return rc; +} + +static int +blob_ass_subscript(pysqlite_Blob *self, PyObject *item, PyObject *value) +{ + if (!check_blob(self)) { + return -1; + } + + if (PyIndex_Check(item)) { + return ass_subscript_index(self, item, value); + } + if (PySlice_Check(item)) { + return ass_subscript_slice(self, item, value); + } + + PyErr_SetString(PyExc_TypeError, "Blob indices must be integers"); + return -1; +} + + +static PyMethodDef blob_methods[] = { + BLOB_CLOSE_METHODDEF + BLOB_ENTER_METHODDEF + BLOB_EXIT_METHODDEF + BLOB_READ_METHODDEF + BLOB_SEEK_METHODDEF + BLOB_TELL_METHODDEF + BLOB_WRITE_METHODDEF + {NULL, NULL} +}; + +static struct PyMemberDef blob_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(pysqlite_Blob, in_weakreflist), READONLY}, + {NULL}, +}; + +static PyType_Slot blob_slots[] = { + {Py_tp_dealloc, blob_dealloc}, + {Py_tp_traverse, blob_traverse}, + {Py_tp_clear, blob_clear}, + {Py_tp_methods, blob_methods}, + {Py_tp_members, blob_members}, + + // Mapping protocol + {Py_mp_length, blob_length}, + {Py_mp_subscript, blob_subscript}, + {Py_mp_ass_subscript, blob_ass_subscript}, + {0, NULL}, +}; + +static PyType_Spec blob_spec = { + .name = MODULE_NAME ".Blob", + .basicsize = sizeof(pysqlite_Blob), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), + .slots = blob_slots, +}; + +int +pysqlite_blob_setup_types(PyObject *mod) +{ + PyObject *type = PyType_FromModuleAndSpec(mod, &blob_spec, NULL); + if (type == NULL) { + return -1; + } + pysqlite_state *state = pysqlite_get_state(mod); + state->BlobType = (PyTypeObject *)type; + return 0; +} diff --git a/Modules/_sqlite/blob.h b/Modules/_sqlite/blob.h new file mode 100644 index 00000000000..418ca03bdb5 --- /dev/null +++ b/Modules/_sqlite/blob.h @@ -0,0 +1,24 @@ +#ifndef PYSQLITE_BLOB_H +#define PYSQLITE_BLOB_H + +#include "Python.h" +#include "sqlite3.h" +#include "connection.h" + +#define BLOB_SEEK_START 0 +#define BLOB_SEEK_CUR 1 +#define BLOB_SEEK_END 2 + +typedef struct { + PyObject_HEAD + pysqlite_Connection *connection; + sqlite3_blob *blob; + int offset; + + PyObject *in_weakreflist; +} pysqlite_Blob; + +int pysqlite_blob_setup_types(PyObject *mod); +void pysqlite_close_all_blobs(pysqlite_Connection *self); + +#endif diff --git a/Modules/_sqlite/clinic/blob.c.h b/Modules/_sqlite/clinic/blob.c.h new file mode 100644 index 00000000000..f3d8a35be46 --- /dev/null +++ b/Modules/_sqlite/clinic/blob.c.h @@ -0,0 +1,222 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(blob_close__doc__, +"close($self, /)\n" +"--\n" +"\n" +"Close the blob."); + +#define BLOB_CLOSE_METHODDEF \ + {"close", (PyCFunction)blob_close, METH_NOARGS, blob_close__doc__}, + +static PyObject * +blob_close_impl(pysqlite_Blob *self); + +static PyObject * +blob_close(pysqlite_Blob *self, PyObject *Py_UNUSED(ignored)) +{ + return blob_close_impl(self); +} + +PyDoc_STRVAR(blob_read__doc__, +"read($self, length=-1, /)\n" +"--\n" +"\n" +"Read data at the current offset position.\n" +"\n" +" length\n" +" Read length in bytes.\n" +"\n" +"If the end of the blob is reached, the data up to end of file will be returned.\n" +"When length is not specified, or is negative, Blob.read() will read until the\n" +"end of the blob."); + +#define BLOB_READ_METHODDEF \ + {"read", _PyCFunction_CAST(blob_read), METH_FASTCALL, blob_read__doc__}, + +static PyObject * +blob_read_impl(pysqlite_Blob *self, int length); + +static PyObject * +blob_read(pysqlite_Blob *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int length = -1; + + if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + length = _PyLong_AsInt(args[0]); + if (length == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = blob_read_impl(self, length); + +exit: + return return_value; +} + +PyDoc_STRVAR(blob_write__doc__, +"write($self, data, /)\n" +"--\n" +"\n" +"Write data at the current offset.\n" +"\n" +"This function cannot change the blob length. Writing beyond the end of the\n" +"blob will result in an exception being raised."); + +#define BLOB_WRITE_METHODDEF \ + {"write", (PyCFunction)blob_write, METH_O, blob_write__doc__}, + +static PyObject * +blob_write_impl(pysqlite_Blob *self, Py_buffer *data); + +static PyObject * +blob_write(pysqlite_Blob *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); + goto exit; + } + return_value = blob_write_impl(self, &data); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +PyDoc_STRVAR(blob_seek__doc__, +"seek($self, offset, origin=0, /)\n" +"--\n" +"\n" +"Set the current access position to offset.\n" +"\n" +"The origin argument defaults to os.SEEK_SET (absolute blob positioning).\n" +"Other values for origin are os.SEEK_CUR (seek relative to the current position)\n" +"and os.SEEK_END (seek relative to the blob\'s end)."); + +#define BLOB_SEEK_METHODDEF \ + {"seek", _PyCFunction_CAST(blob_seek), METH_FASTCALL, blob_seek__doc__}, + +static PyObject * +blob_seek_impl(pysqlite_Blob *self, int offset, int origin); + +static PyObject * +blob_seek(pysqlite_Blob *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int offset; + int origin = 0; + + if (!_PyArg_CheckPositional("seek", nargs, 1, 2)) { + goto exit; + } + offset = _PyLong_AsInt(args[0]); + if (offset == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + origin = _PyLong_AsInt(args[1]); + if (origin == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = blob_seek_impl(self, offset, origin); + +exit: + return return_value; +} + +PyDoc_STRVAR(blob_tell__doc__, +"tell($self, /)\n" +"--\n" +"\n" +"Return the current access position for the blob."); + +#define BLOB_TELL_METHODDEF \ + {"tell", (PyCFunction)blob_tell, METH_NOARGS, blob_tell__doc__}, + +static PyObject * +blob_tell_impl(pysqlite_Blob *self); + +static PyObject * +blob_tell(pysqlite_Blob *self, PyObject *Py_UNUSED(ignored)) +{ + return blob_tell_impl(self); +} + +PyDoc_STRVAR(blob_enter__doc__, +"__enter__($self, /)\n" +"--\n" +"\n" +"Blob context manager enter."); + +#define BLOB_ENTER_METHODDEF \ + {"__enter__", (PyCFunction)blob_enter, METH_NOARGS, blob_enter__doc__}, + +static PyObject * +blob_enter_impl(pysqlite_Blob *self); + +static PyObject * +blob_enter(pysqlite_Blob *self, PyObject *Py_UNUSED(ignored)) +{ + return blob_enter_impl(self); +} + +PyDoc_STRVAR(blob_exit__doc__, +"__exit__($self, type, val, tb, /)\n" +"--\n" +"\n" +"Blob context manager exit."); + +#define BLOB_EXIT_METHODDEF \ + {"__exit__", _PyCFunction_CAST(blob_exit), METH_FASTCALL, blob_exit__doc__}, + +static PyObject * +blob_exit_impl(pysqlite_Blob *self, PyObject *type, PyObject *val, + PyObject *tb); + +static PyObject * +blob_exit(pysqlite_Blob *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *type; + PyObject *val; + PyObject *tb; + + if (!_PyArg_CheckPositional("__exit__", nargs, 3, 3)) { + goto exit; + } + type = args[0]; + val = args[1]; + tb = args[2]; + return_value = blob_exit_impl(self, type, val, tb); + +exit: + return return_value; +} +/*[clinic end generated code: output=ad6a402f70e85977 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index 16ad2ee254e..4c3fd1bd274 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -2,24 +2,54 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static int -pysqlite_connection_init_impl(pysqlite_Connection *self, - const char *database, double timeout, - int detect_types, const char *isolation_level, +pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database, + double timeout, int detect_types, + const char *isolation_level, int check_same_thread, PyObject *factory, - int cache_size, int uri); + int cache_size, int uri, + enum autocommit_mode autocommit); static int pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static const char * const _keywords[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", "uri", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Connection", 0}; - PyObject *argsbuf[8]; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 9 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(database), &_Py_ID(timeout), &_Py_ID(detect_types), &_Py_ID(isolation_level), &_Py_ID(check_same_thread), &_Py_ID(factory), &_Py_ID(cached_statements), &_Py_ID(uri), &_Py_ID(autocommit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", "uri", "autocommit", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Connection", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[9]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; - const char *database = NULL; + PyObject *database; double timeout = 5.0; int detect_types = 0; const char *isolation_level = ""; @@ -27,14 +57,13 @@ pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) PyObject *factory = (PyObject*)clinic_state()->ConnectionType; int cache_size = 128; int uri = 0; + enum autocommit_mode autocommit = LEGACY_TRANSACTION_CONTROL; fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 8, 0, argsbuf); if (!fastargs) { goto exit; } - if (!clinic_fsconverter(fastargs[0], &database)) { - goto exit; - } + database = fastargs[0]; if (!noptargs) { goto skip_optional_pos; } @@ -71,8 +100,8 @@ pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) } } if (fastargs[4]) { - check_same_thread = _PyLong_AsInt(fastargs[4]); - if (check_same_thread == -1 && PyErr_Occurred()) { + check_same_thread = PyObject_IsTrue(fastargs[4]); + if (check_same_thread < 0) { goto exit; } if (!--noptargs) { @@ -94,17 +123,26 @@ pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) goto skip_optional_pos; } } - uri = PyObject_IsTrue(fastargs[7]); - if (uri < 0) { - goto exit; + if (fastargs[7]) { + uri = PyObject_IsTrue(fastargs[7]); + if (uri < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } } skip_optional_pos: - return_value = pysqlite_connection_init_impl((pysqlite_Connection *)self, database, timeout, detect_types, isolation_level, check_same_thread, factory, cache_size, uri); + if (!noptargs) { + goto skip_optional_kwonly; + } + if (!autocommit_converter(fastargs[8], &autocommit)) { + goto exit; + } +skip_optional_kwonly: + return_value = pysqlite_connection_init_impl((pysqlite_Connection *)self, database, timeout, detect_types, isolation_level, check_same_thread, factory, cache_size, uri, autocommit); exit: - /* Cleanup for database */ - PyMem_Free((void *)database); - return return_value; } @@ -115,7 +153,7 @@ PyDoc_STRVAR(pysqlite_connection_cursor__doc__, "Return a cursor for the connection."); #define PYSQLITE_CONNECTION_CURSOR_METHODDEF \ - {"cursor", (PyCFunction)(void(*)(void))pysqlite_connection_cursor, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_cursor__doc__}, + {"cursor", _PyCFunction_CAST(pysqlite_connection_cursor), METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_cursor__doc__}, static PyObject * pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory); @@ -124,8 +162,31 @@ static PyObject * pysqlite_connection_cursor(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(factory), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"factory", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "cursor", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cursor", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *factory = NULL; @@ -145,11 +206,140 @@ exit: return return_value; } +PyDoc_STRVAR(blobopen__doc__, +"blobopen($self, table, column, row, /, *, readonly=False, name=\'main\')\n" +"--\n" +"\n" +"Open and return a BLOB object.\n" +"\n" +" table\n" +" Table name.\n" +" column\n" +" Column name.\n" +" row\n" +" Row index.\n" +" readonly\n" +" Open the BLOB without write permissions.\n" +" name\n" +" Database name."); + +#define BLOBOPEN_METHODDEF \ + {"blobopen", _PyCFunction_CAST(blobopen), METH_FASTCALL|METH_KEYWORDS, blobopen__doc__}, + +static PyObject * +blobopen_impl(pysqlite_Connection *self, const char *table, const char *col, + int row, int readonly, const char *name); + +static PyObject * +blobopen(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(readonly), &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "", "", "readonly", "name", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "blobopen", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[5]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; + const char *table; + const char *col; + int row; + int readonly = 0; + const char *name = "main"; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("blobopen", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t table_length; + table = PyUnicode_AsUTF8AndSize(args[0], &table_length); + if (table == NULL) { + goto exit; + } + if (strlen(table) != (size_t)table_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("blobopen", "argument 2", "str", args[1]); + goto exit; + } + Py_ssize_t col_length; + col = PyUnicode_AsUTF8AndSize(args[1], &col_length); + if (col == NULL) { + goto exit; + } + if (strlen(col) != (size_t)col_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + row = _PyLong_AsInt(args[2]); + if (row == -1 && PyErr_Occurred()) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[3]) { + readonly = PyObject_IsTrue(args[3]); + if (readonly < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (!PyUnicode_Check(args[4])) { + _PyArg_BadArgument("blobopen", "argument 'name'", "str", args[4]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[4], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } +skip_optional_kwonly: + return_value = blobopen_impl(self, table, col, row, readonly, name); + +exit: + return return_value; +} + PyDoc_STRVAR(pysqlite_connection_close__doc__, "close($self, /)\n" "--\n" "\n" -"Closes the connection."); +"Close the database connection.\n" +"\n" +"Any pending transaction is not committed implicitly."); #define PYSQLITE_CONNECTION_CLOSE_METHODDEF \ {"close", (PyCFunction)pysqlite_connection_close, METH_NOARGS, pysqlite_connection_close__doc__}, @@ -167,7 +357,9 @@ PyDoc_STRVAR(pysqlite_connection_commit__doc__, "commit($self, /)\n" "--\n" "\n" -"Commit the current transaction."); +"Commit any pending transaction to the database.\n" +"\n" +"If there is no open transaction, this method is a no-op."); #define PYSQLITE_CONNECTION_COMMIT_METHODDEF \ {"commit", (PyCFunction)pysqlite_connection_commit, METH_NOARGS, pysqlite_connection_commit__doc__}, @@ -185,7 +377,9 @@ PyDoc_STRVAR(pysqlite_connection_rollback__doc__, "rollback($self, /)\n" "--\n" "\n" -"Roll back the current transaction."); +"Roll back to the start of any pending transaction.\n" +"\n" +"If there is no open transaction, this method is a no-op."); #define PYSQLITE_CONNECTION_ROLLBACK_METHODDEF \ {"rollback", (PyCFunction)pysqlite_connection_rollback, METH_NOARGS, pysqlite_connection_rollback__doc__}, @@ -203,10 +397,10 @@ PyDoc_STRVAR(pysqlite_connection_create_function__doc__, "create_function($self, /, name, narg, func, *, deterministic=False)\n" "--\n" "\n" -"Creates a new function. Non-standard."); +"Creates a new function."); #define PYSQLITE_CONNECTION_CREATE_FUNCTION_METHODDEF \ - {"create_function", (PyCFunction)(void(*)(void))pysqlite_connection_create_function, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_function__doc__}, + {"create_function", _PyCFunction_CAST(pysqlite_connection_create_function), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_function__doc__}, static PyObject * pysqlite_connection_create_function_impl(pysqlite_Connection *self, @@ -218,31 +412,159 @@ static PyObject * pysqlite_connection_create_function(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(narg), &_Py_ID(func), &_Py_ID(deterministic), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", "narg", "func", "deterministic", NULL}; - static _PyArg_Parser _parser = {"siO|$p:create_function", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "create_function", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; const char *name; int narg; PyObject *func; int deterministic = 0; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &name, &narg, &func, &deterministic)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { goto exit; } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("create_function", "argument 'name'", "str", args[0]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[0], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + narg = _PyLong_AsInt(args[1]); + if (narg == -1 && PyErr_Occurred()) { + goto exit; + } + func = args[2]; + if (!noptargs) { + goto skip_optional_kwonly; + } + deterministic = PyObject_IsTrue(args[3]); + if (deterministic < 0) { + goto exit; + } +skip_optional_kwonly: return_value = pysqlite_connection_create_function_impl(self, cls, name, narg, func, deterministic); exit: return return_value; } +#if defined(HAVE_WINDOW_FUNCTIONS) + +PyDoc_STRVAR(create_window_function__doc__, +"create_window_function($self, name, num_params, aggregate_class, /)\n" +"--\n" +"\n" +"Creates or redefines an aggregate window function. Non-standard.\n" +"\n" +" name\n" +" The name of the SQL aggregate window function to be created or\n" +" redefined.\n" +" num_params\n" +" The number of arguments the step and inverse methods takes.\n" +" aggregate_class\n" +" A class with step(), finalize(), value(), and inverse() methods.\n" +" Set to None to clear the window function."); + +#define CREATE_WINDOW_FUNCTION_METHODDEF \ + {"create_window_function", _PyCFunction_CAST(create_window_function), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, create_window_function__doc__}, + +static PyObject * +create_window_function_impl(pysqlite_Connection *self, PyTypeObject *cls, + const char *name, int num_params, + PyObject *aggregate_class); + +static PyObject * +create_window_function(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", "", "", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "create_window_function", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + const char *name; + int num_params; + PyObject *aggregate_class; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("create_window_function", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[0], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + num_params = _PyLong_AsInt(args[1]); + if (num_params == -1 && PyErr_Occurred()) { + goto exit; + } + aggregate_class = args[2]; + return_value = create_window_function_impl(self, cls, name, num_params, aggregate_class); + +exit: + return return_value; +} + +#endif /* defined(HAVE_WINDOW_FUNCTIONS) */ + PyDoc_STRVAR(pysqlite_connection_create_aggregate__doc__, "create_aggregate($self, /, name, n_arg, aggregate_class)\n" "--\n" "\n" -"Creates a new aggregate. Non-standard."); +"Creates a new aggregate."); #define PYSQLITE_CONNECTION_CREATE_AGGREGATE_METHODDEF \ - {"create_aggregate", (PyCFunction)(void(*)(void))pysqlite_connection_create_aggregate, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_aggregate__doc__}, + {"create_aggregate", _PyCFunction_CAST(pysqlite_connection_create_aggregate), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_aggregate__doc__}, static PyObject * pysqlite_connection_create_aggregate_impl(pysqlite_Connection *self, @@ -254,16 +576,58 @@ static PyObject * pysqlite_connection_create_aggregate(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(n_arg), &_Py_ID(aggregate_class), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", "n_arg", "aggregate_class", NULL}; - static _PyArg_Parser _parser = {"siO:create_aggregate", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "create_aggregate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; const char *name; int n_arg; PyObject *aggregate_class; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &name, &n_arg, &aggregate_class)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { goto exit; } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("create_aggregate", "argument 'name'", "str", args[0]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[0], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + n_arg = _PyLong_AsInt(args[1]); + if (n_arg == -1 && PyErr_Occurred()) { + goto exit; + } + aggregate_class = args[2]; return_value = pysqlite_connection_create_aggregate_impl(self, cls, name, n_arg, aggregate_class); exit: @@ -274,10 +638,10 @@ PyDoc_STRVAR(pysqlite_connection_set_authorizer__doc__, "set_authorizer($self, /, authorizer_callback)\n" "--\n" "\n" -"Sets authorizer callback. Non-standard."); +"Sets authorizer callback."); #define PYSQLITE_CONNECTION_SET_AUTHORIZER_METHODDEF \ - {"set_authorizer", (PyCFunction)(void(*)(void))pysqlite_connection_set_authorizer, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_authorizer__doc__}, + {"set_authorizer", _PyCFunction_CAST(pysqlite_connection_set_authorizer), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_authorizer__doc__}, static PyObject * pysqlite_connection_set_authorizer_impl(pysqlite_Connection *self, @@ -288,14 +652,39 @@ static PyObject * pysqlite_connection_set_authorizer(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(authorizer_callback), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"authorizer_callback", NULL}; - static _PyArg_Parser _parser = {"O:set_authorizer", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_authorizer", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; PyObject *callable; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &callable)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { goto exit; } + callable = args[0]; return_value = pysqlite_connection_set_authorizer_impl(self, cls, callable); exit: @@ -306,10 +695,10 @@ PyDoc_STRVAR(pysqlite_connection_set_progress_handler__doc__, "set_progress_handler($self, /, progress_handler, n)\n" "--\n" "\n" -"Sets progress handler callback. Non-standard."); +"Sets progress handler callback."); #define PYSQLITE_CONNECTION_SET_PROGRESS_HANDLER_METHODDEF \ - {"set_progress_handler", (PyCFunction)(void(*)(void))pysqlite_connection_set_progress_handler, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_progress_handler__doc__}, + {"set_progress_handler", _PyCFunction_CAST(pysqlite_connection_set_progress_handler), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_progress_handler__doc__}, static PyObject * pysqlite_connection_set_progress_handler_impl(pysqlite_Connection *self, @@ -320,13 +709,42 @@ static PyObject * pysqlite_connection_set_progress_handler(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(progress_handler), &_Py_ID(n), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"progress_handler", "n", NULL}; - static _PyArg_Parser _parser = {"Oi:set_progress_handler", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_progress_handler", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; PyObject *callable; int n; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &callable, &n)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + callable = args[0]; + n = _PyLong_AsInt(args[1]); + if (n == -1 && PyErr_Occurred()) { goto exit; } return_value = pysqlite_connection_set_progress_handler_impl(self, cls, callable, n); @@ -339,12 +757,10 @@ PyDoc_STRVAR(pysqlite_connection_set_trace_callback__doc__, "set_trace_callback($self, /, trace_callback)\n" "--\n" "\n" -"Sets a trace callback called for each SQL statement (passed as unicode).\n" -"\n" -"Non-standard."); +"Sets a trace callback called for each SQL statement (passed as unicode)."); #define PYSQLITE_CONNECTION_SET_TRACE_CALLBACK_METHODDEF \ - {"set_trace_callback", (PyCFunction)(void(*)(void))pysqlite_connection_set_trace_callback, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_trace_callback__doc__}, + {"set_trace_callback", _PyCFunction_CAST(pysqlite_connection_set_trace_callback), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_trace_callback__doc__}, static PyObject * pysqlite_connection_set_trace_callback_impl(pysqlite_Connection *self, @@ -355,14 +771,39 @@ static PyObject * pysqlite_connection_set_trace_callback(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(trace_callback), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"trace_callback", NULL}; - static _PyArg_Parser _parser = {"O:set_trace_callback", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_trace_callback", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; PyObject *callable; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &callable)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { goto exit; } + callable = args[0]; return_value = pysqlite_connection_set_trace_callback_impl(self, cls, callable); exit: @@ -375,7 +816,7 @@ PyDoc_STRVAR(pysqlite_connection_enable_load_extension__doc__, "enable_load_extension($self, enable, /)\n" "--\n" "\n" -"Enable dynamic loading of SQLite extension modules. Non-standard."); +"Enable dynamic loading of SQLite extension modules."); #define PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF \ {"enable_load_extension", (PyCFunction)pysqlite_connection_enable_load_extension, METH_O, pysqlite_connection_enable_load_extension__doc__}, @@ -390,8 +831,8 @@ pysqlite_connection_enable_load_extension(pysqlite_Connection *self, PyObject *a PyObject *return_value = NULL; int onoff; - onoff = _PyLong_AsInt(arg); - if (onoff == -1 && PyErr_Occurred()) { + onoff = PyObject_IsTrue(arg); + if (onoff < 0) { goto exit; } return_value = pysqlite_connection_enable_load_extension_impl(self, onoff); @@ -408,7 +849,7 @@ PyDoc_STRVAR(pysqlite_connection_load_extension__doc__, "load_extension($self, name, /)\n" "--\n" "\n" -"Load SQLite extension module. Non-standard."); +"Load SQLite extension module."); #define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF \ {"load_extension", (PyCFunction)pysqlite_connection_load_extension, METH_O, pysqlite_connection_load_extension__doc__}, @@ -448,10 +889,10 @@ PyDoc_STRVAR(pysqlite_connection_execute__doc__, "execute($self, sql, parameters=, /)\n" "--\n" "\n" -"Executes a SQL statement. Non-standard."); +"Executes an SQL statement."); #define PYSQLITE_CONNECTION_EXECUTE_METHODDEF \ - {"execute", (PyCFunction)(void(*)(void))pysqlite_connection_execute, METH_FASTCALL, pysqlite_connection_execute__doc__}, + {"execute", _PyCFunction_CAST(pysqlite_connection_execute), METH_FASTCALL, pysqlite_connection_execute__doc__}, static PyObject * pysqlite_connection_execute_impl(pysqlite_Connection *self, PyObject *sql, @@ -490,10 +931,10 @@ PyDoc_STRVAR(pysqlite_connection_executemany__doc__, "executemany($self, sql, parameters, /)\n" "--\n" "\n" -"Repeatedly executes a SQL statement. Non-standard."); +"Repeatedly executes an SQL statement."); #define PYSQLITE_CONNECTION_EXECUTEMANY_METHODDEF \ - {"executemany", (PyCFunction)(void(*)(void))pysqlite_connection_executemany, METH_FASTCALL, pysqlite_connection_executemany__doc__}, + {"executemany", _PyCFunction_CAST(pysqlite_connection_executemany), METH_FASTCALL, pysqlite_connection_executemany__doc__}, static PyObject * pysqlite_connection_executemany_impl(pysqlite_Connection *self, @@ -528,7 +969,7 @@ PyDoc_STRVAR(pysqlite_connection_executescript__doc__, "executescript($self, sql_script, /)\n" "--\n" "\n" -"Executes multiple SQL statements at once. Non-standard."); +"Executes multiple SQL statements at once."); #define PYSQLITE_CONNECTION_EXECUTESCRIPT_METHODDEF \ {"executescript", (PyCFunction)pysqlite_connection_executescript, METH_O, pysqlite_connection_executescript__doc__}, @@ -537,7 +978,7 @@ PyDoc_STRVAR(pysqlite_connection_interrupt__doc__, "interrupt($self, /)\n" "--\n" "\n" -"Abort any pending database operation. Non-standard."); +"Abort any pending database operation."); #define PYSQLITE_CONNECTION_INTERRUPT_METHODDEF \ {"interrupt", (PyCFunction)pysqlite_connection_interrupt, METH_NOARGS, pysqlite_connection_interrupt__doc__}, @@ -555,9 +996,7 @@ PyDoc_STRVAR(pysqlite_connection_iterdump__doc__, "iterdump($self, /)\n" "--\n" "\n" -"Returns iterator to the dump of the database in an SQL text format.\n" -"\n" -"Non-standard."); +"Returns iterator to the dump of the database in an SQL text format."); #define PYSQLITE_CONNECTION_ITERDUMP_METHODDEF \ {"iterdump", (PyCFunction)pysqlite_connection_iterdump, METH_NOARGS, pysqlite_connection_iterdump__doc__}, @@ -576,10 +1015,10 @@ PyDoc_STRVAR(pysqlite_connection_backup__doc__, " sleep=0.25)\n" "--\n" "\n" -"Makes a backup of the database. Non-standard."); +"Makes a backup of the database."); #define PYSQLITE_CONNECTION_BACKUP_METHODDEF \ - {"backup", (PyCFunction)(void(*)(void))pysqlite_connection_backup, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_backup__doc__}, + {"backup", _PyCFunction_CAST(pysqlite_connection_backup), METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_backup__doc__}, static PyObject * pysqlite_connection_backup_impl(pysqlite_Connection *self, @@ -591,8 +1030,31 @@ static PyObject * pysqlite_connection_backup(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(target), &_Py_ID(pages), &_Py_ID(progress), &_Py_ID(name), &_Py_ID(sleep), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"target", "pages", "progress", "name", "sleep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "backup", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "backup", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; pysqlite_Connection *target; @@ -667,10 +1129,10 @@ PyDoc_STRVAR(pysqlite_connection_create_collation__doc__, "create_collation($self, name, callback, /)\n" "--\n" "\n" -"Creates a collation function. Non-standard."); +"Creates a collation function."); #define PYSQLITE_CONNECTION_CREATE_COLLATION_METHODDEF \ - {"create_collation", (PyCFunction)(void(*)(void))pysqlite_connection_create_collation, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_collation__doc__}, + {"create_collation", _PyCFunction_CAST(pysqlite_connection_create_collation), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_collation__doc__}, static PyObject * pysqlite_connection_create_collation_impl(pysqlite_Connection *self, @@ -682,21 +1144,243 @@ static PyObject * pysqlite_connection_create_collation(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {"sO:create_collation", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "create_collation", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; const char *name; PyObject *callable; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &name, &callable)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { goto exit; } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("create_collation", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[0], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + callable = args[1]; return_value = pysqlite_connection_create_collation_impl(self, cls, name, callable); exit: return return_value; } +#if defined(PY_SQLITE_HAVE_SERIALIZE) + +PyDoc_STRVAR(serialize__doc__, +"serialize($self, /, *, name=\'main\')\n" +"--\n" +"\n" +"Serialize a database into a byte string.\n" +"\n" +" name\n" +" Which database to serialize.\n" +"\n" +"For an ordinary on-disk database file, the serialization is just a copy of the\n" +"disk file. For an in-memory database or a \"temp\" database, the serialization is\n" +"the same sequence of bytes which would be written to disk if that database\n" +"were backed up to disk."); + +#define SERIALIZE_METHODDEF \ + {"serialize", _PyCFunction_CAST(serialize), METH_FASTCALL|METH_KEYWORDS, serialize__doc__}, + +static PyObject * +serialize_impl(pysqlite_Connection *self, const char *name); + +static PyObject * +serialize(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"name", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "serialize", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + const char *name = "main"; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("serialize", "argument 'name'", "str", args[0]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[0], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } +skip_optional_kwonly: + return_value = serialize_impl(self, name); + +exit: + return return_value; +} + +#endif /* defined(PY_SQLITE_HAVE_SERIALIZE) */ + +#if defined(PY_SQLITE_HAVE_SERIALIZE) + +PyDoc_STRVAR(deserialize__doc__, +"deserialize($self, data, /, *, name=\'main\')\n" +"--\n" +"\n" +"Load a serialized database.\n" +"\n" +" data\n" +" The serialized database content.\n" +" name\n" +" Which database to reopen with the deserialization.\n" +"\n" +"The deserialize interface causes the database connection to disconnect from the\n" +"target database, and then reopen it as an in-memory database based on the given\n" +"serialized data.\n" +"\n" +"The deserialize interface will fail with SQLITE_BUSY if the database is\n" +"currently in a read transaction or is involved in a backup operation."); + +#define DESERIALIZE_METHODDEF \ + {"deserialize", _PyCFunction_CAST(deserialize), METH_FASTCALL|METH_KEYWORDS, deserialize__doc__}, + +static PyObject * +deserialize_impl(pysqlite_Connection *self, Py_buffer *data, + const char *name); + +static PyObject * +deserialize(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "name", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "deserialize", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_buffer data = {NULL, NULL}; + const char *name = "main"; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyUnicode_Check(args[0])) { + Py_ssize_t len; + const char *ptr = PyUnicode_AsUTF8AndSize(args[0], &len); + if (ptr == NULL) { + goto exit; + } + PyBuffer_FillInfo(&data, args[0], (void *)ptr, len, 1, 0); + } + else { /* any bytes-like object */ + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("deserialize", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("deserialize", "argument 'name'", "str", args[1]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[1], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } +skip_optional_kwonly: + return_value = deserialize_impl(self, &data, name); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + +#endif /* defined(PY_SQLITE_HAVE_SERIALIZE) */ + PyDoc_STRVAR(pysqlite_connection_enter__doc__, "__enter__($self, /)\n" "--\n" @@ -726,7 +1410,7 @@ PyDoc_STRVAR(pysqlite_connection_exit__doc__, "If there was any exception, a rollback takes place; otherwise we commit."); #define PYSQLITE_CONNECTION_EXIT_METHODDEF \ - {"__exit__", (PyCFunction)(void(*)(void))pysqlite_connection_exit, METH_FASTCALL, pysqlite_connection_exit__doc__}, + {"__exit__", _PyCFunction_CAST(pysqlite_connection_exit), METH_FASTCALL, pysqlite_connection_exit__doc__}, static PyObject * pysqlite_connection_exit_impl(pysqlite_Connection *self, PyObject *exc_type, @@ -769,7 +1453,7 @@ PyDoc_STRVAR(setlimit__doc__, "the prior value of the limit is returned."); #define SETLIMIT_METHODDEF \ - {"setlimit", (PyCFunction)(void(*)(void))setlimit, METH_FASTCALL, setlimit__doc__}, + {"setlimit", _PyCFunction_CAST(setlimit), METH_FASTCALL, setlimit__doc__}, static PyObject * setlimit_impl(pysqlite_Connection *self, int category, int limit); @@ -829,6 +1513,10 @@ exit: return return_value; } +#ifndef CREATE_WINDOW_FUNCTION_METHODDEF + #define CREATE_WINDOW_FUNCTION_METHODDEF +#endif /* !defined(CREATE_WINDOW_FUNCTION_METHODDEF) */ + #ifndef PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF #define PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF #endif /* !defined(PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF) */ @@ -836,4 +1524,12 @@ exit: #ifndef PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF #define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF #endif /* !defined(PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF) */ -/*[clinic end generated code: output=c2faf6563397091b input=a9049054013a1b77]*/ + +#ifndef SERIALIZE_METHODDEF + #define SERIALIZE_METHODDEF +#endif /* !defined(SERIALIZE_METHODDEF) */ + +#ifndef DESERIALIZE_METHODDEF + #define DESERIALIZE_METHODDEF +#endif /* !defined(DESERIALIZE_METHODDEF) */ +/*[clinic end generated code: output=f10306e10427488b input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index d8a36ac38aa..36b8d0051a2 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static int pysqlite_cursor_init_impl(pysqlite_Cursor *self, pysqlite_Connection *connection); @@ -35,10 +41,10 @@ PyDoc_STRVAR(pysqlite_cursor_execute__doc__, "execute($self, sql, parameters=(), /)\n" "--\n" "\n" -"Executes a SQL statement."); +"Executes an SQL statement."); #define PYSQLITE_CURSOR_EXECUTE_METHODDEF \ - {"execute", (PyCFunction)(void(*)(void))pysqlite_cursor_execute, METH_FASTCALL, pysqlite_cursor_execute__doc__}, + {"execute", _PyCFunction_CAST(pysqlite_cursor_execute), METH_FASTCALL, pysqlite_cursor_execute__doc__}, static PyObject * pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyObject *sql, @@ -77,10 +83,10 @@ PyDoc_STRVAR(pysqlite_cursor_executemany__doc__, "executemany($self, sql, seq_of_parameters, /)\n" "--\n" "\n" -"Repeatedly executes a SQL statement."); +"Repeatedly executes an SQL statement."); #define PYSQLITE_CURSOR_EXECUTEMANY_METHODDEF \ - {"executemany", (PyCFunction)(void(*)(void))pysqlite_cursor_executemany, METH_FASTCALL, pysqlite_cursor_executemany__doc__}, + {"executemany", _PyCFunction_CAST(pysqlite_cursor_executemany), METH_FASTCALL, pysqlite_cursor_executemany__doc__}, static PyObject * pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyObject *sql, @@ -115,7 +121,7 @@ PyDoc_STRVAR(pysqlite_cursor_executescript__doc__, "executescript($self, sql_script, /)\n" "--\n" "\n" -"Executes multiple SQL statements at once. Non-standard."); +"Executes multiple SQL statements at once."); #define PYSQLITE_CURSOR_EXECUTESCRIPT_METHODDEF \ {"executescript", (PyCFunction)pysqlite_cursor_executescript, METH_O, pysqlite_cursor_executescript__doc__}, @@ -177,7 +183,7 @@ PyDoc_STRVAR(pysqlite_cursor_fetchmany__doc__, " The default value is set by the Cursor.arraysize attribute."); #define PYSQLITE_CURSOR_FETCHMANY_METHODDEF \ - {"fetchmany", (PyCFunction)(void(*)(void))pysqlite_cursor_fetchmany, METH_FASTCALL|METH_KEYWORDS, pysqlite_cursor_fetchmany__doc__}, + {"fetchmany", _PyCFunction_CAST(pysqlite_cursor_fetchmany), METH_FASTCALL|METH_KEYWORDS, pysqlite_cursor_fetchmany__doc__}, static PyObject * pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, int maxrows); @@ -186,8 +192,31 @@ static PyObject * pysqlite_cursor_fetchmany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(size), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"size", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fetchmany", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fetchmany", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int maxrows = self->arraysize; @@ -232,7 +261,7 @@ PyDoc_STRVAR(pysqlite_cursor_setinputsizes__doc__, "setinputsizes($self, sizes, /)\n" "--\n" "\n" -"Required by DB-API. Does nothing in pysqlite."); +"Required by DB-API. Does nothing in sqlite3."); #define PYSQLITE_CURSOR_SETINPUTSIZES_METHODDEF \ {"setinputsizes", (PyCFunction)pysqlite_cursor_setinputsizes, METH_O, pysqlite_cursor_setinputsizes__doc__}, @@ -241,10 +270,10 @@ PyDoc_STRVAR(pysqlite_cursor_setoutputsize__doc__, "setoutputsize($self, size, column=None, /)\n" "--\n" "\n" -"Required by DB-API. Does nothing in pysqlite."); +"Required by DB-API. Does nothing in sqlite3."); #define PYSQLITE_CURSOR_SETOUTPUTSIZE_METHODDEF \ - {"setoutputsize", (PyCFunction)(void(*)(void))pysqlite_cursor_setoutputsize, METH_FASTCALL, pysqlite_cursor_setoutputsize__doc__}, + {"setoutputsize", _PyCFunction_CAST(pysqlite_cursor_setoutputsize), METH_FASTCALL, pysqlite_cursor_setoutputsize__doc__}, static PyObject * pysqlite_cursor_setoutputsize_impl(pysqlite_Cursor *self, PyObject *size, @@ -289,4 +318,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=514f6eb4e4974671 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e53e75a32a9d92bd input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/module.c.h b/Modules/_sqlite/clinic/module.c.h index 667343da97f..12f60835880 100644 --- a/Modules/_sqlite/clinic/module.c.h +++ b/Modules/_sqlite/clinic/module.c.h @@ -2,126 +2,20 @@ preserve [clinic start generated code]*/ -PyDoc_STRVAR(pysqlite_connect__doc__, -"connect($module, /, database, timeout=5.0, detect_types=0,\n" -" isolation_level=, check_same_thread=True,\n" -" factory=ConnectionType, cached_statements=128, uri=False)\n" -"--\n" -"\n" -"Opens a connection to the SQLite database file database.\n" -"\n" -"You can use \":memory:\" to open a database connection to a database that resides\n" -"in RAM instead of on disk."); +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif -#define PYSQLITE_CONNECT_METHODDEF \ - {"connect", (PyCFunction)(void(*)(void))pysqlite_connect, METH_FASTCALL|METH_KEYWORDS, pysqlite_connect__doc__}, - -static PyObject * -pysqlite_connect_impl(PyObject *module, PyObject *database, double timeout, - int detect_types, PyObject *isolation_level, - int check_same_thread, PyObject *factory, - int cached_statements, int uri); - -static PyObject * -pysqlite_connect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", "uri", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "connect", 0}; - PyObject *argsbuf[8]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - PyObject *database; - double timeout = 5.0; - int detect_types = 0; - PyObject *isolation_level = NULL; - int check_same_thread = 1; - PyObject *factory = (PyObject*)clinic_state()->ConnectionType; - int cached_statements = 128; - int uri = 0; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 8, 0, argsbuf); - if (!args) { - goto exit; - } - if (!PyUnicode_FSConverter(args[0], &database)) { - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - if (args[1]) { - if (PyFloat_CheckExact(args[1])) { - timeout = PyFloat_AS_DOUBLE(args[1]); - } - else - { - timeout = PyFloat_AsDouble(args[1]); - if (timeout == -1.0 && PyErr_Occurred()) { - goto exit; - } - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (args[2]) { - detect_types = _PyLong_AsInt(args[2]); - if (detect_types == -1 && PyErr_Occurred()) { - goto exit; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (args[3]) { - isolation_level = args[3]; - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (args[4]) { - check_same_thread = _PyLong_AsInt(args[4]); - if (check_same_thread == -1 && PyErr_Occurred()) { - goto exit; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (args[5]) { - factory = args[5]; - if (!--noptargs) { - goto skip_optional_pos; - } - } - if (args[6]) { - cached_statements = _PyLong_AsInt(args[6]); - if (cached_statements == -1 && PyErr_Occurred()) { - goto exit; - } - if (!--noptargs) { - goto skip_optional_pos; - } - } - uri = PyObject_IsTrue(args[7]); - if (uri < 0) { - goto exit; - } -skip_optional_pos: - return_value = pysqlite_connect_impl(module, database, timeout, detect_types, isolation_level, check_same_thread, factory, cached_statements, uri); - -exit: - return return_value; -} PyDoc_STRVAR(pysqlite_complete_statement__doc__, "complete_statement($module, /, statement)\n" "--\n" "\n" -"Checks if a string contains a complete SQL statement. Non-standard."); +"Checks if a string contains a complete SQL statement."); #define PYSQLITE_COMPLETE_STATEMENT_METHODDEF \ - {"complete_statement", (PyCFunction)(void(*)(void))pysqlite_complete_statement, METH_FASTCALL|METH_KEYWORDS, pysqlite_complete_statement__doc__}, + {"complete_statement", _PyCFunction_CAST(pysqlite_complete_statement), METH_FASTCALL|METH_KEYWORDS, pysqlite_complete_statement__doc__}, static PyObject * pysqlite_complete_statement_impl(PyObject *module, const char *statement); @@ -130,8 +24,31 @@ static PyObject * pysqlite_complete_statement(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(statement), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"statement", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "complete_statement", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "complete_statement", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; const char *statement; @@ -158,51 +75,14 @@ exit: return return_value; } -PyDoc_STRVAR(pysqlite_enable_shared_cache__doc__, -"enable_shared_cache($module, /, do_enable)\n" -"--\n" -"\n" -"Enable or disable shared cache mode for the calling thread.\n" -"\n" -"Experimental/Non-standard."); - -#define PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF \ - {"enable_shared_cache", (PyCFunction)(void(*)(void))pysqlite_enable_shared_cache, METH_FASTCALL|METH_KEYWORDS, pysqlite_enable_shared_cache__doc__}, - -static PyObject * -pysqlite_enable_shared_cache_impl(PyObject *module, int do_enable); - -static PyObject * -pysqlite_enable_shared_cache(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"do_enable", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "enable_shared_cache", 0}; - PyObject *argsbuf[1]; - int do_enable; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - do_enable = _PyLong_AsInt(args[0]); - if (do_enable == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = pysqlite_enable_shared_cache_impl(module, do_enable); - -exit: - return return_value; -} - PyDoc_STRVAR(pysqlite_register_adapter__doc__, -"register_adapter($module, type, caster, /)\n" +"register_adapter($module, type, adapter, /)\n" "--\n" "\n" -"Registers an adapter with pysqlite\'s adapter registry. Non-standard."); +"Register a function to adapt Python objects to SQLite values."); #define PYSQLITE_REGISTER_ADAPTER_METHODDEF \ - {"register_adapter", (PyCFunction)(void(*)(void))pysqlite_register_adapter, METH_FASTCALL, pysqlite_register_adapter__doc__}, + {"register_adapter", _PyCFunction_CAST(pysqlite_register_adapter), METH_FASTCALL, pysqlite_register_adapter__doc__}, static PyObject * pysqlite_register_adapter_impl(PyObject *module, PyTypeObject *type, @@ -227,13 +107,13 @@ exit: } PyDoc_STRVAR(pysqlite_register_converter__doc__, -"register_converter($module, name, converter, /)\n" +"register_converter($module, typename, converter, /)\n" "--\n" "\n" -"Registers a converter with pysqlite. Non-standard."); +"Register a function to convert SQLite values to Python objects."); #define PYSQLITE_REGISTER_CONVERTER_METHODDEF \ - {"register_converter", (PyCFunction)(void(*)(void))pysqlite_register_converter, METH_FASTCALL, pysqlite_register_converter__doc__}, + {"register_converter", _PyCFunction_CAST(pysqlite_register_converter), METH_FASTCALL, pysqlite_register_converter__doc__}, static PyObject * pysqlite_register_converter_impl(PyObject *module, PyObject *orig_name, @@ -296,10 +176,10 @@ PyDoc_STRVAR(pysqlite_adapt__doc__, "adapt($module, obj, proto=PrepareProtocolType, alt=, /)\n" "--\n" "\n" -"Adapt given object to given protocol. Non-standard."); +"Adapt given object to given protocol."); #define PYSQLITE_ADAPT_METHODDEF \ - {"adapt", (PyCFunction)(void(*)(void))pysqlite_adapt, METH_FASTCALL, pysqlite_adapt__doc__}, + {"adapt", _PyCFunction_CAST(pysqlite_adapt), METH_FASTCALL, pysqlite_adapt__doc__}, static PyObject * pysqlite_adapt_impl(PyObject *module, PyObject *obj, PyObject *proto, @@ -331,4 +211,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=ef03fdbf018d3391 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=39d38c6cfc455042 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/row.c.h b/Modules/_sqlite/clinic/row.c.h index c936ef75fde..c543b398db3 100644 --- a/Modules/_sqlite/clinic/row.c.h +++ b/Modules/_sqlite/clinic/row.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * pysqlite_row_new_impl(PyTypeObject *type, pysqlite_Cursor *cursor, PyObject *data); @@ -54,4 +60,4 @@ pysqlite_row_keys(pysqlite_Row *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_row_keys_impl(self); } -/*[clinic end generated code: output=9d54919dbb4ba5f1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=87b91f234633702e input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 0bc9d1d0eed..4c07d5e0b61 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -26,6 +26,7 @@ #include "connection.h" #include "statement.h" #include "cursor.h" +#include "blob.h" #include "prepare_protocol.h" #include "util.h" @@ -33,6 +34,10 @@ #define HAVE_TRACE_V2 #endif +#if SQLITE_VERSION_NUMBER >= 3025000 +#define HAVE_WINDOW_FUNCTIONS +#endif + static const char * get_isolation_level(const char *level) { @@ -88,28 +93,26 @@ isolation_level_converter(PyObject *str_or_none, const char **result) } static int -clinic_fsconverter(PyObject *pathlike, const char **result) +autocommit_converter(PyObject *val, enum autocommit_mode *result) { - PyObject *bytes = NULL; - Py_ssize_t len; - char *str; - - if (!PyUnicode_FSConverter(pathlike, &bytes)) { - goto error; + if (Py_IsTrue(val)) { + *result = AUTOCOMMIT_ENABLED; + return 1; } - if (PyBytes_AsStringAndSize(bytes, &str, &len) < 0) { - goto error; + if (Py_IsFalse(val)) { + *result = AUTOCOMMIT_DISABLED; + return 1; } - if ((*result = (const char *)PyMem_Malloc(len+1)) == NULL) { - goto error; + if (PyLong_Check(val) && + PyLong_AsLong(val) == LEGACY_TRANSACTION_CONTROL) + { + *result = AUTOCOMMIT_LEGACY; + return 1; } - memcpy((void *)(*result), str, len+1); - Py_DECREF(bytes); - return 1; - -error: - Py_XDECREF(bytes); + PyErr_SetString(PyExc_ValueError, + "autocommit must be True, False, or " + "sqlite3.LEGACY_TRANSACTION_CONTROL"); return 0; } @@ -123,13 +126,12 @@ class _sqlite3.Connection "pysqlite_Connection *" "clinic_state()->ConnectionTyp [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=67369db2faf80891]*/ -_Py_IDENTIFIER(cursor); - static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self); static void free_callback_context(callback_context *ctx); static void set_callback_context(callback_context **ctx_pp, callback_context *ctx); static void connection_close(pysqlite_Connection *self); +PyObject *_pysqlite_query_execute(pysqlite_Cursor *, int, PyObject *, PyObject *); static PyObject * new_statement_cache(pysqlite_Connection *self, pysqlite_state *state, @@ -154,44 +156,70 @@ new_statement_cache(pysqlite_Connection *self, pysqlite_state *state, return res; } -/*[python input] -class FSConverter_converter(CConverter): - type = "const char *" - converter = "clinic_fsconverter" - def converter_init(self): - self.c_default = "NULL" - def cleanup(self): - return f"PyMem_Free((void *){self.name});\n" +static inline int +connection_exec_stmt(pysqlite_Connection *self, const char *sql) +{ + int rc; + Py_BEGIN_ALLOW_THREADS + int len = (int)strlen(sql) + 1; + sqlite3_stmt *stmt; + rc = sqlite3_prepare_v2(self->db, sql, len, &stmt, NULL); + if (rc == SQLITE_OK) { + (void)sqlite3_step(stmt); + rc = sqlite3_finalize(stmt); + } + Py_END_ALLOW_THREADS + if (rc != SQLITE_OK) { + (void)_pysqlite_seterror(self->state, self->db); + return -1; + } + return 0; +} + +/*[python input] class IsolationLevel_converter(CConverter): type = "const char *" converter = "isolation_level_converter" -[python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=be142323885672ab]*/ +class Autocommit_converter(CConverter): + type = "enum autocommit_mode" + converter = "autocommit_converter" +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=bc2aa6c7ba0c5f8f]*/ + +// NB: This needs to be in sync with the sqlite3.connect docstring /*[clinic input] _sqlite3.Connection.__init__ as pysqlite_connection_init - database: FSConverter + database: object timeout: double = 5.0 detect_types: int = 0 isolation_level: IsolationLevel = "" - check_same_thread: bool(accept={int}) = True + check_same_thread: bool = True factory: object(c_default='(PyObject*)clinic_state()->ConnectionType') = ConnectionType cached_statements as cache_size: int = 128 uri: bool = False + * + autocommit: Autocommit(c_default='LEGACY_TRANSACTION_CONTROL') = sqlite3.LEGACY_TRANSACTION_CONTROL [clinic start generated code]*/ static int -pysqlite_connection_init_impl(pysqlite_Connection *self, - const char *database, double timeout, - int detect_types, const char *isolation_level, +pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database, + double timeout, int detect_types, + const char *isolation_level, int check_same_thread, PyObject *factory, - int cache_size, int uri) -/*[clinic end generated code: output=7d640ae1d83abfd4 input=342173993434ba1e]*/ + int cache_size, int uri, + enum autocommit_mode autocommit) +/*[clinic end generated code: output=cba057313ea7712f input=9b0ab6c12f674fa3]*/ { - if (PySys_Audit("sqlite3.connect", "s", database) < 0) { + if (PySys_Audit("sqlite3.connect", "O", database) < 0) { + return -1; + } + + PyObject *bytes; + if (!PyUnicode_FSConverter(database, &bytes)) { return -1; } @@ -206,7 +234,7 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, sqlite3 *db; int rc; Py_BEGIN_ALLOW_THREADS - rc = sqlite3_open_v2(database, &db, + rc = sqlite3_open_v2(PyBytes_AS_STRING(bytes), &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | (uri ? SQLITE_OPEN_URI : 0), NULL); if (rc == SQLITE_OK) { @@ -214,6 +242,7 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, } Py_END_ALLOW_THREADS + Py_DECREF(bytes); if (db == NULL && rc == SQLITE_NOMEM) { PyErr_NoMemory(); return -1; @@ -222,20 +251,27 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, pysqlite_state *state = pysqlite_get_state_by_type(Py_TYPE(self)); if (rc != SQLITE_OK) { _pysqlite_seterror(state, db); - return -1; + goto error; } // Create LRU statement cache; returns a new reference. PyObject *statement_cache = new_statement_cache(self, state, cache_size); if (statement_cache == NULL) { - return -1; + goto error; } - // Create list of weak references to cursors. + /* Create lists of weak references to cursors and blobs */ PyObject *cursors = PyList_New(0); if (cursors == NULL) { Py_DECREF(statement_cache); - return -1; + goto error; + } + + PyObject *blobs = PyList_New(0); + if (blobs == NULL) { + Py_DECREF(statement_cache); + Py_DECREF(cursors); + goto error; } // Init connection state members. @@ -243,10 +279,12 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, self->state = state; self->detect_types = detect_types; self->isolation_level = isolation_level; + self->autocommit = autocommit; self->check_same_thread = check_same_thread; self->thread_ident = PyThread_get_thread_ident(); self->statement_cache = statement_cache; self->cursors = cursors; + self->blobs = blobs; self->created_cursors = 0; self->row_factory = Py_NewRef(Py_None); self->text_factory = Py_NewRef(&PyUnicode_Type); @@ -267,33 +305,22 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, self->NotSupportedError = state->NotSupportedError; if (PySys_Audit("sqlite3.connect/handle", "O", self) < 0) { - return -1; + return -1; // Don't goto error; at this point, dealloc will clean up. } self->initialized = 1; + + if (autocommit == AUTOCOMMIT_DISABLED) { + (void)connection_exec_stmt(self, "BEGIN"); + } return 0; -} -static void -pysqlite_do_all_statements(pysqlite_Connection *self) -{ - // Reset all statements - sqlite3_stmt *stmt = NULL; - while ((stmt = sqlite3_next_stmt(self->db, stmt))) { - if (sqlite3_stmt_busy(stmt)) { - (void)sqlite3_reset(stmt); - } - } - - // Reset all cursors - for (int i = 0; i < PyList_Size(self->cursors); i++) { - PyObject *weakref = PyList_GetItem(self->cursors, i); - PyObject *object = PyWeakref_GetObject(weakref); - if (object != Py_None) { - pysqlite_Cursor *cursor = (pysqlite_Cursor *)object; - cursor->reset = 1; - } - } +error: + // There are no statements or other SQLite objects attached to the + // database, so sqlite3_close() should always return SQLITE_OK. + rc = sqlite3_close(db); + assert(rc == SQLITE_OK); + return -1; } #define VISIT_CALLBACK_CONTEXT(ctx) \ @@ -310,6 +337,7 @@ connection_traverse(pysqlite_Connection *self, visitproc visit, void *arg) Py_VISIT(Py_TYPE(self)); Py_VISIT(self->statement_cache); Py_VISIT(self->cursors); + Py_VISIT(self->blobs); Py_VISIT(self->row_factory); Py_VISIT(self->text_factory); VISIT_CALLBACK_CONTEXT(self->trace_ctx); @@ -333,6 +361,7 @@ connection_clear(pysqlite_Connection *self) { Py_CLEAR(self->statement_cache); Py_CLEAR(self->cursors); + Py_CLEAR(self->blobs); Py_CLEAR(self->row_factory); Py_CLEAR(self->text_factory); clear_callback_context(self->trace_ctx); @@ -349,10 +378,33 @@ free_callback_contexts(pysqlite_Connection *self) set_callback_context(&self->authorizer_ctx, NULL); } +static void +remove_callbacks(sqlite3 *db) +{ +#ifdef HAVE_TRACE_V2 + sqlite3_trace_v2(db, SQLITE_TRACE_STMT, 0, 0); +#else + sqlite3_trace(db, 0, (void*)0); +#endif + sqlite3_progress_handler(db, 0, 0, (void *)0); + (void)sqlite3_set_authorizer(db, NULL, NULL); +} + static void connection_close(pysqlite_Connection *self) { if (self->db) { + if (self->autocommit == AUTOCOMMIT_DISABLED && + !sqlite3_get_autocommit(self->db)) + { + /* If close is implicitly called as a result of interpreter + * tear-down, we must not call back into Python. */ + if (_Py_IsFinalizing()) { + remove_callbacks(self->db); + } + (void)connection_exec_stmt(self, "ROLLBACK"); + } + free_callback_contexts(self); sqlite3 *db = self->db; @@ -379,32 +431,6 @@ connection_dealloc(pysqlite_Connection *self) Py_DECREF(tp); } -/* - * Registers a cursor with the connection. - * - * 0 => error; 1 => ok - */ -int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObject* cursor) -{ - PyObject* weakref; - - weakref = PyWeakref_NewRef((PyObject*)cursor, NULL); - if (!weakref) { - goto error; - } - - if (PyList_Append(connection->cursors, weakref) != 0) { - Py_CLEAR(weakref); - goto error; - } - - Py_DECREF(weakref); - - return 1; -error: - return 0; -} - /*[clinic input] _sqlite3.Connection.cursor as pysqlite_connection_cursor @@ -448,15 +474,91 @@ pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory) return cursor; } +/*[clinic input] +_sqlite3.Connection.blobopen as blobopen + + table: str + Table name. + column as col: str + Column name. + row: int + Row index. + / + * + readonly: bool = False + Open the BLOB without write permissions. + name: str = "main" + Database name. + +Open and return a BLOB object. +[clinic start generated code]*/ + +static PyObject * +blobopen_impl(pysqlite_Connection *self, const char *table, const char *col, + int row, int readonly, const char *name) +/*[clinic end generated code: output=0c8e2e58516d0b5c input=fa73c83aa7a7ddee]*/ +{ + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + + int rc; + sqlite3_blob *blob; + + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_blob_open(self->db, name, table, col, row, !readonly, &blob); + Py_END_ALLOW_THREADS + + if (rc == SQLITE_MISUSE) { + PyErr_Format(self->state->InterfaceError, sqlite3_errstr(rc)); + return NULL; + } + else if (rc != SQLITE_OK) { + _pysqlite_seterror(self->state, self->db); + return NULL; + } + + pysqlite_Blob *obj = PyObject_GC_New(pysqlite_Blob, self->state->BlobType); + if (obj == NULL) { + goto error; + } + + obj->connection = (pysqlite_Connection *)Py_NewRef(self); + obj->blob = blob; + obj->offset = 0; + obj->in_weakreflist = NULL; + + PyObject_GC_Track(obj); + + // Add our blob to connection blobs list + PyObject *weakref = PyWeakref_NewRef((PyObject *)obj, NULL); + if (weakref == NULL) { + goto error; + } + rc = PyList_Append(self->blobs, weakref); + Py_DECREF(weakref); + if (rc < 0) { + goto error; + } + + return (PyObject *)obj; + +error: + Py_XDECREF(obj); + return NULL; +} + /*[clinic input] _sqlite3.Connection.close as pysqlite_connection_close -Closes the connection. +Close the database connection. + +Any pending transaction is not committed implicitly. [clinic start generated code]*/ static PyObject * pysqlite_connection_close_impl(pysqlite_Connection *self) -/*[clinic end generated code: output=a546a0da212c9b97 input=3d58064bbffaa3d3]*/ +/*[clinic end generated code: output=a546a0da212c9b97 input=b3ed5b74f6fefc06]*/ { if (!pysqlite_check_thread(self)) { return NULL; @@ -470,6 +572,7 @@ pysqlite_connection_close_impl(pysqlite_Connection *self) return NULL; } + pysqlite_close_all_blobs(self); Py_CLEAR(self->statement_cache); connection_close(self); @@ -502,73 +605,68 @@ int pysqlite_check_connection(pysqlite_Connection* con) /*[clinic input] _sqlite3.Connection.commit as pysqlite_connection_commit -Commit the current transaction. +Commit any pending transaction to the database. + +If there is no open transaction, this method is a no-op. [clinic start generated code]*/ static PyObject * pysqlite_connection_commit_impl(pysqlite_Connection *self) -/*[clinic end generated code: output=3da45579e89407f2 input=39c12c04dda276a8]*/ +/*[clinic end generated code: output=3da45579e89407f2 input=c8793c97c3446065]*/ { if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } - if (!sqlite3_get_autocommit(self->db)) { - int rc; - - Py_BEGIN_ALLOW_THREADS - sqlite3_stmt *statement; - rc = sqlite3_prepare_v2(self->db, "COMMIT", 7, &statement, NULL); - if (rc == SQLITE_OK) { - (void)sqlite3_step(statement); - rc = sqlite3_finalize(statement); + if (self->autocommit == AUTOCOMMIT_LEGACY) { + if (!sqlite3_get_autocommit(self->db)) { + if (connection_exec_stmt(self, "COMMIT") < 0) { + return NULL; + } } - Py_END_ALLOW_THREADS - - if (rc != SQLITE_OK) { - (void)_pysqlite_seterror(self->state, self->db); + } + else if (self->autocommit == AUTOCOMMIT_DISABLED) { + if (connection_exec_stmt(self, "COMMIT") < 0) { + return NULL; + } + if (connection_exec_stmt(self, "BEGIN") < 0) { return NULL; } } - Py_RETURN_NONE; } /*[clinic input] _sqlite3.Connection.rollback as pysqlite_connection_rollback -Roll back the current transaction. +Roll back to the start of any pending transaction. + +If there is no open transaction, this method is a no-op. [clinic start generated code]*/ static PyObject * pysqlite_connection_rollback_impl(pysqlite_Connection *self) -/*[clinic end generated code: output=b66fa0d43e7ef305 input=12d4e8d068942830]*/ +/*[clinic end generated code: output=b66fa0d43e7ef305 input=7f60a2f1076f16b3]*/ { if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; } - if (!sqlite3_get_autocommit(self->db)) { - pysqlite_do_all_statements(self); - - int rc; - - Py_BEGIN_ALLOW_THREADS - sqlite3_stmt *statement; - rc = sqlite3_prepare_v2(self->db, "ROLLBACK", 9, &statement, NULL); - if (rc == SQLITE_OK) { - (void)sqlite3_step(statement); - rc = sqlite3_finalize(statement); + if (self->autocommit == AUTOCOMMIT_LEGACY) { + if (!sqlite3_get_autocommit(self->db)) { + if (connection_exec_stmt(self, "ROLLBACK") < 0) { + return NULL; + } } - Py_END_ALLOW_THREADS - - if (rc != SQLITE_OK) { - (void)_pysqlite_seterror(self->state, self->db); + } + else if (self->autocommit == AUTOCOMMIT_DISABLED) { + if (connection_exec_stmt(self, "ROLLBACK") < 0) { + return NULL; + } + if (connection_exec_stmt(self, "BEGIN") < 0) { return NULL; } - } - Py_RETURN_NONE; } @@ -583,7 +681,11 @@ _pysqlite_set_result(sqlite3_context* context, PyObject* py_val) return -1; sqlite3_result_int64(context, value); } else if (PyFloat_Check(py_val)) { - sqlite3_result_double(context, PyFloat_AsDouble(py_val)); + double value = PyFloat_AsDouble(py_val); + if (value == -1 && PyErr_Occurred()) { + return -1; + } + sqlite3_result_double(context, value); } else if (PyUnicode_Check(py_val)) { Py_ssize_t sz; const char *str = PyUnicode_AsUTF8AndSize(py_val, &sz); @@ -599,8 +701,6 @@ _pysqlite_set_result(sqlite3_context* context, PyObject* py_val) } else if (PyObject_CheckBuffer(py_val)) { Py_buffer view; if (PyObject_GetBuffer(py_val, &view, PyBUF_SIMPLE) != 0) { - PyErr_SetString(PyExc_ValueError, - "could not convert BLOB to buffer"); return -1; } if (view.len > INT_MAX) { @@ -612,6 +712,11 @@ _pysqlite_set_result(sqlite3_context* context, PyObject* py_val) sqlite3_result_blob(context, view.buf, (int)view.len, SQLITE_TRANSIENT); PyBuffer_Release(&view); } else { + callback_context *ctx = (callback_context *)sqlite3_user_data(context); + PyErr_Format(ctx->state->ProgrammingError, + "User-defined functions cannot return '%s' values to " + "SQLite", + Py_TYPE(py_val)->tp_name); return -1; } return 0; @@ -691,7 +796,7 @@ print_or_clear_traceback(callback_context *ctx) assert(ctx != NULL); assert(ctx->state != NULL); if (ctx->state->enable_callback_tracebacks) { - PyErr_Print(); + PyErr_WriteUnraisable(ctx->callable); } else { PyErr_Clear(); @@ -755,11 +860,11 @@ step_callback(sqlite3_context *context, int argc, sqlite3_value **params) PyObject** aggregate_instance; PyObject* stepmethod = NULL; - aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*)); + callback_context *ctx = (callback_context *)sqlite3_user_data(context); + assert(ctx != NULL); + aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*)); if (*aggregate_instance == NULL) { - callback_context *ctx = (callback_context *)sqlite3_user_data(context); - assert(ctx != NULL); *aggregate_instance = PyObject_CallNoArgs(ctx->callable); if (!*aggregate_instance) { set_sqlite_error(context, @@ -768,8 +873,10 @@ step_callback(sqlite3_context *context, int argc, sqlite3_value **params) } } - stepmethod = PyObject_GetAttrString(*aggregate_instance, "step"); + stepmethod = PyObject_GetAttr(*aggregate_instance, ctx->state->str_step); if (!stepmethod) { + set_sqlite_error(context, + "user-defined aggregate's 'step' method not defined"); goto error; } @@ -800,7 +907,6 @@ final_callback(sqlite3_context *context) PyObject* function_result; PyObject** aggregate_instance; - _Py_IDENTIFIER(finalize); int ok; PyObject *exception, *value, *tb; @@ -816,11 +922,13 @@ final_callback(sqlite3_context *context) goto error; } - /* Keep the exception (if any) of the last call to step() */ + // Keep the exception (if any) of the last call to step, value, or inverse PyErr_Fetch(&exception, &value, &tb); - function_result = _PyObject_CallMethodIdNoArgs(*aggregate_instance, &PyId_finalize); - + callback_context *ctx = (callback_context *)sqlite3_user_data(context); + assert(ctx != NULL); + function_result = PyObject_CallMethodNoArgs(*aggregate_instance, + ctx->state->str_finalize); Py_DECREF(*aggregate_instance); ok = 0; @@ -829,13 +937,20 @@ final_callback(sqlite3_context *context) Py_DECREF(function_result); } if (!ok) { - set_sqlite_error(context, - "user-defined aggregate's 'finalize' method raised error"); - } + int attr_err = PyErr_ExceptionMatches(PyExc_AttributeError); + _PyErr_ChainExceptions(exception, value, tb); - /* Restore the exception (if any) of the last call to step(), - but clear also the current exception if finalize() failed */ - PyErr_Restore(exception, value, tb); + /* Note: contrary to the step, value, and inverse callbacks, SQLite + * does _not_, as of SQLite 3.38.0, propagate errors to sqlite3_step() + * from the finalize callback. This implies that execute*() will not + * raise OperationalError, as it normally would. */ + set_sqlite_error(context, attr_err + ? "user-defined aggregate's 'finalize' method not defined" + : "user-defined aggregate's 'finalize' method raised error"); + } + else { + PyErr_Restore(exception, value, tb); + } error: PyGILState_Release(threadstate); @@ -934,7 +1049,7 @@ _sqlite3.Connection.create_function as pysqlite_connection_create_function * deterministic: bool = False -Creates a new function. Non-standard. +Creates a new function. [clinic start generated code]*/ static PyObject * @@ -942,7 +1057,7 @@ pysqlite_connection_create_function_impl(pysqlite_Connection *self, PyTypeObject *cls, const char *name, int narg, PyObject *func, int deterministic) -/*[clinic end generated code: output=8a811529287ad240 input=f0f99754bfeafd8d]*/ +/*[clinic end generated code: output=8a811529287ad240 input=b3e8e1d8ddaffbef]*/ { int rc; int flags = SQLITE_UTF8; @@ -983,6 +1098,159 @@ pysqlite_connection_create_function_impl(pysqlite_Connection *self, Py_RETURN_NONE; } +#ifdef HAVE_WINDOW_FUNCTIONS +/* + * Regarding the 'inverse' aggregate callback: + * This method is only required by window aggregate functions, not + * ordinary aggregate function implementations. It is invoked to remove + * a row from the current window. The function arguments, if any, + * correspond to the row being removed. + */ +static void +inverse_callback(sqlite3_context *context, int argc, sqlite3_value **params) +{ + PyGILState_STATE gilstate = PyGILState_Ensure(); + + callback_context *ctx = (callback_context *)sqlite3_user_data(context); + assert(ctx != NULL); + + int size = sizeof(PyObject *); + PyObject **cls = (PyObject **)sqlite3_aggregate_context(context, size); + assert(cls != NULL); + assert(*cls != NULL); + + PyObject *method = PyObject_GetAttr(*cls, ctx->state->str_inverse); + if (method == NULL) { + set_sqlite_error(context, + "user-defined aggregate's 'inverse' method not defined"); + goto exit; + } + + PyObject *args = _pysqlite_build_py_params(context, argc, params); + if (args == NULL) { + set_sqlite_error(context, + "unable to build arguments for user-defined aggregate's " + "'inverse' method"); + goto exit; + } + + PyObject *res = PyObject_CallObject(method, args); + Py_DECREF(args); + if (res == NULL) { + set_sqlite_error(context, + "user-defined aggregate's 'inverse' method raised error"); + goto exit; + } + Py_DECREF(res); + +exit: + Py_XDECREF(method); + PyGILState_Release(gilstate); +} + +/* + * Regarding the 'value' aggregate callback: + * This method is only required by window aggregate functions, not + * ordinary aggregate function implementations. It is invoked to return + * the current value of the aggregate. + */ +static void +value_callback(sqlite3_context *context) +{ + PyGILState_STATE gilstate = PyGILState_Ensure(); + + callback_context *ctx = (callback_context *)sqlite3_user_data(context); + assert(ctx != NULL); + + int size = sizeof(PyObject *); + PyObject **cls = (PyObject **)sqlite3_aggregate_context(context, size); + assert(cls != NULL); + assert(*cls != NULL); + + PyObject *res = PyObject_CallMethodNoArgs(*cls, ctx->state->str_value); + if (res == NULL) { + int attr_err = PyErr_ExceptionMatches(PyExc_AttributeError); + set_sqlite_error(context, attr_err + ? "user-defined aggregate's 'value' method not defined" + : "user-defined aggregate's 'value' method raised error"); + } + else { + int rc = _pysqlite_set_result(context, res); + Py_DECREF(res); + if (rc < 0) { + set_sqlite_error(context, + "unable to set result from user-defined aggregate's " + "'value' method"); + } + } + + PyGILState_Release(gilstate); +} + +/*[clinic input] +_sqlite3.Connection.create_window_function as create_window_function + + cls: defining_class + name: str + The name of the SQL aggregate window function to be created or + redefined. + num_params: int + The number of arguments the step and inverse methods takes. + aggregate_class: object + A class with step(), finalize(), value(), and inverse() methods. + Set to None to clear the window function. + / + +Creates or redefines an aggregate window function. Non-standard. +[clinic start generated code]*/ + +static PyObject * +create_window_function_impl(pysqlite_Connection *self, PyTypeObject *cls, + const char *name, int num_params, + PyObject *aggregate_class) +/*[clinic end generated code: output=5332cd9464522235 input=46d57a54225b5228]*/ +{ + if (sqlite3_libversion_number() < 3025000) { + PyErr_SetString(self->NotSupportedError, + "create_window_function() requires " + "SQLite 3.25.0 or higher"); + return NULL; + } + + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + + int flags = SQLITE_UTF8; + int rc; + if (Py_IsNone(aggregate_class)) { + rc = sqlite3_create_window_function(self->db, name, num_params, flags, + 0, 0, 0, 0, 0, 0); + } + else { + callback_context *ctx = create_callback_context(cls, aggregate_class); + if (ctx == NULL) { + return NULL; + } + rc = sqlite3_create_window_function(self->db, name, num_params, flags, + ctx, + &step_callback, + &final_callback, + &value_callback, + &inverse_callback, + &destructor_callback); + } + + if (rc != SQLITE_OK) { + // Errors are not set on the database connection, so we cannot + // use _pysqlite_seterror(). + PyErr_SetString(self->ProgrammingError, sqlite3_errstr(rc)); + return NULL; + } + Py_RETURN_NONE; +} +#endif + /*[clinic input] _sqlite3.Connection.create_aggregate as pysqlite_connection_create_aggregate @@ -992,7 +1260,7 @@ _sqlite3.Connection.create_aggregate as pysqlite_connection_create_aggregate n_arg: int aggregate_class: object -Creates a new aggregate. Non-standard. +Creates a new aggregate. [clinic start generated code]*/ static PyObject * @@ -1000,7 +1268,7 @@ pysqlite_connection_create_aggregate_impl(pysqlite_Connection *self, PyTypeObject *cls, const char *name, int n_arg, PyObject *aggregate_class) -/*[clinic end generated code: output=1b02d0f0aec7ff96 input=bd527067e6c2e33f]*/ +/*[clinic end generated code: output=1b02d0f0aec7ff96 input=68a2a26366d4c686]*/ { int rc; @@ -1097,11 +1365,10 @@ progress_callback(void *ctx) * to ensure future compatibility. */ static int -trace_callback(unsigned int type, void *ctx, void *prepared_statement, - void *statement_string) +trace_callback(unsigned int type, void *ctx, void *stmt, void *sql) #else static void -trace_callback(void *ctx, const char *statement_string) +trace_callback(void *ctx, const char *sql) #endif { #ifdef HAVE_TRACE_V2 @@ -1112,24 +1379,51 @@ trace_callback(void *ctx, const char *statement_string) PyGILState_STATE gilstate = PyGILState_Ensure(); - PyObject *py_statement = NULL; - PyObject *ret = NULL; - py_statement = PyUnicode_DecodeUTF8(statement_string, - strlen(statement_string), "replace"); assert(ctx != NULL); - if (py_statement) { - PyObject *callable = ((callback_context *)ctx)->callable; - ret = PyObject_CallOneArg(callable, py_statement); - Py_DECREF(py_statement); - } + pysqlite_state *state = ((callback_context *)ctx)->state; + assert(state != NULL); - if (ret) { - Py_DECREF(ret); + PyObject *py_statement = NULL; +#ifdef HAVE_TRACE_V2 + const char *expanded_sql = sqlite3_expanded_sql((sqlite3_stmt *)stmt); + if (expanded_sql == NULL) { + sqlite3 *db = sqlite3_db_handle((sqlite3_stmt *)stmt); + if (sqlite3_errcode(db) == SQLITE_NOMEM) { + (void)PyErr_NoMemory(); + goto exit; + } + + PyErr_SetString(state->DataError, + "Expanded SQL string exceeds the maximum string length"); + print_or_clear_traceback((callback_context *)ctx); + + // Fall back to unexpanded sql + py_statement = PyUnicode_FromString((const char *)sql); } else { - print_or_clear_traceback(ctx); + py_statement = PyUnicode_FromString(expanded_sql); + sqlite3_free((void *)expanded_sql); + } +#else + if (sql == NULL) { + PyErr_SetString(state->DataError, + "Expanded SQL string exceeds the maximum string length"); + print_or_clear_traceback((callback_context *)ctx); + goto exit; + } + py_statement = PyUnicode_FromString(sql); +#endif + if (py_statement) { + PyObject *callable = ((callback_context *)ctx)->callable; + PyObject *ret = PyObject_CallOneArg(callable, py_statement); + Py_DECREF(py_statement); + Py_XDECREF(ret); + } + if (PyErr_Occurred()) { + print_or_clear_traceback((callback_context *)ctx); } +exit: PyGILState_Release(gilstate); #ifdef HAVE_TRACE_V2 return 0; @@ -1143,14 +1437,14 @@ _sqlite3.Connection.set_authorizer as pysqlite_connection_set_authorizer / authorizer_callback as callable: object -Sets authorizer callback. Non-standard. +Sets authorizer callback. [clinic start generated code]*/ static PyObject * pysqlite_connection_set_authorizer_impl(pysqlite_Connection *self, PyTypeObject *cls, PyObject *callable) -/*[clinic end generated code: output=75fa60114fc971c3 input=9f3e90d3d642c4a0]*/ +/*[clinic end generated code: output=75fa60114fc971c3 input=605d32ba92dd3eca]*/ { if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; @@ -1186,14 +1480,14 @@ _sqlite3.Connection.set_progress_handler as pysqlite_connection_set_progress_han progress_handler as callable: object n: int -Sets progress handler callback. Non-standard. +Sets progress handler callback. [clinic start generated code]*/ static PyObject * pysqlite_connection_set_progress_handler_impl(pysqlite_Connection *self, PyTypeObject *cls, PyObject *callable, int n) -/*[clinic end generated code: output=0739957fd8034a50 input=83e8dcbb4ce183f7]*/ +/*[clinic end generated code: output=0739957fd8034a50 input=f7c1837984bd86db]*/ { if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; @@ -1223,15 +1517,13 @@ _sqlite3.Connection.set_trace_callback as pysqlite_connection_set_trace_callback trace_callback as callable: object Sets a trace callback called for each SQL statement (passed as unicode). - -Non-standard. [clinic start generated code]*/ static PyObject * pysqlite_connection_set_trace_callback_impl(pysqlite_Connection *self, PyTypeObject *cls, PyObject *callable) -/*[clinic end generated code: output=d91048c03bfcee05 input=96f03acec3ec8044]*/ +/*[clinic end generated code: output=d91048c03bfcee05 input=351a94210c5f81bb]*/ { if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; @@ -1272,16 +1564,16 @@ pysqlite_connection_set_trace_callback_impl(pysqlite_Connection *self, /*[clinic input] _sqlite3.Connection.enable_load_extension as pysqlite_connection_enable_load_extension - enable as onoff: bool(accept={int}) + enable as onoff: bool / -Enable dynamic loading of SQLite extension modules. Non-standard. +Enable dynamic loading of SQLite extension modules. [clinic start generated code]*/ static PyObject * pysqlite_connection_enable_load_extension_impl(pysqlite_Connection *self, int onoff) -/*[clinic end generated code: output=9cac37190d388baf input=5c0da5b121121cbc]*/ +/*[clinic end generated code: output=9cac37190d388baf input=2a1e87931486380f]*/ { int rc; @@ -1311,13 +1603,13 @@ _sqlite3.Connection.load_extension as pysqlite_connection_load_extension name as extension_name: str / -Load SQLite extension module. Non-standard. +Load SQLite extension module. [clinic start generated code]*/ static PyObject * pysqlite_connection_load_extension_impl(pysqlite_Connection *self, const char *extension_name) -/*[clinic end generated code: output=47eb1d7312bc97a7 input=0b711574560db9fc]*/ +/*[clinic end generated code: output=47eb1d7312bc97a7 input=edd507389d89d621]*/ { int rc; char* errmsg; @@ -1370,9 +1662,8 @@ static PyObject* pysqlite_connection_get_total_changes(pysqlite_Connection* self { if (!pysqlite_check_connection(self)) { return NULL; - } else { - return Py_BuildValue("i", sqlite3_total_changes(self->db)); } + return PyLong_FromLong(sqlite3_total_changes(self->db)); } static PyObject* pysqlite_connection_get_in_transaction(pysqlite_Connection* self, void* unused) @@ -1442,24 +1733,22 @@ _sqlite3.Connection.execute as pysqlite_connection_execute parameters: object = NULL / -Executes a SQL statement. Non-standard. +Executes an SQL statement. [clinic start generated code]*/ static PyObject * pysqlite_connection_execute_impl(pysqlite_Connection *self, PyObject *sql, PyObject *parameters) -/*[clinic end generated code: output=5be05ae01ee17ee4 input=fbd17c75c7140271]*/ +/*[clinic end generated code: output=5be05ae01ee17ee4 input=27aa7792681ddba2]*/ { - _Py_IDENTIFIER(execute); - PyObject* cursor = 0; PyObject* result = 0; - cursor = _PyObject_CallMethodIdNoArgs((PyObject*)self, &PyId_cursor); + PyObject *cursor = pysqlite_connection_cursor_impl(self, NULL); if (!cursor) { goto error; } - result = _PyObject_CallMethodIdObjArgs(cursor, &PyId_execute, sql, parameters, NULL); + result = _pysqlite_query_execute((pysqlite_Cursor *)cursor, 0, sql, parameters); if (!result) { Py_CLEAR(cursor); } @@ -1477,25 +1766,22 @@ _sqlite3.Connection.executemany as pysqlite_connection_executemany parameters: object / -Repeatedly executes a SQL statement. Non-standard. +Repeatedly executes an SQL statement. [clinic start generated code]*/ static PyObject * pysqlite_connection_executemany_impl(pysqlite_Connection *self, PyObject *sql, PyObject *parameters) -/*[clinic end generated code: output=776cd2fd20bfe71f input=4feab80659ffc82b]*/ +/*[clinic end generated code: output=776cd2fd20bfe71f input=495be76551d525db]*/ { - _Py_IDENTIFIER(executemany); - PyObject* cursor = 0; PyObject* result = 0; - cursor = _PyObject_CallMethodIdNoArgs((PyObject*)self, &PyId_cursor); + PyObject *cursor = pysqlite_connection_cursor_impl(self, NULL); if (!cursor) { goto error; } - result = _PyObject_CallMethodIdObjArgs(cursor, &PyId_executemany, sql, - parameters, NULL); + result = _pysqlite_query_execute((pysqlite_Cursor *)cursor, 1, sql, parameters); if (!result) { Py_CLEAR(cursor); } @@ -1512,25 +1798,23 @@ _sqlite3.Connection.executescript as pysqlite_connection_executescript sql_script as script_obj: object / -Executes multiple SQL statements at once. Non-standard. +Executes multiple SQL statements at once. [clinic start generated code]*/ static PyObject * pysqlite_connection_executescript(pysqlite_Connection *self, PyObject *script_obj) -/*[clinic end generated code: output=4c4f9d77aa0ae37d input=b27ae5c24ffb8b43]*/ +/*[clinic end generated code: output=4c4f9d77aa0ae37d input=f6e5f1ccfa313db4]*/ { - _Py_IDENTIFIER(executescript); - PyObject* cursor = 0; PyObject* result = 0; - cursor = _PyObject_CallMethodIdNoArgs((PyObject*)self, &PyId_cursor); + PyObject *cursor = pysqlite_connection_cursor_impl(self, NULL); if (!cursor) { goto error; } - result = _PyObject_CallMethodIdObjArgs(cursor, &PyId_executescript, - script_obj, NULL); + PyObject *meth = self->state->str_executescript; // borrowed ref. + result = PyObject_CallMethodObjArgs(cursor, meth, script_obj, NULL); if (!result) { Py_CLEAR(cursor); } @@ -1601,12 +1885,12 @@ finally: /*[clinic input] _sqlite3.Connection.interrupt as pysqlite_connection_interrupt -Abort any pending database operation. Non-standard. +Abort any pending database operation. [clinic start generated code]*/ static PyObject * pysqlite_connection_interrupt_impl(pysqlite_Connection *self) -/*[clinic end generated code: output=f193204bc9e70b47 input=4bd0ad083cf93aa7]*/ +/*[clinic end generated code: output=f193204bc9e70b47 input=75ad03ade7012859]*/ { PyObject* retval = NULL; @@ -1630,47 +1914,27 @@ finally: _sqlite3.Connection.iterdump as pysqlite_connection_iterdump Returns iterator to the dump of the database in an SQL text format. - -Non-standard. [clinic start generated code]*/ static PyObject * pysqlite_connection_iterdump_impl(pysqlite_Connection *self) -/*[clinic end generated code: output=586997aaf9808768 input=53bc907cb5eedb85]*/ +/*[clinic end generated code: output=586997aaf9808768 input=1911ca756066da89]*/ { - _Py_IDENTIFIER(_iterdump); - PyObject* retval = NULL; - PyObject* module = NULL; - PyObject* module_dict; - PyObject* pyfn_iterdump; - if (!pysqlite_check_connection(self)) { - goto finally; + return NULL; } - module = PyImport_ImportModule(MODULE_NAME ".dump"); - if (!module) { - goto finally; - } - - module_dict = PyModule_GetDict(module); - if (!module_dict) { - goto finally; - } - - pyfn_iterdump = _PyDict_GetItemIdWithError(module_dict, &PyId__iterdump); - if (!pyfn_iterdump) { + PyObject *iterdump = _PyImport_GetModuleAttrString(MODULE_NAME ".dump", "_iterdump"); + if (!iterdump) { if (!PyErr_Occurred()) { PyErr_SetString(self->OperationalError, "Failed to obtain _iterdump() reference"); } - goto finally; + return NULL; } - retval = PyObject_CallOneArg(pyfn_iterdump, (PyObject *)self); - -finally: - Py_XDECREF(module); + PyObject *retval = PyObject_CallOneArg(iterdump, (PyObject *)self); + Py_DECREF(iterdump); return retval; } @@ -1684,7 +1948,7 @@ _sqlite3.Connection.backup as pysqlite_connection_backup name: str = "main" sleep: double = 0.250 -Makes a backup of the database. Non-standard. +Makes a backup of the database. [clinic start generated code]*/ static PyObject * @@ -1692,7 +1956,7 @@ pysqlite_connection_backup_impl(pysqlite_Connection *self, pysqlite_Connection *target, int pages, PyObject *progress, const char *name, double sleep) -/*[clinic end generated code: output=306a3e6a38c36334 input=c759627ab1ad46ff]*/ +/*[clinic end generated code: output=306a3e6a38c36334 input=c6519d0f59d0fd7f]*/ { int rc; int sleep_ms = (int)(sleep * 1000.0); @@ -1790,7 +2054,7 @@ _sqlite3.Connection.create_collation as pysqlite_connection_create_collation callback as callable: object / -Creates a collation function. Non-standard. +Creates a collation function. [clinic start generated code]*/ static PyObject * @@ -1798,7 +2062,7 @@ pysqlite_connection_create_collation_impl(pysqlite_Connection *self, PyTypeObject *cls, const char *name, PyObject *callable) -/*[clinic end generated code: output=32d339e97869c378 input=fee2c8e5708602ad]*/ +/*[clinic end generated code: output=32d339e97869c378 input=f67ecd2e31e61ad3]*/ { if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; @@ -1840,6 +2104,125 @@ pysqlite_connection_create_collation_impl(pysqlite_Connection *self, Py_RETURN_NONE; } +#ifdef PY_SQLITE_HAVE_SERIALIZE +/*[clinic input] +_sqlite3.Connection.serialize as serialize + + * + name: str = "main" + Which database to serialize. + +Serialize a database into a byte string. + +For an ordinary on-disk database file, the serialization is just a copy of the +disk file. For an in-memory database or a "temp" database, the serialization is +the same sequence of bytes which would be written to disk if that database +were backed up to disk. +[clinic start generated code]*/ + +static PyObject * +serialize_impl(pysqlite_Connection *self, const char *name) +/*[clinic end generated code: output=97342b0e55239dd3 input=d2eb5194a65abe2b]*/ +{ + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + + /* If SQLite has a contiguous memory representation of the database, we can + * avoid memory allocations, so we try with the no-copy flag first. + */ + sqlite3_int64 size; + unsigned int flags = SQLITE_SERIALIZE_NOCOPY; + const char *data; + + Py_BEGIN_ALLOW_THREADS + data = (const char *)sqlite3_serialize(self->db, name, &size, flags); + if (data == NULL) { + flags &= ~SQLITE_SERIALIZE_NOCOPY; + data = (const char *)sqlite3_serialize(self->db, name, &size, flags); + } + Py_END_ALLOW_THREADS + + if (data == NULL) { + PyErr_Format(self->OperationalError, "unable to serialize '%s'", + name); + return NULL; + } + PyObject *res = PyBytes_FromStringAndSize(data, (Py_ssize_t)size); + if (!(flags & SQLITE_SERIALIZE_NOCOPY)) { + sqlite3_free((void *)data); + } + return res; +} + +/*[clinic input] +_sqlite3.Connection.deserialize as deserialize + + data: Py_buffer(accept={buffer, str}) + The serialized database content. + / + * + name: str = "main" + Which database to reopen with the deserialization. + +Load a serialized database. + +The deserialize interface causes the database connection to disconnect from the +target database, and then reopen it as an in-memory database based on the given +serialized data. + +The deserialize interface will fail with SQLITE_BUSY if the database is +currently in a read transaction or is involved in a backup operation. +[clinic start generated code]*/ + +static PyObject * +deserialize_impl(pysqlite_Connection *self, Py_buffer *data, + const char *name) +/*[clinic end generated code: output=e394c798b98bad89 input=1be4ca1faacf28f2]*/ +{ + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + + /* Transfer ownership of the buffer to SQLite: + * - Move buffer from Py to SQLite + * - Tell SQLite to free buffer memory + * - Tell SQLite that it is permitted to grow the resulting database + * + * Make sure we don't overflow sqlite3_deserialize(); it accepts a signed + * 64-bit int as its data size argument. + * + * We can safely use sqlite3_malloc64 here, since it was introduced before + * the serialize APIs. + */ + if (data->len > 9223372036854775807) { // (1 << 63) - 1 + PyErr_SetString(PyExc_OverflowError, "'data' is too large"); + return NULL; + } + + sqlite3_int64 size = (sqlite3_int64)data->len; + unsigned char *buf = sqlite3_malloc64(size); + if (buf == NULL) { + return PyErr_NoMemory(); + } + + const unsigned int flags = SQLITE_DESERIALIZE_FREEONCLOSE | + SQLITE_DESERIALIZE_RESIZEABLE; + int rc; + Py_BEGIN_ALLOW_THREADS + (void)memcpy(buf, data->buf, data->len); + rc = sqlite3_deserialize(self->db, name, buf, size, size, flags); + Py_END_ALLOW_THREADS + + if (rc != SQLITE_OK) { + (void)_pysqlite_seterror(self->state, self->db); + return NULL; + } + Py_RETURN_NONE; +} +#endif // PY_SQLITE_HAVE_SERIALIZE + + /*[clinic input] _sqlite3.Connection.__enter__ as pysqlite_connection_enter @@ -1960,6 +2343,48 @@ getlimit_impl(pysqlite_Connection *self, int category) } +static PyObject * +get_autocommit(pysqlite_Connection *self, void *Py_UNUSED(ctx)) +{ + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + if (self->autocommit == AUTOCOMMIT_ENABLED) { + Py_RETURN_TRUE; + } + if (self->autocommit == AUTOCOMMIT_DISABLED) { + Py_RETURN_FALSE; + } + return PyLong_FromLong(LEGACY_TRANSACTION_CONTROL); +} + +static int +set_autocommit(pysqlite_Connection *self, PyObject *val, void *Py_UNUSED(ctx)) +{ + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return -1; + } + if (!autocommit_converter(val, &self->autocommit)) { + return -1; + } + if (self->autocommit == AUTOCOMMIT_ENABLED) { + if (!sqlite3_get_autocommit(self->db)) { + if (connection_exec_stmt(self, "COMMIT") < 0) { + return -1; + } + } + } + else if (self->autocommit == AUTOCOMMIT_DISABLED) { + if (sqlite3_get_autocommit(self->db)) { + if (connection_exec_stmt(self, "BEGIN") < 0) { + return -1; + } + } + } + return 0; +} + + static const char connection_doc[] = PyDoc_STR("SQLite database connection object."); @@ -1967,6 +2392,7 @@ static PyGetSetDef connection_getset[] = { {"isolation_level", (getter)pysqlite_connection_get_isolation_level, (setter)pysqlite_connection_set_isolation_level}, {"total_changes", (getter)pysqlite_connection_get_total_changes, (setter)0}, {"in_transaction", (getter)pysqlite_connection_get_in_transaction, (setter)0}, + {"autocommit", (getter)get_autocommit, (setter)set_autocommit}, {NULL} }; @@ -1993,6 +2419,10 @@ static PyMethodDef connection_methods[] = { PYSQLITE_CONNECTION_SET_TRACE_CALLBACK_METHODDEF SETLIMIT_METHODDEF GETLIMIT_METHODDEF + SERIALIZE_METHODDEF + DESERIALIZE_METHODDEF + CREATE_WINDOW_FUNCTION_METHODDEF + BLOBOPEN_METHODDEF {NULL, NULL} }; diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h index 84f1f095cb3..1df92065a58 100644 --- a/Modules/_sqlite/connection.h +++ b/Modules/_sqlite/connection.h @@ -39,6 +39,12 @@ typedef struct _callback_context pysqlite_state *state; } callback_context; +enum autocommit_mode { + AUTOCOMMIT_LEGACY = LEGACY_TRANSACTION_CONTROL, + AUTOCOMMIT_ENABLED = 1, + AUTOCOMMIT_DISABLED = 0, +}; + typedef struct { PyObject_HEAD @@ -51,6 +57,7 @@ typedef struct /* NULL for autocommit, otherwise a string with the isolation level */ const char *isolation_level; + enum autocommit_mode autocommit; /* 1 if a check should be performed for each API call if the connection is * used from the same thread it was created in */ @@ -63,8 +70,9 @@ typedef struct PyObject *statement_cache; - /* Lists of weak references to statements and cursors used within this connection */ - PyObject* cursors; + /* Lists of weak references to cursors and blobs used within this connection */ + PyObject *cursors; + PyObject *blobs; /* Counters for how many cursors were created in the connection. May be * reset to 0 at certain intervals */ @@ -98,7 +106,6 @@ typedef struct PyObject* NotSupportedError; } pysqlite_Connection; -int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObject* cursor); int pysqlite_check_thread(pysqlite_Connection* self); int pysqlite_check_connection(pysqlite_Connection* con); diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index e475d933b53..a4e22bb4a2b 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -22,20 +22,60 @@ */ #include "cursor.h" +#include "microprotocols.h" #include "module.h" #include "util.h" +typedef enum { + TYPE_LONG, + TYPE_FLOAT, + TYPE_UNICODE, + TYPE_BUFFER, + TYPE_UNKNOWN +} parameter_type; + #define clinic_state() (pysqlite_get_state_by_type(Py_TYPE(self))) #include "clinic/cursor.c.h" #undef clinic_state +static inline int +check_cursor_locked(pysqlite_Cursor *cur) +{ + if (cur->locked) { + PyErr_SetString(cur->connection->ProgrammingError, + "Recursive use of cursors not allowed."); + return 0; + } + return 1; +} + /*[clinic input] module _sqlite3 class _sqlite3.Cursor "pysqlite_Cursor *" "clinic_state()->CursorType" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c5b8115c5cf30f1]*/ -static const char errmsg_fetch_across_rollback[] = "Cursor needed to be reset because of commit/rollback and can no longer be fetched from."; +/* + * Registers a cursor with the connection. + * + * 0 => error; 1 => ok + */ +static int +register_cursor(pysqlite_Connection *connection, PyObject *cursor) +{ + PyObject *weakref = PyWeakref_NewRef((PyObject *)cursor, NULL); + if (weakref == NULL) { + return 0; + } + + if (PyList_Append(connection->cursors, weakref) < 0) { + Py_CLEAR(weakref); + return 0; + } + + Py_DECREF(weakref); + return 1; +} /*[clinic input] _sqlite3.Cursor.__init__ as pysqlite_cursor_init @@ -50,6 +90,10 @@ pysqlite_cursor_init_impl(pysqlite_Cursor *self, pysqlite_Connection *connection) /*[clinic end generated code: output=ac59dce49a809ca8 input=23d4265b534989fb]*/ { + if (!check_cursor_locked(self)) { + return -1; + } + Py_INCREF(connection); Py_XSETREF(self->connection, connection); Py_CLEAR(self->statement); @@ -63,8 +107,6 @@ pysqlite_cursor_init_impl(pysqlite_Cursor *self, self->arraysize = 1; self->closed = 0; - self->reset = 0; - self->rowcount = -1L; Py_INCREF(Py_None); @@ -74,7 +116,7 @@ pysqlite_cursor_init_impl(pysqlite_Cursor *self, return -1; } - if (!pysqlite_connection_register_cursor(connection, (PyObject*)self)) { + if (!register_cursor(connection, (PyObject *)self)) { return -1; } @@ -83,6 +125,20 @@ pysqlite_cursor_init_impl(pysqlite_Cursor *self, return 0; } +static inline int +stmt_reset(pysqlite_Statement *self) +{ + int rc = SQLITE_OK; + + if (self->st != NULL) { + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_reset(self->st); + Py_END_ALLOW_THREADS + } + + return rc; +} + static int cursor_traverse(pysqlite_Cursor *self, visitproc visit, void *arg) { @@ -106,7 +162,7 @@ cursor_clear(pysqlite_Cursor *self) Py_CLEAR(self->row_factory); if (self->statement) { /* Reset the statement if the user has not closed the cursor */ - pysqlite_statement_reset(self->statement); + stmt_reset(self->statement); Py_CLEAR(self->statement); } @@ -133,13 +189,12 @@ _pysqlite_get_converter(pysqlite_state *state, const char *keystr, PyObject *key; PyObject *upcase_key; PyObject *retval; - _Py_IDENTIFIER(upper); key = PyUnicode_FromStringAndSize(keystr, keylen); if (!key) { return NULL; } - upcase_key = _PyObject_CallMethodIdNoArgs(key, &PyId_upper); + upcase_key = PyObject_CallMethodNoArgs(key, state->str_upper); Py_DECREF(key); if (!upcase_key) { return NULL; @@ -273,12 +328,6 @@ _pysqlite_fetch_one_row(pysqlite_Cursor* self) const char* colname; PyObject* error_msg; - if (self->reset) { - PyObject *exc = self->connection->InterfaceError; - PyErr_SetString(exc, errmsg_fetch_across_rollback); - return NULL; - } - Py_BEGIN_ALLOW_THREADS numcols = sqlite3_data_count(self->statement->st); Py_END_ALLOW_THREADS @@ -418,13 +467,9 @@ static int check_cursor(pysqlite_Cursor* cur) return 0; } - if (cur->locked) { - PyErr_SetString(cur->connection->state->ProgrammingError, - "Recursive use of cursors not allowed."); - return 0; - } - - return pysqlite_check_thread(cur->connection) && pysqlite_check_connection(cur->connection); + return (pysqlite_check_thread(cur->connection) + && pysqlite_check_connection(cur->connection) + && check_cursor_locked(cur)); } static int @@ -465,7 +510,263 @@ get_statement_from_cache(pysqlite_Cursor *self, PyObject *operation) return PyObject_Vectorcall(cache, args + 1, nargsf, NULL); } -static PyObject * +static inline int +stmt_step(sqlite3_stmt *statement) +{ + int rc; + + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_step(statement); + Py_END_ALLOW_THREADS + + return rc; +} + +static int +bind_param(pysqlite_state *state, pysqlite_Statement *self, int pos, + PyObject *parameter) +{ + int rc = SQLITE_OK; + const char *string; + Py_ssize_t buflen; + parameter_type paramtype; + + if (parameter == Py_None) { + rc = sqlite3_bind_null(self->st, pos); + goto final; + } + + if (PyLong_CheckExact(parameter)) { + paramtype = TYPE_LONG; + } else if (PyFloat_CheckExact(parameter)) { + paramtype = TYPE_FLOAT; + } else if (PyUnicode_CheckExact(parameter)) { + paramtype = TYPE_UNICODE; + } else if (PyLong_Check(parameter)) { + paramtype = TYPE_LONG; + } else if (PyFloat_Check(parameter)) { + paramtype = TYPE_FLOAT; + } else if (PyUnicode_Check(parameter)) { + paramtype = TYPE_UNICODE; + } else if (PyObject_CheckBuffer(parameter)) { + paramtype = TYPE_BUFFER; + } else { + paramtype = TYPE_UNKNOWN; + } + + switch (paramtype) { + case TYPE_LONG: { + sqlite_int64 value = _pysqlite_long_as_int64(parameter); + if (value == -1 && PyErr_Occurred()) + rc = -1; + else + rc = sqlite3_bind_int64(self->st, pos, value); + break; + } + case TYPE_FLOAT: { + double value = PyFloat_AsDouble(parameter); + if (value == -1 && PyErr_Occurred()) { + rc = -1; + } + else { + rc = sqlite3_bind_double(self->st, pos, value); + } + break; + } + case TYPE_UNICODE: + string = PyUnicode_AsUTF8AndSize(parameter, &buflen); + if (string == NULL) + return -1; + if (buflen > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "string longer than INT_MAX bytes"); + return -1; + } + rc = sqlite3_bind_text(self->st, pos, string, (int)buflen, SQLITE_TRANSIENT); + break; + case TYPE_BUFFER: { + Py_buffer view; + if (PyObject_GetBuffer(parameter, &view, PyBUF_SIMPLE) != 0) { + return -1; + } + if (view.len > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "BLOB longer than INT_MAX bytes"); + PyBuffer_Release(&view); + return -1; + } + rc = sqlite3_bind_blob(self->st, pos, view.buf, (int)view.len, SQLITE_TRANSIENT); + PyBuffer_Release(&view); + break; + } + case TYPE_UNKNOWN: + PyErr_Format(state->ProgrammingError, + "Error binding parameter %d: type '%s' is not supported", + pos, Py_TYPE(parameter)->tp_name); + rc = -1; + } + +final: + return rc; +} + +/* returns 0 if the object is one of Python's internal ones that don't need to be adapted */ +static inline int +need_adapt(pysqlite_state *state, PyObject *obj) +{ + if (state->BaseTypeAdapted) { + return 1; + } + + if (PyLong_CheckExact(obj) || PyFloat_CheckExact(obj) + || PyUnicode_CheckExact(obj) || PyByteArray_CheckExact(obj)) { + return 0; + } else { + return 1; + } +} + +static void +bind_parameters(pysqlite_state *state, pysqlite_Statement *self, + PyObject *parameters) +{ + PyObject* current_param; + PyObject* adapted; + const char* binding_name; + int i; + int rc; + int num_params_needed; + Py_ssize_t num_params; + + Py_BEGIN_ALLOW_THREADS + num_params_needed = sqlite3_bind_parameter_count(self->st); + Py_END_ALLOW_THREADS + + if (PyTuple_CheckExact(parameters) || PyList_CheckExact(parameters) || (!PyDict_Check(parameters) && PySequence_Check(parameters))) { + /* parameters passed as sequence */ + if (PyTuple_CheckExact(parameters)) { + num_params = PyTuple_GET_SIZE(parameters); + } else if (PyList_CheckExact(parameters)) { + num_params = PyList_GET_SIZE(parameters); + } else { + num_params = PySequence_Size(parameters); + if (num_params == -1) { + return; + } + } + if (num_params != num_params_needed) { + PyErr_Format(state->ProgrammingError, + "Incorrect number of bindings supplied. The current " + "statement uses %d, and there are %zd supplied.", + num_params_needed, num_params); + return; + } + for (i = 0; i < num_params; i++) { + if (PyTuple_CheckExact(parameters)) { + PyObject *item = PyTuple_GET_ITEM(parameters, i); + current_param = Py_NewRef(item); + } else if (PyList_CheckExact(parameters)) { + PyObject *item = PyList_GetItem(parameters, i); + current_param = Py_XNewRef(item); + } else { + current_param = PySequence_GetItem(parameters, i); + } + if (!current_param) { + return; + } + + if (!need_adapt(state, current_param)) { + adapted = current_param; + } else { + PyObject *protocol = (PyObject *)state->PrepareProtocolType; + adapted = pysqlite_microprotocols_adapt(state, current_param, + protocol, + current_param); + Py_DECREF(current_param); + if (!adapted) { + return; + } + } + + rc = bind_param(state, self, i + 1, adapted); + Py_DECREF(adapted); + + if (rc != SQLITE_OK) { + PyObject *exc, *val, *tb; + PyErr_Fetch(&exc, &val, &tb); + sqlite3 *db = sqlite3_db_handle(self->st); + _pysqlite_seterror(state, db); + _PyErr_ChainExceptions(exc, val, tb); + return; + } + } + } else if (PyDict_Check(parameters)) { + /* parameters passed as dictionary */ + for (i = 1; i <= num_params_needed; i++) { + PyObject *binding_name_obj; + Py_BEGIN_ALLOW_THREADS + binding_name = sqlite3_bind_parameter_name(self->st, i); + Py_END_ALLOW_THREADS + if (!binding_name) { + PyErr_Format(state->ProgrammingError, + "Binding %d has no name, but you supplied a " + "dictionary (which has only names).", i); + return; + } + + binding_name++; /* skip first char (the colon) */ + binding_name_obj = PyUnicode_FromString(binding_name); + if (!binding_name_obj) { + return; + } + if (PyDict_CheckExact(parameters)) { + PyObject *item = PyDict_GetItemWithError(parameters, binding_name_obj); + current_param = Py_XNewRef(item); + } else { + current_param = PyObject_GetItem(parameters, binding_name_obj); + } + Py_DECREF(binding_name_obj); + if (!current_param) { + if (!PyErr_Occurred() || PyErr_ExceptionMatches(PyExc_LookupError)) { + PyErr_Format(state->ProgrammingError, + "You did not supply a value for binding " + "parameter :%s.", binding_name); + } + return; + } + + if (!need_adapt(state, current_param)) { + adapted = current_param; + } else { + PyObject *protocol = (PyObject *)state->PrepareProtocolType; + adapted = pysqlite_microprotocols_adapt(state, current_param, + protocol, + current_param); + Py_DECREF(current_param); + if (!adapted) { + return; + } + } + + rc = bind_param(state, self, i, adapted); + Py_DECREF(adapted); + + if (rc != SQLITE_OK) { + PyObject *exc, *val, *tb; + PyErr_Fetch(&exc, &val, &tb); + sqlite3 *db = sqlite3_db_handle(self->st); + _pysqlite_seterror(state, db); + _PyErr_ChainExceptions(exc, val, tb); + return; + } + } + } else { + PyErr_SetString(state->ProgrammingError, + "parameters are of unsupported type"); + } +} + +PyObject * _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation, PyObject* second_argument) { PyObject* parameters_list = NULL; @@ -475,14 +776,12 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation int rc; int numcols; PyObject* column_name; - sqlite_int64 lastrowid; if (!check_cursor(self)) { goto error; } self->locked = 1; - self->reset = 0; if (multiple) { if (PyIter_Check(second_argument)) { @@ -521,18 +820,13 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation } } - if (self->statement != NULL) { - /* There is an active statement */ - pysqlite_statement_reset(self->statement); - } - - /* reset description and rowcount */ + /* reset description */ Py_INCREF(Py_None); Py_SETREF(self->description, Py_None); - self->rowcount = 0L; if (self->statement) { - (void)pysqlite_statement_reset(self->statement); + // Reset pending statements on this cursor. + (void)stmt_reset(self->statement); } PyObject *stmt = get_statement_from_cache(self, operation); @@ -548,7 +842,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation goto error; } - if (self->statement->in_use) { + if (sqlite3_stmt_busy(self->statement->st)) { Py_SETREF(self->statement, pysqlite_statement_create(self->connection, operation)); if (self->statement == NULL) { @@ -556,12 +850,13 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation } } - pysqlite_statement_reset(self->statement); - pysqlite_statement_mark_dirty(self->statement); + (void)stmt_reset(self->statement); + self->rowcount = self->statement->is_dml ? 0L : -1L; /* We start a transaction implicitly before a DML statement. SELECT is the only exception. See #9924. */ - if (self->connection->isolation_level + if (self->connection->autocommit == AUTOCOMMIT_LEGACY + && self->connection->isolation_level && self->statement->is_dml && sqlite3_get_autocommit(self->connection->db)) { @@ -570,20 +865,19 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation } } + assert(!sqlite3_stmt_busy(self->statement->st)); while (1) { parameters = PyIter_Next(parameters_iter); if (!parameters) { break; } - pysqlite_statement_mark_dirty(self->statement); - - pysqlite_statement_bind_parameters(state, self->statement, parameters); + bind_parameters(state, self->statement, parameters); if (PyErr_Occurred()) { goto error; } - rc = pysqlite_step(self->statement->st); + rc = stmt_step(self->statement->st); if (rc != SQLITE_DONE && rc != SQLITE_ROW) { if (PyErr_Occurred()) { /* there was an error that occurred in a user-defined callback */ @@ -593,7 +887,6 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation PyErr_Clear(); } } - (void)pysqlite_statement_reset(self->statement); _pysqlite_seterror(state, self->connection->db); goto error; } @@ -635,33 +928,26 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation } } - if (self->statement->is_dml) { - self->rowcount += (long)sqlite3_changes(self->connection->db); - } else { - self->rowcount= -1L; - } - - if (!multiple) { - Py_BEGIN_ALLOW_THREADS - lastrowid = sqlite3_last_insert_rowid(self->connection->db); - Py_END_ALLOW_THREADS - Py_SETREF(self->lastrowid, PyLong_FromLongLong(lastrowid)); - if (self->lastrowid == NULL) { - goto error; + if (rc == SQLITE_DONE) { + if (self->statement->is_dml) { + self->rowcount += (long)sqlite3_changes(self->connection->db); } - } - - if (rc == SQLITE_DONE && !multiple) { - pysqlite_statement_reset(self->statement); - Py_CLEAR(self->statement); - } - - if (multiple) { - pysqlite_statement_reset(self->statement); + stmt_reset(self->statement); } Py_XDECREF(parameters); } + if (!multiple) { + sqlite_int64 lastrowid; + + Py_BEGIN_ALLOW_THREADS + lastrowid = sqlite3_last_insert_rowid(self->connection->db); + Py_END_ALLOW_THREADS + + Py_SETREF(self->lastrowid, PyLong_FromLongLong(lastrowid)); + // Fall through on error. + } + error: Py_XDECREF(parameters); Py_XDECREF(parameters_iter); @@ -670,11 +956,17 @@ error: self->locked = 0; if (PyErr_Occurred()) { + if (self->statement) { + (void)stmt_reset(self->statement); + Py_CLEAR(self->statement); + } self->rowcount = -1L; return NULL; - } else { - return Py_NewRef((PyObject *)self); } + if (self->statement && !sqlite3_stmt_busy(self->statement->st)) { + Py_CLEAR(self->statement); + } + return Py_NewRef((PyObject *)self); } /*[clinic input] @@ -684,13 +976,13 @@ _sqlite3.Cursor.execute as pysqlite_cursor_execute parameters: object(c_default = 'NULL') = () / -Executes a SQL statement. +Executes an SQL statement. [clinic start generated code]*/ static PyObject * pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyObject *sql, PyObject *parameters) -/*[clinic end generated code: output=d81b4655c7c0bbad input=91d7bb36f127f597]*/ +/*[clinic end generated code: output=d81b4655c7c0bbad input=a8e0200a11627f94]*/ { return _pysqlite_query_execute(self, 0, sql, parameters); } @@ -702,13 +994,13 @@ _sqlite3.Cursor.executemany as pysqlite_cursor_executemany seq_of_parameters: object / -Repeatedly executes a SQL statement. +Repeatedly executes an SQL statement. [clinic start generated code]*/ static PyObject * pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyObject *sql, PyObject *seq_of_parameters) -/*[clinic end generated code: output=2c65a3c4733fb5d8 input=440707b7af87fba8]*/ +/*[clinic end generated code: output=2c65a3c4733fb5d8 input=0d0a52e5eb7ccd35]*/ { return _pysqlite_query_execute(self, 1, sql, seq_of_parameters); } @@ -719,20 +1011,18 @@ _sqlite3.Cursor.executescript as pysqlite_cursor_executescript sql_script: str / -Executes multiple SQL statements at once. Non-standard. +Executes multiple SQL statements at once. [clinic start generated code]*/ static PyObject * pysqlite_cursor_executescript_impl(pysqlite_Cursor *self, const char *sql_script) -/*[clinic end generated code: output=8fd726dde1c65164 input=1ac0693dc8db02a8]*/ +/*[clinic end generated code: output=8fd726dde1c65164 input=78f093be415a8a2c]*/ { if (!check_cursor(self)) { return NULL; } - self->reset = 0; - size_t sql_len = strlen(sql_script); int max_length = sqlite3_limit(self->connection->db, SQLITE_LIMIT_SQL_LENGTH, -1); @@ -744,7 +1034,9 @@ pysqlite_cursor_executescript_impl(pysqlite_Cursor *self, // Commit if needed sqlite3 *db = self->connection->db; - if (!sqlite3_get_autocommit(db)) { + if (self->connection->autocommit == AUTOCOMMIT_LEGACY + && !sqlite3_get_autocommit(db)) + { int rc = SQLITE_OK; Py_BEGIN_ALLOW_THREADS @@ -797,35 +1089,33 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self) return NULL; } - if (self->reset) { - PyObject *exc = self->connection->InterfaceError; - PyErr_SetString(exc, errmsg_fetch_across_rollback); - return NULL; - } - if (self->statement == NULL) { return NULL; } sqlite3_stmt *stmt = self->statement->st; assert(stmt != NULL); - if (sqlite3_data_count(stmt) == 0) { - (void)pysqlite_statement_reset(self->statement); - Py_CLEAR(self->statement); - return NULL; - } + assert(sqlite3_data_count(stmt) != 0); + self->locked = 1; // GH-80254: Prevent recursive use of cursors. PyObject *row = _pysqlite_fetch_one_row(self); + self->locked = 0; if (row == NULL) { return NULL; } - int rc = pysqlite_step(stmt); + int rc = stmt_step(stmt); if (rc == SQLITE_DONE) { - (void)pysqlite_statement_reset(self->statement); + if (self->statement->is_dml) { + self->rowcount = (long)sqlite3_changes(self->connection->db); + } + (void)stmt_reset(self->statement); + Py_CLEAR(self->statement); } else if (rc != SQLITE_ROW) { (void)_pysqlite_seterror(self->connection->state, self->connection->db); + (void)stmt_reset(self->statement); + Py_CLEAR(self->statement); Py_DECREF(row); return NULL; } @@ -833,8 +1123,7 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self) PyObject *factory = self->row_factory; PyObject *args[] = { (PyObject *)self, row, }; PyObject *new_row = PyObject_Vectorcall(factory, args, 2, NULL); - Py_DECREF(row); - row = new_row; + Py_SETREF(row, new_row); } return row; } @@ -941,12 +1230,12 @@ _sqlite3.Cursor.setinputsizes as pysqlite_cursor_setinputsizes sizes: object / -Required by DB-API. Does nothing in pysqlite. +Required by DB-API. Does nothing in sqlite3. [clinic start generated code]*/ static PyObject * pysqlite_cursor_setinputsizes(pysqlite_Cursor *self, PyObject *sizes) -/*[clinic end generated code: output=893c817afe9d08ad input=7cffbb168663bc69]*/ +/*[clinic end generated code: output=893c817afe9d08ad input=de7950a3aec79bdf]*/ { Py_RETURN_NONE; } @@ -958,13 +1247,13 @@ _sqlite3.Cursor.setoutputsize as pysqlite_cursor_setoutputsize column: object = None / -Required by DB-API. Does nothing in pysqlite. +Required by DB-API. Does nothing in sqlite3. [clinic start generated code]*/ static PyObject * pysqlite_cursor_setoutputsize_impl(pysqlite_Cursor *self, PyObject *size, PyObject *column) -/*[clinic end generated code: output=018d7e9129d45efe input=077b017da58b9389]*/ +/*[clinic end generated code: output=018d7e9129d45efe input=607a6bece8bbb273]*/ { Py_RETURN_NONE; } @@ -979,6 +1268,10 @@ static PyObject * pysqlite_cursor_close_impl(pysqlite_Cursor *self) /*[clinic end generated code: output=b6055e4ec6fe63b6 input=08b36552dbb9a986]*/ { + if (!check_cursor_locked(self)) { + return NULL; + } + if (!self->connection) { PyTypeObject *tp = Py_TYPE(self); pysqlite_state *state = pysqlite_get_state_by_type(tp); @@ -991,7 +1284,7 @@ pysqlite_cursor_close_impl(pysqlite_Cursor *self) } if (self->statement) { - (void)pysqlite_statement_reset(self->statement); + (void)stmt_reset(self->statement); Py_CLEAR(self->statement); } diff --git a/Modules/_sqlite/cursor.h b/Modules/_sqlite/cursor.h index d26d20a9fc5..0bcdddc3e29 100644 --- a/Modules/_sqlite/cursor.h +++ b/Modules/_sqlite/cursor.h @@ -42,7 +42,6 @@ typedef struct PyObject* row_factory; pysqlite_Statement* statement; int closed; - int reset; int locked; int initialized; diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c index 95c799d306f..148220d0f91 100644 --- a/Modules/_sqlite/microprotocols.c +++ b/Modules/_sqlite/microprotocols.c @@ -57,7 +57,7 @@ pysqlite_microprotocols_add(pysqlite_state *state, PyTypeObject *type, assert(type != NULL); assert(proto != NULL); - key = Py_BuildValue("(OO)", (PyObject*)type, proto); + key = PyTuple_Pack(2, (PyObject *)type, proto); if (!key) { return -1; } @@ -74,8 +74,6 @@ PyObject * pysqlite_microprotocols_adapt(pysqlite_state *state, PyObject *obj, PyObject *proto, PyObject *alt) { - _Py_IDENTIFIER(__adapt__); - _Py_IDENTIFIER(__conform__); PyObject *adapter, *key, *adapted; /* we don't check for exact type conformance as specified in PEP 246 @@ -83,7 +81,7 @@ pysqlite_microprotocols_adapt(pysqlite_state *state, PyObject *obj, way to get a quotable object to be its instance */ /* look for an adapter in the registry */ - key = Py_BuildValue("(OO)", (PyObject*)Py_TYPE(obj), proto); + key = PyTuple_Pack(2, (PyObject *)Py_TYPE(obj), proto); if (!key) { return NULL; } @@ -100,7 +98,7 @@ pysqlite_microprotocols_adapt(pysqlite_state *state, PyObject *obj, } /* try to have the protocol adapt this object */ - if (_PyObject_LookupAttrId(proto, &PyId___adapt__, &adapter) < 0) { + if (_PyObject_LookupAttr(proto, state->str___adapt__, &adapter) < 0) { return NULL; } if (adapter) { @@ -119,7 +117,7 @@ pysqlite_microprotocols_adapt(pysqlite_state *state, PyObject *obj, } /* and finally try to have the object adapt itself */ - if (_PyObject_LookupAttrId(obj, &PyId___conform__, &adapter) < 0) { + if (_PyObject_LookupAttr(obj, state->str___conform__, &adapter) < 0) { return NULL; } if (adapter) { diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 3b9f79799b5..6db3d51fd20 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -27,6 +27,7 @@ #include "prepare_protocol.h" #include "microprotocols.h" #include "row.h" +#include "blob.h" #if SQLITE_VERSION_NUMBER < 3007015 #error "SQLite 3.7.15 or higher required" @@ -41,48 +42,45 @@ module _sqlite3 [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=81e330492d57488e]*/ -// NOTE: This must equal sqlite3.Connection.__init__ argument spec! -/*[clinic input] -_sqlite3.connect as pysqlite_connect +// NB: This needs to be in sync with the Connection.__init__ docstring. +PyDoc_STRVAR(module_connect_doc, +"connect($module, /, database, timeout=5.0, detect_types=0,\n" +" isolation_level='', check_same_thread=True,\n" +" factory=ConnectionType, cached_statements=128, uri=False, *,\n" +" autocommit=sqlite3.LEGACY_TRANSACTION_CONTROL)\n" +"--\n" +"\n" +"Opens a connection to the SQLite database file database.\n" +"\n" +"You can use \":memory:\" to open a database connection to a database that resides\n" +"in RAM instead of on disk."); - database: object(converter='PyUnicode_FSConverter') - timeout: double = 5.0 - detect_types: int = 0 - isolation_level: object = NULL - check_same_thread: bool(accept={int}) = True - factory: object(c_default='(PyObject*)clinic_state()->ConnectionType') = ConnectionType - cached_statements: int = 128 - uri: bool = False - -Opens a connection to the SQLite database file database. - -You can use ":memory:" to open a database connection to a database that resides -in RAM instead of on disk. -[clinic start generated code]*/ +#define PYSQLITE_CONNECT_METHODDEF \ + {"connect", _PyCFunction_CAST(module_connect), METH_FASTCALL|METH_KEYWORDS, module_connect_doc}, static PyObject * -pysqlite_connect_impl(PyObject *module, PyObject *database, double timeout, - int detect_types, PyObject *isolation_level, - int check_same_thread, PyObject *factory, - int cached_statements, int uri) -/*[clinic end generated code: output=450ac9078b4868bb input=ea6355ba55a78e12]*/ +module_connect(PyObject *module, PyObject *const *args, Py_ssize_t nargsf, + PyObject *kwnames) { - if (isolation_level == NULL) { - isolation_level = PyUnicode_FromString(""); - if (isolation_level == NULL) { - return NULL; + pysqlite_state *state = pysqlite_get_state(module); + PyObject *factory = (PyObject *)state->ConnectionType; + + static const int FACTORY_POS = 5; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (nargs > FACTORY_POS) { + factory = args[FACTORY_POS]; + } + else if (kwnames != NULL) { + for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(kwnames); i++) { + PyObject *item = PyTuple_GET_ITEM(kwnames, i); // borrowed ref. + if (PyUnicode_CompareWithASCIIString(item, "factory") == 0) { + factory = args[nargs + i]; + break; + } } } - else { - Py_INCREF(isolation_level); - } - PyObject *res = PyObject_CallFunction(factory, "OdiOiOii", database, - timeout, detect_types, - isolation_level, check_same_thread, - factory, cached_statements, uri); - Py_DECREF(database); // needed bco. the AC FSConverter - Py_DECREF(isolation_level); - return res; + + return PyObject_Vectorcall(factory, args, nargsf, kwnames); } /*[clinic input] @@ -90,12 +88,12 @@ _sqlite3.complete_statement as pysqlite_complete_statement statement: str -Checks if a string contains a complete SQL statement. Non-standard. +Checks if a string contains a complete SQL statement. [clinic start generated code]*/ static PyObject * pysqlite_complete_statement_impl(PyObject *module, const char *statement) -/*[clinic end generated code: output=e55f1ff1952df558 input=f6b24996b31c5c33]*/ +/*[clinic end generated code: output=e55f1ff1952df558 input=ac45d257375bb828]*/ { if (sqlite3_complete(statement)) { return Py_NewRef(Py_True); @@ -104,47 +102,20 @@ pysqlite_complete_statement_impl(PyObject *module, const char *statement) } } -/*[clinic input] -_sqlite3.enable_shared_cache as pysqlite_enable_shared_cache - - do_enable: int - -Enable or disable shared cache mode for the calling thread. - -Experimental/Non-standard. -[clinic start generated code]*/ - -static PyObject * -pysqlite_enable_shared_cache_impl(PyObject *module, int do_enable) -/*[clinic end generated code: output=259c74eedee1516b input=8400e41bc58b6b24]*/ -{ - int rc; - - rc = sqlite3_enable_shared_cache(do_enable); - - if (rc != SQLITE_OK) { - pysqlite_state *state = pysqlite_get_state(module); - PyErr_SetString(state->OperationalError, "Changing the shared_cache flag failed"); - return NULL; - } else { - Py_RETURN_NONE; - } -} - /*[clinic input] _sqlite3.register_adapter as pysqlite_register_adapter type: object(type='PyTypeObject *') - caster: object + adapter as caster: object / -Registers an adapter with pysqlite's adapter registry. Non-standard. +Register a function to adapt Python objects to SQLite values. [clinic start generated code]*/ static PyObject * pysqlite_register_adapter_impl(PyObject *module, PyTypeObject *type, PyObject *caster) -/*[clinic end generated code: output=a287e8db18e8af23 input=839dad90e2492725]*/ +/*[clinic end generated code: output=a287e8db18e8af23 input=29a5e0f213030242]*/ { int rc; @@ -169,29 +140,28 @@ pysqlite_register_adapter_impl(PyObject *module, PyTypeObject *type, /*[clinic input] _sqlite3.register_converter as pysqlite_register_converter - name as orig_name: unicode + typename as orig_name: unicode converter as callable: object / -Registers a converter with pysqlite. Non-standard. +Register a function to convert SQLite values to Python objects. [clinic start generated code]*/ static PyObject * pysqlite_register_converter_impl(PyObject *module, PyObject *orig_name, PyObject *callable) -/*[clinic end generated code: output=a2f2bfeed7230062 input=e074cf7f4890544f]*/ +/*[clinic end generated code: output=a2f2bfeed7230062 input=159a444971b40378]*/ { PyObject* name = NULL; PyObject* retval = NULL; - _Py_IDENTIFIER(upper); /* convert the name to upper case */ - name = _PyObject_CallMethodIdNoArgs(orig_name, &PyId_upper); + pysqlite_state *state = pysqlite_get_state(module); + name = PyObject_CallMethodNoArgs(orig_name, state->str_upper); if (!name) { goto error; } - pysqlite_state *state = pysqlite_get_state(module); if (PyDict_SetItem(state->converters, name, callable) != 0) { goto error; } @@ -229,13 +199,13 @@ _sqlite3.adapt as pysqlite_adapt alt: object = NULL / -Adapt given object to given protocol. Non-standard. +Adapt given object to given protocol. [clinic start generated code]*/ static PyObject * pysqlite_adapt_impl(PyObject *module, PyObject *obj, PyObject *proto, PyObject *alt) -/*[clinic end generated code: output=0c3927c5fcd23dd9 input=c8995aeb25d0e542]*/ +/*[clinic end generated code: output=0c3927c5fcd23dd9 input=a53dc9993e81e15f]*/ { pysqlite_state *state = pysqlite_get_state(module); return pysqlite_microprotocols_adapt(state, obj, proto, alt); @@ -255,14 +225,8 @@ static int converters_init(PyObject* module) static int load_functools_lru_cache(PyObject *module) { - PyObject *functools = PyImport_ImportModule("functools"); - if (functools == NULL) { - return -1; - } - pysqlite_state *state = pysqlite_get_state(module); - state->lru_cache = PyObject_GetAttrString(functools, "lru_cache"); - Py_DECREF(functools); + state->lru_cache = _PyImport_GetModuleAttrString("functools", "lru_cache"); if (state->lru_cache == NULL) { return -1; } @@ -274,7 +238,6 @@ static PyMethodDef module_methods[] = { PYSQLITE_COMPLETE_STATEMENT_METHODDEF PYSQLITE_CONNECT_METHODDEF PYSQLITE_ENABLE_CALLBACK_TRACE_METHODDEF - PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF PYSQLITE_REGISTER_ADAPTER_METHODDEF PYSQLITE_REGISTER_CONVERTER_METHODDEF {NULL, NULL} @@ -580,6 +543,7 @@ module_traverse(PyObject *module, visitproc visit, void *arg) Py_VISIT(state->Warning); // Types + Py_VISIT(state->BlobType); Py_VISIT(state->ConnectionType); Py_VISIT(state->CursorType); Py_VISIT(state->PrepareProtocolType); @@ -612,6 +576,7 @@ module_clear(PyObject *module) Py_CLEAR(state->Warning); // Types + Py_CLEAR(state->BlobType); Py_CLEAR(state->ConnectionType); Py_CLEAR(state->CursorType); Py_CLEAR(state->PrepareProtocolType); @@ -623,6 +588,16 @@ module_clear(PyObject *module) Py_CLEAR(state->lru_cache); Py_CLEAR(state->psyco_adapters); + // Interned strings + Py_CLEAR(state->str___adapt__); + Py_CLEAR(state->str___conform__); + Py_CLEAR(state->str_executescript); + Py_CLEAR(state->str_finalize); + Py_CLEAR(state->str_inverse); + Py_CLEAR(state->str_step); + Py_CLEAR(state->str_upper); + Py_CLEAR(state->str_value); + return 0; } @@ -648,6 +623,15 @@ do { \ ADD_TYPE(module, (PyTypeObject *)state->exc); \ } while (0) +#define ADD_INTERNED(state, string) \ +do { \ + PyObject *tmp = PyUnicode_InternFromString(#string); \ + if (tmp == NULL) { \ + goto error; \ + } \ + state->str_ ## string = tmp; \ +} while (0) + static int module_exec(PyObject *module) { @@ -666,12 +650,14 @@ module_exec(PyObject *module) (pysqlite_cursor_setup_types(module) < 0) || (pysqlite_connection_setup_types(module) < 0) || (pysqlite_statement_setup_types(module) < 0) || - (pysqlite_prepare_protocol_setup_types(module) < 0) + (pysqlite_prepare_protocol_setup_types(module) < 0) || + (pysqlite_blob_setup_types(module) < 0) ) { goto error; } pysqlite_state *state = pysqlite_get_state(module); + ADD_TYPE(module, state->BlobType); ADD_TYPE(module, state->ConnectionType); ADD_TYPE(module, state->CursorType); ADD_TYPE(module, state->PrepareProtocolType); @@ -693,6 +679,16 @@ module_exec(PyObject *module) ADD_EXCEPTION(module, state, DataError, state->DatabaseError); ADD_EXCEPTION(module, state, NotSupportedError, state->DatabaseError); + /* Add interned strings */ + ADD_INTERNED(state, __adapt__); + ADD_INTERNED(state, __conform__); + ADD_INTERNED(state, executescript); + ADD_INTERNED(state, finalize); + ADD_INTERNED(state, inverse); + ADD_INTERNED(state, step); + ADD_INTERNED(state, upper); + ADD_INTERNED(state, value); + /* Set error constants */ if (add_error_constants(module) < 0) { goto error; @@ -703,7 +699,7 @@ module_exec(PyObject *module) goto error; } - if (PyModule_AddStringConstant(module, "version", PYSQLITE_VERSION) < 0) { + if (PyModule_AddStringConstant(module, "_deprecated_version", PYSQLITE_VERSION) < 0) { goto error; } @@ -711,6 +707,10 @@ module_exec(PyObject *module) goto error; } + if (PyModule_AddIntMacro(module, LEGACY_TRANSACTION_CONTROL) < 0) { + goto error; + } + int threadsafety = get_threadsafety(state); if (threadsafety < 0) { goto error; diff --git a/Modules/_sqlite/module.h b/Modules/_sqlite/module.h index 1d319f1ed55..daa22091d38 100644 --- a/Modules/_sqlite/module.h +++ b/Modules/_sqlite/module.h @@ -26,6 +26,8 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#define LEGACY_TRANSACTION_CONTROL -1 + #define PYSQLITE_VERSION "2.6.0" #define MODULE_NAME "sqlite3" @@ -53,11 +55,22 @@ typedef struct { int BaseTypeAdapted; int enable_callback_tracebacks; + PyTypeObject *BlobType; PyTypeObject *ConnectionType; PyTypeObject *CursorType; PyTypeObject *PrepareProtocolType; PyTypeObject *RowType; PyTypeObject *StatementType; + + /* Pointers to interned strings */ + PyObject *str___adapt__; + PyObject *str___conform__; + PyObject *str_executescript; + PyObject *str_finalize; + PyObject *str_inverse; + PyObject *str_step; + PyObject *str_upper; + PyObject *str_value; } pysqlite_state; extern pysqlite_state pysqlite_global_state; @@ -74,7 +87,7 @@ extern struct PyModuleDef _sqlite3module; static inline pysqlite_state * pysqlite_get_state_by_type(PyTypeObject *tp) { - PyObject *module = _PyType_GetModuleByDef(tp, &_sqlite3module); + PyObject *module = PyType_GetModuleByDef(tp, &_sqlite3module); assert(module != NULL); return pysqlite_get_state(module); } diff --git a/Modules/_sqlite/prepare_protocol.c b/Modules/_sqlite/prepare_protocol.c index cefb46e390a..44533225665 100644 --- a/Modules/_sqlite/prepare_protocol.c +++ b/Modules/_sqlite/prepare_protocol.c @@ -46,10 +46,13 @@ pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol *self) Py_DECREF(tp); } +PyDoc_STRVAR(doc, "PEP 246 style object adaption protocol type."); + static PyType_Slot type_slots[] = { {Py_tp_dealloc, pysqlite_prepare_protocol_dealloc}, {Py_tp_init, pysqlite_prepare_protocol_init}, {Py_tp_traverse, pysqlite_prepare_protocol_traverse}, + {Py_tp_doc, (void *)doc}, {0, NULL}, }; diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 66fadb63e53..229bfc3b504 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -21,32 +21,12 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include "statement.h" -#include "cursor.h" #include "connection.h" -#include "microprotocols.h" -#include "prepare_protocol.h" +#include "statement.h" #include "util.h" /* prototypes */ -static int pysqlite_check_remaining_sql(const char* tail); - -typedef enum { - LINECOMMENT_1, - IN_LINECOMMENT, - COMMENTSTART_1, - IN_COMMENT, - COMMENTEND_1, - NORMAL -} parse_remaining_sql_state; - -typedef enum { - TYPE_LONG, - TYPE_FLOAT, - TYPE_UNICODE, - TYPE_BUFFER, - TYPE_UNKNOWN -} parameter_type; +static const char *lstrip_sql(const char *sql); pysqlite_Statement * pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql) @@ -67,7 +47,7 @@ pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql) return NULL; } if (strlen(sql_cstr) != (size_t)size) { - PyErr_SetString(PyExc_ValueError, + PyErr_SetString(connection->ProgrammingError, "the query contains a null character"); return NULL; } @@ -84,8 +64,8 @@ pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql) return NULL; } - if (pysqlite_check_remaining_sql(tail)) { - PyErr_SetString(connection->Warning, + if (lstrip_sql(tail) != NULL) { + PyErr_SetString(connection->ProgrammingError, "You can only execute one statement at a time."); goto error; } @@ -93,20 +73,12 @@ pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql) /* Determine if the statement is a DML statement. SELECT is the only exception. See #9924. */ int is_dml = 0; - for (const char *p = sql_cstr; *p != 0; p++) { - switch (*p) { - case ' ': - case '\r': - case '\n': - case '\t': - continue; - } - + const char *p = lstrip_sql(sql_cstr); + if (p != NULL) { is_dml = (PyOS_strnicmp(p, "insert", 6) == 0) || (PyOS_strnicmp(p, "update", 6) == 0) || (PyOS_strnicmp(p, "delete", 6) == 0) || (PyOS_strnicmp(p, "replace", 7) == 0); - break; } pysqlite_Statement *self = PyObject_GC_New(pysqlite_Statement, @@ -116,7 +88,6 @@ pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql) } self->st = stmt; - self->in_use = 0; self->is_dml = is_dml; PyObject_GC_Track(self); @@ -127,263 +98,6 @@ error: return NULL; } -int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter) -{ - int rc = SQLITE_OK; - const char *string; - Py_ssize_t buflen; - parameter_type paramtype; - - if (parameter == Py_None) { - rc = sqlite3_bind_null(self->st, pos); - goto final; - } - - if (PyLong_CheckExact(parameter)) { - paramtype = TYPE_LONG; - } else if (PyFloat_CheckExact(parameter)) { - paramtype = TYPE_FLOAT; - } else if (PyUnicode_CheckExact(parameter)) { - paramtype = TYPE_UNICODE; - } else if (PyLong_Check(parameter)) { - paramtype = TYPE_LONG; - } else if (PyFloat_Check(parameter)) { - paramtype = TYPE_FLOAT; - } else if (PyUnicode_Check(parameter)) { - paramtype = TYPE_UNICODE; - } else if (PyObject_CheckBuffer(parameter)) { - paramtype = TYPE_BUFFER; - } else { - paramtype = TYPE_UNKNOWN; - } - - switch (paramtype) { - case TYPE_LONG: { - sqlite_int64 value = _pysqlite_long_as_int64(parameter); - if (value == -1 && PyErr_Occurred()) - rc = -1; - else - rc = sqlite3_bind_int64(self->st, pos, value); - break; - } - case TYPE_FLOAT: - rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter)); - break; - case TYPE_UNICODE: - string = PyUnicode_AsUTF8AndSize(parameter, &buflen); - if (string == NULL) - return -1; - if (buflen > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "string longer than INT_MAX bytes"); - return -1; - } - rc = sqlite3_bind_text(self->st, pos, string, (int)buflen, SQLITE_TRANSIENT); - break; - case TYPE_BUFFER: { - Py_buffer view; - if (PyObject_GetBuffer(parameter, &view, PyBUF_SIMPLE) != 0) { - PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer"); - return -1; - } - if (view.len > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "BLOB longer than INT_MAX bytes"); - PyBuffer_Release(&view); - return -1; - } - rc = sqlite3_bind_blob(self->st, pos, view.buf, (int)view.len, SQLITE_TRANSIENT); - PyBuffer_Release(&view); - break; - } - case TYPE_UNKNOWN: - rc = -1; - } - -final: - return rc; -} - -/* returns 0 if the object is one of Python's internal ones that don't need to be adapted */ -static int -_need_adapt(pysqlite_state *state, PyObject *obj) -{ - if (state->BaseTypeAdapted) { - return 1; - } - - if (PyLong_CheckExact(obj) || PyFloat_CheckExact(obj) - || PyUnicode_CheckExact(obj) || PyByteArray_CheckExact(obj)) { - return 0; - } else { - return 1; - } -} - -void -pysqlite_statement_bind_parameters(pysqlite_state *state, - pysqlite_Statement *self, - PyObject *parameters) -{ - PyObject* current_param; - PyObject* adapted; - const char* binding_name; - int i; - int rc; - int num_params_needed; - Py_ssize_t num_params; - - Py_BEGIN_ALLOW_THREADS - num_params_needed = sqlite3_bind_parameter_count(self->st); - Py_END_ALLOW_THREADS - - if (PyTuple_CheckExact(parameters) || PyList_CheckExact(parameters) || (!PyDict_Check(parameters) && PySequence_Check(parameters))) { - /* parameters passed as sequence */ - if (PyTuple_CheckExact(parameters)) { - num_params = PyTuple_GET_SIZE(parameters); - } else if (PyList_CheckExact(parameters)) { - num_params = PyList_GET_SIZE(parameters); - } else { - num_params = PySequence_Size(parameters); - if (num_params == -1) { - return; - } - } - if (num_params != num_params_needed) { - PyErr_Format(state->ProgrammingError, - "Incorrect number of bindings supplied. The current " - "statement uses %d, and there are %zd supplied.", - num_params_needed, num_params); - return; - } - for (i = 0; i < num_params; i++) { - if (PyTuple_CheckExact(parameters)) { - PyObject *item = PyTuple_GET_ITEM(parameters, i); - current_param = Py_NewRef(item); - } else if (PyList_CheckExact(parameters)) { - PyObject *item = PyList_GetItem(parameters, i); - current_param = Py_XNewRef(item); - } else { - current_param = PySequence_GetItem(parameters, i); - } - if (!current_param) { - return; - } - - if (!_need_adapt(state, current_param)) { - adapted = current_param; - } else { - PyObject *protocol = (PyObject *)state->PrepareProtocolType; - adapted = pysqlite_microprotocols_adapt(state, current_param, - protocol, - current_param); - Py_DECREF(current_param); - if (!adapted) { - return; - } - } - - rc = pysqlite_statement_bind_parameter(self, i + 1, adapted); - Py_DECREF(adapted); - - if (rc != SQLITE_OK) { - if (!PyErr_Occurred()) { - PyErr_Format(state->InterfaceError, - "Error binding parameter %d - " - "probably unsupported type.", i); - } - return; - } - } - } else if (PyDict_Check(parameters)) { - /* parameters passed as dictionary */ - for (i = 1; i <= num_params_needed; i++) { - PyObject *binding_name_obj; - Py_BEGIN_ALLOW_THREADS - binding_name = sqlite3_bind_parameter_name(self->st, i); - Py_END_ALLOW_THREADS - if (!binding_name) { - PyErr_Format(state->ProgrammingError, - "Binding %d has no name, but you supplied a " - "dictionary (which has only names).", i); - return; - } - - binding_name++; /* skip first char (the colon) */ - binding_name_obj = PyUnicode_FromString(binding_name); - if (!binding_name_obj) { - return; - } - if (PyDict_CheckExact(parameters)) { - PyObject *item = PyDict_GetItemWithError(parameters, binding_name_obj); - current_param = Py_XNewRef(item); - } else { - current_param = PyObject_GetItem(parameters, binding_name_obj); - } - Py_DECREF(binding_name_obj); - if (!current_param) { - if (!PyErr_Occurred() || PyErr_ExceptionMatches(PyExc_LookupError)) { - PyErr_Format(state->ProgrammingError, - "You did not supply a value for binding " - "parameter :%s.", binding_name); - } - return; - } - - if (!_need_adapt(state, current_param)) { - adapted = current_param; - } else { - PyObject *protocol = (PyObject *)state->PrepareProtocolType; - adapted = pysqlite_microprotocols_adapt(state, current_param, - protocol, - current_param); - Py_DECREF(current_param); - if (!adapted) { - return; - } - } - - rc = pysqlite_statement_bind_parameter(self, i, adapted); - Py_DECREF(adapted); - - if (rc != SQLITE_OK) { - if (!PyErr_Occurred()) { - PyErr_Format(state->InterfaceError, - "Error binding parameter :%s - " - "probably unsupported type.", binding_name); - } - return; - } - } - } else { - PyErr_SetString(PyExc_ValueError, "parameters are of unsupported type"); - } -} - -int pysqlite_statement_reset(pysqlite_Statement* self) -{ - int rc; - - rc = SQLITE_OK; - - if (self->in_use && self->st) { - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_reset(self->st); - Py_END_ALLOW_THREADS - - if (rc == SQLITE_OK) { - self->in_use = 0; - } - } - - return rc; -} - -void pysqlite_statement_mark_dirty(pysqlite_Statement* self) -{ - self->in_use = 1; -} - static void stmt_dealloc(pysqlite_Statement *self) { @@ -407,73 +121,61 @@ stmt_traverse(pysqlite_Statement *self, visitproc visit, void *arg) } /* - * Checks if there is anything left in an SQL string after SQLite compiled it. - * This is used to check if somebody tried to execute more than one SQL command - * with one execute()/executemany() command, which the DB-API and we don't - * allow. + * Strip leading whitespace and comments from incoming SQL (null terminated C + * string) and return a pointer to the first non-whitespace, non-comment + * character. * - * Returns 1 if there is more left than should be. 0 if ok. + * This is used to check if somebody tries to execute more than one SQL query + * with one execute()/executemany() command, which the DB-API don't allow. + * + * It is also used to harden DML query detection. */ -static int pysqlite_check_remaining_sql(const char* tail) +static inline const char * +lstrip_sql(const char *sql) { - const char* pos = tail; - - parse_remaining_sql_state state = NORMAL; - - for (;;) { + // This loop is borrowed from the SQLite source code. + for (const char *pos = sql; *pos; pos++) { switch (*pos) { - case 0: - return 0; - case '-': - if (state == NORMAL) { - state = LINECOMMENT_1; - } else if (state == LINECOMMENT_1) { - state = IN_LINECOMMENT; - } - break; case ' ': case '\t': - break; + case '\f': case '\n': - case 13: - if (state == IN_LINECOMMENT) { - state = NORMAL; - } + case '\r': + // Skip whitespace. break; + case '-': + // Skip line comments. + if (pos[1] == '-') { + pos += 2; + while (pos[0] && pos[0] != '\n') { + pos++; + } + if (pos[0] == '\0') { + return NULL; + } + continue; + } + return pos; case '/': - if (state == NORMAL) { - state = COMMENTSTART_1; - } else if (state == COMMENTEND_1) { - state = NORMAL; - } else if (state == COMMENTSTART_1) { - return 1; + // Skip C style comments. + if (pos[1] == '*') { + pos += 2; + while (pos[0] && (pos[0] != '*' || pos[1] != '/')) { + pos++; + } + if (pos[0] == '\0') { + return NULL; + } + pos++; + continue; } - break; - case '*': - if (state == NORMAL) { - return 1; - } else if (state == LINECOMMENT_1) { - return 1; - } else if (state == COMMENTSTART_1) { - state = IN_COMMENT; - } else if (state == IN_COMMENT) { - state = COMMENTEND_1; - } - break; + return pos; default: - if (state == COMMENTEND_1) { - state = IN_COMMENT; - } else if (state == IN_LINECOMMENT) { - } else if (state == IN_COMMENT) { - } else { - return 1; - } + return pos; } - - pos++; } - return 0; + return NULL; } static PyType_Slot stmt_slots[] = { diff --git a/Modules/_sqlite/statement.h b/Modules/_sqlite/statement.h index b901c43c479..11a6464b1a1 100644 --- a/Modules/_sqlite/statement.h +++ b/Modules/_sqlite/statement.h @@ -33,20 +33,11 @@ typedef struct { PyObject_HEAD sqlite3_stmt* st; - int in_use; int is_dml; } pysqlite_Statement; pysqlite_Statement *pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql); -int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter); -void pysqlite_statement_bind_parameters(pysqlite_state *state, - pysqlite_Statement *self, - PyObject *parameters); - -int pysqlite_statement_reset(pysqlite_Statement* self); -void pysqlite_statement_mark_dirty(pysqlite_Statement* self); - int pysqlite_statement_setup_types(PyObject *module); #endif diff --git a/Modules/_sqlite/util.c b/Modules/_sqlite/util.c index 113b581bfac..2b3bbfefa3c 100644 --- a/Modules/_sqlite/util.c +++ b/Modules/_sqlite/util.c @@ -24,18 +24,6 @@ #include "module.h" #include "connection.h" -int -pysqlite_step(sqlite3_stmt *statement) -{ - int rc; - - Py_BEGIN_ALLOW_THREADS - rc = sqlite3_step(statement); - Py_END_ALLOW_THREADS - - return rc; -} - // Returns non-NULL if a new exception should be raised static PyObject * get_exception_class(pysqlite_state *state, int errorcode) @@ -71,7 +59,6 @@ get_exception_class(pysqlite_state *state, int errorcode) case SQLITE_MISMATCH: return state->IntegrityError; case SQLITE_MISUSE: - return state->ProgrammingError; case SQLITE_RANGE: return state->InterfaceError; default: diff --git a/Modules/_sqlite/util.h b/Modules/_sqlite/util.h index 5eee3fac6f1..a22bcd82d2a 100644 --- a/Modules/_sqlite/util.h +++ b/Modules/_sqlite/util.h @@ -29,8 +29,6 @@ #include "sqlite3.h" #include "connection.h" -int pysqlite_step(sqlite3_stmt *statement); - /** * Checks the SQLite error code and sets the appropriate DB-API exception. * Returns the error code (0 means no error occurred). diff --git a/Modules/clinic/_sre.c.h b/Modules/_sre/clinic/sre.c.h similarity index 54% rename from Modules/clinic/_sre.c.h rename to Modules/_sre/clinic/sre.c.h index 72d772c289a..da641081ce9 100644 --- a/Modules/clinic/_sre.c.h +++ b/Modules/_sre/clinic/sre.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_sre_getcodesize__doc__, "getcodesize($module, /)\n" "--\n" @@ -164,7 +170,7 @@ PyDoc_STRVAR(_sre_SRE_Pattern_match__doc__, "Matches zero or more characters at the beginning of the string."); #define _SRE_SRE_PATTERN_MATCH_METHODDEF \ - {"match", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_match, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_match__doc__}, + {"match", _PyCFunction_CAST(_sre_SRE_Pattern_match), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_match__doc__}, static PyObject * _sre_SRE_Pattern_match_impl(PatternObject *self, PyTypeObject *cls, @@ -175,16 +181,75 @@ static PyObject * _sre_SRE_Pattern_match(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {"O|nn:match", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "match", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &string, &pos, &endpos)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { goto exit; } + string = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + pos = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + endpos = ival; + } +skip_optional_pos: return_value = _sre_SRE_Pattern_match_impl(self, cls, string, pos, endpos); exit: @@ -198,7 +263,7 @@ PyDoc_STRVAR(_sre_SRE_Pattern_fullmatch__doc__, "Matches against all of the string."); #define _SRE_SRE_PATTERN_FULLMATCH_METHODDEF \ - {"fullmatch", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_fullmatch, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_fullmatch__doc__}, + {"fullmatch", _PyCFunction_CAST(_sre_SRE_Pattern_fullmatch), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_fullmatch__doc__}, static PyObject * _sre_SRE_Pattern_fullmatch_impl(PatternObject *self, PyTypeObject *cls, @@ -209,16 +274,75 @@ static PyObject * _sre_SRE_Pattern_fullmatch(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {"O|nn:fullmatch", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fullmatch", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &string, &pos, &endpos)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { goto exit; } + string = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + pos = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + endpos = ival; + } +skip_optional_pos: return_value = _sre_SRE_Pattern_fullmatch_impl(self, cls, string, pos, endpos); exit: @@ -234,7 +358,7 @@ PyDoc_STRVAR(_sre_SRE_Pattern_search__doc__, "Return None if no position in the string matches."); #define _SRE_SRE_PATTERN_SEARCH_METHODDEF \ - {"search", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_search, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_search__doc__}, + {"search", _PyCFunction_CAST(_sre_SRE_Pattern_search), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_search__doc__}, static PyObject * _sre_SRE_Pattern_search_impl(PatternObject *self, PyTypeObject *cls, @@ -245,16 +369,75 @@ static PyObject * _sre_SRE_Pattern_search(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {"O|nn:search", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "search", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &string, &pos, &endpos)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { goto exit; } + string = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + pos = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + endpos = ival; + } +skip_optional_pos: return_value = _sre_SRE_Pattern_search_impl(self, cls, string, pos, endpos); exit: @@ -268,7 +451,7 @@ PyDoc_STRVAR(_sre_SRE_Pattern_findall__doc__, "Return a list of all non-overlapping matches of pattern in string."); #define _SRE_SRE_PATTERN_FINDALL_METHODDEF \ - {"findall", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_findall, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_findall__doc__}, + {"findall", _PyCFunction_CAST(_sre_SRE_Pattern_findall), METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_findall__doc__}, static PyObject * _sre_SRE_Pattern_findall_impl(PatternObject *self, PyObject *string, @@ -278,8 +461,31 @@ static PyObject * _sre_SRE_Pattern_findall(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "findall", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "findall", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; @@ -339,7 +545,7 @@ PyDoc_STRVAR(_sre_SRE_Pattern_finditer__doc__, "For each match, the iterator returns a match object."); #define _SRE_SRE_PATTERN_FINDITER_METHODDEF \ - {"finditer", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_finditer, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_finditer__doc__}, + {"finditer", _PyCFunction_CAST(_sre_SRE_Pattern_finditer), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_finditer__doc__}, static PyObject * _sre_SRE_Pattern_finditer_impl(PatternObject *self, PyTypeObject *cls, @@ -350,16 +556,75 @@ static PyObject * _sre_SRE_Pattern_finditer(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {"O|nn:finditer", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "finditer", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &string, &pos, &endpos)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { goto exit; } + string = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + pos = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + endpos = ival; + } +skip_optional_pos: return_value = _sre_SRE_Pattern_finditer_impl(self, cls, string, pos, endpos); exit: @@ -372,7 +637,7 @@ PyDoc_STRVAR(_sre_SRE_Pattern_scanner__doc__, "\n"); #define _SRE_SRE_PATTERN_SCANNER_METHODDEF \ - {"scanner", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_scanner, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_scanner__doc__}, + {"scanner", _PyCFunction_CAST(_sre_SRE_Pattern_scanner), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_scanner__doc__}, static PyObject * _sre_SRE_Pattern_scanner_impl(PatternObject *self, PyTypeObject *cls, @@ -383,16 +648,75 @@ static PyObject * _sre_SRE_Pattern_scanner(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {"O|nn:scanner", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "scanner", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; Py_ssize_t pos = 0; Py_ssize_t endpos = PY_SSIZE_T_MAX; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &string, &pos, &endpos)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { goto exit; } + string = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + pos = ival; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + endpos = ival; + } +skip_optional_pos: return_value = _sre_SRE_Pattern_scanner_impl(self, cls, string, pos, endpos); exit: @@ -406,7 +730,7 @@ PyDoc_STRVAR(_sre_SRE_Pattern_split__doc__, "Split string by the occurrences of pattern."); #define _SRE_SRE_PATTERN_SPLIT_METHODDEF \ - {"split", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_split, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_split__doc__}, + {"split", _PyCFunction_CAST(_sre_SRE_Pattern_split), METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_split__doc__}, static PyObject * _sre_SRE_Pattern_split_impl(PatternObject *self, PyObject *string, @@ -416,8 +740,31 @@ static PyObject * _sre_SRE_Pattern_split(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "split", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; @@ -457,7 +804,7 @@ PyDoc_STRVAR(_sre_SRE_Pattern_sub__doc__, "Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl."); #define _SRE_SRE_PATTERN_SUB_METHODDEF \ - {"sub", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_sub, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_sub__doc__}, + {"sub", _PyCFunction_CAST(_sre_SRE_Pattern_sub), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_sub__doc__}, static PyObject * _sre_SRE_Pattern_sub_impl(PatternObject *self, PyTypeObject *cls, @@ -467,16 +814,59 @@ static PyObject * _sre_SRE_Pattern_sub(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(repl), &_Py_ID(string), &_Py_ID(count), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"repl", "string", "count", NULL}; - static _PyArg_Parser _parser = {"OO|n:sub", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sub", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *repl; PyObject *string; Py_ssize_t count = 0; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &repl, &string, &count)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { goto exit; } + repl = args[0]; + string = args[1]; + if (!noptargs) { + goto skip_optional_pos; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + count = ival; + } +skip_optional_pos: return_value = _sre_SRE_Pattern_sub_impl(self, cls, repl, string, count); exit: @@ -490,7 +880,7 @@ PyDoc_STRVAR(_sre_SRE_Pattern_subn__doc__, "Return the tuple (new_string, number_of_subs_made) found by replacing the leftmost non-overlapping occurrences of pattern with the replacement repl."); #define _SRE_SRE_PATTERN_SUBN_METHODDEF \ - {"subn", (PyCFunction)(void(*)(void))_sre_SRE_Pattern_subn, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_subn__doc__}, + {"subn", _PyCFunction_CAST(_sre_SRE_Pattern_subn), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Pattern_subn__doc__}, static PyObject * _sre_SRE_Pattern_subn_impl(PatternObject *self, PyTypeObject *cls, @@ -501,16 +891,59 @@ static PyObject * _sre_SRE_Pattern_subn(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(repl), &_Py_ID(string), &_Py_ID(count), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"repl", "string", "count", NULL}; - static _PyArg_Parser _parser = {"OO|n:subn", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "subn", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *repl; PyObject *string; Py_ssize_t count = 0; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &repl, &string, &count)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { goto exit; } + repl = args[0]; + string = args[1]; + if (!noptargs) { + goto skip_optional_pos; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + count = ival; + } +skip_optional_pos: return_value = _sre_SRE_Pattern_subn_impl(self, cls, repl, string, count); exit: @@ -549,7 +982,7 @@ PyDoc_STRVAR(_sre_compile__doc__, "\n"); #define _SRE_COMPILE_METHODDEF \ - {"compile", (PyCFunction)(void(*)(void))_sre_compile, METH_FASTCALL|METH_KEYWORDS, _sre_compile__doc__}, + {"compile", _PyCFunction_CAST(_sre_compile), METH_FASTCALL|METH_KEYWORDS, _sre_compile__doc__}, static PyObject * _sre_compile_impl(PyObject *module, PyObject *pattern, int flags, @@ -560,8 +993,31 @@ static PyObject * _sre_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 6 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pattern), &_Py_ID(flags), &_Py_ID(code), &_Py_ID(groups), &_Py_ID(groupindex), &_Py_ID(indexgroup), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"pattern", "flags", "code", "groups", "groupindex", "indexgroup", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; PyObject *pattern; int flags; @@ -612,6 +1068,45 @@ exit: return return_value; } +PyDoc_STRVAR(_sre_template__doc__, +"template($module, pattern, template, /)\n" +"--\n" +"\n" +"\n" +"\n" +" template\n" +" A list containing interleaved literal strings (str or bytes) and group\n" +" indices (int), as returned by re._parser.parse_template():\n" +" [literal1, group1, ..., literalN, groupN]"); + +#define _SRE_TEMPLATE_METHODDEF \ + {"template", _PyCFunction_CAST(_sre_template), METH_FASTCALL, _sre_template__doc__}, + +static PyObject * +_sre_template_impl(PyObject *module, PyObject *pattern, PyObject *template); + +static PyObject * +_sre_template(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *pattern; + PyObject *template; + + if (!_PyArg_CheckPositional("template", nargs, 2, 2)) { + goto exit; + } + pattern = args[0]; + if (!PyList_Check(args[1])) { + _PyArg_BadArgument("template", "argument 2", "list", args[1]); + goto exit; + } + template = args[1]; + return_value = _sre_template_impl(module, pattern, template); + +exit: + return return_value; +} + PyDoc_STRVAR(_sre_SRE_Match_expand__doc__, "expand($self, /, template)\n" "--\n" @@ -619,7 +1114,7 @@ PyDoc_STRVAR(_sre_SRE_Match_expand__doc__, "Return the string obtained by doing backslash substitution on the string template, as done by the sub() method."); #define _SRE_SRE_MATCH_EXPAND_METHODDEF \ - {"expand", (PyCFunction)(void(*)(void))_sre_SRE_Match_expand, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Match_expand__doc__}, + {"expand", _PyCFunction_CAST(_sre_SRE_Match_expand), METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Match_expand__doc__}, static PyObject * _sre_SRE_Match_expand_impl(MatchObject *self, PyObject *template); @@ -628,8 +1123,31 @@ static PyObject * _sre_SRE_Match_expand(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(template), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"template", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "expand", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "expand", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *template; @@ -654,7 +1172,7 @@ PyDoc_STRVAR(_sre_SRE_Match_groups__doc__, " Is used for groups that did not participate in the match."); #define _SRE_SRE_MATCH_GROUPS_METHODDEF \ - {"groups", (PyCFunction)(void(*)(void))_sre_SRE_Match_groups, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Match_groups__doc__}, + {"groups", _PyCFunction_CAST(_sre_SRE_Match_groups), METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Match_groups__doc__}, static PyObject * _sre_SRE_Match_groups_impl(MatchObject *self, PyObject *default_value); @@ -663,8 +1181,31 @@ static PyObject * _sre_SRE_Match_groups(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(default), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "groups", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "groups", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *default_value = Py_None; @@ -694,7 +1235,7 @@ PyDoc_STRVAR(_sre_SRE_Match_groupdict__doc__, " Is used for groups that did not participate in the match."); #define _SRE_SRE_MATCH_GROUPDICT_METHODDEF \ - {"groupdict", (PyCFunction)(void(*)(void))_sre_SRE_Match_groupdict, METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Match_groupdict__doc__}, + {"groupdict", _PyCFunction_CAST(_sre_SRE_Match_groupdict), METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Match_groupdict__doc__}, static PyObject * _sre_SRE_Match_groupdict_impl(MatchObject *self, PyObject *default_value); @@ -703,8 +1244,31 @@ static PyObject * _sre_SRE_Match_groupdict(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(default), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "groupdict", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "groupdict", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *default_value = Py_None; @@ -731,7 +1295,7 @@ PyDoc_STRVAR(_sre_SRE_Match_start__doc__, "Return index of the start of the substring matched by group."); #define _SRE_SRE_MATCH_START_METHODDEF \ - {"start", (PyCFunction)(void(*)(void))_sre_SRE_Match_start, METH_FASTCALL, _sre_SRE_Match_start__doc__}, + {"start", _PyCFunction_CAST(_sre_SRE_Match_start), METH_FASTCALL, _sre_SRE_Match_start__doc__}, static Py_ssize_t _sre_SRE_Match_start_impl(MatchObject *self, PyObject *group); @@ -768,7 +1332,7 @@ PyDoc_STRVAR(_sre_SRE_Match_end__doc__, "Return index of the end of the substring matched by group."); #define _SRE_SRE_MATCH_END_METHODDEF \ - {"end", (PyCFunction)(void(*)(void))_sre_SRE_Match_end, METH_FASTCALL, _sre_SRE_Match_end__doc__}, + {"end", _PyCFunction_CAST(_sre_SRE_Match_end), METH_FASTCALL, _sre_SRE_Match_end__doc__}, static Py_ssize_t _sre_SRE_Match_end_impl(MatchObject *self, PyObject *group); @@ -805,7 +1369,7 @@ PyDoc_STRVAR(_sre_SRE_Match_span__doc__, "For match object m, return the 2-tuple (m.start(group), m.end(group))."); #define _SRE_SRE_MATCH_SPAN_METHODDEF \ - {"span", (PyCFunction)(void(*)(void))_sre_SRE_Match_span, METH_FASTCALL, _sre_SRE_Match_span__doc__}, + {"span", _PyCFunction_CAST(_sre_SRE_Match_span), METH_FASTCALL, _sre_SRE_Match_span__doc__}, static PyObject * _sre_SRE_Match_span_impl(MatchObject *self, PyObject *group); @@ -861,7 +1425,7 @@ PyDoc_STRVAR(_sre_SRE_Scanner_match__doc__, "\n"); #define _SRE_SRE_SCANNER_MATCH_METHODDEF \ - {"match", (PyCFunction)(void(*)(void))_sre_SRE_Scanner_match, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Scanner_match__doc__}, + {"match", _PyCFunction_CAST(_sre_SRE_Scanner_match), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Scanner_match__doc__}, static PyObject * _sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls); @@ -869,18 +1433,11 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls); static PyObject * _sre_SRE_Scanner_match(ScannerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":match", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "match() takes no arguments"); + return NULL; } - return_value = _sre_SRE_Scanner_match_impl(self, cls); - -exit: - return return_value; + return _sre_SRE_Scanner_match_impl(self, cls); } PyDoc_STRVAR(_sre_SRE_Scanner_search__doc__, @@ -889,7 +1446,7 @@ PyDoc_STRVAR(_sre_SRE_Scanner_search__doc__, "\n"); #define _SRE_SRE_SCANNER_SEARCH_METHODDEF \ - {"search", (PyCFunction)(void(*)(void))_sre_SRE_Scanner_search, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Scanner_search__doc__}, + {"search", _PyCFunction_CAST(_sre_SRE_Scanner_search), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sre_SRE_Scanner_search__doc__}, static PyObject * _sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls); @@ -897,17 +1454,10 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls); static PyObject * _sre_SRE_Scanner_search(ScannerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":search", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "search() takes no arguments"); + return NULL; } - return_value = _sre_SRE_Scanner_search_impl(self, cls); - -exit: - return return_value; + return _sre_SRE_Scanner_search_impl(self, cls); } -/*[clinic end generated code: output=518f7bb775c1184f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e3ba72156dd71572 input=a9049054013a1b77]*/ diff --git a/Modules/_sre.c b/Modules/_sre/sre.c similarity index 86% rename from Modules/_sre.c rename to Modules/_sre/sre.c index 213730860cf..4b6290a5967 100644 --- a/Modules/_sre.c +++ b/Modules/_sre/sre.c @@ -51,13 +51,6 @@ static const char copyright[] = #include -/* name of this module, minus the leading underscore */ -#if !defined(SRE_MODULE) -#define SRE_MODULE "sre" -#endif - -#define SRE_PY_MODULE "re" - /* defining this one enables tracing */ #undef VERBOSE @@ -254,6 +247,8 @@ typedef struct { PyTypeObject *Pattern_Type; PyTypeObject *Match_Type; PyTypeObject *Scanner_Type; + PyTypeObject *Template_Type; + PyObject *compile_template; // reference to re._compile_template } _sremodulestate; static _sremodulestate * @@ -464,8 +459,7 @@ state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string, state->start = (void*) ((char*) ptr + start * state->charsize); state->end = (void*) ((char*) ptr + end * state->charsize); - Py_INCREF(string); - state->string = string; + state->string = Py_NewRef(string); state->pos = start; state->endpos = end; @@ -504,8 +498,7 @@ getslice(int isbytes, const void *ptr, if (isbytes) { if (PyBytes_CheckExact(string) && start == 0 && end == PyBytes_GET_SIZE(string)) { - Py_INCREF(string); - return string; + return Py_NewRef(string); } return PyBytes_FromStringAndSize( (const char *)ptr + start, end - start); @@ -532,6 +525,14 @@ state_getslice(SRE_STATE* state, Py_ssize_t index, PyObject* string, int empty) } else { i = STATE_OFFSET(state, state->mark[index]); j = STATE_OFFSET(state, state->mark[index+1]); + + /* check wrong span */ + if (i > j) { + PyErr_SetString(PyExc_SystemError, + "The span of capturing group is wrong," + " please report a bug for the re module."); + return NULL; + } } return getslice(state->isbytes, state->beginning, string, i, j); @@ -749,33 +750,6 @@ _sre_SRE_Pattern_search_impl(PatternObject *self, PyTypeObject *cls, return match; } -static PyObject* -call(const char* module, const char* function, PyObject* args) -{ - PyObject* name; - PyObject* mod; - PyObject* func; - PyObject* result; - - if (!args) - return NULL; - name = PyUnicode_FromString(module); - if (!name) - return NULL; - mod = PyImport_Import(name); - Py_DECREF(name); - if (!mod) - return NULL; - func = PyObject_GetAttrString(mod, function); - Py_DECREF(mod); - if (!func) - return NULL; - result = PyObject_CallObject(func, args); - Py_DECREF(func); - Py_DECREF(args); - return result; -} - /*[clinic input] _sre.SRE_Pattern.findall @@ -1038,6 +1012,57 @@ error: } +static PyObject * +compile_template(_sremodulestate *module_state, + PatternObject *pattern, PyObject *template) +{ + /* delegate to Python code */ + PyObject *func = module_state->compile_template; + if (func == NULL) { + func = _PyImport_GetModuleAttrString("re", "_compile_template"); + if (func == NULL) { + return NULL; + } + Py_XSETREF(module_state->compile_template, func); + } + + PyObject *args[] = {(PyObject *)pattern, template}; + PyObject *result = PyObject_Vectorcall(func, args, 2, NULL); + + if (result == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) { + /* If the replacement string is unhashable (e.g. bytearray), + * convert it to the basic type (str or bytes) and repeat. */ + if (PyUnicode_Check(template) && !PyUnicode_CheckExact(template)) { + PyErr_Clear(); + template = _PyUnicode_Copy(template); + } + else if (PyObject_CheckBuffer(template) && !PyBytes_CheckExact(template)) { + PyErr_Clear(); + template = PyBytes_FromObject(template); + } + else { + return NULL; + } + if (template == NULL) { + return NULL; + } + args[1] = template; + result = PyObject_Vectorcall(func, args, 2, NULL); + Py_DECREF(template); + } + + if (result != NULL && Py_TYPE(result) != module_state->Template_Type) { + PyErr_Format(PyExc_RuntimeError, + "the result of compiling a replacement string is %.200s", + Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; + } + return result; +} + +static PyObject *expand_template(TemplateObject *, MatchObject *); /* Forward */ + static PyObject* pattern_subx(_sremodulestate* module_state, PatternObject* self, @@ -1057,14 +1082,13 @@ pattern_subx(_sremodulestate* module_state, Py_ssize_t n; Py_ssize_t i, b, e; int isbytes, charsize; - int filter_is_callable; + enum {LITERAL, TEMPLATE, CALLABLE} filter_type; Py_buffer view; if (PyCallable_Check(ptemplate)) { /* sub/subn takes either a function or a template */ - filter = ptemplate; - Py_INCREF(filter); - filter_is_callable = 1; + filter = Py_NewRef(ptemplate); + filter_type = CALLABLE; } else { /* if not callable, check if it's a literal string */ int literal; @@ -1082,18 +1106,23 @@ pattern_subx(_sremodulestate* module_state, if (view.buf) PyBuffer_Release(&view); if (literal) { - filter = ptemplate; - Py_INCREF(filter); - filter_is_callable = 0; + filter = Py_NewRef(ptemplate); + filter_type = LITERAL; } else { /* not a literal; hand it over to the template compiler */ - filter = call( - SRE_PY_MODULE, "_subx", - PyTuple_Pack(2, self, ptemplate) - ); + filter = compile_template(module_state, self, ptemplate); if (!filter) return NULL; - filter_is_callable = PyCallable_Check(filter); + + assert(Py_TYPE(filter) == module_state->Template_Type); + if (Py_SIZE(filter) == 0) { + Py_SETREF(filter, + Py_NewRef(((TemplateObject *)filter)->literal)); + filter_type = LITERAL; + } + else { + filter_type = TEMPLATE; + } } } @@ -1144,19 +1173,25 @@ pattern_subx(_sremodulestate* module_state, } - if (filter_is_callable) { + if (filter_type != LITERAL) { /* pass match object through filter */ match = pattern_new_match(module_state, self, &state, 1); if (!match) goto error; - item = PyObject_CallOneArg(filter, match); + if (filter_type == TEMPLATE) { + item = expand_template((TemplateObject *)filter, + (MatchObject *)match); + } + else { + assert(filter_type == CALLABLE); + item = PyObject_CallOneArg(filter, match); + } Py_DECREF(match); if (!item) goto error; } else { /* filter is literal string */ - item = filter; - Py_INCREF(item); + item = Py_NewRef(filter); } /* add to list */ @@ -1277,8 +1312,7 @@ static PyObject * _sre_SRE_Pattern___copy___impl(PatternObject *self) /*[clinic end generated code: output=85dedc2db1bd8694 input=a730a59d863bc9f5]*/ { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } /*[clinic input] @@ -1293,8 +1327,7 @@ static PyObject * _sre_SRE_Pattern___deepcopy__(PatternObject *self, PyObject *memo) /*[clinic end generated code: output=2ad25679c1f1204a input=a465b1602f997bed]*/ { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } static PyObject * @@ -1460,19 +1493,16 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags, PyBuffer_Release(&view); } - Py_INCREF(pattern); - self->pattern = pattern; + self->pattern = Py_NewRef(pattern); self->flags = flags; self->groups = groups; if (PyDict_GET_SIZE(groupindex) > 0) { - Py_INCREF(groupindex); - self->groupindex = groupindex; + self->groupindex = Py_NewRef(groupindex); if (PyTuple_GET_SIZE(indexgroup) > 0) { - Py_INCREF(indexgroup); - self->indexgroup = indexgroup; + self->indexgroup = Py_NewRef(indexgroup); } } @@ -1484,6 +1514,67 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags, return (PyObject*) self; } +/*[clinic input] +_sre.template + + pattern: object + template: object(subclass_of="&PyList_Type") + A list containing interleaved literal strings (str or bytes) and group + indices (int), as returned by re._parser.parse_template(): + [literal1, group1, ..., literalN, groupN] + / + +[clinic start generated code]*/ + +static PyObject * +_sre_template_impl(PyObject *module, PyObject *pattern, PyObject *template) +/*[clinic end generated code: output=d51290e596ebca86 input=af55380b27f02942]*/ +{ + /* template is a list containing interleaved literal strings (str or bytes) + * and group indices (int), as returned by _parser.parse_template: + * [literal1, group1, literal2, ..., literalN]. + */ + _sremodulestate *module_state = get_sre_module_state(module); + TemplateObject *self = NULL; + Py_ssize_t n = PyList_GET_SIZE(template); + if ((n & 1) == 0 || n < 1) { + goto bad_template; + } + n /= 2; + self = PyObject_GC_NewVar(TemplateObject, module_state->Template_Type, n); + if (!self) + return NULL; + self->chunks = 1 + 2*n; + self->literal = Py_NewRef(PyList_GET_ITEM(template, 0)); + for (Py_ssize_t i = 0; i < n; i++) { + Py_ssize_t index = PyLong_AsSsize_t(PyList_GET_ITEM(template, 2*i+1)); + if (index == -1 && PyErr_Occurred()) { + Py_DECREF(self); + return NULL; + } + if (index < 0) { + goto bad_template; + } + self->items[i].index = index; + + PyObject *literal = PyList_GET_ITEM(template, 2*i+2); + // Skip empty literals. + if ((PyUnicode_Check(literal) && !PyUnicode_GET_LENGTH(literal)) || + (PyBytes_Check(literal) && !PyBytes_GET_SIZE(literal))) + { + literal = NULL; + self->chunks--; + } + self->items[i].literal = Py_XNewRef(literal); + } + return (PyObject*) self; + +bad_template: + PyErr_SetString(PyExc_TypeError, "invalid template"); + Py_XDECREF(self); + return NULL; +} + /* -------------------------------------------------------------------- */ /* Code validation */ @@ -1520,7 +1611,7 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags, #endif /* Report failure */ -#define FAIL do { VTRACE(("FAIL: %d\n", __LINE__)); return 0; } while (0) +#define FAIL do { VTRACE(("FAIL: %d\n", __LINE__)); return -1; } while (0) /* Extract opcode, argument, or skip count from code array */ #define GET_OP \ @@ -1544,7 +1635,7 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags, skip = *code; \ VTRACE(("%lu (skip to %p)\n", \ (unsigned long)skip, code+skip)); \ - if (skip-adj > (uintptr_t)(end - code)) \ + if (skip-adj > (uintptr_t)(end - code)) \ FAIL; \ code++; \ } while (0) @@ -1633,9 +1724,10 @@ _validate_charset(SRE_CODE *code, SRE_CODE *end) } } - return 1; + return 0; } +/* Returns 0 on success, -1 on failure, and 1 if the last op is JUMP. */ static int _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) { @@ -1713,7 +1805,7 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) case SRE_OP_IN_LOC_IGNORE: GET_SKIP; /* Stop 1 before the end; we check the FAILURE below */ - if (!_validate_charset(code, code+skip-2)) + if (_validate_charset(code, code+skip-2)) FAIL; if (code[skip-2] != SRE_OP_FAILURE) FAIL; @@ -1767,7 +1859,7 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) } /* Validate the charset */ if (flags & SRE_INFO_CHARSET) { - if (!_validate_charset(code, newcode-1)) + if (_validate_charset(code, newcode-1)) FAIL; if (newcode[-1] != SRE_OP_FAILURE) FAIL; @@ -1788,7 +1880,7 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) if (skip == 0) break; /* Stop 2 before the end; we check the JUMP below */ - if (!_validate_inner(code, code+skip-3, groups)) + if (_validate_inner(code, code+skip-3, groups)) FAIL; code += skip-3; /* Check that it ends with a JUMP, and that each JUMP @@ -1802,11 +1894,14 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) else if (code+skip-1 != target) FAIL; } + if (code != target) + FAIL; } break; case SRE_OP_REPEAT_ONE: case SRE_OP_MIN_REPEAT_ONE: + case SRE_OP_POSSESSIVE_REPEAT_ONE: { SRE_CODE min, max; GET_SKIP; @@ -1816,7 +1911,7 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) FAIL; if (max > SRE_MAXREPEAT) FAIL; - if (!_validate_inner(code, code+skip-4, groups)) + if (_validate_inner(code, code+skip-4, groups)) FAIL; code += skip-4; GET_OP; @@ -1826,8 +1921,9 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) break; case SRE_OP_REPEAT: + case SRE_OP_POSSESSIVE_REPEAT: { - SRE_CODE min, max; + SRE_CODE op1 = op, min, max; GET_SKIP; GET_ARG; min = arg; GET_ARG; max = arg; @@ -1835,11 +1931,29 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) FAIL; if (max > SRE_MAXREPEAT) FAIL; - if (!_validate_inner(code, code+skip-3, groups)) + if (_validate_inner(code, code+skip-3, groups)) FAIL; code += skip-3; GET_OP; - if (op != SRE_OP_MAX_UNTIL && op != SRE_OP_MIN_UNTIL) + if (op1 == SRE_OP_POSSESSIVE_REPEAT) { + if (op != SRE_OP_SUCCESS) + FAIL; + } + else { + if (op != SRE_OP_MAX_UNTIL && op != SRE_OP_MIN_UNTIL) + FAIL; + } + } + break; + + case SRE_OP_ATOMIC_GROUP: + { + GET_SKIP; + if (_validate_inner(code, code+skip-2, groups)) + FAIL; + code += skip-2; + GET_OP; + if (op != SRE_OP_SUCCESS) FAIL; } break; @@ -1887,24 +2001,17 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) to allow arbitrary jumps anywhere in the code; so we just look for a JUMP opcode preceding our skip target. */ - if (skip >= 3 && skip-3 < (uintptr_t)(end - code) && - code[skip-3] == SRE_OP_JUMP) - { - VTRACE(("both then and else parts present\n")); - if (!_validate_inner(code+1, code+skip-3, groups)) - FAIL; + VTRACE(("then part:\n")); + int rc = _validate_inner(code+1, code+skip-1, groups); + if (rc == 1) { + VTRACE(("else part:\n")); code += skip-2; /* Position after JUMP, at */ GET_SKIP; - if (!_validate_inner(code, code+skip-1, groups)) - FAIL; - code += skip-1; - } - else { - VTRACE(("only a then part present\n")); - if (!_validate_inner(code+1, code+skip-1, groups)) - FAIL; - code += skip-1; + rc = _validate_inner(code, code+skip-1, groups); } + if (rc) + FAIL; + code += skip-1; break; case SRE_OP_ASSERT: @@ -1915,7 +2022,7 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) if (arg & 0x80000000) FAIL; /* Width too large */ /* Stop 1 before the end; we check the SUCCESS below */ - if (!_validate_inner(code+1, code+skip-2, groups)) + if (_validate_inner(code+1, code+skip-2, groups)) FAIL; code += skip-2; GET_OP; @@ -1923,6 +2030,12 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) FAIL; break; + case SRE_OP_JUMP: + if (code + 1 != end) + FAIL; + VTRACE(("JUMP: %d\n", __LINE__)); + return 1; + default: FAIL; @@ -1930,7 +2043,7 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) } VTRACE(("okay\n")); - return 1; + return 0; } static int @@ -1945,7 +2058,7 @@ _validate_outer(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) static int _validate(PatternObject *self) { - if (!_validate_outer(self->code, self->code+self->codesize, self->groups)) + if (_validate_outer(self->code, self->code+self->codesize, self->groups)) { PyErr_SetString(PyExc_RuntimeError, "invalid SRE code"); return 0; @@ -2003,8 +2116,7 @@ match_getslice_by_index(MatchObject* self, Py_ssize_t index, PyObject* def) if (self->string == Py_None || self->mark[index] < 0) { /* return default value if the string or group is undefined */ - Py_INCREF(def); - return def; + return Py_NewRef(def); } ptr = getstring(self->string, &length, &isbytes, &charsize, &view); @@ -2078,11 +2190,14 @@ static PyObject * _sre_SRE_Match_expand_impl(MatchObject *self, PyObject *template) /*[clinic end generated code: output=931b58ccc323c3a1 input=4bfdb22c2f8b146a]*/ { - /* delegate to Python code */ - return call( - SRE_PY_MODULE, "_expand", - PyTuple_Pack(3, self->pattern, self, template) - ); + _sremodulestate *module_state = get_sre_module_state_by_class(Py_TYPE(self)); + PyObject *filter = compile_template(module_state, self->pattern, template); + if (filter == NULL) { + return NULL; + } + PyObject *result = expand_template((TemplateObject *)filter, self); + Py_DECREF(filter); + return result; } static PyObject* @@ -2320,8 +2435,7 @@ match_regs(MatchObject* self) PyTuple_SET_ITEM(regs, index, item); } - Py_INCREF(regs); - self->regs = regs; + self->regs = Py_NewRef(regs); return regs; } @@ -2335,8 +2449,7 @@ static PyObject * _sre_SRE_Match___copy___impl(MatchObject *self) /*[clinic end generated code: output=a779c5fc8b5b4eb4 input=3bb4d30b6baddb5b]*/ { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } /*[clinic input] @@ -2351,8 +2464,7 @@ static PyObject * _sre_SRE_Match___deepcopy__(MatchObject *self, PyObject *memo) /*[clinic end generated code: output=ba7cb46d655e4ee2 input=779d12a31c2c325e]*/ { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } PyDoc_STRVAR(match_doc, @@ -2381,8 +2493,7 @@ match_lastgroup_get(MatchObject *self, void *Py_UNUSED(ignored)) { PyObject *result = PyTuple_GET_ITEM(self->pattern->indexgroup, self->lastindex); - Py_INCREF(result); - return result; + return Py_NewRef(result); } Py_RETURN_NONE; } @@ -2391,8 +2502,7 @@ static PyObject * match_regs_get(MatchObject *self, void *Py_UNUSED(ignored)) { if (self->regs) { - Py_INCREF(self->regs); - return self->regs; + return Py_NewRef(self->regs); } else return match_regs(self); } @@ -2436,11 +2546,9 @@ pattern_new_match(_sremodulestate* module_state, if (!match) return NULL; - Py_INCREF(pattern); - match->pattern = pattern; + match->pattern = (PatternObject*)Py_NewRef(pattern); - Py_INCREF(state->string); - match->string = state->string; + match->string = Py_NewRef(state->string); match->regs = NULL; match->groups = pattern->groups+1; @@ -2457,6 +2565,15 @@ pattern_new_match(_sremodulestate* module_state, if (j+1 <= state->lastmark && state->mark[j] && state->mark[j+1]) { match->mark[j+2] = ((char*) state->mark[j] - base) / n; match->mark[j+3] = ((char*) state->mark[j+1] - base) / n; + + /* check wrong span */ + if (match->mark[j+2] > match->mark[j+3]) { + PyErr_SetString(PyExc_SystemError, + "The span of capturing group is wrong," + " please report a bug for the re module."); + Py_DECREF(match); + return NULL; + } } else match->mark[j+2] = match->mark[j+3] = -1; /* undefined */ @@ -2511,6 +2628,25 @@ scanner_dealloc(ScannerObject* self) Py_DECREF(tp); } +static int +scanner_begin(ScannerObject* self) +{ + if (self->executing) { + PyErr_SetString(PyExc_ValueError, + "regular expression scanner already executing"); + return 0; + } + self->executing = 1; + return 1; +} + +static void +scanner_end(ScannerObject* self) +{ + assert(self->executing); + self->executing = 0; +} + /*[clinic input] _sre.SRE_Scanner.match @@ -2528,16 +2664,23 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls) PyObject* match; Py_ssize_t status; - if (state->start == NULL) + if (!scanner_begin(self)) { + return NULL; + } + if (state->start == NULL) { + scanner_end(self); Py_RETURN_NONE; + } state_reset(state); state->ptr = state->start; status = sre_match(state, PatternObject_GetCode(self->pattern)); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + scanner_end(self); return NULL; + } match = pattern_new_match(module_state, (PatternObject*) self->pattern, state, status); @@ -2549,6 +2692,7 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls) state->start = state->ptr; } + scanner_end(self); return match; } @@ -2570,16 +2714,23 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls) PyObject* match; Py_ssize_t status; - if (state->start == NULL) + if (!scanner_begin(self)) { + return NULL; + } + if (state->start == NULL) { + scanner_end(self); Py_RETURN_NONE; + } state_reset(state); state->ptr = state->start; status = sre_search(state, PatternObject_GetCode(self->pattern)); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + scanner_end(self); return NULL; + } match = pattern_new_match(module_state, (PatternObject*) self->pattern, state, status); @@ -2591,6 +2742,7 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls) state->start = state->ptr; } + scanner_end(self); return match; } @@ -2608,6 +2760,7 @@ pattern_scanner(_sremodulestate *module_state, if (!scanner) return NULL; scanner->pattern = NULL; + scanner->executing = 0; /* create search state object */ if (!state_init(&scanner->state, self, string, pos, endpos)) { @@ -2615,13 +2768,114 @@ pattern_scanner(_sremodulestate *module_state, return NULL; } - Py_INCREF(self); - scanner->pattern = (PyObject*) self; + scanner->pattern = Py_NewRef(self); PyObject_GC_Track(scanner); return (PyObject*) scanner; } +/* -------------------------------------------------------------------- */ +/* template methods */ + +static int +template_traverse(TemplateObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->literal); + for (Py_ssize_t i = 0, n = Py_SIZE(self); i < n; i++) { + Py_VISIT(self->items[i].literal); + } + return 0; +} + +static int +template_clear(TemplateObject *self) +{ + Py_CLEAR(self->literal); + for (Py_ssize_t i = 0, n = Py_SIZE(self); i < n; i++) { + Py_CLEAR(self->items[i].literal); + } + return 0; +} + +static void +template_dealloc(TemplateObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + + PyObject_GC_UnTrack(self); + (void)template_clear(self); + tp->tp_free(self); + Py_DECREF(tp); +} + +static PyObject * +expand_template(TemplateObject *self, MatchObject *match) +{ + if (Py_SIZE(self) == 0) { + return Py_NewRef(self->literal); + } + + PyObject *result = NULL; + Py_ssize_t count = 0; // the number of non-empty chunks + /* For small number of strings use a buffer allocated on the stack, + * otherwise use a list object. */ + PyObject *buffer[10]; + PyObject **out = buffer; + PyObject *list = NULL; + if (self->chunks > (int)Py_ARRAY_LENGTH(buffer) || + !PyUnicode_Check(self->literal)) + { + list = PyList_New(self->chunks); + if (!list) { + return NULL; + } + out = &PyList_GET_ITEM(list, 0); + } + + out[count++] = Py_NewRef(self->literal); + for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { + Py_ssize_t index = self->items[i].index; + if (index >= match->groups) { + PyErr_SetString(PyExc_IndexError, "no such group"); + goto cleanup; + } + PyObject *item = match_getslice_by_index(match, index, Py_None); + if (item == NULL) { + goto cleanup; + } + if (item != Py_None) { + out[count++] = Py_NewRef(item); + } + Py_DECREF(item); + + PyObject *literal = self->items[i].literal; + if (literal != NULL) { + out[count++] = Py_NewRef(literal); + } + } + + if (PyUnicode_Check(self->literal)) { + result = _PyUnicode_JoinArray(&_Py_STR(empty), out, count); + } + else { + Py_SET_SIZE(list, count); + result = _PyBytes_Join((PyObject *)&_Py_SINGLETON(bytes_empty), list); + } + +cleanup: + if (list) { + Py_DECREF(list); + } + else { + for (Py_ssize_t i = 0; i < count; i++) { + Py_DECREF(out[i]); + } + } + return result; +} + + static Py_hash_t pattern_hash(PatternObject *self) { @@ -2694,7 +2948,7 @@ pattern_richcompare(PyObject *lefto, PyObject *righto, int op) return PyBool_FromLong(cmp); } -#include "clinic/_sre.c.h" +#include "clinic/sre.c.h" static PyMethodDef pattern_methods[] = { _SRE_SRE_PATTERN_MATCH_METHODDEF @@ -2844,15 +3098,32 @@ static PyType_Slot scanner_slots[] = { }; static PyType_Spec scanner_spec = { - .name = "_" SRE_MODULE ".SRE_Scanner", + .name = "_sre.SRE_Scanner", .basicsize = sizeof(ScannerObject), .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), .slots = scanner_slots, }; +static PyType_Slot template_slots[] = { + {Py_tp_dealloc, template_dealloc}, + {Py_tp_traverse, template_traverse}, + {Py_tp_clear, template_clear}, + {0, NULL}, +}; + +static PyType_Spec template_spec = { + .name = "_sre.SRE_Template", + .basicsize = sizeof(TemplateObject), + .itemsize = sizeof(((TemplateObject *)0)->items[0]), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), + .slots = template_slots, +}; + static PyMethodDef _functions[] = { _SRE_COMPILE_METHODDEF + _SRE_TEMPLATE_METHODDEF _SRE_GETCODESIZE_METHODDEF _SRE_ASCII_ISCASED_METHODDEF _SRE_UNICODE_ISCASED_METHODDEF @@ -2869,6 +3140,8 @@ sre_traverse(PyObject *module, visitproc visit, void *arg) Py_VISIT(state->Pattern_Type); Py_VISIT(state->Match_Type); Py_VISIT(state->Scanner_Type); + Py_VISIT(state->Template_Type); + Py_VISIT(state->compile_template); return 0; } @@ -2881,6 +3154,8 @@ sre_clear(PyObject *module) Py_CLEAR(state->Pattern_Type); Py_CLEAR(state->Match_Type); Py_CLEAR(state->Scanner_Type); + Py_CLEAR(state->Template_Type); + Py_CLEAR(state->compile_template); return 0; } @@ -2921,6 +3196,7 @@ sre_exec(PyObject *m) CREATE_TYPE(m, state->Pattern_Type, &pattern_spec); CREATE_TYPE(m, state->Match_Type, &match_spec); CREATE_TYPE(m, state->Scanner_Type, &scanner_spec); + CREATE_TYPE(m, state->Template_Type, &template_spec); if (PyModule_AddIntConstant(m, "MAGIC", SRE_MAGIC) < 0) { goto error; @@ -2950,7 +3226,7 @@ static PyModuleDef_Slot sre_slots[] = { static struct PyModuleDef sremodule = { .m_base = PyModuleDef_HEAD_INIT, - .m_name = "_" SRE_MODULE, + .m_name = "_sre", .m_size = sizeof(_sremodulestate), .m_methods = _functions, .m_slots = sre_slots, diff --git a/Modules/sre.h b/Modules/_sre/sre.h similarity index 81% rename from Modules/sre.h rename to Modules/_sre/sre.h index 9b0d8b19042..d967d9ea04b 100644 --- a/Modules/sre.h +++ b/Modules/_sre/sre.h @@ -5,7 +5,7 @@ * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * - * See the _sre.c file for information on usage and redistribution. + * See the sre.c file for information on usage and redistribution. */ #ifndef SRE_INCLUDED @@ -18,10 +18,10 @@ #define SRE_CODE Py_UCS4 #if SIZEOF_SIZE_T > 4 # define SRE_MAXREPEAT (~(SRE_CODE)0) -# define SRE_MAXGROUPS ((~(SRE_CODE)0) / 2) +# define SRE_MAXGROUPS ((SRE_CODE)INT32_MAX / 2) #else # define SRE_MAXREPEAT ((SRE_CODE)PY_SSIZE_T_MAX) -# define SRE_MAXGROUPS ((SRE_CODE)PY_SSIZE_T_MAX / SIZEOF_SIZE_T / 2) +# define SRE_MAXGROUPS ((SRE_CODE)PY_SSIZE_T_MAX / SIZEOF_VOID_P / 2) #endif typedef struct { @@ -52,6 +52,17 @@ typedef struct { Py_ssize_t mark[1]; } MatchObject; +typedef struct { + PyObject_VAR_HEAD + Py_ssize_t chunks; /* the number of group references and non-NULL literals + * self->chunks <= 2*Py_SIZE(self) + 1 */ + PyObject *literal; + struct { + Py_ssize_t index; + PyObject *literal; /* NULL if empty */ + } items[0]; +} TemplateObject; + typedef struct SRE_REPEAT_T { Py_ssize_t count; const SRE_CODE* pattern; /* points to REPEAT operator arguments */ @@ -71,12 +82,12 @@ typedef struct { Py_ssize_t pos, endpos; int isbytes; int charsize; /* character size */ - /* registers */ - Py_ssize_t lastindex; - Py_ssize_t lastmark; - const void** mark; int match_all; int must_advance; + /* marks */ + int lastmark; + int lastindex; + const void** mark; /* dynamically allocated stuff */ char* data_stack; size_t data_stack_size; @@ -89,6 +100,7 @@ typedef struct { PyObject_HEAD PyObject* pattern; SRE_STATE state; + int executing; } ScannerObject; #endif diff --git a/Modules/sre_constants.h b/Modules/_sre/sre_constants.h similarity index 56% rename from Modules/sre_constants.h rename to Modules/_sre/sre_constants.h index c8ccb32d21d..b5692292f65 100644 --- a/Modules/sre_constants.h +++ b/Modules/_sre/sre_constants.h @@ -3,15 +3,15 @@ * * regular expression matching engine * - * NOTE: This file is generated by sre_constants.py. If you need - * to change anything in here, edit sre_constants.py and run it. + * Auto-generated by Tools/build/generate_sre_constants.py from + * Lib/re/_constants.py. * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * - * See the _sre.c file for information on usage and redistribution. + * See the sre.c file for information on usage and redistribution. */ -#define SRE_MAGIC 20171005 +#define SRE_MAGIC 20221023 #define SRE_OP_FAILURE 0 #define SRE_OP_SUCCESS 1 #define SRE_OP_ANY 2 @@ -20,39 +20,41 @@ #define SRE_OP_ASSERT_NOT 5 #define SRE_OP_AT 6 #define SRE_OP_BRANCH 7 -#define SRE_OP_CALL 8 -#define SRE_OP_CATEGORY 9 -#define SRE_OP_CHARSET 10 -#define SRE_OP_BIGCHARSET 11 -#define SRE_OP_GROUPREF 12 -#define SRE_OP_GROUPREF_EXISTS 13 -#define SRE_OP_IN 14 -#define SRE_OP_INFO 15 -#define SRE_OP_JUMP 16 -#define SRE_OP_LITERAL 17 -#define SRE_OP_MARK 18 -#define SRE_OP_MAX_UNTIL 19 -#define SRE_OP_MIN_UNTIL 20 -#define SRE_OP_NOT_LITERAL 21 -#define SRE_OP_NEGATE 22 -#define SRE_OP_RANGE 23 -#define SRE_OP_REPEAT 24 -#define SRE_OP_REPEAT_ONE 25 -#define SRE_OP_SUBPATTERN 26 -#define SRE_OP_MIN_REPEAT_ONE 27 -#define SRE_OP_GROUPREF_IGNORE 28 -#define SRE_OP_IN_IGNORE 29 -#define SRE_OP_LITERAL_IGNORE 30 -#define SRE_OP_NOT_LITERAL_IGNORE 31 -#define SRE_OP_GROUPREF_LOC_IGNORE 32 -#define SRE_OP_IN_LOC_IGNORE 33 -#define SRE_OP_LITERAL_LOC_IGNORE 34 -#define SRE_OP_NOT_LITERAL_LOC_IGNORE 35 -#define SRE_OP_GROUPREF_UNI_IGNORE 36 -#define SRE_OP_IN_UNI_IGNORE 37 -#define SRE_OP_LITERAL_UNI_IGNORE 38 -#define SRE_OP_NOT_LITERAL_UNI_IGNORE 39 -#define SRE_OP_RANGE_UNI_IGNORE 40 +#define SRE_OP_CATEGORY 8 +#define SRE_OP_CHARSET 9 +#define SRE_OP_BIGCHARSET 10 +#define SRE_OP_GROUPREF 11 +#define SRE_OP_GROUPREF_EXISTS 12 +#define SRE_OP_IN 13 +#define SRE_OP_INFO 14 +#define SRE_OP_JUMP 15 +#define SRE_OP_LITERAL 16 +#define SRE_OP_MARK 17 +#define SRE_OP_MAX_UNTIL 18 +#define SRE_OP_MIN_UNTIL 19 +#define SRE_OP_NOT_LITERAL 20 +#define SRE_OP_NEGATE 21 +#define SRE_OP_RANGE 22 +#define SRE_OP_REPEAT 23 +#define SRE_OP_REPEAT_ONE 24 +#define SRE_OP_SUBPATTERN 25 +#define SRE_OP_MIN_REPEAT_ONE 26 +#define SRE_OP_ATOMIC_GROUP 27 +#define SRE_OP_POSSESSIVE_REPEAT 28 +#define SRE_OP_POSSESSIVE_REPEAT_ONE 29 +#define SRE_OP_GROUPREF_IGNORE 30 +#define SRE_OP_IN_IGNORE 31 +#define SRE_OP_LITERAL_IGNORE 32 +#define SRE_OP_NOT_LITERAL_IGNORE 33 +#define SRE_OP_GROUPREF_LOC_IGNORE 34 +#define SRE_OP_IN_LOC_IGNORE 35 +#define SRE_OP_LITERAL_LOC_IGNORE 36 +#define SRE_OP_NOT_LITERAL_LOC_IGNORE 37 +#define SRE_OP_GROUPREF_UNI_IGNORE 38 +#define SRE_OP_IN_UNI_IGNORE 39 +#define SRE_OP_LITERAL_UNI_IGNORE 40 +#define SRE_OP_NOT_LITERAL_UNI_IGNORE 41 +#define SRE_OP_RANGE_UNI_IGNORE 42 #define SRE_AT_BEGINNING 0 #define SRE_AT_BEGINNING_LINE 1 #define SRE_AT_BEGINNING_STRING 2 diff --git a/Modules/sre_lib.h b/Modules/_sre/sre_lib.h similarity index 59% rename from Modules/sre_lib.h rename to Modules/_sre/sre_lib.h index 322f66fb4da..fb4c18b63d6 100644 --- a/Modules/sre_lib.h +++ b/Modules/_sre/sre_lib.h @@ -5,7 +5,7 @@ * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * - * See the _sre.c file for information on usage and redistribution. + * See the sre.c file for information on usage and redistribution. */ /* String matching engine */ @@ -333,34 +333,6 @@ SRE(count)(SRE_STATE* state, const SRE_CODE* pattern, Py_ssize_t maxcount) return ptr - (SRE_CHAR*) state->ptr; } -#if 0 /* not used in this release */ -LOCAL(int) -SRE(info)(SRE_STATE* state, const SRE_CODE* pattern) -{ - /* check if an SRE_OP_INFO block matches at the current position. - returns the number of SRE_CODE objects to skip if successful, 0 - if no match */ - - const SRE_CHAR* end = (const SRE_CHAR*) state->end; - const SRE_CHAR* ptr = (const SRE_CHAR*) state->ptr; - Py_ssize_t i; - - /* check minimal length */ - if (pattern[3] && end - ptr < pattern[3]) - return 0; - - /* check known prefix */ - if (pattern[2] & SRE_INFO_PREFIX && pattern[5] > 1) { - /* */ - for (i = 0; i < pattern[5]; i++) - if ((SRE_CODE) ptr[i] != pattern[7 + i]) - return 0; - return pattern[0] + 2 * pattern[6]; - } - return pattern[0]; -} -#endif - /* The macros below should be used to protect recursive SRE(match)() * calls that *failed* and do *not* return immediately (IOW, those * that will backtrack). Explaining: @@ -477,21 +449,24 @@ do { \ DATA_STACK_LOOKUP_AT(state,t,p,pos) #define MARK_PUSH(lastmark) \ - do if (lastmark > 0) { \ - i = lastmark; /* ctx->lastmark may change if reallocated */ \ - DATA_STACK_PUSH(state, state->mark, (i+1)*sizeof(void*)); \ + do if (lastmark >= 0) { \ + size_t _marks_size = (lastmark+1) * sizeof(void*); \ + DATA_STACK_PUSH(state, state->mark, _marks_size); \ } while (0) #define MARK_POP(lastmark) \ - do if (lastmark > 0) { \ - DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 1); \ + do if (lastmark >= 0) { \ + size_t _marks_size = (lastmark+1) * sizeof(void*); \ + DATA_STACK_POP(state, state->mark, _marks_size, 1); \ } while (0) #define MARK_POP_KEEP(lastmark) \ - do if (lastmark > 0) { \ - DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 0); \ + do if (lastmark >= 0) { \ + size_t _marks_size = (lastmark+1) * sizeof(void*); \ + DATA_STACK_POP(state, state->mark, _marks_size, 0); \ } while (0) #define MARK_POP_DISCARD(lastmark) \ - do if (lastmark > 0) { \ - DATA_STACK_POP_DISCARD(state, (lastmark+1)*sizeof(void*)); \ + do if (lastmark >= 0) { \ + size_t _marks_size = (lastmark+1) * sizeof(void*); \ + DATA_STACK_POP_DISCARD(state, _marks_size); \ } while (0) #define JUMP_NONE 0 @@ -508,18 +483,25 @@ do { \ #define JUMP_BRANCH 11 #define JUMP_ASSERT 12 #define JUMP_ASSERT_NOT 13 +#define JUMP_POSS_REPEAT_1 14 +#define JUMP_POSS_REPEAT_2 15 +#define JUMP_ATOMIC_GROUP 16 #define DO_JUMPX(jumpvalue, jumplabel, nextpattern, toplevel_) \ + ctx->pattern = pattern; \ + ctx->ptr = ptr; \ DATA_ALLOC(SRE(match_context), nextctx); \ - nextctx->last_ctx_pos = ctx_pos; \ - nextctx->jump = jumpvalue; \ nextctx->pattern = nextpattern; \ nextctx->toplevel = toplevel_; \ + nextctx->jump = jumpvalue; \ + nextctx->last_ctx_pos = ctx_pos; \ + pattern = nextpattern; \ ctx_pos = alloc_pos; \ ctx = nextctx; \ goto entrance; \ jumplabel: \ - while (0) /* gcc doesn't like labels at end of scopes */ \ + pattern = ctx->pattern; \ + ptr = ctx->ptr; #define DO_JUMP(jumpvalue, jumplabel, nextpattern) \ DO_JUMPX(jumpvalue, jumplabel, nextpattern, ctx->toplevel) @@ -528,20 +510,50 @@ do { \ DO_JUMPX(jumpvalue, jumplabel, nextpattern, 0) typedef struct { - Py_ssize_t last_ctx_pos; - Py_ssize_t jump; - const SRE_CHAR* ptr; - const SRE_CODE* pattern; Py_ssize_t count; - Py_ssize_t lastmark; - Py_ssize_t lastindex; union { SRE_CODE chr; SRE_REPEAT* rep; } u; + int lastmark; + int lastindex; + const SRE_CODE* pattern; + const SRE_CHAR* ptr; int toplevel; + int jump; + Py_ssize_t last_ctx_pos; } SRE(match_context); +#define MAYBE_CHECK_SIGNALS \ + do { \ + if ((0 == (++sigcount & 0xfff)) && PyErr_CheckSignals()) { \ + RETURN_ERROR(SRE_ERROR_INTERRUPTED); \ + } \ + } while (0) + +#ifdef HAVE_COMPUTED_GOTOS + #ifndef USE_COMPUTED_GOTOS + #define USE_COMPUTED_GOTOS 1 + #endif +#elif defined(USE_COMPUTED_GOTOS) && USE_COMPUTED_GOTOS + #error "Computed gotos are not supported on this compiler." +#else + #undef USE_COMPUTED_GOTOS + #define USE_COMPUTED_GOTOS 0 +#endif + +#if USE_COMPUTED_GOTOS + #define TARGET(OP) TARGET_ ## OP + #define DISPATCH \ + do { \ + MAYBE_CHECK_SIGNALS; \ + goto *sre_targets[*pattern++]; \ + } while (0) +#else + #define TARGET(OP) case OP + #define DISPATCH goto dispatch +#endif + /* check if string matches the given pattern. returns <0 for error, 0 for failure, and 1 for success */ LOCAL(Py_ssize_t) @@ -549,8 +561,8 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) { const SRE_CHAR* end = (const SRE_CHAR *)state->end; Py_ssize_t alloc_pos, ctx_pos = -1; - Py_ssize_t i, ret = 0; - Py_ssize_t jump; + Py_ssize_t ret = 0; + int jump; unsigned int sigcount=0; SRE(match_context)* ctx; @@ -561,270 +573,277 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) DATA_ALLOC(SRE(match_context), ctx); ctx->last_ctx_pos = -1; ctx->jump = JUMP_NONE; - ctx->pattern = pattern; ctx->toplevel = toplevel; ctx_pos = alloc_pos; +#if USE_COMPUTED_GOTOS +#include "sre_targets.h" +#endif + entrance: - ctx->ptr = (SRE_CHAR *)state->ptr; + ; // Fashion statement. + const SRE_CHAR *ptr = (SRE_CHAR *)state->ptr; - if (ctx->pattern[0] == SRE_OP_INFO) { + if (pattern[0] == SRE_OP_INFO) { /* optimization info block */ /* <1=skip> <2=flags> <3=min> ... */ - if (ctx->pattern[3] && (uintptr_t)(end - ctx->ptr) < ctx->pattern[3]) { + if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) { TRACE(("reject (got %zd chars, need %zd)\n", - end - ctx->ptr, (Py_ssize_t) ctx->pattern[3])); + end - ptr, (Py_ssize_t) pattern[3])); RETURN_FAILURE; } - ctx->pattern += ctx->pattern[1] + 1; + pattern += pattern[1] + 1; } - for (;;) { - ++sigcount; - if ((0 == (sigcount & 0xfff)) && PyErr_CheckSignals()) - RETURN_ERROR(SRE_ERROR_INTERRUPTED); +#if USE_COMPUTED_GOTOS + DISPATCH; +#else +dispatch: + MAYBE_CHECK_SIGNALS; + switch (*pattern++) +#endif + { - switch (*ctx->pattern++) { - - case SRE_OP_MARK: + TARGET(SRE_OP_MARK): /* set mark */ /* */ - TRACE(("|%p|%p|MARK %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[0])); - i = ctx->pattern[0]; - if (i & 1) - state->lastindex = i/2 + 1; - if (i > state->lastmark) { - /* state->lastmark is the highest valid index in the - state->mark array. If it is increased by more than 1, - the intervening marks must be set to NULL to signal - that these marks have not been encountered. */ - Py_ssize_t j = state->lastmark + 1; - while (j < i) - state->mark[j++] = NULL; - state->lastmark = i; + TRACE(("|%p|%p|MARK %d\n", pattern, + ptr, pattern[0])); + { + int i = pattern[0]; + if (i & 1) + state->lastindex = i/2 + 1; + if (i > state->lastmark) { + /* state->lastmark is the highest valid index in the + state->mark array. If it is increased by more than 1, + the intervening marks must be set to NULL to signal + that these marks have not been encountered. */ + int j = state->lastmark + 1; + while (j < i) + state->mark[j++] = NULL; + state->lastmark = i; + } + state->mark[i] = ptr; } - state->mark[i] = ctx->ptr; - ctx->pattern++; - break; + pattern++; + DISPATCH; - case SRE_OP_LITERAL: + TARGET(SRE_OP_LITERAL): /* match literal string */ /* */ - TRACE(("|%p|%p|LITERAL %d\n", ctx->pattern, - ctx->ptr, *ctx->pattern)); - if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] != ctx->pattern[0]) + TRACE(("|%p|%p|LITERAL %d\n", pattern, + ptr, *pattern)); + if (ptr >= end || (SRE_CODE) ptr[0] != pattern[0]) RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; + pattern++; + ptr++; + DISPATCH; - case SRE_OP_NOT_LITERAL: + TARGET(SRE_OP_NOT_LITERAL): /* match anything that is not literal character */ /* */ - TRACE(("|%p|%p|NOT_LITERAL %d\n", ctx->pattern, - ctx->ptr, *ctx->pattern)); - if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] == ctx->pattern[0]) + TRACE(("|%p|%p|NOT_LITERAL %d\n", pattern, + ptr, *pattern)); + if (ptr >= end || (SRE_CODE) ptr[0] == pattern[0]) RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; + pattern++; + ptr++; + DISPATCH; - case SRE_OP_SUCCESS: + TARGET(SRE_OP_SUCCESS): /* end of pattern */ - TRACE(("|%p|%p|SUCCESS\n", ctx->pattern, ctx->ptr)); + TRACE(("|%p|%p|SUCCESS\n", pattern, ptr)); if (ctx->toplevel && - ((state->match_all && ctx->ptr != state->end) || - (state->must_advance && ctx->ptr == state->start))) + ((state->match_all && ptr != state->end) || + (state->must_advance && ptr == state->start))) { RETURN_FAILURE; } - state->ptr = ctx->ptr; + state->ptr = ptr; RETURN_SUCCESS; - case SRE_OP_AT: + TARGET(SRE_OP_AT): /* match at given position */ /* */ - TRACE(("|%p|%p|AT %d\n", ctx->pattern, ctx->ptr, *ctx->pattern)); - if (!SRE(at)(state, ctx->ptr, *ctx->pattern)) + TRACE(("|%p|%p|AT %d\n", pattern, ptr, *pattern)); + if (!SRE(at)(state, ptr, *pattern)) RETURN_FAILURE; - ctx->pattern++; - break; + pattern++; + DISPATCH; - case SRE_OP_CATEGORY: + TARGET(SRE_OP_CATEGORY): /* match at given category */ /* */ - TRACE(("|%p|%p|CATEGORY %d\n", ctx->pattern, - ctx->ptr, *ctx->pattern)); - if (ctx->ptr >= end || !sre_category(ctx->pattern[0], ctx->ptr[0])) + TRACE(("|%p|%p|CATEGORY %d\n", pattern, + ptr, *pattern)); + if (ptr >= end || !sre_category(pattern[0], ptr[0])) RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; + pattern++; + ptr++; + DISPATCH; - case SRE_OP_ANY: + TARGET(SRE_OP_ANY): /* match anything (except a newline) */ /* */ - TRACE(("|%p|%p|ANY\n", ctx->pattern, ctx->ptr)); - if (ctx->ptr >= end || SRE_IS_LINEBREAK(ctx->ptr[0])) + TRACE(("|%p|%p|ANY\n", pattern, ptr)); + if (ptr >= end || SRE_IS_LINEBREAK(ptr[0])) RETURN_FAILURE; - ctx->ptr++; - break; + ptr++; + DISPATCH; - case SRE_OP_ANY_ALL: + TARGET(SRE_OP_ANY_ALL): /* match anything */ /* */ - TRACE(("|%p|%p|ANY_ALL\n", ctx->pattern, ctx->ptr)); - if (ctx->ptr >= end) + TRACE(("|%p|%p|ANY_ALL\n", pattern, ptr)); + if (ptr >= end) RETURN_FAILURE; - ctx->ptr++; - break; + ptr++; + DISPATCH; - case SRE_OP_IN: + TARGET(SRE_OP_IN): /* match set member (or non_member) */ /* */ - TRACE(("|%p|%p|IN\n", ctx->pattern, ctx->ptr)); - if (ctx->ptr >= end || - !SRE(charset)(state, ctx->pattern + 1, *ctx->ptr)) + TRACE(("|%p|%p|IN\n", pattern, ptr)); + if (ptr >= end || + !SRE(charset)(state, pattern + 1, *ptr)) RETURN_FAILURE; - ctx->pattern += ctx->pattern[0]; - ctx->ptr++; - break; + pattern += pattern[0]; + ptr++; + DISPATCH; - case SRE_OP_LITERAL_IGNORE: + TARGET(SRE_OP_LITERAL_IGNORE): TRACE(("|%p|%p|LITERAL_IGNORE %d\n", - ctx->pattern, ctx->ptr, ctx->pattern[0])); - if (ctx->ptr >= end || - sre_lower_ascii(*ctx->ptr) != *ctx->pattern) + pattern, ptr, pattern[0])); + if (ptr >= end || + sre_lower_ascii(*ptr) != *pattern) RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; + pattern++; + ptr++; + DISPATCH; - case SRE_OP_LITERAL_UNI_IGNORE: + TARGET(SRE_OP_LITERAL_UNI_IGNORE): TRACE(("|%p|%p|LITERAL_UNI_IGNORE %d\n", - ctx->pattern, ctx->ptr, ctx->pattern[0])); - if (ctx->ptr >= end || - sre_lower_unicode(*ctx->ptr) != *ctx->pattern) + pattern, ptr, pattern[0])); + if (ptr >= end || + sre_lower_unicode(*ptr) != *pattern) RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; + pattern++; + ptr++; + DISPATCH; - case SRE_OP_LITERAL_LOC_IGNORE: + TARGET(SRE_OP_LITERAL_LOC_IGNORE): TRACE(("|%p|%p|LITERAL_LOC_IGNORE %d\n", - ctx->pattern, ctx->ptr, ctx->pattern[0])); - if (ctx->ptr >= end - || !char_loc_ignore(*ctx->pattern, *ctx->ptr)) + pattern, ptr, pattern[0])); + if (ptr >= end + || !char_loc_ignore(*pattern, *ptr)) RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; + pattern++; + ptr++; + DISPATCH; - case SRE_OP_NOT_LITERAL_IGNORE: + TARGET(SRE_OP_NOT_LITERAL_IGNORE): TRACE(("|%p|%p|NOT_LITERAL_IGNORE %d\n", - ctx->pattern, ctx->ptr, *ctx->pattern)); - if (ctx->ptr >= end || - sre_lower_ascii(*ctx->ptr) == *ctx->pattern) + pattern, ptr, *pattern)); + if (ptr >= end || + sre_lower_ascii(*ptr) == *pattern) RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; + pattern++; + ptr++; + DISPATCH; - case SRE_OP_NOT_LITERAL_UNI_IGNORE: + TARGET(SRE_OP_NOT_LITERAL_UNI_IGNORE): TRACE(("|%p|%p|NOT_LITERAL_UNI_IGNORE %d\n", - ctx->pattern, ctx->ptr, *ctx->pattern)); - if (ctx->ptr >= end || - sre_lower_unicode(*ctx->ptr) == *ctx->pattern) + pattern, ptr, *pattern)); + if (ptr >= end || + sre_lower_unicode(*ptr) == *pattern) RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; + pattern++; + ptr++; + DISPATCH; - case SRE_OP_NOT_LITERAL_LOC_IGNORE: + TARGET(SRE_OP_NOT_LITERAL_LOC_IGNORE): TRACE(("|%p|%p|NOT_LITERAL_LOC_IGNORE %d\n", - ctx->pattern, ctx->ptr, *ctx->pattern)); - if (ctx->ptr >= end - || char_loc_ignore(*ctx->pattern, *ctx->ptr)) + pattern, ptr, *pattern)); + if (ptr >= end + || char_loc_ignore(*pattern, *ptr)) RETURN_FAILURE; - ctx->pattern++; - ctx->ptr++; - break; + pattern++; + ptr++; + DISPATCH; - case SRE_OP_IN_IGNORE: - TRACE(("|%p|%p|IN_IGNORE\n", ctx->pattern, ctx->ptr)); - if (ctx->ptr >= end - || !SRE(charset)(state, ctx->pattern+1, - (SRE_CODE)sre_lower_ascii(*ctx->ptr))) + TARGET(SRE_OP_IN_IGNORE): + TRACE(("|%p|%p|IN_IGNORE\n", pattern, ptr)); + if (ptr >= end + || !SRE(charset)(state, pattern+1, + (SRE_CODE)sre_lower_ascii(*ptr))) RETURN_FAILURE; - ctx->pattern += ctx->pattern[0]; - ctx->ptr++; - break; + pattern += pattern[0]; + ptr++; + DISPATCH; - case SRE_OP_IN_UNI_IGNORE: - TRACE(("|%p|%p|IN_UNI_IGNORE\n", ctx->pattern, ctx->ptr)); - if (ctx->ptr >= end - || !SRE(charset)(state, ctx->pattern+1, - (SRE_CODE)sre_lower_unicode(*ctx->ptr))) + TARGET(SRE_OP_IN_UNI_IGNORE): + TRACE(("|%p|%p|IN_UNI_IGNORE\n", pattern, ptr)); + if (ptr >= end + || !SRE(charset)(state, pattern+1, + (SRE_CODE)sre_lower_unicode(*ptr))) RETURN_FAILURE; - ctx->pattern += ctx->pattern[0]; - ctx->ptr++; - break; + pattern += pattern[0]; + ptr++; + DISPATCH; - case SRE_OP_IN_LOC_IGNORE: - TRACE(("|%p|%p|IN_LOC_IGNORE\n", ctx->pattern, ctx->ptr)); - if (ctx->ptr >= end - || !SRE(charset_loc_ignore)(state, ctx->pattern+1, *ctx->ptr)) + TARGET(SRE_OP_IN_LOC_IGNORE): + TRACE(("|%p|%p|IN_LOC_IGNORE\n", pattern, ptr)); + if (ptr >= end + || !SRE(charset_loc_ignore)(state, pattern+1, *ptr)) RETURN_FAILURE; - ctx->pattern += ctx->pattern[0]; - ctx->ptr++; - break; + pattern += pattern[0]; + ptr++; + DISPATCH; - case SRE_OP_JUMP: - case SRE_OP_INFO: + TARGET(SRE_OP_JUMP): + TARGET(SRE_OP_INFO): /* jump forward */ /* */ - TRACE(("|%p|%p|JUMP %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[0])); - ctx->pattern += ctx->pattern[0]; - break; + TRACE(("|%p|%p|JUMP %d\n", pattern, + ptr, pattern[0])); + pattern += pattern[0]; + DISPATCH; - case SRE_OP_BRANCH: + TARGET(SRE_OP_BRANCH): /* alternation */ /* <0=skip> code ... */ - TRACE(("|%p|%p|BRANCH\n", ctx->pattern, ctx->ptr)); + TRACE(("|%p|%p|BRANCH\n", pattern, ptr)); LASTMARK_SAVE(); - ctx->u.rep = state->repeat; - if (ctx->u.rep) + if (state->repeat) MARK_PUSH(ctx->lastmark); - for (; ctx->pattern[0]; ctx->pattern += ctx->pattern[0]) { - if (ctx->pattern[1] == SRE_OP_LITERAL && - (ctx->ptr >= end || - (SRE_CODE) *ctx->ptr != ctx->pattern[2])) + for (; pattern[0]; pattern += pattern[0]) { + if (pattern[1] == SRE_OP_LITERAL && + (ptr >= end || + (SRE_CODE) *ptr != pattern[2])) continue; - if (ctx->pattern[1] == SRE_OP_IN && - (ctx->ptr >= end || - !SRE(charset)(state, ctx->pattern + 3, - (SRE_CODE) *ctx->ptr))) + if (pattern[1] == SRE_OP_IN && + (ptr >= end || + !SRE(charset)(state, pattern + 3, + (SRE_CODE) *ptr))) continue; - state->ptr = ctx->ptr; - DO_JUMP(JUMP_BRANCH, jump_branch, ctx->pattern+1); + state->ptr = ptr; + DO_JUMP(JUMP_BRANCH, jump_branch, pattern+1); if (ret) { - if (ctx->u.rep) + if (state->repeat) MARK_POP_DISCARD(ctx->lastmark); RETURN_ON_ERROR(ret); RETURN_SUCCESS; } - if (ctx->u.rep) + if (state->repeat) MARK_POP_KEEP(ctx->lastmark); LASTMARK_RESTORE(); } - if (ctx->u.rep) + if (state->repeat) MARK_POP_DISCARD(ctx->lastmark); RETURN_FAILURE; - case SRE_OP_REPEAT_ONE: + TARGET(SRE_OP_REPEAT_ONE): /* match repeated sequence (maximizing regexp) */ /* this operator only works if the repeated item is @@ -834,83 +853,96 @@ entrance: /* <1=min> <2=max> item tail */ - TRACE(("|%p|%p|REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr, - ctx->pattern[1], ctx->pattern[2])); + TRACE(("|%p|%p|REPEAT_ONE %d %d\n", pattern, ptr, + pattern[1], pattern[2])); - if ((Py_ssize_t) ctx->pattern[1] > end - ctx->ptr) + if ((Py_ssize_t) pattern[1] > end - ptr) RETURN_FAILURE; /* cannot match */ - state->ptr = ctx->ptr; + state->ptr = ptr; - ret = SRE(count)(state, ctx->pattern+3, ctx->pattern[2]); + ret = SRE(count)(state, pattern+3, pattern[2]); RETURN_ON_ERROR(ret); DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos); ctx->count = ret; - ctx->ptr += ctx->count; + ptr += ctx->count; /* when we arrive here, count contains the number of - matches, and ctx->ptr points to the tail of the target + matches, and ptr points to the tail of the target string. check if the rest of the pattern matches, and backtrack if not. */ - if (ctx->count < (Py_ssize_t) ctx->pattern[1]) + if (ctx->count < (Py_ssize_t) pattern[1]) RETURN_FAILURE; - if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS && - ctx->ptr == state->end && - !(ctx->toplevel && state->must_advance && ctx->ptr == state->start)) + if (pattern[pattern[0]] == SRE_OP_SUCCESS && + ptr == state->end && + !(ctx->toplevel && state->must_advance && ptr == state->start)) { /* tail is empty. we're finished */ - state->ptr = ctx->ptr; + state->ptr = ptr; RETURN_SUCCESS; } LASTMARK_SAVE(); + if (state->repeat) + MARK_PUSH(ctx->lastmark); - if (ctx->pattern[ctx->pattern[0]] == SRE_OP_LITERAL) { + if (pattern[pattern[0]] == SRE_OP_LITERAL) { /* tail starts with a literal. skip positions where the rest of the pattern cannot possibly match */ - ctx->u.chr = ctx->pattern[ctx->pattern[0]+1]; + ctx->u.chr = pattern[pattern[0]+1]; for (;;) { - while (ctx->count >= (Py_ssize_t) ctx->pattern[1] && - (ctx->ptr >= end || *ctx->ptr != ctx->u.chr)) { - ctx->ptr--; + while (ctx->count >= (Py_ssize_t) pattern[1] && + (ptr >= end || *ptr != ctx->u.chr)) { + ptr--; ctx->count--; } - if (ctx->count < (Py_ssize_t) ctx->pattern[1]) + if (ctx->count < (Py_ssize_t) pattern[1]) break; - state->ptr = ctx->ptr; + state->ptr = ptr; DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1, - ctx->pattern+ctx->pattern[0]); + pattern+pattern[0]); if (ret) { + if (state->repeat) + MARK_POP_DISCARD(ctx->lastmark); RETURN_ON_ERROR(ret); RETURN_SUCCESS; } - + if (state->repeat) + MARK_POP_KEEP(ctx->lastmark); LASTMARK_RESTORE(); - ctx->ptr--; + ptr--; ctx->count--; } - + if (state->repeat) + MARK_POP_DISCARD(ctx->lastmark); } else { /* general case */ - while (ctx->count >= (Py_ssize_t) ctx->pattern[1]) { - state->ptr = ctx->ptr; + while (ctx->count >= (Py_ssize_t) pattern[1]) { + state->ptr = ptr; DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2, - ctx->pattern+ctx->pattern[0]); + pattern+pattern[0]); if (ret) { + if (state->repeat) + MARK_POP_DISCARD(ctx->lastmark); RETURN_ON_ERROR(ret); RETURN_SUCCESS; } - ctx->ptr--; - ctx->count--; + if (state->repeat) + MARK_POP_KEEP(ctx->lastmark); LASTMARK_RESTORE(); + + ptr--; + ctx->count--; } + if (state->repeat) + MARK_POP_DISCARD(ctx->lastmark); } RETURN_FAILURE; - case SRE_OP_MIN_REPEAT_ONE: + TARGET(SRE_OP_MIN_REPEAT_ONE): /* match repeated sequence (minimizing regexp) */ /* this operator only works if the repeated item is @@ -920,85 +952,152 @@ entrance: /* <1=min> <2=max> item tail */ - TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr, - ctx->pattern[1], ctx->pattern[2])); + TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", pattern, ptr, + pattern[1], pattern[2])); - if ((Py_ssize_t) ctx->pattern[1] > end - ctx->ptr) + if ((Py_ssize_t) pattern[1] > end - ptr) RETURN_FAILURE; /* cannot match */ - state->ptr = ctx->ptr; + state->ptr = ptr; - if (ctx->pattern[1] == 0) + if (pattern[1] == 0) ctx->count = 0; else { /* count using pattern min as the maximum */ - ret = SRE(count)(state, ctx->pattern+3, ctx->pattern[1]); + ret = SRE(count)(state, pattern+3, pattern[1]); RETURN_ON_ERROR(ret); DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos); - if (ret < (Py_ssize_t) ctx->pattern[1]) + if (ret < (Py_ssize_t) pattern[1]) /* didn't match minimum number of times */ RETURN_FAILURE; /* advance past minimum matches of repeat */ ctx->count = ret; - ctx->ptr += ctx->count; + ptr += ctx->count; } - if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS && + if (pattern[pattern[0]] == SRE_OP_SUCCESS && !(ctx->toplevel && - ((state->match_all && ctx->ptr != state->end) || - (state->must_advance && ctx->ptr == state->start)))) + ((state->match_all && ptr != state->end) || + (state->must_advance && ptr == state->start)))) { /* tail is empty. we're finished */ - state->ptr = ctx->ptr; + state->ptr = ptr; RETURN_SUCCESS; } else { /* general case */ LASTMARK_SAVE(); - while ((Py_ssize_t)ctx->pattern[2] == SRE_MAXREPEAT - || ctx->count <= (Py_ssize_t)ctx->pattern[2]) { - state->ptr = ctx->ptr; + if (state->repeat) + MARK_PUSH(ctx->lastmark); + + while ((Py_ssize_t)pattern[2] == SRE_MAXREPEAT + || ctx->count <= (Py_ssize_t)pattern[2]) { + state->ptr = ptr; DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one, - ctx->pattern+ctx->pattern[0]); + pattern+pattern[0]); if (ret) { + if (state->repeat) + MARK_POP_DISCARD(ctx->lastmark); RETURN_ON_ERROR(ret); RETURN_SUCCESS; } - state->ptr = ctx->ptr; - ret = SRE(count)(state, ctx->pattern+3, 1); + if (state->repeat) + MARK_POP_KEEP(ctx->lastmark); + LASTMARK_RESTORE(); + + state->ptr = ptr; + ret = SRE(count)(state, pattern+3, 1); RETURN_ON_ERROR(ret); DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos); if (ret == 0) break; assert(ret == 1); - ctx->ptr++; + ptr++; ctx->count++; - LASTMARK_RESTORE(); } + if (state->repeat) + MARK_POP_DISCARD(ctx->lastmark); } RETURN_FAILURE; - case SRE_OP_REPEAT: + TARGET(SRE_OP_POSSESSIVE_REPEAT_ONE): + /* match repeated sequence (maximizing regexp) without + backtracking */ + + /* this operator only works if the repeated item is + exactly one character wide, and we're not already + collecting backtracking points. for other cases, + use the MAX_REPEAT operator */ + + /* <1=min> <2=max> item + tail */ + + TRACE(("|%p|%p|POSSESSIVE_REPEAT_ONE %d %d\n", pattern, + ptr, pattern[1], pattern[2])); + + if (ptr + pattern[1] > end) { + RETURN_FAILURE; /* cannot match */ + } + + state->ptr = ptr; + + ret = SRE(count)(state, pattern + 3, pattern[2]); + RETURN_ON_ERROR(ret); + DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos); + ctx->count = ret; + ptr += ctx->count; + + /* when we arrive here, count contains the number of + matches, and ptr points to the tail of the target + string. check if the rest of the pattern matches, + and fail if not. */ + + /* Test for not enough repetitions in match */ + if (ctx->count < (Py_ssize_t) pattern[1]) { + RETURN_FAILURE; + } + + /* Update the pattern to point to the next op code */ + pattern += pattern[0]; + + /* Let the tail be evaluated separately and consider this + match successful. */ + if (*pattern == SRE_OP_SUCCESS && + ptr == state->end && + !(ctx->toplevel && state->must_advance && ptr == state->start)) + { + /* tail is empty. we're finished */ + state->ptr = ptr; + RETURN_SUCCESS; + } + + /* Attempt to match the rest of the string */ + DISPATCH; + + TARGET(SRE_OP_REPEAT): /* create repeat context. all the hard work is done by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */ - /* <1=min> <2=max> item tail */ - TRACE(("|%p|%p|REPEAT %d %d\n", ctx->pattern, ctx->ptr, - ctx->pattern[1], ctx->pattern[2])); + /* <1=min> <2=max> + <3=repeat_index> item tail */ + TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr, + pattern[1], pattern[2])); /* install new repeat context */ + /* TODO(https://github.com/python/cpython/issues/67877): Fix this + * potential memory leak. */ ctx->u.rep = (SRE_REPEAT*) PyObject_Malloc(sizeof(*ctx->u.rep)); if (!ctx->u.rep) { PyErr_NoMemory(); RETURN_FAILURE; } ctx->u.rep->count = -1; - ctx->u.rep->pattern = ctx->pattern; + ctx->u.rep->pattern = pattern; ctx->u.rep->prev = state->repeat; ctx->u.rep->last_ptr = NULL; state->repeat = ctx->u.rep; - state->ptr = ctx->ptr; - DO_JUMP(JUMP_REPEAT, jump_repeat, ctx->pattern+ctx->pattern[0]); + state->ptr = ptr; + DO_JUMP(JUMP_REPEAT, jump_repeat, pattern+pattern[0]); state->repeat = ctx->u.rep->prev; PyObject_Free(ctx->u.rep); @@ -1008,7 +1107,7 @@ entrance: } RETURN_FAILURE; - case SRE_OP_MAX_UNTIL: + TARGET(SRE_OP_MAX_UNTIL): /* maximizing repeat */ /* <1=min> <2=max> item tail */ @@ -1019,12 +1118,12 @@ entrance: if (!ctx->u.rep) RETURN_ERROR(SRE_ERROR_STATE); - state->ptr = ctx->ptr; + state->ptr = ptr; ctx->count = ctx->u.rep->count+1; - TRACE(("|%p|%p|MAX_UNTIL %zd\n", ctx->pattern, - ctx->ptr, ctx->count)); + TRACE(("|%p|%p|MAX_UNTIL %zd\n", pattern, + ptr, ctx->count)); if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) { /* not enough matches */ @@ -1036,7 +1135,7 @@ entrance: RETURN_SUCCESS; } ctx->u.rep->count = ctx->count-1; - state->ptr = ctx->ptr; + state->ptr = ptr; RETURN_FAILURE; } @@ -1062,19 +1161,20 @@ entrance: MARK_POP(ctx->lastmark); LASTMARK_RESTORE(); ctx->u.rep->count = ctx->count-1; - state->ptr = ctx->ptr; + state->ptr = ptr; } /* cannot match more repeated items here. make sure the tail matches */ state->repeat = ctx->u.rep->prev; - DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, ctx->pattern); + DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, pattern); + state->repeat = ctx->u.rep; // restore repeat before return + RETURN_ON_SUCCESS(ret); - state->repeat = ctx->u.rep; - state->ptr = ctx->ptr; + state->ptr = ptr; RETURN_FAILURE; - case SRE_OP_MIN_UNTIL: + TARGET(SRE_OP_MIN_UNTIL): /* minimizing repeat */ /* <1=min> <2=max> item tail */ @@ -1082,12 +1182,12 @@ entrance: if (!ctx->u.rep) RETURN_ERROR(SRE_ERROR_STATE); - state->ptr = ctx->ptr; + state->ptr = ptr; ctx->count = ctx->u.rep->count+1; - TRACE(("|%p|%p|MIN_UNTIL %zd %p\n", ctx->pattern, - ctx->ptr, ctx->count, ctx->u.rep->pattern)); + TRACE(("|%p|%p|MIN_UNTIL %zd %p\n", pattern, + ptr, ctx->count, ctx->u.rep->pattern)); if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) { /* not enough matches */ @@ -1099,25 +1199,33 @@ entrance: RETURN_SUCCESS; } ctx->u.rep->count = ctx->count-1; - state->ptr = ctx->ptr; + state->ptr = ptr; RETURN_FAILURE; } - LASTMARK_SAVE(); - /* see if the tail matches */ state->repeat = ctx->u.rep->prev; - DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, ctx->pattern); + + LASTMARK_SAVE(); + if (state->repeat) + MARK_PUSH(ctx->lastmark); + + DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, pattern); + SRE_REPEAT *repeat_of_tail = state->repeat; + state->repeat = ctx->u.rep; // restore repeat before return + if (ret) { + if (repeat_of_tail) + MARK_POP_DISCARD(ctx->lastmark); RETURN_ON_ERROR(ret); RETURN_SUCCESS; } - - state->repeat = ctx->u.rep; - state->ptr = ctx->ptr; - + if (repeat_of_tail) + MARK_POP(ctx->lastmark); LASTMARK_RESTORE(); + state->ptr = ptr; + if ((ctx->count >= (Py_ssize_t) ctx->u.rep->pattern[2] && ctx->u.rep->pattern[2] != SRE_MAXREPEAT) || state->ptr == ctx->u.rep->last_ptr) @@ -1135,173 +1243,318 @@ entrance: RETURN_SUCCESS; } ctx->u.rep->count = ctx->count-1; - state->ptr = ctx->ptr; + state->ptr = ptr; RETURN_FAILURE; - case SRE_OP_GROUPREF: - /* match backreference */ - TRACE(("|%p|%p|GROUPREF %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[0])); - i = ctx->pattern[0]; - { - Py_ssize_t groupref = i+i; - if (groupref >= state->lastmark) { + TARGET(SRE_OP_POSSESSIVE_REPEAT): + /* create possessive repeat contexts. */ + /* <1=min> <2=max> pattern + tail */ + TRACE(("|%p|%p|POSSESSIVE_REPEAT %d %d\n", pattern, + ptr, pattern[1], pattern[2])); + + /* Set the global Input pointer to this context's Input + pointer */ + state->ptr = ptr; + + /* Initialize Count to 0 */ + ctx->count = 0; + + /* Check for minimum required matches. */ + while (ctx->count < (Py_ssize_t)pattern[1]) { + /* not enough matches */ + DO_JUMP0(JUMP_POSS_REPEAT_1, jump_poss_repeat_1, + &pattern[3]); + if (ret) { + RETURN_ON_ERROR(ret); + ctx->count++; + } + else { + state->ptr = ptr; RETURN_FAILURE; - } else { - SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; - SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; - if (!p || !e || e < p) - RETURN_FAILURE; - while (p < e) { - if (ctx->ptr >= end || *ctx->ptr != *p) - RETURN_FAILURE; - p++; - ctx->ptr++; - } } } - ctx->pattern++; - break; - case SRE_OP_GROUPREF_IGNORE: - /* match backreference */ - TRACE(("|%p|%p|GROUPREF_IGNORE %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[0])); - i = ctx->pattern[0]; - { - Py_ssize_t groupref = i+i; - if (groupref >= state->lastmark) { - RETURN_FAILURE; - } else { - SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; - SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; - if (!p || !e || e < p) - RETURN_FAILURE; - while (p < e) { - if (ctx->ptr >= end || - sre_lower_ascii(*ctx->ptr) != sre_lower_ascii(*p)) - RETURN_FAILURE; - p++; - ctx->ptr++; - } + /* Clear the context's Input stream pointer so that it + doesn't match the global state so that the while loop can + be entered. */ + ptr = NULL; + + /* Keep trying to parse the sub-pattern until the + end is reached, creating a new context each time. */ + while ((ctx->count < (Py_ssize_t)pattern[2] || + (Py_ssize_t)pattern[2] == SRE_MAXREPEAT) && + state->ptr != ptr) { + /* Save the Capture Group Marker state into the current + Context and back up the current highest number + Capture Group marker. */ + LASTMARK_SAVE(); + MARK_PUSH(ctx->lastmark); + + /* zero-width match protection */ + /* Set the context's Input Stream pointer to be the + current Input Stream pointer from the global + state. When the loop reaches the next iteration, + the context will then store the last known good + position with the global state holding the Input + Input Stream position that has been updated with + the most recent match. Thus, if state's Input + stream remains the same as the one stored in the + current Context, we know we have successfully + matched an empty string and that all subsequent + matches will also be the empty string until the + maximum number of matches are counted, and because + of this, we could immediately stop at that point and + consider this match successful. */ + ptr = state->ptr; + + /* We have not reached the maximin matches, so try to + match once more. */ + DO_JUMP0(JUMP_POSS_REPEAT_2, jump_poss_repeat_2, + &pattern[3]); + + /* Check to see if the last attempted match + succeeded. */ + if (ret) { + /* Drop the saved highest number Capture Group + marker saved above and use the newly updated + value. */ + MARK_POP_DISCARD(ctx->lastmark); + RETURN_ON_ERROR(ret); + + /* Success, increment the count. */ + ctx->count++; } - } - ctx->pattern++; - break; + /* Last attempted match failed. */ + else { + /* Restore the previously saved highest number + Capture Group marker since the last iteration + did not match, then restore that to the global + state. */ + MARK_POP(ctx->lastmark); + LASTMARK_RESTORE(); - case SRE_OP_GROUPREF_UNI_IGNORE: - /* match backreference */ - TRACE(("|%p|%p|GROUPREF_UNI_IGNORE %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[0])); - i = ctx->pattern[0]; - { - Py_ssize_t groupref = i+i; - if (groupref >= state->lastmark) { - RETURN_FAILURE; - } else { - SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; - SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; - if (!p || !e || e < p) - RETURN_FAILURE; - while (p < e) { - if (ctx->ptr >= end || - sre_lower_unicode(*ctx->ptr) != sre_lower_unicode(*p)) - RETURN_FAILURE; - p++; - ctx->ptr++; - } - } - } - ctx->pattern++; - break; - - case SRE_OP_GROUPREF_LOC_IGNORE: - /* match backreference */ - TRACE(("|%p|%p|GROUPREF_LOC_IGNORE %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[0])); - i = ctx->pattern[0]; - { - Py_ssize_t groupref = i+i; - if (groupref >= state->lastmark) { - RETURN_FAILURE; - } else { - SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; - SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; - if (!p || !e || e < p) - RETURN_FAILURE; - while (p < e) { - if (ctx->ptr >= end || - sre_lower_locale(*ctx->ptr) != sre_lower_locale(*p)) - RETURN_FAILURE; - p++; - ctx->ptr++; - } - } - } - ctx->pattern++; - break; - - case SRE_OP_GROUPREF_EXISTS: - TRACE(("|%p|%p|GROUPREF_EXISTS %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[0])); - /* codeyes codeno ... */ - i = ctx->pattern[0]; - { - Py_ssize_t groupref = i+i; - if (groupref >= state->lastmark) { - ctx->pattern += ctx->pattern[1]; + /* We have sufficient matches, so exit loop. */ break; + } + } + + /* Evaluate Tail */ + /* Jump to end of pattern indicated by skip, and then skip + the SUCCESS op code that follows it. */ + pattern += pattern[0] + 1; + ptr = state->ptr; + DISPATCH; + + TARGET(SRE_OP_ATOMIC_GROUP): + /* Atomic Group Sub Pattern */ + /* pattern tail */ + TRACE(("|%p|%p|ATOMIC_GROUP\n", pattern, ptr)); + + /* Set the global Input pointer to this context's Input + pointer */ + state->ptr = ptr; + + /* Evaluate the Atomic Group in a new context, terminating + when the end of the group, represented by a SUCCESS op + code, is reached. */ + /* Group Pattern begins at an offset of 1 code. */ + DO_JUMP0(JUMP_ATOMIC_GROUP, jump_atomic_group, + &pattern[1]); + + /* Test Exit Condition */ + RETURN_ON_ERROR(ret); + + if (ret == 0) { + /* Atomic Group failed to Match. */ + state->ptr = ptr; + RETURN_FAILURE; + } + + /* Evaluate Tail */ + /* Jump to end of pattern indicated by skip, and then skip + the SUCCESS op code that follows it. */ + pattern += pattern[0]; + ptr = state->ptr; + DISPATCH; + + TARGET(SRE_OP_GROUPREF): + /* match backreference */ + TRACE(("|%p|%p|GROUPREF %d\n", pattern, + ptr, pattern[0])); + { + int groupref = pattern[0] * 2; + if (groupref >= state->lastmark) { + RETURN_FAILURE; + } else { + SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; + SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; + if (!p || !e || e < p) + RETURN_FAILURE; + while (p < e) { + if (ptr >= end || *ptr != *p) + RETURN_FAILURE; + p++; + ptr++; + } + } + } + pattern++; + DISPATCH; + + TARGET(SRE_OP_GROUPREF_IGNORE): + /* match backreference */ + TRACE(("|%p|%p|GROUPREF_IGNORE %d\n", pattern, + ptr, pattern[0])); + { + int groupref = pattern[0] * 2; + if (groupref >= state->lastmark) { + RETURN_FAILURE; + } else { + SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; + SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; + if (!p || !e || e < p) + RETURN_FAILURE; + while (p < e) { + if (ptr >= end || + sre_lower_ascii(*ptr) != sre_lower_ascii(*p)) + RETURN_FAILURE; + p++; + ptr++; + } + } + } + pattern++; + DISPATCH; + + TARGET(SRE_OP_GROUPREF_UNI_IGNORE): + /* match backreference */ + TRACE(("|%p|%p|GROUPREF_UNI_IGNORE %d\n", pattern, + ptr, pattern[0])); + { + int groupref = pattern[0] * 2; + if (groupref >= state->lastmark) { + RETURN_FAILURE; + } else { + SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; + SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; + if (!p || !e || e < p) + RETURN_FAILURE; + while (p < e) { + if (ptr >= end || + sre_lower_unicode(*ptr) != sre_lower_unicode(*p)) + RETURN_FAILURE; + p++; + ptr++; + } + } + } + pattern++; + DISPATCH; + + TARGET(SRE_OP_GROUPREF_LOC_IGNORE): + /* match backreference */ + TRACE(("|%p|%p|GROUPREF_LOC_IGNORE %d\n", pattern, + ptr, pattern[0])); + { + int groupref = pattern[0] * 2; + if (groupref >= state->lastmark) { + RETURN_FAILURE; + } else { + SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; + SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; + if (!p || !e || e < p) + RETURN_FAILURE; + while (p < e) { + if (ptr >= end || + sre_lower_locale(*ptr) != sre_lower_locale(*p)) + RETURN_FAILURE; + p++; + ptr++; + } + } + } + pattern++; + DISPATCH; + + TARGET(SRE_OP_GROUPREF_EXISTS): + TRACE(("|%p|%p|GROUPREF_EXISTS %d\n", pattern, + ptr, pattern[0])); + /* codeyes codeno ... */ + { + int groupref = pattern[0] * 2; + if (groupref >= state->lastmark) { + pattern += pattern[1]; + DISPATCH; } else { SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref]; SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1]; if (!p || !e || e < p) { - ctx->pattern += ctx->pattern[1]; - break; + pattern += pattern[1]; + DISPATCH; } } } - ctx->pattern += 2; - break; + pattern += 2; + DISPATCH; - case SRE_OP_ASSERT: + TARGET(SRE_OP_ASSERT): /* assert subpattern */ /* */ - TRACE(("|%p|%p|ASSERT %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[1])); - if (ctx->ptr - (SRE_CHAR *)state->beginning < (Py_ssize_t)ctx->pattern[1]) + TRACE(("|%p|%p|ASSERT %d\n", pattern, + ptr, pattern[1])); + if (ptr - (SRE_CHAR *)state->beginning < (Py_ssize_t)pattern[1]) RETURN_FAILURE; - state->ptr = ctx->ptr - ctx->pattern[1]; - DO_JUMP0(JUMP_ASSERT, jump_assert, ctx->pattern+2); + state->ptr = ptr - pattern[1]; + DO_JUMP0(JUMP_ASSERT, jump_assert, pattern+2); RETURN_ON_FAILURE(ret); - ctx->pattern += ctx->pattern[0]; - break; + pattern += pattern[0]; + DISPATCH; - case SRE_OP_ASSERT_NOT: + TARGET(SRE_OP_ASSERT_NOT): /* assert not subpattern */ /* */ - TRACE(("|%p|%p|ASSERT_NOT %d\n", ctx->pattern, - ctx->ptr, ctx->pattern[1])); - if (ctx->ptr - (SRE_CHAR *)state->beginning >= (Py_ssize_t)ctx->pattern[1]) { - state->ptr = ctx->ptr - ctx->pattern[1]; - DO_JUMP0(JUMP_ASSERT_NOT, jump_assert_not, ctx->pattern+2); + TRACE(("|%p|%p|ASSERT_NOT %d\n", pattern, + ptr, pattern[1])); + if (ptr - (SRE_CHAR *)state->beginning >= (Py_ssize_t)pattern[1]) { + state->ptr = ptr - pattern[1]; + LASTMARK_SAVE(); + if (state->repeat) + MARK_PUSH(ctx->lastmark); + + DO_JUMP0(JUMP_ASSERT_NOT, jump_assert_not, pattern+2); if (ret) { + if (state->repeat) + MARK_POP_DISCARD(ctx->lastmark); RETURN_ON_ERROR(ret); RETURN_FAILURE; } + if (state->repeat) + MARK_POP(ctx->lastmark); + LASTMARK_RESTORE(); } - ctx->pattern += ctx->pattern[0]; - break; + pattern += pattern[0]; + DISPATCH; - case SRE_OP_FAILURE: + TARGET(SRE_OP_FAILURE): /* immediate failure */ - TRACE(("|%p|%p|FAILURE\n", ctx->pattern, ctx->ptr)); + TRACE(("|%p|%p|FAILURE\n", pattern, ptr)); RETURN_FAILURE; +#if !USE_COMPUTED_GOTOS default: - TRACE(("|%p|%p|UNKNOWN %d\n", ctx->pattern, ctx->ptr, - ctx->pattern[-1])); +#endif + // Also any unused opcodes: + TARGET(SRE_OP_RANGE_UNI_IGNORE): + TARGET(SRE_OP_SUBPATTERN): + TARGET(SRE_OP_RANGE): + TARGET(SRE_OP_NEGATE): + TARGET(SRE_OP_BIGCHARSET): + TARGET(SRE_OP_CHARSET): + TRACE(("|%p|%p|UNKNOWN %d\n", pattern, ptr, + pattern[-1])); RETURN_ERROR(SRE_ERROR_ILLEGAL); - } + } exit: @@ -1314,47 +1567,56 @@ exit: switch (jump) { case JUMP_MAX_UNTIL_2: - TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", ctx->pattern, ctx->ptr)); + TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", pattern, ptr)); goto jump_max_until_2; case JUMP_MAX_UNTIL_3: - TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", ctx->pattern, ctx->ptr)); + TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", pattern, ptr)); goto jump_max_until_3; case JUMP_MIN_UNTIL_2: - TRACE(("|%p|%p|JUMP_MIN_UNTIL_2\n", ctx->pattern, ctx->ptr)); + TRACE(("|%p|%p|JUMP_MIN_UNTIL_2\n", pattern, ptr)); goto jump_min_until_2; case JUMP_MIN_UNTIL_3: - TRACE(("|%p|%p|JUMP_MIN_UNTIL_3\n", ctx->pattern, ctx->ptr)); + TRACE(("|%p|%p|JUMP_MIN_UNTIL_3\n", pattern, ptr)); goto jump_min_until_3; case JUMP_BRANCH: - TRACE(("|%p|%p|JUMP_BRANCH\n", ctx->pattern, ctx->ptr)); + TRACE(("|%p|%p|JUMP_BRANCH\n", pattern, ptr)); goto jump_branch; case JUMP_MAX_UNTIL_1: - TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", ctx->pattern, ctx->ptr)); + TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", pattern, ptr)); goto jump_max_until_1; case JUMP_MIN_UNTIL_1: - TRACE(("|%p|%p|JUMP_MIN_UNTIL_1\n", ctx->pattern, ctx->ptr)); + TRACE(("|%p|%p|JUMP_MIN_UNTIL_1\n", pattern, ptr)); goto jump_min_until_1; + case JUMP_POSS_REPEAT_1: + TRACE(("|%p|%p|JUMP_POSS_REPEAT_1\n", pattern, ptr)); + goto jump_poss_repeat_1; + case JUMP_POSS_REPEAT_2: + TRACE(("|%p|%p|JUMP_POSS_REPEAT_2\n", pattern, ptr)); + goto jump_poss_repeat_2; case JUMP_REPEAT: - TRACE(("|%p|%p|JUMP_REPEAT\n", ctx->pattern, ctx->ptr)); + TRACE(("|%p|%p|JUMP_REPEAT\n", pattern, ptr)); goto jump_repeat; case JUMP_REPEAT_ONE_1: - TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", ctx->pattern, ctx->ptr)); + TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", pattern, ptr)); goto jump_repeat_one_1; case JUMP_REPEAT_ONE_2: - TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", ctx->pattern, ctx->ptr)); + TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", pattern, ptr)); goto jump_repeat_one_2; case JUMP_MIN_REPEAT_ONE: - TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", ctx->pattern, ctx->ptr)); + TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", pattern, ptr)); goto jump_min_repeat_one; + case JUMP_ATOMIC_GROUP: + TRACE(("|%p|%p|JUMP_ATOMIC_GROUP\n", pattern, ptr)); + goto jump_atomic_group; case JUMP_ASSERT: - TRACE(("|%p|%p|JUMP_ASSERT\n", ctx->pattern, ctx->ptr)); + TRACE(("|%p|%p|JUMP_ASSERT\n", pattern, ptr)); goto jump_assert; case JUMP_ASSERT_NOT: - TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", ctx->pattern, ctx->ptr)); + TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", pattern, ptr)); goto jump_assert_not; case JUMP_NONE: - TRACE(("|%p|%p|RETURN %zd\n", ctx->pattern, - ctx->ptr, ret)); + TRACE(("|%p|%p|RETURN %zd\n", pattern, + ptr, ret)); break; } @@ -1523,6 +1785,13 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern) state->start = state->ptr = ptr; status = SRE(match)(state, pattern, 1); state->must_advance = 0; + if (status == 0 && pattern[0] == SRE_OP_AT && + (pattern[1] == SRE_AT_BEGINNING || + pattern[1] == SRE_AT_BEGINNING_STRING)) + { + state->start = state->ptr = ptr = end; + return 0; + } while (status == 0 && ptr < end) { ptr++; RESET_CAPTURE_GROUP(); diff --git a/Modules/_sre/sre_targets.h b/Modules/_sre/sre_targets.h new file mode 100644 index 00000000000..62761a0000d --- /dev/null +++ b/Modules/_sre/sre_targets.h @@ -0,0 +1,58 @@ +/* + * Secret Labs' Regular Expression Engine + * + * regular expression matching engine + * + * Auto-generated by Tools/build/generate_sre_constants.py from + * Lib/re/_constants.py. + * + * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. + * + * See the sre.c file for information on usage and redistribution. + */ + +static void *sre_targets[43] = { + &&TARGET_SRE_OP_FAILURE, + &&TARGET_SRE_OP_SUCCESS, + &&TARGET_SRE_OP_ANY, + &&TARGET_SRE_OP_ANY_ALL, + &&TARGET_SRE_OP_ASSERT, + &&TARGET_SRE_OP_ASSERT_NOT, + &&TARGET_SRE_OP_AT, + &&TARGET_SRE_OP_BRANCH, + &&TARGET_SRE_OP_CATEGORY, + &&TARGET_SRE_OP_CHARSET, + &&TARGET_SRE_OP_BIGCHARSET, + &&TARGET_SRE_OP_GROUPREF, + &&TARGET_SRE_OP_GROUPREF_EXISTS, + &&TARGET_SRE_OP_IN, + &&TARGET_SRE_OP_INFO, + &&TARGET_SRE_OP_JUMP, + &&TARGET_SRE_OP_LITERAL, + &&TARGET_SRE_OP_MARK, + &&TARGET_SRE_OP_MAX_UNTIL, + &&TARGET_SRE_OP_MIN_UNTIL, + &&TARGET_SRE_OP_NOT_LITERAL, + &&TARGET_SRE_OP_NEGATE, + &&TARGET_SRE_OP_RANGE, + &&TARGET_SRE_OP_REPEAT, + &&TARGET_SRE_OP_REPEAT_ONE, + &&TARGET_SRE_OP_SUBPATTERN, + &&TARGET_SRE_OP_MIN_REPEAT_ONE, + &&TARGET_SRE_OP_ATOMIC_GROUP, + &&TARGET_SRE_OP_POSSESSIVE_REPEAT, + &&TARGET_SRE_OP_POSSESSIVE_REPEAT_ONE, + &&TARGET_SRE_OP_GROUPREF_IGNORE, + &&TARGET_SRE_OP_IN_IGNORE, + &&TARGET_SRE_OP_LITERAL_IGNORE, + &&TARGET_SRE_OP_NOT_LITERAL_IGNORE, + &&TARGET_SRE_OP_GROUPREF_LOC_IGNORE, + &&TARGET_SRE_OP_IN_LOC_IGNORE, + &&TARGET_SRE_OP_LITERAL_LOC_IGNORE, + &&TARGET_SRE_OP_NOT_LITERAL_LOC_IGNORE, + &&TARGET_SRE_OP_GROUPREF_UNI_IGNORE, + &&TARGET_SRE_OP_IN_UNI_IGNORE, + &&TARGET_SRE_OP_LITERAL_UNI_IGNORE, + &&TARGET_SRE_OP_NOT_LITERAL_UNI_IGNORE, + &&TARGET_SRE_OP_RANGE_UNI_IGNORE, +}; diff --git a/Modules/_ssl.c b/Modules/_ssl.c index b2e241a0a33..8f03a846aed 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -40,8 +40,6 @@ #define PySSL_BEGIN_ALLOW_THREADS { \ PyThreadState *_save = NULL; \ PySSL_BEGIN_ALLOW_THREADS_S(_save); -#define PySSL_BLOCK_THREADS PySSL_END_ALLOW_THREADS_S(_save); -#define PySSL_UNBLOCK_THREADS PySSL_BEGIN_ALLOW_THREADS_S(_save); #define PySSL_END_ALLOW_THREADS PySSL_END_ALLOW_THREADS_S(_save); } @@ -140,9 +138,6 @@ extern const SSL_METHOD *TLSv1_2_method(void); #define INVALID_SOCKET (-1) #endif -/* OpenSSL 1.1 does not have SSL 2.0 */ -#define OPENSSL_NO_SSL2 - /* Default cipher suites */ #ifndef PY_SSL_DEFAULT_CIPHERS #define PY_SSL_DEFAULT_CIPHERS 1 @@ -420,8 +415,7 @@ static PyObject * SSLError_str(PyOSErrorObject *self) { if (self->strerror != NULL && PyUnicode_Check(self->strerror)) { - Py_INCREF(self->strerror); - return self->strerror; + return Py_NewRef(self->strerror); } else return PyObject_Str(self->args); @@ -448,10 +442,6 @@ fill_and_set_sslerror(_sslmodulestate *state, PyObject *err_value = NULL, *reason_obj = NULL, *lib_obj = NULL; PyObject *verify_obj = NULL, *verify_code_obj = NULL; PyObject *init_value, *msg, *key; - _Py_IDENTIFIER(reason); - _Py_IDENTIFIER(library); - _Py_IDENTIFIER(verify_message); - _Py_IDENTIFIER(verify_code); if (errcode != 0) { int lib, reason; @@ -509,8 +499,7 @@ fill_and_set_sslerror(_sslmodulestate *state, if (verify_str != NULL) { verify_obj = PyUnicode_FromString(verify_str); } else { - verify_obj = Py_None; - Py_INCREF(verify_obj); + verify_obj = Py_NewRef(Py_None); } break; } @@ -545,20 +534,20 @@ fill_and_set_sslerror(_sslmodulestate *state, if (reason_obj == NULL) reason_obj = Py_None; - if (_PyObject_SetAttrId(err_value, &PyId_reason, reason_obj)) + if (PyObject_SetAttr(err_value, state->str_reason, reason_obj)) goto fail; if (lib_obj == NULL) lib_obj = Py_None; - if (_PyObject_SetAttrId(err_value, &PyId_library, lib_obj)) + if (PyObject_SetAttr(err_value, state->str_library, lib_obj)) goto fail; if ((sslsock != NULL) && (type == state->PySSLCertVerificationErrorObject)) { /* Only set verify code / message for SSLCertVerificationError */ - if (_PyObject_SetAttrId(err_value, &PyId_verify_code, + if (PyObject_SetAttr(err_value, state->str_verify_code, verify_code_obj)) goto fail; - if (_PyObject_SetAttrId(err_value, &PyId_verify_message, verify_obj)) + if (PyObject_SetAttr(err_value, state->str_verify_message, verify_obj)) goto fail; } @@ -809,8 +798,7 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, self->ssl = NULL; self->Socket = NULL; - self->ctx = sslctx; - Py_INCREF(sslctx); + self->ctx = (PySSLContext*)Py_NewRef(sslctx); self->shutdown_seen_zero = 0; self->owner = NULL; self->server_hostname = NULL; @@ -1035,8 +1023,7 @@ _asn1obj2py(_sslmodulestate *state, const ASN1_OBJECT *name, int no_name) } } if (!buflen && no_name) { - Py_INCREF(Py_None); - name_obj = Py_None; + name_obj = Py_NewRef(Py_None); } else { name_obj = PyUnicode_FromStringAndSize(namebuf, buflen); @@ -1054,17 +1041,29 @@ _create_tuple_for_attribute(_sslmodulestate *state, ASN1_OBJECT *name, ASN1_STRING *value) { Py_ssize_t buflen; - unsigned char *valuebuf = NULL; - PyObject *attr; + PyObject *pyattr; + PyObject *pyname = _asn1obj2py(state, name, 0); - buflen = ASN1_STRING_to_UTF8(&valuebuf, value); - if (buflen < 0) { + if (pyname == NULL) { _setSSLError(state, NULL, 0, __FILE__, __LINE__); return NULL; } - attr = Py_BuildValue("Ns#", _asn1obj2py(state, name, 0), valuebuf, buflen); - OPENSSL_free(valuebuf); - return attr; + + if (ASN1_STRING_type(value) == V_ASN1_BIT_STRING) { + buflen = ASN1_STRING_length(value); + pyattr = Py_BuildValue("Ny#", pyname, ASN1_STRING_get0_data(value), buflen); + } else { + unsigned char *valuebuf = NULL; + buflen = ASN1_STRING_to_UTF8(&valuebuf, value); + if (buflen < 0) { + _setSSLError(state, NULL, 0, __FILE__, __LINE__); + Py_DECREF(pyname); + return NULL; + } + pyattr = Py_BuildValue("Ns#", pyname, valuebuf, buflen); + OPENSSL_free(valuebuf); + } + return pyattr; } static PyObject * @@ -1873,8 +1872,7 @@ _ssl__SSLSocket_get_unverified_chain_impl(PySSLSocket *self) X509 *peer = SSL_get_peer_certificate(self->ssl); if (peer == NULL) { - peerobj = Py_None; - Py_INCREF(peerobj); + peerobj = Py_NewRef(Py_None); } else { /* consume X509 reference on success */ peerobj = _PySSL_CertificateFromX509(self->ctx->state, peer, 0); @@ -1904,8 +1902,7 @@ cipher_to_tuple(const SSL_CIPHER *cipher) cipher_name = SSL_CIPHER_get_name(cipher); if (cipher_name == NULL) { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(retval, 0, Py_None); + PyTuple_SET_ITEM(retval, 0, Py_NewRef(Py_None)); } else { v = PyUnicode_FromString(cipher_name); if (v == NULL) @@ -1915,8 +1912,7 @@ cipher_to_tuple(const SSL_CIPHER *cipher) cipher_protocol = SSL_CIPHER_get_version(cipher); if (cipher_protocol == NULL) { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(retval, 1, Py_None); + PyTuple_SET_ITEM(retval, 1, Py_NewRef(Py_None)); } else { v = PyUnicode_FromString(cipher_protocol); if (v == NULL) @@ -2100,16 +2096,14 @@ _ssl__SSLSocket_compression_impl(PySSLSocket *self) } static PySSLContext *PySSL_get_context(PySSLSocket *self, void *closure) { - Py_INCREF(self->ctx); - return self->ctx; + return (PySSLContext*)Py_NewRef(self->ctx); } static int PySSL_set_context(PySSLSocket *self, PyObject *value, void *closure) { if (PyObject_TypeCheck(value, self->ctx->state->PySSLContext_Type)) { - Py_INCREF(value); - Py_SETREF(self->ctx, (PySSLContext *)value); + Py_SETREF(self->ctx, (PySSLContext *)Py_NewRef(value)); SSL_set_SSL_CTX(self->ssl, self->ctx->ctx); /* Set SSL* internal msg_callback to state of new context's state */ SSL_set_msg_callback( @@ -2147,8 +2141,7 @@ PySSL_get_server_hostname(PySSLSocket *self, void *c) { if (self->server_hostname == NULL) Py_RETURN_NONE; - Py_INCREF(self->server_hostname); - return self->server_hostname; + return Py_NewRef(self->server_hostname); } PyDoc_STRVAR(PySSL_get_server_hostname_doc, @@ -2163,8 +2156,7 @@ PySSL_get_owner(PySSLSocket *self, void *c) Py_RETURN_NONE; owner = PyWeakref_GetObject(self->owner); - Py_INCREF(owner); - return owner; + return Py_NewRef(owner); } static int @@ -2817,8 +2809,7 @@ PySSL_get_session(PySSLSocket *self, void *closure) { } assert(self->ctx); - pysess->ctx = self->ctx; - Py_INCREF(pysess->ctx); + pysess->ctx = (PySSLContext*)Py_NewRef(self->ctx); pysess->session = session; PyObject_GC_Track(pysess); return (PyObject *)pysess; @@ -2989,8 +2980,8 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) int result; /* slower approach, walk MRO and get borrowed reference to module. - * _PyType_GetModuleByDef is required for SSLContext subclasses */ - PyObject *module = _PyType_GetModuleByDef(type, &_sslmodule_def); + * PyType_GetModuleByDef is required for SSLContext subclasses */ + PyObject *module = PyType_GetModuleByDef(type, &_sslmodule_def); if (module == NULL) { PyErr_SetString(PyExc_RuntimeError, "Cannot find internal module state"); @@ -3512,7 +3503,7 @@ set_min_max_proto_version(PySSLContext *self, PyObject *arg, int what) static PyObject * get_minimum_version(PySSLContext *self, void *c) { - int v = SSL_CTX_ctrl(self->ctx, SSL_CTRL_GET_MIN_PROTO_VERSION, 0, NULL); + int v = SSL_CTX_get_min_proto_version(self->ctx); if (v == 0) { v = PY_PROTO_MINIMUM_SUPPORTED; } @@ -3528,7 +3519,7 @@ set_minimum_version(PySSLContext *self, PyObject *arg, void *c) static PyObject * get_maximum_version(PySSLContext *self, void *c) { - int v = SSL_CTX_ctrl(self->ctx, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL); + int v = SSL_CTX_get_max_proto_version(self->ctx); if (v == 0) { v = PY_PROTO_MAXIMUM_SUPPORTED; } @@ -4177,7 +4168,7 @@ _ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath) /*[clinic input] _ssl._SSLContext._wrap_socket sock: object(subclass_of="get_state_ctx(self)->Sock_Type") - server_side: int + server_side: bool server_hostname as hostname_obj: object = None * owner: object = None @@ -4189,7 +4180,7 @@ static PyObject * _ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock, int server_side, PyObject *hostname_obj, PyObject *owner, PyObject *session) -/*[clinic end generated code: output=f103f238633940b4 input=f5916eadbc6eae81]*/ +/*[clinic end generated code: output=f103f238633940b4 input=700ca8fedff53994]*/ { char *hostname = NULL; PyObject *res; @@ -4214,7 +4205,7 @@ _ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock, _ssl._SSLContext._wrap_bio incoming: object(subclass_of="get_state_ctx(self)->PySSLMemoryBIO_Type", type="PySSLMemoryBIO *") outgoing: object(subclass_of="get_state_ctx(self)->PySSLMemoryBIO_Type", type="PySSLMemoryBIO *") - server_side: int + server_side: bool server_hostname as hostname_obj: object = None * owner: object = None @@ -4227,7 +4218,7 @@ _ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming, PySSLMemoryBIO *outgoing, int server_side, PyObject *hostname_obj, PyObject *owner, PyObject *session) -/*[clinic end generated code: output=5c5d6d9b41f99332 input=331edeec9c738382]*/ +/*[clinic end generated code: output=5c5d6d9b41f99332 input=a9205d097fd45a82]*/ { char *hostname = NULL; PyObject *res; @@ -4299,7 +4290,11 @@ static PyObject * _ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self) /*[clinic end generated code: output=0bee74e6e09deaaa input=35f3408021463d74]*/ { - if (!SSL_CTX_set_default_verify_paths(self->ctx)) { + int rc; + Py_BEGIN_ALLOW_THREADS + rc = SSL_CTX_set_default_verify_paths(self->ctx); + Py_END_ALLOW_THREADS + if (!rc) { _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); return NULL; } @@ -4452,8 +4447,7 @@ get_sni_callback(PySSLContext *self, void *c) if (cb == NULL) { Py_RETURN_NONE; } - Py_INCREF(cb); - return cb; + return Py_NewRef(cb); } static int @@ -4475,8 +4469,7 @@ set_sni_callback(PySSLContext *self, PyObject *arg, void *c) "not a callable object"); return -1; } - Py_INCREF(arg); - self->set_sni_cb = arg; + self->set_sni_cb = Py_NewRef(arg); SSL_CTX_set_tlsext_servername_callback(self->ctx, _servername_callback); SSL_CTX_set_tlsext_servername_arg(self->ctx, self); } @@ -5061,7 +5054,8 @@ static PyType_Spec PySSLSession_spec = { .name = "_ssl.SSLSession", .basicsize = sizeof(PySSLSession), .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_IMMUTABLETYPE), + Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION), .slots = PySSLSession_slots, }; @@ -5151,24 +5145,6 @@ _ssl_RAND_bytes_impl(PyObject *module, int n) return PySSL_RAND(module, n, 0); } -/*[clinic input] -_ssl.RAND_pseudo_bytes - n: int - / - -Generate n pseudo-random bytes. - -Return a pair (bytes, is_cryptographic). is_cryptographic is True -if the bytes generated are cryptographically strong. -[clinic start generated code]*/ - -static PyObject * -_ssl_RAND_pseudo_bytes_impl(PyObject *module, int n) -/*[clinic end generated code: output=b1509e937000e52d input=58312bd53f9bbdd0]*/ -{ - PY_SSL_DEPRECATED("ssl.RAND_pseudo_bytes() is deprecated", 1, NULL); - return PySSL_RAND(module, n, 1); -} /*[clinic input] _ssl.RAND_status @@ -5206,7 +5182,7 @@ _ssl_get_default_verify_paths_impl(PyObject *module) #define CONVERT(info, target) { \ const char *tmp = (info); \ target = NULL; \ - if (!tmp) { Py_INCREF(Py_None); target = Py_None; } \ + if (!tmp) { target = Py_NewRef(Py_None); } \ else if ((target = PyUnicode_DecodeFSDefault(tmp)) == NULL) { \ target = PyBytes_FromString(tmp); } \ if (!target) goto error; \ @@ -5321,11 +5297,9 @@ certEncodingType(DWORD encodingType) } switch(encodingType) { case X509_ASN_ENCODING: - Py_INCREF(x509_asn); - return x509_asn; + return Py_NewRef(x509_asn); case PKCS_7_ASN_ENCODING: - Py_INCREF(pkcs_7_asn); - return pkcs_7_asn; + return Py_NewRef(pkcs_7_asn); default: return PyLong_FromLong(encodingType); } @@ -5627,7 +5601,6 @@ static PyMethodDef PySSL_methods[] = { _SSL__TEST_DECODE_CERT_METHODDEF _SSL_RAND_ADD_METHODDEF _SSL_RAND_BYTES_METHODDEF - _SSL_RAND_PSEUDO_BYTES_METHODDEF _SSL_RAND_STATUS_METHODDEF _SSL_GET_DEFAULT_VERIFY_PATHS_METHODDEF _SSL_ENUM_CERTIFICATES_METHODDEF @@ -5728,8 +5701,7 @@ sslmodule_init_socketapi(PyObject *module) if ((sockmod == NULL) || (sockmod->Sock_Type == NULL)) { return -1; } - state->Sock_Type = sockmod->Sock_Type; - Py_INCREF(state->Sock_Type); + state->Sock_Type = (PyTypeObject*)Py_NewRef(sockmod->Sock_Type); return 0; } @@ -5837,10 +5809,6 @@ sslmodule_init_constants(PyObject *m) #undef ADD_AD_CONSTANT /* protocol versions */ -#ifndef OPENSSL_NO_SSL2 - PyModule_AddIntConstant(m, "PROTOCOL_SSLv2", - PY_SSL_VERSION_SSL2); -#endif #ifndef OPENSSL_NO_SSL3 PyModule_AddIntConstant(m, "PROTOCOL_SSLv3", PY_SSL_VERSION_SSL3); @@ -5877,6 +5845,8 @@ sslmodule_init_constants(PyObject *m) SSL_OP_CIPHER_SERVER_PREFERENCE); PyModule_AddIntConstant(m, "OP_SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE); PyModule_AddIntConstant(m, "OP_NO_TICKET", SSL_OP_NO_TICKET); + PyModule_AddIntConstant(m, "OP_LEGACY_SERVER_CONNECT", + SSL_OP_LEGACY_SERVER_CONNECT); #ifdef SSL_OP_SINGLE_ECDH_USE PyModule_AddIntConstant(m, "OP_SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE); #endif @@ -5896,6 +5866,9 @@ sslmodule_init_constants(PyObject *m) PyModule_AddIntConstant(m, "OP_IGNORE_UNEXPECTED_EOF", SSL_OP_IGNORE_UNEXPECTED_EOF); #endif +#ifdef SSL_OP_ENABLE_KTLS + PyModule_AddIntConstant(m, "OP_ENABLE_KTLS", SSL_OP_ENABLE_KTLS); +#endif #ifdef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT PyModule_AddIntConstant(m, "HOSTFLAG_ALWAYS_CHECK_SUBJECT", @@ -5940,8 +5913,7 @@ sslmodule_init_constants(PyObject *m) #define addbool(m, key, value) \ do { \ PyObject *bool_obj = (value) ? Py_True : Py_False; \ - Py_INCREF(bool_obj); \ - PyModule_AddObject((m), (key), bool_obj); \ + PyModule_AddObject((m), (key), Py_NewRef(bool_obj)); \ } while (0) addbool(m, "HAS_SNI", 1); @@ -5950,11 +5922,7 @@ sslmodule_init_constants(PyObject *m) addbool(m, "HAS_NPN", 0); addbool(m, "HAS_ALPN", 1); -#if defined(SSL2_VERSION) && !defined(OPENSSL_NO_SSL2) - addbool(m, "HAS_SSLv2", 1); -#else addbool(m, "HAS_SSLv2", 0); -#endif #if defined(SSL3_VERSION) && !defined(OPENSSL_NO_SSL3) addbool(m, "HAS_SSLv3", 1); @@ -6147,6 +6115,29 @@ sslmodule_init_types(PyObject *module) return 0; } +static int +sslmodule_init_strings(PyObject *module) +{ + _sslmodulestate *state = get_ssl_state(module); + state->str_library = PyUnicode_InternFromString("library"); + if (state->str_library == NULL) { + return -1; + } + state->str_reason = PyUnicode_InternFromString("reason"); + if (state->str_reason == NULL) { + return -1; + } + state->str_verify_message = PyUnicode_InternFromString("verify_message"); + if (state->str_verify_message == NULL) { + return -1; + } + state->str_verify_code = PyUnicode_InternFromString("verify_code"); + if (state->str_verify_code == NULL) { + return -1; + } + return 0; +} + static PyModuleDef_Slot sslmodule_slots[] = { {Py_mod_exec, sslmodule_init_types}, {Py_mod_exec, sslmodule_init_exceptions}, @@ -6154,6 +6145,7 @@ static PyModuleDef_Slot sslmodule_slots[] = { {Py_mod_exec, sslmodule_init_errorcodes}, {Py_mod_exec, sslmodule_init_constants}, {Py_mod_exec, sslmodule_init_versioninfo}, + {Py_mod_exec, sslmodule_init_strings}, {0, NULL} }; @@ -6203,7 +6195,10 @@ sslmodule_clear(PyObject *m) Py_CLEAR(state->err_names_to_codes); Py_CLEAR(state->lib_codes_to_names); Py_CLEAR(state->Sock_Type); - + Py_CLEAR(state->str_library); + Py_CLEAR(state->str_reason); + Py_CLEAR(state->str_verify_code); + Py_CLEAR(state->str_verify_message); return 0; } diff --git a/Modules/_ssl.h b/Modules/_ssl.h index 5fe6504a9dd..d68ccdec5e8 100644 --- a/Modules/_ssl.h +++ b/Modules/_ssl.h @@ -29,6 +29,11 @@ typedef struct { PyObject *lib_codes_to_names; /* socket type from module CAPI */ PyTypeObject *Sock_Type; + /* Interned strings */ + PyObject *str_library; + PyObject *str_reason; + PyObject *str_verify_code; + PyObject *str_verify_message; } _sslmodulestate; static struct PyModuleDef _sslmodule_def; @@ -42,7 +47,7 @@ get_ssl_state(PyObject *module) } #define get_state_type(type) \ - (get_ssl_state(_PyType_GetModuleByDef(type, &_sslmodule_def))) + (get_ssl_state(PyType_GetModuleByDef(type, &_sslmodule_def))) #define get_state_ctx(c) (((PySSLContext *)(c))->state) #define get_state_sock(s) (((PySSLSocket *)(s))->ctx->state) #define get_state_obj(o) ((_sslmodulestate *)PyType_GetModuleState(Py_TYPE(o))) diff --git a/Modules/_ssl/clinic/cert.c.h b/Modules/_ssl/clinic/cert.c.h index c4377128b36..a052ab2086f 100644 --- a/Modules/_ssl/clinic/cert.c.h +++ b/Modules/_ssl/clinic/cert.c.h @@ -2,13 +2,19 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_ssl_Certificate_public_bytes__doc__, "public_bytes($self, /, format=Encoding.PEM)\n" "--\n" "\n"); #define _SSL_CERTIFICATE_PUBLIC_BYTES_METHODDEF \ - {"public_bytes", (PyCFunction)(void(*)(void))_ssl_Certificate_public_bytes, METH_FASTCALL|METH_KEYWORDS, _ssl_Certificate_public_bytes__doc__}, + {"public_bytes", _PyCFunction_CAST(_ssl_Certificate_public_bytes), METH_FASTCALL|METH_KEYWORDS, _ssl_Certificate_public_bytes__doc__}, static PyObject * _ssl_Certificate_public_bytes_impl(PySSLCertificate *self, int format); @@ -17,8 +23,31 @@ static PyObject * _ssl_Certificate_public_bytes(PySSLCertificate *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(format), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"format", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "public_bytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "public_bytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int format = PY_SSL_ENCODING_PEM; @@ -57,4 +86,4 @@ _ssl_Certificate_get_info(PySSLCertificate *self, PyObject *Py_UNUSED(ignored)) { return _ssl_Certificate_get_info_impl(self); } -/*[clinic end generated code: output=569d161749ead2da input=a9049054013a1b77]*/ +/*[clinic end generated code: output=82efada014f9b7fe input=a9049054013a1b77]*/ diff --git a/Modules/_ssl/debughelpers.c b/Modules/_ssl/debughelpers.c index 03c125eb44f..08f3457035b 100644 --- a/Modules/_ssl/debughelpers.c +++ b/Modules/_ssl/debughelpers.c @@ -87,8 +87,7 @@ _PySSL_msg_callback(int write_p, int version, int content_type, static PyObject * _PySSLContext_get_msg_callback(PySSLContext *self, void *c) { if (self->msg_cb != NULL) { - Py_INCREF(self->msg_cb); - return self->msg_cb; + return Py_NewRef(self->msg_cb); } else { Py_RETURN_NONE; } @@ -107,8 +106,7 @@ _PySSLContext_set_msg_callback(PySSLContext *self, PyObject *arg, void *c) { "not a callable object"); return -1; } - Py_INCREF(arg); - self->msg_cb = arg; + self->msg_cb = Py_NewRef(arg); SSL_CTX_set_msg_callback(self->ctx, _PySSL_msg_callback); } return 0; @@ -166,8 +164,7 @@ _PySSL_keylog_callback(const SSL *ssl, const char *line) static PyObject * _PySSLContext_get_keylog_filename(PySSLContext *self, void *c) { if (self->keylog_filename != NULL) { - Py_INCREF(self->keylog_filename); - return self->keylog_filename; + return Py_NewRef(self->keylog_filename); } else { Py_RETURN_NONE; } @@ -203,8 +200,7 @@ _PySSLContext_set_keylog_filename(PySSLContext *self, PyObject *arg, void *c) { "Can't malloc memory for keylog file"); return -1; } - Py_INCREF(arg); - self->keylog_filename = arg; + self->keylog_filename = Py_NewRef(arg); /* Write a header for seekable, empty files (this excludes pipes). */ PySSL_BEGIN_ALLOW_THREADS diff --git a/Modules/_statisticsmodule.c b/Modules/_statisticsmodule.c index 78c0676a01f..b9d1e4f1616 100644 --- a/Modules/_statisticsmodule.c +++ b/Modules/_statisticsmodule.c @@ -31,7 +31,7 @@ _statistics__normal_dist_inv_cdf_impl(PyObject *module, double p, double mu, /*[clinic end generated code: output=02fd19ddaab36602 input=24715a74be15296a]*/ { double q, num, den, r, x; - if (p <= 0.0 || p >= 1.0 || sigma <= 0.0) { + if (p <= 0.0 || p >= 1.0) { goto error; } diff --git a/Modules/_struct.c b/Modules/_struct.c index 210dbdc752f..3db7b991acd 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -10,7 +10,6 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" -#include "pycore_floatobject.h" // _PyFloat_Unpack2() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "structmember.h" // PyMemberDef #include @@ -38,7 +37,7 @@ get_struct_state(PyObject *module) static struct PyModuleDef _structmodule; #define get_struct_state_structinst(self) \ - (get_struct_state(_PyType_GetModuleByDef(Py_TYPE(self), &_structmodule))) + (get_struct_state(PyType_GetModuleByDef(Py_TYPE(self), &_structmodule))) #define get_struct_state_iterinst(self) \ (get_struct_state(PyType_GetModule(Py_TYPE(self)))) @@ -168,9 +167,6 @@ get_long(_structmodulestate *state, PyObject *v, long *p) x = PyLong_AsLong(v); Py_DECREF(v); if (x == (long)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(state->StructError, - "argument out of range"); return -1; } *p = x; @@ -192,9 +188,6 @@ get_ulong(_structmodulestate *state, PyObject *v, unsigned long *p) x = PyLong_AsUnsignedLong(v); Py_DECREF(v); if (x == (unsigned long)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(state->StructError, - "argument out of range"); return -1; } *p = x; @@ -215,9 +208,6 @@ get_longlong(_structmodulestate *state, PyObject *v, long long *p) x = PyLong_AsLongLong(v); Py_DECREF(v); if (x == (long long)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(state->StructError, - "argument out of range"); return -1; } *p = x; @@ -238,9 +228,6 @@ get_ulonglong(_structmodulestate *state, PyObject *v, unsigned long long *p) x = PyLong_AsUnsignedLongLong(v); Py_DECREF(v); if (x == (unsigned long long)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(state->StructError, - "argument out of range"); return -1; } *p = x; @@ -261,9 +248,6 @@ get_ssize_t(_structmodulestate *state, PyObject *v, Py_ssize_t *p) x = PyLong_AsSsize_t(v); Py_DECREF(v); if (x == (Py_ssize_t)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(state->StructError, - "argument out of range"); return -1; } *p = x; @@ -284,9 +268,6 @@ get_size_t(_structmodulestate *state, PyObject *v, size_t *p) x = PyLong_AsSize_t(v); Py_DECREF(v); if (x == (size_t)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(state->StructError, - "argument out of range"); return -1; } *p = x; @@ -294,7 +275,7 @@ get_size_t(_structmodulestate *state, PyObject *v, size_t *p) } -#define RANGE_ERROR(state, x, f, flag, mask) return _range_error(state, f, flag) +#define RANGE_ERROR(state, f, flag) return _range_error(state, f, flag) /* Floating point helpers */ @@ -303,9 +284,7 @@ static PyObject * unpack_halffloat(const char *p, /* start of 2-byte string */ int le) /* true for little-endian, false for big-endian */ { - double x; - - x = _PyFloat_Unpack2((unsigned char *)p, le); + double x = PyFloat_Unpack2(p, le); if (x == -1.0 && PyErr_Occurred()) { return NULL; } @@ -324,7 +303,7 @@ pack_halffloat(_structmodulestate *state, "required argument is not a float"); return -1; } - return _PyFloat_Pack2(x, (unsigned char *)p, le); + return PyFloat_Pack2(x, p, le); } static PyObject * @@ -333,7 +312,7 @@ unpack_float(const char *p, /* start of 4-byte string */ { double x; - x = _PyFloat_Unpack4((unsigned char *)p, le); + x = PyFloat_Unpack4(p, le); if (x == -1.0 && PyErr_Occurred()) return NULL; return PyFloat_FromDouble(x); @@ -345,7 +324,7 @@ unpack_double(const char *p, /* start of 8-byte string */ { double x; - x = _PyFloat_Unpack8((unsigned char *)p, le); + x = PyFloat_Unpack8(p, le); if (x == -1.0 && PyErr_Occurred()) return NULL; return PyFloat_FromDouble(x); @@ -548,12 +527,14 @@ static int np_byte(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; - if (get_long(state, v, &x) < 0) + if (get_long(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 0); + } return -1; + } if (x < -128 || x > 127) { - PyErr_SetString(state->StructError, - "byte format requires -128 <= number <= 127"); - return -1; + RANGE_ERROR(state, f, 0); } *p = (char)x; return 0; @@ -563,12 +544,14 @@ static int np_ubyte(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; - if (get_long(state, v, &x) < 0) + if (get_long(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 1); + } return -1; + } if (x < 0 || x > 255) { - PyErr_SetString(state->StructError, - "ubyte format requires 0 <= number <= 255"); - return -1; + RANGE_ERROR(state, f, 1); } *(unsigned char *)p = (unsigned char)x; return 0; @@ -591,13 +574,14 @@ np_short(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; short y; - if (get_long(state, v, &x) < 0) + if (get_long(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 0); + } return -1; + } if (x < SHRT_MIN || x > SHRT_MAX) { - PyErr_Format(state->StructError, - "short format requires %d <= number <= %d", - (int)SHRT_MIN, (int)SHRT_MAX); - return -1; + RANGE_ERROR(state, f, 0); } y = (short)x; memcpy(p, (char *)&y, sizeof y); @@ -609,13 +593,14 @@ np_ushort(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; unsigned short y; - if (get_long(state, v, &x) < 0) + if (get_long(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 1); + } return -1; + } if (x < 0 || x > USHRT_MAX) { - PyErr_Format(state->StructError, - "ushort format requires 0 <= number <= %u", - (unsigned int)USHRT_MAX); - return -1; + RANGE_ERROR(state, f, 1); } y = (unsigned short)x; memcpy(p, (char *)&y, sizeof y); @@ -627,11 +612,15 @@ np_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; int y; - if (get_long(state, v, &x) < 0) + if (get_long(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 0); + } return -1; + } #if (SIZEOF_LONG > SIZEOF_INT) if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX))) - RANGE_ERROR(state, x, f, 0, -1); + RANGE_ERROR(state, f, 0); #endif y = (int)x; memcpy(p, (char *)&y, sizeof y); @@ -643,12 +632,16 @@ np_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { unsigned long x; unsigned int y; - if (get_ulong(state, v, &x) < 0) + if (get_ulong(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 1); + } return -1; + } y = (unsigned int)x; #if (SIZEOF_LONG > SIZEOF_INT) if (x > ((unsigned long)UINT_MAX)) - RANGE_ERROR(state, y, f, 1, -1); + RANGE_ERROR(state, f, 1); #endif memcpy(p, (char *)&y, sizeof y); return 0; @@ -658,8 +651,12 @@ static int np_long(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; - if (get_long(state, v, &x) < 0) + if (get_long(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 0); + } return -1; + } memcpy(p, (char *)&x, sizeof x); return 0; } @@ -668,8 +665,12 @@ static int np_ulong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { unsigned long x; - if (get_ulong(state, v, &x) < 0) + if (get_ulong(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 1); + } return -1; + } memcpy(p, (char *)&x, sizeof x); return 0; } @@ -678,8 +679,12 @@ static int np_ssize_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { Py_ssize_t x; - if (get_ssize_t(state, v, &x) < 0) + if (get_ssize_t(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 0); + } return -1; + } memcpy(p, (char *)&x, sizeof x); return 0; } @@ -688,8 +693,12 @@ static int np_size_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { size_t x; - if (get_size_t(state, v, &x) < 0) + if (get_size_t(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 1); + } return -1; + } memcpy(p, (char *)&x, sizeof x); return 0; } @@ -698,8 +707,16 @@ static int np_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long long x; - if (get_longlong(state, v, &x) < 0) + if (get_longlong(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_Format(state->StructError, + "'%c' format requires %lld <= number <= %lld", + f->format, + LLONG_MIN, + LLONG_MAX); + } return -1; + } memcpy(p, (char *)&x, sizeof x); return 0; } @@ -708,8 +725,15 @@ static int np_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { unsigned long long x; - if (get_ulonglong(state, v, &x) < 0) + if (get_ulonglong(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_Format(state->StructError, + "'%c' format requires 0 <= number <= %llu", + f->format, + ULLONG_MAX); + } return -1; + } memcpy(p, (char *)&x, sizeof x); return 0; } @@ -809,18 +833,37 @@ static const formatdef native_table[] = { /* Big-endian routines. *****************************************************/ static PyObject * -bu_int(_structmodulestate *state, const char *p, const formatdef *f) +bu_short(_structmodulestate *state, const char *p, const formatdef *f) { - long x = 0; - Py_ssize_t i = f->size; + unsigned long x = 0; + + /* This function is only ever used in the case f->size == 2. */ + assert(f->size == 2); + Py_ssize_t i = 2; const unsigned char *bytes = (const unsigned char *)p; do { x = (x<<8) | *bytes++; } while (--i > 0); - /* Extend the sign bit. */ - if (SIZEOF_LONG > f->size) - x |= -(x & (1L << ((8 * f->size) - 1))); - return PyLong_FromLong(x); + /* Extend sign, avoiding implementation-defined or undefined behaviour. */ + x = (x ^ 0x8000U) - 0x8000U; + return PyLong_FromLong(x & 0x8000U ? -1 - (long)(~x) : (long)x); +} + +static PyObject * +bu_int(_structmodulestate *state, const char *p, const formatdef *f) +{ + unsigned long x = 0; + + /* This function is only ever used in the case f->size == 4. */ + assert(f->size == 4); + Py_ssize_t i = 4; + const unsigned char *bytes = (const unsigned char *)p; + do { + x = (x<<8) | *bytes++; + } while (--i > 0); + /* Extend sign, avoiding implementation-defined or undefined behaviour. */ + x = (x ^ 0x80000000U) - 0x80000000U; + return PyLong_FromLong(x & 0x80000000U ? -1 - (long)(~x) : (long)x); } static PyObject * @@ -838,16 +881,19 @@ bu_uint(_structmodulestate *state, const char *p, const formatdef *f) static PyObject * bu_longlong(_structmodulestate *state, const char *p, const formatdef *f) { - long long x = 0; - Py_ssize_t i = f->size; + unsigned long long x = 0; + + /* This function is only ever used in the case f->size == 8. */ + assert(f->size == 8); + Py_ssize_t i = 8; const unsigned char *bytes = (const unsigned char *)p; do { x = (x<<8) | *bytes++; } while (--i > 0); - /* Extend the sign bit. */ - if (SIZEOF_LONG_LONG > f->size) - x |= -(x & ((long long)1 << ((8 * f->size) - 1))); - return PyLong_FromLongLong(x); + /* Extend sign, avoiding implementation-defined or undefined behaviour. */ + x = (x ^ 0x8000000000000000U) - 0x8000000000000000U; + return PyLong_FromLongLong( + x & 0x8000000000000000U ? -1 - (long long)(~x) : (long long)x); } static PyObject * @@ -892,15 +938,19 @@ bp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) long x; Py_ssize_t i; unsigned char *q = (unsigned char *)p; - if (get_long(state, v, &x) < 0) + if (get_long(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 0); + } return -1; + } i = f->size; if (i != SIZEOF_LONG) { if ((i == 2) && (x < -32768 || x > 32767)) - RANGE_ERROR(state, x, f, 0, 0xffffL); + RANGE_ERROR(state, f, 0); #if (SIZEOF_LONG != 4) else if ((i == 4) && (x < -2147483648L || x > 2147483647L)) - RANGE_ERROR(state, x, f, 0, 0xffffffffL); + RANGE_ERROR(state, f, 0); #endif } do { @@ -916,14 +966,18 @@ bp_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) unsigned long x; Py_ssize_t i; unsigned char *q = (unsigned char *)p; - if (get_ulong(state, v, &x) < 0) + if (get_ulong(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 1); + } return -1; + } i = f->size; if (i != SIZEOF_LONG) { unsigned long maxint = 1; maxint <<= (unsigned long)(i * 8); if (x >= maxint) - RANGE_ERROR(state, x, f, 1, maxint - 1); + RANGE_ERROR(state, f, 1); } do { q[--i] = (unsigned char)(x & 0xffUL); @@ -945,6 +999,14 @@ bp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 0, /* little_endian */ 1 /* signed */); Py_DECREF(v); + if (res == -1 && PyErr_Occurred()) { + PyErr_Format(state->StructError, + "'%c' format requires %lld <= number <= %lld", + f->format, + LLONG_MIN, + LLONG_MAX); + return -1; + } return res; } @@ -961,6 +1023,13 @@ bp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f 0, /* little_endian */ 0 /* signed */); Py_DECREF(v); + if (res == -1 && PyErr_Occurred()) { + PyErr_Format(state->StructError, + "'%c' format requires 0 <= number <= %llu", + f->format, + ULLONG_MAX); + return -1; + } return res; } @@ -979,7 +1048,7 @@ bp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) "required argument is not a float"); return -1; } - return _PyFloat_Pack4(x, (unsigned char *)p, 0); + return PyFloat_Pack4(x, p, 0); } static int @@ -991,7 +1060,7 @@ bp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) "required argument is not a float"); return -1; } - return _PyFloat_Pack8(x, (unsigned char *)p, 0); + return PyFloat_Pack8(x, p, 0); } static int @@ -1012,7 +1081,7 @@ static formatdef bigendian_table[] = { {'c', 1, 0, nu_char, np_char}, {'s', 1, 0, NULL}, {'p', 1, 0, NULL}, - {'h', 2, 0, bu_int, bp_int}, + {'h', 2, 0, bu_short, bp_int}, {'H', 2, 0, bu_uint, bp_uint}, {'i', 4, 0, bu_int, bp_int}, {'I', 4, 0, bu_uint, bp_uint}, @@ -1030,18 +1099,37 @@ static formatdef bigendian_table[] = { /* Little-endian routines. *****************************************************/ static PyObject * -lu_int(_structmodulestate *state, const char *p, const formatdef *f) +lu_short(_structmodulestate *state, const char *p, const formatdef *f) { - long x = 0; - Py_ssize_t i = f->size; + unsigned long x = 0; + + /* This function is only ever used in the case f->size == 2. */ + assert(f->size == 2); + Py_ssize_t i = 2; const unsigned char *bytes = (const unsigned char *)p; do { x = (x<<8) | bytes[--i]; } while (i > 0); - /* Extend the sign bit. */ - if (SIZEOF_LONG > f->size) - x |= -(x & (1L << ((8 * f->size) - 1))); - return PyLong_FromLong(x); + /* Extend sign, avoiding implementation-defined or undefined behaviour. */ + x = (x ^ 0x8000U) - 0x8000U; + return PyLong_FromLong(x & 0x8000U ? -1 - (long)(~x) : (long)x); +} + +static PyObject * +lu_int(_structmodulestate *state, const char *p, const formatdef *f) +{ + unsigned long x = 0; + + /* This function is only ever used in the case f->size == 4. */ + assert(f->size == 4); + Py_ssize_t i = 4; + const unsigned char *bytes = (const unsigned char *)p; + do { + x = (x<<8) | bytes[--i]; + } while (i > 0); + /* Extend sign, avoiding implementation-defined or undefined behaviour. */ + x = (x ^ 0x80000000U) - 0x80000000U; + return PyLong_FromLong(x & 0x80000000U ? -1 - (long)(~x) : (long)x); } static PyObject * @@ -1059,16 +1147,19 @@ lu_uint(_structmodulestate *state, const char *p, const formatdef *f) static PyObject * lu_longlong(_structmodulestate *state, const char *p, const formatdef *f) { - long long x = 0; - Py_ssize_t i = f->size; + unsigned long long x = 0; + + /* This function is only ever used in the case f->size == 8. */ + assert(f->size == 8); + Py_ssize_t i = 8; const unsigned char *bytes = (const unsigned char *)p; do { x = (x<<8) | bytes[--i]; } while (i > 0); - /* Extend the sign bit. */ - if (SIZEOF_LONG_LONG > f->size) - x |= -(x & ((long long)1 << ((8 * f->size) - 1))); - return PyLong_FromLongLong(x); + /* Extend sign, avoiding implementation-defined or undefined behaviour. */ + x = (x ^ 0x8000000000000000U) - 0x8000000000000000U; + return PyLong_FromLongLong( + x & 0x8000000000000000U ? -1 - (long long)(~x) : (long long)x); } static PyObject * @@ -1107,15 +1198,19 @@ lp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) long x; Py_ssize_t i; unsigned char *q = (unsigned char *)p; - if (get_long(state, v, &x) < 0) + if (get_long(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 0); + } return -1; + } i = f->size; if (i != SIZEOF_LONG) { if ((i == 2) && (x < -32768 || x > 32767)) - RANGE_ERROR(state, x, f, 0, 0xffffL); + RANGE_ERROR(state, f, 0); #if (SIZEOF_LONG != 4) else if ((i == 4) && (x < -2147483648L || x > 2147483647L)) - RANGE_ERROR(state, x, f, 0, 0xffffffffL); + RANGE_ERROR(state, f, 0); #endif } do { @@ -1131,14 +1226,18 @@ lp_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) unsigned long x; Py_ssize_t i; unsigned char *q = (unsigned char *)p; - if (get_ulong(state, v, &x) < 0) + if (get_ulong(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 1); + } return -1; + } i = f->size; if (i != SIZEOF_LONG) { unsigned long maxint = 1; maxint <<= (unsigned long)(i * 8); if (x >= maxint) - RANGE_ERROR(state, x, f, 1, maxint - 1); + RANGE_ERROR(state, f, 1); } do { *q++ = (unsigned char)(x & 0xffUL); @@ -1160,6 +1259,14 @@ lp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 1, /* little_endian */ 1 /* signed */); Py_DECREF(v); + if (res == -1 && PyErr_Occurred()) { + PyErr_Format(state->StructError, + "'%c' format requires %lld <= number <= %lld", + f->format, + LLONG_MIN, + LLONG_MAX); + return -1; + } return res; } @@ -1176,6 +1283,13 @@ lp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f 1, /* little_endian */ 0 /* signed */); Py_DECREF(v); + if (res == -1 && PyErr_Occurred()) { + PyErr_Format(state->StructError, + "'%c' format requires 0 <= number <= %llu", + f->format, + ULLONG_MAX); + return -1; + } return res; } @@ -1194,7 +1308,7 @@ lp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) "required argument is not a float"); return -1; } - return _PyFloat_Pack4(x, (unsigned char *)p, 1); + return PyFloat_Pack4(x, p, 1); } static int @@ -1206,7 +1320,7 @@ lp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) "required argument is not a float"); return -1; } - return _PyFloat_Pack8(x, (unsigned char *)p, 1); + return PyFloat_Pack8(x, p, 1); } static formatdef lilendian_table[] = { @@ -1216,7 +1330,7 @@ static formatdef lilendian_table[] = { {'c', 1, 0, nu_char, np_char}, {'s', 1, 0, NULL}, {'p', 1, 0, NULL}, - {'h', 2, 0, lu_int, lp_int}, + {'h', 2, 0, lu_short, lp_int}, {'H', 2, 0, lu_uint, lp_uint}, {'i', 4, 0, lu_int, lp_int}, {'I', 4, 0, lu_uint, lp_uint}, @@ -1436,28 +1550,9 @@ prepare_s(PyStructObject *self) return -1; } -static PyObject * -s_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *self; - - assert(type != NULL); - allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc); - assert(alloc_func != NULL); - - self = alloc_func(type, 0); - if (self != NULL) { - PyStructObject *s = (PyStructObject*)self; - s->s_format = Py_NewRef(Py_None); - s->s_codes = NULL; - s->s_size = -1; - s->s_len = -1; - } - return self; -} - /*[clinic input] -Struct.__init__ +@classmethod +Struct.__new__ format: object @@ -1469,16 +1564,24 @@ the format string. See help(struct) for more on format strings. [clinic start generated code]*/ -static int -Struct___init___impl(PyStructObject *self, PyObject *format) -/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/ +static PyObject * +Struct_impl(PyTypeObject *type, PyObject *format) +/*[clinic end generated code: output=49468b044e334308 input=8b91868eb1df0e28]*/ { - int ret = 0; + allocfunc alloc = PyType_GetSlot(type, Py_tp_alloc); + assert(alloc != NULL); + PyStructObject *self = (PyStructObject *)alloc(type, 0); + + if (self == NULL) { + return NULL; + } if (PyUnicode_Check(format)) { format = PyUnicode_AsASCIIString(format); - if (format == NULL) - return -1; + if (format == NULL) { + Py_DECREF(self); + return NULL; + } } else { Py_INCREF(format); @@ -1486,23 +1589,44 @@ Struct___init___impl(PyStructObject *self, PyObject *format) if (!PyBytes_Check(format)) { Py_DECREF(format); + Py_DECREF(self); PyErr_Format(PyExc_TypeError, "Struct() argument 1 must be a str or bytes object, " "not %.200s", _PyType_Name(Py_TYPE(format))); - return -1; + return NULL; } - Py_SETREF(self->s_format, format); + self->s_format = format; - ret = prepare_s(self); - return ret; + if (prepare_s(self) < 0) { + Py_DECREF(self); + return NULL; + } + return (PyObject *)self; +} + + +static int +s_clear(PyStructObject *s) +{ + Py_CLEAR(s->s_format); + return 0; +} + +static int +s_traverse(PyStructObject *s, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(s)); + Py_VISIT(s->s_format); + return 0; } static void s_dealloc(PyStructObject *s) { PyTypeObject *tp = Py_TYPE(s); + PyObject_GC_UnTrack(s); if (s->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *)s); if (s->s_codes != NULL) { @@ -1728,7 +1852,8 @@ static PyType_Spec unpackiter_type_spec = { "_struct.unpack_iterator", sizeof(unpackiterobject), 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), unpackiter_type_slots }; @@ -1777,8 +1902,7 @@ Struct_iter_unpack(PyStructObject *self, PyObject *buffer) Py_DECREF(iter); return NULL; } - Py_INCREF(self); - iter->so = self; + iter->so = (PyStructObject*)Py_NewRef(self); iter->index = 0; return (PyObject *)iter; } @@ -2039,21 +2163,19 @@ PyDoc_STRVAR(s_sizeof__doc__, static PyObject * s_sizeof(PyStructObject *self, void *unused) { - Py_ssize_t size; - formatcode *code; - - size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode); - for (code = self->s_codes; code->fmtdef != NULL; code++) + size_t size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode); + for (formatcode *code = self->s_codes; code->fmtdef != NULL; code++) { size += sizeof(formatcode); - return PyLong_FromSsize_t(size); + } + return PyLong_FromSize_t(size); } /* List of functions */ static struct PyMethodDef s_methods[] = { STRUCT_ITER_UNPACK_METHODDEF - {"pack", (PyCFunction)(void(*)(void))s_pack, METH_FASTCALL, s_pack__doc__}, - {"pack_into", (PyCFunction)(void(*)(void))s_pack_into, METH_FASTCALL, s_pack_into__doc__}, + {"pack", _PyCFunction_CAST(s_pack), METH_FASTCALL, s_pack__doc__}, + {"pack_into", _PyCFunction_CAST(s_pack_into), METH_FASTCALL, s_pack_into__doc__}, STRUCT_UNPACK_METHODDEF STRUCT_UNPACK_FROM_METHODDEF {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__}, @@ -2065,8 +2187,6 @@ static PyMemberDef s_members[] = { {NULL} /* sentinel */ }; -#define OFF(x) offsetof(PyStructObject, x) - static PyGetSetDef s_getsetlist[] = { {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL}, {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL}, @@ -2083,13 +2203,14 @@ static PyType_Slot PyStructType_slots[] = { {Py_tp_getattro, PyObject_GenericGetAttr}, {Py_tp_setattro, PyObject_GenericSetAttr}, {Py_tp_doc, (void*)s__doc__}, + {Py_tp_traverse, s_traverse}, + {Py_tp_clear, s_clear}, {Py_tp_methods, s_methods}, {Py_tp_members, s_members}, {Py_tp_getset, s_getsetlist}, - {Py_tp_init, Struct___init__}, + {Py_tp_new, Struct}, {Py_tp_alloc, PyType_GenericAlloc}, - {Py_tp_new, s_new}, - {Py_tp_free, PyObject_Del}, + {Py_tp_free, PyObject_GC_Del}, {0, 0}, }; @@ -2097,7 +2218,8 @@ static PyType_Spec PyStructType_spec = { "_struct.Struct", sizeof(PyStructObject), 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_IMMUTABLETYPE), PyStructType_slots }; @@ -2113,8 +2235,7 @@ cache_struct_converter(PyObject *module, PyObject *fmt, PyStructObject **ptr) _structmodulestate *state = get_struct_state(module); if (fmt == NULL) { - Py_DECREF(*ptr); - *ptr = NULL; + Py_SETREF(*ptr, NULL); return 1; } @@ -2126,8 +2247,7 @@ cache_struct_converter(PyObject *module, PyObject *fmt, PyStructObject **ptr) s_object = PyDict_GetItemWithError(state->cache, fmt); if (s_object != NULL) { - Py_INCREF(s_object); - *ptr = (PyStructObject *)s_object; + *ptr = (PyStructObject *)Py_NewRef(s_object); return Py_CLEANUP_SUPPORTED; } else if (PyErr_Occurred()) { @@ -2303,8 +2423,8 @@ static struct PyMethodDef module_functions[] = { _CLEARCACHE_METHODDEF CALCSIZE_METHODDEF ITER_UNPACK_METHODDEF - {"pack", (PyCFunction)(void(*)(void))pack, METH_FASTCALL, pack_doc}, - {"pack_into", (PyCFunction)(void(*)(void))pack_into, METH_FASTCALL, pack_into_doc}, + {"pack", _PyCFunction_CAST(pack), METH_FASTCALL, pack_doc}, + {"pack_into", _PyCFunction_CAST(pack_into), METH_FASTCALL, pack_into_doc}, UNPACK_METHODDEF UNPACK_FROM_METHODDEF {NULL, NULL} /* sentinel */ diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 1b4fb09fb8f..63ed4dc6ca8 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -1524,8 +1524,7 @@ ndarray_getbuf(NDArrayObject *self, Py_buffer *view, int flags) return -1; } - view->obj = (PyObject *)self; - Py_INCREF(view->obj); + view->obj = Py_NewRef(self); self->head->exports++; return 0; @@ -1788,8 +1787,7 @@ ndarray_subscript(NDArrayObject *self, PyObject *key) return unpack_single(base->buf, base->format, base->itemsize); } else if (key == Py_Ellipsis) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else { PyErr_SetString(PyExc_TypeError, "invalid indexing of scalar"); @@ -2021,8 +2019,7 @@ ndarray_get_obj(NDArrayObject *self, void *closure) if (base->obj == NULL) { Py_RETURN_NONE; } - Py_INCREF(base->obj); - return base->obj; + return Py_NewRef(base->obj); } static PyObject * @@ -2559,8 +2556,7 @@ result: PyBuffer_Release(&v2); ret = equal ? Py_True : Py_False; - Py_INCREF(ret); - return ret; + return Py_NewRef(ret); } static PyObject * @@ -2597,8 +2593,7 @@ is_contiguous(PyObject *self, PyObject *args) PyBuffer_Release(&view); } - Py_INCREF(ret); - return ret; + return Py_NewRef(ret); } static Py_hash_t @@ -2633,7 +2628,7 @@ static PyMethodDef ndarray_methods [] = { { "tolist", ndarray_tolist, METH_NOARGS, NULL }, { "tobytes", ndarray_tobytes, METH_NOARGS, NULL }, - { "push", (PyCFunction)(void(*)(void))ndarray_push, METH_VARARGS|METH_KEYWORDS, NULL }, + { "push", _PyCFunction_CAST(ndarray_push), METH_VARARGS|METH_KEYWORDS, NULL }, { "pop", ndarray_pop, METH_NOARGS, NULL }, { "add_suboffsets", ndarray_add_suboffsets, METH_NOARGS, NULL }, { "memoryview_from_buffer", ndarray_memoryview_from_buffer, METH_NOARGS, NULL }, @@ -2748,8 +2743,7 @@ staticarray_getbuf(StaticArrayObject *self, Py_buffer *view, int flags) view->obj = NULL; /* Don't use this in new code. */ } else { - view->obj = (PyObject *)self; - Py_INCREF(view->obj); + view->obj = Py_NewRef(self); } return 0; diff --git a/Modules/_testcapi/README.txt b/Modules/_testcapi/README.txt new file mode 100644 index 00000000000..134b6efc638 --- /dev/null +++ b/Modules/_testcapi/README.txt @@ -0,0 +1,3 @@ +Tests in this directory are compiled into the _testcapi extension. +The main file for the extension is Modules/_testcapimodule.c, which +calls `_PyTestCapi_Init_*` from these functions. diff --git a/Modules/_testcapi/clinic/vectorcall.c.h b/Modules/_testcapi/clinic/vectorcall.c.h new file mode 100644 index 00000000000..765afeda9b3 --- /dev/null +++ b/Modules/_testcapi/clinic/vectorcall.c.h @@ -0,0 +1,113 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(_testcapi_VectorCallClass_set_vectorcall__doc__, +"set_vectorcall($self, type, /)\n" +"--\n" +"\n" +"Set self\'s vectorcall function for `type` to one that returns \"vectorcall\""); + +#define _TESTCAPI_VECTORCALLCLASS_SET_VECTORCALL_METHODDEF \ + {"set_vectorcall", (PyCFunction)_testcapi_VectorCallClass_set_vectorcall, METH_O, _testcapi_VectorCallClass_set_vectorcall__doc__}, + +static PyObject * +_testcapi_VectorCallClass_set_vectorcall_impl(PyObject *self, + PyTypeObject *type); + +static PyObject * +_testcapi_VectorCallClass_set_vectorcall(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyTypeObject *type; + + if (!PyObject_TypeCheck(arg, &PyType_Type)) { + _PyArg_BadArgument("set_vectorcall", "argument", (&PyType_Type)->tp_name, arg); + goto exit; + } + type = (PyTypeObject *)arg; + return_value = _testcapi_VectorCallClass_set_vectorcall_impl(self, type); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_make_vectorcall_class__doc__, +"make_vectorcall_class($module, base=, /)\n" +"--\n" +"\n" +"Create a class whose instances return \"tpcall\" when called.\n" +"\n" +"When the \"set_vectorcall\" method is called on an instance, a vectorcall\n" +"function that returns \"vectorcall\" will be installed."); + +#define _TESTCAPI_MAKE_VECTORCALL_CLASS_METHODDEF \ + {"make_vectorcall_class", _PyCFunction_CAST(_testcapi_make_vectorcall_class), METH_FASTCALL, _testcapi_make_vectorcall_class__doc__}, + +static PyObject * +_testcapi_make_vectorcall_class_impl(PyObject *module, PyTypeObject *base); + +static PyObject * +_testcapi_make_vectorcall_class(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyTypeObject *base = NULL; + + if (!_PyArg_CheckPositional("make_vectorcall_class", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!PyObject_TypeCheck(args[0], &PyType_Type)) { + _PyArg_BadArgument("make_vectorcall_class", "argument 1", (&PyType_Type)->tp_name, args[0]); + goto exit; + } + base = (PyTypeObject *)args[0]; +skip_optional: + return_value = _testcapi_make_vectorcall_class_impl(module, base); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_has_vectorcall_flag__doc__, +"has_vectorcall_flag($module, type, /)\n" +"--\n" +"\n" +"Return true iff Py_TPFLAGS_HAVE_VECTORCALL is set on the class."); + +#define _TESTCAPI_HAS_VECTORCALL_FLAG_METHODDEF \ + {"has_vectorcall_flag", (PyCFunction)_testcapi_has_vectorcall_flag, METH_O, _testcapi_has_vectorcall_flag__doc__}, + +static int +_testcapi_has_vectorcall_flag_impl(PyObject *module, PyTypeObject *type); + +static PyObject * +_testcapi_has_vectorcall_flag(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyTypeObject *type; + int _return_value; + + if (!PyObject_TypeCheck(arg, &PyType_Type)) { + _PyArg_BadArgument("has_vectorcall_flag", "argument", (&PyType_Type)->tp_name, arg); + goto exit; + } + type = (PyTypeObject *)arg; + _return_value = _testcapi_has_vectorcall_flag_impl(module, type); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} +/*[clinic end generated code: output=609569aa9942584f input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/datetime.c b/Modules/_testcapi/datetime.c new file mode 100644 index 00000000000..88f992915fa --- /dev/null +++ b/Modules/_testcapi/datetime.c @@ -0,0 +1,451 @@ +#include "parts.h" + +#include "datetime.h" // PyDateTimeAPI + + +static int test_run_counter = 0; + +static PyObject * +test_datetime_capi(PyObject *self, PyObject *args) +{ + if (PyDateTimeAPI) { + if (test_run_counter) { + /* Probably regrtest.py -R */ + Py_RETURN_NONE; + } + else { + PyErr_SetString(PyExc_AssertionError, + "PyDateTime_CAPI somehow initialized"); + return NULL; + } + } + test_run_counter++; + PyDateTime_IMPORT; + + if (PyDateTimeAPI) { + Py_RETURN_NONE; + } + return NULL; +} + +/* Functions exposing the C API type checking for testing */ +#define MAKE_DATETIME_CHECK_FUNC(check_method, exact_method) \ +do { \ + PyObject *obj; \ + int exact = 0; \ + if (!PyArg_ParseTuple(args, "O|p", &obj, &exact)) { \ + return NULL; \ + } \ + int rv = exact?exact_method(obj):check_method(obj); \ + if (rv) { \ + Py_RETURN_TRUE; \ + } \ + Py_RETURN_FALSE; \ +} while (0) \ + +static PyObject * +datetime_check_date(PyObject *self, PyObject *args) +{ + MAKE_DATETIME_CHECK_FUNC(PyDate_Check, PyDate_CheckExact); +} + +static PyObject * +datetime_check_time(PyObject *self, PyObject *args) +{ + MAKE_DATETIME_CHECK_FUNC(PyTime_Check, PyTime_CheckExact); +} + +static PyObject * +datetime_check_datetime(PyObject *self, PyObject *args) +{ + MAKE_DATETIME_CHECK_FUNC(PyDateTime_Check, PyDateTime_CheckExact); +} + +static PyObject * +datetime_check_delta(PyObject *self, PyObject *args) +{ + MAKE_DATETIME_CHECK_FUNC(PyDelta_Check, PyDelta_CheckExact); +} + +static PyObject * +datetime_check_tzinfo(PyObject *self, PyObject *args) +{ + MAKE_DATETIME_CHECK_FUNC(PyTZInfo_Check, PyTZInfo_CheckExact); +} +#undef MAKE_DATETIME_CHECK_FUNC + + +/* Makes three variations on timezone representing UTC-5: + 1. timezone with offset and name from PyDateTimeAPI + 2. timezone with offset and name from PyTimeZone_FromOffsetAndName + 3. timezone with offset (no name) from PyTimeZone_FromOffset +*/ +static PyObject * +make_timezones_capi(PyObject *self, PyObject *args) +{ + PyObject *offset = PyDelta_FromDSU(0, -18000, 0); + PyObject *name = PyUnicode_FromString("EST"); + + PyObject *est_zone_capi = PyDateTimeAPI->TimeZone_FromTimeZone(offset, name); + PyObject *est_zone_macro = PyTimeZone_FromOffsetAndName(offset, name); + PyObject *est_zone_macro_noname = PyTimeZone_FromOffset(offset); + + Py_DecRef(offset); + Py_DecRef(name); + + PyObject *rv = PyTuple_New(3); + if (rv == NULL) { + return NULL; + } + + PyTuple_SET_ITEM(rv, 0, est_zone_capi); + PyTuple_SET_ITEM(rv, 1, est_zone_macro); + PyTuple_SET_ITEM(rv, 2, est_zone_macro_noname); + + return rv; +} + +static PyObject * +get_timezones_offset_zero(PyObject *self, PyObject *args) +{ + PyObject *offset = PyDelta_FromDSU(0, 0, 0); + PyObject *name = PyUnicode_FromString(""); + + // These two should return the UTC singleton + PyObject *utc_singleton_0 = PyTimeZone_FromOffset(offset); + PyObject *utc_singleton_1 = PyTimeZone_FromOffsetAndName(offset, NULL); + + // This one will return +00:00 zone, but not the UTC singleton + PyObject *non_utc_zone = PyTimeZone_FromOffsetAndName(offset, name); + + Py_DecRef(offset); + Py_DecRef(name); + + PyObject *rv = PyTuple_New(3); + PyTuple_SET_ITEM(rv, 0, utc_singleton_0); + PyTuple_SET_ITEM(rv, 1, utc_singleton_1); + PyTuple_SET_ITEM(rv, 2, non_utc_zone); + + return rv; +} + +static PyObject * +get_timezone_utc_capi(PyObject *self, PyObject *args) +{ + int macro = 0; + if (!PyArg_ParseTuple(args, "|p", ¯o)) { + return NULL; + } + if (macro) { + return Py_NewRef(PyDateTime_TimeZone_UTC); + } + return Py_NewRef(PyDateTimeAPI->TimeZone_UTC); +} + +static PyObject * +get_date_fromdate(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int year, month, day; + + if (!PyArg_ParseTuple(args, "piii", ¯o, &year, &month, &day)) { + return NULL; + } + + if (macro) { + rv = PyDate_FromDate(year, month, day); + } + else { + rv = PyDateTimeAPI->Date_FromDate( + year, month, day, + PyDateTimeAPI->DateType); + } + return rv; +} + +static PyObject * +get_datetime_fromdateandtime(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int year, month, day; + int hour, minute, second, microsecond; + + if (!PyArg_ParseTuple(args, "piiiiiii", + ¯o, + &year, &month, &day, + &hour, &minute, &second, µsecond)) { + return NULL; + } + + if (macro) { + rv = PyDateTime_FromDateAndTime( + year, month, day, + hour, minute, second, microsecond); + } + else { + rv = PyDateTimeAPI->DateTime_FromDateAndTime( + year, month, day, + hour, minute, second, microsecond, + Py_None, + PyDateTimeAPI->DateTimeType); + } + return rv; +} + +static PyObject * +get_datetime_fromdateandtimeandfold(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int year, month, day; + int hour, minute, second, microsecond, fold; + + if (!PyArg_ParseTuple(args, "piiiiiiii", + ¯o, + &year, &month, &day, + &hour, &minute, &second, µsecond, + &fold)) { + return NULL; + } + + if (macro) { + rv = PyDateTime_FromDateAndTimeAndFold( + year, month, day, + hour, minute, second, microsecond, + fold); + } + else { + rv = PyDateTimeAPI->DateTime_FromDateAndTimeAndFold( + year, month, day, + hour, minute, second, microsecond, + Py_None, + fold, + PyDateTimeAPI->DateTimeType); + } + return rv; +} + +static PyObject * +get_time_fromtime(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int hour, minute, second, microsecond; + + if (!PyArg_ParseTuple(args, "piiii", + ¯o, + &hour, &minute, &second, µsecond)) + { + return NULL; + } + + if (macro) { + rv = PyTime_FromTime(hour, minute, second, microsecond); + } + else { + rv = PyDateTimeAPI->Time_FromTime( + hour, minute, second, microsecond, + Py_None, + PyDateTimeAPI->TimeType); + } + return rv; +} + +static PyObject * +get_time_fromtimeandfold(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int hour, minute, second, microsecond, fold; + + if (!PyArg_ParseTuple(args, "piiiii", + ¯o, + &hour, &minute, &second, µsecond, + &fold)) { + return NULL; + } + + if (macro) { + rv = PyTime_FromTimeAndFold(hour, minute, second, microsecond, fold); + } + else { + rv = PyDateTimeAPI->Time_FromTimeAndFold( + hour, minute, second, microsecond, + Py_None, + fold, + PyDateTimeAPI->TimeType); + } + return rv; +} + +static PyObject * +get_delta_fromdsu(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int days, seconds, microseconds; + + if (!PyArg_ParseTuple(args, "piii", + ¯o, + &days, &seconds, µseconds)) { + return NULL; + } + + if (macro) { + rv = PyDelta_FromDSU(days, seconds, microseconds); + } + else { + rv = PyDateTimeAPI->Delta_FromDelta( + days, seconds, microseconds, 1, + PyDateTimeAPI->DeltaType); + } + + return rv; +} + +static PyObject * +get_date_fromtimestamp(PyObject *self, PyObject *args) +{ + PyObject *tsargs = NULL, *ts = NULL, *rv = NULL; + int macro = 0; + + if (!PyArg_ParseTuple(args, "O|p", &ts, ¯o)) { + return NULL; + } + + // Construct the argument tuple + if ((tsargs = PyTuple_Pack(1, ts)) == NULL) { + return NULL; + } + + // Pass along to the API function + if (macro) { + rv = PyDate_FromTimestamp(tsargs); + } + else { + rv = PyDateTimeAPI->Date_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateType, tsargs + ); + } + + Py_DECREF(tsargs); + return rv; +} + +static PyObject * +get_datetime_fromtimestamp(PyObject *self, PyObject *args) +{ + int macro = 0; + int usetz = 0; + PyObject *tsargs = NULL, *ts = NULL, *tzinfo = Py_None, *rv = NULL; + if (!PyArg_ParseTuple(args, "OO|pp", &ts, &tzinfo, &usetz, ¯o)) { + return NULL; + } + + // Construct the argument tuple + if (usetz) { + tsargs = PyTuple_Pack(2, ts, tzinfo); + } + else { + tsargs = PyTuple_Pack(1, ts); + } + + if (tsargs == NULL) { + return NULL; + } + + // Pass along to the API function + if (macro) { + rv = PyDateTime_FromTimestamp(tsargs); + } + else { + rv = PyDateTimeAPI->DateTime_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, NULL + ); + } + + Py_DECREF(tsargs); + return rv; +} + +static PyObject * +test_PyDateTime_GET(PyObject *self, PyObject *obj) +{ + int year, month, day; + + year = PyDateTime_GET_YEAR(obj); + month = PyDateTime_GET_MONTH(obj); + day = PyDateTime_GET_DAY(obj); + + return Py_BuildValue("(iii)", year, month, day); +} + +static PyObject * +test_PyDateTime_DATE_GET(PyObject *self, PyObject *obj) +{ + int hour = PyDateTime_DATE_GET_HOUR(obj); + int minute = PyDateTime_DATE_GET_MINUTE(obj); + int second = PyDateTime_DATE_GET_SECOND(obj); + int microsecond = PyDateTime_DATE_GET_MICROSECOND(obj); + PyObject *tzinfo = PyDateTime_DATE_GET_TZINFO(obj); + + return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo); +} + +static PyObject * +test_PyDateTime_TIME_GET(PyObject *self, PyObject *obj) +{ + int hour = PyDateTime_TIME_GET_HOUR(obj); + int minute = PyDateTime_TIME_GET_MINUTE(obj); + int second = PyDateTime_TIME_GET_SECOND(obj); + int microsecond = PyDateTime_TIME_GET_MICROSECOND(obj); + PyObject *tzinfo = PyDateTime_TIME_GET_TZINFO(obj); + + return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo); +} + +static PyObject * +test_PyDateTime_DELTA_GET(PyObject *self, PyObject *obj) +{ + int days = PyDateTime_DELTA_GET_DAYS(obj); + int seconds = PyDateTime_DELTA_GET_SECONDS(obj); + int microseconds = PyDateTime_DELTA_GET_MICROSECONDS(obj); + + return Py_BuildValue("(iii)", days, seconds, microseconds); +} + +static PyMethodDef test_methods[] = { + {"PyDateTime_DATE_GET", test_PyDateTime_DATE_GET, METH_O}, + {"PyDateTime_DELTA_GET", test_PyDateTime_DELTA_GET, METH_O}, + {"PyDateTime_GET", test_PyDateTime_GET, METH_O}, + {"PyDateTime_TIME_GET", test_PyDateTime_TIME_GET, METH_O}, + {"datetime_check_date", datetime_check_date, METH_VARARGS}, + {"datetime_check_datetime", datetime_check_datetime, METH_VARARGS}, + {"datetime_check_delta", datetime_check_delta, METH_VARARGS}, + {"datetime_check_time", datetime_check_time, METH_VARARGS}, + {"datetime_check_tzinfo", datetime_check_tzinfo, METH_VARARGS}, + {"get_date_fromdate", get_date_fromdate, METH_VARARGS}, + {"get_date_fromtimestamp", get_date_fromtimestamp, METH_VARARGS}, + {"get_datetime_fromdateandtime", get_datetime_fromdateandtime, METH_VARARGS}, + {"get_datetime_fromdateandtimeandfold", get_datetime_fromdateandtimeandfold, METH_VARARGS}, + {"get_datetime_fromtimestamp", get_datetime_fromtimestamp, METH_VARARGS}, + {"get_delta_fromdsu", get_delta_fromdsu, METH_VARARGS}, + {"get_time_fromtime", get_time_fromtime, METH_VARARGS}, + {"get_time_fromtimeandfold", get_time_fromtimeandfold, METH_VARARGS}, + {"get_timezone_utc_capi", get_timezone_utc_capi, METH_VARARGS}, + {"get_timezones_offset_zero", get_timezones_offset_zero, METH_NOARGS}, + {"make_timezones_capi", make_timezones_capi, METH_NOARGS}, + {"test_datetime_capi", test_datetime_capi, METH_NOARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_DateTime(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + return 0; +} diff --git a/Modules/_testcapi/docstring.c b/Modules/_testcapi/docstring.c new file mode 100644 index 00000000000..a997c54a8a6 --- /dev/null +++ b/Modules/_testcapi/docstring.c @@ -0,0 +1,107 @@ +#include "parts.h" + + +PyDoc_STRVAR(docstring_empty, +"" +); + +PyDoc_STRVAR(docstring_no_signature, +"This docstring has no signature." +); + +PyDoc_STRVAR(docstring_with_invalid_signature, +"docstring_with_invalid_signature($module, /, boo)\n" +"\n" +"This docstring has an invalid signature." +); + +PyDoc_STRVAR(docstring_with_invalid_signature2, +"docstring_with_invalid_signature2($module, /, boo)\n" +"\n" +"--\n" +"\n" +"This docstring also has an invalid signature." +); + +PyDoc_STRVAR(docstring_with_signature, +"docstring_with_signature($module, /, sig)\n" +"--\n" +"\n" +"This docstring has a valid signature." +); + +PyDoc_STRVAR(docstring_with_signature_but_no_doc, +"docstring_with_signature_but_no_doc($module, /, sig)\n" +"--\n" +"\n" +); + +PyDoc_STRVAR(docstring_with_signature_and_extra_newlines, +"docstring_with_signature_and_extra_newlines($module, /, parameter)\n" +"--\n" +"\n" +"\n" +"This docstring has a valid signature and some extra newlines." +); + +PyDoc_STRVAR(docstring_with_signature_with_defaults, +"docstring_with_signature_with_defaults(module, s='avocado',\n" +" b=b'bytes', d=3.14, i=35, n=None, t=True, f=False,\n" +" local=the_number_three, sys=sys.maxsize,\n" +" exp=sys.maxsize - 1)\n" +"--\n" +"\n" +"\n" +"\n" +"This docstring has a valid signature with parameters,\n" +"and the parameters take defaults of varying types." +); + +/* This is here to provide a docstring for test_descr. */ +static PyObject * +test_with_docstring(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + Py_RETURN_NONE; +} + +static PyMethodDef test_methods[] = { + {"docstring_empty", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_empty}, + {"docstring_no_signature", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_no_signature}, + {"docstring_with_invalid_signature", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_with_invalid_signature}, + {"docstring_with_invalid_signature2", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_with_invalid_signature2}, + {"docstring_with_signature", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_with_signature}, + {"docstring_with_signature_and_extra_newlines", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_with_signature_and_extra_newlines}, + {"docstring_with_signature_but_no_doc", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_with_signature_but_no_doc}, + {"docstring_with_signature_with_defaults", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_with_signature_with_defaults}, + {"no_docstring", + (PyCFunction)test_with_docstring, METH_NOARGS}, + {"test_with_docstring", + test_with_docstring, METH_NOARGS, + PyDoc_STR("This is a pretty normal docstring.")}, + {NULL}, +}; + +int +_PyTestCapi_Init_Docstring(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + return 0; +} diff --git a/Modules/_testcapi/float.c b/Modules/_testcapi/float.c new file mode 100644 index 00000000000..26d99d990e0 --- /dev/null +++ b/Modules/_testcapi/float.c @@ -0,0 +1,98 @@ +#define PY_SSIZE_T_CLEAN + +#include "parts.h" + + +// Test PyFloat_Pack2(), PyFloat_Pack4() and PyFloat_Pack8() +static PyObject * +test_float_pack(PyObject *self, PyObject *args) +{ + int size; + double d; + int le; + if (!PyArg_ParseTuple(args, "idi", &size, &d, &le)) { + return NULL; + } + switch (size) + { + case 2: + { + char data[2]; + if (PyFloat_Pack2(d, data, le) < 0) { + return NULL; + } + return PyBytes_FromStringAndSize(data, Py_ARRAY_LENGTH(data)); + } + case 4: + { + char data[4]; + if (PyFloat_Pack4(d, data, le) < 0) { + return NULL; + } + return PyBytes_FromStringAndSize(data, Py_ARRAY_LENGTH(data)); + } + case 8: + { + char data[8]; + if (PyFloat_Pack8(d, data, le) < 0) { + return NULL; + } + return PyBytes_FromStringAndSize(data, Py_ARRAY_LENGTH(data)); + } + default: break; + } + + PyErr_SetString(PyExc_ValueError, "size must 2, 4 or 8"); + return NULL; +} + + +// Test PyFloat_Unpack2(), PyFloat_Unpack4() and PyFloat_Unpack8() +static PyObject * +test_float_unpack(PyObject *self, PyObject *args) +{ + assert(!PyErr_Occurred()); + const char *data; + Py_ssize_t size; + int le; + if (!PyArg_ParseTuple(args, "y#i", &data, &size, &le)) { + return NULL; + } + double d; + switch (size) + { + case 2: + d = PyFloat_Unpack2(data, le); + break; + case 4: + d = PyFloat_Unpack4(data, le); + break; + case 8: + d = PyFloat_Unpack8(data, le); + break; + default: + PyErr_SetString(PyExc_ValueError, "data length must 2, 4 or 8 bytes"); + return NULL; + } + + if (d == -1.0 && PyErr_Occurred()) { + return NULL; + } + return PyFloat_FromDouble(d); +} + +static PyMethodDef test_methods[] = { + {"float_pack", test_float_pack, METH_VARARGS, NULL}, + {"float_unpack", test_float_unpack, METH_VARARGS, NULL}, + {NULL}, +}; + +int +_PyTestCapi_Init_Float(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/getargs.c b/Modules/_testcapi/getargs.c new file mode 100644 index 00000000000..aa201319950 --- /dev/null +++ b/Modules/_testcapi/getargs.c @@ -0,0 +1,939 @@ +/* + * Tests for Python/getargs.c and Python/modsupport.c; + * APIs that parse and build arguments. + */ + +#define PY_SSIZE_T_CLEAN + +#include "parts.h" + +static PyObject * +parse_tuple_and_keywords(PyObject *self, PyObject *args) +{ + PyObject *sub_args; + PyObject *sub_kwargs; + const char *sub_format; + PyObject *sub_keywords; + + double buffers[8][4]; /* double ensures alignment where necessary */ + PyObject *converted[8]; + char *keywords[8 + 1]; /* space for NULL at end */ + + PyObject *return_value = NULL; + + if (!PyArg_ParseTuple(args, "OOsO:parse_tuple_and_keywords", + &sub_args, &sub_kwargs, &sub_format, &sub_keywords)) + { + return NULL; + } + + if (!(PyList_CheckExact(sub_keywords) || + PyTuple_CheckExact(sub_keywords))) + { + PyErr_SetString(PyExc_ValueError, + "parse_tuple_and_keywords: " + "sub_keywords must be either list or tuple"); + return NULL; + } + + memset(buffers, 0, sizeof(buffers)); + memset(converted, 0, sizeof(converted)); + memset(keywords, 0, sizeof(keywords)); + + Py_ssize_t size = PySequence_Fast_GET_SIZE(sub_keywords); + if (size > 8) { + PyErr_SetString(PyExc_ValueError, + "parse_tuple_and_keywords: too many keywords in sub_keywords"); + goto exit; + } + + for (Py_ssize_t i = 0; i < size; i++) { + PyObject *o = PySequence_Fast_GET_ITEM(sub_keywords, i); + if (!PyUnicode_FSConverter(o, (void *)(converted + i))) { + PyErr_Format(PyExc_ValueError, + "parse_tuple_and_keywords: " + "could not convert keywords[%zd] to narrow string", i); + goto exit; + } + keywords[i] = PyBytes_AS_STRING(converted[i]); + } + + int result = PyArg_ParseTupleAndKeywords(sub_args, sub_kwargs, + sub_format, keywords, + buffers + 0, buffers + 1, buffers + 2, buffers + 3, + buffers + 4, buffers + 5, buffers + 6, buffers + 7); + + if (result) { + return_value = Py_NewRef(Py_None); + } + +exit: + size = sizeof(converted) / sizeof(converted[0]); + for (Py_ssize_t i = 0; i < size; i++) { + Py_XDECREF(converted[i]); + } + return return_value; +} + +static PyObject * +get_args(PyObject *self, PyObject *args) +{ + if (args == NULL) { + args = Py_None; + } + return Py_NewRef(args); +} + +static PyObject * +get_kwargs(PyObject *self, PyObject *args, PyObject *kwargs) +{ + if (kwargs == NULL) { + kwargs = Py_None; + } + return Py_NewRef(kwargs); +} + +static PyObject * +getargs_w_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + + if (!PyArg_ParseTuple(args, "w*:getargs_w_star", &buffer)) { + return NULL; + } + + if (2 <= buffer.len) { + char *str = buffer.buf; + str[0] = '['; + str[buffer.len-1] = ']'; + } + + PyObject *result = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + PyBuffer_Release(&buffer); + return result; +} + +static PyObject * +test_empty_argparse(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + /* Test that formats can begin with '|'. See issue #4720. */ + PyObject *dict = NULL; + static char *kwlist[] = {NULL}; + PyObject *tuple = PyTuple_New(0); + if (!tuple) { + return NULL; + } + int result; + if (!(result = PyArg_ParseTuple(tuple, "|:test_empty_argparse"))) { + goto done; + } + dict = PyDict_New(); + if (!dict) { + goto done; + } + result = PyArg_ParseTupleAndKeywords(tuple, dict, "|:test_empty_argparse", + kwlist); + done: + Py_DECREF(tuple); + Py_XDECREF(dict); + if (!result) { + return NULL; + } + Py_RETURN_NONE; +} + +/* Test tuple argument processing */ +static PyObject * +getargs_tuple(PyObject *self, PyObject *args) +{ + int a, b, c; + if (!PyArg_ParseTuple(args, "i(ii)", &a, &b, &c)) { + return NULL; + } + return Py_BuildValue("iii", a, b, c); +} + +/* test PyArg_ParseTupleAndKeywords */ +static PyObject * +getargs_keywords(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[] = {"arg1","arg2","arg3","arg4","arg5", NULL}; + static const char fmt[] = "(ii)i|(i(ii))(iii)i"; + int int_args[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords, + &int_args[0], &int_args[1], &int_args[2], &int_args[3], &int_args[4], + &int_args[5], &int_args[6], &int_args[7], &int_args[8], &int_args[9])) + { + return NULL; + } + return Py_BuildValue("iiiiiiiiii", + int_args[0], int_args[1], int_args[2], int_args[3], int_args[4], + int_args[5], int_args[6], int_args[7], int_args[8], int_args[9]); +} + +/* test PyArg_ParseTupleAndKeywords keyword-only arguments */ +static PyObject * +getargs_keyword_only(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[] = {"required", "optional", "keyword_only", NULL}; + int required = -1; + int optional = -1; + int keyword_only = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i$i", keywords, + &required, &optional, &keyword_only)) + { + return NULL; + } + return Py_BuildValue("iii", required, optional, keyword_only); +} + +/* test PyArg_ParseTupleAndKeywords positional-only arguments */ +static PyObject * +getargs_positional_only_and_keywords(PyObject *self, PyObject *args, + PyObject *kwargs) +{ + static char *keywords[] = {"", "", "keyword", NULL}; + int required = -1; + int optional = -1; + int keyword = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii", keywords, + &required, &optional, &keyword)) + { + return NULL; + } + return Py_BuildValue("iii", required, optional, keyword); +} + +/* Functions to call PyArg_ParseTuple with integer format codes, + and return the result. +*/ +static PyObject * +getargs_b(PyObject *self, PyObject *args) +{ + unsigned char value; + if (!PyArg_ParseTuple(args, "b", &value)) { + return NULL; + } + return PyLong_FromUnsignedLong((unsigned long)value); +} + +static PyObject * +getargs_B(PyObject *self, PyObject *args) +{ + unsigned char value; + if (!PyArg_ParseTuple(args, "B", &value)) { + return NULL; + } + return PyLong_FromUnsignedLong((unsigned long)value); +} + +static PyObject * +getargs_h(PyObject *self, PyObject *args) +{ + short value; + if (!PyArg_ParseTuple(args, "h", &value)) { + return NULL; + } + return PyLong_FromLong((long)value); +} + +static PyObject * +getargs_H(PyObject *self, PyObject *args) +{ + unsigned short value; + if (!PyArg_ParseTuple(args, "H", &value)) { + return NULL; + } + return PyLong_FromUnsignedLong((unsigned long)value); +} + +static PyObject * +getargs_I(PyObject *self, PyObject *args) +{ + unsigned int value; + if (!PyArg_ParseTuple(args, "I", &value)) { + return NULL; + } + return PyLong_FromUnsignedLong((unsigned long)value); +} + +static PyObject * +getargs_k(PyObject *self, PyObject *args) +{ + unsigned long value; + if (!PyArg_ParseTuple(args, "k", &value)) { + return NULL; + } + return PyLong_FromUnsignedLong(value); +} + +static PyObject * +getargs_i(PyObject *self, PyObject *args) +{ + int value; + if (!PyArg_ParseTuple(args, "i", &value)) { + return NULL; + } + return PyLong_FromLong((long)value); +} + +static PyObject * +getargs_l(PyObject *self, PyObject *args) +{ + long value; + if (!PyArg_ParseTuple(args, "l", &value)) { + return NULL; + } + return PyLong_FromLong(value); +} + +static PyObject * +getargs_n(PyObject *self, PyObject *args) +{ + Py_ssize_t value; + if (!PyArg_ParseTuple(args, "n", &value)) { + return NULL; + } + return PyLong_FromSsize_t(value); +} + +static PyObject * +getargs_p(PyObject *self, PyObject *args) +{ + int value; + if (!PyArg_ParseTuple(args, "p", &value)) { + return NULL; + } + return PyLong_FromLong(value); +} + +static PyObject * +getargs_L(PyObject *self, PyObject *args) +{ + long long value; + if (!PyArg_ParseTuple(args, "L", &value)) { + return NULL; + } + return PyLong_FromLongLong(value); +} + +static PyObject * +getargs_K(PyObject *self, PyObject *args) +{ + unsigned long long value; + if (!PyArg_ParseTuple(args, "K", &value)) { + return NULL; + } + return PyLong_FromUnsignedLongLong(value); +} + +/* This function not only tests the 'k' getargs code, but also the + PyLong_AsUnsignedLongMask() function. */ +static PyObject * +test_k_code(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *tuple, *num; + unsigned long value; + + tuple = PyTuple_New(1); + if (tuple == NULL) { + return NULL; + } + + /* a number larger than ULONG_MAX even on 64-bit platforms */ + num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) { + return NULL; + } + + value = PyLong_AsUnsignedLongMask(num); + if (value != ULONG_MAX) { + PyErr_SetString(PyExc_AssertionError, + "test_k_code: " + "PyLong_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF"); + return NULL; + } + + PyTuple_SET_ITEM(tuple, 0, num); + + value = 0; + if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) { + return NULL; + } + if (value != ULONG_MAX) { + PyErr_SetString(PyExc_AssertionError, + "test_k_code: k code returned wrong value for long 0xFFF...FFF"); + return NULL; + } + + Py_DECREF(num); + num = PyLong_FromString("-FFFFFFFF000000000000000042", NULL, 16); + if (num == NULL) { + return NULL; + } + + value = PyLong_AsUnsignedLongMask(num); + if (value != (unsigned long)-0x42) { + PyErr_SetString(PyExc_AssertionError, + "test_k_code: " + "PyLong_AsUnsignedLongMask() returned wrong value for long -0xFFF..000042"); + return NULL; + } + + PyTuple_SET_ITEM(tuple, 0, num); + + value = 0; + if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) { + return NULL; + } + if (value != (unsigned long)-0x42) { + PyErr_SetString(PyExc_AssertionError, + "test_k_code: k code returned wrong value for long -0xFFF..000042"); + return NULL; + } + + Py_DECREF(tuple); + Py_RETURN_NONE; +} + +static PyObject * +getargs_f(PyObject *self, PyObject *args) +{ + float f; + if (!PyArg_ParseTuple(args, "f", &f)) { + return NULL; + } + return PyFloat_FromDouble(f); +} + +static PyObject * +getargs_d(PyObject *self, PyObject *args) +{ + double d; + if (!PyArg_ParseTuple(args, "d", &d)) { + return NULL; + } + return PyFloat_FromDouble(d); +} + +static PyObject * +getargs_D(PyObject *self, PyObject *args) +{ + Py_complex cval; + if (!PyArg_ParseTuple(args, "D", &cval)) { + return NULL; + } + return PyComplex_FromCComplex(cval); +} + +static PyObject * +getargs_S(PyObject *self, PyObject *args) +{ + PyObject *obj; + if (!PyArg_ParseTuple(args, "S", &obj)) { + return NULL; + } + return Py_NewRef(obj); +} + +static PyObject * +getargs_Y(PyObject *self, PyObject *args) +{ + PyObject *obj; + if (!PyArg_ParseTuple(args, "Y", &obj)) { + return NULL; + } + return Py_NewRef(obj); +} + +static PyObject * +getargs_U(PyObject *self, PyObject *args) +{ + PyObject *obj; + if (!PyArg_ParseTuple(args, "U", &obj)) { + return NULL; + } + return Py_NewRef(obj); +} + +static PyObject * +getargs_c(PyObject *self, PyObject *args) +{ + char c; + if (!PyArg_ParseTuple(args, "c", &c)) { + return NULL; + } + return PyLong_FromLong((unsigned char)c); +} + +static PyObject * +getargs_C(PyObject *self, PyObject *args) +{ + int c; + if (!PyArg_ParseTuple(args, "C", &c)) { + return NULL; + } + return PyLong_FromLong(c); +} + +static PyObject * +getargs_s(PyObject *self, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "s", &str)) { + return NULL; + } + return PyBytes_FromString(str); +} + +static PyObject * +getargs_s_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + PyObject *bytes; + if (!PyArg_ParseTuple(args, "s*", &buffer)) { + return NULL; + } + bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + PyBuffer_Release(&buffer); + return bytes; +} + +static PyObject * +getargs_s_hash(PyObject *self, PyObject *args) +{ + char *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "s#", &str, &size)) { + return NULL; + } + return PyBytes_FromStringAndSize(str, size); +} + +static PyObject * +getargs_z(PyObject *self, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "z", &str)) { + return NULL; + } + if (str != NULL) { + return PyBytes_FromString(str); + } + Py_RETURN_NONE; +} + +static PyObject * +getargs_z_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + PyObject *bytes; + if (!PyArg_ParseTuple(args, "z*", &buffer)) { + return NULL; + } + if (buffer.buf != NULL) { + bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + } + else { + bytes = Py_NewRef(Py_None); + } + PyBuffer_Release(&buffer); + return bytes; +} + +static PyObject * +getargs_z_hash(PyObject *self, PyObject *args) +{ + char *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "z#", &str, &size)) { + return NULL; + } + if (str != NULL) { + return PyBytes_FromStringAndSize(str, size); + } + Py_RETURN_NONE; +} + +static PyObject * +getargs_y(PyObject *self, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "y", &str)) { + return NULL; + } + return PyBytes_FromString(str); +} + +static PyObject * +getargs_y_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + if (!PyArg_ParseTuple(args, "y*", &buffer)) { + return NULL; + } + PyObject *bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + PyBuffer_Release(&buffer); + return bytes; +} + +static PyObject * +getargs_y_hash(PyObject *self, PyObject *args) +{ + char *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "y#", &str, &size)) { + return NULL; + } + return PyBytes_FromStringAndSize(str, size); +} + +static PyObject * +getargs_u(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + if (!PyArg_ParseTuple(args, "u", &str)) { + return NULL; + } + return PyUnicode_FromWideChar(str, -1); +} + +static PyObject * +getargs_u_hash(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "u#", &str, &size)) { + return NULL; + } + return PyUnicode_FromWideChar(str, size); +} + +static PyObject * +getargs_Z(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + if (!PyArg_ParseTuple(args, "Z", &str)) { + return NULL; + } + if (str != NULL) { + return PyUnicode_FromWideChar(str, -1); + } + Py_RETURN_NONE; +} + +static PyObject * +getargs_Z_hash(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Z#", &str, &size)) { + return NULL; + } + if (str != NULL) { + return PyUnicode_FromWideChar(str, size); + } + Py_RETURN_NONE; +} + +static PyObject * +getargs_es(PyObject *self, PyObject *args) +{ + PyObject *arg; + const char *encoding = NULL; + char *str; + + if (!PyArg_ParseTuple(args, "O|s", &arg, &encoding)) { + return NULL; + } + if (!PyArg_Parse(arg, "es", encoding, &str)) { + return NULL; + } + PyObject *result = PyBytes_FromString(str); + PyMem_Free(str); + return result; +} + +static PyObject * +getargs_et(PyObject *self, PyObject *args) +{ + PyObject *arg; + const char *encoding = NULL; + char *str; + + if (!PyArg_ParseTuple(args, "O|s", &arg, &encoding)) { + return NULL; + } + if (!PyArg_Parse(arg, "et", encoding, &str)) { + return NULL; + } + PyObject *result = PyBytes_FromString(str); + PyMem_Free(str); + return result; +} + +static PyObject * +getargs_es_hash(PyObject *self, PyObject *args) +{ + PyObject *arg; + const char *encoding = NULL; + PyByteArrayObject *buffer = NULL; + char *str = NULL; + Py_ssize_t size; + + if (!PyArg_ParseTuple(args, "O|sY", &arg, &encoding, &buffer)) { + return NULL; + } + if (buffer != NULL) { + str = PyByteArray_AS_STRING(buffer); + size = PyByteArray_GET_SIZE(buffer); + } + if (!PyArg_Parse(arg, "es#", encoding, &str, &size)) { + return NULL; + } + PyObject *result = PyBytes_FromStringAndSize(str, size); + if (buffer == NULL) { + PyMem_Free(str); + } + return result; +} + +static PyObject * +getargs_et_hash(PyObject *self, PyObject *args) +{ + PyObject *arg; + const char *encoding = NULL; + PyByteArrayObject *buffer = NULL; + char *str = NULL; + Py_ssize_t size; + + if (!PyArg_ParseTuple(args, "O|sY", &arg, &encoding, &buffer)) { + return NULL; + } + if (buffer != NULL) { + str = PyByteArray_AS_STRING(buffer); + size = PyByteArray_GET_SIZE(buffer); + } + if (!PyArg_Parse(arg, "et#", encoding, &str, &size)) { + return NULL; + } + PyObject *result = PyBytes_FromStringAndSize(str, size); + if (buffer == NULL) { + PyMem_Free(str); + } + return result; +} + +/* Test the L code for PyArg_ParseTuple. This should deliver a long long + for both long and int arguments. The test may leak a little memory if + it fails. +*/ +static PyObject * +test_L_code(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *tuple, *num; + long long value; + + tuple = PyTuple_New(1); + if (tuple == NULL) { + return NULL; + } + + num = PyLong_FromLong(42); + if (num == NULL) { + return NULL; + } + + PyTuple_SET_ITEM(tuple, 0, num); + + value = -1; + if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) { + return NULL; + } + if (value != 42) { + PyErr_SetString(PyExc_AssertionError, + "test_L_code: L code returned wrong value for long 42"); + return NULL; + } + + Py_DECREF(num); + num = PyLong_FromLong(42); + if (num == NULL) { + return NULL; + } + + PyTuple_SET_ITEM(tuple, 0, num); + + value = -1; + if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) { + return NULL; + } + if (value != 42) { + PyErr_SetString(PyExc_AssertionError, + "test_L_code: L code returned wrong value for int 42"); + return NULL; + } + + Py_DECREF(tuple); + Py_RETURN_NONE; +} + +/* Test the s and z codes for PyArg_ParseTuple. +*/ +static PyObject * +test_s_code(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + /* Unicode strings should be accepted */ + PyObject *tuple = PyTuple_New(1); + if (tuple == NULL) { + return NULL; + } + + PyObject *obj = PyUnicode_Decode("t\xeate", strlen("t\xeate"), + "latin-1", NULL); + if (obj == NULL) { + return NULL; + } + + PyTuple_SET_ITEM(tuple, 0, obj); + + /* These two blocks used to raise a TypeError: + * "argument must be string without null bytes, not str" + */ + char *value; + if (!PyArg_ParseTuple(tuple, "s:test_s_code1", &value)) { + return NULL; + } + + if (!PyArg_ParseTuple(tuple, "z:test_s_code2", &value)) { + return NULL; + } + + Py_DECREF(tuple); + Py_RETURN_NONE; +} + +#undef PyArg_ParseTupleAndKeywords +PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, + const char *, char **, ...); + +static PyObject * +getargs_s_hash_int(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[] = {"", "", "x", NULL}; + Py_buffer buf = {NULL}; + const char *s; + int len; + int i = 0; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "w*|s#i", keywords, + &buf, &s, &len, &i)) + { + return NULL; + } + PyBuffer_Release(&buf); + Py_RETURN_NONE; +} + +static PyObject * +getargs_s_hash_int2(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[] = {"", "", "x", NULL}; + Py_buffer buf = {NULL}; + const char *s; + int len; + int i = 0; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "w*|(s#)i", keywords, + &buf, &s, &len, &i)) + { + return NULL; + } + PyBuffer_Release(&buf); + Py_RETURN_NONE; +} + +static PyObject * +gh_99240_clear_args(PyObject *self, PyObject *args) +{ + char *a = NULL; + char *b = NULL; + + if (!PyArg_ParseTuple(args, "eses", "idna", &a, "idna", &b)) { + if (a || b) { + PyErr_Clear(); + PyErr_SetString(PyExc_AssertionError, "Arguments are not cleared."); + } + return NULL; + } + PyMem_Free(a); + PyMem_Free(b); + Py_RETURN_NONE; +} + +static PyMethodDef test_methods[] = { + {"get_args", get_args, METH_VARARGS}, + {"get_kwargs", _PyCFunction_CAST(get_kwargs), METH_VARARGS|METH_KEYWORDS}, + {"getargs_B", getargs_B, METH_VARARGS}, + {"getargs_C", getargs_C, METH_VARARGS}, + {"getargs_D", getargs_D, METH_VARARGS}, + {"getargs_H", getargs_H, METH_VARARGS}, + {"getargs_I", getargs_I, METH_VARARGS}, + {"getargs_K", getargs_K, METH_VARARGS}, + {"getargs_L", getargs_L, METH_VARARGS}, + {"getargs_S", getargs_S, METH_VARARGS}, + {"getargs_U", getargs_U, METH_VARARGS}, + {"getargs_Y", getargs_Y, METH_VARARGS}, + {"getargs_Z", getargs_Z, METH_VARARGS}, + {"getargs_Z_hash", getargs_Z_hash, METH_VARARGS}, + {"getargs_b", getargs_b, METH_VARARGS}, + {"getargs_c", getargs_c, METH_VARARGS}, + {"getargs_d", getargs_d, METH_VARARGS}, + {"getargs_es", getargs_es, METH_VARARGS}, + {"getargs_es_hash", getargs_es_hash, METH_VARARGS}, + {"getargs_et", getargs_et, METH_VARARGS}, + {"getargs_et_hash", getargs_et_hash, METH_VARARGS}, + {"getargs_f", getargs_f, METH_VARARGS}, + {"getargs_h", getargs_h, METH_VARARGS}, + {"getargs_i", getargs_i, METH_VARARGS}, + {"getargs_k", getargs_k, METH_VARARGS}, + {"getargs_keyword_only", _PyCFunction_CAST(getargs_keyword_only), METH_VARARGS|METH_KEYWORDS}, + {"getargs_keywords", _PyCFunction_CAST(getargs_keywords), METH_VARARGS|METH_KEYWORDS}, + {"getargs_l", getargs_l, METH_VARARGS}, + {"getargs_n", getargs_n, METH_VARARGS}, + {"getargs_p", getargs_p, METH_VARARGS}, + {"getargs_positional_only_and_keywords", _PyCFunction_CAST(getargs_positional_only_and_keywords), METH_VARARGS|METH_KEYWORDS}, + {"getargs_s", getargs_s, METH_VARARGS}, + {"getargs_s_hash", getargs_s_hash, METH_VARARGS}, + {"getargs_s_hash_int", _PyCFunction_CAST(getargs_s_hash_int), METH_VARARGS|METH_KEYWORDS}, + {"getargs_s_hash_int2", _PyCFunction_CAST(getargs_s_hash_int2), METH_VARARGS|METH_KEYWORDS}, + {"getargs_s_star", getargs_s_star, METH_VARARGS}, + {"getargs_tuple", getargs_tuple, METH_VARARGS}, + {"getargs_u", getargs_u, METH_VARARGS}, + {"getargs_u_hash", getargs_u_hash, METH_VARARGS}, + {"getargs_w_star", getargs_w_star, METH_VARARGS}, + {"getargs_y", getargs_y, METH_VARARGS}, + {"getargs_y_hash", getargs_y_hash, METH_VARARGS}, + {"getargs_y_star", getargs_y_star, METH_VARARGS}, + {"getargs_z", getargs_z, METH_VARARGS}, + {"getargs_z_hash", getargs_z_hash, METH_VARARGS}, + {"getargs_z_star", getargs_z_star, METH_VARARGS}, + {"parse_tuple_and_keywords", parse_tuple_and_keywords, METH_VARARGS}, + {"test_L_code", test_L_code, METH_NOARGS}, + {"test_empty_argparse", test_empty_argparse, METH_NOARGS}, + {"test_k_code", test_k_code, METH_NOARGS}, + {"test_s_code", test_s_code, METH_NOARGS}, + {"gh_99240_clear_args", gh_99240_clear_args, METH_VARARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_GetArgs(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/heaptype.c b/Modules/_testcapi/heaptype.c new file mode 100644 index 00000000000..bf80fd64d80 --- /dev/null +++ b/Modules/_testcapi/heaptype.c @@ -0,0 +1,1095 @@ +#include "parts.h" +#include "structmember.h" // PyMemberDef + +static struct PyModuleDef *_testcapimodule = NULL; // set at initialization + +/* Tests for heap types (PyType_From*) */ + +static PyObject *pytype_fromspec_meta(PyObject* self, PyObject *meta) +{ + if (!PyType_Check(meta)) { + PyErr_SetString( + PyExc_TypeError, + "pytype_fromspec_meta: must be invoked with a type argument!"); + return NULL; + } + + PyType_Slot HeapCTypeViaMetaclass_slots[] = { + {0}, + }; + + PyType_Spec HeapCTypeViaMetaclass_spec = { + "_testcapi.HeapCTypeViaMetaclass", + sizeof(PyObject), + 0, + Py_TPFLAGS_DEFAULT, + HeapCTypeViaMetaclass_slots + }; + + return PyType_FromMetaclass( + (PyTypeObject *) meta, NULL, &HeapCTypeViaMetaclass_spec, NULL); +} + + +static PyType_Slot empty_type_slots[] = { + {0, 0}, +}; + +static PyType_Spec MinimalMetaclass_spec = { + .name = "_testcapi.MinimalMetaclass", + .basicsize = sizeof(PyHeapTypeObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .slots = empty_type_slots, +}; + +static PyType_Spec MinimalType_spec = { + .name = "_testcapi.MinimalSpecType", + .basicsize = 0, // Updated later + .flags = Py_TPFLAGS_DEFAULT, + .slots = empty_type_slots, +}; + + +static PyObject * +test_from_spec_metatype_inheritance(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *metaclass = NULL; + PyObject *class = NULL; + PyObject *new = NULL; + PyObject *subclasses = NULL; + PyObject *result = NULL; + int r; + + metaclass = PyType_FromSpecWithBases(&MinimalMetaclass_spec, (PyObject*)&PyType_Type); + if (metaclass == NULL) { + goto finally; + } + class = PyObject_CallFunction(metaclass, "s(){}", "TestClass"); + if (class == NULL) { + goto finally; + } + + MinimalType_spec.basicsize = (int)(((PyTypeObject*)class)->tp_basicsize); + new = PyType_FromSpecWithBases(&MinimalType_spec, class); + if (new == NULL) { + goto finally; + } + if (Py_TYPE(new) != (PyTypeObject*)metaclass) { + PyErr_SetString(PyExc_AssertionError, + "Metaclass not set properly!"); + goto finally; + } + + /* Assert that __subclasses__ is updated */ + subclasses = PyObject_CallMethod(class, "__subclasses__", ""); + if (!subclasses) { + goto finally; + } + r = PySequence_Contains(subclasses, new); + if (r < 0) { + goto finally; + } + if (r == 0) { + PyErr_SetString(PyExc_AssertionError, + "subclasses not set properly!"); + goto finally; + } + + result = Py_NewRef(Py_None); + +finally: + Py_XDECREF(metaclass); + Py_XDECREF(class); + Py_XDECREF(new); + Py_XDECREF(subclasses); + return result; +} + + +static PyObject * +test_from_spec_invalid_metatype_inheritance(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *metaclass_a = NULL; + PyObject *metaclass_b = NULL; + PyObject *class_a = NULL; + PyObject *class_b = NULL; + PyObject *bases = NULL; + PyObject *new = NULL; + PyObject *meta_error_string = NULL; + PyObject *exc_type = NULL; + PyObject *exc_value = NULL; + PyObject *exc_traceback = NULL; + PyObject *result = NULL; + + metaclass_a = PyType_FromSpecWithBases(&MinimalMetaclass_spec, (PyObject*)&PyType_Type); + if (metaclass_a == NULL) { + goto finally; + } + metaclass_b = PyType_FromSpecWithBases(&MinimalMetaclass_spec, (PyObject*)&PyType_Type); + if (metaclass_b == NULL) { + goto finally; + } + class_a = PyObject_CallFunction(metaclass_a, "s(){}", "TestClassA"); + if (class_a == NULL) { + goto finally; + } + + class_b = PyObject_CallFunction(metaclass_b, "s(){}", "TestClassB"); + if (class_b == NULL) { + goto finally; + } + + bases = PyTuple_Pack(2, class_a, class_b); + if (bases == NULL) { + goto finally; + } + + /* + * The following should raise a TypeError due to a MetaClass conflict. + */ + new = PyType_FromSpecWithBases(&MinimalType_spec, bases); + if (new != NULL) { + PyErr_SetString(PyExc_AssertionError, + "MetaType conflict not recognized by PyType_FromSpecWithBases"); + goto finally; + } + + // Assert that the correct exception was raised + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); + + meta_error_string = PyUnicode_FromString("metaclass conflict:"); + if (meta_error_string == NULL) { + goto finally; + } + int res = PyUnicode_Contains(exc_value, meta_error_string); + if (res < 0) { + goto finally; + } + if (res == 0) { + PyErr_SetString(PyExc_AssertionError, + "TypeError did not inlclude expected message."); + goto finally; + } + result = Py_NewRef(Py_None); + } +finally: + Py_XDECREF(metaclass_a); + Py_XDECREF(metaclass_b); + Py_XDECREF(bases); + Py_XDECREF(new); + Py_XDECREF(meta_error_string); + Py_XDECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_traceback); + Py_XDECREF(class_a); + Py_XDECREF(class_b); + return result; +} + + +static PyObject * +simple_str(PyObject *self) { + return PyUnicode_FromString(""); +} + + +static PyObject * +test_type_from_ephemeral_spec(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + // Test that a heap type can be created from a spec that's later deleted + // (along with all its contents). + // All necessary data must be copied and held by the class + PyType_Spec *spec = NULL; + char *name = NULL; + char *doc = NULL; + PyType_Slot *slots = NULL; + PyObject *class = NULL; + PyObject *instance = NULL; + PyObject *obj = NULL; + PyObject *result = NULL; + + /* create a spec (and all its contents) on the heap */ + + const char NAME[] = "testcapi._Test"; + const char DOC[] = "a test class"; + + spec = PyMem_New(PyType_Spec, 1); + if (spec == NULL) { + PyErr_NoMemory(); + goto finally; + } + name = PyMem_New(char, sizeof(NAME)); + if (name == NULL) { + PyErr_NoMemory(); + goto finally; + } + memcpy(name, NAME, sizeof(NAME)); + + doc = PyMem_New(char, sizeof(DOC)); + if (doc == NULL) { + PyErr_NoMemory(); + goto finally; + } + memcpy(doc, DOC, sizeof(DOC)); + + spec->name = name; + spec->basicsize = sizeof(PyObject); + spec->itemsize = 0; + spec->flags = Py_TPFLAGS_DEFAULT; + slots = PyMem_New(PyType_Slot, 3); + if (slots == NULL) { + PyErr_NoMemory(); + goto finally; + } + slots[0].slot = Py_tp_str; + slots[0].pfunc = simple_str; + slots[1].slot = Py_tp_doc; + slots[1].pfunc = doc; + slots[2].slot = 0; + slots[2].pfunc = NULL; + spec->slots = slots; + + /* create the class */ + + class = PyType_FromSpec(spec); + if (class == NULL) { + goto finally; + } + + /* deallocate the spec (and all contents) */ + + // (Explicitly ovewrite memory before freeing, + // so bugs show themselves even without the debug allocator's help.) + memset(spec, 0xdd, sizeof(PyType_Spec)); + PyMem_Del(spec); + spec = NULL; + memset(name, 0xdd, sizeof(NAME)); + PyMem_Del(name); + name = NULL; + memset(doc, 0xdd, sizeof(DOC)); + PyMem_Del(doc); + doc = NULL; + memset(slots, 0xdd, 3 * sizeof(PyType_Slot)); + PyMem_Del(slots); + slots = NULL; + + /* check that everything works */ + + PyTypeObject *class_tp = (PyTypeObject *)class; + PyHeapTypeObject *class_ht = (PyHeapTypeObject *)class; + assert(strcmp(class_tp->tp_name, "testcapi._Test") == 0); + assert(strcmp(PyUnicode_AsUTF8(class_ht->ht_name), "_Test") == 0); + assert(strcmp(PyUnicode_AsUTF8(class_ht->ht_qualname), "_Test") == 0); + assert(strcmp(class_tp->tp_doc, "a test class") == 0); + + // call and check __str__ + instance = PyObject_CallNoArgs(class); + if (instance == NULL) { + goto finally; + } + obj = PyObject_Str(instance); + if (obj == NULL) { + goto finally; + } + assert(strcmp(PyUnicode_AsUTF8(obj), "") == 0); + Py_CLEAR(obj); + + result = Py_NewRef(Py_None); + finally: + PyMem_Del(spec); + PyMem_Del(name); + PyMem_Del(doc); + PyMem_Del(slots); + Py_XDECREF(class); + Py_XDECREF(instance); + Py_XDECREF(obj); + return result; +} + +PyType_Slot repeated_doc_slots[] = { + {Py_tp_doc, "A class used for tests·"}, + {Py_tp_doc, "A class used for tests"}, + {0, 0}, +}; + +PyType_Spec repeated_doc_slots_spec = { + .name = "RepeatedDocSlotClass", + .basicsize = sizeof(PyObject), + .slots = repeated_doc_slots, +}; + +typedef struct { + PyObject_HEAD + int data; +} HeapCTypeWithDataObject; + + +static struct PyMemberDef members_to_repeat[] = { + {"T_INT", T_INT, offsetof(HeapCTypeWithDataObject, data), 0, NULL}, + {NULL} +}; + +PyType_Slot repeated_members_slots[] = { + {Py_tp_members, members_to_repeat}, + {Py_tp_members, members_to_repeat}, + {0, 0}, +}; + +PyType_Spec repeated_members_slots_spec = { + .name = "RepeatedMembersSlotClass", + .basicsize = sizeof(HeapCTypeWithDataObject), + .slots = repeated_members_slots, +}; + +static PyObject * +create_type_from_repeated_slots(PyObject *self, PyObject *variant_obj) +{ + PyObject *class = NULL; + int variant = PyLong_AsLong(variant_obj); + if (PyErr_Occurred()) { + return NULL; + } + switch (variant) { + case 0: + class = PyType_FromSpec(&repeated_doc_slots_spec); + break; + case 1: + class = PyType_FromSpec(&repeated_members_slots_spec); + break; + default: + PyErr_SetString(PyExc_ValueError, "bad test variant"); + break; + } + return class; +} + + + +static PyObject * +make_immutable_type_with_base(PyObject *self, PyObject *base) +{ + assert(PyType_Check(base)); + PyType_Spec ImmutableSubclass_spec = { + .name = "ImmutableSubclass", + .basicsize = (int)((PyTypeObject*)base)->tp_basicsize, + .slots = empty_type_slots, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, + }; + return PyType_FromSpecWithBases(&ImmutableSubclass_spec, base); +} + + +static PyMethodDef TestMethods[] = { + {"pytype_fromspec_meta", pytype_fromspec_meta, METH_O}, + {"test_type_from_ephemeral_spec", test_type_from_ephemeral_spec, METH_NOARGS}, + {"create_type_from_repeated_slots", + create_type_from_repeated_slots, METH_O}, + {"test_from_spec_metatype_inheritance", test_from_spec_metatype_inheritance, + METH_NOARGS}, + {"test_from_spec_invalid_metatype_inheritance", + test_from_spec_invalid_metatype_inheritance, + METH_NOARGS}, + {"make_immutable_type_with_base", make_immutable_type_with_base, METH_O}, + {NULL}, +}; + + +PyDoc_STRVAR(heapdocctype__doc__, +"HeapDocCType(arg1, arg2)\n" +"--\n" +"\n" +"somedoc"); + +typedef struct { + PyObject_HEAD +} HeapDocCTypeObject; + +static PyType_Slot HeapDocCType_slots[] = { + {Py_tp_doc, (char*)heapdocctype__doc__}, + {0}, +}; + +static PyType_Spec HeapDocCType_spec = { + "_testcapi.HeapDocCType", + sizeof(HeapDocCTypeObject), + 0, + Py_TPFLAGS_DEFAULT, + HeapDocCType_slots +}; + +typedef struct { + PyObject_HEAD +} NullTpDocTypeObject; + +static PyType_Slot NullTpDocType_slots[] = { + {Py_tp_doc, NULL}, + {0, 0}, +}; + +static PyType_Spec NullTpDocType_spec = { + "_testcapi.NullTpDocType", + sizeof(NullTpDocTypeObject), + 0, + Py_TPFLAGS_DEFAULT, + NullTpDocType_slots +}; + + +PyDoc_STRVAR(heapgctype__doc__, +"A heap type with GC, and with overridden dealloc.\n\n" +"The 'value' attribute is set to 10 in __init__."); + +typedef struct { + PyObject_HEAD + int value; +} HeapCTypeObject; + +static struct PyMemberDef heapctype_members[] = { + {"value", T_INT, offsetof(HeapCTypeObject, value)}, + {NULL} /* Sentinel */ +}; + +static int +heapctype_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + ((HeapCTypeObject *)self)->value = 10; + return 0; +} + +static int +heapgcctype_traverse(HeapCTypeObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + +static void +heapgcctype_dealloc(HeapCTypeObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + PyObject_GC_Del(self); + Py_DECREF(tp); +} + +static PyType_Slot HeapGcCType_slots[] = { + {Py_tp_init, heapctype_init}, + {Py_tp_members, heapctype_members}, + {Py_tp_dealloc, heapgcctype_dealloc}, + {Py_tp_traverse, heapgcctype_traverse}, + {Py_tp_doc, (char*)heapgctype__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapGcCType_spec = { + "_testcapi.HeapGcCType", + sizeof(HeapCTypeObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + HeapGcCType_slots +}; + +PyDoc_STRVAR(heapctype__doc__, +"A heap type without GC, but with overridden dealloc.\n\n" +"The 'value' attribute is set to 10 in __init__."); + +static void +heapctype_dealloc(HeapCTypeObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_Free(self); + Py_DECREF(tp); +} + +static PyType_Slot HeapCType_slots[] = { + {Py_tp_init, heapctype_init}, + {Py_tp_members, heapctype_members}, + {Py_tp_dealloc, heapctype_dealloc}, + {Py_tp_doc, (char*)heapctype__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapCType_spec = { + "_testcapi.HeapCType", + sizeof(HeapCTypeObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCType_slots +}; + +PyDoc_STRVAR(heapctypesubclass__doc__, +"Subclass of HeapCType, without GC.\n\n" +"__init__ sets the 'value' attribute to 10 and 'value2' to 20."); + +typedef struct { + HeapCTypeObject base; + int value2; +} HeapCTypeSubclassObject; + +static int +heapctypesubclass_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + /* Call __init__ of the superclass */ + if (heapctype_init(self, args, kwargs) < 0) { + return -1; + } + /* Initialize additional element */ + ((HeapCTypeSubclassObject *)self)->value2 = 20; + return 0; +} + +static struct PyMemberDef heapctypesubclass_members[] = { + {"value2", T_INT, offsetof(HeapCTypeSubclassObject, value2)}, + {NULL} /* Sentinel */ +}; + +static PyType_Slot HeapCTypeSubclass_slots[] = { + {Py_tp_init, heapctypesubclass_init}, + {Py_tp_members, heapctypesubclass_members}, + {Py_tp_doc, (char*)heapctypesubclass__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeSubclass_spec = { + "_testcapi.HeapCTypeSubclass", + sizeof(HeapCTypeSubclassObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeSubclass_slots +}; + +PyDoc_STRVAR(heapctypewithbuffer__doc__, +"Heap type with buffer support.\n\n" +"The buffer is set to [b'1', b'2', b'3', b'4']"); + +typedef struct { + HeapCTypeObject base; + char buffer[4]; +} HeapCTypeWithBufferObject; + +static int +heapctypewithbuffer_getbuffer(HeapCTypeWithBufferObject *self, Py_buffer *view, int flags) +{ + self->buffer[0] = '1'; + self->buffer[1] = '2'; + self->buffer[2] = '3'; + self->buffer[3] = '4'; + return PyBuffer_FillInfo( + view, (PyObject*)self, (void *)self->buffer, 4, 1, flags); +} + +static void +heapctypewithbuffer_releasebuffer(HeapCTypeWithBufferObject *self, Py_buffer *view) +{ + assert(view->obj == (void*) self); +} + +static PyType_Slot HeapCTypeWithBuffer_slots[] = { + {Py_bf_getbuffer, heapctypewithbuffer_getbuffer}, + {Py_bf_releasebuffer, heapctypewithbuffer_releasebuffer}, + {Py_tp_doc, (char*)heapctypewithbuffer__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithBuffer_spec = { + "_testcapi.HeapCTypeWithBuffer", + sizeof(HeapCTypeWithBufferObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithBuffer_slots +}; + +PyDoc_STRVAR(heapctypesubclasswithfinalizer__doc__, +"Subclass of HeapCType with a finalizer that reassigns __class__.\n\n" +"__class__ is set to plain HeapCTypeSubclass during finalization.\n" +"__init__ sets the 'value' attribute to 10 and 'value2' to 20."); + +static int +heapctypesubclasswithfinalizer_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyTypeObject *base = (PyTypeObject *)PyType_GetSlot(Py_TYPE(self), Py_tp_base); + initproc base_init = PyType_GetSlot(base, Py_tp_init); + base_init(self, args, kwargs); + return 0; +} + +static void +heapctypesubclasswithfinalizer_finalize(PyObject *self) +{ + PyObject *error_type, *error_value, *error_traceback, *m; + PyObject *oldtype = NULL, *newtype = NULL, *refcnt = NULL; + + /* Save the current exception, if any. */ + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + if (_testcapimodule == NULL) { + goto cleanup_finalize; + } + m = PyState_FindModule(_testcapimodule); + if (m == NULL) { + goto cleanup_finalize; + } + oldtype = PyObject_GetAttrString(m, "HeapCTypeSubclassWithFinalizer"); + newtype = PyObject_GetAttrString(m, "HeapCTypeSubclass"); + if (oldtype == NULL || newtype == NULL) { + goto cleanup_finalize; + } + + if (PyObject_SetAttrString(self, "__class__", newtype) < 0) { + goto cleanup_finalize; + } + refcnt = PyLong_FromSsize_t(Py_REFCNT(oldtype)); + if (refcnt == NULL) { + goto cleanup_finalize; + } + if (PyObject_SetAttrString(oldtype, "refcnt_in_del", refcnt) < 0) { + goto cleanup_finalize; + } + Py_DECREF(refcnt); + refcnt = PyLong_FromSsize_t(Py_REFCNT(newtype)); + if (refcnt == NULL) { + goto cleanup_finalize; + } + if (PyObject_SetAttrString(newtype, "refcnt_in_del", refcnt) < 0) { + goto cleanup_finalize; + } + +cleanup_finalize: + Py_XDECREF(oldtype); + Py_XDECREF(newtype); + Py_XDECREF(refcnt); + + /* Restore the saved exception. */ + PyErr_Restore(error_type, error_value, error_traceback); +} + +static PyType_Slot HeapCTypeSubclassWithFinalizer_slots[] = { + {Py_tp_init, heapctypesubclasswithfinalizer_init}, + {Py_tp_members, heapctypesubclass_members}, + {Py_tp_finalize, heapctypesubclasswithfinalizer_finalize}, + {Py_tp_doc, (char*)heapctypesubclasswithfinalizer__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeSubclassWithFinalizer_spec = { + "_testcapi.HeapCTypeSubclassWithFinalizer", + sizeof(HeapCTypeSubclassObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE, + HeapCTypeSubclassWithFinalizer_slots +}; + +static PyType_Slot HeapCTypeMetaclass_slots[] = { + {0}, +}; + +static PyType_Spec HeapCTypeMetaclass_spec = { + "_testcapi.HeapCTypeMetaclass", + sizeof(PyHeapTypeObject), + sizeof(PyMemberDef), + Py_TPFLAGS_DEFAULT, + HeapCTypeMetaclass_slots +}; + +static PyObject * +heap_ctype_metaclass_custom_tp_new(PyTypeObject *tp, PyObject *args, PyObject *kwargs) +{ + return PyType_Type.tp_new(tp, args, kwargs); +} + +static PyType_Slot HeapCTypeMetaclassCustomNew_slots[] = { + { Py_tp_new, heap_ctype_metaclass_custom_tp_new }, + {0}, +}; + +static PyType_Spec HeapCTypeMetaclassCustomNew_spec = { + "_testcapi.HeapCTypeMetaclassCustomNew", + sizeof(PyHeapTypeObject), + sizeof(PyMemberDef), + Py_TPFLAGS_DEFAULT, + HeapCTypeMetaclassCustomNew_slots +}; + + +typedef struct { + PyObject_HEAD + PyObject *dict; +} HeapCTypeWithDictObject; + +static void +heapctypewithdict_dealloc(HeapCTypeWithDictObject* self) +{ + + PyTypeObject *tp = Py_TYPE(self); + Py_XDECREF(self->dict); + PyObject_Free(self); + Py_DECREF(tp); +} + +static PyGetSetDef heapctypewithdict_getsetlist[] = { + {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, + {NULL} /* Sentinel */ +}; + +static struct PyMemberDef heapctypewithdict_members[] = { + {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, + {"__dictoffset__", T_PYSSIZET, offsetof(HeapCTypeWithDictObject, dict), READONLY}, + {NULL} /* Sentinel */ +}; + +static PyType_Slot HeapCTypeWithDict_slots[] = { + {Py_tp_members, heapctypewithdict_members}, + {Py_tp_getset, heapctypewithdict_getsetlist}, + {Py_tp_dealloc, heapctypewithdict_dealloc}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithDict_spec = { + "_testcapi.HeapCTypeWithDict", + sizeof(HeapCTypeWithDictObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithDict_slots +}; + +static PyType_Spec HeapCTypeWithDict2_spec = { + "_testcapi.HeapCTypeWithDict2", + sizeof(HeapCTypeWithDictObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithDict_slots +}; + +static int +heapmanaged_traverse(HeapCTypeObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return _PyObject_VisitManagedDict((PyObject *)self, visit, arg); +} + +static int +heapmanaged_clear(HeapCTypeObject *self) +{ + _PyObject_ClearManagedDict((PyObject *)self); + return 0; +} + +static void +heapmanaged_dealloc(HeapCTypeObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + _PyObject_ClearManagedDict((PyObject *)self); + PyObject_GC_UnTrack(self); + PyObject_GC_Del(self); + Py_DECREF(tp); +} + +static PyType_Slot HeapCTypeWithManagedDict_slots[] = { + {Py_tp_traverse, heapmanaged_traverse}, + {Py_tp_getset, heapctypewithdict_getsetlist}, + {Py_tp_clear, heapmanaged_clear}, + {Py_tp_dealloc, heapmanaged_dealloc}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithManagedDict_spec = { + "_testcapi.HeapCTypeWithManagedDict", + sizeof(PyObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_DICT, + HeapCTypeWithManagedDict_slots +}; + +static void +heapctypewithmanagedweakref_dealloc(PyObject* self) +{ + + PyTypeObject *tp = Py_TYPE(self); + PyObject_ClearWeakRefs(self); + PyObject_GC_UnTrack(self); + PyObject_GC_Del(self); + Py_DECREF(tp); +} + +static PyType_Slot HeapCTypeWithManagedWeakref_slots[] = { + {Py_tp_traverse, heapgcctype_traverse}, + {Py_tp_getset, heapctypewithdict_getsetlist}, + {Py_tp_dealloc, heapctypewithmanagedweakref_dealloc}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithManagedWeakref_spec = { + "_testcapi.HeapCTypeWithManagedWeakref", + sizeof(PyObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_WEAKREF, + HeapCTypeWithManagedWeakref_slots +}; + +static struct PyMemberDef heapctypewithnegativedict_members[] = { + {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, + {"__dictoffset__", T_PYSSIZET, -(Py_ssize_t)sizeof(void*), READONLY}, + {NULL} /* Sentinel */ +}; + +static PyType_Slot HeapCTypeWithNegativeDict_slots[] = { + {Py_tp_members, heapctypewithnegativedict_members}, + {Py_tp_getset, heapctypewithdict_getsetlist}, + {Py_tp_dealloc, heapctypewithdict_dealloc}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithNegativeDict_spec = { + "_testcapi.HeapCTypeWithNegativeDict", + sizeof(HeapCTypeWithDictObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithNegativeDict_slots +}; + +typedef struct { + PyObject_HEAD + PyObject *weakreflist; +} HeapCTypeWithWeakrefObject; + +static struct PyMemberDef heapctypewithweakref_members[] = { + {"weakreflist", T_OBJECT, offsetof(HeapCTypeWithWeakrefObject, weakreflist)}, + {"__weaklistoffset__", T_PYSSIZET, + offsetof(HeapCTypeWithWeakrefObject, weakreflist), READONLY}, + {NULL} /* Sentinel */ +}; + +static void +heapctypewithweakref_dealloc(HeapCTypeWithWeakrefObject* self) +{ + + PyTypeObject *tp = Py_TYPE(self); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + Py_XDECREF(self->weakreflist); + PyObject_Free(self); + Py_DECREF(tp); +} + +static PyType_Slot HeapCTypeWithWeakref_slots[] = { + {Py_tp_members, heapctypewithweakref_members}, + {Py_tp_dealloc, heapctypewithweakref_dealloc}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithWeakref_spec = { + "_testcapi.HeapCTypeWithWeakref", + sizeof(HeapCTypeWithWeakrefObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithWeakref_slots +}; + +static PyType_Spec HeapCTypeWithWeakref2_spec = { + "_testcapi.HeapCTypeWithWeakref2", + sizeof(HeapCTypeWithWeakrefObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithWeakref_slots +}; + +PyDoc_STRVAR(heapctypesetattr__doc__, +"A heap type without GC, but with overridden __setattr__.\n\n" +"The 'value' attribute is set to 10 in __init__ and updated via attribute setting."); + +typedef struct { + PyObject_HEAD + long value; +} HeapCTypeSetattrObject; + +static struct PyMemberDef heapctypesetattr_members[] = { + {"pvalue", T_LONG, offsetof(HeapCTypeSetattrObject, value)}, + {NULL} /* Sentinel */ +}; + +static int +heapctypesetattr_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + ((HeapCTypeSetattrObject *)self)->value = 10; + return 0; +} + +static void +heapctypesetattr_dealloc(HeapCTypeSetattrObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_Free(self); + Py_DECREF(tp); +} + +static int +heapctypesetattr_setattro(HeapCTypeSetattrObject *self, PyObject *attr, PyObject *value) +{ + PyObject *svalue = PyUnicode_FromString("value"); + if (svalue == NULL) + return -1; + int eq = PyObject_RichCompareBool(svalue, attr, Py_EQ); + Py_DECREF(svalue); + if (eq < 0) + return -1; + if (!eq) { + return PyObject_GenericSetAttr((PyObject*) self, attr, value); + } + if (value == NULL) { + self->value = 0; + return 0; + } + PyObject *ivalue = PyNumber_Long(value); + if (ivalue == NULL) + return -1; + long v = PyLong_AsLong(ivalue); + Py_DECREF(ivalue); + if (v == -1 && PyErr_Occurred()) + return -1; + self->value = v; + return 0; +} + +static PyType_Slot HeapCTypeSetattr_slots[] = { + {Py_tp_init, heapctypesetattr_init}, + {Py_tp_members, heapctypesetattr_members}, + {Py_tp_setattro, heapctypesetattr_setattro}, + {Py_tp_dealloc, heapctypesetattr_dealloc}, + {Py_tp_doc, (char*)heapctypesetattr__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeSetattr_spec = { + "_testcapi.HeapCTypeSetattr", + sizeof(HeapCTypeSetattrObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeSetattr_slots +}; + +int +_PyTestCapi_Init_Heaptype(PyObject *m) { + _testcapimodule = PyModule_GetDef(m); + + if (PyModule_AddFunctions(m, TestMethods) < 0) { + return -1; + } + + PyObject *HeapDocCType = PyType_FromSpec(&HeapDocCType_spec); + if (HeapDocCType == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapDocCType", HeapDocCType); + + /* bpo-41832: Add a new type to test PyType_FromSpec() + now can accept a NULL tp_doc slot. */ + PyObject *NullTpDocType = PyType_FromSpec(&NullTpDocType_spec); + if (NullTpDocType == NULL) { + return -1; + } + PyModule_AddObject(m, "NullTpDocType", NullTpDocType); + + PyObject *HeapGcCType = PyType_FromSpec(&HeapGcCType_spec); + if (HeapGcCType == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapGcCType", HeapGcCType); + + PyObject *HeapCType = PyType_FromSpec(&HeapCType_spec); + if (HeapCType == NULL) { + return -1; + } + PyObject *subclass_bases = PyTuple_Pack(1, HeapCType); + if (subclass_bases == NULL) { + return -1; + } + PyObject *HeapCTypeSubclass = PyType_FromSpecWithBases(&HeapCTypeSubclass_spec, subclass_bases); + if (HeapCTypeSubclass == NULL) { + return -1; + } + Py_DECREF(subclass_bases); + PyModule_AddObject(m, "HeapCTypeSubclass", HeapCTypeSubclass); + + PyObject *HeapCTypeWithDict = PyType_FromSpec(&HeapCTypeWithDict_spec); + if (HeapCTypeWithDict == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithDict", HeapCTypeWithDict); + + PyObject *HeapCTypeWithDict2 = PyType_FromSpec(&HeapCTypeWithDict2_spec); + if (HeapCTypeWithDict2 == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithDict2", HeapCTypeWithDict2); + + PyObject *HeapCTypeWithNegativeDict = PyType_FromSpec(&HeapCTypeWithNegativeDict_spec); + if (HeapCTypeWithNegativeDict == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithNegativeDict", HeapCTypeWithNegativeDict); + + PyObject *HeapCTypeWithManagedDict = PyType_FromSpec(&HeapCTypeWithManagedDict_spec); + if (HeapCTypeWithManagedDict == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithManagedDict", HeapCTypeWithManagedDict); + + PyObject *HeapCTypeWithManagedWeakref = PyType_FromSpec(&HeapCTypeWithManagedWeakref_spec); + if (HeapCTypeWithManagedWeakref == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithManagedWeakref", HeapCTypeWithManagedWeakref); + + PyObject *HeapCTypeWithWeakref = PyType_FromSpec(&HeapCTypeWithWeakref_spec); + if (HeapCTypeWithWeakref == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithWeakref", HeapCTypeWithWeakref); + + PyObject *HeapCTypeWithWeakref2 = PyType_FromSpec(&HeapCTypeWithWeakref2_spec); + if (HeapCTypeWithWeakref2 == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithWeakref2", HeapCTypeWithWeakref2); + + PyObject *HeapCTypeWithBuffer = PyType_FromSpec(&HeapCTypeWithBuffer_spec); + if (HeapCTypeWithBuffer == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithBuffer", HeapCTypeWithBuffer); + + PyObject *HeapCTypeSetattr = PyType_FromSpec(&HeapCTypeSetattr_spec); + if (HeapCTypeSetattr == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeSetattr", HeapCTypeSetattr); + + PyObject *subclass_with_finalizer_bases = PyTuple_Pack(1, HeapCTypeSubclass); + if (subclass_with_finalizer_bases == NULL) { + return -1; + } + PyObject *HeapCTypeSubclassWithFinalizer = PyType_FromSpecWithBases( + &HeapCTypeSubclassWithFinalizer_spec, subclass_with_finalizer_bases); + if (HeapCTypeSubclassWithFinalizer == NULL) { + return -1; + } + Py_DECREF(subclass_with_finalizer_bases); + PyModule_AddObject(m, "HeapCTypeSubclassWithFinalizer", HeapCTypeSubclassWithFinalizer); + + PyObject *HeapCTypeMetaclass = PyType_FromMetaclass( + &PyType_Type, m, &HeapCTypeMetaclass_spec, (PyObject *) &PyType_Type); + if (HeapCTypeMetaclass == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeMetaclass", HeapCTypeMetaclass); + + PyObject *HeapCTypeMetaclassCustomNew = PyType_FromMetaclass( + &PyType_Type, m, &HeapCTypeMetaclassCustomNew_spec, (PyObject *) &PyType_Type); + if (HeapCTypeMetaclassCustomNew == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeMetaclassCustomNew", HeapCTypeMetaclassCustomNew); + + return 0; +} diff --git a/Modules/_testcapi/long.c b/Modules/_testcapi/long.c new file mode 100644 index 00000000000..1be8de5e576 --- /dev/null +++ b/Modules/_testcapi/long.c @@ -0,0 +1,557 @@ +#include "parts.h" + + +static PyObject * +raiseTestError(const char* test_name, const char* msg) +{ + PyErr_Format(PyExc_AssertionError, "%s: %s", test_name, msg); + return NULL; +} + +/* Tests of PyLong_{As, From}{Unsigned,}Long(), and + PyLong_{As, From}{Unsigned,}LongLong(). + + Note that the meat of the test is contained in testcapi_long.h. + This is revolting, but delicate code duplication is worse: "almost + exactly the same" code is needed to test long long, but the ubiquitous + dependence on type names makes it impossible to use a parameterized + function. A giant macro would be even worse than this. A C++ template + would be perfect. + + The "report an error" functions are deliberately not part of the #include + file: if the test fails, you can set a breakpoint in the appropriate + error function directly, and crawl back from there in the debugger. +*/ + +#define UNBIND(X) Py_DECREF(X); (X) = NULL + +static PyObject * +raise_test_long_error(const char* msg) +{ + return raiseTestError("test_long_api", msg); +} + +#define TESTNAME test_long_api_inner +#define TYPENAME long +#define F_S_TO_PY PyLong_FromLong +#define F_PY_TO_S PyLong_AsLong +#define F_U_TO_PY PyLong_FromUnsignedLong +#define F_PY_TO_U PyLong_AsUnsignedLong + +#include "testcapi_long.h" + +static PyObject * +test_long_api(PyObject* self, PyObject *Py_UNUSED(ignored)) +{ + return TESTNAME(raise_test_long_error); +} + +#undef TESTNAME +#undef TYPENAME +#undef F_S_TO_PY +#undef F_PY_TO_S +#undef F_U_TO_PY +#undef F_PY_TO_U + +static PyObject * +raise_test_longlong_error(const char* msg) +{ + return raiseTestError("test_longlong_api", msg); +} + +#define TESTNAME test_longlong_api_inner +#define TYPENAME long long +#define F_S_TO_PY PyLong_FromLongLong +#define F_PY_TO_S PyLong_AsLongLong +#define F_U_TO_PY PyLong_FromUnsignedLongLong +#define F_PY_TO_U PyLong_AsUnsignedLongLong + +#include "testcapi_long.h" + +static PyObject * +test_longlong_api(PyObject* self, PyObject *args) +{ + return TESTNAME(raise_test_longlong_error); +} + +#undef TESTNAME +#undef TYPENAME +#undef F_S_TO_PY +#undef F_PY_TO_S +#undef F_U_TO_PY +#undef F_PY_TO_U + +/* Test the PyLong_AsLongAndOverflow API. General conversion to PY_LONG + is tested by test_long_api_inner. This test will concentrate on proper + handling of overflow. +*/ + +static PyObject * +test_long_and_overflow(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *num, *one, *temp; + long value; + int overflow; + + /* Test that overflow is set properly for a large value. */ + /* num is a number larger than LONG_MAX even on 64-bit platforms */ + num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_and_overflow", + "return value was not set to -1"); + if (overflow != 1) + return raiseTestError("test_long_and_overflow", + "overflow was not set to 1"); + + /* Same again, with num = LONG_MAX + 1 */ + num = PyLong_FromLong(LONG_MAX); + if (num == NULL) + return NULL; + one = PyLong_FromLong(1L); + if (one == NULL) { + Py_DECREF(num); + return NULL; + } + temp = PyNumber_Add(num, one); + Py_DECREF(one); + Py_SETREF(num, temp); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_and_overflow", + "return value was not set to -1"); + if (overflow != 1) + return raiseTestError("test_long_and_overflow", + "overflow was not set to 1"); + + /* Test that overflow is set properly for a large negative value. */ + /* num is a number smaller than LONG_MIN even on 64-bit platforms */ + num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_and_overflow", + "return value was not set to -1"); + if (overflow != -1) + return raiseTestError("test_long_and_overflow", + "overflow was not set to -1"); + + /* Same again, with num = LONG_MIN - 1 */ + num = PyLong_FromLong(LONG_MIN); + if (num == NULL) + return NULL; + one = PyLong_FromLong(1L); + if (one == NULL) { + Py_DECREF(num); + return NULL; + } + temp = PyNumber_Subtract(num, one); + Py_DECREF(one); + Py_SETREF(num, temp); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_and_overflow", + "return value was not set to -1"); + if (overflow != -1) + return raiseTestError("test_long_and_overflow", + "overflow was not set to -1"); + + /* Test that overflow is cleared properly for small values. */ + num = PyLong_FromString("FF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != 0xFF) + return raiseTestError("test_long_and_overflow", + "expected return value 0xFF"); + if (overflow != 0) + return raiseTestError("test_long_and_overflow", + "overflow was not cleared"); + + num = PyLong_FromString("-FF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -0xFF) + return raiseTestError("test_long_and_overflow", + "expected return value 0xFF"); + if (overflow != 0) + return raiseTestError("test_long_and_overflow", + "overflow was set incorrectly"); + + num = PyLong_FromLong(LONG_MAX); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != LONG_MAX) + return raiseTestError("test_long_and_overflow", + "expected return value LONG_MAX"); + if (overflow != 0) + return raiseTestError("test_long_and_overflow", + "overflow was not cleared"); + + num = PyLong_FromLong(LONG_MIN); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != LONG_MIN) + return raiseTestError("test_long_and_overflow", + "expected return value LONG_MIN"); + if (overflow != 0) + return raiseTestError("test_long_and_overflow", + "overflow was not cleared"); + + Py_RETURN_NONE; +} + +/* Test the PyLong_AsLongLongAndOverflow API. General conversion to + long long is tested by test_long_api_inner. This test will + concentrate on proper handling of overflow. +*/ + +static PyObject * +test_long_long_and_overflow(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *num, *one, *temp; + long long value; + int overflow; + + /* Test that overflow is set properly for a large value. */ + /* num is a number larger than LLONG_MAX on a typical machine. */ + num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_long_and_overflow", + "return value was not set to -1"); + if (overflow != 1) + return raiseTestError("test_long_long_and_overflow", + "overflow was not set to 1"); + + /* Same again, with num = LLONG_MAX + 1 */ + num = PyLong_FromLongLong(LLONG_MAX); + if (num == NULL) + return NULL; + one = PyLong_FromLong(1L); + if (one == NULL) { + Py_DECREF(num); + return NULL; + } + temp = PyNumber_Add(num, one); + Py_DECREF(one); + Py_SETREF(num, temp); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_long_and_overflow", + "return value was not set to -1"); + if (overflow != 1) + return raiseTestError("test_long_long_and_overflow", + "overflow was not set to 1"); + + /* Test that overflow is set properly for a large negative value. */ + /* num is a number smaller than LLONG_MIN on a typical platform */ + num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_long_and_overflow", + "return value was not set to -1"); + if (overflow != -1) + return raiseTestError("test_long_long_and_overflow", + "overflow was not set to -1"); + + /* Same again, with num = LLONG_MIN - 1 */ + num = PyLong_FromLongLong(LLONG_MIN); + if (num == NULL) + return NULL; + one = PyLong_FromLong(1L); + if (one == NULL) { + Py_DECREF(num); + return NULL; + } + temp = PyNumber_Subtract(num, one); + Py_DECREF(one); + Py_SETREF(num, temp); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_long_and_overflow", + "return value was not set to -1"); + if (overflow != -1) + return raiseTestError("test_long_long_and_overflow", + "overflow was not set to -1"); + + /* Test that overflow is cleared properly for small values. */ + num = PyLong_FromString("FF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != 0xFF) + return raiseTestError("test_long_long_and_overflow", + "expected return value 0xFF"); + if (overflow != 0) + return raiseTestError("test_long_long_and_overflow", + "overflow was not cleared"); + + num = PyLong_FromString("-FF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -0xFF) + return raiseTestError("test_long_long_and_overflow", + "expected return value 0xFF"); + if (overflow != 0) + return raiseTestError("test_long_long_and_overflow", + "overflow was set incorrectly"); + + num = PyLong_FromLongLong(LLONG_MAX); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != LLONG_MAX) + return raiseTestError("test_long_long_and_overflow", + "expected return value LLONG_MAX"); + if (overflow != 0) + return raiseTestError("test_long_long_and_overflow", + "overflow was not cleared"); + + num = PyLong_FromLongLong(LLONG_MIN); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != LLONG_MIN) + return raiseTestError("test_long_long_and_overflow", + "expected return value LLONG_MIN"); + if (overflow != 0) + return raiseTestError("test_long_long_and_overflow", + "overflow was not cleared"); + + Py_RETURN_NONE; +} + +/* Test the PyLong_As{Size,Ssize}_t API. At present this just tests that + non-integer arguments are handled correctly. It should be extended to + test overflow handling. + */ + +static PyObject * +test_long_as_size_t(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + size_t out_u; + Py_ssize_t out_s; + + Py_INCREF(Py_None); + + out_u = PyLong_AsSize_t(Py_None); + if (out_u != (size_t)-1 || !PyErr_Occurred()) + return raiseTestError("test_long_as_size_t", + "PyLong_AsSize_t(None) didn't complain"); + if (!PyErr_ExceptionMatches(PyExc_TypeError)) + return raiseTestError("test_long_as_size_t", + "PyLong_AsSize_t(None) raised " + "something other than TypeError"); + PyErr_Clear(); + + out_s = PyLong_AsSsize_t(Py_None); + if (out_s != (Py_ssize_t)-1 || !PyErr_Occurred()) + return raiseTestError("test_long_as_size_t", + "PyLong_AsSsize_t(None) didn't complain"); + if (!PyErr_ExceptionMatches(PyExc_TypeError)) + return raiseTestError("test_long_as_size_t", + "PyLong_AsSsize_t(None) raised " + "something other than TypeError"); + PyErr_Clear(); + + /* Py_INCREF(Py_None) omitted - we already have a reference to it. */ + return Py_None; +} + +static PyObject * +test_long_as_unsigned_long_long_mask(PyObject *self, + PyObject *Py_UNUSED(ignored)) +{ + unsigned long long res = PyLong_AsUnsignedLongLongMask(NULL); + + if (res != (unsigned long long)-1 || !PyErr_Occurred()) { + return raiseTestError("test_long_as_unsigned_long_long_mask", + "PyLong_AsUnsignedLongLongMask(NULL) didn't " + "complain"); + } + if (!PyErr_ExceptionMatches(PyExc_SystemError)) { + return raiseTestError("test_long_as_unsigned_long_long_mask", + "PyLong_AsUnsignedLongLongMask(NULL) raised " + "something other than SystemError"); + } + PyErr_Clear(); + Py_RETURN_NONE; +} + +/* Test the PyLong_AsDouble API. At present this just tests that + non-integer arguments are handled correctly. + */ + +static PyObject * +test_long_as_double(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + double out; + + Py_INCREF(Py_None); + + out = PyLong_AsDouble(Py_None); + if (out != -1.0 || !PyErr_Occurred()) + return raiseTestError("test_long_as_double", + "PyLong_AsDouble(None) didn't complain"); + if (!PyErr_ExceptionMatches(PyExc_TypeError)) + return raiseTestError("test_long_as_double", + "PyLong_AsDouble(None) raised " + "something other than TypeError"); + PyErr_Clear(); + + /* Py_INCREF(Py_None) omitted - we already have a reference to it. */ + return Py_None; +} + +/* Simple test of _PyLong_NumBits and _PyLong_Sign. */ +static PyObject * +test_long_numbits(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + struct triple { + long input; + size_t nbits; + int sign; + } testcases[] = {{0, 0, 0}, + {1L, 1, 1}, + {-1L, 1, -1}, + {2L, 2, 1}, + {-2L, 2, -1}, + {3L, 2, 1}, + {-3L, 2, -1}, + {4L, 3, 1}, + {-4L, 3, -1}, + {0x7fffL, 15, 1}, /* one Python int digit */ + {-0x7fffL, 15, -1}, + {0xffffL, 16, 1}, + {-0xffffL, 16, -1}, + {0xfffffffL, 28, 1}, + {-0xfffffffL, 28, -1}}; + size_t i; + + for (i = 0; i < Py_ARRAY_LENGTH(testcases); ++i) { + size_t nbits; + int sign; + PyObject *plong; + + plong = PyLong_FromLong(testcases[i].input); + if (plong == NULL) + return NULL; + nbits = _PyLong_NumBits(plong); + sign = _PyLong_Sign(plong); + + Py_DECREF(plong); + if (nbits != testcases[i].nbits) + return raiseTestError("test_long_numbits", + "wrong result for _PyLong_NumBits"); + if (sign != testcases[i].sign) + return raiseTestError("test_long_numbits", + "wrong result for _PyLong_Sign"); + } + Py_RETURN_NONE; +} + +static PyMethodDef test_methods[] = { + {"test_long_and_overflow", test_long_and_overflow, METH_NOARGS}, + {"test_long_api", test_long_api, METH_NOARGS}, + {"test_long_as_double", test_long_as_double, METH_NOARGS}, + {"test_long_as_size_t", test_long_as_size_t, METH_NOARGS}, + {"test_long_as_unsigned_long_long_mask", test_long_as_unsigned_long_long_mask, METH_NOARGS}, + {"test_long_long_and_overflow",test_long_long_and_overflow, METH_NOARGS}, + {"test_long_numbits", test_long_numbits, METH_NOARGS}, + {"test_longlong_api", test_longlong_api, METH_NOARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_Long(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/mem.c b/Modules/_testcapi/mem.c new file mode 100644 index 00000000000..ae3f7a4372d --- /dev/null +++ b/Modules/_testcapi/mem.c @@ -0,0 +1,724 @@ +#include "parts.h" + +#include + + +typedef struct { + PyMemAllocatorEx alloc; + + size_t malloc_size; + size_t calloc_nelem; + size_t calloc_elsize; + void *realloc_ptr; + size_t realloc_new_size; + void *free_ptr; + void *ctx; +} alloc_hook_t; + +static void * +hook_malloc(void *ctx, size_t size) +{ + alloc_hook_t *hook = (alloc_hook_t *)ctx; + hook->ctx = ctx; + hook->malloc_size = size; + return hook->alloc.malloc(hook->alloc.ctx, size); +} + +static void * +hook_calloc(void *ctx, size_t nelem, size_t elsize) +{ + alloc_hook_t *hook = (alloc_hook_t *)ctx; + hook->ctx = ctx; + hook->calloc_nelem = nelem; + hook->calloc_elsize = elsize; + return hook->alloc.calloc(hook->alloc.ctx, nelem, elsize); +} + +static void * +hook_realloc(void *ctx, void *ptr, size_t new_size) +{ + alloc_hook_t *hook = (alloc_hook_t *)ctx; + hook->ctx = ctx; + hook->realloc_ptr = ptr; + hook->realloc_new_size = new_size; + return hook->alloc.realloc(hook->alloc.ctx, ptr, new_size); +} + +static void +hook_free(void *ctx, void *ptr) +{ + alloc_hook_t *hook = (alloc_hook_t *)ctx; + hook->ctx = ctx; + hook->free_ptr = ptr; + hook->alloc.free(hook->alloc.ctx, ptr); +} + +/* Most part of the following code is inherited from the pyfailmalloc project + * written by Victor Stinner. */ +static struct { + int installed; + PyMemAllocatorEx raw; + PyMemAllocatorEx mem; + PyMemAllocatorEx obj; +} FmHook; + +static struct { + int start; + int stop; + Py_ssize_t count; +} FmData; + +static int +fm_nomemory(void) +{ + FmData.count++; + if (FmData.count > FmData.start && + (FmData.stop <= 0 || FmData.count <= FmData.stop)) + { + return 1; + } + return 0; +} + +static void * +hook_fmalloc(void *ctx, size_t size) +{ + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + if (fm_nomemory()) { + return NULL; + } + return alloc->malloc(alloc->ctx, size); +} + +static void * +hook_fcalloc(void *ctx, size_t nelem, size_t elsize) +{ + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + if (fm_nomemory()) { + return NULL; + } + return alloc->calloc(alloc->ctx, nelem, elsize); +} + +static void * +hook_frealloc(void *ctx, void *ptr, size_t new_size) +{ + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + if (fm_nomemory()) { + return NULL; + } + return alloc->realloc(alloc->ctx, ptr, new_size); +} + +static void +hook_ffree(void *ctx, void *ptr) +{ + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + alloc->free(alloc->ctx, ptr); +} + +static void +fm_setup_hooks(void) +{ + if (FmHook.installed) { + return; + } + FmHook.installed = 1; + + PyMemAllocatorEx alloc; + alloc.malloc = hook_fmalloc; + alloc.calloc = hook_fcalloc; + alloc.realloc = hook_frealloc; + alloc.free = hook_ffree; + PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &FmHook.raw); + PyMem_GetAllocator(PYMEM_DOMAIN_MEM, &FmHook.mem); + PyMem_GetAllocator(PYMEM_DOMAIN_OBJ, &FmHook.obj); + + alloc.ctx = &FmHook.raw; + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &alloc); + + alloc.ctx = &FmHook.mem; + PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &alloc); + + alloc.ctx = &FmHook.obj; + PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc); +} + +static void +fm_remove_hooks(void) +{ + if (FmHook.installed) { + FmHook.installed = 0; + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &FmHook.raw); + PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &FmHook.mem); + PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &FmHook.obj); + } +} + +static PyObject * +set_nomemory(PyObject *self, PyObject *args) +{ + /* Memory allocation fails after 'start' allocation requests, and until + * 'stop' allocation requests except when 'stop' is negative or equal + * to 0 (default) in which case allocation failures never stop. */ + FmData.count = 0; + FmData.stop = 0; + if (!PyArg_ParseTuple(args, "i|i", &FmData.start, &FmData.stop)) { + return NULL; + } + fm_setup_hooks(); + Py_RETURN_NONE; +} + +static PyObject * +remove_mem_hooks(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + fm_remove_hooks(); + Py_RETURN_NONE; +} + +static PyObject * +test_setallocators(PyMemAllocatorDomain domain) +{ + PyObject *res = NULL; + const char *error_msg; + alloc_hook_t hook; + + memset(&hook, 0, sizeof(hook)); + + PyMemAllocatorEx alloc; + alloc.ctx = &hook; + alloc.malloc = &hook_malloc; + alloc.calloc = &hook_calloc; + alloc.realloc = &hook_realloc; + alloc.free = &hook_free; + PyMem_GetAllocator(domain, &hook.alloc); + PyMem_SetAllocator(domain, &alloc); + + /* malloc, realloc, free */ + size_t size = 42; + hook.ctx = NULL; + void *ptr; + switch(domain) { + case PYMEM_DOMAIN_RAW: + ptr = PyMem_RawMalloc(size); + break; + case PYMEM_DOMAIN_MEM: + ptr = PyMem_Malloc(size); + break; + case PYMEM_DOMAIN_OBJ: + ptr = PyObject_Malloc(size); + break; + default: + ptr = NULL; + break; + } + +#define CHECK_CTX(FUNC) \ + if (hook.ctx != &hook) { \ + error_msg = FUNC " wrong context"; \ + goto fail; \ + } \ + hook.ctx = NULL; /* reset for next check */ + + if (ptr == NULL) { + error_msg = "malloc failed"; + goto fail; + } + CHECK_CTX("malloc"); + if (hook.malloc_size != size) { + error_msg = "malloc invalid size"; + goto fail; + } + + size_t size2 = 200; + void *ptr2; + switch(domain) { + case PYMEM_DOMAIN_RAW: + ptr2 = PyMem_RawRealloc(ptr, size2); + break; + case PYMEM_DOMAIN_MEM: + ptr2 = PyMem_Realloc(ptr, size2); + break; + case PYMEM_DOMAIN_OBJ: + ptr2 = PyObject_Realloc(ptr, size2); + break; + default: + ptr2 = NULL; + break; + } + + if (ptr2 == NULL) { + error_msg = "realloc failed"; + goto fail; + } + CHECK_CTX("realloc"); + if (hook.realloc_ptr != ptr || hook.realloc_new_size != size2) { + error_msg = "realloc invalid parameters"; + goto fail; + } + + switch(domain) { + case PYMEM_DOMAIN_RAW: + PyMem_RawFree(ptr2); + break; + case PYMEM_DOMAIN_MEM: + PyMem_Free(ptr2); + break; + case PYMEM_DOMAIN_OBJ: + PyObject_Free(ptr2); + break; + } + + CHECK_CTX("free"); + if (hook.free_ptr != ptr2) { + error_msg = "free invalid pointer"; + goto fail; + } + + /* calloc, free */ + size_t nelem = 2; + size_t elsize = 5; + switch(domain) { + case PYMEM_DOMAIN_RAW: + ptr = PyMem_RawCalloc(nelem, elsize); + break; + case PYMEM_DOMAIN_MEM: + ptr = PyMem_Calloc(nelem, elsize); + break; + case PYMEM_DOMAIN_OBJ: + ptr = PyObject_Calloc(nelem, elsize); + break; + default: + ptr = NULL; + break; + } + + if (ptr == NULL) { + error_msg = "calloc failed"; + goto fail; + } + CHECK_CTX("calloc"); + if (hook.calloc_nelem != nelem || hook.calloc_elsize != elsize) { + error_msg = "calloc invalid nelem or elsize"; + goto fail; + } + + hook.free_ptr = NULL; + switch(domain) { + case PYMEM_DOMAIN_RAW: + PyMem_RawFree(ptr); + break; + case PYMEM_DOMAIN_MEM: + PyMem_Free(ptr); + break; + case PYMEM_DOMAIN_OBJ: + PyObject_Free(ptr); + break; + } + + CHECK_CTX("calloc free"); + if (hook.free_ptr != ptr) { + error_msg = "calloc free invalid pointer"; + goto fail; + } + + res = Py_NewRef(Py_None); + goto finally; + +fail: + PyErr_SetString(PyExc_RuntimeError, error_msg); + +finally: + PyMem_SetAllocator(domain, &hook.alloc); + return res; + +#undef CHECK_CTX +} + +static PyObject * +test_pyobject_setallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return test_setallocators(PYMEM_DOMAIN_OBJ); +} + +static PyObject * +test_pyobject_new(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *obj; + PyTypeObject *type = &PyBaseObject_Type; + PyTypeObject *var_type = &PyLong_Type; + + // PyObject_New() + obj = PyObject_New(PyObject, type); + if (obj == NULL) { + goto alloc_failed; + } + Py_DECREF(obj); + + // PyObject_NEW() + obj = PyObject_NEW(PyObject, type); + if (obj == NULL) { + goto alloc_failed; + } + Py_DECREF(obj); + + // PyObject_NewVar() + obj = PyObject_NewVar(PyObject, var_type, 3); + if (obj == NULL) { + goto alloc_failed; + } + Py_DECREF(obj); + + // PyObject_NEW_VAR() + obj = PyObject_NEW_VAR(PyObject, var_type, 3); + if (obj == NULL) { + goto alloc_failed; + } + Py_DECREF(obj); + + Py_RETURN_NONE; + +alloc_failed: + PyErr_NoMemory(); + return NULL; +} + +static PyObject * +test_pymem_alloc0(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + void *ptr; + + ptr = PyMem_RawMalloc(0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "PyMem_RawMalloc(0) returns NULL"); + return NULL; + } + PyMem_RawFree(ptr); + + ptr = PyMem_RawCalloc(0, 0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "PyMem_RawCalloc(0, 0) returns NULL"); + return NULL; + } + PyMem_RawFree(ptr); + + ptr = PyMem_Malloc(0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "PyMem_Malloc(0) returns NULL"); + return NULL; + } + PyMem_Free(ptr); + + ptr = PyMem_Calloc(0, 0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "PyMem_Calloc(0, 0) returns NULL"); + return NULL; + } + PyMem_Free(ptr); + + ptr = PyObject_Malloc(0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "PyObject_Malloc(0) returns NULL"); + return NULL; + } + PyObject_Free(ptr); + + ptr = PyObject_Calloc(0, 0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "PyObject_Calloc(0, 0) returns NULL"); + return NULL; + } + PyObject_Free(ptr); + + Py_RETURN_NONE; +} + +static PyObject * +test_pymem_getallocatorsname(PyObject *self, PyObject *args) +{ + const char *name = _PyMem_GetCurrentAllocatorName(); + if (name == NULL) { + PyErr_SetString(PyExc_RuntimeError, "cannot get allocators name"); + return NULL; + } + return PyUnicode_FromString(name); +} + +static PyObject * +test_pymem_setrawallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return test_setallocators(PYMEM_DOMAIN_RAW); +} + +static PyObject * +test_pymem_setallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return test_setallocators(PYMEM_DOMAIN_MEM); +} + +static PyObject * +pyobject_malloc_without_gil(PyObject *self, PyObject *args) +{ + char *buffer; + + /* Deliberate bug to test debug hooks on Python memory allocators: + call PyObject_Malloc() without holding the GIL */ + Py_BEGIN_ALLOW_THREADS + buffer = PyObject_Malloc(10); + Py_END_ALLOW_THREADS + + PyObject_Free(buffer); + + Py_RETURN_NONE; +} + +static PyObject * +pymem_buffer_overflow(PyObject *self, PyObject *args) +{ + char *buffer; + + /* Deliberate buffer overflow to check that PyMem_Free() detects + the overflow when debug hooks are installed. */ + buffer = PyMem_Malloc(16); + if (buffer == NULL) { + PyErr_NoMemory(); + return NULL; + } + buffer[16] = 'x'; + PyMem_Free(buffer); + + Py_RETURN_NONE; +} + +static PyObject * +pymem_api_misuse(PyObject *self, PyObject *args) +{ + char *buffer; + + /* Deliberate misusage of Python allocators: + allococate with PyMem but release with PyMem_Raw. */ + buffer = PyMem_Malloc(16); + PyMem_RawFree(buffer); + + Py_RETURN_NONE; +} + +static PyObject * +pymem_malloc_without_gil(PyObject *self, PyObject *args) +{ + char *buffer; + + /* Deliberate bug to test debug hooks on Python memory allocators: + call PyMem_Malloc() without holding the GIL */ + Py_BEGIN_ALLOW_THREADS + buffer = PyMem_Malloc(10); + Py_END_ALLOW_THREADS + + PyMem_Free(buffer); + + Py_RETURN_NONE; +} + +static PyObject * +test_pyobject_is_freed(const char *test_name, PyObject *op) +{ + if (!_PyObject_IsFreed(op)) { + PyErr_SetString(PyExc_AssertionError, + "object is not seen as freed"); + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +check_pyobject_null_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) +{ + PyObject *op = NULL; + return test_pyobject_is_freed("check_pyobject_null_is_freed", op); +} + + +static PyObject * +check_pyobject_uninitialized_is_freed(PyObject *self, + PyObject *Py_UNUSED(args)) +{ + PyObject *op = (PyObject *)PyObject_Malloc(sizeof(PyObject)); + if (op == NULL) { + return NULL; + } + /* Initialize reference count to avoid early crash in ceval or GC */ + Py_SET_REFCNT(op, 1); + /* object fields like ob_type are uninitialized! */ + return test_pyobject_is_freed("check_pyobject_uninitialized_is_freed", op); +} + + +static PyObject * +check_pyobject_forbidden_bytes_is_freed(PyObject *self, + PyObject *Py_UNUSED(args)) +{ + /* Allocate an incomplete PyObject structure: truncate 'ob_type' field */ + PyObject *op = (PyObject *)PyObject_Malloc(offsetof(PyObject, ob_type)); + if (op == NULL) { + return NULL; + } + /* Initialize reference count to avoid early crash in ceval or GC */ + Py_SET_REFCNT(op, 1); + /* ob_type field is after the memory block: part of "forbidden bytes" + when using debug hooks on memory allocators! */ + return test_pyobject_is_freed("check_pyobject_forbidden_bytes_is_freed", op); +} + + +static PyObject * +check_pyobject_freed_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) +{ + /* This test would fail if run with the address sanitizer */ +#ifdef _Py_ADDRESS_SANITIZER + Py_RETURN_NONE; +#else + PyObject *op = PyObject_CallNoArgs((PyObject *)&PyBaseObject_Type); + if (op == NULL) { + return NULL; + } + Py_TYPE(op)->tp_dealloc(op); + /* Reset reference count to avoid early crash in ceval or GC */ + Py_SET_REFCNT(op, 1); + /* object memory is freed! */ + return test_pyobject_is_freed("check_pyobject_freed_is_freed", op); +#endif +} + +// Tracemalloc tests +static PyObject * +tracemalloc_track(PyObject *self, PyObject *args) +{ + unsigned int domain; + PyObject *ptr_obj; + Py_ssize_t size; + int release_gil = 0; + + if (!PyArg_ParseTuple(args, "IOn|i", + &domain, &ptr_obj, &size, &release_gil)) + { + return NULL; + } + void *ptr = PyLong_AsVoidPtr(ptr_obj); + if (PyErr_Occurred()) { + return NULL; + } + + int res; + if (release_gil) { + Py_BEGIN_ALLOW_THREADS + res = PyTraceMalloc_Track(domain, (uintptr_t)ptr, size); + Py_END_ALLOW_THREADS + } + else { + res = PyTraceMalloc_Track(domain, (uintptr_t)ptr, size); + } + if (res < 0) { + PyErr_SetString(PyExc_RuntimeError, "PyTraceMalloc_Track error"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject * +tracemalloc_untrack(PyObject *self, PyObject *args) +{ + unsigned int domain; + PyObject *ptr_obj; + + if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj)) { + return NULL; + } + void *ptr = PyLong_AsVoidPtr(ptr_obj); + if (PyErr_Occurred()) { + return NULL; + } + + int res = PyTraceMalloc_Untrack(domain, (uintptr_t)ptr); + if (res < 0) { + PyErr_SetString(PyExc_RuntimeError, "PyTraceMalloc_Untrack error"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject * +tracemalloc_get_traceback(PyObject *self, PyObject *args) +{ + unsigned int domain; + PyObject *ptr_obj; + + if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj)) { + return NULL; + } + void *ptr = PyLong_AsVoidPtr(ptr_obj); + if (PyErr_Occurred()) { + return NULL; + } + + return _PyTraceMalloc_GetTraceback(domain, (uintptr_t)ptr); +} + +static PyMethodDef test_methods[] = { + {"check_pyobject_forbidden_bytes_is_freed", + check_pyobject_forbidden_bytes_is_freed, METH_NOARGS}, + {"check_pyobject_freed_is_freed", check_pyobject_freed_is_freed, METH_NOARGS}, + {"check_pyobject_null_is_freed", check_pyobject_null_is_freed, METH_NOARGS}, + {"check_pyobject_uninitialized_is_freed", + check_pyobject_uninitialized_is_freed, METH_NOARGS}, + {"pymem_api_misuse", pymem_api_misuse, METH_NOARGS}, + {"pymem_buffer_overflow", pymem_buffer_overflow, METH_NOARGS}, + {"pymem_getallocatorsname", test_pymem_getallocatorsname, METH_NOARGS}, + {"pymem_malloc_without_gil", pymem_malloc_without_gil, METH_NOARGS}, + {"pyobject_malloc_without_gil", pyobject_malloc_without_gil, METH_NOARGS}, + {"remove_mem_hooks", remove_mem_hooks, METH_NOARGS, + PyDoc_STR("Remove memory hooks.")}, + {"set_nomemory", (PyCFunction)set_nomemory, METH_VARARGS, + PyDoc_STR("set_nomemory(start:int, stop:int = 0)")}, + {"test_pymem_alloc0", test_pymem_alloc0, METH_NOARGS}, + {"test_pymem_setallocators", test_pymem_setallocators, METH_NOARGS}, + {"test_pymem_setrawallocators", test_pymem_setrawallocators, METH_NOARGS}, + {"test_pyobject_new", test_pyobject_new, METH_NOARGS}, + {"test_pyobject_setallocators", test_pyobject_setallocators, METH_NOARGS}, + + // Tracemalloc tests + {"tracemalloc_track", tracemalloc_track, METH_VARARGS}, + {"tracemalloc_untrack", tracemalloc_untrack, METH_VARARGS}, + {"tracemalloc_get_traceback", tracemalloc_get_traceback, METH_VARARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_Mem(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + + PyObject *v; +#ifdef WITH_PYMALLOC + v = Py_NewRef(Py_True); +#else + v = Py_NewRef(Py_False); +#endif + int rc = PyModule_AddObjectRef(mod, "WITH_PYMALLOC", v); + Py_DECREF(v); + if (rc < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h new file mode 100644 index 00000000000..7ba3c4ebff8 --- /dev/null +++ b/Modules/_testcapi/parts.h @@ -0,0 +1,45 @@ +#ifndef Py_TESTCAPI_PARTS_H +#define Py_TESTCAPI_PARTS_H + +#include "pyconfig.h" // for Py_TRACE_REFS + +// Figure out if Limited API is available for this build. If it isn't we won't +// build tests for it. +// Currently, only Py_TRACE_REFS disables Limited API. +#ifdef Py_TRACE_REFS +#undef LIMITED_API_AVAILABLE +#else +#define LIMITED_API_AVAILABLE 1 +#endif + +// Always enable assertions +#undef NDEBUG + +#if !defined(LIMITED_API_AVAILABLE) && defined(Py_LIMITED_API) +// Limited API being unavailable means that with Py_LIMITED_API defined +// we can't even include Python.h. +// Do nothing; the .c file that defined Py_LIMITED_API should also do nothing. + +#else + +#include "Python.h" + +int _PyTestCapi_Init_Vectorcall(PyObject *module); +int _PyTestCapi_Init_Heaptype(PyObject *module); +int _PyTestCapi_Init_Unicode(PyObject *module); +int _PyTestCapi_Init_GetArgs(PyObject *module); +int _PyTestCapi_Init_PyTime(PyObject *module); +int _PyTestCapi_Init_DateTime(PyObject *module); +int _PyTestCapi_Init_Docstring(PyObject *module); +int _PyTestCapi_Init_Mem(PyObject *module); +int _PyTestCapi_Init_Watchers(PyObject *module); +int _PyTestCapi_Init_Long(PyObject *module); +int _PyTestCapi_Init_Float(PyObject *module); +int _PyTestCapi_Init_Structmember(PyObject *module); + +#ifdef LIMITED_API_AVAILABLE +int _PyTestCapi_Init_VectorcallLimited(PyObject *module); +#endif // LIMITED_API_AVAILABLE + +#endif +#endif // Py_TESTCAPI_PARTS_H diff --git a/Modules/_testcapi/pytime.c b/Modules/_testcapi/pytime.c new file mode 100644 index 00000000000..7422bafc301 --- /dev/null +++ b/Modules/_testcapi/pytime.c @@ -0,0 +1,274 @@ +#include "parts.h" + +#ifdef MS_WINDOWS +# include // struct timeval +#endif + +static PyObject * +test_pytime_fromseconds(PyObject *self, PyObject *args) +{ + int seconds; + if (!PyArg_ParseTuple(args, "i", &seconds)) { + return NULL; + } + _PyTime_t ts = _PyTime_FromSeconds(seconds); + return _PyTime_AsNanosecondsObject(ts); +} + +static int +check_time_rounding(int round) +{ + if (round != _PyTime_ROUND_FLOOR + && round != _PyTime_ROUND_CEILING + && round != _PyTime_ROUND_HALF_EVEN + && round != _PyTime_ROUND_UP) + { + PyErr_SetString(PyExc_ValueError, "invalid rounding"); + return -1; + } + return 0; +} + +static PyObject * +test_pytime_fromsecondsobject(PyObject *self, PyObject *args) +{ + PyObject *obj; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + _PyTime_t ts; + if (_PyTime_FromSecondsObject(&ts, obj, round) == -1) { + return NULL; + } + return _PyTime_AsNanosecondsObject(ts); +} + +static PyObject * +test_pytime_assecondsdouble(PyObject *self, PyObject *args) +{ + PyObject *obj; + if (!PyArg_ParseTuple(args, "O", &obj)) { + return NULL; + } + _PyTime_t ts; + if (_PyTime_FromNanosecondsObject(&ts, obj) < 0) { + return NULL; + } + double d = _PyTime_AsSecondsDouble(ts); + return PyFloat_FromDouble(d); +} + +static PyObject * +test_PyTime_AsTimeval(PyObject *self, PyObject *args) +{ + PyObject *obj; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + struct timeval tv; + if (_PyTime_AsTimeval(t, &tv, round) < 0) { + return NULL; + } + + PyObject *seconds = PyLong_FromLongLong(tv.tv_sec); + if (seconds == NULL) { + return NULL; + } + return Py_BuildValue("Nl", seconds, (long)tv.tv_usec); +} + +static PyObject * +test_PyTime_AsTimeval_clamp(PyObject *self, PyObject *args) +{ + PyObject *obj; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + struct timeval tv; + _PyTime_AsTimeval_clamp(t, &tv, round); + + PyObject *seconds = PyLong_FromLongLong(tv.tv_sec); + if (seconds == NULL) { + return NULL; + } + return Py_BuildValue("Nl", seconds, (long)tv.tv_usec); +} + +#ifdef HAVE_CLOCK_GETTIME +static PyObject * +test_PyTime_AsTimespec(PyObject *self, PyObject *args) +{ + PyObject *obj; + if (!PyArg_ParseTuple(args, "O", &obj)) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + struct timespec ts; + if (_PyTime_AsTimespec(t, &ts) == -1) { + return NULL; + } + return Py_BuildValue("Nl", _PyLong_FromTime_t(ts.tv_sec), ts.tv_nsec); +} + +static PyObject * +test_PyTime_AsTimespec_clamp(PyObject *self, PyObject *args) +{ + PyObject *obj; + if (!PyArg_ParseTuple(args, "O", &obj)) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + struct timespec ts; + _PyTime_AsTimespec_clamp(t, &ts); + return Py_BuildValue("Nl", _PyLong_FromTime_t(ts.tv_sec), ts.tv_nsec); +} +#endif + +static PyObject * +test_PyTime_AsMilliseconds(PyObject *self, PyObject *args) +{ + PyObject *obj; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + _PyTime_t ms = _PyTime_AsMilliseconds(t, round); + _PyTime_t ns = _PyTime_FromNanoseconds(ms); + return _PyTime_AsNanosecondsObject(ns); +} + +static PyObject * +test_PyTime_AsMicroseconds(PyObject *self, PyObject *args) +{ + PyObject *obj; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + _PyTime_t us = _PyTime_AsMicroseconds(t, round); + _PyTime_t ns = _PyTime_FromNanoseconds(us); + return _PyTime_AsNanosecondsObject(ns); +} + +static PyObject * +test_pytime_object_to_time_t(PyObject *self, PyObject *args) +{ + PyObject *obj; + time_t sec; + int round; + if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_time_t", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + if (_PyTime_ObjectToTime_t(obj, &sec, round) == -1) { + return NULL; + } + return _PyLong_FromTime_t(sec); +} + +static PyObject * +test_pytime_object_to_timeval(PyObject *self, PyObject *args) +{ + PyObject *obj; + time_t sec; + long usec; + int round; + if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_timeval", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + if (_PyTime_ObjectToTimeval(obj, &sec, &usec, round) == -1) { + return NULL; + } + return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), usec); +} + +static PyObject * +test_pytime_object_to_timespec(PyObject *self, PyObject *args) +{ + PyObject *obj; + time_t sec; + long nsec; + int round; + if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_timespec", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + if (_PyTime_ObjectToTimespec(obj, &sec, &nsec, round) == -1) { + return NULL; + } + return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), nsec); +} + +static PyMethodDef test_methods[] = { + {"PyTime_AsMicroseconds", test_PyTime_AsMicroseconds, METH_VARARGS}, + {"PyTime_AsMilliseconds", test_PyTime_AsMilliseconds, METH_VARARGS}, + {"PyTime_AsSecondsDouble", test_pytime_assecondsdouble, METH_VARARGS}, +#ifdef HAVE_CLOCK_GETTIME + {"PyTime_AsTimespec", test_PyTime_AsTimespec, METH_VARARGS}, + {"PyTime_AsTimespec_clamp", test_PyTime_AsTimespec_clamp, METH_VARARGS}, +#endif + {"PyTime_AsTimeval", test_PyTime_AsTimeval, METH_VARARGS}, + {"PyTime_AsTimeval_clamp", test_PyTime_AsTimeval_clamp, METH_VARARGS}, + {"PyTime_FromSeconds", test_pytime_fromseconds, METH_VARARGS}, + {"PyTime_FromSecondsObject", test_pytime_fromsecondsobject, METH_VARARGS}, + {"pytime_object_to_time_t", test_pytime_object_to_time_t, METH_VARARGS}, + {"pytime_object_to_timespec", test_pytime_object_to_timespec, METH_VARARGS}, + {"pytime_object_to_timeval", test_pytime_object_to_timeval, METH_VARARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_PyTime(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + return 0; +} diff --git a/Modules/_testcapi/structmember.c b/Modules/_testcapi/structmember.c new file mode 100644 index 00000000000..0fb872a4328 --- /dev/null +++ b/Modules/_testcapi/structmember.c @@ -0,0 +1,217 @@ +#define PY_SSIZE_T_CLEAN +#include "parts.h" +#include // for offsetof() + + +// This defines two classes that contain all the simple member types, one +// using "new" Py_-prefixed API, and the other using "old" . +// They should behave identically in Python. + +typedef struct { + char bool_member; + char byte_member; + unsigned char ubyte_member; + short short_member; + unsigned short ushort_member; + int int_member; + unsigned int uint_member; + long long_member; + unsigned long ulong_member; + Py_ssize_t pyssizet_member; + float float_member; + double double_member; + char inplace_member[6]; + long long longlong_member; + unsigned long long ulonglong_member; +} all_structmembers; + +typedef struct { + PyObject_HEAD + all_structmembers structmembers; +} test_structmembers; + + +static struct PyMemberDef test_members_newapi[] = { + {"T_BOOL", Py_T_BOOL, offsetof(test_structmembers, structmembers.bool_member), 0, NULL}, + {"T_BYTE", Py_T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL}, + {"T_UBYTE", Py_T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL}, + {"T_SHORT", Py_T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL}, + {"T_USHORT", Py_T_USHORT, offsetof(test_structmembers, structmembers.ushort_member), 0, NULL}, + {"T_INT", Py_T_INT, offsetof(test_structmembers, structmembers.int_member), 0, NULL}, + {"T_UINT", Py_T_UINT, offsetof(test_structmembers, structmembers.uint_member), 0, NULL}, + {"T_LONG", Py_T_LONG, offsetof(test_structmembers, structmembers.long_member), 0, NULL}, + {"T_ULONG", Py_T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL}, + {"T_PYSSIZET", Py_T_PYSSIZET, offsetof(test_structmembers, structmembers.pyssizet_member), 0, NULL}, + {"T_FLOAT", Py_T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL}, + {"T_DOUBLE", Py_T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL}, + {"T_STRING_INPLACE", Py_T_STRING_INPLACE, offsetof(test_structmembers, structmembers.inplace_member), 0, NULL}, + {"T_LONGLONG", Py_T_LONGLONG, offsetof(test_structmembers, structmembers.longlong_member), 0, NULL}, + {"T_ULONGLONG", Py_T_ULONGLONG, offsetof(test_structmembers, structmembers.ulonglong_member), 0, NULL}, + {NULL} +}; + +static PyObject * +test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + static char *keywords[] = { + "T_BOOL", "T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", + "T_INT", "T_UINT", "T_LONG", "T_ULONG", "T_PYSSIZET", + "T_FLOAT", "T_DOUBLE", "T_STRING_INPLACE", + "T_LONGLONG", "T_ULONGLONG", + NULL}; + static const char fmt[] = "|bbBhHiIlknfds#LK"; + test_structmembers *ob; + const char *s = NULL; + Py_ssize_t string_len = 0; + ob = PyObject_New(test_structmembers, type); + if (ob == NULL) { + return NULL; + } + memset(&ob->structmembers, 0, sizeof(all_structmembers)); + if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords, + &ob->structmembers.bool_member, + &ob->structmembers.byte_member, + &ob->structmembers.ubyte_member, + &ob->structmembers.short_member, + &ob->structmembers.ushort_member, + &ob->structmembers.int_member, + &ob->structmembers.uint_member, + &ob->structmembers.long_member, + &ob->structmembers.ulong_member, + &ob->structmembers.pyssizet_member, + &ob->structmembers.float_member, + &ob->structmembers.double_member, + &s, &string_len, + &ob->structmembers.longlong_member, + &ob->structmembers.ulonglong_member)) + { + Py_DECREF(ob); + return NULL; + } + if (s != NULL) { + if (string_len > 5) { + Py_DECREF(ob); + PyErr_SetString(PyExc_ValueError, "string too long"); + return NULL; + } + strcpy(ob->structmembers.inplace_member, s); + } + else { + strcpy(ob->structmembers.inplace_member, ""); + } + return (PyObject *)ob; +} + +static PyType_Slot test_structmembers_slots[] = { + {Py_tp_new, test_structmembers_new}, + {Py_tp_members, test_members_newapi}, + {0}, +}; + +static PyType_Spec test_structmembers_spec = { + .name = "_testcapi._test_structmembersType_NewAPI", + .flags = Py_TPFLAGS_DEFAULT, + .basicsize = sizeof(test_structmembers), + .slots = test_structmembers_slots, +}; + +#include + +static struct PyMemberDef test_members[] = { + {"T_BOOL", T_BOOL, offsetof(test_structmembers, structmembers.bool_member), 0, NULL}, + {"T_BYTE", T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL}, + {"T_UBYTE", T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL}, + {"T_SHORT", T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL}, + {"T_USHORT", T_USHORT, offsetof(test_structmembers, structmembers.ushort_member), 0, NULL}, + {"T_INT", T_INT, offsetof(test_structmembers, structmembers.int_member), 0, NULL}, + {"T_UINT", T_UINT, offsetof(test_structmembers, structmembers.uint_member), 0, NULL}, + {"T_LONG", T_LONG, offsetof(test_structmembers, structmembers.long_member), 0, NULL}, + {"T_ULONG", T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL}, + {"T_PYSSIZET", T_PYSSIZET, offsetof(test_structmembers, structmembers.pyssizet_member), 0, NULL}, + {"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL}, + {"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL}, + {"T_STRING_INPLACE", T_STRING_INPLACE, offsetof(test_structmembers, structmembers.inplace_member), 0, NULL}, + {"T_LONGLONG", T_LONGLONG, offsetof(test_structmembers, structmembers.longlong_member), 0, NULL}, + {"T_ULONGLONG", T_ULONGLONG, offsetof(test_structmembers, structmembers.ulonglong_member), 0, NULL}, + {NULL} +}; + + +static void +test_structmembers_free(PyObject *ob) +{ + PyObject_Free(ob); +} + +/* Designated initializers would work too, but this does test the *old* API */ +static PyTypeObject test_structmembersType_OldAPI= { + PyVarObject_HEAD_INIT(NULL, 0) + "test_structmembersType_OldAPI", + sizeof(test_structmembers), /* tp_basicsize */ + 0, /* tp_itemsize */ + test_structmembers_free, /* destructor tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + "Type containing all structmember types", + 0, /* traverseproc tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + test_members, /* tp_members */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + test_structmembers_new, /* tp_new */ +}; + + +int +_PyTestCapi_Init_Structmember(PyObject *m) +{ + int res; + res = PyType_Ready(&test_structmembersType_OldAPI); + if (res < 0) { + return -1; + } + res = PyModule_AddObject( + m, + "_test_structmembersType_OldAPI", + (PyObject *)&test_structmembersType_OldAPI); + if (res < 0) { + return -1; + } + + PyObject *test_structmembersType_NewAPI = PyType_FromModuleAndSpec( + m, &test_structmembers_spec, NULL); + if (!test_structmembersType_NewAPI) { + return -1; + } + res = PyModule_AddType(m, (PyTypeObject*)test_structmembersType_NewAPI); + Py_DECREF(test_structmembersType_NewAPI); + if (res < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/testcapi_long.h b/Modules/_testcapi/testcapi_long.h similarity index 99% rename from Modules/testcapi_long.h rename to Modules/_testcapi/testcapi_long.h index 6bddad7bb5d..143258140b4 100644 --- a/Modules/testcapi_long.h +++ b/Modules/_testcapi/testcapi_long.h @@ -202,6 +202,5 @@ TESTNAME(PyObject *error(const char*)) Py_DECREF(Py_None); } - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } diff --git a/Modules/_testcapi/unicode.c b/Modules/_testcapi/unicode.c new file mode 100644 index 00000000000..2d23993ce42 --- /dev/null +++ b/Modules/_testcapi/unicode.c @@ -0,0 +1,1096 @@ +#define PY_SSIZE_T_CLEAN +#include "parts.h" + +static struct PyModuleDef *_testcapimodule = NULL; // set at initialization + +static PyObject * +codec_incrementalencoder(PyObject *self, PyObject *args) +{ + const char *encoding, *errors = NULL; + if (!PyArg_ParseTuple(args, "s|s:test_incrementalencoder", + &encoding, &errors)) + return NULL; + return PyCodec_IncrementalEncoder(encoding, errors); +} + +static PyObject * +codec_incrementaldecoder(PyObject *self, PyObject *args) +{ + const char *encoding, *errors = NULL; + if (!PyArg_ParseTuple(args, "s|s:test_incrementaldecoder", + &encoding, &errors)) + return NULL; + return PyCodec_IncrementalDecoder(encoding, errors); +} + +static PyObject * +test_unicode_compare_with_ascii(PyObject *self, PyObject *Py_UNUSED(ignored)) { + PyObject *py_s = PyUnicode_FromStringAndSize("str\0", 4); + int result; + if (py_s == NULL) + return NULL; + result = PyUnicode_CompareWithASCIIString(py_s, "str"); + Py_DECREF(py_s); + if (!result) { + PyErr_SetString(PyExc_AssertionError, "Python string ending in NULL " + "should not compare equal to c string."); + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +test_widechar(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ +#if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4) + const wchar_t wtext[2] = {(wchar_t)0x10ABCDu}; + size_t wtextlen = 1; + const wchar_t invalid[1] = {(wchar_t)0x110000u}; +#else + const wchar_t wtext[3] = {(wchar_t)0xDBEAu, (wchar_t)0xDFCDu}; + size_t wtextlen = 2; +#endif + PyObject *wide, *utf8; + + wide = PyUnicode_FromWideChar(wtext, wtextlen); + if (wide == NULL) + return NULL; + + utf8 = PyUnicode_FromString("\xf4\x8a\xaf\x8d"); + if (utf8 == NULL) { + Py_DECREF(wide); + return NULL; + } + + if (PyUnicode_GET_LENGTH(wide) != PyUnicode_GET_LENGTH(utf8)) { + Py_DECREF(wide); + Py_DECREF(utf8); + PyErr_SetString(PyExc_AssertionError, + "test_widechar: " + "wide string and utf8 string " + "have different length"); + return NULL; + } + if (PyUnicode_Compare(wide, utf8)) { + Py_DECREF(wide); + Py_DECREF(utf8); + if (PyErr_Occurred()) + return NULL; + PyErr_SetString(PyExc_AssertionError, + "test_widechar: " + "wide string and utf8 string " + "are different"); + return NULL; + } + + Py_DECREF(wide); + Py_DECREF(utf8); + +#if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4) + wide = PyUnicode_FromWideChar(invalid, 1); + if (wide == NULL) + PyErr_Clear(); + else { + PyErr_SetString(PyExc_AssertionError, + "test_widechar: " + "PyUnicode_FromWideChar(L\"\\U00110000\", 1) didn't fail"); + return NULL; + } +#endif + Py_RETURN_NONE; +} + +#define NULLABLE(x) do { if (x == Py_None) x = NULL; } while (0); + +/* Test PyUnicode_FromObject() */ +static PyObject * +unicode_fromobject(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyUnicode_FromObject(arg); +} + +/* Test PyUnicode_AsWideChar() */ +static PyObject * +unicode_aswidechar(PyObject *self, PyObject *args) +{ + PyObject *unicode, *result; + Py_ssize_t buflen, size; + wchar_t *buffer; + + if (!PyArg_ParseTuple(args, "Un", &unicode, &buflen)) + return NULL; + buffer = PyMem_New(wchar_t, buflen); + if (buffer == NULL) + return PyErr_NoMemory(); + + size = PyUnicode_AsWideChar(unicode, buffer, buflen); + if (size == -1) { + PyMem_Free(buffer); + return NULL; + } + + if (size < buflen) + buflen = size + 1; + else + buflen = size; + result = PyUnicode_FromWideChar(buffer, buflen); + PyMem_Free(buffer); + if (result == NULL) + return NULL; + + return Py_BuildValue("(Nn)", result, size); +} + +/* Test PyUnicode_AsWideCharString() */ +static PyObject * +unicode_aswidecharstring(PyObject *self, PyObject *args) +{ + PyObject *unicode, *result; + Py_ssize_t size; + wchar_t *buffer; + + if (!PyArg_ParseTuple(args, "U", &unicode)) + return NULL; + + buffer = PyUnicode_AsWideCharString(unicode, &size); + if (buffer == NULL) + return NULL; + + result = PyUnicode_FromWideChar(buffer, size + 1); + PyMem_Free(buffer); + if (result == NULL) + return NULL; + return Py_BuildValue("(Nn)", result, size); +} + +/* Test PyUnicode_AsUCS4() */ +static PyObject * +unicode_asucs4(PyObject *self, PyObject *args) +{ + PyObject *unicode, *result; + Py_UCS4 *buffer; + int copy_null; + Py_ssize_t str_len, buf_len; + + if (!PyArg_ParseTuple(args, "Unp:unicode_asucs4", &unicode, &str_len, ©_null)) { + return NULL; + } + + buf_len = str_len + 1; + buffer = PyMem_NEW(Py_UCS4, buf_len); + if (buffer == NULL) { + return PyErr_NoMemory(); + } + memset(buffer, 0, sizeof(Py_UCS4)*buf_len); + buffer[str_len] = 0xffffU; + + if (!PyUnicode_AsUCS4(unicode, buffer, buf_len, copy_null)) { + PyMem_Free(buffer); + return NULL; + } + + result = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, buffer, buf_len); + PyMem_Free(buffer); + return result; +} + +/* Test PyUnicode_AsUTF8() */ +static PyObject * +unicode_asutf8(PyObject *self, PyObject *args) +{ + PyObject *unicode; + const char *buffer; + + if (!PyArg_ParseTuple(args, "U", &unicode)) { + return NULL; + } + + buffer = PyUnicode_AsUTF8(unicode); + if (buffer == NULL) { + return NULL; + } + + return PyBytes_FromString(buffer); +} + +/* Test PyUnicode_AsUTF8AndSize() */ +static PyObject * +unicode_asutf8andsize(PyObject *self, PyObject *args) +{ + PyObject *unicode, *result; + const char *buffer; + Py_ssize_t utf8_len; + + if(!PyArg_ParseTuple(args, "U", &unicode)) { + return NULL; + } + + buffer = PyUnicode_AsUTF8AndSize(unicode, &utf8_len); + if (buffer == NULL) { + return NULL; + } + + result = PyBytes_FromString(buffer); + if (result == NULL) { + return NULL; + } + + return Py_BuildValue("(Nn)", result, utf8_len); +} + +/* Test PyUnicode_DecodeUTF8() */ +static PyObject * +unicode_decodeutf8(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) + return NULL; + + return PyUnicode_DecodeUTF8(data, size, errors); +} + +/* Test PyUnicode_DecodeUTF8Stateful() */ +static PyObject * +unicode_decodeutf8stateful(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors = NULL; + Py_ssize_t consumed = 123456789; + PyObject *result; + + if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) + return NULL; + + result = PyUnicode_DecodeUTF8Stateful(data, size, errors, &consumed); + if (!result) { + return NULL; + } + return Py_BuildValue("(Nn)", result, consumed); +} + +/* Test PyUnicode_Concat() */ +static PyObject * +unicode_concat(PyObject *self, PyObject *args) +{ + PyObject *left; + PyObject *right; + + if (!PyArg_ParseTuple(args, "OO", &left, &right)) + return NULL; + + NULLABLE(left); + NULLABLE(right); + return PyUnicode_Concat(left, right); +} + +/* Test PyUnicode_Split() */ +static PyObject * +unicode_split(PyObject *self, PyObject *args) +{ + PyObject *s; + PyObject *sep; + Py_ssize_t maxsplit = -1; + + if (!PyArg_ParseTuple(args, "OO|n", &s, &sep, &maxsplit)) + return NULL; + + NULLABLE(s); + NULLABLE(sep); + return PyUnicode_Split(s, sep, maxsplit); +} + +/* Test PyUnicode_RSplit() */ +static PyObject * +unicode_rsplit(PyObject *self, PyObject *args) +{ + PyObject *s; + PyObject *sep; + Py_ssize_t maxsplit = -1; + + if (!PyArg_ParseTuple(args, "OO|n", &s, &sep, &maxsplit)) + return NULL; + + NULLABLE(s); + NULLABLE(sep); + return PyUnicode_RSplit(s, sep, maxsplit); +} + +/* Test PyUnicode_Splitlines() */ +static PyObject * +unicode_splitlines(PyObject *self, PyObject *args) +{ + PyObject *s; + int keepends = 0; + + if (!PyArg_ParseTuple(args, "O|i", &s, &keepends)) + return NULL; + + NULLABLE(s); + return PyUnicode_Splitlines(s, keepends); +} + +/* Test PyUnicode_Partition() */ +static PyObject * +unicode_partition(PyObject *self, PyObject *args) +{ + PyObject *s; + PyObject *sep; + + if (!PyArg_ParseTuple(args, "OO", &s, &sep)) + return NULL; + + NULLABLE(s); + NULLABLE(sep); + return PyUnicode_Partition(s, sep); +} + +/* Test PyUnicode_RPartition() */ +static PyObject * +unicode_rpartition(PyObject *self, PyObject *args) +{ + PyObject *s; + PyObject *sep; + + if (!PyArg_ParseTuple(args, "OO", &s, &sep)) + return NULL; + + NULLABLE(s); + NULLABLE(sep); + return PyUnicode_RPartition(s, sep); +} + +/* Test PyUnicode_Translate() */ +static PyObject * +unicode_translate(PyObject *self, PyObject *args) +{ + PyObject *obj; + PyObject *table; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "OO|z", &obj, &table, &errors)) + return NULL; + + NULLABLE(obj); + NULLABLE(table); + return PyUnicode_Translate(obj, table, errors); +} + +/* Test PyUnicode_Join() */ +static PyObject * +unicode_join(PyObject *self, PyObject *args) +{ + PyObject *sep; + PyObject *seq; + + if (!PyArg_ParseTuple(args, "OO", &sep, &seq)) + return NULL; + + NULLABLE(sep); + NULLABLE(seq); + return PyUnicode_Join(sep, seq); +} + +/* Test PyUnicode_Count() */ +static PyObject * +unicode_count(PyObject *self, PyObject *args) +{ + PyObject *str; + PyObject *substr; + Py_ssize_t start; + Py_ssize_t end; + Py_ssize_t result; + + if (!PyArg_ParseTuple(args, "OOnn", &str, &substr, &start, &end)) + return NULL; + + NULLABLE(str); + NULLABLE(substr); + result = PyUnicode_Count(str, substr, start, end); + if (result == -1) + return NULL; + return PyLong_FromSsize_t(result); +} + +/* Test PyUnicode_Find() */ +static PyObject * +unicode_find(PyObject *self, PyObject *args) +{ + PyObject *str; + PyObject *substr; + Py_ssize_t start; + Py_ssize_t end; + int direction; + Py_ssize_t result; + + if (!PyArg_ParseTuple(args, "OOnni", &str, &substr, &start, &end, &direction)) + return NULL; + + NULLABLE(str); + NULLABLE(substr); + result = PyUnicode_Find(str, substr, start, end, direction); + if (result == -2) + return NULL; + return PyLong_FromSsize_t(result); +} + +/* Test PyUnicode_Tailmatch() */ +static PyObject * +unicode_tailmatch(PyObject *self, PyObject *args) +{ + PyObject *str; + PyObject *substr; + Py_ssize_t start; + Py_ssize_t end; + int direction; + Py_ssize_t result; + + if (!PyArg_ParseTuple(args, "OOnni", &str, &substr, &start, &end, &direction)) + return NULL; + + NULLABLE(str); + NULLABLE(substr); + result = PyUnicode_Tailmatch(str, substr, start, end, direction); + if (result == -1) + return NULL; + return PyLong_FromSsize_t(result); +} + +/* Test PyUnicode_FindChar() */ +static PyObject * +unicode_findchar(PyObject *self, PyObject *args) +{ + PyObject *str; + int direction; + unsigned int ch; + Py_ssize_t result; + Py_ssize_t start, end; + + if (!PyArg_ParseTuple(args, "UInni:unicode_findchar", &str, &ch, + &start, &end, &direction)) { + return NULL; + } + + result = PyUnicode_FindChar(str, (Py_UCS4)ch, start, end, direction); + if (result == -2) + return NULL; + else + return PyLong_FromSsize_t(result); +} + +/* Test PyUnicode_Replace() */ +static PyObject * +unicode_replace(PyObject *self, PyObject *args) +{ + PyObject *str; + PyObject *substr; + PyObject *replstr; + Py_ssize_t maxcount = -1; + + if (!PyArg_ParseTuple(args, "OOO|n", &str, &substr, &replstr, &maxcount)) + return NULL; + + NULLABLE(str); + NULLABLE(substr); + NULLABLE(replstr); + return PyUnicode_Replace(str, substr, replstr, maxcount); +} + +/* Test PyUnicode_Compare() */ +static PyObject * +unicode_compare(PyObject *self, PyObject *args) +{ + PyObject *left; + PyObject *right; + int result; + + if (!PyArg_ParseTuple(args, "OO", &left, &right)) + return NULL; + + NULLABLE(left); + NULLABLE(right); + result = PyUnicode_Compare(left, right); + if (result == -1 && PyErr_Occurred()) { + return NULL; + } + return PyLong_FromLong(result); +} + +/* Test PyUnicode_CompareWithASCIIString() */ +static PyObject * +unicode_comparewithasciistring(PyObject *self, PyObject *args) +{ + PyObject *left; + const char *right = NULL; + Py_ssize_t right_len; + int result; + + if (!PyArg_ParseTuple(args, "O|y#", &left, &right, &right_len)) + return NULL; + + NULLABLE(left); + result = PyUnicode_CompareWithASCIIString(left, right); + if (result == -1 && PyErr_Occurred()) { + return NULL; + } + return PyLong_FromLong(result); +} + +/* Test PyUnicode_RichCompare() */ +static PyObject * +unicode_richcompare(PyObject *self, PyObject *args) +{ + PyObject *left; + PyObject *right; + int op; + + if (!PyArg_ParseTuple(args, "OOi", &left, &right, &op)) + return NULL; + + NULLABLE(left); + NULLABLE(right); + return PyUnicode_RichCompare(left, right, op); +} + +/* Test PyUnicode_Format() */ +static PyObject * +unicode_format(PyObject *self, PyObject *args) +{ + PyObject *format; + PyObject *fargs; + + if (!PyArg_ParseTuple(args, "OO", &format, &fargs)) + return NULL; + + NULLABLE(format); + NULLABLE(fargs); + return PyUnicode_Format(format, fargs); +} + +/* Test PyUnicode_Contains() */ +static PyObject * +unicode_contains(PyObject *self, PyObject *args) +{ + PyObject *container; + PyObject *element; + int result; + + if (!PyArg_ParseTuple(args, "OO", &container, &element)) + return NULL; + + NULLABLE(container); + NULLABLE(element); + result = PyUnicode_Contains(container, element); + if (result == -1 && PyErr_Occurred()) { + return NULL; + } + return PyLong_FromLong(result); +} + +/* Test PyUnicode_IsIdentifier() */ +static PyObject * +unicode_isidentifier(PyObject *self, PyObject *arg) +{ + int result; + + NULLABLE(arg); + result = PyUnicode_IsIdentifier(arg); + if (result == -1 && PyErr_Occurred()) { + return NULL; + } + return PyLong_FromLong(result); +} + +/* Test PyUnicode_CopyCharacters() */ +static PyObject * +unicode_copycharacters(PyObject *self, PyObject *args) +{ + PyObject *from, *to, *to_copy; + Py_ssize_t from_start, to_start, how_many, copied; + + if (!PyArg_ParseTuple(args, "UnOnn:unicode_copycharacters", &to, &to_start, + &from, &from_start, &how_many)) { + return NULL; + } + + if (!(to_copy = PyUnicode_New(PyUnicode_GET_LENGTH(to), + PyUnicode_MAX_CHAR_VALUE(to)))) { + return NULL; + } + if (PyUnicode_Fill(to_copy, 0, PyUnicode_GET_LENGTH(to_copy), 0U) < 0) { + Py_DECREF(to_copy); + return NULL; + } + + if ((copied = PyUnicode_CopyCharacters(to_copy, to_start, from, + from_start, how_many)) < 0) { + Py_DECREF(to_copy); + return NULL; + } + + return Py_BuildValue("(Nn)", to_copy, copied); +} + +static int +check_raised_systemerror(PyObject *result, char* msg) +{ + if (result) { + // no exception + PyErr_Format(PyExc_AssertionError, + "SystemError not raised: %s", + msg); + return 0; + } + if (PyErr_ExceptionMatches(PyExc_SystemError)) { + // expected exception + PyErr_Clear(); + return 1; + } + // unexpected exception + return 0; +} + +static PyObject * +test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *result; + PyObject *unicode = PyUnicode_FromString("None"); + +#define CHECK_FORMAT_2(FORMAT, EXPECTED, ARG1, ARG2) \ + result = PyUnicode_FromFormat(FORMAT, ARG1, ARG2); \ + if (EXPECTED == NULL) { \ + if (!check_raised_systemerror(result, FORMAT)) { \ + goto Fail; \ + } \ + } \ + else if (result == NULL) \ + return NULL; \ + else if (!_PyUnicode_EqualToASCIIString(result, EXPECTED)) { \ + PyErr_Format(PyExc_AssertionError, \ + "test_string_from_format: failed at \"%s\" " \ + "expected \"%s\" got \"%s\"", \ + FORMAT, EXPECTED, PyUnicode_AsUTF8(result)); \ + goto Fail; \ + } \ + Py_XDECREF(result) + +#define CHECK_FORMAT_1(FORMAT, EXPECTED, ARG) \ + CHECK_FORMAT_2(FORMAT, EXPECTED, ARG, 0) + +#define CHECK_FORMAT_0(FORMAT, EXPECTED) \ + CHECK_FORMAT_2(FORMAT, EXPECTED, 0, 0) + + // Unrecognized + CHECK_FORMAT_2("%u %? %u", NULL, 1, 2); + + // "%%" (options are rejected) + CHECK_FORMAT_0( "%%", "%"); + CHECK_FORMAT_0( "%0%", NULL); + CHECK_FORMAT_0("%00%", NULL); + CHECK_FORMAT_0( "%2%", NULL); + CHECK_FORMAT_0("%02%", NULL); + CHECK_FORMAT_0("%.0%", NULL); + CHECK_FORMAT_0("%.2%", NULL); + + // "%c" + CHECK_FORMAT_1( "%c", "c", 'c'); + CHECK_FORMAT_1( "%0c", "c", 'c'); + CHECK_FORMAT_1("%00c", "c", 'c'); + CHECK_FORMAT_1( "%2c", "c", 'c'); + CHECK_FORMAT_1("%02c", "c", 'c'); + CHECK_FORMAT_1("%.0c", "c", 'c'); + CHECK_FORMAT_1("%.2c", "c", 'c'); + + // Integers + CHECK_FORMAT_1("%d", "123", (int)123); + CHECK_FORMAT_1("%i", "123", (int)123); + CHECK_FORMAT_1("%u", "123", (unsigned int)123); + CHECK_FORMAT_1("%ld", "123", (long)123); + CHECK_FORMAT_1("%li", "123", (long)123); + CHECK_FORMAT_1("%lu", "123", (unsigned long)123); + CHECK_FORMAT_1("%lld", "123", (long long)123); + CHECK_FORMAT_1("%lli", "123", (long long)123); + CHECK_FORMAT_1("%llu", "123", (unsigned long long)123); + CHECK_FORMAT_1("%zd", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%zi", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%zu", "123", (size_t)123); + CHECK_FORMAT_1("%x", "7b", (int)123); + + CHECK_FORMAT_1("%d", "-123", (int)-123); + CHECK_FORMAT_1("%i", "-123", (int)-123); + CHECK_FORMAT_1("%ld", "-123", (long)-123); + CHECK_FORMAT_1("%li", "-123", (long)-123); + CHECK_FORMAT_1("%lld", "-123", (long long)-123); + CHECK_FORMAT_1("%lli", "-123", (long long)-123); + CHECK_FORMAT_1("%zd", "-123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%zi", "-123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%x", "ffffff85", (int)-123); + + // Integers: width < length + CHECK_FORMAT_1("%1d", "123", (int)123); + CHECK_FORMAT_1("%1i", "123", (int)123); + CHECK_FORMAT_1("%1u", "123", (unsigned int)123); + CHECK_FORMAT_1("%1ld", "123", (long)123); + CHECK_FORMAT_1("%1li", "123", (long)123); + CHECK_FORMAT_1("%1lu", "123", (unsigned long)123); + CHECK_FORMAT_1("%1lld", "123", (long long)123); + CHECK_FORMAT_1("%1lli", "123", (long long)123); + CHECK_FORMAT_1("%1llu", "123", (unsigned long long)123); + CHECK_FORMAT_1("%1zd", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%1zi", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%1zu", "123", (size_t)123); + CHECK_FORMAT_1("%1x", "7b", (int)123); + + CHECK_FORMAT_1("%1d", "-123", (int)-123); + CHECK_FORMAT_1("%1i", "-123", (int)-123); + CHECK_FORMAT_1("%1ld", "-123", (long)-123); + CHECK_FORMAT_1("%1li", "-123", (long)-123); + CHECK_FORMAT_1("%1lld", "-123", (long long)-123); + CHECK_FORMAT_1("%1lli", "-123", (long long)-123); + CHECK_FORMAT_1("%1zd", "-123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%1zi", "-123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%1x", "ffffff85", (int)-123); + + // Integers: width > length + CHECK_FORMAT_1("%5d", " 123", (int)123); + CHECK_FORMAT_1("%5i", " 123", (int)123); + CHECK_FORMAT_1("%5u", " 123", (unsigned int)123); + CHECK_FORMAT_1("%5ld", " 123", (long)123); + CHECK_FORMAT_1("%5li", " 123", (long)123); + CHECK_FORMAT_1("%5lu", " 123", (unsigned long)123); + CHECK_FORMAT_1("%5lld", " 123", (long long)123); + CHECK_FORMAT_1("%5lli", " 123", (long long)123); + CHECK_FORMAT_1("%5llu", " 123", (unsigned long long)123); + CHECK_FORMAT_1("%5zd", " 123", (Py_ssize_t)123); + CHECK_FORMAT_1("%5zi", " 123", (Py_ssize_t)123); + CHECK_FORMAT_1("%5zu", " 123", (size_t)123); + CHECK_FORMAT_1("%5x", " 7b", (int)123); + + CHECK_FORMAT_1("%5d", " -123", (int)-123); + CHECK_FORMAT_1("%5i", " -123", (int)-123); + CHECK_FORMAT_1("%5ld", " -123", (long)-123); + CHECK_FORMAT_1("%5li", " -123", (long)-123); + CHECK_FORMAT_1("%5lld", " -123", (long long)-123); + CHECK_FORMAT_1("%5lli", " -123", (long long)-123); + CHECK_FORMAT_1("%5zd", " -123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%5zi", " -123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%9x", " ffffff85", (int)-123); + + // Integers: width > length, 0-flag + CHECK_FORMAT_1("%05d", "00123", (int)123); + CHECK_FORMAT_1("%05i", "00123", (int)123); + CHECK_FORMAT_1("%05u", "00123", (unsigned int)123); + CHECK_FORMAT_1("%05ld", "00123", (long)123); + CHECK_FORMAT_1("%05li", "00123", (long)123); + CHECK_FORMAT_1("%05lu", "00123", (unsigned long)123); + CHECK_FORMAT_1("%05lld", "00123", (long long)123); + CHECK_FORMAT_1("%05lli", "00123", (long long)123); + CHECK_FORMAT_1("%05llu", "00123", (unsigned long long)123); + CHECK_FORMAT_1("%05zd", "00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%05zi", "00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%05zu", "00123", (size_t)123); + CHECK_FORMAT_1("%05x", "0007b", (int)123); + + CHECK_FORMAT_1("%05d", "-0123", (int)-123); + CHECK_FORMAT_1("%05i", "-0123", (int)-123); + CHECK_FORMAT_1("%05ld", "-0123", (long)-123); + CHECK_FORMAT_1("%05li", "-0123", (long)-123); + CHECK_FORMAT_1("%05lld", "-0123", (long long)-123); + CHECK_FORMAT_1("%05lli", "-0123", (long long)-123); + CHECK_FORMAT_1("%05zd", "-0123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%05zi", "-0123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%09x", "0ffffff85", (int)-123); + + // Integers: precision < length + CHECK_FORMAT_1("%.1d", "123", (int)123); + CHECK_FORMAT_1("%.1i", "123", (int)123); + CHECK_FORMAT_1("%.1u", "123", (unsigned int)123); + CHECK_FORMAT_1("%.1ld", "123", (long)123); + CHECK_FORMAT_1("%.1li", "123", (long)123); + CHECK_FORMAT_1("%.1lu", "123", (unsigned long)123); + CHECK_FORMAT_1("%.1lld", "123", (long long)123); + CHECK_FORMAT_1("%.1lli", "123", (long long)123); + CHECK_FORMAT_1("%.1llu", "123", (unsigned long long)123); + CHECK_FORMAT_1("%.1zd", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%.1zi", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%.1zu", "123", (size_t)123); + CHECK_FORMAT_1("%.1x", "7b", (int)123); + + CHECK_FORMAT_1("%.1d", "-123", (int)-123); + CHECK_FORMAT_1("%.1i", "-123", (int)-123); + CHECK_FORMAT_1("%.1ld", "-123", (long)-123); + CHECK_FORMAT_1("%.1li", "-123", (long)-123); + CHECK_FORMAT_1("%.1lld", "-123", (long long)-123); + CHECK_FORMAT_1("%.1lli", "-123", (long long)-123); + CHECK_FORMAT_1("%.1zd", "-123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%.1zi", "-123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%.1x", "ffffff85", (int)-123); + + // Integers: precision > length + CHECK_FORMAT_1("%.5d", "00123", (int)123); + CHECK_FORMAT_1("%.5i", "00123", (int)123); + CHECK_FORMAT_1("%.5u", "00123", (unsigned int)123); + CHECK_FORMAT_1("%.5ld", "00123", (long)123); + CHECK_FORMAT_1("%.5li", "00123", (long)123); + CHECK_FORMAT_1("%.5lu", "00123", (unsigned long)123); + CHECK_FORMAT_1("%.5lld", "00123", (long long)123); + CHECK_FORMAT_1("%.5lli", "00123", (long long)123); + CHECK_FORMAT_1("%.5llu", "00123", (unsigned long long)123); + CHECK_FORMAT_1("%.5zd", "00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%.5zi", "00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%.5zu", "00123", (size_t)123); + CHECK_FORMAT_1("%.5x", "0007b", (int)123); + + CHECK_FORMAT_1("%.5d", "-00123", (int)-123); + CHECK_FORMAT_1("%.5i", "-00123", (int)-123); + CHECK_FORMAT_1("%.5ld", "-00123", (long)-123); + CHECK_FORMAT_1("%.5li", "-00123", (long)-123); + CHECK_FORMAT_1("%.5lld", "-00123", (long long)-123); + CHECK_FORMAT_1("%.5lli", "-00123", (long long)-123); + CHECK_FORMAT_1("%.5zd", "-00123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%.5zi", "-00123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%.9x", "0ffffff85", (int)-123); + + // Integers: width > precision > length + CHECK_FORMAT_1("%7.5d", " 00123", (int)123); + CHECK_FORMAT_1("%7.5i", " 00123", (int)123); + CHECK_FORMAT_1("%7.5u", " 00123", (unsigned int)123); + CHECK_FORMAT_1("%7.5ld", " 00123", (long)123); + CHECK_FORMAT_1("%7.5li", " 00123", (long)123); + CHECK_FORMAT_1("%7.5lu", " 00123", (unsigned long)123); + CHECK_FORMAT_1("%7.5lld", " 00123", (long long)123); + CHECK_FORMAT_1("%7.5lli", " 00123", (long long)123); + CHECK_FORMAT_1("%7.5llu", " 00123", (unsigned long long)123); + CHECK_FORMAT_1("%7.5zd", " 00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%7.5zi", " 00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%7.5zu", " 00123", (size_t)123); + CHECK_FORMAT_1("%7.5x", " 0007b", (int)123); + + CHECK_FORMAT_1("%7.5d", " -00123", (int)-123); + CHECK_FORMAT_1("%7.5i", " -00123", (int)-123); + CHECK_FORMAT_1("%7.5ld", " -00123", (long)-123); + CHECK_FORMAT_1("%7.5li", " -00123", (long)-123); + CHECK_FORMAT_1("%7.5lld", " -00123", (long long)-123); + CHECK_FORMAT_1("%7.5lli", " -00123", (long long)-123); + CHECK_FORMAT_1("%7.5zd", " -00123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%7.5zi", " -00123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%10.9x", " 0ffffff85", (int)-123); + + // Integers: width > precision > length, 0-flag + CHECK_FORMAT_1("%07.5d", "0000123", (int)123); + CHECK_FORMAT_1("%07.5i", "0000123", (int)123); + CHECK_FORMAT_1("%07.5u", "0000123", (unsigned int)123); + CHECK_FORMAT_1("%07.5ld", "0000123", (long)123); + CHECK_FORMAT_1("%07.5li", "0000123", (long)123); + CHECK_FORMAT_1("%07.5lu", "0000123", (unsigned long)123); + CHECK_FORMAT_1("%07.5lld", "0000123", (long long)123); + CHECK_FORMAT_1("%07.5lli", "0000123", (long long)123); + CHECK_FORMAT_1("%07.5llu", "0000123", (unsigned long long)123); + CHECK_FORMAT_1("%07.5zd", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%07.5zi", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%07.5zu", "0000123", (size_t)123); + CHECK_FORMAT_1("%07.5x", "000007b", (int)123); + + CHECK_FORMAT_1("%07.5d", "-000123", (int)-123); + CHECK_FORMAT_1("%07.5i", "-000123", (int)-123); + CHECK_FORMAT_1("%07.5ld", "-000123", (long)-123); + CHECK_FORMAT_1("%07.5li", "-000123", (long)-123); + CHECK_FORMAT_1("%07.5lld", "-000123", (long long)-123); + CHECK_FORMAT_1("%07.5lli", "-000123", (long long)-123); + CHECK_FORMAT_1("%07.5zd", "-000123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%07.5zi", "-000123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%010.9x", "00ffffff85", (int)-123); + + // Integers: precision > width > length + CHECK_FORMAT_1("%5.7d", "0000123", (int)123); + CHECK_FORMAT_1("%5.7i", "0000123", (int)123); + CHECK_FORMAT_1("%5.7u", "0000123", (unsigned int)123); + CHECK_FORMAT_1("%5.7ld", "0000123", (long)123); + CHECK_FORMAT_1("%5.7li", "0000123", (long)123); + CHECK_FORMAT_1("%5.7lu", "0000123", (unsigned long)123); + CHECK_FORMAT_1("%5.7lld", "0000123", (long long)123); + CHECK_FORMAT_1("%5.7lli", "0000123", (long long)123); + CHECK_FORMAT_1("%5.7llu", "0000123", (unsigned long long)123); + CHECK_FORMAT_1("%5.7zd", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%5.7zi", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%5.7zu", "0000123", (size_t)123); + CHECK_FORMAT_1("%5.7x", "000007b", (int)123); + + CHECK_FORMAT_1("%5.7d", "-0000123", (int)-123); + CHECK_FORMAT_1("%5.7i", "-0000123", (int)-123); + CHECK_FORMAT_1("%5.7ld", "-0000123", (long)-123); + CHECK_FORMAT_1("%5.7li", "-0000123", (long)-123); + CHECK_FORMAT_1("%5.7lld", "-0000123", (long long)-123); + CHECK_FORMAT_1("%5.7lli", "-0000123", (long long)-123); + CHECK_FORMAT_1("%5.7zd", "-0000123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%5.7zi", "-0000123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%9.10x", "00ffffff85", (int)-123); + + // Integers: precision > width > length, 0-flag + CHECK_FORMAT_1("%05.7d", "0000123", (int)123); + CHECK_FORMAT_1("%05.7i", "0000123", (int)123); + CHECK_FORMAT_1("%05.7u", "0000123", (unsigned int)123); + CHECK_FORMAT_1("%05.7ld", "0000123", (long)123); + CHECK_FORMAT_1("%05.7li", "0000123", (long)123); + CHECK_FORMAT_1("%05.7lu", "0000123", (unsigned long)123); + CHECK_FORMAT_1("%05.7lld", "0000123", (long long)123); + CHECK_FORMAT_1("%05.7lli", "0000123", (long long)123); + CHECK_FORMAT_1("%05.7llu", "0000123", (unsigned long long)123); + CHECK_FORMAT_1("%05.7zd", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%05.7zi", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%05.7zu", "0000123", (size_t)123); + CHECK_FORMAT_1("%05.7x", "000007b", (int)123); + + CHECK_FORMAT_1("%05.7d", "-0000123", (int)-123); + CHECK_FORMAT_1("%05.7i", "-0000123", (int)-123); + CHECK_FORMAT_1("%05.7ld", "-0000123", (long)-123); + CHECK_FORMAT_1("%05.7li", "-0000123", (long)-123); + CHECK_FORMAT_1("%05.7lld", "-0000123", (long long)-123); + CHECK_FORMAT_1("%05.7lli", "-0000123", (long long)-123); + CHECK_FORMAT_1("%05.7zd", "-0000123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%05.7zi", "-0000123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%09.10x", "00ffffff85", (int)-123); + + // Integers: precision = 0, arg = 0 (empty string in C) + CHECK_FORMAT_1("%.0d", "0", (int)0); + CHECK_FORMAT_1("%.0i", "0", (int)0); + CHECK_FORMAT_1("%.0u", "0", (unsigned int)0); + CHECK_FORMAT_1("%.0ld", "0", (long)0); + CHECK_FORMAT_1("%.0li", "0", (long)0); + CHECK_FORMAT_1("%.0lu", "0", (unsigned long)0); + CHECK_FORMAT_1("%.0lld", "0", (long long)0); + CHECK_FORMAT_1("%.0lli", "0", (long long)0); + CHECK_FORMAT_1("%.0llu", "0", (unsigned long long)0); + CHECK_FORMAT_1("%.0zd", "0", (Py_ssize_t)0); + CHECK_FORMAT_1("%.0zi", "0", (Py_ssize_t)0); + CHECK_FORMAT_1("%.0zu", "0", (size_t)0); + CHECK_FORMAT_1("%.0x", "0", (int)0); + + // Strings + CHECK_FORMAT_1("%s", "None", "None"); + CHECK_FORMAT_1("%U", "None", unicode); + CHECK_FORMAT_1("%A", "None", Py_None); + CHECK_FORMAT_1("%S", "None", Py_None); + CHECK_FORMAT_1("%R", "None", Py_None); + CHECK_FORMAT_2("%V", "None", unicode, "ignored"); + CHECK_FORMAT_2("%V", "None", NULL, "None"); + + // Strings: width < length + CHECK_FORMAT_1("%1s", "None", "None"); + CHECK_FORMAT_1("%1U", "None", unicode); + CHECK_FORMAT_1("%1A", "None", Py_None); + CHECK_FORMAT_1("%1S", "None", Py_None); + CHECK_FORMAT_1("%1R", "None", Py_None); + CHECK_FORMAT_2("%1V", "None", unicode, "ignored"); + CHECK_FORMAT_2("%1V", "None", NULL, "None"); + + // Strings: width > length + CHECK_FORMAT_1("%5s", " None", "None"); + CHECK_FORMAT_1("%5U", " None", unicode); + CHECK_FORMAT_1("%5A", " None", Py_None); + CHECK_FORMAT_1("%5S", " None", Py_None); + CHECK_FORMAT_1("%5R", " None", Py_None); + CHECK_FORMAT_2("%5V", " None", unicode, "ignored"); + CHECK_FORMAT_2("%5V", " None", NULL, "None"); + + // Strings: precision < length + CHECK_FORMAT_1("%.1s", "N", "None"); + CHECK_FORMAT_1("%.1U", "N", unicode); + CHECK_FORMAT_1("%.1A", "N", Py_None); + CHECK_FORMAT_1("%.1S", "N", Py_None); + CHECK_FORMAT_1("%.1R", "N", Py_None); + CHECK_FORMAT_2("%.1V", "N", unicode, "ignored"); + CHECK_FORMAT_2("%.1V", "N", NULL, "None"); + + // Strings: precision > length + CHECK_FORMAT_1("%.5s", "None", "None"); + CHECK_FORMAT_1("%.5U", "None", unicode); + CHECK_FORMAT_1("%.5A", "None", Py_None); + CHECK_FORMAT_1("%.5S", "None", Py_None); + CHECK_FORMAT_1("%.5R", "None", Py_None); + CHECK_FORMAT_2("%.5V", "None", unicode, "ignored"); + CHECK_FORMAT_2("%.5V", "None", NULL, "None"); + + // Strings: precision < length, width > length + CHECK_FORMAT_1("%5.1s", " N", "None"); + CHECK_FORMAT_1("%5.1U", " N", unicode); + CHECK_FORMAT_1("%5.1A", " N", Py_None); + CHECK_FORMAT_1("%5.1S", " N", Py_None); + CHECK_FORMAT_1("%5.1R", " N", Py_None); + CHECK_FORMAT_2("%5.1V", " N", unicode, "ignored"); + CHECK_FORMAT_2("%5.1V", " N", NULL, "None"); + + // Strings: width < length, precision > length + CHECK_FORMAT_1("%1.5s", "None", "None"); + CHECK_FORMAT_1("%1.5U", "None", unicode); + CHECK_FORMAT_1("%1.5A", "None", Py_None); + CHECK_FORMAT_1("%1.5S", "None", Py_None); + CHECK_FORMAT_1("%1.5R", "None", Py_None); + CHECK_FORMAT_2("%1.5V", "None", unicode, "ignored"); + CHECK_FORMAT_2("%1.5V", "None", NULL, "None"); + + Py_XDECREF(unicode); + Py_RETURN_NONE; + + Fail: + Py_XDECREF(result); + Py_XDECREF(unicode); + return NULL; + +#undef CHECK_FORMAT_2 +#undef CHECK_FORMAT_1 +#undef CHECK_FORMAT_0 +} + +static PyMethodDef TestMethods[] = { + {"codec_incrementalencoder", codec_incrementalencoder, METH_VARARGS}, + {"codec_incrementaldecoder", codec_incrementaldecoder, METH_VARARGS}, + {"test_unicode_compare_with_ascii", + test_unicode_compare_with_ascii, METH_NOARGS}, + {"test_string_from_format", test_string_from_format, METH_NOARGS}, + {"test_widechar", test_widechar, METH_NOARGS}, + {"unicode_fromobject", unicode_fromobject, METH_O}, + {"unicode_aswidechar", unicode_aswidechar, METH_VARARGS}, + {"unicode_aswidecharstring", unicode_aswidecharstring, METH_VARARGS}, + {"unicode_asucs4", unicode_asucs4, METH_VARARGS}, + {"unicode_asutf8", unicode_asutf8, METH_VARARGS}, + {"unicode_asutf8andsize", unicode_asutf8andsize, METH_VARARGS}, + {"unicode_decodeutf8", unicode_decodeutf8, METH_VARARGS}, + {"unicode_decodeutf8stateful",unicode_decodeutf8stateful, METH_VARARGS}, + {"unicode_concat", unicode_concat, METH_VARARGS}, + {"unicode_splitlines", unicode_splitlines, METH_VARARGS}, + {"unicode_split", unicode_split, METH_VARARGS}, + {"unicode_rsplit", unicode_rsplit, METH_VARARGS}, + {"unicode_partition", unicode_partition, METH_VARARGS}, + {"unicode_rpartition", unicode_rpartition, METH_VARARGS}, + {"unicode_translate", unicode_translate, METH_VARARGS}, + {"unicode_join", unicode_join, METH_VARARGS}, + {"unicode_count", unicode_count, METH_VARARGS}, + {"unicode_tailmatch", unicode_tailmatch, METH_VARARGS}, + {"unicode_find", unicode_find, METH_VARARGS}, + {"unicode_findchar", unicode_findchar, METH_VARARGS}, + {"unicode_replace", unicode_replace, METH_VARARGS}, + {"unicode_compare", unicode_compare, METH_VARARGS}, + {"unicode_comparewithasciistring",unicode_comparewithasciistring,METH_VARARGS}, + {"unicode_richcompare", unicode_richcompare, METH_VARARGS}, + {"unicode_format", unicode_format, METH_VARARGS}, + {"unicode_contains", unicode_contains, METH_VARARGS}, + {"unicode_isidentifier", unicode_isidentifier, METH_O}, + {"unicode_copycharacters", unicode_copycharacters, METH_VARARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_Unicode(PyObject *m) { + _testcapimodule = PyModule_GetDef(m); + + if (PyModule_AddFunctions(m, TestMethods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/vectorcall.c b/Modules/_testcapi/vectorcall.c new file mode 100644 index 00000000000..dcbc973c9fb --- /dev/null +++ b/Modules/_testcapi/vectorcall.c @@ -0,0 +1,406 @@ +#include "parts.h" +#include "clinic/vectorcall.c.h" + +#include "structmember.h" // PyMemberDef +#include // offsetof + + +/* Test PEP 590 - Vectorcall */ + +static int +fastcall_args(PyObject *args, PyObject ***stack, Py_ssize_t *nargs) +{ + if (args == Py_None) { + *stack = NULL; + *nargs = 0; + } + else if (PyTuple_Check(args)) { + *stack = ((PyTupleObject *)args)->ob_item; + *nargs = PyTuple_GET_SIZE(args); + } + else { + PyErr_SetString(PyExc_TypeError, "args must be None or a tuple"); + return -1; + } + return 0; +} + + +static PyObject * +test_pyobject_fastcall(PyObject *self, PyObject *args) +{ + PyObject *func, *func_args; + PyObject **stack; + Py_ssize_t nargs; + + if (!PyArg_ParseTuple(args, "OO", &func, &func_args)) { + return NULL; + } + + if (fastcall_args(func_args, &stack, &nargs) < 0) { + return NULL; + } + return _PyObject_FastCall(func, stack, nargs); +} + +static PyObject * +test_pyobject_fastcalldict(PyObject *self, PyObject *args) +{ + PyObject *func, *func_args, *kwargs; + PyObject **stack; + Py_ssize_t nargs; + + if (!PyArg_ParseTuple(args, "OOO", &func, &func_args, &kwargs)) { + return NULL; + } + + if (fastcall_args(func_args, &stack, &nargs) < 0) { + return NULL; + } + + if (kwargs == Py_None) { + kwargs = NULL; + } + else if (!PyDict_Check(kwargs)) { + PyErr_SetString(PyExc_TypeError, "kwnames must be None or a dict"); + return NULL; + } + + return PyObject_VectorcallDict(func, stack, nargs, kwargs); +} + +static PyObject * +test_pyobject_vectorcall(PyObject *self, PyObject *args) +{ + PyObject *func, *func_args, *kwnames = NULL; + PyObject **stack; + Py_ssize_t nargs, nkw; + + if (!PyArg_ParseTuple(args, "OOO", &func, &func_args, &kwnames)) { + return NULL; + } + + if (fastcall_args(func_args, &stack, &nargs) < 0) { + return NULL; + } + + if (kwnames == Py_None) { + kwnames = NULL; + } + else if (PyTuple_Check(kwnames)) { + nkw = PyTuple_GET_SIZE(kwnames); + if (nargs < nkw) { + PyErr_SetString(PyExc_ValueError, "kwnames longer than args"); + return NULL; + } + nargs -= nkw; + } + else { + PyErr_SetString(PyExc_TypeError, "kwnames must be None or a tuple"); + return NULL; + } + return PyObject_Vectorcall(func, stack, nargs, kwnames); +} + +static PyObject * +override_vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, + PyObject *kwnames) +{ + return PyUnicode_FromString("overridden"); +} + +static PyObject * +function_setvectorcall(PyObject *self, PyObject *func) +{ + if (!PyFunction_Check(func)) { + PyErr_SetString(PyExc_TypeError, "'func' must be a function"); + return NULL; + } + PyFunction_SetVectorcall((PyFunctionObject *)func, (vectorcallfunc)override_vectorcall); + Py_RETURN_NONE; +} + +static PyObject * +test_pyvectorcall_call(PyObject *self, PyObject *args) +{ + PyObject *func; + PyObject *argstuple; + PyObject *kwargs = NULL; + + if (!PyArg_ParseTuple(args, "OO|O", &func, &argstuple, &kwargs)) { + return NULL; + } + + if (!PyTuple_Check(argstuple)) { + PyErr_SetString(PyExc_TypeError, "args must be a tuple"); + return NULL; + } + if (kwargs != NULL && !PyDict_Check(kwargs)) { + PyErr_SetString(PyExc_TypeError, "kwargs must be a dict"); + return NULL; + } + + return PyVectorcall_Call(func, argstuple, kwargs); +} + +PyObject * +VectorCallClass_tpcall(PyObject *self, PyObject *args, PyObject *kwargs) { + return PyUnicode_FromString("tp_call"); +} + +PyObject * +VectorCallClass_vectorcall(PyObject *callable, + PyObject *const *args, + size_t nargsf, + PyObject *kwnames) { + return PyUnicode_FromString("vectorcall"); +} + +/*[clinic input] +module _testcapi +class _testcapi.VectorCallClass "PyObject *" "&PyType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8423a8e919f2f0df]*/ + +/*[clinic input] +_testcapi.VectorCallClass.set_vectorcall + + type: object(subclass_of="&PyType_Type", type="PyTypeObject *") + / + +Set self's vectorcall function for `type` to one that returns "vectorcall" +[clinic start generated code]*/ + +static PyObject * +_testcapi_VectorCallClass_set_vectorcall_impl(PyObject *self, + PyTypeObject *type) +/*[clinic end generated code: output=b37f0466f15da903 input=840de66182c7d71a]*/ +{ + if (!PyObject_TypeCheck(self, type)) { + return PyErr_Format( + PyExc_TypeError, + "expected %s instance", + PyType_GetName(type)); + } + if (!type->tp_vectorcall_offset) { + return PyErr_Format( + PyExc_TypeError, + "type %s has no vectorcall offset", + PyType_GetName(type)); + } + *(vectorcallfunc*)((char*)self + type->tp_vectorcall_offset) = ( + VectorCallClass_vectorcall); + Py_RETURN_NONE; +} + +PyMethodDef VectorCallClass_methods[] = { + _TESTCAPI_VECTORCALLCLASS_SET_VECTORCALL_METHODDEF + {NULL, NULL} +}; + +PyMemberDef VectorCallClass_members[] = { + {"__vectorcalloffset__", T_PYSSIZET, 0/* set later */, READONLY}, + {NULL} +}; + +PyType_Slot VectorCallClass_slots[] = { + {Py_tp_call, VectorCallClass_tpcall}, + {Py_tp_members, VectorCallClass_members}, + {Py_tp_methods, VectorCallClass_methods}, + {0}, +}; + +/*[clinic input] +_testcapi.make_vectorcall_class + + base: object(subclass_of="&PyType_Type", type="PyTypeObject *") = NULL + / + +Create a class whose instances return "tpcall" when called. + +When the "set_vectorcall" method is called on an instance, a vectorcall +function that returns "vectorcall" will be installed. +[clinic start generated code]*/ + +static PyObject * +_testcapi_make_vectorcall_class_impl(PyObject *module, PyTypeObject *base) +/*[clinic end generated code: output=16dcfc3062ddf968 input=f72e01ccf52de2b4]*/ +{ + if (!base) { + base = (PyTypeObject *)&PyBaseObject_Type; + } + VectorCallClass_members[0].offset = base->tp_basicsize; + PyType_Spec spec = { + .name = "_testcapi.VectorcallClass", + .basicsize = (int)(base->tp_basicsize + sizeof(vectorcallfunc)), + .flags = Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_HAVE_VECTORCALL + | Py_TPFLAGS_BASETYPE, + .slots = VectorCallClass_slots, + }; + + return PyType_FromSpecWithBases(&spec, (PyObject *)base); +} + +/*[clinic input] +_testcapi.has_vectorcall_flag -> bool + + type: object(subclass_of="&PyType_Type", type="PyTypeObject *") + / + +Return true iff Py_TPFLAGS_HAVE_VECTORCALL is set on the class. +[clinic start generated code]*/ + +static int +_testcapi_has_vectorcall_flag_impl(PyObject *module, PyTypeObject *type) +/*[clinic end generated code: output=3ae8d1374388c671 input=8eee492ac548749e]*/ +{ + return PyType_HasFeature(type, Py_TPFLAGS_HAVE_VECTORCALL); +} + +static PyMethodDef TestMethods[] = { + {"pyobject_fastcall", test_pyobject_fastcall, METH_VARARGS}, + {"pyobject_fastcalldict", test_pyobject_fastcalldict, METH_VARARGS}, + {"pyobject_vectorcall", test_pyobject_vectorcall, METH_VARARGS}, + {"function_setvectorcall", function_setvectorcall, METH_O}, + {"pyvectorcall_call", test_pyvectorcall_call, METH_VARARGS}, + _TESTCAPI_MAKE_VECTORCALL_CLASS_METHODDEF + _TESTCAPI_HAS_VECTORCALL_FLAG_METHODDEF + {NULL}, +}; + + +typedef struct { + PyObject_HEAD + vectorcallfunc vectorcall; +} MethodDescriptorObject; + +static PyObject * +MethodDescriptor_vectorcall(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + /* True if using the vectorcall function in MethodDescriptorObject + * but False for MethodDescriptor2Object */ + MethodDescriptorObject *md = (MethodDescriptorObject *)callable; + return PyBool_FromLong(md->vectorcall != NULL); +} + +static PyObject * +MethodDescriptor_new(PyTypeObject* type, PyObject* args, PyObject *kw) +{ + MethodDescriptorObject *op = (MethodDescriptorObject *)type->tp_alloc(type, 0); + op->vectorcall = MethodDescriptor_vectorcall; + return (PyObject *)op; +} + +static PyObject * +func_descr_get(PyObject *func, PyObject *obj, PyObject *type) +{ + if (obj == Py_None || obj == NULL) { + return Py_NewRef(func); + } + return PyMethod_New(func, obj); +} + +static PyObject * +nop_descr_get(PyObject *func, PyObject *obj, PyObject *type) +{ + return Py_NewRef(func); +} + +static PyObject * +call_return_args(PyObject *self, PyObject *args, PyObject *kwargs) +{ + return Py_NewRef(args); +} + +static PyTypeObject MethodDescriptorBase_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MethodDescriptorBase", + sizeof(MethodDescriptorObject), + .tp_new = MethodDescriptor_new, + .tp_call = PyVectorcall_Call, + .tp_vectorcall_offset = offsetof(MethodDescriptorObject, vectorcall), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_METHOD_DESCRIPTOR | Py_TPFLAGS_HAVE_VECTORCALL, + .tp_descr_get = func_descr_get, +}; + +static PyTypeObject MethodDescriptorDerived_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MethodDescriptorDerived", + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, +}; + +static PyTypeObject MethodDescriptorNopGet_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MethodDescriptorNopGet", + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_call = call_return_args, + .tp_descr_get = nop_descr_get, +}; + +typedef struct { + MethodDescriptorObject base; + vectorcallfunc vectorcall; +} MethodDescriptor2Object; + +static PyObject * +MethodDescriptor2_new(PyTypeObject* type, PyObject* args, PyObject *kw) +{ + MethodDescriptor2Object *op = PyObject_New(MethodDescriptor2Object, type); + op->base.vectorcall = NULL; + op->vectorcall = MethodDescriptor_vectorcall; + return (PyObject *)op; +} + +static PyTypeObject MethodDescriptor2_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MethodDescriptor2", + sizeof(MethodDescriptor2Object), + .tp_new = MethodDescriptor2_new, + .tp_call = PyVectorcall_Call, + .tp_vectorcall_offset = offsetof(MethodDescriptor2Object, vectorcall), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL, +}; + + +int +_PyTestCapi_Init_Vectorcall(PyObject *m) { + if (PyModule_AddFunctions(m, TestMethods) < 0) { + return -1; + } + + if (PyType_Ready(&MethodDescriptorBase_Type) < 0) { + return -1; + } + if (PyModule_AddType(m, &MethodDescriptorBase_Type) < 0) { + return -1; + } + + MethodDescriptorDerived_Type.tp_base = &MethodDescriptorBase_Type; + if (PyType_Ready(&MethodDescriptorDerived_Type) < 0) { + return -1; + } + if (PyModule_AddType(m, &MethodDescriptorDerived_Type) < 0) { + return -1; + } + + MethodDescriptorNopGet_Type.tp_base = &MethodDescriptorBase_Type; + if (PyType_Ready(&MethodDescriptorNopGet_Type) < 0) { + return -1; + } + if (PyModule_AddType(m, &MethodDescriptorNopGet_Type) < 0) { + return -1; + } + + MethodDescriptor2_Type.tp_base = &MethodDescriptorBase_Type; + if (PyType_Ready(&MethodDescriptor2_Type) < 0) { + return -1; + } + if (PyModule_AddType(m, &MethodDescriptor2_Type) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/vectorcall_limited.c b/Modules/_testcapi/vectorcall_limited.c new file mode 100644 index 00000000000..a69f1d3f2a7 --- /dev/null +++ b/Modules/_testcapi/vectorcall_limited.c @@ -0,0 +1,179 @@ +#define Py_LIMITED_API 0x030c0000 // 3.12 +#include "parts.h" + +#ifdef LIMITED_API_AVAILABLE + +#include "structmember.h" // PyMemberDef + +/* Test Vectorcall in the limited API */ + +static PyObject * +LimitedVectorCallClass_tpcall(PyObject *self, PyObject *args, PyObject *kwargs) { + return PyUnicode_FromString("tp_call called"); +} + +static PyObject * +LimitedVectorCallClass_vectorcall(PyObject *callable, + PyObject *const *args, + size_t nargsf, + PyObject *kwnames) { + return PyUnicode_FromString("vectorcall called"); +} + +static PyObject * +LimitedVectorCallClass_new(PyTypeObject *tp, PyTypeObject *a, PyTypeObject *kw) +{ + PyObject *self = ((allocfunc)PyType_GetSlot(tp, Py_tp_alloc))(tp, 0); + if (!self) { + return NULL; + } + *(vectorcallfunc*)((char*)self + sizeof(PyObject)) = ( + LimitedVectorCallClass_vectorcall); + return self; +} + +static PyObject * +call_vectorcall(PyObject* self, PyObject *callable) +{ + PyObject *args[3] = { NULL, NULL, NULL }; + PyObject *kwname = NULL, *kwnames = NULL, *result = NULL; + + args[1] = PyUnicode_FromString("foo"); + if (!args[1]) { + goto leave; + } + + args[2] = PyUnicode_FromString("bar"); + if (!args[2]) { + goto leave; + } + + kwname = PyUnicode_InternFromString("baz"); + if (!kwname) { + goto leave; + } + + kwnames = PyTuple_New(1); + if (!kwnames) { + goto leave; + } + + if (PyTuple_SetItem(kwnames, 0, kwname)) { + goto leave; + } + + result = PyObject_Vectorcall( + callable, + args + 1, + 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, + kwnames + ); + +leave: + Py_XDECREF(args[1]); + Py_XDECREF(args[2]); + Py_XDECREF(kwnames); + + return result; +} + +static PyObject * +call_vectorcall_method(PyObject* self, PyObject *callable) +{ + PyObject *args[3] = { NULL, NULL, NULL }; + PyObject *name = NULL, *kwname = NULL, + *kwnames = NULL, *result = NULL; + + name = PyUnicode_FromString("f"); + if (!name) { + goto leave; + } + + args[0] = callable; + args[1] = PyUnicode_FromString("foo"); + if (!args[1]) { + goto leave; + } + + args[2] = PyUnicode_FromString("bar"); + if (!args[2]) { + goto leave; + } + + kwname = PyUnicode_InternFromString("baz"); + if (!kwname) { + goto leave; + } + + kwnames = PyTuple_New(1); + if (!kwnames) { + goto leave; + } + + if (PyTuple_SetItem(kwnames, 0, kwname)) { + goto leave; + } + + + result = PyObject_VectorcallMethod( + name, + args, + 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, + kwnames + ); + +leave: + Py_XDECREF(name); + Py_XDECREF(args[1]); + Py_XDECREF(args[2]); + Py_XDECREF(kwnames); + + return result; +} + +static PyMemberDef LimitedVectorCallClass_members[] = { + {"__vectorcalloffset__", T_PYSSIZET, sizeof(PyObject), READONLY}, + {NULL} +}; + +static PyType_Slot LimitedVectorallClass_slots[] = { + {Py_tp_new, LimitedVectorCallClass_new}, + {Py_tp_call, LimitedVectorCallClass_tpcall}, + {Py_tp_members, LimitedVectorCallClass_members}, + {0}, +}; + +static PyType_Spec LimitedVectorCallClass_spec = { + .name = "_testcapi.LimitedVectorCallClass", + .basicsize = (int)(sizeof(PyObject) + sizeof(vectorcallfunc)), + .flags = Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_HAVE_VECTORCALL + | Py_TPFLAGS_BASETYPE, + .slots = LimitedVectorallClass_slots, +}; + +static PyMethodDef TestMethods[] = { + {"call_vectorcall", call_vectorcall, METH_O}, + {"call_vectorcall_method", call_vectorcall_method, METH_O}, + {NULL}, +}; + +int +_PyTestCapi_Init_VectorcallLimited(PyObject *m) { + if (PyModule_AddFunctions(m, TestMethods) < 0) { + return -1; + } + + PyObject *LimitedVectorCallClass = PyType_FromModuleAndSpec( + m, &LimitedVectorCallClass_spec, NULL); + if (!LimitedVectorCallClass) { + return -1; + } + if (PyModule_AddType(m, (PyTypeObject *)LimitedVectorCallClass) < 0) { + return -1; + } + + return 0; +} + +#endif // LIMITED_API_AVAILABLE diff --git a/Modules/_testcapi/watchers.c b/Modules/_testcapi/watchers.c new file mode 100644 index 00000000000..2e8fe1dbf78 --- /dev/null +++ b/Modules/_testcapi/watchers.c @@ -0,0 +1,681 @@ +#include "parts.h" + +#define Py_BUILD_CORE +#include "pycore_function.h" // FUNC_MAX_WATCHERS +#include "pycore_code.h" // CODE_MAX_WATCHERS + +// Test dict watching +static PyObject *g_dict_watch_events; +static int g_dict_watchers_installed; + +static int +dict_watch_callback(PyDict_WatchEvent event, + PyObject *dict, + PyObject *key, + PyObject *new_value) +{ + PyObject *msg; + switch (event) { + case PyDict_EVENT_CLEARED: + msg = PyUnicode_FromString("clear"); + break; + case PyDict_EVENT_DEALLOCATED: + msg = PyUnicode_FromString("dealloc"); + break; + case PyDict_EVENT_CLONED: + msg = PyUnicode_FromString("clone"); + break; + case PyDict_EVENT_ADDED: + msg = PyUnicode_FromFormat("new:%S:%S", key, new_value); + break; + case PyDict_EVENT_MODIFIED: + msg = PyUnicode_FromFormat("mod:%S:%S", key, new_value); + break; + case PyDict_EVENT_DELETED: + msg = PyUnicode_FromFormat("del:%S", key); + break; + default: + msg = PyUnicode_FromString("unknown"); + } + if (msg == NULL) { + return -1; + } + assert(PyList_Check(g_dict_watch_events)); + if (PyList_Append(g_dict_watch_events, msg) < 0) { + Py_DECREF(msg); + return -1; + } + Py_DECREF(msg); + return 0; +} + +static int +dict_watch_callback_second(PyDict_WatchEvent event, + PyObject *dict, + PyObject *key, + PyObject *new_value) +{ + PyObject *msg = PyUnicode_FromString("second"); + if (msg == NULL) { + return -1; + } + int rc = PyList_Append(g_dict_watch_events, msg); + Py_DECREF(msg); + if (rc < 0) { + return -1; + } + return 0; +} + +static int +dict_watch_callback_error(PyDict_WatchEvent event, + PyObject *dict, + PyObject *key, + PyObject *new_value) +{ + PyErr_SetString(PyExc_RuntimeError, "boom!"); + return -1; +} + +static PyObject * +add_dict_watcher(PyObject *self, PyObject *kind) +{ + int watcher_id; + assert(PyLong_Check(kind)); + long kind_l = PyLong_AsLong(kind); + if (kind_l == 2) { + watcher_id = PyDict_AddWatcher(dict_watch_callback_second); + } + else if (kind_l == 1) { + watcher_id = PyDict_AddWatcher(dict_watch_callback_error); + } + else { + watcher_id = PyDict_AddWatcher(dict_watch_callback); + } + if (watcher_id < 0) { + return NULL; + } + if (!g_dict_watchers_installed) { + assert(!g_dict_watch_events); + if (!(g_dict_watch_events = PyList_New(0))) { + return NULL; + } + } + g_dict_watchers_installed++; + return PyLong_FromLong(watcher_id); +} + +static PyObject * +clear_dict_watcher(PyObject *self, PyObject *watcher_id) +{ + if (PyDict_ClearWatcher(PyLong_AsLong(watcher_id))) { + return NULL; + } + g_dict_watchers_installed--; + if (!g_dict_watchers_installed) { + assert(g_dict_watch_events); + Py_CLEAR(g_dict_watch_events); + } + Py_RETURN_NONE; +} + +static PyObject * +watch_dict(PyObject *self, PyObject *args) +{ + PyObject *dict; + int watcher_id; + if (!PyArg_ParseTuple(args, "iO", &watcher_id, &dict)) { + return NULL; + } + if (PyDict_Watch(watcher_id, dict)) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +unwatch_dict(PyObject *self, PyObject *args) +{ + PyObject *dict; + int watcher_id; + if (!PyArg_ParseTuple(args, "iO", &watcher_id, &dict)) { + return NULL; + } + if (PyDict_Unwatch(watcher_id, dict)) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +get_dict_watcher_events(PyObject *self, PyObject *Py_UNUSED(args)) +{ + if (!g_dict_watch_events) { + PyErr_SetString(PyExc_RuntimeError, "no watchers active"); + return NULL; + } + return Py_NewRef(g_dict_watch_events); +} + +// Test type watchers +static PyObject *g_type_modified_events; +static int g_type_watchers_installed; + +static int +type_modified_callback(PyTypeObject *type) +{ + assert(PyList_Check(g_type_modified_events)); + if(PyList_Append(g_type_modified_events, (PyObject *)type) < 0) { + return -1; + } + return 0; +} + +static int +type_modified_callback_wrap(PyTypeObject *type) +{ + assert(PyList_Check(g_type_modified_events)); + PyObject *list = PyList_New(0); + if (list == NULL) { + return -1; + } + if (PyList_Append(list, (PyObject *)type) < 0) { + Py_DECREF(list); + return -1; + } + if (PyList_Append(g_type_modified_events, list) < 0) { + Py_DECREF(list); + return -1; + } + Py_DECREF(list); + return 0; +} + +static int +type_modified_callback_error(PyTypeObject *type) +{ + PyErr_SetString(PyExc_RuntimeError, "boom!"); + return -1; +} + +static PyObject * +add_type_watcher(PyObject *self, PyObject *kind) +{ + int watcher_id; + assert(PyLong_Check(kind)); + long kind_l = PyLong_AsLong(kind); + if (kind_l == 2) { + watcher_id = PyType_AddWatcher(type_modified_callback_wrap); + } + else if (kind_l == 1) { + watcher_id = PyType_AddWatcher(type_modified_callback_error); + } + else { + watcher_id = PyType_AddWatcher(type_modified_callback); + } + if (watcher_id < 0) { + return NULL; + } + if (!g_type_watchers_installed) { + assert(!g_type_modified_events); + if (!(g_type_modified_events = PyList_New(0))) { + return NULL; + } + } + g_type_watchers_installed++; + return PyLong_FromLong(watcher_id); +} + +static PyObject * +clear_type_watcher(PyObject *self, PyObject *watcher_id) +{ + if (PyType_ClearWatcher(PyLong_AsLong(watcher_id))) { + return NULL; + } + g_type_watchers_installed--; + if (!g_type_watchers_installed) { + assert(g_type_modified_events); + Py_CLEAR(g_type_modified_events); + } + Py_RETURN_NONE; +} + +static PyObject * +get_type_modified_events(PyObject *self, PyObject *Py_UNUSED(args)) +{ + if (!g_type_modified_events) { + PyErr_SetString(PyExc_RuntimeError, "no watchers active"); + return NULL; + } + return Py_NewRef(g_type_modified_events); +} + +static PyObject * +watch_type(PyObject *self, PyObject *args) +{ + PyObject *type; + int watcher_id; + if (!PyArg_ParseTuple(args, "iO", &watcher_id, &type)) { + return NULL; + } + if (PyType_Watch(watcher_id, type)) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +unwatch_type(PyObject *self, PyObject *args) +{ + PyObject *type; + int watcher_id; + if (!PyArg_ParseTuple(args, "iO", &watcher_id, &type)) { + return NULL; + } + if (PyType_Unwatch(watcher_id, type)) { + return NULL; + } + Py_RETURN_NONE; +} + + +// Test code object watching + +#define NUM_CODE_WATCHERS 2 +static int num_code_object_created_events[NUM_CODE_WATCHERS] = {0, 0}; +static int num_code_object_destroyed_events[NUM_CODE_WATCHERS] = {0, 0}; + +static int +handle_code_object_event(int which_watcher, PyCodeEvent event, PyCodeObject *co) { + if (event == PY_CODE_EVENT_CREATE) { + num_code_object_created_events[which_watcher]++; + } + else if (event == PY_CODE_EVENT_DESTROY) { + num_code_object_destroyed_events[which_watcher]++; + } + else { + return -1; + } + return 0; +} + +static int +first_code_object_callback(PyCodeEvent event, PyCodeObject *co) +{ + return handle_code_object_event(0, event, co); +} + +static int +second_code_object_callback(PyCodeEvent event, PyCodeObject *co) +{ + return handle_code_object_event(1, event, co); +} + +static int +noop_code_event_handler(PyCodeEvent event, PyCodeObject *co) +{ + return 0; +} + +static PyObject * +add_code_watcher(PyObject *self, PyObject *which_watcher) +{ + int watcher_id; + assert(PyLong_Check(which_watcher)); + long which_l = PyLong_AsLong(which_watcher); + if (which_l == 0) { + watcher_id = PyCode_AddWatcher(first_code_object_callback); + num_code_object_created_events[0] = 0; + num_code_object_destroyed_events[0] = 0; + } + else if (which_l == 1) { + watcher_id = PyCode_AddWatcher(second_code_object_callback); + num_code_object_created_events[1] = 0; + num_code_object_destroyed_events[1] = 0; + } + else { + return NULL; + } + if (watcher_id < 0) { + return NULL; + } + return PyLong_FromLong(watcher_id); +} + +static PyObject * +clear_code_watcher(PyObject *self, PyObject *watcher_id) +{ + assert(PyLong_Check(watcher_id)); + long watcher_id_l = PyLong_AsLong(watcher_id); + if (PyCode_ClearWatcher(watcher_id_l) < 0) { + return NULL; + } + // reset static events counters + if (watcher_id_l >= 0 && watcher_id_l < NUM_CODE_WATCHERS) { + num_code_object_created_events[watcher_id_l] = 0; + num_code_object_destroyed_events[watcher_id_l] = 0; + } + Py_RETURN_NONE; +} + +static PyObject * +get_code_watcher_num_created_events(PyObject *self, PyObject *watcher_id) +{ + assert(PyLong_Check(watcher_id)); + long watcher_id_l = PyLong_AsLong(watcher_id); + assert(watcher_id_l >= 0 && watcher_id_l < NUM_CODE_WATCHERS); + return PyLong_FromLong(num_code_object_created_events[watcher_id_l]); +} + +static PyObject * +get_code_watcher_num_destroyed_events(PyObject *self, PyObject *watcher_id) +{ + assert(PyLong_Check(watcher_id)); + long watcher_id_l = PyLong_AsLong(watcher_id); + assert(watcher_id_l >= 0 && watcher_id_l < NUM_CODE_WATCHERS); + return PyLong_FromLong(num_code_object_destroyed_events[watcher_id_l]); +} + +static PyObject * +allocate_too_many_code_watchers(PyObject *self, PyObject *args) +{ + int watcher_ids[CODE_MAX_WATCHERS + 1]; + int num_watchers = 0; + for (unsigned long i = 0; i < sizeof(watcher_ids) / sizeof(int); i++) { + int watcher_id = PyCode_AddWatcher(noop_code_event_handler); + if (watcher_id == -1) { + break; + } + watcher_ids[i] = watcher_id; + num_watchers++; + } + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + for (int i = 0; i < num_watchers; i++) { + if (PyCode_ClearWatcher(watcher_ids[i]) < 0) { + PyErr_WriteUnraisable(Py_None); + break; + } + } + if (type) { + PyErr_Restore(type, value, traceback); + return NULL; + } + else if (PyErr_Occurred()) { + return NULL; + } + Py_RETURN_NONE; +} + +// Test function watchers + +#define NUM_FUNC_WATCHERS 2 +static PyObject *pyfunc_watchers[NUM_FUNC_WATCHERS]; +static int func_watcher_ids[NUM_FUNC_WATCHERS] = {-1, -1}; + +static PyObject * +get_id(PyObject *obj) +{ + PyObject *builtins = PyEval_GetBuiltins(); // borrowed ref. + if (builtins == NULL) { + return NULL; + } + PyObject *id_str = PyUnicode_FromString("id"); + if (id_str == NULL) { + return NULL; + } + PyObject *id_func = PyObject_GetItem(builtins, id_str); + Py_DECREF(id_str); + if (id_func == NULL) { + return NULL; + } + PyObject *stack[] = {obj}; + PyObject *id = PyObject_Vectorcall(id_func, stack, 1, NULL); + Py_DECREF(id_func); + return id; +} + +static int +call_pyfunc_watcher(PyObject *watcher, PyFunction_WatchEvent event, + PyFunctionObject *func, PyObject *new_value) +{ + PyObject *event_obj = PyLong_FromLong(event); + if (event_obj == NULL) { + return -1; + } + if (new_value == NULL) { + new_value = Py_None; + } + Py_INCREF(new_value); + PyObject *func_or_id = NULL; + if (event == PyFunction_EVENT_DESTROY) { + /* Don't expose a function that's about to be destroyed to managed code */ + func_or_id = get_id((PyObject *) func); + if (func_or_id == NULL) { + Py_DECREF(event_obj); + Py_DECREF(new_value); + return -1; + } + } + else { + Py_INCREF(func); + func_or_id = (PyObject *) func; + } + PyObject *stack[] = {event_obj, func_or_id, new_value}; + PyObject *res = PyObject_Vectorcall(watcher, stack, 3, NULL); + int st = (res == NULL) ? -1 : 0; + Py_XDECREF(res); + Py_DECREF(new_value); + Py_DECREF(event_obj); + Py_DECREF(func_or_id); + return st; +} + +static int +first_func_watcher_callback(PyFunction_WatchEvent event, PyFunctionObject *func, + PyObject *new_value) +{ + return call_pyfunc_watcher(pyfunc_watchers[0], event, func, new_value); +} + +static int +second_func_watcher_callback(PyFunction_WatchEvent event, + PyFunctionObject *func, PyObject *new_value) +{ + return call_pyfunc_watcher(pyfunc_watchers[1], event, func, new_value); +} + +static PyFunction_WatchCallback func_watcher_callbacks[NUM_FUNC_WATCHERS] = { + first_func_watcher_callback, + second_func_watcher_callback +}; + +static int +add_func_event(PyObject *module, const char *name, PyFunction_WatchEvent event) +{ + PyObject *value = PyLong_FromLong(event); + if (value == NULL) { + return -1; + } + int ok = PyModule_AddObjectRef(module, name, value); + Py_DECREF(value); + return ok; +} + +static PyObject * +add_func_watcher(PyObject *self, PyObject *func) +{ + if (!PyFunction_Check(func)) { + PyErr_SetString(PyExc_TypeError, "'func' must be a function"); + return NULL; + } + int idx = -1; + for (int i = 0; i < NUM_FUNC_WATCHERS; i++) { + if (func_watcher_ids[i] == -1) { + idx = i; + break; + } + } + if (idx == -1) { + PyErr_SetString(PyExc_RuntimeError, "no free watchers"); + return NULL; + } + PyObject *result = PyLong_FromLong(idx); + if (result == NULL) { + return NULL; + } + func_watcher_ids[idx] = PyFunction_AddWatcher(func_watcher_callbacks[idx]); + if (func_watcher_ids[idx] < 0) { + Py_DECREF(result); + return NULL; + } + pyfunc_watchers[idx] = Py_NewRef(func); + return result; +} + +static PyObject * +clear_func_watcher(PyObject *self, PyObject *watcher_id_obj) +{ + long watcher_id = PyLong_AsLong(watcher_id_obj); + if ((watcher_id < INT_MIN) || (watcher_id > INT_MAX)) { + PyErr_SetString(PyExc_ValueError, "invalid watcher ID"); + return NULL; + } + int wid = (int) watcher_id; + if (PyFunction_ClearWatcher(wid) < 0) { + return NULL; + } + int idx = -1; + for (int i = 0; i < NUM_FUNC_WATCHERS; i++) { + if (func_watcher_ids[i] == wid) { + idx = i; + break; + } + } + assert(idx != -1); + Py_CLEAR(pyfunc_watchers[idx]); + func_watcher_ids[idx] = -1; + Py_RETURN_NONE; +} + +static int +noop_func_event_handler(PyFunction_WatchEvent event, PyFunctionObject *func, + PyObject *new_value) +{ + return 0; +} + +static PyObject * +allocate_too_many_func_watchers(PyObject *self, PyObject *args) +{ + int watcher_ids[FUNC_MAX_WATCHERS + 1]; + int num_watchers = 0; + for (unsigned long i = 0; i < sizeof(watcher_ids) / sizeof(int); i++) { + int watcher_id = PyFunction_AddWatcher(noop_func_event_handler); + if (watcher_id == -1) { + break; + } + watcher_ids[i] = watcher_id; + num_watchers++; + } + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + for (int i = 0; i < num_watchers; i++) { + if (PyFunction_ClearWatcher(watcher_ids[i]) < 0) { + PyErr_WriteUnraisable(Py_None); + break; + } + } + if (type) { + PyErr_Restore(type, value, traceback); + return NULL; + } + else if (PyErr_Occurred()) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +set_func_defaults(PyObject *self, PyObject *args) +{ + PyObject *func = NULL; + PyObject *defaults = NULL; + if (!PyArg_ParseTuple(args, "OO", &func, &defaults)) { + return NULL; + } + if (PyFunction_SetDefaults(func, defaults) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +set_func_kwdefaults(PyObject *self, PyObject *args) +{ + PyObject *func = NULL; + PyObject *kwdefaults = NULL; + if (!PyArg_ParseTuple(args, "OO", &func, &kwdefaults)) { + return NULL; + } + if (PyFunction_SetKwDefaults(func, kwdefaults) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyMethodDef test_methods[] = { + // Dict watchers. + {"add_dict_watcher", add_dict_watcher, METH_O, NULL}, + {"clear_dict_watcher", clear_dict_watcher, METH_O, NULL}, + {"watch_dict", watch_dict, METH_VARARGS, NULL}, + {"unwatch_dict", unwatch_dict, METH_VARARGS, NULL}, + {"get_dict_watcher_events", + (PyCFunction) get_dict_watcher_events, METH_NOARGS, NULL}, + + // Type watchers. + {"add_type_watcher", add_type_watcher, METH_O, NULL}, + {"clear_type_watcher", clear_type_watcher, METH_O, NULL}, + {"watch_type", watch_type, METH_VARARGS, NULL}, + {"unwatch_type", unwatch_type, METH_VARARGS, NULL}, + {"get_type_modified_events", + (PyCFunction) get_type_modified_events, METH_NOARGS, NULL}, + + // Code object watchers. + {"add_code_watcher", add_code_watcher, METH_O, NULL}, + {"clear_code_watcher", clear_code_watcher, METH_O, NULL}, + {"get_code_watcher_num_created_events", + get_code_watcher_num_created_events, METH_O, NULL}, + {"get_code_watcher_num_destroyed_events", + get_code_watcher_num_destroyed_events, METH_O, NULL}, + {"allocate_too_many_code_watchers", + (PyCFunction) allocate_too_many_code_watchers, METH_NOARGS, NULL}, + + // Function watchers. + {"add_func_watcher", add_func_watcher, METH_O, NULL}, + {"clear_func_watcher", clear_func_watcher, METH_O, NULL}, + {"set_func_defaults_via_capi", set_func_defaults, METH_VARARGS, NULL}, + {"set_func_kwdefaults_via_capi", set_func_kwdefaults, METH_VARARGS, NULL}, + {"allocate_too_many_func_watchers", allocate_too_many_func_watchers, + METH_NOARGS, NULL}, + {NULL}, +}; + +int +_PyTestCapi_Init_Watchers(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + + /* Expose each event as an attribute on the module */ +#define ADD_EVENT(event) \ + if (add_func_event(mod, "PYFUNC_EVENT_" #event, \ + PyFunction_EVENT_##event)) { \ + return -1; \ + } + FOREACH_FUNC_EVENT(ADD_EVENT); +#undef ADD_EVENT + + return 0; +} diff --git a/Modules/_testcapi_feature_macros.inc b/Modules/_testcapi_feature_macros.inc new file mode 100644 index 00000000000..b1763b57d91 --- /dev/null +++ b/Modules/_testcapi_feature_macros.inc @@ -0,0 +1,49 @@ +// Generated by Tools/scripts/stable_abi.py + +// Add an entry in dict `result` for each Stable ABI feature macro. + +#ifdef HAVE_FORK + res = PyDict_SetItemString(result, "HAVE_FORK", Py_True); +#else + res = PyDict_SetItemString(result, "HAVE_FORK", Py_False); +#endif +if (res) { + Py_DECREF(result); return NULL; +} + +#ifdef MS_WINDOWS + res = PyDict_SetItemString(result, "MS_WINDOWS", Py_True); +#else + res = PyDict_SetItemString(result, "MS_WINDOWS", Py_False); +#endif +if (res) { + Py_DECREF(result); return NULL; +} + +#ifdef PY_HAVE_THREAD_NATIVE_ID + res = PyDict_SetItemString(result, "PY_HAVE_THREAD_NATIVE_ID", Py_True); +#else + res = PyDict_SetItemString(result, "PY_HAVE_THREAD_NATIVE_ID", Py_False); +#endif +if (res) { + Py_DECREF(result); return NULL; +} + +#ifdef Py_REF_DEBUG + res = PyDict_SetItemString(result, "Py_REF_DEBUG", Py_True); +#else + res = PyDict_SetItemString(result, "Py_REF_DEBUG", Py_False); +#endif +if (res) { + Py_DECREF(result); return NULL; +} + +#ifdef USE_STACKCHECK + res = PyDict_SetItemString(result, "USE_STACKCHECK", Py_True); +#else + res = PyDict_SetItemString(result, "USE_STACKCHECK", Py_False); +#endif +if (res) { + Py_DECREF(result); return NULL; +} + diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index c9ba1489731..46c025bf534 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -12,21 +12,21 @@ macro defined, but only the public C API must be tested here. */ #undef Py_BUILD_CORE_MODULE +#undef Py_BUILD_CORE_BUILTIN + /* Always enable assertions */ #undef NDEBUG #define PY_SSIZE_T_CLEAN #include "Python.h" -#include "frameobject.h" // PyFrame_Check() -#include "datetime.h" // PyDateTimeAPI +#include "frameobject.h" // PyFrame_New #include "marshal.h" // PyMarshal_WriteLongToFile -#include "structmember.h" // PyMemberDef +#include "structmember.h" // for offsetof(), T_OBJECT #include // FLT_MAX #include - -#ifdef MS_WINDOWS -# include // struct timeval +#ifndef MS_WINDOWS +#include #endif #ifdef HAVE_SYS_WAIT_H @@ -37,10 +37,16 @@ # error "_testcapi must test the public Python C API, not CPython internal C API" #endif +#ifdef bool +# error "The public headers should not include , see bpo-46748" +#endif + +// Several parts of this module are broken out into files in _testcapi/. +// Include definitions from there. +#include "_testcapi/parts.h" // Forward declarations static struct PyModuleDef _testcapimodule; -static PyType_Spec HeapTypeNameType_Spec; static PyObject *TestError; /* set to exception object in init */ @@ -302,6 +308,8 @@ test_dict_inner(int count) } } + + static PyObject* test_dict_iteration(PyObject* self, PyObject *Py_UNUSED(ignored)) { @@ -333,8 +341,7 @@ dict_getitem_knownhash(PyObject *self, PyObject *args) return NULL; } - Py_XINCREF(result); - return result; + return Py_XNewRef(result); } /* Issue #4701: Check that PyObject_Hash implicitly calls @@ -391,7 +398,7 @@ pycompilestring(PyObject* self, PyObject *obj) { if (the_string == NULL) { return NULL; } - return Py_CompileString(the_string, "blech", Py_file_input); + return Py_CompileString(the_string, "", Py_file_input); } static PyObject* @@ -457,537 +464,6 @@ test_lazy_hash_inheritance(PyObject* self, PyObject *Py_UNUSED(ignored)) Py_RETURN_NONE; } - -/* Tests of PyLong_{As, From}{Unsigned,}Long(), and - PyLong_{As, From}{Unsigned,}LongLong(). - - Note that the meat of the test is contained in testcapi_long.h. - This is revolting, but delicate code duplication is worse: "almost - exactly the same" code is needed to test long long, but the ubiquitous - dependence on type names makes it impossible to use a parameterized - function. A giant macro would be even worse than this. A C++ template - would be perfect. - - The "report an error" functions are deliberately not part of the #include - file: if the test fails, you can set a breakpoint in the appropriate - error function directly, and crawl back from there in the debugger. -*/ - -#define UNBIND(X) Py_DECREF(X); (X) = NULL - -static PyObject * -raise_test_long_error(const char* msg) -{ - return raiseTestError("test_long_api", msg); -} - -#define TESTNAME test_long_api_inner -#define TYPENAME long -#define F_S_TO_PY PyLong_FromLong -#define F_PY_TO_S PyLong_AsLong -#define F_U_TO_PY PyLong_FromUnsignedLong -#define F_PY_TO_U PyLong_AsUnsignedLong - -#include "testcapi_long.h" - -static PyObject * -test_long_api(PyObject* self, PyObject *Py_UNUSED(ignored)) -{ - return TESTNAME(raise_test_long_error); -} - -#undef TESTNAME -#undef TYPENAME -#undef F_S_TO_PY -#undef F_PY_TO_S -#undef F_U_TO_PY -#undef F_PY_TO_U - -static PyObject * -raise_test_longlong_error(const char* msg) -{ - return raiseTestError("test_longlong_api", msg); -} - -#define TESTNAME test_longlong_api_inner -#define TYPENAME long long -#define F_S_TO_PY PyLong_FromLongLong -#define F_PY_TO_S PyLong_AsLongLong -#define F_U_TO_PY PyLong_FromUnsignedLongLong -#define F_PY_TO_U PyLong_AsUnsignedLongLong - -#include "testcapi_long.h" - -static PyObject * -test_longlong_api(PyObject* self, PyObject *args) -{ - return TESTNAME(raise_test_longlong_error); -} - -#undef TESTNAME -#undef TYPENAME -#undef F_S_TO_PY -#undef F_PY_TO_S -#undef F_U_TO_PY -#undef F_PY_TO_U - -/* Test the PyLong_AsLongAndOverflow API. General conversion to PY_LONG - is tested by test_long_api_inner. This test will concentrate on proper - handling of overflow. -*/ - -static PyObject * -test_long_and_overflow(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *num, *one, *temp; - long value; - int overflow; - - /* Test that overflow is set properly for a large value. */ - /* num is a number larger than LONG_MAX even on 64-bit platforms */ - num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); - if (num == NULL) - return NULL; - overflow = 1234; - value = PyLong_AsLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -1) - return raiseTestError("test_long_and_overflow", - "return value was not set to -1"); - if (overflow != 1) - return raiseTestError("test_long_and_overflow", - "overflow was not set to 1"); - - /* Same again, with num = LONG_MAX + 1 */ - num = PyLong_FromLong(LONG_MAX); - if (num == NULL) - return NULL; - one = PyLong_FromLong(1L); - if (one == NULL) { - Py_DECREF(num); - return NULL; - } - temp = PyNumber_Add(num, one); - Py_DECREF(one); - Py_DECREF(num); - num = temp; - if (num == NULL) - return NULL; - overflow = 0; - value = PyLong_AsLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -1) - return raiseTestError("test_long_and_overflow", - "return value was not set to -1"); - if (overflow != 1) - return raiseTestError("test_long_and_overflow", - "overflow was not set to 1"); - - /* Test that overflow is set properly for a large negative value. */ - /* num is a number smaller than LONG_MIN even on 64-bit platforms */ - num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); - if (num == NULL) - return NULL; - overflow = 1234; - value = PyLong_AsLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -1) - return raiseTestError("test_long_and_overflow", - "return value was not set to -1"); - if (overflow != -1) - return raiseTestError("test_long_and_overflow", - "overflow was not set to -1"); - - /* Same again, with num = LONG_MIN - 1 */ - num = PyLong_FromLong(LONG_MIN); - if (num == NULL) - return NULL; - one = PyLong_FromLong(1L); - if (one == NULL) { - Py_DECREF(num); - return NULL; - } - temp = PyNumber_Subtract(num, one); - Py_DECREF(one); - Py_DECREF(num); - num = temp; - if (num == NULL) - return NULL; - overflow = 0; - value = PyLong_AsLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -1) - return raiseTestError("test_long_and_overflow", - "return value was not set to -1"); - if (overflow != -1) - return raiseTestError("test_long_and_overflow", - "overflow was not set to -1"); - - /* Test that overflow is cleared properly for small values. */ - num = PyLong_FromString("FF", NULL, 16); - if (num == NULL) - return NULL; - overflow = 1234; - value = PyLong_AsLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != 0xFF) - return raiseTestError("test_long_and_overflow", - "expected return value 0xFF"); - if (overflow != 0) - return raiseTestError("test_long_and_overflow", - "overflow was not cleared"); - - num = PyLong_FromString("-FF", NULL, 16); - if (num == NULL) - return NULL; - overflow = 0; - value = PyLong_AsLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -0xFF) - return raiseTestError("test_long_and_overflow", - "expected return value 0xFF"); - if (overflow != 0) - return raiseTestError("test_long_and_overflow", - "overflow was set incorrectly"); - - num = PyLong_FromLong(LONG_MAX); - if (num == NULL) - return NULL; - overflow = 1234; - value = PyLong_AsLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != LONG_MAX) - return raiseTestError("test_long_and_overflow", - "expected return value LONG_MAX"); - if (overflow != 0) - return raiseTestError("test_long_and_overflow", - "overflow was not cleared"); - - num = PyLong_FromLong(LONG_MIN); - if (num == NULL) - return NULL; - overflow = 0; - value = PyLong_AsLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != LONG_MIN) - return raiseTestError("test_long_and_overflow", - "expected return value LONG_MIN"); - if (overflow != 0) - return raiseTestError("test_long_and_overflow", - "overflow was not cleared"); - - Py_RETURN_NONE; -} - -/* Test the PyLong_AsLongLongAndOverflow API. General conversion to - long long is tested by test_long_api_inner. This test will - concentrate on proper handling of overflow. -*/ - -static PyObject * -test_long_long_and_overflow(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *num, *one, *temp; - long long value; - int overflow; - - /* Test that overflow is set properly for a large value. */ - /* num is a number larger than LLONG_MAX on a typical machine. */ - num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); - if (num == NULL) - return NULL; - overflow = 1234; - value = PyLong_AsLongLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -1) - return raiseTestError("test_long_long_and_overflow", - "return value was not set to -1"); - if (overflow != 1) - return raiseTestError("test_long_long_and_overflow", - "overflow was not set to 1"); - - /* Same again, with num = LLONG_MAX + 1 */ - num = PyLong_FromLongLong(LLONG_MAX); - if (num == NULL) - return NULL; - one = PyLong_FromLong(1L); - if (one == NULL) { - Py_DECREF(num); - return NULL; - } - temp = PyNumber_Add(num, one); - Py_DECREF(one); - Py_DECREF(num); - num = temp; - if (num == NULL) - return NULL; - overflow = 0; - value = PyLong_AsLongLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -1) - return raiseTestError("test_long_long_and_overflow", - "return value was not set to -1"); - if (overflow != 1) - return raiseTestError("test_long_long_and_overflow", - "overflow was not set to 1"); - - /* Test that overflow is set properly for a large negative value. */ - /* num is a number smaller than LLONG_MIN on a typical platform */ - num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); - if (num == NULL) - return NULL; - overflow = 1234; - value = PyLong_AsLongLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -1) - return raiseTestError("test_long_long_and_overflow", - "return value was not set to -1"); - if (overflow != -1) - return raiseTestError("test_long_long_and_overflow", - "overflow was not set to -1"); - - /* Same again, with num = LLONG_MIN - 1 */ - num = PyLong_FromLongLong(LLONG_MIN); - if (num == NULL) - return NULL; - one = PyLong_FromLong(1L); - if (one == NULL) { - Py_DECREF(num); - return NULL; - } - temp = PyNumber_Subtract(num, one); - Py_DECREF(one); - Py_DECREF(num); - num = temp; - if (num == NULL) - return NULL; - overflow = 0; - value = PyLong_AsLongLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -1) - return raiseTestError("test_long_long_and_overflow", - "return value was not set to -1"); - if (overflow != -1) - return raiseTestError("test_long_long_and_overflow", - "overflow was not set to -1"); - - /* Test that overflow is cleared properly for small values. */ - num = PyLong_FromString("FF", NULL, 16); - if (num == NULL) - return NULL; - overflow = 1234; - value = PyLong_AsLongLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != 0xFF) - return raiseTestError("test_long_long_and_overflow", - "expected return value 0xFF"); - if (overflow != 0) - return raiseTestError("test_long_long_and_overflow", - "overflow was not cleared"); - - num = PyLong_FromString("-FF", NULL, 16); - if (num == NULL) - return NULL; - overflow = 0; - value = PyLong_AsLongLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -0xFF) - return raiseTestError("test_long_long_and_overflow", - "expected return value 0xFF"); - if (overflow != 0) - return raiseTestError("test_long_long_and_overflow", - "overflow was set incorrectly"); - - num = PyLong_FromLongLong(LLONG_MAX); - if (num == NULL) - return NULL; - overflow = 1234; - value = PyLong_AsLongLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != LLONG_MAX) - return raiseTestError("test_long_long_and_overflow", - "expected return value LLONG_MAX"); - if (overflow != 0) - return raiseTestError("test_long_long_and_overflow", - "overflow was not cleared"); - - num = PyLong_FromLongLong(LLONG_MIN); - if (num == NULL) - return NULL; - overflow = 0; - value = PyLong_AsLongLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != LLONG_MIN) - return raiseTestError("test_long_long_and_overflow", - "expected return value LLONG_MIN"); - if (overflow != 0) - return raiseTestError("test_long_long_and_overflow", - "overflow was not cleared"); - - Py_RETURN_NONE; -} - -/* Test the PyLong_As{Size,Ssize}_t API. At present this just tests that - non-integer arguments are handled correctly. It should be extended to - test overflow handling. - */ - -static PyObject * -test_long_as_size_t(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - size_t out_u; - Py_ssize_t out_s; - - Py_INCREF(Py_None); - - out_u = PyLong_AsSize_t(Py_None); - if (out_u != (size_t)-1 || !PyErr_Occurred()) - return raiseTestError("test_long_as_size_t", - "PyLong_AsSize_t(None) didn't complain"); - if (!PyErr_ExceptionMatches(PyExc_TypeError)) - return raiseTestError("test_long_as_size_t", - "PyLong_AsSize_t(None) raised " - "something other than TypeError"); - PyErr_Clear(); - - out_s = PyLong_AsSsize_t(Py_None); - if (out_s != (Py_ssize_t)-1 || !PyErr_Occurred()) - return raiseTestError("test_long_as_size_t", - "PyLong_AsSsize_t(None) didn't complain"); - if (!PyErr_ExceptionMatches(PyExc_TypeError)) - return raiseTestError("test_long_as_size_t", - "PyLong_AsSsize_t(None) raised " - "something other than TypeError"); - PyErr_Clear(); - - /* Py_INCREF(Py_None) omitted - we already have a reference to it. */ - return Py_None; -} - -static PyObject * -test_long_as_unsigned_long_long_mask(PyObject *self, - PyObject *Py_UNUSED(ignored)) -{ - unsigned long long res = PyLong_AsUnsignedLongLongMask(NULL); - - if (res != (unsigned long long)-1 || !PyErr_Occurred()) { - return raiseTestError("test_long_as_unsigned_long_long_mask", - "PyLong_AsUnsignedLongLongMask(NULL) didn't " - "complain"); - } - if (!PyErr_ExceptionMatches(PyExc_SystemError)) { - return raiseTestError("test_long_as_unsigned_long_long_mask", - "PyLong_AsUnsignedLongLongMask(NULL) raised " - "something other than SystemError"); - } - PyErr_Clear(); - Py_RETURN_NONE; -} - -/* Test the PyLong_AsDouble API. At present this just tests that - non-integer arguments are handled correctly. - */ - -static PyObject * -test_long_as_double(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - double out; - - Py_INCREF(Py_None); - - out = PyLong_AsDouble(Py_None); - if (out != -1.0 || !PyErr_Occurred()) - return raiseTestError("test_long_as_double", - "PyLong_AsDouble(None) didn't complain"); - if (!PyErr_ExceptionMatches(PyExc_TypeError)) - return raiseTestError("test_long_as_double", - "PyLong_AsDouble(None) raised " - "something other than TypeError"); - PyErr_Clear(); - - /* Py_INCREF(Py_None) omitted - we already have a reference to it. */ - return Py_None; -} - -/* Test the L code for PyArg_ParseTuple. This should deliver a long long - for both long and int arguments. The test may leak a little memory if - it fails. -*/ -static PyObject * -test_L_code(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *tuple, *num; - long long value; - - tuple = PyTuple_New(1); - if (tuple == NULL) - return NULL; - - num = PyLong_FromLong(42); - if (num == NULL) - return NULL; - - PyTuple_SET_ITEM(tuple, 0, num); - - value = -1; - if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) { - return NULL; - } - if (value != 42) - return raiseTestError("test_L_code", - "L code returned wrong value for long 42"); - - Py_DECREF(num); - num = PyLong_FromLong(42); - if (num == NULL) - return NULL; - - PyTuple_SET_ITEM(tuple, 0, num); - - value = -1; - if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) { - return NULL; - } - if (value != 42) - return raiseTestError("test_L_code", - "L code returned wrong value for int 42"); - - Py_DECREF(tuple); - Py_RETURN_NONE; -} - static PyObject * return_none(void *unused) { @@ -1138,6 +614,17 @@ test_get_statictype_slots(PyObject *self, PyObject *Py_UNUSED(ignored)) } +static PyType_Slot HeapTypeNameType_slots[] = { + {0}, +}; + +static PyType_Spec HeapTypeNameType_Spec = { + .name = "_testcapi.HeapTypeNameType", + .basicsize = sizeof(PyObject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = HeapTypeNameType_slots, +}; + static PyObject * test_get_type_name(PyObject *self, PyObject *Py_UNUSED(ignored)) { @@ -1176,126 +663,6 @@ test_get_type_name(PyObject *self, PyObject *Py_UNUSED(ignored)) } -static PyObject * -simple_str(PyObject *self) { - return PyUnicode_FromString(""); -} - - -static PyObject * -test_type_from_ephemeral_spec(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - // Test that a heap type can be created from a spec that's later deleted - // (along with all its contents). - // All necessary data must be copied and held by the class - PyType_Spec *spec = NULL; - char *name = NULL; - char *doc = NULL; - PyType_Slot *slots = NULL; - PyObject *class = NULL; - PyObject *instance = NULL; - PyObject *obj = NULL; - PyObject *result = NULL; - - /* create a spec (and all its contents) on the heap */ - - const char NAME[] = "testcapi._Test"; - const char DOC[] = "a test class"; - - spec = PyMem_New(PyType_Spec, 1); - if (spec == NULL) { - PyErr_NoMemory(); - goto finally; - } - name = PyMem_New(char, sizeof(NAME)); - if (name == NULL) { - PyErr_NoMemory(); - goto finally; - } - memcpy(name, NAME, sizeof(NAME)); - - doc = PyMem_New(char, sizeof(DOC)); - if (name == NULL) { - PyErr_NoMemory(); - goto finally; - } - memcpy(doc, DOC, sizeof(DOC)); - - spec->name = name; - spec->basicsize = sizeof(PyObject); - spec->itemsize = 0; - spec->flags = Py_TPFLAGS_DEFAULT; - slots = PyMem_New(PyType_Slot, 3); - if (slots == NULL) { - PyErr_NoMemory(); - goto finally; - } - slots[0].slot = Py_tp_str; - slots[0].pfunc = simple_str; - slots[1].slot = Py_tp_doc; - slots[1].pfunc = doc; - slots[2].slot = 0; - slots[2].pfunc = NULL; - spec->slots = slots; - - /* create the class */ - - class = PyType_FromSpec(spec); - if (class == NULL) { - goto finally; - } - - /* deallocate the spec (and all contents) */ - - // (Explicitly ovewrite memory before freeing, - // so bugs show themselves even without the debug allocator's help.) - memset(spec, 0xdd, sizeof(PyType_Spec)); - PyMem_Del(spec); - spec = NULL; - memset(name, 0xdd, sizeof(NAME)); - PyMem_Del(name); - name = NULL; - memset(doc, 0xdd, sizeof(DOC)); - PyMem_Del(doc); - doc = NULL; - memset(slots, 0xdd, 3 * sizeof(PyType_Slot)); - PyMem_Del(slots); - slots = NULL; - - /* check that everything works */ - - PyTypeObject *class_tp = (PyTypeObject *)class; - PyHeapTypeObject *class_ht = (PyHeapTypeObject *)class; - assert(strcmp(class_tp->tp_name, "testcapi._Test") == 0); - assert(strcmp(PyUnicode_AsUTF8(class_ht->ht_name), "_Test") == 0); - assert(strcmp(PyUnicode_AsUTF8(class_ht->ht_qualname), "_Test") == 0); - assert(strcmp(class_tp->tp_doc, "a test class") == 0); - - // call and check __str__ - instance = PyObject_CallNoArgs(class); - if (instance == NULL) { - goto finally; - } - obj = PyObject_Str(instance); - if (obj == NULL) { - goto finally; - } - assert(strcmp(PyUnicode_AsUTF8(obj), "") == 0); - Py_CLEAR(obj); - - result = Py_NewRef(Py_None); - finally: - PyMem_Del(spec); - PyMem_Del(name); - PyMem_Del(doc); - PyMem_Del(slots); - Py_XDECREF(class); - Py_XDECREF(instance); - Py_XDECREF(obj); - return result; -} - - static PyObject * test_get_type_qualname(PyObject *self, PyObject *Py_UNUSED(ignored)) { @@ -1335,1170 +702,6 @@ test_get_type_qualname(PyObject *self, PyObject *Py_UNUSED(ignored)) Py_RETURN_NONE; } - -static PyObject * -get_args(PyObject *self, PyObject *args) -{ - if (args == NULL) { - args = Py_None; - } - Py_INCREF(args); - return args; -} - -static PyObject * -get_kwargs(PyObject *self, PyObject *args, PyObject *kwargs) -{ - if (kwargs == NULL) { - kwargs = Py_None; - } - Py_INCREF(kwargs); - return kwargs; -} - -/* Test tuple argument processing */ -static PyObject * -getargs_tuple(PyObject *self, PyObject *args) -{ - int a, b, c; - if (!PyArg_ParseTuple(args, "i(ii)", &a, &b, &c)) - return NULL; - return Py_BuildValue("iii", a, b, c); -} - -/* test PyArg_ParseTupleAndKeywords */ -static PyObject * -getargs_keywords(PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *keywords[] = {"arg1","arg2","arg3","arg4","arg5", NULL}; - static const char fmt[] = "(ii)i|(i(ii))(iii)i"; - int int_args[10]={-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords, - &int_args[0], &int_args[1], &int_args[2], &int_args[3], &int_args[4], - &int_args[5], &int_args[6], &int_args[7], &int_args[8], &int_args[9])) - return NULL; - return Py_BuildValue("iiiiiiiiii", - int_args[0], int_args[1], int_args[2], int_args[3], int_args[4], - int_args[5], int_args[6], int_args[7], int_args[8], int_args[9]); -} - -/* test PyArg_ParseTupleAndKeywords keyword-only arguments */ -static PyObject * -getargs_keyword_only(PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *keywords[] = {"required", "optional", "keyword_only", NULL}; - int required = -1; - int optional = -1; - int keyword_only = -1; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i$i", keywords, - &required, &optional, &keyword_only)) - return NULL; - return Py_BuildValue("iii", required, optional, keyword_only); -} - -/* test PyArg_ParseTupleAndKeywords positional-only arguments */ -static PyObject * -getargs_positional_only_and_keywords(PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *keywords[] = {"", "", "keyword", NULL}; - int required = -1; - int optional = -1; - int keyword = -1; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii", keywords, - &required, &optional, &keyword)) - return NULL; - return Py_BuildValue("iii", required, optional, keyword); -} - -/* Functions to call PyArg_ParseTuple with integer format codes, - and return the result. -*/ -static PyObject * -getargs_b(PyObject *self, PyObject *args) -{ - unsigned char value; - if (!PyArg_ParseTuple(args, "b", &value)) - return NULL; - return PyLong_FromUnsignedLong((unsigned long)value); -} - -static PyObject * -getargs_B(PyObject *self, PyObject *args) -{ - unsigned char value; - if (!PyArg_ParseTuple(args, "B", &value)) - return NULL; - return PyLong_FromUnsignedLong((unsigned long)value); -} - -static PyObject * -getargs_h(PyObject *self, PyObject *args) -{ - short value; - if (!PyArg_ParseTuple(args, "h", &value)) - return NULL; - return PyLong_FromLong((long)value); -} - -static PyObject * -getargs_H(PyObject *self, PyObject *args) -{ - unsigned short value; - if (!PyArg_ParseTuple(args, "H", &value)) - return NULL; - return PyLong_FromUnsignedLong((unsigned long)value); -} - -static PyObject * -getargs_I(PyObject *self, PyObject *args) -{ - unsigned int value; - if (!PyArg_ParseTuple(args, "I", &value)) - return NULL; - return PyLong_FromUnsignedLong((unsigned long)value); -} - -static PyObject * -getargs_k(PyObject *self, PyObject *args) -{ - unsigned long value; - if (!PyArg_ParseTuple(args, "k", &value)) - return NULL; - return PyLong_FromUnsignedLong(value); -} - -static PyObject * -getargs_i(PyObject *self, PyObject *args) -{ - int value; - if (!PyArg_ParseTuple(args, "i", &value)) - return NULL; - return PyLong_FromLong((long)value); -} - -static PyObject * -getargs_l(PyObject *self, PyObject *args) -{ - long value; - if (!PyArg_ParseTuple(args, "l", &value)) - return NULL; - return PyLong_FromLong(value); -} - -static PyObject * -getargs_n(PyObject *self, PyObject *args) -{ - Py_ssize_t value; - if (!PyArg_ParseTuple(args, "n", &value)) - return NULL; - return PyLong_FromSsize_t(value); -} - -static PyObject * -getargs_p(PyObject *self, PyObject *args) -{ - int value; - if (!PyArg_ParseTuple(args, "p", &value)) - return NULL; - return PyLong_FromLong(value); -} - -static PyObject * -getargs_L(PyObject *self, PyObject *args) -{ - long long value; - if (!PyArg_ParseTuple(args, "L", &value)) - return NULL; - return PyLong_FromLongLong(value); -} - -static PyObject * -getargs_K(PyObject *self, PyObject *args) -{ - unsigned long long value; - if (!PyArg_ParseTuple(args, "K", &value)) - return NULL; - return PyLong_FromUnsignedLongLong(value); -} - -/* This function not only tests the 'k' getargs code, but also the - PyLong_AsUnsignedLongMask() function. */ -static PyObject * -test_k_code(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *tuple, *num; - unsigned long value; - - tuple = PyTuple_New(1); - if (tuple == NULL) - return NULL; - - /* a number larger than ULONG_MAX even on 64-bit platforms */ - num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); - if (num == NULL) - return NULL; - - value = PyLong_AsUnsignedLongMask(num); - if (value != ULONG_MAX) - return raiseTestError("test_k_code", - "PyLong_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF"); - - PyTuple_SET_ITEM(tuple, 0, num); - - value = 0; - if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) { - return NULL; - } - if (value != ULONG_MAX) - return raiseTestError("test_k_code", - "k code returned wrong value for long 0xFFF...FFF"); - - Py_DECREF(num); - num = PyLong_FromString("-FFFFFFFF000000000000000042", NULL, 16); - if (num == NULL) - return NULL; - - value = PyLong_AsUnsignedLongMask(num); - if (value != (unsigned long)-0x42) - return raiseTestError("test_k_code", - "PyLong_AsUnsignedLongMask() returned wrong " - "value for long -0xFFF..000042"); - - PyTuple_SET_ITEM(tuple, 0, num); - - value = 0; - if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) { - return NULL; - } - if (value != (unsigned long)-0x42) - return raiseTestError("test_k_code", - "k code returned wrong value for long -0xFFF..000042"); - - Py_DECREF(tuple); - Py_RETURN_NONE; -} - -static PyObject * -getargs_f(PyObject *self, PyObject *args) -{ - float f; - if (!PyArg_ParseTuple(args, "f", &f)) - return NULL; - return PyFloat_FromDouble(f); -} - -static PyObject * -getargs_d(PyObject *self, PyObject *args) -{ - double d; - if (!PyArg_ParseTuple(args, "d", &d)) - return NULL; - return PyFloat_FromDouble(d); -} - -static PyObject * -getargs_D(PyObject *self, PyObject *args) -{ - Py_complex cval; - if (!PyArg_ParseTuple(args, "D", &cval)) - return NULL; - return PyComplex_FromCComplex(cval); -} - -static PyObject * -getargs_S(PyObject *self, PyObject *args) -{ - PyObject *obj; - if (!PyArg_ParseTuple(args, "S", &obj)) - return NULL; - Py_INCREF(obj); - return obj; -} - -static PyObject * -getargs_Y(PyObject *self, PyObject *args) -{ - PyObject *obj; - if (!PyArg_ParseTuple(args, "Y", &obj)) - return NULL; - Py_INCREF(obj); - return obj; -} - -static PyObject * -getargs_U(PyObject *self, PyObject *args) -{ - PyObject *obj; - if (!PyArg_ParseTuple(args, "U", &obj)) - return NULL; - Py_INCREF(obj); - return obj; -} - -static PyObject * -getargs_c(PyObject *self, PyObject *args) -{ - char c; - if (!PyArg_ParseTuple(args, "c", &c)) - return NULL; - return PyLong_FromLong((unsigned char)c); -} - -static PyObject * -getargs_C(PyObject *self, PyObject *args) -{ - int c; - if (!PyArg_ParseTuple(args, "C", &c)) - return NULL; - return PyLong_FromLong(c); -} - -static PyObject * -getargs_s(PyObject *self, PyObject *args) -{ - char *str; - if (!PyArg_ParseTuple(args, "s", &str)) - return NULL; - return PyBytes_FromString(str); -} - -static PyObject * -getargs_s_star(PyObject *self, PyObject *args) -{ - Py_buffer buffer; - PyObject *bytes; - if (!PyArg_ParseTuple(args, "s*", &buffer)) - return NULL; - bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); - PyBuffer_Release(&buffer); - return bytes; -} - -static PyObject * -getargs_s_hash(PyObject *self, PyObject *args) -{ - char *str; - Py_ssize_t size; - if (!PyArg_ParseTuple(args, "s#", &str, &size)) - return NULL; - return PyBytes_FromStringAndSize(str, size); -} - -static PyObject * -getargs_z(PyObject *self, PyObject *args) -{ - char *str; - if (!PyArg_ParseTuple(args, "z", &str)) - return NULL; - if (str != NULL) - return PyBytes_FromString(str); - else - Py_RETURN_NONE; -} - -static PyObject * -getargs_z_star(PyObject *self, PyObject *args) -{ - Py_buffer buffer; - PyObject *bytes; - if (!PyArg_ParseTuple(args, "z*", &buffer)) - return NULL; - if (buffer.buf != NULL) - bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); - else { - Py_INCREF(Py_None); - bytes = Py_None; - } - PyBuffer_Release(&buffer); - return bytes; -} - -static PyObject * -getargs_z_hash(PyObject *self, PyObject *args) -{ - char *str; - Py_ssize_t size; - if (!PyArg_ParseTuple(args, "z#", &str, &size)) - return NULL; - if (str != NULL) - return PyBytes_FromStringAndSize(str, size); - else - Py_RETURN_NONE; -} - -static PyObject * -getargs_y(PyObject *self, PyObject *args) -{ - char *str; - if (!PyArg_ParseTuple(args, "y", &str)) - return NULL; - return PyBytes_FromString(str); -} - -static PyObject * -getargs_y_star(PyObject *self, PyObject *args) -{ - Py_buffer buffer; - PyObject *bytes; - if (!PyArg_ParseTuple(args, "y*", &buffer)) - return NULL; - bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); - PyBuffer_Release(&buffer); - return bytes; -} - -static PyObject * -getargs_y_hash(PyObject *self, PyObject *args) -{ - char *str; - Py_ssize_t size; - if (!PyArg_ParseTuple(args, "y#", &str, &size)) - return NULL; - return PyBytes_FromStringAndSize(str, size); -} - -static PyObject * -getargs_u(PyObject *self, PyObject *args) -{ - Py_UNICODE *str; - if (!PyArg_ParseTuple(args, "u", &str)) - return NULL; - return PyUnicode_FromWideChar(str, -1); -} - -static PyObject * -getargs_u_hash(PyObject *self, PyObject *args) -{ - Py_UNICODE *str; - Py_ssize_t size; - if (!PyArg_ParseTuple(args, "u#", &str, &size)) - return NULL; - return PyUnicode_FromWideChar(str, size); -} - -static PyObject * -getargs_Z(PyObject *self, PyObject *args) -{ - Py_UNICODE *str; - if (!PyArg_ParseTuple(args, "Z", &str)) - return NULL; - if (str != NULL) { - return PyUnicode_FromWideChar(str, -1); - } else - Py_RETURN_NONE; -} - -static PyObject * -getargs_Z_hash(PyObject *self, PyObject *args) -{ - Py_UNICODE *str; - Py_ssize_t size; - if (!PyArg_ParseTuple(args, "Z#", &str, &size)) - return NULL; - if (str != NULL) - return PyUnicode_FromWideChar(str, size); - else - Py_RETURN_NONE; -} - -static PyObject * -getargs_es(PyObject *self, PyObject *args) -{ - PyObject *arg, *result; - const char *encoding = NULL; - char *str; - - if (!PyArg_ParseTuple(args, "O|s", &arg, &encoding)) - return NULL; - if (!PyArg_Parse(arg, "es", encoding, &str)) - return NULL; - result = PyBytes_FromString(str); - PyMem_Free(str); - return result; -} - -static PyObject * -getargs_et(PyObject *self, PyObject *args) -{ - PyObject *arg, *result; - const char *encoding = NULL; - char *str; - - if (!PyArg_ParseTuple(args, "O|s", &arg, &encoding)) - return NULL; - if (!PyArg_Parse(arg, "et", encoding, &str)) - return NULL; - result = PyBytes_FromString(str); - PyMem_Free(str); - return result; -} - -static PyObject * -getargs_es_hash(PyObject *self, PyObject *args) -{ - PyObject *arg, *result; - const char *encoding = NULL; - PyByteArrayObject *buffer = NULL; - char *str = NULL; - Py_ssize_t size; - - if (!PyArg_ParseTuple(args, "O|sY", &arg, &encoding, &buffer)) - return NULL; - if (buffer != NULL) { - str = PyByteArray_AS_STRING(buffer); - size = PyByteArray_GET_SIZE(buffer); - } - if (!PyArg_Parse(arg, "es#", encoding, &str, &size)) - return NULL; - result = PyBytes_FromStringAndSize(str, size); - if (buffer == NULL) - PyMem_Free(str); - return result; -} - -static PyObject * -getargs_et_hash(PyObject *self, PyObject *args) -{ - PyObject *arg, *result; - const char *encoding = NULL; - PyByteArrayObject *buffer = NULL; - char *str = NULL; - Py_ssize_t size; - - if (!PyArg_ParseTuple(args, "O|sY", &arg, &encoding, &buffer)) - return NULL; - if (buffer != NULL) { - str = PyByteArray_AS_STRING(buffer); - size = PyByteArray_GET_SIZE(buffer); - } - if (!PyArg_Parse(arg, "et#", encoding, &str, &size)) - return NULL; - result = PyBytes_FromStringAndSize(str, size); - if (buffer == NULL) - PyMem_Free(str); - return result; -} - -/* Test the s and z codes for PyArg_ParseTuple. -*/ -static PyObject * -test_s_code(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - /* Unicode strings should be accepted */ - PyObject *tuple, *obj; - char *value; - - tuple = PyTuple_New(1); - if (tuple == NULL) - return NULL; - - obj = PyUnicode_Decode("t\xeate", strlen("t\xeate"), - "latin-1", NULL); - if (obj == NULL) - return NULL; - - PyTuple_SET_ITEM(tuple, 0, obj); - - /* These two blocks used to raise a TypeError: - * "argument must be string without null bytes, not str" - */ - if (!PyArg_ParseTuple(tuple, "s:test_s_code1", &value)) { - return NULL; - } - - if (!PyArg_ParseTuple(tuple, "z:test_s_code2", &value)) { - return NULL; - } - - Py_DECREF(tuple); - Py_RETURN_NONE; -} - -static PyObject * -parse_tuple_and_keywords(PyObject *self, PyObject *args) -{ - PyObject *sub_args; - PyObject *sub_kwargs; - const char *sub_format; - PyObject *sub_keywords; - - Py_ssize_t i, size; - char *keywords[8 + 1]; /* space for NULL at end */ - PyObject *o; - PyObject *converted[8]; - - int result; - PyObject *return_value = NULL; - - double buffers[8][4]; /* double ensures alignment where necessary */ - - if (!PyArg_ParseTuple(args, "OOsO:parse_tuple_and_keywords", - &sub_args, &sub_kwargs, - &sub_format, &sub_keywords)) - return NULL; - - if (!(PyList_CheckExact(sub_keywords) || PyTuple_CheckExact(sub_keywords))) { - PyErr_SetString(PyExc_ValueError, - "parse_tuple_and_keywords: sub_keywords must be either list or tuple"); - return NULL; - } - - memset(buffers, 0, sizeof(buffers)); - memset(converted, 0, sizeof(converted)); - memset(keywords, 0, sizeof(keywords)); - - size = PySequence_Fast_GET_SIZE(sub_keywords); - if (size > 8) { - PyErr_SetString(PyExc_ValueError, - "parse_tuple_and_keywords: too many keywords in sub_keywords"); - goto exit; - } - - for (i = 0; i < size; i++) { - o = PySequence_Fast_GET_ITEM(sub_keywords, i); - if (!PyUnicode_FSConverter(o, (void *)(converted + i))) { - PyErr_Format(PyExc_ValueError, - "parse_tuple_and_keywords: could not convert keywords[%zd] to narrow string", i); - goto exit; - } - keywords[i] = PyBytes_AS_STRING(converted[i]); - } - - result = PyArg_ParseTupleAndKeywords(sub_args, sub_kwargs, - sub_format, keywords, - buffers + 0, buffers + 1, buffers + 2, buffers + 3, - buffers + 4, buffers + 5, buffers + 6, buffers + 7); - - if (result) { - return_value = Py_None; - Py_INCREF(Py_None); - } - -exit: - size = sizeof(converted) / sizeof(converted[0]); - for (i = 0; i < size; i++) { - Py_XDECREF(converted[i]); - } - return return_value; -} - -static volatile int x; - -#if USE_UNICODE_WCHAR_CACHE -/* Ignore use of deprecated APIs */ -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - -/* Test the u and u# codes for PyArg_ParseTuple. May leak memory in case - of an error. -*/ -static PyObject * -test_u_code(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *tuple, *obj; - Py_UNICODE *value; - Py_ssize_t len; - - /* issue4122: Undefined reference to _Py_ascii_whitespace on Windows */ - /* Just use the macro and check that it compiles */ - x = Py_UNICODE_ISSPACE(25); - - tuple = PyTuple_New(1); - if (tuple == NULL) - return NULL; - - obj = PyUnicode_Decode("test", strlen("test"), - "ascii", NULL); - if (obj == NULL) - return NULL; - - PyTuple_SET_ITEM(tuple, 0, obj); - - value = 0; - if (!PyArg_ParseTuple(tuple, "u:test_u_code", &value)) { - return NULL; - } - if (value != PyUnicode_AS_UNICODE(obj)) - return raiseTestError("test_u_code", - "u code returned wrong value for u'test'"); - value = 0; - if (!PyArg_ParseTuple(tuple, "u#:test_u_code", &value, &len)) { - return NULL; - } - if (value != PyUnicode_AS_UNICODE(obj) || - len != PyUnicode_GET_SIZE(obj)) - return raiseTestError("test_u_code", - "u# code returned wrong values for u'test'"); - - Py_DECREF(tuple); - Py_RETURN_NONE; -} - -/* Test Z and Z# codes for PyArg_ParseTuple */ -static PyObject * -test_Z_code(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *tuple, *obj; - const Py_UNICODE *value1, *value2; - Py_ssize_t len1, len2; - - tuple = PyTuple_New(2); - if (tuple == NULL) - return NULL; - - obj = PyUnicode_FromString("test"); - PyTuple_SET_ITEM(tuple, 0, obj); - Py_INCREF(Py_None); - PyTuple_SET_ITEM(tuple, 1, Py_None); - - /* swap values on purpose */ - value1 = NULL; - value2 = PyUnicode_AS_UNICODE(obj); - - /* Test Z for both values */ - if (!PyArg_ParseTuple(tuple, "ZZ:test_Z_code", &value1, &value2)) { - return NULL; - } - if (value1 != PyUnicode_AS_UNICODE(obj)) - return raiseTestError("test_Z_code", - "Z code returned wrong value for 'test'"); - if (value2 != NULL) - return raiseTestError("test_Z_code", - "Z code returned wrong value for None"); - - value1 = NULL; - value2 = PyUnicode_AS_UNICODE(obj); - len1 = -1; - len2 = -1; - - /* Test Z# for both values */ - if (!PyArg_ParseTuple(tuple, "Z#Z#:test_Z_code", &value1, &len1, - &value2, &len2)) - { - return NULL; - } - if (value1 != PyUnicode_AS_UNICODE(obj) || - len1 != PyUnicode_GET_SIZE(obj)) - return raiseTestError("test_Z_code", - "Z# code returned wrong values for 'test'"); - if (value2 != NULL || - len2 != 0) - return raiseTestError("test_Z_code", - "Z# code returned wrong values for None'"); - - Py_DECREF(tuple); - Py_RETURN_NONE; -} -_Py_COMP_DIAG_POP -#endif /* USE_UNICODE_WCHAR_CACHE */ - -static PyObject * -test_widechar(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ -#if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4) - const wchar_t wtext[2] = {(wchar_t)0x10ABCDu}; - size_t wtextlen = 1; - const wchar_t invalid[1] = {(wchar_t)0x110000u}; -#else - const wchar_t wtext[3] = {(wchar_t)0xDBEAu, (wchar_t)0xDFCDu}; - size_t wtextlen = 2; -#endif - PyObject *wide, *utf8; - - wide = PyUnicode_FromWideChar(wtext, wtextlen); - if (wide == NULL) - return NULL; - - utf8 = PyUnicode_FromString("\xf4\x8a\xaf\x8d"); - if (utf8 == NULL) { - Py_DECREF(wide); - return NULL; - } - - if (PyUnicode_GET_LENGTH(wide) != PyUnicode_GET_LENGTH(utf8)) { - Py_DECREF(wide); - Py_DECREF(utf8); - return raiseTestError("test_widechar", - "wide string and utf8 string " - "have different length"); - } - if (PyUnicode_Compare(wide, utf8)) { - Py_DECREF(wide); - Py_DECREF(utf8); - if (PyErr_Occurred()) - return NULL; - return raiseTestError("test_widechar", - "wide string and utf8 string " - "are different"); - } - - Py_DECREF(wide); - Py_DECREF(utf8); - -#if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4) - wide = PyUnicode_FromWideChar(invalid, 1); - if (wide == NULL) - PyErr_Clear(); - else - return raiseTestError("test_widechar", - "PyUnicode_FromWideChar(L\"\\U00110000\", 1) didn't fail"); - -#if USE_UNICODE_WCHAR_CACHE -/* Ignore use of deprecated APIs */ -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - wide = PyUnicode_FromUnicode(invalid, 1); - if (wide == NULL) - PyErr_Clear(); - else - return raiseTestError("test_widechar", - "PyUnicode_FromUnicode(L\"\\U00110000\", 1) didn't fail"); - - wide = PyUnicode_FromUnicode(NULL, 1); - if (wide == NULL) - return NULL; - PyUnicode_AS_UNICODE(wide)[0] = invalid[0]; - if (_PyUnicode_Ready(wide) < 0) { - Py_DECREF(wide); - PyErr_Clear(); - } - else { - Py_DECREF(wide); - return raiseTestError("test_widechar", - "PyUnicode_Ready() didn't fail"); - } -_Py_COMP_DIAG_POP -#endif /* USE_UNICODE_WCHAR_CACHE */ -#endif - - Py_RETURN_NONE; -} - -static PyObject * -unicode_aswidechar(PyObject *self, PyObject *args) -{ - PyObject *unicode, *result; - Py_ssize_t buflen, size; - wchar_t *buffer; - - if (!PyArg_ParseTuple(args, "Un", &unicode, &buflen)) - return NULL; - buffer = PyMem_New(wchar_t, buflen); - if (buffer == NULL) - return PyErr_NoMemory(); - - size = PyUnicode_AsWideChar(unicode, buffer, buflen); - if (size == -1) { - PyMem_Free(buffer); - return NULL; - } - - if (size < buflen) - buflen = size + 1; - else - buflen = size; - result = PyUnicode_FromWideChar(buffer, buflen); - PyMem_Free(buffer); - if (result == NULL) - return NULL; - - return Py_BuildValue("(Nn)", result, size); -} - -static PyObject * -unicode_aswidecharstring(PyObject *self, PyObject *args) -{ - PyObject *unicode, *result; - Py_ssize_t size; - wchar_t *buffer; - - if (!PyArg_ParseTuple(args, "U", &unicode)) - return NULL; - - buffer = PyUnicode_AsWideCharString(unicode, &size); - if (buffer == NULL) - return NULL; - - result = PyUnicode_FromWideChar(buffer, size + 1); - PyMem_Free(buffer); - if (result == NULL) - return NULL; - return Py_BuildValue("(Nn)", result, size); -} - -static PyObject * -unicode_asucs4(PyObject *self, PyObject *args) -{ - PyObject *unicode, *result; - Py_UCS4 *buffer; - int copy_null; - Py_ssize_t str_len, buf_len; - - if (!PyArg_ParseTuple(args, "Unp:unicode_asucs4", &unicode, &str_len, ©_null)) { - return NULL; - } - - buf_len = str_len + 1; - buffer = PyMem_NEW(Py_UCS4, buf_len); - if (buffer == NULL) { - return PyErr_NoMemory(); - } - memset(buffer, 0, sizeof(Py_UCS4)*buf_len); - buffer[str_len] = 0xffffU; - - if (!PyUnicode_AsUCS4(unicode, buffer, buf_len, copy_null)) { - PyMem_Free(buffer); - return NULL; - } - - result = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, buffer, buf_len); - PyMem_Free(buffer); - return result; -} - -static PyObject * -unicode_asutf8(PyObject *self, PyObject *args) -{ - PyObject *unicode; - const char *buffer; - - if (!PyArg_ParseTuple(args, "U", &unicode)) { - return NULL; - } - - buffer = PyUnicode_AsUTF8(unicode); - if (buffer == NULL) { - return NULL; - } - - return PyBytes_FromString(buffer); -} - -static PyObject * -unicode_asutf8andsize(PyObject *self, PyObject *args) -{ - PyObject *unicode, *result; - const char *buffer; - Py_ssize_t utf8_len; - - if(!PyArg_ParseTuple(args, "U", &unicode)) { - return NULL; - } - - buffer = PyUnicode_AsUTF8AndSize(unicode, &utf8_len); - if (buffer == NULL) { - return NULL; - } - - result = PyBytes_FromString(buffer); - if (result == NULL) { - return NULL; - } - - return Py_BuildValue("(Nn)", result, utf8_len); -} - -static PyObject * -unicode_findchar(PyObject *self, PyObject *args) -{ - PyObject *str; - int direction; - unsigned int ch; - Py_ssize_t result; - Py_ssize_t start, end; - - if (!PyArg_ParseTuple(args, "UInni:unicode_findchar", &str, &ch, - &start, &end, &direction)) { - return NULL; - } - - result = PyUnicode_FindChar(str, (Py_UCS4)ch, start, end, direction); - if (result == -2) - return NULL; - else - return PyLong_FromSsize_t(result); -} - -static PyObject * -unicode_copycharacters(PyObject *self, PyObject *args) -{ - PyObject *from, *to, *to_copy; - Py_ssize_t from_start, to_start, how_many, copied; - - if (!PyArg_ParseTuple(args, "UnOnn:unicode_copycharacters", &to, &to_start, - &from, &from_start, &how_many)) { - return NULL; - } - - if (!(to_copy = PyUnicode_New(PyUnicode_GET_LENGTH(to), - PyUnicode_MAX_CHAR_VALUE(to)))) { - return NULL; - } - if (PyUnicode_Fill(to_copy, 0, PyUnicode_GET_LENGTH(to_copy), 0U) < 0) { - Py_DECREF(to_copy); - return NULL; - } - - if ((copied = PyUnicode_CopyCharacters(to_copy, to_start, from, - from_start, how_many)) < 0) { - Py_DECREF(to_copy); - return NULL; - } - - return Py_BuildValue("(Nn)", to_copy, copied); -} - -#if USE_UNICODE_WCHAR_CACHE -/* Ignore use of deprecated APIs */ -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - -static PyObject * -unicode_legacy_string(PyObject *self, PyObject *args) -{ - Py_UNICODE *data; - Py_ssize_t len; - PyObject *u; - - if (!PyArg_ParseTuple(args, "u#", &data, &len)) - return NULL; - - u = PyUnicode_FromUnicode(NULL, len); - if (u == NULL) - return NULL; - - memcpy(PyUnicode_AS_UNICODE(u), data, len * sizeof(Py_UNICODE)); - - if (len > 0) { /* The empty string is always ready. */ - assert(!PyUnicode_IS_READY(u)); - } - - return u; -} -_Py_COMP_DIAG_POP -#endif /* USE_UNICODE_WCHAR_CACHE */ - -static PyObject * -getargs_w_star(PyObject *self, PyObject *args) -{ - Py_buffer buffer; - PyObject *result; - char *str; - - if (!PyArg_ParseTuple(args, "w*:getargs_w_star", &buffer)) - return NULL; - - if (2 <= buffer.len) { - str = buffer.buf; - str[0] = '['; - str[buffer.len-1] = ']'; - } - - result = PyBytes_FromStringAndSize(buffer.buf, buffer.len); - PyBuffer_Release(&buffer); - return result; -} - - -static PyObject * -test_empty_argparse(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - /* Test that formats can begin with '|'. See issue #4720. */ - PyObject *tuple, *dict = NULL; - static char *kwlist[] = {NULL}; - int result; - tuple = PyTuple_New(0); - if (!tuple) - return NULL; - if (!(result = PyArg_ParseTuple(tuple, "|:test_empty_argparse"))) { - goto done; - } - dict = PyDict_New(); - if (!dict) - goto done; - result = PyArg_ParseTupleAndKeywords(tuple, dict, "|:test_empty_argparse", kwlist); - done: - Py_DECREF(tuple); - Py_XDECREF(dict); - if (!result) { - return NULL; - } - else { - Py_RETURN_NONE; - } -} - -static PyObject * -codec_incrementalencoder(PyObject *self, PyObject *args) -{ - const char *encoding, *errors = NULL; - if (!PyArg_ParseTuple(args, "s|s:test_incrementalencoder", - &encoding, &errors)) - return NULL; - return PyCodec_IncrementalEncoder(encoding, errors); -} - -static PyObject * -codec_incrementaldecoder(PyObject *self, PyObject *args) -{ - const char *encoding, *errors = NULL; - if (!PyArg_ParseTuple(args, "s|s:test_incrementaldecoder", - &encoding, &errors)) - return NULL; - return PyCodec_IncrementalDecoder(encoding, errors); -} - - -/* Simple test of _PyLong_NumBits and _PyLong_Sign. */ -static PyObject * -test_long_numbits(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - struct triple { - long input; - size_t nbits; - int sign; - } testcases[] = {{0, 0, 0}, - {1L, 1, 1}, - {-1L, 1, -1}, - {2L, 2, 1}, - {-2L, 2, -1}, - {3L, 2, 1}, - {-3L, 2, -1}, - {4L, 3, 1}, - {-4L, 3, -1}, - {0x7fffL, 15, 1}, /* one Python int digit */ - {-0x7fffL, 15, -1}, - {0xffffL, 16, 1}, - {-0xffffL, 16, -1}, - {0xfffffffL, 28, 1}, - {-0xfffffffL, 28, -1}}; - size_t i; - - for (i = 0; i < Py_ARRAY_LENGTH(testcases); ++i) { - size_t nbits; - int sign; - PyObject *plong; - - plong = PyLong_FromLong(testcases[i].input); - if (plong == NULL) - return NULL; - nbits = _PyLong_NumBits(plong); - sign = _PyLong_Sign(plong); - - Py_DECREF(plong); - if (nbits != testcases[i].nbits) - return raiseTestError("test_long_numbits", - "wrong result for _PyLong_NumBits"); - if (sign != testcases[i].sign) - return raiseTestError("test_long_numbits", - "wrong result for _PyLong_Sign"); - } - Py_RETURN_NONE; -} - static PyObject * pyobject_repr_from_null(PyObject *self, PyObject *Py_UNUSED(ignored)) { @@ -2556,6 +759,16 @@ set_errno(PyObject *self, PyObject *args) Py_RETURN_NONE; } +static PyObject * +test_set_exception(PyObject *self, PyObject *new_exc) +{ + PyObject *exc = PyErr_GetHandledException(); + assert(PyExceptionInstance_Check(exc) || exc == NULL); + + PyErr_SetHandledException(new_exc); + return exc; +} + static PyObject * test_set_exc_info(PyObject *self, PyObject *args) { @@ -2580,413 +793,6 @@ test_set_exc_info(PyObject *self, PyObject *args) return orig_exc; } -static int test_run_counter = 0; - -static PyObject * -test_datetime_capi(PyObject *self, PyObject *args) { - if (PyDateTimeAPI) { - if (test_run_counter) { - /* Probably regrtest.py -R */ - Py_RETURN_NONE; - } - else { - PyErr_SetString(PyExc_AssertionError, - "PyDateTime_CAPI somehow initialized"); - return NULL; - } - } - test_run_counter++; - PyDateTime_IMPORT; - - if (PyDateTimeAPI) - Py_RETURN_NONE; - else - return NULL; -} - -/* Functions exposing the C API type checking for testing */ -#define MAKE_DATETIME_CHECK_FUNC(check_method, exact_method) \ - PyObject *obj; \ - int exact = 0; \ - if (!PyArg_ParseTuple(args, "O|p", &obj, &exact)) { \ - return NULL; \ - } \ - int rv = exact?exact_method(obj):check_method(obj); \ - if (rv) { \ - Py_RETURN_TRUE; \ - } else { \ - Py_RETURN_FALSE; \ - } - -static PyObject * -datetime_check_date(PyObject *self, PyObject *args) { - MAKE_DATETIME_CHECK_FUNC(PyDate_Check, PyDate_CheckExact) -} - -static PyObject * -datetime_check_time(PyObject *self, PyObject *args) { - MAKE_DATETIME_CHECK_FUNC(PyTime_Check, PyTime_CheckExact) -} - -static PyObject * -datetime_check_datetime(PyObject *self, PyObject *args) { - MAKE_DATETIME_CHECK_FUNC(PyDateTime_Check, PyDateTime_CheckExact) -} - -static PyObject * -datetime_check_delta(PyObject *self, PyObject *args) { - MAKE_DATETIME_CHECK_FUNC(PyDelta_Check, PyDelta_CheckExact) -} - -static PyObject * -datetime_check_tzinfo(PyObject *self, PyObject *args) { - MAKE_DATETIME_CHECK_FUNC(PyTZInfo_Check, PyTZInfo_CheckExact) -} - - -/* Makes three variations on timezone representing UTC-5: - 1. timezone with offset and name from PyDateTimeAPI - 2. timezone with offset and name from PyTimeZone_FromOffsetAndName - 3. timezone with offset (no name) from PyTimeZone_FromOffset -*/ -static PyObject * -make_timezones_capi(PyObject *self, PyObject *args) { - PyObject *offset = PyDelta_FromDSU(0, -18000, 0); - PyObject *name = PyUnicode_FromString("EST"); - - PyObject *est_zone_capi = PyDateTimeAPI->TimeZone_FromTimeZone(offset, name); - PyObject *est_zone_macro = PyTimeZone_FromOffsetAndName(offset, name); - PyObject *est_zone_macro_noname = PyTimeZone_FromOffset(offset); - - Py_DecRef(offset); - Py_DecRef(name); - - PyObject *rv = PyTuple_New(3); - - PyTuple_SET_ITEM(rv, 0, est_zone_capi); - PyTuple_SET_ITEM(rv, 1, est_zone_macro); - PyTuple_SET_ITEM(rv, 2, est_zone_macro_noname); - - return rv; -} - -static PyObject * -get_timezones_offset_zero(PyObject *self, PyObject *args) { - PyObject *offset = PyDelta_FromDSU(0, 0, 0); - PyObject *name = PyUnicode_FromString(""); - - // These two should return the UTC singleton - PyObject *utc_singleton_0 = PyTimeZone_FromOffset(offset); - PyObject *utc_singleton_1 = PyTimeZone_FromOffsetAndName(offset, NULL); - - // This one will return +00:00 zone, but not the UTC singleton - PyObject *non_utc_zone = PyTimeZone_FromOffsetAndName(offset, name); - - Py_DecRef(offset); - Py_DecRef(name); - - PyObject *rv = PyTuple_New(3); - PyTuple_SET_ITEM(rv, 0, utc_singleton_0); - PyTuple_SET_ITEM(rv, 1, utc_singleton_1); - PyTuple_SET_ITEM(rv, 2, non_utc_zone); - - return rv; -} - -static PyObject * -get_timezone_utc_capi(PyObject* self, PyObject *args) { - int macro = 0; - if (!PyArg_ParseTuple(args, "|p", ¯o)) { - return NULL; - } - if (macro) { - Py_INCREF(PyDateTime_TimeZone_UTC); - return PyDateTime_TimeZone_UTC; - } else { - Py_INCREF(PyDateTimeAPI->TimeZone_UTC); - return PyDateTimeAPI->TimeZone_UTC; - } -} - -static PyObject * -get_date_fromdate(PyObject *self, PyObject *args) -{ - PyObject *rv = NULL; - int macro; - int year, month, day; - - if (!PyArg_ParseTuple(args, "piii", ¯o, &year, &month, &day)) { - return NULL; - } - - if (macro) { - rv = PyDate_FromDate(year, month, day); - } - else { - rv = PyDateTimeAPI->Date_FromDate( - year, month, day, - PyDateTimeAPI->DateType); - } - return rv; -} - -static PyObject * -get_datetime_fromdateandtime(PyObject *self, PyObject *args) -{ - PyObject *rv = NULL; - int macro; - int year, month, day; - int hour, minute, second, microsecond; - - if (!PyArg_ParseTuple(args, "piiiiiii", - ¯o, - &year, &month, &day, - &hour, &minute, &second, µsecond)) { - return NULL; - } - - if (macro) { - rv = PyDateTime_FromDateAndTime( - year, month, day, - hour, minute, second, microsecond); - } - else { - rv = PyDateTimeAPI->DateTime_FromDateAndTime( - year, month, day, - hour, minute, second, microsecond, - Py_None, - PyDateTimeAPI->DateTimeType); - } - return rv; -} - -static PyObject * -get_datetime_fromdateandtimeandfold(PyObject *self, PyObject *args) -{ - PyObject *rv = NULL; - int macro; - int year, month, day; - int hour, minute, second, microsecond, fold; - - if (!PyArg_ParseTuple(args, "piiiiiiii", - ¯o, - &year, &month, &day, - &hour, &minute, &second, µsecond, - &fold)) { - return NULL; - } - - if (macro) { - rv = PyDateTime_FromDateAndTimeAndFold( - year, month, day, - hour, minute, second, microsecond, - fold); - } - else { - rv = PyDateTimeAPI->DateTime_FromDateAndTimeAndFold( - year, month, day, - hour, minute, second, microsecond, - Py_None, - fold, - PyDateTimeAPI->DateTimeType); - } - return rv; -} - -static PyObject * -get_time_fromtime(PyObject *self, PyObject *args) -{ - PyObject *rv = NULL; - int macro; - int hour, minute, second, microsecond; - - if (!PyArg_ParseTuple(args, "piiii", - ¯o, - &hour, &minute, &second, µsecond)) { - return NULL; - } - - if (macro) { - rv = PyTime_FromTime(hour, minute, second, microsecond); - } - else { - rv = PyDateTimeAPI->Time_FromTime( - hour, minute, second, microsecond, - Py_None, - PyDateTimeAPI->TimeType); - } - return rv; -} - -static PyObject * -get_time_fromtimeandfold(PyObject *self, PyObject *args) -{ - PyObject *rv = NULL; - int macro; - int hour, minute, second, microsecond, fold; - - if (!PyArg_ParseTuple(args, "piiiii", - ¯o, - &hour, &minute, &second, µsecond, - &fold)) { - return NULL; - } - - if (macro) { - rv = PyTime_FromTimeAndFold(hour, minute, second, microsecond, fold); - } - else { - rv = PyDateTimeAPI->Time_FromTimeAndFold( - hour, minute, second, microsecond, - Py_None, - fold, - PyDateTimeAPI->TimeType); - } - return rv; -} - -static PyObject * -get_delta_fromdsu(PyObject *self, PyObject *args) -{ - PyObject *rv = NULL; - int macro; - int days, seconds, microseconds; - - if (!PyArg_ParseTuple(args, "piii", - ¯o, - &days, &seconds, µseconds)) { - return NULL; - } - - if (macro) { - rv = PyDelta_FromDSU(days, seconds, microseconds); - } - else { - rv = PyDateTimeAPI->Delta_FromDelta( - days, seconds, microseconds, 1, - PyDateTimeAPI->DeltaType); - } - - return rv; -} - -static PyObject * -get_date_fromtimestamp(PyObject* self, PyObject *args) -{ - PyObject *tsargs = NULL, *ts = NULL, *rv = NULL; - int macro = 0; - - if (!PyArg_ParseTuple(args, "O|p", &ts, ¯o)) { - return NULL; - } - - // Construct the argument tuple - if ((tsargs = PyTuple_Pack(1, ts)) == NULL) { - return NULL; - } - - // Pass along to the API function - if (macro) { - rv = PyDate_FromTimestamp(tsargs); - } - else { - rv = PyDateTimeAPI->Date_FromTimestamp( - (PyObject *)PyDateTimeAPI->DateType, tsargs - ); - } - - Py_DECREF(tsargs); - return rv; -} - -static PyObject * -get_datetime_fromtimestamp(PyObject* self, PyObject *args) -{ - int macro = 0; - int usetz = 0; - PyObject *tsargs = NULL, *ts = NULL, *tzinfo = Py_None, *rv = NULL; - if (!PyArg_ParseTuple(args, "OO|pp", &ts, &tzinfo, &usetz, ¯o)) { - return NULL; - } - - // Construct the argument tuple - if (usetz) { - tsargs = PyTuple_Pack(2, ts, tzinfo); - } - else { - tsargs = PyTuple_Pack(1, ts); - } - - if (tsargs == NULL) { - return NULL; - } - - // Pass along to the API function - if (macro) { - rv = PyDateTime_FromTimestamp(tsargs); - } - else { - rv = PyDateTimeAPI->DateTime_FromTimestamp( - (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, NULL - ); - } - - Py_DECREF(tsargs); - return rv; -} - -static PyObject * -test_PyDateTime_GET(PyObject *self, PyObject *obj) -{ - int year, month, day; - - year = PyDateTime_GET_YEAR(obj); - month = PyDateTime_GET_MONTH(obj); - day = PyDateTime_GET_DAY(obj); - - return Py_BuildValue("(lll)", year, month, day); -} - -static PyObject * -test_PyDateTime_DATE_GET(PyObject *self, PyObject *obj) -{ - int hour, minute, second, microsecond; - - hour = PyDateTime_DATE_GET_HOUR(obj); - minute = PyDateTime_DATE_GET_MINUTE(obj); - second = PyDateTime_DATE_GET_SECOND(obj); - microsecond = PyDateTime_DATE_GET_MICROSECOND(obj); - PyObject *tzinfo = PyDateTime_DATE_GET_TZINFO(obj); - - return Py_BuildValue("(llllO)", hour, minute, second, microsecond, tzinfo); -} - -static PyObject * -test_PyDateTime_TIME_GET(PyObject *self, PyObject *obj) -{ - int hour, minute, second, microsecond; - - hour = PyDateTime_TIME_GET_HOUR(obj); - minute = PyDateTime_TIME_GET_MINUTE(obj); - second = PyDateTime_TIME_GET_SECOND(obj); - microsecond = PyDateTime_TIME_GET_MICROSECOND(obj); - PyObject *tzinfo = PyDateTime_TIME_GET_TZINFO(obj); - - return Py_BuildValue("(llllO)", hour, minute, second, microsecond, tzinfo); -} - -static PyObject * -test_PyDateTime_DELTA_GET(PyObject *self, PyObject *obj) -{ - int days, seconds, microseconds; - - days = PyDateTime_DELTA_GET_DAYS(obj); - seconds = PyDateTime_DELTA_GET_SECONDS(obj); - microseconds = PyDateTime_DELTA_GET_MICROSECONDS(obj); - - return Py_BuildValue("(lll)", days, seconds, microseconds); -} - /* test_thread_state spawns a thread of its own, and that thread releases * `thread_done` when it's finished. The driver code has to know when the * thread finishes, because the thread uses a PyObject (the callable) that @@ -3068,6 +874,46 @@ test_thread_state(PyObject *self, PyObject *args) Py_RETURN_NONE; } +#ifndef MS_WINDOWS +static PyThread_type_lock wait_done = NULL; + +static void wait_for_lock(void *unused) { + PyThread_acquire_lock(wait_done, 1); + PyThread_release_lock(wait_done); + PyThread_free_lock(wait_done); + wait_done = NULL; +} + +// These can be used to test things that care about the existence of another +// thread that the threading module doesn't know about. + +static PyObject * +spawn_pthread_waiter(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + if (wait_done) { + PyErr_SetString(PyExc_RuntimeError, "thread already running"); + return NULL; + } + wait_done = PyThread_allocate_lock(); + if (wait_done == NULL) + return PyErr_NoMemory(); + PyThread_acquire_lock(wait_done, 1); + PyThread_start_new_thread(wait_for_lock, NULL); + Py_RETURN_NONE; +} + +static PyObject * +end_spawned_pthread(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + if (!wait_done) { + PyErr_SetString(PyExc_RuntimeError, "call _spawn_pthread_waiter 1st"); + return NULL; + } + PyThread_release_lock(wait_done); + Py_RETURN_NONE; +} +#endif // not MS_WINDOWS + /* test Py_AddPendingCalls using threads */ static int _pending_callback(void *arg) { @@ -3104,70 +950,6 @@ pending_threadfunc(PyObject *self, PyObject *arg) Py_RETURN_TRUE; } -/* Some tests of PyUnicode_FromFormat(). This needs more tests. */ -static PyObject * -test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *result; - char *msg; - -#define CHECK_1_FORMAT(FORMAT, TYPE) \ - result = PyUnicode_FromFormat(FORMAT, (TYPE)1); \ - if (result == NULL) \ - return NULL; \ - if (!_PyUnicode_EqualToASCIIString(result, "1")) { \ - msg = FORMAT " failed at 1"; \ - goto Fail; \ - } \ - Py_DECREF(result) - - CHECK_1_FORMAT("%d", int); - CHECK_1_FORMAT("%ld", long); - /* The z width modifier was added in Python 2.5. */ - CHECK_1_FORMAT("%zd", Py_ssize_t); - - /* The u type code was added in Python 2.5. */ - CHECK_1_FORMAT("%u", unsigned int); - CHECK_1_FORMAT("%lu", unsigned long); - CHECK_1_FORMAT("%zu", size_t); - - /* "%lld" and "%llu" support added in Python 2.7. */ - CHECK_1_FORMAT("%llu", unsigned long long); - CHECK_1_FORMAT("%lld", long long); - - Py_RETURN_NONE; - - Fail: - Py_XDECREF(result); - return raiseTestError("test_string_from_format", msg); - -#undef CHECK_1_FORMAT -} - - -static PyObject * -test_unicode_compare_with_ascii(PyObject *self, PyObject *Py_UNUSED(ignored)) { - PyObject *py_s = PyUnicode_FromStringAndSize("str\0", 4); - int result; - if (py_s == NULL) - return NULL; - result = PyUnicode_CompareWithASCIIString(py_s, "str"); - Py_DECREF(py_s); - if (!result) { - PyErr_SetString(TestError, "Python string ending in NULL " - "should not compare equal to c string."); - return NULL; - } - Py_RETURN_NONE; -} - -/* This is here to provide a docstring for test_descr. */ -static PyObject * -test_with_docstring(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - Py_RETURN_NONE; -} - /* Test PyOS_string_to_double. */ static PyObject * test_string_to_double(PyObject *self, PyObject *Py_UNUSED(ignored)) { @@ -3513,17 +1295,17 @@ static PyObject * exception_print(PyObject *self, PyObject *args) { PyObject *value; - PyObject *tb; + PyObject *tb = NULL; if (!PyArg_ParseTuple(args, "O:exception_print", - &value)) - return NULL; - if (!PyExceptionInstance_Check(value)) { - PyErr_Format(PyExc_TypeError, "an exception instance is required"); + &value)) { return NULL; } - tb = PyException_GetTraceback(value); + if (PyExceptionInstance_Check(value)) { + tb = PyException_GetTraceback(value); + } + PyErr_Display((PyObject *) Py_TYPE(value), value, tb); Py_XDECREF(tb); @@ -3548,8 +1330,7 @@ failing_converter(PyObject *obj, void *arg) { /* Clone str1, then let the conversion fail. */ assert(str1); - str2 = str1; - Py_INCREF(str2); + str2 = Py_NewRef(str1); return 0; } static PyObject* @@ -3788,70 +1569,79 @@ run_in_subinterp(PyObject *self, PyObject *args) return PyLong_FromLong(r); } -static int -check_time_rounding(int round) +/* To run some code in a sub-interpreter. */ +static PyObject * +run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs) { - if (round != _PyTime_ROUND_FLOOR - && round != _PyTime_ROUND_CEILING - && round != _PyTime_ROUND_HALF_EVEN - && round != _PyTime_ROUND_UP) { - PyErr_SetString(PyExc_ValueError, "invalid rounding"); - return -1; + const char *code; + int allow_fork = -1; + int allow_exec = -1; + int allow_threads = -1; + int allow_daemon_threads = -1; + int r; + PyThreadState *substate, *mainstate; + /* only initialise 'cflags.cf_flags' to test backwards compatibility */ + PyCompilerFlags cflags = {0}; + + static char *kwlist[] = {"code", + "allow_fork", + "allow_exec", + "allow_threads", + "allow_daemon_threads", + NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "s$pppp:run_in_subinterp_with_config", kwlist, + &code, &allow_fork, &allow_exec, + &allow_threads, &allow_daemon_threads)) { + return NULL; + } + if (allow_fork < 0) { + PyErr_SetString(PyExc_ValueError, "missing allow_fork"); + return NULL; + } + if (allow_exec < 0) { + PyErr_SetString(PyExc_ValueError, "missing allow_exec"); + return NULL; + } + if (allow_threads < 0) { + PyErr_SetString(PyExc_ValueError, "missing allow_threads"); + return NULL; + } + if (allow_daemon_threads < 0) { + PyErr_SetString(PyExc_ValueError, "missing allow_daemon_threads"); + return NULL; } - return 0; -} -static PyObject * -test_pytime_object_to_time_t(PyObject *self, PyObject *args) -{ - PyObject *obj; - time_t sec; - int round; - if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_time_t", &obj, &round)) - return NULL; - if (check_time_rounding(round) < 0) - return NULL; - if (_PyTime_ObjectToTime_t(obj, &sec, round) == -1) - return NULL; - return _PyLong_FromTime_t(sec); -} + mainstate = PyThreadState_Get(); -static PyObject * -test_pytime_object_to_timeval(PyObject *self, PyObject *args) -{ - PyObject *obj; - time_t sec; - long usec; - int round; - if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_timeval", &obj, &round)) - return NULL; - if (check_time_rounding(round) < 0) - return NULL; - if (_PyTime_ObjectToTimeval(obj, &sec, &usec, round) == -1) - return NULL; - return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), usec); -} + PyThreadState_Swap(NULL); -static PyObject * -test_pytime_object_to_timespec(PyObject *self, PyObject *args) -{ - PyObject *obj; - time_t sec; - long nsec; - int round; - if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_timespec", &obj, &round)) + const _PyInterpreterConfig config = { + .allow_fork = allow_fork, + .allow_exec = allow_exec, + .allow_threads = allow_threads, + .allow_daemon_threads = allow_daemon_threads, + }; + substate = _Py_NewInterpreterFromConfig(&config); + if (substate == NULL) { + /* Since no new thread state was created, there is no exception to + propagate; raise a fresh one after swapping in the old thread + state. */ + PyThreadState_Swap(mainstate); + PyErr_SetString(PyExc_RuntimeError, "sub-interpreter creation failed"); return NULL; - if (check_time_rounding(round) < 0) - return NULL; - if (_PyTime_ObjectToTimespec(obj, &sec, &nsec, round) == -1) - return NULL; - return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), nsec); + } + r = PyRun_SimpleStringFlags(code, &cflags); + Py_EndInterpreter(substate); + + PyThreadState_Swap(mainstate); + + return PyLong_FromLong(r); } static void slot_tp_del(PyObject *self) { - _Py_IDENTIFIER(__tp_del__); PyObject *del, *res; PyObject *error_type, *error_value, *error_traceback; @@ -3862,15 +1652,21 @@ slot_tp_del(PyObject *self) /* Save the current exception, if any. */ PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *tp_del = PyUnicode_InternFromString("__tp_del__"); + if (tp_del == NULL) { + PyErr_WriteUnraisable(NULL); + PyErr_Restore(error_type, error_value, error_traceback); + return; + } /* Execute __del__ method, if any. */ - del = _PyObject_LookupSpecial(self, &PyId___tp_del__); + del = _PyType_Lookup(Py_TYPE(self), tp_del); + Py_DECREF(tp_del); if (del != NULL) { - res = PyObject_CallNoArgs(del); + res = PyObject_CallOneArg(del, self); if (res == NULL) PyErr_WriteUnraisable(del); else Py_DECREF(res); - Py_DECREF(del); } /* Restore the saved exception. */ @@ -3917,8 +1713,7 @@ with_tp_del(PyObject *self, PyObject *args) return NULL; } tp->tp_del = slot_tp_del; - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } static PyObject * @@ -3936,8 +1731,7 @@ without_gc(PyObject *Py_UNUSED(self), PyObject *obj) tp->tp_clear = NULL; } assert(!PyType_IS_GC(tp)); - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } static PyMethodDef ml; @@ -3958,8 +1752,7 @@ static PyMethodDef ml = { static PyObject * _test_incref(PyObject *ob) { - Py_INCREF(ob); - return ob; + return Py_NewRef(ob); } static PyObject * @@ -4052,430 +1845,6 @@ test_incref_decref_API(PyObject *ob, PyObject *Py_UNUSED(ignored)) Py_RETURN_NONE; } -static PyObject * -test_pymem_alloc0(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - void *ptr; - - ptr = PyMem_RawMalloc(0); - if (ptr == NULL) { - PyErr_SetString(PyExc_RuntimeError, "PyMem_RawMalloc(0) returns NULL"); - return NULL; - } - PyMem_RawFree(ptr); - - ptr = PyMem_RawCalloc(0, 0); - if (ptr == NULL) { - PyErr_SetString(PyExc_RuntimeError, "PyMem_RawCalloc(0, 0) returns NULL"); - return NULL; - } - PyMem_RawFree(ptr); - - ptr = PyMem_Malloc(0); - if (ptr == NULL) { - PyErr_SetString(PyExc_RuntimeError, "PyMem_Malloc(0) returns NULL"); - return NULL; - } - PyMem_Free(ptr); - - ptr = PyMem_Calloc(0, 0); - if (ptr == NULL) { - PyErr_SetString(PyExc_RuntimeError, "PyMem_Calloc(0, 0) returns NULL"); - return NULL; - } - PyMem_Free(ptr); - - ptr = PyObject_Malloc(0); - if (ptr == NULL) { - PyErr_SetString(PyExc_RuntimeError, "PyObject_Malloc(0) returns NULL"); - return NULL; - } - PyObject_Free(ptr); - - ptr = PyObject_Calloc(0, 0); - if (ptr == NULL) { - PyErr_SetString(PyExc_RuntimeError, "PyObject_Calloc(0, 0) returns NULL"); - return NULL; - } - PyObject_Free(ptr); - - Py_RETURN_NONE; -} - -typedef struct { - PyMemAllocatorEx alloc; - - size_t malloc_size; - size_t calloc_nelem; - size_t calloc_elsize; - void *realloc_ptr; - size_t realloc_new_size; - void *free_ptr; - void *ctx; -} alloc_hook_t; - -static void* hook_malloc(void* ctx, size_t size) -{ - alloc_hook_t *hook = (alloc_hook_t *)ctx; - hook->ctx = ctx; - hook->malloc_size = size; - return hook->alloc.malloc(hook->alloc.ctx, size); -} - -static void* hook_calloc(void* ctx, size_t nelem, size_t elsize) -{ - alloc_hook_t *hook = (alloc_hook_t *)ctx; - hook->ctx = ctx; - hook->calloc_nelem = nelem; - hook->calloc_elsize = elsize; - return hook->alloc.calloc(hook->alloc.ctx, nelem, elsize); -} - -static void* hook_realloc(void* ctx, void* ptr, size_t new_size) -{ - alloc_hook_t *hook = (alloc_hook_t *)ctx; - hook->ctx = ctx; - hook->realloc_ptr = ptr; - hook->realloc_new_size = new_size; - return hook->alloc.realloc(hook->alloc.ctx, ptr, new_size); -} - -static void hook_free(void *ctx, void *ptr) -{ - alloc_hook_t *hook = (alloc_hook_t *)ctx; - hook->ctx = ctx; - hook->free_ptr = ptr; - hook->alloc.free(hook->alloc.ctx, ptr); -} - -static PyObject * -test_setallocators(PyMemAllocatorDomain domain) -{ - PyObject *res = NULL; - const char *error_msg; - alloc_hook_t hook; - PyMemAllocatorEx alloc; - size_t size, size2, nelem, elsize; - void *ptr, *ptr2; - - memset(&hook, 0, sizeof(hook)); - - alloc.ctx = &hook; - alloc.malloc = &hook_malloc; - alloc.calloc = &hook_calloc; - alloc.realloc = &hook_realloc; - alloc.free = &hook_free; - PyMem_GetAllocator(domain, &hook.alloc); - PyMem_SetAllocator(domain, &alloc); - - /* malloc, realloc, free */ - size = 42; - hook.ctx = NULL; - switch(domain) - { - case PYMEM_DOMAIN_RAW: ptr = PyMem_RawMalloc(size); break; - case PYMEM_DOMAIN_MEM: ptr = PyMem_Malloc(size); break; - case PYMEM_DOMAIN_OBJ: ptr = PyObject_Malloc(size); break; - default: ptr = NULL; break; - } - -#define CHECK_CTX(FUNC) \ - if (hook.ctx != &hook) { \ - error_msg = FUNC " wrong context"; \ - goto fail; \ - } \ - hook.ctx = NULL; /* reset for next check */ - - if (ptr == NULL) { - error_msg = "malloc failed"; - goto fail; - } - CHECK_CTX("malloc"); - if (hook.malloc_size != size) { - error_msg = "malloc invalid size"; - goto fail; - } - - size2 = 200; - switch(domain) - { - case PYMEM_DOMAIN_RAW: ptr2 = PyMem_RawRealloc(ptr, size2); break; - case PYMEM_DOMAIN_MEM: ptr2 = PyMem_Realloc(ptr, size2); break; - case PYMEM_DOMAIN_OBJ: ptr2 = PyObject_Realloc(ptr, size2); break; - default: ptr2 = NULL; break; - } - - if (ptr2 == NULL) { - error_msg = "realloc failed"; - goto fail; - } - CHECK_CTX("realloc"); - if (hook.realloc_ptr != ptr - || hook.realloc_new_size != size2) { - error_msg = "realloc invalid parameters"; - goto fail; - } - - switch(domain) - { - case PYMEM_DOMAIN_RAW: PyMem_RawFree(ptr2); break; - case PYMEM_DOMAIN_MEM: PyMem_Free(ptr2); break; - case PYMEM_DOMAIN_OBJ: PyObject_Free(ptr2); break; - } - - CHECK_CTX("free"); - if (hook.free_ptr != ptr2) { - error_msg = "free invalid pointer"; - goto fail; - } - - /* calloc, free */ - nelem = 2; - elsize = 5; - switch(domain) - { - case PYMEM_DOMAIN_RAW: ptr = PyMem_RawCalloc(nelem, elsize); break; - case PYMEM_DOMAIN_MEM: ptr = PyMem_Calloc(nelem, elsize); break; - case PYMEM_DOMAIN_OBJ: ptr = PyObject_Calloc(nelem, elsize); break; - default: ptr = NULL; break; - } - - if (ptr == NULL) { - error_msg = "calloc failed"; - goto fail; - } - CHECK_CTX("calloc"); - if (hook.calloc_nelem != nelem || hook.calloc_elsize != elsize) { - error_msg = "calloc invalid nelem or elsize"; - goto fail; - } - - hook.free_ptr = NULL; - switch(domain) - { - case PYMEM_DOMAIN_RAW: PyMem_RawFree(ptr); break; - case PYMEM_DOMAIN_MEM: PyMem_Free(ptr); break; - case PYMEM_DOMAIN_OBJ: PyObject_Free(ptr); break; - } - - CHECK_CTX("calloc free"); - if (hook.free_ptr != ptr) { - error_msg = "calloc free invalid pointer"; - goto fail; - } - - Py_INCREF(Py_None); - res = Py_None; - goto finally; - -fail: - PyErr_SetString(PyExc_RuntimeError, error_msg); - -finally: - PyMem_SetAllocator(domain, &hook.alloc); - return res; - -#undef CHECK_CTX -} - -static PyObject * -test_pymem_setrawallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return test_setallocators(PYMEM_DOMAIN_RAW); -} - -static PyObject * -test_pymem_setallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return test_setallocators(PYMEM_DOMAIN_MEM); -} - -static PyObject * -test_pyobject_setallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return test_setallocators(PYMEM_DOMAIN_OBJ); -} - -/* Most part of the following code is inherited from the pyfailmalloc project - * written by Victor Stinner. */ -static struct { - int installed; - PyMemAllocatorEx raw; - PyMemAllocatorEx mem; - PyMemAllocatorEx obj; -} FmHook; - -static struct { - int start; - int stop; - Py_ssize_t count; -} FmData; - -static int -fm_nomemory(void) -{ - FmData.count++; - if (FmData.count > FmData.start && - (FmData.stop <= 0 || FmData.count <= FmData.stop)) { - return 1; - } - return 0; -} - -static void * -hook_fmalloc(void *ctx, size_t size) -{ - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - if (fm_nomemory()) { - return NULL; - } - return alloc->malloc(alloc->ctx, size); -} - -static void * -hook_fcalloc(void *ctx, size_t nelem, size_t elsize) -{ - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - if (fm_nomemory()) { - return NULL; - } - return alloc->calloc(alloc->ctx, nelem, elsize); -} - -static void * -hook_frealloc(void *ctx, void *ptr, size_t new_size) -{ - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - if (fm_nomemory()) { - return NULL; - } - return alloc->realloc(alloc->ctx, ptr, new_size); -} - -static void -hook_ffree(void *ctx, void *ptr) -{ - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - alloc->free(alloc->ctx, ptr); -} - -static void -fm_setup_hooks(void) -{ - PyMemAllocatorEx alloc; - - if (FmHook.installed) { - return; - } - FmHook.installed = 1; - - alloc.malloc = hook_fmalloc; - alloc.calloc = hook_fcalloc; - alloc.realloc = hook_frealloc; - alloc.free = hook_ffree; - PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &FmHook.raw); - PyMem_GetAllocator(PYMEM_DOMAIN_MEM, &FmHook.mem); - PyMem_GetAllocator(PYMEM_DOMAIN_OBJ, &FmHook.obj); - - alloc.ctx = &FmHook.raw; - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &alloc); - - alloc.ctx = &FmHook.mem; - PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &alloc); - - alloc.ctx = &FmHook.obj; - PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc); -} - -static void -fm_remove_hooks(void) -{ - if (FmHook.installed) { - FmHook.installed = 0; - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &FmHook.raw); - PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &FmHook.mem); - PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &FmHook.obj); - } -} - -static PyObject* -set_nomemory(PyObject *self, PyObject *args) -{ - /* Memory allocation fails after 'start' allocation requests, and until - * 'stop' allocation requests except when 'stop' is negative or equal - * to 0 (default) in which case allocation failures never stop. */ - FmData.count = 0; - FmData.stop = 0; - if (!PyArg_ParseTuple(args, "i|i", &FmData.start, &FmData.stop)) { - return NULL; - } - fm_setup_hooks(); - Py_RETURN_NONE; -} - -static PyObject* -remove_mem_hooks(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - fm_remove_hooks(); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(docstring_empty, -"" -); - -PyDoc_STRVAR(docstring_no_signature, -"This docstring has no signature." -); - -PyDoc_STRVAR(docstring_with_invalid_signature, -"docstring_with_invalid_signature($module, /, boo)\n" -"\n" -"This docstring has an invalid signature." -); - -PyDoc_STRVAR(docstring_with_invalid_signature2, -"docstring_with_invalid_signature2($module, /, boo)\n" -"\n" -"--\n" -"\n" -"This docstring also has an invalid signature." -); - -PyDoc_STRVAR(docstring_with_signature, -"docstring_with_signature($module, /, sig)\n" -"--\n" -"\n" -"This docstring has a valid signature." -); - -PyDoc_STRVAR(docstring_with_signature_but_no_doc, -"docstring_with_signature_but_no_doc($module, /, sig)\n" -"--\n" -"\n" -); - -PyDoc_STRVAR(docstring_with_signature_and_extra_newlines, -"docstring_with_signature_and_extra_newlines($module, /, parameter)\n" -"--\n" -"\n" -"\n" -"This docstring has a valid signature and some extra newlines." -); - -PyDoc_STRVAR(docstring_with_signature_with_defaults, -"docstring_with_signature_with_defaults(module, s='avocado',\n" -" b=b'bytes', d=3.14, i=35, n=None, t=True, f=False,\n" -" local=the_number_three, sys=sys.maxsize,\n" -" exp=sys.maxsize - 1)\n" -"--\n" -"\n" -"\n" -"\n" -"This docstring has a valid signature with parameters,\n" -"and the parameters take defaults of varying types." -); - typedef struct { PyThread_type_lock start_event; PyThread_type_lock exit_event; @@ -4510,12 +1879,19 @@ temporary_c_thread(void *data) PyThread_release_lock(test_c_thread->exit_event); } +static test_c_thread_t test_c_thread; + static PyObject * -call_in_temporary_c_thread(PyObject *self, PyObject *callback) +call_in_temporary_c_thread(PyObject *self, PyObject *args) { PyObject *res = NULL; - test_c_thread_t test_c_thread; + PyObject *callback = NULL; long thread; + int wait = 1; + if (!PyArg_ParseTuple(args, "O|i", &callback, &wait)) + { + return NULL; + } test_c_thread.start_event = PyThread_allocate_lock(); test_c_thread.exit_event = PyThread_allocate_lock(); @@ -4525,8 +1901,7 @@ call_in_temporary_c_thread(PyObject *self, PyObject *callback) goto exit; } - Py_INCREF(callback); - test_c_thread.callback = callback; + test_c_thread.callback = Py_NewRef(callback); PyThread_acquire_lock(test_c_thread.start_event, 1); PyThread_acquire_lock(test_c_thread.exit_event, 1); @@ -4542,23 +1917,45 @@ call_in_temporary_c_thread(PyObject *self, PyObject *callback) PyThread_acquire_lock(test_c_thread.start_event, 1); PyThread_release_lock(test_c_thread.start_event); + if (!wait) { + Py_RETURN_NONE; + } + Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(test_c_thread.exit_event, 1); PyThread_release_lock(test_c_thread.exit_event); Py_END_ALLOW_THREADS - Py_INCREF(Py_None); - res = Py_None; + res = Py_NewRef(Py_None); exit: Py_CLEAR(test_c_thread.callback); - if (test_c_thread.start_event) + if (test_c_thread.start_event) { PyThread_free_lock(test_c_thread.start_event); - if (test_c_thread.exit_event) + test_c_thread.start_event = NULL; + } + if (test_c_thread.exit_event) { PyThread_free_lock(test_c_thread.exit_event); + test_c_thread.exit_event = NULL; + } return res; } +static PyObject * +join_temporary_c_thread(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(test_c_thread.exit_event, 1); + PyThread_release_lock(test_c_thread.exit_event); + Py_END_ALLOW_THREADS + Py_CLEAR(test_c_thread.callback); + PyThread_free_lock(test_c_thread.start_event); + test_c_thread.start_event = NULL; + PyThread_free_lock(test_c_thread.exit_event); + test_c_thread.exit_event = NULL; + Py_RETURN_NONE; +} + /* marshal */ static PyObject* @@ -4742,394 +2139,6 @@ getitem_with_error(PyObject *self, PyObject *args) return PyObject_GetItem(map, key); } -static PyObject * -test_pytime_fromseconds(PyObject *self, PyObject *args) -{ - int seconds; - if (!PyArg_ParseTuple(args, "i", &seconds)) { - return NULL; - } - _PyTime_t ts = _PyTime_FromSeconds(seconds); - return _PyTime_AsNanosecondsObject(ts); -} - -static PyObject * -test_pytime_fromsecondsobject(PyObject *self, PyObject *args) -{ - PyObject *obj; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { - return NULL; - } - if (check_time_rounding(round) < 0) { - return NULL; - } - _PyTime_t ts; - if (_PyTime_FromSecondsObject(&ts, obj, round) == -1) { - return NULL; - } - return _PyTime_AsNanosecondsObject(ts); -} - -static PyObject * -test_pytime_assecondsdouble(PyObject *self, PyObject *args) -{ - PyObject *obj; - if (!PyArg_ParseTuple(args, "O", &obj)) { - return NULL; - } - _PyTime_t ts; - if (_PyTime_FromNanosecondsObject(&ts, obj) < 0) { - return NULL; - } - double d = _PyTime_AsSecondsDouble(ts); - return PyFloat_FromDouble(d); -} - -static PyObject * -test_PyTime_AsTimeval(PyObject *self, PyObject *args) -{ - PyObject *obj; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { - return NULL; - } - if (check_time_rounding(round) < 0) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; - } - struct timeval tv; - if (_PyTime_AsTimeval(t, &tv, round) < 0) { - return NULL; - } - - PyObject *seconds = PyLong_FromLongLong(tv.tv_sec); - if (seconds == NULL) { - return NULL; - } - return Py_BuildValue("Nl", seconds, (long)tv.tv_usec); -} - -static PyObject * -test_PyTime_AsTimeval_clamp(PyObject *self, PyObject *args) -{ - PyObject *obj; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { - return NULL; - } - if (check_time_rounding(round) < 0) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; - } - struct timeval tv; - _PyTime_AsTimeval_clamp(t, &tv, round); - - PyObject *seconds = PyLong_FromLongLong(tv.tv_sec); - if (seconds == NULL) { - return NULL; - } - return Py_BuildValue("Nl", seconds, (long)tv.tv_usec); -} - -#ifdef HAVE_CLOCK_GETTIME -static PyObject * -test_PyTime_AsTimespec(PyObject *self, PyObject *args) -{ - PyObject *obj; - if (!PyArg_ParseTuple(args, "O", &obj)) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; - } - struct timespec ts; - if (_PyTime_AsTimespec(t, &ts) == -1) { - return NULL; - } - return Py_BuildValue("Nl", _PyLong_FromTime_t(ts.tv_sec), ts.tv_nsec); -} - -static PyObject * -test_PyTime_AsTimespec_clamp(PyObject *self, PyObject *args) -{ - PyObject *obj; - if (!PyArg_ParseTuple(args, "O", &obj)) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; - } - struct timespec ts; - _PyTime_AsTimespec_clamp(t, &ts); - return Py_BuildValue("Nl", _PyLong_FromTime_t(ts.tv_sec), ts.tv_nsec); -} -#endif - -static PyObject * -test_PyTime_AsMilliseconds(PyObject *self, PyObject *args) -{ - PyObject *obj; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; - } - if (check_time_rounding(round) < 0) { - return NULL; - } - _PyTime_t ms = _PyTime_AsMilliseconds(t, round); - _PyTime_t ns = _PyTime_FromNanoseconds(ms); - return _PyTime_AsNanosecondsObject(ns); -} - -static PyObject * -test_PyTime_AsMicroseconds(PyObject *self, PyObject *args) -{ - PyObject *obj; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; - } - if (check_time_rounding(round) < 0) { - return NULL; - } - _PyTime_t us = _PyTime_AsMicroseconds(t, round); - _PyTime_t ns = _PyTime_FromNanoseconds(us); - return _PyTime_AsNanosecondsObject(ns); -} - -static PyObject* -pymem_buffer_overflow(PyObject *self, PyObject *args) -{ - char *buffer; - - /* Deliberate buffer overflow to check that PyMem_Free() detects - the overflow when debug hooks are installed. */ - buffer = PyMem_Malloc(16); - if (buffer == NULL) { - PyErr_NoMemory(); - return NULL; - } - buffer[16] = 'x'; - PyMem_Free(buffer); - - Py_RETURN_NONE; -} - -static PyObject* -pymem_api_misuse(PyObject *self, PyObject *args) -{ - char *buffer; - - /* Deliberate misusage of Python allocators: - allococate with PyMem but release with PyMem_Raw. */ - buffer = PyMem_Malloc(16); - PyMem_RawFree(buffer); - - Py_RETURN_NONE; -} - -static PyObject* -pymem_malloc_without_gil(PyObject *self, PyObject *args) -{ - char *buffer; - - /* Deliberate bug to test debug hooks on Python memory allocators: - call PyMem_Malloc() without holding the GIL */ - Py_BEGIN_ALLOW_THREADS - buffer = PyMem_Malloc(10); - Py_END_ALLOW_THREADS - - PyMem_Free(buffer); - - Py_RETURN_NONE; -} - - -static PyObject* -test_pymem_getallocatorsname(PyObject *self, PyObject *args) -{ - const char *name = _PyMem_GetCurrentAllocatorName(); - if (name == NULL) { - PyErr_SetString(PyExc_RuntimeError, "cannot get allocators name"); - return NULL; - } - return PyUnicode_FromString(name); -} - - -static PyObject* -test_pyobject_is_freed(const char *test_name, PyObject *op) -{ - if (!_PyObject_IsFreed(op)) { - return raiseTestError(test_name, "object is not seen as freed"); - } - Py_RETURN_NONE; -} - - -static PyObject* -check_pyobject_null_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) -{ - PyObject *op = NULL; - return test_pyobject_is_freed("check_pyobject_null_is_freed", op); -} - - -static PyObject* -check_pyobject_uninitialized_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) -{ - PyObject *op = (PyObject *)PyObject_Malloc(sizeof(PyObject)); - if (op == NULL) { - return NULL; - } - /* Initialize reference count to avoid early crash in ceval or GC */ - Py_SET_REFCNT(op, 1); - /* object fields like ob_type are uninitialized! */ - return test_pyobject_is_freed("check_pyobject_uninitialized_is_freed", op); -} - - -static PyObject* -check_pyobject_forbidden_bytes_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) -{ - /* Allocate an incomplete PyObject structure: truncate 'ob_type' field */ - PyObject *op = (PyObject *)PyObject_Malloc(offsetof(PyObject, ob_type)); - if (op == NULL) { - return NULL; - } - /* Initialize reference count to avoid early crash in ceval or GC */ - Py_SET_REFCNT(op, 1); - /* ob_type field is after the memory block: part of "forbidden bytes" - when using debug hooks on memory allocators! */ - return test_pyobject_is_freed("check_pyobject_forbidden_bytes_is_freed", op); -} - - -static PyObject* -check_pyobject_freed_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) -{ - /* This test would fail if run with the address sanitizer */ -#ifdef _Py_ADDRESS_SANITIZER - Py_RETURN_NONE; -#else - PyObject *op = PyObject_CallNoArgs((PyObject *)&PyBaseObject_Type); - if (op == NULL) { - return NULL; - } - Py_TYPE(op)->tp_dealloc(op); - /* Reset reference count to avoid early crash in ceval or GC */ - Py_SET_REFCNT(op, 1); - /* object memory is freed! */ - return test_pyobject_is_freed("check_pyobject_freed_is_freed", op); -#endif -} - - -static PyObject* -pyobject_malloc_without_gil(PyObject *self, PyObject *args) -{ - char *buffer; - - /* Deliberate bug to test debug hooks on Python memory allocators: - call PyObject_Malloc() without holding the GIL */ - Py_BEGIN_ALLOW_THREADS - buffer = PyObject_Malloc(10); - Py_END_ALLOW_THREADS - - PyObject_Free(buffer); - - Py_RETURN_NONE; -} - -static PyObject * -tracemalloc_track(PyObject *self, PyObject *args) -{ - unsigned int domain; - PyObject *ptr_obj; - void *ptr; - Py_ssize_t size; - int release_gil = 0; - int res; - - if (!PyArg_ParseTuple(args, "IOn|i", &domain, &ptr_obj, &size, &release_gil)) - return NULL; - ptr = PyLong_AsVoidPtr(ptr_obj); - if (PyErr_Occurred()) - return NULL; - - if (release_gil) { - Py_BEGIN_ALLOW_THREADS - res = PyTraceMalloc_Track(domain, (uintptr_t)ptr, size); - Py_END_ALLOW_THREADS - } - else { - res = PyTraceMalloc_Track(domain, (uintptr_t)ptr, size); - } - - if (res < 0) { - PyErr_SetString(PyExc_RuntimeError, "PyTraceMalloc_Track error"); - return NULL; - } - - Py_RETURN_NONE; -} - -static PyObject * -tracemalloc_untrack(PyObject *self, PyObject *args) -{ - unsigned int domain; - PyObject *ptr_obj; - void *ptr; - int res; - - if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj)) - return NULL; - ptr = PyLong_AsVoidPtr(ptr_obj); - if (PyErr_Occurred()) - return NULL; - - res = PyTraceMalloc_Untrack(domain, (uintptr_t)ptr); - if (res < 0) { - PyErr_SetString(PyExc_RuntimeError, "PyTraceMalloc_Untrack error"); - return NULL; - } - - Py_RETURN_NONE; -} - -static PyObject * -tracemalloc_get_traceback(PyObject *self, PyObject *args) -{ - unsigned int domain; - PyObject *ptr_obj; - void *ptr; - - if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj)) - return NULL; - ptr = PyLong_AsVoidPtr(ptr_obj); - if (PyErr_Occurred()) - return NULL; - - return _PyTraceMalloc_GetTraceback(domain, (uintptr_t)ptr); -} - static PyObject * dict_get_version(PyObject *self, PyObject *args) { @@ -5139,9 +2148,13 @@ dict_get_version(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict)) return NULL; + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS version = dict->ma_version_tag; + _Py_COMP_DIAG_POP - Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(version)); + static_assert(sizeof(unsigned long long) >= sizeof(version), + "version is larger than unsigned long long"); return PyLong_FromUnsignedLongLong((unsigned long long)version); } @@ -5149,7 +2162,6 @@ dict_get_version(PyObject *self, PyObject *args) static PyObject * raise_SIGINT_then_send_None(PyObject *self, PyObject *args) { - _Py_IDENTIFIER(send); PyGenObject *gen; if (!PyArg_ParseTuple(args, "O!", &PyGen_Type, &gen)) @@ -5166,129 +2178,7 @@ raise_SIGINT_then_send_None(PyObject *self, PyObject *args) because we check for signals before every bytecode operation. */ raise(SIGINT); - return _PyObject_CallMethodIdOneArg((PyObject *)gen, &PyId_send, Py_None); -} - - -static int -fastcall_args(PyObject *args, PyObject ***stack, Py_ssize_t *nargs) -{ - if (args == Py_None) { - *stack = NULL; - *nargs = 0; - } - else if (PyTuple_Check(args)) { - *stack = ((PyTupleObject *)args)->ob_item; - *nargs = PyTuple_GET_SIZE(args); - } - else { - PyErr_SetString(PyExc_TypeError, "args must be None or a tuple"); - return -1; - } - return 0; -} - - -static PyObject * -test_pyobject_fastcall(PyObject *self, PyObject *args) -{ - PyObject *func, *func_args; - PyObject **stack; - Py_ssize_t nargs; - - if (!PyArg_ParseTuple(args, "OO", &func, &func_args)) { - return NULL; - } - - if (fastcall_args(func_args, &stack, &nargs) < 0) { - return NULL; - } - return _PyObject_FastCall(func, stack, nargs); -} - - -static PyObject * -test_pyobject_fastcalldict(PyObject *self, PyObject *args) -{ - PyObject *func, *func_args, *kwargs; - PyObject **stack; - Py_ssize_t nargs; - - if (!PyArg_ParseTuple(args, "OOO", &func, &func_args, &kwargs)) { - return NULL; - } - - if (fastcall_args(func_args, &stack, &nargs) < 0) { - return NULL; - } - - if (kwargs == Py_None) { - kwargs = NULL; - } - else if (!PyDict_Check(kwargs)) { - PyErr_SetString(PyExc_TypeError, "kwnames must be None or a dict"); - return NULL; - } - - return PyObject_VectorcallDict(func, stack, nargs, kwargs); -} - - -static PyObject * -test_pyobject_vectorcall(PyObject *self, PyObject *args) -{ - PyObject *func, *func_args, *kwnames = NULL; - PyObject **stack; - Py_ssize_t nargs, nkw; - - if (!PyArg_ParseTuple(args, "OOO", &func, &func_args, &kwnames)) { - return NULL; - } - - if (fastcall_args(func_args, &stack, &nargs) < 0) { - return NULL; - } - - if (kwnames == Py_None) { - kwnames = NULL; - } - else if (PyTuple_Check(kwnames)) { - nkw = PyTuple_GET_SIZE(kwnames); - if (nargs < nkw) { - PyErr_SetString(PyExc_ValueError, "kwnames longer than args"); - return NULL; - } - nargs -= nkw; - } - else { - PyErr_SetString(PyExc_TypeError, "kwnames must be None or a tuple"); - return NULL; - } - return PyObject_Vectorcall(func, stack, nargs, kwnames); -} - - -static PyObject * -test_pyvectorcall_call(PyObject *self, PyObject *args) -{ - PyObject *func; - PyObject *argstuple; - PyObject *kwargs = NULL; - - if (!PyArg_ParseTuple(args, "OO|O", &func, &argstuple, &kwargs)) { - return NULL; - } - - if (!PyTuple_Check(argstuple)) { - PyErr_SetString(PyExc_TypeError, "args must be a tuple"); - return NULL; - } - if (kwargs != NULL && !PyDict_Check(kwargs)) { - PyErr_SetString(PyExc_TypeError, "kwargs must be a dict"); - return NULL; - } - - return PyVectorcall_Call(func, argstuple, kwargs); + return PyObject_CallMethod((PyObject *)gen, "send", "O", Py_None); } @@ -5332,6 +2222,71 @@ get_mapping_items(PyObject* self, PyObject *obj) return PyMapping_Items(obj); } +static PyObject * +test_mapping_has_key_string(PyObject *self, PyObject *Py_UNUSED(args)) +{ + PyObject *context = PyDict_New(); + PyObject *val = PyLong_FromLong(1); + + // Since this uses `const char*` it is easier to test this in C: + PyDict_SetItemString(context, "a", val); + if (!PyMapping_HasKeyString(context, "a")) { + PyErr_SetString(PyExc_RuntimeError, + "Existing mapping key does not exist"); + return NULL; + } + if (PyMapping_HasKeyString(context, "b")) { + PyErr_SetString(PyExc_RuntimeError, + "Missing mapping key exists"); + return NULL; + } + + Py_DECREF(val); + Py_DECREF(context); + Py_RETURN_NONE; +} + +static PyObject * +mapping_has_key(PyObject* self, PyObject *args) +{ + PyObject *context, *key; + if (!PyArg_ParseTuple(args, "OO", &context, &key)) { + return NULL; + } + return PyLong_FromLong(PyMapping_HasKey(context, key)); +} + +static PyObject * +sequence_set_slice(PyObject* self, PyObject *args) +{ + PyObject *sequence, *obj; + Py_ssize_t i1, i2; + if (!PyArg_ParseTuple(args, "OnnO", &sequence, &i1, &i2, &obj)) { + return NULL; + } + + int res = PySequence_SetSlice(sequence, i1, i2, obj); + if (res == -1) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +sequence_del_slice(PyObject* self, PyObject *args) +{ + PyObject *sequence; + Py_ssize_t i1, i2; + if (!PyArg_ParseTuple(args, "Onn", &sequence, &i1, &i2)) { + return NULL; + } + + int res = PySequence_DelSlice(sequence, i1, i2); + if (res == -1) { + return NULL; + } + Py_RETURN_NONE; +} static PyObject * test_pythread_tss_key_state(PyObject *self, PyObject *args) @@ -5417,98 +2372,6 @@ bad_get(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } -static PyObject * -encode_locale_ex(PyObject *self, PyObject *args) -{ - PyObject *unicode; - int current_locale = 0; - wchar_t *wstr; - PyObject *res = NULL; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "U|is", &unicode, ¤t_locale, &errors)) { - return NULL; - } - wstr = PyUnicode_AsWideCharString(unicode, NULL); - if (wstr == NULL) { - return NULL; - } - _Py_error_handler error_handler = _Py_GetErrorHandler(errors); - - char *str = NULL; - size_t error_pos; - const char *reason = NULL; - int ret = _Py_EncodeLocaleEx(wstr, - &str, &error_pos, &reason, - current_locale, error_handler); - PyMem_Free(wstr); - - switch(ret) { - case 0: - res = PyBytes_FromString(str); - PyMem_RawFree(str); - break; - case -1: - PyErr_NoMemory(); - break; - case -2: - PyErr_Format(PyExc_RuntimeError, "encode error: pos=%zu, reason=%s", - error_pos, reason); - break; - case -3: - PyErr_SetString(PyExc_ValueError, "unsupported error handler"); - break; - default: - PyErr_SetString(PyExc_ValueError, "unknown error code"); - break; - } - return res; -} - - -static PyObject * -decode_locale_ex(PyObject *self, PyObject *args) -{ - char *str; - int current_locale = 0; - PyObject *res = NULL; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "y|is", &str, ¤t_locale, &errors)) { - return NULL; - } - _Py_error_handler error_handler = _Py_GetErrorHandler(errors); - - wchar_t *wstr = NULL; - size_t wlen = 0; - const char *reason = NULL; - int ret = _Py_DecodeLocaleEx(str, - &wstr, &wlen, &reason, - current_locale, error_handler); - - switch(ret) { - case 0: - res = PyUnicode_FromWideChar(wstr, wlen); - PyMem_RawFree(wstr); - break; - case -1: - PyErr_NoMemory(); - break; - case -2: - PyErr_Format(PyExc_RuntimeError, "decode error: pos=%zu, reason=%s", - wlen, reason); - break; - case -3: - PyErr_SetString(PyExc_ValueError, "unsupported error handler"); - break; - default: - PyErr_SetString(PyExc_ValueError, "unknown error code"); - break; - } - return res; -} - - #ifdef Py_REF_DEBUG static PyObject * negative_refcount(PyObject *self, PyObject *Py_UNUSED(args)) @@ -5565,6 +2428,60 @@ sequence_getitem(PyObject *self, PyObject *args) } +static PyObject * +sequence_setitem(PyObject *self, PyObject *args) +{ + Py_ssize_t i; + PyObject *seq, *val; + if (!PyArg_ParseTuple(args, "OnO", &seq, &i, &val)) { + return NULL; + } + if (PySequence_SetItem(seq, i, val)) { + return NULL; + } + Py_RETURN_NONE; +} + + +static PyObject * +sequence_delitem(PyObject *self, PyObject *args) +{ + Py_ssize_t i; + PyObject *seq; + if (!PyArg_ParseTuple(args, "On", &seq, &i)) { + return NULL; + } + if (PySequence_DelItem(seq, i)) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +hasattr_string(PyObject *self, PyObject* args) +{ + PyObject* obj; + PyObject* attr_name; + + if (!PyArg_UnpackTuple(args, "hasattr_string", 2, 2, &obj, &attr_name)) { + return NULL; + } + + if (!PyUnicode_Check(attr_name)) { + PyErr_SetString(PyExc_TypeError, "attribute name must a be string"); + return PyErr_Occurred(); + } + + const char *name_str = PyUnicode_AsUTF8(attr_name); + if (PyObject_HasAttrString(obj, name_str)) { + Py_RETURN_TRUE; + } + else { + Py_RETURN_FALSE; + } +} + + /* Functions for testing C calling conventions (METH_*) are named meth_*, * e.g. "meth_varargs" for METH_VARARGS. * @@ -5579,8 +2496,7 @@ _null_to_none(PyObject* obj) if (obj == NULL) { Py_RETURN_NONE; } - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } static PyObject* @@ -5637,12 +2553,13 @@ meth_fastcall_keywords(PyObject* self, PyObject* const* args, if (pyargs == NULL) { return NULL; } + assert(args != NULL || nargs == 0); + PyObject* const* args_offset = args == NULL ? NULL : args + nargs; PyObject *pykwargs = PyObject_Vectorcall((PyObject*)&PyDict_Type, - args + nargs, 0, kwargs); + args_offset, 0, kwargs); return Py_BuildValue("NNN", _null_to_none(self), pyargs, pykwargs); } - static PyObject* pynumber_tobase(PyObject *module, PyObject *args) { @@ -5655,7 +2572,6 @@ pynumber_tobase(PyObject *module, PyObject *args) return PyNumber_ToBase(obj, base); } - static PyObject* test_set_type_size(PyObject *self, PyObject *Py_UNUSED(ignored)) { @@ -5678,6 +2594,91 @@ test_set_type_size(PyObject *self, PyObject *Py_UNUSED(ignored)) } +// Test Py_CLEAR() macro +static PyObject* +test_py_clear(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + // simple case with a variable + PyObject *obj = PyList_New(0); + if (obj == NULL) { + return NULL; + } + Py_CLEAR(obj); + assert(obj == NULL); + + // gh-98724: complex case, Py_CLEAR() argument has a side effect + PyObject* array[1]; + array[0] = PyList_New(0); + if (array[0] == NULL) { + return NULL; + } + + PyObject **p = array; + Py_CLEAR(*p++); + assert(array[0] == NULL); + assert(p == array + 1); + + Py_RETURN_NONE; +} + + +// Test Py_SETREF() and Py_XSETREF() macros, similar to test_py_clear() +static PyObject* +test_py_setref(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + // Py_SETREF() simple case with a variable + PyObject *obj = PyList_New(0); + if (obj == NULL) { + return NULL; + } + Py_SETREF(obj, NULL); + assert(obj == NULL); + + // Py_XSETREF() simple case with a variable + PyObject *obj2 = PyList_New(0); + if (obj2 == NULL) { + return NULL; + } + Py_XSETREF(obj2, NULL); + assert(obj2 == NULL); + // test Py_XSETREF() when the argument is NULL + Py_XSETREF(obj2, NULL); + assert(obj2 == NULL); + + // gh-98724: complex case, Py_SETREF() argument has a side effect + PyObject* array[1]; + array[0] = PyList_New(0); + if (array[0] == NULL) { + return NULL; + } + + PyObject **p = array; + Py_SETREF(*p++, NULL); + assert(array[0] == NULL); + assert(p == array + 1); + + // gh-98724: complex case, Py_XSETREF() argument has a side effect + PyObject* array2[1]; + array2[0] = PyList_New(0); + if (array2[0] == NULL) { + return NULL; + } + + PyObject **p2 = array2; + Py_XSETREF(*p2++, NULL); + assert(array2[0] == NULL); + assert(p2 == array2 + 1); + + // test Py_XSETREF() when the argument is NULL + p2 = array2; + Py_XSETREF(*p2++, NULL); + assert(array2[0] == NULL); + assert(p2 == array2 + 1); + + Py_RETURN_NONE; +} + + #define TEST_REFCOUNT() \ do { \ PyObject *obj = PyList_New(0); \ @@ -5860,9 +2861,390 @@ test_tstate_capi(PyObject *self, PyObject *Py_UNUSED(args)) Py_RETURN_NONE; } +static PyObject * +frame_getlocals(PyObject *self, PyObject *frame) +{ + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; + } + return PyFrame_GetLocals((PyFrameObject *)frame); +} + +static PyObject * +frame_getglobals(PyObject *self, PyObject *frame) +{ + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; + } + return PyFrame_GetGlobals((PyFrameObject *)frame); +} + +static PyObject * +frame_getgenerator(PyObject *self, PyObject *frame) +{ + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; + } + return PyFrame_GetGenerator((PyFrameObject *)frame); +} + +static PyObject * +frame_getbuiltins(PyObject *self, PyObject *frame) +{ + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; + } + return PyFrame_GetBuiltins((PyFrameObject *)frame); +} + +static PyObject * +frame_getlasti(PyObject *self, PyObject *frame) +{ + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; + } + int lasti = PyFrame_GetLasti((PyFrameObject *)frame); + if (lasti < 0) { + assert(lasti == -1); + Py_RETURN_NONE; + } + return PyLong_FromLong(lasti); +} + +static PyObject * +frame_new(PyObject *self, PyObject *args) +{ + PyObject *code, *globals, *locals; + if (!PyArg_ParseTuple(args, "OOO", &code, &globals, &locals)) { + return NULL; + } + if (!PyCode_Check(code)) { + PyErr_SetString(PyExc_TypeError, "argument must be a code object"); + return NULL; + } + PyThreadState *tstate = PyThreadState_Get(); + + return (PyObject *)PyFrame_New(tstate, (PyCodeObject *)code, globals, locals); +} + +static PyObject * +test_frame_getvar(PyObject *self, PyObject *args) +{ + PyObject *frame, *name; + if (!PyArg_ParseTuple(args, "OO", &frame, &name)) { + return NULL; + } + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; + } + + return PyFrame_GetVar((PyFrameObject *)frame, name); +} + +static PyObject * +test_frame_getvarstring(PyObject *self, PyObject *args) +{ + PyObject *frame; + const char *name; + if (!PyArg_ParseTuple(args, "Oy", &frame, &name)) { + return NULL; + } + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; + } + + return PyFrame_GetVarString((PyFrameObject *)frame, name); +} + + +static PyObject * +eval_get_func_name(PyObject *self, PyObject *func) +{ + return PyUnicode_FromString(PyEval_GetFuncName(func)); +} + +static PyObject * +eval_get_func_desc(PyObject *self, PyObject *func) +{ + return PyUnicode_FromString(PyEval_GetFuncDesc(func)); +} + +static PyObject * +get_feature_macros(PyObject *self, PyObject *Py_UNUSED(args)) +{ + PyObject *result = PyDict_New(); + if (!result) { + return NULL; + } + int res; +#include "_testcapi_feature_macros.inc" + return result; +} + +static PyObject * +test_code_api(PyObject *self, PyObject *Py_UNUSED(args)) +{ + PyCodeObject *co = PyCode_NewEmpty("_testcapi", "dummy", 1); + if (co == NULL) { + return NULL; + } + /* co_code */ + { + PyObject *co_code = PyCode_GetCode(co); + if (co_code == NULL) { + goto fail; + } + assert(PyBytes_CheckExact(co_code)); + if (PyObject_Length(co_code) == 0) { + PyErr_SetString(PyExc_ValueError, "empty co_code"); + Py_DECREF(co_code); + goto fail; + } + Py_DECREF(co_code); + } + /* co_varnames */ + { + PyObject *co_varnames = PyCode_GetVarnames(co); + if (co_varnames == NULL) { + goto fail; + } + if (!PyTuple_CheckExact(co_varnames)) { + PyErr_SetString(PyExc_TypeError, "co_varnames not tuple"); + Py_DECREF(co_varnames); + goto fail; + } + if (PyTuple_GET_SIZE(co_varnames) != 0) { + PyErr_SetString(PyExc_ValueError, "non-empty co_varnames"); + Py_DECREF(co_varnames); + goto fail; + } + Py_DECREF(co_varnames); + } + /* co_cellvars */ + { + PyObject *co_cellvars = PyCode_GetCellvars(co); + if (co_cellvars == NULL) { + goto fail; + } + if (!PyTuple_CheckExact(co_cellvars)) { + PyErr_SetString(PyExc_TypeError, "co_cellvars not tuple"); + Py_DECREF(co_cellvars); + goto fail; + } + if (PyTuple_GET_SIZE(co_cellvars) != 0) { + PyErr_SetString(PyExc_ValueError, "non-empty co_cellvars"); + Py_DECREF(co_cellvars); + goto fail; + } + Py_DECREF(co_cellvars); + } + /* co_freevars */ + { + PyObject *co_freevars = PyCode_GetFreevars(co); + if (co_freevars == NULL) { + goto fail; + } + if (!PyTuple_CheckExact(co_freevars)) { + PyErr_SetString(PyExc_TypeError, "co_freevars not tuple"); + Py_DECREF(co_freevars); + goto fail; + } + if (PyTuple_GET_SIZE(co_freevars) != 0) { + PyErr_SetString(PyExc_ValueError, "non-empty co_freevars"); + Py_DECREF(co_freevars); + goto fail; + } + Py_DECREF(co_freevars); + } + Py_DECREF(co); + Py_RETURN_NONE; +fail: + Py_DECREF(co); + return NULL; +} + +static int +record_func(PyObject *obj, PyFrameObject *f, int what, PyObject *arg) +{ + assert(PyList_Check(obj)); + PyObject *what_obj = NULL; + PyObject *line_obj = NULL; + PyObject *tuple = NULL; + int res = -1; + what_obj = PyLong_FromLong(what); + if (what_obj == NULL) { + goto error; + } + int line = PyFrame_GetLineNumber(f); + line_obj = PyLong_FromLong(line); + if (line_obj == NULL) { + goto error; + } + tuple = PyTuple_Pack(3, what_obj, line_obj, arg); + if (tuple == NULL) { + goto error; + } + PyTuple_SET_ITEM(tuple, 0, what_obj); + if (PyList_Append(obj, tuple)) { + goto error; + } + res = 0; +error: + Py_XDECREF(what_obj); + Py_XDECREF(line_obj); + Py_XDECREF(tuple); + return res; +} + +static PyObject * +settrace_to_record(PyObject *self, PyObject *list) +{ + + if (!PyList_Check(list)) { + PyErr_SetString(PyExc_TypeError, "argument must be a list"); + return NULL; + } + PyEval_SetTrace(record_func, list); + Py_RETURN_NONE; +} + +static PyObject * +clear_managed_dict(PyObject *self, PyObject *obj) +{ + _PyObject_ClearManagedDict(obj); + Py_RETURN_NONE; +} + + +static PyObject * +test_macros(PyObject *self, PyObject *Py_UNUSED(args)) +{ + struct MyStruct { + int x; + }; + wchar_t array[3]; + + // static_assert(), Py_BUILD_ASSERT() + static_assert(1 == 1, "bug"); + Py_BUILD_ASSERT(1 == 1); + + + // Py_MIN(), Py_MAX(), Py_ABS() + assert(Py_MIN(5, 11) == 5); + assert(Py_MAX(5, 11) == 11); + assert(Py_ABS(-5) == 5); + + // Py_STRINGIFY() + assert(strcmp(Py_STRINGIFY(123), "123") == 0); + + // Py_MEMBER_SIZE(), Py_ARRAY_LENGTH() + assert(Py_MEMBER_SIZE(struct MyStruct, x) == sizeof(int)); + assert(Py_ARRAY_LENGTH(array) == 3); + + // Py_CHARMASK() + int c = 0xab00 | 7; + assert(Py_CHARMASK(c) == 7); + + // _Py_IS_TYPE_SIGNED() + assert(_Py_IS_TYPE_SIGNED(int)); + assert(!_Py_IS_TYPE_SIGNED(unsigned int)); + + Py_RETURN_NONE; +} + +static PyObject * +function_get_code(PyObject *self, PyObject *func) +{ + PyObject *code = PyFunction_GetCode(func); + if (code != NULL) { + return Py_NewRef(code); + } else { + return NULL; + } +} + +static PyObject * +function_get_globals(PyObject *self, PyObject *func) +{ + PyObject *globals = PyFunction_GetGlobals(func); + if (globals != NULL) { + return Py_NewRef(globals); + } else { + return NULL; + } +} + +static PyObject * +function_get_module(PyObject *self, PyObject *func) +{ + PyObject *module = PyFunction_GetModule(func); + if (module != NULL) { + return Py_NewRef(module); + } else { + return NULL; + } +} + +static PyObject * +function_get_defaults(PyObject *self, PyObject *func) +{ + PyObject *defaults = PyFunction_GetDefaults(func); + if (defaults != NULL) { + return Py_NewRef(defaults); + } else if (PyErr_Occurred()) { + return NULL; + } else { + Py_RETURN_NONE; // This can happen when `defaults` are set to `None` + } +} + +static PyObject * +function_set_defaults(PyObject *self, PyObject *args) +{ + PyObject *func = NULL, *defaults = NULL; + if (!PyArg_ParseTuple(args, "OO", &func, &defaults)) { + return NULL; + } + int result = PyFunction_SetDefaults(func, defaults); + if (result == -1) + return NULL; + Py_RETURN_NONE; +} + +static PyObject * +function_get_kw_defaults(PyObject *self, PyObject *func) +{ + PyObject *defaults = PyFunction_GetKwDefaults(func); + if (defaults != NULL) { + return Py_NewRef(defaults); + } else if (PyErr_Occurred()) { + return NULL; + } else { + Py_RETURN_NONE; // This can happen when `kwdefaults` are set to `None` + } +} + +static PyObject * +function_set_kw_defaults(PyObject *self, PyObject *args) +{ + PyObject *func = NULL, *defaults = NULL; + if (!PyArg_ParseTuple(args, "OO", &func, &defaults)) { + return NULL; + } + int result = PyFunction_SetKwDefaults(func, defaults); + if (result == -1) + return NULL; + Py_RETURN_NONE; +} static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *); -static PyObject *getargs_s_hash_int(PyObject *, PyObject *, PyObject*); static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, @@ -5870,33 +3252,11 @@ static PyMethodDef TestMethods[] = { {"set_errno", set_errno, METH_VARARGS}, {"test_config", test_config, METH_NOARGS}, {"test_sizeof_c_types", test_sizeof_c_types, METH_NOARGS}, - {"test_datetime_capi", test_datetime_capi, METH_NOARGS}, - {"datetime_check_date", datetime_check_date, METH_VARARGS}, - {"datetime_check_time", datetime_check_time, METH_VARARGS}, - {"datetime_check_datetime", datetime_check_datetime, METH_VARARGS}, - {"datetime_check_delta", datetime_check_delta, METH_VARARGS}, - {"datetime_check_tzinfo", datetime_check_tzinfo, METH_VARARGS}, - {"make_timezones_capi", make_timezones_capi, METH_NOARGS}, - {"get_timezones_offset_zero", get_timezones_offset_zero, METH_NOARGS}, - {"get_timezone_utc_capi", get_timezone_utc_capi, METH_VARARGS}, - {"get_date_fromdate", get_date_fromdate, METH_VARARGS}, - {"get_datetime_fromdateandtime", get_datetime_fromdateandtime, METH_VARARGS}, - {"get_datetime_fromdateandtimeandfold", get_datetime_fromdateandtimeandfold, METH_VARARGS}, - {"get_time_fromtime", get_time_fromtime, METH_VARARGS}, - {"get_time_fromtimeandfold", get_time_fromtimeandfold, METH_VARARGS}, - {"get_delta_fromdsu", get_delta_fromdsu, METH_VARARGS}, - {"get_date_fromtimestamp", get_date_fromtimestamp, METH_VARARGS}, - {"get_datetime_fromtimestamp", get_datetime_fromtimestamp, METH_VARARGS}, - {"PyDateTime_GET", test_PyDateTime_GET, METH_O}, - {"PyDateTime_DATE_GET", test_PyDateTime_DATE_GET, METH_O}, - {"PyDateTime_TIME_GET", test_PyDateTime_TIME_GET, METH_O}, - {"PyDateTime_DELTA_GET", test_PyDateTime_DELTA_GET, METH_O}, {"test_gc_control", test_gc_control, METH_NOARGS}, {"test_list_api", test_list_api, METH_NOARGS}, {"test_dict_iteration", test_dict_iteration, METH_NOARGS}, {"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS}, {"test_lazy_hash_inheritance", test_lazy_hash_inheritance,METH_NOARGS}, - {"test_long_api", test_long_api, METH_NOARGS}, {"test_xincref_doesnt_leak",test_xincref_doesnt_leak, METH_NOARGS}, {"test_incref_doesnt_leak", test_incref_doesnt_leak, METH_NOARGS}, {"test_xdecref_doesnt_leak",test_xdecref_doesnt_leak, METH_NOARGS}, @@ -5906,168 +3266,51 @@ static PyMethodDef TestMethods[] = { {"test_structseq_newtype_null_descr_doc", test_structseq_newtype_null_descr_doc, METH_NOARGS}, {"test_incref_decref_API", test_incref_decref_API, METH_NOARGS}, - {"test_long_and_overflow", test_long_and_overflow, METH_NOARGS}, - {"test_long_as_double", test_long_as_double, METH_NOARGS}, - {"test_long_as_size_t", test_long_as_size_t, METH_NOARGS}, - {"test_long_as_unsigned_long_long_mask", - test_long_as_unsigned_long_long_mask, METH_NOARGS}, - {"test_long_numbits", test_long_numbits, METH_NOARGS}, - {"test_k_code", test_k_code, METH_NOARGS}, - {"test_empty_argparse", test_empty_argparse, METH_NOARGS}, - {"parse_tuple_and_keywords", parse_tuple_and_keywords, METH_VARARGS}, {"pyobject_repr_from_null", pyobject_repr_from_null, METH_NOARGS}, {"pyobject_str_from_null", pyobject_str_from_null, METH_NOARGS}, {"pyobject_bytes_from_null", pyobject_bytes_from_null, METH_NOARGS}, - {"test_string_from_format", (PyCFunction)test_string_from_format, METH_NOARGS}, - {"test_with_docstring", test_with_docstring, METH_NOARGS, - PyDoc_STR("This is a pretty normal docstring.")}, {"test_string_to_double", test_string_to_double, METH_NOARGS}, - {"test_unicode_compare_with_ascii", test_unicode_compare_with_ascii, - METH_NOARGS}, {"test_capsule", (PyCFunction)test_capsule, METH_NOARGS}, {"test_from_contiguous", (PyCFunction)test_from_contiguous, METH_NOARGS}, #if (defined(__linux__) || defined(__FreeBSD__)) && defined(__GNUC__) {"test_pep3118_obsolete_write_locks", (PyCFunction)test_pep3118_obsolete_write_locks, METH_NOARGS}, #endif - {"getbuffer_with_null_view", getbuffer_with_null_view, METH_O}, - {"PyBuffer_SizeFromFormat", test_PyBuffer_SizeFromFormat, METH_VARARGS}, - {"test_buildvalue_N", test_buildvalue_N, METH_NOARGS}, + {"getbuffer_with_null_view", getbuffer_with_null_view, METH_O}, + {"PyBuffer_SizeFromFormat", test_PyBuffer_SizeFromFormat, METH_VARARGS}, + {"test_buildvalue_N", test_buildvalue_N, METH_NOARGS}, {"test_buildvalue_issue38913", test_buildvalue_issue38913, METH_NOARGS}, - {"get_args", get_args, METH_VARARGS}, {"test_get_statictype_slots", test_get_statictype_slots, METH_NOARGS}, {"test_get_type_name", test_get_type_name, METH_NOARGS}, - {"test_get_type_qualname", test_get_type_qualname, METH_NOARGS}, - {"test_type_from_ephemeral_spec", test_type_from_ephemeral_spec, METH_NOARGS}, - {"get_kwargs", (PyCFunction)(void(*)(void))get_kwargs, - METH_VARARGS|METH_KEYWORDS}, - {"getargs_tuple", getargs_tuple, METH_VARARGS}, - {"getargs_keywords", (PyCFunction)(void(*)(void))getargs_keywords, - METH_VARARGS|METH_KEYWORDS}, - {"getargs_keyword_only", (PyCFunction)(void(*)(void))getargs_keyword_only, - METH_VARARGS|METH_KEYWORDS}, - {"getargs_positional_only_and_keywords", - (PyCFunction)(void(*)(void))getargs_positional_only_and_keywords, - METH_VARARGS|METH_KEYWORDS}, - {"getargs_b", getargs_b, METH_VARARGS}, - {"getargs_B", getargs_B, METH_VARARGS}, - {"getargs_h", getargs_h, METH_VARARGS}, - {"getargs_H", getargs_H, METH_VARARGS}, - {"getargs_I", getargs_I, METH_VARARGS}, - {"getargs_k", getargs_k, METH_VARARGS}, - {"getargs_i", getargs_i, METH_VARARGS}, - {"getargs_l", getargs_l, METH_VARARGS}, - {"getargs_n", getargs_n, METH_VARARGS}, - {"getargs_p", getargs_p, METH_VARARGS}, - {"getargs_L", getargs_L, METH_VARARGS}, - {"getargs_K", getargs_K, METH_VARARGS}, - {"test_longlong_api", test_longlong_api, METH_NOARGS}, - {"test_long_long_and_overflow",test_long_long_and_overflow, METH_NOARGS}, - {"test_L_code", test_L_code, METH_NOARGS}, - {"getargs_f", getargs_f, METH_VARARGS}, - {"getargs_d", getargs_d, METH_VARARGS}, - {"getargs_D", getargs_D, METH_VARARGS}, - {"getargs_S", getargs_S, METH_VARARGS}, - {"getargs_Y", getargs_Y, METH_VARARGS}, - {"getargs_U", getargs_U, METH_VARARGS}, - {"getargs_c", getargs_c, METH_VARARGS}, - {"getargs_C", getargs_C, METH_VARARGS}, - {"getargs_s", getargs_s, METH_VARARGS}, - {"getargs_s_star", getargs_s_star, METH_VARARGS}, - {"getargs_s_hash", getargs_s_hash, METH_VARARGS}, - {"getargs_s_hash_int", (PyCFunction)(void(*)(void))getargs_s_hash_int, - METH_VARARGS|METH_KEYWORDS}, - {"getargs_z", getargs_z, METH_VARARGS}, - {"getargs_z_star", getargs_z_star, METH_VARARGS}, - {"getargs_z_hash", getargs_z_hash, METH_VARARGS}, - {"getargs_y", getargs_y, METH_VARARGS}, - {"getargs_y_star", getargs_y_star, METH_VARARGS}, - {"getargs_y_hash", getargs_y_hash, METH_VARARGS}, - {"getargs_u", getargs_u, METH_VARARGS}, - {"getargs_u_hash", getargs_u_hash, METH_VARARGS}, - {"getargs_Z", getargs_Z, METH_VARARGS}, - {"getargs_Z_hash", getargs_Z_hash, METH_VARARGS}, - {"getargs_w_star", getargs_w_star, METH_VARARGS}, - {"getargs_es", getargs_es, METH_VARARGS}, - {"getargs_et", getargs_et, METH_VARARGS}, - {"getargs_es_hash", getargs_es_hash, METH_VARARGS}, - {"getargs_et_hash", getargs_et_hash, METH_VARARGS}, - {"codec_incrementalencoder", - (PyCFunction)codec_incrementalencoder, METH_VARARGS}, - {"codec_incrementaldecoder", - (PyCFunction)codec_incrementaldecoder, METH_VARARGS}, - {"test_s_code", test_s_code, METH_NOARGS}, -#if USE_UNICODE_WCHAR_CACHE - {"test_u_code", test_u_code, METH_NOARGS}, - {"test_Z_code", test_Z_code, METH_NOARGS}, -#endif /* USE_UNICODE_WCHAR_CACHE */ - {"test_widechar", test_widechar, METH_NOARGS}, - {"unicode_aswidechar", unicode_aswidechar, METH_VARARGS}, - {"unicode_aswidecharstring",unicode_aswidecharstring, METH_VARARGS}, - {"unicode_asucs4", unicode_asucs4, METH_VARARGS}, - {"unicode_asutf8", unicode_asutf8, METH_VARARGS}, - {"unicode_asutf8andsize", unicode_asutf8andsize, METH_VARARGS}, - {"unicode_findchar", unicode_findchar, METH_VARARGS}, - {"unicode_copycharacters", unicode_copycharacters, METH_VARARGS}, -#if USE_UNICODE_WCHAR_CACHE - {"unicode_legacy_string", unicode_legacy_string, METH_VARARGS}, -#endif /* USE_UNICODE_WCHAR_CACHE */ + {"test_get_type_qualname", test_get_type_qualname, METH_NOARGS}, {"_test_thread_state", test_thread_state, METH_VARARGS}, +#ifndef MS_WINDOWS + {"_spawn_pthread_waiter", spawn_pthread_waiter, METH_NOARGS}, + {"_end_spawned_pthread", end_spawned_pthread, METH_NOARGS}, +#endif {"_pending_threadfunc", pending_threadfunc, METH_VARARGS}, #ifdef HAVE_GETTIMEOFDAY {"profile_int", profile_int, METH_NOARGS}, #endif {"traceback_print", traceback_print, METH_VARARGS}, {"exception_print", exception_print, METH_VARARGS}, + {"set_exception", test_set_exception, METH_O}, {"set_exc_info", test_set_exc_info, METH_VARARGS}, {"argparsing", argparsing, METH_VARARGS}, {"code_newempty", code_newempty, METH_VARARGS}, - {"make_exception_with_doc", (PyCFunction)(void(*)(void))make_exception_with_doc, + {"make_exception_with_doc", _PyCFunction_CAST(make_exception_with_doc), METH_VARARGS | METH_KEYWORDS}, {"make_memoryview_from_NULL_pointer", make_memoryview_from_NULL_pointer, METH_NOARGS}, {"crash_no_current_thread", crash_no_current_thread, METH_NOARGS}, {"run_in_subinterp", run_in_subinterp, METH_VARARGS}, - {"pytime_object_to_time_t", test_pytime_object_to_time_t, METH_VARARGS}, - {"pytime_object_to_timeval", test_pytime_object_to_timeval, METH_VARARGS}, - {"pytime_object_to_timespec", test_pytime_object_to_timespec, METH_VARARGS}, + {"run_in_subinterp_with_config", + _PyCFunction_CAST(run_in_subinterp_with_config), + METH_VARARGS | METH_KEYWORDS}, {"with_tp_del", with_tp_del, METH_VARARGS}, {"create_cfunction", create_cfunction, METH_NOARGS}, - {"test_pymem_alloc0", test_pymem_alloc0, METH_NOARGS}, - {"test_pymem_setrawallocators",test_pymem_setrawallocators, METH_NOARGS}, - {"test_pymem_setallocators",test_pymem_setallocators, METH_NOARGS}, - {"test_pyobject_setallocators",test_pyobject_setallocators, METH_NOARGS}, - {"set_nomemory", (PyCFunction)set_nomemory, METH_VARARGS, - PyDoc_STR("set_nomemory(start:int, stop:int = 0)")}, - {"remove_mem_hooks", remove_mem_hooks, METH_NOARGS, - PyDoc_STR("Remove memory hooks.")}, - {"no_docstring", - (PyCFunction)test_with_docstring, METH_NOARGS}, - {"docstring_empty", - (PyCFunction)test_with_docstring, METH_NOARGS, - docstring_empty}, - {"docstring_no_signature", - (PyCFunction)test_with_docstring, METH_NOARGS, - docstring_no_signature}, - {"docstring_with_invalid_signature", - (PyCFunction)test_with_docstring, METH_NOARGS, - docstring_with_invalid_signature}, - {"docstring_with_invalid_signature2", - (PyCFunction)test_with_docstring, METH_NOARGS, - docstring_with_invalid_signature2}, - {"docstring_with_signature", - (PyCFunction)test_with_docstring, METH_NOARGS, - docstring_with_signature}, - {"docstring_with_signature_but_no_doc", - (PyCFunction)test_with_docstring, METH_NOARGS, - docstring_with_signature_but_no_doc}, - {"docstring_with_signature_and_extra_newlines", - (PyCFunction)test_with_docstring, METH_NOARGS, - docstring_with_signature_and_extra_newlines}, - {"docstring_with_signature_with_defaults", - (PyCFunction)test_with_docstring, METH_NOARGS, - docstring_with_signature_with_defaults}, - {"call_in_temporary_c_thread", call_in_temporary_c_thread, METH_O, + {"call_in_temporary_c_thread", call_in_temporary_c_thread, METH_VARARGS, PyDoc_STR("set_error_class(error_class) -> None")}, + {"join_temporary_c_thread", join_temporary_c_thread, METH_NOARGS}, {"pymarshal_write_long_to_file", pymarshal_write_long_to_file, METH_VARARGS}, {"pymarshal_write_object_to_file", @@ -6084,35 +3327,8 @@ static PyMethodDef TestMethods[] = { {"return_result_with_error", return_result_with_error, METH_NOARGS}, {"getitem_with_error", getitem_with_error, METH_VARARGS}, {"Py_CompileString", pycompilestring, METH_O}, - {"PyTime_FromSeconds", test_pytime_fromseconds, METH_VARARGS}, - {"PyTime_FromSecondsObject", test_pytime_fromsecondsobject, METH_VARARGS}, - {"PyTime_AsSecondsDouble", test_pytime_assecondsdouble, METH_VARARGS}, - {"PyTime_AsTimeval", test_PyTime_AsTimeval, METH_VARARGS}, - {"PyTime_AsTimeval_clamp", test_PyTime_AsTimeval_clamp, METH_VARARGS}, -#ifdef HAVE_CLOCK_GETTIME - {"PyTime_AsTimespec", test_PyTime_AsTimespec, METH_VARARGS}, - {"PyTime_AsTimespec_clamp", test_PyTime_AsTimespec_clamp, METH_VARARGS}, -#endif - {"PyTime_AsMilliseconds", test_PyTime_AsMilliseconds, METH_VARARGS}, - {"PyTime_AsMicroseconds", test_PyTime_AsMicroseconds, METH_VARARGS}, - {"pymem_buffer_overflow", pymem_buffer_overflow, METH_NOARGS}, - {"pymem_api_misuse", pymem_api_misuse, METH_NOARGS}, - {"pymem_malloc_without_gil", pymem_malloc_without_gil, METH_NOARGS}, - {"pymem_getallocatorsname", test_pymem_getallocatorsname, METH_NOARGS}, - {"check_pyobject_null_is_freed", check_pyobject_null_is_freed, METH_NOARGS}, - {"check_pyobject_uninitialized_is_freed", check_pyobject_uninitialized_is_freed, METH_NOARGS}, - {"check_pyobject_forbidden_bytes_is_freed", check_pyobject_forbidden_bytes_is_freed, METH_NOARGS}, - {"check_pyobject_freed_is_freed", check_pyobject_freed_is_freed, METH_NOARGS}, - {"pyobject_malloc_without_gil", pyobject_malloc_without_gil, METH_NOARGS}, - {"tracemalloc_track", tracemalloc_track, METH_VARARGS}, - {"tracemalloc_untrack", tracemalloc_untrack, METH_VARARGS}, - {"tracemalloc_get_traceback", tracemalloc_get_traceback, METH_VARARGS}, {"dict_get_version", dict_get_version, METH_VARARGS}, {"raise_SIGINT_then_send_None", raise_SIGINT_then_send_None, METH_VARARGS}, - {"pyobject_fastcall", test_pyobject_fastcall, METH_VARARGS}, - {"pyobject_fastcalldict", test_pyobject_fastcalldict, METH_VARARGS}, - {"pyobject_vectorcall", test_pyobject_vectorcall, METH_VARARGS}, - {"pyvectorcall_call", test_pyvectorcall_call, METH_VARARGS}, {"stack_pointer", stack_pointer, METH_NOARGS}, #ifdef W_STOPCODE {"W_STOPCODE", py_w_stopcode, METH_VARARGS}, @@ -6120,25 +3336,32 @@ static PyMethodDef TestMethods[] = { {"get_mapping_keys", get_mapping_keys, METH_O}, {"get_mapping_values", get_mapping_values, METH_O}, {"get_mapping_items", get_mapping_items, METH_O}, + {"test_mapping_has_key_string", test_mapping_has_key_string, METH_NOARGS}, + {"mapping_has_key", mapping_has_key, METH_VARARGS}, + {"sequence_set_slice", sequence_set_slice, METH_VARARGS}, + {"sequence_del_slice", sequence_del_slice, METH_VARARGS}, {"test_pythread_tss_key_state", test_pythread_tss_key_state, METH_VARARGS}, {"hamt", new_hamt, METH_NOARGS}, - {"bad_get", (PyCFunction)(void(*)(void))bad_get, METH_FASTCALL}, - {"EncodeLocaleEx", encode_locale_ex, METH_VARARGS}, - {"DecodeLocaleEx", decode_locale_ex, METH_VARARGS}, + {"bad_get", _PyCFunction_CAST(bad_get), METH_FASTCALL}, #ifdef Py_REF_DEBUG {"negative_refcount", negative_refcount, METH_NOARGS}, #endif {"write_unraisable_exc", test_write_unraisable_exc, METH_VARARGS}, {"sequence_getitem", sequence_getitem, METH_VARARGS}, + {"sequence_setitem", sequence_setitem, METH_VARARGS}, + {"sequence_delitem", sequence_delitem, METH_VARARGS}, + {"hasattr_string", hasattr_string, METH_VARARGS}, {"meth_varargs", meth_varargs, METH_VARARGS}, - {"meth_varargs_keywords", (PyCFunction)(void(*)(void))meth_varargs_keywords, METH_VARARGS|METH_KEYWORDS}, + {"meth_varargs_keywords", _PyCFunction_CAST(meth_varargs_keywords), METH_VARARGS|METH_KEYWORDS}, {"meth_o", meth_o, METH_O}, {"meth_noargs", meth_noargs, METH_NOARGS}, - {"meth_fastcall", (PyCFunction)(void(*)(void))meth_fastcall, METH_FASTCALL}, - {"meth_fastcall_keywords", (PyCFunction)(void(*)(void))meth_fastcall_keywords, METH_FASTCALL|METH_KEYWORDS}, + {"meth_fastcall", _PyCFunction_CAST(meth_fastcall), METH_FASTCALL}, + {"meth_fastcall_keywords", _PyCFunction_CAST(meth_fastcall_keywords), METH_FASTCALL|METH_KEYWORDS}, {"pynumber_tobase", pynumber_tobase, METH_VARARGS}, {"without_gc", without_gc, METH_O}, {"test_set_type_size", test_set_type_size, METH_NOARGS}, + {"test_py_clear", test_py_clear, METH_NOARGS}, + {"test_py_setref", test_py_setref, METH_NOARGS}, {"test_refcount_macros", test_refcount_macros, METH_NOARGS}, {"test_refcount_funcs", test_refcount_funcs, METH_NOARGS}, {"test_py_is_macros", test_py_is_macros, METH_NOARGS}, @@ -6147,152 +3370,31 @@ static PyMethodDef TestMethods[] = { PyDoc_STR("fatal_error(message, release_gil=False): call Py_FatalError(message)")}, {"type_get_version", type_get_version, METH_O, PyDoc_STR("type->tp_version_tag")}, {"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL}, + {"frame_getlocals", frame_getlocals, METH_O, NULL}, + {"frame_getglobals", frame_getglobals, METH_O, NULL}, + {"frame_getgenerator", frame_getgenerator, METH_O, NULL}, + {"frame_getbuiltins", frame_getbuiltins, METH_O, NULL}, + {"frame_getlasti", frame_getlasti, METH_O, NULL}, + {"frame_new", frame_new, METH_VARARGS, NULL}, + {"frame_getvar", test_frame_getvar, METH_VARARGS, NULL}, + {"frame_getvarstring", test_frame_getvarstring, METH_VARARGS, NULL}, + {"eval_get_func_name", eval_get_func_name, METH_O, NULL}, + {"eval_get_func_desc", eval_get_func_desc, METH_O, NULL}, + {"get_feature_macros", get_feature_macros, METH_NOARGS, NULL}, + {"test_code_api", test_code_api, METH_NOARGS, NULL}, + {"settrace_to_record", settrace_to_record, METH_O, NULL}, + {"test_macros", test_macros, METH_NOARGS, NULL}, + {"clear_managed_dict", clear_managed_dict, METH_O, NULL}, + {"function_get_code", function_get_code, METH_O, NULL}, + {"function_get_globals", function_get_globals, METH_O, NULL}, + {"function_get_module", function_get_module, METH_O, NULL}, + {"function_get_defaults", function_get_defaults, METH_O, NULL}, + {"function_set_defaults", function_set_defaults, METH_VARARGS, NULL}, + {"function_get_kw_defaults", function_get_kw_defaults, METH_O, NULL}, + {"function_set_kw_defaults", function_set_kw_defaults, METH_VARARGS, NULL}, {NULL, NULL} /* sentinel */ }; -#define AddSym(d, n, f, v) {PyObject *o = f(v); PyDict_SetItemString(d, n, o); Py_DECREF(o);} - -typedef struct { - char bool_member; - char byte_member; - unsigned char ubyte_member; - short short_member; - unsigned short ushort_member; - int int_member; - unsigned int uint_member; - long long_member; - unsigned long ulong_member; - Py_ssize_t pyssizet_member; - float float_member; - double double_member; - char inplace_member[6]; - long long longlong_member; - unsigned long long ulonglong_member; -} all_structmembers; - -typedef struct { - PyObject_HEAD - all_structmembers structmembers; -} test_structmembers; - -static struct PyMemberDef test_members[] = { - {"T_BOOL", T_BOOL, offsetof(test_structmembers, structmembers.bool_member), 0, NULL}, - {"T_BYTE", T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL}, - {"T_UBYTE", T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL}, - {"T_SHORT", T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL}, - {"T_USHORT", T_USHORT, offsetof(test_structmembers, structmembers.ushort_member), 0, NULL}, - {"T_INT", T_INT, offsetof(test_structmembers, structmembers.int_member), 0, NULL}, - {"T_UINT", T_UINT, offsetof(test_structmembers, structmembers.uint_member), 0, NULL}, - {"T_LONG", T_LONG, offsetof(test_structmembers, structmembers.long_member), 0, NULL}, - {"T_ULONG", T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL}, - {"T_PYSSIZET", T_PYSSIZET, offsetof(test_structmembers, structmembers.pyssizet_member), 0, NULL}, - {"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL}, - {"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL}, - {"T_STRING_INPLACE", T_STRING_INPLACE, offsetof(test_structmembers, structmembers.inplace_member), 0, NULL}, - {"T_LONGLONG", T_LONGLONG, offsetof(test_structmembers, structmembers.longlong_member), 0, NULL}, - {"T_ULONGLONG", T_ULONGLONG, offsetof(test_structmembers, structmembers.ulonglong_member), 0, NULL}, - {NULL} -}; - - -static PyObject * -test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - static char *keywords[] = { - "T_BOOL", "T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", - "T_INT", "T_UINT", "T_LONG", "T_ULONG", "T_PYSSIZET", - "T_FLOAT", "T_DOUBLE", "T_STRING_INPLACE", - "T_LONGLONG", "T_ULONGLONG", - NULL}; - static const char fmt[] = "|bbBhHiIlknfds#LK"; - test_structmembers *ob; - const char *s = NULL; - Py_ssize_t string_len = 0; - ob = PyObject_New(test_structmembers, type); - if (ob == NULL) - return NULL; - memset(&ob->structmembers, 0, sizeof(all_structmembers)); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords, - &ob->structmembers.bool_member, - &ob->structmembers.byte_member, - &ob->structmembers.ubyte_member, - &ob->structmembers.short_member, - &ob->structmembers.ushort_member, - &ob->structmembers.int_member, - &ob->structmembers.uint_member, - &ob->structmembers.long_member, - &ob->structmembers.ulong_member, - &ob->structmembers.pyssizet_member, - &ob->structmembers.float_member, - &ob->structmembers.double_member, - &s, &string_len - , &ob->structmembers.longlong_member, - &ob->structmembers.ulonglong_member - )) { - Py_DECREF(ob); - return NULL; - } - if (s != NULL) { - if (string_len > 5) { - Py_DECREF(ob); - PyErr_SetString(PyExc_ValueError, "string too long"); - return NULL; - } - strcpy(ob->structmembers.inplace_member, s); - } - else { - strcpy(ob->structmembers.inplace_member, ""); - } - return (PyObject *)ob; -} - -static void -test_structmembers_free(PyObject *ob) -{ - PyObject_Free(ob); -} - -static PyTypeObject test_structmembersType = { - PyVarObject_HEAD_INIT(NULL, 0) - "test_structmembersType", - sizeof(test_structmembers), /* tp_basicsize */ - 0, /* tp_itemsize */ - test_structmembers_free, /* destructor tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - PyObject_GenericSetAttr, /* tp_setattro */ - 0, /* tp_as_buffer */ - 0, /* tp_flags */ - "Type containing all structmember types", - 0, /* traverseproc tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - test_members, /* tp_members */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - test_structmembers_new, /* tp_new */ -}; - typedef struct { PyObject_HEAD @@ -6439,8 +3541,7 @@ awaitObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - Py_INCREF(v); - ao->ao_iterator = v; + ao->ao_iterator = Py_NewRef(v); return (PyObject *)ao; } @@ -6457,8 +3558,7 @@ awaitObject_dealloc(awaitObject *ao) static PyObject * awaitObject_await(awaitObject *ao) { - Py_INCREF(ao->ao_iterator); - return ao->ao_iterator; + return Py_NewRef(ao->ao_iterator); } static PyAsyncMethods awaitType_as_async = { @@ -6535,7 +3635,7 @@ static PyTypeObject PyRecursingInfinitelyError_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "Instantiating this exception starts infinite recursion.", /* tp_doc */ + PyDoc_STR("Instantiating this exception starts infinite recursion."), /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -6658,7 +3758,7 @@ generic_alias_mro_entries(PyGenericAliasObject *self, PyObject *bases) } static PyMethodDef generic_alias_methods[] = { - {"__mro_entries__", (PyCFunction)(void(*)(void))generic_alias_mro_entries, METH_O, NULL}, + {"__mro_entries__", _PyCFunction_CAST(generic_alias_mro_entries), METH_O, NULL}, {NULL} /* sentinel */ }; @@ -6679,8 +3779,7 @@ generic_alias_new(PyObject *item) if (o == NULL) { return NULL; } - Py_INCREF(item); - o->item = item; + o->item = Py_NewRef(item); return (PyObject*) o; } @@ -6708,584 +3807,13 @@ static PyTypeObject Generic_Type = { .tp_methods = generic_methods, }; - -/* Test PEP 590 */ - -typedef struct { - PyObject_HEAD - vectorcallfunc vectorcall; -} MethodDescriptorObject; - -static PyObject * -MethodDescriptor_vectorcall(PyObject *callable, PyObject *const *args, - size_t nargsf, PyObject *kwnames) -{ - /* True if using the vectorcall function in MethodDescriptorObject - * but False for MethodDescriptor2Object */ - MethodDescriptorObject *md = (MethodDescriptorObject *)callable; - return PyBool_FromLong(md->vectorcall != NULL); -} - -static PyObject * -MethodDescriptor_new(PyTypeObject* type, PyObject* args, PyObject *kw) -{ - MethodDescriptorObject *op = (MethodDescriptorObject *)type->tp_alloc(type, 0); - op->vectorcall = MethodDescriptor_vectorcall; - return (PyObject *)op; -} - -static PyObject * -func_descr_get(PyObject *func, PyObject *obj, PyObject *type) -{ - if (obj == Py_None || obj == NULL) { - Py_INCREF(func); - return func; - } - return PyMethod_New(func, obj); -} - -static PyObject * -nop_descr_get(PyObject *func, PyObject *obj, PyObject *type) -{ - Py_INCREF(func); - return func; -} - -static PyObject * -call_return_args(PyObject *self, PyObject *args, PyObject *kwargs) -{ - Py_INCREF(args); - return args; -} - -static PyTypeObject MethodDescriptorBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MethodDescriptorBase", - sizeof(MethodDescriptorObject), - .tp_new = MethodDescriptor_new, - .tp_call = PyVectorcall_Call, - .tp_vectorcall_offset = offsetof(MethodDescriptorObject, vectorcall), - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_METHOD_DESCRIPTOR | Py_TPFLAGS_HAVE_VECTORCALL, - .tp_descr_get = func_descr_get, -}; - -static PyTypeObject MethodDescriptorDerived_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MethodDescriptorDerived", - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, -}; - -static PyTypeObject MethodDescriptorNopGet_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MethodDescriptorNopGet", - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_call = call_return_args, - .tp_descr_get = nop_descr_get, -}; - -typedef struct { - MethodDescriptorObject base; - vectorcallfunc vectorcall; -} MethodDescriptor2Object; - -static PyObject * -MethodDescriptor2_new(PyTypeObject* type, PyObject* args, PyObject *kw) -{ - MethodDescriptor2Object *op = PyObject_New(MethodDescriptor2Object, type); - op->base.vectorcall = NULL; - op->vectorcall = MethodDescriptor_vectorcall; - return (PyObject *)op; -} - -static PyTypeObject MethodDescriptor2_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MethodDescriptor2", - sizeof(MethodDescriptor2Object), - .tp_new = MethodDescriptor2_new, - .tp_call = PyVectorcall_Call, - .tp_vectorcall_offset = offsetof(MethodDescriptor2Object, vectorcall), - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL, -}; - -PyDoc_STRVAR(heapdocctype__doc__, -"HeapDocCType(arg1, arg2)\n" -"--\n" -"\n" -"somedoc"); - -typedef struct { - PyObject_HEAD -} HeapDocCTypeObject; - -static PyType_Slot HeapDocCType_slots[] = { - {Py_tp_doc, (char*)heapdocctype__doc__}, - {0}, -}; - -static PyType_Spec HeapDocCType_spec = { - "_testcapi.HeapDocCType", - sizeof(HeapDocCTypeObject), - 0, - Py_TPFLAGS_DEFAULT, - HeapDocCType_slots -}; - -typedef struct { - PyObject_HEAD -} HeapTypeNameObject; - -static PyType_Slot HeapTypeNameType_slots[] = { - {0}, -}; - -static PyType_Spec HeapTypeNameType_Spec = { - .name = "_testcapi.HeapTypeNameType", - .basicsize = sizeof(HeapTypeNameObject), - .flags = Py_TPFLAGS_DEFAULT, - .slots = HeapTypeNameType_slots, -}; - -typedef struct { - PyObject_HEAD -} NullTpDocTypeObject; - -static PyType_Slot NullTpDocType_slots[] = { - {Py_tp_doc, NULL}, - {0, 0}, -}; - -static PyType_Spec NullTpDocType_spec = { - "_testcapi.NullTpDocType", - sizeof(NullTpDocTypeObject), - 0, - Py_TPFLAGS_DEFAULT, - NullTpDocType_slots -}; - - -PyDoc_STRVAR(heapgctype__doc__, -"A heap type with GC, and with overridden dealloc.\n\n" -"The 'value' attribute is set to 10 in __init__."); - -typedef struct { - PyObject_HEAD - int value; -} HeapCTypeObject; - -static struct PyMemberDef heapctype_members[] = { - {"value", T_INT, offsetof(HeapCTypeObject, value)}, - {NULL} /* Sentinel */ -}; - -static int -heapctype_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - ((HeapCTypeObject *)self)->value = 10; - return 0; -} - -static int -heapgcctype_traverse(HeapCTypeObject *self, visitproc visit, void *arg) -{ - Py_VISIT(Py_TYPE(self)); - return 0; -} - -static void -heapgcctype_dealloc(HeapCTypeObject *self) -{ - PyTypeObject *tp = Py_TYPE(self); - PyObject_GC_UnTrack(self); - PyObject_GC_Del(self); - Py_DECREF(tp); -} - -static PyType_Slot HeapGcCType_slots[] = { - {Py_tp_init, heapctype_init}, - {Py_tp_members, heapctype_members}, - {Py_tp_dealloc, heapgcctype_dealloc}, - {Py_tp_traverse, heapgcctype_traverse}, - {Py_tp_doc, (char*)heapgctype__doc__}, - {0, 0}, -}; - -static PyType_Spec HeapGcCType_spec = { - "_testcapi.HeapGcCType", - sizeof(HeapCTypeObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - HeapGcCType_slots -}; - -PyDoc_STRVAR(heapctype__doc__, -"A heap type without GC, but with overridden dealloc.\n\n" -"The 'value' attribute is set to 10 in __init__."); - -static void -heapctype_dealloc(HeapCTypeObject *self) -{ - PyTypeObject *tp = Py_TYPE(self); - PyObject_Free(self); - Py_DECREF(tp); -} - -static PyType_Slot HeapCType_slots[] = { - {Py_tp_init, heapctype_init}, - {Py_tp_members, heapctype_members}, - {Py_tp_dealloc, heapctype_dealloc}, - {Py_tp_doc, (char*)heapctype__doc__}, - {0, 0}, -}; - -static PyType_Spec HeapCType_spec = { - "_testcapi.HeapCType", - sizeof(HeapCTypeObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCType_slots -}; - -PyDoc_STRVAR(heapctypesubclass__doc__, -"Subclass of HeapCType, without GC.\n\n" -"__init__ sets the 'value' attribute to 10 and 'value2' to 20."); - -typedef struct { - HeapCTypeObject base; - int value2; -} HeapCTypeSubclassObject; - -static int -heapctypesubclass_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - /* Call __init__ of the superclass */ - if (heapctype_init(self, args, kwargs) < 0) { - return -1; - } - /* Initialize additional element */ - ((HeapCTypeSubclassObject *)self)->value2 = 20; - return 0; -} - -static struct PyMemberDef heapctypesubclass_members[] = { - {"value2", T_INT, offsetof(HeapCTypeSubclassObject, value2)}, - {NULL} /* Sentinel */ -}; - -static PyType_Slot HeapCTypeSubclass_slots[] = { - {Py_tp_init, heapctypesubclass_init}, - {Py_tp_members, heapctypesubclass_members}, - {Py_tp_doc, (char*)heapctypesubclass__doc__}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeSubclass_spec = { - "_testcapi.HeapCTypeSubclass", - sizeof(HeapCTypeSubclassObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeSubclass_slots -}; - -PyDoc_STRVAR(heapctypewithbuffer__doc__, -"Heap type with buffer support.\n\n" -"The buffer is set to [b'1', b'2', b'3', b'4']"); - -typedef struct { - HeapCTypeObject base; - char buffer[4]; -} HeapCTypeWithBufferObject; - -static int -heapctypewithbuffer_getbuffer(HeapCTypeWithBufferObject *self, Py_buffer *view, int flags) -{ - self->buffer[0] = '1'; - self->buffer[1] = '2'; - self->buffer[2] = '3'; - self->buffer[3] = '4'; - return PyBuffer_FillInfo( - view, (PyObject*)self, (void *)self->buffer, 4, 1, flags); -} - -static void -heapctypewithbuffer_releasebuffer(HeapCTypeWithBufferObject *self, Py_buffer *view) -{ - assert(view->obj == (void*) self); -} - -static PyType_Slot HeapCTypeWithBuffer_slots[] = { - {Py_bf_getbuffer, heapctypewithbuffer_getbuffer}, - {Py_bf_releasebuffer, heapctypewithbuffer_releasebuffer}, - {Py_tp_doc, (char*)heapctypewithbuffer__doc__}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeWithBuffer_spec = { - "_testcapi.HeapCTypeWithBuffer", - sizeof(HeapCTypeWithBufferObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeWithBuffer_slots -}; - -PyDoc_STRVAR(heapctypesubclasswithfinalizer__doc__, -"Subclass of HeapCType with a finalizer that reassigns __class__.\n\n" -"__class__ is set to plain HeapCTypeSubclass during finalization.\n" -"__init__ sets the 'value' attribute to 10 and 'value2' to 20."); - -static int -heapctypesubclasswithfinalizer_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyTypeObject *base = (PyTypeObject *)PyType_GetSlot(Py_TYPE(self), Py_tp_base); - initproc base_init = PyType_GetSlot(base, Py_tp_init); - base_init(self, args, kwargs); - return 0; -} - -static void -heapctypesubclasswithfinalizer_finalize(PyObject *self) -{ - PyObject *error_type, *error_value, *error_traceback, *m; - PyObject *oldtype = NULL, *newtype = NULL, *refcnt = NULL; - - /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); - - m = PyState_FindModule(&_testcapimodule); - if (m == NULL) { - goto cleanup_finalize; - } - oldtype = PyObject_GetAttrString(m, "HeapCTypeSubclassWithFinalizer"); - newtype = PyObject_GetAttrString(m, "HeapCTypeSubclass"); - if (oldtype == NULL || newtype == NULL) { - goto cleanup_finalize; - } - - if (PyObject_SetAttrString(self, "__class__", newtype) < 0) { - goto cleanup_finalize; - } - refcnt = PyLong_FromSsize_t(Py_REFCNT(oldtype)); - if (refcnt == NULL) { - goto cleanup_finalize; - } - if (PyObject_SetAttrString(oldtype, "refcnt_in_del", refcnt) < 0) { - goto cleanup_finalize; - } - Py_DECREF(refcnt); - refcnt = PyLong_FromSsize_t(Py_REFCNT(newtype)); - if (refcnt == NULL) { - goto cleanup_finalize; - } - if (PyObject_SetAttrString(newtype, "refcnt_in_del", refcnt) < 0) { - goto cleanup_finalize; - } - -cleanup_finalize: - Py_XDECREF(oldtype); - Py_XDECREF(newtype); - Py_XDECREF(refcnt); - - /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); -} - -static PyType_Slot HeapCTypeSubclassWithFinalizer_slots[] = { - {Py_tp_init, heapctypesubclasswithfinalizer_init}, - {Py_tp_members, heapctypesubclass_members}, - {Py_tp_finalize, heapctypesubclasswithfinalizer_finalize}, - {Py_tp_doc, (char*)heapctypesubclasswithfinalizer__doc__}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeSubclassWithFinalizer_spec = { - "_testcapi.HeapCTypeSubclassWithFinalizer", - sizeof(HeapCTypeSubclassObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE, - HeapCTypeSubclassWithFinalizer_slots -}; - -typedef struct { - PyObject_HEAD - PyObject *dict; -} HeapCTypeWithDictObject; - -static void -heapctypewithdict_dealloc(HeapCTypeWithDictObject* self) -{ - - PyTypeObject *tp = Py_TYPE(self); - Py_XDECREF(self->dict); - PyObject_Free(self); - Py_DECREF(tp); -} - -static PyGetSetDef heapctypewithdict_getsetlist[] = { - {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, - {NULL} /* Sentinel */ -}; - -static struct PyMemberDef heapctypewithdict_members[] = { - {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, - {"__dictoffset__", T_PYSSIZET, offsetof(HeapCTypeWithDictObject, dict), READONLY}, - {NULL} /* Sentinel */ -}; - -static PyType_Slot HeapCTypeWithDict_slots[] = { - {Py_tp_members, heapctypewithdict_members}, - {Py_tp_getset, heapctypewithdict_getsetlist}, - {Py_tp_dealloc, heapctypewithdict_dealloc}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeWithDict_spec = { - "_testcapi.HeapCTypeWithDict", - sizeof(HeapCTypeWithDictObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeWithDict_slots -}; - -static struct PyMemberDef heapctypewithnegativedict_members[] = { - {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, - {"__dictoffset__", T_PYSSIZET, -(Py_ssize_t)sizeof(void*), READONLY}, - {NULL} /* Sentinel */ -}; - -static PyType_Slot HeapCTypeWithNegativeDict_slots[] = { - {Py_tp_members, heapctypewithnegativedict_members}, - {Py_tp_getset, heapctypewithdict_getsetlist}, - {Py_tp_dealloc, heapctypewithdict_dealloc}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeWithNegativeDict_spec = { - "_testcapi.HeapCTypeWithNegativeDict", - sizeof(HeapCTypeWithDictObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeWithNegativeDict_slots -}; - -typedef struct { - PyObject_HEAD - PyObject *weakreflist; -} HeapCTypeWithWeakrefObject; - -static struct PyMemberDef heapctypewithweakref_members[] = { - {"weakreflist", T_OBJECT, offsetof(HeapCTypeWithWeakrefObject, weakreflist)}, - {"__weaklistoffset__", T_PYSSIZET, - offsetof(HeapCTypeWithWeakrefObject, weakreflist), READONLY}, - {NULL} /* Sentinel */ -}; - -static void -heapctypewithweakref_dealloc(HeapCTypeWithWeakrefObject* self) -{ - - PyTypeObject *tp = Py_TYPE(self); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_XDECREF(self->weakreflist); - PyObject_Free(self); - Py_DECREF(tp); -} - -static PyType_Slot HeapCTypeWithWeakref_slots[] = { - {Py_tp_members, heapctypewithweakref_members}, - {Py_tp_dealloc, heapctypewithweakref_dealloc}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeWithWeakref_spec = { - "_testcapi.HeapCTypeWithWeakref", - sizeof(HeapCTypeWithWeakrefObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeWithWeakref_slots -}; - -PyDoc_STRVAR(heapctypesetattr__doc__, -"A heap type without GC, but with overridden __setattr__.\n\n" -"The 'value' attribute is set to 10 in __init__ and updated via attribute setting."); - -typedef struct { - PyObject_HEAD - long value; -} HeapCTypeSetattrObject; - -static struct PyMemberDef heapctypesetattr_members[] = { - {"pvalue", T_LONG, offsetof(HeapCTypeSetattrObject, value)}, - {NULL} /* Sentinel */ -}; - -static int -heapctypesetattr_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - ((HeapCTypeSetattrObject *)self)->value = 10; - return 0; -} - -static void -heapctypesetattr_dealloc(HeapCTypeSetattrObject *self) -{ - PyTypeObject *tp = Py_TYPE(self); - PyObject_Free(self); - Py_DECREF(tp); -} - -static int -heapctypesetattr_setattro(HeapCTypeSetattrObject *self, PyObject *attr, PyObject *value) -{ - PyObject *svalue = PyUnicode_FromString("value"); - if (svalue == NULL) - return -1; - int eq = PyObject_RichCompareBool(svalue, attr, Py_EQ); - Py_DECREF(svalue); - if (eq < 0) - return -1; - if (!eq) { - return PyObject_GenericSetAttr((PyObject*) self, attr, value); - } - if (value == NULL) { - self->value = 0; - return 0; - } - PyObject *ivalue = PyNumber_Long(value); - if (ivalue == NULL) - return -1; - long v = PyLong_AsLong(ivalue); - Py_DECREF(ivalue); - if (v == -1 && PyErr_Occurred()) - return -1; - self->value = v; - return 0; -} - -static PyType_Slot HeapCTypeSetattr_slots[] = { - {Py_tp_init, heapctypesetattr_init}, - {Py_tp_members, heapctypesetattr_members}, - {Py_tp_setattro, heapctypesetattr_setattro}, - {Py_tp_dealloc, heapctypesetattr_dealloc}, - {Py_tp_doc, (char*)heapctypesetattr__doc__}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeSetattr_spec = { - "_testcapi.HeapCTypeSetattr", - sizeof(HeapCTypeSetattrObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeSetattr_slots -}; - static PyMethodDef meth_instance_methods[] = { {"meth_varargs", meth_varargs, METH_VARARGS}, - {"meth_varargs_keywords", (PyCFunction)(void(*)(void))meth_varargs_keywords, METH_VARARGS|METH_KEYWORDS}, + {"meth_varargs_keywords", _PyCFunction_CAST(meth_varargs_keywords), METH_VARARGS|METH_KEYWORDS}, {"meth_o", meth_o, METH_O}, {"meth_noargs", meth_noargs, METH_NOARGS}, - {"meth_fastcall", (PyCFunction)(void(*)(void))meth_fastcall, METH_FASTCALL}, - {"meth_fastcall_keywords", (PyCFunction)(void(*)(void))meth_fastcall_keywords, METH_FASTCALL|METH_KEYWORDS}, + {"meth_fastcall", _PyCFunction_CAST(meth_fastcall), METH_FASTCALL}, + {"meth_fastcall_keywords", _PyCFunction_CAST(meth_fastcall_keywords), METH_FASTCALL|METH_KEYWORDS}, {NULL, NULL} /* sentinel */ }; @@ -7303,11 +3831,11 @@ static PyTypeObject MethInstance_Type = { static PyMethodDef meth_class_methods[] = { {"meth_varargs", meth_varargs, METH_VARARGS|METH_CLASS}, - {"meth_varargs_keywords", (PyCFunction)(void(*)(void))meth_varargs_keywords, METH_VARARGS|METH_KEYWORDS|METH_CLASS}, + {"meth_varargs_keywords", _PyCFunction_CAST(meth_varargs_keywords), METH_VARARGS|METH_KEYWORDS|METH_CLASS}, {"meth_o", meth_o, METH_O|METH_CLASS}, {"meth_noargs", meth_noargs, METH_NOARGS|METH_CLASS}, - {"meth_fastcall", (PyCFunction)(void(*)(void))meth_fastcall, METH_FASTCALL|METH_CLASS}, - {"meth_fastcall_keywords", (PyCFunction)(void(*)(void))meth_fastcall_keywords, METH_FASTCALL|METH_KEYWORDS|METH_CLASS}, + {"meth_fastcall", _PyCFunction_CAST(meth_fastcall), METH_FASTCALL|METH_CLASS}, + {"meth_fastcall_keywords", _PyCFunction_CAST(meth_fastcall_keywords), METH_FASTCALL|METH_KEYWORDS|METH_CLASS}, {NULL, NULL} /* sentinel */ }; @@ -7325,11 +3853,11 @@ static PyTypeObject MethClass_Type = { static PyMethodDef meth_static_methods[] = { {"meth_varargs", meth_varargs, METH_VARARGS|METH_STATIC}, - {"meth_varargs_keywords", (PyCFunction)(void(*)(void))meth_varargs_keywords, METH_VARARGS|METH_KEYWORDS|METH_STATIC}, + {"meth_varargs_keywords", _PyCFunction_CAST(meth_varargs_keywords), METH_VARARGS|METH_KEYWORDS|METH_STATIC}, {"meth_o", meth_o, METH_O|METH_STATIC}, {"meth_noargs", meth_noargs, METH_NOARGS|METH_STATIC}, - {"meth_fastcall", (PyCFunction)(void(*)(void))meth_fastcall, METH_FASTCALL|METH_STATIC}, - {"meth_fastcall_keywords", (PyCFunction)(void(*)(void))meth_fastcall_keywords, METH_FASTCALL|METH_KEYWORDS|METH_STATIC}, + {"meth_fastcall", _PyCFunction_CAST(meth_fastcall), METH_FASTCALL|METH_STATIC}, + {"meth_fastcall_keywords", _PyCFunction_CAST(meth_fastcall_keywords), METH_FASTCALL|METH_KEYWORDS|METH_STATIC}, {NULL, NULL} /* sentinel */ }; @@ -7419,11 +3947,6 @@ PyInit__testcapi(void) Py_SET_TYPE(&_HashInheritanceTester_Type, &PyType_Type); - Py_SET_TYPE(&test_structmembersType, &PyType_Type); - Py_INCREF(&test_structmembersType); - /* don't use a name starting with "test", since we don't want - test_capi to automatically call this */ - PyModule_AddObject(m, "_test_structmembersType", (PyObject *)&test_structmembersType); if (PyType_Ready(&matmulType) < 0) return NULL; Py_INCREF(&matmulType); @@ -7445,29 +3968,6 @@ PyInit__testcapi(void) Py_INCREF(&MyList_Type); PyModule_AddObject(m, "MyList", (PyObject *)&MyList_Type); - if (PyType_Ready(&MethodDescriptorBase_Type) < 0) - return NULL; - Py_INCREF(&MethodDescriptorBase_Type); - PyModule_AddObject(m, "MethodDescriptorBase", (PyObject *)&MethodDescriptorBase_Type); - - MethodDescriptorDerived_Type.tp_base = &MethodDescriptorBase_Type; - if (PyType_Ready(&MethodDescriptorDerived_Type) < 0) - return NULL; - Py_INCREF(&MethodDescriptorDerived_Type); - PyModule_AddObject(m, "MethodDescriptorDerived", (PyObject *)&MethodDescriptorDerived_Type); - - MethodDescriptorNopGet_Type.tp_base = &MethodDescriptorBase_Type; - if (PyType_Ready(&MethodDescriptorNopGet_Type) < 0) - return NULL; - Py_INCREF(&MethodDescriptorNopGet_Type); - PyModule_AddObject(m, "MethodDescriptorNopGet", (PyObject *)&MethodDescriptorNopGet_Type); - - MethodDescriptor2_Type.tp_base = &MethodDescriptorBase_Type; - if (PyType_Ready(&MethodDescriptor2_Type) < 0) - return NULL; - Py_INCREF(&MethodDescriptor2_Type); - PyModule_AddObject(m, "MethodDescriptor2", (PyObject *)&MethodDescriptor2_Type); - if (PyType_Ready(&GenericAlias_Type) < 0) return NULL; Py_INCREF(&GenericAlias_Type); @@ -7523,100 +4023,16 @@ PyInit__testcapi(void) PyModule_AddObject(m, "PY_SSIZE_T_MAX", PyLong_FromSsize_t(PY_SSIZE_T_MAX)); PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyLong_FromSsize_t(PY_SSIZE_T_MIN)); PyModule_AddObject(m, "SIZEOF_TIME_T", PyLong_FromSsize_t(sizeof(time_t))); + PyModule_AddObject(m, "Py_Version", PyLong_FromUnsignedLong(Py_Version)); Py_INCREF(&PyInstanceMethod_Type); PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type); PyModule_AddIntConstant(m, "the_number_three", 3); - PyObject *v; -#ifdef WITH_PYMALLOC - v = Py_True; -#else - v = Py_False; -#endif - Py_INCREF(v); - PyModule_AddObject(m, "WITH_PYMALLOC", v); TestError = PyErr_NewException("_testcapi.error", NULL, NULL); Py_INCREF(TestError); PyModule_AddObject(m, "error", TestError); - PyObject *HeapDocCType = PyType_FromSpec(&HeapDocCType_spec); - if (HeapDocCType == NULL) { - return NULL; - } - PyModule_AddObject(m, "HeapDocCType", HeapDocCType); - - /* bpo-41832: Add a new type to test PyType_FromSpec() - now can accept a NULL tp_doc slot. */ - PyObject *NullTpDocType = PyType_FromSpec(&NullTpDocType_spec); - if (NullTpDocType == NULL) { - return NULL; - } - PyModule_AddObject(m, "NullTpDocType", NullTpDocType); - - PyObject *HeapGcCType = PyType_FromSpec(&HeapGcCType_spec); - if (HeapGcCType == NULL) { - return NULL; - } - PyModule_AddObject(m, "HeapGcCType", HeapGcCType); - - PyObject *HeapCType = PyType_FromSpec(&HeapCType_spec); - if (HeapCType == NULL) { - return NULL; - } - PyObject *subclass_bases = PyTuple_Pack(1, HeapCType); - if (subclass_bases == NULL) { - return NULL; - } - PyObject *HeapCTypeSubclass = PyType_FromSpecWithBases(&HeapCTypeSubclass_spec, subclass_bases); - if (HeapCTypeSubclass == NULL) { - return NULL; - } - Py_DECREF(subclass_bases); - PyModule_AddObject(m, "HeapCTypeSubclass", HeapCTypeSubclass); - - PyObject *HeapCTypeWithDict = PyType_FromSpec(&HeapCTypeWithDict_spec); - if (HeapCTypeWithDict == NULL) { - return NULL; - } - PyModule_AddObject(m, "HeapCTypeWithDict", HeapCTypeWithDict); - - PyObject *HeapCTypeWithNegativeDict = PyType_FromSpec(&HeapCTypeWithNegativeDict_spec); - if (HeapCTypeWithNegativeDict == NULL) { - return NULL; - } - PyModule_AddObject(m, "HeapCTypeWithNegativeDict", HeapCTypeWithNegativeDict); - - PyObject *HeapCTypeWithWeakref = PyType_FromSpec(&HeapCTypeWithWeakref_spec); - if (HeapCTypeWithWeakref == NULL) { - return NULL; - } - PyModule_AddObject(m, "HeapCTypeWithWeakref", HeapCTypeWithWeakref); - - PyObject *HeapCTypeWithBuffer = PyType_FromSpec(&HeapCTypeWithBuffer_spec); - if (HeapCTypeWithBuffer == NULL) { - return NULL; - } - PyModule_AddObject(m, "HeapCTypeWithBuffer", HeapCTypeWithBuffer); - - PyObject *HeapCTypeSetattr = PyType_FromSpec(&HeapCTypeSetattr_spec); - if (HeapCTypeSetattr == NULL) { - return NULL; - } - PyModule_AddObject(m, "HeapCTypeSetattr", HeapCTypeSetattr); - - PyObject *subclass_with_finalizer_bases = PyTuple_Pack(1, HeapCTypeSubclass); - if (subclass_with_finalizer_bases == NULL) { - return NULL; - } - PyObject *HeapCTypeSubclassWithFinalizer = PyType_FromSpecWithBases( - &HeapCTypeSubclassWithFinalizer_spec, subclass_with_finalizer_bases); - if (HeapCTypeSubclassWithFinalizer == NULL) { - return NULL; - } - Py_DECREF(subclass_with_finalizer_bases); - PyModule_AddObject(m, "HeapCTypeSubclassWithFinalizer", HeapCTypeSubclassWithFinalizer); - if (PyType_Ready(&ContainerNoGC_type) < 0) { return NULL; } @@ -7625,11 +4041,57 @@ PyInit__testcapi(void) (PyObject *) &ContainerNoGC_type) < 0) return NULL; + /* Include tests from the _testcapi/ directory */ + if (_PyTestCapi_Init_Vectorcall(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Heaptype(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Unicode(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_GetArgs(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_PyTime(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_DateTime(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Docstring(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Mem(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Watchers(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Long(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Float(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Structmember(m) < 0) { + return NULL; + } + +#ifndef LIMITED_API_AVAILABLE + PyModule_AddObjectRef(m, "LIMITED_API_AVAILABLE", Py_False); +#else + PyModule_AddObjectRef(m, "LIMITED_API_AVAILABLE", Py_True); + if (_PyTestCapi_Init_VectorcallLimited(m) < 0) { + return NULL; + } +#endif + PyState_AddModule(m, &_testcapimodule); return m; } - /* Test the C API exposed when PY_SSIZE_T_CLEAN is not defined */ #undef Py_BuildValue @@ -7671,22 +4133,5 @@ test_buildvalue_issue38913(PyObject *self, PyObject *Py_UNUSED(ignored)) } PyErr_Clear(); - - Py_RETURN_NONE; -} - -#undef PyArg_ParseTupleAndKeywords -PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, - const char *, char **, ...); - -static PyObject * -getargs_s_hash_int(PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *keywords[] = {"", "x", NULL}; - const char *s; - int len; - int i = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s#i", keywords, &s, &len, &i)) - return NULL; Py_RETURN_NONE; } diff --git a/Modules/_testclinic.c b/Modules/_testclinic.c new file mode 100644 index 00000000000..91fdee24d32 --- /dev/null +++ b/Modules/_testclinic.c @@ -0,0 +1,1187 @@ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + +/* Always enable assertions */ +#undef NDEBUG + +#define PY_SSIZE_T_CLEAN + +#include "Python.h" + +#include "clinic/_testclinic.c.h" + + +/* Pack arguments to a tuple, implicitly increase all the arguments' refcount. + * NULL arguments will be replaced to Py_None. */ +static PyObject * +pack_arguments_newref(int argc, ...) +{ + assert(!PyErr_Occurred()); + PyObject *tuple = PyTuple_New(argc); + if (!tuple) { + return NULL; + } + + va_list vargs; + va_start(vargs, argc); + for (int i = 0; i < argc; i++) { + PyObject *arg = va_arg(vargs, PyObject *); + if (arg) { + if (_PyObject_IsFreed(arg)) { + PyErr_Format(PyExc_AssertionError, + "argument %d at %p is freed or corrupted!", + i, arg); + va_end(vargs); + Py_DECREF(tuple); + return NULL; + } + } + else { + arg = Py_None; + } + PyTuple_SET_ITEM(tuple, i, Py_NewRef(arg)); + } + va_end(vargs); + return tuple; +} + +/* Pack arguments to a tuple. + * `wrapper` is function which converts primitive type to PyObject. + * `arg_type` is type that arguments should be converted to before wrapped. */ +#define RETURN_PACKED_ARGS(argc, wrapper, arg_type, ...) do { \ + assert(!PyErr_Occurred()); \ + arg_type in[argc] = {__VA_ARGS__}; \ + PyObject *out[argc] = {NULL,}; \ + for (int _i = 0; _i < argc; _i++) { \ + out[_i] = wrapper(in[_i]); \ + assert(out[_i] || PyErr_Occurred()); \ + if (!out[_i]) { \ + for (int _j = 0; _j < _i; _j++) { \ + Py_DECREF(out[_j]); \ + } \ + return NULL; \ + } \ + } \ + PyObject *tuple = PyTuple_New(argc); \ + if (!tuple) { \ + for (int _i = 0; _i < argc; _i++) { \ + Py_DECREF(out[_i]); \ + } \ + return NULL; \ + } \ + for (int _i = 0; _i < argc; _i++) { \ + PyTuple_SET_ITEM(tuple, _i, out[_i]); \ + } \ + return tuple; \ + } while (0) + + +/*[clinic input] +module _testclinic +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d4981b80d6efdb12]*/ + + +/*[clinic input] +test_empty_function + +[clinic start generated code]*/ + +static PyObject * +test_empty_function_impl(PyObject *module) +/*[clinic end generated code: output=0f8aeb3ddced55cb input=0dd7048651ad4ae4]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +objects_converter + + a: object + b: object = NULL + / + +[clinic start generated code]*/ + +static PyObject * +objects_converter_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=3f9c9415ec86c695 input=1533b1bd94187de4]*/ +{ + return pack_arguments_newref(2, a, b); +} + + +/*[clinic input] +bytes_object_converter + + a: PyBytesObject + / + +[clinic start generated code]*/ + +static PyObject * +bytes_object_converter_impl(PyObject *module, PyBytesObject *a) +/*[clinic end generated code: output=7732da869d74b784 input=94211751e7996236]*/ +{ + if (!PyBytes_Check(a)) { + PyErr_SetString(PyExc_AssertionError, + "argument a is not a PyBytesObject"); + return NULL; + } + return pack_arguments_newref(1, a); +} + + +/*[clinic input] +byte_array_object_converter + + a: PyByteArrayObject + / + +[clinic start generated code]*/ + +static PyObject * +byte_array_object_converter_impl(PyObject *module, PyByteArrayObject *a) +/*[clinic end generated code: output=51f15c76f302b1f7 input=b04d253db51c6f56]*/ +{ + if (!PyByteArray_Check(a)) { + PyErr_SetString(PyExc_AssertionError, + "argument a is not a PyByteArrayObject"); + return NULL; + } + return pack_arguments_newref(1, a); +} + + +/*[clinic input] +unicode_converter + + a: unicode + / + +[clinic start generated code]*/ + +static PyObject * +unicode_converter_impl(PyObject *module, PyObject *a) +/*[clinic end generated code: output=1b4a4adbb6ac6e34 input=de7b5adbf07435ba]*/ +{ + if (!PyUnicode_Check(a)) { + PyErr_SetString(PyExc_AssertionError, + "argument a is not a unicode object"); + return NULL; + } + return pack_arguments_newref(1, a); +} + + +/*[clinic input] +bool_converter + + a: bool = True + b: bool(accept={object}) = True + c: bool(accept={int}) = True + / + +[clinic start generated code]*/ + +static PyObject * +bool_converter_impl(PyObject *module, int a, int b, int c) +/*[clinic end generated code: output=17005b0c29afd590 input=7f6537705b2f32f4]*/ +{ + PyObject *obj_a = a ? Py_True : Py_False; + PyObject *obj_b = b ? Py_True : Py_False; + PyObject *obj_c = c ? Py_True : Py_False; + return pack_arguments_newref(3, obj_a, obj_b, obj_c); +} + + +/*[clinic input] +char_converter + + a: char = b'A' + b: char = b'\a' + c: char = b'\b' + d: char = b'\t' + e: char = b'\n' + f: char = b'\v' + g: char = b'\f' + h: char = b'\r' + i: char = b'"' + j: char = b"'" + k: char = b'?' + l: char = b'\\' + m: char = b'\000' + n: char = b'\377' + / + +[clinic start generated code]*/ + +static PyObject * +char_converter_impl(PyObject *module, char a, char b, char c, char d, char e, + char f, char g, char h, char i, char j, char k, char l, + char m, char n) +/*[clinic end generated code: output=f929dbd2e55a9871 input=b601bc5bc7fe85e3]*/ +{ + RETURN_PACKED_ARGS(14, PyLong_FromUnsignedLong, unsigned char, + a, b, c, d, e, f, g, h, i, j, k, l, m, n); +} + + +/*[clinic input] +unsigned_char_converter + + a: unsigned_char = 12 + b: unsigned_char(bitwise=False) = 34 + c: unsigned_char(bitwise=True) = 56 + / + +[clinic start generated code]*/ + +static PyObject * +unsigned_char_converter_impl(PyObject *module, unsigned char a, + unsigned char b, unsigned char c) +/*[clinic end generated code: output=490af3b39ce0b199 input=e859502fbe0b3185]*/ +{ + RETURN_PACKED_ARGS(3, PyLong_FromUnsignedLong, unsigned char, a, b, c); +} + + +/*[clinic input] +short_converter + + a: short = 12 + / + +[clinic start generated code]*/ + +static PyObject * +short_converter_impl(PyObject *module, short a) +/*[clinic end generated code: output=1ebb7ddb64248988 input=b4e2309a66f650ae]*/ +{ + RETURN_PACKED_ARGS(1, PyLong_FromLong, long, a); +} + + +/*[clinic input] +unsigned_short_converter + + a: unsigned_short = 12 + b: unsigned_short(bitwise=False) = 34 + c: unsigned_short(bitwise=True) = 56 + / + +[clinic start generated code]*/ + +static PyObject * +unsigned_short_converter_impl(PyObject *module, unsigned short a, + unsigned short b, unsigned short c) +/*[clinic end generated code: output=5f92cc72fc8707a7 input=9d15cd11e741d0c6]*/ +{ + RETURN_PACKED_ARGS(3, PyLong_FromUnsignedLong, unsigned long, a, b, c); +} + + +/*[clinic input] +int_converter + + a: int = 12 + b: int(accept={int}) = 34 + c: int(accept={str}) = 45 + / + +[clinic start generated code]*/ + +static PyObject * +int_converter_impl(PyObject *module, int a, int b, int c) +/*[clinic end generated code: output=8e56b59be7d0c306 input=a1dbc6344853db7a]*/ +{ + RETURN_PACKED_ARGS(3, PyLong_FromLong, long, a, b, c); +} + + +/*[clinic input] +unsigned_int_converter + + a: unsigned_int = 12 + b: unsigned_int(bitwise=False) = 34 + c: unsigned_int(bitwise=True) = 56 + / + +[clinic start generated code]*/ + +static PyObject * +unsigned_int_converter_impl(PyObject *module, unsigned int a, unsigned int b, + unsigned int c) +/*[clinic end generated code: output=399a57a05c494cc7 input=8427ed9a3f96272d]*/ +{ + RETURN_PACKED_ARGS(3, PyLong_FromUnsignedLong, unsigned long, a, b, c); +} + + +/*[clinic input] +long_converter + + a: long = 12 + / + +[clinic start generated code]*/ + +static PyObject * +long_converter_impl(PyObject *module, long a) +/*[clinic end generated code: output=9663d936a652707a input=84ad0ef28f24bd85]*/ +{ + RETURN_PACKED_ARGS(1, PyLong_FromLong, long, a); +} + + +/*[clinic input] +unsigned_long_converter + + a: unsigned_long = 12 + b: unsigned_long(bitwise=False) = 34 + c: unsigned_long(bitwise=True) = 56 + / + +[clinic start generated code]*/ + +static PyObject * +unsigned_long_converter_impl(PyObject *module, unsigned long a, + unsigned long b, unsigned long c) +/*[clinic end generated code: output=120b82ea9ebd93a8 input=440dd6f1817f5d91]*/ +{ + RETURN_PACKED_ARGS(3, PyLong_FromUnsignedLong, unsigned long, a, b, c); +} + + +/*[clinic input] +long_long_converter + + a: long_long = 12 + / + +[clinic start generated code]*/ + +static PyObject * +long_long_converter_impl(PyObject *module, long long a) +/*[clinic end generated code: output=5fb5f2220770c3e1 input=730fcb3eecf4d993]*/ +{ + RETURN_PACKED_ARGS(1, PyLong_FromLongLong, long long, a); +} + + +/*[clinic input] +unsigned_long_long_converter + + a: unsigned_long_long = 12 + b: unsigned_long_long(bitwise=False) = 34 + c: unsigned_long_long(bitwise=True) = 56 + / + +[clinic start generated code]*/ + +static PyObject * +unsigned_long_long_converter_impl(PyObject *module, unsigned long long a, + unsigned long long b, unsigned long long c) +/*[clinic end generated code: output=65b7273e63501762 input=300737b0bdb230e9]*/ +{ + RETURN_PACKED_ARGS(3, PyLong_FromUnsignedLongLong, unsigned long long, + a, b, c); +} + + +/*[clinic input] +py_ssize_t_converter + + a: Py_ssize_t = 12 + b: Py_ssize_t(accept={int}) = 34 + c: Py_ssize_t(accept={int, NoneType}) = 56 + / + +[clinic start generated code]*/ + +static PyObject * +py_ssize_t_converter_impl(PyObject *module, Py_ssize_t a, Py_ssize_t b, + Py_ssize_t c) +/*[clinic end generated code: output=ce252143e0ed0372 input=76d0f342e9317a1f]*/ +{ + RETURN_PACKED_ARGS(3, PyLong_FromSsize_t, Py_ssize_t, a, b, c); +} + + +/*[clinic input] +slice_index_converter + + a: slice_index = 12 + b: slice_index(accept={int}) = 34 + c: slice_index(accept={int, NoneType}) = 56 + / + +[clinic start generated code]*/ + +static PyObject * +slice_index_converter_impl(PyObject *module, Py_ssize_t a, Py_ssize_t b, + Py_ssize_t c) +/*[clinic end generated code: output=923c6cac77666a6b input=64f99f3f83265e47]*/ +{ + RETURN_PACKED_ARGS(3, PyLong_FromSsize_t, Py_ssize_t, a, b, c); +} + + +/*[clinic input] +size_t_converter + + a: size_t = 12 + / + +[clinic start generated code]*/ + +static PyObject * +size_t_converter_impl(PyObject *module, size_t a) +/*[clinic end generated code: output=412b5b7334ab444d input=83ae7d9171fbf208]*/ +{ + RETURN_PACKED_ARGS(1, PyLong_FromSize_t, size_t, a); +} + + +/*[clinic input] +float_converter + + a: float = 12.5 + / + +[clinic start generated code]*/ + +static PyObject * +float_converter_impl(PyObject *module, float a) +/*[clinic end generated code: output=1c98f64f2cf1d55c input=a625b59ad68047d8]*/ +{ + RETURN_PACKED_ARGS(1, PyFloat_FromDouble, double, a); +} + + +/*[clinic input] +double_converter + + a: double = 12.5 + / + +[clinic start generated code]*/ + +static PyObject * +double_converter_impl(PyObject *module, double a) +/*[clinic end generated code: output=a4e8532d284d035d input=098df188f24e7c62]*/ +{ + RETURN_PACKED_ARGS(1, PyFloat_FromDouble, double, a); +} + + +/*[clinic input] +py_complex_converter + + a: Py_complex + / + +[clinic start generated code]*/ + +static PyObject * +py_complex_converter_impl(PyObject *module, Py_complex a) +/*[clinic end generated code: output=9e6ca2eb53b14846 input=e9148a8ca1dbf195]*/ +{ + RETURN_PACKED_ARGS(1, PyComplex_FromCComplex, Py_complex, a); +} + + +/*[clinic input] +str_converter + + a: str = "a" + b: str(accept={robuffer}) = "b" + c: str(accept={robuffer, str}, zeroes=True) = "c" + / + +[clinic start generated code]*/ + +static PyObject * +str_converter_impl(PyObject *module, const char *a, const char *b, + const char *c, Py_ssize_t c_length) +/*[clinic end generated code: output=475bea40548c8cd6 input=bff2656c92ee25de]*/ +{ + assert(!PyErr_Occurred()); + PyObject *out[3] = {NULL,}; + int i = 0; + PyObject *arg; + + arg = PyUnicode_FromString(a); + assert(arg || PyErr_Occurred()); + if (!arg) { + goto error; + } + out[i++] = arg; + + arg = PyUnicode_FromString(b); + assert(arg || PyErr_Occurred()); + if (!arg) { + goto error; + } + out[i++] = arg; + + arg = PyUnicode_FromStringAndSize(c, c_length); + assert(arg || PyErr_Occurred()); + if (!arg) { + goto error; + } + out[i++] = arg; + + PyObject *tuple = PyTuple_New(3); + if (!tuple) { + goto error; + } + for (int j = 0; j < 3; j++) { + PyTuple_SET_ITEM(tuple, j, out[j]); + } + return tuple; + +error: + for (int j = 0; j < i; j++) { + Py_DECREF(out[j]); + } + return NULL; +} + + +/*[clinic input] +str_converter_encoding + + a: str(encoding="idna") + b: str(encoding="idna", accept={bytes, bytearray, str}) + c: str(encoding="idna", accept={bytes, bytearray, str}, zeroes=True) + / + +[clinic start generated code]*/ + +static PyObject * +str_converter_encoding_impl(PyObject *module, char *a, char *b, char *c, + Py_ssize_t c_length) +/*[clinic end generated code: output=af68766049248a1c input=0c5cf5159d0e870d]*/ +{ + assert(!PyErr_Occurred()); + PyObject *out[3] = {NULL,}; + int i = 0; + PyObject *arg; + + arg = PyUnicode_FromString(a); + assert(arg || PyErr_Occurred()); + if (!arg) { + goto error; + } + out[i++] = arg; + + arg = PyUnicode_FromString(b); + assert(arg || PyErr_Occurred()); + if (!arg) { + goto error; + } + out[i++] = arg; + + arg = PyUnicode_FromStringAndSize(c, c_length); + assert(arg || PyErr_Occurred()); + if (!arg) { + goto error; + } + out[i++] = arg; + + PyObject *tuple = PyTuple_New(3); + if (!tuple) { + goto error; + } + for (int j = 0; j < 3; j++) { + PyTuple_SET_ITEM(tuple, j, out[j]); + } + return tuple; + +error: + for (int j = 0; j < i; j++) { + Py_DECREF(out[j]); + } + return NULL; +} + + +static PyObject * +bytes_from_buffer(Py_buffer *buf) +{ + PyObject *bytes_obj = PyBytes_FromStringAndSize(NULL, buf->len); + if (!bytes_obj) { + return NULL; + } + void *bytes_obj_buf = ((PyBytesObject *)bytes_obj)->ob_sval; + if (PyBuffer_ToContiguous(bytes_obj_buf, buf, buf->len, 'C') < 0) { + Py_DECREF(bytes_obj); + return NULL; + } + return bytes_obj; +} + +/*[clinic input] +py_buffer_converter + + a: Py_buffer(accept={str, buffer, NoneType}) + b: Py_buffer(accept={rwbuffer}) + / + +[clinic start generated code]*/ + +static PyObject * +py_buffer_converter_impl(PyObject *module, Py_buffer *a, Py_buffer *b) +/*[clinic end generated code: output=52fb13311e3d6d03 input=775de727de5c7421]*/ +{ + RETURN_PACKED_ARGS(2, bytes_from_buffer, Py_buffer *, a, b); +} + + +/*[clinic input] +keywords + + a: object + b: object + +[clinic start generated code]*/ + +static PyObject * +keywords_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=850aaed53e26729e input=f44b89e718c1a93b]*/ +{ + return pack_arguments_newref(2, a, b); +} + + +/*[clinic input] +keywords_kwonly + + a: object + * + b: object + +[clinic start generated code]*/ + +static PyObject * +keywords_kwonly_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=a45c48241da584dc input=1f08e39c3312b015]*/ +{ + return pack_arguments_newref(2, a, b); +} + + +/*[clinic input] +keywords_opt + + a: object + b: object = None + c: object = None + +[clinic start generated code]*/ + +static PyObject * +keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) +/*[clinic end generated code: output=25e4b67d91c76a66 input=b0ba0e4f04904556]*/ +{ + return pack_arguments_newref(3, a, b, c); +} + + +/*[clinic input] +keywords_opt_kwonly + + a: object + b: object = None + * + c: object = None + d: object = None + +[clinic start generated code]*/ + +static PyObject * +keywords_opt_kwonly_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d) +/*[clinic end generated code: output=6aa5b655a6e9aeb0 input=f79da689d6c51076]*/ +{ + return pack_arguments_newref(4, a, b, c, d); +} + + +/*[clinic input] +keywords_kwonly_opt + + a: object + * + b: object = None + c: object = None + +[clinic start generated code]*/ + +static PyObject * +keywords_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c) +/*[clinic end generated code: output=707f78eb0f55c2b1 input=e0fa1a0e46dca791]*/ +{ + return pack_arguments_newref(3, a, b, c); +} + + +/*[clinic input] +posonly_keywords + + a: object + / + b: object + +[clinic start generated code]*/ + +static PyObject * +posonly_keywords_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=6ac88f4a5f0bfc8d input=fde0a2f79fe82b06]*/ +{ + return pack_arguments_newref(2, a, b); +} + + +/*[clinic input] +posonly_kwonly + + a: object + / + * + b: object + +[clinic start generated code]*/ + +static PyObject * +posonly_kwonly_impl(PyObject *module, PyObject *a, PyObject *b) +/*[clinic end generated code: output=483e6790d3482185 input=78b3712768da9a19]*/ +{ + return pack_arguments_newref(2, a, b); +} + + +/*[clinic input] +posonly_keywords_kwonly + + a: object + / + b: object + * + c: object + +[clinic start generated code]*/ + +static PyObject * +posonly_keywords_kwonly_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c) +/*[clinic end generated code: output=2fae573e8cc3fad8 input=a1ad5d2295eb803c]*/ +{ + return pack_arguments_newref(3, a, b, c); +} + + +/*[clinic input] +posonly_keywords_opt + + a: object + / + b: object + c: object = None + d: object = None + +[clinic start generated code]*/ + +static PyObject * +posonly_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d) +/*[clinic end generated code: output=f5eb66241bcf68fb input=51c10de2a120e279]*/ +{ + return pack_arguments_newref(4, a, b, c, d); +} + + +/*[clinic input] +posonly_opt_keywords_opt + + a: object + b: object = None + / + c: object = None + d: object = None + +[clinic start generated code]*/ + +static PyObject * +posonly_opt_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d) +/*[clinic end generated code: output=d54a30e549296ffd input=f408a1de7dfaf31f]*/ +{ + return pack_arguments_newref(4, a, b, c, d); +} + + +/*[clinic input] +posonly_kwonly_opt + + a: object + / + * + b: object + c: object = None + d: object = None + +[clinic start generated code]*/ + +static PyObject * +posonly_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d) +/*[clinic end generated code: output=a20503fe36b4fd62 input=3494253975272f52]*/ +{ + return pack_arguments_newref(4, a, b, c, d); +} + + +/*[clinic input] +posonly_opt_kwonly_opt + + a: object + b: object = None + / + * + c: object = None + d: object = None + +[clinic start generated code]*/ + +static PyObject * +posonly_opt_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d) +/*[clinic end generated code: output=64f3204a3a0413b6 input=d17516581e478412]*/ +{ + return pack_arguments_newref(4, a, b, c, d); +} + + +/*[clinic input] +posonly_keywords_kwonly_opt + + a: object + / + b: object + * + c: object + d: object = None + e: object = None + +[clinic start generated code]*/ + +static PyObject * +posonly_keywords_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d, PyObject *e) +/*[clinic end generated code: output=dbd7e7ddd6257fa0 input=33529f29e97e5adb]*/ +{ + return pack_arguments_newref(5, a, b, c, d, e); +} + + +/*[clinic input] +posonly_keywords_opt_kwonly_opt + + a: object + / + b: object + c: object = None + * + d: object = None + e: object = None + +[clinic start generated code]*/ + +static PyObject * +posonly_keywords_opt_kwonly_opt_impl(PyObject *module, PyObject *a, + PyObject *b, PyObject *c, PyObject *d, + PyObject *e) +/*[clinic end generated code: output=775d12ae44653045 input=4d4cc62f11441301]*/ +{ + return pack_arguments_newref(5, a, b, c, d, e); +} + + +/*[clinic input] +posonly_opt_keywords_opt_kwonly_opt + + a: object + b: object = None + / + c: object = None + * + d: object = None + +[clinic start generated code]*/ + +static PyObject * +posonly_opt_keywords_opt_kwonly_opt_impl(PyObject *module, PyObject *a, + PyObject *b, PyObject *c, + PyObject *d) +/*[clinic end generated code: output=40c6dc422591eade input=3964960a68622431]*/ +{ + return pack_arguments_newref(4, a, b, c, d); +} + + +/*[clinic input] +keyword_only_parameter + + * + a: object + +[clinic start generated code]*/ + +static PyObject * +keyword_only_parameter_impl(PyObject *module, PyObject *a) +/*[clinic end generated code: output=c454b6ce98232787 input=8d2868b8d0b27bdb]*/ +{ + return pack_arguments_newref(1, a); +} + + +/*[clinic input] +posonly_vararg + + a: object + / + b: object + *args: object + +[clinic start generated code]*/ + +static PyObject * +posonly_vararg_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *args) +/*[clinic end generated code: output=ee6713acda6b954e input=783427fe7ec2b67a]*/ +{ + return pack_arguments_newref(3, a, b, args); +} + + +/*[clinic input] +vararg_and_posonly + + a: object + *args: object + / + +[clinic start generated code]*/ + +static PyObject * +vararg_and_posonly_impl(PyObject *module, PyObject *a, PyObject *args) +/*[clinic end generated code: output=42792f799465a14d input=defe017b19ba52e8]*/ +{ + return pack_arguments_newref(2, a, args); +} + + +/*[clinic input] +vararg + + a: object + *args: object + +[clinic start generated code]*/ + +static PyObject * +vararg_impl(PyObject *module, PyObject *a, PyObject *args) +/*[clinic end generated code: output=91ab7a0efc52dd5e input=02c0f772d05f591e]*/ +{ + return pack_arguments_newref(2, a, args); +} + + +/*[clinic input] +vararg_with_default + + a: object + *args: object + b: bool = False + +[clinic start generated code]*/ + +static PyObject * +vararg_with_default_impl(PyObject *module, PyObject *a, PyObject *args, + int b) +/*[clinic end generated code: output=182c01035958ce92 input=68cafa6a79f89e36]*/ +{ + PyObject *obj_b = b ? Py_True : Py_False; + return pack_arguments_newref(3, a, args, obj_b); +} + + +/*[clinic input] +vararg_with_only_defaults + + *args: object + b: object = None + +[clinic start generated code]*/ + +static PyObject * +vararg_with_only_defaults_impl(PyObject *module, PyObject *args, PyObject *b) +/*[clinic end generated code: output=c06b1826d91f2f7b input=678c069bc67550e1]*/ +{ + return pack_arguments_newref(2, args, b); +} + + + +/*[clinic input] +gh_32092_oob + + pos1: object + pos2: object + *varargs: object + kw1: object = None + kw2: object = None + +Proof-of-concept of GH-32092 OOB bug. + +[clinic start generated code]*/ + +static PyObject * +gh_32092_oob_impl(PyObject *module, PyObject *pos1, PyObject *pos2, + PyObject *varargs, PyObject *kw1, PyObject *kw2) +/*[clinic end generated code: output=ee259c130054653f input=46d15c881608f8ff]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +gh_32092_kw_pass + + pos: object + *args: object + kw: object = None + +Proof-of-concept of GH-32092 keyword args passing bug. + +[clinic start generated code]*/ + +static PyObject * +gh_32092_kw_pass_impl(PyObject *module, PyObject *pos, PyObject *args, + PyObject *kw) +/*[clinic end generated code: output=4a2bbe4f7c8604e9 input=5c0bd5b9079a0cce]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +gh_99233_refcount + + *args: object + / + +Proof-of-concept of GH-99233 refcount error bug. + +[clinic start generated code]*/ + +static PyObject * +gh_99233_refcount_impl(PyObject *module, PyObject *args) +/*[clinic end generated code: output=585855abfbca9a7f input=85f5fb47ac91a626]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +gh_99240_double_free + + a: str(encoding="idna") + b: str(encoding="idna") + / + +Proof-of-concept of GH-99240 double-free bug. + +[clinic start generated code]*/ + +static PyObject * +gh_99240_double_free_impl(PyObject *module, char *a, char *b) +/*[clinic end generated code: output=586dc714992fe2ed input=23db44aa91870fc7]*/ +{ + Py_RETURN_NONE; +} + + +static PyMethodDef tester_methods[] = { + TEST_EMPTY_FUNCTION_METHODDEF + OBJECTS_CONVERTER_METHODDEF + BYTES_OBJECT_CONVERTER_METHODDEF + BYTE_ARRAY_OBJECT_CONVERTER_METHODDEF + UNICODE_CONVERTER_METHODDEF + BOOL_CONVERTER_METHODDEF + CHAR_CONVERTER_METHODDEF + UNSIGNED_CHAR_CONVERTER_METHODDEF + SHORT_CONVERTER_METHODDEF + UNSIGNED_SHORT_CONVERTER_METHODDEF + INT_CONVERTER_METHODDEF + UNSIGNED_INT_CONVERTER_METHODDEF + LONG_CONVERTER_METHODDEF + UNSIGNED_LONG_CONVERTER_METHODDEF + LONG_LONG_CONVERTER_METHODDEF + UNSIGNED_LONG_LONG_CONVERTER_METHODDEF + PY_SSIZE_T_CONVERTER_METHODDEF + SLICE_INDEX_CONVERTER_METHODDEF + SIZE_T_CONVERTER_METHODDEF + FLOAT_CONVERTER_METHODDEF + DOUBLE_CONVERTER_METHODDEF + PY_COMPLEX_CONVERTER_METHODDEF + STR_CONVERTER_METHODDEF + STR_CONVERTER_ENCODING_METHODDEF + PY_BUFFER_CONVERTER_METHODDEF + KEYWORDS_METHODDEF + KEYWORDS_KWONLY_METHODDEF + KEYWORDS_OPT_METHODDEF + KEYWORDS_OPT_KWONLY_METHODDEF + KEYWORDS_KWONLY_OPT_METHODDEF + POSONLY_KEYWORDS_METHODDEF + POSONLY_KWONLY_METHODDEF + POSONLY_KEYWORDS_KWONLY_METHODDEF + POSONLY_KEYWORDS_OPT_METHODDEF + POSONLY_OPT_KEYWORDS_OPT_METHODDEF + POSONLY_KWONLY_OPT_METHODDEF + POSONLY_OPT_KWONLY_OPT_METHODDEF + POSONLY_KEYWORDS_KWONLY_OPT_METHODDEF + POSONLY_KEYWORDS_OPT_KWONLY_OPT_METHODDEF + POSONLY_OPT_KEYWORDS_OPT_KWONLY_OPT_METHODDEF + KEYWORD_ONLY_PARAMETER_METHODDEF + POSONLY_VARARG_METHODDEF + VARARG_AND_POSONLY_METHODDEF + VARARG_METHODDEF + VARARG_WITH_DEFAULT_METHODDEF + VARARG_WITH_ONLY_DEFAULTS_METHODDEF + GH_32092_OOB_METHODDEF + GH_32092_KW_PASS_METHODDEF + GH_99233_REFCOUNT_METHODDEF + GH_99240_DOUBLE_FREE_METHODDEF + {NULL, NULL} +}; + +static struct PyModuleDef _testclinic_module = { + PyModuleDef_HEAD_INIT, + .m_name = "_testclinic", + .m_size = 0, + .m_methods = tester_methods, +}; + +PyMODINIT_FUNC +PyInit__testclinic(void) +{ + return PyModule_Create(&_testclinic_module); +} + +#undef RETURN_PACKED_ARGS diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index c230ba28d61..ba57719d920 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -14,16 +14,78 @@ #include "Python.h" #include "pycore_atomic_funcs.h" // _Py_atomic_int_get() #include "pycore_bitutils.h" // _Py_bswap32() -#include "pycore_fileutils.h" // _Py_normalize_path +#include "pycore_compile.h" // _PyCompile_CodeGen, _PyCompile_OptimizeCfg +#include "pycore_fileutils.h" // _Py_normpath +#include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_gc.h" // PyGC_Head #include "pycore_hashtable.h" // _Py_hashtable_new() #include "pycore_initconfig.h" // _Py_GetConfigsAsDict() +#include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal() #include "pycore_interp.h" // _PyInterpreterState_GetConfigCopy() #include "pycore_pyerrors.h" // _Py_UTF8_Edit_Cost() #include "pycore_pystate.h" // _PyThreadState_GET() -#include "osdefs.h" // MAXPATHLEN +#include "osdefs.h" // MAXPATHLEN + +#include "clinic/_testinternalcapi.c.h" +#define MODULE_NAME "_testinternalcapi" + + +static PyObject * +_get_current_module(void) +{ + // We ensured it was imported in _run_script(). + PyObject *name = PyUnicode_FromString(MODULE_NAME); + if (name == NULL) { + return NULL; + } + PyObject *mod = PyImport_GetModule(name); + Py_DECREF(name); + if (mod == NULL) { + return NULL; + } + assert(mod != Py_None); + return mod; +} + + +/* module state *************************************************************/ + +typedef struct { + PyObject *record_list; +} module_state; + +static inline module_state * +get_module_state(PyObject *mod) +{ + assert(mod != NULL); + module_state *state = PyModule_GetState(mod); + assert(state != NULL); + return state; +} + +static int +traverse_module_state(module_state *state, visitproc visit, void *arg) +{ + Py_VISIT(state->record_list); + return 0; +} + +static int +clear_module_state(module_state *state) +{ + Py_CLEAR(state->record_list); + return 0; +} + + +/* module functions *********************************************************/ + +/*[clinic input] +module _testinternalcapi +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7bb583d8c9eb9a78]*/ static PyObject * get_configs(PyObject *self, PyObject *Py_UNUSED(args)) { @@ -36,9 +98,7 @@ get_recursion_depth(PyObject *self, PyObject *Py_UNUSED(args)) { PyThreadState *tstate = _PyThreadState_GET(); - /* subtract one to ignore the frame of the get_recursion_depth() call */ - - return PyLong_FromLong(tstate->recursion_limit - tstate->recursion_remaining - 1); + return PyLong_FromLong(tstate->py_recursion_limit - tstate->py_recursion_remaining); } @@ -99,6 +159,7 @@ test_popcount(PyObject *self, PyObject *Py_UNUSED(args)) CHECK(0, 0); CHECK(1, 1); CHECK(0x08080808, 4); + CHECK(0x10000001, 2); CHECK(0x10101010, 4); CHECK(0x10204080, 4); CHECK(0xDEADCAFE, 22); @@ -273,6 +334,14 @@ error: } +static PyObject * +test_reset_path_config(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(arg)) +{ + _PyPathConfig_ClearGlobal(); + Py_RETURN_NONE; +} + + static PyObject* test_atomic_funcs(PyObject *self, PyObject *Py_UNUSED(args)) { @@ -296,7 +365,7 @@ check_edit_cost(const char *a, const char *b, Py_ssize_t expected) goto exit; } b_obj = PyUnicode_FromString(b); - if (a_obj == NULL) { + if (b_obj == NULL) { goto exit; } Py_ssize_t result = _Py_UTF8_Edit_Cost(a_obj, b_obj, -1); @@ -378,19 +447,231 @@ normalize_path(PyObject *self, PyObject *filename) return NULL; } - wchar_t buf[MAXPATHLEN + 1]; - int res = _Py_normalize_path(encoded, buf, Py_ARRAY_LENGTH(buf)); + PyObject *result = PyUnicode_FromWideChar(_Py_normpath(encoded, size), -1); PyMem_Free(encoded); - if (res != 0) { - PyErr_SetString(PyExc_ValueError, "string too long"); - return NULL; - } - return PyUnicode_FromWideChar(buf, -1); + return result; +} + +static PyObject * +get_getpath_codeobject(PyObject *self, PyObject *Py_UNUSED(args)) { + return _Py_Get_Getpath_CodeObject(); } -static PyMethodDef TestMethods[] = { +static PyObject * +encode_locale_ex(PyObject *self, PyObject *args) +{ + PyObject *unicode; + int current_locale = 0; + wchar_t *wstr; + PyObject *res = NULL; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "U|is", &unicode, ¤t_locale, &errors)) { + return NULL; + } + wstr = PyUnicode_AsWideCharString(unicode, NULL); + if (wstr == NULL) { + return NULL; + } + _Py_error_handler error_handler = _Py_GetErrorHandler(errors); + + char *str = NULL; + size_t error_pos; + const char *reason = NULL; + int ret = _Py_EncodeLocaleEx(wstr, + &str, &error_pos, &reason, + current_locale, error_handler); + PyMem_Free(wstr); + + switch(ret) { + case 0: + res = PyBytes_FromString(str); + PyMem_RawFree(str); + break; + case -1: + PyErr_NoMemory(); + break; + case -2: + PyErr_Format(PyExc_RuntimeError, "encode error: pos=%zu, reason=%s", + error_pos, reason); + break; + case -3: + PyErr_SetString(PyExc_ValueError, "unsupported error handler"); + break; + default: + PyErr_SetString(PyExc_ValueError, "unknown error code"); + break; + } + return res; +} + + +static PyObject * +decode_locale_ex(PyObject *self, PyObject *args) +{ + char *str; + int current_locale = 0; + PyObject *res = NULL; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "y|is", &str, ¤t_locale, &errors)) { + return NULL; + } + _Py_error_handler error_handler = _Py_GetErrorHandler(errors); + + wchar_t *wstr = NULL; + size_t wlen = 0; + const char *reason = NULL; + int ret = _Py_DecodeLocaleEx(str, + &wstr, &wlen, &reason, + current_locale, error_handler); + + switch(ret) { + case 0: + res = PyUnicode_FromWideChar(wstr, wlen); + PyMem_RawFree(wstr); + break; + case -1: + PyErr_NoMemory(); + break; + case -2: + PyErr_Format(PyExc_RuntimeError, "decode error: pos=%zu, reason=%s", + wlen, reason); + break; + case -3: + PyErr_SetString(PyExc_ValueError, "unsupported error handler"); + break; + default: + PyErr_SetString(PyExc_ValueError, "unknown error code"); + break; + } + return res; +} + +static PyObject * +set_eval_frame_default(PyObject *self, PyObject *Py_UNUSED(args)) +{ + module_state *state = get_module_state(self); + _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState_Get(), _PyEval_EvalFrameDefault); + Py_CLEAR(state->record_list); + Py_RETURN_NONE; +} + +static PyObject * +record_eval(PyThreadState *tstate, struct _PyInterpreterFrame *f, int exc) +{ + if (PyFunction_Check(f->f_funcobj)) { + PyObject *module = _get_current_module(); + assert(module != NULL); + module_state *state = get_module_state(module); + Py_DECREF(module); + PyList_Append(state->record_list, ((PyFunctionObject *)f->f_funcobj)->func_name); + } + return _PyEval_EvalFrameDefault(tstate, f, exc); +} + + +static PyObject * +set_eval_frame_record(PyObject *self, PyObject *list) +{ + module_state *state = get_module_state(self); + if (!PyList_Check(list)) { + PyErr_SetString(PyExc_TypeError, "argument must be a list"); + return NULL; + } + Py_XSETREF(state->record_list, Py_NewRef(list)); + _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState_Get(), record_eval); + Py_RETURN_NONE; +} + +/*[clinic input] + +_testinternalcapi.compiler_codegen -> object + + ast: object + filename: object + optimize: int + +Apply compiler code generation to an AST. +[clinic start generated code]*/ + +static PyObject * +_testinternalcapi_compiler_codegen_impl(PyObject *module, PyObject *ast, + PyObject *filename, int optimize) +/*[clinic end generated code: output=fbbbbfb34700c804 input=e9fbe6562f7f75e4]*/ +{ + PyCompilerFlags *flags = NULL; + return _PyCompile_CodeGen(ast, filename, flags, optimize); +} + + +/*[clinic input] + +_testinternalcapi.optimize_cfg -> object + + instructions: object + consts: object + +Apply compiler optimizations to an instruction list. +[clinic start generated code]*/ + +static PyObject * +_testinternalcapi_optimize_cfg_impl(PyObject *module, PyObject *instructions, + PyObject *consts) +/*[clinic end generated code: output=5412aeafca683c8b input=7e8a3de86ebdd0f9]*/ +{ + return _PyCompile_OptimizeCfg(instructions, consts); +} + + +static PyObject * +get_interp_settings(PyObject *self, PyObject *args) +{ + int interpid = -1; + if (!PyArg_ParseTuple(args, "|i:get_interp_settings", &interpid)) { + return NULL; + } + + PyInterpreterState *interp = NULL; + if (interpid < 0) { + PyThreadState *tstate = _PyThreadState_GET(); + interp = tstate ? tstate->interp : _PyInterpreterState_Main(); + } + else if (interpid == 0) { + interp = _PyInterpreterState_Main(); + } + else { + PyErr_Format(PyExc_NotImplementedError, + "%zd", interpid); + return NULL; + } + assert(interp != NULL); + + PyObject *settings = PyDict_New(); + if (settings == NULL) { + return NULL; + } + + /* Add the feature flags. */ + PyObject *flags = PyLong_FromUnsignedLong(interp->feature_flags); + if (flags == NULL) { + Py_DECREF(settings); + return NULL; + } + int res = PyDict_SetItemString(settings, "feature_flags", flags); + Py_DECREF(flags); + if (res != 0) { + Py_DECREF(settings); + return NULL; + } + + return settings; +} + + +static PyMethodDef module_functions[] = { {"get_configs", get_configs, METH_NOARGS}, {"get_recursion_depth", get_recursion_depth, METH_NOARGS}, {"test_bswap", test_bswap, METH_NOARGS}, @@ -399,42 +680,81 @@ static PyMethodDef TestMethods[] = { {"test_hashtable", test_hashtable, METH_NOARGS}, {"get_config", test_get_config, METH_NOARGS}, {"set_config", test_set_config, METH_O}, + {"reset_path_config", test_reset_path_config, METH_NOARGS}, {"test_atomic_funcs", test_atomic_funcs, METH_NOARGS}, {"test_edit_cost", test_edit_cost, METH_NOARGS}, {"normalize_path", normalize_path, METH_O, NULL}, + {"get_getpath_codeobject", get_getpath_codeobject, METH_NOARGS, NULL}, + {"EncodeLocaleEx", encode_locale_ex, METH_VARARGS}, + {"DecodeLocaleEx", decode_locale_ex, METH_VARARGS}, + {"set_eval_frame_default", set_eval_frame_default, METH_NOARGS, NULL}, + {"set_eval_frame_record", set_eval_frame_record, METH_O, NULL}, + _TESTINTERNALCAPI_COMPILER_CODEGEN_METHODDEF + _TESTINTERNALCAPI_OPTIMIZE_CFG_METHODDEF + {"get_interp_settings", get_interp_settings, METH_VARARGS, NULL}, {NULL, NULL} /* sentinel */ }; +/* initialization function */ + +static int +module_exec(PyObject *module) +{ + if (PyModule_AddObject(module, "SIZEOF_PYGC_HEAD", + PyLong_FromSsize_t(sizeof(PyGC_Head))) < 0) { + return 1; + } + + return 0; +} + +static struct PyModuleDef_Slot module_slots[] = { + {Py_mod_exec, module_exec}, + {0, NULL}, +}; + +static int +module_traverse(PyObject *module, visitproc visit, void *arg) +{ + module_state *state = get_module_state(module); + assert(state != NULL); + traverse_module_state(state, visit, arg); + return 0; +} + +static int +module_clear(PyObject *module) +{ + module_state *state = get_module_state(module); + assert(state != NULL); + (void)clear_module_state(state); + return 0; +} + +static void +module_free(void *module) +{ + module_state *state = get_module_state(module); + assert(state != NULL); + (void)clear_module_state(state); +} + static struct PyModuleDef _testcapimodule = { - PyModuleDef_HEAD_INIT, - "_testinternalcapi", - NULL, - -1, - TestMethods, - NULL, - NULL, - NULL, - NULL + .m_base = PyModuleDef_HEAD_INIT, + .m_name = MODULE_NAME, + .m_doc = NULL, + .m_size = sizeof(module_state), + .m_methods = module_functions, + .m_slots = module_slots, + .m_traverse = module_traverse, + .m_clear = module_clear, + .m_free = (freefunc)module_free, }; PyMODINIT_FUNC PyInit__testinternalcapi(void) { - PyObject *module = PyModule_Create(&_testcapimodule); - if (module == NULL) { - return NULL; - } - - if (PyModule_AddObject(module, "SIZEOF_PYGC_HEAD", - PyLong_FromSsize_t(sizeof(PyGC_Head))) < 0) { - goto error; - } - - return module; - -error: - Py_DECREF(module); - return NULL; + return PyModuleDef_Init(&_testcapimodule); } diff --git a/Modules/_testmultiphase.c b/Modules/_testmultiphase.c index ee69c423361..e34854f7025 100644 --- a/Modules/_testmultiphase.c +++ b/Modules/_testmultiphase.c @@ -57,8 +57,7 @@ Example_demo(ExampleObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "|O:demo", &o)) return NULL; if (o != NULL && PyUnicode_Check(o)) { - Py_INCREF(o); - return o; + return Py_NewRef(o); } Py_RETURN_NONE; } @@ -77,8 +76,7 @@ Example_getattro(ExampleObject *self, PyObject *name) if (self->x_attr != NULL) { PyObject *v = PyDict_GetItemWithError(self->x_attr, name); if (v != NULL) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } else if (PyErr_Occurred()) { return NULL; @@ -126,6 +124,8 @@ static PyType_Spec Example_Type_spec = { static PyModuleDef def_meth_state_access; +static PyModuleDef def_nonmodule; +static PyModuleDef def_nonmodule_with_methods; /*[clinic input] _testmultiphase.StateAccessType.get_defining_module @@ -134,23 +134,40 @@ _testmultiphase.StateAccessType.get_defining_module Return the module of the defining class. -Also tests that result of _PyType_GetModuleByDef matches defining_class's +Also tests that result of PyType_GetModuleByDef matches defining_class's module. [clinic start generated code]*/ static PyObject * _testmultiphase_StateAccessType_get_defining_module_impl(StateAccessTypeObject *self, PyTypeObject *cls) -/*[clinic end generated code: output=ba2a14284a5d0921 input=356f999fc16e0933]*/ +/*[clinic end generated code: output=ba2a14284a5d0921 input=d2c7245c8a9d06f8]*/ { PyObject *retval; retval = PyType_GetModule(cls); if (retval == NULL) { return NULL; } - assert(_PyType_GetModuleByDef(Py_TYPE(self), &def_meth_state_access) == retval); - Py_INCREF(retval); - return retval; + assert(PyType_GetModuleByDef(Py_TYPE(self), &def_meth_state_access) == retval); + return Py_NewRef(retval); +} + +/*[clinic input] +_testmultiphase.StateAccessType.getmodulebydef_bad_def + + cls: defining_class + +Test that result of PyType_GetModuleByDef with a bad def is NULL. +[clinic start generated code]*/ + +static PyObject * +_testmultiphase_StateAccessType_getmodulebydef_bad_def_impl(StateAccessTypeObject *self, + PyTypeObject *cls) +/*[clinic end generated code: output=64509074dfcdbd31 input=edaff09aa4788204]*/ +{ + PyType_GetModuleByDef(Py_TYPE(self), &def_nonmodule); // should raise + assert(PyErr_Occurred()); + return NULL; } /*[clinic input] @@ -249,11 +266,12 @@ _testmultiphase_StateAccessType_get_count_impl(StateAccessTypeObject *self, static PyMethodDef StateAccessType_methods[] = { _TESTMULTIPHASE_STATEACCESSTYPE_GET_DEFINING_MODULE_METHODDEF + _TESTMULTIPHASE_STATEACCESSTYPE_GETMODULEBYDEF_BAD_DEF_METHODDEF _TESTMULTIPHASE_STATEACCESSTYPE_GET_COUNT_METHODDEF _TESTMULTIPHASE_STATEACCESSTYPE_INCREMENT_COUNT_CLINIC_METHODDEF { "increment_count_noclinic", - (PyCFunction)(void(*)(void))_StateAccessType_increment_count_noclinic, + _PyCFunction_CAST(_StateAccessType_increment_count_noclinic), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _StateAccessType_decrement_count__doc__ }, @@ -429,7 +447,7 @@ static PyModuleDef_Slot main_slots[] = { static PyModuleDef main_def = TEST_MODULE_DEF("main", main_slots, testexport_methods); PyMODINIT_FUNC -PyInit__testmultiphase(PyObject *spec) +PyInit__testmultiphase(void) { return PyModuleDef_Init(&main_def); } @@ -437,9 +455,6 @@ PyInit__testmultiphase(PyObject *spec) /**** Importing a non-module object ****/ -static PyModuleDef def_nonmodule; -static PyModuleDef def_nonmodule_with_methods; - /* Create a SimpleNamespace(three=3) */ static PyObject* createfunc_nonmodule(PyObject *spec, PyModuleDef *def) @@ -477,7 +492,7 @@ static PyModuleDef def_nonmodule = TEST_MODULE_DEF( "_testmultiphase_nonmodule", slots_create_nonmodule, NULL); PyMODINIT_FUNC -PyInit__testmultiphase_nonmodule(PyObject *spec) +PyInit__testmultiphase_nonmodule(void) { return PyModuleDef_Init(&def_nonmodule); } @@ -507,7 +522,7 @@ static PyModuleDef def_nonmodule_with_methods = TEST_MODULE_DEF( "_testmultiphase_nonmodule_with_methods", slots_create_nonmodule, nonmodule_methods); PyMODINIT_FUNC -PyInit__testmultiphase_nonmodule_with_methods(PyObject *spec) +PyInit__testmultiphase_nonmodule_with_methods(void) { return PyModuleDef_Init(&def_nonmodule_with_methods); } @@ -527,7 +542,7 @@ static PyModuleDef def_nonascii_latin = { \ }; PyMODINIT_FUNC -PyInitU__testmultiphase_zkouka_naten_evc07gi8e(PyObject *spec) +PyInitU__testmultiphase_zkouka_naten_evc07gi8e(void) { return PyModuleDef_Init(&def_nonascii_latin); } @@ -545,7 +560,7 @@ static PyModuleDef def_nonascii_kana = { \ }; PyMODINIT_FUNC -PyInitU_eckzbwbhc6jpgzcx415x(PyObject *spec) +PyInitU_eckzbwbhc6jpgzcx415x(void) { return PyModuleDef_Init(&def_nonascii_kana); } @@ -553,7 +568,7 @@ PyInitU_eckzbwbhc6jpgzcx415x(PyObject *spec) /*** Module with a single-character name ***/ PyMODINIT_FUNC -PyInit_x(PyObject *spec) +PyInit_x(void) { return PyModuleDef_Init(&main_def); } @@ -564,7 +579,7 @@ static PyModuleDef null_slots_def = TEST_MODULE_DEF( "_testmultiphase_null_slots", NULL, NULL); PyMODINIT_FUNC -PyInit__testmultiphase_null_slots(PyObject *spec) +PyInit__testmultiphase_null_slots(void) { return PyModuleDef_Init(&null_slots_def); } @@ -580,7 +595,7 @@ static PyModuleDef def_bad_large = TEST_MODULE_DEF( "_testmultiphase_bad_slot_large", slots_bad_large, NULL); PyMODINIT_FUNC -PyInit__testmultiphase_bad_slot_large(PyObject *spec) +PyInit__testmultiphase_bad_slot_large(void) { return PyModuleDef_Init(&def_bad_large); } @@ -594,7 +609,7 @@ static PyModuleDef def_bad_negative = TEST_MODULE_DEF( "_testmultiphase_bad_slot_negative", slots_bad_negative, NULL); PyMODINIT_FUNC -PyInit__testmultiphase_bad_slot_negative(PyObject *spec) +PyInit__testmultiphase_bad_slot_negative(void) { return PyModuleDef_Init(&def_bad_negative); } @@ -612,7 +627,7 @@ static PyModuleDef def_create_int_with_state = { \ }; PyMODINIT_FUNC -PyInit__testmultiphase_create_int_with_state(PyObject *spec) +PyInit__testmultiphase_create_int_with_state(void) { return PyModuleDef_Init(&def_create_int_with_state); } @@ -631,7 +646,7 @@ static PyModuleDef def_negative_size = { \ }; PyMODINIT_FUNC -PyInit__testmultiphase_negative_size(PyObject *spec) +PyInit__testmultiphase_negative_size(void) { return PyModuleDef_Init(&def_negative_size); } @@ -640,26 +655,26 @@ PyInit__testmultiphase_negative_size(PyObject *spec) static PyModuleDef uninitialized_def = TEST_MODULE_DEF("main", main_slots, testexport_methods); PyMODINIT_FUNC -PyInit__testmultiphase_export_uninitialized(PyObject *spec) +PyInit__testmultiphase_export_uninitialized(void) { return (PyObject*) &uninitialized_def; } PyMODINIT_FUNC -PyInit__testmultiphase_export_null(PyObject *spec) +PyInit__testmultiphase_export_null(void) { return NULL; } PyMODINIT_FUNC -PyInit__testmultiphase_export_raise(PyObject *spec) +PyInit__testmultiphase_export_raise(void) { PyErr_SetString(PyExc_SystemError, "bad export function"); return NULL; } PyMODINIT_FUNC -PyInit__testmultiphase_export_unreported_exception(PyObject *spec) +PyInit__testmultiphase_export_unreported_exception(void) { PyErr_SetString(PyExc_SystemError, "bad export function"); return PyModuleDef_Init(&main_def); @@ -680,7 +695,7 @@ static PyModuleDef def_create_null = TEST_MODULE_DEF( "_testmultiphase_create_null", slots_create_null, NULL); PyMODINIT_FUNC -PyInit__testmultiphase_create_null(PyObject *spec) +PyInit__testmultiphase_create_null(void) { return PyModuleDef_Init(&def_create_null); } @@ -701,7 +716,7 @@ static PyModuleDef def_create_raise = TEST_MODULE_DEF( "_testmultiphase_create_null", slots_create_raise, NULL); PyMODINIT_FUNC -PyInit__testmultiphase_create_raise(PyObject *spec) +PyInit__testmultiphase_create_raise(void) { return PyModuleDef_Init(&def_create_raise); } @@ -722,7 +737,7 @@ static PyModuleDef def_create_unreported_exception = TEST_MODULE_DEF( "_testmultiphase_create_unreported_exception", slots_create_unreported_exception, NULL); PyMODINIT_FUNC -PyInit__testmultiphase_create_unreported_exception(PyObject *spec) +PyInit__testmultiphase_create_unreported_exception(void) { return PyModuleDef_Init(&def_create_unreported_exception); } @@ -737,7 +752,7 @@ static PyModuleDef def_nonmodule_with_exec_slots = TEST_MODULE_DEF( "_testmultiphase_nonmodule_with_exec_slots", slots_nonmodule_with_exec_slots, NULL); PyMODINIT_FUNC -PyInit__testmultiphase_nonmodule_with_exec_slots(PyObject *spec) +PyInit__testmultiphase_nonmodule_with_exec_slots(void) { return PyModuleDef_Init(&def_nonmodule_with_exec_slots); } @@ -757,7 +772,7 @@ static PyModuleDef def_exec_err = TEST_MODULE_DEF( "_testmultiphase_exec_err", slots_exec_err, NULL); PyMODINIT_FUNC -PyInit__testmultiphase_exec_err(PyObject *spec) +PyInit__testmultiphase_exec_err(void) { return PyModuleDef_Init(&def_exec_err); } @@ -778,7 +793,7 @@ static PyModuleDef def_exec_raise = TEST_MODULE_DEF( "_testmultiphase_exec_raise", slots_exec_raise, NULL); PyMODINIT_FUNC -PyInit__testmultiphase_exec_raise(PyObject *mod) +PyInit__testmultiphase_exec_raise(void) { return PyModuleDef_Init(&def_exec_raise); } @@ -799,7 +814,7 @@ static PyModuleDef def_exec_unreported_exception = TEST_MODULE_DEF( "_testmultiphase_exec_unreported_exception", slots_exec_unreported_exception, NULL); PyMODINIT_FUNC -PyInit__testmultiphase_exec_unreported_exception(PyObject *spec) +PyInit__testmultiphase_exec_unreported_exception(void) { return PyModuleDef_Init(&def_exec_unreported_exception); } @@ -843,7 +858,7 @@ static PyModuleDef def_meth_state_access = { }; PyMODINIT_FUNC -PyInit__testmultiphase_meth_state_access(PyObject *spec) +PyInit__testmultiphase_meth_state_access(void) { return PyModuleDef_Init(&def_meth_state_access); } @@ -856,7 +871,7 @@ static PyModuleDef def_module_state_shared = { }; PyMODINIT_FUNC -PyInit__test_module_state_shared(PyObject *spec) +PyInit__test_module_state_shared(void) { PyObject *module = PyModule_Create(&def_module_state_shared); if (module == NULL) { @@ -876,7 +891,7 @@ PyInit__test_module_state_shared(PyObject *spec) static PyModuleDef imp_dummy_def = TEST_MODULE_DEF("imp_dummy", main_slots, testexport_methods); PyMODINIT_FUNC -PyInit_imp_dummy(PyObject *spec) +PyInit_imp_dummy(void) { return PyModuleDef_Init(&imp_dummy_def); } diff --git a/Modules/_testsinglephase.c b/Modules/_testsinglephase.c new file mode 100644 index 00000000000..3bfe159e54f --- /dev/null +++ b/Modules/_testsinglephase.c @@ -0,0 +1,78 @@ + +/* Testing module for single-phase initialization of extension modules + */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + +#include "Python.h" +#include "pycore_namespace.h" // _PyNamespace_New() + + +/* Function of two integers returning integer */ + +PyDoc_STRVAR(testexport_foo_doc, +"foo(i,j)\n\ +\n\ +Return the sum of i and j."); + +static PyObject * +testexport_foo(PyObject *self, PyObject *args) +{ + long i, j; + long res; + if (!PyArg_ParseTuple(args, "ll:foo", &i, &j)) + return NULL; + res = i + j; + return PyLong_FromLong(res); +} + + +static PyMethodDef TestMethods[] = { + {"foo", testexport_foo, METH_VARARGS, + testexport_foo_doc}, + {NULL, NULL} /* sentinel */ +}; + + +static struct PyModuleDef _testsinglephase = { + PyModuleDef_HEAD_INIT, + .m_name = "_testsinglephase", + .m_doc = PyDoc_STR("Test module _testsinglephase (main)"), + .m_size = -1, // no module state + .m_methods = TestMethods, +}; + + +PyMODINIT_FUNC +PyInit__testsinglephase(void) +{ + PyObject *module = PyModule_Create(&_testsinglephase); + if (module == NULL) { + return NULL; + } + + /* Add an exception type */ + PyObject *temp = PyErr_NewException("_testsinglephase.error", NULL, NULL); + if (temp == NULL) { + goto error; + } + if (PyModule_AddObject(module, "error", temp) != 0) { + Py_DECREF(temp); + goto error; + } + + if (PyModule_AddIntConstant(module, "int_const", 1969) != 0) { + goto error; + } + + if (PyModule_AddStringConstant(module, "str_const", "something different") != 0) { + goto error; + } + + return module; + +error: + Py_DECREF(module); + return NULL; +} diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 39b116afcaa..bf4b6ec00e3 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -3,10 +3,10 @@ /* Interface to Sjoerd's portable C thread library */ #include "Python.h" -#include "pycore_interp.h" // _PyInterpreterState.num_threads +#include "pycore_interp.h" // _PyInterpreterState.threads.count #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_pylifecycle.h" -#include "pycore_pystate.h" // _PyThreadState_Init() +#include "pycore_pystate.h" // _PyThreadState_SetCurrent() #include // offsetof() #include "structmember.h" // PyMemberDef @@ -17,17 +17,13 @@ // ThreadError is just an alias to PyExc_RuntimeError #define ThreadError PyExc_RuntimeError -_Py_IDENTIFIER(__dict__); - -_Py_IDENTIFIER(stderr); -_Py_IDENTIFIER(flush); - // Forward declarations static struct PyModuleDef thread_module; typedef struct { + PyTypeObject *excepthook_type; PyTypeObject *lock_type; PyTypeObject *local_type; PyTypeObject *local_dummy_type; @@ -61,6 +57,7 @@ lock_traverse(lockobject *self, visitproc visit, void *arg) static void lock_dealloc(lockobject *self) { + PyObject_GC_UnTrack(self); if (self->in_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) self); } @@ -138,7 +135,7 @@ lock_acquire_parse_args(PyObject *args, PyObject *kwds, *timeout = unset_timeout ; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO:acquire", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|pO:acquire", kwlist, &blocking, &timeout_obj)) return -1; @@ -258,9 +255,9 @@ lock__at_fork_reinit(lockobject *self, PyObject *Py_UNUSED(args)) static PyMethodDef lock_methods[] = { - {"acquire_lock", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock, + {"acquire_lock", _PyCFunction_CAST(lock_PyThread_acquire_lock), METH_VARARGS | METH_KEYWORDS, acquire_doc}, - {"acquire", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock, + {"acquire", _PyCFunction_CAST(lock_PyThread_acquire_lock), METH_VARARGS | METH_KEYWORDS, acquire_doc}, {"release_lock", (PyCFunction)lock_PyThread_release_lock, METH_NOARGS, release_doc}, @@ -270,7 +267,7 @@ static PyMethodDef lock_methods[] = { METH_NOARGS, locked_doc}, {"locked", (PyCFunction)lock_locked_lock, METH_NOARGS, locked_doc}, - {"__enter__", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock, + {"__enter__", _PyCFunction_CAST(lock_PyThread_acquire_lock), METH_VARARGS | METH_KEYWORDS, acquire_doc}, {"__exit__", (PyCFunction)lock_PyThread_release_lock, METH_VARARGS, release_doc}, @@ -337,6 +334,7 @@ rlock_traverse(rlockobject *self, visitproc visit, void *arg) static void rlock_dealloc(rlockobject *self) { + PyObject_GC_UnTrack(self); if (self->in_weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed @@ -552,7 +550,7 @@ rlock__at_fork_reinit(rlockobject *self, PyObject *Py_UNUSED(args)) static PyMethodDef rlock_methods[] = { - {"acquire", (PyCFunction)(void(*)(void))rlock_acquire, + {"acquire", _PyCFunction_CAST(rlock_acquire), METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc}, {"release", (PyCFunction)rlock_release, METH_NOARGS, rlock_release_doc}, @@ -562,7 +560,7 @@ static PyMethodDef rlock_methods[] = { METH_VARARGS, rlock_acquire_restore_doc}, {"_release_save", (PyCFunction)rlock_release_save, METH_NOARGS, rlock_release_save_doc}, - {"__enter__", (PyCFunction)(void(*)(void))rlock_acquire, + {"__enter__", _PyCFunction_CAST(rlock_acquire), METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc}, {"__exit__", (PyCFunction)rlock_release, METH_VARARGS, rlock_release_doc}, @@ -790,7 +788,7 @@ local_new(PyTypeObject *type, PyObject *args, PyObject *kw) } } - PyObject *module = _PyType_GetModuleByDef(type, &thread_module); + PyObject *module = PyType_GetModuleByDef(type, &thread_module); thread_module_state *state = get_thread_state(module); localobject *self = (localobject *)type->tp_alloc(type, 0); @@ -851,18 +849,23 @@ local_clear(localobject *self) /* Remove all strong references to dummies from the thread states */ if (self->key) { PyInterpreterState *interp = _PyInterpreterState_GET(); + _PyRuntimeState *runtime = &_PyRuntime; + HEAD_LOCK(runtime); PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); - for(; tstate; tstate = PyThreadState_Next(tstate)) { - if (tstate->dict == NULL) { - continue; - } - PyObject *v = _PyDict_Pop(tstate->dict, self->key, Py_None); - if (v != NULL) { - Py_DECREF(v); - } - else { - PyErr_Clear(); + HEAD_UNLOCK(runtime); + while (tstate) { + if (tstate->dict) { + PyObject *v = _PyDict_Pop(tstate->dict, self->key, Py_None); + if (v != NULL) { + Py_DECREF(v); + } + else { + PyErr_Clear(); + } } + HEAD_LOCK(runtime); + tstate = PyThreadState_Next(tstate); + HEAD_UNLOCK(runtime); } } return 0; @@ -929,7 +932,7 @@ _ldict(localobject *self, thread_module_state *state) static int local_setattro(localobject *self, PyObject *name, PyObject *v) { - PyObject *module = _PyType_GetModuleByDef(Py_TYPE(self), &thread_module); + PyObject *module = PyType_GetModuleByDef(Py_TYPE(self), &thread_module); thread_module_state *state = get_thread_state(module); PyObject *ldict = _ldict(self, state); @@ -937,12 +940,7 @@ local_setattro(localobject *self, PyObject *name, PyObject *v) return -1; } - PyObject *str_dict = _PyUnicode_FromId(&PyId___dict__); // borrowed ref - if (str_dict == NULL) { - return -1; - } - - int r = PyObject_RichCompareBool(name, str_dict, Py_EQ); + int r = PyObject_RichCompareBool(name, &_Py_ID(__dict__), Py_EQ); if (r == -1) { return -1; } @@ -986,19 +984,14 @@ static PyType_Spec local_type_spec = { static PyObject * local_getattro(localobject *self, PyObject *name) { - PyObject *module = _PyType_GetModuleByDef(Py_TYPE(self), &thread_module); + PyObject *module = PyType_GetModuleByDef(Py_TYPE(self), &thread_module); thread_module_state *state = get_thread_state(module); PyObject *ldict = _ldict(self, state); if (ldict == NULL) return NULL; - PyObject *str_dict = _PyUnicode_FromId(&PyId___dict__); // borrowed ref - if (str_dict == NULL) { - return NULL; - } - - int r = PyObject_RichCompareBool(name, str_dict, Py_EQ); + int r = PyObject_RichCompareBool(name, &_Py_ID(__dict__), Py_EQ); if (r == 1) { return Py_NewRef(ldict); } @@ -1081,15 +1074,9 @@ thread_run(void *boot_raw) PyThreadState *tstate; tstate = boot->tstate; - tstate->thread_id = PyThread_get_thread_ident(); -#ifdef PY_HAVE_THREAD_NATIVE_ID - tstate->native_thread_id = PyThread_get_thread_native_id(); -#else - tstate->native_thread_id = 0; -#endif - _PyThreadState_Init(tstate); + _PyThreadState_Bind(tstate); PyEval_AcquireThread(tstate); - tstate->interp->num_threads++; + tstate->interp->threads.count++; PyObject *res = PyObject_Call(boot->func, boot->args, boot->kwargs); if (res == NULL) { @@ -1105,7 +1092,7 @@ thread_run(void *boot_raw) } thread_bootstate_free(boot); - tstate->interp->num_threads--; + tstate->interp->threads.count--; PyThreadState_Clear(tstate); _PyThreadState_DeleteCurrent(tstate); @@ -1114,6 +1101,24 @@ thread_run(void *boot_raw) // to open the libgcc_s.so library (ex: EMFILE error). } +static PyObject * +thread_daemon_threads_allowed(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyInterpreterState *interp = _PyInterpreterState_Get(); + if (interp->feature_flags & Py_RTFLAGS_DAEMON_THREADS) { + Py_RETURN_TRUE; + } + else { + Py_RETURN_FALSE; + } +} + +PyDoc_STRVAR(daemon_threads_allowed_doc, +"daemon_threads_allowed()\n\ +\n\ +Return True if daemon threads are allowed in the current interpreter,\n\ +and False otherwise.\n"); + static PyObject * thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) { @@ -1139,8 +1144,13 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) return NULL; } + if (PySys_Audit("_thread.start_new_thread", "OOO", + func, args, kwargs ? kwargs : Py_None) < 0) { + return NULL; + } + PyInterpreterState *interp = _PyInterpreterState_GET(); - if (interp->config._isolated_interpreter) { + if (!_PyInterpreterState_HasFeature(interp, Py_RTFLAGS_THREADS)) { PyErr_SetString(PyExc_RuntimeError, "thread is not supported for isolated subinterpreters"); return NULL; @@ -1154,7 +1164,10 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) boot->tstate = _PyThreadState_Prealloc(boot->interp); if (boot->tstate == NULL) { PyMem_Free(boot); - return PyErr_NoMemory(); + if (!PyErr_Occurred()) { + return PyErr_NoMemory(); + } + return NULL; } boot->runtime = runtime; boot->func = Py_NewRef(func); @@ -1279,7 +1292,7 @@ static PyObject * thread__count(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyInterpreterState *interp = _PyInterpreterState_GET(); - return PyLong_FromLong(interp->num_threads); + return PyLong_FromLong(interp->threads.count); } PyDoc_STRVAR(_count_doc, @@ -1412,7 +1425,6 @@ static int thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value, PyObject *exc_traceback, PyObject *thread) { - _Py_IDENTIFIER(name); /* print(f"Exception in thread {thread.name}:", file=file) */ if (PyFile_WriteString("Exception in thread ", file) < 0) { return -1; @@ -1420,7 +1432,7 @@ thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value, PyObject *name = NULL; if (thread != Py_None) { - if (_PyObject_LookupAttrId(thread, &PyId_name, &name) < 0) { + if (_PyObject_LookupAttr(thread, &_Py_ID(name), &name) < 0) { return -1; } } @@ -1458,7 +1470,7 @@ thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value, _PyErr_Display(file, exc_type, exc_value, exc_traceback); /* Call file.flush() */ - PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush); + PyObject *res = PyObject_CallMethodNoArgs(file, &_Py_ID(flush)); if (!res) { return -1; } @@ -1473,8 +1485,6 @@ PyDoc_STRVAR(ExceptHookArgs__doc__, \n\ Type used to pass arguments to threading.excepthook."); -static PyTypeObject ExceptHookArgsType; - static PyStructSequence_Field ExceptHookArgs_fields[] = { {"exc_type", "Exception type"}, {"exc_value", "Exception value"}, @@ -1492,9 +1502,11 @@ static PyStructSequence_Desc ExceptHookArgs_desc = { static PyObject * -thread_excepthook(PyObject *self, PyObject *args) +thread_excepthook(PyObject *module, PyObject *args) { - if (!Py_IS_TYPE(args, &ExceptHookArgsType)) { + thread_module_state *state = get_thread_state(module); + + if (!Py_IS_TYPE(args, state->excepthook_type)) { PyErr_SetString(PyExc_TypeError, "_thread.excepthook argument type " "must be ExceptHookArgs"); @@ -1513,7 +1525,8 @@ thread_excepthook(PyObject *self, PyObject *args) PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2); PyObject *thread = PyStructSequence_GET_ITEM(args, 3); - PyObject *file = _PySys_GetObjectId(&PyId_stderr); + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *file = _PySys_GetAttr(tstate, &_Py_ID(stderr)); if (file == NULL || file == Py_None) { if (thread == Py_None) { /* do nothing if sys.stderr is None and thread is None */ @@ -1555,6 +1568,8 @@ static PyMethodDef thread_methods[] = { METH_VARARGS, start_new_doc}, {"start_new", (PyCFunction)thread_PyThread_start_new_thread, METH_VARARGS, start_new_doc}, + {"daemon_threads_allowed", (PyCFunction)thread_daemon_threads_allowed, + METH_NOARGS, daemon_threads_allowed_doc}, {"allocate_lock", thread_PyThread_allocate_lock, METH_NOARGS, allocate_doc}, {"allocate", thread_PyThread_allocate_lock, @@ -1629,23 +1644,22 @@ thread_module_exec(PyObject *module) return -1; } - if (ExceptHookArgsType.tp_name == NULL) { - if (PyStructSequence_InitType2(&ExceptHookArgsType, - &ExceptHookArgs_desc) < 0) { - return -1; - } - } - // Add module attributes if (PyDict_SetItemString(d, "error", ThreadError) < 0) { return -1; } - if (PyModule_AddType(module, &ExceptHookArgsType) < 0) { + + // _ExceptHookArgs type + state->excepthook_type = PyStructSequence_NewType(&ExceptHookArgs_desc); + if (state->excepthook_type == NULL) { + return -1; + } + if (PyModule_AddType(module, state->excepthook_type) < 0) { return -1; } // TIMEOUT_MAX - double timeout_max = (_PyTime_t)PY_TIMEOUT_MAX * 1e-6; + double timeout_max = (double)PY_TIMEOUT_MAX * 1e-6; double time_max = _PyTime_AsSecondsDouble(_PyTime_MAX); timeout_max = Py_MIN(timeout_max, time_max); // Round towards minus infinity @@ -1664,6 +1678,7 @@ static int thread_module_traverse(PyObject *module, visitproc visit, void *arg) { thread_module_state *state = get_thread_state(module); + Py_VISIT(state->excepthook_type); Py_VISIT(state->lock_type); Py_VISIT(state->local_type); Py_VISIT(state->local_dummy_type); @@ -1674,6 +1689,7 @@ static int thread_module_clear(PyObject *module) { thread_module_state *state = get_thread_state(module); + Py_CLEAR(state->excepthook_type); Py_CLEAR(state->lock_type); Py_CLEAR(state->local_type); Py_CLEAR(state->local_dummy_type); diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index aabf20b8d96..d4a12905870 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -9,8 +9,8 @@ Copyright (C) 1994 Steen Lumholt. /* TCL/TK VERSION INFO: - Only Tcl/Tk 8.4 and later are supported. Older versions are not - supported. Use Python 3.4 or older if you cannot upgrade your + Only Tcl/Tk 8.5.12 and later are supported. Older versions are not + supported. Use Python 3.10 or older if you cannot upgrade your Tcl/Tk libraries. */ @@ -22,9 +22,15 @@ Copyright (C) 1994 Steen Lumholt. */ #define PY_SSIZE_T_CLEAN +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif #include "Python.h" #include +#ifdef MS_WINDOWS +# include "pycore_fileutils.h" // _Py_stat() +#endif #ifdef MS_WINDOWS #include @@ -48,15 +54,11 @@ Copyright (C) 1994 Steen Lumholt. #include "tkinter.h" -#if TK_HEX_VERSION < 0x08040200 -#error "Tk older than 8.4 not supported" +#if TK_HEX_VERSION < 0x0805020c +#error "Tk older than 8.5.12 not supported" #endif -#if TK_HEX_VERSION >= 0x08050208 && TK_HEX_VERSION < 0x08060000 || \ - TK_HEX_VERSION >= 0x08060200 -#define HAVE_LIBTOMMATH #include -#endif #if !(defined(MS_WINDOWS) || defined(__CYGWIN__)) #define HAVE_CREATEFILEHANDLER @@ -312,10 +314,6 @@ typedef struct { #define Tkapp_Interp(v) (((TkappObject *) (v))->interp) -#define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \ -(void *) v, Py_REFCNT(v))) - - /**** Error Handling ****/ @@ -786,16 +784,14 @@ PyTclObject_string(PyTclObject *self, void *ignored) if (!self->string) return NULL; } - Py_INCREF(self->string); - return self->string; + return Py_NewRef(self->string); } static PyObject * PyTclObject_str(PyTclObject *self) { if (self->string) { - Py_INCREF(self->string); - return self->string; + return Py_NewRef(self->string); } /* XXX Could cache result if it is non-ASCII. */ return unicodeFromTclObj(self->value); @@ -883,7 +879,6 @@ static PyType_Spec PyTclObject_Type_spec = { #define CHECK_STRING_LENGTH(s) #endif -#ifdef HAVE_LIBTOMMATH static Tcl_Obj* asBignumObj(PyObject *value) { @@ -920,7 +915,6 @@ asBignumObj(PyObject *value) } return result; } -#endif static Tcl_Obj* AsObj(PyObject *value) @@ -963,9 +957,7 @@ AsObj(PyObject *value) #endif /* If there is an overflow in the wideInt conversion, fall through to bignum handling. */ -#ifdef HAVE_LIBTOMMATH return asBignumObj(value); -#endif /* If there is no wideInt or bignum support, fall through to default object handling. */ } @@ -1085,7 +1077,6 @@ fromWideIntObj(TkappObject *tkapp, Tcl_Obj *value) return NULL; } -#ifdef HAVE_LIBTOMMATH static PyObject* fromBignumObj(TkappObject *tkapp, Tcl_Obj *value) { @@ -1114,13 +1105,11 @@ fromBignumObj(TkappObject *tkapp, Tcl_Obj *value) PyMem_Free(bytes); if (res != NULL && bigValue.sign == MP_NEG) { PyObject *res2 = PyNumber_Negative(res); - Py_DECREF(res); - res = res2; + Py_SETREF(res, res2); } mp_clear(&bigValue); return res; } -#endif static PyObject* FromObj(TkappObject *tkapp, Tcl_Obj *value) @@ -1165,13 +1154,11 @@ FromObj(TkappObject *tkapp, Tcl_Obj *value) fall through to bignum handling. */ } -#ifdef HAVE_LIBTOMMATH if (value->typePtr == tkapp->IntType || value->typePtr == tkapp->WideIntType || value->typePtr == tkapp->BignumType) { return fromBignumObj(tkapp, value); } -#endif if (value->typePtr == tkapp->ListType) { int size; @@ -1209,23 +1196,19 @@ FromObj(TkappObject *tkapp, Tcl_Obj *value) return unicodeFromTclObj(value); } -#if TK_HEX_VERSION >= 0x08050000 if (tkapp->BooleanType == NULL && strcmp(value->typePtr->name, "booleanString") == 0) { /* booleanString type is not registered in Tcl */ tkapp->BooleanType = value->typePtr; return fromBoolean(tkapp, value); } -#endif -#ifdef HAVE_LIBTOMMATH if (tkapp->BignumType == NULL && strcmp(value->typePtr->name, "bignum") == 0) { /* bignum type is not registered in Tcl */ tkapp->BignumType = value->typePtr; return fromBignumObj(tkapp, value); } -#endif return newPyTclObject(value); } @@ -1750,8 +1733,7 @@ SetVar(TkappObject *self, PyObject *args, int flags) if (!ok) Tkinter_Error(self); else { - res = Py_None; - Py_INCREF(res); + res = Py_NewRef(Py_None); } LEAVE_OVERLAP_TCL break; @@ -1769,8 +1751,7 @@ SetVar(TkappObject *self, PyObject *args, int flags) if (!ok) Tkinter_Error(self); else { - res = Py_None; - Py_INCREF(res); + res = Py_NewRef(Py_None); } LEAVE_OVERLAP_TCL break; @@ -1856,8 +1837,7 @@ UnsetVar(TkappObject *self, PyObject *args, int flags) if (code == TCL_ERROR) res = Tkinter_Error(self); else { - Py_INCREF(Py_None); - res = Py_None; + res = Py_NewRef(Py_None); } LEAVE_OVERLAP_TCL return res; @@ -1897,8 +1877,7 @@ _tkinter_tkapp_getint(TkappObject *self, PyObject *arg) PyObject *result; if (PyLong_Check(arg)) { - Py_INCREF(arg); - return arg; + return Py_NewRef(arg); } if (PyTclObject_Check(arg)) { @@ -1919,11 +1898,7 @@ _tkinter_tkapp_getint(TkappObject *self, PyObject *arg) Prefer bignum because Tcl_GetWideIntFromObj returns ambiguous result for value in ranges -2**64..-2**63-1 and 2**63..2**64-1 (on 32-bit platform). */ -#ifdef HAVE_LIBTOMMATH result = fromBignumObj(self, value); -#else - result = fromWideIntObj(self, value); -#endif Tcl_DecrRefCount(value); if (result != NULL || PyErr_Occurred()) return result; @@ -1946,8 +1921,7 @@ _tkinter_tkapp_getdouble(TkappObject *self, PyObject *arg) double v; if (PyFloat_Check(arg)) { - Py_INCREF(arg); - return arg; + return Py_NewRef(arg); } if (PyNumber_Check(arg)) { @@ -2163,8 +2137,7 @@ _tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg) return v; } if (PyTuple_Check(arg)) { - Py_INCREF(arg); - return arg; + return Py_NewRef(arg); } if (PyList_Check(arg)) { return PySequence_Tuple(arg); @@ -2190,8 +2163,7 @@ _tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg) for (i = 0; i < argc; i++) { PyObject *s = unicodeFromTclString(argv[i]); if (!s) { - Py_DECREF(v); - v = NULL; + Py_SETREF(v, NULL); goto finally; } PyTuple_SET_ITEM(v, i, s); @@ -2340,10 +2312,8 @@ _tkinter_tkapp_createcommand_impl(TkappObject *self, const char *name, data = PyMem_NEW(PythonCmd_ClientData, 1); if (!data) return PyErr_NoMemory(); - Py_INCREF(self); - Py_INCREF(func); - data->self = (PyObject *) self; - data->func = func; + data->self = Py_NewRef(self); + data->func = Py_NewRef(func); if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { Tcl_Condition cond = NULL; CommandEvent *ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent)); @@ -2448,10 +2418,8 @@ NewFHCD(PyObject *func, PyObject *file, int id) FileHandler_ClientData *p; p = PyMem_NEW(FileHandler_ClientData, 1); if (p != NULL) { - Py_XINCREF(func); - Py_XINCREF(file); - p->func = func; - p->file = file; + p->func = Py_XNewRef(func); + p->file = Py_XNewRef(file); p->id = id; p->next = HeadFHCD; HeadFHCD = p; @@ -2609,13 +2577,11 @@ Tktt_New(PyObject *func) if (v == NULL) return NULL; - Py_INCREF(func); v->token = NULL; - v->func = func; + v->func = Py_NewRef(func); /* Extra reference, deleted when called or when handler is deleted */ - Py_INCREF(v); - return v; + return (TkttObject*)Py_NewRef(v); } static void @@ -2866,7 +2832,7 @@ Tkapp_WantObjects(PyObject *self, PyObject *args) { int wantobjects = -1; - if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects)) + if (!PyArg_ParseTuple(args, "|p:wantobjects", &wantobjects)) return NULL; if (wantobjects == -1) return PyBool_FromLong(((TkappObject*)self)->wantobjects); @@ -2958,9 +2924,8 @@ _flatten1(FlattenContext* context, PyObject* item, int depth) if (context->size + 1 > context->maxsize && !_bump(context, 1)) return 0; - Py_INCREF(o); PyTuple_SET_ITEM(context->tuple, - context->size++, o); + context->size++, Py_NewRef(o)); } } } else { @@ -3013,11 +2978,11 @@ _tkinter.create screenName: str(accept={str, NoneType}) = None baseName: str = "" className: str = "Tk" - interactive: bool(accept={int}) = False - wantobjects: bool(accept={int}) = False - wantTk: bool(accept={int}) = True + interactive: bool = False + wantobjects: bool = False + wantTk: bool = True if false, then Tk_Init() doesn't get called - sync: bool(accept={int}) = False + sync: bool = False if true, then pass -sync to wish use: str(accept={str, NoneType}) = None if not None, then pass -use to wish @@ -3030,7 +2995,7 @@ _tkinter_create_impl(PyObject *module, const char *screenName, const char *baseName, const char *className, int interactive, int wantobjects, int wantTk, int sync, const char *use) -/*[clinic end generated code: output=e3315607648e6bb4 input=da9b17ee7358d862]*/ +/*[clinic end generated code: output=e3315607648e6bb4 input=09afef9adea70a19]*/ { /* XXX baseName is not used anymore; * try getting rid of it. */ @@ -3284,8 +3249,7 @@ PyInit__tkinter(void) Py_DECREF(m); return NULL; } - Py_INCREF(o); - if (PyModule_AddObject(m, "TclError", o)) { + if (PyModule_AddObject(m, "TclError", Py_NewRef(o))) { Py_DECREF(o); Py_DECREF(m); return NULL; @@ -3438,11 +3402,5 @@ PyInit__tkinter(void) return NULL; } -#if 0 - /* This was not a good idea; through bindings, - Tcl_Finalize() may invoke Python code but at that point the - interpreter and thread state have already been destroyed! */ - Py_AtExit(Tcl_Finalize); -#endif return m; } diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index 68e5f0d52dd..9826ad2935b 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -1,8 +1,10 @@ #include "Python.h" +#include "pycore_fileutils.h" // _Py_write_noraise() #include "pycore_gc.h" // PyGC_Head +#include "pycore_hashtable.h" // _Py_hashtable_t #include "pycore_pymem.h" // _Py_tracemalloc_config +#include "pycore_runtime.h" // _Py_ID() #include "pycore_traceback.h" -#include "pycore_hashtable.h" #include #include // malloc() @@ -14,8 +16,9 @@ module _tracemalloc [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=708a98302fc46e5f]*/ -/* Trace memory blocks allocated by PyMem_RawMalloc() */ -#define TRACE_RAW_MALLOC +#define tracemalloc_config _PyRuntime.tracemalloc.config + +_Py_DECLARE_STR(anon_unknown, ""); /* Forward declaration */ static void tracemalloc_stop(void); @@ -29,19 +32,14 @@ static void raw_free(void *ptr); #define TO_PTR(key) ((const void *)(uintptr_t)(key)) #define FROM_PTR(key) ((uintptr_t)(key)) -/* Protected by the GIL */ -static struct { - PyMemAllocatorEx mem; - PyMemAllocatorEx raw; - PyMemAllocatorEx obj; -} allocators; +#define allocators _PyRuntime.tracemalloc.allocators #if defined(TRACE_RAW_MALLOC) /* This lock is needed because tracemalloc_free() is called without the GIL held from PyMem_RawFree(). It cannot acquire the lock because it would introduce a deadlock in _PyThreadState_DeleteCurrent(). */ -static PyThread_type_lock tables_lock; +# define tables_lock _PyRuntime.tracemalloc.tables_lock # define TABLES_LOCK() PyThread_acquire_lock(tables_lock, 1) # define TABLES_UNLOCK() PyThread_release_lock(tables_lock) #else @@ -53,33 +51,8 @@ static PyThread_type_lock tables_lock; #define DEFAULT_DOMAIN 0 -/* Pack the frame_t structure to reduce the memory footprint on 64-bit - architectures: 12 bytes instead of 16. */ -typedef struct -#ifdef __GNUC__ -__attribute__((packed)) -#elif defined(_MSC_VER) -#pragma pack(push, 4) -#endif -{ - /* filename cannot be NULL: "" is used if the Python frame - filename is NULL */ - PyObject *filename; - unsigned int lineno; -} frame_t; -#ifdef _MSC_VER -#pragma pack(pop) -#endif - - -typedef struct { - Py_uhash_t hash; - /* Number of frames stored */ - uint16_t nframe; - /* Total number of frames the traceback had */ - uint16_t total_nframe; - frame_t frames[1]; -} traceback_t; +typedef struct tracemalloc_frame frame_t; +typedef struct tracemalloc_traceback traceback_t; #define TRACEBACK_SIZE(NFRAME) \ (sizeof(traceback_t) + sizeof(frame_t) * (NFRAME - 1)) @@ -90,8 +63,8 @@ typedef struct { static const unsigned long MAX_NFRAME = Py_MIN(UINT16_MAX, ((SIZE_MAX - sizeof(traceback_t)) / sizeof(frame_t) + 1)); -static PyObject *unknown_filename = NULL; -static traceback_t tracemalloc_empty_traceback; +#define tracemalloc_empty_traceback _PyRuntime.tracemalloc.empty_traceback + /* Trace of a memory block */ typedef struct { @@ -103,35 +76,13 @@ typedef struct { } trace_t; -/* Size in bytes of currently traced memory. - Protected by TABLES_LOCK(). */ -static size_t tracemalloc_traced_memory = 0; - -/* Peak size in bytes of traced memory. - Protected by TABLES_LOCK(). */ -static size_t tracemalloc_peak_traced_memory = 0; - -/* Hash table used as a set to intern filenames: - PyObject* => PyObject*. - Protected by the GIL */ -static _Py_hashtable_t *tracemalloc_filenames = NULL; - -/* Buffer to store a new traceback in traceback_new(). - Protected by the GIL. */ -static traceback_t *tracemalloc_traceback = NULL; - -/* Hash table used as a set to intern tracebacks: - traceback_t* => traceback_t* - Protected by the GIL */ -static _Py_hashtable_t *tracemalloc_tracebacks = NULL; - -/* pointer (void*) => trace (trace_t*). - Protected by TABLES_LOCK(). */ -static _Py_hashtable_t *tracemalloc_traces = NULL; - -/* domain (unsigned int) => traces (_Py_hashtable_t). - Protected by TABLES_LOCK(). */ -static _Py_hashtable_t *tracemalloc_domains = NULL; +#define tracemalloc_traced_memory _PyRuntime.tracemalloc.traced_memory +#define tracemalloc_peak_traced_memory _PyRuntime.tracemalloc.peak_traced_memory +#define tracemalloc_filenames _PyRuntime.tracemalloc.filenames +#define tracemalloc_traceback _PyRuntime.tracemalloc.traceback +#define tracemalloc_tracebacks _PyRuntime.tracemalloc.tracebacks +#define tracemalloc_traces _PyRuntime.tracemalloc.traces +#define tracemalloc_domains _PyRuntime.tracemalloc.domains #ifdef TRACE_DEBUG @@ -152,7 +103,7 @@ tracemalloc_error(const char *format, ...) #if defined(TRACE_RAW_MALLOC) #define REENTRANT_THREADLOCAL -static Py_tss_t tracemalloc_reentrant_key = Py_tss_NEEDS_INIT; +#define tracemalloc_reentrant_key _PyRuntime.tracemalloc.reentrant_key /* Any non-NULL pointer can be used */ #define REENTRANT Py_True @@ -302,10 +253,10 @@ hashtable_compare_traceback(const void *key1, const void *key2) static void -tracemalloc_get_frame(InterpreterFrame *pyframe, frame_t *frame) +tracemalloc_get_frame(_PyInterpreterFrame *pyframe, frame_t *frame) { - frame->filename = unknown_filename; - int lineno = PyCode_Addr2Line(pyframe->f_code, pyframe->f_lasti*sizeof(_Py_CODEUNIT)); + frame->filename = &_Py_STR(anon_unknown); + int lineno = _PyInterpreterFrame_GetLine(pyframe); if (lineno < 0) { lineno = 0; } @@ -344,8 +295,8 @@ tracemalloc_get_frame(InterpreterFrame *pyframe, frame_t *frame) else { /* tracemalloc_filenames is responsible to keep a reference to the filename */ - Py_INCREF(filename); - if (_Py_hashtable_set(tracemalloc_filenames, filename, NULL) < 0) { + if (_Py_hashtable_set(tracemalloc_filenames, Py_NewRef(filename), + NULL) < 0) { Py_DECREF(filename); #ifdef TRACE_DEBUG tracemalloc_error("failed to intern the filename"); @@ -396,9 +347,9 @@ traceback_get_frames(traceback_t *traceback) return; } - InterpreterFrame *pyframe = tstate->cframe->current_frame; - for (; pyframe != NULL;) { - if (traceback->nframe < _Py_tracemalloc_config.max_nframe) { + _PyInterpreterFrame *pyframe = _PyThreadState_GetFrame(tstate); + while (pyframe) { + if (traceback->nframe < tracemalloc_config.max_nframe) { tracemalloc_get_frame(pyframe, &traceback->frames[traceback->nframe]); assert(traceback->frames[traceback->nframe].filename != NULL); traceback->nframe++; @@ -406,9 +357,7 @@ traceback_get_frames(traceback_t *traceback) if (traceback->total_nframe < UINT16_MAX) { traceback->total_nframe++; } - - InterpreterFrame *back = pyframe->previous; - pyframe = back; + pyframe = _PyFrame_GetFirstComplete(pyframe->previous); } } @@ -497,7 +446,7 @@ tracemalloc_get_traces_table(unsigned int domain) static void tracemalloc_remove_trace(unsigned int domain, uintptr_t ptr) { - assert(_Py_tracemalloc_config.tracing); + assert(tracemalloc_config.tracing); _Py_hashtable_t *traces = tracemalloc_get_traces_table(domain); if (!traces) { @@ -521,7 +470,7 @@ static int tracemalloc_add_trace(unsigned int domain, uintptr_t ptr, size_t size) { - assert(_Py_tracemalloc_config.tracing); + assert(tracemalloc_config.tracing); traceback_t *traceback = traceback_new(); if (traceback == NULL) { @@ -855,13 +804,13 @@ tracemalloc_clear_traces(void) static int tracemalloc_init(void) { - if (_Py_tracemalloc_config.initialized == TRACEMALLOC_FINALIZED) { + if (tracemalloc_config.initialized == TRACEMALLOC_FINALIZED) { PyErr_SetString(PyExc_RuntimeError, "the tracemalloc module has been unloaded"); return -1; } - if (_Py_tracemalloc_config.initialized == TRACEMALLOC_INITIALIZED) + if (tracemalloc_config.initialized == TRACEMALLOC_INITIALIZED) return 0; PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw); @@ -904,19 +853,14 @@ tracemalloc_init(void) return -1; } - unknown_filename = PyUnicode_FromString(""); - if (unknown_filename == NULL) - return -1; - PyUnicode_InternInPlace(&unknown_filename); - tracemalloc_empty_traceback.nframe = 1; tracemalloc_empty_traceback.total_nframe = 1; /* borrowed reference */ - tracemalloc_empty_traceback.frames[0].filename = unknown_filename; + tracemalloc_empty_traceback.frames[0].filename = &_Py_STR(anon_unknown); tracemalloc_empty_traceback.frames[0].lineno = 0; tracemalloc_empty_traceback.hash = traceback_hash(&tracemalloc_empty_traceback); - _Py_tracemalloc_config.initialized = TRACEMALLOC_INITIALIZED; + tracemalloc_config.initialized = TRACEMALLOC_INITIALIZED; return 0; } @@ -924,9 +868,9 @@ tracemalloc_init(void) static void tracemalloc_deinit(void) { - if (_Py_tracemalloc_config.initialized != TRACEMALLOC_INITIALIZED) + if (tracemalloc_config.initialized != TRACEMALLOC_INITIALIZED) return; - _Py_tracemalloc_config.initialized = TRACEMALLOC_FINALIZED; + tracemalloc_config.initialized = TRACEMALLOC_FINALIZED; tracemalloc_stop(); @@ -946,8 +890,6 @@ tracemalloc_deinit(void) #ifdef REENTRANT_THREADLOCAL PyThread_tss_delete(&tracemalloc_reentrant_key); #endif - - Py_XDECREF(unknown_filename); } @@ -968,12 +910,12 @@ tracemalloc_start(int max_nframe) return -1; } - if (_Py_tracemalloc_config.tracing) { + if (tracemalloc_config.tracing) { /* hook already installed: do nothing */ return 0; } - _Py_tracemalloc_config.max_nframe = max_nframe; + tracemalloc_config.max_nframe = max_nframe; /* allocate a buffer to store a new traceback */ size = TRACEBACK_SIZE(max_nframe); @@ -1009,7 +951,7 @@ tracemalloc_start(int max_nframe) PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc); /* everything is ready: start tracing Python memory allocations */ - _Py_tracemalloc_config.tracing = 1; + tracemalloc_config.tracing = 1; return 0; } @@ -1018,11 +960,11 @@ tracemalloc_start(int max_nframe) static void tracemalloc_stop(void) { - if (!_Py_tracemalloc_config.tracing) + if (!tracemalloc_config.tracing) return; /* stop tracing Python memory allocations */ - _Py_tracemalloc_config.tracing = 0; + tracemalloc_config.tracing = 0; /* unregister the hook on memory allocators */ #ifdef TRACE_RAW_MALLOC @@ -1050,7 +992,7 @@ static PyObject * _tracemalloc_is_tracing_impl(PyObject *module) /*[clinic end generated code: output=2d763b42601cd3ef input=af104b0a00192f63]*/ { - return PyBool_FromLong(_Py_tracemalloc_config.tracing); + return PyBool_FromLong(tracemalloc_config.tracing); } @@ -1064,7 +1006,7 @@ static PyObject * _tracemalloc_clear_traces_impl(PyObject *module) /*[clinic end generated code: output=a86080ee41b84197 input=0dab5b6c785183a5]*/ { - if (!_Py_tracemalloc_config.tracing) + if (!tracemalloc_config.tracing) Py_RETURN_NONE; set_reentrant(1); @@ -1084,8 +1026,7 @@ frame_to_pyobject(frame_t *frame) if (frame_obj == NULL) return NULL; - Py_INCREF(frame->filename); - PyTuple_SET_ITEM(frame_obj, 0, frame->filename); + PyTuple_SET_ITEM(frame_obj, 0, Py_NewRef(frame->filename)); lineno_obj = PyLong_FromUnsignedLong(frame->lineno); if (lineno_obj == NULL) { @@ -1106,8 +1047,7 @@ traceback_to_pyobject(traceback_t *traceback, _Py_hashtable_t *intern_table) if (intern_table != NULL) { frames = _Py_hashtable_get(intern_table, (const void *)traceback); if (frames) { - Py_INCREF(frames); - return frames; + return Py_NewRef(frames); } } @@ -1241,6 +1181,9 @@ tracemalloc_copy_domain(_Py_hashtable_t *domains, _Py_hashtable_t *traces = (_Py_hashtable_t *)value; _Py_hashtable_t *traces2 = tracemalloc_copy_traces(traces); + if (traces2 == NULL) { + return -1; + } if (_Py_hashtable_set(domains2, TO_PTR(domain), traces2) < 0) { _Py_hashtable_destroy(traces2); return -1; @@ -1343,7 +1286,7 @@ _tracemalloc__get_traces_impl(PyObject *module) if (get_traces.list == NULL) goto error; - if (!_Py_tracemalloc_config.tracing) + if (!tracemalloc_config.tracing) return get_traces.list; /* the traceback hash table is used temporarily to intern traceback tuple @@ -1416,7 +1359,7 @@ static traceback_t* tracemalloc_get_traceback(unsigned int domain, uintptr_t ptr) { - if (!_Py_tracemalloc_config.tracing) + if (!tracemalloc_config.tracing) return NULL; trace_t *trace; @@ -1496,7 +1439,7 @@ _PyMem_DumpTraceback(int fd, const void *ptr) traceback_t *traceback; int i; - if (!_Py_tracemalloc_config.tracing) { + if (!tracemalloc_config.tracing) { PUTS(fd, "Enable tracemalloc to get the memory block " "allocation traceback\n\n"); return; @@ -1570,7 +1513,7 @@ static PyObject * _tracemalloc_get_traceback_limit_impl(PyObject *module) /*[clinic end generated code: output=d556d9306ba95567 input=da3cd977fc68ae3b]*/ { - return PyLong_FromLong(_Py_tracemalloc_config.max_nframe); + return PyLong_FromLong(tracemalloc_config.max_nframe); } @@ -1628,7 +1571,7 @@ _tracemalloc_get_traced_memory_impl(PyObject *module) { Py_ssize_t size, peak_size; - if (!_Py_tracemalloc_config.tracing) + if (!tracemalloc_config.tracing) return Py_BuildValue("ii", 0, 0); TABLES_LOCK(); @@ -1652,7 +1595,7 @@ static PyObject * _tracemalloc_reset_peak_impl(PyObject *module) /*[clinic end generated code: output=140c2870f691dbb2 input=18afd0635066e9ce]*/ { - if (!_Py_tracemalloc_config.tracing) { + if (!tracemalloc_config.tracing) { Py_RETURN_NONE; } @@ -1733,7 +1676,7 @@ PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, int res; PyGILState_STATE gil_state; - if (!_Py_tracemalloc_config.tracing) { + if (!tracemalloc_config.tracing) { /* tracemalloc is not tracing: do nothing */ return -2; } @@ -1752,7 +1695,7 @@ PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, int PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr) { - if (!_Py_tracemalloc_config.tracing) { + if (!tracemalloc_config.tracing) { /* tracemalloc is not tracing: do nothing */ return -2; } @@ -1775,7 +1718,7 @@ _PyTraceMalloc_NewReference(PyObject *op) { assert(PyGILState_Check()); - if (!_Py_tracemalloc_config.tracing) { + if (!tracemalloc_config.tracing) { /* tracemalloc is not tracing: do nothing */ return -1; } diff --git a/Modules/_typingmodule.c b/Modules/_typingmodule.c index 8b6faa646d6..262dddb63fd 100644 --- a/Modules/_typingmodule.c +++ b/Modules/_typingmodule.c @@ -23,8 +23,7 @@ static PyObject * _typing__idfunc(PyObject *module, PyObject *x) /*[clinic end generated code: output=63c38be4a6ec5f2c input=49f17284b43de451]*/ { - Py_INCREF(x); - return x; + return Py_NewRef(x); } diff --git a/Modules/_uuidmodule.c b/Modules/_uuidmodule.c index 3f33e22a055..eae38f5c98c 100644 --- a/Modules/_uuidmodule.c +++ b/Modules/_uuidmodule.c @@ -6,10 +6,12 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" -#ifdef HAVE_UUID_UUID_H -#include -#elif defined(HAVE_UUID_H) -#include +#if defined(HAVE_UUID_H) + // AIX, FreeBSD, libuuid with pkgconf + #include +#elif defined(HAVE_UUID_UUID_H) + // libuuid without pkgconf + #include #endif #ifdef MS_WINDOWS diff --git a/Modules/_weakref.c b/Modules/_weakref.c index e33cba2a3dd..157a852ae9a 100644 --- a/Modules/_weakref.c +++ b/Modules/_weakref.c @@ -28,7 +28,7 @@ _weakref_getweakrefcount_impl(PyObject *module, PyObject *object) { PyWeakReference **list; - if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) + if (!_PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) return 0; list = GET_WEAKREFS_LISTPTR(object); @@ -76,16 +76,21 @@ _weakref__remove_dead_weakref_impl(PyObject *module, PyObject *dct, } -PyDoc_STRVAR(weakref_getweakrefs__doc__, -"getweakrefs(object) -- return a list of all weak reference objects\n" -"that point to 'object'."); +/*[clinic input] +_weakref.getweakrefs + object: object + / + +Return a list of all weak reference objects pointing to 'object'. +[clinic start generated code]*/ static PyObject * -weakref_getweakrefs(PyObject *self, PyObject *object) +_weakref_getweakrefs(PyObject *module, PyObject *object) +/*[clinic end generated code: output=25c7731d8e011824 input=00c6d0e5d3206693]*/ { PyObject *result = NULL; - if (PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) { + if (_PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) { PyWeakReference **list = GET_WEAKREFS_LISTPTR(object); Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list); @@ -107,22 +112,24 @@ weakref_getweakrefs(PyObject *self, PyObject *object) } -PyDoc_STRVAR(weakref_proxy__doc__, -"proxy(object[, callback]) -- create a proxy object that weakly\n" -"references 'object'. 'callback', if given, is called with a\n" -"reference to the proxy when 'object' is about to be finalized."); +/*[clinic input] + +_weakref.proxy + object: object + callback: object(c_default="NULL") = None + / + +Create a proxy object that weakly references 'object'. + +'callback', if given, is called with a reference to the +proxy when 'object' is about to be finalized. +[clinic start generated code]*/ static PyObject * -weakref_proxy(PyObject *self, PyObject *args) +_weakref_proxy_impl(PyObject *module, PyObject *object, PyObject *callback) +/*[clinic end generated code: output=d68fa4ad9ea40519 input=4808adf22fd137e7]*/ { - PyObject *object; - PyObject *callback = NULL; - PyObject *result = NULL; - - if (PyArg_UnpackTuple(args, "proxy", 1, 2, &object, &callback)) { - result = PyWeakref_NewProxy(object, callback); - } - return result; + return PyWeakref_NewProxy(object, callback); } @@ -130,10 +137,8 @@ static PyMethodDef weakref_functions[] = { _WEAKREF_GETWEAKREFCOUNT_METHODDEF _WEAKREF__REMOVE_DEAD_WEAKREF_METHODDEF - {"getweakrefs", weakref_getweakrefs, METH_O, - weakref_getweakrefs__doc__}, - {"proxy", weakref_proxy, METH_VARARGS, - weakref_proxy__doc__}, + _WEAKREF_GETWEAKREFS_METHODDEF + _WEAKREF_PROXY_METHODDEF {NULL, NULL, 0, NULL} }; diff --git a/Modules/_winapi.c b/Modules/_winapi.c index 3e24d512cac..f4d982b15d4 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -291,8 +291,7 @@ _winapi_Overlapped_getbuffer_impl(OverlappedObject *self) return NULL; } res = self->read_buffer ? self->read_buffer : Py_None; - Py_INCREF(res); - return res; + return Py_NewRef(res); } /*[clinic input] @@ -405,13 +404,13 @@ _winapi_CloseHandle_impl(PyObject *module, HANDLE handle) _winapi.ConnectNamedPipe handle: HANDLE - overlapped as use_overlapped: bool(accept={int}) = False + overlapped as use_overlapped: bool = False [clinic start generated code]*/ static PyObject * _winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle, int use_overlapped) -/*[clinic end generated code: output=335a0e7086800671 input=34f937c1c86e5e68]*/ +/*[clinic end generated code: output=335a0e7086800671 input=a80e56e8bd370e31]*/ { BOOL success; OverlappedObject *overlapped = NULL; @@ -1089,14 +1088,6 @@ _winapi_CreateProcess_impl(PyObject *module, return NULL; } - PyInterpreterState *interp = PyInterpreterState_Get(); - const PyConfig *config = _PyInterpreterState_GetConfig(interp); - if (config->_isolated_interpreter) { - PyErr_SetString(PyExc_RuntimeError, - "subprocess not supported for isolated subinterpreters"); - return NULL; - } - ZeroMemory(&si, sizeof(si)); si.StartupInfo.cb = sizeof(si); @@ -1402,6 +1393,30 @@ _winapi_MapViewOfFile_impl(PyObject *module, HANDLE file_map, return address; } +/*[clinic input] +_winapi.UnmapViewOfFile + + address: LPCVOID + / +[clinic start generated code]*/ + +static PyObject * +_winapi_UnmapViewOfFile_impl(PyObject *module, LPCVOID address) +/*[clinic end generated code: output=4f7e18ac75d19744 input=8c4b6119ad9288a3]*/ +{ + BOOL success; + + Py_BEGIN_ALLOW_THREADS + success = UnmapViewOfFile(address); + Py_END_ALLOW_THREADS + + if (!success) { + return PyErr_SetFromWindowsErr(0); + } + + Py_RETURN_NONE; +} + /*[clinic input] _winapi.OpenFileMapping -> HANDLE @@ -1512,18 +1527,62 @@ _winapi_PeekNamedPipe_impl(PyObject *module, HANDLE handle, int size) } } +/*[clinic input] +_winapi.LCMapStringEx + + locale: LPCWSTR + flags: DWORD + src: LPCWSTR + +[clinic start generated code]*/ + +static PyObject * +_winapi_LCMapStringEx_impl(PyObject *module, LPCWSTR locale, DWORD flags, + LPCWSTR src) +/*[clinic end generated code: output=cf4713d80e2b47c9 input=9fe26f95d5ab0001]*/ +{ + if (flags & (LCMAP_SORTHANDLE | LCMAP_HASH | LCMAP_BYTEREV | + LCMAP_SORTKEY)) { + return PyErr_Format(PyExc_ValueError, "unsupported flags"); + } + + int dest_size = LCMapStringEx(locale, flags, src, -1, NULL, 0, + NULL, NULL, 0); + if (dest_size == 0) { + return PyErr_SetFromWindowsErr(0); + } + + wchar_t* dest = PyMem_NEW(wchar_t, dest_size); + if (dest == NULL) { + return PyErr_NoMemory(); + } + + int nmapped = LCMapStringEx(locale, flags, src, -1, dest, dest_size, + NULL, NULL, 0); + if (nmapped == 0) { + DWORD error = GetLastError(); + PyMem_DEL(dest); + return PyErr_SetFromWindowsErr(error); + } + + PyObject *ret = PyUnicode_FromWideChar(dest, dest_size - 1); + PyMem_DEL(dest); + + return ret; +} + /*[clinic input] _winapi.ReadFile handle: HANDLE size: DWORD - overlapped as use_overlapped: bool(accept={int}) = False + overlapped as use_overlapped: bool = False [clinic start generated code]*/ static PyObject * _winapi_ReadFile_impl(PyObject *module, HANDLE handle, DWORD size, int use_overlapped) -/*[clinic end generated code: output=d3d5b44a8201b944 input=08c439d03a11aac5]*/ +/*[clinic end generated code: output=d3d5b44a8201b944 input=4f82f8e909ad91ad]*/ { DWORD nread; PyObject *buf; @@ -1803,13 +1862,13 @@ _winapi.WriteFile handle: HANDLE buffer: object - overlapped as use_overlapped: bool(accept={int}) = False + overlapped as use_overlapped: bool = False [clinic start generated code]*/ static PyObject * _winapi_WriteFile_impl(PyObject *module, HANDLE handle, PyObject *buffer, int use_overlapped) -/*[clinic end generated code: output=2ca80f6bf3fa92e3 input=11eae2a03aa32731]*/ +/*[clinic end generated code: output=2ca80f6bf3fa92e3 input=2badb008c8a2e2a0]*/ { Py_buffer _buf, *buf; DWORD len, written; @@ -2023,9 +2082,11 @@ static PyMethodDef winapi_functions[] = { _WINAPI_OPENFILEMAPPING_METHODDEF _WINAPI_OPENPROCESS_METHODDEF _WINAPI_PEEKNAMEDPIPE_METHODDEF + _WINAPI_LCMAPSTRINGEX_METHODDEF _WINAPI_READFILE_METHODDEF _WINAPI_SETNAMEDPIPEHANDLESTATE_METHODDEF _WINAPI_TERMINATEPROCESS_METHODDEF + _WINAPI_UNMAPVIEWOFFILE_METHODDEF _WINAPI_VIRTUALQUERYSIZE_METHODDEF _WINAPI_WAITNAMEDPIPE_METHODDEF _WINAPI_WAITFORMULTIPLEOBJECTS_METHODDEF @@ -2160,6 +2221,22 @@ static int winapi_exec(PyObject *m) WINAPI_CONSTANT(F_DWORD, FILE_TYPE_PIPE); WINAPI_CONSTANT(F_DWORD, FILE_TYPE_REMOTE); + WINAPI_CONSTANT("u", LOCALE_NAME_INVARIANT); + WINAPI_CONSTANT(F_DWORD, LOCALE_NAME_MAX_LENGTH); + WINAPI_CONSTANT("u", LOCALE_NAME_SYSTEM_DEFAULT); + WINAPI_CONSTANT("u", LOCALE_NAME_USER_DEFAULT); + + WINAPI_CONSTANT(F_DWORD, LCMAP_FULLWIDTH); + WINAPI_CONSTANT(F_DWORD, LCMAP_HALFWIDTH); + WINAPI_CONSTANT(F_DWORD, LCMAP_HIRAGANA); + WINAPI_CONSTANT(F_DWORD, LCMAP_KATAKANA); + WINAPI_CONSTANT(F_DWORD, LCMAP_LINGUISTIC_CASING); + WINAPI_CONSTANT(F_DWORD, LCMAP_LOWERCASE); + WINAPI_CONSTANT(F_DWORD, LCMAP_SIMPLIFIED_CHINESE); + WINAPI_CONSTANT(F_DWORD, LCMAP_TITLECASE); + WINAPI_CONSTANT(F_DWORD, LCMAP_TRADITIONAL_CHINESE); + WINAPI_CONSTANT(F_DWORD, LCMAP_UPPERCASE); + WINAPI_CONSTANT("i", NULL); return 0; diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index 1507abf3114..0892fa3a959 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -6,12 +6,15 @@ #endif #include "Python.h" -#include "frameobject.h" +// XXX This module should not rely on internal API. #include "pycore_frame.h" #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_interpreteridobject.h" +#define MODULE_NAME "_xxsubinterpreters" + + static char * _copy_raw_string(PyObject *strobj) { @@ -29,13 +32,186 @@ _copy_raw_string(PyObject *strobj) } static PyInterpreterState * -_get_current(void) +_get_current_interp(void) { // PyInterpreterState_Get() aborts if lookup fails, so don't need // to check the result for NULL. return PyInterpreterState_Get(); } +static PyObject * +_get_current_module(void) +{ + // We ensured it was imported in _run_script(). + PyObject *name = PyUnicode_FromString(MODULE_NAME); + if (name == NULL) { + return NULL; + } + PyObject *mod = PyImport_GetModule(name); + Py_DECREF(name); + if (mod == NULL) { + return NULL; + } + assert(mod != Py_None); + return mod; +} + +static PyObject * +get_module_from_owned_type(PyTypeObject *cls) +{ + assert(cls != NULL); + return _get_current_module(); + // XXX Use the more efficient API now that we use heap types: + //return PyType_GetModule(cls); +} + +static struct PyModuleDef moduledef; + +static PyObject * +get_module_from_type(PyTypeObject *cls) +{ + assert(cls != NULL); + return _get_current_module(); + // XXX Use the more efficient API now that we use heap types: + //return PyType_GetModuleByDef(cls, &moduledef); +} + +static PyObject * +add_new_exception(PyObject *mod, const char *name, PyObject *base) +{ + assert(!PyObject_HasAttrString(mod, name)); + PyObject *exctype = PyErr_NewException(name, base, NULL); + if (exctype == NULL) { + return NULL; + } + int res = PyModule_AddType(mod, (PyTypeObject *)exctype); + if (res < 0) { + Py_DECREF(exctype); + return NULL; + } + return exctype; +} + +#define ADD_NEW_EXCEPTION(MOD, NAME, BASE) \ + add_new_exception(MOD, MODULE_NAME "." Py_STRINGIFY(NAME), BASE) + +static PyTypeObject * +add_new_type(PyObject *mod, PyType_Spec *spec, crossinterpdatafunc shared) +{ + PyTypeObject *cls = (PyTypeObject *)PyType_FromMetaclass( + NULL, mod, spec, NULL); + if (cls == NULL) { + return NULL; + } + if (PyModule_AddType(mod, cls) < 0) { + Py_DECREF(cls); + return NULL; + } + if (shared != NULL) { + if (_PyCrossInterpreterData_RegisterClass(cls, shared)) { + Py_DECREF(cls); + return NULL; + } + } + return cls; +} + +static int +_release_xid_data(_PyCrossInterpreterData *data, int ignoreexc) +{ + PyObject *exctype, *excval, *exctb; + if (ignoreexc) { + PyErr_Fetch(&exctype, &excval, &exctb); + } + int res = _PyCrossInterpreterData_Release(data); + if (res < 0) { + // XXX Fix this! + /* The owning interpreter is already destroyed. + * Ideally, this shouldn't ever happen. When an interpreter is + * about to be destroyed, we should clear out all of its objects + * from every channel associated with that interpreter. + * For now we hack around that to resolve refleaks, by decref'ing + * the released object here, even if its the wrong interpreter. + * The owning interpreter has already been destroyed + * so we should be okay, especially since the currently + * shareable types are all very basic, with no GC. + * That said, it becomes much messier once interpreters + * no longer share a GIL, so this needs to be fixed before then. */ + _PyCrossInterpreterData_Clear(NULL, data); + if (ignoreexc) { + // XXX Emit a warning? + PyErr_Clear(); + } + } + if (ignoreexc) { + PyErr_Restore(exctype, excval, exctb); + } + return res; +} + + +/* module state *************************************************************/ + +typedef struct { + PyTypeObject *ChannelIDType; + + /* interpreter exceptions */ + PyObject *RunFailedError; + + /* channel exceptions */ + PyObject *ChannelError; + PyObject *ChannelNotFoundError; + PyObject *ChannelClosedError; + PyObject *ChannelEmptyError; + PyObject *ChannelNotEmptyError; +} module_state; + +static inline module_state * +get_module_state(PyObject *mod) +{ + assert(mod != NULL); + module_state *state = PyModule_GetState(mod); + assert(state != NULL); + return state; +} + +static int +traverse_module_state(module_state *state, visitproc visit, void *arg) +{ + /* heap types */ + Py_VISIT(state->ChannelIDType); + + /* interpreter exceptions */ + Py_VISIT(state->RunFailedError); + + /* channel exceptions */ + Py_VISIT(state->ChannelError); + Py_VISIT(state->ChannelNotFoundError); + Py_VISIT(state->ChannelClosedError); + Py_VISIT(state->ChannelEmptyError); + Py_VISIT(state->ChannelNotEmptyError); + return 0; +} + +static int +clear_module_state(module_state *state) +{ + /* heap types */ + (void)_PyCrossInterpreterData_UnregisterClass(state->ChannelIDType); + Py_CLEAR(state->ChannelIDType); + + /* interpreter exceptions */ + Py_CLEAR(state->RunFailedError); + + /* channel exceptions */ + Py_CLEAR(state->ChannelError); + Py_CLEAR(state->ChannelNotFoundError); + Py_CLEAR(state->ChannelClosedError); + Py_CLEAR(state->ChannelEmptyError); + Py_CLEAR(state->ChannelNotEmptyError); + return 0; +} + /* data-sharing-specific code ***********************************************/ @@ -67,7 +243,7 @@ _sharednsitem_clear(struct _sharednsitem *item) PyMem_Free(item->name); item->name = NULL; } - _PyCrossInterpreterData_Release(&item->data); + (void)_release_xid_data(&item->data, 1); } static int @@ -122,8 +298,10 @@ _sharedns_free(_sharedns *shared) } static _sharedns * -_get_shared_ns(PyObject *shareable) +_get_shared_ns(PyObject *shareable, PyTypeObject *channelidtype, + int *needs_import) { + *needs_import = 0; if (shareable == NULL || shareable == Py_None) { return NULL; } @@ -145,6 +323,9 @@ _get_shared_ns(PyObject *shareable) if (_sharednsitem_init(&shared->items[i], key, value) != 0) { break; } + if (Py_TYPE(value) == channelidtype) { + *needs_import = 1; + } } if (PyErr_Occurred()) { _sharedns_free(shared); @@ -288,70 +469,99 @@ _sharedexception_apply(_sharedexception *exc, PyObject *wrapperclass) #define CHANNEL_BOTH 0 #define CHANNEL_RECV -1 -static PyObject *ChannelError; -static PyObject *ChannelNotFoundError; -static PyObject *ChannelClosedError; -static PyObject *ChannelEmptyError; -static PyObject *ChannelNotEmptyError; +/* channel errors */ + +#define ERR_CHANNEL_NOT_FOUND -2 +#define ERR_CHANNEL_CLOSED -3 +#define ERR_CHANNEL_INTERP_CLOSED -4 +#define ERR_CHANNEL_EMPTY -5 +#define ERR_CHANNEL_NOT_EMPTY -6 +#define ERR_CHANNEL_MUTEX_INIT -7 +#define ERR_CHANNELS_MUTEX_INIT -8 +#define ERR_NO_NEXT_CHANNEL_ID -9 static int -channel_exceptions_init(PyObject *ns) +channel_exceptions_init(PyObject *mod) { - // XXX Move the exceptions into per-module memory? + module_state *state = get_module_state(mod); + if (state == NULL) { + return -1; + } + +#define ADD(NAME, BASE) \ + do { \ + assert(state->NAME == NULL); \ + state->NAME = ADD_NEW_EXCEPTION(mod, NAME, BASE); \ + if (state->NAME == NULL) { \ + return -1; \ + } \ + } while (0) // A channel-related operation failed. - ChannelError = PyErr_NewException("_xxsubinterpreters.ChannelError", - PyExc_RuntimeError, NULL); - if (ChannelError == NULL) { - return -1; - } - if (PyDict_SetItemString(ns, "ChannelError", ChannelError) != 0) { - return -1; - } - + ADD(ChannelError, PyExc_RuntimeError); // An operation tried to use a channel that doesn't exist. - ChannelNotFoundError = PyErr_NewException( - "_xxsubinterpreters.ChannelNotFoundError", ChannelError, NULL); - if (ChannelNotFoundError == NULL) { - return -1; - } - if (PyDict_SetItemString(ns, "ChannelNotFoundError", ChannelNotFoundError) != 0) { - return -1; - } - + ADD(ChannelNotFoundError, state->ChannelError); // An operation tried to use a closed channel. - ChannelClosedError = PyErr_NewException( - "_xxsubinterpreters.ChannelClosedError", ChannelError, NULL); - if (ChannelClosedError == NULL) { - return -1; - } - if (PyDict_SetItemString(ns, "ChannelClosedError", ChannelClosedError) != 0) { - return -1; - } - + ADD(ChannelClosedError, state->ChannelError); // An operation tried to pop from an empty channel. - ChannelEmptyError = PyErr_NewException( - "_xxsubinterpreters.ChannelEmptyError", ChannelError, NULL); - if (ChannelEmptyError == NULL) { - return -1; - } - if (PyDict_SetItemString(ns, "ChannelEmptyError", ChannelEmptyError) != 0) { - return -1; - } - + ADD(ChannelEmptyError, state->ChannelError); // An operation tried to close a non-empty channel. - ChannelNotEmptyError = PyErr_NewException( - "_xxsubinterpreters.ChannelNotEmptyError", ChannelError, NULL); - if (ChannelNotEmptyError == NULL) { - return -1; - } - if (PyDict_SetItemString(ns, "ChannelNotEmptyError", ChannelNotEmptyError) != 0) { - return -1; - } + ADD(ChannelNotEmptyError, state->ChannelError); +#undef ADD return 0; } +static int +handle_channel_error(int err, PyObject *mod, int64_t cid) +{ + if (err == 0) { + assert(!PyErr_Occurred()); + return 0; + } + assert(err < 0); + module_state *state = get_module_state(mod); + assert(state != NULL); + if (err == ERR_CHANNEL_NOT_FOUND) { + PyErr_Format(state->ChannelNotFoundError, + "channel %" PRId64 " not found", cid); + } + else if (err == ERR_CHANNEL_CLOSED) { + PyErr_Format(state->ChannelClosedError, + "channel %" PRId64 " is closed", cid); + } + else if (err == ERR_CHANNEL_INTERP_CLOSED) { + PyErr_Format(state->ChannelClosedError, + "channel %" PRId64 " is already closed", cid); + } + else if (err == ERR_CHANNEL_EMPTY) { + PyErr_Format(state->ChannelEmptyError, + "channel %" PRId64 " is empty", cid); + } + else if (err == ERR_CHANNEL_NOT_EMPTY) { + PyErr_Format(state->ChannelNotEmptyError, + "channel %" PRId64 " may not be closed " + "if not empty (try force=True)", + cid); + } + else if (err == ERR_CHANNEL_MUTEX_INIT) { + PyErr_SetString(state->ChannelError, + "can't initialize mutex for new channel"); + } + else if (err == ERR_CHANNELS_MUTEX_INIT) { + PyErr_SetString(state->ChannelError, + "can't initialize mutex for channel management"); + } + else if (err == ERR_NO_NEXT_CHANNEL_ID) { + PyErr_SetString(state->ChannelError, + "failed to get a channel ID"); + } + else { + assert(PyErr_Occurred()); + } + return 1; +} + /* the channel queue */ struct _channelitem; @@ -378,7 +588,7 @@ static void _channelitem_clear(_channelitem *item) { if (item->data != NULL) { - _PyCrossInterpreterData_Release(item->data); + (void)_release_xid_data(item->data, 1); PyMem_Free(item->data); item->data = NULL; } @@ -622,8 +832,7 @@ _channelends_associate(_channelends *ends, int64_t interp, int send) interp, &prev); if (end != NULL) { if (!end->open) { - PyErr_SetString(ChannelClosedError, "channel already closed"); - return -1; + return ERR_CHANNEL_CLOSED; } // already associated return 0; @@ -722,19 +931,13 @@ typedef struct _channel { } _PyChannelState; static _PyChannelState * -_channel_new(void) +_channel_new(PyThread_type_lock mutex) { _PyChannelState *chan = PyMem_NEW(_PyChannelState, 1); if (chan == NULL) { return NULL; } - chan->mutex = PyThread_allocate_lock(); - if (chan->mutex == NULL) { - PyMem_Free(chan); - PyErr_SetString(ChannelError, - "can't initialize mutex for new channel"); - return NULL; - } + chan->mutex = mutex; chan->queue = _channelqueue_new(); if (chan->queue == NULL) { PyMem_Free(chan); @@ -772,10 +975,11 @@ _channel_add(_PyChannelState *chan, int64_t interp, PyThread_acquire_lock(chan->mutex, WAIT_LOCK); if (!chan->open) { - PyErr_SetString(ChannelClosedError, "channel closed"); + res = ERR_CHANNEL_CLOSED; goto done; } if (_channelends_associate(chan->ends, interp, 1) != 0) { + res = ERR_CHANNEL_INTERP_CLOSED; goto done; } @@ -789,31 +993,34 @@ done: return res; } -static _PyCrossInterpreterData * -_channel_next(_PyChannelState *chan, int64_t interp) +static int +_channel_next(_PyChannelState *chan, int64_t interp, + _PyCrossInterpreterData **res) { - _PyCrossInterpreterData *data = NULL; + int err = 0; PyThread_acquire_lock(chan->mutex, WAIT_LOCK); if (!chan->open) { - PyErr_SetString(ChannelClosedError, "channel closed"); + err = ERR_CHANNEL_CLOSED; goto done; } if (_channelends_associate(chan->ends, interp, 0) != 0) { + err = ERR_CHANNEL_INTERP_CLOSED; goto done; } - data = _channelqueue_get(chan->queue); + _PyCrossInterpreterData *data = _channelqueue_get(chan->queue); if (data == NULL && !PyErr_Occurred() && chan->closing != NULL) { chan->open = 0; } + *res = data; done: PyThread_release_lock(chan->mutex); if (chan->queue->count == 0) { _channel_finish_closing(chan); } - return data; + return err; } static int @@ -823,7 +1030,7 @@ _channel_close_interpreter(_PyChannelState *chan, int64_t interp, int end) int res = -1; if (!chan->open) { - PyErr_SetString(ChannelClosedError, "channel already closed"); + res = ERR_CHANNEL_CLOSED; goto done; } @@ -845,13 +1052,12 @@ _channel_close_all(_PyChannelState *chan, int end, int force) PyThread_acquire_lock(chan->mutex, WAIT_LOCK); if (!chan->open) { - PyErr_SetString(ChannelClosedError, "channel already closed"); + res = ERR_CHANNEL_CLOSED; goto done; } if (!force && chan->queue->count > 0) { - PyErr_SetString(ChannelNotEmptyError, - "may not be closed if not empty (try force=True)"); + res = ERR_CHANNEL_NOT_EMPTY; goto done; } @@ -936,21 +1142,24 @@ typedef struct _channels { int64_t next_id; } _channels; -static int -_channels_init(_channels *channels) +static void +_channels_init(_channels *channels, PyThread_type_lock mutex) { - if (channels->mutex == NULL) { - channels->mutex = PyThread_allocate_lock(); - if (channels->mutex == NULL) { - PyErr_SetString(ChannelError, - "can't initialize mutex for channel management"); - return -1; - } - } + channels->mutex = mutex; channels->head = NULL; channels->numopen = 0; channels->next_id = 0; - return 0; +} + +static void +_channels_fini(_channels *channels) +{ + assert(channels->numopen == 0); + assert(channels->head == NULL); + if (channels->mutex != NULL) { + PyThread_free_lock(channels->mutex); + channels->mutex = NULL; + } } static int64_t @@ -959,17 +1168,17 @@ _channels_next_id(_channels *channels) // needs lock int64_t id = channels->next_id; if (id < 0) { /* overflow */ - PyErr_SetString(ChannelError, - "failed to get a channel ID"); return -1; } channels->next_id += 1; return id; } -static _PyChannelState * -_channels_lookup(_channels *channels, int64_t id, PyThread_type_lock *pmutex) +static int +_channels_lookup(_channels *channels, int64_t id, PyThread_type_lock *pmutex, + _PyChannelState **res) { + int err = -1; _PyChannelState *chan = NULL; PyThread_acquire_lock(channels->mutex, WAIT_LOCK); if (pmutex != NULL) { @@ -978,11 +1187,11 @@ _channels_lookup(_channels *channels, int64_t id, PyThread_type_lock *pmutex) _channelref *ref = _channelref_find(channels->head, id, NULL); if (ref == NULL) { - PyErr_Format(ChannelNotFoundError, "channel %" PRId64 " not found", id); + err = ERR_CHANNEL_NOT_FOUND; goto done; } if (ref->chan == NULL || !ref->chan->open) { - PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", id); + err = ERR_CHANNEL_CLOSED; goto done; } @@ -992,11 +1201,14 @@ _channels_lookup(_channels *channels, int64_t id, PyThread_type_lock *pmutex) } chan = ref->chan; + err = 0; + done: if (pmutex == NULL || *pmutex == NULL) { PyThread_release_lock(channels->mutex); } - return chan; + *res = chan; + return err; } static int64_t @@ -1008,6 +1220,7 @@ _channels_add(_channels *channels, _PyChannelState *chan) // Create a new ref. int64_t id = _channels_next_id(channels); if (id < 0) { + cid = ERR_NO_NEXT_CHANNEL_ID; goto done; } _channelref *ref = _channelref_new(id, chan); @@ -1042,31 +1255,32 @@ _channels_close(_channels *channels, int64_t cid, _PyChannelState **pchan, _channelref *ref = _channelref_find(channels->head, cid, NULL); if (ref == NULL) { - PyErr_Format(ChannelNotFoundError, "channel %" PRId64 " not found", cid); + res = ERR_CHANNEL_NOT_FOUND; goto done; } if (ref->chan == NULL) { - PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", cid); + res = ERR_CHANNEL_CLOSED; goto done; } else if (!force && end == CHANNEL_SEND && ref->chan->closing != NULL) { - PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", cid); + res = ERR_CHANNEL_CLOSED; goto done; } else { - if (_channel_close_all(ref->chan, end, force) != 0) { - if (end == CHANNEL_SEND && - PyErr_ExceptionMatches(ChannelNotEmptyError)) { + int err = _channel_close_all(ref->chan, end, force); + if (err != 0) { + if (end == CHANNEL_SEND && err == ERR_CHANNEL_NOT_EMPTY) { if (ref->chan->closing != NULL) { - PyErr_Format(ChannelClosedError, - "channel %" PRId64 " closed", cid); + res = ERR_CHANNEL_CLOSED; goto done; } // Mark the channel as closing and return. The channel // will be cleaned up in _channel_next(). PyErr_Clear(); - if (_channel_set_closing(ref, channels->mutex) != 0) { + int err = _channel_set_closing(ref, channels->mutex); + if (err != 0) { + res = err; goto done; } if (pchan != NULL) { @@ -1074,6 +1288,9 @@ _channels_close(_channels *channels, int64_t cid, _PyChannelState **pchan, } res = 0; } + else { + res = err; + } goto done; } if (pchan != NULL) { @@ -1122,7 +1339,7 @@ _channels_remove(_channels *channels, int64_t id, _PyChannelState **pchan) _channelref *prev = NULL; _channelref *ref = _channelref_find(channels->head, id, &prev); if (ref == NULL) { - PyErr_Format(ChannelNotFoundError, "channel %" PRId64 " not found", id); + res = ERR_CHANNEL_NOT_FOUND; goto done; } @@ -1142,7 +1359,7 @@ _channels_add_id_object(_channels *channels, int64_t id) _channelref *ref = _channelref_find(channels->head, id, NULL); if (ref == NULL) { - PyErr_Format(ChannelNotFoundError, "channel %" PRId64 " not found", id); + res = ERR_CHANNEL_NOT_FOUND; goto done; } ref->objcount += 1; @@ -1216,7 +1433,7 @@ _channel_set_closing(struct _channelref *ref, PyThread_type_lock mutex) { int res = -1; PyThread_acquire_lock(chan->mutex, WAIT_LOCK); if (chan->closing != NULL) { - PyErr_SetString(ChannelClosedError, "channel closed"); + res = ERR_CHANNEL_CLOSED; goto done; } chan->closing = PyMem_NEW(struct _channel_closing, 1); @@ -1259,14 +1476,18 @@ _channel_finish_closing(struct _channel *chan) { static int64_t _channel_create(_channels *channels) { - _PyChannelState *chan = _channel_new(); + PyThread_type_lock mutex = PyThread_allocate_lock(); + if (mutex == NULL) { + return ERR_CHANNEL_MUTEX_INIT; + } + _PyChannelState *chan = _channel_new(mutex); if (chan == NULL) { + PyThread_free_lock(mutex); return -1; } int64_t id = _channels_add(channels, chan); if (id < 0) { _channel_free(chan); - return -1; } return id; } @@ -1275,8 +1496,9 @@ static int _channel_destroy(_channels *channels, int64_t id) { _PyChannelState *chan = NULL; - if (_channels_remove(channels, id, &chan) != 0) { - return -1; + int err = _channels_remove(channels, id, &chan); + if (err != 0) { + return err; } if (chan != NULL) { _channel_free(chan); @@ -1287,23 +1509,24 @@ _channel_destroy(_channels *channels, int64_t id) static int _channel_send(_channels *channels, int64_t id, PyObject *obj) { - PyInterpreterState *interp = _get_current(); + PyInterpreterState *interp = _get_current_interp(); if (interp == NULL) { return -1; } // Look up the channel. PyThread_type_lock mutex = NULL; - _PyChannelState *chan = _channels_lookup(channels, id, &mutex); - if (chan == NULL) { - return -1; + _PyChannelState *chan = NULL; + int err = _channels_lookup(channels, id, &mutex, &chan); + if (err != 0) { + return err; } + assert(chan != NULL); // Past this point we are responsible for releasing the mutex. if (chan->closing != NULL) { - PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", id); PyThread_release_lock(mutex); - return -1; + return ERR_CHANNEL_CLOSED; } // Convert the object to cross-interpreter data. @@ -1322,61 +1545,87 @@ _channel_send(_channels *channels, int64_t id, PyObject *obj) int res = _channel_add(chan, PyInterpreterState_GetID(interp), data); PyThread_release_lock(mutex); if (res != 0) { - _PyCrossInterpreterData_Release(data); + // We may chain an exception here: + (void)_release_xid_data(data, 0); PyMem_Free(data); - return -1; + return res; } return 0; } -static PyObject * -_channel_recv(_channels *channels, int64_t id) +static int +_channel_recv(_channels *channels, int64_t id, PyObject **res) { - PyInterpreterState *interp = _get_current(); + int err; + *res = NULL; + + PyInterpreterState *interp = _get_current_interp(); if (interp == NULL) { - return NULL; + // XXX Is this always an error? + if (PyErr_Occurred()) { + return -1; + } + return 0; } // Look up the channel. PyThread_type_lock mutex = NULL; - _PyChannelState *chan = _channels_lookup(channels, id, &mutex); - if (chan == NULL) { - return NULL; + _PyChannelState *chan = NULL; + err = _channels_lookup(channels, id, &mutex, &chan); + if (err != 0) { + return err; } + assert(chan != NULL); // Past this point we are responsible for releasing the mutex. // Pop off the next item from the channel. - _PyCrossInterpreterData *data = _channel_next(chan, PyInterpreterState_GetID(interp)); + _PyCrossInterpreterData *data = NULL; + err = _channel_next(chan, PyInterpreterState_GetID(interp), &data); PyThread_release_lock(mutex); - if (data == NULL) { - return NULL; + if (err != 0) { + return err; + } + else if (data == NULL) { + assert(!PyErr_Occurred()); + return 0; } // Convert the data back to an object. PyObject *obj = _PyCrossInterpreterData_NewObject(data); - _PyCrossInterpreterData_Release(data); - PyMem_Free(data); if (obj == NULL) { - return NULL; + assert(PyErr_Occurred()); + (void)_release_xid_data(data, 1); + PyMem_Free(data); + return -1; + } + int release_res = _release_xid_data(data, 0); + PyMem_Free(data); + if (release_res < 0) { + // The source interpreter has been destroyed already. + assert(PyErr_Occurred()); + Py_DECREF(obj); + return -1; } - return obj; + *res = obj; + return 0; } static int _channel_drop(_channels *channels, int64_t id, int send, int recv) { - PyInterpreterState *interp = _get_current(); + PyInterpreterState *interp = _get_current_interp(); if (interp == NULL) { return -1; } // Look up the channel. PyThread_type_lock mutex = NULL; - _PyChannelState *chan = _channels_lookup(channels, id, &mutex); - if (chan == NULL) { - return -1; + _PyChannelState *chan = NULL; + int err = _channels_lookup(channels, id, &mutex, &chan); + if (err != 0) { + return err; } // Past this point we are responsible for releasing the mutex. @@ -1396,12 +1645,13 @@ static int _channel_is_associated(_channels *channels, int64_t cid, int64_t interp, int send) { - _PyChannelState *chan = _channels_lookup(channels, cid, NULL); - if (chan == NULL) { - return -1; - } else if (send && chan->closing != NULL) { - PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", cid); - return -1; + _PyChannelState *chan = NULL; + int err = _channels_lookup(channels, cid, NULL, &chan); + if (err != 0) { + return err; + } + else if (send && chan->closing != NULL) { + return ERR_CHANNEL_CLOSED; } _channelend *end = _channelend_find(send ? chan->ends->send : chan->ends->recv, @@ -1412,8 +1662,6 @@ _channel_is_associated(_channels *channels, int64_t cid, int64_t interp, /* ChannelID class */ -static PyTypeObject ChannelIDtype; - typedef struct channelid { PyObject_HEAD int64_t id; @@ -1422,11 +1670,19 @@ typedef struct channelid { _channels *channels; } channelid; +struct channel_id_converter_data { + PyObject *module; + int64_t cid; +}; + static int channel_id_converter(PyObject *arg, void *ptr) { int64_t cid; - if (PyObject_TypeCheck(arg, &ChannelIDtype)) { + struct channel_id_converter_data *data = ptr; + module_state *state = get_module_state(data->module); + assert(state != NULL); + if (PyObject_TypeCheck(arg, state->ChannelIDType)) { cid = ((channelid *)arg)->id; } else if (PyIndex_Check(arg)) { @@ -1446,51 +1702,62 @@ channel_id_converter(PyObject *arg, void *ptr) Py_TYPE(arg)->tp_name); return 0; } - *(int64_t *)ptr = cid; + data->cid = cid; return 1; } -static channelid * +static int newchannelid(PyTypeObject *cls, int64_t cid, int end, _channels *channels, - int force, int resolve) + int force, int resolve, channelid **res) { + *res = NULL; + channelid *self = PyObject_New(channelid, cls); if (self == NULL) { - return NULL; + return -1; } self->id = cid; self->end = end; self->resolve = resolve; self->channels = channels; - if (_channels_add_id_object(channels, cid) != 0) { - if (force && PyErr_ExceptionMatches(ChannelNotFoundError)) { - PyErr_Clear(); + int err = _channels_add_id_object(channels, cid); + if (err != 0) { + if (force && err == ERR_CHANNEL_NOT_FOUND) { + assert(!PyErr_Occurred()); } else { Py_DECREF((PyObject *)self); - return NULL; + return err; } } - return self; + *res = self; + return 0; } static _channels * _global_channels(void); static PyObject * -channelid_new(PyTypeObject *cls, PyObject *args, PyObject *kwds) +_channelid_new(PyObject *mod, PyTypeObject *cls, + PyObject *args, PyObject *kwds) { static char *kwlist[] = {"id", "send", "recv", "force", "_resolve", NULL}; int64_t cid; + struct channel_id_converter_data cid_data = { + .module = mod, + }; int send = -1; int recv = -1; int force = 0; int resolve = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|$pppp:ChannelID.__new__", kwlist, - channel_id_converter, &cid, &send, &recv, &force, &resolve)) + channel_id_converter, &cid_data, + &send, &recv, &force, &resolve)) { return NULL; + } + cid = cid_data.cid; // Handle "send" and "recv". if (send == 0 && recv == 0) { @@ -1509,16 +1776,33 @@ channelid_new(PyTypeObject *cls, PyObject *args, PyObject *kwds) end = CHANNEL_RECV; } - return (PyObject *)newchannelid(cls, cid, end, _global_channels(), - force, resolve); + PyObject *id = NULL; + int err = newchannelid(cls, cid, end, _global_channels(), + force, resolve, + (channelid **)&id); + if (handle_channel_error(err, mod, cid)) { + assert(id == NULL); + return NULL; + } + assert(id != NULL); + return id; } static void -channelid_dealloc(PyObject *v) +channelid_dealloc(PyObject *self) { - int64_t cid = ((channelid *)v)->id; - _channels *channels = ((channelid *)v)->channels; - Py_TYPE(v)->tp_free(v); + int64_t cid = ((channelid *)self)->id; + _channels *channels = ((channelid *)self)->channels; + + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free(self); + /* "Instances of heap-allocated types hold a reference to their type." + * See: https://docs.python.org/3.11/howto/isolating-extensions.html#garbage-collection-protocol + * See: https://docs.python.org/3.11/c-api/typeobj.html#c.PyTypeObject.tp_traverse + */ + // XXX Why don't we implement Py_TPFLAGS_HAVE_GC, e.g. Py_tp_traverse, + // like we do for _abc._abc_data? + Py_DECREF(tp); _channels_drop_id_object(channels, cid); } @@ -1557,46 +1841,6 @@ channelid_int(PyObject *self) return PyLong_FromLongLong(cid->id); } -static PyNumberMethods channelid_as_number = { - 0, /* nb_add */ - 0, /* nb_subtract */ - 0, /* nb_multiply */ - 0, /* nb_remainder */ - 0, /* nb_divmod */ - 0, /* nb_power */ - 0, /* nb_negative */ - 0, /* nb_positive */ - 0, /* nb_absolute */ - 0, /* nb_bool */ - 0, /* nb_invert */ - 0, /* nb_lshift */ - 0, /* nb_rshift */ - 0, /* nb_and */ - 0, /* nb_xor */ - 0, /* nb_or */ - (unaryfunc)channelid_int, /* nb_int */ - 0, /* nb_reserved */ - 0, /* nb_float */ - - 0, /* nb_inplace_add */ - 0, /* nb_inplace_subtract */ - 0, /* nb_inplace_multiply */ - 0, /* nb_inplace_remainder */ - 0, /* nb_inplace_power */ - 0, /* nb_inplace_lshift */ - 0, /* nb_inplace_rshift */ - 0, /* nb_inplace_and */ - 0, /* nb_inplace_xor */ - 0, /* nb_inplace_or */ - - 0, /* nb_floor_divide */ - 0, /* nb_true_divide */ - 0, /* nb_inplace_floor_divide */ - 0, /* nb_inplace_true_divide */ - - (unaryfunc)channelid_int, /* nb_index */ -}; - static Py_hash_t channelid_hash(PyObject *self) { @@ -1613,17 +1857,28 @@ channelid_hash(PyObject *self) static PyObject * channelid_richcompare(PyObject *self, PyObject *other, int op) { + PyObject *res = NULL; if (op != Py_EQ && op != Py_NE) { Py_RETURN_NOTIMPLEMENTED; } - if (!PyObject_TypeCheck(self, &ChannelIDtype)) { - Py_RETURN_NOTIMPLEMENTED; + PyObject *mod = get_module_from_type(Py_TYPE(self)); + if (mod == NULL) { + return NULL; + } + module_state *state = get_module_state(mod); + if (state == NULL) { + goto done; + } + + if (!PyObject_TypeCheck(self, state->ChannelIDType)) { + res = Py_NewRef(Py_NotImplemented); + goto done; } channelid *cid = (channelid *)self; int equal; - if (PyObject_TypeCheck(other, &ChannelIDtype)) { + if (PyObject_TypeCheck(other, state->ChannelIDType)) { channelid *othercid = (channelid *)other; equal = (cid->end == othercid->end) && (cid->id == othercid->id); } @@ -1632,27 +1887,34 @@ channelid_richcompare(PyObject *self, PyObject *other, int op) int overflow; long long othercid = PyLong_AsLongLongAndOverflow(other, &overflow); if (othercid == -1 && PyErr_Occurred()) { - return NULL; + goto done; } equal = !overflow && (othercid >= 0) && (cid->id == othercid); } else if (PyNumber_Check(other)) { PyObject *pyid = PyLong_FromLongLong(cid->id); if (pyid == NULL) { - return NULL; + goto done; } - PyObject *res = PyObject_RichCompare(pyid, other, op); + res = PyObject_RichCompare(pyid, other, op); Py_DECREF(pyid); - return res; + goto done; } else { - Py_RETURN_NOTIMPLEMENTED; + res = Py_NewRef(Py_NotImplemented); + goto done; } if ((op == Py_EQ && equal) || (op == Py_NE && !equal)) { - Py_RETURN_TRUE; + res = Py_NewRef(Py_True); } - Py_RETURN_FALSE; + else { + res = Py_NewRef(Py_False); + } + +done: + Py_DECREF(mod); + return res; } static PyObject * @@ -1691,42 +1953,63 @@ static PyObject * _channelid_from_xid(_PyCrossInterpreterData *data) { struct _channelid_xid *xid = (struct _channelid_xid *)data->data; + + PyObject *mod = _get_current_module(); + if (mod == NULL) { + return NULL; + } + module_state *state = get_module_state(mod); + if (state == NULL) { + return NULL; + } + // Note that we do not preserve the "resolve" flag. - PyObject *cid = (PyObject *)newchannelid(&ChannelIDtype, xid->id, xid->end, - _global_channels(), 0, 0); + PyObject *cid = NULL; + int err = newchannelid(state->ChannelIDType, xid->id, xid->end, + _global_channels(), 0, 0, + (channelid **)&cid); + if (err != 0) { + assert(cid == NULL); + (void)handle_channel_error(err, mod, xid->id); + goto done; + } + assert(cid != NULL); if (xid->end == 0) { - return cid; + goto done; } if (!xid->resolve) { - return cid; + goto done; } /* Try returning a high-level channel end but fall back to the ID. */ PyObject *chan = _channel_from_cid(cid, xid->end); if (chan == NULL) { PyErr_Clear(); - return cid; + goto done; } Py_DECREF(cid); - return chan; + cid = chan; + +done: + Py_DECREF(mod); + return cid; } static int -_channelid_shared(PyObject *obj, _PyCrossInterpreterData *data) +_channelid_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) { - struct _channelid_xid *xid = PyMem_NEW(struct _channelid_xid, 1); - if (xid == NULL) { + if (_PyCrossInterpreterData_InitWithSize( + data, tstate->interp, sizeof(struct _channelid_xid), obj, + _channelid_from_xid + ) < 0) + { return -1; } + struct _channelid_xid *xid = (struct _channelid_xid *)data->data; xid->id = ((channelid *)obj)->id; xid->end = ((channelid *)obj)->end; xid->resolve = ((channelid *)obj)->resolve; - - data->data = xid; - Py_INCREF(obj); - data->obj = obj; - data->new_object = _channelid_from_xid; - data->free = PyMem_Free; return 0; } @@ -1736,8 +2019,22 @@ channelid_end(PyObject *self, void *end) int force = 1; channelid *cid = (channelid *)self; if (end != NULL) { - return (PyObject *)newchannelid(Py_TYPE(self), cid->id, *(int *)end, - cid->channels, force, cid->resolve); + PyObject *id = NULL; + int err = newchannelid(Py_TYPE(self), cid->id, *(int *)end, + cid->channels, force, cid->resolve, + (channelid **)&id); + if (err != 0) { + assert(id == NULL); + PyObject *mod = get_module_from_type(Py_TYPE(self)); + if (mod == NULL) { + return NULL; + } + (void)handle_channel_error(err, mod, cid->id); + Py_DECREF(mod); + return NULL; + } + assert(id != NULL); + return id; } if (cid->end == CHANNEL_SEND) { @@ -1765,66 +2062,52 @@ static PyGetSetDef channelid_getsets[] = { PyDoc_STRVAR(channelid_doc, "A channel ID identifies a channel and may be used as an int."); -static PyTypeObject ChannelIDtype = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "_xxsubinterpreters.ChannelID", /* tp_name */ - sizeof(channelid), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)channelid_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)channelid_repr, /* tp_repr */ - &channelid_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - channelid_hash, /* tp_hash */ - 0, /* tp_call */ - (reprfunc)channelid_str, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - // Use Py_TPFLAGS_DISALLOW_INSTANTIATION so the type cannot be instantiated - // from Python code. We do this because there is a strong relationship - // between channel IDs and the channel lifecycle, so this limitation avoids - // related complications. Use the _channel_id() function instead. - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_DISALLOW_INSTANTIATION, /* tp_flags */ - channelid_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - channelid_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - channelid_getsets, /* tp_getset */ +static PyType_Slot ChannelIDType_slots[] = { + {Py_tp_dealloc, (destructor)channelid_dealloc}, + {Py_tp_doc, (void *)channelid_doc}, + {Py_tp_repr, (reprfunc)channelid_repr}, + {Py_tp_str, (reprfunc)channelid_str}, + {Py_tp_hash, channelid_hash}, + {Py_tp_richcompare, channelid_richcompare}, + {Py_tp_getset, channelid_getsets}, + // number slots + {Py_nb_int, (unaryfunc)channelid_int}, + {Py_nb_index, (unaryfunc)channelid_int}, + {0, NULL}, +}; + +static PyType_Spec ChannelIDType_spec = { + .name = "_xxsubinterpreters.ChannelID", + .basicsize = sizeof(channelid), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE), + .slots = ChannelIDType_slots, }; /* interpreter-specific code ************************************************/ -static PyObject * RunFailedError = NULL; - static int -interp_exceptions_init(PyObject *ns) +interp_exceptions_init(PyObject *mod) { - // XXX Move the exceptions into per-module memory? - - if (RunFailedError == NULL) { - // An uncaught exception came out of interp_run_string(). - RunFailedError = PyErr_NewException("_xxsubinterpreters.RunFailedError", - PyExc_RuntimeError, NULL); - if (RunFailedError == NULL) { - return -1; - } - if (PyDict_SetItemString(ns, "RunFailedError", RunFailedError) != 0) { - return -1; - } + module_state *state = get_module_state(mod); + if (state == NULL) { + return -1; } +#define ADD(NAME, BASE) \ + do { \ + assert(state->NAME == NULL); \ + state->NAME = ADD_NEW_EXCEPTION(mod, NAME, BASE); \ + if (state->NAME == NULL) { \ + return -1; \ + } \ + } while (0) + + // An uncaught exception came out of interp_run_string(). + ADD(RunFailedError, PyExc_RuntimeError); +#undef ADD + return 0; } @@ -1839,14 +2122,11 @@ _is_running(PyInterpreterState *interp) } assert(!PyErr_Occurred()); - InterpreterFrame *frame = tstate->cframe->current_frame; + _PyInterpreterFrame *frame = tstate->cframe->current_frame; if (frame == NULL) { return 0; } - - int executing = _PyFrame_IsExecuting(frame); - - return executing; + return 1; } static int @@ -1865,12 +2145,24 @@ _ensure_not_running(PyInterpreterState *interp) static int _run_script(PyInterpreterState *interp, const char *codestr, - _sharedns *shared, _sharedexception **exc) + _sharedns *shared, int needs_import, + _sharedexception **exc) { PyObject *exctype = NULL; PyObject *excval = NULL; PyObject *tb = NULL; + if (needs_import) { + // It might not have been imported yet in the current interpreter. + // However, it will (almost) always have been imported already + // in the main interpreter. + PyObject *mod = PyImport_ImportModule(MODULE_NAME); + if (mod == NULL) { + goto error; + } + Py_DECREF(mod); + } + PyObject *main_mod = _PyInterpreterState_GetMainModule(interp); if (main_mod == NULL) { goto error; @@ -1923,32 +2215,21 @@ error: } static int -_run_script_in_interpreter(PyInterpreterState *interp, const char *codestr, - PyObject *shareables) +_run_script_in_interpreter(PyObject *mod, PyInterpreterState *interp, + const char *codestr, PyObject *shareables) { if (_ensure_not_running(interp) < 0) { return -1; } + module_state *state = get_module_state(mod); - _sharedns *shared = _get_shared_ns(shareables); + int needs_import = 0; + _sharedns *shared = _get_shared_ns(shareables, state->ChannelIDType, + &needs_import); if (shared == NULL && PyErr_Occurred()) { return -1; } -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - // Switch to interpreter. - PyThreadState *new_tstate = PyInterpreterState_ThreadHead(interp); - PyThreadState *save1 = PyEval_SaveThread(); - - (void)PyThreadState_Swap(new_tstate); - - // Run the script. - _sharedexception *exc = NULL; - int result = _run_script(interp, codestr, shared, &exc); - - // Switch back. - PyEval_RestoreThread(save1); -#else // Switch to interpreter. PyThreadState *save_tstate = NULL; if (interp != PyInterpreterState_Get()) { @@ -1960,17 +2241,17 @@ _run_script_in_interpreter(PyInterpreterState *interp, const char *codestr, // Run the script. _sharedexception *exc = NULL; - int result = _run_script(interp, codestr, shared, &exc); + int result = _run_script(interp, codestr, shared, needs_import, &exc); // Switch back. if (save_tstate != NULL) { PyThreadState_Swap(save_tstate); } -#endif // Propagate any exception out to the caller. if (exc != NULL) { - _sharedexception_apply(exc, RunFailedError); + assert(state != NULL); + _sharedexception_apply(exc, state->RunFailedError); _sharedexception_free(exc); } else if (result != 0) { @@ -1992,18 +2273,41 @@ _run_script_in_interpreter(PyInterpreterState *interp, const char *codestr, the data that we need to share between interpreters, so it cannot hold PyObject values. */ static struct globals { + int module_count; _channels channels; -} _globals = {{0}}; +} _globals = {0}; static int -_init_globals(void) +_globals_init(void) { - if (_channels_init(&_globals.channels) != 0) { - return -1; + // XXX This isn't thread-safe. + _globals.module_count++; + if (_globals.module_count > 1) { + // Already initialized. + return 0; } + + assert(_globals.channels.mutex == NULL); + PyThread_type_lock mutex = PyThread_allocate_lock(); + if (mutex == NULL) { + return ERR_CHANNELS_MUTEX_INIT; + } + _channels_init(&_globals.channels, mutex); return 0; } +static void +_globals_fini(void) +{ + // XXX This isn't thread-safe. + _globals.module_count--; + if (_globals.module_count > 0) { + return; + } + + _channels_fini(&_globals.channels); +} + static _channels * _global_channels(void) { return &_globals.channels; @@ -2022,8 +2326,11 @@ interp_create(PyObject *self, PyObject *args, PyObject *kwds) // Create and initialize the new interpreter. PyThreadState *save_tstate = _PyThreadState_GET(); + const _PyInterpreterConfig config = isolated + ? (_PyInterpreterConfig)_PyInterpreterConfig_INIT + : (_PyInterpreterConfig)_PyInterpreterConfig_LEGACY_INIT; // XXX Possible GILState issues? - PyThreadState *tstate = _Py_NewInterpreter(isolated); + PyThreadState *tstate = _Py_NewInterpreterFromConfig(&config); PyThreadState_Swap(save_tstate); if (tstate == NULL) { /* Since no new thread state was created, there is no exception to @@ -2069,7 +2376,7 @@ interp_destroy(PyObject *self, PyObject *args, PyObject *kwds) } // Ensure we don't try to destroy the current interpreter. - PyInterpreterState *current = _get_current(); + PyInterpreterState *current = _get_current_interp(); if (current == NULL) { return NULL; } @@ -2146,7 +2453,7 @@ Return a list containing the ID of every existing interpreter."); static PyObject * interp_get_current(PyObject *self, PyObject *Py_UNUSED(ignored)) { - PyInterpreterState *interp =_get_current(); + PyInterpreterState *interp =_get_current_interp(); if (interp == NULL) { return NULL; } @@ -2204,7 +2511,7 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds) } // Run the code in the interpreter. - if (_run_script_in_interpreter(interp, codestr, shared) != 0) { + if (_run_script_in_interpreter(self, interp, codestr, shared) != 0) { return NULL; } Py_RETURN_NONE; @@ -2276,16 +2583,26 @@ channel_create(PyObject *self, PyObject *Py_UNUSED(ignored)) { int64_t cid = _channel_create(&_globals.channels); if (cid < 0) { + (void)handle_channel_error(-1, self, cid); return NULL; } - PyObject *id = (PyObject *)newchannelid(&ChannelIDtype, cid, 0, - &_globals.channels, 0, 0); - if (id == NULL) { - if (_channel_destroy(&_globals.channels, cid) != 0) { + module_state *state = get_module_state(self); + if (state == NULL) { + return NULL; + } + PyObject *id = NULL; + int err = newchannelid(state->ChannelIDType, cid, 0, + &_globals.channels, 0, 0, + (channelid **)&id); + if (handle_channel_error(err, self, cid)) { + assert(id == NULL); + err = _channel_destroy(&_globals.channels, cid); + if (handle_channel_error(err, self, cid)) { // XXX issue a warning? } return NULL; } + assert(id != NULL); assert(((channelid *)id)->channels != NULL); return id; } @@ -2300,12 +2617,17 @@ channel_destroy(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"cid", NULL}; int64_t cid; + struct channel_id_converter_data cid_data = { + .module = self, + }; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:channel_destroy", kwlist, - channel_id_converter, &cid)) { + channel_id_converter, &cid_data)) { return NULL; } + cid = cid_data.cid; - if (_channel_destroy(&_globals.channels, cid) != 0) { + int err = _channel_destroy(&_globals.channels, cid); + if (handle_channel_error(err, self, cid)) { return NULL; } Py_RETURN_NONE; @@ -2332,16 +2654,25 @@ channel_list_all(PyObject *self, PyObject *Py_UNUSED(ignored)) if (ids == NULL) { goto finally; } + module_state *state = get_module_state(self); + if (state == NULL) { + Py_DECREF(ids); + ids = NULL; + goto finally; + } int64_t *cur = cids; for (int64_t i=0; i < count; cur++, i++) { - PyObject *id = (PyObject *)newchannelid(&ChannelIDtype, *cur, 0, - &_globals.channels, 0, 0); - if (id == NULL) { - Py_DECREF(ids); - ids = NULL; + PyObject *id = NULL; + int err = newchannelid(state->ChannelIDType, *cur, 0, + &_globals.channels, 0, 0, + (channelid **)&id); + if (handle_channel_error(err, self, *cur)) { + assert(id == NULL); + Py_SETREF(ids, NULL); break; } - PyList_SET_ITEM(ids, i, id); + assert(id != NULL); + PyList_SET_ITEM(ids, (Py_ssize_t)i, id); } finally: @@ -2359,6 +2690,9 @@ channel_list_interpreters(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"cid", "send", NULL}; int64_t cid; /* Channel ID */ + struct channel_id_converter_data cid_data = { + .module = self, + }; int send = 0; /* Send or receive end? */ int64_t id; PyObject *ids, *id_obj; @@ -2366,9 +2700,10 @@ channel_list_interpreters(PyObject *self, PyObject *args, PyObject *kwds) if (!PyArg_ParseTupleAndKeywords( args, kwds, "O&$p:channel_list_interpreters", - kwlist, channel_id_converter, &cid, &send)) { + kwlist, channel_id_converter, &cid_data, &send)) { return NULL; } + cid = cid_data.cid; ids = PyList_New(0); if (ids == NULL) { @@ -2381,6 +2716,7 @@ channel_list_interpreters(PyObject *self, PyObject *args, PyObject *kwds) assert(id >= 0); int res = _channel_is_associated(&_globals.channels, cid, id, send); if (res < 0) { + (void)handle_channel_error(res, self, cid); goto except; } if (res) { @@ -2400,8 +2736,7 @@ channel_list_interpreters(PyObject *self, PyObject *args, PyObject *kwds) goto finally; except: - Py_XDECREF(ids); - ids = NULL; + Py_CLEAR(ids); finally: return ids; @@ -2421,13 +2756,18 @@ channel_send(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"cid", "obj", NULL}; int64_t cid; + struct channel_id_converter_data cid_data = { + .module = self, + }; PyObject *obj; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O:channel_send", kwlist, - channel_id_converter, &cid, &obj)) { + channel_id_converter, &cid_data, &obj)) { return NULL; } + cid = cid_data.cid; - if (_channel_send(&_globals.channels, cid, obj) != 0) { + int err = _channel_send(&_globals.channels, cid, obj); + if (handle_channel_error(err, self, cid)) { return NULL; } Py_RETURN_NONE; @@ -2443,26 +2783,32 @@ channel_recv(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"cid", "default", NULL}; int64_t cid; + struct channel_id_converter_data cid_data = { + .module = self, + }; PyObject *dflt = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O:channel_recv", kwlist, - channel_id_converter, &cid, &dflt)) { + channel_id_converter, &cid_data, &dflt)) { + return NULL; + } + cid = cid_data.cid; + + PyObject *obj = NULL; + int err = _channel_recv(&_globals.channels, cid, &obj); + if (handle_channel_error(err, self, cid)) { return NULL; } Py_XINCREF(dflt); - - PyObject *obj = _channel_recv(&_globals.channels, cid); - if (obj != NULL) { - Py_XDECREF(dflt); - return obj; - } else if (PyErr_Occurred()) { - Py_XDECREF(dflt); - return NULL; - } else if (dflt != NULL) { - return dflt; - } else { - PyErr_Format(ChannelEmptyError, "channel %" PRId64 " is empty", cid); - return NULL; + if (obj == NULL) { + // Use the default. + if (dflt == NULL) { + (void)handle_channel_error(ERR_CHANNEL_EMPTY, self, cid); + return NULL; + } + obj = Py_NewRef(dflt); } + Py_XDECREF(dflt); + return obj; } PyDoc_STRVAR(channel_recv_doc, @@ -2478,16 +2824,22 @@ channel_close(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"cid", "send", "recv", "force", NULL}; int64_t cid; + struct channel_id_converter_data cid_data = { + .module = self, + }; int send = 0; int recv = 0; int force = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|$ppp:channel_close", kwlist, - channel_id_converter, &cid, &send, &recv, &force)) { + channel_id_converter, &cid_data, + &send, &recv, &force)) { return NULL; } + cid = cid_data.cid; - if (_channel_close(&_globals.channels, cid, send-recv, force) != 0) { + int err = _channel_close(&_globals.channels, cid, send-recv, force); + if (handle_channel_error(err, self, cid)) { return NULL; } Py_RETURN_NONE; @@ -2526,14 +2878,19 @@ channel_release(PyObject *self, PyObject *args, PyObject *kwds) // Note that only the current interpreter is affected. static char *kwlist[] = {"cid", "send", "recv", "force", NULL}; int64_t cid; + struct channel_id_converter_data cid_data = { + .module = self, + }; int send = 0; int recv = 0; int force = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|$ppp:channel_release", kwlist, - channel_id_converter, &cid, &send, &recv, &force)) { + channel_id_converter, &cid_data, + &send, &recv, &force)) { return NULL; } + cid = cid_data.cid; if (send == 0 && recv == 0) { send = 1; recv = 1; @@ -2542,7 +2899,8 @@ channel_release(PyObject *self, PyObject *args, PyObject *kwds) // XXX Handle force is True. // XXX Fix implicit release. - if (_channel_drop(&_globals.channels, cid, send, recv) != 0) { + int err = _channel_drop(&_globals.channels, cid, send, recv); + if (handle_channel_error(err, self, cid)) { return NULL; } Py_RETURN_NONE; @@ -2558,13 +2916,24 @@ ends are closed. Closing an already closed end is a noop."); static PyObject * channel__channel_id(PyObject *self, PyObject *args, PyObject *kwds) { - return channelid_new(&ChannelIDtype, args, kwds); + module_state *state = get_module_state(self); + if (state == NULL) { + return NULL; + } + PyTypeObject *cls = state->ChannelIDType; + PyObject *mod = get_module_from_owned_type(cls); + if (mod == NULL) { + return NULL; + } + PyObject *cid = _channelid_new(mod, cls, args, kwds); + Py_DECREF(mod); + return cid; } static PyMethodDef module_functions[] = { - {"create", (PyCFunction)(void(*)(void))interp_create, + {"create", _PyCFunction_CAST(interp_create), METH_VARARGS | METH_KEYWORDS, create_doc}, - {"destroy", (PyCFunction)(void(*)(void))interp_destroy, + {"destroy", _PyCFunction_CAST(interp_destroy), METH_VARARGS | METH_KEYWORDS, destroy_doc}, {"list_all", interp_list_all, METH_NOARGS, list_all_doc}, @@ -2572,31 +2941,31 @@ static PyMethodDef module_functions[] = { METH_NOARGS, get_current_doc}, {"get_main", interp_get_main, METH_NOARGS, get_main_doc}, - {"is_running", (PyCFunction)(void(*)(void))interp_is_running, + {"is_running", _PyCFunction_CAST(interp_is_running), METH_VARARGS | METH_KEYWORDS, is_running_doc}, - {"run_string", (PyCFunction)(void(*)(void))interp_run_string, + {"run_string", _PyCFunction_CAST(interp_run_string), METH_VARARGS | METH_KEYWORDS, run_string_doc}, - {"is_shareable", (PyCFunction)(void(*)(void))object_is_shareable, + {"is_shareable", _PyCFunction_CAST(object_is_shareable), METH_VARARGS | METH_KEYWORDS, is_shareable_doc}, {"channel_create", channel_create, METH_NOARGS, channel_create_doc}, - {"channel_destroy", (PyCFunction)(void(*)(void))channel_destroy, + {"channel_destroy", _PyCFunction_CAST(channel_destroy), METH_VARARGS | METH_KEYWORDS, channel_destroy_doc}, {"channel_list_all", channel_list_all, METH_NOARGS, channel_list_all_doc}, - {"channel_list_interpreters", (PyCFunction)(void(*)(void))channel_list_interpreters, + {"channel_list_interpreters", _PyCFunction_CAST(channel_list_interpreters), METH_VARARGS | METH_KEYWORDS, channel_list_interpreters_doc}, - {"channel_send", (PyCFunction)(void(*)(void))channel_send, + {"channel_send", _PyCFunction_CAST(channel_send), METH_VARARGS | METH_KEYWORDS, channel_send_doc}, - {"channel_recv", (PyCFunction)(void(*)(void))channel_recv, + {"channel_recv", _PyCFunction_CAST(channel_recv), METH_VARARGS | METH_KEYWORDS, channel_recv_doc}, - {"channel_close", (PyCFunction)(void(*)(void))channel_close, + {"channel_close", _PyCFunction_CAST(channel_close), METH_VARARGS | METH_KEYWORDS, channel_close_doc}, - {"channel_release", (PyCFunction)(void(*)(void))channel_release, + {"channel_release", _PyCFunction_CAST(channel_release), METH_VARARGS | METH_KEYWORDS, channel_release_doc}, - {"_channel_id", (PyCFunction)(void(*)(void))channel__channel_id, + {"_channel_id", _PyCFunction_CAST(channel__channel_id), METH_VARARGS | METH_KEYWORDS, NULL}, {NULL, NULL} /* sentinel */ @@ -2609,59 +2978,94 @@ PyDoc_STRVAR(module_doc, "This module provides primitive operations to manage Python interpreters.\n\ The 'interpreters' module provides a more convenient interface."); -static struct PyModuleDef interpretersmodule = { - PyModuleDef_HEAD_INIT, - "_xxsubinterpreters", /* m_name */ - module_doc, /* m_doc */ - -1, /* m_size */ - module_functions, /* m_methods */ - NULL, /* m_slots */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ +static int +module_exec(PyObject *mod) +{ + if (_globals_init() != 0) { + return -1; + } + + module_state *state = get_module_state(mod); + if (state == NULL) { + goto error; + } + + /* Add exception types */ + if (interp_exceptions_init(mod) != 0) { + goto error; + } + if (channel_exceptions_init(mod) != 0) { + goto error; + } + + /* Add other types */ + + // ChannelID + state->ChannelIDType = add_new_type( + mod, &ChannelIDType_spec, _channelid_shared); + if (state->ChannelIDType == NULL) { + goto error; + } + + // PyInterpreterID + if (PyModule_AddType(mod, &_PyInterpreterID_Type) < 0) { + goto error; + } + + return 0; + +error: + (void)_PyCrossInterpreterData_UnregisterClass(state->ChannelIDType); + _globals_fini(); + return -1; +} + +static struct PyModuleDef_Slot module_slots[] = { + {Py_mod_exec, module_exec}, + {0, NULL}, }; +static int +module_traverse(PyObject *mod, visitproc visit, void *arg) +{ + module_state *state = get_module_state(mod); + assert(state != NULL); + traverse_module_state(state, visit, arg); + return 0; +} + +static int +module_clear(PyObject *mod) +{ + module_state *state = get_module_state(mod); + assert(state != NULL); + clear_module_state(state); + return 0; +} + +static void +module_free(void *mod) +{ + module_state *state = get_module_state(mod); + assert(state != NULL); + clear_module_state(state); + _globals_fini(); +} + +static struct PyModuleDef moduledef = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = MODULE_NAME, + .m_doc = module_doc, + .m_size = sizeof(module_state), + .m_methods = module_functions, + .m_slots = module_slots, + .m_traverse = module_traverse, + .m_clear = module_clear, + .m_free = (freefunc)module_free, +}; PyMODINIT_FUNC PyInit__xxsubinterpreters(void) { - if (_init_globals() != 0) { - return NULL; - } - - /* Initialize types */ - if (PyType_Ready(&ChannelIDtype) != 0) { - return NULL; - } - - /* Create the module */ - PyObject *module = PyModule_Create(&interpretersmodule); - if (module == NULL) { - return NULL; - } - - /* Add exception types */ - PyObject *ns = PyModule_GetDict(module); // borrowed - if (interp_exceptions_init(ns) != 0) { - return NULL; - } - if (channel_exceptions_init(ns) != 0) { - return NULL; - } - - /* Add other types */ - Py_INCREF(&ChannelIDtype); - if (PyDict_SetItemString(ns, "ChannelID", (PyObject *)&ChannelIDtype) != 0) { - return NULL; - } - Py_INCREF(&_PyInterpreterID_Type); - if (PyDict_SetItemString(ns, "InterpreterID", (PyObject *)&_PyInterpreterID_Type) != 0) { - return NULL; - } - - if (_PyCrossInterpreterData_RegisterClass(&ChannelIDtype, _channelid_shared)) { - return NULL; - } - - return module; + return PyModuleDef_Init(&moduledef); } diff --git a/Modules/_xxtestfuzz/fuzzer.c b/Modules/_xxtestfuzz/fuzzer.c index 366e81a5451..fb0c191d2c4 100644 --- a/Modules/_xxtestfuzz/fuzzer.c +++ b/Modules/_xxtestfuzz/fuzzer.c @@ -142,7 +142,7 @@ static int fuzz_struct_unpack(const char* data, size_t size) { } -#define MAX_JSON_TEST_SIZE 0x10000 +#define MAX_JSON_TEST_SIZE 0x100000 PyObject* json_loads_method = NULL; /* Called by LLVMFuzzerTestOneInput for initialization */ @@ -335,7 +335,7 @@ static int fuzz_sre_match(const char* data, size_t size) { return 0; } -#define MAX_CSV_TEST_SIZE 0x10000 +#define MAX_CSV_TEST_SIZE 0x100000 PyObject* csv_module = NULL; PyObject* csv_error = NULL; /* Called by LLVMFuzzerTestOneInput for initialization */ @@ -393,7 +393,7 @@ static int fuzz_csv_reader(const char* data, size_t size) { return 0; } -#define MAX_AST_LITERAL_EVAL_TEST_SIZE 0x10000 +#define MAX_AST_LITERAL_EVAL_TEST_SIZE 0x100000 PyObject* ast_literal_eval_method = NULL; /* Called by LLVMFuzzerTestOneInput for initialization */ static int init_ast_literal_eval(void) { @@ -459,6 +459,9 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) { PyConfig config; PyConfig_InitPythonConfig(&config); config.install_signal_handlers = 0; + /* Raise the limit above the default allows exercising larger things + * now that we fall back to the _pylong module for large values. */ + config.int_max_str_digits = 8086; PyStatus status; status = PyConfig_SetBytesString(&config, &config.program_name, *argv[0]); if (PyStatus_Exception(status)) { diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index cac347071f9..9d38589ea3d 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -12,6 +12,13 @@ #include "datetime.h" +#include "clinic/_zoneinfo.c.h" +/*[clinic input] +module zoneinfo +class zoneinfo.ZoneInfo "PyObject *" "PyTypeObject *" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d12c73c0eef36df8]*/ + // Imports static PyObject *io_open = NULL; static PyObject *_tzpath_find_tzfile = NULL; @@ -213,20 +220,17 @@ zoneinfo_new_instance(PyTypeObject *type, PyObject *key) } PyObject *rv = PyObject_CallMethod(file_obj, "close", NULL); - Py_DECREF(file_obj); - file_obj = NULL; + Py_SETREF(file_obj, NULL); if (rv == NULL) { goto error; } Py_DECREF(rv); - ((PyZoneInfo_ZoneInfo *)self)->key = key; - Py_INCREF(key); + ((PyZoneInfo_ZoneInfo *)self)->key = Py_NewRef(key); goto cleanup; error: - Py_XDECREF(self); - self = NULL; + Py_CLEAR(self); cleanup: if (file_obj != NULL) { PyObject *exc, *val, *tb; @@ -338,19 +342,24 @@ zoneinfo_dealloc(PyObject *obj_self) Py_TYPE(self)->tp_free((PyObject *)self); } -static PyObject * -zoneinfo_from_file(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyObject *file_obj = NULL; - PyObject *file_repr = NULL; - PyObject *key = Py_None; - PyZoneInfo_ZoneInfo *self = NULL; +/*[clinic input] +@classmethod +zoneinfo.ZoneInfo.from_file - static char *kwlist[] = {"", "key", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist, &file_obj, - &key)) { - return NULL; - } + file_obj: object + / + key: object = None + +Create a ZoneInfo file from a file object. +[clinic start generated code]*/ + +static PyObject * +zoneinfo_ZoneInfo_from_file_impl(PyTypeObject *type, PyObject *file_obj, + PyObject *key) +/*[clinic end generated code: output=68ed2022404ae5be input=ccfe73708133d2e4]*/ +{ + PyObject *file_repr = NULL; + PyZoneInfo_ZoneInfo *self = NULL; PyObject *obj_self = (PyObject *)(type->tp_alloc(type, 0)); self = (PyZoneInfo_ZoneInfo *)obj_self; @@ -369,26 +378,29 @@ zoneinfo_from_file(PyTypeObject *type, PyObject *args, PyObject *kwargs) self->source = SOURCE_FILE; self->file_repr = file_repr; - self->key = key; - Py_INCREF(key); - + self->key = Py_NewRef(key); return obj_self; + error: Py_XDECREF(file_repr); Py_XDECREF(self); return NULL; } -static PyObject * -zoneinfo_no_cache(PyTypeObject *cls, PyObject *args, PyObject *kwargs) -{ - static char *kwlist[] = {"key", NULL}; - PyObject *key = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &key)) { - return NULL; - } +/*[clinic input] +@classmethod +zoneinfo.ZoneInfo.no_cache - PyObject *out = zoneinfo_new_instance(cls, key); + key: object + +Get a new instance of ZoneInfo, bypassing the cache. +[clinic start generated code]*/ + +static PyObject * +zoneinfo_ZoneInfo_no_cache_impl(PyTypeObject *type, PyObject *key) +/*[clinic end generated code: output=751c6894ad66f91b input=bb24afd84a80ba46]*/ +{ + PyObject *out = zoneinfo_new_instance(type, key); if (out != NULL) { ((PyZoneInfo_ZoneInfo *)out)->source = SOURCE_NOCACHE; } @@ -396,18 +408,20 @@ zoneinfo_no_cache(PyTypeObject *cls, PyObject *args, PyObject *kwargs) return out; } +/*[clinic input] +@classmethod +zoneinfo.ZoneInfo.clear_cache + + * + only_keys: object = None + +Clear the ZoneInfo cache. +[clinic start generated code]*/ + static PyObject * -zoneinfo_clear_cache(PyObject *cls, PyObject *args, PyObject *kwargs) +zoneinfo_ZoneInfo_clear_cache_impl(PyTypeObject *type, PyObject *only_keys) +/*[clinic end generated code: output=eec0a3276f07bd90 input=8cff0182a95f295b]*/ { - PyObject *only_keys = NULL; - static char *kwlist[] = {"only_keys", NULL}; - - if (!(PyArg_ParseTupleAndKeywords(args, kwargs, "|$O", kwlist, - &only_keys))) { - return NULL; - } - - PyTypeObject *type = (PyTypeObject *)cls; PyObject *weak_cache = get_weak_cache(type); if (only_keys == NULL || only_keys == Py_None) { @@ -466,8 +480,7 @@ zoneinfo_utcoffset(PyObject *self, PyObject *dt) if (tti == NULL) { return NULL; } - Py_INCREF(tti->utcoff); - return tti->utcoff; + return Py_NewRef(tti->utcoff); } static PyObject * @@ -477,8 +490,7 @@ zoneinfo_dst(PyObject *self, PyObject *dt) if (tti == NULL) { return NULL; } - Py_INCREF(tti->dstoff); - return tti->dstoff; + return Py_NewRef(tti->dstoff); } static PyObject * @@ -488,8 +500,7 @@ zoneinfo_tzname(PyObject *self, PyObject *dt) if (tti == NULL) { return NULL; } - Py_INCREF(tti->tzname); - return tti->tzname; + return Py_NewRef(tti->tzname); } #define GET_DT_TZINFO PyDateTime_DATE_GET_TZINFO @@ -633,8 +644,7 @@ static PyObject * zoneinfo_str(PyZoneInfo_ZoneInfo *self) { if (!(self->key == Py_None)) { - Py_INCREF(self->key); - return self->key; + return Py_NewRef(self->key); } else { return zoneinfo_repr(self); @@ -659,14 +669,8 @@ zoneinfo_reduce(PyObject *obj_self, PyObject *unused) PyZoneInfo_ZoneInfo *self = (PyZoneInfo_ZoneInfo *)obj_self; if (self->source == SOURCE_FILE) { // Objects constructed from files cannot be pickled. - PyObject *pickle = PyImport_ImportModule("pickle"); - if (pickle == NULL) { - return NULL; - } - PyObject *pickle_error = - PyObject_GetAttrString(pickle, "PicklingError"); - Py_DECREF(pickle); + _PyImport_GetModuleAttrString("pickle", "PicklingError"); if (pickle_error == NULL) { return NULL; } @@ -781,8 +785,7 @@ build_ttinfo(long utcoffset, long dstoffset, PyObject *tzname, _ttinfo *out) return -1; } - out->tzname = tzname; - Py_INCREF(tzname); + out->tzname = Py_NewRef(tzname); return 0; } @@ -1069,9 +1072,7 @@ load_data(PyZoneInfo_ZoneInfo *self, PyObject *file_obj) // that the dstoff is set correctly in that case. if (PyObject_IsTrue(tti->dstoff)) { _ttinfo *tti_after = &(self->tzrule_after.std); - Py_DECREF(tti_after->dstoff); - tti_after->dstoff = tti->dstoff; - Py_INCREF(tti_after->dstoff); + Py_SETREF(tti_after->dstoff, Py_NewRef(tti->dstoff)); } } @@ -2273,13 +2274,10 @@ strong_cache_node_new(PyObject *key, PyObject *zone) return NULL; } - Py_INCREF(key); - Py_INCREF(zone); - node->next = NULL; node->prev = NULL; - node->key = key; - node->zone = zone; + node->key = Py_NewRef(key); + node->zone = Py_NewRef(zone); return node; } @@ -2431,8 +2429,7 @@ zone_from_strong_cache(const PyTypeObject *const type, PyObject *const key) if (node != NULL) { move_strong_cache_node_to_front(&ZONEINFO_STRONG_CACHE, node); - Py_INCREF(node->zone); - return node->zone; + return Py_NewRef(node->zone); } return NULL; // Cache miss @@ -2492,14 +2489,13 @@ clear_strong_cache(const PyTypeObject *const type) static PyObject * new_weak_cache(void) { - PyObject *weakref_module = PyImport_ImportModule("weakref"); - if (weakref_module == NULL) { + PyObject *WeakValueDictionary = + _PyImport_GetModuleAttrString("weakref", "WeakValueDictionary"); + if (WeakValueDictionary == NULL) { return NULL; } - - PyObject *weak_cache = - PyObject_CallMethod(weakref_module, "WeakValueDictionary", ""); - Py_DECREF(weakref_module); + PyObject *weak_cache = PyObject_CallNoArgs(WeakValueDictionary); + Py_DECREF(WeakValueDictionary); return weak_cache; } @@ -2552,15 +2548,9 @@ zoneinfo_init_subclass(PyTypeObject *cls, PyObject *args, PyObject **kwargs) ///// // Specify the ZoneInfo type static PyMethodDef zoneinfo_methods[] = { - {"clear_cache", (PyCFunction)(void (*)(void))zoneinfo_clear_cache, - METH_VARARGS | METH_KEYWORDS | METH_CLASS, - PyDoc_STR("Clear the ZoneInfo cache.")}, - {"no_cache", (PyCFunction)(void (*)(void))zoneinfo_no_cache, - METH_VARARGS | METH_KEYWORDS | METH_CLASS, - PyDoc_STR("Get a new instance of ZoneInfo, bypassing the cache.")}, - {"from_file", (PyCFunction)(void (*)(void))zoneinfo_from_file, - METH_VARARGS | METH_KEYWORDS | METH_CLASS, - PyDoc_STR("Create a ZoneInfo file from a file object.")}, + ZONEINFO_ZONEINFO_CLEAR_CACHE_METHODDEF + ZONEINFO_ZONEINFO_NO_CACHE_METHODDEF + ZONEINFO_ZONEINFO_FROM_FILE_METHODDEF {"utcoffset", (PyCFunction)zoneinfo_utcoffset, METH_O, PyDoc_STR("Retrieve a timedelta representing the UTC offset in a zone at " "the given datetime.")}, @@ -2612,16 +2602,11 @@ static PyTypeObject PyZoneInfo_ZoneInfoType = { // Specify the _zoneinfo module static PyMethodDef module_methods[] = {{NULL, NULL}}; static void -module_free(void) +module_free(void *m) { - Py_XDECREF(_tzpath_find_tzfile); - _tzpath_find_tzfile = NULL; - - Py_XDECREF(_common_mod); - _common_mod = NULL; - - Py_XDECREF(io_open); - io_open = NULL; + Py_CLEAR(_tzpath_find_tzfile); + Py_CLEAR(_common_mod); + Py_CLEAR(io_open); xdecref_ttinfo(&NO_TTINFO); @@ -2652,29 +2637,18 @@ zoneinfomodule_exec(PyObject *m) goto error; } - Py_INCREF(&PyZoneInfo_ZoneInfoType); - PyModule_AddObject(m, "ZoneInfo", (PyObject *)&PyZoneInfo_ZoneInfoType); - - /* Populate imports */ - PyObject *_tzpath_module = PyImport_ImportModule("zoneinfo._tzpath"); - if (_tzpath_module == NULL) { + if (PyModule_AddObjectRef(m, "ZoneInfo", (PyObject *)&PyZoneInfo_ZoneInfoType) < 0) { goto error; } + /* Populate imports */ _tzpath_find_tzfile = - PyObject_GetAttrString(_tzpath_module, "find_tzfile"); - Py_DECREF(_tzpath_module); + _PyImport_GetModuleAttrString("zoneinfo._tzpath", "find_tzfile"); if (_tzpath_find_tzfile == NULL) { goto error; } - PyObject *io_module = PyImport_ImportModule("io"); - if (io_module == NULL) { - goto error; - } - - io_open = PyObject_GetAttrString(io_module, "open"); - Py_DECREF(io_module); + io_open = _PyImport_GetModuleAttrString("io", "open"); if (io_open == NULL) { goto error; } @@ -2685,13 +2659,9 @@ zoneinfomodule_exec(PyObject *m) } if (NO_TTINFO.utcoff == NULL) { - NO_TTINFO.utcoff = Py_None; - NO_TTINFO.dstoff = Py_None; - NO_TTINFO.tzname = Py_None; - - for (size_t i = 0; i < 3; ++i) { - Py_INCREF(Py_None); - } + NO_TTINFO.utcoff = Py_NewRef(Py_None); + NO_TTINFO.dstoff = Py_NewRef(Py_None); + NO_TTINFO.tzname = Py_NewRef(Py_None); } if (initialize_caches()) { diff --git a/Modules/addrinfo.h b/Modules/addrinfo.h index c3c86248dd4..66e5a795f86 100644 --- a/Modules/addrinfo.h +++ b/Modules/addrinfo.h @@ -162,7 +162,9 @@ struct sockaddr_storage { #ifdef __cplusplus extern "C" { #endif +#ifdef ENABLE_IPV6 extern void freehostent(struct hostent *); +#endif #ifdef __cplusplus } #endif diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 8e430632813..114c69a0335 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -9,8 +9,8 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" -#include "pycore_floatobject.h" // _PyFloat_Unpack4() #include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_bytesobject.h" // _PyBytes_Repeat #include "structmember.h" // PyMemberDef #include // offsetof() #include @@ -57,6 +57,13 @@ typedef struct { typedef struct { PyTypeObject *ArrayType; PyTypeObject *ArrayIterType; + + PyObject *array_reconstructor; + + PyObject *str_read; + PyObject *str_write; + PyObject *str___dict__; + PyObject *str_iter; } array_state; static array_state * @@ -66,7 +73,7 @@ get_array_state(PyObject *module) } #define find_array_state_by_type(tp) \ - (get_array_state(_PyType_GetModuleByDef(tp, &arraymodule))) + (get_array_state(PyType_GetModuleByDef(tp, &arraymodule))) #define get_array_state_by_class(cls) \ (get_array_state(PyType_GetModule(cls))) @@ -702,8 +709,7 @@ array_richcompare(PyObject *v, PyObject *w, int op) res = Py_False; else res = Py_True; - Py_INCREF(res); - return res; + return Py_NewRef(res); } if (va->ob_descr == wa->ob_descr && va->ob_descr->compareitems != NULL) { @@ -726,8 +732,7 @@ array_richcompare(PyObject *v, PyObject *w, int op) default: return NULL; /* cannot happen */ } PyObject *res = cmp ? Py_True : Py_False; - Py_INCREF(res); - return res; + return Py_NewRef(res); } @@ -771,18 +776,15 @@ array_richcompare(PyObject *v, PyObject *w, int op) res = Py_True; else res = Py_False; - Py_INCREF(res); - return res; + return Py_NewRef(res); } /* We have an item that differs. First, shortcuts for EQ/NE */ if (op == Py_EQ) { - Py_INCREF(Py_False); - res = Py_False; + res = Py_NewRef(Py_False); } else if (op == Py_NE) { - Py_INCREF(Py_True); - res = Py_True; + res = Py_NewRef(Py_True); } else { /* Compare the final item again using the proper operator */ @@ -905,34 +907,24 @@ static PyObject * array_repeat(arrayobject *a, Py_ssize_t n) { array_state *state = find_array_state_by_type(Py_TYPE(a)); - Py_ssize_t size; - arrayobject *np; - Py_ssize_t oldbytes, newbytes; + if (n < 0) n = 0; - if ((Py_SIZE(a) != 0) && (n > PY_SSIZE_T_MAX / Py_SIZE(a))) { + const Py_ssize_t array_length = Py_SIZE(a); + if ((array_length != 0) && (n > PY_SSIZE_T_MAX / array_length)) { return PyErr_NoMemory(); } - size = Py_SIZE(a) * n; - np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr); + Py_ssize_t size = array_length * n; + arrayobject* np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr); if (np == NULL) return NULL; if (size == 0) return (PyObject *)np; - oldbytes = Py_SIZE(a) * a->ob_descr->itemsize; - newbytes = oldbytes * n; - /* this follows the code in unicode_repeat */ - if (oldbytes == 1) { - memset(np->ob_item, a->ob_item[0], newbytes); - } else { - Py_ssize_t done = oldbytes; - memcpy(np->ob_item, a->ob_item, oldbytes); - while (done < newbytes) { - Py_ssize_t ncopy = (done <= newbytes-done) ? done : newbytes-done; - memcpy(np->ob_item+done, np->ob_item, ncopy); - done += ncopy; - } - } + + const Py_ssize_t oldbytes = array_length * a->ob_descr->itemsize; + const Py_ssize_t newbytes = oldbytes * n; + _PyBytes_Repeat(np->ob_item, newbytes, a->ob_item, oldbytes); + return (PyObject *)np; } @@ -1063,37 +1055,31 @@ array_inplace_concat(arrayobject *self, PyObject *bb) } if (array_do_extend(state, self, bb) == -1) return NULL; - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } static PyObject * array_inplace_repeat(arrayobject *self, Py_ssize_t n) { - char *items, *p; - Py_ssize_t size, i; + const Py_ssize_t array_size = Py_SIZE(self); - if (Py_SIZE(self) > 0) { + if (array_size > 0 && n != 1 ) { if (n < 0) n = 0; if ((self->ob_descr->itemsize != 0) && - (Py_SIZE(self) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) { + (array_size > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) { return PyErr_NoMemory(); } - size = Py_SIZE(self) * self->ob_descr->itemsize; + Py_ssize_t size = array_size * self->ob_descr->itemsize; if (n > 0 && size > PY_SSIZE_T_MAX / n) { return PyErr_NoMemory(); } - if (array_resize(self, n * Py_SIZE(self)) == -1) + if (array_resize(self, n * array_size) == -1) return NULL; - items = p = self->ob_item; - for (i = 1; i < n; i++) { - p += size; - memcpy(p, items, size); - } + + _PyBytes_Repeat(self->ob_item, n*size, self->ob_item, size); } - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } @@ -1463,6 +1449,7 @@ array_array_reverse_impl(arrayobject *self) /*[clinic input] array.array.fromfile + cls: defining_class f: object n: Py_ssize_t / @@ -1471,13 +1458,13 @@ Read n objects from the file object f and append them to the end of the array. [clinic start generated code]*/ static PyObject * -array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n) -/*[clinic end generated code: output=ec9f600e10f53510 input=e188afe8e58adf40]*/ +array_array_fromfile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f, + Py_ssize_t n) +/*[clinic end generated code: output=83a667080b345ebc input=3822e907c1c11f1a]*/ { PyObject *b, *res; Py_ssize_t itemsize = self->ob_descr->itemsize; Py_ssize_t nbytes; - _Py_IDENTIFIER(read); int not_enough_bytes; if (n < 0) { @@ -1488,9 +1475,14 @@ array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n) PyErr_NoMemory(); return NULL; } + + + array_state *state = get_array_state_by_class(cls); + assert(state != NULL); + nbytes = n * itemsize; - b = _PyObject_CallMethodId(f, &PyId_read, "n", nbytes); + b = _PyObject_CallMethod(f, state->str_read, "n", nbytes); if (b == NULL) return NULL; @@ -1521,6 +1513,7 @@ array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n) /*[clinic input] array.array.tofile + cls: defining_class f: object / @@ -1528,8 +1521,8 @@ Write all items (as machine values) to the file object f. [clinic start generated code]*/ static PyObject * -array_array_tofile(arrayobject *self, PyObject *f) -/*[clinic end generated code: output=3a2cfa8128df0777 input=b0669a484aab0831]*/ +array_array_tofile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f) +/*[clinic end generated code: output=4560c628d9c18bc2 input=5a24da7a7b407b52]*/ { Py_ssize_t nbytes = Py_SIZE(self) * self->ob_descr->itemsize; /* Write 64K blocks at a time */ @@ -1541,18 +1534,21 @@ array_array_tofile(arrayobject *self, PyObject *f) if (Py_SIZE(self) == 0) goto done; + + array_state *state = get_array_state_by_class(cls); + assert(state != NULL); + for (i = 0; i < nblocks; i++) { char* ptr = self->ob_item + i*BLOCKSIZE; Py_ssize_t size = BLOCKSIZE; PyObject *bytes, *res; - _Py_IDENTIFIER(write); if (i*BLOCKSIZE + size > nbytes) size = nbytes - i*BLOCKSIZE; bytes = PyBytes_FromStringAndSize(ptr, size); if (bytes == NULL) return NULL; - res = _PyObject_CallMethodIdOneArg(f, &PyId_write, bytes); + res = PyObject_CallMethodOneArg(f, state->str_write, bytes); Py_DECREF(bytes); if (res == NULL) return NULL; @@ -1777,9 +1773,9 @@ static PyObject * array_array___sizeof___impl(arrayobject *self) /*[clinic end generated code: output=d8e1c61ebbe3eaed input=805586565bf2b3c6]*/ { - Py_ssize_t res; - res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * self->ob_descr->itemsize; - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(self)); + res += (size_t)self->allocated * (size_t)self->ob_descr->itemsize; + return PyLong_FromSize_t(res); } @@ -1944,9 +1940,8 @@ make_array(PyTypeObject *arraytype, char typecode, PyObject *items) Py_DECREF(typecode_obj); return NULL; } - Py_INCREF(items); PyTuple_SET_ITEM(new_args, 0, typecode_obj); - PyTuple_SET_ITEM(new_args, 1, items); + PyTuple_SET_ITEM(new_args, 1, Py_NewRef(items)); array_obj = array_new(arraytype, new_args, NULL); Py_DECREF(new_args); @@ -2040,15 +2035,14 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, Py_ssize_t i; int le = (mformat_code == IEEE_754_FLOAT_LE) ? 1 : 0; Py_ssize_t itemcount = Py_SIZE(items) / 4; - const unsigned char *memstr = - (unsigned char *)PyBytes_AS_STRING(items); + const char *memstr = PyBytes_AS_STRING(items); converted_items = PyList_New(itemcount); if (converted_items == NULL) return NULL; for (i = 0; i < itemcount; i++) { PyObject *pyfloat = PyFloat_FromDouble( - _PyFloat_Unpack4(&memstr[i * 4], le)); + PyFloat_Unpack4(&memstr[i * 4], le)); if (pyfloat == NULL) { Py_DECREF(converted_items); return NULL; @@ -2062,15 +2056,14 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, Py_ssize_t i; int le = (mformat_code == IEEE_754_DOUBLE_LE) ? 1 : 0; Py_ssize_t itemcount = Py_SIZE(items) / 8; - const unsigned char *memstr = - (unsigned char *)PyBytes_AS_STRING(items); + const char *memstr = PyBytes_AS_STRING(items); converted_items = PyList_New(itemcount); if (converted_items == NULL) return NULL; for (i = 0; i < itemcount; i++) { PyObject *pyfloat = PyFloat_FromDouble( - _PyFloat_Unpack8(&memstr[i * 8], le)); + PyFloat_Unpack8(&memstr[i * 8], le)); if (pyfloat == NULL) { Py_DECREF(converted_items); return NULL; @@ -2175,6 +2168,7 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, /*[clinic input] array.array.__reduce_ex__ + cls: defining_class value: object / @@ -2182,29 +2176,26 @@ Return state information for pickling. [clinic start generated code]*/ static PyObject * -array_array___reduce_ex__(arrayobject *self, PyObject *value) -/*[clinic end generated code: output=051e0a6175d0eddb input=c36c3f85de7df6cd]*/ +array_array___reduce_ex___impl(arrayobject *self, PyTypeObject *cls, + PyObject *value) +/*[clinic end generated code: output=4958ee5d79452ad5 input=19968cf0f91d3eea]*/ { PyObject *dict; PyObject *result; PyObject *array_str; int typecode = self->ob_descr->typecode; int mformat_code; - static PyObject *array_reconstructor = NULL; long protocol; - _Py_IDENTIFIER(_array_reconstructor); - _Py_IDENTIFIER(__dict__); - if (array_reconstructor == NULL) { - PyObject *array_module = PyImport_ImportModule("array"); - if (array_module == NULL) - return NULL; - array_reconstructor = _PyObject_GetAttrId( - array_module, - &PyId__array_reconstructor); - Py_DECREF(array_module); - if (array_reconstructor == NULL) + array_state *state = get_array_state_by_class(cls); + assert(state != NULL); + + if (state->array_reconstructor == NULL) { + state->array_reconstructor = _PyImport_GetModuleAttrString( + "array", "_array_reconstructor"); + if (state->array_reconstructor == NULL) { return NULL; + } } if (!PyLong_Check(value)) { @@ -2216,12 +2207,11 @@ array_array___reduce_ex__(arrayobject *self, PyObject *value) if (protocol == -1 && PyErr_Occurred()) return NULL; - if (_PyObject_LookupAttrId((PyObject *)self, &PyId___dict__, &dict) < 0) { + if (_PyObject_LookupAttr((PyObject *)self, state->str___dict__, &dict) < 0) { return NULL; } if (dict == NULL) { - dict = Py_None; - Py_INCREF(dict); + dict = Py_NewRef(Py_None); } mformat_code = typecode_to_mformat_code(typecode); @@ -2255,8 +2245,10 @@ array_array___reduce_ex__(arrayobject *self, PyObject *value) Py_DECREF(dict); return NULL; } + + assert(state->array_reconstructor != NULL); result = Py_BuildValue( - "O(OCiN)O", array_reconstructor, Py_TYPE(self), typecode, + "O(OCiN)O", state->array_reconstructor, Py_TYPE(self), typecode, mformat_code, array_str, dict); Py_DECREF(dict); return result; @@ -2306,6 +2298,7 @@ static PyMethodDef array_methods[] = { ARRAY_ARRAY_TOBYTES_METHODDEF ARRAY_ARRAY_TOUNICODE_METHODDEF ARRAY_ARRAY___SIZEOF___METHODDEF + {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, {NULL, NULL} /* sentinel */ }; @@ -2570,8 +2563,7 @@ array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags) } view->buf = (void *)self->ob_item; - view->obj = (PyObject*)self; - Py_INCREF(self); + view->obj = Py_NewRef(self); if (view->buf == NULL) view->buf = (void *)emptybuf; view->len = Py_SIZE(self) * self->ob_descr->itemsize; @@ -2883,8 +2875,7 @@ array_iter(arrayobject *ao) if (it == NULL) return NULL; - Py_INCREF(ao); - it->ao = ao; + it->ao = (arrayobject*)Py_NewRef(ao); it->index = 0; it->getitem = ao->ob_descr->getitem; PyObject_GC_Track(it); @@ -2938,15 +2929,20 @@ arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg) /*[clinic input] array.arrayiterator.__reduce__ + cls: defining_class + / + Return state information for pickling. [clinic start generated code]*/ static PyObject * -array_arrayiterator___reduce___impl(arrayiterobject *self) -/*[clinic end generated code: output=7898a52e8e66e016 input=a062ea1e9951417a]*/ +array_arrayiterator___reduce___impl(arrayiterobject *self, PyTypeObject *cls) +/*[clinic end generated code: output=4b032417a2c8f5e6 input=ac64e65a87ad452e]*/ { - _Py_IDENTIFIER(iter); - PyObject *func = _PyEval_GetBuiltinId(&PyId_iter); + + array_state *state = get_array_state_by_class(cls); + assert(state != NULL); + PyObject *func = _PyEval_GetBuiltin(state->str_iter); if (self->ao == NULL) { return Py_BuildValue("N(())", func); } @@ -3010,6 +3006,7 @@ array_traverse(PyObject *module, visitproc visit, void *arg) array_state *state = get_array_state(module); Py_VISIT(state->ArrayType); Py_VISIT(state->ArrayIterType); + Py_VISIT(state->array_reconstructor); return 0; } @@ -3019,6 +3016,11 @@ array_clear(PyObject *module) array_state *state = get_array_state(module); Py_CLEAR(state->ArrayType); Py_CLEAR(state->ArrayIterType); + Py_CLEAR(state->array_reconstructor); + Py_CLEAR(state->str_read); + Py_CLEAR(state->str_write); + Py_CLEAR(state->str___dict__); + Py_CLEAR(state->str_iter); return 0; } @@ -3042,6 +3044,15 @@ do { \ } \ } while (0) +#define ADD_INTERNED(state, string) \ +do { \ + PyObject *tmp = PyUnicode_InternFromString(#string); \ + if (tmp == NULL) { \ + return -1; \ + } \ + state->str_ ## string = tmp; \ +} while (0) + static int array_modexec(PyObject *m) { @@ -3050,23 +3061,25 @@ array_modexec(PyObject *m) PyObject *typecodes; const struct arraydescr *descr; + state->array_reconstructor = NULL; + /* Add interned strings */ + ADD_INTERNED(state, read); + ADD_INTERNED(state, write); + ADD_INTERNED(state, __dict__); + ADD_INTERNED(state, iter); + CREATE_TYPE(m, state->ArrayType, &array_spec); CREATE_TYPE(m, state->ArrayIterType, &arrayiter_spec); Py_SET_TYPE(state->ArrayIterType, &PyType_Type); - Py_INCREF((PyObject *)state->ArrayType); - if (PyModule_AddObject(m, "ArrayType", (PyObject *)state->ArrayType) < 0) { + if (PyModule_AddObject(m, "ArrayType", + Py_NewRef((PyObject *)state->ArrayType)) < 0) { Py_DECREF((PyObject *)state->ArrayType); return -1; } - PyObject *abc_mod = PyImport_ImportModule("collections.abc"); - if (!abc_mod) { - Py_DECREF((PyObject *)state->ArrayType); - return -1; - } - PyObject *mutablesequence = PyObject_GetAttrString(abc_mod, "MutableSequence"); - Py_DECREF(abc_mod); + PyObject *mutablesequence = _PyImport_GetModuleAttrString( + "collections.abc", "MutableSequence"); if (!mutablesequence) { Py_DECREF((PyObject *)state->ArrayType); return -1; diff --git a/Modules/atexitmodule.c b/Modules/atexitmodule.c index e536b4abe29..a1c511e09d7 100644 --- a/Modules/atexitmodule.c +++ b/Modules/atexitmodule.c @@ -93,13 +93,16 @@ atexit_callfuncs(struct atexit_state *state) continue; } + // bpo-46025: Increment the refcount of cb->func as the call itself may unregister it + PyObject* the_func = Py_NewRef(cb->func); PyObject *res = PyObject_Call(cb->func, cb->args, cb->kwargs); if (res == NULL) { - _PyErr_WriteUnraisableMsg("in atexit callback", cb->func); + _PyErr_WriteUnraisableMsg("in atexit callback", the_func); } else { Py_DECREF(res); } + Py_DECREF(the_func); } atexit_cleanup(state); @@ -182,7 +185,7 @@ PyDoc_STRVAR(atexit_run_exitfuncs__doc__, \n\ Run all registered exit functions.\n\ \n\ -If a callaback raises an exception, it is logged with sys.unraisablehook."); +If a callback raises an exception, it is logged with sys.unraisablehook."); static PyObject * atexit_run_exitfuncs(PyObject *module, PyObject *unused) @@ -248,7 +251,7 @@ atexit_unregister(PyObject *module, PyObject *func) static PyMethodDef atexit_methods[] = { - {"register", (PyCFunction)(void(*)(void)) atexit_register, METH_VARARGS|METH_KEYWORDS, + {"register", _PyCFunction_CAST(atexit_register), METH_VARARGS|METH_KEYWORDS, atexit_register__doc__}, {"_clear", (PyCFunction) atexit_clear, METH_NOARGS, atexit_clear__doc__}, diff --git a/Modules/audioop.c b/Modules/audioop.c index 3aeb6f04f13..9325f82f9a1 100644 --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -1,3 +1,33 @@ +/* The audioop module uses the code base in g777.c file of the Sox project. + * Source: https://web.archive.org/web/19970716121258/http://www.spies.com/Sox/Archive/soxgamma.tar.gz + * Programming the AdLib/Sound Blaster + * FM Music Chips + * Version 2.0 (24 Feb 1992) + * + * Copyright (c) 1991, 1992 by Jeffrey S. Lee + * + * jlee@smylex.uucp + * + * + * + * Warranty and Copyright Policy + * + * This document is provided on an "as-is" basis, and its author makes + * no warranty or representation, express or implied, with respect to + * its quality performance or fitness for a particular purpose. In no + * event will the author of this document be liable for direct, indirect, + * special, incidental, or consequential damages arising out of the use + * or inability to use the information contained within. Use of this + * document is at your own risk. + * + * This file may be used and copied freely so long as the applicable + * copyright notices are retained, and no modifications are made to the + * text of the document. No money shall be charged for its distribution + * beyond reasonable shipping, handling and duplication costs, nor shall + * proprietary changes be made to this document so that it cannot be + * distributed freely. This document may not be included in published + * material or commercial packages without the written consent of its + * author. */ /* audioopmodule - Module to detect peak values in arrays */ @@ -5,13 +35,6 @@ #include "Python.h" -#if defined(__CHAR_UNSIGNED__) -#if defined(signed) -/* This module currently does not work on systems where only unsigned - characters are available. Take it out of Setup. Sorry. */ -#endif -#endif - static const int maxvals[] = {0, 0x7F, 0x7FFF, 0x7FFFFF, 0x7FFFFFFF}; /* -1 trick is needed on Windows to support -0x80000000 without a warning */ static const int minvals[] = {0, -0x80, -0x8000, -0x800000, -0x7FFFFFFF-1}; @@ -35,20 +58,6 @@ fbound(double val, double minval, double maxval) } -/* Code shamelessly stolen from sox, 12.17.7, g711.c -** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */ - -/* From g711.c: - * - * December 30, 1994: - * Functions linear2alaw, linear2ulaw have been updated to correctly - * convert unquantized 16 bit values. - * Tables for direct u- to A-law and A- to u-law conversions have been - * corrected. - * Borge Lindberg, Center for PersonKommunikation, Aalborg University. - * bli@cpk.auc.dk - * - */ #define BIAS 0x84 /* define the add-in bias for 16 bit samples */ #define CLIP 32635 #define SIGN_BIT (0x80) /* Sign bit for an A-law byte. */ @@ -66,6 +75,8 @@ static const int16_t seg_uend[8] = { static int16_t search(int16_t val, const int16_t *table, int size) { + assert(0 <= size); + assert(size < INT16_MAX); int i; for (i = 0; i < size; i++) { @@ -177,6 +188,7 @@ st_14linear2ulaw(int16_t pcm_val) /* 2's complement (14-bit range) */ if (seg >= 8) /* out of range, return maximum value. */ return (unsigned char) (0x7F ^ mask); else { + assert(seg >= 0); uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF); return (uval ^ mask); } @@ -304,16 +316,16 @@ static const int stepsizeTable[89] = { #define GETINT16(cp, i) GETINTX(int16_t, (cp), (i)) #define GETINT32(cp, i) GETINTX(int32_t, (cp), (i)) -#if WORDS_BIGENDIAN +#ifdef WORDS_BIGENDIAN #define GETINT24(cp, i) ( \ ((unsigned char *)(cp) + (i))[2] + \ - (((unsigned char *)(cp) + (i))[1] << 8) + \ - (((signed char *)(cp) + (i))[0] << 16) ) + (((unsigned char *)(cp) + (i))[1] * (1 << 8)) + \ + (((signed char *)(cp) + (i))[0] * (1 << 16)) ) #else #define GETINT24(cp, i) ( \ ((unsigned char *)(cp) + (i))[0] + \ - (((unsigned char *)(cp) + (i))[1] << 8) + \ - (((signed char *)(cp) + (i))[2] << 16) ) + (((unsigned char *)(cp) + (i))[1] * (1 << 8)) + \ + (((signed char *)(cp) + (i))[2] * (1 << 16)) ) #endif @@ -321,7 +333,7 @@ static const int stepsizeTable[89] = { #define SETINT16(cp, i, val) SETINTX(int16_t, (cp), (i), (val)) #define SETINT32(cp, i, val) SETINTX(int32_t, (cp), (i), (val)) -#if WORDS_BIGENDIAN +#ifdef WORDS_BIGENDIAN #define SETINT24(cp, i, val) do { \ ((unsigned char *)(cp) + (i))[2] = (int)(val); \ ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \ @@ -354,10 +366,10 @@ static const int stepsizeTable[89] = { } while(0) -#define GETSAMPLE32(size, cp, i) ( \ - (size == 1) ? (int)GETINT8((cp), (i)) << 24 : \ - (size == 2) ? (int)GETINT16((cp), (i)) << 16 : \ - (size == 3) ? (int)GETINT24((cp), (i)) << 8 : \ +#define GETSAMPLE32(size, cp, i) ( \ + (size == 1) ? (int)GETINT8((cp), (i)) * (1 << 24) : \ + (size == 2) ? (int)GETINT16((cp), (i)) * (1 << 16) : \ + (size == 3) ? (int)GETINT24((cp), (i)) * (1 << 8) : \ (int)GETINT32((cp), (i))) #define SETSAMPLE32(size, cp, i, val) do { \ @@ -1459,8 +1471,7 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, len = (Py_ssize_t)(ncp - PyBytes_AsString(str)); rv = PyBytes_FromStringAndSize (PyBytes_AsString(str), len); - Py_DECREF(str); - str = rv; + Py_SETREF(str, rv); if (str == NULL) goto exit; rv = Py_BuildValue("(O(iO))", str, d, samps); @@ -1565,7 +1576,7 @@ audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width) cp = fragment->buf; for (i = 0; i < fragment->len*width; i += width) { - int val = st_ulaw2linear16(*cp++) << 16; + int val = st_ulaw2linear16(*cp++) * (1 << 16); SETSAMPLE32(width, ncp, i, val); } return rv; @@ -1639,7 +1650,7 @@ audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width) cp = fragment->buf; for (i = 0; i < fragment->len*width; i += width) { - val = st_alaw2linear16(*cp++) << 16; + val = st_alaw2linear16(*cp++) * (1 << 16); SETSAMPLE32(width, ncp, i, val); } return rv; @@ -1764,7 +1775,7 @@ audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width, /* Step 6 - Output value */ if ( bufferstep ) { - outputbuffer = (delta << 4) & 0xf0; + outputbuffer = (delta * (1 << 4)) & 0xf0; } else { *ncp++ = (delta & 0x0f) | outputbuffer; } @@ -1882,7 +1893,7 @@ audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width, step = stepsizeTable[index]; /* Step 6 - Output value */ - SETSAMPLE32(width, ncp, i, valpred << 16); + SETSAMPLE32(width, ncp, i, valpred * (1 << 16)); } rv = Py_BuildValue("(O(ii))", str, valpred, index); @@ -1982,5 +1993,12 @@ static struct PyModuleDef audioopmodule = { PyMODINIT_FUNC PyInit_audioop(void) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "'audioop' is deprecated and slated for removal in " + "Python 3.13", + 7)) { + return NULL; + } + return PyModuleDef_Init(&audioopmodule); } diff --git a/Modules/binascii.c b/Modules/binascii.c index fec0d82a39c..95ddb26988d 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -303,14 +303,14 @@ binascii.b2a_uu data: Py_buffer / * - backtick: bool(accept={int}) = False + backtick: bool = False Uuencode line of data. [clinic start generated code]*/ static PyObject * binascii_b2a_uu_impl(PyObject *module, Py_buffer *data, int backtick) -/*[clinic end generated code: output=b1b99de62d9bbeb8 input=b26bc8d32b6ed2f6]*/ +/*[clinic end generated code: output=b1b99de62d9bbeb8 input=beb27822241095cd]*/ { unsigned char *ascii_data; const unsigned char *bin_data; @@ -375,7 +375,7 @@ binascii.a2b_base64 data: ascii_buffer / * - strict_mode: bool(accept={int}) = False + strict_mode: bool = False Decode a line of base64 data. @@ -386,7 +386,7 @@ Decode a line of base64 data. static PyObject * binascii_a2b_base64_impl(PyObject *module, Py_buffer *data, int strict_mode) -/*[clinic end generated code: output=5409557788d4f975 input=3a30c4e3528317c6]*/ +/*[clinic end generated code: output=5409557788d4f975 input=c0c15fd0f8f9a62d]*/ { assert(data->len >= 0); @@ -521,14 +521,14 @@ binascii.b2a_base64 data: Py_buffer / * - newline: bool(accept={int}) = True + newline: bool = True Base64-code line of data. [clinic start generated code]*/ static PyObject * binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline) -/*[clinic end generated code: output=4ad62c8e8485d3b3 input=6083dac5777fa45d]*/ +/*[clinic end generated code: output=4ad62c8e8485d3b3 input=0e20ff59c5f2e3e1]*/ { unsigned char *ascii_data; const unsigned char *bin_data; @@ -737,6 +737,21 @@ static const unsigned int crc_32_tab[256] = { 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, 0x2d02ef8dU }; + +static unsigned int +internal_crc32(const unsigned char *bin_data, Py_ssize_t len, unsigned int crc) +{ /* By Jim Ahlstrom; All rights transferred to CNRI */ + unsigned int result; + + crc = ~ crc; + while (len-- > 0) { + crc = crc_32_tab[(crc ^ *bin_data++) & 0xff] ^ (crc >> 8); + /* Note: (crc >> 8) MUST zero fill on left */ + } + + result = (crc ^ 0xFFFFFFFF); + return result & 0xffffffff; +} #endif /* USE_ZLIB_CRC32 */ /*[clinic input] @@ -754,34 +769,46 @@ binascii_crc32_impl(PyObject *module, Py_buffer *data, unsigned int crc) /*[clinic end generated code: output=52cf59056a78593b input=bbe340bc99d25aa8]*/ #ifdef USE_ZLIB_CRC32 -/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */ +/* This is the same as zlibmodule.c zlib_crc32_impl. It exists in two + * modules for historical reasons. */ { - const Byte *buf; - Py_ssize_t len; - int signed_val; + /* Releasing the GIL for very small buffers is inefficient + and may lower performance */ + if (data->len > 1024*5) { + unsigned char *buf = data->buf; + Py_ssize_t len = data->len; - buf = (Byte*)data->buf; - len = data->len; - signed_val = crc32(crc, buf, len); - return (unsigned int)signed_val & 0xffffffffU; + Py_BEGIN_ALLOW_THREADS + /* Avoid truncation of length for very large buffers. crc32() takes + length as an unsigned int, which may be narrower than Py_ssize_t. */ + while ((size_t)len > UINT_MAX) { + crc = crc32(crc, buf, UINT_MAX); + buf += (size_t) UINT_MAX; + len -= (size_t) UINT_MAX; + } + crc = crc32(crc, buf, (unsigned int)len); + Py_END_ALLOW_THREADS + } else { + crc = crc32(crc, data->buf, (unsigned int)data->len); + } + return crc & 0xffffffff; } #else /* USE_ZLIB_CRC32 */ -{ /* By Jim Ahlstrom; All rights transferred to CNRI */ - const unsigned char *bin_data; - Py_ssize_t len; - unsigned int result; +{ + const unsigned char *bin_data = data->buf; + Py_ssize_t len = data->len; - bin_data = data->buf; - len = data->len; - - crc = ~ crc; - while (len-- > 0) { - crc = crc_32_tab[(crc ^ *bin_data++) & 0xff] ^ (crc >> 8); - /* Note: (crc >> 8) MUST zero fill on left */ + /* Releasing the GIL for very small buffers is inefficient + and may lower performance */ + if (len > 1024*5) { + unsigned int result; + Py_BEGIN_ALLOW_THREADS + result = internal_crc32(bin_data, len, crc); + Py_END_ALLOW_THREADS + return result; + } else { + return internal_crc32(bin_data, len, crc); } - - result = (crc ^ 0xFFFFFFFF); - return result & 0xffffffff; } #endif /* USE_ZLIB_CRC32 */ @@ -925,14 +952,14 @@ binascii_unhexlify_impl(PyObject *module, Py_buffer *hexstr) binascii.a2b_qp data: ascii_buffer - header: bool(accept={int}) = False + header: bool = False Decode a string of qp-encoded data. [clinic start generated code]*/ static PyObject * binascii_a2b_qp_impl(PyObject *module, Py_buffer *data, int header) -/*[clinic end generated code: output=e99f7846cfb9bc53 input=bf6766fea76cce8f]*/ +/*[clinic end generated code: output=e99f7846cfb9bc53 input=bdfb31598d4e47b9]*/ { Py_ssize_t in, out; char ch; @@ -997,10 +1024,7 @@ binascii_a2b_qp_impl(PyObject *module, Py_buffer *data, int header) out++; } } - if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { - PyMem_Free(odata); - return NULL; - } + rv = PyBytes_FromStringAndSize((char *)odata, out); PyMem_Free(odata); return rv; } @@ -1024,9 +1048,9 @@ to_hex (unsigned char ch, unsigned char *s) binascii.b2a_qp data: Py_buffer - quotetabs: bool(accept={int}) = False - istext: bool(accept={int}) = True - header: bool(accept={int}) = False + quotetabs: bool = False + istext: bool = True + header: bool = False Encode a string using quoted-printable encoding. @@ -1038,7 +1062,7 @@ are both encoded. When quotetabs is set, space and tabs are encoded. static PyObject * binascii_b2a_qp_impl(PyObject *module, Py_buffer *data, int quotetabs, int istext, int header) -/*[clinic end generated code: output=e9884472ebb1a94c input=21fb7eea4a184ba6]*/ +/*[clinic end generated code: output=e9884472ebb1a94c input=e9102879afb0defd]*/ { Py_ssize_t in, out; const unsigned char *databuf; @@ -1205,10 +1229,7 @@ binascii_b2a_qp_impl(PyObject *module, Py_buffer *data, int quotetabs, } } } - if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { - PyMem_Free(odata); - return NULL; - } + rv = PyBytes_FromStringAndSize((char *)odata, out); PyMem_Free(odata); return rv; } diff --git a/Modules/cjkcodecs/cjkcodecs.h b/Modules/cjkcodecs/cjkcodecs.h index ba8fad26055..d9aeec2ff40 100644 --- a/Modules/cjkcodecs/cjkcodecs.h +++ b/Modules/cjkcodecs/cjkcodecs.h @@ -245,14 +245,7 @@ static const struct dbcs_map *mapping_list; static PyObject * getmultibytecodec(void) { - PyObject *mod = PyImport_ImportModuleNoBlock("_multibytecodec"); - if (mod == NULL) { - return NULL; - } - - PyObject *cofunc = PyObject_GetAttrString(mod, "__create_codec"); - Py_DECREF(mod); - return cofunc; + return _PyImport_GetModuleAttrString("_multibytecodec", "__create_codec"); } static PyObject * diff --git a/Modules/cjkcodecs/clinic/multibytecodec.c.h b/Modules/cjkcodecs/clinic/multibytecodec.c.h index 563888370d0..1b41c231eac 100644 --- a/Modules/cjkcodecs/clinic/multibytecodec.c.h +++ b/Modules/cjkcodecs/clinic/multibytecodec.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_multibytecodec_MultibyteCodec_encode__doc__, "encode($self, /, input, errors=None)\n" "--\n" @@ -14,7 +20,7 @@ PyDoc_STRVAR(_multibytecodec_MultibyteCodec_encode__doc__, "registered with codecs.register_error that can handle UnicodeEncodeErrors."); #define _MULTIBYTECODEC_MULTIBYTECODEC_ENCODE_METHODDEF \ - {"encode", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteCodec_encode, METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteCodec_encode__doc__}, + {"encode", _PyCFunction_CAST(_multibytecodec_MultibyteCodec_encode), METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteCodec_encode__doc__}, static PyObject * _multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self, @@ -25,8 +31,31 @@ static PyObject * _multibytecodec_MultibyteCodec_encode(MultibyteCodecObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(input), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"input", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "encode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *input; @@ -77,7 +106,7 @@ PyDoc_STRVAR(_multibytecodec_MultibyteCodec_decode__doc__, "codecs.register_error that is able to handle UnicodeDecodeErrors.\""); #define _MULTIBYTECODEC_MULTIBYTECODEC_DECODE_METHODDEF \ - {"decode", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteCodec_decode, METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteCodec_decode__doc__}, + {"decode", _PyCFunction_CAST(_multibytecodec_MultibyteCodec_decode), METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteCodec_decode__doc__}, static PyObject * _multibytecodec_MultibyteCodec_decode_impl(MultibyteCodecObject *self, @@ -88,8 +117,31 @@ static PyObject * _multibytecodec_MultibyteCodec_decode(MultibyteCodecObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(input), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"input", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer input = {NULL, NULL}; @@ -145,7 +197,7 @@ PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalEncoder_encode__doc__, "\n"); #define _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_ENCODE_METHODDEF \ - {"encode", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteIncrementalEncoder_encode, METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteIncrementalEncoder_encode__doc__}, + {"encode", _PyCFunction_CAST(_multibytecodec_MultibyteIncrementalEncoder_encode), METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteIncrementalEncoder_encode__doc__}, static PyObject * _multibytecodec_MultibyteIncrementalEncoder_encode_impl(MultibyteIncrementalEncoderObject *self, @@ -156,8 +208,31 @@ static PyObject * _multibytecodec_MultibyteIncrementalEncoder_encode(MultibyteIncrementalEncoderObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(input), &_Py_ID(final), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"input", "final", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "encode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *input; @@ -171,8 +246,8 @@ _multibytecodec_MultibyteIncrementalEncoder_encode(MultibyteIncrementalEncoderOb if (!noptargs) { goto skip_optional_pos; } - final = _PyLong_AsInt(args[1]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[1]); + if (final < 0) { goto exit; } skip_optional_pos: @@ -251,7 +326,7 @@ PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalDecoder_decode__doc__, "\n"); #define _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_DECODE_METHODDEF \ - {"decode", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteIncrementalDecoder_decode, METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteIncrementalDecoder_decode__doc__}, + {"decode", _PyCFunction_CAST(_multibytecodec_MultibyteIncrementalDecoder_decode), METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteIncrementalDecoder_decode__doc__}, static PyObject * _multibytecodec_MultibyteIncrementalDecoder_decode_impl(MultibyteIncrementalDecoderObject *self, @@ -262,8 +337,31 @@ static PyObject * _multibytecodec_MultibyteIncrementalDecoder_decode(MultibyteIncrementalDecoderObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(input), &_Py_ID(final), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"input", "final", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer input = {NULL, NULL}; @@ -283,8 +381,8 @@ _multibytecodec_MultibyteIncrementalDecoder_decode(MultibyteIncrementalDecoderOb if (!noptargs) { goto skip_optional_pos; } - final = _PyLong_AsInt(args[1]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[1]); + if (final < 0) { goto exit; } skip_optional_pos: @@ -368,7 +466,7 @@ PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_read__doc__, "\n"); #define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READ_METHODDEF \ - {"read", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteStreamReader_read, METH_FASTCALL, _multibytecodec_MultibyteStreamReader_read__doc__}, + {"read", _PyCFunction_CAST(_multibytecodec_MultibyteStreamReader_read), METH_FASTCALL, _multibytecodec_MultibyteStreamReader_read__doc__}, static PyObject * _multibytecodec_MultibyteStreamReader_read_impl(MultibyteStreamReaderObject *self, @@ -400,7 +498,7 @@ PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_readline__doc__, "\n"); #define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINE_METHODDEF \ - {"readline", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteStreamReader_readline, METH_FASTCALL, _multibytecodec_MultibyteStreamReader_readline__doc__}, + {"readline", _PyCFunction_CAST(_multibytecodec_MultibyteStreamReader_readline), METH_FASTCALL, _multibytecodec_MultibyteStreamReader_readline__doc__}, static PyObject * _multibytecodec_MultibyteStreamReader_readline_impl(MultibyteStreamReaderObject *self, @@ -432,7 +530,7 @@ PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_readlines__doc__, "\n"); #define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINES_METHODDEF \ - {"readlines", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteStreamReader_readlines, METH_FASTCALL, _multibytecodec_MultibyteStreamReader_readlines__doc__}, + {"readlines", _PyCFunction_CAST(_multibytecodec_MultibyteStreamReader_readlines), METH_FASTCALL, _multibytecodec_MultibyteStreamReader_readlines__doc__}, static PyObject * _multibytecodec_MultibyteStreamReader_readlines_impl(MultibyteStreamReaderObject *self, @@ -481,7 +579,43 @@ PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_write__doc__, "\n"); #define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITE_METHODDEF \ - {"write", (PyCFunction)_multibytecodec_MultibyteStreamWriter_write, METH_O, _multibytecodec_MultibyteStreamWriter_write__doc__}, + {"write", _PyCFunction_CAST(_multibytecodec_MultibyteStreamWriter_write), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteStreamWriter_write__doc__}, + +static PyObject * +_multibytecodec_MultibyteStreamWriter_write_impl(MultibyteStreamWriterObject *self, + PyTypeObject *cls, + PyObject *strobj); + +static PyObject * +_multibytecodec_MultibyteStreamWriter_write(MultibyteStreamWriterObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "write", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *strobj; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + strobj = args[0]; + return_value = _multibytecodec_MultibyteStreamWriter_write_impl(self, cls, strobj); + +exit: + return return_value; +} PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_writelines__doc__, "writelines($self, lines, /)\n" @@ -489,7 +623,43 @@ PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_writelines__doc__, "\n"); #define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITELINES_METHODDEF \ - {"writelines", (PyCFunction)_multibytecodec_MultibyteStreamWriter_writelines, METH_O, _multibytecodec_MultibyteStreamWriter_writelines__doc__}, + {"writelines", _PyCFunction_CAST(_multibytecodec_MultibyteStreamWriter_writelines), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteStreamWriter_writelines__doc__}, + +static PyObject * +_multibytecodec_MultibyteStreamWriter_writelines_impl(MultibyteStreamWriterObject *self, + PyTypeObject *cls, + PyObject *lines); + +static PyObject * +_multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "writelines", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *lines; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + lines = args[0]; + return_value = _multibytecodec_MultibyteStreamWriter_writelines_impl(self, cls, lines); + +exit: + return return_value; +} PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_reset__doc__, "reset($self, /)\n" @@ -497,15 +667,20 @@ PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_reset__doc__, "\n"); #define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_RESET_METHODDEF \ - {"reset", (PyCFunction)_multibytecodec_MultibyteStreamWriter_reset, METH_NOARGS, _multibytecodec_MultibyteStreamWriter_reset__doc__}, + {"reset", _PyCFunction_CAST(_multibytecodec_MultibyteStreamWriter_reset), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteStreamWriter_reset__doc__}, static PyObject * -_multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self); +_multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self, + PyTypeObject *cls); static PyObject * -_multibytecodec_MultibyteStreamWriter_reset(MultibyteStreamWriterObject *self, PyObject *Py_UNUSED(ignored)) +_multibytecodec_MultibyteStreamWriter_reset(MultibyteStreamWriterObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _multibytecodec_MultibyteStreamWriter_reset_impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "reset() takes no arguments"); + return NULL; + } + return _multibytecodec_MultibyteStreamWriter_reset_impl(self, cls); } PyDoc_STRVAR(_multibytecodec___create_codec__doc__, @@ -515,4 +690,4 @@ PyDoc_STRVAR(_multibytecodec___create_codec__doc__, #define _MULTIBYTECODEC___CREATE_CODEC_METHODDEF \ {"__create_codec", (PyCFunction)_multibytecodec___create_codec, METH_O, _multibytecodec___create_codec__doc__}, -/*[clinic end generated code: output=5c0f74129db07c87 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5f0e8dacddb0ac76 input=a9049054013a1b77]*/ diff --git a/Modules/cjkcodecs/mappings_hk.h b/Modules/cjkcodecs/mappings_hk.h index 1b1d70e7c17..9012ae350c4 100644 --- a/Modules/cjkcodecs/mappings_hk.h +++ b/Modules/cjkcodecs/mappings_hk.h @@ -1,3 +1,4 @@ +// AUTO-GENERATED FILE FROM genmap_tchinese.py: DO NOT EDIT static const ucs2_t __big5hkscs_decmap[6219] = { 17392,19506,17923,17830,17784,29287,19831,17843,31921,19682,31941,15253,18230, 18244,19527,19520,17087,13847,29522,28299,28882,19543,41809,18255,17882,19589, diff --git a/Modules/cjkcodecs/mappings_tw.h b/Modules/cjkcodecs/mappings_tw.h index ec3f9f7468e..ceb4bc56a21 100644 --- a/Modules/cjkcodecs/mappings_tw.h +++ b/Modules/cjkcodecs/mappings_tw.h @@ -1,3 +1,4 @@ +// AUTO-GENERATED FILE FROM genmap_tchinese.py: DO NOT EDIT static const ucs2_t __big5_decmap[16702] = { 12288,65292,12289,12290,65294,8226,65307,65306,65311,65281,65072,8230,8229, 65104,65380,65106,183,65108,65109,65110,65111,65372,8211,65073,8212,65075, @@ -2631,3 +2632,4 @@ static const struct unim_index cp950ext_encmap[256] = { 0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+342,81,104},{ __cp950ext_encmap+366,15,229}, }; + diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index ba558d0dbf2..8564494f626 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -18,6 +18,7 @@ typedef struct { PyTypeObject *reader_type; PyTypeObject *writer_type; PyTypeObject *multibytecodec_type; + PyObject *str_write; } _multibytecodec_state; static _multibytecodec_state * @@ -32,7 +33,7 @@ static struct PyModuleDef _multibytecodecmodule; static _multibytecodec_state * _multibyte_codec_find_state_by_type(PyTypeObject *type) { - PyObject *module = _PyType_GetModuleByDef(type, &_multibytecodecmodule); + PyObject *module = PyType_GetModuleByDef(type, &_multibytecodecmodule); assert(module != NULL); return _multibytecodec_get_state(module); } @@ -71,8 +72,6 @@ static PyObject *multibytecodec_encode(MultibyteCodec *, #define MBENC_RESET MBENC_MAX<<1 /* reset after an encoding session */ -_Py_IDENTIFIER(write); - static PyObject * make_tuple(PyObject *object, Py_ssize_t len) { @@ -142,8 +141,7 @@ codecctx_errors_get(MultibyteStatefulCodecContext *self, void *Py_UNUSED(ignored else if (self->errors == ERROR_REPLACE) errors = "replace"; else { - Py_INCREF(self->errors); - return self->errors; + return Py_NewRef(self->errors); } return PyUnicode_FromString(errors); @@ -342,8 +340,7 @@ multibytecodec_encerror(MultibyteCodec *codec, goto errorexit; } else { - Py_INCREF(tobj); - retstr = tobj; + retstr = Py_NewRef(tobj); } assert(PyBytes_Check(retstr)); @@ -787,11 +784,9 @@ encoder_encode_stateful(MultibyteStatefulEncoderContext *ctx, if (ctx->pending) { PyObject *inbuf_tmp; - Py_INCREF(ctx->pending); - origpending = ctx->pending; + origpending = Py_NewRef(ctx->pending); - Py_INCREF(ctx->pending); - inbuf_tmp = ctx->pending; + inbuf_tmp = Py_NewRef(ctx->pending); PyUnicode_Append(&inbuf_tmp, unistr); if (inbuf_tmp == NULL) goto errorexit; @@ -801,8 +796,7 @@ encoder_encode_stateful(MultibyteStatefulEncoderContext *ctx, else { origpending = NULL; - Py_INCREF(unistr); - inbuf = unistr; + inbuf = Py_NewRef(unistr); } if (PyUnicode_READY(inbuf) < 0) goto errorexit; @@ -899,14 +893,14 @@ decoder_feed_buffer(MultibyteStatefulDecoderContext *ctx, _multibytecodec.MultibyteIncrementalEncoder.encode input: object - final: bool(accept={int}) = False + final: bool = False [clinic start generated code]*/ static PyObject * _multibytecodec_MultibyteIncrementalEncoder_encode_impl(MultibyteIncrementalEncoderObject *self, PyObject *input, int final) -/*[clinic end generated code: output=123361b6c505e2c1 input=093a1ddbb2fc6721]*/ +/*[clinic end generated code: output=123361b6c505e2c1 input=bd5f7d40d43e99b0]*/ { return encoder_encode_stateful(STATEFUL_ECTX(self), input, final); } @@ -986,8 +980,7 @@ _multibytecodec_MultibyteIncrementalEncoder_setstate_impl(MultibyteIncrementalEn goto errorexit; } - Py_CLEAR(self->pending); - self->pending = pending; + Py_XSETREF(self->pending, pending); memcpy(self->state.c, statebytes+1+statebytes[0], sizeof(self->state.c)); @@ -1121,14 +1114,14 @@ static PyType_Spec encoder_spec = { _multibytecodec.MultibyteIncrementalDecoder.decode input: Py_buffer - final: bool(accept={int}) = False + final: bool = False [clinic start generated code]*/ static PyObject * _multibytecodec_MultibyteIncrementalDecoder_decode_impl(MultibyteIncrementalDecoderObject *self, Py_buffer *input, int final) -/*[clinic end generated code: output=b9b9090e8a9ce2ba input=c9132b24d503eb1d]*/ +/*[clinic end generated code: output=b9b9090e8a9ce2ba input=8795fbb20860027a]*/ { MultibyteDecodeBuffer buf; char *data, *wdata = NULL; @@ -1444,8 +1437,7 @@ mbstreamreader_iread(MultibyteStreamReaderObject *self, memcpy(ctrdata + self->pendingsize, PyBytes_AS_STRING(cres), PyBytes_GET_SIZE(cres)); - Py_DECREF(cres); - cres = ctr; + Py_SETREF(cres, ctr); self->pendingsize = 0; } @@ -1471,8 +1463,7 @@ mbstreamreader_iread(MultibyteStreamReaderObject *self, goto errorexit; } - Py_DECREF(cres); - cres = NULL; + Py_SETREF(cres, NULL); if (sizehint < 0 || buf.writer.pos != 0 || rsize == 0) break; @@ -1646,8 +1637,7 @@ mbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } self->codec = ((MultibyteCodecObject *)codec)->codec; - self->stream = stream; - Py_INCREF(stream); + self->stream = Py_NewRef(stream); self->pendingsize = 0; self->errors = internal_error_callback(errors); if (self->errors == NULL) @@ -1714,7 +1704,7 @@ static PyType_Spec reader_spec = { static int mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, - PyObject *unistr) + PyObject *unistr, PyObject *str_write) { PyObject *str, *wr; @@ -1722,7 +1712,7 @@ mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, if (str == NULL) return -1; - wr = _PyObject_CallMethodIdOneArg(self->stream, &PyId_write, str); + wr = _PyObject_CallMethodOneArg(self->stream, str_write, str); Py_DECREF(str); if (wr == NULL) return -1; @@ -1734,32 +1724,38 @@ mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, /*[clinic input] _multibytecodec.MultibyteStreamWriter.write + cls: defining_class strobj: object / [clinic start generated code]*/ static PyObject * -_multibytecodec_MultibyteStreamWriter_write(MultibyteStreamWriterObject *self, - PyObject *strobj) -/*[clinic end generated code: output=e13ae841c895251e input=551dc4c018c10a2b]*/ +_multibytecodec_MultibyteStreamWriter_write_impl(MultibyteStreamWriterObject *self, + PyTypeObject *cls, + PyObject *strobj) +/*[clinic end generated code: output=68ade3aea26410ac input=199f26f68bd8425a]*/ { - if (mbstreamwriter_iwrite(self, strobj)) + _multibytecodec_state *state = PyType_GetModuleState(cls); + assert(state != NULL); + if (mbstreamwriter_iwrite(self, strobj, state->str_write)) { return NULL; - else - Py_RETURN_NONE; + } + Py_RETURN_NONE; } /*[clinic input] _multibytecodec.MultibyteStreamWriter.writelines + cls: defining_class lines: object / [clinic start generated code]*/ static PyObject * -_multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *self, - PyObject *lines) -/*[clinic end generated code: output=e5c4285ac8e7d522 input=57797fe7008d4e96]*/ +_multibytecodec_MultibyteStreamWriter_writelines_impl(MultibyteStreamWriterObject *self, + PyTypeObject *cls, + PyObject *lines) +/*[clinic end generated code: output=b4c99d2cf23ffb88 input=a6d5fe7c74972a34]*/ { PyObject *strobj; int i, r; @@ -1770,13 +1766,15 @@ _multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *se return NULL; } + _multibytecodec_state *state = PyType_GetModuleState(cls); + assert(state != NULL); for (i = 0; i < PySequence_Length(lines); i++) { /* length can be changed even within this loop */ strobj = PySequence_GetItem(lines, i); if (strobj == NULL) return NULL; - r = mbstreamwriter_iwrite(self, strobj); + r = mbstreamwriter_iwrite(self, strobj, state->str_write); Py_DECREF(strobj); if (r == -1) return NULL; @@ -1790,11 +1788,16 @@ _multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *se /*[clinic input] _multibytecodec.MultibyteStreamWriter.reset + + cls: defining_class + / + [clinic start generated code]*/ static PyObject * -_multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self) -/*[clinic end generated code: output=8f54a4d9b03db5ff input=b56dbcbaf35cc10c]*/ +_multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self, + PyTypeObject *cls) +/*[clinic end generated code: output=32ef224c2a38aa3d input=28af6a9cd38d1979]*/ { PyObject *pwrt; @@ -1813,10 +1816,14 @@ _multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *se return NULL; assert(PyBytes_Check(pwrt)); + + _multibytecodec_state *state = PyType_GetModuleState(cls); + assert(state != NULL); + if (PyBytes_Size(pwrt) > 0) { PyObject *wr; - wr = _PyObject_CallMethodIdOneArg(self->stream, &PyId_write, pwrt); + wr = _PyObject_CallMethodOneArg(self->stream, state->str_write, pwrt); if (wr == NULL) { Py_DECREF(pwrt); return NULL; @@ -1853,8 +1860,7 @@ mbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } self->codec = ((MultibyteCodecObject *)codec)->codec; - self->stream = stream; - Py_INCREF(stream); + self->stream = Py_NewRef(stream); self->pending = NULL; self->errors = internal_error_callback(errors); if (self->errors == NULL) @@ -1988,6 +1994,7 @@ _multibytecodec_clear(PyObject *mod) Py_CLEAR(state->decoder_type); Py_CLEAR(state->reader_type); Py_CLEAR(state->writer_type); + Py_CLEAR(state->str_write); return 0; } @@ -2016,6 +2023,10 @@ static int _multibytecodec_exec(PyObject *mod) { _multibytecodec_state *state = _multibytecodec_get_state(mod); + state->str_write = PyUnicode_InternFromString("write"); + if (state->str_write == NULL) { + return -1; + } CREATE_TYPE(mod, state->multibytecodec_type, &multibytecodec_spec); CREATE_TYPE(mod, state->encoder_type, &encoder_spec); CREATE_TYPE(mod, state->decoder_type, &decoder_spec); diff --git a/Modules/clinic/_abc.c.h b/Modules/clinic/_abc.c.h index 62c6552ba64..2adec818c91 100644 --- a/Modules/clinic/_abc.c.h +++ b/Modules/clinic/_abc.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_abc__reset_registry__doc__, "_reset_registry($module, self, /)\n" "--\n" @@ -53,7 +59,7 @@ PyDoc_STRVAR(_abc__abc_register__doc__, "Internal ABC helper for subclasss registration. Should be never used outside abc module."); #define _ABC__ABC_REGISTER_METHODDEF \ - {"_abc_register", (PyCFunction)(void(*)(void))_abc__abc_register, METH_FASTCALL, _abc__abc_register__doc__}, + {"_abc_register", _PyCFunction_CAST(_abc__abc_register), METH_FASTCALL, _abc__abc_register__doc__}, static PyObject * _abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass); @@ -83,7 +89,7 @@ PyDoc_STRVAR(_abc__abc_instancecheck__doc__, "Internal ABC helper for instance checks. Should be never used outside abc module."); #define _ABC__ABC_INSTANCECHECK_METHODDEF \ - {"_abc_instancecheck", (PyCFunction)(void(*)(void))_abc__abc_instancecheck, METH_FASTCALL, _abc__abc_instancecheck__doc__}, + {"_abc_instancecheck", _PyCFunction_CAST(_abc__abc_instancecheck), METH_FASTCALL, _abc__abc_instancecheck__doc__}, static PyObject * _abc__abc_instancecheck_impl(PyObject *module, PyObject *self, @@ -114,7 +120,7 @@ PyDoc_STRVAR(_abc__abc_subclasscheck__doc__, "Internal ABC helper for subclasss checks. Should be never used outside abc module."); #define _ABC__ABC_SUBCLASSCHECK_METHODDEF \ - {"_abc_subclasscheck", (PyCFunction)(void(*)(void))_abc__abc_subclasscheck, METH_FASTCALL, _abc__abc_subclasscheck__doc__}, + {"_abc_subclasscheck", _PyCFunction_CAST(_abc__abc_subclasscheck), METH_FASTCALL, _abc__abc_subclasscheck__doc__}, static PyObject * _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self, @@ -159,4 +165,4 @@ _abc_get_cache_token(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _abc_get_cache_token_impl(module); } -/*[clinic end generated code: output=2544b4b5ae50a089 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c2e69611a495c98d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index c472e652fb7..43c5d771798 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_asyncio_Future___init____doc__, "Future(*, loop=None)\n" "--\n" @@ -26,8 +32,31 @@ static int _asyncio_Future___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(loop), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"loop", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Future", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Future", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -83,15 +112,19 @@ PyDoc_STRVAR(_asyncio_Future_exception__doc__, "InvalidStateError."); #define _ASYNCIO_FUTURE_EXCEPTION_METHODDEF \ - {"exception", (PyCFunction)_asyncio_Future_exception, METH_NOARGS, _asyncio_Future_exception__doc__}, + {"exception", _PyCFunction_CAST(_asyncio_Future_exception), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_exception__doc__}, static PyObject * -_asyncio_Future_exception_impl(FutureObj *self); +_asyncio_Future_exception_impl(FutureObj *self, PyTypeObject *cls); static PyObject * -_asyncio_Future_exception(FutureObj *self, PyObject *Py_UNUSED(ignored)) +_asyncio_Future_exception(FutureObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _asyncio_Future_exception_impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "exception() takes no arguments"); + return NULL; + } + return _asyncio_Future_exception_impl(self, cls); } PyDoc_STRVAR(_asyncio_Future_set_result__doc__, @@ -104,7 +137,42 @@ PyDoc_STRVAR(_asyncio_Future_set_result__doc__, "InvalidStateError."); #define _ASYNCIO_FUTURE_SET_RESULT_METHODDEF \ - {"set_result", (PyCFunction)_asyncio_Future_set_result, METH_O, _asyncio_Future_set_result__doc__}, + {"set_result", _PyCFunction_CAST(_asyncio_Future_set_result), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_set_result__doc__}, + +static PyObject * +_asyncio_Future_set_result_impl(FutureObj *self, PyTypeObject *cls, + PyObject *result); + +static PyObject * +_asyncio_Future_set_result(FutureObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_result", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *result; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + result = args[0]; + return_value = _asyncio_Future_set_result_impl(self, cls, result); + +exit: + return return_value; +} PyDoc_STRVAR(_asyncio_Future_set_exception__doc__, "set_exception($self, exception, /)\n" @@ -116,7 +184,42 @@ PyDoc_STRVAR(_asyncio_Future_set_exception__doc__, "InvalidStateError."); #define _ASYNCIO_FUTURE_SET_EXCEPTION_METHODDEF \ - {"set_exception", (PyCFunction)_asyncio_Future_set_exception, METH_O, _asyncio_Future_set_exception__doc__}, + {"set_exception", _PyCFunction_CAST(_asyncio_Future_set_exception), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_set_exception__doc__}, + +static PyObject * +_asyncio_Future_set_exception_impl(FutureObj *self, PyTypeObject *cls, + PyObject *exception); + +static PyObject * +_asyncio_Future_set_exception(FutureObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_exception", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *exception; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + exception = args[0]; + return_value = _asyncio_Future_set_exception_impl(self, cls, exception); + +exit: + return return_value; +} PyDoc_STRVAR(_asyncio_Future_add_done_callback__doc__, "add_done_callback($self, fn, /, *, context=)\n" @@ -129,18 +232,41 @@ PyDoc_STRVAR(_asyncio_Future_add_done_callback__doc__, "scheduled with call_soon."); #define _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF \ - {"add_done_callback", (PyCFunction)(void(*)(void))_asyncio_Future_add_done_callback, METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_add_done_callback__doc__}, + {"add_done_callback", _PyCFunction_CAST(_asyncio_Future_add_done_callback), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_add_done_callback__doc__}, static PyObject * -_asyncio_Future_add_done_callback_impl(FutureObj *self, PyObject *fn, - PyObject *context); +_asyncio_Future_add_done_callback_impl(FutureObj *self, PyTypeObject *cls, + PyObject *fn, PyObject *context); static PyObject * -_asyncio_Future_add_done_callback(FutureObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_asyncio_Future_add_done_callback(FutureObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "context", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "add_done_callback", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "add_done_callback", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *fn; @@ -156,7 +282,7 @@ _asyncio_Future_add_done_callback(FutureObj *self, PyObject *const *args, Py_ssi } context = args[1]; skip_optional_kwonly: - return_value = _asyncio_Future_add_done_callback_impl(self, fn, context); + return_value = _asyncio_Future_add_done_callback_impl(self, cls, fn, context); exit: return return_value; @@ -171,7 +297,42 @@ PyDoc_STRVAR(_asyncio_Future_remove_done_callback__doc__, "Returns the number of callbacks removed."); #define _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF \ - {"remove_done_callback", (PyCFunction)_asyncio_Future_remove_done_callback, METH_O, _asyncio_Future_remove_done_callback__doc__}, + {"remove_done_callback", _PyCFunction_CAST(_asyncio_Future_remove_done_callback), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_remove_done_callback__doc__}, + +static PyObject * +_asyncio_Future_remove_done_callback_impl(FutureObj *self, PyTypeObject *cls, + PyObject *fn); + +static PyObject * +_asyncio_Future_remove_done_callback(FutureObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "remove_done_callback", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *fn; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + fn = args[0]; + return_value = _asyncio_Future_remove_done_callback_impl(self, cls, fn); + +exit: + return return_value; +} PyDoc_STRVAR(_asyncio_Future_cancel__doc__, "cancel($self, /, msg=None)\n" @@ -184,17 +345,41 @@ PyDoc_STRVAR(_asyncio_Future_cancel__doc__, "return True."); #define _ASYNCIO_FUTURE_CANCEL_METHODDEF \ - {"cancel", (PyCFunction)(void(*)(void))_asyncio_Future_cancel, METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_cancel__doc__}, + {"cancel", _PyCFunction_CAST(_asyncio_Future_cancel), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_cancel__doc__}, static PyObject * -_asyncio_Future_cancel_impl(FutureObj *self, PyObject *msg); +_asyncio_Future_cancel_impl(FutureObj *self, PyTypeObject *cls, + PyObject *msg); static PyObject * -_asyncio_Future_cancel(FutureObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_asyncio_Future_cancel(FutureObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(msg), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"msg", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "cancel", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cancel", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *msg = Py_None; @@ -208,7 +393,7 @@ _asyncio_Future_cancel(FutureObj *self, PyObject *const *args, Py_ssize_t nargs, } msg = args[0]; skip_optional_pos: - return_value = _asyncio_Future_cancel_impl(self, msg); + return_value = _asyncio_Future_cancel_impl(self, cls, msg); exit: return return_value; @@ -260,15 +445,19 @@ PyDoc_STRVAR(_asyncio_Future_get_loop__doc__, "Return the event loop the Future is bound to."); #define _ASYNCIO_FUTURE_GET_LOOP_METHODDEF \ - {"get_loop", (PyCFunction)_asyncio_Future_get_loop, METH_NOARGS, _asyncio_Future_get_loop__doc__}, + {"get_loop", _PyCFunction_CAST(_asyncio_Future_get_loop), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_get_loop__doc__}, static PyObject * -_asyncio_Future_get_loop_impl(FutureObj *self); +_asyncio_Future_get_loop_impl(FutureObj *self, PyTypeObject *cls); static PyObject * -_asyncio_Future_get_loop(FutureObj *self, PyObject *Py_UNUSED(ignored)) +_asyncio_Future_get_loop(FutureObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _asyncio_Future_get_loop_impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "get_loop() takes no arguments"); + return NULL; + } + return _asyncio_Future_get_loop_impl(self, cls); } PyDoc_STRVAR(_asyncio_Future__make_cancelled_error__doc__, @@ -292,46 +481,53 @@ _asyncio_Future__make_cancelled_error(FutureObj *self, PyObject *Py_UNUSED(ignor return _asyncio_Future__make_cancelled_error_impl(self); } -PyDoc_STRVAR(_asyncio_Future__repr_info__doc__, -"_repr_info($self, /)\n" -"--\n" -"\n"); - -#define _ASYNCIO_FUTURE__REPR_INFO_METHODDEF \ - {"_repr_info", (PyCFunction)_asyncio_Future__repr_info, METH_NOARGS, _asyncio_Future__repr_info__doc__}, - -static PyObject * -_asyncio_Future__repr_info_impl(FutureObj *self); - -static PyObject * -_asyncio_Future__repr_info(FutureObj *self, PyObject *Py_UNUSED(ignored)) -{ - return _asyncio_Future__repr_info_impl(self); -} - PyDoc_STRVAR(_asyncio_Task___init____doc__, -"Task(coro, *, loop=None, name=None)\n" +"Task(coro, *, loop=None, name=None, context=None)\n" "--\n" "\n" "A coroutine wrapped in a Future."); static int _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop, - PyObject *name); + PyObject *name, PyObject *context); static int _asyncio_Task___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static const char * const _keywords[] = {"coro", "loop", "name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Task", 0}; - PyObject *argsbuf[3]; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(coro), &_Py_ID(loop), &_Py_ID(name), &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"coro", "loop", "name", "context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; PyObject *coro; PyObject *loop = Py_None; PyObject *name = Py_None; + PyObject *context = Py_None; fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); if (!fastargs) { @@ -347,9 +543,15 @@ _asyncio_Task___init__(PyObject *self, PyObject *args, PyObject *kwargs) goto skip_optional_kwonly; } } - name = fastargs[2]; + if (fastargs[2]) { + name = fastargs[2]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + context = fastargs[3]; skip_optional_kwonly: - return_value = _asyncio_Task___init___impl((TaskObj *)self, coro, loop, name); + return_value = _asyncio_Task___init___impl((TaskObj *)self, coro, loop, name, context); exit: return return_value; @@ -376,23 +578,6 @@ _asyncio_Task__make_cancelled_error(TaskObj *self, PyObject *Py_UNUSED(ignored)) return _asyncio_Task__make_cancelled_error_impl(self); } -PyDoc_STRVAR(_asyncio_Task__repr_info__doc__, -"_repr_info($self, /)\n" -"--\n" -"\n"); - -#define _ASYNCIO_TASK__REPR_INFO_METHODDEF \ - {"_repr_info", (PyCFunction)_asyncio_Task__repr_info, METH_NOARGS, _asyncio_Task__repr_info__doc__}, - -static PyObject * -_asyncio_Task__repr_info_impl(TaskObj *self); - -static PyObject * -_asyncio_Task__repr_info(TaskObj *self, PyObject *Py_UNUSED(ignored)) -{ - return _asyncio_Task__repr_info_impl(self); -} - PyDoc_STRVAR(_asyncio_Task_cancel__doc__, "cancel($self, /, msg=None)\n" "--\n" @@ -414,10 +599,12 @@ PyDoc_STRVAR(_asyncio_Task_cancel__doc__, "not return True (unless the task was already cancelled). A\n" "task will be marked as cancelled when the wrapped coroutine\n" "terminates with a CancelledError exception (even if cancel()\n" -"was not called)."); +"was not called).\n" +"\n" +"This also increases the task\'s count of cancellation requests."); #define _ASYNCIO_TASK_CANCEL_METHODDEF \ - {"cancel", (PyCFunction)(void(*)(void))_asyncio_Task_cancel, METH_FASTCALL|METH_KEYWORDS, _asyncio_Task_cancel__doc__}, + {"cancel", _PyCFunction_CAST(_asyncio_Task_cancel), METH_FASTCALL|METH_KEYWORDS, _asyncio_Task_cancel__doc__}, static PyObject * _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg); @@ -426,8 +613,31 @@ static PyObject * _asyncio_Task_cancel(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(msg), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"msg", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "cancel", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cancel", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *msg = Py_None; @@ -447,6 +657,50 @@ exit: return return_value; } +PyDoc_STRVAR(_asyncio_Task_cancelling__doc__, +"cancelling($self, /)\n" +"--\n" +"\n" +"Return the count of the task\'s cancellation requests.\n" +"\n" +"This count is incremented when .cancel() is called\n" +"and may be decremented using .uncancel()."); + +#define _ASYNCIO_TASK_CANCELLING_METHODDEF \ + {"cancelling", (PyCFunction)_asyncio_Task_cancelling, METH_NOARGS, _asyncio_Task_cancelling__doc__}, + +static PyObject * +_asyncio_Task_cancelling_impl(TaskObj *self); + +static PyObject * +_asyncio_Task_cancelling(TaskObj *self, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_Task_cancelling_impl(self); +} + +PyDoc_STRVAR(_asyncio_Task_uncancel__doc__, +"uncancel($self, /)\n" +"--\n" +"\n" +"Decrement the task\'s count of cancellation requests.\n" +"\n" +"This should be used by tasks that catch CancelledError\n" +"and wish to continue indefinitely until they are cancelled again.\n" +"\n" +"Returns the remaining number of cancellation requests."); + +#define _ASYNCIO_TASK_UNCANCEL_METHODDEF \ + {"uncancel", (PyCFunction)_asyncio_Task_uncancel, METH_NOARGS, _asyncio_Task_uncancel__doc__}, + +static PyObject * +_asyncio_Task_uncancel_impl(TaskObj *self); + +static PyObject * +_asyncio_Task_uncancel(TaskObj *self, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_Task_uncancel_impl(self); +} + PyDoc_STRVAR(_asyncio_Task_get_stack__doc__, "get_stack($self, /, *, limit=None)\n" "--\n" @@ -472,17 +726,41 @@ PyDoc_STRVAR(_asyncio_Task_get_stack__doc__, "returned for a suspended coroutine."); #define _ASYNCIO_TASK_GET_STACK_METHODDEF \ - {"get_stack", (PyCFunction)(void(*)(void))_asyncio_Task_get_stack, METH_FASTCALL|METH_KEYWORDS, _asyncio_Task_get_stack__doc__}, + {"get_stack", _PyCFunction_CAST(_asyncio_Task_get_stack), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Task_get_stack__doc__}, static PyObject * -_asyncio_Task_get_stack_impl(TaskObj *self, PyObject *limit); +_asyncio_Task_get_stack_impl(TaskObj *self, PyTypeObject *cls, + PyObject *limit); static PyObject * -_asyncio_Task_get_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_asyncio_Task_get_stack(TaskObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(limit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"limit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get_stack", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get_stack", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *limit = Py_None; @@ -496,7 +774,7 @@ _asyncio_Task_get_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, } limit = args[0]; skip_optional_kwonly: - return_value = _asyncio_Task_get_stack_impl(self, limit); + return_value = _asyncio_Task_get_stack_impl(self, cls, limit); exit: return return_value; @@ -515,18 +793,41 @@ PyDoc_STRVAR(_asyncio_Task_print_stack__doc__, "to sys.stderr."); #define _ASYNCIO_TASK_PRINT_STACK_METHODDEF \ - {"print_stack", (PyCFunction)(void(*)(void))_asyncio_Task_print_stack, METH_FASTCALL|METH_KEYWORDS, _asyncio_Task_print_stack__doc__}, + {"print_stack", _PyCFunction_CAST(_asyncio_Task_print_stack), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Task_print_stack__doc__}, static PyObject * -_asyncio_Task_print_stack_impl(TaskObj *self, PyObject *limit, - PyObject *file); +_asyncio_Task_print_stack_impl(TaskObj *self, PyTypeObject *cls, + PyObject *limit, PyObject *file); static PyObject * -_asyncio_Task_print_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_asyncio_Task_print_stack(TaskObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(limit), &_Py_ID(file), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"limit", "file", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "print_stack", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "print_stack", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *limit = Py_None; @@ -547,7 +848,7 @@ _asyncio_Task_print_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs } file = args[1]; skip_optional_kwonly: - return_value = _asyncio_Task_print_stack_impl(self, limit, file); + return_value = _asyncio_Task_print_stack_impl(self, cls, limit, file); exit: return return_value; @@ -586,6 +887,23 @@ _asyncio_Task_get_coro(TaskObj *self, PyObject *Py_UNUSED(ignored)) return _asyncio_Task_get_coro_impl(self); } +PyDoc_STRVAR(_asyncio_Task_get_context__doc__, +"get_context($self, /)\n" +"--\n" +"\n"); + +#define _ASYNCIO_TASK_GET_CONTEXT_METHODDEF \ + {"get_context", (PyCFunction)_asyncio_Task_get_context, METH_NOARGS, _asyncio_Task_get_context__doc__}, + +static PyObject * +_asyncio_Task_get_context_impl(TaskObj *self); + +static PyObject * +_asyncio_Task_get_context(TaskObj *self, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_Task_get_context_impl(self); +} + PyDoc_STRVAR(_asyncio_Task_get_name__doc__, "get_name($self, /)\n" "--\n" @@ -669,45 +987,6 @@ _asyncio_get_event_loop(PyObject *module, PyObject *Py_UNUSED(ignored)) return _asyncio_get_event_loop_impl(module); } -PyDoc_STRVAR(_asyncio__get_event_loop__doc__, -"_get_event_loop($module, /, stacklevel=3)\n" -"--\n" -"\n"); - -#define _ASYNCIO__GET_EVENT_LOOP_METHODDEF \ - {"_get_event_loop", (PyCFunction)(void(*)(void))_asyncio__get_event_loop, METH_FASTCALL|METH_KEYWORDS, _asyncio__get_event_loop__doc__}, - -static PyObject * -_asyncio__get_event_loop_impl(PyObject *module, int stacklevel); - -static PyObject * -_asyncio__get_event_loop(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"stacklevel", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_get_event_loop", 0}; - PyObject *argsbuf[1]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - int stacklevel = 3; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); - if (!args) { - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - stacklevel = _PyLong_AsInt(args[0]); - if (stacklevel == -1 && PyErr_Occurred()) { - goto exit; - } -skip_optional_pos: - return_value = _asyncio__get_event_loop_impl(module, stacklevel); - -exit: - return return_value; -} - PyDoc_STRVAR(_asyncio_get_running_loop__doc__, "get_running_loop($module, /)\n" "--\n" @@ -737,7 +1016,7 @@ PyDoc_STRVAR(_asyncio__register_task__doc__, "Returns None."); #define _ASYNCIO__REGISTER_TASK_METHODDEF \ - {"_register_task", (PyCFunction)(void(*)(void))_asyncio__register_task, METH_FASTCALL|METH_KEYWORDS, _asyncio__register_task__doc__}, + {"_register_task", _PyCFunction_CAST(_asyncio__register_task), METH_FASTCALL|METH_KEYWORDS, _asyncio__register_task__doc__}, static PyObject * _asyncio__register_task_impl(PyObject *module, PyObject *task); @@ -746,8 +1025,31 @@ static PyObject * _asyncio__register_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(task), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"task", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_register_task", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_register_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *task; @@ -771,7 +1073,7 @@ PyDoc_STRVAR(_asyncio__unregister_task__doc__, "Returns None."); #define _ASYNCIO__UNREGISTER_TASK_METHODDEF \ - {"_unregister_task", (PyCFunction)(void(*)(void))_asyncio__unregister_task, METH_FASTCALL|METH_KEYWORDS, _asyncio__unregister_task__doc__}, + {"_unregister_task", _PyCFunction_CAST(_asyncio__unregister_task), METH_FASTCALL|METH_KEYWORDS, _asyncio__unregister_task__doc__}, static PyObject * _asyncio__unregister_task_impl(PyObject *module, PyObject *task); @@ -780,8 +1082,31 @@ static PyObject * _asyncio__unregister_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(task), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"task", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_unregister_task", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_unregister_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *task; @@ -807,7 +1132,7 @@ PyDoc_STRVAR(_asyncio__enter_task__doc__, "Returns None."); #define _ASYNCIO__ENTER_TASK_METHODDEF \ - {"_enter_task", (PyCFunction)(void(*)(void))_asyncio__enter_task, METH_FASTCALL|METH_KEYWORDS, _asyncio__enter_task__doc__}, + {"_enter_task", _PyCFunction_CAST(_asyncio__enter_task), METH_FASTCALL|METH_KEYWORDS, _asyncio__enter_task__doc__}, static PyObject * _asyncio__enter_task_impl(PyObject *module, PyObject *loop, PyObject *task); @@ -816,8 +1141,31 @@ static PyObject * _asyncio__enter_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(loop), &_Py_ID(task), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"loop", "task", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_enter_task", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_enter_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *loop; PyObject *task; @@ -845,7 +1193,7 @@ PyDoc_STRVAR(_asyncio__leave_task__doc__, "Returns None."); #define _ASYNCIO__LEAVE_TASK_METHODDEF \ - {"_leave_task", (PyCFunction)(void(*)(void))_asyncio__leave_task, METH_FASTCALL|METH_KEYWORDS, _asyncio__leave_task__doc__}, + {"_leave_task", _PyCFunction_CAST(_asyncio__leave_task), METH_FASTCALL|METH_KEYWORDS, _asyncio__leave_task__doc__}, static PyObject * _asyncio__leave_task_impl(PyObject *module, PyObject *loop, PyObject *task); @@ -854,8 +1202,31 @@ static PyObject * _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(loop), &_Py_ID(task), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"loop", "task", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_leave_task", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_leave_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *loop; PyObject *task; @@ -871,4 +1242,64 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=0d127162ac92e0c0 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_asyncio_current_task__doc__, +"current_task($module, /, loop=None)\n" +"--\n" +"\n" +"Return a currently executed task."); + +#define _ASYNCIO_CURRENT_TASK_METHODDEF \ + {"current_task", _PyCFunction_CAST(_asyncio_current_task), METH_FASTCALL|METH_KEYWORDS, _asyncio_current_task__doc__}, + +static PyObject * +_asyncio_current_task_impl(PyObject *module, PyObject *loop); + +static PyObject * +_asyncio_current_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(loop), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"loop", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "current_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *loop = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + loop = args[0]; +skip_optional_pos: + return_value = _asyncio_current_task_impl(module, loop); + +exit: + return return_value; +} +/*[clinic end generated code: output=00f494214f2fd008 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_bisectmodule.c.h b/Modules/clinic/_bisectmodule.c.h index f118f4bbf86..bbf456e4b0f 100644 --- a/Modules/clinic/_bisectmodule.c.h +++ b/Modules/clinic/_bisectmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_bisect_bisect_right__doc__, "bisect_right($module, /, a, x, lo=0, hi=None, *, key=None)\n" "--\n" @@ -16,7 +22,7 @@ PyDoc_STRVAR(_bisect_bisect_right__doc__, "slice of a to be searched."); #define _BISECT_BISECT_RIGHT_METHODDEF \ - {"bisect_right", (PyCFunction)(void(*)(void))_bisect_bisect_right, METH_FASTCALL|METH_KEYWORDS, _bisect_bisect_right__doc__}, + {"bisect_right", _PyCFunction_CAST(_bisect_bisect_right), METH_FASTCALL|METH_KEYWORDS, _bisect_bisect_right__doc__}, static Py_ssize_t _bisect_bisect_right_impl(PyObject *module, PyObject *a, PyObject *x, @@ -26,8 +32,31 @@ static PyObject * _bisect_bisect_right(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(x), &_Py_ID(lo), &_Py_ID(hi), &_Py_ID(key), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "bisect_right", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "bisect_right", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -99,7 +128,7 @@ PyDoc_STRVAR(_bisect_insort_right__doc__, "slice of a to be searched."); #define _BISECT_INSORT_RIGHT_METHODDEF \ - {"insort_right", (PyCFunction)(void(*)(void))_bisect_insort_right, METH_FASTCALL|METH_KEYWORDS, _bisect_insort_right__doc__}, + {"insort_right", _PyCFunction_CAST(_bisect_insort_right), METH_FASTCALL|METH_KEYWORDS, _bisect_insort_right__doc__}, static PyObject * _bisect_insort_right_impl(PyObject *module, PyObject *a, PyObject *x, @@ -109,8 +138,31 @@ static PyObject * _bisect_insort_right(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(x), &_Py_ID(lo), &_Py_ID(hi), &_Py_ID(key), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "insort_right", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "insort_right", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -179,7 +231,7 @@ PyDoc_STRVAR(_bisect_bisect_left__doc__, "slice of a to be searched."); #define _BISECT_BISECT_LEFT_METHODDEF \ - {"bisect_left", (PyCFunction)(void(*)(void))_bisect_bisect_left, METH_FASTCALL|METH_KEYWORDS, _bisect_bisect_left__doc__}, + {"bisect_left", _PyCFunction_CAST(_bisect_bisect_left), METH_FASTCALL|METH_KEYWORDS, _bisect_bisect_left__doc__}, static Py_ssize_t _bisect_bisect_left_impl(PyObject *module, PyObject *a, PyObject *x, @@ -189,8 +241,31 @@ static PyObject * _bisect_bisect_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(x), &_Py_ID(lo), &_Py_ID(hi), &_Py_ID(key), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "bisect_left", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "bisect_left", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -262,7 +337,7 @@ PyDoc_STRVAR(_bisect_insort_left__doc__, "slice of a to be searched."); #define _BISECT_INSORT_LEFT_METHODDEF \ - {"insort_left", (PyCFunction)(void(*)(void))_bisect_insort_left, METH_FASTCALL|METH_KEYWORDS, _bisect_insort_left__doc__}, + {"insort_left", _PyCFunction_CAST(_bisect_insort_left), METH_FASTCALL|METH_KEYWORDS, _bisect_insort_left__doc__}, static PyObject * _bisect_insort_left_impl(PyObject *module, PyObject *a, PyObject *x, @@ -272,8 +347,31 @@ static PyObject * _bisect_insort_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(x), &_Py_ID(lo), &_Py_ID(hi), &_Py_ID(key), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "insort_left", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "insort_left", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -327,4 +425,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=aeb97db6db79bf96 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7dc87f7af75275a1 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_bz2module.c.h b/Modules/clinic/_bz2module.c.h index 71ad0b13571..50a48b0bf2b 100644 --- a/Modules/clinic/_bz2module.c.h +++ b/Modules/clinic/_bz2module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_bz2_BZ2Compressor_compress__doc__, "compress($self, data, /)\n" "--\n" @@ -85,7 +91,7 @@ PyDoc_STRVAR(_bz2_BZ2Decompressor_decompress__doc__, "the unused_data attribute."); #define _BZ2_BZ2DECOMPRESSOR_DECOMPRESS_METHODDEF \ - {"decompress", (PyCFunction)(void(*)(void))_bz2_BZ2Decompressor_decompress, METH_FASTCALL|METH_KEYWORDS, _bz2_BZ2Decompressor_decompress__doc__}, + {"decompress", _PyCFunction_CAST(_bz2_BZ2Decompressor_decompress), METH_FASTCALL|METH_KEYWORDS, _bz2_BZ2Decompressor_decompress__doc__}, static PyObject * _bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data, @@ -95,8 +101,31 @@ static PyObject * _bz2_BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(max_length), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"data", "max_length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -139,4 +168,4 @@ exit: return return_value; } -/*[clinic end generated code: output=ed10705d7a9fd598 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=829bed4097cf2e63 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_codecsmodule.c.h b/Modules/clinic/_codecsmodule.c.h index 855ac77a7f7..f11bcc8815b 100644 --- a/Modules/clinic/_codecsmodule.c.h +++ b/Modules/clinic/_codecsmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_codecs_register__doc__, "register($module, search_function, /)\n" "--\n" @@ -76,7 +82,7 @@ PyDoc_STRVAR(_codecs_encode__doc__, "codecs.register_error that can handle ValueErrors."); #define _CODECS_ENCODE_METHODDEF \ - {"encode", (PyCFunction)(void(*)(void))_codecs_encode, METH_FASTCALL|METH_KEYWORDS, _codecs_encode__doc__}, + {"encode", _PyCFunction_CAST(_codecs_encode), METH_FASTCALL|METH_KEYWORDS, _codecs_encode__doc__}, static PyObject * _codecs_encode_impl(PyObject *module, PyObject *obj, const char *encoding, @@ -86,8 +92,31 @@ static PyObject * _codecs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(obj), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"obj", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "encode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *obj; @@ -153,7 +182,7 @@ PyDoc_STRVAR(_codecs_decode__doc__, "codecs.register_error that can handle ValueErrors."); #define _CODECS_DECODE_METHODDEF \ - {"decode", (PyCFunction)(void(*)(void))_codecs_decode, METH_FASTCALL|METH_KEYWORDS, _codecs_decode__doc__}, + {"decode", _PyCFunction_CAST(_codecs_decode), METH_FASTCALL|METH_KEYWORDS, _codecs_decode__doc__}, static PyObject * _codecs_decode_impl(PyObject *module, PyObject *obj, const char *encoding, @@ -163,8 +192,31 @@ static PyObject * _codecs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(obj), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"obj", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *obj; @@ -223,7 +275,7 @@ PyDoc_STRVAR(_codecs_escape_decode__doc__, "\n"); #define _CODECS_ESCAPE_DECODE_METHODDEF \ - {"escape_decode", (PyCFunction)(void(*)(void))_codecs_escape_decode, METH_FASTCALL, _codecs_escape_decode__doc__}, + {"escape_decode", _PyCFunction_CAST(_codecs_escape_decode), METH_FASTCALL, _codecs_escape_decode__doc__}, static PyObject * _codecs_escape_decode_impl(PyObject *module, Py_buffer *data, @@ -295,7 +347,7 @@ PyDoc_STRVAR(_codecs_escape_encode__doc__, "\n"); #define _CODECS_ESCAPE_ENCODE_METHODDEF \ - {"escape_encode", (PyCFunction)(void(*)(void))_codecs_escape_encode, METH_FASTCALL, _codecs_escape_encode__doc__}, + {"escape_encode", _PyCFunction_CAST(_codecs_escape_encode), METH_FASTCALL, _codecs_escape_encode__doc__}, static PyObject * _codecs_escape_encode_impl(PyObject *module, PyObject *data, @@ -350,7 +402,7 @@ PyDoc_STRVAR(_codecs_utf_7_decode__doc__, "\n"); #define _CODECS_UTF_7_DECODE_METHODDEF \ - {"utf_7_decode", (PyCFunction)(void(*)(void))_codecs_utf_7_decode, METH_FASTCALL, _codecs_utf_7_decode__doc__}, + {"utf_7_decode", _PyCFunction_CAST(_codecs_utf_7_decode), METH_FASTCALL, _codecs_utf_7_decode__doc__}, static PyObject * _codecs_utf_7_decode_impl(PyObject *module, Py_buffer *data, @@ -398,8 +450,8 @@ _codecs_utf_7_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -420,7 +472,7 @@ PyDoc_STRVAR(_codecs_utf_8_decode__doc__, "\n"); #define _CODECS_UTF_8_DECODE_METHODDEF \ - {"utf_8_decode", (PyCFunction)(void(*)(void))_codecs_utf_8_decode, METH_FASTCALL, _codecs_utf_8_decode__doc__}, + {"utf_8_decode", _PyCFunction_CAST(_codecs_utf_8_decode), METH_FASTCALL, _codecs_utf_8_decode__doc__}, static PyObject * _codecs_utf_8_decode_impl(PyObject *module, Py_buffer *data, @@ -468,8 +520,8 @@ _codecs_utf_8_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -490,7 +542,7 @@ PyDoc_STRVAR(_codecs_utf_16_decode__doc__, "\n"); #define _CODECS_UTF_16_DECODE_METHODDEF \ - {"utf_16_decode", (PyCFunction)(void(*)(void))_codecs_utf_16_decode, METH_FASTCALL, _codecs_utf_16_decode__doc__}, + {"utf_16_decode", _PyCFunction_CAST(_codecs_utf_16_decode), METH_FASTCALL, _codecs_utf_16_decode__doc__}, static PyObject * _codecs_utf_16_decode_impl(PyObject *module, Py_buffer *data, @@ -538,8 +590,8 @@ _codecs_utf_16_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -560,7 +612,7 @@ PyDoc_STRVAR(_codecs_utf_16_le_decode__doc__, "\n"); #define _CODECS_UTF_16_LE_DECODE_METHODDEF \ - {"utf_16_le_decode", (PyCFunction)(void(*)(void))_codecs_utf_16_le_decode, METH_FASTCALL, _codecs_utf_16_le_decode__doc__}, + {"utf_16_le_decode", _PyCFunction_CAST(_codecs_utf_16_le_decode), METH_FASTCALL, _codecs_utf_16_le_decode__doc__}, static PyObject * _codecs_utf_16_le_decode_impl(PyObject *module, Py_buffer *data, @@ -608,8 +660,8 @@ _codecs_utf_16_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -630,7 +682,7 @@ PyDoc_STRVAR(_codecs_utf_16_be_decode__doc__, "\n"); #define _CODECS_UTF_16_BE_DECODE_METHODDEF \ - {"utf_16_be_decode", (PyCFunction)(void(*)(void))_codecs_utf_16_be_decode, METH_FASTCALL, _codecs_utf_16_be_decode__doc__}, + {"utf_16_be_decode", _PyCFunction_CAST(_codecs_utf_16_be_decode), METH_FASTCALL, _codecs_utf_16_be_decode__doc__}, static PyObject * _codecs_utf_16_be_decode_impl(PyObject *module, Py_buffer *data, @@ -678,8 +730,8 @@ _codecs_utf_16_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -701,7 +753,7 @@ PyDoc_STRVAR(_codecs_utf_16_ex_decode__doc__, "\n"); #define _CODECS_UTF_16_EX_DECODE_METHODDEF \ - {"utf_16_ex_decode", (PyCFunction)(void(*)(void))_codecs_utf_16_ex_decode, METH_FASTCALL, _codecs_utf_16_ex_decode__doc__}, + {"utf_16_ex_decode", _PyCFunction_CAST(_codecs_utf_16_ex_decode), METH_FASTCALL, _codecs_utf_16_ex_decode__doc__}, static PyObject * _codecs_utf_16_ex_decode_impl(PyObject *module, Py_buffer *data, @@ -757,8 +809,8 @@ _codecs_utf_16_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 4) { goto skip_optional; } - final = _PyLong_AsInt(args[3]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[3]); + if (final < 0) { goto exit; } skip_optional: @@ -779,7 +831,7 @@ PyDoc_STRVAR(_codecs_utf_32_decode__doc__, "\n"); #define _CODECS_UTF_32_DECODE_METHODDEF \ - {"utf_32_decode", (PyCFunction)(void(*)(void))_codecs_utf_32_decode, METH_FASTCALL, _codecs_utf_32_decode__doc__}, + {"utf_32_decode", _PyCFunction_CAST(_codecs_utf_32_decode), METH_FASTCALL, _codecs_utf_32_decode__doc__}, static PyObject * _codecs_utf_32_decode_impl(PyObject *module, Py_buffer *data, @@ -827,8 +879,8 @@ _codecs_utf_32_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -849,7 +901,7 @@ PyDoc_STRVAR(_codecs_utf_32_le_decode__doc__, "\n"); #define _CODECS_UTF_32_LE_DECODE_METHODDEF \ - {"utf_32_le_decode", (PyCFunction)(void(*)(void))_codecs_utf_32_le_decode, METH_FASTCALL, _codecs_utf_32_le_decode__doc__}, + {"utf_32_le_decode", _PyCFunction_CAST(_codecs_utf_32_le_decode), METH_FASTCALL, _codecs_utf_32_le_decode__doc__}, static PyObject * _codecs_utf_32_le_decode_impl(PyObject *module, Py_buffer *data, @@ -897,8 +949,8 @@ _codecs_utf_32_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -919,7 +971,7 @@ PyDoc_STRVAR(_codecs_utf_32_be_decode__doc__, "\n"); #define _CODECS_UTF_32_BE_DECODE_METHODDEF \ - {"utf_32_be_decode", (PyCFunction)(void(*)(void))_codecs_utf_32_be_decode, METH_FASTCALL, _codecs_utf_32_be_decode__doc__}, + {"utf_32_be_decode", _PyCFunction_CAST(_codecs_utf_32_be_decode), METH_FASTCALL, _codecs_utf_32_be_decode__doc__}, static PyObject * _codecs_utf_32_be_decode_impl(PyObject *module, Py_buffer *data, @@ -967,8 +1019,8 @@ _codecs_utf_32_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -990,7 +1042,7 @@ PyDoc_STRVAR(_codecs_utf_32_ex_decode__doc__, "\n"); #define _CODECS_UTF_32_EX_DECODE_METHODDEF \ - {"utf_32_ex_decode", (PyCFunction)(void(*)(void))_codecs_utf_32_ex_decode, METH_FASTCALL, _codecs_utf_32_ex_decode__doc__}, + {"utf_32_ex_decode", _PyCFunction_CAST(_codecs_utf_32_ex_decode), METH_FASTCALL, _codecs_utf_32_ex_decode__doc__}, static PyObject * _codecs_utf_32_ex_decode_impl(PyObject *module, Py_buffer *data, @@ -1046,8 +1098,8 @@ _codecs_utf_32_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 4) { goto skip_optional; } - final = _PyLong_AsInt(args[3]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[3]); + if (final < 0) { goto exit; } skip_optional: @@ -1068,7 +1120,7 @@ PyDoc_STRVAR(_codecs_unicode_escape_decode__doc__, "\n"); #define _CODECS_UNICODE_ESCAPE_DECODE_METHODDEF \ - {"unicode_escape_decode", (PyCFunction)(void(*)(void))_codecs_unicode_escape_decode, METH_FASTCALL, _codecs_unicode_escape_decode__doc__}, + {"unicode_escape_decode", _PyCFunction_CAST(_codecs_unicode_escape_decode), METH_FASTCALL, _codecs_unicode_escape_decode__doc__}, static PyObject * _codecs_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, @@ -1126,8 +1178,8 @@ _codecs_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_ if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -1148,7 +1200,7 @@ PyDoc_STRVAR(_codecs_raw_unicode_escape_decode__doc__, "\n"); #define _CODECS_RAW_UNICODE_ESCAPE_DECODE_METHODDEF \ - {"raw_unicode_escape_decode", (PyCFunction)(void(*)(void))_codecs_raw_unicode_escape_decode, METH_FASTCALL, _codecs_raw_unicode_escape_decode__doc__}, + {"raw_unicode_escape_decode", _PyCFunction_CAST(_codecs_raw_unicode_escape_decode), METH_FASTCALL, _codecs_raw_unicode_escape_decode__doc__}, static PyObject * _codecs_raw_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, @@ -1206,8 +1258,8 @@ _codecs_raw_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ss if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -1228,7 +1280,7 @@ PyDoc_STRVAR(_codecs_latin_1_decode__doc__, "\n"); #define _CODECS_LATIN_1_DECODE_METHODDEF \ - {"latin_1_decode", (PyCFunction)(void(*)(void))_codecs_latin_1_decode, METH_FASTCALL, _codecs_latin_1_decode__doc__}, + {"latin_1_decode", _PyCFunction_CAST(_codecs_latin_1_decode), METH_FASTCALL, _codecs_latin_1_decode__doc__}, static PyObject * _codecs_latin_1_decode_impl(PyObject *module, Py_buffer *data, @@ -1290,7 +1342,7 @@ PyDoc_STRVAR(_codecs_ascii_decode__doc__, "\n"); #define _CODECS_ASCII_DECODE_METHODDEF \ - {"ascii_decode", (PyCFunction)(void(*)(void))_codecs_ascii_decode, METH_FASTCALL, _codecs_ascii_decode__doc__}, + {"ascii_decode", _PyCFunction_CAST(_codecs_ascii_decode), METH_FASTCALL, _codecs_ascii_decode__doc__}, static PyObject * _codecs_ascii_decode_impl(PyObject *module, Py_buffer *data, @@ -1352,7 +1404,7 @@ PyDoc_STRVAR(_codecs_charmap_decode__doc__, "\n"); #define _CODECS_CHARMAP_DECODE_METHODDEF \ - {"charmap_decode", (PyCFunction)(void(*)(void))_codecs_charmap_decode, METH_FASTCALL, _codecs_charmap_decode__doc__}, + {"charmap_decode", _PyCFunction_CAST(_codecs_charmap_decode), METH_FASTCALL, _codecs_charmap_decode__doc__}, static PyObject * _codecs_charmap_decode_impl(PyObject *module, Py_buffer *data, @@ -1421,7 +1473,7 @@ PyDoc_STRVAR(_codecs_mbcs_decode__doc__, "\n"); #define _CODECS_MBCS_DECODE_METHODDEF \ - {"mbcs_decode", (PyCFunction)(void(*)(void))_codecs_mbcs_decode, METH_FASTCALL, _codecs_mbcs_decode__doc__}, + {"mbcs_decode", _PyCFunction_CAST(_codecs_mbcs_decode), METH_FASTCALL, _codecs_mbcs_decode__doc__}, static PyObject * _codecs_mbcs_decode_impl(PyObject *module, Py_buffer *data, @@ -1469,8 +1521,8 @@ _codecs_mbcs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -1495,7 +1547,7 @@ PyDoc_STRVAR(_codecs_oem_decode__doc__, "\n"); #define _CODECS_OEM_DECODE_METHODDEF \ - {"oem_decode", (PyCFunction)(void(*)(void))_codecs_oem_decode, METH_FASTCALL, _codecs_oem_decode__doc__}, + {"oem_decode", _PyCFunction_CAST(_codecs_oem_decode), METH_FASTCALL, _codecs_oem_decode__doc__}, static PyObject * _codecs_oem_decode_impl(PyObject *module, Py_buffer *data, @@ -1543,8 +1595,8 @@ _codecs_oem_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -1569,7 +1621,7 @@ PyDoc_STRVAR(_codecs_code_page_decode__doc__, "\n"); #define _CODECS_CODE_PAGE_DECODE_METHODDEF \ - {"code_page_decode", (PyCFunction)(void(*)(void))_codecs_code_page_decode, METH_FASTCALL, _codecs_code_page_decode__doc__}, + {"code_page_decode", _PyCFunction_CAST(_codecs_code_page_decode), METH_FASTCALL, _codecs_code_page_decode__doc__}, static PyObject * _codecs_code_page_decode_impl(PyObject *module, int codepage, @@ -1622,8 +1674,8 @@ _codecs_code_page_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 4) { goto skip_optional; } - final = _PyLong_AsInt(args[3]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[3]); + if (final < 0) { goto exit; } skip_optional: @@ -1646,7 +1698,7 @@ PyDoc_STRVAR(_codecs_readbuffer_encode__doc__, "\n"); #define _CODECS_READBUFFER_ENCODE_METHODDEF \ - {"readbuffer_encode", (PyCFunction)(void(*)(void))_codecs_readbuffer_encode, METH_FASTCALL, _codecs_readbuffer_encode__doc__}, + {"readbuffer_encode", _PyCFunction_CAST(_codecs_readbuffer_encode), METH_FASTCALL, _codecs_readbuffer_encode__doc__}, static PyObject * _codecs_readbuffer_encode_impl(PyObject *module, Py_buffer *data, @@ -1718,7 +1770,7 @@ PyDoc_STRVAR(_codecs_utf_7_encode__doc__, "\n"); #define _CODECS_UTF_7_ENCODE_METHODDEF \ - {"utf_7_encode", (PyCFunction)(void(*)(void))_codecs_utf_7_encode, METH_FASTCALL, _codecs_utf_7_encode__doc__}, + {"utf_7_encode", _PyCFunction_CAST(_codecs_utf_7_encode), METH_FASTCALL, _codecs_utf_7_encode__doc__}, static PyObject * _codecs_utf_7_encode_impl(PyObject *module, PyObject *str, @@ -1776,7 +1828,7 @@ PyDoc_STRVAR(_codecs_utf_8_encode__doc__, "\n"); #define _CODECS_UTF_8_ENCODE_METHODDEF \ - {"utf_8_encode", (PyCFunction)(void(*)(void))_codecs_utf_8_encode, METH_FASTCALL, _codecs_utf_8_encode__doc__}, + {"utf_8_encode", _PyCFunction_CAST(_codecs_utf_8_encode), METH_FASTCALL, _codecs_utf_8_encode__doc__}, static PyObject * _codecs_utf_8_encode_impl(PyObject *module, PyObject *str, @@ -1834,7 +1886,7 @@ PyDoc_STRVAR(_codecs_utf_16_encode__doc__, "\n"); #define _CODECS_UTF_16_ENCODE_METHODDEF \ - {"utf_16_encode", (PyCFunction)(void(*)(void))_codecs_utf_16_encode, METH_FASTCALL, _codecs_utf_16_encode__doc__}, + {"utf_16_encode", _PyCFunction_CAST(_codecs_utf_16_encode), METH_FASTCALL, _codecs_utf_16_encode__doc__}, static PyObject * _codecs_utf_16_encode_impl(PyObject *module, PyObject *str, @@ -1900,7 +1952,7 @@ PyDoc_STRVAR(_codecs_utf_16_le_encode__doc__, "\n"); #define _CODECS_UTF_16_LE_ENCODE_METHODDEF \ - {"utf_16_le_encode", (PyCFunction)(void(*)(void))_codecs_utf_16_le_encode, METH_FASTCALL, _codecs_utf_16_le_encode__doc__}, + {"utf_16_le_encode", _PyCFunction_CAST(_codecs_utf_16_le_encode), METH_FASTCALL, _codecs_utf_16_le_encode__doc__}, static PyObject * _codecs_utf_16_le_encode_impl(PyObject *module, PyObject *str, @@ -1958,7 +2010,7 @@ PyDoc_STRVAR(_codecs_utf_16_be_encode__doc__, "\n"); #define _CODECS_UTF_16_BE_ENCODE_METHODDEF \ - {"utf_16_be_encode", (PyCFunction)(void(*)(void))_codecs_utf_16_be_encode, METH_FASTCALL, _codecs_utf_16_be_encode__doc__}, + {"utf_16_be_encode", _PyCFunction_CAST(_codecs_utf_16_be_encode), METH_FASTCALL, _codecs_utf_16_be_encode__doc__}, static PyObject * _codecs_utf_16_be_encode_impl(PyObject *module, PyObject *str, @@ -2016,7 +2068,7 @@ PyDoc_STRVAR(_codecs_utf_32_encode__doc__, "\n"); #define _CODECS_UTF_32_ENCODE_METHODDEF \ - {"utf_32_encode", (PyCFunction)(void(*)(void))_codecs_utf_32_encode, METH_FASTCALL, _codecs_utf_32_encode__doc__}, + {"utf_32_encode", _PyCFunction_CAST(_codecs_utf_32_encode), METH_FASTCALL, _codecs_utf_32_encode__doc__}, static PyObject * _codecs_utf_32_encode_impl(PyObject *module, PyObject *str, @@ -2082,7 +2134,7 @@ PyDoc_STRVAR(_codecs_utf_32_le_encode__doc__, "\n"); #define _CODECS_UTF_32_LE_ENCODE_METHODDEF \ - {"utf_32_le_encode", (PyCFunction)(void(*)(void))_codecs_utf_32_le_encode, METH_FASTCALL, _codecs_utf_32_le_encode__doc__}, + {"utf_32_le_encode", _PyCFunction_CAST(_codecs_utf_32_le_encode), METH_FASTCALL, _codecs_utf_32_le_encode__doc__}, static PyObject * _codecs_utf_32_le_encode_impl(PyObject *module, PyObject *str, @@ -2140,7 +2192,7 @@ PyDoc_STRVAR(_codecs_utf_32_be_encode__doc__, "\n"); #define _CODECS_UTF_32_BE_ENCODE_METHODDEF \ - {"utf_32_be_encode", (PyCFunction)(void(*)(void))_codecs_utf_32_be_encode, METH_FASTCALL, _codecs_utf_32_be_encode__doc__}, + {"utf_32_be_encode", _PyCFunction_CAST(_codecs_utf_32_be_encode), METH_FASTCALL, _codecs_utf_32_be_encode__doc__}, static PyObject * _codecs_utf_32_be_encode_impl(PyObject *module, PyObject *str, @@ -2198,7 +2250,7 @@ PyDoc_STRVAR(_codecs_unicode_escape_encode__doc__, "\n"); #define _CODECS_UNICODE_ESCAPE_ENCODE_METHODDEF \ - {"unicode_escape_encode", (PyCFunction)(void(*)(void))_codecs_unicode_escape_encode, METH_FASTCALL, _codecs_unicode_escape_encode__doc__}, + {"unicode_escape_encode", _PyCFunction_CAST(_codecs_unicode_escape_encode), METH_FASTCALL, _codecs_unicode_escape_encode__doc__}, static PyObject * _codecs_unicode_escape_encode_impl(PyObject *module, PyObject *str, @@ -2256,7 +2308,7 @@ PyDoc_STRVAR(_codecs_raw_unicode_escape_encode__doc__, "\n"); #define _CODECS_RAW_UNICODE_ESCAPE_ENCODE_METHODDEF \ - {"raw_unicode_escape_encode", (PyCFunction)(void(*)(void))_codecs_raw_unicode_escape_encode, METH_FASTCALL, _codecs_raw_unicode_escape_encode__doc__}, + {"raw_unicode_escape_encode", _PyCFunction_CAST(_codecs_raw_unicode_escape_encode), METH_FASTCALL, _codecs_raw_unicode_escape_encode__doc__}, static PyObject * _codecs_raw_unicode_escape_encode_impl(PyObject *module, PyObject *str, @@ -2314,7 +2366,7 @@ PyDoc_STRVAR(_codecs_latin_1_encode__doc__, "\n"); #define _CODECS_LATIN_1_ENCODE_METHODDEF \ - {"latin_1_encode", (PyCFunction)(void(*)(void))_codecs_latin_1_encode, METH_FASTCALL, _codecs_latin_1_encode__doc__}, + {"latin_1_encode", _PyCFunction_CAST(_codecs_latin_1_encode), METH_FASTCALL, _codecs_latin_1_encode__doc__}, static PyObject * _codecs_latin_1_encode_impl(PyObject *module, PyObject *str, @@ -2372,7 +2424,7 @@ PyDoc_STRVAR(_codecs_ascii_encode__doc__, "\n"); #define _CODECS_ASCII_ENCODE_METHODDEF \ - {"ascii_encode", (PyCFunction)(void(*)(void))_codecs_ascii_encode, METH_FASTCALL, _codecs_ascii_encode__doc__}, + {"ascii_encode", _PyCFunction_CAST(_codecs_ascii_encode), METH_FASTCALL, _codecs_ascii_encode__doc__}, static PyObject * _codecs_ascii_encode_impl(PyObject *module, PyObject *str, @@ -2430,7 +2482,7 @@ PyDoc_STRVAR(_codecs_charmap_encode__doc__, "\n"); #define _CODECS_CHARMAP_ENCODE_METHODDEF \ - {"charmap_encode", (PyCFunction)(void(*)(void))_codecs_charmap_encode, METH_FASTCALL, _codecs_charmap_encode__doc__}, + {"charmap_encode", _PyCFunction_CAST(_codecs_charmap_encode), METH_FASTCALL, _codecs_charmap_encode__doc__}, static PyObject * _codecs_charmap_encode_impl(PyObject *module, PyObject *str, @@ -2526,7 +2578,7 @@ PyDoc_STRVAR(_codecs_mbcs_encode__doc__, "\n"); #define _CODECS_MBCS_ENCODE_METHODDEF \ - {"mbcs_encode", (PyCFunction)(void(*)(void))_codecs_mbcs_encode, METH_FASTCALL, _codecs_mbcs_encode__doc__}, + {"mbcs_encode", _PyCFunction_CAST(_codecs_mbcs_encode), METH_FASTCALL, _codecs_mbcs_encode__doc__}, static PyObject * _codecs_mbcs_encode_impl(PyObject *module, PyObject *str, const char *errors); @@ -2587,7 +2639,7 @@ PyDoc_STRVAR(_codecs_oem_encode__doc__, "\n"); #define _CODECS_OEM_ENCODE_METHODDEF \ - {"oem_encode", (PyCFunction)(void(*)(void))_codecs_oem_encode, METH_FASTCALL, _codecs_oem_encode__doc__}, + {"oem_encode", _PyCFunction_CAST(_codecs_oem_encode), METH_FASTCALL, _codecs_oem_encode__doc__}, static PyObject * _codecs_oem_encode_impl(PyObject *module, PyObject *str, const char *errors); @@ -2648,7 +2700,7 @@ PyDoc_STRVAR(_codecs_code_page_encode__doc__, "\n"); #define _CODECS_CODE_PAGE_ENCODE_METHODDEF \ - {"code_page_encode", (PyCFunction)(void(*)(void))_codecs_code_page_encode, METH_FASTCALL, _codecs_code_page_encode__doc__}, + {"code_page_encode", _PyCFunction_CAST(_codecs_code_page_encode), METH_FASTCALL, _codecs_code_page_encode__doc__}, static PyObject * _codecs_code_page_encode_impl(PyObject *module, int code_page, PyObject *str, @@ -2718,7 +2770,7 @@ PyDoc_STRVAR(_codecs_register_error__doc__, "error and must return a (replacement, new position) tuple."); #define _CODECS_REGISTER_ERROR_METHODDEF \ - {"register_error", (PyCFunction)(void(*)(void))_codecs_register_error, METH_FASTCALL, _codecs_register_error__doc__}, + {"register_error", _PyCFunction_CAST(_codecs_register_error), METH_FASTCALL, _codecs_register_error__doc__}, static PyObject * _codecs_register_error_impl(PyObject *module, const char *errors, @@ -2817,4 +2869,4 @@ exit: #ifndef _CODECS_CODE_PAGE_ENCODE_METHODDEF #define _CODECS_CODE_PAGE_ENCODE_METHODDEF #endif /* !defined(_CODECS_CODE_PAGE_ENCODE_METHODDEF) */ -/*[clinic end generated code: output=814dae36b6f885cb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=603da07cf8dfeb4b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_collectionsmodule.c.h b/Modules/clinic/_collectionsmodule.c.h index 2875b3cd266..ad4da8856ac 100644 --- a/Modules/clinic/_collectionsmodule.c.h +++ b/Modules/clinic/_collectionsmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_collections__count_elements__doc__, "_count_elements($module, mapping, iterable, /)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(_collections__count_elements__doc__, "Count elements in the iterable, updating the mapping"); #define _COLLECTIONS__COUNT_ELEMENTS_METHODDEF \ - {"_count_elements", (PyCFunction)(void(*)(void))_collections__count_elements, METH_FASTCALL, _collections__count_elements__doc__}, + {"_count_elements", _PyCFunction_CAST(_collections__count_elements), METH_FASTCALL, _collections__count_elements__doc__}, static PyObject * _collections__count_elements_impl(PyObject *module, PyObject *mapping, @@ -69,4 +75,4 @@ tuplegetter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=3dfa12a35e655844 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=12168d58a11a4fb9 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_contextvarsmodule.c.h b/Modules/clinic/_contextvarsmodule.c.h index b1885e41c35..461d4845635 100644 --- a/Modules/clinic/_contextvarsmodule.c.h +++ b/Modules/clinic/_contextvarsmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_contextvars_copy_context__doc__, "copy_context($module, /)\n" "--\n" @@ -18,4 +24,4 @@ _contextvars_copy_context(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _contextvars_copy_context_impl(module); } -/*[clinic end generated code: output=26e07024451baf52 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1736c27450823e70 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cryptmodule.c.h b/Modules/clinic/_cryptmodule.c.h index ea91d7c130b..97b70b3c17e 100644 --- a/Modules/clinic/_cryptmodule.c.h +++ b/Modules/clinic/_cryptmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(crypt_crypt__doc__, "crypt($module, word, salt, /)\n" "--\n" @@ -14,7 +20,7 @@ PyDoc_STRVAR(crypt_crypt__doc__, "results for a given *word*."); #define CRYPT_CRYPT_METHODDEF \ - {"crypt", (PyCFunction)(void(*)(void))crypt_crypt, METH_FASTCALL, crypt_crypt__doc__}, + {"crypt", _PyCFunction_CAST(crypt_crypt), METH_FASTCALL, crypt_crypt__doc__}, static PyObject * crypt_crypt_impl(PyObject *module, const char *word, const char *salt); @@ -60,4 +66,4 @@ crypt_crypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=549de0d43b030126 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=235ccef9211184f4 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_csv.c.h b/Modules/clinic/_csv.c.h new file mode 100644 index 00000000000..8900946350a --- /dev/null +++ b/Modules/clinic/_csv.c.h @@ -0,0 +1,209 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(_csv_list_dialects__doc__, +"list_dialects($module, /)\n" +"--\n" +"\n" +"Return a list of all known dialect names.\n" +"\n" +" names = csv.list_dialects()"); + +#define _CSV_LIST_DIALECTS_METHODDEF \ + {"list_dialects", (PyCFunction)_csv_list_dialects, METH_NOARGS, _csv_list_dialects__doc__}, + +static PyObject * +_csv_list_dialects_impl(PyObject *module); + +static PyObject * +_csv_list_dialects(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _csv_list_dialects_impl(module); +} + +PyDoc_STRVAR(_csv_unregister_dialect__doc__, +"unregister_dialect($module, /, name)\n" +"--\n" +"\n" +"Delete the name/dialect mapping associated with a string name.\n" +"\n" +" csv.unregister_dialect(name)"); + +#define _CSV_UNREGISTER_DIALECT_METHODDEF \ + {"unregister_dialect", _PyCFunction_CAST(_csv_unregister_dialect), METH_FASTCALL|METH_KEYWORDS, _csv_unregister_dialect__doc__}, + +static PyObject * +_csv_unregister_dialect_impl(PyObject *module, PyObject *name); + +static PyObject * +_csv_unregister_dialect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"name", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unregister_dialect", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *name; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + name = args[0]; + return_value = _csv_unregister_dialect_impl(module, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_csv_get_dialect__doc__, +"get_dialect($module, /, name)\n" +"--\n" +"\n" +"Return the dialect instance associated with name.\n" +"\n" +" dialect = csv.get_dialect(name)"); + +#define _CSV_GET_DIALECT_METHODDEF \ + {"get_dialect", _PyCFunction_CAST(_csv_get_dialect), METH_FASTCALL|METH_KEYWORDS, _csv_get_dialect__doc__}, + +static PyObject * +_csv_get_dialect_impl(PyObject *module, PyObject *name); + +static PyObject * +_csv_get_dialect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"name", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get_dialect", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *name; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + name = args[0]; + return_value = _csv_get_dialect_impl(module, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_csv_field_size_limit__doc__, +"field_size_limit($module, /, new_limit=)\n" +"--\n" +"\n" +"Sets an upper limit on parsed fields.\n" +"\n" +" csv.field_size_limit([limit])\n" +"\n" +"Returns old limit. If limit is not given, no new limit is set and\n" +"the old limit is returned"); + +#define _CSV_FIELD_SIZE_LIMIT_METHODDEF \ + {"field_size_limit", _PyCFunction_CAST(_csv_field_size_limit), METH_FASTCALL|METH_KEYWORDS, _csv_field_size_limit__doc__}, + +static PyObject * +_csv_field_size_limit_impl(PyObject *module, PyObject *new_limit); + +static PyObject * +_csv_field_size_limit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(new_limit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"new_limit", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "field_size_limit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *new_limit = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + new_limit = args[0]; +skip_optional_pos: + return_value = _csv_field_size_limit_impl(module, new_limit); + +exit: + return return_value; +} +/*[clinic end generated code: output=94374e41eb2806ee input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_curses_panel.c.h b/Modules/clinic/_curses_panel.c.h index 45898070b1f..bb6cc90f043 100644 --- a/Modules/clinic/_curses_panel.c.h +++ b/Modules/clinic/_curses_panel.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, "bottom($self, /)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, "Push the panel to the bottom of the stack."); #define _CURSES_PANEL_PANEL_BOTTOM_METHODDEF \ - {"bottom", (PyCFunction)(void(*)(void))_curses_panel_panel_bottom, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_bottom__doc__}, + {"bottom", _PyCFunction_CAST(_curses_panel_panel_bottom), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_bottom__doc__}, static PyObject * _curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls); @@ -17,18 +23,11 @@ _curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * _curses_panel_panel_bottom(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":bottom", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "bottom() takes no arguments"); + return NULL; } - return_value = _curses_panel_panel_bottom_impl(self, cls); - -exit: - return return_value; + return _curses_panel_panel_bottom_impl(self, cls); } PyDoc_STRVAR(_curses_panel_panel_hide__doc__, @@ -40,7 +39,7 @@ PyDoc_STRVAR(_curses_panel_panel_hide__doc__, "This does not delete the object, it just makes the window on screen invisible."); #define _CURSES_PANEL_PANEL_HIDE_METHODDEF \ - {"hide", (PyCFunction)(void(*)(void))_curses_panel_panel_hide, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_hide__doc__}, + {"hide", _PyCFunction_CAST(_curses_panel_panel_hide), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_hide__doc__}, static PyObject * _curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls); @@ -48,18 +47,11 @@ _curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * _curses_panel_panel_hide(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":hide", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "hide() takes no arguments"); + return NULL; } - return_value = _curses_panel_panel_hide_impl(self, cls); - -exit: - return return_value; + return _curses_panel_panel_hide_impl(self, cls); } PyDoc_STRVAR(_curses_panel_panel_show__doc__, @@ -69,7 +61,7 @@ PyDoc_STRVAR(_curses_panel_panel_show__doc__, "Display the panel (which might have been hidden)."); #define _CURSES_PANEL_PANEL_SHOW_METHODDEF \ - {"show", (PyCFunction)(void(*)(void))_curses_panel_panel_show, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_show__doc__}, + {"show", _PyCFunction_CAST(_curses_panel_panel_show), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_show__doc__}, static PyObject * _curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls); @@ -77,18 +69,11 @@ _curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * _curses_panel_panel_show(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":show", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "show() takes no arguments"); + return NULL; } - return_value = _curses_panel_panel_show_impl(self, cls); - -exit: - return return_value; + return _curses_panel_panel_show_impl(self, cls); } PyDoc_STRVAR(_curses_panel_panel_top__doc__, @@ -98,7 +83,7 @@ PyDoc_STRVAR(_curses_panel_panel_top__doc__, "Push panel to the top of the stack."); #define _CURSES_PANEL_PANEL_TOP_METHODDEF \ - {"top", (PyCFunction)(void(*)(void))_curses_panel_panel_top, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_top__doc__}, + {"top", _PyCFunction_CAST(_curses_panel_panel_top), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_top__doc__}, static PyObject * _curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls); @@ -106,18 +91,11 @@ _curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls); static PyObject * _curses_panel_panel_top(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":top", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "top() takes no arguments"); + return NULL; } - return_value = _curses_panel_panel_top_impl(self, cls); - -exit: - return return_value; + return _curses_panel_panel_top_impl(self, cls); } PyDoc_STRVAR(_curses_panel_panel_above__doc__, @@ -181,7 +159,7 @@ PyDoc_STRVAR(_curses_panel_panel_move__doc__, "Move the panel to the screen coordinates (y, x)."); #define _CURSES_PANEL_PANEL_MOVE_METHODDEF \ - {"move", (PyCFunction)(void(*)(void))_curses_panel_panel_move, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_move__doc__}, + {"move", _PyCFunction_CAST(_curses_panel_panel_move), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_move__doc__}, static PyObject * _curses_panel_panel_move_impl(PyCursesPanelObject *self, PyTypeObject *cls, @@ -191,13 +169,33 @@ static PyObject * _curses_panel_panel_move(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {"ii:move", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "move", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; int y; int x; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &y, &x)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + y = _PyLong_AsInt(args[0]); + if (y == -1 && PyErr_Occurred()) { + goto exit; + } + x = _PyLong_AsInt(args[1]); + if (x == -1 && PyErr_Occurred()) { goto exit; } return_value = _curses_panel_panel_move_impl(self, cls, y, x); @@ -231,7 +229,7 @@ PyDoc_STRVAR(_curses_panel_panel_replace__doc__, "Change the window associated with the panel to the window win."); #define _CURSES_PANEL_PANEL_REPLACE_METHODDEF \ - {"replace", (PyCFunction)(void(*)(void))_curses_panel_panel_replace, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_replace__doc__}, + {"replace", _PyCFunction_CAST(_curses_panel_panel_replace), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_replace__doc__}, static PyObject * _curses_panel_panel_replace_impl(PyCursesPanelObject *self, @@ -242,14 +240,31 @@ static PyObject * _curses_panel_panel_replace(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"O!:replace", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "replace", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; PyCursesWindowObject *win; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &PyCursesWindow_Type, &win)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { goto exit; } + if (!PyObject_TypeCheck(args[0], &PyCursesWindow_Type)) { + _PyArg_BadArgument("replace", "argument 1", (&PyCursesWindow_Type)->tp_name, args[0]); + goto exit; + } + win = (PyCursesWindowObject *)args[0]; return_value = _curses_panel_panel_replace_impl(self, cls, win); exit: @@ -263,7 +278,7 @@ PyDoc_STRVAR(_curses_panel_panel_set_userptr__doc__, "Set the panel\'s user pointer to obj."); #define _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF \ - {"set_userptr", (PyCFunction)(void(*)(void))_curses_panel_panel_set_userptr, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_set_userptr__doc__}, + {"set_userptr", _PyCFunction_CAST(_curses_panel_panel_set_userptr), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_set_userptr__doc__}, static PyObject * _curses_panel_panel_set_userptr_impl(PyCursesPanelObject *self, @@ -273,14 +288,27 @@ static PyObject * _curses_panel_panel_set_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"O:set_userptr", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_userptr", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; PyObject *obj; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &obj)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { goto exit; } + obj = args[0]; return_value = _curses_panel_panel_set_userptr_impl(self, cls, obj); exit: @@ -294,7 +322,7 @@ PyDoc_STRVAR(_curses_panel_panel_userptr__doc__, "Return the user pointer for the panel."); #define _CURSES_PANEL_PANEL_USERPTR_METHODDEF \ - {"userptr", (PyCFunction)(void(*)(void))_curses_panel_panel_userptr, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_userptr__doc__}, + {"userptr", _PyCFunction_CAST(_curses_panel_panel_userptr), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_userptr__doc__}, static PyObject * _curses_panel_panel_userptr_impl(PyCursesPanelObject *self, @@ -303,18 +331,11 @@ _curses_panel_panel_userptr_impl(PyCursesPanelObject *self, static PyObject * _curses_panel_panel_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":userptr", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "userptr() takes no arguments"); + return NULL; } - return_value = _curses_panel_panel_userptr_impl(self, cls); - -exit: - return return_value; + return _curses_panel_panel_userptr_impl(self, cls); } PyDoc_STRVAR(_curses_panel_bottom_panel__doc__, @@ -401,4 +422,4 @@ _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _curses_panel_update_panels_impl(module); } -/*[clinic end generated code: output=3081ef24e5560cb0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8d0533681891523c input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h index 9c9611685b7..9d99d41af5d 100644 --- a/Modules/clinic/_cursesmodule.c.h +++ b/Modules/clinic/_cursesmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_curses_window_addch__doc__, "addch([y, x,] ch, [attr=_curses.A_NORMAL])\n" "Paint the character.\n" @@ -233,7 +239,7 @@ PyDoc_STRVAR(_curses_window_bkgd__doc__, " Background attributes."); #define _CURSES_WINDOW_BKGD_METHODDEF \ - {"bkgd", (PyCFunction)(void(*)(void))_curses_window_bkgd, METH_FASTCALL, _curses_window_bkgd__doc__}, + {"bkgd", _PyCFunction_CAST(_curses_window_bkgd), METH_FASTCALL, _curses_window_bkgd__doc__}, static PyObject * _curses_window_bkgd_impl(PyCursesWindowObject *self, PyObject *ch, long attr); @@ -359,7 +365,7 @@ PyDoc_STRVAR(_curses_window_bkgdset__doc__, " Background attributes."); #define _CURSES_WINDOW_BKGDSET_METHODDEF \ - {"bkgdset", (PyCFunction)(void(*)(void))_curses_window_bkgdset, METH_FASTCALL, _curses_window_bkgdset__doc__}, + {"bkgdset", _PyCFunction_CAST(_curses_window_bkgdset), METH_FASTCALL, _curses_window_bkgdset__doc__}, static PyObject * _curses_window_bkgdset_impl(PyCursesWindowObject *self, PyObject *ch, @@ -422,7 +428,7 @@ PyDoc_STRVAR(_curses_window_border__doc__, "used for that parameter."); #define _CURSES_WINDOW_BORDER_METHODDEF \ - {"border", (PyCFunction)(void(*)(void))_curses_window_border, METH_FASTCALL, _curses_window_border__doc__}, + {"border", _PyCFunction_CAST(_curses_window_border), METH_FASTCALL, _curses_window_border__doc__}, static PyObject * _curses_window_border_impl(PyCursesWindowObject *self, PyObject *ls, @@ -642,7 +648,7 @@ PyDoc_STRVAR(_curses_window_echochar__doc__, " Attributes for the character."); #define _CURSES_WINDOW_ECHOCHAR_METHODDEF \ - {"echochar", (PyCFunction)(void(*)(void))_curses_window_echochar, METH_FASTCALL, _curses_window_echochar__doc__}, + {"echochar", _PyCFunction_CAST(_curses_window_echochar), METH_FASTCALL, _curses_window_echochar__doc__}, static PyObject * _curses_window_echochar_impl(PyCursesWindowObject *self, PyObject *ch, @@ -687,7 +693,7 @@ PyDoc_STRVAR(_curses_window_enclose__doc__, " X-coordinate."); #define _CURSES_WINDOW_ENCLOSE_METHODDEF \ - {"enclose", (PyCFunction)(void(*)(void))_curses_window_enclose, METH_FASTCALL, _curses_window_enclose__doc__}, + {"enclose", _PyCFunction_CAST(_curses_window_enclose), METH_FASTCALL, _curses_window_enclose__doc__}, static PyObject * _curses_window_enclose_impl(PyCursesWindowObject *self, int y, int x); @@ -1487,7 +1493,7 @@ PyDoc_STRVAR(_curses_window_redrawln__doc__, "They should be completely redrawn on the next refresh() call."); #define _CURSES_WINDOW_REDRAWLN_METHODDEF \ - {"redrawln", (PyCFunction)(void(*)(void))_curses_window_redrawln, METH_FASTCALL, _curses_window_redrawln__doc__}, + {"redrawln", _PyCFunction_CAST(_curses_window_redrawln), METH_FASTCALL, _curses_window_redrawln__doc__}, static PyObject * _curses_window_redrawln_impl(PyCursesWindowObject *self, int beg, int num); @@ -1585,7 +1591,7 @@ PyDoc_STRVAR(_curses_window_setscrreg__doc__, "All scrolling actions will take place in this region."); #define _CURSES_WINDOW_SETSCRREG_METHODDEF \ - {"setscrreg", (PyCFunction)(void(*)(void))_curses_window_setscrreg, METH_FASTCALL, _curses_window_setscrreg__doc__}, + {"setscrreg", _PyCFunction_CAST(_curses_window_setscrreg), METH_FASTCALL, _curses_window_setscrreg__doc__}, static PyObject * _curses_window_setscrreg_impl(PyCursesWindowObject *self, int top, @@ -1742,7 +1748,7 @@ _curses_window_touchline(PyCursesWindowObject *self, PyObject *args) } break; case 3: - if (!PyArg_ParseTuple(args, "iii:touchline", &start, &count, &changed)) { + if (!PyArg_ParseTuple(args, "iip:touchline", &start, &count, &changed)) { goto exit; } group_right_1 = 1; @@ -1918,7 +1924,7 @@ PyDoc_STRVAR(_curses_cbreak__doc__, "Calling first raw() then cbreak() leaves the terminal in cbreak mode."); #define _CURSES_CBREAK_METHODDEF \ - {"cbreak", (PyCFunction)(void(*)(void))_curses_cbreak, METH_FASTCALL, _curses_cbreak__doc__}, + {"cbreak", _PyCFunction_CAST(_curses_cbreak), METH_FASTCALL, _curses_cbreak__doc__}, static PyObject * _curses_cbreak_impl(PyObject *module, int flag); @@ -1935,8 +1941,8 @@ _curses_cbreak(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - flag = _PyLong_AsInt(args[0]); - if (flag == -1 && PyErr_Occurred()) { + flag = PyObject_IsTrue(args[0]); + if (flag < 0) { goto exit; } skip_optional: @@ -2154,7 +2160,7 @@ PyDoc_STRVAR(_curses_echo__doc__, "In echo mode, each character input is echoed to the screen as it is entered."); #define _CURSES_ECHO_METHODDEF \ - {"echo", (PyCFunction)(void(*)(void))_curses_echo, METH_FASTCALL, _curses_echo__doc__}, + {"echo", _PyCFunction_CAST(_curses_echo), METH_FASTCALL, _curses_echo__doc__}, static PyObject * _curses_echo_impl(PyObject *module, int flag); @@ -2171,8 +2177,8 @@ _curses_echo(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - flag = _PyLong_AsInt(args[0]); - if (flag == -1 && PyErr_Occurred()) { + flag = PyObject_IsTrue(args[0]); + if (flag < 0) { goto exit; } skip_optional: @@ -2319,7 +2325,7 @@ PyDoc_STRVAR(_curses_ungetmouse__doc__, "The following getmouse() will return the given state data."); #define _CURSES_UNGETMOUSE_METHODDEF \ - {"ungetmouse", (PyCFunction)(void(*)(void))_curses_ungetmouse, METH_FASTCALL, _curses_ungetmouse__doc__}, + {"ungetmouse", _PyCFunction_CAST(_curses_ungetmouse), METH_FASTCALL, _curses_ungetmouse__doc__}, static PyObject * _curses_ungetmouse_impl(PyObject *module, short id, int x, int y, int z, @@ -2551,7 +2557,7 @@ PyDoc_STRVAR(_curses_init_color__doc__, "most terminals; it is active only if can_change_color() returns true."); #define _CURSES_INIT_COLOR_METHODDEF \ - {"init_color", (PyCFunction)(void(*)(void))_curses_init_color, METH_FASTCALL, _curses_init_color__doc__}, + {"init_color", _PyCFunction_CAST(_curses_init_color), METH_FASTCALL, _curses_init_color__doc__}, static PyObject * _curses_init_color_impl(PyObject *module, int color_number, short r, short g, @@ -2604,7 +2610,7 @@ PyDoc_STRVAR(_curses_init_pair__doc__, "all occurrences of that color-pair are changed to the new definition."); #define _CURSES_INIT_PAIR_METHODDEF \ - {"init_pair", (PyCFunction)(void(*)(void))_curses_init_pair, METH_FASTCALL, _curses_init_pair__doc__}, + {"init_pair", _PyCFunction_CAST(_curses_init_pair), METH_FASTCALL, _curses_init_pair__doc__}, static PyObject * _curses_init_pair_impl(PyObject *module, int pair_number, int fg, int bg); @@ -2669,7 +2675,7 @@ PyDoc_STRVAR(_curses_setupterm__doc__, " If not supplied, the file descriptor for sys.stdout will be used."); #define _CURSES_SETUPTERM_METHODDEF \ - {"setupterm", (PyCFunction)(void(*)(void))_curses_setupterm, METH_FASTCALL|METH_KEYWORDS, _curses_setupterm__doc__}, + {"setupterm", _PyCFunction_CAST(_curses_setupterm), METH_FASTCALL|METH_KEYWORDS, _curses_setupterm__doc__}, static PyObject * _curses_setupterm_impl(PyObject *module, const char *term, int fd); @@ -2678,8 +2684,31 @@ static PyObject * _curses_setupterm(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(term), &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"term", "fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "setupterm", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "setupterm", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *term = NULL; @@ -2871,8 +2900,8 @@ _curses_intrflush(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int flag; - flag = _PyLong_AsInt(arg); - if (flag == -1 && PyErr_Occurred()) { + flag = PyObject_IsTrue(arg); + if (flag < 0) { goto exit; } return_value = _curses_intrflush_impl(module, flag); @@ -2913,7 +2942,7 @@ PyDoc_STRVAR(_curses_is_term_resized__doc__, " Width."); #define _CURSES_IS_TERM_RESIZED_METHODDEF \ - {"is_term_resized", (PyCFunction)(void(*)(void))_curses_is_term_resized, METH_FASTCALL, _curses_is_term_resized__doc__}, + {"is_term_resized", _PyCFunction_CAST(_curses_is_term_resized), METH_FASTCALL, _curses_is_term_resized__doc__}, static PyObject * _curses_is_term_resized_impl(PyObject *module, int nlines, int ncols); @@ -3035,8 +3064,8 @@ _curses_meta(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int yes; - yes = _PyLong_AsInt(arg); - if (yes == -1 && PyErr_Occurred()) { + yes = PyObject_IsTrue(arg); + if (yes < 0) { goto exit; } return_value = _curses_meta_impl(module, yes); @@ -3165,7 +3194,7 @@ PyDoc_STRVAR(_curses_newpad__doc__, " Width."); #define _CURSES_NEWPAD_METHODDEF \ - {"newpad", (PyCFunction)(void(*)(void))_curses_newpad, METH_FASTCALL, _curses_newpad__doc__}, + {"newpad", _PyCFunction_CAST(_curses_newpad), METH_FASTCALL, _curses_newpad__doc__}, static PyObject * _curses_newpad_impl(PyObject *module, int nlines, int ncols); @@ -3262,7 +3291,7 @@ PyDoc_STRVAR(_curses_nl__doc__, "newline into return and line-feed on output. Newline mode is initially on."); #define _CURSES_NL_METHODDEF \ - {"nl", (PyCFunction)(void(*)(void))_curses_nl, METH_FASTCALL, _curses_nl__doc__}, + {"nl", _PyCFunction_CAST(_curses_nl), METH_FASTCALL, _curses_nl__doc__}, static PyObject * _curses_nl_impl(PyObject *module, int flag); @@ -3279,8 +3308,8 @@ _curses_nl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - flag = _PyLong_AsInt(args[0]); - if (flag == -1 && PyErr_Occurred()) { + flag = PyObject_IsTrue(args[0]); + if (flag < 0) { goto exit; } skip_optional: @@ -3494,7 +3523,7 @@ PyDoc_STRVAR(_curses_qiflush__doc__, "will be flushed when the INTR, QUIT and SUSP characters are read."); #define _CURSES_QIFLUSH_METHODDEF \ - {"qiflush", (PyCFunction)(void(*)(void))_curses_qiflush, METH_FASTCALL, _curses_qiflush__doc__}, + {"qiflush", _PyCFunction_CAST(_curses_qiflush), METH_FASTCALL, _curses_qiflush__doc__}, static PyObject * _curses_qiflush_impl(PyObject *module, int flag); @@ -3511,8 +3540,8 @@ _curses_qiflush(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - flag = _PyLong_AsInt(args[0]); - if (flag == -1 && PyErr_Occurred()) { + flag = PyObject_IsTrue(args[0]); + if (flag < 0) { goto exit; } skip_optional: @@ -3557,7 +3586,7 @@ PyDoc_STRVAR(_curses_raw__doc__, "curses input functions one by one."); #define _CURSES_RAW_METHODDEF \ - {"raw", (PyCFunction)(void(*)(void))_curses_raw, METH_FASTCALL, _curses_raw__doc__}, + {"raw", _PyCFunction_CAST(_curses_raw), METH_FASTCALL, _curses_raw__doc__}, static PyObject * _curses_raw_impl(PyObject *module, int flag); @@ -3574,8 +3603,8 @@ _curses_raw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - flag = _PyLong_AsInt(args[0]); - if (flag == -1 && PyErr_Occurred()) { + flag = PyObject_IsTrue(args[0]); + if (flag < 0) { goto exit; } skip_optional: @@ -3656,7 +3685,7 @@ PyDoc_STRVAR(_curses_resizeterm__doc__, "window dimensions (in particular the SIGWINCH handler)."); #define _CURSES_RESIZETERM_METHODDEF \ - {"resizeterm", (PyCFunction)(void(*)(void))_curses_resizeterm, METH_FASTCALL, _curses_resizeterm__doc__}, + {"resizeterm", _PyCFunction_CAST(_curses_resizeterm), METH_FASTCALL, _curses_resizeterm__doc__}, static PyObject * _curses_resizeterm_impl(PyObject *module, int nlines, int ncols); @@ -3707,7 +3736,7 @@ PyDoc_STRVAR(_curses_resize_term__doc__, "without additional interaction with the application."); #define _CURSES_RESIZE_TERM_METHODDEF \ - {"resize_term", (PyCFunction)(void(*)(void))_curses_resize_term, METH_FASTCALL, _curses_resize_term__doc__}, + {"resize_term", _PyCFunction_CAST(_curses_resize_term), METH_FASTCALL, _curses_resize_term__doc__}, static PyObject * _curses_resize_term_impl(PyObject *module, int nlines, int ncols); @@ -3772,7 +3801,7 @@ PyDoc_STRVAR(_curses_setsyx__doc__, "If y and x are both -1, then leaveok is set."); #define _CURSES_SETSYX_METHODDEF \ - {"setsyx", (PyCFunction)(void(*)(void))_curses_setsyx, METH_FASTCALL, _curses_setsyx__doc__}, + {"setsyx", _PyCFunction_CAST(_curses_setsyx), METH_FASTCALL, _curses_setsyx__doc__}, static PyObject * _curses_setsyx_impl(PyObject *module, int y, int x); @@ -4004,7 +4033,7 @@ PyDoc_STRVAR(_curses_tparm__doc__, " Parameterized byte string obtained from the terminfo database."); #define _CURSES_TPARM_METHODDEF \ - {"tparm", (PyCFunction)(void(*)(void))_curses_tparm, METH_FASTCALL, _curses_tparm__doc__}, + {"tparm", _PyCFunction_CAST(_curses_tparm), METH_FASTCALL, _curses_tparm__doc__}, static PyObject * _curses_tparm_impl(PyObject *module, const char *str, int i1, int i2, int i3, @@ -4135,8 +4164,8 @@ _curses_use_env(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int flag; - flag = _PyLong_AsInt(arg); - if (flag == -1 && PyErr_Occurred()) { + flag = PyObject_IsTrue(arg); + if (flag < 0) { goto exit; } return_value = _curses_use_env_impl(module, flag); @@ -4284,4 +4313,4 @@ _curses_has_extended_color_support(PyObject *module, PyObject *Py_UNUSED(ignored #ifndef _CURSES_USE_DEFAULT_COLORS_METHODDEF #define _CURSES_USE_DEFAULT_COLORS_METHODDEF #endif /* !defined(_CURSES_USE_DEFAULT_COLORS_METHODDEF) */ -/*[clinic end generated code: output=9efc9943a3ac3741 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=27a2364193b503c1 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_datetimemodule.c.h b/Modules/clinic/_datetimemodule.c.h index 7bd7c1986dc..51e51e3791c 100644 --- a/Modules/clinic/_datetimemodule.c.h +++ b/Modules/clinic/_datetimemodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(datetime_date_fromtimestamp__doc__, "fromtimestamp($type, timestamp, /)\n" "--\n" @@ -22,8 +28,31 @@ static PyObject * iso_calendar_date_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(year), &_Py_ID(week), &_Py_ID(weekday), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"year", "week", "weekday", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "IsoCalendarDate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "IsoCalendarDate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -65,7 +94,7 @@ PyDoc_STRVAR(datetime_datetime_now__doc__, "If no tz is specified, uses local timezone."); #define DATETIME_DATETIME_NOW_METHODDEF \ - {"now", (PyCFunction)(void(*)(void))datetime_datetime_now, METH_FASTCALL|METH_KEYWORDS|METH_CLASS, datetime_datetime_now__doc__}, + {"now", _PyCFunction_CAST(datetime_datetime_now), METH_FASTCALL|METH_KEYWORDS|METH_CLASS, datetime_datetime_now__doc__}, static PyObject * datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz); @@ -74,8 +103,31 @@ static PyObject * datetime_datetime_now(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tz), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"tz", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "now", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "now", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *tz = Py_None; @@ -94,4 +146,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=f61310936e3d8091 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=42654669940e0e3a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_dbmmodule.c.h b/Modules/clinic/_dbmmodule.c.h index f0b8220e7fe..172dc4b9d57 100644 --- a/Modules/clinic/_dbmmodule.c.h +++ b/Modules/clinic/_dbmmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_dbm_dbm_close__doc__, "close($self, /)\n" "--\n" @@ -27,7 +33,7 @@ PyDoc_STRVAR(_dbm_dbm_keys__doc__, "Return a list of all keys in the database."); #define _DBM_DBM_KEYS_METHODDEF \ - {"keys", (PyCFunction)(void(*)(void))_dbm_dbm_keys, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_keys__doc__}, + {"keys", _PyCFunction_CAST(_dbm_dbm_keys), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_keys__doc__}, static PyObject * _dbm_dbm_keys_impl(dbmobject *self, PyTypeObject *cls); @@ -35,18 +41,11 @@ _dbm_dbm_keys_impl(dbmobject *self, PyTypeObject *cls); static PyObject * _dbm_dbm_keys(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":keys", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "keys() takes no arguments"); + return NULL; } - return_value = _dbm_dbm_keys_impl(self, cls); - -exit: - return return_value; + return _dbm_dbm_keys_impl(self, cls); } PyDoc_STRVAR(_dbm_dbm_get__doc__, @@ -56,7 +55,7 @@ PyDoc_STRVAR(_dbm_dbm_get__doc__, "Return the value for key if present, otherwise default."); #define _DBM_DBM_GET_METHODDEF \ - {"get", (PyCFunction)(void(*)(void))_dbm_dbm_get, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_get__doc__}, + {"get", _PyCFunction_CAST(_dbm_dbm_get), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_get__doc__}, static PyObject * _dbm_dbm_get_impl(dbmobject *self, PyTypeObject *cls, const char *key, @@ -66,8 +65,19 @@ static PyObject * _dbm_dbm_get(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {"s#|O:get", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "s#|O:get", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE const char *key; Py_ssize_t key_length; PyObject *default_value = Py_None; @@ -91,7 +101,7 @@ PyDoc_STRVAR(_dbm_dbm_setdefault__doc__, "If key is not in the database, it is inserted with default as the value."); #define _DBM_DBM_SETDEFAULT_METHODDEF \ - {"setdefault", (PyCFunction)(void(*)(void))_dbm_dbm_setdefault, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_setdefault__doc__}, + {"setdefault", _PyCFunction_CAST(_dbm_dbm_setdefault), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _dbm_dbm_setdefault__doc__}, static PyObject * _dbm_dbm_setdefault_impl(dbmobject *self, PyTypeObject *cls, const char *key, @@ -101,8 +111,19 @@ static PyObject * _dbm_dbm_setdefault(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {"s#|O:setdefault", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "s#|O:setdefault", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE const char *key; Py_ssize_t key_length; PyObject *default_value = NULL; @@ -132,7 +153,7 @@ PyDoc_STRVAR(dbmopen__doc__, " (e.g. os.O_RDWR)."); #define DBMOPEN_METHODDEF \ - {"open", (PyCFunction)(void(*)(void))dbmopen, METH_FASTCALL, dbmopen__doc__}, + {"open", _PyCFunction_CAST(dbmopen), METH_FASTCALL, dbmopen__doc__}, static PyObject * dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, @@ -179,4 +200,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=32ef6c0f8f2d3db9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=28dcf736654137c2 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_elementtree.c.h b/Modules/clinic/_elementtree.c.h index 2c9ba47823b..a0bc751ca21 100644 --- a/Modules/clinic/_elementtree.c.h +++ b/Modules/clinic/_elementtree.c.h @@ -2,29 +2,54 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_elementtree_Element_append__doc__, "append($self, subelement, /)\n" "--\n" "\n"); #define _ELEMENTTREE_ELEMENT_APPEND_METHODDEF \ - {"append", (PyCFunction)_elementtree_Element_append, METH_O, _elementtree_Element_append__doc__}, + {"append", _PyCFunction_CAST(_elementtree_Element_append), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_append__doc__}, static PyObject * -_elementtree_Element_append_impl(ElementObject *self, PyObject *subelement); +_elementtree_Element_append_impl(ElementObject *self, PyTypeObject *cls, + PyObject *subelement); static PyObject * -_elementtree_Element_append(ElementObject *self, PyObject *arg) +_elementtree_Element_append(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "append", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; PyObject *subelement; - if (!PyObject_TypeCheck(arg, &Element_Type)) { - _PyArg_BadArgument("append", "argument", (&Element_Type)->tp_name, arg); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { goto exit; } - subelement = arg; - return_value = _elementtree_Element_append_impl(self, subelement); + if (!PyObject_TypeCheck(args[0], clinic_state()->Element_Type)) { + _PyArg_BadArgument("append", "argument 1", (clinic_state()->Element_Type)->tp_name, args[0]); + goto exit; + } + subelement = args[0]; + return_value = _elementtree_Element_append_impl(self, cls, subelement); exit: return return_value; @@ -53,15 +78,19 @@ PyDoc_STRVAR(_elementtree_Element___copy____doc__, "\n"); #define _ELEMENTTREE_ELEMENT___COPY___METHODDEF \ - {"__copy__", (PyCFunction)_elementtree_Element___copy__, METH_NOARGS, _elementtree_Element___copy____doc__}, + {"__copy__", _PyCFunction_CAST(_elementtree_Element___copy__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element___copy____doc__}, static PyObject * -_elementtree_Element___copy___impl(ElementObject *self); +_elementtree_Element___copy___impl(ElementObject *self, PyTypeObject *cls); static PyObject * -_elementtree_Element___copy__(ElementObject *self, PyObject *Py_UNUSED(ignored)) +_elementtree_Element___copy__(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _elementtree_Element___copy___impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "__copy__() takes no arguments"); + return NULL; + } + return _elementtree_Element___copy___impl(self, cls); } PyDoc_STRVAR(_elementtree_Element___deepcopy____doc__, @@ -100,20 +129,20 @@ PyDoc_STRVAR(_elementtree_Element___sizeof____doc__, #define _ELEMENTTREE_ELEMENT___SIZEOF___METHODDEF \ {"__sizeof__", (PyCFunction)_elementtree_Element___sizeof__, METH_NOARGS, _elementtree_Element___sizeof____doc__}, -static Py_ssize_t +static size_t _elementtree_Element___sizeof___impl(ElementObject *self); static PyObject * _elementtree_Element___sizeof__(ElementObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *return_value = NULL; - Py_ssize_t _return_value; + size_t _return_value; _return_value = _elementtree_Element___sizeof___impl(self); - if ((_return_value == -1) && PyErr_Occurred()) { + if ((_return_value == (size_t)-1) && PyErr_Occurred()) { goto exit; } - return_value = PyLong_FromSsize_t(_return_value); + return_value = PyLong_FromSize_t(_return_value); exit: return return_value; @@ -142,7 +171,42 @@ PyDoc_STRVAR(_elementtree_Element___setstate____doc__, "\n"); #define _ELEMENTTREE_ELEMENT___SETSTATE___METHODDEF \ - {"__setstate__", (PyCFunction)_elementtree_Element___setstate__, METH_O, _elementtree_Element___setstate____doc__}, + {"__setstate__", _PyCFunction_CAST(_elementtree_Element___setstate__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element___setstate____doc__}, + +static PyObject * +_elementtree_Element___setstate___impl(ElementObject *self, + PyTypeObject *cls, PyObject *state); + +static PyObject * +_elementtree_Element___setstate__(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__setstate__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *state; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + state = args[0]; + return_value = _elementtree_Element___setstate___impl(self, cls, state); + +exit: + return return_value; +} PyDoc_STRVAR(_elementtree_Element_extend__doc__, "extend($self, elements, /)\n" @@ -150,7 +214,42 @@ PyDoc_STRVAR(_elementtree_Element_extend__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_EXTEND_METHODDEF \ - {"extend", (PyCFunction)_elementtree_Element_extend, METH_O, _elementtree_Element_extend__doc__}, + {"extend", _PyCFunction_CAST(_elementtree_Element_extend), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_extend__doc__}, + +static PyObject * +_elementtree_Element_extend_impl(ElementObject *self, PyTypeObject *cls, + PyObject *elements); + +static PyObject * +_elementtree_Element_extend(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "extend", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *elements; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + elements = args[0]; + return_value = _elementtree_Element_extend_impl(self, cls, elements); + +exit: + return return_value; +} PyDoc_STRVAR(_elementtree_Element_find__doc__, "find($self, /, path, namespaces=None)\n" @@ -158,18 +257,41 @@ PyDoc_STRVAR(_elementtree_Element_find__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_FIND_METHODDEF \ - {"find", (PyCFunction)(void(*)(void))_elementtree_Element_find, METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_find__doc__}, + {"find", _PyCFunction_CAST(_elementtree_Element_find), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_find__doc__}, static PyObject * -_elementtree_Element_find_impl(ElementObject *self, PyObject *path, - PyObject *namespaces); +_elementtree_Element_find_impl(ElementObject *self, PyTypeObject *cls, + PyObject *path, PyObject *namespaces); static PyObject * -_elementtree_Element_find(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_elementtree_Element_find(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(namespaces), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "namespaces", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "find", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "find", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *path; @@ -185,7 +307,7 @@ _elementtree_Element_find(ElementObject *self, PyObject *const *args, Py_ssize_t } namespaces = args[1]; skip_optional_pos: - return_value = _elementtree_Element_find_impl(self, path, namespaces); + return_value = _elementtree_Element_find_impl(self, cls, path, namespaces); exit: return return_value; @@ -197,19 +319,42 @@ PyDoc_STRVAR(_elementtree_Element_findtext__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_FINDTEXT_METHODDEF \ - {"findtext", (PyCFunction)(void(*)(void))_elementtree_Element_findtext, METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_findtext__doc__}, + {"findtext", _PyCFunction_CAST(_elementtree_Element_findtext), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_findtext__doc__}, static PyObject * -_elementtree_Element_findtext_impl(ElementObject *self, PyObject *path, - PyObject *default_value, +_elementtree_Element_findtext_impl(ElementObject *self, PyTypeObject *cls, + PyObject *path, PyObject *default_value, PyObject *namespaces); static PyObject * -_elementtree_Element_findtext(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_elementtree_Element_findtext(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(default), &_Py_ID(namespaces), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "default", "namespaces", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "findtext", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "findtext", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *path; @@ -232,7 +377,7 @@ _elementtree_Element_findtext(ElementObject *self, PyObject *const *args, Py_ssi } namespaces = args[2]; skip_optional_pos: - return_value = _elementtree_Element_findtext_impl(self, path, default_value, namespaces); + return_value = _elementtree_Element_findtext_impl(self, cls, path, default_value, namespaces); exit: return return_value; @@ -244,18 +389,41 @@ PyDoc_STRVAR(_elementtree_Element_findall__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_FINDALL_METHODDEF \ - {"findall", (PyCFunction)(void(*)(void))_elementtree_Element_findall, METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_findall__doc__}, + {"findall", _PyCFunction_CAST(_elementtree_Element_findall), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_findall__doc__}, static PyObject * -_elementtree_Element_findall_impl(ElementObject *self, PyObject *path, - PyObject *namespaces); +_elementtree_Element_findall_impl(ElementObject *self, PyTypeObject *cls, + PyObject *path, PyObject *namespaces); static PyObject * -_elementtree_Element_findall(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_elementtree_Element_findall(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(namespaces), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "namespaces", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "findall", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "findall", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *path; @@ -271,7 +439,7 @@ _elementtree_Element_findall(ElementObject *self, PyObject *const *args, Py_ssiz } namespaces = args[1]; skip_optional_pos: - return_value = _elementtree_Element_findall_impl(self, path, namespaces); + return_value = _elementtree_Element_findall_impl(self, cls, path, namespaces); exit: return return_value; @@ -283,18 +451,41 @@ PyDoc_STRVAR(_elementtree_Element_iterfind__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_ITERFIND_METHODDEF \ - {"iterfind", (PyCFunction)(void(*)(void))_elementtree_Element_iterfind, METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_iterfind__doc__}, + {"iterfind", _PyCFunction_CAST(_elementtree_Element_iterfind), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_iterfind__doc__}, static PyObject * -_elementtree_Element_iterfind_impl(ElementObject *self, PyObject *path, - PyObject *namespaces); +_elementtree_Element_iterfind_impl(ElementObject *self, PyTypeObject *cls, + PyObject *path, PyObject *namespaces); static PyObject * -_elementtree_Element_iterfind(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_elementtree_Element_iterfind(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(namespaces), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "namespaces", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "iterfind", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "iterfind", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *path; @@ -310,7 +501,7 @@ _elementtree_Element_iterfind(ElementObject *self, PyObject *const *args, Py_ssi } namespaces = args[1]; skip_optional_pos: - return_value = _elementtree_Element_iterfind_impl(self, path, namespaces); + return_value = _elementtree_Element_iterfind_impl(self, cls, path, namespaces); exit: return return_value; @@ -322,7 +513,7 @@ PyDoc_STRVAR(_elementtree_Element_get__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_GET_METHODDEF \ - {"get", (PyCFunction)(void(*)(void))_elementtree_Element_get, METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_get__doc__}, + {"get", _PyCFunction_CAST(_elementtree_Element_get), METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_get__doc__}, static PyObject * _elementtree_Element_get_impl(ElementObject *self, PyObject *key, @@ -332,8 +523,31 @@ static PyObject * _elementtree_Element_get(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(default), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *key; @@ -361,17 +575,41 @@ PyDoc_STRVAR(_elementtree_Element_iter__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_ITER_METHODDEF \ - {"iter", (PyCFunction)(void(*)(void))_elementtree_Element_iter, METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_iter__doc__}, + {"iter", _PyCFunction_CAST(_elementtree_Element_iter), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_iter__doc__}, static PyObject * -_elementtree_Element_iter_impl(ElementObject *self, PyObject *tag); +_elementtree_Element_iter_impl(ElementObject *self, PyTypeObject *cls, + PyObject *tag); static PyObject * -_elementtree_Element_iter(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_elementtree_Element_iter(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tag), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"tag", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "iter", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "iter", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *tag = Py_None; @@ -385,7 +623,7 @@ _elementtree_Element_iter(ElementObject *self, PyObject *const *args, Py_ssize_t } tag = args[0]; skip_optional_pos: - return_value = _elementtree_Element_iter_impl(self, tag); + return_value = _elementtree_Element_iter_impl(self, cls, tag); exit: return return_value; @@ -397,15 +635,19 @@ PyDoc_STRVAR(_elementtree_Element_itertext__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_ITERTEXT_METHODDEF \ - {"itertext", (PyCFunction)_elementtree_Element_itertext, METH_NOARGS, _elementtree_Element_itertext__doc__}, + {"itertext", _PyCFunction_CAST(_elementtree_Element_itertext), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_itertext__doc__}, static PyObject * -_elementtree_Element_itertext_impl(ElementObject *self); +_elementtree_Element_itertext_impl(ElementObject *self, PyTypeObject *cls); static PyObject * -_elementtree_Element_itertext(ElementObject *self, PyObject *Py_UNUSED(ignored)) +_elementtree_Element_itertext(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _elementtree_Element_itertext_impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "itertext() takes no arguments"); + return NULL; + } + return _elementtree_Element_itertext_impl(self, cls); } PyDoc_STRVAR(_elementtree_Element_insert__doc__, @@ -414,7 +656,7 @@ PyDoc_STRVAR(_elementtree_Element_insert__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_INSERT_METHODDEF \ - {"insert", (PyCFunction)(void(*)(void))_elementtree_Element_insert, METH_FASTCALL, _elementtree_Element_insert__doc__}, + {"insert", _PyCFunction_CAST(_elementtree_Element_insert), METH_FASTCALL, _elementtree_Element_insert__doc__}, static PyObject * _elementtree_Element_insert_impl(ElementObject *self, Py_ssize_t index, @@ -442,8 +684,8 @@ _elementtree_Element_insert(ElementObject *self, PyObject *const *args, Py_ssize } index = ival; } - if (!PyObject_TypeCheck(args[1], &Element_Type)) { - _PyArg_BadArgument("insert", "argument 2", (&Element_Type)->tp_name, args[1]); + if (!PyObject_TypeCheck(args[1], clinic_state()->Element_Type)) { + _PyArg_BadArgument("insert", "argument 2", (clinic_state()->Element_Type)->tp_name, args[1]); goto exit; } subelement = args[1]; @@ -493,20 +735,35 @@ PyDoc_STRVAR(_elementtree_Element_makeelement__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_MAKEELEMENT_METHODDEF \ - {"makeelement", (PyCFunction)(void(*)(void))_elementtree_Element_makeelement, METH_FASTCALL, _elementtree_Element_makeelement__doc__}, + {"makeelement", _PyCFunction_CAST(_elementtree_Element_makeelement), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_makeelement__doc__}, static PyObject * -_elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, - PyObject *attrib); +_elementtree_Element_makeelement_impl(ElementObject *self, PyTypeObject *cls, + PyObject *tag, PyObject *attrib); static PyObject * -_elementtree_Element_makeelement(ElementObject *self, PyObject *const *args, Py_ssize_t nargs) +_elementtree_Element_makeelement(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", "", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "makeelement", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; PyObject *tag; PyObject *attrib; - if (!_PyArg_CheckPositional("makeelement", nargs, 2, 2)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { goto exit; } tag = args[0]; @@ -515,7 +772,7 @@ _elementtree_Element_makeelement(ElementObject *self, PyObject *const *args, Py_ goto exit; } attrib = args[1]; - return_value = _elementtree_Element_makeelement_impl(self, tag, attrib); + return_value = _elementtree_Element_makeelement_impl(self, cls, tag, attrib); exit: return return_value; @@ -538,8 +795,8 @@ _elementtree_Element_remove(ElementObject *self, PyObject *arg) PyObject *return_value = NULL; PyObject *subelement; - if (!PyObject_TypeCheck(arg, &Element_Type)) { - _PyArg_BadArgument("remove", "argument", (&Element_Type)->tp_name, arg); + if (!PyObject_TypeCheck(arg, clinic_state()->Element_Type)) { + _PyArg_BadArgument("remove", "argument", (clinic_state()->Element_Type)->tp_name, arg); goto exit; } subelement = arg; @@ -555,7 +812,7 @@ PyDoc_STRVAR(_elementtree_Element_set__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_SET_METHODDEF \ - {"set", (PyCFunction)(void(*)(void))_elementtree_Element_set, METH_FASTCALL, _elementtree_Element_set__doc__}, + {"set", _PyCFunction_CAST(_elementtree_Element_set), METH_FASTCALL, _elementtree_Element_set__doc__}, static PyObject * _elementtree_Element_set_impl(ElementObject *self, PyObject *key, @@ -590,8 +847,31 @@ static int _elementtree_TreeBuilder___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(element_factory), &_Py_ID(comment_factory), &_Py_ID(pi_factory), &_Py_ID(insert_comments), &_Py_ID(insert_pis), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"element_factory", "comment_factory", "pi_factory", "insert_comments", "insert_pis", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "TreeBuilder", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "TreeBuilder", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -660,7 +940,7 @@ PyDoc_STRVAR(_elementtree__set_factories__doc__, "For internal use only."); #define _ELEMENTTREE__SET_FACTORIES_METHODDEF \ - {"_set_factories", (PyCFunction)(void(*)(void))_elementtree__set_factories, METH_FASTCALL, _elementtree__set_factories__doc__}, + {"_set_factories", _PyCFunction_CAST(_elementtree__set_factories), METH_FASTCALL, _elementtree__set_factories__doc__}, static PyObject * _elementtree__set_factories_impl(PyObject *module, PyObject *comment_factory, @@ -714,7 +994,7 @@ PyDoc_STRVAR(_elementtree_TreeBuilder_pi__doc__, "\n"); #define _ELEMENTTREE_TREEBUILDER_PI_METHODDEF \ - {"pi", (PyCFunction)(void(*)(void))_elementtree_TreeBuilder_pi, METH_FASTCALL, _elementtree_TreeBuilder_pi__doc__}, + {"pi", _PyCFunction_CAST(_elementtree_TreeBuilder_pi), METH_FASTCALL, _elementtree_TreeBuilder_pi__doc__}, static PyObject * _elementtree_TreeBuilder_pi_impl(TreeBuilderObject *self, PyObject *target, @@ -765,7 +1045,7 @@ PyDoc_STRVAR(_elementtree_TreeBuilder_start__doc__, "\n"); #define _ELEMENTTREE_TREEBUILDER_START_METHODDEF \ - {"start", (PyCFunction)(void(*)(void))_elementtree_TreeBuilder_start, METH_FASTCALL, _elementtree_TreeBuilder_start__doc__}, + {"start", _PyCFunction_CAST(_elementtree_TreeBuilder_start), METH_FASTCALL, _elementtree_TreeBuilder_start__doc__}, static PyObject * _elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag, @@ -801,13 +1081,36 @@ static int _elementtree_XMLParser___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(target), &_Py_ID(encoding), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"target", "encoding", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "XMLParser", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "XMLParser", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; - PyObject *target = NULL; + PyObject *target = Py_None; const char *encoding = NULL; fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 0, 0, argsbuf); @@ -887,7 +1190,7 @@ PyDoc_STRVAR(_elementtree_XMLParser__setevents__doc__, "\n"); #define _ELEMENTTREE_XMLPARSER__SETEVENTS_METHODDEF \ - {"_setevents", (PyCFunction)(void(*)(void))_elementtree_XMLParser__setevents, METH_FASTCALL, _elementtree_XMLParser__setevents__doc__}, + {"_setevents", _PyCFunction_CAST(_elementtree_XMLParser__setevents), METH_FASTCALL, _elementtree_XMLParser__setevents__doc__}, static PyObject * _elementtree_XMLParser__setevents_impl(XMLParserObject *self, @@ -915,4 +1218,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=1385b5e5688f3614 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=40767b1a98e54b60 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_functoolsmodule.c.h b/Modules/clinic/_functoolsmodule.c.h new file mode 100644 index 00000000000..9c79e643041 --- /dev/null +++ b/Modules/clinic/_functoolsmodule.c.h @@ -0,0 +1,104 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(_functools_cmp_to_key__doc__, +"cmp_to_key($module, /, mycmp)\n" +"--\n" +"\n" +"Convert a cmp= function into a key= function.\n" +"\n" +" mycmp\n" +" Function that compares two objects."); + +#define _FUNCTOOLS_CMP_TO_KEY_METHODDEF \ + {"cmp_to_key", _PyCFunction_CAST(_functools_cmp_to_key), METH_FASTCALL|METH_KEYWORDS, _functools_cmp_to_key__doc__}, + +static PyObject * +_functools_cmp_to_key_impl(PyObject *module, PyObject *mycmp); + +static PyObject * +_functools_cmp_to_key(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(mycmp), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"mycmp", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cmp_to_key", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *mycmp; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + mycmp = args[0]; + return_value = _functools_cmp_to_key_impl(module, mycmp); + +exit: + return return_value; +} + +PyDoc_STRVAR(_functools__lru_cache_wrapper_cache_info__doc__, +"cache_info($self, /)\n" +"--\n" +"\n" +"Report cache statistics"); + +#define _FUNCTOOLS__LRU_CACHE_WRAPPER_CACHE_INFO_METHODDEF \ + {"cache_info", (PyCFunction)_functools__lru_cache_wrapper_cache_info, METH_NOARGS, _functools__lru_cache_wrapper_cache_info__doc__}, + +static PyObject * +_functools__lru_cache_wrapper_cache_info_impl(PyObject *self); + +static PyObject * +_functools__lru_cache_wrapper_cache_info(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _functools__lru_cache_wrapper_cache_info_impl(self); +} + +PyDoc_STRVAR(_functools__lru_cache_wrapper_cache_clear__doc__, +"cache_clear($self, /)\n" +"--\n" +"\n" +"Clear the cache and cache statistics"); + +#define _FUNCTOOLS__LRU_CACHE_WRAPPER_CACHE_CLEAR_METHODDEF \ + {"cache_clear", (PyCFunction)_functools__lru_cache_wrapper_cache_clear, METH_NOARGS, _functools__lru_cache_wrapper_cache_clear__doc__}, + +static PyObject * +_functools__lru_cache_wrapper_cache_clear_impl(PyObject *self); + +static PyObject * +_functools__lru_cache_wrapper_cache_clear(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _functools__lru_cache_wrapper_cache_clear_impl(self); +} +/*[clinic end generated code: output=7e7f3bcf9ed61f23 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_gdbmmodule.c.h b/Modules/clinic/_gdbmmodule.c.h index a40e80d8e1a..5c6aeeee778 100644 --- a/Modules/clinic/_gdbmmodule.c.h +++ b/Modules/clinic/_gdbmmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_gdbm_gdbm_get__doc__, "get($self, key, default=None, /)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(_gdbm_gdbm_get__doc__, "Get the value for key, or default if not present."); #define _GDBM_GDBM_GET_METHODDEF \ - {"get", (PyCFunction)(void(*)(void))_gdbm_gdbm_get, METH_FASTCALL, _gdbm_gdbm_get__doc__}, + {"get", _PyCFunction_CAST(_gdbm_gdbm_get), METH_FASTCALL, _gdbm_gdbm_get__doc__}, static PyObject * _gdbm_gdbm_get_impl(gdbmobject *self, PyObject *key, PyObject *default_value); @@ -43,7 +49,7 @@ PyDoc_STRVAR(_gdbm_gdbm_setdefault__doc__, "Get value for key, or set it to default and return default if not present."); #define _GDBM_GDBM_SETDEFAULT_METHODDEF \ - {"setdefault", (PyCFunction)(void(*)(void))_gdbm_gdbm_setdefault, METH_FASTCALL, _gdbm_gdbm_setdefault__doc__}, + {"setdefault", _PyCFunction_CAST(_gdbm_gdbm_setdefault), METH_FASTCALL, _gdbm_gdbm_setdefault__doc__}, static PyObject * _gdbm_gdbm_setdefault_impl(gdbmobject *self, PyObject *key, @@ -96,7 +102,7 @@ PyDoc_STRVAR(_gdbm_gdbm_keys__doc__, "Get a list of all keys in the database."); #define _GDBM_GDBM_KEYS_METHODDEF \ - {"keys", (PyCFunction)(void(*)(void))_gdbm_gdbm_keys, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_keys__doc__}, + {"keys", _PyCFunction_CAST(_gdbm_gdbm_keys), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_keys__doc__}, static PyObject * _gdbm_gdbm_keys_impl(gdbmobject *self, PyTypeObject *cls); @@ -104,18 +110,11 @@ _gdbm_gdbm_keys_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * _gdbm_gdbm_keys(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":keys", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "keys() takes no arguments"); + return NULL; } - return_value = _gdbm_gdbm_keys_impl(self, cls); - -exit: - return return_value; + return _gdbm_gdbm_keys_impl(self, cls); } PyDoc_STRVAR(_gdbm_gdbm_firstkey__doc__, @@ -129,7 +128,7 @@ PyDoc_STRVAR(_gdbm_gdbm_firstkey__doc__, "hash values, and won\'t be sorted by the key values."); #define _GDBM_GDBM_FIRSTKEY_METHODDEF \ - {"firstkey", (PyCFunction)(void(*)(void))_gdbm_gdbm_firstkey, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_firstkey__doc__}, + {"firstkey", _PyCFunction_CAST(_gdbm_gdbm_firstkey), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_firstkey__doc__}, static PyObject * _gdbm_gdbm_firstkey_impl(gdbmobject *self, PyTypeObject *cls); @@ -137,18 +136,11 @@ _gdbm_gdbm_firstkey_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * _gdbm_gdbm_firstkey(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":firstkey", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "firstkey() takes no arguments"); + return NULL; } - return_value = _gdbm_gdbm_firstkey_impl(self, cls); - -exit: - return return_value; + return _gdbm_gdbm_firstkey_impl(self, cls); } PyDoc_STRVAR(_gdbm_gdbm_nextkey__doc__, @@ -166,7 +158,7 @@ PyDoc_STRVAR(_gdbm_gdbm_nextkey__doc__, " k = db.nextkey(k)"); #define _GDBM_GDBM_NEXTKEY_METHODDEF \ - {"nextkey", (PyCFunction)(void(*)(void))_gdbm_gdbm_nextkey, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_nextkey__doc__}, + {"nextkey", _PyCFunction_CAST(_gdbm_gdbm_nextkey), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_nextkey__doc__}, static PyObject * _gdbm_gdbm_nextkey_impl(gdbmobject *self, PyTypeObject *cls, const char *key, @@ -176,8 +168,19 @@ static PyObject * _gdbm_gdbm_nextkey(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"s#:nextkey", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "s#:nextkey", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE const char *key; Py_ssize_t key_length; @@ -204,7 +207,7 @@ PyDoc_STRVAR(_gdbm_gdbm_reorganize__doc__, "kept and reused as new (key,value) pairs are added."); #define _GDBM_GDBM_REORGANIZE_METHODDEF \ - {"reorganize", (PyCFunction)(void(*)(void))_gdbm_gdbm_reorganize, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_reorganize__doc__}, + {"reorganize", _PyCFunction_CAST(_gdbm_gdbm_reorganize), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_reorganize__doc__}, static PyObject * _gdbm_gdbm_reorganize_impl(gdbmobject *self, PyTypeObject *cls); @@ -212,18 +215,11 @@ _gdbm_gdbm_reorganize_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * _gdbm_gdbm_reorganize(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":reorganize", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "reorganize() takes no arguments"); + return NULL; } - return_value = _gdbm_gdbm_reorganize_impl(self, cls); - -exit: - return return_value; + return _gdbm_gdbm_reorganize_impl(self, cls); } PyDoc_STRVAR(_gdbm_gdbm_sync__doc__, @@ -236,7 +232,7 @@ PyDoc_STRVAR(_gdbm_gdbm_sync__doc__, "any unwritten data to be written to the disk."); #define _GDBM_GDBM_SYNC_METHODDEF \ - {"sync", (PyCFunction)(void(*)(void))_gdbm_gdbm_sync, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_sync__doc__}, + {"sync", _PyCFunction_CAST(_gdbm_gdbm_sync), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _gdbm_gdbm_sync__doc__}, static PyObject * _gdbm_gdbm_sync_impl(gdbmobject *self, PyTypeObject *cls); @@ -244,18 +240,11 @@ _gdbm_gdbm_sync_impl(gdbmobject *self, PyTypeObject *cls); static PyObject * _gdbm_gdbm_sync(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":sync", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "sync() takes no arguments"); + return NULL; } - return_value = _gdbm_gdbm_sync_impl(self, cls); - -exit: - return return_value; + return _gdbm_gdbm_sync_impl(self, cls); } PyDoc_STRVAR(dbmopen__doc__, @@ -286,7 +275,7 @@ PyDoc_STRVAR(dbmopen__doc__, "when the database has to be created. It defaults to octal 0o666."); #define DBMOPEN_METHODDEF \ - {"open", (PyCFunction)(void(*)(void))dbmopen, METH_FASTCALL, dbmopen__doc__}, + {"open", _PyCFunction_CAST(dbmopen), METH_FASTCALL, dbmopen__doc__}, static PyObject * dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, @@ -333,4 +322,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=63c507f93d84a3a4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c6e721d82335adb3 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_hashopenssl.c.h b/Modules/clinic/_hashopenssl.c.h index de01489e6a3..fb61a444018 100644 --- a/Modules/clinic/_hashopenssl.c.h +++ b/Modules/clinic/_hashopenssl.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(EVP_copy__doc__, "copy($self, /)\n" "--\n" @@ -74,7 +80,7 @@ PyDoc_STRVAR(EVPXOF_digest__doc__, "Return the digest value as a bytes object."); #define EVPXOF_DIGEST_METHODDEF \ - {"digest", (PyCFunction)(void(*)(void))EVPXOF_digest, METH_FASTCALL|METH_KEYWORDS, EVPXOF_digest__doc__}, + {"digest", _PyCFunction_CAST(EVPXOF_digest), METH_FASTCALL|METH_KEYWORDS, EVPXOF_digest__doc__}, static PyObject * EVPXOF_digest_impl(EVPobject *self, Py_ssize_t length); @@ -83,8 +89,31 @@ static PyObject * EVPXOF_digest(EVPobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(length), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "digest", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "digest", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t length; @@ -121,7 +150,7 @@ PyDoc_STRVAR(EVPXOF_hexdigest__doc__, "Return the digest value as a string of hexadecimal digits."); #define EVPXOF_HEXDIGEST_METHODDEF \ - {"hexdigest", (PyCFunction)(void(*)(void))EVPXOF_hexdigest, METH_FASTCALL|METH_KEYWORDS, EVPXOF_hexdigest__doc__}, + {"hexdigest", _PyCFunction_CAST(EVPXOF_hexdigest), METH_FASTCALL|METH_KEYWORDS, EVPXOF_hexdigest__doc__}, static PyObject * EVPXOF_hexdigest_impl(EVPobject *self, Py_ssize_t length); @@ -130,8 +159,31 @@ static PyObject * EVPXOF_hexdigest(EVPobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(length), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hexdigest", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hexdigest", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t length; @@ -171,7 +223,7 @@ PyDoc_STRVAR(EVP_new__doc__, "The MD5 and SHA1 algorithms are always supported."); #define EVP_NEW_METHODDEF \ - {"new", (PyCFunction)(void(*)(void))EVP_new, METH_FASTCALL|METH_KEYWORDS, EVP_new__doc__}, + {"new", _PyCFunction_CAST(EVP_new), METH_FASTCALL|METH_KEYWORDS, EVP_new__doc__}, static PyObject * EVP_new_impl(PyObject *module, PyObject *name_obj, PyObject *data_obj, @@ -181,8 +233,31 @@ static PyObject * EVP_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", "string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "new", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "new", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *name_obj; @@ -225,7 +300,7 @@ PyDoc_STRVAR(_hashlib_openssl_md5__doc__, "Returns a md5 hash object; optionally initialized with a string"); #define _HASHLIB_OPENSSL_MD5_METHODDEF \ - {"openssl_md5", (PyCFunction)(void(*)(void))_hashlib_openssl_md5, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_md5__doc__}, + {"openssl_md5", _PyCFunction_CAST(_hashlib_openssl_md5), METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_md5__doc__}, static PyObject * _hashlib_openssl_md5_impl(PyObject *module, PyObject *data_obj, @@ -235,8 +310,31 @@ static PyObject * _hashlib_openssl_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_md5", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_md5", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -277,7 +375,7 @@ PyDoc_STRVAR(_hashlib_openssl_sha1__doc__, "Returns a sha1 hash object; optionally initialized with a string"); #define _HASHLIB_OPENSSL_SHA1_METHODDEF \ - {"openssl_sha1", (PyCFunction)(void(*)(void))_hashlib_openssl_sha1, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha1__doc__}, + {"openssl_sha1", _PyCFunction_CAST(_hashlib_openssl_sha1), METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha1__doc__}, static PyObject * _hashlib_openssl_sha1_impl(PyObject *module, PyObject *data_obj, @@ -287,8 +385,31 @@ static PyObject * _hashlib_openssl_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha1", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -329,7 +450,7 @@ PyDoc_STRVAR(_hashlib_openssl_sha224__doc__, "Returns a sha224 hash object; optionally initialized with a string"); #define _HASHLIB_OPENSSL_SHA224_METHODDEF \ - {"openssl_sha224", (PyCFunction)(void(*)(void))_hashlib_openssl_sha224, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha224__doc__}, + {"openssl_sha224", _PyCFunction_CAST(_hashlib_openssl_sha224), METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha224__doc__}, static PyObject * _hashlib_openssl_sha224_impl(PyObject *module, PyObject *data_obj, @@ -339,8 +460,31 @@ static PyObject * _hashlib_openssl_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha224", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha224", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -381,7 +525,7 @@ PyDoc_STRVAR(_hashlib_openssl_sha256__doc__, "Returns a sha256 hash object; optionally initialized with a string"); #define _HASHLIB_OPENSSL_SHA256_METHODDEF \ - {"openssl_sha256", (PyCFunction)(void(*)(void))_hashlib_openssl_sha256, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha256__doc__}, + {"openssl_sha256", _PyCFunction_CAST(_hashlib_openssl_sha256), METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha256__doc__}, static PyObject * _hashlib_openssl_sha256_impl(PyObject *module, PyObject *data_obj, @@ -391,8 +535,31 @@ static PyObject * _hashlib_openssl_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha256", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha256", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -433,7 +600,7 @@ PyDoc_STRVAR(_hashlib_openssl_sha384__doc__, "Returns a sha384 hash object; optionally initialized with a string"); #define _HASHLIB_OPENSSL_SHA384_METHODDEF \ - {"openssl_sha384", (PyCFunction)(void(*)(void))_hashlib_openssl_sha384, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha384__doc__}, + {"openssl_sha384", _PyCFunction_CAST(_hashlib_openssl_sha384), METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha384__doc__}, static PyObject * _hashlib_openssl_sha384_impl(PyObject *module, PyObject *data_obj, @@ -443,8 +610,31 @@ static PyObject * _hashlib_openssl_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha384", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha384", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -485,7 +675,7 @@ PyDoc_STRVAR(_hashlib_openssl_sha512__doc__, "Returns a sha512 hash object; optionally initialized with a string"); #define _HASHLIB_OPENSSL_SHA512_METHODDEF \ - {"openssl_sha512", (PyCFunction)(void(*)(void))_hashlib_openssl_sha512, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha512__doc__}, + {"openssl_sha512", _PyCFunction_CAST(_hashlib_openssl_sha512), METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha512__doc__}, static PyObject * _hashlib_openssl_sha512_impl(PyObject *module, PyObject *data_obj, @@ -495,8 +685,31 @@ static PyObject * _hashlib_openssl_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha512", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha512", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -539,7 +752,7 @@ PyDoc_STRVAR(_hashlib_openssl_sha3_224__doc__, "Returns a sha3-224 hash object; optionally initialized with a string"); #define _HASHLIB_OPENSSL_SHA3_224_METHODDEF \ - {"openssl_sha3_224", (PyCFunction)(void(*)(void))_hashlib_openssl_sha3_224, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha3_224__doc__}, + {"openssl_sha3_224", _PyCFunction_CAST(_hashlib_openssl_sha3_224), METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha3_224__doc__}, static PyObject * _hashlib_openssl_sha3_224_impl(PyObject *module, PyObject *data_obj, @@ -549,8 +762,31 @@ static PyObject * _hashlib_openssl_sha3_224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha3_224", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha3_224", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -595,7 +831,7 @@ PyDoc_STRVAR(_hashlib_openssl_sha3_256__doc__, "Returns a sha3-256 hash object; optionally initialized with a string"); #define _HASHLIB_OPENSSL_SHA3_256_METHODDEF \ - {"openssl_sha3_256", (PyCFunction)(void(*)(void))_hashlib_openssl_sha3_256, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha3_256__doc__}, + {"openssl_sha3_256", _PyCFunction_CAST(_hashlib_openssl_sha3_256), METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha3_256__doc__}, static PyObject * _hashlib_openssl_sha3_256_impl(PyObject *module, PyObject *data_obj, @@ -605,8 +841,31 @@ static PyObject * _hashlib_openssl_sha3_256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha3_256", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha3_256", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -651,7 +910,7 @@ PyDoc_STRVAR(_hashlib_openssl_sha3_384__doc__, "Returns a sha3-384 hash object; optionally initialized with a string"); #define _HASHLIB_OPENSSL_SHA3_384_METHODDEF \ - {"openssl_sha3_384", (PyCFunction)(void(*)(void))_hashlib_openssl_sha3_384, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha3_384__doc__}, + {"openssl_sha3_384", _PyCFunction_CAST(_hashlib_openssl_sha3_384), METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha3_384__doc__}, static PyObject * _hashlib_openssl_sha3_384_impl(PyObject *module, PyObject *data_obj, @@ -661,8 +920,31 @@ static PyObject * _hashlib_openssl_sha3_384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha3_384", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha3_384", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -707,7 +989,7 @@ PyDoc_STRVAR(_hashlib_openssl_sha3_512__doc__, "Returns a sha3-512 hash object; optionally initialized with a string"); #define _HASHLIB_OPENSSL_SHA3_512_METHODDEF \ - {"openssl_sha3_512", (PyCFunction)(void(*)(void))_hashlib_openssl_sha3_512, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha3_512__doc__}, + {"openssl_sha3_512", _PyCFunction_CAST(_hashlib_openssl_sha3_512), METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_sha3_512__doc__}, static PyObject * _hashlib_openssl_sha3_512_impl(PyObject *module, PyObject *data_obj, @@ -717,8 +999,31 @@ static PyObject * _hashlib_openssl_sha3_512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha3_512", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha3_512", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -763,7 +1068,7 @@ PyDoc_STRVAR(_hashlib_openssl_shake_128__doc__, "Returns a shake-128 variable hash object; optionally initialized with a string"); #define _HASHLIB_OPENSSL_SHAKE_128_METHODDEF \ - {"openssl_shake_128", (PyCFunction)(void(*)(void))_hashlib_openssl_shake_128, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_shake_128__doc__}, + {"openssl_shake_128", _PyCFunction_CAST(_hashlib_openssl_shake_128), METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_shake_128__doc__}, static PyObject * _hashlib_openssl_shake_128_impl(PyObject *module, PyObject *data_obj, @@ -773,8 +1078,31 @@ static PyObject * _hashlib_openssl_shake_128(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_shake_128", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_shake_128", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -819,7 +1147,7 @@ PyDoc_STRVAR(_hashlib_openssl_shake_256__doc__, "Returns a shake-256 variable hash object; optionally initialized with a string"); #define _HASHLIB_OPENSSL_SHAKE_256_METHODDEF \ - {"openssl_shake_256", (PyCFunction)(void(*)(void))_hashlib_openssl_shake_256, METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_shake_256__doc__}, + {"openssl_shake_256", _PyCFunction_CAST(_hashlib_openssl_shake_256), METH_FASTCALL|METH_KEYWORDS, _hashlib_openssl_shake_256__doc__}, static PyObject * _hashlib_openssl_shake_256_impl(PyObject *module, PyObject *data_obj, @@ -829,8 +1157,31 @@ static PyObject * _hashlib_openssl_shake_256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_shake_256", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_shake_256", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -874,7 +1225,7 @@ PyDoc_STRVAR(pbkdf2_hmac__doc__, "Password based key derivation function 2 (PKCS #5 v2.0) with HMAC as pseudorandom function."); #define PBKDF2_HMAC_METHODDEF \ - {"pbkdf2_hmac", (PyCFunction)(void(*)(void))pbkdf2_hmac, METH_FASTCALL|METH_KEYWORDS, pbkdf2_hmac__doc__}, + {"pbkdf2_hmac", _PyCFunction_CAST(pbkdf2_hmac), METH_FASTCALL|METH_KEYWORDS, pbkdf2_hmac__doc__}, static PyObject * pbkdf2_hmac_impl(PyObject *module, const char *hash_name, @@ -885,8 +1236,31 @@ static PyObject * pbkdf2_hmac(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(hash_name), &_Py_ID(password), &_Py_ID(salt), &_Py_ID(iterations), &_Py_ID(dklen), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"hash_name", "password", "salt", "iterations", "dklen", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "pbkdf2_hmac", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "pbkdf2_hmac", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; const char *hash_name; @@ -960,7 +1334,7 @@ PyDoc_STRVAR(_hashlib_scrypt__doc__, "scrypt password-based key derivation function."); #define _HASHLIB_SCRYPT_METHODDEF \ - {"scrypt", (PyCFunction)(void(*)(void))_hashlib_scrypt, METH_FASTCALL|METH_KEYWORDS, _hashlib_scrypt__doc__}, + {"scrypt", _PyCFunction_CAST(_hashlib_scrypt), METH_FASTCALL|METH_KEYWORDS, _hashlib_scrypt__doc__}, static PyObject * _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt, @@ -971,8 +1345,31 @@ static PyObject * _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 7 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(password), &_Py_ID(salt), &_Py_ID(n), &_Py_ID(r), &_Py_ID(p), &_Py_ID(maxmem), &_Py_ID(dklen), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"password", "salt", "n", "r", "p", "maxmem", "dklen", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "scrypt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "scrypt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[7]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer password = {NULL, NULL}; @@ -1077,7 +1474,7 @@ PyDoc_STRVAR(_hashlib_hmac_singleshot__doc__, "Single-shot HMAC."); #define _HASHLIB_HMAC_SINGLESHOT_METHODDEF \ - {"hmac_digest", (PyCFunction)(void(*)(void))_hashlib_hmac_singleshot, METH_FASTCALL|METH_KEYWORDS, _hashlib_hmac_singleshot__doc__}, + {"hmac_digest", _PyCFunction_CAST(_hashlib_hmac_singleshot), METH_FASTCALL|METH_KEYWORDS, _hashlib_hmac_singleshot__doc__}, static PyObject * _hashlib_hmac_singleshot_impl(PyObject *module, Py_buffer *key, @@ -1087,8 +1484,31 @@ static PyObject * _hashlib_hmac_singleshot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(msg), &_Py_ID(digest), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "msg", "digest", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hmac_digest", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hmac_digest", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_buffer key = {NULL, NULL}; Py_buffer msg = {NULL, NULL}; @@ -1135,7 +1555,7 @@ PyDoc_STRVAR(_hashlib_hmac_new__doc__, "Return a new hmac object."); #define _HASHLIB_HMAC_NEW_METHODDEF \ - {"hmac_new", (PyCFunction)(void(*)(void))_hashlib_hmac_new, METH_FASTCALL|METH_KEYWORDS, _hashlib_hmac_new__doc__}, + {"hmac_new", _PyCFunction_CAST(_hashlib_hmac_new), METH_FASTCALL|METH_KEYWORDS, _hashlib_hmac_new__doc__}, static PyObject * _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj, @@ -1145,8 +1565,31 @@ static PyObject * _hashlib_hmac_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(msg), &_Py_ID(digestmod), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "msg", "digestmod", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hmac_new", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hmac_new", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer key = {NULL, NULL}; @@ -1211,7 +1654,7 @@ PyDoc_STRVAR(_hashlib_HMAC_update__doc__, "Update the HMAC object with msg."); #define _HASHLIB_HMAC_UPDATE_METHODDEF \ - {"update", (PyCFunction)(void(*)(void))_hashlib_HMAC_update, METH_FASTCALL|METH_KEYWORDS, _hashlib_HMAC_update__doc__}, + {"update", _PyCFunction_CAST(_hashlib_HMAC_update), METH_FASTCALL|METH_KEYWORDS, _hashlib_HMAC_update__doc__}, static PyObject * _hashlib_HMAC_update_impl(HMACobject *self, PyObject *msg); @@ -1220,8 +1663,31 @@ static PyObject * _hashlib_HMAC_update(HMACobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(msg), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"msg", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "update", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "update", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *msg; @@ -1327,7 +1793,7 @@ PyDoc_STRVAR(_hashlib_compare_digest__doc__, "types and lengths of a and b--but not their values."); #define _HASHLIB_COMPARE_DIGEST_METHODDEF \ - {"compare_digest", (PyCFunction)(void(*)(void))_hashlib_compare_digest, METH_FASTCALL, _hashlib_compare_digest__doc__}, + {"compare_digest", _PyCFunction_CAST(_hashlib_compare_digest), METH_FASTCALL, _hashlib_compare_digest__doc__}, static PyObject * _hashlib_compare_digest_impl(PyObject *module, PyObject *a, PyObject *b); @@ -1385,4 +1851,4 @@ exit: #ifndef _HASHLIB_SCRYPT_METHODDEF #define _HASHLIB_SCRYPT_METHODDEF #endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */ -/*[clinic end generated code: output=162369cb9d43f1cc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b339e255db698147 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_heapqmodule.c.h b/Modules/clinic/_heapqmodule.c.h index a894315a766..3ee3f51702f 100644 --- a/Modules/clinic/_heapqmodule.c.h +++ b/Modules/clinic/_heapqmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_heapq_heappush__doc__, "heappush($module, heap, item, /)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(_heapq_heappush__doc__, "Push item onto heap, maintaining the heap invariant."); #define _HEAPQ_HEAPPUSH_METHODDEF \ - {"heappush", (PyCFunction)(void(*)(void))_heapq_heappush, METH_FASTCALL, _heapq_heappush__doc__}, + {"heappush", _PyCFunction_CAST(_heapq_heappush), METH_FASTCALL, _heapq_heappush__doc__}, static PyObject * _heapq_heappush_impl(PyObject *module, PyObject *heap, PyObject *item); @@ -80,7 +86,7 @@ PyDoc_STRVAR(_heapq_heapreplace__doc__, " item = heapreplace(heap, item)"); #define _HEAPQ_HEAPREPLACE_METHODDEF \ - {"heapreplace", (PyCFunction)(void(*)(void))_heapq_heapreplace, METH_FASTCALL, _heapq_heapreplace__doc__}, + {"heapreplace", _PyCFunction_CAST(_heapq_heapreplace), METH_FASTCALL, _heapq_heapreplace__doc__}, static PyObject * _heapq_heapreplace_impl(PyObject *module, PyObject *heap, PyObject *item); @@ -117,7 +123,7 @@ PyDoc_STRVAR(_heapq_heappushpop__doc__, "a separate call to heappop()."); #define _HEAPQ_HEAPPUSHPOP_METHODDEF \ - {"heappushpop", (PyCFunction)(void(*)(void))_heapq_heappushpop, METH_FASTCALL, _heapq_heappushpop__doc__}, + {"heappushpop", _PyCFunction_CAST(_heapq_heappushpop), METH_FASTCALL, _heapq_heappushpop__doc__}, static PyObject * _heapq_heappushpop_impl(PyObject *module, PyObject *heap, PyObject *item); @@ -209,7 +215,7 @@ PyDoc_STRVAR(_heapq__heapreplace_max__doc__, "Maxheap variant of heapreplace."); #define _HEAPQ__HEAPREPLACE_MAX_METHODDEF \ - {"_heapreplace_max", (PyCFunction)(void(*)(void))_heapq__heapreplace_max, METH_FASTCALL, _heapq__heapreplace_max__doc__}, + {"_heapreplace_max", _PyCFunction_CAST(_heapq__heapreplace_max), METH_FASTCALL, _heapq__heapreplace_max__doc__}, static PyObject * _heapq__heapreplace_max_impl(PyObject *module, PyObject *heap, @@ -265,4 +271,4 @@ _heapq__heapify_max(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=9975cf51762878d5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=29e99a48c57f82bb input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_localemodule.c.h b/Modules/clinic/_localemodule.c.h index 703d034c32e..e6b99962d15 100644 --- a/Modules/clinic/_localemodule.c.h +++ b/Modules/clinic/_localemodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_locale_setlocale__doc__, "setlocale($module, category, locale=, /)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(_locale_setlocale__doc__, "Activates/queries locale processing."); #define _LOCALE_SETLOCALE_METHODDEF \ - {"setlocale", (PyCFunction)(void(*)(void))_locale_setlocale, METH_FASTCALL, _locale_setlocale__doc__}, + {"setlocale", _PyCFunction_CAST(_locale_setlocale), METH_FASTCALL, _locale_setlocale__doc__}, static PyObject * _locale_setlocale_impl(PyObject *module, int category, const char *locale); @@ -83,7 +89,7 @@ PyDoc_STRVAR(_locale_strcoll__doc__, "Compares two strings according to the locale."); #define _LOCALE_STRCOLL_METHODDEF \ - {"strcoll", (PyCFunction)(void(*)(void))_locale_strcoll, METH_FASTCALL, _locale_strcoll__doc__}, + {"strcoll", _PyCFunction_CAST(_locale_strcoll), METH_FASTCALL, _locale_strcoll__doc__}, static PyObject * _locale_strcoll_impl(PyObject *module, PyObject *os1, PyObject *os2); @@ -265,7 +271,7 @@ PyDoc_STRVAR(_locale_dgettext__doc__, "Return translation of msg in domain."); #define _LOCALE_DGETTEXT_METHODDEF \ - {"dgettext", (PyCFunction)(void(*)(void))_locale_dgettext, METH_FASTCALL, _locale_dgettext__doc__}, + {"dgettext", _PyCFunction_CAST(_locale_dgettext), METH_FASTCALL, _locale_dgettext__doc__}, static PyObject * _locale_dgettext_impl(PyObject *module, const char *domain, const char *in); @@ -328,7 +334,7 @@ PyDoc_STRVAR(_locale_dcgettext__doc__, "Return translation of msg in domain and category."); #define _LOCALE_DCGETTEXT_METHODDEF \ - {"dcgettext", (PyCFunction)(void(*)(void))_locale_dcgettext, METH_FASTCALL, _locale_dcgettext__doc__}, + {"dcgettext", _PyCFunction_CAST(_locale_dcgettext), METH_FASTCALL, _locale_dcgettext__doc__}, static PyObject * _locale_dcgettext_impl(PyObject *module, const char *domain, @@ -443,7 +449,7 @@ PyDoc_STRVAR(_locale_bindtextdomain__doc__, "Bind the C library\'s domain to dir."); #define _LOCALE_BINDTEXTDOMAIN_METHODDEF \ - {"bindtextdomain", (PyCFunction)(void(*)(void))_locale_bindtextdomain, METH_FASTCALL, _locale_bindtextdomain__doc__}, + {"bindtextdomain", _PyCFunction_CAST(_locale_bindtextdomain), METH_FASTCALL, _locale_bindtextdomain__doc__}, static PyObject * _locale_bindtextdomain_impl(PyObject *module, const char *domain, @@ -490,7 +496,7 @@ PyDoc_STRVAR(_locale_bind_textdomain_codeset__doc__, "Bind the C library\'s domain to codeset."); #define _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF \ - {"bind_textdomain_codeset", (PyCFunction)(void(*)(void))_locale_bind_textdomain_codeset, METH_FASTCALL, _locale_bind_textdomain_codeset__doc__}, + {"bind_textdomain_codeset", _PyCFunction_CAST(_locale_bind_textdomain_codeset), METH_FASTCALL, _locale_bind_textdomain_codeset__doc__}, static PyObject * _locale_bind_textdomain_codeset_impl(PyObject *module, const char *domain, @@ -545,22 +551,22 @@ exit: #endif /* defined(HAVE_LIBINTL_H) && defined(HAVE_BIND_TEXTDOMAIN_CODESET) */ -PyDoc_STRVAR(_locale__get_locale_encoding__doc__, -"_get_locale_encoding($module, /)\n" +PyDoc_STRVAR(_locale_getencoding__doc__, +"getencoding($module, /)\n" "--\n" "\n" "Get the current locale encoding."); -#define _LOCALE__GET_LOCALE_ENCODING_METHODDEF \ - {"_get_locale_encoding", (PyCFunction)_locale__get_locale_encoding, METH_NOARGS, _locale__get_locale_encoding__doc__}, +#define _LOCALE_GETENCODING_METHODDEF \ + {"getencoding", (PyCFunction)_locale_getencoding, METH_NOARGS, _locale_getencoding__doc__}, static PyObject * -_locale__get_locale_encoding_impl(PyObject *module); +_locale_getencoding_impl(PyObject *module); static PyObject * -_locale__get_locale_encoding(PyObject *module, PyObject *Py_UNUSED(ignored)) +_locale_getencoding(PyObject *module, PyObject *Py_UNUSED(ignored)) { - return _locale__get_locale_encoding_impl(module); + return _locale_getencoding_impl(module); } #ifndef _LOCALE_STRCOLL_METHODDEF @@ -602,4 +608,4 @@ _locale__get_locale_encoding(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF #define _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF #endif /* !defined(_LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF) */ -/*[clinic end generated code: output=cd703c8a3a75fcf4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=406842c3441559cb input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_lsprof.c.h b/Modules/clinic/_lsprof.c.h index 5d9c209eab8..5fcc7ae02e3 100644 --- a/Modules/clinic/_lsprof.c.h +++ b/Modules/clinic/_lsprof.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_lsprof_Profiler_getstats__doc__, "getstats($self, /)\n" "--\n" @@ -31,7 +37,7 @@ PyDoc_STRVAR(_lsprof_Profiler_getstats__doc__, " inlinetime inline time (not in further subcalls)"); #define _LSPROF_PROFILER_GETSTATS_METHODDEF \ - {"getstats", (PyCFunction)(void(*)(void))_lsprof_Profiler_getstats, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _lsprof_Profiler_getstats__doc__}, + {"getstats", _PyCFunction_CAST(_lsprof_Profiler_getstats), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _lsprof_Profiler_getstats__doc__}, static PyObject * _lsprof_Profiler_getstats_impl(ProfilerObject *self, PyTypeObject *cls); @@ -39,17 +45,10 @@ _lsprof_Profiler_getstats_impl(ProfilerObject *self, PyTypeObject *cls); static PyObject * _lsprof_Profiler_getstats(ProfilerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":getstats", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "getstats() takes no arguments"); + return NULL; } - return_value = _lsprof_Profiler_getstats_impl(self, cls); - -exit: - return return_value; + return _lsprof_Profiler_getstats_impl(self, cls); } -/*[clinic end generated code: output=b4727cfebecdd22d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7425d3481349629a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_lzmamodule.c.h b/Modules/clinic/_lzmamodule.c.h index 526031ade3b..286d2b00706 100644 --- a/Modules/clinic/_lzmamodule.c.h +++ b/Modules/clinic/_lzmamodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_lzma_LZMACompressor_compress__doc__, "compress($self, data, /)\n" "--\n" @@ -85,7 +91,7 @@ PyDoc_STRVAR(_lzma_LZMADecompressor_decompress__doc__, "the unused_data attribute."); #define _LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF \ - {"decompress", (PyCFunction)(void(*)(void))_lzma_LZMADecompressor_decompress, METH_FASTCALL|METH_KEYWORDS, _lzma_LZMADecompressor_decompress__doc__}, + {"decompress", _PyCFunction_CAST(_lzma_LZMADecompressor_decompress), METH_FASTCALL|METH_KEYWORDS, _lzma_LZMADecompressor_decompress__doc__}, static PyObject * _lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data, @@ -95,8 +101,31 @@ static PyObject * _lzma_LZMADecompressor_decompress(Decompressor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(max_length), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"data", "max_length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -171,8 +200,31 @@ static int _lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(format), &_Py_ID(memlimit), &_Py_ID(filters), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"format", "memlimit", "filters", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "LZMADecompressor", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "LZMADecompressor", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -250,7 +302,7 @@ PyDoc_STRVAR(_lzma__decode_filter_properties__doc__, "The result does not include the filter ID itself, only the options."); #define _LZMA__DECODE_FILTER_PROPERTIES_METHODDEF \ - {"_decode_filter_properties", (PyCFunction)(void(*)(void))_lzma__decode_filter_properties, METH_FASTCALL, _lzma__decode_filter_properties__doc__}, + {"_decode_filter_properties", _PyCFunction_CAST(_lzma__decode_filter_properties), METH_FASTCALL, _lzma__decode_filter_properties__doc__}, static PyObject * _lzma__decode_filter_properties_impl(PyObject *module, lzma_vli filter_id, @@ -286,4 +338,4 @@ exit: return return_value; } -/*[clinic end generated code: output=867b9e334053b679 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=da3e83ba97244044 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_opcode.c.h b/Modules/clinic/_opcode.c.h index 6ef303bb05e..3bd3ba02387 100644 --- a/Modules/clinic/_opcode.c.h +++ b/Modules/clinic/_opcode.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_opcode_stack_effect__doc__, "stack_effect($module, opcode, oparg=None, /, *, jump=None)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(_opcode_stack_effect__doc__, "Compute the stack effect of the opcode."); #define _OPCODE_STACK_EFFECT_METHODDEF \ - {"stack_effect", (PyCFunction)(void(*)(void))_opcode_stack_effect, METH_FASTCALL|METH_KEYWORDS, _opcode_stack_effect__doc__}, + {"stack_effect", _PyCFunction_CAST(_opcode_stack_effect), METH_FASTCALL|METH_KEYWORDS, _opcode_stack_effect__doc__}, static int _opcode_stack_effect_impl(PyObject *module, int opcode, PyObject *oparg, @@ -19,8 +25,31 @@ static PyObject * _opcode_stack_effect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(jump), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "jump", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "stack_effect", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "stack_effect", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; int opcode; @@ -74,4 +103,4 @@ _opcode_get_specialization_stats(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _opcode_get_specialization_stats_impl(module); } -/*[clinic end generated code: output=1699b4b1488b49c1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=21e3d53a659c651a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_operator.c.h b/Modules/clinic/_operator.c.h index bda2eba6d12..b68e6e0144a 100644 --- a/Modules/clinic/_operator.c.h +++ b/Modules/clinic/_operator.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_operator_truth__doc__, "truth($module, a, /)\n" "--\n" @@ -37,7 +43,7 @@ PyDoc_STRVAR(_operator_add__doc__, "Same as a + b."); #define _OPERATOR_ADD_METHODDEF \ - {"add", (PyCFunction)(void(*)(void))_operator_add, METH_FASTCALL, _operator_add__doc__}, + {"add", _PyCFunction_CAST(_operator_add), METH_FASTCALL, _operator_add__doc__}, static PyObject * _operator_add_impl(PyObject *module, PyObject *a, PyObject *b); @@ -67,7 +73,7 @@ PyDoc_STRVAR(_operator_sub__doc__, "Same as a - b."); #define _OPERATOR_SUB_METHODDEF \ - {"sub", (PyCFunction)(void(*)(void))_operator_sub, METH_FASTCALL, _operator_sub__doc__}, + {"sub", _PyCFunction_CAST(_operator_sub), METH_FASTCALL, _operator_sub__doc__}, static PyObject * _operator_sub_impl(PyObject *module, PyObject *a, PyObject *b); @@ -97,7 +103,7 @@ PyDoc_STRVAR(_operator_mul__doc__, "Same as a * b."); #define _OPERATOR_MUL_METHODDEF \ - {"mul", (PyCFunction)(void(*)(void))_operator_mul, METH_FASTCALL, _operator_mul__doc__}, + {"mul", _PyCFunction_CAST(_operator_mul), METH_FASTCALL, _operator_mul__doc__}, static PyObject * _operator_mul_impl(PyObject *module, PyObject *a, PyObject *b); @@ -127,7 +133,7 @@ PyDoc_STRVAR(_operator_matmul__doc__, "Same as a @ b."); #define _OPERATOR_MATMUL_METHODDEF \ - {"matmul", (PyCFunction)(void(*)(void))_operator_matmul, METH_FASTCALL, _operator_matmul__doc__}, + {"matmul", _PyCFunction_CAST(_operator_matmul), METH_FASTCALL, _operator_matmul__doc__}, static PyObject * _operator_matmul_impl(PyObject *module, PyObject *a, PyObject *b); @@ -157,7 +163,7 @@ PyDoc_STRVAR(_operator_floordiv__doc__, "Same as a // b."); #define _OPERATOR_FLOORDIV_METHODDEF \ - {"floordiv", (PyCFunction)(void(*)(void))_operator_floordiv, METH_FASTCALL, _operator_floordiv__doc__}, + {"floordiv", _PyCFunction_CAST(_operator_floordiv), METH_FASTCALL, _operator_floordiv__doc__}, static PyObject * _operator_floordiv_impl(PyObject *module, PyObject *a, PyObject *b); @@ -187,7 +193,7 @@ PyDoc_STRVAR(_operator_truediv__doc__, "Same as a / b."); #define _OPERATOR_TRUEDIV_METHODDEF \ - {"truediv", (PyCFunction)(void(*)(void))_operator_truediv, METH_FASTCALL, _operator_truediv__doc__}, + {"truediv", _PyCFunction_CAST(_operator_truediv), METH_FASTCALL, _operator_truediv__doc__}, static PyObject * _operator_truediv_impl(PyObject *module, PyObject *a, PyObject *b); @@ -217,7 +223,7 @@ PyDoc_STRVAR(_operator_mod__doc__, "Same as a % b."); #define _OPERATOR_MOD_METHODDEF \ - {"mod", (PyCFunction)(void(*)(void))_operator_mod, METH_FASTCALL, _operator_mod__doc__}, + {"mod", _PyCFunction_CAST(_operator_mod), METH_FASTCALL, _operator_mod__doc__}, static PyObject * _operator_mod_impl(PyObject *module, PyObject *a, PyObject *b); @@ -292,7 +298,7 @@ PyDoc_STRVAR(_operator_lshift__doc__, "Same as a << b."); #define _OPERATOR_LSHIFT_METHODDEF \ - {"lshift", (PyCFunction)(void(*)(void))_operator_lshift, METH_FASTCALL, _operator_lshift__doc__}, + {"lshift", _PyCFunction_CAST(_operator_lshift), METH_FASTCALL, _operator_lshift__doc__}, static PyObject * _operator_lshift_impl(PyObject *module, PyObject *a, PyObject *b); @@ -322,7 +328,7 @@ PyDoc_STRVAR(_operator_rshift__doc__, "Same as a >> b."); #define _OPERATOR_RSHIFT_METHODDEF \ - {"rshift", (PyCFunction)(void(*)(void))_operator_rshift, METH_FASTCALL, _operator_rshift__doc__}, + {"rshift", _PyCFunction_CAST(_operator_rshift), METH_FASTCALL, _operator_rshift__doc__}, static PyObject * _operator_rshift_impl(PyObject *module, PyObject *a, PyObject *b); @@ -380,7 +386,7 @@ PyDoc_STRVAR(_operator_and___doc__, "Same as a & b."); #define _OPERATOR_AND__METHODDEF \ - {"and_", (PyCFunction)(void(*)(void))_operator_and_, METH_FASTCALL, _operator_and___doc__}, + {"and_", _PyCFunction_CAST(_operator_and_), METH_FASTCALL, _operator_and___doc__}, static PyObject * _operator_and__impl(PyObject *module, PyObject *a, PyObject *b); @@ -410,7 +416,7 @@ PyDoc_STRVAR(_operator_xor__doc__, "Same as a ^ b."); #define _OPERATOR_XOR_METHODDEF \ - {"xor", (PyCFunction)(void(*)(void))_operator_xor, METH_FASTCALL, _operator_xor__doc__}, + {"xor", _PyCFunction_CAST(_operator_xor), METH_FASTCALL, _operator_xor__doc__}, static PyObject * _operator_xor_impl(PyObject *module, PyObject *a, PyObject *b); @@ -440,7 +446,7 @@ PyDoc_STRVAR(_operator_or___doc__, "Same as a | b."); #define _OPERATOR_OR__METHODDEF \ - {"or_", (PyCFunction)(void(*)(void))_operator_or_, METH_FASTCALL, _operator_or___doc__}, + {"or_", _PyCFunction_CAST(_operator_or_), METH_FASTCALL, _operator_or___doc__}, static PyObject * _operator_or__impl(PyObject *module, PyObject *a, PyObject *b); @@ -470,7 +476,7 @@ PyDoc_STRVAR(_operator_iadd__doc__, "Same as a += b."); #define _OPERATOR_IADD_METHODDEF \ - {"iadd", (PyCFunction)(void(*)(void))_operator_iadd, METH_FASTCALL, _operator_iadd__doc__}, + {"iadd", _PyCFunction_CAST(_operator_iadd), METH_FASTCALL, _operator_iadd__doc__}, static PyObject * _operator_iadd_impl(PyObject *module, PyObject *a, PyObject *b); @@ -500,7 +506,7 @@ PyDoc_STRVAR(_operator_isub__doc__, "Same as a -= b."); #define _OPERATOR_ISUB_METHODDEF \ - {"isub", (PyCFunction)(void(*)(void))_operator_isub, METH_FASTCALL, _operator_isub__doc__}, + {"isub", _PyCFunction_CAST(_operator_isub), METH_FASTCALL, _operator_isub__doc__}, static PyObject * _operator_isub_impl(PyObject *module, PyObject *a, PyObject *b); @@ -530,7 +536,7 @@ PyDoc_STRVAR(_operator_imul__doc__, "Same as a *= b."); #define _OPERATOR_IMUL_METHODDEF \ - {"imul", (PyCFunction)(void(*)(void))_operator_imul, METH_FASTCALL, _operator_imul__doc__}, + {"imul", _PyCFunction_CAST(_operator_imul), METH_FASTCALL, _operator_imul__doc__}, static PyObject * _operator_imul_impl(PyObject *module, PyObject *a, PyObject *b); @@ -560,7 +566,7 @@ PyDoc_STRVAR(_operator_imatmul__doc__, "Same as a @= b."); #define _OPERATOR_IMATMUL_METHODDEF \ - {"imatmul", (PyCFunction)(void(*)(void))_operator_imatmul, METH_FASTCALL, _operator_imatmul__doc__}, + {"imatmul", _PyCFunction_CAST(_operator_imatmul), METH_FASTCALL, _operator_imatmul__doc__}, static PyObject * _operator_imatmul_impl(PyObject *module, PyObject *a, PyObject *b); @@ -590,7 +596,7 @@ PyDoc_STRVAR(_operator_ifloordiv__doc__, "Same as a //= b."); #define _OPERATOR_IFLOORDIV_METHODDEF \ - {"ifloordiv", (PyCFunction)(void(*)(void))_operator_ifloordiv, METH_FASTCALL, _operator_ifloordiv__doc__}, + {"ifloordiv", _PyCFunction_CAST(_operator_ifloordiv), METH_FASTCALL, _operator_ifloordiv__doc__}, static PyObject * _operator_ifloordiv_impl(PyObject *module, PyObject *a, PyObject *b); @@ -620,7 +626,7 @@ PyDoc_STRVAR(_operator_itruediv__doc__, "Same as a /= b."); #define _OPERATOR_ITRUEDIV_METHODDEF \ - {"itruediv", (PyCFunction)(void(*)(void))_operator_itruediv, METH_FASTCALL, _operator_itruediv__doc__}, + {"itruediv", _PyCFunction_CAST(_operator_itruediv), METH_FASTCALL, _operator_itruediv__doc__}, static PyObject * _operator_itruediv_impl(PyObject *module, PyObject *a, PyObject *b); @@ -650,7 +656,7 @@ PyDoc_STRVAR(_operator_imod__doc__, "Same as a %= b."); #define _OPERATOR_IMOD_METHODDEF \ - {"imod", (PyCFunction)(void(*)(void))_operator_imod, METH_FASTCALL, _operator_imod__doc__}, + {"imod", _PyCFunction_CAST(_operator_imod), METH_FASTCALL, _operator_imod__doc__}, static PyObject * _operator_imod_impl(PyObject *module, PyObject *a, PyObject *b); @@ -680,7 +686,7 @@ PyDoc_STRVAR(_operator_ilshift__doc__, "Same as a <<= b."); #define _OPERATOR_ILSHIFT_METHODDEF \ - {"ilshift", (PyCFunction)(void(*)(void))_operator_ilshift, METH_FASTCALL, _operator_ilshift__doc__}, + {"ilshift", _PyCFunction_CAST(_operator_ilshift), METH_FASTCALL, _operator_ilshift__doc__}, static PyObject * _operator_ilshift_impl(PyObject *module, PyObject *a, PyObject *b); @@ -710,7 +716,7 @@ PyDoc_STRVAR(_operator_irshift__doc__, "Same as a >>= b."); #define _OPERATOR_IRSHIFT_METHODDEF \ - {"irshift", (PyCFunction)(void(*)(void))_operator_irshift, METH_FASTCALL, _operator_irshift__doc__}, + {"irshift", _PyCFunction_CAST(_operator_irshift), METH_FASTCALL, _operator_irshift__doc__}, static PyObject * _operator_irshift_impl(PyObject *module, PyObject *a, PyObject *b); @@ -740,7 +746,7 @@ PyDoc_STRVAR(_operator_iand__doc__, "Same as a &= b."); #define _OPERATOR_IAND_METHODDEF \ - {"iand", (PyCFunction)(void(*)(void))_operator_iand, METH_FASTCALL, _operator_iand__doc__}, + {"iand", _PyCFunction_CAST(_operator_iand), METH_FASTCALL, _operator_iand__doc__}, static PyObject * _operator_iand_impl(PyObject *module, PyObject *a, PyObject *b); @@ -770,7 +776,7 @@ PyDoc_STRVAR(_operator_ixor__doc__, "Same as a ^= b."); #define _OPERATOR_IXOR_METHODDEF \ - {"ixor", (PyCFunction)(void(*)(void))_operator_ixor, METH_FASTCALL, _operator_ixor__doc__}, + {"ixor", _PyCFunction_CAST(_operator_ixor), METH_FASTCALL, _operator_ixor__doc__}, static PyObject * _operator_ixor_impl(PyObject *module, PyObject *a, PyObject *b); @@ -800,7 +806,7 @@ PyDoc_STRVAR(_operator_ior__doc__, "Same as a |= b."); #define _OPERATOR_IOR_METHODDEF \ - {"ior", (PyCFunction)(void(*)(void))_operator_ior, METH_FASTCALL, _operator_ior__doc__}, + {"ior", _PyCFunction_CAST(_operator_ior), METH_FASTCALL, _operator_ior__doc__}, static PyObject * _operator_ior_impl(PyObject *module, PyObject *a, PyObject *b); @@ -830,7 +836,7 @@ PyDoc_STRVAR(_operator_concat__doc__, "Same as a + b, for a and b sequences."); #define _OPERATOR_CONCAT_METHODDEF \ - {"concat", (PyCFunction)(void(*)(void))_operator_concat, METH_FASTCALL, _operator_concat__doc__}, + {"concat", _PyCFunction_CAST(_operator_concat), METH_FASTCALL, _operator_concat__doc__}, static PyObject * _operator_concat_impl(PyObject *module, PyObject *a, PyObject *b); @@ -860,7 +866,7 @@ PyDoc_STRVAR(_operator_iconcat__doc__, "Same as a += b, for a and b sequences."); #define _OPERATOR_ICONCAT_METHODDEF \ - {"iconcat", (PyCFunction)(void(*)(void))_operator_iconcat, METH_FASTCALL, _operator_iconcat__doc__}, + {"iconcat", _PyCFunction_CAST(_operator_iconcat), METH_FASTCALL, _operator_iconcat__doc__}, static PyObject * _operator_iconcat_impl(PyObject *module, PyObject *a, PyObject *b); @@ -890,7 +896,7 @@ PyDoc_STRVAR(_operator_contains__doc__, "Same as b in a (note reversed operands)."); #define _OPERATOR_CONTAINS_METHODDEF \ - {"contains", (PyCFunction)(void(*)(void))_operator_contains, METH_FASTCALL, _operator_contains__doc__}, + {"contains", _PyCFunction_CAST(_operator_contains), METH_FASTCALL, _operator_contains__doc__}, static int _operator_contains_impl(PyObject *module, PyObject *a, PyObject *b); @@ -925,7 +931,7 @@ PyDoc_STRVAR(_operator_indexOf__doc__, "Return the first index of b in a."); #define _OPERATOR_INDEXOF_METHODDEF \ - {"indexOf", (PyCFunction)(void(*)(void))_operator_indexOf, METH_FASTCALL, _operator_indexOf__doc__}, + {"indexOf", _PyCFunction_CAST(_operator_indexOf), METH_FASTCALL, _operator_indexOf__doc__}, static Py_ssize_t _operator_indexOf_impl(PyObject *module, PyObject *a, PyObject *b); @@ -960,7 +966,7 @@ PyDoc_STRVAR(_operator_countOf__doc__, "Return the number of items in a which are, or which equal, b."); #define _OPERATOR_COUNTOF_METHODDEF \ - {"countOf", (PyCFunction)(void(*)(void))_operator_countOf, METH_FASTCALL, _operator_countOf__doc__}, + {"countOf", _PyCFunction_CAST(_operator_countOf), METH_FASTCALL, _operator_countOf__doc__}, static Py_ssize_t _operator_countOf_impl(PyObject *module, PyObject *a, PyObject *b); @@ -995,7 +1001,7 @@ PyDoc_STRVAR(_operator_getitem__doc__, "Same as a[b]."); #define _OPERATOR_GETITEM_METHODDEF \ - {"getitem", (PyCFunction)(void(*)(void))_operator_getitem, METH_FASTCALL, _operator_getitem__doc__}, + {"getitem", _PyCFunction_CAST(_operator_getitem), METH_FASTCALL, _operator_getitem__doc__}, static PyObject * _operator_getitem_impl(PyObject *module, PyObject *a, PyObject *b); @@ -1025,7 +1031,7 @@ PyDoc_STRVAR(_operator_setitem__doc__, "Same as a[b] = c."); #define _OPERATOR_SETITEM_METHODDEF \ - {"setitem", (PyCFunction)(void(*)(void))_operator_setitem, METH_FASTCALL, _operator_setitem__doc__}, + {"setitem", _PyCFunction_CAST(_operator_setitem), METH_FASTCALL, _operator_setitem__doc__}, static PyObject * _operator_setitem_impl(PyObject *module, PyObject *a, PyObject *b, @@ -1058,7 +1064,7 @@ PyDoc_STRVAR(_operator_delitem__doc__, "Same as del a[b]."); #define _OPERATOR_DELITEM_METHODDEF \ - {"delitem", (PyCFunction)(void(*)(void))_operator_delitem, METH_FASTCALL, _operator_delitem__doc__}, + {"delitem", _PyCFunction_CAST(_operator_delitem), METH_FASTCALL, _operator_delitem__doc__}, static PyObject * _operator_delitem_impl(PyObject *module, PyObject *a, PyObject *b); @@ -1088,7 +1094,7 @@ PyDoc_STRVAR(_operator_eq__doc__, "Same as a == b."); #define _OPERATOR_EQ_METHODDEF \ - {"eq", (PyCFunction)(void(*)(void))_operator_eq, METH_FASTCALL, _operator_eq__doc__}, + {"eq", _PyCFunction_CAST(_operator_eq), METH_FASTCALL, _operator_eq__doc__}, static PyObject * _operator_eq_impl(PyObject *module, PyObject *a, PyObject *b); @@ -1118,7 +1124,7 @@ PyDoc_STRVAR(_operator_ne__doc__, "Same as a != b."); #define _OPERATOR_NE_METHODDEF \ - {"ne", (PyCFunction)(void(*)(void))_operator_ne, METH_FASTCALL, _operator_ne__doc__}, + {"ne", _PyCFunction_CAST(_operator_ne), METH_FASTCALL, _operator_ne__doc__}, static PyObject * _operator_ne_impl(PyObject *module, PyObject *a, PyObject *b); @@ -1148,7 +1154,7 @@ PyDoc_STRVAR(_operator_lt__doc__, "Same as a < b."); #define _OPERATOR_LT_METHODDEF \ - {"lt", (PyCFunction)(void(*)(void))_operator_lt, METH_FASTCALL, _operator_lt__doc__}, + {"lt", _PyCFunction_CAST(_operator_lt), METH_FASTCALL, _operator_lt__doc__}, static PyObject * _operator_lt_impl(PyObject *module, PyObject *a, PyObject *b); @@ -1178,7 +1184,7 @@ PyDoc_STRVAR(_operator_le__doc__, "Same as a <= b."); #define _OPERATOR_LE_METHODDEF \ - {"le", (PyCFunction)(void(*)(void))_operator_le, METH_FASTCALL, _operator_le__doc__}, + {"le", _PyCFunction_CAST(_operator_le), METH_FASTCALL, _operator_le__doc__}, static PyObject * _operator_le_impl(PyObject *module, PyObject *a, PyObject *b); @@ -1208,7 +1214,7 @@ PyDoc_STRVAR(_operator_gt__doc__, "Same as a > b."); #define _OPERATOR_GT_METHODDEF \ - {"gt", (PyCFunction)(void(*)(void))_operator_gt, METH_FASTCALL, _operator_gt__doc__}, + {"gt", _PyCFunction_CAST(_operator_gt), METH_FASTCALL, _operator_gt__doc__}, static PyObject * _operator_gt_impl(PyObject *module, PyObject *a, PyObject *b); @@ -1238,7 +1244,7 @@ PyDoc_STRVAR(_operator_ge__doc__, "Same as a >= b."); #define _OPERATOR_GE_METHODDEF \ - {"ge", (PyCFunction)(void(*)(void))_operator_ge, METH_FASTCALL, _operator_ge__doc__}, + {"ge", _PyCFunction_CAST(_operator_ge), METH_FASTCALL, _operator_ge__doc__}, static PyObject * _operator_ge_impl(PyObject *module, PyObject *a, PyObject *b); @@ -1268,7 +1274,7 @@ PyDoc_STRVAR(_operator_pow__doc__, "Same as a ** b."); #define _OPERATOR_POW_METHODDEF \ - {"pow", (PyCFunction)(void(*)(void))_operator_pow, METH_FASTCALL, _operator_pow__doc__}, + {"pow", _PyCFunction_CAST(_operator_pow), METH_FASTCALL, _operator_pow__doc__}, static PyObject * _operator_pow_impl(PyObject *module, PyObject *a, PyObject *b); @@ -1298,7 +1304,7 @@ PyDoc_STRVAR(_operator_ipow__doc__, "Same as a **= b."); #define _OPERATOR_IPOW_METHODDEF \ - {"ipow", (PyCFunction)(void(*)(void))_operator_ipow, METH_FASTCALL, _operator_ipow__doc__}, + {"ipow", _PyCFunction_CAST(_operator_ipow), METH_FASTCALL, _operator_ipow__doc__}, static PyObject * _operator_ipow_impl(PyObject *module, PyObject *a, PyObject *b); @@ -1337,7 +1343,7 @@ PyDoc_STRVAR(_operator_is___doc__, "Same as a is b."); #define _OPERATOR_IS__METHODDEF \ - {"is_", (PyCFunction)(void(*)(void))_operator_is_, METH_FASTCALL, _operator_is___doc__}, + {"is_", _PyCFunction_CAST(_operator_is_), METH_FASTCALL, _operator_is___doc__}, static PyObject * _operator_is__impl(PyObject *module, PyObject *a, PyObject *b); @@ -1367,7 +1373,7 @@ PyDoc_STRVAR(_operator_is_not__doc__, "Same as a is not b."); #define _OPERATOR_IS_NOT_METHODDEF \ - {"is_not", (PyCFunction)(void(*)(void))_operator_is_not, METH_FASTCALL, _operator_is_not__doc__}, + {"is_not", _PyCFunction_CAST(_operator_is_not), METH_FASTCALL, _operator_is_not__doc__}, static PyObject * _operator_is_not_impl(PyObject *module, PyObject *a, PyObject *b); @@ -1403,7 +1409,7 @@ PyDoc_STRVAR(_operator_length_hint__doc__, "The result will be an integer >= 0."); #define _OPERATOR_LENGTH_HINT_METHODDEF \ - {"length_hint", (PyCFunction)(void(*)(void))_operator_length_hint, METH_FASTCALL, _operator_length_hint__doc__}, + {"length_hint", _PyCFunction_CAST(_operator_length_hint), METH_FASTCALL, _operator_length_hint__doc__}, static Py_ssize_t _operator_length_hint_impl(PyObject *module, PyObject *obj, @@ -1464,7 +1470,7 @@ PyDoc_STRVAR(_operator__compare_digest__doc__, "types and lengths of a and b--but not their values."); #define _OPERATOR__COMPARE_DIGEST_METHODDEF \ - {"_compare_digest", (PyCFunction)(void(*)(void))_operator__compare_digest, METH_FASTCALL, _operator__compare_digest__doc__}, + {"_compare_digest", _PyCFunction_CAST(_operator__compare_digest), METH_FASTCALL, _operator__compare_digest__doc__}, static PyObject * _operator__compare_digest_impl(PyObject *module, PyObject *a, PyObject *b); @@ -1486,4 +1492,4 @@ _operator__compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t na exit: return return_value; } -/*[clinic end generated code: output=16749e11fda51785 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=227cbcfed44f736e input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h index 136524b6a71..adb3abc5eb2 100644 --- a/Modules/clinic/_pickle.c.h +++ b/Modules/clinic/_pickle.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_pickle_Pickler_clear_memo__doc__, "clear_memo($self, /)\n" "--\n" @@ -43,20 +49,20 @@ PyDoc_STRVAR(_pickle_Pickler___sizeof____doc__, #define _PICKLE_PICKLER___SIZEOF___METHODDEF \ {"__sizeof__", (PyCFunction)_pickle_Pickler___sizeof__, METH_NOARGS, _pickle_Pickler___sizeof____doc__}, -static Py_ssize_t +static size_t _pickle_Pickler___sizeof___impl(PicklerObject *self); static PyObject * _pickle_Pickler___sizeof__(PicklerObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *return_value = NULL; - Py_ssize_t _return_value; + size_t _return_value; _return_value = _pickle_Pickler___sizeof___impl(self); - if ((_return_value == -1) && PyErr_Occurred()) { + if ((_return_value == (size_t)-1) && PyErr_Occurred()) { goto exit; } - return_value = PyLong_FromSsize_t(_return_value); + return_value = PyLong_FromSize_t(_return_value); exit: return return_value; @@ -106,8 +112,31 @@ static int _pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(protocol), &_Py_ID(fix_imports), &_Py_ID(buffer_callback), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"file", "protocol", "fix_imports", "buffer_callback", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Pickler", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Pickler", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -238,7 +267,7 @@ PyDoc_STRVAR(_pickle_Unpickler_find_class__doc__, "needed. Both arguments passed are str objects."); #define _PICKLE_UNPICKLER_FIND_CLASS_METHODDEF \ - {"find_class", (PyCFunction)(void(*)(void))_pickle_Unpickler_find_class, METH_FASTCALL, _pickle_Unpickler_find_class__doc__}, + {"find_class", _PyCFunction_CAST(_pickle_Unpickler_find_class), METH_FASTCALL, _pickle_Unpickler_find_class__doc__}, static PyObject * _pickle_Unpickler_find_class_impl(UnpicklerObject *self, @@ -272,20 +301,20 @@ PyDoc_STRVAR(_pickle_Unpickler___sizeof____doc__, #define _PICKLE_UNPICKLER___SIZEOF___METHODDEF \ {"__sizeof__", (PyCFunction)_pickle_Unpickler___sizeof__, METH_NOARGS, _pickle_Unpickler___sizeof____doc__}, -static Py_ssize_t +static size_t _pickle_Unpickler___sizeof___impl(UnpicklerObject *self); static PyObject * _pickle_Unpickler___sizeof__(UnpicklerObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *return_value = NULL; - Py_ssize_t _return_value; + size_t _return_value; _return_value = _pickle_Unpickler___sizeof___impl(self); - if ((_return_value == -1) && PyErr_Occurred()) { + if ((_return_value == (size_t)-1) && PyErr_Occurred()) { goto exit; } - return_value = PyLong_FromSsize_t(_return_value); + return_value = PyLong_FromSize_t(_return_value); exit: return return_value; @@ -326,8 +355,31 @@ static int _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(fix_imports), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(buffers), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"file", "fix_imports", "encoding", "errors", "buffers", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Unpickler", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Unpickler", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -486,7 +538,7 @@ PyDoc_STRVAR(_pickle_dump__doc__, "*buffer_callback* is not None and *protocol* is None or smaller than 5."); #define _PICKLE_DUMP_METHODDEF \ - {"dump", (PyCFunction)(void(*)(void))_pickle_dump, METH_FASTCALL|METH_KEYWORDS, _pickle_dump__doc__}, + {"dump", _PyCFunction_CAST(_pickle_dump), METH_FASTCALL|METH_KEYWORDS, _pickle_dump__doc__}, static PyObject * _pickle_dump_impl(PyObject *module, PyObject *obj, PyObject *file, @@ -497,8 +549,31 @@ static PyObject * _pickle_dump(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(obj), &_Py_ID(file), &_Py_ID(protocol), &_Py_ID(fix_imports), &_Py_ID(buffer_callback), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"obj", "file", "protocol", "fix_imports", "buffer_callback", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "dump", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "dump", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *obj; @@ -568,7 +643,7 @@ PyDoc_STRVAR(_pickle_dumps__doc__, "*buffer_callback* is not None and *protocol* is None or smaller than 5."); #define _PICKLE_DUMPS_METHODDEF \ - {"dumps", (PyCFunction)(void(*)(void))_pickle_dumps, METH_FASTCALL|METH_KEYWORDS, _pickle_dumps__doc__}, + {"dumps", _PyCFunction_CAST(_pickle_dumps), METH_FASTCALL|METH_KEYWORDS, _pickle_dumps__doc__}, static PyObject * _pickle_dumps_impl(PyObject *module, PyObject *obj, PyObject *protocol, @@ -578,8 +653,31 @@ static PyObject * _pickle_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(obj), &_Py_ID(protocol), &_Py_ID(fix_imports), &_Py_ID(buffer_callback), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"obj", "protocol", "fix_imports", "buffer_callback", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "dumps", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "dumps", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *obj; @@ -652,7 +750,7 @@ PyDoc_STRVAR(_pickle_load__doc__, "string instances as bytes objects."); #define _PICKLE_LOAD_METHODDEF \ - {"load", (PyCFunction)(void(*)(void))_pickle_load, METH_FASTCALL|METH_KEYWORDS, _pickle_load__doc__}, + {"load", _PyCFunction_CAST(_pickle_load), METH_FASTCALL|METH_KEYWORDS, _pickle_load__doc__}, static PyObject * _pickle_load_impl(PyObject *module, PyObject *file, int fix_imports, @@ -663,8 +761,31 @@ static PyObject * _pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(fix_imports), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(buffers), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"file", "fix_imports", "encoding", "errors", "buffers", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "load", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "load", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *file; @@ -755,7 +876,7 @@ PyDoc_STRVAR(_pickle_loads__doc__, "string instances as bytes objects."); #define _PICKLE_LOADS_METHODDEF \ - {"loads", (PyCFunction)(void(*)(void))_pickle_loads, METH_FASTCALL|METH_KEYWORDS, _pickle_loads__doc__}, + {"loads", _PyCFunction_CAST(_pickle_loads), METH_FASTCALL|METH_KEYWORDS, _pickle_loads__doc__}, static PyObject * _pickle_loads_impl(PyObject *module, PyObject *data, int fix_imports, @@ -766,8 +887,31 @@ static PyObject * _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fix_imports), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(buffers), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "fix_imports", "encoding", "errors", "buffers", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "loads", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "loads", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *data; @@ -836,4 +980,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=324aad69644beda2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=730dc26938561313 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_queuemodule.c.h b/Modules/clinic/_queuemodule.c.h index 22d2e992b63..f86dac3c497 100644 --- a/Modules/clinic/_queuemodule.c.h +++ b/Modules/clinic/_queuemodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(simplequeue_new__doc__, "SimpleQueue()\n" "--\n" @@ -42,7 +48,7 @@ PyDoc_STRVAR(_queue_SimpleQueue_put__doc__, "never blocks. They are provided for compatibility with the Queue class."); #define _QUEUE_SIMPLEQUEUE_PUT_METHODDEF \ - {"put", (PyCFunction)(void(*)(void))_queue_SimpleQueue_put, METH_FASTCALL|METH_KEYWORDS, _queue_SimpleQueue_put__doc__}, + {"put", _PyCFunction_CAST(_queue_SimpleQueue_put), METH_FASTCALL|METH_KEYWORDS, _queue_SimpleQueue_put__doc__}, static PyObject * _queue_SimpleQueue_put_impl(simplequeueobject *self, PyObject *item, @@ -52,8 +58,31 @@ static PyObject * _queue_SimpleQueue_put(simplequeueobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(item), &_Py_ID(block), &_Py_ID(timeout), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"item", "block", "timeout", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "put", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "put", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *item; @@ -95,7 +124,7 @@ PyDoc_STRVAR(_queue_SimpleQueue_put_nowait__doc__, "for compatibility with the Queue class."); #define _QUEUE_SIMPLEQUEUE_PUT_NOWAIT_METHODDEF \ - {"put_nowait", (PyCFunction)(void(*)(void))_queue_SimpleQueue_put_nowait, METH_FASTCALL|METH_KEYWORDS, _queue_SimpleQueue_put_nowait__doc__}, + {"put_nowait", _PyCFunction_CAST(_queue_SimpleQueue_put_nowait), METH_FASTCALL|METH_KEYWORDS, _queue_SimpleQueue_put_nowait__doc__}, static PyObject * _queue_SimpleQueue_put_nowait_impl(simplequeueobject *self, PyObject *item); @@ -104,8 +133,31 @@ static PyObject * _queue_SimpleQueue_put_nowait(simplequeueobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(item), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"item", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "put_nowait", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "put_nowait", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *item; @@ -135,7 +187,7 @@ PyDoc_STRVAR(_queue_SimpleQueue_get__doc__, "in that case)."); #define _QUEUE_SIMPLEQUEUE_GET_METHODDEF \ - {"get", (PyCFunction)(void(*)(void))_queue_SimpleQueue_get, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _queue_SimpleQueue_get__doc__}, + {"get", _PyCFunction_CAST(_queue_SimpleQueue_get), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _queue_SimpleQueue_get__doc__}, static PyObject * _queue_SimpleQueue_get_impl(simplequeueobject *self, PyTypeObject *cls, @@ -145,15 +197,54 @@ static PyObject * _queue_SimpleQueue_get(simplequeueobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(block), &_Py_ID(timeout), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"block", "timeout", NULL}; - static _PyArg_Parser _parser = {"|pO:get", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int block = 1; PyObject *timeout_obj = Py_None; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &block, &timeout_obj)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { goto exit; } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + block = PyObject_IsTrue(args[0]); + if (block < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + timeout_obj = args[1]; +skip_optional_pos: return_value = _queue_SimpleQueue_get_impl(self, cls, block, timeout_obj); exit: @@ -170,7 +261,7 @@ PyDoc_STRVAR(_queue_SimpleQueue_get_nowait__doc__, "raise the Empty exception."); #define _QUEUE_SIMPLEQUEUE_GET_NOWAIT_METHODDEF \ - {"get_nowait", (PyCFunction)(void(*)(void))_queue_SimpleQueue_get_nowait, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _queue_SimpleQueue_get_nowait__doc__}, + {"get_nowait", _PyCFunction_CAST(_queue_SimpleQueue_get_nowait), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _queue_SimpleQueue_get_nowait__doc__}, static PyObject * _queue_SimpleQueue_get_nowait_impl(simplequeueobject *self, @@ -179,18 +270,11 @@ _queue_SimpleQueue_get_nowait_impl(simplequeueobject *self, static PyObject * _queue_SimpleQueue_get_nowait(simplequeueobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":get_nowait", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "get_nowait() takes no arguments"); + return NULL; } - return_value = _queue_SimpleQueue_get_nowait_impl(self, cls); - -exit: - return return_value; + return _queue_SimpleQueue_get_nowait_impl(self, cls); } PyDoc_STRVAR(_queue_SimpleQueue_empty__doc__, @@ -248,4 +332,4 @@ _queue_SimpleQueue_qsize(simplequeueobject *self, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=acfaf0191d8935db input=a9049054013a1b77]*/ +/*[clinic end generated code: output=628e992d38f50aac input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_randommodule.c.h b/Modules/clinic/_randommodule.c.h index b3cd435b6f2..ec8531ce006 100644 --- a/Modules/clinic/_randommodule.c.h +++ b/Modules/clinic/_randommodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_random_Random_random__doc__, "random($self, /)\n" "--\n" @@ -30,7 +36,7 @@ PyDoc_STRVAR(_random_Random_seed__doc__, "of the current time and the process identifier."); #define _RANDOM_RANDOM_SEED_METHODDEF \ - {"seed", (PyCFunction)(void(*)(void))_random_Random_seed, METH_FASTCALL, _random_Random_seed__doc__}, + {"seed", _PyCFunction_CAST(_random_Random_seed), METH_FASTCALL, _random_Random_seed__doc__}, static PyObject * _random_Random_seed_impl(RandomObject *self, PyObject *n); @@ -109,4 +115,4 @@ _random_Random_getrandbits(RandomObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=cc8a23b2757dc6ba input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bc17406a886824fc input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 67eaf3f9609..2d7c98c4f01 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_ssl__SSLSocket_do_handshake__doc__, "do_handshake($self, /)\n" "--\n" @@ -60,7 +66,7 @@ PyDoc_STRVAR(_ssl__SSLSocket_getpeercert__doc__, "return the certificate even if it wasn\'t validated."); #define _SSL__SSLSOCKET_GETPEERCERT_METHODDEF \ - {"getpeercert", (PyCFunction)(void(*)(void))_ssl__SSLSocket_getpeercert, METH_FASTCALL, _ssl__SSLSocket_getpeercert__doc__}, + {"getpeercert", _PyCFunction_CAST(_ssl__SSLSocket_getpeercert), METH_FASTCALL, _ssl__SSLSocket_getpeercert__doc__}, static PyObject * _ssl__SSLSocket_getpeercert_impl(PySSLSocket *self, int binary_mode); @@ -338,7 +344,7 @@ PyDoc_STRVAR(_ssl__SSLSocket_get_channel_binding__doc__, "Only \'tls-unique\' channel binding data from RFC 5929 is supported."); #define _SSL__SSLSOCKET_GET_CHANNEL_BINDING_METHODDEF \ - {"get_channel_binding", (PyCFunction)(void(*)(void))_ssl__SSLSocket_get_channel_binding, METH_FASTCALL|METH_KEYWORDS, _ssl__SSLSocket_get_channel_binding__doc__}, + {"get_channel_binding", _PyCFunction_CAST(_ssl__SSLSocket_get_channel_binding), METH_FASTCALL|METH_KEYWORDS, _ssl__SSLSocket_get_channel_binding__doc__}, static PyObject * _ssl__SSLSocket_get_channel_binding_impl(PySSLSocket *self, @@ -348,8 +354,31 @@ static PyObject * _ssl__SSLSocket_get_channel_binding(PySSLSocket *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(cb_type), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"cb_type", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get_channel_binding", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get_channel_binding", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *cb_type = "tls-unique"; @@ -521,7 +550,7 @@ PyDoc_STRVAR(_ssl__SSLContext_load_cert_chain__doc__, "\n"); #define _SSL__SSLCONTEXT_LOAD_CERT_CHAIN_METHODDEF \ - {"load_cert_chain", (PyCFunction)(void(*)(void))_ssl__SSLContext_load_cert_chain, METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext_load_cert_chain__doc__}, + {"load_cert_chain", _PyCFunction_CAST(_ssl__SSLContext_load_cert_chain), METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext_load_cert_chain__doc__}, static PyObject * _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, @@ -531,8 +560,31 @@ static PyObject * _ssl__SSLContext_load_cert_chain(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(certfile), &_Py_ID(keyfile), &_Py_ID(password), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"certfile", "keyfile", "password", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "load_cert_chain", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "load_cert_chain", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *certfile; @@ -567,7 +619,7 @@ PyDoc_STRVAR(_ssl__SSLContext_load_verify_locations__doc__, "\n"); #define _SSL__SSLCONTEXT_LOAD_VERIFY_LOCATIONS_METHODDEF \ - {"load_verify_locations", (PyCFunction)(void(*)(void))_ssl__SSLContext_load_verify_locations, METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext_load_verify_locations__doc__}, + {"load_verify_locations", _PyCFunction_CAST(_ssl__SSLContext_load_verify_locations), METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext_load_verify_locations__doc__}, static PyObject * _ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, @@ -579,8 +631,31 @@ static PyObject * _ssl__SSLContext_load_verify_locations(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(cafile), &_Py_ID(capath), &_Py_ID(cadata), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"cafile", "capath", "cadata", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "load_verify_locations", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "load_verify_locations", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *cafile = Py_None; @@ -629,7 +704,7 @@ PyDoc_STRVAR(_ssl__SSLContext__wrap_socket__doc__, "\n"); #define _SSL__SSLCONTEXT__WRAP_SOCKET_METHODDEF \ - {"_wrap_socket", (PyCFunction)(void(*)(void))_ssl__SSLContext__wrap_socket, METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext__wrap_socket__doc__}, + {"_wrap_socket", _PyCFunction_CAST(_ssl__SSLContext__wrap_socket), METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext__wrap_socket__doc__}, static PyObject * _ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock, @@ -640,8 +715,31 @@ static PyObject * _ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sock), &_Py_ID(server_side), &_Py_ID(server_hostname), &_Py_ID(owner), &_Py_ID(session), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sock", "server_side", "server_hostname", "owner", "session", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_wrap_socket", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_wrap_socket", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *sock; @@ -659,8 +757,8 @@ _ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *const *args, Py_ssiz goto exit; } sock = args[0]; - server_side = _PyLong_AsInt(args[1]); - if (server_side == -1 && PyErr_Occurred()) { + server_side = PyObject_IsTrue(args[1]); + if (server_side < 0) { goto exit; } if (!noptargs) { @@ -697,7 +795,7 @@ PyDoc_STRVAR(_ssl__SSLContext__wrap_bio__doc__, "\n"); #define _SSL__SSLCONTEXT__WRAP_BIO_METHODDEF \ - {"_wrap_bio", (PyCFunction)(void(*)(void))_ssl__SSLContext__wrap_bio, METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext__wrap_bio__doc__}, + {"_wrap_bio", _PyCFunction_CAST(_ssl__SSLContext__wrap_bio), METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext__wrap_bio__doc__}, static PyObject * _ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming, @@ -709,8 +807,31 @@ static PyObject * _ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 6 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(incoming), &_Py_ID(outgoing), &_Py_ID(server_side), &_Py_ID(server_hostname), &_Py_ID(owner), &_Py_ID(session), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"incoming", "outgoing", "server_side", "server_hostname", "owner", "session", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_wrap_bio", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_wrap_bio", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; PySSLMemoryBIO *incoming; @@ -734,8 +855,8 @@ _ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t goto exit; } outgoing = (PySSLMemoryBIO *)args[1]; - server_side = _PyLong_AsInt(args[2]); - if (server_side == -1 && PyErr_Occurred()) { + server_side = PyObject_IsTrue(args[2]); + if (server_side < 0) { goto exit; } if (!noptargs) { @@ -844,7 +965,7 @@ PyDoc_STRVAR(_ssl__SSLContext_get_ca_certs__doc__, "been used at least once."); #define _SSL__SSLCONTEXT_GET_CA_CERTS_METHODDEF \ - {"get_ca_certs", (PyCFunction)(void(*)(void))_ssl__SSLContext_get_ca_certs, METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext_get_ca_certs__doc__}, + {"get_ca_certs", _PyCFunction_CAST(_ssl__SSLContext_get_ca_certs), METH_FASTCALL|METH_KEYWORDS, _ssl__SSLContext_get_ca_certs__doc__}, static PyObject * _ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form); @@ -853,8 +974,31 @@ static PyObject * _ssl__SSLContext_get_ca_certs(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(binary_form), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"binary_form", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get_ca_certs", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get_ca_certs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int binary_form = 0; @@ -913,7 +1057,7 @@ PyDoc_STRVAR(_ssl_MemoryBIO_read__doc__, "distinguish between the two."); #define _SSL_MEMORYBIO_READ_METHODDEF \ - {"read", (PyCFunction)(void(*)(void))_ssl_MemoryBIO_read, METH_FASTCALL, _ssl_MemoryBIO_read__doc__}, + {"read", _PyCFunction_CAST(_ssl_MemoryBIO_read), METH_FASTCALL, _ssl_MemoryBIO_read__doc__}, static PyObject * _ssl_MemoryBIO_read_impl(PySSLMemoryBIO *self, int len); @@ -1009,7 +1153,7 @@ PyDoc_STRVAR(_ssl_RAND_add__doc__, "string. See RFC 4086."); #define _SSL_RAND_ADD_METHODDEF \ - {"RAND_add", (PyCFunction)(void(*)(void))_ssl_RAND_add, METH_FASTCALL, _ssl_RAND_add__doc__}, + {"RAND_add", _PyCFunction_CAST(_ssl_RAND_add), METH_FASTCALL, _ssl_RAND_add__doc__}, static PyObject * _ssl_RAND_add_impl(PyObject *module, Py_buffer *view, double entropy); @@ -1090,37 +1234,6 @@ exit: return return_value; } -PyDoc_STRVAR(_ssl_RAND_pseudo_bytes__doc__, -"RAND_pseudo_bytes($module, n, /)\n" -"--\n" -"\n" -"Generate n pseudo-random bytes.\n" -"\n" -"Return a pair (bytes, is_cryptographic). is_cryptographic is True\n" -"if the bytes generated are cryptographically strong."); - -#define _SSL_RAND_PSEUDO_BYTES_METHODDEF \ - {"RAND_pseudo_bytes", (PyCFunction)_ssl_RAND_pseudo_bytes, METH_O, _ssl_RAND_pseudo_bytes__doc__}, - -static PyObject * -_ssl_RAND_pseudo_bytes_impl(PyObject *module, int n); - -static PyObject * -_ssl_RAND_pseudo_bytes(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int n; - - n = _PyLong_AsInt(arg); - if (n == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = _ssl_RAND_pseudo_bytes_impl(module, n); - -exit: - return return_value; -} - PyDoc_STRVAR(_ssl_RAND_status__doc__, "RAND_status($module, /)\n" "--\n" @@ -1172,7 +1285,7 @@ PyDoc_STRVAR(_ssl_txt2obj__doc__, "long name are also matched."); #define _SSL_TXT2OBJ_METHODDEF \ - {"txt2obj", (PyCFunction)(void(*)(void))_ssl_txt2obj, METH_FASTCALL|METH_KEYWORDS, _ssl_txt2obj__doc__}, + {"txt2obj", _PyCFunction_CAST(_ssl_txt2obj), METH_FASTCALL|METH_KEYWORDS, _ssl_txt2obj__doc__}, static PyObject * _ssl_txt2obj_impl(PyObject *module, const char *txt, int name); @@ -1181,8 +1294,31 @@ static PyObject * _ssl_txt2obj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(txt), &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"txt", "name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "txt2obj", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "txt2obj", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; const char *txt; @@ -1262,7 +1398,7 @@ PyDoc_STRVAR(_ssl_enum_certificates__doc__, "a set of OIDs or the boolean True."); #define _SSL_ENUM_CERTIFICATES_METHODDEF \ - {"enum_certificates", (PyCFunction)(void(*)(void))_ssl_enum_certificates, METH_FASTCALL|METH_KEYWORDS, _ssl_enum_certificates__doc__}, + {"enum_certificates", _PyCFunction_CAST(_ssl_enum_certificates), METH_FASTCALL|METH_KEYWORDS, _ssl_enum_certificates__doc__}, static PyObject * _ssl_enum_certificates_impl(PyObject *module, const char *store_name); @@ -1271,8 +1407,31 @@ static PyObject * _ssl_enum_certificates(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(store_name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"store_name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "enum_certificates", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "enum_certificates", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; const char *store_name; @@ -1315,7 +1474,7 @@ PyDoc_STRVAR(_ssl_enum_crls__doc__, "X509_ASN_ENCODING or PKCS_7_ASN_ENCODING."); #define _SSL_ENUM_CRLS_METHODDEF \ - {"enum_crls", (PyCFunction)(void(*)(void))_ssl_enum_crls, METH_FASTCALL|METH_KEYWORDS, _ssl_enum_crls__doc__}, + {"enum_crls", _PyCFunction_CAST(_ssl_enum_crls), METH_FASTCALL|METH_KEYWORDS, _ssl_enum_crls__doc__}, static PyObject * _ssl_enum_crls_impl(PyObject *module, const char *store_name); @@ -1324,8 +1483,31 @@ static PyObject * _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(store_name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"store_name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "enum_crls", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "enum_crls", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; const char *store_name; @@ -1361,4 +1543,4 @@ exit: #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=cd2a53c26eda295e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a3d97a19163bb044 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_statisticsmodule.c.h b/Modules/clinic/_statisticsmodule.c.h index 5ff01efddcd..4dedadd2939 100644 --- a/Modules/clinic/_statisticsmodule.c.h +++ b/Modules/clinic/_statisticsmodule.c.h @@ -2,13 +2,19 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_statistics__normal_dist_inv_cdf__doc__, "_normal_dist_inv_cdf($module, p, mu, sigma, /)\n" "--\n" "\n"); #define _STATISTICS__NORMAL_DIST_INV_CDF_METHODDEF \ - {"_normal_dist_inv_cdf", (PyCFunction)(void(*)(void))_statistics__normal_dist_inv_cdf, METH_FASTCALL, _statistics__normal_dist_inv_cdf__doc__}, + {"_normal_dist_inv_cdf", _PyCFunction_CAST(_statistics__normal_dist_inv_cdf), METH_FASTCALL, _statistics__normal_dist_inv_cdf__doc__}, static double _statistics__normal_dist_inv_cdf_impl(PyObject *module, double p, double mu, @@ -65,4 +71,4 @@ _statistics__normal_dist_inv_cdf(PyObject *module, PyObject *const *args, Py_ssi exit: return return_value; } -/*[clinic end generated code: output=c5826928a238326c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6899dc752cc6b457 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_struct.c.h b/Modules/clinic/_struct.c.h index b0c1eb4587a..c3cf179ed4c 100644 --- a/Modules/clinic/_struct.c.h +++ b/Modules/clinic/_struct.c.h @@ -2,7 +2,13 @@ preserve [clinic start generated code]*/ -PyDoc_STRVAR(Struct___init____doc__, +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(Struct__doc__, "Struct(format)\n" "--\n" "\n" @@ -13,15 +19,38 @@ PyDoc_STRVAR(Struct___init____doc__, "\n" "See help(struct) for more on format strings."); -static int -Struct___init___impl(PyStructObject *self, PyObject *format); +static PyObject * +Struct_impl(PyTypeObject *type, PyObject *format); -static int -Struct___init__(PyObject *self, PyObject *args, PyObject *kwargs) +static PyObject * +Struct(PyTypeObject *type, PyObject *args, PyObject *kwargs) { - int return_value = -1; + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(format), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"format", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Struct", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Struct", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -32,7 +61,7 @@ Struct___init__(PyObject *self, PyObject *args, PyObject *kwargs) goto exit; } format = fastargs[0]; - return_value = Struct___init___impl((PyStructObject *)self, format); + return_value = Struct_impl(type, format); exit: return return_value; @@ -93,7 +122,7 @@ PyDoc_STRVAR(Struct_unpack_from__doc__, "See help(struct) for more on format strings."); #define STRUCT_UNPACK_FROM_METHODDEF \ - {"unpack_from", (PyCFunction)(void(*)(void))Struct_unpack_from, METH_FASTCALL|METH_KEYWORDS, Struct_unpack_from__doc__}, + {"unpack_from", _PyCFunction_CAST(Struct_unpack_from), METH_FASTCALL|METH_KEYWORDS, Struct_unpack_from__doc__}, static PyObject * Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer, @@ -103,8 +132,31 @@ static PyObject * Struct_unpack_from(PyStructObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(buffer), &_Py_ID(offset), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"buffer", "offset", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "unpack_from", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unpack_from", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer buffer = {NULL, NULL}; @@ -226,7 +278,7 @@ PyDoc_STRVAR(unpack__doc__, "See help(struct) for more on format strings."); #define UNPACK_METHODDEF \ - {"unpack", (PyCFunction)(void(*)(void))unpack, METH_FASTCALL, unpack__doc__}, + {"unpack", _PyCFunction_CAST(unpack), METH_FASTCALL, unpack__doc__}, static PyObject * unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer); @@ -275,7 +327,7 @@ PyDoc_STRVAR(unpack_from__doc__, "See help(struct) for more on format strings."); #define UNPACK_FROM_METHODDEF \ - {"unpack_from", (PyCFunction)(void(*)(void))unpack_from, METH_FASTCALL|METH_KEYWORDS, unpack_from__doc__}, + {"unpack_from", _PyCFunction_CAST(unpack_from), METH_FASTCALL|METH_KEYWORDS, unpack_from__doc__}, static PyObject * unpack_from_impl(PyObject *module, PyStructObject *s_object, @@ -285,8 +337,31 @@ static PyObject * unpack_from(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(buffer), &_Py_ID(offset), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "buffer", "offset", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "unpack_from", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unpack_from", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyStructObject *s_object = NULL; @@ -348,7 +423,7 @@ PyDoc_STRVAR(iter_unpack__doc__, "Requires that the bytes length be a multiple of the format struct size."); #define ITER_UNPACK_METHODDEF \ - {"iter_unpack", (PyCFunction)(void(*)(void))iter_unpack, METH_FASTCALL, iter_unpack__doc__}, + {"iter_unpack", _PyCFunction_CAST(iter_unpack), METH_FASTCALL, iter_unpack__doc__}, static PyObject * iter_unpack_impl(PyObject *module, PyStructObject *s_object, @@ -376,4 +451,4 @@ exit: return return_value; } -/*[clinic end generated code: output=a3d3cd900091cb1c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f3d6e06f80368998 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testclinic.c.h b/Modules/clinic/_testclinic.c.h new file mode 100644 index 00000000000..831f58ca650 --- /dev/null +++ b/Modules/clinic/_testclinic.c.h @@ -0,0 +1,2820 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(test_empty_function__doc__, +"test_empty_function($module, /)\n" +"--\n" +"\n"); + +#define TEST_EMPTY_FUNCTION_METHODDEF \ + {"test_empty_function", (PyCFunction)test_empty_function, METH_NOARGS, test_empty_function__doc__}, + +static PyObject * +test_empty_function_impl(PyObject *module); + +static PyObject * +test_empty_function(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return test_empty_function_impl(module); +} + +PyDoc_STRVAR(objects_converter__doc__, +"objects_converter($module, a, b=, /)\n" +"--\n" +"\n"); + +#define OBJECTS_CONVERTER_METHODDEF \ + {"objects_converter", _PyCFunction_CAST(objects_converter), METH_FASTCALL, objects_converter__doc__}, + +static PyObject * +objects_converter_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +objects_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b = NULL; + + if (!_PyArg_CheckPositional("objects_converter", nargs, 1, 2)) { + goto exit; + } + a = args[0]; + if (nargs < 2) { + goto skip_optional; + } + b = args[1]; +skip_optional: + return_value = objects_converter_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytes_object_converter__doc__, +"bytes_object_converter($module, a, /)\n" +"--\n" +"\n"); + +#define BYTES_OBJECT_CONVERTER_METHODDEF \ + {"bytes_object_converter", (PyCFunction)bytes_object_converter, METH_O, bytes_object_converter__doc__}, + +static PyObject * +bytes_object_converter_impl(PyObject *module, PyBytesObject *a); + +static PyObject * +bytes_object_converter(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyBytesObject *a; + + if (!PyBytes_Check(arg)) { + _PyArg_BadArgument("bytes_object_converter", "argument", "bytes", arg); + goto exit; + } + a = (PyBytesObject *)arg; + return_value = bytes_object_converter_impl(module, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(byte_array_object_converter__doc__, +"byte_array_object_converter($module, a, /)\n" +"--\n" +"\n"); + +#define BYTE_ARRAY_OBJECT_CONVERTER_METHODDEF \ + {"byte_array_object_converter", (PyCFunction)byte_array_object_converter, METH_O, byte_array_object_converter__doc__}, + +static PyObject * +byte_array_object_converter_impl(PyObject *module, PyByteArrayObject *a); + +static PyObject * +byte_array_object_converter(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyByteArrayObject *a; + + if (!PyByteArray_Check(arg)) { + _PyArg_BadArgument("byte_array_object_converter", "argument", "bytearray", arg); + goto exit; + } + a = (PyByteArrayObject *)arg; + return_value = byte_array_object_converter_impl(module, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicode_converter__doc__, +"unicode_converter($module, a, /)\n" +"--\n" +"\n"); + +#define UNICODE_CONVERTER_METHODDEF \ + {"unicode_converter", (PyCFunction)unicode_converter, METH_O, unicode_converter__doc__}, + +static PyObject * +unicode_converter_impl(PyObject *module, PyObject *a); + +static PyObject * +unicode_converter(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *a; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("unicode_converter", "argument", "str", arg); + goto exit; + } + if (PyUnicode_READY(arg) == -1) { + goto exit; + } + a = arg; + return_value = unicode_converter_impl(module, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(bool_converter__doc__, +"bool_converter($module, a=True, b=True, c=True, /)\n" +"--\n" +"\n"); + +#define BOOL_CONVERTER_METHODDEF \ + {"bool_converter", _PyCFunction_CAST(bool_converter), METH_FASTCALL, bool_converter__doc__}, + +static PyObject * +bool_converter_impl(PyObject *module, int a, int b, int c); + +static PyObject * +bool_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int a = 1; + int b = 1; + int c = 1; + + if (!_PyArg_CheckPositional("bool_converter", nargs, 0, 3)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + a = PyObject_IsTrue(args[0]); + if (a < 0) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + b = PyObject_IsTrue(args[1]); + if (b < 0) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + c = _PyLong_AsInt(args[2]); + if (c == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = bool_converter_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(char_converter__doc__, +"char_converter($module, a=b\'A\', b=b\'\\x07\', c=b\'\\x08\', d=b\'\\t\', e=b\'\\n\',\n" +" f=b\'\\x0b\', g=b\'\\x0c\', h=b\'\\r\', i=b\'\"\', j=b\"\'\", k=b\'?\',\n" +" l=b\'\\\\\', m=b\'\\x00\', n=b\'\\xff\', /)\n" +"--\n" +"\n"); + +#define CHAR_CONVERTER_METHODDEF \ + {"char_converter", _PyCFunction_CAST(char_converter), METH_FASTCALL, char_converter__doc__}, + +static PyObject * +char_converter_impl(PyObject *module, char a, char b, char c, char d, char e, + char f, char g, char h, char i, char j, char k, char l, + char m, char n); + +static PyObject * +char_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + char a = 'A'; + char b = '\x07'; + char c = '\x08'; + char d = '\t'; + char e = '\n'; + char f = '\x0b'; + char g = '\x0c'; + char h = '\r'; + char i = '"'; + char j = '\''; + char k = '?'; + char l = '\\'; + char m = '\x00'; + char n = '\xff'; + + if (!_PyArg_CheckPositional("char_converter", nargs, 0, 14)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyBytes_Check(args[0]) && PyBytes_GET_SIZE(args[0]) == 1) { + a = PyBytes_AS_STRING(args[0])[0]; + } + else if (PyByteArray_Check(args[0]) && PyByteArray_GET_SIZE(args[0]) == 1) { + a = PyByteArray_AS_STRING(args[0])[0]; + } + else { + _PyArg_BadArgument("char_converter", "argument 1", "a byte string of length 1", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (PyBytes_Check(args[1]) && PyBytes_GET_SIZE(args[1]) == 1) { + b = PyBytes_AS_STRING(args[1])[0]; + } + else if (PyByteArray_Check(args[1]) && PyByteArray_GET_SIZE(args[1]) == 1) { + b = PyByteArray_AS_STRING(args[1])[0]; + } + else { + _PyArg_BadArgument("char_converter", "argument 2", "a byte string of length 1", args[1]); + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (PyBytes_Check(args[2]) && PyBytes_GET_SIZE(args[2]) == 1) { + c = PyBytes_AS_STRING(args[2])[0]; + } + else if (PyByteArray_Check(args[2]) && PyByteArray_GET_SIZE(args[2]) == 1) { + c = PyByteArray_AS_STRING(args[2])[0]; + } + else { + _PyArg_BadArgument("char_converter", "argument 3", "a byte string of length 1", args[2]); + goto exit; + } + if (nargs < 4) { + goto skip_optional; + } + if (PyBytes_Check(args[3]) && PyBytes_GET_SIZE(args[3]) == 1) { + d = PyBytes_AS_STRING(args[3])[0]; + } + else if (PyByteArray_Check(args[3]) && PyByteArray_GET_SIZE(args[3]) == 1) { + d = PyByteArray_AS_STRING(args[3])[0]; + } + else { + _PyArg_BadArgument("char_converter", "argument 4", "a byte string of length 1", args[3]); + goto exit; + } + if (nargs < 5) { + goto skip_optional; + } + if (PyBytes_Check(args[4]) && PyBytes_GET_SIZE(args[4]) == 1) { + e = PyBytes_AS_STRING(args[4])[0]; + } + else if (PyByteArray_Check(args[4]) && PyByteArray_GET_SIZE(args[4]) == 1) { + e = PyByteArray_AS_STRING(args[4])[0]; + } + else { + _PyArg_BadArgument("char_converter", "argument 5", "a byte string of length 1", args[4]); + goto exit; + } + if (nargs < 6) { + goto skip_optional; + } + if (PyBytes_Check(args[5]) && PyBytes_GET_SIZE(args[5]) == 1) { + f = PyBytes_AS_STRING(args[5])[0]; + } + else if (PyByteArray_Check(args[5]) && PyByteArray_GET_SIZE(args[5]) == 1) { + f = PyByteArray_AS_STRING(args[5])[0]; + } + else { + _PyArg_BadArgument("char_converter", "argument 6", "a byte string of length 1", args[5]); + goto exit; + } + if (nargs < 7) { + goto skip_optional; + } + if (PyBytes_Check(args[6]) && PyBytes_GET_SIZE(args[6]) == 1) { + g = PyBytes_AS_STRING(args[6])[0]; + } + else if (PyByteArray_Check(args[6]) && PyByteArray_GET_SIZE(args[6]) == 1) { + g = PyByteArray_AS_STRING(args[6])[0]; + } + else { + _PyArg_BadArgument("char_converter", "argument 7", "a byte string of length 1", args[6]); + goto exit; + } + if (nargs < 8) { + goto skip_optional; + } + if (PyBytes_Check(args[7]) && PyBytes_GET_SIZE(args[7]) == 1) { + h = PyBytes_AS_STRING(args[7])[0]; + } + else if (PyByteArray_Check(args[7]) && PyByteArray_GET_SIZE(args[7]) == 1) { + h = PyByteArray_AS_STRING(args[7])[0]; + } + else { + _PyArg_BadArgument("char_converter", "argument 8", "a byte string of length 1", args[7]); + goto exit; + } + if (nargs < 9) { + goto skip_optional; + } + if (PyBytes_Check(args[8]) && PyBytes_GET_SIZE(args[8]) == 1) { + i = PyBytes_AS_STRING(args[8])[0]; + } + else if (PyByteArray_Check(args[8]) && PyByteArray_GET_SIZE(args[8]) == 1) { + i = PyByteArray_AS_STRING(args[8])[0]; + } + else { + _PyArg_BadArgument("char_converter", "argument 9", "a byte string of length 1", args[8]); + goto exit; + } + if (nargs < 10) { + goto skip_optional; + } + if (PyBytes_Check(args[9]) && PyBytes_GET_SIZE(args[9]) == 1) { + j = PyBytes_AS_STRING(args[9])[0]; + } + else if (PyByteArray_Check(args[9]) && PyByteArray_GET_SIZE(args[9]) == 1) { + j = PyByteArray_AS_STRING(args[9])[0]; + } + else { + _PyArg_BadArgument("char_converter", "argument 10", "a byte string of length 1", args[9]); + goto exit; + } + if (nargs < 11) { + goto skip_optional; + } + if (PyBytes_Check(args[10]) && PyBytes_GET_SIZE(args[10]) == 1) { + k = PyBytes_AS_STRING(args[10])[0]; + } + else if (PyByteArray_Check(args[10]) && PyByteArray_GET_SIZE(args[10]) == 1) { + k = PyByteArray_AS_STRING(args[10])[0]; + } + else { + _PyArg_BadArgument("char_converter", "argument 11", "a byte string of length 1", args[10]); + goto exit; + } + if (nargs < 12) { + goto skip_optional; + } + if (PyBytes_Check(args[11]) && PyBytes_GET_SIZE(args[11]) == 1) { + l = PyBytes_AS_STRING(args[11])[0]; + } + else if (PyByteArray_Check(args[11]) && PyByteArray_GET_SIZE(args[11]) == 1) { + l = PyByteArray_AS_STRING(args[11])[0]; + } + else { + _PyArg_BadArgument("char_converter", "argument 12", "a byte string of length 1", args[11]); + goto exit; + } + if (nargs < 13) { + goto skip_optional; + } + if (PyBytes_Check(args[12]) && PyBytes_GET_SIZE(args[12]) == 1) { + m = PyBytes_AS_STRING(args[12])[0]; + } + else if (PyByteArray_Check(args[12]) && PyByteArray_GET_SIZE(args[12]) == 1) { + m = PyByteArray_AS_STRING(args[12])[0]; + } + else { + _PyArg_BadArgument("char_converter", "argument 13", "a byte string of length 1", args[12]); + goto exit; + } + if (nargs < 14) { + goto skip_optional; + } + if (PyBytes_Check(args[13]) && PyBytes_GET_SIZE(args[13]) == 1) { + n = PyBytes_AS_STRING(args[13])[0]; + } + else if (PyByteArray_Check(args[13]) && PyByteArray_GET_SIZE(args[13]) == 1) { + n = PyByteArray_AS_STRING(args[13])[0]; + } + else { + _PyArg_BadArgument("char_converter", "argument 14", "a byte string of length 1", args[13]); + goto exit; + } +skip_optional: + return_value = char_converter_impl(module, a, b, c, d, e, f, g, h, i, j, k, l, m, n); + +exit: + return return_value; +} + +PyDoc_STRVAR(unsigned_char_converter__doc__, +"unsigned_char_converter($module, a=12, b=34, c=56, /)\n" +"--\n" +"\n"); + +#define UNSIGNED_CHAR_CONVERTER_METHODDEF \ + {"unsigned_char_converter", _PyCFunction_CAST(unsigned_char_converter), METH_FASTCALL, unsigned_char_converter__doc__}, + +static PyObject * +unsigned_char_converter_impl(PyObject *module, unsigned char a, + unsigned char b, unsigned char c); + +static PyObject * +unsigned_char_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + unsigned char a = 12; + unsigned char b = 34; + unsigned char c = 56; + + if (!_PyArg_CheckPositional("unsigned_char_converter", nargs, 0, 3)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + { + long ival = PyLong_AsLong(args[0]); + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + else if (ival < 0) { + PyErr_SetString(PyExc_OverflowError, + "unsigned byte integer is less than minimum"); + goto exit; + } + else if (ival > UCHAR_MAX) { + PyErr_SetString(PyExc_OverflowError, + "unsigned byte integer is greater than maximum"); + goto exit; + } + else { + a = (unsigned char) ival; + } + } + if (nargs < 2) { + goto skip_optional; + } + { + long ival = PyLong_AsLong(args[1]); + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + else if (ival < 0) { + PyErr_SetString(PyExc_OverflowError, + "unsigned byte integer is less than minimum"); + goto exit; + } + else if (ival > UCHAR_MAX) { + PyErr_SetString(PyExc_OverflowError, + "unsigned byte integer is greater than maximum"); + goto exit; + } + else { + b = (unsigned char) ival; + } + } + if (nargs < 3) { + goto skip_optional; + } + { + unsigned long ival = PyLong_AsUnsignedLongMask(args[2]); + if (ival == (unsigned long)-1 && PyErr_Occurred()) { + goto exit; + } + else { + c = (unsigned char) ival; + } + } +skip_optional: + return_value = unsigned_char_converter_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(short_converter__doc__, +"short_converter($module, a=12, /)\n" +"--\n" +"\n"); + +#define SHORT_CONVERTER_METHODDEF \ + {"short_converter", _PyCFunction_CAST(short_converter), METH_FASTCALL, short_converter__doc__}, + +static PyObject * +short_converter_impl(PyObject *module, short a); + +static PyObject * +short_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + short a = 12; + + if (!_PyArg_CheckPositional("short_converter", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + { + long ival = PyLong_AsLong(args[0]); + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + else if (ival < SHRT_MIN) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is less than minimum"); + goto exit; + } + else if (ival > SHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "signed short integer is greater than maximum"); + goto exit; + } + else { + a = (short) ival; + } + } +skip_optional: + return_value = short_converter_impl(module, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(unsigned_short_converter__doc__, +"unsigned_short_converter($module, a=12, b=34, c=56, /)\n" +"--\n" +"\n"); + +#define UNSIGNED_SHORT_CONVERTER_METHODDEF \ + {"unsigned_short_converter", _PyCFunction_CAST(unsigned_short_converter), METH_FASTCALL, unsigned_short_converter__doc__}, + +static PyObject * +unsigned_short_converter_impl(PyObject *module, unsigned short a, + unsigned short b, unsigned short c); + +static PyObject * +unsigned_short_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + unsigned short a = 12; + unsigned short b = 34; + unsigned short c = 56; + + if (!_PyArg_CheckPositional("unsigned_short_converter", nargs, 0, 3)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_PyLong_UnsignedShort_Converter(args[0], &a)) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (!_PyLong_UnsignedShort_Converter(args[1], &b)) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + c = (unsigned short)PyLong_AsUnsignedLongMask(args[2]); + if (c == (unsigned short)-1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = unsigned_short_converter_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(int_converter__doc__, +"int_converter($module, a=12, b=34, c=45, /)\n" +"--\n" +"\n"); + +#define INT_CONVERTER_METHODDEF \ + {"int_converter", _PyCFunction_CAST(int_converter), METH_FASTCALL, int_converter__doc__}, + +static PyObject * +int_converter_impl(PyObject *module, int a, int b, int c); + +static PyObject * +int_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int a = 12; + int b = 34; + int c = 45; + + if (!_PyArg_CheckPositional("int_converter", nargs, 0, 3)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + a = _PyLong_AsInt(args[0]); + if (a == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + b = _PyLong_AsInt(args[1]); + if (b == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (!PyUnicode_Check(args[2])) { + _PyArg_BadArgument("int_converter", "argument 3", "a unicode character", args[2]); + goto exit; + } + if (PyUnicode_READY(args[2])) { + goto exit; + } + if (PyUnicode_GET_LENGTH(args[2]) != 1) { + _PyArg_BadArgument("int_converter", "argument 3", "a unicode character", args[2]); + goto exit; + } + c = PyUnicode_READ_CHAR(args[2], 0); +skip_optional: + return_value = int_converter_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(unsigned_int_converter__doc__, +"unsigned_int_converter($module, a=12, b=34, c=56, /)\n" +"--\n" +"\n"); + +#define UNSIGNED_INT_CONVERTER_METHODDEF \ + {"unsigned_int_converter", _PyCFunction_CAST(unsigned_int_converter), METH_FASTCALL, unsigned_int_converter__doc__}, + +static PyObject * +unsigned_int_converter_impl(PyObject *module, unsigned int a, unsigned int b, + unsigned int c); + +static PyObject * +unsigned_int_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + unsigned int a = 12; + unsigned int b = 34; + unsigned int c = 56; + + if (!_PyArg_CheckPositional("unsigned_int_converter", nargs, 0, 3)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_PyLong_UnsignedInt_Converter(args[0], &a)) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (!_PyLong_UnsignedInt_Converter(args[1], &b)) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + c = (unsigned int)PyLong_AsUnsignedLongMask(args[2]); + if (c == (unsigned int)-1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = unsigned_int_converter_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(long_converter__doc__, +"long_converter($module, a=12, /)\n" +"--\n" +"\n"); + +#define LONG_CONVERTER_METHODDEF \ + {"long_converter", _PyCFunction_CAST(long_converter), METH_FASTCALL, long_converter__doc__}, + +static PyObject * +long_converter_impl(PyObject *module, long a); + +static PyObject * +long_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + long a = 12; + + if (!_PyArg_CheckPositional("long_converter", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + a = PyLong_AsLong(args[0]); + if (a == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = long_converter_impl(module, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(unsigned_long_converter__doc__, +"unsigned_long_converter($module, a=12, b=34, c=56, /)\n" +"--\n" +"\n"); + +#define UNSIGNED_LONG_CONVERTER_METHODDEF \ + {"unsigned_long_converter", _PyCFunction_CAST(unsigned_long_converter), METH_FASTCALL, unsigned_long_converter__doc__}, + +static PyObject * +unsigned_long_converter_impl(PyObject *module, unsigned long a, + unsigned long b, unsigned long c); + +static PyObject * +unsigned_long_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + unsigned long a = 12; + unsigned long b = 34; + unsigned long c = 56; + + if (!_PyArg_CheckPositional("unsigned_long_converter", nargs, 0, 3)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_PyLong_UnsignedLong_Converter(args[0], &a)) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (!_PyLong_UnsignedLong_Converter(args[1], &b)) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (!PyLong_Check(args[2])) { + _PyArg_BadArgument("unsigned_long_converter", "argument 3", "int", args[2]); + goto exit; + } + c = PyLong_AsUnsignedLongMask(args[2]); +skip_optional: + return_value = unsigned_long_converter_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(long_long_converter__doc__, +"long_long_converter($module, a=12, /)\n" +"--\n" +"\n"); + +#define LONG_LONG_CONVERTER_METHODDEF \ + {"long_long_converter", _PyCFunction_CAST(long_long_converter), METH_FASTCALL, long_long_converter__doc__}, + +static PyObject * +long_long_converter_impl(PyObject *module, long long a); + +static PyObject * +long_long_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + long long a = 12; + + if (!_PyArg_CheckPositional("long_long_converter", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + a = PyLong_AsLongLong(args[0]); + if (a == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = long_long_converter_impl(module, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(unsigned_long_long_converter__doc__, +"unsigned_long_long_converter($module, a=12, b=34, c=56, /)\n" +"--\n" +"\n"); + +#define UNSIGNED_LONG_LONG_CONVERTER_METHODDEF \ + {"unsigned_long_long_converter", _PyCFunction_CAST(unsigned_long_long_converter), METH_FASTCALL, unsigned_long_long_converter__doc__}, + +static PyObject * +unsigned_long_long_converter_impl(PyObject *module, unsigned long long a, + unsigned long long b, unsigned long long c); + +static PyObject * +unsigned_long_long_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + unsigned long long a = 12; + unsigned long long b = 34; + unsigned long long c = 56; + + if (!_PyArg_CheckPositional("unsigned_long_long_converter", nargs, 0, 3)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_PyLong_UnsignedLongLong_Converter(args[0], &a)) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (!_PyLong_UnsignedLongLong_Converter(args[1], &b)) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (!PyLong_Check(args[2])) { + _PyArg_BadArgument("unsigned_long_long_converter", "argument 3", "int", args[2]); + goto exit; + } + c = PyLong_AsUnsignedLongLongMask(args[2]); +skip_optional: + return_value = unsigned_long_long_converter_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(py_ssize_t_converter__doc__, +"py_ssize_t_converter($module, a=12, b=34, c=56, /)\n" +"--\n" +"\n"); + +#define PY_SSIZE_T_CONVERTER_METHODDEF \ + {"py_ssize_t_converter", _PyCFunction_CAST(py_ssize_t_converter), METH_FASTCALL, py_ssize_t_converter__doc__}, + +static PyObject * +py_ssize_t_converter_impl(PyObject *module, Py_ssize_t a, Py_ssize_t b, + Py_ssize_t c); + +static PyObject * +py_ssize_t_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t a = 12; + Py_ssize_t b = 34; + Py_ssize_t c = 56; + + if (!_PyArg_CheckPositional("py_ssize_t_converter", nargs, 0, 3)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + a = ival; + } + if (nargs < 2) { + goto skip_optional; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + b = ival; + } + if (nargs < 3) { + goto skip_optional; + } + if (!_Py_convert_optional_to_ssize_t(args[2], &c)) { + goto exit; + } +skip_optional: + return_value = py_ssize_t_converter_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(slice_index_converter__doc__, +"slice_index_converter($module, a=12, b=34, c=56, /)\n" +"--\n" +"\n"); + +#define SLICE_INDEX_CONVERTER_METHODDEF \ + {"slice_index_converter", _PyCFunction_CAST(slice_index_converter), METH_FASTCALL, slice_index_converter__doc__}, + +static PyObject * +slice_index_converter_impl(PyObject *module, Py_ssize_t a, Py_ssize_t b, + Py_ssize_t c); + +static PyObject * +slice_index_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_ssize_t a = 12; + Py_ssize_t b = 34; + Py_ssize_t c = 56; + + if (!_PyArg_CheckPositional("slice_index_converter", nargs, 0, 3)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_PyEval_SliceIndex(args[0], &a)) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + if (!_PyEval_SliceIndexNotNone(args[1], &b)) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (!_PyEval_SliceIndex(args[2], &c)) { + goto exit; + } +skip_optional: + return_value = slice_index_converter_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(size_t_converter__doc__, +"size_t_converter($module, a=12, /)\n" +"--\n" +"\n"); + +#define SIZE_T_CONVERTER_METHODDEF \ + {"size_t_converter", _PyCFunction_CAST(size_t_converter), METH_FASTCALL, size_t_converter__doc__}, + +static PyObject * +size_t_converter_impl(PyObject *module, size_t a); + +static PyObject * +size_t_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + size_t a = 12; + + if (!_PyArg_CheckPositional("size_t_converter", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!_PyLong_Size_t_Converter(args[0], &a)) { + goto exit; + } +skip_optional: + return_value = size_t_converter_impl(module, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(float_converter__doc__, +"float_converter($module, a=12.5, /)\n" +"--\n" +"\n"); + +#define FLOAT_CONVERTER_METHODDEF \ + {"float_converter", _PyCFunction_CAST(float_converter), METH_FASTCALL, float_converter__doc__}, + +static PyObject * +float_converter_impl(PyObject *module, float a); + +static PyObject * +float_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + float a = 12.5; + + if (!_PyArg_CheckPositional("float_converter", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_CheckExact(args[0])) { + a = (float) (PyFloat_AS_DOUBLE(args[0])); + } + else + { + a = (float) PyFloat_AsDouble(args[0]); + if (a == -1.0 && PyErr_Occurred()) { + goto exit; + } + } +skip_optional: + return_value = float_converter_impl(module, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(double_converter__doc__, +"double_converter($module, a=12.5, /)\n" +"--\n" +"\n"); + +#define DOUBLE_CONVERTER_METHODDEF \ + {"double_converter", _PyCFunction_CAST(double_converter), METH_FASTCALL, double_converter__doc__}, + +static PyObject * +double_converter_impl(PyObject *module, double a); + +static PyObject * +double_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + double a = 12.5; + + if (!_PyArg_CheckPositional("double_converter", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (PyFloat_CheckExact(args[0])) { + a = PyFloat_AS_DOUBLE(args[0]); + } + else + { + a = PyFloat_AsDouble(args[0]); + if (a == -1.0 && PyErr_Occurred()) { + goto exit; + } + } +skip_optional: + return_value = double_converter_impl(module, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(py_complex_converter__doc__, +"py_complex_converter($module, a, /)\n" +"--\n" +"\n"); + +#define PY_COMPLEX_CONVERTER_METHODDEF \ + {"py_complex_converter", (PyCFunction)py_complex_converter, METH_O, py_complex_converter__doc__}, + +static PyObject * +py_complex_converter_impl(PyObject *module, Py_complex a); + +static PyObject * +py_complex_converter(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex a; + + a = PyComplex_AsCComplex(arg); + if (PyErr_Occurred()) { + goto exit; + } + return_value = py_complex_converter_impl(module, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(str_converter__doc__, +"str_converter($module, a=\'a\', b=\'b\', c=\'c\', /)\n" +"--\n" +"\n"); + +#define STR_CONVERTER_METHODDEF \ + {"str_converter", _PyCFunction_CAST(str_converter), METH_FASTCALL, str_converter__doc__}, + +static PyObject * +str_converter_impl(PyObject *module, const char *a, const char *b, + const char *c, Py_ssize_t c_length); + +static PyObject * +str_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *a = "a"; + const char *b = "b"; + const char *c = "c"; + Py_ssize_t c_length; + + if (!_PyArg_ParseStack(args, nargs, "|sys#:str_converter", + &a, &b, &c, &c_length)) { + goto exit; + } + return_value = str_converter_impl(module, a, b, c, c_length); + +exit: + return return_value; +} + +PyDoc_STRVAR(str_converter_encoding__doc__, +"str_converter_encoding($module, a, b, c, /)\n" +"--\n" +"\n"); + +#define STR_CONVERTER_ENCODING_METHODDEF \ + {"str_converter_encoding", _PyCFunction_CAST(str_converter_encoding), METH_FASTCALL, str_converter_encoding__doc__}, + +static PyObject * +str_converter_encoding_impl(PyObject *module, char *a, char *b, char *c, + Py_ssize_t c_length); + +static PyObject * +str_converter_encoding(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + char *a = NULL; + char *b = NULL; + char *c = NULL; + Py_ssize_t c_length; + + if (!_PyArg_ParseStack(args, nargs, "esetet#:str_converter_encoding", + "idna", &a, "idna", &b, "idna", &c, &c_length)) { + goto exit; + } + return_value = str_converter_encoding_impl(module, a, b, c, c_length); + /* Post parse cleanup for a */ + PyMem_FREE(a); + /* Post parse cleanup for b */ + PyMem_FREE(b); + /* Post parse cleanup for c */ + PyMem_FREE(c); + +exit: + return return_value; +} + +PyDoc_STRVAR(py_buffer_converter__doc__, +"py_buffer_converter($module, a, b, /)\n" +"--\n" +"\n"); + +#define PY_BUFFER_CONVERTER_METHODDEF \ + {"py_buffer_converter", _PyCFunction_CAST(py_buffer_converter), METH_FASTCALL, py_buffer_converter__doc__}, + +static PyObject * +py_buffer_converter_impl(PyObject *module, Py_buffer *a, Py_buffer *b); + +static PyObject * +py_buffer_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + Py_buffer a = {NULL, NULL}; + Py_buffer b = {NULL, NULL}; + + if (!_PyArg_ParseStack(args, nargs, "z*w*:py_buffer_converter", + &a, &b)) { + goto exit; + } + return_value = py_buffer_converter_impl(module, &a, &b); + +exit: + /* Cleanup for a */ + if (a.obj) { + PyBuffer_Release(&a); + } + /* Cleanup for b */ + if (b.obj) { + PyBuffer_Release(&b); + } + + return return_value; +} + +PyDoc_STRVAR(keywords__doc__, +"keywords($module, /, a, b)\n" +"--\n" +"\n"); + +#define KEYWORDS_METHODDEF \ + {"keywords", _PyCFunction_CAST(keywords), METH_FASTCALL|METH_KEYWORDS, keywords__doc__}, + +static PyObject * +keywords_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +keywords(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "keywords", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *a; + PyObject *b; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + return_value = keywords_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(keywords_kwonly__doc__, +"keywords_kwonly($module, /, a, *, b)\n" +"--\n" +"\n"); + +#define KEYWORDS_KWONLY_METHODDEF \ + {"keywords_kwonly", _PyCFunction_CAST(keywords_kwonly), METH_FASTCALL|METH_KEYWORDS, keywords_kwonly__doc__}, + +static PyObject * +keywords_kwonly_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +keywords_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "keywords_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *a; + PyObject *b; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + return_value = keywords_kwonly_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(keywords_opt__doc__, +"keywords_opt($module, /, a, b=None, c=None)\n" +"--\n" +"\n"); + +#define KEYWORDS_OPT_METHODDEF \ + {"keywords_opt", _PyCFunction_CAST(keywords_opt), METH_FASTCALL|METH_KEYWORDS, keywords_opt__doc__}, + +static PyObject * +keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c); + +static PyObject * +keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", "c", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "keywords_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *a; + PyObject *b = Py_None; + PyObject *c = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + b = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + c = args[2]; +skip_optional_pos: + return_value = keywords_opt_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(keywords_opt_kwonly__doc__, +"keywords_opt_kwonly($module, /, a, b=None, *, c=None, d=None)\n" +"--\n" +"\n"); + +#define KEYWORDS_OPT_KWONLY_METHODDEF \ + {"keywords_opt_kwonly", _PyCFunction_CAST(keywords_opt_kwonly), METH_FASTCALL|METH_KEYWORDS, keywords_opt_kwonly__doc__}, + +static PyObject * +keywords_opt_kwonly_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d); + +static PyObject * +keywords_opt_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "keywords_opt_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *a; + PyObject *b = Py_None; + PyObject *c = Py_None; + PyObject *d = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + b = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[2]) { + c = args[2]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + d = args[3]; +skip_optional_kwonly: + return_value = keywords_opt_kwonly_impl(module, a, b, c, d); + +exit: + return return_value; +} + +PyDoc_STRVAR(keywords_kwonly_opt__doc__, +"keywords_kwonly_opt($module, /, a, *, b=None, c=None)\n" +"--\n" +"\n"); + +#define KEYWORDS_KWONLY_OPT_METHODDEF \ + {"keywords_kwonly_opt", _PyCFunction_CAST(keywords_kwonly_opt), METH_FASTCALL|METH_KEYWORDS, keywords_kwonly_opt__doc__}, + +static PyObject * +keywords_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c); + +static PyObject * +keywords_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", "c", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "keywords_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *a; + PyObject *b = Py_None; + PyObject *c = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[1]) { + b = args[1]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + c = args[2]; +skip_optional_kwonly: + return_value = keywords_kwonly_opt_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(posonly_keywords__doc__, +"posonly_keywords($module, a, /, b)\n" +"--\n" +"\n"); + +#define POSONLY_KEYWORDS_METHODDEF \ + {"posonly_keywords", _PyCFunction_CAST(posonly_keywords), METH_FASTCALL|METH_KEYWORDS, posonly_keywords__doc__}, + +static PyObject * +posonly_keywords_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +posonly_keywords(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_keywords", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *a; + PyObject *b; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + return_value = posonly_keywords_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(posonly_kwonly__doc__, +"posonly_kwonly($module, a, /, *, b)\n" +"--\n" +"\n"); + +#define POSONLY_KWONLY_METHODDEF \ + {"posonly_kwonly", _PyCFunction_CAST(posonly_kwonly), METH_FASTCALL|METH_KEYWORDS, posonly_kwonly__doc__}, + +static PyObject * +posonly_kwonly_impl(PyObject *module, PyObject *a, PyObject *b); + +static PyObject * +posonly_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *a; + PyObject *b; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + return_value = posonly_kwonly_impl(module, a, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(posonly_keywords_kwonly__doc__, +"posonly_keywords_kwonly($module, a, /, b, *, c)\n" +"--\n" +"\n"); + +#define POSONLY_KEYWORDS_KWONLY_METHODDEF \ + {"posonly_keywords_kwonly", _PyCFunction_CAST(posonly_keywords_kwonly), METH_FASTCALL|METH_KEYWORDS, posonly_keywords_kwonly__doc__}, + +static PyObject * +posonly_keywords_kwonly_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c); + +static PyObject * +posonly_keywords_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", "c", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_keywords_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + PyObject *a; + PyObject *b; + PyObject *c; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + c = args[2]; + return_value = posonly_keywords_kwonly_impl(module, a, b, c); + +exit: + return return_value; +} + +PyDoc_STRVAR(posonly_keywords_opt__doc__, +"posonly_keywords_opt($module, a, /, b, c=None, d=None)\n" +"--\n" +"\n"); + +#define POSONLY_KEYWORDS_OPT_METHODDEF \ + {"posonly_keywords_opt", _PyCFunction_CAST(posonly_keywords_opt), METH_FASTCALL|METH_KEYWORDS, posonly_keywords_opt__doc__}, + +static PyObject * +posonly_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d); + +static PyObject * +posonly_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_keywords_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *a; + PyObject *b; + PyObject *c = Py_None; + PyObject *d = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 4, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[2]) { + c = args[2]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + d = args[3]; +skip_optional_pos: + return_value = posonly_keywords_opt_impl(module, a, b, c, d); + +exit: + return return_value; +} + +PyDoc_STRVAR(posonly_opt_keywords_opt__doc__, +"posonly_opt_keywords_opt($module, a, b=None, /, c=None, d=None)\n" +"--\n" +"\n"); + +#define POSONLY_OPT_KEYWORDS_OPT_METHODDEF \ + {"posonly_opt_keywords_opt", _PyCFunction_CAST(posonly_opt_keywords_opt), METH_FASTCALL|METH_KEYWORDS, posonly_opt_keywords_opt__doc__}, + +static PyObject * +posonly_opt_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d); + +static PyObject * +posonly_opt_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_opt_keywords_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *a; + PyObject *b = Py_None; + PyObject *c = Py_None; + PyObject *d = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 4, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + if (nargs < 2) { + goto skip_optional_posonly; + } + noptargs--; + b = args[1]; +skip_optional_posonly: + if (!noptargs) { + goto skip_optional_pos; + } + if (args[2]) { + c = args[2]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + d = args[3]; +skip_optional_pos: + return_value = posonly_opt_keywords_opt_impl(module, a, b, c, d); + +exit: + return return_value; +} + +PyDoc_STRVAR(posonly_kwonly_opt__doc__, +"posonly_kwonly_opt($module, a, /, *, b, c=None, d=None)\n" +"--\n" +"\n"); + +#define POSONLY_KWONLY_OPT_METHODDEF \ + {"posonly_kwonly_opt", _PyCFunction_CAST(posonly_kwonly_opt), METH_FASTCALL|METH_KEYWORDS, posonly_kwonly_opt__doc__}, + +static PyObject * +posonly_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d); + +static PyObject * +posonly_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *a; + PyObject *b; + PyObject *c = Py_None; + PyObject *d = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[2]) { + c = args[2]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + d = args[3]; +skip_optional_kwonly: + return_value = posonly_kwonly_opt_impl(module, a, b, c, d); + +exit: + return return_value; +} + +PyDoc_STRVAR(posonly_opt_kwonly_opt__doc__, +"posonly_opt_kwonly_opt($module, a, b=None, /, *, c=None, d=None)\n" +"--\n" +"\n"); + +#define POSONLY_OPT_KWONLY_OPT_METHODDEF \ + {"posonly_opt_kwonly_opt", _PyCFunction_CAST(posonly_opt_kwonly_opt), METH_FASTCALL|METH_KEYWORDS, posonly_opt_kwonly_opt__doc__}, + +static PyObject * +posonly_opt_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d); + +static PyObject * +posonly_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_opt_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *a; + PyObject *b = Py_None; + PyObject *c = Py_None; + PyObject *d = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + if (nargs < 2) { + goto skip_optional_posonly; + } + noptargs--; + b = args[1]; +skip_optional_posonly: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[2]) { + c = args[2]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + d = args[3]; +skip_optional_kwonly: + return_value = posonly_opt_kwonly_opt_impl(module, a, b, c, d); + +exit: + return return_value; +} + +PyDoc_STRVAR(posonly_keywords_kwonly_opt__doc__, +"posonly_keywords_kwonly_opt($module, a, /, b, *, c, d=None, e=None)\n" +"--\n" +"\n"); + +#define POSONLY_KEYWORDS_KWONLY_OPT_METHODDEF \ + {"posonly_keywords_kwonly_opt", _PyCFunction_CAST(posonly_keywords_kwonly_opt), METH_FASTCALL|METH_KEYWORDS, posonly_keywords_kwonly_opt__doc__}, + +static PyObject * +posonly_keywords_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *c, PyObject *d, PyObject *e); + +static PyObject * +posonly_keywords_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", "c", "d", "e", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_keywords_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[5]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; + PyObject *a; + PyObject *b; + PyObject *c; + PyObject *d = Py_None; + PyObject *e = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + c = args[2]; + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[3]) { + d = args[3]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + e = args[4]; +skip_optional_kwonly: + return_value = posonly_keywords_kwonly_opt_impl(module, a, b, c, d, e); + +exit: + return return_value; +} + +PyDoc_STRVAR(posonly_keywords_opt_kwonly_opt__doc__, +"posonly_keywords_opt_kwonly_opt($module, a, /, b, c=None, *, d=None,\n" +" e=None)\n" +"--\n" +"\n"); + +#define POSONLY_KEYWORDS_OPT_KWONLY_OPT_METHODDEF \ + {"posonly_keywords_opt_kwonly_opt", _PyCFunction_CAST(posonly_keywords_opt_kwonly_opt), METH_FASTCALL|METH_KEYWORDS, posonly_keywords_opt_kwonly_opt__doc__}, + +static PyObject * +posonly_keywords_opt_kwonly_opt_impl(PyObject *module, PyObject *a, + PyObject *b, PyObject *c, PyObject *d, + PyObject *e); + +static PyObject * +posonly_keywords_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", "c", "d", "e", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_keywords_opt_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[5]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *a; + PyObject *b; + PyObject *c = Py_None; + PyObject *d = Py_None; + PyObject *e = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[2]) { + c = args[2]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[3]) { + d = args[3]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + e = args[4]; +skip_optional_kwonly: + return_value = posonly_keywords_opt_kwonly_opt_impl(module, a, b, c, d, e); + +exit: + return return_value; +} + +PyDoc_STRVAR(posonly_opt_keywords_opt_kwonly_opt__doc__, +"posonly_opt_keywords_opt_kwonly_opt($module, a, b=None, /, c=None, *,\n" +" d=None)\n" +"--\n" +"\n"); + +#define POSONLY_OPT_KEYWORDS_OPT_KWONLY_OPT_METHODDEF \ + {"posonly_opt_keywords_opt_kwonly_opt", _PyCFunction_CAST(posonly_opt_keywords_opt_kwonly_opt), METH_FASTCALL|METH_KEYWORDS, posonly_opt_keywords_opt_kwonly_opt__doc__}, + +static PyObject * +posonly_opt_keywords_opt_kwonly_opt_impl(PyObject *module, PyObject *a, + PyObject *b, PyObject *c, + PyObject *d); + +static PyObject * +posonly_opt_keywords_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "", "c", "d", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_opt_keywords_opt_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *a; + PyObject *b = Py_None; + PyObject *c = Py_None; + PyObject *d = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + if (nargs < 2) { + goto skip_optional_posonly; + } + noptargs--; + b = args[1]; +skip_optional_posonly: + if (!noptargs) { + goto skip_optional_pos; + } + if (args[2]) { + c = args[2]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + d = args[3]; +skip_optional_kwonly: + return_value = posonly_opt_keywords_opt_kwonly_opt_impl(module, a, b, c, d); + +exit: + return return_value; +} + +PyDoc_STRVAR(keyword_only_parameter__doc__, +"keyword_only_parameter($module, /, *, a)\n" +"--\n" +"\n"); + +#define KEYWORD_ONLY_PARAMETER_METHODDEF \ + {"keyword_only_parameter", _PyCFunction_CAST(keyword_only_parameter), METH_FASTCALL|METH_KEYWORDS, keyword_only_parameter__doc__}, + +static PyObject * +keyword_only_parameter_impl(PyObject *module, PyObject *a); + +static PyObject * +keyword_only_parameter(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "keyword_only_parameter", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *a; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + return_value = keyword_only_parameter_impl(module, a); + +exit: + return return_value; +} + +PyDoc_STRVAR(posonly_vararg__doc__, +"posonly_vararg($module, a, /, b, *args)\n" +"--\n" +"\n"); + +#define POSONLY_VARARG_METHODDEF \ + {"posonly_vararg", _PyCFunction_CAST(posonly_vararg), METH_FASTCALL|METH_KEYWORDS, posonly_vararg__doc__}, + +static PyObject * +posonly_vararg_impl(PyObject *module, PyObject *a, PyObject *b, + PyObject *args); + +static PyObject * +posonly_vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "b", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_vararg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + PyObject *a; + PyObject *b; + PyObject *__clinic_args = NULL; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, 2, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + b = args[1]; + __clinic_args = args[2]; + return_value = posonly_vararg_impl(module, a, b, __clinic_args); + +exit: + Py_XDECREF(__clinic_args); + return return_value; +} + +PyDoc_STRVAR(vararg_and_posonly__doc__, +"vararg_and_posonly($module, a, /, *args)\n" +"--\n" +"\n"); + +#define VARARG_AND_POSONLY_METHODDEF \ + {"vararg_and_posonly", _PyCFunction_CAST(vararg_and_posonly), METH_FASTCALL, vararg_and_posonly__doc__}, + +static PyObject * +vararg_and_posonly_impl(PyObject *module, PyObject *a, PyObject *args); + +static PyObject * +vararg_and_posonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *__clinic_args = NULL; + + if (!_PyArg_CheckPositional("vararg_and_posonly", nargs, 1, PY_SSIZE_T_MAX)) { + goto exit; + } + a = args[0]; + __clinic_args = PyTuple_New(nargs - 1); + if (!__clinic_args) { + goto exit; + } + for (Py_ssize_t i = 0; i < nargs - 1; ++i) { + PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[1 + i])); + } + return_value = vararg_and_posonly_impl(module, a, __clinic_args); + +exit: + Py_XDECREF(__clinic_args); + return return_value; +} + +PyDoc_STRVAR(vararg__doc__, +"vararg($module, /, a, *args)\n" +"--\n" +"\n"); + +#define VARARG_METHODDEF \ + {"vararg", _PyCFunction_CAST(vararg), METH_FASTCALL|METH_KEYWORDS, vararg__doc__}, + +static PyObject * +vararg_impl(PyObject *module, PyObject *a, PyObject *args); + +static PyObject * +vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "vararg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *a; + PyObject *__clinic_args = NULL; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + __clinic_args = args[1]; + return_value = vararg_impl(module, a, __clinic_args); + +exit: + Py_XDECREF(__clinic_args); + return return_value; +} + +PyDoc_STRVAR(vararg_with_default__doc__, +"vararg_with_default($module, /, a, *args, b=False)\n" +"--\n" +"\n"); + +#define VARARG_WITH_DEFAULT_METHODDEF \ + {"vararg_with_default", _PyCFunction_CAST(vararg_with_default), METH_FASTCALL|METH_KEYWORDS, vararg_with_default__doc__}, + +static PyObject * +vararg_with_default_impl(PyObject *module, PyObject *a, PyObject *args, + int b); + +static PyObject * +vararg_with_default(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "vararg_with_default", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *a; + PyObject *__clinic_args = NULL; + int b = 0; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, 1, argsbuf); + if (!args) { + goto exit; + } + a = args[0]; + __clinic_args = args[1]; + if (!noptargs) { + goto skip_optional_kwonly; + } + b = PyObject_IsTrue(args[2]); + if (b < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = vararg_with_default_impl(module, a, __clinic_args, b); + +exit: + Py_XDECREF(__clinic_args); + return return_value; +} + +PyDoc_STRVAR(vararg_with_only_defaults__doc__, +"vararg_with_only_defaults($module, /, *args, b=None)\n" +"--\n" +"\n"); + +#define VARARG_WITH_ONLY_DEFAULTS_METHODDEF \ + {"vararg_with_only_defaults", _PyCFunction_CAST(vararg_with_only_defaults), METH_FASTCALL|METH_KEYWORDS, vararg_with_only_defaults__doc__}, + +static PyObject * +vararg_with_only_defaults_impl(PyObject *module, PyObject *args, PyObject *b); + +static PyObject * +vararg_with_only_defaults(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"b", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "vararg_with_only_defaults", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *__clinic_args = NULL; + PyObject *b = Py_None; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf); + if (!args) { + goto exit; + } + __clinic_args = args[0]; + if (!noptargs) { + goto skip_optional_kwonly; + } + b = args[1]; +skip_optional_kwonly: + return_value = vararg_with_only_defaults_impl(module, __clinic_args, b); + +exit: + Py_XDECREF(__clinic_args); + return return_value; +} + +PyDoc_STRVAR(gh_32092_oob__doc__, +"gh_32092_oob($module, /, pos1, pos2, *varargs, kw1=None, kw2=None)\n" +"--\n" +"\n" +"Proof-of-concept of GH-32092 OOB bug."); + +#define GH_32092_OOB_METHODDEF \ + {"gh_32092_oob", _PyCFunction_CAST(gh_32092_oob), METH_FASTCALL|METH_KEYWORDS, gh_32092_oob__doc__}, + +static PyObject * +gh_32092_oob_impl(PyObject *module, PyObject *pos1, PyObject *pos2, + PyObject *varargs, PyObject *kw1, PyObject *kw2); + +static PyObject * +gh_32092_oob(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pos1), &_Py_ID(pos2), &_Py_ID(kw1), &_Py_ID(kw2), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"pos1", "pos2", "kw1", "kw2", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "gh_32092_oob", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[5]; + Py_ssize_t noptargs = Py_MIN(nargs, 2) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *pos1; + PyObject *pos2; + PyObject *varargs = NULL; + PyObject *kw1 = Py_None; + PyObject *kw2 = Py_None; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, 2, argsbuf); + if (!args) { + goto exit; + } + pos1 = args[0]; + pos2 = args[1]; + varargs = args[2]; + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[3]) { + kw1 = args[3]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + kw2 = args[4]; +skip_optional_kwonly: + return_value = gh_32092_oob_impl(module, pos1, pos2, varargs, kw1, kw2); + +exit: + Py_XDECREF(varargs); + return return_value; +} + +PyDoc_STRVAR(gh_32092_kw_pass__doc__, +"gh_32092_kw_pass($module, /, pos, *args, kw=None)\n" +"--\n" +"\n" +"Proof-of-concept of GH-32092 keyword args passing bug."); + +#define GH_32092_KW_PASS_METHODDEF \ + {"gh_32092_kw_pass", _PyCFunction_CAST(gh_32092_kw_pass), METH_FASTCALL|METH_KEYWORDS, gh_32092_kw_pass__doc__}, + +static PyObject * +gh_32092_kw_pass_impl(PyObject *module, PyObject *pos, PyObject *args, + PyObject *kw); + +static PyObject * +gh_32092_kw_pass(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pos), &_Py_ID(kw), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"pos", "kw", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "gh_32092_kw_pass", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *pos; + PyObject *__clinic_args = NULL; + PyObject *kw = Py_None; + + args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, 1, argsbuf); + if (!args) { + goto exit; + } + pos = args[0]; + __clinic_args = args[1]; + if (!noptargs) { + goto skip_optional_kwonly; + } + kw = args[2]; +skip_optional_kwonly: + return_value = gh_32092_kw_pass_impl(module, pos, __clinic_args, kw); + +exit: + Py_XDECREF(__clinic_args); + return return_value; +} + +PyDoc_STRVAR(gh_99233_refcount__doc__, +"gh_99233_refcount($module, /, *args)\n" +"--\n" +"\n" +"Proof-of-concept of GH-99233 refcount error bug."); + +#define GH_99233_REFCOUNT_METHODDEF \ + {"gh_99233_refcount", _PyCFunction_CAST(gh_99233_refcount), METH_FASTCALL, gh_99233_refcount__doc__}, + +static PyObject * +gh_99233_refcount_impl(PyObject *module, PyObject *args); + +static PyObject * +gh_99233_refcount(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *__clinic_args = NULL; + + if (!_PyArg_CheckPositional("gh_99233_refcount", nargs, 0, PY_SSIZE_T_MAX)) { + goto exit; + } + __clinic_args = PyTuple_New(nargs - 0); + if (!__clinic_args) { + goto exit; + } + for (Py_ssize_t i = 0; i < nargs - 0; ++i) { + PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i])); + } + return_value = gh_99233_refcount_impl(module, __clinic_args); + +exit: + Py_XDECREF(__clinic_args); + return return_value; +} + +PyDoc_STRVAR(gh_99240_double_free__doc__, +"gh_99240_double_free($module, a, b, /)\n" +"--\n" +"\n" +"Proof-of-concept of GH-99240 double-free bug."); + +#define GH_99240_DOUBLE_FREE_METHODDEF \ + {"gh_99240_double_free", _PyCFunction_CAST(gh_99240_double_free), METH_FASTCALL, gh_99240_double_free__doc__}, + +static PyObject * +gh_99240_double_free_impl(PyObject *module, char *a, char *b); + +static PyObject * +gh_99240_double_free(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + char *a = NULL; + char *b = NULL; + + if (!_PyArg_ParseStack(args, nargs, "eses:gh_99240_double_free", + "idna", &a, "idna", &b)) { + goto exit; + } + return_value = gh_99240_double_free_impl(module, a, b); + /* Post parse cleanup for a */ + PyMem_FREE(a); + /* Post parse cleanup for b */ + PyMem_FREE(b); + +exit: + return return_value; +} +/*[clinic end generated code: output=e8211606b03d733a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testinternalcapi.c.h b/Modules/clinic/_testinternalcapi.c.h new file mode 100644 index 00000000000..e8d5681b194 --- /dev/null +++ b/Modules/clinic/_testinternalcapi.c.h @@ -0,0 +1,131 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(_testinternalcapi_compiler_codegen__doc__, +"compiler_codegen($module, /, ast, filename, optimize)\n" +"--\n" +"\n" +"Apply compiler code generation to an AST."); + +#define _TESTINTERNALCAPI_COMPILER_CODEGEN_METHODDEF \ + {"compiler_codegen", _PyCFunction_CAST(_testinternalcapi_compiler_codegen), METH_FASTCALL|METH_KEYWORDS, _testinternalcapi_compiler_codegen__doc__}, + +static PyObject * +_testinternalcapi_compiler_codegen_impl(PyObject *module, PyObject *ast, + PyObject *filename, int optimize); + +static PyObject * +_testinternalcapi_compiler_codegen(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(ast), &_Py_ID(filename), &_Py_ID(optimize), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"ast", "filename", "optimize", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compiler_codegen", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + PyObject *ast; + PyObject *filename; + int optimize; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + ast = args[0]; + filename = args[1]; + optimize = _PyLong_AsInt(args[2]); + if (optimize == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _testinternalcapi_compiler_codegen_impl(module, ast, filename, optimize); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testinternalcapi_optimize_cfg__doc__, +"optimize_cfg($module, /, instructions, consts)\n" +"--\n" +"\n" +"Apply compiler optimizations to an instruction list."); + +#define _TESTINTERNALCAPI_OPTIMIZE_CFG_METHODDEF \ + {"optimize_cfg", _PyCFunction_CAST(_testinternalcapi_optimize_cfg), METH_FASTCALL|METH_KEYWORDS, _testinternalcapi_optimize_cfg__doc__}, + +static PyObject * +_testinternalcapi_optimize_cfg_impl(PyObject *module, PyObject *instructions, + PyObject *consts); + +static PyObject * +_testinternalcapi_optimize_cfg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(instructions), &_Py_ID(consts), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"instructions", "consts", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "optimize_cfg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *instructions; + PyObject *consts; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + instructions = args[0]; + consts = args[1]; + return_value = _testinternalcapi_optimize_cfg_impl(module, instructions, consts); + +exit: + return return_value; +} +/*[clinic end generated code: output=efe95836482fd542 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testmultiphase.c.h b/Modules/clinic/_testmultiphase.c.h index 55f934be8c6..42ec7475e5e 100644 --- a/Modules/clinic/_testmultiphase.c.h +++ b/Modules/clinic/_testmultiphase.c.h @@ -2,17 +2,23 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_testmultiphase_StateAccessType_get_defining_module__doc__, "get_defining_module($self, /)\n" "--\n" "\n" "Return the module of the defining class.\n" "\n" -"Also tests that result of _PyType_GetModuleByDef matches defining_class\'s\n" +"Also tests that result of PyType_GetModuleByDef matches defining_class\'s\n" "module."); #define _TESTMULTIPHASE_STATEACCESSTYPE_GET_DEFINING_MODULE_METHODDEF \ - {"get_defining_module", (PyCFunction)(void(*)(void))_testmultiphase_StateAccessType_get_defining_module, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _testmultiphase_StateAccessType_get_defining_module__doc__}, + {"get_defining_module", _PyCFunction_CAST(_testmultiphase_StateAccessType_get_defining_module), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _testmultiphase_StateAccessType_get_defining_module__doc__}, static PyObject * _testmultiphase_StateAccessType_get_defining_module_impl(StateAccessTypeObject *self, @@ -21,18 +27,34 @@ _testmultiphase_StateAccessType_get_defining_module_impl(StateAccessTypeObject * static PyObject * _testmultiphase_StateAccessType_get_defining_module(StateAccessTypeObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":get_defining_module", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "get_defining_module() takes no arguments"); + return NULL; } - return_value = _testmultiphase_StateAccessType_get_defining_module_impl(self, cls); + return _testmultiphase_StateAccessType_get_defining_module_impl(self, cls); +} -exit: - return return_value; +PyDoc_STRVAR(_testmultiphase_StateAccessType_getmodulebydef_bad_def__doc__, +"getmodulebydef_bad_def($self, /)\n" +"--\n" +"\n" +"Test that result of PyType_GetModuleByDef with a bad def is NULL."); + +#define _TESTMULTIPHASE_STATEACCESSTYPE_GETMODULEBYDEF_BAD_DEF_METHODDEF \ + {"getmodulebydef_bad_def", _PyCFunction_CAST(_testmultiphase_StateAccessType_getmodulebydef_bad_def), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _testmultiphase_StateAccessType_getmodulebydef_bad_def__doc__}, + +static PyObject * +_testmultiphase_StateAccessType_getmodulebydef_bad_def_impl(StateAccessTypeObject *self, + PyTypeObject *cls); + +static PyObject * +_testmultiphase_StateAccessType_getmodulebydef_bad_def(StateAccessTypeObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + if (nargs) { + PyErr_SetString(PyExc_TypeError, "getmodulebydef_bad_def() takes no arguments"); + return NULL; + } + return _testmultiphase_StateAccessType_getmodulebydef_bad_def_impl(self, cls); } PyDoc_STRVAR(_testmultiphase_StateAccessType_increment_count_clinic__doc__, @@ -46,7 +68,7 @@ PyDoc_STRVAR(_testmultiphase_StateAccessType_increment_count_clinic__doc__, "This tests Argument Clinic support for defining_class."); #define _TESTMULTIPHASE_STATEACCESSTYPE_INCREMENT_COUNT_CLINIC_METHODDEF \ - {"increment_count_clinic", (PyCFunction)(void(*)(void))_testmultiphase_StateAccessType_increment_count_clinic, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _testmultiphase_StateAccessType_increment_count_clinic__doc__}, + {"increment_count_clinic", _PyCFunction_CAST(_testmultiphase_StateAccessType_increment_count_clinic), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _testmultiphase_StateAccessType_increment_count_clinic__doc__}, static PyObject * _testmultiphase_StateAccessType_increment_count_clinic_impl(StateAccessTypeObject *self, @@ -57,15 +79,61 @@ static PyObject * _testmultiphase_StateAccessType_increment_count_clinic(StateAccessTypeObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(n), &_Py_ID(twice), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"n", "twice", NULL}; - static _PyArg_Parser _parser = {"|i$p:increment_count_clinic", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "increment_count_clinic", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int n = 1; int twice = 0; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &n, &twice)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { goto exit; } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + n = _PyLong_AsInt(args[0]); + if (n == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + twice = PyObject_IsTrue(args[1]); + if (twice < 0) { + goto exit; + } +skip_optional_kwonly: return_value = _testmultiphase_StateAccessType_increment_count_clinic_impl(self, cls, n, twice); exit: @@ -79,7 +147,7 @@ PyDoc_STRVAR(_testmultiphase_StateAccessType_get_count__doc__, "Return the value of the module-state counter."); #define _TESTMULTIPHASE_STATEACCESSTYPE_GET_COUNT_METHODDEF \ - {"get_count", (PyCFunction)(void(*)(void))_testmultiphase_StateAccessType_get_count, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _testmultiphase_StateAccessType_get_count__doc__}, + {"get_count", _PyCFunction_CAST(_testmultiphase_StateAccessType_get_count), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _testmultiphase_StateAccessType_get_count__doc__}, static PyObject * _testmultiphase_StateAccessType_get_count_impl(StateAccessTypeObject *self, @@ -88,17 +156,10 @@ _testmultiphase_StateAccessType_get_count_impl(StateAccessTypeObject *self, static PyObject * _testmultiphase_StateAccessType_get_count(StateAccessTypeObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":get_count", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "get_count() takes no arguments"); + return NULL; } - return_value = _testmultiphase_StateAccessType_get_count_impl(self, cls); - -exit: - return return_value; + return _testmultiphase_StateAccessType_get_count_impl(self, cls); } -/*[clinic end generated code: output=f01137bb3b373e14 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=52ea97ab2f03bb6d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_tkinter.c.h b/Modules/clinic/_tkinter.c.h index ea45858d73f..96c6ee26f42 100644 --- a/Modules/clinic/_tkinter.c.h +++ b/Modules/clinic/_tkinter.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_tkinter_tkapp_eval__doc__, "eval($self, script, /)\n" "--\n" @@ -328,7 +334,7 @@ PyDoc_STRVAR(_tkinter_tkapp_createcommand__doc__, "\n"); #define _TKINTER_TKAPP_CREATECOMMAND_METHODDEF \ - {"createcommand", (PyCFunction)(void(*)(void))_tkinter_tkapp_createcommand, METH_FASTCALL, _tkinter_tkapp_createcommand__doc__}, + {"createcommand", _PyCFunction_CAST(_tkinter_tkapp_createcommand), METH_FASTCALL, _tkinter_tkapp_createcommand__doc__}, static PyObject * _tkinter_tkapp_createcommand_impl(TkappObject *self, const char *name, @@ -408,7 +414,7 @@ PyDoc_STRVAR(_tkinter_tkapp_createfilehandler__doc__, "\n"); #define _TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF \ - {"createfilehandler", (PyCFunction)(void(*)(void))_tkinter_tkapp_createfilehandler, METH_FASTCALL, _tkinter_tkapp_createfilehandler__doc__}, + {"createfilehandler", _PyCFunction_CAST(_tkinter_tkapp_createfilehandler), METH_FASTCALL, _tkinter_tkapp_createfilehandler__doc__}, static PyObject * _tkinter_tkapp_createfilehandler_impl(TkappObject *self, PyObject *file, @@ -474,7 +480,7 @@ PyDoc_STRVAR(_tkinter_tkapp_createtimerhandler__doc__, "\n"); #define _TKINTER_TKAPP_CREATETIMERHANDLER_METHODDEF \ - {"createtimerhandler", (PyCFunction)(void(*)(void))_tkinter_tkapp_createtimerhandler, METH_FASTCALL, _tkinter_tkapp_createtimerhandler__doc__}, + {"createtimerhandler", _PyCFunction_CAST(_tkinter_tkapp_createtimerhandler), METH_FASTCALL, _tkinter_tkapp_createtimerhandler__doc__}, static PyObject * _tkinter_tkapp_createtimerhandler_impl(TkappObject *self, int milliseconds, @@ -507,7 +513,7 @@ PyDoc_STRVAR(_tkinter_tkapp_mainloop__doc__, "\n"); #define _TKINTER_TKAPP_MAINLOOP_METHODDEF \ - {"mainloop", (PyCFunction)(void(*)(void))_tkinter_tkapp_mainloop, METH_FASTCALL, _tkinter_tkapp_mainloop__doc__}, + {"mainloop", _PyCFunction_CAST(_tkinter_tkapp_mainloop), METH_FASTCALL, _tkinter_tkapp_mainloop__doc__}, static PyObject * _tkinter_tkapp_mainloop_impl(TkappObject *self, int threshold); @@ -541,7 +547,7 @@ PyDoc_STRVAR(_tkinter_tkapp_dooneevent__doc__, "\n"); #define _TKINTER_TKAPP_DOONEEVENT_METHODDEF \ - {"dooneevent", (PyCFunction)(void(*)(void))_tkinter_tkapp_dooneevent, METH_FASTCALL, _tkinter_tkapp_dooneevent__doc__}, + {"dooneevent", _PyCFunction_CAST(_tkinter_tkapp_dooneevent), METH_FASTCALL, _tkinter_tkapp_dooneevent__doc__}, static PyObject * _tkinter_tkapp_dooneevent_impl(TkappObject *self, int flags); @@ -661,7 +667,7 @@ PyDoc_STRVAR(_tkinter_create__doc__, " if not None, then pass -use to wish"); #define _TKINTER_CREATE_METHODDEF \ - {"create", (PyCFunction)(void(*)(void))_tkinter_create, METH_FASTCALL, _tkinter_create__doc__}, + {"create", _PyCFunction_CAST(_tkinter_create), METH_FASTCALL, _tkinter_create__doc__}, static PyObject * _tkinter_create_impl(PyObject *module, const char *screenName, @@ -741,29 +747,29 @@ _tkinter_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 4) { goto skip_optional; } - interactive = _PyLong_AsInt(args[3]); - if (interactive == -1 && PyErr_Occurred()) { + interactive = PyObject_IsTrue(args[3]); + if (interactive < 0) { goto exit; } if (nargs < 5) { goto skip_optional; } - wantobjects = _PyLong_AsInt(args[4]); - if (wantobjects == -1 && PyErr_Occurred()) { + wantobjects = PyObject_IsTrue(args[4]); + if (wantobjects < 0) { goto exit; } if (nargs < 6) { goto skip_optional; } - wantTk = _PyLong_AsInt(args[5]); - if (wantTk == -1 && PyErr_Occurred()) { + wantTk = PyObject_IsTrue(args[5]); + if (wantTk < 0) { goto exit; } if (nargs < 7) { goto skip_optional; } - sync = _PyLong_AsInt(args[6]); - if (sync == -1 && PyErr_Occurred()) { + sync = PyObject_IsTrue(args[6]); + if (sync < 0) { goto exit; } if (nargs < 8) { @@ -859,4 +865,4 @@ exit: #ifndef _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF #define _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF #endif /* !defined(_TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF) */ -/*[clinic end generated code: output=b6d2dcb488c13aa7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2a4e3bf8448604b5 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_tracemalloc.c.h b/Modules/clinic/_tracemalloc.c.h index 20afd76f06f..a89cd9aabca 100644 --- a/Modules/clinic/_tracemalloc.c.h +++ b/Modules/clinic/_tracemalloc.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_tracemalloc_is_tracing__doc__, "is_tracing($module, /)\n" "--\n" @@ -84,7 +90,7 @@ PyDoc_STRVAR(_tracemalloc_start__doc__, "trace to nframe."); #define _TRACEMALLOC_START_METHODDEF \ - {"start", (PyCFunction)(void(*)(void))_tracemalloc_start, METH_FASTCALL, _tracemalloc_start__doc__}, + {"start", _PyCFunction_CAST(_tracemalloc_start), METH_FASTCALL, _tracemalloc_start__doc__}, static PyObject * _tracemalloc_start_impl(PyObject *module, int nframe); @@ -212,4 +218,4 @@ _tracemalloc_reset_peak(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _tracemalloc_reset_peak_impl(module); } -/*[clinic end generated code: output=bafca0a19b0b0823 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=44e3f8553aae2535 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_typingmodule.c.h b/Modules/clinic/_typingmodule.c.h index ea415e67153..f980aa0d084 100644 --- a/Modules/clinic/_typingmodule.c.h +++ b/Modules/clinic/_typingmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_typing__idfunc__doc__, "_idfunc($module, x, /)\n" "--\n" @@ -9,4 +15,4 @@ PyDoc_STRVAR(_typing__idfunc__doc__, #define _TYPING__IDFUNC_METHODDEF \ {"_idfunc", (PyCFunction)_typing__idfunc, METH_O, _typing__idfunc__doc__}, -/*[clinic end generated code: output=e7ea2a3cb7ab301a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=97457fda45072c7d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_weakref.c.h b/Modules/clinic/_weakref.c.h index c3a908fa6a1..48feb042cac 100644 --- a/Modules/clinic/_weakref.c.h +++ b/Modules/clinic/_weakref.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_weakref_getweakrefcount__doc__, "getweakrefcount($module, object, /)\n" "--\n" @@ -37,7 +43,7 @@ PyDoc_STRVAR(_weakref__remove_dead_weakref__doc__, "Atomically remove key from dict if it points to a dead weakref."); #define _WEAKREF__REMOVE_DEAD_WEAKREF_METHODDEF \ - {"_remove_dead_weakref", (PyCFunction)(void(*)(void))_weakref__remove_dead_weakref, METH_FASTCALL, _weakref__remove_dead_weakref__doc__}, + {"_remove_dead_weakref", _PyCFunction_CAST(_weakref__remove_dead_weakref), METH_FASTCALL, _weakref__remove_dead_weakref__doc__}, static PyObject * _weakref__remove_dead_weakref_impl(PyObject *module, PyObject *dct, @@ -64,4 +70,50 @@ _weakref__remove_dead_weakref(PyObject *module, PyObject *const *args, Py_ssize_ exit: return return_value; } -/*[clinic end generated code: output=c543dc2cd6ece975 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_weakref_getweakrefs__doc__, +"getweakrefs($module, object, /)\n" +"--\n" +"\n" +"Return a list of all weak reference objects pointing to \'object\'."); + +#define _WEAKREF_GETWEAKREFS_METHODDEF \ + {"getweakrefs", (PyCFunction)_weakref_getweakrefs, METH_O, _weakref_getweakrefs__doc__}, + +PyDoc_STRVAR(_weakref_proxy__doc__, +"proxy($module, object, callback=None, /)\n" +"--\n" +"\n" +"Create a proxy object that weakly references \'object\'.\n" +"\n" +"\'callback\', if given, is called with a reference to the\n" +"proxy when \'object\' is about to be finalized."); + +#define _WEAKREF_PROXY_METHODDEF \ + {"proxy", _PyCFunction_CAST(_weakref_proxy), METH_FASTCALL, _weakref_proxy__doc__}, + +static PyObject * +_weakref_proxy_impl(PyObject *module, PyObject *object, PyObject *callback); + +static PyObject * +_weakref_proxy(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *object; + PyObject *callback = NULL; + + if (!_PyArg_CheckPositional("proxy", nargs, 1, 2)) { + goto exit; + } + object = args[0]; + if (nargs < 2) { + goto skip_optional; + } + callback = args[1]; +skip_optional: + return_value = _weakref_proxy_impl(module, object, callback); + +exit: + return return_value; +} +/*[clinic end generated code: output=28265e89d583273d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_winapi.c.h b/Modules/clinic/_winapi.c.h index 5bda156d7aa..891b3f851d1 100644 --- a/Modules/clinic/_winapi.c.h +++ b/Modules/clinic/_winapi.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_winapi_Overlapped_GetOverlappedResult__doc__, "GetOverlappedResult($self, wait, /)\n" "--\n" @@ -96,7 +102,7 @@ PyDoc_STRVAR(_winapi_ConnectNamedPipe__doc__, "\n"); #define _WINAPI_CONNECTNAMEDPIPE_METHODDEF \ - {"ConnectNamedPipe", (PyCFunction)(void(*)(void))_winapi_ConnectNamedPipe, METH_FASTCALL|METH_KEYWORDS, _winapi_ConnectNamedPipe__doc__}, + {"ConnectNamedPipe", _PyCFunction_CAST(_winapi_ConnectNamedPipe), METH_FASTCALL|METH_KEYWORDS, _winapi_ConnectNamedPipe__doc__}, static PyObject * _winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle, @@ -106,8 +112,31 @@ static PyObject * _winapi_ConnectNamedPipe(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(handle), &_Py_ID(overlapped), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"handle", "overlapped", NULL}; - static _PyArg_Parser _parser = {"" F_HANDLE "|i:ConnectNamedPipe", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" F_HANDLE "|p:ConnectNamedPipe", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE HANDLE handle; int use_overlapped = 0; @@ -129,7 +158,7 @@ PyDoc_STRVAR(_winapi_CreateFile__doc__, "\n"); #define _WINAPI_CREATEFILE_METHODDEF \ - {"CreateFile", (PyCFunction)(void(*)(void))_winapi_CreateFile, METH_FASTCALL, _winapi_CreateFile__doc__}, + {"CreateFile", _PyCFunction_CAST(_winapi_CreateFile), METH_FASTCALL, _winapi_CreateFile__doc__}, static HANDLE _winapi_CreateFile_impl(PyObject *module, LPCTSTR file_name, @@ -175,7 +204,7 @@ PyDoc_STRVAR(_winapi_CreateFileMapping__doc__, "\n"); #define _WINAPI_CREATEFILEMAPPING_METHODDEF \ - {"CreateFileMapping", (PyCFunction)(void(*)(void))_winapi_CreateFileMapping, METH_FASTCALL, _winapi_CreateFileMapping__doc__}, + {"CreateFileMapping", _PyCFunction_CAST(_winapi_CreateFileMapping), METH_FASTCALL, _winapi_CreateFileMapping__doc__}, static HANDLE _winapi_CreateFileMapping_impl(PyObject *module, HANDLE file_handle, @@ -192,7 +221,7 @@ _winapi_CreateFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t na DWORD protect; DWORD max_size_high; DWORD max_size_low; - LPCWSTR name; + LPCWSTR name = NULL; HANDLE _return_value; if (!_PyArg_ParseStack(args, nargs, "" F_HANDLE "" F_POINTER "kkkO&:CreateFileMapping", @@ -210,9 +239,7 @@ _winapi_CreateFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t na exit: /* Cleanup for name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)name); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -223,7 +250,7 @@ PyDoc_STRVAR(_winapi_CreateJunction__doc__, "\n"); #define _WINAPI_CREATEJUNCTION_METHODDEF \ - {"CreateJunction", (PyCFunction)(void(*)(void))_winapi_CreateJunction, METH_FASTCALL, _winapi_CreateJunction__doc__}, + {"CreateJunction", _PyCFunction_CAST(_winapi_CreateJunction), METH_FASTCALL, _winapi_CreateJunction__doc__}, static PyObject * _winapi_CreateJunction_impl(PyObject *module, LPCWSTR src_path, @@ -233,8 +260,8 @@ static PyObject * _winapi_CreateJunction(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - LPCWSTR src_path; - LPCWSTR dst_path; + LPCWSTR src_path = NULL; + LPCWSTR dst_path = NULL; if (!_PyArg_CheckPositional("CreateJunction", nargs, 2, 2)) { goto exit; @@ -243,11 +270,7 @@ _winapi_CreateJunction(PyObject *module, PyObject *const *args, Py_ssize_t nargs _PyArg_BadArgument("CreateJunction", "argument 1", "str", args[0]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - src_path = _PyUnicode_AsUnicode(args[0]); - #else /* USE_UNICODE_WCHAR_CACHE */ src_path = PyUnicode_AsWideCharString(args[0], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (src_path == NULL) { goto exit; } @@ -255,11 +278,7 @@ _winapi_CreateJunction(PyObject *module, PyObject *const *args, Py_ssize_t nargs _PyArg_BadArgument("CreateJunction", "argument 2", "str", args[1]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - dst_path = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ dst_path = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (dst_path == NULL) { goto exit; } @@ -267,13 +286,9 @@ _winapi_CreateJunction(PyObject *module, PyObject *const *args, Py_ssize_t nargs exit: /* Cleanup for src_path */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)src_path); - #endif /* USE_UNICODE_WCHAR_CACHE */ /* Cleanup for dst_path */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)dst_path); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -286,7 +301,7 @@ PyDoc_STRVAR(_winapi_CreateNamedPipe__doc__, "\n"); #define _WINAPI_CREATENAMEDPIPE_METHODDEF \ - {"CreateNamedPipe", (PyCFunction)(void(*)(void))_winapi_CreateNamedPipe, METH_FASTCALL, _winapi_CreateNamedPipe__doc__}, + {"CreateNamedPipe", _PyCFunction_CAST(_winapi_CreateNamedPipe), METH_FASTCALL, _winapi_CreateNamedPipe__doc__}, static HANDLE _winapi_CreateNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD open_mode, @@ -338,7 +353,7 @@ PyDoc_STRVAR(_winapi_CreatePipe__doc__, "Returns a 2-tuple of handles, to the read and write ends of the pipe."); #define _WINAPI_CREATEPIPE_METHODDEF \ - {"CreatePipe", (PyCFunction)(void(*)(void))_winapi_CreatePipe, METH_FASTCALL, _winapi_CreatePipe__doc__}, + {"CreatePipe", _PyCFunction_CAST(_winapi_CreatePipe), METH_FASTCALL, _winapi_CreatePipe__doc__}, static PyObject * _winapi_CreatePipe_impl(PyObject *module, PyObject *pipe_attrs, DWORD size); @@ -379,7 +394,7 @@ PyDoc_STRVAR(_winapi_CreateProcess__doc__, "process ID, and thread ID."); #define _WINAPI_CREATEPROCESS_METHODDEF \ - {"CreateProcess", (PyCFunction)(void(*)(void))_winapi_CreateProcess, METH_FASTCALL, _winapi_CreateProcess__doc__}, + {"CreateProcess", _PyCFunction_CAST(_winapi_CreateProcess), METH_FASTCALL, _winapi_CreateProcess__doc__}, static PyObject * _winapi_CreateProcess_impl(PyObject *module, @@ -394,14 +409,14 @@ static PyObject * _winapi_CreateProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - const Py_UNICODE *application_name; + const Py_UNICODE *application_name = NULL; PyObject *command_line; PyObject *proc_attrs; PyObject *thread_attrs; BOOL inherit_handles; DWORD creation_flags; PyObject *env_mapping; - const Py_UNICODE *current_directory; + const Py_UNICODE *current_directory = NULL; PyObject *startup_info; if (!_PyArg_ParseStack(args, nargs, "O&OOOikOO&O:CreateProcess", @@ -412,13 +427,9 @@ _winapi_CreateProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for application_name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)application_name); - #endif /* USE_UNICODE_WCHAR_CACHE */ /* Cleanup for current_directory */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)current_directory); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -436,7 +447,7 @@ PyDoc_STRVAR(_winapi_DuplicateHandle__doc__, "through both handles."); #define _WINAPI_DUPLICATEHANDLE_METHODDEF \ - {"DuplicateHandle", (PyCFunction)(void(*)(void))_winapi_DuplicateHandle, METH_FASTCALL, _winapi_DuplicateHandle__doc__}, + {"DuplicateHandle", _PyCFunction_CAST(_winapi_DuplicateHandle), METH_FASTCALL, _winapi_DuplicateHandle__doc__}, static HANDLE _winapi_DuplicateHandle_impl(PyObject *module, HANDLE source_process_handle, @@ -699,7 +710,7 @@ PyDoc_STRVAR(_winapi_MapViewOfFile__doc__, "\n"); #define _WINAPI_MAPVIEWOFFILE_METHODDEF \ - {"MapViewOfFile", (PyCFunction)(void(*)(void))_winapi_MapViewOfFile, METH_FASTCALL, _winapi_MapViewOfFile__doc__}, + {"MapViewOfFile", _PyCFunction_CAST(_winapi_MapViewOfFile), METH_FASTCALL, _winapi_MapViewOfFile__doc__}, static LPVOID _winapi_MapViewOfFile_impl(PyObject *module, HANDLE file_map, @@ -731,13 +742,39 @@ exit: return return_value; } +PyDoc_STRVAR(_winapi_UnmapViewOfFile__doc__, +"UnmapViewOfFile($module, address, /)\n" +"--\n" +"\n"); + +#define _WINAPI_UNMAPVIEWOFFILE_METHODDEF \ + {"UnmapViewOfFile", (PyCFunction)_winapi_UnmapViewOfFile, METH_O, _winapi_UnmapViewOfFile__doc__}, + +static PyObject * +_winapi_UnmapViewOfFile_impl(PyObject *module, LPCVOID address); + +static PyObject * +_winapi_UnmapViewOfFile(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + LPCVOID address; + + if (!PyArg_Parse(arg, "" F_POINTER ":UnmapViewOfFile", &address)) { + goto exit; + } + return_value = _winapi_UnmapViewOfFile_impl(module, address); + +exit: + return return_value; +} + PyDoc_STRVAR(_winapi_OpenFileMapping__doc__, "OpenFileMapping($module, desired_access, inherit_handle, name, /)\n" "--\n" "\n"); #define _WINAPI_OPENFILEMAPPING_METHODDEF \ - {"OpenFileMapping", (PyCFunction)(void(*)(void))_winapi_OpenFileMapping, METH_FASTCALL, _winapi_OpenFileMapping__doc__}, + {"OpenFileMapping", _PyCFunction_CAST(_winapi_OpenFileMapping), METH_FASTCALL, _winapi_OpenFileMapping__doc__}, static HANDLE _winapi_OpenFileMapping_impl(PyObject *module, DWORD desired_access, @@ -749,7 +786,7 @@ _winapi_OpenFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t narg PyObject *return_value = NULL; DWORD desired_access; BOOL inherit_handle; - LPCWSTR name; + LPCWSTR name = NULL; HANDLE _return_value; if (!_PyArg_ParseStack(args, nargs, "kiO&:OpenFileMapping", @@ -767,9 +804,7 @@ _winapi_OpenFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t narg exit: /* Cleanup for name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)name); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -780,7 +815,7 @@ PyDoc_STRVAR(_winapi_OpenProcess__doc__, "\n"); #define _WINAPI_OPENPROCESS_METHODDEF \ - {"OpenProcess", (PyCFunction)(void(*)(void))_winapi_OpenProcess, METH_FASTCALL, _winapi_OpenProcess__doc__}, + {"OpenProcess", _PyCFunction_CAST(_winapi_OpenProcess), METH_FASTCALL, _winapi_OpenProcess__doc__}, static HANDLE _winapi_OpenProcess_impl(PyObject *module, DWORD desired_access, @@ -818,7 +853,7 @@ PyDoc_STRVAR(_winapi_PeekNamedPipe__doc__, "\n"); #define _WINAPI_PEEKNAMEDPIPE_METHODDEF \ - {"PeekNamedPipe", (PyCFunction)(void(*)(void))_winapi_PeekNamedPipe, METH_FASTCALL, _winapi_PeekNamedPipe__doc__}, + {"PeekNamedPipe", _PyCFunction_CAST(_winapi_PeekNamedPipe), METH_FASTCALL, _winapi_PeekNamedPipe__doc__}, static PyObject * _winapi_PeekNamedPipe_impl(PyObject *module, HANDLE handle, int size); @@ -840,13 +875,73 @@ exit: return return_value; } +PyDoc_STRVAR(_winapi_LCMapStringEx__doc__, +"LCMapStringEx($module, /, locale, flags, src)\n" +"--\n" +"\n"); + +#define _WINAPI_LCMAPSTRINGEX_METHODDEF \ + {"LCMapStringEx", _PyCFunction_CAST(_winapi_LCMapStringEx), METH_FASTCALL|METH_KEYWORDS, _winapi_LCMapStringEx__doc__}, + +static PyObject * +_winapi_LCMapStringEx_impl(PyObject *module, LPCWSTR locale, DWORD flags, + LPCWSTR src); + +static PyObject * +_winapi_LCMapStringEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(locale), &_Py_ID(flags), &_Py_ID(src), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"locale", "flags", "src", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "O&kO&:LCMapStringEx", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + LPCWSTR locale = NULL; + DWORD flags; + LPCWSTR src = NULL; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + _PyUnicode_WideCharString_Converter, &locale, &flags, _PyUnicode_WideCharString_Converter, &src)) { + goto exit; + } + return_value = _winapi_LCMapStringEx_impl(module, locale, flags, src); + +exit: + /* Cleanup for locale */ + PyMem_Free((void *)locale); + /* Cleanup for src */ + PyMem_Free((void *)src); + + return return_value; +} + PyDoc_STRVAR(_winapi_ReadFile__doc__, "ReadFile($module, /, handle, size, overlapped=False)\n" "--\n" "\n"); #define _WINAPI_READFILE_METHODDEF \ - {"ReadFile", (PyCFunction)(void(*)(void))_winapi_ReadFile, METH_FASTCALL|METH_KEYWORDS, _winapi_ReadFile__doc__}, + {"ReadFile", _PyCFunction_CAST(_winapi_ReadFile), METH_FASTCALL|METH_KEYWORDS, _winapi_ReadFile__doc__}, static PyObject * _winapi_ReadFile_impl(PyObject *module, HANDLE handle, DWORD size, @@ -856,8 +951,31 @@ static PyObject * _winapi_ReadFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(handle), &_Py_ID(size), &_Py_ID(overlapped), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"handle", "size", "overlapped", NULL}; - static _PyArg_Parser _parser = {"" F_HANDLE "k|i:ReadFile", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" F_HANDLE "k|p:ReadFile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE HANDLE handle; DWORD size; int use_overlapped = 0; @@ -879,7 +997,7 @@ PyDoc_STRVAR(_winapi_SetNamedPipeHandleState__doc__, "\n"); #define _WINAPI_SETNAMEDPIPEHANDLESTATE_METHODDEF \ - {"SetNamedPipeHandleState", (PyCFunction)(void(*)(void))_winapi_SetNamedPipeHandleState, METH_FASTCALL, _winapi_SetNamedPipeHandleState__doc__}, + {"SetNamedPipeHandleState", _PyCFunction_CAST(_winapi_SetNamedPipeHandleState), METH_FASTCALL, _winapi_SetNamedPipeHandleState__doc__}, static PyObject * _winapi_SetNamedPipeHandleState_impl(PyObject *module, HANDLE named_pipe, @@ -913,7 +1031,7 @@ PyDoc_STRVAR(_winapi_TerminateProcess__doc__, "Terminate the specified process and all of its threads."); #define _WINAPI_TERMINATEPROCESS_METHODDEF \ - {"TerminateProcess", (PyCFunction)(void(*)(void))_winapi_TerminateProcess, METH_FASTCALL, _winapi_TerminateProcess__doc__}, + {"TerminateProcess", _PyCFunction_CAST(_winapi_TerminateProcess), METH_FASTCALL, _winapi_TerminateProcess__doc__}, static PyObject * _winapi_TerminateProcess_impl(PyObject *module, HANDLE handle, @@ -973,7 +1091,7 @@ PyDoc_STRVAR(_winapi_WaitNamedPipe__doc__, "\n"); #define _WINAPI_WAITNAMEDPIPE_METHODDEF \ - {"WaitNamedPipe", (PyCFunction)(void(*)(void))_winapi_WaitNamedPipe, METH_FASTCALL, _winapi_WaitNamedPipe__doc__}, + {"WaitNamedPipe", _PyCFunction_CAST(_winapi_WaitNamedPipe), METH_FASTCALL, _winapi_WaitNamedPipe__doc__}, static PyObject * _winapi_WaitNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD timeout); @@ -1002,7 +1120,7 @@ PyDoc_STRVAR(_winapi_WaitForMultipleObjects__doc__, "\n"); #define _WINAPI_WAITFORMULTIPLEOBJECTS_METHODDEF \ - {"WaitForMultipleObjects", (PyCFunction)(void(*)(void))_winapi_WaitForMultipleObjects, METH_FASTCALL, _winapi_WaitForMultipleObjects__doc__}, + {"WaitForMultipleObjects", _PyCFunction_CAST(_winapi_WaitForMultipleObjects), METH_FASTCALL, _winapi_WaitForMultipleObjects__doc__}, static PyObject * _winapi_WaitForMultipleObjects_impl(PyObject *module, PyObject *handle_seq, @@ -1037,7 +1155,7 @@ PyDoc_STRVAR(_winapi_WaitForSingleObject__doc__, "in milliseconds."); #define _WINAPI_WAITFORSINGLEOBJECT_METHODDEF \ - {"WaitForSingleObject", (PyCFunction)(void(*)(void))_winapi_WaitForSingleObject, METH_FASTCALL, _winapi_WaitForSingleObject__doc__}, + {"WaitForSingleObject", _PyCFunction_CAST(_winapi_WaitForSingleObject), METH_FASTCALL, _winapi_WaitForSingleObject__doc__}, static long _winapi_WaitForSingleObject_impl(PyObject *module, HANDLE handle, @@ -1071,7 +1189,7 @@ PyDoc_STRVAR(_winapi_WriteFile__doc__, "\n"); #define _WINAPI_WRITEFILE_METHODDEF \ - {"WriteFile", (PyCFunction)(void(*)(void))_winapi_WriteFile, METH_FASTCALL|METH_KEYWORDS, _winapi_WriteFile__doc__}, + {"WriteFile", _PyCFunction_CAST(_winapi_WriteFile), METH_FASTCALL|METH_KEYWORDS, _winapi_WriteFile__doc__}, static PyObject * _winapi_WriteFile_impl(PyObject *module, HANDLE handle, PyObject *buffer, @@ -1081,8 +1199,31 @@ static PyObject * _winapi_WriteFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(handle), &_Py_ID(buffer), &_Py_ID(overlapped), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"handle", "buffer", "overlapped", NULL}; - static _PyArg_Parser _parser = {"" F_HANDLE "O|i:WriteFile", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" F_HANDLE "O|p:WriteFile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE HANDLE handle; PyObject *buffer; int use_overlapped = 0; @@ -1121,7 +1262,7 @@ PyDoc_STRVAR(_winapi_GetFileType__doc__, "\n"); #define _WINAPI_GETFILETYPE_METHODDEF \ - {"GetFileType", (PyCFunction)(void(*)(void))_winapi_GetFileType, METH_FASTCALL|METH_KEYWORDS, _winapi_GetFileType__doc__}, + {"GetFileType", _PyCFunction_CAST(_winapi_GetFileType), METH_FASTCALL|METH_KEYWORDS, _winapi_GetFileType__doc__}, static DWORD _winapi_GetFileType_impl(PyObject *module, HANDLE handle); @@ -1130,8 +1271,31 @@ static PyObject * _winapi_GetFileType(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(handle), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"handle", NULL}; - static _PyArg_Parser _parser = {"" F_HANDLE ":GetFileType", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" F_HANDLE ":GetFileType", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE HANDLE handle; DWORD _return_value; @@ -1159,7 +1323,7 @@ PyDoc_STRVAR(_winapi__mimetypes_read_windows_registry__doc__, "MimeTypes.add_type."); #define _WINAPI__MIMETYPES_READ_WINDOWS_REGISTRY_METHODDEF \ - {"_mimetypes_read_windows_registry", (PyCFunction)(void(*)(void))_winapi__mimetypes_read_windows_registry, METH_FASTCALL|METH_KEYWORDS, _winapi__mimetypes_read_windows_registry__doc__}, + {"_mimetypes_read_windows_registry", _PyCFunction_CAST(_winapi__mimetypes_read_windows_registry), METH_FASTCALL|METH_KEYWORDS, _winapi__mimetypes_read_windows_registry__doc__}, static PyObject * _winapi__mimetypes_read_windows_registry_impl(PyObject *module, @@ -1169,8 +1333,31 @@ static PyObject * _winapi__mimetypes_read_windows_registry(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(on_type_read), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"on_type_read", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_mimetypes_read_windows_registry", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_mimetypes_read_windows_registry", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *on_type_read; @@ -1184,4 +1371,4 @@ _winapi__mimetypes_read_windows_registry(PyObject *module, PyObject *const *args exit: return return_value; } -/*[clinic end generated code: output=ac3623be6e42017c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=edb1a9d1bbfd6394 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_zoneinfo.c.h b/Modules/clinic/_zoneinfo.c.h new file mode 100644 index 00000000000..78fcbfa9411 --- /dev/null +++ b/Modules/clinic/_zoneinfo.c.h @@ -0,0 +1,188 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(zoneinfo_ZoneInfo_from_file__doc__, +"from_file($type, file_obj, /, key=None)\n" +"--\n" +"\n" +"Create a ZoneInfo file from a file object."); + +#define ZONEINFO_ZONEINFO_FROM_FILE_METHODDEF \ + {"from_file", _PyCFunction_CAST(zoneinfo_ZoneInfo_from_file), METH_FASTCALL|METH_KEYWORDS|METH_CLASS, zoneinfo_ZoneInfo_from_file__doc__}, + +static PyObject * +zoneinfo_ZoneInfo_from_file_impl(PyTypeObject *type, PyObject *file_obj, + PyObject *key); + +static PyObject * +zoneinfo_ZoneInfo_from_file(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "key", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "from_file", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *file_obj; + PyObject *key = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + file_obj = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + key = args[1]; +skip_optional_pos: + return_value = zoneinfo_ZoneInfo_from_file_impl(type, file_obj, key); + +exit: + return return_value; +} + +PyDoc_STRVAR(zoneinfo_ZoneInfo_no_cache__doc__, +"no_cache($type, /, key)\n" +"--\n" +"\n" +"Get a new instance of ZoneInfo, bypassing the cache."); + +#define ZONEINFO_ZONEINFO_NO_CACHE_METHODDEF \ + {"no_cache", _PyCFunction_CAST(zoneinfo_ZoneInfo_no_cache), METH_FASTCALL|METH_KEYWORDS|METH_CLASS, zoneinfo_ZoneInfo_no_cache__doc__}, + +static PyObject * +zoneinfo_ZoneInfo_no_cache_impl(PyTypeObject *type, PyObject *key); + +static PyObject * +zoneinfo_ZoneInfo_no_cache(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"key", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "no_cache", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *key; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + key = args[0]; + return_value = zoneinfo_ZoneInfo_no_cache_impl(type, key); + +exit: + return return_value; +} + +PyDoc_STRVAR(zoneinfo_ZoneInfo_clear_cache__doc__, +"clear_cache($type, /, *, only_keys=None)\n" +"--\n" +"\n" +"Clear the ZoneInfo cache."); + +#define ZONEINFO_ZONEINFO_CLEAR_CACHE_METHODDEF \ + {"clear_cache", _PyCFunction_CAST(zoneinfo_ZoneInfo_clear_cache), METH_FASTCALL|METH_KEYWORDS|METH_CLASS, zoneinfo_ZoneInfo_clear_cache__doc__}, + +static PyObject * +zoneinfo_ZoneInfo_clear_cache_impl(PyTypeObject *type, PyObject *only_keys); + +static PyObject * +zoneinfo_ZoneInfo_clear_cache(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(only_keys), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"only_keys", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "clear_cache", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *only_keys = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + only_keys = args[0]; +skip_optional_kwonly: + return_value = zoneinfo_ZoneInfo_clear_cache_impl(type, only_keys); + +exit: + return return_value; +} +/*[clinic end generated code: output=d2da73ef66146b83 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h index c46cc738de9..e68c3920072 100644 --- a/Modules/clinic/arraymodule.c.h +++ b/Modules/clinic/arraymodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(array_array___copy____doc__, "__copy__($self, /)\n" "--\n" @@ -47,7 +53,7 @@ PyDoc_STRVAR(array_array_index__doc__, "Raise ValueError if the value is not present."); #define ARRAY_ARRAY_INDEX_METHODDEF \ - {"index", (PyCFunction)(void(*)(void))array_array_index, METH_FASTCALL, array_array_index__doc__}, + {"index", _PyCFunction_CAST(array_array_index), METH_FASTCALL, array_array_index__doc__}, static PyObject * array_array_index_impl(arrayobject *self, PyObject *v, Py_ssize_t start, @@ -102,7 +108,7 @@ PyDoc_STRVAR(array_array_pop__doc__, "i defaults to -1."); #define ARRAY_ARRAY_POP_METHODDEF \ - {"pop", (PyCFunction)(void(*)(void))array_array_pop, METH_FASTCALL, array_array_pop__doc__}, + {"pop", _PyCFunction_CAST(array_array_pop), METH_FASTCALL, array_array_pop__doc__}, static PyObject * array_array_pop_impl(arrayobject *self, Py_ssize_t i); @@ -145,7 +151,7 @@ PyDoc_STRVAR(array_array_extend__doc__, "Append items to the end of the array."); #define ARRAY_ARRAY_EXTEND_METHODDEF \ - {"extend", (PyCFunction)(void(*)(void))array_array_extend, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, array_array_extend__doc__}, + {"extend", _PyCFunction_CAST(array_array_extend), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, array_array_extend__doc__}, static PyObject * array_array_extend_impl(arrayobject *self, PyTypeObject *cls, PyObject *bb); @@ -154,14 +160,27 @@ static PyObject * array_array_extend(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"O:extend", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "extend", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; PyObject *bb; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &bb)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { goto exit; } + bb = args[0]; return_value = array_array_extend_impl(self, cls, bb); exit: @@ -175,7 +194,7 @@ PyDoc_STRVAR(array_array_insert__doc__, "Insert a new item v into the array before position i."); #define ARRAY_ARRAY_INSERT_METHODDEF \ - {"insert", (PyCFunction)(void(*)(void))array_array_insert, METH_FASTCALL, array_array_insert__doc__}, + {"insert", _PyCFunction_CAST(array_array_insert), METH_FASTCALL, array_array_insert__doc__}, static PyObject * array_array_insert_impl(arrayobject *self, Py_ssize_t i, PyObject *v); @@ -285,19 +304,35 @@ PyDoc_STRVAR(array_array_fromfile__doc__, "Read n objects from the file object f and append them to the end of the array."); #define ARRAY_ARRAY_FROMFILE_METHODDEF \ - {"fromfile", (PyCFunction)(void(*)(void))array_array_fromfile, METH_FASTCALL, array_array_fromfile__doc__}, + {"fromfile", _PyCFunction_CAST(array_array_fromfile), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, array_array_fromfile__doc__}, static PyObject * -array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n); +array_array_fromfile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f, + Py_ssize_t n); static PyObject * -array_array_fromfile(arrayobject *self, PyObject *const *args, Py_ssize_t nargs) +array_array_fromfile(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", "", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fromfile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; PyObject *f; Py_ssize_t n; - if (!_PyArg_CheckPositional("fromfile", nargs, 2, 2)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { goto exit; } f = args[0]; @@ -313,7 +348,7 @@ array_array_fromfile(arrayobject *self, PyObject *const *args, Py_ssize_t nargs) } n = ival; } - return_value = array_array_fromfile_impl(self, f, n); + return_value = array_array_fromfile_impl(self, cls, f, n); exit: return return_value; @@ -326,7 +361,41 @@ PyDoc_STRVAR(array_array_tofile__doc__, "Write all items (as machine values) to the file object f."); #define ARRAY_ARRAY_TOFILE_METHODDEF \ - {"tofile", (PyCFunction)array_array_tofile, METH_O, array_array_tofile__doc__}, + {"tofile", _PyCFunction_CAST(array_array_tofile), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, array_array_tofile__doc__}, + +static PyObject * +array_array_tofile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f); + +static PyObject * +array_array_tofile(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "tofile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *f; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + f = args[0]; + return_value = array_array_tofile_impl(self, cls, f); + +exit: + return return_value; +} PyDoc_STRVAR(array_array_fromlist__doc__, "fromlist($self, list, /)\n" @@ -493,7 +562,7 @@ PyDoc_STRVAR(array__array_reconstructor__doc__, "Internal. Used for pickling support."); #define ARRAY__ARRAY_RECONSTRUCTOR_METHODDEF \ - {"_array_reconstructor", (PyCFunction)(void(*)(void))array__array_reconstructor, METH_FASTCALL, array__array_reconstructor__doc__}, + {"_array_reconstructor", _PyCFunction_CAST(array__array_reconstructor), METH_FASTCALL, array__array_reconstructor__doc__}, static PyObject * array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, @@ -544,7 +613,42 @@ PyDoc_STRVAR(array_array___reduce_ex____doc__, "Return state information for pickling."); #define ARRAY_ARRAY___REDUCE_EX___METHODDEF \ - {"__reduce_ex__", (PyCFunction)array_array___reduce_ex__, METH_O, array_array___reduce_ex____doc__}, + {"__reduce_ex__", _PyCFunction_CAST(array_array___reduce_ex__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, array_array___reduce_ex____doc__}, + +static PyObject * +array_array___reduce_ex___impl(arrayobject *self, PyTypeObject *cls, + PyObject *value); + +static PyObject * +array_array___reduce_ex__(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__reduce_ex__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + value = args[0]; + return_value = array_array___reduce_ex___impl(self, cls, value); + +exit: + return return_value; +} PyDoc_STRVAR(array_arrayiterator___reduce____doc__, "__reduce__($self, /)\n" @@ -553,15 +657,19 @@ PyDoc_STRVAR(array_arrayiterator___reduce____doc__, "Return state information for pickling."); #define ARRAY_ARRAYITERATOR___REDUCE___METHODDEF \ - {"__reduce__", (PyCFunction)array_arrayiterator___reduce__, METH_NOARGS, array_arrayiterator___reduce____doc__}, + {"__reduce__", _PyCFunction_CAST(array_arrayiterator___reduce__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, array_arrayiterator___reduce____doc__}, static PyObject * -array_arrayiterator___reduce___impl(arrayiterobject *self); +array_arrayiterator___reduce___impl(arrayiterobject *self, PyTypeObject *cls); static PyObject * -array_arrayiterator___reduce__(arrayiterobject *self, PyObject *Py_UNUSED(ignored)) +array_arrayiterator___reduce__(arrayiterobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return array_arrayiterator___reduce___impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "__reduce__() takes no arguments"); + return NULL; + } + return array_arrayiterator___reduce___impl(self, cls); } PyDoc_STRVAR(array_arrayiterator___setstate____doc__, @@ -572,4 +680,4 @@ PyDoc_STRVAR(array_arrayiterator___setstate____doc__, #define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF \ {"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O, array_arrayiterator___setstate____doc__}, -/*[clinic end generated code: output=f130a994f98f1227 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=69bc1451f7bda234 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/audioop.c.h b/Modules/clinic/audioop.c.h index da12bd17b5a..1a7ccf8b828 100644 --- a/Modules/clinic/audioop.c.h +++ b/Modules/clinic/audioop.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(audioop_getsample__doc__, "getsample($module, fragment, width, index, /)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(audioop_getsample__doc__, "Return the value of sample index from the fragment."); #define AUDIOOP_GETSAMPLE_METHODDEF \ - {"getsample", (PyCFunction)(void(*)(void))audioop_getsample, METH_FASTCALL, audioop_getsample__doc__}, + {"getsample", _PyCFunction_CAST(audioop_getsample), METH_FASTCALL, audioop_getsample__doc__}, static PyObject * audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width, @@ -67,7 +73,7 @@ PyDoc_STRVAR(audioop_max__doc__, "Return the maximum of the absolute value of all samples in a fragment."); #define AUDIOOP_MAX_METHODDEF \ - {"max", (PyCFunction)(void(*)(void))audioop_max, METH_FASTCALL, audioop_max__doc__}, + {"max", _PyCFunction_CAST(audioop_max), METH_FASTCALL, audioop_max__doc__}, static PyObject * audioop_max_impl(PyObject *module, Py_buffer *fragment, int width); @@ -111,7 +117,7 @@ PyDoc_STRVAR(audioop_minmax__doc__, "Return the minimum and maximum values of all samples in the sound fragment."); #define AUDIOOP_MINMAX_METHODDEF \ - {"minmax", (PyCFunction)(void(*)(void))audioop_minmax, METH_FASTCALL, audioop_minmax__doc__}, + {"minmax", _PyCFunction_CAST(audioop_minmax), METH_FASTCALL, audioop_minmax__doc__}, static PyObject * audioop_minmax_impl(PyObject *module, Py_buffer *fragment, int width); @@ -155,7 +161,7 @@ PyDoc_STRVAR(audioop_avg__doc__, "Return the average over all samples in the fragment."); #define AUDIOOP_AVG_METHODDEF \ - {"avg", (PyCFunction)(void(*)(void))audioop_avg, METH_FASTCALL, audioop_avg__doc__}, + {"avg", _PyCFunction_CAST(audioop_avg), METH_FASTCALL, audioop_avg__doc__}, static PyObject * audioop_avg_impl(PyObject *module, Py_buffer *fragment, int width); @@ -199,7 +205,7 @@ PyDoc_STRVAR(audioop_rms__doc__, "Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n)."); #define AUDIOOP_RMS_METHODDEF \ - {"rms", (PyCFunction)(void(*)(void))audioop_rms, METH_FASTCALL, audioop_rms__doc__}, + {"rms", _PyCFunction_CAST(audioop_rms), METH_FASTCALL, audioop_rms__doc__}, static PyObject * audioop_rms_impl(PyObject *module, Py_buffer *fragment, int width); @@ -243,7 +249,7 @@ PyDoc_STRVAR(audioop_findfit__doc__, "Try to match reference as well as possible to a portion of fragment."); #define AUDIOOP_FINDFIT_METHODDEF \ - {"findfit", (PyCFunction)(void(*)(void))audioop_findfit, METH_FASTCALL, audioop_findfit__doc__}, + {"findfit", _PyCFunction_CAST(audioop_findfit), METH_FASTCALL, audioop_findfit__doc__}, static PyObject * audioop_findfit_impl(PyObject *module, Py_buffer *fragment, @@ -295,7 +301,7 @@ PyDoc_STRVAR(audioop_findfactor__doc__, "Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal."); #define AUDIOOP_FINDFACTOR_METHODDEF \ - {"findfactor", (PyCFunction)(void(*)(void))audioop_findfactor, METH_FASTCALL, audioop_findfactor__doc__}, + {"findfactor", _PyCFunction_CAST(audioop_findfactor), METH_FASTCALL, audioop_findfactor__doc__}, static PyObject * audioop_findfactor_impl(PyObject *module, Py_buffer *fragment, @@ -347,7 +353,7 @@ PyDoc_STRVAR(audioop_findmax__doc__, "Search fragment for a slice of specified number of samples with maximum energy."); #define AUDIOOP_FINDMAX_METHODDEF \ - {"findmax", (PyCFunction)(void(*)(void))audioop_findmax, METH_FASTCALL, audioop_findmax__doc__}, + {"findmax", _PyCFunction_CAST(audioop_findmax), METH_FASTCALL, audioop_findmax__doc__}, static PyObject * audioop_findmax_impl(PyObject *module, Py_buffer *fragment, @@ -400,7 +406,7 @@ PyDoc_STRVAR(audioop_avgpp__doc__, "Return the average peak-peak value over all samples in the fragment."); #define AUDIOOP_AVGPP_METHODDEF \ - {"avgpp", (PyCFunction)(void(*)(void))audioop_avgpp, METH_FASTCALL, audioop_avgpp__doc__}, + {"avgpp", _PyCFunction_CAST(audioop_avgpp), METH_FASTCALL, audioop_avgpp__doc__}, static PyObject * audioop_avgpp_impl(PyObject *module, Py_buffer *fragment, int width); @@ -444,7 +450,7 @@ PyDoc_STRVAR(audioop_maxpp__doc__, "Return the maximum peak-peak value in the sound fragment."); #define AUDIOOP_MAXPP_METHODDEF \ - {"maxpp", (PyCFunction)(void(*)(void))audioop_maxpp, METH_FASTCALL, audioop_maxpp__doc__}, + {"maxpp", _PyCFunction_CAST(audioop_maxpp), METH_FASTCALL, audioop_maxpp__doc__}, static PyObject * audioop_maxpp_impl(PyObject *module, Py_buffer *fragment, int width); @@ -488,7 +494,7 @@ PyDoc_STRVAR(audioop_cross__doc__, "Return the number of zero crossings in the fragment passed as an argument."); #define AUDIOOP_CROSS_METHODDEF \ - {"cross", (PyCFunction)(void(*)(void))audioop_cross, METH_FASTCALL, audioop_cross__doc__}, + {"cross", _PyCFunction_CAST(audioop_cross), METH_FASTCALL, audioop_cross__doc__}, static PyObject * audioop_cross_impl(PyObject *module, Py_buffer *fragment, int width); @@ -532,7 +538,7 @@ PyDoc_STRVAR(audioop_mul__doc__, "Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor."); #define AUDIOOP_MUL_METHODDEF \ - {"mul", (PyCFunction)(void(*)(void))audioop_mul, METH_FASTCALL, audioop_mul__doc__}, + {"mul", _PyCFunction_CAST(audioop_mul), METH_FASTCALL, audioop_mul__doc__}, static PyObject * audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width, @@ -588,7 +594,7 @@ PyDoc_STRVAR(audioop_tomono__doc__, "Convert a stereo fragment to a mono fragment."); #define AUDIOOP_TOMONO_METHODDEF \ - {"tomono", (PyCFunction)(void(*)(void))audioop_tomono, METH_FASTCALL, audioop_tomono__doc__}, + {"tomono", _PyCFunction_CAST(audioop_tomono), METH_FASTCALL, audioop_tomono__doc__}, static PyObject * audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width, @@ -655,7 +661,7 @@ PyDoc_STRVAR(audioop_tostereo__doc__, "Generate a stereo fragment from a mono fragment."); #define AUDIOOP_TOSTEREO_METHODDEF \ - {"tostereo", (PyCFunction)(void(*)(void))audioop_tostereo, METH_FASTCALL, audioop_tostereo__doc__}, + {"tostereo", _PyCFunction_CAST(audioop_tostereo), METH_FASTCALL, audioop_tostereo__doc__}, static PyObject * audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width, @@ -722,7 +728,7 @@ PyDoc_STRVAR(audioop_add__doc__, "Return a fragment which is the addition of the two samples passed as parameters."); #define AUDIOOP_ADD_METHODDEF \ - {"add", (PyCFunction)(void(*)(void))audioop_add, METH_FASTCALL, audioop_add__doc__}, + {"add", _PyCFunction_CAST(audioop_add), METH_FASTCALL, audioop_add__doc__}, static PyObject * audioop_add_impl(PyObject *module, Py_buffer *fragment1, @@ -779,7 +785,7 @@ PyDoc_STRVAR(audioop_bias__doc__, "Return a fragment that is the original fragment with a bias added to each sample."); #define AUDIOOP_BIAS_METHODDEF \ - {"bias", (PyCFunction)(void(*)(void))audioop_bias, METH_FASTCALL, audioop_bias__doc__}, + {"bias", _PyCFunction_CAST(audioop_bias), METH_FASTCALL, audioop_bias__doc__}, static PyObject * audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias); @@ -828,7 +834,7 @@ PyDoc_STRVAR(audioop_reverse__doc__, "Reverse the samples in a fragment and returns the modified fragment."); #define AUDIOOP_REVERSE_METHODDEF \ - {"reverse", (PyCFunction)(void(*)(void))audioop_reverse, METH_FASTCALL, audioop_reverse__doc__}, + {"reverse", _PyCFunction_CAST(audioop_reverse), METH_FASTCALL, audioop_reverse__doc__}, static PyObject * audioop_reverse_impl(PyObject *module, Py_buffer *fragment, int width); @@ -872,7 +878,7 @@ PyDoc_STRVAR(audioop_byteswap__doc__, "Convert big-endian samples to little-endian and vice versa."); #define AUDIOOP_BYTESWAP_METHODDEF \ - {"byteswap", (PyCFunction)(void(*)(void))audioop_byteswap, METH_FASTCALL, audioop_byteswap__doc__}, + {"byteswap", _PyCFunction_CAST(audioop_byteswap), METH_FASTCALL, audioop_byteswap__doc__}, static PyObject * audioop_byteswap_impl(PyObject *module, Py_buffer *fragment, int width); @@ -916,7 +922,7 @@ PyDoc_STRVAR(audioop_lin2lin__doc__, "Convert samples between 1-, 2-, 3- and 4-byte formats."); #define AUDIOOP_LIN2LIN_METHODDEF \ - {"lin2lin", (PyCFunction)(void(*)(void))audioop_lin2lin, METH_FASTCALL, audioop_lin2lin__doc__}, + {"lin2lin", _PyCFunction_CAST(audioop_lin2lin), METH_FASTCALL, audioop_lin2lin__doc__}, static PyObject * audioop_lin2lin_impl(PyObject *module, Py_buffer *fragment, int width, @@ -967,7 +973,7 @@ PyDoc_STRVAR(audioop_ratecv__doc__, "Convert the frame rate of the input fragment."); #define AUDIOOP_RATECV_METHODDEF \ - {"ratecv", (PyCFunction)(void(*)(void))audioop_ratecv, METH_FASTCALL, audioop_ratecv__doc__}, + {"ratecv", _PyCFunction_CAST(audioop_ratecv), METH_FASTCALL, audioop_ratecv__doc__}, static PyObject * audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, @@ -1047,7 +1053,7 @@ PyDoc_STRVAR(audioop_lin2ulaw__doc__, "Convert samples in the audio fragment to u-LAW encoding."); #define AUDIOOP_LIN2ULAW_METHODDEF \ - {"lin2ulaw", (PyCFunction)(void(*)(void))audioop_lin2ulaw, METH_FASTCALL, audioop_lin2ulaw__doc__}, + {"lin2ulaw", _PyCFunction_CAST(audioop_lin2ulaw), METH_FASTCALL, audioop_lin2ulaw__doc__}, static PyObject * audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width); @@ -1091,7 +1097,7 @@ PyDoc_STRVAR(audioop_ulaw2lin__doc__, "Convert sound fragments in u-LAW encoding to linearly encoded sound fragments."); #define AUDIOOP_ULAW2LIN_METHODDEF \ - {"ulaw2lin", (PyCFunction)(void(*)(void))audioop_ulaw2lin, METH_FASTCALL, audioop_ulaw2lin__doc__}, + {"ulaw2lin", _PyCFunction_CAST(audioop_ulaw2lin), METH_FASTCALL, audioop_ulaw2lin__doc__}, static PyObject * audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width); @@ -1135,7 +1141,7 @@ PyDoc_STRVAR(audioop_lin2alaw__doc__, "Convert samples in the audio fragment to a-LAW encoding."); #define AUDIOOP_LIN2ALAW_METHODDEF \ - {"lin2alaw", (PyCFunction)(void(*)(void))audioop_lin2alaw, METH_FASTCALL, audioop_lin2alaw__doc__}, + {"lin2alaw", _PyCFunction_CAST(audioop_lin2alaw), METH_FASTCALL, audioop_lin2alaw__doc__}, static PyObject * audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width); @@ -1179,7 +1185,7 @@ PyDoc_STRVAR(audioop_alaw2lin__doc__, "Convert sound fragments in a-LAW encoding to linearly encoded sound fragments."); #define AUDIOOP_ALAW2LIN_METHODDEF \ - {"alaw2lin", (PyCFunction)(void(*)(void))audioop_alaw2lin, METH_FASTCALL, audioop_alaw2lin__doc__}, + {"alaw2lin", _PyCFunction_CAST(audioop_alaw2lin), METH_FASTCALL, audioop_alaw2lin__doc__}, static PyObject * audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width); @@ -1223,7 +1229,7 @@ PyDoc_STRVAR(audioop_lin2adpcm__doc__, "Convert samples to 4 bit Intel/DVI ADPCM encoding."); #define AUDIOOP_LIN2ADPCM_METHODDEF \ - {"lin2adpcm", (PyCFunction)(void(*)(void))audioop_lin2adpcm, METH_FASTCALL, audioop_lin2adpcm__doc__}, + {"lin2adpcm", _PyCFunction_CAST(audioop_lin2adpcm), METH_FASTCALL, audioop_lin2adpcm__doc__}, static PyObject * audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width, @@ -1270,7 +1276,7 @@ PyDoc_STRVAR(audioop_adpcm2lin__doc__, "Decode an Intel/DVI ADPCM coded fragment to a linear fragment."); #define AUDIOOP_ADPCM2LIN_METHODDEF \ - {"adpcm2lin", (PyCFunction)(void(*)(void))audioop_adpcm2lin, METH_FASTCALL, audioop_adpcm2lin__doc__}, + {"adpcm2lin", _PyCFunction_CAST(audioop_adpcm2lin), METH_FASTCALL, audioop_adpcm2lin__doc__}, static PyObject * audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width, @@ -1309,4 +1315,4 @@ exit: return return_value; } -/*[clinic end generated code: output=840f8c315ebd4946 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9a7e36f1179f0223 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h index a0ca6d60ce9..63566dfb10e 100644 --- a/Modules/clinic/binascii.c.h +++ b/Modules/clinic/binascii.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(binascii_a2b_uu__doc__, "a2b_uu($module, data, /)\n" "--\n" @@ -40,7 +46,7 @@ PyDoc_STRVAR(binascii_b2a_uu__doc__, "Uuencode line of data."); #define BINASCII_B2A_UU_METHODDEF \ - {"b2a_uu", (PyCFunction)(void(*)(void))binascii_b2a_uu, METH_FASTCALL|METH_KEYWORDS, binascii_b2a_uu__doc__}, + {"b2a_uu", _PyCFunction_CAST(binascii_b2a_uu), METH_FASTCALL|METH_KEYWORDS, binascii_b2a_uu__doc__}, static PyObject * binascii_b2a_uu_impl(PyObject *module, Py_buffer *data, int backtick); @@ -49,8 +55,31 @@ static PyObject * binascii_b2a_uu(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(backtick), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "backtick", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "b2a_uu", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "b2a_uu", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -70,8 +99,8 @@ binascii_b2a_uu(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (!noptargs) { goto skip_optional_kwonly; } - backtick = _PyLong_AsInt(args[1]); - if (backtick == -1 && PyErr_Occurred()) { + backtick = PyObject_IsTrue(args[1]); + if (backtick < 0) { goto exit; } skip_optional_kwonly: @@ -97,7 +126,7 @@ PyDoc_STRVAR(binascii_a2b_base64__doc__, " The same applies to excess data after padding (= / ==)."); #define BINASCII_A2B_BASE64_METHODDEF \ - {"a2b_base64", (PyCFunction)(void(*)(void))binascii_a2b_base64, METH_FASTCALL|METH_KEYWORDS, binascii_a2b_base64__doc__}, + {"a2b_base64", _PyCFunction_CAST(binascii_a2b_base64), METH_FASTCALL|METH_KEYWORDS, binascii_a2b_base64__doc__}, static PyObject * binascii_a2b_base64_impl(PyObject *module, Py_buffer *data, int strict_mode); @@ -106,8 +135,31 @@ static PyObject * binascii_a2b_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(strict_mode), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "strict_mode", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "a2b_base64", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "a2b_base64", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -123,8 +175,8 @@ binascii_a2b_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P if (!noptargs) { goto skip_optional_kwonly; } - strict_mode = _PyLong_AsInt(args[1]); - if (strict_mode == -1 && PyErr_Occurred()) { + strict_mode = PyObject_IsTrue(args[1]); + if (strict_mode < 0) { goto exit; } skip_optional_kwonly: @@ -145,7 +197,7 @@ PyDoc_STRVAR(binascii_b2a_base64__doc__, "Base64-code line of data."); #define BINASCII_B2A_BASE64_METHODDEF \ - {"b2a_base64", (PyCFunction)(void(*)(void))binascii_b2a_base64, METH_FASTCALL|METH_KEYWORDS, binascii_b2a_base64__doc__}, + {"b2a_base64", _PyCFunction_CAST(binascii_b2a_base64), METH_FASTCALL|METH_KEYWORDS, binascii_b2a_base64__doc__}, static PyObject * binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline); @@ -154,8 +206,31 @@ static PyObject * binascii_b2a_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(newline), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "newline", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "b2a_base64", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "b2a_base64", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -175,8 +250,8 @@ binascii_b2a_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P if (!noptargs) { goto skip_optional_kwonly; } - newline = _PyLong_AsInt(args[1]); - if (newline == -1 && PyErr_Occurred()) { + newline = PyObject_IsTrue(args[1]); + if (newline < 0) { goto exit; } skip_optional_kwonly: @@ -198,7 +273,7 @@ PyDoc_STRVAR(binascii_crc_hqx__doc__, "Compute CRC-CCITT incrementally."); #define BINASCII_CRC_HQX_METHODDEF \ - {"crc_hqx", (PyCFunction)(void(*)(void))binascii_crc_hqx, METH_FASTCALL, binascii_crc_hqx__doc__}, + {"crc_hqx", _PyCFunction_CAST(binascii_crc_hqx), METH_FASTCALL, binascii_crc_hqx__doc__}, static PyObject * binascii_crc_hqx_impl(PyObject *module, Py_buffer *data, unsigned int crc); @@ -242,7 +317,7 @@ PyDoc_STRVAR(binascii_crc32__doc__, "Compute CRC-32 incrementally."); #define BINASCII_CRC32_METHODDEF \ - {"crc32", (PyCFunction)(void(*)(void))binascii_crc32, METH_FASTCALL, binascii_crc32__doc__}, + {"crc32", _PyCFunction_CAST(binascii_crc32), METH_FASTCALL, binascii_crc32__doc__}, static unsigned int binascii_crc32_impl(PyObject *module, Py_buffer *data, unsigned int crc); @@ -312,7 +387,7 @@ PyDoc_STRVAR(binascii_b2a_hex__doc__, "b\'b9_01ef\'"); #define BINASCII_B2A_HEX_METHODDEF \ - {"b2a_hex", (PyCFunction)(void(*)(void))binascii_b2a_hex, METH_FASTCALL|METH_KEYWORDS, binascii_b2a_hex__doc__}, + {"b2a_hex", _PyCFunction_CAST(binascii_b2a_hex), METH_FASTCALL|METH_KEYWORDS, binascii_b2a_hex__doc__}, static PyObject * binascii_b2a_hex_impl(PyObject *module, Py_buffer *data, PyObject *sep, @@ -322,8 +397,31 @@ static PyObject * binascii_b2a_hex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"data", "sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "b2a_hex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "b2a_hex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -382,7 +480,7 @@ PyDoc_STRVAR(binascii_hexlify__doc__, "available as \"b2a_hex()\"."); #define BINASCII_HEXLIFY_METHODDEF \ - {"hexlify", (PyCFunction)(void(*)(void))binascii_hexlify, METH_FASTCALL|METH_KEYWORDS, binascii_hexlify__doc__}, + {"hexlify", _PyCFunction_CAST(binascii_hexlify), METH_FASTCALL|METH_KEYWORDS, binascii_hexlify__doc__}, static PyObject * binascii_hexlify_impl(PyObject *module, Py_buffer *data, PyObject *sep, @@ -392,8 +490,31 @@ static PyObject * binascii_hexlify(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"data", "sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hexlify", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hexlify", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -510,7 +631,7 @@ PyDoc_STRVAR(binascii_a2b_qp__doc__, "Decode a string of qp-encoded data."); #define BINASCII_A2B_QP_METHODDEF \ - {"a2b_qp", (PyCFunction)(void(*)(void))binascii_a2b_qp, METH_FASTCALL|METH_KEYWORDS, binascii_a2b_qp__doc__}, + {"a2b_qp", _PyCFunction_CAST(binascii_a2b_qp), METH_FASTCALL|METH_KEYWORDS, binascii_a2b_qp__doc__}, static PyObject * binascii_a2b_qp_impl(PyObject *module, Py_buffer *data, int header); @@ -519,8 +640,31 @@ static PyObject * binascii_a2b_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(header), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"data", "header", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "a2b_qp", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "a2b_qp", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -536,8 +680,8 @@ binascii_a2b_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (!noptargs) { goto skip_optional_pos; } - header = _PyLong_AsInt(args[1]); - if (header == -1 && PyErr_Occurred()) { + header = PyObject_IsTrue(args[1]); + if (header < 0) { goto exit; } skip_optional_pos: @@ -562,7 +706,7 @@ PyDoc_STRVAR(binascii_b2a_qp__doc__, "are both encoded. When quotetabs is set, space and tabs are encoded."); #define BINASCII_B2A_QP_METHODDEF \ - {"b2a_qp", (PyCFunction)(void(*)(void))binascii_b2a_qp, METH_FASTCALL|METH_KEYWORDS, binascii_b2a_qp__doc__}, + {"b2a_qp", _PyCFunction_CAST(binascii_b2a_qp), METH_FASTCALL|METH_KEYWORDS, binascii_b2a_qp__doc__}, static PyObject * binascii_b2a_qp_impl(PyObject *module, Py_buffer *data, int quotetabs, @@ -572,8 +716,31 @@ static PyObject * binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(quotetabs), &_Py_ID(istext), &_Py_ID(header), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"data", "quotetabs", "istext", "header", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "b2a_qp", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "b2a_qp", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -596,8 +763,8 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto skip_optional_pos; } if (args[1]) { - quotetabs = _PyLong_AsInt(args[1]); - if (quotetabs == -1 && PyErr_Occurred()) { + quotetabs = PyObject_IsTrue(args[1]); + if (quotetabs < 0) { goto exit; } if (!--noptargs) { @@ -605,16 +772,16 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } } if (args[2]) { - istext = _PyLong_AsInt(args[2]); - if (istext == -1 && PyErr_Occurred()) { + istext = PyObject_IsTrue(args[2]); + if (istext < 0) { goto exit; } if (!--noptargs) { goto skip_optional_pos; } } - header = _PyLong_AsInt(args[3]); - if (header == -1 && PyErr_Occurred()) { + header = PyObject_IsTrue(args[3]); + if (header < 0) { goto exit; } skip_optional_pos: @@ -628,4 +795,4 @@ exit: return return_value; } -/*[clinic end generated code: output=4162d08536697182 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ab156917c9db79d2 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/cmathmodule.c.h b/Modules/clinic/cmathmodule.c.h index 4b6653aa219..bc91c20f373 100644 --- a/Modules/clinic/cmathmodule.c.h +++ b/Modules/clinic/cmathmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(cmath_acos__doc__, "acos($module, z, /)\n" "--\n" @@ -633,15 +639,16 @@ exit: } PyDoc_STRVAR(cmath_log__doc__, -"log($module, z, base=, /)\n" +"log($module, z, base=None, /)\n" "--\n" "\n" "log(z[, base]) -> the logarithm of z to the given base.\n" "\n" -"If the base not specified, returns the natural logarithm (base e) of z."); +"If the base is not specified or is None, returns the\n" +"natural logarithm (base e) of z."); #define CMATH_LOG_METHODDEF \ - {"log", (PyCFunction)(void(*)(void))cmath_log, METH_FASTCALL, cmath_log__doc__}, + {"log", _PyCFunction_CAST(cmath_log), METH_FASTCALL, cmath_log__doc__}, static PyObject * cmath_log_impl(PyObject *module, Py_complex x, PyObject *y_obj); @@ -651,7 +658,7 @@ cmath_log(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_complex x; - PyObject *y_obj = NULL; + PyObject *y_obj = Py_None; if (!_PyArg_CheckPositional("log", nargs, 1, 2)) { goto exit; @@ -736,7 +743,7 @@ PyDoc_STRVAR(cmath_rect__doc__, "Convert from polar coordinates to rectangular coordinates."); #define CMATH_RECT_METHODDEF \ - {"rect", (PyCFunction)(void(*)(void))cmath_rect, METH_FASTCALL, cmath_rect__doc__}, + {"rect", _PyCFunction_CAST(cmath_rect), METH_FASTCALL, cmath_rect__doc__}, static PyObject * cmath_rect_impl(PyObject *module, double r, double phi); @@ -883,7 +890,7 @@ PyDoc_STRVAR(cmath_isclose__doc__, "not close to anything, even itself. inf and -inf are only close to themselves."); #define CMATH_ISCLOSE_METHODDEF \ - {"isclose", (PyCFunction)(void(*)(void))cmath_isclose, METH_FASTCALL|METH_KEYWORDS, cmath_isclose__doc__}, + {"isclose", _PyCFunction_CAST(cmath_isclose), METH_FASTCALL|METH_KEYWORDS, cmath_isclose__doc__}, static int cmath_isclose_impl(PyObject *module, Py_complex a, Py_complex b, @@ -893,8 +900,31 @@ static PyObject * cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(rel_tol), &_Py_ID(abs_tol), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "isclose", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "isclose", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; Py_complex a; @@ -953,4 +983,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=353347db2e808e0d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2630f8740909a8f7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/fcntlmodule.c.h b/Modules/clinic/fcntlmodule.c.h index adf527fd443..20eb50b0e76 100644 --- a/Modules/clinic/fcntlmodule.c.h +++ b/Modules/clinic/fcntlmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(fcntl_fcntl__doc__, "fcntl($module, fd, cmd, arg=0, /)\n" "--\n" @@ -19,7 +25,7 @@ PyDoc_STRVAR(fcntl_fcntl__doc__, "corresponding to the return value of the fcntl call in the C code."); #define FCNTL_FCNTL_METHODDEF \ - {"fcntl", (PyCFunction)(void(*)(void))fcntl_fcntl, METH_FASTCALL, fcntl_fcntl__doc__}, + {"fcntl", _PyCFunction_CAST(fcntl_fcntl), METH_FASTCALL, fcntl_fcntl__doc__}, static PyObject * fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg); @@ -87,7 +93,7 @@ PyDoc_STRVAR(fcntl_ioctl__doc__, "code."); #define FCNTL_IOCTL_METHODDEF \ - {"ioctl", (PyCFunction)(void(*)(void))fcntl_ioctl, METH_FASTCALL, fcntl_ioctl__doc__}, + {"ioctl", _PyCFunction_CAST(fcntl_ioctl), METH_FASTCALL, fcntl_ioctl__doc__}, static PyObject * fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code, @@ -140,7 +146,7 @@ PyDoc_STRVAR(fcntl_flock__doc__, "function is emulated using fcntl())."); #define FCNTL_FLOCK_METHODDEF \ - {"flock", (PyCFunction)(void(*)(void))fcntl_flock, METH_FASTCALL, fcntl_flock__doc__}, + {"flock", _PyCFunction_CAST(fcntl_flock), METH_FASTCALL, fcntl_flock__doc__}, static PyObject * fcntl_flock_impl(PyObject *module, int fd, int code); @@ -196,7 +202,7 @@ PyDoc_STRVAR(fcntl_lockf__doc__, " 2 - relative to the end of the file (SEEK_END)"); #define FCNTL_LOCKF_METHODDEF \ - {"lockf", (PyCFunction)(void(*)(void))fcntl_lockf, METH_FASTCALL, fcntl_lockf__doc__}, + {"lockf", _PyCFunction_CAST(fcntl_lockf), METH_FASTCALL, fcntl_lockf__doc__}, static PyObject * fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj, @@ -243,4 +249,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=8ea34bd0f7cf25ec input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1db859412172dd53 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/gcmodule.c.h b/Modules/clinic/gcmodule.c.h index 30efc7e0c2c..2d18e2ee097 100644 --- a/Modules/clinic/gcmodule.c.h +++ b/Modules/clinic/gcmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(gc_enable__doc__, "enable($module, /)\n" "--\n" @@ -79,7 +85,7 @@ PyDoc_STRVAR(gc_collect__doc__, "The number of unreachable objects is returned."); #define GC_COLLECT_METHODDEF \ - {"collect", (PyCFunction)(void(*)(void))gc_collect, METH_FASTCALL|METH_KEYWORDS, gc_collect__doc__}, + {"collect", _PyCFunction_CAST(gc_collect), METH_FASTCALL|METH_KEYWORDS, gc_collect__doc__}, static Py_ssize_t gc_collect_impl(PyObject *module, int generation); @@ -88,8 +94,31 @@ static PyObject * gc_collect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(generation), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"generation", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "collect", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "collect", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int generation = NUM_GENERATIONS - 1; @@ -233,7 +262,7 @@ PyDoc_STRVAR(gc_get_objects__doc__, "that are in that generation."); #define GC_GET_OBJECTS_METHODDEF \ - {"get_objects", (PyCFunction)(void(*)(void))gc_get_objects, METH_FASTCALL|METH_KEYWORDS, gc_get_objects__doc__}, + {"get_objects", _PyCFunction_CAST(gc_get_objects), METH_FASTCALL|METH_KEYWORDS, gc_get_objects__doc__}, static PyObject * gc_get_objects_impl(PyObject *module, Py_ssize_t generation); @@ -242,8 +271,31 @@ static PyObject * gc_get_objects(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(generation), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"generation", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get_objects", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get_objects", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; Py_ssize_t generation = -1; @@ -372,4 +424,4 @@ gc_get_freeze_count(PyObject *module, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=61e15f3a549f3ab5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=66432ac0e17fd04f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/grpmodule.c.h b/Modules/clinic/grpmodule.c.h index 2e2690ad8d3..4914bc9abd6 100644 --- a/Modules/clinic/grpmodule.c.h +++ b/Modules/clinic/grpmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(grp_getgrgid__doc__, "getgrgid($module, /, id)\n" "--\n" @@ -11,7 +17,7 @@ PyDoc_STRVAR(grp_getgrgid__doc__, "If id is not valid, raise KeyError."); #define GRP_GETGRGID_METHODDEF \ - {"getgrgid", (PyCFunction)(void(*)(void))grp_getgrgid, METH_FASTCALL|METH_KEYWORDS, grp_getgrgid__doc__}, + {"getgrgid", _PyCFunction_CAST(grp_getgrgid), METH_FASTCALL|METH_KEYWORDS, grp_getgrgid__doc__}, static PyObject * grp_getgrgid_impl(PyObject *module, PyObject *id); @@ -20,8 +26,31 @@ static PyObject * grp_getgrgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(id), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"id", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "getgrgid", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getgrgid", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *id; @@ -45,7 +74,7 @@ PyDoc_STRVAR(grp_getgrnam__doc__, "If name is not valid, raise KeyError."); #define GRP_GETGRNAM_METHODDEF \ - {"getgrnam", (PyCFunction)(void(*)(void))grp_getgrnam, METH_FASTCALL|METH_KEYWORDS, grp_getgrnam__doc__}, + {"getgrnam", _PyCFunction_CAST(grp_getgrnam), METH_FASTCALL|METH_KEYWORDS, grp_getgrnam__doc__}, static PyObject * grp_getgrnam_impl(PyObject *module, PyObject *name); @@ -54,8 +83,31 @@ static PyObject * grp_getgrnam(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "getgrnam", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getgrnam", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *name; @@ -97,4 +149,4 @@ grp_getgrall(PyObject *module, PyObject *Py_UNUSED(ignored)) { return grp_getgrall_impl(module); } -/*[clinic end generated code: output=9b3f26779e4e1a52 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0916fdbcdeaf5d7d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/itertoolsmodule.c.h b/Modules/clinic/itertoolsmodule.c.h index 7f5abe648af..287de524e91 100644 --- a/Modules/clinic/itertoolsmodule.c.h +++ b/Modules/clinic/itertoolsmodule.c.h @@ -2,6 +2,91 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(batched_new__doc__, +"batched(iterable, n)\n" +"--\n" +"\n" +"Batch data into tuples of length n. The last batch may be shorter than n.\n" +"\n" +"Loops over the input iterable and accumulates data into tuples\n" +"up to size n. The input is consumed lazily, just enough to\n" +"fill a batch. The result is yielded as soon as a batch is full\n" +"or when the input iterable is exhausted.\n" +"\n" +" >>> for batch in batched(\'ABCDEFG\', 3):\n" +" ... print(batch)\n" +" ...\n" +" (\'A\', \'B\', \'C\')\n" +" (\'D\', \'E\', \'F\')\n" +" (\'G\',)"); + +static PyObject * +batched_new_impl(PyTypeObject *type, PyObject *iterable, Py_ssize_t n); + +static PyObject * +batched_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(n), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"iterable", "n", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "batched", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *iterable; + Py_ssize_t n; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 2, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + iterable = fastargs[0]; + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(fastargs[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + n = ival; + } + return_value = batched_new_impl(type, iterable, n); + +exit: + return return_value; +} + PyDoc_STRVAR(pairwise_new__doc__, "pairwise(iterable, /)\n" "--\n" @@ -54,8 +139,31 @@ static PyObject * itertools_groupby(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(key), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"iterable", "key", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "groupby", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "groupby", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -186,7 +294,7 @@ PyDoc_STRVAR(itertools_tee__doc__, "Returns a tuple of n independent iterators."); #define ITERTOOLS_TEE_METHODDEF \ - {"tee", (PyCFunction)(void(*)(void))itertools_tee, METH_FASTCALL, itertools_tee__doc__}, + {"tee", _PyCFunction_CAST(itertools_tee), METH_FASTCALL, itertools_tee__doc__}, static PyObject * itertools_tee_impl(PyObject *module, PyObject *iterable, Py_ssize_t n); @@ -377,8 +485,31 @@ static PyObject * itertools_combinations(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(r), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"iterable", "r", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "combinations", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "combinations", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -414,7 +545,7 @@ PyDoc_STRVAR(itertools_combinations_with_replacement__doc__, "\n" "Return successive r-length combinations of elements in the iterable allowing individual elements to have successive repeats.\n" "\n" -"combinations_with_replacement(\'ABC\', 2) --> AA AB AC BB BC CC\""); +"combinations_with_replacement(\'ABC\', 2) --> (\'A\',\'A\'), (\'A\',\'B\'), (\'A\',\'C\'), (\'B\',\'B\'), (\'B\',\'C\'), (\'C\',\'C\')"); static PyObject * itertools_combinations_with_replacement_impl(PyTypeObject *type, @@ -425,8 +556,31 @@ static PyObject * itertools_combinations_with_replacement(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(r), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"iterable", "r", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "combinations_with_replacement", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "combinations_with_replacement", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -472,8 +626,31 @@ static PyObject * itertools_permutations(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(r), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"iterable", "r", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "permutations", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "permutations", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -511,8 +688,31 @@ static PyObject * itertools_accumulate(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(func), &_Py_ID(initial), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"iterable", "func", "initial", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "accumulate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "accumulate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -563,8 +763,31 @@ static PyObject * itertools_compress(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(selectors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"data", "selectors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -638,8 +861,31 @@ static PyObject * itertools_count(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(start), &_Py_ID(step), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"start", "step", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "count", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "count", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -667,4 +913,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=5364de2e143609b9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0229ebd72962f130 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index 65f3dd4f520..0d61fd1be38 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(math_ceil__doc__, "ceil($module, x, /)\n" "--\n" @@ -45,10 +51,10 @@ PyDoc_STRVAR(math_isqrt__doc__, {"isqrt", (PyCFunction)math_isqrt, METH_O, math_isqrt__doc__}, PyDoc_STRVAR(math_factorial__doc__, -"factorial($module, x, /)\n" +"factorial($module, n, /)\n" "--\n" "\n" -"Find x!.\n" +"Find n!.\n" "\n" "Raise a ValueError if x is negative or non-integral."); @@ -112,7 +118,7 @@ PyDoc_STRVAR(math_ldexp__doc__, "This is essentially the inverse of frexp()."); #define MATH_LDEXP_METHODDEF \ - {"ldexp", (PyCFunction)(void(*)(void))math_ldexp, METH_FASTCALL, math_ldexp__doc__}, + {"ldexp", _PyCFunction_CAST(math_ldexp), METH_FASTCALL, math_ldexp__doc__}, static PyObject * math_ldexp_impl(PyObject *module, double x, PyObject *i); @@ -181,43 +187,37 @@ exit: } PyDoc_STRVAR(math_log__doc__, -"log(x, [base=math.e])\n" +"log($module, x, base=None, /)\n" +"--\n" +"\n" "Return the logarithm of x to the given base.\n" "\n" -"If the base not specified, returns the natural logarithm (base e) of x."); +"If the base is not specified or is None, returns the natural\n" +"logarithm (base e) of x."); #define MATH_LOG_METHODDEF \ - {"log", (PyCFunction)math_log, METH_VARARGS, math_log__doc__}, + {"log", _PyCFunction_CAST(math_log), METH_FASTCALL, math_log__doc__}, static PyObject * -math_log_impl(PyObject *module, PyObject *x, int group_right_1, - PyObject *base); +math_log_impl(PyObject *module, PyObject *x, PyObject *base); static PyObject * -math_log(PyObject *module, PyObject *args) +math_log(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; PyObject *x; - int group_right_1 = 0; - PyObject *base = NULL; + PyObject *base = Py_None; - switch (PyTuple_GET_SIZE(args)) { - case 1: - if (!PyArg_ParseTuple(args, "O:log", &x)) { - goto exit; - } - break; - case 2: - if (!PyArg_ParseTuple(args, "OO:log", &x, &base)) { - goto exit; - } - group_right_1 = 1; - break; - default: - PyErr_SetString(PyExc_TypeError, "math.log requires 1 to 2 arguments"); - goto exit; + if (!_PyArg_CheckPositional("log", nargs, 1, 2)) { + goto exit; } - return_value = math_log_impl(module, x, group_right_1, base); + x = args[0]; + if (nargs < 2) { + goto skip_optional; + } + base = args[1]; +skip_optional: + return_value = math_log_impl(module, x, base); exit: return return_value; @@ -250,7 +250,7 @@ PyDoc_STRVAR(math_fmod__doc__, "x % y may differ."); #define MATH_FMOD_METHODDEF \ - {"fmod", (PyCFunction)(void(*)(void))math_fmod, METH_FASTCALL, math_fmod__doc__}, + {"fmod", _PyCFunction_CAST(math_fmod), METH_FASTCALL, math_fmod__doc__}, static PyObject * math_fmod_impl(PyObject *module, double x, double y); @@ -304,7 +304,7 @@ PyDoc_STRVAR(math_dist__doc__, " sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))"); #define MATH_DIST_METHODDEF \ - {"dist", (PyCFunction)(void(*)(void))math_dist, METH_FASTCALL, math_dist__doc__}, + {"dist", _PyCFunction_CAST(math_dist), METH_FASTCALL, math_dist__doc__}, static PyObject * math_dist_impl(PyObject *module, PyObject *p, PyObject *q); @@ -327,6 +327,43 @@ exit: return return_value; } +PyDoc_STRVAR(math_sumprod__doc__, +"sumprod($module, p, q, /)\n" +"--\n" +"\n" +"Return the sum of products of values from two iterables p and q.\n" +"\n" +"Roughly equivalent to:\n" +"\n" +" sum(itertools.starmap(operator.mul, zip(p, q, strict=True)))\n" +"\n" +"For float and mixed int/float inputs, the intermediate products\n" +"and sums are computed with extended precision."); + +#define MATH_SUMPROD_METHODDEF \ + {"sumprod", _PyCFunction_CAST(math_sumprod), METH_FASTCALL, math_sumprod__doc__}, + +static PyObject * +math_sumprod_impl(PyObject *module, PyObject *p, PyObject *q); + +static PyObject * +math_sumprod(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *p; + PyObject *q; + + if (!_PyArg_CheckPositional("sumprod", nargs, 2, 2)) { + goto exit; + } + p = args[0]; + q = args[1]; + return_value = math_sumprod_impl(module, p, q); + +exit: + return return_value; +} + PyDoc_STRVAR(math_pow__doc__, "pow($module, x, y, /)\n" "--\n" @@ -334,7 +371,7 @@ PyDoc_STRVAR(math_pow__doc__, "Return x**y (x to the power of y)."); #define MATH_POW_METHODDEF \ - {"pow", (PyCFunction)(void(*)(void))math_pow, METH_FASTCALL, math_pow__doc__}, + {"pow", _PyCFunction_CAST(math_pow), METH_FASTCALL, math_pow__doc__}, static PyObject * math_pow_impl(PyObject *module, double x, double y); @@ -568,7 +605,7 @@ PyDoc_STRVAR(math_isclose__doc__, "only close to themselves."); #define MATH_ISCLOSE_METHODDEF \ - {"isclose", (PyCFunction)(void(*)(void))math_isclose, METH_FASTCALL|METH_KEYWORDS, math_isclose__doc__}, + {"isclose", _PyCFunction_CAST(math_isclose), METH_FASTCALL|METH_KEYWORDS, math_isclose__doc__}, static int math_isclose_impl(PyObject *module, double a, double b, double rel_tol, @@ -578,8 +615,31 @@ static PyObject * math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(rel_tol), &_Py_ID(abs_tol), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "isclose", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "isclose", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; double a; @@ -664,7 +724,7 @@ PyDoc_STRVAR(math_prod__doc__, "non-numeric types."); #define MATH_PROD_METHODDEF \ - {"prod", (PyCFunction)(void(*)(void))math_prod, METH_FASTCALL|METH_KEYWORDS, math_prod__doc__}, + {"prod", _PyCFunction_CAST(math_prod), METH_FASTCALL|METH_KEYWORDS, math_prod__doc__}, static PyObject * math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start); @@ -673,8 +733,31 @@ static PyObject * math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(start), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "start", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "prod", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "prod", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *iterable; @@ -712,7 +795,7 @@ PyDoc_STRVAR(math_perm__doc__, "Raises ValueError if either of the arguments are negative."); #define MATH_PERM_METHODDEF \ - {"perm", (PyCFunction)(void(*)(void))math_perm, METH_FASTCALL, math_perm__doc__}, + {"perm", _PyCFunction_CAST(math_perm), METH_FASTCALL, math_perm__doc__}, static PyObject * math_perm_impl(PyObject *module, PyObject *n, PyObject *k); @@ -756,7 +839,7 @@ PyDoc_STRVAR(math_comb__doc__, "Raises ValueError if either of the arguments are negative."); #define MATH_COMB_METHODDEF \ - {"comb", (PyCFunction)(void(*)(void))math_comb, METH_FASTCALL, math_comb__doc__}, + {"comb", _PyCFunction_CAST(math_comb), METH_FASTCALL, math_comb__doc__}, static PyObject * math_comb_impl(PyObject *module, PyObject *n, PyObject *k); @@ -786,7 +869,7 @@ PyDoc_STRVAR(math_nextafter__doc__, "Return the next floating-point value after x towards y."); #define MATH_NEXTAFTER_METHODDEF \ - {"nextafter", (PyCFunction)(void(*)(void))math_nextafter, METH_FASTCALL, math_nextafter__doc__}, + {"nextafter", _PyCFunction_CAST(math_nextafter), METH_FASTCALL, math_nextafter__doc__}, static PyObject * math_nextafter_impl(PyObject *module, double x, double y); @@ -865,4 +948,4 @@ math_ulp(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=1eae2b3ef19568fa input=a9049054013a1b77]*/ +/*[clinic end generated code: output=afec63ebb0da709a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/md5module.c.h b/Modules/clinic/md5module.c.h index 4762f2800d4..b4602104f18 100644 --- a/Modules/clinic/md5module.c.h +++ b/Modules/clinic/md5module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(MD5Type_copy__doc__, "copy($self, /)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(MD5Type_copy__doc__, "Return a copy of the hash object."); #define MD5TYPE_COPY_METHODDEF \ - {"copy", (PyCFunction)(void(*)(void))MD5Type_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, MD5Type_copy__doc__}, + {"copy", _PyCFunction_CAST(MD5Type_copy), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, MD5Type_copy__doc__}, static PyObject * MD5Type_copy_impl(MD5object *self, PyTypeObject *cls); @@ -17,18 +23,11 @@ MD5Type_copy_impl(MD5object *self, PyTypeObject *cls); static PyObject * MD5Type_copy(MD5object *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":copy", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); + return NULL; } - return_value = MD5Type_copy_impl(self, cls); - -exit: - return return_value; + return MD5Type_copy_impl(self, cls); } PyDoc_STRVAR(MD5Type_digest__doc__, @@ -83,7 +82,7 @@ PyDoc_STRVAR(_md5_md5__doc__, "Return a new MD5 hash object; optionally initialized with a string."); #define _MD5_MD5_METHODDEF \ - {"md5", (PyCFunction)(void(*)(void))_md5_md5, METH_FASTCALL|METH_KEYWORDS, _md5_md5__doc__}, + {"md5", _PyCFunction_CAST(_md5_md5), METH_FASTCALL|METH_KEYWORDS, _md5_md5__doc__}, static PyObject * _md5_md5_impl(PyObject *module, PyObject *string, int usedforsecurity); @@ -92,8 +91,31 @@ static PyObject * _md5_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "md5", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "md5", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *string = NULL; @@ -126,4 +148,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=53ff7f22dbaaea36 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b4924c9905cc9f34 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/overlapped.c.h b/Modules/clinic/overlapped.c.h index efecd9028b7..9d9f2cbf6af 100644 --- a/Modules/clinic/overlapped.c.h +++ b/Modules/clinic/overlapped.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_overlapped_CreateIoCompletionPort__doc__, "CreateIoCompletionPort($module, handle, port, key, concurrency, /)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(_overlapped_CreateIoCompletionPort__doc__, "Create a completion port or register a handle with a port."); #define _OVERLAPPED_CREATEIOCOMPLETIONPORT_METHODDEF \ - {"CreateIoCompletionPort", (PyCFunction)(void(*)(void))_overlapped_CreateIoCompletionPort, METH_FASTCALL, _overlapped_CreateIoCompletionPort__doc__}, + {"CreateIoCompletionPort", _PyCFunction_CAST(_overlapped_CreateIoCompletionPort), METH_FASTCALL, _overlapped_CreateIoCompletionPort__doc__}, static PyObject * _overlapped_CreateIoCompletionPort_impl(PyObject *module, HANDLE FileHandle, @@ -26,8 +32,22 @@ _overlapped_CreateIoCompletionPort(PyObject *module, PyObject *const *args, Py_s ULONG_PTR CompletionKey; DWORD NumberOfConcurrentThreads; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE""F_ULONG_PTR"k:CreateIoCompletionPort", - &FileHandle, &ExistingCompletionPort, &CompletionKey, &NumberOfConcurrentThreads)) { + if (!_PyArg_CheckPositional("CreateIoCompletionPort", nargs, 4, 4)) { + goto exit; + } + FileHandle = PyLong_AsVoidPtr(args[0]); + if (!FileHandle && PyErr_Occurred()) { + goto exit; + } + ExistingCompletionPort = PyLong_AsVoidPtr(args[1]); + if (!ExistingCompletionPort && PyErr_Occurred()) { + goto exit; + } + CompletionKey = (uintptr_t)PyLong_AsVoidPtr(args[2]); + if (!CompletionKey && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[3], &NumberOfConcurrentThreads)) { goto exit; } return_value = _overlapped_CreateIoCompletionPort_impl(module, FileHandle, ExistingCompletionPort, CompletionKey, NumberOfConcurrentThreads); @@ -45,7 +65,7 @@ PyDoc_STRVAR(_overlapped_GetQueuedCompletionStatus__doc__, "Wait for up to msecs milliseconds."); #define _OVERLAPPED_GETQUEUEDCOMPLETIONSTATUS_METHODDEF \ - {"GetQueuedCompletionStatus", (PyCFunction)(void(*)(void))_overlapped_GetQueuedCompletionStatus, METH_FASTCALL, _overlapped_GetQueuedCompletionStatus__doc__}, + {"GetQueuedCompletionStatus", _PyCFunction_CAST(_overlapped_GetQueuedCompletionStatus), METH_FASTCALL, _overlapped_GetQueuedCompletionStatus__doc__}, static PyObject * _overlapped_GetQueuedCompletionStatus_impl(PyObject *module, @@ -59,8 +79,14 @@ _overlapped_GetQueuedCompletionStatus(PyObject *module, PyObject *const *args, P HANDLE CompletionPort; DWORD Milliseconds; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k:GetQueuedCompletionStatus", - &CompletionPort, &Milliseconds)) { + if (!_PyArg_CheckPositional("GetQueuedCompletionStatus", nargs, 2, 2)) { + goto exit; + } + CompletionPort = PyLong_AsVoidPtr(args[0]); + if (!CompletionPort && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[1], &Milliseconds)) { goto exit; } return_value = _overlapped_GetQueuedCompletionStatus_impl(module, CompletionPort, Milliseconds); @@ -76,7 +102,7 @@ PyDoc_STRVAR(_overlapped_PostQueuedCompletionStatus__doc__, "Post a message to completion port."); #define _OVERLAPPED_POSTQUEUEDCOMPLETIONSTATUS_METHODDEF \ - {"PostQueuedCompletionStatus", (PyCFunction)(void(*)(void))_overlapped_PostQueuedCompletionStatus, METH_FASTCALL, _overlapped_PostQueuedCompletionStatus__doc__}, + {"PostQueuedCompletionStatus", _PyCFunction_CAST(_overlapped_PostQueuedCompletionStatus), METH_FASTCALL, _overlapped_PostQueuedCompletionStatus__doc__}, static PyObject * _overlapped_PostQueuedCompletionStatus_impl(PyObject *module, @@ -94,8 +120,22 @@ _overlapped_PostQueuedCompletionStatus(PyObject *module, PyObject *const *args, ULONG_PTR CompletionKey; OVERLAPPED *Overlapped; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k"F_ULONG_PTR""F_POINTER":PostQueuedCompletionStatus", - &CompletionPort, &NumberOfBytes, &CompletionKey, &Overlapped)) { + if (!_PyArg_CheckPositional("PostQueuedCompletionStatus", nargs, 4, 4)) { + goto exit; + } + CompletionPort = PyLong_AsVoidPtr(args[0]); + if (!CompletionPort && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[1], &NumberOfBytes)) { + goto exit; + } + CompletionKey = (uintptr_t)PyLong_AsVoidPtr(args[2]); + if (!CompletionKey && PyErr_Occurred()) { + goto exit; + } + Overlapped = PyLong_AsVoidPtr(args[3]); + if (!Overlapped && PyErr_Occurred()) { goto exit; } return_value = _overlapped_PostQueuedCompletionStatus_impl(module, CompletionPort, NumberOfBytes, CompletionKey, Overlapped); @@ -112,7 +152,7 @@ PyDoc_STRVAR(_overlapped_RegisterWaitWithQueue__doc__, "Register wait for Object; when complete CompletionPort is notified."); #define _OVERLAPPED_REGISTERWAITWITHQUEUE_METHODDEF \ - {"RegisterWaitWithQueue", (PyCFunction)(void(*)(void))_overlapped_RegisterWaitWithQueue, METH_FASTCALL, _overlapped_RegisterWaitWithQueue__doc__}, + {"RegisterWaitWithQueue", _PyCFunction_CAST(_overlapped_RegisterWaitWithQueue), METH_FASTCALL, _overlapped_RegisterWaitWithQueue__doc__}, static PyObject * _overlapped_RegisterWaitWithQueue_impl(PyObject *module, HANDLE Object, @@ -129,8 +169,22 @@ _overlapped_RegisterWaitWithQueue(PyObject *module, PyObject *const *args, Py_ss OVERLAPPED *Overlapped; DWORD Milliseconds; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE""F_POINTER"k:RegisterWaitWithQueue", - &Object, &CompletionPort, &Overlapped, &Milliseconds)) { + if (!_PyArg_CheckPositional("RegisterWaitWithQueue", nargs, 4, 4)) { + goto exit; + } + Object = PyLong_AsVoidPtr(args[0]); + if (!Object && PyErr_Occurred()) { + goto exit; + } + CompletionPort = PyLong_AsVoidPtr(args[1]); + if (!CompletionPort && PyErr_Occurred()) { + goto exit; + } + Overlapped = PyLong_AsVoidPtr(args[2]); + if (!Overlapped && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[3], &Milliseconds)) { goto exit; } return_value = _overlapped_RegisterWaitWithQueue_impl(module, Object, CompletionPort, Overlapped, Milliseconds); @@ -157,7 +211,8 @@ _overlapped_UnregisterWait(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HANDLE WaitHandle; - if (!PyArg_Parse(arg, ""F_HANDLE":UnregisterWait", &WaitHandle)) { + WaitHandle = PyLong_AsVoidPtr(arg); + if (!WaitHandle && PyErr_Occurred()) { goto exit; } return_value = _overlapped_UnregisterWait_impl(module, WaitHandle); @@ -173,7 +228,7 @@ PyDoc_STRVAR(_overlapped_UnregisterWaitEx__doc__, "Unregister wait handle."); #define _OVERLAPPED_UNREGISTERWAITEX_METHODDEF \ - {"UnregisterWaitEx", (PyCFunction)(void(*)(void))_overlapped_UnregisterWaitEx, METH_FASTCALL, _overlapped_UnregisterWaitEx__doc__}, + {"UnregisterWaitEx", _PyCFunction_CAST(_overlapped_UnregisterWaitEx), METH_FASTCALL, _overlapped_UnregisterWaitEx__doc__}, static PyObject * _overlapped_UnregisterWaitEx_impl(PyObject *module, HANDLE WaitHandle, @@ -186,8 +241,15 @@ _overlapped_UnregisterWaitEx(PyObject *module, PyObject *const *args, Py_ssize_t HANDLE WaitHandle; HANDLE Event; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE":UnregisterWaitEx", - &WaitHandle, &Event)) { + if (!_PyArg_CheckPositional("UnregisterWaitEx", nargs, 2, 2)) { + goto exit; + } + WaitHandle = PyLong_AsVoidPtr(args[0]); + if (!WaitHandle && PyErr_Occurred()) { + goto exit; + } + Event = PyLong_AsVoidPtr(args[1]); + if (!Event && PyErr_Occurred()) { goto exit; } return_value = _overlapped_UnregisterWaitEx_impl(module, WaitHandle, Event); @@ -206,7 +268,7 @@ PyDoc_STRVAR(_overlapped_CreateEvent__doc__, "EventAttributes must be None."); #define _OVERLAPPED_CREATEEVENT_METHODDEF \ - {"CreateEvent", (PyCFunction)(void(*)(void))_overlapped_CreateEvent, METH_FASTCALL, _overlapped_CreateEvent__doc__}, + {"CreateEvent", _PyCFunction_CAST(_overlapped_CreateEvent), METH_FASTCALL, _overlapped_CreateEvent__doc__}, static PyObject * _overlapped_CreateEvent_impl(PyObject *module, PyObject *EventAttributes, @@ -220,19 +282,38 @@ _overlapped_CreateEvent(PyObject *module, PyObject *const *args, Py_ssize_t narg PyObject *EventAttributes; BOOL ManualReset; BOOL InitialState; - const Py_UNICODE *Name; + const Py_UNICODE *Name = NULL; - if (!_PyArg_ParseStack(args, nargs, "OiiO&:CreateEvent", - &EventAttributes, &ManualReset, &InitialState, _PyUnicode_WideCharString_Opt_Converter, &Name)) { + if (!_PyArg_CheckPositional("CreateEvent", nargs, 4, 4)) { + goto exit; + } + EventAttributes = args[0]; + ManualReset = _PyLong_AsInt(args[1]); + if (ManualReset == -1 && PyErr_Occurred()) { + goto exit; + } + InitialState = _PyLong_AsInt(args[2]); + if (InitialState == -1 && PyErr_Occurred()) { + goto exit; + } + if (args[3] == Py_None) { + Name = NULL; + } + else if (PyUnicode_Check(args[3])) { + Name = PyUnicode_AsWideCharString(args[3], NULL); + if (Name == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("CreateEvent", "argument 4", "str or None", args[3]); goto exit; } return_value = _overlapped_CreateEvent_impl(module, EventAttributes, ManualReset, InitialState, Name); exit: /* Cleanup for Name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)Name); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -255,7 +336,8 @@ _overlapped_SetEvent(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HANDLE Handle; - if (!PyArg_Parse(arg, ""F_HANDLE":SetEvent", &Handle)) { + Handle = PyLong_AsVoidPtr(arg); + if (!Handle && PyErr_Occurred()) { goto exit; } return_value = _overlapped_SetEvent_impl(module, Handle); @@ -282,7 +364,8 @@ _overlapped_ResetEvent(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HANDLE Handle; - if (!PyArg_Parse(arg, ""F_HANDLE":ResetEvent", &Handle)) { + Handle = PyLong_AsVoidPtr(arg); + if (!Handle && PyErr_Occurred()) { goto exit; } return_value = _overlapped_ResetEvent_impl(module, Handle); @@ -300,7 +383,7 @@ PyDoc_STRVAR(_overlapped_BindLocal__doc__, "family should be AF_INET or AF_INET6."); #define _OVERLAPPED_BINDLOCAL_METHODDEF \ - {"BindLocal", (PyCFunction)(void(*)(void))_overlapped_BindLocal, METH_FASTCALL, _overlapped_BindLocal__doc__}, + {"BindLocal", _PyCFunction_CAST(_overlapped_BindLocal), METH_FASTCALL, _overlapped_BindLocal__doc__}, static PyObject * _overlapped_BindLocal_impl(PyObject *module, HANDLE Socket, int Family); @@ -312,8 +395,15 @@ _overlapped_BindLocal(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HANDLE Socket; int Family; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"i:BindLocal", - &Socket, &Family)) { + if (!_PyArg_CheckPositional("BindLocal", nargs, 2, 2)) { + goto exit; + } + Socket = PyLong_AsVoidPtr(args[0]); + if (!Socket && PyErr_Occurred()) { + goto exit; + } + Family = _PyLong_AsInt(args[1]); + if (Family == -1 && PyErr_Occurred()) { goto exit; } return_value = _overlapped_BindLocal_impl(module, Socket, Family); @@ -340,7 +430,7 @@ _overlapped_FormatMessage(PyObject *module, PyObject *arg) PyObject *return_value = NULL; DWORD code; - if (!PyArg_Parse(arg, "k:FormatMessage", &code)) { + if (!_PyLong_UnsignedLong_Converter(arg, &code)) { goto exit; } return_value = _overlapped_FormatMessage_impl(module, code); @@ -362,14 +452,49 @@ static PyObject * _overlapped_Overlapped(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(event), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"event", NULL}; - static _PyArg_Parser _parser = {"|"F_HANDLE":Overlapped", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Overlapped", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; HANDLE event = INVALID_HANDLE_VALUE; - if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, - &event)) { + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); + if (!fastargs) { goto exit; } + if (!noptargs) { + goto skip_optional_pos; + } + event = PyLong_AsVoidPtr(fastargs[0]); + if (!event && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: return_value = _overlapped_Overlapped_impl(type, event); exit: @@ -404,7 +529,7 @@ PyDoc_STRVAR(_overlapped_Overlapped_getresult__doc__, "is false and the operation is still pending then an error is raised."); #define _OVERLAPPED_OVERLAPPED_GETRESULT_METHODDEF \ - {"getresult", (PyCFunction)(void(*)(void))_overlapped_Overlapped_getresult, METH_FASTCALL, _overlapped_Overlapped_getresult__doc__}, + {"getresult", _PyCFunction_CAST(_overlapped_Overlapped_getresult), METH_FASTCALL, _overlapped_Overlapped_getresult__doc__}, static PyObject * _overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait); @@ -415,10 +540,17 @@ _overlapped_Overlapped_getresult(OverlappedObject *self, PyObject *const *args, PyObject *return_value = NULL; BOOL wait = FALSE; - if (!_PyArg_ParseStack(args, nargs, "|i:getresult", - &wait)) { + if (!_PyArg_CheckPositional("getresult", nargs, 0, 1)) { goto exit; } + if (nargs < 1) { + goto skip_optional; + } + wait = _PyLong_AsInt(args[0]); + if (wait == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: return_value = _overlapped_Overlapped_getresult_impl(self, wait); exit: @@ -432,7 +564,7 @@ PyDoc_STRVAR(_overlapped_Overlapped_ReadFile__doc__, "Start overlapped read."); #define _OVERLAPPED_OVERLAPPED_READFILE_METHODDEF \ - {"ReadFile", (PyCFunction)(void(*)(void))_overlapped_Overlapped_ReadFile, METH_FASTCALL, _overlapped_Overlapped_ReadFile__doc__}, + {"ReadFile", _PyCFunction_CAST(_overlapped_Overlapped_ReadFile), METH_FASTCALL, _overlapped_Overlapped_ReadFile__doc__}, static PyObject * _overlapped_Overlapped_ReadFile_impl(OverlappedObject *self, HANDLE handle, @@ -445,8 +577,14 @@ _overlapped_Overlapped_ReadFile(OverlappedObject *self, PyObject *const *args, P HANDLE handle; DWORD size; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k:ReadFile", - &handle, &size)) { + if (!_PyArg_CheckPositional("ReadFile", nargs, 2, 2)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[1], &size)) { goto exit; } return_value = _overlapped_Overlapped_ReadFile_impl(self, handle, size); @@ -462,26 +600,41 @@ PyDoc_STRVAR(_overlapped_Overlapped_ReadFileInto__doc__, "Start overlapped receive."); #define _OVERLAPPED_OVERLAPPED_READFILEINTO_METHODDEF \ - {"ReadFileInto", (PyCFunction)(void(*)(void))_overlapped_Overlapped_ReadFileInto, METH_FASTCALL, _overlapped_Overlapped_ReadFileInto__doc__}, + {"ReadFileInto", _PyCFunction_CAST(_overlapped_Overlapped_ReadFileInto), METH_FASTCALL, _overlapped_Overlapped_ReadFileInto__doc__}, static PyObject * _overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self, - HANDLE handle, PyObject *bufobj); + HANDLE handle, Py_buffer *bufobj); static PyObject * _overlapped_Overlapped_ReadFileInto(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O:ReadFileInto", - &handle, &bufobj)) { + if (!_PyArg_CheckPositional("ReadFileInto", nargs, 2, 2)) { goto exit; } - return_value = _overlapped_Overlapped_ReadFileInto_impl(self, handle, bufobj); + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&bufobj, 'C')) { + _PyArg_BadArgument("ReadFileInto", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + return_value = _overlapped_Overlapped_ReadFileInto_impl(self, handle, &bufobj); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -492,7 +645,7 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSARecv__doc__, "Start overlapped receive."); #define _OVERLAPPED_OVERLAPPED_WSARECV_METHODDEF \ - {"WSARecv", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WSARecv, METH_FASTCALL, _overlapped_Overlapped_WSARecv__doc__}, + {"WSARecv", _PyCFunction_CAST(_overlapped_Overlapped_WSARecv), METH_FASTCALL, _overlapped_Overlapped_WSARecv__doc__}, static PyObject * _overlapped_Overlapped_WSARecv_impl(OverlappedObject *self, HANDLE handle, @@ -506,10 +659,23 @@ _overlapped_Overlapped_WSARecv(OverlappedObject *self, PyObject *const *args, Py DWORD size; DWORD flags = 0; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k|k:WSARecv", - &handle, &size, &flags)) { + if (!_PyArg_CheckPositional("WSARecv", nargs, 2, 3)) { goto exit; } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[1], &size)) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (!_PyLong_UnsignedLong_Converter(args[2], &flags)) { + goto exit; + } +skip_optional: return_value = _overlapped_Overlapped_WSARecv_impl(self, handle, size, flags); exit: @@ -523,11 +689,11 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSARecvInto__doc__, "Start overlapped receive."); #define _OVERLAPPED_OVERLAPPED_WSARECVINTO_METHODDEF \ - {"WSARecvInto", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WSARecvInto, METH_FASTCALL, _overlapped_Overlapped_WSARecvInto__doc__}, + {"WSARecvInto", _PyCFunction_CAST(_overlapped_Overlapped_WSARecvInto), METH_FASTCALL, _overlapped_Overlapped_WSARecvInto__doc__}, static PyObject * _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, - HANDLE handle, PyObject *bufobj, + HANDLE handle, Py_buffer *bufobj, DWORD flags); static PyObject * @@ -535,16 +701,34 @@ _overlapped_Overlapped_WSARecvInto(OverlappedObject *self, PyObject *const *args { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; DWORD flags; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"Ok:WSARecvInto", - &handle, &bufobj, &flags)) { + if (!_PyArg_CheckPositional("WSARecvInto", nargs, 3, 3)) { goto exit; } - return_value = _overlapped_Overlapped_WSARecvInto_impl(self, handle, bufobj, flags); + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&bufobj, 'C')) { + _PyArg_BadArgument("WSARecvInto", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[2], &flags)) { + goto exit; + } + return_value = _overlapped_Overlapped_WSARecvInto_impl(self, handle, &bufobj, flags); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -555,26 +739,41 @@ PyDoc_STRVAR(_overlapped_Overlapped_WriteFile__doc__, "Start overlapped write."); #define _OVERLAPPED_OVERLAPPED_WRITEFILE_METHODDEF \ - {"WriteFile", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WriteFile, METH_FASTCALL, _overlapped_Overlapped_WriteFile__doc__}, + {"WriteFile", _PyCFunction_CAST(_overlapped_Overlapped_WriteFile), METH_FASTCALL, _overlapped_Overlapped_WriteFile__doc__}, static PyObject * _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj); + Py_buffer *bufobj); static PyObject * _overlapped_Overlapped_WriteFile(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O:WriteFile", - &handle, &bufobj)) { + if (!_PyArg_CheckPositional("WriteFile", nargs, 2, 2)) { goto exit; } - return_value = _overlapped_Overlapped_WriteFile_impl(self, handle, bufobj); + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&bufobj, 'C')) { + _PyArg_BadArgument("WriteFile", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + return_value = _overlapped_Overlapped_WriteFile_impl(self, handle, &bufobj); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -585,27 +784,45 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSASend__doc__, "Start overlapped send."); #define _OVERLAPPED_OVERLAPPED_WSASEND_METHODDEF \ - {"WSASend", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WSASend, METH_FASTCALL, _overlapped_Overlapped_WSASend__doc__}, + {"WSASend", _PyCFunction_CAST(_overlapped_Overlapped_WSASend), METH_FASTCALL, _overlapped_Overlapped_WSASend__doc__}, static PyObject * _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj, DWORD flags); + Py_buffer *bufobj, DWORD flags); static PyObject * _overlapped_Overlapped_WSASend(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; DWORD flags; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"Ok:WSASend", - &handle, &bufobj, &flags)) { + if (!_PyArg_CheckPositional("WSASend", nargs, 3, 3)) { goto exit; } - return_value = _overlapped_Overlapped_WSASend_impl(self, handle, bufobj, flags); + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&bufobj, 'C')) { + _PyArg_BadArgument("WSASend", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[2], &flags)) { + goto exit; + } + return_value = _overlapped_Overlapped_WSASend_impl(self, handle, &bufobj, flags); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -616,7 +833,7 @@ PyDoc_STRVAR(_overlapped_Overlapped_AcceptEx__doc__, "Start overlapped wait for client to connect."); #define _OVERLAPPED_OVERLAPPED_ACCEPTEX_METHODDEF \ - {"AcceptEx", (PyCFunction)(void(*)(void))_overlapped_Overlapped_AcceptEx, METH_FASTCALL, _overlapped_Overlapped_AcceptEx__doc__}, + {"AcceptEx", _PyCFunction_CAST(_overlapped_Overlapped_AcceptEx), METH_FASTCALL, _overlapped_Overlapped_AcceptEx__doc__}, static PyObject * _overlapped_Overlapped_AcceptEx_impl(OverlappedObject *self, @@ -630,8 +847,15 @@ _overlapped_Overlapped_AcceptEx(OverlappedObject *self, PyObject *const *args, P HANDLE ListenSocket; HANDLE AcceptSocket; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE":AcceptEx", - &ListenSocket, &AcceptSocket)) { + if (!_PyArg_CheckPositional("AcceptEx", nargs, 2, 2)) { + goto exit; + } + ListenSocket = PyLong_AsVoidPtr(args[0]); + if (!ListenSocket && PyErr_Occurred()) { + goto exit; + } + AcceptSocket = PyLong_AsVoidPtr(args[1]); + if (!AcceptSocket && PyErr_Occurred()) { goto exit; } return_value = _overlapped_Overlapped_AcceptEx_impl(self, ListenSocket, AcceptSocket); @@ -649,7 +873,7 @@ PyDoc_STRVAR(_overlapped_Overlapped_ConnectEx__doc__, "client_handle should be unbound."); #define _OVERLAPPED_OVERLAPPED_CONNECTEX_METHODDEF \ - {"ConnectEx", (PyCFunction)(void(*)(void))_overlapped_Overlapped_ConnectEx, METH_FASTCALL, _overlapped_Overlapped_ConnectEx__doc__}, + {"ConnectEx", _PyCFunction_CAST(_overlapped_Overlapped_ConnectEx), METH_FASTCALL, _overlapped_Overlapped_ConnectEx__doc__}, static PyObject * _overlapped_Overlapped_ConnectEx_impl(OverlappedObject *self, @@ -663,10 +887,18 @@ _overlapped_Overlapped_ConnectEx(OverlappedObject *self, PyObject *const *args, HANDLE ConnectSocket; PyObject *AddressObj; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O!:ConnectEx", - &ConnectSocket, &PyTuple_Type, &AddressObj)) { + if (!_PyArg_CheckPositional("ConnectEx", nargs, 2, 2)) { goto exit; } + ConnectSocket = PyLong_AsVoidPtr(args[0]); + if (!ConnectSocket && PyErr_Occurred()) { + goto exit; + } + if (!PyTuple_Check(args[1])) { + _PyArg_BadArgument("ConnectEx", "argument 2", "tuple", args[1]); + goto exit; + } + AddressObj = args[1]; return_value = _overlapped_Overlapped_ConnectEx_impl(self, ConnectSocket, AddressObj); exit: @@ -679,7 +911,7 @@ PyDoc_STRVAR(_overlapped_Overlapped_DisconnectEx__doc__, "\n"); #define _OVERLAPPED_OVERLAPPED_DISCONNECTEX_METHODDEF \ - {"DisconnectEx", (PyCFunction)(void(*)(void))_overlapped_Overlapped_DisconnectEx, METH_FASTCALL, _overlapped_Overlapped_DisconnectEx__doc__}, + {"DisconnectEx", _PyCFunction_CAST(_overlapped_Overlapped_DisconnectEx), METH_FASTCALL, _overlapped_Overlapped_DisconnectEx__doc__}, static PyObject * _overlapped_Overlapped_DisconnectEx_impl(OverlappedObject *self, @@ -692,8 +924,14 @@ _overlapped_Overlapped_DisconnectEx(OverlappedObject *self, PyObject *const *arg HANDLE Socket; DWORD flags; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k:DisconnectEx", - &Socket, &flags)) { + if (!_PyArg_CheckPositional("DisconnectEx", nargs, 2, 2)) { + goto exit; + } + Socket = PyLong_AsVoidPtr(args[0]); + if (!Socket && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[1], &flags)) { goto exit; } return_value = _overlapped_Overlapped_DisconnectEx_impl(self, Socket, flags); @@ -710,7 +948,7 @@ PyDoc_STRVAR(_overlapped_Overlapped_TransmitFile__doc__, "Transmit file data over a connected socket."); #define _OVERLAPPED_OVERLAPPED_TRANSMITFILE_METHODDEF \ - {"TransmitFile", (PyCFunction)(void(*)(void))_overlapped_Overlapped_TransmitFile, METH_FASTCALL, _overlapped_Overlapped_TransmitFile__doc__}, + {"TransmitFile", _PyCFunction_CAST(_overlapped_Overlapped_TransmitFile), METH_FASTCALL, _overlapped_Overlapped_TransmitFile__doc__}, static PyObject * _overlapped_Overlapped_TransmitFile_impl(OverlappedObject *self, @@ -731,8 +969,30 @@ _overlapped_Overlapped_TransmitFile(OverlappedObject *self, PyObject *const *arg DWORD count_per_send; DWORD flags; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE"kkkkk:TransmitFile", - &Socket, &File, &offset, &offset_high, &count_to_write, &count_per_send, &flags)) { + if (!_PyArg_CheckPositional("TransmitFile", nargs, 7, 7)) { + goto exit; + } + Socket = PyLong_AsVoidPtr(args[0]); + if (!Socket && PyErr_Occurred()) { + goto exit; + } + File = PyLong_AsVoidPtr(args[1]); + if (!File && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[2], &offset)) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[3], &offset_high)) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[4], &count_to_write)) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[5], &count_per_send)) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[6], &flags)) { goto exit; } return_value = _overlapped_Overlapped_TransmitFile_impl(self, Socket, File, offset, offset_high, count_to_write, count_per_send, flags); @@ -760,7 +1020,8 @@ _overlapped_Overlapped_ConnectNamedPipe(OverlappedObject *self, PyObject *arg) PyObject *return_value = NULL; HANDLE Pipe; - if (!PyArg_Parse(arg, ""F_HANDLE":ConnectNamedPipe", &Pipe)) { + Pipe = PyLong_AsVoidPtr(arg); + if (!Pipe && PyErr_Occurred()) { goto exit; } return_value = _overlapped_Overlapped_ConnectNamedPipe_impl(self, Pipe); @@ -786,17 +1047,13 @@ static PyObject * _overlapped_Overlapped_ConnectPipe(OverlappedObject *self, PyObject *arg) { PyObject *return_value = NULL; - const Py_UNICODE *Address; + const Py_UNICODE *Address = NULL; if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("ConnectPipe", "argument", "str", arg); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - Address = _PyUnicode_AsUnicode(arg); - #else /* USE_UNICODE_WCHAR_CACHE */ Address = PyUnicode_AsWideCharString(arg, NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (Address == NULL) { goto exit; } @@ -804,9 +1061,7 @@ _overlapped_Overlapped_ConnectPipe(OverlappedObject *self, PyObject *arg) exit: /* Cleanup for Address */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)Address); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -818,7 +1073,7 @@ PyDoc_STRVAR(_overlapped_WSAConnect__doc__, "Bind a remote address to a connectionless (UDP) socket."); #define _OVERLAPPED_WSACONNECT_METHODDEF \ - {"WSAConnect", (PyCFunction)(void(*)(void))_overlapped_WSAConnect, METH_FASTCALL, _overlapped_WSAConnect__doc__}, + {"WSAConnect", _PyCFunction_CAST(_overlapped_WSAConnect), METH_FASTCALL, _overlapped_WSAConnect__doc__}, static PyObject * _overlapped_WSAConnect_impl(PyObject *module, HANDLE ConnectSocket, @@ -831,10 +1086,18 @@ _overlapped_WSAConnect(PyObject *module, PyObject *const *args, Py_ssize_t nargs HANDLE ConnectSocket; PyObject *AddressObj; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O:WSAConnect", - &ConnectSocket, &AddressObj)) { + if (!_PyArg_CheckPositional("WSAConnect", nargs, 2, 2)) { goto exit; } + ConnectSocket = PyLong_AsVoidPtr(args[0]); + if (!ConnectSocket && PyErr_Occurred()) { + goto exit; + } + if (!PyTuple_Check(args[1])) { + _PyArg_BadArgument("WSAConnect", "argument 2", "tuple", args[1]); + goto exit; + } + AddressObj = args[1]; return_value = _overlapped_WSAConnect_impl(module, ConnectSocket, AddressObj); exit: @@ -848,11 +1111,11 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSASendTo__doc__, "Start overlapped sendto over a connectionless (UDP) socket."); #define _OVERLAPPED_OVERLAPPED_WSASENDTO_METHODDEF \ - {"WSASendTo", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WSASendTo, METH_FASTCALL, _overlapped_Overlapped_WSASendTo__doc__}, + {"WSASendTo", _PyCFunction_CAST(_overlapped_Overlapped_WSASendTo), METH_FASTCALL, _overlapped_Overlapped_WSASendTo__doc__}, static PyObject * _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj, DWORD flags, + Py_buffer *bufobj, DWORD flags, PyObject *AddressObj); static PyObject * @@ -860,17 +1123,40 @@ _overlapped_Overlapped_WSASendTo(OverlappedObject *self, PyObject *const *args, { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; DWORD flags; PyObject *AddressObj; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"OkO:WSASendTo", - &handle, &bufobj, &flags, &AddressObj)) { + if (!_PyArg_CheckPositional("WSASendTo", nargs, 4, 4)) { goto exit; } - return_value = _overlapped_Overlapped_WSASendTo_impl(self, handle, bufobj, flags, AddressObj); + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&bufobj, 'C')) { + _PyArg_BadArgument("WSASendTo", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[2], &flags)) { + goto exit; + } + if (!PyTuple_Check(args[3])) { + _PyArg_BadArgument("WSASendTo", "argument 4", "tuple", args[3]); + goto exit; + } + AddressObj = args[3]; + return_value = _overlapped_Overlapped_WSASendTo_impl(self, handle, &bufobj, flags, AddressObj); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -881,7 +1167,7 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSARecvFrom__doc__, "Start overlapped receive."); #define _OVERLAPPED_OVERLAPPED_WSARECVFROM_METHODDEF \ - {"WSARecvFrom", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WSARecvFrom, METH_FASTCALL, _overlapped_Overlapped_WSARecvFrom__doc__}, + {"WSARecvFrom", _PyCFunction_CAST(_overlapped_Overlapped_WSARecvFrom), METH_FASTCALL, _overlapped_Overlapped_WSARecvFrom__doc__}, static PyObject * _overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self, @@ -896,13 +1182,84 @@ _overlapped_Overlapped_WSARecvFrom(OverlappedObject *self, PyObject *const *args DWORD size; DWORD flags = 0; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k|k:WSARecvFrom", - &handle, &size, &flags)) { + if (!_PyArg_CheckPositional("WSARecvFrom", nargs, 2, 3)) { goto exit; } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[1], &size)) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (!_PyLong_UnsignedLong_Converter(args[2], &flags)) { + goto exit; + } +skip_optional: return_value = _overlapped_Overlapped_WSARecvFrom_impl(self, handle, size, flags); exit: return return_value; } -/*[clinic end generated code: output=ee2ec2f93c8d334b input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_overlapped_Overlapped_WSARecvFromInto__doc__, +"WSARecvFromInto($self, handle, buf, size, flags=0, /)\n" +"--\n" +"\n" +"Start overlapped receive."); + +#define _OVERLAPPED_OVERLAPPED_WSARECVFROMINTO_METHODDEF \ + {"WSARecvFromInto", _PyCFunction_CAST(_overlapped_Overlapped_WSARecvFromInto), METH_FASTCALL, _overlapped_Overlapped_WSARecvFromInto__doc__}, + +static PyObject * +_overlapped_Overlapped_WSARecvFromInto_impl(OverlappedObject *self, + HANDLE handle, Py_buffer *bufobj, + DWORD size, DWORD flags); + +static PyObject * +_overlapped_Overlapped_WSARecvFromInto(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + Py_buffer bufobj = {NULL, NULL}; + DWORD size; + DWORD flags = 0; + + if (!_PyArg_CheckPositional("WSARecvFromInto", nargs, 3, 4)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&bufobj, 'C')) { + _PyArg_BadArgument("WSARecvFromInto", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[2], &size)) { + goto exit; + } + if (nargs < 4) { + goto skip_optional; + } + if (!_PyLong_UnsignedLong_Converter(args[3], &flags)) { + goto exit; + } +skip_optional: + return_value = _overlapped_Overlapped_WSARecvFromInto_impl(self, handle, &bufobj, size, flags); + +exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + + return return_value; +} +/*[clinic end generated code: output=b2e89694b8de3d00 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 7921c222b90..d4722cc533c 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(os_stat__doc__, "stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n" "--\n" @@ -28,7 +34,7 @@ PyDoc_STRVAR(os_stat__doc__, " an open file descriptor."); #define OS_STAT_METHODDEF \ - {"stat", (PyCFunction)(void(*)(void))os_stat, METH_FASTCALL|METH_KEYWORDS, os_stat__doc__}, + {"stat", _PyCFunction_CAST(os_stat), METH_FASTCALL|METH_KEYWORDS, os_stat__doc__}, static PyObject * os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks); @@ -37,8 +43,31 @@ static PyObject * os_stat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "dir_fd", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "stat", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "stat", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("stat", "path", 0, 1); @@ -87,7 +116,7 @@ PyDoc_STRVAR(os_lstat__doc__, "Equivalent to stat(path, follow_symlinks=False)."); #define OS_LSTAT_METHODDEF \ - {"lstat", (PyCFunction)(void(*)(void))os_lstat, METH_FASTCALL|METH_KEYWORDS, os_lstat__doc__}, + {"lstat", _PyCFunction_CAST(os_lstat), METH_FASTCALL|METH_KEYWORDS, os_lstat__doc__}, static PyObject * os_lstat_impl(PyObject *module, path_t *path, int dir_fd); @@ -96,8 +125,31 @@ static PyObject * os_lstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "lstat", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "lstat", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0); @@ -159,7 +211,7 @@ PyDoc_STRVAR(os_access__doc__, " has the specified access to the path."); #define OS_ACCESS_METHODDEF \ - {"access", (PyCFunction)(void(*)(void))os_access, METH_FASTCALL|METH_KEYWORDS, os_access__doc__}, + {"access", _PyCFunction_CAST(os_access), METH_FASTCALL|METH_KEYWORDS, os_access__doc__}, static int os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd, @@ -169,8 +221,31 @@ static PyObject * os_access(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(dir_fd), &_Py_ID(effective_ids), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "access", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "access", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("access", "path", 0, 0); @@ -297,7 +372,7 @@ PyDoc_STRVAR(os_chdir__doc__, " If this functionality is unavailable, using it raises an exception."); #define OS_CHDIR_METHODDEF \ - {"chdir", (PyCFunction)(void(*)(void))os_chdir, METH_FASTCALL|METH_KEYWORDS, os_chdir__doc__}, + {"chdir", _PyCFunction_CAST(os_chdir), METH_FASTCALL|METH_KEYWORDS, os_chdir__doc__}, static PyObject * os_chdir_impl(PyObject *module, path_t *path); @@ -306,8 +381,31 @@ static PyObject * os_chdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "chdir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "chdir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("chdir", "path", 0, PATH_HAVE_FCHDIR); @@ -339,7 +437,7 @@ PyDoc_STRVAR(os_fchdir__doc__, "Equivalent to os.chdir(fd)."); #define OS_FCHDIR_METHODDEF \ - {"fchdir", (PyCFunction)(void(*)(void))os_fchdir, METH_FASTCALL|METH_KEYWORDS, os_fchdir__doc__}, + {"fchdir", _PyCFunction_CAST(os_fchdir), METH_FASTCALL|METH_KEYWORDS, os_fchdir__doc__}, static PyObject * os_fchdir_impl(PyObject *module, int fd); @@ -348,8 +446,31 @@ static PyObject * os_fchdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fchdir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fchdir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -380,6 +501,9 @@ PyDoc_STRVAR(os_chmod__doc__, " If this functionality is unavailable, using it raises an exception.\n" " mode\n" " Operating-system mode bitfield.\n" +" Be careful when using number literals for *mode*. The conventional UNIX notation for\n" +" numeric modes uses an octal base, which needs to be indicated with a ``0o`` prefix in\n" +" Python.\n" " dir_fd\n" " If not None, it should be a file descriptor open to a directory,\n" " and path should be relative; path will then be relative to that\n" @@ -395,7 +519,7 @@ PyDoc_STRVAR(os_chmod__doc__, " If they are unavailable, using them will raise a NotImplementedError."); #define OS_CHMOD_METHODDEF \ - {"chmod", (PyCFunction)(void(*)(void))os_chmod, METH_FASTCALL|METH_KEYWORDS, os_chmod__doc__}, + {"chmod", _PyCFunction_CAST(os_chmod), METH_FASTCALL|METH_KEYWORDS, os_chmod__doc__}, static PyObject * os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, @@ -405,8 +529,31 @@ static PyObject * os_chmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(dir_fd), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "mode", "dir_fd", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "chmod", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "chmod", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("chmod", "path", 0, PATH_HAVE_FCHMOD); @@ -458,10 +605,18 @@ PyDoc_STRVAR(os_fchmod__doc__, "\n" "Change the access permissions of the file given by file descriptor fd.\n" "\n" +" fd\n" +" The file descriptor of the file to be modified.\n" +" mode\n" +" Operating-system mode bitfield.\n" +" Be careful when using number literals for *mode*. The conventional UNIX notation for\n" +" numeric modes uses an octal base, which needs to be indicated with a ``0o`` prefix in\n" +" Python.\n" +"\n" "Equivalent to os.chmod(fd, mode)."); #define OS_FCHMOD_METHODDEF \ - {"fchmod", (PyCFunction)(void(*)(void))os_fchmod, METH_FASTCALL|METH_KEYWORDS, os_fchmod__doc__}, + {"fchmod", _PyCFunction_CAST(os_fchmod), METH_FASTCALL|METH_KEYWORDS, os_fchmod__doc__}, static PyObject * os_fchmod_impl(PyObject *module, int fd, int mode); @@ -470,8 +625,31 @@ static PyObject * os_fchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(mode), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", "mode", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fchmod", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fchmod", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int fd; int mode; @@ -508,7 +686,7 @@ PyDoc_STRVAR(os_lchmod__doc__, "Equivalent to chmod(path, mode, follow_symlinks=False).\""); #define OS_LCHMOD_METHODDEF \ - {"lchmod", (PyCFunction)(void(*)(void))os_lchmod, METH_FASTCALL|METH_KEYWORDS, os_lchmod__doc__}, + {"lchmod", _PyCFunction_CAST(os_lchmod), METH_FASTCALL|METH_KEYWORDS, os_lchmod__doc__}, static PyObject * os_lchmod_impl(PyObject *module, path_t *path, int mode); @@ -517,8 +695,31 @@ static PyObject * os_lchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "mode", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "lchmod", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "lchmod", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0); int mode; @@ -560,7 +761,7 @@ PyDoc_STRVAR(os_chflags__doc__, "unavailable, using it will raise a NotImplementedError."); #define OS_CHFLAGS_METHODDEF \ - {"chflags", (PyCFunction)(void(*)(void))os_chflags, METH_FASTCALL|METH_KEYWORDS, os_chflags__doc__}, + {"chflags", _PyCFunction_CAST(os_chflags), METH_FASTCALL|METH_KEYWORDS, os_chflags__doc__}, static PyObject * os_chflags_impl(PyObject *module, path_t *path, unsigned long flags, @@ -570,8 +771,31 @@ static PyObject * os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(flags), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "flags", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "chflags", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "chflags", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0); @@ -621,7 +845,7 @@ PyDoc_STRVAR(os_lchflags__doc__, "Equivalent to chflags(path, flags, follow_symlinks=False)."); #define OS_LCHFLAGS_METHODDEF \ - {"lchflags", (PyCFunction)(void(*)(void))os_lchflags, METH_FASTCALL|METH_KEYWORDS, os_lchflags__doc__}, + {"lchflags", _PyCFunction_CAST(os_lchflags), METH_FASTCALL|METH_KEYWORDS, os_lchflags__doc__}, static PyObject * os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags); @@ -630,8 +854,31 @@ static PyObject * os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "lchflags", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "lchflags", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0); unsigned long flags; @@ -668,7 +915,7 @@ PyDoc_STRVAR(os_chroot__doc__, "Change root directory to path."); #define OS_CHROOT_METHODDEF \ - {"chroot", (PyCFunction)(void(*)(void))os_chroot, METH_FASTCALL|METH_KEYWORDS, os_chroot__doc__}, + {"chroot", _PyCFunction_CAST(os_chroot), METH_FASTCALL|METH_KEYWORDS, os_chroot__doc__}, static PyObject * os_chroot_impl(PyObject *module, path_t *path); @@ -677,8 +924,31 @@ static PyObject * os_chroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "chroot", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "chroot", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0); @@ -709,7 +979,7 @@ PyDoc_STRVAR(os_fsync__doc__, "Force write of fd to disk."); #define OS_FSYNC_METHODDEF \ - {"fsync", (PyCFunction)(void(*)(void))os_fsync, METH_FASTCALL|METH_KEYWORDS, os_fsync__doc__}, + {"fsync", _PyCFunction_CAST(os_fsync), METH_FASTCALL|METH_KEYWORDS, os_fsync__doc__}, static PyObject * os_fsync_impl(PyObject *module, int fd); @@ -718,8 +988,31 @@ static PyObject * os_fsync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fsync", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fsync", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -769,7 +1062,7 @@ PyDoc_STRVAR(os_fdatasync__doc__, "Force write of fd to disk without forcing update of metadata."); #define OS_FDATASYNC_METHODDEF \ - {"fdatasync", (PyCFunction)(void(*)(void))os_fdatasync, METH_FASTCALL|METH_KEYWORDS, os_fdatasync__doc__}, + {"fdatasync", _PyCFunction_CAST(os_fdatasync), METH_FASTCALL|METH_KEYWORDS, os_fdatasync__doc__}, static PyObject * os_fdatasync_impl(PyObject *module, int fd); @@ -778,8 +1071,31 @@ static PyObject * os_fdatasync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fdatasync", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fdatasync", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -831,7 +1147,7 @@ PyDoc_STRVAR(os_chown__doc__, " If they are unavailable, using them will raise a NotImplementedError."); #define OS_CHOWN_METHODDEF \ - {"chown", (PyCFunction)(void(*)(void))os_chown, METH_FASTCALL|METH_KEYWORDS, os_chown__doc__}, + {"chown", _PyCFunction_CAST(os_chown), METH_FASTCALL|METH_KEYWORDS, os_chown__doc__}, static PyObject * os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid, @@ -841,8 +1157,31 @@ static PyObject * os_chown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(uid), &_Py_ID(gid), &_Py_ID(dir_fd), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "uid", "gid", "dir_fd", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "chown", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "chown", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; path_t path = PATH_T_INITIALIZE("chown", "path", 0, PATH_HAVE_FCHOWN); @@ -902,7 +1241,7 @@ PyDoc_STRVAR(os_fchown__doc__, "Equivalent to os.chown(fd, uid, gid)."); #define OS_FCHOWN_METHODDEF \ - {"fchown", (PyCFunction)(void(*)(void))os_fchown, METH_FASTCALL|METH_KEYWORDS, os_fchown__doc__}, + {"fchown", _PyCFunction_CAST(os_fchown), METH_FASTCALL|METH_KEYWORDS, os_fchown__doc__}, static PyObject * os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid); @@ -911,8 +1250,31 @@ static PyObject * os_fchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(uid), &_Py_ID(gid), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", "uid", "gid", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fchown", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fchown", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; int fd; uid_t uid; @@ -952,7 +1314,7 @@ PyDoc_STRVAR(os_lchown__doc__, "Equivalent to os.chown(path, uid, gid, follow_symlinks=False)."); #define OS_LCHOWN_METHODDEF \ - {"lchown", (PyCFunction)(void(*)(void))os_lchown, METH_FASTCALL|METH_KEYWORDS, os_lchown__doc__}, + {"lchown", _PyCFunction_CAST(os_lchown), METH_FASTCALL|METH_KEYWORDS, os_lchown__doc__}, static PyObject * os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid); @@ -961,8 +1323,31 @@ static PyObject * os_lchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(uid), &_Py_ID(gid), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "uid", "gid", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "lchown", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "lchown", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0); uid_t uid; @@ -1048,7 +1433,7 @@ PyDoc_STRVAR(os_link__doc__, " NotImplementedError."); #define OS_LINK_METHODDEF \ - {"link", (PyCFunction)(void(*)(void))os_link, METH_FASTCALL|METH_KEYWORDS, os_link__doc__}, + {"link", _PyCFunction_CAST(os_link), METH_FASTCALL|METH_KEYWORDS, os_link__doc__}, static PyObject * os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, @@ -1058,8 +1443,31 @@ static PyObject * os_link(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(src_dir_fd), &_Py_ID(dst_dir_fd), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "link", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "link", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t src = PATH_T_INITIALIZE("link", "src", 0, 0); @@ -1133,7 +1541,7 @@ PyDoc_STRVAR(os_listdir__doc__, "entries \'.\' and \'..\' even if they are present in the directory."); #define OS_LISTDIR_METHODDEF \ - {"listdir", (PyCFunction)(void(*)(void))os_listdir, METH_FASTCALL|METH_KEYWORDS, os_listdir__doc__}, + {"listdir", _PyCFunction_CAST(os_listdir), METH_FASTCALL|METH_KEYWORDS, os_listdir__doc__}, static PyObject * os_listdir_impl(PyObject *module, path_t *path); @@ -1142,8 +1550,31 @@ static PyObject * os_listdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "listdir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "listdir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; path_t path = PATH_T_INITIALIZE("listdir", "path", 1, PATH_HAVE_FDOPENDIR); @@ -1244,7 +1675,7 @@ PyDoc_STRVAR(os__getvolumepathname__doc__, "A helper function for ismount on Win32."); #define OS__GETVOLUMEPATHNAME_METHODDEF \ - {"_getvolumepathname", (PyCFunction)(void(*)(void))os__getvolumepathname, METH_FASTCALL|METH_KEYWORDS, os__getvolumepathname__doc__}, + {"_getvolumepathname", _PyCFunction_CAST(os__getvolumepathname), METH_FASTCALL|METH_KEYWORDS, os__getvolumepathname__doc__}, static PyObject * os__getvolumepathname_impl(PyObject *module, path_t *path); @@ -1253,8 +1684,31 @@ static PyObject * os__getvolumepathname(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_getvolumepathname", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_getvolumepathname", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("_getvolumepathname", "path", 0, 0); @@ -1285,7 +1739,7 @@ PyDoc_STRVAR(os__path_splitroot__doc__, "Removes everything after the root on Win32."); #define OS__PATH_SPLITROOT_METHODDEF \ - {"_path_splitroot", (PyCFunction)(void(*)(void))os__path_splitroot, METH_FASTCALL|METH_KEYWORDS, os__path_splitroot__doc__}, + {"_path_splitroot", _PyCFunction_CAST(os__path_splitroot), METH_FASTCALL|METH_KEYWORDS, os__path_splitroot__doc__}, static PyObject * os__path_splitroot_impl(PyObject *module, path_t *path); @@ -1294,8 +1748,31 @@ static PyObject * os__path_splitroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_path_splitroot", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_path_splitroot", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("_path_splitroot", "path", 0, 0); @@ -1317,6 +1794,61 @@ exit: #endif /* defined(MS_WINDOWS) */ +PyDoc_STRVAR(os__path_normpath__doc__, +"_path_normpath($module, /, path)\n" +"--\n" +"\n" +"Basic path normalization."); + +#define OS__PATH_NORMPATH_METHODDEF \ + {"_path_normpath", _PyCFunction_CAST(os__path_normpath), METH_FASTCALL|METH_KEYWORDS, os__path_normpath__doc__}, + +static PyObject * +os__path_normpath_impl(PyObject *module, PyObject *path); + +static PyObject * +os__path_normpath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_path_normpath", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *path; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + path = args[0]; + return_value = os__path_normpath_impl(module, path); + +exit: + return return_value; +} + PyDoc_STRVAR(os_mkdir__doc__, "mkdir($module, /, path, mode=511, *, dir_fd=None)\n" "--\n" @@ -1328,10 +1860,11 @@ PyDoc_STRVAR(os_mkdir__doc__, "dir_fd may not be implemented on your platform.\n" " If it is unavailable, using it will raise a NotImplementedError.\n" "\n" -"The mode argument is ignored on Windows."); +"The mode argument is ignored on Windows. Where it is used, the current umask\n" +"value is first masked out."); #define OS_MKDIR_METHODDEF \ - {"mkdir", (PyCFunction)(void(*)(void))os_mkdir, METH_FASTCALL|METH_KEYWORDS, os_mkdir__doc__}, + {"mkdir", _PyCFunction_CAST(os_mkdir), METH_FASTCALL|METH_KEYWORDS, os_mkdir__doc__}, static PyObject * os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd); @@ -1340,8 +1873,31 @@ static PyObject * os_mkdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "mode", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "mkdir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "mkdir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0); @@ -1425,7 +1981,7 @@ PyDoc_STRVAR(os_getpriority__doc__, "Return program scheduling priority."); #define OS_GETPRIORITY_METHODDEF \ - {"getpriority", (PyCFunction)(void(*)(void))os_getpriority, METH_FASTCALL|METH_KEYWORDS, os_getpriority__doc__}, + {"getpriority", _PyCFunction_CAST(os_getpriority), METH_FASTCALL|METH_KEYWORDS, os_getpriority__doc__}, static PyObject * os_getpriority_impl(PyObject *module, int which, int who); @@ -1434,8 +1990,31 @@ static PyObject * os_getpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(which), &_Py_ID(who), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"which", "who", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "getpriority", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getpriority", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int which; int who; @@ -1469,7 +2048,7 @@ PyDoc_STRVAR(os_setpriority__doc__, "Set program scheduling priority."); #define OS_SETPRIORITY_METHODDEF \ - {"setpriority", (PyCFunction)(void(*)(void))os_setpriority, METH_FASTCALL|METH_KEYWORDS, os_setpriority__doc__}, + {"setpriority", _PyCFunction_CAST(os_setpriority), METH_FASTCALL|METH_KEYWORDS, os_setpriority__doc__}, static PyObject * os_setpriority_impl(PyObject *module, int which, int who, int priority); @@ -1478,8 +2057,31 @@ static PyObject * os_setpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(which), &_Py_ID(who), &_Py_ID(priority), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"which", "who", "priority", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "setpriority", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "setpriority", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; int which; int who; @@ -1522,7 +2124,7 @@ PyDoc_STRVAR(os_rename__doc__, " If they are unavailable, using them will raise a NotImplementedError."); #define OS_RENAME_METHODDEF \ - {"rename", (PyCFunction)(void(*)(void))os_rename, METH_FASTCALL|METH_KEYWORDS, os_rename__doc__}, + {"rename", _PyCFunction_CAST(os_rename), METH_FASTCALL|METH_KEYWORDS, os_rename__doc__}, static PyObject * os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, @@ -1532,8 +2134,31 @@ static PyObject * os_rename(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(src_dir_fd), &_Py_ID(dst_dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rename", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rename", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0); @@ -1590,7 +2215,7 @@ PyDoc_STRVAR(os_replace__doc__, " If they are unavailable, using them will raise a NotImplementedError."); #define OS_REPLACE_METHODDEF \ - {"replace", (PyCFunction)(void(*)(void))os_replace, METH_FASTCALL|METH_KEYWORDS, os_replace__doc__}, + {"replace", _PyCFunction_CAST(os_replace), METH_FASTCALL|METH_KEYWORDS, os_replace__doc__}, static PyObject * os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, @@ -1600,8 +2225,31 @@ static PyObject * os_replace(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(src_dir_fd), &_Py_ID(dst_dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "replace", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "replace", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t src = PATH_T_INITIALIZE("replace", "src", 0, 0); @@ -1657,7 +2305,7 @@ PyDoc_STRVAR(os_rmdir__doc__, " If it is unavailable, using it will raise a NotImplementedError."); #define OS_RMDIR_METHODDEF \ - {"rmdir", (PyCFunction)(void(*)(void))os_rmdir, METH_FASTCALL|METH_KEYWORDS, os_rmdir__doc__}, + {"rmdir", _PyCFunction_CAST(os_rmdir), METH_FASTCALL|METH_KEYWORDS, os_rmdir__doc__}, static PyObject * os_rmdir_impl(PyObject *module, path_t *path, int dir_fd); @@ -1666,8 +2314,31 @@ static PyObject * os_rmdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rmdir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rmdir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0); @@ -1705,7 +2376,7 @@ PyDoc_STRVAR(os_system__doc__, "Execute the command in a subshell."); #define OS_SYSTEM_METHODDEF \ - {"system", (PyCFunction)(void(*)(void))os_system, METH_FASTCALL|METH_KEYWORDS, os_system__doc__}, + {"system", _PyCFunction_CAST(os_system), METH_FASTCALL|METH_KEYWORDS, os_system__doc__}, static long os_system_impl(PyObject *module, const Py_UNICODE *command); @@ -1714,10 +2385,33 @@ static PyObject * os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(command), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"command", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "system", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "system", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; - const Py_UNICODE *command; + const Py_UNICODE *command = NULL; long _return_value; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -1728,11 +2422,7 @@ os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k _PyArg_BadArgument("system", "argument 'command'", "str", args[0]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - command = _PyUnicode_AsUnicode(args[0]); - #else /* USE_UNICODE_WCHAR_CACHE */ command = PyUnicode_AsWideCharString(args[0], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (command == NULL) { goto exit; } @@ -1744,9 +2434,7 @@ os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k exit: /* Cleanup for command */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)command); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -1762,7 +2450,7 @@ PyDoc_STRVAR(os_system__doc__, "Execute the command in a subshell."); #define OS_SYSTEM_METHODDEF \ - {"system", (PyCFunction)(void(*)(void))os_system, METH_FASTCALL|METH_KEYWORDS, os_system__doc__}, + {"system", _PyCFunction_CAST(os_system), METH_FASTCALL|METH_KEYWORDS, os_system__doc__}, static long os_system_impl(PyObject *module, PyObject *command); @@ -1771,8 +2459,31 @@ static PyObject * os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(command), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"command", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "system", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "system", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *command = NULL; long _return_value; @@ -1799,6 +2510,8 @@ exit: #endif /* defined(HAVE_SYSTEM) && !defined(MS_WINDOWS) */ +#if defined(HAVE_UMASK) + PyDoc_STRVAR(os_umask__doc__, "umask($module, mask, /)\n" "--\n" @@ -1827,6 +2540,8 @@ exit: return return_value; } +#endif /* defined(HAVE_UMASK) */ + PyDoc_STRVAR(os_unlink__doc__, "unlink($module, /, path, *, dir_fd=None)\n" "--\n" @@ -1839,7 +2554,7 @@ PyDoc_STRVAR(os_unlink__doc__, " If it is unavailable, using it will raise a NotImplementedError."); #define OS_UNLINK_METHODDEF \ - {"unlink", (PyCFunction)(void(*)(void))os_unlink, METH_FASTCALL|METH_KEYWORDS, os_unlink__doc__}, + {"unlink", _PyCFunction_CAST(os_unlink), METH_FASTCALL|METH_KEYWORDS, os_unlink__doc__}, static PyObject * os_unlink_impl(PyObject *module, path_t *path, int dir_fd); @@ -1848,8 +2563,31 @@ static PyObject * os_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "unlink", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unlink", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0); @@ -1890,7 +2628,7 @@ PyDoc_STRVAR(os_remove__doc__, " If it is unavailable, using it will raise a NotImplementedError."); #define OS_REMOVE_METHODDEF \ - {"remove", (PyCFunction)(void(*)(void))os_remove, METH_FASTCALL|METH_KEYWORDS, os_remove__doc__}, + {"remove", _PyCFunction_CAST(os_remove), METH_FASTCALL|METH_KEYWORDS, os_remove__doc__}, static PyObject * os_remove_impl(PyObject *module, path_t *path, int dir_fd); @@ -1899,8 +2637,31 @@ static PyObject * os_remove(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "remove", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "remove", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("remove", "path", 0, 0); @@ -1984,7 +2745,7 @@ PyDoc_STRVAR(os_utime__doc__, " If they are unavailable, using them will raise a NotImplementedError."); #define OS_UTIME_METHODDEF \ - {"utime", (PyCFunction)(void(*)(void))os_utime, METH_FASTCALL|METH_KEYWORDS, os_utime__doc__}, + {"utime", _PyCFunction_CAST(os_utime), METH_FASTCALL|METH_KEYWORDS, os_utime__doc__}, static PyObject * os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, @@ -1994,8 +2755,31 @@ static PyObject * os_utime(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(times), &_Py_ID(ns), &_Py_ID(dir_fd), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "times", "ns", "dir_fd", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "utime", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "utime", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("utime", "path", 0, PATH_UTIME_HAVE_FD); @@ -2059,7 +2843,7 @@ PyDoc_STRVAR(os__exit__doc__, "Exit to the system with specified status, without normal exit processing."); #define OS__EXIT_METHODDEF \ - {"_exit", (PyCFunction)(void(*)(void))os__exit, METH_FASTCALL|METH_KEYWORDS, os__exit__doc__}, + {"_exit", _PyCFunction_CAST(os__exit), METH_FASTCALL|METH_KEYWORDS, os__exit__doc__}, static PyObject * os__exit_impl(PyObject *module, int status); @@ -2068,8 +2852,31 @@ static PyObject * os__exit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_exit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_exit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; @@ -2101,7 +2908,7 @@ PyDoc_STRVAR(os_execv__doc__, " Tuple or list of strings."); #define OS_EXECV_METHODDEF \ - {"execv", (PyCFunction)(void(*)(void))os_execv, METH_FASTCALL, os_execv__doc__}, + {"execv", _PyCFunction_CAST(os_execv), METH_FASTCALL, os_execv__doc__}, static PyObject * os_execv_impl(PyObject *module, path_t *path, PyObject *argv); @@ -2147,7 +2954,7 @@ PyDoc_STRVAR(os_execve__doc__, " Dictionary of strings mapping to strings."); #define OS_EXECVE_METHODDEF \ - {"execve", (PyCFunction)(void(*)(void))os_execve, METH_FASTCALL|METH_KEYWORDS, os_execve__doc__}, + {"execve", _PyCFunction_CAST(os_execve), METH_FASTCALL|METH_KEYWORDS, os_execve__doc__}, static PyObject * os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env); @@ -2156,8 +2963,31 @@ static PyObject * os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(argv), &_Py_ID(env), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "argv", "env", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "execve", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "execve", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; path_t path = PATH_T_INITIALIZE("execve", "path", 0, PATH_HAVE_FEXECVE); PyObject *argv; @@ -2215,7 +3045,7 @@ PyDoc_STRVAR(os_posix_spawn__doc__, " A tuple with the scheduler policy (optional) and parameters."); #define OS_POSIX_SPAWN_METHODDEF \ - {"posix_spawn", (PyCFunction)(void(*)(void))os_posix_spawn, METH_FASTCALL|METH_KEYWORDS, os_posix_spawn__doc__}, + {"posix_spawn", _PyCFunction_CAST(os_posix_spawn), METH_FASTCALL|METH_KEYWORDS, os_posix_spawn__doc__}, static PyObject * os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, @@ -2228,8 +3058,31 @@ static PyObject * os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 7 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file_actions), &_Py_ID(setpgroup), &_Py_ID(resetids), &_Py_ID(setsid), &_Py_ID(setsigmask), &_Py_ID(setsigdef), &_Py_ID(scheduler), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "", "file_actions", "setpgroup", "resetids", "setsid", "setsigmask", "setsigdef", "scheduler", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posix_spawn", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posix_spawn", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[10]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; path_t path = PATH_T_INITIALIZE("posix_spawn", "path", 0, 0); @@ -2268,8 +3121,8 @@ os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[5]) { - resetids = _PyLong_AsInt(args[5]); - if (resetids == -1 && PyErr_Occurred()) { + resetids = PyObject_IsTrue(args[5]); + if (resetids < 0) { goto exit; } if (!--noptargs) { @@ -2277,8 +3130,8 @@ os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[6]) { - setsid = _PyLong_AsInt(args[6]); - if (setsid == -1 && PyErr_Occurred()) { + setsid = PyObject_IsTrue(args[6]); + if (setsid < 0) { goto exit; } if (!--noptargs) { @@ -2342,7 +3195,7 @@ PyDoc_STRVAR(os_posix_spawnp__doc__, " A tuple with the scheduler policy (optional) and parameters."); #define OS_POSIX_SPAWNP_METHODDEF \ - {"posix_spawnp", (PyCFunction)(void(*)(void))os_posix_spawnp, METH_FASTCALL|METH_KEYWORDS, os_posix_spawnp__doc__}, + {"posix_spawnp", _PyCFunction_CAST(os_posix_spawnp), METH_FASTCALL|METH_KEYWORDS, os_posix_spawnp__doc__}, static PyObject * os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv, @@ -2355,8 +3208,31 @@ static PyObject * os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 7 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file_actions), &_Py_ID(setpgroup), &_Py_ID(resetids), &_Py_ID(setsid), &_Py_ID(setsigmask), &_Py_ID(setsigdef), &_Py_ID(scheduler), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "", "file_actions", "setpgroup", "resetids", "setsid", "setsigmask", "setsigdef", "scheduler", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posix_spawnp", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posix_spawnp", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[10]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; path_t path = PATH_T_INITIALIZE("posix_spawnp", "path", 0, 0); @@ -2395,8 +3271,8 @@ os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } } if (args[5]) { - resetids = _PyLong_AsInt(args[5]); - if (resetids == -1 && PyErr_Occurred()) { + resetids = PyObject_IsTrue(args[5]); + if (resetids < 0) { goto exit; } if (!--noptargs) { @@ -2404,8 +3280,8 @@ os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } } if (args[6]) { - setsid = _PyLong_AsInt(args[6]); - if (setsid == -1 && PyErr_Occurred()) { + setsid = PyObject_IsTrue(args[6]); + if (setsid < 0) { goto exit; } if (!--noptargs) { @@ -2453,7 +3329,7 @@ PyDoc_STRVAR(os_spawnv__doc__, " Tuple or list of strings."); #define OS_SPAWNV_METHODDEF \ - {"spawnv", (PyCFunction)(void(*)(void))os_spawnv, METH_FASTCALL, os_spawnv__doc__}, + {"spawnv", _PyCFunction_CAST(os_spawnv), METH_FASTCALL, os_spawnv__doc__}, static PyObject * os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv); @@ -2506,7 +3382,7 @@ PyDoc_STRVAR(os_spawnve__doc__, " Dictionary of strings mapping to strings."); #define OS_SPAWNVE_METHODDEF \ - {"spawnve", (PyCFunction)(void(*)(void))os_spawnve, METH_FASTCALL, os_spawnve__doc__}, + {"spawnve", _PyCFunction_CAST(os_spawnve), METH_FASTCALL, os_spawnve__doc__}, static PyObject * os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, @@ -2565,7 +3441,7 @@ PyDoc_STRVAR(os_register_at_fork__doc__, "\'after_in_child\' and \'after_in_parent\' callbacks are called in order."); #define OS_REGISTER_AT_FORK_METHODDEF \ - {"register_at_fork", (PyCFunction)(void(*)(void))os_register_at_fork, METH_FASTCALL|METH_KEYWORDS, os_register_at_fork__doc__}, + {"register_at_fork", _PyCFunction_CAST(os_register_at_fork), METH_FASTCALL|METH_KEYWORDS, os_register_at_fork__doc__}, static PyObject * os_register_at_fork_impl(PyObject *module, PyObject *before, @@ -2575,8 +3451,31 @@ static PyObject * os_register_at_fork(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(before), &_Py_ID(after_in_child), &_Py_ID(after_in_parent), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"before", "after_in_child", "after_in_parent", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "register_at_fork", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "register_at_fork", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *before = NULL; @@ -2669,7 +3568,7 @@ PyDoc_STRVAR(os_sched_get_priority_max__doc__, "Get the maximum scheduling priority for policy."); #define OS_SCHED_GET_PRIORITY_MAX_METHODDEF \ - {"sched_get_priority_max", (PyCFunction)(void(*)(void))os_sched_get_priority_max, METH_FASTCALL|METH_KEYWORDS, os_sched_get_priority_max__doc__}, + {"sched_get_priority_max", _PyCFunction_CAST(os_sched_get_priority_max), METH_FASTCALL|METH_KEYWORDS, os_sched_get_priority_max__doc__}, static PyObject * os_sched_get_priority_max_impl(PyObject *module, int policy); @@ -2678,8 +3577,31 @@ static PyObject * os_sched_get_priority_max(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(policy), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"policy", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sched_get_priority_max", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sched_get_priority_max", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int policy; @@ -2708,7 +3630,7 @@ PyDoc_STRVAR(os_sched_get_priority_min__doc__, "Get the minimum scheduling priority for policy."); #define OS_SCHED_GET_PRIORITY_MIN_METHODDEF \ - {"sched_get_priority_min", (PyCFunction)(void(*)(void))os_sched_get_priority_min, METH_FASTCALL|METH_KEYWORDS, os_sched_get_priority_min__doc__}, + {"sched_get_priority_min", _PyCFunction_CAST(os_sched_get_priority_min), METH_FASTCALL|METH_KEYWORDS, os_sched_get_priority_min__doc__}, static PyObject * os_sched_get_priority_min_impl(PyObject *module, int policy); @@ -2717,8 +3639,31 @@ static PyObject * os_sched_get_priority_min(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(policy), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"policy", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sched_get_priority_min", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sched_get_priority_min", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int policy; @@ -2789,8 +3734,31 @@ static PyObject * os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sched_priority), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sched_priority", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sched_param", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sched_param", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -2821,7 +3789,7 @@ PyDoc_STRVAR(os_sched_setscheduler__doc__, "param is an instance of sched_param."); #define OS_SCHED_SETSCHEDULER_METHODDEF \ - {"sched_setscheduler", (PyCFunction)(void(*)(void))os_sched_setscheduler, METH_FASTCALL, os_sched_setscheduler__doc__}, + {"sched_setscheduler", _PyCFunction_CAST(os_sched_setscheduler), METH_FASTCALL, os_sched_setscheduler__doc__}, static PyObject * os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy, @@ -2893,7 +3861,7 @@ PyDoc_STRVAR(os_sched_setparam__doc__, "param should be an instance of sched_param."); #define OS_SCHED_SETPARAM_METHODDEF \ - {"sched_setparam", (PyCFunction)(void(*)(void))os_sched_setparam, METH_FASTCALL, os_sched_setparam__doc__}, + {"sched_setparam", _PyCFunction_CAST(os_sched_setparam), METH_FASTCALL, os_sched_setparam__doc__}, static PyObject * os_sched_setparam_impl(PyObject *module, pid_t pid, PyObject *param_obj); @@ -2988,7 +3956,7 @@ PyDoc_STRVAR(os_sched_setaffinity__doc__, "mask should be an iterable of integers identifying CPUs."); #define OS_SCHED_SETAFFINITY_METHODDEF \ - {"sched_setaffinity", (PyCFunction)(void(*)(void))os_sched_setaffinity, METH_FASTCALL, os_sched_setaffinity__doc__}, + {"sched_setaffinity", _PyCFunction_CAST(os_sched_setaffinity), METH_FASTCALL, os_sched_setaffinity__doc__}, static PyObject * os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask); @@ -3070,6 +4038,41 @@ os_openpty(PyObject *module, PyObject *Py_UNUSED(ignored)) #endif /* (defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)) */ +#if (defined(HAVE_LOGIN_TTY) || defined(HAVE_FALLBACK_LOGIN_TTY)) + +PyDoc_STRVAR(os_login_tty__doc__, +"login_tty($module, fd, /)\n" +"--\n" +"\n" +"Prepare the tty of which fd is a file descriptor for a new login session.\n" +"\n" +"Make the calling process a session leader; make the tty the\n" +"controlling tty, the stdin, the stdout, and the stderr of the\n" +"calling process; close fd."); + +#define OS_LOGIN_TTY_METHODDEF \ + {"login_tty", (PyCFunction)os_login_tty, METH_O, os_login_tty__doc__}, + +static PyObject * +os_login_tty_impl(PyObject *module, int fd); + +static PyObject * +os_login_tty(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!_PyLong_FileDescriptor_Converter(arg, &fd)) { + goto exit; + } + return_value = os_login_tty_impl(module, fd); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_LOGIN_TTY) || defined(HAVE_FALLBACK_LOGIN_TTY)) */ + #if defined(HAVE_FORKPTY) PyDoc_STRVAR(os_forkpty__doc__, @@ -3199,7 +4202,7 @@ PyDoc_STRVAR(os_getgrouplist__doc__, " base group id of the user"); #define OS_GETGROUPLIST_METHODDEF \ - {"getgrouplist", (PyCFunction)(void(*)(void))os_getgrouplist, METH_FASTCALL, os_getgrouplist__doc__}, + {"getgrouplist", _PyCFunction_CAST(os_getgrouplist), METH_FASTCALL, os_getgrouplist__doc__}, static PyObject * os_getgrouplist_impl(PyObject *module, const char *user, int basegid); @@ -3253,7 +4256,7 @@ PyDoc_STRVAR(os_getgrouplist__doc__, " base group id of the user"); #define OS_GETGROUPLIST_METHODDEF \ - {"getgrouplist", (PyCFunction)(void(*)(void))os_getgrouplist, METH_FASTCALL, os_getgrouplist__doc__}, + {"getgrouplist", _PyCFunction_CAST(os_getgrouplist), METH_FASTCALL, os_getgrouplist__doc__}, static PyObject * os_getgrouplist_impl(PyObject *module, const char *user, gid_t basegid); @@ -3327,7 +4330,7 @@ PyDoc_STRVAR(os_initgroups__doc__, "group id."); #define OS_INITGROUPS_METHODDEF \ - {"initgroups", (PyCFunction)(void(*)(void))os_initgroups, METH_FASTCALL, os_initgroups__doc__}, + {"initgroups", _PyCFunction_CAST(os_initgroups), METH_FASTCALL, os_initgroups__doc__}, static PyObject * os_initgroups_impl(PyObject *module, PyObject *oname, int gid); @@ -3373,7 +4376,7 @@ PyDoc_STRVAR(os_initgroups__doc__, "group id."); #define OS_INITGROUPS_METHODDEF \ - {"initgroups", (PyCFunction)(void(*)(void))os_initgroups, METH_FASTCALL, os_initgroups__doc__}, + {"initgroups", _PyCFunction_CAST(os_initgroups), METH_FASTCALL, os_initgroups__doc__}, static PyObject * os_initgroups_impl(PyObject *module, PyObject *oname, gid_t gid); @@ -3414,7 +4417,7 @@ PyDoc_STRVAR(os_getpgid__doc__, "Call the system call getpgid(), and return the result."); #define OS_GETPGID_METHODDEF \ - {"getpgid", (PyCFunction)(void(*)(void))os_getpgid, METH_FASTCALL|METH_KEYWORDS, os_getpgid__doc__}, + {"getpgid", _PyCFunction_CAST(os_getpgid), METH_FASTCALL|METH_KEYWORDS, os_getpgid__doc__}, static PyObject * os_getpgid_impl(PyObject *module, pid_t pid); @@ -3423,8 +4426,31 @@ static PyObject * os_getpgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pid), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"pid", NULL}; - static _PyArg_Parser _parser = {"" _Py_PARSE_PID ":getpgid", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" _Py_PARSE_PID ":getpgid", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE pid_t pid; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, @@ -3561,7 +4587,7 @@ PyDoc_STRVAR(os_kill__doc__, "Kill a process with a signal."); #define OS_KILL_METHODDEF \ - {"kill", (PyCFunction)(void(*)(void))os_kill, METH_FASTCALL, os_kill__doc__}, + {"kill", _PyCFunction_CAST(os_kill), METH_FASTCALL, os_kill__doc__}, static PyObject * os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal); @@ -3594,7 +4620,7 @@ PyDoc_STRVAR(os_killpg__doc__, "Kill a process group with a signal."); #define OS_KILLPG_METHODDEF \ - {"killpg", (PyCFunction)(void(*)(void))os_killpg, METH_FASTCALL, os_killpg__doc__}, + {"killpg", _PyCFunction_CAST(os_killpg), METH_FASTCALL, os_killpg__doc__}, static PyObject * os_killpg_impl(PyObject *module, pid_t pgid, int signal); @@ -3752,7 +4778,7 @@ PyDoc_STRVAR(os_setreuid__doc__, "Set the current process\'s real and effective user ids."); #define OS_SETREUID_METHODDEF \ - {"setreuid", (PyCFunction)(void(*)(void))os_setreuid, METH_FASTCALL, os_setreuid__doc__}, + {"setreuid", _PyCFunction_CAST(os_setreuid), METH_FASTCALL, os_setreuid__doc__}, static PyObject * os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid); @@ -3790,7 +4816,7 @@ PyDoc_STRVAR(os_setregid__doc__, "Set the current process\'s real and effective group ids."); #define OS_SETREGID_METHODDEF \ - {"setregid", (PyCFunction)(void(*)(void))os_setregid, METH_FASTCALL, os_setregid__doc__}, + {"setregid", _PyCFunction_CAST(os_setregid), METH_FASTCALL, os_setregid__doc__}, static PyObject * os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid); @@ -3875,7 +4901,7 @@ PyDoc_STRVAR(os_wait3__doc__, " (pid, status, rusage)"); #define OS_WAIT3_METHODDEF \ - {"wait3", (PyCFunction)(void(*)(void))os_wait3, METH_FASTCALL|METH_KEYWORDS, os_wait3__doc__}, + {"wait3", _PyCFunction_CAST(os_wait3), METH_FASTCALL|METH_KEYWORDS, os_wait3__doc__}, static PyObject * os_wait3_impl(PyObject *module, int options); @@ -3884,8 +4910,31 @@ static PyObject * os_wait3(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(options), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"options", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "wait3", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "wait3", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int options; @@ -3917,7 +4966,7 @@ PyDoc_STRVAR(os_wait4__doc__, " (pid, status, rusage)"); #define OS_WAIT4_METHODDEF \ - {"wait4", (PyCFunction)(void(*)(void))os_wait4, METH_FASTCALL|METH_KEYWORDS, os_wait4__doc__}, + {"wait4", _PyCFunction_CAST(os_wait4), METH_FASTCALL|METH_KEYWORDS, os_wait4__doc__}, static PyObject * os_wait4_impl(PyObject *module, pid_t pid, int options); @@ -3926,8 +4975,31 @@ static PyObject * os_wait4(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pid), &_Py_ID(options), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"pid", "options", NULL}; - static _PyArg_Parser _parser = {"" _Py_PARSE_PID "i:wait4", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" _Py_PARSE_PID "i:wait4", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE pid_t pid; int options; @@ -3963,7 +5035,7 @@ PyDoc_STRVAR(os_waitid__doc__, "no children in a waitable state."); #define OS_WAITID_METHODDEF \ - {"waitid", (PyCFunction)(void(*)(void))os_waitid, METH_FASTCALL, os_waitid__doc__}, + {"waitid", _PyCFunction_CAST(os_waitid), METH_FASTCALL, os_waitid__doc__}, static PyObject * os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options); @@ -4002,7 +5074,7 @@ PyDoc_STRVAR(os_waitpid__doc__, "The options argument is ignored on Windows."); #define OS_WAITPID_METHODDEF \ - {"waitpid", (PyCFunction)(void(*)(void))os_waitpid, METH_FASTCALL, os_waitpid__doc__}, + {"waitpid", _PyCFunction_CAST(os_waitpid), METH_FASTCALL, os_waitpid__doc__}, static PyObject * os_waitpid_impl(PyObject *module, pid_t pid, int options); @@ -4040,7 +5112,7 @@ PyDoc_STRVAR(os_waitpid__doc__, "The options argument is ignored on Windows."); #define OS_WAITPID_METHODDEF \ - {"waitpid", (PyCFunction)(void(*)(void))os_waitpid, METH_FASTCALL, os_waitpid__doc__}, + {"waitpid", _PyCFunction_CAST(os_waitpid), METH_FASTCALL, os_waitpid__doc__}, static PyObject * os_waitpid_impl(PyObject *module, intptr_t pid, int options); @@ -4101,7 +5173,7 @@ PyDoc_STRVAR(os_pidfd_open__doc__, "signals."); #define OS_PIDFD_OPEN_METHODDEF \ - {"pidfd_open", (PyCFunction)(void(*)(void))os_pidfd_open, METH_FASTCALL|METH_KEYWORDS, os_pidfd_open__doc__}, + {"pidfd_open", _PyCFunction_CAST(os_pidfd_open), METH_FASTCALL|METH_KEYWORDS, os_pidfd_open__doc__}, static PyObject * os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags); @@ -4110,8 +5182,31 @@ static PyObject * os_pidfd_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pid), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"pid", "flags", NULL}; - static _PyArg_Parser _parser = {"" _Py_PARSE_PID "|O&:pidfd_open", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" _Py_PARSE_PID "|O&:pidfd_open", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE pid_t pid; unsigned int flags = 0; @@ -4127,6 +5222,147 @@ exit: #endif /* (defined(__linux__) && defined(__NR_pidfd_open)) */ +#if defined(HAVE_SETNS) + +PyDoc_STRVAR(os_setns__doc__, +"setns($module, /, fd, nstype=0)\n" +"--\n" +"\n" +"Move the calling thread into different namespaces.\n" +"\n" +" fd\n" +" A file descriptor to a namespace.\n" +" nstype\n" +" Type of namespace."); + +#define OS_SETNS_METHODDEF \ + {"setns", _PyCFunction_CAST(os_setns), METH_FASTCALL|METH_KEYWORDS, os_setns__doc__}, + +static PyObject * +os_setns_impl(PyObject *module, int fd, int nstype); + +static PyObject * +os_setns(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(nstype), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"fd", "nstype", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "setns", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + int fd; + int nstype = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + nstype = _PyLong_AsInt(args[1]); + if (nstype == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = os_setns_impl(module, fd, nstype); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SETNS) */ + +#if defined(HAVE_UNSHARE) + +PyDoc_STRVAR(os_unshare__doc__, +"unshare($module, /, flags)\n" +"--\n" +"\n" +"Disassociate parts of a process (or thread) execution context.\n" +"\n" +" flags\n" +" Namespaces to be unshared."); + +#define OS_UNSHARE_METHODDEF \ + {"unshare", _PyCFunction_CAST(os_unshare), METH_FASTCALL|METH_KEYWORDS, os_unshare__doc__}, + +static PyObject * +os_unshare_impl(PyObject *module, int flags); + +static PyObject * +os_unshare(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"flags", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unshare", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + int flags; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + flags = _PyLong_AsInt(args[0]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = os_unshare_impl(module, flags); + +exit: + return return_value; +} + +#endif /* defined(HAVE_UNSHARE) */ + #if (defined(HAVE_READLINK) || defined(MS_WINDOWS)) PyDoc_STRVAR(os_readlink__doc__, @@ -4142,7 +5378,7 @@ PyDoc_STRVAR(os_readlink__doc__, "using it will raise a NotImplementedError."); #define OS_READLINK_METHODDEF \ - {"readlink", (PyCFunction)(void(*)(void))os_readlink, METH_FASTCALL|METH_KEYWORDS, os_readlink__doc__}, + {"readlink", _PyCFunction_CAST(os_readlink), METH_FASTCALL|METH_KEYWORDS, os_readlink__doc__}, static PyObject * os_readlink_impl(PyObject *module, path_t *path, int dir_fd); @@ -4151,8 +5387,31 @@ static PyObject * os_readlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "readlink", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "readlink", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("readlink", "path", 0, 0); @@ -4202,7 +5461,7 @@ PyDoc_STRVAR(os_symlink__doc__, " If it is unavailable, using it will raise a NotImplementedError."); #define OS_SYMLINK_METHODDEF \ - {"symlink", (PyCFunction)(void(*)(void))os_symlink, METH_FASTCALL|METH_KEYWORDS, os_symlink__doc__}, + {"symlink", _PyCFunction_CAST(os_symlink), METH_FASTCALL|METH_KEYWORDS, os_symlink__doc__}, static PyObject * os_symlink_impl(PyObject *module, path_t *src, path_t *dst, @@ -4212,8 +5471,31 @@ static PyObject * os_symlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(target_is_directory), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"src", "dst", "target_is_directory", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "symlink", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "symlink", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t src = PATH_T_INITIALIZE("symlink", "src", 0, 0); @@ -4352,7 +5634,7 @@ PyDoc_STRVAR(os_setpgid__doc__, "Call the system call setpgid(pid, pgrp)."); #define OS_SETPGID_METHODDEF \ - {"setpgid", (PyCFunction)(void(*)(void))os_setpgid, METH_FASTCALL, os_setpgid__doc__}, + {"setpgid", _PyCFunction_CAST(os_setpgid), METH_FASTCALL, os_setpgid__doc__}, static PyObject * os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp); @@ -4417,7 +5699,7 @@ PyDoc_STRVAR(os_tcsetpgrp__doc__, "Set the process group associated with the terminal specified by fd."); #define OS_TCSETPGRP_METHODDEF \ - {"tcsetpgrp", (PyCFunction)(void(*)(void))os_tcsetpgrp, METH_FASTCALL, os_tcsetpgrp__doc__}, + {"tcsetpgrp", _PyCFunction_CAST(os_tcsetpgrp), METH_FASTCALL, os_tcsetpgrp__doc__}, static PyObject * os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid); @@ -4453,7 +5735,7 @@ PyDoc_STRVAR(os_open__doc__, " If it is unavailable, using it will raise a NotImplementedError."); #define OS_OPEN_METHODDEF \ - {"open", (PyCFunction)(void(*)(void))os_open, METH_FASTCALL|METH_KEYWORDS, os_open__doc__}, + {"open", _PyCFunction_CAST(os_open), METH_FASTCALL|METH_KEYWORDS, os_open__doc__}, static int os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd); @@ -4462,8 +5744,31 @@ static PyObject * os_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(flags), &_Py_ID(mode), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "open", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "open", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("open", "path", 0, 0); @@ -4523,7 +5828,7 @@ PyDoc_STRVAR(os_close__doc__, "Close a file descriptor."); #define OS_CLOSE_METHODDEF \ - {"close", (PyCFunction)(void(*)(void))os_close, METH_FASTCALL|METH_KEYWORDS, os_close__doc__}, + {"close", _PyCFunction_CAST(os_close), METH_FASTCALL|METH_KEYWORDS, os_close__doc__}, static PyObject * os_close_impl(PyObject *module, int fd); @@ -4532,8 +5837,31 @@ static PyObject * os_close(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "close", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "close", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -4558,7 +5886,7 @@ PyDoc_STRVAR(os_closerange__doc__, "Closes all file descriptors in [fd_low, fd_high), ignoring errors."); #define OS_CLOSERANGE_METHODDEF \ - {"closerange", (PyCFunction)(void(*)(void))os_closerange, METH_FASTCALL, os_closerange__doc__}, + {"closerange", _PyCFunction_CAST(os_closerange), METH_FASTCALL, os_closerange__doc__}, static PyObject * os_closerange_impl(PyObject *module, int fd_low, int fd_high); @@ -4620,6 +5948,8 @@ exit: return return_value; } +#if ((defined(HAVE_DUP3) || defined(F_DUPFD) || defined(MS_WINDOWS))) + PyDoc_STRVAR(os_dup2__doc__, "dup2($module, /, fd, fd2, inheritable=True)\n" "--\n" @@ -4627,7 +5957,7 @@ PyDoc_STRVAR(os_dup2__doc__, "Duplicate file descriptor."); #define OS_DUP2_METHODDEF \ - {"dup2", (PyCFunction)(void(*)(void))os_dup2, METH_FASTCALL|METH_KEYWORDS, os_dup2__doc__}, + {"dup2", _PyCFunction_CAST(os_dup2), METH_FASTCALL|METH_KEYWORDS, os_dup2__doc__}, static int os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable); @@ -4636,8 +5966,31 @@ static PyObject * os_dup2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(fd2), &_Py_ID(inheritable), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", "fd2", "inheritable", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "dup2", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "dup2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; int fd; @@ -4675,6 +6028,8 @@ exit: return return_value; } +#endif /* ((defined(HAVE_DUP3) || defined(F_DUPFD) || defined(MS_WINDOWS))) */ + #if defined(HAVE_LOCKF) PyDoc_STRVAR(os_lockf__doc__, @@ -4691,7 +6046,7 @@ PyDoc_STRVAR(os_lockf__doc__, " The number of bytes to lock, starting at the current position."); #define OS_LOCKF_METHODDEF \ - {"lockf", (PyCFunction)(void(*)(void))os_lockf, METH_FASTCALL, os_lockf__doc__}, + {"lockf", _PyCFunction_CAST(os_lockf), METH_FASTCALL, os_lockf__doc__}, static PyObject * os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length); @@ -4736,7 +6091,7 @@ PyDoc_STRVAR(os_lseek__doc__, "relative to the beginning of the file."); #define OS_LSEEK_METHODDEF \ - {"lseek", (PyCFunction)(void(*)(void))os_lseek, METH_FASTCALL, os_lseek__doc__}, + {"lseek", _PyCFunction_CAST(os_lseek), METH_FASTCALL, os_lseek__doc__}, static Py_off_t os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how); @@ -4781,7 +6136,7 @@ PyDoc_STRVAR(os_read__doc__, "Read from a file descriptor. Returns a bytes object."); #define OS_READ_METHODDEF \ - {"read", (PyCFunction)(void(*)(void))os_read, METH_FASTCALL, os_read__doc__}, + {"read", _PyCFunction_CAST(os_read), METH_FASTCALL, os_read__doc__}, static PyObject * os_read_impl(PyObject *module, int fd, Py_ssize_t length); @@ -4835,7 +6190,7 @@ PyDoc_STRVAR(os_readv__doc__, "which may be less than the total capacity of all the buffers."); #define OS_READV_METHODDEF \ - {"readv", (PyCFunction)(void(*)(void))os_readv, METH_FASTCALL, os_readv__doc__}, + {"readv", _PyCFunction_CAST(os_readv), METH_FASTCALL, os_readv__doc__}, static Py_ssize_t os_readv_impl(PyObject *module, int fd, PyObject *buffers); @@ -4880,7 +6235,7 @@ PyDoc_STRVAR(os_pread__doc__, "the beginning of the file. The file offset remains unchanged."); #define OS_PREAD_METHODDEF \ - {"pread", (PyCFunction)(void(*)(void))os_pread, METH_FASTCALL, os_pread__doc__}, + {"pread", _PyCFunction_CAST(os_pread), METH_FASTCALL, os_pread__doc__}, static PyObject * os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset); @@ -4946,7 +6301,7 @@ PyDoc_STRVAR(os_preadv__doc__, "Using non-zero flags requires Linux 4.6 or newer."); #define OS_PREADV_METHODDEF \ - {"preadv", (PyCFunction)(void(*)(void))os_preadv, METH_FASTCALL, os_preadv__doc__}, + {"preadv", _PyCFunction_CAST(os_preadv), METH_FASTCALL, os_preadv__doc__}, static Py_ssize_t os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, @@ -5000,7 +6355,7 @@ PyDoc_STRVAR(os_write__doc__, "Write a bytes object to a file descriptor."); #define OS_WRITE_METHODDEF \ - {"write", (PyCFunction)(void(*)(void))os_write, METH_FASTCALL, os_write__doc__}, + {"write", _PyCFunction_CAST(os_write), METH_FASTCALL, os_write__doc__}, static Py_ssize_t os_write_impl(PyObject *module, int fd, Py_buffer *data); @@ -5052,7 +6407,7 @@ PyDoc_STRVAR(os_sendfile__doc__, "Copy count bytes from file descriptor in_fd to file descriptor out_fd."); #define OS_SENDFILE_METHODDEF \ - {"sendfile", (PyCFunction)(void(*)(void))os_sendfile, METH_FASTCALL|METH_KEYWORDS, os_sendfile__doc__}, + {"sendfile", _PyCFunction_CAST(os_sendfile), METH_FASTCALL|METH_KEYWORDS, os_sendfile__doc__}, static PyObject * os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset, @@ -5063,8 +6418,31 @@ static PyObject * os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 7 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(out_fd), &_Py_ID(in_fd), &_Py_ID(offset), &_Py_ID(count), &_Py_ID(headers), &_Py_ID(trailers), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", "headers", "trailers", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sendfile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sendfile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[7]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; int out_fd; @@ -5131,7 +6509,7 @@ PyDoc_STRVAR(os_sendfile__doc__, "Copy count bytes from file descriptor in_fd to file descriptor out_fd."); #define OS_SENDFILE_METHODDEF \ - {"sendfile", (PyCFunction)(void(*)(void))os_sendfile, METH_FASTCALL|METH_KEYWORDS, os_sendfile__doc__}, + {"sendfile", _PyCFunction_CAST(os_sendfile), METH_FASTCALL|METH_KEYWORDS, os_sendfile__doc__}, static PyObject * os_sendfile_impl(PyObject *module, int out_fd, int in_fd, Py_off_t offset, @@ -5142,8 +6520,31 @@ static PyObject * os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 7 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(out_fd), &_Py_ID(in_fd), &_Py_ID(offset), &_Py_ID(count), &_Py_ID(headers), &_Py_ID(trailers), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", "headers", "trailers", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sendfile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sendfile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[7]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; int out_fd; @@ -5218,7 +6619,7 @@ PyDoc_STRVAR(os_sendfile__doc__, "Copy count bytes from file descriptor in_fd to file descriptor out_fd."); #define OS_SENDFILE_METHODDEF \ - {"sendfile", (PyCFunction)(void(*)(void))os_sendfile, METH_FASTCALL|METH_KEYWORDS, os_sendfile__doc__}, + {"sendfile", _PyCFunction_CAST(os_sendfile), METH_FASTCALL|METH_KEYWORDS, os_sendfile__doc__}, static PyObject * os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj, @@ -5228,8 +6629,31 @@ static PyObject * os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(out_fd), &_Py_ID(in_fd), &_Py_ID(offset), &_Py_ID(count), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sendfile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sendfile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; int out_fd; int in_fd; @@ -5278,7 +6702,7 @@ PyDoc_STRVAR(os__fcopyfile__doc__, "Efficiently copy content or metadata of 2 regular file descriptors (macOS)."); #define OS__FCOPYFILE_METHODDEF \ - {"_fcopyfile", (PyCFunction)(void(*)(void))os__fcopyfile, METH_FASTCALL, os__fcopyfile__doc__}, + {"_fcopyfile", _PyCFunction_CAST(os__fcopyfile), METH_FASTCALL, os__fcopyfile__doc__}, static PyObject * os__fcopyfile_impl(PyObject *module, int in_fd, int out_fd, int flags); @@ -5324,7 +6748,7 @@ PyDoc_STRVAR(os_fstat__doc__, "Equivalent to os.stat(fd)."); #define OS_FSTAT_METHODDEF \ - {"fstat", (PyCFunction)(void(*)(void))os_fstat, METH_FASTCALL|METH_KEYWORDS, os_fstat__doc__}, + {"fstat", _PyCFunction_CAST(os_fstat), METH_FASTCALL|METH_KEYWORDS, os_fstat__doc__}, static PyObject * os_fstat_impl(PyObject *module, int fd); @@ -5333,8 +6757,31 @@ static PyObject * os_fstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fstat", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fstat", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -5463,7 +6910,7 @@ PyDoc_STRVAR(os_writev__doc__, "buffers must be a sequence of bytes-like objects."); #define OS_WRITEV_METHODDEF \ - {"writev", (PyCFunction)(void(*)(void))os_writev, METH_FASTCALL, os_writev__doc__}, + {"writev", _PyCFunction_CAST(os_writev), METH_FASTCALL, os_writev__doc__}, static Py_ssize_t os_writev_impl(PyObject *module, int fd, PyObject *buffers); @@ -5509,7 +6956,7 @@ PyDoc_STRVAR(os_pwrite__doc__, "current file offset."); #define OS_PWRITE_METHODDEF \ - {"pwrite", (PyCFunction)(void(*)(void))os_pwrite, METH_FASTCALL, os_pwrite__doc__}, + {"pwrite", _PyCFunction_CAST(os_pwrite), METH_FASTCALL, os_pwrite__doc__}, static Py_ssize_t os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset); @@ -5581,7 +7028,7 @@ PyDoc_STRVAR(os_pwritev__doc__, "Using non-zero flags requires Linux 4.7 or newer."); #define OS_PWRITEV_METHODDEF \ - {"pwritev", (PyCFunction)(void(*)(void))os_pwritev, METH_FASTCALL, os_pwritev__doc__}, + {"pwritev", _PyCFunction_CAST(os_pwritev), METH_FASTCALL, os_pwritev__doc__}, static Py_ssize_t os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, @@ -5652,7 +7099,7 @@ PyDoc_STRVAR(os_copy_file_range__doc__, "respectively for offset_dst."); #define OS_COPY_FILE_RANGE_METHODDEF \ - {"copy_file_range", (PyCFunction)(void(*)(void))os_copy_file_range, METH_FASTCALL|METH_KEYWORDS, os_copy_file_range__doc__}, + {"copy_file_range", _PyCFunction_CAST(os_copy_file_range), METH_FASTCALL|METH_KEYWORDS, os_copy_file_range__doc__}, static PyObject * os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count, @@ -5662,8 +7109,31 @@ static PyObject * os_copy_file_range(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(count), &_Py_ID(offset_src), &_Py_ID(offset_dst), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"src", "dst", "count", "offset_src", "offset_dst", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "copy_file_range", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "copy_file_range", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; int src; @@ -5742,7 +7212,7 @@ PyDoc_STRVAR(os_splice__doc__, "descriptor that refers to a pipe must be None."); #define OS_SPLICE_METHODDEF \ - {"splice", (PyCFunction)(void(*)(void))os_splice, METH_FASTCALL|METH_KEYWORDS, os_splice__doc__}, + {"splice", _PyCFunction_CAST(os_splice), METH_FASTCALL|METH_KEYWORDS, os_splice__doc__}, static PyObject * os_splice_impl(PyObject *module, int src, int dst, Py_ssize_t count, @@ -5753,8 +7223,31 @@ static PyObject * os_splice(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 6 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(count), &_Py_ID(offset_src), &_Py_ID(offset_dst), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"src", "dst", "count", "offset_src", "offset_dst", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "splice", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "splice", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; int src; @@ -5829,7 +7322,7 @@ PyDoc_STRVAR(os_mkfifo__doc__, " If it is unavailable, using it will raise a NotImplementedError."); #define OS_MKFIFO_METHODDEF \ - {"mkfifo", (PyCFunction)(void(*)(void))os_mkfifo, METH_FASTCALL|METH_KEYWORDS, os_mkfifo__doc__}, + {"mkfifo", _PyCFunction_CAST(os_mkfifo), METH_FASTCALL|METH_KEYWORDS, os_mkfifo__doc__}, static PyObject * os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd); @@ -5838,8 +7331,31 @@ static PyObject * os_mkfifo(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "mode", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "mkfifo", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "mkfifo", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0); @@ -5905,7 +7421,7 @@ PyDoc_STRVAR(os_mknod__doc__, " If it is unavailable, using it will raise a NotImplementedError."); #define OS_MKNOD_METHODDEF \ - {"mknod", (PyCFunction)(void(*)(void))os_mknod, METH_FASTCALL|METH_KEYWORDS, os_mknod__doc__}, + {"mknod", _PyCFunction_CAST(os_mknod), METH_FASTCALL|METH_KEYWORDS, os_mknod__doc__}, static PyObject * os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device, @@ -5915,8 +7431,31 @@ static PyObject * os_mknod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(device), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "mode", "device", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "mknod", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "mknod", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0); @@ -6051,7 +7590,7 @@ PyDoc_STRVAR(os_makedev__doc__, "Composes a raw device number from the major and minor device numbers."); #define OS_MAKEDEV_METHODDEF \ - {"makedev", (PyCFunction)(void(*)(void))os_makedev, METH_FASTCALL, os_makedev__doc__}, + {"makedev", _PyCFunction_CAST(os_makedev), METH_FASTCALL, os_makedev__doc__}, static dev_t os_makedev_impl(PyObject *module, int major, int minor); @@ -6096,7 +7635,7 @@ PyDoc_STRVAR(os_ftruncate__doc__, "Truncate a file, specified by file descriptor, to a specific length."); #define OS_FTRUNCATE_METHODDEF \ - {"ftruncate", (PyCFunction)(void(*)(void))os_ftruncate, METH_FASTCALL, os_ftruncate__doc__}, + {"ftruncate", _PyCFunction_CAST(os_ftruncate), METH_FASTCALL, os_ftruncate__doc__}, static PyObject * os_ftruncate_impl(PyObject *module, int fd, Py_off_t length); @@ -6138,7 +7677,7 @@ PyDoc_STRVAR(os_truncate__doc__, " If this functionality is unavailable, using it raises an exception."); #define OS_TRUNCATE_METHODDEF \ - {"truncate", (PyCFunction)(void(*)(void))os_truncate, METH_FASTCALL|METH_KEYWORDS, os_truncate__doc__}, + {"truncate", _PyCFunction_CAST(os_truncate), METH_FASTCALL|METH_KEYWORDS, os_truncate__doc__}, static PyObject * os_truncate_impl(PyObject *module, path_t *path, Py_off_t length); @@ -6147,8 +7686,31 @@ static PyObject * os_truncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(length), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "truncate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "truncate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; path_t path = PATH_T_INITIALIZE("truncate", "path", 0, PATH_HAVE_FTRUNCATE); Py_off_t length; @@ -6186,7 +7748,7 @@ PyDoc_STRVAR(os_posix_fallocate__doc__, "starting at offset bytes from the beginning and continuing for length bytes."); #define OS_POSIX_FALLOCATE_METHODDEF \ - {"posix_fallocate", (PyCFunction)(void(*)(void))os_posix_fallocate, METH_FASTCALL, os_posix_fallocate__doc__}, + {"posix_fallocate", _PyCFunction_CAST(os_posix_fallocate), METH_FASTCALL, os_posix_fallocate__doc__}, static PyObject * os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset, @@ -6238,7 +7800,7 @@ PyDoc_STRVAR(os_posix_fadvise__doc__, "POSIX_FADV_DONTNEED."); #define OS_POSIX_FADVISE_METHODDEF \ - {"posix_fadvise", (PyCFunction)(void(*)(void))os_posix_fadvise, METH_FASTCALL, os_posix_fadvise__doc__}, + {"posix_fadvise", _PyCFunction_CAST(os_posix_fadvise), METH_FASTCALL, os_posix_fadvise__doc__}, static PyObject * os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset, @@ -6287,7 +7849,7 @@ PyDoc_STRVAR(os_putenv__doc__, "Change or add an environment variable."); #define OS_PUTENV_METHODDEF \ - {"putenv", (PyCFunction)(void(*)(void))os_putenv, METH_FASTCALL, os_putenv__doc__}, + {"putenv", _PyCFunction_CAST(os_putenv), METH_FASTCALL, os_putenv__doc__}, static PyObject * os_putenv_impl(PyObject *module, PyObject *name, PyObject *value); @@ -6335,7 +7897,7 @@ PyDoc_STRVAR(os_putenv__doc__, "Change or add an environment variable."); #define OS_PUTENV_METHODDEF \ - {"putenv", (PyCFunction)(void(*)(void))os_putenv, METH_FASTCALL, os_putenv__doc__}, + {"putenv", _PyCFunction_CAST(os_putenv), METH_FASTCALL, os_putenv__doc__}, static PyObject * os_putenv_impl(PyObject *module, PyObject *name, PyObject *value); @@ -6516,7 +8078,7 @@ PyDoc_STRVAR(os_WIFCONTINUED__doc__, "job control stop."); #define OS_WIFCONTINUED_METHODDEF \ - {"WIFCONTINUED", (PyCFunction)(void(*)(void))os_WIFCONTINUED, METH_FASTCALL|METH_KEYWORDS, os_WIFCONTINUED__doc__}, + {"WIFCONTINUED", _PyCFunction_CAST(os_WIFCONTINUED), METH_FASTCALL|METH_KEYWORDS, os_WIFCONTINUED__doc__}, static int os_WIFCONTINUED_impl(PyObject *module, int status); @@ -6525,8 +8087,31 @@ static PyObject * os_WIFCONTINUED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WIFCONTINUED", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WIFCONTINUED", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6560,7 +8145,7 @@ PyDoc_STRVAR(os_WIFSTOPPED__doc__, "Return True if the process returning status was stopped."); #define OS_WIFSTOPPED_METHODDEF \ - {"WIFSTOPPED", (PyCFunction)(void(*)(void))os_WIFSTOPPED, METH_FASTCALL|METH_KEYWORDS, os_WIFSTOPPED__doc__}, + {"WIFSTOPPED", _PyCFunction_CAST(os_WIFSTOPPED), METH_FASTCALL|METH_KEYWORDS, os_WIFSTOPPED__doc__}, static int os_WIFSTOPPED_impl(PyObject *module, int status); @@ -6569,8 +8154,31 @@ static PyObject * os_WIFSTOPPED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WIFSTOPPED", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WIFSTOPPED", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6604,7 +8212,7 @@ PyDoc_STRVAR(os_WIFSIGNALED__doc__, "Return True if the process returning status was terminated by a signal."); #define OS_WIFSIGNALED_METHODDEF \ - {"WIFSIGNALED", (PyCFunction)(void(*)(void))os_WIFSIGNALED, METH_FASTCALL|METH_KEYWORDS, os_WIFSIGNALED__doc__}, + {"WIFSIGNALED", _PyCFunction_CAST(os_WIFSIGNALED), METH_FASTCALL|METH_KEYWORDS, os_WIFSIGNALED__doc__}, static int os_WIFSIGNALED_impl(PyObject *module, int status); @@ -6613,8 +8221,31 @@ static PyObject * os_WIFSIGNALED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WIFSIGNALED", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WIFSIGNALED", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6648,7 +8279,7 @@ PyDoc_STRVAR(os_WIFEXITED__doc__, "Return True if the process returning status exited via the exit() system call."); #define OS_WIFEXITED_METHODDEF \ - {"WIFEXITED", (PyCFunction)(void(*)(void))os_WIFEXITED, METH_FASTCALL|METH_KEYWORDS, os_WIFEXITED__doc__}, + {"WIFEXITED", _PyCFunction_CAST(os_WIFEXITED), METH_FASTCALL|METH_KEYWORDS, os_WIFEXITED__doc__}, static int os_WIFEXITED_impl(PyObject *module, int status); @@ -6657,8 +8288,31 @@ static PyObject * os_WIFEXITED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WIFEXITED", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WIFEXITED", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6692,7 +8346,7 @@ PyDoc_STRVAR(os_WEXITSTATUS__doc__, "Return the process return code from status."); #define OS_WEXITSTATUS_METHODDEF \ - {"WEXITSTATUS", (PyCFunction)(void(*)(void))os_WEXITSTATUS, METH_FASTCALL|METH_KEYWORDS, os_WEXITSTATUS__doc__}, + {"WEXITSTATUS", _PyCFunction_CAST(os_WEXITSTATUS), METH_FASTCALL|METH_KEYWORDS, os_WEXITSTATUS__doc__}, static int os_WEXITSTATUS_impl(PyObject *module, int status); @@ -6701,8 +8355,31 @@ static PyObject * os_WEXITSTATUS(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WEXITSTATUS", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WEXITSTATUS", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6736,7 +8413,7 @@ PyDoc_STRVAR(os_WTERMSIG__doc__, "Return the signal that terminated the process that provided the status value."); #define OS_WTERMSIG_METHODDEF \ - {"WTERMSIG", (PyCFunction)(void(*)(void))os_WTERMSIG, METH_FASTCALL|METH_KEYWORDS, os_WTERMSIG__doc__}, + {"WTERMSIG", _PyCFunction_CAST(os_WTERMSIG), METH_FASTCALL|METH_KEYWORDS, os_WTERMSIG__doc__}, static int os_WTERMSIG_impl(PyObject *module, int status); @@ -6745,8 +8422,31 @@ static PyObject * os_WTERMSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WTERMSIG", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WTERMSIG", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6780,7 +8480,7 @@ PyDoc_STRVAR(os_WSTOPSIG__doc__, "Return the signal that stopped the process that provided the status value."); #define OS_WSTOPSIG_METHODDEF \ - {"WSTOPSIG", (PyCFunction)(void(*)(void))os_WSTOPSIG, METH_FASTCALL|METH_KEYWORDS, os_WSTOPSIG__doc__}, + {"WSTOPSIG", _PyCFunction_CAST(os_WSTOPSIG), METH_FASTCALL|METH_KEYWORDS, os_WSTOPSIG__doc__}, static int os_WSTOPSIG_impl(PyObject *module, int status); @@ -6789,8 +8489,31 @@ static PyObject * os_WSTOPSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WSTOPSIG", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WSTOPSIG", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6862,7 +8585,7 @@ PyDoc_STRVAR(os_statvfs__doc__, " If this functionality is unavailable, using it raises an exception."); #define OS_STATVFS_METHODDEF \ - {"statvfs", (PyCFunction)(void(*)(void))os_statvfs, METH_FASTCALL|METH_KEYWORDS, os_statvfs__doc__}, + {"statvfs", _PyCFunction_CAST(os_statvfs), METH_FASTCALL|METH_KEYWORDS, os_statvfs__doc__}, static PyObject * os_statvfs_impl(PyObject *module, path_t *path); @@ -6871,8 +8594,31 @@ static PyObject * os_statvfs(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "statvfs", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "statvfs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, PATH_HAVE_FSTATVFS); @@ -6903,7 +8649,7 @@ PyDoc_STRVAR(os__getdiskusage__doc__, "Return disk usage statistics about the given path as a (total, free) tuple."); #define OS__GETDISKUSAGE_METHODDEF \ - {"_getdiskusage", (PyCFunction)(void(*)(void))os__getdiskusage, METH_FASTCALL|METH_KEYWORDS, os__getdiskusage__doc__}, + {"_getdiskusage", _PyCFunction_CAST(os__getdiskusage), METH_FASTCALL|METH_KEYWORDS, os__getdiskusage__doc__}, static PyObject * os__getdiskusage_impl(PyObject *module, path_t *path); @@ -6912,8 +8658,31 @@ static PyObject * os__getdiskusage(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_getdiskusage", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_getdiskusage", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("_getdiskusage", "path", 0, 0); @@ -6946,7 +8715,7 @@ PyDoc_STRVAR(os_fpathconf__doc__, "If there is no limit, return -1."); #define OS_FPATHCONF_METHODDEF \ - {"fpathconf", (PyCFunction)(void(*)(void))os_fpathconf, METH_FASTCALL, os_fpathconf__doc__}, + {"fpathconf", _PyCFunction_CAST(os_fpathconf), METH_FASTCALL, os_fpathconf__doc__}, static long os_fpathconf_impl(PyObject *module, int fd, int name); @@ -6993,7 +8762,7 @@ PyDoc_STRVAR(os_pathconf__doc__, " If this functionality is unavailable, using it raises an exception."); #define OS_PATHCONF_METHODDEF \ - {"pathconf", (PyCFunction)(void(*)(void))os_pathconf, METH_FASTCALL|METH_KEYWORDS, os_pathconf__doc__}, + {"pathconf", _PyCFunction_CAST(os_pathconf), METH_FASTCALL|METH_KEYWORDS, os_pathconf__doc__}, static long os_pathconf_impl(PyObject *module, path_t *path, int name); @@ -7002,8 +8771,31 @@ static PyObject * os_pathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "pathconf", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "pathconf", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, PATH_HAVE_FPATHCONF); int name; @@ -7157,7 +8949,7 @@ PyDoc_STRVAR(os_startfile__doc__, "the underlying Win32 ShellExecute function doesn\'t work if it is."); #define OS_STARTFILE_METHODDEF \ - {"startfile", (PyCFunction)(void(*)(void))os_startfile, METH_FASTCALL|METH_KEYWORDS, os_startfile__doc__}, + {"startfile", _PyCFunction_CAST(os_startfile), METH_FASTCALL|METH_KEYWORDS, os_startfile__doc__}, static PyObject * os_startfile_impl(PyObject *module, path_t *filepath, @@ -7168,8 +8960,31 @@ static PyObject * os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(filepath), &_Py_ID(operation), &_Py_ID(arguments), &_Py_ID(cwd), &_Py_ID(show_cmd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"filepath", "operation", "arguments", "cwd", "show_cmd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "startfile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "startfile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t filepath = PATH_T_INITIALIZE("startfile", "filepath", 0, 0); @@ -7193,11 +9008,7 @@ os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject _PyArg_BadArgument("startfile", "argument 'operation'", "str", args[1]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - operation = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ operation = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (operation == NULL) { goto exit; } @@ -7210,11 +9021,7 @@ os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject _PyArg_BadArgument("startfile", "argument 'arguments'", "str", args[2]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - arguments = _PyUnicode_AsUnicode(args[2]); - #else /* USE_UNICODE_WCHAR_CACHE */ arguments = PyUnicode_AsWideCharString(args[2], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (arguments == NULL) { goto exit; } @@ -7241,13 +9048,9 @@ exit: /* Cleanup for filepath */ path_cleanup(&filepath); /* Cleanup for operation */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)operation); - #endif /* USE_UNICODE_WCHAR_CACHE */ /* Cleanup for arguments */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)arguments); - #endif /* USE_UNICODE_WCHAR_CACHE */ /* Cleanup for cwd */ path_cleanup(&cwd); @@ -7292,7 +9095,7 @@ PyDoc_STRVAR(os_device_encoding__doc__, "If the device is not a terminal, return None."); #define OS_DEVICE_ENCODING_METHODDEF \ - {"device_encoding", (PyCFunction)(void(*)(void))os_device_encoding, METH_FASTCALL|METH_KEYWORDS, os_device_encoding__doc__}, + {"device_encoding", _PyCFunction_CAST(os_device_encoding), METH_FASTCALL|METH_KEYWORDS, os_device_encoding__doc__}, static PyObject * os_device_encoding_impl(PyObject *module, int fd); @@ -7301,8 +9104,31 @@ static PyObject * os_device_encoding(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "device_encoding", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "device_encoding", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -7329,7 +9155,7 @@ PyDoc_STRVAR(os_setresuid__doc__, "Set the current process\'s real, effective, and saved user ids."); #define OS_SETRESUID_METHODDEF \ - {"setresuid", (PyCFunction)(void(*)(void))os_setresuid, METH_FASTCALL, os_setresuid__doc__}, + {"setresuid", _PyCFunction_CAST(os_setresuid), METH_FASTCALL, os_setresuid__doc__}, static PyObject * os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid); @@ -7371,7 +9197,7 @@ PyDoc_STRVAR(os_setresgid__doc__, "Set the current process\'s real, effective, and saved group ids."); #define OS_SETRESGID_METHODDEF \ - {"setresgid", (PyCFunction)(void(*)(void))os_setresgid, METH_FASTCALL, os_setresgid__doc__}, + {"setresgid", _PyCFunction_CAST(os_setresgid), METH_FASTCALL, os_setresgid__doc__}, static PyObject * os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid); @@ -7462,7 +9288,7 @@ PyDoc_STRVAR(os_getxattr__doc__, " the link points to."); #define OS_GETXATTR_METHODDEF \ - {"getxattr", (PyCFunction)(void(*)(void))os_getxattr, METH_FASTCALL|METH_KEYWORDS, os_getxattr__doc__}, + {"getxattr", _PyCFunction_CAST(os_getxattr), METH_FASTCALL|METH_KEYWORDS, os_getxattr__doc__}, static PyObject * os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute, @@ -7472,8 +9298,31 @@ static PyObject * os_getxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(attribute), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "attribute", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "getxattr", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getxattr", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 1); @@ -7526,7 +9375,7 @@ PyDoc_STRVAR(os_setxattr__doc__, " the link points to."); #define OS_SETXATTR_METHODDEF \ - {"setxattr", (PyCFunction)(void(*)(void))os_setxattr, METH_FASTCALL|METH_KEYWORDS, os_setxattr__doc__}, + {"setxattr", _PyCFunction_CAST(os_setxattr), METH_FASTCALL|METH_KEYWORDS, os_setxattr__doc__}, static PyObject * os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute, @@ -7536,8 +9385,31 @@ static PyObject * os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(attribute), &_Py_ID(value), &_Py_ID(flags), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "attribute", "value", "flags", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "setxattr", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "setxattr", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; path_t path = PATH_T_INITIALIZE("setxattr", "path", 0, 1); @@ -7615,7 +9487,7 @@ PyDoc_STRVAR(os_removexattr__doc__, " the link points to."); #define OS_REMOVEXATTR_METHODDEF \ - {"removexattr", (PyCFunction)(void(*)(void))os_removexattr, METH_FASTCALL|METH_KEYWORDS, os_removexattr__doc__}, + {"removexattr", _PyCFunction_CAST(os_removexattr), METH_FASTCALL|METH_KEYWORDS, os_removexattr__doc__}, static PyObject * os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute, @@ -7625,8 +9497,31 @@ static PyObject * os_removexattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(attribute), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "attribute", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "removexattr", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "removexattr", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 1); @@ -7679,7 +9574,7 @@ PyDoc_STRVAR(os_listxattr__doc__, " the link points to."); #define OS_LISTXATTR_METHODDEF \ - {"listxattr", (PyCFunction)(void(*)(void))os_listxattr, METH_FASTCALL|METH_KEYWORDS, os_listxattr__doc__}, + {"listxattr", _PyCFunction_CAST(os_listxattr), METH_FASTCALL|METH_KEYWORDS, os_listxattr__doc__}, static PyObject * os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks); @@ -7688,8 +9583,31 @@ static PyObject * os_listxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "listxattr", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "listxattr", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 1); @@ -7774,7 +9692,7 @@ PyDoc_STRVAR(os_memfd_create__doc__, "\n"); #define OS_MEMFD_CREATE_METHODDEF \ - {"memfd_create", (PyCFunction)(void(*)(void))os_memfd_create, METH_FASTCALL|METH_KEYWORDS, os_memfd_create__doc__}, + {"memfd_create", _PyCFunction_CAST(os_memfd_create), METH_FASTCALL|METH_KEYWORDS, os_memfd_create__doc__}, static PyObject * os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags); @@ -7783,8 +9701,31 @@ static PyObject * os_memfd_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "memfd_create", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "memfd_create", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *name = NULL; @@ -7816,7 +9757,7 @@ exit: #endif /* defined(HAVE_MEMFD_CREATE) */ -#if defined(HAVE_EVENTFD) +#if (defined(HAVE_EVENTFD) && defined(EFD_CLOEXEC)) PyDoc_STRVAR(os_eventfd__doc__, "eventfd($module, /, initval, flags=EFD_CLOEXEC)\n" @@ -7825,7 +9766,7 @@ PyDoc_STRVAR(os_eventfd__doc__, "Creates and returns an event notification file descriptor."); #define OS_EVENTFD_METHODDEF \ - {"eventfd", (PyCFunction)(void(*)(void))os_eventfd, METH_FASTCALL|METH_KEYWORDS, os_eventfd__doc__}, + {"eventfd", _PyCFunction_CAST(os_eventfd), METH_FASTCALL|METH_KEYWORDS, os_eventfd__doc__}, static PyObject * os_eventfd_impl(PyObject *module, unsigned int initval, int flags); @@ -7834,8 +9775,31 @@ static PyObject * os_eventfd(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(initval), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"initval", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "eventfd", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "eventfd", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; unsigned int initval; @@ -7862,9 +9826,9 @@ exit: return return_value; } -#endif /* defined(HAVE_EVENTFD) */ +#endif /* (defined(HAVE_EVENTFD) && defined(EFD_CLOEXEC)) */ -#if defined(HAVE_EVENTFD) +#if (defined(HAVE_EVENTFD) && defined(EFD_CLOEXEC)) PyDoc_STRVAR(os_eventfd_read__doc__, "eventfd_read($module, /, fd)\n" @@ -7873,7 +9837,7 @@ PyDoc_STRVAR(os_eventfd_read__doc__, "Read eventfd value"); #define OS_EVENTFD_READ_METHODDEF \ - {"eventfd_read", (PyCFunction)(void(*)(void))os_eventfd_read, METH_FASTCALL|METH_KEYWORDS, os_eventfd_read__doc__}, + {"eventfd_read", _PyCFunction_CAST(os_eventfd_read), METH_FASTCALL|METH_KEYWORDS, os_eventfd_read__doc__}, static PyObject * os_eventfd_read_impl(PyObject *module, int fd); @@ -7882,8 +9846,31 @@ static PyObject * os_eventfd_read(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "eventfd_read", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "eventfd_read", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -7900,9 +9887,9 @@ exit: return return_value; } -#endif /* defined(HAVE_EVENTFD) */ +#endif /* (defined(HAVE_EVENTFD) && defined(EFD_CLOEXEC)) */ -#if defined(HAVE_EVENTFD) +#if (defined(HAVE_EVENTFD) && defined(EFD_CLOEXEC)) PyDoc_STRVAR(os_eventfd_write__doc__, "eventfd_write($module, /, fd, value)\n" @@ -7911,7 +9898,7 @@ PyDoc_STRVAR(os_eventfd_write__doc__, "Write eventfd value."); #define OS_EVENTFD_WRITE_METHODDEF \ - {"eventfd_write", (PyCFunction)(void(*)(void))os_eventfd_write, METH_FASTCALL|METH_KEYWORDS, os_eventfd_write__doc__}, + {"eventfd_write", _PyCFunction_CAST(os_eventfd_write), METH_FASTCALL|METH_KEYWORDS, os_eventfd_write__doc__}, static PyObject * os_eventfd_write_impl(PyObject *module, int fd, unsigned long long value); @@ -7920,8 +9907,31 @@ static PyObject * os_eventfd_write(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(value), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", "value", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "eventfd_write", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "eventfd_write", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int fd; unsigned long long value; @@ -7942,7 +9952,7 @@ exit: return return_value; } -#endif /* defined(HAVE_EVENTFD) */ +#endif /* (defined(HAVE_EVENTFD) && defined(EFD_CLOEXEC)) */ #if (defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)) @@ -7965,7 +9975,7 @@ PyDoc_STRVAR(os_get_terminal_size__doc__, "normally be used, os.get_terminal_size is the low-level implementation."); #define OS_GET_TERMINAL_SIZE_METHODDEF \ - {"get_terminal_size", (PyCFunction)(void(*)(void))os_get_terminal_size, METH_FASTCALL, os_get_terminal_size__doc__}, + {"get_terminal_size", _PyCFunction_CAST(os_get_terminal_size), METH_FASTCALL, os_get_terminal_size__doc__}, static PyObject * os_get_terminal_size_impl(PyObject *module, int fd); @@ -8057,7 +10067,7 @@ PyDoc_STRVAR(os_set_inheritable__doc__, "Set the inheritable flag of the specified file descriptor."); #define OS_SET_INHERITABLE_METHODDEF \ - {"set_inheritable", (PyCFunction)(void(*)(void))os_set_inheritable, METH_FASTCALL, os_set_inheritable__doc__}, + {"set_inheritable", _PyCFunction_CAST(os_set_inheritable), METH_FASTCALL, os_set_inheritable__doc__}, static PyObject * os_set_inheritable_impl(PyObject *module, int fd, int inheritable); @@ -8131,7 +10141,7 @@ PyDoc_STRVAR(os_set_handle_inheritable__doc__, "Set the inheritable flag of the specified handle."); #define OS_SET_HANDLE_INHERITABLE_METHODDEF \ - {"set_handle_inheritable", (PyCFunction)(void(*)(void))os_set_handle_inheritable, METH_FASTCALL, os_set_handle_inheritable__doc__}, + {"set_handle_inheritable", _PyCFunction_CAST(os_set_handle_inheritable), METH_FASTCALL, os_set_handle_inheritable__doc__}, static PyObject * os_set_handle_inheritable_impl(PyObject *module, intptr_t handle, @@ -8207,7 +10217,7 @@ PyDoc_STRVAR(os_set_blocking__doc__, "clear the O_NONBLOCK flag otherwise."); #define OS_SET_BLOCKING_METHODDEF \ - {"set_blocking", (PyCFunction)(void(*)(void))os_set_blocking, METH_FASTCALL, os_set_blocking__doc__}, + {"set_blocking", _PyCFunction_CAST(os_set_blocking), METH_FASTCALL, os_set_blocking__doc__}, static PyObject * os_set_blocking_impl(PyObject *module, int fd, int blocking); @@ -8226,8 +10236,8 @@ os_set_blocking(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (fd == -1 && PyErr_Occurred()) { goto exit; } - blocking = _PyLong_AsInt(args[1]); - if (blocking == -1 && PyErr_Occurred()) { + blocking = PyObject_IsTrue(args[1]); + if (blocking < 0) { goto exit; } return_value = os_set_blocking_impl(module, fd, blocking); @@ -8245,7 +10255,7 @@ PyDoc_STRVAR(os_DirEntry_is_symlink__doc__, "Return True if the entry is a symbolic link; cached per entry."); #define OS_DIRENTRY_IS_SYMLINK_METHODDEF \ - {"is_symlink", (PyCFunction)(void(*)(void))os_DirEntry_is_symlink, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, os_DirEntry_is_symlink__doc__}, + {"is_symlink", _PyCFunction_CAST(os_DirEntry_is_symlink), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, os_DirEntry_is_symlink__doc__}, static int os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class); @@ -8254,12 +10264,10 @@ static PyObject * os_DirEntry_is_symlink(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":is_symlink", _keywords, 0}; int _return_value; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { + if (nargs) { + PyErr_SetString(PyExc_TypeError, "is_symlink() takes no arguments"); goto exit; } _return_value = os_DirEntry_is_symlink_impl(self, defining_class); @@ -8272,6 +10280,38 @@ exit: return return_value; } +PyDoc_STRVAR(os_DirEntry_is_junction__doc__, +"is_junction($self, /)\n" +"--\n" +"\n" +"Return True if the entry is a junction; cached per entry."); + +#define OS_DIRENTRY_IS_JUNCTION_METHODDEF \ + {"is_junction", _PyCFunction_CAST(os_DirEntry_is_junction), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, os_DirEntry_is_junction__doc__}, + +static int +os_DirEntry_is_junction_impl(DirEntry *self, PyTypeObject *defining_class); + +static PyObject * +os_DirEntry_is_junction(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + int _return_value; + + if (nargs) { + PyErr_SetString(PyExc_TypeError, "is_junction() takes no arguments"); + goto exit; + } + _return_value = os_DirEntry_is_junction_impl(self, defining_class); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + PyDoc_STRVAR(os_DirEntry_stat__doc__, "stat($self, /, *, follow_symlinks=True)\n" "--\n" @@ -8279,7 +10319,7 @@ PyDoc_STRVAR(os_DirEntry_stat__doc__, "Return stat_result object for the entry; cached per entry."); #define OS_DIRENTRY_STAT_METHODDEF \ - {"stat", (PyCFunction)(void(*)(void))os_DirEntry_stat, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, os_DirEntry_stat__doc__}, + {"stat", _PyCFunction_CAST(os_DirEntry_stat), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, os_DirEntry_stat__doc__}, static PyObject * os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class, @@ -8289,14 +10329,47 @@ static PyObject * os_DirEntry_stat(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"follow_symlinks", NULL}; - static _PyArg_Parser _parser = {"|$p:stat", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "stat", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int follow_symlinks = 1; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &follow_symlinks)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { goto exit; } + if (!noptargs) { + goto skip_optional_kwonly; + } + follow_symlinks = PyObject_IsTrue(args[0]); + if (follow_symlinks < 0) { + goto exit; + } +skip_optional_kwonly: return_value = os_DirEntry_stat_impl(self, defining_class, follow_symlinks); exit: @@ -8310,7 +10383,7 @@ PyDoc_STRVAR(os_DirEntry_is_dir__doc__, "Return True if the entry is a directory; cached per entry."); #define OS_DIRENTRY_IS_DIR_METHODDEF \ - {"is_dir", (PyCFunction)(void(*)(void))os_DirEntry_is_dir, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, os_DirEntry_is_dir__doc__}, + {"is_dir", _PyCFunction_CAST(os_DirEntry_is_dir), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, os_DirEntry_is_dir__doc__}, static int os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class, @@ -8320,15 +10393,48 @@ static PyObject * os_DirEntry_is_dir(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"follow_symlinks", NULL}; - static _PyArg_Parser _parser = {"|$p:is_dir", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "is_dir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int follow_symlinks = 1; int _return_value; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &follow_symlinks)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { goto exit; } + if (!noptargs) { + goto skip_optional_kwonly; + } + follow_symlinks = PyObject_IsTrue(args[0]); + if (follow_symlinks < 0) { + goto exit; + } +skip_optional_kwonly: _return_value = os_DirEntry_is_dir_impl(self, defining_class, follow_symlinks); if ((_return_value == -1) && PyErr_Occurred()) { goto exit; @@ -8346,7 +10452,7 @@ PyDoc_STRVAR(os_DirEntry_is_file__doc__, "Return True if the entry is a file; cached per entry."); #define OS_DIRENTRY_IS_FILE_METHODDEF \ - {"is_file", (PyCFunction)(void(*)(void))os_DirEntry_is_file, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, os_DirEntry_is_file__doc__}, + {"is_file", _PyCFunction_CAST(os_DirEntry_is_file), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, os_DirEntry_is_file__doc__}, static int os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class, @@ -8356,15 +10462,48 @@ static PyObject * os_DirEntry_is_file(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"follow_symlinks", NULL}; - static _PyArg_Parser _parser = {"|$p:is_file", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "is_file", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int follow_symlinks = 1; int _return_value; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &follow_symlinks)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { goto exit; } + if (!noptargs) { + goto skip_optional_kwonly; + } + follow_symlinks = PyObject_IsTrue(args[0]); + if (follow_symlinks < 0) { + goto exit; + } +skip_optional_kwonly: _return_value = os_DirEntry_is_file_impl(self, defining_class, follow_symlinks); if ((_return_value == -1) && PyErr_Occurred()) { goto exit; @@ -8424,7 +10563,7 @@ PyDoc_STRVAR(os_scandir__doc__, "If path is None, uses the path=\'.\'."); #define OS_SCANDIR_METHODDEF \ - {"scandir", (PyCFunction)(void(*)(void))os_scandir, METH_FASTCALL|METH_KEYWORDS, os_scandir__doc__}, + {"scandir", _PyCFunction_CAST(os_scandir), METH_FASTCALL|METH_KEYWORDS, os_scandir__doc__}, static PyObject * os_scandir_impl(PyObject *module, path_t *path); @@ -8433,8 +10572,31 @@ static PyObject * os_scandir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "scandir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "scandir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; path_t path = PATH_T_INITIALIZE("scandir", "path", 1, PATH_HAVE_FDOPENDIR); @@ -8470,7 +10632,7 @@ PyDoc_STRVAR(os_fspath__doc__, "types raise a TypeError."); #define OS_FSPATH_METHODDEF \ - {"fspath", (PyCFunction)(void(*)(void))os_fspath, METH_FASTCALL|METH_KEYWORDS, os_fspath__doc__}, + {"fspath", _PyCFunction_CAST(os_fspath), METH_FASTCALL|METH_KEYWORDS, os_fspath__doc__}, static PyObject * os_fspath_impl(PyObject *module, PyObject *path); @@ -8479,8 +10641,31 @@ static PyObject * os_fspath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fspath", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fspath", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *path; @@ -8504,7 +10689,7 @@ PyDoc_STRVAR(os_getrandom__doc__, "Obtain a series of random bytes."); #define OS_GETRANDOM_METHODDEF \ - {"getrandom", (PyCFunction)(void(*)(void))os_getrandom, METH_FASTCALL|METH_KEYWORDS, os_getrandom__doc__}, + {"getrandom", _PyCFunction_CAST(os_getrandom), METH_FASTCALL|METH_KEYWORDS, os_getrandom__doc__}, static PyObject * os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags); @@ -8513,8 +10698,31 @@ static PyObject * os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(size), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"size", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "getrandom", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getrandom", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_ssize_t size; @@ -8568,7 +10776,7 @@ PyDoc_STRVAR(os__add_dll_directory__doc__, "to remove this directory from the search path."); #define OS__ADD_DLL_DIRECTORY_METHODDEF \ - {"_add_dll_directory", (PyCFunction)(void(*)(void))os__add_dll_directory, METH_FASTCALL|METH_KEYWORDS, os__add_dll_directory__doc__}, + {"_add_dll_directory", _PyCFunction_CAST(os__add_dll_directory), METH_FASTCALL|METH_KEYWORDS, os__add_dll_directory__doc__}, static PyObject * os__add_dll_directory_impl(PyObject *module, path_t *path); @@ -8577,8 +10785,31 @@ static PyObject * os__add_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_add_dll_directory", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_add_dll_directory", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("_add_dll_directory", "path", 0, 0); @@ -8613,7 +10844,7 @@ PyDoc_STRVAR(os__remove_dll_directory__doc__, "yourself."); #define OS__REMOVE_DLL_DIRECTORY_METHODDEF \ - {"_remove_dll_directory", (PyCFunction)(void(*)(void))os__remove_dll_directory, METH_FASTCALL|METH_KEYWORDS, os__remove_dll_directory__doc__}, + {"_remove_dll_directory", _PyCFunction_CAST(os__remove_dll_directory), METH_FASTCALL|METH_KEYWORDS, os__remove_dll_directory__doc__}, static PyObject * os__remove_dll_directory_impl(PyObject *module, PyObject *cookie); @@ -8622,8 +10853,31 @@ static PyObject * os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(cookie), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"cookie", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_remove_dll_directory", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_remove_dll_directory", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *cookie; @@ -8661,7 +10915,7 @@ PyDoc_STRVAR(os_waitstatus_to_exitcode__doc__, "This function must not be called if WIFSTOPPED(status) is true."); #define OS_WAITSTATUS_TO_EXITCODE_METHODDEF \ - {"waitstatus_to_exitcode", (PyCFunction)(void(*)(void))os_waitstatus_to_exitcode, METH_FASTCALL|METH_KEYWORDS, os_waitstatus_to_exitcode__doc__}, + {"waitstatus_to_exitcode", _PyCFunction_CAST(os_waitstatus_to_exitcode), METH_FASTCALL|METH_KEYWORDS, os_waitstatus_to_exitcode__doc__}, static PyObject * os_waitstatus_to_exitcode_impl(PyObject *module, PyObject *status_obj); @@ -8670,8 +10924,31 @@ static PyObject * os_waitstatus_to_exitcode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "waitstatus_to_exitcode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "waitstatus_to_exitcode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *status_obj; @@ -8780,6 +11057,10 @@ exit: #define OS_SYSTEM_METHODDEF #endif /* !defined(OS_SYSTEM_METHODDEF) */ +#ifndef OS_UMASK_METHODDEF + #define OS_UMASK_METHODDEF +#endif /* !defined(OS_UMASK_METHODDEF) */ + #ifndef OS_UNAME_METHODDEF #define OS_UNAME_METHODDEF #endif /* !defined(OS_UNAME_METHODDEF) */ @@ -8864,6 +11145,10 @@ exit: #define OS_OPENPTY_METHODDEF #endif /* !defined(OS_OPENPTY_METHODDEF) */ +#ifndef OS_LOGIN_TTY_METHODDEF + #define OS_LOGIN_TTY_METHODDEF +#endif /* !defined(OS_LOGIN_TTY_METHODDEF) */ + #ifndef OS_FORKPTY_METHODDEF #define OS_FORKPTY_METHODDEF #endif /* !defined(OS_FORKPTY_METHODDEF) */ @@ -8984,6 +11269,14 @@ exit: #define OS_PIDFD_OPEN_METHODDEF #endif /* !defined(OS_PIDFD_OPEN_METHODDEF) */ +#ifndef OS_SETNS_METHODDEF + #define OS_SETNS_METHODDEF +#endif /* !defined(OS_SETNS_METHODDEF) */ + +#ifndef OS_UNSHARE_METHODDEF + #define OS_UNSHARE_METHODDEF +#endif /* !defined(OS_UNSHARE_METHODDEF) */ + #ifndef OS_READLINK_METHODDEF #define OS_READLINK_METHODDEF #endif /* !defined(OS_READLINK_METHODDEF) */ @@ -9016,6 +11309,10 @@ exit: #define OS_TCSETPGRP_METHODDEF #endif /* !defined(OS_TCSETPGRP_METHODDEF) */ +#ifndef OS_DUP2_METHODDEF + #define OS_DUP2_METHODDEF +#endif /* !defined(OS_DUP2_METHODDEF) */ + #ifndef OS_LOCKF_METHODDEF #define OS_LOCKF_METHODDEF #endif /* !defined(OS_LOCKF_METHODDEF) */ @@ -9263,4 +11560,4 @@ exit: #ifndef OS_WAITSTATUS_TO_EXITCODE_METHODDEF #define OS_WAITSTATUS_TO_EXITCODE_METHODDEF #endif /* !defined(OS_WAITSTATUS_TO_EXITCODE_METHODDEF) */ -/*[clinic end generated code: output=65a85d7d3f2c487e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=41eab6c3523792a9 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pwdmodule.c.h b/Modules/clinic/pwdmodule.c.h index cb83062495d..f2603eaf322 100644 --- a/Modules/clinic/pwdmodule.c.h +++ b/Modules/clinic/pwdmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(pwd_getpwuid__doc__, "getpwuid($module, uidobj, /)\n" "--\n" @@ -74,4 +80,4 @@ pwd_getpwall(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef PWD_GETPWALL_METHODDEF #define PWD_GETPWALL_METHODDEF #endif /* !defined(PWD_GETPWALL_METHODDEF) */ -/*[clinic end generated code: output=7fceab7f1a85da36 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a95bc08653cda56b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pyexpat.c.h b/Modules/clinic/pyexpat.c.h index 7c56d6a8b25..34937c5d594 100644 --- a/Modules/clinic/pyexpat.c.h +++ b/Modules/clinic/pyexpat.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(pyexpat_xmlparser_Parse__doc__, "Parse($self, data, isfinal=False, /)\n" "--\n" @@ -11,7 +17,7 @@ PyDoc_STRVAR(pyexpat_xmlparser_Parse__doc__, "`isfinal\' should be true at end of input."); #define PYEXPAT_XMLPARSER_PARSE_METHODDEF \ - {"Parse", (PyCFunction)(void(*)(void))pyexpat_xmlparser_Parse, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_Parse__doc__}, + {"Parse", _PyCFunction_CAST(pyexpat_xmlparser_Parse), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_Parse__doc__}, static PyObject * pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyTypeObject *cls, @@ -21,15 +27,36 @@ static PyObject * pyexpat_xmlparser_Parse(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {"O|i:Parse", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Parse", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; PyObject *data; int isfinal = 0; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &data, &isfinal)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { goto exit; } + data = args[0]; + if (nargs < 2) { + goto skip_optional_posonly; + } + isfinal = PyObject_IsTrue(args[1]); + if (isfinal < 0) { + goto exit; + } +skip_optional_posonly: return_value = pyexpat_xmlparser_Parse_impl(self, cls, data, isfinal); exit: @@ -43,7 +70,7 @@ PyDoc_STRVAR(pyexpat_xmlparser_ParseFile__doc__, "Parse XML data from file-like object."); #define PYEXPAT_XMLPARSER_PARSEFILE_METHODDEF \ - {"ParseFile", (PyCFunction)(void(*)(void))pyexpat_xmlparser_ParseFile, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_ParseFile__doc__}, + {"ParseFile", _PyCFunction_CAST(pyexpat_xmlparser_ParseFile), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_ParseFile__doc__}, static PyObject * pyexpat_xmlparser_ParseFile_impl(xmlparseobject *self, PyTypeObject *cls, @@ -53,14 +80,27 @@ static PyObject * pyexpat_xmlparser_ParseFile(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"O:ParseFile", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "ParseFile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; PyObject *file; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &file)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { goto exit; } + file = args[0]; return_value = pyexpat_xmlparser_ParseFile_impl(self, cls, file); exit: @@ -151,7 +191,7 @@ PyDoc_STRVAR(pyexpat_xmlparser_ExternalEntityParserCreate__doc__, "Create a parser for parsing an external entity based on the information passed to the ExternalEntityRefHandler."); #define PYEXPAT_XMLPARSER_EXTERNALENTITYPARSERCREATE_METHODDEF \ - {"ExternalEntityParserCreate", (PyCFunction)(void(*)(void))pyexpat_xmlparser_ExternalEntityParserCreate, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_ExternalEntityParserCreate__doc__}, + {"ExternalEntityParserCreate", _PyCFunction_CAST(pyexpat_xmlparser_ExternalEntityParserCreate), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_ExternalEntityParserCreate__doc__}, static PyObject * pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, @@ -163,15 +203,62 @@ static PyObject * pyexpat_xmlparser_ExternalEntityParserCreate(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {"z|s:ExternalEntityParserCreate", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "ExternalEntityParserCreate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; const char *context; const char *encoding = NULL; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &context, &encoding)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { goto exit; } + if (args[0] == Py_None) { + context = NULL; + } + else if (PyUnicode_Check(args[0])) { + Py_ssize_t context_length; + context = PyUnicode_AsUTF8AndSize(args[0], &context_length); + if (context == NULL) { + goto exit; + } + if (strlen(context) != (size_t)context_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("ExternalEntityParserCreate", "argument 1", "str or None", args[0]); + goto exit; + } + if (nargs < 2) { + goto skip_optional_posonly; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("ExternalEntityParserCreate", "argument 2", "str", args[1]); + goto exit; + } + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(args[1], &encoding_length); + if (encoding == NULL) { + goto exit; + } + if (strlen(encoding) != (size_t)encoding_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } +skip_optional_posonly: return_value = pyexpat_xmlparser_ExternalEntityParserCreate_impl(self, cls, context, encoding); exit: @@ -224,7 +311,7 @@ PyDoc_STRVAR(pyexpat_xmlparser_UseForeignDTD__doc__, "information to the parser. \'flag\' defaults to True if not provided."); #define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF \ - {"UseForeignDTD", (PyCFunction)(void(*)(void))pyexpat_xmlparser_UseForeignDTD, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_UseForeignDTD__doc__}, + {"UseForeignDTD", _PyCFunction_CAST(pyexpat_xmlparser_UseForeignDTD), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pyexpat_xmlparser_UseForeignDTD__doc__}, static PyObject * pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, PyTypeObject *cls, @@ -234,14 +321,34 @@ static PyObject * pyexpat_xmlparser_UseForeignDTD(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"|p:UseForeignDTD", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "UseForeignDTD", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; int flag = 1; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &flag)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { goto exit; } + if (nargs < 1) { + goto skip_optional_posonly; + } + flag = PyObject_IsTrue(args[0]); + if (flag < 0) { + goto exit; + } +skip_optional_posonly: return_value = pyexpat_xmlparser_UseForeignDTD_impl(self, cls, flag); exit: @@ -258,7 +365,7 @@ PyDoc_STRVAR(pyexpat_ParserCreate__doc__, "Return a new XML parser object."); #define PYEXPAT_PARSERCREATE_METHODDEF \ - {"ParserCreate", (PyCFunction)(void(*)(void))pyexpat_ParserCreate, METH_FASTCALL|METH_KEYWORDS, pyexpat_ParserCreate__doc__}, + {"ParserCreate", _PyCFunction_CAST(pyexpat_ParserCreate), METH_FASTCALL|METH_KEYWORDS, pyexpat_ParserCreate__doc__}, static PyObject * pyexpat_ParserCreate_impl(PyObject *module, const char *encoding, @@ -268,8 +375,31 @@ static PyObject * pyexpat_ParserCreate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(namespace_separator), &_Py_ID(intern), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"encoding", "namespace_separator", "intern", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "ParserCreate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "ParserCreate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *encoding = NULL; @@ -368,4 +498,4 @@ exit: #ifndef PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #endif /* !defined(PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF) */ -/*[clinic end generated code: output=612b9d6a17a679a7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=63efc62e24a7b5a7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/readline.c.h b/Modules/clinic/readline.c.h index d1ee8089f73..e36d651f67f 100644 --- a/Modules/clinic/readline.c.h +++ b/Modules/clinic/readline.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(readline_parse_and_bind__doc__, "parse_and_bind($module, string, /)\n" "--\n" @@ -20,7 +26,7 @@ PyDoc_STRVAR(readline_read_init_file__doc__, "The default filename is the last filename used."); #define READLINE_READ_INIT_FILE_METHODDEF \ - {"read_init_file", (PyCFunction)(void(*)(void))readline_read_init_file, METH_FASTCALL, readline_read_init_file__doc__}, + {"read_init_file", _PyCFunction_CAST(readline_read_init_file), METH_FASTCALL, readline_read_init_file__doc__}, static PyObject * readline_read_init_file_impl(PyObject *module, PyObject *filename_obj); @@ -54,7 +60,7 @@ PyDoc_STRVAR(readline_read_history_file__doc__, "The default filename is ~/.history."); #define READLINE_READ_HISTORY_FILE_METHODDEF \ - {"read_history_file", (PyCFunction)(void(*)(void))readline_read_history_file, METH_FASTCALL, readline_read_history_file__doc__}, + {"read_history_file", _PyCFunction_CAST(readline_read_history_file), METH_FASTCALL, readline_read_history_file__doc__}, static PyObject * readline_read_history_file_impl(PyObject *module, PyObject *filename_obj); @@ -88,7 +94,7 @@ PyDoc_STRVAR(readline_write_history_file__doc__, "The default filename is ~/.history."); #define READLINE_WRITE_HISTORY_FILE_METHODDEF \ - {"write_history_file", (PyCFunction)(void(*)(void))readline_write_history_file, METH_FASTCALL, readline_write_history_file__doc__}, + {"write_history_file", _PyCFunction_CAST(readline_write_history_file), METH_FASTCALL, readline_write_history_file__doc__}, static PyObject * readline_write_history_file_impl(PyObject *module, PyObject *filename_obj); @@ -124,7 +130,7 @@ PyDoc_STRVAR(readline_append_history_file__doc__, "The default filename is ~/.history."); #define READLINE_APPEND_HISTORY_FILE_METHODDEF \ - {"append_history_file", (PyCFunction)(void(*)(void))readline_append_history_file, METH_FASTCALL, readline_append_history_file__doc__}, + {"append_history_file", _PyCFunction_CAST(readline_append_history_file), METH_FASTCALL, readline_append_history_file__doc__}, static PyObject * readline_append_history_file_impl(PyObject *module, int nelements, @@ -216,7 +222,7 @@ PyDoc_STRVAR(readline_set_completion_display_matches_hook__doc__, "once each time matches need to be displayed."); #define READLINE_SET_COMPLETION_DISPLAY_MATCHES_HOOK_METHODDEF \ - {"set_completion_display_matches_hook", (PyCFunction)(void(*)(void))readline_set_completion_display_matches_hook, METH_FASTCALL, readline_set_completion_display_matches_hook__doc__}, + {"set_completion_display_matches_hook", _PyCFunction_CAST(readline_set_completion_display_matches_hook), METH_FASTCALL, readline_set_completion_display_matches_hook__doc__}, static PyObject * readline_set_completion_display_matches_hook_impl(PyObject *module, @@ -252,7 +258,7 @@ PyDoc_STRVAR(readline_set_startup_hook__doc__, "before readline prints the first prompt."); #define READLINE_SET_STARTUP_HOOK_METHODDEF \ - {"set_startup_hook", (PyCFunction)(void(*)(void))readline_set_startup_hook, METH_FASTCALL, readline_set_startup_hook__doc__}, + {"set_startup_hook", _PyCFunction_CAST(readline_set_startup_hook), METH_FASTCALL, readline_set_startup_hook__doc__}, static PyObject * readline_set_startup_hook_impl(PyObject *module, PyObject *function); @@ -290,7 +296,7 @@ PyDoc_STRVAR(readline_set_pre_input_hook__doc__, "characters."); #define READLINE_SET_PRE_INPUT_HOOK_METHODDEF \ - {"set_pre_input_hook", (PyCFunction)(void(*)(void))readline_set_pre_input_hook, METH_FASTCALL, readline_set_pre_input_hook__doc__}, + {"set_pre_input_hook", _PyCFunction_CAST(readline_set_pre_input_hook), METH_FASTCALL, readline_set_pre_input_hook__doc__}, static PyObject * readline_set_pre_input_hook_impl(PyObject *module, PyObject *function); @@ -417,7 +423,7 @@ PyDoc_STRVAR(readline_replace_history_item__doc__, "pos is zero-based."); #define READLINE_REPLACE_HISTORY_ITEM_METHODDEF \ - {"replace_history_item", (PyCFunction)(void(*)(void))readline_replace_history_item, METH_FASTCALL, readline_replace_history_item__doc__}, + {"replace_history_item", _PyCFunction_CAST(readline_replace_history_item), METH_FASTCALL, readline_replace_history_item__doc__}, static PyObject * readline_replace_history_item_impl(PyObject *module, int entry_number, @@ -518,7 +524,7 @@ PyDoc_STRVAR(readline_set_completer__doc__, "It should return the next possible completion starting with \'text\'."); #define READLINE_SET_COMPLETER_METHODDEF \ - {"set_completer", (PyCFunction)(void(*)(void))readline_set_completer, METH_FASTCALL, readline_set_completer__doc__}, + {"set_completer", _PyCFunction_CAST(readline_set_completer), METH_FASTCALL, readline_set_completer__doc__}, static PyObject * readline_set_completer_impl(PyObject *module, PyObject *function); @@ -685,4 +691,4 @@ readline_redisplay(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef READLINE_CLEAR_HISTORY_METHODDEF #define READLINE_CLEAR_HISTORY_METHODDEF #endif /* !defined(READLINE_CLEAR_HISTORY_METHODDEF) */ -/*[clinic end generated code: output=f7d390113b27989f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9097fcb749c19e27 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/resource.c.h b/Modules/clinic/resource.c.h index 32c092ad7a9..d0ca8e7150f 100644 --- a/Modules/clinic/resource.c.h +++ b/Modules/clinic/resource.c.h @@ -2,6 +2,14 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +#if defined(HAVE_GETRUSAGE) + PyDoc_STRVAR(resource_getrusage__doc__, "getrusage($module, who, /)\n" "--\n" @@ -29,6 +37,8 @@ exit: return return_value; } +#endif /* defined(HAVE_GETRUSAGE) */ + PyDoc_STRVAR(resource_getrlimit__doc__, "getrlimit($module, resource, /)\n" "--\n" @@ -62,7 +72,7 @@ PyDoc_STRVAR(resource_setrlimit__doc__, "\n"); #define RESOURCE_SETRLIMIT_METHODDEF \ - {"setrlimit", (PyCFunction)(void(*)(void))resource_setrlimit, METH_FASTCALL, resource_setrlimit__doc__}, + {"setrlimit", _PyCFunction_CAST(resource_setrlimit), METH_FASTCALL, resource_setrlimit__doc__}, static PyObject * resource_setrlimit_impl(PyObject *module, int resource, PyObject *limits); @@ -91,41 +101,42 @@ exit: #if defined(HAVE_PRLIMIT) PyDoc_STRVAR(resource_prlimit__doc__, -"prlimit(pid, resource, [limits])"); +"prlimit($module, pid, resource, limits=None, /)\n" +"--\n" +"\n"); #define RESOURCE_PRLIMIT_METHODDEF \ - {"prlimit", (PyCFunction)resource_prlimit, METH_VARARGS, resource_prlimit__doc__}, + {"prlimit", _PyCFunction_CAST(resource_prlimit), METH_FASTCALL, resource_prlimit__doc__}, static PyObject * resource_prlimit_impl(PyObject *module, pid_t pid, int resource, - int group_right_1, PyObject *limits); + PyObject *limits); static PyObject * -resource_prlimit(PyObject *module, PyObject *args) +resource_prlimit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; pid_t pid; int resource; - int group_right_1 = 0; - PyObject *limits = NULL; + PyObject *limits = Py_None; - switch (PyTuple_GET_SIZE(args)) { - case 2: - if (!PyArg_ParseTuple(args, "" _Py_PARSE_PID "i:prlimit", &pid, &resource)) { - goto exit; - } - break; - case 3: - if (!PyArg_ParseTuple(args, "" _Py_PARSE_PID "iO:prlimit", &pid, &resource, &limits)) { - goto exit; - } - group_right_1 = 1; - break; - default: - PyErr_SetString(PyExc_TypeError, "resource.prlimit requires 2 to 3 arguments"); - goto exit; + if (!_PyArg_CheckPositional("prlimit", nargs, 2, 3)) { + goto exit; } - return_value = resource_prlimit_impl(module, pid, resource, group_right_1, limits); + pid = PyLong_AsPid(args[0]); + if (pid == -1 && PyErr_Occurred()) { + goto exit; + } + resource = _PyLong_AsInt(args[1]); + if (resource == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + limits = args[2]; +skip_optional: + return_value = resource_prlimit_impl(module, pid, resource, limits); exit: return return_value; @@ -160,7 +171,11 @@ exit: return return_value; } +#ifndef RESOURCE_GETRUSAGE_METHODDEF + #define RESOURCE_GETRUSAGE_METHODDEF +#endif /* !defined(RESOURCE_GETRUSAGE_METHODDEF) */ + #ifndef RESOURCE_PRLIMIT_METHODDEF #define RESOURCE_PRLIMIT_METHODDEF #endif /* !defined(RESOURCE_PRLIMIT_METHODDEF) */ -/*[clinic end generated code: output=ad190fb33d647d1e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2fbec74335a57230 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index a1695f2390a..fda9aaab475 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(select_select__doc__, "select($module, rlist, wlist, xlist, timeout=None, /)\n" "--\n" @@ -30,7 +36,7 @@ PyDoc_STRVAR(select_select__doc__, "descriptors can be used."); #define SELECT_SELECT_METHODDEF \ - {"select", (PyCFunction)(void(*)(void))select_select, METH_FASTCALL, select_select__doc__}, + {"select", _PyCFunction_CAST(select_select), METH_FASTCALL, select_select__doc__}, static PyObject * select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist, @@ -77,7 +83,7 @@ PyDoc_STRVAR(select_poll_register__doc__, " an optional bitmask describing the type of events to check for"); #define SELECT_POLL_REGISTER_METHODDEF \ - {"register", (PyCFunction)(void(*)(void))select_poll_register, METH_FASTCALL, select_poll_register__doc__}, + {"register", _PyCFunction_CAST(select_poll_register), METH_FASTCALL, select_poll_register__doc__}, static PyObject * select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask); @@ -125,7 +131,7 @@ PyDoc_STRVAR(select_poll_modify__doc__, " a bitmask describing the type of events to check for"); #define SELECT_POLL_MODIFY_METHODDEF \ - {"modify", (PyCFunction)(void(*)(void))select_poll_modify, METH_FASTCALL, select_poll_modify__doc__}, + {"modify", _PyCFunction_CAST(select_poll_modify), METH_FASTCALL, select_poll_modify__doc__}, static PyObject * select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask); @@ -193,11 +199,15 @@ PyDoc_STRVAR(select_poll_poll__doc__, "\n" "Polls the set of registered file descriptors.\n" "\n" +" timeout\n" +" The maximum time to wait in milliseconds, or else None (or a negative\n" +" value) to wait indefinitely.\n" +"\n" "Returns a list containing any descriptors that have events or errors to\n" "report, as a list of (fd, event) 2-tuples."); #define SELECT_POLL_POLL_METHODDEF \ - {"poll", (PyCFunction)(void(*)(void))select_poll_poll, METH_FASTCALL, select_poll_poll__doc__}, + {"poll", _PyCFunction_CAST(select_poll_poll), METH_FASTCALL, select_poll_poll__doc__}, static PyObject * select_poll_poll_impl(pollObject *self, PyObject *timeout_obj); @@ -240,7 +250,7 @@ PyDoc_STRVAR(select_devpoll_register__doc__, " an optional bitmask describing the type of events to check for"); #define SELECT_DEVPOLL_REGISTER_METHODDEF \ - {"register", (PyCFunction)(void(*)(void))select_devpoll_register, METH_FASTCALL, select_devpoll_register__doc__}, + {"register", _PyCFunction_CAST(select_devpoll_register), METH_FASTCALL, select_devpoll_register__doc__}, static PyObject * select_devpoll_register_impl(devpollObject *self, int fd, @@ -290,7 +300,7 @@ PyDoc_STRVAR(select_devpoll_modify__doc__, " an optional bitmask describing the type of events to check for"); #define SELECT_DEVPOLL_MODIFY_METHODDEF \ - {"modify", (PyCFunction)(void(*)(void))select_devpoll_modify, METH_FASTCALL, select_devpoll_modify__doc__}, + {"modify", _PyCFunction_CAST(select_devpoll_modify), METH_FASTCALL, select_devpoll_modify__doc__}, static PyObject * select_devpoll_modify_impl(devpollObject *self, int fd, @@ -363,11 +373,15 @@ PyDoc_STRVAR(select_devpoll_poll__doc__, "\n" "Polls the set of registered file descriptors.\n" "\n" +" timeout\n" +" The maximum time to wait in milliseconds, or else None (or a negative\n" +" value) to wait indefinitely.\n" +"\n" "Returns a list containing any descriptors that have events or errors to\n" "report, as a list of (fd, event) 2-tuples."); #define SELECT_DEVPOLL_POLL_METHODDEF \ - {"poll", (PyCFunction)(void(*)(void))select_devpoll_poll, METH_FASTCALL, select_devpoll_poll__doc__}, + {"poll", _PyCFunction_CAST(select_devpoll_poll), METH_FASTCALL, select_devpoll_poll__doc__}, static PyObject * select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj); @@ -514,8 +528,31 @@ static PyObject * select_epoll(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sizehint), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sizehint", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "epoll", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "epoll", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -647,7 +684,7 @@ PyDoc_STRVAR(select_epoll_register__doc__, "The epoll interface supports all file descriptors that support poll."); #define SELECT_EPOLL_REGISTER_METHODDEF \ - {"register", (PyCFunction)(void(*)(void))select_epoll_register, METH_FASTCALL|METH_KEYWORDS, select_epoll_register__doc__}, + {"register", _PyCFunction_CAST(select_epoll_register), METH_FASTCALL|METH_KEYWORDS, select_epoll_register__doc__}, static PyObject * select_epoll_register_impl(pyEpoll_Object *self, int fd, @@ -657,8 +694,31 @@ static PyObject * select_epoll_register(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(eventmask), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", "eventmask", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "register", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "register", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; int fd; @@ -701,7 +761,7 @@ PyDoc_STRVAR(select_epoll_modify__doc__, " a bit set composed of the various EPOLL constants"); #define SELECT_EPOLL_MODIFY_METHODDEF \ - {"modify", (PyCFunction)(void(*)(void))select_epoll_modify, METH_FASTCALL|METH_KEYWORDS, select_epoll_modify__doc__}, + {"modify", _PyCFunction_CAST(select_epoll_modify), METH_FASTCALL|METH_KEYWORDS, select_epoll_modify__doc__}, static PyObject * select_epoll_modify_impl(pyEpoll_Object *self, int fd, @@ -711,8 +771,31 @@ static PyObject * select_epoll_modify(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(eventmask), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", "eventmask", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "modify", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "modify", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int fd; unsigned int eventmask; @@ -748,7 +831,7 @@ PyDoc_STRVAR(select_epoll_unregister__doc__, " the target file descriptor of the operation"); #define SELECT_EPOLL_UNREGISTER_METHODDEF \ - {"unregister", (PyCFunction)(void(*)(void))select_epoll_unregister, METH_FASTCALL|METH_KEYWORDS, select_epoll_unregister__doc__}, + {"unregister", _PyCFunction_CAST(select_epoll_unregister), METH_FASTCALL|METH_KEYWORDS, select_epoll_unregister__doc__}, static PyObject * select_epoll_unregister_impl(pyEpoll_Object *self, int fd); @@ -757,8 +840,31 @@ static PyObject * select_epoll_unregister(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "unregister", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unregister", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -795,7 +901,7 @@ PyDoc_STRVAR(select_epoll_poll__doc__, "as a list of (fd, events) 2-tuples."); #define SELECT_EPOLL_POLL_METHODDEF \ - {"poll", (PyCFunction)(void(*)(void))select_epoll_poll, METH_FASTCALL|METH_KEYWORDS, select_epoll_poll__doc__}, + {"poll", _PyCFunction_CAST(select_epoll_poll), METH_FASTCALL|METH_KEYWORDS, select_epoll_poll__doc__}, static PyObject * select_epoll_poll_impl(pyEpoll_Object *self, PyObject *timeout_obj, @@ -805,8 +911,31 @@ static PyObject * select_epoll_poll(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(timeout), &_Py_ID(maxevents), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"timeout", "maxevents", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "poll", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "poll", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *timeout_obj = Py_None; @@ -867,7 +996,7 @@ PyDoc_STRVAR(select_epoll___exit____doc__, "\n"); #define SELECT_EPOLL___EXIT___METHODDEF \ - {"__exit__", (PyCFunction)(void(*)(void))select_epoll___exit__, METH_FASTCALL, select_epoll___exit____doc__}, + {"__exit__", _PyCFunction_CAST(select_epoll___exit__), METH_FASTCALL, select_epoll___exit____doc__}, static PyObject * select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type, @@ -1047,7 +1176,7 @@ PyDoc_STRVAR(select_kqueue_control__doc__, " This accepts floats for smaller timeouts, too."); #define SELECT_KQUEUE_CONTROL_METHODDEF \ - {"control", (PyCFunction)(void(*)(void))select_kqueue_control, METH_FASTCALL, select_kqueue_control__doc__}, + {"control", _PyCFunction_CAST(select_kqueue_control), METH_FASTCALL, select_kqueue_control__doc__}, static PyObject * select_kqueue_control_impl(kqueue_queue_Object *self, PyObject *changelist, @@ -1181,4 +1310,4 @@ exit: #ifndef SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ -/*[clinic end generated code: output=ed1e5a658863244c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9556c7d6cd5192d1 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha1module.c.h b/Modules/clinic/sha1module.c.h index 3a3ab58c123..ad15ddaadfc 100644 --- a/Modules/clinic/sha1module.c.h +++ b/Modules/clinic/sha1module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(SHA1Type_copy__doc__, "copy($self, /)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(SHA1Type_copy__doc__, "Return a copy of the hash object."); #define SHA1TYPE_COPY_METHODDEF \ - {"copy", (PyCFunction)(void(*)(void))SHA1Type_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, SHA1Type_copy__doc__}, + {"copy", _PyCFunction_CAST(SHA1Type_copy), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, SHA1Type_copy__doc__}, static PyObject * SHA1Type_copy_impl(SHA1object *self, PyTypeObject *cls); @@ -17,18 +23,11 @@ SHA1Type_copy_impl(SHA1object *self, PyTypeObject *cls); static PyObject * SHA1Type_copy(SHA1object *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":copy", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); + return NULL; } - return_value = SHA1Type_copy_impl(self, cls); - -exit: - return return_value; + return SHA1Type_copy_impl(self, cls); } PyDoc_STRVAR(SHA1Type_digest__doc__, @@ -83,7 +82,7 @@ PyDoc_STRVAR(_sha1_sha1__doc__, "Return a new SHA1 hash object; optionally initialized with a string."); #define _SHA1_SHA1_METHODDEF \ - {"sha1", (PyCFunction)(void(*)(void))_sha1_sha1, METH_FASTCALL|METH_KEYWORDS, _sha1_sha1__doc__}, + {"sha1", _PyCFunction_CAST(_sha1_sha1), METH_FASTCALL|METH_KEYWORDS, _sha1_sha1__doc__}, static PyObject * _sha1_sha1_impl(PyObject *module, PyObject *string, int usedforsecurity); @@ -92,8 +91,31 @@ static PyObject * _sha1_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha1", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *string = NULL; @@ -126,4 +148,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=abf1ab2545cea5a2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4d1293ca3472acdb input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha256module.c.h b/Modules/clinic/sha256module.c.h index 89205c4f14f..10d09fac695 100644 --- a/Modules/clinic/sha256module.c.h +++ b/Modules/clinic/sha256module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(SHA256Type_copy__doc__, "copy($self, /)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(SHA256Type_copy__doc__, "Return a copy of the hash object."); #define SHA256TYPE_COPY_METHODDEF \ - {"copy", (PyCFunction)(void(*)(void))SHA256Type_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, SHA256Type_copy__doc__}, + {"copy", _PyCFunction_CAST(SHA256Type_copy), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, SHA256Type_copy__doc__}, static PyObject * SHA256Type_copy_impl(SHAobject *self, PyTypeObject *cls); @@ -17,18 +23,11 @@ SHA256Type_copy_impl(SHAobject *self, PyTypeObject *cls); static PyObject * SHA256Type_copy(SHAobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":copy", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); + return NULL; } - return_value = SHA256Type_copy_impl(self, cls); - -exit: - return return_value; + return SHA256Type_copy_impl(self, cls); } PyDoc_STRVAR(SHA256Type_digest__doc__, @@ -83,7 +82,7 @@ PyDoc_STRVAR(_sha256_sha256__doc__, "Return a new SHA-256 hash object; optionally initialized with a string."); #define _SHA256_SHA256_METHODDEF \ - {"sha256", (PyCFunction)(void(*)(void))_sha256_sha256, METH_FASTCALL|METH_KEYWORDS, _sha256_sha256__doc__}, + {"sha256", _PyCFunction_CAST(_sha256_sha256), METH_FASTCALL|METH_KEYWORDS, _sha256_sha256__doc__}, static PyObject * _sha256_sha256_impl(PyObject *module, PyObject *string, int usedforsecurity); @@ -92,8 +91,31 @@ static PyObject * _sha256_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha256", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha256", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *string = NULL; @@ -134,7 +156,7 @@ PyDoc_STRVAR(_sha256_sha224__doc__, "Return a new SHA-224 hash object; optionally initialized with a string."); #define _SHA256_SHA224_METHODDEF \ - {"sha224", (PyCFunction)(void(*)(void))_sha256_sha224, METH_FASTCALL|METH_KEYWORDS, _sha256_sha224__doc__}, + {"sha224", _PyCFunction_CAST(_sha256_sha224), METH_FASTCALL|METH_KEYWORDS, _sha256_sha224__doc__}, static PyObject * _sha256_sha224_impl(PyObject *module, PyObject *string, int usedforsecurity); @@ -143,8 +165,31 @@ static PyObject * _sha256_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha224", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha224", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *string = NULL; @@ -177,4 +222,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=b7283f75c9d08f30 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ae926f7ec85e7c97 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha512module.c.h b/Modules/clinic/sha512module.c.h index f1192d74f9a..f8d326363c3 100644 --- a/Modules/clinic/sha512module.c.h +++ b/Modules/clinic/sha512module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(SHA512Type_copy__doc__, "copy($self, /)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(SHA512Type_copy__doc__, "Return a copy of the hash object."); #define SHA512TYPE_COPY_METHODDEF \ - {"copy", (PyCFunction)(void(*)(void))SHA512Type_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, SHA512Type_copy__doc__}, + {"copy", _PyCFunction_CAST(SHA512Type_copy), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, SHA512Type_copy__doc__}, static PyObject * SHA512Type_copy_impl(SHAobject *self, PyTypeObject *cls); @@ -17,18 +23,11 @@ SHA512Type_copy_impl(SHAobject *self, PyTypeObject *cls); static PyObject * SHA512Type_copy(SHAobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":copy", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); + return NULL; } - return_value = SHA512Type_copy_impl(self, cls); - -exit: - return return_value; + return SHA512Type_copy_impl(self, cls); } PyDoc_STRVAR(SHA512Type_digest__doc__, @@ -83,7 +82,7 @@ PyDoc_STRVAR(_sha512_sha512__doc__, "Return a new SHA-512 hash object; optionally initialized with a string."); #define _SHA512_SHA512_METHODDEF \ - {"sha512", (PyCFunction)(void(*)(void))_sha512_sha512, METH_FASTCALL|METH_KEYWORDS, _sha512_sha512__doc__}, + {"sha512", _PyCFunction_CAST(_sha512_sha512), METH_FASTCALL|METH_KEYWORDS, _sha512_sha512__doc__}, static PyObject * _sha512_sha512_impl(PyObject *module, PyObject *string, int usedforsecurity); @@ -92,8 +91,31 @@ static PyObject * _sha512_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha512", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha512", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *string = NULL; @@ -134,7 +156,7 @@ PyDoc_STRVAR(_sha512_sha384__doc__, "Return a new SHA-384 hash object; optionally initialized with a string."); #define _SHA512_SHA384_METHODDEF \ - {"sha384", (PyCFunction)(void(*)(void))_sha512_sha384, METH_FASTCALL|METH_KEYWORDS, _sha512_sha384__doc__}, + {"sha384", _PyCFunction_CAST(_sha512_sha384), METH_FASTCALL|METH_KEYWORDS, _sha512_sha384__doc__}, static PyObject * _sha512_sha384_impl(PyObject *module, PyObject *string, int usedforsecurity); @@ -143,8 +165,31 @@ static PyObject * _sha512_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha384", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha384", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *string = NULL; @@ -177,4 +222,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=9ff9f11937fabf35 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=dd168f3f21097afe input=a9049054013a1b77]*/ diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h index 4713bab7486..3b3c6ba150a 100644 --- a/Modules/clinic/signalmodule.c.h +++ b/Modules/clinic/signalmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(signal_default_int_handler__doc__, "default_int_handler($module, signalnum, frame, /)\n" "--\n" @@ -11,7 +17,7 @@ PyDoc_STRVAR(signal_default_int_handler__doc__, "It raises KeyboardInterrupt."); #define SIGNAL_DEFAULT_INT_HANDLER_METHODDEF \ - {"default_int_handler", (PyCFunction)(void(*)(void))signal_default_int_handler, METH_FASTCALL, signal_default_int_handler__doc__}, + {"default_int_handler", _PyCFunction_CAST(signal_default_int_handler), METH_FASTCALL, signal_default_int_handler__doc__}, static PyObject * signal_default_int_handler_impl(PyObject *module, int signalnum, @@ -139,7 +145,7 @@ PyDoc_STRVAR(signal_signal__doc__, "the first is the signal number, the second is the interrupted stack frame."); #define SIGNAL_SIGNAL_METHODDEF \ - {"signal", (PyCFunction)(void(*)(void))signal_signal, METH_FASTCALL, signal_signal__doc__}, + {"signal", _PyCFunction_CAST(signal_signal), METH_FASTCALL, signal_signal__doc__}, static PyObject * signal_signal_impl(PyObject *module, int signalnum, PyObject *handler); @@ -205,8 +211,9 @@ PyDoc_STRVAR(signal_strsignal__doc__, "\n" "Return the system description of the given signal.\n" "\n" -"The return values can be such as \"Interrupt\", \"Segmentation fault\", etc.\n" -"Returns None if the signal is not recognized."); +"Returns the description of signal *signalnum*, such as \"Interrupt\"\n" +"for :const:`SIGINT`. Returns :const:`None` if *signalnum* has no\n" +"description. Raises :exc:`ValueError` if *signalnum* is invalid."); #define SIGNAL_STRSIGNAL_METHODDEF \ {"strsignal", (PyCFunction)signal_strsignal, METH_O, signal_strsignal__doc__}, @@ -242,7 +249,7 @@ PyDoc_STRVAR(signal_siginterrupt__doc__, "signal sig, else system calls will be interrupted."); #define SIGNAL_SIGINTERRUPT_METHODDEF \ - {"siginterrupt", (PyCFunction)(void(*)(void))signal_siginterrupt, METH_FASTCALL, signal_siginterrupt__doc__}, + {"siginterrupt", _PyCFunction_CAST(signal_siginterrupt), METH_FASTCALL, signal_siginterrupt__doc__}, static PyObject * signal_siginterrupt_impl(PyObject *module, int signalnum, int flag); @@ -287,7 +294,7 @@ PyDoc_STRVAR(signal_setitimer__doc__, "Returns old values as a tuple: (delay, interval)."); #define SIGNAL_SETITIMER_METHODDEF \ - {"setitimer", (PyCFunction)(void(*)(void))signal_setitimer, METH_FASTCALL, signal_setitimer__doc__}, + {"setitimer", _PyCFunction_CAST(signal_setitimer), METH_FASTCALL, signal_setitimer__doc__}, static PyObject * signal_setitimer_impl(PyObject *module, int which, PyObject *seconds, @@ -354,7 +361,7 @@ exit: #endif /* defined(HAVE_GETITIMER) */ -#if defined(PYPTHREAD_SIGMASK) +#if defined(HAVE_SIGSET_T) && defined(PYPTHREAD_SIGMASK) PyDoc_STRVAR(signal_pthread_sigmask__doc__, "pthread_sigmask($module, how, mask, /)\n" @@ -363,7 +370,7 @@ PyDoc_STRVAR(signal_pthread_sigmask__doc__, "Fetch and/or change the signal mask of the calling thread."); #define SIGNAL_PTHREAD_SIGMASK_METHODDEF \ - {"pthread_sigmask", (PyCFunction)(void(*)(void))signal_pthread_sigmask, METH_FASTCALL, signal_pthread_sigmask__doc__}, + {"pthread_sigmask", _PyCFunction_CAST(signal_pthread_sigmask), METH_FASTCALL, signal_pthread_sigmask__doc__}, static PyObject * signal_pthread_sigmask_impl(PyObject *module, int how, sigset_t mask); @@ -391,9 +398,9 @@ exit: return return_value; } -#endif /* defined(PYPTHREAD_SIGMASK) */ +#endif /* defined(HAVE_SIGSET_T) && defined(PYPTHREAD_SIGMASK) */ -#if defined(HAVE_SIGPENDING) +#if defined(HAVE_SIGSET_T) && defined(HAVE_SIGPENDING) PyDoc_STRVAR(signal_sigpending__doc__, "sigpending($module, /)\n" @@ -416,9 +423,9 @@ signal_sigpending(PyObject *module, PyObject *Py_UNUSED(ignored)) return signal_sigpending_impl(module); } -#endif /* defined(HAVE_SIGPENDING) */ +#endif /* defined(HAVE_SIGSET_T) && defined(HAVE_SIGPENDING) */ -#if defined(HAVE_SIGWAIT) +#if defined(HAVE_SIGSET_T) && defined(HAVE_SIGWAIT) PyDoc_STRVAR(signal_sigwait__doc__, "sigwait($module, sigset, /)\n" @@ -451,9 +458,9 @@ exit: return return_value; } -#endif /* defined(HAVE_SIGWAIT) */ +#endif /* defined(HAVE_SIGSET_T) && defined(HAVE_SIGWAIT) */ -#if (defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)) +#if ((defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS)) PyDoc_STRVAR(signal_valid_signals__doc__, "valid_signals($module, /)\n" @@ -476,9 +483,9 @@ signal_valid_signals(PyObject *module, PyObject *Py_UNUSED(ignored)) return signal_valid_signals_impl(module); } -#endif /* (defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS)) */ +#endif /* ((defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS)) */ -#if defined(HAVE_SIGWAITINFO) +#if defined(HAVE_SIGSET_T) && defined(HAVE_SIGWAITINFO) PyDoc_STRVAR(signal_sigwaitinfo__doc__, "sigwaitinfo($module, sigset, /)\n" @@ -509,9 +516,9 @@ exit: return return_value; } -#endif /* defined(HAVE_SIGWAITINFO) */ +#endif /* defined(HAVE_SIGSET_T) && defined(HAVE_SIGWAITINFO) */ -#if defined(HAVE_SIGTIMEDWAIT) +#if defined(HAVE_SIGSET_T) && defined(HAVE_SIGTIMEDWAIT) PyDoc_STRVAR(signal_sigtimedwait__doc__, "sigtimedwait($module, sigset, timeout, /)\n" @@ -522,7 +529,7 @@ PyDoc_STRVAR(signal_sigtimedwait__doc__, "The timeout is specified in seconds, with floating point numbers allowed."); #define SIGNAL_SIGTIMEDWAIT_METHODDEF \ - {"sigtimedwait", (PyCFunction)(void(*)(void))signal_sigtimedwait, METH_FASTCALL, signal_sigtimedwait__doc__}, + {"sigtimedwait", _PyCFunction_CAST(signal_sigtimedwait), METH_FASTCALL, signal_sigtimedwait__doc__}, static PyObject * signal_sigtimedwait_impl(PyObject *module, sigset_t sigset, @@ -548,7 +555,7 @@ exit: return return_value; } -#endif /* defined(HAVE_SIGTIMEDWAIT) */ +#endif /* defined(HAVE_SIGSET_T) && defined(HAVE_SIGTIMEDWAIT) */ #if defined(HAVE_PTHREAD_KILL) @@ -559,7 +566,7 @@ PyDoc_STRVAR(signal_pthread_kill__doc__, "Send a signal to a thread."); #define SIGNAL_PTHREAD_KILL_METHODDEF \ - {"pthread_kill", (PyCFunction)(void(*)(void))signal_pthread_kill, METH_FASTCALL, signal_pthread_kill__doc__}, + {"pthread_kill", _PyCFunction_CAST(signal_pthread_kill), METH_FASTCALL, signal_pthread_kill__doc__}, static PyObject * signal_pthread_kill_impl(PyObject *module, unsigned long thread_id, @@ -601,7 +608,7 @@ PyDoc_STRVAR(signal_pidfd_send_signal__doc__, "Send a signal to a process referred to by a pid file descriptor."); #define SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF \ - {"pidfd_send_signal", (PyCFunction)(void(*)(void))signal_pidfd_send_signal, METH_FASTCALL, signal_pidfd_send_signal__doc__}, + {"pidfd_send_signal", _PyCFunction_CAST(signal_pidfd_send_signal), METH_FASTCALL, signal_pidfd_send_signal__doc__}, static PyObject * signal_pidfd_send_signal_impl(PyObject *module, int pidfd, int signalnum, @@ -698,4 +705,4 @@ exit: #ifndef SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF #define SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF #endif /* !defined(SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF) */ -/*[clinic end generated code: output=59c33f0af42aebb5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2b54dc607f6e3146 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/socketmodule.c.h b/Modules/clinic/socketmodule.c.h new file mode 100644 index 00000000000..8ff1044d013 --- /dev/null +++ b/Modules/clinic/socketmodule.c.h @@ -0,0 +1,94 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +static int +sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto, + PyObject *fdobj); + +static int +sock_initobj(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(family), &_Py_ID(type), &_Py_ID(proto), &_Py_ID(fileno), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"family", "type", "proto", "fileno", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "socket", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; + int family = -1; + int type = -1; + int proto = -1; + PyObject *fdobj = NULL; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 4, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (fastargs[0]) { + family = _PyLong_AsInt(fastargs[0]); + if (family == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[1]) { + type = _PyLong_AsInt(fastargs[1]); + if (type == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (fastargs[2]) { + proto = _PyLong_AsInt(fastargs[2]); + if (proto == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + fdobj = fastargs[3]; +skip_optional_pos: + return_value = sock_initobj_impl((PySocketSockObject *)self, family, type, proto, fdobj); + +exit: + return return_value; +} +/*[clinic end generated code: output=987155ac4b48a198 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/spwdmodule.c.h b/Modules/clinic/spwdmodule.c.h index 411d2344e18..f47aa9a77f3 100644 --- a/Modules/clinic/spwdmodule.c.h +++ b/Modules/clinic/spwdmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(HAVE_GETSPNAM) PyDoc_STRVAR(spwd_getspnam__doc__, @@ -71,4 +77,4 @@ spwd_getspall(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SPWD_GETSPALL_METHODDEF #define SPWD_GETSPALL_METHODDEF #endif /* !defined(SPWD_GETSPALL_METHODDEF) */ -/*[clinic end generated code: output=eec8d0bedcd312e5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=dd61827a7b708e11 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/symtablemodule.c.h b/Modules/clinic/symtablemodule.c.h index 4a17f130ac9..04fdb9f2d9b 100644 --- a/Modules/clinic/symtablemodule.c.h +++ b/Modules/clinic/symtablemodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_symtable_symtable__doc__, "symtable($module, source, filename, startstr, /)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(_symtable_symtable__doc__, "Return symbol and scope dictionaries used internally by compiler."); #define _SYMTABLE_SYMTABLE_METHODDEF \ - {"symtable", (PyCFunction)(void(*)(void))_symtable_symtable, METH_FASTCALL, _symtable_symtable__doc__}, + {"symtable", _PyCFunction_CAST(_symtable_symtable), METH_FASTCALL, _symtable_symtable__doc__}, static PyObject * _symtable_symtable_impl(PyObject *module, PyObject *source, @@ -48,4 +54,4 @@ _symtable_symtable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=a12f75cdbdf4e52a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=07716ddbd6c7efe1 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/syslogmodule.c.h b/Modules/clinic/syslogmodule.c.h new file mode 100644 index 00000000000..0ce66ad4e1a --- /dev/null +++ b/Modules/clinic/syslogmodule.c.h @@ -0,0 +1,257 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(syslog_openlog__doc__, +"openlog($module, /, ident=, logoption=0,\n" +" facility=LOG_USER)\n" +"--\n" +"\n" +"Set logging options of subsequent syslog() calls."); + +#define SYSLOG_OPENLOG_METHODDEF \ + {"openlog", _PyCFunction_CAST(syslog_openlog), METH_FASTCALL|METH_KEYWORDS, syslog_openlog__doc__}, + +static PyObject * +syslog_openlog_impl(PyObject *module, PyObject *ident, long logopt, + long facility); + +static PyObject * +syslog_openlog(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(ident), &_Py_ID(logoption), &_Py_ID(facility), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"ident", "logoption", "facility", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openlog", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *ident = NULL; + long logopt = 0; + long facility = LOG_USER; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("openlog", "argument 'ident'", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + ident = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[1]) { + logopt = PyLong_AsLong(args[1]); + if (logopt == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + facility = PyLong_AsLong(args[2]); + if (facility == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = syslog_openlog_impl(module, ident, logopt, facility); + +exit: + return return_value; +} + +PyDoc_STRVAR(syslog_syslog__doc__, +"syslog([priority=LOG_INFO,] message)\n" +"Send the string message to the system logger."); + +#define SYSLOG_SYSLOG_METHODDEF \ + {"syslog", (PyCFunction)syslog_syslog, METH_VARARGS, syslog_syslog__doc__}, + +static PyObject * +syslog_syslog_impl(PyObject *module, int group_left_1, int priority, + const char *message); + +static PyObject * +syslog_syslog(PyObject *module, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int priority = LOG_INFO; + const char *message; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "s:syslog", &message)) { + goto exit; + } + break; + case 2: + if (!PyArg_ParseTuple(args, "is:syslog", &priority, &message)) { + goto exit; + } + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "syslog.syslog requires 1 to 2 arguments"); + goto exit; + } + return_value = syslog_syslog_impl(module, group_left_1, priority, message); + +exit: + return return_value; +} + +PyDoc_STRVAR(syslog_closelog__doc__, +"closelog($module, /)\n" +"--\n" +"\n" +"Reset the syslog module values and call the system library closelog()."); + +#define SYSLOG_CLOSELOG_METHODDEF \ + {"closelog", (PyCFunction)syslog_closelog, METH_NOARGS, syslog_closelog__doc__}, + +static PyObject * +syslog_closelog_impl(PyObject *module); + +static PyObject * +syslog_closelog(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return syslog_closelog_impl(module); +} + +PyDoc_STRVAR(syslog_setlogmask__doc__, +"setlogmask($module, maskpri, /)\n" +"--\n" +"\n" +"Set the priority mask to maskpri and return the previous mask value."); + +#define SYSLOG_SETLOGMASK_METHODDEF \ + {"setlogmask", (PyCFunction)syslog_setlogmask, METH_O, syslog_setlogmask__doc__}, + +static long +syslog_setlogmask_impl(PyObject *module, long maskpri); + +static PyObject * +syslog_setlogmask(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + long maskpri; + long _return_value; + + maskpri = PyLong_AsLong(arg); + if (maskpri == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = syslog_setlogmask_impl(module, maskpri); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(syslog_LOG_MASK__doc__, +"LOG_MASK($module, pri, /)\n" +"--\n" +"\n" +"Calculates the mask for the individual priority pri."); + +#define SYSLOG_LOG_MASK_METHODDEF \ + {"LOG_MASK", (PyCFunction)syslog_LOG_MASK, METH_O, syslog_LOG_MASK__doc__}, + +static long +syslog_LOG_MASK_impl(PyObject *module, long pri); + +static PyObject * +syslog_LOG_MASK(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + long pri; + long _return_value; + + pri = PyLong_AsLong(arg); + if (pri == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = syslog_LOG_MASK_impl(module, pri); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(syslog_LOG_UPTO__doc__, +"LOG_UPTO($module, pri, /)\n" +"--\n" +"\n" +"Calculates the mask for all priorities up to and including pri."); + +#define SYSLOG_LOG_UPTO_METHODDEF \ + {"LOG_UPTO", (PyCFunction)syslog_LOG_UPTO, METH_O, syslog_LOG_UPTO__doc__}, + +static long +syslog_LOG_UPTO_impl(PyObject *module, long pri); + +static PyObject * +syslog_LOG_UPTO(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + long pri; + long _return_value; + + pri = PyLong_AsLong(arg); + if (pri == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = syslog_LOG_UPTO_impl(module, pri); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} +/*[clinic end generated code: output=3b1bdb16565b8fda input=a9049054013a1b77]*/ diff --git a/Modules/clinic/termios.c.h b/Modules/clinic/termios.c.h index b4d179abbe4..78863e53c42 100644 --- a/Modules/clinic/termios.c.h +++ b/Modules/clinic/termios.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(termios_tcgetattr__doc__, "tcgetattr($module, fd, /)\n" "--\n" @@ -50,7 +56,7 @@ PyDoc_STRVAR(termios_tcsetattr__doc__, "queued output and discarding all queued input."); #define TERMIOS_TCSETATTR_METHODDEF \ - {"tcsetattr", (PyCFunction)(void(*)(void))termios_tcsetattr, METH_FASTCALL, termios_tcsetattr__doc__}, + {"tcsetattr", _PyCFunction_CAST(termios_tcsetattr), METH_FASTCALL, termios_tcsetattr__doc__}, static PyObject * termios_tcsetattr_impl(PyObject *module, int fd, int when, PyObject *term); @@ -90,7 +96,7 @@ PyDoc_STRVAR(termios_tcsendbreak__doc__, "has a system dependent meaning."); #define TERMIOS_TCSENDBREAK_METHODDEF \ - {"tcsendbreak", (PyCFunction)(void(*)(void))termios_tcsendbreak, METH_FASTCALL, termios_tcsendbreak__doc__}, + {"tcsendbreak", _PyCFunction_CAST(termios_tcsendbreak), METH_FASTCALL, termios_tcsendbreak__doc__}, static PyObject * termios_tcsendbreak_impl(PyObject *module, int fd, int duration); @@ -156,7 +162,7 @@ PyDoc_STRVAR(termios_tcflush__doc__, "both queues."); #define TERMIOS_TCFLUSH_METHODDEF \ - {"tcflush", (PyCFunction)(void(*)(void))termios_tcflush, METH_FASTCALL, termios_tcflush__doc__}, + {"tcflush", _PyCFunction_CAST(termios_tcflush), METH_FASTCALL, termios_tcflush__doc__}, static PyObject * termios_tcflush_impl(PyObject *module, int fd, int queue); @@ -195,7 +201,7 @@ PyDoc_STRVAR(termios_tcflow__doc__, "or termios.TCION to restart input."); #define TERMIOS_TCFLOW_METHODDEF \ - {"tcflow", (PyCFunction)(void(*)(void))termios_tcflow, METH_FASTCALL, termios_tcflow__doc__}, + {"tcflow", _PyCFunction_CAST(termios_tcflow), METH_FASTCALL, termios_tcflow__doc__}, static PyObject * termios_tcflow_impl(PyObject *module, int fd, int action); @@ -262,7 +268,7 @@ PyDoc_STRVAR(termios_tcsetwinsize__doc__, "is a two-item tuple (ws_row, ws_col) like the one returned by tcgetwinsize()."); #define TERMIOS_TCSETWINSIZE_METHODDEF \ - {"tcsetwinsize", (PyCFunction)(void(*)(void))termios_tcsetwinsize, METH_FASTCALL, termios_tcsetwinsize__doc__}, + {"tcsetwinsize", _PyCFunction_CAST(termios_tcsetwinsize), METH_FASTCALL, termios_tcsetwinsize__doc__}, static PyObject * termios_tcsetwinsize_impl(PyObject *module, int fd, PyObject *winsz); @@ -286,4 +292,4 @@ termios_tcsetwinsize(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=db808d31296f6643 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d286a3906a051869 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/unicodedata.c.h b/Modules/clinic/unicodedata.c.h index 17f2e009701..6102027d07a 100644 --- a/Modules/clinic/unicodedata.c.h +++ b/Modules/clinic/unicodedata.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(unicodedata_UCD_decimal__doc__, "decimal($self, chr, default=, /)\n" "--\n" @@ -13,7 +19,7 @@ PyDoc_STRVAR(unicodedata_UCD_decimal__doc__, "ValueError is raised."); #define UNICODEDATA_UCD_DECIMAL_METHODDEF \ - {"decimal", (PyCFunction)(void(*)(void))unicodedata_UCD_decimal, METH_FASTCALL, unicodedata_UCD_decimal__doc__}, + {"decimal", _PyCFunction_CAST(unicodedata_UCD_decimal), METH_FASTCALL, unicodedata_UCD_decimal__doc__}, static PyObject * unicodedata_UCD_decimal_impl(PyObject *self, int chr, @@ -63,7 +69,7 @@ PyDoc_STRVAR(unicodedata_UCD_digit__doc__, "ValueError is raised."); #define UNICODEDATA_UCD_DIGIT_METHODDEF \ - {"digit", (PyCFunction)(void(*)(void))unicodedata_UCD_digit, METH_FASTCALL, unicodedata_UCD_digit__doc__}, + {"digit", _PyCFunction_CAST(unicodedata_UCD_digit), METH_FASTCALL, unicodedata_UCD_digit__doc__}, static PyObject * unicodedata_UCD_digit_impl(PyObject *self, int chr, PyObject *default_value); @@ -112,7 +118,7 @@ PyDoc_STRVAR(unicodedata_UCD_numeric__doc__, "ValueError is raised."); #define UNICODEDATA_UCD_NUMERIC_METHODDEF \ - {"numeric", (PyCFunction)(void(*)(void))unicodedata_UCD_numeric, METH_FASTCALL, unicodedata_UCD_numeric__doc__}, + {"numeric", _PyCFunction_CAST(unicodedata_UCD_numeric), METH_FASTCALL, unicodedata_UCD_numeric__doc__}, static PyObject * unicodedata_UCD_numeric_impl(PyObject *self, int chr, @@ -395,7 +401,7 @@ PyDoc_STRVAR(unicodedata_UCD_is_normalized__doc__, "Valid values for form are \'NFC\', \'NFKC\', \'NFD\', and \'NFKD\'."); #define UNICODEDATA_UCD_IS_NORMALIZED_METHODDEF \ - {"is_normalized", (PyCFunction)(void(*)(void))unicodedata_UCD_is_normalized, METH_FASTCALL, unicodedata_UCD_is_normalized__doc__}, + {"is_normalized", _PyCFunction_CAST(unicodedata_UCD_is_normalized), METH_FASTCALL, unicodedata_UCD_is_normalized__doc__}, static PyObject * unicodedata_UCD_is_normalized_impl(PyObject *self, PyObject *form, @@ -442,7 +448,7 @@ PyDoc_STRVAR(unicodedata_UCD_normalize__doc__, "Valid values for form are \'NFC\', \'NFKC\', \'NFD\', and \'NFKD\'."); #define UNICODEDATA_UCD_NORMALIZE_METHODDEF \ - {"normalize", (PyCFunction)(void(*)(void))unicodedata_UCD_normalize, METH_FASTCALL, unicodedata_UCD_normalize__doc__}, + {"normalize", _PyCFunction_CAST(unicodedata_UCD_normalize), METH_FASTCALL, unicodedata_UCD_normalize__doc__}, static PyObject * unicodedata_UCD_normalize_impl(PyObject *self, PyObject *form, @@ -490,7 +496,7 @@ PyDoc_STRVAR(unicodedata_UCD_name__doc__, "ValueError is raised."); #define UNICODEDATA_UCD_NAME_METHODDEF \ - {"name", (PyCFunction)(void(*)(void))unicodedata_UCD_name, METH_FASTCALL, unicodedata_UCD_name__doc__}, + {"name", _PyCFunction_CAST(unicodedata_UCD_name), METH_FASTCALL, unicodedata_UCD_name__doc__}, static PyObject * unicodedata_UCD_name_impl(PyObject *self, int chr, PyObject *default_value); @@ -559,4 +565,4 @@ unicodedata_UCD_lookup(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=a3c0eb84eda47b2d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=aaf601d28b352353 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h index e2a5fccd36c..65412b2435a 100644 --- a/Modules/clinic/zlibmodule.c.h +++ b/Modules/clinic/zlibmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(zlib_compress__doc__, "compress($module, data, /, level=Z_DEFAULT_COMPRESSION, wbits=MAX_WBITS)\n" "--\n" @@ -16,7 +22,7 @@ PyDoc_STRVAR(zlib_compress__doc__, " The window buffer size and container format."); #define ZLIB_COMPRESS_METHODDEF \ - {"compress", (PyCFunction)(void(*)(void))zlib_compress, METH_FASTCALL|METH_KEYWORDS, zlib_compress__doc__}, + {"compress", _PyCFunction_CAST(zlib_compress), METH_FASTCALL|METH_KEYWORDS, zlib_compress__doc__}, static PyObject * zlib_compress_impl(PyObject *module, Py_buffer *data, int level, int wbits); @@ -25,8 +31,31 @@ static PyObject * zlib_compress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(level), &_Py_ID(wbits), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "level", "wbits", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -86,7 +115,7 @@ PyDoc_STRVAR(zlib_decompress__doc__, " The initial output buffer size."); #define ZLIB_DECOMPRESS_METHODDEF \ - {"decompress", (PyCFunction)(void(*)(void))zlib_decompress, METH_FASTCALL|METH_KEYWORDS, zlib_decompress__doc__}, + {"decompress", _PyCFunction_CAST(zlib_decompress), METH_FASTCALL|METH_KEYWORDS, zlib_decompress__doc__}, static PyObject * zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, @@ -96,8 +125,31 @@ static PyObject * zlib_decompress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(wbits), &_Py_ID(bufsize), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "wbits", "bufsize", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -182,7 +234,7 @@ PyDoc_STRVAR(zlib_compressobj__doc__, " containing subsequences that are likely to occur in the input data."); #define ZLIB_COMPRESSOBJ_METHODDEF \ - {"compressobj", (PyCFunction)(void(*)(void))zlib_compressobj, METH_FASTCALL|METH_KEYWORDS, zlib_compressobj__doc__}, + {"compressobj", _PyCFunction_CAST(zlib_compressobj), METH_FASTCALL|METH_KEYWORDS, zlib_compressobj__doc__}, static PyObject * zlib_compressobj_impl(PyObject *module, int level, int method, int wbits, @@ -192,8 +244,31 @@ static PyObject * zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 6 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(level), &_Py_ID(method), &_Py_ID(wbits), &_Py_ID(memLevel), &_Py_ID(strategy), &_Py_ID(zdict), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"level", "method", "wbits", "memLevel", "strategy", "zdict", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compressobj", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compressobj", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int level = Z_DEFAULT_COMPRESSION; @@ -287,7 +362,7 @@ PyDoc_STRVAR(zlib_decompressobj__doc__, " dictionary as used by the compressor that produced the input data."); #define ZLIB_DECOMPRESSOBJ_METHODDEF \ - {"decompressobj", (PyCFunction)(void(*)(void))zlib_decompressobj, METH_FASTCALL|METH_KEYWORDS, zlib_decompressobj__doc__}, + {"decompressobj", _PyCFunction_CAST(zlib_decompressobj), METH_FASTCALL|METH_KEYWORDS, zlib_decompressobj__doc__}, static PyObject * zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict); @@ -296,8 +371,31 @@ static PyObject * zlib_decompressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(wbits), &_Py_ID(zdict), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"wbits", "zdict", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decompressobj", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompressobj", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int wbits = MAX_WBITS; @@ -341,7 +439,7 @@ PyDoc_STRVAR(zlib_Compress_compress__doc__, "Call the flush() method to clear these buffers."); #define ZLIB_COMPRESS_COMPRESS_METHODDEF \ - {"compress", (PyCFunction)(void(*)(void))zlib_Compress_compress, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress_compress__doc__}, + {"compress", _PyCFunction_CAST(zlib_Compress_compress), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress_compress__doc__}, static PyObject * zlib_Compress_compress_impl(compobject *self, PyTypeObject *cls, @@ -351,12 +449,31 @@ static PyObject * zlib_Compress_compress(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"y*:compress", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; Py_buffer data = {NULL, NULL}; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &data)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("compress", "argument 1", "contiguous buffer", args[0]); goto exit; } return_value = zlib_Compress_compress_impl(self, cls, &data); @@ -388,7 +505,7 @@ PyDoc_STRVAR(zlib_Decompress_decompress__doc__, "Call the flush() method to clear these buffers."); #define ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF \ - {"decompress", (PyCFunction)(void(*)(void))zlib_Decompress_decompress, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress_decompress__doc__}, + {"decompress", _PyCFunction_CAST(zlib_Decompress_decompress), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress_decompress__doc__}, static PyObject * zlib_Decompress_decompress_impl(compobject *self, PyTypeObject *cls, @@ -398,15 +515,63 @@ static PyObject * zlib_Decompress_decompress(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(max_length), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "max_length", NULL}; - static _PyArg_Parser _parser = {"y*|n:decompress", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; Py_ssize_t max_length = 0; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &data, &max_length)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { goto exit; } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("decompress", "argument 1", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + max_length = ival; + } +skip_optional_pos: return_value = zlib_Decompress_decompress_impl(self, cls, &data, max_length); exit: @@ -431,7 +596,7 @@ PyDoc_STRVAR(zlib_Compress_flush__doc__, " can still be compressed."); #define ZLIB_COMPRESS_FLUSH_METHODDEF \ - {"flush", (PyCFunction)(void(*)(void))zlib_Compress_flush, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress_flush__doc__}, + {"flush", _PyCFunction_CAST(zlib_Compress_flush), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress_flush__doc__}, static PyObject * zlib_Compress_flush_impl(compobject *self, PyTypeObject *cls, int mode); @@ -440,14 +605,34 @@ static PyObject * zlib_Compress_flush(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"|i:flush", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "flush", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; int mode = Z_FINISH; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &mode)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { goto exit; } + if (nargs < 1) { + goto skip_optional_posonly; + } + mode = _PyLong_AsInt(args[0]); + if (mode == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_posonly: return_value = zlib_Compress_flush_impl(self, cls, mode); exit: @@ -463,7 +648,7 @@ PyDoc_STRVAR(zlib_Compress_copy__doc__, "Return a copy of the compression object."); #define ZLIB_COMPRESS_COPY_METHODDEF \ - {"copy", (PyCFunction)(void(*)(void))zlib_Compress_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress_copy__doc__}, + {"copy", _PyCFunction_CAST(zlib_Compress_copy), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress_copy__doc__}, static PyObject * zlib_Compress_copy_impl(compobject *self, PyTypeObject *cls); @@ -471,18 +656,11 @@ zlib_Compress_copy_impl(compobject *self, PyTypeObject *cls); static PyObject * zlib_Compress_copy(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":copy", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); + return NULL; } - return_value = zlib_Compress_copy_impl(self, cls); - -exit: - return return_value; + return zlib_Compress_copy_impl(self, cls); } #endif /* defined(HAVE_ZLIB_COPY) */ @@ -495,7 +673,7 @@ PyDoc_STRVAR(zlib_Compress___copy____doc__, "\n"); #define ZLIB_COMPRESS___COPY___METHODDEF \ - {"__copy__", (PyCFunction)(void(*)(void))zlib_Compress___copy__, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress___copy____doc__}, + {"__copy__", _PyCFunction_CAST(zlib_Compress___copy__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress___copy____doc__}, static PyObject * zlib_Compress___copy___impl(compobject *self, PyTypeObject *cls); @@ -503,18 +681,11 @@ zlib_Compress___copy___impl(compobject *self, PyTypeObject *cls); static PyObject * zlib_Compress___copy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":__copy__", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "__copy__() takes no arguments"); + return NULL; } - return_value = zlib_Compress___copy___impl(self, cls); - -exit: - return return_value; + return zlib_Compress___copy___impl(self, cls); } #endif /* defined(HAVE_ZLIB_COPY) */ @@ -527,7 +698,7 @@ PyDoc_STRVAR(zlib_Compress___deepcopy____doc__, "\n"); #define ZLIB_COMPRESS___DEEPCOPY___METHODDEF \ - {"__deepcopy__", (PyCFunction)(void(*)(void))zlib_Compress___deepcopy__, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress___deepcopy____doc__}, + {"__deepcopy__", _PyCFunction_CAST(zlib_Compress___deepcopy__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Compress___deepcopy____doc__}, static PyObject * zlib_Compress___deepcopy___impl(compobject *self, PyTypeObject *cls, @@ -537,14 +708,27 @@ static PyObject * zlib_Compress___deepcopy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"O:__deepcopy__", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__deepcopy__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; PyObject *memo; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &memo)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { goto exit; } + memo = args[0]; return_value = zlib_Compress___deepcopy___impl(self, cls, memo); exit: @@ -562,7 +746,7 @@ PyDoc_STRVAR(zlib_Decompress_copy__doc__, "Return a copy of the decompression object."); #define ZLIB_DECOMPRESS_COPY_METHODDEF \ - {"copy", (PyCFunction)(void(*)(void))zlib_Decompress_copy, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress_copy__doc__}, + {"copy", _PyCFunction_CAST(zlib_Decompress_copy), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress_copy__doc__}, static PyObject * zlib_Decompress_copy_impl(compobject *self, PyTypeObject *cls); @@ -570,18 +754,11 @@ zlib_Decompress_copy_impl(compobject *self, PyTypeObject *cls); static PyObject * zlib_Decompress_copy(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":copy", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); + return NULL; } - return_value = zlib_Decompress_copy_impl(self, cls); - -exit: - return return_value; + return zlib_Decompress_copy_impl(self, cls); } #endif /* defined(HAVE_ZLIB_COPY) */ @@ -594,7 +771,7 @@ PyDoc_STRVAR(zlib_Decompress___copy____doc__, "\n"); #define ZLIB_DECOMPRESS___COPY___METHODDEF \ - {"__copy__", (PyCFunction)(void(*)(void))zlib_Decompress___copy__, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress___copy____doc__}, + {"__copy__", _PyCFunction_CAST(zlib_Decompress___copy__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress___copy____doc__}, static PyObject * zlib_Decompress___copy___impl(compobject *self, PyTypeObject *cls); @@ -602,18 +779,11 @@ zlib_Decompress___copy___impl(compobject *self, PyTypeObject *cls); static PyObject * zlib_Decompress___copy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":__copy__", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; + if (nargs) { + PyErr_SetString(PyExc_TypeError, "__copy__() takes no arguments"); + return NULL; } - return_value = zlib_Decompress___copy___impl(self, cls); - -exit: - return return_value; + return zlib_Decompress___copy___impl(self, cls); } #endif /* defined(HAVE_ZLIB_COPY) */ @@ -626,7 +796,7 @@ PyDoc_STRVAR(zlib_Decompress___deepcopy____doc__, "\n"); #define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF \ - {"__deepcopy__", (PyCFunction)(void(*)(void))zlib_Decompress___deepcopy__, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress___deepcopy____doc__}, + {"__deepcopy__", _PyCFunction_CAST(zlib_Decompress___deepcopy__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress___deepcopy____doc__}, static PyObject * zlib_Decompress___deepcopy___impl(compobject *self, PyTypeObject *cls, @@ -636,14 +806,27 @@ static PyObject * zlib_Decompress___deepcopy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"O:__deepcopy__", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__deepcopy__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; PyObject *memo; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &memo)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { goto exit; } + memo = args[0]; return_value = zlib_Decompress___deepcopy___impl(self, cls, memo); exit: @@ -662,7 +845,7 @@ PyDoc_STRVAR(zlib_Decompress_flush__doc__, " the initial size of the output buffer."); #define ZLIB_DECOMPRESS_FLUSH_METHODDEF \ - {"flush", (PyCFunction)(void(*)(void))zlib_Decompress_flush, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress_flush__doc__}, + {"flush", _PyCFunction_CAST(zlib_Decompress_flush), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zlib_Decompress_flush__doc__}, static PyObject * zlib_Decompress_flush_impl(compobject *self, PyTypeObject *cls, @@ -672,20 +855,146 @@ static PyObject * zlib_Decompress_flush(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"|n:flush", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "flush", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; Py_ssize_t length = DEF_BUF_SIZE; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &length)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { goto exit; } + if (nargs < 1) { + goto skip_optional_posonly; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[0]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + length = ival; + } +skip_optional_posonly: return_value = zlib_Decompress_flush_impl(self, cls, length); exit: return return_value; } +PyDoc_STRVAR(zlib_ZlibDecompressor_decompress__doc__, +"decompress($self, /, data, max_length=-1)\n" +"--\n" +"\n" +"Decompress *data*, returning uncompressed data as bytes.\n" +"\n" +"If *max_length* is nonnegative, returns at most *max_length* bytes of\n" +"decompressed data. If this limit is reached and further output can be\n" +"produced, *self.needs_input* will be set to ``False``. In this case, the next\n" +"call to *decompress()* may provide *data* as b\'\' to obtain more of the output.\n" +"\n" +"If all of the input data was decompressed and returned (either because this\n" +"was less than *max_length* bytes, or because *max_length* was negative),\n" +"*self.needs_input* will be set to True.\n" +"\n" +"Attempting to decompress data after the end of stream is reached raises an\n" +"EOFError. Any data found after the end of the stream is ignored and saved in\n" +"the unused_data attribute."); + +#define ZLIB_ZLIBDECOMPRESSOR_DECOMPRESS_METHODDEF \ + {"decompress", _PyCFunction_CAST(zlib_ZlibDecompressor_decompress), METH_FASTCALL|METH_KEYWORDS, zlib_ZlibDecompressor_decompress__doc__}, + +static PyObject * +zlib_ZlibDecompressor_decompress_impl(ZlibDecompressor *self, + Py_buffer *data, Py_ssize_t max_length); + +static PyObject * +zlib_ZlibDecompressor_decompress(ZlibDecompressor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(max_length), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"data", "max_length", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_buffer data = {NULL, NULL}; + Py_ssize_t max_length = -1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("decompress", "argument 'data'", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + max_length = ival; + } +skip_optional_pos: + return_value = zlib_ZlibDecompressor_decompress_impl(self, &data, max_length); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + PyDoc_STRVAR(zlib_adler32__doc__, "adler32($module, data, value=1, /)\n" "--\n" @@ -698,7 +1007,7 @@ PyDoc_STRVAR(zlib_adler32__doc__, "The returned checksum is an integer."); #define ZLIB_ADLER32_METHODDEF \ - {"adler32", (PyCFunction)(void(*)(void))zlib_adler32, METH_FASTCALL, zlib_adler32__doc__}, + {"adler32", _PyCFunction_CAST(zlib_adler32), METH_FASTCALL, zlib_adler32__doc__}, static PyObject * zlib_adler32_impl(PyObject *module, Py_buffer *data, unsigned int value); @@ -751,9 +1060,9 @@ PyDoc_STRVAR(zlib_crc32__doc__, "The returned checksum is an integer."); #define ZLIB_CRC32_METHODDEF \ - {"crc32", (PyCFunction)(void(*)(void))zlib_crc32, METH_FASTCALL, zlib_crc32__doc__}, + {"crc32", _PyCFunction_CAST(zlib_crc32), METH_FASTCALL, zlib_crc32__doc__}, -static PyObject * +static unsigned int zlib_crc32_impl(PyObject *module, Py_buffer *data, unsigned int value); static PyObject * @@ -762,6 +1071,7 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) PyObject *return_value = NULL; Py_buffer data = {NULL, NULL}; unsigned int value = 0; + unsigned int _return_value; if (!_PyArg_CheckPositional("crc32", nargs, 1, 2)) { goto exit; @@ -781,7 +1091,11 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = zlib_crc32_impl(module, &data, value); + _return_value = zlib_crc32_impl(module, &data, value); + if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); exit: /* Cleanup for data */ @@ -815,4 +1129,4 @@ exit: #ifndef ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #endif /* !defined(ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF) */ -/*[clinic end generated code: output=e3e8a6142ea045a7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=57ff7b511ab23132 input=a9049054013a1b77]*/ diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c index 281d3937e26..62caba031ed 100644 --- a/Modules/cmathmodule.c +++ b/Modules/cmathmodule.c @@ -7,7 +7,8 @@ #endif #include "Python.h" -#include "pycore_dtoa.h" +#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR +#include "pycore_dtoa.h" // _Py_dg_stdnan() /* we need DBL_MAX, DBL_MIN, DBL_EPSILON, DBL_MANT_DIG and FLT_RADIX from float.h. We assume that FLT_RADIX is either 2 or 16. */ #include @@ -89,14 +90,14 @@ else { /* Constants cmath.inf, cmath.infj, cmath.nan, cmath.nanj. cmath.nan and cmath.nanj are defined only when either - PY_NO_SHORT_FLOAT_REPR is *not* defined (which should be + _PY_SHORT_FLOAT_REPR is 1 (which should be the most common situation on machines using an IEEE 754 representation), or Py_NAN is defined. */ static double m_inf(void) { -#ifndef PY_NO_SHORT_FLOAT_REPR +#if _PY_SHORT_FLOAT_REPR == 1 return _Py_dg_infinity(0); #else return Py_HUGE_VAL; @@ -112,12 +113,12 @@ c_infj(void) return r; } -#if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) +#if _PY_SHORT_FLOAT_REPR == 1 static double m_nan(void) { -#ifndef PY_NO_SHORT_FLOAT_REPR +#if _PY_SHORT_FLOAT_REPR == 1 return _Py_dg_stdnan(0); #else return Py_NAN; @@ -951,23 +952,24 @@ cmath_tanh_impl(PyObject *module, Py_complex z) cmath.log z as x: Py_complex - base as y_obj: object = NULL + base as y_obj: object = None / log(z[, base]) -> the logarithm of z to the given base. -If the base not specified, returns the natural logarithm (base e) of z. +If the base is not specified or is None, returns the +natural logarithm (base e) of z. [clinic start generated code]*/ static PyObject * cmath_log_impl(PyObject *module, Py_complex x, PyObject *y_obj) -/*[clinic end generated code: output=4effdb7d258e0d94 input=230ed3a71ecd000a]*/ +/*[clinic end generated code: output=4effdb7d258e0d94 input=e7db51859ebf70bf]*/ { Py_complex y; errno = 0; x = c_log(x); - if (y_obj != NULL) { + if (y_obj != Py_None) { y = PyComplex_AsCComplex(y_obj); if (PyErr_Occurred()) { return NULL; @@ -1281,7 +1283,7 @@ cmath_exec(PyObject *mod) PyComplex_FromCComplex(c_infj())) < 0) { return -1; } -#if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) +#if _PY_SHORT_FLOAT_REPR == 1 if (PyModule_AddObject(mod, "nan", PyFloat_FromDouble(m_nan())) < 0) { return -1; } @@ -1426,4 +1428,4 @@ PyMODINIT_FUNC PyInit_cmath(void) { return PyModuleDef_Init(&cmathmodule); -} \ No newline at end of file +} diff --git a/Modules/errnomodule.c b/Modules/errnomodule.c index bf6766e0234..4de4144520a 100644 --- a/Modules/errnomodule.c +++ b/Modules/errnomodule.c @@ -280,6 +280,10 @@ errno_exec(PyObject *module) #ifdef ENOANO add_errcode("ENOANO", ENOANO, "No anode"); #endif +#if defined(__wasi__) && !defined(ESHUTDOWN) + // WASI SDK 16 does not have ESHUTDOWN, shutdown results in EPIPE. + #define ESHUTDOWN EPIPE +#endif #ifdef ESHUTDOWN add_errcode("ESHUTDOWN", ESHUTDOWN, "Cannot send after transport endpoint shutdown"); #else @@ -923,6 +927,10 @@ errno_exec(PyObject *module) #ifdef EQFULL add_errcode("EQFULL", EQFULL, "Interface output queue is full"); #endif +#ifdef ENOTCAPABLE + // WASI extension + add_errcode("ENOTCAPABLE", ENOTCAPABLE, "Capabilities insufficient"); +#endif Py_DECREF(error_dict); return 0; diff --git a/Modules/expat/COPYING b/Modules/expat/COPYING index 3c0142e71c8..ce9e5939291 100644 --- a/Modules/expat/COPYING +++ b/Modules/expat/COPYING @@ -1,5 +1,5 @@ Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper -Copyright (c) 2001-2019 Expat maintainers +Copyright (c) 2001-2022 Expat maintainers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h index b7d6d354801..1c83563cbf6 100644 --- a/Modules/expat/expat.h +++ b/Modules/expat/expat.h @@ -11,10 +11,11 @@ Copyright (c) 2000-2005 Fred L. Drake, Jr. Copyright (c) 2001-2002 Greg Stein Copyright (c) 2002-2016 Karl Waclawek - Copyright (c) 2016-2021 Sebastian Pipping + Copyright (c) 2016-2022 Sebastian Pipping Copyright (c) 2016 Cristian Rodríguez Copyright (c) 2016 Thomas Beutlich Copyright (c) 2017 Rhodri James + Copyright (c) 2022 Thijs Schreijer Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -174,8 +175,10 @@ struct XML_cp { }; /* This is called for an element declaration. See above for - description of the model argument. It's the caller's responsibility - to free model when finished with it. + description of the model argument. It's the user code's responsibility + to free model when finished with it. See XML_FreeContentModel. + There is no need to free the model from the handler, it can be kept + around and freed at a later stage. */ typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData, const XML_Char *name, @@ -237,6 +240,17 @@ XML_ParserCreate(const XML_Char *encoding); and the local part will be concatenated without any separator. It is a programming error to use the separator '\0' with namespace triplets (see XML_SetReturnNSTriplet). + If a namespace separator is chosen that can be part of a URI or + part of an XML name, splitting an expanded name back into its + 1, 2 or 3 original parts on application level in the element handler + may end up vulnerable, so these are advised against; sane choices for + a namespace separator are e.g. '\n' (line feed) and '|' (pipe). + + Note that Expat does not validate namespace URIs (beyond encoding) + against RFC 3986 today (and is not required to do so with regard to + the XML 1.0 namespaces specification) but it may start doing that + in future releases. Before that, an application using Expat must + be ready to receive namespace URIs containing non-URI characters. */ XMLPARSEAPI(XML_Parser) XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); @@ -317,7 +331,7 @@ typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData, const XML_Char *pubid, int has_internal_subset); -/* This is called for the start of the DOCTYPE declaration when the +/* This is called for the end of the DOCTYPE declaration when the closing > is encountered, but after processing any external subset. */ @@ -1040,8 +1054,8 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold( See http://semver.org. */ #define XML_MAJOR_VERSION 2 -#define XML_MINOR_VERSION 4 -#define XML_MICRO_VERSION 1 +#define XML_MINOR_VERSION 5 +#define XML_MICRO_VERSION 0 #ifdef __cplusplus } diff --git a/Modules/expat/internal.h b/Modules/expat/internal.h index 444eba0fb03..e09f533b23c 100644 --- a/Modules/expat/internal.h +++ b/Modules/expat/internal.h @@ -28,7 +28,7 @@ Copyright (c) 2002-2003 Fred L. Drake, Jr. Copyright (c) 2002-2006 Karl Waclawek Copyright (c) 2003 Greg Stein - Copyright (c) 2016-2021 Sebastian Pipping + Copyright (c) 2016-2022 Sebastian Pipping Copyright (c) 2018 Yury Gribov Copyright (c) 2019 David Loffredo Licensed under the MIT license: @@ -107,7 +107,9 @@ #include // ULONG_MAX -#if defined(_WIN32) && ! defined(__USE_MINGW_ANSI_STDIO) +#if defined(_WIN32) \ + && (! defined(__USE_MINGW_ANSI_STDIO) \ + || (1 - __USE_MINGW_ANSI_STDIO - 1 == 0)) # define EXPAT_FMT_ULL(midpart) "%" midpart "I64u" # if defined(_WIN64) // Note: modifiers "td" and "zu" do not work for MinGW # define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "I64d" diff --git a/Modules/expat/pyexpatns.h b/Modules/expat/pyexpatns.h index cfb742ee000..d45d9b6c457 100644 --- a/Modules/expat/pyexpatns.h +++ b/Modules/expat/pyexpatns.h @@ -38,6 +38,9 @@ #ifndef PYEXPATNS_H #define PYEXPATNS_H +#define testingAccountingGetCountBytesDirect PyExpat_testingAccountingGetCountBytesDirect +#define testingAccountingGetCountBytesIndirect PyExpat_testingAccountingGetCountBytesIndirect +#define unsignedCharToPrintable PyExpat_unsignedCharToPrintable #define XML_DefaultCurrent PyExpat_XML_DefaultCurrent #define XML_ErrorString PyExpat_XML_ErrorString #define XML_ExpatVersion PyExpat_XML_ExpatVersion @@ -81,6 +84,8 @@ #define XML_ResumeParser PyExpat_XML_ResumeParser #define XML_SetAttlistDeclHandler PyExpat_XML_SetAttlistDeclHandler #define XML_SetBase PyExpat_XML_SetBase +#define XML_SetBillionLaughsAttackProtectionActivationThreshold PyExpat_XML_SetBillionLaughsAttackProtectionActivationThreshold +#define XML_SetBillionLaughsAttackProtectionMaximumAmplification PyExpat_XML_SetBillionLaughsAttackProtectionMaximumAmplification #define XML_SetCdataSectionHandler PyExpat_XML_SetCdataSectionHandler #define XML_SetCharacterDataHandler PyExpat_XML_SetCharacterDataHandler #define XML_SetCommentHandler PyExpat_XML_SetCommentHandler diff --git a/Modules/expat/siphash.h b/Modules/expat/siphash.h index e5406d7ee9e..303283ad2de 100644 --- a/Modules/expat/siphash.h +++ b/Modules/expat/siphash.h @@ -106,7 +106,7 @@ * if this code is included and compiled as C++; related GCC warning is: * warning: use of C++11 long long integer constant [-Wlong-long] */ -#define _SIP_ULL(high, low) (((uint64_t)high << 32) | low) +#define _SIP_ULL(high, low) ((((uint64_t)high) << 32) | (low)) #define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index 034a03c3085..b6c2eca9756 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -1,4 +1,4 @@ -/* 8539b9040d9d901366a62560a064af7cb99811335784b363abc039c5b0ebc416 (2.4.1+) +/* 5ab094ffadd6edfc94c3eee53af44a86951f9f1f0933ada3114bbce2bfb02c99 (2.5.0+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| @@ -11,15 +11,15 @@ Copyright (c) 2000-2006 Fred L. Drake, Jr. Copyright (c) 2001-2002 Greg Stein Copyright (c) 2002-2016 Karl Waclawek - Copyright (c) 2005-2009 Steven Solie + Copyright (c) 2005-2009 Steven Solie Copyright (c) 2016 Eric Rahm - Copyright (c) 2016-2021 Sebastian Pipping + Copyright (c) 2016-2022 Sebastian Pipping Copyright (c) 2016 Gaurav Copyright (c) 2016 Thomas Beutlich Copyright (c) 2016 Gustavo Grieco Copyright (c) 2016 Pascal Cuoq Copyright (c) 2016 Ed Schouten - Copyright (c) 2017-2018 Rhodri James + Copyright (c) 2017-2022 Rhodri James Copyright (c) 2017 Václav Slavík Copyright (c) 2017 Viktor Szakats Copyright (c) 2017 Chanho Park @@ -32,6 +32,10 @@ Copyright (c) 2019 David Loffredo Copyright (c) 2019-2020 Ben Wagner Copyright (c) 2019 Vadim Zeitlin + Copyright (c) 2021 Dong-hee Na + Copyright (c) 2022 Samanta Navarro + Copyright (c) 2022 Jeffrey Walton + Copyright (c) 2022 Jann Horn Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -54,6 +58,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#define XML_BUILDING_EXPAT 1 + +#include + #if ! defined(_GNU_SOURCE) # define _GNU_SOURCE 1 /* syscall prototype */ #endif @@ -84,14 +92,10 @@ # include #endif -#define XML_BUILDING_EXPAT 1 - #ifdef _WIN32 # include "winconfig.h" #endif -#include - #include "ascii.h" #include "expat.h" #include "siphash.h" @@ -131,7 +135,7 @@ * BSD / macOS (including <10.7) (arc4random): HAVE_ARC4RANDOM, \ * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \ * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \ - * Linux (including <3.17) / BSD / macOS (including <10.7) (/dev/urandom): XML_DEV_URANDOM, \ + * Linux (including <3.17) / BSD / macOS (including <10.7) / Solaris >=8 (/dev/urandom): XML_DEV_URANDOM, \ * Windows >=Vista (rand_s): _WIN32. \ \ If insist on not using any of these, bypass this error by defining \ @@ -716,11 +720,11 @@ XML_ParserCreate(const XML_Char *encodingName) { XML_Parser XMLCALL XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) { - XML_Char tmp[2]; - *tmp = nsSep; + XML_Char tmp[2] = {nsSep, 0}; return XML_ParserCreate_MM(encodingName, NULL, tmp); } +// "xml=http://www.w3.org/XML/1998/namespace" static const XML_Char implicitContext[] = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, @@ -973,7 +977,7 @@ parserCreate(const XML_Char *encodingName, if (memsuite) { XML_Memory_Handling_Suite *mtemp; - parser = (XML_Parser)memsuite->malloc_fcn(sizeof(struct XML_ParserStruct)); + parser = memsuite->malloc_fcn(sizeof(struct XML_ParserStruct)); if (parser != NULL) { mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); mtemp->malloc_fcn = memsuite->malloc_fcn; @@ -1065,6 +1069,14 @@ parserCreate(const XML_Char *encodingName, parserInit(parser, encodingName); if (encodingName && ! parser->m_protocolEncodingName) { + if (dtd) { + // We need to stop the upcoming call to XML_ParserFree from happily + // destroying parser->m_dtd because the DTD is shared with the parent + // parser and the only guard that keeps XML_ParserFree from destroying + // parser->m_dtd is parser->m_isParamEntity but it will be set to + // XML_TRUE only later in XML_ExternalEntityParserCreate (or not at all). + parser->m_dtd = NULL; + } XML_ParserFree(parser); return NULL; } @@ -1342,8 +1354,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, would be otherwise. */ if (parser->m_ns) { - XML_Char tmp[2]; - *tmp = parser->m_namespaceSeparator; + XML_Char tmp[2] = {parser->m_namespaceSeparator, 0}; parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd); } else { parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd); @@ -2066,6 +2077,11 @@ XML_GetBuffer(XML_Parser parser, int len) { keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer); if (keep > XML_CONTEXT_BYTES) keep = XML_CONTEXT_BYTES; + /* Detect and prevent integer overflow */ + if (keep > INT_MAX - neededSize) { + parser->m_errorCode = XML_ERROR_NO_MEMORY; + return NULL; + } neededSize += keep; #endif /* defined XML_CONTEXT_BYTES */ if (neededSize @@ -2556,6 +2572,7 @@ storeRawNames(XML_Parser parser) { while (tag) { int bufSize; int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); + size_t rawNameLen; char *rawNameBuf = tag->buf + nameLen; /* Stop if already stored. Since m_tagStack is a stack, we can stop at the first entry that has already been copied; everything @@ -2567,7 +2584,11 @@ storeRawNames(XML_Parser parser) { /* For re-use purposes we need to ensure that the size of tag->buf is a multiple of sizeof(XML_Char). */ - bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); + rawNameLen = ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); + /* Detect and prevent integer overflow. */ + if (rawNameLen > (size_t)INT_MAX - nameLen) + return XML_FALSE; + bufSize = nameLen + (int)rawNameLen; if (bufSize > tag->bufEnd - tag->buf) { char *temp = (char *)REALLOC(parser, tag->buf, bufSize); if (temp == NULL) @@ -2999,9 +3020,6 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, int len; const char *rawName; TAG *tag = parser->m_tagStack; - parser->m_tagStack = tag->parent; - tag->parent = parser->m_freeTagList; - parser->m_freeTagList = tag; rawName = s + enc->minBytesPerChar * 2; len = XmlNameLength(enc, rawName); if (len != tag->rawNameLength @@ -3009,6 +3027,9 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, *eventPP = rawName; return XML_ERROR_TAG_MISMATCH; } + parser->m_tagStack = tag->parent; + tag->parent = parser->m_freeTagList; + parser->m_freeTagList = tag; --parser->m_tagLevel; if (parser->m_endElementHandler) { const XML_Char *localPart; @@ -3260,13 +3281,38 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, /* get the attributes from the tokenizer */ n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts); + + /* Detect and prevent integer overflow */ + if (n > INT_MAX - nDefaultAtts) { + return XML_ERROR_NO_MEMORY; + } + if (n + nDefaultAtts > parser->m_attsSize) { int oldAttsSize = parser->m_attsSize; ATTRIBUTE *temp; #ifdef XML_ATTR_INFO XML_AttrInfo *temp2; #endif + + /* Detect and prevent integer overflow */ + if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE) + || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) { + return XML_ERROR_NO_MEMORY; + } + parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; + + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) { + parser->m_attsSize = oldAttsSize; + return XML_ERROR_NO_MEMORY; + } +#endif + temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, parser->m_attsSize * sizeof(ATTRIBUTE)); if (temp == NULL) { @@ -3275,6 +3321,17 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, } parser->m_atts = temp; #ifdef XML_ATTR_INFO + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +# if UINT_MAX >= SIZE_MAX + if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(XML_AttrInfo)) { + parser->m_attsSize = oldAttsSize; + return XML_ERROR_NO_MEMORY; + } +# endif + temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, parser->m_attsSize * sizeof(XML_AttrInfo)); if (temp2 == NULL) { @@ -3413,7 +3470,13 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, if (nPrefixes) { int j; /* hash table index */ unsigned long version = parser->m_nsAttsVersion; - int nsAttsSize = (int)1 << parser->m_nsAttsPower; + + /* Detect and prevent invalid shift */ + if (parser->m_nsAttsPower >= sizeof(unsigned int) * 8 /* bits per byte */) { + return XML_ERROR_NO_MEMORY; + } + + unsigned int nsAttsSize = 1u << parser->m_nsAttsPower; unsigned char oldNsAttsPower = parser->m_nsAttsPower; /* size of hash table must be at least 2 * (# of prefixed attributes) */ if ((nPrefixes << 1) @@ -3424,7 +3487,28 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, ; if (parser->m_nsAttsPower < 3) parser->m_nsAttsPower = 3; - nsAttsSize = (int)1 << parser->m_nsAttsPower; + + /* Detect and prevent invalid shift */ + if (parser->m_nsAttsPower >= sizeof(nsAttsSize) * 8 /* bits per byte */) { + /* Restore actual size of memory in m_nsAtts */ + parser->m_nsAttsPower = oldNsAttsPower; + return XML_ERROR_NO_MEMORY; + } + + nsAttsSize = 1u << parser->m_nsAttsPower; + + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if (nsAttsSize > (size_t)(-1) / sizeof(NS_ATT)) { + /* Restore actual size of memory in m_nsAtts */ + parser->m_nsAttsPower = oldNsAttsPower; + return XML_ERROR_NO_MEMORY; + } +#endif + temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts, nsAttsSize * sizeof(NS_ATT)); if (! temp) { @@ -3582,9 +3666,31 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, tagNamePtr->prefixLen = prefixLen; for (i = 0; localPart[i++];) ; /* i includes null terminator */ + + /* Detect and prevent integer overflow */ + if (binding->uriLen > INT_MAX - prefixLen + || i > INT_MAX - (binding->uriLen + prefixLen)) { + return XML_ERROR_NO_MEMORY; + } + n = i + binding->uriLen + prefixLen; if (n > binding->uriAlloc) { TAG *p; + + /* Detect and prevent integer overflow */ + if (n > INT_MAX - EXPAND_SPARE) { + return XML_ERROR_NO_MEMORY; + } + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { + return XML_ERROR_NO_MEMORY; + } +#endif + uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char)); if (! uri) return XML_ERROR_NO_MEMORY; @@ -3609,12 +3715,124 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, return XML_ERROR_NONE; } +static XML_Bool +is_rfc3986_uri_char(XML_Char candidate) { + // For the RFC 3986 ANBF grammar see + // https://datatracker.ietf.org/doc/html/rfc3986#appendix-A + + switch (candidate) { + // From rule "ALPHA" (uppercase half) + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + + // From rule "ALPHA" (lowercase half) + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + + // From rule "DIGIT" + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + + // From rule "pct-encoded" + case '%': + + // From rule "unreserved" + case '-': + case '.': + case '_': + case '~': + + // From rule "gen-delims" + case ':': + case '/': + case '?': + case '#': + case '[': + case ']': + case '@': + + // From rule "sub-delims" + case '!': + case '$': + case '&': + case '\'': + case '(': + case ')': + case '*': + case '+': + case ',': + case ';': + case '=': + return XML_TRUE; + + default: + return XML_FALSE; + } +} + /* addBinding() overwrites the value of prefix->binding without checking. Therefore one must keep track of the old value outside of addBinding(). */ static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr) { + // "http://www.w3.org/XML/1998/namespace" static const XML_Char xmlNamespace[] = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, @@ -3625,6 +3843,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'}; static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1; + // "http://www.w3.org/2000/xmlns/" static const XML_Char xmlnsNamespace[] = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, @@ -3664,6 +3883,29 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, if (! mustBeXML && isXMLNS && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) isXMLNS = XML_FALSE; + + // NOTE: While Expat does not validate namespace URIs against RFC 3986 + // today (and is not REQUIRED to do so with regard to the XML 1.0 + // namespaces specification) we have to at least make sure, that + // the application on top of Expat (that is likely splitting expanded + // element names ("qualified names") of form + // "[uri sep] local [sep prefix] '\0'" back into 1, 2 or 3 pieces + // in its element handler code) cannot be confused by an attacker + // putting additional namespace separator characters into namespace + // declarations. That would be ambiguous and not to be expected. + // + // While the HTML API docs of function XML_ParserCreateNS have been + // advising against use of a namespace separator character that can + // appear in a URI for >20 years now, some widespread applications + // are using URI characters (':' (colon) in particular) for a + // namespace separator, in practice. To keep these applications + // functional, we only reject namespaces URIs containing the + // application-chosen namespace separator if the chosen separator + // is a non-URI character with regard to RFC 3986. + if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator) + && ! is_rfc3986_uri_char(uri[len])) { + return XML_ERROR_SYNTAX; + } } isXML = isXML && len == xmlLen; isXMLNS = isXMLNS && len == xmlnsLen; @@ -3680,6 +3922,21 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, if (parser->m_freeBindingList) { b = parser->m_freeBindingList; if (len > b->uriAlloc) { + /* Detect and prevent integer overflow */ + if (len > INT_MAX - EXPAND_SPARE) { + return XML_ERROR_NO_MEMORY; + } + + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { + return XML_ERROR_NO_MEMORY; + } +#endif + XML_Char *temp = (XML_Char *)REALLOC( parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE)); if (temp == NULL) @@ -3692,6 +3949,21 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, b = (BINDING *)MALLOC(parser, sizeof(BINDING)); if (! b) return XML_ERROR_NO_MEMORY; + + /* Detect and prevent integer overflow */ + if (len > INT_MAX - EXPAND_SPARE) { + return XML_ERROR_NO_MEMORY; + } + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { + return XML_ERROR_NO_MEMORY; + } +#endif + b->uri = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE)); if (! b->uri) { @@ -3976,7 +4248,7 @@ initializeEncoding(XML_Parser parser) { const char *s; #ifdef XML_UNICODE char encodingBuf[128]; - /* See comments about `protoclEncodingName` in parserInit() */ + /* See comments about `protocolEncodingName` in parserInit() */ if (! parser->m_protocolEncodingName) s = NULL; else { @@ -4008,7 +4280,7 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s, const XML_Char *storedEncName = NULL; const ENCODING *newEncoding = NULL; const char *version = NULL; - const char *versionend; + const char *versionend = NULL; const XML_Char *storedversion = NULL; int standalone = -1; @@ -4712,10 +4984,10 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, parser->m_handlerArg, parser->m_declElementType->name, parser->m_declAttributeId->name, parser->m_declAttributeType, 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); - poolClear(&parser->m_tempPool); handleDefault = XML_FALSE; } } + poolClear(&parser->m_tempPool); break; case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: case XML_ROLE_FIXED_ATTRIBUTE_VALUE: @@ -5018,6 +5290,11 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, if (parser->m_prologState.level >= parser->m_groupSize) { if (parser->m_groupSize) { { + /* Detect and prevent integer overflow */ + if (parser->m_groupSize > (unsigned int)(-1) / 2u) { + return XML_ERROR_NO_MEMORY; + } + char *const new_connector = (char *)REALLOC( parser, parser->m_groupConnector, parser->m_groupSize *= 2); if (new_connector == NULL) { @@ -5028,6 +5305,16 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, } if (dtd->scaffIndex) { + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if (parser->m_groupSize > (size_t)(-1) / sizeof(int)) { + return XML_ERROR_NO_MEMORY; + } +#endif + int *const new_scaff_index = (int *)REALLOC( parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int)); if (new_scaff_index == NULL) @@ -5108,7 +5395,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, * * If 'standalone' is false, the DTD must have no * parameter entities or we wouldn't have passed the outer - * 'if' statement. That measn the only entity in the hash + * 'if' statement. That means the only entity in the hash * table is the external subset name "#" which cannot be * given as a parameter entity name in XML syntax, so the * lookup must have returned NULL and we don't even reach @@ -5236,7 +5523,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, if (dtd->in_eldecl) { ELEMENT_TYPE *el; const XML_Char *name; - int nameLen; + size_t nameLen; const char *nxt = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar); int myindex = nextScaffoldPart(parser); @@ -5252,7 +5539,13 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, nameLen = 0; for (; name[nameLen++];) ; - dtd->contentStringLen += nameLen; + + /* Detect and prevent integer overflow */ + if (nameLen > UINT_MAX - dtd->contentStringLen) { + return XML_ERROR_NO_MEMORY; + } + + dtd->contentStringLen += (unsigned)nameLen; if (parser->m_elementDeclHandler) handleDefault = XML_FALSE; } @@ -5514,19 +5807,27 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end, if (result != XML_ERROR_NONE) return result; - else if (textEnd != next - && parser->m_parsingStatus.parsing == XML_SUSPENDED) { + + if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { entity->processed = (int)(next - (const char *)entity->textPtr); return result; - } else { + } + #ifdef XML_DTD - entityTrackingOnClose(parser, entity, __LINE__); + entityTrackingOnClose(parser, entity, __LINE__); #endif - entity->open = XML_FALSE; - parser->m_openInternalEntities = openEntity->next; - /* put openEntity back in list of free instances */ - openEntity->next = parser->m_freeInternalEntities; - parser->m_freeInternalEntities = openEntity; + entity->open = XML_FALSE; + parser->m_openInternalEntities = openEntity->next; + /* put openEntity back in list of free instances */ + openEntity->next = parser->m_freeInternalEntities; + parser->m_freeInternalEntities = openEntity; + + // If there are more open entities we want to stop right here and have the + // upcoming call to XML_ResumeParser continue with entity content, or it would + // be ignored altogether. + if (parser->m_openInternalEntities != NULL + && parser->m_parsingStatus.parsing == XML_SUSPENDED) { + return XML_ERROR_NONE; } #ifdef XML_DTD @@ -5542,10 +5843,15 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end, { parser->m_processor = contentProcessor; /* see externalEntityContentProcessor vs contentProcessor */ - return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, - s, end, nextPtr, - (XML_Bool)! parser->m_parsingStatus.finalBuffer, - XML_ACCOUNT_DIRECT); + result = doContent(parser, parser->m_parentParser ? 1 : 0, + parser->m_encoding, s, end, nextPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer, + XML_ACCOUNT_DIRECT); + if (result == XML_ERROR_NONE) { + if (! storeRawNames(parser)) + return XML_ERROR_NO_MEMORY; + } + return result; } } @@ -6098,7 +6404,24 @@ defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, } } else { DEFAULT_ATTRIBUTE *temp; + + /* Detect and prevent integer overflow */ + if (type->allocDefaultAtts > INT_MAX / 2) { + return 0; + } + int count = type->allocDefaultAtts * 2; + + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if ((unsigned)count > (size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE)) { + return 0; + } +#endif + temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE))); if (temp == NULL) @@ -6388,7 +6711,7 @@ normalizePublicId(XML_Char *publicId) { static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms) { - DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD)); + DTD *p = ms->malloc_fcn(sizeof(DTD)); if (p == NULL) return p; poolInit(&(p->pool), ms); @@ -6561,8 +6884,8 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, if (! newE) return 0; if (oldE->nDefaultAtts) { - newE->defaultAtts = (DEFAULT_ATTRIBUTE *)ms->malloc_fcn( - oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); + newE->defaultAtts + = ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); if (! newE->defaultAtts) { return 0; } @@ -6724,7 +7047,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) { /* table->size is a power of 2 */ table->size = (size_t)1 << INIT_POWER; tsize = table->size * sizeof(NAMED *); - table->v = (NAMED **)table->mem->malloc_fcn(tsize); + table->v = table->mem->malloc_fcn(tsize); if (! table->v) { table->size = 0; return NULL; @@ -6749,10 +7072,22 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) { /* check for overflow (table is half full) */ if (table->used >> (table->power - 1)) { unsigned char newPower = table->power + 1; + + /* Detect and prevent invalid shift */ + if (newPower >= sizeof(unsigned long) * 8 /* bits per byte */) { + return NULL; + } + size_t newSize = (size_t)1 << newPower; unsigned long newMask = (unsigned long)newSize - 1; + + /* Detect and prevent integer overflow */ + if (newSize > (size_t)(-1) / sizeof(NAMED *)) { + return NULL; + } + size_t tsize = newSize * sizeof(NAMED *); - NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize); + NAMED **newV = table->mem->malloc_fcn(tsize); if (! newV) return NULL; memset(newV, 0, tsize); @@ -6781,7 +7116,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) { } } } - table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize); + table->v[i] = table->mem->malloc_fcn(createSize); if (! table->v[i]) return NULL; memset(table->v[i], 0, createSize); @@ -7069,7 +7404,7 @@ poolGrow(STRING_POOL *pool) { if (bytesToAllocate == 0) return XML_FALSE; - tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate); + tem = pool->mem->malloc_fcn(bytesToAllocate); if (! tem) return XML_FALSE; tem->size = blockSize; @@ -7100,6 +7435,20 @@ nextScaffoldPart(XML_Parser parser) { if (dtd->scaffCount >= dtd->scaffSize) { CONTENT_SCAFFOLD *temp; if (dtd->scaffold) { + /* Detect and prevent integer overflow */ + if (dtd->scaffSize > UINT_MAX / 2u) { + return -1; + } + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if (dtd->scaffSize > (size_t)(-1) / 2u / sizeof(CONTENT_SCAFFOLD)) { + return -1; + } +#endif + temp = (CONTENT_SCAFFOLD *)REALLOC( parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); if (temp == NULL) @@ -7131,55 +7480,130 @@ nextScaffoldPart(XML_Parser parser) { return next; } -static void -build_node(XML_Parser parser, int src_node, XML_Content *dest, - XML_Content **contpos, XML_Char **strpos) { - DTD *const dtd = parser->m_dtd; /* save one level of indirection */ - dest->type = dtd->scaffold[src_node].type; - dest->quant = dtd->scaffold[src_node].quant; - if (dest->type == XML_CTYPE_NAME) { - const XML_Char *src; - dest->name = *strpos; - src = dtd->scaffold[src_node].name; - for (;;) { - *(*strpos)++ = *src; - if (! *src) - break; - src++; - } - dest->numchildren = 0; - dest->children = NULL; - } else { - unsigned int i; - int cn; - dest->numchildren = dtd->scaffold[src_node].childcnt; - dest->children = *contpos; - *contpos += dest->numchildren; - for (i = 0, cn = dtd->scaffold[src_node].firstchild; i < dest->numchildren; - i++, cn = dtd->scaffold[cn].nextsib) { - build_node(parser, cn, &(dest->children[i]), contpos, strpos); - } - dest->name = NULL; - } -} - static XML_Content * build_model(XML_Parser parser) { + /* Function build_model transforms the existing parser->m_dtd->scaffold + * array of CONTENT_SCAFFOLD tree nodes into a new array of + * XML_Content tree nodes followed by a gapless list of zero-terminated + * strings. */ DTD *const dtd = parser->m_dtd; /* save one level of indirection */ XML_Content *ret; - XML_Content *cpos; - XML_Char *str; - int allocsize = (dtd->scaffCount * sizeof(XML_Content) - + (dtd->contentStringLen * sizeof(XML_Char))); + XML_Char *str; /* the current string writing location */ + + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if (dtd->scaffCount > (size_t)(-1) / sizeof(XML_Content)) { + return NULL; + } + if (dtd->contentStringLen > (size_t)(-1) / sizeof(XML_Char)) { + return NULL; + } +#endif + if (dtd->scaffCount * sizeof(XML_Content) + > (size_t)(-1) - dtd->contentStringLen * sizeof(XML_Char)) { + return NULL; + } + + const size_t allocsize = (dtd->scaffCount * sizeof(XML_Content) + + (dtd->contentStringLen * sizeof(XML_Char))); ret = (XML_Content *)MALLOC(parser, allocsize); if (! ret) return NULL; - str = (XML_Char *)(&ret[dtd->scaffCount]); - cpos = &ret[1]; + /* What follows is an iterative implementation (of what was previously done + * recursively in a dedicated function called "build_node". The old recursive + * build_node could be forced into stack exhaustion from input as small as a + * few megabyte, and so that was a security issue. Hence, a function call + * stack is avoided now by resolving recursion.) + * + * The iterative approach works as follows: + * + * - We have two writing pointers, both walking up the result array; one does + * the work, the other creates "jobs" for its colleague to do, and leads + * the way: + * + * - The faster one, pointer jobDest, always leads and writes "what job + * to do" by the other, once they reach that place in the + * array: leader "jobDest" stores the source node array index (relative + * to array dtd->scaffold) in field "numchildren". + * + * - The slower one, pointer dest, looks at the value stored in the + * "numchildren" field (which actually holds a source node array index + * at that time) and puts the real data from dtd->scaffold in. + * + * - Before the loop starts, jobDest writes source array index 0 + * (where the root node is located) so that dest will have something to do + * when it starts operation. + * + * - Whenever nodes with children are encountered, jobDest appends + * them as new jobs, in order. As a result, tree node siblings are + * adjacent in the resulting array, for example: + * + * [0] root, has two children + * [1] first child of 0, has three children + * [3] first child of 1, does not have children + * [4] second child of 1, does not have children + * [5] third child of 1, does not have children + * [2] second child of 0, does not have children + * + * Or (the same data) presented in flat array view: + * + * [0] root, has two children + * + * [1] first child of 0, has three children + * [2] second child of 0, does not have children + * + * [3] first child of 1, does not have children + * [4] second child of 1, does not have children + * [5] third child of 1, does not have children + * + * - The algorithm repeats until all target array indices have been processed. + */ + XML_Content *dest = ret; /* tree node writing location, moves upwards */ + XML_Content *const destLimit = &ret[dtd->scaffCount]; + XML_Content *jobDest = ret; /* next free writing location in target array */ + str = (XML_Char *)&ret[dtd->scaffCount]; + + /* Add the starting job, the root node (index 0) of the source tree */ + (jobDest++)->numchildren = 0; + + for (; dest < destLimit; dest++) { + /* Retrieve source tree array index from job storage */ + const int src_node = (int)dest->numchildren; + + /* Convert item */ + dest->type = dtd->scaffold[src_node].type; + dest->quant = dtd->scaffold[src_node].quant; + if (dest->type == XML_CTYPE_NAME) { + const XML_Char *src; + dest->name = str; + src = dtd->scaffold[src_node].name; + for (;;) { + *str++ = *src; + if (! *src) + break; + src++; + } + dest->numchildren = 0; + dest->children = NULL; + } else { + unsigned int i; + int cn; + dest->name = NULL; + dest->numchildren = dtd->scaffold[src_node].childcnt; + dest->children = jobDest; + + /* Append scaffold indices of children to array */ + for (i = 0, cn = dtd->scaffold[src_node].firstchild; + i < dest->numchildren; i++, cn = dtd->scaffold[cn].nextsib) + (jobDest++)->numchildren = (unsigned int)cn; + } + } - build_node(parser, 0, ret, &cpos, &str); return ret; } @@ -7208,7 +7632,7 @@ getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr, static XML_Char * copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) { - int charsRequired = 0; + size_t charsRequired = 0; XML_Char *result; /* First determine how long the string is */ diff --git a/Modules/expat/xmlrole.c b/Modules/expat/xmlrole.c index 08173b0fd54..3f0f5c150c6 100644 --- a/Modules/expat/xmlrole.c +++ b/Modules/expat/xmlrole.c @@ -11,10 +11,11 @@ Copyright (c) 2002 Greg Stein Copyright (c) 2002-2006 Karl Waclawek Copyright (c) 2002-2003 Fred L. Drake, Jr. - Copyright (c) 2005-2009 Steven Solie + Copyright (c) 2005-2009 Steven Solie Copyright (c) 2016-2021 Sebastian Pipping Copyright (c) 2017 Rhodri James Copyright (c) 2019 David Loffredo + Copyright (c) 2021 Dong-hee Na Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -37,14 +38,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include + #include #ifdef _WIN32 # include "winconfig.h" #endif -#include - #include "expat_external.h" #include "internal.h" #include "xmlrole.h" diff --git a/Modules/expat/xmltok.c b/Modules/expat/xmltok.c index 5b935718743..2b7012a58be 100644 --- a/Modules/expat/xmltok.c +++ b/Modules/expat/xmltok.c @@ -11,8 +11,8 @@ Copyright (c) 2001-2003 Fred L. Drake, Jr. Copyright (c) 2002 Greg Stein Copyright (c) 2002-2016 Karl Waclawek - Copyright (c) 2005-2009 Steven Solie - Copyright (c) 2016-2021 Sebastian Pipping + Copyright (c) 2005-2009 Steven Solie + Copyright (c) 2016-2022 Sebastian Pipping Copyright (c) 2016 Pascal Cuoq Copyright (c) 2016 Don Lewis Copyright (c) 2017 Rhodri James @@ -20,6 +20,8 @@ Copyright (c) 2017 Benbuck Nason Copyright (c) 2017 José Gutiérrez de la Concha Copyright (c) 2019 David Loffredo + Copyright (c) 2021 Dong-hee Na + Copyright (c) 2022 Martin Ettl Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -42,16 +44,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifdef _WIN32 -# include "winconfig.h" -#endif - #include #include #include /* memcpy */ #include +#ifdef _WIN32 +# include "winconfig.h" +#endif + #include "expat_external.h" #include "internal.h" #include "xmltok.h" @@ -97,11 +99,6 @@ + ((((byte)[1]) & 3) << 1) + ((((byte)[2]) >> 5) & 1)] \ & (1u << (((byte)[2]) & 0x1F))) -#define UTF8_GET_NAMING(pages, p, n) \ - ((n) == 2 \ - ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \ - : ((n) == 3 ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) : 0)) - /* Detection of invalid UTF-8 sequences is based on Table 3.1B of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/ with the additional restriction of not allowing the Unicode @@ -300,7 +297,7 @@ sb_charMatches(const ENCODING *enc, const char *p, int c) { } #else /* c is an ASCII character */ -# define CHAR_MATCHES(enc, p, c) (*(p) == c) +# define CHAR_MATCHES(enc, p, c) (*(p) == (c)) #endif #define PREFIX(ident) normal_##ident @@ -744,7 +741,7 @@ DEFINE_UTF16_TO_UTF16(big2_) ((p)[1] == 0 ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \ : unicode_byte_type((p)[1], (p)[0])) #define LITTLE2_BYTE_TO_ASCII(p) ((p)[1] == 0 ? (p)[0] : -1) -#define LITTLE2_CHAR_MATCHES(p, c) ((p)[1] == 0 && (p)[0] == c) +#define LITTLE2_CHAR_MATCHES(p, c) ((p)[1] == 0 && (p)[0] == (c)) #define LITTLE2_IS_NAME_CHAR_MINBPC(p) \ UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) #define LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) \ @@ -879,7 +876,7 @@ static const struct normal_encoding internal_little2_encoding ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \ : unicode_byte_type((p)[0], (p)[1])) #define BIG2_BYTE_TO_ASCII(p) ((p)[0] == 0 ? (p)[1] : -1) -#define BIG2_CHAR_MATCHES(p, c) ((p)[0] == 0 && (p)[1] == c) +#define BIG2_CHAR_MATCHES(p, c) ((p)[0] == 0 && (p)[1] == (c)) #define BIG2_IS_NAME_CHAR_MINBPC(p) \ UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) #define BIG2_IS_NMSTRT_CHAR_MINBPC(p) \ diff --git a/Modules/expat/xmltok_impl.c b/Modules/expat/xmltok_impl.c index 0430591b426..1971d74bf8c 100644 --- a/Modules/expat/xmltok_impl.c +++ b/Modules/expat/xmltok_impl.c @@ -10,12 +10,13 @@ Copyright (c) 2000 Clark Cooper Copyright (c) 2002 Fred L. Drake, Jr. Copyright (c) 2002-2016 Karl Waclawek - Copyright (c) 2016-2021 Sebastian Pipping + Copyright (c) 2016-2022 Sebastian Pipping Copyright (c) 2017 Rhodri James Copyright (c) 2018 Benjamin Peterson Copyright (c) 2018 Anton Maklakov Copyright (c) 2019 David Loffredo Copyright (c) 2020 Boris Kolpackov + Copyright (c) 2022 Martin Ettl Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -69,7 +70,7 @@ case BT_LEAD##n: \ if (end - ptr < n) \ return XML_TOK_PARTIAL_CHAR; \ - if (! IS_NAME_CHAR(enc, ptr, n)) { \ + if (IS_INVALID_CHAR(enc, ptr, n) || ! IS_NAME_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ @@ -96,9 +97,9 @@ # define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \ case BT_LEAD##n: \ - if (end - ptr < n) \ + if ((end) - (ptr) < (n)) \ return XML_TOK_PARTIAL_CHAR; \ - if (! IS_NMSTRT_CHAR(enc, ptr, n)) { \ + if (IS_INVALID_CHAR(enc, ptr, n) || ! IS_NMSTRT_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ @@ -124,7 +125,8 @@ # define PREFIX(ident) ident # endif -# define HAS_CHARS(enc, ptr, end, count) (end - ptr >= count * MINBPC(enc)) +# define HAS_CHARS(enc, ptr, end, count) \ + ((end) - (ptr) >= ((count)*MINBPC(enc))) # define HAS_CHAR(enc, ptr, end) HAS_CHARS(enc, ptr, end, 1) @@ -1142,6 +1144,10 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, case BT_LEAD##n: \ if (end - ptr < n) \ return XML_TOK_PARTIAL_CHAR; \ + if (IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ ptr += n; \ tok = XML_TOK_NAME; \ @@ -1270,7 +1276,7 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end, switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ - ptr += n; \ + ptr += n; /* NOTE: The encoding has already been validated. */ \ break; LEAD_CASE(2) LEAD_CASE(3) @@ -1339,7 +1345,7 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end, switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ - ptr += n; \ + ptr += n; /* NOTE: The encoding has already been validated. */ \ break; LEAD_CASE(2) LEAD_CASE(3) @@ -1518,7 +1524,7 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr, int attsMax, state = inName; \ } # define LEAD_CASE(n) \ - case BT_LEAD##n: \ + case BT_LEAD##n: /* NOTE: The encoding has already been validated. */ \ START_NAME ptr += (n - MINBPC(enc)); \ break; LEAD_CASE(2) @@ -1730,7 +1736,7 @@ PREFIX(nameLength)(const ENCODING *enc, const char *ptr) { switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ - ptr += n; \ + ptr += n; /* NOTE: The encoding has already been validated. */ \ break; LEAD_CASE(2) LEAD_CASE(3) @@ -1775,7 +1781,7 @@ PREFIX(updatePosition)(const ENCODING *enc, const char *ptr, const char *end, switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ - ptr += n; \ + ptr += n; /* NOTE: The encoding has already been validated. */ \ pos->columnNumber++; \ break; LEAD_CASE(2) diff --git a/Modules/expat/xmltok_impl.h b/Modules/expat/xmltok_impl.h index c518aada013..3469c4ae138 100644 --- a/Modules/expat/xmltok_impl.h +++ b/Modules/expat/xmltok_impl.h @@ -45,7 +45,7 @@ enum { BT_LF, /* line feed = "\n" */ BT_GT, /* greater than = ">" */ BT_QUOT, /* quotation character = "\"" */ - BT_APOS, /* aposthrophe = "'" */ + BT_APOS, /* apostrophe = "'" */ BT_EQUALS, /* equal sign = "=" */ BT_QUEST, /* question mark = "?" */ BT_EXCL, /* exclamation mark = "!" */ diff --git a/Modules/expat/xmltok_ns.c b/Modules/expat/xmltok_ns.c index 5fd83922359..fbdd3e3c7b7 100644 --- a/Modules/expat/xmltok_ns.c +++ b/Modules/expat/xmltok_ns.c @@ -11,7 +11,7 @@ Copyright (c) 2002 Greg Stein Copyright (c) 2002 Fred L. Drake, Jr. Copyright (c) 2002-2006 Karl Waclawek - Copyright (c) 2017 Sebastian Pipping + Copyright (c) 2017-2021 Sebastian Pipping Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -93,7 +93,7 @@ NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, static const ENCODING * NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) { # define ENCODING_MAX 128 - char buf[ENCODING_MAX]; + char buf[ENCODING_MAX] = ""; char *p = buf; int i; XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1); diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index cb2e2588e19..5309a3728c5 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -2,15 +2,13 @@ #include "pycore_initconfig.h" // _PyStatus_ERR #include "pycore_pyerrors.h" // _Py_DumpExtensionModules #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_signal.h" // Py_NSIG #include "pycore_traceback.h" // _Py_DumpTracebackThreads -#include "frameobject.h" - #include #include -#include #include // abort() -#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) +#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) && defined(HAVE_PTHREAD_H) # include #endif #ifdef MS_WINDOWS @@ -20,28 +18,32 @@ # include #endif +#if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) && defined(HAVE_SYS_AUXV_H) +# include // AT_MINSIGSTKSZ +# include // getauxval() +#endif + /* Allocate at maximum 100 MiB of the stack to raise the stack overflow */ #define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024) -#ifndef MS_WINDOWS - /* register() is useless on Windows, because only SIGSEGV, SIGABRT and - SIGILL can be handled by the process, and these signals can only be used - with enable(), not using register() */ -# define FAULTHANDLER_USER -#endif - #define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str)) -_Py_IDENTIFIER(enable); -_Py_IDENTIFIER(fileno); -_Py_IDENTIFIER(flush); -_Py_IDENTIFIER(stderr); -#ifdef HAVE_SIGACTION -typedef struct sigaction _Py_sighandler_t; -#else -typedef PyOS_sighandler_t _Py_sighandler_t; +// clang uses __attribute__((no_sanitize("undefined"))) +// GCC 4.9+ uses __attribute__((no_sanitize_undefined)) +#if defined(__has_feature) // Clang +# if __has_feature(undefined_behavior_sanitizer) +# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined"))) +# endif #endif +#if defined(__GNUC__) \ + && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) +# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined)) +#endif +#ifndef _Py_NO_SANITIZE_UNDEFINED +# define _Py_NO_SANITIZE_UNDEFINED +#endif + typedef struct { int signum; @@ -51,60 +53,12 @@ typedef struct { int all_threads; } fault_handler_t; -static struct { - int enabled; - PyObject *file; - int fd; - int all_threads; - PyInterpreterState *interp; -#ifdef MS_WINDOWS - void *exc_handler; -#endif -} fatal_error = {0, NULL, -1, 0}; - -static struct { - PyObject *file; - int fd; - PY_TIMEOUT_T timeout_us; /* timeout in microseconds */ - int repeat; - PyInterpreterState *interp; - int exit; - char *header; - size_t header_len; - /* The main thread always holds this lock. It is only released when - faulthandler_thread() is interrupted before this thread exits, or at - Python exit. */ - PyThread_type_lock cancel_event; - /* released by child thread when joined */ - PyThread_type_lock running; -} thread; +#define fatal_error _PyRuntime.faulthandler.fatal_error +#define thread _PyRuntime.faulthandler.thread #ifdef FAULTHANDLER_USER -typedef struct { - int enabled; - PyObject *file; - int fd; - int all_threads; - int chain; - _Py_sighandler_t previous; - PyInterpreterState *interp; -} user_signal_t; - -static user_signal_t *user_signals; - -/* the following macros come from Python: Modules/signalmodule.c */ -#ifndef NSIG -# if defined(_NSIG) -# define NSIG _NSIG /* For BSD/SysV */ -# elif defined(_SIGMAX) -# define NSIG (_SIGMAX + 1) /* For QNX */ -# elif defined(SIGMAX) -# define NSIG (SIGMAX + 1) /* For djgpp */ -# else -# define NSIG 64 /* Use a reasonable default value */ -# endif -#endif - +#define user_signals _PyRuntime.faulthandler.user_signals +typedef struct faulthandler_user_signal user_signal_t; static void faulthandler_user(int signum); #endif /* FAULTHANDLER_USER */ @@ -125,15 +79,9 @@ static fault_handler_t faulthandler_handlers[] = { static const size_t faulthandler_nsignals = \ Py_ARRAY_LENGTH(faulthandler_handlers); -/* Using an alternative stack requires sigaltstack() - and sigaction() SA_ONSTACK */ -#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) -# define FAULTHANDLER_USE_ALT_STACK -#endif - #ifdef FAULTHANDLER_USE_ALT_STACK -static stack_t stack; -static stack_t old_stack; +# define stack _PyRuntime.faulthandler.stack +# define old_stack _PyRuntime.faulthandler.old_stack #endif @@ -155,7 +103,8 @@ faulthandler_get_fileno(PyObject **file_ptr) PyObject *file = *file_ptr; if (file == NULL || file == Py_None) { - file = _PySys_GetObjectId(&PyId_stderr); + PyThreadState *tstate = _PyThreadState_GET(); + file = _PySys_GetAttr(tstate, &_Py_ID(stderr)); if (file == NULL) { PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr"); return -1; @@ -178,7 +127,7 @@ faulthandler_get_fileno(PyObject **file_ptr) return fd; } - result = _PyObject_CallMethodIdNoArgs(file, &PyId_fileno); + result = PyObject_CallMethodNoArgs(file, &_Py_ID(fileno)); if (result == NULL) return -1; @@ -196,7 +145,7 @@ faulthandler_get_fileno(PyObject **file_ptr) return -1; } - result = _PyObject_CallMethodIdNoArgs(file, &PyId_flush); + result = PyObject_CallMethodNoArgs(file, &_Py_ID(flush)); if (result != NULL) Py_DECREF(result); else { @@ -267,7 +216,7 @@ faulthandler_dump_traceback_py(PyObject *self, int fd; if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "|Oi:dump_traceback", kwlist, + "|Op:dump_traceback", kwlist, &file, &all_threads)) return NULL; @@ -330,14 +279,17 @@ faulthandler_fatal_error(int signum) size_t i; fault_handler_t *handler = NULL; int save_errno = errno; + int found = 0; if (!fatal_error.enabled) return; for (i=0; i < faulthandler_nsignals; i++) { handler = &faulthandler_handlers[i]; - if (handler->signum == signum) + if (handler->signum == signum) { + found = 1; break; + } } if (handler == NULL) { /* faulthandler_nsignals == 0 (unlikely) */ @@ -347,9 +299,18 @@ faulthandler_fatal_error(int signum) /* restore the previous handler */ faulthandler_disable_fatal_handler(handler); - PUTS(fd, "Fatal Python error: "); - PUTS(fd, handler->name); - PUTS(fd, "\n\n"); + if (found) { + PUTS(fd, "Fatal Python error: "); + PUTS(fd, handler->name); + PUTS(fd, "\n\n"); + } + else { + char unknown_signum[23] = {0,}; + snprintf(unknown_signum, 23, "%d", signum); + PUTS(fd, "Fatal Python error from unexpected signum: "); + PUTS(fd, unknown_signum); + PUTS(fd, "\n\n"); + } faulthandler_dump_traceback(fd, fatal_error.all_threads, fatal_error.interp); @@ -531,7 +492,7 @@ faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs) PyThreadState *tstate; if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "|Oi:enable", kwlist, &file, &all_threads)) + "|Op:enable", kwlist, &file, &all_threads)) return NULL; fd = faulthandler_get_fileno(&file); @@ -858,7 +819,7 @@ faulthandler_user(int signum) errno = save_errno; } #else - if (user->chain) { + if (user->chain && user->previous != NULL) { errno = save_errno; /* call the previous signal handler */ user->previous(signum); @@ -878,7 +839,7 @@ check_signum(int signum) return 0; } } - if (signum < 1 || NSIG <= signum) { + if (signum < 1 || Py_NSIG <= signum) { PyErr_SetString(PyExc_ValueError, "signal number out of range"); return 0; } @@ -901,7 +862,7 @@ faulthandler_register_py(PyObject *self, int err; if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "i|Oii:register", kwlist, + "i|Opp:register", kwlist, &signum, &file, &all_threads, &chain)) return NULL; @@ -917,7 +878,7 @@ faulthandler_register_py(PyObject *self, return NULL; if (user_signals == NULL) { - user_signals = PyMem_Calloc(NSIG, sizeof(user_signal_t)); + user_signals = PyMem_Calloc(Py_NSIG, sizeof(user_signal_t)); if (user_signals == NULL) return PyErr_NoMemory(); } @@ -1017,7 +978,7 @@ faulthandler_suppress_crash_report(void) #endif } -static PyObject * +static PyObject* _Py_NO_SANITIZE_UNDEFINED faulthandler_read_null(PyObject *self, PyObject *args) { volatile int *x; @@ -1079,7 +1040,7 @@ faulthandler_fatal_error_thread(void *plock) static PyObject * faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args) { - long thread; + long tid; PyThread_type_lock lock; faulthandler_suppress_crash_report(); @@ -1090,8 +1051,8 @@ faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args) PyThread_acquire_lock(lock, WAIT_LOCK); - thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock); - if (thread == -1) { + tid = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock); + if (tid == -1) { PyThread_free_lock(lock); PyErr_SetString(PyExc_RuntimeError, "unable to start the thread"); return NULL; @@ -1106,17 +1067,20 @@ faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args) Py_RETURN_NONE; } -static PyObject * +static PyObject* _Py_NO_SANITIZE_UNDEFINED faulthandler_sigfpe(PyObject *self, PyObject *args) { + faulthandler_suppress_crash_report(); + /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on PowerPC. Use volatile to disable compile-time optimizations. */ volatile int x = 1, y = 0, z; - faulthandler_suppress_crash_report(); z = x / y; + /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC), raise it manually. */ raise(SIGFPE); + /* This line is never reached, but we pretend to make something with z to silence a compiler warning. */ return PyLong_FromLong(z); @@ -1194,7 +1158,7 @@ faulthandler_traverse(PyObject *module, visitproc visit, void *arg) Py_VISIT(thread.file); #ifdef FAULTHANDLER_USER if (user_signals != NULL) { - for (size_t signum=0; signum < NSIG; signum++) + for (size_t signum=0; signum < Py_NSIG; signum++) Py_VISIT(user_signals[signum].file); } #endif @@ -1220,7 +1184,7 @@ PyDoc_STRVAR(module_doc, static PyMethodDef module_methods[] = { {"enable", - (PyCFunction)(void(*)(void))faulthandler_py_enable, METH_VARARGS|METH_KEYWORDS, + _PyCFunction_CAST(faulthandler_py_enable), METH_VARARGS|METH_KEYWORDS, PyDoc_STR("enable(file=sys.stderr, all_threads=True): " "enable the fault handler")}, {"disable", faulthandler_disable_py, METH_NOARGS, @@ -1228,13 +1192,13 @@ static PyMethodDef module_methods[] = { {"is_enabled", faulthandler_is_enabled, METH_NOARGS, PyDoc_STR("is_enabled()->bool: check if the handler is enabled")}, {"dump_traceback", - (PyCFunction)(void(*)(void))faulthandler_dump_traceback_py, METH_VARARGS|METH_KEYWORDS, + _PyCFunction_CAST(faulthandler_dump_traceback_py), METH_VARARGS|METH_KEYWORDS, PyDoc_STR("dump_traceback(file=sys.stderr, all_threads=True): " "dump the traceback of the current thread, or of all threads " "if all_threads is True, into file")}, {"dump_traceback_later", - (PyCFunction)(void(*)(void))faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n" + _PyCFunction_CAST(faulthandler_dump_traceback_later), METH_VARARGS|METH_KEYWORDS, + PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderr, exit=False):\n" "dump the traceback of all threads in timeout seconds,\n" "or each timeout seconds if repeat is True. If exit is True, " "call _exit(1) which is not safe.")}, @@ -1244,13 +1208,13 @@ static PyMethodDef module_methods[] = { "to dump_traceback_later().")}, #ifdef FAULTHANDLER_USER {"register", - (PyCFunction)(void(*)(void))faulthandler_register_py, METH_VARARGS|METH_KEYWORDS, + _PyCFunction_CAST(faulthandler_register_py), METH_VARARGS|METH_KEYWORDS, PyDoc_STR("register(signum, file=sys.stderr, all_threads=True, chain=False): " "register a handler for the signal 'signum': dump the " "traceback of the current thread, or of all threads if " "all_threads is True, into file")}, {"unregister", - (PyCFunction)(void(*)(void))faulthandler_unregister_py, METH_VARARGS|METH_KEYWORDS, + _PyCFunction_CAST(faulthandler_unregister_py), METH_VARARGS|METH_KEYWORDS, PyDoc_STR("unregister(signum): unregister the handler of the signal " "'signum' registered by register()")}, #endif @@ -1331,13 +1295,13 @@ PyInit_faulthandler(void) static int faulthandler_init_enable(void) { - PyObject *module = PyImport_ImportModule("faulthandler"); - if (module == NULL) { + PyObject *enable = _PyImport_GetModuleAttrString("faulthandler", "enable"); + if (enable == NULL) { return -1; } - PyObject *res = _PyObject_CallMethodIdNoArgs(module, &PyId_enable); - Py_DECREF(module); + PyObject *res = PyObject_CallNoArgs(enable); + Py_DECREF(enable); if (res == NULL) { return -1; } @@ -1357,6 +1321,15 @@ _PyFaulthandler_Init(int enable) signal handler uses more than SIGSTKSZ bytes of stack memory on some platforms. */ stack.ss_size = SIGSTKSZ * 2; +#ifdef AT_MINSIGSTKSZ + /* bpo-46968: Query Linux for minimal stack size to ensure signal delivery + for the hardware running CPython. This OS feature is available in + Linux kernel version >= 5.14 */ + unsigned long at_minstack_size = getauxval(AT_MINSIGSTKSZ); + if (at_minstack_size != 0) { + stack.ss_size = SIGSTKSZ + at_minstack_size; + } +#endif #endif memset(&thread, 0, sizeof(thread)); @@ -1386,7 +1359,7 @@ void _PyFaulthandler_Fini(void) #ifdef FAULTHANDLER_USER /* user */ if (user_signals != NULL) { - for (size_t signum=0; signum < NSIG; signum++) { + for (size_t signum=0; signum < Py_NSIG; signum++) { faulthandler_unregister(&user_signals[signum], signum); } PyMem_Free(user_signals); diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index cdf0f9bf379..9a8ec8dc985 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -8,6 +8,9 @@ #ifdef HAVE_SYS_FILE_H #include #endif +#ifdef HAVE_LINUX_FS_H +#include +#endif #include #include @@ -572,6 +575,12 @@ all_ins(PyObject* m) #ifdef F_GETPIPE_SZ if (PyModule_AddIntMacro(m, F_GETPIPE_SZ)) return -1; #endif +#ifdef FICLONE + if (PyModule_AddIntMacro(m, FICLONE)) return -1; +#endif +#ifdef FICLONERANGE + if (PyModule_AddIntMacro(m, FICLONERANGE)) return -1; +#endif /* OS X specifics */ #ifdef F_FULLFSYNC @@ -581,6 +590,14 @@ all_ins(PyObject* m) if (PyModule_AddIntMacro(m, F_NOCACHE)) return -1; #endif +/* FreeBSD specifics */ +#ifdef F_DUP2FD + if (PyModule_AddIntMacro(m, F_DUP2FD)) return -1; +#endif +#ifdef F_DUP2FD_CLOEXEC + if (PyModule_AddIntMacro(m, F_DUP2FD_CLOEXEC)) return -1; +#endif + /* For F_{GET|SET}FL */ #ifdef FD_CLOEXEC if (PyModule_AddIntMacro(m, FD_CLOEXEC)) return -1; diff --git a/Modules/gc_weakref.txt b/Modules/gc_weakref.txt index 6d07cce1236..f53fb99dd6c 100644 --- a/Modules/gc_weakref.txt +++ b/Modules/gc_weakref.txt @@ -47,7 +47,7 @@ soon as we execute Python code, threads other than the gc thread can run too, and they can do ordinary things with weakrefs that end up resurrecting CT while gc is running. - https://www.python.org/sf/1055820 + https://bugs.python.org/issue1055820 shows how innocent it can be, and also how nasty. Variants of the three focused test cases attached to that bug report are now part of Python's diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 7d1a45bcaea..6630faa6f44 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -69,10 +69,10 @@ module gc #define NEXT_MASK_UNREACHABLE (1) /* Get an object's GC head */ -#define AS_GC(o) ((PyGC_Head *)(o)-1) +#define AS_GC(o) ((PyGC_Head *)(((char *)(o))-sizeof(PyGC_Head))) /* Get the object given the GC head */ -#define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g)+1)) +#define FROM_GC(g) ((PyObject *)(((char *)(g))+sizeof(PyGC_Head))) static inline int gc_is_collecting(PyGC_Head *g) @@ -139,24 +139,20 @@ get_gc_state(void) void _PyGC_InitState(GCState *gcstate) { - gcstate->enabled = 1; /* automatic collection enabled? */ +#define INIT_HEAD(GEN) \ + do { \ + GEN.head._gc_next = (uintptr_t)&GEN.head; \ + GEN.head._gc_prev = (uintptr_t)&GEN.head; \ + } while (0) -#define _GEN_HEAD(n) GEN_HEAD(gcstate, n) - struct gc_generation generations[NUM_GENERATIONS] = { - /* PyGC_Head, threshold, count */ - {{(uintptr_t)_GEN_HEAD(0), (uintptr_t)_GEN_HEAD(0)}, 700, 0}, - {{(uintptr_t)_GEN_HEAD(1), (uintptr_t)_GEN_HEAD(1)}, 10, 0}, - {{(uintptr_t)_GEN_HEAD(2), (uintptr_t)_GEN_HEAD(2)}, 10, 0}, - }; for (int i = 0; i < NUM_GENERATIONS; i++) { - gcstate->generations[i] = generations[i]; + assert(gcstate->generations[i].count == 0); + INIT_HEAD(gcstate->generations[i]); }; gcstate->generation0 = GEN_HEAD(gcstate, 0); - struct gc_generation permanent_generation = { - {(uintptr_t)&gcstate->permanent_generation.head, - (uintptr_t)&gcstate->permanent_generation.head}, 0, 0 - }; - gcstate->permanent_generation = permanent_generation; + INIT_HEAD(gcstate->permanent_generation); + +#undef INIT_HEAD } @@ -795,12 +791,15 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) _PyWeakref_ClearRef((PyWeakReference *)op); } - if (! PyType_SUPPORTS_WEAKREFS(Py_TYPE(op))) + if (! _PyType_SUPPORTS_WEAKREFS(Py_TYPE(op))) continue; - /* It supports weakrefs. Does it have any? */ - wrlist = (PyWeakReference **) - _PyObject_GET_WEAKREFS_LISTPTR(op); + /* It supports weakrefs. Does it have any? + * + * This is never triggered for static types so we can avoid the + * (slightly) more costly _PyObject_GET_WEAKREFS_LISTPTR(). + */ + wrlist = _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(op); /* `op` may have some weakrefs. March over the list, clear * all the weakrefs, and move the weakrefs with callbacks @@ -1038,7 +1037,6 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate, static void clear_freelists(PyInterpreterState *interp) { - _PyFrame_ClearFreeList(interp); _PyTuple_ClearFreeList(interp); _PyFloat_ClearFreeList(interp); _PyList_ClearFreeList(interp); @@ -1200,14 +1198,6 @@ gc_collect_main(PyThreadState *tstate, int generation, assert(gcstate->garbage != NULL); assert(!_PyErr_Occurred(tstate)); -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - if (tstate->interp->config._isolated_interpreter) { - // bpo-40533: The garbage collector must not be run on parallel on - // Python objects shared by multiple interpreters. - return 0; - } -#endif - if (gcstate->debug & DEBUG_STATS) { PySys_WriteStderr("gc: collecting generation %d...\n", generation); show_stats_each_generations(gcstate); @@ -1880,8 +1870,7 @@ gc_is_tracked(PyObject *module, PyObject *obj) result = Py_True; else result = Py_False; - Py_INCREF(result); - return result; + return Py_NewRef(result); } /*[clinic input] @@ -2162,12 +2151,42 @@ _PyGC_DumpShutdownStats(PyInterpreterState *interp) } } + +static void +gc_fini_untrack(PyGC_Head *list) +{ + PyGC_Head *gc; + for (gc = GC_NEXT(list); gc != list; gc = GC_NEXT(list)) { + PyObject *op = FROM_GC(gc); + _PyObject_GC_UNTRACK(op); + // gh-92036: If a deallocator function expect the object to be tracked + // by the GC (ex: func_dealloc()), it can crash if called on an object + // which is no longer tracked by the GC. Leak one strong reference on + // purpose so the object is never deleted and its deallocator is not + // called. + Py_INCREF(op); + } +} + + void _PyGC_Fini(PyInterpreterState *interp) { GCState *gcstate = &interp->gc; Py_CLEAR(gcstate->garbage); Py_CLEAR(gcstate->callbacks); + + if (!_Py_IsMainInterpreter(interp)) { + // bpo-46070: Explicitly untrack all objects currently tracked by the + // GC. Otherwise, if an object is used later by another interpreter, + // calling PyObject_GC_UnTrack() on the object crashs if the previous + // or the next object of the PyGC_Head structure became a dangling + // pointer. + for (int i = 0; i < NUM_GENERATIONS; i++) { + PyGC_Head *gen = GEN_HEAD(gcstate, i); + gc_fini_untrack(gen); + } + } } /* for debugging */ @@ -2232,28 +2251,28 @@ PyObject_IS_GC(PyObject *obj) return _PyObject_IS_GC(obj); } -static PyObject * -_PyObject_GC_Alloc(int use_calloc, size_t basicsize) +void +_Py_ScheduleGC(PyInterpreterState *interp) { + GCState *gcstate = &interp->gc; + if (gcstate->collecting == 1) { + return; + } + struct _ceval_state *ceval = &interp->ceval; + if (!_Py_atomic_load_relaxed(&ceval->gc_scheduled)) { + _Py_atomic_store_relaxed(&ceval->gc_scheduled, 1); + _Py_atomic_store_relaxed(&ceval->eval_breaker, 1); + } +} + +void +_PyObject_GC_Link(PyObject *op) +{ + PyGC_Head *g = AS_GC(op); + assert(((uintptr_t)g & (sizeof(uintptr_t)-1)) == 0); // g must be correctly aligned + PyThreadState *tstate = _PyThreadState_GET(); GCState *gcstate = &tstate->interp->gc; - if (basicsize > PY_SSIZE_T_MAX - sizeof(PyGC_Head)) { - return _PyErr_NoMemory(tstate); - } - size_t size = sizeof(PyGC_Head) + basicsize; - - PyGC_Head *g; - if (use_calloc) { - g = (PyGC_Head *)PyObject_Calloc(1, size); - } - else { - g = (PyGC_Head *)PyObject_Malloc(size); - } - if (g == NULL) { - return _PyErr_NoMemory(tstate); - } - assert(((uintptr_t)g & 3) == 0); // g must be aligned 4bytes boundary - g->_gc_next = 0; g->_gc_prev = 0; gcstate->generations[0].count++; /* number of allocated GC objects */ @@ -2263,30 +2282,43 @@ _PyObject_GC_Alloc(int use_calloc, size_t basicsize) !gcstate->collecting && !_PyErr_Occurred(tstate)) { - gcstate->collecting = 1; - gc_collect_generations(tstate); - gcstate->collecting = 0; + _Py_ScheduleGC(tstate->interp); } - PyObject *op = FROM_GC(g); +} + +void +_Py_RunGC(PyThreadState *tstate) +{ + GCState *gcstate = &tstate->interp->gc; + gcstate->collecting = 1; + gc_collect_generations(tstate); + gcstate->collecting = 0; +} + +static PyObject * +gc_alloc(size_t basicsize, size_t presize) +{ + PyThreadState *tstate = _PyThreadState_GET(); + if (basicsize > PY_SSIZE_T_MAX - presize) { + return _PyErr_NoMemory(tstate); + } + size_t size = presize + basicsize; + char *mem = PyObject_Malloc(size); + if (mem == NULL) { + return _PyErr_NoMemory(tstate); + } + ((PyObject **)mem)[0] = NULL; + ((PyObject **)mem)[1] = NULL; + PyObject *op = (PyObject *)(mem + presize); + _PyObject_GC_Link(op); return op; } -PyObject * -_PyObject_GC_Malloc(size_t basicsize) -{ - return _PyObject_GC_Alloc(0, basicsize); -} - -PyObject * -_PyObject_GC_Calloc(size_t basicsize) -{ - return _PyObject_GC_Alloc(1, basicsize); -} - PyObject * _PyObject_GC_New(PyTypeObject *tp) { - PyObject *op = _PyObject_GC_Malloc(_PyObject_SIZE(tp)); + size_t presize = _PyType_PreHeaderSize(tp); + PyObject *op = gc_alloc(_PyObject_SIZE(tp), presize); if (op == NULL) { return NULL; } @@ -2297,15 +2329,15 @@ _PyObject_GC_New(PyTypeObject *tp) PyVarObject * _PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems) { - size_t size; PyVarObject *op; if (nitems < 0) { PyErr_BadInternalCall(); return NULL; } - size = _PyObject_VAR_SIZE(tp, nitems); - op = (PyVarObject *) _PyObject_GC_Malloc(size); + size_t presize = _PyType_PreHeaderSize(tp); + size_t size = _PyObject_VAR_SIZE(tp, nitems); + op = (PyVarObject *)gc_alloc(size, presize); if (op == NULL) { return NULL; } @@ -2318,7 +2350,7 @@ _PyObject_GC_Resize(PyVarObject *op, Py_ssize_t nitems) { const size_t basicsize = _PyObject_VAR_SIZE(Py_TYPE(op), nitems); _PyObject_ASSERT((PyObject *)op, !_PyObject_GC_IS_TRACKED(op)); - if (basicsize > PY_SSIZE_T_MAX - sizeof(PyGC_Head)) { + if (basicsize > (size_t)PY_SSIZE_T_MAX - sizeof(PyGC_Head)) { return (PyVarObject *)PyErr_NoMemory(); } @@ -2334,15 +2366,23 @@ _PyObject_GC_Resize(PyVarObject *op, Py_ssize_t nitems) void PyObject_GC_Del(void *op) { + size_t presize = _PyType_PreHeaderSize(((PyObject *)op)->ob_type); PyGC_Head *g = AS_GC(op); if (_PyObject_GC_IS_TRACKED(op)) { +#ifdef Py_DEBUG + if (PyErr_WarnExplicitFormat(PyExc_ResourceWarning, "gc", 0, + "gc", NULL, "Object of type %s is not untracked before destruction", + ((PyObject*)op)->ob_type->tp_name)) { + PyErr_WriteUnraisable(NULL); + } +#endif gc_list_remove(g); } GCState *gcstate = get_gc_state(); if (gcstate->generations[0].count > 0) { gcstate->generations[0].count--; } - PyObject_Free(g); + PyObject_Free(((char *)op)-presize); } int diff --git a/Modules/getaddrinfo.c b/Modules/getaddrinfo.c index 5aaa6e7c814..0b4620ed683 100644 --- a/Modules/getaddrinfo.c +++ b/Modules/getaddrinfo.c @@ -61,6 +61,9 @@ # define FAITH #endif +#ifdef HAVE_NETDB_H +#define HAVE_GETADDRINFO 1 + #define SUCCESS 0 #define GAI_ANY 0 #define YES 1 @@ -636,3 +639,5 @@ get_addr(hostname, af, res, pai, port0) *res = NULL; return error; } + +#endif // HAVE_NETDB_H diff --git a/Modules/getbuildinfo.c b/Modules/getbuildinfo.c index 7cb7397a22c..a24750b76c0 100644 --- a/Modules/getbuildinfo.c +++ b/Modules/getbuildinfo.c @@ -31,12 +31,18 @@ #define GITBRANCH "" #endif +static int initialized = 0; +static char buildinfo[50 + sizeof(GITVERSION) + + ((sizeof(GITTAG) > sizeof(GITBRANCH)) ? + sizeof(GITTAG) : sizeof(GITBRANCH))]; + const char * Py_GetBuildInfo(void) { - static char buildinfo[50 + sizeof(GITVERSION) + - ((sizeof(GITTAG) > sizeof(GITBRANCH)) ? - sizeof(GITTAG) : sizeof(GITBRANCH))]; + if (initialized) { + return buildinfo; + } + initialized = 1; const char *revision = _Py_gitversion(); const char *sep = *revision ? ":" : ""; const char *gitid = _Py_gitidentifier(); diff --git a/Modules/getnameinfo.c b/Modules/getnameinfo.c index f014c11ae15..335021f79ba 100644 --- a/Modules/getnameinfo.c +++ b/Modules/getnameinfo.c @@ -48,6 +48,9 @@ #include "addrinfo.h" #endif +#ifdef HAVE_NETDB_H +#define HAVE_GETNAMEINFO 1 + #define SUCCESS 0 #define YES 1 #define NO 0 @@ -104,8 +107,8 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) u_long v4a; #ifdef ENABLE_IPV6 u_char pfx; -#endif int h_error; +#endif char numserv[512]; char numaddr[512]; @@ -181,7 +184,6 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) hp = getipnodebyaddr(addr, gni_afd->a_addrlen, gni_afd->a_af, &h_error); #else hp = gethostbyaddr(addr, gni_afd->a_addrlen, gni_afd->a_af); - h_error = h_errno; #endif if (hp) { @@ -212,3 +214,4 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) } return SUCCESS; } +#endif // HAVE_NETDB_H diff --git a/Modules/getpath.c b/Modules/getpath.c index 4dbd502ddcf..13db010649f 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -1,1617 +1,947 @@ /* Return the initial module search path. */ #include "Python.h" -#include "pycore_fileutils.h" -#include "pycore_initconfig.h" -#include "pycore_pathconfig.h" +#include "marshal.h" // PyMarshal_ReadObjectFromString #include "osdefs.h" // DELIM +#include "pycore_initconfig.h" +#include "pycore_fileutils.h" +#include "pycore_pathconfig.h" +#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() +#include -#include // getenv() -#include -#include +#ifdef MS_WINDOWS +# include // GetFullPathNameW(), MAX_PATH +# include +#endif #ifdef __APPLE__ # include #endif -/* Search in some common locations for the associated Python libraries. - * - * Two directories must be found, the platform independent directory - * (prefix), containing the common .py and .pyc files, and the platform - * dependent directory (exec_prefix), containing the shared library - * modules. Note that prefix and exec_prefix can be the same directory, - * but for some installations, they are different. - * - * Py_GetPath() carries out separate searches for prefix and exec_prefix. - * Each search tries a number of different locations until a ``landmark'' - * file or directory is found. If no prefix or exec_prefix is found, a - * warning message is issued and the preprocessor defined PREFIX and - * EXEC_PREFIX are used (even though they will not work); python carries on - * as best as is possible, but most imports will fail. - * - * Before any searches are done, the location of the executable is - * determined. If argv[0] has one or more slashes in it, it is used - * unchanged. Otherwise, it must have been invoked from the shell's path, - * so we search $PATH for the named executable and use that. If the - * executable was not found on $PATH (or there was no $PATH environment - * variable), the original argv[0] string is used. - * - * Next, the executable location is examined to see if it is a symbolic - * link. If so, the link is chased (correctly interpreting a relative - * pathname if one is found) and the directory of the link target is used. - * - * Finally, argv0_path is set to the directory containing the executable - * (i.e. the last component is stripped). - * - * With argv0_path in hand, we perform a number of steps. The same steps - * are performed for prefix and for exec_prefix, but with a different - * landmark. - * - * Step 1. Are we running python out of the build directory? This is - * checked by looking for a different kind of landmark relative to - * argv0_path. For prefix, the landmark's path is derived from the VPATH - * preprocessor variable (taking into account that its value is almost, but - * not quite, what we need). For exec_prefix, the landmark is - * pybuilddir.txt. If the landmark is found, we're done. - * - * For the remaining steps, the prefix landmark will always be - * lib/python$VERSION/os.py and the exec_prefix will always be - * lib/python$VERSION/lib-dynload, where $VERSION is Python's version - * number as supplied by the Makefile. Note that this means that no more - * build directory checking is performed; if the first step did not find - * the landmarks, the assumption is that python is running from an - * installed setup. - * - * Step 2. See if the $PYTHONHOME environment variable points to the - * installed location of the Python libraries. If $PYTHONHOME is set, then - * it points to prefix and exec_prefix. $PYTHONHOME can be a single - * directory, which is used for both, or the prefix and exec_prefix - * directories separated by a colon. - * - * Step 3. Try to find prefix and exec_prefix relative to argv0_path, - * backtracking up the path until it is exhausted. This is the most common - * step to succeed. Note that if prefix and exec_prefix are different, - * exec_prefix is more likely to be found; however if exec_prefix is a - * subdirectory of prefix, both will be found. - * - * Step 4. Search the directories pointed to by the preprocessor variables - * PREFIX and EXEC_PREFIX. These are supplied by the Makefile but can be - * passed in as options to the configure script. - * - * That's it! - * - * Well, almost. Once we have determined prefix and exec_prefix, the - * preprocessor variable PYTHONPATH is used to construct a path. Each - * relative path on PYTHONPATH is prefixed with prefix. Then the directory - * containing the shared library modules is appended. The environment - * variable $PYTHONPATH is inserted in front of it all. Finally, the - * prefix and exec_prefix globals are tweaked so they reflect the values - * expected by other code, by stripping the "lib/python$VERSION/..." stuff - * off. If either points to the build directory, the globals are reset to - * the corresponding preprocessor variables (so sys.prefix will reflect the - * installation location, even though sys.path points into the build - * directory). This seems to make more sense given that currently the only - * known use of sys.prefix and sys.exec_prefix is for the ILU installation - * process to find the installed Python tree. - * - * An embedding application can use Py_SetPath() to override all of - * these automatic path computations. - * - * NOTE: Windows MSVC builds use PC/getpathp.c instead! - */ - -#ifdef __cplusplus -extern "C" { -#endif - +/* Reference the precompiled getpath.py */ +#include "../Python/frozen_modules/getpath.h" #if (!defined(PREFIX) || !defined(EXEC_PREFIX) \ - || !defined(VERSION) || !defined(VPATH)) -#error "PREFIX, EXEC_PREFIX, VERSION and VPATH macros must be defined" + || !defined(VERSION) || !defined(VPATH) \ + || !defined(PLATLIBDIR)) +#error "PREFIX, EXEC_PREFIX, VERSION, VPATH and PLATLIBDIR macros must be defined" #endif -#ifndef LANDMARK -#define LANDMARK L"os.py" +#if !defined(PYTHONPATH) +#define PYTHONPATH NULL #endif -#define BUILD_LANDMARK L"Modules/Setup.local" +#if !defined(PYDEBUGEXT) +#define PYDEBUGEXT NULL +#endif -#define PATHLEN_ERR() _PyStatus_ERR("path configuration: path too long") +#if !defined(PYWINVER) +#ifdef MS_DLL_ID +#define PYWINVER MS_DLL_ID +#else +#define PYWINVER NULL +#endif +#endif -typedef struct { - wchar_t *path_env; /* PATH environment variable */ - - wchar_t *pythonpath_macro; /* PYTHONPATH macro */ - wchar_t *prefix_macro; /* PREFIX macro */ - wchar_t *exec_prefix_macro; /* EXEC_PREFIX macro */ - wchar_t *vpath_macro; /* VPATH macro */ - - wchar_t *lib_python; /* / "pythonX.Y" */ - - int prefix_found; /* found platform independent libraries? */ - int exec_prefix_found; /* found the platform dependent libraries? */ - - int warnings; - const wchar_t *pythonpath_env; - const wchar_t *platlibdir; - - wchar_t *argv0_path; - wchar_t *zip_path; - wchar_t *prefix; - wchar_t *exec_prefix; -} PyCalculatePath; - -static const wchar_t delimiter[2] = {DELIM, '\0'}; -static const wchar_t separator[2] = {SEP, '\0'}; +#if !defined(EXE_SUFFIX) +#if defined(MS_WINDOWS) || defined(__CYGWIN__) || defined(__MINGW32__) +#define EXE_SUFFIX L".exe" +#else +#define EXE_SUFFIX NULL +#endif +#endif -static void -reduce(wchar_t *dir) +/* HELPER FUNCTIONS for getpath.py */ + +static PyObject * +getpath_abspath(PyObject *Py_UNUSED(self), PyObject *args) { - size_t i = wcslen(dir); - while (i > 0 && dir[i] != SEP) { - --i; + PyObject *r = NULL; + PyObject *pathobj; + wchar_t *path; + if (!PyArg_ParseTuple(args, "U", &pathobj)) { + return NULL; } - dir[i] = '\0'; -} - - -/* Is file, not directory */ -static int -isfile(const wchar_t *filename) -{ - struct stat buf; - if (_Py_wstat(filename, &buf) != 0) { - return 0; - } - if (!S_ISREG(buf.st_mode)) { - return 0; - } - return 1; -} - - -/* Is executable file */ -static int -isxfile(const wchar_t *filename) -{ - struct stat buf; - if (_Py_wstat(filename, &buf) != 0) { - return 0; - } - if (!S_ISREG(buf.st_mode)) { - return 0; - } - if ((buf.st_mode & 0111) == 0) { - return 0; - } - return 1; -} - - -/* Is directory */ -static int -isdir(const wchar_t *filename) -{ - struct stat buf; - if (_Py_wstat(filename, &buf) != 0) { - return 0; - } - if (!S_ISDIR(buf.st_mode)) { - return 0; - } - return 1; -} - - -/* Add a path component, by appending stuff to buffer. - buflen: 'buffer' length in characters including trailing NUL. - - If path2 is empty: - - - if path doesn't end with SEP and is not empty, add SEP to path - - otherwise, do nothing. */ -static PyStatus -joinpath(wchar_t *path, const wchar_t *path2, size_t path_len) -{ - if (_Py_isabs(path2)) { - if (wcslen(path2) >= path_len) { - return PATHLEN_ERR(); + Py_ssize_t len; + path = PyUnicode_AsWideCharString(pathobj, &len); + if (path) { + wchar_t *abs; + if (_Py_abspath((const wchar_t *)_Py_normpath(path, -1), &abs) == 0 && abs) { + r = PyUnicode_FromWideChar(abs, -1); + PyMem_RawFree((void *)abs); + } else { + PyErr_SetString(PyExc_OSError, "failed to make path absolute"); } - wcscpy(path, path2); + PyMem_Free((void *)path); } - else { - if (_Py_add_relfile(path, path2, path_len) < 0) { - return PATHLEN_ERR(); - } - return _PyStatus_OK(); - } - return _PyStatus_OK(); + return r; } -static wchar_t* -substring(const wchar_t *str, size_t len) +static PyObject * +getpath_basename(PyObject *Py_UNUSED(self), PyObject *args) { - wchar_t *substr = PyMem_RawMalloc((len + 1) * sizeof(wchar_t)); - if (substr == NULL) { + PyObject *path; + if (!PyArg_ParseTuple(args, "U", &path)) { + return NULL; + } + Py_ssize_t end = PyUnicode_GET_LENGTH(path); + Py_ssize_t pos = PyUnicode_FindChar(path, SEP, 0, end, -1); + if (pos < 0) { + return Py_NewRef(path); + } + return PyUnicode_Substring(path, pos + 1, end); +} + + +static PyObject * +getpath_dirname(PyObject *Py_UNUSED(self), PyObject *args) +{ + PyObject *path; + if (!PyArg_ParseTuple(args, "U", &path)) { + return NULL; + } + Py_ssize_t end = PyUnicode_GET_LENGTH(path); + Py_ssize_t pos = PyUnicode_FindChar(path, SEP, 0, end, -1); + if (pos < 0) { + return PyUnicode_FromStringAndSize(NULL, 0); + } + return PyUnicode_Substring(path, 0, pos); +} + + +static PyObject * +getpath_isabs(PyObject *Py_UNUSED(self), PyObject *args) +{ + PyObject *r = NULL; + PyObject *pathobj; + const wchar_t *path; + if (!PyArg_ParseTuple(args, "U", &pathobj)) { + return NULL; + } + path = PyUnicode_AsWideCharString(pathobj, NULL); + if (path) { + r = _Py_isabs(path) ? Py_True : Py_False; + PyMem_Free((void *)path); + } + return Py_XNewRef(r); +} + + +static PyObject * +getpath_hassuffix(PyObject *Py_UNUSED(self), PyObject *args) +{ + PyObject *r = NULL; + PyObject *pathobj; + PyObject *suffixobj; + const wchar_t *path; + const wchar_t *suffix; + if (!PyArg_ParseTuple(args, "UU", &pathobj, &suffixobj)) { + return NULL; + } + Py_ssize_t len, suffixLen; + path = PyUnicode_AsWideCharString(pathobj, &len); + if (path) { + suffix = PyUnicode_AsWideCharString(suffixobj, &suffixLen); + if (suffix) { + if (suffixLen > len || +#ifdef MS_WINDOWS + wcsicmp(&path[len - suffixLen], suffix) != 0 +#else + wcscmp(&path[len - suffixLen], suffix) != 0 +#endif + ) { + r = Py_NewRef(Py_False); + } else { + r = Py_NewRef(Py_True); + } + PyMem_Free((void *)suffix); + } + PyMem_Free((void *)path); + } + return r; +} + + +static PyObject * +getpath_isdir(PyObject *Py_UNUSED(self), PyObject *args) +{ + PyObject *r = NULL; + PyObject *pathobj; + const wchar_t *path; + if (!PyArg_ParseTuple(args, "U", &pathobj)) { + return NULL; + } + path = PyUnicode_AsWideCharString(pathobj, NULL); + if (path) { +#ifdef MS_WINDOWS + DWORD attr = GetFileAttributesW(path); + r = (attr != INVALID_FILE_ATTRIBUTES) && + (attr & FILE_ATTRIBUTE_DIRECTORY) ? Py_True : Py_False; +#else + struct stat st; + r = (_Py_wstat(path, &st) == 0) && S_ISDIR(st.st_mode) ? Py_True : Py_False; +#endif + PyMem_Free((void *)path); + } + return Py_XNewRef(r); +} + + +static PyObject * +getpath_isfile(PyObject *Py_UNUSED(self), PyObject *args) +{ + PyObject *r = NULL; + PyObject *pathobj; + const wchar_t *path; + if (!PyArg_ParseTuple(args, "U", &pathobj)) { + return NULL; + } + path = PyUnicode_AsWideCharString(pathobj, NULL); + if (path) { +#ifdef MS_WINDOWS + DWORD attr = GetFileAttributesW(path); + r = (attr != INVALID_FILE_ATTRIBUTES) && + !(attr & FILE_ATTRIBUTE_DIRECTORY) ? Py_True : Py_False; +#else + struct stat st; + r = (_Py_wstat(path, &st) == 0) && S_ISREG(st.st_mode) ? Py_True : Py_False; +#endif + PyMem_Free((void *)path); + } + return Py_XNewRef(r); +} + + +static PyObject * +getpath_isxfile(PyObject *Py_UNUSED(self), PyObject *args) +{ + PyObject *r = NULL; + PyObject *pathobj; + const wchar_t *path; + Py_ssize_t cchPath; + if (!PyArg_ParseTuple(args, "U", &pathobj)) { + return NULL; + } + path = PyUnicode_AsWideCharString(pathobj, &cchPath); + if (path) { +#ifdef MS_WINDOWS + const wchar_t *ext; + DWORD attr = GetFileAttributesW(path); + r = (attr != INVALID_FILE_ATTRIBUTES) && + !(attr & FILE_ATTRIBUTE_DIRECTORY) && + SUCCEEDED(PathCchFindExtension(path, cchPath + 1, &ext)) && + (CompareStringOrdinal(ext, -1, L".exe", -1, 1 /* ignore case */) == CSTR_EQUAL) + ? Py_True : Py_False; +#else + struct stat st; + r = (_Py_wstat(path, &st) == 0) && + S_ISREG(st.st_mode) && + (st.st_mode & 0111) + ? Py_True : Py_False; +#endif + PyMem_Free((void *)path); + } + return Py_XNewRef(r); +} + + +static PyObject * +getpath_joinpath(PyObject *Py_UNUSED(self), PyObject *args) +{ + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_TypeError, "requires tuple of arguments"); + return NULL; + } + Py_ssize_t n = PyTuple_GET_SIZE(args); + if (n == 0) { + return PyUnicode_FromStringAndSize(NULL, 0); + } + /* Convert all parts to wchar and accumulate max final length */ + wchar_t **parts = (wchar_t **)PyMem_Malloc(n * sizeof(wchar_t *)); + memset(parts, 0, n * sizeof(wchar_t *)); + Py_ssize_t cchFinal = 0; + Py_ssize_t first = 0; + + for (Py_ssize_t i = 0; i < n; ++i) { + PyObject *s = PyTuple_GET_ITEM(args, i); + Py_ssize_t cch; + if (s == Py_None) { + cch = 0; + } else if (PyUnicode_Check(s)) { + parts[i] = PyUnicode_AsWideCharString(s, &cch); + if (!parts[i]) { + cchFinal = -1; + break; + } + if (_Py_isabs(parts[i])) { + first = i; + } + } else { + PyErr_SetString(PyExc_TypeError, "all arguments to joinpath() must be str or None"); + cchFinal = -1; + break; + } + cchFinal += cch + 1; + } + + wchar_t *final = cchFinal > 0 ? (wchar_t *)PyMem_Malloc(cchFinal * sizeof(wchar_t)) : NULL; + if (!final) { + for (Py_ssize_t i = 0; i < n; ++i) { + PyMem_Free(parts[i]); + } + PyMem_Free(parts); + if (cchFinal) { + PyErr_NoMemory(); + return NULL; + } + return PyUnicode_FromStringAndSize(NULL, 0); + } + + final[0] = '\0'; + /* Now join all the paths. The final result should be shorter than the buffer */ + for (Py_ssize_t i = 0; i < n; ++i) { + if (!parts[i]) { + continue; + } + if (i >= first && final) { + if (!final[0]) { + /* final is definitely long enough to fit any individual part */ + wcscpy(final, parts[i]); + } else if (_Py_add_relfile(final, parts[i], cchFinal) < 0) { + /* if we fail, keep iterating to free memory, but stop adding parts */ + PyMem_Free(final); + final = NULL; + } + } + PyMem_Free(parts[i]); + } + PyMem_Free(parts); + if (!final) { + PyErr_SetString(PyExc_SystemError, "failed to join paths"); + return NULL; + } + PyObject *r = PyUnicode_FromWideChar(_Py_normpath(final, -1), -1); + PyMem_Free(final); + return r; +} + + +static PyObject * +getpath_readlines(PyObject *Py_UNUSED(self), PyObject *args) +{ + PyObject *r = NULL; + PyObject *pathobj; + const wchar_t *path; + if (!PyArg_ParseTuple(args, "U", &pathobj)) { + return NULL; + } + path = PyUnicode_AsWideCharString(pathobj, NULL); + if (!path) { + return NULL; + } + FILE *fp = _Py_wfopen(path, L"rb"); + PyMem_Free((void *)path); + if (!fp) { + PyErr_SetFromErrno(PyExc_OSError); return NULL; } - if (len) { - memcpy(substr, str, len * sizeof(wchar_t)); + r = PyList_New(0); + if (!r) { + fclose(fp); + return NULL; } - substr[len] = L'\0'; - return substr; -} - - -static wchar_t* -joinpath2(const wchar_t *path, const wchar_t *path2) -{ - if (_Py_isabs(path2)) { - return _PyMem_RawWcsdup(path2); - } - return _Py_join_relfile(path, path2); -} - - -static inline int -safe_wcscpy(wchar_t *dst, const wchar_t *src, size_t n) -{ - size_t srclen = wcslen(src); - if (n <= srclen) { - dst[0] = L'\0'; - return -1; - } - memcpy(dst, src, (srclen + 1) * sizeof(wchar_t)); - return 0; -} - - -/* copy_absolute requires that path be allocated at least - 'abs_path_len' characters (including trailing NUL). */ -static PyStatus -copy_absolute(wchar_t *abs_path, const wchar_t *path, size_t abs_path_len) -{ - if (_Py_isabs(path)) { - if (safe_wcscpy(abs_path, path, abs_path_len) < 0) { - return PATHLEN_ERR(); - } - } - else { - if (!_Py_wgetcwd(abs_path, abs_path_len)) { - /* unable to get the current directory */ - if (safe_wcscpy(abs_path, path, abs_path_len) < 0) { - return PATHLEN_ERR(); - } - return _PyStatus_OK(); - } - if (path[0] == '.' && path[1] == SEP) { - path += 2; - } - PyStatus status = joinpath(abs_path, path, abs_path_len); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - return _PyStatus_OK(); -} - - -/* path_len: path length in characters including trailing NUL */ -static PyStatus -absolutize(wchar_t **path_p) -{ - assert(!_Py_isabs(*path_p)); - - wchar_t abs_path[MAXPATHLEN+1]; - wchar_t *path = *path_p; - - PyStatus status = copy_absolute(abs_path, path, Py_ARRAY_LENGTH(abs_path)); - if (_PyStatus_EXCEPTION(status)) { - return status; + const size_t MAX_FILE = 32 * 1024; + char *buffer = (char *)PyMem_Malloc(MAX_FILE); + if (!buffer) { + Py_DECREF(r); + fclose(fp); + return NULL; } - PyMem_RawFree(*path_p); - *path_p = _PyMem_RawWcsdup(abs_path); - if (*path_p == NULL) { - return _PyStatus_NO_MEMORY(); - } - return _PyStatus_OK(); -} - - -/* Is module -- check for .pyc too */ -static PyStatus -ismodule(const wchar_t *path, int *result) -{ - wchar_t *filename = joinpath2(path, LANDMARK); - if (filename == NULL) { - return _PyStatus_NO_MEMORY(); - } - - if (isfile(filename)) { - PyMem_RawFree(filename); - *result = 1; - return _PyStatus_OK(); - } - - /* Check for the compiled version of prefix. */ - size_t len = wcslen(filename); - wchar_t *pyc = PyMem_RawMalloc((len + 2) * sizeof(wchar_t)); - if (pyc == NULL) { - PyMem_RawFree(filename); - return _PyStatus_NO_MEMORY(); - } - - memcpy(pyc, filename, len * sizeof(wchar_t)); - pyc[len] = L'c'; - pyc[len + 1] = L'\0'; - *result = isfile(pyc); - - PyMem_RawFree(filename); - PyMem_RawFree(pyc); - - return _PyStatus_OK(); -} - - -#if defined(__CYGWIN__) || defined(__MINGW32__) -#ifndef EXE_SUFFIX -#define EXE_SUFFIX L".exe" -#endif - -/* pathlen: 'path' length in characters including trailing NUL */ -static PyStatus -add_exe_suffix(wchar_t **progpath_p) -{ - wchar_t *progpath = *progpath_p; - - /* Check for already have an executable suffix */ - size_t n = wcslen(progpath); - size_t s = wcslen(EXE_SUFFIX); - if (wcsncasecmp(EXE_SUFFIX, progpath + n - s, s) == 0) { - return _PyStatus_OK(); - } - - wchar_t *progpath2 = PyMem_RawMalloc((n + s + 1) * sizeof(wchar_t)); - if (progpath2 == NULL) { - return _PyStatus_NO_MEMORY(); - } - - memcpy(progpath2, progpath, n * sizeof(wchar_t)); - memcpy(progpath2 + n, EXE_SUFFIX, s * sizeof(wchar_t)); - progpath2[n+s] = L'\0'; - - if (isxfile(progpath2)) { - PyMem_RawFree(*progpath_p); - *progpath_p = progpath2; - } - else { - PyMem_RawFree(progpath2); - } - return _PyStatus_OK(); -} -#endif - - -/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN - bytes long. -*/ -static PyStatus -search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, - wchar_t *prefix, size_t prefix_len, int *found) -{ - PyStatus status; - - /* If PYTHONHOME is set, we believe it unconditionally */ - if (pathconfig->home) { - /* Path: / */ - if (safe_wcscpy(prefix, pathconfig->home, prefix_len) < 0) { - return PATHLEN_ERR(); - } - wchar_t *delim = wcschr(prefix, DELIM); - if (delim) { - *delim = L'\0'; - } - status = joinpath(prefix, calculate->lib_python, prefix_len); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - *found = 1; - return _PyStatus_OK(); - } - - /* Check to see if argv0_path is in the build directory - - Path: / */ - wchar_t *path = joinpath2(calculate->argv0_path, BUILD_LANDMARK); - if (path == NULL) { - return _PyStatus_NO_MEMORY(); - } - - int is_build_dir = isfile(path); - PyMem_RawFree(path); - - if (is_build_dir) { - /* argv0_path is the build directory (BUILD_LANDMARK exists), - now also check LANDMARK using ismodule(). */ - - /* Path: / / Lib */ - /* or if VPATH is empty: / Lib */ - if (safe_wcscpy(prefix, calculate->argv0_path, prefix_len) < 0) { - return PATHLEN_ERR(); - } - - status = joinpath(prefix, calculate->vpath_macro, prefix_len); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = joinpath(prefix, L"Lib", prefix_len); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - int module; - status = ismodule(prefix, &module); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - if (module) { - /* BUILD_LANDMARK and LANDMARK found */ - *found = -1; - return _PyStatus_OK(); - } - } - - /* Search from argv0_path, until root is found */ - status = copy_absolute(prefix, calculate->argv0_path, prefix_len); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - do { - /* Path: / / LANDMARK */ - size_t n = wcslen(prefix); - status = joinpath(prefix, calculate->lib_python, prefix_len); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - int module; - status = ismodule(prefix, &module); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - if (module) { - *found = 1; - return _PyStatus_OK(); - } - prefix[n] = L'\0'; - reduce(prefix); - } while (prefix[0]); - - /* Look at configure's PREFIX. - Path: / / LANDMARK */ - if (safe_wcscpy(prefix, calculate->prefix_macro, prefix_len) < 0) { - return PATHLEN_ERR(); - } - status = joinpath(prefix, calculate->lib_python, prefix_len); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - int module; - status = ismodule(prefix, &module); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - if (module) { - *found = 1; - return _PyStatus_OK(); - } - - /* Fail */ - *found = 0; - return _PyStatus_OK(); -} - - -static PyStatus -calculate_set_stdlib_dir(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ - // Note that, unlike calculate_set_prefix(), here we allow a negative - // prefix_found. That means the source tree Lib dir gets used. - if (!calculate->prefix_found) { - return _PyStatus_OK(); - } - PyStatus status; - wchar_t *prefix = calculate->prefix; - if (!_Py_isabs(prefix)) { - prefix = _PyMem_RawWcsdup(prefix); - if (prefix == NULL) { - return _PyStatus_NO_MEMORY(); - } - status = absolutize(&prefix); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - wchar_t buf[MAXPATHLEN + 1]; - int res = _Py_normalize_path(prefix, buf, Py_ARRAY_LENGTH(buf)); - if (prefix != calculate->prefix) { - PyMem_RawFree(prefix); - } - if (res < 0) { - return PATHLEN_ERR(); - } - pathconfig->stdlib_dir = _PyMem_RawWcsdup(buf); - if (pathconfig->stdlib_dir == NULL) { - return _PyStatus_NO_MEMORY(); - } - return _PyStatus_OK(); -} - - -static PyStatus -calculate_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ - wchar_t prefix[MAXPATHLEN+1]; - memset(prefix, 0, sizeof(prefix)); - size_t prefix_len = Py_ARRAY_LENGTH(prefix); - - PyStatus status; - status = search_for_prefix(calculate, pathconfig, - prefix, prefix_len, - &calculate->prefix_found); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (!calculate->prefix_found) { - if (calculate->warnings) { - fprintf(stderr, - "Could not find platform independent libraries \n"); - } - - calculate->prefix = joinpath2(calculate->prefix_macro, - calculate->lib_python); - } - else { - calculate->prefix = _PyMem_RawWcsdup(prefix); - } - - if (calculate->prefix == NULL) { - return _PyStatus_NO_MEMORY(); - } - return _PyStatus_OK(); -} - - -static PyStatus -calculate_set_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ - /* Reduce prefix and exec_prefix to their essence, - * e.g. /usr/local/lib/python1.5 is reduced to /usr/local. - * If we're loading relative to the build directory, - * return the compiled-in defaults instead. - */ - if (calculate->prefix_found > 0) { - wchar_t *prefix = _PyMem_RawWcsdup(calculate->prefix); - if (prefix == NULL) { - return _PyStatus_NO_MEMORY(); - } - - reduce(prefix); - reduce(prefix); - if (prefix[0]) { - pathconfig->prefix = prefix; - } - else { - PyMem_RawFree(prefix); - - /* The prefix is the root directory, but reduce() chopped - off the "/". */ - pathconfig->prefix = _PyMem_RawWcsdup(separator); - if (pathconfig->prefix == NULL) { - return _PyStatus_NO_MEMORY(); - } - } - } - else { - pathconfig->prefix = _PyMem_RawWcsdup(calculate->prefix_macro); - if (pathconfig->prefix == NULL) { - return _PyStatus_NO_MEMORY(); - } - } - return _PyStatus_OK(); -} - - -static PyStatus -calculate_pybuilddir(const wchar_t *argv0_path, - wchar_t *exec_prefix, size_t exec_prefix_len, - int *found) -{ - PyStatus status; - - /* Check to see if argv[0] is in the build directory. "pybuilddir.txt" - is written by setup.py and contains the relative path to the location - of shared library modules. - - Filename: / "pybuilddir.txt" */ - wchar_t *filename = joinpath2(argv0_path, L"pybuilddir.txt"); - if (filename == NULL) { - return _PyStatus_NO_MEMORY(); - } - - FILE *fp = _Py_wfopen(filename, L"rb"); - PyMem_RawFree(filename); - if (fp == NULL) { - errno = 0; - return _PyStatus_OK(); - } - - char buf[MAXPATHLEN + 1]; - size_t n = fread(buf, 1, Py_ARRAY_LENGTH(buf) - 1, fp); - buf[n] = '\0'; + size_t cb = fread(buffer, 1, MAX_FILE, fp); fclose(fp); - - size_t dec_len; - wchar_t *pybuilddir = _Py_DecodeUTF8_surrogateescape(buf, n, &dec_len); - if (!pybuilddir) { - return DECODE_LOCALE_ERR("pybuilddir.txt", dec_len); + if (!cb) { + return r; } - - /* Path: / */ - if (safe_wcscpy(exec_prefix, argv0_path, exec_prefix_len) < 0) { - PyMem_RawFree(pybuilddir); - return PATHLEN_ERR(); - } - status = joinpath(exec_prefix, pybuilddir, exec_prefix_len); - PyMem_RawFree(pybuilddir); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - *found = -1; - return _PyStatus_OK(); -} - - -/* search_for_exec_prefix requires that argv0_path be no more than - MAXPATHLEN bytes long. -*/ -static PyStatus -search_for_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, - wchar_t *exec_prefix, size_t exec_prefix_len, - int *found) -{ - PyStatus status; - - /* If PYTHONHOME is set, we believe it unconditionally */ - if (pathconfig->home) { - /* Path: / / "lib-dynload" */ - wchar_t *delim = wcschr(pathconfig->home, DELIM); - if (delim) { - if (safe_wcscpy(exec_prefix, delim+1, exec_prefix_len) < 0) { - return PATHLEN_ERR(); - } - } - else { - if (safe_wcscpy(exec_prefix, pathconfig->home, exec_prefix_len) < 0) { - return PATHLEN_ERR(); - } - } - status = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - status = joinpath(exec_prefix, L"lib-dynload", exec_prefix_len); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - *found = 1; - return _PyStatus_OK(); - } - - /* Check for pybuilddir.txt */ - assert(*found == 0); - status = calculate_pybuilddir(calculate->argv0_path, - exec_prefix, exec_prefix_len, found); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - if (*found) { - return _PyStatus_OK(); - } - - /* Search from argv0_path, until root is found */ - status = copy_absolute(exec_prefix, calculate->argv0_path, exec_prefix_len); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - do { - /* Path: / / "lib-dynload" */ - size_t n = wcslen(exec_prefix); - status = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - status = joinpath(exec_prefix, L"lib-dynload", exec_prefix_len); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - if (isdir(exec_prefix)) { - *found = 1; - return _PyStatus_OK(); - } - exec_prefix[n] = L'\0'; - reduce(exec_prefix); - } while (exec_prefix[0]); - - /* Look at configure's EXEC_PREFIX. - - Path: / / "lib-dynload" */ - if (safe_wcscpy(exec_prefix, calculate->exec_prefix_macro, exec_prefix_len) < 0) { - return PATHLEN_ERR(); - } - status = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - status = joinpath(exec_prefix, L"lib-dynload", exec_prefix_len); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - if (isdir(exec_prefix)) { - *found = 1; - return _PyStatus_OK(); - } - - /* Fail */ - *found = 0; - return _PyStatus_OK(); -} - - -static PyStatus -calculate_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ - PyStatus status; - wchar_t exec_prefix[MAXPATHLEN+1]; - memset(exec_prefix, 0, sizeof(exec_prefix)); - size_t exec_prefix_len = Py_ARRAY_LENGTH(exec_prefix); - - status = search_for_exec_prefix(calculate, pathconfig, - exec_prefix, exec_prefix_len, - &calculate->exec_prefix_found); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (!calculate->exec_prefix_found) { - if (calculate->warnings) { - fprintf(stderr, - "Could not find platform dependent libraries \n"); - } - - /* / "lib-dynload" */ - wchar_t *lib_dynload = joinpath2(calculate->platlibdir, - L"lib-dynload"); - if (lib_dynload == NULL) { - return _PyStatus_NO_MEMORY(); - } - - calculate->exec_prefix = joinpath2(calculate->exec_prefix_macro, - lib_dynload); - PyMem_RawFree(lib_dynload); - - if (calculate->exec_prefix == NULL) { - return _PyStatus_NO_MEMORY(); - } - } - else { - /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ - calculate->exec_prefix = _PyMem_RawWcsdup(exec_prefix); - if (calculate->exec_prefix == NULL) { - return _PyStatus_NO_MEMORY(); - } - } - return _PyStatus_OK(); -} - - -static PyStatus -calculate_set_exec_prefix(PyCalculatePath *calculate, - _PyPathConfig *pathconfig) -{ - if (calculate->exec_prefix_found > 0) { - wchar_t *exec_prefix = _PyMem_RawWcsdup(calculate->exec_prefix); - if (exec_prefix == NULL) { - return _PyStatus_NO_MEMORY(); - } - - reduce(exec_prefix); - reduce(exec_prefix); - reduce(exec_prefix); - - if (exec_prefix[0]) { - pathconfig->exec_prefix = exec_prefix; - } - else { - /* empty string: use SEP instead */ - PyMem_RawFree(exec_prefix); - - /* The exec_prefix is the root directory, but reduce() chopped - off the "/". */ - pathconfig->exec_prefix = _PyMem_RawWcsdup(separator); - if (pathconfig->exec_prefix == NULL) { - return _PyStatus_NO_MEMORY(); - } - } - } - else { - pathconfig->exec_prefix = _PyMem_RawWcsdup(calculate->exec_prefix_macro); - if (pathconfig->exec_prefix == NULL) { - return _PyStatus_NO_MEMORY(); - } - } - return _PyStatus_OK(); -} - - -/* Similar to shutil.which(). - If found, write the path into *abs_path_p. */ -static PyStatus -calculate_which(const wchar_t *path_env, wchar_t *program_name, - wchar_t **abs_path_p) -{ - while (1) { - wchar_t *delim = wcschr(path_env, DELIM); - wchar_t *abs_path; - - if (delim) { - wchar_t *path = substring(path_env, delim - path_env); - if (path == NULL) { - return _PyStatus_NO_MEMORY(); - } - abs_path = joinpath2(path, program_name); - PyMem_RawFree(path); - } - else { - abs_path = joinpath2(path_env, program_name); - } - - if (abs_path == NULL) { - return _PyStatus_NO_MEMORY(); - } - - if (isxfile(abs_path)) { - *abs_path_p = abs_path; - return _PyStatus_OK(); - } - PyMem_RawFree(abs_path); - - if (!delim) { - break; - } - path_env = delim + 1; - } - - /* not found */ - return _PyStatus_OK(); -} - - -#ifdef __APPLE__ -static PyStatus -calculate_program_macos(wchar_t **abs_path_p) -{ - char execpath[MAXPATHLEN + 1]; - uint32_t nsexeclength = Py_ARRAY_LENGTH(execpath) - 1; - - /* On Mac OS X, if a script uses an interpreter of the form - "#!/opt/python2.3/bin/python", the kernel only passes "python" - as argv[0], which falls through to the $PATH search below. - If /opt/python2.3/bin isn't in your path, or is near the end, - this algorithm may incorrectly find /usr/bin/python. To work - around this, we can use _NSGetExecutablePath to get a better - hint of what the intended interpreter was, although this - will fail if a relative path was used. but in that case, - absolutize() should help us out below - */ - if (_NSGetExecutablePath(execpath, &nsexeclength) != 0 - || (wchar_t)execpath[0] != SEP) - { - /* _NSGetExecutablePath() failed or the path is relative */ - return _PyStatus_OK(); + if (cb >= MAX_FILE) { + Py_DECREF(r); + PyErr_SetString(PyExc_MemoryError, + "cannot read file larger than 32KB during initialization"); + return NULL; } + buffer[cb] = '\0'; size_t len; - *abs_path_p = Py_DecodeLocale(execpath, &len); - if (*abs_path_p == NULL) { - return DECODE_LOCALE_ERR("executable path", len); + wchar_t *wbuffer = _Py_DecodeUTF8_surrogateescape(buffer, cb, &len); + PyMem_Free((void *)buffer); + if (!wbuffer) { + Py_DECREF(r); + PyErr_NoMemory(); + return NULL; } - return _PyStatus_OK(); -} -#endif /* __APPLE__ */ - -static PyStatus -calculate_program_impl(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ - assert(pathconfig->program_full_path == NULL); - - PyStatus status; - - /* If there is no slash in the argv0 path, then we have to - * assume python is on the user's $PATH, since there's no - * other way to find a directory to start the search from. If - * $PATH isn't exported, you lose. - */ - if (wcschr(pathconfig->program_name, SEP)) { - pathconfig->program_full_path = _PyMem_RawWcsdup(pathconfig->program_name); - if (pathconfig->program_full_path == NULL) { - return _PyStatus_NO_MEMORY(); + wchar_t *p1 = wbuffer; + wchar_t *p2 = p1; + while ((p2 = wcschr(p1, L'\n')) != NULL) { + Py_ssize_t cb = p2 - p1; + while (cb >= 0 && (p1[cb] == L'\n' || p1[cb] == L'\r')) { + --cb; } - return _PyStatus_OK(); - } - -#ifdef __APPLE__ - wchar_t *abs_path = NULL; - status = calculate_program_macos(&abs_path); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - if (abs_path) { - pathconfig->program_full_path = abs_path; - return _PyStatus_OK(); - } -#endif /* __APPLE__ */ - - if (calculate->path_env) { - wchar_t *abs_path = NULL; - status = calculate_which(calculate->path_env, pathconfig->program_name, - &abs_path); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - if (abs_path) { - pathconfig->program_full_path = abs_path; - return _PyStatus_OK(); - } - } - - /* In the last resort, use an empty string */ - pathconfig->program_full_path = _PyMem_RawWcsdup(L""); - if (pathconfig->program_full_path == NULL) { - return _PyStatus_NO_MEMORY(); - } - return _PyStatus_OK(); -} - - -/* Calculate pathconfig->program_full_path */ -static PyStatus -calculate_program(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ - PyStatus status; - - status = calculate_program_impl(calculate, pathconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (pathconfig->program_full_path[0] != '\0') { - /* program_full_path is not empty */ - - /* Make sure that program_full_path is an absolute path */ - if (!_Py_isabs(pathconfig->program_full_path)) { - status = absolutize(&pathconfig->program_full_path); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - -#if defined(__CYGWIN__) || defined(__MINGW32__) - /* For these platforms it is necessary to ensure that the .exe suffix - * is appended to the filename, otherwise there is potential for - * sys.executable to return the name of a directory under the same - * path (bpo-28441). - */ - status = add_exe_suffix(&pathconfig->program_full_path); - if (_PyStatus_EXCEPTION(status)) { - return status; - } -#endif - } - return _PyStatus_OK(); -} - - -#if HAVE_READLINK -static PyStatus -resolve_symlinks(wchar_t **path_p) -{ - wchar_t new_path[MAXPATHLEN + 1]; - const size_t new_path_len = Py_ARRAY_LENGTH(new_path); - unsigned int nlink = 0; - - while (1) { - int linklen = _Py_wreadlink(*path_p, new_path, new_path_len); - if (linklen == -1) { - /* not a symbolic link: we are done */ + PyObject *u = PyUnicode_FromWideChar(p1, cb >= 0 ? cb + 1 : 0); + if (!u || PyList_Append(r, u) < 0) { + Py_XDECREF(u); + Py_CLEAR(r); break; } - - if (_Py_isabs(new_path)) { - PyMem_RawFree(*path_p); - *path_p = _PyMem_RawWcsdup(new_path); - if (*path_p == NULL) { - return _PyStatus_NO_MEMORY(); - } + Py_DECREF(u); + p1 = p2 + 1; + } + if (r && p1 && *p1) { + PyObject *u = PyUnicode_FromWideChar(p1, -1); + if (!u || PyList_Append(r, u) < 0) { + Py_CLEAR(r); } - else { - /* new_path is relative to path */ - reduce(*path_p); + Py_XDECREF(u); + } + PyMem_RawFree(wbuffer); + return r; +} - wchar_t *abs_path = joinpath2(*path_p, new_path); - if (abs_path == NULL) { - return _PyStatus_NO_MEMORY(); - } - PyMem_RawFree(*path_p); - *path_p = abs_path; +static PyObject * +getpath_realpath(PyObject *Py_UNUSED(self) , PyObject *args) +{ + PyObject *pathobj; + if (!PyArg_ParseTuple(args, "U", &pathobj)) { + return NULL; + } +#if defined(HAVE_READLINK) + /* This readlink calculation only resolves a symlinked file, and + does not resolve any path segments. This is consistent with + prior releases, however, the realpath implementation below is + potentially correct in more cases. */ + PyObject *r = NULL; + int nlink = 0; + wchar_t *path = PyUnicode_AsWideCharString(pathobj, NULL); + if (!path) { + goto done; + } + wchar_t *path2 = _PyMem_RawWcsdup(path); + PyMem_Free((void *)path); + path = path2; + while (path) { + wchar_t resolved[MAXPATHLEN + 1]; + int linklen = _Py_wreadlink(path, resolved, Py_ARRAY_LENGTH(resolved)); + if (linklen == -1) { + r = PyUnicode_FromWideChar(path, -1); + break; + } + if (_Py_isabs(resolved)) { + PyMem_RawFree((void *)path); + path = _PyMem_RawWcsdup(resolved); + } else { + wchar_t *s = wcsrchr(path, SEP); + if (s) { + *s = L'\0'; + } + path2 = _Py_normpath(_Py_join_relfile(path, resolved), -1); + PyMem_RawFree((void *)path); + path = path2; } - nlink++; /* 40 is the Linux kernel 4.2 limit */ if (nlink >= 40) { - return _PyStatus_ERR("maximum number of symbolic links reached"); - } - } - return _PyStatus_OK(); -} -#endif /* HAVE_READLINK */ - - -#ifdef WITH_NEXT_FRAMEWORK -static PyStatus -calculate_argv0_path_framework(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ - NSModule pythonModule; - - /* On Mac OS X we have a special case if we're running from a framework. - This is because the python home should be set relative to the library, - which is in the framework, not relative to the executable, which may - be outside of the framework. Except when we're in the build - directory... */ - pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize")); - - /* Use dylib functions to find out where the framework was loaded from */ - const char* modPath = NSLibraryNameForModule(pythonModule); - if (modPath == NULL) { - return _PyStatus_OK(); - } - - /* We're in a framework. - See if we might be in the build directory. The framework in the - build directory is incomplete, it only has the .dylib and a few - needed symlinks, it doesn't have the Lib directories and such. - If we're running with the framework from the build directory we must - be running the interpreter in the build directory, so we use the - build-directory-specific logic to find Lib and such. */ - size_t len; - wchar_t* wbuf = Py_DecodeLocale(modPath, &len); - if (wbuf == NULL) { - return DECODE_LOCALE_ERR("framework location", len); - } - - /* Path: reduce(modPath) / lib_python / LANDMARK */ - PyStatus status; - - wchar_t *parent = _PyMem_RawWcsdup(wbuf); - if (parent == NULL) { - status = _PyStatus_NO_MEMORY(); - goto done; - } - - reduce(parent); - wchar_t *lib_python = joinpath2(parent, calculate->lib_python); - PyMem_RawFree(parent); - - if (lib_python == NULL) { - status = _PyStatus_NO_MEMORY(); - goto done; - } - - int module; - status = ismodule(lib_python, &module); - PyMem_RawFree(lib_python); - - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - if (!module) { - /* We are in the build directory so use the name of the - executable - we know that the absolute path is passed */ - PyMem_RawFree(calculate->argv0_path); - calculate->argv0_path = _PyMem_RawWcsdup(pathconfig->program_full_path); - if (calculate->argv0_path == NULL) { - status = _PyStatus_NO_MEMORY(); - goto done; - } - - status = _PyStatus_OK(); - goto done; - } - - /* Use the location of the library as argv0_path */ - PyMem_RawFree(calculate->argv0_path); - calculate->argv0_path = wbuf; - return _PyStatus_OK(); - -done: - PyMem_RawFree(wbuf); - return status; -} -#endif - - -static PyStatus -calculate_argv0_path(PyCalculatePath *calculate, - _PyPathConfig *pathconfig) -{ - PyStatus status; - - calculate->argv0_path = _PyMem_RawWcsdup(pathconfig->program_full_path); - if (calculate->argv0_path == NULL) { - return _PyStatus_NO_MEMORY(); - } - -#ifdef WITH_NEXT_FRAMEWORK - status = calculate_argv0_path_framework(calculate, pathconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; - } -#endif - - status = resolve_symlinks(&calculate->argv0_path); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - reduce(calculate->argv0_path); - - return _PyStatus_OK(); -} - - -static PyStatus -calculate_open_pyenv(PyCalculatePath *calculate, FILE **env_file_p) -{ - *env_file_p = NULL; - - const wchar_t *env_cfg = L"pyvenv.cfg"; - - /* Filename: / "pyvenv.cfg" */ - wchar_t *filename = joinpath2(calculate->argv0_path, env_cfg); - if (filename == NULL) { - return _PyStatus_NO_MEMORY(); - } - - *env_file_p = _Py_wfopen(filename, L"r"); - PyMem_RawFree(filename); - - if (*env_file_p != NULL) { - return _PyStatus_OK(); - - } - - /* fopen() failed: reset errno */ - errno = 0; - - /* Path: / "pyvenv.cfg" */ - wchar_t *parent = _PyMem_RawWcsdup(calculate->argv0_path); - if (parent == NULL) { - return _PyStatus_NO_MEMORY(); - } - reduce(parent); - - filename = joinpath2(parent, env_cfg); - PyMem_RawFree(parent); - if (filename == NULL) { - return _PyStatus_NO_MEMORY(); - } - - *env_file_p = _Py_wfopen(filename, L"r"); - PyMem_RawFree(filename); - - if (*env_file_p == NULL) { - /* fopen() failed: reset errno */ - errno = 0; - } - return _PyStatus_OK(); -} - - -/* Search for an "pyvenv.cfg" environment configuration file, first in the - executable's directory and then in the parent directory. - If found, open it for use when searching for prefixes. - - Write the 'home' variable of pyvenv.cfg into calculate->argv0_path. */ -static PyStatus -calculate_read_pyenv(PyCalculatePath *calculate) -{ - PyStatus status; - FILE *env_file = NULL; - - status = calculate_open_pyenv(calculate, &env_file); - if (_PyStatus_EXCEPTION(status)) { - assert(env_file == NULL); - return status; - } - if (env_file == NULL) { - /* pyvenv.cfg not found */ - return _PyStatus_OK(); - } - - /* Look for a 'home' variable and set argv0_path to it, if found */ - wchar_t *home = NULL; - status = _Py_FindEnvConfigValue(env_file, L"home", &home); - if (_PyStatus_EXCEPTION(status)) { - fclose(env_file); - return status; - } - - if (home) { - PyMem_RawFree(calculate->argv0_path); - calculate->argv0_path = home; - } - fclose(env_file); - return _PyStatus_OK(); -} - - -static PyStatus -calculate_zip_path(PyCalculatePath *calculate) -{ - PyStatus res; - - /* Path: / "pythonXY.zip" */ - wchar_t *path = joinpath2(calculate->platlibdir, - L"python" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) - L".zip"); - if (path == NULL) { - return _PyStatus_NO_MEMORY(); - } - - if (calculate->prefix_found > 0) { - /* Use the reduced prefix returned by Py_GetPrefix() - - Path: / / "pythonXY.zip" */ - wchar_t *parent = _PyMem_RawWcsdup(calculate->prefix); - if (parent == NULL) { - res = _PyStatus_NO_MEMORY(); - goto done; - } - reduce(parent); - reduce(parent); - calculate->zip_path = joinpath2(parent, path); - PyMem_RawFree(parent); - } - else { - calculate->zip_path = joinpath2(calculate->prefix_macro, path); - } - - if (calculate->zip_path == NULL) { - res = _PyStatus_NO_MEMORY(); - goto done; - } - - res = _PyStatus_OK(); - -done: - PyMem_RawFree(path); - return res; -} - - -static PyStatus -calculate_module_search_path(PyCalculatePath *calculate, - _PyPathConfig *pathconfig) -{ - /* Calculate size of return buffer */ - size_t bufsz = 0; - if (calculate->pythonpath_env != NULL) { - bufsz += wcslen(calculate->pythonpath_env) + 1; - } - - wchar_t *defpath = calculate->pythonpath_macro; - size_t prefixsz = wcslen(calculate->prefix) + 1; - while (1) { - wchar_t *delim = wcschr(defpath, DELIM); - - if (!_Py_isabs(defpath)) { - /* Paths are relative to prefix */ - bufsz += prefixsz; - } - - if (delim) { - bufsz += delim - defpath + 1; - } - else { - bufsz += wcslen(defpath) + 1; + PyErr_SetString(PyExc_OSError, "maximum number of symbolic links reached"); break; } - defpath = delim + 1; } - - bufsz += wcslen(calculate->zip_path) + 1; - bufsz += wcslen(calculate->exec_prefix) + 1; - - /* Allocate the buffer */ - wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t)); - if (buf == NULL) { - return _PyStatus_NO_MEMORY(); + if (!path) { + PyErr_NoMemory(); } - buf[0] = '\0'; +done: + PyMem_RawFree((void *)path); + return r; - /* Run-time value of $PYTHONPATH goes first */ - if (calculate->pythonpath_env) { - wcscpy(buf, calculate->pythonpath_env); - wcscat(buf, delimiter); +#elif defined(HAVE_REALPATH) + PyObject *r = NULL; + struct stat st; + const char *narrow = NULL; + wchar_t *path = PyUnicode_AsWideCharString(pathobj, NULL); + if (!path) { + goto done; } + narrow = Py_EncodeLocale(path, NULL); + if (!narrow) { + PyErr_NoMemory(); + goto done; + } + if (lstat(narrow, &st)) { + PyErr_SetFromErrno(PyExc_OSError); + goto done; + } + if (!S_ISLNK(st.st_mode)) { + r = Py_NewRef(pathobj); + goto done; + } + wchar_t resolved[MAXPATHLEN+1]; + if (_Py_wrealpath(path, resolved, MAXPATHLEN) == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + } else { + r = PyUnicode_FromWideChar(resolved, -1); + } +done: + PyMem_Free((void *)path); + PyMem_Free((void *)narrow); + return r; +#endif - /* Next is the default zip path */ - wcscat(buf, calculate->zip_path); - wcscat(buf, delimiter); + return Py_NewRef(pathobj); +} - /* Next goes merge of compile-time $PYTHONPATH with - * dynamically located prefix. - */ - defpath = calculate->pythonpath_macro; - while (1) { - wchar_t *delim = wcschr(defpath, DELIM); - if (!_Py_isabs(defpath)) { - wcscat(buf, calculate->prefix); - if (prefixsz >= 2 && calculate->prefix[prefixsz - 2] != SEP && - defpath[0] != (delim ? DELIM : L'\0')) - { - /* not empty */ - wcscat(buf, separator); +static PyMethodDef getpath_methods[] = { + {"abspath", getpath_abspath, METH_VARARGS, NULL}, + {"basename", getpath_basename, METH_VARARGS, NULL}, + {"dirname", getpath_dirname, METH_VARARGS, NULL}, + {"hassuffix", getpath_hassuffix, METH_VARARGS, NULL}, + {"isabs", getpath_isabs, METH_VARARGS, NULL}, + {"isdir", getpath_isdir, METH_VARARGS, NULL}, + {"isfile", getpath_isfile, METH_VARARGS, NULL}, + {"isxfile", getpath_isxfile, METH_VARARGS, NULL}, + {"joinpath", getpath_joinpath, METH_VARARGS, NULL}, + {"readlines", getpath_readlines, METH_VARARGS, NULL}, + {"realpath", getpath_realpath, METH_VARARGS, NULL}, + {NULL, NULL, 0, NULL} +}; + + +/* Two implementations of warn() to use depending on whether warnings + are enabled or not. */ + +static PyObject * +getpath_warn(PyObject *Py_UNUSED(self), PyObject *args) +{ + PyObject *msgobj; + if (!PyArg_ParseTuple(args, "U", &msgobj)) { + return NULL; + } + fprintf(stderr, "%s\n", PyUnicode_AsUTF8(msgobj)); + Py_RETURN_NONE; +} + + +static PyObject * +getpath_nowarn(PyObject *Py_UNUSED(self), PyObject *args) +{ + Py_RETURN_NONE; +} + + +static PyMethodDef getpath_warn_method = {"warn", getpath_warn, METH_VARARGS, NULL}; +static PyMethodDef getpath_nowarn_method = {"warn", getpath_nowarn, METH_VARARGS, NULL}; + +/* Add the helper functions to the dict */ +static int +funcs_to_dict(PyObject *dict, int warnings) +{ + for (PyMethodDef *m = getpath_methods; m->ml_name; ++m) { + PyObject *f = PyCFunction_NewEx(m, NULL, NULL); + if (!f) { + return 0; + } + if (PyDict_SetItemString(dict, m->ml_name, f) < 0) { + Py_DECREF(f); + return 0; + } + Py_DECREF(f); + } + PyMethodDef *m2 = warnings ? &getpath_warn_method : &getpath_nowarn_method; + PyObject *f = PyCFunction_NewEx(m2, NULL, NULL); + if (!f) { + return 0; + } + if (PyDict_SetItemString(dict, m2->ml_name, f) < 0) { + Py_DECREF(f); + return 0; + } + Py_DECREF(f); + return 1; +} + + +/* Add a wide-character string constant to the dict */ +static int +wchar_to_dict(PyObject *dict, const char *key, const wchar_t *s) +{ + PyObject *u; + int r; + if (s && s[0]) { + u = PyUnicode_FromWideChar(s, -1); + if (!u) { + return 0; + } + } else { + u = Py_NewRef(Py_None); + } + r = PyDict_SetItemString(dict, key, u) == 0; + Py_DECREF(u); + return r; +} + + +/* Add a narrow string constant to the dict, using default locale decoding */ +static int +decode_to_dict(PyObject *dict, const char *key, const char *s) +{ + PyObject *u = NULL; + int r; + if (s && s[0]) { + size_t len; + const wchar_t *w = Py_DecodeLocale(s, &len); + if (w) { + u = PyUnicode_FromWideChar(w, len); + PyMem_RawFree((void *)w); + } + if (!u) { + return 0; + } + } else { + u = Py_NewRef(Py_None); + } + r = PyDict_SetItemString(dict, key, u) == 0; + Py_DECREF(u); + return r; +} + +/* Add an environment variable to the dict, optionally clearing it afterwards */ +static int +env_to_dict(PyObject *dict, const char *key, int and_clear) +{ + PyObject *u = NULL; + int r = 0; + assert(strncmp(key, "ENV_", 4) == 0); + assert(strlen(key) < 64); +#ifdef MS_WINDOWS + wchar_t wkey[64]; + // Quick convert to wchar_t, since we know key is ASCII + wchar_t *wp = wkey; + for (const char *p = &key[4]; *p; ++p) { + assert(*p < 128); + *wp++ = *p; + } + *wp = L'\0'; + const wchar_t *v = _wgetenv(wkey); + if (v) { + u = PyUnicode_FromWideChar(v, -1); + if (!u) { + PyErr_Clear(); + } + } +#else + const char *v = getenv(&key[4]); + if (v) { + size_t len; + const wchar_t *w = Py_DecodeLocale(v, &len); + if (w) { + u = PyUnicode_FromWideChar(w, len); + if (!u) { + PyErr_Clear(); + } + PyMem_RawFree((void *)w); + } + } +#endif + if (u) { + r = PyDict_SetItemString(dict, key, u) == 0; + Py_DECREF(u); + } else { + r = PyDict_SetItemString(dict, key, Py_None) == 0; + } + if (r && and_clear) { +#ifdef MS_WINDOWS + _wputenv_s(wkey, L""); +#else + unsetenv(&key[4]); +#endif + } + return r; +} + + +/* Add an integer constant to the dict */ +static int +int_to_dict(PyObject *dict, const char *key, int v) +{ + PyObject *o; + int r; + o = PyLong_FromLong(v); + if (!o) { + return 0; + } + r = PyDict_SetItemString(dict, key, o) == 0; + Py_DECREF(o); + return r; +} + + +#ifdef MS_WINDOWS +static int +winmodule_to_dict(PyObject *dict, const char *key, HMODULE mod) +{ + wchar_t *buffer = NULL; + for (DWORD cch = 256; buffer == NULL && cch < (1024 * 1024); cch *= 2) { + buffer = (wchar_t*)PyMem_RawMalloc(cch * sizeof(wchar_t)); + if (buffer) { + if (GetModuleFileNameW(mod, buffer, cch) == cch) { + PyMem_RawFree(buffer); + buffer = NULL; } } - - if (delim) { - size_t len = delim - defpath + 1; - size_t end = wcslen(buf) + len; - wcsncat(buf, defpath, len); - buf[end] = '\0'; - } - else { - wcscat(buf, defpath); - break; - } - defpath = delim + 1; } - wcscat(buf, delimiter); - - /* Finally, on goes the directory for dynamic-load modules */ - wcscat(buf, calculate->exec_prefix); - - pathconfig->module_search_path = buf; - return _PyStatus_OK(); -} - - -static PyStatus -calculate_init(PyCalculatePath *calculate, const PyConfig *config) -{ - size_t len; - - calculate->warnings = config->pathconfig_warnings; - calculate->pythonpath_env = config->pythonpath_env; - calculate->platlibdir = config->platlibdir; - - const char *path = getenv("PATH"); - if (path) { - calculate->path_env = Py_DecodeLocale(path, &len); - if (!calculate->path_env) { - return DECODE_LOCALE_ERR("PATH environment variable", len); - } - } - - /* Decode macros */ - calculate->pythonpath_macro = Py_DecodeLocale(PYTHONPATH, &len); - if (!calculate->pythonpath_macro) { - return DECODE_LOCALE_ERR("PYTHONPATH macro", len); - } - calculate->prefix_macro = Py_DecodeLocale(PREFIX, &len); - if (!calculate->prefix_macro) { - return DECODE_LOCALE_ERR("PREFIX macro", len); - } - calculate->exec_prefix_macro = Py_DecodeLocale(EXEC_PREFIX, &len); - if (!calculate->exec_prefix_macro) { - return DECODE_LOCALE_ERR("EXEC_PREFIX macro", len); - } - calculate->vpath_macro = Py_DecodeLocale(VPATH, &len); - if (!calculate->vpath_macro) { - return DECODE_LOCALE_ERR("VPATH macro", len); - } - - // / "pythonX.Y" - wchar_t *pyversion = Py_DecodeLocale("python" VERSION, &len); - if (!pyversion) { - return DECODE_LOCALE_ERR("VERSION macro", len); - } - calculate->lib_python = joinpath2(config->platlibdir, pyversion); - PyMem_RawFree(pyversion); - if (calculate->lib_python == NULL) { - return _PyStatus_NO_MEMORY(); - } - - return _PyStatus_OK(); -} - - -static void -calculate_free(PyCalculatePath *calculate) -{ - PyMem_RawFree(calculate->pythonpath_macro); - PyMem_RawFree(calculate->prefix_macro); - PyMem_RawFree(calculate->exec_prefix_macro); - PyMem_RawFree(calculate->vpath_macro); - PyMem_RawFree(calculate->lib_python); - PyMem_RawFree(calculate->path_env); - PyMem_RawFree(calculate->zip_path); - PyMem_RawFree(calculate->argv0_path); - PyMem_RawFree(calculate->prefix); - PyMem_RawFree(calculate->exec_prefix); -} - - -static PyStatus -calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ - PyStatus status; - - if (pathconfig->program_full_path == NULL) { - status = calculate_program(calculate, pathconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - status = calculate_argv0_path(calculate, pathconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - /* If a pyvenv.cfg configure file is found, - argv0_path is overridden with its 'home' variable. */ - status = calculate_read_pyenv(calculate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = calculate_prefix(calculate, pathconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = calculate_zip_path(calculate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = calculate_exec_prefix(calculate, pathconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if ((!calculate->prefix_found || !calculate->exec_prefix_found) - && calculate->warnings) - { - fprintf(stderr, - "Consider setting $PYTHONHOME to [:]\n"); - } - - if (pathconfig->module_search_path == NULL) { - status = calculate_module_search_path(calculate, pathconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (pathconfig->stdlib_dir == NULL) { - /* This must be done *before* calculate_set_prefix() is called. */ - status = calculate_set_stdlib_dir(calculate, pathconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (pathconfig->prefix == NULL) { - status = calculate_set_prefix(calculate, pathconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (pathconfig->exec_prefix == NULL) { - status = calculate_set_exec_prefix(calculate, pathconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - return _PyStatus_OK(); -} - - -/* Calculate the Python path configuration. - - Inputs: - - - PATH environment variable - - Macros: PYTHONPATH, PREFIX, EXEC_PREFIX, VERSION (ex: "3.9"). - PREFIX and EXEC_PREFIX are generated by the configure script. - PYTHONPATH macro is the default search path. - - pybuilddir.txt file - - pyvenv.cfg configuration file - - PyConfig fields ('config' function argument): - - - pathconfig_warnings - - pythonpath_env (PYTHONPATH environment variable) - - - _PyPathConfig fields ('pathconfig' function argument): - - - program_name: see config_init_program_name() - - home: Py_SetPythonHome() or PYTHONHOME environment variable - - - current working directory: see copy_absolute() - - Outputs, 'pathconfig' fields: - - - program_full_path - - module_search_path - - prefix - - exec_prefix - - If a field is already set (non NULL), it is left unchanged. */ -PyStatus -_PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config) -{ - PyStatus status; - PyCalculatePath calculate; - memset(&calculate, 0, sizeof(calculate)); - - status = calculate_init(&calculate, config); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - status = calculate_path(&calculate, pathconfig); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - /* program_full_path must an either an empty string or an absolute path */ - assert(wcslen(pathconfig->program_full_path) == 0 - || _Py_isabs(pathconfig->program_full_path)); - - status = _PyStatus_OK(); - -done: - calculate_free(&calculate); - return status; -} - -#ifdef __cplusplus + int r = wchar_to_dict(dict, key, buffer); + PyMem_RawFree(buffer); + return r; } #endif + + +/* Add the current executable's path to the dict */ +static int +progname_to_dict(PyObject *dict, const char *key) +{ +#ifdef MS_WINDOWS + return winmodule_to_dict(dict, key, NULL); +#elif defined(__APPLE__) + char *path; + uint32_t pathLen = 256; + while (pathLen) { + path = PyMem_RawMalloc((pathLen + 1) * sizeof(char)); + if (!path) { + return 0; + } + if (_NSGetExecutablePath(path, &pathLen) != 0) { + PyMem_RawFree(path); + continue; + } + // Only keep if the path is absolute + if (path[0] == SEP) { + int r = decode_to_dict(dict, key, path); + PyMem_RawFree(path); + return r; + } + // Fall back and store None + PyMem_RawFree(path); + break; + } +#endif + return PyDict_SetItemString(dict, key, Py_None) == 0; +} + + +/* Add the runtime library's path to the dict */ +static int +library_to_dict(PyObject *dict, const char *key) +{ +#ifdef MS_WINDOWS + extern HMODULE PyWin_DLLhModule; + if (PyWin_DLLhModule) { + return winmodule_to_dict(dict, key, PyWin_DLLhModule); + } +#elif defined(WITH_NEXT_FRAMEWORK) + static char modPath[MAXPATHLEN + 1]; + static int modPathInitialized = -1; + if (modPathInitialized < 0) { + modPathInitialized = 0; + + /* On Mac OS X we have a special case if we're running from a framework. + This is because the python home should be set relative to the library, + which is in the framework, not relative to the executable, which may + be outside of the framework. Except when we're in the build + directory... */ + NSSymbol symbol = NSLookupAndBindSymbol("_Py_Initialize"); + if (symbol != NULL) { + NSModule pythonModule = NSModuleForSymbol(symbol); + if (pythonModule != NULL) { + /* Use dylib functions to find out where the framework was loaded from */ + const char *path = NSLibraryNameForModule(pythonModule); + if (path) { + strncpy(modPath, path, MAXPATHLEN); + modPathInitialized = 1; + } + } + } + } + if (modPathInitialized > 0) { + return decode_to_dict(dict, key, modPath); + } +#endif + return PyDict_SetItemString(dict, key, Py_None) == 0; +} + + +PyObject * +_Py_Get_Getpath_CodeObject(void) +{ + return PyMarshal_ReadObjectFromString( + (const char*)_Py_M__getpath, sizeof(_Py_M__getpath)); +} + + +/* Perform the actual path calculation. + + When compute_path_config is 0, this only reads any initialised path + config values into the PyConfig struct. For example, Py_SetHome() or + Py_SetPath(). The only error should be due to failed memory allocation. + + When compute_path_config is 1, full path calculation is performed. + The GIL must be held, and there may be filesystem access, side + effects, and potential unraisable errors that are reported directly + to stderr. + + Calling this function multiple times on the same PyConfig is only + safe because already-configured values are not recalculated. To + actually recalculate paths, you need a clean PyConfig. +*/ +PyStatus +_PyConfig_InitPathConfig(PyConfig *config, int compute_path_config) +{ + PyStatus status = _PyPathConfig_ReadGlobal(config); + + if (_PyStatus_EXCEPTION(status) || !compute_path_config) { + return status; + } + + if (!_PyThreadState_UncheckedGet()) { + return PyStatus_Error("cannot calculate path configuration without GIL"); + } + + PyObject *configDict = _PyConfig_AsDict(config); + if (!configDict) { + PyErr_Clear(); + return PyStatus_NoMemory(); + } + + PyObject *dict = PyDict_New(); + if (!dict) { + PyErr_Clear(); + Py_DECREF(configDict); + return PyStatus_NoMemory(); + } + + if (PyDict_SetItemString(dict, "config", configDict) < 0) { + PyErr_Clear(); + Py_DECREF(configDict); + Py_DECREF(dict); + return PyStatus_NoMemory(); + } + /* reference now held by dict */ + Py_DECREF(configDict); + + PyObject *co = _Py_Get_Getpath_CodeObject(); + if (!co || !PyCode_Check(co)) { + PyErr_Clear(); + Py_XDECREF(co); + Py_DECREF(dict); + return PyStatus_Error("error reading frozen getpath.py"); + } + +#ifdef MS_WINDOWS + PyObject *winreg = PyImport_ImportModule("winreg"); + if (!winreg || PyDict_SetItemString(dict, "winreg", winreg) < 0) { + PyErr_Clear(); + Py_XDECREF(winreg); + if (PyDict_SetItemString(dict, "winreg", Py_None) < 0) { + PyErr_Clear(); + Py_DECREF(co); + Py_DECREF(dict); + return PyStatus_Error("error importing winreg module"); + } + } else { + Py_DECREF(winreg); + } +#endif + + if ( +#ifdef MS_WINDOWS + !decode_to_dict(dict, "os_name", "nt") || +#elif defined(__APPLE__) + !decode_to_dict(dict, "os_name", "darwin") || +#else + !decode_to_dict(dict, "os_name", "posix") || +#endif +#ifdef WITH_NEXT_FRAMEWORK + !int_to_dict(dict, "WITH_NEXT_FRAMEWORK", 1) || +#else + !int_to_dict(dict, "WITH_NEXT_FRAMEWORK", 0) || +#endif + !decode_to_dict(dict, "PREFIX", PREFIX) || + !decode_to_dict(dict, "EXEC_PREFIX", EXEC_PREFIX) || + !decode_to_dict(dict, "PYTHONPATH", PYTHONPATH) || + !decode_to_dict(dict, "VPATH", VPATH) || + !decode_to_dict(dict, "PLATLIBDIR", PLATLIBDIR) || + !decode_to_dict(dict, "PYDEBUGEXT", PYDEBUGEXT) || + !int_to_dict(dict, "VERSION_MAJOR", PY_MAJOR_VERSION) || + !int_to_dict(dict, "VERSION_MINOR", PY_MINOR_VERSION) || + !decode_to_dict(dict, "PYWINVER", PYWINVER) || + !wchar_to_dict(dict, "EXE_SUFFIX", EXE_SUFFIX) || + !env_to_dict(dict, "ENV_PATH", 0) || + !env_to_dict(dict, "ENV_PYTHONHOME", 0) || + !env_to_dict(dict, "ENV_PYTHONEXECUTABLE", 0) || + !env_to_dict(dict, "ENV___PYVENV_LAUNCHER__", 1) || + !progname_to_dict(dict, "real_executable") || + !library_to_dict(dict, "library") || + !wchar_to_dict(dict, "executable_dir", NULL) || + !wchar_to_dict(dict, "py_setpath", _PyPathConfig_GetGlobalModuleSearchPath()) || + !funcs_to_dict(dict, config->pathconfig_warnings) || +#ifndef MS_WINDOWS + PyDict_SetItemString(dict, "winreg", Py_None) < 0 || +#endif + PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins()) < 0 + ) { + Py_DECREF(co); + Py_DECREF(dict); + _PyErr_WriteUnraisableMsg("error evaluating initial values", NULL); + return PyStatus_Error("error evaluating initial values"); + } + + PyObject *r = PyEval_EvalCode(co, dict, dict); + Py_DECREF(co); + + if (!r) { + Py_DECREF(dict); + _PyErr_WriteUnraisableMsg("error evaluating path", NULL); + return PyStatus_Error("error evaluating path"); + } + Py_DECREF(r); + +#if 0 + PyObject *it = PyObject_GetIter(configDict); + for (PyObject *k = PyIter_Next(it); k; k = PyIter_Next(it)) { + if (!strcmp("__builtins__", PyUnicode_AsUTF8(k))) { + Py_DECREF(k); + continue; + } + fprintf(stderr, "%s = ", PyUnicode_AsUTF8(k)); + PyObject *o = PyDict_GetItem(configDict, k); + o = PyObject_Repr(o); + fprintf(stderr, "%s\n", PyUnicode_AsUTF8(o)); + Py_DECREF(o); + Py_DECREF(k); + } + Py_DECREF(it); +#endif + + if (_PyConfig_FromDict(config, configDict) < 0) { + _PyErr_WriteUnraisableMsg("reading getpath results", NULL); + Py_DECREF(dict); + return PyStatus_Error("error getting getpath results"); + } + + Py_DECREF(dict); + + return _PyStatus_OK(); +} + diff --git a/Modules/getpath.py b/Modules/getpath.py new file mode 100644 index 00000000000..6a088387877 --- /dev/null +++ b/Modules/getpath.py @@ -0,0 +1,796 @@ +# ****************************************************************************** +# getpath.py +# ****************************************************************************** + +# This script is designed to be precompiled to bytecode, frozen into the +# main binary, and then directly evaluated. It is not an importable module, +# and does not import any other modules (besides winreg on Windows). +# Rather, the values listed below must be specified in the globals dict +# used when evaluating the bytecode. + +# See _PyConfig_InitPathConfig in Modules/getpath.c for the execution. + +# ****************************************************************************** +# REQUIRED GLOBALS +# ****************************************************************************** + +# ** Helper functions ** +# abspath(path) -- make relative paths absolute against CWD +# basename(path) -- the filename of path +# dirname(path) -- the directory name of path +# hassuffix(path, suffix) -- returns True if path has suffix +# isabs(path) -- path is absolute or not +# isdir(path) -- path exists and is a directory +# isfile(path) -- path exists and is a file +# isxfile(path) -- path exists and is an executable file +# joinpath(*paths) -- combine the paths +# readlines(path) -- a list of each line of text in the UTF-8 encoded file +# realpath(path) -- resolves symlinks in path +# warn(message) -- print a warning (if enabled) + +# ** Values known at compile time ** +# os_name -- [in] one of 'nt', 'posix', 'darwin' +# PREFIX -- [in] sysconfig.get_config_var(...) +# EXEC_PREFIX -- [in] sysconfig.get_config_var(...) +# PYTHONPATH -- [in] sysconfig.get_config_var(...) +# WITH_NEXT_FRAMEWORK -- [in] sysconfig.get_config_var(...) +# VPATH -- [in] sysconfig.get_config_var(...) +# PLATLIBDIR -- [in] sysconfig.get_config_var(...) +# PYDEBUGEXT -- [in, opt] '_d' on Windows for debug builds +# EXE_SUFFIX -- [in, opt] '.exe' on Windows/Cygwin/similar +# VERSION_MAJOR -- [in] sys.version_info.major +# VERSION_MINOR -- [in] sys.version_info.minor +# PYWINVER -- [in] the Windows platform-specific version (e.g. 3.8-32) + +# ** Values read from the environment ** +# There is no need to check the use_environment flag before reading +# these, as the flag will be tested in this script. +# Also note that ENV_PYTHONPATH is read from config['pythonpath_env'] +# to allow for embedders who choose to specify it via that struct. +# ENV_PATH -- [in] getenv(...) +# ENV_PYTHONHOME -- [in] getenv(...) +# ENV_PYTHONEXECUTABLE -- [in] getenv(...) +# ENV___PYVENV_LAUNCHER__ -- [in] getenv(...) + +# ** Values calculated at runtime ** +# config -- [in/out] dict of the PyConfig structure +# real_executable -- [in, optional] resolved path to main process +# On Windows and macOS, read directly from the running process +# Otherwise, leave None and it will be calculated from executable +# executable_dir -- [in, optional] real directory containing binary +# If None, will be calculated from real_executable or executable +# py_setpath -- [in] argument provided to Py_SetPath +# If None, 'prefix' and 'exec_prefix' may be updated in config +# library -- [in, optional] path of dylib/DLL/so +# Only used for locating ._pth files +# winreg -- [in, optional] the winreg module (only on Windows) + +# ****************************************************************************** +# HIGH-LEVEL ALGORITHM +# ****************************************************************************** + +# IMPORTANT: The code is the actual specification at time of writing. +# This prose description is based on the original comment from the old +# getpath.c to help capture the intent, but should not be considered +# a specification. + +# Search in some common locations for the associated Python libraries. + +# Two directories must be found, the platform independent directory +# (prefix), containing the common .py and .pyc files, and the platform +# dependent directory (exec_prefix), containing the shared library +# modules. Note that prefix and exec_prefix can be the same directory, +# but for some installations, they are different. + +# This script carries out separate searches for prefix and exec_prefix. +# Each search tries a number of different locations until a ``landmark'' +# file or directory is found. If no prefix or exec_prefix is found, a +# warning message is issued and the preprocessor defined PREFIX and +# EXEC_PREFIX are used (even though they will not work); python carries on +# as best as is possible, but most imports will fail. + +# Before any searches are done, the location of the executable is +# determined. If Py_SetPath() was called, or if we are running on +# Windows, the 'real_executable' path is used (if known). Otherwise, +# we use the config-specified program name or default to argv[0]. +# If this has one or more slashes in it, it is made absolute against +# the current working directory. If it only contains a name, it must +# have been invoked from the shell's path, so we search $PATH for the +# named executable and use that. If the executable was not found on +# $PATH (or there was no $PATH environment variable), the original +# argv[0] string is used. + +# At this point, provided Py_SetPath was not used, the +# __PYVENV_LAUNCHER__ variable may override the executable (on macOS, +# the PYTHON_EXECUTABLE variable may also override). This allows +# certain launchers that run Python as a subprocess to properly +# specify the executable path. They are not intended for users. + +# Next, the executable location is examined to see if it is a symbolic +# link. If so, the link is realpath-ed and the directory of the link +# target is used for the remaining searches. The same steps are +# performed for prefix and for exec_prefix, but with different landmarks. + +# Step 1. Are we running in a virtual environment? Unless 'home' has +# been specified another way, check for a pyvenv.cfg and use its 'home' +# property to override the executable dir used later for prefix searches. +# We do not activate the venv here - that is performed later by site.py. + +# Step 2. Is there a ._pth file? A ._pth file lives adjacent to the +# runtime library (if any) or the actual executable (not the symlink), +# and contains precisely the intended contents of sys.path as relative +# paths (to its own location). Its presence also enables isolated mode +# and suppresses other environment variable usage. Unless already +# specified by Py_SetHome(), the directory containing the ._pth file is +# set as 'home'. + +# Step 3. Are we running python out of the build directory? This is +# checked by looking for the BUILDDIR_TXT file, which contains the +# relative path to the platlib dir. The executable_dir value is +# derived from joining the VPATH preprocessor variable to the +# directory containing pybuilddir.txt. If it is not found, the +# BUILD_LANDMARK file is found, which is part of the source tree. +# prefix is then found by searching up for a file that should only +# exist in the source tree, and the stdlib dir is set to prefix/Lib. + +# Step 4. If 'home' is set, either by Py_SetHome(), ENV_PYTHONHOME, +# a pyvenv.cfg file, ._pth file, or by detecting a build directory, it +# is assumed to point to prefix and exec_prefix. $PYTHONHOME can be a +# single directory, which is used for both, or the prefix and exec_prefix +# directories separated by DELIM (colon on POSIX; semicolon on Windows). + +# Step 5. Try to find prefix and exec_prefix relative to executable_dir, +# backtracking up the path until it is exhausted. This is the most common +# step to succeed. Note that if prefix and exec_prefix are different, +# exec_prefix is more likely to be found; however if exec_prefix is a +# subdirectory of prefix, both will be found. + +# Step 6. Search the directories pointed to by the preprocessor variables +# PREFIX and EXEC_PREFIX. These are supplied by the Makefile but can be +# passed in as options to the configure script. + +# That's it! + +# Well, almost. Once we have determined prefix and exec_prefix, the +# preprocessor variable PYTHONPATH is used to construct a path. Each +# relative path on PYTHONPATH is prefixed with prefix. Then the directory +# containing the shared library modules is appended. The environment +# variable $PYTHONPATH is inserted in front of it all. On POSIX, if we are +# in a build directory, both prefix and exec_prefix are reset to the +# corresponding preprocessor variables (so sys.prefix will reflect the +# installation location, even though sys.path points into the build +# directory). This seems to make more sense given that currently the only +# known use of sys.prefix and sys.exec_prefix is for the ILU installation +# process to find the installed Python tree. + +# An embedding application can use Py_SetPath() to override all of +# these automatic path computations. + + +# ****************************************************************************** +# PLATFORM CONSTANTS +# ****************************************************************************** + +platlibdir = config.get('platlibdir') or PLATLIBDIR + +if os_name == 'posix' or os_name == 'darwin': + BUILDDIR_TXT = 'pybuilddir.txt' + BUILD_LANDMARK = 'Modules/Setup.local' + DEFAULT_PROGRAM_NAME = f'python{VERSION_MAJOR}' + STDLIB_SUBDIR = f'{platlibdir}/python{VERSION_MAJOR}.{VERSION_MINOR}' + STDLIB_LANDMARKS = [f'{STDLIB_SUBDIR}/os.py', f'{STDLIB_SUBDIR}/os.pyc'] + PLATSTDLIB_LANDMARK = f'{platlibdir}/python{VERSION_MAJOR}.{VERSION_MINOR}/lib-dynload' + BUILDSTDLIB_LANDMARKS = ['Lib/os.py'] + VENV_LANDMARK = 'pyvenv.cfg' + ZIP_LANDMARK = f'{platlibdir}/python{VERSION_MAJOR}{VERSION_MINOR}.zip' + DELIM = ':' + SEP = '/' + +elif os_name == 'nt': + BUILDDIR_TXT = 'pybuilddir.txt' + BUILD_LANDMARK = f'{VPATH}\\Modules\\Setup.local' + DEFAULT_PROGRAM_NAME = f'python' + STDLIB_SUBDIR = 'Lib' + STDLIB_LANDMARKS = [f'{STDLIB_SUBDIR}\\os.py', f'{STDLIB_SUBDIR}\\os.pyc'] + PLATSTDLIB_LANDMARK = f'{platlibdir}' + BUILDSTDLIB_LANDMARKS = ['Lib\\os.py'] + VENV_LANDMARK = 'pyvenv.cfg' + ZIP_LANDMARK = f'python{VERSION_MAJOR}{VERSION_MINOR}{PYDEBUGEXT or ""}.zip' + WINREG_KEY = f'SOFTWARE\\Python\\PythonCore\\{PYWINVER}\\PythonPath' + DELIM = ';' + SEP = '\\' + + +# ****************************************************************************** +# HELPER FUNCTIONS (note that we prefer C functions for performance) +# ****************************************************************************** + +def search_up(prefix, *landmarks, test=isfile): + while prefix: + if any(test(joinpath(prefix, f)) for f in landmarks): + return prefix + prefix = dirname(prefix) + + +# ****************************************************************************** +# READ VARIABLES FROM config +# ****************************************************************************** + +program_name = config.get('program_name') +home = config.get('home') +executable = config.get('executable') +base_executable = config.get('base_executable') +prefix = config.get('prefix') +exec_prefix = config.get('exec_prefix') +base_prefix = config.get('base_prefix') +base_exec_prefix = config.get('base_exec_prefix') +ENV_PYTHONPATH = config['pythonpath_env'] +use_environment = config.get('use_environment', 1) + +pythonpath = config.get('module_search_paths') +pythonpath_was_set = config.get('module_search_paths_set') + +real_executable_dir = None +stdlib_dir = None +platstdlib_dir = None + +# ****************************************************************************** +# CALCULATE program_name +# ****************************************************************************** + +program_name_was_set = bool(program_name) + +if not program_name: + try: + program_name = config.get('orig_argv', [])[0] + except IndexError: + pass + +if not program_name: + program_name = DEFAULT_PROGRAM_NAME + +if EXE_SUFFIX and not hassuffix(program_name, EXE_SUFFIX) and isxfile(program_name + EXE_SUFFIX): + program_name = program_name + EXE_SUFFIX + + +# ****************************************************************************** +# CALCULATE executable +# ****************************************************************************** + +if py_setpath: + # When Py_SetPath has been called, executable defaults to + # the real executable path. + if not executable: + executable = real_executable + +if not executable and SEP in program_name: + # Resolve partial path program_name against current directory + executable = abspath(program_name) + +if not executable: + # All platforms default to real_executable if known at this + # stage. POSIX does not set this value. + executable = real_executable +elif os_name == 'darwin': + # QUIRK: On macOS we may know the real executable path, but + # if our caller has lied to us about it (e.g. most of + # test_embed), we need to use their path in order to detect + # whether we are in a build tree. This is true even if the + # executable path was provided in the config. + real_executable = executable + +if not executable and program_name and ENV_PATH: + # Resolve names against PATH. + # NOTE: The use_environment value is ignored for this lookup. + # To properly isolate, launch Python with a full path. + for p in ENV_PATH.split(DELIM): + p = joinpath(p, program_name) + if isxfile(p): + executable = p + break + +if not executable: + executable = '' + # When we cannot calculate the executable, subsequent searches + # look in the current working directory. Here, we emulate that + # (the former getpath.c would do it apparently by accident). + executable_dir = abspath('.') + # Also need to set this fallback in case we are running from a + # build directory with an invalid argv0 (i.e. test_sys.test_executable) + real_executable_dir = executable_dir + +if ENV_PYTHONEXECUTABLE or ENV___PYVENV_LAUNCHER__: + # If set, these variables imply that we should be using them as + # sys.executable and when searching for venvs. However, we should + # use the argv0 path for prefix calculation + + if os_name == 'darwin' and WITH_NEXT_FRAMEWORK: + # In a framework build the binary in {sys.exec_prefix}/bin is + # a stub executable that execs the real interpreter in an + # embedded app bundle. That bundle is an implementation detail + # and should not affect base_executable. + base_executable = f"{dirname(library)}/bin/python{VERSION_MAJOR}.{VERSION_MINOR}" + else: + base_executable = executable + + if not real_executable: + real_executable = base_executable + #real_executable_dir = dirname(real_executable) + executable = ENV_PYTHONEXECUTABLE or ENV___PYVENV_LAUNCHER__ + executable_dir = dirname(executable) + + +# ****************************************************************************** +# CALCULATE (default) home +# ****************************************************************************** + +# Used later to distinguish between Py_SetPythonHome and other +# ways that it may have been set +home_was_set = False + +if home: + home_was_set = True +elif use_environment and ENV_PYTHONHOME and not py_setpath: + home = ENV_PYTHONHOME + + +# ****************************************************************************** +# READ pyvenv.cfg +# ****************************************************************************** + +venv_prefix = None + +# Calling Py_SetPythonHome(), Py_SetPath() or +# setting $PYTHONHOME will override venv detection. +if not home and not py_setpath: + try: + # prefix2 is just to avoid calculating dirname again later, + # as the path in venv_prefix is the more common case. + venv_prefix2 = executable_dir or dirname(executable) + venv_prefix = dirname(venv_prefix2) + try: + # Read pyvenv.cfg from one level above executable + pyvenvcfg = readlines(joinpath(venv_prefix, VENV_LANDMARK)) + except (FileNotFoundError, PermissionError): + # Try the same directory as executable + pyvenvcfg = readlines(joinpath(venv_prefix2, VENV_LANDMARK)) + venv_prefix = venv_prefix2 + except (FileNotFoundError, PermissionError): + venv_prefix = None + pyvenvcfg = [] + + for line in pyvenvcfg: + key, had_equ, value = line.partition('=') + if had_equ and key.strip().lower() == 'home': + executable_dir = real_executable_dir = value.strip() + if not base_executable: + # First try to resolve symlinked executables, since that may be + # more accurate than assuming the executable in 'home'. + try: + base_executable = realpath(executable) + if base_executable == executable: + # No change, so probably not a link. Clear it and fall back + base_executable = '' + except OSError: + pass + if not base_executable: + base_executable = joinpath(executable_dir, basename(executable)) + # It's possible "python" is executed from within a posix venv but that + # "python" is not available in the "home" directory as the standard + # `make install` does not create it and distros often do not provide it. + # + # In this case, try to fall back to known alternatives + if os_name != 'nt' and not isfile(base_executable): + base_exe = basename(executable) + for candidate in (DEFAULT_PROGRAM_NAME, f'python{VERSION_MAJOR}.{VERSION_MINOR}'): + candidate += EXE_SUFFIX if EXE_SUFFIX else '' + if base_exe == candidate: + continue + candidate = joinpath(executable_dir, candidate) + # Only set base_executable if the candidate exists. + # If no candidate succeeds, subsequent errors related to + # base_executable (like FileNotFoundError) remain in the + # context of the original executable name + if isfile(candidate): + base_executable = candidate + break + break + else: + venv_prefix = None + + +# ****************************************************************************** +# CALCULATE base_executable, real_executable AND executable_dir +# ****************************************************************************** + +if not base_executable: + base_executable = executable or real_executable or '' + +if not real_executable: + real_executable = base_executable + +try: + real_executable = realpath(real_executable) +except OSError as ex: + # Only warn if the file actually exists and was unresolvable + # Otherwise users who specify a fake executable may get spurious warnings. + if isfile(real_executable): + warn(f'Failed to find real location of {base_executable}') + +if not executable_dir and os_name == 'darwin' and library: + # QUIRK: macOS checks adjacent to its library early + library_dir = dirname(library) + if any(isfile(joinpath(library_dir, p)) for p in STDLIB_LANDMARKS): + # Exceptions here should abort the whole process (to match + # previous behavior) + executable_dir = realpath(library_dir) + real_executable_dir = executable_dir + +# If we do not have the executable's directory, we can calculate it. +# This is the directory used to find prefix/exec_prefix if necessary. +if not executable_dir: + executable_dir = real_executable_dir = dirname(real_executable) + +# If we do not have the real executable's directory, we calculate it. +# This is the directory used to detect build layouts. +if not real_executable_dir: + real_executable_dir = dirname(real_executable) + +# ****************************************************************************** +# DETECT _pth FILE +# ****************************************************************************** + +# The contents of an optional ._pth file are used to totally override +# sys.path calculation. Its presence also implies isolated mode and +# no-site (unless explicitly requested) +pth = None +pth_dir = None + +# Calling Py_SetPythonHome() or Py_SetPath() will override ._pth search, +# but environment variables and command-line options cannot. +if not py_setpath and not home_was_set: + # 1. Check adjacent to the main DLL/dylib/so (if set) + # 2. Check adjacent to the original executable + # 3. Check adjacent to our actual executable + # This may allow a venv to override the base_executable's + # ._pth file, but it cannot override the library's one. + for p in [library, executable, real_executable]: + if p: + if os_name == 'nt' and (hassuffix(p, 'exe') or hassuffix(p, 'dll')): + p = p.rpartition('.')[0] + p += '._pth' + try: + pth = readlines(p) + pth_dir = dirname(p) + break + except OSError: + pass + + # If we found a ._pth file, disable environment and home + # detection now. Later, we will do the rest. + if pth_dir: + use_environment = 0 + home = pth_dir + pythonpath = [] + + +# ****************************************************************************** +# CHECK FOR BUILD DIRECTORY +# ****************************************************************************** + +build_prefix = None + +if ((not home_was_set and real_executable_dir and not py_setpath) + or config.get('_is_python_build', 0) > 0): + # Detect a build marker and use it to infer prefix, exec_prefix, + # stdlib_dir and the platstdlib_dir directories. + try: + platstdlib_dir = joinpath( + real_executable_dir, + readlines(joinpath(real_executable_dir, BUILDDIR_TXT))[0], + ) + build_prefix = joinpath(real_executable_dir, VPATH) + except IndexError: + # File exists but is empty + platstdlib_dir = real_executable_dir + build_prefix = joinpath(real_executable_dir, VPATH) + except (FileNotFoundError, PermissionError): + if isfile(joinpath(real_executable_dir, BUILD_LANDMARK)): + build_prefix = joinpath(real_executable_dir, VPATH) + if os_name == 'nt': + # QUIRK: Windows builds need platstdlib_dir to be the executable + # dir. Normally the builddir marker handles this, but in this + # case we need to correct manually. + platstdlib_dir = real_executable_dir + + if build_prefix: + if os_name == 'nt': + # QUIRK: No searching for more landmarks on Windows + build_stdlib_prefix = build_prefix + else: + build_stdlib_prefix = search_up(build_prefix, *BUILDSTDLIB_LANDMARKS) + # Always use the build prefix for stdlib + if build_stdlib_prefix: + stdlib_dir = joinpath(build_stdlib_prefix, 'Lib') + else: + stdlib_dir = joinpath(build_prefix, 'Lib') + # Only use the build prefix for prefix if it hasn't already been set + if not prefix: + prefix = build_stdlib_prefix + # Do not warn, because 'prefix' never equals 'build_prefix' on POSIX + #elif not venv_prefix and prefix != build_prefix: + # warn('Detected development environment but prefix is already set') + if not exec_prefix: + exec_prefix = build_prefix + # Do not warn, because 'exec_prefix' never equals 'build_prefix' on POSIX + #elif not venv_prefix and exec_prefix != build_prefix: + # warn('Detected development environment but exec_prefix is already set') + config['_is_python_build'] = 1 + + +# ****************************************************************************** +# CALCULATE prefix AND exec_prefix +# ****************************************************************************** + +if py_setpath: + # As documented, calling Py_SetPath will force both prefix + # and exec_prefix to the empty string. + prefix = exec_prefix = '' + +else: + # Read prefix and exec_prefix from explicitly set home + if home: + # When multiple paths are listed with ':' or ';' delimiters, + # split into prefix:exec_prefix + prefix, had_delim, exec_prefix = home.partition(DELIM) + if not had_delim: + exec_prefix = prefix + # Reset the standard library directory if it was already set + stdlib_dir = None + + + # First try to detect prefix by looking alongside our runtime library, if known + if library and not prefix: + library_dir = dirname(library) + if ZIP_LANDMARK: + if os_name == 'nt': + # QUIRK: Windows does not search up for ZIP file + if isfile(joinpath(library_dir, ZIP_LANDMARK)): + prefix = library_dir + else: + prefix = search_up(library_dir, ZIP_LANDMARK) + if STDLIB_SUBDIR and STDLIB_LANDMARKS and not prefix: + if any(isfile(joinpath(library_dir, f)) for f in STDLIB_LANDMARKS): + prefix = library_dir + stdlib_dir = joinpath(prefix, STDLIB_SUBDIR) + + + # Detect prefix by looking for zip file + if ZIP_LANDMARK and executable_dir and not prefix: + if os_name == 'nt': + # QUIRK: Windows does not search up for ZIP file + if isfile(joinpath(executable_dir, ZIP_LANDMARK)): + prefix = executable_dir + else: + prefix = search_up(executable_dir, ZIP_LANDMARK) + if prefix: + stdlib_dir = joinpath(prefix, STDLIB_SUBDIR) + if not isdir(stdlib_dir): + stdlib_dir = None + + + # Detect prefix by searching from our executable location for the stdlib_dir + if STDLIB_SUBDIR and STDLIB_LANDMARKS and executable_dir and not prefix: + prefix = search_up(executable_dir, *STDLIB_LANDMARKS) + if prefix: + stdlib_dir = joinpath(prefix, STDLIB_SUBDIR) + + if PREFIX and not prefix: + prefix = PREFIX + if not any(isfile(joinpath(prefix, f)) for f in STDLIB_LANDMARKS): + warn('Could not find platform independent libraries ') + + if not prefix: + prefix = abspath('') + warn('Could not find platform independent libraries ') + + + # Detect exec_prefix by searching from executable for the platstdlib_dir + if PLATSTDLIB_LANDMARK and not exec_prefix: + if os_name == 'nt': + # QUIRK: Windows always assumed these were the same + # gh-100320: Our PYDs are assumed to be relative to the Lib directory + # (that is, prefix) rather than the executable (that is, executable_dir) + exec_prefix = prefix + if not exec_prefix and executable_dir: + exec_prefix = search_up(executable_dir, PLATSTDLIB_LANDMARK, test=isdir) + if not exec_prefix and EXEC_PREFIX: + exec_prefix = EXEC_PREFIX + if not exec_prefix or not isdir(joinpath(exec_prefix, PLATSTDLIB_LANDMARK)): + if os_name == 'nt': + # QUIRK: If DLLs is missing on Windows, don't warn, just assume + # that they're in exec_prefix + if not platstdlib_dir: + # gh-98790: We set platstdlib_dir here to avoid adding "DLLs" into + # sys.path when it doesn't exist in the platstdlib place, which + # would give Lib packages precedence over executable_dir where our + # PYDs *probably* live. Ideally, whoever changes our layout will tell + # us what the layout is, but in the past this worked, so it should + # keep working. + platstdlib_dir = exec_prefix + else: + warn('Could not find platform dependent libraries ') + + + # Fallback: assume exec_prefix == prefix + if not exec_prefix: + exec_prefix = prefix + + + if not prefix or not exec_prefix: + warn('Consider setting $PYTHONHOME to [:]') + + +# If we haven't set [plat]stdlib_dir already, set them now +if not stdlib_dir: + if prefix: + stdlib_dir = joinpath(prefix, STDLIB_SUBDIR) + else: + stdlib_dir = '' + +if not platstdlib_dir: + if exec_prefix: + platstdlib_dir = joinpath(exec_prefix, PLATSTDLIB_LANDMARK) + else: + platstdlib_dir = '' + + +# For a venv, update the main prefix/exec_prefix but leave the base ones unchanged +# XXX: We currently do not update prefix here, but it happens in site.py +#if venv_prefix: +# base_prefix = prefix +# base_exec_prefix = exec_prefix +# prefix = exec_prefix = venv_prefix + + +# ****************************************************************************** +# UPDATE pythonpath (sys.path) +# ****************************************************************************** + +if py_setpath: + # If Py_SetPath was called then it overrides any existing search path + config['module_search_paths'] = py_setpath.split(DELIM) + config['module_search_paths_set'] = 1 + +elif not pythonpath_was_set: + # If pythonpath was already explicitly set or calculated, we leave it alone. + # This won't matter in normal use, but if an embedded host is trying to + # recalculate paths while running then we do not want to change it. + pythonpath = [] + + # First add entries from the process environment + if use_environment and ENV_PYTHONPATH: + for p in ENV_PYTHONPATH.split(DELIM): + pythonpath.append(abspath(p)) + + # Then add the default zip file + if os_name == 'nt': + # QUIRK: Windows uses the library directory rather than the prefix + if library: + library_dir = dirname(library) + else: + library_dir = executable_dir + pythonpath.append(joinpath(library_dir, ZIP_LANDMARK)) + elif build_prefix: + # QUIRK: POSIX uses the default prefix when in the build directory + pythonpath.append(joinpath(PREFIX, ZIP_LANDMARK)) + else: + pythonpath.append(joinpath(prefix, ZIP_LANDMARK)) + + if os_name == 'nt' and use_environment and winreg: + # QUIRK: Windows also lists paths in the registry. Paths are stored + # as the default value of each subkey of + # {HKCU,HKLM}\Software\Python\PythonCore\{winver}\PythonPath + # where winver is sys.winver (typically '3.x' or '3.x-32') + for hk in (winreg.HKEY_CURRENT_USER, winreg.HKEY_LOCAL_MACHINE): + try: + key = winreg.OpenKeyEx(hk, WINREG_KEY) + try: + i = 0 + while True: + try: + v = winreg.QueryValue(key, winreg.EnumKey(key, i)) + except OSError: + break + if isinstance(v, str): + pythonpath.extend(v.split(DELIM)) + i += 1 + # Paths from the core key get appended last, but only + # when home was not set and we aren't in a build dir + if not home_was_set and not venv_prefix and not build_prefix: + v = winreg.QueryValue(key, None) + if isinstance(v, str): + pythonpath.extend(v.split(DELIM)) + finally: + winreg.CloseKey(key) + except OSError: + pass + + # Then add any entries compiled into the PYTHONPATH macro. + if PYTHONPATH: + for p in PYTHONPATH.split(DELIM): + pythonpath.append(joinpath(prefix, p)) + + # Then add stdlib_dir and platstdlib_dir + if os_name == 'nt': + # QUIRK: Windows generates paths differently + if platstdlib_dir: + pythonpath.append(platstdlib_dir) + if stdlib_dir: + pythonpath.append(stdlib_dir) + if executable_dir and executable_dir not in pythonpath: + # QUIRK: the executable directory is on sys.path + # We keep it low priority, so that properly installed modules are + # found first. It may be earlier in the order if we found some + # reason to put it there. + pythonpath.append(executable_dir) + else: + if stdlib_dir: + pythonpath.append(stdlib_dir) + if platstdlib_dir: + pythonpath.append(platstdlib_dir) + + config['module_search_paths'] = pythonpath + config['module_search_paths_set'] = 1 + + +# ****************************************************************************** +# POSIX prefix/exec_prefix QUIRKS +# ****************************************************************************** + +# QUIRK: Non-Windows replaces prefix/exec_prefix with defaults when running +# in build directory. This happens after pythonpath calculation. +if os_name != 'nt' and build_prefix: + prefix = config.get('prefix') or PREFIX + exec_prefix = config.get('exec_prefix') or EXEC_PREFIX or prefix + + +# ****************************************************************************** +# SET pythonpath FROM _PTH FILE +# ****************************************************************************** + +if pth: + config['isolated'] = 1 + config['use_environment'] = 0 + config['site_import'] = 0 + config['safe_path'] = 1 + pythonpath = [] + for line in pth: + line = line.partition('#')[0].strip() + if not line: + pass + elif line == 'import site': + config['site_import'] = 1 + elif line.startswith('import '): + warn("unsupported 'import' line in ._pth file") + else: + pythonpath.append(joinpath(pth_dir, line)) + config['module_search_paths'] = pythonpath + config['module_search_paths_set'] = 1 + +# ****************************************************************************** +# UPDATE config FROM CALCULATED VALUES +# ****************************************************************************** + +config['program_name'] = program_name +config['home'] = home +config['executable'] = executable +config['base_executable'] = base_executable +config['prefix'] = prefix +config['exec_prefix'] = exec_prefix +config['base_prefix'] = base_prefix or prefix +config['base_exec_prefix'] = base_exec_prefix or exec_prefix + +config['platlibdir'] = platlibdir +config['stdlib_dir'] = stdlib_dir +config['platstdlib_dir'] = platstdlib_dir diff --git a/Modules/getpath_noop.c b/Modules/getpath_noop.c new file mode 100644 index 00000000000..c10e41d07f2 --- /dev/null +++ b/Modules/getpath_noop.c @@ -0,0 +1,10 @@ +/* Implements the getpath API for compiling with no functionality */ + +#include "Python.h" +#include "pycore_pathconfig.h" + +PyStatus +_PyConfig_InitPathConfig(PyConfig *config, int compute_path_config) +{ + return PyStatus_Error("path configuration is unsupported"); +} diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 342a3e6555b..c1f1e7320db 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -16,6 +16,7 @@ class itertools.groupby "groupbyobject *" "&groupby_type" class itertools._grouper "_grouperobject *" "&_grouper_type" class itertools.teedataobject "teedataobject *" "&teedataobject_type" class itertools._tee "teeobject *" "&tee_type" +class itertools.batched "batchedobject *" "&batched_type" class itertools.cycle "cycleobject *" "&cycle_type" class itertools.dropwhile "dropwhileobject *" "&dropwhile_type" class itertools.takewhile "takewhileobject *" "&takewhile_type" @@ -30,12 +31,13 @@ class itertools.filterfalse "filterfalseobject *" "&filterfalse_type" class itertools.count "countobject *" "&count_type" class itertools.pairwise "pairwiseobject *" "&pairwise_type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6498ed21fbe1bf94]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1168b274011ce21b]*/ static PyTypeObject groupby_type; static PyTypeObject _grouper_type; static PyTypeObject teedataobject_type; static PyTypeObject tee_type; +static PyTypeObject batched_type; static PyTypeObject cycle_type; static PyTypeObject dropwhile_type; static PyTypeObject takewhile_type; @@ -51,6 +53,184 @@ static PyTypeObject pairwise_type; #include "clinic/itertoolsmodule.c.h" +/* batched object ************************************************************/ + +/* Note: The built-in zip() function includes a "strict" argument + that was needed because that function would silently truncate data, + and there was no easy way for a user to detect the data loss. + The same reasoning does not apply to batched() which never drops data. + Instead, batched() produces a shorter tuple which can be handled + as the user sees fit. If requested, it would be reasonable to add + "fillvalue" support which had demonstrated value in zip_longest(). + For now, the API is kept simple and clean. + */ + +typedef struct { + PyObject_HEAD + PyObject *it; + Py_ssize_t batch_size; +} batchedobject; + +/*[clinic input] +@classmethod +itertools.batched.__new__ as batched_new + iterable: object + n: Py_ssize_t +Batch data into tuples of length n. The last batch may be shorter than n. + +Loops over the input iterable and accumulates data into tuples +up to size n. The input is consumed lazily, just enough to +fill a batch. The result is yielded as soon as a batch is full +or when the input iterable is exhausted. + + >>> for batch in batched('ABCDEFG', 3): + ... print(batch) + ... + ('A', 'B', 'C') + ('D', 'E', 'F') + ('G',) + +[clinic start generated code]*/ + +static PyObject * +batched_new_impl(PyTypeObject *type, PyObject *iterable, Py_ssize_t n) +/*[clinic end generated code: output=7ebc954d655371b6 input=ffd70726927c5129]*/ +{ + PyObject *it; + batchedobject *bo; + + if (n < 1) { + /* We could define the n==0 case to return an empty iterator + but that is at odds with the idea that batching should + never throw-away input data. + */ + PyErr_SetString(PyExc_ValueError, "n must be at least one"); + return NULL; + } + it = PyObject_GetIter(iterable); + if (it == NULL) { + return NULL; + } + + /* create batchedobject structure */ + bo = (batchedobject *)type->tp_alloc(type, 0); + if (bo == NULL) { + Py_DECREF(it); + return NULL; + } + bo->batch_size = n; + bo->it = it; + return (PyObject *)bo; +} + +static void +batched_dealloc(batchedobject *bo) +{ + PyObject_GC_UnTrack(bo); + Py_XDECREF(bo->it); + Py_TYPE(bo)->tp_free(bo); +} + +static int +batched_traverse(batchedobject *bo, visitproc visit, void *arg) +{ + if (bo->it != NULL) { + Py_VISIT(bo->it); + } + return 0; +} + +static PyObject * +batched_next(batchedobject *bo) +{ + Py_ssize_t i; + Py_ssize_t n = bo->batch_size; + PyObject *it = bo->it; + PyObject *item; + PyObject *result; + + if (it == NULL) { + return NULL; + } + result = PyTuple_New(n); + if (result == NULL) { + return NULL; + } + iternextfunc iternext = *Py_TYPE(it)->tp_iternext; + PyObject **items = _PyTuple_ITEMS(result); + for (i=0 ; i < n ; i++) { + item = iternext(it); + if (item == NULL) { + goto null_item; + } + items[i] = item; + } + return result; + + null_item: + if (PyErr_Occurred()) { + if (!PyErr_ExceptionMatches(PyExc_StopIteration)) { + /* Input raised an exception other than StopIteration */ + Py_CLEAR(bo->it); + Py_DECREF(result); + return NULL; + } + PyErr_Clear(); + } + if (i == 0) { + Py_CLEAR(bo->it); + Py_DECREF(result); + return NULL; + } + _PyTuple_Resize(&result, i); + return result; +} + +static PyTypeObject batched_type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "itertools.batched", /* tp_name */ + sizeof(batchedobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)batched_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + batched_new__doc__, /* tp_doc */ + (traverseproc)batched_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)batched_next, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + batched_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; + + /* pairwise object ***********************************************************/ typedef struct { @@ -222,8 +402,7 @@ itertools_groupby_impl(PyTypeObject *type, PyObject *it, PyObject *keyfunc) gbo->tgtkey = NULL; gbo->currkey = NULL; gbo->currvalue = NULL; - gbo->keyfunc = keyfunc; - Py_INCREF(keyfunc); + gbo->keyfunc = Py_NewRef(keyfunc); gbo->it = PyObject_GetIter(it); if (gbo->it == NULL) { Py_DECREF(gbo); @@ -265,8 +444,7 @@ groupby_step(groupbyobject *gbo) return -1; if (gbo->keyfunc == Py_None) { - newkey = newvalue; - Py_INCREF(newvalue); + newkey = Py_NewRef(newvalue); } else { newkey = PyObject_CallOneArg(gbo->keyfunc, newvalue); if (newkey == NULL) { @@ -446,10 +624,8 @@ _grouper_create(groupbyobject *parent, PyObject *tgtkey) igo = PyObject_GC_New(_grouperobject, &_grouper_type); if (igo == NULL) return NULL; - igo->parent = (PyObject *)parent; - Py_INCREF(parent); - igo->tgtkey = tgtkey; - Py_INCREF(tgtkey); + igo->parent = Py_NewRef(parent); + igo->tgtkey = Py_NewRef(tgtkey); parent->currgrouper = igo; /* borrowed reference */ PyObject_GC_Track(igo); @@ -503,9 +679,8 @@ _grouper_next(_grouperobject *igo) static PyObject * _grouper_reduce(_grouperobject *lz, PyObject *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(iter); if (((groupbyobject *)lz->parent)->currgrouper != lz) { - return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter)); + return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter))); } return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->parent, lz->tgtkey); } @@ -601,8 +776,7 @@ teedataobject_newinternal(PyObject *it) tdo->running = 0; tdo->numread = 0; tdo->nextlink = NULL; - Py_INCREF(it); - tdo->it = it; + tdo->it = Py_NewRef(it); PyObject_GC_Track(tdo); return (PyObject *)tdo; } @@ -612,8 +786,7 @@ teedataobject_jumplink(teedataobject *tdo) { if (tdo->nextlink == NULL) tdo->nextlink = teedataobject_newinternal(tdo->it); - Py_XINCREF(tdo->nextlink); - return tdo->nextlink; + return Py_XNewRef(tdo->nextlink); } static PyObject * @@ -640,8 +813,7 @@ teedataobject_getitem(teedataobject *tdo, int i) tdo->numread++; tdo->values[i] = value; } - Py_INCREF(value); - return value; + return Py_NewRef(value); } static int @@ -663,8 +835,7 @@ teedataobject_safe_decref(PyObject *obj) Py_REFCNT(obj) == 1) { PyObject *nextlink = ((teedataobject *)obj)->nextlink; ((teedataobject *)obj)->nextlink = NULL; - Py_DECREF(obj); - obj = nextlink; + Py_SETREF(obj, nextlink); } Py_XDECREF(obj); } @@ -749,8 +920,7 @@ itertools_teedataobject_impl(PyTypeObject *type, PyObject *it, if (!Py_IS_TYPE(next, &teedataobject_type)) goto err; assert(tdo->nextlink == NULL); - Py_INCREF(next); - tdo->nextlink = next; + tdo->nextlink = Py_NewRef(next); } } else { if (next != Py_None) @@ -848,8 +1018,7 @@ tee_copy(teeobject *to, PyObject *Py_UNUSED(ignored)) newto = PyObject_GC_New(teeobject, &tee_type); if (newto == NULL) return NULL; - Py_INCREF(to->dataobj); - newto->dataobj = to->dataobj; + newto->dataobj = (teedataobject*)Py_NewRef(to->dataobj); newto->index = to->index; newto->weakreflist = NULL; PyObject_GC_Track(newto); @@ -1015,7 +1184,6 @@ itertools_tee_impl(PyObject *module, PyObject *iterable, Py_ssize_t n) { Py_ssize_t i; PyObject *it, *copyable, *copyfunc, *result; - _Py_IDENTIFIER(__copy__); if (n < 0) { PyErr_SetString(PyExc_ValueError, "n must be >= 0"); @@ -1032,7 +1200,7 @@ itertools_tee_impl(PyObject *module, PyObject *iterable, Py_ssize_t n) return NULL; } - if (_PyObject_LookupAttrId(it, &PyId___copy__, ©func) < 0) { + if (_PyObject_LookupAttr(it, &_Py_ID(__copy__), ©func) < 0) { Py_DECREF(it); Py_DECREF(result); return NULL; @@ -1047,7 +1215,7 @@ itertools_tee_impl(PyObject *module, PyObject *iterable, Py_ssize_t n) Py_DECREF(result); return NULL; } - copyfunc = _PyObject_GetAttrId(copyable, &PyId___copy__); + copyfunc = PyObject_GetAttr(copyable, &_Py_ID(__copy__)); if (copyfunc == NULL) { Py_DECREF(copyable); Py_DECREF(result); @@ -1166,8 +1334,7 @@ cycle_next(cycleobject *lz) lz->index++; if (lz->index >= PyList_GET_SIZE(lz->saved)) lz->index = 0; - Py_INCREF(item); - return item; + return Py_NewRef(item); } static PyObject * @@ -1179,9 +1346,8 @@ cycle_reduce(cycleobject *lz, PyObject *Py_UNUSED(ignored)) if (it == NULL) return NULL; if (lz->index != 0) { - _Py_IDENTIFIER(__setstate__); - PyObject *res = _PyObject_CallMethodId(it, &PyId___setstate__, - "n", lz->index); + PyObject *res = _PyObject_CallMethod(it, &_Py_ID(__setstate__), + "n", lz->index); if (res == NULL) { Py_DECREF(it); return NULL; @@ -1203,6 +1369,7 @@ cycle_setstate(cycleobject *lz, PyObject *state) PyErr_SetString(PyExc_TypeError, "state is not a tuple"); return NULL; } + // The second item can be 1/0 in old pickles and True/False in new pickles if (!PyArg_ParseTuple(state, "O!i", &PyList_Type, &saved, &firstpass)) { return NULL; } @@ -1304,8 +1471,7 @@ itertools_dropwhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq) Py_DECREF(it); return NULL; } - Py_INCREF(func); - lz->func = func; + lz->func = Py_NewRef(func); lz->it = it; lz->start = 0; @@ -1467,8 +1633,7 @@ itertools_takewhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq) Py_DECREF(it); return NULL; } - Py_INCREF(func); - lz->func = func; + lz->func = Py_NewRef(func); lz->it = it; lz->stop = 0; @@ -1764,8 +1929,7 @@ islice_reduce(isliceobject *lz, PyObject *Py_UNUSED(ignored)) return Py_BuildValue("O(Nn)n", Py_TYPE(lz), empty_it, 0, 0); } if (lz->stop == -1) { - stop = Py_None; - Py_INCREF(stop); + stop = Py_NewRef(Py_None); } else { stop = PyLong_FromSsize_t(lz->stop); if (stop == NULL) @@ -1886,8 +2050,7 @@ itertools_starmap_impl(PyTypeObject *type, PyObject *func, PyObject *seq) Py_DECREF(it); return NULL; } - Py_INCREF(func); - lz->func = func; + lz->func = Py_NewRef(func); lz->it = it; return (PyObject *)lz; @@ -2323,11 +2486,9 @@ product_dealloc(productobject *lz) static PyObject * product_sizeof(productobject *lz, void *unused) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(lz)); - res += PyTuple_GET_SIZE(lz->pools) * sizeof(Py_ssize_t); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(lz)); + res += (size_t)PyTuple_GET_SIZE(lz->pools) * sizeof(Py_ssize_t); + return PyLong_FromSize_t(res); } PyDoc_STRVAR(sizeof_doc, "Returns size in memory, in bytes."); @@ -2419,8 +2580,7 @@ product_next(productobject *lz) goto empty; } - Py_INCREF(result); - return result; + return Py_NewRef(result); empty: lz->stopped = 1; @@ -2657,11 +2817,9 @@ combinations_dealloc(combinationsobject *co) static PyObject * combinations_sizeof(combinationsobject *co, void *unused) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(co)); - res += co->r * sizeof(Py_ssize_t); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(co)); + res += (size_t)co->r * sizeof(Py_ssize_t); + return PyLong_FromSize_t(res); } static int @@ -2750,8 +2908,7 @@ combinations_next(combinationsobject *co) } } - Py_INCREF(result); - return result; + return Py_NewRef(result); empty: co->stopped = 1; @@ -2927,14 +3084,14 @@ itertools.combinations_with_replacement.__new__ r: Py_ssize_t Return successive r-length combinations of elements in the iterable allowing individual elements to have successive repeats. -combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC" +combinations_with_replacement('ABC', 2) --> ('A','A'), ('A','B'), ('A','C'), ('B','B'), ('B','C'), ('C','C') [clinic start generated code]*/ static PyObject * itertools_combinations_with_replacement_impl(PyTypeObject *type, PyObject *iterable, Py_ssize_t r) -/*[clinic end generated code: output=48b26856d4e659ca input=dc2a8c7ba785fad7]*/ +/*[clinic end generated code: output=48b26856d4e659ca input=1dc58e82a0878fdc]*/ { cwrobject *co; Py_ssize_t n; @@ -2994,11 +3151,9 @@ cwr_dealloc(cwrobject *co) static PyObject * cwr_sizeof(cwrobject *co, void *unused) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(co)); - res += co->r * sizeof(Py_ssize_t); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(co)); + res += (size_t)co->r * sizeof(Py_ssize_t); + return PyLong_FromSize_t(res); } static int @@ -3081,8 +3236,7 @@ cwr_next(cwrobject *co) } } - Py_INCREF(result); - return result; + return Py_NewRef(result); empty: co->stopped = 1; @@ -3340,12 +3494,10 @@ permutations_dealloc(permutationsobject *po) static PyObject * permutations_sizeof(permutationsobject *po, void *unused) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(po)); - res += PyTuple_GET_SIZE(po->pool) * sizeof(Py_ssize_t); - res += po->r * sizeof(Py_ssize_t); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(po)); + res += (size_t)PyTuple_GET_SIZE(po->pool) * sizeof(Py_ssize_t); + res += (size_t)po->r * sizeof(Py_ssize_t); + return PyLong_FromSize_t(res); } static int @@ -3439,8 +3591,7 @@ permutations_next(permutationsobject *po) if (i < 0) goto empty; } - Py_INCREF(result); - return result; + return Py_NewRef(result); empty: po->stopped = 1; @@ -3643,13 +3794,11 @@ itertools_accumulate_impl(PyTypeObject *type, PyObject *iterable, } if (binop != Py_None) { - Py_XINCREF(binop); - lz->binop = binop; + lz->binop = Py_XNewRef(binop); } lz->total = NULL; lz->it = it; - Py_XINCREF(initial); - lz->initial = initial; + lz->initial = Py_XNewRef(initial); return (PyObject *)lz; } @@ -3681,18 +3830,15 @@ accumulate_next(accumulateobject *lz) if (lz->initial != Py_None) { lz->total = lz->initial; - Py_INCREF(Py_None); - lz->initial = Py_None; - Py_INCREF(lz->total); - return lz->total; + lz->initial = Py_NewRef(Py_None); + return Py_NewRef(lz->total); } val = (*Py_TYPE(lz->it)->tp_iternext)(lz->it); if (val == NULL) return NULL; if (lz->total == NULL) { - Py_INCREF(val); - lz->total = val; + lz->total = Py_NewRef(val); return lz->total; } @@ -4010,8 +4156,7 @@ itertools_filterfalse_impl(PyTypeObject *type, PyObject *func, PyObject *seq) Py_DECREF(it); return NULL; } - Py_INCREF(func); - lz->func = func; + lz->func = Py_NewRef(func); lz->it = it; return (PyObject *)lz; @@ -4405,8 +4550,7 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ro = (repeatobject *)type->tp_alloc(type, 0); if (ro == NULL) return NULL; - Py_INCREF(element); - ro->element = element; + ro->element = Py_NewRef(element); ro->cnt = cnt; return (PyObject *)ro; } @@ -4433,8 +4577,7 @@ repeat_next(repeatobject *ro) return NULL; if (ro->cnt > 0) ro->cnt--; - Py_INCREF(ro->element); - return ro->element; + return Py_NewRef(ro->element); } static PyObject * @@ -4545,7 +4688,6 @@ static PyTypeObject ziplongest_type; static PyObject * zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - _Py_IDENTIFIER(fillvalue); ziplongestobject *lz; Py_ssize_t i; PyObject *ittuple; /* tuple of iterators */ @@ -4556,7 +4698,7 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (kwds != NULL && PyDict_CheckExact(kwds) && PyDict_GET_SIZE(kwds) > 0) { fillvalue = NULL; if (PyDict_GET_SIZE(kwds) == 1) { - fillvalue = _PyDict_GetItemIdWithError(kwds, &PyId_fillvalue); + fillvalue = PyDict_GetItemWithError(kwds, &_Py_ID(fillvalue)); } if (fillvalue == NULL) { if (!PyErr_Occurred()) { @@ -4607,8 +4749,7 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) lz->tuplesize = tuplesize; lz->numactive = tuplesize; lz->result = result; - Py_INCREF(fillvalue); - lz->fillvalue = fillvalue; + lz->fillvalue = Py_NewRef(fillvalue); return (PyObject *)lz; } @@ -4650,8 +4791,7 @@ zip_longest_next(ziplongestobject *lz) for (i=0 ; i < tuplesize ; i++) { it = PyTuple_GET_ITEM(lz->ittuple, i); if (it == NULL) { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + item = Py_NewRef(lz->fillvalue); } else { item = PyIter_Next(it); if (item == NULL) { @@ -4661,8 +4801,7 @@ zip_longest_next(ziplongestobject *lz) Py_DECREF(result); return NULL; } else { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + item = Py_NewRef(lz->fillvalue); PyTuple_SET_ITEM(lz->ittuple, i, NULL); Py_DECREF(it); } @@ -4684,8 +4823,7 @@ zip_longest_next(ziplongestobject *lz) for (i=0 ; i < tuplesize ; i++) { it = PyTuple_GET_ITEM(lz->ittuple, i); if (it == NULL) { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + item = Py_NewRef(lz->fillvalue); } else { item = PyIter_Next(it); if (item == NULL) { @@ -4695,8 +4833,7 @@ zip_longest_next(ziplongestobject *lz) Py_DECREF(result); return NULL; } else { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + item = Py_NewRef(lz->fillvalue); PyTuple_SET_ITEM(lz->ittuple, i, NULL); Py_DECREF(it); } @@ -4819,6 +4956,7 @@ repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\ \n\ Iterators terminating on the shortest input sequence:\n\ accumulate(p[, func]) --> p0, p0+p1, p0+p1+p2\n\ +batched(p, n) --> [p0, p1, ..., p_n-1], [p_n, p_n+1, ..., p_2n-1], ...\n\ chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...\n\ chain.from_iterable([p, q, ...]) --> p0, p1, ... plast, q0, q1, ...\n\ compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...\n\ @@ -4845,6 +4983,7 @@ itertoolsmodule_exec(PyObject *m) { PyTypeObject *typelist[] = { &accumulate_type, + &batched_type, &combinations_type, &cwr_type, &cycle_type, diff --git a/Modules/main.c b/Modules/main.c index c537e6b6785..7edfeb3365b 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -158,11 +158,10 @@ error: static int pymain_sys_path_add_path0(PyInterpreterState *interp, PyObject *path0) { - _Py_IDENTIFIER(path); PyObject *sys_path; PyObject *sysdict = interp->sysdict; if (sysdict != NULL) { - sys_path = _PyDict_GetItemIdWithError(sysdict, &PyId_path); + sys_path = PyDict_GetItemWithError(sysdict, &_Py_ID(path)); if (sys_path == NULL && PyErr_Occurred()) { return -1; } @@ -220,6 +219,13 @@ pymain_import_readline(const PyConfig *config) else { Py_DECREF(mod); } + mod = PyImport_ImportModule("rlcompleter"); + if (mod == NULL) { + PyErr_Clear(); + } + else { + Py_DECREF(mod); + } } @@ -290,10 +296,10 @@ pymain_run_module(const wchar_t *modname, int set_argv0) Py_DECREF(module); return pymain_exit_err_print(); } - _Py_UnhandledKeyboardInterrupt = 0; + _PyRuntime.signals.unhandled_keyboard_interrupt = 0; result = PyObject_Call(runmodule, runargs, NULL); if (!result && PyErr_Occurred() == PyExc_KeyboardInterrupt) { - _Py_UnhandledKeyboardInterrupt = 1; + _PyRuntime.signals.unhandled_keyboard_interrupt = 1; } Py_DECREF(runpy); Py_DECREF(runmodule); @@ -473,12 +479,23 @@ error: } +static void +pymain_set_inspect(PyConfig *config, int inspect) +{ + config->inspect = inspect; +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS + Py_InspectFlag = inspect; +_Py_COMP_DIAG_POP +} + + static int pymain_run_stdin(PyConfig *config) { if (stdin_is_interactive(config)) { - config->inspect = 0; - Py_InspectFlag = 0; /* do exit on SystemExit */ + // do exit on SystemExit + pymain_set_inspect(config, 0); int exitcode; if (pymain_run_startup(config, &exitcode)) { @@ -511,16 +528,14 @@ pymain_repl(PyConfig *config, int *exitcode) /* Check this environment variable at the end, to give programs the opportunity to set it from Python. */ if (!config->inspect && _Py_GetEnv(config->use_environment, "PYTHONINSPECT")) { - config->inspect = 1; - Py_InspectFlag = 1; + pymain_set_inspect(config, 1); } if (!(config->inspect && stdin_is_interactive(config) && config_run_code(config))) { return; } - config->inspect = 0; - Py_InspectFlag = 0; + pymain_set_inspect(config, 0); if (pymain_run_interactive_hook(exitcode)) { return; } @@ -534,11 +549,16 @@ pymain_repl(PyConfig *config, int *exitcode) static void pymain_run_python(int *exitcode) { + PyObject *main_importer_path = NULL; PyInterpreterState *interp = _PyInterpreterState_GET(); /* pymain_run_stdin() modify the config */ PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp); - PyObject *main_importer_path = NULL; + /* ensure path config is written into global variables */ + if (_PyStatus_EXCEPTION(_PyPathConfig_UpdateGlobal(config))) { + goto error; + } + if (config->run_filename != NULL) { /* If filename is a package (ex: directory or ZIP file) which contains __main__.py, main_importer_path is set to filename and will be @@ -551,12 +571,15 @@ pymain_run_python(int *exitcode) } } + // import readline and rlcompleter before script dir is added to sys.path + pymain_import_readline(config); + if (main_importer_path != NULL) { if (pymain_sys_path_add_path0(interp, main_importer_path) < 0) { goto error; } } - else if (!config->isolated) { + else if (!config->safe_path) { PyObject *path0 = NULL; int res = _PyPathConfig_ComputeSysPath0(&config->argv, &path0); if (res < 0) { @@ -573,7 +596,6 @@ pymain_run_python(int *exitcode) } pymain_header(config); - pymain_import_readline(config); if (config->run_command) { *exitcode = pymain_run_command(config->run_command); @@ -627,7 +649,7 @@ exit_sigint(void) * SIG_DFL handler for SIGINT if KeyboardInterrupt went unhandled. * If we don't, a calling process such as a shell may not know * about the user's ^C. https://www.cons.org/cracauer/sigint.html */ -#if defined(HAVE_GETPID) && !defined(MS_WINDOWS) +#if defined(HAVE_GETPID) && defined(HAVE_KILL) && !defined(MS_WINDOWS) if (PyOS_setsig(SIGINT, SIG_DFL) == SIG_ERR) { perror("signal"); /* Impossible in normal environments. */ } else { @@ -674,7 +696,7 @@ Py_RunMain(void) pymain_free(); - if (_Py_UnhandledKeyboardInterrupt) { + if (_PyRuntime.signals.unhandled_keyboard_interrupt) { exitcode = exit_sigint(); } diff --git a/Modules/makesetup b/Modules/makesetup index 2335724e804..f000c9cd673 100755 --- a/Modules/makesetup +++ b/Modules/makesetup @@ -1,4 +1,5 @@ #! /bin/sh +set -e # Convert templates into Makefile and config.c, based on the module # definitions found in the file Setup. @@ -117,6 +118,7 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | BUILT= BUILT_SHARED= DISABLED= + CONFIGURED= MODS= SHAREDMODS= OBJS= @@ -206,6 +208,17 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | cpps="\$(MODULE_${mods_upper}_CFLAGS)" libs="\$(MODULE_${mods_upper}_LDFLAGS)" fi + for mod in $mods + do + case $CONFIGURED in + *,${mod},*) + # Detected multiple rules for a module, first rule wins. This + # allows users to disable modules in Setup.local. + echo 1>&2 "maksetup: '$mod' was handled by previous rule." + continue 2;; + esac + CONFIGURED="$CONFIGURED,${mod}," + done case $doconfig in yes) LIBS="$LIBS $libs" @@ -247,13 +260,17 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | \$*) ;; *) src='$(srcdir)/'"$srcdir/$src";; esac + # custom flags first, PY_STDMODULE_CFLAGS may contain -I with system libmpdec case $doconfig in - no) cc="$cc \$(CCSHARED) \$(PY_CFLAGS_NODIST) \$(PY_CPPFLAGS)";; + no) + cc="$cc $cpps \$(PY_STDMODULE_CFLAGS) \$(CCSHARED)" + rule="$obj: $src \$(MODULE_${mods_upper}_DEPS) \$(MODULE_DEPS_SHARED) \$(PYTHON_HEADERS); $cc -c $src -o $obj" + ;; *) - cc="$cc \$(PY_BUILTIN_MODULE_CFLAGS)";; + cc="$cc $cpps \$(PY_BUILTIN_MODULE_CFLAGS)" + rule="$obj: $src \$(MODULE_${mods_upper}_DEPS) \$(MODULE_DEPS_STATIC) \$(PYTHON_HEADERS); $cc -c $src -o $obj" + ;; esac - # force rebuild when header file or module build flavor (static/shared) is changed - rule="$obj: $src \$(MODULE_${mods_upper}_DEPS) \$(PYTHON_HEADERS) Modules/config.c; $cc $cpps -c $src -o $obj" echo "$rule" >>$rulesf done case $doconfig in @@ -310,8 +327,13 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | case $makepre in -) ;; - *) sedf="@sed.in.$$" - trap 'rm -f $sedf' 0 1 2 3 + *) + # macOS' sed has issues with 'a' command. Use 'r' command with an + # external replacement file instead. + sedf="@sed.in.$$" + sedr="@sed.replace.$$" + trap 'rm -f $sedf $sedr' 0 1 2 3 + echo "$NL$NL$DEFS" | sed 's/\\$//' > $sedr echo "1i\\" >$sedf str="# Generated automatically from $makepre by makesetup." echo "$str" >>$sedf @@ -320,10 +342,10 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | echo "s%_MODDISABLED_NAMES_%$DISABLED%" >>$sedf echo "s%_MODOBJS_%$OBJS%" >>$sedf echo "s%_MODLIBS_%$LIBS%" >>$sedf - echo "/Definitions added by makesetup/a$NL$NL$DEFS" >>$sedf + echo "/Definitions added by makesetup/r $sedr" >>$sedf sed -f $sedf $makepre >Makefile cat $rulesf >>Makefile - rm -f $sedf + rm -f $sedf $sedr ;; esac diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 67669f19bc2..e6cdb3bae1e 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -61,10 +61,14 @@ raised for division by zero and mod by zero. #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_dtoa.h" // _Py_dg_infinity() #include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_object.h" // _PyObject_LookupSpecial() +#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR /* For DBL_EPSILON in _math.h */ #include /* For _Py_log1p with workarounds for buggy handling of zeros. */ #include "_math.h" +#include #include "clinic/mathmodule.c.h" @@ -74,6 +78,20 @@ module math /*[clinic end generated code: output=da39a3ee5e6b4b0d input=76bc7002685dd942]*/ +typedef struct { + PyObject *str___ceil__; + PyObject *str___floor__; + PyObject *str___trunc__; +} math_module_state; + +static inline math_module_state* +get_math_module_state(PyObject *module) +{ + void *state = _PyModule_GetState(module); + assert(state != NULL); + return (math_module_state *)state; +} + /* sin(pi*x), giving accurate results for all finite x (especially x integral or close to an integer). This is here for use in the @@ -271,7 +289,7 @@ lanczos_sum(double x) static double m_inf(void) { -#ifndef PY_NO_SHORT_FLOAT_REPR +#if _PY_SHORT_FLOAT_REPR == 1 return _Py_dg_infinity(0); #else return Py_HUGE_VAL; @@ -281,12 +299,12 @@ m_inf(void) /* Constant nan value, generated in the same way as float('nan'). */ /* We don't currently assume that Py_NAN is defined everywhere. */ -#if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) +#if _PY_SHORT_FLOAT_REPR == 1 static double m_nan(void) { -#ifndef PY_NO_SHORT_FLOAT_REPR +#if _PY_SHORT_FLOAT_REPR == 1 return _Py_dg_stdnan(0); #else return Py_NAN; @@ -985,9 +1003,13 @@ is_error(double x) * On some platforms (Ubuntu/ia64) it seems that errno can be * set to ERANGE for subnormal results that do *not* underflow * to zero. So to be safe, we'll ignore ERANGE whenever the - * function result is less than one in absolute value. + * function result is less than 1.5 in absolute value. + * + * bpo-46018: Changed to 1.5 to ensure underflows in expm1() + * are correctly detected, since the function may underflow + * toward -1.0 rather than 0.0. */ - if (fabs(x) < 1.0) + if (fabs(x) < 1.5) result = 0; else PyErr_SetString(PyExc_OverflowError, @@ -1209,10 +1231,10 @@ static PyObject * math_ceil(PyObject *module, PyObject *number) /*[clinic end generated code: output=6c3b8a78bc201c67 input=2725352806399cab]*/ { - _Py_IDENTIFIER(__ceil__); if (!PyFloat_CheckExact(number)) { - PyObject *method = _PyObject_LookupSpecial(number, &PyId___ceil__); + math_module_state *state = get_math_module_state(module); + PyObject *method = _PyObject_LookupSpecial(number, state->str___ceil__); if (method != NULL) { PyObject *result = _PyObject_CallNoArgs(method); Py_DECREF(method); @@ -1248,6 +1270,9 @@ FUNC1A(erfc, m_erfc, FUNC1(exp, exp, 1, "exp($module, x, /)\n--\n\n" "Return e raised to the power of x.") +FUNC1(exp2, exp2, 1, + "exp2($module, x, /)\n--\n\n" + "Return 2 raised to the power of x.") FUNC1(expm1, expm1, 1, "expm1($module, x, /)\n--\n\n" "Return exp(x)-1.\n\n" @@ -1274,14 +1299,13 @@ math_floor(PyObject *module, PyObject *number) { double x; - _Py_IDENTIFIER(__floor__); - if (PyFloat_CheckExact(number)) { x = PyFloat_AS_DOUBLE(number); } else { - PyObject *method = _PyObject_LookupSpecial(number, &PyId___floor__); + math_module_state *state = get_math_module_state(module); + PyObject *method = _PyObject_LookupSpecial(number, state->str___floor__); if (method != NULL) { PyObject *result = _PyObject_CallNoArgs(method); Py_DECREF(method); @@ -1334,30 +1358,30 @@ FUNC1(tanh, tanh, 0, Dickinson's post at . See those links for more details, proofs and other references. - Note 1: IEEE 754R floating point semantics are assumed, - but the current implementation does not re-establish special - value semantics across iterations (i.e. handling -Inf + Inf). + Note 1: IEEE 754 floating-point semantics with a rounding mode of + roundTiesToEven are assumed. - Note 2: No provision is made for intermediate overflow handling; - therefore, sum([1e+308, 1e-308, 1e+308]) returns 1e+308 while - sum([1e+308, 1e+308, 1e-308]) raises an OverflowError due to the + Note 2: No provision is made for intermediate overflow handling; + therefore, fsum([1e+308, -1e+308, 1e+308]) returns 1e+308 while + fsum([1e+308, 1e+308, -1e+308]) raises an OverflowError due to the overflow of the first partial sum. - Note 3: The intermediate values lo, yr, and hi are declared volatile so - aggressive compilers won't algebraically reduce lo to always be exactly 0.0. - Also, the volatile declaration forces the values to be stored in memory as - regular doubles instead of extended long precision (80-bit) values. This - prevents double rounding because any addition or subtraction of two doubles - can be resolved exactly into double-sized hi and lo values. As long as the - hi value gets forced into a double before yr and lo are computed, the extra - bits in downstream extended precision operations (x87 for example) will be - exactly zero and therefore can be losslessly stored back into a double, - thereby preventing double rounding. + Note 3: The algorithm has two potential sources of fragility. First, C + permits arithmetic operations on `double`s to be performed in an + intermediate format whose range and precision may be greater than those of + `double` (see for example C99 §5.2.4.2.2, paragraph 8). This can happen for + example on machines using the now largely historical x87 FPUs. In this case, + `fsum` can produce incorrect results. If `FLT_EVAL_METHOD` is `0` or `1`, or + `FLT_EVAL_METHOD` is `2` and `long double` is identical to `double`, then we + should be safe from this source of errors. Second, an aggressively + optimizing compiler can re-associate operations so that (for example) the + statement `yr = hi - x;` is treated as `yr = (x + y) - x` and then + re-associated as `yr = y + (x - x)`, giving `y = yr` and `lo = 0.0`. That + re-association would be in violation of the C standard, and should not occur + except possibly in the presence of unsafe optimizations (e.g., -ffast-math, + -fassociative-math). Such optimizations should be avoided for this module. - Note 4: A similar implementation is in Modules/cmathmodule.c. - Be sure to update both when making changes. - - Note 5: The signature of math.fsum() differs from builtins.sum() + Note 4: The signature of math.fsum() differs from builtins.sum() because the start argument doesn't make sense in the context of accurate summation. Since the partials table is collapsed before returning a result, sum(seq2, start=sum(seq1)) may not equal the @@ -1443,7 +1467,7 @@ math_fsum(PyObject *module, PyObject *seq) Py_ssize_t i, j, n = 0, m = NUM_PARTIALS; double x, y, t, ps[NUM_PARTIALS], *p = ps; double xsave, special_sum = 0.0, inf_sum = 0.0; - volatile double hi, yr, lo; + double hi, yr, lo = 0.0; iter = PyObject_GetIter(seq); if (iter == NULL) @@ -1711,20 +1735,49 @@ completes the proof sketch. */ +/* + The _approximate_isqrt_tab table provides approximate square roots for + 16-bit integers. For any n in the range 2**14 <= n < 2**16, the value + + a = _approximate_isqrt_tab[(n >> 8) - 64] + + is an approximate square root of n, satisfying (a - 1)**2 < n < (a + 1)**2. + + The table was computed in Python using the expression: + + [min(round(sqrt(256*n + 128)), 255) for n in range(64, 256)] +*/ + +static const uint8_t _approximate_isqrt_tab[192] = { + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 144, 145, 146, 147, 148, 149, 150, + 151, 151, 152, 153, 154, 155, 156, 156, 157, 158, 159, 160, + 160, 161, 162, 163, 164, 164, 165, 166, 167, 167, 168, 169, + 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, + 179, 179, 180, 181, 181, 182, 183, 183, 184, 185, 186, 186, + 187, 188, 188, 189, 190, 190, 191, 192, 192, 193, 194, 194, + 195, 196, 196, 197, 198, 198, 199, 200, 200, 201, 201, 202, + 203, 203, 204, 205, 205, 206, 206, 207, 208, 208, 209, 210, + 210, 211, 211, 212, 213, 213, 214, 214, 215, 216, 216, 217, + 217, 218, 219, 219, 220, 220, 221, 221, 222, 223, 223, 224, + 224, 225, 225, 226, 227, 227, 228, 228, 229, 229, 230, 230, + 231, 232, 232, 233, 233, 234, 234, 235, 235, 236, 237, 237, + 238, 238, 239, 239, 240, 240, 241, 241, 242, 242, 243, 243, + 244, 244, 245, 246, 246, 247, 247, 248, 248, 249, 249, 250, + 250, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255, 255, +}; /* Approximate square root of a large 64-bit integer. Given `n` satisfying `2**62 <= n < 2**64`, return `a` satisfying `(a - 1)**2 < n < (a + 1)**2`. */ -static uint64_t +static inline uint32_t _approximate_isqrt(uint64_t n) { - uint32_t u = 1U + (n >> 62); - u = (u << 1) + (n >> 59) / u; - u = (u << 3) + (n >> 53) / u; - u = (u << 7) + (n >> 41) / u; - return (u << 15) + (n >> 17) / u; + uint32_t u = _approximate_isqrt_tab[(n >> 56) - 64]; + u = (u << 7) + (uint32_t)(n >> 41) / u; + return (u << 15) + (uint32_t)((n >> 17) / u); } /*[clinic input] @@ -1742,7 +1795,8 @@ math_isqrt(PyObject *module, PyObject *n) { int a_too_large, c_bit_length; size_t c, d; - uint64_t m, u; + uint64_t m; + uint32_t u; PyObject *a = NULL, *b; n = _PyNumber_Index(n); @@ -1769,18 +1823,17 @@ math_isqrt(PyObject *module, PyObject *n) c = (c - 1U) / 2U; /* Fast path: if c <= 31 then n < 2**64 and we can compute directly with a - fast, almost branch-free algorithm. In the final correction, we use `u*u - - 1 >= m` instead of the simpler `u*u > m` in order to get the correct - result in the corner case where `u=2**32`. */ + fast, almost branch-free algorithm. */ if (c <= 31U) { + int shift = 31 - (int)c; m = (uint64_t)PyLong_AsUnsignedLongLong(n); Py_DECREF(n); if (m == (uint64_t)(-1) && PyErr_Occurred()) { return NULL; } - u = _approximate_isqrt(m << (62U - 2U*c)) >> (31U - c); - u -= u * u - 1U >= m; - return PyLong_FromUnsignedLongLong((unsigned long long)u); + u = _approximate_isqrt(m << 2*shift) >> shift; + u -= (uint64_t)u * u > m; + return PyLong_FromUnsignedLong(u); } /* Slow path: n >= 2**64. We perform the first five iterations in C integer @@ -1804,7 +1857,7 @@ math_isqrt(PyObject *module, PyObject *n) goto error; } u = _approximate_isqrt(m) >> (31U - d); - a = PyLong_FromUnsignedLongLong((unsigned long long)u); + a = PyLong_FromUnsignedLong(u); if (a == NULL) { goto error; } @@ -1996,8 +2049,7 @@ factorial_odd_part(unsigned long n) inner = PyLong_FromLong(1); if (inner == NULL) return NULL; - outer = inner; - Py_INCREF(outer); + outer = Py_NewRef(inner); upper = 3; for (i = _Py_bit_length(n) - 2; i >= 0; i--) { @@ -2018,8 +2070,7 @@ factorial_odd_part(unsigned long n) Py_DECREF(partial); if (tmp == NULL) goto error; - Py_DECREF(inner); - inner = tmp; + Py_SETREF(inner, tmp); /* Now inner is the product of all odd integers j in the range (0, n/2**i], giving the inner product in the formula above. */ @@ -2027,8 +2078,7 @@ factorial_odd_part(unsigned long n) tmp = PyNumber_Multiply(outer, inner); if (tmp == NULL) goto error; - Py_DECREF(outer); - outer = tmp; + Py_SETREF(outer, tmp); } Py_DECREF(inner); return outer; @@ -2055,17 +2105,17 @@ static const unsigned long SmallFactorials[] = { /*[clinic input] math.factorial - x as arg: object + n as arg: object / -Find x!. +Find n!. Raise a ValueError if x is negative or non-integral. [clinic start generated code]*/ static PyObject * math_factorial(PyObject *module, PyObject *arg) -/*[clinic end generated code: output=6686f26fae00e9ca input=6d1c8105c0d91fb4]*/ +/*[clinic end generated code: output=6686f26fae00e9ca input=713fb771677e8c31]*/ { long x, two_valuation; int overflow; @@ -2118,7 +2168,6 @@ static PyObject * math_trunc(PyObject *module, PyObject *x) /*[clinic end generated code: output=34b9697b707e1031 input=2168b34e0a09134d]*/ { - _Py_IDENTIFIER(__trunc__); PyObject *trunc, *result; if (PyFloat_CheckExact(x)) { @@ -2130,7 +2179,8 @@ math_trunc(PyObject *module, PyObject *x) return NULL; } - trunc = _PyObject_LookupSpecial(x, &PyId___trunc__); + math_module_state *state = get_math_module_state(module); + trunc = _PyObject_LookupSpecial(x, state->str___trunc__); if (trunc == NULL) { if (!PyErr_Occurred()) PyErr_Format(PyExc_TypeError, @@ -2274,7 +2324,7 @@ math_modf_impl(PyObject *module, double x) in that int is larger than PY_SSIZE_T_MAX. */ static PyObject* -loghelper(PyObject* arg, double (*func)(double), const char *funcname) +loghelper(PyObject* arg, double (*func)(double)) { /* If it is int, do it ourselves. */ if (PyLong_Check(arg)) { @@ -2316,29 +2366,27 @@ loghelper(PyObject* arg, double (*func)(double), const char *funcname) math.log x: object - [ - base: object(c_default="NULL") = math.e - ] + base: object = None / Return the logarithm of x to the given base. -If the base not specified, returns the natural logarithm (base e) of x. +If the base is not specified or is None, returns the natural +logarithm (base e) of x. [clinic start generated code]*/ static PyObject * -math_log_impl(PyObject *module, PyObject *x, int group_right_1, - PyObject *base) -/*[clinic end generated code: output=7b5a39e526b73fc9 input=0f62d5726cbfebbd]*/ +math_log_impl(PyObject *module, PyObject *x, PyObject *base) +/*[clinic end generated code: output=1dead263cbb1e854 input=ef032cc9837943e1]*/ { PyObject *num, *den; PyObject *ans; - num = loghelper(x, m_log, "log"); - if (num == NULL || base == NULL) + num = loghelper(x, m_log); + if (num == NULL || base == Py_None) return num; - den = loghelper(base, m_log, "log"); + den = loghelper(base, m_log); if (den == NULL) { Py_DECREF(num); return NULL; @@ -2364,7 +2412,7 @@ static PyObject * math_log2(PyObject *module, PyObject *x) /*[clinic end generated code: output=5425899a4d5d6acb input=08321262bae4f39b]*/ { - return loghelper(x, m_log2, "log2"); + return loghelper(x, m_log2); } @@ -2381,7 +2429,7 @@ static PyObject * math_log10(PyObject *module, PyObject *x) /*[clinic end generated code: output=be72a64617df9c6f input=b2469d02c6469e53]*/ { - return loghelper(x, m_log10, "log10"); + return loghelper(x, m_log10); } @@ -2665,13 +2713,13 @@ math_dist_impl(PyObject *module, PyObject *p, PyObject *q) if (m != n) { PyErr_SetString(PyExc_ValueError, "both points must have the same number of dimensions"); - return NULL; - + goto error_exit; } if (n > NUM_STACK_ELEMS) { diffs = (double *) PyObject_Malloc(n * sizeof(double)); if (diffs == NULL) { - return PyErr_NoMemory(); + PyErr_NoMemory(); + goto error_exit; } } for (i=0 ; i 0) ? (b > LONG_MAX - a) : (b < LONG_MIN - a); +} + +/* +Double and triple length extended precision algorithms from: + + Accurate Sum and Dot Product + by Takeshi Ogita, Siegfried M. Rump, and Shin’Ichi Oishi + https://doi.org/10.1137/030601818 + https://www.tuhh.de/ti3/paper/rump/OgRuOi05.pdf + +*/ + +typedef struct{ double hi; double lo; } DoubleLength; + +static DoubleLength +dl_sum(double a, double b) +{ + /* Algorithm 3.1 Error-free transformation of the sum */ + double x = a + b; + double z = x - a; + double y = (a - (x - z)) + (b - z); + return (DoubleLength) {x, y}; +} + +static DoubleLength +dl_mul(double x, double y) +{ + /* Algorithm 3.5. Error-free transformation of a product */ + double z = x * y; + double zz = fma(x, y, -z); + return (DoubleLength) {z, zz}; +} + +typedef struct { double hi; double lo; double tiny; } TripleLength; + +static const TripleLength tl_zero = {0.0, 0.0, 0.0}; + +static TripleLength +tl_fma(double x, double y, TripleLength total) +{ + /* Algorithm 5.10 with SumKVert for K=3 */ + DoubleLength pr = dl_mul(x, y); + DoubleLength sm = dl_sum(total.hi, pr.hi); + DoubleLength r1 = dl_sum(total.lo, pr.lo); + DoubleLength r2 = dl_sum(r1.hi, sm.lo); + return (TripleLength) {sm.hi, r2.hi, total.tiny + r1.lo + r2.lo}; +} + +static double +tl_to_d(TripleLength total) +{ + DoubleLength last = dl_sum(total.lo, total.hi); + return total.tiny + last.lo + last.hi; +} + +/*[clinic input] +math.sumprod + + p: object + q: object + / + +Return the sum of products of values from two iterables p and q. + +Roughly equivalent to: + + sum(itertools.starmap(operator.mul, zip(p, q, strict=True))) + +For float and mixed int/float inputs, the intermediate products +and sums are computed with extended precision. +[clinic start generated code]*/ + +static PyObject * +math_sumprod_impl(PyObject *module, PyObject *p, PyObject *q) +/*[clinic end generated code: output=6722dbfe60664554 input=82be54fe26f87e30]*/ +{ + PyObject *p_i = NULL, *q_i = NULL, *term_i = NULL, *new_total = NULL; + PyObject *p_it, *q_it, *total; + iternextfunc p_next, q_next; + bool p_stopped = false, q_stopped = false; + bool int_path_enabled = true, int_total_in_use = false; + bool flt_path_enabled = true, flt_total_in_use = false; + long int_total = 0; + TripleLength flt_total = tl_zero; + + p_it = PyObject_GetIter(p); + if (p_it == NULL) { + return NULL; + } + q_it = PyObject_GetIter(q); + if (q_it == NULL) { + Py_DECREF(p_it); + return NULL; + } + total = PyLong_FromLong(0); + if (total == NULL) { + Py_DECREF(p_it); + Py_DECREF(q_it); + return NULL; + } + p_next = *Py_TYPE(p_it)->tp_iternext; + q_next = *Py_TYPE(q_it)->tp_iternext; + while (1) { + bool finished; + + assert (p_i == NULL); + assert (q_i == NULL); + assert (term_i == NULL); + assert (new_total == NULL); + + assert (p_it != NULL); + assert (q_it != NULL); + assert (total != NULL); + + p_i = p_next(p_it); + if (p_i == NULL) { + if (PyErr_Occurred()) { + if (!PyErr_ExceptionMatches(PyExc_StopIteration)) { + goto err_exit; + } + PyErr_Clear(); + } + p_stopped = true; + } + q_i = q_next(q_it); + if (q_i == NULL) { + if (PyErr_Occurred()) { + if (!PyErr_ExceptionMatches(PyExc_StopIteration)) { + goto err_exit; + } + PyErr_Clear(); + } + q_stopped = true; + } + if (p_stopped != q_stopped) { + PyErr_Format(PyExc_ValueError, "Inputs are not the same length"); + goto err_exit; + } + finished = p_stopped & q_stopped; + + if (int_path_enabled) { + + if (!finished && PyLong_CheckExact(p_i) & PyLong_CheckExact(q_i)) { + int overflow; + long int_p, int_q, int_prod; + + int_p = PyLong_AsLongAndOverflow(p_i, &overflow); + if (overflow) { + goto finalize_int_path; + } + int_q = PyLong_AsLongAndOverflow(q_i, &overflow); + if (overflow) { + goto finalize_int_path; + } + if (_check_long_mult_overflow(int_p, int_q)) { + goto finalize_int_path; + } + int_prod = int_p * int_q; + if (long_add_would_overflow(int_total, int_prod)) { + goto finalize_int_path; + } + int_total += int_prod; + int_total_in_use = true; + Py_CLEAR(p_i); + Py_CLEAR(q_i); + continue; + } + + finalize_int_path: + // We're finished, overflowed, or have a non-int + int_path_enabled = false; + if (int_total_in_use) { + term_i = PyLong_FromLong(int_total); + if (term_i == NULL) { + goto err_exit; + } + new_total = PyNumber_Add(total, term_i); + if (new_total == NULL) { + goto err_exit; + } + Py_SETREF(total, new_total); + new_total = NULL; + Py_CLEAR(term_i); + int_total = 0; // An ounce of prevention, ... + int_total_in_use = false; + } + } + + if (flt_path_enabled) { + + if (!finished) { + double flt_p, flt_q; + bool p_type_float = PyFloat_CheckExact(p_i); + bool q_type_float = PyFloat_CheckExact(q_i); + if (p_type_float && q_type_float) { + flt_p = PyFloat_AS_DOUBLE(p_i); + flt_q = PyFloat_AS_DOUBLE(q_i); + } else if (p_type_float && (PyLong_CheckExact(q_i) || PyBool_Check(q_i))) { + /* We care about float/int pairs and int/float pairs because + they arise naturally in several use cases such as price + times quantity, measurements with integer weights, or + data selected by a vector of bools. */ + flt_p = PyFloat_AS_DOUBLE(p_i); + flt_q = PyLong_AsDouble(q_i); + if (flt_q == -1.0 && PyErr_Occurred()) { + PyErr_Clear(); + goto finalize_flt_path; + } + } else if (q_type_float && (PyLong_CheckExact(p_i) || PyBool_Check(q_i))) { + flt_q = PyFloat_AS_DOUBLE(q_i); + flt_p = PyLong_AsDouble(p_i); + if (flt_p == -1.0 && PyErr_Occurred()) { + PyErr_Clear(); + goto finalize_flt_path; + } + } else { + goto finalize_flt_path; + } + TripleLength new_flt_total = tl_fma(flt_p, flt_q, flt_total); + if (isfinite(new_flt_total.hi)) { + flt_total = new_flt_total; + flt_total_in_use = true; + Py_CLEAR(p_i); + Py_CLEAR(q_i); + continue; + } + } + + finalize_flt_path: + // We're finished, overflowed, have a non-float, or got a non-finite value + flt_path_enabled = false; + if (flt_total_in_use) { + term_i = PyFloat_FromDouble(tl_to_d(flt_total)); + if (term_i == NULL) { + goto err_exit; + } + new_total = PyNumber_Add(total, term_i); + if (new_total == NULL) { + goto err_exit; + } + Py_SETREF(total, new_total); + new_total = NULL; + Py_CLEAR(term_i); + flt_total = tl_zero; + flt_total_in_use = false; + } + } + + assert(!int_total_in_use); + assert(!flt_total_in_use); + if (finished) { + goto normal_exit; + } + term_i = PyNumber_Multiply(p_i, q_i); + if (term_i == NULL) { + goto err_exit; + } + new_total = PyNumber_Add(total, term_i); + if (new_total == NULL) { + goto err_exit; + } + Py_SETREF(total, new_total); + new_total = NULL; + Py_CLEAR(p_i); + Py_CLEAR(q_i); + Py_CLEAR(term_i); + } + + normal_exit: + Py_DECREF(p_it); + Py_DECREF(q_it); + return total; + + err_exit: + Py_DECREF(p_it); + Py_DECREF(q_it); + Py_DECREF(total); + Py_XDECREF(p_i); + Py_XDECREF(q_i); + Py_XDECREF(term_i); + Py_XDECREF(new_total); + return NULL; +} + + /* pow can't use math_2, but needs its own wrapper: the problem is that an infinite result can arise either as a result of overflow (in which case OverflowError should be raised) or as a result of @@ -3103,8 +3445,7 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start) long i_result = PyLong_AsLongAndOverflow(result, &overflow); /* If this already overflowed, don't even enter the loop. */ if (overflow == 0) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); } /* Loop over all the items in the iterable until we finish, we overflow * or we found a non integer element */ @@ -3151,8 +3492,7 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start) */ if (PyFloat_CheckExact(result)) { double f_result = PyFloat_AS_DOUBLE(result); - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); while(result == NULL) { item = PyIter_Next(iter); if (item == NULL) { @@ -3201,8 +3541,7 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start) if (item == NULL) { /* error, or end-of-sequence */ if (PyErr_Occurred()) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); } break; } @@ -3218,6 +3557,299 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start) } +/* least significant 64 bits of the odd part of factorial(n), for n in range(128). + +Python code to generate the values: + + import math + + for n in range(128): + fac = math.factorial(n) + fac_odd_part = fac // (fac & -fac) + reduced_fac_odd_part = fac_odd_part % (2**64) + print(f"{reduced_fac_odd_part:#018x}u") +*/ +static const uint64_t reduced_factorial_odd_part[] = { + 0x0000000000000001u, 0x0000000000000001u, 0x0000000000000001u, 0x0000000000000003u, + 0x0000000000000003u, 0x000000000000000fu, 0x000000000000002du, 0x000000000000013bu, + 0x000000000000013bu, 0x0000000000000b13u, 0x000000000000375fu, 0x0000000000026115u, + 0x000000000007233fu, 0x00000000005cca33u, 0x0000000002898765u, 0x00000000260eeeebu, + 0x00000000260eeeebu, 0x0000000286fddd9bu, 0x00000016beecca73u, 0x000001b02b930689u, + 0x00000870d9df20adu, 0x0000b141df4dae31u, 0x00079dd498567c1bu, 0x00af2e19afc5266du, + 0x020d8a4d0f4f7347u, 0x335281867ec241efu, 0x9b3093d46fdd5923u, 0x5e1f9767cc5866b1u, + 0x92dd23d6966aced7u, 0xa30d0f4f0a196e5bu, 0x8dc3e5a1977d7755u, 0x2ab8ce915831734bu, + 0x2ab8ce915831734bu, 0x81d2a0bc5e5fdcabu, 0x9efcac82445da75bu, 0xbc8b95cf58cde171u, + 0xa0e8444a1f3cecf9u, 0x4191deb683ce3ffdu, 0xddd3878bc84ebfc7u, 0xcb39a64b83ff3751u, + 0xf8203f7993fc1495u, 0xbd2a2a78b35f4bddu, 0x84757be6b6d13921u, 0x3fbbcfc0b524988bu, + 0xbd11ed47c8928df9u, 0x3c26b59e41c2f4c5u, 0x677a5137e883fdb3u, 0xff74e943b03b93ddu, + 0xfe5ebbcb10b2bb97u, 0xb021f1de3235e7e7u, 0x33509eb2e743a58fu, 0x390f9da41279fb7du, + 0xe5cb0154f031c559u, 0x93074695ba4ddb6du, 0x81c471caa636247fu, 0xe1347289b5a1d749u, + 0x286f21c3f76ce2ffu, 0x00be84a2173e8ac7u, 0x1595065ca215b88bu, 0xf95877595b018809u, + 0x9c2efe3c5516f887u, 0x373294604679382bu, 0xaf1ff7a888adcd35u, 0x18ddf279a2c5800bu, + 0x18ddf279a2c5800bu, 0x505a90e2542582cbu, 0x5bacad2cd8d5dc2bu, 0xfe3152bcbff89f41u, + 0xe1467e88bf829351u, 0xb8001adb9e31b4d5u, 0x2803ac06a0cbb91fu, 0x1904b5d698805799u, + 0xe12a648b5c831461u, 0x3516abbd6160cfa9u, 0xac46d25f12fe036du, 0x78bfa1da906b00efu, + 0xf6390338b7f111bdu, 0x0f25f80f538255d9u, 0x4ec8ca55b8db140fu, 0x4ff670740b9b30a1u, + 0x8fd032443a07f325u, 0x80dfe7965c83eeb5u, 0xa3dc1714d1213afdu, 0x205b7bbfcdc62007u, + 0xa78126bbe140a093u, 0x9de1dc61ca7550cfu, 0x84f0046d01b492c5u, 0x2d91810b945de0f3u, + 0xf5408b7f6008aa71u, 0x43707f4863034149u, 0xdac65fb9679279d5u, 0xc48406e7d1114eb7u, + 0xa7dc9ed3c88e1271u, 0xfb25b2efdb9cb30du, 0x1bebda0951c4df63u, 0x5c85e975580ee5bdu, + 0x1591bc60082cb137u, 0x2c38606318ef25d7u, 0x76ca72f7c5c63e27u, 0xf04a75d17baa0915u, + 0x77458175139ae30du, 0x0e6c1330bc1b9421u, 0xdf87d2b5797e8293u, 0xefa5c703e1e68925u, + 0x2b6b1b3278b4f6e1u, 0xceee27b382394249u, 0xd74e3829f5dab91du, 0xfdb17989c26b5f1fu, + 0xc1b7d18781530845u, 0x7b4436b2105a8561u, 0x7ba7c0418372a7d7u, 0x9dbc5c67feb6c639u, + 0x502686d7f6ff6b8fu, 0x6101855406be7a1fu, 0x9956afb5806930e7u, 0xe1f0ee88af40f7c5u, + 0x984b057bda5c1151u, 0x9a49819acc13ea05u, 0x8ef0dead0896ef27u, 0x71f7826efe292b21u, + 0xad80a480e46986efu, 0x01cdc0ebf5e0c6f7u, 0x6e06f839968f68dbu, 0xdd5943ab56e76139u, + 0xcdcf31bf8604c5e7u, 0x7e2b4a847054a1cbu, 0x0ca75697a4d3d0f5u, 0x4703f53ac514a98bu, +}; + +/* inverses of reduced_factorial_odd_part values modulo 2**64. + +Python code to generate the values: + + import math + + for n in range(128): + fac = math.factorial(n) + fac_odd_part = fac // (fac & -fac) + inverted_fac_odd_part = pow(fac_odd_part, -1, 2**64) + print(f"{inverted_fac_odd_part:#018x}u") +*/ +static const uint64_t inverted_factorial_odd_part[] = { + 0x0000000000000001u, 0x0000000000000001u, 0x0000000000000001u, 0xaaaaaaaaaaaaaaabu, + 0xaaaaaaaaaaaaaaabu, 0xeeeeeeeeeeeeeeefu, 0x4fa4fa4fa4fa4fa5u, 0x2ff2ff2ff2ff2ff3u, + 0x2ff2ff2ff2ff2ff3u, 0x938cc70553e3771bu, 0xb71c27cddd93e49fu, 0xb38e3229fcdee63du, + 0xe684bb63544a4cbfu, 0xc2f684917ca340fbu, 0xf747c9cba417526du, 0xbb26eb51d7bd49c3u, + 0xbb26eb51d7bd49c3u, 0xb0a7efb985294093u, 0xbe4b8c69f259eabbu, 0x6854d17ed6dc4fb9u, + 0xe1aa904c915f4325u, 0x3b8206df131cead1u, 0x79c6009fea76fe13u, 0xd8c5d381633cd365u, + 0x4841f12b21144677u, 0x4a91ff68200b0d0fu, 0x8f9513a58c4f9e8bu, 0x2b3e690621a42251u, + 0x4f520f00e03c04e7u, 0x2edf84ee600211d3u, 0xadcaa2764aaacdfdu, 0x161f4f9033f4fe63u, + 0x161f4f9033f4fe63u, 0xbada2932ea4d3e03u, 0xcec189f3efaa30d3u, 0xf7475bb68330bf91u, + 0x37eb7bf7d5b01549u, 0x46b35660a4e91555u, 0xa567c12d81f151f7u, 0x4c724007bb2071b1u, + 0x0f4a0cce58a016bdu, 0xfa21068e66106475u, 0x244ab72b5a318ae1u, 0x366ce67e080d0f23u, + 0xd666fdae5dd2a449u, 0xd740ddd0acc06a0du, 0xb050bbbb28e6f97bu, 0x70b003fe890a5c75u, + 0xd03aabff83037427u, 0x13ec4ca72c783bd7u, 0x90282c06afdbd96fu, 0x4414ddb9db4a95d5u, + 0xa2c68735ae6832e9u, 0xbf72d71455676665u, 0xa8469fab6b759b7fu, 0xc1e55b56e606caf9u, + 0x40455630fc4a1cffu, 0x0120a7b0046d16f7u, 0xa7c3553b08faef23u, 0x9f0bfd1b08d48639u, + 0xa433ffce9a304d37u, 0xa22ad1d53915c683u, 0xcb6cbc723ba5dd1du, 0x547fb1b8ab9d0ba3u, + 0x547fb1b8ab9d0ba3u, 0x8f15a826498852e3u, 0x32e1a03f38880283u, 0x3de4cce63283f0c1u, + 0x5dfe6667e4da95b1u, 0xfda6eeeef479e47du, 0xf14de991cc7882dfu, 0xe68db79247630ca9u, + 0xa7d6db8207ee8fa1u, 0x255e1f0fcf034499u, 0xc9a8990e43dd7e65u, 0x3279b6f289702e0fu, + 0xe7b5905d9b71b195u, 0x03025ba41ff0da69u, 0xb7df3d6d3be55aefu, 0xf89b212ebff2b361u, + 0xfe856d095996f0adu, 0xd6e533e9fdf20f9du, 0xf8c0e84a63da3255u, 0xa677876cd91b4db7u, + 0x07ed4f97780d7d9bu, 0x90a8705f258db62fu, 0xa41bbb2be31b1c0du, 0x6ec28690b038383bu, + 0xdb860c3bb2edd691u, 0x0838286838a980f9u, 0x558417a74b36f77du, 0x71779afc3646ef07u, + 0x743cda377ccb6e91u, 0x7fdf9f3fe89153c5u, 0xdc97d25df49b9a4bu, 0x76321a778eb37d95u, + 0x7cbb5e27da3bd487u, 0x9cff4ade1a009de7u, 0x70eb166d05c15197u, 0xdcf0460b71d5fe3du, + 0x5ac1ee5260b6a3c5u, 0xc922dedfdd78efe1u, 0xe5d381dc3b8eeb9bu, 0xd57e5347bafc6aadu, + 0x86939040983acd21u, 0x395b9d69740a4ff9u, 0x1467299c8e43d135u, 0x5fe440fcad975cdfu, + 0xcaa9a39794a6ca8du, 0xf61dbd640868dea1u, 0xac09d98d74843be7u, 0x2b103b9e1a6b4809u, + 0x2ab92d16960f536fu, 0x6653323d5e3681dfu, 0xefd48c1c0624e2d7u, 0xa496fefe04816f0du, + 0x1754a7b07bbdd7b1u, 0x23353c829a3852cdu, 0xbf831261abd59097u, 0x57a8e656df0618e1u, + 0x16e9206c3100680fu, 0xadad4c6ee921dac7u, 0x635f2b3860265353u, 0xdd6d0059f44b3d09u, + 0xac4dd6b894447dd7u, 0x42ea183eeaa87be3u, 0x15612d1550ee5b5du, 0x226fa19d656cb623u, +}; + +/* exponent of the largest power of 2 dividing factorial(n), for n in range(68) + +Python code to generate the values: + +import math + +for n in range(128): + fac = math.factorial(n) + fac_trailing_zeros = (fac & -fac).bit_length() - 1 + print(fac_trailing_zeros) +*/ + +static const uint8_t factorial_trailing_zeros[] = { + 0, 0, 1, 1, 3, 3, 4, 4, 7, 7, 8, 8, 10, 10, 11, 11, // 0-15 + 15, 15, 16, 16, 18, 18, 19, 19, 22, 22, 23, 23, 25, 25, 26, 26, // 16-31 + 31, 31, 32, 32, 34, 34, 35, 35, 38, 38, 39, 39, 41, 41, 42, 42, // 32-47 + 46, 46, 47, 47, 49, 49, 50, 50, 53, 53, 54, 54, 56, 56, 57, 57, // 48-63 + 63, 63, 64, 64, 66, 66, 67, 67, 70, 70, 71, 71, 73, 73, 74, 74, // 64-79 + 78, 78, 79, 79, 81, 81, 82, 82, 85, 85, 86, 86, 88, 88, 89, 89, // 80-95 + 94, 94, 95, 95, 97, 97, 98, 98, 101, 101, 102, 102, 104, 104, 105, 105, // 96-111 + 109, 109, 110, 110, 112, 112, 113, 113, 116, 116, 117, 117, 119, 119, 120, 120, // 112-127 +}; + +/* Number of permutations and combinations. + * P(n, k) = n! / (n-k)! + * C(n, k) = P(n, k) / k! + */ + +/* Calculate C(n, k) for n in the 63-bit range. */ +static PyObject * +perm_comb_small(unsigned long long n, unsigned long long k, int iscomb) +{ + if (k == 0) { + return PyLong_FromLong(1); + } + + /* For small enough n and k the result fits in the 64-bit range and can + * be calculated without allocating intermediate PyLong objects. */ + if (iscomb) { + /* Maps k to the maximal n so that 2*k-1 <= n <= 127 and C(n, k) + * fits into a uint64_t. Exclude k = 1, because the second fast + * path is faster for this case.*/ + static const unsigned char fast_comb_limits1[] = { + 0, 0, 127, 127, 127, 127, 127, 127, // 0-7 + 127, 127, 127, 127, 127, 127, 127, 127, // 8-15 + 116, 105, 97, 91, 86, 82, 78, 76, // 16-23 + 74, 72, 71, 70, 69, 68, 68, 67, // 24-31 + 67, 67, 67, // 32-34 + }; + if (k < Py_ARRAY_LENGTH(fast_comb_limits1) && n <= fast_comb_limits1[k]) { + /* + comb(n, k) fits into a uint64_t. We compute it as + + comb_odd_part << shift + + where 2**shift is the largest power of two dividing comb(n, k) + and comb_odd_part is comb(n, k) >> shift. comb_odd_part can be + calculated efficiently via arithmetic modulo 2**64, using three + lookups and two uint64_t multiplications. + */ + uint64_t comb_odd_part = reduced_factorial_odd_part[n] + * inverted_factorial_odd_part[k] + * inverted_factorial_odd_part[n - k]; + int shift = factorial_trailing_zeros[n] + - factorial_trailing_zeros[k] + - factorial_trailing_zeros[n - k]; + return PyLong_FromUnsignedLongLong(comb_odd_part << shift); + } + + /* Maps k to the maximal n so that 2*k-1 <= n <= 127 and C(n, k)*k + * fits into a long long (which is at least 64 bit). Only contains + * items larger than in fast_comb_limits1. */ + static const unsigned long long fast_comb_limits2[] = { + 0, ULLONG_MAX, 4294967296ULL, 3329022, 102570, 13467, 3612, 1449, // 0-7 + 746, 453, 308, 227, 178, 147, // 8-13 + }; + if (k < Py_ARRAY_LENGTH(fast_comb_limits2) && n <= fast_comb_limits2[k]) { + /* C(n, k) = C(n, k-1) * (n-k+1) / k */ + unsigned long long result = n; + for (unsigned long long i = 1; i < k;) { + result *= --n; + result /= ++i; + } + return PyLong_FromUnsignedLongLong(result); + } + } + else { + /* Maps k to the maximal n so that k <= n and P(n, k) + * fits into a long long (which is at least 64 bit). */ + static const unsigned long long fast_perm_limits[] = { + 0, ULLONG_MAX, 4294967296ULL, 2642246, 65537, 7133, 1627, 568, // 0-7 + 259, 142, 88, 61, 45, 36, 30, 26, // 8-15 + 24, 22, 21, 20, 20, // 16-20 + }; + if (k < Py_ARRAY_LENGTH(fast_perm_limits) && n <= fast_perm_limits[k]) { + if (n <= 127) { + /* P(n, k) fits into a uint64_t. */ + uint64_t perm_odd_part = reduced_factorial_odd_part[n] + * inverted_factorial_odd_part[n - k]; + int shift = factorial_trailing_zeros[n] + - factorial_trailing_zeros[n - k]; + return PyLong_FromUnsignedLongLong(perm_odd_part << shift); + } + + /* P(n, k) = P(n, k-1) * (n-k+1) */ + unsigned long long result = n; + for (unsigned long long i = 1; i < k;) { + result *= --n; + ++i; + } + return PyLong_FromUnsignedLongLong(result); + } + } + + /* For larger n use recursive formulas: + * + * P(n, k) = P(n, j) * P(n-j, k-j) + * C(n, k) = C(n, j) * C(n-j, k-j) // C(k, j) + */ + unsigned long long j = k / 2; + PyObject *a, *b; + a = perm_comb_small(n, j, iscomb); + if (a == NULL) { + return NULL; + } + b = perm_comb_small(n - j, k - j, iscomb); + if (b == NULL) { + goto error; + } + Py_SETREF(a, PyNumber_Multiply(a, b)); + Py_DECREF(b); + if (iscomb && a != NULL) { + b = perm_comb_small(k, j, 1); + if (b == NULL) { + goto error; + } + Py_SETREF(a, PyNumber_FloorDivide(a, b)); + Py_DECREF(b); + } + return a; + +error: + Py_DECREF(a); + return NULL; +} + +/* Calculate P(n, k) or C(n, k) using recursive formulas. + * It is more efficient than sequential multiplication thanks to + * Karatsuba multiplication. + */ +static PyObject * +perm_comb(PyObject *n, unsigned long long k, int iscomb) +{ + if (k == 0) { + return PyLong_FromLong(1); + } + if (k == 1) { + return Py_NewRef(n); + } + + /* P(n, k) = P(n, j) * P(n-j, k-j) */ + /* C(n, k) = C(n, j) * C(n-j, k-j) // C(k, j) */ + unsigned long long j = k / 2; + PyObject *a, *b; + a = perm_comb(n, j, iscomb); + if (a == NULL) { + return NULL; + } + PyObject *t = PyLong_FromUnsignedLongLong(j); + if (t == NULL) { + goto error; + } + n = PyNumber_Subtract(n, t); + Py_DECREF(t); + if (n == NULL) { + goto error; + } + b = perm_comb(n, k - j, iscomb); + Py_DECREF(n); + if (b == NULL) { + goto error; + } + Py_SETREF(a, PyNumber_Multiply(a, b)); + Py_DECREF(b); + if (iscomb && a != NULL) { + b = perm_comb_small(k, j, 1); + if (b == NULL) { + goto error; + } + Py_SETREF(a, PyNumber_FloorDivide(a, b)); + Py_DECREF(b); + } + return a; + +error: + Py_DECREF(a); + return NULL; +} + /*[clinic input] math.perm @@ -3241,9 +3873,9 @@ static PyObject * math_perm_impl(PyObject *module, PyObject *n, PyObject *k) /*[clinic end generated code: output=e021a25469653e23 input=5311c5a00f359b53]*/ { - PyObject *result = NULL, *factor = NULL; + PyObject *result = NULL; int overflow, cmp; - long long i, factors; + long long ki, ni; if (k == Py_None) { return math_factorial(module, n); @@ -3257,6 +3889,7 @@ math_perm_impl(PyObject *module, PyObject *n, PyObject *k) Py_DECREF(n); return NULL; } + assert(PyLong_CheckExact(n) && PyLong_CheckExact(k)); if (Py_SIZE(n) < 0) { PyErr_SetString(PyExc_ValueError, @@ -3278,57 +3911,38 @@ math_perm_impl(PyObject *module, PyObject *n, PyObject *k) goto error; } - factors = PyLong_AsLongLongAndOverflow(k, &overflow); + ki = PyLong_AsLongLongAndOverflow(k, &overflow); + assert(overflow >= 0 && !PyErr_Occurred()); if (overflow > 0) { PyErr_Format(PyExc_OverflowError, "k must not exceed %lld", LLONG_MAX); goto error; } - else if (factors == -1) { - /* k is nonnegative, so a return value of -1 can only indicate error */ - goto error; - } + assert(ki >= 0); - if (factors == 0) { - result = PyLong_FromLong(1); - goto done; + ni = PyLong_AsLongLongAndOverflow(n, &overflow); + assert(overflow >= 0 && !PyErr_Occurred()); + if (!overflow && ki > 1) { + assert(ni >= 0); + result = perm_comb_small((unsigned long long)ni, + (unsigned long long)ki, 0); } - - result = n; - Py_INCREF(result); - if (factors == 1) { - goto done; + else { + result = perm_comb(n, (unsigned long long)ki, 0); } - factor = Py_NewRef(n); - PyObject *one = _PyLong_GetOne(); // borrowed ref - for (i = 1; i < factors; ++i) { - Py_SETREF(factor, PyNumber_Subtract(factor, one)); - if (factor == NULL) { - goto error; - } - Py_SETREF(result, PyNumber_Multiply(result, factor)); - if (result == NULL) { - goto error; - } - } - Py_DECREF(factor); - done: Py_DECREF(n); Py_DECREF(k); return result; error: - Py_XDECREF(factor); - Py_XDECREF(result); Py_DECREF(n); Py_DECREF(k); return NULL; } - /*[clinic input] math.comb @@ -3354,9 +3968,9 @@ static PyObject * math_comb_impl(PyObject *module, PyObject *n, PyObject *k) /*[clinic end generated code: output=bd2cec8d854f3493 input=9a05315af2518709]*/ { - PyObject *result = NULL, *factor = NULL, *temp; + PyObject *result = NULL, *temp; int overflow, cmp; - long long i, factors; + long long ki, ni; n = PyNumber_Index(n); if (n == NULL) { @@ -3367,6 +3981,7 @@ math_comb_impl(PyObject *module, PyObject *n, PyObject *k) Py_DECREF(n); return NULL; } + assert(PyLong_CheckExact(n) && PyLong_CheckExact(k)); if (Py_SIZE(n) < 0) { PyErr_SetString(PyExc_ValueError, @@ -3379,73 +3994,60 @@ math_comb_impl(PyObject *module, PyObject *n, PyObject *k) goto error; } - /* k = min(k, n - k) */ - temp = PyNumber_Subtract(n, k); - if (temp == NULL) { - goto error; - } - if (Py_SIZE(temp) < 0) { - Py_DECREF(temp); - result = PyLong_FromLong(0); - goto done; - } - cmp = PyObject_RichCompareBool(temp, k, Py_LT); - if (cmp > 0) { - Py_SETREF(k, temp); + ni = PyLong_AsLongLongAndOverflow(n, &overflow); + assert(overflow >= 0 && !PyErr_Occurred()); + if (!overflow) { + assert(ni >= 0); + ki = PyLong_AsLongLongAndOverflow(k, &overflow); + assert(overflow >= 0 && !PyErr_Occurred()); + if (overflow || ki > ni) { + result = PyLong_FromLong(0); + goto done; + } + assert(ki >= 0); + + ki = Py_MIN(ki, ni - ki); + if (ki > 1) { + result = perm_comb_small((unsigned long long)ni, + (unsigned long long)ki, 1); + goto done; + } + /* For k == 1 just return the original n in perm_comb(). */ } else { - Py_DECREF(temp); - if (cmp < 0) { - goto error; - } - } - - factors = PyLong_AsLongLongAndOverflow(k, &overflow); - if (overflow > 0) { - PyErr_Format(PyExc_OverflowError, - "min(n - k, k) must not exceed %lld", - LLONG_MAX); - goto error; - } - if (factors == -1) { - /* k is nonnegative, so a return value of -1 can only indicate error */ - goto error; - } - - if (factors == 0) { - result = PyLong_FromLong(1); - goto done; - } - - result = n; - Py_INCREF(result); - if (factors == 1) { - goto done; - } - - factor = Py_NewRef(n); - PyObject *one = _PyLong_GetOne(); // borrowed ref - for (i = 1; i < factors; ++i) { - Py_SETREF(factor, PyNumber_Subtract(factor, one)); - if (factor == NULL) { - goto error; - } - Py_SETREF(result, PyNumber_Multiply(result, factor)); - if (result == NULL) { - goto error; - } - - temp = PyLong_FromUnsignedLongLong((unsigned long long)i + 1); + /* k = min(k, n - k) */ + temp = PyNumber_Subtract(n, k); if (temp == NULL) { goto error; } - Py_SETREF(result, PyNumber_FloorDivide(result, temp)); - Py_DECREF(temp); - if (result == NULL) { + if (Py_SIZE(temp) < 0) { + Py_DECREF(temp); + result = PyLong_FromLong(0); + goto done; + } + cmp = PyObject_RichCompareBool(temp, k, Py_LT); + if (cmp > 0) { + Py_SETREF(k, temp); + } + else { + Py_DECREF(temp); + if (cmp < 0) { + goto error; + } + } + + ki = PyLong_AsLongLongAndOverflow(k, &overflow); + assert(overflow >= 0 && !PyErr_Occurred()); + if (overflow) { + PyErr_Format(PyExc_OverflowError, + "min(n - k, k) must not exceed %lld", + LLONG_MAX); goto error; } + assert(ki >= 0); } - Py_DECREF(factor); + + result = perm_comb(n, (unsigned long long)ki, 1); done: Py_DECREF(n); @@ -3453,8 +4055,6 @@ done: return result; error: - Py_XDECREF(factor); - Py_XDECREF(result); Py_DECREF(n); Py_DECREF(k); return NULL; @@ -3525,6 +4125,20 @@ math_ulp_impl(PyObject *module, double x) static int math_exec(PyObject *module) { + + math_module_state *state = get_math_module_state(module); + state->str___ceil__ = PyUnicode_InternFromString("__ceil__"); + if (state->str___ceil__ == NULL) { + return -1; + } + state->str___floor__ = PyUnicode_InternFromString("__floor__"); + if (state->str___floor__ == NULL) { + return -1; + } + state->str___trunc__ = PyUnicode_InternFromString("__trunc__"); + if (state->str___trunc__ == NULL) { + return -1; + } if (PyModule_AddObject(module, "pi", PyFloat_FromDouble(Py_MATH_PI)) < 0) { return -1; } @@ -3538,7 +4152,7 @@ math_exec(PyObject *module) if (PyModule_AddObject(module, "inf", PyFloat_FromDouble(m_inf())) < 0) { return -1; } -#if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) +#if _PY_SHORT_FLOAT_REPR == 1 if (PyModule_AddObject(module, "nan", PyFloat_FromDouble(m_nan())) < 0) { return -1; } @@ -3546,17 +4160,33 @@ math_exec(PyObject *module) return 0; } +static int +math_clear(PyObject *module) +{ + math_module_state *state = get_math_module_state(module); + Py_CLEAR(state->str___ceil__); + Py_CLEAR(state->str___floor__); + Py_CLEAR(state->str___trunc__); + return 0; +} + +static void +math_free(void *module) +{ + math_clear((PyObject *)module); +} + static PyMethodDef math_methods[] = { {"acos", math_acos, METH_O, math_acos_doc}, {"acosh", math_acosh, METH_O, math_acosh_doc}, {"asin", math_asin, METH_O, math_asin_doc}, {"asinh", math_asinh, METH_O, math_asinh_doc}, {"atan", math_atan, METH_O, math_atan_doc}, - {"atan2", (PyCFunction)(void(*)(void))math_atan2, METH_FASTCALL, math_atan2_doc}, + {"atan2", _PyCFunction_CAST(math_atan2), METH_FASTCALL, math_atan2_doc}, {"atanh", math_atanh, METH_O, math_atanh_doc}, {"cbrt", math_cbrt, METH_O, math_cbrt_doc}, MATH_CEIL_METHODDEF - {"copysign", (PyCFunction)(void(*)(void))math_copysign, METH_FASTCALL, math_copysign_doc}, + {"copysign", _PyCFunction_CAST(math_copysign), METH_FASTCALL, math_copysign_doc}, {"cos", math_cos, METH_O, math_cos_doc}, {"cosh", math_cosh, METH_O, math_cosh_doc}, MATH_DEGREES_METHODDEF @@ -3564,6 +4194,7 @@ static PyMethodDef math_methods[] = { {"erf", math_erf, METH_O, math_erf_doc}, {"erfc", math_erfc, METH_O, math_erfc_doc}, {"exp", math_exp, METH_O, math_exp_doc}, + {"exp2", math_exp2, METH_O, math_exp2_doc}, {"expm1", math_expm1, METH_O, math_expm1_doc}, {"fabs", math_fabs, METH_O, math_fabs_doc}, MATH_FACTORIAL_METHODDEF @@ -3572,14 +4203,14 @@ static PyMethodDef math_methods[] = { MATH_FREXP_METHODDEF MATH_FSUM_METHODDEF {"gamma", math_gamma, METH_O, math_gamma_doc}, - {"gcd", (PyCFunction)(void(*)(void))math_gcd, METH_FASTCALL, math_gcd_doc}, - {"hypot", (PyCFunction)(void(*)(void))math_hypot, METH_FASTCALL, math_hypot_doc}, + {"gcd", _PyCFunction_CAST(math_gcd), METH_FASTCALL, math_gcd_doc}, + {"hypot", _PyCFunction_CAST(math_hypot), METH_FASTCALL, math_hypot_doc}, MATH_ISCLOSE_METHODDEF MATH_ISFINITE_METHODDEF MATH_ISINF_METHODDEF MATH_ISNAN_METHODDEF MATH_ISQRT_METHODDEF - {"lcm", (PyCFunction)(void(*)(void))math_lcm, METH_FASTCALL, math_lcm_doc}, + {"lcm", _PyCFunction_CAST(math_lcm), METH_FASTCALL, math_lcm_doc}, MATH_LDEXP_METHODDEF {"lgamma", math_lgamma, METH_O, math_lgamma_doc}, MATH_LOG_METHODDEF @@ -3589,12 +4220,13 @@ static PyMethodDef math_methods[] = { MATH_MODF_METHODDEF MATH_POW_METHODDEF MATH_RADIANS_METHODDEF - {"remainder", (PyCFunction)(void(*)(void))math_remainder, METH_FASTCALL, math_remainder_doc}, + {"remainder", _PyCFunction_CAST(math_remainder), METH_FASTCALL, math_remainder_doc}, {"sin", math_sin, METH_O, math_sin_doc}, {"sinh", math_sinh, METH_O, math_sinh_doc}, {"sqrt", math_sqrt, METH_O, math_sqrt_doc}, {"tan", math_tan, METH_O, math_tan_doc}, {"tanh", math_tanh, METH_O, math_tanh_doc}, + MATH_SUMPROD_METHODDEF MATH_TRUNC_METHODDEF MATH_PROD_METHODDEF MATH_PERM_METHODDEF @@ -3617,9 +4249,11 @@ static struct PyModuleDef mathmodule = { PyModuleDef_HEAD_INIT, .m_name = "math", .m_doc = module_doc, - .m_size = 0, + .m_size = sizeof(math_module_state), .m_methods = math_methods, .m_slots = math_slots, + .m_clear = math_clear, + .m_free = math_free, }; PyMODINIT_FUNC diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 21d53365776..8244202376c 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -18,8 +18,14 @@ / ftp://squirl.nightmare.com/pub/python/python-ext. */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #define PY_SSIZE_T_CLEAN #include +#include "pycore_bytesobject.h" // _PyBytes_Find() +#include "pycore_fileutils.h" // _Py_stat_struct #include "structmember.h" // PyMemberDef #include // offsetof() @@ -114,18 +120,6 @@ typedef struct { access_mode access; } mmap_object; -typedef struct { - PyTypeObject *mmap_object_type; -} mmap_state; - -static mmap_state * -get_mmap_state(PyObject *module) -{ - mmap_state *state = PyModule_GetState(module); - assert(state); - return state; -} - static int mmap_object_traverse(mmap_object *m_obj, visitproc visit, void *arg) { @@ -310,12 +304,8 @@ mmap_gfind(mmap_object *self, if (!PyArg_ParseTuple(args, reverse ? "y*|nn:rfind" : "y*|nn:find", &view, &start, &end)) { return NULL; - } else { - const char *p, *start_p, *end_p; - int sign = reverse ? -1 : 1; - const char *needle = view.buf; - Py_ssize_t len = view.len; - + } + else { if (start < 0) start += self->size; if (start < 0) @@ -330,21 +320,19 @@ mmap_gfind(mmap_object *self, else if (end > self->size) end = self->size; - start_p = self->data + start; - end_p = self->data + end; - - for (p = (reverse ? end_p - len : start_p); - (p >= start_p) && (p + len <= end_p); p += sign) { - Py_ssize_t i; - for (i = 0; i < len && needle[i] == p[i]; ++i) - /* nothing */; - if (i == len) { - PyBuffer_Release(&view); - return PyLong_FromSsize_t(p - self->data); - } + Py_ssize_t res; + if (reverse) { + res = _PyBytes_ReverseFind( + self->data + start, end - start, + view.buf, view.len, start); + } + else { + res = _PyBytes_Find( + self->data + start, end - start, + view.buf, view.len, start); } PyBuffer_Release(&view); - return PyLong_FromLong(-1); + return PyLong_FromSsize_t(res); } } @@ -536,7 +524,8 @@ mmap_resize_method(mmap_object *self, !SetEndOfFile(self->file_handle)) { /* resizing failed. try to remap the file */ file_resize_error = GetLastError(); - new_size = max_size.QuadPart = self->size; + max_size.QuadPart = self->size; + new_size = self->size; } } @@ -757,16 +746,13 @@ mmap__enter__method(mmap_object *self, PyObject *args) { CHECK_VALID(NULL); - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } static PyObject * mmap__exit__method(PyObject *self, PyObject *args) { - _Py_IDENTIFIER(close); - - return _PyObject_CallMethodIdNoArgs(self, &PyId_close); + return mmap_close_method((mmap_object *)self, NULL); } static PyObject * @@ -818,12 +804,11 @@ mmap__repr__method(PyObject *self) static PyObject * mmap__sizeof__method(mmap_object *self, void *unused) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)); - if (self->tagname) + size_t res = _PyObject_SIZE(Py_TYPE(self)); + if (self->tagname) { res += strlen(self->tagname) + 1; - return PyLong_FromSsize_t(res); + } + return PyLong_FromSize_t(res); } #endif @@ -1331,9 +1316,9 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) } } - m_obj->data = mmap(NULL, map_size, - prot, flags, - fd, offset); + Py_BEGIN_ALLOW_THREADS + m_obj->data = mmap(NULL, map_size, prot, flags, fd, offset); + Py_END_ALLOW_THREADS if (devzero != -1) { close(devzero); @@ -1556,46 +1541,23 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) } #endif /* MS_WINDOWS */ -static int -mmap_traverse(PyObject *module, visitproc visit, void *arg) -{ - mmap_state *state = get_mmap_state(module); - Py_VISIT(state->mmap_object_type); - return 0; -} - -static int -mmap_clear(PyObject *module) -{ - mmap_state *state = get_mmap_state(module); - Py_CLEAR(state->mmap_object_type); - return 0; -} - -static void -mmap_free(void *module) -{ - mmap_clear((PyObject *)module); -} - static int mmap_exec(PyObject *module) { - mmap_state *state = get_mmap_state(module); - Py_INCREF(PyExc_OSError); if (PyModule_AddObject(module, "error", PyExc_OSError) < 0) { Py_DECREF(PyExc_OSError); return -1; } - state->mmap_object_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, - &mmap_object_spec, - NULL); - if (state->mmap_object_type == NULL) { + PyObject *mmap_object_type = PyType_FromModuleAndSpec(module, + &mmap_object_spec, NULL); + if (mmap_object_type == NULL) { return -1; } - if (PyModule_AddType(module, state->mmap_object_type) < 0) { + int rc = PyModule_AddType(module, (PyTypeObject *)mmap_object_type); + Py_DECREF(mmap_object_type); + if (rc < 0) { return -1; } @@ -1636,6 +1598,11 @@ mmap_exec(PyObject *module) #endif #ifdef MAP_POPULATE ADD_INT_MACRO(module, MAP_POPULATE); +#endif +#ifdef MAP_STACK + // Mostly a no-op on Linux and NetBSD, but useful on OpenBSD + // for stack usage (even on x86 arch) + ADD_INT_MACRO(module, MAP_STACK); #endif if (PyModule_AddIntConstant(module, "PAGESIZE", (long)my_getpagesize()) < 0 ) { return -1; @@ -1740,13 +1707,10 @@ static PyModuleDef_Slot mmap_slots[] = { }; static struct PyModuleDef mmapmodule = { - PyModuleDef_HEAD_INIT, + .m_base = PyModuleDef_HEAD_INIT, .m_name = "mmap", - .m_size = sizeof(mmap_state), + .m_size = 0, .m_slots = mmap_slots, - .m_traverse = mmap_traverse, - .m_clear = mmap_clear, - .m_free = mmap_free, }; PyMODINIT_FUNC diff --git a/Modules/nismodule.c b/Modules/nismodule.c index cdda1a6a2fb..ec7f6d8031e 100644 --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -458,8 +458,7 @@ nis_maps (PyObject *module, PyObject *args, PyObject *kwdict) if (!str || PyList_Append(list, str) < 0) { Py_XDECREF(str); - Py_DECREF(list); - list = NULL; + Py_SETREF(list, NULL); break; } Py_DECREF(str); @@ -469,13 +468,13 @@ nis_maps (PyObject *module, PyObject *args, PyObject *kwdict) } static PyMethodDef nis_methods[] = { - {"match", (PyCFunction)(void(*)(void))nis_match, + {"match", _PyCFunction_CAST(nis_match), METH_VARARGS | METH_KEYWORDS, match__doc__}, - {"cat", (PyCFunction)(void(*)(void))nis_cat, + {"cat", _PyCFunction_CAST(nis_cat), METH_VARARGS | METH_KEYWORDS, cat__doc__}, - {"maps", (PyCFunction)(void(*)(void))nis_maps, + {"maps", _PyCFunction_CAST(nis_maps), METH_VARARGS | METH_KEYWORDS, maps__doc__}, {"get_default_domain", nis_get_default_domain, @@ -524,5 +523,11 @@ static struct PyModuleDef nismodule = { PyMODINIT_FUNC PyInit_nis(void) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "'nis' is deprecated and slated for removal in " + "Python 3.13", + 7)) { + return NULL; + } return PyModuleDef_Init(&nismodule); } diff --git a/Modules/ossaudiodev.c b/Modules/ossaudiodev.c index 4bab9a58eb1..2319eac449e 100644 --- a/Modules/ossaudiodev.c +++ b/Modules/ossaudiodev.c @@ -17,8 +17,13 @@ * $Id$ */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_fileutils.h" // _Py_write() #include "structmember.h" // PyMemberDef #include // getenv() @@ -529,16 +534,13 @@ oss_close(oss_audio_t *self, PyObject *unused) static PyObject * oss_self(PyObject *self, PyObject *unused) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * oss_exit(PyObject *self, PyObject *unused) { - _Py_IDENTIFIER(close); - - PyObject *ret = _PyObject_CallMethodIdNoArgs(self, &PyId_close); + PyObject *ret = PyObject_CallMethod(self, "close", NULL); if (!ret) return NULL; Py_DECREF(ret); @@ -567,7 +569,7 @@ oss_setparameters(oss_audio_t *self, PyObject *args) if (!_is_fd_valid(self->fd)) return NULL; - if (!PyArg_ParseTuple(args, "iii|i:setparameters", + if (!PyArg_ParseTuple(args, "iii|p:setparameters", &wanted_fmt, &wanted_channels, &wanted_rate, &strict)) return NULL; @@ -1111,6 +1113,13 @@ PyInit_ossaudiodev(void) { PyObject *m; + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "'ossaudiodev' is deprecated and slated for removal in " + "Python 3.13", + 7)) { + return NULL; + } + if (PyType_Ready(&OSSAudioType) < 0) return NULL; @@ -1125,10 +1134,8 @@ PyInit_ossaudiodev(void) NULL, NULL); if (OSSAudioError) { /* Each call to PyModule_AddObject decrefs it; compensate: */ - Py_INCREF(OSSAudioError); - Py_INCREF(OSSAudioError); - PyModule_AddObject(m, "error", OSSAudioError); - PyModule_AddObject(m, "OSSAudioError", OSSAudioError); + PyModule_AddObject(m, "error", Py_NewRef(OSSAudioError)); + PyModule_AddObject(m, "OSSAudioError", Py_NewRef(OSSAudioError)); } /* Build 'control_labels' and 'control_names' lists and add them @@ -1213,16 +1220,36 @@ PyInit_ossaudiodev(void) /* Expose all the ioctl numbers for masochists who like to do this stuff directly. */ +#ifdef SNDCTL_COPR_HALT _EXPORT_INT(m, SNDCTL_COPR_HALT); +#endif +#ifdef SNDCTL_COPR_LOAD _EXPORT_INT(m, SNDCTL_COPR_LOAD); +#endif +#ifdef SNDCTL_COPR_RCODE _EXPORT_INT(m, SNDCTL_COPR_RCODE); +#endif +#ifdef SNDCTL_COPR_RCVMSG _EXPORT_INT(m, SNDCTL_COPR_RCVMSG); +#endif +#ifdef SNDCTL_COPR_RDATA _EXPORT_INT(m, SNDCTL_COPR_RDATA); +#endif +#ifdef SNDCTL_COPR_RESET _EXPORT_INT(m, SNDCTL_COPR_RESET); +#endif +#ifdef SNDCTL_COPR_RUN _EXPORT_INT(m, SNDCTL_COPR_RUN); +#endif +#ifdef SNDCTL_COPR_SENDMSG _EXPORT_INT(m, SNDCTL_COPR_SENDMSG); +#endif +#ifdef SNDCTL_COPR_WCODE _EXPORT_INT(m, SNDCTL_COPR_WCODE); +#endif +#ifdef SNDCTL_COPR_WDATA _EXPORT_INT(m, SNDCTL_COPR_WDATA); +#endif #ifdef SNDCTL_DSP_BIND_CHANNEL _EXPORT_INT(m, SNDCTL_DSP_BIND_CHANNEL); #endif @@ -1244,8 +1271,12 @@ PyInit_ossaudiodev(void) _EXPORT_INT(m, SNDCTL_DSP_GETSPDIF); #endif _EXPORT_INT(m, SNDCTL_DSP_GETTRIGGER); +#ifdef SNDCTL_DSP_MAPINBUF _EXPORT_INT(m, SNDCTL_DSP_MAPINBUF); +#endif +#ifdef SNDCTL_DSP_MAPOUTBUF _EXPORT_INT(m, SNDCTL_DSP_MAPOUTBUF); +#endif _EXPORT_INT(m, SNDCTL_DSP_NONBLOCK); _EXPORT_INT(m, SNDCTL_DSP_POST); #ifdef SNDCTL_DSP_PROFILE @@ -1265,46 +1296,104 @@ PyInit_ossaudiodev(void) _EXPORT_INT(m, SNDCTL_DSP_STEREO); _EXPORT_INT(m, SNDCTL_DSP_SUBDIVIDE); _EXPORT_INT(m, SNDCTL_DSP_SYNC); +#ifdef SNDCTL_FM_4OP_ENABLE _EXPORT_INT(m, SNDCTL_FM_4OP_ENABLE); +#endif +#ifdef SNDCTL_FM_LOAD_INSTR _EXPORT_INT(m, SNDCTL_FM_LOAD_INSTR); +#endif +#ifdef SNDCTL_MIDI_INFO _EXPORT_INT(m, SNDCTL_MIDI_INFO); +#endif +#ifdef SNDCTL_MIDI_MPUCMD _EXPORT_INT(m, SNDCTL_MIDI_MPUCMD); +#endif +#ifdef SNDCTL_MIDI_MPUMODE _EXPORT_INT(m, SNDCTL_MIDI_MPUMODE); +#endif +#ifdef SNDCTL_MIDI_PRETIME _EXPORT_INT(m, SNDCTL_MIDI_PRETIME); +#endif +#ifdef SNDCTL_SEQ_CTRLRATE _EXPORT_INT(m, SNDCTL_SEQ_CTRLRATE); +#endif +#ifdef SNDCTL_SEQ_GETINCOUNT _EXPORT_INT(m, SNDCTL_SEQ_GETINCOUNT); +#endif +#ifdef SNDCTL_SEQ_GETOUTCOUNT _EXPORT_INT(m, SNDCTL_SEQ_GETOUTCOUNT); +#endif #ifdef SNDCTL_SEQ_GETTIME _EXPORT_INT(m, SNDCTL_SEQ_GETTIME); #endif +#ifdef SNDCTL_SEQ_NRMIDIS _EXPORT_INT(m, SNDCTL_SEQ_NRMIDIS); +#endif +#ifdef SNDCTL_SEQ_NRSYNTHS _EXPORT_INT(m, SNDCTL_SEQ_NRSYNTHS); +#endif +#ifdef SNDCTL_SEQ_OUTOFBAND _EXPORT_INT(m, SNDCTL_SEQ_OUTOFBAND); +#endif +#ifdef SNDCTL_SEQ_PANIC _EXPORT_INT(m, SNDCTL_SEQ_PANIC); +#endif +#ifdef SNDCTL_SEQ_PERCMODE _EXPORT_INT(m, SNDCTL_SEQ_PERCMODE); +#endif +#ifdef SNDCTL_SEQ_RESET _EXPORT_INT(m, SNDCTL_SEQ_RESET); +#endif +#ifdef SNDCTL_SEQ_RESETSAMPLES _EXPORT_INT(m, SNDCTL_SEQ_RESETSAMPLES); +#endif +#ifdef SNDCTL_SEQ_SYNC _EXPORT_INT(m, SNDCTL_SEQ_SYNC); +#endif +#ifdef SNDCTL_SEQ_TESTMIDI _EXPORT_INT(m, SNDCTL_SEQ_TESTMIDI); +#endif +#ifdef SNDCTL_SEQ_THRESHOLD _EXPORT_INT(m, SNDCTL_SEQ_THRESHOLD); +#endif #ifdef SNDCTL_SYNTH_CONTROL _EXPORT_INT(m, SNDCTL_SYNTH_CONTROL); #endif #ifdef SNDCTL_SYNTH_ID _EXPORT_INT(m, SNDCTL_SYNTH_ID); #endif +#ifdef SNDCTL_SYNTH_INFO _EXPORT_INT(m, SNDCTL_SYNTH_INFO); +#endif +#ifdef SNDCTL_SYNTH_MEMAVL _EXPORT_INT(m, SNDCTL_SYNTH_MEMAVL); +#endif #ifdef SNDCTL_SYNTH_REMOVESAMPLE _EXPORT_INT(m, SNDCTL_SYNTH_REMOVESAMPLE); #endif +#ifdef SNDCTL_TMR_CONTINUE _EXPORT_INT(m, SNDCTL_TMR_CONTINUE); +#endif +#ifdef SNDCTL_TMR_METRONOME _EXPORT_INT(m, SNDCTL_TMR_METRONOME); +#endif +#ifdef SNDCTL_TMR_SELECT _EXPORT_INT(m, SNDCTL_TMR_SELECT); +#endif +#ifdef SNDCTL_TMR_SOURCE _EXPORT_INT(m, SNDCTL_TMR_SOURCE); +#endif +#ifdef SNDCTL_TMR_START _EXPORT_INT(m, SNDCTL_TMR_START); +#endif +#ifdef SNDCTL_TMR_STOP _EXPORT_INT(m, SNDCTL_TMR_STOP); +#endif +#ifdef SNDCTL_TMR_TEMPO _EXPORT_INT(m, SNDCTL_TMR_TEMPO); +#endif +#ifdef SNDCTL_TMR_TIMEBASE _EXPORT_INT(m, SNDCTL_TMR_TIMEBASE); +#endif return m; } diff --git a/Modules/overlapped.c b/Modules/overlapped.c index 7c4570896bc..02c0f401be4 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -23,12 +23,6 @@ # define T_POINTER T_ULONGLONG #endif -/* Compatibility with Python 3.3 */ -#if PY_VERSION_HEX < 0x03040000 -# define PyMem_RawMalloc PyMem_Malloc -# define PyMem_RawFree PyMem_Free -#endif - #define F_HANDLE F_POINTER #define F_ULONG_PTR F_POINTER #define F_DWORD "k" @@ -38,27 +32,41 @@ #define T_HANDLE T_POINTER /*[python input] -class OVERLAPPED_converter(CConverter): - type = 'OVERLAPPED *' +class pointer_converter(CConverter): format_unit = '"F_POINTER"' -class HANDLE_converter(CConverter): + def parse_arg(self, argname, displayname): + return """ + {paramname} = PyLong_AsVoidPtr({argname}); + if (!{paramname} && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.parser_name) + +class OVERLAPPED_converter(pointer_converter): + type = 'OVERLAPPED *' + +class HANDLE_converter(pointer_converter): type = 'HANDLE' - format_unit = '"F_HANDLE"' -class ULONG_PTR_converter(CConverter): +class ULONG_PTR_converter(pointer_converter): type = 'ULONG_PTR' - format_unit = '"F_ULONG_PTR"' -class DWORD_converter(CConverter): + def parse_arg(self, argname, displayname): + return """ + {paramname} = (uintptr_t)PyLong_AsVoidPtr({argname}); + if (!{paramname} && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.parser_name) + +class DWORD_converter(unsigned_long_converter): type = 'DWORD' - format_unit = 'k' -class BOOL_converter(CConverter): +class BOOL_converter(int_converter): type = 'BOOL' - format_unit = 'i' [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=83bb8c2c2514f2a8]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=8a07ea3018f4cec8]*/ /*[clinic input] module _overlapped @@ -70,7 +78,7 @@ class _overlapped.Overlapped "OverlappedObject *" "&OverlappedType" enum {TYPE_NONE, TYPE_NOT_STARTED, TYPE_READ, TYPE_READINTO, TYPE_WRITE, TYPE_ACCEPT, TYPE_CONNECT, TYPE_DISCONNECT, TYPE_CONNECT_NAMED_PIPE, TYPE_WAIT_NAMED_PIPE_AND_CONNECT, TYPE_TRANSMIT_FILE, TYPE_READ_FROM, - TYPE_WRITE_TO}; + TYPE_WRITE_TO, TYPE_READ_FROM_INTO}; typedef struct { PyObject_HEAD @@ -97,22 +105,28 @@ typedef struct { struct sockaddr_in6 address; int address_length; } read_from; + + /* Data used for reading from a connectionless socket: + TYPE_READ_FROM_INTO */ + struct { + // A (number of bytes read, (host, port)) tuple + PyObject* result; + /* Buffer passed by the user */ + Py_buffer user_buffer; + struct sockaddr_in6 address; + int address_length; + } read_from_into; }; } OverlappedObject; -typedef struct { - PyTypeObject *overlapped_type; -} OverlappedState; -static inline OverlappedState* -overlapped_get_state(PyObject *module) +static inline void +steal_buffer(Py_buffer * dst, Py_buffer * src) { - void *state = PyModule_GetState(module); - assert(state != NULL); - return (OverlappedState *)state; + memcpy(dst, src, sizeof(Py_buffer)); + memset(src, 0, sizeof(Py_buffer)); } - /* * Map Windows error codes to subclasses of OSError */ @@ -145,7 +159,6 @@ static LPFN_ACCEPTEX Py_AcceptEx = NULL; static LPFN_CONNECTEX Py_ConnectEx = NULL; static LPFN_DISCONNECTEX Py_DisconnectEx = NULL; static LPFN_TRANSMITFILE Py_TransmitFile = NULL; -static BOOL (CALLBACK *Py_CancelIoEx)(HANDLE, LPOVERLAPPED) = NULL; #define GET_WSA_POINTER(s, x) \ (SOCKET_ERROR != WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ @@ -159,10 +172,19 @@ initialize_function_pointers(void) GUID GuidConnectEx = WSAID_CONNECTEX; GUID GuidDisconnectEx = WSAID_DISCONNECTEX; GUID GuidTransmitFile = WSAID_TRANSMITFILE; - HINSTANCE hKernel32; SOCKET s; DWORD dwBytes; + if (Py_AcceptEx != NULL && + Py_ConnectEx != NULL && + Py_DisconnectEx != NULL && + Py_TransmitFile != NULL) + { + // All function pointers are initialized already + // by previous module import + return 0; + } + s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s == INVALID_SOCKET) { SetFromWindowsErr(WSAGetLastError()); @@ -180,12 +202,6 @@ initialize_function_pointers(void) } closesocket(s); - - /* On WinXP we will have Py_CancelIoEx == NULL */ - Py_BEGIN_ALLOW_THREADS - hKernel32 = GetModuleHandle("KERNEL32"); - *(FARPROC *)&Py_CancelIoEx = GetProcAddress(hKernel32, "CancelIoEx"); - Py_END_ALLOW_THREADS return 0; } @@ -591,7 +607,7 @@ _overlapped_FormatMessage_impl(PyObject *module, DWORD code) * Mark operation as completed - used when reading produces ERROR_BROKEN_PIPE */ -static void +static inline void mark_as_completed(OVERLAPPED *ov) { ov->Internal = 0; @@ -668,6 +684,16 @@ Overlapped_clear(OverlappedObject *self) } break; } + case TYPE_READ_FROM_INTO: { + if (self->read_from_into.result) { + // We've received a message, free the result tuple. + Py_CLEAR(self->read_from_into.result); + } + if (self->read_from_into.user_buffer.obj) { + PyBuffer_Release(&self->read_from_into.user_buffer); + } + break; + } case TYPE_WRITE: case TYPE_WRITE_TO: case TYPE_READINTO: { @@ -692,10 +718,10 @@ Overlapped_dealloc(OverlappedObject *self) if (!HasOverlappedIoCompleted(&self->overlapped) && self->type != TYPE_NOT_STARTED) { - if (Py_CancelIoEx && Py_CancelIoEx(self->handle, &self->overlapped)) + Py_BEGIN_ALLOW_THREADS + if (CancelIoEx(self->handle, &self->overlapped)) wait = TRUE; - Py_BEGIN_ALLOW_THREADS ret = GetOverlappedResult(self->handle, &self->overlapped, &bytes, wait); Py_END_ALLOW_THREADS @@ -808,10 +834,7 @@ _overlapped_Overlapped_cancel_impl(OverlappedObject *self) if (!HasOverlappedIoCompleted(&self->overlapped)) { Py_BEGIN_ALLOW_THREADS - if (Py_CancelIoEx) - ret = Py_CancelIoEx(self->handle, &self->overlapped); - else - ret = CancelIo(self->handle); + ret = CancelIoEx(self->handle, &self->overlapped); Py_END_ALLOW_THREADS } @@ -872,6 +895,11 @@ _overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait) { break; } + else if (self->type == TYPE_READ_FROM_INTO && + self->read_from_into.result != NULL) + { + break; + } /* fall through */ default: return SetFromWindowsErr(err); @@ -884,8 +912,7 @@ _overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait) _PyBytes_Resize(&self->allocated_buffer, transferred)) return NULL; - Py_INCREF(self->allocated_buffer); - return self->allocated_buffer; + return Py_NewRef(self->allocated_buffer); case TYPE_READ_FROM: assert(PyBytes_CheckExact(self->read_from.allocated_buffer)); @@ -912,14 +939,35 @@ _overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait) } // first item: message - Py_INCREF(self->read_from.allocated_buffer); PyTuple_SET_ITEM(self->read_from.result, 0, - self->read_from.allocated_buffer); + Py_NewRef(self->read_from.allocated_buffer)); // second item: address PyTuple_SET_ITEM(self->read_from.result, 1, addr); - Py_INCREF(self->read_from.result); - return self->read_from.result; + return Py_NewRef(self->read_from.result); + case TYPE_READ_FROM_INTO: + // unparse the address + addr = unparse_address((SOCKADDR*)&self->read_from_into.address, + self->read_from_into.address_length); + + if (addr == NULL) { + return NULL; + } + + // The result is a two item tuple: (number of bytes read, address) + self->read_from_into.result = PyTuple_New(2); + if (self->read_from_into.result == NULL) { + Py_CLEAR(addr); + return NULL; + } + + // first item: number of bytes read + PyTuple_SET_ITEM(self->read_from_into.result, 0, + PyLong_FromUnsignedLong((unsigned long)transferred)); + // second item: address + PyTuple_SET_ITEM(self->read_from_into.result, 1, addr); + + return Py_NewRef(self->read_from_into.result); default: return PyLong_FromUnsignedLong((unsigned long) transferred); } @@ -993,7 +1041,7 @@ _overlapped_Overlapped_ReadFile_impl(OverlappedObject *self, HANDLE handle, _overlapped.Overlapped.ReadFileInto handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer / Start overlapped receive. @@ -1001,24 +1049,21 @@ Start overlapped receive. static PyObject * _overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self, - HANDLE handle, PyObject *bufobj) -/*[clinic end generated code: output=1e9e712e742e5b2a input=16f6cc268d1d0387]*/ + HANDLE handle, Py_buffer *bufobj) +/*[clinic end generated code: output=8754744506023071 input=4f037ba09939e32d]*/ { if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_READINTO; self->handle = handle; @@ -1059,6 +1104,7 @@ do_WSARecv(OverlappedObject *self, HANDLE handle, } } + /*[clinic input] _overlapped.Overlapped.WSARecv @@ -1100,7 +1146,7 @@ _overlapped_Overlapped_WSARecv_impl(OverlappedObject *self, HANDLE handle, _overlapped.Overlapped.WSARecvInto handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer flags: DWORD / @@ -1109,25 +1155,22 @@ Start overlapped receive. static PyObject * _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, - HANDLE handle, PyObject *bufobj, + HANDLE handle, Py_buffer *bufobj, DWORD flags) -/*[clinic end generated code: output=9a438abc436fe87c input=4f87c38fc381d525]*/ +/*[clinic end generated code: output=59ae7688786cf86b input=73e7fa00db633edd]*/ { if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_READINTO; self->handle = handle; @@ -1140,7 +1183,7 @@ _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, _overlapped.Overlapped.WriteFile handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer / Start overlapped write. @@ -1148,8 +1191,8 @@ Start overlapped write. static PyObject * _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj) -/*[clinic end generated code: output=c376230b6120d877 input=b8d9a7608d8a1e72]*/ + Py_buffer *bufobj) +/*[clinic end generated code: output=fa5d5880a1bf04b1 input=ac54424c362abfc1]*/ { DWORD written; BOOL ret; @@ -1160,16 +1203,13 @@ _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_WRITE; self->handle = handle; @@ -1195,7 +1235,7 @@ _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, _overlapped.Overlapped.WSASend handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer flags: DWORD / @@ -1204,8 +1244,8 @@ Start overlapped send. static PyObject * _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj, DWORD flags) -/*[clinic end generated code: output=316031c7467040cc input=932e7cba6d18f708]*/ + Py_buffer *bufobj, DWORD flags) +/*[clinic end generated code: output=3baaa6e1f7fe229e input=c4167420ba2f93d8]*/ { DWORD written; WSABUF wsabuf; @@ -1217,16 +1257,13 @@ _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_WRITE; self->handle = handle; @@ -1307,7 +1344,7 @@ static int parse_address(PyObject *obj, SOCKADDR *Address, int Length) { PyObject *Host_obj; - Py_UNICODE *Host; + wchar_t *Host; unsigned short Port; unsigned long FlowInfo; unsigned long ScopeId; @@ -1319,11 +1356,7 @@ parse_address(PyObject *obj, SOCKADDR *Address, int Length) if (!PyArg_ParseTuple(obj, "UH", &Host_obj, &Port)) { return -1; } -#if USE_UNICODE_WCHAR_CACHE - Host = (wchar_t *)_PyUnicode_AsUnicode(Host_obj); -#else /* USE_UNICODE_WCHAR_CACHE */ Host = PyUnicode_AsWideCharString(Host_obj, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (Host == NULL) { return -1; } @@ -1335,9 +1368,7 @@ parse_address(PyObject *obj, SOCKADDR *Address, int Length) else { ((SOCKADDR_IN*)Address)->sin_port = htons(Port); } -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(Host); -#endif /* USE_UNICODE_WCHAR_CACHE */ return Length; } case 4: { @@ -1347,11 +1378,7 @@ parse_address(PyObject *obj, SOCKADDR *Address, int Length) { return -1; } -#if USE_UNICODE_WCHAR_CACHE - Host = (wchar_t *)_PyUnicode_AsUnicode(Host_obj); -#else /* USE_UNICODE_WCHAR_CACHE */ Host = PyUnicode_AsWideCharString(Host_obj, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (Host == NULL) { return -1; } @@ -1365,9 +1392,7 @@ parse_address(PyObject *obj, SOCKADDR *Address, int Length) ((SOCKADDR_IN6*)Address)->sin6_flowinfo = FlowInfo; ((SOCKADDR_IN6*)Address)->sin6_scope_id = ScopeId; } -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(Host); -#endif /* USE_UNICODE_WCHAR_CACHE */ return Length; } default: @@ -1623,6 +1648,13 @@ Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) case TYPE_READ_FROM: Py_VISIT(self->read_from.result); Py_VISIT(self->read_from.allocated_buffer); + break; + case TYPE_READ_FROM_INTO: + Py_VISIT(self->read_from_into.result); + if (self->read_from_into.user_buffer.obj) { + Py_VISIT(&self->read_from_into.user_buffer.obj); + } + break; } return 0; } @@ -1638,7 +1670,7 @@ Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) _overlapped.WSAConnect client_handle as ConnectSocket: HANDLE - address_as_bytes as AddressObj: object + address_as_bytes as AddressObj: object(subclass_of='&PyTuple_Type') / Bind a remote address to a connectionless (UDP) socket. @@ -1647,7 +1679,7 @@ Bind a remote address to a connectionless (UDP) socket. static PyObject * _overlapped_WSAConnect_impl(PyObject *module, HANDLE ConnectSocket, PyObject *AddressObj) -/*[clinic end generated code: output=ea0b4391e94dad63 input=169f8075e9ae7fa4]*/ +/*[clinic end generated code: output=ea0b4391e94dad63 input=7cf65313d49c015a]*/ { char AddressBuf[sizeof(struct sockaddr_in6)]; SOCKADDR *Address = (SOCKADDR*)AddressBuf; @@ -1679,9 +1711,9 @@ _overlapped_WSAConnect_impl(PyObject *module, HANDLE ConnectSocket, _overlapped.Overlapped.WSASendTo handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer flags: DWORD - address_as_bytes as AddressObj: object + address_as_bytes as AddressObj: object(subclass_of='&PyTuple_Type') / Start overlapped sendto over a connectionless (UDP) socket. @@ -1689,9 +1721,9 @@ Start overlapped sendto over a connectionless (UDP) socket. static PyObject * _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj, DWORD flags, + Py_buffer *bufobj, DWORD flags, PyObject *AddressObj) -/*[clinic end generated code: output=fe0ff55eb60d65e1 input=f709e6ecebd9bc18]*/ +/*[clinic end generated code: output=3cdedc4cfaeb70cd input=31f44cd4ab92fc33]*/ { char AddressBuf[sizeof(struct sockaddr_in6)]; SOCKADDR *Address = (SOCKADDR*)AddressBuf; @@ -1713,17 +1745,13 @@ _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) { - return NULL; - } - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_WRITE_TO; self->handle = handle; @@ -1772,8 +1800,8 @@ _overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self, DWORD flags) /*[clinic end generated code: output=13832a2025b86860 input=1b2663fa130e0286]*/ { - DWORD nread; PyObject *buf; + DWORD nread; WSABUF wsabuf; int ret; DWORD err; @@ -1791,8 +1819,8 @@ _overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self, return NULL; } - wsabuf.len = size; wsabuf.buf = PyBytes_AS_STRING(buf); + wsabuf.len = size; self->type = TYPE_READ_FROM; self->handle = handle; @@ -1808,8 +1836,7 @@ _overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self, Py_END_ALLOW_THREADS self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS); - - switch(err) { + switch (err) { case ERROR_BROKEN_PIPE: mark_as_completed(&self->overlapped); return SetFromWindowsErr(err); @@ -1823,6 +1850,74 @@ _overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self, } } + +/*[clinic input] +_overlapped.Overlapped.WSARecvFromInto + + handle: HANDLE + buf as bufobj: Py_buffer + size: DWORD + flags: DWORD = 0 + / + +Start overlapped receive. +[clinic start generated code]*/ + +static PyObject * +_overlapped_Overlapped_WSARecvFromInto_impl(OverlappedObject *self, + HANDLE handle, Py_buffer *bufobj, + DWORD size, DWORD flags) +/*[clinic end generated code: output=30c7ea171a691757 input=4be4b08d03531e76]*/ +{ + DWORD nread; + WSABUF wsabuf; + int ret; + DWORD err; + + if (self->type != TYPE_NONE) { + PyErr_SetString(PyExc_ValueError, "operation already attempted"); + return NULL; + } + +#if SIZEOF_SIZE_T > SIZEOF_LONG + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { + PyErr_SetString(PyExc_ValueError, "buffer too large"); + return NULL; + } +#endif + + wsabuf.buf = bufobj->buf; + wsabuf.len = size; + + self->type = TYPE_READ_FROM_INTO; + self->handle = handle; + steal_buffer(&self->read_from_into.user_buffer, bufobj); + memset(&self->read_from_into.address, 0, sizeof(self->read_from_into.address)); + self->read_from_into.address_length = sizeof(self->read_from_into.address); + + Py_BEGIN_ALLOW_THREADS + ret = WSARecvFrom((SOCKET)handle, &wsabuf, 1, &nread, &flags, + (SOCKADDR*)&self->read_from_into.address, + &self->read_from_into.address_length, + &self->overlapped, NULL); + Py_END_ALLOW_THREADS + + self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS); + switch (err) { + case ERROR_BROKEN_PIPE: + mark_as_completed(&self->overlapped); + return SetFromWindowsErr(err); + case ERROR_SUCCESS: + case ERROR_MORE_DATA: + case ERROR_IO_PENDING: + Py_RETURN_NONE; + default: + self->type = TYPE_NOT_STARTED; + return SetFromWindowsErr(err); + } +} + + #include "clinic/overlapped.c.h" static PyMethodDef Overlapped_methods[] = { @@ -1832,6 +1927,8 @@ static PyMethodDef Overlapped_methods[] = { _OVERLAPPED_OVERLAPPED_READFILEINTO_METHODDEF _OVERLAPPED_OVERLAPPED_WSARECV_METHODDEF _OVERLAPPED_OVERLAPPED_WSARECVINTO_METHODDEF + _OVERLAPPED_OVERLAPPED_WSARECVFROM_METHODDEF + _OVERLAPPED_OVERLAPPED_WSARECVFROMINTO_METHODDEF _OVERLAPPED_OVERLAPPED_WRITEFILE_METHODDEF _OVERLAPPED_OVERLAPPED_WSASEND_METHODDEF _OVERLAPPED_OVERLAPPED_ACCEPTEX_METHODDEF @@ -1897,28 +1994,6 @@ static PyMethodDef overlapped_functions[] = { {NULL} }; -static int -overlapped_traverse(PyObject *module, visitproc visit, void *arg) -{ - OverlappedState *state = overlapped_get_state(module); - Py_VISIT(state->overlapped_type); - return 0; -} - -static int -overlapped_clear(PyObject *module) -{ - OverlappedState *state = overlapped_get_state(module); - Py_CLEAR(state->overlapped_type); - return 0; -} - -static void -overlapped_free(void *module) -{ - overlapped_clear((PyObject *)module); -} - #define WINAPI_CONSTANT(fmt, con) \ do { \ PyObject *value = Py_BuildValue(fmt, con); \ @@ -1946,14 +2021,15 @@ overlapped_exec(PyObject *module) return -1; } - OverlappedState *st = overlapped_get_state(module); - st->overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec( + PyTypeObject *overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec( module, &overlapped_type_spec, NULL); - if (st->overlapped_type == NULL) { + if (overlapped_type == NULL) { return -1; } - if (PyModule_AddType(module, st->overlapped_type) < 0) { + int rc = PyModule_AddType(module, overlapped_type); + Py_DECREF(overlapped_type); + if (rc < 0) { return -1; } @@ -1978,14 +2054,10 @@ static PyModuleDef_Slot overlapped_slots[] = { }; static struct PyModuleDef overlapped_module = { - PyModuleDef_HEAD_INIT, + .m_base = PyModuleDef_HEAD_INIT, .m_name = "_overlapped", - .m_size = sizeof(OverlappedState), .m_methods = overlapped_functions, .m_slots = overlapped_slots, - .m_traverse = overlapped_traverse, - .m_clear = overlapped_clear, - .m_free = overlapped_free }; PyMODINIT_FUNC diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 667a3339f5b..b84fb0d280f 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -16,18 +16,23 @@ #ifdef MS_WINDOWS # include # include +# include // UNLEN +# include "osdefs.h" // SEP +# define HAVE_SYMLINK #endif #ifdef __VXWORKS__ # include "pycore_bitutils.h" // _Py_popcount32() #endif #include "pycore_call.h" // _PyObject_CallNoArgs() -#include "pycore_fileutils.h" // _Py_closerange() -#include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_ceval.h" // _PyEval_ReInitThreads() +#include "pycore_fileutils.h" // _Py_closerange() #include "pycore_import.h" // _PyImport_ReInitLock() #include "pycore_initconfig.h" // _PyStatus_EXCEPTION() +#include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_object.h" // _PyObject_LookupSpecial() #include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_signal.h" // Py_NSIG #include "structmember.h" // PyMemberDef #ifndef MS_WINDOWS @@ -67,6 +72,8 @@ */ #if defined(__APPLE__) +#include + #if defined(__has_builtin) #if __has_builtin(__builtin_available) #define HAVE_BUILTIN_AVAILABLE 1 @@ -89,6 +96,8 @@ # define HAVE_FUTIMENS_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) # define HAVE_UTIMENSAT_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) # define HAVE_PWRITEV_RUNTIME __builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *) +# define HAVE_MKFIFOAT_RUNTIME __builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *) +# define HAVE_MKNODAT_RUNTIME __builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *) # define HAVE_POSIX_SPAWN_SETSID_RUNTIME __builtin_available(macOS 10.15, *) @@ -150,6 +159,18 @@ # define HAVE_SYMLINKAT_RUNTIME (symlinkat != NULL) # endif +# ifdef HAVE_UTIMENSAT +# define HAVE_UTIMENSAT_RUNTIME (utimensat != NULL) +# endif + +# ifdef HAVE_FUTIMENS +# define HAVE_FUTIMENS_RUNTIME (futimens != NULL) +# endif + +# ifdef HAVE_PWRITEV +# define HAVE_PWRITEV_RUNTIME (pwritev != NULL) +# endif + #endif #ifdef HAVE_FUTIMESAT @@ -173,6 +194,8 @@ # define HAVE_FUTIMENS_RUNTIME 1 # define HAVE_UTIMENSAT_RUNTIME 1 # define HAVE_PWRITEV_RUNTIME 1 +# define HAVE_MKFIFOAT_RUNTIME 1 +# define HAVE_MKNODAT_RUNTIME 1 #endif @@ -320,31 +343,9 @@ corresponding Unix manual entries for more information on calls."); # define HAVE_CWAIT 1 # define HAVE_FSYNC 1 # define fsync _commit -# else - /* Unix functions that the configure script doesn't check for */ -# ifndef __VXWORKS__ -# define HAVE_EXECV 1 -# define HAVE_FORK 1 -# if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */ -# define HAVE_FORK1 1 -# endif -# endif -# define HAVE_GETEGID 1 -# define HAVE_GETEUID 1 -# define HAVE_GETGID 1 -# define HAVE_GETPPID 1 -# define HAVE_GETUID 1 -# define HAVE_KILL 1 -# define HAVE_OPENDIR 1 -# define HAVE_PIPE 1 -# define HAVE_SYSTEM 1 -# define HAVE_WAIT 1 -# define HAVE_TTYNAME 1 # endif /* _MSC_VER */ #endif /* ! __WATCOMC__ || __QNX__ */ -_Py_IDENTIFIER(__fspath__); - /*[clinic input] # one of the few times we lie about this name! module os @@ -430,18 +431,7 @@ extern char *ctermid_r(char *); # ifdef HAVE_PROCESS_H # include # endif -# ifndef IO_REPARSE_TAG_SYMLINK -# define IO_REPARSE_TAG_SYMLINK (0xA000000CL) -# endif -# ifndef IO_REPARSE_TAG_MOUNT_POINT -# define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) -# endif -# include "osdefs.h" // SEP # include -# include -# include // ShellExecute() -# include // UNLEN -# define HAVE_SYMLINK #endif /* _MSC_VER */ #ifndef MAXPATHLEN @@ -507,9 +497,11 @@ extern char *ctermid_r(char *); #ifdef MS_WINDOWS # define INITFUNC PyInit_nt # define MODNAME "nt" +# define MODNAME_OBJ &_Py_ID(nt) #else # define INITFUNC PyInit_posix # define MODNAME "posix" +# define MODNAME_OBJ &_Py_ID(posix) #endif #if defined(__sun) @@ -595,7 +587,7 @@ PyOS_AfterFork_Child(void) PyStatus status; _PyRuntimeState *runtime = &_PyRuntime; - status = _PyGILState_Reinit(runtime); + status = _PyRuntimeState_ReInitThreads(runtime); if (_PyStatus_EXCEPTION(status)) { goto fatal_error; } @@ -603,6 +595,10 @@ PyOS_AfterFork_Child(void) PyThreadState *tstate = _PyThreadState_GET(); _Py_EnsureTstateNotNULL(tstate); +#ifdef PY_HAVE_THREAD_NATIVE_ID + tstate->native_thread_id = PyThread_get_thread_native_id(); +#endif + status = _PyEval_ReInitThreads(tstate); if (_PyStatus_EXCEPTION(status)) { goto fatal_error; @@ -615,17 +611,17 @@ PyOS_AfterFork_Child(void) _PySignal_AfterFork(); - status = _PyRuntimeState_ReInitThreads(runtime); - if (_PyStatus_EXCEPTION(status)) { - goto fatal_error; - } - status = _PyInterpreterState_DeleteExceptMain(runtime); if (_PyStatus_EXCEPTION(status)) { goto fatal_error; } assert(_PyThreadState_GET() == tstate); + status = _PyPerfTrampoline_AfterFork_Child(); + if (_PyStatus_EXCEPTION(status)) { + goto fatal_error; + } + run_at_forkers(tstate->interp->after_forkers_child, 0); return; @@ -901,7 +897,7 @@ fail: #define _PyLong_FromDev PyLong_FromLongLong -#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) +#if (defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)) || defined(HAVE_DEVICE_MACROS) static int _Py_Dev_Converter(PyObject *obj, void *p) { @@ -910,7 +906,7 @@ _Py_Dev_Converter(PyObject *obj, void *p) return 0; return 1; } -#endif /* HAVE_MKNOD && HAVE_MAKEDEV */ +#endif /* (HAVE_MKNOD && HAVE_MAKEDEV) || HAVE_DEVICE_MACROS */ #ifdef AT_FDCWD @@ -981,6 +977,7 @@ typedef struct { #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) PyObject *SchedParamType; #endif + newfunc statresult_new_orig; PyObject *StatResultType; PyObject *StatVFSResultType; PyObject *TerminalSizeType; @@ -1118,11 +1115,9 @@ typedef struct { static void path_cleanup(path_t *path) { -#if !USE_UNICODE_WCHAR_CACHE wchar_t *wide = (wchar_t *)path->wide; path->wide = NULL; PyMem_Free(wide); -#endif /* USE_UNICODE_WCHAR_CACHE */ Py_CLEAR(path->object); Py_CLEAR(path->cleanup); } @@ -1133,7 +1128,7 @@ path_converter(PyObject *o, void *p) path_t *path = (path_t *)p; PyObject *bytes = NULL; Py_ssize_t length = 0; - int is_index, is_buffer, is_bytes, is_unicode; + int is_index, is_bytes, is_unicode; const char *narrow; #ifdef MS_WINDOWS PyObject *wo = NULL; @@ -1171,15 +1166,14 @@ path_converter(PyObject *o, void *p) /* Only call this here so that we don't treat the return value of os.fspath() as an fd or buffer. */ is_index = path->allow_fd && PyIndex_Check(o); - is_buffer = PyObject_CheckBuffer(o); is_bytes = PyBytes_Check(o); is_unicode = PyUnicode_Check(o); - if (!is_index && !is_buffer && !is_unicode && !is_bytes) { + if (!is_index && !is_unicode && !is_bytes) { /* Inline PyOS_FSPath() for better error messages. */ PyObject *func, *res; - func = _PyObject_LookupSpecial(o, &PyId___fspath__); + func = _PyObject_LookupSpecial(o, &_Py_ID(__fspath__)); if (NULL == func) { goto error_format; } @@ -1204,20 +1198,12 @@ path_converter(PyObject *o, void *p) } /* still owns a reference to the original object */ - Py_DECREF(o); - o = res; + Py_SETREF(o, res); } if (is_unicode) { #ifdef MS_WINDOWS -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - wide = PyUnicode_AsUnicodeAndSize(o, &length); -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ wide = PyUnicode_AsWideCharString(o, &length); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (!wide) { goto error_exit; } @@ -1233,9 +1219,7 @@ _Py_COMP_DIAG_POP path->wide = wide; path->narrow = FALSE; path->fd = -1; -#if !USE_UNICODE_WCHAR_CACHE wide = NULL; -#endif /* USE_UNICODE_WCHAR_CACHE */ goto success_exit; #else if (!PyUnicode_FSConverter(o, &bytes)) { @@ -1244,29 +1228,7 @@ _Py_COMP_DIAG_POP #endif } else if (is_bytes) { - bytes = o; - Py_INCREF(bytes); - } - else if (is_buffer) { - /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code - after removing support of non-bytes buffer objects. */ - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "%s%s%s should be %s, not %.200s", - path->function_name ? path->function_name : "", - path->function_name ? ": " : "", - path->argument_name ? path->argument_name : "path", - path->allow_fd && path->nullable ? "string, bytes, os.PathLike, " - "integer or None" : - path->allow_fd ? "string, bytes, os.PathLike or integer" : - path->nullable ? "string, bytes, os.PathLike or None" : - "string, bytes or os.PathLike", - _PyType_Name(Py_TYPE(o)))) { - goto error_exit; - } - bytes = PyBytes_FromObject(o); - if (!bytes) { - goto error_exit; - } + bytes = Py_NewRef(o); } else if (is_index) { if (!_fd_converter(o, &path->fd)) { @@ -1311,15 +1273,8 @@ _Py_COMP_DIAG_POP goto error_exit; } -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - wide = PyUnicode_AsUnicodeAndSize(wo, &length); -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ wide = PyUnicode_AsWideCharString(wo, &length); Py_DECREF(wo); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (!wide) { goto error_exit; } @@ -1334,11 +1289,7 @@ _Py_COMP_DIAG_POP path->wide = wide; path->narrow = TRUE; Py_DECREF(bytes); -#if USE_UNICODE_WCHAR_CACHE - path->cleanup = wo; -#else /* USE_UNICODE_WCHAR_CACHE */ wide = NULL; -#endif /* USE_UNICODE_WCHAR_CACHE */ #else path->wide = NULL; path->narrow = narrow; @@ -1362,11 +1313,7 @@ _Py_COMP_DIAG_POP Py_XDECREF(o); Py_XDECREF(bytes); #ifdef MS_WINDOWS -#if USE_UNICODE_WCHAR_CACHE - Py_XDECREF(wo); -#else /* USE_UNICODE_WCHAR_CACHE */ PyMem_Free(wide); -#endif /* USE_UNICODE_WCHAR_CACHE */ #endif return 0; } @@ -1524,10 +1471,11 @@ _Py_Sigset_Converter(PyObject *obj, void *addr) while ((item = PyIter_Next(iterator)) != NULL) { signum = PyLong_AsLongAndOverflow(item, &overflow); Py_DECREF(item); - if (signum <= 0 || signum >= NSIG) { + if (signum <= 0 || signum >= Py_NSIG) { if (overflow || signum != -1 || !PyErr_Occurred()) { PyErr_Format(PyExc_ValueError, - "signal number %ld out of range", signum); + "signal number %ld out of range [1; %i]", + signum, Py_NSIG - 1); } goto error; } @@ -1909,7 +1857,17 @@ win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result, /* Try reading the parent directory. */ if (!attributes_from_dir(path, &fileInfo, &tagInfo.ReparseTag)) { /* Cannot read the parent directory. */ - SetLastError(error); + switch (GetLastError()) { + case ERROR_FILE_NOT_FOUND: /* File cannot be found */ + case ERROR_PATH_NOT_FOUND: /* File parent directory cannot be found */ + case ERROR_NOT_READY: /* Drive exists but unavailable */ + case ERROR_BAD_NET_NAME: /* Remote drive unavailable */ + break; + /* Restore the error from CreateFileW(). */ + default: + SetLastError(error); + } + return -1; } if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { @@ -2271,7 +2229,6 @@ static PyStructSequence_Desc waitid_result_desc = { 5 }; #endif -static newfunc structseq_new; static PyObject * statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -2279,6 +2236,19 @@ statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyStructSequence *result; int i; + // ht_module doesn't get set in PyStructSequence_NewType(), + // so we can't use PyType_GetModule(). + PyObject *mod = PyImport_GetModule(MODNAME_OBJ); + if (mod == NULL) { + return NULL; + } + _posixstate *state = get_posix_state(mod); + Py_DECREF(mod); + if (state == NULL) { + return NULL; + } +#define structseq_new state->statresult_new_orig + result = (PyStructSequence*)structseq_new(type, args, kwds); if (!result) return NULL; @@ -2288,8 +2258,7 @@ statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds) for (i = 7; i <= 9; i++) { if (result->ob_item[i+3] == Py_None) { Py_DECREF(Py_None); - Py_INCREF(result->ob_item[i]); - result->ob_item[i+3] = result->ob_item[i]; + result->ob_item[i+3] = Py_NewRef(result->ob_item[i]); } } return (PyObject*)result; @@ -2402,7 +2371,8 @@ _pystat_fromstructstat(PyObject *module, STRUCT_STAT *st) return NULL; PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode)); - Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(st->st_ino)); + static_assert(sizeof(unsigned long long) >= sizeof(st->st_ino), + "stat.st_ino is larger than unsigned long long"); PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino)); #ifdef MS_WINDOWS PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev)); @@ -2417,7 +2387,8 @@ _pystat_fromstructstat(PyObject *module, STRUCT_STAT *st) PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid)); PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid)); #endif - Py_BUILD_ASSERT(sizeof(long long) >= sizeof(st->st_size)); + static_assert(sizeof(long long) >= sizeof(st->st_size), + "stat.st_size is larger than long long"); PyStructSequence_SET_ITEM(v, 6, PyLong_FromLongLong(st->st_size)); #if defined(HAVE_STAT_TV_NSEC) @@ -3203,6 +3174,9 @@ os.chmod mode: int Operating-system mode bitfield. + Be careful when using number literals for *mode*. The conventional UNIX notation for + numeric modes uses an octal base, which needs to be indicated with a ``0o`` prefix in + Python. * @@ -3228,7 +3202,7 @@ dir_fd and follow_symlinks may not be implemented on your platform. static PyObject * os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, int follow_symlinks) -/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/ +/*[clinic end generated code: output=5cf6a94915cc7bff input=674a14bc998de09d]*/ { int result; @@ -3312,7 +3286,18 @@ os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, } else #endif /* HAVE_FHCMODAT */ + { +#ifdef HAVE_CHMOD result = chmod(path->narrow, mode); +#elif defined(__wasi__) + // WASI SDK 15.0 does not support chmod. + // Ignore missing syscall for now. + result = 0; +#else + result = -1; + errno = ENOSYS; +#endif + } Py_END_ALLOW_THREADS if (result) { @@ -3347,7 +3332,12 @@ os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, os.fchmod fd: int + The file descriptor of the file to be modified. mode: int + Operating-system mode bitfield. + Be careful when using number literals for *mode*. The conventional UNIX notation for + numeric modes uses an octal base, which needs to be indicated with a ``0o`` prefix in + Python. Change the access permissions of the file given by file descriptor fd. @@ -3356,7 +3346,7 @@ Equivalent to os.chmod(fd, mode). static PyObject * os_fchmod_impl(PyObject *module, int fd, int mode) -/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/ +/*[clinic end generated code: output=afd9bc05b4e426b3 input=b5594618bbbc22df]*/ { int res; int async_err = 0; @@ -4062,14 +4052,12 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) Py_SETREF(v, PyUnicode_EncodeFSDefault(v)); } if (v == NULL) { - Py_DECREF(list); - list = NULL; + Py_SETREF(list, NULL); break; } if (PyList_Append(list, v) != 0) { Py_DECREF(v); - Py_DECREF(list); - list = NULL; + Py_SETREF(list, NULL); break; } Py_DECREF(v); @@ -4139,8 +4127,8 @@ _posix_listdir(path_t *path, PyObject *list) const char *name; if (path->narrow) { name = path->narrow; - /* only return bytes if they specified a bytes-like object */ - return_str = !PyObject_CheckBuffer(path->object); + /* only return bytes if they specified a bytes object */ + return_str = !PyBytes_Check(path->object); } else { name = "."; @@ -4253,6 +4241,48 @@ os_listdir_impl(PyObject *module, path_t *path) } #ifdef MS_WINDOWS +int +_PyOS_getfullpathname(const wchar_t *path, wchar_t **abspath_p) +{ + wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf; + DWORD result; + + result = GetFullPathNameW(path, + Py_ARRAY_LENGTH(woutbuf), woutbuf, + NULL); + if (!result) { + return -1; + } + + if (result >= Py_ARRAY_LENGTH(woutbuf)) { + if ((size_t)result <= (size_t)PY_SSIZE_T_MAX / sizeof(wchar_t)) { + woutbufp = PyMem_RawMalloc((size_t)result * sizeof(wchar_t)); + } + else { + woutbufp = NULL; + } + if (!woutbufp) { + *abspath_p = NULL; + return 0; + } + + result = GetFullPathNameW(path, result, woutbufp, NULL); + if (!result) { + PyMem_RawFree(woutbufp); + return -1; + } + } + + if (woutbufp != woutbuf) { + *abspath_p = woutbufp; + return 0; + } + + *abspath_p = _PyMem_RawWcsdup(woutbufp); + return 0; +} + + /* A helper function for abspath on win32 */ /*[clinic input] os._getfullpathname @@ -4268,8 +4298,7 @@ os__getfullpathname_impl(PyObject *module, path_t *path) { wchar_t *abspath; - /* _Py_abspath() is implemented with GetFullPathNameW() on Windows */ - if (_Py_abspath(path->wide, &abspath) < 0) { + if (_PyOS_getfullpathname(path->wide, &abspath) < 0) { return win32_error_object("GetFullPathNameW", path->object); } if (abspath == NULL) { @@ -4464,6 +4493,33 @@ os__path_splitroot_impl(PyObject *module, path_t *path) #endif /* MS_WINDOWS */ +/*[clinic input] +os._path_normpath + + path: object + +Basic path normalization. +[clinic start generated code]*/ + +static PyObject * +os__path_normpath_impl(PyObject *module, PyObject *path) +/*[clinic end generated code: output=b94d696d828019da input=5e90c39e12549dc0]*/ +{ + if (!PyUnicode_Check(path)) { + PyErr_Format(PyExc_TypeError, "expected 'str', not '%.200s'", + Py_TYPE(path)->tp_name); + return NULL; + } + Py_ssize_t len; + wchar_t *buffer = PyUnicode_AsWideCharString(path, &len); + if (!buffer) { + return NULL; + } + PyObject *result = PyUnicode_FromWideChar(_Py_normpath(buffer, len), -1); + PyMem_Free(buffer); + return result; +} + /*[clinic input] os.mkdir @@ -4484,12 +4540,13 @@ If dir_fd is not None, it should be a file descriptor open to a directory, dir_fd may not be implemented on your platform. If it is unavailable, using it will raise a NotImplementedError. -The mode argument is ignored on Windows. +The mode argument is ignored on Windows. Where it is used, the current umask +value is first masked out. [clinic start generated code]*/ static PyObject * os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd) -/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/ +/*[clinic end generated code: output=a70446903abe821f input=a61722e1576fab03]*/ { int result; #ifdef HAVE_MKDIRAT @@ -4878,6 +4935,7 @@ os_system_impl(PyObject *module, PyObject *command) #endif /* HAVE_SYSTEM */ +#ifdef HAVE_UMASK /*[clinic input] os.umask @@ -4896,6 +4954,7 @@ os_umask_impl(PyObject *module, int mask) return posix_error(); return PyLong_FromLong((long)i); } +#endif #ifdef MS_WINDOWS @@ -5737,6 +5796,13 @@ os_execv_impl(PyObject *module, path_t *path, PyObject *argv) EXECV_CHAR **argvlist; Py_ssize_t argc; + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (!_PyInterpreterState_HasFeature(interp, Py_RTFLAGS_EXEC)) { + PyErr_SetString(PyExc_RuntimeError, + "exec not supported for isolated subinterpreters"); + return NULL; + } + /* execv has two arguments: (path, argv), where argv is a list or tuple of strings. */ @@ -5803,6 +5869,13 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) EXECV_CHAR **envlist; Py_ssize_t argc, envc; + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (!_PyInterpreterState_HasFeature(interp, Py_RTFLAGS_EXEC)) { + PyErr_SetString(PyExc_RuntimeError, + "exec not supported for isolated subinterpreters"); + return NULL; + } + /* execve has three arguments: (path, argv, env), where argv is a list or tuple of strings and env is a dictionary like posix.environ. */ @@ -5934,6 +6007,7 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg } +#ifdef HAVE_SIGSET_T if (setsigmask) { sigset_t set; if (!_Py_Sigset_Converter(setsigmask, &set)) { @@ -5959,6 +6033,13 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg } all_flags |= POSIX_SPAWN_SETSIGDEF; } +#else + if (setsigmask || setsigdef) { + PyErr_SetString(PyExc_NotImplementedError, + "sigset is not supported on this platform"); + goto fail; + } +#endif if (scheduler) { #ifdef POSIX_SPAWN_SETSCHEDULER @@ -6267,9 +6348,9 @@ os.posix_spawn A sequence of file action tuples. setpgroup: object = NULL The pgroup to use with the POSIX_SPAWN_SETPGROUP flag. - resetids: bool(accept={int}) = False + resetids: bool = False If the value is `true` the POSIX_SPAWN_RESETIDS will be activated. - setsid: bool(accept={int}) = False + setsid: bool = False If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated. setsigmask: object(c_default='NULL') = () The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag. @@ -6287,7 +6368,7 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask, PyObject *setsigdef, PyObject *scheduler) -/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/ +/*[clinic end generated code: output=14a1098c566bc675 input=808aed1090d84e33]*/ { return py_posix_spawn(0, module, path, argv, env, file_actions, setpgroup, resetids, setsid, setsigmask, setsigdef, @@ -6313,9 +6394,9 @@ os.posix_spawnp A sequence of file action tuples. setpgroup: object = NULL The pgroup to use with the POSIX_SPAWN_SETPGROUP flag. - resetids: bool(accept={int}) = False + resetids: bool = False If the value is `True` the POSIX_SPAWN_RESETIDS will be activated. - setsid: bool(accept={int}) = False + setsid: bool = False If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated. setsigmask: object(c_default='NULL') = () The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag. @@ -6333,7 +6414,7 @@ os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask, PyObject *setsigdef, PyObject *scheduler) -/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/ +/*[clinic end generated code: output=7b9aaefe3031238d input=9e89e616116752a1]*/ { return py_posix_spawn(1, module, path, argv, env, file_actions, setpgroup, resetids, setsid, setsigmask, setsigdef, @@ -6665,6 +6746,104 @@ os_register_at_fork_impl(PyObject *module, PyObject *before, } #endif /* HAVE_FORK */ +// Common code to raise a warning if we detect there is more than one thread +// running in the process. Best effort, silent if unable to count threads. +// Constraint: Quick. Never overcounts. Never leaves an error set. +// +// This code might do an import, thus acquiring the import lock, which +// PyOS_BeforeFork() also does. As this should only be called from +// the parent process, it is in the same thread so that works. +static void warn_about_fork_with_threads(const char* name) { + // TODO: Consider making an `os` module API to return the current number + // of threads in the process. That'd presumably use this platform code but + // raise an error rather than using the inaccurate fallback. + Py_ssize_t num_python_threads = 0; +#if defined(__APPLE__) && defined(HAVE_GETPID) + mach_port_t macos_self = mach_task_self(); + mach_port_t macos_task; + if (task_for_pid(macos_self, getpid(), &macos_task) == KERN_SUCCESS) { + thread_array_t macos_threads; + mach_msg_type_number_t macos_n_threads; + if (task_threads(macos_task, &macos_threads, + &macos_n_threads) == KERN_SUCCESS) { + num_python_threads = macos_n_threads; + } + } +#elif defined(__linux__) + // Linux /proc/self/stat 20th field is the number of threads. + FILE* proc_stat = fopen("/proc/self/stat", "r"); + if (proc_stat) { + size_t n; + // Size chosen arbitrarily. ~60% more bytes than a 20th column index + // observed on the author's workstation. + char stat_line[160]; + n = fread(&stat_line, 1, 159, proc_stat); + stat_line[n] = '\0'; + fclose(proc_stat); + + char *saveptr = NULL; + char *field = strtok_r(stat_line, " ", &saveptr); + unsigned int idx; + for (idx = 19; idx && field; --idx) { + field = strtok_r(NULL, " ", &saveptr); + } + if (idx == 0 && field) { // found the 20th field + num_python_threads = atoi(field); // 0 on error + } + } +#endif + if (num_python_threads <= 0) { + // Fall back to just the number our threading module knows about. + // An incomplete view of the world, but better than nothing. + PyObject *threading = PyImport_GetModule(&_Py_ID(threading)); + if (!threading) { + PyErr_Clear(); + return; + } + PyObject *threading_active = + PyObject_GetAttr(threading, &_Py_ID(_active)); + if (!threading_active) { + PyErr_Clear(); + Py_DECREF(threading); + return; + } + PyObject *threading_limbo = + PyObject_GetAttr(threading, &_Py_ID(_limbo)); + if (!threading_limbo) { + PyErr_Clear(); + Py_DECREF(threading); + Py_DECREF(threading_active); + return; + } + Py_DECREF(threading); + // Duplicating what threading.active_count() does but without holding + // threading._active_limbo_lock so our count could be inaccurate if + // these dicts are mid-update from another thread. Not a big deal. + // Worst case if someone replaced threading._active or threading._limbo + // with non-dicts, we get -1 from *Length() below and undercount. + // Nobody should, but we're best effort so we clear errors and move on. + num_python_threads = (PyMapping_Length(threading_active) + + PyMapping_Length(threading_limbo)); + PyErr_Clear(); + Py_DECREF(threading_active); + Py_DECREF(threading_limbo); + } + if (num_python_threads > 1) { + PyErr_WarnFormat( + PyExc_DeprecationWarning, 1, +#ifdef HAVE_GETPID + "This process (pid=%d) is multi-threaded, " +#else + "This process is multi-threaded, " +#endif + "use of %s() may lead to deadlocks in the child.", +#ifdef HAVE_GETPID + getpid(), +#endif + name); + PyErr_Clear(); + } +} #ifdef HAVE_FORK1 /*[clinic input] @@ -6681,7 +6860,7 @@ os_fork1_impl(PyObject *module) { pid_t pid; - if (_PyInterpreterState_GET() != PyInterpreterState_Main()) { + if (!_Py_IsMainInterpreter(_PyInterpreterState_GET())) { PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); return NULL; } @@ -6691,6 +6870,7 @@ os_fork1_impl(PyObject *module) /* child: this clobbers and resets the import lock. */ PyOS_AfterFork_Child(); } else { + warn_about_fork_with_threads("fork1"); /* parent: release the import lock. */ PyOS_AfterFork_Parent(); } @@ -6716,7 +6896,7 @@ os_fork_impl(PyObject *module) { pid_t pid; PyInterpreterState *interp = _PyInterpreterState_GET(); - if (interp->config._isolated_interpreter) { + if (!_PyInterpreterState_HasFeature(interp, Py_RTFLAGS_FORK)) { PyErr_SetString(PyExc_RuntimeError, "fork not supported for isolated subinterpreters"); return NULL; @@ -6730,6 +6910,7 @@ os_fork_impl(PyObject *module) /* child: this clobbers and resets the import lock. */ PyOS_AfterFork_Child(); } else { + warn_about_fork_with_threads("fork"); /* parent: release the import lock. */ PyOS_AfterFork_Parent(); } @@ -6830,8 +7011,7 @@ os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority) res = PyStructSequence_New(type); if (!res) return NULL; - Py_INCREF(sched_priority); - PyStructSequence_SET_ITEM(res, 0, sched_priority); + PyStructSequence_SET_ITEM(res, 0, Py_NewRef(sched_priority)); return res; } @@ -7010,8 +7190,13 @@ static PyObject * os_sched_yield_impl(PyObject *module) /*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/ { - if (sched_yield()) + int result; + Py_BEGIN_ALLOW_THREADS + result = sched_yield(); + Py_END_ALLOW_THREADS + if (result < 0) { return posix_error(); + } Py_RETURN_NONE; } @@ -7196,22 +7381,21 @@ error: # define DEV_PTY_FILE "/dev/ptmx" #endif -#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) +#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_LOGIN_TTY) || defined(HAVE_DEV_PTMX) #ifdef HAVE_PTY_H #include -#else -#ifdef HAVE_LIBUTIL_H +#ifdef HAVE_UTMP_H +#include +#endif /* HAVE_UTMP_H */ +#elif defined(HAVE_LIBUTIL_H) #include -#else -#ifdef HAVE_UTIL_H +#elif defined(HAVE_UTIL_H) #include -#endif /* HAVE_UTIL_H */ -#endif /* HAVE_LIBUTIL_H */ #endif /* HAVE_PTY_H */ #ifdef HAVE_STROPTS_H #include #endif -#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */ +#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_LOGIN_TTY) || defined(HAVE_DEV_PTMX) */ #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) @@ -7314,6 +7498,56 @@ error: #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */ +#if defined(HAVE_SETSID) && defined(TIOCSCTTY) +#define HAVE_FALLBACK_LOGIN_TTY 1 +#endif /* defined(HAVE_SETSID) && defined(TIOCSCTTY) */ + +#if defined(HAVE_LOGIN_TTY) || defined(HAVE_FALLBACK_LOGIN_TTY) +/*[clinic input] +os.login_tty + + fd: fildes + / + +Prepare the tty of which fd is a file descriptor for a new login session. + +Make the calling process a session leader; make the tty the +controlling tty, the stdin, the stdout, and the stderr of the +calling process; close fd. +[clinic start generated code]*/ + +static PyObject * +os_login_tty_impl(PyObject *module, int fd) +/*[clinic end generated code: output=495a79911b4cc1bc input=5f298565099903a2]*/ +{ +#ifdef HAVE_LOGIN_TTY + if (login_tty(fd) == -1) { + return posix_error(); + } +#else /* defined(HAVE_FALLBACK_LOGIN_TTY) */ + /* Establish a new session. */ + if (setsid() == -1) { + return posix_error(); + } + + /* The tty becomes the controlling terminal. */ + if (ioctl(fd, TIOCSCTTY, (char *)NULL) == -1) { + return posix_error(); + } + + /* The tty becomes stdin/stdout/stderr */ + if (dup2(fd, 0) == -1 || dup2(fd, 1) == -1 || dup2(fd, 2) == -1) { + return posix_error(); + } + if (fd > 2) { + close(fd); + } +#endif /* HAVE_LOGIN_TTY */ + Py_RETURN_NONE; +} +#endif /* defined(HAVE_LOGIN_TTY) || defined(HAVE_FALLBACK_LOGIN_TTY) */ + + #ifdef HAVE_FORKPTY /*[clinic input] os.forkpty @@ -7333,7 +7567,7 @@ os_forkpty_impl(PyObject *module) int master_fd = -1; pid_t pid; - if (_PyInterpreterState_GET() != PyInterpreterState_Main()) { + if (!_Py_IsMainInterpreter(_PyInterpreterState_GET())) { PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); return NULL; } @@ -7346,11 +7580,13 @@ os_forkpty_impl(PyObject *module) /* child: this clobbers and resets the import lock. */ PyOS_AfterFork_Child(); } else { + warn_about_fork_with_threads("forkpty"); /* parent: release the import lock. */ PyOS_AfterFork_Parent(); } - if (pid == -1) + if (pid == -1) { return posix_error(); + } return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd); } #endif /* HAVE_FORKPTY */ @@ -7559,93 +7795,47 @@ static PyObject * os_getgroups_impl(PyObject *module) /*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/ { - PyObject *result = NULL; - gid_t grouplist[MAX_GROUPS]; - - /* On MacOSX getgroups(2) can return more than MAX_GROUPS results - * This is a helper variable to store the intermediate result when - * that happens. - * - * To keep the code readable the OSX behaviour is unconditional, - * according to the POSIX spec this should be safe on all unix-y - * systems. - */ - gid_t* alt_grouplist = grouplist; - int n; - -#ifdef __APPLE__ - /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if - * there are more groups than can fit in grouplist. Therefore, on OS X - * always first call getgroups with length 0 to get the actual number - * of groups. - */ - n = getgroups(0, NULL); + // Call getgroups with length 0 to get the actual number of groups + int n = getgroups(0, NULL); if (n < 0) { return posix_error(); - } else if (n <= MAX_GROUPS) { - /* groups will fit in existing array */ - alt_grouplist = grouplist; - } else { - alt_grouplist = PyMem_New(gid_t, n); - if (alt_grouplist == NULL) { - return PyErr_NoMemory(); - } } - n = getgroups(n, alt_grouplist); + if (n == 0) { + return PyList_New(0); + } + + gid_t *grouplist = PyMem_New(gid_t, n); + if (grouplist == NULL) { + return PyErr_NoMemory(); + } + + n = getgroups(n, grouplist); if (n == -1) { - if (alt_grouplist != grouplist) { - PyMem_Free(alt_grouplist); - } + PyMem_Free(grouplist); return posix_error(); } -#else - n = getgroups(MAX_GROUPS, grouplist); - if (n < 0) { - if (errno == EINVAL) { - n = getgroups(0, NULL); - if (n == -1) { - return posix_error(); - } - if (n == 0) { - /* Avoid malloc(0) */ - alt_grouplist = grouplist; - } else { - alt_grouplist = PyMem_New(gid_t, n); - if (alt_grouplist == NULL) { - return PyErr_NoMemory(); - } - n = getgroups(n, alt_grouplist); - if (n == -1) { - PyMem_Free(alt_grouplist); - return posix_error(); - } - } - } else { - return posix_error(); - } - } -#endif - result = PyList_New(n); - if (result != NULL) { - int i; - for (i = 0; i < n; ++i) { - PyObject *o = _PyLong_FromGid(alt_grouplist[i]); - if (o == NULL) { - Py_DECREF(result); - result = NULL; - break; - } - PyList_SET_ITEM(result, i, o); - } + PyObject *result = PyList_New(n); + if (result == NULL) { + goto error; } - if (alt_grouplist != grouplist) { - PyMem_Free(alt_grouplist); + for (int i = 0; i < n; ++i) { + PyObject *group = _PyLong_FromGid(grouplist[i]); + if (group == NULL) { + goto error; + } + PyList_SET_ITEM(result, i, group); } + PyMem_Free(grouplist); return result; + +error: + PyMem_Free(grouplist); + Py_XDECREF(result); + return NULL; } #endif /* HAVE_GETGROUPS */ @@ -7909,8 +8099,17 @@ os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal) return NULL; } #ifndef MS_WINDOWS - if (kill(pid, (int)signal) == -1) + if (kill(pid, (int)signal) == -1) { return posix_error(); + } + + // Check immediately if the signal was sent to the current process. + // Don't micro-optimize pid == getpid(), since PyErr_SetString() check + // is cheap. + if (PyErr_CheckSignals()) { + return NULL; + } + Py_RETURN_NONE; #else /* !MS_WINDOWS */ PyObject *result; @@ -7941,8 +8140,7 @@ os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal) err = GetLastError(); result = PyErr_SetFromWindowsErr(err); } else { - Py_INCREF(Py_None); - result = Py_None; + result = Py_NewRef(Py_None); } CloseHandle(handle); @@ -8148,14 +8346,11 @@ static PyObject * os_setgroups(PyObject *module, PyObject *groups) /*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/ { - Py_ssize_t i, len; - gid_t grouplist[MAX_GROUPS]; - if (!PySequence_Check(groups)) { PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence"); return NULL; } - len = PySequence_Size(groups); + Py_ssize_t len = PySequence_Size(groups); if (len < 0) { return NULL; } @@ -8163,27 +8358,36 @@ os_setgroups(PyObject *module, PyObject *groups) PyErr_SetString(PyExc_ValueError, "too many groups"); return NULL; } - for(i = 0; i < len; i++) { + + gid_t *grouplist = PyMem_New(gid_t, len); + for (Py_ssize_t i = 0; i < len; i++) { PyObject *elem; elem = PySequence_GetItem(groups, i); - if (!elem) + if (!elem) { + PyMem_Free(grouplist); return NULL; + } if (!PyLong_Check(elem)) { PyErr_SetString(PyExc_TypeError, "groups must be integers"); Py_DECREF(elem); + PyMem_Free(grouplist); return NULL; } else { if (!_Py_Gid_Converter(elem, &grouplist[i])) { Py_DECREF(elem); + PyMem_Free(grouplist); return NULL; } } Py_DECREF(elem); } - if (setgroups(len, grouplist) < 0) + if (setgroups(len, grouplist) < 0) { + PyMem_Free(grouplist); return posix_error(); + } + PyMem_Free(grouplist); Py_RETURN_NONE; } #endif /* HAVE_SETGROUPS */ @@ -8204,11 +8408,7 @@ wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru) memset(ru, 0, sizeof(*ru)); } - PyObject *m = PyImport_ImportModuleNoBlock("resource"); - if (m == NULL) - return NULL; - struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage); - Py_DECREF(m); + struct_rusage = _PyImport_GetModuleAttrString("resource", "struct_rusage"); if (struct_rusage == NULL) return NULL; @@ -8517,6 +8717,64 @@ os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags) #endif +#ifdef HAVE_SETNS +/*[clinic input] +os.setns + fd: fildes + A file descriptor to a namespace. + nstype: int = 0 + Type of namespace. + +Move the calling thread into different namespaces. +[clinic start generated code]*/ + +static PyObject * +os_setns_impl(PyObject *module, int fd, int nstype) +/*[clinic end generated code: output=5dbd055bfb66ecd0 input=42787871226bf3ee]*/ +{ + int res; + + Py_BEGIN_ALLOW_THREADS + res = setns(fd, nstype); + Py_END_ALLOW_THREADS + + if (res != 0) { + return posix_error(); + } + + Py_RETURN_NONE; +} +#endif + + +#ifdef HAVE_UNSHARE +/*[clinic input] +os.unshare + flags: int + Namespaces to be unshared. + +Disassociate parts of a process (or thread) execution context. +[clinic start generated code]*/ + +static PyObject * +os_unshare_impl(PyObject *module, int flags) +/*[clinic end generated code: output=1b3177906dd237ee input=9e065db3232b8b1b]*/ +{ + int res; + + Py_BEGIN_ALLOW_THREADS + res = unshare(flags); + Py_END_ALLOW_THREADS + + if (res != 0) { + return posix_error(); + } + + Py_RETURN_NONE; +} +#endif + + #if defined(HAVE_READLINK) || defined(MS_WINDOWS) /*[clinic input] os.readlink @@ -8918,11 +9176,6 @@ build_times_result(PyObject *module, double user, double system, } -#ifndef MS_WINDOWS -#define NEED_TICKS_PER_SECOND -static long ticks_per_second = -1; -#endif /* MS_WINDOWS */ - /*[clinic input] os.times @@ -8958,20 +9211,22 @@ os_times_impl(PyObject *module) } #else /* MS_WINDOWS */ { - - struct tms t; clock_t c; errno = 0; c = times(&t); - if (c == (clock_t) -1) + if (c == (clock_t) -1) { return posix_error(); + } + assert(_PyRuntime.time.ticks_per_second_initialized); +#define ticks_per_second _PyRuntime.time.ticks_per_second return build_times_result(module, (double)t.tms_utime / ticks_per_second, (double)t.tms_stime / ticks_per_second, (double)t.tms_cutime / ticks_per_second, (double)t.tms_cstime / ticks_per_second, (double)c / ticks_per_second); +#undef ticks_per_second } #endif /* MS_WINDOWS */ #endif /* HAVE_TIMES */ @@ -9245,7 +9500,9 @@ os_dup_impl(PyObject *module, int fd) return _Py_dup(fd); } - +// dup2() is either provided by libc or dup2.c with AC_REPLACE_FUNCS(). +// dup2.c provides working dup2() if and only if F_DUPFD is available. +#if (defined(HAVE_DUP3) || defined(F_DUPFD) || defined(MS_WINDOWS)) /*[clinic input] os.dup2 -> int fd: int @@ -9345,6 +9602,7 @@ os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable) return res; } +#endif #ifdef HAVE_LOCKF @@ -9703,7 +9961,7 @@ os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); #else do { -#ifdef __APPLE__ +#if defined(__APPLE__) && defined(__clang__) /* This entire function will be removed from the module dict when the API * is not available. */ @@ -9718,7 +9976,7 @@ os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, Py_END_ALLOW_THREADS } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); -#ifdef __APPLE__ +#if defined(__APPLE__) && defined(__clang__) #pragma clang diagnostic pop #endif @@ -10345,7 +10603,7 @@ os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); #else -#ifdef __APPLE__ +#if defined(__APPLE__) && defined(__clang__) /* This entire function will be removed from the module dict when the API * is not available. */ @@ -10361,7 +10619,7 @@ os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, Py_END_ALLOW_THREADS } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); -#ifdef __APPLE__ +#if defined(__APPLE__) && defined(__clang__) #pragma clang diagnostic pop #endif @@ -10540,18 +10798,35 @@ os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd) { int result; int async_err = 0; +#ifdef HAVE_MKFIFOAT + int mkfifoat_unavailable = 0; +#endif do { Py_BEGIN_ALLOW_THREADS #ifdef HAVE_MKFIFOAT - if (dir_fd != DEFAULT_DIR_FD) - result = mkfifoat(dir_fd, path->narrow, mode); - else + if (dir_fd != DEFAULT_DIR_FD) { + if (HAVE_MKFIFOAT_RUNTIME) { + result = mkfifoat(dir_fd, path->narrow, mode); + + } else { + mkfifoat_unavailable = 1; + result = 0; + } + } else #endif result = mkfifo(path->narrow, mode); Py_END_ALLOW_THREADS } while (result != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + +#ifdef HAVE_MKFIFOAT + if (mkfifoat_unavailable) { + argument_unavailable_error(NULL, "dir_fd"); + return NULL; + } +#endif + if (result != 0) return (!async_err) ? posix_error() : NULL; @@ -10592,18 +10867,33 @@ os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device, { int result; int async_err = 0; +#ifdef HAVE_MKNODAT + int mknodat_unavailable = 0; +#endif do { Py_BEGIN_ALLOW_THREADS #ifdef HAVE_MKNODAT - if (dir_fd != DEFAULT_DIR_FD) - result = mknodat(dir_fd, path->narrow, mode, device); - else + if (dir_fd != DEFAULT_DIR_FD) { + if (HAVE_MKNODAT_RUNTIME) { + result = mknodat(dir_fd, path->narrow, mode, device); + + } else { + mknodat_unavailable = 1; + result = 0; + } + } else #endif result = mknod(path->narrow, mode, device); Py_END_ALLOW_THREADS } while (result != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); +#ifdef HAVE_MKNODAT + if (mknodat_unavailable) { + argument_unavailable_error(NULL, "dir_fd"); + return NULL; + } +#endif if (result != 0) return (!async_err) ? posix_error() : NULL; @@ -12322,6 +12612,9 @@ static struct constdef posix_constants_sysconf[] = { #ifdef _SC_XOPEN_XPG4 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4}, #endif +#ifdef _SC_MINSIGSTKSZ + {"SC_MINSIGSTKSZ", _SC_MINSIGSTKSZ}, +#endif }; static int @@ -12950,15 +13243,13 @@ os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks) PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start, trace - start); if (!attribute) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); goto exit; } error = PyList_Append(result, attribute); Py_DECREF(attribute); if (error) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); goto exit; } start = trace + 1; @@ -13030,7 +13321,7 @@ os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags) } #endif -#ifdef HAVE_EVENTFD +#if defined(HAVE_EVENTFD) && defined(EFD_CLOEXEC) /*[clinic input] os.eventfd @@ -13101,7 +13392,7 @@ os_eventfd_write_impl(PyObject *module, int fd, unsigned long long value) } Py_RETURN_NONE; } -#endif /* HAVE_EVENTFD */ +#endif /* HAVE_EVENTFD && EFD_CLOEXEC */ /* Terminal size querying */ @@ -13170,24 +13461,11 @@ os_get_terminal_size_impl(PyObject *module, int fd) #ifdef TERMSIZE_USE_CONIO { - DWORD nhandle; HANDLE handle; CONSOLE_SCREEN_BUFFER_INFO csbi; - switch (fd) { - case 0: nhandle = STD_INPUT_HANDLE; - break; - case 1: nhandle = STD_OUTPUT_HANDLE; - break; - case 2: nhandle = STD_ERROR_HANDLE; - break; - default: - return PyErr_Format(PyExc_ValueError, "bad file descriptor"); - } - handle = GetStdHandle(nhandle); - if (handle == NULL) - return PyErr_Format(PyExc_OSError, "handle cannot be retrieved"); + handle = _Py_get_osfhandle(fd); if (handle == INVALID_HANDLE_VALUE) - return PyErr_SetFromWindowsErr(0); + return NULL; if (!GetConsoleScreenBufferInfo(handle, &csbi)) return PyErr_SetFromWindowsErr(0); @@ -13372,7 +13650,7 @@ os_get_blocking_impl(PyObject *module, int fd) /*[clinic input] os.set_blocking fd: int - blocking: bool(accept={int}) + blocking: bool / Set the blocking mode of the specified file descriptor. @@ -13383,7 +13661,7 @@ clear the O_NONBLOCK flag otherwise. static PyObject * os_set_blocking_impl(PyObject *module, int fd, int blocking) -/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/ +/*[clinic end generated code: output=384eb43aa0762a9d input=7e9dfc9b14804dd4]*/ { int result; @@ -13465,6 +13743,25 @@ os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class) #endif } +/*[clinic input] +os.DirEntry.is_junction -> bool + defining_class: defining_class + / + +Return True if the entry is a junction; cached per entry. +[clinic start generated code]*/ + +static int +os_DirEntry_is_junction_impl(DirEntry *self, PyTypeObject *defining_class) +/*[clinic end generated code: output=7061a07b0ef2cd1f input=475cd36fb7d4723f]*/ +{ +#ifdef MS_WINDOWS + return self->win32_lstat.st_reparse_tag == IO_REPARSE_TAG_MOUNT_POINT; +#else + return 0; +#endif +} + static PyObject * DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks) { @@ -13475,15 +13772,8 @@ DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks) #ifdef MS_WINDOWS if (!PyUnicode_FSDecoder(self->path, &ub)) return NULL; -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - const wchar_t *path = PyUnicode_AsUnicode(ub); -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ wchar_t *path = PyUnicode_AsWideCharString(ub, NULL); Py_DECREF(ub); -#endif /* USE_UNICODE_WCHAR_CACHE */ #else /* POSIX */ if (!PyUnicode_FSConverter(self->path, &ub)) return NULL; @@ -13516,11 +13806,11 @@ _Py_COMP_DIAG_POP } Py_END_ALLOW_THREADS } -#if defined(MS_WINDOWS) && !USE_UNICODE_WCHAR_CACHE +#if defined(MS_WINDOWS) PyMem_Free(path); -#else /* USE_UNICODE_WCHAR_CACHE */ +#else Py_DECREF(ub); -#endif /* USE_UNICODE_WCHAR_CACHE */ +#endif if (result != 0) return path_object_error(self->path); @@ -13539,8 +13829,7 @@ DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self) self->lstat = DirEntry_fetch_stat(module, self, 0); #endif } - Py_XINCREF(self->lstat); - return self->lstat; + return Py_XNewRef(self->lstat); } /*[clinic input] @@ -13576,8 +13865,7 @@ os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class, } } - Py_XINCREF(self->stat); - return self->stat; + return Py_XNewRef(self->stat); } /* Set exception and return -1 on error, 0 for False, 1 for True */ @@ -13714,19 +14002,10 @@ os_DirEntry_inode_impl(DirEntry *self) if (!PyUnicode_FSDecoder(self->path, &unicode)) return NULL; -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - const wchar_t *path = PyUnicode_AsUnicode(unicode); - result = LSTAT(path, &stat); - Py_DECREF(unicode); -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ wchar_t *path = PyUnicode_AsWideCharString(unicode, NULL); Py_DECREF(unicode); result = LSTAT(path, &stat); PyMem_Free(path); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (result != 0) return path_object_error(self->path); @@ -13734,10 +14013,12 @@ _Py_COMP_DIAG_POP self->win32_file_index = stat.st_ino; self->got_file_index = 1; } - Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->win32_file_index)); + static_assert(sizeof(unsigned long long) >= sizeof(self->win32_file_index), + "DirEntry.win32_file_index is larger than unsigned long long"); return PyLong_FromUnsignedLongLong(self->win32_file_index); #else /* POSIX */ - Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(self->d_ino)); + static_assert(sizeof(unsigned long long) >= sizeof(self->d_ino), + "DirEntry.d_ino is larger than unsigned long long"); return PyLong_FromUnsignedLongLong(self->d_ino); #endif } @@ -13758,8 +14039,7 @@ static PyObject * os_DirEntry___fspath___impl(DirEntry *self) /*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/ { - Py_INCREF(self->path); - return self->path; + return Py_NewRef(self->path); } static PyMemberDef DirEntry_members[] = { @@ -13776,6 +14056,7 @@ static PyMethodDef DirEntry_methods[] = { OS_DIRENTRY_IS_DIR_METHODDEF OS_DIRENTRY_IS_FILE_METHODDEF OS_DIRENTRY_IS_SYMLINK_METHODDEF + OS_DIRENTRY_IS_JUNCTION_METHODDEF OS_DIRENTRY_STAT_METHODDEF OS_DIRENTRY_INODE_METHODDEF OS_DIRENTRY___FSPATH___METHODDEF @@ -13952,7 +14233,7 @@ DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name, goto error; } - if (!path->narrow || !PyObject_CheckBuffer(path->object)) { + if (!path->narrow || !PyBytes_Check(path->object)) { entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len); if (joined_path) entry->path = PyUnicode_DecodeFSDefault(joined_path); @@ -13967,8 +14248,7 @@ DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name, goto error; if (path->fd != -1) { - entry->path = entry->name; - Py_INCREF(entry->path); + entry->path = Py_NewRef(entry->name); } else if (!entry->path) goto error; @@ -14159,8 +14439,7 @@ ScandirIterator_close(ScandirIterator *self, PyObject *args) static PyObject * ScandirIterator_enter(PyObject *self, PyObject *args) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * @@ -14368,11 +14647,10 @@ PyOS_FSPath(PyObject *path) PyObject *path_repr = NULL; if (PyUnicode_Check(path) || PyBytes_Check(path)) { - Py_INCREF(path); - return path; + return Py_NewRef(path); } - func = _PyObject_LookupSpecial(path, &PyId___fspath__); + func = _PyObject_LookupSpecial(path, &_Py_ID(__fspath__)); if (NULL == func) { return PyErr_Format(PyExc_TypeError, "expected str, bytes or os.PathLike object, " @@ -14745,6 +15023,7 @@ static PyMethodDef posix_methods[] = { OS_SCHED_SETAFFINITY_METHODDEF OS_SCHED_GETAFFINITY_METHODDEF OS_OPENPTY_METHODDEF + OS_LOGIN_TTY_METHODDEF OS_FORKPTY_METHODDEF OS_GETEGID_METHODDEF OS_GETEUID_METHODDEF @@ -14838,6 +15117,7 @@ static PyMethodDef posix_methods[] = { OS__GETFINALPATHNAME_METHODDEF OS__GETVOLUMEPATHNAME_METHODDEF OS__PATH_SPLITROOT_METHODDEF + OS__PATH_NORMPATH_METHODDEF OS_GETLOADAVG_METHODDEF OS_URANDOM_METHODDEF OS_SETRESUID_METHODDEF @@ -14868,6 +15148,8 @@ static PyMethodDef posix_methods[] = { OS__ADD_DLL_DIRECTORY_METHODDEF OS__REMOVE_DLL_DIRECTORY_METHODDEF OS_WAITSTATUS_TO_EXITCODE_METHODDEF + OS_SETNS_METHODDEF + OS_UNSHARE_METHODDEF {NULL, NULL} /* Sentinel */ }; @@ -15154,12 +15436,16 @@ all_ins(PyObject *m) #ifdef SF_NODISKIO if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1; #endif + /* is obsolete since the 11.x release */ #ifdef SF_MNOWAIT if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1; #endif #ifdef SF_SYNC if (PyModule_AddIntMacro(m, SF_SYNC)) return -1; #endif +#ifdef SF_NOCACHE + if (PyModule_AddIntMacro(m, SF_NOCACHE)) return -1; +#endif /* constants for posix_fadvise */ #ifdef POSIX_FADV_NORMAL @@ -15189,6 +15475,9 @@ all_ins(PyObject *m) #ifdef P_PIDFD if (PyModule_AddIntMacro(m, P_PIDFD)) return -1; #endif +#ifdef PIDFD_NONBLOCK + if (PyModule_AddIntMacro(m, PIDFD_NONBLOCK)) return -1; +#endif #endif #ifdef WEXITED if (PyModule_AddIntMacro(m, WEXITED)) return -1; @@ -15306,6 +15595,53 @@ all_ins(PyObject *m) #ifdef SCHED_FX if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1; #endif + +/* constants for namespaces */ +#if defined(HAVE_SETNS) || defined(HAVE_UNSHARE) +#ifdef CLONE_FS + if (PyModule_AddIntMacro(m, CLONE_FS)) return -1; +#endif +#ifdef CLONE_FILES + if (PyModule_AddIntMacro(m, CLONE_FILES)) return -1; +#endif +#ifdef CLONE_NEWNS + if (PyModule_AddIntMacro(m, CLONE_NEWNS)) return -1; +#endif +#ifdef CLONE_NEWCGROUP + if (PyModule_AddIntMacro(m, CLONE_NEWCGROUP)) return -1; +#endif +#ifdef CLONE_NEWUTS + if (PyModule_AddIntMacro(m, CLONE_NEWUTS)) return -1; +#endif +#ifdef CLONE_NEWIPC + if (PyModule_AddIntMacro(m, CLONE_NEWIPC)) return -1; +#endif +#ifdef CLONE_NEWUSER + if (PyModule_AddIntMacro(m, CLONE_NEWUSER)) return -1; +#endif +#ifdef CLONE_NEWPID + if (PyModule_AddIntMacro(m, CLONE_NEWPID)) return -1; +#endif +#ifdef CLONE_NEWNET + if (PyModule_AddIntMacro(m, CLONE_NEWNET)) return -1; +#endif +#ifdef CLONE_NEWTIME + if (PyModule_AddIntMacro(m, CLONE_NEWTIME)) return -1; +#endif +#ifdef CLONE_SYSVSEM + if (PyModule_AddIntMacro(m, CLONE_SYSVSEM)) return -1; +#endif +#ifdef CLONE_THREAD + if (PyModule_AddIntMacro(m, CLONE_THREAD)) return -1; +#endif +#ifdef CLONE_SIGHAND + if (PyModule_AddIntMacro(m, CLONE_SIGHAND)) return -1; +#endif +#ifdef CLONE_VM + if (PyModule_AddIntMacro(m, CLONE_VM)) return -1; +#endif +#endif + #endif #ifdef USE_XATTRS @@ -15393,14 +15729,21 @@ all_ins(PyObject *m) #endif #endif /* HAVE_MEMFD_CREATE */ -#ifdef HAVE_EVENTFD +#if defined(HAVE_EVENTFD) && defined(EFD_CLOEXEC) if (PyModule_AddIntMacro(m, EFD_CLOEXEC)) return -1; +#ifdef EFD_NONBLOCK if (PyModule_AddIntMacro(m, EFD_NONBLOCK)) return -1; +#endif +#ifdef EFD_SEMAPHORE if (PyModule_AddIntMacro(m, EFD_SEMAPHORE)) return -1; #endif +#endif /* HAVE_EVENTFD && EFD_CLOEXEC */ #if defined(__APPLE__) if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1; + if (PyModule_AddIntConstant(m, "_COPYFILE_STAT", COPYFILE_STAT)) return -1; + if (PyModule_AddIntConstant(m, "_COPYFILE_ACL", COPYFILE_ACL)) return -1; + if (PyModule_AddIntConstant(m, "_COPYFILE_XATTR", COPYFILE_XATTR)) return -1; #endif #ifdef MS_WINDOWS @@ -15454,6 +15797,14 @@ PROBE(probe_fdopendir, HAVE_FDOPENDIR_RUNTIME) PROBE(probe_mkdirat, HAVE_MKDIRAT_RUNTIME) #endif +#ifdef HAVE_MKFIFOAT +PROBE(probe_mkfifoat, HAVE_MKFIFOAT_RUNTIME) +#endif + +#ifdef HAVE_MKNODAT +PROBE(probe_mknodat, HAVE_MKNODAT_RUNTIME) +#endif + #ifdef HAVE_RENAMEAT PROBE(probe_renameat, HAVE_RENAMEAT_RUNTIME) #endif @@ -15587,11 +15938,11 @@ static const struct have_function { #endif #ifdef HAVE_MKFIFOAT - { "HAVE_MKFIFOAT", NULL }, + { "HAVE_MKFIFOAT", probe_mkfifoat }, #endif #ifdef HAVE_MKNODAT - { "HAVE_MKNODAT", NULL }, + { "HAVE_MKNODAT", probe_mknodat }, #endif #ifdef HAVE_OPENAT @@ -15661,8 +16012,7 @@ posixmodule_exec(PyObject *m) if (setup_confname_tables(m)) return -1; - Py_INCREF(PyExc_OSError); - PyModule_AddObject(m, "error", PyExc_OSError); + PyModule_AddObject(m, "error", Py_NewRef(PyExc_OSError)); #if defined(HAVE_WAITID) && !defined(__APPLE__) waitid_result_desc.name = MODNAME ".waitid_result"; @@ -15670,8 +16020,7 @@ posixmodule_exec(PyObject *m) if (WaitidResultType == NULL) { return -1; } - Py_INCREF(WaitidResultType); - PyModule_AddObject(m, "waitid_result", WaitidResultType); + PyModule_AddObject(m, "waitid_result", Py_NewRef(WaitidResultType)); state->WaitidResultType = WaitidResultType; #endif @@ -15683,10 +16032,9 @@ posixmodule_exec(PyObject *m) if (StatResultType == NULL) { return -1; } - Py_INCREF(StatResultType); - PyModule_AddObject(m, "stat_result", StatResultType); + PyModule_AddObject(m, "stat_result", Py_NewRef(StatResultType)); state->StatResultType = StatResultType; - structseq_new = ((PyTypeObject *)StatResultType)->tp_new; + state->statresult_new_orig = ((PyTypeObject *)StatResultType)->tp_new; ((PyTypeObject *)StatResultType)->tp_new = statresult_new; statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ @@ -15694,18 +16042,8 @@ posixmodule_exec(PyObject *m) if (StatVFSResultType == NULL) { return -1; } - Py_INCREF(StatVFSResultType); - PyModule_AddObject(m, "statvfs_result", StatVFSResultType); + PyModule_AddObject(m, "statvfs_result", Py_NewRef(StatVFSResultType)); state->StatVFSResultType = StatVFSResultType; -#ifdef NEED_TICKS_PER_SECOND -# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) - ticks_per_second = sysconf(_SC_CLK_TCK); -# elif defined(HZ) - ticks_per_second = HZ; -# else - ticks_per_second = 60; /* magic fallback value; may be bogus */ -# endif -#endif #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) sched_param_desc.name = MODNAME ".sched_param"; @@ -15713,8 +16051,7 @@ posixmodule_exec(PyObject *m) if (SchedParamType == NULL) { return -1; } - Py_INCREF(SchedParamType); - PyModule_AddObject(m, "sched_param", SchedParamType); + PyModule_AddObject(m, "sched_param", Py_NewRef(SchedParamType)); state->SchedParamType = SchedParamType; ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param; #endif @@ -15724,8 +16061,7 @@ posixmodule_exec(PyObject *m) if (TerminalSizeType == NULL) { return -1; } - Py_INCREF(TerminalSizeType); - PyModule_AddObject(m, "terminal_size", TerminalSizeType); + PyModule_AddObject(m, "terminal_size", Py_NewRef(TerminalSizeType)); state->TerminalSizeType = TerminalSizeType; /* initialize scandir types */ @@ -15739,8 +16075,7 @@ posixmodule_exec(PyObject *m) if (DirEntryType == NULL) { return -1; } - Py_INCREF(DirEntryType); - PyModule_AddObject(m, "DirEntry", DirEntryType); + PyModule_AddObject(m, "DirEntry", Py_NewRef(DirEntryType)); state->DirEntryType = DirEntryType; times_result_desc.name = MODNAME ".times_result"; @@ -15748,16 +16083,15 @@ posixmodule_exec(PyObject *m) if (TimesResultType == NULL) { return -1; } - Py_INCREF(TimesResultType); - PyModule_AddObject(m, "times_result", TimesResultType); + PyModule_AddObject(m, "times_result", Py_NewRef(TimesResultType)); state->TimesResultType = TimesResultType; PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc); if (UnameResultType == NULL) { return -1; } - Py_INCREF(UnameResultType); - PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType); + ; + PyModule_AddObject(m, "uname_result", Py_NewRef(UnameResultType)); state->UnameResultType = (PyObject *)UnameResultType; if ((state->billion = PyLong_FromLong(1000000000)) == NULL) diff --git a/Modules/posixmodule.h b/Modules/posixmodule.h index 711ac686934..5452ffbf17a 100644 --- a/Modules/posixmodule.h +++ b/Modules/posixmodule.h @@ -23,9 +23,7 @@ PyAPI_FUNC(int) _Py_Gid_Converter(PyObject *, gid_t *); # define HAVE_SIGSET_T #endif -#ifdef HAVE_SIGSET_T PyAPI_FUNC(int) _Py_Sigset_Converter(PyObject *, void *); -#endif /* HAVE_SIGSET_T */ #endif /* Py_LIMITED_API */ #ifdef __cplusplus diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c index 14d3f9dcb1c..a757380bd09 100644 --- a/Modules/pwdmodule.c +++ b/Modules/pwdmodule.c @@ -84,7 +84,6 @@ mkpwent(PyObject *module, struct passwd *p) if (v == NULL) return NULL; -#define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyLong_FromLong((long) val)) #define SETS(i,val) sets(v, i, val) SETS(setIndex++, p->pw_name); @@ -104,7 +103,6 @@ mkpwent(PyObject *module, struct passwd *p) SETS(setIndex++, p->pw_shell); #undef SETS -#undef SETI if (PyErr_Occurred()) { Py_XDECREF(v); diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index b3d9bdda7e7..63a3392d5ef 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -2,7 +2,6 @@ #include #include "structmember.h" // PyMemberDef -#include "frameobject.h" #include "expat.h" #include "pyexpat.h" @@ -50,6 +49,7 @@ enum HandlerTypes { typedef struct { PyTypeObject *xml_parse_type; PyObject *error; + PyObject *str_read; } pyexpat_state; static inline pyexpat_state* @@ -710,7 +710,7 @@ pyexpat.xmlparser.Parse cls: defining_class data: object - isfinal: bool(accept={int}) = False + isfinal: bool = False / Parse XML data. @@ -721,7 +721,7 @@ Parse XML data. static PyObject * pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyTypeObject *cls, PyObject *data, int isfinal) -/*[clinic end generated code: output=8faffe07fe1f862a input=fc97f833558ca715]*/ +/*[clinic end generated code: output=8faffe07fe1f862a input=d0eb2a69fab3b9f1]*/ { const char *s; Py_ssize_t slen; @@ -744,6 +744,8 @@ pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyTypeObject *cls, slen = view.len; } + static_assert(MAX_CHUNK_SIZE <= INT_MAX, + "MAX_CHUNK_SIZE is larger than INT_MAX"); while (slen > MAX_CHUNK_SIZE) { rc = XML_Parse(self->itself, s, MAX_CHUNK_SIZE, 0); if (!rc) @@ -751,7 +753,7 @@ pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyTypeObject *cls, s += MAX_CHUNK_SIZE; slen -= MAX_CHUNK_SIZE; } - Py_BUILD_ASSERT(MAX_CHUNK_SIZE <= INT_MAX); + assert(slen <= INT_MAX); rc = XML_Parse(self->itself, s, (int)slen, isfinal); @@ -773,7 +775,7 @@ readinst(char *buf, int buf_size, PyObject *meth) Py_ssize_t len; const char *ptr; - str = PyObject_CallFunction(meth, "n", buf_size); + str = PyObject_CallFunction(meth, "i", buf_size); if (str == NULL) goto error; @@ -822,11 +824,10 @@ pyexpat_xmlparser_ParseFile_impl(xmlparseobject *self, PyTypeObject *cls, { int rv = 1; PyObject *readmethod = NULL; - _Py_IDENTIFIER(read); pyexpat_state *state = PyType_GetModuleState(cls); - if (_PyObject_LookupAttrId(file, &PyId_read, &readmethod) < 0) { + if (_PyObject_LookupAttr(file, state->str_read, &readmethod) < 0) { return NULL; } if (readmethod == NULL) { @@ -958,8 +959,7 @@ pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context, encoding); new_parser->handlers = 0; - new_parser->intern = self->intern; - Py_XINCREF(new_parser->intern); + new_parser->intern = Py_XNewRef(self->intern); if (self->buffer != NULL) { new_parser->buffer = PyMem_Malloc(new_parser->buffer_size); @@ -990,8 +990,7 @@ pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, for (i = 0; handler_info[i].name != NULL; i++) { PyObject *handler = self->handlers[i]; if (handler != NULL) { - Py_INCREF(handler); - new_parser->handlers[i] = handler; + new_parser->handlers[i] = Py_NewRef(handler); handler_info[i].setter(new_parser->itself, handler_info[i].handler); } @@ -1086,7 +1085,7 @@ PyUnknownEncodingHandler(void *encodingHandlerData, PyObject* u; int i; const void *data; - unsigned int kind; + int kind; if (PyErr_Occurred()) return XML_STATUS_ERROR; @@ -1147,8 +1146,7 @@ newxmlparseobject(pyexpat_state *state, const char *encoding, self->in_callback = 0; self->ns_prefixes = 0; self->handlers = NULL; - self->intern = intern; - Py_XINCREF(self->intern); + self->intern = Py_XNewRef(intern); /* namespace_separator is either NULL or contains one char + \0 */ self->itself = XML_ParserCreate_MM(encoding, &ExpatMemoryHandler, @@ -1231,8 +1229,7 @@ xmlparse_handler_getter(xmlparseobject *self, struct HandlerInfo *hi) PyObject *result = self->handlers[handlernum]; if (result == NULL) result = Py_None; - Py_INCREF(result); - return result; + return Py_NewRef(result); } static int @@ -1364,9 +1361,7 @@ xmlparse_buffer_size_setter(xmlparseobject *self, PyObject *v, void *closure) /* check maximum */ if (new_buffer_size > INT_MAX) { - char errmsg[100]; - sprintf(errmsg, "buffer_size must not be greater than %i", INT_MAX); - PyErr_SetString(PyExc_ValueError, errmsg); + PyErr_Format(PyExc_ValueError, "buffer_size must not be greater than %i", INT_MAX); return -1; } @@ -1650,16 +1645,95 @@ add_submodule(PyObject *mod, const char *fullname) return submodule; } +struct ErrorInfo { + const char * name; /* Error constant name, e.g. "XML_ERROR_NO_MEMORY" */ + const char * description; /* Error description as returned by XML_ErrorString() */ +}; + +static +struct ErrorInfo error_info_of[] = { + {NULL, NULL}, /* XML_ERROR_NONE (value 0) is not exposed */ + + {"XML_ERROR_NO_MEMORY", "out of memory"}, + {"XML_ERROR_SYNTAX", "syntax error"}, + {"XML_ERROR_NO_ELEMENTS", "no element found"}, + {"XML_ERROR_INVALID_TOKEN", "not well-formed (invalid token)"}, + {"XML_ERROR_UNCLOSED_TOKEN", "unclosed token"}, + {"XML_ERROR_PARTIAL_CHAR", "partial character"}, + {"XML_ERROR_TAG_MISMATCH", "mismatched tag"}, + {"XML_ERROR_DUPLICATE_ATTRIBUTE", "duplicate attribute"}, + {"XML_ERROR_JUNK_AFTER_DOC_ELEMENT", "junk after document element"}, + {"XML_ERROR_PARAM_ENTITY_REF", "illegal parameter entity reference"}, + {"XML_ERROR_UNDEFINED_ENTITY", "undefined entity"}, + {"XML_ERROR_RECURSIVE_ENTITY_REF", "recursive entity reference"}, + {"XML_ERROR_ASYNC_ENTITY", "asynchronous entity"}, + {"XML_ERROR_BAD_CHAR_REF", "reference to invalid character number"}, + {"XML_ERROR_BINARY_ENTITY_REF", "reference to binary entity"}, + {"XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF", "reference to external entity in attribute"}, + {"XML_ERROR_MISPLACED_XML_PI", "XML or text declaration not at start of entity"}, + {"XML_ERROR_UNKNOWN_ENCODING", "unknown encoding"}, + {"XML_ERROR_INCORRECT_ENCODING", "encoding specified in XML declaration is incorrect"}, + {"XML_ERROR_UNCLOSED_CDATA_SECTION", "unclosed CDATA section"}, + {"XML_ERROR_EXTERNAL_ENTITY_HANDLING", "error in processing external entity reference"}, + {"XML_ERROR_NOT_STANDALONE", "document is not standalone"}, + {"XML_ERROR_UNEXPECTED_STATE", "unexpected parser state - please send a bug report"}, + {"XML_ERROR_ENTITY_DECLARED_IN_PE", "entity declared in parameter entity"}, + {"XML_ERROR_FEATURE_REQUIRES_XML_DTD", "requested feature requires XML_DTD support in Expat"}, + {"XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING", "cannot change setting once parsing has begun"}, + + /* Added in Expat 1.95.7. */ + {"XML_ERROR_UNBOUND_PREFIX", "unbound prefix"}, + + /* Added in Expat 1.95.8. */ + {"XML_ERROR_UNDECLARING_PREFIX", "must not undeclare prefix"}, + {"XML_ERROR_INCOMPLETE_PE", "incomplete markup in parameter entity"}, + {"XML_ERROR_XML_DECL", "XML declaration not well-formed"}, + {"XML_ERROR_TEXT_DECL", "text declaration not well-formed"}, + {"XML_ERROR_PUBLICID", "illegal character(s) in public id"}, + {"XML_ERROR_SUSPENDED", "parser suspended"}, + {"XML_ERROR_NOT_SUSPENDED", "parser not suspended"}, + {"XML_ERROR_ABORTED", "parsing aborted"}, + {"XML_ERROR_FINISHED", "parsing finished"}, + {"XML_ERROR_SUSPEND_PE", "cannot suspend in external parameter entity"}, + + /* Added in 2.0.0. */ + {"XML_ERROR_RESERVED_PREFIX_XML", "reserved prefix (xml) must not be undeclared or bound to another namespace name"}, + {"XML_ERROR_RESERVED_PREFIX_XMLNS", "reserved prefix (xmlns) must not be declared or undeclared"}, + {"XML_ERROR_RESERVED_NAMESPACE_URI", "prefix must not be bound to one of the reserved namespace names"}, + + /* Added in 2.2.1. */ + {"XML_ERROR_INVALID_ARGUMENT", "invalid argument"}, + + /* Added in 2.3.0. */ + {"XML_ERROR_NO_BUFFER", "a successful prior call to function XML_GetBuffer is required"}, + + /* Added in 2.4.0. */ + {"XML_ERROR_AMPLIFICATION_LIMIT_BREACH", "limit on input amplification factor (from DTD and entities) breached"} +}; + static int add_error(PyObject *errors_module, PyObject *codes_dict, - PyObject *rev_codes_dict, const char *name, int value) + PyObject *rev_codes_dict, size_t error_index) { - const char *error_string = XML_ErrorString(value); + const char * const name = error_info_of[error_index].name; + const int error_code = (int)error_index; + + /* NOTE: This keeps the source of truth regarding error + * messages with libexpat and (by definition) in bulletproof sync + * with the other uses of the XML_ErrorString function + * elsewhere within this file. pyexpat's copy of the messages + * only acts as a fallback in case of outdated runtime libexpat, + * where it returns NULL. */ + const char *error_string = XML_ErrorString(error_code); + if (error_string == NULL) { + error_string = error_info_of[error_index].description; + } + if (PyModule_AddStringConstant(errors_module, name, error_string) < 0) { return -1; } - PyObject *num = PyLong_FromLong(value); + PyObject *num = PyLong_FromLong(error_code); if (num == NULL) { return -1; } @@ -1699,53 +1773,16 @@ add_errors_module(PyObject *mod) goto error; } -#define ADD_CONST(name) do { \ - if (add_error(errors_module, codes_dict, rev_codes_dict, \ - #name, name) < 0) { \ - goto error; \ - } \ - } while(0) + size_t error_index = 0; + for (; error_index < sizeof(error_info_of) / sizeof(struct ErrorInfo); error_index++) { + if (error_info_of[error_index].name == NULL) { + continue; + } - ADD_CONST(XML_ERROR_NO_MEMORY); - ADD_CONST(XML_ERROR_SYNTAX); - ADD_CONST(XML_ERROR_NO_ELEMENTS); - ADD_CONST(XML_ERROR_INVALID_TOKEN); - ADD_CONST(XML_ERROR_UNCLOSED_TOKEN); - ADD_CONST(XML_ERROR_PARTIAL_CHAR); - ADD_CONST(XML_ERROR_TAG_MISMATCH); - ADD_CONST(XML_ERROR_DUPLICATE_ATTRIBUTE); - ADD_CONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT); - ADD_CONST(XML_ERROR_PARAM_ENTITY_REF); - ADD_CONST(XML_ERROR_UNDEFINED_ENTITY); - ADD_CONST(XML_ERROR_RECURSIVE_ENTITY_REF); - ADD_CONST(XML_ERROR_ASYNC_ENTITY); - ADD_CONST(XML_ERROR_BAD_CHAR_REF); - ADD_CONST(XML_ERROR_BINARY_ENTITY_REF); - ADD_CONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF); - ADD_CONST(XML_ERROR_MISPLACED_XML_PI); - ADD_CONST(XML_ERROR_UNKNOWN_ENCODING); - ADD_CONST(XML_ERROR_INCORRECT_ENCODING); - ADD_CONST(XML_ERROR_UNCLOSED_CDATA_SECTION); - ADD_CONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING); - ADD_CONST(XML_ERROR_NOT_STANDALONE); - ADD_CONST(XML_ERROR_UNEXPECTED_STATE); - ADD_CONST(XML_ERROR_ENTITY_DECLARED_IN_PE); - ADD_CONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD); - ADD_CONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING); - /* Added in Expat 1.95.7. */ - ADD_CONST(XML_ERROR_UNBOUND_PREFIX); - /* Added in Expat 1.95.8. */ - ADD_CONST(XML_ERROR_UNDECLARING_PREFIX); - ADD_CONST(XML_ERROR_INCOMPLETE_PE); - ADD_CONST(XML_ERROR_XML_DECL); - ADD_CONST(XML_ERROR_TEXT_DECL); - ADD_CONST(XML_ERROR_PUBLICID); - ADD_CONST(XML_ERROR_SUSPENDED); - ADD_CONST(XML_ERROR_NOT_SUSPENDED); - ADD_CONST(XML_ERROR_ABORTED); - ADD_CONST(XML_ERROR_FINISHED); - ADD_CONST(XML_ERROR_SUSPEND_PE); -#undef ADD_CONST + if (add_error(errors_module, codes_dict, rev_codes_dict, error_index) < 0) { + goto error; + } + } if (PyModule_AddStringConstant(errors_module, "__doc__", "Constants used to describe " @@ -1753,15 +1790,13 @@ add_errors_module(PyObject *mod) goto error; } - Py_INCREF(codes_dict); - if (PyModule_AddObject(errors_module, "codes", codes_dict) < 0) { + if (PyModule_AddObject(errors_module, "codes", Py_NewRef(codes_dict)) < 0) { Py_DECREF(codes_dict); goto error; } Py_CLEAR(codes_dict); - Py_INCREF(rev_codes_dict); - if (PyModule_AddObject(errors_module, "messages", rev_codes_dict) < 0) { + if (PyModule_AddObject(errors_module, "messages", Py_NewRef(rev_codes_dict)) < 0) { Py_DECREF(rev_codes_dict); goto error; } @@ -1843,17 +1878,14 @@ error: } #endif -static void -pyexpat_destructor(PyObject *op) -{ - void *p = PyCapsule_GetPointer(op, PyExpat_CAPSULE_NAME); - PyMem_Free(p); -} - static int pyexpat_exec(PyObject *mod) { pyexpat_state *state = pyexpat_get_state(mod); + state->str_read = PyUnicode_InternFromString("read"); + if (state->str_read == NULL) { + return -1; + } state->xml_parse_type = (PyTypeObject *)PyType_FromModuleAndSpec( mod, &_xml_parse_type_spec, NULL); @@ -1933,46 +1965,40 @@ pyexpat_exec(PyObject *mod) MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS); #undef MYCONST - struct PyExpat_CAPI *capi = PyMem_Calloc(1, sizeof(struct PyExpat_CAPI)); - if (capi == NULL) { - PyErr_NoMemory(); - return -1; - } + static struct PyExpat_CAPI capi; /* initialize pyexpat dispatch table */ - capi->size = sizeof(*capi); - capi->magic = PyExpat_CAPI_MAGIC; - capi->MAJOR_VERSION = XML_MAJOR_VERSION; - capi->MINOR_VERSION = XML_MINOR_VERSION; - capi->MICRO_VERSION = XML_MICRO_VERSION; - capi->ErrorString = XML_ErrorString; - capi->GetErrorCode = XML_GetErrorCode; - capi->GetErrorColumnNumber = XML_GetErrorColumnNumber; - capi->GetErrorLineNumber = XML_GetErrorLineNumber; - capi->Parse = XML_Parse; - capi->ParserCreate_MM = XML_ParserCreate_MM; - capi->ParserFree = XML_ParserFree; - capi->SetCharacterDataHandler = XML_SetCharacterDataHandler; - capi->SetCommentHandler = XML_SetCommentHandler; - capi->SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand; - capi->SetElementHandler = XML_SetElementHandler; - capi->SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler; - capi->SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler; - capi->SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler; - capi->SetUserData = XML_SetUserData; - capi->SetStartDoctypeDeclHandler = XML_SetStartDoctypeDeclHandler; - capi->SetEncoding = XML_SetEncoding; - capi->DefaultUnknownEncodingHandler = PyUnknownEncodingHandler; + capi.size = sizeof(capi); + capi.magic = PyExpat_CAPI_MAGIC; + capi.MAJOR_VERSION = XML_MAJOR_VERSION; + capi.MINOR_VERSION = XML_MINOR_VERSION; + capi.MICRO_VERSION = XML_MICRO_VERSION; + capi.ErrorString = XML_ErrorString; + capi.GetErrorCode = XML_GetErrorCode; + capi.GetErrorColumnNumber = XML_GetErrorColumnNumber; + capi.GetErrorLineNumber = XML_GetErrorLineNumber; + capi.Parse = XML_Parse; + capi.ParserCreate_MM = XML_ParserCreate_MM; + capi.ParserFree = XML_ParserFree; + capi.SetCharacterDataHandler = XML_SetCharacterDataHandler; + capi.SetCommentHandler = XML_SetCommentHandler; + capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand; + capi.SetElementHandler = XML_SetElementHandler; + capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler; + capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler; + capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler; + capi.SetUserData = XML_SetUserData; + capi.SetStartDoctypeDeclHandler = XML_SetStartDoctypeDeclHandler; + capi.SetEncoding = XML_SetEncoding; + capi.DefaultUnknownEncodingHandler = PyUnknownEncodingHandler; #if XML_COMBINED_VERSION >= 20100 - capi->SetHashSalt = XML_SetHashSalt; + capi.SetHashSalt = XML_SetHashSalt; #else - capi->SetHashSalt = NULL; + capi.SetHashSalt = NULL; #endif /* export using capsule */ - PyObject *capi_object = PyCapsule_New(capi, PyExpat_CAPSULE_NAME, - pyexpat_destructor); + PyObject *capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL); if (capi_object == NULL) { - PyMem_Free(capi); return -1; } @@ -1990,6 +2016,7 @@ pyexpat_traverse(PyObject *module, visitproc visit, void *arg) pyexpat_state *state = pyexpat_get_state(module); Py_VISIT(state->xml_parse_type); Py_VISIT(state->error); + Py_VISIT(state->str_read); return 0; } @@ -1999,6 +2026,7 @@ pyexpat_clear(PyObject *module) pyexpat_state *state = pyexpat_get_state(module); Py_CLEAR(state->xml_parse_type); Py_CLEAR(state->error); + Py_CLEAR(state->str_read); return 0; } diff --git a/Modules/readline.c b/Modules/readline.c index 1b616fc4f3b..fdb6356e1c8 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -402,8 +402,7 @@ set_hook(const char *funcname, PyObject **hook_var, PyObject *function) Py_CLEAR(*hook_var); } else if (PyCallable_Check(function)) { - Py_INCREF(function); - Py_XSETREF(*hook_var, function); + Py_XSETREF(*hook_var, Py_NewRef(function)); } else { PyErr_Format(PyExc_TypeError, @@ -524,8 +523,7 @@ static PyObject * readline_get_begidx_impl(PyObject *module) /*[clinic end generated code: output=362616ee8ed1b2b1 input=e083b81c8eb4bac3]*/ { - Py_INCREF(readlinestate_global->begidx); - return readlinestate_global->begidx; + return Py_NewRef(readlinestate_global->begidx); } /* Get the ending index for the scope of the tab-completion */ @@ -540,8 +538,7 @@ static PyObject * readline_get_endidx_impl(PyObject *module) /*[clinic end generated code: output=7f763350b12d7517 input=d4c7e34a625fd770]*/ { - Py_INCREF(readlinestate_global->endidx); - return readlinestate_global->endidx; + return Py_NewRef(readlinestate_global->endidx); } /* Set the tab-completion word-delimiters that readline uses */ @@ -784,8 +781,7 @@ readline_get_completer_impl(PyObject *module) if (readlinestate_global->completer == NULL) { Py_RETURN_NONE; } - Py_INCREF(readlinestate_global->completer); - return readlinestate_global->completer; + return Py_NewRef(readlinestate_global->completer); } /* Private function to get current length of history. XXX It may be @@ -1258,9 +1254,9 @@ setup_readline(readlinestate *mod_state) rl_attempted_completion_function = flex_complete; /* Set Python word break characters */ completer_word_break_characters = - rl_completer_word_break_characters = strdup(" \t\n`~!@#$%^&*()-=+[{]}\\|;:'\",<>/?"); /* All nonalphanums except '.' */ + rl_completer_word_break_characters = completer_word_break_characters; mod_state->begidx = PyLong_FromLong(0L); mod_state->endidx = PyLong_FromLong(0L); diff --git a/Modules/resource.c b/Modules/resource.c index 0d69c2983b4..a97fb870062 100644 --- a/Modules/resource.c +++ b/Modules/resource.c @@ -24,8 +24,16 @@ module resource class pid_t_converter(CConverter): type = 'pid_t' format_unit = '" _Py_PARSE_PID "' + + def parse_arg(self, argname, displayname): + return """ + {paramname} = PyLong_AsPid({argname}); + if ({paramname} == -1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.parser_name) [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=0c1d19f640d57e48]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=5af1c116d56cbb5a]*/ #include "clinic/resource.c.h" @@ -78,6 +86,7 @@ get_resource_state(PyObject *module) static struct PyModuleDef resourcemodule; +#ifdef HAVE_GETRUSAGE /*[clinic input] resource.getrusage @@ -134,6 +143,7 @@ resource_getrusage_impl(PyObject *module, int who) return result; } +#endif static int py2rlimit(PyObject *limits, struct rlimit *rl_out) @@ -266,17 +276,15 @@ resource.prlimit pid: pid_t resource: int - [ - limits: object - ] + limits: object = None / [clinic start generated code]*/ static PyObject * resource_prlimit_impl(PyObject *module, pid_t pid, int resource, - int group_right_1, PyObject *limits) -/*[clinic end generated code: output=ee976b393187a7a3 input=b77743bdccc83564]*/ + PyObject *limits) +/*[clinic end generated code: output=6ebc49ff8c3a816e input=54bb69c9585e33bf]*/ { struct rlimit old_limit, new_limit; int retval; @@ -292,7 +300,7 @@ resource_prlimit_impl(PyObject *module, pid_t pid, int resource, return NULL; } - if (group_right_1) { + if (limits != Py_None) { if (py2rlimit(limits, &new_limit) < 0) { return NULL; } diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index ff1c028d0d6..df4043de08d 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -4,11 +4,16 @@ have any value except INVALID_SOCKET. */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #if defined(HAVE_POLL_H) && !defined(_GNU_SOURCE) -#define _GNU_SOURCE +# define _GNU_SOURCE #endif #include "Python.h" +#include "pycore_fileutils.h" // _Py_set_inheritable() #include "structmember.h" // PyMemberDef #ifdef HAVE_SYS_DEVPOLL_H @@ -58,6 +63,11 @@ extern void bzero(void *, int); # define SOCKET int #endif +// WASI SDK 16 does not have POLLPRIO, define as no-op +#if defined(__wasi__) && !defined(POLLPRI) +# define POLLPRI 0 +#endif + typedef struct { PyObject *close; PyTypeObject *poll_Type; @@ -325,7 +335,12 @@ select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist, do { Py_BEGIN_ALLOW_THREADS errno = 0; - n = select(max, &ifdset, &ofdset, &efdset, tvp); + n = select( + max, + imax ? &ifdset : NULL, + omax ? &ofdset : NULL, + emax ? &efdset : NULL, + tvp); Py_END_ALLOW_THREADS if (errno != EINTR) @@ -565,6 +580,8 @@ select_poll_unregister_impl(pollObject *self, int fd) select.poll.poll timeout as timeout_obj: object = None + The maximum time to wait in milliseconds, or else None (or a negative + value) to wait indefinitely. / Polls the set of registered file descriptors. @@ -575,7 +592,7 @@ report, as a list of (fd, event) 2-tuples. static PyObject * select_poll_poll_impl(pollObject *self, PyObject *timeout_obj) -/*[clinic end generated code: output=876e837d193ed7e4 input=7a446ed45189e894]*/ +/*[clinic end generated code: output=876e837d193ed7e4 input=c2f6953ec45e5622]*/ { PyObject *result_list = NULL; int poll_result, i, j; @@ -889,6 +906,8 @@ select_devpoll_unregister_impl(devpollObject *self, int fd) /*[clinic input] select.devpoll.poll timeout as timeout_obj: object = None + The maximum time to wait in milliseconds, or else None (or a negative + value) to wait indefinitely. / Polls the set of registered file descriptors. @@ -899,7 +918,7 @@ report, as a list of (fd, event) 2-tuples. static PyObject * select_devpoll_poll_impl(devpollObject *self, PyObject *timeout_obj) -/*[clinic end generated code: output=2654e5457cca0b3c input=fd0db698d84f0333]*/ +/*[clinic end generated code: output=2654e5457cca0b3c input=3c3f0a355ec2bedb]*/ { struct dvpoll dvp; PyObject *result_list = NULL; @@ -1633,8 +1652,7 @@ select_epoll___enter___impl(pyEpoll_Object *self) if (self->epfd < 0) return pyepoll_err_closed(); - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } /*[clinic input] diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 927880376c3..44a5ecf63e9 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -7,12 +7,13 @@ #include "pycore_atomic.h" // _Py_atomic_int #include "pycore_call.h" // _PyObject_Call() #include "pycore_ceval.h" // _PyEval_SignalReceived() +#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS #include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH -#include "pycore_frame.h" // InterpreterFrame +#include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_pyerrors.h" // _PyErr_SetString() -#include "pycore_pylifecycle.h" // NSIG #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_signal.h" #ifndef MS_WINDOWS # include "posixmodule.h" @@ -22,12 +23,13 @@ #endif #ifdef MS_WINDOWS -# include # ifdef HAVE_PROCESS_H # include # endif #endif +#include "pycore_signal.h" // Py_NSIG + #ifdef HAVE_SIGNAL_H # include #endif @@ -60,6 +62,8 @@ module signal [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0301a3bde5fe9d3]*/ +#ifdef HAVE_SETSIG_T + /*[python input] class sigset_t_converter(CConverter): @@ -68,6 +72,7 @@ class sigset_t_converter(CConverter): [python start generated code]*/ /*[python end generated code: output=da39a3ee5e6b4b0d input=b5689d14466b6823]*/ +#endif /* NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS @@ -96,47 +101,13 @@ class sigset_t_converter(CConverter): may not be the thread that received the signal. */ -static volatile struct { - _Py_atomic_int tripped; - /* func is atomic to ensure that PyErr_SetInterrupt is async-signal-safe - * (even though it would probably be otherwise, anyway). - */ - _Py_atomic_address func; -} Handlers[NSIG]; - -#ifdef MS_WINDOWS -#define INVALID_FD ((SOCKET_T)-1) - -static volatile struct { - SOCKET_T fd; - int warn_on_full_buffer; - int use_send; -} wakeup = {.fd = INVALID_FD, .warn_on_full_buffer = 1, .use_send = 0}; -#else -#define INVALID_FD (-1) -static volatile struct { -#ifdef __VXWORKS__ - int fd; -#else - sig_atomic_t fd; -#endif - int warn_on_full_buffer; -} wakeup = {.fd = INVALID_FD, .warn_on_full_buffer = 1}; -#endif - -/* Speed up sigcheck() when none tripped */ -static _Py_atomic_int is_tripped; - -typedef struct { - PyObject *default_handler; - PyObject *ignore_handler; -#ifdef MS_WINDOWS - HANDLE sigint_event; -#endif -} signal_state_t; +#define Handlers _PyRuntime.signals.handlers +#define wakeup _PyRuntime.signals.wakeup +#define is_tripped _PyRuntime.signals.is_tripped // State shared by all Python interpreters -static signal_state_t signal_global_state = {0}; +typedef struct _signals_runtime_state signal_state_t; +#define signal_global_state _PyRuntime.signals #if defined(HAVE_GETITIMER) || defined(HAVE_SETITIMER) # define PYHAVE_ITIMER_ERROR @@ -148,6 +119,7 @@ typedef struct { #ifdef PYHAVE_ITIMER_ERROR PyObject *itimer_error; #endif + PyTypeObject *siginfo_type; } _signal_module_state; @@ -173,8 +145,19 @@ get_signal_state(PyObject *module) } -#ifdef HAVE_GETITIMER -/* auxiliary functions for setitimer */ +static inline int +compare_handler(PyObject *func, PyObject *dfl_ign_handler) +{ + assert(PyLong_CheckExact(dfl_ign_handler)); + if (!PyLong_CheckExact(func)) { + return 0; + } + // Assume that comparison of two PyLong objects will never fail. + return PyObject_RichCompareBool(func, dfl_ign_handler, Py_EQ) == 1; +} + +#ifdef HAVE_SETITIMER +/* auxiliary function for setitimer */ static int timeval_from_double(PyObject *obj, struct timeval *tv) { @@ -190,7 +173,10 @@ timeval_from_double(PyObject *obj, struct timeval *tv) } return _PyTime_AsTimeval(t, tv, _PyTime_ROUND_CEILING); } +#endif +#if defined(HAVE_SETITIMER) || defined(HAVE_GETITIMER) +/* auxiliary functions for get/setitimer */ Py_LOCAL_INLINE(double) double_from_timeval(struct timeval *tv) { @@ -253,9 +239,8 @@ report_wakeup_write_error(void *data) errno = (int) (intptr_t) data; PyErr_Fetch(&exc, &val, &tb); PyErr_SetFromErrno(PyExc_OSError); - PySys_WriteStderr("Exception ignored when trying to write to the " - "signal wakeup fd:\n"); - PyErr_WriteUnraisable(NULL); + _PyErr_WriteUnraisableMsg("when trying to write to the signal wakeup fd", + NULL); PyErr_Restore(exc, val, tb); errno = save_errno; return 0; @@ -265,15 +250,15 @@ report_wakeup_write_error(void *data) static int report_wakeup_send_error(void* data) { + int send_errno = (int) (intptr_t) data; + PyObject *exc, *val, *tb; PyErr_Fetch(&exc, &val, &tb); /* PyErr_SetExcFromWindowsErr() invokes FormatMessage() which recognizes the error codes used by both GetLastError() and WSAGetLastError */ - PyErr_SetExcFromWindowsErr(PyExc_OSError, (int) (intptr_t) data); - PySys_WriteStderr("Exception ignored when trying to send to the " - "signal wakeup fd:\n"); - PyErr_WriteUnraisable(NULL); + PyErr_SetExcFromWindowsErr(PyExc_OSError, send_errno); + _PyErr_WriteUnraisableMsg("when trying to send to the signal wakeup fd", NULL); PyErr_Restore(exc, val, tb); return 0; } @@ -289,7 +274,7 @@ trip_signal(int sig_num) _Py_atomic_store(&is_tripped, 1); /* Signals are always handled by the main interpreter */ - PyInterpreterState *interp = _PyRuntime.interpreters.main; + PyInterpreterState *interp = _PyInterpreterState_Main(); /* Notify ceval.c */ _PyEval_SignalReceived(interp); @@ -313,13 +298,7 @@ trip_signal(int sig_num) See bpo-30038 for more details. */ - int fd; -#ifdef MS_WINDOWS - fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int); -#else - fd = wakeup.fd; -#endif - + int fd = wakeup.fd; if (fd != INVALID_FD) { unsigned char byte = (unsigned char)sig_num; #ifdef MS_WINDOWS @@ -389,7 +368,7 @@ signal_handler(int sig_num) #ifdef MS_WINDOWS if (sig_num == SIGINT) { signal_state_t *state = &signal_global_state; - SetEvent(state->sigint_event); + SetEvent((HANDLE)state->sigint_event); } #endif } @@ -465,6 +444,13 @@ signal_raise_signal_impl(PyObject *module, int signalnum) if (err) { return PyErr_SetFromErrno(PyExc_OSError); } + + // If the current thread can handle signals, handle immediately + // the raised signal. + if (PyErr_CheckSignals()) { + return NULL; + } + Py_RETURN_NONE; } @@ -519,26 +505,23 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler) "of the main interpreter"); return NULL; } - if (signalnum < 1 || signalnum >= NSIG) { + if (signalnum < 1 || signalnum >= Py_NSIG) { _PyErr_SetString(tstate, PyExc_ValueError, "signal number out of range"); return NULL; } - if (handler == modstate->ignore_handler) { + if (PyCallable_Check(handler)) { + func = signal_handler; + } else if (compare_handler(handler, modstate->ignore_handler)) { func = SIG_IGN; - } - else if (handler == modstate->default_handler) { + } else if (compare_handler(handler, modstate->default_handler)) { func = SIG_DFL; - } - else if (!PyCallable_Check(handler)) { + } else { _PyErr_SetString(tstate, PyExc_TypeError, "signal handler must be signal.SIG_IGN, " "signal.SIG_DFL, or a callable object"); return NULL; } - else { - func = signal_handler; - } /* Check for pending signals before changing signal handler */ if (_PyErr_CheckSignalsTstate(tstate)) { @@ -581,7 +564,7 @@ signal_getsignal_impl(PyObject *module, int signalnum) /*[clinic end generated code: output=35b3e0e796fd555e input=ac23a00f19dfa509]*/ { PyObject *old_handler; - if (signalnum < 1 || signalnum >= NSIG) { + if (signalnum < 1 || signalnum >= Py_NSIG) { PyErr_SetString(PyExc_ValueError, "signal number out of range"); return NULL; @@ -604,17 +587,18 @@ signal.strsignal Return the system description of the given signal. -The return values can be such as "Interrupt", "Segmentation fault", etc. -Returns None if the signal is not recognized. +Returns the description of signal *signalnum*, such as "Interrupt" +for :const:`SIGINT`. Returns :const:`None` if *signalnum* has no +description. Raises :exc:`ValueError` if *signalnum* is invalid. [clinic start generated code]*/ static PyObject * signal_strsignal_impl(PyObject *module, int signalnum) -/*[clinic end generated code: output=44e12e1e3b666261 input=b77914b03f856c74]*/ +/*[clinic end generated code: output=44e12e1e3b666261 input=238b335847778bc0]*/ { const char *res; - if (signalnum < 1 || signalnum >= NSIG) { + if (signalnum < 1 || signalnum >= Py_NSIG) { PyErr_SetString(PyExc_ValueError, "signal number out of range"); return NULL; @@ -692,7 +676,7 @@ static PyObject * signal_siginterrupt_impl(PyObject *module, int signalnum, int flag) /*[clinic end generated code: output=063816243d85dd19 input=4160acacca3e2099]*/ { - if (signalnum < 1 || signalnum >= NSIG) { + if (signalnum < 1 || signalnum >= Py_NSIG) { PyErr_SetString(PyExc_ValueError, "signal number out of range"); return NULL; @@ -762,7 +746,7 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds) is_socket = 0; if (sockfd != INVALID_FD) { /* Import the _socket module to call WSAStartup() */ - mod = PyImport_ImportModuleNoBlock("_socket"); + mod = PyImport_ImportModule("_socket"); if (mod == NULL) return NULL; Py_DECREF(mod); @@ -799,7 +783,7 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds) } old_sockfd = wakeup.fd; - wakeup.fd = sockfd; + wakeup.fd = Py_SAFE_DOWNCAST(sockfd, SOCKET_T, int); wakeup.warn_on_full_buffer = warn_on_full_buffer; wakeup.use_send = is_socket; @@ -850,11 +834,7 @@ PySignal_SetWakeupFd(int fd) fd = -1; } -#ifdef MS_WINDOWS - int old_fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int); -#else int old_fd = wakeup.fd; -#endif wakeup.fd = fd; wakeup.warn_on_full_buffer = 1; return old_fd; @@ -932,6 +912,7 @@ signal_getitimer_impl(PyObject *module, int which) #endif // HAVE_GETITIMER +#ifdef HAVE_SIGSET_T #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING) static PyObject* sigset_to_set(sigset_t mask) @@ -943,7 +924,7 @@ sigset_to_set(sigset_t mask) if (result == NULL) return NULL; - for (sig = 1; sig < NSIG; sig++) { + for (sig = 1; sig < Py_NSIG; sig++) { if (sigismember(&mask, sig) != 1) continue; @@ -1063,9 +1044,9 @@ signal_sigwait_impl(PyObject *module, sigset_t sigset) } #endif /* #ifdef HAVE_SIGWAIT */ +#endif /* #ifdef HAVE_SIGSET_T */ - -#if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS) +#if (defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS) /*[clinic input] signal.valid_signals @@ -1103,7 +1084,8 @@ signal_valid_signals_impl(PyObject *module) #endif } -#endif /* #if defined(HAVE_SIGFILLSET) || defined(MS_WINDOWS) */ +#endif /* #if (defined(HAVE_SIGFILLSET) && defined(HAVE_SIGSET_T)) || defined(MS_WINDOWS) */ + #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) @@ -1131,12 +1113,11 @@ static PyStructSequence_Desc struct_siginfo_desc = { 7 /* n_in_sequence */ }; -static PyTypeObject SiginfoType; static PyObject * -fill_siginfo(siginfo_t *si) +fill_siginfo(_signal_module_state *state, siginfo_t *si) { - PyObject *result = PyStructSequence_New(&SiginfoType); + PyObject *result = PyStructSequence_New(state->siginfo_type); if (!result) return NULL; @@ -1168,6 +1149,7 @@ fill_siginfo(siginfo_t *si) } #endif +#ifdef HAVE_SIGSET_T #ifdef HAVE_SIGWAITINFO /*[clinic input] @@ -1198,7 +1180,8 @@ signal_sigwaitinfo_impl(PyObject *module, sigset_t sigset) if (err == -1) return (!async_err) ? PyErr_SetFromErrno(PyExc_OSError) : NULL; - return fill_siginfo(&si); + _signal_module_state *state = get_signal_state(module); + return fill_siginfo(state, &si); } #endif /* #ifdef HAVE_SIGWAITINFO */ @@ -1266,10 +1249,12 @@ signal_sigtimedwait_impl(PyObject *module, sigset_t sigset, } } while (1); - return fill_siginfo(&si); + _signal_module_state *state = get_signal_state(module); + return fill_siginfo(state, &si); } #endif /* #ifdef HAVE_SIGTIMEDWAIT */ +#endif /* #ifdef HAVE_SIGSET_T */ #if defined(HAVE_PTHREAD_KILL) @@ -1356,7 +1341,7 @@ static PyMethodDef signal_methods[] = { SIGNAL_RAISE_SIGNAL_METHODDEF SIGNAL_STRSIGNAL_METHODDEF SIGNAL_GETSIGNAL_METHODDEF - {"set_wakeup_fd", (PyCFunction)(void(*)(void))signal_set_wakeup_fd, METH_VARARGS | METH_KEYWORDS, set_wakeup_fd_doc}, + {"set_wakeup_fd", _PyCFunction_CAST(signal_set_wakeup_fd), METH_VARARGS | METH_KEYWORDS, set_wakeup_fd_doc}, SIGNAL_SIGINTERRUPT_METHODDEF SIGNAL_PAUSE_METHODDEF SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF @@ -1414,13 +1399,15 @@ the first is the signal number, the second is the interrupted stack frame."); static int signal_add_constants(PyObject *module) { + if (PyModule_AddIntConstant(module, "NSIG", Py_NSIG) < 0) { + return -1; + } + #define ADD_INT_MACRO(macro) \ if (PyModule_AddIntConstant(module, #macro, macro) < 0) { \ return -1; \ } - ADD_INT_MACRO(NSIG); - // SIG_xxx pthread_sigmask() constants #ifdef SIG_BLOCK ADD_INT_MACRO(SIG_BLOCK); @@ -1547,6 +1534,9 @@ signal_add_constants(PyObject *module) #ifdef SIGINFO ADD_INT_MACRO(SIGINFO); #endif +#ifdef SIGSTKFLT + ADD_INT_MACRO(SIGSTKFLT); +#endif // ITIMER_xxx constants #ifdef ITIMER_REAL @@ -1577,7 +1567,7 @@ static int signal_get_set_handlers(signal_state_t *state, PyObject *mod_dict) { // Get signal handlers - for (int signum = 1; signum < NSIG; signum++) { + for (int signum = 1; signum < Py_NSIG; signum++) { void (*c_handler)(int) = PyOS_getsig(signum); PyObject *func; if (c_handler == SIG_DFL) { @@ -1621,6 +1611,8 @@ signal_module_exec(PyObject *m) signal_state_t *state = &signal_global_state; _signal_module_state *modstate = get_signal_state(m); + // XXX For proper isolation, these values must be guaranteed + // to be effectively const (e.g. immortal). modstate->default_handler = state->default_handler; // borrowed ref modstate->ignore_handler = state->ignore_handler; // borrowed ref @@ -1649,8 +1641,15 @@ signal_module_exec(PyObject *m) return -1; } #endif + #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) - if (PyModule_AddType(m, &SiginfoType) < 0) { + modstate->siginfo_type = PyStructSequence_NewType(&struct_siginfo_desc); + if (modstate->siginfo_type == NULL) { + return -1; + } +#endif +#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) + if (PyModule_AddType(m, modstate->siginfo_type) < 0) { return -1; } #endif @@ -1671,16 +1670,18 @@ signal_module_exec(PyObject *m) static int _signal_module_traverse(PyObject *module, visitproc visit, void *arg) { - _signal_module_state *modstate = get_signal_state(module); - Py_VISIT(modstate->itimer_error); + _signal_module_state *state = get_signal_state(module); + Py_VISIT(state->itimer_error); + Py_VISIT(state->siginfo_type); return 0; } static int _signal_module_clear(PyObject *module) { - _signal_module_state *modstate = get_signal_state(module); - Py_CLEAR(modstate->itimer_error); + _signal_module_state *state = get_signal_state(module); + Py_CLEAR(state->itimer_error); + Py_CLEAR(state->siginfo_type); return 0; } @@ -1725,14 +1726,14 @@ _PySignal_Fini(void) signal_state_t *state = &signal_global_state; // Restore default signals and clear handlers - for (int signum = 1; signum < NSIG; signum++) { + for (int signum = 1; signum < Py_NSIG; signum++) { PyObject *func = get_handler(signum); _Py_atomic_store_relaxed(&Handlers[signum].tripped, 0); set_handler(signum, NULL); if (func != NULL && func != Py_None - && func != state->default_handler - && func != state->ignore_handler) + && !compare_handler(func, state->default_handler) + && !compare_handler(func, state->ignore_handler)) { PyOS_setsig(signum, SIG_DFL); } @@ -1741,7 +1742,7 @@ _PySignal_Fini(void) #ifdef MS_WINDOWS if (state->sigint_event != NULL) { - CloseHandle(state->sigint_event); + CloseHandle((HANDLE)state->sigint_event); state->sigint_event = NULL; } #endif @@ -1756,6 +1757,19 @@ int PyErr_CheckSignals(void) { PyThreadState *tstate = _PyThreadState_GET(); + + /* Opportunistically check if the GC is scheduled to run and run it + if we have a request. This is done here because native code needs + to call this API if is going to run for some time without executing + Python code to ensure signals are handled. Checking for the GC here + allows long running native code to clean cycles created using the C-API + even if it doesn't run the evaluation loop */ + struct _ceval_state *interp_ceval_state = &tstate->interp->ceval; + if (_Py_atomic_load_relaxed(&interp_ceval_state->gc_scheduled)) { + _Py_atomic_store_relaxed(&interp_ceval_state->gc_scheduled, 0); + _Py_RunGC(tstate); + } + if (!_Py_ThreadCanHandleSignals(tstate->interp)) { return 0; } @@ -1768,6 +1782,7 @@ PyErr_CheckSignals(void) int _PyErr_CheckSignalsTstate(PyThreadState *tstate) { + _Py_CHECK_EMSCRIPTEN_SIGNALS(); if (!_Py_atomic_load(&is_tripped)) { return 0; } @@ -1788,9 +1803,9 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate) */ _Py_atomic_store(&is_tripped, 0); - InterpreterFrame *frame = tstate->cframe->current_frame; + _PyInterpreterFrame *frame = _PyThreadState_GetFrame(tstate); signal_state_t *state = &signal_global_state; - for (int i = 1; i < NSIG; i++) { + for (int i = 1; i < Py_NSIG; i++) { if (!_Py_atomic_load_relaxed(&Handlers[i].tripped)) { continue; } @@ -1803,8 +1818,9 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate) * (see bpo-43406). */ PyObject *func = get_handler(i); - if (func == NULL || func == Py_None || func == state->ignore_handler || - func == state->default_handler) { + if (func == NULL || func == Py_None || + compare_handler(func, state->ignore_handler) || + compare_handler(func, state->default_handler)) { /* No Python signal handler due to aforementioned race condition. * We can't call raise() as it would break the assumption * that PyErr_SetInterrupt() only *simulates* an incoming @@ -1866,13 +1882,14 @@ _PyErr_CheckSignals(void) int PyErr_SetInterruptEx(int signum) { - if (signum < 1 || signum >= NSIG) { + if (signum < 1 || signum >= Py_NSIG) { return -1; } signal_state_t *state = &signal_global_state; PyObject *func = get_handler(signum); - if (func != state->ignore_handler && func != state->default_handler) { + if (!compare_handler(func, state->ignore_handler) + && !compare_handler(func, state->default_handler)) { trip_signal(signum); } return 0; @@ -1948,22 +1965,14 @@ _PySignal_Init(int install_signal_handlers) #ifdef MS_WINDOWS /* Create manual-reset event, initially unset */ - state->sigint_event = CreateEvent(NULL, TRUE, FALSE, FALSE); + state->sigint_event = (void *)CreateEvent(NULL, TRUE, FALSE, FALSE); if (state->sigint_event == NULL) { PyErr_SetFromWindowsErr(0); return -1; } #endif -#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) - if (SiginfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&SiginfoType, &struct_siginfo_desc) < 0) { - return -1; - } - } -#endif - - for (int signum = 1; signum < NSIG; signum++) { + for (int signum = 1; signum < Py_NSIG; signum++) { _Py_atomic_store_relaxed(&Handlers[signum].tripped, 0); } @@ -2013,7 +2022,7 @@ _clear_pending_signals(void) } _Py_atomic_store(&is_tripped, 0); - for (int i = 1; i < NSIG; ++i) { + for (int i = 1; i < Py_NSIG; ++i) { _Py_atomic_store_relaxed(&Handlers[i].tripped, 0); } } diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index ed1043c0c43..0a9e46512b1 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -85,6 +85,10 @@ Local naming conventions: */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #ifdef __APPLE__ // Issue #35569: Expose RFC 3542 socket options. #define __APPLE_USE_RFC_3542 1 @@ -103,6 +107,7 @@ Local naming conventions: #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_fileutils.h" // _Py_set_inheritable() #include "structmember.h" // PyMemberDef #ifdef _Py_MEMORY_SANITIZER @@ -222,7 +227,7 @@ shutdown(how) -- shut down traffic in one or both directions\n\ #define HAVE_INET_PTON #include -#endif +#endif // __sgi /* Solaris fails to define this variable at all. */ #if (defined(__sun) && defined(__SVR4)) && !defined(INET_ADDRSTRLEN) @@ -242,6 +247,10 @@ shutdown(how) -- shut down traffic in one or both directions\n\ #include #endif +#ifdef HAVE_NET_ETHERNET_H +#include +#endif + /* Generic socket object definitions and includes */ #define PySocket_BUILDING_SOCKET #include "socketmodule.h" @@ -251,7 +260,9 @@ shutdown(how) -- shut down traffic in one or both directions\n\ #ifndef MS_WINDOWS /* Non-MS WINDOWS includes */ -# include +#ifdef HAVE_NETDB_H +# include +#endif # include /* Headers needed for inet_ntoa() and inet_addr() */ @@ -266,6 +277,9 @@ shutdown(how) -- shut down traffic in one or both directions\n\ # include # endif +/* Helpers needed for AF_HYPERV */ +# include + /* Macros based on the IPPROTO enum, see: https://bugs.python.org/issue29515 */ #ifdef MS_WINDOWS #define IPPROTO_ICMP IPPROTO_ICMP @@ -323,6 +337,12 @@ static FlagRuntimeInfo win_runtime_flags[] = { {14393, "TCP_FASTOPEN"} }; +/*[clinic input] +module _socket +class _socket.socket "PySocketSockObject *" "&sock_type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7a8313d9b7f51988]*/ + static int remove_unusable_flags(PyObject *m) { @@ -425,10 +445,11 @@ remove_unusable_flags(PyObject *m) #define freeaddrinfo fake_freeaddrinfo #include "getaddrinfo.c" #endif + #if !defined(HAVE_GETNAMEINFO) #define getnameinfo fake_getnameinfo #include "getnameinfo.c" -#endif +#endif // HAVE_GETNAMEINFO #ifdef MS_WINDOWS #define SOCKETCLOSE closesocket @@ -506,6 +527,8 @@ remove_unusable_flags(PyObject *m) #define INADDR_NONE (-1) #endif +#include "clinic/socketmodule.c.h" + /* XXX There's a problem here: *static* functions are not supposed to have a Py prefix (or use CapitalizedWords). Later... */ @@ -607,6 +630,7 @@ set_error(void) } +#if defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYNAME) || defined (HAVE_GETHOSTBYADDR) static PyObject * set_herror(int h_error) { @@ -624,8 +648,10 @@ set_herror(int h_error) return NULL; } +#endif +#ifdef HAVE_GETADDRINFO static PyObject * set_gaierror(int error) { @@ -649,6 +675,7 @@ set_gaierror(int error) return NULL; } +#endif /* Function to perform the setting of socket blocking mode internally. block = (1 | 0). */ @@ -1000,6 +1027,7 @@ init_sockobject(PySocketSockObject *s, } +#ifdef HAVE_SOCKETPAIR /* Create a new socket object. This just creates the object and initializes it. If the creation fails, return NULL and set an exception (implicit @@ -1019,6 +1047,7 @@ new_sockobject(SOCKET_T fd, int family, int type, int proto) } return s; } +#endif /* Lock to allow python interpreter to continue, but only allow one @@ -1028,6 +1057,7 @@ static PyThread_type_lock netdb_lock; #endif +#ifdef HAVE_GETADDRINFO /* Convert a string specifying a host name or one of a few symbolic names to a numeric IP address. This usually calls gethostbyname() to do the work; the names "" and "" are special. @@ -1055,6 +1085,7 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int subsequent call to getaddrinfo() does not destroy the outcome of the first call. */ if (error) { + res = NULL; // no-op, remind us that it is invalid; gh-100795 set_gaierror(error); return -1; } @@ -1165,6 +1196,7 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int #endif Py_END_ALLOW_THREADS if (error) { + res = NULL; // no-op, remind us that it is invalid; gh-100795 set_gaierror(error); return -1; } @@ -1184,7 +1216,7 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int return -1; } } - +#endif // HAVE_GETADDRINFO /* Convert IPv4 sockaddr to a Python str. */ @@ -1566,6 +1598,35 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) } #endif /* HAVE_SOCKADDR_ALG */ +#ifdef HAVE_AF_HYPERV + case AF_HYPERV: + { + SOCKADDR_HV *a = (SOCKADDR_HV *) addr; + + wchar_t *guidStr; + RPC_STATUS res = UuidToStringW(&a->VmId, &guidStr); + if (res != RPC_S_OK) { + PyErr_SetFromWindowsErr(res); + return 0; + } + PyObject *vmId = PyUnicode_FromWideChar(guidStr, -1); + res = RpcStringFreeW(&guidStr); + assert(res == RPC_S_OK); + + res = UuidToStringW(&a->ServiceId, &guidStr); + if (res != RPC_S_OK) { + Py_DECREF(vmId); + PyErr_SetFromWindowsErr(res); + return 0; + } + PyObject *serviceId = PyUnicode_FromWideChar(guidStr, -1); + res = RpcStringFreeW(&guidStr); + assert(res == RPC_S_OK); + + return Py_BuildValue("NN", vmId, serviceId); + } +#endif /* AF_HYPERV */ + /* More cases here... */ default: @@ -1579,6 +1640,7 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) } } +#if defined(HAVE_BIND) || defined(HAVE_CONNECTTO) || defined(CMSG_LEN) /* Helper for getsockaddrarg: bypass IDNA for ASCII-only host names (in particular, numeric IP addresses). */ struct maybe_idna { @@ -1677,13 +1739,17 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, struct sockaddr_un* addr = &addrbuf->un; #ifdef __linux__ - if (path.len > 0 && *(const char *)path.buf == 0) { - /* Linux abstract namespace extension */ + if (path.len == 0 || *(const char *)path.buf == 0) { + /* Linux abstract namespace extension: + - Empty address auto-binding to an abstract address + - Address that starts with null byte */ if ((size_t)path.len > sizeof addr->sun_path) { PyErr_SetString(PyExc_OSError, "AF_UNIX path too long"); goto unix_out; } + + *len_ret = path.len + offsetof(struct sockaddr_un, sun_path); } else #endif /* linux */ @@ -1695,10 +1761,13 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, goto unix_out; } addr->sun_path[path.len] = 0; + + /* including the tailing NUL */ + *len_ret = path.len + offsetof(struct sockaddr_un, sun_path) + 1; } addr->sun_family = s->sock_family; memcpy(addr->sun_path, path.buf, path.len); - *len_ret = path.len + offsetof(struct sockaddr_un, sun_path); + retval = 1; unix_out: PyBuffer_Release(&path); @@ -2357,6 +2426,76 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, return 1; } #endif /* HAVE_SOCKADDR_ALG */ +#ifdef HAVE_AF_HYPERV + case AF_HYPERV: + { + switch (s->sock_proto) { + case HV_PROTOCOL_RAW: + { + PyObject *vm_id_obj = NULL; + PyObject *service_id_obj = NULL; + + SOCKADDR_HV *addr = &addrbuf->hv; + + memset(addr, 0, sizeof(*addr)); + addr->Family = AF_HYPERV; + + if (!PyTuple_Check(args)) { + PyErr_Format(PyExc_TypeError, + "%s(): AF_HYPERV address must be tuple, not %.500s", + caller, Py_TYPE(args)->tp_name); + return 0; + } + if (!PyArg_ParseTuple(args, + "UU;AF_HYPERV address must be a str tuple (vm_id, service_id)", + &vm_id_obj, &service_id_obj)) + { + return 0; + } + + wchar_t *guid_str = PyUnicode_AsWideCharString(vm_id_obj, NULL); + if (guid_str == NULL) { + PyErr_Format(PyExc_ValueError, + "%s(): AF_HYPERV address vm_id is not a valid UUID string", + caller); + return 0; + } + RPC_STATUS rc = UuidFromStringW(guid_str, &addr->VmId); + PyMem_Free(guid_str); + if (rc != RPC_S_OK) { + PyErr_Format(PyExc_ValueError, + "%s(): AF_HYPERV address vm_id is not a valid UUID string", + caller); + return 0; + } + + guid_str = PyUnicode_AsWideCharString(service_id_obj, NULL); + if (guid_str == NULL) { + PyErr_Format(PyExc_ValueError, + "%s(): AF_HYPERV address service_id is not a valid UUID string", + caller); + return 0; + } + rc = UuidFromStringW(guid_str, &addr->ServiceId); + PyMem_Free(guid_str); + if (rc != RPC_S_OK) { + PyErr_Format(PyExc_ValueError, + "%s(): AF_HYPERV address service_id is not a valid UUID string", + caller); + return 0; + } + + *len_ret = sizeof(*addr); + return 1; + } + default: + PyErr_Format(PyExc_OSError, + "%s(): unsupported AF_HYPERV protocol: %d", + caller, s->sock_proto); + return 0; + } + } +#endif /* HAVE_AF_HYPERV */ /* More cases here... */ @@ -2366,6 +2505,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, } } +#endif // defined(HAVE_BIND) || defined(HAVE_CONNECTTO) || defined(CMSG_LEN) /* Get the address length according to the socket object's address family. @@ -2506,6 +2646,13 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret) return 1; } #endif /* HAVE_SOCKADDR_ALG */ +#ifdef HAVE_AF_HYPERV + case AF_HYPERV: + { + *len_ret = sizeof (SOCKADDR_HV); + return 1; + } +#endif /* HAVE_AF_HYPERV */ /* More cases here... */ @@ -2656,6 +2803,7 @@ struct sock_accept { SOCKET_T result; }; +#if defined(HAVE_ACCEPT) || defined(HAVE_ACCEPT4) #if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) /* accept4() is available on Linux 2.6.28+ and glibc 2.10 */ static int accept4_works = -1; @@ -2769,6 +2917,8 @@ PyDoc_STRVAR(accept_doc, Wait for an incoming connection. Return a new socket file descriptor\n\ representing the connection, and the address of the client.\n\ For IP sockets, the address info is a pair (hostaddr, port)."); +#endif // defined(HAVE_ACCEPT) || defined(HAVE_ACCEPT4) + /* s.setblocking(flag) method. Argument: False -- non-blocking mode; same as settimeout(0) @@ -2780,8 +2930,8 @@ sock_setblocking(PySocketSockObject *s, PyObject *arg) { long block; - block = PyLong_AsLong(arg); - if (block == -1 && PyErr_Occurred()) + block = PyObject_IsTrue(arg); + if (block < 0) return NULL; s->sock_timeout = _PyTime_FromSeconds(block ? -1 : 0); @@ -2933,6 +3083,7 @@ Returns the timeout in seconds (float) associated with socket\n\ operations. A timeout of None indicates that timeouts on socket\n\ operations are disabled."); +#ifdef HAVE_SETSOCKOPT /* s.setsockopt() method. With an integer third argument, sets an integer optval with optlen=4. With None as third argument and an integer fourth argument, set @@ -3022,7 +3173,7 @@ setsockopt(level, option, None, optlen: int)\n\ Set a socket option. See the Unix manual for level and option.\n\ The value argument can either be an integer, a string buffer, or\n\ None, optlen."); - +#endif /* s.getsockopt() method. With two arguments, retrieves an integer option. @@ -3096,6 +3247,7 @@ If a nonzero buffersize argument is given, the return value is a\n\ string of that length; otherwise it is an integer."); +#ifdef HAVE_BIND /* s.bind(sockaddr) method */ static PyObject * @@ -3127,6 +3279,7 @@ PyDoc_STRVAR(bind_doc, Bind the socket to a local address. For IP sockets, the address is a\n\ pair (host, port); the host must refer to the local host. For raw packet\n\ sockets the address is a tuple (ifname, proto [,pkttype [,hatype [,addr]]])"); +#endif /* s.close() method. @@ -3179,6 +3332,7 @@ Close the socket object without closing the underlying file descriptor.\n\ The object cannot be used after this call, but the file descriptor\n\ can be reused for other purposes. The file descriptor is returned."); +#ifdef HAVE_CONNECT static int sock_connect_impl(PySocketSockObject *s, void* Py_UNUSED(data)) { @@ -3326,6 +3480,7 @@ PyDoc_STRVAR(connect_ex_doc, \n\ This is like connect(address), but returns an error code (the errno value)\n\ instead of raising an exception when an error occurs."); +#endif // HAVE_CONNECT /* s.fileno() method */ @@ -3342,6 +3497,7 @@ PyDoc_STRVAR(fileno_doc, Return the integer file descriptor of the socket."); +#ifdef HAVE_GETSOCKNAME /* s.getsockname() method */ static PyObject * @@ -3369,6 +3525,7 @@ PyDoc_STRVAR(getsockname_doc, Return the address of the local endpoint. The format depends on the\n\ address family. For IPv4 sockets, the address info is a pair\n\ (hostaddr, port)."); +#endif #ifdef HAVE_GETPEERNAME /* Cray APP doesn't have this :-( */ @@ -3402,6 +3559,7 @@ info is a pair (hostaddr, port)."); #endif /* HAVE_GETPEERNAME */ +#ifdef HAVE_LISTEN /* s.listen(n) method */ static PyObject * @@ -3434,6 +3592,7 @@ Enable a server to accept connections. If backlog is specified, it must be\n\ at least 0 (if it is lower, it is set to 0); it specifies the number of\n\ unaccepted connections that the system will allow before refusing new\n\ connections. If not specified, a default reasonable value is chosen."); +#endif struct sock_recv { char *cbuf; @@ -3610,6 +3769,7 @@ struct sock_recvfrom { Py_ssize_t result; }; +#ifdef HAVE_RECVFROM static int sock_recvfrom_impl(PySocketSockObject *s, void *data) { @@ -3782,6 +3942,7 @@ PyDoc_STRVAR(recvfrom_into_doc, "recvfrom_into(buffer[, nbytes[, flags]]) -> (nbytes, address info)\n\ \n\ Like recv_into(buffer[, nbytes[, flags]]) but also return the sender's address info."); +#endif /* The sendmsg() and recvmsg[_into]() methods require a working CMSG_LEN(). See the comment near get_CMSG_LEN(). */ @@ -3951,8 +4112,7 @@ makeval_recvmsg(ssize_t received, void *data) if (received < PyBytes_GET_SIZE(*buf)) _PyBytes_Resize(buf, received); - Py_XINCREF(*buf); - return *buf; + return Py_XNewRef(*buf); } /* s.recvmsg(bufsize[, ancbufsize[, flags]]) method */ @@ -4231,8 +4391,7 @@ sock_sendall(PySocketSockObject *s, PyObject *args) } while (len > 0); PyBuffer_Release(&pbuf); - Py_INCREF(Py_None); - res = Py_None; + res = Py_NewRef(Py_None); done: PyBuffer_Release(&pbuf); @@ -4248,6 +4407,7 @@ until all data is sent. If an error occurs, it's impossible\n\ to tell how much data has been sent."); +#ifdef HAVE_SENDTO struct sock_sendto { char *buf; Py_ssize_t len; @@ -4340,6 +4500,7 @@ PyDoc_STRVAR(sendto_doc, \n\ Like send(data, flags) but allows specifying the destination address.\n\ For IP sockets, the address is a pair (hostaddr, port)."); +#endif /* The sendmsg() and recvmsg[_into]() methods require a working @@ -4788,6 +4949,7 @@ Set operation mode, IV and length of associated data for an AF_ALG\n\ operation socket."); #endif +#ifdef HAVE_SHUTDOWN /* s.shutdown(how) method */ static PyObject * @@ -4812,6 +4974,7 @@ PyDoc_STRVAR(shutdown_doc, \n\ Shut down the reading side of the socket (flag == SHUT_RD), the writing side\n\ of the socket (flag == SHUT_WR), or both ends (flag == SHUT_RDWR)."); +#endif #if defined(MS_WINDOWS) && defined(SIO_RCVALL) static PyObject* @@ -4901,16 +5064,22 @@ socket.fromshare()."); /* List of methods for socket objects */ static PyMethodDef sock_methods[] = { +#if defined(HAVE_ACCEPT) || defined(HAVE_ACCEPT4) {"_accept", (PyCFunction)sock_accept, METH_NOARGS, accept_doc}, +#endif +#ifdef HAVE_BIND {"bind", (PyCFunction)sock_bind, METH_O, bind_doc}, +#endif {"close", (PyCFunction)sock_close, METH_NOARGS, sock_close_doc}, +#ifdef HAVE_CONNECT {"connect", (PyCFunction)sock_connect, METH_O, connect_doc}, {"connect_ex", (PyCFunction)sock_connect_ex, METH_O, connect_ex_doc}, +#endif {"detach", (PyCFunction)sock_detach, METH_NOARGS, detach_doc}, {"fileno", (PyCFunction)sock_fileno, METH_NOARGS, @@ -4919,8 +5088,10 @@ static PyMethodDef sock_methods[] = { {"getpeername", (PyCFunction)sock_getpeername, METH_NOARGS, getpeername_doc}, #endif +#ifdef HAVE_GETSOCKNAME {"getsockname", (PyCFunction)sock_getsockname, METH_NOARGS, getsockname_doc}, +#endif {"getsockopt", (PyCFunction)sock_getsockopt, METH_VARARGS, getsockopt_doc}, #if defined(MS_WINDOWS) && defined(SIO_RCVALL) @@ -4931,22 +5102,28 @@ static PyMethodDef sock_methods[] = { {"share", (PyCFunction)sock_share, METH_VARARGS, sock_share_doc}, #endif +#ifdef HAVE_LISTEN {"listen", (PyCFunction)sock_listen, METH_VARARGS, listen_doc}, +#endif {"recv", (PyCFunction)sock_recv, METH_VARARGS, recv_doc}, - {"recv_into", (PyCFunction)(void(*)(void))sock_recv_into, METH_VARARGS | METH_KEYWORDS, + {"recv_into", _PyCFunction_CAST(sock_recv_into), METH_VARARGS | METH_KEYWORDS, recv_into_doc}, +#ifdef HAVE_RECVFROM {"recvfrom", (PyCFunction)sock_recvfrom, METH_VARARGS, recvfrom_doc}, - {"recvfrom_into", (PyCFunction)(void(*)(void))sock_recvfrom_into, METH_VARARGS | METH_KEYWORDS, + {"recvfrom_into", _PyCFunction_CAST(sock_recvfrom_into), METH_VARARGS | METH_KEYWORDS, recvfrom_into_doc}, +#endif {"send", (PyCFunction)sock_send, METH_VARARGS, send_doc}, {"sendall", (PyCFunction)sock_sendall, METH_VARARGS, sendall_doc}, +#ifdef HAVE_SENDTO {"sendto", (PyCFunction)sock_sendto, METH_VARARGS, sendto_doc}, +#endif {"setblocking", (PyCFunction)sock_setblocking, METH_O, setblocking_doc}, {"getblocking", (PyCFunction)sock_getblocking, METH_NOARGS, @@ -4955,10 +5132,14 @@ static PyMethodDef sock_methods[] = { settimeout_doc}, {"gettimeout", (PyCFunction)sock_gettimeout, METH_NOARGS, gettimeout_doc}, +#ifdef HAVE_SETSOCKOPT {"setsockopt", (PyCFunction)sock_setsockopt, METH_VARARGS, setsockopt_doc}, +#endif +#ifdef HAVE_SHUTDOWN {"shutdown", (PyCFunction)sock_shutdown, METH_O, shutdown_doc}, +#endif #ifdef CMSG_LEN {"recvmsg", (PyCFunction)sock_recvmsg, METH_VARARGS, recvmsg_doc}, @@ -4968,7 +5149,7 @@ static PyMethodDef sock_methods[] = { sendmsg_doc}, #endif #ifdef HAVE_SOCKADDR_ALG - {"sendmsg_afalg", (PyCFunction)(void(*)(void))sock_sendmsg_afalg, METH_VARARGS | METH_KEYWORDS, + {"sendmsg_afalg", _PyCFunction_CAST(sock_sendmsg_afalg), METH_VARARGS | METH_KEYWORDS, sendmsg_afalg_doc}, #endif {NULL, NULL} /* sentinel */ @@ -5089,14 +5270,33 @@ static int sock_cloexec_works = -1; #endif /*ARGSUSED*/ + +#ifndef HAVE_SOCKET +#define socket stub_socket static int -sock_initobj(PyObject *self, PyObject *args, PyObject *kwds) +socket(int domain, int type, int protocol) { - PySocketSockObject *s = (PySocketSockObject *)self; - PyObject *fdobj = NULL; + errno = ENOTSUP; + return INVALID_SOCKET; +} +#endif + +/*[clinic input] +_socket.socket.__init__ as sock_initobj + family: int = -1 + type: int = -1 + proto: int = -1 + fileno as fdobj: object = NULL +[clinic start generated code]*/ + +static int +sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto, + PyObject *fdobj) +/*[clinic end generated code: output=d114d026b9a9a810 input=04cfc32953f5cc25]*/ +{ + SOCKET_T fd = INVALID_SOCKET; - int family = -1, type = -1, proto = -1; - static char *keywords[] = {"family", "type", "proto", "fileno", 0}; + #ifndef MS_WINDOWS #ifdef SOCK_CLOEXEC int *atomic_flag_works = &sock_cloexec_works; @@ -5105,18 +5305,13 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwds) #endif #endif - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "|iiiO:socket", keywords, - &family, &type, &proto, &fdobj)) - return -1; - #ifdef MS_WINDOWS /* In this case, we don't use the family, type and proto args */ if (fdobj == NULL || fdobj == Py_None) #endif { if (PySys_Audit("socket.__new__", "Oiii", - s, family, type, proto) < 0) { + self, family, type, proto) < 0) { return -1; } } @@ -5134,7 +5329,7 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwds) } memcpy(&info, PyBytes_AS_STRING(fdobj), sizeof(info)); - if (PySys_Audit("socket.__new__", "Oiii", s, + if (PySys_Audit("socket.__new__", "Oiii", self, info.iAddressFamily, info.iSocketType, info.iProtocol) < 0) { return -1; @@ -5172,6 +5367,7 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwds) socklen_t addrlen = sizeof(sock_addr_t); memset(&addrbuf, 0, addrlen); +#ifdef HAVE_GETSOCKNAME if (getsockname(fd, SAS2SA(&addrbuf), &addrlen) == 0) { if (family == -1) { family = SAS2SA(&addrbuf)->sa_family; @@ -5190,6 +5386,7 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwds) return -1; } } +#endif // HAVE_GETSOCKNAME #ifdef SO_TYPE if (type == -1) { int tmp; @@ -5304,7 +5501,7 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwds) } #endif } - if (init_sockobject(s, fd, family, type, proto) == -1) { + if (init_sockobject(self, fd, family, type, proto) == -1) { SOCKETCLOSE(fd); return -1; } @@ -5368,6 +5565,7 @@ static PyTypeObject sock_type = { }; +#ifdef HAVE_GETHOSTNAME /* Python interface to gethostname(). */ /*ARGSUSED*/ @@ -5431,6 +5629,7 @@ PyDoc_STRVAR(gethostname_doc, "gethostname() -> string\n\ \n\ Return the current host name."); +#endif #ifdef HAVE_SETHOSTNAME PyDoc_STRVAR(sethostname_doc, @@ -5474,6 +5673,7 @@ extern int sethostname(const char *, size_t); } #endif +#ifdef HAVE_GETADDRINFO /* Python interface to gethostbyname(name). */ /*ARGSUSED*/ @@ -5501,8 +5701,10 @@ PyDoc_STRVAR(gethostbyname_doc, "gethostbyname(host) -> address\n\ \n\ Return the IP address (a string of the form '255.255.255.255') for a host."); +#endif +#if defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYNAME) || defined (HAVE_GETHOSTBYADDR) static PyObject* sock_decode_hostname(const char *name) { @@ -5644,8 +5846,9 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af) Py_XDECREF(addr_list); return rtn_tuple; } +#endif - +#if defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYNAME) /* Python interface to gethostbyname_ex(name). */ /*ARGSUSED*/ @@ -5718,8 +5921,9 @@ PyDoc_STRVAR(ghbn_ex_doc, \n\ Return the true host name, a list of aliases, and a list of IP addresses,\n\ for a host. The host argument is a string giving a host name or IP number."); +#endif - +#if defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR) /* Python interface to gethostbyaddr(IP). */ /*ARGSUSED*/ @@ -5814,8 +6018,9 @@ PyDoc_STRVAR(gethostbyaddr_doc, \n\ Return the true host name, a list of aliases, and a list of IP addresses,\n\ for a host. The host argument is a string giving a host name or IP number."); +#endif - +#ifdef HAVE_GETSERVBYNAME /* Python interface to getservbyname(name). This only returns the port number, since the other info is already known or not useful (like the list of aliases). */ @@ -5849,8 +6054,9 @@ PyDoc_STRVAR(getservbyname_doc, Return a port number from a service name and protocol name.\n\ The optional protocol name, if given, should be 'tcp' or 'udp',\n\ otherwise any protocol will match."); +#endif - +#ifdef HAVE_GETSERVBYPORT /* Python interface to getservbyport(port). This only returns the service name, since the other info is already known or not useful (like the list of aliases). */ @@ -5891,7 +6097,9 @@ PyDoc_STRVAR(getservbyport_doc, Return the service name from a port number and protocol name.\n\ The optional protocol name, if given, should be 'tcp' or 'udp',\n\ otherwise any protocol will match."); +#endif +#ifdef HAVE_GETPROTOBYNAME /* Python interface to getprotobyname(name). This only returns the protocol number, since the other info is already known or not useful (like the list of aliases). */ @@ -5918,6 +6126,7 @@ PyDoc_STRVAR(getprotobyname_doc, "getprotobyname(name) -> integer\n\ \n\ Return the protocol number for the named protocol. (Rarely used.)"); +#endif static PyObject * socket_close(PyObject *self, PyObject *fdobj) @@ -6287,6 +6496,7 @@ socket_inet_aton(PyObject *self, PyObject *args) #endif } +#ifdef HAVE_INET_NTOA PyDoc_STRVAR(inet_ntoa_doc, "inet_ntoa(packed_ip) -> ip_address_string\n\ \n\ @@ -6315,6 +6525,7 @@ socket_inet_ntoa(PyObject *self, PyObject *args) SUPPRESS_DEPRECATED_CALL return PyUnicode_FromString(inet_ntoa(packed_addr)); } +#endif // HAVE_INET_NTOA #ifdef HAVE_INET_PTON @@ -6426,6 +6637,7 @@ socket_inet_ntop(PyObject *self, PyObject *args) #endif /* HAVE_INET_PTON */ +#ifdef HAVE_GETADDRINFO /* Python interface to getaddrinfo(host, port). */ /*ARGSUSED*/ @@ -6509,6 +6721,7 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) error = getaddrinfo(hptr, pptr, &hints, &res0); Py_END_ALLOW_THREADS if (error) { + res0 = NULL; // gh-100795 set_gaierror(error); goto err; } @@ -6553,7 +6766,9 @@ PyDoc_STRVAR(getaddrinfo_doc, -> list of (family, type, proto, canonname, sockaddr)\n\ \n\ Resolve host and port into addrinfo struct."); +#endif // HAVE_GETADDRINFO +#ifdef HAVE_GETNAMEINFO /* Python interface to getnameinfo(sa, flags). */ /*ARGSUSED*/ @@ -6603,6 +6818,7 @@ socket_getnameinfo(PyObject *self, PyObject *args) error = getaddrinfo(hostp, pbuf, &hints, &res); Py_END_ALLOW_THREADS if (error) { + res = NULL; // gh-100795 set_gaierror(error); goto fail; } @@ -6654,7 +6870,7 @@ PyDoc_STRVAR(getnameinfo_doc, "getnameinfo(sockaddr, flags) --> (host, port)\n\ \n\ Get host and port for a sockaddr."); - +#endif // HAVE_GETNAMEINFO /* Python API to getting and setting the default timeout value. */ @@ -6910,24 +7126,38 @@ range of values."); /* List of functions exported by this module. */ static PyMethodDef socket_methods[] = { +#ifdef HAVE_GETADDRINFO {"gethostbyname", socket_gethostbyname, METH_VARARGS, gethostbyname_doc}, +#endif +#if defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYNAME) {"gethostbyname_ex", socket_gethostbyname_ex, METH_VARARGS, ghbn_ex_doc}, +#endif +#if defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR) {"gethostbyaddr", socket_gethostbyaddr, METH_VARARGS, gethostbyaddr_doc}, +#endif +#ifdef HAVE_GETHOSTNAME {"gethostname", socket_gethostname, METH_NOARGS, gethostname_doc}, +#endif #ifdef HAVE_SETHOSTNAME {"sethostname", socket_sethostname, METH_VARARGS, sethostname_doc}, #endif +#ifdef HAVE_GETSERVBYNAME {"getservbyname", socket_getservbyname, METH_VARARGS, getservbyname_doc}, +#endif +#ifdef HAVE_GETSERVBYPORT {"getservbyport", socket_getservbyport, METH_VARARGS, getservbyport_doc}, +#endif +#ifdef HAVE_GETPROTOBYNAME {"getprotobyname", socket_getprotobyname, METH_VARARGS, getprotobyname_doc}, +#endif {"close", socket_close, METH_O, close_doc}, #ifndef NO_DUP @@ -6948,18 +7178,24 @@ static PyMethodDef socket_methods[] = { METH_O, htonl_doc}, {"inet_aton", socket_inet_aton, METH_VARARGS, inet_aton_doc}, +#ifdef HAVE_INET_NTOA {"inet_ntoa", socket_inet_ntoa, METH_VARARGS, inet_ntoa_doc}, +#endif #ifdef HAVE_INET_PTON {"inet_pton", socket_inet_pton, METH_VARARGS, inet_pton_doc}, {"inet_ntop", socket_inet_ntop, METH_VARARGS, inet_ntop_doc}, #endif - {"getaddrinfo", (PyCFunction)(void(*)(void))socket_getaddrinfo, +#ifdef HAVE_GETADDRINFO + {"getaddrinfo", _PyCFunction_CAST(socket_getaddrinfo), METH_VARARGS | METH_KEYWORDS, getaddrinfo_doc}, +#endif +#ifdef HAVE_GETNAMEINFO {"getnameinfo", socket_getnameinfo, METH_VARARGS, getnameinfo_doc}, +#endif {"getdefaulttimeout", socket_getdefaulttimeout, METH_NOARGS, getdefaulttimeout_doc}, {"setdefaulttimeout", socket_setdefaulttimeout, @@ -7112,29 +7348,22 @@ PyInit__socket(void) if (m == NULL) return NULL; - Py_INCREF(PyExc_OSError); - PyModule_AddObject(m, "error", PyExc_OSError); + PyModule_AddObject(m, "error", Py_NewRef(PyExc_OSError)); socket_herror = PyErr_NewException("socket.herror", PyExc_OSError, NULL); if (socket_herror == NULL) return NULL; - Py_INCREF(socket_herror); - PyModule_AddObject(m, "herror", socket_herror); + PyModule_AddObject(m, "herror", Py_NewRef(socket_herror)); socket_gaierror = PyErr_NewException("socket.gaierror", PyExc_OSError, NULL); if (socket_gaierror == NULL) return NULL; - Py_INCREF(socket_gaierror); - PyModule_AddObject(m, "gaierror", socket_gaierror); + PyModule_AddObject(m, "gaierror", Py_NewRef(socket_gaierror)); PyModule_AddObjectRef(m, "timeout", PyExc_TimeoutError); - Py_INCREF((PyObject *)&sock_type); - if (PyModule_AddObject(m, "SocketType", - (PyObject *)&sock_type) != 0) + if (PyModule_AddObject(m, "SocketType", Py_NewRef(&sock_type)) != 0) return NULL; - Py_INCREF((PyObject *)&sock_type); - if (PyModule_AddObject(m, "socket", - (PyObject *)&sock_type) != 0) + if (PyModule_AddObject(m, "socket", Py_NewRef(&sock_type)) != 0) return NULL; #ifdef ENABLE_IPV6 @@ -7142,8 +7371,7 @@ PyInit__socket(void) #else has_ipv6 = Py_False; #endif - Py_INCREF(has_ipv6); - PyModule_AddObject(m, "has_ipv6", has_ipv6); + PyModule_AddObject(m, "has_ipv6", Py_NewRef(has_ipv6)); /* Export C API */ PySocketModule_APIObject *capi = sock_get_api(); @@ -7325,6 +7553,27 @@ PyInit__socket(void) /* Linux LLC */ PyModule_AddIntMacro(m, AF_LLC); #endif +#ifdef HAVE_AF_HYPERV + /* Hyper-V sockets */ + PyModule_AddIntMacro(m, AF_HYPERV); + + /* for proto */ + PyModule_AddIntMacro(m, HV_PROTOCOL_RAW); + + /* for setsockopt() */ + PyModule_AddIntMacro(m, HVSOCKET_CONNECT_TIMEOUT); + PyModule_AddIntMacro(m, HVSOCKET_CONNECT_TIMEOUT_MAX); + PyModule_AddIntMacro(m, HVSOCKET_CONNECTED_SUSPEND); + PyModule_AddIntMacro(m, HVSOCKET_ADDRESS_FLAG_PASSTHRU); + + /* for bind() or connect() */ + PyModule_AddStringConstant(m, "HV_GUID_ZERO", "00000000-0000-0000-0000-000000000000"); + PyModule_AddStringConstant(m, "HV_GUID_WILDCARD", "00000000-0000-0000-0000-000000000000"); + PyModule_AddStringConstant(m, "HV_GUID_BROADCAST", "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"); + PyModule_AddStringConstant(m, "HV_GUID_CHILDREN", "90DB8B89-0D35-4F79-8CE9-49EA0AC8B7CD"); + PyModule_AddStringConstant(m, "HV_GUID_LOOPBACK", "E0E16197-DD56-4A10-9195-5EE7A155A838"); + PyModule_AddStringConstant(m, "HV_GUID_PARENT", "A42E7CDA-D03F-480C-9CC2-A4DE20ABB878"); +#endif /* HAVE_AF_HYPERV */ #ifdef USE_BLUETOOTH PyModule_AddIntMacro(m, AF_BLUETOOTH); @@ -7460,6 +7709,25 @@ PyInit__socket(void) PyModule_AddIntMacro(m, ALG_OP_VERIFY); #endif +/* IEEE 802.3 protocol numbers required for a standard TCP/IP network stack */ +#ifdef ETHERTYPE_ARP + PyModule_AddIntMacro(m, ETHERTYPE_ARP); +#endif +#ifdef ETHERTYPE_IP + PyModule_AddIntMacro(m, ETHERTYPE_IP); +#endif +#ifdef ETHERTYPE_IPV6 + PyModule_AddIntMacro(m, ETHERTYPE_IPV6); +#endif +#ifdef ETHERTYPE_VLAN + PyModule_AddIntMacro(m, ETHERTYPE_VLAN); +#endif + +/* Linux pseudo-protocol for sniffing every packet */ +#ifdef ETH_P_ALL + PyModule_AddIntMacro(m, ETH_P_ALL); +#endif + /* Socket types */ PyModule_AddIntMacro(m, SOCK_STREAM); PyModule_AddIntMacro(m, SOCK_DGRAM); @@ -7468,7 +7736,9 @@ PyInit__socket(void) /* SOCK_RAW is marked as optional in the POSIX specification */ PyModule_AddIntMacro(m, SOCK_RAW); #endif +#ifdef SOCK_SEQPACKET PyModule_AddIntMacro(m, SOCK_SEQPACKET); +#endif #if defined(SOCK_RDM) PyModule_AddIntMacro(m, SOCK_RDM); #endif @@ -7491,6 +7761,9 @@ PyInit__socket(void) #ifdef SO_EXCLUSIVEADDRUSE PyModule_AddIntMacro(m, SO_EXCLUSIVEADDRUSE); #endif +#ifdef SO_INCOMING_CPU + PyModule_AddIntMacro(m, SO_INCOMING_CPU); +#endif #ifdef SO_KEEPALIVE PyModule_AddIntMacro(m, SO_KEEPALIVE); @@ -7566,12 +7839,24 @@ PyInit__socket(void) #ifdef SO_MARK PyModule_AddIntMacro(m, SO_MARK); #endif +#ifdef SO_USER_COOKIE + PyModule_AddIntMacro(m, SO_USER_COOKIE); +#endif +#ifdef SO_RTABLE + PyModule_AddIntMacro(m, SO_RTABLE); +#endif #ifdef SO_DOMAIN PyModule_AddIntMacro(m, SO_DOMAIN); #endif #ifdef SO_PROTOCOL PyModule_AddIntMacro(m, SO_PROTOCOL); #endif +#ifdef LOCAL_CREDS + PyModule_AddIntMacro(m, LOCAL_CREDS); +#endif +#ifdef LOCAL_CREDS_PERSISTENT + PyModule_AddIntMacro(m, LOCAL_CREDS_PERSISTENT); +#endif /* Maximum number of connections for "listen" */ #ifdef SOMAXCONN @@ -7590,6 +7875,9 @@ PyInit__socket(void) #ifdef SCM_CREDS PyModule_AddIntMacro(m, SCM_CREDS); #endif +#ifdef SCM_CREDS2 + PyModule_AddIntMacro(m, SCM_CREDS2); +#endif /* Flags for send, recv */ #ifdef MSG_OOB @@ -7608,6 +7896,10 @@ PyInit__socket(void) PyModule_AddIntMacro(m, MSG_EOR); #endif #ifdef MSG_TRUNC + // workaround for https://github.com/WebAssembly/wasi-libc/issues/305 + #if defined(__wasi__) && !defined(__WASI_RIFLAGS_RECV_DATA_TRUNCATED) + # define __WASI_RIFLAGS_RECV_DATA_TRUNCATED 2 + #endif PyModule_AddIntMacro(m, MSG_TRUNC); #endif #ifdef MSG_CTRUNC @@ -7694,7 +7986,7 @@ PyInit__socket(void) PyModule_AddIntMacro(m, SOL_CAN_RAW); PyModule_AddIntMacro(m, CAN_RAW); #endif -#ifdef HAVE_LINUX_CAN_H +#if defined(HAVE_LINUX_CAN_H) || defined(HAVE_NETCAN_CAN_H) PyModule_AddIntMacro(m, CAN_EFF_FLAG); PyModule_AddIntMacro(m, CAN_RTR_FLAG); PyModule_AddIntMacro(m, CAN_ERR_FLAG); @@ -7709,9 +8001,11 @@ PyInit__socket(void) PyModule_AddIntMacro(m, CAN_J1939); #endif #endif -#ifdef HAVE_LINUX_CAN_RAW_H +#if defined(HAVE_LINUX_CAN_RAW_H) || defined(HAVE_NETCAN_CAN_H) PyModule_AddIntMacro(m, CAN_RAW_FILTER); +#ifdef CAN_RAW_ERR_FILTER PyModule_AddIntMacro(m, CAN_RAW_ERR_FILTER); +#endif PyModule_AddIntMacro(m, CAN_RAW_LOOPBACK); PyModule_AddIntMacro(m, CAN_RAW_RECV_OWN_MSGS); #endif @@ -8061,6 +8355,12 @@ PyInit__socket(void) #ifdef IP_TRANSPARENT PyModule_AddIntMacro(m, IP_TRANSPARENT); #endif +#ifdef IP_PKTINFO + PyModule_AddIntMacro(m, IP_PKTINFO); +#endif +#ifdef IP_BIND_ADDRESS_NO_PORT + PyModule_AddIntMacro(m, IP_BIND_ADDRESS_NO_PORT); +#endif /* IPv6 [gs]etsockopt options, defined in RFC2553 */ #ifdef IPV6_JOIN_GROUP @@ -8185,21 +8485,84 @@ PyInit__socket(void) #ifdef TCP_INFO PyModule_AddIntMacro(m, TCP_INFO); #endif +#ifdef TCP_CONNECTION_INFO + PyModule_AddIntMacro(m, TCP_CONNECTION_INFO); +#endif #ifdef TCP_QUICKACK PyModule_AddIntMacro(m, TCP_QUICKACK); #endif -#ifdef TCP_FASTOPEN - PyModule_AddIntMacro(m, TCP_FASTOPEN); -#endif #ifdef TCP_CONGESTION PyModule_AddIntMacro(m, TCP_CONGESTION); #endif +#ifdef TCP_MD5SIG + PyModule_AddIntMacro(m, TCP_MD5SIG); +#endif +#ifdef TCP_THIN_LINEAR_TIMEOUTS + PyModule_AddIntMacro(m, TCP_THIN_LINEAR_TIMEOUTS); +#endif +#ifdef TCP_THIN_DUPACK + PyModule_AddIntMacro(m, TCP_THIN_DUPACK); +#endif #ifdef TCP_USER_TIMEOUT PyModule_AddIntMacro(m, TCP_USER_TIMEOUT); #endif +#ifdef TCP_REPAIR + PyModule_AddIntMacro(m, TCP_REPAIR); +#endif +#ifdef TCP_REPAIR_QUEUE + PyModule_AddIntMacro(m, TCP_REPAIR_QUEUE); +#endif +#ifdef TCP_QUEUE_SEQ + PyModule_AddIntMacro(m, TCP_QUEUE_SEQ); +#endif +#ifdef TCP_REPAIR_OPTIONS + PyModule_AddIntMacro(m, TCP_REPAIR_OPTIONS); +#endif +#ifdef TCP_FASTOPEN + PyModule_AddIntMacro(m, TCP_FASTOPEN); +#endif +#ifdef TCP_TIMESTAMP + PyModule_AddIntMacro(m, TCP_TIMESTAMP); +#endif #ifdef TCP_NOTSENT_LOWAT PyModule_AddIntMacro(m, TCP_NOTSENT_LOWAT); #endif +#ifdef TCP_CC_INFO + PyModule_AddIntMacro(m, TCP_CC_INFO); +#endif +#ifdef TCP_SAVE_SYN + PyModule_AddIntMacro(m, TCP_SAVE_SYN); +#endif +#ifdef TCP_SAVED_SYN + PyModule_AddIntMacro(m, TCP_SAVED_SYN); +#endif +#ifdef TCP_REPAIR_WINDOW + PyModule_AddIntMacro(m, TCP_REPAIR_WINDOW); +#endif +#ifdef TCP_FASTOPEN_CONNECT + PyModule_AddIntMacro(m, TCP_FASTOPEN_CONNECT); +#endif +#ifdef TCP_ULP + PyModule_AddIntMacro(m, TCP_ULP); +#endif +#ifdef TCP_MD5SIG_EXT + PyModule_AddIntMacro(m, TCP_MD5SIG_EXT); +#endif +#ifdef TCP_FASTOPEN_KEY + PyModule_AddIntMacro(m, TCP_FASTOPEN_KEY); +#endif +#ifdef TCP_FASTOPEN_NO_COOKIE + PyModule_AddIntMacro(m, TCP_FASTOPEN_NO_COOKIE); +#endif +#ifdef TCP_ZEROCOPY_RECEIVE + PyModule_AddIntMacro(m, TCP_ZEROCOPY_RECEIVE); +#endif +#ifdef TCP_INQ + PyModule_AddIntMacro(m, TCP_INQ); +#endif +#ifdef TCP_TX_DELAY + PyModule_AddIntMacro(m, TCP_TX_DELAY); +#endif /* IPX options */ #ifdef IPX_TYPE diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index aea599f0ee6..f31ba532a6c 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -76,6 +76,15 @@ struct SOCKADDR_BTH_REDEF { # else typedef int socklen_t; # endif /* IPPROTO_IPV6 */ + +/* Remove ifdef once Py_WINVER >= 0x0604 + * socket.h only defines AF_HYPERV if _WIN32_WINNT is at that level or higher + * so for now it's just manually defined. + */ +# ifndef AF_HYPERV +# define AF_HYPERV 34 +# endif +# include #endif /* MS_WINDOWS */ #ifdef HAVE_SYS_UN_H @@ -129,6 +138,8 @@ typedef int socklen_t; #ifdef HAVE_LINUX_CAN_H # include +#elif defined(HAVE_NETCAN_CAN_H) +# include #else # undef AF_CAN # undef PF_CAN @@ -190,6 +201,21 @@ typedef int socklen_t; #endif /* HAVE_SOCKADDR_ALG */ +#ifdef __EMSCRIPTEN__ +// wasm32-emscripten sockets only support subset of IPv4 and IPv6. +// SCTP protocol crashes runtime. +#ifdef IPPROTO_SCTP +# undef IPPROTO_SCTP +#endif +// setsockopt() fails with ENOPROTOOPT, getsockopt only supports SO_ERROR. +// undef SO_REUSEADDR and SO_REUSEPORT so they cannot be used. +#ifdef SO_REUSEADDR +# undef SO_REUSEADDR +#endif +#ifdef SO_REUSEPORT +# undef SO_REUSEPORT +#endif +#endif // __EMSCRIPTEN__ #ifndef Py__SOCKET_H #define Py__SOCKET_H @@ -223,6 +249,11 @@ typedef int SOCKET_T; #define PyLong_AsSocket_t(fd) (SOCKET_T)PyLong_AsLongLong(fd) #endif +// AF_HYPERV is only supported on Windows +#if defined(AF_HYPERV) && defined(MS_WINDOWS) +# define HAVE_AF_HYPERV +#endif + /* Socket address */ typedef union sock_addr { struct sockaddr_in in; @@ -253,7 +284,7 @@ typedef union sock_addr { #ifdef HAVE_NETPACKET_PACKET_H struct sockaddr_ll ll; #endif -#ifdef HAVE_LINUX_CAN_H +#if defined(HAVE_LINUX_CAN_H) || defined(HAVE_NETCAN_CAN_H) struct sockaddr_can can; #endif #ifdef HAVE_SYS_KERN_CONTROL_H @@ -271,6 +302,9 @@ typedef union sock_addr { #ifdef HAVE_LINUX_TIPC_H struct sockaddr_tipc tipc; #endif +#ifdef HAVE_AF_HYPERV + SOCKADDR_HV hv; +#endif } sock_addr_t; /* The object holding a socket. It holds some extra information, diff --git a/Modules/spwdmodule.c b/Modules/spwdmodule.c index acea30679bf..42123c93b59 100644 --- a/Modules/spwdmodule.c +++ b/Modules/spwdmodule.c @@ -256,5 +256,12 @@ static struct PyModuleDef spwdmodule = { PyMODINIT_FUNC PyInit_spwd(void) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "'spwd' is deprecated and slated for removal in " + "Python 3.13", + 7)) { + return NULL; + } + return PyModuleDef_Init(&spwdmodule); } diff --git a/Modules/symtablemodule.c b/Modules/symtablemodule.c index c25ecc2b5dc..4ef1d8cde07 100644 --- a/Modules/symtablemodule.c +++ b/Modules/symtablemodule.c @@ -56,8 +56,7 @@ _symtable_symtable_impl(PyObject *module, PyObject *source, if (st == NULL) { return NULL; } - t = (PyObject *)st->st_top; - Py_INCREF(t); + t = Py_NewRef(st->st_top); _PySymtable_Free(st); return t; } diff --git a/Modules/syslogmodule.c b/Modules/syslogmodule.c index 0f2fea15b3a..f45aa5227f1 100644 --- a/Modules/syslogmodule.c +++ b/Modules/syslogmodule.c @@ -54,10 +54,23 @@ Revision history: #include -/* only one instance, only one syslog, so globals should be ok */ -static PyObject *S_ident_o = NULL; /* identifier, held by openlog() */ +/*[clinic input] +module syslog +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=478f4ac94a1d4cae]*/ + +#include "clinic/syslogmodule.c.h" + +/* only one instance, only one syslog, so globals should be ok, + * these fields are writable from the main interpreter only. */ +static PyObject *S_ident_o = NULL; // identifier, held by openlog() static char S_log_open = 0; +static inline int +is_main_interpreter(void) +{ + return (PyInterpreterState_Get() == PyInterpreterState_Main()); +} static PyObject * syslog_get_argv(void) @@ -87,6 +100,10 @@ syslog_get_argv(void) } scriptobj = PyList_GetItem(argv, 0); + if (scriptobj == NULL) { + PyErr_Clear(); + return NULL; + } if (!PyUnicode_Check(scriptobj)) { return(NULL); } @@ -96,112 +113,147 @@ syslog_get_argv(void) } slash = PyUnicode_FindChar(scriptobj, SEP, 0, scriptlen, -1); - if (slash == -2) + if (slash == -2) { + PyErr_Clear(); return NULL; + } if (slash != -1) { return PyUnicode_Substring(scriptobj, slash + 1, scriptlen); } else { Py_INCREF(scriptobj); return(scriptobj); } - - return(NULL); } +/*[clinic input] +syslog.openlog + + ident: unicode = NULL + logoption as logopt: long = 0 + facility: long(c_default="LOG_USER") = LOG_USER + +Set logging options of subsequent syslog() calls. +[clinic start generated code]*/ + static PyObject * -syslog_openlog(PyObject * self, PyObject * args, PyObject *kwds) +syslog_openlog_impl(PyObject *module, PyObject *ident, long logopt, + long facility) +/*[clinic end generated code: output=5476c12829b6eb75 input=8a987a96a586eee7]*/ { - long logopt = 0; - long facility = LOG_USER; - PyObject *new_S_ident_o = NULL; - static char *keywords[] = {"ident", "logoption", "facility", 0}; - const char *ident = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "|Ull:openlog", keywords, &new_S_ident_o, &logopt, &facility)) + // Since the sys.openlog changes the process level state of syslog library, + // this operation is only allowed for the main interpreter. + if (!is_main_interpreter()) { + PyErr_SetString(PyExc_RuntimeError, "subinterpreter can't use syslog.openlog()"); return NULL; - - if (new_S_ident_o) { - Py_INCREF(new_S_ident_o); } - /* get sys.argv[0] or NULL if we can't for some reason */ - if (!new_S_ident_o) { - new_S_ident_o = syslog_get_argv(); + const char *ident_str = NULL; + + if (ident) { + Py_INCREF(ident); + } + else { + /* get sys.argv[0] or NULL if we can't for some reason */ + ident = syslog_get_argv(); } - Py_XDECREF(S_ident_o); - S_ident_o = new_S_ident_o; - - /* At this point, S_ident_o should be INCREF()ed. openlog(3) does not - * make a copy, and syslog(3) later uses it. We can't garbagecollect it + /* At this point, ident should be INCREF()ed. openlog(3) does not + * make a copy, and syslog(3) later uses it. We can't garbagecollect it. * If NULL, just let openlog figure it out (probably using C argv[0]). */ - if (S_ident_o) { - ident = PyUnicode_AsUTF8(S_ident_o); - if (ident == NULL) + if (ident) { + ident_str = PyUnicode_AsUTF8(ident); + if (ident_str == NULL) { + Py_DECREF(ident); return NULL; + } } - - if (PySys_Audit("syslog.openlog", "sll", ident, logopt, facility) < 0) { + if (PySys_Audit("syslog.openlog", "Oll", ident ? ident : Py_None, logopt, facility) < 0) { + Py_DECREF(ident); return NULL; } - openlog(ident, logopt, facility); + openlog(ident_str, logopt, facility); S_log_open = 1; + Py_XSETREF(S_ident_o, ident); Py_RETURN_NONE; } + +/*[clinic input] +syslog.syslog + + [ + priority: int(c_default="LOG_INFO") = LOG_INFO + ] + + message: str + + / + +Send the string message to the system logger. +[clinic start generated code]*/ + static PyObject * -syslog_syslog(PyObject * self, PyObject * args) +syslog_syslog_impl(PyObject *module, int group_left_1, int priority, + const char *message) +/*[clinic end generated code: output=c3dbc73445a0e078 input=ac83d92b12ea3d4e]*/ { - PyObject *message_object; - const char *message; - int priority = LOG_INFO; - - if (!PyArg_ParseTuple(args, "iU;[priority,] message string", - &priority, &message_object)) { - PyErr_Clear(); - if (!PyArg_ParseTuple(args, "U;[priority,] message string", - &message_object)) - return NULL; - } - - message = PyUnicode_AsUTF8(message_object); - if (message == NULL) - return NULL; - if (PySys_Audit("syslog.syslog", "is", priority, message) < 0) { return NULL; } /* if log is not opened, open it now */ if (!S_log_open) { - PyObject *openargs; - - /* Continue even if PyTuple_New fails, because openlog(3) is optional. - * So, we can still do logging in the unlikely event things are so hosed - * that we can't do this tuple. - */ - if ((openargs = PyTuple_New(0))) { - PyObject *openlog_ret = syslog_openlog(self, openargs, NULL); - Py_XDECREF(openlog_ret); - Py_DECREF(openargs); + if (!is_main_interpreter()) { + PyErr_SetString(PyExc_RuntimeError, "subinterpreter can't use syslog.syslog() " + "until the syslog is opened by the main interpreter"); + return NULL; } + PyObject *openlog_ret = syslog_openlog_impl(module, NULL, 0, LOG_USER); + if (openlog_ret == NULL) { + return NULL; + } + Py_DECREF(openlog_ret); } + /* Incref ident, because it can be decrefed if syslog.openlog() is + * called when the GIL is released. + */ + PyObject *ident = Py_XNewRef(S_ident_o); +#ifdef __APPLE__ + // gh-98178: On macOS, libc syslog() is not thread-safe + syslog(priority, "%s", message); +#else Py_BEGIN_ALLOW_THREADS; syslog(priority, "%s", message); Py_END_ALLOW_THREADS; +#endif + Py_XDECREF(ident); Py_RETURN_NONE; } + +/*[clinic input] +syslog.closelog + +Reset the syslog module values and call the system library closelog(). +[clinic start generated code]*/ + static PyObject * -syslog_closelog(PyObject *self, PyObject *unused) +syslog_closelog_impl(PyObject *module) +/*[clinic end generated code: output=97890a80a24b1b84 input=fb77a54d447acf07]*/ { + // Since the sys.closelog changes the process level state of syslog library, + // this operation is only allowed for the main interpreter. + if (!is_main_interpreter()) { + PyErr_SetString(PyExc_RuntimeError, "sunbinterpreter can't use syslog.closelog()"); + return NULL; + } + if (PySys_Audit("syslog.closelog", NULL) < 0) { return NULL; } @@ -213,51 +265,67 @@ syslog_closelog(PyObject *self, PyObject *unused) Py_RETURN_NONE; } -static PyObject * -syslog_setlogmask(PyObject *self, PyObject *args) -{ - long maskpri, omaskpri; +/*[clinic input] +syslog.setlogmask -> long - if (!PyArg_ParseTuple(args, "l;mask for priority", &maskpri)) - return NULL; - if (PySys_Audit("syslog.setlogmask", "(O)", args ? args : Py_None) < 0) { - return NULL; + maskpri: long + / + +Set the priority mask to maskpri and return the previous mask value. +[clinic start generated code]*/ + +static long +syslog_setlogmask_impl(PyObject *module, long maskpri) +/*[clinic end generated code: output=d6ed163917b434bf input=adff2c2b76c7629c]*/ +{ + if (PySys_Audit("syslog.setlogmask", "l", maskpri) < 0) { + return -1; } - omaskpri = setlogmask(maskpri); - return PyLong_FromLong(omaskpri); + + return setlogmask(maskpri); } -static PyObject * -syslog_log_mask(PyObject *self, PyObject *args) +/*[clinic input] +syslog.LOG_MASK -> long + + pri: long + / + +Calculates the mask for the individual priority pri. +[clinic start generated code]*/ + +static long +syslog_LOG_MASK_impl(PyObject *module, long pri) +/*[clinic end generated code: output=c4a5bbfcc74c7c94 input=534829cb7fb5f7d2]*/ { - long mask; - long pri; - if (!PyArg_ParseTuple(args, "l:LOG_MASK", &pri)) - return NULL; - mask = LOG_MASK(pri); - return PyLong_FromLong(mask); + return LOG_MASK(pri); } -static PyObject * -syslog_log_upto(PyObject *self, PyObject *args) +/*[clinic input] +syslog.LOG_UPTO -> long + + pri: long + / + +Calculates the mask for all priorities up to and including pri. +[clinic start generated code]*/ + +static long +syslog_LOG_UPTO_impl(PyObject *module, long pri) +/*[clinic end generated code: output=9eab083c90601d7e input=5e906d6c406b7458]*/ { - long mask; - long pri; - if (!PyArg_ParseTuple(args, "l:LOG_UPTO", &pri)) - return NULL; - mask = LOG_UPTO(pri); - return PyLong_FromLong(mask); + return LOG_UPTO(pri); } /* List of functions defined in the module */ static PyMethodDef syslog_methods[] = { - {"openlog", (PyCFunction)(void(*)(void)) syslog_openlog, METH_VARARGS | METH_KEYWORDS}, - {"closelog", syslog_closelog, METH_NOARGS}, - {"syslog", syslog_syslog, METH_VARARGS}, - {"setlogmask", syslog_setlogmask, METH_VARARGS}, - {"LOG_MASK", syslog_log_mask, METH_VARARGS}, - {"LOG_UPTO", syslog_log_upto, METH_VARARGS}, + SYSLOG_OPENLOG_METHODDEF + SYSLOG_CLOSELOG_METHODDEF + SYSLOG_SYSLOG_METHODDEF + SYSLOG_SETLOGMASK_METHODDEF + SYSLOG_LOG_MASK_METHODDEF + SYSLOG_LOG_UPTO_METHODDEF {NULL, NULL, 0} }; @@ -355,4 +423,4 @@ PyMODINIT_FUNC PyInit_syslog(void) { return PyModuleDef_Init(&syslogmodule); -} \ No newline at end of file +} diff --git a/Modules/termios.c b/Modules/termios.c index 354e5ca18d0..fcc8f042679 100644 --- a/Modules/termios.c +++ b/Modules/termios.c @@ -82,7 +82,12 @@ termios_tcgetattr_impl(PyObject *module, int fd) { termiosmodulestate *state = PyModule_GetState(module); struct termios mode; - if (tcgetattr(fd, &mode) == -1) { + int r; + + Py_BEGIN_ALLOW_THREADS + r = tcgetattr(fd, &mode); + Py_END_ALLOW_THREADS + if (r == -1) { return PyErr_SetFromErrno(state->TermiosError); } @@ -169,7 +174,12 @@ termios_tcsetattr_impl(PyObject *module, int fd, int when, PyObject *term) /* Get the old mode, in case there are any hidden fields... */ termiosmodulestate *state = PyModule_GetState(module); struct termios mode; - if (tcgetattr(fd, &mode) == -1) { + int r; + + Py_BEGIN_ALLOW_THREADS + r = tcgetattr(fd, &mode); + Py_END_ALLOW_THREADS + if (r == -1) { return PyErr_SetFromErrno(state->TermiosError); } @@ -211,7 +221,12 @@ termios_tcsetattr_impl(PyObject *module, int fd, int when, PyObject *term) return PyErr_SetFromErrno(state->TermiosError); if (cfsetospeed(&mode, (speed_t) ospeed) == -1) return PyErr_SetFromErrno(state->TermiosError); - if (tcsetattr(fd, when, &mode) == -1) + + Py_BEGIN_ALLOW_THREADS + r = tcsetattr(fd, when, &mode); + Py_END_ALLOW_THREADS + + if (r == -1) return PyErr_SetFromErrno(state->TermiosError); Py_RETURN_NONE; @@ -235,7 +250,13 @@ termios_tcsendbreak_impl(PyObject *module, int fd, int duration) /*[clinic end generated code: output=5945f589b5d3ac66 input=dc2f32417691f8ed]*/ { termiosmodulestate *state = PyModule_GetState(module); - if (tcsendbreak(fd, duration) == -1) { + int r; + + Py_BEGIN_ALLOW_THREADS + r = tcsendbreak(fd, duration); + Py_END_ALLOW_THREADS + + if (r == -1) { return PyErr_SetFromErrno(state->TermiosError); } @@ -256,7 +277,13 @@ termios_tcdrain_impl(PyObject *module, int fd) /*[clinic end generated code: output=5fd86944c6255955 input=c99241b140b32447]*/ { termiosmodulestate *state = PyModule_GetState(module); - if (tcdrain(fd) == -1) { + int r; + + Py_BEGIN_ALLOW_THREADS + r = tcdrain(fd); + Py_END_ALLOW_THREADS + + if (r == -1) { return PyErr_SetFromErrno(state->TermiosError); } @@ -282,7 +309,13 @@ termios_tcflush_impl(PyObject *module, int fd, int queue) /*[clinic end generated code: output=2424f80312ec2f21 input=0f7d08122ddc07b5]*/ { termiosmodulestate *state = PyModule_GetState(module); - if (tcflush(fd, queue) == -1) { + int r; + + Py_BEGIN_ALLOW_THREADS + r = tcflush(fd, queue); + Py_END_ALLOW_THREADS + + if (r == -1) { return PyErr_SetFromErrno(state->TermiosError); } @@ -308,7 +341,13 @@ termios_tcflow_impl(PyObject *module, int fd, int action) /*[clinic end generated code: output=afd10928e6ea66eb input=c6aff0640b6efd9c]*/ { termiosmodulestate *state = PyModule_GetState(module); - if (tcflow(fd, action) == -1) { + int r; + + Py_BEGIN_ALLOW_THREADS + r = tcflow(fd, action); + Py_END_ALLOW_THREADS + + if (r == -1) { return PyErr_SetFromErrno(state->TermiosError); } @@ -333,7 +372,13 @@ termios_tcgetwinsize_impl(PyObject *module, int fd) #if defined(TIOCGWINSZ) termiosmodulestate *state = PyModule_GetState(module); struct winsize w; - if (ioctl(fd, TIOCGWINSZ, &w) == -1) { + int r; + + Py_BEGIN_ALLOW_THREADS + r = ioctl(fd, TIOCGWINSZ, &w); + Py_END_ALLOW_THREADS + + if (r == -1) { return PyErr_SetFromErrno(state->TermiosError); } @@ -352,7 +397,12 @@ termios_tcgetwinsize_impl(PyObject *module, int fd) #elif defined(TIOCGSIZE) termiosmodulestate *state = PyModule_GetState(module); struct ttysize s; - if (ioctl(fd, TIOCGSIZE, &s) == -1) { + int r; + + Py_BEGIN_ALLOW_THREADS + r = ioctl(fd, TIOCGSIZE, &s); + Py_END_ALLOW_THREADS + if (r == -1) { return PyErr_SetFromErrno(state->TermiosError); } @@ -433,15 +483,25 @@ termios_tcsetwinsize_impl(PyObject *module, int fd, PyObject *winsz) return NULL; } - if (ioctl(fd, TIOCSWINSZ, &w) == -1) { + int r; + Py_BEGIN_ALLOW_THREADS + r = ioctl(fd, TIOCSWINSZ, &w); + Py_END_ALLOW_THREADS + + if (r == -1) { return PyErr_SetFromErrno(state->TermiosError); } Py_RETURN_NONE; #elif defined(TIOCGSIZE) && defined(TIOCSSIZE) struct ttysize s; + int r; /* Get the old ttysize because it might have more fields. */ - if (ioctl(fd, TIOCGSIZE, &s) == -1) { + Py_BEGIN_ALLOW_THREADS + r = ioctl(fd, TIOCGSIZE, &s); + Py_END_ALLOW_THREADS + + if (r == -1) { return PyErr_SetFromErrno(state->TermiosError); } @@ -453,7 +513,11 @@ termios_tcsetwinsize_impl(PyObject *module, int fd, PyObject *winsz) return NULL; } - if (ioctl(fd, TIOCSSIZE, &s) == -1) { + Py_BEGIN_ALLOW_THREADS + r = ioctl(fd, TIOCSSIZE, &s); + Py_END_ALLOW_THREADS + + if (r == -1) { return PyErr_SetFromErrno(state->TermiosError); } diff --git a/Modules/timemodule.c b/Modules/timemodule.c index bb713908eb1..c2bacaae0c0 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -2,7 +2,9 @@ #include "Python.h" #include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH +#include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_namespace.h" // _PyNamespace_New() +#include "pycore_runtime.h" // _Py_ID() #include @@ -60,10 +62,73 @@ #define SEC_TO_NS (1000 * 1000 * 1000) +#if defined(HAVE_TIMES) || defined(HAVE_CLOCK) +static int +check_ticks_per_second(long tps, const char *context) +{ + /* Effectively, check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second) + cannot overflow. */ + if (tps >= 0 && (_PyTime_t)tps > _PyTime_MAX / SEC_TO_NS) { + PyErr_Format(PyExc_OverflowError, "%s is too large", context); + return -1; + } + return 0; +} +#endif /* HAVE_TIMES || HAVE_CLOCK */ + +#ifdef HAVE_TIMES + +# define ticks_per_second _PyRuntime.time.ticks_per_second + +static void +ensure_ticks_per_second(void) +{ + if (_PyRuntime.time.ticks_per_second_initialized) { + return; + } + _PyRuntime.time.ticks_per_second_initialized = 1; +# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) + ticks_per_second = sysconf(_SC_CLK_TCK); + if (ticks_per_second < 1) { + ticks_per_second = -1; + } +# elif defined(HZ) + ticks_per_second = HZ; +# else + ticks_per_second = 60; /* magic fallback value; may be bogus */ +# endif +} + +#endif /* HAVE_TIMES */ + + +PyStatus +_PyTime_Init(void) +{ +#ifdef HAVE_TIMES + ensure_ticks_per_second(); +#endif + return PyStatus_Ok(); +} + + /* Forward declarations */ static int pysleep(_PyTime_t timeout); +typedef struct { + PyTypeObject *struct_time_type; +} time_module_state; + +static inline time_module_state* +get_time_state(PyObject *module) +{ + void *state = _PyModule_GetState(module); + assert(state != NULL); + return (time_module_state *)state; +} + + static PyObject* _PyFloat_FromPyTime(_PyTime_t t) { @@ -125,18 +190,8 @@ Return the current time in nanoseconds since the Epoch."); static int _PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) { - static int initialized = 0; - - if (!initialized) { - initialized = 1; - - /* Make sure that _PyTime_MulDiv(ticks, SEC_TO_NS, CLOCKS_PER_SEC) - above cannot overflow */ - if ((_PyTime_t)CLOCKS_PER_SEC > _PyTime_MAX / SEC_TO_NS) { - PyErr_SetString(PyExc_OverflowError, - "CLOCKS_PER_SEC is too large"); - return -1; - } + if (check_ticks_per_second(CLOCKS_PER_SEC, "CLOCKS_PER_SEC") < 0) { + return -1; } if (info) { @@ -405,9 +460,6 @@ static PyStructSequence_Desc struct_time_type_desc = { 9, }; -static int initialized; -static PyTypeObject StructTimeType; - #if defined(MS_WINDOWS) #ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION #define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002 @@ -417,13 +469,13 @@ static DWORD timer_flags = (DWORD)-1; #endif static PyObject * -tmtotuple(struct tm *p +tmtotuple(time_module_state *state, struct tm *p #ifndef HAVE_STRUCT_TM_TM_ZONE , const char *zone, time_t gmtoff #endif ) { - PyObject *v = PyStructSequence_New(&StructTimeType); + PyObject *v = PyStructSequence_New(state->struct_time_type); if (v == NULL) return NULL; @@ -480,7 +532,7 @@ parse_time_t_args(PyObject *args, const char *format, time_t *pwhen) } static PyObject * -time_gmtime(PyObject *self, PyObject *args) +time_gmtime(PyObject *module, PyObject *args) { time_t when; struct tm buf; @@ -491,10 +543,12 @@ time_gmtime(PyObject *self, PyObject *args) errno = 0; if (_PyTime_gmtime(when, &buf) != 0) return NULL; + + time_module_state *state = get_time_state(module); #ifdef HAVE_STRUCT_TM_TM_ZONE - return tmtotuple(&buf); + return tmtotuple(state, &buf); #else - return tmtotuple(&buf, "UTC", 0); + return tmtotuple(state, &buf, "UTC", 0); #endif } @@ -522,7 +576,7 @@ If the platform supports the tm_gmtoff and tm_zone, they are available as\n\ attributes only."); static PyObject * -time_localtime(PyObject *self, PyObject *args) +time_localtime(PyObject *module, PyObject *args) { time_t when; struct tm buf; @@ -531,8 +585,10 @@ time_localtime(PyObject *self, PyObject *args) return NULL; if (_PyTime_localtime(when, &buf) != 0) return NULL; + + time_module_state *state = get_time_state(module); #ifdef HAVE_STRUCT_TM_TM_ZONE - return tmtotuple(&buf); + return tmtotuple(state, &buf); #else { struct tm local = buf; @@ -540,7 +596,7 @@ time_localtime(PyObject *self, PyObject *args) time_t gmtoff; strftime(zone, sizeof(zone), "%Z", &buf); gmtoff = timegm(&buf) - when; - return tmtotuple(&local, zone, gmtoff); + return tmtotuple(state, &local, zone, gmtoff); } #endif } @@ -560,7 +616,8 @@ When 'seconds' is not passed in, convert the current time instead."); * an exception and return 0 on error. */ static int -gettmarg(PyObject *args, struct tm *p, const char *format) +gettmarg(time_module_state *state, PyObject *args, + struct tm *p, const char *format) { int y; @@ -588,7 +645,7 @@ gettmarg(PyObject *args, struct tm *p, const char *format) p->tm_wday = (p->tm_wday + 1) % 7; p->tm_yday--; #ifdef HAVE_STRUCT_TM_TM_ZONE - if (Py_IS_TYPE(args, &StructTimeType)) { + if (Py_IS_TYPE(args, state->struct_time_type)) { PyObject *item; item = PyStructSequence_GET_ITEM(args, 9); if (item != Py_None) { @@ -729,7 +786,7 @@ the C library strftime function.\n" #endif static PyObject * -time_strftime(PyObject *self, PyObject *args) +time_strftime(PyObject *module, PyObject *args) { PyObject *tup = NULL; struct tm buf; @@ -753,12 +810,13 @@ time_strftime(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "U|O:strftime", &format_arg, &tup)) return NULL; + time_module_state *state = get_time_state(module); if (tup == NULL) { time_t tt = time(NULL); if (_PyTime_localtime(tt, &buf) != 0) return NULL; } - else if (!gettmarg(tup, &buf, + else if (!gettmarg(state, tup, &buf, "iiiiiiiii;strftime(): illegal time tuple argument") || !checktm(&buf)) { @@ -892,15 +950,9 @@ is not present, current time as returned by localtime() is used.\n\ static PyObject * time_strptime(PyObject *self, PyObject *args) { - PyObject *module, *func, *result; - _Py_IDENTIFIER(_strptime_time); + PyObject *func, *result; - module = PyImport_ImportModuleNoBlock("_strptime"); - if (!module) - return NULL; - - func = _PyObject_GetAttrId(module, &PyId__strptime_time); - Py_DECREF(module); + func = _PyImport_GetModuleAttrString("_strptime", "_strptime_time"); if (!func) { return NULL; } @@ -941,19 +993,21 @@ _asctime(struct tm *timeptr) } static PyObject * -time_asctime(PyObject *self, PyObject *args) +time_asctime(PyObject *module, PyObject *args) { PyObject *tup = NULL; struct tm buf; if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup)) return NULL; + + time_module_state *state = get_time_state(module); if (tup == NULL) { time_t tt = time(NULL); if (_PyTime_localtime(tt, &buf) != 0) return NULL; } - else if (!gettmarg(tup, &buf, + else if (!gettmarg(state, tup, &buf, "iiiiiiiii;asctime(): illegal time tuple argument") || !checktm(&buf)) { @@ -990,12 +1044,13 @@ not present, current time as returned by localtime() is used."); #ifdef HAVE_MKTIME static PyObject * -time_mktime(PyObject *self, PyObject *tm_tuple) +time_mktime(PyObject *module, PyObject *tm_tuple) { struct tm tm; time_t tt; - if (!gettmarg(tm_tuple, &tm, + time_module_state *state = get_time_state(module); + if (!gettmarg(state, tm_tuple, &tm, "iiiiiiiii;mktime(): illegal time tuple argument")) { return NULL; @@ -1075,7 +1130,7 @@ time_tzset(PyObject *self, PyObject *unused) { PyObject* m; - m = PyImport_ImportModuleNoBlock("time"); + m = PyImport_ImportModule("time"); if (m == NULL) { return NULL; } @@ -1262,7 +1317,7 @@ _PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) #endif /* getrusage(RUSAGE_SELF) */ -#if defined(HAVE_SYS_RESOURCE_H) +#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRUSAGE) struct rusage ru; if (getrusage(RUSAGE_SELF, &ru) == 0) { @@ -1293,36 +1348,10 @@ _PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) struct tms t; if (times(&t) != (clock_t)-1) { - static long ticks_per_second = -1; - - if (ticks_per_second == -1) { - long freq; -#if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) - freq = sysconf(_SC_CLK_TCK); - if (freq < 1) { - freq = -1; - } -#elif defined(HZ) - freq = HZ; -#else - freq = 60; /* magic fallback value; may be bogus */ -#endif - - if (freq != -1) { - /* check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second) - cannot overflow below */ -#if LONG_MAX > _PyTime_MAX / SEC_TO_NS - if ((_PyTime_t)freq > _PyTime_MAX / SEC_TO_NS) { - PyErr_SetString(PyExc_OverflowError, - "_SC_CLK_TCK is too large"); - return -1; - } -#endif - - ticks_per_second = freq; - } + assert(_PyRuntime.time.ticks_per_second_initialized); + if (check_ticks_per_second(ticks_per_second, "_SC_CLK_TCK") < 0) { + return -1; } - if (ticks_per_second != -1) { if (info) { info->implementation = "times()"; @@ -1459,7 +1488,9 @@ _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) return 0; } -#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID) +#elif defined(HAVE_CLOCK_GETTIME) && \ + defined(CLOCK_PROCESS_CPUTIME_ID) && \ + !defined(__EMSCRIPTEN__) && !defined(__wasi__) #define HAVE_THREAD_TIME #if defined(__APPLE__) && defined(__has_attribute) && __has_attribute(availability) @@ -1888,6 +1919,7 @@ if it is -1, mktime() should guess based on the date and time.\n"); static int time_exec(PyObject *module) { + time_module_state *state = get_time_state(module); #if defined(__APPLE__) && defined(HAVE_CLOCK_GETTIME) if (HAVE_CLOCK_GETTIME_RUNTIME) { /* pass: ^^^ cannot use '!' here */ @@ -2001,21 +2033,18 @@ time_exec(PyObject *module) #endif /* defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES) */ - if (!initialized) { - if (PyStructSequence_InitType2(&StructTimeType, - &struct_time_type_desc) < 0) { - return -1; - } - } if (PyModule_AddIntConstant(module, "_STRUCT_TM_ITEMS", 11)) { return -1; } - Py_INCREF(&StructTimeType); - if (PyModule_AddObject(module, "struct_time", (PyObject*) &StructTimeType)) { - Py_DECREF(&StructTimeType); + + // struct_time type + state->struct_time_type = PyStructSequence_NewType(&struct_time_type_desc); + if (state->struct_time_type == NULL) { + return -1; + } + if (PyModule_AddType(module, state->struct_time_type)) { return -1; } - initialized = 1; #if defined(__linux__) && !defined(__GLIBC__) struct tm tm; @@ -2044,6 +2073,32 @@ time_exec(PyObject *module) return 0; } + +static int +time_module_traverse(PyObject *module, visitproc visit, void *arg) +{ + time_module_state *state = get_time_state(module); + Py_VISIT(state->struct_time_type); + return 0; +} + + +static int +time_module_clear(PyObject *module) +{ + time_module_state *state = get_time_state(module); + Py_CLEAR(state->struct_time_type); + return 0; +} + + +static void +time_module_free(void *module) +{ + time_module_clear((PyObject *)module); +} + + static struct PyModuleDef_Slot time_slots[] = { {Py_mod_exec, time_exec}, {0, NULL} @@ -2051,14 +2106,14 @@ static struct PyModuleDef_Slot time_slots[] = { static struct PyModuleDef timemodule = { PyModuleDef_HEAD_INIT, - "time", - module_doc, - 0, - time_methods, - time_slots, - NULL, - NULL, - NULL + .m_name = "time", + .m_doc = module_doc, + .m_size = sizeof(time_module_state), + .m_methods = time_methods, + .m_slots = time_slots, + .m_traverse = time_module_traverse, + .m_clear = time_module_clear, + .m_free = time_module_free, }; PyMODINIT_FUNC diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index bdbddcf10b7..59fccd4b834 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -24,11 +24,6 @@ #include -_Py_IDENTIFIER(NFC); -_Py_IDENTIFIER(NFD); -_Py_IDENTIFIER(NFKC); -_Py_IDENTIFIER(NFKD); - /*[clinic input] module unicodedata class unicodedata.UCD 'PreviousDBVersion *' '' @@ -164,8 +159,7 @@ unicodedata_UCD_decimal_impl(PyObject *self, int chr, return NULL; } else { - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } } return PyLong_FromLong(rc); @@ -199,8 +193,7 @@ unicodedata_UCD_digit_impl(PyObject *self, int chr, PyObject *default_value) return NULL; } else { - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } } return PyLong_FromLong(rc); @@ -251,8 +244,7 @@ unicodedata_UCD_numeric_impl(PyObject *self, int chr, return NULL; } else { - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } } return PyFloat_FromDouble(rc); @@ -889,17 +881,17 @@ unicodedata_UCD_is_normalized_impl(PyObject *self, PyObject *form, PyObject *cmp; int match = 0; - if (_PyUnicode_EqualToASCIIId(form, &PyId_NFC)) { + if (PyUnicode_CompareWithASCIIString(form, "NFC") == 0) { nfc = true; } - else if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKC)) { + else if (PyUnicode_CompareWithASCIIString(form, "NFKC") == 0) { nfc = true; k = true; } - else if (_PyUnicode_EqualToASCIIId(form, &PyId_NFD)) { + else if (PyUnicode_CompareWithASCIIString(form, "NFD") == 0) { /* matches default values for `nfc` and `k` */ } - else if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKD)) { + else if (PyUnicode_CompareWithASCIIString(form, "NFKD") == 0) { k = true; } else { @@ -922,8 +914,7 @@ unicodedata_UCD_is_normalized_impl(PyObject *self, PyObject *form, result = (m == YES) ? Py_True : Py_False; } - Py_INCREF(result); - return result; + return Py_NewRef(result); } @@ -948,39 +939,34 @@ unicodedata_UCD_normalize_impl(PyObject *self, PyObject *form, if (PyUnicode_GET_LENGTH(input) == 0) { /* Special case empty input strings, since resizing them later would cause internal errors. */ - Py_INCREF(input); - return input; + return Py_NewRef(input); } - if (_PyUnicode_EqualToASCIIId(form, &PyId_NFC)) { + if (PyUnicode_CompareWithASCIIString(form, "NFC") == 0) { if (is_normalized_quickcheck(self, input, true, false, true) == YES) { - Py_INCREF(input); - return input; + return Py_NewRef(input); } return nfc_nfkc(self, input, 0); } - if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKC)) { + if (PyUnicode_CompareWithASCIIString(form, "NFKC") == 0) { if (is_normalized_quickcheck(self, input, true, true, true) == YES) { - Py_INCREF(input); - return input; + return Py_NewRef(input); } return nfc_nfkc(self, input, 1); } - if (_PyUnicode_EqualToASCIIId(form, &PyId_NFD)) { + if (PyUnicode_CompareWithASCIIString(form, "NFD") == 0) { if (is_normalized_quickcheck(self, input, false, false, true) == YES) { - Py_INCREF(input); - return input; + return Py_NewRef(input); } return nfd_nfkd(self, input, 0); } - if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKD)) { + if (PyUnicode_CompareWithASCIIString(form, "NFKD") == 0) { if (is_normalized_quickcheck(self, input, false, true, true) == YES) { - Py_INCREF(input); - return input; + return Py_NewRef(input); } return nfd_nfkd(self, input, 1); } @@ -1051,11 +1037,12 @@ is_unified_ideograph(Py_UCS4 code) (0x3400 <= code && code <= 0x4DBF) || /* CJK Ideograph Extension A */ (0x4E00 <= code && code <= 0x9FFF) || /* CJK Ideograph */ (0x20000 <= code && code <= 0x2A6DF) || /* CJK Ideograph Extension B */ - (0x2A700 <= code && code <= 0x2B738) || /* CJK Ideograph Extension C */ + (0x2A700 <= code && code <= 0x2B739) || /* CJK Ideograph Extension C */ (0x2B740 <= code && code <= 0x2B81D) || /* CJK Ideograph Extension D */ (0x2B820 <= code && code <= 0x2CEA1) || /* CJK Ideograph Extension E */ (0x2CEB0 <= code && code <= 0x2EBE0) || /* CJK Ideograph Extension F */ - (0x30000 <= code && code <= 0x3134A); /* CJK Ideograph Extension G */ + (0x30000 <= code && code <= 0x3134A) || /* CJK Ideograph Extension G */ + (0x31350 <= code && code <= 0x323AF); /* CJK Ideograph Extension H */ } /* macros used to determine if the given code point is in the PUA range that @@ -1374,8 +1361,7 @@ unicodedata_UCD_name_impl(PyObject *self, int chr, PyObject *default_value) return NULL; } else { - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } } diff --git a/Modules/unicodedata_db.h b/Modules/unicodedata_db.h index f56fa035b68..4c4b2f589c5 100644 --- a/Modules/unicodedata_db.h +++ b/Modules/unicodedata_db.h @@ -1,13 +1,13 @@ /* this file was generated by Tools/unicode/makeunicodedata.py 3.3 */ -#define UNIDATA_VERSION "14.0.0" +#define UNIDATA_VERSION "15.0.0" /* a list of unique database records */ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {0, 0, 0, 0, 0, 0}, - {13, 0, 15, 0, 5, 0}, - {13, 0, 17, 0, 5, 0}, - {13, 0, 16, 0, 5, 0}, - {13, 0, 18, 0, 5, 0}, + {13, 0, 15, 0, 0, 0}, + {13, 0, 17, 0, 0, 0}, + {13, 0, 16, 0, 0, 0}, + {13, 0, 18, 0, 0, 0}, {10, 0, 18, 0, 3, 0}, {26, 0, 19, 0, 3, 0}, {26, 0, 11, 0, 3, 0}, @@ -24,44 +24,44 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {29, 0, 19, 0, 3, 0}, {20, 0, 19, 0, 3, 0}, {2, 0, 1, 0, 3, 0}, - {10, 0, 13, 0, 5, 136}, + {10, 0, 13, 0, 0, 136}, {26, 0, 19, 0, 4, 0}, {28, 0, 11, 0, 4, 0}, {30, 0, 19, 0, 3, 0}, {29, 0, 19, 0, 4, 136}, - {30, 0, 19, 0, 5, 0}, + {30, 0, 19, 0, 0, 0}, {19, 0, 1, 0, 4, 136}, - {24, 0, 19, 1, 5, 0}, + {24, 0, 19, 1, 0, 0}, {14, 0, 15, 0, 4, 0}, {30, 0, 19, 0, 4, 0}, {29, 0, 19, 0, 3, 136}, {30, 0, 11, 0, 4, 0}, {27, 0, 11, 0, 4, 0}, {9, 0, 9, 0, 4, 136}, - {2, 0, 1, 0, 5, 136}, - {25, 0, 19, 1, 5, 0}, + {2, 0, 1, 0, 0, 136}, + {25, 0, 19, 1, 0, 0}, {9, 0, 19, 0, 4, 136}, - {1, 0, 1, 0, 5, 10}, + {1, 0, 1, 0, 0, 10}, {1, 0, 1, 0, 4, 0}, {27, 0, 19, 0, 4, 0}, {2, 0, 1, 0, 4, 0}, {2, 0, 1, 0, 4, 10}, - {2, 0, 1, 0, 5, 10}, - {1, 0, 1, 0, 5, 0}, + {2, 0, 1, 0, 0, 10}, + {1, 0, 1, 0, 0, 0}, {1, 0, 1, 0, 4, 136}, {2, 0, 1, 0, 4, 136}, - {2, 0, 1, 0, 5, 0}, - {19, 0, 1, 0, 5, 0}, - {1, 0, 1, 0, 5, 136}, - {3, 0, 1, 0, 5, 136}, - {18, 0, 1, 0, 5, 136}, - {18, 0, 19, 0, 5, 0}, - {18, 0, 1, 0, 5, 0}, - {29, 0, 19, 0, 5, 0}, + {2, 0, 1, 0, 0, 0}, + {19, 0, 1, 0, 0, 0}, + {1, 0, 1, 0, 0, 136}, + {3, 0, 1, 0, 0, 136}, + {18, 0, 1, 0, 0, 136}, + {18, 0, 19, 0, 0, 0}, + {18, 0, 1, 0, 0, 0}, + {29, 0, 19, 0, 0, 0}, {29, 0, 19, 0, 4, 0}, {18, 0, 19, 0, 4, 0}, {18, 0, 1, 0, 4, 0}, - {29, 0, 19, 0, 5, 136}, + {29, 0, 19, 0, 0, 136}, {4, 230, 14, 0, 4, 80}, {4, 230, 14, 0, 4, 0}, {4, 232, 14, 0, 4, 0}, @@ -77,173 +77,173 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {4, 0, 14, 0, 4, 0}, {4, 233, 14, 0, 4, 0}, {4, 234, 14, 0, 4, 0}, - {18, 0, 19, 0, 5, 170}, - {26, 0, 19, 0, 5, 170}, - {29, 0, 19, 0, 5, 138}, - {1, 0, 1, 0, 5, 138}, - {27, 0, 19, 0, 5, 0}, + {18, 0, 19, 0, 0, 170}, + {26, 0, 19, 0, 0, 170}, + {29, 0, 19, 0, 0, 138}, + {1, 0, 1, 0, 0, 138}, + {27, 0, 19, 0, 0, 0}, {1, 0, 1, 0, 4, 10}, - {30, 0, 1, 0, 5, 0}, - {4, 230, 14, 0, 5, 0}, - {6, 0, 14, 0, 5, 0}, - {26, 0, 1, 0, 5, 0}, - {21, 0, 19, 0, 5, 0}, - {28, 0, 11, 0, 5, 0}, - {4, 220, 14, 0, 5, 0}, - {4, 222, 14, 0, 5, 0}, - {4, 228, 14, 0, 5, 0}, - {4, 10, 14, 0, 5, 0}, - {4, 11, 14, 0, 5, 0}, - {4, 12, 14, 0, 5, 0}, - {4, 13, 14, 0, 5, 0}, - {4, 14, 14, 0, 5, 0}, - {4, 15, 14, 0, 5, 0}, - {4, 16, 14, 0, 5, 0}, - {4, 17, 14, 0, 5, 0}, - {4, 18, 14, 0, 5, 0}, - {4, 19, 14, 0, 5, 0}, - {4, 20, 14, 0, 5, 0}, - {4, 21, 14, 0, 5, 0}, - {4, 22, 14, 0, 5, 0}, - {21, 0, 4, 0, 5, 0}, - {4, 23, 14, 0, 5, 0}, - {26, 0, 4, 0, 5, 0}, - {4, 24, 14, 0, 5, 0}, - {4, 25, 14, 0, 5, 0}, - {19, 0, 4, 0, 5, 0}, - {14, 0, 12, 0, 5, 0}, - {27, 0, 5, 0, 5, 0}, - {26, 0, 11, 0, 5, 0}, - {28, 0, 5, 0, 5, 0}, - {26, 0, 13, 0, 5, 0}, - {26, 0, 5, 0, 5, 0}, - {4, 30, 14, 0, 5, 0}, - {4, 31, 14, 0, 5, 0}, - {4, 32, 14, 0, 5, 0}, - {14, 0, 5, 0, 5, 0}, - {19, 0, 5, 0, 5, 0}, - {19, 0, 5, 0, 5, 10}, - {18, 0, 5, 0, 5, 0}, - {4, 27, 14, 0, 5, 0}, - {4, 28, 14, 0, 5, 0}, - {4, 29, 14, 0, 5, 0}, - {4, 33, 14, 0, 5, 0}, - {4, 34, 14, 0, 5, 0}, - {4, 230, 14, 0, 5, 80}, - {4, 220, 14, 0, 5, 80}, - {7, 0, 12, 0, 5, 0}, - {26, 0, 12, 0, 5, 0}, - {4, 35, 14, 0, 5, 0}, - {19, 0, 5, 0, 5, 136}, - {7, 0, 9, 0, 5, 0}, - {30, 0, 5, 0, 5, 0}, - {4, 36, 14, 0, 5, 0}, - {4, 0, 14, 0, 5, 0}, - {7, 0, 4, 0, 5, 0}, - {18, 0, 4, 0, 5, 0}, - {26, 0, 19, 0, 5, 0}, - {28, 0, 4, 0, 5, 0}, - {29, 0, 5, 0, 5, 0}, - {5, 0, 1, 0, 5, 0}, - {19, 0, 1, 0, 5, 10}, - {4, 7, 14, 0, 5, 80}, - {4, 9, 14, 0, 5, 0}, - {19, 0, 1, 0, 5, 170}, - {7, 0, 1, 0, 5, 0}, - {4, 7, 14, 0, 5, 0}, - {5, 0, 1, 0, 5, 80}, - {5, 0, 1, 0, 5, 10}, - {9, 0, 1, 0, 5, 0}, - {4, 0, 14, 0, 5, 80}, - {4, 0, 14, 0, 5, 10}, - {4, 84, 14, 0, 5, 0}, - {4, 91, 14, 0, 5, 80}, - {9, 0, 19, 0, 5, 0}, - {4, 0, 1, 0, 5, 0}, - {4, 9, 14, 0, 5, 80}, - {19, 0, 1, 0, 5, 136}, - {4, 103, 14, 0, 5, 0}, - {4, 107, 14, 0, 5, 0}, - {4, 118, 14, 0, 5, 0}, - {4, 122, 14, 0, 5, 0}, - {26, 0, 1, 0, 5, 136}, - {4, 216, 14, 0, 5, 0}, - {22, 0, 19, 1, 5, 0}, - {23, 0, 19, 1, 5, 0}, - {4, 129, 14, 0, 5, 0}, - {4, 130, 14, 0, 5, 0}, - {4, 0, 14, 0, 5, 170}, - {4, 132, 14, 0, 5, 0}, - {4, 0, 14, 0, 5, 136}, + {30, 0, 1, 0, 0, 0}, + {4, 230, 14, 0, 0, 0}, + {6, 0, 14, 0, 0, 0}, + {26, 0, 1, 0, 0, 0}, + {21, 0, 19, 0, 0, 0}, + {28, 0, 11, 0, 0, 0}, + {4, 220, 14, 0, 0, 0}, + {4, 222, 14, 0, 0, 0}, + {4, 228, 14, 0, 0, 0}, + {4, 10, 14, 0, 0, 0}, + {4, 11, 14, 0, 0, 0}, + {4, 12, 14, 0, 0, 0}, + {4, 13, 14, 0, 0, 0}, + {4, 14, 14, 0, 0, 0}, + {4, 15, 14, 0, 0, 0}, + {4, 16, 14, 0, 0, 0}, + {4, 17, 14, 0, 0, 0}, + {4, 18, 14, 0, 0, 0}, + {4, 19, 14, 0, 0, 0}, + {4, 20, 14, 0, 0, 0}, + {4, 21, 14, 0, 0, 0}, + {4, 22, 14, 0, 0, 0}, + {21, 0, 4, 0, 0, 0}, + {4, 23, 14, 0, 0, 0}, + {26, 0, 4, 0, 0, 0}, + {4, 24, 14, 0, 0, 0}, + {4, 25, 14, 0, 0, 0}, + {19, 0, 4, 0, 0, 0}, + {14, 0, 12, 0, 0, 0}, + {27, 0, 5, 0, 0, 0}, + {26, 0, 11, 0, 0, 0}, + {28, 0, 5, 0, 0, 0}, + {26, 0, 13, 0, 0, 0}, + {26, 0, 5, 0, 0, 0}, + {4, 30, 14, 0, 0, 0}, + {4, 31, 14, 0, 0, 0}, + {4, 32, 14, 0, 0, 0}, + {14, 0, 5, 0, 0, 0}, + {19, 0, 5, 0, 0, 0}, + {19, 0, 5, 0, 0, 10}, + {18, 0, 5, 0, 0, 0}, + {4, 27, 14, 0, 0, 0}, + {4, 28, 14, 0, 0, 0}, + {4, 29, 14, 0, 0, 0}, + {4, 33, 14, 0, 0, 0}, + {4, 34, 14, 0, 0, 0}, + {4, 230, 14, 0, 0, 80}, + {4, 220, 14, 0, 0, 80}, + {7, 0, 12, 0, 0, 0}, + {26, 0, 12, 0, 0, 0}, + {4, 35, 14, 0, 0, 0}, + {19, 0, 5, 0, 0, 136}, + {7, 0, 9, 0, 0, 0}, + {30, 0, 5, 0, 0, 0}, + {4, 36, 14, 0, 0, 0}, + {4, 0, 14, 0, 0, 0}, + {7, 0, 4, 0, 0, 0}, + {18, 0, 4, 0, 0, 0}, + {26, 0, 19, 0, 0, 0}, + {28, 0, 4, 0, 0, 0}, + {29, 0, 5, 0, 0, 0}, + {5, 0, 1, 0, 0, 0}, + {19, 0, 1, 0, 0, 10}, + {4, 7, 14, 0, 0, 80}, + {4, 9, 14, 0, 0, 0}, + {19, 0, 1, 0, 0, 170}, + {7, 0, 1, 0, 0, 0}, + {4, 7, 14, 0, 0, 0}, + {5, 0, 1, 0, 0, 80}, + {5, 0, 1, 0, 0, 10}, + {9, 0, 1, 0, 0, 0}, + {4, 0, 14, 0, 0, 80}, + {4, 0, 14, 0, 0, 10}, + {4, 84, 14, 0, 0, 0}, + {4, 91, 14, 0, 0, 80}, + {9, 0, 19, 0, 0, 0}, + {4, 0, 1, 0, 0, 0}, + {4, 9, 14, 0, 0, 80}, + {19, 0, 1, 0, 0, 136}, + {4, 103, 14, 0, 0, 0}, + {4, 107, 14, 0, 0, 0}, + {4, 118, 14, 0, 0, 0}, + {4, 122, 14, 0, 0, 0}, + {26, 0, 1, 0, 0, 136}, + {4, 216, 14, 0, 0, 0}, + {22, 0, 19, 1, 0, 0}, + {23, 0, 19, 1, 0, 0}, + {4, 129, 14, 0, 0, 0}, + {4, 130, 14, 0, 0, 0}, + {4, 0, 14, 0, 0, 170}, + {4, 132, 14, 0, 0, 0}, + {4, 0, 14, 0, 0, 136}, {19, 0, 1, 0, 2, 0}, - {19, 0, 1, 0, 5, 80}, - {10, 0, 18, 0, 5, 0}, - {8, 0, 1, 0, 5, 0}, - {5, 9, 1, 0, 5, 0}, - {14, 0, 15, 0, 5, 0}, - {4, 1, 14, 0, 5, 0}, - {4, 234, 14, 0, 5, 0}, - {4, 214, 14, 0, 5, 0}, - {4, 202, 14, 0, 5, 0}, - {4, 232, 14, 0, 5, 0}, - {4, 218, 14, 0, 5, 0}, - {4, 233, 14, 0, 5, 0}, - {2, 0, 1, 0, 5, 138}, - {2, 0, 1, 0, 5, 170}, - {3, 0, 1, 0, 5, 10}, - {1, 0, 1, 0, 5, 170}, - {29, 0, 19, 0, 5, 170}, - {10, 0, 18, 0, 5, 170}, - {10, 0, 18, 0, 5, 136}, - {14, 0, 1, 0, 5, 0}, - {14, 0, 4, 0, 5, 0}, + {19, 0, 1, 0, 0, 80}, + {10, 0, 18, 0, 0, 0}, + {8, 0, 1, 0, 0, 0}, + {5, 9, 1, 0, 0, 0}, + {14, 0, 15, 0, 0, 0}, + {4, 1, 14, 0, 0, 0}, + {4, 234, 14, 0, 0, 0}, + {4, 214, 14, 0, 0, 0}, + {4, 202, 14, 0, 0, 0}, + {4, 232, 14, 0, 0, 0}, + {4, 218, 14, 0, 0, 0}, + {4, 233, 14, 0, 0, 0}, + {2, 0, 1, 0, 0, 138}, + {2, 0, 1, 0, 0, 170}, + {3, 0, 1, 0, 0, 10}, + {1, 0, 1, 0, 0, 170}, + {29, 0, 19, 0, 0, 170}, + {10, 0, 18, 0, 0, 170}, + {10, 0, 18, 0, 0, 136}, + {14, 0, 1, 0, 0, 0}, + {14, 0, 4, 0, 0, 0}, {21, 0, 19, 0, 4, 0}, - {21, 0, 19, 0, 5, 136}, - {26, 0, 19, 0, 5, 136}, + {21, 0, 19, 0, 0, 136}, + {26, 0, 19, 0, 0, 136}, {24, 0, 19, 0, 4, 0}, {25, 0, 19, 0, 4, 0}, - {22, 0, 19, 0, 5, 0}, - {24, 0, 19, 0, 5, 0}, + {22, 0, 19, 0, 0, 0}, + {24, 0, 19, 0, 0, 0}, {26, 0, 19, 0, 4, 136}, - {11, 0, 18, 0, 5, 0}, - {12, 0, 16, 0, 5, 0}, - {14, 0, 2, 0, 5, 0}, - {14, 0, 6, 0, 5, 0}, - {14, 0, 8, 0, 5, 0}, - {14, 0, 3, 0, 5, 0}, - {14, 0, 7, 0, 5, 0}, + {11, 0, 18, 0, 0, 0}, + {12, 0, 16, 0, 0, 0}, + {14, 0, 2, 0, 0, 0}, + {14, 0, 6, 0, 0, 0}, + {14, 0, 8, 0, 0, 0}, + {14, 0, 3, 0, 0, 0}, + {14, 0, 7, 0, 0, 0}, {26, 0, 11, 0, 4, 0}, {26, 0, 11, 0, 4, 136}, - {26, 0, 11, 0, 5, 136}, - {20, 0, 19, 0, 5, 0}, - {27, 0, 13, 0, 5, 0}, - {14, 0, 20, 0, 5, 0}, - {14, 0, 21, 0, 5, 0}, - {14, 0, 22, 0, 5, 0}, - {14, 0, 23, 0, 5, 0}, - {9, 0, 9, 0, 5, 136}, - {27, 0, 10, 0, 5, 136}, - {27, 0, 19, 0, 5, 136}, - {22, 0, 19, 1, 5, 136}, - {23, 0, 19, 1, 5, 136}, + {26, 0, 11, 0, 0, 136}, + {20, 0, 19, 0, 0, 0}, + {27, 0, 13, 0, 0, 0}, + {14, 0, 20, 0, 0, 0}, + {14, 0, 21, 0, 0, 0}, + {14, 0, 22, 0, 0, 0}, + {14, 0, 23, 0, 0, 0}, + {9, 0, 9, 0, 0, 136}, + {27, 0, 10, 0, 0, 136}, + {27, 0, 19, 0, 0, 136}, + {22, 0, 19, 1, 0, 136}, + {23, 0, 19, 1, 0, 136}, {18, 0, 1, 0, 4, 136}, - {28, 0, 11, 0, 5, 136}, + {28, 0, 11, 0, 0, 136}, {28, 0, 11, 0, 1, 0}, - {30, 0, 19, 0, 5, 136}, + {30, 0, 19, 0, 0, 136}, {30, 0, 19, 0, 4, 136}, {1, 0, 1, 0, 4, 170}, - {30, 0, 11, 0, 5, 0}, - {27, 0, 19, 1, 5, 136}, - {9, 0, 19, 0, 5, 136}, + {30, 0, 11, 0, 0, 0}, + {27, 0, 19, 1, 0, 136}, + {9, 0, 19, 0, 0, 136}, {8, 0, 1, 0, 4, 136}, - {8, 0, 1, 0, 5, 136}, - {27, 0, 19, 0, 5, 10}, - {30, 0, 19, 0, 5, 10}, - {27, 0, 19, 1, 5, 0}, + {8, 0, 1, 0, 0, 136}, + {27, 0, 19, 0, 0, 10}, + {30, 0, 19, 0, 0, 10}, + {27, 0, 19, 1, 0, 0}, {27, 0, 19, 1, 4, 0}, - {27, 0, 19, 1, 5, 10}, - {27, 0, 10, 0, 5, 0}, - {27, 0, 11, 0, 5, 0}, + {27, 0, 19, 1, 0, 10}, + {27, 0, 10, 0, 0, 0}, + {27, 0, 11, 0, 0, 0}, {27, 0, 19, 1, 4, 136}, {27, 0, 19, 1, 4, 10}, {30, 0, 19, 0, 2, 0}, @@ -252,10 +252,10 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {30, 0, 1, 0, 4, 136}, {9, 0, 19, 0, 4, 0}, {27, 0, 19, 0, 2, 0}, - {27, 0, 19, 1, 5, 170}, - {30, 0, 19, 1, 5, 0}, + {27, 0, 19, 1, 0, 170}, + {30, 0, 19, 1, 0, 0}, {30, 0, 19, 0, 2, 136}, - {10, 0, 18, 0, 0, 136}, + {10, 0, 18, 0, 5, 136}, {26, 0, 19, 0, 2, 0}, {18, 0, 1, 0, 2, 0}, {8, 0, 1, 0, 2, 0}, @@ -280,15 +280,16 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {30, 0, 1, 0, 2, 136}, {9, 0, 1, 0, 4, 0}, {9, 0, 19, 0, 2, 136}, - {29, 0, 1, 0, 5, 0}, - {15, 0, 1, 0, 5, 0}, + {29, 0, 1, 0, 0, 0}, + {15, 0, 1, 0, 0, 0}, {16, 0, 1, 0, 4, 0}, {19, 0, 1, 0, 2, 170}, - {19, 0, 4, 0, 5, 170}, - {4, 26, 14, 0, 5, 0}, - {19, 0, 4, 0, 5, 136}, - {23, 0, 19, 0, 5, 0}, - {28, 0, 5, 0, 5, 136}, + {0, 0, 0, 0, 2, 0}, + {19, 0, 4, 0, 0, 170}, + {4, 26, 14, 0, 0, 0}, + {19, 0, 4, 0, 0, 136}, + {23, 0, 19, 0, 0, 0}, + {28, 0, 5, 0, 0, 136}, {26, 0, 19, 0, 2, 136}, {22, 0, 19, 0, 2, 136}, {23, 0, 19, 0, 2, 136}, @@ -303,47 +304,47 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {27, 0, 19, 1, 2, 136}, {27, 0, 19, 0, 2, 136}, {28, 0, 11, 0, 2, 136}, - {26, 0, 19, 0, 0, 136}, - {26, 0, 11, 0, 0, 136}, - {28, 0, 11, 0, 0, 136}, - {22, 0, 19, 1, 0, 136}, - {23, 0, 19, 1, 0, 136}, - {27, 0, 10, 0, 0, 136}, - {26, 0, 13, 0, 0, 136}, - {21, 0, 10, 0, 0, 136}, - {7, 0, 9, 0, 0, 136}, - {27, 0, 19, 1, 0, 136}, - {27, 0, 19, 0, 0, 136}, - {1, 0, 1, 0, 0, 136}, - {29, 0, 19, 0, 0, 136}, - {20, 0, 19, 0, 0, 136}, - {2, 0, 1, 0, 0, 136}, + {26, 0, 19, 0, 5, 136}, + {26, 0, 11, 0, 5, 136}, + {28, 0, 11, 0, 5, 136}, + {22, 0, 19, 1, 5, 136}, + {23, 0, 19, 1, 5, 136}, + {27, 0, 10, 0, 5, 136}, + {26, 0, 13, 0, 5, 136}, + {21, 0, 10, 0, 5, 136}, + {7, 0, 9, 0, 5, 136}, + {27, 0, 19, 1, 5, 136}, + {27, 0, 19, 0, 5, 136}, + {1, 0, 1, 0, 5, 136}, + {29, 0, 19, 0, 5, 136}, + {20, 0, 19, 0, 5, 136}, + {2, 0, 1, 0, 5, 136}, {26, 0, 19, 0, 1, 136}, {22, 0, 19, 1, 1, 136}, {23, 0, 19, 1, 1, 136}, {19, 0, 1, 0, 1, 136}, {18, 0, 1, 0, 1, 136}, - {30, 0, 19, 0, 0, 136}, + {30, 0, 19, 0, 5, 136}, {30, 0, 19, 0, 1, 136}, {27, 0, 19, 0, 1, 136}, - {14, 0, 19, 0, 5, 0}, - {8, 0, 19, 0, 5, 0}, - {9, 0, 9, 0, 5, 0}, - {9, 0, 4, 0, 5, 0}, - {30, 0, 4, 0, 5, 0}, - {1, 0, 4, 0, 5, 0}, - {2, 0, 4, 0, 5, 0}, - {9, 0, 12, 0, 5, 0}, - {9, 0, 5, 0, 5, 0}, - {4, 9, 1, 0, 5, 0}, + {14, 0, 19, 0, 0, 0}, + {8, 0, 19, 0, 0, 0}, + {9, 0, 9, 0, 0, 0}, + {9, 0, 4, 0, 0, 0}, + {30, 0, 4, 0, 0, 0}, + {1, 0, 4, 0, 0, 0}, + {2, 0, 4, 0, 0, 0}, + {9, 0, 12, 0, 0, 0}, + {9, 0, 5, 0, 0, 0}, + {4, 9, 1, 0, 0, 0}, {4, 0, 14, 0, 2, 0}, {5, 6, 1, 0, 2, 0}, - {30, 0, 1, 0, 5, 170}, - {5, 216, 1, 0, 5, 0}, - {5, 226, 1, 0, 5, 0}, - {27, 0, 1, 0, 5, 136}, - {7, 0, 9, 0, 5, 136}, - {30, 0, 1, 0, 5, 136}, + {30, 0, 1, 0, 0, 170}, + {5, 216, 1, 0, 0, 0}, + {5, 226, 1, 0, 0, 0}, + {27, 0, 1, 0, 0, 136}, + {7, 0, 9, 0, 0, 136}, + {30, 0, 1, 0, 0, 136}, {30, 0, 1, 0, 4, 0}, {29, 0, 19, 0, 2, 0}, }; @@ -674,12 +675,12 @@ const char *_PyUnicode_BidirectionalNames[] = { NULL }; const char *_PyUnicode_EastAsianWidthNames[] = { - "F", + "N", "H", "W", "Na", "A", - "N", + "F", NULL }; static const char *decomp_prefix[] = { @@ -743,38 +744,38 @@ static const unsigned short index1[] = { 137, 138, 139, 140, 141, 142, 143, 144, 41, 41, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 137, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 137, 169, 170, 137, 171, 172, 173, 174, - 137, 175, 176, 177, 178, 179, 180, 137, 137, 181, 182, 183, 184, 137, - 185, 137, 186, 41, 41, 41, 41, 41, 41, 41, 187, 188, 41, 189, 137, 137, + 137, 175, 176, 177, 178, 179, 180, 181, 137, 182, 183, 184, 185, 137, + 186, 187, 188, 41, 41, 41, 41, 41, 41, 41, 189, 190, 41, 191, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 190, 41, 41, 41, 41, 41, 41, 41, 41, 191, 137, 137, + 137, 137, 137, 137, 192, 41, 41, 41, 41, 41, 41, 41, 41, 193, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 41, 41, 41, 41, 192, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 41, 41, 41, 41, 194, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 41, 41, 41, 41, 193, 194, 195, 196, 137, 137, 137, 137, 197, - 198, 199, 200, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 137, 137, 41, 41, 41, 41, 195, 196, 197, 198, 137, 137, 137, 137, 199, + 200, 201, 202, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 201, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 202, 203, 137, 137, 137, 137, 137, 137, 137, 137, + 101, 101, 101, 101, 101, 101, 101, 101, 203, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 204, 205, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 204, 101, 101, 205, 101, 101, 206, 137, 137, 137, + 137, 137, 137, 137, 206, 101, 101, 207, 101, 101, 208, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 207, 208, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 209, 210, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 209, 210, 78, 211, - 212, 213, 214, 215, 216, 137, 217, 218, 219, 220, 221, 222, 223, 224, 78, - 78, 78, 78, 225, 226, 137, 137, 137, 137, 137, 137, 137, 137, 227, 137, - 228, 137, 229, 137, 137, 230, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 231, 232, 233, 234, 137, 137, 137, 137, 137, 235, 236, 237, 137, - 238, 239, 137, 137, 240, 241, 242, 243, 244, 137, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 211, 212, 78, 213, + 214, 215, 216, 217, 218, 137, 219, 220, 221, 222, 223, 224, 225, 226, 78, + 78, 78, 78, 227, 228, 137, 137, 137, 137, 137, 137, 137, 137, 229, 137, + 230, 231, 232, 137, 137, 233, 137, 137, 137, 234, 137, 137, 137, 137, + 137, 235, 236, 237, 238, 137, 137, 137, 137, 137, 239, 240, 241, 137, + 242, 243, 137, 137, 244, 245, 246, 247, 248, 137, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 137, 137, 137, 137, 137, 137, 137, 137, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, @@ -799,22 +800,56 @@ static const unsigned short index1[] = { 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 263, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 267, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 264, 101, 265, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 268, 101, 269, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 266, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 270, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 267, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 121, 121, 121, 121, 268, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 121, 121, 121, 121, 273, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 274, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 269, 137, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 275, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 276, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, @@ -1180,41 +1215,7 @@ static const unsigned short index1[] = { 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 270, 137, 271, 272, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 277, 137, 278, 279, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, @@ -1287,7 +1288,7 @@ static const unsigned short index1[] = { 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 273, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 280, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, @@ -1324,7 +1325,7 @@ static const unsigned short index1[] = { 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 273, + 120, 280, }; static const unsigned short index2[] = { @@ -1519,7 +1520,7 @@ static const unsigned short index2[] = { 48, 0, 0, 147, 48, 141, 156, 149, 141, 148, 141, 141, 0, 156, 149, 149, 0, 149, 149, 135, 144, 0, 0, 0, 0, 0, 0, 0, 148, 148, 0, 0, 0, 0, 0, 0, 48, 48, 0, 48, 48, 135, 135, 0, 0, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 0, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, + 146, 146, 146, 0, 48, 48, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, 141, 141, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, @@ -1545,76 +1546,76 @@ static const unsigned short index2[] = { 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 48, 158, 135, 135, 135, 135, 161, 161, 144, 135, 135, 48, 0, - 0, 48, 48, 48, 48, 48, 0, 53, 0, 162, 162, 162, 162, 135, 135, 0, 0, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 158, 158, 48, 48, 0, + 0, 48, 48, 48, 48, 48, 0, 53, 0, 162, 162, 162, 162, 135, 135, 135, 0, + 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 158, 158, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 48, 80, 80, 80, 83, 83, 83, 83, 83, 83, 83, 83, 163, - 83, 83, 83, 83, 83, 83, 80, 83, 80, 80, 80, 86, 86, 80, 80, 80, 80, 80, - 80, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 80, 86, 80, 86, 80, 164, 165, 166, 165, - 166, 141, 141, 48, 48, 48, 145, 48, 48, 48, 48, 0, 48, 48, 48, 48, 145, - 48, 48, 48, 48, 145, 48, 48, 48, 48, 145, 48, 48, 48, 48, 145, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 145, 48, 48, 48, 0, 0, 0, 0, 167, - 168, 169, 170, 169, 169, 171, 169, 171, 168, 168, 168, 168, 135, 141, - 168, 169, 81, 81, 144, 83, 81, 81, 48, 48, 48, 48, 48, 135, 135, 135, - 135, 135, 135, 169, 135, 135, 135, 135, 0, 135, 135, 135, 135, 169, 135, - 135, 135, 135, 169, 135, 135, 135, 135, 169, 135, 135, 135, 135, 169, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 169, 135, - 135, 135, 0, 80, 80, 80, 80, 80, 80, 80, 80, 86, 80, 80, 80, 80, 80, 80, - 0, 80, 80, 83, 83, 83, 83, 83, 80, 80, 80, 80, 83, 83, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 48, 80, 80, 80, 83, 83, 83, 83, 83, 83, 83, 83, + 163, 83, 83, 83, 83, 83, 83, 80, 83, 80, 80, 80, 86, 86, 80, 80, 80, 80, + 80, 80, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 80, 86, 80, 86, 80, 164, 165, 166, + 165, 166, 141, 141, 48, 48, 48, 145, 48, 48, 48, 48, 0, 48, 48, 48, 48, + 145, 48, 48, 48, 48, 145, 48, 48, 48, 48, 145, 48, 48, 48, 48, 145, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 145, 48, 48, 48, 0, 0, 0, 0, + 167, 168, 169, 170, 169, 169, 171, 169, 171, 168, 168, 168, 168, 135, + 141, 168, 169, 81, 81, 144, 83, 81, 81, 48, 48, 48, 48, 48, 135, 135, + 135, 135, 135, 135, 169, 135, 135, 135, 135, 0, 135, 135, 135, 135, 169, + 135, 135, 135, 135, 169, 135, 135, 135, 135, 169, 135, 135, 135, 135, + 169, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 169, + 135, 135, 135, 0, 80, 80, 80, 80, 80, 80, 80, 80, 86, 80, 80, 80, 80, 80, + 80, 0, 80, 80, 83, 83, 83, 83, 83, 80, 80, 80, 80, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 142, 48, 48, 48, 48, 141, 141, 135, 151, 135, - 135, 141, 135, 135, 135, 135, 135, 147, 141, 144, 144, 141, 141, 135, - 135, 48, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 83, 83, 83, - 83, 83, 83, 48, 48, 48, 48, 48, 48, 141, 141, 135, 135, 48, 48, 48, 48, - 135, 135, 135, 48, 141, 141, 141, 48, 48, 141, 141, 141, 141, 141, 141, - 141, 48, 48, 48, 135, 135, 135, 135, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 135, 141, 141, 135, 135, 141, 141, 141, 141, 141, 141, - 86, 48, 141, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 141, 141, - 141, 135, 80, 80, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 48, 48, 48, 48, 48, 48, 48, 48, 142, 48, 48, 48, 48, 141, 141, 135, 151, + 135, 135, 141, 135, 135, 135, 135, 135, 147, 141, 144, 144, 141, 141, + 135, 135, 48, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 83, 83, + 83, 83, 83, 83, 48, 48, 48, 48, 48, 48, 141, 141, 135, 135, 48, 48, 48, + 48, 135, 135, 135, 48, 141, 141, 141, 48, 48, 141, 141, 141, 141, 141, + 141, 141, 48, 48, 48, 135, 135, 135, 135, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 135, 141, 141, 135, 135, 141, 141, 141, 141, 141, + 141, 86, 48, 141, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 141, + 141, 141, 135, 80, 80, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 0, 44, 0, 0, 0, 0, 0, 44, 0, 0, 47, 47, 47, 47, + 44, 44, 44, 44, 44, 44, 44, 44, 0, 44, 0, 0, 0, 0, 0, 44, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 83, 51, 47, 47, 47, 172, 172, 172, 172, 172, 172, 172, 172, + 47, 47, 47, 47, 47, 83, 51, 47, 47, 47, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 48, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, - 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 48, 48, 48, 48, + 172, 172, 172, 172, 172, 172, 48, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 173, 173, 173, 173, 173, 173, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, - 173, 173, 173, 173, 173, 173, 173, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 173, 173, 173, 173, 173, 173, 173, 173, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, - 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, - 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, + 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, + 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, - 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 0, 0, 48, + 48, 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, - 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, + 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 81, 81, - 81, 83, 83, 83, 83, 83, 83, 83, 83, 83, 150, 150, 150, 150, 150, 150, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 81, + 81, 81, 83, 83, 83, 83, 83, 83, 83, 83, 83, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, @@ -2259,7 +2260,7 @@ static const unsigned short index2[] = { 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 0, 0, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 281, 281, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, @@ -2267,22 +2268,23 @@ static const unsigned short index2[] = { 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, - 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 35, 35, 35, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 35, 0, 0, 0, 0, 0, - 281, 282, 281, 283, 283, 283, 283, 283, 283, 283, 283, 283, 219, 281, - 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 0, 281, 281, - 281, 281, 281, 0, 281, 0, 281, 281, 0, 281, 281, 0, 281, 281, 281, 281, - 281, 281, 281, 281, 281, 283, 131, 131, 131, 131, 131, 131, 131, 131, + 280, 280, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 35, 35, 35, + 35, 35, 35, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 35, + 0, 0, 0, 0, 0, 282, 283, 282, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 219, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + 282, 0, 282, 282, 282, 282, 282, 0, 282, 0, 282, 282, 0, 282, 282, 0, + 282, 282, 282, 282, 282, 282, 282, 282, 282, 284, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, @@ -2299,26 +2301,26 @@ static const unsigned short index2[] = { 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 284, 199, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 285, 199, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 285, 26, 26, 26, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 286, 286, 286, 286, 286, 286, 286, 287, 288, 286, 0, 0, 0, 0, - 0, 0, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 81, 81, - 286, 289, 289, 290, 290, 287, 288, 287, 288, 287, 288, 287, 288, 287, - 288, 287, 288, 287, 288, 287, 288, 253, 253, 287, 288, 286, 286, 286, - 286, 290, 290, 290, 291, 286, 291, 0, 286, 291, 286, 286, 289, 292, 293, - 292, 293, 292, 293, 294, 286, 286, 295, 296, 297, 297, 298, 0, 286, 299, - 294, 286, 0, 0, 0, 0, 131, 131, 131, 118, 131, 0, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, + 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 286, 26, 26, 26, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 287, 287, 287, 287, 287, 287, 287, 288, 289, + 287, 0, 0, 0, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, + 86, 86, 81, 81, 287, 290, 290, 291, 291, 288, 289, 288, 289, 288, 289, + 288, 289, 288, 289, 288, 289, 288, 289, 288, 289, 253, 253, 288, 289, + 287, 287, 287, 287, 291, 291, 291, 292, 287, 292, 0, 287, 292, 287, 287, + 290, 293, 294, 293, 294, 293, 294, 295, 287, 287, 296, 297, 298, 298, + 299, 0, 287, 300, 295, 287, 0, 0, 0, 0, 131, 131, 131, 118, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, @@ -2328,605 +2330,619 @@ static const unsigned short index2[] = { 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 0, 0, 177, 0, 300, 300, 301, 302, 301, 300, 300, - 303, 304, 300, 305, 306, 307, 306, 306, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 306, 300, 309, 310, 309, 300, 300, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 311, 303, 300, 304, 312, 313, - 312, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 303, - 310, 304, 310, 303, 304, 315, 316, 317, 315, 315, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 319, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 319, 319, 318, 318, - 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 0, 0, 0, 318, 318, 318, 318, 318, 318, 0, 0, 318, 318, 318, 318, - 318, 318, 0, 0, 318, 318, 318, 318, 318, 318, 0, 0, 318, 318, 318, 0, 0, - 0, 302, 302, 310, 312, 320, 302, 302, 0, 321, 322, 322, 322, 322, 321, - 321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 323, 323, 323, 26, 30, 0, 0, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, + 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 177, 0, 301, 301, 302, 303, + 302, 301, 301, 304, 305, 301, 306, 307, 308, 307, 307, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 307, 301, 310, 311, 310, 301, 301, + 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 304, 301, + 305, 313, 314, 313, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 304, 311, 305, 311, 304, 305, 316, 317, 318, 316, 316, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 320, 319, 319, 319, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 320, + 320, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 319, 0, 0, 0, 319, 319, 319, 319, 319, 319, 0, 0, 319, + 319, 319, 319, 319, 319, 0, 0, 319, 319, 319, 319, 319, 319, 0, 0, 319, + 319, 319, 0, 0, 0, 303, 303, 311, 313, 321, 303, 303, 0, 322, 323, 323, + 323, 323, 322, 322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, 324, 324, 26, 30, + 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 0, 0, 0, 0, 0, 83, 138, 83, 0, 0, 0, 0, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 0, - 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 324, 324, 324, 324, 324, 324, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, - 324, 324, 324, 324, 324, 155, 155, 155, 155, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 155, 155, 26, 80, 80, 0, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 26, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 0, 0, 0, 0, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 150, 150, 150, 150, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 175, 48, 48, 48, 48, 48, 48, 48, 48, 175, 0, 0, - 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 0, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 83, 175, 175, 175, 175, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 83, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 44, 44, 44, 44, - 44, 44, 44, 0, 44, 44, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, - 47, 47, 47, 47, 47, 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 51, 51, 51, 51, - 51, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, - 107, 107, 107, 107, 0, 0, 107, 0, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 0, 107, 107, 0, 0, 0, 107, 0, 0, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 104, 326, 326, 326, 326, - 326, 326, 326, 326, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 327, - 327, 326, 326, 326, 326, 326, 326, 326, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, - 0, 0, 326, 326, 326, 326, 326, 326, 326, 326, 326, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 0, 107, 107, 0, 0, 0, 0, 0, 326, 326, 326, 326, 326, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 326, 326, 326, 326, 326, 326, 0, 0, 0, 138, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 326, 326, - 107, 107, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 0, 0, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 107, 135, 135, 135, 0, 135, - 135, 0, 0, 0, 0, 0, 135, 86, 135, 81, 107, 107, 107, 107, 0, 107, 107, - 107, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 0, 0, 81, 178, 86, 0, 0, 0, 0, 144, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 0, 0, 0, 0, 0, 0, 0, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 326, 326, 104, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 326, 326, - 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 327, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 81, - 86, 0, 0, 0, 0, 326, 326, 326, 326, 326, 104, 104, 104, 104, 104, 104, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 0, 0, 0, 138, 138, 138, 138, 138, 138, 138, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 0, 0, 326, 326, 326, 326, 326, 326, 326, - 326, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 326, 326, 326, 326, 326, - 326, 326, 326, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 104, 104, 104, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 326, 326, 326, 326, 326, 326, - 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, - 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, - 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, - 329, 329, 329, 329, 329, 329, 329, 329, 329, 0, 0, 0, 0, 0, 0, 0, 326, - 326, 326, 326, 326, 326, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 81, 81, - 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, - 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, - 330, 330, 330, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 0, 81, 81, 102, 0, 0, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 107, 0, 0, 0, 0, 0, 0, 0, 0, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 86, 86, 81, 81, 81, 86, 81, 86, - 86, 86, 86, 331, 331, 331, 331, 113, 113, 113, 113, 113, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 81, - 86, 81, 86, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 326, 326, 326, 326, 326, 326, 326, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, 135, 141, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 144, 83, - 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 144, 48, 48, 135, 135, 48, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 135, 135, 141, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 142, - 48, 142, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 142, 48, - 48, 48, 48, 141, 141, 141, 135, 135, 135, 135, 141, 141, 144, 143, 83, - 83, 192, 83, 83, 83, 83, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 81, 81, 81, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 151, 135, 135, - 135, 135, 141, 135, 152, 152, 135, 135, 135, 144, 144, 0, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 83, 83, 83, 83, 48, 141, 141, 48, 0, - 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 147, 83, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, - 141, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 141, 141, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 141, 176, 48, 48, 48, 48, 83, 83, - 83, 83, 135, 147, 135, 135, 83, 141, 135, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 48, 83, 48, 83, 83, 83, 0, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, - 141, 141, 135, 135, 135, 141, 141, 135, 176, 147, 135, 83, 83, 83, 83, - 83, 83, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, - 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 83, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 135, 141, 141, 141, 135, 135, 135, 135, 135, 135, 147, 144, 0, 0, 0, 0, - 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, - 135, 135, 141, 141, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 0, - 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, - 48, 48, 48, 0, 147, 147, 48, 148, 141, 135, 141, 141, 141, 141, 0, 0, - 141, 141, 0, 0, 149, 149, 176, 0, 0, 48, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, - 0, 0, 48, 48, 48, 48, 48, 141, 141, 0, 0, 81, 81, 81, 81, 81, 81, 81, 0, - 0, 0, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 141, 141, - 135, 135, 135, 135, 135, 135, 135, 135, 141, 141, 144, 135, 135, 141, - 147, 48, 48, 48, 48, 83, 83, 83, 83, 83, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 83, 83, 0, 83, 81, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 148, 141, 141, 135, 135, 135, - 135, 135, 135, 141, 151, 149, 149, 148, 149, 135, 135, 141, 144, 147, 48, - 48, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 148, 141, 141, 135, 135, 135, 135, 0, 0, 141, - 141, 149, 149, 135, 135, 141, 144, 147, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 48, 48, 48, - 48, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 141, 141, 141, 135, 135, 135, 135, 135, 135, 135, 135, - 141, 141, 135, 141, 144, 135, 83, 83, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 135, 141, 135, 141, 141, 135, 135, 135, 135, 135, 135, 176, 147, 48, - 83, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 135, 135, 135, - 141, 141, 135, 135, 135, 135, 141, 135, 135, 135, 135, 144, 0, 0, 0, 0, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 150, 150, 83, 83, 83, - 80, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 141, 141, 141, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 141, 144, 147, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 0, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, - 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 148, 141, 141, 141, 141, 141, 0, 141, - 149, 0, 0, 135, 135, 176, 144, 48, 141, 48, 141, 147, 83, 83, 83, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, + 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 141, 141, 135, 135, 135, - 135, 0, 0, 135, 135, 141, 141, 141, 141, 144, 48, 83, 48, 141, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 48, 135, 135, 135, 135, 135, 135, 156, 156, 135, 135, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, - 144, 135, 135, 135, 135, 141, 48, 135, 135, 135, 135, 83, 83, 83, 83, 83, - 83, 83, 83, 144, 0, 0, 0, 0, 0, 0, 0, 0, 48, 135, 135, 135, 135, 135, - 135, 141, 141, 135, 135, 135, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 141, 135, - 144, 83, 83, 83, 48, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 141, 135, 135, 135, 135, 135, 135, 135, 0, 135, 135, 135, 135, 135, 135, - 141, 332, 48, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 0, 0, 0, - 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 0, 141, 135, 135, 135, 135, 135, 135, 135, - 141, 135, 135, 141, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, - 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 135, 135, 135, 135, 135, 135, 0, 0, 0, 135, 0, 135, 135, 0, - 135, 135, 135, 147, 135, 144, 144, 48, 135, 0, 0, 0, 0, 0, 0, 0, 0, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 48, 48, - 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 141, 141, 141, 141, 141, 0, 135, 135, 0, 141, 141, 135, 141, - 144, 48, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 141, - 141, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 26, 26, 26, 26, 26, 26, 26, 26, - 85, 85, 85, 85, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 0, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, - 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 178, 178, - 178, 178, 178, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 83, 138, 83, 0, 0, 0, 0, 150, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 155, 155, 155, 155, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 155, 155, 26, 80, + 80, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 81, 81, 81, 81, 81, 81, 81, 83, 83, 83, 83, 83, - 80, 80, 80, 80, 53, 53, 53, 53, 83, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 150, 150, 150, 150, - 150, 150, 150, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, + 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 0, 0, 0, + 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 150, 150, + 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 175, 48, 48, 48, 48, 48, 48, + 48, 48, 175, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 83, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 48, + 48, 48, 48, 48, 48, 48, 48, 83, 175, 175, 175, 175, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 150, 150, 150, 150, 150, 150, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 0, 44, 44, 44, 44, 44, 44, 44, 0, 44, 44, 0, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 53, 51, 51, 51, 51, 51, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 0, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 107, 107, 107, 107, 107, 107, 0, 0, 107, 0, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 107, 107, + 0, 0, 0, 107, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 104, + 327, 327, 327, 327, 327, 327, 327, 327, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 328, 328, 327, 327, 327, 327, 327, 327, 327, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 0, 0, 0, 0, 0, 0, 0, 0, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 0, 107, 107, 0, 0, 0, 0, 0, 327, 327, 327, 327, + 327, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 327, 327, 327, 327, 327, + 327, 0, 0, 0, 138, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, + 0, 0, 0, 327, 327, 107, 107, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 0, 0, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 107, 135, + 135, 135, 0, 135, 135, 0, 0, 0, 0, 0, 135, 86, 135, 81, 107, 107, 107, + 107, 0, 107, 107, 107, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 0, 0, 81, 178, 86, 0, 0, 0, 0, 144, 327, + 327, 327, 327, 327, 327, 327, 327, 327, 0, 0, 0, 0, 0, 0, 0, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 327, 327, + 104, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 327, 327, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, + 107, 107, 107, 328, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 81, 86, 0, 0, 0, 0, 327, 327, 327, 327, 327, 104, + 104, 104, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 138, 138, 138, 138, + 138, 138, 138, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 327, 327, + 327, 327, 327, 327, 327, 327, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, + 327, 327, 327, 327, 327, 327, 327, 327, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, + 0, 0, 0, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 327, + 327, 327, 327, 327, 327, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 0, 0, 0, + 0, 0, 0, 0, 327, 327, 327, 327, 327, 327, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, + 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, + 331, 331, 331, 331, 331, 331, 331, 0, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 0, 81, 81, 102, 0, 0, 107, 107, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 86, 86, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 107, 0, 0, 0, 0, 0, 0, 0, 0, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 86, 86, + 81, 81, 81, 86, 81, 86, 86, 86, 86, 332, 332, 332, 332, 113, 113, 113, + 113, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 81, 86, 81, 86, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 327, 327, 327, + 327, 327, 327, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 141, 135, 141, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 144, 83, 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 144, 48, + 48, 135, 135, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 135, 135, 141, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 142, 48, 142, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 142, 48, 48, 48, 48, 141, 141, 141, 135, 135, 135, 135, 141, 141, + 144, 143, 83, 83, 192, 83, 83, 83, 83, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 192, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 81, 81, 81, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 151, + 135, 135, 135, 135, 141, 135, 152, 152, 135, 135, 135, 144, 144, 0, 146, + 146, 146, 146, 146, 146, 146, 146, 146, 146, 83, 83, 83, 83, 48, 141, + 141, 48, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 147, 83, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 135, 135, 141, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 141, + 141, 135, 135, 135, 135, 135, 135, 135, 135, 135, 141, 176, 48, 48, 48, + 48, 83, 83, 83, 83, 135, 147, 135, 135, 83, 141, 135, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 48, 83, 48, 83, 83, 83, 0, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 150, 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 141, 141, 141, 135, 135, 135, 141, 141, 135, 176, 147, 135, 83, + 83, 83, 83, 83, 83, 135, 48, 48, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, 48, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 83, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 135, 141, 141, 141, 135, 135, 135, 135, 135, 135, 147, + 144, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, + 0, 0, 0, 0, 0, 135, 135, 141, 141, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, + 0, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, + 0, 48, 48, 48, 48, 48, 0, 147, 147, 48, 148, 141, 135, 141, 141, 141, + 141, 0, 0, 141, 141, 0, 0, 149, 149, 176, 0, 0, 48, 0, 0, 0, 0, 0, 0, + 148, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 141, 141, 0, 0, 81, 81, 81, 81, + 81, 81, 81, 0, 0, 0, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, + 141, 141, 135, 135, 135, 135, 135, 135, 135, 135, 141, 141, 144, 135, + 135, 141, 147, 48, 48, 48, 48, 83, 83, 83, 83, 83, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 83, 83, 0, 83, 81, 48, 48, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 148, 141, 141, 135, + 135, 135, 135, 135, 135, 141, 151, 149, 149, 148, 149, 135, 135, 141, + 144, 147, 48, 48, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 148, 141, 141, 135, 135, 135, + 135, 0, 0, 141, 141, 149, 149, 135, 135, 141, 144, 147, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 48, 48, 48, 48, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 141, 141, 135, 135, 135, 135, + 135, 135, 135, 135, 141, 141, 135, 141, 144, 135, 83, 83, 83, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 0, 0, 0, 0, 0, 0, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 135, 141, 135, 141, 141, 135, 135, 135, 135, + 135, 135, 176, 147, 48, 83, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 0, 0, 135, 135, 135, 141, 141, 135, 135, 135, 135, 141, 135, 135, + 135, 135, 144, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 150, 150, 83, 83, 83, 80, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 141, 141, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 141, 144, 147, 83, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 146, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 150, 150, 150, 150, 150, 150, 150, 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 0, 0, 48, 48, 48, + 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 148, 141, 141, + 141, 141, 141, 0, 141, 149, 0, 0, 135, 135, 176, 144, 48, 141, 48, 141, + 147, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 141, + 141, 135, 135, 135, 135, 0, 0, 135, 135, 141, 141, 141, 141, 144, 48, 83, + 48, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 48, 135, 135, 135, 135, 135, 135, 156, 156, 135, 135, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 135, 144, 135, 135, 135, 135, 141, 48, 135, 135, 135, + 135, 83, 83, 83, 83, 83, 83, 83, 83, 144, 0, 0, 0, 0, 0, 0, 0, 0, 48, + 135, 135, 135, 135, 135, 135, 141, 141, 135, 135, 135, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 141, 135, 144, 83, 83, 83, 48, 83, 83, 83, 83, 83, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 135, + 135, 135, 135, 135, 135, 135, 0, 135, 135, 135, 135, 135, 135, 141, 333, + 48, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 0, 0, 0, 83, 83, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 0, 141, 135, 135, 135, 135, 135, 135, 135, 141, 135, + 135, 141, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 135, 135, 135, 135, 135, 135, 0, 0, 0, 135, 0, 135, 135, 0, 135, 135, + 135, 147, 135, 144, 144, 48, 135, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, + 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 141, 141, 141, 141, 141, 0, 135, 135, 0, 141, 141, 135, 141, 144, 48, 0, + 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 141, 141, 83, 83, 0, 0, + 0, 0, 0, 0, 0, 135, 135, 48, 141, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 141, 141, 135, 135, 135, 135, 135, 0, 0, 0, 141, 141, 135, 176, + 144, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 26, 26, 26, 26, 26, 26, 26, 26, 85, 85, 85, 85, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 0, + 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 192, 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 135, 48, 48, 48, 48, 48, 48, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 135, - 48, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 0, 0, 0, - 0, 0, 0, 0, 135, 135, 135, 135, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 254, - 253, 254, 333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 334, 334, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, - 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 254, 254, 254, 254, 0, 254, 254, 254, 254, 254, - 254, 254, 0, 254, 254, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 0, 0, 0, - 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 83, + 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, - 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 80, 135, 178, - 83, 177, 177, 177, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 0, 0, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 335, 335, 335, 335, 335, 335, 335, - 336, 336, 178, 178, 178, 80, 80, 80, 337, 336, 336, 336, 336, 336, 177, - 177, 177, 177, 177, 177, 177, 177, 86, 86, 86, 86, 86, 86, 86, 86, 80, - 80, 81, 81, 81, 81, 81, 86, 86, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 81, 81, 81, 81, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 335, 335, 335, 335, 335, 335, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 26, 26, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 81, 81, 81, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 0, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 0, 0, 178, 178, 178, 178, 178, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 81, 81, 81, 81, 81, + 81, 83, 83, 83, 83, 83, 80, 80, 80, 80, 53, 53, 53, 53, 83, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, + 150, 150, 150, 150, 150, 150, 150, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, + 150, 150, 150, 150, 150, 150, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 135, 48, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 0, 0, 0, 0, 0, 0, 0, 135, 135, 135, 135, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 254, 254, 253, 254, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 335, 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 254, 254, 254, 0, + 254, 254, 254, 254, 254, 254, 254, 0, 254, 254, 0, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 172, 172, 172, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 0, 0, 80, 135, 178, 83, 177, 177, 177, 177, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 0, 0, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 336, 336, + 336, 336, 336, 336, 336, 337, 337, 178, 178, 178, 80, 80, 80, 338, 337, + 337, 337, 337, 337, 177, 177, 177, 177, 177, 177, 177, 177, 86, 86, 86, + 86, 86, 86, 86, 86, 80, 80, 81, 81, 81, 81, 81, 86, 86, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 336, 336, 336, 336, 336, 336, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 81, 81, 81, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, @@ -2966,26 +2982,26 @@ static const unsigned short index2[] = { 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 338, 35, 35, 35, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 339, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 338, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 339, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 338, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 49, 49, 49, 49, 339, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 338, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 49, 49, 49, 49, 49, 49, 49, 49, 339, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 338, 35, 35, 35, 35, 35, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 339, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 35, 0, 0, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 35, 0, 0, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, @@ -3001,153 +3017,166 @@ static const unsigned short index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 47, + 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 81, 81, 81, + 81, 81, 81, 0, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 0, 0, 81, 81, 81, 81, 81, 81, 81, 0, 81, 81, 0, 81, 81, 81, + 81, 81, 0, 0, 0, 0, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 81, 81, 81, 81, - 81, 81, 0, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 0, 0, 81, 81, 81, 81, 81, 81, 81, 0, 81, 81, 0, 81, 81, 81, 81, - 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, 53, 53, 53, 53, 53, 53, 53, 0, - 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 48, 80, + 48, 48, 48, 48, 48, 48, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, 53, 53, 53, + 53, 53, 53, 53, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, + 0, 0, 0, 0, 48, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 81, 81, 81, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 81, 81, 81, 146, + 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 0, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 0, 0, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 182, 182, 86, 81, + 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 329, 329, 329, 329, 329, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, + 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, - 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, - 329, 81, 81, 81, 81, 81, 81, 147, 137, 0, 0, 0, 0, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 0, 0, 0, 0, 104, 104, 0, 0, 0, 0, 0, 0, 0, + 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 81, 81, 81, 81, 81, 81, 147, 137, 0, 0, 0, 0, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 0, 0, 0, 0, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 133, - 331, 331, 331, 111, 331, 331, 331, 331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 133, 332, 332, 332, 111, 332, 332, 332, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 133, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 133, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, - 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, - 131, 131, 0, 131, 0, 0, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 0, 131, 131, 131, 131, 0, 131, 0, 131, 0, 0, 0, 0, 0, 0, 131, - 0, 0, 0, 0, 131, 0, 131, 0, 131, 0, 131, 131, 131, 0, 131, 131, 0, 131, - 0, 0, 131, 0, 131, 0, 131, 0, 131, 0, 131, 0, 131, 131, 0, 131, 0, 0, - 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, 0, 131, 131, - 131, 131, 0, 131, 131, 131, 131, 0, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 131, 131, 131, 0, 131, - 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 0, 131, 131, 0, 131, 0, 0, 131, 0, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 0, 131, 131, 131, 131, 0, 131, 0, 131, 0, + 0, 0, 0, 0, 0, 131, 0, 0, 0, 0, 131, 0, 131, 0, 131, 0, 131, 131, 131, 0, + 131, 131, 0, 131, 0, 0, 131, 0, 131, 0, 131, 0, 131, 0, 131, 0, 131, 131, + 0, 131, 0, 0, 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, + 0, 131, 131, 131, 131, 0, 131, 131, 131, 131, 0, 131, 0, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 131, + 131, 131, 0, 131, 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 78, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 243, 26, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 78, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 0, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 155, 155, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 155, + 155, 26, 26, 26, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 341, 26, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, - 246, 246, 340, 26, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, - 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, - 246, 246, 246, 246, 246, 246, 246, 341, 341, 341, 341, 341, 341, 341, - 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, - 341, 341, 341, 341, 341, 226, 226, 226, 26, 26, 26, 341, 341, 341, 341, - 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, - 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 272, 341, - 246, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 341, 341, 341, - 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, - 341, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 226, 226, 226, 26, 26, 26, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 272, 342, 246, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 274, 274, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 274, 274, 274, 274, 274, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 274, 274, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 0, 0, 0, 0, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 0, 0, 0, 0, 0, 0, 0, 274, 274, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 243, 243, 243, 243, 243, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 0, + 0, 0, 0, 274, 274, 274, 274, 274, 274, 274, 274, 274, 0, 0, 0, 0, 0, 0, + 0, 274, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 243, 243, + 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, - 26, 26, 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 26, 26, 26, 243, 26, 26, 26, 243, 243, 243, 342, 342, - 342, 342, 342, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 26, 26, 26, 26, 243, 243, 243, 243, 243, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 243, 26, 26, 26, + 243, 243, 243, 343, 343, 343, 343, 343, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 243, 26, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 26, 243, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, @@ -3160,132 +3189,133 @@ static const unsigned short index2[] = { 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, 243, 243, 26, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, + 243, 243, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, 243, 26, 26, - 26, 243, 243, 243, 26, 26, 243, 243, 243, 0, 0, 0, 0, 0, 243, 243, 243, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, 0, 0, 0, 26, 26, - 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, 26, 26, 26, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, + 243, 26, 26, 26, 243, 243, 243, 26, 26, 243, 243, 243, 0, 0, 0, 0, 243, + 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, 0, + 0, 0, 26, 26, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 0, + 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 0, 0, 0, 0, 0, 0, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 0, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, + 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 0, 0, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 26, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 243, 243, + 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 0, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, 0, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, 0, - 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, - 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, - 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 0, 0, 243, 243, 243, 243, 243, 0, 0, 0, 243, 243, 243, 243, - 243, 0, 0, 0, 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 0, 0, 0, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, - 0, 0, 0, 0, 243, 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 243, - 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 0, 243, 243, 243, - 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 281, 281, 281, 281, 281, + 281, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 281, 281, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, @@ -3294,8 +3324,9 @@ static const unsigned short index2[] = { 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, @@ -3307,31 +3338,63 @@ static const unsigned short index2[] = { 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, + 280, 280, 280, 280, 280, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 0, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 281, 281, 281, + 281, 281, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 0, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 0, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, @@ -3344,8 +3407,8 @@ static const unsigned short index2[] = { 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, @@ -3354,7 +3417,7 @@ static const unsigned short index2[] = { 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 0, 0, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 0, 0, }; /* decomposition data */ @@ -3420,121 +3483,120 @@ static const unsigned int decomp_data[] = { 259, 121, 514, 32, 774, 514, 32, 775, 514, 32, 778, 514, 32, 808, 514, 32, 771, 514, 32, 779, 259, 611, 259, 108, 259, 115, 259, 120, 259, 661, 256, 768, 256, 769, 256, 787, 512, 776, 769, 256, 697, 514, 32, 837, 256, - 59, 514, 32, 769, 512, 168, 769, 512, 913, 769, 256, 183, 512, 917, 769, - 512, 919, 769, 512, 921, 769, 512, 927, 769, 512, 933, 769, 512, 937, - 769, 512, 970, 769, 512, 921, 776, 512, 933, 776, 512, 945, 769, 512, - 949, 769, 512, 951, 769, 512, 953, 769, 512, 971, 769, 512, 953, 776, - 512, 965, 776, 512, 959, 769, 512, 965, 769, 512, 969, 769, 258, 946, - 258, 952, 258, 933, 512, 978, 769, 512, 978, 776, 258, 966, 258, 960, - 258, 954, 258, 961, 258, 962, 258, 920, 258, 949, 258, 931, 512, 1045, - 768, 512, 1045, 776, 512, 1043, 769, 512, 1030, 776, 512, 1050, 769, 512, - 1048, 768, 512, 1059, 774, 512, 1048, 774, 512, 1080, 774, 512, 1077, - 768, 512, 1077, 776, 512, 1075, 769, 512, 1110, 776, 512, 1082, 769, 512, - 1080, 768, 512, 1091, 774, 512, 1140, 783, 512, 1141, 783, 512, 1046, - 774, 512, 1078, 774, 512, 1040, 774, 512, 1072, 774, 512, 1040, 776, 512, - 1072, 776, 512, 1045, 774, 512, 1077, 774, 512, 1240, 776, 512, 1241, - 776, 512, 1046, 776, 512, 1078, 776, 512, 1047, 776, 512, 1079, 776, 512, - 1048, 772, 512, 1080, 772, 512, 1048, 776, 512, 1080, 776, 512, 1054, - 776, 512, 1086, 776, 512, 1256, 776, 512, 1257, 776, 512, 1069, 776, 512, - 1101, 776, 512, 1059, 772, 512, 1091, 772, 512, 1059, 776, 512, 1091, - 776, 512, 1059, 779, 512, 1091, 779, 512, 1063, 776, 512, 1095, 776, 512, - 1067, 776, 512, 1099, 776, 514, 1381, 1410, 512, 1575, 1619, 512, 1575, - 1620, 512, 1608, 1620, 512, 1575, 1621, 512, 1610, 1620, 514, 1575, 1652, - 514, 1608, 1652, 514, 1735, 1652, 514, 1610, 1652, 512, 1749, 1620, 512, - 1729, 1620, 512, 1746, 1620, 512, 2344, 2364, 512, 2352, 2364, 512, 2355, - 2364, 512, 2325, 2364, 512, 2326, 2364, 512, 2327, 2364, 512, 2332, 2364, - 512, 2337, 2364, 512, 2338, 2364, 512, 2347, 2364, 512, 2351, 2364, 512, - 2503, 2494, 512, 2503, 2519, 512, 2465, 2492, 512, 2466, 2492, 512, 2479, - 2492, 512, 2610, 2620, 512, 2616, 2620, 512, 2582, 2620, 512, 2583, 2620, - 512, 2588, 2620, 512, 2603, 2620, 512, 2887, 2902, 512, 2887, 2878, 512, - 2887, 2903, 512, 2849, 2876, 512, 2850, 2876, 512, 2962, 3031, 512, 3014, - 3006, 512, 3015, 3006, 512, 3014, 3031, 512, 3142, 3158, 512, 3263, 3285, - 512, 3270, 3285, 512, 3270, 3286, 512, 3270, 3266, 512, 3274, 3285, 512, - 3398, 3390, 512, 3399, 3390, 512, 3398, 3415, 512, 3545, 3530, 512, 3545, - 3535, 512, 3548, 3530, 512, 3545, 3551, 514, 3661, 3634, 514, 3789, 3762, - 514, 3755, 3737, 514, 3755, 3745, 257, 3851, 512, 3906, 4023, 512, 3916, - 4023, 512, 3921, 4023, 512, 3926, 4023, 512, 3931, 4023, 512, 3904, 4021, - 512, 3953, 3954, 512, 3953, 3956, 512, 4018, 3968, 514, 4018, 3969, 512, - 4019, 3968, 514, 4019, 3969, 512, 3953, 3968, 512, 3986, 4023, 512, 3996, - 4023, 512, 4001, 4023, 512, 4006, 4023, 512, 4011, 4023, 512, 3984, 4021, - 512, 4133, 4142, 259, 4316, 512, 6917, 6965, 512, 6919, 6965, 512, 6921, - 6965, 512, 6923, 6965, 512, 6925, 6965, 512, 6929, 6965, 512, 6970, 6965, - 512, 6972, 6965, 512, 6974, 6965, 512, 6975, 6965, 512, 6978, 6965, 259, - 65, 259, 198, 259, 66, 259, 68, 259, 69, 259, 398, 259, 71, 259, 72, 259, - 73, 259, 74, 259, 75, 259, 76, 259, 77, 259, 78, 259, 79, 259, 546, 259, - 80, 259, 82, 259, 84, 259, 85, 259, 87, 259, 97, 259, 592, 259, 593, 259, - 7426, 259, 98, 259, 100, 259, 101, 259, 601, 259, 603, 259, 604, 259, - 103, 259, 107, 259, 109, 259, 331, 259, 111, 259, 596, 259, 7446, 259, - 7447, 259, 112, 259, 116, 259, 117, 259, 7453, 259, 623, 259, 118, 259, - 7461, 259, 946, 259, 947, 259, 948, 259, 966, 259, 967, 261, 105, 261, - 114, 261, 117, 261, 118, 261, 946, 261, 947, 261, 961, 261, 966, 261, - 967, 259, 1085, 259, 594, 259, 99, 259, 597, 259, 240, 259, 604, 259, - 102, 259, 607, 259, 609, 259, 613, 259, 616, 259, 617, 259, 618, 259, - 7547, 259, 669, 259, 621, 259, 7557, 259, 671, 259, 625, 259, 624, 259, - 626, 259, 627, 259, 628, 259, 629, 259, 632, 259, 642, 259, 643, 259, - 427, 259, 649, 259, 650, 259, 7452, 259, 651, 259, 652, 259, 122, 259, - 656, 259, 657, 259, 658, 259, 952, 512, 65, 805, 512, 97, 805, 512, 66, - 775, 512, 98, 775, 512, 66, 803, 512, 98, 803, 512, 66, 817, 512, 98, - 817, 512, 199, 769, 512, 231, 769, 512, 68, 775, 512, 100, 775, 512, 68, - 803, 512, 100, 803, 512, 68, 817, 512, 100, 817, 512, 68, 807, 512, 100, - 807, 512, 68, 813, 512, 100, 813, 512, 274, 768, 512, 275, 768, 512, 274, - 769, 512, 275, 769, 512, 69, 813, 512, 101, 813, 512, 69, 816, 512, 101, - 816, 512, 552, 774, 512, 553, 774, 512, 70, 775, 512, 102, 775, 512, 71, - 772, 512, 103, 772, 512, 72, 775, 512, 104, 775, 512, 72, 803, 512, 104, - 803, 512, 72, 776, 512, 104, 776, 512, 72, 807, 512, 104, 807, 512, 72, - 814, 512, 104, 814, 512, 73, 816, 512, 105, 816, 512, 207, 769, 512, 239, - 769, 512, 75, 769, 512, 107, 769, 512, 75, 803, 512, 107, 803, 512, 75, - 817, 512, 107, 817, 512, 76, 803, 512, 108, 803, 512, 7734, 772, 512, - 7735, 772, 512, 76, 817, 512, 108, 817, 512, 76, 813, 512, 108, 813, 512, - 77, 769, 512, 109, 769, 512, 77, 775, 512, 109, 775, 512, 77, 803, 512, - 109, 803, 512, 78, 775, 512, 110, 775, 512, 78, 803, 512, 110, 803, 512, - 78, 817, 512, 110, 817, 512, 78, 813, 512, 110, 813, 512, 213, 769, 512, - 245, 769, 512, 213, 776, 512, 245, 776, 512, 332, 768, 512, 333, 768, - 512, 332, 769, 512, 333, 769, 512, 80, 769, 512, 112, 769, 512, 80, 775, - 512, 112, 775, 512, 82, 775, 512, 114, 775, 512, 82, 803, 512, 114, 803, - 512, 7770, 772, 512, 7771, 772, 512, 82, 817, 512, 114, 817, 512, 83, - 775, 512, 115, 775, 512, 83, 803, 512, 115, 803, 512, 346, 775, 512, 347, - 775, 512, 352, 775, 512, 353, 775, 512, 7778, 775, 512, 7779, 775, 512, - 84, 775, 512, 116, 775, 512, 84, 803, 512, 116, 803, 512, 84, 817, 512, - 116, 817, 512, 84, 813, 512, 116, 813, 512, 85, 804, 512, 117, 804, 512, - 85, 816, 512, 117, 816, 512, 85, 813, 512, 117, 813, 512, 360, 769, 512, - 361, 769, 512, 362, 776, 512, 363, 776, 512, 86, 771, 512, 118, 771, 512, - 86, 803, 512, 118, 803, 512, 87, 768, 512, 119, 768, 512, 87, 769, 512, - 119, 769, 512, 87, 776, 512, 119, 776, 512, 87, 775, 512, 119, 775, 512, - 87, 803, 512, 119, 803, 512, 88, 775, 512, 120, 775, 512, 88, 776, 512, - 120, 776, 512, 89, 775, 512, 121, 775, 512, 90, 770, 512, 122, 770, 512, - 90, 803, 512, 122, 803, 512, 90, 817, 512, 122, 817, 512, 104, 817, 512, - 116, 776, 512, 119, 778, 512, 121, 778, 514, 97, 702, 512, 383, 775, 512, - 65, 803, 512, 97, 803, 512, 65, 777, 512, 97, 777, 512, 194, 769, 512, - 226, 769, 512, 194, 768, 512, 226, 768, 512, 194, 777, 512, 226, 777, - 512, 194, 771, 512, 226, 771, 512, 7840, 770, 512, 7841, 770, 512, 258, - 769, 512, 259, 769, 512, 258, 768, 512, 259, 768, 512, 258, 777, 512, - 259, 777, 512, 258, 771, 512, 259, 771, 512, 7840, 774, 512, 7841, 774, - 512, 69, 803, 512, 101, 803, 512, 69, 777, 512, 101, 777, 512, 69, 771, - 512, 101, 771, 512, 202, 769, 512, 234, 769, 512, 202, 768, 512, 234, - 768, 512, 202, 777, 512, 234, 777, 512, 202, 771, 512, 234, 771, 512, - 7864, 770, 512, 7865, 770, 512, 73, 777, 512, 105, 777, 512, 73, 803, - 512, 105, 803, 512, 79, 803, 512, 111, 803, 512, 79, 777, 512, 111, 777, - 512, 212, 769, 512, 244, 769, 512, 212, 768, 512, 244, 768, 512, 212, - 777, 512, 244, 777, 512, 212, 771, 512, 244, 771, 512, 7884, 770, 512, - 7885, 770, 512, 416, 769, 512, 417, 769, 512, 416, 768, 512, 417, 768, - 512, 416, 777, 512, 417, 777, 512, 416, 771, 512, 417, 771, 512, 416, - 803, 512, 417, 803, 512, 85, 803, 512, 117, 803, 512, 85, 777, 512, 117, - 777, 512, 431, 769, 512, 432, 769, 512, 431, 768, 512, 432, 768, 512, - 431, 777, 512, 432, 777, 512, 431, 771, 512, 432, 771, 512, 431, 803, - 512, 432, 803, 512, 89, 768, 512, 121, 768, 512, 89, 803, 512, 121, 803, - 512, 89, 777, 512, 121, 777, 512, 89, 771, 512, 121, 771, 512, 945, 787, - 512, 945, 788, 512, 7936, 768, 512, 7937, 768, 512, 7936, 769, 512, 7937, - 769, 512, 7936, 834, 512, 7937, 834, 512, 913, 787, 512, 913, 788, 512, - 7944, 768, 512, 7945, 768, 512, 7944, 769, 512, 7945, 769, 512, 7944, - 834, 512, 7945, 834, 512, 949, 787, 512, 949, 788, 512, 7952, 768, 512, - 7953, 768, 512, 7952, 769, 512, 7953, 769, 512, 917, 787, 512, 917, 788, - 512, 7960, 768, 512, 7961, 768, 512, 7960, 769, 512, 7961, 769, 512, 951, - 787, 512, 951, 788, 512, 7968, 768, 512, 7969, 768, 512, 7968, 769, 512, - 7969, 769, 512, 7968, 834, 512, 7969, 834, 512, 919, 787, 512, 919, 788, - 512, 7976, 768, 512, 7977, 768, 512, 7976, 769, 512, 7977, 769, 512, - 7976, 834, 512, 7977, 834, 512, 953, 787, 512, 953, 788, 512, 7984, 768, - 512, 7985, 768, 512, 7984, 769, 512, 7985, 769, 512, 7984, 834, 512, + 59, 512, 168, 769, 512, 913, 769, 256, 183, 512, 917, 769, 512, 919, 769, + 512, 921, 769, 512, 927, 769, 512, 933, 769, 512, 937, 769, 512, 970, + 769, 512, 921, 776, 512, 933, 776, 512, 945, 769, 512, 949, 769, 512, + 951, 769, 512, 953, 769, 512, 971, 769, 512, 953, 776, 512, 965, 776, + 512, 959, 769, 512, 965, 769, 512, 969, 769, 258, 946, 258, 952, 258, + 933, 512, 978, 769, 512, 978, 776, 258, 966, 258, 960, 258, 954, 258, + 961, 258, 962, 258, 920, 258, 949, 258, 931, 512, 1045, 768, 512, 1045, + 776, 512, 1043, 769, 512, 1030, 776, 512, 1050, 769, 512, 1048, 768, 512, + 1059, 774, 512, 1048, 774, 512, 1080, 774, 512, 1077, 768, 512, 1077, + 776, 512, 1075, 769, 512, 1110, 776, 512, 1082, 769, 512, 1080, 768, 512, + 1091, 774, 512, 1140, 783, 512, 1141, 783, 512, 1046, 774, 512, 1078, + 774, 512, 1040, 774, 512, 1072, 774, 512, 1040, 776, 512, 1072, 776, 512, + 1045, 774, 512, 1077, 774, 512, 1240, 776, 512, 1241, 776, 512, 1046, + 776, 512, 1078, 776, 512, 1047, 776, 512, 1079, 776, 512, 1048, 772, 512, + 1080, 772, 512, 1048, 776, 512, 1080, 776, 512, 1054, 776, 512, 1086, + 776, 512, 1256, 776, 512, 1257, 776, 512, 1069, 776, 512, 1101, 776, 512, + 1059, 772, 512, 1091, 772, 512, 1059, 776, 512, 1091, 776, 512, 1059, + 779, 512, 1091, 779, 512, 1063, 776, 512, 1095, 776, 512, 1067, 776, 512, + 1099, 776, 514, 1381, 1410, 512, 1575, 1619, 512, 1575, 1620, 512, 1608, + 1620, 512, 1575, 1621, 512, 1610, 1620, 514, 1575, 1652, 514, 1608, 1652, + 514, 1735, 1652, 514, 1610, 1652, 512, 1749, 1620, 512, 1729, 1620, 512, + 1746, 1620, 512, 2344, 2364, 512, 2352, 2364, 512, 2355, 2364, 512, 2325, + 2364, 512, 2326, 2364, 512, 2327, 2364, 512, 2332, 2364, 512, 2337, 2364, + 512, 2338, 2364, 512, 2347, 2364, 512, 2351, 2364, 512, 2503, 2494, 512, + 2503, 2519, 512, 2465, 2492, 512, 2466, 2492, 512, 2479, 2492, 512, 2610, + 2620, 512, 2616, 2620, 512, 2582, 2620, 512, 2583, 2620, 512, 2588, 2620, + 512, 2603, 2620, 512, 2887, 2902, 512, 2887, 2878, 512, 2887, 2903, 512, + 2849, 2876, 512, 2850, 2876, 512, 2962, 3031, 512, 3014, 3006, 512, 3015, + 3006, 512, 3014, 3031, 512, 3142, 3158, 512, 3263, 3285, 512, 3270, 3285, + 512, 3270, 3286, 512, 3270, 3266, 512, 3274, 3285, 512, 3398, 3390, 512, + 3399, 3390, 512, 3398, 3415, 512, 3545, 3530, 512, 3545, 3535, 512, 3548, + 3530, 512, 3545, 3551, 514, 3661, 3634, 514, 3789, 3762, 514, 3755, 3737, + 514, 3755, 3745, 257, 3851, 512, 3906, 4023, 512, 3916, 4023, 512, 3921, + 4023, 512, 3926, 4023, 512, 3931, 4023, 512, 3904, 4021, 512, 3953, 3954, + 512, 3953, 3956, 512, 4018, 3968, 514, 4018, 3969, 512, 4019, 3968, 514, + 4019, 3969, 512, 3953, 3968, 512, 3986, 4023, 512, 3996, 4023, 512, 4001, + 4023, 512, 4006, 4023, 512, 4011, 4023, 512, 3984, 4021, 512, 4133, 4142, + 259, 4316, 512, 6917, 6965, 512, 6919, 6965, 512, 6921, 6965, 512, 6923, + 6965, 512, 6925, 6965, 512, 6929, 6965, 512, 6970, 6965, 512, 6972, 6965, + 512, 6974, 6965, 512, 6975, 6965, 512, 6978, 6965, 259, 65, 259, 198, + 259, 66, 259, 68, 259, 69, 259, 398, 259, 71, 259, 72, 259, 73, 259, 74, + 259, 75, 259, 76, 259, 77, 259, 78, 259, 79, 259, 546, 259, 80, 259, 82, + 259, 84, 259, 85, 259, 87, 259, 592, 259, 593, 259, 7426, 259, 98, 259, + 100, 259, 101, 259, 601, 259, 603, 259, 604, 259, 103, 259, 107, 259, + 109, 259, 331, 259, 596, 259, 7446, 259, 7447, 259, 112, 259, 116, 259, + 117, 259, 7453, 259, 623, 259, 118, 259, 7461, 259, 946, 259, 947, 259, + 948, 259, 966, 259, 967, 261, 105, 261, 114, 261, 117, 261, 118, 261, + 946, 261, 947, 261, 961, 261, 966, 261, 967, 259, 1085, 259, 594, 259, + 99, 259, 597, 259, 240, 259, 102, 259, 607, 259, 609, 259, 613, 259, 616, + 259, 617, 259, 618, 259, 7547, 259, 669, 259, 621, 259, 7557, 259, 671, + 259, 625, 259, 624, 259, 626, 259, 627, 259, 628, 259, 629, 259, 632, + 259, 642, 259, 643, 259, 427, 259, 649, 259, 650, 259, 7452, 259, 651, + 259, 652, 259, 122, 259, 656, 259, 657, 259, 658, 259, 952, 512, 65, 805, + 512, 97, 805, 512, 66, 775, 512, 98, 775, 512, 66, 803, 512, 98, 803, + 512, 66, 817, 512, 98, 817, 512, 199, 769, 512, 231, 769, 512, 68, 775, + 512, 100, 775, 512, 68, 803, 512, 100, 803, 512, 68, 817, 512, 100, 817, + 512, 68, 807, 512, 100, 807, 512, 68, 813, 512, 100, 813, 512, 274, 768, + 512, 275, 768, 512, 274, 769, 512, 275, 769, 512, 69, 813, 512, 101, 813, + 512, 69, 816, 512, 101, 816, 512, 552, 774, 512, 553, 774, 512, 70, 775, + 512, 102, 775, 512, 71, 772, 512, 103, 772, 512, 72, 775, 512, 104, 775, + 512, 72, 803, 512, 104, 803, 512, 72, 776, 512, 104, 776, 512, 72, 807, + 512, 104, 807, 512, 72, 814, 512, 104, 814, 512, 73, 816, 512, 105, 816, + 512, 207, 769, 512, 239, 769, 512, 75, 769, 512, 107, 769, 512, 75, 803, + 512, 107, 803, 512, 75, 817, 512, 107, 817, 512, 76, 803, 512, 108, 803, + 512, 7734, 772, 512, 7735, 772, 512, 76, 817, 512, 108, 817, 512, 76, + 813, 512, 108, 813, 512, 77, 769, 512, 109, 769, 512, 77, 775, 512, 109, + 775, 512, 77, 803, 512, 109, 803, 512, 78, 775, 512, 110, 775, 512, 78, + 803, 512, 110, 803, 512, 78, 817, 512, 110, 817, 512, 78, 813, 512, 110, + 813, 512, 213, 769, 512, 245, 769, 512, 213, 776, 512, 245, 776, 512, + 332, 768, 512, 333, 768, 512, 332, 769, 512, 333, 769, 512, 80, 769, 512, + 112, 769, 512, 80, 775, 512, 112, 775, 512, 82, 775, 512, 114, 775, 512, + 82, 803, 512, 114, 803, 512, 7770, 772, 512, 7771, 772, 512, 82, 817, + 512, 114, 817, 512, 83, 775, 512, 115, 775, 512, 83, 803, 512, 115, 803, + 512, 346, 775, 512, 347, 775, 512, 352, 775, 512, 353, 775, 512, 7778, + 775, 512, 7779, 775, 512, 84, 775, 512, 116, 775, 512, 84, 803, 512, 116, + 803, 512, 84, 817, 512, 116, 817, 512, 84, 813, 512, 116, 813, 512, 85, + 804, 512, 117, 804, 512, 85, 816, 512, 117, 816, 512, 85, 813, 512, 117, + 813, 512, 360, 769, 512, 361, 769, 512, 362, 776, 512, 363, 776, 512, 86, + 771, 512, 118, 771, 512, 86, 803, 512, 118, 803, 512, 87, 768, 512, 119, + 768, 512, 87, 769, 512, 119, 769, 512, 87, 776, 512, 119, 776, 512, 87, + 775, 512, 119, 775, 512, 87, 803, 512, 119, 803, 512, 88, 775, 512, 120, + 775, 512, 88, 776, 512, 120, 776, 512, 89, 775, 512, 121, 775, 512, 90, + 770, 512, 122, 770, 512, 90, 803, 512, 122, 803, 512, 90, 817, 512, 122, + 817, 512, 104, 817, 512, 116, 776, 512, 119, 778, 512, 121, 778, 514, 97, + 702, 512, 383, 775, 512, 65, 803, 512, 97, 803, 512, 65, 777, 512, 97, + 777, 512, 194, 769, 512, 226, 769, 512, 194, 768, 512, 226, 768, 512, + 194, 777, 512, 226, 777, 512, 194, 771, 512, 226, 771, 512, 7840, 770, + 512, 7841, 770, 512, 258, 769, 512, 259, 769, 512, 258, 768, 512, 259, + 768, 512, 258, 777, 512, 259, 777, 512, 258, 771, 512, 259, 771, 512, + 7840, 774, 512, 7841, 774, 512, 69, 803, 512, 101, 803, 512, 69, 777, + 512, 101, 777, 512, 69, 771, 512, 101, 771, 512, 202, 769, 512, 234, 769, + 512, 202, 768, 512, 234, 768, 512, 202, 777, 512, 234, 777, 512, 202, + 771, 512, 234, 771, 512, 7864, 770, 512, 7865, 770, 512, 73, 777, 512, + 105, 777, 512, 73, 803, 512, 105, 803, 512, 79, 803, 512, 111, 803, 512, + 79, 777, 512, 111, 777, 512, 212, 769, 512, 244, 769, 512, 212, 768, 512, + 244, 768, 512, 212, 777, 512, 244, 777, 512, 212, 771, 512, 244, 771, + 512, 7884, 770, 512, 7885, 770, 512, 416, 769, 512, 417, 769, 512, 416, + 768, 512, 417, 768, 512, 416, 777, 512, 417, 777, 512, 416, 771, 512, + 417, 771, 512, 416, 803, 512, 417, 803, 512, 85, 803, 512, 117, 803, 512, + 85, 777, 512, 117, 777, 512, 431, 769, 512, 432, 769, 512, 431, 768, 512, + 432, 768, 512, 431, 777, 512, 432, 777, 512, 431, 771, 512, 432, 771, + 512, 431, 803, 512, 432, 803, 512, 89, 768, 512, 121, 768, 512, 89, 803, + 512, 121, 803, 512, 89, 777, 512, 121, 777, 512, 89, 771, 512, 121, 771, + 512, 945, 787, 512, 945, 788, 512, 7936, 768, 512, 7937, 768, 512, 7936, + 769, 512, 7937, 769, 512, 7936, 834, 512, 7937, 834, 512, 913, 787, 512, + 913, 788, 512, 7944, 768, 512, 7945, 768, 512, 7944, 769, 512, 7945, 769, + 512, 7944, 834, 512, 7945, 834, 512, 949, 787, 512, 949, 788, 512, 7952, + 768, 512, 7953, 768, 512, 7952, 769, 512, 7953, 769, 512, 917, 787, 512, + 917, 788, 512, 7960, 768, 512, 7961, 768, 512, 7960, 769, 512, 7961, 769, + 512, 951, 787, 512, 951, 788, 512, 7968, 768, 512, 7969, 768, 512, 7968, + 769, 512, 7969, 769, 512, 7968, 834, 512, 7969, 834, 512, 919, 787, 512, + 919, 788, 512, 7976, 768, 512, 7977, 768, 512, 7976, 769, 512, 7977, 769, + 512, 7976, 834, 512, 7977, 834, 512, 953, 787, 512, 953, 788, 512, 7984, + 768, 512, 7985, 768, 512, 7984, 769, 512, 7985, 769, 512, 7984, 834, 512, 7985, 834, 512, 921, 787, 512, 921, 788, 512, 7992, 768, 512, 7993, 768, 512, 7992, 769, 512, 7993, 769, 512, 7992, 834, 512, 7993, 834, 512, 959, 787, 512, 959, 788, 512, 8000, 768, 512, 8001, 768, 512, 8000, 769, 512, @@ -3561,124 +3623,121 @@ static const unsigned int decomp_data[] = { 8045, 837, 512, 8046, 837, 512, 8047, 837, 512, 945, 774, 512, 945, 772, 512, 8048, 837, 512, 945, 837, 512, 940, 837, 512, 945, 834, 512, 8118, 837, 512, 913, 774, 512, 913, 772, 512, 913, 768, 256, 902, 512, 913, - 837, 514, 32, 787, 256, 953, 514, 32, 787, 514, 32, 834, 512, 168, 834, - 512, 8052, 837, 512, 951, 837, 512, 942, 837, 512, 951, 834, 512, 8134, - 837, 512, 917, 768, 256, 904, 512, 919, 768, 256, 905, 512, 919, 837, - 512, 8127, 768, 512, 8127, 769, 512, 8127, 834, 512, 953, 774, 512, 953, - 772, 512, 970, 768, 256, 912, 512, 953, 834, 512, 970, 834, 512, 921, - 774, 512, 921, 772, 512, 921, 768, 256, 906, 512, 8190, 768, 512, 8190, - 769, 512, 8190, 834, 512, 965, 774, 512, 965, 772, 512, 971, 768, 256, - 944, 512, 961, 787, 512, 961, 788, 512, 965, 834, 512, 971, 834, 512, - 933, 774, 512, 933, 772, 512, 933, 768, 256, 910, 512, 929, 788, 512, - 168, 768, 256, 901, 256, 96, 512, 8060, 837, 512, 969, 837, 512, 974, - 837, 512, 969, 834, 512, 8182, 837, 512, 927, 768, 256, 908, 512, 937, - 768, 256, 911, 512, 937, 837, 256, 180, 514, 32, 788, 256, 8194, 256, - 8195, 258, 32, 258, 32, 258, 32, 258, 32, 258, 32, 257, 32, 258, 32, 258, - 32, 258, 32, 257, 8208, 514, 32, 819, 258, 46, 514, 46, 46, 770, 46, 46, - 46, 257, 32, 514, 8242, 8242, 770, 8242, 8242, 8242, 514, 8245, 8245, - 770, 8245, 8245, 8245, 514, 33, 33, 514, 32, 773, 514, 63, 63, 514, 63, - 33, 514, 33, 63, 1026, 8242, 8242, 8242, 8242, 258, 32, 259, 48, 259, - 105, 259, 52, 259, 53, 259, 54, 259, 55, 259, 56, 259, 57, 259, 43, 259, - 8722, 259, 61, 259, 40, 259, 41, 259, 110, 261, 48, 261, 49, 261, 50, - 261, 51, 261, 52, 261, 53, 261, 54, 261, 55, 261, 56, 261, 57, 261, 43, - 261, 8722, 261, 61, 261, 40, 261, 41, 261, 97, 261, 101, 261, 111, 261, - 120, 261, 601, 261, 104, 261, 107, 261, 108, 261, 109, 261, 110, 261, - 112, 261, 115, 261, 116, 514, 82, 115, 770, 97, 47, 99, 770, 97, 47, 115, - 262, 67, 514, 176, 67, 770, 99, 47, 111, 770, 99, 47, 117, 258, 400, 514, - 176, 70, 262, 103, 262, 72, 262, 72, 262, 72, 262, 104, 262, 295, 262, - 73, 262, 73, 262, 76, 262, 108, 262, 78, 514, 78, 111, 262, 80, 262, 81, - 262, 82, 262, 82, 262, 82, 515, 83, 77, 770, 84, 69, 76, 515, 84, 77, - 262, 90, 256, 937, 262, 90, 256, 75, 256, 197, 262, 66, 262, 67, 262, - 101, 262, 69, 262, 70, 262, 77, 262, 111, 258, 1488, 258, 1489, 258, - 1490, 258, 1491, 262, 105, 770, 70, 65, 88, 262, 960, 262, 947, 262, 915, - 262, 928, 262, 8721, 262, 68, 262, 100, 262, 101, 262, 105, 262, 106, - 772, 49, 8260, 55, 772, 49, 8260, 57, 1028, 49, 8260, 49, 48, 772, 49, - 8260, 51, 772, 50, 8260, 51, 772, 49, 8260, 53, 772, 50, 8260, 53, 772, - 51, 8260, 53, 772, 52, 8260, 53, 772, 49, 8260, 54, 772, 53, 8260, 54, - 772, 49, 8260, 56, 772, 51, 8260, 56, 772, 53, 8260, 56, 772, 55, 8260, - 56, 516, 49, 8260, 258, 73, 514, 73, 73, 770, 73, 73, 73, 514, 73, 86, - 258, 86, 514, 86, 73, 770, 86, 73, 73, 1026, 86, 73, 73, 73, 514, 73, 88, - 258, 88, 514, 88, 73, 770, 88, 73, 73, 258, 76, 258, 67, 258, 68, 258, - 77, 258, 105, 514, 105, 105, 770, 105, 105, 105, 514, 105, 118, 258, 118, - 514, 118, 105, 770, 118, 105, 105, 1026, 118, 105, 105, 105, 514, 105, - 120, 258, 120, 514, 120, 105, 770, 120, 105, 105, 258, 108, 258, 99, 258, - 100, 258, 109, 772, 48, 8260, 51, 512, 8592, 824, 512, 8594, 824, 512, - 8596, 824, 512, 8656, 824, 512, 8660, 824, 512, 8658, 824, 512, 8707, - 824, 512, 8712, 824, 512, 8715, 824, 512, 8739, 824, 512, 8741, 824, 514, - 8747, 8747, 770, 8747, 8747, 8747, 514, 8750, 8750, 770, 8750, 8750, - 8750, 512, 8764, 824, 512, 8771, 824, 512, 8773, 824, 512, 8776, 824, - 512, 61, 824, 512, 8801, 824, 512, 8781, 824, 512, 60, 824, 512, 62, 824, - 512, 8804, 824, 512, 8805, 824, 512, 8818, 824, 512, 8819, 824, 512, - 8822, 824, 512, 8823, 824, 512, 8826, 824, 512, 8827, 824, 512, 8834, - 824, 512, 8835, 824, 512, 8838, 824, 512, 8839, 824, 512, 8866, 824, 512, - 8872, 824, 512, 8873, 824, 512, 8875, 824, 512, 8828, 824, 512, 8829, - 824, 512, 8849, 824, 512, 8850, 824, 512, 8882, 824, 512, 8883, 824, 512, - 8884, 824, 512, 8885, 824, 256, 12296, 256, 12297, 263, 49, 263, 50, 263, - 51, 263, 52, 263, 53, 263, 54, 263, 55, 263, 56, 263, 57, 519, 49, 48, - 519, 49, 49, 519, 49, 50, 519, 49, 51, 519, 49, 52, 519, 49, 53, 519, 49, - 54, 519, 49, 55, 519, 49, 56, 519, 49, 57, 519, 50, 48, 770, 40, 49, 41, - 770, 40, 50, 41, 770, 40, 51, 41, 770, 40, 52, 41, 770, 40, 53, 41, 770, - 40, 54, 41, 770, 40, 55, 41, 770, 40, 56, 41, 770, 40, 57, 41, 1026, 40, - 49, 48, 41, 1026, 40, 49, 49, 41, 1026, 40, 49, 50, 41, 1026, 40, 49, 51, - 41, 1026, 40, 49, 52, 41, 1026, 40, 49, 53, 41, 1026, 40, 49, 54, 41, - 1026, 40, 49, 55, 41, 1026, 40, 49, 56, 41, 1026, 40, 49, 57, 41, 1026, - 40, 50, 48, 41, 514, 49, 46, 514, 50, 46, 514, 51, 46, 514, 52, 46, 514, - 53, 46, 514, 54, 46, 514, 55, 46, 514, 56, 46, 514, 57, 46, 770, 49, 48, - 46, 770, 49, 49, 46, 770, 49, 50, 46, 770, 49, 51, 46, 770, 49, 52, 46, - 770, 49, 53, 46, 770, 49, 54, 46, 770, 49, 55, 46, 770, 49, 56, 46, 770, - 49, 57, 46, 770, 50, 48, 46, 770, 40, 97, 41, 770, 40, 98, 41, 770, 40, - 99, 41, 770, 40, 100, 41, 770, 40, 101, 41, 770, 40, 102, 41, 770, 40, - 103, 41, 770, 40, 104, 41, 770, 40, 105, 41, 770, 40, 106, 41, 770, 40, - 107, 41, 770, 40, 108, 41, 770, 40, 109, 41, 770, 40, 110, 41, 770, 40, - 111, 41, 770, 40, 112, 41, 770, 40, 113, 41, 770, 40, 114, 41, 770, 40, - 115, 41, 770, 40, 116, 41, 770, 40, 117, 41, 770, 40, 118, 41, 770, 40, - 119, 41, 770, 40, 120, 41, 770, 40, 121, 41, 770, 40, 122, 41, 263, 65, - 263, 66, 263, 67, 263, 68, 263, 69, 263, 70, 263, 71, 263, 72, 263, 73, - 263, 74, 263, 75, 263, 76, 263, 77, 263, 78, 263, 79, 263, 80, 263, 81, - 263, 82, 263, 83, 263, 84, 263, 85, 263, 86, 263, 87, 263, 88, 263, 89, - 263, 90, 263, 97, 263, 98, 263, 99, 263, 100, 263, 101, 263, 102, 263, - 103, 263, 104, 263, 105, 263, 106, 263, 107, 263, 108, 263, 109, 263, - 110, 263, 111, 263, 112, 263, 113, 263, 114, 263, 115, 263, 116, 263, - 117, 263, 118, 263, 119, 263, 120, 263, 121, 263, 122, 263, 48, 1026, - 8747, 8747, 8747, 8747, 770, 58, 58, 61, 514, 61, 61, 770, 61, 61, 61, - 512, 10973, 824, 261, 106, 259, 86, 259, 11617, 258, 27597, 258, 40863, - 258, 19968, 258, 20008, 258, 20022, 258, 20031, 258, 20057, 258, 20101, - 258, 20108, 258, 20128, 258, 20154, 258, 20799, 258, 20837, 258, 20843, - 258, 20866, 258, 20886, 258, 20907, 258, 20960, 258, 20981, 258, 20992, - 258, 21147, 258, 21241, 258, 21269, 258, 21274, 258, 21304, 258, 21313, - 258, 21340, 258, 21353, 258, 21378, 258, 21430, 258, 21448, 258, 21475, - 258, 22231, 258, 22303, 258, 22763, 258, 22786, 258, 22794, 258, 22805, - 258, 22823, 258, 22899, 258, 23376, 258, 23424, 258, 23544, 258, 23567, - 258, 23586, 258, 23608, 258, 23662, 258, 23665, 258, 24027, 258, 24037, - 258, 24049, 258, 24062, 258, 24178, 258, 24186, 258, 24191, 258, 24308, - 258, 24318, 258, 24331, 258, 24339, 258, 24400, 258, 24417, 258, 24435, - 258, 24515, 258, 25096, 258, 25142, 258, 25163, 258, 25903, 258, 25908, - 258, 25991, 258, 26007, 258, 26020, 258, 26041, 258, 26080, 258, 26085, - 258, 26352, 258, 26376, 258, 26408, 258, 27424, 258, 27490, 258, 27513, - 258, 27571, 258, 27595, 258, 27604, 258, 27611, 258, 27663, 258, 27668, - 258, 27700, 258, 28779, 258, 29226, 258, 29238, 258, 29243, 258, 29247, - 258, 29255, 258, 29273, 258, 29275, 258, 29356, 258, 29572, 258, 29577, - 258, 29916, 258, 29926, 258, 29976, 258, 29983, 258, 29992, 258, 30000, - 258, 30091, 258, 30098, 258, 30326, 258, 30333, 258, 30382, 258, 30399, - 258, 30446, 258, 30683, 258, 30690, 258, 30707, 258, 31034, 258, 31160, - 258, 31166, 258, 31348, 258, 31435, 258, 31481, 258, 31859, 258, 31992, - 258, 32566, 258, 32593, 258, 32650, 258, 32701, 258, 32769, 258, 32780, - 258, 32786, 258, 32819, 258, 32895, 258, 32905, 258, 33251, 258, 33258, - 258, 33267, 258, 33276, 258, 33292, 258, 33307, 258, 33311, 258, 33390, - 258, 33394, 258, 33400, 258, 34381, 258, 34411, 258, 34880, 258, 34892, - 258, 34915, 258, 35198, 258, 35211, 258, 35282, 258, 35328, 258, 35895, - 258, 35910, 258, 35925, 258, 35960, 258, 35997, 258, 36196, 258, 36208, - 258, 36275, 258, 36523, 258, 36554, 258, 36763, 258, 36784, 258, 36789, - 258, 37009, 258, 37193, 258, 37318, 258, 37324, 258, 37329, 258, 38263, - 258, 38272, 258, 38428, 258, 38582, 258, 38585, 258, 38632, 258, 38737, - 258, 38750, 258, 38754, 258, 38761, 258, 38859, 258, 38893, 258, 38899, - 258, 38913, 258, 39080, 258, 39131, 258, 39135, 258, 39318, 258, 39321, - 258, 39340, 258, 39592, 258, 39640, 258, 39647, 258, 39717, 258, 39727, - 258, 39730, 258, 39740, 258, 39770, 258, 40165, 258, 40565, 258, 40575, - 258, 40613, 258, 40635, 258, 40643, 258, 40653, 258, 40657, 258, 40697, - 258, 40701, 258, 40718, 258, 40723, 258, 40736, 258, 40763, 258, 40778, - 258, 40786, 258, 40845, 258, 40860, 258, 40864, 264, 32, 258, 12306, 258, - 21313, 258, 21316, 258, 21317, 512, 12363, 12441, 512, 12365, 12441, 512, + 837, 514, 32, 787, 256, 953, 514, 32, 834, 512, 168, 834, 512, 8052, 837, + 512, 951, 837, 512, 942, 837, 512, 951, 834, 512, 8134, 837, 512, 917, + 768, 256, 904, 512, 919, 768, 256, 905, 512, 919, 837, 512, 8127, 768, + 512, 8127, 769, 512, 8127, 834, 512, 953, 774, 512, 953, 772, 512, 970, + 768, 256, 912, 512, 953, 834, 512, 970, 834, 512, 921, 774, 512, 921, + 772, 512, 921, 768, 256, 906, 512, 8190, 768, 512, 8190, 769, 512, 8190, + 834, 512, 965, 774, 512, 965, 772, 512, 971, 768, 256, 944, 512, 961, + 787, 512, 961, 788, 512, 965, 834, 512, 971, 834, 512, 933, 774, 512, + 933, 772, 512, 933, 768, 256, 910, 512, 929, 788, 512, 168, 768, 256, + 901, 256, 96, 512, 8060, 837, 512, 969, 837, 512, 974, 837, 512, 969, + 834, 512, 8182, 837, 512, 927, 768, 256, 908, 512, 937, 768, 256, 911, + 512, 937, 837, 256, 180, 514, 32, 788, 256, 8194, 256, 8195, 258, 32, + 257, 8208, 514, 32, 819, 258, 46, 514, 46, 46, 770, 46, 46, 46, 514, + 8242, 8242, 770, 8242, 8242, 8242, 514, 8245, 8245, 770, 8245, 8245, + 8245, 514, 33, 33, 514, 32, 773, 514, 63, 63, 514, 63, 33, 514, 33, 63, + 1026, 8242, 8242, 8242, 8242, 259, 48, 259, 105, 259, 52, 259, 53, 259, + 54, 259, 55, 259, 56, 259, 57, 259, 43, 259, 8722, 259, 61, 259, 40, 259, + 41, 259, 110, 261, 48, 261, 49, 261, 50, 261, 51, 261, 52, 261, 53, 261, + 54, 261, 55, 261, 56, 261, 57, 261, 43, 261, 8722, 261, 61, 261, 40, 261, + 41, 261, 97, 261, 101, 261, 111, 261, 120, 261, 601, 261, 104, 261, 107, + 261, 108, 261, 109, 261, 110, 261, 112, 261, 115, 261, 116, 514, 82, 115, + 770, 97, 47, 99, 770, 97, 47, 115, 262, 67, 514, 176, 67, 770, 99, 47, + 111, 770, 99, 47, 117, 258, 400, 514, 176, 70, 262, 103, 262, 72, 262, + 104, 262, 295, 262, 73, 262, 76, 262, 108, 262, 78, 514, 78, 111, 262, + 80, 262, 81, 262, 82, 515, 83, 77, 770, 84, 69, 76, 515, 84, 77, 262, 90, + 256, 937, 256, 75, 256, 197, 262, 66, 262, 101, 262, 69, 262, 70, 262, + 77, 262, 111, 258, 1488, 258, 1489, 258, 1490, 258, 1491, 262, 105, 770, + 70, 65, 88, 262, 960, 262, 947, 262, 915, 262, 928, 262, 8721, 262, 68, + 262, 100, 262, 106, 772, 49, 8260, 55, 772, 49, 8260, 57, 1028, 49, 8260, + 49, 48, 772, 49, 8260, 51, 772, 50, 8260, 51, 772, 49, 8260, 53, 772, 50, + 8260, 53, 772, 51, 8260, 53, 772, 52, 8260, 53, 772, 49, 8260, 54, 772, + 53, 8260, 54, 772, 49, 8260, 56, 772, 51, 8260, 56, 772, 53, 8260, 56, + 772, 55, 8260, 56, 516, 49, 8260, 258, 73, 514, 73, 73, 770, 73, 73, 73, + 514, 73, 86, 258, 86, 514, 86, 73, 770, 86, 73, 73, 1026, 86, 73, 73, 73, + 514, 73, 88, 258, 88, 514, 88, 73, 770, 88, 73, 73, 258, 76, 258, 67, + 258, 68, 258, 77, 258, 105, 514, 105, 105, 770, 105, 105, 105, 514, 105, + 118, 258, 118, 514, 118, 105, 770, 118, 105, 105, 1026, 118, 105, 105, + 105, 514, 105, 120, 258, 120, 514, 120, 105, 770, 120, 105, 105, 258, + 108, 258, 99, 258, 100, 258, 109, 772, 48, 8260, 51, 512, 8592, 824, 512, + 8594, 824, 512, 8596, 824, 512, 8656, 824, 512, 8660, 824, 512, 8658, + 824, 512, 8707, 824, 512, 8712, 824, 512, 8715, 824, 512, 8739, 824, 512, + 8741, 824, 514, 8747, 8747, 770, 8747, 8747, 8747, 514, 8750, 8750, 770, + 8750, 8750, 8750, 512, 8764, 824, 512, 8771, 824, 512, 8773, 824, 512, + 8776, 824, 512, 61, 824, 512, 8801, 824, 512, 8781, 824, 512, 60, 824, + 512, 62, 824, 512, 8804, 824, 512, 8805, 824, 512, 8818, 824, 512, 8819, + 824, 512, 8822, 824, 512, 8823, 824, 512, 8826, 824, 512, 8827, 824, 512, + 8834, 824, 512, 8835, 824, 512, 8838, 824, 512, 8839, 824, 512, 8866, + 824, 512, 8872, 824, 512, 8873, 824, 512, 8875, 824, 512, 8828, 824, 512, + 8829, 824, 512, 8849, 824, 512, 8850, 824, 512, 8882, 824, 512, 8883, + 824, 512, 8884, 824, 512, 8885, 824, 256, 12296, 256, 12297, 263, 49, + 263, 50, 263, 51, 263, 52, 263, 53, 263, 54, 263, 55, 263, 56, 263, 57, + 519, 49, 48, 519, 49, 49, 519, 49, 50, 519, 49, 51, 519, 49, 52, 519, 49, + 53, 519, 49, 54, 519, 49, 55, 519, 49, 56, 519, 49, 57, 519, 50, 48, 770, + 40, 49, 41, 770, 40, 50, 41, 770, 40, 51, 41, 770, 40, 52, 41, 770, 40, + 53, 41, 770, 40, 54, 41, 770, 40, 55, 41, 770, 40, 56, 41, 770, 40, 57, + 41, 1026, 40, 49, 48, 41, 1026, 40, 49, 49, 41, 1026, 40, 49, 50, 41, + 1026, 40, 49, 51, 41, 1026, 40, 49, 52, 41, 1026, 40, 49, 53, 41, 1026, + 40, 49, 54, 41, 1026, 40, 49, 55, 41, 1026, 40, 49, 56, 41, 1026, 40, 49, + 57, 41, 1026, 40, 50, 48, 41, 514, 49, 46, 514, 50, 46, 514, 51, 46, 514, + 52, 46, 514, 53, 46, 514, 54, 46, 514, 55, 46, 514, 56, 46, 514, 57, 46, + 770, 49, 48, 46, 770, 49, 49, 46, 770, 49, 50, 46, 770, 49, 51, 46, 770, + 49, 52, 46, 770, 49, 53, 46, 770, 49, 54, 46, 770, 49, 55, 46, 770, 49, + 56, 46, 770, 49, 57, 46, 770, 50, 48, 46, 770, 40, 97, 41, 770, 40, 98, + 41, 770, 40, 99, 41, 770, 40, 100, 41, 770, 40, 101, 41, 770, 40, 102, + 41, 770, 40, 103, 41, 770, 40, 104, 41, 770, 40, 105, 41, 770, 40, 106, + 41, 770, 40, 107, 41, 770, 40, 108, 41, 770, 40, 109, 41, 770, 40, 110, + 41, 770, 40, 111, 41, 770, 40, 112, 41, 770, 40, 113, 41, 770, 40, 114, + 41, 770, 40, 115, 41, 770, 40, 116, 41, 770, 40, 117, 41, 770, 40, 118, + 41, 770, 40, 119, 41, 770, 40, 120, 41, 770, 40, 121, 41, 770, 40, 122, + 41, 263, 65, 263, 66, 263, 67, 263, 68, 263, 69, 263, 70, 263, 71, 263, + 72, 263, 73, 263, 74, 263, 75, 263, 76, 263, 77, 263, 78, 263, 79, 263, + 80, 263, 81, 263, 82, 263, 83, 263, 84, 263, 85, 263, 86, 263, 87, 263, + 88, 263, 89, 263, 90, 263, 97, 263, 98, 263, 99, 263, 100, 263, 101, 263, + 102, 263, 103, 263, 104, 263, 105, 263, 106, 263, 107, 263, 108, 263, + 109, 263, 110, 263, 111, 263, 112, 263, 113, 263, 114, 263, 115, 263, + 116, 263, 117, 263, 118, 263, 119, 263, 120, 263, 121, 263, 122, 263, 48, + 1026, 8747, 8747, 8747, 8747, 770, 58, 58, 61, 514, 61, 61, 770, 61, 61, + 61, 512, 10973, 824, 261, 106, 259, 86, 259, 11617, 258, 27597, 258, + 40863, 258, 19968, 258, 20008, 258, 20022, 258, 20031, 258, 20057, 258, + 20101, 258, 20108, 258, 20128, 258, 20154, 258, 20799, 258, 20837, 258, + 20843, 258, 20866, 258, 20886, 258, 20907, 258, 20960, 258, 20981, 258, + 20992, 258, 21147, 258, 21241, 258, 21269, 258, 21274, 258, 21304, 258, + 21313, 258, 21340, 258, 21353, 258, 21378, 258, 21430, 258, 21448, 258, + 21475, 258, 22231, 258, 22303, 258, 22763, 258, 22786, 258, 22794, 258, + 22805, 258, 22823, 258, 22899, 258, 23376, 258, 23424, 258, 23544, 258, + 23567, 258, 23586, 258, 23608, 258, 23662, 258, 23665, 258, 24027, 258, + 24037, 258, 24049, 258, 24062, 258, 24178, 258, 24186, 258, 24191, 258, + 24308, 258, 24318, 258, 24331, 258, 24339, 258, 24400, 258, 24417, 258, + 24435, 258, 24515, 258, 25096, 258, 25142, 258, 25163, 258, 25903, 258, + 25908, 258, 25991, 258, 26007, 258, 26020, 258, 26041, 258, 26080, 258, + 26085, 258, 26352, 258, 26376, 258, 26408, 258, 27424, 258, 27490, 258, + 27513, 258, 27571, 258, 27595, 258, 27604, 258, 27611, 258, 27663, 258, + 27668, 258, 27700, 258, 28779, 258, 29226, 258, 29238, 258, 29243, 258, + 29247, 258, 29255, 258, 29273, 258, 29275, 258, 29356, 258, 29572, 258, + 29577, 258, 29916, 258, 29926, 258, 29976, 258, 29983, 258, 29992, 258, + 30000, 258, 30091, 258, 30098, 258, 30326, 258, 30333, 258, 30382, 258, + 30399, 258, 30446, 258, 30683, 258, 30690, 258, 30707, 258, 31034, 258, + 31160, 258, 31166, 258, 31348, 258, 31435, 258, 31481, 258, 31859, 258, + 31992, 258, 32566, 258, 32593, 258, 32650, 258, 32701, 258, 32769, 258, + 32780, 258, 32786, 258, 32819, 258, 32895, 258, 32905, 258, 33251, 258, + 33258, 258, 33267, 258, 33276, 258, 33292, 258, 33307, 258, 33311, 258, + 33390, 258, 33394, 258, 33400, 258, 34381, 258, 34411, 258, 34880, 258, + 34892, 258, 34915, 258, 35198, 258, 35211, 258, 35282, 258, 35328, 258, + 35895, 258, 35910, 258, 35925, 258, 35960, 258, 35997, 258, 36196, 258, + 36208, 258, 36275, 258, 36523, 258, 36554, 258, 36763, 258, 36784, 258, + 36789, 258, 37009, 258, 37193, 258, 37318, 258, 37324, 258, 37329, 258, + 38263, 258, 38272, 258, 38428, 258, 38582, 258, 38585, 258, 38632, 258, + 38737, 258, 38750, 258, 38754, 258, 38761, 258, 38859, 258, 38893, 258, + 38899, 258, 38913, 258, 39080, 258, 39131, 258, 39135, 258, 39318, 258, + 39321, 258, 39340, 258, 39592, 258, 39640, 258, 39647, 258, 39717, 258, + 39727, 258, 39730, 258, 39740, 258, 39770, 258, 40165, 258, 40565, 258, + 40575, 258, 40613, 258, 40635, 258, 40643, 258, 40653, 258, 40657, 258, + 40697, 258, 40701, 258, 40718, 258, 40723, 258, 40736, 258, 40763, 258, + 40778, 258, 40786, 258, 40845, 258, 40860, 258, 40864, 264, 32, 258, + 12306, 258, 21316, 258, 21317, 512, 12363, 12441, 512, 12365, 12441, 512, 12367, 12441, 512, 12369, 12441, 512, 12371, 12441, 512, 12373, 12441, 512, 12375, 12441, 512, 12377, 12441, 512, 12379, 12441, 512, 12381, 12441, 512, 12383, 12441, 512, 12385, 12441, 512, 12388, 12441, 512, @@ -3844,43 +3903,42 @@ static const unsigned int decomp_data[] = { 51, 49, 26085, 778, 103, 97, 108, 259, 1098, 259, 1100, 259, 42863, 259, 67, 259, 70, 259, 81, 259, 294, 259, 339, 259, 42791, 259, 43831, 259, 619, 259, 43858, 259, 653, 256, 35912, 256, 26356, 256, 36554, 256, - 36040, 256, 28369, 256, 20018, 256, 21477, 256, 40860, 256, 40860, 256, - 22865, 256, 37329, 256, 21895, 256, 22856, 256, 25078, 256, 30313, 256, - 32645, 256, 34367, 256, 34746, 256, 35064, 256, 37007, 256, 27138, 256, - 27931, 256, 28889, 256, 29662, 256, 33853, 256, 37226, 256, 39409, 256, - 20098, 256, 21365, 256, 27396, 256, 29211, 256, 34349, 256, 40478, 256, - 23888, 256, 28651, 256, 34253, 256, 35172, 256, 25289, 256, 33240, 256, - 34847, 256, 24266, 256, 26391, 256, 28010, 256, 29436, 256, 37070, 256, - 20358, 256, 20919, 256, 21214, 256, 25796, 256, 27347, 256, 29200, 256, - 30439, 256, 32769, 256, 34310, 256, 34396, 256, 36335, 256, 38706, 256, - 39791, 256, 40442, 256, 30860, 256, 31103, 256, 32160, 256, 33737, 256, - 37636, 256, 40575, 256, 35542, 256, 22751, 256, 24324, 256, 31840, 256, - 32894, 256, 29282, 256, 30922, 256, 36034, 256, 38647, 256, 22744, 256, - 23650, 256, 27155, 256, 28122, 256, 28431, 256, 32047, 256, 32311, 256, - 38475, 256, 21202, 256, 32907, 256, 20956, 256, 20940, 256, 31260, 256, - 32190, 256, 33777, 256, 38517, 256, 35712, 256, 25295, 256, 27138, 256, - 35582, 256, 20025, 256, 23527, 256, 24594, 256, 29575, 256, 30064, 256, - 21271, 256, 30971, 256, 20415, 256, 24489, 256, 19981, 256, 27852, 256, - 25976, 256, 32034, 256, 21443, 256, 22622, 256, 30465, 256, 33865, 256, - 35498, 256, 27578, 256, 36784, 256, 27784, 256, 25342, 256, 33509, 256, - 25504, 256, 30053, 256, 20142, 256, 20841, 256, 20937, 256, 26753, 256, - 31975, 256, 33391, 256, 35538, 256, 37327, 256, 21237, 256, 21570, 256, - 22899, 256, 24300, 256, 26053, 256, 28670, 256, 31018, 256, 38317, 256, - 39530, 256, 40599, 256, 40654, 256, 21147, 256, 26310, 256, 27511, 256, - 36706, 256, 24180, 256, 24976, 256, 25088, 256, 25754, 256, 28451, 256, - 29001, 256, 29833, 256, 31178, 256, 32244, 256, 32879, 256, 36646, 256, - 34030, 256, 36899, 256, 37706, 256, 21015, 256, 21155, 256, 21693, 256, - 28872, 256, 35010, 256, 35498, 256, 24265, 256, 24565, 256, 25467, 256, - 27566, 256, 31806, 256, 29557, 256, 20196, 256, 22265, 256, 23527, 256, - 23994, 256, 24604, 256, 29618, 256, 29801, 256, 32666, 256, 32838, 256, - 37428, 256, 38646, 256, 38728, 256, 38936, 256, 20363, 256, 31150, 256, - 37300, 256, 38584, 256, 24801, 256, 20102, 256, 20698, 256, 23534, 256, - 23615, 256, 26009, 256, 27138, 256, 29134, 256, 30274, 256, 34044, 256, - 36988, 256, 40845, 256, 26248, 256, 38446, 256, 21129, 256, 26491, 256, - 26611, 256, 27969, 256, 28316, 256, 29705, 256, 30041, 256, 30827, 256, - 32016, 256, 39006, 256, 20845, 256, 25134, 256, 38520, 256, 20523, 256, - 23833, 256, 28138, 256, 36650, 256, 24459, 256, 24900, 256, 26647, 256, - 29575, 256, 38534, 256, 21033, 256, 21519, 256, 23653, 256, 26131, 256, + 36040, 256, 28369, 256, 20018, 256, 21477, 256, 40860, 256, 22865, 256, + 37329, 256, 21895, 256, 22856, 256, 25078, 256, 30313, 256, 32645, 256, + 34367, 256, 34746, 256, 35064, 256, 37007, 256, 27138, 256, 27931, 256, + 28889, 256, 29662, 256, 33853, 256, 37226, 256, 39409, 256, 20098, 256, + 21365, 256, 27396, 256, 29211, 256, 34349, 256, 40478, 256, 23888, 256, + 28651, 256, 34253, 256, 35172, 256, 25289, 256, 33240, 256, 34847, 256, + 24266, 256, 26391, 256, 28010, 256, 29436, 256, 37070, 256, 20358, 256, + 20919, 256, 21214, 256, 25796, 256, 27347, 256, 29200, 256, 30439, 256, + 32769, 256, 34310, 256, 34396, 256, 36335, 256, 38706, 256, 39791, 256, + 40442, 256, 30860, 256, 31103, 256, 32160, 256, 33737, 256, 37636, 256, + 40575, 256, 35542, 256, 22751, 256, 24324, 256, 31840, 256, 32894, 256, + 29282, 256, 30922, 256, 36034, 256, 38647, 256, 22744, 256, 23650, 256, + 27155, 256, 28122, 256, 28431, 256, 32047, 256, 32311, 256, 38475, 256, + 21202, 256, 32907, 256, 20956, 256, 20940, 256, 31260, 256, 32190, 256, + 33777, 256, 38517, 256, 35712, 256, 25295, 256, 35582, 256, 20025, 256, + 23527, 256, 24594, 256, 29575, 256, 30064, 256, 21271, 256, 30971, 256, + 20415, 256, 24489, 256, 19981, 256, 27852, 256, 25976, 256, 32034, 256, + 21443, 256, 22622, 256, 30465, 256, 33865, 256, 35498, 256, 27578, 256, + 36784, 256, 27784, 256, 25342, 256, 33509, 256, 25504, 256, 30053, 256, + 20142, 256, 20841, 256, 20937, 256, 26753, 256, 31975, 256, 33391, 256, + 35538, 256, 37327, 256, 21237, 256, 21570, 256, 22899, 256, 24300, 256, + 26053, 256, 28670, 256, 31018, 256, 38317, 256, 39530, 256, 40599, 256, + 40654, 256, 21147, 256, 26310, 256, 27511, 256, 36706, 256, 24180, 256, + 24976, 256, 25088, 256, 25754, 256, 28451, 256, 29001, 256, 29833, 256, + 31178, 256, 32244, 256, 32879, 256, 36646, 256, 34030, 256, 36899, 256, + 37706, 256, 21015, 256, 21155, 256, 21693, 256, 28872, 256, 35010, 256, + 24265, 256, 24565, 256, 25467, 256, 27566, 256, 31806, 256, 29557, 256, + 20196, 256, 22265, 256, 23994, 256, 24604, 256, 29618, 256, 29801, 256, + 32666, 256, 32838, 256, 37428, 256, 38646, 256, 38728, 256, 38936, 256, + 20363, 256, 31150, 256, 37300, 256, 38584, 256, 24801, 256, 20102, 256, + 20698, 256, 23534, 256, 23615, 256, 26009, 256, 29134, 256, 30274, 256, + 34044, 256, 36988, 256, 40845, 256, 26248, 256, 38446, 256, 21129, 256, + 26491, 256, 26611, 256, 27969, 256, 28316, 256, 29705, 256, 30041, 256, + 30827, 256, 32016, 256, 39006, 256, 20845, 256, 25134, 256, 38520, 256, + 20523, 256, 23833, 256, 28138, 256, 36650, 256, 24459, 256, 24900, 256, + 26647, 256, 38534, 256, 21033, 256, 21519, 256, 23653, 256, 26131, 256, 26446, 256, 26792, 256, 27877, 256, 29702, 256, 30178, 256, 32633, 256, 35023, 256, 35041, 256, 37324, 256, 38626, 256, 21311, 256, 28346, 256, 21533, 256, 29136, 256, 29848, 256, 34298, 256, 38563, 256, 40023, 256, @@ -3898,65 +3956,60 @@ static const unsigned int decomp_data[] = { 25935, 256, 26082, 256, 26257, 256, 26757, 256, 28023, 256, 28186, 256, 28450, 256, 29038, 256, 29227, 256, 29730, 256, 30865, 256, 31038, 256, 31049, 256, 31048, 256, 31056, 256, 31062, 256, 31069, 256, 31117, 256, - 31118, 256, 31296, 256, 31361, 256, 31680, 256, 32244, 256, 32265, 256, - 32321, 256, 32626, 256, 32773, 256, 33261, 256, 33401, 256, 33401, 256, - 33879, 256, 35088, 256, 35222, 256, 35585, 256, 35641, 256, 36051, 256, - 36104, 256, 36790, 256, 36920, 256, 38627, 256, 38911, 256, 38971, 256, - 24693, 256, 148206, 256, 33304, 256, 20006, 256, 20917, 256, 20840, 256, - 20352, 256, 20805, 256, 20864, 256, 21191, 256, 21242, 256, 21917, 256, - 21845, 256, 21913, 256, 21986, 256, 22618, 256, 22707, 256, 22852, 256, - 22868, 256, 23138, 256, 23336, 256, 24274, 256, 24281, 256, 24425, 256, - 24493, 256, 24792, 256, 24910, 256, 24840, 256, 24974, 256, 24928, 256, - 25074, 256, 25140, 256, 25540, 256, 25628, 256, 25682, 256, 25942, 256, - 26228, 256, 26391, 256, 26395, 256, 26454, 256, 27513, 256, 27578, 256, - 27969, 256, 28379, 256, 28363, 256, 28450, 256, 28702, 256, 29038, 256, - 30631, 256, 29237, 256, 29359, 256, 29482, 256, 29809, 256, 29958, 256, - 30011, 256, 30237, 256, 30239, 256, 30410, 256, 30427, 256, 30452, 256, - 30538, 256, 30528, 256, 30924, 256, 31409, 256, 31680, 256, 31867, 256, - 32091, 256, 32244, 256, 32574, 256, 32773, 256, 33618, 256, 33775, 256, - 34681, 256, 35137, 256, 35206, 256, 35222, 256, 35519, 256, 35576, 256, - 35531, 256, 35585, 256, 35582, 256, 35565, 256, 35641, 256, 35722, 256, - 36104, 256, 36664, 256, 36978, 256, 37273, 256, 37494, 256, 38524, 256, - 38627, 256, 38742, 256, 38875, 256, 38911, 256, 38923, 256, 38971, 256, - 39698, 256, 40860, 256, 141386, 256, 141380, 256, 144341, 256, 15261, - 256, 16408, 256, 16441, 256, 152137, 256, 154832, 256, 163539, 256, - 40771, 256, 40846, 514, 102, 102, 514, 102, 105, 514, 102, 108, 770, 102, - 102, 105, 770, 102, 102, 108, 514, 383, 116, 514, 115, 116, 514, 1396, - 1398, 514, 1396, 1381, 514, 1396, 1387, 514, 1406, 1398, 514, 1396, 1389, - 512, 1497, 1460, 512, 1522, 1463, 262, 1506, 262, 1488, 262, 1491, 262, - 1492, 262, 1499, 262, 1500, 262, 1501, 262, 1512, 262, 1514, 262, 43, - 512, 1513, 1473, 512, 1513, 1474, 512, 64329, 1473, 512, 64329, 1474, - 512, 1488, 1463, 512, 1488, 1464, 512, 1488, 1468, 512, 1489, 1468, 512, - 1490, 1468, 512, 1491, 1468, 512, 1492, 1468, 512, 1493, 1468, 512, 1494, - 1468, 512, 1496, 1468, 512, 1497, 1468, 512, 1498, 1468, 512, 1499, 1468, - 512, 1500, 1468, 512, 1502, 1468, 512, 1504, 1468, 512, 1505, 1468, 512, - 1507, 1468, 512, 1508, 1468, 512, 1510, 1468, 512, 1511, 1468, 512, 1512, - 1468, 512, 1513, 1468, 512, 1514, 1468, 512, 1493, 1465, 512, 1489, 1471, - 512, 1499, 1471, 512, 1508, 1471, 514, 1488, 1500, 267, 1649, 268, 1649, - 267, 1659, 268, 1659, 269, 1659, 270, 1659, 267, 1662, 268, 1662, 269, - 1662, 270, 1662, 267, 1664, 268, 1664, 269, 1664, 270, 1664, 267, 1658, - 268, 1658, 269, 1658, 270, 1658, 267, 1663, 268, 1663, 269, 1663, 270, - 1663, 267, 1657, 268, 1657, 269, 1657, 270, 1657, 267, 1700, 268, 1700, - 269, 1700, 270, 1700, 267, 1702, 268, 1702, 269, 1702, 270, 1702, 267, - 1668, 268, 1668, 269, 1668, 270, 1668, 267, 1667, 268, 1667, 269, 1667, - 270, 1667, 267, 1670, 268, 1670, 269, 1670, 270, 1670, 267, 1671, 268, - 1671, 269, 1671, 270, 1671, 267, 1677, 268, 1677, 267, 1676, 268, 1676, - 267, 1678, 268, 1678, 267, 1672, 268, 1672, 267, 1688, 268, 1688, 267, - 1681, 268, 1681, 267, 1705, 268, 1705, 269, 1705, 270, 1705, 267, 1711, - 268, 1711, 269, 1711, 270, 1711, 267, 1715, 268, 1715, 269, 1715, 270, - 1715, 267, 1713, 268, 1713, 269, 1713, 270, 1713, 267, 1722, 268, 1722, - 267, 1723, 268, 1723, 269, 1723, 270, 1723, 267, 1728, 268, 1728, 267, - 1729, 268, 1729, 269, 1729, 270, 1729, 267, 1726, 268, 1726, 269, 1726, - 270, 1726, 267, 1746, 268, 1746, 267, 1747, 268, 1747, 267, 1709, 268, - 1709, 269, 1709, 270, 1709, 267, 1735, 268, 1735, 267, 1734, 268, 1734, - 267, 1736, 268, 1736, 267, 1655, 267, 1739, 268, 1739, 267, 1733, 268, - 1733, 267, 1737, 268, 1737, 267, 1744, 268, 1744, 269, 1744, 270, 1744, - 269, 1609, 270, 1609, 523, 1574, 1575, 524, 1574, 1575, 523, 1574, 1749, - 524, 1574, 1749, 523, 1574, 1608, 524, 1574, 1608, 523, 1574, 1735, 524, - 1574, 1735, 523, 1574, 1734, 524, 1574, 1734, 523, 1574, 1736, 524, 1574, - 1736, 523, 1574, 1744, 524, 1574, 1744, 525, 1574, 1744, 523, 1574, 1609, - 524, 1574, 1609, 525, 1574, 1609, 267, 1740, 268, 1740, 269, 1740, 270, - 1740, 523, 1574, 1580, 523, 1574, 1581, 523, 1574, 1605, 523, 1574, 1609, + 31118, 256, 31296, 256, 31361, 256, 31680, 256, 32265, 256, 32321, 256, + 32626, 256, 32773, 256, 33261, 256, 33401, 256, 33879, 256, 35088, 256, + 35222, 256, 35585, 256, 35641, 256, 36051, 256, 36104, 256, 36790, 256, + 38627, 256, 38911, 256, 38971, 256, 24693, 256, 148206, 256, 33304, 256, + 20006, 256, 20917, 256, 20840, 256, 20352, 256, 20805, 256, 20864, 256, + 21191, 256, 21242, 256, 21845, 256, 21913, 256, 21986, 256, 22707, 256, + 22852, 256, 22868, 256, 23138, 256, 23336, 256, 24274, 256, 24281, 256, + 24425, 256, 24493, 256, 24792, 256, 24910, 256, 24840, 256, 24928, 256, + 25140, 256, 25540, 256, 25628, 256, 25682, 256, 25942, 256, 26395, 256, + 26454, 256, 27513, 256, 28379, 256, 28363, 256, 28702, 256, 30631, 256, + 29237, 256, 29359, 256, 29809, 256, 29958, 256, 30011, 256, 30237, 256, + 30239, 256, 30427, 256, 30452, 256, 30538, 256, 30528, 256, 30924, 256, + 31409, 256, 31867, 256, 32091, 256, 32574, 256, 33618, 256, 33775, 256, + 34681, 256, 35137, 256, 35206, 256, 35519, 256, 35531, 256, 35565, 256, + 35722, 256, 36664, 256, 36978, 256, 37273, 256, 37494, 256, 38524, 256, + 38875, 256, 38923, 256, 39698, 256, 141386, 256, 141380, 256, 144341, + 256, 15261, 256, 16408, 256, 16441, 256, 152137, 256, 154832, 256, + 163539, 256, 40771, 256, 40846, 514, 102, 102, 514, 102, 105, 514, 102, + 108, 770, 102, 102, 105, 770, 102, 102, 108, 514, 383, 116, 514, 115, + 116, 514, 1396, 1398, 514, 1396, 1381, 514, 1396, 1387, 514, 1406, 1398, + 514, 1396, 1389, 512, 1497, 1460, 512, 1522, 1463, 262, 1506, 262, 1488, + 262, 1491, 262, 1492, 262, 1499, 262, 1500, 262, 1501, 262, 1512, 262, + 1514, 262, 43, 512, 1513, 1473, 512, 1513, 1474, 512, 64329, 1473, 512, + 64329, 1474, 512, 1488, 1463, 512, 1488, 1464, 512, 1488, 1468, 512, + 1489, 1468, 512, 1490, 1468, 512, 1491, 1468, 512, 1492, 1468, 512, 1493, + 1468, 512, 1494, 1468, 512, 1496, 1468, 512, 1497, 1468, 512, 1498, 1468, + 512, 1499, 1468, 512, 1500, 1468, 512, 1502, 1468, 512, 1504, 1468, 512, + 1505, 1468, 512, 1507, 1468, 512, 1508, 1468, 512, 1510, 1468, 512, 1511, + 1468, 512, 1512, 1468, 512, 1513, 1468, 512, 1514, 1468, 512, 1493, 1465, + 512, 1489, 1471, 512, 1499, 1471, 512, 1508, 1471, 514, 1488, 1500, 267, + 1649, 268, 1649, 267, 1659, 268, 1659, 269, 1659, 270, 1659, 267, 1662, + 268, 1662, 269, 1662, 270, 1662, 267, 1664, 268, 1664, 269, 1664, 270, + 1664, 267, 1658, 268, 1658, 269, 1658, 270, 1658, 267, 1663, 268, 1663, + 269, 1663, 270, 1663, 267, 1657, 268, 1657, 269, 1657, 270, 1657, 267, + 1700, 268, 1700, 269, 1700, 270, 1700, 267, 1702, 268, 1702, 269, 1702, + 270, 1702, 267, 1668, 268, 1668, 269, 1668, 270, 1668, 267, 1667, 268, + 1667, 269, 1667, 270, 1667, 267, 1670, 268, 1670, 269, 1670, 270, 1670, + 267, 1671, 268, 1671, 269, 1671, 270, 1671, 267, 1677, 268, 1677, 267, + 1676, 268, 1676, 267, 1678, 268, 1678, 267, 1672, 268, 1672, 267, 1688, + 268, 1688, 267, 1681, 268, 1681, 267, 1705, 268, 1705, 269, 1705, 270, + 1705, 267, 1711, 268, 1711, 269, 1711, 270, 1711, 267, 1715, 268, 1715, + 269, 1715, 270, 1715, 267, 1713, 268, 1713, 269, 1713, 270, 1713, 267, + 1722, 268, 1722, 267, 1723, 268, 1723, 269, 1723, 270, 1723, 267, 1728, + 268, 1728, 267, 1729, 268, 1729, 269, 1729, 270, 1729, 267, 1726, 268, + 1726, 269, 1726, 270, 1726, 267, 1746, 268, 1746, 267, 1747, 268, 1747, + 267, 1709, 268, 1709, 269, 1709, 270, 1709, 267, 1735, 268, 1735, 267, + 1734, 268, 1734, 267, 1736, 268, 1736, 267, 1655, 267, 1739, 268, 1739, + 267, 1733, 268, 1733, 267, 1737, 268, 1737, 267, 1744, 268, 1744, 269, + 1744, 270, 1744, 269, 1609, 270, 1609, 523, 1574, 1575, 524, 1574, 1575, + 523, 1574, 1749, 524, 1574, 1749, 523, 1574, 1608, 524, 1574, 1608, 523, + 1574, 1735, 524, 1574, 1735, 523, 1574, 1734, 524, 1574, 1734, 523, 1574, + 1736, 524, 1574, 1736, 523, 1574, 1744, 524, 1574, 1744, 525, 1574, 1744, + 523, 1574, 1609, 524, 1574, 1609, 525, 1574, 1609, 267, 1740, 268, 1740, + 269, 1740, 270, 1740, 523, 1574, 1580, 523, 1574, 1581, 523, 1574, 1605, 523, 1574, 1610, 523, 1576, 1580, 523, 1576, 1581, 523, 1576, 1582, 523, 1576, 1605, 523, 1576, 1609, 523, 1576, 1610, 523, 1578, 1580, 523, 1578, 1581, 523, 1578, 1582, 523, 1578, 1605, 523, 1578, 1609, 523, 1578, 1610, @@ -3980,172 +4033,171 @@ static const unsigned int decomp_data[] = { 1610, 523, 1584, 1648, 523, 1585, 1648, 523, 1609, 1648, 779, 32, 1612, 1617, 779, 32, 1613, 1617, 779, 32, 1614, 1617, 779, 32, 1615, 1617, 779, 32, 1616, 1617, 779, 32, 1617, 1648, 524, 1574, 1585, 524, 1574, 1586, - 524, 1574, 1605, 524, 1574, 1606, 524, 1574, 1609, 524, 1574, 1610, 524, - 1576, 1585, 524, 1576, 1586, 524, 1576, 1605, 524, 1576, 1606, 524, 1576, - 1609, 524, 1576, 1610, 524, 1578, 1585, 524, 1578, 1586, 524, 1578, 1605, - 524, 1578, 1606, 524, 1578, 1609, 524, 1578, 1610, 524, 1579, 1585, 524, - 1579, 1586, 524, 1579, 1605, 524, 1579, 1606, 524, 1579, 1609, 524, 1579, - 1610, 524, 1601, 1609, 524, 1601, 1610, 524, 1602, 1609, 524, 1602, 1610, - 524, 1603, 1575, 524, 1603, 1604, 524, 1603, 1605, 524, 1603, 1609, 524, - 1603, 1610, 524, 1604, 1605, 524, 1604, 1609, 524, 1604, 1610, 524, 1605, - 1575, 524, 1605, 1605, 524, 1606, 1585, 524, 1606, 1586, 524, 1606, 1605, - 524, 1606, 1606, 524, 1606, 1609, 524, 1606, 1610, 524, 1609, 1648, 524, - 1610, 1585, 524, 1610, 1586, 524, 1610, 1605, 524, 1610, 1606, 524, 1610, - 1609, 524, 1610, 1610, 525, 1574, 1580, 525, 1574, 1581, 525, 1574, 1582, - 525, 1574, 1605, 525, 1574, 1607, 525, 1576, 1580, 525, 1576, 1581, 525, - 1576, 1582, 525, 1576, 1605, 525, 1576, 1607, 525, 1578, 1580, 525, 1578, - 1581, 525, 1578, 1582, 525, 1578, 1605, 525, 1578, 1607, 525, 1579, 1605, - 525, 1580, 1581, 525, 1580, 1605, 525, 1581, 1580, 525, 1581, 1605, 525, - 1582, 1580, 525, 1582, 1605, 525, 1587, 1580, 525, 1587, 1581, 525, 1587, - 1582, 525, 1587, 1605, 525, 1589, 1581, 525, 1589, 1582, 525, 1589, 1605, - 525, 1590, 1580, 525, 1590, 1581, 525, 1590, 1582, 525, 1590, 1605, 525, - 1591, 1581, 525, 1592, 1605, 525, 1593, 1580, 525, 1593, 1605, 525, 1594, - 1580, 525, 1594, 1605, 525, 1601, 1580, 525, 1601, 1581, 525, 1601, 1582, - 525, 1601, 1605, 525, 1602, 1581, 525, 1602, 1605, 525, 1603, 1580, 525, - 1603, 1581, 525, 1603, 1582, 525, 1603, 1604, 525, 1603, 1605, 525, 1604, - 1580, 525, 1604, 1581, 525, 1604, 1582, 525, 1604, 1605, 525, 1604, 1607, - 525, 1605, 1580, 525, 1605, 1581, 525, 1605, 1582, 525, 1605, 1605, 525, - 1606, 1580, 525, 1606, 1581, 525, 1606, 1582, 525, 1606, 1605, 525, 1606, - 1607, 525, 1607, 1580, 525, 1607, 1605, 525, 1607, 1648, 525, 1610, 1580, - 525, 1610, 1581, 525, 1610, 1582, 525, 1610, 1605, 525, 1610, 1607, 526, - 1574, 1605, 526, 1574, 1607, 526, 1576, 1605, 526, 1576, 1607, 526, 1578, - 1605, 526, 1578, 1607, 526, 1579, 1605, 526, 1579, 1607, 526, 1587, 1605, - 526, 1587, 1607, 526, 1588, 1605, 526, 1588, 1607, 526, 1603, 1604, 526, - 1603, 1605, 526, 1604, 1605, 526, 1606, 1605, 526, 1606, 1607, 526, 1610, - 1605, 526, 1610, 1607, 782, 1600, 1614, 1617, 782, 1600, 1615, 1617, 782, - 1600, 1616, 1617, 523, 1591, 1609, 523, 1591, 1610, 523, 1593, 1609, 523, - 1593, 1610, 523, 1594, 1609, 523, 1594, 1610, 523, 1587, 1609, 523, 1587, - 1610, 523, 1588, 1609, 523, 1588, 1610, 523, 1581, 1609, 523, 1581, 1610, - 523, 1580, 1609, 523, 1580, 1610, 523, 1582, 1609, 523, 1582, 1610, 523, - 1589, 1609, 523, 1589, 1610, 523, 1590, 1609, 523, 1590, 1610, 523, 1588, - 1580, 523, 1588, 1581, 523, 1588, 1582, 523, 1588, 1605, 523, 1588, 1585, - 523, 1587, 1585, 523, 1589, 1585, 523, 1590, 1585, 524, 1591, 1609, 524, - 1591, 1610, 524, 1593, 1609, 524, 1593, 1610, 524, 1594, 1609, 524, 1594, - 1610, 524, 1587, 1609, 524, 1587, 1610, 524, 1588, 1609, 524, 1588, 1610, - 524, 1581, 1609, 524, 1581, 1610, 524, 1580, 1609, 524, 1580, 1610, 524, - 1582, 1609, 524, 1582, 1610, 524, 1589, 1609, 524, 1589, 1610, 524, 1590, - 1609, 524, 1590, 1610, 524, 1588, 1580, 524, 1588, 1581, 524, 1588, 1582, - 524, 1588, 1605, 524, 1588, 1585, 524, 1587, 1585, 524, 1589, 1585, 524, - 1590, 1585, 525, 1588, 1580, 525, 1588, 1581, 525, 1588, 1582, 525, 1588, - 1605, 525, 1587, 1607, 525, 1588, 1607, 525, 1591, 1605, 526, 1587, 1580, - 526, 1587, 1581, 526, 1587, 1582, 526, 1588, 1580, 526, 1588, 1581, 526, - 1588, 1582, 526, 1591, 1605, 526, 1592, 1605, 524, 1575, 1611, 523, 1575, - 1611, 781, 1578, 1580, 1605, 780, 1578, 1581, 1580, 781, 1578, 1581, - 1580, 781, 1578, 1581, 1605, 781, 1578, 1582, 1605, 781, 1578, 1605, - 1580, 781, 1578, 1605, 1581, 781, 1578, 1605, 1582, 780, 1580, 1605, - 1581, 781, 1580, 1605, 1581, 780, 1581, 1605, 1610, 780, 1581, 1605, - 1609, 781, 1587, 1581, 1580, 781, 1587, 1580, 1581, 780, 1587, 1580, - 1609, 780, 1587, 1605, 1581, 781, 1587, 1605, 1581, 781, 1587, 1605, - 1580, 780, 1587, 1605, 1605, 781, 1587, 1605, 1605, 780, 1589, 1581, - 1581, 781, 1589, 1581, 1581, 780, 1589, 1605, 1605, 780, 1588, 1581, - 1605, 781, 1588, 1581, 1605, 780, 1588, 1580, 1610, 780, 1588, 1605, - 1582, 781, 1588, 1605, 1582, 780, 1588, 1605, 1605, 781, 1588, 1605, - 1605, 780, 1590, 1581, 1609, 780, 1590, 1582, 1605, 781, 1590, 1582, - 1605, 780, 1591, 1605, 1581, 781, 1591, 1605, 1581, 781, 1591, 1605, - 1605, 780, 1591, 1605, 1610, 780, 1593, 1580, 1605, 780, 1593, 1605, - 1605, 781, 1593, 1605, 1605, 780, 1593, 1605, 1609, 780, 1594, 1605, - 1605, 780, 1594, 1605, 1610, 780, 1594, 1605, 1609, 780, 1601, 1582, - 1605, 781, 1601, 1582, 1605, 780, 1602, 1605, 1581, 780, 1602, 1605, - 1605, 780, 1604, 1581, 1605, 780, 1604, 1581, 1610, 780, 1604, 1581, - 1609, 781, 1604, 1580, 1580, 780, 1604, 1580, 1580, 780, 1604, 1582, - 1605, 781, 1604, 1582, 1605, 780, 1604, 1605, 1581, 781, 1604, 1605, - 1581, 781, 1605, 1581, 1580, 781, 1605, 1581, 1605, 780, 1605, 1581, - 1610, 781, 1605, 1580, 1581, 781, 1605, 1580, 1605, 781, 1605, 1582, - 1580, 781, 1605, 1582, 1605, 781, 1605, 1580, 1582, 781, 1607, 1605, - 1580, 781, 1607, 1605, 1605, 781, 1606, 1581, 1605, 780, 1606, 1581, - 1609, 780, 1606, 1580, 1605, 781, 1606, 1580, 1605, 780, 1606, 1580, - 1609, 780, 1606, 1605, 1610, 780, 1606, 1605, 1609, 780, 1610, 1605, - 1605, 781, 1610, 1605, 1605, 780, 1576, 1582, 1610, 780, 1578, 1580, - 1610, 780, 1578, 1580, 1609, 780, 1578, 1582, 1610, 780, 1578, 1582, - 1609, 780, 1578, 1605, 1610, 780, 1578, 1605, 1609, 780, 1580, 1605, - 1610, 780, 1580, 1581, 1609, 780, 1580, 1605, 1609, 780, 1587, 1582, - 1609, 780, 1589, 1581, 1610, 780, 1588, 1581, 1610, 780, 1590, 1581, - 1610, 780, 1604, 1580, 1610, 780, 1604, 1605, 1610, 780, 1610, 1581, - 1610, 780, 1610, 1580, 1610, 780, 1610, 1605, 1610, 780, 1605, 1605, - 1610, 780, 1602, 1605, 1610, 780, 1606, 1581, 1610, 781, 1602, 1605, - 1581, 781, 1604, 1581, 1605, 780, 1593, 1605, 1610, 780, 1603, 1605, - 1610, 781, 1606, 1580, 1581, 780, 1605, 1582, 1610, 781, 1604, 1580, - 1605, 780, 1603, 1605, 1605, 780, 1604, 1580, 1605, 780, 1606, 1580, - 1581, 780, 1580, 1581, 1610, 780, 1581, 1580, 1610, 780, 1605, 1580, - 1610, 780, 1601, 1605, 1610, 780, 1576, 1581, 1610, 781, 1603, 1605, - 1605, 781, 1593, 1580, 1605, 781, 1589, 1605, 1605, 780, 1587, 1582, - 1610, 780, 1606, 1580, 1610, 779, 1589, 1604, 1746, 779, 1602, 1604, - 1746, 1035, 1575, 1604, 1604, 1607, 1035, 1575, 1603, 1576, 1585, 1035, - 1605, 1581, 1605, 1583, 1035, 1589, 1604, 1593, 1605, 1035, 1585, 1587, - 1608, 1604, 1035, 1593, 1604, 1610, 1607, 1035, 1608, 1587, 1604, 1605, - 779, 1589, 1604, 1609, 4619, 1589, 1604, 1609, 32, 1575, 1604, 1604, - 1607, 32, 1593, 1604, 1610, 1607, 32, 1608, 1587, 1604, 1605, 2059, 1580, - 1604, 32, 1580, 1604, 1575, 1604, 1607, 1035, 1585, 1740, 1575, 1604, - 265, 44, 265, 12289, 265, 12290, 265, 58, 265, 59, 265, 33, 265, 63, 265, - 12310, 265, 12311, 265, 8230, 265, 8229, 265, 8212, 265, 8211, 265, 95, - 265, 95, 265, 40, 265, 41, 265, 123, 265, 125, 265, 12308, 265, 12309, - 265, 12304, 265, 12305, 265, 12298, 265, 12299, 265, 12296, 265, 12297, - 265, 12300, 265, 12301, 265, 12302, 265, 12303, 265, 91, 265, 93, 258, - 8254, 258, 8254, 258, 8254, 258, 8254, 258, 95, 258, 95, 258, 95, 271, - 44, 271, 12289, 271, 46, 271, 59, 271, 58, 271, 63, 271, 33, 271, 8212, - 271, 40, 271, 41, 271, 123, 271, 125, 271, 12308, 271, 12309, 271, 35, - 271, 38, 271, 42, 271, 43, 271, 45, 271, 60, 271, 62, 271, 61, 271, 92, - 271, 36, 271, 37, 271, 64, 523, 32, 1611, 526, 1600, 1611, 523, 32, 1612, - 523, 32, 1613, 523, 32, 1614, 526, 1600, 1614, 523, 32, 1615, 526, 1600, - 1615, 523, 32, 1616, 526, 1600, 1616, 523, 32, 1617, 526, 1600, 1617, - 523, 32, 1618, 526, 1600, 1618, 267, 1569, 267, 1570, 268, 1570, 267, - 1571, 268, 1571, 267, 1572, 268, 1572, 267, 1573, 268, 1573, 267, 1574, - 268, 1574, 269, 1574, 270, 1574, 267, 1575, 268, 1575, 267, 1576, 268, - 1576, 269, 1576, 270, 1576, 267, 1577, 268, 1577, 267, 1578, 268, 1578, - 269, 1578, 270, 1578, 267, 1579, 268, 1579, 269, 1579, 270, 1579, 267, - 1580, 268, 1580, 269, 1580, 270, 1580, 267, 1581, 268, 1581, 269, 1581, - 270, 1581, 267, 1582, 268, 1582, 269, 1582, 270, 1582, 267, 1583, 268, - 1583, 267, 1584, 268, 1584, 267, 1585, 268, 1585, 267, 1586, 268, 1586, - 267, 1587, 268, 1587, 269, 1587, 270, 1587, 267, 1588, 268, 1588, 269, - 1588, 270, 1588, 267, 1589, 268, 1589, 269, 1589, 270, 1589, 267, 1590, - 268, 1590, 269, 1590, 270, 1590, 267, 1591, 268, 1591, 269, 1591, 270, - 1591, 267, 1592, 268, 1592, 269, 1592, 270, 1592, 267, 1593, 268, 1593, - 269, 1593, 270, 1593, 267, 1594, 268, 1594, 269, 1594, 270, 1594, 267, - 1601, 268, 1601, 269, 1601, 270, 1601, 267, 1602, 268, 1602, 269, 1602, - 270, 1602, 267, 1603, 268, 1603, 269, 1603, 270, 1603, 267, 1604, 268, - 1604, 269, 1604, 270, 1604, 267, 1605, 268, 1605, 269, 1605, 270, 1605, - 267, 1606, 268, 1606, 269, 1606, 270, 1606, 267, 1607, 268, 1607, 269, - 1607, 270, 1607, 267, 1608, 268, 1608, 267, 1609, 268, 1609, 267, 1610, - 268, 1610, 269, 1610, 270, 1610, 523, 1604, 1570, 524, 1604, 1570, 523, - 1604, 1571, 524, 1604, 1571, 523, 1604, 1573, 524, 1604, 1573, 523, 1604, - 1575, 524, 1604, 1575, 264, 33, 264, 34, 264, 35, 264, 36, 264, 37, 264, - 38, 264, 39, 264, 40, 264, 41, 264, 42, 264, 43, 264, 44, 264, 45, 264, - 46, 264, 47, 264, 48, 264, 49, 264, 50, 264, 51, 264, 52, 264, 53, 264, - 54, 264, 55, 264, 56, 264, 57, 264, 58, 264, 59, 264, 60, 264, 61, 264, - 62, 264, 63, 264, 64, 264, 65, 264, 66, 264, 67, 264, 68, 264, 69, 264, - 70, 264, 71, 264, 72, 264, 73, 264, 74, 264, 75, 264, 76, 264, 77, 264, - 78, 264, 79, 264, 80, 264, 81, 264, 82, 264, 83, 264, 84, 264, 85, 264, - 86, 264, 87, 264, 88, 264, 89, 264, 90, 264, 91, 264, 92, 264, 93, 264, - 94, 264, 95, 264, 96, 264, 97, 264, 98, 264, 99, 264, 100, 264, 101, 264, - 102, 264, 103, 264, 104, 264, 105, 264, 106, 264, 107, 264, 108, 264, - 109, 264, 110, 264, 111, 264, 112, 264, 113, 264, 114, 264, 115, 264, - 116, 264, 117, 264, 118, 264, 119, 264, 120, 264, 121, 264, 122, 264, - 123, 264, 124, 264, 125, 264, 126, 264, 10629, 264, 10630, 272, 12290, - 272, 12300, 272, 12301, 272, 12289, 272, 12539, 272, 12530, 272, 12449, - 272, 12451, 272, 12453, 272, 12455, 272, 12457, 272, 12515, 272, 12517, - 272, 12519, 272, 12483, 272, 12540, 272, 12450, 272, 12452, 272, 12454, - 272, 12456, 272, 12458, 272, 12459, 272, 12461, 272, 12463, 272, 12465, - 272, 12467, 272, 12469, 272, 12471, 272, 12473, 272, 12475, 272, 12477, - 272, 12479, 272, 12481, 272, 12484, 272, 12486, 272, 12488, 272, 12490, - 272, 12491, 272, 12492, 272, 12493, 272, 12494, 272, 12495, 272, 12498, - 272, 12501, 272, 12504, 272, 12507, 272, 12510, 272, 12511, 272, 12512, - 272, 12513, 272, 12514, 272, 12516, 272, 12518, 272, 12520, 272, 12521, - 272, 12522, 272, 12523, 272, 12524, 272, 12525, 272, 12527, 272, 12531, - 272, 12441, 272, 12442, 272, 12644, 272, 12593, 272, 12594, 272, 12595, - 272, 12596, 272, 12597, 272, 12598, 272, 12599, 272, 12600, 272, 12601, - 272, 12602, 272, 12603, 272, 12604, 272, 12605, 272, 12606, 272, 12607, - 272, 12608, 272, 12609, 272, 12610, 272, 12611, 272, 12612, 272, 12613, - 272, 12614, 272, 12615, 272, 12616, 272, 12617, 272, 12618, 272, 12619, - 272, 12620, 272, 12621, 272, 12622, 272, 12623, 272, 12624, 272, 12625, - 272, 12626, 272, 12627, 272, 12628, 272, 12629, 272, 12630, 272, 12631, - 272, 12632, 272, 12633, 272, 12634, 272, 12635, 272, 12636, 272, 12637, - 272, 12638, 272, 12639, 272, 12640, 272, 12641, 272, 12642, 272, 12643, - 264, 162, 264, 163, 264, 172, 264, 175, 264, 166, 264, 165, 264, 8361, - 272, 9474, 272, 8592, 272, 8593, 272, 8594, 272, 8595, 272, 9632, 272, - 9675, 259, 720, 259, 721, 259, 230, 259, 665, 259, 595, 259, 675, 259, - 43878, 259, 677, 259, 676, 259, 598, 259, 599, 259, 7569, 259, 600, 259, - 606, 259, 681, 259, 612, 259, 610, 259, 608, 259, 667, 259, 295, 259, - 668, 259, 615, 259, 644, 259, 682, 259, 683, 259, 620, 259, 122628, 259, + 524, 1574, 1605, 524, 1574, 1606, 524, 1574, 1610, 524, 1576, 1585, 524, + 1576, 1586, 524, 1576, 1605, 524, 1576, 1606, 524, 1576, 1609, 524, 1576, + 1610, 524, 1578, 1585, 524, 1578, 1586, 524, 1578, 1605, 524, 1578, 1606, + 524, 1578, 1609, 524, 1578, 1610, 524, 1579, 1585, 524, 1579, 1586, 524, + 1579, 1605, 524, 1579, 1606, 524, 1579, 1609, 524, 1579, 1610, 524, 1601, + 1609, 524, 1601, 1610, 524, 1602, 1609, 524, 1602, 1610, 524, 1603, 1575, + 524, 1603, 1604, 524, 1603, 1605, 524, 1603, 1609, 524, 1603, 1610, 524, + 1604, 1605, 524, 1604, 1609, 524, 1604, 1610, 524, 1605, 1575, 524, 1605, + 1605, 524, 1606, 1585, 524, 1606, 1586, 524, 1606, 1605, 524, 1606, 1606, + 524, 1606, 1609, 524, 1606, 1610, 524, 1609, 1648, 524, 1610, 1585, 524, + 1610, 1586, 524, 1610, 1605, 524, 1610, 1606, 524, 1610, 1609, 524, 1610, + 1610, 525, 1574, 1580, 525, 1574, 1581, 525, 1574, 1582, 525, 1574, 1605, + 525, 1574, 1607, 525, 1576, 1580, 525, 1576, 1581, 525, 1576, 1582, 525, + 1576, 1605, 525, 1576, 1607, 525, 1578, 1580, 525, 1578, 1581, 525, 1578, + 1582, 525, 1578, 1605, 525, 1578, 1607, 525, 1579, 1605, 525, 1580, 1581, + 525, 1580, 1605, 525, 1581, 1580, 525, 1581, 1605, 525, 1582, 1580, 525, + 1582, 1605, 525, 1587, 1580, 525, 1587, 1581, 525, 1587, 1582, 525, 1587, + 1605, 525, 1589, 1581, 525, 1589, 1582, 525, 1589, 1605, 525, 1590, 1580, + 525, 1590, 1581, 525, 1590, 1582, 525, 1590, 1605, 525, 1591, 1581, 525, + 1592, 1605, 525, 1593, 1580, 525, 1593, 1605, 525, 1594, 1580, 525, 1594, + 1605, 525, 1601, 1580, 525, 1601, 1581, 525, 1601, 1582, 525, 1601, 1605, + 525, 1602, 1581, 525, 1602, 1605, 525, 1603, 1580, 525, 1603, 1581, 525, + 1603, 1582, 525, 1603, 1604, 525, 1603, 1605, 525, 1604, 1580, 525, 1604, + 1581, 525, 1604, 1582, 525, 1604, 1605, 525, 1604, 1607, 525, 1605, 1580, + 525, 1605, 1581, 525, 1605, 1582, 525, 1605, 1605, 525, 1606, 1580, 525, + 1606, 1581, 525, 1606, 1582, 525, 1606, 1605, 525, 1606, 1607, 525, 1607, + 1580, 525, 1607, 1605, 525, 1607, 1648, 525, 1610, 1580, 525, 1610, 1581, + 525, 1610, 1582, 525, 1610, 1605, 525, 1610, 1607, 526, 1574, 1605, 526, + 1574, 1607, 526, 1576, 1605, 526, 1576, 1607, 526, 1578, 1605, 526, 1578, + 1607, 526, 1579, 1605, 526, 1579, 1607, 526, 1587, 1605, 526, 1587, 1607, + 526, 1588, 1605, 526, 1588, 1607, 526, 1603, 1604, 526, 1603, 1605, 526, + 1604, 1605, 526, 1606, 1605, 526, 1606, 1607, 526, 1610, 1605, 526, 1610, + 1607, 782, 1600, 1614, 1617, 782, 1600, 1615, 1617, 782, 1600, 1616, + 1617, 523, 1591, 1609, 523, 1591, 1610, 523, 1593, 1609, 523, 1593, 1610, + 523, 1594, 1609, 523, 1594, 1610, 523, 1587, 1609, 523, 1587, 1610, 523, + 1588, 1609, 523, 1588, 1610, 523, 1581, 1609, 523, 1581, 1610, 523, 1580, + 1609, 523, 1580, 1610, 523, 1582, 1609, 523, 1582, 1610, 523, 1589, 1609, + 523, 1589, 1610, 523, 1590, 1609, 523, 1590, 1610, 523, 1588, 1580, 523, + 1588, 1581, 523, 1588, 1582, 523, 1588, 1605, 523, 1588, 1585, 523, 1587, + 1585, 523, 1589, 1585, 523, 1590, 1585, 524, 1591, 1609, 524, 1591, 1610, + 524, 1593, 1609, 524, 1593, 1610, 524, 1594, 1609, 524, 1594, 1610, 524, + 1587, 1609, 524, 1587, 1610, 524, 1588, 1609, 524, 1588, 1610, 524, 1581, + 1609, 524, 1581, 1610, 524, 1580, 1609, 524, 1580, 1610, 524, 1582, 1609, + 524, 1582, 1610, 524, 1589, 1609, 524, 1589, 1610, 524, 1590, 1609, 524, + 1590, 1610, 524, 1588, 1580, 524, 1588, 1581, 524, 1588, 1582, 524, 1588, + 1605, 524, 1588, 1585, 524, 1587, 1585, 524, 1589, 1585, 524, 1590, 1585, + 525, 1588, 1580, 525, 1588, 1581, 525, 1588, 1582, 525, 1588, 1605, 525, + 1587, 1607, 525, 1588, 1607, 525, 1591, 1605, 526, 1587, 1580, 526, 1587, + 1581, 526, 1587, 1582, 526, 1588, 1580, 526, 1588, 1581, 526, 1588, 1582, + 526, 1591, 1605, 526, 1592, 1605, 524, 1575, 1611, 523, 1575, 1611, 781, + 1578, 1580, 1605, 780, 1578, 1581, 1580, 781, 1578, 1581, 1580, 781, + 1578, 1581, 1605, 781, 1578, 1582, 1605, 781, 1578, 1605, 1580, 781, + 1578, 1605, 1581, 781, 1578, 1605, 1582, 780, 1580, 1605, 1581, 781, + 1580, 1605, 1581, 780, 1581, 1605, 1610, 780, 1581, 1605, 1609, 781, + 1587, 1581, 1580, 781, 1587, 1580, 1581, 780, 1587, 1580, 1609, 780, + 1587, 1605, 1581, 781, 1587, 1605, 1581, 781, 1587, 1605, 1580, 780, + 1587, 1605, 1605, 781, 1587, 1605, 1605, 780, 1589, 1581, 1581, 781, + 1589, 1581, 1581, 780, 1589, 1605, 1605, 780, 1588, 1581, 1605, 781, + 1588, 1581, 1605, 780, 1588, 1580, 1610, 780, 1588, 1605, 1582, 781, + 1588, 1605, 1582, 780, 1588, 1605, 1605, 781, 1588, 1605, 1605, 780, + 1590, 1581, 1609, 780, 1590, 1582, 1605, 781, 1590, 1582, 1605, 780, + 1591, 1605, 1581, 781, 1591, 1605, 1581, 781, 1591, 1605, 1605, 780, + 1591, 1605, 1610, 780, 1593, 1580, 1605, 780, 1593, 1605, 1605, 781, + 1593, 1605, 1605, 780, 1593, 1605, 1609, 780, 1594, 1605, 1605, 780, + 1594, 1605, 1610, 780, 1594, 1605, 1609, 780, 1601, 1582, 1605, 781, + 1601, 1582, 1605, 780, 1602, 1605, 1581, 780, 1602, 1605, 1605, 780, + 1604, 1581, 1605, 780, 1604, 1581, 1610, 780, 1604, 1581, 1609, 781, + 1604, 1580, 1580, 780, 1604, 1580, 1580, 780, 1604, 1582, 1605, 781, + 1604, 1582, 1605, 780, 1604, 1605, 1581, 781, 1604, 1605, 1581, 781, + 1605, 1581, 1580, 781, 1605, 1581, 1605, 780, 1605, 1581, 1610, 781, + 1605, 1580, 1581, 781, 1605, 1580, 1605, 781, 1605, 1582, 1580, 781, + 1605, 1582, 1605, 781, 1605, 1580, 1582, 781, 1607, 1605, 1580, 781, + 1607, 1605, 1605, 781, 1606, 1581, 1605, 780, 1606, 1581, 1609, 780, + 1606, 1580, 1605, 781, 1606, 1580, 1605, 780, 1606, 1580, 1609, 780, + 1606, 1605, 1610, 780, 1606, 1605, 1609, 780, 1610, 1605, 1605, 781, + 1610, 1605, 1605, 780, 1576, 1582, 1610, 780, 1578, 1580, 1610, 780, + 1578, 1580, 1609, 780, 1578, 1582, 1610, 780, 1578, 1582, 1609, 780, + 1578, 1605, 1610, 780, 1578, 1605, 1609, 780, 1580, 1605, 1610, 780, + 1580, 1581, 1609, 780, 1580, 1605, 1609, 780, 1587, 1582, 1609, 780, + 1589, 1581, 1610, 780, 1588, 1581, 1610, 780, 1590, 1581, 1610, 780, + 1604, 1580, 1610, 780, 1604, 1605, 1610, 780, 1610, 1581, 1610, 780, + 1610, 1580, 1610, 780, 1610, 1605, 1610, 780, 1605, 1605, 1610, 780, + 1602, 1605, 1610, 780, 1606, 1581, 1610, 781, 1602, 1605, 1581, 781, + 1604, 1581, 1605, 780, 1593, 1605, 1610, 780, 1603, 1605, 1610, 781, + 1606, 1580, 1581, 780, 1605, 1582, 1610, 781, 1604, 1580, 1605, 780, + 1603, 1605, 1605, 780, 1604, 1580, 1605, 780, 1606, 1580, 1581, 780, + 1580, 1581, 1610, 780, 1581, 1580, 1610, 780, 1605, 1580, 1610, 780, + 1601, 1605, 1610, 780, 1576, 1581, 1610, 781, 1603, 1605, 1605, 781, + 1593, 1580, 1605, 781, 1589, 1605, 1605, 780, 1587, 1582, 1610, 780, + 1606, 1580, 1610, 779, 1589, 1604, 1746, 779, 1602, 1604, 1746, 1035, + 1575, 1604, 1604, 1607, 1035, 1575, 1603, 1576, 1585, 1035, 1605, 1581, + 1605, 1583, 1035, 1589, 1604, 1593, 1605, 1035, 1585, 1587, 1608, 1604, + 1035, 1593, 1604, 1610, 1607, 1035, 1608, 1587, 1604, 1605, 779, 1589, + 1604, 1609, 4619, 1589, 1604, 1609, 32, 1575, 1604, 1604, 1607, 32, 1593, + 1604, 1610, 1607, 32, 1608, 1587, 1604, 1605, 2059, 1580, 1604, 32, 1580, + 1604, 1575, 1604, 1607, 1035, 1585, 1740, 1575, 1604, 265, 44, 265, + 12289, 265, 12290, 265, 58, 265, 59, 265, 33, 265, 63, 265, 12310, 265, + 12311, 265, 8230, 265, 8229, 265, 8212, 265, 8211, 265, 95, 265, 40, 265, + 41, 265, 123, 265, 125, 265, 12308, 265, 12309, 265, 12304, 265, 12305, + 265, 12298, 265, 12299, 265, 12296, 265, 12297, 265, 12300, 265, 12301, + 265, 12302, 265, 12303, 265, 91, 265, 93, 258, 8254, 258, 95, 271, 44, + 271, 12289, 271, 46, 271, 59, 271, 58, 271, 63, 271, 33, 271, 8212, 271, + 40, 271, 41, 271, 123, 271, 125, 271, 12308, 271, 12309, 271, 35, 271, + 38, 271, 42, 271, 43, 271, 45, 271, 60, 271, 62, 271, 61, 271, 92, 271, + 36, 271, 37, 271, 64, 523, 32, 1611, 526, 1600, 1611, 523, 32, 1612, 523, + 32, 1613, 523, 32, 1614, 526, 1600, 1614, 523, 32, 1615, 526, 1600, 1615, + 523, 32, 1616, 526, 1600, 1616, 523, 32, 1617, 526, 1600, 1617, 523, 32, + 1618, 526, 1600, 1618, 267, 1569, 267, 1570, 268, 1570, 267, 1571, 268, + 1571, 267, 1572, 268, 1572, 267, 1573, 268, 1573, 267, 1574, 268, 1574, + 269, 1574, 270, 1574, 267, 1575, 268, 1575, 267, 1576, 268, 1576, 269, + 1576, 270, 1576, 267, 1577, 268, 1577, 267, 1578, 268, 1578, 269, 1578, + 270, 1578, 267, 1579, 268, 1579, 269, 1579, 270, 1579, 267, 1580, 268, + 1580, 269, 1580, 270, 1580, 267, 1581, 268, 1581, 269, 1581, 270, 1581, + 267, 1582, 268, 1582, 269, 1582, 270, 1582, 267, 1583, 268, 1583, 267, + 1584, 268, 1584, 267, 1585, 268, 1585, 267, 1586, 268, 1586, 267, 1587, + 268, 1587, 269, 1587, 270, 1587, 267, 1588, 268, 1588, 269, 1588, 270, + 1588, 267, 1589, 268, 1589, 269, 1589, 270, 1589, 267, 1590, 268, 1590, + 269, 1590, 270, 1590, 267, 1591, 268, 1591, 269, 1591, 270, 1591, 267, + 1592, 268, 1592, 269, 1592, 270, 1592, 267, 1593, 268, 1593, 269, 1593, + 270, 1593, 267, 1594, 268, 1594, 269, 1594, 270, 1594, 267, 1601, 268, + 1601, 269, 1601, 270, 1601, 267, 1602, 268, 1602, 269, 1602, 270, 1602, + 267, 1603, 268, 1603, 269, 1603, 270, 1603, 267, 1604, 268, 1604, 269, + 1604, 270, 1604, 267, 1605, 268, 1605, 269, 1605, 270, 1605, 267, 1606, + 268, 1606, 269, 1606, 270, 1606, 267, 1607, 268, 1607, 269, 1607, 270, + 1607, 267, 1608, 268, 1608, 267, 1609, 268, 1609, 267, 1610, 268, 1610, + 269, 1610, 270, 1610, 523, 1604, 1570, 524, 1604, 1570, 523, 1604, 1571, + 524, 1604, 1571, 523, 1604, 1573, 524, 1604, 1573, 523, 1604, 1575, 524, + 1604, 1575, 264, 33, 264, 34, 264, 35, 264, 36, 264, 37, 264, 38, 264, + 39, 264, 40, 264, 41, 264, 42, 264, 43, 264, 44, 264, 45, 264, 46, 264, + 47, 264, 48, 264, 49, 264, 50, 264, 51, 264, 52, 264, 53, 264, 54, 264, + 55, 264, 56, 264, 57, 264, 58, 264, 59, 264, 60, 264, 61, 264, 62, 264, + 63, 264, 64, 264, 65, 264, 66, 264, 67, 264, 68, 264, 69, 264, 70, 264, + 71, 264, 72, 264, 73, 264, 74, 264, 75, 264, 76, 264, 77, 264, 78, 264, + 79, 264, 80, 264, 81, 264, 82, 264, 83, 264, 84, 264, 85, 264, 86, 264, + 87, 264, 88, 264, 89, 264, 90, 264, 91, 264, 92, 264, 93, 264, 94, 264, + 95, 264, 96, 264, 97, 264, 98, 264, 99, 264, 100, 264, 101, 264, 102, + 264, 103, 264, 104, 264, 105, 264, 106, 264, 107, 264, 108, 264, 109, + 264, 110, 264, 111, 264, 112, 264, 113, 264, 114, 264, 115, 264, 116, + 264, 117, 264, 118, 264, 119, 264, 120, 264, 121, 264, 122, 264, 123, + 264, 124, 264, 125, 264, 126, 264, 10629, 264, 10630, 272, 12290, 272, + 12300, 272, 12301, 272, 12289, 272, 12539, 272, 12530, 272, 12449, 272, + 12451, 272, 12453, 272, 12455, 272, 12457, 272, 12515, 272, 12517, 272, + 12519, 272, 12483, 272, 12540, 272, 12450, 272, 12452, 272, 12454, 272, + 12456, 272, 12458, 272, 12459, 272, 12461, 272, 12463, 272, 12465, 272, + 12467, 272, 12469, 272, 12471, 272, 12473, 272, 12475, 272, 12477, 272, + 12479, 272, 12481, 272, 12484, 272, 12486, 272, 12488, 272, 12490, 272, + 12491, 272, 12492, 272, 12493, 272, 12494, 272, 12495, 272, 12498, 272, + 12501, 272, 12504, 272, 12507, 272, 12510, 272, 12511, 272, 12512, 272, + 12513, 272, 12514, 272, 12516, 272, 12518, 272, 12520, 272, 12521, 272, + 12522, 272, 12523, 272, 12524, 272, 12525, 272, 12527, 272, 12531, 272, + 12441, 272, 12442, 272, 12644, 272, 12593, 272, 12594, 272, 12595, 272, + 12596, 272, 12597, 272, 12598, 272, 12599, 272, 12600, 272, 12601, 272, + 12602, 272, 12603, 272, 12604, 272, 12605, 272, 12606, 272, 12607, 272, + 12608, 272, 12609, 272, 12610, 272, 12611, 272, 12612, 272, 12613, 272, + 12614, 272, 12615, 272, 12616, 272, 12617, 272, 12618, 272, 12619, 272, + 12620, 272, 12621, 272, 12622, 272, 12623, 272, 12624, 272, 12625, 272, + 12626, 272, 12627, 272, 12628, 272, 12629, 272, 12630, 272, 12631, 272, + 12632, 272, 12633, 272, 12634, 272, 12635, 272, 12636, 272, 12637, 272, + 12638, 272, 12639, 272, 12640, 272, 12641, 272, 12642, 272, 12643, 264, + 162, 264, 163, 264, 172, 264, 175, 264, 166, 264, 165, 264, 8361, 272, + 9474, 272, 8592, 272, 8593, 272, 8594, 272, 8595, 272, 9632, 272, 9675, + 259, 720, 259, 721, 259, 230, 259, 665, 259, 595, 259, 675, 259, 43878, + 259, 677, 259, 676, 259, 598, 259, 599, 259, 7569, 259, 600, 259, 606, + 259, 681, 259, 612, 259, 610, 259, 608, 259, 667, 259, 295, 259, 668, + 259, 615, 259, 644, 259, 682, 259, 683, 259, 620, 259, 122628, 259, 42894, 259, 622, 259, 122629, 259, 654, 259, 122630, 259, 248, 259, 630, 259, 631, 259, 113, 259, 634, 259, 122632, 259, 637, 259, 638, 259, 640, 259, 680, 259, 678, 259, 43879, 259, 679, 259, 648, 259, 11377, 259, 655, @@ -4157,281 +4209,141 @@ static const unsigned int decomp_data[] = { 512, 119128, 119141, 512, 119135, 119150, 512, 119135, 119151, 512, 119135, 119152, 512, 119135, 119153, 512, 119135, 119154, 512, 119225, 119141, 512, 119226, 119141, 512, 119227, 119150, 512, 119228, 119150, - 512, 119227, 119151, 512, 119228, 119151, 262, 65, 262, 66, 262, 67, 262, - 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, - 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, - 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, - 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, - 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, - 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, - 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, - 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, - 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, - 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, - 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 105, 262, 106, 262, 107, - 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, - 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, - 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, - 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, - 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, - 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, - 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, - 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, - 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, - 262, 65, 262, 67, 262, 68, 262, 71, 262, 74, 262, 75, 262, 78, 262, 79, - 262, 80, 262, 81, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, - 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 102, 262, - 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, - 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, - 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, - 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, - 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, - 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, - 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, - 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, - 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, - 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 68, 262, 69, 262, 70, - 262, 71, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, - 262, 81, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, - 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, - 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, - 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, - 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 68, - 262, 69, 262, 70, 262, 71, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, - 262, 79, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, - 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, - 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, - 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, - 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, - 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, - 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, - 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, - 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, - 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, - 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, - 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, - 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, - 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, - 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, - 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, - 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, - 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, - 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, - 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, - 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, - 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, - 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, - 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, - 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, - 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, - 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, - 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, - 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, - 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, - 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, - 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, - 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, - 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, - 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, - 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, - 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, - 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, - 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, - 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, - 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, - 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, - 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, - 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, - 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, - 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, - 305, 262, 567, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, - 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, - 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, - 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, - 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, - 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, - 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, - 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, - 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, - 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, - 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, - 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, - 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, - 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, - 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, - 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, - 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, - 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, - 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, - 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, - 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, - 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, - 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, - 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, - 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, - 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, - 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, - 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, - 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, - 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, - 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, - 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, - 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, - 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, - 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, - 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, - 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, - 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, - 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, - 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, - 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, - 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 988, 262, 989, 262, - 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, - 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, - 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, - 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, - 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, - 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, - 56, 262, 57, 262, 1575, 262, 1576, 262, 1580, 262, 1583, 262, 1608, 262, - 1586, 262, 1581, 262, 1591, 262, 1610, 262, 1603, 262, 1604, 262, 1605, - 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, - 1585, 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1584, 262, 1590, - 262, 1592, 262, 1594, 262, 1646, 262, 1722, 262, 1697, 262, 1647, 262, - 1576, 262, 1580, 262, 1607, 262, 1581, 262, 1610, 262, 1603, 262, 1604, - 262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, - 1602, 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1590, 262, 1594, - 262, 1580, 262, 1581, 262, 1610, 262, 1604, 262, 1606, 262, 1587, 262, - 1593, 262, 1589, 262, 1602, 262, 1588, 262, 1582, 262, 1590, 262, 1594, - 262, 1722, 262, 1647, 262, 1576, 262, 1580, 262, 1607, 262, 1581, 262, - 1591, 262, 1610, 262, 1603, 262, 1605, 262, 1606, 262, 1587, 262, 1593, - 262, 1601, 262, 1589, 262, 1602, 262, 1588, 262, 1578, 262, 1579, 262, - 1582, 262, 1590, 262, 1592, 262, 1594, 262, 1646, 262, 1697, 262, 1575, - 262, 1576, 262, 1580, 262, 1583, 262, 1607, 262, 1608, 262, 1586, 262, - 1581, 262, 1591, 262, 1610, 262, 1604, 262, 1605, 262, 1606, 262, 1587, - 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, - 1578, 262, 1579, 262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, - 262, 1576, 262, 1580, 262, 1583, 262, 1608, 262, 1586, 262, 1581, 262, - 1591, 262, 1610, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, 1593, + 512, 119227, 119151, 512, 119228, 119151, 262, 65, 262, 71, 262, 74, 262, + 75, 262, 79, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, + 89, 262, 97, 262, 98, 262, 99, 262, 102, 262, 107, 262, 109, 262, 110, + 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, + 262, 119, 262, 120, 262, 121, 262, 122, 262, 305, 262, 567, 262, 913, + 262, 914, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, + 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 929, + 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, + 262, 937, 262, 8711, 262, 945, 262, 946, 262, 948, 262, 949, 262, 950, + 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, + 262, 958, 262, 959, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, + 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, + 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 988, 262, 989, 262, 48, + 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, + 262, 57, 259, 1072, 259, 1073, 259, 1074, 259, 1075, 259, 1076, 259, + 1077, 259, 1078, 259, 1079, 259, 1080, 259, 1082, 259, 1083, 259, 1084, + 259, 1086, 259, 1087, 259, 1088, 259, 1089, 259, 1090, 259, 1091, 259, + 1092, 259, 1093, 259, 1094, 259, 1095, 259, 1096, 259, 1099, 259, 1101, + 259, 1102, 259, 42633, 259, 1241, 259, 1110, 259, 1112, 259, 1257, 259, + 1199, 259, 1231, 261, 1072, 261, 1073, 261, 1074, 261, 1075, 261, 1076, + 261, 1077, 261, 1078, 261, 1079, 261, 1080, 261, 1082, 261, 1083, 261, + 1086, 261, 1087, 261, 1089, 261, 1091, 261, 1092, 261, 1093, 261, 1094, + 261, 1095, 261, 1096, 261, 1098, 261, 1099, 261, 1169, 261, 1110, 261, + 1109, 261, 1119, 259, 1195, 259, 42577, 259, 1201, 262, 1575, 262, 1576, + 262, 1580, 262, 1583, 262, 1608, 262, 1586, 262, 1581, 262, 1591, 262, + 1610, 262, 1603, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, 1578, 262, - 1579, 262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, 514, 48, 46, - 514, 48, 44, 514, 49, 44, 514, 50, 44, 514, 51, 44, 514, 52, 44, 514, 53, - 44, 514, 54, 44, 514, 55, 44, 514, 56, 44, 514, 57, 44, 770, 40, 65, 41, - 770, 40, 66, 41, 770, 40, 67, 41, 770, 40, 68, 41, 770, 40, 69, 41, 770, - 40, 70, 41, 770, 40, 71, 41, 770, 40, 72, 41, 770, 40, 73, 41, 770, 40, - 74, 41, 770, 40, 75, 41, 770, 40, 76, 41, 770, 40, 77, 41, 770, 40, 78, - 41, 770, 40, 79, 41, 770, 40, 80, 41, 770, 40, 81, 41, 770, 40, 82, 41, - 770, 40, 83, 41, 770, 40, 84, 41, 770, 40, 85, 41, 770, 40, 86, 41, 770, - 40, 87, 41, 770, 40, 88, 41, 770, 40, 89, 41, 770, 40, 90, 41, 770, - 12308, 83, 12309, 263, 67, 263, 82, 519, 67, 68, 519, 87, 90, 266, 65, - 266, 66, 266, 67, 266, 68, 266, 69, 266, 70, 266, 71, 266, 72, 266, 73, - 266, 74, 266, 75, 266, 76, 266, 77, 266, 78, 266, 79, 266, 80, 266, 81, - 266, 82, 266, 83, 266, 84, 266, 85, 266, 86, 266, 87, 266, 88, 266, 89, - 266, 90, 522, 72, 86, 522, 77, 86, 522, 83, 68, 522, 83, 83, 778, 80, 80, - 86, 522, 87, 67, 515, 77, 67, 515, 77, 68, 515, 77, 82, 522, 68, 74, 522, - 12411, 12363, 522, 12467, 12467, 266, 12469, 266, 25163, 266, 23383, 266, - 21452, 266, 12487, 266, 20108, 266, 22810, 266, 35299, 266, 22825, 266, - 20132, 266, 26144, 266, 28961, 266, 26009, 266, 21069, 266, 24460, 266, - 20877, 266, 26032, 266, 21021, 266, 32066, 266, 29983, 266, 36009, 266, - 22768, 266, 21561, 266, 28436, 266, 25237, 266, 25429, 266, 19968, 266, - 19977, 266, 36938, 266, 24038, 266, 20013, 266, 21491, 266, 25351, 266, - 36208, 266, 25171, 266, 31105, 266, 31354, 266, 21512, 266, 28288, 266, - 26377, 266, 26376, 266, 30003, 266, 21106, 266, 21942, 266, 37197, 770, - 12308, 26412, 12309, 770, 12308, 19977, 12309, 770, 12308, 20108, 12309, - 770, 12308, 23433, 12309, 770, 12308, 28857, 12309, 770, 12308, 25171, - 12309, 770, 12308, 30423, 12309, 770, 12308, 21213, 12309, 770, 12308, - 25943, 12309, 263, 24471, 263, 21487, 262, 48, 262, 49, 262, 50, 262, 51, - 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 256, 20029, 256, - 20024, 256, 20033, 256, 131362, 256, 20320, 256, 20398, 256, 20411, 256, - 20482, 256, 20602, 256, 20633, 256, 20711, 256, 20687, 256, 13470, 256, - 132666, 256, 20813, 256, 20820, 256, 20836, 256, 20855, 256, 132380, 256, - 13497, 256, 20839, 256, 20877, 256, 132427, 256, 20887, 256, 20900, 256, - 20172, 256, 20908, 256, 20917, 256, 168415, 256, 20981, 256, 20995, 256, - 13535, 256, 21051, 256, 21062, 256, 21106, 256, 21111, 256, 13589, 256, - 21191, 256, 21193, 256, 21220, 256, 21242, 256, 21253, 256, 21254, 256, - 21271, 256, 21321, 256, 21329, 256, 21338, 256, 21363, 256, 21373, 256, - 21375, 256, 21375, 256, 21375, 256, 133676, 256, 28784, 256, 21450, 256, - 21471, 256, 133987, 256, 21483, 256, 21489, 256, 21510, 256, 21662, 256, - 21560, 256, 21576, 256, 21608, 256, 21666, 256, 21750, 256, 21776, 256, - 21843, 256, 21859, 256, 21892, 256, 21892, 256, 21913, 256, 21931, 256, - 21939, 256, 21954, 256, 22294, 256, 22022, 256, 22295, 256, 22097, 256, - 22132, 256, 20999, 256, 22766, 256, 22478, 256, 22516, 256, 22541, 256, - 22411, 256, 22578, 256, 22577, 256, 22700, 256, 136420, 256, 22770, 256, - 22775, 256, 22790, 256, 22810, 256, 22818, 256, 22882, 256, 136872, 256, - 136938, 256, 23020, 256, 23067, 256, 23079, 256, 23000, 256, 23142, 256, - 14062, 256, 14076, 256, 23304, 256, 23358, 256, 23358, 256, 137672, 256, - 23491, 256, 23512, 256, 23527, 256, 23539, 256, 138008, 256, 23551, 256, - 23558, 256, 24403, 256, 23586, 256, 14209, 256, 23648, 256, 23662, 256, - 23744, 256, 23693, 256, 138724, 256, 23875, 256, 138726, 256, 23918, 256, - 23915, 256, 23932, 256, 24033, 256, 24034, 256, 14383, 256, 24061, 256, - 24104, 256, 24125, 256, 24169, 256, 14434, 256, 139651, 256, 14460, 256, - 24240, 256, 24243, 256, 24246, 256, 24266, 256, 172946, 256, 24318, 256, - 140081, 256, 140081, 256, 33281, 256, 24354, 256, 24354, 256, 14535, 256, - 144056, 256, 156122, 256, 24418, 256, 24427, 256, 14563, 256, 24474, 256, - 24525, 256, 24535, 256, 24569, 256, 24705, 256, 14650, 256, 14620, 256, - 24724, 256, 141012, 256, 24775, 256, 24904, 256, 24908, 256, 24910, 256, - 24908, 256, 24954, 256, 24974, 256, 25010, 256, 24996, 256, 25007, 256, - 25054, 256, 25074, 256, 25078, 256, 25104, 256, 25115, 256, 25181, 256, - 25265, 256, 25300, 256, 25424, 256, 142092, 256, 25405, 256, 25340, 256, - 25448, 256, 25475, 256, 25572, 256, 142321, 256, 25634, 256, 25541, 256, - 25513, 256, 14894, 256, 25705, 256, 25726, 256, 25757, 256, 25719, 256, - 14956, 256, 25935, 256, 25964, 256, 143370, 256, 26083, 256, 26360, 256, - 26185, 256, 15129, 256, 26257, 256, 15112, 256, 15076, 256, 20882, 256, - 20885, 256, 26368, 256, 26268, 256, 32941, 256, 17369, 256, 26391, 256, - 26395, 256, 26401, 256, 26462, 256, 26451, 256, 144323, 256, 15177, 256, - 26618, 256, 26501, 256, 26706, 256, 26757, 256, 144493, 256, 26766, 256, - 26655, 256, 26900, 256, 15261, 256, 26946, 256, 27043, 256, 27114, 256, - 27304, 256, 145059, 256, 27355, 256, 15384, 256, 27425, 256, 145575, 256, - 27476, 256, 15438, 256, 27506, 256, 27551, 256, 27578, 256, 27579, 256, - 146061, 256, 138507, 256, 146170, 256, 27726, 256, 146620, 256, 27839, - 256, 27853, 256, 27751, 256, 27926, 256, 27966, 256, 28023, 256, 27969, - 256, 28009, 256, 28024, 256, 28037, 256, 146718, 256, 27956, 256, 28207, - 256, 28270, 256, 15667, 256, 28363, 256, 28359, 256, 147153, 256, 28153, - 256, 28526, 256, 147294, 256, 147342, 256, 28614, 256, 28729, 256, 28702, - 256, 28699, 256, 15766, 256, 28746, 256, 28797, 256, 28791, 256, 28845, - 256, 132389, 256, 28997, 256, 148067, 256, 29084, 256, 148395, 256, - 29224, 256, 29237, 256, 29264, 256, 149000, 256, 29312, 256, 29333, 256, - 149301, 256, 149524, 256, 29562, 256, 29579, 256, 16044, 256, 29605, 256, - 16056, 256, 16056, 256, 29767, 256, 29788, 256, 29809, 256, 29829, 256, - 29898, 256, 16155, 256, 29988, 256, 150582, 256, 30014, 256, 150674, 256, - 30064, 256, 139679, 256, 30224, 256, 151457, 256, 151480, 256, 151620, - 256, 16380, 256, 16392, 256, 30452, 256, 151795, 256, 151794, 256, - 151833, 256, 151859, 256, 30494, 256, 30495, 256, 30495, 256, 30538, 256, - 16441, 256, 30603, 256, 16454, 256, 16534, 256, 152605, 256, 30798, 256, - 30860, 256, 30924, 256, 16611, 256, 153126, 256, 31062, 256, 153242, 256, - 153285, 256, 31119, 256, 31211, 256, 16687, 256, 31296, 256, 31306, 256, - 31311, 256, 153980, 256, 154279, 256, 154279, 256, 31470, 256, 16898, - 256, 154539, 256, 31686, 256, 31689, 256, 16935, 256, 154752, 256, 31954, - 256, 17056, 256, 31976, 256, 31971, 256, 32000, 256, 155526, 256, 32099, - 256, 17153, 256, 32199, 256, 32258, 256, 32325, 256, 17204, 256, 156200, - 256, 156231, 256, 17241, 256, 156377, 256, 32634, 256, 156478, 256, - 32661, 256, 32762, 256, 32773, 256, 156890, 256, 156963, 256, 32864, 256, - 157096, 256, 32880, 256, 144223, 256, 17365, 256, 32946, 256, 33027, 256, - 17419, 256, 33086, 256, 23221, 256, 157607, 256, 157621, 256, 144275, - 256, 144284, 256, 33281, 256, 33284, 256, 36766, 256, 17515, 256, 33425, - 256, 33419, 256, 33437, 256, 21171, 256, 33457, 256, 33459, 256, 33469, - 256, 33510, 256, 158524, 256, 33509, 256, 33565, 256, 33635, 256, 33709, - 256, 33571, 256, 33725, 256, 33767, 256, 33879, 256, 33619, 256, 33738, - 256, 33740, 256, 33756, 256, 158774, 256, 159083, 256, 158933, 256, - 17707, 256, 34033, 256, 34035, 256, 34070, 256, 160714, 256, 34148, 256, - 159532, 256, 17757, 256, 17761, 256, 159665, 256, 159954, 256, 17771, - 256, 34384, 256, 34396, 256, 34407, 256, 34409, 256, 34473, 256, 34440, - 256, 34574, 256, 34530, 256, 34681, 256, 34600, 256, 34667, 256, 34694, - 256, 17879, 256, 34785, 256, 34817, 256, 17913, 256, 34912, 256, 34915, - 256, 161383, 256, 35031, 256, 35038, 256, 17973, 256, 35066, 256, 13499, - 256, 161966, 256, 162150, 256, 18110, 256, 18119, 256, 35488, 256, 35565, - 256, 35722, 256, 35925, 256, 162984, 256, 36011, 256, 36033, 256, 36123, - 256, 36215, 256, 163631, 256, 133124, 256, 36299, 256, 36284, 256, 36336, - 256, 133342, 256, 36564, 256, 36664, 256, 165330, 256, 165357, 256, + 1579, 262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, 262, 1646, + 262, 1722, 262, 1697, 262, 1647, 262, 1607, 514, 48, 46, 514, 48, 44, + 514, 49, 44, 514, 50, 44, 514, 51, 44, 514, 52, 44, 514, 53, 44, 514, 54, + 44, 514, 55, 44, 514, 56, 44, 514, 57, 44, 770, 40, 65, 41, 770, 40, 66, + 41, 770, 40, 67, 41, 770, 40, 68, 41, 770, 40, 69, 41, 770, 40, 70, 41, + 770, 40, 71, 41, 770, 40, 72, 41, 770, 40, 73, 41, 770, 40, 74, 41, 770, + 40, 75, 41, 770, 40, 76, 41, 770, 40, 77, 41, 770, 40, 78, 41, 770, 40, + 79, 41, 770, 40, 80, 41, 770, 40, 81, 41, 770, 40, 82, 41, 770, 40, 83, + 41, 770, 40, 84, 41, 770, 40, 85, 41, 770, 40, 86, 41, 770, 40, 87, 41, + 770, 40, 88, 41, 770, 40, 89, 41, 770, 40, 90, 41, 770, 12308, 83, 12309, + 519, 67, 68, 519, 87, 90, 266, 65, 266, 66, 266, 67, 266, 68, 266, 69, + 266, 70, 266, 71, 266, 72, 266, 73, 266, 74, 266, 75, 266, 76, 266, 77, + 266, 78, 266, 79, 266, 80, 266, 81, 266, 82, 266, 83, 266, 84, 266, 85, + 266, 86, 266, 87, 266, 88, 266, 89, 266, 90, 522, 72, 86, 522, 83, 68, + 522, 83, 83, 778, 80, 80, 86, 522, 87, 67, 515, 77, 67, 515, 77, 68, 515, + 77, 82, 522, 68, 74, 522, 12411, 12363, 522, 12467, 12467, 266, 12469, + 266, 25163, 266, 23383, 266, 21452, 266, 12487, 266, 20108, 266, 22810, + 266, 35299, 266, 22825, 266, 20132, 266, 26144, 266, 28961, 266, 26009, + 266, 21069, 266, 24460, 266, 20877, 266, 26032, 266, 21021, 266, 32066, + 266, 29983, 266, 36009, 266, 22768, 266, 21561, 266, 28436, 266, 25237, + 266, 25429, 266, 19968, 266, 19977, 266, 36938, 266, 24038, 266, 20013, + 266, 21491, 266, 25351, 266, 36208, 266, 25171, 266, 31105, 266, 31354, + 266, 21512, 266, 28288, 266, 26377, 266, 26376, 266, 30003, 266, 21106, + 266, 21942, 266, 37197, 770, 12308, 26412, 12309, 770, 12308, 19977, + 12309, 770, 12308, 20108, 12309, 770, 12308, 23433, 12309, 770, 12308, + 28857, 12309, 770, 12308, 25171, 12309, 770, 12308, 30423, 12309, 770, + 12308, 21213, 12309, 770, 12308, 25943, 12309, 263, 24471, 263, 21487, + 256, 20029, 256, 20024, 256, 20033, 256, 131362, 256, 20320, 256, 20411, + 256, 20482, 256, 20602, 256, 20633, 256, 20687, 256, 13470, 256, 132666, + 256, 20820, 256, 20836, 256, 20855, 256, 132380, 256, 13497, 256, 20839, + 256, 20877, 256, 132427, 256, 20887, 256, 20900, 256, 20172, 256, 20908, + 256, 168415, 256, 20981, 256, 20995, 256, 13535, 256, 21051, 256, 21062, + 256, 21106, 256, 21111, 256, 13589, 256, 21253, 256, 21254, 256, 21321, + 256, 21338, 256, 21363, 256, 21373, 256, 21375, 256, 133676, 256, 28784, + 256, 21450, 256, 21471, 256, 133987, 256, 21483, 256, 21489, 256, 21510, + 256, 21662, 256, 21560, 256, 21576, 256, 21608, 256, 21666, 256, 21750, + 256, 21776, 256, 21843, 256, 21859, 256, 21892, 256, 21931, 256, 21939, + 256, 21954, 256, 22294, 256, 22295, 256, 22097, 256, 22132, 256, 22766, + 256, 22478, 256, 22516, 256, 22541, 256, 22411, 256, 22578, 256, 22577, + 256, 22700, 256, 136420, 256, 22770, 256, 22775, 256, 22790, 256, 22810, + 256, 22818, 256, 22882, 256, 136872, 256, 136938, 256, 23020, 256, 23067, + 256, 23079, 256, 23000, 256, 23142, 256, 14062, 256, 14076, 256, 23304, + 256, 23358, 256, 137672, 256, 23491, 256, 23512, 256, 23539, 256, 138008, + 256, 23551, 256, 23558, 256, 24403, 256, 23586, 256, 14209, 256, 23648, + 256, 23744, 256, 23693, 256, 138724, 256, 23875, 256, 138726, 256, 23918, + 256, 23915, 256, 23932, 256, 24033, 256, 24034, 256, 14383, 256, 24061, + 256, 24104, 256, 24125, 256, 24169, 256, 14434, 256, 139651, 256, 14460, + 256, 24240, 256, 24243, 256, 24246, 256, 172946, 256, 24318, 256, 140081, + 256, 33281, 256, 24354, 256, 14535, 256, 144056, 256, 156122, 256, 24418, + 256, 24427, 256, 14563, 256, 24474, 256, 24525, 256, 24535, 256, 24569, + 256, 24705, 256, 14650, 256, 14620, 256, 141012, 256, 24775, 256, 24904, + 256, 24908, 256, 24954, 256, 25010, 256, 24996, 256, 25007, 256, 25054, + 256, 25104, 256, 25115, 256, 25181, 256, 25265, 256, 25300, 256, 25424, + 256, 142092, 256, 25405, 256, 25340, 256, 25448, 256, 25475, 256, 25572, + 256, 142321, 256, 25634, 256, 25541, 256, 25513, 256, 14894, 256, 25705, + 256, 25726, 256, 25757, 256, 25719, 256, 14956, 256, 25964, 256, 143370, + 256, 26083, 256, 26360, 256, 26185, 256, 15129, 256, 15112, 256, 15076, + 256, 20882, 256, 20885, 256, 26368, 256, 26268, 256, 32941, 256, 17369, + 256, 26401, 256, 26462, 256, 26451, 256, 144323, 256, 15177, 256, 26618, + 256, 26501, 256, 26706, 256, 144493, 256, 26766, 256, 26655, 256, 26900, + 256, 26946, 256, 27043, 256, 27114, 256, 27304, 256, 145059, 256, 27355, + 256, 15384, 256, 27425, 256, 145575, 256, 27476, 256, 15438, 256, 27506, + 256, 27551, 256, 27579, 256, 146061, 256, 138507, 256, 146170, 256, + 27726, 256, 146620, 256, 27839, 256, 27853, 256, 27751, 256, 27926, 256, + 27966, 256, 28009, 256, 28024, 256, 28037, 256, 146718, 256, 27956, 256, + 28207, 256, 28270, 256, 15667, 256, 28359, 256, 147153, 256, 28153, 256, + 28526, 256, 147294, 256, 147342, 256, 28614, 256, 28729, 256, 28699, 256, + 15766, 256, 28746, 256, 28797, 256, 28791, 256, 28845, 256, 132389, 256, + 28997, 256, 148067, 256, 29084, 256, 148395, 256, 29224, 256, 29264, 256, + 149000, 256, 29312, 256, 29333, 256, 149301, 256, 149524, 256, 29562, + 256, 29579, 256, 16044, 256, 29605, 256, 16056, 256, 29767, 256, 29788, + 256, 29829, 256, 29898, 256, 16155, 256, 29988, 256, 150582, 256, 30014, + 256, 150674, 256, 139679, 256, 30224, 256, 151457, 256, 151480, 256, + 151620, 256, 16380, 256, 16392, 256, 151795, 256, 151794, 256, 151833, + 256, 151859, 256, 30494, 256, 30495, 256, 30603, 256, 16454, 256, 16534, + 256, 152605, 256, 30798, 256, 16611, 256, 153126, 256, 153242, 256, + 153285, 256, 31211, 256, 16687, 256, 31306, 256, 31311, 256, 153980, 256, + 154279, 256, 31470, 256, 16898, 256, 154539, 256, 31686, 256, 31689, 256, + 16935, 256, 154752, 256, 31954, 256, 17056, 256, 31976, 256, 31971, 256, + 32000, 256, 155526, 256, 32099, 256, 17153, 256, 32199, 256, 32258, 256, + 32325, 256, 17204, 256, 156200, 256, 156231, 256, 17241, 256, 156377, + 256, 32634, 256, 156478, 256, 32661, 256, 32762, 256, 156890, 256, + 156963, 256, 32864, 256, 157096, 256, 32880, 256, 144223, 256, 17365, + 256, 32946, 256, 33027, 256, 17419, 256, 33086, 256, 23221, 256, 157607, + 256, 157621, 256, 144275, 256, 144284, 256, 33284, 256, 36766, 256, + 17515, 256, 33425, 256, 33419, 256, 33437, 256, 21171, 256, 33457, 256, + 33459, 256, 33469, 256, 33510, 256, 158524, 256, 33565, 256, 33635, 256, + 33709, 256, 33571, 256, 33725, 256, 33767, 256, 33619, 256, 33738, 256, + 33740, 256, 33756, 256, 158774, 256, 159083, 256, 158933, 256, 17707, + 256, 34033, 256, 34035, 256, 34070, 256, 160714, 256, 34148, 256, 159532, + 256, 17757, 256, 17761, 256, 159665, 256, 159954, 256, 17771, 256, 34384, + 256, 34407, 256, 34409, 256, 34473, 256, 34440, 256, 34574, 256, 34530, + 256, 34600, 256, 34667, 256, 34694, 256, 17879, 256, 34785, 256, 34817, + 256, 17913, 256, 34912, 256, 34915, 256, 161383, 256, 35031, 256, 35038, + 256, 17973, 256, 35066, 256, 13499, 256, 161966, 256, 162150, 256, 18110, + 256, 18119, 256, 35488, 256, 35925, 256, 162984, 256, 36011, 256, 36033, + 256, 36123, 256, 36215, 256, 163631, 256, 133124, 256, 36299, 256, 36284, + 256, 36336, 256, 133342, 256, 36564, 256, 165330, 256, 165357, 256, 37012, 256, 37105, 256, 37137, 256, 165678, 256, 37147, 256, 37432, 256, 37591, 256, 37592, 256, 37500, 256, 37881, 256, 37909, 256, 166906, 256, 38283, 256, 18837, 256, 38327, 256, 167287, 256, 18918, 256, 38595, 256, 23986, 256, 38691, 256, 168261, 256, 168474, 256, 19054, 256, 19062, 256, - 38880, 256, 168970, 256, 19122, 256, 169110, 256, 38923, 256, 38923, 256, - 38953, 256, 169398, 256, 39138, 256, 19251, 256, 39209, 256, 39335, 256, - 39362, 256, 39422, 256, 19406, 256, 170800, 256, 39698, 256, 40000, 256, - 40189, 256, 19662, 256, 19693, 256, 40295, 256, 172238, 256, 19704, 256, - 172293, 256, 172558, 256, 172689, 256, 40635, 256, 19798, 256, 40697, - 256, 40702, 256, 40709, 256, 40719, 256, 40726, 256, 40763, 256, 173568, + 38880, 256, 168970, 256, 19122, 256, 169110, 256, 38953, 256, 169398, + 256, 39138, 256, 19251, 256, 39209, 256, 39335, 256, 39362, 256, 39422, + 256, 19406, 256, 170800, 256, 40000, 256, 40189, 256, 19662, 256, 19693, + 256, 40295, 256, 172238, 256, 19704, 256, 172293, 256, 172558, 256, + 172689, 256, 40635, 256, 19798, 256, 40697, 256, 40702, 256, 40709, 256, + 40719, 256, 40726, 256, 40763, 256, 173568, }; /* index tables for the decomposition data */ @@ -4478,9 +4390,9 @@ static const unsigned char decomp_index1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 85, 0, 0, 0, 0, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 94, 95, 0, 0, 0, 0, 96, 97, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 95, 96, 0, 0, 0, 0, 97, 98, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4501,7 +4413,7 @@ static const unsigned char decomp_index1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 101, 102, 103, 104, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 102, 103, 104, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4849,116 +4761,116 @@ static const unsigned short decomp_index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 894, 896, 0, 898, 900, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 903, 0, 0, 0, 0, - 0, 905, 0, 0, 0, 908, 0, 0, 0, 0, 0, 910, 913, 916, 919, 921, 924, 927, - 0, 930, 0, 933, 936, 939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 942, 945, 948, 951, 954, 957, 960, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 963, 966, - 969, 972, 975, 0, 978, 980, 982, 984, 987, 990, 992, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 994, 996, 998, 0, - 1000, 1002, 0, 0, 0, 1004, 0, 0, 0, 0, 0, 0, 1006, 1009, 0, 1012, 0, 0, - 0, 1015, 0, 0, 0, 0, 1018, 1021, 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1030, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1033, 1036, 0, 1039, 0, 0, 0, 1042, 0, 0, 0, - 0, 1045, 1048, 1051, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1054, 1057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 905, 0, 0, 0, 908, 0, 0, 0, 0, 0, 15, 910, 913, 916, 918, 921, 924, 0, + 927, 0, 930, 933, 936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 939, 942, 945, 948, 951, 954, 957, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 960, 963, + 966, 969, 972, 0, 975, 977, 979, 981, 984, 987, 989, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 991, 993, 995, 0, + 997, 999, 0, 0, 0, 1001, 0, 0, 0, 0, 0, 0, 1003, 1006, 0, 1009, 0, 0, 0, + 1012, 0, 0, 0, 0, 1015, 1018, 1021, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1024, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1030, 1033, 0, 1036, 0, 0, 0, 1039, 0, 0, 0, 0, + 1042, 1045, 1048, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1051, 1054, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1060, 1063, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1066, 1069, 1072, 1075, 0, 0, 1078, 1081, 0, 0, 1084, 1087, - 1090, 1093, 1096, 1099, 0, 0, 1102, 1105, 1108, 1111, 1114, 1117, 0, 0, - 1120, 1123, 1126, 1129, 1132, 1135, 1138, 1141, 1144, 1147, 1150, 1153, - 0, 0, 1156, 1159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1162, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1057, 1060, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1063, 1066, 1069, 1072, 0, 0, 1075, 1078, 0, 0, 1081, 1084, + 1087, 1090, 1093, 1096, 0, 0, 1099, 1102, 1105, 1108, 1111, 1114, 0, 0, + 1117, 1120, 1123, 1126, 1129, 1132, 1135, 1138, 1141, 1144, 1147, 1150, + 0, 0, 1153, 1156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1165, 1168, 1171, 1174, 1177, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1162, 1165, 1168, 1171, 1174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1180, 1183, 1186, 1189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1177, 1180, 1183, 1186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1192, 0, 1195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1189, 0, 1192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1201, 0, 0, 0, - 0, 0, 0, 0, 1204, 0, 0, 1207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1210, - 1213, 1216, 1219, 1222, 1225, 1228, 1231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1198, 0, 0, 0, + 0, 0, 0, 0, 1201, 0, 0, 1204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1207, + 1210, 1213, 1216, 1219, 1222, 1225, 1228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1234, 1237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1240, 1243, - 0, 1246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1231, 1234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1237, 1240, + 0, 1243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1249, 0, 0, 1252, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1246, 0, 0, 1249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1255, 1258, 1261, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1252, 1255, 1258, 0, 0, 1261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1267, 0, 0, 1270, 1273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1276, 1279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1264, 0, 0, 1267, 1270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1273, 1276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1285, 1288, 1291, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1282, 1285, 1288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1297, 0, 0, 0, 0, 0, 0, 1300, 1303, 0, 1306, 1309, 0, 0, 0, 0, + 0, 0, 0, 1294, 0, 0, 0, 0, 0, 0, 1297, 1300, 0, 1303, 1306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1312, 1315, 1318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1309, 1312, 1315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1321, 0, 1324, 1327, 1330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1318, 0, 1321, 1324, 1327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1339, 1342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1336, 1339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1347, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1350, 0, 0, 0, 0, 1353, 0, 0, 0, 0, 1356, 0, 0, 0, 0, 1359, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1365, 0, - 1368, 1371, 1374, 1377, 1380, 0, 0, 0, 0, 0, 0, 0, 1383, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1386, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1389, 0, 0, 0, 0, 1392, 0, 0, 0, 0, 1395, 0, 0, 0, 0, 1398, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1344, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1347, 0, 0, 0, 0, 1350, 0, 0, 0, 0, 1353, 0, 0, 0, 0, 1356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1362, 0, + 1365, 1368, 1371, 1374, 1377, 0, 0, 0, 0, 0, 0, 0, 1380, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1383, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1386, 0, 0, 0, 0, 1389, 0, 0, 0, 0, 1392, 0, 0, 0, 0, 1395, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1404, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4967,252 +4879,252 @@ static const unsigned short decomp_index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1407, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1409, 0, 1412, 0, 1415, 0, 1418, 0, 1421, 0, 0, - 0, 1424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1427, 0, 1430, - 0, 0, 1433, 1436, 0, 1439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1404, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1406, 0, 1409, 0, 1412, 0, 1415, 0, 1418, 0, 0, + 0, 1421, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1424, 0, 1427, + 0, 0, 1430, 1433, 0, 1436, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1442, 1444, 1446, 0, - 1448, 1450, 1452, 1454, 1456, 1458, 1460, 1462, 1464, 1466, 1468, 0, - 1470, 1472, 1474, 1476, 1478, 1480, 1482, 1484, 1486, 1488, 1490, 1492, - 1494, 1496, 1498, 1500, 1502, 1504, 0, 1506, 1508, 1510, 1512, 1514, - 1516, 1518, 1520, 1522, 1524, 1526, 1528, 1530, 1532, 1534, 1536, 1538, - 1540, 1542, 1544, 1546, 1548, 1550, 1552, 1554, 1556, 1558, 1560, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1439, 1441, 1443, 0, + 1445, 1447, 1449, 1451, 1453, 1455, 1457, 1459, 1461, 1463, 1465, 0, + 1467, 1469, 1471, 1473, 1475, 1477, 1479, 6, 1481, 1483, 1485, 1487, + 1489, 1491, 1493, 1495, 1497, 1499, 0, 1501, 1503, 1505, 25, 1507, 1509, + 1511, 1513, 1515, 1517, 1519, 1521, 1523, 1525, 1527, 1529, 1531, 1533, + 1535, 1537, 1539, 1541, 1543, 1545, 1547, 1549, 1551, 1553, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1557, + 1559, 1561, 1563, 1497, 1565, 1567, 1569, 1571, 1573, 1575, 1577, 1579, + 1581, 1583, 1585, 1587, 1589, 1591, 1593, 1595, 1597, 1599, 1601, 1603, + 1605, 1607, 1609, 1611, 1613, 1615, 1617, 1619, 1621, 1623, 1625, 1627, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1629, 1632, 1635, 1638, + 1641, 1644, 1647, 1650, 1653, 1656, 1659, 1662, 1665, 1668, 1671, 1674, + 1677, 1680, 1683, 1686, 1689, 1692, 1695, 1698, 1701, 1704, 1707, 1710, + 1713, 1716, 1719, 1722, 1725, 1728, 1731, 1734, 1737, 1740, 1743, 1746, + 1749, 1752, 1755, 1758, 1761, 1764, 1767, 1770, 1773, 1776, 1779, 1782, + 1785, 1788, 1791, 1794, 1797, 1800, 1803, 1806, 1809, 1812, 1815, 1818, + 1821, 1824, 1827, 1830, 1833, 1836, 1839, 1842, 1845, 1848, 1851, 1854, + 1857, 1860, 1863, 1866, 1869, 1872, 1875, 1878, 1881, 1884, 1887, 1890, + 1893, 1896, 1899, 1902, 1905, 1908, 1911, 1914, 1917, 1920, 1923, 1926, + 1929, 1932, 1935, 1938, 1941, 1944, 1947, 1950, 1953, 1956, 1959, 1962, + 1965, 1968, 1971, 1974, 1977, 1980, 1983, 1986, 1989, 1992, 1995, 1998, + 2001, 2004, 2007, 2010, 2013, 2016, 2019, 2022, 2025, 2028, 2031, 2034, + 2037, 2040, 2043, 2046, 2049, 2052, 2055, 2058, 2061, 2064, 2067, 2070, + 2073, 2076, 2079, 2082, 2085, 2088, 2091, 2094, 0, 0, 0, 0, 2097, 2100, + 2103, 2106, 2109, 2112, 2115, 2118, 2121, 2124, 2127, 2130, 2133, 2136, + 2139, 2142, 2145, 2148, 2151, 2154, 2157, 2160, 2163, 2166, 2169, 2172, + 2175, 2178, 2181, 2184, 2187, 2190, 2193, 2196, 2199, 2202, 2205, 2208, + 2211, 2214, 2217, 2220, 2223, 2226, 2229, 2232, 2235, 2238, 2241, 2244, + 2247, 2250, 2253, 2256, 2259, 2262, 2265, 2268, 2271, 2274, 2277, 2280, + 2283, 2286, 2289, 2292, 2295, 2298, 2301, 2304, 2307, 2310, 2313, 2316, + 2319, 2322, 2325, 2328, 2331, 2334, 2337, 2340, 2343, 2346, 2349, 2352, + 2355, 2358, 2361, 2364, 0, 0, 0, 0, 0, 0, 2367, 2370, 2373, 2376, 2379, + 2382, 2385, 2388, 2391, 2394, 2397, 2400, 2403, 2406, 2409, 2412, 2415, + 2418, 2421, 2424, 2427, 2430, 0, 0, 2433, 2436, 2439, 2442, 2445, 2448, + 0, 0, 2451, 2454, 2457, 2460, 2463, 2466, 2469, 2472, 2475, 2478, 2481, + 2484, 2487, 2490, 2493, 2496, 2499, 2502, 2505, 2508, 2511, 2514, 2517, + 2520, 2523, 2526, 2529, 2532, 2535, 2538, 2541, 2544, 2547, 2550, 2553, + 2556, 2559, 2562, 0, 0, 2565, 2568, 2571, 2574, 2577, 2580, 0, 0, 2583, + 2586, 2589, 2592, 2595, 2598, 2601, 2604, 0, 2607, 0, 2610, 0, 2613, 0, + 2616, 2619, 2622, 2625, 2628, 2631, 2634, 2637, 2640, 2643, 2646, 2649, + 2652, 2655, 2658, 2661, 2664, 2667, 2670, 2672, 2675, 2677, 2680, 2682, + 2685, 2687, 2690, 2692, 2695, 2697, 2700, 0, 0, 2702, 2705, 2708, 2711, + 2714, 2717, 2720, 2723, 2726, 2729, 2732, 2735, 2738, 2741, 2744, 2747, + 2750, 2753, 2756, 2759, 2762, 2765, 2768, 2771, 2774, 2777, 2780, 2783, + 2786, 2789, 2792, 2795, 2798, 2801, 2804, 2807, 2810, 2813, 2816, 2819, + 2822, 2825, 2828, 2831, 2834, 2837, 2840, 2843, 2846, 2849, 2852, 2855, + 2858, 0, 2861, 2864, 2867, 2870, 2873, 2876, 2878, 2881, 2884, 2881, + 2886, 2889, 2892, 2895, 2898, 0, 2901, 2904, 2907, 2910, 2912, 2915, + 2917, 2920, 2923, 2926, 2929, 2932, 2935, 2938, 0, 0, 2940, 2943, 2946, + 2949, 2952, 2955, 0, 2957, 2960, 2963, 2966, 2969, 2972, 2975, 2977, + 2980, 2983, 2986, 2989, 2992, 2995, 2998, 3000, 3003, 3006, 3008, 0, 0, + 3010, 3013, 3016, 0, 3019, 3022, 3025, 3028, 3030, 3033, 3035, 3038, + 3040, 0, 3043, 3045, 3047, 3047, 3047, 3047, 3047, 1, 3047, 3047, 3047, + 0, 0, 0, 0, 0, 0, 3049, 0, 0, 0, 0, 0, 3051, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3054, 3056, 3059, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3063, + 3066, 0, 3070, 3073, 0, 0, 0, 0, 3077, 0, 3080, 0, 0, 0, 0, 0, 0, 0, 0, + 3083, 3086, 3089, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3092, 0, 0, 0, + 0, 0, 0, 0, 3047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3097, + 3099, 0, 0, 3101, 3103, 3105, 3107, 3109, 3111, 3113, 3115, 3117, 3119, + 3121, 3123, 3125, 3127, 3129, 3131, 3133, 3135, 3137, 3139, 3141, 3143, + 3145, 3147, 3149, 3151, 3153, 0, 3155, 3157, 3159, 3161, 3163, 3165, + 3167, 3169, 3171, 3173, 3175, 3177, 3179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3184, 3188, 3192, + 3194, 0, 3197, 3201, 3205, 0, 3207, 3210, 3212, 3212, 3212, 3214, 3216, + 3218, 3218, 3220, 3222, 0, 3224, 3226, 0, 0, 3229, 3231, 3233, 3233, + 3233, 0, 0, 3235, 3238, 3242, 0, 3245, 0, 3247, 0, 3245, 0, 3249, 3251, + 3253, 3192, 0, 3255, 3257, 3259, 0, 3261, 3263, 3265, 3267, 3269, 3271, + 3273, 0, 3275, 3279, 3281, 3283, 3285, 3287, 0, 0, 0, 0, 3289, 3291, + 3255, 3273, 3293, 0, 0, 0, 0, 0, 0, 3295, 3299, 3303, 3308, 3312, 3316, + 3320, 3324, 3328, 3332, 3336, 3340, 3344, 3348, 3352, 3356, 3359, 3361, + 3364, 3368, 3371, 3373, 3376, 3380, 3385, 3388, 3390, 3393, 3397, 3399, + 3401, 3403, 3405, 3407, 3410, 3414, 3417, 3419, 3422, 3426, 3431, 3434, + 3436, 3439, 3443, 3445, 3447, 3449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3451, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3455, 3458, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3461, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3464, + 3467, 3470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3473, 0, 0, 0, 0, 3476, 0, 0, 3479, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3482, 0, 3485, + 0, 0, 0, 0, 0, 3488, 3491, 0, 3495, 3498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3502, 0, 0, 3505, 0, 0, 3508, 0, 3511, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3514, 0, 3517, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3520, 3523, 3526, 3529, 3532, 0, 0, 3535, 3538, + 0, 0, 3541, 3544, 0, 0, 0, 0, 0, 0, 3547, 3550, 0, 0, 3553, 3556, 0, 0, + 3559, 3562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3565, 3568, 3571, 3574, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3577, + 3580, 3583, 3586, 0, 0, 0, 0, 0, 0, 3589, 3592, 3595, 3598, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3601, 3603, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3605, 3607, 3609, 3611, 3613, 3615, 3617, 3619, 3621, 3623, 3626, 3629, + 3632, 3635, 3638, 3641, 3644, 3647, 3650, 3653, 3656, 3660, 3664, 3668, + 3672, 3676, 3680, 3684, 3688, 3692, 3697, 3702, 3707, 3712, 3717, 3722, + 3727, 3732, 3737, 3742, 3747, 3750, 3753, 3756, 3759, 3762, 3765, 3768, + 3771, 3774, 3778, 3782, 3786, 3790, 3794, 3798, 3802, 3806, 3810, 3814, + 3818, 3822, 3826, 3830, 3834, 3838, 3842, 3846, 3850, 3854, 3858, 3862, + 3866, 3870, 3874, 3878, 3882, 3886, 3890, 3894, 3898, 3902, 3906, 3910, + 3914, 3918, 3922, 3924, 3926, 3928, 3930, 3932, 3934, 3936, 3938, 3940, + 3942, 3944, 3946, 3948, 3950, 3952, 3954, 3956, 3958, 3960, 3962, 3964, + 3966, 3968, 3970, 3972, 3974, 3976, 3978, 3980, 3982, 3984, 3986, 3988, + 3990, 3992, 3994, 3996, 3998, 4000, 4002, 4004, 4006, 4008, 4010, 4012, + 4014, 4016, 4018, 4020, 4022, 4024, 4026, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1564, 1566, 1568, 1570, 1572, 1574, 1576, 1578, 1580, 1582, 1584, 1586, - 1588, 1590, 1592, 1594, 1596, 1598, 1600, 1602, 1604, 1606, 1608, 1610, - 1612, 1614, 1616, 1618, 1620, 1622, 1624, 1626, 1628, 1630, 1632, 1634, - 1636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1638, 1641, 1644, - 1647, 1650, 1653, 1656, 1659, 1662, 1665, 1668, 1671, 1674, 1677, 1680, - 1683, 1686, 1689, 1692, 1695, 1698, 1701, 1704, 1707, 1710, 1713, 1716, - 1719, 1722, 1725, 1728, 1731, 1734, 1737, 1740, 1743, 1746, 1749, 1752, - 1755, 1758, 1761, 1764, 1767, 1770, 1773, 1776, 1779, 1782, 1785, 1788, - 1791, 1794, 1797, 1800, 1803, 1806, 1809, 1812, 1815, 1818, 1821, 1824, - 1827, 1830, 1833, 1836, 1839, 1842, 1845, 1848, 1851, 1854, 1857, 1860, - 1863, 1866, 1869, 1872, 1875, 1878, 1881, 1884, 1887, 1890, 1893, 1896, - 1899, 1902, 1905, 1908, 1911, 1914, 1917, 1920, 1923, 1926, 1929, 1932, - 1935, 1938, 1941, 1944, 1947, 1950, 1953, 1956, 1959, 1962, 1965, 1968, - 1971, 1974, 1977, 1980, 1983, 1986, 1989, 1992, 1995, 1998, 2001, 2004, - 2007, 2010, 2013, 2016, 2019, 2022, 2025, 2028, 2031, 2034, 2037, 2040, - 2043, 2046, 2049, 2052, 2055, 2058, 2061, 2064, 2067, 2070, 2073, 2076, - 2079, 2082, 2085, 2088, 2091, 2094, 2097, 2100, 2103, 0, 0, 0, 0, 2106, - 2109, 2112, 2115, 2118, 2121, 2124, 2127, 2130, 2133, 2136, 2139, 2142, - 2145, 2148, 2151, 2154, 2157, 2160, 2163, 2166, 2169, 2172, 2175, 2178, - 2181, 2184, 2187, 2190, 2193, 2196, 2199, 2202, 2205, 2208, 2211, 2214, - 2217, 2220, 2223, 2226, 2229, 2232, 2235, 2238, 2241, 2244, 2247, 2250, - 2253, 2256, 2259, 2262, 2265, 2268, 2271, 2274, 2277, 2280, 2283, 2286, - 2289, 2292, 2295, 2298, 2301, 2304, 2307, 2310, 2313, 2316, 2319, 2322, - 2325, 2328, 2331, 2334, 2337, 2340, 2343, 2346, 2349, 2352, 2355, 2358, - 2361, 2364, 2367, 2370, 2373, 0, 0, 0, 0, 0, 0, 2376, 2379, 2382, 2385, - 2388, 2391, 2394, 2397, 2400, 2403, 2406, 2409, 2412, 2415, 2418, 2421, - 2424, 2427, 2430, 2433, 2436, 2439, 0, 0, 2442, 2445, 2448, 2451, 2454, - 2457, 0, 0, 2460, 2463, 2466, 2469, 2472, 2475, 2478, 2481, 2484, 2487, - 2490, 2493, 2496, 2499, 2502, 2505, 2508, 2511, 2514, 2517, 2520, 2523, - 2526, 2529, 2532, 2535, 2538, 2541, 2544, 2547, 2550, 2553, 2556, 2559, - 2562, 2565, 2568, 2571, 0, 0, 2574, 2577, 2580, 2583, 2586, 2589, 0, 0, - 2592, 2595, 2598, 2601, 2604, 2607, 2610, 2613, 0, 2616, 0, 2619, 0, - 2622, 0, 2625, 2628, 2631, 2634, 2637, 2640, 2643, 2646, 2649, 2652, - 2655, 2658, 2661, 2664, 2667, 2670, 2673, 2676, 2679, 2681, 2684, 2686, - 2689, 2691, 2694, 2696, 2699, 2701, 2704, 2706, 2709, 0, 0, 2711, 2714, - 2717, 2720, 2723, 2726, 2729, 2732, 2735, 2738, 2741, 2744, 2747, 2750, - 2753, 2756, 2759, 2762, 2765, 2768, 2771, 2774, 2777, 2780, 2783, 2786, - 2789, 2792, 2795, 2798, 2801, 2804, 2807, 2810, 2813, 2816, 2819, 2822, - 2825, 2828, 2831, 2834, 2837, 2840, 2843, 2846, 2849, 2852, 2855, 2858, - 2861, 2864, 2867, 0, 2870, 2873, 2876, 2879, 2882, 2885, 2887, 2890, - 2893, 2895, 2898, 2901, 2904, 2907, 2910, 0, 2913, 2916, 2919, 2922, - 2924, 2927, 2929, 2932, 2935, 2938, 2941, 2944, 2947, 2950, 0, 0, 2952, - 2955, 2958, 2961, 2964, 2967, 0, 2969, 2972, 2975, 2978, 2981, 2984, - 2987, 2989, 2992, 2995, 2998, 3001, 3004, 3007, 3010, 3012, 3015, 3018, - 3020, 0, 0, 3022, 3025, 3028, 0, 3031, 3034, 3037, 3040, 3042, 3045, - 3047, 3050, 3052, 0, 3055, 3057, 3059, 3061, 3063, 3065, 3067, 3069, - 3071, 3073, 3075, 0, 0, 0, 0, 0, 0, 3077, 0, 0, 0, 0, 0, 3079, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3082, 3084, 3087, 0, 0, 0, 0, 0, 0, 0, 0, - 3091, 0, 0, 0, 3093, 3096, 0, 3100, 3103, 0, 0, 0, 0, 3107, 0, 3110, 0, - 0, 0, 0, 0, 0, 0, 0, 3113, 3116, 3119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3122, 0, 0, 0, 0, 0, 0, 0, 3127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3129, 3131, 0, 0, 3133, 3135, 3137, 3139, 3141, 3143, - 3145, 3147, 3149, 3151, 3153, 3155, 3157, 3159, 3161, 3163, 3165, 3167, - 3169, 3171, 3173, 3175, 3177, 3179, 3181, 3183, 3185, 0, 3187, 3189, - 3191, 3193, 3195, 3197, 3199, 3201, 3203, 3205, 3207, 3209, 3211, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4028, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3216, 3220, 3224, 3226, 0, 3229, 3233, 3237, 0, 3239, 3242, 3244, - 3246, 3248, 3250, 3252, 3254, 3256, 3258, 3260, 0, 3262, 3264, 0, 0, - 3267, 3269, 3271, 3273, 3275, 0, 0, 3277, 3280, 3284, 0, 3287, 0, 3289, - 0, 3291, 0, 3293, 3295, 3297, 3299, 0, 3301, 3303, 3305, 0, 3307, 3309, - 3311, 3313, 3315, 3317, 3319, 0, 3321, 3325, 3327, 3329, 3331, 3333, 0, - 0, 0, 0, 3335, 3337, 3339, 3341, 3343, 0, 0, 0, 0, 0, 0, 3345, 3349, - 3353, 3358, 3362, 3366, 3370, 3374, 3378, 3382, 3386, 3390, 3394, 3398, - 3402, 3406, 3409, 3411, 3414, 3418, 3421, 3423, 3426, 3430, 3435, 3438, - 3440, 3443, 3447, 3449, 3451, 3453, 3455, 3457, 3460, 3464, 3467, 3469, - 3472, 3476, 3481, 3484, 3486, 3489, 3493, 3495, 3497, 3499, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3505, 3508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3511, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4033, 4037, 4040, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3514, 3517, 3520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3523, 0, 0, 0, 0, 3526, - 0, 0, 3529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3532, 0, 3535, 0, 0, 0, 0, 0, 3538, 3541, 0, 3545, 3548, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3552, 0, 0, 3555, 0, 0, 3558, - 0, 3561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3564, 0, 3567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3570, 3573, 3576, 3579, - 3582, 0, 0, 3585, 3588, 0, 0, 3591, 3594, 0, 0, 0, 0, 0, 0, 3597, 3600, - 0, 0, 3603, 3606, 0, 0, 3609, 3612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3615, - 3618, 3621, 3624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3627, 3630, 3633, 3636, 0, 0, 0, 0, 0, 0, 3639, 3642, - 3645, 3648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3651, 3653, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4044, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3655, 3657, 3659, 3661, 3663, 3665, 3667, 3669, - 3671, 3673, 3676, 3679, 3682, 3685, 3688, 3691, 3694, 3697, 3700, 3703, - 3706, 3710, 3714, 3718, 3722, 3726, 3730, 3734, 3738, 3742, 3747, 3752, - 3757, 3762, 3767, 3772, 3777, 3782, 3787, 3792, 3797, 3800, 3803, 3806, - 3809, 3812, 3815, 3818, 3821, 3824, 3828, 3832, 3836, 3840, 3844, 3848, - 3852, 3856, 3860, 3864, 3868, 3872, 3876, 3880, 3884, 3888, 3892, 3896, - 3900, 3904, 3908, 3912, 3916, 3920, 3924, 3928, 3932, 3936, 3940, 3944, - 3948, 3952, 3956, 3960, 3964, 3968, 3972, 3974, 3976, 3978, 3980, 3982, - 3984, 3986, 3988, 3990, 3992, 3994, 3996, 3998, 4000, 4002, 4004, 4006, - 4008, 4010, 4012, 4014, 4016, 4018, 4020, 4022, 4024, 4026, 4028, 4030, - 4032, 4034, 4036, 4038, 4040, 4042, 4044, 4046, 4048, 4050, 4052, 4054, - 4056, 4058, 4060, 4062, 4064, 4066, 4068, 4070, 4072, 4074, 4076, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4078, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4083, 4087, 4090, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4047, 4049, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4094, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4051, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4053, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4057, 4059, 4061, 4063, 4065, + 4067, 4069, 4071, 4073, 4075, 4077, 4079, 4081, 4083, 4085, 4087, 4089, + 4091, 4093, 4095, 4097, 4099, 4101, 4103, 4105, 4107, 4109, 4111, 4113, + 4115, 4117, 4119, 4121, 4123, 4125, 4127, 4129, 4131, 4133, 4135, 4137, + 4139, 4141, 4143, 4145, 4147, 4149, 4151, 4153, 4155, 4157, 4159, 4161, + 4163, 4165, 4167, 4169, 4171, 4173, 4175, 4177, 4179, 4181, 4183, 4185, + 4187, 4189, 4191, 4193, 4195, 4197, 4199, 4201, 4203, 4205, 4207, 4209, + 4211, 4213, 4215, 4217, 4219, 4221, 4223, 4225, 4227, 4229, 4231, 4233, + 4235, 4237, 4239, 4241, 4243, 4245, 4247, 4249, 4251, 4253, 4255, 4257, + 4259, 4261, 4263, 4265, 4267, 4269, 4271, 4273, 4275, 4277, 4279, 4281, + 4283, 4285, 4287, 4289, 4291, 4293, 4295, 4297, 4299, 4301, 4303, 4305, + 4307, 4309, 4311, 4313, 4315, 4317, 4319, 4321, 4323, 4325, 4327, 4329, + 4331, 4333, 4335, 4337, 4339, 4341, 4343, 4345, 4347, 4349, 4351, 4353, + 4355, 4357, 4359, 4361, 4363, 4365, 4367, 4369, 4371, 4373, 4375, 4377, + 4379, 4381, 4383, 4385, 4387, 4389, 4391, 4393, 4395, 4397, 4399, 4401, + 4403, 4405, 4407, 4409, 4411, 4413, 4415, 4417, 4419, 4421, 4423, 4425, + 4427, 4429, 4431, 4433, 4435, 4437, 4439, 4441, 4443, 4445, 4447, 4449, + 4451, 4453, 4455, 4457, 4459, 4461, 4463, 4465, 4467, 4469, 4471, 4473, + 4475, 4477, 4479, 4481, 4483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4097, 4099, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4487, 0, 4103, 4489, 4491, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4493, 0, 4496, 0, 4499, 0, 4502, + 0, 4505, 0, 4508, 0, 4511, 0, 4514, 0, 4517, 0, 4520, 0, 4523, 0, 4526, + 0, 0, 4529, 0, 4532, 0, 4535, 0, 0, 0, 0, 0, 0, 4538, 4541, 0, 4544, + 4547, 0, 4550, 4553, 0, 4556, 4559, 0, 4562, 4565, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4568, 0, 0, 0, 0, 0, 0, + 4571, 4574, 0, 4577, 4580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4583, 0, + 4586, 0, 4589, 0, 4592, 0, 4595, 0, 4598, 0, 4601, 0, 4604, 0, 4607, 0, + 4610, 0, 4613, 0, 4616, 0, 0, 4619, 0, 4622, 0, 4625, 0, 0, 0, 0, 0, 0, + 4628, 4631, 0, 4634, 4637, 0, 4640, 4643, 0, 4646, 4649, 0, 4652, 4655, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4658, + 0, 0, 4661, 4664, 4667, 4670, 0, 0, 0, 4673, 4676, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4679, 4681, 4683, + 4685, 4687, 4689, 4691, 4693, 4695, 4697, 4699, 4701, 4703, 4705, 4707, + 4709, 4711, 4713, 4715, 4717, 4719, 4721, 4723, 4725, 4727, 4729, 4731, + 4733, 4735, 4737, 4739, 4741, 4743, 4745, 4747, 4749, 4751, 4753, 4755, + 4757, 4759, 4761, 4763, 4765, 4767, 4769, 4771, 4773, 4775, 4777, 4779, + 4781, 4783, 4785, 4787, 4789, 4791, 4793, 4795, 4797, 4799, 4801, 4803, + 4805, 4807, 4809, 4811, 4813, 4815, 4817, 4819, 4821, 4823, 4825, 4827, + 4829, 4831, 4833, 4835, 4837, 4839, 4841, 4843, 4845, 4847, 4849, 4851, + 4853, 4855, 4857, 4859, 4861, 4863, 4865, 0, 0, 0, 4867, 4869, 4871, + 4873, 4875, 4877, 4879, 4881, 4883, 4885, 4887, 4889, 4891, 4893, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4101, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4103, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4107, - 4109, 4111, 4113, 4115, 4117, 4119, 4121, 4123, 4125, 4127, 4129, 4131, - 4133, 4135, 4137, 4139, 4141, 4143, 4145, 4147, 4149, 4151, 4153, 4155, - 4157, 4159, 4161, 4163, 4165, 4167, 4169, 4171, 4173, 4175, 4177, 4179, - 4181, 4183, 4185, 4187, 4189, 4191, 4193, 4195, 4197, 4199, 4201, 4203, - 4205, 4207, 4209, 4211, 4213, 4215, 4217, 4219, 4221, 4223, 4225, 4227, - 4229, 4231, 4233, 4235, 4237, 4239, 4241, 4243, 4245, 4247, 4249, 4251, - 4253, 4255, 4257, 4259, 4261, 4263, 4265, 4267, 4269, 4271, 4273, 4275, - 4277, 4279, 4281, 4283, 4285, 4287, 4289, 4291, 4293, 4295, 4297, 4299, - 4301, 4303, 4305, 4307, 4309, 4311, 4313, 4315, 4317, 4319, 4321, 4323, - 4325, 4327, 4329, 4331, 4333, 4335, 4337, 4339, 4341, 4343, 4345, 4347, - 4349, 4351, 4353, 4355, 4357, 4359, 4361, 4363, 4365, 4367, 4369, 4371, - 4373, 4375, 4377, 4379, 4381, 4383, 4385, 4387, 4389, 4391, 4393, 4395, - 4397, 4399, 4401, 4403, 4405, 4407, 4409, 4411, 4413, 4415, 4417, 4419, - 4421, 4423, 4425, 4427, 4429, 4431, 4433, 4435, 4437, 4439, 4441, 4443, - 4445, 4447, 4449, 4451, 4453, 4455, 4457, 4459, 4461, 4463, 4465, 4467, - 4469, 4471, 4473, 4475, 4477, 4479, 4481, 4483, 4485, 4487, 4489, 4491, - 4493, 4495, 4497, 4499, 4501, 4503, 4505, 4507, 4509, 4511, 4513, 4515, - 4517, 4519, 4521, 4523, 4525, 4527, 4529, 4531, 4533, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4537, 0, 4539, - 4541, 4543, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4545, 0, - 4548, 0, 4551, 0, 4554, 0, 4557, 0, 4560, 0, 4563, 0, 4566, 0, 4569, 0, - 4572, 0, 4575, 0, 4578, 0, 0, 4581, 0, 4584, 0, 4587, 0, 0, 0, 0, 0, 0, - 4590, 4593, 0, 4596, 4599, 0, 4602, 4605, 0, 4608, 4611, 0, 4614, 4617, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4620, - 0, 0, 0, 0, 0, 0, 4623, 4626, 0, 4629, 4632, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4635, 0, 4638, 0, 4641, 0, 4644, 0, 4647, 0, 4650, 0, 4653, 0, - 4656, 0, 4659, 0, 4662, 0, 4665, 0, 4668, 0, 0, 4671, 0, 4674, 0, 4677, - 0, 0, 0, 0, 0, 0, 4680, 4683, 0, 4686, 4689, 0, 4692, 4695, 0, 4698, - 4701, 0, 4704, 4707, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4710, 0, 0, 4713, 4716, 4719, 4722, 0, 0, 0, 4725, 4728, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4731, 4733, 4735, 4737, 4739, 4741, 4743, 4745, 4747, 4749, 4751, - 4753, 4755, 4757, 4759, 4761, 4763, 4765, 4767, 4769, 4771, 4773, 4775, - 4777, 4779, 4781, 4783, 4785, 4787, 4789, 4791, 4793, 4795, 4797, 4799, - 4801, 4803, 4805, 4807, 4809, 4811, 4813, 4815, 4817, 4819, 4821, 4823, - 4825, 4827, 4829, 4831, 4833, 4835, 4837, 4839, 4841, 4843, 4845, 4847, - 4849, 4851, 4853, 4855, 4857, 4859, 4861, 4863, 4865, 4867, 4869, 4871, - 4873, 4875, 4877, 4879, 4881, 4883, 4885, 4887, 4889, 4891, 4893, 4895, - 4897, 4899, 4901, 4903, 4905, 4907, 4909, 4911, 4913, 4915, 4917, 0, 0, - 0, 4919, 4921, 4923, 4925, 4927, 4929, 4931, 4933, 4935, 4937, 4939, - 4941, 4943, 4945, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4947, 4951, 4955, 4959, 4963, 4967, 4971, 4975, 4979, - 4983, 4987, 4991, 4995, 4999, 5003, 5008, 5013, 5018, 5023, 5028, 5033, - 5038, 5043, 5048, 5053, 5058, 5063, 5068, 5073, 5078, 5086, 0, 5093, - 5097, 5101, 5105, 5109, 5113, 5117, 5121, 5125, 5129, 5133, 5137, 5141, - 5145, 5149, 5153, 5157, 5161, 5165, 5169, 5173, 5177, 5181, 5185, 5189, - 5193, 5197, 5201, 5205, 5209, 5213, 5217, 5221, 5225, 5229, 5233, 5237, - 5239, 5241, 5243, 0, 0, 0, 0, 0, 0, 0, 0, 5245, 5249, 5252, 5255, 5258, - 5261, 5264, 5267, 5270, 5273, 5276, 5279, 5282, 5285, 5288, 5291, 5294, - 5296, 5298, 5300, 5302, 5304, 5306, 5308, 5310, 5312, 5314, 5316, 5318, - 5320, 5322, 5325, 5328, 5331, 5334, 5337, 5340, 5343, 5346, 5349, 5352, - 5355, 5358, 5361, 5364, 5370, 5375, 0, 5378, 5380, 5382, 5384, 5386, - 5388, 5390, 5392, 5394, 5396, 5398, 5400, 5402, 5404, 5406, 5408, 5410, - 5412, 5414, 5416, 5418, 5420, 5422, 5424, 5426, 5428, 5430, 5432, 5434, - 5436, 5438, 5440, 5442, 5444, 5446, 5448, 5450, 5452, 5454, 5456, 5458, - 5460, 5462, 5464, 5466, 5468, 5470, 5472, 5474, 5476, 5479, 5482, 5485, - 5488, 5491, 5494, 5497, 5500, 5503, 5506, 5509, 5512, 5515, 5518, 5521, - 5524, 5527, 5530, 5533, 5536, 5539, 5542, 5545, 5548, 5552, 5556, 5560, - 5563, 5567, 5570, 5574, 5576, 5578, 5580, 5582, 5584, 5586, 5588, 5590, - 5592, 5594, 5596, 5598, 5600, 5602, 5604, 5606, 5608, 5610, 5612, 5614, - 5616, 5618, 5620, 5622, 5624, 5626, 5628, 5630, 5632, 5634, 5636, 5638, - 5640, 5642, 5644, 5646, 5648, 5650, 5652, 5654, 5656, 5658, 5660, 5662, - 5664, 5666, 5668, 5671, 5676, 5681, 5686, 5690, 5695, 5699, 5703, 5709, - 5714, 5718, 5722, 5726, 5731, 5736, 5740, 5744, 5747, 5751, 5756, 5761, - 5764, 5770, 5777, 5783, 5787, 5793, 5799, 5804, 5808, 5812, 5816, 5821, - 5827, 5832, 5836, 5840, 5844, 5847, 5850, 5853, 5856, 5860, 5864, 5870, - 5874, 5879, 5885, 5889, 5892, 5895, 5901, 5906, 5912, 5916, 5922, 5925, - 5929, 5933, 5937, 5941, 5945, 5950, 5954, 5957, 5961, 5965, 5969, 5974, - 5978, 5982, 5986, 5992, 5997, 6000, 6006, 6009, 6014, 6019, 6023, 6027, - 6031, 6036, 6039, 6043, 6048, 6051, 6057, 6061, 6064, 6067, 6070, 6073, - 6076, 6079, 6082, 6085, 6088, 6091, 6095, 6099, 6103, 6107, 6111, 6115, - 6119, 6123, 6127, 6131, 6135, 6139, 6143, 6147, 6151, 6155, 6158, 6161, - 6165, 6168, 6171, 6174, 6178, 6182, 6185, 6188, 6191, 6194, 6197, 6202, - 6205, 6208, 6211, 6214, 6217, 6220, 6223, 6226, 6230, 6235, 6238, 6241, - 6244, 6247, 6250, 6253, 6256, 6260, 6264, 6268, 6272, 6275, 6278, 6281, - 6284, 6287, 6290, 6293, 6296, 6299, 6302, 6306, 6310, 6313, 6317, 6321, - 6325, 6328, 6332, 6336, 6341, 6344, 6348, 6352, 6356, 6360, 6366, 6373, - 6376, 6379, 6382, 6385, 6388, 6391, 6394, 6397, 6400, 6403, 6406, 6409, - 6412, 6415, 6418, 6421, 6424, 6427, 6432, 6435, 6438, 6441, 6446, 6450, - 6453, 6456, 6459, 6462, 6465, 6468, 6471, 6474, 6477, 6480, 6484, 6487, - 6490, 6494, 6498, 6501, 6506, 6510, 6513, 6516, 6519, 6522, 6526, 6530, - 6533, 6536, 6539, 6542, 6545, 6548, 6551, 6554, 6557, 6561, 6565, 6569, - 6573, 6577, 6581, 6585, 6589, 6593, 6597, 6601, 6605, 6609, 6613, 6617, - 6621, 6625, 6629, 6633, 6637, 6641, 6645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6649, 6651, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4895, + 4899, 4903, 4907, 4911, 4915, 4919, 4923, 4927, 4931, 4935, 4939, 4943, + 4947, 4951, 4956, 4961, 4966, 4971, 4976, 4981, 4986, 4991, 4996, 5001, + 5006, 5011, 5016, 5021, 5026, 5034, 0, 5041, 5045, 5049, 5053, 5057, + 5061, 5065, 5069, 5073, 5077, 5081, 5085, 5089, 5093, 5097, 5101, 5105, + 5109, 5113, 5117, 5121, 5125, 5129, 5133, 5137, 5141, 5145, 5149, 5153, + 5157, 5161, 5165, 5169, 5173, 5177, 5181, 5185, 5187, 5189, 5191, 0, 0, + 0, 0, 0, 0, 0, 0, 5193, 5197, 5200, 5203, 5206, 5209, 5212, 5215, 5218, + 5221, 5224, 5227, 5230, 5233, 5236, 5239, 5242, 5244, 5246, 5248, 5250, + 5252, 5254, 5256, 5258, 5260, 5262, 5264, 5266, 5268, 5270, 5273, 5276, + 5279, 5282, 5285, 5288, 5291, 5294, 5297, 5300, 5303, 5306, 5309, 5312, + 5318, 5323, 0, 5326, 5328, 5330, 5332, 5334, 5336, 5338, 5340, 5342, + 5344, 5346, 5348, 5350, 5352, 5354, 5356, 5358, 5360, 5362, 5364, 5366, + 5368, 5370, 5372, 5374, 5376, 5378, 5380, 5382, 5384, 5386, 5388, 5390, + 5392, 5394, 5396, 5398, 5400, 5402, 5404, 5406, 5408, 5410, 5412, 5414, + 5416, 5418, 5420, 5422, 5424, 5427, 5430, 5433, 5436, 5439, 5442, 5445, + 5448, 5451, 5454, 5457, 5460, 5463, 5466, 5469, 5472, 5475, 5478, 5481, + 5484, 5487, 5490, 5493, 5496, 5500, 5504, 5508, 5511, 5515, 5518, 5522, + 5524, 5526, 5528, 5530, 5532, 5534, 5536, 5538, 5540, 5542, 5544, 5546, + 5548, 5550, 5552, 5554, 5556, 5558, 5560, 5562, 5564, 5566, 5568, 5570, + 5572, 5574, 5576, 5578, 5580, 5582, 5584, 5586, 5588, 5590, 5592, 5594, + 5596, 5598, 5600, 5602, 5604, 5606, 5608, 5610, 5612, 5614, 5616, 5619, + 5624, 5629, 5634, 5638, 5643, 5647, 5651, 5657, 5662, 5666, 5670, 5674, + 5679, 5684, 5688, 5692, 5695, 5699, 5704, 5709, 5712, 5718, 5725, 5731, + 5735, 5741, 5747, 5752, 5756, 5760, 5764, 5769, 5775, 5780, 5784, 5788, + 5792, 5795, 5798, 5801, 5804, 5808, 5812, 5818, 5822, 5827, 5833, 5837, + 5840, 5843, 5849, 5854, 5860, 5864, 5870, 5873, 5877, 5881, 5885, 5889, + 5893, 5898, 5902, 5905, 5909, 5913, 5917, 5922, 5926, 5930, 5934, 5940, + 5945, 5948, 5954, 5957, 5962, 5967, 5971, 5975, 5979, 5984, 5987, 5991, + 5996, 5999, 6005, 6009, 6012, 6015, 6018, 6021, 6024, 6027, 6030, 6033, + 6036, 6039, 6043, 6047, 6051, 6055, 6059, 6063, 6067, 6071, 6075, 6079, + 6083, 6087, 6091, 6095, 6099, 6103, 6106, 6109, 6113, 6116, 6119, 6122, + 6126, 6130, 6133, 6136, 6139, 6142, 6145, 6150, 6153, 6156, 6159, 6162, + 6165, 6168, 6171, 6174, 6178, 6183, 6186, 6189, 6192, 6195, 6198, 6201, + 6204, 6208, 6212, 6216, 6220, 6223, 6226, 6229, 6232, 6235, 6238, 6241, + 6244, 6247, 6250, 6254, 6258, 6261, 6265, 6269, 6273, 6276, 6280, 6284, + 6289, 6292, 6296, 6300, 6304, 6308, 6314, 6321, 6324, 6327, 6330, 6333, + 6336, 6339, 6342, 6345, 6348, 6351, 6354, 6357, 6360, 6363, 6366, 6369, + 6372, 6375, 6380, 6383, 6386, 6389, 6394, 6398, 6401, 6404, 6407, 6410, + 6413, 6416, 6419, 6422, 6425, 6428, 6432, 6435, 6438, 6442, 6446, 6449, + 6454, 6458, 6461, 6464, 6467, 6470, 6474, 6478, 6481, 6484, 6487, 6490, + 6493, 6496, 6499, 6502, 6505, 6509, 6513, 6517, 6521, 6525, 6529, 6533, + 6537, 6541, 6545, 6549, 6553, 6557, 6561, 6565, 6569, 6573, 6577, 6581, + 6585, 6589, 6593, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6597, 6599, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5221,422 +5133,424 @@ static const unsigned short decomp_index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6653, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 6601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6655, 6657, 6659, 0, 0, 0, 6661, 6663, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6603, 6605, + 6607, 0, 0, 0, 6609, 6611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6665, 6667, 6669, - 6671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6673, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6675, 6677, 6679, 6681, 6683, 6685, - 6687, 6689, 6691, 6693, 6695, 6697, 6699, 6701, 6703, 6705, 6707, 6709, - 6711, 6713, 6715, 6717, 6719, 6721, 6723, 6725, 6727, 6729, 6731, 6733, - 6735, 6737, 6739, 6741, 6743, 6745, 6747, 6749, 6751, 6753, 6755, 6757, - 6759, 6761, 6763, 6765, 6767, 6769, 6771, 6773, 6775, 6777, 6779, 6781, - 6783, 6785, 6787, 6789, 6791, 6793, 6795, 6797, 6799, 6801, 6803, 6805, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6613, 6615, 6617, 6619, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6621, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6623, 6625, 6627, 6629, 6631, 6633, 6635, 6637, 6637, 6639, + 6641, 6643, 6645, 6647, 6649, 6651, 6653, 6655, 6657, 6659, 6661, 6663, + 6665, 6667, 6669, 6671, 6673, 6675, 6677, 6679, 6681, 6683, 6685, 6687, + 6689, 6691, 6693, 6695, 6697, 6699, 6701, 6703, 6705, 6707, 6709, 6711, + 6713, 6715, 6717, 6719, 6721, 6723, 6725, 6727, 6729, 6731, 6733, 6735, + 6737, 6739, 6741, 6743, 6745, 6747, 6749, 6751, 6753, 6755, 6757, 6759, + 6761, 6763, 6765, 6767, 6769, 6771, 6773, 6775, 6777, 6779, 6781, 6783, + 6785, 6787, 6789, 6791, 6793, 6795, 6797, 6799, 6801, 6803, 6661, 6805, 6807, 6809, 6811, 6813, 6815, 6817, 6819, 6821, 6823, 6825, 6827, 6829, 6831, 6833, 6835, 6837, 6839, 6841, 6843, 6845, 6847, 6849, 6851, 6853, 6855, 6857, 6859, 6861, 6863, 6865, 6867, 6869, 6871, 6873, 6875, 6877, 6879, 6881, 6883, 6885, 6887, 6889, 6891, 6893, 6895, 6897, 6899, 6901, 6903, 6905, 6907, 6909, 6911, 6913, 6915, 6917, 6919, 6921, 6923, 6925, - 6927, 6929, 6931, 6933, 6935, 6937, 6939, 6941, 6943, 6945, 6947, 6949, - 6951, 6953, 6955, 6957, 6959, 6961, 6963, 6965, 6967, 6969, 6971, 6973, - 6975, 6977, 6979, 6981, 6983, 6985, 6987, 6989, 6991, 6993, 6995, 6997, - 6999, 7001, 7003, 7005, 7007, 7009, 7011, 7013, 7015, 7017, 7019, 7021, - 7023, 7025, 7027, 7029, 7031, 7033, 7035, 7037, 7039, 7041, 7043, 7045, - 7047, 7049, 7051, 7053, 7055, 7057, 7059, 7061, 7063, 7065, 7067, 7069, - 7071, 7073, 7075, 7077, 7079, 7081, 7083, 7085, 7087, 7089, 7091, 7093, - 7095, 7097, 7099, 7101, 7103, 7105, 7107, 7109, 7111, 7113, 7115, 7117, - 7119, 7121, 7123, 7125, 7127, 7129, 7131, 7133, 7135, 7137, 7139, 7141, - 7143, 7145, 7147, 7149, 7151, 7153, 7155, 7157, 7159, 7161, 7163, 7165, - 7167, 7169, 7171, 7173, 7175, 7177, 7179, 7181, 7183, 7185, 7187, 7189, - 7191, 7193, 7195, 7197, 7199, 7201, 7203, 7205, 7207, 7209, 7211, 7213, - 0, 0, 7215, 0, 7217, 0, 0, 7219, 7221, 7223, 7225, 7227, 7229, 7231, - 7233, 7235, 7237, 0, 7239, 0, 7241, 0, 0, 7243, 7245, 0, 0, 0, 7247, - 7249, 7251, 7253, 7255, 7257, 7259, 7261, 7263, 7265, 7267, 7269, 7271, - 7273, 7275, 7277, 7279, 7281, 7283, 7285, 7287, 7289, 7291, 7293, 7295, - 7297, 7299, 7301, 7303, 7305, 7307, 7309, 7311, 7313, 7315, 7317, 7319, - 7321, 7323, 7325, 7327, 7329, 7331, 7333, 7335, 7337, 7339, 7341, 7343, - 7345, 7347, 7349, 7351, 7353, 7355, 7357, 7359, 7361, 7363, 7365, 7367, - 7369, 7371, 7373, 7375, 7377, 7379, 7381, 0, 0, 7383, 7385, 7387, 7389, - 7391, 7393, 7395, 7397, 7399, 7401, 7403, 7405, 7407, 7409, 7411, 7413, - 7415, 7417, 7419, 7421, 7423, 7425, 7427, 7429, 7431, 7433, 7435, 7437, - 7439, 7441, 7443, 7445, 7447, 7449, 7451, 7453, 7455, 7457, 7459, 7461, - 7463, 7465, 7467, 7469, 7471, 7473, 7475, 7477, 7479, 7481, 7483, 7485, - 7487, 7489, 7491, 7493, 7495, 7497, 7499, 7501, 7503, 7505, 7507, 7509, - 7511, 7513, 7515, 7517, 7519, 7521, 7523, 7525, 7527, 7529, 7531, 7533, - 7535, 7537, 7539, 7541, 7543, 7545, 7547, 7549, 7551, 7553, 7555, 7557, - 7559, 7561, 7563, 7565, 7567, 7569, 7571, 7573, 7575, 7577, 7579, 7581, - 7583, 7585, 7587, 7589, 7591, 7593, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7595, 7598, 7601, 7604, 7608, 7612, 7615, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7618, 7621, 7624, 7627, 7630, 0, 0, 0, 0, 0, 7633, 0, 7636, - 7639, 7641, 7643, 7645, 7647, 7649, 7651, 7653, 7655, 7657, 7659, 7662, - 7665, 7668, 7671, 7674, 7677, 7680, 7683, 7686, 7689, 7692, 7695, 0, - 7698, 7701, 7704, 7707, 7710, 0, 7713, 0, 7716, 7719, 0, 7722, 7725, 0, - 7728, 7731, 7734, 7737, 7740, 7743, 7746, 7749, 7752, 7755, 7758, 7760, - 7762, 7764, 7766, 7768, 7770, 7772, 7774, 7776, 7778, 7780, 7782, 7784, - 7786, 7788, 7790, 7792, 7794, 7796, 7798, 7800, 7802, 7804, 7806, 7808, - 7810, 7812, 7814, 7816, 7818, 7820, 7822, 7824, 7826, 7828, 7830, 7832, - 7834, 7836, 7838, 7840, 7842, 7844, 7846, 7848, 7850, 7852, 7854, 7856, - 7858, 7860, 7862, 7864, 7866, 7868, 7870, 7872, 7874, 7876, 7878, 7880, - 7882, 7884, 7886, 7888, 7890, 7892, 7894, 7896, 7898, 7900, 7902, 7904, - 7906, 7908, 7910, 7912, 7914, 7916, 7918, 7920, 7922, 7924, 7926, 7928, - 7930, 7932, 7934, 7936, 7938, 7940, 7942, 7944, 7946, 7948, 7950, 7952, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 7954, 7956, 7958, 7960, 7962, 7964, 7966, - 7968, 7970, 7972, 7974, 7976, 7978, 7980, 7982, 7984, 7986, 7988, 7990, - 7992, 7994, 7996, 7998, 8000, 8003, 8006, 8009, 8012, 8015, 8018, 8021, - 8024, 8027, 8030, 8033, 8036, 8039, 8042, 8045, 8048, 8051, 8054, 8056, - 8058, 8060, 8062, 8065, 8068, 8071, 8074, 8077, 8080, 8083, 8086, 8089, - 8092, 8095, 8098, 8101, 8104, 8107, 8110, 8113, 8116, 8119, 8122, 8125, - 8128, 8131, 8134, 8137, 8140, 8143, 8146, 8149, 8152, 8155, 8158, 8161, - 8164, 8167, 8170, 8173, 8176, 8179, 8182, 8185, 8188, 8191, 8194, 8197, - 8200, 8203, 8206, 8209, 8212, 8215, 8218, 8221, 8224, 8227, 8230, 8233, - 8236, 8239, 8242, 8245, 8248, 8251, 8254, 8257, 8260, 8263, 8266, 8269, - 8272, 8275, 8278, 8281, 8284, 8287, 8290, 8293, 8296, 8299, 8302, 8305, - 8308, 8311, 8314, 8317, 8320, 8323, 8326, 8329, 8332, 8335, 8338, 8341, - 8344, 8348, 8352, 8356, 8360, 8364, 8368, 8371, 8374, 8377, 8380, 8383, - 8386, 8389, 8392, 8395, 8398, 8401, 8404, 8407, 8410, 8413, 8416, 8419, - 8422, 8425, 8428, 8431, 8434, 8437, 8440, 8443, 8446, 8449, 8452, 8455, - 8458, 8461, 8464, 8467, 8470, 8473, 8476, 8479, 8482, 8485, 8488, 8491, - 8494, 8497, 8500, 8503, 8506, 8509, 8512, 8515, 8518, 8521, 8524, 8527, - 8530, 8533, 8536, 8539, 8542, 8545, 8548, 8551, 8554, 8557, 8560, 8563, - 8566, 8569, 8572, 8575, 8578, 8581, 8584, 8587, 8590, 8593, 8596, 8599, - 8602, 8605, 8608, 8611, 8614, 8617, 8620, 8623, 8626, 8629, 8632, 8635, - 8638, 8641, 8644, 8647, 8650, 8653, 8656, 8659, 8662, 8665, 8668, 8671, - 8674, 8677, 8680, 8683, 8686, 8689, 8692, 8695, 8698, 8701, 8704, 8707, - 8710, 8713, 8716, 8719, 8722, 8725, 8728, 8731, 8734, 8737, 8740, 8743, - 8746, 8749, 8752, 8755, 8758, 8761, 8764, 8767, 8770, 8773, 8776, 8779, - 8782, 8785, 8788, 8791, 8794, 8798, 8802, 8806, 8809, 8812, 8815, 8818, - 8821, 8824, 8827, 8830, 8833, 8836, 8839, 8842, 8845, 8848, 8851, 8854, - 8857, 8860, 8863, 8866, 8869, 8872, 8875, 8878, 8881, 8884, 8887, 8890, - 8893, 8896, 8899, 8902, 8905, 8908, 8911, 8914, 8917, 8920, 8923, 8926, - 8929, 8932, 8935, 8938, 8941, 8944, 8947, 8950, 8953, 8956, 8959, 8962, - 8965, 8968, 8971, 8974, 8977, 8980, 8983, 8986, 8989, 8992, 8995, 8998, - 9001, 9004, 9007, 9010, 9013, 9016, 9019, 9022, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9025, 9029, 9033, 9037, 9041, 9045, 9049, - 9053, 9057, 9061, 9065, 9069, 9073, 9077, 9081, 9085, 9089, 9093, 9097, - 9101, 9105, 9109, 9113, 9117, 9121, 9125, 9129, 9133, 9137, 9141, 9145, - 9149, 9153, 9157, 9161, 9165, 9169, 9173, 9177, 9181, 9185, 9189, 9193, - 9197, 9201, 9205, 9209, 9213, 9217, 9221, 9225, 9229, 9233, 9237, 9241, - 9245, 9249, 9253, 9257, 9261, 9265, 9269, 9273, 9277, 0, 0, 9281, 9285, - 9289, 9293, 9297, 9301, 9305, 9309, 9313, 9317, 9321, 9325, 9329, 9333, - 9337, 9341, 9345, 9349, 9353, 9357, 9361, 9365, 9369, 9373, 9377, 9381, - 9385, 9389, 9393, 9397, 9401, 9405, 9409, 9413, 9417, 9421, 9425, 9429, - 9433, 9437, 9441, 9445, 9449, 9453, 9457, 9461, 9465, 9469, 9473, 9477, - 9481, 9485, 9489, 9493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9497, 9501, 9505, 9510, 9515, 9520, 9525, 9530, 9535, 9540, 9544, 9563, - 9572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9577, - 9579, 9581, 9583, 9585, 9587, 9589, 9591, 9593, 9595, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9597, 9599, 9601, 9603, - 9605, 9607, 9609, 9611, 9613, 9615, 9617, 9619, 9621, 9623, 9625, 9627, - 9629, 9631, 9633, 9635, 9637, 0, 0, 9639, 9641, 9643, 9645, 9647, 9649, - 9651, 9653, 9655, 9657, 9659, 9661, 0, 9663, 9665, 9667, 9669, 9671, - 9673, 9675, 9677, 9679, 9681, 9683, 9685, 9687, 9689, 9691, 9693, 9695, - 9697, 9699, 0, 9701, 9703, 9705, 9707, 0, 0, 0, 0, 9709, 9712, 9715, 0, - 9718, 0, 9721, 9724, 9727, 9730, 9733, 9736, 9739, 9742, 9745, 9748, - 9751, 9753, 9755, 9757, 9759, 9761, 9763, 9765, 9767, 9769, 9771, 9773, - 9775, 9777, 9779, 9781, 9783, 9785, 9787, 9789, 9791, 9793, 9795, 9797, - 9799, 9801, 9803, 9805, 9807, 9809, 9811, 9813, 9815, 9817, 9819, 9821, - 9823, 9825, 9827, 9829, 9831, 9833, 9835, 9837, 9839, 9841, 9843, 9845, - 9847, 9849, 9851, 9853, 9855, 9857, 9859, 9861, 9863, 9865, 9867, 9869, - 9871, 9873, 9875, 9877, 9879, 9881, 9883, 9885, 9887, 9889, 9891, 9893, - 9895, 9897, 9899, 9901, 9903, 9905, 9907, 9909, 9911, 9913, 9915, 9917, - 9919, 9921, 9923, 9925, 9927, 9929, 9931, 9933, 9935, 9937, 9939, 9941, - 9943, 9945, 9947, 9949, 9951, 9953, 9955, 9957, 9959, 9961, 9963, 9965, - 9967, 9969, 9971, 9973, 9975, 9977, 9979, 9981, 9983, 9985, 9988, 9991, - 9994, 9997, 10000, 10003, 10006, 0, 0, 0, 0, 10009, 10011, 10013, 10015, - 10017, 10019, 10021, 10023, 10025, 10027, 10029, 10031, 10033, 10035, - 10037, 10039, 10041, 10043, 10045, 10047, 10049, 10051, 10053, 10055, - 10057, 10059, 10061, 10063, 10065, 10067, 10069, 10071, 10073, 10075, - 10077, 10079, 10081, 10083, 10085, 10087, 10089, 10091, 10093, 10095, - 10097, 10099, 10101, 10103, 10105, 10107, 10109, 10111, 10113, 10115, - 10117, 10119, 10121, 10123, 10125, 10127, 10129, 10131, 10133, 10135, - 10137, 10139, 10141, 10143, 10145, 10147, 10149, 10151, 10153, 10155, - 10157, 10159, 10161, 10163, 10165, 10167, 10169, 10171, 10173, 10175, - 10177, 10179, 10181, 10183, 10185, 10187, 10189, 10191, 10193, 10195, - 10197, 10199, 10201, 10203, 10205, 10207, 10209, 10211, 10213, 10215, - 10217, 10219, 10221, 10223, 10225, 10227, 10229, 10231, 10233, 10235, - 10237, 10239, 10241, 10243, 10245, 10247, 10249, 10251, 10253, 10255, - 10257, 10259, 10261, 10263, 10265, 10267, 10269, 10271, 10273, 10275, - 10277, 10279, 10281, 10283, 10285, 10287, 10289, 10291, 10293, 10295, - 10297, 10299, 10301, 10303, 10305, 10307, 10309, 10311, 10313, 10315, - 10317, 10319, 10321, 10323, 10325, 10327, 10329, 10331, 10333, 10335, - 10337, 10339, 10341, 10343, 10345, 10347, 10349, 10351, 10353, 10355, - 10357, 10359, 10361, 10363, 10365, 10367, 10369, 10371, 10373, 10375, - 10377, 10379, 10381, 10383, 10385, 10387, 0, 0, 0, 10389, 10391, 10393, - 10395, 10397, 10399, 0, 0, 10401, 10403, 10405, 10407, 10409, 10411, 0, - 0, 10413, 10415, 10417, 10419, 10421, 10423, 0, 0, 10425, 10427, 10429, - 0, 0, 0, 10431, 10433, 10435, 10437, 10439, 10441, 10443, 0, 10445, - 10447, 10449, 10451, 10453, 10455, 10457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 10459, 10461, 10463, 10465, 10467, 0, 10469, - 10471, 10473, 10475, 10477, 10479, 10481, 10483, 10485, 10487, 10489, - 10491, 10493, 10495, 10497, 10499, 10501, 10503, 10505, 10507, 10509, - 10511, 10513, 10515, 10517, 10519, 10521, 10523, 10525, 10527, 10529, - 10531, 10533, 10535, 10537, 10539, 10541, 10543, 10545, 10547, 10549, - 10551, 0, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, 10569, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6927, 6929, 6931, 6933, 6935, 6937, 6939, 6841, 6941, 6943, 6945, 6947, + 6949, 6951, 6953, 6955, 6809, 6957, 6959, 6961, 6963, 6965, 6967, 6969, + 6971, 6973, 6975, 6977, 6979, 6981, 6983, 6985, 6987, 6989, 6991, 6993, + 6995, 6661, 6997, 6999, 7001, 7003, 7005, 7007, 7009, 7011, 7013, 7015, + 7017, 7019, 7021, 7023, 7025, 7027, 7029, 7031, 7033, 7035, 7037, 7039, + 7041, 7043, 7045, 7047, 7049, 6813, 7051, 7053, 7055, 7057, 7059, 7061, + 7063, 7065, 7067, 7069, 7071, 7073, 7075, 7077, 7079, 7081, 7083, 7085, + 7087, 7089, 7091, 7093, 7095, 7097, 7099, 7101, 7103, 7105, 7107, 7109, + 7111, 7113, 7115, 7117, 7119, 7121, 7123, 7125, 7127, 7129, 7131, 7133, + 7135, 7137, 7139, 7141, 7143, 7145, 7147, 7149, 0, 0, 7151, 0, 7153, 0, + 0, 7155, 7157, 7159, 7161, 7163, 7165, 7167, 7169, 7171, 7173, 0, 7175, + 0, 7177, 0, 0, 7179, 7181, 0, 0, 0, 7183, 7185, 7187, 7189, 7191, 7193, + 7195, 7197, 7199, 7201, 7203, 7205, 7207, 7209, 7211, 7213, 7215, 7217, + 7219, 7221, 7223, 7225, 7227, 7229, 7231, 7233, 7235, 7237, 7239, 7241, + 7243, 7245, 7247, 7249, 7251, 7253, 7255, 7257, 7259, 7261, 7263, 7265, + 7267, 7269, 7271, 6919, 7273, 7275, 7277, 7279, 7281, 7283, 7283, 7285, + 7287, 7289, 7291, 7293, 7295, 7297, 7299, 7179, 7301, 7303, 7305, 7307, + 7309, 7311, 0, 0, 7313, 7315, 7317, 7319, 7321, 7323, 7325, 7327, 7207, + 7329, 7331, 7333, 7151, 7335, 7337, 7339, 7341, 7343, 7345, 7347, 7349, + 7351, 7353, 7355, 7357, 7225, 7359, 7227, 7361, 7363, 7365, 7367, 7369, + 7153, 6703, 7371, 7373, 7375, 6843, 7017, 7377, 7379, 7241, 7381, 7243, + 7383, 7385, 7387, 7157, 7389, 7391, 7393, 7395, 7397, 7159, 7399, 7401, + 7403, 7405, 7407, 7409, 7271, 7411, 7413, 6919, 7415, 7279, 7417, 7419, + 7421, 7423, 7425, 7289, 7427, 7177, 7429, 7291, 6805, 7431, 7293, 7433, + 7297, 7435, 7437, 7439, 7441, 7443, 7301, 7169, 7445, 7303, 7447, 7305, + 7449, 6637, 7451, 7453, 7455, 7457, 7459, 7461, 7463, 7465, 7467, 7469, + 7471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7473, 7476, 7479, 7482, + 7486, 7490, 7493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7496, 7499, 7502, + 7505, 7508, 0, 0, 0, 0, 0, 7511, 0, 7514, 7517, 7519, 7521, 7523, 7525, + 7527, 7529, 7531, 7533, 7535, 7537, 7540, 7543, 7546, 7549, 7552, 7555, + 7558, 7561, 7564, 7567, 7570, 7573, 0, 7576, 7579, 7582, 7585, 7588, 0, + 7591, 0, 7594, 7597, 0, 7600, 7603, 0, 7606, 7609, 7612, 7615, 7618, + 7621, 7624, 7627, 7630, 7633, 7636, 7638, 7640, 7642, 7644, 7646, 7648, + 7650, 7652, 7654, 7656, 7658, 7660, 7662, 7664, 7666, 7668, 7670, 7672, + 7674, 7676, 7678, 7680, 7682, 7684, 7686, 7688, 7690, 7692, 7694, 7696, + 7698, 7700, 7702, 7704, 7706, 7708, 7710, 7712, 7714, 7716, 7718, 7720, + 7722, 7724, 7726, 7728, 7730, 7732, 7734, 7736, 7738, 7740, 7742, 7744, + 7746, 7748, 7750, 7752, 7754, 7756, 7758, 7760, 7762, 7764, 7766, 7768, + 7770, 7772, 7774, 7776, 7778, 7780, 7782, 7784, 7786, 7788, 7790, 7792, + 7794, 7796, 7798, 7800, 7802, 7804, 7806, 7808, 7810, 7812, 7814, 7816, + 7818, 7820, 7822, 7824, 7826, 7828, 7830, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10571, 0, 10574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10577, 0, 0, + 7832, 7834, 7836, 7838, 7840, 7842, 7844, 7846, 7848, 7850, 7852, 7854, + 7856, 7858, 7860, 7862, 7864, 7866, 7868, 7870, 7872, 7874, 7876, 7878, + 7881, 7884, 7887, 7890, 7893, 7896, 7899, 7902, 7905, 7908, 7911, 7914, + 7917, 7920, 7923, 7926, 7929, 7932, 7934, 7936, 7938, 7940, 7943, 7946, + 7923, 7949, 7952, 7955, 7958, 7961, 7964, 7967, 7970, 7973, 7976, 7979, + 7982, 7985, 7988, 7991, 7994, 7997, 8000, 8003, 8006, 8009, 8012, 8015, + 8018, 8021, 8024, 8027, 8030, 8033, 8036, 8039, 8042, 8045, 8048, 8051, + 8054, 8057, 8060, 8063, 8066, 8069, 8072, 8075, 8078, 8081, 8084, 8087, + 8090, 8093, 8096, 8099, 8102, 8105, 8108, 8111, 8114, 8117, 8120, 8123, + 8126, 8129, 8132, 8135, 8138, 8141, 8144, 8147, 8150, 8153, 8156, 8159, + 8162, 8165, 8168, 8171, 8174, 8177, 8180, 8183, 8186, 8189, 8192, 8195, + 8198, 8201, 8204, 8207, 8210, 8213, 8216, 8219, 8223, 8227, 8231, 8235, + 8239, 8243, 8246, 8249, 8252, 7926, 8255, 8258, 8261, 8264, 8267, 8270, + 8273, 8276, 8279, 8282, 8285, 8288, 8291, 8294, 8297, 8300, 8303, 8306, + 8309, 8312, 8315, 8318, 8321, 8324, 8327, 8330, 8333, 8336, 8339, 8342, + 8345, 8348, 8351, 8354, 8357, 8360, 8363, 8366, 8369, 8372, 8375, 8378, + 8381, 8384, 8387, 8390, 8393, 8396, 8399, 8402, 8405, 8408, 8411, 8414, + 8417, 8420, 8423, 8426, 8429, 8432, 8435, 8438, 8441, 8444, 8447, 8450, + 8453, 8456, 8459, 8462, 8465, 8468, 8471, 8474, 8477, 8480, 8483, 8486, + 8489, 8492, 8495, 8498, 8501, 8504, 8507, 8510, 8513, 8516, 8519, 8522, + 8525, 8528, 8531, 8534, 8537, 8540, 8543, 8546, 8549, 8552, 8555, 8558, + 8561, 8564, 8567, 8570, 8573, 8576, 8579, 8582, 8585, 8588, 8591, 8594, + 8597, 8600, 8603, 8606, 8609, 8612, 8615, 8618, 8621, 8624, 8627, 8630, + 8633, 8636, 8639, 8642, 8645, 8648, 8651, 8654, 8657, 8660, 8663, 8666, + 8670, 8674, 8678, 8681, 8684, 8687, 8690, 8693, 8696, 8699, 8702, 8705, + 8708, 8711, 8714, 8717, 8720, 8723, 8726, 8729, 8732, 8735, 8738, 8741, + 8744, 8747, 8750, 8753, 8756, 8759, 8762, 8765, 8768, 8771, 8774, 8777, + 8780, 8783, 8786, 8789, 8792, 8795, 8798, 8801, 8804, 8807, 8810, 8813, + 8816, 8819, 8822, 8825, 8828, 8831, 8834, 8837, 8840, 8843, 8846, 8849, + 8852, 8855, 8858, 8861, 8864, 8867, 8870, 8873, 8876, 8879, 8882, 8885, + 8888, 8891, 8894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8897, 8901, 8905, 8909, 8913, 8917, 8921, 8925, 8929, 8933, 8937, 8941, + 8945, 8949, 8953, 8957, 8961, 8965, 8969, 8973, 8977, 8981, 8985, 8989, + 8993, 8997, 9001, 9005, 9009, 9013, 9017, 9021, 9025, 9029, 9033, 9037, + 9041, 9045, 9049, 9053, 9057, 9061, 9065, 9069, 9073, 9077, 9081, 9085, + 9089, 9093, 9097, 9101, 9105, 9109, 9113, 9117, 9121, 9125, 9129, 9133, + 9137, 9141, 9145, 9149, 0, 0, 9153, 9157, 9161, 9165, 9169, 9173, 9177, + 9181, 9185, 9189, 9193, 9197, 9201, 9205, 9209, 9213, 9217, 9221, 9225, + 9229, 9233, 9237, 9241, 9245, 9249, 9253, 9257, 9261, 9265, 9269, 9273, + 9277, 9281, 9285, 9289, 9293, 9297, 9301, 9305, 9309, 9313, 9317, 9321, + 9325, 9329, 9333, 9337, 9341, 9345, 9349, 9353, 9357, 9361, 9365, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9369, 9373, 9377, 9382, 9387, + 9392, 9397, 9402, 9407, 9412, 9416, 9435, 9444, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9449, 9451, 9453, 9455, 9457, 9459, + 9461, 9463, 9465, 9467, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9469, 9471, 9473, 9475, 9475, 9477, 9479, 9481, 9483, + 9485, 9487, 9489, 9491, 9493, 9495, 9497, 9499, 9501, 9503, 9505, 9507, + 0, 0, 9509, 9511, 9513, 9513, 9513, 9513, 9515, 9515, 9515, 9517, 9519, + 9521, 0, 9523, 9525, 9527, 9529, 9531, 9533, 9535, 9537, 9539, 9541, + 9543, 9545, 9547, 9549, 9551, 9553, 9555, 9557, 9559, 0, 9561, 9563, + 9565, 9567, 0, 0, 0, 0, 9569, 9572, 9575, 0, 9578, 0, 9581, 9584, 9587, + 9590, 9593, 9596, 9599, 9602, 9605, 9608, 9611, 9613, 9615, 9617, 9619, + 9621, 9623, 9625, 9627, 9629, 9631, 9633, 9635, 9637, 9639, 9641, 9643, + 9645, 9647, 9649, 9651, 9653, 9655, 9657, 9659, 9661, 9663, 9665, 9667, + 9669, 9671, 9673, 9675, 9677, 9679, 9681, 9683, 9685, 9687, 9689, 9691, + 9693, 9695, 9697, 9699, 9701, 9703, 9705, 9707, 9709, 9711, 9713, 9715, + 9717, 9719, 9721, 9723, 9725, 9727, 9729, 9731, 9733, 9735, 9737, 9739, + 9741, 9743, 9745, 9747, 9749, 9751, 9753, 9755, 9757, 9759, 9761, 9763, + 9765, 9767, 9769, 9771, 9773, 9775, 9777, 9779, 9781, 9783, 9785, 9787, + 9789, 9791, 9793, 9795, 9797, 9799, 9801, 9803, 9805, 9807, 9809, 9811, + 9813, 9815, 9817, 9819, 9821, 9823, 9825, 9827, 9829, 9831, 9833, 9835, + 9837, 9839, 9841, 9843, 9845, 9848, 9851, 9854, 9857, 9860, 9863, 9866, + 0, 0, 0, 0, 9869, 9871, 9873, 9875, 9877, 9879, 9881, 9883, 9885, 9887, + 9889, 9891, 9893, 9895, 9897, 9899, 9901, 9903, 9905, 9907, 9909, 9911, + 9913, 9915, 9917, 9919, 9921, 9923, 9925, 9927, 9929, 9931, 9933, 9935, + 9937, 9939, 9941, 9943, 9945, 9947, 9949, 9951, 9953, 9955, 9957, 9959, + 9961, 9963, 9965, 9967, 9969, 9971, 9973, 9975, 9977, 9979, 9981, 9983, + 9985, 9987, 9989, 9991, 9993, 9995, 9997, 9999, 10001, 10003, 10005, + 10007, 10009, 10011, 10013, 10015, 10017, 10019, 10021, 10023, 10025, + 10027, 10029, 10031, 10033, 10035, 10037, 10039, 10041, 10043, 10045, + 10047, 10049, 10051, 10053, 10055, 10057, 10059, 10061, 10063, 10065, + 10067, 10069, 10071, 10073, 10075, 10077, 10079, 10081, 10083, 10085, + 10087, 10089, 10091, 10093, 10095, 10097, 10099, 10101, 10103, 10105, + 10107, 10109, 10111, 10113, 10115, 10117, 10119, 10121, 10123, 10125, + 10127, 10129, 10131, 10133, 10135, 10137, 10139, 10141, 10143, 10145, + 10147, 10149, 10151, 10153, 10155, 10157, 10159, 10161, 10163, 10165, + 10167, 10169, 10171, 10173, 10175, 10177, 10179, 10181, 10183, 10185, + 10187, 10189, 10191, 10193, 10195, 10197, 10199, 10201, 10203, 10205, + 10207, 10209, 10211, 10213, 10215, 10217, 10219, 10221, 10223, 10225, + 10227, 10229, 10231, 10233, 10235, 10237, 10239, 10241, 10243, 10245, + 10247, 0, 0, 0, 10249, 10251, 10253, 10255, 10257, 10259, 0, 0, 10261, + 10263, 10265, 10267, 10269, 10271, 0, 0, 10273, 10275, 10277, 10279, + 10281, 10283, 0, 0, 10285, 10287, 10289, 0, 0, 0, 10291, 10293, 10295, + 10297, 10299, 10301, 10303, 0, 10305, 10307, 10309, 10311, 10313, 10315, + 10317, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10319, + 10321, 10323, 10325, 10327, 0, 10329, 10331, 10333, 10335, 10337, 10339, + 10341, 10343, 10345, 10347, 10349, 10351, 10353, 10355, 10357, 10359, + 10361, 10363, 10365, 10367, 10369, 10371, 10373, 10375, 10377, 10379, + 10381, 10383, 10385, 10387, 10389, 10391, 10393, 10395, 10397, 10399, + 10401, 10403, 10405, 10407, 10409, 10411, 0, 10413, 10415, 10417, 10419, + 10421, 10423, 10425, 10427, 10429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10431, 0, 10434, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10437, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 10580, 10583, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10586, 10589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10592, 10595, 0, - 10598, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 10601, 10604, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10607, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10440, 10443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10610, 10613, 10616, 10619, 10622, - 10625, 10628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10631, 10634, - 10637, 10640, 10643, 10646, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10649, 10651, 10653, 10655, 10657, 10659, 10661, 10663, 10665, 10667, - 10669, 10671, 10673, 10675, 10677, 10679, 10681, 10683, 10685, 10687, - 10689, 10691, 10693, 10695, 10697, 10699, 10701, 10703, 10705, 10707, - 10709, 10711, 10713, 10715, 10717, 10719, 10721, 10723, 10725, 10727, - 10729, 10731, 10733, 10735, 10737, 10739, 10741, 10743, 10745, 10747, - 10749, 10751, 10753, 10755, 10757, 10759, 10761, 10763, 10765, 10767, - 10769, 10771, 10773, 10775, 10777, 10779, 10781, 10783, 10785, 10787, - 10789, 10791, 10793, 10795, 10797, 10799, 10801, 10803, 10805, 10807, - 10809, 10811, 10813, 10815, 10817, 0, 10819, 10821, 10823, 10825, 10827, - 10829, 10831, 10833, 10835, 10837, 10839, 10841, 10843, 10845, 10847, - 10849, 10851, 10853, 10855, 10857, 10859, 10861, 10863, 10865, 10867, - 10869, 10871, 10873, 10875, 10877, 10879, 10881, 10883, 10885, 10887, - 10889, 10891, 10893, 10895, 10897, 10899, 10901, 10903, 10905, 10907, - 10909, 10911, 10913, 10915, 10917, 10919, 10921, 10923, 10925, 10927, - 10929, 10931, 10933, 10935, 10937, 10939, 10941, 10943, 10945, 10947, - 10949, 10951, 10953, 10955, 10957, 10959, 0, 10961, 10963, 0, 0, 10965, - 0, 0, 10967, 10969, 0, 0, 10971, 10973, 10975, 10977, 0, 10979, 10981, - 10983, 10985, 10987, 10989, 10991, 10993, 10995, 10997, 10999, 11001, 0, - 11003, 0, 11005, 11007, 11009, 11011, 11013, 11015, 11017, 0, 11019, - 11021, 11023, 11025, 11027, 11029, 11031, 11033, 11035, 11037, 11039, - 11041, 11043, 11045, 11047, 11049, 11051, 11053, 11055, 11057, 11059, - 11061, 11063, 11065, 11067, 11069, 11071, 11073, 11075, 11077, 11079, - 11081, 11083, 11085, 11087, 11089, 11091, 11093, 11095, 11097, 11099, - 11101, 11103, 11105, 11107, 11109, 11111, 11113, 11115, 11117, 11119, - 11121, 11123, 11125, 11127, 11129, 11131, 11133, 11135, 11137, 11139, - 11141, 11143, 11145, 11147, 0, 11149, 11151, 11153, 11155, 0, 0, 11157, - 11159, 11161, 11163, 11165, 11167, 11169, 11171, 0, 11173, 11175, 11177, - 11179, 11181, 11183, 11185, 0, 11187, 11189, 11191, 11193, 11195, 11197, - 11199, 11201, 11203, 11205, 11207, 11209, 11211, 11213, 11215, 11217, - 11219, 11221, 11223, 11225, 11227, 11229, 11231, 11233, 11235, 11237, - 11239, 11241, 0, 11243, 11245, 11247, 11249, 0, 11251, 11253, 11255, - 11257, 11259, 0, 11261, 0, 0, 0, 11263, 11265, 11267, 11269, 11271, - 11273, 11275, 0, 11277, 11279, 11281, 11283, 11285, 11287, 11289, 11291, - 11293, 11295, 11297, 11299, 11301, 11303, 11305, 11307, 11309, 11311, - 11313, 11315, 11317, 11319, 11321, 11323, 11325, 11327, 11329, 11331, - 11333, 11335, 11337, 11339, 11341, 11343, 11345, 11347, 11349, 11351, - 11353, 11355, 11357, 11359, 11361, 11363, 11365, 11367, 11369, 11371, - 11373, 11375, 11377, 11379, 11381, 11383, 11385, 11387, 11389, 11391, - 11393, 11395, 11397, 11399, 11401, 11403, 11405, 11407, 11409, 11411, - 11413, 11415, 11417, 11419, 11421, 11423, 11425, 11427, 11429, 11431, - 11433, 11435, 11437, 11439, 11441, 11443, 11445, 11447, 11449, 11451, - 11453, 11455, 11457, 11459, 11461, 11463, 11465, 11467, 11469, 11471, - 11473, 11475, 11477, 11479, 11481, 11483, 11485, 11487, 11489, 11491, - 11493, 11495, 11497, 11499, 11501, 11503, 11505, 11507, 11509, 11511, - 11513, 11515, 11517, 11519, 11521, 11523, 11525, 11527, 11529, 11531, - 11533, 11535, 11537, 11539, 11541, 11543, 11545, 11547, 11549, 11551, - 11553, 11555, 11557, 11559, 11561, 11563, 11565, 11567, 11569, 11571, - 11573, 11575, 11577, 11579, 11581, 11583, 11585, 11587, 11589, 11591, - 11593, 11595, 11597, 11599, 11601, 11603, 11605, 11607, 11609, 11611, - 11613, 11615, 11617, 11619, 11621, 11623, 11625, 11627, 11629, 11631, - 11633, 11635, 11637, 11639, 11641, 11643, 11645, 11647, 11649, 11651, - 11653, 11655, 11657, 11659, 11661, 11663, 11665, 11667, 11669, 11671, - 11673, 11675, 11677, 11679, 11681, 11683, 11685, 11687, 11689, 11691, - 11693, 11695, 11697, 11699, 11701, 11703, 11705, 11707, 11709, 11711, - 11713, 11715, 11717, 11719, 11721, 11723, 11725, 11727, 11729, 11731, - 11733, 11735, 11737, 11739, 11741, 11743, 11745, 11747, 11749, 11751, - 11753, 11755, 11757, 11759, 11761, 11763, 11765, 11767, 11769, 11771, - 11773, 11775, 11777, 11779, 11781, 11783, 11785, 11787, 11789, 11791, - 11793, 11795, 11797, 11799, 11801, 11803, 11805, 11807, 11809, 11811, - 11813, 11815, 11817, 11819, 11821, 11823, 11825, 11827, 11829, 11831, - 11833, 11835, 11837, 11839, 11841, 11843, 11845, 11847, 11849, 11851, - 11853, 11855, 11857, 11859, 11861, 11863, 11865, 11867, 11869, 11871, - 11873, 11875, 11877, 11879, 11881, 11883, 11885, 11887, 11889, 11891, - 11893, 11895, 11897, 11899, 11901, 11903, 11905, 11907, 11909, 11911, - 11913, 11915, 11917, 11919, 11921, 11923, 11925, 11927, 11929, 11931, - 11933, 11935, 11937, 11939, 11941, 11943, 11945, 11947, 11949, 11951, - 11953, 11955, 0, 0, 11957, 11959, 11961, 11963, 11965, 11967, 11969, - 11971, 11973, 11975, 11977, 11979, 11981, 11983, 11985, 11987, 11989, - 11991, 11993, 11995, 11997, 11999, 12001, 12003, 12005, 12007, 12009, - 12011, 12013, 12015, 12017, 12019, 12021, 12023, 12025, 12027, 12029, - 12031, 12033, 12035, 12037, 12039, 12041, 12043, 12045, 12047, 12049, - 12051, 12053, 12055, 12057, 12059, 12061, 12063, 12065, 12067, 12069, - 12071, 12073, 12075, 12077, 12079, 12081, 12083, 12085, 12087, 12089, - 12091, 12093, 12095, 12097, 12099, 12101, 12103, 12105, 12107, 12109, - 12111, 12113, 12115, 12117, 12119, 12121, 12123, 12125, 12127, 12129, - 12131, 12133, 12135, 12137, 12139, 12141, 12143, 12145, 12147, 12149, - 12151, 12153, 12155, 12157, 12159, 12161, 12163, 12165, 12167, 12169, - 12171, 12173, 12175, 12177, 12179, 12181, 12183, 12185, 12187, 12189, - 12191, 12193, 12195, 12197, 12199, 12201, 12203, 12205, 12207, 12209, - 12211, 12213, 12215, 12217, 12219, 12221, 12223, 12225, 12227, 12229, - 12231, 12233, 12235, 12237, 12239, 12241, 12243, 12245, 12247, 12249, - 12251, 12253, 12255, 12257, 12259, 12261, 12263, 12265, 12267, 12269, - 12271, 12273, 12275, 12277, 12279, 12281, 12283, 12285, 12287, 12289, - 12291, 12293, 12295, 12297, 12299, 12301, 12303, 12305, 12307, 12309, - 12311, 12313, 12315, 12317, 12319, 12321, 12323, 12325, 12327, 12329, - 12331, 12333, 12335, 12337, 12339, 12341, 12343, 12345, 12347, 12349, - 12351, 12353, 12355, 12357, 12359, 12361, 12363, 12365, 12367, 12369, - 12371, 12373, 12375, 12377, 12379, 12381, 12383, 12385, 12387, 12389, - 12391, 12393, 12395, 12397, 12399, 12401, 12403, 12405, 12407, 12409, - 12411, 12413, 12415, 12417, 12419, 12421, 12423, 12425, 12427, 12429, - 12431, 12433, 12435, 12437, 12439, 12441, 12443, 12445, 12447, 12449, - 12451, 12453, 12455, 12457, 12459, 12461, 12463, 12465, 12467, 12469, - 12471, 12473, 12475, 12477, 12479, 12481, 12483, 12485, 12487, 12489, - 12491, 12493, 12495, 12497, 12499, 12501, 12503, 12505, 12507, 12509, - 12511, 12513, 12515, 12517, 12519, 12521, 12523, 12525, 12527, 12529, - 12531, 12533, 12535, 12537, 12539, 0, 0, 12541, 12543, 12545, 12547, - 12549, 12551, 12553, 12555, 12557, 12559, 12561, 12563, 12565, 12567, - 12569, 12571, 12573, 12575, 12577, 12579, 12581, 12583, 12585, 12587, - 12589, 12591, 12593, 12595, 12597, 12599, 12601, 12603, 12605, 12607, - 12609, 12611, 12613, 12615, 12617, 12619, 12621, 12623, 12625, 12627, - 12629, 12631, 12633, 12635, 12637, 12639, 12641, 12643, 12645, 12647, 0, - 12649, 12651, 12653, 12655, 12657, 12659, 12661, 12663, 12665, 12667, - 12669, 12671, 12673, 12675, 12677, 12679, 12681, 12683, 12685, 12687, - 12689, 12691, 12693, 12695, 12697, 12699, 12701, 0, 12703, 12705, 0, - 12707, 0, 0, 12709, 0, 12711, 12713, 12715, 12717, 12719, 12721, 12723, - 12725, 12727, 12729, 0, 12731, 12733, 12735, 12737, 0, 12739, 0, 12741, - 0, 0, 0, 0, 0, 0, 12743, 0, 0, 0, 0, 12745, 0, 12747, 0, 12749, 0, 12751, - 12753, 12755, 0, 12757, 12759, 0, 12761, 0, 0, 12763, 0, 12765, 0, 12767, - 0, 12769, 0, 12771, 0, 12773, 12775, 0, 12777, 0, 0, 12779, 12781, 12783, - 12785, 0, 12787, 12789, 12791, 12793, 12795, 12797, 12799, 0, 12801, - 12803, 12805, 12807, 0, 12809, 12811, 12813, 12815, 0, 12817, 0, 12819, - 12821, 12823, 12825, 12827, 12829, 12831, 12833, 12835, 12837, 0, 12839, - 12841, 12843, 12845, 12847, 12849, 12851, 12853, 12855, 12857, 12859, - 12861, 12863, 12865, 12867, 12869, 12871, 0, 0, 0, 0, 0, 12873, 12875, - 12877, 0, 12879, 12881, 12883, 12885, 12887, 0, 12889, 12891, 12893, - 12895, 12897, 12899, 12901, 12903, 12905, 12907, 12909, 12911, 12913, - 12915, 12917, 12919, 12921, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12923, 12926, 12929, 12932, 12935, 12938, 12941, 12944, - 12947, 12950, 12953, 0, 0, 0, 0, 0, 12956, 12960, 12964, 12968, 12972, - 12976, 12980, 12984, 12988, 12992, 12996, 13000, 13004, 13008, 13012, - 13016, 13020, 13024, 13028, 13032, 13036, 13040, 13044, 13048, 13052, - 13056, 13060, 13064, 13066, 13068, 13071, 0, 13074, 13076, 13078, 13080, - 13082, 13084, 13086, 13088, 13090, 13092, 13094, 13096, 13098, 13100, - 13102, 13104, 13106, 13108, 13110, 13112, 13114, 13116, 13118, 13120, - 13122, 13124, 13126, 13129, 13132, 13135, 13138, 13142, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13145, 13148, - 13151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13154, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10446, 10449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 13157, 13160, 13163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 13165, 13167, 13169, 13171, 13173, 13175, 13177, 13179, 13181, - 13183, 13185, 13187, 13189, 13191, 13193, 13195, 13197, 13199, 13201, - 13203, 13205, 13207, 13209, 13211, 13213, 13215, 13217, 13219, 13221, - 13223, 13225, 13227, 13229, 13231, 13233, 13235, 13237, 13239, 13241, - 13243, 13245, 13247, 13249, 13251, 0, 0, 0, 0, 13253, 13257, 13261, - 13265, 13269, 13273, 13277, 13281, 13285, 0, 0, 0, 0, 0, 0, 0, 13289, - 13291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10452, 10455, 0, 10458, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10461, 10464, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10467, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13293, 13295, 13297, - 13299, 13301, 13303, 13305, 13307, 13309, 13311, 0, 0, 0, 0, 0, 0, 13313, - 13315, 13317, 13319, 13321, 13323, 13325, 13327, 13329, 13331, 13333, - 13335, 13337, 13339, 13341, 13343, 13345, 13347, 13349, 13351, 13353, - 13355, 13357, 13359, 13361, 13363, 13365, 13367, 13369, 13371, 13373, - 13375, 13377, 13379, 13381, 13383, 13385, 13387, 13389, 13391, 13393, - 13395, 13397, 13399, 13401, 13403, 13405, 13407, 13409, 13411, 13413, - 13415, 13417, 13419, 13421, 13423, 13425, 13427, 13429, 13431, 13433, - 13435, 13437, 13439, 13441, 13443, 13445, 13447, 13449, 13451, 13453, - 13455, 13457, 13459, 13461, 13463, 13465, 13467, 13469, 13471, 13473, - 13475, 13477, 13479, 13481, 13483, 13485, 13487, 13489, 13491, 13493, - 13495, 13497, 13499, 13501, 13503, 13505, 13507, 13509, 13511, 13513, - 13515, 13517, 13519, 13521, 13523, 13525, 13527, 13529, 13531, 13533, - 13535, 13537, 13539, 13541, 13543, 13545, 13547, 13549, 13551, 13553, - 13555, 13557, 13559, 13561, 13563, 13565, 13567, 13569, 13571, 13573, - 13575, 13577, 13579, 13581, 13583, 13585, 13587, 13589, 13591, 13593, - 13595, 13597, 13599, 13601, 13603, 13605, 13607, 13609, 13611, 13613, - 13615, 13617, 13619, 13621, 13623, 13625, 13627, 13629, 13631, 13633, - 13635, 13637, 13639, 13641, 13643, 13645, 13647, 13649, 13651, 13653, - 13655, 13657, 13659, 13661, 13663, 13665, 13667, 13669, 13671, 13673, - 13675, 13677, 13679, 13681, 13683, 13685, 13687, 13689, 13691, 13693, - 13695, 13697, 13699, 13701, 13703, 13705, 13707, 13709, 13711, 13713, - 13715, 13717, 13719, 13721, 13723, 13725, 13727, 13729, 13731, 13733, - 13735, 13737, 13739, 13741, 13743, 13745, 13747, 13749, 13751, 13753, - 13755, 13757, 13759, 13761, 13763, 13765, 13767, 13769, 13771, 13773, - 13775, 13777, 13779, 13781, 13783, 13785, 13787, 13789, 13791, 13793, - 13795, 13797, 13799, 13801, 13803, 13805, 13807, 13809, 13811, 13813, - 13815, 13817, 13819, 13821, 13823, 13825, 13827, 13829, 13831, 13833, - 13835, 13837, 13839, 13841, 13843, 13845, 13847, 13849, 13851, 13853, - 13855, 13857, 13859, 13861, 13863, 13865, 13867, 13869, 13871, 13873, - 13875, 13877, 13879, 13881, 13883, 13885, 13887, 13889, 13891, 13893, - 13895, 13897, 13899, 13901, 13903, 13905, 13907, 13909, 13911, 13913, - 13915, 13917, 13919, 13921, 13923, 13925, 13927, 13929, 13931, 13933, - 13935, 13937, 13939, 13941, 13943, 13945, 13947, 13949, 13951, 13953, - 13955, 13957, 13959, 13961, 13963, 13965, 13967, 13969, 13971, 13973, - 13975, 13977, 13979, 13981, 13983, 13985, 13987, 13989, 13991, 13993, - 13995, 13997, 13999, 14001, 14003, 14005, 14007, 14009, 14011, 14013, - 14015, 14017, 14019, 14021, 14023, 14025, 14027, 14029, 14031, 14033, - 14035, 14037, 14039, 14041, 14043, 14045, 14047, 14049, 14051, 14053, - 14055, 14057, 14059, 14061, 14063, 14065, 14067, 14069, 14071, 14073, - 14075, 14077, 14079, 14081, 14083, 14085, 14087, 14089, 14091, 14093, - 14095, 14097, 14099, 14101, 14103, 14105, 14107, 14109, 14111, 14113, - 14115, 14117, 14119, 14121, 14123, 14125, 14127, 14129, 14131, 14133, - 14135, 14137, 14139, 14141, 14143, 14145, 14147, 14149, 14151, 14153, - 14155, 14157, 14159, 14161, 14163, 14165, 14167, 14169, 14171, 14173, - 14175, 14177, 14179, 14181, 14183, 14185, 14187, 14189, 14191, 14193, - 14195, 14197, 14199, 14201, 14203, 14205, 14207, 14209, 14211, 14213, - 14215, 14217, 14219, 14221, 14223, 14225, 14227, 14229, 14231, 14233, - 14235, 14237, 14239, 14241, 14243, 14245, 14247, 14249, 14251, 14253, - 14255, 14257, 14259, 14261, 14263, 14265, 14267, 14269, 14271, 14273, - 14275, 14277, 14279, 14281, 14283, 14285, 14287, 14289, 14291, 14293, - 14295, 14297, 14299, 14301, 14303, 14305, 14307, 14309, 14311, 14313, - 14315, 14317, 14319, 14321, 14323, 14325, 14327, 14329, 14331, 14333, - 14335, 14337, 14339, 14341, 14343, 14345, 14347, 14349, 14351, 14353, - 14355, 14357, 14359, 14361, 14363, 14365, 14367, 14369, 14371, 14373, - 14375, 14377, 14379, 14381, 14383, 14385, 14387, 14389, 14391, 14393, - 14395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10470, 10473, + 10476, 10479, 10482, 10485, 10488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, + 0, 10491, 10494, 10497, 10500, 10503, 10506, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 10509, 3253, 3192, 3289, 3257, 3259, 10511, 3212, 3218, + 10513, 10515, 3220, 3261, 3224, 10517, 3229, 3231, 3233, 10519, 10521, + 10523, 10525, 10527, 10529, 10531, 3245, 10533, 10535, 10537, 3291, 3255, + 10539, 3210, 3214, 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, + 10549, 10551, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, + 10509, 3253, 3192, 3289, 3257, 3259, 10511, 3212, 3218, 10513, 10515, + 3220, 3261, 3224, 10517, 3229, 3231, 3233, 10519, 10521, 10523, 10525, + 10527, 10529, 10531, 3245, 10533, 10535, 10537, 3291, 3255, 10539, 3210, + 0, 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, 10549, 10551, + 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, 10509, 3253, + 3192, 3289, 3257, 3259, 10511, 3212, 3218, 10513, 10515, 3220, 3261, + 3224, 10517, 3229, 3231, 3233, 10519, 10521, 10523, 10525, 10527, 10529, + 10531, 3245, 10533, 10535, 10537, 3291, 3255, 10539, 3210, 3214, 3273, + 3293, 10541, 3222, 10543, 10545, 3263, 10547, 10549, 10551, 10553, 10555, + 10557, 10559, 10561, 10563, 10565, 10567, 10509, 0, 3192, 3289, 0, 0, + 10511, 0, 0, 10513, 10515, 0, 0, 3224, 10517, 3229, 3231, 0, 10519, + 10521, 10523, 10525, 10527, 10529, 10531, 3245, 10533, 10535, 10537, + 3291, 0, 10539, 0, 3214, 3273, 3293, 10541, 3222, 10543, 10545, 0, 10547, + 10549, 10551, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, + 10509, 3253, 3192, 3289, 3257, 3259, 10511, 3212, 3218, 10513, 10515, + 3220, 3261, 3224, 10517, 3229, 3231, 3233, 10519, 10521, 10523, 10525, + 10527, 10529, 10531, 3245, 10533, 10535, 10537, 3291, 3255, 10539, 3210, + 3214, 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, 10549, 10551, + 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, 10509, 3253, 0, + 3289, 3257, 3259, 10511, 0, 0, 10513, 10515, 3220, 3261, 3224, 10517, + 3229, 3231, 0, 10519, 10521, 10523, 10525, 10527, 10529, 10531, 0, 10533, + 10535, 10537, 3291, 3255, 10539, 3210, 3214, 3273, 3293, 10541, 3222, + 10543, 10545, 3263, 10547, 10549, 10551, 10553, 10555, 10557, 10559, + 10561, 10563, 10565, 10567, 10509, 3253, 0, 3289, 3257, 3259, 10511, 0, + 3218, 10513, 10515, 3220, 3261, 0, 10517, 0, 0, 0, 10519, 10521, 10523, + 10525, 10527, 10529, 10531, 0, 10533, 10535, 10537, 3291, 3255, 10539, + 3210, 3214, 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, 10549, + 10551, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, 10509, + 3253, 3192, 3289, 3257, 3259, 10511, 3212, 3218, 10513, 10515, 3220, + 3261, 3224, 10517, 3229, 3231, 3233, 10519, 10521, 10523, 10525, 10527, + 10529, 10531, 3245, 10533, 10535, 10537, 3291, 3255, 10539, 3210, 3214, + 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, 10549, 10551, 10553, + 10555, 10557, 10559, 10561, 10563, 10565, 10567, 10509, 3253, 3192, 3289, + 3257, 3259, 10511, 3212, 3218, 10513, 10515, 3220, 3261, 3224, 10517, + 3229, 3231, 3233, 10519, 10521, 10523, 10525, 10527, 10529, 10531, 3245, + 10533, 10535, 10537, 3291, 3255, 10539, 3210, 3214, 3273, 3293, 10541, + 3222, 10543, 10545, 3263, 10547, 10549, 10551, 10553, 10555, 10557, + 10559, 10561, 10563, 10565, 10567, 10509, 3253, 3192, 3289, 3257, 3259, + 10511, 3212, 3218, 10513, 10515, 3220, 3261, 3224, 10517, 3229, 3231, + 3233, 10519, 10521, 10523, 10525, 10527, 10529, 10531, 3245, 10533, + 10535, 10537, 3291, 3255, 10539, 3210, 3214, 3273, 3293, 10541, 3222, + 10543, 10545, 3263, 10547, 10549, 10551, 10553, 10555, 10557, 10559, + 10561, 10563, 10565, 10567, 10509, 3253, 3192, 3289, 3257, 3259, 10511, + 3212, 3218, 10513, 10515, 3220, 3261, 3224, 10517, 3229, 3231, 3233, + 10519, 10521, 10523, 10525, 10527, 10529, 10531, 3245, 10533, 10535, + 10537, 3291, 3255, 10539, 3210, 3214, 3273, 3293, 10541, 3222, 10543, + 10545, 3263, 10547, 10549, 10551, 10553, 10555, 10557, 10559, 10561, + 10563, 10565, 10567, 10509, 3253, 3192, 3289, 3257, 3259, 10511, 3212, + 3218, 10513, 10515, 3220, 3261, 3224, 10517, 3229, 3231, 3233, 10519, + 10521, 10523, 10525, 10527, 10529, 10531, 3245, 10533, 10535, 10537, + 3291, 3255, 10539, 3210, 3214, 3273, 3293, 10541, 3222, 10543, 10545, + 3263, 10547, 10549, 10551, 10553, 10555, 10557, 10559, 10561, 10563, + 10565, 10567, 10509, 3253, 3192, 3289, 3257, 3259, 10511, 3212, 3218, + 10513, 10515, 3220, 3261, 3224, 10517, 3229, 3231, 3233, 10519, 10521, + 10523, 10525, 10527, 10529, 10531, 3245, 10533, 10535, 10537, 3291, 3255, + 10539, 3210, 3214, 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, + 10549, 10551, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, + 10569, 10571, 0, 0, 10573, 10575, 3283, 10577, 10579, 10581, 10583, + 10585, 10587, 10589, 10591, 10593, 10595, 10597, 10599, 3285, 10601, + 10603, 10605, 10607, 10609, 10611, 10613, 10615, 10617, 10619, 10621, + 10623, 3281, 10625, 10627, 10629, 10631, 10633, 10635, 10637, 10639, + 10641, 10643, 10645, 10647, 3279, 10649, 10651, 10653, 10655, 10657, + 10659, 10661, 10663, 10665, 10667, 10669, 10671, 10673, 10675, 10677, + 10679, 10573, 10575, 3283, 10577, 10579, 10581, 10583, 10585, 10587, + 10589, 10591, 10593, 10595, 10597, 10599, 3285, 10601, 10603, 10605, + 10607, 10609, 10611, 10613, 10615, 10617, 10619, 10621, 10623, 3281, + 10625, 10627, 10629, 10631, 10633, 10635, 10637, 10639, 10641, 10643, + 10645, 10647, 3279, 10649, 10651, 10653, 10655, 10657, 10659, 10661, + 10663, 10665, 10667, 10669, 10671, 10673, 10675, 10677, 10679, 10573, + 10575, 3283, 10577, 10579, 10581, 10583, 10585, 10587, 10589, 10591, + 10593, 10595, 10597, 10599, 3285, 10601, 10603, 10605, 10607, 10609, + 10611, 10613, 10615, 10617, 10619, 10621, 10623, 3281, 10625, 10627, + 10629, 10631, 10633, 10635, 10637, 10639, 10641, 10643, 10645, 10647, + 3279, 10649, 10651, 10653, 10655, 10657, 10659, 10661, 10663, 10665, + 10667, 10669, 10671, 10673, 10675, 10677, 10679, 10573, 10575, 3283, + 10577, 10579, 10581, 10583, 10585, 10587, 10589, 10591, 10593, 10595, + 10597, 10599, 3285, 10601, 10603, 10605, 10607, 10609, 10611, 10613, + 10615, 10617, 10619, 10621, 10623, 3281, 10625, 10627, 10629, 10631, + 10633, 10635, 10637, 10639, 10641, 10643, 10645, 10647, 3279, 10649, + 10651, 10653, 10655, 10657, 10659, 10661, 10663, 10665, 10667, 10669, + 10671, 10673, 10675, 10677, 10679, 10573, 10575, 3283, 10577, 10579, + 10581, 10583, 10585, 10587, 10589, 10591, 10593, 10595, 10597, 10599, + 3285, 10601, 10603, 10605, 10607, 10609, 10611, 10613, 10615, 10617, + 10619, 10621, 10623, 3281, 10625, 10627, 10629, 10631, 10633, 10635, + 10637, 10639, 10641, 10643, 10645, 10647, 3279, 10649, 10651, 10653, + 10655, 10657, 10659, 10661, 10663, 10665, 10667, 10669, 10671, 10673, + 10675, 10677, 10679, 10681, 10683, 0, 0, 10685, 10687, 10689, 10691, + 10693, 10695, 10697, 10699, 10701, 10703, 10685, 10687, 10689, 10691, + 10693, 10695, 10697, 10699, 10701, 10703, 10685, 10687, 10689, 10691, + 10693, 10695, 10697, 10699, 10701, 10703, 10685, 10687, 10689, 10691, + 10693, 10695, 10697, 10699, 10701, 10703, 10685, 10687, 10689, 10691, + 10693, 10695, 10697, 10699, 10701, 10703, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10705, 10707, 10709, 10711, + 10713, 10715, 10717, 10719, 10721, 10723, 10725, 10727, 10729, 10731, + 10733, 10735, 10737, 10739, 10741, 10743, 10745, 10747, 10749, 10751, + 10753, 10755, 10757, 10759, 10761, 10763, 10765, 10767, 10769, 10771, + 10773, 10775, 10777, 10779, 10781, 10783, 10785, 10787, 10789, 10791, + 10793, 10795, 10797, 10799, 10801, 10803, 10805, 10807, 10809, 10811, + 10813, 10815, 10817, 10819, 10821, 10823, 10825, 10827, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10829, 10831, 10833, 10835, 0, 10837, + 10839, 10841, 10843, 10845, 10847, 10849, 10851, 10853, 10855, 10857, + 10859, 10861, 10863, 10865, 10867, 10869, 10871, 10873, 10875, 10877, + 10879, 10881, 10883, 10885, 10887, 10889, 0, 10831, 10833, 0, 10891, 0, + 0, 10841, 0, 10845, 10847, 10849, 10851, 10853, 10855, 10857, 10859, + 10861, 10863, 0, 10867, 10869, 10871, 10873, 0, 10877, 0, 10881, 0, 0, 0, + 0, 0, 0, 10833, 0, 0, 0, 0, 10841, 0, 10845, 0, 10849, 0, 10853, 10855, + 10857, 0, 10861, 10863, 0, 10867, 0, 0, 10873, 0, 10877, 0, 10881, 0, + 10885, 0, 10889, 0, 10831, 10833, 0, 10891, 0, 0, 10841, 10843, 10845, + 10847, 0, 10851, 10853, 10855, 10857, 10859, 10861, 10863, 0, 10867, + 10869, 10871, 10873, 0, 10877, 10879, 10881, 10883, 0, 10887, 0, 10829, + 10831, 10833, 10835, 10891, 10837, 10839, 10841, 10843, 10845, 0, 10849, + 10851, 10853, 10855, 10857, 10859, 10861, 10863, 10865, 10867, 10869, + 10871, 10873, 10875, 10877, 10879, 10881, 0, 0, 0, 0, 0, 10831, 10833, + 10835, 0, 10837, 10839, 10841, 10843, 10845, 0, 10849, 10851, 10853, + 10855, 10857, 10859, 10861, 10863, 10865, 10867, 10869, 10871, 10873, + 10875, 10877, 10879, 10881, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10893, 10896, 10899, 10902, 10905, 10908, 10911, 10914, + 10917, 10920, 10923, 0, 0, 0, 0, 0, 10926, 10930, 10934, 10938, 10942, + 10946, 10950, 10954, 10958, 10962, 10966, 10970, 10974, 10978, 10982, + 10986, 10990, 10994, 10998, 11002, 11006, 11010, 11014, 11018, 11022, + 11026, 11030, 3926, 3956, 11034, 11037, 0, 11040, 11042, 11044, 11046, + 11048, 11050, 11052, 11054, 11056, 11058, 11060, 11062, 11064, 11066, + 11068, 11070, 11072, 11074, 11076, 11078, 11080, 11082, 11084, 11086, + 11088, 11090, 11092, 6348, 11095, 11098, 11101, 11105, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11108, 11111, + 11114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11117, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 11120, 11123, 11126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 11128, 11130, 11132, 11134, 11136, 11138, 11140, 11142, 11144, + 11146, 11148, 11150, 11152, 11154, 11156, 11158, 11160, 11162, 11164, + 11166, 11168, 11170, 11172, 11174, 11176, 11178, 11180, 11182, 11184, + 11186, 11188, 11190, 11192, 11194, 11196, 11198, 11200, 11202, 11204, + 11206, 11208, 11210, 11212, 11214, 0, 0, 0, 0, 11216, 11220, 11224, + 11228, 11232, 11236, 11240, 11244, 11248, 0, 0, 0, 0, 0, 0, 0, 11252, + 11254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10685, 10687, 10689, + 10691, 10693, 10695, 10697, 10699, 10701, 10703, 0, 0, 0, 0, 0, 0, 11256, + 11258, 11260, 11262, 11264, 7195, 11266, 11268, 11270, 11272, 7197, + 11274, 11276, 11278, 7199, 11280, 11282, 11284, 11286, 11288, 11290, + 11292, 11294, 11296, 11298, 11300, 11302, 7315, 11304, 11306, 11308, + 11310, 11312, 11314, 11316, 11318, 11320, 7325, 7201, 7203, 7327, 11322, + 11324, 6817, 11326, 7205, 11328, 11330, 11332, 11334, 11334, 11334, + 11336, 11338, 11340, 11342, 11344, 11346, 11348, 11350, 11352, 11354, + 11356, 11358, 11360, 11362, 11364, 11366, 11368, 11370, 11370, 7331, + 11372, 11374, 11376, 11378, 7209, 11380, 11382, 11384, 7123, 11386, + 11388, 11390, 11392, 11394, 11396, 11398, 11400, 11402, 11404, 11406, + 11408, 11410, 11412, 11414, 11416, 11418, 11420, 11422, 11424, 11426, + 11428, 11430, 11432, 11434, 11436, 11436, 11438, 11440, 11442, 6809, + 11444, 11446, 11448, 11450, 11452, 11454, 11456, 11458, 7219, 11460, + 11462, 11464, 11466, 11468, 11470, 11472, 11474, 11476, 11478, 11480, + 11482, 11484, 11486, 11488, 11490, 11492, 11494, 11496, 11498, 11500, + 6701, 11502, 11504, 11506, 11506, 11508, 11510, 11510, 11512, 11514, + 11516, 11518, 11520, 11522, 11524, 11526, 11528, 11530, 11532, 11534, + 11536, 7221, 11538, 11540, 11542, 11544, 7355, 11544, 11546, 7225, 11548, + 11550, 11552, 11554, 7227, 6647, 11556, 11558, 11560, 11562, 11564, + 11566, 11568, 11570, 11572, 11574, 11576, 11578, 11580, 11582, 11584, + 11586, 11588, 11590, 11592, 11594, 11596, 11598, 7229, 11600, 11602, + 11604, 11606, 11608, 11610, 7233, 11612, 11614, 11616, 11618, 11620, + 11622, 11624, 11626, 6703, 7371, 11628, 11630, 11632, 11634, 11636, + 11638, 11640, 11642, 7235, 11644, 11646, 11648, 11650, 7457, 11652, + 11654, 11656, 11658, 11660, 11662, 11664, 11666, 11668, 11670, 11672, + 11674, 11676, 6843, 11678, 11680, 11682, 11684, 11686, 11688, 11690, + 11692, 11694, 11696, 11698, 7237, 7017, 11700, 11702, 11704, 11706, + 11708, 11710, 11712, 11714, 7379, 11716, 11718, 11720, 11722, 11724, + 11726, 11728, 11730, 7381, 11732, 11734, 11736, 11738, 11740, 11742, + 11744, 11746, 11748, 11750, 11752, 11754, 7385, 11756, 11758, 11760, + 11762, 11764, 11766, 11768, 11770, 11772, 11774, 11776, 11776, 11778, + 11780, 7389, 11782, 11784, 11786, 11788, 11790, 11792, 11794, 6815, + 11796, 11798, 11800, 11802, 11804, 11806, 11808, 7401, 11810, 11812, + 11814, 11816, 11818, 11820, 11820, 7403, 7461, 11822, 11824, 11826, + 11828, 11830, 6739, 7407, 11832, 11834, 7259, 11836, 11838, 7167, 11840, + 11842, 7267, 11844, 11846, 11848, 11850, 11850, 11852, 11854, 11856, + 11858, 11860, 11862, 11864, 11866, 11868, 11870, 11872, 11874, 11876, + 11878, 11880, 11882, 11884, 11886, 11888, 11890, 11892, 11894, 11896, + 11898, 11900, 11902, 11904, 7279, 11906, 11908, 11910, 11912, 11914, + 11916, 11918, 11920, 11922, 11924, 11926, 11928, 11930, 11932, 11934, + 11936, 11508, 11938, 11940, 11942, 11944, 11946, 11948, 11950, 11952, + 11954, 11956, 11958, 11960, 6851, 11962, 11964, 11966, 11968, 11970, + 11972, 7285, 11974, 11976, 11978, 11980, 11982, 11984, 11986, 11988, + 11990, 11992, 11994, 11996, 11998, 12000, 12002, 12004, 12006, 12008, + 12010, 12012, 6729, 12014, 12016, 12018, 12020, 12022, 12024, 7421, + 12026, 12028, 12030, 12032, 12034, 12036, 12038, 12040, 12042, 12044, + 12046, 12048, 12050, 12052, 12054, 12056, 12058, 12060, 12062, 12064, + 7431, 7433, 12066, 12068, 12070, 12072, 12074, 12076, 12078, 12080, + 12082, 12084, 12086, 12088, 12090, 7435, 12092, 12094, 12096, 12098, + 12100, 12102, 12104, 12106, 12108, 12110, 12112, 12114, 12116, 12118, + 12120, 12122, 12124, 12126, 12128, 12130, 12132, 12134, 12136, 12138, + 12140, 12142, 12144, 12146, 12148, 12150, 7447, 7447, 12152, 12154, + 12156, 12158, 12160, 12162, 12164, 12166, 12168, 12170, 7449, 12172, + 12174, 12176, 12178, 12180, 12182, 12184, 12186, 12188, 12190, 12192, + 12194, 12196, 12198, 12200, 12202, 12204, 12206, 12208, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; /* NFC pairs */ @@ -6107,7 +6021,7 @@ static const change_record change_records_3_2_0[] = { { 19, 30, 255, 255, 255, 0 }, { 255, 8, 255, 255, 255, 0 }, { 255, 27, 255, 255, 255, 0 }, - { 255, 255, 255, 255, 5, 0 }, + { 255, 255, 255, 255, 0, 0 }, { 255, 22, 255, 255, 255, 0 }, { 255, 23, 255, 255, 255, 0 }, { 9, 255, 255, 255, 255, 0 }, @@ -6145,55 +6059,57 @@ static const unsigned char changes_3_2_0_index[] = { 2, 122, 123, 124, 125, 126, 127, 2, 128, 129, 130, 131, 132, 133, 134, 52, 52, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 2, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 2, 159, 160, 2, - 161, 162, 163, 164, 2, 165, 166, 167, 168, 169, 170, 2, 2, 171, 172, 173, - 174, 2, 175, 2, 176, 52, 52, 52, 52, 52, 52, 52, 177, 178, 52, 179, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 180, 52, 52, 52, - 52, 52, 52, 52, 52, 181, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 52, 52, 52, 182, 2, 2, + 161, 162, 163, 164, 2, 165, 166, 167, 168, 169, 170, 171, 2, 172, 173, + 174, 175, 2, 176, 177, 178, 52, 52, 52, 52, 52, 52, 52, 179, 180, 52, + 181, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 182, 52, + 52, 52, 52, 52, 52, 52, 52, 183, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 52, 52, 52, + 184, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 52, 52, 52, 183, - 184, 185, 186, 2, 2, 2, 2, 187, 188, 189, 190, 52, 52, 52, 52, 52, 52, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 52, 52, + 52, 185, 186, 187, 188, 2, 2, 2, 2, 189, 190, 191, 192, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 102, 52, 52, 52, 52, 52, 52, 52, 52, 52, 191, 192, 2, + 52, 52, 52, 52, 52, 52, 52, 102, 52, 52, 52, 52, 52, 52, 52, 52, 52, 183, + 193, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 194, 52, + 52, 195, 52, 52, 196, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 197, 198, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 199, 181, 2, 2, 200, 201, + 202, 203, 204, 2, 2, 205, 2, 2, 2, 206, 207, 208, 52, 52, 52, 52, 52, + 209, 2, 2, 2, 2, 2, 2, 2, 2, 210, 2, 211, 212, 213, 2, 2, 214, 2, 2, 2, + 215, 2, 2, 2, 2, 2, 216, 52, 217, 218, 2, 2, 2, 2, 2, 219, 220, 221, 2, + 222, 223, 2, 2, 224, 225, 52, 226, 227, 2, 52, 52, 52, 52, 52, 52, 52, + 228, 229, 230, 231, 232, 52, 52, 233, 234, 52, 235, 2, 2, 2, 2, 2, 2, 2, + 2, 236, 237, 97, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 86, 238, 2, + 239, 240, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 241, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 242, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 243, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 193, 52, 52, - 194, 52, 52, 195, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 196, 197, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 198, 179, 2, 2, 199, 200, - 201, 202, 203, 2, 2, 204, 2, 2, 2, 205, 206, 207, 52, 52, 52, 52, 52, - 208, 2, 2, 2, 2, 2, 2, 2, 2, 209, 2, 210, 2, 211, 2, 2, 212, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 213, 52, 214, 215, 2, 2, 2, 2, 2, 216, 217, 218, 2, 219, - 220, 2, 2, 221, 222, 52, 223, 224, 2, 52, 52, 52, 52, 52, 52, 52, 225, - 226, 227, 228, 229, 52, 52, 230, 231, 52, 232, 2, 2, 2, 2, 2, 2, 2, 2, - 233, 234, 97, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 86, 235, 2, - 236, 237, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 238, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 239, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 240, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 241, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 244, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 242, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 243, - 52, 244, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 2, 2, 245, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 246, + 52, 247, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 245, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 248, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 246, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 238, 2, 2, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 249, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 241, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 247, 2, 2, 2, 2, 2, 2, 2, 2, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 250, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 251, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -6425,8 +6341,8 @@ static const unsigned char changes_3_2_0_index[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 52, 252, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 248, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -6489,8 +6405,7 @@ static const unsigned char changes_3_2_0_index[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, }; static const unsigned char changes_3_2_0_data[] = { @@ -6621,7 +6536,7 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 20, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, @@ -6636,7 +6551,7 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 9, 0, 0, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7298,7 +7213,7 @@ static const unsigned char changes_3_2_0_data[] = { 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -7333,7 +7248,7 @@ static const unsigned char changes_3_2_0_data[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, @@ -7411,230 +7326,246 @@ static const unsigned char changes_3_2_0_data[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, - 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 0, 0, 0, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 57, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7702,18 +7633,18 @@ static const unsigned char changes_3_2_0_data[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -7730,12 +7661,12 @@ static const unsigned char changes_3_2_0_data[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -7797,7 +7728,7 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -7819,14 +7750,20 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, }; static const change_record* get_change_3_2_0(Py_UCS4 n) diff --git a/Modules/unicodename_db.h b/Modules/unicodename_db.h index 69047048599..f6320c43e53 100644 --- a/Modules/unicodename_db.h +++ b/Modules/unicodename_db.h @@ -12,742 +12,744 @@ static const unsigned char lexicon[] = { 65, 206, 67, 79, 77, 80, 65, 84, 73, 66, 73, 76, 73, 84, 217, 83, 89, 77, 66, 79, 204, 68, 73, 71, 73, 212, 86, 79, 87, 69, 204, 84, 65, 78, 71, 85, 212, 70, 79, 82, 77, 128, 67, 65, 78, 65, 68, 73, 65, 206, 83, 89, - 76, 76, 65, 66, 73, 67, 211, 83, 73, 71, 78, 87, 82, 73, 84, 73, 78, 199, - 65, 78, 196, 84, 73, 77, 69, 211, 66, 65, 77, 85, 205, 83, 67, 82, 73, + 76, 76, 65, 66, 73, 67, 211, 65, 78, 196, 83, 73, 71, 78, 87, 82, 73, 84, + 73, 78, 199, 84, 73, 77, 69, 211, 66, 65, 77, 85, 205, 83, 67, 82, 73, 80, 212, 66, 79, 76, 196, 65, 78, 65, 84, 79, 76, 73, 65, 206, 72, 65, 78, 71, 85, 204, 78, 85, 77, 66, 69, 210, 76, 73, 78, 69, 65, 210, 67, 79, 77, 66, 73, 78, 73, 78, 199, 76, 73, 71, 65, 84, 85, 82, 197, 71, 82, 69, 69, 203, 69, 84, 72, 73, 79, 80, 73, 195, 77, 85, 83, 73, 67, 65, - 204, 70, 79, 210, 75, 72, 73, 84, 65, 206, 193, 67, 89, 82, 73, 76, 76, - 73, 195, 73, 84, 65, 76, 73, 195, 84, 65, 77, 73, 204, 76, 69, 70, 212, + 204, 67, 89, 82, 73, 76, 76, 73, 195, 70, 79, 210, 75, 72, 73, 84, 65, + 206, 193, 73, 84, 65, 76, 73, 195, 84, 65, 77, 73, 204, 76, 69, 70, 212, 78, 85, 83, 72, 213, 67, 73, 82, 67, 76, 69, 196, 82, 65, 68, 73, 67, 65, 204, 83, 65, 78, 83, 45, 83, 69, 82, 73, 198, 82, 73, 71, 72, 212, 83, - 81, 85, 65, 82, 197, 70, 73, 78, 65, 204, 84, 65, 201, 68, 79, 85, 66, - 76, 197, 65, 82, 82, 79, 87, 128, 65, 66, 79, 86, 69, 128, 83, 73, 71, - 78, 128, 86, 65, 201, 77, 79, 68, 73, 70, 73, 69, 210, 66, 69, 76, 79, + 81, 85, 65, 82, 197, 77, 79, 68, 73, 70, 73, 69, 210, 70, 73, 78, 65, + 204, 84, 65, 201, 68, 79, 85, 66, 76, 197, 83, 73, 71, 78, 128, 65, 82, + 82, 79, 87, 128, 65, 66, 79, 86, 69, 128, 86, 65, 201, 66, 69, 76, 79, 87, 128, 72, 69, 78, 84, 65, 73, 71, 65, 78, 193, 66, 76, 65, 67, 203, - 65, 82, 82, 79, 215, 87, 72, 73, 84, 197, 65, 128, 86, 65, 82, 73, 65, - 84, 73, 79, 206, 66, 82, 65, 73, 76, 76, 197, 80, 65, 84, 84, 69, 82, - 206, 85, 128, 73, 128, 75, 65, 84, 65, 75, 65, 78, 193, 66, 89, 90, 65, - 78, 84, 73, 78, 197, 79, 128, 68, 79, 212, 73, 83, 79, 76, 65, 84, 69, - 196, 77, 65, 82, 75, 128, 194, 77, 89, 65, 78, 77, 65, 210, 79, 198, 86, - 69, 82, 84, 73, 67, 65, 204, 77, 73, 68, 68, 76, 197, 75, 65, 78, 71, 88, + 87, 72, 73, 84, 197, 65, 82, 82, 79, 215, 65, 128, 85, 128, 86, 65, 82, + 73, 65, 84, 73, 79, 206, 73, 128, 66, 82, 65, 73, 76, 76, 197, 80, 65, + 84, 84, 69, 82, 206, 75, 65, 84, 65, 75, 65, 78, 193, 66, 89, 90, 65, 78, + 84, 73, 78, 197, 79, 128, 68, 79, 212, 73, 83, 79, 76, 65, 84, 69, 196, + 77, 65, 82, 75, 128, 194, 79, 198, 77, 89, 65, 78, 77, 65, 210, 86, 69, + 82, 84, 73, 67, 65, 204, 77, 73, 68, 68, 76, 197, 75, 65, 78, 71, 88, 201, 75, 73, 75, 65, 75, 85, 201, 77, 69, 78, 68, 197, 84, 73, 66, 69, 84, 65, 206, 77, 65, 82, 203, 72, 69, 65, 86, 217, 73, 78, 73, 84, 73, - 65, 204, 72, 77, 79, 78, 199, 79, 78, 197, 77, 69, 69, 205, 67, 79, 80, - 84, 73, 195, 75, 72, 77, 69, 210, 65, 66, 79, 86, 197, 82, 73, 71, 72, + 65, 204, 72, 77, 79, 78, 199, 79, 78, 197, 77, 69, 69, 205, 65, 66, 79, + 86, 197, 67, 79, 80, 84, 73, 195, 75, 72, 77, 69, 210, 82, 73, 71, 72, 84, 87, 65, 82, 68, 211, 90, 78, 65, 77, 69, 78, 78, 217, 67, 65, 82, 82, - 73, 69, 210, 89, 69, 200, 71, 69, 79, 82, 71, 73, 65, 206, 67, 72, 69, - 82, 79, 75, 69, 197, 77, 79, 78, 71, 79, 76, 73, 65, 206, 84, 87, 207, - 68, 69, 86, 65, 78, 65, 71, 65, 82, 201, 83, 84, 82, 79, 75, 69, 128, 72, - 79, 79, 75, 128, 80, 76, 85, 211, 79, 78, 69, 128, 84, 87, 79, 128, 76, + 73, 69, 210, 89, 69, 200, 68, 69, 86, 65, 78, 65, 71, 65, 82, 201, 71, + 69, 79, 82, 71, 73, 65, 206, 72, 79, 79, 75, 128, 67, 72, 69, 82, 79, 75, + 69, 197, 77, 79, 78, 71, 79, 76, 73, 65, 206, 84, 87, 207, 83, 84, 82, + 79, 75, 69, 128, 79, 78, 69, 128, 80, 76, 85, 211, 84, 87, 79, 128, 76, 79, 87, 69, 210, 66, 79, 216, 83, 81, 85, 65, 82, 69, 196, 83, 89, 77, 66, 79, 76, 128, 80, 72, 65, 83, 69, 45, 197, 84, 72, 82, 69, 197, 85, - 80, 80, 69, 210, 76, 69, 70, 84, 87, 65, 82, 68, 211, 84, 207, 67, 79, - 78, 83, 79, 78, 65, 78, 212, 77, 73, 65, 207, 86, 79, 67, 65, 76, 73, - 195, 68, 82, 65, 87, 73, 78, 71, 211, 84, 73, 76, 197, 68, 85, 80, 76, - 79, 89, 65, 206, 74, 79, 78, 71, 83, 69, 79, 78, 199, 80, 65, 82, 69, 78, - 84, 72, 69, 83, 73, 90, 69, 196, 84, 72, 65, 205, 71, 79, 78, 68, 201, - 65, 76, 69, 198, 76, 79, 215, 85, 208, 71, 76, 65, 71, 79, 76, 73, 84, - 73, 195, 72, 65, 76, 198, 72, 69, 66, 82, 69, 215, 72, 73, 71, 200, 70, - 79, 85, 82, 128, 79, 86, 69, 210, 84, 72, 82, 69, 69, 128, 73, 78, 68, + 80, 80, 69, 210, 86, 79, 67, 65, 76, 73, 195, 76, 69, 70, 84, 87, 65, 82, + 68, 211, 84, 207, 67, 79, 78, 83, 79, 78, 65, 78, 212, 77, 73, 65, 207, + 68, 82, 65, 87, 73, 78, 71, 211, 84, 73, 76, 197, 68, 85, 80, 76, 79, 89, + 65, 206, 74, 79, 78, 71, 83, 69, 79, 78, 199, 80, 65, 82, 69, 78, 84, 72, + 69, 83, 73, 90, 69, 196, 84, 72, 65, 205, 71, 79, 78, 68, 201, 76, 79, + 215, 65, 76, 69, 198, 72, 65, 76, 198, 85, 208, 70, 79, 85, 82, 128, 71, + 76, 65, 71, 79, 76, 73, 84, 73, 195, 72, 69, 66, 82, 69, 215, 72, 73, 71, + 200, 84, 72, 82, 69, 69, 128, 79, 86, 69, 210, 72, 65, 128, 73, 78, 68, 69, 216, 77, 65, 76, 65, 89, 65, 76, 65, 205, 83, 73, 89, 65, 209, 68, - 79, 87, 206, 72, 65, 128, 80, 65, 72, 65, 87, 200, 67, 72, 79, 83, 69, - 79, 78, 199, 66, 65, 76, 73, 78, 69, 83, 197, 72, 65, 76, 70, 87, 73, 68, - 84, 200, 72, 65, 78, 68, 45, 70, 73, 83, 212, 77, 69, 82, 79, 73, 84, 73, - 195, 84, 85, 82, 78, 69, 196, 70, 73, 86, 69, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 73, 195, 76, 73, 71, 72, 212, 73, 68, 69, 79, 71, 82, 65, - 205, 75, 65, 128, 80, 72, 65, 83, 69, 45, 196, 84, 79, 128, 65, 76, 67, - 72, 69, 77, 73, 67, 65, 204, 78, 69, 85, 77, 197, 66, 82, 65, 72, 77, - 201, 84, 79, 78, 197, 66, 65, 82, 128, 83, 73, 78, 72, 65, 76, 193, 82, - 65, 128, 78, 85, 77, 69, 82, 73, 195, 80, 65, 128, 89, 65, 128, 76, 65, - 128, 77, 65, 128, 83, 73, 88, 128, 84, 72, 85, 77, 194, 72, 85, 78, 71, - 65, 82, 73, 65, 206, 69, 73, 71, 72, 84, 128, 76, 79, 78, 199, 66, 65, - 82, 194, 72, 65, 200, 78, 65, 128, 83, 69, 86, 69, 78, 128, 66, 76, 79, - 67, 203, 68, 79, 84, 211, 78, 73, 78, 69, 128, 78, 79, 82, 84, 200, 82, - 73, 71, 72, 84, 128, 84, 72, 79, 85, 83, 65, 78, 68, 128, 83, 65, 128, - 70, 85, 76, 76, 87, 73, 68, 84, 200, 90, 90, 89, 88, 128, 90, 90, 89, 84, - 128, 90, 90, 89, 82, 88, 128, 90, 90, 89, 82, 128, 90, 90, 89, 80, 128, - 90, 90, 89, 65, 128, 90, 90, 89, 128, 90, 90, 85, 88, 128, 90, 90, 85, - 82, 88, 128, 90, 90, 85, 82, 128, 90, 90, 85, 80, 128, 90, 90, 85, 128, - 90, 90, 83, 89, 65, 128, 90, 90, 83, 65, 128, 90, 90, 79, 88, 128, 90, - 90, 79, 80, 128, 90, 90, 79, 128, 90, 90, 73, 88, 128, 90, 90, 73, 84, - 128, 90, 90, 73, 80, 128, 90, 90, 73, 69, 88, 128, 90, 90, 73, 69, 84, - 128, 90, 90, 73, 69, 80, 128, 90, 90, 73, 69, 128, 90, 90, 73, 128, 90, - 90, 69, 88, 128, 90, 90, 69, 80, 128, 90, 90, 69, 69, 128, 90, 90, 69, - 128, 90, 90, 65, 88, 128, 90, 90, 65, 84, 128, 90, 90, 65, 80, 128, 90, - 90, 65, 65, 128, 90, 90, 65, 128, 90, 89, 71, 79, 83, 128, 90, 87, 83, - 80, 128, 90, 87, 78, 74, 128, 90, 87, 78, 66, 83, 80, 128, 90, 87, 74, - 128, 90, 87, 202, 90, 87, 65, 82, 65, 75, 65, 89, 128, 90, 87, 65, 128, - 90, 85, 84, 128, 90, 85, 79, 88, 128, 90, 85, 79, 80, 128, 90, 85, 79, - 128, 90, 85, 77, 128, 90, 85, 66, 85, 82, 128, 90, 85, 53, 128, 90, 85, - 181, 90, 213, 90, 83, 72, 65, 128, 90, 82, 65, 128, 90, 81, 65, 80, 72, - 193, 90, 79, 84, 128, 90, 79, 79, 128, 90, 79, 77, 66, 73, 69, 128, 90, - 79, 65, 128, 90, 77, 69, 89, 84, 83, 65, 128, 90, 76, 65, 77, 193, 90, - 76, 65, 128, 90, 76, 193, 90, 74, 69, 128, 90, 73, 90, 50, 128, 90, 73, - 81, 65, 65, 128, 90, 73, 80, 80, 69, 82, 45, 77, 79, 85, 84, 200, 90, 73, - 78, 79, 82, 128, 90, 73, 76, 68, 69, 128, 90, 73, 71, 90, 65, 199, 90, - 73, 71, 128, 90, 73, 68, 193, 90, 73, 66, 128, 90, 73, 194, 90, 73, 51, - 128, 90, 201, 90, 72, 89, 88, 128, 90, 72, 89, 84, 128, 90, 72, 89, 82, - 88, 128, 90, 72, 89, 82, 128, 90, 72, 89, 80, 128, 90, 72, 89, 128, 90, - 72, 87, 69, 128, 90, 72, 87, 65, 128, 90, 72, 85, 88, 128, 90, 72, 85, - 84, 128, 90, 72, 85, 82, 88, 128, 90, 72, 85, 82, 128, 90, 72, 85, 80, - 128, 90, 72, 85, 79, 88, 128, 90, 72, 85, 79, 80, 128, 90, 72, 85, 79, - 128, 90, 72, 85, 128, 90, 72, 79, 88, 128, 90, 72, 79, 84, 128, 90, 72, - 79, 80, 128, 90, 72, 79, 79, 128, 90, 72, 79, 73, 128, 90, 72, 79, 128, - 90, 72, 73, 86, 69, 84, 69, 128, 90, 72, 73, 76, 128, 90, 72, 73, 128, - 90, 72, 69, 88, 128, 90, 72, 69, 84, 128, 90, 72, 69, 80, 128, 90, 72, - 69, 69, 128, 90, 72, 69, 128, 90, 72, 197, 90, 72, 65, 89, 73, 78, 128, - 90, 72, 65, 88, 128, 90, 72, 65, 84, 128, 90, 72, 65, 82, 128, 90, 72, - 65, 80, 128, 90, 72, 65, 73, 78, 128, 90, 72, 65, 65, 128, 90, 72, 65, - 128, 90, 72, 128, 90, 69, 86, 79, 75, 128, 90, 69, 85, 83, 128, 90, 69, - 84, 65, 128, 90, 69, 82, 79, 128, 90, 69, 82, 207, 90, 69, 78, 128, 90, - 69, 77, 76, 89, 65, 128, 90, 69, 77, 76, 74, 65, 128, 90, 69, 76, 79, - 128, 90, 69, 66, 82, 193, 90, 69, 50, 128, 90, 197, 90, 65, 89, 78, 128, - 90, 65, 89, 73, 78, 45, 89, 79, 68, 72, 128, 90, 65, 89, 73, 78, 128, 90, - 65, 89, 73, 206, 90, 65, 86, 73, 89, 65, 78, 73, 128, 90, 65, 84, 65, - 128, 90, 65, 82, 81, 65, 128, 90, 65, 82, 76, 128, 90, 65, 81, 69, 198, - 90, 65, 80, 89, 65, 84, 89, 77, 73, 128, 90, 65, 80, 89, 65, 84, 79, 89, - 128, 90, 65, 80, 89, 65, 84, 79, 217, 90, 65, 80, 89, 65, 84, 65, 89, 65, - 128, 90, 65, 78, 79, 90, 72, 69, 75, 128, 90, 65, 78, 65, 66, 65, 90, 65, - 210, 90, 65, 77, 88, 128, 90, 65, 76, 128, 90, 65, 204, 90, 65, 75, 82, - 89, 84, 79, 69, 128, 90, 65, 75, 82, 89, 84, 65, 89, 65, 128, 90, 65, 75, - 82, 89, 84, 65, 89, 193, 90, 65, 73, 78, 128, 90, 65, 73, 206, 90, 65, - 73, 128, 90, 65, 72, 128, 90, 65, 200, 90, 65, 71, 128, 90, 65, 69, 70, - 128, 90, 65, 68, 69, 82, 90, 72, 75, 65, 128, 90, 65, 55, 128, 90, 193, - 90, 48, 49, 54, 72, 128, 90, 48, 49, 54, 71, 128, 90, 48, 49, 54, 70, - 128, 90, 48, 49, 54, 69, 128, 90, 48, 49, 54, 68, 128, 90, 48, 49, 54, - 67, 128, 90, 48, 49, 54, 66, 128, 90, 48, 49, 54, 65, 128, 90, 48, 49, - 54, 128, 90, 48, 49, 53, 73, 128, 90, 48, 49, 53, 72, 128, 90, 48, 49, - 53, 71, 128, 90, 48, 49, 53, 70, 128, 90, 48, 49, 53, 69, 128, 90, 48, - 49, 53, 68, 128, 90, 48, 49, 53, 67, 128, 90, 48, 49, 53, 66, 128, 90, - 48, 49, 53, 65, 128, 90, 48, 49, 53, 128, 90, 48, 49, 52, 128, 90, 48, - 49, 51, 128, 90, 48, 49, 50, 128, 90, 48, 49, 49, 128, 90, 48, 49, 48, - 128, 90, 48, 48, 57, 128, 90, 48, 48, 56, 128, 90, 48, 48, 55, 128, 90, - 48, 48, 54, 128, 90, 48, 48, 53, 65, 128, 90, 48, 48, 53, 128, 90, 48, - 48, 52, 65, 128, 90, 48, 48, 52, 128, 90, 48, 48, 51, 66, 128, 90, 48, - 48, 51, 65, 128, 90, 48, 48, 51, 128, 90, 48, 48, 50, 68, 128, 90, 48, - 48, 50, 67, 128, 90, 48, 48, 50, 66, 128, 90, 48, 48, 50, 65, 128, 90, - 48, 48, 50, 128, 90, 48, 48, 49, 128, 90, 128, 218, 89, 89, 88, 128, 89, - 89, 84, 128, 89, 89, 82, 88, 128, 89, 89, 82, 128, 89, 89, 80, 128, 89, - 89, 69, 128, 89, 89, 65, 65, 128, 89, 89, 65, 128, 89, 89, 128, 89, 87, - 79, 79, 128, 89, 87, 79, 128, 89, 87, 73, 73, 128, 89, 87, 73, 128, 89, - 87, 69, 128, 89, 87, 65, 65, 128, 89, 87, 65, 128, 89, 86, 128, 89, 85, - 88, 128, 89, 85, 87, 79, 81, 128, 89, 85, 85, 75, 65, 76, 69, 65, 80, 73, - 78, 84, 85, 128, 89, 85, 85, 128, 89, 85, 84, 128, 89, 85, 83, 128, 89, - 85, 211, 89, 85, 82, 88, 128, 89, 85, 82, 128, 89, 85, 81, 128, 89, 85, - 209, 89, 85, 80, 128, 89, 85, 79, 88, 128, 89, 85, 79, 84, 128, 89, 85, - 79, 80, 128, 89, 85, 79, 77, 128, 89, 85, 79, 128, 89, 85, 78, 128, 89, - 85, 77, 128, 89, 85, 74, 128, 89, 85, 73, 128, 89, 85, 69, 81, 128, 89, - 85, 69, 128, 89, 85, 68, 72, 128, 89, 85, 68, 200, 89, 85, 65, 78, 128, - 89, 85, 65, 69, 78, 128, 89, 85, 45, 89, 69, 79, 128, 89, 85, 45, 89, 69, - 128, 89, 85, 45, 85, 128, 89, 85, 45, 79, 128, 89, 85, 45, 73, 128, 89, - 85, 45, 69, 79, 128, 89, 85, 45, 69, 128, 89, 85, 45, 65, 69, 128, 89, - 85, 45, 65, 128, 89, 85, 45, 52, 128, 89, 85, 45, 51, 128, 89, 85, 45, - 50, 128, 89, 85, 45, 49, 128, 89, 85, 128, 89, 213, 89, 82, 89, 128, 89, - 80, 83, 73, 76, 73, 128, 89, 80, 79, 82, 82, 79, 73, 128, 89, 80, 79, 75, - 82, 73, 83, 73, 83, 128, 89, 80, 79, 75, 82, 73, 83, 73, 211, 89, 80, 79, - 71, 69, 71, 82, 65, 77, 77, 69, 78, 73, 128, 89, 79, 89, 128, 89, 79, 88, - 128, 89, 79, 87, 68, 128, 89, 79, 85, 84, 72, 70, 85, 76, 78, 69, 83, 83, - 128, 89, 79, 85, 84, 72, 70, 85, 204, 89, 79, 213, 89, 79, 84, 128, 89, - 79, 212, 89, 79, 82, 73, 128, 89, 79, 81, 128, 89, 79, 209, 89, 79, 80, - 128, 89, 79, 79, 128, 89, 79, 77, 79, 128, 89, 79, 71, 72, 128, 89, 79, - 68, 128, 89, 79, 196, 89, 79, 65, 128, 89, 79, 45, 89, 79, 128, 89, 79, - 45, 89, 69, 79, 128, 89, 79, 45, 89, 65, 69, 128, 89, 79, 45, 89, 65, - 128, 89, 79, 45, 79, 128, 89, 79, 45, 73, 128, 89, 79, 45, 69, 79, 128, - 89, 79, 45, 65, 69, 128, 89, 79, 45, 65, 128, 89, 79, 45, 54, 128, 89, - 79, 45, 53, 128, 89, 79, 45, 52, 128, 89, 79, 45, 51, 128, 89, 79, 45, - 50, 128, 89, 79, 45, 49, 128, 89, 207, 89, 73, 90, 69, 84, 128, 89, 73, - 88, 128, 89, 73, 87, 78, 128, 89, 73, 84, 128, 89, 73, 80, 128, 89, 73, - 78, 71, 128, 89, 73, 73, 128, 89, 73, 72, 128, 89, 73, 199, 89, 73, 69, - 88, 128, 89, 73, 69, 84, 128, 89, 73, 69, 80, 128, 89, 73, 69, 69, 128, - 89, 73, 69, 128, 89, 73, 68, 68, 73, 83, 200, 89, 73, 45, 85, 128, 89, - 73, 128, 89, 72, 69, 128, 89, 72, 65, 128, 89, 70, 69, 83, 73, 83, 128, - 89, 70, 69, 83, 73, 211, 89, 70, 69, 206, 89, 69, 90, 73, 68, 201, 89, - 69, 89, 128, 89, 69, 87, 128, 89, 69, 85, 88, 128, 89, 69, 85, 82, 65, - 69, 128, 89, 69, 85, 81, 128, 89, 69, 85, 77, 128, 89, 69, 85, 65, 69, - 84, 128, 89, 69, 85, 65, 69, 128, 89, 69, 84, 73, 86, 128, 89, 69, 83, - 84, 85, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 83, 83, 65, 78, 71, 75, - 73, 89, 69, 79, 75, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 83, 73, 79, - 83, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 80, 65, 78, 83, 73, 79, 83, - 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 77, 73, 69, 85, 77, 128, 89, 69, - 83, 73, 69, 85, 78, 71, 45, 75, 73, 89, 69, 79, 75, 128, 89, 69, 83, 73, - 69, 85, 78, 71, 45, 75, 72, 73, 69, 85, 75, 72, 128, 89, 69, 83, 73, 69, - 85, 78, 71, 45, 72, 73, 69, 85, 72, 128, 89, 69, 83, 73, 69, 85, 78, 71, - 128, 89, 69, 82, 85, 128, 89, 69, 82, 213, 89, 69, 82, 73, 128, 89, 69, - 82, 65, 200, 89, 69, 82, 128, 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, - 128, 89, 69, 79, 45, 89, 65, 128, 89, 69, 79, 45, 85, 128, 89, 69, 79, - 45, 79, 128, 89, 69, 78, 73, 83, 69, 201, 89, 69, 78, 65, 80, 128, 89, - 69, 78, 128, 89, 69, 206, 89, 69, 76, 76, 79, 87, 128, 89, 69, 76, 76, - 79, 215, 89, 69, 73, 78, 128, 89, 69, 72, 128, 89, 69, 69, 71, 128, 89, - 69, 69, 128, 89, 69, 65, 210, 89, 69, 65, 128, 89, 65, 90, 90, 128, 89, - 65, 90, 72, 128, 89, 65, 90, 128, 89, 65, 89, 68, 128, 89, 65, 89, 65, - 78, 78, 65, 128, 89, 65, 89, 128, 89, 65, 87, 78, 73, 78, 199, 89, 65, - 87, 78, 128, 89, 65, 87, 128, 89, 65, 86, 128, 89, 65, 85, 128, 89, 65, - 84, 84, 128, 89, 65, 84, 73, 128, 89, 65, 84, 72, 128, 89, 65, 84, 128, - 89, 65, 83, 83, 128, 89, 65, 83, 72, 128, 89, 65, 83, 128, 89, 65, 82, - 82, 128, 89, 65, 82, 78, 128, 89, 65, 82, 128, 89, 65, 210, 89, 65, 81, - 128, 89, 65, 80, 128, 89, 65, 78, 83, 65, 89, 65, 128, 89, 65, 78, 71, - 128, 89, 65, 78, 199, 89, 65, 78, 128, 89, 65, 77, 79, 75, 128, 89, 65, - 77, 65, 75, 75, 65, 78, 128, 89, 65, 77, 128, 89, 65, 76, 128, 89, 65, - 75, 72, 72, 128, 89, 65, 75, 72, 128, 89, 65, 75, 65, 83, 72, 128, 89, - 65, 75, 128, 89, 65, 74, 85, 82, 86, 69, 68, 73, 195, 89, 65, 74, 128, - 89, 65, 73, 128, 89, 65, 72, 72, 128, 89, 65, 72, 128, 89, 65, 71, 78, - 128, 89, 65, 71, 72, 72, 128, 89, 65, 71, 72, 128, 89, 65, 71, 128, 89, - 65, 70, 213, 89, 65, 70, 128, 89, 65, 69, 77, 77, 65, 69, 128, 89, 65, - 68, 72, 128, 89, 65, 68, 68, 72, 128, 89, 65, 68, 68, 128, 89, 65, 68, - 128, 89, 65, 67, 72, 128, 89, 65, 66, 72, 128, 89, 65, 66, 128, 89, 65, - 65, 82, 85, 128, 89, 65, 65, 73, 128, 89, 65, 65, 68, 79, 128, 89, 65, - 45, 89, 79, 128, 89, 65, 45, 85, 128, 89, 65, 45, 79, 128, 89, 65, 45, - 53, 128, 89, 65, 45, 52, 128, 89, 65, 45, 51, 128, 89, 65, 45, 50, 128, - 89, 65, 45, 49, 128, 89, 48, 48, 56, 128, 89, 48, 48, 55, 128, 89, 48, - 48, 54, 128, 89, 48, 48, 53, 128, 89, 48, 48, 52, 128, 89, 48, 48, 51, - 128, 89, 48, 48, 50, 128, 89, 48, 48, 49, 65, 128, 89, 48, 48, 49, 128, - 89, 45, 67, 82, 69, 197, 88, 89, 88, 128, 88, 89, 85, 128, 88, 89, 84, - 128, 88, 89, 82, 88, 128, 88, 89, 82, 128, 88, 89, 80, 128, 88, 89, 79, - 79, 74, 128, 88, 89, 79, 79, 128, 88, 89, 79, 128, 88, 89, 73, 128, 88, - 89, 69, 69, 205, 88, 89, 69, 69, 128, 88, 89, 69, 128, 88, 89, 65, 65, - 128, 88, 89, 65, 128, 88, 89, 128, 88, 87, 73, 128, 88, 87, 69, 69, 128, - 88, 87, 69, 128, 88, 87, 65, 65, 128, 88, 87, 65, 128, 88, 87, 128, 88, - 215, 88, 86, 69, 128, 88, 86, 65, 128, 88, 85, 79, 88, 128, 88, 85, 79, - 128, 88, 85, 128, 88, 83, 72, 65, 65, 89, 65, 84, 72, 73, 89, 65, 128, - 88, 79, 88, 128, 88, 79, 84, 128, 88, 79, 82, 128, 88, 79, 80, 72, 128, - 88, 79, 80, 128, 88, 79, 65, 128, 88, 79, 128, 88, 73, 88, 128, 88, 73, - 84, 128, 88, 73, 82, 79, 206, 88, 73, 80, 128, 88, 73, 69, 88, 128, 88, - 73, 69, 84, 128, 88, 73, 69, 80, 128, 88, 73, 69, 128, 88, 73, 65, 78, - 71, 81, 201, 88, 73, 65, 66, 128, 88, 73, 128, 88, 72, 69, 89, 78, 128, - 88, 71, 128, 88, 69, 89, 78, 128, 88, 69, 83, 84, 69, 211, 88, 69, 72, - 128, 88, 69, 69, 128, 88, 69, 128, 88, 65, 85, 83, 128, 88, 65, 85, 128, - 88, 65, 80, 72, 128, 88, 65, 78, 128, 88, 65, 65, 128, 88, 65, 128, 88, - 48, 48, 56, 65, 128, 88, 48, 48, 56, 128, 88, 48, 48, 55, 128, 88, 48, - 48, 54, 65, 128, 88, 48, 48, 54, 128, 88, 48, 48, 53, 128, 88, 48, 48, - 52, 66, 128, 88, 48, 48, 52, 65, 128, 88, 48, 48, 52, 128, 88, 48, 48, - 51, 128, 88, 48, 48, 50, 128, 88, 48, 48, 49, 128, 88, 45, 216, 88, 45, - 82, 65, 89, 128, 87, 90, 128, 87, 89, 78, 78, 128, 87, 89, 78, 206, 87, - 86, 73, 128, 87, 86, 69, 128, 87, 86, 65, 128, 87, 86, 128, 87, 85, 80, - 128, 87, 85, 79, 88, 128, 87, 85, 79, 80, 128, 87, 85, 79, 128, 87, 85, - 78, 74, 207, 87, 85, 78, 128, 87, 85, 76, 85, 128, 87, 85, 76, 213, 87, - 85, 73, 128, 87, 85, 69, 128, 87, 85, 65, 69, 84, 128, 87, 85, 65, 69, - 78, 128, 87, 85, 128, 87, 82, 217, 87, 82, 79, 78, 71, 128, 87, 82, 73, - 83, 212, 87, 82, 73, 78, 75, 76, 69, 83, 128, 87, 82, 73, 78, 75, 76, 69, - 211, 87, 82, 73, 78, 75, 76, 69, 68, 128, 87, 82, 69, 83, 84, 76, 69, 82, - 83, 128, 87, 82, 69, 78, 67, 72, 128, 87, 82, 69, 65, 84, 200, 87, 82, - 65, 80, 80, 69, 196, 87, 82, 65, 80, 128, 87, 79, 88, 128, 87, 79, 87, - 128, 87, 79, 82, 83, 72, 73, 80, 128, 87, 79, 82, 82, 73, 69, 196, 87, - 79, 82, 77, 128, 87, 79, 82, 76, 196, 87, 79, 82, 75, 69, 82, 128, 87, - 79, 82, 75, 128, 87, 79, 82, 203, 87, 79, 82, 68, 83, 80, 65, 67, 69, - 128, 87, 79, 82, 196, 87, 79, 80, 128, 87, 79, 79, 78, 128, 87, 79, 79, - 76, 128, 87, 79, 79, 68, 83, 45, 67, 82, 69, 197, 87, 79, 79, 68, 128, - 87, 79, 78, 128, 87, 79, 206, 87, 79, 77, 69, 78, 211, 87, 79, 77, 69, - 206, 87, 79, 77, 65, 78, 211, 87, 79, 77, 65, 78, 128, 87, 79, 77, 65, - 206, 87, 79, 76, 79, 83, 79, 128, 87, 79, 76, 198, 87, 79, 69, 128, 87, - 79, 65, 128, 87, 79, 45, 55, 128, 87, 79, 45, 54, 128, 87, 79, 45, 53, - 128, 87, 79, 45, 52, 128, 87, 79, 45, 51, 128, 87, 79, 45, 50, 128, 87, - 79, 45, 49, 128, 87, 73, 84, 72, 79, 85, 212, 87, 73, 84, 72, 73, 78, - 128, 87, 73, 84, 72, 73, 206, 87, 73, 82, 69, 196, 87, 73, 78, 84, 69, - 82, 128, 87, 73, 78, 75, 73, 78, 199, 87, 73, 78, 75, 128, 87, 73, 78, - 74, 65, 128, 87, 73, 78, 71, 83, 128, 87, 73, 78, 69, 128, 87, 73, 78, - 197, 87, 73, 78, 68, 85, 128, 87, 73, 78, 68, 79, 87, 128, 87, 73, 78, - 68, 128, 87, 73, 78, 196, 87, 73, 78, 128, 87, 73, 76, 84, 69, 196, 87, - 73, 71, 78, 89, 65, 78, 128, 87, 73, 71, 71, 76, 217, 87, 73, 71, 71, 76, - 69, 83, 128, 87, 73, 68, 84, 72, 128, 87, 73, 68, 69, 78, 73, 78, 199, - 87, 73, 68, 69, 45, 72, 69, 65, 68, 69, 196, 87, 73, 68, 197, 87, 73, 65, - 78, 71, 87, 65, 65, 75, 128, 87, 73, 65, 78, 71, 128, 87, 73, 45, 53, - 128, 87, 73, 45, 52, 128, 87, 73, 45, 51, 128, 87, 73, 45, 50, 128, 87, - 73, 45, 49, 128, 87, 72, 79, 76, 197, 87, 72, 73, 84, 69, 45, 70, 69, 65, - 84, 72, 69, 82, 69, 196, 87, 72, 73, 84, 69, 128, 87, 72, 69, 69, 76, 69, - 196, 87, 72, 69, 69, 76, 67, 72, 65, 73, 82, 128, 87, 72, 69, 69, 76, 67, - 72, 65, 73, 210, 87, 72, 69, 69, 76, 128, 87, 72, 69, 69, 204, 87, 72, - 69, 65, 84, 128, 87, 72, 65, 76, 69, 128, 87, 72, 128, 87, 71, 128, 87, - 69, 88, 128, 87, 69, 85, 88, 128, 87, 69, 212, 87, 69, 83, 84, 69, 82, - 206, 87, 69, 83, 84, 45, 67, 82, 69, 197, 87, 69, 83, 84, 128, 87, 69, - 83, 212, 87, 69, 80, 128, 87, 69, 79, 128, 87, 69, 78, 128, 87, 69, 76, - 76, 128, 87, 69, 73, 71, 72, 212, 87, 69, 73, 69, 82, 83, 84, 82, 65, 83, - 211, 87, 69, 73, 128, 87, 69, 69, 78, 128, 87, 69, 68, 71, 69, 45, 84, - 65, 73, 76, 69, 196, 87, 69, 68, 71, 69, 128, 87, 69, 68, 68, 73, 78, 71, - 128, 87, 69, 66, 128, 87, 69, 65, 82, 217, 87, 69, 65, 80, 79, 78, 128, - 87, 69, 45, 52, 128, 87, 69, 45, 51, 128, 87, 69, 45, 50, 128, 87, 69, - 45, 49, 128, 87, 67, 128, 87, 66, 128, 87, 65, 89, 128, 87, 65, 217, 87, - 65, 88, 73, 78, 199, 87, 65, 88, 128, 87, 65, 87, 45, 65, 89, 73, 78, 45, - 82, 69, 83, 72, 128, 87, 65, 87, 128, 87, 65, 215, 87, 65, 86, 217, 87, - 65, 86, 73, 78, 199, 87, 65, 86, 69, 83, 128, 87, 65, 86, 69, 128, 87, - 65, 86, 197, 87, 65, 85, 128, 87, 65, 84, 84, 79, 128, 87, 65, 84, 69, - 82, 77, 69, 76, 79, 78, 128, 87, 65, 84, 69, 82, 128, 87, 65, 84, 69, - 210, 87, 65, 84, 67, 72, 128, 87, 65, 84, 128, 87, 65, 83, 84, 73, 78, - 71, 128, 87, 65, 83, 84, 69, 66, 65, 83, 75, 69, 84, 128, 87, 65, 83, 83, - 65, 76, 76, 65, 77, 128, 87, 65, 83, 76, 65, 128, 87, 65, 83, 76, 193, - 87, 65, 83, 65, 76, 76, 65, 77, 128, 87, 65, 83, 65, 76, 76, 65, 205, 87, - 65, 83, 45, 83, 65, 76, 65, 65, 77, 128, 87, 65, 82, 78, 73, 78, 199, 87, - 65, 82, 65, 78, 199, 87, 65, 81, 70, 65, 128, 87, 65, 80, 128, 87, 65, - 78, 73, 78, 199, 87, 65, 78, 71, 75, 85, 79, 81, 128, 87, 65, 78, 68, 69, - 82, 69, 82, 128, 87, 65, 78, 68, 128, 87, 65, 78, 67, 72, 207, 87, 65, - 78, 128, 87, 65, 76, 76, 80, 76, 65, 78, 197, 87, 65, 76, 76, 128, 87, - 65, 76, 204, 87, 65, 76, 75, 128, 87, 65, 76, 203, 87, 65, 73, 84, 73, - 78, 71, 128, 87, 65, 73, 83, 84, 128, 87, 65, 73, 128, 87, 65, 70, 70, - 76, 69, 128, 87, 65, 69, 78, 128, 87, 65, 69, 128, 87, 65, 68, 68, 65, - 128, 87, 65, 65, 86, 85, 128, 87, 65, 65, 74, 73, 66, 128, 87, 65, 65, - 65, 76, 73, 72, 69, 197, 87, 65, 45, 84, 65, 65, 65, 76, 65, 65, 128, 87, - 65, 45, 83, 65, 76, 76, 65, 77, 128, 87, 65, 45, 65, 65, 76, 73, 72, 128, - 87, 65, 45, 53, 128, 87, 65, 45, 52, 128, 87, 65, 45, 51, 128, 87, 65, - 45, 50, 128, 87, 65, 45, 49, 128, 87, 193, 87, 48, 50, 53, 128, 87, 48, - 50, 52, 65, 128, 87, 48, 50, 52, 128, 87, 48, 50, 51, 128, 87, 48, 50, - 50, 128, 87, 48, 50, 49, 128, 87, 48, 50, 48, 128, 87, 48, 49, 57, 128, - 87, 48, 49, 56, 65, 128, 87, 48, 49, 56, 128, 87, 48, 49, 55, 65, 128, - 87, 48, 49, 55, 128, 87, 48, 49, 54, 128, 87, 48, 49, 53, 128, 87, 48, - 49, 52, 65, 128, 87, 48, 49, 52, 128, 87, 48, 49, 51, 128, 87, 48, 49, - 50, 128, 87, 48, 49, 49, 128, 87, 48, 49, 48, 65, 128, 87, 48, 49, 48, - 128, 87, 48, 48, 57, 65, 128, 87, 48, 48, 57, 128, 87, 48, 48, 56, 128, - 87, 48, 48, 55, 128, 87, 48, 48, 54, 128, 87, 48, 48, 53, 128, 87, 48, - 48, 52, 128, 87, 48, 48, 51, 65, 128, 87, 48, 48, 51, 128, 87, 48, 48, - 50, 128, 87, 48, 48, 49, 128, 86, 90, 77, 69, 84, 128, 86, 90, 128, 86, - 89, 88, 128, 86, 89, 84, 128, 86, 89, 83, 79, 75, 79, 128, 86, 89, 83, - 79, 75, 207, 86, 89, 82, 88, 128, 86, 89, 82, 128, 86, 89, 80, 128, 86, - 89, 128, 86, 88, 128, 86, 87, 74, 128, 86, 87, 65, 128, 86, 87, 128, 86, - 85, 88, 128, 86, 85, 85, 128, 86, 85, 84, 128, 86, 85, 82, 88, 128, 86, - 85, 82, 128, 86, 85, 80, 128, 86, 85, 76, 71, 65, 210, 86, 85, 76, 67, - 65, 78, 85, 83, 128, 86, 85, 69, 81, 128, 86, 84, 83, 128, 86, 84, 128, - 86, 83, 57, 57, 128, 86, 83, 57, 56, 128, 86, 83, 57, 55, 128, 86, 83, - 57, 54, 128, 86, 83, 57, 53, 128, 86, 83, 57, 52, 128, 86, 83, 57, 51, - 128, 86, 83, 57, 50, 128, 86, 83, 57, 49, 128, 86, 83, 57, 48, 128, 86, - 83, 57, 128, 86, 83, 56, 57, 128, 86, 83, 56, 56, 128, 86, 83, 56, 55, - 128, 86, 83, 56, 54, 128, 86, 83, 56, 53, 128, 86, 83, 56, 52, 128, 86, - 83, 56, 51, 128, 86, 83, 56, 50, 128, 86, 83, 56, 49, 128, 86, 83, 56, - 48, 128, 86, 83, 56, 128, 86, 83, 55, 57, 128, 86, 83, 55, 56, 128, 86, - 83, 55, 55, 128, 86, 83, 55, 54, 128, 86, 83, 55, 53, 128, 86, 83, 55, - 52, 128, 86, 83, 55, 51, 128, 86, 83, 55, 50, 128, 86, 83, 55, 49, 128, - 86, 83, 55, 48, 128, 86, 83, 55, 128, 86, 83, 54, 57, 128, 86, 83, 54, - 56, 128, 86, 83, 54, 55, 128, 86, 83, 54, 54, 128, 86, 83, 54, 53, 128, - 86, 83, 54, 52, 128, 86, 83, 54, 51, 128, 86, 83, 54, 50, 128, 86, 83, - 54, 49, 128, 86, 83, 54, 48, 128, 86, 83, 54, 128, 86, 83, 53, 57, 128, - 86, 83, 53, 56, 128, 86, 83, 53, 55, 128, 86, 83, 53, 54, 128, 86, 83, - 53, 53, 128, 86, 83, 53, 52, 128, 86, 83, 53, 51, 128, 86, 83, 53, 50, - 128, 86, 83, 53, 49, 128, 86, 83, 53, 48, 128, 86, 83, 53, 128, 86, 83, - 52, 57, 128, 86, 83, 52, 56, 128, 86, 83, 52, 55, 128, 86, 83, 52, 54, - 128, 86, 83, 52, 53, 128, 86, 83, 52, 52, 128, 86, 83, 52, 51, 128, 86, - 83, 52, 50, 128, 86, 83, 52, 49, 128, 86, 83, 52, 48, 128, 86, 83, 52, - 128, 86, 83, 51, 57, 128, 86, 83, 51, 56, 128, 86, 83, 51, 55, 128, 86, - 83, 51, 54, 128, 86, 83, 51, 53, 128, 86, 83, 51, 52, 128, 86, 83, 51, - 51, 128, 86, 83, 51, 50, 128, 86, 83, 51, 49, 128, 86, 83, 51, 48, 128, - 86, 83, 51, 128, 86, 83, 50, 57, 128, 86, 83, 50, 56, 128, 86, 83, 50, - 55, 128, 86, 83, 50, 54, 128, 86, 83, 50, 53, 54, 128, 86, 83, 50, 53, - 53, 128, 86, 83, 50, 53, 52, 128, 86, 83, 50, 53, 51, 128, 86, 83, 50, - 53, 50, 128, 86, 83, 50, 53, 49, 128, 86, 83, 50, 53, 48, 128, 86, 83, - 50, 53, 128, 86, 83, 50, 52, 57, 128, 86, 83, 50, 52, 56, 128, 86, 83, - 50, 52, 55, 128, 86, 83, 50, 52, 54, 128, 86, 83, 50, 52, 53, 128, 86, - 83, 50, 52, 52, 128, 86, 83, 50, 52, 51, 128, 86, 83, 50, 52, 50, 128, - 86, 83, 50, 52, 49, 128, 86, 83, 50, 52, 48, 128, 86, 83, 50, 52, 128, - 86, 83, 50, 51, 57, 128, 86, 83, 50, 51, 56, 128, 86, 83, 50, 51, 55, - 128, 86, 83, 50, 51, 54, 128, 86, 83, 50, 51, 53, 128, 86, 83, 50, 51, - 52, 128, 86, 83, 50, 51, 51, 128, 86, 83, 50, 51, 50, 128, 86, 83, 50, - 51, 49, 128, 86, 83, 50, 51, 48, 128, 86, 83, 50, 51, 128, 86, 83, 50, - 50, 57, 128, 86, 83, 50, 50, 56, 128, 86, 83, 50, 50, 55, 128, 86, 83, - 50, 50, 54, 128, 86, 83, 50, 50, 53, 128, 86, 83, 50, 50, 52, 128, 86, - 83, 50, 50, 51, 128, 86, 83, 50, 50, 50, 128, 86, 83, 50, 50, 49, 128, - 86, 83, 50, 50, 48, 128, 86, 83, 50, 50, 128, 86, 83, 50, 49, 57, 128, - 86, 83, 50, 49, 56, 128, 86, 83, 50, 49, 55, 128, 86, 83, 50, 49, 54, - 128, 86, 83, 50, 49, 53, 128, 86, 83, 50, 49, 52, 128, 86, 83, 50, 49, - 51, 128, 86, 83, 50, 49, 50, 128, 86, 83, 50, 49, 49, 128, 86, 83, 50, - 49, 48, 128, 86, 83, 50, 49, 128, 86, 83, 50, 48, 57, 128, 86, 83, 50, - 48, 56, 128, 86, 83, 50, 48, 55, 128, 86, 83, 50, 48, 54, 128, 86, 83, - 50, 48, 53, 128, 86, 83, 50, 48, 52, 128, 86, 83, 50, 48, 51, 128, 86, - 83, 50, 48, 50, 128, 86, 83, 50, 48, 49, 128, 86, 83, 50, 48, 48, 128, - 86, 83, 50, 48, 128, 86, 83, 50, 128, 86, 83, 49, 57, 57, 128, 86, 83, - 49, 57, 56, 128, 86, 83, 49, 57, 55, 128, 86, 83, 49, 57, 54, 128, 86, - 83, 49, 57, 53, 128, 86, 83, 49, 57, 52, 128, 86, 83, 49, 57, 51, 128, - 86, 83, 49, 57, 50, 128, 86, 83, 49, 57, 49, 128, 86, 83, 49, 57, 48, - 128, 86, 83, 49, 57, 128, 86, 83, 49, 56, 57, 128, 86, 83, 49, 56, 56, - 128, 86, 83, 49, 56, 55, 128, 86, 83, 49, 56, 54, 128, 86, 83, 49, 56, - 53, 128, 86, 83, 49, 56, 52, 128, 86, 83, 49, 56, 51, 128, 86, 83, 49, - 56, 50, 128, 86, 83, 49, 56, 49, 128, 86, 83, 49, 56, 48, 128, 86, 83, - 49, 56, 128, 86, 83, 49, 55, 57, 128, 86, 83, 49, 55, 56, 128, 86, 83, - 49, 55, 55, 128, 86, 83, 49, 55, 54, 128, 86, 83, 49, 55, 53, 128, 86, - 83, 49, 55, 52, 128, 86, 83, 49, 55, 51, 128, 86, 83, 49, 55, 50, 128, - 86, 83, 49, 55, 49, 128, 86, 83, 49, 55, 48, 128, 86, 83, 49, 55, 128, - 86, 83, 49, 54, 57, 128, 86, 83, 49, 54, 56, 128, 86, 83, 49, 54, 55, - 128, 86, 83, 49, 54, 54, 128, 86, 83, 49, 54, 53, 128, 86, 83, 49, 54, - 52, 128, 86, 83, 49, 54, 51, 128, 86, 83, 49, 54, 50, 128, 86, 83, 49, - 54, 49, 128, 86, 83, 49, 54, 48, 128, 86, 83, 49, 54, 128, 86, 83, 49, - 53, 57, 128, 86, 83, 49, 53, 56, 128, 86, 83, 49, 53, 55, 128, 86, 83, - 49, 53, 54, 128, 86, 83, 49, 53, 53, 128, 86, 83, 49, 53, 52, 128, 86, - 83, 49, 53, 51, 128, 86, 83, 49, 53, 50, 128, 86, 83, 49, 53, 49, 128, - 86, 83, 49, 53, 48, 128, 86, 83, 49, 53, 128, 86, 83, 49, 52, 57, 128, - 86, 83, 49, 52, 56, 128, 86, 83, 49, 52, 55, 128, 86, 83, 49, 52, 54, - 128, 86, 83, 49, 52, 53, 128, 86, 83, 49, 52, 52, 128, 86, 83, 49, 52, - 51, 128, 86, 83, 49, 52, 50, 128, 86, 83, 49, 52, 49, 128, 86, 83, 49, - 52, 48, 128, 86, 83, 49, 52, 128, 86, 83, 49, 51, 57, 128, 86, 83, 49, - 51, 56, 128, 86, 83, 49, 51, 55, 128, 86, 83, 49, 51, 54, 128, 86, 83, - 49, 51, 53, 128, 86, 83, 49, 51, 52, 128, 86, 83, 49, 51, 51, 128, 86, - 83, 49, 51, 50, 128, 86, 83, 49, 51, 49, 128, 86, 83, 49, 51, 48, 128, - 86, 83, 49, 51, 128, 86, 83, 49, 50, 57, 128, 86, 83, 49, 50, 56, 128, - 86, 83, 49, 50, 55, 128, 86, 83, 49, 50, 54, 128, 86, 83, 49, 50, 53, - 128, 86, 83, 49, 50, 52, 128, 86, 83, 49, 50, 51, 128, 86, 83, 49, 50, - 50, 128, 86, 83, 49, 50, 49, 128, 86, 83, 49, 50, 48, 128, 86, 83, 49, - 50, 128, 86, 83, 49, 49, 57, 128, 86, 83, 49, 49, 56, 128, 86, 83, 49, - 49, 55, 128, 86, 83, 49, 49, 54, 128, 86, 83, 49, 49, 53, 128, 86, 83, - 49, 49, 52, 128, 86, 83, 49, 49, 51, 128, 86, 83, 49, 49, 50, 128, 86, - 83, 49, 49, 49, 128, 86, 83, 49, 49, 48, 128, 86, 83, 49, 49, 128, 86, - 83, 49, 48, 57, 128, 86, 83, 49, 48, 56, 128, 86, 83, 49, 48, 55, 128, - 86, 83, 49, 48, 54, 128, 86, 83, 49, 48, 53, 128, 86, 83, 49, 48, 52, - 128, 86, 83, 49, 48, 51, 128, 86, 83, 49, 48, 50, 128, 86, 83, 49, 48, - 49, 128, 86, 83, 49, 48, 48, 128, 86, 83, 49, 48, 128, 86, 83, 49, 128, - 86, 83, 128, 86, 82, 65, 75, 72, 73, 89, 193, 86, 82, 65, 67, 72, 89, - 128, 86, 81, 128, 86, 79, 88, 128, 86, 79, 87, 69, 76, 45, 67, 65, 82, - 82, 73, 69, 210, 86, 79, 87, 128, 86, 79, 85, 128, 86, 79, 84, 128, 86, - 79, 211, 86, 79, 80, 128, 86, 79, 79, 73, 128, 86, 79, 79, 128, 86, 79, - 77, 73, 84, 73, 78, 71, 128, 86, 79, 77, 128, 86, 79, 76, 85, 77, 197, - 86, 79, 76, 84, 65, 71, 197, 86, 79, 76, 76, 69, 89, 66, 65, 76, 76, 128, - 86, 79, 76, 67, 65, 78, 79, 128, 86, 79, 76, 65, 80, 85, 203, 86, 79, 73, - 68, 69, 196, 86, 79, 73, 196, 86, 79, 73, 67, 73, 78, 71, 128, 86, 79, - 73, 67, 69, 76, 69, 83, 211, 86, 79, 73, 67, 69, 196, 86, 79, 68, 128, - 86, 79, 67, 65, 76, 73, 90, 65, 84, 73, 79, 206, 86, 79, 67, 65, 204, 86, - 79, 128, 86, 73, 89, 79, 128, 86, 73, 88, 128, 86, 73, 84, 82, 73, 79, - 76, 45, 50, 128, 86, 73, 84, 82, 73, 79, 76, 128, 86, 73, 84, 72, 75, 85, - 81, 201, 86, 73, 84, 65, 69, 45, 50, 128, 86, 73, 84, 65, 69, 128, 86, - 73, 84, 128, 86, 73, 83, 73, 71, 79, 84, 72, 73, 195, 86, 73, 83, 65, 82, - 71, 65, 89, 65, 128, 86, 73, 83, 65, 82, 71, 65, 128, 86, 73, 83, 65, 82, - 71, 193, 86, 73, 82, 73, 65, 77, 128, 86, 73, 82, 71, 79, 128, 86, 73, - 82, 71, 65, 128, 86, 73, 82, 65, 77, 65, 128, 86, 73, 80, 128, 86, 73, - 79, 76, 73, 78, 128, 86, 73, 78, 69, 71, 65, 82, 45, 51, 128, 86, 73, 78, - 69, 71, 65, 82, 45, 50, 128, 86, 73, 78, 69, 71, 65, 82, 128, 86, 73, 78, - 69, 71, 65, 210, 86, 73, 78, 69, 128, 86, 73, 78, 197, 86, 73, 78, 128, - 86, 73, 76, 76, 65, 71, 69, 128, 86, 73, 73, 128, 86, 73, 71, 73, 78, 84, - 73, 76, 69, 128, 86, 73, 69, 88, 128, 86, 73, 69, 87, 73, 78, 199, 86, - 73, 69, 87, 69, 82, 128, 86, 73, 69, 87, 68, 65, 84, 193, 86, 73, 69, 84, - 78, 65, 77, 69, 83, 197, 86, 73, 69, 84, 128, 86, 73, 69, 212, 86, 73, - 69, 80, 128, 86, 73, 69, 128, 86, 73, 68, 74, 45, 50, 128, 86, 73, 68, - 74, 128, 86, 73, 68, 69, 79, 67, 65, 83, 83, 69, 84, 84, 69, 128, 86, 73, - 68, 69, 207, 86, 73, 68, 65, 128, 86, 73, 67, 84, 79, 82, 217, 86, 73, - 66, 82, 65, 84, 73, 79, 206, 86, 72, 65, 128, 86, 70, 65, 128, 86, 69, - 89, 90, 128, 86, 69, 88, 128, 86, 69, 87, 128, 86, 69, 215, 86, 69, 85, - 88, 128, 86, 69, 85, 77, 128, 86, 69, 85, 65, 69, 80, 69, 78, 128, 86, - 69, 85, 65, 69, 128, 86, 69, 83, 84, 65, 128, 86, 69, 83, 84, 128, 86, - 69, 83, 83, 69, 204, 86, 69, 82, 217, 86, 69, 82, 84, 73, 67, 65, 76, 76, - 89, 128, 86, 69, 82, 84, 73, 67, 65, 76, 76, 217, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 54, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 54, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, - 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 51, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 50, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 54, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 53, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, - 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 52, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 51, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 53, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 53, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, - 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 53, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 52, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 52, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 52, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, - 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 54, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 53, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 51, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 51, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, - 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 48, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 54, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 50, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 50, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, - 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 49, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 48, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 49, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 49, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, - 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 50, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 49, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 48, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 48, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, - 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 51, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 50, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 48, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 128, - 86, 69, 82, 83, 73, 67, 76, 69, 128, 86, 69, 82, 83, 197, 86, 69, 82, 71, - 69, 128, 86, 69, 82, 68, 73, 71, 82, 73, 83, 128, 86, 69, 82, 128, 86, - 69, 80, 128, 86, 69, 78, 68, 128, 86, 69, 76, 73, 128, 86, 69, 73, 76, - 128, 86, 69, 72, 73, 67, 76, 69, 128, 86, 69, 72, 128, 86, 69, 200, 86, - 69, 69, 128, 86, 69, 197, 86, 69, 68, 69, 128, 86, 69, 67, 84, 79, 210, - 86, 67, 128, 86, 65, 89, 65, 78, 78, 65, 128, 86, 65, 88, 128, 86, 65, - 86, 128, 86, 65, 214, 86, 65, 85, 128, 86, 65, 84, 72, 89, 128, 86, 65, - 84, 128, 86, 65, 83, 84, 78, 69, 83, 211, 86, 65, 83, 73, 83, 128, 86, - 65, 82, 89, 211, 86, 65, 82, 73, 75, 65, 128, 86, 65, 82, 73, 65, 78, 84, - 128, 86, 65, 82, 73, 65, 78, 212, 86, 65, 82, 73, 65, 128, 86, 65, 82, - 73, 193, 86, 65, 82, 69, 73, 65, 201, 86, 65, 82, 69, 73, 193, 86, 65, - 82, 65, 65, 75, 65, 78, 128, 86, 65, 80, 79, 85, 82, 83, 128, 86, 65, 80, - 128, 86, 65, 78, 69, 128, 86, 65, 77, 80, 73, 82, 69, 128, 86, 65, 77, - 65, 71, 79, 77, 85, 75, 72, 65, 128, 86, 65, 77, 65, 71, 79, 77, 85, 75, - 72, 193, 86, 65, 76, 76, 69, 89, 128, 86, 65, 75, 65, 73, 89, 65, 82, 65, - 65, 128, 86, 65, 74, 128, 86, 65, 73, 128, 86, 65, 72, 128, 86, 65, 200, - 86, 65, 65, 86, 85, 128, 86, 65, 65, 128, 86, 193, 86, 48, 52, 48, 65, - 128, 86, 48, 52, 48, 128, 86, 48, 51, 57, 128, 86, 48, 51, 56, 128, 86, - 48, 51, 55, 65, 128, 86, 48, 51, 55, 128, 86, 48, 51, 54, 128, 86, 48, - 51, 53, 128, 86, 48, 51, 52, 128, 86, 48, 51, 51, 65, 128, 86, 48, 51, - 51, 128, 86, 48, 51, 50, 128, 86, 48, 51, 49, 65, 128, 86, 48, 51, 49, - 128, 86, 48, 51, 48, 65, 128, 86, 48, 51, 48, 128, 86, 48, 50, 57, 65, - 128, 86, 48, 50, 57, 128, 86, 48, 50, 56, 65, 128, 86, 48, 50, 56, 128, - 86, 48, 50, 55, 128, 86, 48, 50, 54, 128, 86, 48, 50, 53, 128, 86, 48, - 50, 52, 128, 86, 48, 50, 51, 65, 128, 86, 48, 50, 51, 128, 86, 48, 50, - 50, 128, 86, 48, 50, 49, 128, 86, 48, 50, 48, 76, 128, 86, 48, 50, 48, - 75, 128, 86, 48, 50, 48, 74, 128, 86, 48, 50, 48, 73, 128, 86, 48, 50, - 48, 72, 128, 86, 48, 50, 48, 71, 128, 86, 48, 50, 48, 70, 128, 86, 48, - 50, 48, 69, 128, 86, 48, 50, 48, 68, 128, 86, 48, 50, 48, 67, 128, 86, - 48, 50, 48, 66, 128, 86, 48, 50, 48, 65, 128, 86, 48, 50, 48, 128, 86, - 48, 49, 57, 128, 86, 48, 49, 56, 128, 86, 48, 49, 55, 128, 86, 48, 49, - 54, 128, 86, 48, 49, 53, 128, 86, 48, 49, 52, 128, 86, 48, 49, 51, 128, - 86, 48, 49, 50, 66, 128, 86, 48, 49, 50, 65, 128, 86, 48, 49, 50, 128, - 86, 48, 49, 49, 67, 128, 86, 48, 49, 49, 66, 128, 86, 48, 49, 49, 65, - 128, 86, 48, 49, 49, 128, 86, 48, 49, 48, 128, 86, 48, 48, 57, 128, 86, - 48, 48, 56, 128, 86, 48, 48, 55, 66, 128, 86, 48, 48, 55, 65, 128, 86, - 48, 48, 55, 128, 86, 48, 48, 54, 128, 86, 48, 48, 53, 128, 86, 48, 48, - 52, 128, 86, 48, 48, 51, 128, 86, 48, 48, 50, 65, 128, 86, 48, 48, 50, - 128, 86, 48, 48, 49, 73, 128, 86, 48, 48, 49, 72, 128, 86, 48, 48, 49, - 71, 128, 86, 48, 48, 49, 70, 128, 86, 48, 48, 49, 69, 128, 86, 48, 48, - 49, 68, 128, 86, 48, 48, 49, 67, 128, 86, 48, 48, 49, 66, 128, 86, 48, - 48, 49, 65, 128, 86, 48, 48, 49, 128, 85, 90, 85, 128, 85, 90, 72, 65, - 75, 75, 85, 128, 85, 90, 51, 128, 85, 90, 179, 85, 90, 128, 85, 89, 71, - 72, 85, 210, 85, 89, 65, 78, 78, 65, 128, 85, 89, 128, 85, 87, 85, 128, - 85, 85, 89, 65, 78, 78, 65, 128, 85, 85, 85, 85, 128, 85, 85, 85, 51, - 128, 85, 85, 85, 50, 128, 85, 85, 69, 128, 85, 84, 85, 75, 73, 128, 85, - 83, 83, 85, 51, 128, 85, 83, 83, 85, 128, 85, 83, 72, 88, 128, 85, 83, - 72, 85, 77, 88, 128, 85, 83, 72, 69, 78, 78, 65, 128, 85, 83, 72, 50, - 128, 85, 83, 72, 128, 85, 83, 200, 85, 83, 69, 196, 85, 83, 69, 45, 50, - 128, 85, 83, 69, 45, 49, 128, 85, 83, 69, 128, 85, 83, 197, 85, 82, 85, - 218, 85, 82, 85, 83, 128, 85, 82, 85, 68, 65, 128, 85, 82, 85, 68, 193, - 85, 82, 85, 128, 85, 82, 213, 85, 82, 78, 128, 85, 82, 73, 78, 69, 128, - 85, 82, 73, 51, 128, 85, 82, 73, 128, 85, 82, 65, 78, 85, 83, 128, 85, - 82, 65, 128, 85, 82, 52, 128, 85, 82, 50, 128, 85, 82, 178, 85, 80, 87, - 65, 82, 68, 83, 128, 85, 80, 87, 65, 82, 68, 211, 85, 80, 87, 65, 82, 68, - 128, 85, 80, 87, 65, 82, 196, 85, 80, 84, 85, 82, 78, 128, 85, 80, 83, - 73, 76, 79, 78, 128, 85, 80, 83, 73, 76, 79, 206, 85, 80, 83, 73, 68, 69, - 45, 68, 79, 87, 206, 85, 80, 82, 73, 71, 72, 212, 85, 80, 80, 69, 82, - 128, 85, 80, 65, 68, 72, 77, 65, 78, 73, 89, 65, 128, 85, 80, 45, 80, 79, - 73, 78, 84, 73, 78, 199, 85, 79, 78, 128, 85, 79, 71, 128, 85, 78, 78, - 128, 85, 78, 77, 65, 82, 82, 73, 69, 196, 85, 78, 75, 78, 79, 87, 78, - 128, 85, 78, 75, 128, 85, 78, 73, 86, 69, 82, 83, 65, 204, 85, 78, 73, - 84, 89, 128, 85, 78, 73, 84, 69, 196, 85, 78, 73, 84, 128, 85, 78, 73, - 212, 85, 78, 73, 79, 78, 128, 85, 78, 73, 79, 206, 85, 78, 73, 70, 79, - 82, 77, 128, 85, 78, 73, 70, 73, 69, 196, 85, 78, 73, 67, 79, 82, 206, - 85, 78, 69, 86, 69, 206, 85, 78, 68, 207, 85, 78, 68, 69, 82, 84, 73, 69, - 128, 85, 78, 68, 69, 82, 76, 73, 78, 197, 85, 78, 68, 69, 82, 68, 79, 84, - 128, 85, 78, 68, 69, 82, 66, 65, 82, 128, 85, 78, 68, 69, 82, 128, 85, - 78, 68, 69, 210, 85, 78, 67, 73, 193, 85, 78, 67, 69, 82, 84, 65, 73, 78, - 84, 217, 85, 78, 66, 76, 69, 78, 68, 69, 196, 85, 78, 65, 83, 80, 73, 82, - 65, 84, 69, 68, 128, 85, 78, 65, 80, 128, 85, 78, 65, 77, 85, 83, 69, - 196, 85, 78, 65, 128, 85, 206, 85, 77, 85, 77, 128, 85, 77, 85, 205, 85, - 77, 66, 82, 69, 76, 76, 65, 128, 85, 77, 66, 82, 69, 76, 76, 193, 85, 77, - 66, 73, 78, 128, 85, 75, 85, 128, 85, 75, 82, 65, 73, 78, 73, 65, 206, - 85, 75, 65, 82, 65, 128, 85, 75, 65, 82, 193, 85, 75, 128, 85, 73, 90, - 128, 85, 73, 88, 128, 85, 73, 85, 90, 128, 85, 73, 85, 88, 128, 85, 73, - 85, 81, 128, 85, 73, 85, 67, 128, 85, 73, 81, 128, 85, 73, 76, 76, 69, - 65, 78, 78, 128, 85, 73, 71, 72, 85, 210, 85, 73, 67, 128, 85, 72, 68, - 128, 85, 71, 65, 82, 73, 84, 73, 195, 85, 69, 90, 128, 85, 69, 89, 128, - 85, 69, 88, 128, 85, 69, 78, 128, 85, 69, 73, 128, 85, 69, 69, 128, 85, - 69, 67, 128, 85, 69, 65, 128, 85, 68, 85, 71, 128, 85, 68, 65, 84, 84, - 65, 128, 85, 68, 65, 84, 84, 193, 85, 68, 65, 82, 75, 65, 128, 85, 68, - 65, 65, 84, 128, 85, 68, 128, 85, 196, 85, 66, 85, 70, 73, 76, 73, 128, - 85, 66, 72, 65, 89, 65, 84, 207, 85, 66, 65, 68, 65, 77, 65, 128, 85, 66, - 128, 85, 65, 84, 72, 128, 85, 65, 78, 71, 128, 85, 65, 128, 85, 178, 85, - 48, 52, 50, 128, 85, 48, 52, 49, 128, 85, 48, 52, 48, 128, 85, 48, 51, - 57, 128, 85, 48, 51, 56, 128, 85, 48, 51, 55, 128, 85, 48, 51, 54, 128, - 85, 48, 51, 53, 128, 85, 48, 51, 52, 128, 85, 48, 51, 51, 128, 85, 48, - 51, 50, 65, 128, 85, 48, 51, 50, 128, 85, 48, 51, 49, 128, 85, 48, 51, - 48, 128, 85, 48, 50, 57, 65, 128, 85, 48, 50, 57, 128, 85, 48, 50, 56, - 128, 85, 48, 50, 55, 128, 85, 48, 50, 54, 128, 85, 48, 50, 53, 128, 85, - 48, 50, 52, 128, 85, 48, 50, 51, 65, 128, 85, 48, 50, 51, 128, 85, 48, - 50, 50, 128, 85, 48, 50, 49, 128, 85, 48, 50, 48, 128, 85, 48, 49, 57, - 128, 85, 48, 49, 56, 128, 85, 48, 49, 55, 128, 85, 48, 49, 54, 128, 85, - 48, 49, 53, 128, 85, 48, 49, 52, 128, 85, 48, 49, 51, 128, 85, 48, 49, - 50, 128, 85, 48, 49, 49, 128, 85, 48, 49, 48, 128, 85, 48, 48, 57, 128, - 85, 48, 48, 56, 128, 85, 48, 48, 55, 128, 85, 48, 48, 54, 66, 128, 85, - 48, 48, 54, 65, 128, 85, 48, 48, 54, 128, 85, 48, 48, 53, 128, 85, 48, - 48, 52, 128, 85, 48, 48, 51, 128, 85, 48, 48, 50, 128, 85, 48, 48, 49, - 128, 85, 45, 83, 72, 65, 80, 69, 196, 85, 45, 73, 45, 73, 128, 85, 45, - 69, 79, 45, 69, 85, 128, 85, 45, 66, 82, 74, 71, 85, 128, 85, 45, 53, - 128, 84, 90, 85, 128, 84, 90, 79, 65, 128, 84, 90, 79, 128, 84, 90, 73, - 210, 84, 90, 73, 128, 84, 90, 69, 69, 128, 84, 90, 69, 128, 84, 90, 65, - 65, 128, 84, 90, 65, 128, 84, 90, 128, 84, 89, 210, 84, 89, 80, 69, 45, - 183, 84, 89, 80, 69, 45, 54, 128, 84, 89, 80, 69, 45, 182, 84, 89, 80, - 69, 45, 53, 128, 84, 89, 80, 69, 45, 181, 84, 89, 80, 69, 45, 52, 128, - 84, 89, 80, 69, 45, 180, 84, 89, 80, 69, 45, 51, 128, 84, 89, 80, 69, 45, - 179, 84, 89, 80, 69, 45, 178, 84, 89, 80, 69, 45, 49, 45, 50, 128, 84, - 89, 80, 69, 45, 177, 84, 89, 80, 197, 84, 89, 79, 128, 84, 89, 73, 128, - 84, 89, 69, 128, 84, 89, 65, 89, 128, 84, 89, 65, 128, 84, 88, 87, 86, - 128, 84, 88, 87, 214, 84, 88, 72, 69, 69, 202, 84, 88, 65, 128, 84, 87, - 79, 79, 128, 84, 87, 79, 45, 87, 65, 217, 84, 87, 79, 45, 84, 72, 73, 82, - 84, 89, 128, 84, 87, 79, 45, 76, 73, 78, 197, 84, 87, 79, 45, 72, 69, 65, - 68, 69, 196, 84, 87, 79, 45, 69, 205, 84, 87, 79, 45, 67, 73, 82, 67, 76, - 197, 84, 87, 73, 83, 84, 73, 78, 71, 128, 84, 87, 73, 83, 84, 69, 196, - 84, 87, 73, 73, 128, 84, 87, 73, 128, 84, 87, 69, 78, 84, 89, 45, 84, 87, - 79, 128, 84, 87, 69, 78, 84, 89, 45, 84, 87, 207, 84, 87, 69, 78, 84, 89, - 45, 84, 72, 82, 69, 69, 128, 84, 87, 69, 78, 84, 89, 45, 83, 73, 88, 128, - 84, 87, 69, 78, 84, 89, 45, 83, 69, 86, 69, 78, 128, 84, 87, 69, 78, 84, - 89, 45, 79, 78, 69, 128, 84, 87, 69, 78, 84, 89, 45, 78, 73, 78, 69, 128, - 84, 87, 69, 78, 84, 89, 45, 70, 79, 85, 82, 128, 84, 87, 69, 78, 84, 89, - 45, 70, 73, 86, 69, 128, 84, 87, 69, 78, 84, 89, 45, 70, 73, 86, 197, 84, - 87, 69, 78, 84, 89, 45, 69, 73, 71, 72, 84, 200, 84, 87, 69, 78, 84, 89, - 45, 69, 73, 71, 72, 84, 128, 84, 87, 69, 78, 84, 89, 128, 84, 87, 69, 78, - 84, 217, 84, 87, 69, 78, 84, 73, 69, 84, 72, 83, 128, 84, 87, 69, 78, 84, - 73, 69, 84, 72, 128, 84, 87, 69, 76, 86, 69, 45, 84, 72, 73, 82, 84, 89, - 128, 84, 87, 69, 76, 86, 69, 128, 84, 87, 69, 76, 86, 197, 84, 87, 69, - 76, 70, 84, 72, 83, 128, 84, 87, 69, 76, 70, 84, 72, 128, 84, 87, 69, - 128, 84, 87, 65, 65, 128, 84, 87, 65, 128, 84, 86, 82, 73, 68, 79, 128, - 84, 86, 73, 77, 65, 68, 85, 210, 84, 85, 88, 69, 68, 79, 128, 84, 85, 88, - 128, 84, 85, 85, 77, 85, 128, 84, 85, 85, 128, 84, 85, 84, 84, 89, 128, - 84, 85, 84, 69, 89, 65, 83, 65, 84, 128, 84, 85, 84, 128, 84, 85, 82, 88, - 128, 84, 85, 82, 85, 128, 84, 85, 82, 84, 76, 69, 128, 84, 85, 82, 79, - 50, 128, 84, 85, 82, 78, 83, 84, 73, 76, 69, 128, 84, 85, 82, 206, 84, - 85, 82, 75, 73, 83, 200, 84, 85, 82, 75, 73, 195, 84, 85, 82, 75, 69, 89, - 128, 84, 85, 82, 66, 65, 78, 128, 84, 85, 82, 128, 84, 85, 210, 84, 85, - 80, 78, 73, 128, 84, 85, 80, 128, 84, 85, 79, 88, 128, 84, 85, 79, 84, - 128, 84, 85, 79, 80, 128, 84, 85, 79, 128, 84, 85, 78, 78, 89, 128, 84, - 85, 77, 69, 84, 69, 83, 128, 84, 85, 77, 66, 76, 69, 210, 84, 85, 77, 65, - 69, 128, 84, 85, 77, 128, 84, 85, 205, 84, 85, 76, 73, 80, 128, 84, 85, - 75, 87, 69, 78, 84, 73, 83, 128, 84, 85, 75, 128, 84, 85, 71, 82, 73, - 203, 84, 85, 71, 50, 128, 84, 85, 71, 178, 84, 85, 66, 69, 128, 84, 85, - 66, 128, 84, 85, 65, 82, 69, 199, 84, 85, 65, 69, 80, 128, 84, 85, 65, - 69, 128, 84, 85, 45, 84, 79, 128, 84, 85, 45, 52, 128, 84, 85, 45, 51, - 128, 84, 85, 45, 50, 128, 84, 85, 45, 49, 128, 84, 213, 84, 84, 85, 85, - 128, 84, 84, 85, 68, 68, 65, 71, 128, 84, 84, 85, 68, 68, 65, 65, 71, - 128, 84, 84, 85, 128, 84, 84, 84, 72, 65, 128, 84, 84, 84, 65, 128, 84, - 84, 83, 85, 128, 84, 84, 83, 79, 128, 84, 84, 83, 73, 128, 84, 84, 83, - 69, 69, 128, 84, 84, 83, 69, 128, 84, 84, 83, 65, 128, 84, 84, 79, 79, - 128, 84, 84, 73, 73, 128, 84, 84, 73, 128, 84, 84, 72, 87, 69, 128, 84, - 84, 72, 85, 128, 84, 84, 72, 79, 79, 128, 84, 84, 72, 79, 128, 84, 84, - 72, 73, 128, 84, 84, 72, 69, 69, 128, 84, 84, 72, 69, 128, 84, 84, 72, - 65, 65, 128, 84, 84, 72, 128, 84, 84, 69, 72, 69, 72, 128, 84, 84, 69, - 72, 69, 200, 84, 84, 69, 72, 128, 84, 84, 69, 200, 84, 84, 69, 69, 128, - 84, 84, 65, 89, 65, 78, 78, 65, 128, 84, 84, 65, 85, 128, 84, 84, 65, 73, - 128, 84, 84, 65, 65, 128, 84, 84, 50, 128, 84, 83, 87, 69, 128, 84, 83, - 87, 66, 128, 84, 83, 87, 65, 128, 84, 83, 86, 128, 84, 83, 83, 69, 128, - 84, 83, 83, 65, 128, 84, 83, 79, 214, 84, 83, 73, 85, 128, 84, 83, 72, - 85, 71, 83, 128, 84, 83, 72, 79, 79, 75, 128, 84, 83, 72, 79, 79, 203, - 84, 83, 72, 79, 79, 74, 128, 84, 83, 72, 69, 83, 128, 84, 83, 72, 69, 71, - 128, 84, 83, 72, 69, 199, 84, 83, 72, 69, 69, 74, 128, 84, 83, 72, 69, - 128, 84, 83, 72, 65, 194, 84, 83, 72, 65, 128, 84, 83, 69, 82, 69, 128, - 84, 83, 69, 69, 66, 128, 84, 83, 65, 84, 193, 84, 83, 65, 68, 73, 128, - 84, 83, 65, 68, 201, 84, 83, 65, 66, 128, 84, 83, 65, 65, 68, 73, 89, - 128, 84, 83, 65, 65, 128, 84, 83, 193, 84, 82, 89, 66, 76, 73, 79, 206, - 84, 82, 89, 65, 83, 79, 83, 84, 82, 69, 76, 78, 65, 89, 65, 128, 84, 82, - 89, 65, 83, 79, 80, 79, 86, 79, 68, 78, 65, 89, 65, 128, 84, 82, 89, 65, - 83, 79, 71, 76, 65, 83, 78, 65, 89, 65, 128, 84, 82, 89, 65, 83, 75, 65, - 128, 84, 82, 85, 84, 72, 128, 84, 82, 85, 78, 75, 128, 84, 82, 85, 78, - 67, 65, 84, 69, 196, 84, 82, 85, 77, 80, 69, 84, 128, 84, 82, 85, 77, 80, - 45, 57, 128, 84, 82, 85, 77, 80, 45, 56, 128, 84, 82, 85, 77, 80, 45, 55, - 128, 84, 82, 85, 77, 80, 45, 54, 128, 84, 82, 85, 77, 80, 45, 53, 128, - 84, 82, 85, 77, 80, 45, 52, 128, 84, 82, 85, 77, 80, 45, 51, 128, 84, 82, - 85, 77, 80, 45, 50, 49, 128, 84, 82, 85, 77, 80, 45, 50, 48, 128, 84, 82, - 85, 77, 80, 45, 50, 128, 84, 82, 85, 77, 80, 45, 49, 57, 128, 84, 82, 85, - 77, 80, 45, 49, 56, 128, 84, 82, 85, 77, 80, 45, 49, 55, 128, 84, 82, 85, - 77, 80, 45, 49, 54, 128, 84, 82, 85, 77, 80, 45, 49, 53, 128, 84, 82, 85, - 77, 80, 45, 49, 52, 128, 84, 82, 85, 77, 80, 45, 49, 51, 128, 84, 82, 85, - 77, 80, 45, 49, 50, 128, 84, 82, 85, 77, 80, 45, 49, 49, 128, 84, 82, 85, - 77, 80, 45, 49, 48, 128, 84, 82, 85, 77, 80, 45, 49, 128, 84, 82, 85, 69, - 128, 84, 82, 85, 197, 84, 82, 85, 67, 75, 128, 84, 82, 79, 80, 73, 67, - 65, 204, 84, 82, 79, 80, 72, 89, 128, 84, 82, 79, 77, 73, 75, 79, 83, 89, - 78, 65, 71, 77, 65, 128, 84, 82, 79, 77, 73, 75, 79, 80, 83, 73, 70, 73, - 83, 84, 79, 78, 128, 84, 82, 79, 77, 73, 75, 79, 80, 65, 82, 65, 75, 65, - 76, 69, 83, 77, 65, 128, 84, 82, 79, 77, 73, 75, 79, 78, 128, 84, 82, 79, - 77, 73, 75, 79, 206, 84, 82, 79, 77, 73, 75, 79, 76, 89, 71, 73, 83, 77, - 65, 128, 84, 82, 79, 76, 76, 69, 89, 66, 85, 83, 128, 84, 82, 79, 76, 76, - 69, 89, 128, 84, 82, 79, 76, 76, 128, 84, 82, 79, 75, 85, 84, 65, 83, 84, - 201, 84, 82, 79, 69, 90, 69, 78, 73, 65, 206, 84, 82, 73, 85, 77, 80, 72, - 128, 84, 82, 73, 84, 79, 211, 84, 82, 73, 84, 73, 77, 79, 82, 73, 79, 78, - 128, 84, 82, 73, 83, 73, 77, 79, 85, 128, 84, 82, 73, 83, 69, 77, 69, - 128, 84, 82, 73, 80, 79, 68, 128, 84, 82, 73, 80, 76, 73, 128, 84, 82, - 73, 80, 76, 69, 128, 84, 82, 73, 80, 76, 197, 84, 82, 73, 79, 206, 84, - 82, 73, 76, 76, 73, 79, 78, 83, 128, 84, 82, 73, 76, 76, 128, 84, 82, 73, - 73, 83, 65, 80, 128, 84, 82, 73, 71, 82, 65, 77, 77, 79, 211, 84, 82, 73, - 71, 82, 65, 205, 84, 82, 73, 71, 79, 82, 71, 79, 78, 128, 84, 82, 73, 70, - 79, 78, 73, 65, 83, 128, 84, 82, 73, 70, 79, 76, 73, 65, 84, 197, 84, 82, - 73, 68, 69, 78, 84, 128, 84, 82, 73, 68, 69, 78, 212, 84, 82, 73, 67, 79, - 76, 79, 78, 128, 84, 82, 73, 65, 78, 71, 85, 76, 65, 210, 84, 82, 73, 65, - 78, 71, 76, 69, 45, 82, 79, 85, 78, 196, 84, 82, 73, 65, 78, 71, 76, 69, - 45, 72, 69, 65, 68, 69, 196, 84, 82, 73, 65, 78, 71, 76, 69, 128, 84, 82, - 73, 65, 78, 71, 76, 197, 84, 82, 73, 65, 128, 84, 82, 73, 128, 84, 82, - 69, 83, 86, 69, 84, 76, 89, 128, 84, 82, 69, 83, 86, 69, 84, 76, 79, 128, - 84, 82, 69, 83, 86, 69, 84, 76, 65, 89, 65, 128, 84, 82, 69, 83, 73, 76, - 76, 79, 128, 84, 82, 69, 78, 68, 128, 84, 82, 69, 78, 196, 84, 82, 69, - 77, 79, 76, 79, 45, 51, 128, 84, 82, 69, 77, 79, 76, 79, 45, 50, 128, 84, - 82, 69, 77, 79, 76, 79, 45, 49, 128, 84, 82, 69, 69, 128, 84, 82, 69, - 197, 84, 82, 69, 68, 69, 67, 73, 76, 69, 128, 84, 82, 69, 65, 68, 73, 78, - 71, 128, 84, 82, 65, 89, 128, 84, 82, 65, 86, 69, 76, 45, 87, 65, 76, 76, - 80, 76, 65, 78, 197, 84, 82, 65, 86, 69, 76, 45, 70, 76, 79, 79, 82, 80, - 76, 65, 78, 197, 84, 82, 65, 80, 69, 90, 73, 85, 77, 128, 84, 82, 65, 80, - 128, 84, 82, 65, 78, 83, 86, 69, 82, 83, 65, 204, 84, 82, 65, 78, 83, 80, - 79, 83, 73, 84, 73, 79, 206, 84, 82, 65, 78, 83, 80, 76, 85, 84, 79, 128, - 84, 82, 65, 78, 83, 77, 73, 212, 84, 82, 65, 78, 83, 77, 73, 83, 83, 73, - 79, 78, 128, 84, 82, 65, 78, 83, 77, 73, 83, 83, 73, 79, 206, 84, 82, 65, - 77, 87, 65, 89, 128, 84, 82, 65, 77, 128, 84, 82, 65, 205, 84, 82, 65, - 73, 78, 128, 84, 82, 65, 73, 206, 84, 82, 65, 73, 76, 73, 78, 199, 84, - 82, 65, 70, 70, 73, 67, 128, 84, 82, 65, 70, 70, 73, 195, 84, 82, 65, 68, - 73, 84, 73, 79, 78, 65, 204, 84, 82, 65, 68, 197, 84, 82, 65, 67, 84, 79, - 82, 128, 84, 82, 65, 67, 75, 66, 65, 76, 76, 128, 84, 82, 65, 67, 75, - 128, 84, 82, 65, 128, 84, 82, 128, 84, 79, 88, 128, 84, 79, 87, 69, 82, - 128, 84, 79, 87, 65, 82, 68, 211, 84, 79, 86, 128, 84, 79, 85, 82, 78, - 79, 73, 211, 84, 79, 85, 67, 72, 84, 79, 78, 197, 84, 79, 85, 67, 72, 73, - 78, 199, 84, 79, 85, 67, 72, 69, 211, 84, 79, 85, 67, 200, 84, 79, 84, - 207, 84, 79, 84, 65, 204, 84, 79, 84, 128, 84, 79, 83, 128, 84, 79, 82, - 84, 79, 73, 83, 197, 84, 79, 82, 83, 79, 45, 87, 65, 76, 76, 80, 76, 65, - 78, 197, 84, 79, 82, 83, 79, 45, 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, - 84, 79, 82, 83, 79, 128, 84, 79, 82, 78, 65, 68, 79, 128, 84, 79, 82, 67, - 85, 76, 85, 83, 128, 84, 79, 82, 67, 85, 76, 85, 211, 84, 79, 82, 67, 72, - 128, 84, 79, 81, 128, 84, 79, 80, 66, 65, 82, 128, 84, 79, 80, 45, 76, - 73, 71, 72, 84, 69, 196, 84, 79, 80, 128, 84, 79, 208, 84, 79, 79, 84, - 72, 66, 82, 85, 83, 72, 128, 84, 79, 79, 84, 72, 128, 84, 79, 79, 78, - 128, 84, 79, 79, 76, 66, 79, 88, 128, 84, 79, 78, 79, 83, 128, 84, 79, - 78, 71, 85, 69, 128, 84, 79, 78, 71, 85, 197, 84, 79, 78, 71, 128, 84, - 79, 78, 69, 45, 86, 128, 84, 79, 78, 69, 45, 83, 128, 84, 79, 78, 69, 45, - 77, 128, 84, 79, 78, 69, 45, 74, 128, 84, 79, 78, 69, 45, 71, 128, 84, - 79, 78, 69, 45, 68, 128, 84, 79, 78, 69, 45, 66, 128, 84, 79, 78, 69, 45, - 56, 128, 84, 79, 78, 69, 45, 55, 128, 84, 79, 78, 69, 45, 54, 128, 84, - 79, 78, 69, 45, 53, 128, 84, 79, 78, 69, 45, 52, 128, 84, 79, 78, 69, 45, - 51, 128, 84, 79, 78, 69, 45, 50, 128, 84, 79, 78, 69, 45, 49, 128, 84, - 79, 78, 69, 128, 84, 79, 78, 65, 204, 84, 79, 77, 80, 73, 128, 84, 79, - 77, 65, 84, 79, 128, 84, 79, 76, 79, 78, 71, 128, 84, 79, 75, 89, 207, - 84, 79, 73, 76, 69, 84, 128, 84, 79, 71, 69, 84, 72, 69, 82, 128, 84, 79, - 68, 207, 84, 79, 67, 72, 75, 65, 128, 84, 79, 65, 78, 68, 65, 75, 72, 73, - 65, 84, 128, 84, 79, 65, 128, 84, 79, 45, 82, 65, 128, 84, 79, 45, 54, - 128, 84, 79, 45, 53, 128, 84, 79, 45, 52, 128, 84, 79, 45, 51, 128, 84, - 79, 45, 50, 128, 84, 79, 45, 49, 128, 84, 78, 128, 84, 76, 86, 128, 84, - 76, 85, 128, 84, 76, 73, 128, 84, 76, 72, 89, 65, 128, 84, 76, 72, 87, - 69, 128, 84, 76, 72, 85, 128, 84, 76, 72, 79, 79, 128, 84, 76, 72, 79, - 128, 84, 76, 72, 73, 128, 84, 76, 72, 69, 69, 128, 84, 76, 72, 69, 128, - 84, 76, 72, 65, 128, 84, 76, 69, 69, 128, 84, 76, 65, 128, 84, 74, 69, - 128, 84, 73, 88, 128, 84, 73, 87, 82, 128, 84, 73, 87, 78, 128, 84, 73, - 87, 65, 218, 84, 73, 84, 85, 65, 69, 80, 128, 84, 73, 84, 76, 79, 128, - 84, 73, 84, 76, 207, 84, 73, 84, 193, 84, 73, 84, 128, 84, 73, 82, 89, - 65, 75, 128, 84, 73, 82, 84, 193, 84, 73, 82, 79, 78, 73, 65, 206, 84, - 73, 82, 72, 85, 84, 193, 84, 73, 82, 69, 196, 84, 73, 82, 128, 84, 73, - 210, 84, 73, 80, 80, 73, 128, 84, 73, 80, 69, 72, 65, 128, 84, 73, 80, - 128, 84, 73, 208, 84, 73, 78, 89, 128, 84, 73, 78, 217, 84, 73, 78, 78, - 69, 128, 84, 73, 78, 67, 84, 85, 82, 69, 128, 84, 73, 78, 65, 71, 77, 65, - 128, 84, 73, 77, 69, 83, 128, 84, 73, 77, 69, 210, 84, 73, 77, 69, 128, - 84, 73, 76, 84, 73, 78, 71, 128, 84, 73, 76, 84, 73, 78, 199, 84, 73, 76, - 84, 128, 84, 73, 76, 69, 83, 128, 84, 73, 76, 68, 69, 128, 84, 73, 76, - 68, 197, 84, 73, 76, 128, 84, 73, 204, 84, 73, 75, 72, 89, 128, 84, 73, - 75, 72, 65, 89, 65, 128, 84, 73, 75, 72, 65, 89, 193, 84, 73, 75, 69, 85, - 84, 45, 84, 72, 73, 69, 85, 84, 72, 128, 84, 73, 75, 69, 85, 84, 45, 83, - 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 84, 73, 75, 69, 85, 84, 45, - 83, 73, 79, 83, 128, 84, 73, 75, 69, 85, 84, 45, 82, 73, 69, 85, 76, 128, - 84, 73, 75, 69, 85, 84, 45, 80, 73, 69, 85, 80, 128, 84, 73, 75, 69, 85, - 84, 45, 77, 73, 69, 85, 77, 128, 84, 73, 75, 69, 85, 84, 45, 75, 73, 89, - 69, 79, 75, 128, 84, 73, 75, 69, 85, 84, 45, 67, 73, 69, 85, 67, 128, 84, - 73, 75, 69, 85, 84, 45, 67, 72, 73, 69, 85, 67, 72, 128, 84, 73, 75, 69, - 85, 84, 128, 84, 73, 75, 69, 85, 212, 84, 73, 71, 72, 84, 76, 89, 45, 67, - 76, 79, 83, 69, 196, 84, 73, 71, 72, 212, 84, 73, 71, 69, 82, 128, 84, - 73, 71, 69, 210, 84, 73, 70, 73, 78, 65, 71, 200, 84, 73, 69, 88, 128, - 84, 73, 69, 80, 128, 84, 73, 197, 84, 73, 67, 75, 69, 84, 83, 128, 84, - 73, 67, 75, 69, 84, 128, 84, 73, 67, 75, 128, 84, 73, 67, 203, 84, 73, - 65, 82, 65, 128, 84, 73, 50, 128, 84, 73, 45, 55, 128, 84, 73, 45, 54, - 128, 84, 73, 45, 53, 128, 84, 73, 45, 52, 128, 84, 73, 45, 51, 128, 84, - 73, 45, 50, 128, 84, 73, 45, 49, 128, 84, 72, 90, 128, 84, 72, 89, 79, - 79, 205, 84, 72, 87, 79, 79, 128, 84, 72, 87, 79, 128, 84, 72, 87, 73, - 73, 128, 84, 72, 87, 73, 128, 84, 72, 87, 69, 69, 128, 84, 72, 87, 65, - 65, 128, 84, 72, 87, 65, 128, 84, 72, 85, 82, 211, 84, 72, 85, 82, 73, - 83, 65, 218, 84, 72, 85, 78, 71, 128, 84, 72, 85, 78, 68, 69, 82, 83, 84, - 79, 82, 77, 128, 84, 72, 85, 78, 68, 69, 82, 128, 84, 72, 85, 78, 68, 69, + 79, 87, 206, 80, 65, 72, 65, 87, 200, 67, 72, 79, 83, 69, 79, 78, 199, + 66, 65, 76, 73, 78, 69, 83, 197, 70, 73, 86, 69, 128, 72, 65, 76, 70, 87, + 73, 68, 84, 200, 72, 65, 78, 68, 45, 70, 73, 83, 212, 77, 69, 82, 79, 73, + 84, 73, 195, 84, 85, 82, 78, 69, 196, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 73, 195, 75, 65, 128, 76, 73, 71, 72, 212, 73, 68, 69, 79, 71, 82, 65, + 205, 80, 72, 65, 83, 69, 45, 196, 84, 79, 128, 65, 76, 67, 72, 69, 77, + 73, 67, 65, 204, 78, 69, 85, 77, 197, 66, 82, 65, 72, 77, 201, 84, 79, + 78, 197, 66, 65, 82, 128, 82, 65, 128, 83, 73, 78, 72, 65, 76, 193, 78, + 85, 77, 69, 82, 73, 195, 80, 65, 128, 83, 73, 88, 128, 89, 65, 128, 69, + 73, 71, 72, 84, 128, 76, 65, 128, 77, 65, 128, 83, 69, 86, 69, 78, 128, + 84, 72, 85, 77, 194, 72, 85, 78, 71, 65, 82, 73, 65, 206, 78, 73, 78, 69, + 128, 76, 79, 78, 199, 78, 65, 128, 66, 65, 82, 194, 72, 65, 200, 82, 73, + 71, 72, 84, 128, 66, 76, 79, 67, 203, 68, 79, 84, 211, 78, 79, 82, 84, + 200, 83, 65, 128, 84, 72, 79, 85, 83, 65, 78, 68, 128, 84, 65, 128, 90, + 90, 89, 88, 128, 90, 90, 89, 84, 128, 90, 90, 89, 82, 88, 128, 90, 90, + 89, 82, 128, 90, 90, 89, 80, 128, 90, 90, 89, 65, 128, 90, 90, 89, 128, + 90, 90, 85, 88, 128, 90, 90, 85, 82, 88, 128, 90, 90, 85, 82, 128, 90, + 90, 85, 80, 128, 90, 90, 85, 128, 90, 90, 83, 89, 65, 128, 90, 90, 83, + 65, 128, 90, 90, 79, 88, 128, 90, 90, 79, 80, 128, 90, 90, 79, 128, 90, + 90, 73, 88, 128, 90, 90, 73, 84, 128, 90, 90, 73, 80, 128, 90, 90, 73, + 69, 88, 128, 90, 90, 73, 69, 84, 128, 90, 90, 73, 69, 80, 128, 90, 90, + 73, 69, 128, 90, 90, 73, 128, 90, 90, 69, 88, 128, 90, 90, 69, 80, 128, + 90, 90, 69, 69, 128, 90, 90, 69, 128, 90, 90, 65, 88, 128, 90, 90, 65, + 84, 128, 90, 90, 65, 80, 128, 90, 90, 65, 65, 128, 90, 90, 65, 128, 90, + 89, 71, 79, 83, 128, 90, 87, 83, 80, 128, 90, 87, 78, 74, 128, 90, 87, + 78, 66, 83, 80, 128, 90, 87, 74, 128, 90, 87, 202, 90, 87, 65, 82, 65, + 75, 65, 89, 128, 90, 87, 65, 128, 90, 85, 84, 128, 90, 85, 79, 88, 128, + 90, 85, 79, 80, 128, 90, 85, 79, 128, 90, 85, 77, 128, 90, 85, 66, 85, + 82, 128, 90, 85, 53, 128, 90, 85, 181, 90, 213, 90, 83, 72, 65, 128, 90, + 82, 65, 128, 90, 81, 65, 80, 72, 193, 90, 79, 84, 128, 90, 79, 79, 128, + 90, 79, 77, 66, 73, 69, 128, 90, 79, 65, 128, 90, 77, 69, 89, 84, 83, 65, + 128, 90, 76, 65, 77, 193, 90, 76, 65, 128, 90, 76, 193, 90, 74, 69, 128, + 90, 73, 90, 50, 128, 90, 73, 81, 65, 65, 128, 90, 73, 80, 80, 69, 82, 45, + 77, 79, 85, 84, 200, 90, 73, 78, 79, 82, 128, 90, 73, 76, 68, 69, 128, + 90, 73, 71, 90, 65, 199, 90, 73, 71, 128, 90, 73, 68, 193, 90, 73, 66, + 128, 90, 73, 194, 90, 73, 51, 128, 90, 201, 90, 72, 89, 88, 128, 90, 72, + 89, 84, 128, 90, 72, 89, 82, 88, 128, 90, 72, 89, 82, 128, 90, 72, 89, + 80, 128, 90, 72, 89, 128, 90, 72, 87, 69, 128, 90, 72, 87, 65, 128, 90, + 72, 85, 88, 128, 90, 72, 85, 84, 128, 90, 72, 85, 82, 88, 128, 90, 72, + 85, 82, 128, 90, 72, 85, 80, 128, 90, 72, 85, 79, 88, 128, 90, 72, 85, + 79, 80, 128, 90, 72, 85, 79, 128, 90, 72, 85, 128, 90, 72, 79, 88, 128, + 90, 72, 79, 84, 128, 90, 72, 79, 80, 128, 90, 72, 79, 79, 128, 90, 72, + 79, 73, 128, 90, 72, 79, 128, 90, 72, 73, 86, 69, 84, 69, 128, 90, 72, + 73, 76, 128, 90, 72, 73, 128, 90, 72, 69, 88, 128, 90, 72, 69, 84, 128, + 90, 72, 69, 80, 128, 90, 72, 69, 69, 128, 90, 72, 69, 128, 90, 72, 197, + 90, 72, 65, 89, 73, 78, 128, 90, 72, 65, 88, 128, 90, 72, 65, 84, 128, + 90, 72, 65, 82, 128, 90, 72, 65, 80, 128, 90, 72, 65, 73, 78, 128, 90, + 72, 65, 65, 128, 90, 72, 65, 128, 90, 72, 128, 90, 69, 86, 79, 75, 128, + 90, 69, 85, 83, 128, 90, 69, 84, 65, 128, 90, 69, 82, 79, 128, 90, 69, + 82, 207, 90, 69, 78, 128, 90, 69, 77, 76, 89, 65, 128, 90, 69, 77, 76, + 74, 65, 128, 90, 69, 76, 79, 128, 90, 69, 66, 82, 193, 90, 69, 50, 128, + 90, 197, 90, 65, 89, 78, 128, 90, 65, 89, 73, 78, 45, 89, 79, 68, 72, + 128, 90, 65, 89, 73, 78, 128, 90, 65, 89, 73, 206, 90, 65, 86, 73, 89, + 65, 78, 73, 128, 90, 65, 84, 65, 128, 90, 65, 82, 81, 65, 128, 90, 65, + 82, 76, 128, 90, 65, 81, 69, 198, 90, 65, 80, 89, 65, 84, 89, 77, 73, + 128, 90, 65, 80, 89, 65, 84, 79, 89, 128, 90, 65, 80, 89, 65, 84, 79, + 217, 90, 65, 80, 89, 65, 84, 65, 89, 65, 128, 90, 65, 78, 79, 90, 72, 69, + 75, 128, 90, 65, 78, 65, 66, 65, 90, 65, 210, 90, 65, 77, 88, 128, 90, + 65, 76, 128, 90, 65, 204, 90, 65, 75, 82, 89, 84, 79, 69, 128, 90, 65, + 75, 82, 89, 84, 65, 89, 65, 128, 90, 65, 75, 82, 89, 84, 65, 89, 193, 90, + 65, 73, 78, 128, 90, 65, 73, 206, 90, 65, 73, 128, 90, 65, 72, 128, 90, + 65, 200, 90, 65, 71, 128, 90, 65, 69, 70, 128, 90, 65, 68, 69, 82, 90, + 72, 75, 65, 128, 90, 65, 55, 128, 90, 193, 90, 48, 49, 54, 72, 128, 90, + 48, 49, 54, 71, 128, 90, 48, 49, 54, 70, 128, 90, 48, 49, 54, 69, 128, + 90, 48, 49, 54, 68, 128, 90, 48, 49, 54, 67, 128, 90, 48, 49, 54, 66, + 128, 90, 48, 49, 54, 65, 128, 90, 48, 49, 54, 128, 90, 48, 49, 53, 73, + 128, 90, 48, 49, 53, 72, 128, 90, 48, 49, 53, 71, 128, 90, 48, 49, 53, + 70, 128, 90, 48, 49, 53, 69, 128, 90, 48, 49, 53, 68, 128, 90, 48, 49, + 53, 67, 128, 90, 48, 49, 53, 66, 128, 90, 48, 49, 53, 65, 128, 90, 48, + 49, 53, 128, 90, 48, 49, 52, 128, 90, 48, 49, 51, 128, 90, 48, 49, 50, + 128, 90, 48, 49, 49, 128, 90, 48, 49, 48, 128, 90, 48, 48, 57, 128, 90, + 48, 48, 56, 128, 90, 48, 48, 55, 128, 90, 48, 48, 54, 128, 90, 48, 48, + 53, 65, 128, 90, 48, 48, 53, 128, 90, 48, 48, 52, 65, 128, 90, 48, 48, + 52, 128, 90, 48, 48, 51, 66, 128, 90, 48, 48, 51, 65, 128, 90, 48, 48, + 51, 128, 90, 48, 48, 50, 68, 128, 90, 48, 48, 50, 67, 128, 90, 48, 48, + 50, 66, 128, 90, 48, 48, 50, 65, 128, 90, 48, 48, 50, 128, 90, 48, 48, + 49, 128, 90, 128, 218, 89, 89, 88, 128, 89, 89, 84, 128, 89, 89, 82, 88, + 128, 89, 89, 82, 128, 89, 89, 80, 128, 89, 89, 69, 128, 89, 89, 65, 65, + 128, 89, 89, 65, 128, 89, 89, 128, 89, 87, 79, 79, 128, 89, 87, 79, 128, + 89, 87, 73, 73, 128, 89, 87, 73, 128, 89, 87, 69, 128, 89, 87, 65, 65, + 128, 89, 87, 65, 128, 89, 86, 128, 89, 85, 88, 128, 89, 85, 87, 79, 81, + 128, 89, 85, 85, 75, 65, 76, 69, 65, 80, 73, 78, 84, 85, 128, 89, 85, 85, + 128, 89, 85, 84, 128, 89, 85, 83, 128, 89, 85, 211, 89, 85, 82, 88, 128, + 89, 85, 82, 128, 89, 85, 81, 128, 89, 85, 209, 89, 85, 80, 128, 89, 85, + 79, 88, 128, 89, 85, 79, 84, 128, 89, 85, 79, 80, 128, 89, 85, 79, 77, + 128, 89, 85, 79, 128, 89, 85, 78, 128, 89, 85, 77, 128, 89, 85, 74, 128, + 89, 85, 73, 128, 89, 85, 69, 81, 128, 89, 85, 69, 128, 89, 85, 68, 72, + 128, 89, 85, 68, 200, 89, 85, 65, 78, 128, 89, 85, 65, 69, 78, 128, 89, + 85, 45, 89, 69, 79, 128, 89, 85, 45, 89, 69, 128, 89, 85, 45, 85, 128, + 89, 85, 45, 79, 128, 89, 85, 45, 73, 128, 89, 85, 45, 69, 79, 128, 89, + 85, 45, 69, 128, 89, 85, 45, 65, 69, 128, 89, 85, 45, 65, 128, 89, 85, + 45, 52, 128, 89, 85, 45, 51, 128, 89, 85, 45, 50, 128, 89, 85, 45, 49, + 128, 89, 85, 128, 89, 213, 89, 82, 89, 128, 89, 80, 83, 73, 76, 73, 128, + 89, 80, 79, 82, 82, 79, 73, 128, 89, 80, 79, 75, 82, 73, 83, 73, 83, 128, + 89, 80, 79, 75, 82, 73, 83, 73, 211, 89, 80, 79, 71, 69, 71, 82, 65, 77, + 77, 69, 78, 73, 128, 89, 79, 89, 128, 89, 79, 88, 128, 89, 79, 87, 68, + 128, 89, 79, 85, 84, 72, 70, 85, 76, 78, 69, 83, 83, 128, 89, 79, 85, 84, + 72, 70, 85, 204, 89, 79, 213, 89, 79, 84, 128, 89, 79, 212, 89, 79, 82, + 73, 128, 89, 79, 81, 128, 89, 79, 209, 89, 79, 80, 128, 89, 79, 79, 128, + 89, 79, 77, 79, 128, 89, 79, 71, 72, 128, 89, 79, 68, 128, 89, 79, 196, + 89, 79, 65, 128, 89, 79, 45, 89, 79, 128, 89, 79, 45, 89, 69, 79, 128, + 89, 79, 45, 89, 65, 69, 128, 89, 79, 45, 89, 65, 128, 89, 79, 45, 79, + 128, 89, 79, 45, 73, 128, 89, 79, 45, 69, 79, 128, 89, 79, 45, 65, 69, + 128, 89, 79, 45, 65, 128, 89, 79, 45, 54, 128, 89, 79, 45, 53, 128, 89, + 79, 45, 52, 128, 89, 79, 45, 51, 128, 89, 79, 45, 50, 128, 89, 79, 45, + 49, 128, 89, 207, 89, 73, 90, 69, 84, 128, 89, 73, 88, 128, 89, 73, 87, + 78, 128, 89, 73, 84, 128, 89, 73, 80, 128, 89, 73, 78, 71, 128, 89, 73, + 73, 128, 89, 73, 72, 128, 89, 73, 199, 89, 73, 69, 88, 128, 89, 73, 69, + 84, 128, 89, 73, 69, 80, 128, 89, 73, 69, 69, 128, 89, 73, 69, 128, 89, + 73, 68, 68, 73, 83, 200, 89, 73, 45, 85, 128, 89, 73, 128, 89, 72, 69, + 128, 89, 72, 65, 128, 89, 70, 69, 83, 73, 83, 128, 89, 70, 69, 83, 73, + 211, 89, 70, 69, 206, 89, 69, 90, 73, 68, 201, 89, 69, 89, 128, 89, 69, + 87, 128, 89, 69, 85, 88, 128, 89, 69, 85, 82, 65, 69, 128, 89, 69, 85, + 81, 128, 89, 69, 85, 77, 128, 89, 69, 85, 65, 69, 84, 128, 89, 69, 85, + 65, 69, 128, 89, 69, 84, 73, 86, 128, 89, 69, 83, 84, 85, 128, 89, 69, + 83, 73, 69, 85, 78, 71, 45, 83, 83, 65, 78, 71, 75, 73, 89, 69, 79, 75, + 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 83, 73, 79, 83, 128, 89, 69, 83, + 73, 69, 85, 78, 71, 45, 80, 65, 78, 83, 73, 79, 83, 128, 89, 69, 83, 73, + 69, 85, 78, 71, 45, 77, 73, 69, 85, 77, 128, 89, 69, 83, 73, 69, 85, 78, + 71, 45, 75, 73, 89, 69, 79, 75, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, + 75, 72, 73, 69, 85, 75, 72, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 72, + 73, 69, 85, 72, 128, 89, 69, 83, 73, 69, 85, 78, 71, 128, 89, 69, 82, 85, + 128, 89, 69, 82, 213, 89, 69, 82, 73, 128, 89, 69, 82, 65, 200, 89, 69, + 82, 128, 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, 128, 89, 69, 79, 45, + 89, 65, 128, 89, 69, 79, 45, 85, 128, 89, 69, 79, 45, 79, 128, 89, 69, + 78, 73, 83, 69, 201, 89, 69, 78, 65, 80, 128, 89, 69, 78, 128, 89, 69, + 206, 89, 69, 76, 76, 79, 87, 128, 89, 69, 76, 76, 79, 215, 89, 69, 73, + 78, 128, 89, 69, 72, 128, 89, 69, 69, 71, 128, 89, 69, 69, 128, 89, 69, + 65, 210, 89, 69, 65, 128, 89, 65, 90, 90, 128, 89, 65, 90, 72, 128, 89, + 65, 90, 128, 89, 65, 89, 68, 128, 89, 65, 89, 65, 78, 78, 65, 128, 89, + 65, 89, 128, 89, 65, 87, 78, 73, 78, 199, 89, 65, 87, 78, 128, 89, 65, + 87, 128, 89, 65, 86, 128, 89, 65, 85, 128, 89, 65, 84, 84, 128, 89, 65, + 84, 73, 128, 89, 65, 84, 72, 128, 89, 65, 84, 128, 89, 65, 83, 83, 128, + 89, 65, 83, 72, 128, 89, 65, 83, 128, 89, 65, 82, 82, 128, 89, 65, 82, + 78, 128, 89, 65, 82, 128, 89, 65, 210, 89, 65, 81, 128, 89, 65, 80, 128, + 89, 65, 78, 83, 65, 89, 65, 128, 89, 65, 78, 71, 128, 89, 65, 78, 199, + 89, 65, 78, 128, 89, 65, 77, 79, 75, 128, 89, 65, 77, 65, 75, 75, 65, 78, + 128, 89, 65, 77, 128, 89, 65, 76, 128, 89, 65, 75, 72, 72, 128, 89, 65, + 75, 72, 128, 89, 65, 75, 65, 83, 72, 128, 89, 65, 75, 128, 89, 65, 74, + 85, 82, 86, 69, 68, 73, 195, 89, 65, 74, 128, 89, 65, 73, 128, 89, 65, + 72, 72, 128, 89, 65, 72, 128, 89, 65, 71, 78, 128, 89, 65, 71, 72, 72, + 128, 89, 65, 71, 72, 128, 89, 65, 71, 128, 89, 65, 70, 213, 89, 65, 70, + 128, 89, 65, 69, 77, 77, 65, 69, 128, 89, 65, 68, 72, 128, 89, 65, 68, + 68, 72, 128, 89, 65, 68, 68, 128, 89, 65, 68, 128, 89, 65, 67, 72, 128, + 89, 65, 66, 72, 128, 89, 65, 66, 128, 89, 65, 65, 82, 85, 128, 89, 65, + 65, 73, 128, 89, 65, 65, 68, 79, 128, 89, 65, 45, 89, 79, 128, 89, 65, + 45, 85, 128, 89, 65, 45, 79, 128, 89, 65, 45, 53, 128, 89, 65, 45, 52, + 128, 89, 65, 45, 51, 128, 89, 65, 45, 50, 128, 89, 65, 45, 49, 128, 89, + 48, 48, 56, 128, 89, 48, 48, 55, 128, 89, 48, 48, 54, 128, 89, 48, 48, + 53, 128, 89, 48, 48, 52, 128, 89, 48, 48, 51, 128, 89, 48, 48, 50, 128, + 89, 48, 48, 49, 65, 128, 89, 48, 48, 49, 128, 89, 45, 67, 82, 69, 197, + 88, 89, 88, 128, 88, 89, 85, 128, 88, 89, 84, 128, 88, 89, 82, 88, 128, + 88, 89, 82, 128, 88, 89, 80, 128, 88, 89, 79, 79, 74, 128, 88, 89, 79, + 79, 128, 88, 89, 79, 128, 88, 89, 73, 128, 88, 89, 69, 69, 205, 88, 89, + 69, 69, 128, 88, 89, 69, 128, 88, 89, 65, 65, 128, 88, 89, 65, 128, 88, + 89, 128, 88, 87, 73, 128, 88, 87, 69, 69, 128, 88, 87, 69, 128, 88, 87, + 65, 65, 128, 88, 87, 65, 128, 88, 87, 128, 88, 215, 88, 86, 69, 128, 88, + 86, 65, 128, 88, 85, 79, 88, 128, 88, 85, 79, 128, 88, 85, 128, 88, 83, + 72, 65, 65, 89, 65, 84, 72, 73, 89, 65, 128, 88, 79, 88, 128, 88, 79, 84, + 128, 88, 79, 82, 128, 88, 79, 80, 72, 128, 88, 79, 80, 128, 88, 79, 65, + 128, 88, 79, 128, 88, 73, 88, 128, 88, 73, 84, 128, 88, 73, 82, 79, 206, + 88, 73, 80, 128, 88, 73, 69, 88, 128, 88, 73, 69, 84, 128, 88, 73, 69, + 80, 128, 88, 73, 69, 128, 88, 73, 65, 78, 71, 81, 201, 88, 73, 65, 66, + 128, 88, 73, 128, 88, 72, 69, 89, 78, 128, 88, 71, 128, 88, 69, 89, 78, + 128, 88, 69, 83, 84, 69, 211, 88, 69, 72, 128, 88, 69, 69, 128, 88, 69, + 128, 88, 65, 85, 83, 128, 88, 65, 85, 128, 88, 65, 80, 72, 128, 88, 65, + 78, 128, 88, 65, 65, 128, 88, 65, 128, 88, 48, 48, 56, 65, 128, 88, 48, + 48, 56, 128, 88, 48, 48, 55, 128, 88, 48, 48, 54, 65, 128, 88, 48, 48, + 54, 128, 88, 48, 48, 53, 128, 88, 48, 48, 52, 66, 128, 88, 48, 48, 52, + 65, 128, 88, 48, 48, 52, 128, 88, 48, 48, 51, 128, 88, 48, 48, 50, 128, + 88, 48, 48, 49, 128, 88, 45, 216, 88, 45, 82, 65, 89, 128, 87, 90, 128, + 87, 89, 78, 78, 128, 87, 89, 78, 206, 87, 86, 73, 128, 87, 86, 69, 128, + 87, 86, 65, 128, 87, 86, 128, 87, 85, 80, 128, 87, 85, 79, 88, 128, 87, + 85, 79, 80, 128, 87, 85, 79, 128, 87, 85, 78, 74, 207, 87, 85, 78, 128, + 87, 85, 76, 85, 128, 87, 85, 76, 213, 87, 85, 73, 128, 87, 85, 69, 128, + 87, 85, 65, 69, 84, 128, 87, 85, 65, 69, 78, 128, 87, 85, 128, 87, 82, + 217, 87, 82, 79, 78, 71, 128, 87, 82, 73, 83, 212, 87, 82, 73, 78, 75, + 76, 69, 83, 128, 87, 82, 73, 78, 75, 76, 69, 211, 87, 82, 73, 78, 75, 76, + 69, 68, 128, 87, 82, 69, 83, 84, 76, 69, 82, 83, 128, 87, 82, 69, 78, 67, + 72, 128, 87, 82, 69, 65, 84, 200, 87, 82, 65, 80, 80, 69, 196, 87, 82, + 65, 80, 128, 87, 79, 88, 128, 87, 79, 87, 128, 87, 79, 82, 83, 72, 73, + 80, 128, 87, 79, 82, 82, 73, 69, 196, 87, 79, 82, 77, 128, 87, 79, 82, + 76, 196, 87, 79, 82, 75, 69, 82, 128, 87, 79, 82, 75, 128, 87, 79, 82, + 203, 87, 79, 82, 68, 83, 80, 65, 67, 69, 128, 87, 79, 82, 196, 87, 79, + 80, 128, 87, 79, 79, 78, 128, 87, 79, 79, 76, 128, 87, 79, 79, 68, 83, + 45, 67, 82, 69, 197, 87, 79, 79, 68, 128, 87, 79, 78, 128, 87, 79, 206, + 87, 79, 77, 69, 78, 211, 87, 79, 77, 69, 206, 87, 79, 77, 65, 78, 211, + 87, 79, 77, 65, 78, 128, 87, 79, 77, 65, 206, 87, 79, 76, 79, 83, 79, + 128, 87, 79, 76, 198, 87, 79, 69, 128, 87, 79, 65, 128, 87, 79, 45, 55, + 128, 87, 79, 45, 54, 128, 87, 79, 45, 53, 128, 87, 79, 45, 52, 128, 87, + 79, 45, 51, 128, 87, 79, 45, 50, 128, 87, 79, 45, 49, 128, 87, 73, 84, + 72, 79, 85, 212, 87, 73, 84, 72, 73, 78, 128, 87, 73, 84, 72, 73, 206, + 87, 73, 82, 69, 76, 69, 83, 83, 128, 87, 73, 82, 69, 196, 87, 73, 78, 84, + 69, 82, 128, 87, 73, 78, 75, 73, 78, 199, 87, 73, 78, 75, 128, 87, 73, + 78, 74, 65, 128, 87, 73, 78, 71, 83, 128, 87, 73, 78, 71, 128, 87, 73, + 78, 69, 128, 87, 73, 78, 197, 87, 73, 78, 68, 85, 128, 87, 73, 78, 68, + 79, 87, 128, 87, 73, 78, 68, 128, 87, 73, 78, 196, 87, 73, 78, 128, 87, + 73, 76, 84, 69, 196, 87, 73, 71, 78, 89, 65, 78, 128, 87, 73, 71, 71, 76, + 217, 87, 73, 71, 71, 76, 69, 83, 128, 87, 73, 68, 84, 72, 128, 87, 73, + 68, 69, 78, 73, 78, 199, 87, 73, 68, 69, 45, 72, 69, 65, 68, 69, 196, 87, + 73, 68, 197, 87, 73, 65, 78, 71, 87, 65, 65, 75, 128, 87, 73, 65, 78, 71, + 128, 87, 73, 45, 53, 128, 87, 73, 45, 52, 128, 87, 73, 45, 51, 128, 87, + 73, 45, 50, 128, 87, 73, 45, 49, 128, 87, 72, 79, 76, 197, 87, 72, 73, + 84, 69, 45, 70, 69, 65, 84, 72, 69, 82, 69, 196, 87, 72, 73, 84, 69, 128, + 87, 72, 69, 69, 76, 69, 196, 87, 72, 69, 69, 76, 67, 72, 65, 73, 82, 128, + 87, 72, 69, 69, 76, 67, 72, 65, 73, 210, 87, 72, 69, 69, 76, 128, 87, 72, + 69, 69, 204, 87, 72, 69, 65, 84, 128, 87, 72, 65, 76, 69, 128, 87, 72, + 128, 87, 71, 128, 87, 69, 88, 128, 87, 69, 85, 88, 128, 87, 69, 212, 87, + 69, 83, 84, 69, 82, 206, 87, 69, 83, 84, 45, 67, 82, 69, 197, 87, 69, 83, + 84, 128, 87, 69, 83, 212, 87, 69, 80, 128, 87, 69, 79, 128, 87, 69, 78, + 128, 87, 69, 76, 76, 128, 87, 69, 73, 71, 72, 212, 87, 69, 73, 69, 82, + 83, 84, 82, 65, 83, 211, 87, 69, 73, 128, 87, 69, 69, 78, 128, 87, 69, + 68, 71, 69, 45, 84, 65, 73, 76, 69, 196, 87, 69, 68, 71, 69, 128, 87, 69, + 68, 68, 73, 78, 71, 128, 87, 69, 66, 128, 87, 69, 65, 82, 217, 87, 69, + 65, 80, 79, 78, 128, 87, 69, 45, 52, 128, 87, 69, 45, 51, 128, 87, 69, + 45, 50, 128, 87, 69, 45, 49, 128, 87, 67, 128, 87, 66, 128, 87, 65, 89, + 128, 87, 65, 217, 87, 65, 88, 73, 78, 199, 87, 65, 88, 128, 87, 65, 87, + 45, 65, 89, 73, 78, 45, 82, 69, 83, 72, 128, 87, 65, 87, 128, 87, 65, + 215, 87, 65, 86, 217, 87, 65, 86, 73, 78, 199, 87, 65, 86, 69, 83, 128, + 87, 65, 86, 69, 128, 87, 65, 86, 197, 87, 65, 85, 128, 87, 65, 84, 84, + 79, 128, 87, 65, 84, 69, 82, 77, 69, 76, 79, 78, 128, 87, 65, 84, 69, 82, + 128, 87, 65, 84, 69, 210, 87, 65, 84, 67, 72, 128, 87, 65, 84, 128, 87, + 65, 83, 84, 73, 78, 71, 128, 87, 65, 83, 84, 69, 66, 65, 83, 75, 69, 84, + 128, 87, 65, 83, 83, 65, 76, 76, 65, 77, 128, 87, 65, 83, 76, 65, 128, + 87, 65, 83, 76, 193, 87, 65, 83, 65, 76, 76, 65, 77, 128, 87, 65, 83, 65, + 76, 76, 65, 205, 87, 65, 83, 45, 83, 65, 76, 65, 65, 77, 128, 87, 65, 82, + 78, 73, 78, 199, 87, 65, 82, 65, 78, 199, 87, 65, 81, 70, 65, 128, 87, + 65, 80, 128, 87, 65, 78, 73, 78, 199, 87, 65, 78, 71, 75, 85, 79, 81, + 128, 87, 65, 78, 68, 69, 82, 69, 82, 128, 87, 65, 78, 68, 128, 87, 65, + 78, 67, 72, 207, 87, 65, 78, 128, 87, 65, 76, 76, 80, 76, 65, 78, 197, + 87, 65, 76, 76, 69, 196, 87, 65, 76, 76, 128, 87, 65, 76, 204, 87, 65, + 76, 75, 128, 87, 65, 76, 203, 87, 65, 73, 84, 73, 78, 71, 128, 87, 65, + 73, 83, 84, 128, 87, 65, 73, 128, 87, 65, 70, 70, 76, 69, 128, 87, 65, + 69, 78, 128, 87, 65, 69, 128, 87, 65, 68, 68, 65, 128, 87, 65, 65, 86, + 85, 128, 87, 65, 65, 74, 73, 66, 128, 87, 65, 65, 65, 76, 73, 72, 69, + 197, 87, 65, 45, 84, 65, 65, 65, 76, 65, 65, 128, 87, 65, 45, 83, 65, 76, + 76, 65, 77, 128, 87, 65, 45, 65, 65, 76, 73, 72, 128, 87, 65, 45, 53, + 128, 87, 65, 45, 52, 128, 87, 65, 45, 51, 128, 87, 65, 45, 50, 128, 87, + 65, 45, 49, 128, 87, 193, 87, 48, 50, 53, 128, 87, 48, 50, 52, 65, 128, + 87, 48, 50, 52, 128, 87, 48, 50, 51, 128, 87, 48, 50, 50, 128, 87, 48, + 50, 49, 128, 87, 48, 50, 48, 128, 87, 48, 49, 57, 128, 87, 48, 49, 56, + 65, 128, 87, 48, 49, 56, 128, 87, 48, 49, 55, 65, 128, 87, 48, 49, 55, + 128, 87, 48, 49, 54, 128, 87, 48, 49, 53, 128, 87, 48, 49, 52, 65, 128, + 87, 48, 49, 52, 128, 87, 48, 49, 51, 128, 87, 48, 49, 50, 128, 87, 48, + 49, 49, 128, 87, 48, 49, 48, 65, 128, 87, 48, 49, 48, 128, 87, 48, 48, + 57, 65, 128, 87, 48, 48, 57, 128, 87, 48, 48, 56, 128, 87, 48, 48, 55, + 128, 87, 48, 48, 54, 128, 87, 48, 48, 53, 128, 87, 48, 48, 52, 128, 87, + 48, 48, 51, 65, 128, 87, 48, 48, 51, 128, 87, 48, 48, 50, 128, 87, 48, + 48, 49, 128, 86, 90, 77, 69, 84, 128, 86, 90, 128, 86, 89, 88, 128, 86, + 89, 84, 128, 86, 89, 83, 79, 75, 79, 128, 86, 89, 83, 79, 75, 207, 86, + 89, 82, 88, 128, 86, 89, 82, 128, 86, 89, 80, 128, 86, 89, 128, 86, 88, + 128, 86, 87, 74, 128, 86, 87, 65, 128, 86, 87, 128, 86, 85, 88, 128, 86, + 85, 85, 128, 86, 85, 84, 128, 86, 85, 82, 88, 128, 86, 85, 82, 128, 86, + 85, 80, 128, 86, 85, 76, 71, 65, 210, 86, 85, 76, 67, 65, 78, 85, 83, + 128, 86, 85, 69, 81, 128, 86, 84, 83, 128, 86, 84, 128, 86, 83, 57, 57, + 128, 86, 83, 57, 56, 128, 86, 83, 57, 55, 128, 86, 83, 57, 54, 128, 86, + 83, 57, 53, 128, 86, 83, 57, 52, 128, 86, 83, 57, 51, 128, 86, 83, 57, + 50, 128, 86, 83, 57, 49, 128, 86, 83, 57, 48, 128, 86, 83, 57, 128, 86, + 83, 56, 57, 128, 86, 83, 56, 56, 128, 86, 83, 56, 55, 128, 86, 83, 56, + 54, 128, 86, 83, 56, 53, 128, 86, 83, 56, 52, 128, 86, 83, 56, 51, 128, + 86, 83, 56, 50, 128, 86, 83, 56, 49, 128, 86, 83, 56, 48, 128, 86, 83, + 56, 128, 86, 83, 55, 57, 128, 86, 83, 55, 56, 128, 86, 83, 55, 55, 128, + 86, 83, 55, 54, 128, 86, 83, 55, 53, 128, 86, 83, 55, 52, 128, 86, 83, + 55, 51, 128, 86, 83, 55, 50, 128, 86, 83, 55, 49, 128, 86, 83, 55, 48, + 128, 86, 83, 55, 128, 86, 83, 54, 57, 128, 86, 83, 54, 56, 128, 86, 83, + 54, 55, 128, 86, 83, 54, 54, 128, 86, 83, 54, 53, 128, 86, 83, 54, 52, + 128, 86, 83, 54, 51, 128, 86, 83, 54, 50, 128, 86, 83, 54, 49, 128, 86, + 83, 54, 48, 128, 86, 83, 54, 128, 86, 83, 53, 57, 128, 86, 83, 53, 56, + 128, 86, 83, 53, 55, 128, 86, 83, 53, 54, 128, 86, 83, 53, 53, 128, 86, + 83, 53, 52, 128, 86, 83, 53, 51, 128, 86, 83, 53, 50, 128, 86, 83, 53, + 49, 128, 86, 83, 53, 48, 128, 86, 83, 53, 128, 86, 83, 52, 57, 128, 86, + 83, 52, 56, 128, 86, 83, 52, 55, 128, 86, 83, 52, 54, 128, 86, 83, 52, + 53, 128, 86, 83, 52, 52, 128, 86, 83, 52, 51, 128, 86, 83, 52, 50, 128, + 86, 83, 52, 49, 128, 86, 83, 52, 48, 128, 86, 83, 52, 128, 86, 83, 51, + 57, 128, 86, 83, 51, 56, 128, 86, 83, 51, 55, 128, 86, 83, 51, 54, 128, + 86, 83, 51, 53, 128, 86, 83, 51, 52, 128, 86, 83, 51, 51, 128, 86, 83, + 51, 50, 128, 86, 83, 51, 49, 128, 86, 83, 51, 48, 128, 86, 83, 51, 128, + 86, 83, 50, 57, 128, 86, 83, 50, 56, 128, 86, 83, 50, 55, 128, 86, 83, + 50, 54, 128, 86, 83, 50, 53, 54, 128, 86, 83, 50, 53, 53, 128, 86, 83, + 50, 53, 52, 128, 86, 83, 50, 53, 51, 128, 86, 83, 50, 53, 50, 128, 86, + 83, 50, 53, 49, 128, 86, 83, 50, 53, 48, 128, 86, 83, 50, 53, 128, 86, + 83, 50, 52, 57, 128, 86, 83, 50, 52, 56, 128, 86, 83, 50, 52, 55, 128, + 86, 83, 50, 52, 54, 128, 86, 83, 50, 52, 53, 128, 86, 83, 50, 52, 52, + 128, 86, 83, 50, 52, 51, 128, 86, 83, 50, 52, 50, 128, 86, 83, 50, 52, + 49, 128, 86, 83, 50, 52, 48, 128, 86, 83, 50, 52, 128, 86, 83, 50, 51, + 57, 128, 86, 83, 50, 51, 56, 128, 86, 83, 50, 51, 55, 128, 86, 83, 50, + 51, 54, 128, 86, 83, 50, 51, 53, 128, 86, 83, 50, 51, 52, 128, 86, 83, + 50, 51, 51, 128, 86, 83, 50, 51, 50, 128, 86, 83, 50, 51, 49, 128, 86, + 83, 50, 51, 48, 128, 86, 83, 50, 51, 128, 86, 83, 50, 50, 57, 128, 86, + 83, 50, 50, 56, 128, 86, 83, 50, 50, 55, 128, 86, 83, 50, 50, 54, 128, + 86, 83, 50, 50, 53, 128, 86, 83, 50, 50, 52, 128, 86, 83, 50, 50, 51, + 128, 86, 83, 50, 50, 50, 128, 86, 83, 50, 50, 49, 128, 86, 83, 50, 50, + 48, 128, 86, 83, 50, 50, 128, 86, 83, 50, 49, 57, 128, 86, 83, 50, 49, + 56, 128, 86, 83, 50, 49, 55, 128, 86, 83, 50, 49, 54, 128, 86, 83, 50, + 49, 53, 128, 86, 83, 50, 49, 52, 128, 86, 83, 50, 49, 51, 128, 86, 83, + 50, 49, 50, 128, 86, 83, 50, 49, 49, 128, 86, 83, 50, 49, 48, 128, 86, + 83, 50, 49, 128, 86, 83, 50, 48, 57, 128, 86, 83, 50, 48, 56, 128, 86, + 83, 50, 48, 55, 128, 86, 83, 50, 48, 54, 128, 86, 83, 50, 48, 53, 128, + 86, 83, 50, 48, 52, 128, 86, 83, 50, 48, 51, 128, 86, 83, 50, 48, 50, + 128, 86, 83, 50, 48, 49, 128, 86, 83, 50, 48, 48, 128, 86, 83, 50, 48, + 128, 86, 83, 50, 128, 86, 83, 49, 57, 57, 128, 86, 83, 49, 57, 56, 128, + 86, 83, 49, 57, 55, 128, 86, 83, 49, 57, 54, 128, 86, 83, 49, 57, 53, + 128, 86, 83, 49, 57, 52, 128, 86, 83, 49, 57, 51, 128, 86, 83, 49, 57, + 50, 128, 86, 83, 49, 57, 49, 128, 86, 83, 49, 57, 48, 128, 86, 83, 49, + 57, 128, 86, 83, 49, 56, 57, 128, 86, 83, 49, 56, 56, 128, 86, 83, 49, + 56, 55, 128, 86, 83, 49, 56, 54, 128, 86, 83, 49, 56, 53, 128, 86, 83, + 49, 56, 52, 128, 86, 83, 49, 56, 51, 128, 86, 83, 49, 56, 50, 128, 86, + 83, 49, 56, 49, 128, 86, 83, 49, 56, 48, 128, 86, 83, 49, 56, 128, 86, + 83, 49, 55, 57, 128, 86, 83, 49, 55, 56, 128, 86, 83, 49, 55, 55, 128, + 86, 83, 49, 55, 54, 128, 86, 83, 49, 55, 53, 128, 86, 83, 49, 55, 52, + 128, 86, 83, 49, 55, 51, 128, 86, 83, 49, 55, 50, 128, 86, 83, 49, 55, + 49, 128, 86, 83, 49, 55, 48, 128, 86, 83, 49, 55, 128, 86, 83, 49, 54, + 57, 128, 86, 83, 49, 54, 56, 128, 86, 83, 49, 54, 55, 128, 86, 83, 49, + 54, 54, 128, 86, 83, 49, 54, 53, 128, 86, 83, 49, 54, 52, 128, 86, 83, + 49, 54, 51, 128, 86, 83, 49, 54, 50, 128, 86, 83, 49, 54, 49, 128, 86, + 83, 49, 54, 48, 128, 86, 83, 49, 54, 128, 86, 83, 49, 53, 57, 128, 86, + 83, 49, 53, 56, 128, 86, 83, 49, 53, 55, 128, 86, 83, 49, 53, 54, 128, + 86, 83, 49, 53, 53, 128, 86, 83, 49, 53, 52, 128, 86, 83, 49, 53, 51, + 128, 86, 83, 49, 53, 50, 128, 86, 83, 49, 53, 49, 128, 86, 83, 49, 53, + 48, 128, 86, 83, 49, 53, 128, 86, 83, 49, 52, 57, 128, 86, 83, 49, 52, + 56, 128, 86, 83, 49, 52, 55, 128, 86, 83, 49, 52, 54, 128, 86, 83, 49, + 52, 53, 128, 86, 83, 49, 52, 52, 128, 86, 83, 49, 52, 51, 128, 86, 83, + 49, 52, 50, 128, 86, 83, 49, 52, 49, 128, 86, 83, 49, 52, 48, 128, 86, + 83, 49, 52, 128, 86, 83, 49, 51, 57, 128, 86, 83, 49, 51, 56, 128, 86, + 83, 49, 51, 55, 128, 86, 83, 49, 51, 54, 128, 86, 83, 49, 51, 53, 128, + 86, 83, 49, 51, 52, 128, 86, 83, 49, 51, 51, 128, 86, 83, 49, 51, 50, + 128, 86, 83, 49, 51, 49, 128, 86, 83, 49, 51, 48, 128, 86, 83, 49, 51, + 128, 86, 83, 49, 50, 57, 128, 86, 83, 49, 50, 56, 128, 86, 83, 49, 50, + 55, 128, 86, 83, 49, 50, 54, 128, 86, 83, 49, 50, 53, 128, 86, 83, 49, + 50, 52, 128, 86, 83, 49, 50, 51, 128, 86, 83, 49, 50, 50, 128, 86, 83, + 49, 50, 49, 128, 86, 83, 49, 50, 48, 128, 86, 83, 49, 50, 128, 86, 83, + 49, 49, 57, 128, 86, 83, 49, 49, 56, 128, 86, 83, 49, 49, 55, 128, 86, + 83, 49, 49, 54, 128, 86, 83, 49, 49, 53, 128, 86, 83, 49, 49, 52, 128, + 86, 83, 49, 49, 51, 128, 86, 83, 49, 49, 50, 128, 86, 83, 49, 49, 49, + 128, 86, 83, 49, 49, 48, 128, 86, 83, 49, 49, 128, 86, 83, 49, 48, 57, + 128, 86, 83, 49, 48, 56, 128, 86, 83, 49, 48, 55, 128, 86, 83, 49, 48, + 54, 128, 86, 83, 49, 48, 53, 128, 86, 83, 49, 48, 52, 128, 86, 83, 49, + 48, 51, 128, 86, 83, 49, 48, 50, 128, 86, 83, 49, 48, 49, 128, 86, 83, + 49, 48, 48, 128, 86, 83, 49, 48, 128, 86, 83, 49, 128, 86, 83, 128, 86, + 82, 65, 75, 72, 73, 89, 193, 86, 82, 65, 67, 72, 89, 128, 86, 81, 128, + 86, 79, 88, 128, 86, 79, 87, 69, 76, 45, 67, 65, 82, 82, 73, 69, 210, 86, + 79, 87, 128, 86, 79, 85, 128, 86, 79, 84, 128, 86, 79, 211, 86, 79, 80, + 128, 86, 79, 79, 73, 128, 86, 79, 79, 128, 86, 79, 77, 73, 84, 73, 78, + 71, 128, 86, 79, 77, 128, 86, 79, 76, 85, 77, 197, 86, 79, 76, 84, 65, + 71, 197, 86, 79, 76, 76, 69, 89, 66, 65, 76, 76, 128, 86, 79, 76, 67, 65, + 78, 79, 128, 86, 79, 76, 65, 80, 85, 203, 86, 79, 73, 68, 69, 196, 86, + 79, 73, 196, 86, 79, 73, 67, 73, 78, 71, 128, 86, 79, 73, 67, 69, 76, 69, + 83, 211, 86, 79, 73, 67, 69, 196, 86, 79, 68, 128, 86, 79, 67, 65, 76, + 73, 90, 65, 84, 73, 79, 206, 86, 79, 67, 65, 204, 86, 79, 128, 86, 73, + 89, 79, 128, 86, 73, 88, 128, 86, 73, 84, 82, 73, 79, 76, 45, 50, 128, + 86, 73, 84, 82, 73, 79, 76, 128, 86, 73, 84, 72, 75, 85, 81, 201, 86, 73, + 84, 65, 69, 45, 50, 128, 86, 73, 84, 65, 69, 128, 86, 73, 84, 128, 86, + 73, 83, 73, 71, 79, 84, 72, 73, 195, 86, 73, 83, 65, 82, 71, 65, 89, 65, + 128, 86, 73, 83, 65, 82, 71, 65, 128, 86, 73, 83, 65, 82, 71, 193, 86, + 73, 82, 73, 65, 77, 128, 86, 73, 82, 71, 79, 128, 86, 73, 82, 71, 65, + 128, 86, 73, 82, 65, 77, 65, 128, 86, 73, 80, 128, 86, 73, 79, 76, 73, + 78, 128, 86, 73, 78, 69, 71, 65, 82, 45, 51, 128, 86, 73, 78, 69, 71, 65, + 82, 45, 50, 128, 86, 73, 78, 69, 71, 65, 82, 128, 86, 73, 78, 69, 71, 65, + 210, 86, 73, 78, 69, 128, 86, 73, 78, 197, 86, 73, 78, 128, 86, 73, 76, + 76, 65, 71, 69, 128, 86, 73, 73, 128, 86, 73, 71, 73, 78, 84, 73, 76, 69, + 128, 86, 73, 69, 88, 128, 86, 73, 69, 87, 73, 78, 199, 86, 73, 69, 87, + 69, 82, 128, 86, 73, 69, 87, 68, 65, 84, 193, 86, 73, 69, 84, 78, 65, 77, + 69, 83, 197, 86, 73, 69, 84, 128, 86, 73, 69, 212, 86, 73, 69, 80, 128, + 86, 73, 69, 128, 86, 73, 68, 74, 45, 50, 128, 86, 73, 68, 74, 128, 86, + 73, 68, 69, 79, 67, 65, 83, 83, 69, 84, 84, 69, 128, 86, 73, 68, 69, 207, + 86, 73, 68, 65, 128, 86, 73, 67, 84, 79, 82, 217, 86, 73, 66, 82, 65, 84, + 73, 79, 206, 86, 72, 65, 128, 86, 70, 65, 128, 86, 69, 89, 90, 128, 86, + 69, 88, 128, 86, 69, 87, 128, 86, 69, 215, 86, 69, 85, 88, 128, 86, 69, + 85, 77, 128, 86, 69, 85, 65, 69, 80, 69, 78, 128, 86, 69, 85, 65, 69, + 128, 86, 69, 83, 84, 65, 128, 86, 69, 83, 84, 128, 86, 69, 83, 83, 69, + 204, 86, 69, 82, 217, 86, 69, 82, 84, 73, 67, 65, 76, 76, 89, 128, 86, + 69, 82, 84, 73, 67, 65, 76, 76, 217, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 54, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, + 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 52, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 51, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 54, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 54, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, + 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 53, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 52, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 53, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 53, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, + 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 54, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 53, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 52, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 52, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, + 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 48, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 54, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 51, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 51, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, + 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 49, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 48, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 50, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 50, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, + 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 50, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 49, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 49, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 49, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, + 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 51, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 50, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 49, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 48, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, + 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 52, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 51, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 48, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 48, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 128, 86, 69, 82, + 83, 73, 67, 76, 69, 128, 86, 69, 82, 83, 197, 86, 69, 82, 71, 69, 128, + 86, 69, 82, 68, 73, 71, 82, 73, 83, 128, 86, 69, 82, 128, 86, 69, 80, + 128, 86, 69, 78, 68, 128, 86, 69, 76, 73, 128, 86, 69, 73, 76, 128, 86, + 69, 72, 73, 67, 76, 69, 128, 86, 69, 72, 128, 86, 69, 200, 86, 69, 69, + 128, 86, 69, 197, 86, 69, 68, 69, 128, 86, 69, 67, 84, 79, 210, 86, 67, + 128, 86, 65, 89, 65, 78, 78, 65, 128, 86, 65, 88, 128, 86, 65, 86, 128, + 86, 65, 214, 86, 65, 85, 128, 86, 65, 84, 72, 89, 128, 86, 65, 84, 128, + 86, 65, 83, 84, 78, 69, 83, 211, 86, 65, 83, 73, 83, 128, 86, 65, 82, 89, + 211, 86, 65, 82, 73, 75, 65, 128, 86, 65, 82, 73, 65, 78, 84, 128, 86, + 65, 82, 73, 65, 78, 212, 86, 65, 82, 73, 65, 128, 86, 65, 82, 73, 193, + 86, 65, 82, 69, 73, 65, 201, 86, 65, 82, 69, 73, 193, 86, 65, 82, 65, 65, + 75, 65, 78, 128, 86, 65, 80, 79, 85, 82, 83, 128, 86, 65, 80, 128, 86, + 65, 78, 69, 128, 86, 65, 77, 80, 73, 82, 69, 128, 86, 65, 77, 65, 71, 79, + 77, 85, 75, 72, 65, 128, 86, 65, 77, 65, 71, 79, 77, 85, 75, 72, 193, 86, + 65, 76, 76, 69, 89, 128, 86, 65, 75, 65, 73, 89, 65, 82, 65, 65, 128, 86, + 65, 74, 128, 86, 65, 73, 128, 86, 65, 72, 128, 86, 65, 200, 86, 65, 65, + 86, 85, 128, 86, 65, 65, 128, 86, 193, 86, 48, 52, 48, 65, 128, 86, 48, + 52, 48, 128, 86, 48, 51, 57, 128, 86, 48, 51, 56, 128, 86, 48, 51, 55, + 65, 128, 86, 48, 51, 55, 128, 86, 48, 51, 54, 128, 86, 48, 51, 53, 128, + 86, 48, 51, 52, 128, 86, 48, 51, 51, 65, 128, 86, 48, 51, 51, 128, 86, + 48, 51, 50, 128, 86, 48, 51, 49, 65, 128, 86, 48, 51, 49, 128, 86, 48, + 51, 48, 65, 128, 86, 48, 51, 48, 128, 86, 48, 50, 57, 65, 128, 86, 48, + 50, 57, 128, 86, 48, 50, 56, 65, 128, 86, 48, 50, 56, 128, 86, 48, 50, + 55, 128, 86, 48, 50, 54, 128, 86, 48, 50, 53, 128, 86, 48, 50, 52, 128, + 86, 48, 50, 51, 65, 128, 86, 48, 50, 51, 128, 86, 48, 50, 50, 128, 86, + 48, 50, 49, 128, 86, 48, 50, 48, 76, 128, 86, 48, 50, 48, 75, 128, 86, + 48, 50, 48, 74, 128, 86, 48, 50, 48, 73, 128, 86, 48, 50, 48, 72, 128, + 86, 48, 50, 48, 71, 128, 86, 48, 50, 48, 70, 128, 86, 48, 50, 48, 69, + 128, 86, 48, 50, 48, 68, 128, 86, 48, 50, 48, 67, 128, 86, 48, 50, 48, + 66, 128, 86, 48, 50, 48, 65, 128, 86, 48, 50, 48, 128, 86, 48, 49, 57, + 128, 86, 48, 49, 56, 128, 86, 48, 49, 55, 128, 86, 48, 49, 54, 128, 86, + 48, 49, 53, 128, 86, 48, 49, 52, 128, 86, 48, 49, 51, 128, 86, 48, 49, + 50, 66, 128, 86, 48, 49, 50, 65, 128, 86, 48, 49, 50, 128, 86, 48, 49, + 49, 68, 128, 86, 48, 49, 49, 67, 128, 86, 48, 49, 49, 66, 128, 86, 48, + 49, 49, 65, 128, 86, 48, 49, 49, 128, 86, 48, 49, 48, 128, 86, 48, 48, + 57, 128, 86, 48, 48, 56, 128, 86, 48, 48, 55, 66, 128, 86, 48, 48, 55, + 65, 128, 86, 48, 48, 55, 128, 86, 48, 48, 54, 128, 86, 48, 48, 53, 128, + 86, 48, 48, 52, 128, 86, 48, 48, 51, 128, 86, 48, 48, 50, 65, 128, 86, + 48, 48, 50, 128, 86, 48, 48, 49, 73, 128, 86, 48, 48, 49, 72, 128, 86, + 48, 48, 49, 71, 128, 86, 48, 48, 49, 70, 128, 86, 48, 48, 49, 69, 128, + 86, 48, 48, 49, 68, 128, 86, 48, 48, 49, 67, 128, 86, 48, 48, 49, 66, + 128, 86, 48, 48, 49, 65, 128, 86, 48, 48, 49, 128, 85, 90, 85, 128, 85, + 90, 72, 65, 75, 75, 85, 128, 85, 90, 51, 128, 85, 90, 179, 85, 90, 128, + 85, 89, 71, 72, 85, 210, 85, 89, 65, 78, 78, 65, 128, 85, 89, 128, 85, + 87, 85, 128, 85, 85, 89, 65, 78, 78, 65, 128, 85, 85, 85, 85, 128, 85, + 85, 85, 51, 128, 85, 85, 85, 50, 128, 85, 85, 69, 128, 85, 84, 85, 75, + 73, 128, 85, 83, 83, 85, 51, 128, 85, 83, 83, 85, 128, 85, 83, 72, 88, + 128, 85, 83, 72, 85, 77, 88, 128, 85, 83, 72, 69, 78, 78, 65, 128, 85, + 83, 72, 50, 128, 85, 83, 72, 128, 85, 83, 200, 85, 83, 69, 196, 85, 83, + 69, 45, 50, 128, 85, 83, 69, 45, 49, 128, 85, 83, 69, 128, 85, 83, 197, + 85, 82, 85, 218, 85, 82, 85, 83, 128, 85, 82, 85, 68, 65, 128, 85, 82, + 85, 68, 193, 85, 82, 85, 128, 85, 82, 213, 85, 82, 78, 128, 85, 82, 73, + 78, 69, 128, 85, 82, 73, 51, 128, 85, 82, 73, 128, 85, 82, 65, 78, 85, + 83, 128, 85, 82, 65, 128, 85, 82, 52, 128, 85, 82, 50, 128, 85, 82, 178, + 85, 80, 87, 65, 82, 68, 83, 128, 85, 80, 87, 65, 82, 68, 211, 85, 80, 87, + 65, 82, 68, 128, 85, 80, 87, 65, 82, 196, 85, 80, 84, 85, 82, 78, 128, + 85, 80, 83, 73, 76, 79, 78, 128, 85, 80, 83, 73, 76, 79, 206, 85, 80, 83, + 73, 68, 69, 45, 68, 79, 87, 206, 85, 80, 82, 73, 71, 72, 212, 85, 80, 80, + 69, 82, 128, 85, 80, 65, 68, 72, 77, 65, 78, 73, 89, 65, 128, 85, 80, 45, + 80, 79, 73, 78, 84, 73, 78, 199, 85, 79, 78, 128, 85, 79, 71, 128, 85, + 78, 78, 128, 85, 78, 77, 65, 82, 82, 73, 69, 196, 85, 78, 75, 78, 79, 87, + 78, 128, 85, 78, 75, 128, 85, 78, 73, 86, 69, 82, 83, 65, 204, 85, 78, + 73, 84, 89, 128, 85, 78, 73, 84, 69, 196, 85, 78, 73, 84, 128, 85, 78, + 73, 212, 85, 78, 73, 79, 78, 128, 85, 78, 73, 79, 206, 85, 78, 73, 70, + 79, 82, 77, 128, 85, 78, 73, 70, 73, 69, 196, 85, 78, 73, 67, 79, 82, + 206, 85, 78, 69, 86, 69, 206, 85, 78, 68, 207, 85, 78, 68, 69, 82, 84, + 73, 69, 128, 85, 78, 68, 69, 82, 76, 73, 78, 197, 85, 78, 68, 69, 82, 68, + 79, 84, 128, 85, 78, 68, 69, 82, 66, 65, 82, 128, 85, 78, 68, 69, 82, + 128, 85, 78, 68, 69, 210, 85, 78, 67, 73, 193, 85, 78, 67, 69, 82, 84, + 65, 73, 78, 84, 217, 85, 78, 66, 76, 69, 78, 68, 69, 196, 85, 78, 65, 83, + 80, 73, 82, 65, 84, 69, 68, 128, 85, 78, 65, 80, 128, 85, 78, 65, 77, 85, + 83, 69, 196, 85, 78, 65, 128, 85, 206, 85, 77, 85, 77, 128, 85, 77, 85, + 205, 85, 77, 66, 82, 69, 76, 76, 65, 128, 85, 77, 66, 82, 69, 76, 76, + 193, 85, 77, 66, 73, 78, 128, 85, 75, 85, 128, 85, 75, 82, 65, 73, 78, + 73, 65, 206, 85, 75, 65, 82, 65, 128, 85, 75, 65, 82, 193, 85, 75, 128, + 85, 73, 90, 128, 85, 73, 88, 128, 85, 73, 85, 90, 128, 85, 73, 85, 88, + 128, 85, 73, 85, 81, 128, 85, 73, 85, 67, 128, 85, 73, 81, 128, 85, 73, + 76, 76, 69, 65, 78, 78, 128, 85, 73, 71, 72, 85, 210, 85, 73, 67, 128, + 85, 72, 68, 128, 85, 71, 65, 82, 73, 84, 73, 195, 85, 69, 90, 128, 85, + 69, 89, 128, 85, 69, 88, 128, 85, 69, 78, 128, 85, 69, 73, 128, 85, 69, + 69, 128, 85, 69, 67, 128, 85, 69, 65, 128, 85, 68, 85, 71, 128, 85, 68, + 65, 84, 84, 65, 128, 85, 68, 65, 84, 84, 193, 85, 68, 65, 82, 75, 65, + 128, 85, 68, 65, 65, 84, 128, 85, 68, 128, 85, 196, 85, 66, 85, 70, 73, + 76, 73, 128, 85, 66, 72, 65, 89, 65, 84, 207, 85, 66, 65, 68, 65, 77, 65, + 128, 85, 66, 128, 85, 65, 84, 72, 128, 85, 65, 78, 71, 128, 85, 65, 128, + 85, 178, 85, 48, 52, 50, 128, 85, 48, 52, 49, 128, 85, 48, 52, 48, 128, + 85, 48, 51, 57, 128, 85, 48, 51, 56, 128, 85, 48, 51, 55, 128, 85, 48, + 51, 54, 128, 85, 48, 51, 53, 128, 85, 48, 51, 52, 128, 85, 48, 51, 51, + 128, 85, 48, 51, 50, 65, 128, 85, 48, 51, 50, 128, 85, 48, 51, 49, 128, + 85, 48, 51, 48, 128, 85, 48, 50, 57, 65, 128, 85, 48, 50, 57, 128, 85, + 48, 50, 56, 128, 85, 48, 50, 55, 128, 85, 48, 50, 54, 128, 85, 48, 50, + 53, 128, 85, 48, 50, 52, 128, 85, 48, 50, 51, 65, 128, 85, 48, 50, 51, + 128, 85, 48, 50, 50, 128, 85, 48, 50, 49, 128, 85, 48, 50, 48, 128, 85, + 48, 49, 57, 128, 85, 48, 49, 56, 128, 85, 48, 49, 55, 128, 85, 48, 49, + 54, 128, 85, 48, 49, 53, 128, 85, 48, 49, 52, 128, 85, 48, 49, 51, 128, + 85, 48, 49, 50, 128, 85, 48, 49, 49, 128, 85, 48, 49, 48, 128, 85, 48, + 48, 57, 128, 85, 48, 48, 56, 128, 85, 48, 48, 55, 128, 85, 48, 48, 54, + 66, 128, 85, 48, 48, 54, 65, 128, 85, 48, 48, 54, 128, 85, 48, 48, 53, + 128, 85, 48, 48, 52, 128, 85, 48, 48, 51, 128, 85, 48, 48, 50, 128, 85, + 48, 48, 49, 128, 85, 45, 83, 72, 65, 80, 69, 196, 85, 45, 73, 45, 73, + 128, 85, 45, 69, 79, 45, 69, 85, 128, 85, 45, 66, 82, 74, 71, 85, 128, + 85, 45, 53, 128, 84, 90, 85, 128, 84, 90, 79, 65, 128, 84, 90, 79, 128, + 84, 90, 73, 210, 84, 90, 73, 128, 84, 90, 69, 69, 128, 84, 90, 69, 128, + 84, 90, 65, 65, 128, 84, 90, 65, 128, 84, 90, 128, 84, 89, 210, 84, 89, + 80, 69, 45, 183, 84, 89, 80, 69, 45, 54, 128, 84, 89, 80, 69, 45, 182, + 84, 89, 80, 69, 45, 53, 128, 84, 89, 80, 69, 45, 181, 84, 89, 80, 69, 45, + 52, 128, 84, 89, 80, 69, 45, 180, 84, 89, 80, 69, 45, 51, 128, 84, 89, + 80, 69, 45, 179, 84, 89, 80, 69, 45, 178, 84, 89, 80, 69, 45, 49, 45, 50, + 128, 84, 89, 80, 69, 45, 177, 84, 89, 80, 197, 84, 89, 79, 128, 84, 89, + 73, 128, 84, 89, 69, 128, 84, 89, 65, 89, 128, 84, 89, 65, 128, 84, 88, + 87, 86, 128, 84, 88, 87, 214, 84, 88, 72, 69, 69, 202, 84, 88, 65, 128, + 84, 87, 79, 79, 128, 84, 87, 79, 45, 87, 65, 217, 84, 87, 79, 45, 84, 72, + 73, 82, 84, 89, 128, 84, 87, 79, 45, 76, 73, 78, 197, 84, 87, 79, 45, 72, + 69, 65, 68, 69, 196, 84, 87, 79, 45, 69, 205, 84, 87, 79, 45, 67, 73, 82, + 67, 76, 197, 84, 87, 73, 83, 84, 73, 78, 71, 128, 84, 87, 73, 83, 84, 69, + 196, 84, 87, 73, 73, 128, 84, 87, 73, 128, 84, 87, 69, 78, 84, 89, 45, + 84, 87, 79, 128, 84, 87, 69, 78, 84, 89, 45, 84, 87, 207, 84, 87, 69, 78, + 84, 89, 45, 84, 72, 82, 69, 69, 128, 84, 87, 69, 78, 84, 89, 45, 83, 73, + 88, 128, 84, 87, 69, 78, 84, 89, 45, 83, 69, 86, 69, 78, 128, 84, 87, 69, + 78, 84, 89, 45, 79, 78, 69, 128, 84, 87, 69, 78, 84, 89, 45, 78, 73, 78, + 69, 128, 84, 87, 69, 78, 84, 89, 45, 70, 79, 85, 82, 128, 84, 87, 69, 78, + 84, 89, 45, 70, 73, 86, 69, 128, 84, 87, 69, 78, 84, 89, 45, 70, 73, 86, + 197, 84, 87, 69, 78, 84, 89, 45, 69, 73, 71, 72, 84, 200, 84, 87, 69, 78, + 84, 89, 45, 69, 73, 71, 72, 84, 128, 84, 87, 69, 78, 84, 89, 128, 84, 87, + 69, 78, 84, 217, 84, 87, 69, 78, 84, 73, 69, 84, 72, 83, 128, 84, 87, 69, + 78, 84, 73, 69, 84, 72, 128, 84, 87, 69, 76, 86, 69, 45, 84, 72, 73, 82, + 84, 89, 128, 84, 87, 69, 76, 86, 69, 128, 84, 87, 69, 76, 86, 197, 84, + 87, 69, 76, 70, 84, 72, 83, 128, 84, 87, 69, 76, 70, 84, 72, 128, 84, 87, + 69, 128, 84, 87, 65, 65, 128, 84, 87, 65, 128, 84, 86, 82, 73, 68, 79, + 128, 84, 86, 73, 77, 65, 68, 85, 210, 84, 85, 88, 69, 68, 79, 128, 84, + 85, 88, 128, 84, 85, 85, 77, 85, 128, 84, 85, 85, 128, 84, 85, 84, 84, + 89, 128, 84, 85, 84, 69, 89, 65, 83, 65, 84, 128, 84, 85, 84, 128, 84, + 85, 82, 88, 128, 84, 85, 82, 85, 128, 84, 85, 82, 84, 76, 69, 128, 84, + 85, 82, 79, 50, 128, 84, 85, 82, 78, 83, 84, 73, 76, 69, 128, 84, 85, 82, + 206, 84, 85, 82, 75, 73, 83, 200, 84, 85, 82, 75, 73, 195, 84, 85, 82, + 75, 69, 89, 128, 84, 85, 82, 66, 65, 78, 128, 84, 85, 82, 128, 84, 85, + 210, 84, 85, 80, 78, 73, 128, 84, 85, 80, 128, 84, 85, 79, 88, 128, 84, + 85, 79, 84, 128, 84, 85, 79, 80, 128, 84, 85, 79, 128, 84, 85, 78, 78, + 89, 128, 84, 85, 77, 69, 84, 69, 83, 128, 84, 85, 77, 66, 76, 69, 210, + 84, 85, 77, 65, 69, 128, 84, 85, 77, 128, 84, 85, 205, 84, 85, 76, 73, + 80, 128, 84, 85, 75, 87, 69, 78, 84, 73, 83, 128, 84, 85, 75, 128, 84, + 85, 71, 82, 73, 203, 84, 85, 71, 50, 128, 84, 85, 71, 178, 84, 85, 66, + 69, 128, 84, 85, 66, 128, 84, 85, 65, 82, 69, 199, 84, 85, 65, 69, 80, + 128, 84, 85, 65, 69, 128, 84, 85, 45, 84, 79, 128, 84, 85, 45, 52, 128, + 84, 85, 45, 51, 128, 84, 85, 45, 50, 128, 84, 85, 45, 49, 128, 84, 213, + 84, 84, 85, 85, 128, 84, 84, 85, 68, 68, 65, 71, 128, 84, 84, 85, 68, 68, + 65, 65, 71, 128, 84, 84, 85, 128, 84, 84, 84, 72, 65, 128, 84, 84, 84, + 65, 128, 84, 84, 83, 85, 128, 84, 84, 83, 79, 128, 84, 84, 83, 73, 128, + 84, 84, 83, 69, 69, 128, 84, 84, 83, 69, 128, 84, 84, 83, 65, 128, 84, + 84, 79, 79, 128, 84, 84, 73, 73, 128, 84, 84, 73, 128, 84, 84, 72, 87, + 69, 128, 84, 84, 72, 85, 128, 84, 84, 72, 79, 79, 128, 84, 84, 72, 79, + 128, 84, 84, 72, 73, 128, 84, 84, 72, 69, 69, 128, 84, 84, 72, 69, 128, + 84, 84, 72, 65, 65, 128, 84, 84, 72, 128, 84, 84, 69, 72, 69, 72, 128, + 84, 84, 69, 72, 69, 200, 84, 84, 69, 72, 128, 84, 84, 69, 200, 84, 84, + 69, 69, 128, 84, 84, 65, 89, 65, 78, 78, 65, 128, 84, 84, 65, 85, 128, + 84, 84, 65, 73, 128, 84, 84, 65, 65, 128, 84, 84, 50, 128, 84, 83, 87, + 69, 128, 84, 83, 87, 66, 128, 84, 83, 87, 65, 128, 84, 83, 86, 128, 84, + 83, 83, 69, 128, 84, 83, 83, 65, 128, 84, 83, 79, 214, 84, 83, 73, 85, + 128, 84, 83, 72, 85, 71, 83, 128, 84, 83, 72, 79, 79, 75, 128, 84, 83, + 72, 79, 79, 203, 84, 83, 72, 79, 79, 74, 128, 84, 83, 72, 69, 83, 128, + 84, 83, 72, 69, 71, 128, 84, 83, 72, 69, 199, 84, 83, 72, 69, 69, 74, + 128, 84, 83, 72, 69, 128, 84, 83, 72, 65, 194, 84, 83, 72, 65, 128, 84, + 83, 69, 82, 69, 128, 84, 83, 69, 69, 66, 128, 84, 83, 65, 84, 193, 84, + 83, 65, 68, 73, 128, 84, 83, 65, 68, 201, 84, 83, 65, 66, 128, 84, 83, + 65, 65, 68, 73, 89, 128, 84, 83, 65, 65, 128, 84, 83, 193, 84, 82, 89, + 66, 76, 73, 79, 206, 84, 82, 89, 65, 83, 79, 83, 84, 82, 69, 76, 78, 65, + 89, 65, 128, 84, 82, 89, 65, 83, 79, 80, 79, 86, 79, 68, 78, 65, 89, 65, + 128, 84, 82, 89, 65, 83, 79, 71, 76, 65, 83, 78, 65, 89, 65, 128, 84, 82, + 89, 65, 83, 75, 65, 128, 84, 82, 85, 84, 72, 128, 84, 82, 85, 78, 75, + 128, 84, 82, 85, 78, 67, 65, 84, 69, 196, 84, 82, 85, 77, 80, 69, 84, + 128, 84, 82, 85, 77, 80, 45, 57, 128, 84, 82, 85, 77, 80, 45, 56, 128, + 84, 82, 85, 77, 80, 45, 55, 128, 84, 82, 85, 77, 80, 45, 54, 128, 84, 82, + 85, 77, 80, 45, 53, 128, 84, 82, 85, 77, 80, 45, 52, 128, 84, 82, 85, 77, + 80, 45, 51, 128, 84, 82, 85, 77, 80, 45, 50, 49, 128, 84, 82, 85, 77, 80, + 45, 50, 48, 128, 84, 82, 85, 77, 80, 45, 50, 128, 84, 82, 85, 77, 80, 45, + 49, 57, 128, 84, 82, 85, 77, 80, 45, 49, 56, 128, 84, 82, 85, 77, 80, 45, + 49, 55, 128, 84, 82, 85, 77, 80, 45, 49, 54, 128, 84, 82, 85, 77, 80, 45, + 49, 53, 128, 84, 82, 85, 77, 80, 45, 49, 52, 128, 84, 82, 85, 77, 80, 45, + 49, 51, 128, 84, 82, 85, 77, 80, 45, 49, 50, 128, 84, 82, 85, 77, 80, 45, + 49, 49, 128, 84, 82, 85, 77, 80, 45, 49, 48, 128, 84, 82, 85, 77, 80, 45, + 49, 128, 84, 82, 85, 69, 128, 84, 82, 85, 197, 84, 82, 85, 67, 75, 128, + 84, 82, 79, 80, 73, 67, 65, 204, 84, 82, 79, 80, 72, 89, 128, 84, 82, 79, + 77, 73, 75, 79, 83, 89, 78, 65, 71, 77, 65, 128, 84, 82, 79, 77, 73, 75, + 79, 80, 83, 73, 70, 73, 83, 84, 79, 78, 128, 84, 82, 79, 77, 73, 75, 79, + 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 65, 128, 84, 82, 79, 77, 73, 75, + 79, 78, 128, 84, 82, 79, 77, 73, 75, 79, 206, 84, 82, 79, 77, 73, 75, 79, + 76, 89, 71, 73, 83, 77, 65, 128, 84, 82, 79, 76, 76, 69, 89, 66, 85, 83, + 128, 84, 82, 79, 76, 76, 69, 89, 128, 84, 82, 79, 76, 76, 128, 84, 82, + 79, 75, 85, 84, 65, 83, 84, 201, 84, 82, 79, 69, 90, 69, 78, 73, 65, 206, + 84, 82, 73, 85, 77, 80, 72, 128, 84, 82, 73, 84, 79, 211, 84, 82, 73, 84, + 73, 77, 79, 82, 73, 79, 78, 128, 84, 82, 73, 83, 73, 77, 79, 85, 128, 84, + 82, 73, 83, 69, 77, 69, 128, 84, 82, 73, 80, 79, 68, 128, 84, 82, 73, 80, + 76, 73, 128, 84, 82, 73, 80, 76, 69, 128, 84, 82, 73, 80, 76, 197, 84, + 82, 73, 79, 206, 84, 82, 73, 76, 76, 73, 79, 78, 83, 128, 84, 82, 73, 76, + 76, 128, 84, 82, 73, 73, 83, 65, 80, 128, 84, 82, 73, 71, 82, 65, 77, 77, + 79, 211, 84, 82, 73, 71, 82, 65, 205, 84, 82, 73, 71, 79, 82, 71, 79, 78, + 128, 84, 82, 73, 70, 79, 78, 73, 65, 83, 128, 84, 82, 73, 70, 79, 76, 73, + 65, 84, 197, 84, 82, 73, 68, 69, 78, 84, 128, 84, 82, 73, 68, 69, 78, + 212, 84, 82, 73, 67, 79, 76, 79, 78, 128, 84, 82, 73, 65, 78, 71, 85, 76, + 65, 210, 84, 82, 73, 65, 78, 71, 76, 69, 45, 82, 79, 85, 78, 196, 84, 82, + 73, 65, 78, 71, 76, 69, 45, 72, 69, 65, 68, 69, 196, 84, 82, 73, 65, 78, + 71, 76, 69, 128, 84, 82, 73, 65, 78, 71, 76, 197, 84, 82, 73, 65, 128, + 84, 82, 73, 128, 84, 82, 69, 83, 86, 69, 84, 76, 89, 128, 84, 82, 69, 83, + 86, 69, 84, 76, 79, 128, 84, 82, 69, 83, 86, 69, 84, 76, 65, 89, 65, 128, + 84, 82, 69, 83, 73, 76, 76, 79, 128, 84, 82, 69, 78, 68, 128, 84, 82, 69, + 78, 196, 84, 82, 69, 77, 79, 76, 79, 45, 51, 128, 84, 82, 69, 77, 79, 76, + 79, 45, 50, 128, 84, 82, 69, 77, 79, 76, 79, 45, 49, 128, 84, 82, 69, 69, + 128, 84, 82, 69, 197, 84, 82, 69, 68, 69, 67, 73, 76, 69, 128, 84, 82, + 69, 65, 68, 73, 78, 71, 128, 84, 82, 65, 89, 128, 84, 82, 65, 86, 69, 76, + 45, 87, 65, 76, 76, 80, 76, 65, 78, 197, 84, 82, 65, 86, 69, 76, 45, 70, + 76, 79, 79, 82, 80, 76, 65, 78, 197, 84, 82, 65, 80, 69, 90, 73, 85, 77, + 128, 84, 82, 65, 80, 128, 84, 82, 65, 78, 83, 86, 69, 82, 83, 65, 204, + 84, 82, 65, 78, 83, 80, 79, 83, 73, 84, 73, 79, 206, 84, 82, 65, 78, 83, + 80, 76, 85, 84, 79, 128, 84, 82, 65, 78, 83, 77, 73, 212, 84, 82, 65, 78, + 83, 77, 73, 83, 83, 73, 79, 78, 128, 84, 82, 65, 78, 83, 77, 73, 83, 83, + 73, 79, 206, 84, 82, 65, 77, 87, 65, 89, 128, 84, 82, 65, 77, 128, 84, + 82, 65, 205, 84, 82, 65, 73, 78, 128, 84, 82, 65, 73, 206, 84, 82, 65, + 73, 76, 73, 78, 199, 84, 82, 65, 70, 70, 73, 67, 128, 84, 82, 65, 70, 70, + 73, 195, 84, 82, 65, 68, 73, 84, 73, 79, 78, 65, 204, 84, 82, 65, 68, + 197, 84, 82, 65, 67, 84, 79, 82, 128, 84, 82, 65, 67, 75, 66, 65, 76, 76, + 128, 84, 82, 65, 67, 75, 128, 84, 82, 65, 128, 84, 82, 128, 84, 79, 89, + 79, 82, 128, 84, 79, 88, 128, 84, 79, 87, 69, 82, 128, 84, 79, 87, 65, + 82, 68, 211, 84, 79, 86, 128, 84, 79, 85, 82, 78, 79, 73, 211, 84, 79, + 85, 67, 72, 84, 79, 78, 197, 84, 79, 85, 67, 72, 73, 78, 199, 84, 79, 85, + 67, 72, 69, 211, 84, 79, 85, 67, 200, 84, 79, 84, 207, 84, 79, 84, 65, + 204, 84, 79, 84, 128, 84, 79, 83, 128, 84, 79, 82, 84, 79, 73, 83, 197, + 84, 79, 82, 83, 79, 45, 87, 65, 76, 76, 80, 76, 65, 78, 197, 84, 79, 82, + 83, 79, 45, 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, 84, 79, 82, 83, 79, + 128, 84, 79, 82, 78, 65, 68, 79, 128, 84, 79, 82, 67, 85, 76, 85, 83, + 128, 84, 79, 82, 67, 85, 76, 85, 211, 84, 79, 82, 67, 72, 128, 84, 79, + 81, 128, 84, 79, 80, 66, 65, 82, 128, 84, 79, 80, 45, 76, 73, 71, 72, 84, + 69, 196, 84, 79, 80, 128, 84, 79, 208, 84, 79, 79, 84, 72, 66, 82, 85, + 83, 72, 128, 84, 79, 79, 84, 72, 128, 84, 79, 79, 78, 128, 84, 79, 79, + 76, 66, 79, 88, 128, 84, 79, 78, 79, 83, 128, 84, 79, 78, 71, 85, 69, + 128, 84, 79, 78, 71, 85, 197, 84, 79, 78, 71, 128, 84, 79, 78, 69, 45, + 86, 128, 84, 79, 78, 69, 45, 83, 128, 84, 79, 78, 69, 45, 77, 128, 84, + 79, 78, 69, 45, 74, 128, 84, 79, 78, 69, 45, 71, 128, 84, 79, 78, 69, 45, + 68, 128, 84, 79, 78, 69, 45, 66, 128, 84, 79, 78, 69, 45, 56, 128, 84, + 79, 78, 69, 45, 55, 128, 84, 79, 78, 69, 45, 54, 128, 84, 79, 78, 69, 45, + 53, 128, 84, 79, 78, 69, 45, 52, 128, 84, 79, 78, 69, 45, 51, 128, 84, + 79, 78, 69, 45, 50, 128, 84, 79, 78, 69, 45, 49, 128, 84, 79, 78, 69, + 128, 84, 79, 78, 65, 204, 84, 79, 77, 80, 73, 128, 84, 79, 77, 65, 84, + 79, 128, 84, 79, 76, 79, 78, 71, 128, 84, 79, 75, 89, 207, 84, 79, 73, + 76, 69, 84, 128, 84, 79, 71, 69, 84, 72, 69, 82, 128, 84, 79, 68, 207, + 84, 79, 67, 72, 75, 65, 128, 84, 79, 65, 78, 68, 65, 75, 72, 73, 65, 84, + 128, 84, 79, 65, 128, 84, 79, 45, 82, 65, 128, 84, 79, 45, 54, 128, 84, + 79, 45, 53, 128, 84, 79, 45, 52, 128, 84, 79, 45, 51, 128, 84, 79, 45, + 50, 128, 84, 79, 45, 49, 128, 84, 78, 128, 84, 76, 86, 128, 84, 76, 85, + 128, 84, 76, 73, 128, 84, 76, 72, 89, 65, 128, 84, 76, 72, 87, 69, 128, + 84, 76, 72, 85, 128, 84, 76, 72, 79, 79, 128, 84, 76, 72, 79, 128, 84, + 76, 72, 73, 128, 84, 76, 72, 69, 69, 128, 84, 76, 72, 69, 128, 84, 76, + 72, 65, 128, 84, 76, 69, 69, 128, 84, 76, 65, 128, 84, 74, 69, 128, 84, + 73, 88, 128, 84, 73, 87, 82, 128, 84, 73, 87, 78, 128, 84, 73, 87, 65, + 218, 84, 73, 84, 85, 65, 69, 80, 128, 84, 73, 84, 76, 79, 128, 84, 73, + 84, 76, 207, 84, 73, 84, 193, 84, 73, 84, 128, 84, 73, 82, 89, 65, 75, + 128, 84, 73, 82, 84, 193, 84, 73, 82, 79, 78, 73, 65, 206, 84, 73, 82, + 72, 85, 84, 193, 84, 73, 82, 69, 196, 84, 73, 82, 128, 84, 73, 210, 84, + 73, 80, 80, 73, 128, 84, 73, 80, 69, 72, 65, 128, 84, 73, 80, 128, 84, + 73, 208, 84, 73, 78, 89, 128, 84, 73, 78, 217, 84, 73, 78, 78, 69, 128, + 84, 73, 78, 67, 84, 85, 82, 69, 128, 84, 73, 78, 65, 71, 77, 65, 128, 84, + 73, 77, 69, 83, 128, 84, 73, 77, 69, 210, 84, 73, 77, 69, 128, 84, 73, + 76, 84, 73, 78, 71, 128, 84, 73, 76, 84, 73, 78, 199, 84, 73, 76, 84, + 128, 84, 73, 76, 69, 83, 128, 84, 73, 76, 68, 69, 128, 84, 73, 76, 68, + 197, 84, 73, 76, 128, 84, 73, 204, 84, 73, 75, 72, 89, 128, 84, 73, 75, + 72, 65, 89, 65, 128, 84, 73, 75, 72, 65, 89, 193, 84, 73, 75, 69, 85, 84, + 45, 84, 72, 73, 69, 85, 84, 72, 128, 84, 73, 75, 69, 85, 84, 45, 83, 73, + 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 84, 73, 75, 69, 85, 84, 45, 83, + 73, 79, 83, 128, 84, 73, 75, 69, 85, 84, 45, 82, 73, 69, 85, 76, 128, 84, + 73, 75, 69, 85, 84, 45, 80, 73, 69, 85, 80, 128, 84, 73, 75, 69, 85, 84, + 45, 77, 73, 69, 85, 77, 128, 84, 73, 75, 69, 85, 84, 45, 75, 73, 89, 69, + 79, 75, 128, 84, 73, 75, 69, 85, 84, 45, 67, 73, 69, 85, 67, 128, 84, 73, + 75, 69, 85, 84, 45, 67, 72, 73, 69, 85, 67, 72, 128, 84, 73, 75, 69, 85, + 84, 128, 84, 73, 75, 69, 85, 212, 84, 73, 71, 72, 84, 76, 89, 45, 67, 76, + 79, 83, 69, 196, 84, 73, 71, 72, 212, 84, 73, 71, 69, 82, 128, 84, 73, + 71, 69, 210, 84, 73, 70, 73, 78, 65, 71, 200, 84, 73, 69, 88, 128, 84, + 73, 69, 80, 128, 84, 73, 197, 84, 73, 67, 75, 69, 84, 83, 128, 84, 73, + 67, 75, 69, 84, 128, 84, 73, 67, 75, 128, 84, 73, 67, 203, 84, 73, 65, + 82, 65, 128, 84, 73, 50, 128, 84, 73, 45, 55, 128, 84, 73, 45, 54, 128, + 84, 73, 45, 53, 128, 84, 73, 45, 52, 128, 84, 73, 45, 51, 128, 84, 73, + 45, 50, 128, 84, 73, 45, 49, 128, 84, 72, 90, 128, 84, 72, 89, 79, 79, + 205, 84, 72, 87, 79, 79, 128, 84, 72, 87, 79, 128, 84, 72, 87, 73, 73, + 128, 84, 72, 87, 73, 128, 84, 72, 87, 69, 69, 128, 84, 72, 87, 65, 65, + 128, 84, 72, 87, 65, 128, 84, 72, 85, 82, 211, 84, 72, 85, 82, 73, 83, + 65, 218, 84, 72, 85, 78, 71, 128, 84, 72, 85, 78, 68, 69, 82, 83, 84, 79, + 82, 77, 128, 84, 72, 85, 78, 68, 69, 82, 128, 84, 72, 85, 78, 68, 69, 210, 84, 72, 85, 77, 66, 211, 84, 72, 85, 77, 66, 128, 84, 72, 82, 79, 87, 73, 78, 199, 84, 72, 82, 79, 85, 71, 72, 128, 84, 72, 82, 79, 85, 71, 200, 84, 72, 82, 69, 69, 45, 84, 72, 73, 82, 84, 89, 128, 84, 72, 82, 69, @@ -910,274 +912,274 @@ static const unsigned char lexicon[] = { 65, 212, 83, 87, 65, 83, 200, 83, 87, 65, 80, 80, 73, 78, 71, 128, 83, 87, 65, 78, 128, 83, 87, 65, 65, 128, 83, 87, 128, 83, 86, 65, 83, 84, 201, 83, 86, 65, 82, 73, 84, 65, 128, 83, 86, 65, 82, 73, 84, 193, 83, - 85, 88, 128, 83, 85, 85, 128, 83, 85, 84, 82, 193, 83, 85, 84, 128, 83, - 85, 83, 80, 69, 78, 83, 73, 79, 206, 83, 85, 83, 72, 73, 128, 83, 85, 82, - 89, 65, 128, 83, 85, 82, 88, 128, 83, 85, 82, 82, 79, 85, 78, 68, 128, - 83, 85, 82, 82, 79, 85, 78, 196, 83, 85, 82, 70, 69, 82, 128, 83, 85, 82, - 70, 65, 67, 197, 83, 85, 82, 69, 128, 83, 85, 82, 65, 78, 71, 128, 83, - 85, 82, 57, 128, 83, 85, 82, 128, 83, 85, 210, 83, 85, 80, 82, 65, 76, - 73, 78, 69, 65, 210, 83, 85, 80, 69, 82, 86, 73, 83, 69, 128, 83, 85, 80, - 69, 82, 86, 73, 76, 76, 65, 73, 78, 128, 83, 85, 80, 69, 82, 83, 69, 84, - 128, 83, 85, 80, 69, 82, 83, 69, 212, 83, 85, 80, 69, 82, 83, 67, 82, 73, - 80, 212, 83, 85, 80, 69, 82, 73, 77, 80, 79, 83, 69, 196, 83, 85, 80, 69, - 82, 72, 69, 82, 79, 128, 83, 85, 80, 69, 82, 70, 73, 88, 69, 196, 83, 85, - 80, 69, 210, 83, 85, 80, 128, 83, 85, 79, 88, 128, 83, 85, 79, 80, 128, - 83, 85, 79, 128, 83, 85, 78, 83, 69, 212, 83, 85, 78, 82, 73, 83, 69, - 128, 83, 85, 78, 82, 73, 83, 197, 83, 85, 78, 71, 76, 65, 83, 83, 69, 83, - 128, 83, 85, 78, 71, 128, 83, 85, 78, 70, 76, 79, 87, 69, 82, 128, 83, - 85, 78, 68, 65, 78, 69, 83, 197, 83, 85, 78, 128, 83, 85, 206, 83, 85, - 77, 77, 69, 82, 128, 83, 85, 77, 77, 65, 84, 73, 79, 78, 128, 83, 85, 77, - 77, 65, 84, 73, 79, 206, 83, 85, 77, 65, 83, 72, 128, 83, 85, 77, 128, - 83, 85, 76, 70, 85, 82, 128, 83, 85, 75, 85, 78, 128, 83, 85, 75, 85, - 206, 83, 85, 75, 85, 128, 83, 85, 75, 213, 83, 85, 73, 84, 65, 66, 76, - 69, 128, 83, 85, 73, 212, 83, 85, 72, 85, 82, 128, 83, 85, 69, 128, 83, - 85, 68, 50, 128, 83, 85, 68, 128, 83, 85, 67, 75, 73, 78, 199, 83, 85, - 67, 75, 69, 68, 128, 83, 85, 67, 203, 83, 85, 67, 67, 69, 69, 68, 83, - 128, 83, 85, 67, 67, 69, 69, 68, 211, 83, 85, 67, 67, 69, 69, 68, 128, - 83, 85, 67, 67, 69, 69, 196, 83, 85, 66, 85, 78, 73, 84, 128, 83, 85, 66, - 83, 84, 73, 84, 85, 84, 73, 79, 206, 83, 85, 66, 83, 84, 73, 84, 85, 84, - 69, 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, 197, 83, 85, 66, 83, 69, 84, - 128, 83, 85, 66, 83, 69, 212, 83, 85, 66, 83, 67, 82, 73, 80, 212, 83, - 85, 66, 80, 85, 78, 67, 84, 73, 83, 128, 83, 85, 66, 76, 73, 78, 69, 65, - 210, 83, 85, 66, 76, 73, 77, 65, 84, 73, 79, 78, 128, 83, 85, 66, 76, 73, - 77, 65, 84, 69, 45, 51, 128, 83, 85, 66, 76, 73, 77, 65, 84, 69, 45, 50, - 128, 83, 85, 66, 76, 73, 77, 65, 84, 69, 128, 83, 85, 66, 76, 73, 77, 65, - 84, 197, 83, 85, 66, 74, 79, 73, 78, 69, 82, 128, 83, 85, 66, 74, 79, 73, - 78, 69, 196, 83, 85, 66, 74, 69, 67, 84, 128, 83, 85, 66, 73, 84, 79, - 128, 83, 85, 66, 72, 65, 65, 78, 65, 72, 213, 83, 85, 66, 71, 82, 79, 85, - 80, 128, 83, 85, 66, 71, 82, 79, 85, 208, 83, 85, 66, 128, 83, 85, 65, - 77, 128, 83, 85, 65, 69, 84, 128, 83, 85, 65, 69, 78, 128, 83, 85, 65, - 69, 128, 83, 85, 65, 66, 128, 83, 85, 65, 128, 83, 85, 45, 56, 128, 83, - 85, 45, 55, 128, 83, 85, 45, 54, 128, 83, 85, 45, 53, 128, 83, 85, 45, - 52, 128, 83, 85, 45, 51, 128, 83, 85, 45, 50, 128, 83, 85, 45, 49, 128, - 83, 213, 83, 84, 88, 128, 83, 84, 87, 65, 128, 83, 84, 85, 80, 65, 128, - 83, 84, 85, 70, 70, 69, 196, 83, 84, 85, 68, 89, 128, 83, 84, 85, 68, 73, - 207, 83, 84, 85, 67, 75, 45, 79, 85, 212, 83, 84, 83, 128, 83, 84, 82, - 79, 78, 199, 83, 84, 82, 79, 75, 69, 83, 128, 83, 84, 82, 79, 75, 69, - 211, 83, 84, 82, 79, 75, 69, 45, 57, 128, 83, 84, 82, 79, 75, 69, 45, 56, - 128, 83, 84, 82, 79, 75, 69, 45, 55, 128, 83, 84, 82, 79, 75, 69, 45, 54, - 128, 83, 84, 82, 79, 75, 69, 45, 53, 128, 83, 84, 82, 79, 75, 69, 45, 52, - 128, 83, 84, 82, 79, 75, 69, 45, 51, 128, 83, 84, 82, 79, 75, 69, 45, 50, - 128, 83, 84, 82, 79, 75, 69, 45, 49, 49, 128, 83, 84, 82, 79, 75, 69, 45, - 49, 48, 128, 83, 84, 82, 79, 75, 69, 45, 49, 128, 83, 84, 82, 79, 75, - 197, 83, 84, 82, 73, 80, 69, 128, 83, 84, 82, 73, 78, 71, 128, 83, 84, - 82, 73, 78, 199, 83, 84, 82, 73, 75, 69, 84, 72, 82, 79, 85, 71, 72, 128, - 83, 84, 82, 73, 75, 197, 83, 84, 82, 73, 68, 69, 128, 83, 84, 82, 73, 67, - 84, 76, 217, 83, 84, 82, 69, 84, 67, 72, 69, 196, 83, 84, 82, 69, 84, 67, - 72, 128, 83, 84, 82, 69, 83, 211, 83, 84, 82, 69, 78, 71, 84, 72, 128, - 83, 84, 82, 69, 76, 193, 83, 84, 82, 69, 65, 77, 69, 82, 128, 83, 84, 82, - 65, 87, 66, 69, 82, 82, 89, 128, 83, 84, 82, 65, 87, 128, 83, 84, 82, 65, - 84, 85, 77, 45, 50, 128, 83, 84, 82, 65, 84, 85, 77, 128, 83, 84, 82, 65, - 84, 85, 205, 83, 84, 82, 65, 84, 73, 65, 206, 83, 84, 82, 65, 78, 78, 79, - 128, 83, 84, 82, 65, 78, 78, 207, 83, 84, 82, 65, 73, 78, 69, 82, 128, - 83, 84, 82, 65, 73, 71, 72, 84, 78, 69, 83, 83, 128, 83, 84, 82, 65, 73, - 71, 72, 84, 128, 83, 84, 82, 65, 73, 71, 72, 212, 83, 84, 82, 65, 73, 70, - 128, 83, 84, 82, 65, 71, 71, 73, 83, 77, 65, 84, 65, 128, 83, 84, 79, 86, - 69, 128, 83, 84, 79, 82, 69, 128, 83, 84, 79, 80, 87, 65, 84, 67, 72, - 128, 83, 84, 79, 80, 80, 73, 78, 71, 128, 83, 84, 79, 80, 80, 65, 71, 69, - 128, 83, 84, 79, 80, 73, 84, 83, 65, 128, 83, 84, 79, 80, 73, 84, 83, - 193, 83, 84, 79, 80, 128, 83, 84, 79, 208, 83, 84, 79, 78, 69, 128, 83, - 84, 79, 67, 75, 128, 83, 84, 79, 67, 203, 83, 84, 73, 82, 82, 85, 208, - 83, 84, 73, 77, 77, 69, 128, 83, 84, 73, 76, 204, 83, 84, 73, 76, 197, - 83, 84, 73, 71, 77, 65, 128, 83, 84, 73, 67, 75, 73, 78, 199, 83, 84, 73, - 67, 203, 83, 84, 69, 84, 72, 79, 83, 67, 79, 80, 69, 128, 83, 84, 69, 82, - 69, 79, 128, 83, 84, 69, 80, 128, 83, 84, 69, 78, 79, 71, 82, 65, 80, 72, - 73, 195, 83, 84, 69, 77, 128, 83, 84, 69, 65, 77, 217, 83, 84, 69, 65, - 77, 73, 78, 199, 83, 84, 69, 65, 77, 128, 83, 84, 69, 65, 205, 83, 84, - 65, 86, 82, 79, 85, 128, 83, 84, 65, 86, 82, 79, 83, 128, 83, 84, 65, 86, - 82, 79, 211, 83, 84, 65, 85, 82, 79, 83, 128, 83, 84, 65, 84, 89, 65, - 128, 83, 84, 65, 84, 89, 193, 83, 84, 65, 84, 85, 197, 83, 84, 65, 84, - 73, 79, 78, 128, 83, 84, 65, 84, 69, 82, 83, 128, 83, 84, 65, 84, 69, - 128, 83, 84, 65, 82, 84, 73, 78, 199, 83, 84, 65, 82, 84, 128, 83, 84, - 65, 82, 212, 83, 84, 65, 82, 83, 128, 83, 84, 65, 82, 82, 69, 196, 83, - 84, 65, 82, 75, 128, 83, 84, 65, 82, 128, 83, 84, 65, 210, 83, 84, 65, - 78, 68, 83, 84, 73, 76, 76, 128, 83, 84, 65, 78, 68, 73, 78, 199, 83, 84, - 65, 78, 68, 65, 82, 196, 83, 84, 65, 78, 68, 128, 83, 84, 65, 78, 128, - 83, 84, 65, 77, 80, 69, 196, 83, 84, 65, 76, 76, 73, 79, 78, 128, 83, 84, - 65, 70, 70, 128, 83, 84, 65, 70, 198, 83, 84, 65, 68, 73, 85, 77, 128, - 83, 84, 65, 67, 75, 69, 196, 83, 84, 65, 67, 67, 65, 84, 79, 128, 83, 84, - 65, 67, 67, 65, 84, 73, 83, 83, 73, 77, 79, 128, 83, 84, 50, 128, 83, 83, - 89, 88, 128, 83, 83, 89, 84, 128, 83, 83, 89, 82, 88, 128, 83, 83, 89, - 82, 128, 83, 83, 89, 80, 128, 83, 83, 89, 128, 83, 83, 85, 88, 128, 83, - 83, 85, 85, 128, 83, 83, 85, 84, 128, 83, 83, 85, 80, 128, 83, 83, 79, - 88, 128, 83, 83, 79, 84, 128, 83, 83, 79, 80, 128, 83, 83, 79, 79, 128, - 83, 83, 79, 128, 83, 83, 73, 88, 128, 83, 83, 73, 84, 128, 83, 83, 73, - 80, 128, 83, 83, 73, 73, 128, 83, 83, 73, 69, 88, 128, 83, 83, 73, 69, - 80, 128, 83, 83, 73, 69, 128, 83, 83, 72, 73, 78, 128, 83, 83, 72, 69, - 128, 83, 83, 69, 88, 128, 83, 83, 69, 80, 128, 83, 83, 69, 69, 128, 83, - 83, 65, 88, 128, 83, 83, 65, 85, 128, 83, 83, 65, 84, 128, 83, 83, 65, - 80, 128, 83, 83, 65, 78, 71, 89, 69, 83, 73, 69, 85, 78, 71, 128, 83, 83, - 65, 78, 71, 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, 128, 83, 83, 65, - 78, 71, 84, 73, 75, 69, 85, 84, 45, 80, 73, 69, 85, 80, 128, 83, 83, 65, - 78, 71, 84, 73, 75, 69, 85, 84, 128, 83, 83, 65, 78, 71, 84, 72, 73, 69, - 85, 84, 72, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, 84, 73, 75, 69, - 85, 84, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, 80, 73, 69, 85, 80, - 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, - 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 83, 83, 65, 78, 71, 82, 73, 69, - 85, 76, 45, 75, 72, 73, 69, 85, 75, 72, 128, 83, 83, 65, 78, 71, 82, 73, - 69, 85, 76, 128, 83, 83, 65, 78, 71, 80, 73, 69, 85, 80, 128, 83, 83, 65, - 78, 71, 78, 73, 69, 85, 78, 128, 83, 83, 65, 78, 71, 77, 73, 69, 85, 77, - 128, 83, 83, 65, 78, 71, 73, 69, 85, 78, 71, 128, 83, 83, 65, 78, 71, 72, - 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, 45, 72, 73, - 69, 85, 72, 128, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, 128, 83, 83, 65, - 78, 71, 65, 82, 65, 69, 65, 128, 83, 83, 65, 73, 128, 83, 83, 65, 65, - 128, 83, 83, 51, 128, 83, 83, 50, 128, 83, 82, 69, 68, 78, 197, 83, 82, - 128, 83, 81, 85, 73, 83, 200, 83, 81, 85, 73, 82, 82, 69, 204, 83, 81, - 85, 73, 71, 71, 76, 197, 83, 81, 85, 73, 68, 128, 83, 81, 85, 69, 69, 90, - 69, 68, 128, 83, 81, 85, 69, 69, 90, 197, 83, 81, 85, 65, 212, 83, 81, - 85, 65, 82, 69, 83, 128, 83, 81, 85, 65, 82, 69, 68, 128, 83, 81, 85, 65, - 82, 69, 128, 83, 80, 89, 128, 83, 80, 87, 65, 128, 83, 80, 85, 78, 71, - 211, 83, 80, 82, 79, 85, 84, 128, 83, 80, 82, 73, 78, 71, 83, 128, 83, - 80, 82, 73, 78, 71, 128, 83, 80, 82, 69, 67, 72, 71, 69, 83, 65, 78, 199, - 83, 80, 82, 69, 65, 68, 128, 83, 80, 82, 69, 65, 196, 83, 80, 79, 85, 84, - 73, 78, 199, 83, 80, 79, 84, 128, 83, 80, 79, 82, 84, 211, 83, 80, 79, - 79, 78, 128, 83, 80, 79, 79, 204, 83, 80, 79, 78, 71, 69, 128, 83, 80, - 79, 128, 83, 80, 76, 73, 84, 84, 73, 78, 199, 83, 80, 76, 73, 84, 128, - 83, 80, 76, 73, 212, 83, 80, 76, 65, 89, 69, 68, 128, 83, 80, 76, 65, 83, - 72, 73, 78, 199, 83, 80, 73, 82, 73, 84, 85, 211, 83, 80, 73, 82, 73, 84, - 128, 83, 80, 73, 82, 73, 212, 83, 80, 73, 82, 65, 78, 84, 128, 83, 80, - 73, 82, 65, 76, 128, 83, 80, 73, 82, 65, 204, 83, 80, 73, 78, 69, 128, - 83, 80, 73, 68, 69, 82, 217, 83, 80, 73, 68, 69, 82, 128, 83, 80, 73, 68, - 69, 210, 83, 80, 73, 67, 69, 128, 83, 80, 73, 128, 83, 80, 72, 69, 82, - 73, 67, 65, 204, 83, 80, 69, 83, 77, 73, 76, 207, 83, 80, 69, 78, 212, - 83, 80, 69, 69, 68, 66, 79, 65, 84, 128, 83, 80, 69, 69, 67, 72, 128, 83, - 80, 69, 69, 67, 200, 83, 80, 69, 67, 73, 65, 76, 128, 83, 80, 69, 65, 82, - 128, 83, 80, 69, 65, 75, 73, 78, 199, 83, 80, 69, 65, 75, 69, 82, 128, - 83, 80, 69, 65, 75, 69, 210, 83, 80, 69, 65, 75, 45, 78, 79, 45, 69, 86, - 73, 204, 83, 80, 69, 128, 83, 80, 65, 84, 72, 73, 128, 83, 80, 65, 82, - 75, 76, 73, 78, 199, 83, 80, 65, 82, 75, 76, 69, 83, 128, 83, 80, 65, 82, - 75, 76, 69, 82, 128, 83, 80, 65, 82, 75, 76, 69, 128, 83, 80, 65, 71, 72, - 69, 84, 84, 73, 128, 83, 80, 65, 68, 69, 83, 128, 83, 80, 65, 68, 197, - 83, 80, 65, 67, 73, 78, 199, 83, 80, 65, 67, 197, 83, 80, 65, 128, 83, - 79, 89, 79, 77, 66, 207, 83, 79, 89, 128, 83, 79, 87, 73, 76, 207, 83, - 79, 87, 128, 83, 79, 85, 84, 72, 69, 82, 206, 83, 79, 85, 84, 72, 45, 83, - 76, 65, 86, 69, 217, 83, 79, 85, 84, 200, 83, 79, 85, 82, 67, 69, 128, - 83, 79, 85, 78, 68, 128, 83, 79, 85, 78, 196, 83, 79, 85, 78, 65, 80, - 128, 83, 79, 85, 128, 83, 79, 83, 128, 83, 79, 82, 79, 67, 72, 89, 193, - 83, 79, 82, 73, 128, 83, 79, 82, 193, 83, 79, 81, 128, 83, 79, 79, 206, - 83, 79, 78, 74, 65, 77, 128, 83, 79, 78, 71, 128, 83, 79, 78, 128, 83, - 79, 77, 80, 69, 78, 199, 83, 79, 77, 128, 83, 79, 205, 83, 79, 76, 73, - 68, 85, 83, 128, 83, 79, 76, 73, 68, 85, 211, 83, 79, 76, 73, 196, 83, - 79, 76, 68, 73, 69, 82, 128, 83, 79, 72, 128, 83, 79, 71, 68, 73, 65, - 206, 83, 79, 70, 84, 87, 65, 82, 69, 45, 70, 85, 78, 67, 84, 73, 79, 206, - 83, 79, 70, 84, 78, 69, 83, 83, 128, 83, 79, 70, 84, 66, 65, 76, 76, 128, - 83, 79, 70, 212, 83, 79, 198, 83, 79, 67, 75, 83, 128, 83, 79, 67, 73, - 69, 84, 89, 128, 83, 79, 67, 67, 69, 210, 83, 79, 65, 80, 128, 83, 79, - 65, 128, 83, 79, 45, 55, 128, 83, 79, 45, 54, 128, 83, 79, 45, 53, 128, - 83, 79, 45, 52, 128, 83, 79, 45, 51, 128, 83, 79, 45, 50, 128, 83, 79, - 45, 49, 128, 83, 207, 83, 78, 79, 87, 77, 65, 78, 128, 83, 78, 79, 87, - 77, 65, 206, 83, 78, 79, 87, 70, 76, 65, 75, 69, 128, 83, 78, 79, 87, 66, - 79, 65, 82, 68, 69, 82, 128, 83, 78, 79, 87, 128, 83, 78, 79, 215, 83, - 78, 79, 85, 84, 128, 83, 78, 79, 85, 212, 83, 78, 69, 69, 90, 73, 78, - 199, 83, 78, 65, 208, 83, 78, 65, 75, 69, 128, 83, 78, 65, 75, 197, 83, - 78, 65, 73, 76, 128, 83, 78, 193, 83, 77, 79, 75, 73, 78, 199, 83, 77, - 73, 82, 75, 73, 78, 199, 83, 77, 73, 76, 73, 78, 199, 83, 77, 73, 76, 69, - 128, 83, 77, 73, 76, 197, 83, 77, 69, 65, 82, 128, 83, 77, 65, 83, 200, - 83, 77, 65, 76, 76, 69, 210, 83, 77, 65, 76, 76, 128, 83, 76, 85, 82, - 128, 83, 76, 79, 90, 72, 73, 84, 73, 69, 128, 83, 76, 79, 90, 72, 73, 84, - 73, 197, 83, 76, 79, 87, 76, 89, 128, 83, 76, 79, 87, 128, 83, 76, 79, - 215, 83, 76, 79, 86, 79, 128, 83, 76, 79, 84, 72, 128, 83, 76, 79, 212, - 83, 76, 79, 80, 73, 78, 199, 83, 76, 79, 80, 69, 128, 83, 76, 79, 65, - 206, 83, 76, 73, 78, 71, 128, 83, 76, 73, 71, 72, 84, 76, 217, 83, 76, - 73, 68, 73, 78, 71, 128, 83, 76, 73, 68, 69, 82, 128, 83, 76, 73, 68, 69, - 128, 83, 76, 73, 67, 69, 128, 83, 76, 73, 67, 197, 83, 76, 69, 85, 84, - 200, 83, 76, 69, 69, 80, 217, 83, 76, 69, 69, 80, 73, 78, 199, 83, 76, - 69, 69, 208, 83, 76, 69, 68, 128, 83, 76, 65, 86, 79, 78, 73, 195, 83, - 76, 65, 86, 69, 128, 83, 76, 65, 83, 72, 128, 83, 76, 65, 83, 200, 83, - 76, 65, 78, 84, 69, 196, 83, 75, 87, 65, 128, 83, 75, 87, 128, 83, 75, - 85, 78, 75, 128, 83, 75, 85, 76, 76, 128, 83, 75, 85, 76, 204, 83, 75, - 79, 66, 65, 128, 83, 75, 76, 73, 82, 79, 206, 83, 75, 73, 78, 128, 83, - 75, 73, 69, 82, 128, 83, 75, 201, 83, 75, 69, 87, 69, 196, 83, 75, 65, - 84, 69, 66, 79, 65, 82, 68, 128, 83, 75, 65, 84, 69, 128, 83, 75, 65, 77, - 69, 89, 84, 83, 193, 83, 75, 128, 83, 74, 69, 128, 83, 73, 90, 197, 83, - 73, 88, 84, 89, 45, 70, 79, 85, 82, 84, 72, 83, 128, 83, 73, 88, 84, 89, - 45, 70, 79, 85, 82, 84, 72, 128, 83, 73, 88, 84, 89, 45, 70, 79, 85, 82, - 84, 200, 83, 73, 88, 84, 89, 128, 83, 73, 88, 84, 217, 83, 73, 88, 84, - 72, 83, 128, 83, 73, 88, 84, 72, 211, 83, 73, 88, 84, 72, 128, 83, 73, - 88, 84, 69, 69, 78, 84, 72, 83, 128, 83, 73, 88, 84, 69, 69, 78, 84, 72, - 45, 50, 128, 83, 73, 88, 84, 69, 69, 78, 84, 72, 45, 49, 128, 83, 73, 88, - 84, 69, 69, 78, 84, 72, 128, 83, 73, 88, 84, 69, 69, 78, 84, 200, 83, 73, - 88, 84, 69, 69, 78, 128, 83, 73, 88, 84, 69, 69, 206, 83, 73, 88, 45, 84, - 72, 73, 82, 84, 89, 128, 83, 73, 88, 45, 83, 84, 82, 73, 78, 199, 83, 73, - 88, 45, 80, 69, 82, 45, 69, 205, 83, 73, 88, 45, 76, 73, 78, 197, 83, 73, - 216, 83, 73, 84, 69, 128, 83, 73, 83, 65, 128, 83, 73, 82, 82, 65, 72, - 128, 83, 73, 82, 73, 78, 71, 85, 128, 83, 73, 79, 83, 45, 84, 72, 73, 69, - 85, 84, 72, 128, 83, 73, 79, 83, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, - 128, 83, 73, 79, 83, 45, 82, 73, 69, 85, 76, 128, 83, 73, 79, 83, 45, 80, - 73, 69, 85, 80, 45, 75, 73, 89, 69, 79, 75, 128, 83, 73, 79, 83, 45, 80, - 72, 73, 69, 85, 80, 72, 128, 83, 73, 79, 83, 45, 80, 65, 78, 83, 73, 79, - 83, 128, 83, 73, 79, 83, 45, 78, 73, 69, 85, 78, 128, 83, 73, 79, 83, 45, - 77, 73, 69, 85, 77, 128, 83, 73, 79, 83, 45, 75, 72, 73, 69, 85, 75, 72, - 128, 83, 73, 79, 83, 45, 75, 65, 80, 89, 69, 79, 85, 78, 80, 73, 69, 85, - 80, 128, 83, 73, 79, 83, 45, 73, 69, 85, 78, 71, 128, 83, 73, 79, 83, 45, - 72, 73, 69, 85, 72, 128, 83, 73, 79, 83, 45, 67, 73, 69, 85, 67, 128, 83, - 73, 79, 83, 45, 67, 72, 73, 69, 85, 67, 72, 128, 83, 73, 79, 211, 83, 73, - 78, 85, 83, 79, 73, 196, 83, 73, 78, 79, 76, 79, 71, 73, 67, 65, 204, 83, - 73, 78, 78, 89, 73, 73, 89, 72, 69, 128, 83, 73, 78, 75, 73, 78, 71, 128, - 83, 73, 78, 71, 76, 69, 45, 83, 72, 73, 70, 84, 45, 51, 128, 83, 73, 78, - 71, 76, 69, 45, 83, 72, 73, 70, 84, 45, 50, 128, 83, 73, 78, 71, 76, 69, - 45, 76, 73, 78, 197, 83, 73, 78, 71, 76, 69, 128, 83, 73, 78, 71, 76, - 197, 83, 73, 78, 71, 65, 65, 84, 128, 83, 73, 78, 197, 83, 73, 78, 68, - 72, 201, 83, 73, 78, 128, 83, 73, 206, 83, 73, 77, 85, 76, 84, 65, 78, - 69, 79, 85, 83, 128, 83, 73, 77, 85, 76, 84, 65, 78, 69, 79, 85, 211, 83, - 73, 77, 80, 76, 73, 70, 73, 69, 196, 83, 73, 77, 73, 76, 65, 82, 128, 83, - 73, 77, 73, 76, 65, 210, 83, 73, 77, 65, 78, 83, 73, 211, 83, 73, 77, 65, - 76, 85, 78, 71, 85, 206, 83, 73, 77, 65, 128, 83, 73, 76, 86, 69, 82, - 128, 83, 73, 76, 75, 128, 83, 73, 76, 73, 81, 85, 193, 83, 73, 76, 72, - 79, 85, 69, 84, 84, 69, 128, 83, 73, 76, 72, 79, 85, 69, 84, 84, 197, 83, - 73, 76, 65, 51, 128, 83, 73, 75, 73, 128, 83, 73, 75, 50, 128, 83, 73, - 75, 178, 83, 73, 71, 78, 83, 128, 83, 73, 71, 77, 79, 73, 196, 83, 73, - 71, 77, 65, 128, 83, 73, 71, 77, 193, 83, 73, 71, 69, 204, 83, 73, 71, - 52, 128, 83, 73, 71, 180, 83, 73, 71, 128, 83, 73, 69, 69, 128, 83, 73, - 68, 69, 87, 65, 89, 211, 83, 73, 68, 69, 128, 83, 73, 68, 197, 83, 73, - 68, 68, 72, 73, 128, 83, 73, 68, 68, 72, 65, 77, 128, 83, 73, 68, 68, 72, - 65, 205, 83, 73, 67, 75, 78, 69, 83, 83, 128, 83, 73, 67, 75, 76, 69, - 128, 83, 73, 66, 197, 83, 73, 65, 128, 83, 73, 45, 54, 128, 83, 73, 45, - 53, 128, 83, 73, 45, 52, 128, 83, 73, 45, 51, 128, 83, 73, 45, 50, 128, - 83, 73, 45, 49, 128, 83, 201, 83, 72, 89, 88, 128, 83, 72, 89, 84, 128, - 83, 72, 89, 82, 88, 128, 83, 72, 89, 82, 128, 83, 72, 89, 80, 128, 83, - 72, 89, 69, 128, 83, 72, 89, 65, 128, 83, 72, 89, 128, 83, 72, 87, 79, - 89, 128, 83, 72, 87, 79, 79, 128, 83, 72, 87, 79, 128, 83, 72, 87, 73, - 73, 128, 83, 72, 87, 73, 128, 83, 72, 87, 69, 128, 83, 72, 87, 197, 83, - 72, 87, 65, 65, 128, 83, 72, 87, 65, 128, 83, 72, 86, 128, 83, 72, 85, - 88, 128, 83, 72, 85, 85, 128, 83, 72, 85, 84, 84, 76, 69, 67, 79, 67, 75, - 128, 83, 72, 85, 84, 128, 83, 72, 85, 82, 88, 128, 83, 72, 85, 82, 128, - 83, 72, 85, 80, 128, 83, 72, 85, 79, 88, 128, 83, 72, 85, 79, 80, 128, - 83, 72, 85, 79, 128, 83, 72, 85, 77, 128, 83, 72, 85, 76, 128, 83, 72, - 85, 70, 70, 76, 197, 83, 72, 85, 69, 81, 128, 83, 72, 85, 69, 78, 83, 72, - 85, 69, 84, 128, 83, 72, 85, 66, 85, 82, 128, 83, 72, 85, 65, 78, 71, 88, - 73, 128, 83, 72, 85, 50, 128, 83, 72, 85, 178, 83, 72, 85, 128, 83, 72, - 84, 65, 80, 73, 67, 128, 83, 72, 84, 65, 128, 83, 72, 82, 85, 71, 128, - 83, 72, 82, 79, 79, 128, 83, 72, 82, 79, 128, 83, 72, 82, 73, 78, 69, - 128, 83, 72, 82, 73, 77, 80, 128, 83, 72, 82, 73, 73, 128, 83, 72, 82, - 73, 128, 83, 72, 82, 65, 65, 128, 83, 72, 82, 65, 128, 83, 72, 79, 89, - 128, 83, 72, 79, 88, 128, 83, 72, 79, 87, 69, 82, 128, 83, 72, 79, 85, - 76, 68, 69, 82, 69, 196, 83, 72, 79, 85, 76, 68, 69, 210, 83, 72, 79, 85, - 128, 83, 72, 79, 84, 128, 83, 72, 79, 82, 84, 83, 128, 83, 72, 79, 82, - 84, 211, 83, 72, 79, 82, 84, 72, 65, 78, 196, 83, 72, 79, 82, 84, 69, 78, - 69, 82, 128, 83, 72, 79, 82, 84, 67, 65, 75, 69, 128, 83, 72, 79, 82, 84, - 45, 84, 87, 73, 71, 45, 89, 82, 128, 83, 72, 79, 82, 84, 45, 84, 87, 73, - 71, 45, 84, 89, 210, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 83, 79, - 204, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 79, 83, 211, 83, 72, 79, - 82, 84, 45, 84, 87, 73, 71, 45, 78, 65, 85, 196, 83, 72, 79, 82, 84, 45, - 84, 87, 73, 71, 45, 77, 65, 68, 210, 83, 72, 79, 82, 84, 45, 84, 87, 73, - 71, 45, 72, 65, 71, 65, 76, 204, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, - 45, 66, 74, 65, 82, 75, 65, 206, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, - 45, 65, 210, 83, 72, 79, 82, 84, 128, 83, 72, 79, 82, 212, 83, 72, 79, - 81, 128, 83, 72, 79, 209, 83, 72, 79, 80, 80, 73, 78, 199, 83, 72, 79, - 80, 128, 83, 72, 79, 79, 84, 73, 78, 199, 83, 72, 79, 79, 84, 128, 83, - 72, 79, 79, 73, 128, 83, 72, 79, 79, 128, 83, 72, 79, 71, 201, 83, 72, - 79, 199, 83, 72, 79, 69, 83, 128, 83, 72, 79, 69, 128, 83, 72, 79, 197, - 83, 72, 79, 67, 75, 69, 196, 83, 72, 79, 65, 128, 83, 72, 79, 128, 83, - 72, 73, 89, 89, 65, 65, 76, 65, 65, 128, 83, 72, 73, 84, 65, 128, 83, 72, - 73, 84, 193, 83, 72, 73, 82, 212, 83, 72, 73, 82, 65, 69, 128, 83, 72, - 73, 82, 128, 83, 72, 73, 210, 83, 72, 73, 81, 128, 83, 72, 73, 78, 84, - 207, 83, 72, 73, 78, 73, 71, 128, 83, 72, 73, 78, 68, 193, 83, 72, 73, - 206, 83, 72, 73, 77, 65, 128, 83, 72, 73, 77, 193, 83, 72, 73, 77, 128, - 83, 72, 73, 205, 83, 72, 73, 73, 78, 128, 83, 72, 73, 73, 128, 83, 72, - 73, 70, 212, 83, 72, 73, 69, 76, 68, 128, 83, 72, 73, 68, 128, 83, 72, - 73, 196, 83, 72, 72, 65, 128, 83, 72, 72, 193, 83, 72, 69, 88, 128, 83, - 72, 69, 86, 65, 128, 83, 72, 69, 85, 88, 128, 83, 72, 69, 85, 79, 81, + 85, 88, 128, 83, 85, 85, 128, 83, 85, 84, 85, 72, 128, 83, 85, 84, 82, + 193, 83, 85, 84, 128, 83, 85, 83, 80, 69, 78, 83, 73, 79, 206, 83, 85, + 83, 72, 73, 128, 83, 85, 82, 89, 65, 128, 83, 85, 82, 88, 128, 83, 85, + 82, 82, 79, 85, 78, 68, 128, 83, 85, 82, 82, 79, 85, 78, 196, 83, 85, 82, + 70, 69, 82, 128, 83, 85, 82, 70, 65, 67, 197, 83, 85, 82, 69, 128, 83, + 85, 82, 65, 78, 71, 128, 83, 85, 82, 57, 128, 83, 85, 82, 128, 83, 85, + 210, 83, 85, 80, 82, 65, 76, 73, 78, 69, 65, 210, 83, 85, 80, 69, 82, 86, + 73, 83, 69, 128, 83, 85, 80, 69, 82, 86, 73, 76, 76, 65, 73, 78, 128, 83, + 85, 80, 69, 82, 83, 69, 84, 128, 83, 85, 80, 69, 82, 83, 69, 212, 83, 85, + 80, 69, 82, 83, 67, 82, 73, 80, 212, 83, 85, 80, 69, 82, 73, 77, 80, 79, + 83, 69, 196, 83, 85, 80, 69, 82, 72, 69, 82, 79, 128, 83, 85, 80, 69, 82, + 70, 73, 88, 69, 196, 83, 85, 80, 69, 210, 83, 85, 80, 128, 83, 85, 79, + 88, 128, 83, 85, 79, 80, 128, 83, 85, 79, 128, 83, 85, 78, 83, 69, 212, + 83, 85, 78, 82, 73, 83, 69, 128, 83, 85, 78, 82, 73, 83, 197, 83, 85, 78, + 71, 76, 65, 83, 83, 69, 83, 128, 83, 85, 78, 71, 128, 83, 85, 78, 70, 76, + 79, 87, 69, 82, 128, 83, 85, 78, 68, 65, 78, 69, 83, 197, 83, 85, 78, + 128, 83, 85, 206, 83, 85, 77, 77, 69, 82, 128, 83, 85, 77, 77, 65, 84, + 73, 79, 78, 128, 83, 85, 77, 77, 65, 84, 73, 79, 206, 83, 85, 77, 65, 83, + 72, 128, 83, 85, 77, 128, 83, 85, 76, 70, 85, 82, 128, 83, 85, 75, 85, + 78, 128, 83, 85, 75, 85, 206, 83, 85, 75, 85, 128, 83, 85, 75, 213, 83, + 85, 73, 84, 65, 66, 76, 69, 128, 83, 85, 73, 212, 83, 85, 72, 85, 82, + 128, 83, 85, 69, 128, 83, 85, 68, 50, 128, 83, 85, 68, 128, 83, 85, 67, + 75, 73, 78, 199, 83, 85, 67, 75, 69, 68, 128, 83, 85, 67, 203, 83, 85, + 67, 67, 69, 69, 68, 83, 128, 83, 85, 67, 67, 69, 69, 68, 211, 83, 85, 67, + 67, 69, 69, 68, 128, 83, 85, 67, 67, 69, 69, 196, 83, 85, 66, 85, 78, 73, + 84, 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, 73, 79, 206, 83, 85, 66, 83, + 84, 73, 84, 85, 84, 69, 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, 197, 83, + 85, 66, 83, 69, 84, 128, 83, 85, 66, 83, 69, 212, 83, 85, 66, 83, 67, 82, + 73, 80, 212, 83, 85, 66, 80, 85, 78, 67, 84, 73, 83, 128, 83, 85, 66, 76, + 73, 78, 69, 65, 210, 83, 85, 66, 76, 73, 77, 65, 84, 73, 79, 78, 128, 83, + 85, 66, 76, 73, 77, 65, 84, 69, 45, 51, 128, 83, 85, 66, 76, 73, 77, 65, + 84, 69, 45, 50, 128, 83, 85, 66, 76, 73, 77, 65, 84, 69, 128, 83, 85, 66, + 76, 73, 77, 65, 84, 197, 83, 85, 66, 74, 79, 73, 78, 69, 82, 128, 83, 85, + 66, 74, 79, 73, 78, 69, 196, 83, 85, 66, 74, 69, 67, 84, 128, 83, 85, 66, + 73, 84, 79, 128, 83, 85, 66, 72, 65, 65, 78, 65, 72, 213, 83, 85, 66, 71, + 82, 79, 85, 80, 128, 83, 85, 66, 71, 82, 79, 85, 208, 83, 85, 66, 128, + 83, 85, 65, 77, 128, 83, 85, 65, 69, 84, 128, 83, 85, 65, 69, 78, 128, + 83, 85, 65, 69, 128, 83, 85, 65, 66, 128, 83, 85, 65, 128, 83, 85, 45, + 56, 128, 83, 85, 45, 55, 128, 83, 85, 45, 54, 128, 83, 85, 45, 53, 128, + 83, 85, 45, 52, 128, 83, 85, 45, 51, 128, 83, 85, 45, 50, 128, 83, 85, + 45, 49, 128, 83, 213, 83, 84, 88, 128, 83, 84, 87, 65, 128, 83, 84, 85, + 80, 65, 128, 83, 84, 85, 70, 70, 69, 196, 83, 84, 85, 68, 89, 128, 83, + 84, 85, 68, 73, 207, 83, 84, 85, 67, 75, 45, 79, 85, 212, 83, 84, 83, + 128, 83, 84, 82, 79, 78, 199, 83, 84, 82, 79, 75, 69, 83, 128, 83, 84, + 82, 79, 75, 69, 211, 83, 84, 82, 79, 75, 69, 45, 57, 128, 83, 84, 82, 79, + 75, 69, 45, 56, 128, 83, 84, 82, 79, 75, 69, 45, 55, 128, 83, 84, 82, 79, + 75, 69, 45, 54, 128, 83, 84, 82, 79, 75, 69, 45, 53, 128, 83, 84, 82, 79, + 75, 69, 45, 52, 128, 83, 84, 82, 79, 75, 69, 45, 51, 128, 83, 84, 82, 79, + 75, 69, 45, 50, 128, 83, 84, 82, 79, 75, 69, 45, 49, 49, 128, 83, 84, 82, + 79, 75, 69, 45, 49, 48, 128, 83, 84, 82, 79, 75, 69, 45, 49, 128, 83, 84, + 82, 79, 75, 197, 83, 84, 82, 73, 80, 69, 128, 83, 84, 82, 73, 78, 71, + 128, 83, 84, 82, 73, 78, 199, 83, 84, 82, 73, 75, 69, 84, 72, 82, 79, 85, + 71, 72, 128, 83, 84, 82, 73, 75, 197, 83, 84, 82, 73, 68, 69, 128, 83, + 84, 82, 73, 67, 84, 76, 217, 83, 84, 82, 69, 84, 67, 72, 69, 196, 83, 84, + 82, 69, 84, 67, 72, 128, 83, 84, 82, 69, 83, 211, 83, 84, 82, 69, 78, 71, + 84, 72, 128, 83, 84, 82, 69, 76, 193, 83, 84, 82, 69, 65, 77, 69, 82, + 128, 83, 84, 82, 65, 87, 66, 69, 82, 82, 89, 128, 83, 84, 82, 65, 87, + 128, 83, 84, 82, 65, 84, 85, 77, 45, 50, 128, 83, 84, 82, 65, 84, 85, 77, + 128, 83, 84, 82, 65, 84, 85, 205, 83, 84, 82, 65, 84, 73, 65, 206, 83, + 84, 82, 65, 78, 78, 79, 128, 83, 84, 82, 65, 78, 78, 207, 83, 84, 82, 65, + 73, 78, 69, 82, 128, 83, 84, 82, 65, 73, 71, 72, 84, 78, 69, 83, 83, 128, + 83, 84, 82, 65, 73, 71, 72, 84, 128, 83, 84, 82, 65, 73, 71, 72, 212, 83, + 84, 82, 65, 73, 70, 128, 83, 84, 82, 65, 71, 71, 73, 83, 77, 65, 84, 65, + 128, 83, 84, 79, 86, 69, 128, 83, 84, 79, 82, 69, 128, 83, 84, 79, 80, + 87, 65, 84, 67, 72, 128, 83, 84, 79, 80, 80, 73, 78, 71, 128, 83, 84, 79, + 80, 80, 65, 71, 69, 128, 83, 84, 79, 80, 73, 84, 83, 65, 128, 83, 84, 79, + 80, 73, 84, 83, 193, 83, 84, 79, 80, 128, 83, 84, 79, 208, 83, 84, 79, + 78, 69, 128, 83, 84, 79, 67, 75, 128, 83, 84, 79, 67, 203, 83, 84, 73, + 82, 82, 85, 208, 83, 84, 73, 77, 77, 69, 128, 83, 84, 73, 76, 204, 83, + 84, 73, 76, 197, 83, 84, 73, 71, 77, 65, 128, 83, 84, 73, 67, 75, 73, 78, + 199, 83, 84, 73, 67, 203, 83, 84, 69, 84, 72, 79, 83, 67, 79, 80, 69, + 128, 83, 84, 69, 82, 69, 79, 128, 83, 84, 69, 80, 128, 83, 84, 69, 78, + 79, 71, 82, 65, 80, 72, 73, 195, 83, 84, 69, 77, 128, 83, 84, 69, 65, 77, + 217, 83, 84, 69, 65, 77, 73, 78, 199, 83, 84, 69, 65, 77, 128, 83, 84, + 69, 65, 205, 83, 84, 65, 86, 82, 79, 85, 128, 83, 84, 65, 86, 82, 79, 83, + 128, 83, 84, 65, 86, 82, 79, 211, 83, 84, 65, 85, 82, 79, 83, 128, 83, + 84, 65, 84, 89, 65, 128, 83, 84, 65, 84, 89, 193, 83, 84, 65, 84, 85, + 197, 83, 84, 65, 84, 73, 79, 78, 128, 83, 84, 65, 84, 69, 82, 83, 128, + 83, 84, 65, 84, 69, 128, 83, 84, 65, 82, 84, 73, 78, 199, 83, 84, 65, 82, + 84, 128, 83, 84, 65, 82, 212, 83, 84, 65, 82, 83, 128, 83, 84, 65, 82, + 82, 69, 196, 83, 84, 65, 82, 75, 128, 83, 84, 65, 82, 128, 83, 84, 65, + 210, 83, 84, 65, 78, 68, 83, 84, 73, 76, 76, 128, 83, 84, 65, 78, 68, 73, + 78, 199, 83, 84, 65, 78, 68, 65, 82, 196, 83, 84, 65, 78, 68, 128, 83, + 84, 65, 78, 128, 83, 84, 65, 77, 80, 69, 196, 83, 84, 65, 76, 76, 73, 79, + 78, 128, 83, 84, 65, 70, 70, 128, 83, 84, 65, 70, 198, 83, 84, 65, 68, + 73, 85, 77, 128, 83, 84, 65, 67, 75, 69, 196, 83, 84, 65, 67, 67, 65, 84, + 79, 128, 83, 84, 65, 67, 67, 65, 84, 73, 83, 83, 73, 77, 79, 128, 83, 84, + 50, 128, 83, 83, 89, 88, 128, 83, 83, 89, 84, 128, 83, 83, 89, 82, 88, + 128, 83, 83, 89, 82, 128, 83, 83, 89, 80, 128, 83, 83, 89, 128, 83, 83, + 85, 88, 128, 83, 83, 85, 85, 128, 83, 83, 85, 84, 128, 83, 83, 85, 80, + 128, 83, 83, 79, 88, 128, 83, 83, 79, 84, 128, 83, 83, 79, 80, 128, 83, + 83, 79, 79, 128, 83, 83, 79, 128, 83, 83, 73, 88, 128, 83, 83, 73, 84, + 128, 83, 83, 73, 80, 128, 83, 83, 73, 73, 128, 83, 83, 73, 69, 88, 128, + 83, 83, 73, 69, 80, 128, 83, 83, 73, 69, 128, 83, 83, 72, 73, 78, 128, + 83, 83, 72, 69, 128, 83, 83, 69, 88, 128, 83, 83, 69, 80, 128, 83, 83, + 69, 69, 128, 83, 83, 65, 88, 128, 83, 83, 65, 85, 128, 83, 83, 65, 84, + 128, 83, 83, 65, 80, 128, 83, 83, 65, 78, 71, 89, 69, 83, 73, 69, 85, 78, + 71, 128, 83, 83, 65, 78, 71, 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, + 128, 83, 83, 65, 78, 71, 84, 73, 75, 69, 85, 84, 45, 80, 73, 69, 85, 80, + 128, 83, 83, 65, 78, 71, 84, 73, 75, 69, 85, 84, 128, 83, 83, 65, 78, 71, + 84, 72, 73, 69, 85, 84, 72, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, + 84, 73, 75, 69, 85, 84, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, 80, + 73, 69, 85, 80, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, 75, 73, 89, + 69, 79, 75, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 83, 83, 65, 78, + 71, 82, 73, 69, 85, 76, 45, 75, 72, 73, 69, 85, 75, 72, 128, 83, 83, 65, + 78, 71, 82, 73, 69, 85, 76, 128, 83, 83, 65, 78, 71, 80, 73, 69, 85, 80, + 128, 83, 83, 65, 78, 71, 78, 73, 69, 85, 78, 128, 83, 83, 65, 78, 71, 77, + 73, 69, 85, 77, 128, 83, 83, 65, 78, 71, 73, 69, 85, 78, 71, 128, 83, 83, + 65, 78, 71, 72, 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 67, 73, 69, 85, + 67, 45, 72, 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, + 128, 83, 83, 65, 78, 71, 65, 82, 65, 69, 65, 128, 83, 83, 65, 73, 128, + 83, 83, 65, 65, 128, 83, 83, 51, 128, 83, 83, 50, 128, 83, 82, 69, 68, + 78, 197, 83, 82, 128, 83, 81, 85, 73, 83, 200, 83, 81, 85, 73, 82, 82, + 69, 204, 83, 81, 85, 73, 71, 71, 76, 197, 83, 81, 85, 73, 68, 128, 83, + 81, 85, 69, 69, 90, 69, 68, 128, 83, 81, 85, 69, 69, 90, 197, 83, 81, 85, + 65, 212, 83, 81, 85, 65, 82, 69, 83, 128, 83, 81, 85, 65, 82, 69, 68, + 128, 83, 81, 85, 65, 82, 69, 128, 83, 80, 89, 128, 83, 80, 87, 65, 128, + 83, 80, 85, 78, 71, 211, 83, 80, 82, 79, 85, 84, 128, 83, 80, 82, 73, 78, + 71, 83, 128, 83, 80, 82, 73, 78, 71, 128, 83, 80, 82, 69, 67, 72, 71, 69, + 83, 65, 78, 199, 83, 80, 82, 69, 65, 68, 128, 83, 80, 82, 69, 65, 196, + 83, 80, 79, 85, 84, 73, 78, 199, 83, 80, 79, 84, 128, 83, 80, 79, 82, 84, + 211, 83, 80, 79, 79, 78, 128, 83, 80, 79, 79, 204, 83, 80, 79, 78, 71, + 69, 128, 83, 80, 79, 128, 83, 80, 76, 73, 84, 84, 73, 78, 199, 83, 80, + 76, 73, 84, 128, 83, 80, 76, 73, 212, 83, 80, 76, 65, 89, 69, 68, 128, + 83, 80, 76, 65, 83, 72, 73, 78, 199, 83, 80, 73, 82, 73, 84, 85, 211, 83, + 80, 73, 82, 73, 84, 128, 83, 80, 73, 82, 73, 212, 83, 80, 73, 82, 65, 78, + 84, 128, 83, 80, 73, 82, 65, 76, 128, 83, 80, 73, 82, 65, 204, 83, 80, + 73, 78, 69, 128, 83, 80, 73, 68, 69, 82, 217, 83, 80, 73, 68, 69, 82, + 128, 83, 80, 73, 68, 69, 210, 83, 80, 73, 67, 69, 128, 83, 80, 73, 128, + 83, 80, 72, 69, 82, 73, 67, 65, 204, 83, 80, 69, 83, 77, 73, 76, 207, 83, + 80, 69, 78, 212, 83, 80, 69, 69, 68, 66, 79, 65, 84, 128, 83, 80, 69, 69, + 67, 72, 128, 83, 80, 69, 69, 67, 200, 83, 80, 69, 67, 73, 65, 76, 128, + 83, 80, 69, 65, 82, 128, 83, 80, 69, 65, 75, 73, 78, 199, 83, 80, 69, 65, + 75, 69, 82, 128, 83, 80, 69, 65, 75, 69, 210, 83, 80, 69, 65, 75, 45, 78, + 79, 45, 69, 86, 73, 204, 83, 80, 69, 128, 83, 80, 65, 84, 72, 73, 128, + 83, 80, 65, 82, 75, 76, 73, 78, 199, 83, 80, 65, 82, 75, 76, 69, 83, 128, + 83, 80, 65, 82, 75, 76, 69, 82, 128, 83, 80, 65, 82, 75, 76, 69, 128, 83, + 80, 65, 71, 72, 69, 84, 84, 73, 128, 83, 80, 65, 68, 69, 83, 128, 83, 80, + 65, 68, 197, 83, 80, 65, 67, 73, 78, 199, 83, 80, 65, 67, 197, 83, 80, + 65, 128, 83, 79, 89, 79, 77, 66, 207, 83, 79, 89, 128, 83, 79, 87, 73, + 76, 207, 83, 79, 87, 128, 83, 79, 85, 84, 72, 69, 82, 206, 83, 79, 85, + 84, 72, 45, 83, 76, 65, 86, 69, 217, 83, 79, 85, 84, 200, 83, 79, 85, 82, + 67, 69, 128, 83, 79, 85, 78, 68, 128, 83, 79, 85, 78, 196, 83, 79, 85, + 78, 65, 80, 128, 83, 79, 85, 128, 83, 79, 83, 128, 83, 79, 82, 79, 67, + 72, 89, 193, 83, 79, 82, 73, 128, 83, 79, 82, 193, 83, 79, 81, 128, 83, + 79, 79, 206, 83, 79, 78, 74, 65, 77, 128, 83, 79, 78, 71, 128, 83, 79, + 78, 128, 83, 79, 77, 80, 69, 78, 199, 83, 79, 77, 128, 83, 79, 205, 83, + 79, 76, 73, 68, 85, 83, 128, 83, 79, 76, 73, 68, 85, 211, 83, 79, 76, 73, + 196, 83, 79, 76, 68, 73, 69, 82, 128, 83, 79, 72, 128, 83, 79, 71, 68, + 73, 65, 206, 83, 79, 70, 84, 87, 65, 82, 69, 45, 70, 85, 78, 67, 84, 73, + 79, 206, 83, 79, 70, 84, 78, 69, 83, 83, 128, 83, 79, 70, 84, 66, 65, 76, + 76, 128, 83, 79, 70, 212, 83, 79, 198, 83, 79, 67, 75, 83, 128, 83, 79, + 67, 73, 69, 84, 89, 128, 83, 79, 67, 67, 69, 210, 83, 79, 65, 80, 128, + 83, 79, 65, 128, 83, 79, 45, 55, 128, 83, 79, 45, 54, 128, 83, 79, 45, + 53, 128, 83, 79, 45, 52, 128, 83, 79, 45, 51, 128, 83, 79, 45, 50, 128, + 83, 79, 45, 49, 128, 83, 207, 83, 78, 79, 87, 77, 65, 78, 128, 83, 78, + 79, 87, 77, 65, 206, 83, 78, 79, 87, 70, 76, 65, 75, 69, 128, 83, 78, 79, + 87, 66, 79, 65, 82, 68, 69, 82, 128, 83, 78, 79, 87, 128, 83, 78, 79, + 215, 83, 78, 79, 85, 84, 128, 83, 78, 79, 85, 212, 83, 78, 69, 69, 90, + 73, 78, 199, 83, 78, 65, 208, 83, 78, 65, 75, 69, 128, 83, 78, 65, 75, + 197, 83, 78, 65, 73, 76, 128, 83, 78, 193, 83, 77, 79, 75, 73, 78, 199, + 83, 77, 73, 82, 75, 73, 78, 199, 83, 77, 73, 76, 73, 78, 199, 83, 77, 73, + 76, 69, 128, 83, 77, 73, 76, 197, 83, 77, 69, 65, 82, 128, 83, 77, 65, + 83, 200, 83, 77, 65, 76, 76, 69, 210, 83, 77, 65, 76, 76, 128, 83, 76, + 85, 82, 128, 83, 76, 79, 90, 72, 73, 84, 73, 69, 128, 83, 76, 79, 90, 72, + 73, 84, 73, 197, 83, 76, 79, 87, 76, 89, 128, 83, 76, 79, 87, 128, 83, + 76, 79, 215, 83, 76, 79, 86, 79, 128, 83, 76, 79, 84, 72, 128, 83, 76, + 79, 212, 83, 76, 79, 80, 73, 78, 199, 83, 76, 79, 80, 69, 128, 83, 76, + 79, 65, 206, 83, 76, 73, 78, 71, 128, 83, 76, 73, 71, 72, 84, 76, 217, + 83, 76, 73, 68, 73, 78, 71, 128, 83, 76, 73, 68, 69, 82, 128, 83, 76, 73, + 68, 69, 128, 83, 76, 73, 67, 69, 128, 83, 76, 73, 67, 197, 83, 76, 69, + 85, 84, 200, 83, 76, 69, 69, 80, 217, 83, 76, 69, 69, 80, 73, 78, 199, + 83, 76, 69, 69, 208, 83, 76, 69, 68, 128, 83, 76, 65, 86, 79, 78, 73, + 195, 83, 76, 65, 86, 69, 128, 83, 76, 65, 83, 72, 128, 83, 76, 65, 83, + 200, 83, 76, 65, 78, 84, 69, 196, 83, 75, 87, 65, 128, 83, 75, 87, 128, + 83, 75, 85, 78, 75, 128, 83, 75, 85, 76, 76, 128, 83, 75, 85, 76, 204, + 83, 75, 79, 66, 65, 128, 83, 75, 76, 73, 82, 79, 206, 83, 75, 73, 78, + 128, 83, 75, 73, 69, 82, 128, 83, 75, 201, 83, 75, 69, 87, 69, 196, 83, + 75, 65, 84, 69, 66, 79, 65, 82, 68, 128, 83, 75, 65, 84, 69, 128, 83, 75, + 65, 77, 69, 89, 84, 83, 193, 83, 75, 128, 83, 74, 69, 128, 83, 73, 90, + 197, 83, 73, 88, 84, 89, 45, 70, 79, 85, 82, 84, 72, 83, 128, 83, 73, 88, + 84, 89, 45, 70, 79, 85, 82, 84, 72, 128, 83, 73, 88, 84, 89, 45, 70, 79, + 85, 82, 84, 200, 83, 73, 88, 84, 89, 128, 83, 73, 88, 84, 217, 83, 73, + 88, 84, 72, 83, 128, 83, 73, 88, 84, 72, 211, 83, 73, 88, 84, 72, 128, + 83, 73, 88, 84, 69, 69, 78, 84, 72, 83, 128, 83, 73, 88, 84, 69, 69, 78, + 84, 72, 45, 50, 128, 83, 73, 88, 84, 69, 69, 78, 84, 72, 45, 49, 128, 83, + 73, 88, 84, 69, 69, 78, 84, 72, 128, 83, 73, 88, 84, 69, 69, 78, 84, 200, + 83, 73, 88, 84, 69, 69, 78, 128, 83, 73, 88, 84, 69, 69, 206, 83, 73, 88, + 45, 84, 72, 73, 82, 84, 89, 128, 83, 73, 88, 45, 83, 84, 82, 73, 78, 199, + 83, 73, 88, 45, 80, 69, 82, 45, 69, 205, 83, 73, 88, 45, 76, 73, 78, 197, + 83, 73, 216, 83, 73, 84, 69, 128, 83, 73, 83, 65, 128, 83, 73, 82, 82, + 65, 72, 128, 83, 73, 82, 73, 78, 71, 85, 128, 83, 73, 79, 83, 45, 84, 72, + 73, 69, 85, 84, 72, 128, 83, 73, 79, 83, 45, 83, 83, 65, 78, 71, 83, 73, + 79, 83, 128, 83, 73, 79, 83, 45, 82, 73, 69, 85, 76, 128, 83, 73, 79, 83, + 45, 80, 73, 69, 85, 80, 45, 75, 73, 89, 69, 79, 75, 128, 83, 73, 79, 83, + 45, 80, 72, 73, 69, 85, 80, 72, 128, 83, 73, 79, 83, 45, 80, 65, 78, 83, + 73, 79, 83, 128, 83, 73, 79, 83, 45, 78, 73, 69, 85, 78, 128, 83, 73, 79, + 83, 45, 77, 73, 69, 85, 77, 128, 83, 73, 79, 83, 45, 75, 72, 73, 69, 85, + 75, 72, 128, 83, 73, 79, 83, 45, 75, 65, 80, 89, 69, 79, 85, 78, 80, 73, + 69, 85, 80, 128, 83, 73, 79, 83, 45, 73, 69, 85, 78, 71, 128, 83, 73, 79, + 83, 45, 72, 73, 69, 85, 72, 128, 83, 73, 79, 83, 45, 67, 73, 69, 85, 67, + 128, 83, 73, 79, 83, 45, 67, 72, 73, 69, 85, 67, 72, 128, 83, 73, 79, + 211, 83, 73, 78, 85, 83, 79, 73, 196, 83, 73, 78, 79, 76, 79, 71, 73, 67, + 65, 204, 83, 73, 78, 78, 89, 73, 73, 89, 72, 69, 128, 83, 73, 78, 75, 73, + 78, 71, 128, 83, 73, 78, 71, 76, 69, 45, 83, 72, 73, 70, 84, 45, 51, 128, + 83, 73, 78, 71, 76, 69, 45, 83, 72, 73, 70, 84, 45, 50, 128, 83, 73, 78, + 71, 76, 69, 45, 76, 73, 78, 197, 83, 73, 78, 71, 76, 69, 128, 83, 73, 78, + 71, 76, 197, 83, 73, 78, 71, 65, 65, 84, 128, 83, 73, 78, 197, 83, 73, + 78, 68, 72, 201, 83, 73, 78, 128, 83, 73, 206, 83, 73, 77, 85, 76, 84, + 65, 78, 69, 79, 85, 83, 128, 83, 73, 77, 85, 76, 84, 65, 78, 69, 79, 85, + 211, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 83, 73, 77, 73, 76, 65, 82, + 128, 83, 73, 77, 73, 76, 65, 210, 83, 73, 77, 65, 78, 83, 73, 211, 83, + 73, 77, 65, 76, 85, 78, 71, 85, 206, 83, 73, 77, 65, 128, 83, 73, 76, 86, + 69, 82, 128, 83, 73, 76, 75, 128, 83, 73, 76, 73, 81, 85, 193, 83, 73, + 76, 72, 79, 85, 69, 84, 84, 69, 128, 83, 73, 76, 72, 79, 85, 69, 84, 84, + 197, 83, 73, 76, 65, 51, 128, 83, 73, 75, 73, 128, 83, 73, 75, 50, 128, + 83, 73, 75, 178, 83, 73, 71, 78, 83, 128, 83, 73, 71, 77, 79, 73, 196, + 83, 73, 71, 77, 65, 128, 83, 73, 71, 77, 193, 83, 73, 71, 69, 204, 83, + 73, 71, 52, 128, 83, 73, 71, 180, 83, 73, 71, 128, 83, 73, 69, 69, 128, + 83, 73, 68, 69, 87, 65, 89, 211, 83, 73, 68, 69, 128, 83, 73, 68, 197, + 83, 73, 68, 68, 72, 73, 128, 83, 73, 68, 68, 72, 65, 77, 128, 83, 73, 68, + 68, 72, 65, 205, 83, 73, 67, 75, 78, 69, 83, 83, 128, 83, 73, 67, 75, 76, + 69, 128, 83, 73, 66, 197, 83, 73, 65, 128, 83, 73, 45, 54, 128, 83, 73, + 45, 53, 128, 83, 73, 45, 52, 128, 83, 73, 45, 51, 128, 83, 73, 45, 50, + 128, 83, 73, 45, 49, 128, 83, 201, 83, 72, 89, 88, 128, 83, 72, 89, 84, + 128, 83, 72, 89, 82, 88, 128, 83, 72, 89, 82, 128, 83, 72, 89, 80, 128, + 83, 72, 89, 69, 128, 83, 72, 89, 65, 128, 83, 72, 89, 128, 83, 72, 87, + 79, 89, 128, 83, 72, 87, 79, 79, 128, 83, 72, 87, 79, 128, 83, 72, 87, + 73, 73, 128, 83, 72, 87, 73, 128, 83, 72, 87, 69, 128, 83, 72, 87, 197, + 83, 72, 87, 65, 65, 128, 83, 72, 87, 65, 128, 83, 72, 86, 128, 83, 72, + 85, 88, 128, 83, 72, 85, 85, 128, 83, 72, 85, 84, 84, 76, 69, 67, 79, 67, + 75, 128, 83, 72, 85, 84, 128, 83, 72, 85, 82, 88, 128, 83, 72, 85, 82, + 128, 83, 72, 85, 80, 128, 83, 72, 85, 79, 88, 128, 83, 72, 85, 79, 80, + 128, 83, 72, 85, 79, 128, 83, 72, 85, 77, 128, 83, 72, 85, 76, 128, 83, + 72, 85, 70, 70, 76, 197, 83, 72, 85, 69, 81, 128, 83, 72, 85, 69, 78, 83, + 72, 85, 69, 84, 128, 83, 72, 85, 66, 85, 82, 128, 83, 72, 85, 65, 78, 71, + 88, 73, 128, 83, 72, 85, 50, 128, 83, 72, 85, 178, 83, 72, 85, 128, 83, + 72, 84, 65, 80, 73, 67, 128, 83, 72, 84, 65, 128, 83, 72, 82, 85, 71, + 128, 83, 72, 82, 79, 79, 128, 83, 72, 82, 79, 128, 83, 72, 82, 73, 78, + 69, 128, 83, 72, 82, 73, 77, 80, 128, 83, 72, 82, 73, 73, 128, 83, 72, + 82, 73, 128, 83, 72, 82, 65, 65, 128, 83, 72, 82, 65, 128, 83, 72, 79, + 89, 128, 83, 72, 79, 88, 128, 83, 72, 79, 87, 69, 82, 128, 83, 72, 79, + 85, 76, 68, 69, 82, 69, 196, 83, 72, 79, 85, 76, 68, 69, 210, 83, 72, 79, + 85, 128, 83, 72, 79, 84, 128, 83, 72, 79, 82, 84, 83, 128, 83, 72, 79, + 82, 84, 211, 83, 72, 79, 82, 84, 72, 65, 78, 196, 83, 72, 79, 82, 84, 69, + 78, 69, 82, 128, 83, 72, 79, 82, 84, 67, 65, 75, 69, 128, 83, 72, 79, 82, + 84, 45, 84, 87, 73, 71, 45, 89, 82, 128, 83, 72, 79, 82, 84, 45, 84, 87, + 73, 71, 45, 84, 89, 210, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 83, + 79, 204, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 79, 83, 211, 83, 72, + 79, 82, 84, 45, 84, 87, 73, 71, 45, 78, 65, 85, 196, 83, 72, 79, 82, 84, + 45, 84, 87, 73, 71, 45, 77, 65, 68, 210, 83, 72, 79, 82, 84, 45, 84, 87, + 73, 71, 45, 72, 65, 71, 65, 76, 204, 83, 72, 79, 82, 84, 45, 84, 87, 73, + 71, 45, 66, 74, 65, 82, 75, 65, 206, 83, 72, 79, 82, 84, 45, 84, 87, 73, + 71, 45, 65, 210, 83, 72, 79, 82, 84, 128, 83, 72, 79, 82, 212, 83, 72, + 79, 81, 128, 83, 72, 79, 209, 83, 72, 79, 80, 80, 73, 78, 199, 83, 72, + 79, 80, 128, 83, 72, 79, 79, 84, 73, 78, 199, 83, 72, 79, 79, 84, 128, + 83, 72, 79, 79, 73, 128, 83, 72, 79, 79, 128, 83, 72, 79, 71, 201, 83, + 72, 79, 199, 83, 72, 79, 69, 83, 128, 83, 72, 79, 69, 128, 83, 72, 79, + 197, 83, 72, 79, 67, 75, 69, 196, 83, 72, 79, 65, 128, 83, 72, 79, 128, + 83, 72, 73, 89, 89, 65, 65, 76, 65, 65, 128, 83, 72, 73, 84, 65, 128, 83, + 72, 73, 84, 193, 83, 72, 73, 82, 212, 83, 72, 73, 82, 65, 69, 128, 83, + 72, 73, 82, 128, 83, 72, 73, 210, 83, 72, 73, 81, 128, 83, 72, 73, 78, + 84, 207, 83, 72, 73, 78, 73, 71, 128, 83, 72, 73, 78, 68, 193, 83, 72, + 73, 206, 83, 72, 73, 77, 65, 128, 83, 72, 73, 77, 193, 83, 72, 73, 77, + 128, 83, 72, 73, 205, 83, 72, 73, 73, 78, 128, 83, 72, 73, 73, 128, 83, + 72, 73, 70, 212, 83, 72, 73, 69, 76, 68, 128, 83, 72, 73, 68, 128, 83, + 72, 73, 196, 83, 72, 72, 65, 128, 83, 72, 72, 193, 83, 72, 69, 88, 128, + 83, 72, 69, 86, 65, 128, 83, 72, 69, 85, 88, 128, 83, 72, 69, 85, 79, 81, 128, 83, 72, 69, 85, 65, 69, 81, 84, 85, 128, 83, 72, 69, 85, 65, 69, 81, 128, 83, 72, 69, 85, 65, 69, 128, 83, 72, 69, 84, 128, 83, 72, 69, 212, 83, 72, 69, 83, 72, 76, 65, 77, 128, 83, 72, 69, 83, 72, 73, 71, 128, 83, @@ -1716,136 +1718,137 @@ static const unsigned char lexicon[] = { 128, 81, 85, 69, 69, 206, 81, 85, 69, 128, 81, 85, 68, 68, 73, 83, 193, 81, 85, 66, 85, 84, 83, 128, 81, 85, 65, 84, 69, 82, 78, 73, 79, 206, 81, 85, 65, 82, 84, 69, 82, 83, 128, 81, 85, 65, 82, 84, 69, 82, 211, 81, 85, - 65, 82, 84, 69, 82, 128, 81, 85, 65, 78, 84, 73, 84, 217, 81, 85, 65, 68, - 82, 85, 80, 76, 197, 81, 85, 65, 68, 82, 65, 78, 84, 128, 81, 85, 65, 68, - 82, 65, 78, 212, 81, 85, 65, 68, 67, 79, 76, 79, 78, 128, 81, 85, 65, 68, - 128, 81, 85, 65, 196, 81, 85, 65, 128, 81, 85, 128, 81, 208, 81, 79, 88, - 128, 81, 79, 84, 128, 81, 79, 80, 72, 128, 81, 79, 80, 65, 128, 81, 79, - 80, 128, 81, 79, 79, 128, 81, 79, 207, 81, 79, 70, 128, 81, 79, 198, 81, - 79, 65, 128, 81, 79, 128, 81, 78, 128, 81, 73, 88, 128, 81, 73, 84, 83, - 65, 128, 81, 73, 84, 128, 81, 73, 80, 128, 81, 73, 73, 128, 81, 73, 70, - 128, 81, 73, 69, 88, 128, 81, 73, 69, 84, 128, 81, 73, 69, 80, 128, 81, - 73, 69, 128, 81, 73, 128, 81, 72, 87, 73, 128, 81, 72, 87, 69, 69, 128, - 81, 72, 87, 69, 128, 81, 72, 87, 65, 65, 128, 81, 72, 87, 65, 128, 81, - 72, 85, 128, 81, 72, 79, 80, 72, 128, 81, 72, 79, 128, 81, 72, 73, 128, - 81, 72, 69, 69, 128, 81, 72, 69, 128, 81, 72, 65, 85, 128, 81, 72, 65, - 65, 128, 81, 72, 65, 128, 81, 71, 65, 128, 81, 69, 84, 65, 78, 65, 128, - 81, 69, 69, 128, 81, 69, 128, 81, 65, 89, 128, 81, 65, 85, 128, 81, 65, - 84, 65, 78, 128, 81, 65, 82, 78, 69, 217, 81, 65, 82, 128, 81, 65, 81, - 128, 81, 65, 80, 72, 128, 81, 65, 77, 65, 84, 83, 128, 81, 65, 77, 65, - 84, 211, 81, 65, 76, 193, 81, 65, 73, 82, 84, 72, 82, 65, 128, 81, 65, - 73, 128, 81, 65, 70, 128, 81, 65, 198, 81, 65, 68, 77, 65, 128, 81, 65, - 65, 73, 128, 81, 65, 65, 70, 85, 128, 81, 65, 65, 70, 128, 81, 48, 48, - 55, 128, 81, 48, 48, 54, 128, 81, 48, 48, 53, 128, 81, 48, 48, 52, 128, - 81, 48, 48, 51, 128, 81, 48, 48, 50, 128, 81, 48, 48, 49, 128, 80, 90, - 128, 80, 89, 88, 128, 80, 89, 84, 128, 80, 89, 82, 88, 128, 80, 89, 82, - 128, 80, 89, 80, 128, 80, 87, 79, 89, 128, 80, 87, 79, 79, 128, 80, 87, - 79, 128, 80, 87, 207, 80, 87, 73, 73, 128, 80, 87, 73, 128, 80, 87, 69, - 69, 128, 80, 87, 69, 128, 80, 87, 65, 65, 128, 80, 87, 128, 80, 86, 128, - 80, 85, 90, 90, 76, 197, 80, 85, 88, 128, 80, 85, 85, 84, 128, 80, 85, - 85, 128, 80, 85, 84, 82, 69, 70, 65, 67, 84, 73, 79, 78, 128, 80, 85, 84, - 78, 65, 89, 65, 128, 80, 85, 84, 128, 80, 85, 212, 80, 85, 83, 72, 80, - 73, 78, 128, 80, 85, 83, 72, 80, 73, 75, 65, 128, 80, 85, 83, 72, 73, 78, - 199, 80, 85, 82, 88, 128, 80, 85, 82, 83, 69, 128, 80, 85, 82, 80, 76, - 197, 80, 85, 82, 78, 65, 77, 65, 128, 80, 85, 82, 73, 84, 89, 128, 80, - 85, 82, 73, 70, 89, 128, 80, 85, 82, 128, 80, 85, 81, 128, 80, 85, 80, - 128, 80, 85, 79, 88, 128, 80, 85, 79, 80, 128, 80, 85, 79, 128, 80, 85, - 78, 71, 65, 65, 77, 128, 80, 85, 78, 71, 128, 80, 85, 78, 67, 84, 85, - 211, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 128, 80, 85, 78, 67, 84, - 85, 65, 84, 73, 79, 206, 80, 85, 77, 80, 128, 80, 85, 77, 128, 80, 85, - 70, 70, 69, 68, 128, 80, 85, 69, 128, 80, 85, 67, 75, 128, 80, 85, 66, - 76, 73, 195, 80, 85, 194, 80, 85, 65, 81, 128, 80, 85, 65, 69, 128, 80, - 85, 65, 67, 72, 85, 197, 80, 85, 50, 128, 80, 85, 49, 128, 80, 85, 128, - 80, 84, 72, 65, 72, 193, 80, 84, 69, 128, 80, 83, 73, 76, 201, 80, 83, - 73, 70, 73, 83, 84, 79, 83, 89, 78, 65, 71, 77, 65, 128, 80, 83, 73, 70, - 73, 83, 84, 79, 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 65, 128, 80, 83, - 73, 70, 73, 83, 84, 79, 206, 80, 83, 73, 70, 73, 83, 84, 79, 76, 89, 71, - 73, 83, 77, 65, 128, 80, 83, 73, 128, 80, 83, 65, 76, 84, 69, 210, 80, - 83, 128, 80, 82, 79, 86, 69, 128, 80, 82, 79, 84, 79, 86, 65, 82, 89, - 211, 80, 82, 79, 84, 79, 211, 80, 82, 79, 84, 69, 67, 84, 69, 196, 80, - 82, 79, 83, 84, 65, 89, 65, 128, 80, 82, 79, 83, 71, 69, 71, 82, 65, 77, - 77, 69, 78, 73, 128, 80, 82, 79, 83, 69, 82, 80, 73, 78, 65, 128, 80, 82, - 79, 80, 79, 82, 84, 73, 79, 78, 65, 204, 80, 82, 79, 80, 79, 82, 84, 73, - 79, 78, 128, 80, 82, 79, 80, 69, 82, 84, 217, 80, 82, 79, 80, 69, 76, 76, - 69, 210, 80, 82, 79, 79, 70, 128, 80, 82, 79, 76, 79, 78, 71, 69, 196, - 80, 82, 79, 76, 65, 84, 73, 79, 78, 197, 80, 82, 79, 74, 69, 67, 84, 79, - 82, 128, 80, 82, 79, 74, 69, 67, 84, 73, 86, 69, 128, 80, 82, 79, 74, 69, - 67, 84, 73, 79, 78, 128, 80, 82, 79, 72, 73, 66, 73, 84, 69, 196, 80, 82, - 79, 71, 82, 69, 83, 83, 128, 80, 82, 79, 71, 82, 65, 205, 80, 82, 79, 70, - 79, 85, 78, 68, 128, 80, 82, 79, 68, 85, 67, 84, 128, 80, 82, 79, 68, 85, - 67, 212, 80, 82, 79, 66, 73, 78, 199, 80, 82, 73, 90, 78, 65, 203, 80, - 82, 73, 86, 65, 84, 69, 128, 80, 82, 73, 86, 65, 84, 197, 80, 82, 73, 86, - 65, 67, 217, 80, 82, 73, 83, 72, 84, 72, 65, 77, 65, 84, 82, 193, 80, 82, - 73, 78, 84, 83, 128, 80, 82, 73, 78, 84, 69, 82, 128, 80, 82, 73, 78, 84, - 69, 210, 80, 82, 73, 78, 84, 128, 80, 82, 73, 78, 212, 80, 82, 73, 78, - 67, 69, 83, 83, 128, 80, 82, 73, 78, 67, 69, 128, 80, 82, 73, 77, 69, - 128, 80, 82, 73, 77, 197, 80, 82, 69, 86, 73, 79, 85, 211, 80, 82, 69, - 84, 90, 69, 76, 128, 80, 82, 69, 83, 83, 69, 196, 80, 82, 69, 83, 69, 84, - 128, 80, 82, 69, 83, 69, 78, 84, 65, 84, 73, 79, 206, 80, 82, 69, 83, 67, - 82, 73, 80, 84, 73, 79, 206, 80, 82, 69, 80, 79, 78, 68, 69, 82, 65, 78, - 67, 69, 128, 80, 82, 69, 78, 75, 72, 65, 128, 80, 82, 69, 71, 78, 65, 78, - 212, 80, 82, 69, 70, 73, 88, 69, 196, 80, 82, 69, 70, 65, 67, 197, 80, - 82, 69, 67, 73, 80, 73, 84, 65, 84, 69, 128, 80, 82, 69, 67, 69, 68, 73, - 78, 199, 80, 82, 69, 67, 69, 68, 69, 83, 128, 80, 82, 69, 67, 69, 68, 69, - 211, 80, 82, 69, 67, 69, 68, 69, 196, 80, 82, 69, 67, 69, 68, 69, 128, - 80, 82, 69, 67, 69, 68, 197, 80, 82, 65, 89, 69, 210, 80, 82, 65, 77, 45, - 80, 73, 73, 128, 80, 82, 65, 77, 45, 80, 73, 201, 80, 82, 65, 77, 45, 77, - 85, 79, 89, 128, 80, 82, 65, 77, 45, 77, 85, 79, 217, 80, 82, 65, 77, 45, - 66, 85, 79, 78, 128, 80, 82, 65, 77, 45, 66, 85, 79, 206, 80, 82, 65, 77, - 45, 66, 69, 73, 128, 80, 82, 65, 77, 45, 66, 69, 201, 80, 82, 65, 77, - 128, 80, 82, 65, 205, 80, 82, 128, 80, 80, 86, 128, 80, 80, 77, 128, 80, - 80, 65, 128, 80, 79, 89, 128, 80, 79, 88, 128, 80, 79, 87, 69, 82, 211, - 80, 79, 87, 69, 82, 128, 80, 79, 87, 69, 210, 80, 79, 87, 68, 69, 82, 69, - 196, 80, 79, 87, 68, 69, 82, 128, 80, 79, 86, 89, 83, 72, 69, 128, 80, - 79, 86, 89, 83, 72, 197, 80, 79, 86, 79, 68, 78, 89, 128, 80, 79, 85, 82, - 73, 78, 199, 80, 79, 85, 78, 196, 80, 79, 85, 76, 84, 82, 217, 80, 79, - 85, 67, 72, 128, 80, 79, 84, 84, 69, 196, 80, 79, 84, 65, 84, 79, 128, - 80, 79, 84, 65, 66, 76, 197, 80, 79, 212, 80, 79, 83, 84, 80, 79, 83, 73, - 84, 73, 79, 206, 80, 79, 83, 84, 66, 79, 88, 128, 80, 79, 83, 84, 65, - 204, 80, 79, 83, 84, 128, 80, 79, 83, 212, 80, 79, 83, 83, 69, 83, 83, - 73, 79, 78, 128, 80, 79, 83, 83, 69, 83, 83, 73, 79, 206, 80, 79, 83, 73, - 84, 73, 79, 78, 83, 128, 80, 79, 83, 73, 84, 73, 79, 78, 128, 80, 79, 83, - 69, 73, 68, 79, 78, 128, 80, 79, 82, 84, 65, 66, 76, 197, 80, 79, 82, 82, - 69, 67, 84, 85, 83, 128, 80, 79, 82, 82, 69, 67, 84, 85, 211, 80, 79, 80, - 80, 73, 78, 199, 80, 79, 80, 80, 69, 82, 128, 80, 79, 80, 67, 79, 82, 78, - 128, 80, 79, 80, 128, 80, 79, 208, 80, 79, 79, 68, 76, 69, 128, 80, 79, - 79, 128, 80, 79, 78, 68, 79, 128, 80, 79, 206, 80, 79, 77, 77, 69, 69, - 128, 80, 79, 77, 77, 69, 197, 80, 79, 76, 85, 80, 79, 86, 79, 68, 78, 65, - 89, 65, 128, 80, 79, 76, 79, 128, 80, 79, 76, 78, 65, 89, 65, 128, 80, - 79, 76, 76, 85, 128, 80, 79, 76, 75, 85, 76, 73, 90, 77, 89, 128, 80, 79, - 76, 73, 83, 72, 128, 80, 79, 76, 73, 83, 200, 80, 79, 76, 73, 67, 197, - 80, 79, 76, 201, 80, 79, 76, 69, 128, 80, 79, 76, 197, 80, 79, 75, 82, - 89, 84, 73, 69, 128, 80, 79, 75, 79, 74, 73, 128, 80, 79, 73, 78, 84, - 211, 80, 79, 73, 78, 84, 79, 128, 80, 79, 73, 78, 84, 69, 82, 128, 80, - 79, 73, 78, 84, 69, 196, 80, 79, 73, 78, 84, 128, 80, 79, 73, 78, 212, - 80, 79, 69, 84, 82, 217, 80, 79, 69, 84, 73, 195, 80, 79, 68, 86, 69, 82, - 84, 75, 65, 128, 80, 79, 68, 67, 72, 65, 83, 72, 73, 69, 77, 128, 80, 79, - 68, 67, 72, 65, 83, 72, 73, 69, 128, 80, 79, 68, 67, 72, 65, 83, 72, 73, - 197, 80, 79, 68, 65, 84, 85, 83, 128, 80, 79, 67, 75, 69, 212, 80, 79, - 65, 128, 80, 207, 80, 78, 69, 85, 77, 65, 84, 65, 128, 80, 76, 85, 84, - 207, 80, 76, 85, 84, 65, 128, 80, 76, 85, 83, 45, 77, 73, 78, 85, 211, - 80, 76, 85, 83, 128, 80, 76, 85, 82, 65, 76, 128, 80, 76, 85, 78, 71, 69, - 82, 128, 80, 76, 85, 77, 69, 196, 80, 76, 85, 77, 128, 80, 76, 85, 75, - 128, 80, 76, 85, 71, 128, 80, 76, 85, 128, 80, 76, 79, 87, 128, 80, 76, - 79, 80, 72, 85, 128, 80, 76, 72, 65, 85, 128, 80, 76, 69, 84, 72, 82, 79, - 78, 128, 80, 76, 69, 65, 68, 73, 78, 199, 80, 76, 68, 128, 80, 76, 65, - 89, 73, 78, 199, 80, 76, 65, 89, 71, 82, 79, 85, 78, 196, 80, 76, 65, 84, - 69, 128, 80, 76, 65, 83, 84, 73, 67, 83, 128, 80, 76, 65, 78, 84, 128, - 80, 76, 65, 78, 69, 84, 128, 80, 76, 65, 78, 69, 128, 80, 76, 65, 78, 67, - 203, 80, 76, 65, 75, 128, 80, 76, 65, 71, 73, 79, 211, 80, 76, 65, 67, - 69, 72, 79, 76, 68, 69, 82, 128, 80, 76, 65, 67, 69, 72, 79, 76, 68, 69, - 210, 80, 76, 65, 67, 197, 80, 76, 65, 67, 65, 82, 68, 128, 80, 76, 65, - 128, 80, 73, 90, 90, 73, 67, 65, 84, 79, 128, 80, 73, 90, 90, 65, 128, - 80, 73, 88, 128, 80, 73, 87, 82, 128, 80, 73, 84, 67, 72, 70, 79, 82, 75, - 128, 80, 73, 84, 67, 72, 70, 79, 82, 203, 80, 73, 84, 128, 80, 73, 83, - 84, 79, 76, 128, 80, 73, 83, 69, 76, 69, 72, 128, 80, 73, 83, 67, 69, 83, - 128, 80, 73, 82, 73, 71, 128, 80, 73, 82, 73, 199, 80, 73, 82, 73, 69, - 69, 78, 128, 80, 73, 82, 65, 67, 89, 128, 80, 73, 82, 50, 128, 80, 73, - 80, 73, 78, 71, 128, 80, 73, 80, 65, 69, 77, 71, 66, 73, 69, 69, 128, 80, - 73, 80, 65, 69, 77, 66, 65, 128, 80, 73, 80, 128, 80, 73, 78, 87, 72, 69, - 69, 204, 80, 73, 78, 69, 65, 80, 80, 76, 69, 128, 80, 73, 78, 197, 80, - 73, 78, 67, 72, 73, 78, 199, 80, 73, 78, 67, 72, 69, 196, 80, 73, 78, 65, - 84, 65, 128, 80, 73, 78, 65, 82, 66, 79, 82, 65, 83, 128, 80, 73, 76, 76, + 65, 82, 84, 69, 82, 128, 81, 85, 65, 79, 65, 82, 128, 81, 85, 65, 78, 84, + 73, 84, 217, 81, 85, 65, 68, 82, 85, 80, 76, 197, 81, 85, 65, 68, 82, 65, + 78, 84, 128, 81, 85, 65, 68, 82, 65, 78, 212, 81, 85, 65, 68, 67, 79, 76, + 79, 78, 128, 81, 85, 65, 68, 128, 81, 85, 65, 196, 81, 85, 65, 128, 81, + 85, 128, 81, 208, 81, 79, 88, 128, 81, 79, 84, 128, 81, 79, 80, 72, 128, + 81, 79, 80, 65, 128, 81, 79, 80, 128, 81, 79, 79, 128, 81, 79, 207, 81, + 79, 70, 128, 81, 79, 198, 81, 79, 65, 128, 81, 79, 128, 81, 78, 128, 81, + 73, 88, 128, 81, 73, 84, 83, 65, 128, 81, 73, 84, 128, 81, 73, 80, 128, + 81, 73, 73, 128, 81, 73, 70, 128, 81, 73, 69, 88, 128, 81, 73, 69, 84, + 128, 81, 73, 69, 80, 128, 81, 73, 69, 128, 81, 73, 128, 81, 72, 87, 73, + 128, 81, 72, 87, 69, 69, 128, 81, 72, 87, 69, 128, 81, 72, 87, 65, 65, + 128, 81, 72, 87, 65, 128, 81, 72, 85, 128, 81, 72, 79, 80, 72, 128, 81, + 72, 79, 128, 81, 72, 73, 128, 81, 72, 69, 69, 128, 81, 72, 69, 128, 81, + 72, 65, 85, 128, 81, 72, 65, 65, 128, 81, 72, 65, 128, 81, 71, 65, 128, + 81, 69, 84, 65, 78, 65, 128, 81, 69, 69, 128, 81, 69, 128, 81, 65, 89, + 128, 81, 65, 85, 128, 81, 65, 84, 65, 78, 128, 81, 65, 83, 82, 128, 81, + 65, 82, 78, 69, 217, 81, 65, 82, 128, 81, 65, 81, 128, 81, 65, 80, 72, + 128, 81, 65, 77, 65, 84, 83, 128, 81, 65, 77, 65, 84, 211, 81, 65, 76, + 193, 81, 65, 73, 82, 84, 72, 82, 65, 128, 81, 65, 73, 128, 81, 65, 70, + 128, 81, 65, 198, 81, 65, 68, 77, 65, 128, 81, 65, 65, 73, 128, 81, 65, + 65, 70, 85, 128, 81, 65, 65, 70, 128, 81, 48, 48, 55, 128, 81, 48, 48, + 54, 128, 81, 48, 48, 53, 128, 81, 48, 48, 52, 128, 81, 48, 48, 51, 128, + 81, 48, 48, 50, 128, 81, 48, 48, 49, 128, 80, 90, 128, 80, 89, 88, 128, + 80, 89, 84, 128, 80, 89, 82, 88, 128, 80, 89, 82, 128, 80, 89, 80, 128, + 80, 87, 79, 89, 128, 80, 87, 79, 79, 128, 80, 87, 79, 128, 80, 87, 207, + 80, 87, 73, 73, 128, 80, 87, 73, 128, 80, 87, 69, 69, 128, 80, 87, 69, + 128, 80, 87, 65, 65, 128, 80, 87, 128, 80, 86, 128, 80, 85, 90, 90, 76, + 197, 80, 85, 88, 128, 80, 85, 85, 84, 128, 80, 85, 85, 128, 80, 85, 84, + 82, 69, 70, 65, 67, 84, 73, 79, 78, 128, 80, 85, 84, 78, 65, 89, 65, 128, + 80, 85, 84, 128, 80, 85, 212, 80, 85, 83, 72, 80, 73, 78, 128, 80, 85, + 83, 72, 80, 73, 75, 65, 128, 80, 85, 83, 72, 73, 78, 199, 80, 85, 82, 88, + 128, 80, 85, 82, 83, 69, 128, 80, 85, 82, 80, 76, 197, 80, 85, 82, 78, + 65, 77, 65, 128, 80, 85, 82, 73, 84, 89, 128, 80, 85, 82, 73, 70, 89, + 128, 80, 85, 82, 128, 80, 85, 81, 128, 80, 85, 80, 128, 80, 85, 79, 88, + 128, 80, 85, 79, 80, 128, 80, 85, 79, 128, 80, 85, 78, 71, 65, 65, 77, + 128, 80, 85, 78, 71, 128, 80, 85, 78, 67, 84, 85, 211, 80, 85, 78, 67, + 84, 85, 65, 84, 73, 79, 78, 128, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, + 206, 80, 85, 77, 80, 128, 80, 85, 77, 128, 80, 85, 70, 70, 69, 68, 128, + 80, 85, 69, 128, 80, 85, 67, 75, 128, 80, 85, 66, 76, 73, 195, 80, 85, + 194, 80, 85, 65, 81, 128, 80, 85, 65, 69, 128, 80, 85, 65, 67, 72, 85, + 197, 80, 85, 50, 128, 80, 85, 49, 128, 80, 85, 128, 80, 84, 72, 65, 72, + 193, 80, 84, 69, 128, 80, 83, 73, 76, 201, 80, 83, 73, 70, 73, 83, 84, + 79, 83, 89, 78, 65, 71, 77, 65, 128, 80, 83, 73, 70, 73, 83, 84, 79, 80, + 65, 82, 65, 75, 65, 76, 69, 83, 77, 65, 128, 80, 83, 73, 70, 73, 83, 84, + 79, 206, 80, 83, 73, 70, 73, 83, 84, 79, 76, 89, 71, 73, 83, 77, 65, 128, + 80, 83, 73, 128, 80, 83, 65, 76, 84, 69, 210, 80, 83, 128, 80, 82, 79, + 86, 69, 128, 80, 82, 79, 84, 79, 86, 65, 82, 89, 211, 80, 82, 79, 84, 79, + 211, 80, 82, 79, 84, 69, 67, 84, 69, 196, 80, 82, 79, 83, 84, 65, 89, 65, + 128, 80, 82, 79, 83, 71, 69, 71, 82, 65, 77, 77, 69, 78, 73, 128, 80, 82, + 79, 83, 69, 82, 80, 73, 78, 65, 128, 80, 82, 79, 80, 79, 82, 84, 73, 79, + 78, 65, 204, 80, 82, 79, 80, 79, 82, 84, 73, 79, 78, 128, 80, 82, 79, 80, + 69, 82, 84, 217, 80, 82, 79, 80, 69, 76, 76, 69, 210, 80, 82, 79, 79, 70, + 128, 80, 82, 79, 76, 79, 78, 71, 69, 196, 80, 82, 79, 76, 65, 84, 73, 79, + 78, 197, 80, 82, 79, 74, 69, 67, 84, 79, 82, 128, 80, 82, 79, 74, 69, 67, + 84, 73, 86, 69, 128, 80, 82, 79, 74, 69, 67, 84, 73, 79, 78, 128, 80, 82, + 79, 72, 73, 66, 73, 84, 69, 196, 80, 82, 79, 71, 82, 69, 83, 83, 128, 80, + 82, 79, 71, 82, 65, 205, 80, 82, 79, 70, 79, 85, 78, 68, 128, 80, 82, 79, + 68, 85, 67, 84, 128, 80, 82, 79, 68, 85, 67, 212, 80, 82, 79, 66, 73, 78, + 199, 80, 82, 73, 90, 78, 65, 203, 80, 82, 73, 86, 65, 84, 69, 128, 80, + 82, 73, 86, 65, 84, 197, 80, 82, 73, 86, 65, 67, 217, 80, 82, 73, 83, 72, + 84, 72, 65, 77, 65, 84, 82, 193, 80, 82, 73, 78, 84, 83, 128, 80, 82, 73, + 78, 84, 69, 82, 128, 80, 82, 73, 78, 84, 69, 210, 80, 82, 73, 78, 84, + 128, 80, 82, 73, 78, 212, 80, 82, 73, 78, 67, 69, 83, 83, 128, 80, 82, + 73, 78, 67, 69, 128, 80, 82, 73, 77, 69, 128, 80, 82, 73, 77, 197, 80, + 82, 69, 86, 73, 79, 85, 211, 80, 82, 69, 84, 90, 69, 76, 128, 80, 82, 69, + 83, 83, 69, 196, 80, 82, 69, 83, 69, 84, 128, 80, 82, 69, 83, 69, 78, 84, + 65, 84, 73, 79, 206, 80, 82, 69, 83, 67, 82, 73, 80, 84, 73, 79, 206, 80, + 82, 69, 80, 79, 78, 68, 69, 82, 65, 78, 67, 69, 128, 80, 82, 69, 78, 75, + 72, 65, 128, 80, 82, 69, 71, 78, 65, 78, 212, 80, 82, 69, 70, 73, 88, 69, + 196, 80, 82, 69, 70, 65, 67, 197, 80, 82, 69, 67, 73, 80, 73, 84, 65, 84, + 69, 128, 80, 82, 69, 67, 69, 68, 73, 78, 199, 80, 82, 69, 67, 69, 68, 69, + 83, 128, 80, 82, 69, 67, 69, 68, 69, 211, 80, 82, 69, 67, 69, 68, 69, + 196, 80, 82, 69, 67, 69, 68, 69, 128, 80, 82, 69, 67, 69, 68, 197, 80, + 82, 65, 89, 69, 210, 80, 82, 65, 77, 45, 80, 73, 73, 128, 80, 82, 65, 77, + 45, 80, 73, 201, 80, 82, 65, 77, 45, 77, 85, 79, 89, 128, 80, 82, 65, 77, + 45, 77, 85, 79, 217, 80, 82, 65, 77, 45, 66, 85, 79, 78, 128, 80, 82, 65, + 77, 45, 66, 85, 79, 206, 80, 82, 65, 77, 45, 66, 69, 73, 128, 80, 82, 65, + 77, 45, 66, 69, 201, 80, 82, 65, 77, 128, 80, 82, 65, 205, 80, 82, 128, + 80, 80, 86, 128, 80, 80, 77, 128, 80, 80, 65, 128, 80, 79, 89, 128, 80, + 79, 88, 128, 80, 79, 87, 69, 82, 211, 80, 79, 87, 69, 82, 128, 80, 79, + 87, 69, 210, 80, 79, 87, 68, 69, 82, 69, 196, 80, 79, 87, 68, 69, 82, + 128, 80, 79, 86, 89, 83, 72, 69, 128, 80, 79, 86, 89, 83, 72, 197, 80, + 79, 86, 79, 68, 78, 89, 128, 80, 79, 85, 82, 73, 78, 199, 80, 79, 85, 78, + 196, 80, 79, 85, 76, 84, 82, 217, 80, 79, 85, 67, 72, 128, 80, 79, 84, + 84, 69, 196, 80, 79, 84, 65, 84, 79, 128, 80, 79, 84, 65, 66, 76, 197, + 80, 79, 212, 80, 79, 83, 84, 80, 79, 83, 73, 84, 73, 79, 206, 80, 79, 83, + 84, 66, 79, 88, 128, 80, 79, 83, 84, 65, 204, 80, 79, 83, 84, 128, 80, + 79, 83, 212, 80, 79, 83, 83, 69, 83, 83, 73, 79, 78, 128, 80, 79, 83, 83, + 69, 83, 83, 73, 79, 206, 80, 79, 83, 73, 84, 73, 79, 78, 83, 128, 80, 79, + 83, 73, 84, 73, 79, 78, 128, 80, 79, 83, 69, 73, 68, 79, 78, 128, 80, 79, + 82, 84, 65, 66, 76, 197, 80, 79, 82, 82, 69, 67, 84, 85, 83, 128, 80, 79, + 82, 82, 69, 67, 84, 85, 211, 80, 79, 80, 80, 73, 78, 199, 80, 79, 80, 80, + 69, 82, 128, 80, 79, 80, 67, 79, 82, 78, 128, 80, 79, 80, 128, 80, 79, + 208, 80, 79, 79, 68, 76, 69, 128, 80, 79, 79, 128, 80, 79, 78, 68, 79, + 128, 80, 79, 206, 80, 79, 77, 77, 69, 69, 128, 80, 79, 77, 77, 69, 197, + 80, 79, 76, 85, 80, 79, 86, 79, 68, 78, 65, 89, 65, 128, 80, 79, 76, 79, + 128, 80, 79, 76, 78, 65, 89, 65, 128, 80, 79, 76, 76, 85, 128, 80, 79, + 76, 75, 85, 76, 73, 90, 77, 89, 128, 80, 79, 76, 73, 83, 72, 128, 80, 79, + 76, 73, 83, 200, 80, 79, 76, 73, 67, 197, 80, 79, 76, 201, 80, 79, 76, + 69, 128, 80, 79, 76, 197, 80, 79, 75, 82, 89, 84, 73, 69, 128, 80, 79, + 75, 79, 74, 73, 128, 80, 79, 73, 78, 84, 211, 80, 79, 73, 78, 84, 79, + 128, 80, 79, 73, 78, 84, 69, 82, 128, 80, 79, 73, 78, 84, 69, 196, 80, + 79, 73, 78, 84, 128, 80, 79, 73, 78, 212, 80, 79, 69, 84, 82, 217, 80, + 79, 69, 84, 73, 195, 80, 79, 68, 86, 69, 82, 84, 75, 65, 128, 80, 79, 68, + 67, 72, 65, 83, 72, 73, 69, 77, 128, 80, 79, 68, 67, 72, 65, 83, 72, 73, + 69, 128, 80, 79, 68, 67, 72, 65, 83, 72, 73, 197, 80, 79, 68, 65, 84, 85, + 83, 128, 80, 79, 67, 75, 69, 212, 80, 79, 65, 128, 80, 207, 80, 78, 69, + 85, 77, 65, 84, 65, 128, 80, 76, 85, 84, 207, 80, 76, 85, 84, 65, 128, + 80, 76, 85, 83, 45, 77, 73, 78, 85, 211, 80, 76, 85, 83, 128, 80, 76, 85, + 82, 65, 76, 128, 80, 76, 85, 78, 71, 69, 82, 128, 80, 76, 85, 77, 69, + 196, 80, 76, 85, 77, 128, 80, 76, 85, 75, 128, 80, 76, 85, 71, 128, 80, + 76, 85, 128, 80, 76, 79, 87, 128, 80, 76, 79, 80, 72, 85, 128, 80, 76, + 72, 65, 85, 128, 80, 76, 69, 84, 72, 82, 79, 78, 128, 80, 76, 69, 65, 68, + 73, 78, 199, 80, 76, 68, 128, 80, 76, 65, 89, 73, 78, 199, 80, 76, 65, + 89, 71, 82, 79, 85, 78, 196, 80, 76, 65, 84, 69, 128, 80, 76, 65, 83, 84, + 73, 67, 83, 128, 80, 76, 65, 78, 84, 128, 80, 76, 65, 78, 69, 84, 128, + 80, 76, 65, 78, 69, 128, 80, 76, 65, 78, 67, 203, 80, 76, 65, 75, 128, + 80, 76, 65, 71, 73, 79, 211, 80, 76, 65, 67, 69, 72, 79, 76, 68, 69, 82, + 128, 80, 76, 65, 67, 69, 72, 79, 76, 68, 69, 210, 80, 76, 65, 67, 197, + 80, 76, 65, 67, 65, 82, 68, 128, 80, 76, 65, 128, 80, 73, 90, 90, 73, 67, + 65, 84, 79, 128, 80, 73, 90, 90, 65, 128, 80, 73, 88, 128, 80, 73, 87, + 82, 128, 80, 73, 84, 67, 72, 70, 79, 82, 75, 128, 80, 73, 84, 67, 72, 70, + 79, 82, 203, 80, 73, 84, 128, 80, 73, 83, 84, 79, 76, 128, 80, 73, 83, + 69, 76, 69, 72, 128, 80, 73, 83, 67, 69, 83, 128, 80, 73, 82, 73, 71, + 128, 80, 73, 82, 73, 199, 80, 73, 82, 73, 69, 69, 78, 128, 80, 73, 82, + 65, 67, 89, 128, 80, 73, 82, 50, 128, 80, 73, 80, 73, 78, 71, 128, 80, + 73, 80, 65, 69, 77, 71, 66, 73, 69, 69, 128, 80, 73, 80, 65, 69, 77, 66, + 65, 128, 80, 73, 80, 128, 80, 73, 78, 87, 72, 69, 69, 204, 80, 73, 78, + 203, 80, 73, 78, 69, 65, 80, 80, 76, 69, 128, 80, 73, 78, 197, 80, 73, + 78, 67, 72, 73, 78, 199, 80, 73, 78, 67, 72, 69, 196, 80, 73, 78, 65, 84, + 65, 128, 80, 73, 78, 65, 82, 66, 79, 82, 65, 83, 128, 80, 73, 76, 76, 128, 80, 73, 76, 197, 80, 73, 76, 67, 82, 79, 215, 80, 73, 75, 85, 82, 85, 128, 80, 73, 75, 79, 128, 80, 73, 71, 128, 80, 73, 199, 80, 73, 69, 88, 128, 80, 73, 69, 85, 80, 45, 84, 72, 73, 69, 85, 84, 72, 128, 80, 73, @@ -1916,2286 +1919,2298 @@ static const unsigned char lexicon[] = { 65, 76, 128, 80, 69, 68, 69, 83, 84, 65, 204, 80, 69, 68, 65, 204, 80, 69, 65, 78, 85, 84, 83, 128, 80, 69, 65, 75, 211, 80, 69, 65, 67, 79, 67, 75, 128, 80, 69, 65, 67, 72, 128, 80, 69, 65, 67, 69, 128, 80, 69, 65, - 67, 197, 80, 68, 73, 128, 80, 68, 70, 128, 80, 68, 128, 80, 67, 128, 80, - 65, 90, 69, 82, 128, 80, 65, 89, 69, 82, 79, 75, 128, 80, 65, 89, 65, 78, - 78, 65, 128, 80, 65, 89, 128, 80, 65, 88, 128, 80, 65, 87, 78, 128, 80, - 65, 87, 206, 80, 65, 215, 80, 65, 86, 73, 89, 65, 78, 73, 128, 80, 65, - 85, 83, 197, 80, 65, 85, 75, 128, 80, 65, 85, 128, 80, 65, 213, 80, 65, - 84, 84, 217, 80, 65, 84, 84, 69, 82, 78, 128, 80, 65, 84, 72, 65, 77, 65, - 83, 65, 84, 128, 80, 65, 84, 72, 65, 75, 75, 85, 128, 80, 65, 84, 200, - 80, 65, 84, 65, 75, 128, 80, 65, 84, 65, 72, 128, 80, 65, 84, 128, 80, - 65, 83, 85, 81, 128, 80, 65, 83, 83, 80, 79, 82, 212, 80, 65, 83, 83, 73, - 86, 69, 45, 80, 85, 76, 76, 45, 85, 80, 45, 79, 85, 84, 80, 85, 212, 80, - 65, 83, 83, 73, 86, 69, 45, 80, 85, 76, 76, 45, 68, 79, 87, 78, 45, 79, - 85, 84, 80, 85, 212, 80, 65, 83, 83, 73, 77, 66, 65, 78, 71, 128, 80, 65, - 83, 83, 69, 78, 71, 69, 210, 80, 65, 83, 83, 69, 196, 80, 65, 83, 72, 84, - 65, 128, 80, 65, 83, 72, 65, 69, 128, 80, 65, 83, 69, 81, 128, 80, 65, - 83, 65, 78, 71, 65, 206, 80, 65, 82, 85, 77, 128, 80, 65, 82, 84, 217, - 80, 65, 82, 84, 78, 69, 82, 83, 72, 73, 208, 80, 65, 82, 84, 73, 65, 76, - 76, 89, 45, 82, 69, 67, 89, 67, 76, 69, 196, 80, 65, 82, 84, 73, 65, 204, - 80, 65, 82, 84, 72, 73, 65, 206, 80, 65, 82, 212, 80, 65, 82, 82, 79, 84, - 128, 80, 65, 82, 75, 128, 80, 65, 82, 73, 67, 72, 79, 78, 128, 80, 65, - 82, 69, 83, 84, 73, 71, 77, 69, 78, 79, 206, 80, 65, 82, 69, 82, 69, 78, - 128, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, 83, 128, 80, 65, 82, 69, 78, - 84, 72, 69, 83, 73, 211, 80, 65, 82, 69, 78, 84, 72, 69, 83, 69, 211, 80, - 65, 82, 65, 80, 72, 82, 65, 83, 197, 80, 65, 82, 65, 76, 76, 69, 76, 79, - 71, 82, 65, 77, 128, 80, 65, 82, 65, 76, 76, 69, 76, 128, 80, 65, 82, 65, - 76, 76, 69, 204, 80, 65, 82, 65, 75, 76, 73, 84, 73, 75, 73, 128, 80, 65, - 82, 65, 75, 76, 73, 84, 73, 75, 201, 80, 65, 82, 65, 75, 76, 73, 84, 128, - 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 193, 80, 65, 82, 65, 71, 82, 65, - 80, 72, 85, 211, 80, 65, 82, 65, 71, 82, 65, 80, 72, 79, 83, 128, 80, 65, - 82, 65, 71, 82, 65, 80, 72, 128, 80, 65, 82, 65, 71, 82, 65, 80, 200, 80, - 65, 82, 65, 67, 72, 85, 84, 69, 128, 80, 65, 82, 65, 128, 80, 65, 82, - 128, 80, 65, 80, 89, 82, 85, 83, 128, 80, 65, 80, 69, 82, 67, 76, 73, 80, - 83, 128, 80, 65, 80, 69, 82, 67, 76, 73, 80, 128, 80, 65, 80, 69, 82, - 128, 80, 65, 80, 69, 210, 80, 65, 80, 128, 80, 65, 208, 80, 65, 207, 80, - 65, 78, 89, 85, 75, 85, 128, 80, 65, 78, 89, 73, 75, 85, 128, 80, 65, 78, - 89, 69, 67, 69, 75, 128, 80, 65, 78, 89, 65, 78, 71, 71, 65, 128, 80, 65, - 78, 89, 65, 75, 82, 65, 128, 80, 65, 78, 84, 73, 128, 80, 65, 78, 84, - 201, 80, 65, 78, 83, 73, 79, 83, 45, 80, 73, 69, 85, 80, 128, 80, 65, 78, - 83, 73, 79, 83, 45, 75, 65, 80, 89, 69, 79, 85, 78, 80, 73, 69, 85, 80, - 128, 80, 65, 78, 79, 78, 71, 79, 78, 65, 78, 128, 80, 65, 78, 79, 76, 79, - 78, 71, 128, 80, 65, 78, 71, 87, 73, 83, 65, 68, 128, 80, 65, 78, 71, 82, - 65, 78, 71, 75, 69, 80, 128, 80, 65, 78, 71, 79, 76, 65, 84, 128, 80, 65, - 78, 71, 76, 79, 78, 71, 128, 80, 65, 78, 71, 76, 65, 89, 65, 82, 128, 80, - 65, 78, 71, 75, 79, 78, 128, 80, 65, 78, 71, 75, 65, 84, 128, 80, 65, 78, - 71, 72, 85, 76, 85, 128, 80, 65, 78, 71, 128, 80, 65, 78, 69, 85, 76, 69, - 85, 78, 71, 128, 80, 65, 78, 68, 193, 80, 65, 78, 67, 65, 75, 69, 83, - 128, 80, 65, 78, 65, 77, 128, 80, 65, 78, 65, 69, 76, 65, 69, 78, 71, - 128, 80, 65, 78, 128, 80, 65, 206, 80, 65, 77, 85, 78, 71, 75, 65, 72, - 128, 80, 65, 77, 85, 68, 80, 79, 68, 128, 80, 65, 77, 83, 72, 65, 69, - 128, 80, 65, 77, 80, 72, 89, 76, 73, 65, 206, 80, 65, 77, 73, 78, 71, 75, - 65, 76, 128, 80, 65, 77, 69, 80, 69, 84, 128, 80, 65, 77, 69, 78, 69, 78, - 71, 128, 80, 65, 77, 65, 68, 65, 128, 80, 65, 77, 65, 68, 193, 80, 65, - 77, 65, 65, 69, 72, 128, 80, 65, 76, 85, 84, 65, 128, 80, 65, 76, 79, 67, - 72, 75, 65, 128, 80, 65, 76, 77, 89, 82, 69, 78, 197, 80, 65, 76, 77, - 211, 80, 65, 76, 77, 128, 80, 65, 76, 205, 80, 65, 76, 76, 65, 87, 65, - 128, 80, 65, 76, 76, 65, 83, 128, 80, 65, 76, 75, 65, 128, 80, 65, 76, - 201, 80, 65, 76, 69, 84, 84, 69, 128, 80, 65, 76, 65, 85, 78, 199, 80, - 65, 76, 65, 84, 65, 76, 73, 90, 69, 196, 80, 65, 76, 65, 84, 65, 76, 73, - 90, 65, 84, 73, 79, 78, 128, 80, 65, 76, 65, 84, 65, 204, 80, 65, 75, 80, - 65, 203, 80, 65, 73, 89, 65, 78, 78, 79, 73, 128, 80, 65, 73, 82, 84, 72, - 82, 65, 128, 80, 65, 73, 82, 69, 196, 80, 65, 73, 78, 84, 66, 82, 85, 83, - 72, 128, 80, 65, 73, 128, 80, 65, 72, 76, 65, 86, 201, 80, 65, 72, 128, - 80, 65, 71, 79, 68, 65, 128, 80, 65, 71, 69, 83, 128, 80, 65, 71, 69, 82, - 128, 80, 65, 71, 197, 80, 65, 68, 77, 193, 80, 65, 68, 68, 76, 197, 80, - 65, 68, 68, 73, 78, 199, 80, 65, 68, 193, 80, 65, 68, 128, 80, 65, 67, - 75, 73, 78, 71, 128, 80, 65, 67, 75, 65, 71, 69, 128, 80, 65, 65, 84, 85, - 128, 80, 65, 65, 83, 69, 78, 84, 79, 128, 80, 65, 65, 82, 65, 77, 128, - 80, 65, 65, 82, 65, 69, 128, 80, 65, 65, 77, 128, 80, 65, 65, 73, 128, - 80, 65, 65, 45, 80, 73, 76, 76, 65, 128, 80, 65, 65, 128, 80, 50, 128, - 80, 48, 49, 49, 128, 80, 48, 49, 48, 128, 80, 48, 48, 57, 128, 80, 48, - 48, 56, 128, 80, 48, 48, 55, 128, 80, 48, 48, 54, 128, 80, 48, 48, 53, - 128, 80, 48, 48, 52, 128, 80, 48, 48, 51, 65, 128, 80, 48, 48, 51, 128, - 80, 48, 48, 50, 128, 80, 48, 48, 49, 65, 128, 80, 48, 48, 49, 128, 79, - 90, 128, 79, 89, 83, 84, 69, 82, 128, 79, 89, 82, 65, 78, 73, 83, 77, - 193, 79, 89, 65, 78, 78, 65, 128, 79, 88, 73, 65, 128, 79, 88, 73, 193, - 79, 88, 69, 73, 65, 201, 79, 88, 69, 73, 193, 79, 87, 76, 128, 79, 86, - 69, 82, 83, 84, 82, 85, 67, 203, 79, 86, 69, 82, 82, 73, 68, 69, 128, 79, - 86, 69, 82, 76, 79, 78, 199, 79, 86, 69, 82, 76, 73, 78, 69, 128, 79, 86, - 69, 82, 76, 65, 89, 128, 79, 86, 69, 82, 76, 65, 217, 79, 86, 69, 82, 76, - 65, 80, 80, 73, 78, 199, 79, 86, 69, 82, 76, 65, 80, 128, 79, 86, 69, 82, - 76, 65, 73, 68, 128, 79, 86, 69, 82, 76, 65, 73, 196, 79, 86, 69, 82, 72, - 69, 65, 84, 69, 196, 79, 86, 69, 82, 66, 65, 82, 128, 79, 86, 65, 76, - 128, 79, 86, 65, 204, 79, 85, 84, 76, 73, 78, 69, 196, 79, 85, 84, 76, - 73, 78, 69, 128, 79, 85, 84, 69, 210, 79, 85, 84, 66, 79, 216, 79, 85, - 78, 75, 73, 193, 79, 85, 78, 67, 69, 128, 79, 85, 78, 67, 197, 79, 84, - 85, 128, 79, 84, 84, 79, 77, 65, 206, 79, 84, 84, 69, 82, 128, 79, 84, - 84, 65, 86, 193, 79, 84, 84, 128, 79, 84, 83, 69, 67, 72, 75, 65, 128, - 79, 84, 72, 69, 82, 211, 79, 84, 72, 69, 210, 79, 84, 72, 65, 76, 65, - 206, 79, 84, 72, 65, 76, 128, 79, 83, 79, 75, 65, 128, 79, 83, 79, 75, - 193, 79, 83, 77, 65, 78, 89, 193, 79, 83, 67, 128, 79, 83, 65, 71, 197, - 79, 82, 84, 72, 79, 71, 79, 78, 65, 204, 79, 82, 84, 72, 79, 68, 79, 216, - 79, 82, 78, 65, 84, 197, 79, 82, 78, 65, 77, 69, 78, 84, 83, 128, 79, 82, - 78, 65, 77, 69, 78, 84, 128, 79, 82, 78, 65, 77, 69, 78, 212, 79, 82, 75, - 72, 79, 206, 79, 82, 73, 89, 193, 79, 82, 73, 71, 73, 78, 65, 204, 79, - 82, 73, 71, 73, 78, 128, 79, 82, 69, 45, 50, 128, 79, 82, 68, 73, 78, 65, - 204, 79, 82, 68, 69, 210, 79, 82, 67, 72, 73, 68, 128, 79, 82, 65, 78, - 71, 85, 84, 65, 78, 128, 79, 82, 65, 78, 71, 197, 79, 80, 84, 73, 79, - 206, 79, 80, 84, 73, 67, 65, 204, 79, 80, 80, 82, 69, 83, 83, 73, 79, 78, - 128, 79, 80, 80, 79, 83, 73, 84, 73, 79, 78, 128, 79, 80, 80, 79, 83, 73, - 78, 199, 79, 80, 80, 79, 83, 69, 128, 79, 80, 72, 73, 85, 67, 72, 85, 83, - 128, 79, 80, 69, 82, 65, 84, 79, 82, 128, 79, 80, 69, 82, 65, 84, 79, - 210, 79, 80, 69, 82, 65, 84, 73, 78, 199, 79, 80, 69, 78, 73, 78, 199, - 79, 80, 69, 78, 45, 80, 128, 79, 80, 69, 78, 45, 79, 85, 84, 76, 73, 78, - 69, 196, 79, 80, 69, 78, 45, 79, 128, 79, 80, 69, 78, 45, 207, 79, 80, - 69, 78, 45, 72, 69, 65, 68, 69, 196, 79, 80, 69, 78, 45, 67, 73, 82, 67, - 85, 73, 84, 45, 79, 85, 84, 80, 85, 212, 79, 80, 69, 78, 128, 79, 80, 69, - 206, 79, 79, 90, 69, 128, 79, 79, 89, 65, 78, 78, 65, 128, 79, 79, 85, - 128, 79, 79, 77, 85, 128, 79, 79, 72, 128, 79, 79, 69, 128, 79, 79, 66, - 79, 79, 70, 73, 76, 73, 128, 79, 78, 85, 128, 79, 78, 83, 85, 128, 79, - 78, 78, 128, 79, 78, 75, 65, 82, 128, 79, 78, 73, 79, 78, 128, 79, 78, - 69, 83, 69, 76, 70, 128, 79, 78, 69, 45, 87, 65, 217, 79, 78, 69, 45, 84, - 72, 73, 82, 84, 89, 128, 79, 78, 69, 45, 80, 73, 69, 67, 197, 79, 78, 69, - 45, 76, 73, 78, 197, 79, 78, 69, 45, 72, 85, 78, 68, 82, 69, 68, 45, 65, - 78, 68, 45, 83, 73, 88, 84, 73, 69, 84, 72, 128, 79, 78, 67, 79, 77, 73, - 78, 199, 79, 78, 65, 80, 128, 79, 78, 45, 79, 70, 198, 79, 77, 73, 83, - 83, 73, 79, 206, 79, 77, 73, 67, 82, 79, 78, 128, 79, 77, 73, 67, 82, 79, - 206, 79, 77, 69, 84, 128, 79, 77, 69, 71, 65, 128, 79, 77, 69, 71, 193, - 79, 77, 65, 76, 79, 78, 128, 79, 76, 73, 86, 69, 128, 79, 76, 73, 71, 79, - 206, 79, 76, 68, 128, 79, 75, 84, 207, 79, 75, 65, 82, 65, 128, 79, 75, - 65, 82, 193, 79, 74, 73, 66, 87, 65, 217, 79, 74, 69, 79, 78, 128, 79, - 73, 78, 128, 79, 73, 76, 128, 79, 73, 204, 79, 72, 77, 128, 79, 72, 205, - 79, 71, 82, 69, 128, 79, 71, 79, 78, 69, 75, 128, 79, 71, 79, 78, 69, - 203, 79, 71, 72, 65, 205, 79, 70, 70, 73, 67, 69, 82, 128, 79, 70, 70, - 73, 67, 69, 128, 79, 70, 70, 73, 67, 197, 79, 70, 70, 128, 79, 69, 89, - 128, 79, 69, 82, 128, 79, 69, 75, 128, 79, 69, 69, 128, 79, 68, 69, 78, - 128, 79, 68, 68, 128, 79, 68, 196, 79, 67, 84, 79, 80, 85, 83, 128, 79, - 67, 84, 79, 66, 69, 82, 128, 79, 67, 84, 69, 212, 79, 67, 84, 65, 71, 79, - 78, 65, 204, 79, 67, 84, 65, 71, 79, 78, 128, 79, 67, 210, 79, 67, 76, - 79, 67, 75, 128, 79, 67, 72, 75, 79, 77, 128, 79, 67, 67, 76, 85, 83, 73, - 79, 78, 128, 79, 66, 83, 84, 82, 85, 67, 84, 73, 79, 78, 128, 79, 66, 83, - 69, 82, 86, 69, 210, 79, 66, 79, 76, 211, 79, 66, 79, 204, 79, 66, 79, - 70, 73, 76, 73, 128, 79, 66, 76, 73, 81, 85, 197, 79, 66, 76, 65, 75, 79, - 128, 79, 66, 76, 65, 67, 72, 75, 79, 128, 79, 66, 74, 69, 67, 212, 79, - 66, 69, 76, 85, 83, 128, 79, 66, 69, 76, 79, 83, 128, 79, 66, 128, 79, - 65, 89, 128, 79, 65, 75, 128, 79, 65, 66, 79, 65, 70, 73, 76, 73, 128, - 79, 193, 79, 48, 53, 49, 128, 79, 48, 53, 48, 66, 128, 79, 48, 53, 48, - 65, 128, 79, 48, 53, 48, 128, 79, 48, 52, 57, 128, 79, 48, 52, 56, 128, - 79, 48, 52, 55, 128, 79, 48, 52, 54, 128, 79, 48, 52, 53, 128, 79, 48, - 52, 52, 128, 79, 48, 52, 51, 128, 79, 48, 52, 50, 128, 79, 48, 52, 49, - 128, 79, 48, 52, 48, 128, 79, 48, 51, 57, 128, 79, 48, 51, 56, 128, 79, - 48, 51, 55, 128, 79, 48, 51, 54, 68, 128, 79, 48, 51, 54, 67, 128, 79, - 48, 51, 54, 66, 128, 79, 48, 51, 54, 65, 128, 79, 48, 51, 54, 128, 79, - 48, 51, 53, 128, 79, 48, 51, 52, 128, 79, 48, 51, 51, 65, 128, 79, 48, - 51, 51, 128, 79, 48, 51, 50, 128, 79, 48, 51, 49, 128, 79, 48, 51, 48, - 65, 128, 79, 48, 51, 48, 128, 79, 48, 50, 57, 65, 128, 79, 48, 50, 57, - 128, 79, 48, 50, 56, 128, 79, 48, 50, 55, 128, 79, 48, 50, 54, 128, 79, - 48, 50, 53, 65, 128, 79, 48, 50, 53, 128, 79, 48, 50, 52, 65, 128, 79, - 48, 50, 52, 128, 79, 48, 50, 51, 128, 79, 48, 50, 50, 128, 79, 48, 50, - 49, 128, 79, 48, 50, 48, 65, 128, 79, 48, 50, 48, 128, 79, 48, 49, 57, - 65, 128, 79, 48, 49, 57, 128, 79, 48, 49, 56, 128, 79, 48, 49, 55, 128, - 79, 48, 49, 54, 128, 79, 48, 49, 53, 128, 79, 48, 49, 52, 128, 79, 48, - 49, 51, 128, 79, 48, 49, 50, 128, 79, 48, 49, 49, 128, 79, 48, 49, 48, - 67, 128, 79, 48, 49, 48, 66, 128, 79, 48, 49, 48, 65, 128, 79, 48, 49, - 48, 128, 79, 48, 48, 57, 128, 79, 48, 48, 56, 128, 79, 48, 48, 55, 128, - 79, 48, 48, 54, 70, 128, 79, 48, 48, 54, 69, 128, 79, 48, 48, 54, 68, - 128, 79, 48, 48, 54, 67, 128, 79, 48, 48, 54, 66, 128, 79, 48, 48, 54, - 65, 128, 79, 48, 48, 54, 128, 79, 48, 48, 53, 65, 128, 79, 48, 48, 53, - 128, 79, 48, 48, 52, 128, 79, 48, 48, 51, 128, 79, 48, 48, 50, 128, 79, - 48, 48, 49, 65, 128, 79, 48, 48, 49, 128, 79, 45, 89, 69, 128, 79, 45, - 79, 45, 73, 128, 79, 45, 69, 128, 78, 90, 89, 88, 128, 78, 90, 89, 84, - 128, 78, 90, 89, 82, 88, 128, 78, 90, 89, 82, 128, 78, 90, 89, 80, 128, - 78, 90, 89, 128, 78, 90, 85, 88, 128, 78, 90, 85, 82, 88, 128, 78, 90, - 85, 82, 128, 78, 90, 85, 81, 128, 78, 90, 85, 80, 128, 78, 90, 85, 79, - 88, 128, 78, 90, 85, 79, 128, 78, 90, 85, 206, 78, 90, 85, 128, 78, 90, - 79, 88, 128, 78, 90, 79, 80, 128, 78, 90, 73, 88, 128, 78, 90, 73, 84, - 128, 78, 90, 73, 80, 128, 78, 90, 73, 69, 88, 128, 78, 90, 73, 69, 80, - 128, 78, 90, 73, 69, 128, 78, 90, 73, 128, 78, 90, 69, 88, 128, 78, 90, - 69, 85, 77, 128, 78, 90, 69, 128, 78, 90, 65, 88, 128, 78, 90, 65, 84, - 128, 78, 90, 65, 81, 128, 78, 90, 65, 80, 128, 78, 90, 65, 128, 78, 90, - 193, 78, 89, 87, 65, 128, 78, 89, 85, 88, 128, 78, 89, 85, 85, 128, 78, - 89, 85, 84, 128, 78, 89, 85, 80, 128, 78, 89, 85, 79, 88, 128, 78, 89, - 85, 79, 80, 128, 78, 89, 85, 79, 128, 78, 89, 85, 78, 128, 78, 89, 85, - 69, 128, 78, 89, 85, 128, 78, 89, 79, 88, 128, 78, 89, 79, 84, 128, 78, - 89, 79, 80, 128, 78, 89, 79, 79, 128, 78, 89, 79, 78, 128, 78, 89, 79, - 65, 128, 78, 89, 79, 128, 78, 89, 74, 65, 128, 78, 89, 73, 88, 128, 78, - 89, 73, 84, 128, 78, 89, 73, 212, 78, 89, 73, 211, 78, 89, 73, 210, 78, - 89, 73, 80, 128, 78, 89, 73, 78, 45, 68, 79, 128, 78, 89, 73, 78, 128, - 78, 89, 73, 73, 128, 78, 89, 73, 69, 88, 128, 78, 89, 73, 69, 84, 128, - 78, 89, 73, 69, 80, 128, 78, 89, 73, 69, 128, 78, 89, 73, 65, 75, 69, 78, - 199, 78, 89, 73, 128, 78, 89, 201, 78, 89, 72, 65, 128, 78, 89, 69, 84, - 128, 78, 89, 69, 212, 78, 89, 69, 78, 128, 78, 89, 69, 72, 128, 78, 89, - 69, 200, 78, 89, 69, 69, 128, 78, 89, 69, 128, 78, 89, 196, 78, 89, 67, - 65, 128, 78, 89, 65, 85, 128, 78, 89, 65, 74, 128, 78, 89, 65, 73, 128, - 78, 89, 65, 72, 128, 78, 89, 65, 69, 77, 65, 69, 128, 78, 89, 65, 65, - 128, 78, 87, 79, 79, 128, 78, 87, 79, 128, 78, 87, 73, 73, 128, 78, 87, - 73, 128, 78, 87, 69, 128, 78, 87, 65, 65, 128, 78, 87, 65, 128, 78, 87, - 128, 78, 86, 128, 78, 85, 88, 128, 78, 85, 85, 78, 128, 78, 85, 85, 128, - 78, 85, 84, 73, 76, 76, 85, 128, 78, 85, 84, 128, 78, 85, 212, 78, 85, - 82, 88, 128, 78, 85, 82, 128, 78, 85, 80, 128, 78, 85, 79, 88, 128, 78, - 85, 79, 80, 128, 78, 85, 79, 128, 78, 85, 78, 85, 90, 128, 78, 85, 78, - 85, 218, 78, 85, 78, 71, 128, 78, 85, 78, 65, 86, 85, 212, 78, 85, 78, - 65, 86, 73, 203, 78, 85, 78, 128, 78, 85, 206, 78, 85, 77, 69, 82, 207, - 78, 85, 77, 69, 82, 65, 84, 79, 210, 78, 85, 77, 69, 82, 65, 204, 78, 85, - 77, 66, 69, 82, 83, 128, 78, 85, 77, 66, 69, 82, 128, 78, 85, 77, 128, - 78, 85, 76, 76, 128, 78, 85, 76, 204, 78, 85, 76, 128, 78, 85, 75, 84, - 65, 128, 78, 85, 75, 84, 193, 78, 85, 69, 78, 71, 128, 78, 85, 69, 128, - 78, 85, 66, 73, 65, 206, 78, 85, 65, 69, 128, 78, 85, 49, 49, 128, 78, - 85, 49, 177, 78, 85, 48, 50, 50, 65, 128, 78, 85, 48, 50, 50, 128, 78, - 85, 48, 50, 49, 128, 78, 85, 48, 50, 48, 128, 78, 85, 48, 49, 57, 128, - 78, 85, 48, 49, 56, 65, 128, 78, 85, 48, 49, 56, 128, 78, 85, 48, 49, 55, - 128, 78, 85, 48, 49, 54, 128, 78, 85, 48, 49, 53, 128, 78, 85, 48, 49, - 52, 128, 78, 85, 48, 49, 51, 128, 78, 85, 48, 49, 50, 128, 78, 85, 48, - 49, 49, 65, 128, 78, 85, 48, 49, 49, 128, 78, 85, 48, 49, 48, 65, 128, - 78, 85, 48, 49, 48, 128, 78, 85, 48, 48, 57, 128, 78, 85, 48, 48, 56, - 128, 78, 85, 48, 48, 55, 128, 78, 85, 48, 48, 54, 128, 78, 85, 48, 48, - 53, 128, 78, 85, 48, 48, 52, 128, 78, 85, 48, 48, 51, 128, 78, 85, 48, - 48, 50, 128, 78, 85, 48, 48, 49, 128, 78, 85, 45, 51, 128, 78, 85, 45, - 50, 128, 78, 85, 45, 49, 128, 78, 84, 88, 73, 86, 128, 78, 84, 88, 65, - 128, 78, 84, 85, 85, 128, 78, 84, 85, 77, 128, 78, 84, 85, 74, 128, 78, - 84, 213, 78, 84, 83, 65, 85, 128, 78, 84, 83, 65, 128, 78, 84, 79, 81, - 80, 69, 78, 128, 78, 84, 79, 71, 128, 78, 84, 79, 199, 78, 84, 73, 69, - 197, 78, 84, 72, 65, 85, 128, 78, 84, 69, 85, 78, 71, 66, 65, 128, 78, - 84, 69, 85, 77, 128, 78, 84, 69, 78, 128, 78, 84, 69, 69, 128, 78, 84, - 65, 80, 128, 78, 84, 65, 208, 78, 84, 65, 65, 128, 78, 84, 65, 128, 78, - 83, 85, 79, 212, 78, 83, 85, 78, 128, 78, 83, 85, 77, 128, 78, 83, 79, - 77, 128, 78, 83, 73, 69, 69, 84, 128, 78, 83, 73, 69, 69, 80, 128, 78, - 83, 73, 69, 69, 128, 78, 83, 72, 85, 84, 128, 78, 83, 72, 85, 212, 78, - 83, 72, 85, 79, 80, 128, 78, 83, 72, 85, 69, 128, 78, 83, 72, 73, 69, 69, - 128, 78, 83, 72, 69, 69, 128, 78, 83, 72, 65, 81, 128, 78, 83, 72, 65, - 128, 78, 83, 69, 85, 65, 69, 78, 128, 78, 83, 69, 78, 128, 78, 83, 65, - 128, 78, 82, 89, 88, 128, 78, 82, 89, 84, 128, 78, 82, 89, 82, 88, 128, - 78, 82, 89, 82, 128, 78, 82, 89, 80, 128, 78, 82, 89, 128, 78, 82, 85, - 88, 128, 78, 82, 85, 84, 128, 78, 82, 85, 82, 88, 128, 78, 82, 85, 82, - 128, 78, 82, 85, 80, 128, 78, 82, 85, 65, 128, 78, 82, 85, 128, 78, 82, - 79, 88, 128, 78, 82, 79, 80, 128, 78, 82, 79, 128, 78, 82, 69, 88, 128, - 78, 82, 69, 84, 128, 78, 82, 69, 211, 78, 82, 69, 80, 128, 78, 82, 69, - 128, 78, 82, 65, 88, 128, 78, 82, 65, 84, 128, 78, 82, 65, 80, 128, 78, - 82, 65, 128, 78, 81, 73, 71, 128, 78, 81, 65, 128, 78, 80, 76, 65, 128, - 78, 80, 65, 128, 78, 79, 90, 72, 75, 65, 128, 78, 79, 89, 128, 78, 79, - 88, 128, 78, 79, 87, 67, 128, 78, 79, 86, 73, 76, 69, 128, 78, 79, 86, - 69, 77, 66, 69, 82, 128, 78, 79, 84, 84, 79, 128, 78, 79, 84, 69, 83, - 128, 78, 79, 84, 69, 72, 69, 65, 68, 128, 78, 79, 84, 69, 72, 69, 65, - 196, 78, 79, 84, 69, 66, 79, 79, 75, 128, 78, 79, 84, 69, 66, 79, 79, - 203, 78, 79, 84, 69, 128, 78, 79, 84, 197, 78, 79, 84, 67, 72, 69, 196, - 78, 79, 84, 67, 72, 128, 78, 79, 84, 65, 84, 73, 79, 206, 78, 79, 84, - 128, 78, 79, 212, 78, 79, 83, 69, 128, 78, 79, 83, 197, 78, 79, 82, 84, - 72, 87, 69, 83, 212, 78, 79, 82, 84, 72, 69, 82, 206, 78, 79, 82, 84, 72, - 69, 65, 83, 84, 45, 80, 79, 73, 78, 84, 73, 78, 199, 78, 79, 82, 77, 65, - 204, 78, 79, 82, 68, 73, 195, 78, 79, 210, 78, 79, 80, 128, 78, 79, 79, - 78, 85, 128, 78, 79, 79, 128, 78, 79, 78, 70, 79, 82, 75, 73, 78, 71, - 128, 78, 79, 78, 45, 80, 79, 84, 65, 66, 76, 197, 78, 79, 78, 45, 74, 79, - 73, 78, 69, 82, 128, 78, 79, 78, 45, 66, 82, 69, 65, 75, 73, 78, 199, 78, - 79, 78, 128, 78, 79, 77, 73, 83, 77, 193, 78, 79, 77, 73, 78, 65, 204, - 78, 79, 75, 72, 85, 75, 128, 78, 79, 68, 69, 128, 78, 79, 65, 128, 78, - 79, 45, 66, 82, 69, 65, 203, 78, 79, 45, 53, 128, 78, 79, 45, 52, 128, - 78, 79, 45, 51, 128, 78, 79, 45, 50, 128, 78, 79, 45, 49, 128, 78, 78, - 85, 85, 128, 78, 78, 85, 128, 78, 78, 79, 79, 128, 78, 78, 78, 85, 85, - 128, 78, 78, 78, 85, 128, 78, 78, 78, 79, 79, 128, 78, 78, 78, 79, 128, - 78, 78, 78, 73, 73, 128, 78, 78, 78, 73, 128, 78, 78, 78, 69, 69, 128, - 78, 78, 78, 69, 128, 78, 78, 78, 65, 85, 128, 78, 78, 78, 65, 73, 128, - 78, 78, 78, 65, 65, 128, 78, 78, 78, 65, 128, 78, 78, 78, 128, 78, 78, - 72, 65, 128, 78, 78, 71, 79, 79, 128, 78, 78, 71, 79, 128, 78, 78, 71, - 73, 73, 128, 78, 78, 71, 73, 128, 78, 78, 71, 65, 65, 128, 78, 78, 71, - 65, 128, 78, 78, 71, 128, 78, 78, 66, 83, 80, 128, 78, 77, 128, 78, 76, - 65, 85, 128, 78, 76, 48, 50, 48, 128, 78, 76, 48, 49, 57, 128, 78, 76, - 48, 49, 56, 128, 78, 76, 48, 49, 55, 65, 128, 78, 76, 48, 49, 55, 128, - 78, 76, 48, 49, 54, 128, 78, 76, 48, 49, 53, 128, 78, 76, 48, 49, 52, - 128, 78, 76, 48, 49, 51, 128, 78, 76, 48, 49, 50, 128, 78, 76, 48, 49, - 49, 128, 78, 76, 48, 49, 48, 128, 78, 76, 48, 48, 57, 128, 78, 76, 48, - 48, 56, 128, 78, 76, 48, 48, 55, 128, 78, 76, 48, 48, 54, 128, 78, 76, - 48, 48, 53, 65, 128, 78, 76, 48, 48, 53, 128, 78, 76, 48, 48, 52, 128, - 78, 76, 48, 48, 51, 128, 78, 76, 48, 48, 50, 128, 78, 76, 48, 48, 49, - 128, 78, 76, 128, 78, 75, 79, 77, 128, 78, 75, 207, 78, 75, 73, 78, 68, - 73, 128, 78, 75, 65, 85, 128, 78, 75, 65, 65, 82, 65, 69, 128, 78, 75, - 65, 128, 78, 74, 89, 88, 128, 78, 74, 89, 84, 128, 78, 74, 89, 82, 88, - 128, 78, 74, 89, 82, 128, 78, 74, 89, 80, 128, 78, 74, 89, 128, 78, 74, - 85, 88, 128, 78, 74, 85, 82, 88, 128, 78, 74, 85, 82, 128, 78, 74, 85, - 81, 65, 128, 78, 74, 85, 80, 128, 78, 74, 85, 79, 88, 128, 78, 74, 85, - 79, 128, 78, 74, 85, 69, 81, 128, 78, 74, 85, 65, 69, 128, 78, 74, 85, - 128, 78, 74, 79, 88, 128, 78, 74, 79, 84, 128, 78, 74, 79, 80, 128, 78, - 74, 79, 79, 128, 78, 74, 79, 128, 78, 74, 73, 88, 128, 78, 74, 73, 84, - 128, 78, 74, 73, 80, 128, 78, 74, 73, 69, 88, 128, 78, 74, 73, 69, 84, - 128, 78, 74, 73, 69, 80, 128, 78, 74, 73, 69, 69, 128, 78, 74, 73, 69, - 128, 78, 74, 73, 128, 78, 74, 201, 78, 74, 69, 85, 88, 128, 78, 74, 69, - 85, 84, 128, 78, 74, 69, 85, 65, 69, 78, 65, 128, 78, 74, 69, 85, 65, 69, - 77, 128, 78, 74, 69, 69, 69, 69, 128, 78, 74, 69, 69, 128, 78, 74, 69, - 197, 78, 74, 69, 128, 78, 74, 65, 81, 128, 78, 74, 65, 80, 128, 78, 74, - 65, 69, 77, 76, 73, 128, 78, 74, 65, 69, 77, 128, 78, 74, 65, 65, 128, - 78, 73, 90, 75, 207, 78, 73, 88, 128, 78, 73, 84, 82, 69, 128, 78, 73, - 83, 65, 71, 128, 78, 73, 82, 85, 71, 85, 128, 78, 73, 80, 128, 78, 73, - 78, 84, 72, 128, 78, 73, 78, 74, 65, 128, 78, 73, 78, 69, 84, 89, 128, - 78, 73, 78, 69, 84, 217, 78, 73, 78, 69, 84, 69, 69, 78, 128, 78, 73, 78, - 69, 84, 69, 69, 206, 78, 73, 78, 69, 45, 84, 72, 73, 82, 84, 89, 128, 78, - 73, 78, 197, 78, 73, 78, 68, 65, 50, 128, 78, 73, 78, 68, 65, 178, 78, - 73, 78, 57, 128, 78, 73, 78, 128, 78, 73, 77, 128, 78, 73, 205, 78, 73, - 75, 79, 76, 83, 66, 85, 82, 199, 78, 73, 75, 72, 65, 72, 73, 84, 128, 78, - 73, 75, 65, 72, 73, 84, 128, 78, 73, 75, 65, 128, 78, 73, 72, 83, 72, 86, - 65, 83, 65, 128, 78, 73, 71, 73, 68, 65, 77, 73, 78, 128, 78, 73, 71, 73, - 68, 65, 69, 83, 72, 128, 78, 73, 71, 72, 84, 128, 78, 73, 71, 72, 212, - 78, 73, 71, 71, 65, 72, 73, 84, 65, 128, 78, 73, 69, 88, 128, 78, 73, 69, - 85, 78, 45, 84, 73, 75, 69, 85, 84, 128, 78, 73, 69, 85, 78, 45, 84, 72, - 73, 69, 85, 84, 72, 128, 78, 73, 69, 85, 78, 45, 83, 73, 79, 83, 128, 78, - 73, 69, 85, 78, 45, 82, 73, 69, 85, 76, 128, 78, 73, 69, 85, 78, 45, 80, - 73, 69, 85, 80, 128, 78, 73, 69, 85, 78, 45, 80, 65, 78, 83, 73, 79, 83, - 128, 78, 73, 69, 85, 78, 45, 75, 73, 89, 69, 79, 75, 128, 78, 73, 69, 85, - 78, 45, 72, 73, 69, 85, 72, 128, 78, 73, 69, 85, 78, 45, 67, 73, 69, 85, - 67, 128, 78, 73, 69, 85, 78, 45, 67, 72, 73, 69, 85, 67, 72, 128, 78, 73, - 69, 85, 206, 78, 73, 69, 80, 128, 78, 73, 69, 128, 78, 73, 66, 128, 78, - 73, 65, 128, 78, 73, 50, 128, 78, 73, 45, 84, 69, 128, 78, 73, 45, 55, - 128, 78, 73, 45, 54, 128, 78, 73, 45, 53, 128, 78, 73, 45, 52, 128, 78, - 73, 45, 51, 128, 78, 73, 45, 50, 128, 78, 73, 45, 49, 128, 78, 72, 85, - 69, 128, 78, 72, 74, 65, 128, 78, 72, 65, 89, 128, 78, 72, 128, 78, 71, - 89, 69, 128, 78, 71, 86, 69, 128, 78, 71, 85, 85, 128, 78, 71, 85, 79, - 88, 128, 78, 71, 85, 79, 84, 128, 78, 71, 85, 79, 128, 78, 71, 85, 65, - 78, 128, 78, 71, 85, 65, 69, 84, 128, 78, 71, 85, 65, 69, 128, 78, 71, - 79, 88, 128, 78, 71, 79, 85, 128, 78, 71, 79, 213, 78, 71, 79, 84, 128, - 78, 71, 79, 81, 128, 78, 71, 79, 80, 128, 78, 71, 79, 78, 128, 78, 71, - 79, 77, 128, 78, 71, 79, 69, 72, 128, 78, 71, 79, 69, 200, 78, 71, 207, - 78, 71, 75, 89, 69, 69, 128, 78, 71, 75, 87, 65, 69, 78, 128, 78, 71, 75, - 85, 80, 128, 78, 71, 75, 85, 78, 128, 78, 71, 75, 85, 77, 128, 78, 71, - 75, 85, 69, 78, 90, 69, 85, 77, 128, 78, 71, 75, 85, 197, 78, 71, 75, 73, - 78, 68, 201, 78, 71, 75, 73, 69, 69, 128, 78, 71, 75, 69, 85, 88, 128, - 78, 71, 75, 69, 85, 82, 73, 128, 78, 71, 75, 69, 85, 65, 69, 81, 128, 78, - 71, 75, 69, 85, 65, 69, 77, 128, 78, 71, 75, 65, 81, 128, 78, 71, 75, 65, - 80, 128, 78, 71, 75, 65, 65, 77, 73, 128, 78, 71, 75, 65, 128, 78, 71, - 73, 69, 88, 128, 78, 71, 73, 69, 80, 128, 78, 71, 73, 69, 128, 78, 71, - 72, 65, 128, 78, 71, 71, 87, 65, 69, 78, 128, 78, 71, 71, 85, 82, 65, 69, - 128, 78, 71, 71, 85, 80, 128, 78, 71, 71, 85, 79, 81, 128, 78, 71, 71, - 85, 79, 209, 78, 71, 71, 85, 79, 78, 128, 78, 71, 71, 85, 79, 77, 128, - 78, 71, 71, 85, 77, 128, 78, 71, 71, 85, 69, 69, 84, 128, 78, 71, 71, 85, - 65, 69, 83, 72, 65, 197, 78, 71, 71, 85, 65, 69, 206, 78, 71, 71, 85, 65, - 128, 78, 71, 71, 85, 128, 78, 71, 71, 79, 79, 128, 78, 71, 71, 79, 128, - 78, 71, 71, 73, 128, 78, 71, 71, 69, 85, 88, 128, 78, 71, 71, 69, 85, 65, - 69, 84, 128, 78, 71, 71, 69, 85, 65, 69, 128, 78, 71, 71, 69, 213, 78, - 71, 71, 69, 78, 128, 78, 71, 71, 69, 69, 84, 128, 78, 71, 71, 69, 69, 69, - 69, 128, 78, 71, 71, 69, 69, 128, 78, 71, 71, 69, 128, 78, 71, 71, 65, - 80, 128, 78, 71, 71, 65, 65, 77, 65, 69, 128, 78, 71, 71, 65, 65, 77, - 128, 78, 71, 71, 65, 65, 128, 78, 71, 71, 128, 78, 71, 69, 88, 128, 78, - 71, 69, 85, 82, 69, 85, 84, 128, 78, 71, 69, 80, 128, 78, 71, 69, 78, - 128, 78, 71, 69, 69, 128, 78, 71, 69, 65, 68, 65, 76, 128, 78, 71, 65, - 88, 128, 78, 71, 65, 85, 128, 78, 71, 65, 84, 128, 78, 71, 65, 211, 78, - 71, 65, 81, 128, 78, 71, 65, 80, 128, 78, 71, 65, 78, 71, 85, 128, 78, - 71, 65, 78, 128, 78, 71, 65, 73, 128, 78, 71, 65, 72, 128, 78, 71, 65, - 65, 73, 128, 78, 71, 193, 78, 70, 128, 78, 69, 88, 212, 78, 69, 88, 128, - 78, 69, 87, 83, 80, 65, 80, 69, 82, 128, 78, 69, 87, 76, 73, 78, 69, 128, - 78, 69, 87, 76, 73, 78, 197, 78, 69, 87, 193, 78, 69, 87, 128, 78, 69, - 215, 78, 69, 85, 84, 82, 65, 76, 128, 78, 69, 85, 84, 82, 65, 204, 78, - 69, 85, 84, 69, 82, 128, 78, 69, 84, 87, 79, 82, 75, 69, 196, 78, 69, - 212, 78, 69, 83, 84, 73, 78, 199, 78, 69, 83, 84, 69, 196, 78, 69, 83, - 84, 128, 78, 69, 83, 212, 78, 69, 83, 83, 85, 83, 128, 78, 69, 82, 196, - 78, 69, 81, 85, 68, 65, 65, 128, 78, 69, 80, 84, 85, 78, 69, 128, 78, 69, - 80, 84, 85, 78, 197, 78, 69, 80, 79, 83, 84, 79, 89, 65, 78, 78, 65, 89, - 65, 128, 78, 69, 80, 128, 78, 69, 79, 128, 78, 69, 207, 78, 69, 78, 79, - 69, 128, 78, 69, 78, 65, 78, 79, 128, 78, 69, 78, 128, 78, 69, 77, 75, - 65, 128, 78, 69, 76, 128, 78, 69, 73, 84, 72, 69, 210, 78, 69, 71, 65, - 84, 73, 86, 197, 78, 69, 71, 65, 84, 73, 79, 206, 78, 69, 71, 65, 84, 69, - 196, 78, 69, 69, 68, 76, 69, 128, 78, 69, 67, 75, 84, 73, 69, 128, 78, - 69, 67, 75, 128, 78, 69, 66, 69, 78, 83, 84, 73, 77, 77, 69, 128, 78, 69, - 45, 75, 79, 128, 78, 68, 85, 88, 128, 78, 68, 85, 84, 128, 78, 68, 85, - 82, 88, 128, 78, 68, 85, 82, 128, 78, 68, 85, 80, 128, 78, 68, 85, 78, - 128, 78, 68, 213, 78, 68, 79, 88, 128, 78, 68, 79, 84, 128, 78, 68, 79, - 80, 128, 78, 68, 79, 79, 128, 78, 68, 79, 78, 128, 78, 68, 79, 77, 66, - 85, 128, 78, 68, 79, 76, 197, 78, 68, 73, 88, 128, 78, 68, 73, 84, 128, - 78, 68, 73, 81, 128, 78, 68, 73, 80, 128, 78, 68, 73, 69, 88, 128, 78, - 68, 73, 69, 128, 78, 68, 73, 68, 65, 128, 78, 68, 73, 65, 81, 128, 78, - 68, 69, 88, 128, 78, 68, 69, 85, 88, 128, 78, 68, 69, 85, 84, 128, 78, - 68, 69, 85, 65, 69, 82, 69, 69, 128, 78, 68, 69, 80, 128, 78, 68, 69, 69, - 128, 78, 68, 69, 128, 78, 68, 65, 88, 128, 78, 68, 65, 84, 128, 78, 68, - 65, 80, 128, 78, 68, 65, 77, 128, 78, 68, 65, 65, 78, 71, 71, 69, 85, 65, - 69, 84, 128, 78, 68, 65, 65, 128, 78, 68, 65, 193, 78, 67, 72, 65, 85, - 128, 78, 67, 65, 128, 78, 66, 89, 88, 128, 78, 66, 89, 84, 128, 78, 66, - 89, 82, 88, 128, 78, 66, 89, 82, 128, 78, 66, 89, 80, 128, 78, 66, 89, - 128, 78, 66, 85, 88, 128, 78, 66, 85, 84, 128, 78, 66, 85, 82, 88, 128, - 78, 66, 85, 82, 128, 78, 66, 85, 80, 128, 78, 66, 85, 128, 78, 66, 79, - 88, 128, 78, 66, 79, 84, 128, 78, 66, 79, 80, 128, 78, 66, 79, 128, 78, - 66, 73, 88, 128, 78, 66, 73, 84, 128, 78, 66, 73, 80, 128, 78, 66, 73, - 69, 88, 128, 78, 66, 73, 69, 80, 128, 78, 66, 73, 69, 128, 78, 66, 73, - 128, 78, 66, 72, 128, 78, 66, 65, 88, 128, 78, 66, 65, 84, 128, 78, 66, - 65, 80, 128, 78, 66, 65, 128, 78, 65, 90, 65, 210, 78, 65, 89, 65, 78, - 78, 65, 128, 78, 65, 89, 128, 78, 65, 88, 73, 65, 206, 78, 65, 88, 128, - 78, 65, 85, 84, 72, 83, 128, 78, 65, 85, 83, 69, 65, 84, 69, 196, 78, 65, - 85, 68, 73, 218, 78, 65, 84, 85, 82, 65, 204, 78, 65, 84, 84, 73, 76, 73, - 203, 78, 65, 84, 73, 79, 78, 65, 204, 78, 65, 83, 75, 65, 80, 201, 78, - 65, 83, 72, 73, 128, 78, 65, 83, 65, 76, 73, 90, 69, 196, 78, 65, 83, 65, - 76, 73, 90, 65, 84, 73, 79, 78, 128, 78, 65, 83, 65, 76, 73, 90, 65, 84, - 73, 79, 206, 78, 65, 83, 65, 204, 78, 65, 82, 82, 79, 215, 78, 65, 82, - 128, 78, 65, 81, 128, 78, 65, 79, 211, 78, 65, 78, 83, 65, 78, 65, 81, - 128, 78, 65, 78, 71, 77, 79, 78, 84, 72, 79, 128, 78, 65, 78, 68, 73, 78, - 65, 71, 65, 82, 201, 78, 65, 78, 68, 128, 78, 65, 78, 65, 128, 78, 65, - 77, 69, 128, 78, 65, 77, 197, 78, 65, 77, 50, 128, 78, 65, 75, 65, 65, - 82, 193, 78, 65, 75, 128, 78, 65, 73, 82, 193, 78, 65, 73, 204, 78, 65, - 71, 82, 201, 78, 65, 71, 65, 82, 128, 78, 65, 71, 65, 128, 78, 65, 71, - 193, 78, 65, 71, 128, 78, 65, 199, 78, 65, 69, 128, 78, 65, 66, 76, 65, - 128, 78, 65, 66, 65, 84, 65, 69, 65, 206, 78, 65, 65, 83, 73, 75, 89, 65, - 89, 65, 128, 78, 65, 65, 75, 83, 73, 75, 89, 65, 89, 65, 128, 78, 65, 65, - 73, 128, 78, 65, 193, 78, 65, 52, 128, 78, 65, 50, 128, 78, 65, 45, 57, - 128, 78, 65, 45, 56, 128, 78, 65, 45, 55, 128, 78, 65, 45, 54, 128, 78, - 65, 45, 53, 128, 78, 65, 45, 52, 128, 78, 65, 45, 51, 128, 78, 65, 45, - 50, 128, 78, 65, 45, 49, 128, 78, 48, 52, 50, 128, 78, 48, 52, 49, 128, - 78, 48, 52, 48, 128, 78, 48, 51, 57, 128, 78, 48, 51, 56, 128, 78, 48, - 51, 55, 65, 128, 78, 48, 51, 55, 128, 78, 48, 51, 54, 128, 78, 48, 51, - 53, 65, 128, 78, 48, 51, 53, 128, 78, 48, 51, 52, 65, 128, 78, 48, 51, - 52, 128, 78, 48, 51, 51, 65, 128, 78, 48, 51, 51, 128, 78, 48, 51, 50, - 128, 78, 48, 51, 49, 128, 78, 48, 51, 48, 128, 78, 48, 50, 57, 128, 78, - 48, 50, 56, 128, 78, 48, 50, 55, 128, 78, 48, 50, 54, 128, 78, 48, 50, - 53, 65, 128, 78, 48, 50, 53, 128, 78, 48, 50, 52, 128, 78, 48, 50, 51, - 128, 78, 48, 50, 50, 128, 78, 48, 50, 49, 128, 78, 48, 50, 48, 128, 78, - 48, 49, 57, 128, 78, 48, 49, 56, 66, 128, 78, 48, 49, 56, 65, 128, 78, - 48, 49, 56, 128, 78, 48, 49, 55, 128, 78, 48, 49, 54, 128, 78, 48, 49, - 53, 128, 78, 48, 49, 52, 128, 78, 48, 49, 51, 128, 78, 48, 49, 50, 128, - 78, 48, 49, 49, 128, 78, 48, 49, 48, 128, 78, 48, 48, 57, 128, 78, 48, - 48, 56, 128, 78, 48, 48, 55, 128, 78, 48, 48, 54, 128, 78, 48, 48, 53, - 128, 78, 48, 48, 52, 128, 78, 48, 48, 51, 128, 78, 48, 48, 50, 128, 78, - 48, 48, 49, 128, 78, 45, 77, 85, 45, 77, 79, 45, 50, 128, 78, 45, 77, 85, - 45, 77, 79, 45, 49, 128, 78, 45, 67, 82, 69, 197, 78, 45, 65, 82, 217, - 77, 90, 128, 77, 89, 88, 128, 77, 89, 84, 128, 77, 89, 83, 76, 73, 84, - 69, 128, 77, 89, 80, 128, 77, 89, 65, 128, 77, 89, 193, 77, 87, 79, 79, - 128, 77, 87, 79, 128, 77, 87, 73, 73, 128, 77, 87, 73, 128, 77, 87, 69, - 69, 128, 77, 87, 69, 128, 77, 87, 65, 65, 128, 77, 87, 65, 128, 77, 87, - 128, 77, 215, 77, 86, 83, 128, 77, 86, 79, 80, 128, 77, 86, 73, 128, 77, - 86, 69, 85, 65, 69, 78, 71, 65, 77, 128, 77, 86, 128, 77, 214, 77, 85, - 88, 128, 77, 85, 85, 86, 85, 90, 72, 65, 75, 75, 85, 128, 77, 85, 85, 83, - 73, 75, 65, 84, 79, 65, 78, 128, 77, 85, 85, 82, 68, 72, 65, 74, 193, 77, - 85, 85, 128, 77, 85, 84, 72, 65, 76, 73, 89, 65, 128, 77, 85, 84, 128, - 77, 85, 83, 73, 67, 128, 77, 85, 83, 73, 195, 77, 85, 83, 72, 82, 79, 79, - 77, 128, 77, 85, 83, 72, 51, 128, 77, 85, 83, 72, 179, 77, 85, 83, 72, - 128, 77, 85, 83, 200, 77, 85, 83, 128, 77, 85, 82, 88, 128, 77, 85, 82, - 71, 85, 50, 128, 77, 85, 82, 69, 128, 77, 85, 82, 68, 65, 128, 77, 85, - 82, 68, 193, 77, 85, 82, 128, 77, 85, 81, 68, 65, 77, 128, 77, 85, 80, - 128, 77, 85, 79, 88, 128, 77, 85, 79, 84, 128, 77, 85, 79, 80, 128, 77, - 85, 79, 77, 65, 69, 128, 77, 85, 79, 128, 77, 85, 78, 83, 85, 66, 128, - 77, 85, 78, 65, 72, 128, 77, 85, 78, 128, 77, 85, 76, 84, 73, 83, 69, 84, + 67, 197, 80, 69, 193, 80, 68, 73, 128, 80, 68, 70, 128, 80, 68, 128, 80, + 67, 128, 80, 65, 90, 69, 82, 128, 80, 65, 89, 69, 82, 79, 75, 128, 80, + 65, 89, 65, 78, 78, 65, 128, 80, 65, 89, 128, 80, 65, 88, 128, 80, 65, + 87, 78, 128, 80, 65, 87, 206, 80, 65, 215, 80, 65, 86, 73, 89, 65, 78, + 73, 128, 80, 65, 85, 83, 197, 80, 65, 85, 75, 128, 80, 65, 85, 128, 80, + 65, 213, 80, 65, 84, 84, 217, 80, 65, 84, 84, 69, 82, 78, 128, 80, 65, + 84, 72, 65, 77, 65, 83, 65, 84, 128, 80, 65, 84, 72, 65, 75, 75, 85, 128, + 80, 65, 84, 200, 80, 65, 84, 65, 75, 128, 80, 65, 84, 65, 72, 128, 80, + 65, 84, 128, 80, 65, 83, 85, 81, 128, 80, 65, 83, 83, 80, 79, 82, 212, + 80, 65, 83, 83, 73, 86, 69, 45, 80, 85, 76, 76, 45, 85, 80, 45, 79, 85, + 84, 80, 85, 212, 80, 65, 83, 83, 73, 86, 69, 45, 80, 85, 76, 76, 45, 68, + 79, 87, 78, 45, 79, 85, 84, 80, 85, 212, 80, 65, 83, 83, 73, 77, 66, 65, + 78, 71, 128, 80, 65, 83, 83, 69, 78, 71, 69, 210, 80, 65, 83, 83, 69, + 196, 80, 65, 83, 72, 84, 65, 128, 80, 65, 83, 72, 65, 69, 128, 80, 65, + 83, 69, 81, 128, 80, 65, 83, 65, 78, 71, 65, 206, 80, 65, 82, 85, 77, + 128, 80, 65, 82, 84, 217, 80, 65, 82, 84, 78, 69, 82, 83, 72, 73, 208, + 80, 65, 82, 84, 73, 65, 76, 76, 89, 45, 82, 69, 67, 89, 67, 76, 69, 196, + 80, 65, 82, 84, 73, 65, 204, 80, 65, 82, 84, 72, 73, 65, 206, 80, 65, 82, + 212, 80, 65, 82, 82, 79, 84, 128, 80, 65, 82, 75, 128, 80, 65, 82, 73, + 67, 72, 79, 78, 128, 80, 65, 82, 69, 83, 84, 73, 71, 77, 69, 78, 79, 206, + 80, 65, 82, 69, 82, 69, 78, 128, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, + 83, 128, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, 211, 80, 65, 82, 69, 78, + 84, 72, 69, 83, 69, 211, 80, 65, 82, 65, 80, 72, 82, 65, 83, 197, 80, 65, + 82, 65, 76, 76, 69, 76, 79, 71, 82, 65, 77, 128, 80, 65, 82, 65, 76, 76, + 69, 76, 128, 80, 65, 82, 65, 76, 76, 69, 204, 80, 65, 82, 65, 75, 76, 73, + 84, 73, 75, 73, 128, 80, 65, 82, 65, 75, 76, 73, 84, 73, 75, 201, 80, 65, + 82, 65, 75, 76, 73, 84, 128, 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 193, + 80, 65, 82, 65, 71, 82, 65, 80, 72, 85, 211, 80, 65, 82, 65, 71, 82, 65, + 80, 72, 79, 83, 128, 80, 65, 82, 65, 71, 82, 65, 80, 72, 128, 80, 65, 82, + 65, 71, 82, 65, 80, 200, 80, 65, 82, 65, 67, 72, 85, 84, 69, 128, 80, 65, + 82, 65, 128, 80, 65, 82, 128, 80, 65, 80, 89, 82, 85, 83, 128, 80, 65, + 80, 69, 82, 67, 76, 73, 80, 83, 128, 80, 65, 80, 69, 82, 67, 76, 73, 80, + 128, 80, 65, 80, 69, 82, 128, 80, 65, 80, 69, 210, 80, 65, 80, 128, 80, + 65, 208, 80, 65, 207, 80, 65, 78, 89, 85, 75, 85, 128, 80, 65, 78, 89, + 73, 75, 85, 128, 80, 65, 78, 89, 69, 67, 69, 75, 128, 80, 65, 78, 89, 65, + 78, 71, 71, 65, 128, 80, 65, 78, 89, 65, 75, 82, 65, 128, 80, 65, 78, 84, + 73, 128, 80, 65, 78, 84, 201, 80, 65, 78, 83, 73, 79, 83, 45, 80, 73, 69, + 85, 80, 128, 80, 65, 78, 83, 73, 79, 83, 45, 75, 65, 80, 89, 69, 79, 85, + 78, 80, 73, 69, 85, 80, 128, 80, 65, 78, 79, 78, 71, 79, 78, 65, 78, 128, + 80, 65, 78, 79, 76, 79, 78, 71, 128, 80, 65, 78, 71, 87, 73, 83, 65, 68, + 128, 80, 65, 78, 71, 82, 65, 78, 71, 75, 69, 80, 128, 80, 65, 78, 71, 79, + 76, 65, 84, 128, 80, 65, 78, 71, 76, 79, 78, 71, 128, 80, 65, 78, 71, 76, + 65, 89, 65, 82, 128, 80, 65, 78, 71, 75, 79, 78, 128, 80, 65, 78, 71, 75, + 65, 84, 128, 80, 65, 78, 71, 72, 85, 76, 85, 128, 80, 65, 78, 71, 128, + 80, 65, 78, 69, 85, 76, 69, 85, 78, 71, 128, 80, 65, 78, 68, 193, 80, 65, + 78, 67, 65, 75, 69, 83, 128, 80, 65, 78, 65, 77, 128, 80, 65, 78, 65, 69, + 76, 65, 69, 78, 71, 128, 80, 65, 78, 128, 80, 65, 206, 80, 65, 77, 85, + 78, 71, 75, 65, 72, 128, 80, 65, 77, 85, 68, 80, 79, 68, 128, 80, 65, 77, + 83, 72, 65, 69, 128, 80, 65, 77, 80, 72, 89, 76, 73, 65, 206, 80, 65, 77, + 73, 78, 71, 75, 65, 76, 128, 80, 65, 77, 69, 80, 69, 84, 128, 80, 65, 77, + 69, 78, 69, 78, 71, 128, 80, 65, 77, 65, 68, 65, 128, 80, 65, 77, 65, 68, + 193, 80, 65, 77, 65, 65, 69, 72, 128, 80, 65, 76, 85, 84, 65, 128, 80, + 65, 76, 79, 67, 72, 75, 65, 128, 80, 65, 76, 77, 89, 82, 69, 78, 197, 80, + 65, 76, 77, 211, 80, 65, 76, 77, 128, 80, 65, 76, 205, 80, 65, 76, 76, + 65, 87, 65, 128, 80, 65, 76, 76, 65, 83, 128, 80, 65, 76, 75, 65, 128, + 80, 65, 76, 201, 80, 65, 76, 69, 84, 84, 69, 128, 80, 65, 76, 65, 85, 78, + 199, 80, 65, 76, 65, 84, 65, 76, 73, 90, 69, 196, 80, 65, 76, 65, 84, 65, + 76, 73, 90, 65, 84, 73, 79, 78, 128, 80, 65, 76, 65, 84, 65, 204, 80, 65, + 75, 80, 65, 203, 80, 65, 73, 89, 65, 78, 78, 79, 73, 128, 80, 65, 73, 82, + 84, 72, 82, 65, 128, 80, 65, 73, 82, 69, 196, 80, 65, 73, 78, 84, 66, 82, + 85, 83, 72, 128, 80, 65, 73, 128, 80, 65, 72, 76, 65, 86, 201, 80, 65, + 72, 128, 80, 65, 71, 79, 68, 65, 128, 80, 65, 71, 69, 83, 128, 80, 65, + 71, 69, 82, 128, 80, 65, 71, 197, 80, 65, 68, 77, 193, 80, 65, 68, 68, + 76, 197, 80, 65, 68, 68, 73, 78, 199, 80, 65, 68, 193, 80, 65, 68, 128, + 80, 65, 67, 75, 73, 78, 71, 128, 80, 65, 67, 75, 65, 71, 69, 128, 80, 65, + 65, 84, 85, 128, 80, 65, 65, 83, 69, 78, 84, 79, 128, 80, 65, 65, 82, 65, + 77, 128, 80, 65, 65, 82, 65, 69, 128, 80, 65, 65, 77, 128, 80, 65, 65, + 73, 128, 80, 65, 65, 45, 80, 73, 76, 76, 65, 128, 80, 65, 65, 128, 80, + 50, 128, 80, 48, 49, 49, 128, 80, 48, 49, 48, 128, 80, 48, 48, 57, 128, + 80, 48, 48, 56, 128, 80, 48, 48, 55, 128, 80, 48, 48, 54, 128, 80, 48, + 48, 53, 128, 80, 48, 48, 52, 128, 80, 48, 48, 51, 65, 128, 80, 48, 48, + 51, 128, 80, 48, 48, 50, 128, 80, 48, 48, 49, 65, 128, 80, 48, 48, 49, + 128, 79, 90, 128, 79, 89, 83, 84, 69, 82, 128, 79, 89, 82, 65, 78, 73, + 83, 77, 193, 79, 89, 65, 78, 78, 65, 128, 79, 88, 73, 65, 128, 79, 88, + 73, 193, 79, 88, 69, 73, 65, 201, 79, 88, 69, 73, 193, 79, 87, 76, 128, + 79, 86, 69, 82, 83, 84, 82, 85, 67, 203, 79, 86, 69, 82, 82, 73, 68, 69, + 128, 79, 86, 69, 82, 76, 79, 78, 199, 79, 86, 69, 82, 76, 73, 78, 69, + 128, 79, 86, 69, 82, 76, 65, 89, 128, 79, 86, 69, 82, 76, 65, 217, 79, + 86, 69, 82, 76, 65, 80, 80, 73, 78, 199, 79, 86, 69, 82, 76, 65, 80, 128, + 79, 86, 69, 82, 76, 65, 73, 68, 128, 79, 86, 69, 82, 76, 65, 73, 196, 79, + 86, 69, 82, 72, 69, 65, 84, 69, 196, 79, 86, 69, 82, 66, 65, 82, 128, 79, + 86, 65, 76, 128, 79, 86, 65, 204, 79, 85, 84, 76, 73, 78, 69, 196, 79, + 85, 84, 76, 73, 78, 69, 128, 79, 85, 84, 69, 210, 79, 85, 84, 66, 79, + 216, 79, 85, 78, 75, 73, 193, 79, 85, 78, 67, 69, 128, 79, 85, 78, 67, + 197, 79, 84, 85, 128, 79, 84, 84, 79, 77, 65, 206, 79, 84, 84, 69, 82, + 128, 79, 84, 84, 65, 86, 193, 79, 84, 84, 128, 79, 84, 83, 69, 67, 72, + 75, 65, 128, 79, 84, 72, 69, 82, 211, 79, 84, 72, 69, 210, 79, 84, 72, + 65, 76, 65, 206, 79, 84, 72, 65, 76, 128, 79, 83, 79, 75, 65, 128, 79, + 83, 79, 75, 193, 79, 83, 77, 65, 78, 89, 193, 79, 83, 67, 128, 79, 83, + 65, 71, 197, 79, 82, 84, 72, 79, 71, 79, 78, 65, 204, 79, 82, 84, 72, 79, + 68, 79, 216, 79, 82, 78, 65, 84, 197, 79, 82, 78, 65, 77, 69, 78, 84, 83, + 128, 79, 82, 78, 65, 77, 69, 78, 84, 128, 79, 82, 78, 65, 77, 69, 78, + 212, 79, 82, 75, 72, 79, 206, 79, 82, 73, 89, 193, 79, 82, 73, 71, 73, + 78, 65, 204, 79, 82, 73, 71, 73, 78, 128, 79, 82, 69, 45, 50, 128, 79, + 82, 68, 73, 78, 65, 204, 79, 82, 68, 69, 210, 79, 82, 67, 85, 83, 128, + 79, 82, 67, 72, 73, 68, 128, 79, 82, 65, 78, 71, 85, 84, 65, 78, 128, 79, + 82, 65, 78, 71, 197, 79, 80, 84, 73, 79, 206, 79, 80, 84, 73, 67, 65, + 204, 79, 80, 80, 82, 69, 83, 83, 73, 79, 78, 128, 79, 80, 80, 79, 83, 73, + 84, 73, 79, 78, 128, 79, 80, 80, 79, 83, 73, 78, 199, 79, 80, 80, 79, 83, + 69, 128, 79, 80, 72, 73, 85, 67, 72, 85, 83, 128, 79, 80, 69, 82, 65, 84, + 79, 82, 128, 79, 80, 69, 82, 65, 84, 79, 210, 79, 80, 69, 82, 65, 84, 73, + 78, 199, 79, 80, 69, 78, 73, 78, 199, 79, 80, 69, 78, 45, 80, 128, 79, + 80, 69, 78, 45, 79, 85, 84, 76, 73, 78, 69, 196, 79, 80, 69, 78, 45, 79, + 128, 79, 80, 69, 78, 45, 207, 79, 80, 69, 78, 45, 72, 69, 65, 68, 69, + 196, 79, 80, 69, 78, 45, 67, 73, 82, 67, 85, 73, 84, 45, 79, 85, 84, 80, + 85, 212, 79, 80, 69, 78, 128, 79, 80, 69, 206, 79, 79, 90, 69, 128, 79, + 79, 89, 65, 78, 78, 65, 128, 79, 79, 85, 128, 79, 79, 77, 85, 128, 79, + 79, 72, 128, 79, 79, 69, 128, 79, 79, 66, 79, 79, 70, 73, 76, 73, 128, + 79, 78, 85, 128, 79, 78, 83, 85, 128, 79, 78, 78, 128, 79, 78, 75, 65, + 82, 128, 79, 78, 73, 79, 78, 128, 79, 78, 69, 83, 69, 76, 70, 128, 79, + 78, 69, 45, 87, 65, 217, 79, 78, 69, 45, 84, 72, 73, 82, 84, 89, 128, 79, + 78, 69, 45, 80, 73, 69, 67, 197, 79, 78, 69, 45, 76, 73, 78, 197, 79, 78, + 69, 45, 72, 85, 78, 68, 82, 69, 68, 45, 65, 78, 68, 45, 83, 73, 88, 84, + 73, 69, 84, 72, 128, 79, 78, 67, 79, 77, 73, 78, 199, 79, 78, 65, 80, + 128, 79, 78, 45, 79, 70, 198, 79, 77, 73, 83, 83, 73, 79, 206, 79, 77, + 73, 67, 82, 79, 78, 128, 79, 77, 73, 67, 82, 79, 206, 79, 77, 69, 84, + 128, 79, 77, 69, 71, 65, 128, 79, 77, 69, 71, 193, 79, 77, 65, 76, 79, + 78, 128, 79, 76, 73, 86, 69, 128, 79, 76, 73, 71, 79, 206, 79, 76, 68, + 128, 79, 75, 84, 207, 79, 75, 65, 82, 65, 128, 79, 75, 65, 82, 193, 79, + 74, 79, 68, 128, 79, 74, 73, 66, 87, 65, 217, 79, 74, 69, 79, 78, 128, + 79, 73, 78, 128, 79, 73, 76, 128, 79, 73, 204, 79, 72, 77, 128, 79, 72, + 205, 79, 71, 82, 69, 128, 79, 71, 79, 78, 69, 75, 128, 79, 71, 79, 78, + 69, 203, 79, 71, 72, 65, 205, 79, 70, 70, 73, 67, 69, 82, 128, 79, 70, + 70, 73, 67, 69, 128, 79, 70, 70, 73, 67, 197, 79, 70, 70, 128, 79, 69, + 89, 128, 79, 69, 82, 128, 79, 69, 75, 128, 79, 69, 69, 128, 79, 68, 69, + 78, 128, 79, 68, 68, 128, 79, 68, 196, 79, 67, 84, 79, 80, 85, 83, 128, + 79, 67, 84, 79, 66, 69, 82, 128, 79, 67, 84, 69, 212, 79, 67, 84, 65, 71, + 79, 78, 65, 204, 79, 67, 84, 65, 71, 79, 78, 128, 79, 67, 210, 79, 67, + 76, 79, 67, 75, 128, 79, 67, 72, 75, 79, 77, 128, 79, 67, 67, 85, 76, 84, + 65, 84, 73, 79, 78, 128, 79, 67, 67, 76, 85, 83, 73, 79, 78, 128, 79, 66, + 83, 84, 82, 85, 67, 84, 73, 79, 78, 128, 79, 66, 83, 69, 82, 86, 69, 210, + 79, 66, 79, 76, 211, 79, 66, 79, 204, 79, 66, 79, 70, 73, 76, 73, 128, + 79, 66, 76, 73, 81, 85, 197, 79, 66, 76, 65, 75, 79, 128, 79, 66, 76, 65, + 67, 72, 75, 79, 128, 79, 66, 74, 69, 67, 212, 79, 66, 69, 76, 85, 83, + 128, 79, 66, 69, 76, 79, 83, 128, 79, 66, 128, 79, 65, 89, 128, 79, 65, + 75, 128, 79, 65, 66, 79, 65, 70, 73, 76, 73, 128, 79, 193, 79, 48, 53, + 49, 128, 79, 48, 53, 48, 66, 128, 79, 48, 53, 48, 65, 128, 79, 48, 53, + 48, 128, 79, 48, 52, 57, 128, 79, 48, 52, 56, 128, 79, 48, 52, 55, 128, + 79, 48, 52, 54, 128, 79, 48, 52, 53, 128, 79, 48, 52, 52, 128, 79, 48, + 52, 51, 128, 79, 48, 52, 50, 128, 79, 48, 52, 49, 128, 79, 48, 52, 48, + 128, 79, 48, 51, 57, 128, 79, 48, 51, 56, 128, 79, 48, 51, 55, 128, 79, + 48, 51, 54, 68, 128, 79, 48, 51, 54, 67, 128, 79, 48, 51, 54, 66, 128, + 79, 48, 51, 54, 65, 128, 79, 48, 51, 54, 128, 79, 48, 51, 53, 128, 79, + 48, 51, 52, 128, 79, 48, 51, 51, 65, 128, 79, 48, 51, 51, 128, 79, 48, + 51, 50, 128, 79, 48, 51, 49, 128, 79, 48, 51, 48, 65, 128, 79, 48, 51, + 48, 128, 79, 48, 50, 57, 65, 128, 79, 48, 50, 57, 128, 79, 48, 50, 56, + 128, 79, 48, 50, 55, 128, 79, 48, 50, 54, 128, 79, 48, 50, 53, 65, 128, + 79, 48, 50, 53, 128, 79, 48, 50, 52, 65, 128, 79, 48, 50, 52, 128, 79, + 48, 50, 51, 128, 79, 48, 50, 50, 128, 79, 48, 50, 49, 128, 79, 48, 50, + 48, 65, 128, 79, 48, 50, 48, 128, 79, 48, 49, 57, 65, 128, 79, 48, 49, + 57, 128, 79, 48, 49, 56, 128, 79, 48, 49, 55, 128, 79, 48, 49, 54, 128, + 79, 48, 49, 53, 128, 79, 48, 49, 52, 128, 79, 48, 49, 51, 128, 79, 48, + 49, 50, 128, 79, 48, 49, 49, 128, 79, 48, 49, 48, 67, 128, 79, 48, 49, + 48, 66, 128, 79, 48, 49, 48, 65, 128, 79, 48, 49, 48, 128, 79, 48, 48, + 57, 128, 79, 48, 48, 56, 128, 79, 48, 48, 55, 128, 79, 48, 48, 54, 70, + 128, 79, 48, 48, 54, 69, 128, 79, 48, 48, 54, 68, 128, 79, 48, 48, 54, + 67, 128, 79, 48, 48, 54, 66, 128, 79, 48, 48, 54, 65, 128, 79, 48, 48, + 54, 128, 79, 48, 48, 53, 65, 128, 79, 48, 48, 53, 128, 79, 48, 48, 52, + 128, 79, 48, 48, 51, 128, 79, 48, 48, 50, 128, 79, 48, 48, 49, 65, 128, + 79, 48, 48, 49, 128, 79, 45, 89, 69, 128, 79, 45, 79, 45, 73, 128, 79, + 45, 69, 128, 78, 90, 89, 88, 128, 78, 90, 89, 84, 128, 78, 90, 89, 82, + 88, 128, 78, 90, 89, 82, 128, 78, 90, 89, 80, 128, 78, 90, 89, 128, 78, + 90, 85, 88, 128, 78, 90, 85, 82, 88, 128, 78, 90, 85, 82, 128, 78, 90, + 85, 81, 128, 78, 90, 85, 80, 128, 78, 90, 85, 79, 88, 128, 78, 90, 85, + 79, 128, 78, 90, 85, 206, 78, 90, 85, 128, 78, 90, 79, 88, 128, 78, 90, + 79, 80, 128, 78, 90, 73, 88, 128, 78, 90, 73, 84, 128, 78, 90, 73, 80, + 128, 78, 90, 73, 69, 88, 128, 78, 90, 73, 69, 80, 128, 78, 90, 73, 69, + 128, 78, 90, 73, 128, 78, 90, 69, 88, 128, 78, 90, 69, 85, 77, 128, 78, + 90, 69, 128, 78, 90, 65, 88, 128, 78, 90, 65, 84, 128, 78, 90, 65, 81, + 128, 78, 90, 65, 80, 128, 78, 90, 65, 128, 78, 90, 193, 78, 89, 87, 65, + 128, 78, 89, 85, 88, 128, 78, 89, 85, 85, 128, 78, 89, 85, 84, 128, 78, + 89, 85, 80, 128, 78, 89, 85, 79, 88, 128, 78, 89, 85, 79, 80, 128, 78, + 89, 85, 79, 128, 78, 89, 85, 78, 128, 78, 89, 85, 69, 128, 78, 89, 85, + 128, 78, 89, 79, 88, 128, 78, 89, 79, 84, 128, 78, 89, 79, 80, 128, 78, + 89, 79, 79, 128, 78, 89, 79, 78, 128, 78, 89, 79, 65, 128, 78, 89, 79, + 128, 78, 89, 74, 65, 128, 78, 89, 73, 88, 128, 78, 89, 73, 84, 128, 78, + 89, 73, 212, 78, 89, 73, 211, 78, 89, 73, 210, 78, 89, 73, 80, 128, 78, + 89, 73, 78, 45, 68, 79, 128, 78, 89, 73, 78, 128, 78, 89, 73, 73, 128, + 78, 89, 73, 69, 88, 128, 78, 89, 73, 69, 84, 128, 78, 89, 73, 69, 80, + 128, 78, 89, 73, 69, 128, 78, 89, 73, 65, 75, 69, 78, 199, 78, 89, 73, + 128, 78, 89, 201, 78, 89, 72, 65, 128, 78, 89, 69, 84, 128, 78, 89, 69, + 212, 78, 89, 69, 78, 128, 78, 89, 69, 72, 128, 78, 89, 69, 200, 78, 89, + 69, 69, 128, 78, 89, 69, 128, 78, 89, 196, 78, 89, 67, 65, 128, 78, 89, + 65, 85, 128, 78, 89, 65, 74, 128, 78, 89, 65, 73, 128, 78, 89, 65, 72, + 128, 78, 89, 65, 69, 77, 65, 69, 128, 78, 89, 65, 65, 128, 78, 87, 79, + 79, 128, 78, 87, 79, 128, 78, 87, 73, 73, 128, 78, 87, 73, 128, 78, 87, + 69, 128, 78, 87, 65, 65, 128, 78, 87, 65, 128, 78, 87, 128, 78, 86, 128, + 78, 85, 88, 128, 78, 85, 85, 78, 128, 78, 85, 85, 128, 78, 85, 84, 73, + 76, 76, 85, 128, 78, 85, 84, 128, 78, 85, 212, 78, 85, 82, 88, 128, 78, + 85, 82, 128, 78, 85, 80, 128, 78, 85, 79, 88, 128, 78, 85, 79, 80, 128, + 78, 85, 79, 128, 78, 85, 78, 85, 90, 128, 78, 85, 78, 85, 218, 78, 85, + 78, 71, 128, 78, 85, 78, 65, 86, 85, 212, 78, 85, 78, 65, 86, 73, 203, + 78, 85, 78, 128, 78, 85, 206, 78, 85, 77, 69, 82, 207, 78, 85, 77, 69, + 82, 65, 84, 79, 210, 78, 85, 77, 69, 82, 65, 204, 78, 85, 77, 66, 69, 82, + 83, 128, 78, 85, 77, 66, 69, 82, 128, 78, 85, 77, 128, 78, 85, 76, 76, + 128, 78, 85, 76, 204, 78, 85, 76, 128, 78, 85, 75, 84, 65, 128, 78, 85, + 75, 84, 193, 78, 85, 69, 78, 71, 128, 78, 85, 69, 128, 78, 85, 66, 73, + 65, 206, 78, 85, 65, 69, 128, 78, 85, 49, 49, 128, 78, 85, 49, 177, 78, + 85, 48, 50, 50, 65, 128, 78, 85, 48, 50, 50, 128, 78, 85, 48, 50, 49, + 128, 78, 85, 48, 50, 48, 128, 78, 85, 48, 49, 57, 128, 78, 85, 48, 49, + 56, 65, 128, 78, 85, 48, 49, 56, 128, 78, 85, 48, 49, 55, 128, 78, 85, + 48, 49, 54, 128, 78, 85, 48, 49, 53, 128, 78, 85, 48, 49, 52, 128, 78, + 85, 48, 49, 51, 128, 78, 85, 48, 49, 50, 128, 78, 85, 48, 49, 49, 65, + 128, 78, 85, 48, 49, 49, 128, 78, 85, 48, 49, 48, 65, 128, 78, 85, 48, + 49, 48, 128, 78, 85, 48, 48, 57, 128, 78, 85, 48, 48, 56, 128, 78, 85, + 48, 48, 55, 128, 78, 85, 48, 48, 54, 128, 78, 85, 48, 48, 53, 128, 78, + 85, 48, 48, 52, 128, 78, 85, 48, 48, 51, 128, 78, 85, 48, 48, 50, 128, + 78, 85, 48, 48, 49, 128, 78, 85, 45, 51, 128, 78, 85, 45, 50, 128, 78, + 85, 45, 49, 128, 78, 84, 88, 73, 86, 128, 78, 84, 88, 65, 128, 78, 84, + 85, 85, 128, 78, 84, 85, 77, 128, 78, 84, 85, 74, 128, 78, 84, 213, 78, + 84, 83, 65, 85, 128, 78, 84, 83, 65, 128, 78, 84, 79, 81, 80, 69, 78, + 128, 78, 84, 79, 71, 128, 78, 84, 79, 199, 78, 84, 73, 69, 197, 78, 84, + 72, 65, 85, 128, 78, 84, 69, 85, 78, 71, 66, 65, 128, 78, 84, 69, 85, 77, + 128, 78, 84, 69, 78, 128, 78, 84, 69, 69, 128, 78, 84, 65, 80, 128, 78, + 84, 65, 208, 78, 84, 65, 65, 128, 78, 84, 65, 128, 78, 83, 85, 79, 212, + 78, 83, 85, 78, 128, 78, 83, 85, 77, 128, 78, 83, 79, 77, 128, 78, 83, + 73, 69, 69, 84, 128, 78, 83, 73, 69, 69, 80, 128, 78, 83, 73, 69, 69, + 128, 78, 83, 72, 85, 84, 128, 78, 83, 72, 85, 212, 78, 83, 72, 85, 79, + 80, 128, 78, 83, 72, 85, 69, 128, 78, 83, 72, 73, 69, 69, 128, 78, 83, + 72, 69, 69, 128, 78, 83, 72, 65, 81, 128, 78, 83, 72, 65, 128, 78, 83, + 69, 85, 65, 69, 78, 128, 78, 83, 69, 78, 128, 78, 83, 65, 128, 78, 82, + 89, 88, 128, 78, 82, 89, 84, 128, 78, 82, 89, 82, 88, 128, 78, 82, 89, + 82, 128, 78, 82, 89, 80, 128, 78, 82, 89, 128, 78, 82, 85, 88, 128, 78, + 82, 85, 84, 128, 78, 82, 85, 82, 88, 128, 78, 82, 85, 82, 128, 78, 82, + 85, 80, 128, 78, 82, 85, 65, 128, 78, 82, 85, 128, 78, 82, 79, 88, 128, + 78, 82, 79, 80, 128, 78, 82, 79, 128, 78, 82, 69, 88, 128, 78, 82, 69, + 84, 128, 78, 82, 69, 211, 78, 82, 69, 80, 128, 78, 82, 69, 128, 78, 82, + 65, 88, 128, 78, 82, 65, 84, 128, 78, 82, 65, 80, 128, 78, 82, 65, 128, + 78, 81, 73, 71, 128, 78, 81, 65, 128, 78, 80, 76, 65, 128, 78, 80, 65, + 128, 78, 79, 90, 72, 75, 65, 128, 78, 79, 89, 128, 78, 79, 88, 128, 78, + 79, 87, 67, 128, 78, 79, 86, 73, 76, 69, 128, 78, 79, 86, 69, 77, 66, 69, + 82, 128, 78, 79, 84, 84, 79, 128, 78, 79, 84, 69, 83, 128, 78, 79, 84, + 69, 72, 69, 65, 68, 128, 78, 79, 84, 69, 72, 69, 65, 196, 78, 79, 84, 69, + 66, 79, 79, 75, 128, 78, 79, 84, 69, 66, 79, 79, 203, 78, 79, 84, 69, + 128, 78, 79, 84, 197, 78, 79, 84, 67, 72, 69, 196, 78, 79, 84, 67, 72, + 128, 78, 79, 84, 65, 84, 73, 79, 206, 78, 79, 84, 128, 78, 79, 212, 78, + 79, 83, 69, 128, 78, 79, 83, 197, 78, 79, 82, 84, 72, 87, 69, 83, 212, + 78, 79, 82, 84, 72, 69, 82, 206, 78, 79, 82, 84, 72, 69, 65, 83, 84, 45, + 80, 79, 73, 78, 84, 73, 78, 199, 78, 79, 82, 77, 65, 204, 78, 79, 82, 68, + 73, 195, 78, 79, 210, 78, 79, 80, 128, 78, 79, 79, 78, 85, 128, 78, 79, + 79, 128, 78, 79, 78, 70, 79, 82, 75, 73, 78, 71, 128, 78, 79, 78, 45, 80, + 79, 84, 65, 66, 76, 197, 78, 79, 78, 45, 74, 79, 73, 78, 69, 82, 128, 78, + 79, 78, 45, 66, 82, 69, 65, 75, 73, 78, 199, 78, 79, 78, 128, 78, 79, 77, + 73, 83, 77, 193, 78, 79, 77, 73, 78, 65, 204, 78, 79, 75, 72, 85, 75, + 128, 78, 79, 68, 69, 128, 78, 79, 65, 128, 78, 79, 45, 66, 82, 69, 65, + 203, 78, 79, 45, 53, 128, 78, 79, 45, 52, 128, 78, 79, 45, 51, 128, 78, + 79, 45, 50, 128, 78, 79, 45, 49, 128, 78, 78, 85, 85, 128, 78, 78, 85, + 128, 78, 78, 79, 79, 128, 78, 78, 78, 85, 85, 128, 78, 78, 78, 85, 128, + 78, 78, 78, 79, 79, 128, 78, 78, 78, 79, 128, 78, 78, 78, 73, 73, 128, + 78, 78, 78, 73, 128, 78, 78, 78, 69, 69, 128, 78, 78, 78, 69, 128, 78, + 78, 78, 65, 85, 128, 78, 78, 78, 65, 73, 128, 78, 78, 78, 65, 65, 128, + 78, 78, 78, 65, 128, 78, 78, 78, 128, 78, 78, 72, 65, 128, 78, 78, 71, + 79, 79, 128, 78, 78, 71, 79, 128, 78, 78, 71, 73, 73, 128, 78, 78, 71, + 73, 128, 78, 78, 71, 65, 65, 128, 78, 78, 71, 65, 128, 78, 78, 71, 128, + 78, 78, 66, 83, 80, 128, 78, 77, 128, 78, 76, 65, 85, 128, 78, 76, 48, + 50, 48, 128, 78, 76, 48, 49, 57, 128, 78, 76, 48, 49, 56, 128, 78, 76, + 48, 49, 55, 65, 128, 78, 76, 48, 49, 55, 128, 78, 76, 48, 49, 54, 128, + 78, 76, 48, 49, 53, 128, 78, 76, 48, 49, 52, 128, 78, 76, 48, 49, 51, + 128, 78, 76, 48, 49, 50, 128, 78, 76, 48, 49, 49, 128, 78, 76, 48, 49, + 48, 128, 78, 76, 48, 48, 57, 128, 78, 76, 48, 48, 56, 128, 78, 76, 48, + 48, 55, 128, 78, 76, 48, 48, 54, 128, 78, 76, 48, 48, 53, 65, 128, 78, + 76, 48, 48, 53, 128, 78, 76, 48, 48, 52, 128, 78, 76, 48, 48, 51, 128, + 78, 76, 48, 48, 50, 128, 78, 76, 48, 48, 49, 128, 78, 76, 128, 78, 75, + 79, 77, 128, 78, 75, 207, 78, 75, 73, 78, 68, 73, 128, 78, 75, 65, 85, + 128, 78, 75, 65, 65, 82, 65, 69, 128, 78, 75, 65, 128, 78, 74, 89, 88, + 128, 78, 74, 89, 84, 128, 78, 74, 89, 82, 88, 128, 78, 74, 89, 82, 128, + 78, 74, 89, 80, 128, 78, 74, 89, 128, 78, 74, 85, 88, 128, 78, 74, 85, + 82, 88, 128, 78, 74, 85, 82, 128, 78, 74, 85, 81, 65, 128, 78, 74, 85, + 80, 128, 78, 74, 85, 79, 88, 128, 78, 74, 85, 79, 128, 78, 74, 85, 69, + 81, 128, 78, 74, 85, 65, 69, 128, 78, 74, 85, 128, 78, 74, 79, 88, 128, + 78, 74, 79, 84, 128, 78, 74, 79, 80, 128, 78, 74, 79, 79, 128, 78, 74, + 79, 128, 78, 74, 73, 88, 128, 78, 74, 73, 84, 128, 78, 74, 73, 80, 128, + 78, 74, 73, 69, 88, 128, 78, 74, 73, 69, 84, 128, 78, 74, 73, 69, 80, + 128, 78, 74, 73, 69, 69, 128, 78, 74, 73, 69, 128, 78, 74, 73, 128, 78, + 74, 201, 78, 74, 69, 85, 88, 128, 78, 74, 69, 85, 84, 128, 78, 74, 69, + 85, 65, 69, 78, 65, 128, 78, 74, 69, 85, 65, 69, 77, 128, 78, 74, 69, 69, + 69, 69, 128, 78, 74, 69, 69, 128, 78, 74, 69, 197, 78, 74, 69, 128, 78, + 74, 65, 81, 128, 78, 74, 65, 80, 128, 78, 74, 65, 69, 77, 76, 73, 128, + 78, 74, 65, 69, 77, 128, 78, 74, 65, 65, 128, 78, 73, 90, 75, 207, 78, + 73, 88, 128, 78, 73, 84, 82, 69, 128, 78, 73, 83, 65, 71, 128, 78, 73, + 82, 85, 71, 85, 128, 78, 73, 80, 128, 78, 73, 78, 84, 72, 128, 78, 73, + 78, 74, 65, 128, 78, 73, 78, 69, 84, 89, 128, 78, 73, 78, 69, 84, 217, + 78, 73, 78, 69, 84, 69, 69, 78, 128, 78, 73, 78, 69, 84, 69, 69, 206, 78, + 73, 78, 69, 45, 84, 72, 73, 82, 84, 89, 128, 78, 73, 78, 69, 45, 76, 73, + 75, 197, 78, 73, 78, 197, 78, 73, 78, 68, 65, 50, 128, 78, 73, 78, 68, + 65, 178, 78, 73, 78, 57, 128, 78, 73, 78, 128, 78, 73, 77, 128, 78, 73, + 205, 78, 73, 75, 79, 76, 83, 66, 85, 82, 199, 78, 73, 75, 72, 65, 72, 73, + 84, 128, 78, 73, 75, 65, 72, 73, 84, 128, 78, 73, 75, 65, 128, 78, 73, + 72, 83, 72, 86, 65, 83, 65, 128, 78, 73, 71, 73, 68, 65, 77, 73, 78, 128, + 78, 73, 71, 73, 68, 65, 69, 83, 72, 128, 78, 73, 71, 72, 84, 128, 78, 73, + 71, 72, 212, 78, 73, 71, 71, 65, 72, 73, 84, 65, 128, 78, 73, 69, 88, + 128, 78, 73, 69, 85, 78, 45, 84, 73, 75, 69, 85, 84, 128, 78, 73, 69, 85, + 78, 45, 84, 72, 73, 69, 85, 84, 72, 128, 78, 73, 69, 85, 78, 45, 83, 73, + 79, 83, 128, 78, 73, 69, 85, 78, 45, 82, 73, 69, 85, 76, 128, 78, 73, 69, + 85, 78, 45, 80, 73, 69, 85, 80, 128, 78, 73, 69, 85, 78, 45, 80, 65, 78, + 83, 73, 79, 83, 128, 78, 73, 69, 85, 78, 45, 75, 73, 89, 69, 79, 75, 128, + 78, 73, 69, 85, 78, 45, 72, 73, 69, 85, 72, 128, 78, 73, 69, 85, 78, 45, + 67, 73, 69, 85, 67, 128, 78, 73, 69, 85, 78, 45, 67, 72, 73, 69, 85, 67, + 72, 128, 78, 73, 69, 85, 206, 78, 73, 69, 80, 128, 78, 73, 69, 128, 78, + 73, 66, 128, 78, 73, 65, 128, 78, 73, 50, 128, 78, 73, 45, 84, 69, 128, + 78, 73, 45, 55, 128, 78, 73, 45, 54, 128, 78, 73, 45, 53, 128, 78, 73, + 45, 52, 128, 78, 73, 45, 51, 128, 78, 73, 45, 50, 128, 78, 73, 45, 49, + 128, 78, 72, 85, 69, 128, 78, 72, 74, 65, 128, 78, 72, 65, 89, 128, 78, + 72, 128, 78, 71, 89, 69, 128, 78, 71, 86, 69, 128, 78, 71, 85, 85, 128, + 78, 71, 85, 79, 88, 128, 78, 71, 85, 79, 84, 128, 78, 71, 85, 79, 128, + 78, 71, 85, 65, 78, 128, 78, 71, 85, 65, 69, 84, 128, 78, 71, 85, 65, 69, + 128, 78, 71, 79, 88, 128, 78, 71, 79, 85, 128, 78, 71, 79, 213, 78, 71, + 79, 84, 128, 78, 71, 79, 81, 128, 78, 71, 79, 80, 128, 78, 71, 79, 78, + 128, 78, 71, 79, 77, 128, 78, 71, 79, 69, 72, 128, 78, 71, 79, 69, 200, + 78, 71, 207, 78, 71, 75, 89, 69, 69, 128, 78, 71, 75, 87, 65, 69, 78, + 128, 78, 71, 75, 85, 80, 128, 78, 71, 75, 85, 78, 128, 78, 71, 75, 85, + 77, 128, 78, 71, 75, 85, 69, 78, 90, 69, 85, 77, 128, 78, 71, 75, 85, + 197, 78, 71, 75, 73, 78, 68, 201, 78, 71, 75, 73, 69, 69, 128, 78, 71, + 75, 69, 85, 88, 128, 78, 71, 75, 69, 85, 82, 73, 128, 78, 71, 75, 69, 85, + 65, 69, 81, 128, 78, 71, 75, 69, 85, 65, 69, 77, 128, 78, 71, 75, 65, 81, + 128, 78, 71, 75, 65, 80, 128, 78, 71, 75, 65, 65, 77, 73, 128, 78, 71, + 75, 65, 128, 78, 71, 73, 69, 88, 128, 78, 71, 73, 69, 80, 128, 78, 71, + 73, 69, 128, 78, 71, 72, 65, 128, 78, 71, 71, 87, 65, 69, 78, 128, 78, + 71, 71, 85, 82, 65, 69, 128, 78, 71, 71, 85, 80, 128, 78, 71, 71, 85, 79, + 81, 128, 78, 71, 71, 85, 79, 209, 78, 71, 71, 85, 79, 78, 128, 78, 71, + 71, 85, 79, 77, 128, 78, 71, 71, 85, 77, 128, 78, 71, 71, 85, 69, 69, 84, + 128, 78, 71, 71, 85, 65, 69, 83, 72, 65, 197, 78, 71, 71, 85, 65, 69, + 206, 78, 71, 71, 85, 65, 128, 78, 71, 71, 85, 128, 78, 71, 71, 79, 79, + 128, 78, 71, 71, 79, 128, 78, 71, 71, 73, 128, 78, 71, 71, 69, 85, 88, + 128, 78, 71, 71, 69, 85, 65, 69, 84, 128, 78, 71, 71, 69, 85, 65, 69, + 128, 78, 71, 71, 69, 213, 78, 71, 71, 69, 78, 128, 78, 71, 71, 69, 69, + 84, 128, 78, 71, 71, 69, 69, 69, 69, 128, 78, 71, 71, 69, 69, 128, 78, + 71, 71, 69, 128, 78, 71, 71, 65, 80, 128, 78, 71, 71, 65, 65, 77, 65, 69, + 128, 78, 71, 71, 65, 65, 77, 128, 78, 71, 71, 65, 65, 128, 78, 71, 71, + 128, 78, 71, 69, 88, 128, 78, 71, 69, 85, 82, 69, 85, 84, 128, 78, 71, + 69, 80, 128, 78, 71, 69, 78, 128, 78, 71, 69, 69, 128, 78, 71, 69, 65, + 68, 65, 76, 128, 78, 71, 65, 88, 128, 78, 71, 65, 85, 128, 78, 71, 65, + 84, 128, 78, 71, 65, 211, 78, 71, 65, 81, 128, 78, 71, 65, 80, 128, 78, + 71, 65, 78, 71, 85, 128, 78, 71, 65, 78, 128, 78, 71, 65, 73, 128, 78, + 71, 65, 72, 128, 78, 71, 65, 65, 73, 128, 78, 71, 193, 78, 70, 128, 78, + 69, 88, 212, 78, 69, 88, 128, 78, 69, 87, 83, 80, 65, 80, 69, 82, 128, + 78, 69, 87, 76, 73, 78, 69, 128, 78, 69, 87, 76, 73, 78, 197, 78, 69, 87, + 193, 78, 69, 87, 128, 78, 69, 215, 78, 69, 85, 84, 82, 65, 76, 128, 78, + 69, 85, 84, 82, 65, 204, 78, 69, 85, 84, 69, 82, 128, 78, 69, 84, 87, 79, + 82, 75, 69, 196, 78, 69, 212, 78, 69, 83, 84, 73, 78, 199, 78, 69, 83, + 84, 69, 196, 78, 69, 83, 84, 128, 78, 69, 83, 212, 78, 69, 83, 83, 85, + 83, 128, 78, 69, 82, 196, 78, 69, 81, 85, 68, 65, 65, 128, 78, 69, 80, + 84, 85, 78, 69, 128, 78, 69, 80, 84, 85, 78, 197, 78, 69, 80, 79, 83, 84, + 79, 89, 65, 78, 78, 65, 89, 65, 128, 78, 69, 80, 128, 78, 69, 79, 128, + 78, 69, 207, 78, 69, 78, 79, 69, 128, 78, 69, 78, 65, 78, 79, 128, 78, + 69, 78, 128, 78, 69, 77, 75, 65, 128, 78, 69, 76, 128, 78, 69, 73, 84, + 72, 69, 210, 78, 69, 71, 65, 84, 73, 86, 197, 78, 69, 71, 65, 84, 73, 79, + 206, 78, 69, 71, 65, 84, 69, 196, 78, 69, 69, 68, 76, 69, 128, 78, 69, + 67, 75, 84, 73, 69, 128, 78, 69, 67, 75, 128, 78, 69, 66, 69, 78, 83, 84, + 73, 77, 77, 69, 128, 78, 69, 45, 75, 79, 128, 78, 68, 85, 88, 128, 78, + 68, 85, 84, 128, 78, 68, 85, 82, 88, 128, 78, 68, 85, 82, 128, 78, 68, + 85, 80, 128, 78, 68, 85, 78, 128, 78, 68, 213, 78, 68, 79, 88, 128, 78, + 68, 79, 84, 128, 78, 68, 79, 80, 128, 78, 68, 79, 79, 128, 78, 68, 79, + 78, 128, 78, 68, 79, 77, 66, 85, 128, 78, 68, 79, 76, 197, 78, 68, 73, + 88, 128, 78, 68, 73, 84, 128, 78, 68, 73, 81, 128, 78, 68, 73, 80, 128, + 78, 68, 73, 69, 88, 128, 78, 68, 73, 69, 128, 78, 68, 73, 68, 65, 128, + 78, 68, 73, 65, 81, 128, 78, 68, 69, 88, 128, 78, 68, 69, 85, 88, 128, + 78, 68, 69, 85, 84, 128, 78, 68, 69, 85, 65, 69, 82, 69, 69, 128, 78, 68, + 69, 80, 128, 78, 68, 69, 69, 128, 78, 68, 69, 128, 78, 68, 65, 88, 128, + 78, 68, 65, 84, 128, 78, 68, 65, 80, 128, 78, 68, 65, 77, 128, 78, 68, + 65, 65, 78, 71, 71, 69, 85, 65, 69, 84, 128, 78, 68, 65, 65, 128, 78, 68, + 65, 193, 78, 67, 72, 65, 85, 128, 78, 67, 65, 128, 78, 66, 89, 88, 128, + 78, 66, 89, 84, 128, 78, 66, 89, 82, 88, 128, 78, 66, 89, 82, 128, 78, + 66, 89, 80, 128, 78, 66, 89, 128, 78, 66, 85, 88, 128, 78, 66, 85, 84, + 128, 78, 66, 85, 82, 88, 128, 78, 66, 85, 82, 128, 78, 66, 85, 80, 128, + 78, 66, 85, 128, 78, 66, 79, 88, 128, 78, 66, 79, 84, 128, 78, 66, 79, + 80, 128, 78, 66, 79, 128, 78, 66, 73, 88, 128, 78, 66, 73, 84, 128, 78, + 66, 73, 80, 128, 78, 66, 73, 69, 88, 128, 78, 66, 73, 69, 80, 128, 78, + 66, 73, 69, 128, 78, 66, 73, 128, 78, 66, 72, 128, 78, 66, 65, 88, 128, + 78, 66, 65, 84, 128, 78, 66, 65, 80, 128, 78, 66, 65, 128, 78, 65, 90, + 65, 210, 78, 65, 89, 65, 78, 78, 65, 128, 78, 65, 89, 128, 78, 65, 88, + 73, 65, 206, 78, 65, 88, 128, 78, 65, 85, 84, 72, 83, 128, 78, 65, 85, + 83, 69, 65, 84, 69, 196, 78, 65, 85, 68, 73, 218, 78, 65, 84, 85, 82, 65, + 204, 78, 65, 84, 84, 73, 76, 73, 203, 78, 65, 84, 73, 79, 78, 65, 204, + 78, 65, 83, 75, 65, 80, 201, 78, 65, 83, 72, 73, 128, 78, 65, 83, 65, 76, + 73, 90, 69, 196, 78, 65, 83, 65, 76, 73, 90, 65, 84, 73, 79, 78, 128, 78, + 65, 83, 65, 76, 73, 90, 65, 84, 73, 79, 206, 78, 65, 83, 65, 204, 78, 65, + 82, 82, 79, 215, 78, 65, 82, 128, 78, 65, 81, 128, 78, 65, 79, 211, 78, + 65, 78, 83, 65, 78, 65, 81, 128, 78, 65, 78, 71, 77, 79, 78, 84, 72, 79, + 128, 78, 65, 78, 68, 73, 78, 65, 71, 65, 82, 201, 78, 65, 78, 68, 128, + 78, 65, 78, 65, 128, 78, 65, 77, 69, 128, 78, 65, 77, 197, 78, 65, 77, + 50, 128, 78, 65, 75, 65, 65, 82, 193, 78, 65, 75, 128, 78, 65, 73, 82, + 193, 78, 65, 73, 204, 78, 65, 71, 82, 201, 78, 65, 71, 65, 82, 128, 78, + 65, 71, 65, 128, 78, 65, 71, 193, 78, 65, 71, 128, 78, 65, 199, 78, 65, + 69, 128, 78, 65, 66, 76, 65, 128, 78, 65, 66, 65, 84, 65, 69, 65, 206, + 78, 65, 65, 83, 73, 75, 89, 65, 89, 65, 128, 78, 65, 65, 75, 83, 73, 75, + 89, 65, 89, 65, 128, 78, 65, 65, 73, 128, 78, 65, 193, 78, 65, 52, 128, + 78, 65, 50, 128, 78, 65, 45, 57, 128, 78, 65, 45, 56, 128, 78, 65, 45, + 55, 128, 78, 65, 45, 54, 128, 78, 65, 45, 53, 128, 78, 65, 45, 52, 128, + 78, 65, 45, 51, 128, 78, 65, 45, 50, 128, 78, 65, 45, 49, 128, 78, 48, + 52, 50, 128, 78, 48, 52, 49, 128, 78, 48, 52, 48, 128, 78, 48, 51, 57, + 128, 78, 48, 51, 56, 128, 78, 48, 51, 55, 65, 128, 78, 48, 51, 55, 128, + 78, 48, 51, 54, 128, 78, 48, 51, 53, 65, 128, 78, 48, 51, 53, 128, 78, + 48, 51, 52, 65, 128, 78, 48, 51, 52, 128, 78, 48, 51, 51, 65, 128, 78, + 48, 51, 51, 128, 78, 48, 51, 50, 128, 78, 48, 51, 49, 128, 78, 48, 51, + 48, 128, 78, 48, 50, 57, 128, 78, 48, 50, 56, 128, 78, 48, 50, 55, 128, + 78, 48, 50, 54, 128, 78, 48, 50, 53, 65, 128, 78, 48, 50, 53, 128, 78, + 48, 50, 52, 128, 78, 48, 50, 51, 128, 78, 48, 50, 50, 128, 78, 48, 50, + 49, 128, 78, 48, 50, 48, 128, 78, 48, 49, 57, 128, 78, 48, 49, 56, 66, + 128, 78, 48, 49, 56, 65, 128, 78, 48, 49, 56, 128, 78, 48, 49, 55, 128, + 78, 48, 49, 54, 128, 78, 48, 49, 53, 128, 78, 48, 49, 52, 128, 78, 48, + 49, 51, 128, 78, 48, 49, 50, 128, 78, 48, 49, 49, 128, 78, 48, 49, 48, + 128, 78, 48, 48, 57, 128, 78, 48, 48, 56, 128, 78, 48, 48, 55, 128, 78, + 48, 48, 54, 128, 78, 48, 48, 53, 128, 78, 48, 48, 52, 128, 78, 48, 48, + 51, 128, 78, 48, 48, 50, 128, 78, 48, 48, 49, 128, 78, 45, 77, 85, 45, + 77, 79, 45, 50, 128, 78, 45, 77, 85, 45, 77, 79, 45, 49, 128, 78, 45, 67, + 82, 69, 197, 78, 45, 65, 82, 217, 77, 90, 128, 77, 89, 88, 128, 77, 89, + 84, 128, 77, 89, 83, 76, 73, 84, 69, 128, 77, 89, 80, 128, 77, 89, 65, + 128, 77, 89, 193, 77, 87, 79, 79, 128, 77, 87, 79, 128, 77, 87, 73, 73, + 128, 77, 87, 73, 128, 77, 87, 69, 69, 128, 77, 87, 69, 128, 77, 87, 65, + 65, 128, 77, 87, 65, 128, 77, 87, 128, 77, 215, 77, 86, 83, 128, 77, 86, + 79, 80, 128, 77, 86, 73, 128, 77, 86, 69, 85, 65, 69, 78, 71, 65, 77, + 128, 77, 86, 128, 77, 214, 77, 85, 88, 128, 77, 85, 85, 86, 85, 90, 72, + 65, 75, 75, 85, 128, 77, 85, 85, 83, 73, 75, 65, 84, 79, 65, 78, 128, 77, + 85, 85, 82, 68, 72, 65, 74, 193, 77, 85, 85, 128, 77, 85, 84, 72, 65, 76, + 73, 89, 65, 128, 77, 85, 84, 128, 77, 85, 83, 73, 67, 128, 77, 85, 83, + 73, 195, 77, 85, 83, 72, 82, 79, 79, 77, 128, 77, 85, 83, 72, 51, 128, + 77, 85, 83, 72, 179, 77, 85, 83, 72, 128, 77, 85, 83, 200, 77, 85, 83, + 128, 77, 85, 82, 88, 128, 77, 85, 82, 71, 85, 50, 128, 77, 85, 82, 69, + 128, 77, 85, 82, 68, 65, 128, 77, 85, 82, 68, 193, 77, 85, 82, 128, 77, + 85, 81, 68, 65, 77, 128, 77, 85, 80, 128, 77, 85, 79, 88, 128, 77, 85, + 79, 84, 128, 77, 85, 79, 80, 128, 77, 85, 79, 77, 65, 69, 128, 77, 85, + 79, 128, 77, 85, 78, 83, 85, 66, 128, 77, 85, 78, 68, 65, 82, 201, 77, + 85, 78, 65, 72, 128, 77, 85, 78, 128, 77, 85, 76, 84, 73, 83, 69, 84, 128, 77, 85, 76, 84, 73, 83, 69, 212, 77, 85, 76, 84, 73, 80, 76, 73, 67, 65, 84, 73, 79, 78, 128, 77, 85, 76, 84, 73, 80, 76, 73, 67, 65, 84, 73, 79, 206, 77, 85, 76, 84, 73, 80, 76, 69, 128, 77, 85, 76, 84, 73, 80, 76, 197, 77, 85, 76, 84, 73, 79, 67, 85, 76, 65, 210, 77, 85, 76, 84, 73, 77, 65, 80, 128, 77, 85, 76, 84, 201, 77, 85, 76, 84, 65, 78, 201, 77, 85, 75, 80, 72, 82, 69, 78, 71, 128, 77, 85, 75, 75, 85, 82, 85, 78, 73, 128, - 77, 85, 73, 78, 128, 77, 85, 71, 83, 128, 77, 85, 71, 128, 77, 85, 199, - 77, 85, 69, 78, 128, 77, 85, 69, 128, 77, 85, 67, 72, 128, 77, 85, 67, - 200, 77, 85, 67, 65, 65, 68, 128, 77, 85, 65, 83, 128, 77, 85, 65, 78, - 128, 77, 85, 65, 69, 128, 77, 85, 45, 71, 65, 65, 72, 76, 65, 193, 77, - 85, 45, 52, 128, 77, 85, 45, 51, 128, 77, 85, 45, 50, 128, 77, 85, 45, - 49, 128, 77, 213, 77, 84, 65, 86, 82, 85, 76, 201, 77, 83, 128, 77, 82, - 207, 77, 82, 65, 67, 72, 78, 89, 128, 77, 82, 65, 67, 72, 78, 79, 84, 73, - 75, 72, 65, 89, 65, 128, 77, 82, 65, 67, 72, 78, 79, 128, 77, 82, 65, 67, - 72, 78, 65, 89, 65, 128, 77, 210, 77, 81, 128, 77, 80, 65, 128, 77, 79, - 89, 65, 73, 128, 77, 79, 88, 128, 77, 79, 86, 73, 197, 77, 79, 86, 69, - 211, 77, 79, 86, 69, 77, 69, 78, 84, 45, 87, 65, 76, 76, 80, 76, 65, 78, - 197, 77, 79, 86, 69, 77, 69, 78, 84, 45, 72, 73, 78, 71, 197, 77, 79, 86, - 69, 77, 69, 78, 84, 45, 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, 77, 79, - 86, 69, 77, 69, 78, 84, 45, 68, 73, 65, 71, 79, 78, 65, 204, 77, 79, 86, - 69, 77, 69, 78, 84, 128, 77, 79, 86, 69, 77, 69, 78, 212, 77, 79, 86, 69, - 196, 77, 79, 86, 69, 128, 77, 79, 85, 84, 72, 128, 77, 79, 85, 83, 69, - 128, 77, 79, 85, 83, 197, 77, 79, 85, 78, 84, 65, 73, 78, 83, 128, 77, - 79, 85, 78, 84, 65, 73, 78, 128, 77, 79, 85, 78, 84, 65, 73, 206, 77, 79, - 85, 78, 212, 77, 79, 85, 78, 68, 128, 77, 79, 85, 78, 196, 77, 79, 84, - 79, 82, 87, 65, 89, 128, 77, 79, 84, 79, 82, 73, 90, 69, 196, 77, 79, 84, - 79, 82, 67, 89, 67, 76, 69, 128, 77, 79, 84, 79, 210, 77, 79, 84, 72, 69, - 82, 128, 77, 79, 84, 72, 69, 210, 77, 79, 84, 128, 77, 79, 83, 81, 85, - 73, 84, 79, 128, 77, 79, 83, 81, 85, 69, 128, 77, 79, 82, 84, 85, 85, 77, - 128, 77, 79, 82, 84, 65, 82, 128, 77, 79, 82, 80, 72, 79, 76, 79, 71, 73, - 67, 65, 204, 77, 79, 82, 78, 73, 78, 71, 128, 77, 79, 80, 128, 77, 79, - 79, 83, 69, 45, 67, 82, 69, 197, 77, 79, 79, 78, 128, 77, 79, 79, 206, - 77, 79, 79, 77, 80, 85, 81, 128, 77, 79, 79, 77, 69, 85, 84, 128, 77, 79, - 79, 68, 128, 77, 79, 79, 196, 77, 79, 79, 128, 77, 79, 78, 84, 73, 69, - 69, 78, 128, 77, 79, 78, 84, 72, 128, 77, 79, 78, 84, 200, 77, 79, 78, - 83, 84, 69, 82, 128, 77, 79, 78, 79, 83, 84, 65, 66, 76, 197, 77, 79, 78, - 79, 83, 80, 65, 67, 197, 77, 79, 78, 79, 82, 65, 73, 76, 128, 77, 79, 78, - 79, 71, 82, 65, 80, 200, 77, 79, 78, 79, 71, 82, 65, 77, 77, 79, 211, 77, - 79, 78, 79, 71, 82, 65, 205, 77, 79, 78, 79, 70, 79, 78, 73, 65, 83, 128, - 77, 79, 78, 79, 67, 85, 76, 65, 210, 77, 79, 78, 79, 67, 76, 69, 128, 77, - 79, 78, 75, 69, 89, 128, 77, 79, 78, 75, 69, 217, 77, 79, 78, 73, 128, - 77, 79, 78, 71, 75, 69, 85, 65, 69, 81, 128, 77, 79, 78, 69, 89, 45, 77, - 79, 85, 84, 200, 77, 79, 78, 69, 217, 77, 79, 78, 128, 77, 79, 206, 77, - 79, 76, 128, 77, 79, 75, 72, 65, 83, 83, 65, 83, 128, 77, 79, 72, 65, 77, - 77, 65, 196, 77, 79, 68, 85, 76, 207, 77, 79, 68, 73, 70, 73, 69, 82, 45, - 57, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 56, 128, 77, 79, 68, 73, 70, - 73, 69, 82, 45, 55, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 54, 128, 77, - 79, 68, 73, 70, 73, 69, 82, 45, 53, 128, 77, 79, 68, 73, 70, 73, 69, 82, - 45, 52, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 51, 128, 77, 79, 68, 73, - 70, 73, 69, 82, 45, 50, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 54, - 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 53, 128, 77, 79, 68, 73, 70, - 73, 69, 82, 45, 49, 52, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 51, - 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 50, 128, 77, 79, 68, 73, 70, - 73, 69, 82, 45, 49, 49, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 48, - 128, 77, 79, 68, 73, 70, 73, 69, 82, 128, 77, 79, 68, 201, 77, 79, 68, - 69, 83, 84, 89, 128, 77, 79, 68, 69, 82, 206, 77, 79, 68, 69, 77, 128, - 77, 79, 68, 69, 76, 83, 128, 77, 79, 68, 69, 76, 128, 77, 79, 68, 69, - 128, 77, 79, 66, 73, 76, 197, 77, 79, 65, 128, 77, 79, 45, 54, 128, 77, - 79, 45, 53, 128, 77, 79, 45, 52, 128, 77, 79, 45, 51, 128, 77, 207, 77, - 78, 89, 65, 205, 77, 78, 65, 83, 128, 77, 77, 83, 80, 128, 77, 77, 128, - 77, 205, 77, 76, 65, 128, 77, 76, 128, 77, 75, 80, 65, 82, 65, 209, 77, - 73, 88, 128, 77, 73, 84, 128, 77, 73, 83, 82, 65, 128, 77, 73, 82, 82, - 79, 82, 128, 77, 73, 82, 82, 79, 210, 77, 73, 82, 73, 66, 65, 65, 82, 85, - 128, 77, 73, 82, 73, 128, 77, 73, 82, 69, 68, 128, 77, 73, 80, 128, 77, - 73, 78, 89, 128, 77, 73, 78, 85, 83, 45, 79, 82, 45, 80, 76, 85, 211, 77, - 73, 78, 85, 83, 128, 77, 73, 78, 78, 65, 206, 77, 73, 78, 73, 83, 84, 69, - 82, 128, 77, 73, 78, 73, 77, 73, 90, 69, 128, 77, 73, 78, 73, 77, 65, - 128, 77, 73, 78, 73, 68, 73, 83, 67, 128, 77, 73, 78, 73, 66, 85, 83, - 128, 77, 73, 77, 69, 128, 77, 73, 77, 128, 77, 73, 76, 76, 73, 79, 78, - 83, 128, 77, 73, 76, 76, 73, 79, 78, 211, 77, 73, 76, 76, 69, 84, 128, - 77, 73, 76, 76, 197, 77, 73, 76, 204, 77, 73, 76, 75, 217, 77, 73, 76, - 75, 128, 77, 73, 76, 73, 84, 65, 82, 217, 77, 73, 76, 128, 77, 73, 75, - 85, 82, 79, 78, 128, 77, 73, 75, 82, 79, 206, 77, 73, 75, 82, 73, 128, - 77, 73, 73, 78, 128, 77, 73, 73, 77, 128, 77, 73, 73, 128, 77, 73, 199, - 77, 73, 69, 88, 128, 77, 73, 69, 85, 77, 45, 84, 73, 75, 69, 85, 84, 128, - 77, 73, 69, 85, 77, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 77, 73, - 69, 85, 77, 45, 83, 83, 65, 78, 71, 78, 73, 69, 85, 78, 128, 77, 73, 69, - 85, 77, 45, 82, 73, 69, 85, 76, 128, 77, 73, 69, 85, 77, 45, 80, 73, 69, - 85, 80, 45, 83, 73, 79, 83, 128, 77, 73, 69, 85, 77, 45, 80, 73, 69, 85, - 80, 128, 77, 73, 69, 85, 77, 45, 80, 65, 78, 83, 73, 79, 83, 128, 77, 73, - 69, 85, 77, 45, 78, 73, 69, 85, 78, 128, 77, 73, 69, 85, 77, 45, 67, 73, - 69, 85, 67, 128, 77, 73, 69, 85, 77, 45, 67, 72, 73, 69, 85, 67, 72, 128, - 77, 73, 69, 85, 205, 77, 73, 69, 80, 128, 77, 73, 69, 69, 128, 77, 73, - 69, 128, 77, 73, 68, 76, 73, 78, 197, 77, 73, 68, 68, 76, 69, 45, 87, 69, - 76, 83, 200, 77, 73, 68, 68, 76, 69, 128, 77, 73, 68, 45, 76, 69, 86, 69, - 204, 77, 73, 196, 77, 73, 67, 82, 79, 83, 67, 79, 80, 69, 128, 77, 73, - 67, 82, 79, 80, 72, 79, 78, 69, 128, 77, 73, 67, 82, 79, 66, 69, 128, 77, - 73, 67, 82, 207, 77, 73, 67, 210, 77, 73, 45, 55, 128, 77, 73, 45, 54, - 128, 77, 73, 45, 53, 128, 77, 73, 45, 52, 128, 77, 73, 45, 51, 128, 77, - 73, 45, 50, 128, 77, 73, 45, 49, 128, 77, 72, 90, 128, 77, 72, 65, 128, - 77, 72, 128, 77, 71, 85, 88, 128, 77, 71, 85, 84, 128, 77, 71, 85, 82, - 88, 128, 77, 71, 85, 82, 128, 77, 71, 85, 80, 128, 77, 71, 85, 79, 88, - 128, 77, 71, 85, 79, 80, 128, 77, 71, 85, 79, 128, 77, 71, 85, 128, 77, - 71, 79, 88, 128, 77, 71, 79, 84, 128, 77, 71, 79, 80, 128, 77, 71, 79, - 128, 77, 71, 207, 77, 71, 73, 69, 88, 128, 77, 71, 73, 69, 128, 77, 71, - 69, 88, 128, 77, 71, 69, 80, 128, 77, 71, 69, 128, 77, 71, 66, 85, 128, - 77, 71, 66, 79, 79, 128, 77, 71, 66, 79, 70, 85, 77, 128, 77, 71, 66, 79, - 128, 77, 71, 66, 73, 128, 77, 71, 66, 69, 85, 78, 128, 77, 71, 66, 69, - 78, 128, 77, 71, 66, 69, 69, 128, 77, 71, 66, 69, 128, 77, 71, 66, 65, - 83, 65, 81, 128, 77, 71, 66, 65, 83, 65, 128, 77, 71, 65, 88, 128, 77, - 71, 65, 84, 128, 77, 71, 65, 80, 128, 77, 71, 65, 128, 77, 71, 128, 77, - 70, 79, 78, 128, 77, 70, 79, 206, 77, 70, 79, 128, 77, 70, 73, 89, 65, - 81, 128, 77, 70, 73, 69, 69, 128, 77, 70, 69, 85, 84, 128, 77, 70, 69, - 85, 81, 128, 77, 70, 69, 85, 65, 69, 128, 77, 70, 65, 65, 128, 77, 69, - 90, 90, 79, 128, 77, 69, 88, 128, 77, 69, 85, 212, 77, 69, 85, 81, 128, - 77, 69, 85, 78, 74, 79, 77, 78, 68, 69, 85, 81, 128, 77, 69, 85, 78, 128, - 77, 69, 84, 82, 79, 128, 77, 69, 84, 82, 73, 67, 65, 204, 77, 69, 84, 82, - 73, 65, 128, 77, 69, 84, 82, 69, 84, 69, 211, 77, 69, 84, 79, 66, 69, 76, - 85, 83, 128, 77, 69, 84, 69, 75, 128, 77, 69, 84, 69, 71, 128, 77, 69, - 84, 65, 76, 128, 77, 69, 84, 193, 77, 69, 83, 83, 69, 78, 73, 65, 206, - 77, 69, 83, 83, 65, 71, 69, 128, 77, 69, 83, 83, 65, 71, 197, 77, 69, 83, - 79, 128, 77, 69, 83, 73, 128, 77, 69, 83, 72, 128, 77, 69, 82, 80, 69, - 82, 83, 79, 78, 128, 77, 69, 82, 75, 72, 65, 128, 77, 69, 82, 75, 72, - 193, 77, 69, 82, 73, 68, 73, 65, 78, 83, 128, 77, 69, 82, 73, 128, 77, - 69, 82, 71, 69, 128, 77, 69, 82, 67, 85, 82, 89, 128, 77, 69, 82, 67, 85, - 82, 217, 77, 69, 78, 79, 82, 65, 200, 77, 69, 78, 79, 69, 128, 77, 69, - 78, 68, 85, 84, 128, 77, 69, 78, 128, 77, 69, 77, 79, 128, 77, 69, 77, - 66, 69, 82, 83, 72, 73, 80, 128, 77, 69, 77, 66, 69, 82, 128, 77, 69, 77, - 66, 69, 210, 77, 69, 77, 45, 81, 79, 80, 72, 128, 77, 69, 77, 128, 77, - 69, 205, 77, 69, 76, 84, 73, 78, 199, 77, 69, 76, 79, 68, 73, 195, 77, - 69, 76, 73, 75, 128, 77, 69, 73, 90, 73, 128, 77, 69, 71, 65, 84, 79, 78, - 128, 77, 69, 71, 65, 80, 72, 79, 78, 69, 128, 77, 69, 71, 65, 76, 73, - 128, 77, 69, 69, 84, 79, 82, 85, 128, 77, 69, 69, 84, 69, 201, 77, 69, - 69, 84, 128, 77, 69, 69, 77, 85, 128, 77, 69, 69, 77, 128, 77, 69, 69, - 202, 77, 69, 69, 69, 69, 128, 77, 69, 68, 73, 85, 77, 128, 77, 69, 68, - 73, 85, 205, 77, 69, 68, 73, 69, 86, 65, 204, 77, 69, 68, 73, 67, 73, 78, - 69, 128, 77, 69, 68, 73, 67, 65, 204, 77, 69, 68, 73, 65, 204, 77, 69, - 68, 69, 70, 65, 73, 68, 82, 73, 206, 77, 69, 68, 65, 76, 128, 77, 69, 67, - 72, 73, 75, 128, 77, 69, 67, 72, 73, 203, 77, 69, 67, 72, 65, 78, 73, 67, - 65, 204, 77, 69, 65, 84, 128, 77, 69, 65, 212, 77, 69, 65, 83, 85, 82, - 69, 196, 77, 69, 65, 83, 85, 82, 69, 128, 77, 69, 65, 83, 85, 82, 197, - 77, 69, 45, 77, 65, 128, 77, 69, 45, 50, 128, 77, 69, 45, 49, 128, 77, - 68, 85, 206, 77, 196, 77, 67, 72, 213, 77, 67, 72, 65, 206, 77, 67, 128, - 77, 195, 77, 66, 85, 85, 128, 77, 66, 85, 79, 81, 128, 77, 66, 85, 79, - 128, 77, 66, 85, 69, 128, 77, 66, 85, 65, 69, 77, 128, 77, 66, 85, 65, - 69, 128, 77, 66, 79, 79, 128, 77, 66, 79, 128, 77, 66, 73, 84, 128, 77, - 66, 73, 212, 77, 66, 73, 82, 73, 69, 69, 78, 128, 77, 66, 73, 128, 77, - 66, 69, 85, 88, 128, 77, 66, 69, 85, 82, 73, 128, 77, 66, 69, 85, 77, - 128, 77, 66, 69, 82, 65, 69, 128, 77, 66, 69, 78, 128, 77, 66, 69, 69, - 75, 69, 69, 84, 128, 77, 66, 69, 69, 128, 77, 66, 69, 128, 77, 66, 65, - 81, 128, 77, 66, 65, 78, 89, 73, 128, 77, 66, 65, 65, 82, 65, 69, 128, - 77, 66, 65, 65, 75, 69, 84, 128, 77, 66, 65, 65, 128, 77, 66, 65, 193, - 77, 66, 193, 77, 66, 52, 128, 77, 66, 51, 128, 77, 66, 50, 128, 77, 65, - 89, 69, 203, 77, 65, 89, 65, 78, 78, 65, 128, 77, 65, 89, 65, 206, 77, - 65, 89, 128, 77, 65, 88, 73, 77, 73, 90, 69, 128, 77, 65, 88, 73, 77, 65, - 128, 77, 65, 88, 128, 77, 65, 85, 128, 77, 65, 84, 84, 79, 67, 75, 128, - 77, 65, 84, 82, 73, 88, 128, 77, 65, 84, 69, 82, 73, 65, 76, 83, 128, 77, - 65, 84, 128, 77, 65, 83, 213, 77, 65, 83, 83, 73, 78, 71, 128, 77, 65, - 83, 83, 65, 71, 69, 128, 77, 65, 83, 79, 82, 193, 77, 65, 83, 75, 128, - 77, 65, 83, 203, 77, 65, 83, 72, 70, 65, 65, 84, 128, 77, 65, 83, 72, 50, - 128, 77, 65, 83, 67, 85, 76, 73, 78, 197, 77, 65, 83, 65, 82, 65, 205, - 77, 65, 82, 89, 128, 77, 65, 82, 87, 65, 82, 201, 77, 65, 82, 85, 75, 85, - 128, 77, 65, 82, 84, 89, 82, 73, 193, 77, 65, 82, 84, 73, 65, 204, 77, - 65, 82, 82, 89, 73, 78, 199, 77, 65, 82, 82, 73, 65, 71, 197, 77, 65, 82, - 82, 65, 84, 65, 78, 128, 77, 65, 82, 75, 211, 77, 65, 82, 75, 69, 82, - 128, 77, 65, 82, 75, 45, 52, 128, 77, 65, 82, 75, 45, 51, 128, 77, 65, - 82, 75, 45, 50, 128, 77, 65, 82, 75, 45, 49, 128, 77, 65, 82, 69, 128, - 77, 65, 82, 67, 72, 69, 206, 77, 65, 82, 67, 72, 128, 77, 65, 82, 67, 65, - 84, 79, 45, 83, 84, 65, 67, 67, 65, 84, 79, 128, 77, 65, 82, 67, 65, 84, - 79, 128, 77, 65, 82, 67, 65, 83, 73, 84, 69, 128, 77, 65, 82, 66, 85, 84, - 65, 128, 77, 65, 82, 66, 85, 84, 193, 77, 65, 82, 128, 77, 65, 81, 65, - 70, 128, 77, 65, 81, 128, 77, 65, 80, 76, 197, 77, 65, 80, 73, 81, 128, - 77, 65, 208, 77, 65, 79, 128, 77, 65, 78, 85, 65, 204, 77, 65, 78, 84, - 69, 76, 80, 73, 69, 67, 197, 77, 65, 78, 83, 89, 79, 78, 128, 77, 65, 78, - 83, 85, 65, 69, 128, 77, 65, 78, 78, 65, 218, 77, 65, 78, 78, 65, 128, - 77, 65, 78, 73, 67, 72, 65, 69, 65, 206, 77, 65, 78, 71, 79, 128, 77, 65, - 78, 71, 65, 76, 65, 77, 128, 77, 65, 78, 68, 65, 82, 73, 78, 128, 77, 65, - 78, 68, 65, 73, 76, 73, 78, 199, 77, 65, 78, 68, 65, 73, 195, 77, 65, 78, - 67, 72, 213, 77, 65, 78, 65, 212, 77, 65, 78, 65, 67, 76, 69, 83, 128, - 77, 65, 77, 77, 79, 84, 72, 128, 77, 65, 76, 84, 69, 83, 197, 77, 65, 76, - 207, 77, 65, 76, 69, 69, 82, 73, 128, 77, 65, 76, 197, 77, 65, 76, 65, - 75, 79, 206, 77, 65, 75, 83, 85, 82, 65, 128, 77, 65, 75, 83, 85, 82, - 193, 77, 65, 75, 65, 83, 65, 210, 77, 65, 73, 90, 69, 128, 77, 65, 73, - 89, 65, 77, 79, 75, 128, 77, 65, 73, 84, 65, 73, 75, 72, 85, 128, 77, 65, - 73, 82, 85, 128, 77, 65, 73, 77, 85, 65, 78, 128, 77, 65, 73, 77, 65, 76, - 65, 73, 128, 77, 65, 73, 76, 66, 79, 216, 77, 65, 73, 75, 85, 82, 79, - 128, 77, 65, 73, 68, 69, 78, 128, 77, 65, 73, 128, 77, 65, 72, 74, 79, - 78, 199, 77, 65, 72, 72, 65, 128, 77, 65, 72, 65, 80, 82, 65, 78, 65, - 128, 77, 65, 72, 65, 80, 65, 75, 72, 128, 77, 65, 72, 65, 74, 65, 78, - 201, 77, 65, 72, 65, 65, 80, 82, 65, 65, 78, 193, 77, 65, 72, 128, 77, - 65, 71, 78, 73, 70, 89, 73, 78, 199, 77, 65, 71, 78, 69, 84, 128, 77, 65, - 71, 73, 195, 77, 65, 71, 69, 128, 77, 65, 69, 83, 73, 128, 77, 65, 69, - 78, 89, 73, 128, 77, 65, 69, 78, 74, 69, 84, 128, 77, 65, 69, 77, 86, 69, - 85, 88, 128, 77, 65, 69, 77, 75, 80, 69, 78, 128, 77, 65, 69, 77, 71, 66, - 73, 69, 69, 128, 77, 65, 69, 77, 66, 71, 66, 73, 69, 69, 128, 77, 65, 69, - 77, 66, 65, 128, 77, 65, 69, 77, 128, 77, 65, 69, 76, 69, 69, 128, 77, - 65, 69, 75, 69, 85, 80, 128, 77, 65, 68, 89, 65, 128, 77, 65, 68, 85, - 128, 77, 65, 68, 68, 65, 72, 128, 77, 65, 68, 68, 65, 200, 77, 65, 68, - 68, 65, 128, 77, 65, 68, 68, 193, 77, 65, 67, 82, 79, 78, 45, 71, 82, 65, - 86, 69, 128, 77, 65, 67, 82, 79, 78, 45, 66, 82, 69, 86, 69, 128, 77, 65, - 67, 82, 79, 78, 45, 65, 67, 85, 84, 69, 128, 77, 65, 67, 82, 79, 78, 128, - 77, 65, 67, 82, 79, 206, 77, 65, 67, 72, 73, 78, 69, 128, 77, 65, 65, 89, - 89, 65, 65, 128, 77, 65, 65, 73, 128, 77, 65, 65, 128, 77, 65, 50, 128, - 77, 65, 45, 55, 128, 77, 65, 45, 54, 128, 77, 65, 45, 53, 128, 77, 65, - 45, 52, 128, 77, 65, 45, 51, 128, 77, 65, 45, 50, 128, 77, 65, 45, 49, - 128, 77, 49, 57, 183, 77, 49, 57, 182, 77, 49, 57, 181, 77, 49, 57, 180, - 77, 49, 57, 179, 77, 49, 57, 178, 77, 49, 57, 177, 77, 49, 57, 176, 77, - 49, 56, 185, 77, 49, 56, 184, 77, 49, 56, 183, 77, 49, 56, 182, 77, 49, - 56, 181, 77, 49, 56, 180, 77, 49, 56, 179, 77, 49, 56, 178, 77, 49, 56, - 177, 77, 49, 56, 176, 77, 49, 55, 185, 77, 49, 55, 184, 77, 49, 55, 183, - 77, 49, 55, 182, 77, 49, 55, 181, 77, 49, 55, 180, 77, 49, 55, 179, 77, - 49, 55, 178, 77, 49, 55, 177, 77, 49, 55, 176, 77, 49, 54, 185, 77, 49, - 54, 184, 77, 49, 54, 183, 77, 49, 54, 182, 77, 49, 54, 181, 77, 49, 54, - 180, 77, 49, 54, 179, 77, 49, 54, 178, 77, 49, 54, 177, 77, 49, 54, 176, - 77, 49, 53, 185, 77, 49, 53, 184, 77, 49, 53, 183, 77, 49, 53, 182, 77, - 49, 53, 181, 77, 49, 53, 180, 77, 49, 53, 179, 77, 49, 53, 178, 77, 49, - 53, 177, 77, 49, 53, 176, 77, 49, 52, 185, 77, 49, 52, 184, 77, 49, 52, - 183, 77, 49, 52, 182, 77, 49, 52, 181, 77, 49, 52, 180, 77, 49, 52, 179, - 77, 49, 52, 178, 77, 49, 52, 177, 77, 49, 52, 176, 77, 49, 51, 185, 77, - 49, 51, 184, 77, 49, 51, 183, 77, 49, 51, 182, 77, 49, 51, 181, 77, 49, - 51, 180, 77, 49, 51, 179, 77, 49, 51, 178, 77, 49, 51, 177, 77, 49, 51, - 176, 77, 49, 50, 185, 77, 49, 50, 184, 77, 49, 50, 183, 77, 49, 50, 182, - 77, 49, 50, 181, 77, 49, 50, 180, 77, 49, 50, 179, 77, 49, 50, 178, 77, - 49, 50, 177, 77, 49, 50, 176, 77, 49, 49, 185, 77, 49, 49, 184, 77, 49, - 49, 183, 77, 49, 49, 182, 77, 49, 49, 181, 77, 49, 49, 180, 77, 49, 49, - 179, 77, 49, 49, 178, 77, 49, 49, 177, 77, 49, 49, 176, 77, 49, 48, 185, - 77, 49, 48, 184, 77, 49, 48, 183, 77, 49, 48, 182, 77, 49, 48, 181, 77, - 49, 48, 180, 77, 49, 48, 179, 77, 49, 48, 178, 77, 49, 48, 177, 77, 49, - 48, 176, 77, 48, 57, 185, 77, 48, 57, 184, 77, 48, 57, 183, 77, 48, 57, - 182, 77, 48, 57, 181, 77, 48, 57, 180, 77, 48, 57, 179, 77, 48, 57, 178, - 77, 48, 57, 177, 77, 48, 57, 176, 77, 48, 56, 185, 77, 48, 56, 184, 77, - 48, 56, 183, 77, 48, 56, 182, 77, 48, 56, 181, 77, 48, 56, 180, 77, 48, - 56, 179, 77, 48, 56, 178, 77, 48, 56, 177, 77, 48, 56, 176, 77, 48, 55, - 185, 77, 48, 55, 184, 77, 48, 55, 183, 77, 48, 55, 182, 77, 48, 55, 181, - 77, 48, 55, 180, 77, 48, 55, 179, 77, 48, 55, 178, 77, 48, 55, 177, 77, - 48, 55, 176, 77, 48, 54, 185, 77, 48, 54, 184, 77, 48, 54, 183, 77, 48, - 54, 182, 77, 48, 54, 181, 77, 48, 54, 180, 77, 48, 54, 179, 77, 48, 54, - 178, 77, 48, 54, 177, 77, 48, 54, 176, 77, 48, 53, 185, 77, 48, 53, 184, - 77, 48, 53, 183, 77, 48, 53, 182, 77, 48, 53, 181, 77, 48, 53, 180, 77, - 48, 53, 179, 77, 48, 53, 178, 77, 48, 53, 177, 77, 48, 53, 176, 77, 48, - 52, 185, 77, 48, 52, 184, 77, 48, 52, 183, 77, 48, 52, 182, 77, 48, 52, - 181, 77, 48, 52, 52, 128, 77, 48, 52, 180, 77, 48, 52, 51, 128, 77, 48, - 52, 179, 77, 48, 52, 50, 128, 77, 48, 52, 178, 77, 48, 52, 49, 128, 77, - 48, 52, 177, 77, 48, 52, 48, 65, 128, 77, 48, 52, 48, 128, 77, 48, 52, - 176, 77, 48, 51, 57, 128, 77, 48, 51, 185, 77, 48, 51, 56, 128, 77, 48, - 51, 184, 77, 48, 51, 55, 128, 77, 48, 51, 183, 77, 48, 51, 54, 128, 77, - 48, 51, 182, 77, 48, 51, 53, 128, 77, 48, 51, 181, 77, 48, 51, 52, 128, - 77, 48, 51, 180, 77, 48, 51, 51, 66, 128, 77, 48, 51, 51, 65, 128, 77, - 48, 51, 51, 128, 77, 48, 51, 179, 77, 48, 51, 50, 128, 77, 48, 51, 178, - 77, 48, 51, 49, 65, 128, 77, 48, 51, 49, 128, 77, 48, 51, 177, 77, 48, - 51, 48, 128, 77, 48, 51, 176, 77, 48, 50, 57, 128, 77, 48, 50, 185, 77, - 48, 50, 56, 65, 128, 77, 48, 50, 56, 128, 77, 48, 50, 184, 77, 48, 50, - 55, 128, 77, 48, 50, 183, 77, 48, 50, 54, 128, 77, 48, 50, 182, 77, 48, - 50, 53, 128, 77, 48, 50, 181, 77, 48, 50, 52, 65, 128, 77, 48, 50, 52, - 128, 77, 48, 50, 180, 77, 48, 50, 51, 128, 77, 48, 50, 179, 77, 48, 50, - 50, 65, 128, 77, 48, 50, 50, 128, 77, 48, 50, 178, 77, 48, 50, 49, 128, - 77, 48, 50, 177, 77, 48, 50, 48, 128, 77, 48, 50, 176, 77, 48, 49, 57, - 128, 77, 48, 49, 185, 77, 48, 49, 56, 128, 77, 48, 49, 184, 77, 48, 49, - 55, 65, 128, 77, 48, 49, 55, 128, 77, 48, 49, 183, 77, 48, 49, 54, 65, - 128, 77, 48, 49, 54, 128, 77, 48, 49, 182, 77, 48, 49, 53, 65, 128, 77, - 48, 49, 53, 128, 77, 48, 49, 181, 77, 48, 49, 52, 128, 77, 48, 49, 180, - 77, 48, 49, 51, 128, 77, 48, 49, 179, 77, 48, 49, 50, 72, 128, 77, 48, - 49, 50, 71, 128, 77, 48, 49, 50, 70, 128, 77, 48, 49, 50, 69, 128, 77, - 48, 49, 50, 68, 128, 77, 48, 49, 50, 67, 128, 77, 48, 49, 50, 66, 128, - 77, 48, 49, 50, 65, 128, 77, 48, 49, 50, 128, 77, 48, 49, 178, 77, 48, - 49, 49, 128, 77, 48, 49, 177, 77, 48, 49, 48, 65, 128, 77, 48, 49, 48, - 128, 77, 48, 49, 176, 77, 48, 48, 57, 128, 77, 48, 48, 185, 77, 48, 48, - 56, 128, 77, 48, 48, 184, 77, 48, 48, 55, 128, 77, 48, 48, 183, 77, 48, - 48, 54, 128, 77, 48, 48, 182, 77, 48, 48, 53, 128, 77, 48, 48, 181, 77, - 48, 48, 52, 128, 77, 48, 48, 180, 77, 48, 48, 51, 65, 128, 77, 48, 48, - 51, 128, 77, 48, 48, 179, 77, 48, 48, 50, 128, 77, 48, 48, 178, 77, 48, - 48, 49, 66, 128, 77, 48, 48, 49, 65, 128, 77, 48, 48, 49, 128, 77, 48, - 48, 177, 76, 218, 76, 89, 89, 128, 76, 89, 88, 128, 76, 89, 84, 128, 76, - 89, 82, 88, 128, 76, 89, 82, 128, 76, 89, 80, 128, 76, 89, 73, 84, 128, - 76, 89, 73, 78, 199, 76, 89, 68, 73, 65, 206, 76, 89, 67, 73, 65, 206, - 76, 88, 128, 76, 87, 79, 79, 128, 76, 87, 79, 128, 76, 87, 73, 73, 128, - 76, 87, 73, 128, 76, 87, 69, 128, 76, 87, 65, 65, 128, 76, 87, 65, 128, - 76, 85, 88, 128, 76, 85, 85, 128, 76, 85, 84, 128, 76, 85, 82, 88, 128, - 76, 85, 80, 128, 76, 85, 79, 88, 128, 76, 85, 79, 84, 128, 76, 85, 79, - 80, 128, 76, 85, 79, 128, 76, 85, 78, 71, 83, 73, 128, 76, 85, 78, 71, - 83, 128, 76, 85, 78, 65, 84, 197, 76, 85, 205, 76, 85, 76, 128, 76, 85, - 73, 83, 128, 76, 85, 72, 85, 82, 128, 76, 85, 72, 128, 76, 85, 200, 76, - 85, 71, 71, 65, 71, 69, 128, 76, 85, 71, 65, 76, 128, 76, 85, 71, 65, - 204, 76, 85, 69, 128, 76, 85, 197, 76, 85, 66, 128, 76, 85, 65, 69, 80, - 128, 76, 85, 51, 128, 76, 85, 50, 128, 76, 85, 178, 76, 82, 79, 128, 76, - 82, 77, 128, 76, 82, 73, 128, 76, 82, 69, 128, 76, 79, 90, 69, 78, 71, - 69, 128, 76, 79, 90, 69, 78, 71, 197, 76, 79, 88, 128, 76, 79, 87, 69, - 82, 69, 196, 76, 79, 87, 45, 82, 69, 86, 69, 82, 83, 69, 68, 45, 185, 76, - 79, 87, 45, 77, 73, 196, 76, 79, 87, 45, 70, 65, 76, 76, 73, 78, 199, 76, - 79, 87, 45, 185, 76, 79, 86, 197, 76, 79, 85, 82, 69, 128, 76, 79, 85, - 68, 83, 80, 69, 65, 75, 69, 82, 128, 76, 79, 85, 68, 76, 217, 76, 79, 84, - 85, 83, 128, 76, 79, 84, 85, 211, 76, 79, 84, 73, 79, 206, 76, 79, 84, - 128, 76, 79, 83, 83, 76, 69, 83, 83, 128, 76, 79, 82, 82, 89, 128, 76, - 79, 82, 82, 65, 73, 78, 69, 128, 76, 79, 81, 128, 76, 79, 80, 128, 76, - 79, 79, 84, 128, 76, 79, 79, 80, 69, 196, 76, 79, 79, 80, 128, 76, 79, - 79, 208, 76, 79, 79, 78, 128, 76, 79, 79, 203, 76, 79, 79, 128, 76, 79, - 78, 83, 85, 77, 128, 76, 79, 78, 71, 65, 128, 76, 79, 78, 71, 193, 76, - 79, 78, 71, 45, 76, 69, 71, 71, 69, 196, 76, 79, 78, 71, 45, 66, 82, 65, - 78, 67, 72, 45, 89, 82, 128, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, - 45, 83, 79, 204, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 79, 83, - 211, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 77, 65, 68, 210, 76, - 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 72, 65, 71, 65, 76, 204, 76, - 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 65, 210, 76, 79, 77, 77, 65, - 69, 128, 76, 79, 77, 75, 65, 128, 76, 79, 77, 128, 76, 79, 205, 76, 79, - 76, 76, 73, 80, 79, 80, 128, 76, 79, 76, 76, 128, 76, 79, 71, 210, 76, - 79, 71, 79, 84, 89, 80, 197, 76, 79, 71, 79, 71, 82, 65, 205, 76, 79, 71, - 128, 76, 79, 68, 69, 83, 84, 79, 78, 69, 128, 76, 79, 67, 79, 77, 79, 84, - 73, 86, 69, 128, 76, 79, 67, 75, 73, 78, 71, 45, 83, 72, 73, 70, 212, 76, - 79, 67, 65, 84, 73, 86, 69, 128, 76, 79, 67, 65, 84, 73, 79, 78, 45, 87, - 65, 76, 76, 80, 76, 65, 78, 197, 76, 79, 67, 65, 84, 73, 79, 78, 45, 70, - 76, 79, 79, 82, 80, 76, 65, 78, 197, 76, 79, 67, 65, 84, 73, 79, 78, 128, - 76, 79, 67, 65, 84, 73, 79, 206, 76, 79, 66, 83, 84, 69, 82, 128, 76, 79, - 65, 128, 76, 78, 128, 76, 76, 85, 85, 128, 76, 76, 79, 79, 128, 76, 76, - 76, 85, 85, 128, 76, 76, 76, 85, 128, 76, 76, 76, 79, 79, 128, 76, 76, - 76, 79, 128, 76, 76, 76, 73, 73, 128, 76, 76, 76, 73, 128, 76, 76, 76, - 69, 69, 128, 76, 76, 76, 69, 128, 76, 76, 76, 65, 85, 128, 76, 76, 76, - 65, 73, 128, 76, 76, 76, 65, 65, 128, 76, 76, 76, 65, 128, 76, 76, 76, - 128, 76, 76, 72, 65, 128, 76, 76, 65, 77, 65, 128, 76, 74, 85, 68, 73, - 74, 69, 128, 76, 74, 69, 128, 76, 74, 128, 76, 73, 90, 65, 82, 68, 128, - 76, 73, 88, 128, 76, 73, 87, 78, 128, 76, 73, 86, 82, 197, 76, 73, 84, - 84, 76, 69, 128, 76, 73, 84, 84, 76, 197, 76, 73, 84, 84, 69, 210, 76, - 73, 84, 82, 193, 76, 73, 84, 200, 76, 73, 83, 213, 76, 73, 83, 128, 76, - 73, 82, 193, 76, 73, 81, 85, 73, 68, 128, 76, 73, 81, 85, 73, 196, 76, - 73, 81, 128, 76, 73, 80, 83, 84, 73, 67, 75, 128, 76, 73, 80, 211, 76, - 73, 208, 76, 73, 78, 75, 73, 78, 199, 76, 73, 78, 75, 69, 196, 76, 73, - 78, 203, 76, 73, 78, 71, 83, 65, 128, 76, 73, 78, 69, 83, 128, 76, 73, - 78, 69, 211, 76, 73, 78, 69, 45, 57, 128, 76, 73, 78, 69, 45, 55, 128, - 76, 73, 78, 69, 45, 51, 128, 76, 73, 78, 69, 45, 49, 128, 76, 73, 77, 77, - 85, 52, 128, 76, 73, 77, 77, 85, 50, 128, 76, 73, 77, 77, 85, 128, 76, - 73, 77, 77, 213, 76, 73, 77, 73, 84, 69, 196, 76, 73, 77, 73, 84, 65, 84, - 73, 79, 78, 128, 76, 73, 77, 73, 84, 128, 76, 73, 77, 69, 128, 76, 73, - 77, 66, 213, 76, 73, 77, 66, 211, 76, 73, 77, 194, 76, 73, 76, 89, 128, - 76, 73, 76, 73, 84, 72, 128, 76, 73, 76, 128, 76, 73, 71, 72, 84, 78, 73, - 78, 71, 128, 76, 73, 71, 72, 84, 78, 73, 78, 199, 76, 73, 71, 72, 84, 72, - 79, 85, 83, 69, 128, 76, 73, 71, 72, 84, 128, 76, 73, 71, 65, 84, 73, 78, - 199, 76, 73, 70, 84, 69, 82, 128, 76, 73, 70, 69, 128, 76, 73, 69, 88, - 128, 76, 73, 69, 84, 128, 76, 73, 69, 80, 128, 76, 73, 69, 69, 128, 76, - 73, 69, 128, 76, 73, 68, 128, 76, 73, 67, 75, 73, 78, 199, 76, 73, 66, - 82, 65, 128, 76, 73, 66, 69, 82, 84, 89, 128, 76, 73, 65, 66, 73, 76, 73, - 84, 217, 76, 72, 73, 73, 128, 76, 72, 65, 86, 73, 89, 65, 78, 73, 128, - 76, 72, 65, 199, 76, 72, 65, 65, 128, 76, 72, 128, 76, 69, 90, 72, 128, - 76, 69, 90, 200, 76, 69, 88, 128, 76, 69, 86, 73, 84, 65, 84, 73, 78, 71, - 128, 76, 69, 86, 69, 76, 45, 51, 128, 76, 69, 86, 69, 76, 45, 50, 128, - 76, 69, 85, 77, 128, 76, 69, 85, 65, 69, 80, 128, 76, 69, 85, 65, 69, 77, - 128, 76, 69, 85, 128, 76, 69, 213, 76, 69, 84, 84, 69, 82, 83, 128, 76, - 69, 84, 84, 69, 82, 128, 76, 69, 212, 76, 69, 83, 83, 69, 210, 76, 69, - 83, 83, 45, 84, 72, 65, 78, 128, 76, 69, 83, 83, 45, 84, 72, 65, 206, 76, - 69, 83, 72, 128, 76, 69, 80, 67, 72, 193, 76, 69, 80, 128, 76, 69, 79, - 80, 65, 82, 68, 128, 76, 69, 79, 128, 76, 69, 78, 84, 73, 67, 85, 76, 65, - 210, 76, 69, 78, 73, 83, 128, 76, 69, 78, 73, 211, 76, 69, 78, 71, 84, - 72, 69, 78, 69, 82, 128, 76, 69, 78, 71, 84, 72, 45, 55, 128, 76, 69, 78, - 71, 84, 72, 45, 54, 128, 76, 69, 78, 71, 84, 72, 45, 53, 128, 76, 69, 78, - 71, 84, 72, 45, 52, 128, 76, 69, 78, 71, 84, 72, 45, 51, 128, 76, 69, 78, - 71, 84, 72, 45, 50, 128, 76, 69, 78, 71, 84, 72, 45, 49, 128, 76, 69, 78, - 71, 84, 200, 76, 69, 78, 71, 65, 128, 76, 69, 78, 71, 193, 76, 69, 77, - 79, 78, 128, 76, 69, 77, 79, 73, 128, 76, 69, 76, 69, 84, 128, 76, 69, - 76, 69, 212, 76, 69, 203, 76, 69, 73, 77, 77, 65, 128, 76, 69, 73, 77, - 77, 193, 76, 69, 73, 128, 76, 69, 71, 83, 128, 76, 69, 71, 73, 79, 78, - 128, 76, 69, 71, 69, 84, 79, 211, 76, 69, 71, 128, 76, 69, 199, 76, 69, - 70, 84, 87, 65, 82, 68, 83, 128, 76, 69, 70, 84, 45, 84, 79, 45, 82, 73, - 71, 72, 212, 76, 69, 70, 84, 45, 83, 84, 69, 205, 76, 69, 70, 84, 45, 83, - 73, 68, 197, 76, 69, 70, 84, 45, 83, 72, 65, 68, 69, 196, 76, 69, 70, 84, - 45, 80, 79, 73, 78, 84, 73, 78, 199, 76, 69, 70, 84, 45, 76, 73, 71, 72, - 84, 69, 196, 76, 69, 70, 84, 45, 72, 65, 78, 68, 69, 196, 76, 69, 70, 84, - 45, 72, 65, 78, 196, 76, 69, 70, 84, 45, 70, 65, 67, 73, 78, 199, 76, 69, - 70, 84, 128, 76, 69, 69, 82, 65, 69, 87, 65, 128, 76, 69, 69, 75, 128, - 76, 69, 69, 69, 69, 128, 76, 69, 68, 71, 69, 82, 128, 76, 69, 65, 84, 72, - 69, 82, 128, 76, 69, 65, 78, 73, 78, 199, 76, 69, 65, 70, 217, 76, 69, - 65, 70, 128, 76, 69, 65, 198, 76, 69, 65, 68, 69, 82, 128, 76, 69, 65, - 196, 76, 68, 65, 78, 128, 76, 68, 50, 128, 76, 67, 201, 76, 67, 197, 76, - 65, 90, 217, 76, 65, 89, 65, 78, 78, 65, 128, 76, 65, 88, 128, 76, 65, - 87, 128, 76, 65, 215, 76, 65, 85, 76, 65, 128, 76, 65, 85, 75, 65, 218, - 76, 65, 85, 74, 128, 76, 65, 85, 71, 72, 73, 78, 71, 128, 76, 65, 84, 73, - 78, 65, 84, 197, 76, 65, 84, 73, 75, 128, 76, 65, 84, 69, 82, 65, 204, - 76, 65, 84, 197, 76, 65, 83, 212, 76, 65, 82, 89, 78, 71, 69, 65, 204, - 76, 65, 82, 201, 76, 65, 82, 71, 69, 83, 84, 128, 76, 65, 82, 71, 69, - 210, 76, 65, 82, 71, 69, 128, 76, 65, 82, 71, 197, 76, 65, 81, 128, 76, - 65, 80, 65, 81, 128, 76, 65, 207, 76, 65, 78, 84, 69, 82, 78, 128, 76, - 65, 78, 84, 65, 78, 71, 128, 76, 65, 78, 71, 85, 65, 71, 197, 76, 65, 78, - 69, 83, 128, 76, 65, 78, 196, 76, 65, 78, 128, 76, 65, 77, 80, 128, 76, - 65, 77, 69, 68, 72, 128, 76, 65, 77, 69, 68, 128, 76, 65, 77, 69, 196, - 76, 65, 77, 69, 128, 76, 65, 77, 197, 76, 65, 77, 68, 65, 128, 76, 65, - 77, 68, 128, 76, 65, 77, 66, 68, 193, 76, 65, 77, 65, 68, 72, 128, 76, - 65, 76, 128, 76, 65, 204, 76, 65, 75, 75, 72, 65, 78, 71, 89, 65, 79, - 128, 76, 65, 75, 72, 65, 78, 128, 76, 65, 75, 72, 128, 76, 65, 75, 200, - 76, 65, 75, 45, 55, 52, 57, 128, 76, 65, 75, 45, 55, 50, 52, 128, 76, 65, - 75, 45, 54, 54, 56, 128, 76, 65, 75, 45, 54, 52, 56, 128, 76, 65, 75, 45, - 54, 52, 184, 76, 65, 75, 45, 54, 51, 54, 128, 76, 65, 75, 45, 54, 49, 55, - 128, 76, 65, 75, 45, 54, 49, 183, 76, 65, 75, 45, 54, 48, 56, 128, 76, - 65, 75, 45, 53, 53, 48, 128, 76, 65, 75, 45, 52, 57, 53, 128, 76, 65, 75, - 45, 52, 57, 51, 128, 76, 65, 75, 45, 52, 57, 50, 128, 76, 65, 75, 45, 52, - 57, 48, 128, 76, 65, 75, 45, 52, 56, 51, 128, 76, 65, 75, 45, 52, 55, 48, - 128, 76, 65, 75, 45, 52, 53, 55, 128, 76, 65, 75, 45, 52, 53, 48, 128, - 76, 65, 75, 45, 52, 52, 57, 128, 76, 65, 75, 45, 52, 52, 185, 76, 65, 75, - 45, 52, 52, 49, 128, 76, 65, 75, 45, 51, 57, 48, 128, 76, 65, 75, 45, 51, - 56, 52, 128, 76, 65, 75, 45, 51, 56, 51, 128, 76, 65, 75, 45, 51, 52, 56, - 128, 76, 65, 75, 45, 51, 52, 55, 128, 76, 65, 75, 45, 51, 52, 51, 128, - 76, 65, 75, 45, 50, 54, 54, 128, 76, 65, 75, 45, 50, 54, 53, 128, 76, 65, - 75, 45, 50, 51, 56, 128, 76, 65, 75, 45, 50, 50, 56, 128, 76, 65, 75, 45, - 50, 50, 53, 128, 76, 65, 75, 45, 50, 50, 48, 128, 76, 65, 75, 45, 50, 49, - 57, 128, 76, 65, 75, 45, 50, 49, 48, 128, 76, 65, 75, 45, 49, 52, 50, - 128, 76, 65, 75, 45, 49, 51, 48, 128, 76, 65, 75, 45, 48, 57, 50, 128, - 76, 65, 75, 45, 48, 56, 49, 128, 76, 65, 75, 45, 48, 56, 177, 76, 65, 75, - 45, 48, 56, 48, 128, 76, 65, 75, 45, 48, 55, 185, 76, 65, 75, 45, 48, 54, - 50, 128, 76, 65, 75, 45, 48, 53, 49, 128, 76, 65, 75, 45, 48, 53, 48, - 128, 76, 65, 75, 45, 48, 51, 48, 128, 76, 65, 75, 45, 48, 50, 53, 128, - 76, 65, 75, 45, 48, 50, 49, 128, 76, 65, 75, 45, 48, 50, 48, 128, 76, 65, - 75, 45, 48, 48, 51, 128, 76, 65, 74, 65, 78, 89, 65, 76, 65, 78, 128, 76, - 65, 73, 78, 199, 76, 65, 201, 76, 65, 72, 83, 72, 85, 128, 76, 65, 72, - 128, 76, 65, 71, 85, 83, 128, 76, 65, 71, 213, 76, 65, 71, 65, 82, 128, - 76, 65, 71, 65, 210, 76, 65, 71, 65, 66, 128, 76, 65, 71, 65, 194, 76, - 65, 69, 86, 128, 76, 65, 69, 128, 76, 65, 68, 217, 76, 65, 68, 68, 69, - 82, 128, 76, 65, 67, 82, 79, 83, 83, 197, 76, 65, 67, 75, 128, 76, 65, - 67, 65, 128, 76, 65, 66, 79, 85, 82, 73, 78, 71, 128, 76, 65, 66, 79, 82, - 128, 76, 65, 66, 73, 65, 76, 73, 90, 65, 84, 73, 79, 206, 76, 65, 66, 73, - 65, 204, 76, 65, 66, 69, 76, 128, 76, 65, 66, 65, 84, 128, 76, 65, 194, - 76, 65, 65, 78, 65, 69, 128, 76, 65, 65, 78, 128, 76, 65, 65, 77, 85, - 128, 76, 65, 65, 73, 128, 76, 54, 128, 76, 52, 128, 76, 51, 128, 76, 50, - 128, 76, 48, 48, 54, 65, 128, 76, 48, 48, 50, 65, 128, 76, 45, 84, 89, - 80, 197, 76, 45, 83, 72, 65, 80, 69, 196, 75, 89, 85, 82, 73, 73, 128, - 75, 89, 85, 128, 75, 89, 79, 128, 75, 89, 76, 73, 83, 77, 65, 128, 75, - 89, 73, 128, 75, 89, 69, 128, 75, 89, 65, 84, 72, 79, 211, 75, 89, 65, - 65, 128, 75, 89, 65, 128, 75, 88, 87, 73, 128, 75, 88, 87, 69, 69, 128, - 75, 88, 87, 69, 128, 75, 88, 87, 65, 65, 128, 75, 88, 87, 65, 128, 75, - 88, 85, 128, 75, 88, 79, 128, 75, 88, 73, 128, 75, 88, 69, 69, 128, 75, - 88, 69, 128, 75, 88, 65, 65, 128, 75, 88, 65, 128, 75, 87, 86, 128, 75, - 87, 85, 51, 49, 56, 128, 75, 87, 79, 79, 128, 75, 87, 79, 128, 75, 87, - 77, 128, 75, 87, 73, 73, 128, 75, 87, 73, 128, 75, 87, 69, 69, 128, 75, - 87, 69, 128, 75, 87, 66, 128, 75, 87, 65, 89, 128, 75, 87, 65, 69, 84, - 128, 75, 87, 65, 65, 128, 75, 86, 65, 128, 75, 86, 128, 75, 85, 90, 72, - 73, 128, 75, 85, 88, 128, 75, 85, 86, 128, 75, 85, 85, 72, 128, 75, 85, - 84, 128, 75, 85, 83, 77, 65, 128, 75, 85, 83, 72, 85, 50, 128, 75, 85, - 83, 72, 85, 178, 75, 85, 82, 88, 128, 75, 85, 82, 85, 90, 69, 73, 82, 79, - 128, 75, 85, 82, 84, 128, 75, 85, 82, 79, 79, 78, 69, 128, 75, 85, 82, - 128, 75, 85, 210, 75, 85, 81, 128, 75, 85, 80, 78, 65, 89, 65, 128, 75, - 85, 79, 88, 128, 75, 85, 79, 80, 128, 75, 85, 79, 208, 75, 85, 79, 77, - 128, 75, 85, 79, 128, 75, 85, 78, 71, 128, 75, 85, 78, 68, 68, 65, 76, - 73, 89, 65, 128, 75, 85, 76, 128, 75, 85, 204, 75, 85, 71, 128, 75, 85, - 70, 73, 83, 77, 65, 128, 75, 85, 69, 84, 128, 75, 85, 66, 128, 75, 85, - 65, 86, 128, 75, 85, 65, 66, 128, 75, 85, 65, 128, 75, 85, 55, 128, 75, - 85, 52, 128, 75, 85, 180, 75, 85, 51, 128, 75, 85, 179, 75, 85, 45, 55, - 128, 75, 85, 45, 54, 128, 75, 85, 45, 53, 128, 75, 85, 45, 52, 128, 75, - 85, 45, 51, 128, 75, 85, 45, 50, 128, 75, 85, 45, 49, 128, 75, 84, 128, - 75, 83, 83, 85, 85, 128, 75, 83, 83, 85, 128, 75, 83, 83, 79, 79, 128, - 75, 83, 83, 79, 128, 75, 83, 83, 73, 73, 128, 75, 83, 83, 73, 128, 75, - 83, 83, 69, 69, 128, 75, 83, 83, 69, 128, 75, 83, 83, 65, 85, 128, 75, - 83, 83, 65, 73, 128, 75, 83, 83, 65, 65, 128, 75, 83, 83, 65, 128, 75, - 83, 83, 128, 75, 83, 73, 128, 75, 82, 89, 90, 72, 69, 86, 65, 89, 65, - 128, 75, 82, 89, 90, 72, 69, 77, 128, 75, 82, 89, 90, 72, 69, 205, 75, - 82, 89, 90, 72, 128, 75, 82, 89, 90, 200, 75, 82, 89, 85, 75, 79, 86, 65, - 89, 65, 128, 75, 82, 89, 85, 75, 79, 86, 65, 89, 193, 75, 82, 89, 85, 75, - 128, 75, 82, 89, 85, 203, 75, 82, 79, 78, 79, 83, 128, 75, 82, 69, 77, - 65, 83, 84, 73, 128, 75, 82, 65, 84, 73, 77, 79, 89, 80, 79, 82, 82, 79, - 79, 78, 128, 75, 82, 65, 84, 73, 77, 79, 75, 79, 85, 70, 73, 83, 77, 65, - 128, 75, 82, 65, 84, 73, 77, 65, 84, 65, 128, 75, 82, 65, 84, 73, 77, - 193, 75, 80, 85, 128, 75, 80, 79, 81, 128, 75, 80, 79, 79, 128, 75, 80, - 79, 128, 75, 80, 73, 128, 75, 80, 69, 85, 88, 128, 75, 80, 69, 69, 128, - 75, 80, 69, 128, 75, 80, 65, 82, 65, 81, 128, 75, 80, 65, 78, 128, 75, - 80, 65, 72, 128, 75, 80, 65, 128, 75, 80, 128, 75, 79, 88, 128, 75, 79, - 86, 85, 85, 128, 75, 79, 86, 128, 75, 79, 84, 79, 128, 75, 79, 82, 85, - 78, 65, 128, 75, 79, 82, 79, 78, 73, 83, 128, 75, 79, 82, 79, 78, 128, - 75, 79, 82, 69, 65, 206, 75, 79, 82, 65, 78, 73, 195, 75, 79, 81, 78, 68, - 79, 78, 128, 75, 79, 80, 80, 65, 128, 75, 79, 80, 128, 75, 79, 79, 86, - 128, 75, 79, 79, 80, 79, 128, 75, 79, 79, 77, 85, 85, 84, 128, 75, 79, - 79, 66, 128, 75, 79, 79, 128, 75, 79, 78, 84, 69, 86, 77, 65, 128, 75, - 79, 78, 84, 69, 86, 77, 193, 75, 79, 77, 201, 75, 79, 77, 66, 85, 86, 65, - 128, 75, 79, 77, 66, 85, 86, 193, 75, 79, 77, 66, 213, 75, 79, 75, 79, - 128, 75, 79, 75, 69, 128, 75, 79, 75, 128, 75, 79, 203, 75, 79, 73, 78, - 73, 128, 75, 79, 73, 128, 75, 79, 201, 75, 79, 72, 128, 75, 79, 71, 72, - 79, 77, 128, 75, 79, 69, 84, 128, 75, 79, 66, 89, 76, 65, 128, 75, 79, - 66, 128, 75, 79, 65, 76, 65, 128, 75, 79, 65, 128, 75, 79, 45, 75, 73, - 128, 75, 79, 45, 51, 128, 75, 79, 45, 50, 128, 75, 79, 45, 49, 128, 75, - 78, 85, 67, 75, 76, 69, 83, 128, 75, 78, 85, 67, 75, 76, 69, 128, 75, 78, - 79, 84, 128, 75, 78, 79, 66, 83, 128, 75, 78, 73, 71, 72, 84, 45, 82, 79, - 79, 75, 128, 75, 78, 73, 71, 72, 84, 45, 81, 85, 69, 69, 78, 128, 75, 78, - 73, 71, 72, 84, 45, 66, 73, 83, 72, 79, 80, 128, 75, 78, 73, 71, 72, 84, - 128, 75, 78, 73, 71, 72, 212, 75, 78, 73, 70, 69, 128, 75, 78, 73, 70, - 197, 75, 78, 69, 69, 76, 73, 78, 199, 75, 77, 128, 75, 205, 75, 76, 89, - 85, 67, 72, 69, 86, 79, 89, 128, 75, 76, 89, 85, 67, 72, 69, 86, 65, 89, - 65, 128, 75, 76, 89, 85, 67, 72, 69, 86, 65, 89, 193, 75, 76, 89, 85, 67, - 72, 69, 80, 79, 86, 79, 68, 78, 89, 128, 75, 76, 89, 85, 67, 72, 69, 80, - 79, 86, 79, 68, 78, 65, 89, 65, 128, 75, 76, 89, 85, 67, 72, 69, 78, 69, - 80, 79, 83, 84, 79, 89, 65, 78, 78, 89, 128, 75, 76, 89, 85, 67, 72, 69, - 78, 69, 80, 79, 83, 84, 79, 89, 65, 78, 78, 65, 89, 65, 128, 75, 76, 89, - 85, 67, 72, 128, 75, 76, 73, 84, 79, 78, 128, 75, 76, 65, 83, 77, 65, - 128, 75, 76, 65, 83, 77, 193, 75, 76, 65, 128, 75, 76, 128, 75, 75, 79, - 128, 75, 75, 73, 128, 75, 75, 69, 69, 128, 75, 75, 69, 128, 75, 75, 65, - 128, 75, 75, 128, 75, 74, 69, 128, 75, 73, 89, 69, 79, 75, 45, 84, 73, - 75, 69, 85, 84, 128, 75, 73, 89, 69, 79, 75, 45, 83, 73, 79, 83, 45, 75, - 73, 89, 69, 79, 75, 128, 75, 73, 89, 69, 79, 75, 45, 82, 73, 69, 85, 76, - 128, 75, 73, 89, 69, 79, 75, 45, 80, 73, 69, 85, 80, 128, 75, 73, 89, 69, - 79, 75, 45, 78, 73, 69, 85, 78, 128, 75, 73, 89, 69, 79, 75, 45, 75, 72, - 73, 69, 85, 75, 72, 128, 75, 73, 89, 69, 79, 75, 45, 67, 72, 73, 69, 85, - 67, 72, 128, 75, 73, 89, 69, 79, 203, 75, 73, 88, 128, 75, 73, 87, 73, - 70, 82, 85, 73, 84, 128, 75, 73, 87, 128, 75, 73, 86, 128, 75, 73, 84, - 69, 128, 75, 73, 84, 128, 75, 73, 83, 83, 73, 78, 199, 75, 73, 83, 83, - 128, 75, 73, 83, 211, 75, 73, 83, 73, 77, 53, 128, 75, 73, 83, 73, 77, - 181, 75, 73, 83, 72, 128, 75, 73, 83, 65, 76, 128, 75, 73, 82, 79, 87, - 65, 84, 84, 79, 128, 75, 73, 82, 79, 77, 69, 69, 84, 79, 82, 85, 128, 75, - 73, 82, 79, 71, 85, 82, 65, 77, 85, 128, 75, 73, 82, 79, 128, 75, 73, 82, - 71, 72, 73, 218, 75, 73, 81, 128, 75, 73, 80, 128, 75, 73, 208, 75, 73, - 78, 83, 72, 73, 80, 128, 75, 73, 78, 78, 193, 75, 73, 78, 68, 69, 82, 71, - 65, 82, 84, 69, 78, 128, 75, 73, 77, 79, 78, 79, 128, 75, 73, 76, 76, 69, - 82, 128, 75, 73, 73, 90, 72, 128, 75, 73, 73, 128, 75, 73, 72, 128, 75, - 73, 69, 88, 128, 75, 73, 69, 86, 65, 206, 75, 73, 69, 80, 128, 75, 73, - 69, 69, 77, 128, 75, 73, 69, 128, 75, 73, 68, 128, 75, 73, 196, 75, 73, - 67, 75, 128, 75, 73, 66, 128, 75, 73, 65, 86, 128, 75, 73, 65, 66, 128, - 75, 73, 45, 56, 128, 75, 73, 45, 55, 128, 75, 73, 45, 54, 128, 75, 73, - 45, 53, 128, 75, 73, 45, 52, 128, 75, 73, 45, 51, 128, 75, 73, 45, 50, - 128, 75, 73, 45, 49, 128, 75, 72, 90, 128, 75, 72, 87, 65, 73, 128, 75, - 72, 85, 69, 78, 45, 76, 85, 197, 75, 72, 85, 69, 206, 75, 72, 85, 68, 65, - 87, 65, 68, 201, 75, 72, 85, 68, 65, 77, 128, 75, 72, 85, 65, 84, 128, - 75, 72, 79, 85, 128, 75, 72, 79, 212, 75, 72, 79, 78, 78, 65, 128, 75, - 72, 79, 78, 128, 75, 72, 79, 77, 85, 84, 128, 75, 72, 79, 75, 72, 76, 79, - 205, 75, 72, 79, 74, 75, 201, 75, 72, 79, 128, 75, 72, 207, 75, 72, 77, - 213, 75, 72, 73, 84, 128, 75, 72, 73, 78, 89, 65, 128, 75, 72, 73, 69, - 85, 75, 200, 75, 72, 73, 128, 75, 72, 201, 75, 72, 72, 79, 128, 75, 72, - 72, 65, 128, 75, 72, 69, 84, 72, 128, 75, 72, 69, 73, 128, 75, 72, 69, - 69, 128, 75, 72, 69, 128, 75, 72, 65, 86, 128, 75, 72, 65, 82, 79, 83, - 72, 84, 72, 201, 75, 72, 65, 82, 128, 75, 72, 65, 80, 72, 128, 75, 72, - 65, 78, 199, 75, 72, 65, 78, 68, 193, 75, 72, 65, 77, 84, 201, 75, 72, - 65, 77, 73, 76, 79, 128, 75, 72, 65, 75, 65, 83, 83, 73, 65, 206, 75, 72, - 65, 73, 128, 75, 72, 65, 72, 128, 75, 72, 65, 200, 75, 72, 65, 70, 128, - 75, 72, 65, 66, 128, 75, 72, 65, 65, 128, 75, 71, 128, 75, 69, 89, 67, - 65, 80, 128, 75, 69, 89, 67, 65, 208, 75, 69, 89, 66, 79, 65, 82, 68, - 128, 75, 69, 89, 66, 79, 65, 82, 196, 75, 69, 88, 128, 75, 69, 86, 128, - 75, 69, 85, 89, 69, 85, 88, 128, 75, 69, 85, 83, 72, 69, 85, 65, 69, 80, - 128, 75, 69, 85, 83, 69, 85, 88, 128, 75, 69, 85, 80, 85, 81, 128, 75, - 69, 85, 79, 212, 75, 69, 85, 77, 128, 75, 69, 85, 75, 69, 85, 84, 78, 68, - 65, 128, 75, 69, 85, 75, 65, 81, 128, 75, 69, 85, 65, 69, 84, 77, 69, 85, - 78, 128, 75, 69, 85, 65, 69, 82, 73, 128, 75, 69, 84, 84, 201, 75, 69, - 83, 72, 50, 128, 75, 69, 82, 69, 84, 128, 75, 69, 79, 87, 128, 75, 69, - 78, 84, 73, 77, 65, 84, 65, 128, 75, 69, 78, 84, 73, 77, 65, 84, 193, 75, - 69, 78, 84, 73, 77, 193, 75, 69, 78, 65, 84, 128, 75, 69, 78, 128, 75, - 69, 206, 75, 69, 77, 80, 85, 76, 128, 75, 69, 77, 80, 85, 204, 75, 69, - 77, 80, 76, 73, 128, 75, 69, 77, 80, 76, 201, 75, 69, 77, 80, 72, 82, 69, - 78, 71, 128, 75, 69, 77, 66, 65, 78, 71, 128, 75, 69, 76, 86, 73, 206, - 75, 69, 72, 69, 72, 128, 75, 69, 72, 69, 200, 75, 69, 72, 128, 75, 69, - 70, 85, 76, 65, 128, 75, 69, 69, 86, 128, 75, 69, 69, 83, 85, 128, 75, - 69, 69, 80, 73, 78, 199, 75, 69, 69, 78, 71, 128, 75, 69, 69, 66, 128, - 75, 69, 66, 128, 75, 69, 65, 65, 69, 128, 75, 67, 65, 76, 128, 75, 66, - 128, 75, 65, 90, 65, 75, 200, 75, 65, 89, 65, 78, 78, 65, 128, 75, 65, - 89, 65, 200, 75, 65, 88, 128, 75, 65, 87, 86, 128, 75, 65, 87, 73, 128, - 75, 65, 87, 66, 128, 75, 65, 86, 89, 75, 65, 128, 75, 65, 86, 89, 75, - 193, 75, 65, 86, 128, 75, 65, 85, 86, 128, 75, 65, 85, 78, 65, 128, 75, - 65, 85, 206, 75, 65, 85, 66, 128, 75, 65, 84, 79, 128, 75, 65, 84, 72, - 73, 83, 84, 73, 128, 75, 65, 84, 72, 65, 75, 193, 75, 65, 84, 65, 86, 65, - 83, 77, 65, 128, 75, 65, 84, 65, 86, 193, 75, 65, 84, 65, 75, 65, 78, 65, - 45, 72, 73, 82, 65, 71, 65, 78, 193, 75, 65, 83, 82, 65, 84, 65, 78, 128, - 75, 65, 83, 82, 65, 84, 65, 206, 75, 65, 83, 82, 65, 128, 75, 65, 83, 82, - 193, 75, 65, 83, 75, 65, 76, 128, 75, 65, 83, 75, 65, 204, 75, 65, 83, - 72, 77, 73, 82, 201, 75, 65, 82, 83, 72, 65, 78, 65, 128, 75, 65, 82, 79, - 82, 73, 73, 128, 75, 65, 82, 79, 82, 65, 78, 128, 75, 65, 82, 79, 82, - 128, 75, 65, 82, 207, 75, 65, 82, 69, 206, 75, 65, 82, 65, 84, 84, 79, - 128, 75, 65, 82, 65, 78, 128, 75, 65, 80, 89, 69, 79, 85, 78, 83, 83, 65, - 78, 71, 80, 73, 69, 85, 80, 128, 75, 65, 80, 89, 69, 79, 85, 78, 82, 73, - 69, 85, 76, 128, 75, 65, 80, 89, 69, 79, 85, 78, 80, 72, 73, 69, 85, 80, - 72, 128, 75, 65, 80, 89, 69, 79, 85, 78, 77, 73, 69, 85, 77, 128, 75, 65, - 80, 80, 65, 128, 75, 65, 80, 80, 193, 75, 65, 80, 79, 128, 75, 65, 80, - 72, 128, 75, 65, 80, 65, 76, 128, 75, 65, 80, 65, 128, 75, 65, 208, 75, - 65, 78, 84, 65, 74, 193, 75, 65, 78, 78, 65, 68, 193, 75, 65, 78, 71, 65, - 82, 79, 79, 128, 75, 65, 78, 71, 128, 75, 65, 78, 199, 75, 65, 78, 65, - 75, 79, 128, 75, 65, 77, 52, 128, 75, 65, 77, 50, 128, 75, 65, 77, 128, - 75, 65, 75, 79, 128, 75, 65, 75, 65, 66, 65, 84, 128, 75, 65, 75, 128, - 75, 65, 203, 75, 65, 73, 86, 128, 75, 65, 73, 84, 72, 201, 75, 65, 73, - 82, 73, 128, 75, 65, 73, 66, 128, 75, 65, 73, 128, 75, 65, 201, 75, 65, - 70, 65, 128, 75, 65, 70, 128, 75, 65, 198, 75, 65, 68, 53, 128, 75, 65, - 68, 181, 75, 65, 68, 52, 128, 75, 65, 68, 51, 128, 75, 65, 68, 179, 75, - 65, 68, 50, 128, 75, 65, 68, 128, 75, 65, 67, 72, 75, 65, 128, 75, 65, - 66, 193, 75, 65, 66, 128, 75, 65, 65, 86, 128, 75, 65, 65, 73, 128, 75, - 65, 65, 70, 85, 128, 75, 65, 65, 70, 128, 75, 65, 65, 67, 85, 128, 75, - 65, 65, 66, 65, 128, 75, 65, 65, 66, 128, 75, 65, 50, 128, 75, 65, 178, - 75, 65, 45, 75, 69, 128, 75, 65, 45, 57, 128, 75, 65, 45, 56, 128, 75, - 65, 45, 55, 128, 75, 65, 45, 54, 128, 75, 65, 45, 53, 128, 75, 65, 45, - 52, 128, 75, 65, 45, 51, 128, 75, 65, 45, 50, 128, 75, 65, 45, 49, 49, - 128, 75, 65, 45, 49, 48, 128, 75, 65, 45, 49, 128, 75, 48, 48, 56, 128, - 75, 48, 48, 55, 128, 75, 48, 48, 54, 128, 75, 48, 48, 53, 128, 75, 48, - 48, 52, 128, 75, 48, 48, 51, 128, 75, 48, 48, 50, 128, 75, 48, 48, 49, - 128, 74, 87, 65, 128, 74, 85, 85, 128, 74, 85, 84, 128, 74, 85, 83, 84, - 73, 70, 73, 67, 65, 84, 73, 79, 78, 128, 74, 85, 80, 73, 84, 69, 82, 128, - 74, 85, 79, 84, 128, 74, 85, 79, 80, 128, 74, 85, 78, 79, 128, 74, 85, - 78, 71, 83, 69, 79, 78, 199, 74, 85, 78, 69, 128, 74, 85, 76, 89, 128, - 74, 85, 71, 71, 76, 73, 78, 71, 128, 74, 85, 69, 85, 73, 128, 74, 85, 68, - 85, 76, 128, 74, 85, 68, 71, 69, 128, 74, 85, 68, 69, 79, 45, 83, 80, 65, - 78, 73, 83, 200, 74, 79, 89, 83, 84, 73, 67, 75, 128, 74, 79, 89, 79, 85, - 211, 74, 79, 89, 128, 74, 79, 86, 69, 128, 74, 79, 212, 74, 79, 78, 71, - 128, 74, 79, 78, 193, 74, 79, 75, 69, 82, 128, 74, 79, 73, 78, 84, 83, - 128, 74, 79, 73, 78, 69, 68, 128, 74, 79, 73, 78, 128, 74, 79, 65, 128, - 74, 78, 89, 65, 128, 74, 74, 89, 88, 128, 74, 74, 89, 84, 128, 74, 74, - 89, 80, 128, 74, 74, 89, 128, 74, 74, 85, 88, 128, 74, 74, 85, 84, 128, - 74, 74, 85, 82, 88, 128, 74, 74, 85, 82, 128, 74, 74, 85, 80, 128, 74, - 74, 85, 79, 88, 128, 74, 74, 85, 79, 80, 128, 74, 74, 85, 79, 128, 74, - 74, 85, 128, 74, 74, 79, 88, 128, 74, 74, 79, 84, 128, 74, 74, 79, 80, - 128, 74, 74, 79, 128, 74, 74, 73, 88, 128, 74, 74, 73, 84, 128, 74, 74, - 73, 80, 128, 74, 74, 73, 69, 88, 128, 74, 74, 73, 69, 84, 128, 74, 74, - 73, 69, 80, 128, 74, 74, 73, 69, 128, 74, 74, 73, 128, 74, 74, 69, 69, - 128, 74, 74, 69, 128, 74, 74, 65, 128, 74, 73, 76, 128, 74, 73, 73, 77, - 128, 74, 73, 73, 128, 74, 73, 72, 86, 65, 77, 85, 76, 73, 89, 65, 128, - 74, 73, 71, 83, 65, 215, 74, 73, 65, 128, 74, 72, 79, 88, 128, 74, 72, - 79, 128, 74, 72, 69, 72, 128, 74, 72, 65, 89, 73, 78, 128, 74, 72, 65, - 78, 128, 74, 72, 65, 77, 128, 74, 72, 65, 65, 128, 74, 72, 65, 128, 74, - 69, 85, 128, 74, 69, 82, 85, 83, 65, 76, 69, 77, 128, 74, 69, 82, 65, - 206, 74, 69, 82, 65, 128, 74, 69, 82, 128, 74, 69, 72, 128, 74, 69, 200, - 74, 69, 71, 79, 71, 65, 78, 128, 74, 69, 69, 77, 128, 74, 69, 69, 205, - 74, 69, 65, 78, 83, 128, 74, 65, 89, 78, 128, 74, 65, 89, 73, 78, 128, - 74, 65, 89, 65, 78, 78, 65, 128, 74, 65, 87, 128, 74, 65, 86, 73, 89, 65, - 78, 73, 128, 74, 65, 86, 65, 78, 69, 83, 197, 74, 65, 85, 128, 74, 65, - 82, 128, 74, 65, 80, 65, 78, 69, 83, 197, 74, 65, 80, 65, 78, 128, 74, - 65, 78, 85, 65, 82, 89, 128, 74, 65, 76, 76, 65, 74, 65, 76, 65, 76, 79, - 85, 72, 79, 85, 128, 74, 65, 76, 76, 128, 74, 65, 73, 206, 74, 65, 73, - 128, 74, 65, 72, 128, 74, 65, 68, 69, 128, 74, 65, 67, 75, 83, 128, 74, - 65, 67, 75, 45, 79, 45, 76, 65, 78, 84, 69, 82, 78, 128, 74, 65, 67, 203, - 74, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 73, 90, 72, 73, 84, 83, - 65, 128, 73, 90, 72, 73, 84, 83, 193, 73, 90, 72, 69, 128, 73, 90, 65, - 75, 65, 89, 193, 73, 89, 69, 75, 128, 73, 89, 65, 78, 78, 65, 128, 73, - 85, 74, 65, 128, 73, 84, 211, 73, 84, 69, 82, 65, 84, 73, 79, 206, 73, - 84, 69, 77, 128, 73, 83, 83, 72, 65, 82, 128, 73, 83, 79, 83, 67, 69, 76, - 69, 211, 73, 83, 79, 78, 128, 73, 83, 79, 206, 73, 83, 79, 76, 65, 84, - 69, 128, 73, 83, 76, 65, 78, 68, 128, 73, 83, 72, 77, 65, 65, 77, 128, - 73, 83, 69, 78, 45, 73, 83, 69, 78, 128, 73, 83, 65, 75, 73, 193, 73, 83, - 45, 80, 73, 76, 76, 65, 128, 73, 82, 85, 89, 65, 78, 78, 65, 128, 73, 82, - 85, 85, 89, 65, 78, 78, 65, 128, 73, 82, 79, 78, 45, 67, 79, 80, 80, 69, - 210, 73, 82, 79, 78, 128, 73, 82, 66, 128, 73, 79, 84, 73, 70, 73, 69, - 196, 73, 79, 84, 65, 84, 69, 196, 73, 79, 84, 65, 128, 73, 79, 84, 193, - 73, 79, 82, 128, 73, 79, 78, 71, 128, 73, 79, 68, 72, 65, 68, 72, 128, - 73, 78, 86, 73, 83, 73, 66, 76, 197, 73, 78, 86, 69, 82, 84, 69, 68, 128, - 73, 78, 86, 69, 82, 84, 69, 196, 73, 78, 86, 69, 82, 84, 69, 66, 82, 65, - 84, 69, 128, 73, 78, 86, 69, 82, 83, 197, 73, 78, 84, 82, 79, 68, 85, 67, - 69, 82, 128, 73, 78, 84, 73, 128, 73, 78, 84, 69, 82, 83, 89, 76, 76, 65, - 66, 73, 195, 73, 78, 84, 69, 82, 83, 69, 67, 84, 73, 79, 78, 128, 73, 78, - 84, 69, 82, 83, 69, 67, 84, 73, 79, 206, 73, 78, 84, 69, 82, 83, 69, 67, - 84, 73, 78, 199, 73, 78, 84, 69, 82, 82, 79, 66, 65, 78, 71, 128, 73, 78, - 84, 69, 82, 82, 79, 66, 65, 78, 199, 73, 78, 84, 69, 82, 80, 79, 76, 65, - 84, 73, 79, 206, 73, 78, 84, 69, 82, 76, 79, 67, 75, 69, 196, 73, 78, 84, - 69, 82, 76, 73, 78, 69, 65, 210, 73, 78, 84, 69, 82, 76, 65, 67, 69, 196, - 73, 78, 84, 69, 82, 73, 79, 210, 73, 78, 84, 69, 82, 69, 83, 212, 73, 78, - 84, 69, 82, 67, 65, 76, 65, 84, 69, 128, 73, 78, 84, 69, 71, 82, 65, 84, - 73, 79, 78, 128, 73, 78, 84, 69, 71, 82, 65, 84, 73, 79, 206, 73, 78, 84, - 69, 71, 82, 65, 76, 128, 73, 78, 84, 69, 71, 82, 65, 204, 73, 78, 83, 85, - 76, 65, 210, 73, 78, 83, 84, 82, 85, 77, 69, 78, 84, 65, 204, 73, 78, 83, - 73, 68, 69, 128, 73, 78, 83, 73, 68, 197, 73, 78, 83, 69, 82, 84, 73, 79, - 206, 73, 78, 83, 69, 82, 212, 73, 78, 83, 69, 67, 84, 128, 73, 78, 83, - 67, 82, 73, 80, 84, 73, 79, 78, 65, 204, 73, 78, 80, 85, 212, 73, 78, 78, - 79, 67, 69, 78, 67, 69, 128, 73, 78, 78, 78, 128, 73, 78, 78, 69, 82, - 128, 73, 78, 78, 69, 210, 73, 78, 78, 128, 73, 78, 73, 78, 71, 85, 128, - 73, 78, 72, 73, 66, 73, 212, 73, 78, 72, 69, 82, 69, 78, 212, 73, 78, 72, - 65, 76, 69, 128, 73, 78, 71, 87, 65, 90, 128, 73, 78, 70, 79, 82, 77, 65, - 84, 73, 79, 206, 73, 78, 70, 76, 85, 69, 78, 67, 69, 128, 73, 78, 70, 73, - 78, 73, 84, 89, 128, 73, 78, 70, 73, 78, 73, 84, 217, 73, 78, 68, 85, 83, - 84, 82, 73, 65, 204, 73, 78, 68, 73, 82, 69, 67, 212, 73, 78, 68, 73, 67, - 84, 73, 79, 206, 73, 78, 68, 73, 67, 65, 84, 79, 82, 128, 73, 78, 68, 73, - 67, 65, 84, 79, 210, 73, 78, 68, 73, 195, 73, 78, 68, 73, 65, 206, 73, - 78, 68, 69, 88, 128, 73, 78, 68, 69, 80, 69, 78, 68, 69, 78, 212, 73, 78, - 67, 82, 69, 77, 69, 78, 84, 128, 73, 78, 67, 82, 69, 65, 83, 69, 211, 73, - 78, 67, 82, 69, 65, 83, 69, 128, 73, 78, 67, 82, 69, 65, 83, 197, 73, 78, - 67, 79, 77, 80, 76, 69, 84, 197, 73, 78, 67, 79, 77, 73, 78, 199, 73, 78, - 67, 76, 85, 68, 73, 78, 199, 73, 78, 67, 72, 128, 73, 78, 66, 79, 216, - 73, 78, 65, 80, 128, 73, 78, 45, 65, 76, 65, 70, 128, 73, 77, 80, 69, 82, - 73, 65, 204, 73, 77, 80, 69, 82, 70, 69, 67, 84, 85, 205, 73, 77, 80, 69, - 82, 70, 69, 67, 84, 65, 128, 73, 77, 80, 69, 82, 70, 69, 67, 84, 193, 73, - 77, 78, 128, 73, 77, 73, 83, 69, 79, 211, 73, 77, 73, 78, 51, 128, 73, - 77, 73, 78, 128, 73, 77, 73, 206, 73, 77, 73, 70, 84, 72, 79, 82, 79, 78, - 128, 73, 77, 73, 70, 84, 72, 79, 82, 65, 128, 73, 77, 73, 70, 79, 78, 79, - 78, 128, 73, 77, 73, 68, 73, 65, 82, 71, 79, 78, 128, 73, 77, 65, 71, - 197, 73, 77, 65, 65, 76, 65, 128, 73, 76, 85, 89, 65, 78, 78, 65, 128, - 73, 76, 85, 89, 128, 73, 76, 85, 85, 89, 65, 78, 78, 65, 128, 73, 76, 85, - 84, 128, 73, 76, 73, 77, 77, 85, 52, 128, 73, 76, 73, 77, 77, 85, 51, - 128, 73, 76, 73, 77, 77, 85, 128, 73, 76, 73, 77, 77, 213, 73, 76, 50, - 128, 73, 75, 65, 82, 65, 128, 73, 75, 65, 82, 193, 73, 74, 128, 73, 73, - 89, 65, 78, 78, 65, 128, 73, 71, 73, 128, 73, 71, 201, 73, 71, 71, 87, - 83, 128, 73, 70, 73, 78, 128, 73, 69, 85, 78, 71, 45, 84, 73, 75, 69, 85, - 84, 128, 73, 69, 85, 78, 71, 45, 84, 72, 73, 69, 85, 84, 72, 128, 73, 69, - 85, 78, 71, 45, 82, 73, 69, 85, 76, 128, 73, 69, 85, 78, 71, 45, 80, 73, - 69, 85, 80, 128, 73, 69, 85, 78, 71, 45, 80, 72, 73, 69, 85, 80, 72, 128, - 73, 69, 85, 78, 71, 45, 67, 73, 69, 85, 67, 128, 73, 69, 85, 78, 71, 45, - 67, 72, 73, 69, 85, 67, 72, 128, 73, 69, 85, 78, 199, 73, 68, 76, 69, - 128, 73, 68, 73, 77, 128, 73, 68, 73, 205, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 68, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 67, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 66, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 65, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 57, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 55, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 70, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 70, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 70, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 70, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 70, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 70, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 69, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 69, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 69, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 69, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 69, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 69, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 69, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 68, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 68, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 68, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 54, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 54, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 57, 49, 52, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 57, 48, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 56, 68, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 56, 67, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 56, 57, 69, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 68, 52, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 65, 55, 65, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 55, 57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 55, 54, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 55, 53, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 53, 49, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 49, 50, 49, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 48, 66, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 54, 70, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 54, 69, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 54, 55, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 55, 48, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 55, 48, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 54, 50, 48, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 54, 53, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 54, 53, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 54, 53, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 51, 53, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 51, 48, 55, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 50, 57, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 54, 50, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 54, 50, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 53, 70, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 68, 69, - 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 66, 56, 57, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 66, 53, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 53, 57, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 53, 57, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 53, 56, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 53, 66, - 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 52, 51, 57, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 52, 48, 56, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 53, 51, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 53, 51, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 53, 50, 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 55, - 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 52, 68, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 49, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 53, 49, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 52, 69, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 52, 69, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 50, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 48, 57, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 48, 48, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 68, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 65, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 65, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 65, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 65, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, - 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 55, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 52, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 65, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 65, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 65, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 65, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 69, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 68, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 67, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 66, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 65, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 65, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 65, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 65, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, - 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 53, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 50, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 65, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 65, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 70, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 70, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 67, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 66, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 65, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 57, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 70, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 70, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 70, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 70, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, - 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 51, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 48, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 69, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 69, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 69, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 69, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 65, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 57, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 56, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 55, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 69, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 69, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 69, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 69, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, - 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 49, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 69, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 68, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 68, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 68, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 56, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 55, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 54, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 53, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, - 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 70, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 67, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 54, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 53, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 52, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 51, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, - 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 68, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 65, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 52, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 51, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 50, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 49, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, - 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 66, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 65, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 56, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 50, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 49, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 48, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 70, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, - 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 57, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 54, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 48, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 70, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 69, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 68, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, - 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 55, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 52, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 69, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 68, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 67, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 66, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, - 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 53, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 50, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 54, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 54, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 67, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 66, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 65, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 57, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, - 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 51, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 48, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 65, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 57, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 56, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 55, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, - 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 49, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 69, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 56, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 55, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 54, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 53, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, - 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 70, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 67, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 54, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 53, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 52, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 51, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, - 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 68, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 65, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 52, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 51, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 50, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 49, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, - 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 66, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 65, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 56, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 50, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 49, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 48, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 70, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, - 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 57, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 54, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 48, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 70, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 69, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 68, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 70, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 70, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, - 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 55, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 52, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 70, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 70, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 69, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 68, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 67, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 66, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 69, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 69, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, - 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 53, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 50, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 69, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 68, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 68, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 67, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 66, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 65, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 57, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, - 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 51, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 48, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 65, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 57, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 56, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 55, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, - 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 49, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 69, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 56, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 55, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 54, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 53, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, - 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 70, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 67, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 54, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 53, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 52, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 51, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, - 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 68, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 65, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 52, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 51, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 50, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 49, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, - 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 66, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 65, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 56, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 50, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 49, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 48, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 70, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, - 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 57, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 54, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 48, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 70, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 69, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 68, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, - 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 55, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 52, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 69, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 68, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 67, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 66, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, - 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 53, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 50, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 67, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 66, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 65, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 57, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, - 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 51, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 48, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 65, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 57, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 56, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 55, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, - 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 49, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 69, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 56, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 55, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 54, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 53, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, - 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 70, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 67, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 54, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 53, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 52, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 51, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, - 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 68, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 65, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 52, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 51, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 50, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 49, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 200, 73, 68, 69, 78, 84, 73, 70, 73, 67, 65, 84, 73, 79, 78, 128, 73, 68, - 69, 78, 84, 73, 70, 73, 67, 65, 84, 73, 79, 206, 73, 68, 69, 78, 84, 73, - 67, 65, 204, 73, 67, 79, 78, 128, 73, 67, 72, 79, 85, 128, 73, 67, 72, - 79, 83, 128, 73, 67, 72, 73, 77, 65, 84, 79, 83, 128, 73, 67, 72, 65, 68, - 73, 78, 128, 73, 67, 69, 76, 65, 78, 68, 73, 67, 45, 89, 82, 128, 73, 66, - 73, 70, 73, 76, 73, 128, 73, 65, 85, 68, 65, 128, 73, 48, 49, 53, 128, - 73, 48, 49, 52, 128, 73, 48, 49, 51, 128, 73, 48, 49, 50, 128, 73, 48, - 49, 49, 65, 128, 73, 48, 49, 49, 128, 73, 48, 49, 48, 65, 128, 73, 48, - 49, 48, 128, 73, 48, 48, 57, 65, 128, 73, 48, 48, 57, 128, 73, 48, 48, - 56, 128, 73, 48, 48, 55, 128, 73, 48, 48, 54, 128, 73, 48, 48, 53, 65, - 128, 73, 48, 48, 53, 128, 73, 48, 48, 52, 128, 73, 48, 48, 51, 128, 73, - 48, 48, 50, 128, 73, 48, 48, 49, 128, 73, 45, 89, 85, 128, 73, 45, 89, - 79, 128, 73, 45, 89, 69, 79, 128, 73, 45, 89, 69, 128, 73, 45, 89, 65, - 69, 128, 73, 45, 89, 65, 45, 79, 128, 73, 45, 89, 65, 128, 73, 45, 79, - 45, 73, 128, 73, 45, 79, 128, 73, 45, 69, 85, 128, 73, 45, 66, 69, 65, - 77, 128, 73, 45, 65, 82, 65, 69, 65, 128, 73, 45, 65, 128, 72, 90, 90, - 90, 71, 128, 72, 90, 90, 90, 128, 72, 90, 90, 80, 128, 72, 90, 90, 128, - 72, 90, 87, 71, 128, 72, 90, 87, 128, 72, 90, 84, 128, 72, 90, 71, 128, - 72, 89, 83, 84, 69, 82, 69, 83, 73, 211, 72, 89, 80, 79, 68, 73, 65, 83, - 84, 79, 76, 69, 128, 72, 89, 80, 72, 69, 78, 65, 84, 73, 79, 206, 72, 89, - 80, 72, 69, 78, 45, 77, 73, 78, 85, 83, 128, 72, 89, 80, 72, 69, 78, 128, - 72, 89, 80, 72, 69, 206, 72, 89, 71, 73, 69, 73, 65, 128, 72, 89, 71, 73, - 69, 65, 128, 72, 88, 87, 71, 128, 72, 88, 85, 79, 88, 128, 72, 88, 85, - 79, 84, 128, 72, 88, 85, 79, 80, 128, 72, 88, 85, 79, 128, 72, 88, 79, - 88, 128, 72, 88, 79, 84, 128, 72, 88, 79, 80, 128, 72, 88, 79, 128, 72, - 88, 73, 88, 128, 72, 88, 73, 84, 128, 72, 88, 73, 80, 128, 72, 88, 73, - 69, 88, 128, 72, 88, 73, 69, 84, 128, 72, 88, 73, 69, 80, 128, 72, 88, - 73, 69, 128, 72, 88, 73, 128, 72, 88, 69, 88, 128, 72, 88, 69, 80, 128, - 72, 88, 69, 128, 72, 88, 65, 88, 128, 72, 88, 65, 84, 128, 72, 88, 65, - 80, 128, 72, 88, 65, 128, 72, 87, 85, 128, 72, 87, 65, 73, 82, 128, 72, - 87, 65, 72, 128, 72, 85, 86, 65, 128, 72, 85, 83, 72, 69, 196, 72, 85, - 83, 72, 128, 72, 85, 82, 65, 78, 128, 72, 85, 79, 84, 128, 72, 85, 78, - 68, 82, 69, 68, 83, 128, 72, 85, 78, 68, 82, 69, 68, 211, 72, 85, 78, 68, - 82, 69, 68, 128, 72, 85, 78, 68, 82, 69, 196, 72, 85, 78, 128, 72, 85, - 77, 208, 72, 85, 77, 65, 78, 128, 72, 85, 77, 65, 206, 72, 85, 76, 50, - 128, 72, 85, 73, 73, 84, 79, 128, 72, 85, 71, 71, 73, 78, 71, 128, 72, - 85, 71, 71, 73, 78, 199, 72, 85, 66, 50, 128, 72, 85, 66, 178, 72, 85, - 66, 128, 72, 85, 65, 82, 65, 68, 68, 79, 128, 72, 85, 65, 78, 128, 72, - 85, 45, 51, 128, 72, 85, 45, 50, 128, 72, 85, 45, 49, 128, 72, 84, 84, - 65, 128, 72, 84, 83, 128, 72, 84, 74, 128, 72, 82, 89, 86, 78, 73, 193, - 72, 80, 87, 71, 128, 72, 80, 65, 128, 72, 80, 128, 72, 79, 85, 83, 197, - 72, 79, 85, 82, 71, 76, 65, 83, 83, 128, 72, 79, 85, 82, 71, 76, 65, 83, - 211, 72, 79, 85, 82, 128, 72, 79, 85, 210, 72, 79, 84, 69, 76, 128, 72, - 79, 84, 65, 128, 72, 79, 83, 80, 73, 84, 65, 76, 128, 72, 79, 82, 83, 69, - 128, 72, 79, 82, 83, 197, 72, 79, 82, 82, 128, 72, 79, 82, 78, 83, 128, - 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 76, 217, 72, 79, 82, 73, 90, 79, - 78, 84, 65, 76, 45, 48, 54, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, - 84, 65, 76, 45, 48, 54, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, - 65, 76, 45, 48, 54, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, - 76, 45, 48, 54, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, - 45, 48, 54, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, - 48, 54, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, - 54, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, - 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, - 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, - 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 51, - 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 50, 128, - 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 49, 128, 72, - 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 48, 128, 72, 79, - 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 54, 128, 72, 79, 82, - 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 53, 128, 72, 79, 82, 73, - 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 52, 128, 72, 79, 82, 73, 90, - 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, - 78, 84, 65, 76, 45, 48, 52, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, - 84, 65, 76, 45, 48, 52, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, - 65, 76, 45, 48, 52, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, - 76, 45, 48, 51, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, - 45, 48, 51, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, - 48, 51, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, - 51, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, - 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, 45, - 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, 45, 48, - 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 54, - 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 53, 128, - 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 52, 128, 72, - 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 51, 128, 72, 79, - 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 50, 128, 72, 79, 82, - 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 49, 128, 72, 79, 82, 73, - 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 48, 128, 72, 79, 82, 73, 90, - 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, - 78, 84, 65, 76, 45, 48, 49, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, - 84, 65, 76, 45, 48, 49, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, - 65, 76, 45, 48, 49, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, - 76, 45, 48, 49, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, - 45, 48, 49, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, - 48, 49, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, - 48, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, - 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, - 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, - 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 50, - 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 49, 128, - 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 48, 128, 72, - 79, 82, 73, 90, 79, 78, 84, 65, 76, 128, 72, 79, 82, 73, 90, 79, 78, 84, - 65, 204, 72, 79, 82, 73, 128, 72, 79, 82, 193, 72, 79, 79, 85, 128, 72, - 79, 79, 82, 85, 128, 72, 79, 79, 80, 128, 72, 79, 79, 78, 128, 72, 79, - 79, 75, 69, 68, 128, 72, 79, 79, 75, 69, 196, 72, 79, 78, 69, 89, 66, 69, - 69, 128, 72, 79, 78, 69, 217, 72, 79, 77, 79, 84, 72, 69, 84, 73, 67, - 128, 72, 79, 77, 79, 84, 72, 69, 84, 73, 195, 72, 79, 76, 79, 128, 72, - 79, 76, 76, 79, 215, 72, 79, 76, 69, 128, 72, 79, 76, 68, 73, 78, 199, - 72, 79, 76, 65, 77, 128, 72, 79, 76, 65, 205, 72, 79, 75, 65, 128, 72, - 79, 67, 75, 69, 217, 72, 79, 67, 72, 79, 128, 72, 79, 45, 56, 128, 72, - 79, 45, 55, 128, 72, 79, 45, 54, 128, 72, 79, 45, 53, 128, 72, 79, 45, - 52, 128, 72, 79, 45, 51, 128, 72, 79, 45, 50, 128, 72, 79, 45, 49, 128, - 72, 78, 85, 84, 128, 72, 78, 85, 79, 88, 128, 72, 78, 85, 79, 128, 72, - 78, 85, 66, 128, 72, 78, 79, 88, 128, 72, 78, 79, 84, 128, 72, 78, 79, - 80, 128, 72, 78, 73, 88, 128, 72, 78, 73, 84, 128, 72, 78, 73, 80, 128, - 72, 78, 73, 69, 88, 128, 72, 78, 73, 69, 84, 128, 72, 78, 73, 69, 80, - 128, 72, 78, 73, 69, 128, 72, 78, 73, 128, 72, 78, 69, 88, 128, 72, 78, - 69, 80, 128, 72, 78, 69, 128, 72, 78, 65, 88, 128, 72, 78, 65, 85, 128, - 72, 78, 65, 84, 128, 72, 78, 65, 80, 128, 72, 78, 65, 128, 72, 77, 89, - 88, 128, 72, 77, 89, 82, 88, 128, 72, 77, 89, 82, 128, 72, 77, 89, 80, - 128, 72, 77, 89, 128, 72, 77, 85, 88, 128, 72, 77, 85, 84, 128, 72, 77, - 85, 82, 88, 128, 72, 77, 85, 82, 128, 72, 77, 85, 80, 128, 72, 77, 85, - 79, 88, 128, 72, 77, 85, 79, 80, 128, 72, 77, 85, 79, 128, 72, 77, 85, - 128, 72, 77, 79, 88, 128, 72, 77, 79, 84, 128, 72, 77, 79, 80, 128, 72, - 77, 79, 128, 72, 77, 73, 88, 128, 72, 77, 73, 84, 128, 72, 77, 73, 80, - 128, 72, 77, 73, 69, 88, 128, 72, 77, 73, 69, 80, 128, 72, 77, 73, 69, - 128, 72, 77, 73, 128, 72, 77, 69, 128, 72, 77, 65, 88, 128, 72, 77, 65, - 84, 128, 72, 77, 65, 80, 128, 72, 77, 65, 128, 72, 76, 89, 88, 128, 72, - 76, 89, 84, 128, 72, 76, 89, 82, 88, 128, 72, 76, 89, 82, 128, 72, 76, - 89, 80, 128, 72, 76, 89, 128, 72, 76, 85, 88, 128, 72, 76, 85, 84, 128, - 72, 76, 85, 82, 88, 128, 72, 76, 85, 82, 128, 72, 76, 85, 80, 128, 72, - 76, 85, 79, 88, 128, 72, 76, 85, 79, 80, 128, 72, 76, 85, 79, 128, 72, - 76, 85, 128, 72, 76, 79, 88, 128, 72, 76, 79, 80, 128, 72, 76, 79, 128, - 72, 76, 73, 88, 128, 72, 76, 73, 84, 128, 72, 76, 73, 80, 128, 72, 76, - 73, 69, 88, 128, 72, 76, 73, 69, 80, 128, 72, 76, 73, 69, 128, 72, 76, - 73, 128, 72, 76, 69, 88, 128, 72, 76, 69, 80, 128, 72, 76, 69, 128, 72, - 76, 65, 88, 128, 72, 76, 65, 85, 128, 72, 76, 65, 84, 128, 72, 76, 65, - 80, 128, 72, 76, 65, 128, 72, 76, 128, 72, 75, 128, 72, 73, 90, 66, 128, - 72, 73, 89, 79, 128, 72, 73, 84, 84, 73, 78, 199, 72, 73, 83, 84, 79, 82, - 73, 195, 72, 73, 82, 73, 81, 128, 72, 73, 80, 80, 79, 80, 79, 84, 65, 77, - 85, 83, 128, 72, 73, 78, 71, 69, 68, 128, 72, 73, 78, 71, 69, 196, 72, - 73, 78, 71, 69, 128, 72, 73, 78, 68, 213, 72, 73, 75, 73, 78, 199, 72, - 73, 71, 72, 45, 83, 80, 69, 69, 196, 72, 73, 71, 72, 45, 82, 69, 86, 69, - 82, 83, 69, 68, 45, 185, 72, 73, 71, 72, 45, 76, 79, 215, 72, 73, 71, 72, - 45, 72, 69, 69, 76, 69, 196, 72, 73, 69, 88, 128, 72, 73, 69, 85, 72, 45, - 83, 73, 79, 83, 128, 72, 73, 69, 85, 72, 45, 82, 73, 69, 85, 76, 128, 72, - 73, 69, 85, 72, 45, 80, 73, 69, 85, 80, 128, 72, 73, 69, 85, 72, 45, 78, - 73, 69, 85, 78, 128, 72, 73, 69, 85, 72, 45, 77, 73, 69, 85, 77, 128, 72, - 73, 69, 85, 200, 72, 73, 69, 82, 79, 71, 76, 89, 80, 72, 73, 195, 72, 73, - 68, 73, 78, 199, 72, 73, 68, 69, 84, 128, 72, 73, 68, 69, 128, 72, 73, - 66, 73, 83, 67, 85, 83, 128, 72, 73, 45, 82, 69, 83, 128, 72, 73, 45, 55, - 128, 72, 73, 45, 54, 128, 72, 73, 45, 53, 128, 72, 73, 45, 52, 128, 72, - 73, 45, 51, 128, 72, 73, 45, 50, 128, 72, 73, 45, 49, 128, 72, 72, 89, - 85, 128, 72, 72, 89, 79, 128, 72, 72, 89, 73, 128, 72, 72, 89, 69, 69, - 128, 72, 72, 89, 69, 128, 72, 72, 89, 65, 65, 128, 72, 72, 89, 65, 128, - 72, 72, 87, 73, 128, 72, 72, 87, 69, 69, 128, 72, 72, 87, 69, 128, 72, - 72, 87, 65, 128, 72, 72, 85, 128, 72, 72, 73, 128, 72, 72, 69, 69, 128, - 72, 72, 69, 128, 72, 72, 65, 65, 128, 72, 71, 128, 72, 69, 89, 84, 128, - 72, 69, 88, 73, 70, 79, 82, 205, 72, 69, 88, 65, 71, 82, 65, 205, 72, 69, - 88, 65, 71, 79, 78, 128, 72, 69, 82, 85, 84, 85, 128, 72, 69, 82, 85, - 128, 72, 69, 82, 77, 73, 84, 73, 65, 206, 72, 69, 82, 77, 73, 79, 78, 73, - 65, 206, 72, 69, 82, 77, 69, 83, 128, 72, 69, 82, 69, 128, 72, 69, 82, - 66, 128, 72, 69, 82, 65, 69, 85, 205, 72, 69, 78, 71, 128, 72, 69, 78, - 199, 72, 69, 77, 80, 128, 72, 69, 76, 77, 69, 84, 128, 72, 69, 76, 77, - 69, 212, 72, 69, 76, 205, 72, 69, 76, 76, 83, 67, 72, 82, 69, 73, 66, 69, - 210, 72, 69, 76, 73, 88, 128, 72, 69, 76, 73, 67, 79, 80, 84, 69, 82, - 128, 72, 69, 75, 85, 84, 65, 65, 82, 85, 128, 72, 69, 73, 83, 69, 73, - 128, 72, 69, 73, 71, 72, 84, 128, 72, 69, 69, 73, 128, 72, 69, 68, 71, - 69, 72, 79, 71, 128, 72, 69, 65, 86, 89, 128, 72, 69, 65, 86, 69, 78, 76, - 217, 72, 69, 65, 86, 69, 78, 128, 72, 69, 65, 86, 69, 206, 72, 69, 65, - 82, 84, 83, 128, 72, 69, 65, 82, 84, 45, 83, 72, 65, 80, 69, 196, 72, 69, - 65, 82, 84, 128, 72, 69, 65, 82, 212, 72, 69, 65, 82, 73, 78, 199, 72, - 69, 65, 82, 45, 78, 79, 45, 69, 86, 73, 204, 72, 69, 65, 68, 83, 84, 82, - 79, 75, 69, 128, 72, 69, 65, 68, 83, 84, 79, 78, 69, 128, 72, 69, 65, 68, - 83, 84, 79, 78, 197, 72, 69, 65, 68, 83, 67, 65, 82, 70, 128, 72, 69, 65, - 68, 80, 72, 79, 78, 69, 128, 72, 69, 65, 68, 73, 78, 71, 128, 72, 69, 65, - 68, 45, 66, 65, 78, 68, 65, 71, 69, 128, 72, 69, 45, 55, 128, 72, 69, 45, - 54, 128, 72, 69, 45, 53, 128, 72, 69, 45, 52, 128, 72, 69, 45, 51, 128, - 72, 69, 45, 50, 128, 72, 69, 45, 49, 128, 72, 68, 82, 128, 72, 67, 128, - 72, 66, 65, 83, 65, 45, 69, 83, 65, 83, 193, 72, 66, 65, 83, 193, 72, 65, - 89, 65, 78, 78, 65, 128, 72, 65, 87, 74, 128, 72, 65, 86, 69, 128, 72, - 65, 85, 80, 84, 83, 84, 73, 77, 77, 69, 128, 72, 65, 213, 72, 65, 84, 82, - 65, 206, 72, 65, 84, 72, 73, 128, 72, 65, 84, 69, 128, 72, 65, 84, 67, - 72, 73, 78, 199, 72, 65, 84, 65, 198, 72, 65, 83, 69, 210, 72, 65, 83, - 65, 78, 84, 65, 128, 72, 65, 82, 80, 79, 79, 78, 128, 72, 65, 82, 80, 79, - 79, 206, 72, 65, 82, 77, 79, 78, 73, 67, 128, 72, 65, 82, 75, 76, 69, 65, - 206, 72, 65, 82, 68, 78, 69, 83, 83, 128, 72, 65, 82, 196, 72, 65, 82, - 66, 65, 72, 65, 89, 128, 72, 65, 80, 80, 217, 72, 65, 78, 85, 78, 79, - 207, 72, 65, 78, 73, 70, 201, 72, 65, 78, 71, 90, 72, 79, 213, 72, 65, - 78, 68, 83, 72, 65, 75, 69, 128, 72, 65, 78, 68, 83, 128, 72, 65, 78, 68, - 211, 72, 65, 78, 68, 76, 69, 83, 128, 72, 65, 78, 68, 76, 69, 128, 72, - 65, 78, 68, 66, 65, 76, 76, 128, 72, 65, 78, 68, 66, 65, 71, 128, 72, 65, - 78, 68, 45, 79, 86, 65, 76, 128, 72, 65, 78, 68, 45, 79, 86, 65, 204, 72, - 65, 78, 68, 45, 72, 79, 79, 75, 128, 72, 65, 78, 68, 45, 72, 79, 79, 203, - 72, 65, 78, 68, 45, 72, 73, 78, 71, 69, 128, 72, 65, 78, 68, 45, 72, 73, - 78, 71, 197, 72, 65, 78, 68, 45, 70, 76, 65, 84, 128, 72, 65, 78, 68, 45, - 70, 76, 65, 212, 72, 65, 78, 68, 45, 70, 73, 83, 84, 128, 72, 65, 78, 68, - 45, 67, 85, 82, 76, 73, 67, 85, 69, 128, 72, 65, 78, 68, 45, 67, 85, 82, - 76, 73, 67, 85, 197, 72, 65, 78, 68, 45, 67, 85, 80, 128, 72, 65, 78, 68, - 45, 67, 85, 208, 72, 65, 78, 68, 45, 67, 76, 65, 87, 128, 72, 65, 78, 68, - 45, 67, 76, 65, 215, 72, 65, 78, 68, 45, 67, 73, 82, 67, 76, 69, 128, 72, - 65, 78, 68, 45, 67, 73, 82, 67, 76, 197, 72, 65, 78, 68, 45, 65, 78, 71, - 76, 69, 128, 72, 65, 78, 68, 45, 65, 78, 71, 76, 197, 72, 65, 78, 68, - 128, 72, 65, 78, 45, 65, 75, 65, 84, 128, 72, 65, 77, 90, 65, 128, 72, - 65, 77, 90, 193, 72, 65, 77, 83, 84, 69, 210, 72, 65, 77, 83, 65, 128, - 72, 65, 77, 77, 69, 82, 128, 72, 65, 77, 77, 69, 210, 72, 65, 77, 66, 85, - 82, 71, 69, 82, 128, 72, 65, 76, 81, 65, 128, 72, 65, 76, 79, 128, 72, - 65, 76, 70, 45, 67, 73, 82, 67, 76, 197, 72, 65, 76, 70, 45, 50, 128, 72, - 65, 76, 70, 45, 49, 128, 72, 65, 76, 70, 128, 72, 65, 76, 66, 69, 82, 68, - 128, 72, 65, 76, 65, 78, 84, 65, 128, 72, 65, 73, 84, 85, 128, 72, 65, - 73, 211, 72, 65, 73, 82, 67, 85, 84, 128, 72, 65, 71, 76, 65, 218, 72, - 65, 71, 76, 128, 72, 65, 70, 85, 75, 72, 65, 128, 72, 65, 70, 85, 75, 72, - 128, 72, 65, 69, 71, 204, 72, 65, 68, 69, 83, 128, 72, 65, 65, 82, 85, - 128, 72, 65, 65, 77, 128, 72, 65, 193, 72, 65, 45, 72, 65, 128, 72, 65, - 45, 57, 128, 72, 65, 45, 56, 128, 72, 65, 45, 55, 128, 72, 65, 45, 54, - 128, 72, 65, 45, 53, 128, 72, 65, 45, 52, 128, 72, 65, 45, 51, 128, 72, - 65, 45, 50, 128, 72, 65, 45, 49, 49, 128, 72, 65, 45, 49, 48, 128, 72, - 65, 45, 49, 128, 72, 48, 48, 56, 128, 72, 48, 48, 55, 128, 72, 48, 48, - 54, 65, 128, 72, 48, 48, 54, 128, 72, 48, 48, 53, 128, 72, 48, 48, 52, - 128, 72, 48, 48, 51, 128, 72, 48, 48, 50, 128, 72, 48, 48, 49, 128, 72, - 45, 84, 89, 80, 197, 71, 89, 85, 128, 71, 89, 79, 78, 128, 71, 89, 79, - 128, 71, 89, 73, 128, 71, 89, 70, 213, 71, 89, 69, 69, 128, 71, 89, 65, - 83, 128, 71, 89, 65, 65, 128, 71, 89, 65, 128, 71, 89, 128, 71, 87, 85, - 128, 71, 87, 73, 128, 71, 87, 69, 69, 128, 71, 87, 69, 128, 71, 87, 65, - 65, 128, 71, 87, 65, 128, 71, 87, 128, 71, 86, 65, 78, 71, 128, 71, 86, - 128, 71, 85, 82, 85, 83, 72, 128, 71, 85, 82, 85, 78, 128, 71, 85, 82, - 77, 85, 75, 72, 201, 71, 85, 82, 65, 77, 85, 84, 79, 78, 128, 71, 85, 82, - 65, 71, 197, 71, 85, 82, 55, 128, 71, 85, 78, 85, 128, 71, 85, 78, 213, - 71, 85, 78, 74, 65, 76, 193, 71, 85, 205, 71, 85, 76, 128, 71, 85, 74, - 65, 82, 65, 84, 201, 71, 85, 73, 84, 65, 82, 128, 71, 85, 73, 68, 197, - 71, 85, 199, 71, 85, 69, 73, 128, 71, 85, 69, 72, 128, 71, 85, 69, 200, - 71, 85, 68, 128, 71, 85, 196, 71, 85, 65, 82, 68, 83, 77, 65, 78, 128, - 71, 85, 65, 82, 68, 69, 68, 78, 69, 83, 83, 128, 71, 85, 65, 82, 68, 69, - 196, 71, 85, 65, 82, 68, 128, 71, 85, 65, 82, 65, 78, 201, 71, 85, 193, - 71, 85, 178, 71, 84, 69, 210, 71, 83, 85, 77, 128, 71, 83, 85, 205, 71, - 82, 213, 71, 82, 79, 87, 73, 78, 199, 71, 82, 79, 85, 78, 68, 128, 71, - 82, 79, 78, 84, 72, 73, 83, 77, 65, 84, 65, 128, 71, 82, 79, 77, 79, 80, - 79, 86, 79, 68, 78, 65, 89, 65, 128, 71, 82, 79, 77, 79, 80, 79, 86, 79, - 68, 78, 65, 89, 193, 71, 82, 79, 77, 79, 75, 82, 89, 90, 72, 69, 86, 65, - 89, 65, 128, 71, 82, 79, 77, 79, 75, 82, 89, 90, 72, 69, 86, 65, 89, 193, - 71, 82, 79, 77, 78, 65, 89, 65, 128, 71, 82, 79, 77, 78, 65, 89, 193, 71, - 82, 73, 78, 78, 73, 78, 199, 71, 82, 73, 77, 65, 67, 73, 78, 199, 71, 82, - 69, 71, 79, 82, 73, 65, 206, 71, 82, 69, 69, 78, 128, 71, 82, 69, 69, - 206, 71, 82, 69, 65, 84, 78, 69, 83, 83, 128, 71, 82, 69, 65, 84, 69, 82, - 45, 84, 72, 65, 78, 128, 71, 82, 69, 65, 84, 69, 82, 45, 84, 72, 65, 206, - 71, 82, 69, 65, 84, 69, 210, 71, 82, 69, 65, 212, 71, 82, 65, 86, 69, 89, - 65, 82, 196, 71, 82, 65, 86, 69, 45, 77, 65, 67, 82, 79, 78, 128, 71, 82, - 65, 86, 69, 45, 65, 67, 85, 84, 69, 45, 71, 82, 65, 86, 69, 128, 71, 82, - 65, 86, 197, 71, 82, 65, 84, 69, 82, 128, 71, 82, 65, 83, 83, 128, 71, - 82, 65, 83, 211, 71, 82, 65, 83, 208, 71, 82, 65, 80, 72, 69, 77, 197, - 71, 82, 65, 80, 69, 83, 128, 71, 82, 65, 78, 84, 72, 193, 71, 82, 65, 77, - 77, 193, 71, 82, 65, 73, 78, 128, 71, 82, 65, 70, 128, 71, 82, 65, 68, - 85, 65, 84, 73, 79, 206, 71, 82, 65, 68, 85, 65, 76, 128, 71, 82, 65, 67, - 69, 128, 71, 82, 65, 67, 197, 71, 80, 65, 128, 71, 79, 82, 84, 72, 77, - 73, 75, 79, 206, 71, 79, 82, 84, 128, 71, 79, 82, 73, 76, 76, 65, 128, - 71, 79, 82, 71, 79, 84, 69, 82, 73, 128, 71, 79, 82, 71, 79, 83, 89, 78, - 84, 72, 69, 84, 79, 78, 128, 71, 79, 82, 71, 79, 206, 71, 79, 82, 71, 73, - 128, 71, 79, 82, 65, 90, 68, 207, 71, 79, 82, 65, 128, 71, 79, 79, 196, - 71, 79, 78, 71, 128, 71, 79, 76, 85, 66, 67, 72, 73, 203, 71, 79, 76, 70, - 69, 82, 128, 71, 79, 76, 68, 128, 71, 79, 75, 128, 71, 79, 73, 78, 199, - 71, 79, 71, 71, 76, 69, 83, 128, 71, 79, 66, 76, 73, 78, 128, 71, 79, 65, - 76, 128, 71, 79, 65, 204, 71, 79, 65, 128, 71, 78, 89, 73, 83, 128, 71, - 78, 65, 86, 73, 89, 65, 78, 73, 128, 71, 76, 79, 87, 73, 78, 199, 71, 76, - 79, 86, 69, 83, 128, 71, 76, 79, 86, 69, 128, 71, 76, 79, 84, 84, 65, - 204, 71, 76, 79, 66, 197, 71, 76, 73, 83, 83, 65, 78, 68, 207, 71, 76, - 69, 73, 67, 200, 71, 76, 65, 71, 79, 76, 73, 128, 71, 76, 65, 128, 71, - 74, 69, 128, 71, 73, 88, 128, 71, 73, 84, 128, 71, 73, 83, 72, 128, 71, - 73, 83, 200, 71, 73, 83, 65, 76, 128, 71, 73, 82, 85, 68, 65, 65, 128, - 71, 73, 82, 76, 211, 71, 73, 82, 76, 128, 71, 73, 82, 65, 70, 70, 197, - 71, 73, 82, 51, 128, 71, 73, 82, 179, 71, 73, 82, 50, 128, 71, 73, 82, - 178, 71, 73, 80, 128, 71, 73, 78, 73, 73, 128, 71, 73, 77, 69, 76, 45, - 72, 69, 84, 72, 128, 71, 73, 77, 69, 76, 128, 71, 73, 77, 69, 204, 71, - 73, 77, 128, 71, 73, 71, 65, 128, 71, 73, 71, 128, 71, 73, 70, 212, 71, - 73, 69, 84, 128, 71, 73, 68, 73, 77, 128, 71, 73, 66, 66, 79, 85, 211, - 71, 73, 66, 65, 128, 71, 73, 52, 128, 71, 73, 180, 71, 72, 90, 128, 71, - 72, 87, 65, 128, 71, 72, 85, 78, 78, 65, 128, 71, 72, 85, 78, 78, 193, - 71, 72, 85, 128, 71, 72, 79, 85, 128, 71, 72, 79, 83, 84, 128, 71, 72, - 79, 128, 71, 72, 73, 77, 69, 76, 128, 71, 72, 73, 128, 71, 72, 72, 65, - 128, 71, 72, 69, 89, 83, 128, 71, 72, 69, 85, 88, 128, 71, 72, 69, 85, - 78, 128, 71, 72, 69, 85, 71, 72, 69, 85, 65, 69, 77, 128, 71, 72, 69, 85, - 71, 72, 69, 78, 128, 71, 72, 69, 85, 65, 69, 82, 65, 69, 128, 71, 72, 69, - 85, 65, 69, 71, 72, 69, 85, 65, 69, 128, 71, 72, 69, 84, 128, 71, 72, 69, - 69, 128, 71, 72, 69, 128, 71, 72, 197, 71, 72, 65, 89, 78, 128, 71, 72, - 65, 82, 65, 69, 128, 71, 72, 65, 80, 128, 71, 72, 65, 78, 128, 71, 72, - 65, 77, 77, 65, 128, 71, 72, 65, 77, 65, 76, 128, 71, 72, 65, 73, 78, 85, + 77, 85, 73, 78, 128, 77, 85, 72, 79, 82, 128, 77, 85, 71, 83, 128, 77, + 85, 71, 128, 77, 85, 199, 77, 85, 69, 78, 128, 77, 85, 69, 128, 77, 85, + 67, 72, 128, 77, 85, 67, 200, 77, 85, 67, 65, 65, 68, 128, 77, 85, 65, + 83, 128, 77, 85, 65, 78, 128, 77, 85, 65, 69, 128, 77, 85, 45, 71, 65, + 65, 72, 76, 65, 193, 77, 85, 45, 52, 128, 77, 85, 45, 51, 128, 77, 85, + 45, 50, 128, 77, 85, 45, 49, 128, 77, 213, 77, 84, 65, 86, 82, 85, 76, + 201, 77, 83, 128, 77, 82, 207, 77, 82, 65, 67, 72, 78, 89, 128, 77, 82, + 65, 67, 72, 78, 79, 84, 73, 75, 72, 65, 89, 65, 128, 77, 82, 65, 67, 72, + 78, 79, 128, 77, 82, 65, 67, 72, 78, 65, 89, 65, 128, 77, 210, 77, 81, + 128, 77, 80, 65, 128, 77, 79, 89, 65, 73, 128, 77, 79, 88, 128, 77, 79, + 86, 73, 197, 77, 79, 86, 69, 211, 77, 79, 86, 69, 77, 69, 78, 84, 45, 87, + 65, 76, 76, 80, 76, 65, 78, 197, 77, 79, 86, 69, 77, 69, 78, 84, 45, 72, + 73, 78, 71, 197, 77, 79, 86, 69, 77, 69, 78, 84, 45, 70, 76, 79, 79, 82, + 80, 76, 65, 78, 197, 77, 79, 86, 69, 77, 69, 78, 84, 45, 68, 73, 65, 71, + 79, 78, 65, 204, 77, 79, 86, 69, 77, 69, 78, 84, 128, 77, 79, 86, 69, 77, + 69, 78, 212, 77, 79, 86, 69, 196, 77, 79, 86, 69, 128, 77, 79, 85, 84, + 72, 128, 77, 79, 85, 83, 69, 128, 77, 79, 85, 83, 197, 77, 79, 85, 78, + 84, 65, 73, 78, 83, 128, 77, 79, 85, 78, 84, 65, 73, 78, 128, 77, 79, 85, + 78, 84, 65, 73, 206, 77, 79, 85, 78, 212, 77, 79, 85, 78, 68, 128, 77, + 79, 85, 78, 196, 77, 79, 84, 79, 82, 87, 65, 89, 128, 77, 79, 84, 79, 82, + 73, 90, 69, 196, 77, 79, 84, 79, 82, 67, 89, 67, 76, 69, 128, 77, 79, 84, + 79, 210, 77, 79, 84, 72, 69, 82, 128, 77, 79, 84, 72, 69, 210, 77, 79, + 84, 128, 77, 79, 83, 81, 85, 73, 84, 79, 128, 77, 79, 83, 81, 85, 69, + 128, 77, 79, 82, 84, 85, 85, 77, 128, 77, 79, 82, 84, 65, 82, 128, 77, + 79, 82, 80, 72, 79, 76, 79, 71, 73, 67, 65, 204, 77, 79, 82, 78, 73, 78, + 71, 128, 77, 79, 80, 128, 77, 79, 79, 83, 69, 45, 67, 82, 69, 197, 77, + 79, 79, 83, 69, 128, 77, 79, 79, 78, 128, 77, 79, 79, 206, 77, 79, 79, + 77, 80, 85, 81, 128, 77, 79, 79, 77, 69, 85, 84, 128, 77, 79, 79, 68, + 128, 77, 79, 79, 196, 77, 79, 79, 128, 77, 79, 78, 84, 73, 69, 69, 78, + 128, 77, 79, 78, 84, 72, 128, 77, 79, 78, 84, 200, 77, 79, 78, 83, 84, + 69, 82, 128, 77, 79, 78, 79, 83, 84, 65, 66, 76, 197, 77, 79, 78, 79, 83, + 80, 65, 67, 197, 77, 79, 78, 79, 82, 65, 73, 76, 128, 77, 79, 78, 79, 71, + 82, 65, 80, 200, 77, 79, 78, 79, 71, 82, 65, 77, 77, 79, 211, 77, 79, 78, + 79, 71, 82, 65, 205, 77, 79, 78, 79, 70, 79, 78, 73, 65, 83, 128, 77, 79, + 78, 79, 67, 85, 76, 65, 210, 77, 79, 78, 79, 67, 76, 69, 128, 77, 79, 78, + 75, 69, 89, 128, 77, 79, 78, 75, 69, 217, 77, 79, 78, 73, 128, 77, 79, + 78, 71, 75, 69, 85, 65, 69, 81, 128, 77, 79, 78, 69, 89, 45, 77, 79, 85, + 84, 200, 77, 79, 78, 69, 217, 77, 79, 78, 128, 77, 79, 206, 77, 79, 76, + 128, 77, 79, 75, 72, 65, 83, 83, 65, 83, 128, 77, 79, 72, 65, 77, 77, 65, + 196, 77, 79, 68, 85, 76, 207, 77, 79, 68, 73, 70, 73, 69, 82, 45, 57, + 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 56, 128, 77, 79, 68, 73, 70, 73, + 69, 82, 45, 55, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 54, 128, 77, 79, + 68, 73, 70, 73, 69, 82, 45, 53, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, + 52, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 51, 128, 77, 79, 68, 73, 70, + 73, 69, 82, 45, 50, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 54, 128, + 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 53, 128, 77, 79, 68, 73, 70, 73, + 69, 82, 45, 49, 52, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 51, 128, + 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 50, 128, 77, 79, 68, 73, 70, 73, + 69, 82, 45, 49, 49, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 48, 128, + 77, 79, 68, 73, 70, 73, 69, 82, 128, 77, 79, 68, 201, 77, 79, 68, 69, 83, + 84, 89, 128, 77, 79, 68, 69, 82, 206, 77, 79, 68, 69, 77, 128, 77, 79, + 68, 69, 76, 83, 128, 77, 79, 68, 69, 76, 128, 77, 79, 68, 69, 128, 77, + 79, 66, 73, 76, 197, 77, 79, 65, 128, 77, 79, 45, 54, 128, 77, 79, 45, + 53, 128, 77, 79, 45, 52, 128, 77, 79, 45, 51, 128, 77, 207, 77, 78, 89, + 65, 205, 77, 78, 65, 83, 128, 77, 77, 83, 80, 128, 77, 77, 128, 77, 205, + 77, 76, 65, 128, 77, 76, 128, 77, 75, 80, 65, 82, 65, 209, 77, 73, 88, + 128, 77, 73, 84, 128, 77, 73, 83, 82, 65, 128, 77, 73, 82, 82, 79, 82, + 128, 77, 73, 82, 82, 79, 210, 77, 73, 82, 73, 66, 65, 65, 82, 85, 128, + 77, 73, 82, 73, 128, 77, 73, 82, 69, 68, 128, 77, 73, 80, 128, 77, 73, + 78, 89, 128, 77, 73, 78, 85, 83, 45, 79, 82, 45, 80, 76, 85, 211, 77, 73, + 78, 85, 83, 128, 77, 73, 78, 78, 65, 206, 77, 73, 78, 73, 83, 84, 69, 82, + 128, 77, 73, 78, 73, 77, 73, 90, 69, 128, 77, 73, 78, 73, 77, 65, 128, + 77, 73, 78, 73, 68, 73, 83, 67, 128, 77, 73, 78, 73, 66, 85, 83, 128, 77, + 73, 78, 68, 85, 128, 77, 73, 77, 69, 128, 77, 73, 77, 128, 77, 73, 76, + 76, 73, 79, 78, 83, 128, 77, 73, 76, 76, 73, 79, 78, 211, 77, 73, 76, 76, + 69, 84, 128, 77, 73, 76, 76, 197, 77, 73, 76, 204, 77, 73, 76, 75, 217, + 77, 73, 76, 75, 128, 77, 73, 76, 73, 84, 65, 82, 217, 77, 73, 76, 128, + 77, 73, 75, 85, 82, 79, 78, 128, 77, 73, 75, 82, 79, 206, 77, 73, 75, 82, + 73, 128, 77, 73, 73, 78, 128, 77, 73, 73, 77, 128, 77, 73, 73, 128, 77, + 73, 199, 77, 73, 69, 88, 128, 77, 73, 69, 85, 77, 45, 84, 73, 75, 69, 85, + 84, 128, 77, 73, 69, 85, 77, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, + 77, 73, 69, 85, 77, 45, 83, 83, 65, 78, 71, 78, 73, 69, 85, 78, 128, 77, + 73, 69, 85, 77, 45, 82, 73, 69, 85, 76, 128, 77, 73, 69, 85, 77, 45, 80, + 73, 69, 85, 80, 45, 83, 73, 79, 83, 128, 77, 73, 69, 85, 77, 45, 80, 73, + 69, 85, 80, 128, 77, 73, 69, 85, 77, 45, 80, 65, 78, 83, 73, 79, 83, 128, + 77, 73, 69, 85, 77, 45, 78, 73, 69, 85, 78, 128, 77, 73, 69, 85, 77, 45, + 67, 73, 69, 85, 67, 128, 77, 73, 69, 85, 77, 45, 67, 72, 73, 69, 85, 67, + 72, 128, 77, 73, 69, 85, 205, 77, 73, 69, 80, 128, 77, 73, 69, 69, 128, + 77, 73, 69, 128, 77, 73, 68, 76, 73, 78, 197, 77, 73, 68, 68, 76, 69, 45, + 87, 69, 76, 83, 200, 77, 73, 68, 68, 76, 69, 128, 77, 73, 68, 45, 76, 69, + 86, 69, 204, 77, 73, 68, 45, 72, 69, 73, 71, 72, 212, 77, 73, 196, 77, + 73, 67, 82, 79, 83, 67, 79, 80, 69, 128, 77, 73, 67, 82, 79, 80, 72, 79, + 78, 69, 128, 77, 73, 67, 82, 79, 66, 69, 128, 77, 73, 67, 82, 207, 77, + 73, 67, 210, 77, 73, 45, 55, 128, 77, 73, 45, 54, 128, 77, 73, 45, 53, + 128, 77, 73, 45, 52, 128, 77, 73, 45, 51, 128, 77, 73, 45, 50, 128, 77, + 73, 45, 49, 128, 77, 72, 90, 128, 77, 72, 65, 128, 77, 72, 128, 77, 71, + 85, 88, 128, 77, 71, 85, 84, 128, 77, 71, 85, 82, 88, 128, 77, 71, 85, + 82, 128, 77, 71, 85, 80, 128, 77, 71, 85, 79, 88, 128, 77, 71, 85, 79, + 80, 128, 77, 71, 85, 79, 128, 77, 71, 85, 128, 77, 71, 79, 88, 128, 77, + 71, 79, 84, 128, 77, 71, 79, 80, 128, 77, 71, 79, 128, 77, 71, 207, 77, + 71, 73, 69, 88, 128, 77, 71, 73, 69, 128, 77, 71, 69, 88, 128, 77, 71, + 69, 80, 128, 77, 71, 69, 128, 77, 71, 66, 85, 128, 77, 71, 66, 79, 79, + 128, 77, 71, 66, 79, 70, 85, 77, 128, 77, 71, 66, 79, 128, 77, 71, 66, + 73, 128, 77, 71, 66, 69, 85, 78, 128, 77, 71, 66, 69, 78, 128, 77, 71, + 66, 69, 69, 128, 77, 71, 66, 69, 128, 77, 71, 66, 65, 83, 65, 81, 128, + 77, 71, 66, 65, 83, 65, 128, 77, 71, 65, 88, 128, 77, 71, 65, 84, 128, + 77, 71, 65, 80, 128, 77, 71, 65, 128, 77, 71, 128, 77, 70, 79, 78, 128, + 77, 70, 79, 206, 77, 70, 79, 128, 77, 70, 73, 89, 65, 81, 128, 77, 70, + 73, 69, 69, 128, 77, 70, 69, 85, 84, 128, 77, 70, 69, 85, 81, 128, 77, + 70, 69, 85, 65, 69, 128, 77, 70, 65, 65, 128, 77, 69, 90, 90, 79, 128, + 77, 69, 88, 128, 77, 69, 85, 212, 77, 69, 85, 81, 128, 77, 69, 85, 78, + 74, 79, 77, 78, 68, 69, 85, 81, 128, 77, 69, 85, 78, 128, 77, 69, 84, 82, + 79, 128, 77, 69, 84, 82, 73, 67, 65, 204, 77, 69, 84, 82, 73, 65, 128, + 77, 69, 84, 82, 69, 84, 69, 211, 77, 69, 84, 79, 66, 69, 76, 85, 83, 128, + 77, 69, 84, 69, 75, 128, 77, 69, 84, 69, 71, 128, 77, 69, 84, 65, 76, + 128, 77, 69, 84, 193, 77, 69, 83, 83, 69, 78, 73, 65, 206, 77, 69, 83, + 83, 65, 71, 69, 128, 77, 69, 83, 83, 65, 71, 197, 77, 69, 83, 79, 128, + 77, 69, 83, 73, 128, 77, 69, 83, 72, 128, 77, 69, 82, 80, 69, 82, 83, 79, + 78, 128, 77, 69, 82, 75, 72, 65, 128, 77, 69, 82, 75, 72, 193, 77, 69, + 82, 73, 68, 73, 65, 78, 83, 128, 77, 69, 82, 73, 128, 77, 69, 82, 71, 69, + 128, 77, 69, 82, 67, 85, 82, 89, 128, 77, 69, 82, 67, 85, 82, 217, 77, + 69, 78, 79, 82, 65, 200, 77, 69, 78, 79, 69, 128, 77, 69, 78, 68, 85, 84, + 128, 77, 69, 78, 128, 77, 69, 77, 79, 128, 77, 69, 77, 66, 69, 82, 83, + 72, 73, 80, 128, 77, 69, 77, 66, 69, 82, 128, 77, 69, 77, 66, 69, 210, + 77, 69, 77, 45, 81, 79, 80, 72, 128, 77, 69, 77, 128, 77, 69, 205, 77, + 69, 76, 84, 73, 78, 199, 77, 69, 76, 79, 68, 73, 195, 77, 69, 76, 73, 75, + 128, 77, 69, 73, 90, 73, 128, 77, 69, 71, 65, 84, 79, 78, 128, 77, 69, + 71, 65, 80, 72, 79, 78, 69, 128, 77, 69, 71, 65, 76, 73, 128, 77, 69, 69, + 84, 79, 82, 85, 128, 77, 69, 69, 84, 69, 201, 77, 69, 69, 84, 128, 77, + 69, 69, 77, 85, 128, 77, 69, 69, 77, 128, 77, 69, 69, 202, 77, 69, 69, + 69, 69, 128, 77, 69, 68, 73, 85, 77, 128, 77, 69, 68, 73, 85, 205, 77, + 69, 68, 73, 69, 86, 65, 204, 77, 69, 68, 73, 67, 73, 78, 69, 128, 77, 69, + 68, 73, 67, 65, 204, 77, 69, 68, 73, 65, 204, 77, 69, 68, 69, 70, 65, 73, + 68, 82, 73, 206, 77, 69, 68, 65, 76, 128, 77, 69, 67, 72, 73, 75, 128, + 77, 69, 67, 72, 73, 203, 77, 69, 67, 72, 65, 78, 73, 67, 65, 204, 77, 69, + 65, 84, 128, 77, 69, 65, 212, 77, 69, 65, 83, 85, 82, 69, 196, 77, 69, + 65, 83, 85, 82, 69, 128, 77, 69, 65, 83, 85, 82, 197, 77, 69, 45, 77, 65, + 128, 77, 69, 45, 50, 128, 77, 69, 45, 49, 128, 77, 68, 85, 206, 77, 196, + 77, 67, 72, 213, 77, 67, 72, 65, 206, 77, 67, 128, 77, 195, 77, 66, 85, + 85, 128, 77, 66, 85, 79, 81, 128, 77, 66, 85, 79, 128, 77, 66, 85, 69, + 128, 77, 66, 85, 65, 69, 77, 128, 77, 66, 85, 65, 69, 128, 77, 66, 79, + 79, 128, 77, 66, 79, 128, 77, 66, 73, 84, 128, 77, 66, 73, 212, 77, 66, + 73, 82, 73, 69, 69, 78, 128, 77, 66, 73, 128, 77, 66, 69, 85, 88, 128, + 77, 66, 69, 85, 82, 73, 128, 77, 66, 69, 85, 77, 128, 77, 66, 69, 82, 65, + 69, 128, 77, 66, 69, 78, 128, 77, 66, 69, 69, 75, 69, 69, 84, 128, 77, + 66, 69, 69, 128, 77, 66, 69, 128, 77, 66, 65, 81, 128, 77, 66, 65, 78, + 89, 73, 128, 77, 66, 65, 65, 82, 65, 69, 128, 77, 66, 65, 65, 75, 69, 84, + 128, 77, 66, 65, 65, 128, 77, 66, 65, 193, 77, 66, 193, 77, 66, 52, 128, + 77, 66, 51, 128, 77, 66, 50, 128, 77, 65, 89, 69, 203, 77, 65, 89, 65, + 78, 78, 65, 128, 77, 65, 89, 65, 206, 77, 65, 89, 128, 77, 65, 88, 73, + 77, 73, 90, 69, 128, 77, 65, 88, 73, 77, 65, 128, 77, 65, 88, 128, 77, + 65, 85, 128, 77, 65, 84, 84, 79, 67, 75, 128, 77, 65, 84, 82, 73, 88, + 128, 77, 65, 84, 69, 82, 73, 65, 76, 83, 128, 77, 65, 84, 128, 77, 65, + 83, 213, 77, 65, 83, 83, 73, 78, 71, 128, 77, 65, 83, 83, 65, 71, 69, + 128, 77, 65, 83, 79, 82, 193, 77, 65, 83, 75, 128, 77, 65, 83, 203, 77, + 65, 83, 72, 70, 65, 65, 84, 128, 77, 65, 83, 72, 50, 128, 77, 65, 83, 67, + 85, 76, 73, 78, 197, 77, 65, 83, 65, 82, 65, 205, 77, 65, 82, 89, 128, + 77, 65, 82, 87, 65, 82, 201, 77, 65, 82, 85, 75, 85, 128, 77, 65, 82, 84, + 89, 82, 73, 193, 77, 65, 82, 84, 73, 65, 204, 77, 65, 82, 82, 89, 73, 78, + 199, 77, 65, 82, 82, 73, 65, 71, 197, 77, 65, 82, 82, 65, 84, 65, 78, + 128, 77, 65, 82, 75, 211, 77, 65, 82, 75, 69, 82, 128, 77, 65, 82, 75, + 45, 52, 128, 77, 65, 82, 75, 45, 51, 128, 77, 65, 82, 75, 45, 50, 128, + 77, 65, 82, 75, 45, 49, 128, 77, 65, 82, 69, 128, 77, 65, 82, 67, 72, 69, + 206, 77, 65, 82, 67, 72, 128, 77, 65, 82, 67, 65, 84, 79, 45, 83, 84, 65, + 67, 67, 65, 84, 79, 128, 77, 65, 82, 67, 65, 84, 79, 128, 77, 65, 82, 67, + 65, 83, 73, 84, 69, 128, 77, 65, 82, 66, 85, 84, 65, 128, 77, 65, 82, 66, + 85, 84, 193, 77, 65, 82, 65, 67, 65, 83, 128, 77, 65, 82, 128, 77, 65, + 81, 65, 70, 128, 77, 65, 81, 128, 77, 65, 80, 76, 197, 77, 65, 80, 73, + 81, 128, 77, 65, 208, 77, 65, 79, 128, 77, 65, 78, 85, 65, 204, 77, 65, + 78, 84, 69, 76, 80, 73, 69, 67, 197, 77, 65, 78, 83, 89, 79, 78, 128, 77, + 65, 78, 83, 85, 65, 69, 128, 77, 65, 78, 78, 65, 218, 77, 65, 78, 78, 65, + 128, 77, 65, 78, 73, 67, 72, 65, 69, 65, 206, 77, 65, 78, 71, 79, 128, + 77, 65, 78, 71, 65, 76, 65, 77, 128, 77, 65, 78, 68, 65, 82, 73, 78, 128, + 77, 65, 78, 68, 65, 73, 76, 73, 78, 199, 77, 65, 78, 68, 65, 73, 195, 77, + 65, 78, 67, 72, 213, 77, 65, 78, 65, 212, 77, 65, 78, 65, 67, 76, 69, 83, + 128, 77, 65, 77, 77, 79, 84, 72, 128, 77, 65, 76, 84, 69, 83, 197, 77, + 65, 76, 207, 77, 65, 76, 69, 69, 82, 73, 128, 77, 65, 76, 197, 77, 65, + 76, 65, 75, 79, 206, 77, 65, 75, 83, 85, 82, 65, 128, 77, 65, 75, 83, 85, + 82, 193, 77, 65, 75, 69, 77, 65, 75, 69, 128, 77, 65, 75, 65, 83, 65, + 210, 77, 65, 73, 90, 69, 128, 77, 65, 73, 89, 65, 77, 79, 75, 128, 77, + 65, 73, 84, 65, 73, 75, 72, 85, 128, 77, 65, 73, 82, 85, 128, 77, 65, 73, + 77, 85, 65, 78, 128, 77, 65, 73, 77, 65, 76, 65, 73, 128, 77, 65, 73, 76, + 66, 79, 216, 77, 65, 73, 75, 85, 82, 79, 128, 77, 65, 73, 68, 69, 78, + 128, 77, 65, 73, 128, 77, 65, 72, 74, 79, 78, 199, 77, 65, 72, 72, 65, + 128, 77, 65, 72, 65, 80, 82, 65, 78, 65, 128, 77, 65, 72, 65, 80, 65, 75, + 72, 128, 77, 65, 72, 65, 74, 65, 78, 201, 77, 65, 72, 65, 65, 80, 82, 65, + 65, 78, 193, 77, 65, 72, 128, 77, 65, 71, 78, 73, 70, 89, 73, 78, 199, + 77, 65, 71, 78, 69, 84, 128, 77, 65, 71, 73, 195, 77, 65, 71, 69, 128, + 77, 65, 69, 83, 73, 128, 77, 65, 69, 78, 89, 73, 128, 77, 65, 69, 78, 74, + 69, 84, 128, 77, 65, 69, 77, 86, 69, 85, 88, 128, 77, 65, 69, 77, 75, 80, + 69, 78, 128, 77, 65, 69, 77, 71, 66, 73, 69, 69, 128, 77, 65, 69, 77, 66, + 71, 66, 73, 69, 69, 128, 77, 65, 69, 77, 66, 65, 128, 77, 65, 69, 77, + 128, 77, 65, 69, 76, 69, 69, 128, 77, 65, 69, 75, 69, 85, 80, 128, 77, + 65, 68, 89, 65, 128, 77, 65, 68, 85, 128, 77, 65, 68, 68, 65, 72, 128, + 77, 65, 68, 68, 65, 200, 77, 65, 68, 68, 65, 128, 77, 65, 68, 68, 193, + 77, 65, 67, 82, 79, 78, 45, 71, 82, 65, 86, 69, 128, 77, 65, 67, 82, 79, + 78, 45, 66, 82, 69, 86, 69, 128, 77, 65, 67, 82, 79, 78, 45, 65, 67, 85, + 84, 69, 128, 77, 65, 67, 82, 79, 78, 128, 77, 65, 67, 82, 79, 206, 77, + 65, 67, 72, 73, 78, 69, 128, 77, 65, 65, 89, 89, 65, 65, 128, 77, 65, 65, + 73, 128, 77, 65, 65, 128, 77, 65, 50, 128, 77, 65, 45, 55, 128, 77, 65, + 45, 54, 128, 77, 65, 45, 53, 128, 77, 65, 45, 52, 128, 77, 65, 45, 51, + 128, 77, 65, 45, 50, 128, 77, 65, 45, 49, 128, 77, 49, 57, 183, 77, 49, + 57, 182, 77, 49, 57, 181, 77, 49, 57, 180, 77, 49, 57, 179, 77, 49, 57, + 178, 77, 49, 57, 177, 77, 49, 57, 176, 77, 49, 56, 185, 77, 49, 56, 184, + 77, 49, 56, 183, 77, 49, 56, 182, 77, 49, 56, 181, 77, 49, 56, 180, 77, + 49, 56, 179, 77, 49, 56, 178, 77, 49, 56, 177, 77, 49, 56, 176, 77, 49, + 55, 185, 77, 49, 55, 184, 77, 49, 55, 183, 77, 49, 55, 182, 77, 49, 55, + 181, 77, 49, 55, 180, 77, 49, 55, 179, 77, 49, 55, 178, 77, 49, 55, 177, + 77, 49, 55, 176, 77, 49, 54, 185, 77, 49, 54, 184, 77, 49, 54, 183, 77, + 49, 54, 182, 77, 49, 54, 181, 77, 49, 54, 180, 77, 49, 54, 179, 77, 49, + 54, 178, 77, 49, 54, 177, 77, 49, 54, 176, 77, 49, 53, 185, 77, 49, 53, + 184, 77, 49, 53, 183, 77, 49, 53, 182, 77, 49, 53, 181, 77, 49, 53, 180, + 77, 49, 53, 179, 77, 49, 53, 178, 77, 49, 53, 177, 77, 49, 53, 176, 77, + 49, 52, 185, 77, 49, 52, 184, 77, 49, 52, 183, 77, 49, 52, 182, 77, 49, + 52, 181, 77, 49, 52, 180, 77, 49, 52, 179, 77, 49, 52, 178, 77, 49, 52, + 177, 77, 49, 52, 176, 77, 49, 51, 185, 77, 49, 51, 184, 77, 49, 51, 183, + 77, 49, 51, 182, 77, 49, 51, 181, 77, 49, 51, 180, 77, 49, 51, 179, 77, + 49, 51, 178, 77, 49, 51, 177, 77, 49, 51, 176, 77, 49, 50, 185, 77, 49, + 50, 184, 77, 49, 50, 183, 77, 49, 50, 182, 77, 49, 50, 181, 77, 49, 50, + 180, 77, 49, 50, 179, 77, 49, 50, 178, 77, 49, 50, 177, 77, 49, 50, 176, + 77, 49, 49, 185, 77, 49, 49, 184, 77, 49, 49, 183, 77, 49, 49, 182, 77, + 49, 49, 181, 77, 49, 49, 180, 77, 49, 49, 179, 77, 49, 49, 178, 77, 49, + 49, 177, 77, 49, 49, 176, 77, 49, 48, 185, 77, 49, 48, 184, 77, 49, 48, + 183, 77, 49, 48, 182, 77, 49, 48, 181, 77, 49, 48, 180, 77, 49, 48, 179, + 77, 49, 48, 178, 77, 49, 48, 177, 77, 49, 48, 176, 77, 48, 57, 185, 77, + 48, 57, 184, 77, 48, 57, 183, 77, 48, 57, 182, 77, 48, 57, 181, 77, 48, + 57, 180, 77, 48, 57, 179, 77, 48, 57, 178, 77, 48, 57, 177, 77, 48, 57, + 176, 77, 48, 56, 185, 77, 48, 56, 184, 77, 48, 56, 183, 77, 48, 56, 182, + 77, 48, 56, 181, 77, 48, 56, 180, 77, 48, 56, 179, 77, 48, 56, 178, 77, + 48, 56, 177, 77, 48, 56, 176, 77, 48, 55, 185, 77, 48, 55, 184, 77, 48, + 55, 183, 77, 48, 55, 182, 77, 48, 55, 181, 77, 48, 55, 180, 77, 48, 55, + 179, 77, 48, 55, 178, 77, 48, 55, 177, 77, 48, 55, 176, 77, 48, 54, 185, + 77, 48, 54, 184, 77, 48, 54, 183, 77, 48, 54, 182, 77, 48, 54, 181, 77, + 48, 54, 180, 77, 48, 54, 179, 77, 48, 54, 178, 77, 48, 54, 177, 77, 48, + 54, 176, 77, 48, 53, 185, 77, 48, 53, 184, 77, 48, 53, 183, 77, 48, 53, + 182, 77, 48, 53, 181, 77, 48, 53, 180, 77, 48, 53, 179, 77, 48, 53, 178, + 77, 48, 53, 177, 77, 48, 53, 176, 77, 48, 52, 185, 77, 48, 52, 184, 77, + 48, 52, 183, 77, 48, 52, 182, 77, 48, 52, 181, 77, 48, 52, 52, 128, 77, + 48, 52, 180, 77, 48, 52, 51, 128, 77, 48, 52, 179, 77, 48, 52, 50, 128, + 77, 48, 52, 178, 77, 48, 52, 49, 128, 77, 48, 52, 177, 77, 48, 52, 48, + 65, 128, 77, 48, 52, 48, 128, 77, 48, 52, 176, 77, 48, 51, 57, 128, 77, + 48, 51, 185, 77, 48, 51, 56, 128, 77, 48, 51, 184, 77, 48, 51, 55, 128, + 77, 48, 51, 183, 77, 48, 51, 54, 128, 77, 48, 51, 182, 77, 48, 51, 53, + 128, 77, 48, 51, 181, 77, 48, 51, 52, 128, 77, 48, 51, 180, 77, 48, 51, + 51, 66, 128, 77, 48, 51, 51, 65, 128, 77, 48, 51, 51, 128, 77, 48, 51, + 179, 77, 48, 51, 50, 128, 77, 48, 51, 178, 77, 48, 51, 49, 65, 128, 77, + 48, 51, 49, 128, 77, 48, 51, 177, 77, 48, 51, 48, 128, 77, 48, 51, 176, + 77, 48, 50, 57, 128, 77, 48, 50, 185, 77, 48, 50, 56, 65, 128, 77, 48, + 50, 56, 128, 77, 48, 50, 184, 77, 48, 50, 55, 128, 77, 48, 50, 183, 77, + 48, 50, 54, 128, 77, 48, 50, 182, 77, 48, 50, 53, 128, 77, 48, 50, 181, + 77, 48, 50, 52, 65, 128, 77, 48, 50, 52, 128, 77, 48, 50, 180, 77, 48, + 50, 51, 128, 77, 48, 50, 179, 77, 48, 50, 50, 65, 128, 77, 48, 50, 50, + 128, 77, 48, 50, 178, 77, 48, 50, 49, 128, 77, 48, 50, 177, 77, 48, 50, + 48, 128, 77, 48, 50, 176, 77, 48, 49, 57, 128, 77, 48, 49, 185, 77, 48, + 49, 56, 128, 77, 48, 49, 184, 77, 48, 49, 55, 65, 128, 77, 48, 49, 55, + 128, 77, 48, 49, 183, 77, 48, 49, 54, 65, 128, 77, 48, 49, 54, 128, 77, + 48, 49, 182, 77, 48, 49, 53, 65, 128, 77, 48, 49, 53, 128, 77, 48, 49, + 181, 77, 48, 49, 52, 128, 77, 48, 49, 180, 77, 48, 49, 51, 128, 77, 48, + 49, 179, 77, 48, 49, 50, 72, 128, 77, 48, 49, 50, 71, 128, 77, 48, 49, + 50, 70, 128, 77, 48, 49, 50, 69, 128, 77, 48, 49, 50, 68, 128, 77, 48, + 49, 50, 67, 128, 77, 48, 49, 50, 66, 128, 77, 48, 49, 50, 65, 128, 77, + 48, 49, 50, 128, 77, 48, 49, 178, 77, 48, 49, 49, 128, 77, 48, 49, 177, + 77, 48, 49, 48, 65, 128, 77, 48, 49, 48, 128, 77, 48, 49, 176, 77, 48, + 48, 57, 128, 77, 48, 48, 185, 77, 48, 48, 56, 128, 77, 48, 48, 184, 77, + 48, 48, 55, 128, 77, 48, 48, 183, 77, 48, 48, 54, 128, 77, 48, 48, 182, + 77, 48, 48, 53, 128, 77, 48, 48, 181, 77, 48, 48, 52, 128, 77, 48, 48, + 180, 77, 48, 48, 51, 65, 128, 77, 48, 48, 51, 128, 77, 48, 48, 179, 77, + 48, 48, 50, 128, 77, 48, 48, 178, 77, 48, 48, 49, 66, 128, 77, 48, 48, + 49, 65, 128, 77, 48, 48, 49, 128, 77, 48, 48, 177, 76, 218, 76, 89, 89, + 128, 76, 89, 88, 128, 76, 89, 84, 128, 76, 89, 82, 88, 128, 76, 89, 82, + 128, 76, 89, 80, 128, 76, 89, 73, 84, 128, 76, 89, 73, 78, 199, 76, 89, + 68, 73, 65, 206, 76, 89, 67, 73, 65, 206, 76, 88, 128, 76, 87, 79, 79, + 128, 76, 87, 79, 128, 76, 87, 73, 73, 128, 76, 87, 73, 128, 76, 87, 69, + 128, 76, 87, 65, 65, 128, 76, 87, 65, 128, 76, 85, 88, 128, 76, 85, 85, + 128, 76, 85, 84, 128, 76, 85, 82, 88, 128, 76, 85, 80, 128, 76, 85, 79, + 88, 128, 76, 85, 79, 84, 128, 76, 85, 79, 80, 128, 76, 85, 79, 128, 76, + 85, 78, 71, 83, 73, 128, 76, 85, 78, 71, 83, 128, 76, 85, 78, 65, 84, + 197, 76, 85, 78, 65, 210, 76, 85, 205, 76, 85, 76, 128, 76, 85, 73, 83, + 128, 76, 85, 72, 85, 82, 128, 76, 85, 72, 128, 76, 85, 200, 76, 85, 71, + 71, 65, 71, 69, 128, 76, 85, 71, 65, 76, 128, 76, 85, 71, 65, 204, 76, + 85, 69, 128, 76, 85, 197, 76, 85, 66, 128, 76, 85, 65, 69, 80, 128, 76, + 85, 51, 128, 76, 85, 50, 128, 76, 85, 178, 76, 82, 79, 128, 76, 82, 77, + 128, 76, 82, 73, 128, 76, 82, 69, 128, 76, 79, 90, 69, 78, 71, 69, 128, + 76, 79, 90, 69, 78, 71, 197, 76, 79, 88, 128, 76, 79, 87, 69, 82, 69, + 196, 76, 79, 87, 45, 82, 69, 86, 69, 82, 83, 69, 68, 45, 185, 76, 79, 87, + 45, 77, 73, 196, 76, 79, 87, 45, 70, 65, 76, 76, 73, 78, 199, 76, 79, 87, + 45, 185, 76, 79, 86, 197, 76, 79, 85, 82, 69, 128, 76, 79, 85, 68, 83, + 80, 69, 65, 75, 69, 82, 128, 76, 79, 85, 68, 76, 217, 76, 79, 84, 85, 83, + 128, 76, 79, 84, 85, 211, 76, 79, 84, 73, 79, 206, 76, 79, 84, 128, 76, + 79, 83, 212, 76, 79, 83, 83, 76, 69, 83, 83, 128, 76, 79, 82, 82, 89, + 128, 76, 79, 82, 82, 65, 73, 78, 69, 128, 76, 79, 81, 128, 76, 79, 80, + 128, 76, 79, 79, 84, 128, 76, 79, 79, 80, 69, 196, 76, 79, 79, 80, 128, + 76, 79, 79, 208, 76, 79, 79, 78, 128, 76, 79, 79, 203, 76, 79, 79, 128, + 76, 79, 78, 83, 85, 77, 128, 76, 79, 78, 71, 65, 128, 76, 79, 78, 71, + 193, 76, 79, 78, 71, 45, 76, 69, 71, 71, 69, 196, 76, 79, 78, 71, 45, 66, + 82, 65, 78, 67, 72, 45, 89, 82, 128, 76, 79, 78, 71, 45, 66, 82, 65, 78, + 67, 72, 45, 83, 79, 204, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, + 79, 83, 211, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 77, 65, 68, + 210, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 72, 65, 71, 65, 76, + 204, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 65, 210, 76, 79, 77, + 77, 65, 69, 128, 76, 79, 77, 75, 65, 128, 76, 79, 77, 128, 76, 79, 205, + 76, 79, 76, 76, 73, 80, 79, 80, 128, 76, 79, 76, 76, 128, 76, 79, 71, + 210, 76, 79, 71, 79, 84, 89, 80, 197, 76, 79, 71, 79, 71, 82, 65, 205, + 76, 79, 71, 128, 76, 79, 68, 69, 83, 84, 79, 78, 69, 128, 76, 79, 67, 79, + 77, 79, 84, 73, 86, 69, 128, 76, 79, 67, 75, 73, 78, 71, 45, 83, 72, 73, + 70, 212, 76, 79, 67, 65, 84, 73, 86, 69, 128, 76, 79, 67, 65, 84, 73, 79, + 78, 45, 87, 65, 76, 76, 80, 76, 65, 78, 197, 76, 79, 67, 65, 84, 73, 79, + 78, 45, 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, 76, 79, 67, 65, 84, 73, + 79, 78, 128, 76, 79, 67, 65, 84, 73, 79, 206, 76, 79, 66, 83, 84, 69, 82, + 128, 76, 79, 65, 128, 76, 78, 128, 76, 76, 85, 85, 128, 76, 76, 79, 79, + 128, 76, 76, 76, 85, 85, 128, 76, 76, 76, 85, 128, 76, 76, 76, 79, 79, + 128, 76, 76, 76, 79, 128, 76, 76, 76, 73, 73, 128, 76, 76, 76, 73, 128, + 76, 76, 76, 69, 69, 128, 76, 76, 76, 69, 128, 76, 76, 76, 65, 85, 128, + 76, 76, 76, 65, 73, 128, 76, 76, 76, 65, 65, 128, 76, 76, 76, 65, 128, + 76, 76, 76, 128, 76, 76, 72, 65, 128, 76, 76, 65, 77, 65, 128, 76, 74, + 85, 68, 73, 74, 69, 128, 76, 74, 69, 128, 76, 74, 128, 76, 73, 90, 65, + 82, 68, 128, 76, 73, 88, 128, 76, 73, 87, 78, 128, 76, 73, 86, 82, 197, + 76, 73, 84, 84, 76, 69, 128, 76, 73, 84, 84, 76, 197, 76, 73, 84, 84, 69, + 210, 76, 73, 84, 82, 193, 76, 73, 84, 200, 76, 73, 83, 213, 76, 73, 83, + 128, 76, 73, 82, 193, 76, 73, 81, 85, 73, 68, 128, 76, 73, 81, 85, 73, + 196, 76, 73, 81, 128, 76, 73, 80, 83, 84, 73, 67, 75, 128, 76, 73, 80, + 211, 76, 73, 208, 76, 73, 78, 75, 73, 78, 199, 76, 73, 78, 75, 69, 196, + 76, 73, 78, 203, 76, 73, 78, 71, 83, 65, 128, 76, 73, 78, 69, 83, 128, + 76, 73, 78, 69, 211, 76, 73, 78, 69, 45, 57, 128, 76, 73, 78, 69, 45, 55, + 128, 76, 73, 78, 69, 45, 51, 128, 76, 73, 78, 69, 45, 49, 128, 76, 73, + 77, 77, 85, 52, 128, 76, 73, 77, 77, 85, 50, 128, 76, 73, 77, 77, 85, + 128, 76, 73, 77, 77, 213, 76, 73, 77, 73, 84, 69, 196, 76, 73, 77, 73, + 84, 65, 84, 73, 79, 78, 128, 76, 73, 77, 73, 84, 128, 76, 73, 77, 69, + 128, 76, 73, 77, 66, 213, 76, 73, 77, 66, 211, 76, 73, 77, 194, 76, 73, + 76, 89, 128, 76, 73, 76, 73, 84, 72, 128, 76, 73, 76, 128, 76, 73, 71, + 72, 84, 78, 73, 78, 71, 128, 76, 73, 71, 72, 84, 78, 73, 78, 199, 76, 73, + 71, 72, 84, 72, 79, 85, 83, 69, 128, 76, 73, 71, 72, 84, 128, 76, 73, 71, + 65, 84, 73, 78, 199, 76, 73, 70, 84, 69, 82, 128, 76, 73, 70, 69, 128, + 76, 73, 69, 88, 128, 76, 73, 69, 84, 128, 76, 73, 69, 80, 128, 76, 73, + 69, 69, 128, 76, 73, 69, 128, 76, 73, 68, 128, 76, 73, 67, 75, 73, 78, + 199, 76, 73, 66, 82, 65, 128, 76, 73, 66, 69, 82, 84, 89, 128, 76, 73, + 65, 66, 73, 76, 73, 84, 217, 76, 72, 73, 73, 128, 76, 72, 65, 86, 73, 89, + 65, 78, 73, 128, 76, 72, 65, 199, 76, 72, 65, 65, 128, 76, 72, 128, 76, + 69, 90, 72, 128, 76, 69, 90, 200, 76, 69, 88, 128, 76, 69, 86, 73, 84, + 65, 84, 73, 78, 71, 128, 76, 69, 86, 69, 76, 45, 51, 128, 76, 69, 86, 69, + 76, 45, 50, 128, 76, 69, 85, 77, 128, 76, 69, 85, 65, 69, 80, 128, 76, + 69, 85, 65, 69, 77, 128, 76, 69, 85, 128, 76, 69, 213, 76, 69, 84, 84, + 69, 82, 83, 128, 76, 69, 84, 84, 69, 82, 128, 76, 69, 212, 76, 69, 83, + 83, 69, 210, 76, 69, 83, 83, 45, 84, 72, 65, 78, 128, 76, 69, 83, 83, 45, + 84, 72, 65, 206, 76, 69, 83, 72, 128, 76, 69, 80, 67, 72, 193, 76, 69, + 80, 128, 76, 69, 79, 80, 65, 82, 68, 128, 76, 69, 79, 128, 76, 69, 78, + 84, 73, 67, 85, 76, 65, 210, 76, 69, 78, 73, 83, 128, 76, 69, 78, 73, + 211, 76, 69, 78, 71, 84, 72, 69, 78, 69, 82, 128, 76, 69, 78, 71, 84, 72, + 45, 55, 128, 76, 69, 78, 71, 84, 72, 45, 54, 128, 76, 69, 78, 71, 84, 72, + 45, 53, 128, 76, 69, 78, 71, 84, 72, 45, 52, 128, 76, 69, 78, 71, 84, 72, + 45, 51, 128, 76, 69, 78, 71, 84, 72, 45, 50, 128, 76, 69, 78, 71, 84, 72, + 45, 49, 128, 76, 69, 78, 71, 84, 200, 76, 69, 78, 71, 65, 128, 76, 69, + 78, 71, 193, 76, 69, 77, 79, 78, 128, 76, 69, 77, 79, 73, 128, 76, 69, + 76, 69, 84, 128, 76, 69, 76, 69, 212, 76, 69, 203, 76, 69, 73, 77, 77, + 65, 128, 76, 69, 73, 77, 77, 193, 76, 69, 73, 128, 76, 69, 71, 83, 128, + 76, 69, 71, 73, 79, 78, 128, 76, 69, 71, 69, 84, 79, 211, 76, 69, 71, + 128, 76, 69, 199, 76, 69, 70, 84, 87, 65, 82, 68, 83, 128, 76, 69, 70, + 84, 45, 84, 79, 45, 82, 73, 71, 72, 212, 76, 69, 70, 84, 45, 83, 84, 69, + 205, 76, 69, 70, 84, 45, 83, 73, 68, 197, 76, 69, 70, 84, 45, 83, 72, 65, + 68, 69, 196, 76, 69, 70, 84, 45, 80, 79, 73, 78, 84, 73, 78, 199, 76, 69, + 70, 84, 45, 76, 73, 71, 72, 84, 69, 196, 76, 69, 70, 84, 45, 72, 65, 78, + 68, 69, 196, 76, 69, 70, 84, 45, 72, 65, 78, 196, 76, 69, 70, 84, 45, 70, + 65, 67, 73, 78, 199, 76, 69, 70, 84, 128, 76, 69, 69, 82, 65, 69, 87, 65, + 128, 76, 69, 69, 75, 128, 76, 69, 69, 69, 69, 128, 76, 69, 68, 71, 69, + 82, 128, 76, 69, 65, 84, 72, 69, 82, 128, 76, 69, 65, 78, 73, 78, 199, + 76, 69, 65, 70, 217, 76, 69, 65, 70, 128, 76, 69, 65, 198, 76, 69, 65, + 68, 69, 82, 128, 76, 69, 65, 196, 76, 68, 65, 78, 128, 76, 68, 50, 128, + 76, 67, 201, 76, 67, 197, 76, 65, 90, 217, 76, 65, 89, 65, 78, 78, 65, + 128, 76, 65, 88, 128, 76, 65, 87, 128, 76, 65, 215, 76, 65, 85, 76, 65, + 128, 76, 65, 85, 75, 65, 218, 76, 65, 85, 74, 128, 76, 65, 85, 71, 72, + 73, 78, 71, 128, 76, 65, 84, 73, 78, 65, 84, 197, 76, 65, 84, 73, 75, + 128, 76, 65, 84, 69, 82, 65, 204, 76, 65, 84, 197, 76, 65, 83, 212, 76, + 65, 82, 89, 78, 71, 69, 65, 204, 76, 65, 82, 201, 76, 65, 82, 71, 69, 83, + 84, 128, 76, 65, 82, 71, 69, 210, 76, 65, 82, 71, 69, 128, 76, 65, 82, + 71, 197, 76, 65, 81, 128, 76, 65, 80, 65, 81, 128, 76, 65, 207, 76, 65, + 78, 84, 69, 82, 78, 128, 76, 65, 78, 84, 65, 78, 71, 128, 76, 65, 78, 71, + 85, 65, 71, 197, 76, 65, 78, 69, 83, 128, 76, 65, 78, 196, 76, 65, 78, + 128, 76, 65, 77, 80, 128, 76, 65, 77, 69, 68, 72, 128, 76, 65, 77, 69, + 68, 128, 76, 65, 77, 69, 196, 76, 65, 77, 69, 128, 76, 65, 77, 197, 76, + 65, 77, 68, 65, 128, 76, 65, 77, 68, 128, 76, 65, 77, 66, 68, 193, 76, + 65, 77, 65, 68, 72, 128, 76, 65, 76, 128, 76, 65, 204, 76, 65, 75, 75, + 72, 65, 78, 71, 89, 65, 79, 128, 76, 65, 75, 72, 65, 78, 128, 76, 65, 75, + 72, 128, 76, 65, 75, 200, 76, 65, 75, 45, 55, 52, 57, 128, 76, 65, 75, + 45, 55, 50, 52, 128, 76, 65, 75, 45, 54, 54, 56, 128, 76, 65, 75, 45, 54, + 52, 56, 128, 76, 65, 75, 45, 54, 52, 184, 76, 65, 75, 45, 54, 51, 54, + 128, 76, 65, 75, 45, 54, 49, 55, 128, 76, 65, 75, 45, 54, 49, 183, 76, + 65, 75, 45, 54, 48, 56, 128, 76, 65, 75, 45, 53, 53, 48, 128, 76, 65, 75, + 45, 52, 57, 53, 128, 76, 65, 75, 45, 52, 57, 51, 128, 76, 65, 75, 45, 52, + 57, 50, 128, 76, 65, 75, 45, 52, 57, 48, 128, 76, 65, 75, 45, 52, 56, 51, + 128, 76, 65, 75, 45, 52, 55, 48, 128, 76, 65, 75, 45, 52, 53, 55, 128, + 76, 65, 75, 45, 52, 53, 48, 128, 76, 65, 75, 45, 52, 52, 57, 128, 76, 65, + 75, 45, 52, 52, 185, 76, 65, 75, 45, 52, 52, 49, 128, 76, 65, 75, 45, 51, + 57, 48, 128, 76, 65, 75, 45, 51, 56, 52, 128, 76, 65, 75, 45, 51, 56, 51, + 128, 76, 65, 75, 45, 51, 52, 56, 128, 76, 65, 75, 45, 51, 52, 55, 128, + 76, 65, 75, 45, 51, 52, 51, 128, 76, 65, 75, 45, 50, 54, 54, 128, 76, 65, + 75, 45, 50, 54, 53, 128, 76, 65, 75, 45, 50, 51, 56, 128, 76, 65, 75, 45, + 50, 50, 56, 128, 76, 65, 75, 45, 50, 50, 53, 128, 76, 65, 75, 45, 50, 50, + 48, 128, 76, 65, 75, 45, 50, 49, 57, 128, 76, 65, 75, 45, 50, 49, 48, + 128, 76, 65, 75, 45, 49, 52, 50, 128, 76, 65, 75, 45, 49, 51, 48, 128, + 76, 65, 75, 45, 48, 57, 50, 128, 76, 65, 75, 45, 48, 56, 49, 128, 76, 65, + 75, 45, 48, 56, 177, 76, 65, 75, 45, 48, 56, 48, 128, 76, 65, 75, 45, 48, + 55, 185, 76, 65, 75, 45, 48, 54, 50, 128, 76, 65, 75, 45, 48, 53, 49, + 128, 76, 65, 75, 45, 48, 53, 48, 128, 76, 65, 75, 45, 48, 51, 48, 128, + 76, 65, 75, 45, 48, 50, 53, 128, 76, 65, 75, 45, 48, 50, 49, 128, 76, 65, + 75, 45, 48, 50, 48, 128, 76, 65, 75, 45, 48, 48, 51, 128, 76, 65, 74, 65, + 78, 89, 65, 76, 65, 78, 128, 76, 65, 73, 78, 199, 76, 65, 201, 76, 65, + 72, 83, 72, 85, 128, 76, 65, 72, 128, 76, 65, 71, 85, 83, 128, 76, 65, + 71, 213, 76, 65, 71, 65, 82, 128, 76, 65, 71, 65, 210, 76, 65, 71, 65, + 66, 128, 76, 65, 71, 65, 194, 76, 65, 69, 86, 128, 76, 65, 69, 128, 76, + 65, 68, 217, 76, 65, 68, 68, 69, 82, 128, 76, 65, 67, 82, 79, 83, 83, + 197, 76, 65, 67, 75, 128, 76, 65, 67, 65, 128, 76, 65, 66, 79, 85, 82, + 73, 78, 71, 128, 76, 65, 66, 79, 82, 128, 76, 65, 66, 73, 65, 76, 73, 90, + 65, 84, 73, 79, 206, 76, 65, 66, 73, 65, 204, 76, 65, 66, 69, 76, 128, + 76, 65, 66, 65, 84, 128, 76, 65, 194, 76, 65, 65, 78, 65, 69, 128, 76, + 65, 65, 78, 128, 76, 65, 65, 77, 85, 128, 76, 65, 65, 73, 128, 76, 54, + 128, 76, 52, 128, 76, 51, 128, 76, 50, 128, 76, 48, 48, 54, 65, 128, 76, + 48, 48, 50, 65, 128, 76, 45, 84, 89, 80, 197, 76, 45, 83, 72, 65, 80, 69, + 196, 75, 89, 85, 82, 73, 73, 128, 75, 89, 85, 128, 75, 89, 79, 128, 75, + 89, 76, 73, 83, 77, 65, 128, 75, 89, 73, 128, 75, 89, 69, 128, 75, 89, + 65, 84, 72, 79, 211, 75, 89, 65, 65, 128, 75, 89, 65, 128, 75, 88, 87, + 73, 128, 75, 88, 87, 69, 69, 128, 75, 88, 87, 69, 128, 75, 88, 87, 65, + 65, 128, 75, 88, 87, 65, 128, 75, 88, 85, 128, 75, 88, 79, 128, 75, 88, + 73, 128, 75, 88, 69, 69, 128, 75, 88, 69, 128, 75, 88, 65, 65, 128, 75, + 88, 65, 128, 75, 87, 86, 128, 75, 87, 85, 51, 49, 56, 128, 75, 87, 79, + 79, 128, 75, 87, 79, 128, 75, 87, 77, 128, 75, 87, 73, 73, 128, 75, 87, + 73, 128, 75, 87, 69, 69, 128, 75, 87, 69, 128, 75, 87, 66, 128, 75, 87, + 65, 89, 128, 75, 87, 65, 69, 84, 128, 75, 87, 65, 65, 128, 75, 86, 65, + 128, 75, 86, 128, 75, 85, 90, 72, 73, 128, 75, 85, 88, 128, 75, 85, 86, + 128, 75, 85, 85, 72, 128, 75, 85, 84, 128, 75, 85, 83, 77, 65, 128, 75, + 85, 83, 72, 85, 50, 128, 75, 85, 83, 72, 85, 178, 75, 85, 82, 88, 128, + 75, 85, 82, 85, 90, 69, 73, 82, 79, 128, 75, 85, 82, 84, 128, 75, 85, 82, + 79, 79, 78, 69, 128, 75, 85, 82, 128, 75, 85, 210, 75, 85, 81, 128, 75, + 85, 80, 78, 65, 89, 65, 128, 75, 85, 79, 88, 128, 75, 85, 79, 80, 128, + 75, 85, 79, 208, 75, 85, 79, 77, 128, 75, 85, 79, 128, 75, 85, 78, 71, + 128, 75, 85, 78, 68, 68, 65, 76, 73, 89, 65, 128, 75, 85, 76, 128, 75, + 85, 204, 75, 85, 71, 128, 75, 85, 70, 73, 83, 77, 65, 128, 75, 85, 69, + 84, 128, 75, 85, 66, 128, 75, 85, 65, 86, 128, 75, 85, 65, 66, 128, 75, + 85, 65, 128, 75, 85, 55, 128, 75, 85, 52, 128, 75, 85, 180, 75, 85, 51, + 128, 75, 85, 179, 75, 85, 45, 55, 128, 75, 85, 45, 54, 128, 75, 85, 45, + 53, 128, 75, 85, 45, 52, 128, 75, 85, 45, 51, 128, 75, 85, 45, 50, 128, + 75, 85, 45, 49, 128, 75, 84, 128, 75, 83, 83, 85, 85, 128, 75, 83, 83, + 85, 128, 75, 83, 83, 79, 79, 128, 75, 83, 83, 79, 128, 75, 83, 83, 73, + 73, 128, 75, 83, 83, 73, 128, 75, 83, 83, 69, 69, 128, 75, 83, 83, 69, + 128, 75, 83, 83, 65, 85, 128, 75, 83, 83, 65, 73, 128, 75, 83, 83, 65, + 65, 128, 75, 83, 83, 65, 128, 75, 83, 83, 128, 75, 83, 73, 128, 75, 82, + 89, 90, 72, 69, 86, 65, 89, 65, 128, 75, 82, 89, 90, 72, 69, 77, 128, 75, + 82, 89, 90, 72, 69, 205, 75, 82, 89, 90, 72, 128, 75, 82, 89, 90, 200, + 75, 82, 89, 85, 75, 79, 86, 65, 89, 65, 128, 75, 82, 89, 85, 75, 79, 86, + 65, 89, 193, 75, 82, 89, 85, 75, 128, 75, 82, 89, 85, 203, 75, 82, 79, + 78, 79, 83, 128, 75, 82, 69, 77, 65, 83, 84, 73, 128, 75, 82, 65, 84, 73, + 77, 79, 89, 80, 79, 82, 82, 79, 79, 78, 128, 75, 82, 65, 84, 73, 77, 79, + 75, 79, 85, 70, 73, 83, 77, 65, 128, 75, 82, 65, 84, 73, 77, 65, 84, 65, + 128, 75, 82, 65, 84, 73, 77, 193, 75, 80, 85, 128, 75, 80, 79, 81, 128, + 75, 80, 79, 79, 128, 75, 80, 79, 128, 75, 80, 73, 128, 75, 80, 69, 85, + 88, 128, 75, 80, 69, 69, 128, 75, 80, 69, 128, 75, 80, 65, 82, 65, 81, + 128, 75, 80, 65, 78, 128, 75, 80, 65, 72, 128, 75, 80, 65, 128, 75, 80, + 128, 75, 79, 88, 128, 75, 79, 86, 85, 85, 128, 75, 79, 86, 128, 75, 79, + 84, 79, 128, 75, 79, 82, 85, 78, 65, 128, 75, 79, 82, 79, 78, 73, 83, + 128, 75, 79, 82, 79, 78, 128, 75, 79, 82, 69, 65, 206, 75, 79, 82, 65, + 78, 73, 195, 75, 79, 81, 78, 68, 79, 78, 128, 75, 79, 80, 80, 65, 128, + 75, 79, 80, 128, 75, 79, 79, 86, 128, 75, 79, 79, 80, 79, 128, 75, 79, + 79, 77, 85, 85, 84, 128, 75, 79, 79, 66, 128, 75, 79, 79, 128, 75, 79, + 78, 84, 69, 86, 77, 65, 128, 75, 79, 78, 84, 69, 86, 77, 193, 75, 79, 77, + 201, 75, 79, 77, 66, 85, 86, 65, 128, 75, 79, 77, 66, 85, 86, 193, 75, + 79, 77, 66, 213, 75, 79, 75, 79, 128, 75, 79, 75, 69, 128, 75, 79, 75, + 128, 75, 79, 203, 75, 79, 73, 78, 73, 128, 75, 79, 73, 128, 75, 79, 201, + 75, 79, 72, 128, 75, 79, 71, 72, 79, 77, 128, 75, 79, 69, 84, 128, 75, + 79, 66, 89, 76, 65, 128, 75, 79, 66, 128, 75, 79, 65, 76, 65, 128, 75, + 79, 65, 128, 75, 79, 45, 75, 73, 128, 75, 79, 45, 51, 128, 75, 79, 45, + 50, 128, 75, 79, 45, 49, 128, 75, 78, 85, 67, 75, 76, 69, 83, 128, 75, + 78, 85, 67, 75, 76, 69, 128, 75, 78, 79, 84, 128, 75, 78, 79, 66, 83, + 128, 75, 78, 73, 71, 72, 84, 45, 82, 79, 79, 75, 128, 75, 78, 73, 71, 72, + 84, 45, 81, 85, 69, 69, 78, 128, 75, 78, 73, 71, 72, 84, 45, 66, 73, 83, + 72, 79, 80, 128, 75, 78, 73, 71, 72, 84, 128, 75, 78, 73, 71, 72, 212, + 75, 78, 73, 70, 69, 128, 75, 78, 73, 70, 197, 75, 78, 69, 69, 76, 73, 78, + 199, 75, 77, 128, 75, 205, 75, 76, 89, 85, 67, 72, 69, 86, 79, 89, 128, + 75, 76, 89, 85, 67, 72, 69, 86, 65, 89, 65, 128, 75, 76, 89, 85, 67, 72, + 69, 86, 65, 89, 193, 75, 76, 89, 85, 67, 72, 69, 80, 79, 86, 79, 68, 78, + 89, 128, 75, 76, 89, 85, 67, 72, 69, 80, 79, 86, 79, 68, 78, 65, 89, 65, + 128, 75, 76, 89, 85, 67, 72, 69, 78, 69, 80, 79, 83, 84, 79, 89, 65, 78, + 78, 89, 128, 75, 76, 89, 85, 67, 72, 69, 78, 69, 80, 79, 83, 84, 79, 89, + 65, 78, 78, 65, 89, 65, 128, 75, 76, 89, 85, 67, 72, 128, 75, 76, 73, 84, + 79, 78, 128, 75, 76, 65, 83, 77, 65, 128, 75, 76, 65, 83, 77, 193, 75, + 76, 65, 128, 75, 76, 128, 75, 75, 79, 128, 75, 75, 73, 128, 75, 75, 69, + 69, 128, 75, 75, 69, 128, 75, 75, 65, 128, 75, 75, 128, 75, 74, 69, 128, + 75, 73, 89, 69, 79, 75, 45, 84, 73, 75, 69, 85, 84, 128, 75, 73, 89, 69, + 79, 75, 45, 83, 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 75, 73, 89, + 69, 79, 75, 45, 82, 73, 69, 85, 76, 128, 75, 73, 89, 69, 79, 75, 45, 80, + 73, 69, 85, 80, 128, 75, 73, 89, 69, 79, 75, 45, 78, 73, 69, 85, 78, 128, + 75, 73, 89, 69, 79, 75, 45, 75, 72, 73, 69, 85, 75, 72, 128, 75, 73, 89, + 69, 79, 75, 45, 67, 72, 73, 69, 85, 67, 72, 128, 75, 73, 89, 69, 79, 203, + 75, 73, 88, 128, 75, 73, 87, 73, 70, 82, 85, 73, 84, 128, 75, 73, 87, + 128, 75, 73, 86, 128, 75, 73, 84, 69, 128, 75, 73, 84, 128, 75, 73, 83, + 83, 73, 78, 199, 75, 73, 83, 83, 128, 75, 73, 83, 211, 75, 73, 83, 73, + 77, 53, 128, 75, 73, 83, 73, 77, 181, 75, 73, 83, 72, 128, 75, 73, 83, + 65, 76, 128, 75, 73, 82, 79, 87, 65, 84, 84, 79, 128, 75, 73, 82, 79, 77, + 69, 69, 84, 79, 82, 85, 128, 75, 73, 82, 79, 71, 85, 82, 65, 77, 85, 128, + 75, 73, 82, 79, 128, 75, 73, 82, 71, 72, 73, 218, 75, 73, 81, 128, 75, + 73, 80, 128, 75, 73, 208, 75, 73, 78, 83, 72, 73, 80, 128, 75, 73, 78, + 78, 193, 75, 73, 78, 68, 69, 82, 71, 65, 82, 84, 69, 78, 128, 75, 73, 77, + 79, 78, 79, 128, 75, 73, 76, 76, 69, 82, 128, 75, 73, 73, 90, 72, 128, + 75, 73, 73, 128, 75, 73, 72, 128, 75, 73, 69, 88, 128, 75, 73, 69, 86, + 65, 206, 75, 73, 69, 80, 128, 75, 73, 69, 69, 77, 128, 75, 73, 69, 128, + 75, 73, 68, 128, 75, 73, 196, 75, 73, 67, 75, 128, 75, 73, 66, 128, 75, + 73, 65, 86, 128, 75, 73, 65, 66, 128, 75, 73, 45, 56, 128, 75, 73, 45, + 55, 128, 75, 73, 45, 54, 128, 75, 73, 45, 53, 128, 75, 73, 45, 52, 128, + 75, 73, 45, 51, 128, 75, 73, 45, 50, 128, 75, 73, 45, 49, 128, 75, 72, + 90, 128, 75, 72, 87, 65, 73, 128, 75, 72, 85, 69, 78, 45, 76, 85, 197, + 75, 72, 85, 69, 206, 75, 72, 85, 68, 65, 87, 65, 68, 201, 75, 72, 85, 68, + 65, 77, 128, 75, 72, 85, 65, 84, 128, 75, 72, 79, 85, 128, 75, 72, 79, + 212, 75, 72, 79, 78, 78, 65, 128, 75, 72, 79, 78, 128, 75, 72, 79, 77, + 85, 84, 128, 75, 72, 79, 75, 72, 76, 79, 205, 75, 72, 79, 74, 75, 201, + 75, 72, 79, 128, 75, 72, 207, 75, 72, 77, 213, 75, 72, 73, 84, 128, 75, + 72, 73, 78, 89, 65, 128, 75, 72, 73, 69, 85, 75, 200, 75, 72, 73, 128, + 75, 72, 201, 75, 72, 72, 79, 128, 75, 72, 72, 65, 128, 75, 72, 69, 84, + 72, 128, 75, 72, 69, 73, 128, 75, 72, 69, 69, 128, 75, 72, 69, 128, 75, + 72, 65, 86, 128, 75, 72, 65, 82, 79, 83, 72, 84, 72, 201, 75, 72, 65, 82, + 128, 75, 72, 65, 80, 72, 128, 75, 72, 65, 78, 199, 75, 72, 65, 78, 68, + 65, 128, 75, 72, 65, 78, 68, 193, 75, 72, 65, 77, 84, 201, 75, 72, 65, + 77, 73, 76, 79, 128, 75, 72, 65, 75, 65, 83, 83, 73, 65, 206, 75, 72, 65, + 73, 128, 75, 72, 65, 72, 128, 75, 72, 65, 200, 75, 72, 65, 70, 128, 75, + 72, 65, 66, 128, 75, 72, 65, 65, 128, 75, 71, 128, 75, 69, 89, 67, 65, + 80, 128, 75, 69, 89, 67, 65, 208, 75, 69, 89, 66, 79, 65, 82, 68, 128, + 75, 69, 89, 66, 79, 65, 82, 196, 75, 69, 88, 128, 75, 69, 86, 128, 75, + 69, 85, 89, 69, 85, 88, 128, 75, 69, 85, 83, 72, 69, 85, 65, 69, 80, 128, + 75, 69, 85, 83, 69, 85, 88, 128, 75, 69, 85, 80, 85, 81, 128, 75, 69, 85, + 79, 212, 75, 69, 85, 77, 128, 75, 69, 85, 75, 69, 85, 84, 78, 68, 65, + 128, 75, 69, 85, 75, 65, 81, 128, 75, 69, 85, 65, 69, 84, 77, 69, 85, 78, + 128, 75, 69, 85, 65, 69, 82, 73, 128, 75, 69, 84, 84, 201, 75, 69, 83, + 72, 50, 128, 75, 69, 82, 69, 84, 128, 75, 69, 79, 87, 128, 75, 69, 78, + 84, 73, 77, 65, 84, 65, 128, 75, 69, 78, 84, 73, 77, 65, 84, 193, 75, 69, + 78, 84, 73, 77, 193, 75, 69, 78, 65, 84, 128, 75, 69, 78, 128, 75, 69, + 206, 75, 69, 77, 80, 85, 76, 128, 75, 69, 77, 80, 85, 204, 75, 69, 77, + 80, 76, 73, 128, 75, 69, 77, 80, 76, 201, 75, 69, 77, 80, 72, 82, 69, 78, + 71, 128, 75, 69, 77, 66, 65, 78, 71, 128, 75, 69, 76, 86, 73, 206, 75, + 69, 72, 69, 72, 128, 75, 69, 72, 69, 200, 75, 69, 72, 128, 75, 69, 70, + 85, 76, 65, 128, 75, 69, 69, 86, 128, 75, 69, 69, 83, 85, 128, 75, 69, + 69, 80, 73, 78, 199, 75, 69, 69, 78, 71, 128, 75, 69, 69, 66, 128, 75, + 69, 66, 128, 75, 69, 65, 65, 69, 128, 75, 67, 65, 76, 128, 75, 66, 128, + 75, 65, 90, 65, 75, 200, 75, 65, 89, 65, 78, 78, 65, 128, 75, 65, 89, 65, + 200, 75, 65, 88, 128, 75, 65, 87, 86, 128, 75, 65, 87, 73, 128, 75, 65, + 87, 201, 75, 65, 87, 66, 128, 75, 65, 86, 89, 75, 65, 128, 75, 65, 86, + 89, 75, 193, 75, 65, 86, 128, 75, 65, 85, 86, 128, 75, 65, 85, 78, 65, + 128, 75, 65, 85, 206, 75, 65, 85, 66, 128, 75, 65, 84, 79, 128, 75, 65, + 84, 72, 73, 83, 84, 73, 128, 75, 65, 84, 72, 65, 75, 193, 75, 65, 84, 65, + 86, 65, 83, 77, 65, 128, 75, 65, 84, 65, 86, 193, 75, 65, 84, 65, 75, 65, + 78, 65, 45, 72, 73, 82, 65, 71, 65, 78, 193, 75, 65, 83, 82, 65, 84, 65, + 78, 128, 75, 65, 83, 82, 65, 84, 65, 206, 75, 65, 83, 82, 65, 128, 75, + 65, 83, 82, 193, 75, 65, 83, 75, 65, 76, 128, 75, 65, 83, 75, 65, 204, + 75, 65, 83, 72, 77, 73, 82, 201, 75, 65, 82, 83, 72, 65, 78, 65, 128, 75, + 65, 82, 79, 82, 73, 73, 128, 75, 65, 82, 79, 82, 65, 78, 128, 75, 65, 82, + 79, 82, 128, 75, 65, 82, 207, 75, 65, 82, 69, 206, 75, 65, 82, 65, 84, + 84, 79, 128, 75, 65, 82, 65, 78, 128, 75, 65, 80, 89, 69, 79, 85, 78, 83, + 83, 65, 78, 71, 80, 73, 69, 85, 80, 128, 75, 65, 80, 89, 69, 79, 85, 78, + 82, 73, 69, 85, 76, 128, 75, 65, 80, 89, 69, 79, 85, 78, 80, 72, 73, 69, + 85, 80, 72, 128, 75, 65, 80, 89, 69, 79, 85, 78, 77, 73, 69, 85, 77, 128, + 75, 65, 80, 80, 65, 128, 75, 65, 80, 80, 193, 75, 65, 80, 79, 128, 75, + 65, 80, 72, 128, 75, 65, 80, 65, 76, 128, 75, 65, 80, 65, 128, 75, 65, + 208, 75, 65, 78, 84, 65, 74, 193, 75, 65, 78, 78, 65, 68, 193, 75, 65, + 78, 71, 65, 82, 79, 79, 128, 75, 65, 78, 71, 128, 75, 65, 78, 199, 75, + 65, 78, 65, 75, 79, 128, 75, 65, 77, 52, 128, 75, 65, 77, 50, 128, 75, + 65, 77, 128, 75, 65, 75, 84, 79, 86, 73, 203, 75, 65, 75, 79, 128, 75, + 65, 75, 65, 66, 65, 84, 128, 75, 65, 75, 128, 75, 65, 203, 75, 65, 73, + 86, 128, 75, 65, 73, 84, 72, 201, 75, 65, 73, 82, 73, 128, 75, 65, 73, + 66, 128, 75, 65, 73, 128, 75, 65, 201, 75, 65, 70, 65, 128, 75, 65, 70, + 128, 75, 65, 198, 75, 65, 68, 53, 128, 75, 65, 68, 181, 75, 65, 68, 52, + 128, 75, 65, 68, 51, 128, 75, 65, 68, 179, 75, 65, 68, 50, 128, 75, 65, + 68, 128, 75, 65, 67, 72, 75, 65, 128, 75, 65, 66, 193, 75, 65, 66, 128, + 75, 65, 65, 86, 128, 75, 65, 65, 73, 128, 75, 65, 65, 70, 85, 128, 75, + 65, 65, 70, 128, 75, 65, 65, 67, 85, 128, 75, 65, 65, 66, 65, 128, 75, + 65, 65, 66, 128, 75, 65, 50, 128, 75, 65, 178, 75, 65, 45, 75, 69, 128, + 75, 65, 45, 57, 128, 75, 65, 45, 56, 128, 75, 65, 45, 55, 128, 75, 65, + 45, 54, 128, 75, 65, 45, 53, 128, 75, 65, 45, 52, 128, 75, 65, 45, 51, + 128, 75, 65, 45, 50, 128, 75, 65, 45, 49, 49, 128, 75, 65, 45, 49, 48, + 128, 75, 65, 45, 49, 128, 75, 48, 48, 56, 128, 75, 48, 48, 55, 128, 75, + 48, 48, 54, 128, 75, 48, 48, 53, 128, 75, 48, 48, 52, 128, 75, 48, 48, + 51, 128, 75, 48, 48, 50, 128, 75, 48, 48, 49, 128, 74, 87, 65, 128, 74, + 85, 85, 128, 74, 85, 84, 128, 74, 85, 83, 84, 73, 70, 73, 67, 65, 84, 73, + 79, 78, 128, 74, 85, 80, 73, 84, 69, 82, 128, 74, 85, 79, 84, 128, 74, + 85, 79, 80, 128, 74, 85, 78, 79, 128, 74, 85, 78, 71, 83, 69, 79, 78, + 199, 74, 85, 78, 69, 128, 74, 85, 76, 89, 128, 74, 85, 71, 71, 76, 73, + 78, 71, 128, 74, 85, 69, 85, 73, 128, 74, 85, 68, 85, 76, 128, 74, 85, + 68, 71, 69, 128, 74, 85, 68, 69, 79, 45, 83, 80, 65, 78, 73, 83, 200, 74, + 79, 89, 83, 84, 73, 67, 75, 128, 74, 79, 89, 79, 85, 211, 74, 79, 89, + 128, 74, 79, 86, 69, 128, 74, 79, 212, 74, 79, 78, 71, 128, 74, 79, 78, + 193, 74, 79, 75, 69, 82, 128, 74, 79, 73, 78, 84, 83, 128, 74, 79, 73, + 78, 69, 68, 128, 74, 79, 73, 78, 128, 74, 79, 65, 128, 74, 78, 89, 65, + 128, 74, 74, 89, 88, 128, 74, 74, 89, 84, 128, 74, 74, 89, 80, 128, 74, + 74, 89, 128, 74, 74, 85, 88, 128, 74, 74, 85, 84, 128, 74, 74, 85, 82, + 88, 128, 74, 74, 85, 82, 128, 74, 74, 85, 80, 128, 74, 74, 85, 79, 88, + 128, 74, 74, 85, 79, 80, 128, 74, 74, 85, 79, 128, 74, 74, 85, 128, 74, + 74, 79, 88, 128, 74, 74, 79, 84, 128, 74, 74, 79, 80, 128, 74, 74, 79, + 128, 74, 74, 73, 88, 128, 74, 74, 73, 84, 128, 74, 74, 73, 80, 128, 74, + 74, 73, 69, 88, 128, 74, 74, 73, 69, 84, 128, 74, 74, 73, 69, 80, 128, + 74, 74, 73, 69, 128, 74, 74, 73, 128, 74, 74, 69, 69, 128, 74, 74, 69, + 128, 74, 74, 65, 128, 74, 73, 76, 128, 74, 73, 73, 77, 128, 74, 73, 73, + 128, 74, 73, 72, 86, 65, 77, 85, 76, 73, 89, 65, 128, 74, 73, 71, 83, 65, + 215, 74, 73, 65, 128, 74, 72, 79, 88, 128, 74, 72, 79, 128, 74, 72, 69, + 72, 128, 74, 72, 65, 89, 73, 78, 128, 74, 72, 65, 78, 128, 74, 72, 65, + 77, 128, 74, 72, 65, 65, 128, 74, 72, 65, 128, 74, 69, 85, 128, 74, 69, + 82, 85, 83, 65, 76, 69, 77, 128, 74, 69, 82, 65, 206, 74, 69, 82, 65, + 128, 74, 69, 82, 128, 74, 69, 76, 76, 89, 70, 73, 83, 72, 128, 74, 69, + 72, 128, 74, 69, 200, 74, 69, 71, 79, 71, 65, 78, 128, 74, 69, 69, 77, + 128, 74, 69, 69, 205, 74, 69, 65, 78, 83, 128, 74, 65, 89, 78, 128, 74, + 65, 89, 73, 78, 128, 74, 65, 89, 65, 78, 78, 65, 128, 74, 65, 87, 128, + 74, 65, 86, 73, 89, 65, 78, 73, 128, 74, 65, 86, 65, 78, 69, 83, 197, 74, + 65, 85, 128, 74, 65, 82, 128, 74, 65, 80, 65, 78, 69, 83, 197, 74, 65, + 80, 65, 78, 128, 74, 65, 78, 85, 65, 82, 89, 128, 74, 65, 76, 76, 65, 74, + 65, 76, 65, 76, 79, 85, 72, 79, 85, 128, 74, 65, 76, 76, 128, 74, 65, 73, + 206, 74, 65, 73, 128, 74, 65, 72, 128, 74, 65, 68, 69, 128, 74, 65, 67, + 75, 83, 128, 74, 65, 67, 75, 45, 79, 45, 76, 65, 78, 84, 69, 82, 78, 128, + 74, 65, 67, 203, 74, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 73, 90, + 72, 73, 84, 83, 65, 128, 73, 90, 72, 73, 84, 83, 193, 73, 90, 72, 69, + 128, 73, 90, 65, 75, 65, 89, 193, 73, 89, 69, 75, 128, 73, 89, 65, 78, + 78, 65, 128, 73, 85, 74, 65, 128, 73, 84, 211, 73, 84, 69, 82, 65, 84, + 73, 79, 206, 73, 84, 69, 77, 128, 73, 83, 83, 72, 65, 82, 128, 73, 83, + 79, 83, 67, 69, 76, 69, 211, 73, 83, 79, 78, 128, 73, 83, 79, 206, 73, + 83, 79, 76, 65, 84, 69, 128, 73, 83, 76, 65, 78, 68, 128, 73, 83, 72, 77, + 65, 65, 77, 128, 73, 83, 69, 78, 45, 73, 83, 69, 78, 128, 73, 83, 65, 75, + 73, 193, 73, 83, 45, 80, 73, 76, 76, 65, 128, 73, 82, 85, 89, 65, 78, 78, + 65, 128, 73, 82, 85, 85, 89, 65, 78, 78, 65, 128, 73, 82, 79, 78, 45, 67, + 79, 80, 80, 69, 210, 73, 82, 79, 78, 128, 73, 82, 66, 128, 73, 79, 84, + 73, 70, 73, 69, 196, 73, 79, 84, 65, 84, 69, 196, 73, 79, 84, 65, 128, + 73, 79, 84, 193, 73, 79, 82, 128, 73, 79, 78, 71, 128, 73, 79, 68, 72, + 65, 68, 72, 128, 73, 78, 86, 73, 83, 73, 66, 76, 197, 73, 78, 86, 69, 82, + 84, 69, 68, 128, 73, 78, 86, 69, 82, 84, 69, 196, 73, 78, 86, 69, 82, 84, + 69, 66, 82, 65, 84, 69, 128, 73, 78, 86, 69, 82, 83, 197, 73, 78, 84, 82, + 79, 68, 85, 67, 69, 82, 128, 73, 78, 84, 73, 128, 73, 78, 84, 69, 82, 83, + 89, 76, 76, 65, 66, 73, 195, 73, 78, 84, 69, 82, 83, 69, 67, 84, 73, 79, + 78, 128, 73, 78, 84, 69, 82, 83, 69, 67, 84, 73, 79, 206, 73, 78, 84, 69, + 82, 83, 69, 67, 84, 73, 78, 199, 73, 78, 84, 69, 82, 82, 79, 66, 65, 78, + 71, 128, 73, 78, 84, 69, 82, 82, 79, 66, 65, 78, 199, 73, 78, 84, 69, 82, + 80, 79, 76, 65, 84, 73, 79, 206, 73, 78, 84, 69, 82, 76, 79, 67, 75, 69, + 196, 73, 78, 84, 69, 82, 76, 73, 78, 69, 65, 210, 73, 78, 84, 69, 82, 76, + 65, 67, 69, 196, 73, 78, 84, 69, 82, 73, 79, 210, 73, 78, 84, 69, 82, 69, + 83, 212, 73, 78, 84, 69, 82, 67, 65, 76, 65, 84, 69, 128, 73, 78, 84, 69, + 71, 82, 65, 84, 73, 79, 78, 128, 73, 78, 84, 69, 71, 82, 65, 84, 73, 79, + 206, 73, 78, 84, 69, 71, 82, 65, 76, 128, 73, 78, 84, 69, 71, 82, 65, + 204, 73, 78, 83, 85, 76, 65, 210, 73, 78, 83, 84, 82, 85, 77, 69, 78, 84, + 65, 204, 73, 78, 83, 73, 68, 69, 128, 73, 78, 83, 73, 68, 197, 73, 78, + 83, 69, 82, 84, 73, 79, 206, 73, 78, 83, 69, 82, 212, 73, 78, 83, 69, 67, + 84, 128, 73, 78, 83, 67, 82, 73, 80, 84, 73, 79, 78, 65, 204, 73, 78, 80, + 85, 212, 73, 78, 78, 79, 67, 69, 78, 67, 69, 128, 73, 78, 78, 78, 128, + 73, 78, 78, 69, 82, 128, 73, 78, 78, 69, 210, 73, 78, 78, 128, 73, 78, + 73, 78, 71, 85, 128, 73, 78, 72, 73, 66, 73, 212, 73, 78, 72, 69, 82, 69, + 78, 212, 73, 78, 72, 65, 76, 69, 128, 73, 78, 71, 87, 65, 90, 128, 73, + 78, 70, 79, 82, 77, 65, 84, 73, 79, 206, 73, 78, 70, 76, 85, 69, 78, 67, + 69, 128, 73, 78, 70, 73, 78, 73, 84, 89, 128, 73, 78, 70, 73, 78, 73, 84, + 217, 73, 78, 68, 85, 83, 84, 82, 73, 65, 204, 73, 78, 68, 73, 82, 69, 67, + 212, 73, 78, 68, 73, 67, 84, 73, 79, 206, 73, 78, 68, 73, 67, 65, 84, 79, + 82, 128, 73, 78, 68, 73, 67, 65, 84, 79, 210, 73, 78, 68, 73, 195, 73, + 78, 68, 73, 65, 206, 73, 78, 68, 69, 88, 128, 73, 78, 68, 69, 80, 69, 78, + 68, 69, 78, 212, 73, 78, 67, 82, 69, 77, 69, 78, 84, 128, 73, 78, 67, 82, + 69, 65, 83, 69, 211, 73, 78, 67, 82, 69, 65, 83, 69, 128, 73, 78, 67, 82, + 69, 65, 83, 197, 73, 78, 67, 79, 77, 80, 76, 69, 84, 197, 73, 78, 67, 79, + 77, 73, 78, 199, 73, 78, 67, 76, 85, 68, 73, 78, 199, 73, 78, 67, 72, + 128, 73, 78, 66, 79, 216, 73, 78, 65, 80, 128, 73, 78, 45, 65, 76, 65, + 70, 128, 73, 77, 80, 69, 82, 73, 65, 204, 73, 77, 80, 69, 82, 70, 69, 67, + 84, 85, 205, 73, 77, 80, 69, 82, 70, 69, 67, 84, 65, 128, 73, 77, 80, 69, + 82, 70, 69, 67, 84, 193, 73, 77, 78, 128, 73, 77, 73, 83, 69, 79, 211, + 73, 77, 73, 78, 51, 128, 73, 77, 73, 78, 128, 73, 77, 73, 206, 73, 77, + 73, 70, 84, 72, 79, 82, 79, 78, 128, 73, 77, 73, 70, 84, 72, 79, 82, 65, + 128, 73, 77, 73, 70, 79, 78, 79, 78, 128, 73, 77, 73, 68, 73, 65, 82, 71, + 79, 78, 128, 73, 77, 65, 71, 197, 73, 77, 65, 65, 76, 65, 128, 73, 76, + 85, 89, 65, 78, 78, 65, 128, 73, 76, 85, 89, 128, 73, 76, 85, 85, 89, 65, + 78, 78, 65, 128, 73, 76, 85, 84, 128, 73, 76, 73, 77, 77, 85, 52, 128, + 73, 76, 73, 77, 77, 85, 51, 128, 73, 76, 73, 77, 77, 85, 128, 73, 76, 73, + 77, 77, 213, 73, 76, 50, 128, 73, 75, 73, 82, 128, 73, 75, 65, 82, 65, + 128, 73, 75, 65, 82, 193, 73, 74, 128, 73, 73, 89, 65, 78, 78, 65, 128, + 73, 71, 73, 128, 73, 71, 201, 73, 71, 71, 87, 83, 128, 73, 70, 73, 78, + 128, 73, 69, 85, 78, 71, 45, 84, 73, 75, 69, 85, 84, 128, 73, 69, 85, 78, + 71, 45, 84, 72, 73, 69, 85, 84, 72, 128, 73, 69, 85, 78, 71, 45, 82, 73, + 69, 85, 76, 128, 73, 69, 85, 78, 71, 45, 80, 73, 69, 85, 80, 128, 73, 69, + 85, 78, 71, 45, 80, 72, 73, 69, 85, 80, 72, 128, 73, 69, 85, 78, 71, 45, + 67, 73, 69, 85, 67, 128, 73, 69, 85, 78, 71, 45, 67, 72, 73, 69, 85, 67, + 72, 128, 73, 69, 85, 78, 199, 73, 68, 76, 69, 128, 73, 68, 73, 77, 128, + 73, 68, 73, 205, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 70, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 70, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 70, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 70, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 69, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 69, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 69, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 69, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 69, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 69, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 68, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 68, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 57, 49, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 57, + 48, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 56, 68, 55, 48, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 56, 67, 65, 57, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 56, 57, 69, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 55, 68, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 55, 65, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, + 57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 54, 68, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 53, 51, 51, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 55, 53, 49, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 55, 49, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 55, 48, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, + 70, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 69, 56, 48, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 55, 50, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 54, 55, 48, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 54, 55, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 54, 54, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, + 53, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 53, 57, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 53, 53, 55, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 54, 51, 53, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 54, 51, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 54, 50, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, + 50, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 50, 52, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 70, 56, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 53, 68, 69, 54, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 53, 66, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 53, 66, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, + 57, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 57, 49, 65, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 56, 70, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 53, 53, 66, 54, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 53, 52, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 53, 52, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, + 51, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 51, 67, 67, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 68, 68, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 55, 50, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 53, 50, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 53, 50, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, + 49, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 65, 52, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 56, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 50, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 52, 69, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 52, 69, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 65, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, + 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 65, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 57, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 56, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 65, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 65, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 65, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 65, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, + 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 50, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 48, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 65, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 65, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 65, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 65, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, + 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 56, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 55, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 54, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 65, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 65, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 65, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 65, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, + 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 48, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 69, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 70, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 70, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 70, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 54, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 53, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 52, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 70, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 70, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 69, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 69, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 67, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 69, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 69, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 69, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 52, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 51, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 50, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 69, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 68, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 68, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 67, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 65, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 50, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 49, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 48, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 65, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 56, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 48, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 70, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 69, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 56, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 54, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 69, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 68, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 67, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 54, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 52, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 67, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 66, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 65, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 52, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 50, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 65, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 57, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 56, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 50, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 48, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 56, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 55, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 54, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 48, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 69, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 54, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 53, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 52, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 69, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 67, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 52, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 51, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 50, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 67, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 65, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 50, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 49, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 48, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 65, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 56, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 48, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 70, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 69, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 56, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 54, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 69, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 68, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 67, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 54, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 52, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 67, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 66, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 65, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 52, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 50, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 70, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 70, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 70, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 65, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 57, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 56, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 70, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 70, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 70, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 70, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 50, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 48, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 69, 69, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 69, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 69, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 69, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 56, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 55, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 54, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 69, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 69, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 69, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 69, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 48, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 69, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 68, 67, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 68, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 68, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 68, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 54, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 53, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 52, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 69, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 67, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 67, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 52, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 51, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 50, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 67, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 65, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 66, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 50, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 49, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 48, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 65, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 56, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 65, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 48, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 70, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 69, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 56, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 54, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 57, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 69, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 68, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 67, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 54, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 52, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 55, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 67, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 66, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 65, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 52, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 50, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 54, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 54, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 65, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 57, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 56, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 50, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 48, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 56, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 55, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 54, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 48, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 69, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 54, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 53, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 52, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 69, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 67, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 52, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 51, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 50, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 67, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 65, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 50, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 49, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 48, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 65, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 56, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 48, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 70, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 69, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 56, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 54, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 200, 73, 68, 69, 78, 84, 73, + 70, 73, 67, 65, 84, 73, 79, 78, 128, 73, 68, 69, 78, 84, 73, 70, 73, 67, + 65, 84, 73, 79, 206, 73, 68, 69, 78, 84, 73, 67, 65, 204, 73, 68, 68, + 128, 73, 67, 79, 78, 128, 73, 67, 72, 79, 85, 128, 73, 67, 72, 79, 83, + 128, 73, 67, 72, 73, 77, 65, 84, 79, 83, 128, 73, 67, 72, 65, 68, 73, 78, + 128, 73, 67, 69, 76, 65, 78, 68, 73, 67, 45, 89, 82, 128, 73, 66, 73, 70, + 73, 76, 73, 128, 73, 65, 85, 68, 65, 128, 73, 48, 49, 53, 128, 73, 48, + 49, 52, 128, 73, 48, 49, 51, 128, 73, 48, 49, 50, 128, 73, 48, 49, 49, + 65, 128, 73, 48, 49, 49, 128, 73, 48, 49, 48, 65, 128, 73, 48, 49, 48, + 128, 73, 48, 48, 57, 65, 128, 73, 48, 48, 57, 128, 73, 48, 48, 56, 128, + 73, 48, 48, 55, 128, 73, 48, 48, 54, 128, 73, 48, 48, 53, 65, 128, 73, + 48, 48, 53, 128, 73, 48, 48, 52, 128, 73, 48, 48, 51, 128, 73, 48, 48, + 50, 128, 73, 48, 48, 49, 128, 73, 45, 89, 85, 128, 73, 45, 89, 79, 128, + 73, 45, 89, 69, 79, 128, 73, 45, 89, 69, 128, 73, 45, 89, 65, 69, 128, + 73, 45, 89, 65, 45, 79, 128, 73, 45, 89, 65, 128, 73, 45, 79, 45, 73, + 128, 73, 45, 79, 128, 73, 45, 69, 85, 128, 73, 45, 66, 69, 65, 77, 128, + 73, 45, 65, 82, 65, 69, 65, 128, 73, 45, 65, 128, 72, 90, 90, 90, 71, + 128, 72, 90, 90, 90, 128, 72, 90, 90, 80, 128, 72, 90, 90, 128, 72, 90, + 87, 71, 128, 72, 90, 87, 128, 72, 90, 84, 128, 72, 90, 71, 128, 72, 89, + 83, 84, 69, 82, 69, 83, 73, 211, 72, 89, 80, 79, 68, 73, 65, 83, 84, 79, + 76, 69, 128, 72, 89, 80, 72, 69, 78, 65, 84, 73, 79, 206, 72, 89, 80, 72, + 69, 78, 45, 77, 73, 78, 85, 83, 128, 72, 89, 80, 72, 69, 78, 128, 72, 89, + 80, 72, 69, 206, 72, 89, 71, 73, 69, 73, 65, 128, 72, 89, 71, 73, 69, 65, + 128, 72, 89, 65, 67, 73, 78, 84, 72, 128, 72, 88, 87, 71, 128, 72, 88, + 85, 79, 88, 128, 72, 88, 85, 79, 84, 128, 72, 88, 85, 79, 80, 128, 72, + 88, 85, 79, 128, 72, 88, 79, 88, 128, 72, 88, 79, 84, 128, 72, 88, 79, + 80, 128, 72, 88, 79, 128, 72, 88, 73, 88, 128, 72, 88, 73, 84, 128, 72, + 88, 73, 80, 128, 72, 88, 73, 69, 88, 128, 72, 88, 73, 69, 84, 128, 72, + 88, 73, 69, 80, 128, 72, 88, 73, 69, 128, 72, 88, 73, 128, 72, 88, 69, + 88, 128, 72, 88, 69, 80, 128, 72, 88, 69, 128, 72, 88, 65, 88, 128, 72, + 88, 65, 84, 128, 72, 88, 65, 80, 128, 72, 88, 65, 128, 72, 87, 85, 128, + 72, 87, 65, 73, 82, 128, 72, 87, 65, 72, 128, 72, 85, 86, 65, 128, 72, + 85, 83, 72, 69, 196, 72, 85, 83, 72, 128, 72, 85, 82, 65, 78, 128, 72, + 85, 79, 84, 128, 72, 85, 78, 68, 82, 69, 68, 83, 128, 72, 85, 78, 68, 82, + 69, 68, 211, 72, 85, 78, 68, 82, 69, 68, 128, 72, 85, 78, 68, 82, 69, + 196, 72, 85, 78, 128, 72, 85, 77, 208, 72, 85, 77, 65, 78, 128, 72, 85, + 77, 65, 206, 72, 85, 76, 50, 128, 72, 85, 73, 73, 84, 79, 128, 72, 85, + 71, 71, 73, 78, 71, 128, 72, 85, 71, 71, 73, 78, 199, 72, 85, 66, 50, + 128, 72, 85, 66, 178, 72, 85, 66, 128, 72, 85, 65, 82, 65, 68, 68, 79, + 128, 72, 85, 65, 78, 128, 72, 85, 45, 51, 128, 72, 85, 45, 50, 128, 72, + 85, 45, 49, 128, 72, 84, 84, 65, 128, 72, 84, 83, 128, 72, 84, 74, 128, + 72, 82, 89, 86, 78, 73, 193, 72, 80, 87, 71, 128, 72, 80, 65, 128, 72, + 80, 128, 72, 79, 85, 83, 197, 72, 79, 85, 82, 71, 76, 65, 83, 83, 128, + 72, 79, 85, 82, 71, 76, 65, 83, 211, 72, 79, 85, 82, 128, 72, 79, 85, + 210, 72, 79, 84, 69, 76, 128, 72, 79, 84, 65, 128, 72, 79, 83, 80, 73, + 84, 65, 76, 128, 72, 79, 82, 83, 69, 128, 72, 79, 82, 83, 197, 72, 79, + 82, 82, 128, 72, 79, 82, 78, 83, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, + 76, 76, 89, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 76, 217, 72, 79, + 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 54, 45, 48, 54, 128, 72, 79, 82, + 73, 90, 79, 78, 84, 65, 76, 45, 48, 54, 45, 48, 53, 128, 72, 79, 82, 73, + 90, 79, 78, 84, 65, 76, 45, 48, 54, 45, 48, 52, 128, 72, 79, 82, 73, 90, + 79, 78, 84, 65, 76, 45, 48, 54, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, + 78, 84, 65, 76, 45, 48, 54, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, + 84, 65, 76, 45, 48, 54, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, + 65, 76, 45, 48, 54, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, + 76, 45, 48, 53, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, + 45, 48, 53, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, + 48, 53, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, + 53, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, + 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, + 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, + 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 54, + 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 53, 128, + 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 52, 128, 72, + 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 51, 128, 72, 79, + 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 50, 128, 72, 79, 82, + 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 49, 128, 72, 79, 82, 73, + 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 48, 128, 72, 79, 82, 73, 90, + 79, 78, 84, 65, 76, 45, 48, 51, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, + 78, 84, 65, 76, 45, 48, 51, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, + 84, 65, 76, 45, 48, 51, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, + 65, 76, 45, 48, 51, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, + 76, 45, 48, 51, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, + 45, 48, 51, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, + 48, 51, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, + 50, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, + 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, + 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, + 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 50, + 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 49, 128, + 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 48, 128, 72, + 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 54, 128, 72, 79, + 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 53, 128, 72, 79, 82, + 73, 90, 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 52, 128, 72, 79, 82, 73, + 90, 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 51, 128, 72, 79, 82, 73, 90, + 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, + 78, 84, 65, 76, 45, 48, 49, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, + 84, 65, 76, 45, 48, 49, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, + 65, 76, 45, 48, 48, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, + 76, 45, 48, 48, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, + 45, 48, 48, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, + 48, 48, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, + 48, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, + 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, + 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 128, 72, 79, 82, 73, + 90, 79, 78, 84, 65, 204, 72, 79, 82, 73, 128, 72, 79, 82, 193, 72, 79, + 79, 85, 128, 72, 79, 79, 82, 85, 128, 72, 79, 79, 80, 128, 72, 79, 79, + 78, 128, 72, 79, 79, 75, 69, 68, 128, 72, 79, 79, 75, 69, 196, 72, 79, + 78, 69, 89, 66, 69, 69, 128, 72, 79, 78, 69, 217, 72, 79, 77, 79, 84, 72, + 69, 84, 73, 67, 128, 72, 79, 77, 79, 84, 72, 69, 84, 73, 195, 72, 79, 76, + 79, 128, 72, 79, 76, 76, 79, 215, 72, 79, 76, 69, 128, 72, 79, 76, 68, + 73, 78, 199, 72, 79, 76, 65, 77, 128, 72, 79, 76, 65, 205, 72, 79, 75, + 65, 128, 72, 79, 67, 75, 69, 217, 72, 79, 67, 72, 79, 128, 72, 79, 45, + 56, 128, 72, 79, 45, 55, 128, 72, 79, 45, 54, 128, 72, 79, 45, 53, 128, + 72, 79, 45, 52, 128, 72, 79, 45, 51, 128, 72, 79, 45, 50, 128, 72, 79, + 45, 49, 128, 72, 78, 85, 84, 128, 72, 78, 85, 79, 88, 128, 72, 78, 85, + 79, 128, 72, 78, 85, 66, 128, 72, 78, 79, 88, 128, 72, 78, 79, 84, 128, + 72, 78, 79, 80, 128, 72, 78, 73, 88, 128, 72, 78, 73, 84, 128, 72, 78, + 73, 80, 128, 72, 78, 73, 69, 88, 128, 72, 78, 73, 69, 84, 128, 72, 78, + 73, 69, 80, 128, 72, 78, 73, 69, 128, 72, 78, 73, 128, 72, 78, 69, 88, + 128, 72, 78, 69, 80, 128, 72, 78, 69, 128, 72, 78, 65, 88, 128, 72, 78, + 65, 85, 128, 72, 78, 65, 84, 128, 72, 78, 65, 80, 128, 72, 78, 65, 128, + 72, 77, 89, 88, 128, 72, 77, 89, 82, 88, 128, 72, 77, 89, 82, 128, 72, + 77, 89, 80, 128, 72, 77, 89, 128, 72, 77, 85, 88, 128, 72, 77, 85, 84, + 128, 72, 77, 85, 82, 88, 128, 72, 77, 85, 82, 128, 72, 77, 85, 80, 128, + 72, 77, 85, 79, 88, 128, 72, 77, 85, 79, 80, 128, 72, 77, 85, 79, 128, + 72, 77, 85, 128, 72, 77, 79, 88, 128, 72, 77, 79, 84, 128, 72, 77, 79, + 80, 128, 72, 77, 79, 128, 72, 77, 73, 88, 128, 72, 77, 73, 84, 128, 72, + 77, 73, 80, 128, 72, 77, 73, 69, 88, 128, 72, 77, 73, 69, 80, 128, 72, + 77, 73, 69, 128, 72, 77, 73, 128, 72, 77, 69, 128, 72, 77, 65, 88, 128, + 72, 77, 65, 84, 128, 72, 77, 65, 80, 128, 72, 77, 65, 128, 72, 76, 89, + 88, 128, 72, 76, 89, 84, 128, 72, 76, 89, 82, 88, 128, 72, 76, 89, 82, + 128, 72, 76, 89, 80, 128, 72, 76, 89, 128, 72, 76, 85, 88, 128, 72, 76, + 85, 84, 128, 72, 76, 85, 82, 88, 128, 72, 76, 85, 82, 128, 72, 76, 85, + 80, 128, 72, 76, 85, 79, 88, 128, 72, 76, 85, 79, 80, 128, 72, 76, 85, + 79, 128, 72, 76, 85, 128, 72, 76, 79, 88, 128, 72, 76, 79, 80, 128, 72, + 76, 79, 128, 72, 76, 73, 88, 128, 72, 76, 73, 84, 128, 72, 76, 73, 80, + 128, 72, 76, 73, 69, 88, 128, 72, 76, 73, 69, 80, 128, 72, 76, 73, 69, + 128, 72, 76, 73, 128, 72, 76, 69, 88, 128, 72, 76, 69, 80, 128, 72, 76, + 69, 128, 72, 76, 65, 88, 128, 72, 76, 65, 85, 128, 72, 76, 65, 84, 128, + 72, 76, 65, 80, 128, 72, 76, 65, 128, 72, 76, 128, 72, 75, 128, 72, 73, + 90, 66, 128, 72, 73, 89, 79, 128, 72, 73, 84, 84, 73, 78, 199, 72, 73, + 83, 84, 79, 82, 73, 195, 72, 73, 82, 73, 81, 128, 72, 73, 80, 80, 79, 80, + 79, 84, 65, 77, 85, 83, 128, 72, 73, 78, 71, 69, 68, 128, 72, 73, 78, 71, + 69, 196, 72, 73, 78, 71, 69, 128, 72, 73, 78, 68, 213, 72, 73, 75, 73, + 78, 199, 72, 73, 71, 72, 45, 83, 80, 69, 69, 196, 72, 73, 71, 72, 45, 82, + 69, 86, 69, 82, 83, 69, 68, 45, 185, 72, 73, 71, 72, 45, 76, 79, 215, 72, + 73, 71, 72, 45, 72, 69, 69, 76, 69, 196, 72, 73, 69, 88, 128, 72, 73, 69, + 85, 72, 45, 83, 73, 79, 83, 128, 72, 73, 69, 85, 72, 45, 82, 73, 69, 85, + 76, 128, 72, 73, 69, 85, 72, 45, 80, 73, 69, 85, 80, 128, 72, 73, 69, 85, + 72, 45, 78, 73, 69, 85, 78, 128, 72, 73, 69, 85, 72, 45, 77, 73, 69, 85, + 77, 128, 72, 73, 69, 85, 200, 72, 73, 69, 82, 79, 71, 76, 89, 80, 72, 73, + 195, 72, 73, 68, 73, 78, 199, 72, 73, 68, 69, 84, 128, 72, 73, 68, 69, + 128, 72, 73, 66, 73, 83, 67, 85, 83, 128, 72, 73, 45, 82, 69, 83, 128, + 72, 73, 45, 55, 128, 72, 73, 45, 54, 128, 72, 73, 45, 53, 128, 72, 73, + 45, 52, 128, 72, 73, 45, 51, 128, 72, 73, 45, 50, 128, 72, 73, 45, 49, + 128, 72, 72, 89, 85, 128, 72, 72, 89, 79, 128, 72, 72, 89, 73, 128, 72, + 72, 89, 69, 69, 128, 72, 72, 89, 69, 128, 72, 72, 89, 65, 65, 128, 72, + 72, 89, 65, 128, 72, 72, 87, 73, 128, 72, 72, 87, 69, 69, 128, 72, 72, + 87, 69, 128, 72, 72, 87, 65, 128, 72, 72, 85, 128, 72, 72, 73, 128, 72, + 72, 69, 69, 128, 72, 72, 69, 128, 72, 72, 65, 65, 128, 72, 71, 128, 72, + 69, 89, 84, 128, 72, 69, 88, 73, 70, 79, 82, 205, 72, 69, 88, 65, 71, 82, + 65, 205, 72, 69, 88, 65, 71, 79, 78, 128, 72, 69, 82, 85, 84, 85, 128, + 72, 69, 82, 85, 128, 72, 69, 82, 77, 73, 84, 73, 65, 206, 72, 69, 82, 77, + 73, 79, 78, 73, 65, 206, 72, 69, 82, 77, 69, 83, 128, 72, 69, 82, 69, + 128, 72, 69, 82, 66, 128, 72, 69, 82, 65, 69, 85, 205, 72, 69, 78, 71, + 128, 72, 69, 78, 199, 72, 69, 77, 80, 128, 72, 69, 76, 77, 69, 84, 128, + 72, 69, 76, 77, 69, 212, 72, 69, 76, 205, 72, 69, 76, 76, 83, 67, 72, 82, + 69, 73, 66, 69, 210, 72, 69, 76, 73, 88, 128, 72, 69, 76, 73, 67, 79, 80, + 84, 69, 82, 128, 72, 69, 75, 85, 84, 65, 65, 82, 85, 128, 72, 69, 73, 83, + 69, 73, 128, 72, 69, 73, 71, 72, 84, 128, 72, 69, 69, 73, 128, 72, 69, + 68, 71, 69, 72, 79, 71, 128, 72, 69, 65, 86, 89, 128, 72, 69, 65, 86, 69, + 78, 76, 217, 72, 69, 65, 86, 69, 78, 128, 72, 69, 65, 86, 69, 206, 72, + 69, 65, 82, 84, 83, 128, 72, 69, 65, 82, 84, 45, 83, 72, 65, 80, 69, 196, + 72, 69, 65, 82, 84, 128, 72, 69, 65, 82, 212, 72, 69, 65, 82, 73, 78, + 199, 72, 69, 65, 82, 45, 78, 79, 45, 69, 86, 73, 204, 72, 69, 65, 68, 83, + 84, 82, 79, 75, 69, 128, 72, 69, 65, 68, 83, 84, 79, 78, 69, 128, 72, 69, + 65, 68, 83, 84, 79, 78, 197, 72, 69, 65, 68, 83, 67, 65, 82, 70, 128, 72, + 69, 65, 68, 80, 72, 79, 78, 69, 128, 72, 69, 65, 68, 73, 78, 71, 128, 72, + 69, 65, 68, 45, 66, 65, 78, 68, 65, 71, 69, 128, 72, 69, 45, 55, 128, 72, + 69, 45, 54, 128, 72, 69, 45, 53, 128, 72, 69, 45, 52, 128, 72, 69, 45, + 51, 128, 72, 69, 45, 50, 128, 72, 69, 45, 49, 128, 72, 68, 82, 128, 72, + 67, 128, 72, 66, 65, 83, 65, 45, 69, 83, 65, 83, 193, 72, 66, 65, 83, + 193, 72, 65, 89, 65, 78, 78, 65, 128, 72, 65, 87, 74, 128, 72, 65, 86, + 69, 128, 72, 65, 85, 80, 84, 83, 84, 73, 77, 77, 69, 128, 72, 65, 85, 77, + 69, 65, 128, 72, 65, 213, 72, 65, 84, 82, 65, 206, 72, 65, 84, 72, 73, + 128, 72, 65, 84, 69, 128, 72, 65, 84, 67, 72, 73, 78, 199, 72, 65, 84, + 65, 198, 72, 65, 83, 69, 210, 72, 65, 83, 65, 78, 84, 65, 128, 72, 65, + 82, 80, 79, 79, 78, 128, 72, 65, 82, 80, 79, 79, 206, 72, 65, 82, 77, 79, + 78, 73, 67, 128, 72, 65, 82, 75, 76, 69, 65, 206, 72, 65, 82, 68, 78, 69, + 83, 83, 128, 72, 65, 82, 196, 72, 65, 82, 66, 65, 72, 65, 89, 128, 72, + 65, 80, 80, 217, 72, 65, 78, 85, 78, 79, 207, 72, 65, 78, 73, 70, 201, + 72, 65, 78, 71, 90, 72, 79, 213, 72, 65, 78, 68, 83, 72, 65, 75, 69, 128, + 72, 65, 78, 68, 83, 128, 72, 65, 78, 68, 211, 72, 65, 78, 68, 76, 69, 83, + 128, 72, 65, 78, 68, 76, 69, 128, 72, 65, 78, 68, 66, 65, 76, 76, 128, + 72, 65, 78, 68, 66, 65, 71, 128, 72, 65, 78, 68, 45, 79, 86, 65, 76, 128, + 72, 65, 78, 68, 45, 79, 86, 65, 204, 72, 65, 78, 68, 45, 72, 79, 79, 75, + 128, 72, 65, 78, 68, 45, 72, 79, 79, 203, 72, 65, 78, 68, 45, 72, 73, 78, + 71, 69, 128, 72, 65, 78, 68, 45, 72, 73, 78, 71, 197, 72, 65, 78, 68, 45, + 70, 76, 65, 84, 128, 72, 65, 78, 68, 45, 70, 76, 65, 212, 72, 65, 78, 68, + 45, 70, 73, 83, 84, 128, 72, 65, 78, 68, 45, 67, 85, 82, 76, 73, 67, 85, + 69, 128, 72, 65, 78, 68, 45, 67, 85, 82, 76, 73, 67, 85, 197, 72, 65, 78, + 68, 45, 67, 85, 80, 128, 72, 65, 78, 68, 45, 67, 85, 208, 72, 65, 78, 68, + 45, 67, 76, 65, 87, 128, 72, 65, 78, 68, 45, 67, 76, 65, 215, 72, 65, 78, + 68, 45, 67, 73, 82, 67, 76, 69, 128, 72, 65, 78, 68, 45, 67, 73, 82, 67, + 76, 197, 72, 65, 78, 68, 45, 65, 78, 71, 76, 69, 128, 72, 65, 78, 68, 45, + 65, 78, 71, 76, 197, 72, 65, 78, 68, 128, 72, 65, 78, 45, 65, 75, 65, 84, + 128, 72, 65, 77, 90, 65, 128, 72, 65, 77, 90, 193, 72, 65, 77, 83, 84, + 69, 210, 72, 65, 77, 83, 65, 128, 72, 65, 77, 77, 69, 82, 128, 72, 65, + 77, 77, 69, 210, 72, 65, 77, 66, 85, 82, 71, 69, 82, 128, 72, 65, 76, 81, + 65, 128, 72, 65, 76, 79, 128, 72, 65, 76, 70, 45, 67, 73, 82, 67, 76, + 197, 72, 65, 76, 70, 45, 50, 128, 72, 65, 76, 70, 45, 49, 128, 72, 65, + 76, 70, 128, 72, 65, 76, 66, 69, 82, 68, 128, 72, 65, 76, 65, 78, 84, 65, + 128, 72, 65, 73, 84, 85, 128, 72, 65, 73, 211, 72, 65, 73, 82, 67, 85, + 84, 128, 72, 65, 71, 76, 65, 218, 72, 65, 71, 76, 128, 72, 65, 70, 85, + 75, 72, 65, 128, 72, 65, 70, 85, 75, 72, 128, 72, 65, 69, 71, 204, 72, + 65, 68, 69, 83, 128, 72, 65, 65, 82, 85, 128, 72, 65, 65, 77, 128, 72, + 65, 193, 72, 65, 45, 72, 65, 128, 72, 65, 45, 57, 128, 72, 65, 45, 56, + 128, 72, 65, 45, 55, 128, 72, 65, 45, 54, 128, 72, 65, 45, 53, 128, 72, + 65, 45, 52, 128, 72, 65, 45, 51, 128, 72, 65, 45, 50, 128, 72, 65, 45, + 49, 49, 128, 72, 65, 45, 49, 48, 128, 72, 65, 45, 49, 128, 72, 48, 48, + 56, 128, 72, 48, 48, 55, 128, 72, 48, 48, 54, 65, 128, 72, 48, 48, 54, + 128, 72, 48, 48, 53, 128, 72, 48, 48, 52, 128, 72, 48, 48, 51, 128, 72, + 48, 48, 50, 128, 72, 48, 48, 49, 128, 72, 45, 84, 89, 80, 197, 71, 89, + 85, 128, 71, 89, 79, 78, 128, 71, 89, 79, 128, 71, 89, 73, 128, 71, 89, + 70, 213, 71, 89, 69, 69, 128, 71, 89, 65, 83, 128, 71, 89, 65, 65, 128, + 71, 89, 65, 128, 71, 89, 128, 71, 87, 85, 128, 71, 87, 73, 128, 71, 87, + 69, 69, 128, 71, 87, 69, 128, 71, 87, 65, 65, 128, 71, 87, 65, 128, 71, + 87, 128, 71, 86, 65, 78, 71, 128, 71, 86, 128, 71, 85, 82, 85, 83, 72, + 128, 71, 85, 82, 85, 78, 128, 71, 85, 82, 77, 85, 75, 72, 201, 71, 85, + 82, 65, 77, 85, 84, 79, 78, 128, 71, 85, 82, 65, 71, 197, 71, 85, 82, 55, + 128, 71, 85, 78, 85, 128, 71, 85, 78, 213, 71, 85, 78, 74, 65, 76, 193, + 71, 85, 205, 71, 85, 76, 128, 71, 85, 74, 65, 82, 65, 84, 201, 71, 85, + 73, 84, 65, 82, 128, 71, 85, 73, 68, 197, 71, 85, 199, 71, 85, 69, 73, + 128, 71, 85, 69, 72, 128, 71, 85, 69, 200, 71, 85, 68, 128, 71, 85, 196, + 71, 85, 65, 82, 68, 83, 77, 65, 78, 128, 71, 85, 65, 82, 68, 69, 68, 78, + 69, 83, 83, 128, 71, 85, 65, 82, 68, 69, 196, 71, 85, 65, 82, 68, 128, + 71, 85, 65, 82, 65, 78, 201, 71, 85, 193, 71, 85, 178, 71, 84, 69, 210, + 71, 83, 85, 77, 128, 71, 83, 85, 205, 71, 82, 213, 71, 82, 79, 87, 73, + 78, 199, 71, 82, 79, 85, 78, 68, 128, 71, 82, 79, 78, 84, 72, 73, 83, 77, + 65, 84, 65, 128, 71, 82, 79, 77, 79, 80, 79, 86, 79, 68, 78, 65, 89, 65, + 128, 71, 82, 79, 77, 79, 80, 79, 86, 79, 68, 78, 65, 89, 193, 71, 82, 79, + 77, 79, 75, 82, 89, 90, 72, 69, 86, 65, 89, 65, 128, 71, 82, 79, 77, 79, + 75, 82, 89, 90, 72, 69, 86, 65, 89, 193, 71, 82, 79, 77, 78, 65, 89, 65, + 128, 71, 82, 79, 77, 78, 65, 89, 193, 71, 82, 73, 78, 78, 73, 78, 199, + 71, 82, 73, 77, 65, 67, 73, 78, 199, 71, 82, 69, 217, 71, 82, 69, 71, 79, + 82, 73, 65, 206, 71, 82, 69, 69, 78, 128, 71, 82, 69, 69, 206, 71, 82, + 69, 65, 84, 78, 69, 83, 83, 128, 71, 82, 69, 65, 84, 69, 82, 45, 84, 72, + 65, 78, 128, 71, 82, 69, 65, 84, 69, 82, 45, 84, 72, 65, 206, 71, 82, 69, + 65, 84, 69, 210, 71, 82, 69, 65, 212, 71, 82, 65, 86, 69, 89, 65, 82, + 196, 71, 82, 65, 86, 69, 45, 77, 65, 67, 82, 79, 78, 128, 71, 82, 65, 86, + 69, 45, 65, 67, 85, 84, 69, 45, 71, 82, 65, 86, 69, 128, 71, 82, 65, 86, + 197, 71, 82, 65, 84, 69, 82, 128, 71, 82, 65, 83, 83, 128, 71, 82, 65, + 83, 211, 71, 82, 65, 83, 208, 71, 82, 65, 80, 72, 69, 77, 197, 71, 82, + 65, 80, 69, 83, 128, 71, 82, 65, 78, 84, 72, 193, 71, 82, 65, 77, 77, + 193, 71, 82, 65, 73, 78, 128, 71, 82, 65, 70, 128, 71, 82, 65, 68, 85, + 65, 84, 73, 79, 206, 71, 82, 65, 68, 85, 65, 76, 128, 71, 82, 65, 67, 69, + 128, 71, 82, 65, 67, 197, 71, 80, 65, 128, 71, 79, 82, 84, 72, 77, 73, + 75, 79, 206, 71, 79, 82, 84, 128, 71, 79, 82, 73, 76, 76, 65, 128, 71, + 79, 82, 71, 79, 84, 69, 82, 73, 128, 71, 79, 82, 71, 79, 83, 89, 78, 84, + 72, 69, 84, 79, 78, 128, 71, 79, 82, 71, 79, 206, 71, 79, 82, 71, 73, + 128, 71, 79, 82, 65, 90, 68, 207, 71, 79, 82, 65, 128, 71, 79, 79, 83, + 69, 128, 71, 79, 79, 196, 71, 79, 78, 71, 71, 79, 78, 71, 128, 71, 79, + 76, 85, 66, 67, 72, 73, 203, 71, 79, 76, 70, 69, 82, 128, 71, 79, 76, 68, + 128, 71, 79, 75, 128, 71, 79, 73, 78, 199, 71, 79, 71, 71, 76, 69, 83, + 128, 71, 79, 66, 76, 73, 78, 128, 71, 79, 65, 76, 128, 71, 79, 65, 204, + 71, 79, 65, 128, 71, 78, 89, 73, 83, 128, 71, 78, 65, 86, 73, 89, 65, 78, + 73, 128, 71, 76, 79, 87, 73, 78, 199, 71, 76, 79, 86, 69, 83, 128, 71, + 76, 79, 86, 69, 128, 71, 76, 79, 84, 84, 65, 204, 71, 76, 79, 66, 197, + 71, 76, 73, 83, 83, 65, 78, 68, 207, 71, 76, 69, 73, 67, 200, 71, 76, 65, + 71, 79, 76, 73, 128, 71, 76, 65, 128, 71, 74, 69, 128, 71, 73, 88, 128, + 71, 73, 84, 128, 71, 73, 83, 72, 128, 71, 73, 83, 200, 71, 73, 83, 65, + 76, 128, 71, 73, 82, 85, 68, 65, 65, 128, 71, 73, 82, 76, 211, 71, 73, + 82, 76, 128, 71, 73, 82, 65, 70, 70, 197, 71, 73, 82, 51, 128, 71, 73, + 82, 179, 71, 73, 82, 50, 128, 71, 73, 82, 178, 71, 73, 80, 128, 71, 73, + 78, 73, 73, 128, 71, 73, 78, 71, 69, 210, 71, 73, 77, 69, 76, 45, 72, 69, + 84, 72, 128, 71, 73, 77, 69, 76, 128, 71, 73, 77, 69, 204, 71, 73, 77, + 128, 71, 73, 71, 65, 128, 71, 73, 71, 128, 71, 73, 70, 212, 71, 73, 69, + 84, 128, 71, 73, 68, 73, 77, 128, 71, 73, 66, 66, 79, 85, 211, 71, 73, + 66, 65, 128, 71, 73, 52, 128, 71, 73, 180, 71, 72, 90, 128, 71, 72, 87, + 65, 128, 71, 72, 85, 78, 78, 65, 128, 71, 72, 85, 78, 78, 193, 71, 72, + 85, 128, 71, 72, 79, 85, 128, 71, 72, 79, 83, 84, 128, 71, 72, 79, 128, + 71, 72, 73, 77, 69, 76, 128, 71, 72, 73, 128, 71, 72, 72, 65, 128, 71, + 72, 69, 89, 83, 128, 71, 72, 69, 85, 88, 128, 71, 72, 69, 85, 78, 128, + 71, 72, 69, 85, 71, 72, 69, 85, 65, 69, 77, 128, 71, 72, 69, 85, 71, 72, + 69, 78, 128, 71, 72, 69, 85, 65, 69, 82, 65, 69, 128, 71, 72, 69, 85, 65, + 69, 71, 72, 69, 85, 65, 69, 128, 71, 72, 69, 84, 128, 71, 72, 69, 69, + 128, 71, 72, 69, 128, 71, 72, 197, 71, 72, 65, 89, 78, 128, 71, 72, 65, + 82, 65, 69, 128, 71, 72, 65, 80, 128, 71, 72, 65, 78, 128, 71, 72, 65, + 77, 77, 65, 128, 71, 72, 65, 77, 65, 76, 128, 71, 72, 65, 73, 78, 85, 128, 71, 72, 65, 73, 78, 128, 71, 72, 65, 73, 206, 71, 72, 65, 68, 128, 71, 72, 65, 65, 77, 65, 69, 128, 71, 72, 65, 65, 128, 71, 71, 87, 73, 128, 71, 71, 87, 69, 69, 128, 71, 71, 87, 69, 128, 71, 71, 87, 65, 65, @@ -4260,155 +4275,157 @@ static const unsigned char lexicon[] = { 128, 70, 86, 83, 50, 128, 70, 86, 83, 49, 128, 70, 85, 88, 128, 70, 85, 84, 128, 70, 85, 83, 69, 128, 70, 85, 83, 193, 70, 85, 82, 88, 128, 70, 85, 80, 128, 70, 85, 78, 69, 82, 65, 204, 70, 85, 78, 67, 84, 73, 79, 78, - 65, 204, 70, 85, 78, 67, 84, 73, 79, 78, 128, 70, 85, 76, 76, 78, 69, 83, - 83, 128, 70, 85, 76, 204, 70, 85, 74, 73, 128, 70, 85, 69, 84, 128, 70, - 85, 69, 204, 70, 85, 69, 128, 70, 85, 65, 128, 70, 84, 72, 79, 82, 193, - 70, 83, 73, 128, 70, 82, 79, 87, 78, 73, 78, 71, 128, 70, 82, 79, 87, 78, - 73, 78, 199, 70, 82, 79, 87, 78, 128, 70, 82, 79, 87, 206, 70, 82, 79, - 78, 84, 45, 84, 73, 76, 84, 69, 196, 70, 82, 79, 78, 84, 45, 70, 65, 67, - 73, 78, 199, 70, 82, 79, 78, 212, 70, 82, 79, 205, 70, 82, 79, 71, 128, - 70, 82, 79, 199, 70, 82, 73, 84, 85, 128, 70, 82, 73, 69, 83, 128, 70, - 82, 73, 69, 196, 70, 82, 73, 67, 65, 84, 73, 86, 69, 128, 70, 82, 69, 84, - 66, 79, 65, 82, 68, 128, 70, 82, 69, 78, 67, 200, 70, 82, 69, 69, 90, 73, - 78, 199, 70, 82, 69, 69, 128, 70, 82, 69, 197, 70, 82, 65, 78, 75, 211, - 70, 82, 65, 78, 195, 70, 82, 65, 77, 69, 83, 128, 70, 82, 65, 77, 69, - 128, 70, 82, 65, 77, 197, 70, 82, 65, 75, 84, 85, 210, 70, 82, 65, 71, - 82, 65, 78, 84, 128, 70, 82, 65, 71, 77, 69, 78, 84, 128, 70, 82, 65, 67, - 84, 73, 79, 206, 70, 79, 88, 128, 70, 79, 216, 70, 79, 85, 82, 84, 69, - 69, 78, 128, 70, 79, 85, 82, 84, 69, 69, 206, 70, 79, 85, 82, 45, 84, 72, - 73, 82, 84, 89, 128, 70, 79, 85, 82, 45, 83, 84, 82, 73, 78, 199, 70, 79, - 85, 82, 45, 80, 69, 82, 45, 69, 205, 70, 79, 85, 82, 45, 76, 73, 78, 197, - 70, 79, 85, 210, 70, 79, 85, 78, 84, 65, 73, 78, 128, 70, 79, 85, 78, 84, - 65, 73, 206, 70, 79, 83, 84, 69, 82, 73, 78, 71, 128, 70, 79, 82, 87, 65, - 82, 68, 128, 70, 79, 82, 87, 65, 82, 196, 70, 79, 82, 84, 89, 45, 70, 73, - 86, 197, 70, 79, 82, 84, 89, 128, 70, 79, 82, 84, 217, 70, 79, 82, 84, - 85, 78, 197, 70, 79, 82, 84, 73, 69, 84, 72, 128, 70, 79, 82, 84, 69, - 128, 70, 79, 82, 77, 211, 70, 79, 82, 77, 69, 69, 128, 70, 79, 82, 77, - 69, 197, 70, 79, 82, 77, 65, 84, 84, 73, 78, 71, 128, 70, 79, 82, 77, 65, - 212, 70, 79, 82, 75, 69, 196, 70, 79, 82, 69, 72, 69, 65, 196, 70, 79, - 82, 67, 69, 83, 128, 70, 79, 82, 67, 69, 128, 70, 79, 80, 128, 70, 79, - 79, 84, 83, 84, 79, 79, 76, 128, 70, 79, 79, 84, 80, 82, 73, 78, 84, 83, - 128, 70, 79, 79, 84, 78, 79, 84, 197, 70, 79, 79, 84, 66, 65, 76, 76, + 65, 204, 70, 85, 78, 67, 84, 73, 79, 78, 128, 70, 85, 76, 76, 87, 73, 68, + 84, 200, 70, 85, 76, 76, 78, 69, 83, 83, 128, 70, 85, 76, 204, 70, 85, + 74, 73, 128, 70, 85, 69, 84, 128, 70, 85, 69, 204, 70, 85, 69, 128, 70, + 85, 65, 128, 70, 84, 72, 79, 82, 193, 70, 83, 73, 128, 70, 82, 79, 87, + 78, 73, 78, 71, 128, 70, 82, 79, 87, 78, 73, 78, 199, 70, 82, 79, 87, 78, + 128, 70, 82, 79, 87, 206, 70, 82, 79, 78, 84, 45, 84, 73, 76, 84, 69, + 196, 70, 82, 79, 78, 84, 45, 70, 65, 67, 73, 78, 199, 70, 82, 79, 78, + 212, 70, 82, 79, 205, 70, 82, 79, 71, 128, 70, 82, 79, 199, 70, 82, 73, + 84, 85, 128, 70, 82, 73, 69, 83, 128, 70, 82, 73, 69, 196, 70, 82, 73, + 67, 65, 84, 73, 86, 69, 128, 70, 82, 69, 84, 66, 79, 65, 82, 68, 128, 70, + 82, 69, 78, 67, 200, 70, 82, 69, 69, 90, 73, 78, 199, 70, 82, 69, 69, + 128, 70, 82, 69, 197, 70, 82, 65, 78, 75, 211, 70, 82, 65, 78, 195, 70, + 82, 65, 77, 69, 83, 128, 70, 82, 65, 77, 69, 128, 70, 82, 65, 77, 197, + 70, 82, 65, 75, 84, 85, 210, 70, 82, 65, 71, 82, 65, 78, 84, 128, 70, 82, + 65, 71, 77, 69, 78, 84, 128, 70, 82, 65, 67, 84, 73, 79, 206, 70, 79, 88, + 128, 70, 79, 216, 70, 79, 85, 82, 84, 69, 69, 78, 128, 70, 79, 85, 82, + 84, 69, 69, 206, 70, 79, 85, 82, 45, 84, 72, 73, 82, 84, 89, 128, 70, 79, + 85, 82, 45, 83, 84, 82, 73, 78, 199, 70, 79, 85, 82, 45, 80, 69, 82, 45, + 69, 205, 70, 79, 85, 82, 45, 76, 73, 78, 197, 70, 79, 85, 210, 70, 79, + 85, 78, 84, 65, 73, 78, 128, 70, 79, 85, 78, 84, 65, 73, 206, 70, 79, 83, + 84, 69, 82, 73, 78, 71, 128, 70, 79, 82, 87, 65, 82, 68, 128, 70, 79, 82, + 87, 65, 82, 196, 70, 79, 82, 84, 89, 45, 70, 73, 86, 197, 70, 79, 82, 84, + 89, 128, 70, 79, 82, 84, 217, 70, 79, 82, 84, 85, 78, 69, 128, 70, 79, + 82, 84, 85, 78, 197, 70, 79, 82, 84, 73, 69, 84, 72, 128, 70, 79, 82, 84, + 69, 128, 70, 79, 82, 77, 211, 70, 79, 82, 77, 69, 69, 128, 70, 79, 82, + 77, 69, 197, 70, 79, 82, 77, 65, 84, 84, 73, 78, 71, 128, 70, 79, 82, 77, + 65, 212, 70, 79, 82, 75, 69, 196, 70, 79, 82, 69, 72, 69, 65, 196, 70, + 79, 82, 67, 69, 83, 128, 70, 79, 82, 67, 69, 128, 70, 79, 80, 128, 70, + 79, 79, 84, 83, 84, 79, 79, 76, 128, 70, 79, 79, 84, 80, 82, 73, 78, 84, + 83, 128, 70, 79, 79, 84, 78, 79, 84, 197, 70, 79, 79, 84, 66, 65, 76, 76, 128, 70, 79, 79, 84, 128, 70, 79, 79, 76, 128, 70, 79, 79, 68, 128, 70, 79, 79, 128, 70, 79, 78, 212, 70, 79, 78, 71, 77, 65, 78, 128, 70, 79, 78, 68, 85, 69, 128, 70, 79, 77, 128, 70, 79, 76, 76, 89, 128, 70, 79, - 76, 76, 79, 87, 73, 78, 71, 128, 70, 79, 76, 68, 69, 82, 128, 70, 79, 76, - 68, 69, 196, 70, 79, 71, 71, 89, 128, 70, 79, 71, 128, 70, 207, 70, 77, - 128, 70, 76, 89, 73, 78, 199, 70, 76, 89, 128, 70, 76, 85, 84, 84, 69, - 82, 73, 78, 71, 128, 70, 76, 85, 84, 84, 69, 82, 73, 78, 199, 70, 76, 85, - 84, 69, 128, 70, 76, 85, 83, 72, 69, 196, 70, 76, 79, 87, 73, 78, 199, - 70, 76, 79, 87, 69, 82, 83, 128, 70, 76, 79, 87, 69, 210, 70, 76, 79, 85, - 82, 73, 83, 72, 128, 70, 76, 79, 82, 69, 84, 84, 69, 128, 70, 76, 79, 82, - 65, 204, 70, 76, 79, 80, 80, 217, 70, 76, 79, 79, 82, 128, 70, 76, 79, - 79, 210, 70, 76, 73, 80, 128, 70, 76, 73, 71, 72, 84, 128, 70, 76, 73, - 67, 203, 70, 76, 69, 88, 85, 83, 128, 70, 76, 69, 88, 69, 196, 70, 76, - 69, 88, 128, 70, 76, 69, 85, 82, 79, 78, 128, 70, 76, 69, 85, 82, 45, 68, - 69, 45, 76, 73, 83, 128, 70, 76, 65, 84, 84, 69, 78, 69, 196, 70, 76, 65, - 84, 78, 69, 83, 83, 128, 70, 76, 65, 84, 66, 82, 69, 65, 68, 128, 70, 76, - 65, 83, 72, 128, 70, 76, 65, 77, 73, 78, 71, 79, 128, 70, 76, 65, 77, 69, - 128, 70, 76, 65, 71, 83, 128, 70, 76, 65, 71, 45, 53, 128, 70, 76, 65, - 71, 45, 52, 128, 70, 76, 65, 71, 45, 51, 128, 70, 76, 65, 71, 45, 50, - 128, 70, 76, 65, 71, 45, 49, 128, 70, 76, 65, 71, 128, 70, 76, 65, 199, - 70, 76, 65, 128, 70, 76, 128, 70, 73, 88, 69, 68, 45, 70, 79, 82, 205, - 70, 73, 88, 128, 70, 73, 86, 69, 45, 84, 72, 73, 82, 84, 89, 128, 70, 73, - 86, 69, 45, 76, 73, 78, 197, 70, 73, 84, 90, 80, 65, 84, 82, 73, 67, 203, - 70, 73, 84, 65, 128, 70, 73, 84, 128, 70, 73, 83, 84, 69, 196, 70, 73, - 83, 72, 73, 78, 199, 70, 73, 83, 72, 72, 79, 79, 75, 128, 70, 73, 83, 72, - 72, 79, 79, 203, 70, 73, 83, 72, 69, 89, 69, 128, 70, 73, 83, 72, 128, - 70, 73, 83, 200, 70, 73, 82, 83, 212, 70, 73, 82, 73, 128, 70, 73, 82, - 69, 87, 79, 82, 75, 83, 128, 70, 73, 82, 69, 87, 79, 82, 203, 70, 73, 82, - 69, 67, 82, 65, 67, 75, 69, 82, 128, 70, 73, 82, 69, 128, 70, 73, 82, - 197, 70, 73, 80, 128, 70, 73, 78, 73, 84, 197, 70, 73, 78, 71, 69, 82, - 83, 128, 70, 73, 78, 71, 69, 82, 211, 70, 73, 78, 71, 69, 82, 78, 65, 73, - 76, 83, 128, 70, 73, 78, 71, 69, 82, 69, 196, 70, 73, 78, 71, 69, 82, 45, - 80, 79, 83, 212, 70, 73, 78, 71, 69, 82, 128, 70, 73, 78, 71, 69, 210, - 70, 73, 78, 65, 78, 67, 73, 65, 76, 128, 70, 73, 78, 65, 76, 128, 70, 73, - 76, 205, 70, 73, 76, 76, 69, 82, 45, 50, 128, 70, 73, 76, 76, 69, 82, 45, - 49, 128, 70, 73, 76, 76, 69, 82, 128, 70, 73, 76, 76, 69, 196, 70, 73, - 76, 76, 128, 70, 73, 76, 204, 70, 73, 76, 197, 70, 73, 73, 128, 70, 73, - 71, 85, 82, 69, 45, 51, 128, 70, 73, 71, 85, 82, 69, 45, 50, 128, 70, 73, - 71, 85, 82, 69, 45, 49, 128, 70, 73, 71, 85, 82, 69, 128, 70, 73, 71, 85, - 82, 197, 70, 73, 71, 72, 84, 128, 70, 73, 70, 84, 89, 128, 70, 73, 70, - 84, 217, 70, 73, 70, 84, 72, 83, 128, 70, 73, 70, 84, 72, 128, 70, 73, - 70, 84, 69, 69, 78, 128, 70, 73, 70, 84, 69, 69, 206, 70, 73, 69, 76, 68, - 128, 70, 73, 69, 76, 196, 70, 72, 84, 79, 82, 193, 70, 70, 76, 128, 70, - 70, 73, 128, 70, 69, 85, 88, 128, 70, 69, 85, 70, 69, 85, 65, 69, 84, - 128, 70, 69, 84, 72, 128, 70, 69, 83, 84, 73, 86, 65, 76, 128, 70, 69, - 82, 82, 89, 128, 70, 69, 82, 82, 73, 211, 70, 69, 82, 77, 65, 84, 65, - 128, 70, 69, 82, 77, 65, 84, 193, 70, 69, 79, 200, 70, 69, 78, 199, 70, - 69, 78, 67, 69, 82, 128, 70, 69, 78, 67, 69, 128, 70, 69, 77, 73, 78, 73, - 78, 197, 70, 69, 77, 65, 76, 69, 128, 70, 69, 77, 65, 76, 197, 70, 69, - 76, 76, 79, 87, 83, 72, 73, 80, 128, 70, 69, 73, 128, 70, 69, 72, 213, - 70, 69, 72, 128, 70, 69, 200, 70, 69, 69, 78, 71, 128, 70, 69, 69, 77, - 128, 70, 69, 69, 68, 128, 70, 69, 69, 196, 70, 69, 69, 128, 70, 69, 66, - 82, 85, 65, 82, 89, 128, 70, 69, 65, 84, 72, 69, 82, 128, 70, 69, 65, 84, - 72, 69, 210, 70, 69, 65, 82, 78, 128, 70, 69, 65, 82, 70, 85, 204, 70, - 69, 65, 82, 128, 70, 65, 89, 65, 78, 78, 65, 128, 70, 65, 89, 128, 70, - 65, 88, 128, 70, 65, 216, 70, 65, 84, 73, 71, 85, 69, 128, 70, 65, 84, - 72, 69, 82, 128, 70, 65, 84, 72, 69, 210, 70, 65, 84, 72, 65, 84, 65, 78, - 128, 70, 65, 84, 72, 65, 84, 65, 206, 70, 65, 84, 72, 65, 128, 70, 65, - 84, 72, 193, 70, 65, 84, 128, 70, 65, 83, 84, 128, 70, 65, 82, 83, 201, - 70, 65, 82, 128, 70, 65, 81, 128, 70, 65, 80, 128, 70, 65, 78, 71, 128, - 70, 65, 78, 69, 82, 79, 83, 73, 211, 70, 65, 78, 128, 70, 65, 77, 73, 76, - 89, 128, 70, 65, 77, 128, 70, 65, 76, 76, 69, 206, 70, 65, 76, 65, 70, - 69, 76, 128, 70, 65, 74, 128, 70, 65, 73, 82, 89, 128, 70, 65, 73, 76, - 85, 82, 69, 128, 70, 65, 73, 72, 85, 128, 70, 65, 73, 66, 128, 70, 65, - 72, 82, 69, 78, 72, 69, 73, 84, 128, 70, 65, 67, 84, 79, 82, 89, 128, 70, - 65, 67, 84, 79, 210, 70, 65, 67, 83, 73, 77, 73, 76, 197, 70, 65, 67, 73, - 78, 71, 83, 128, 70, 65, 67, 69, 45, 54, 128, 70, 65, 67, 69, 45, 53, - 128, 70, 65, 67, 69, 45, 52, 128, 70, 65, 67, 69, 45, 51, 128, 70, 65, - 67, 69, 45, 50, 128, 70, 65, 67, 69, 45, 49, 128, 70, 65, 65, 77, 65, 69, - 128, 70, 65, 65, 73, 128, 70, 65, 65, 70, 85, 128, 70, 48, 53, 51, 128, - 70, 48, 53, 50, 128, 70, 48, 53, 49, 67, 128, 70, 48, 53, 49, 66, 128, - 70, 48, 53, 49, 65, 128, 70, 48, 53, 49, 128, 70, 48, 53, 48, 128, 70, - 48, 52, 57, 128, 70, 48, 52, 56, 128, 70, 48, 52, 55, 65, 128, 70, 48, - 52, 55, 128, 70, 48, 52, 54, 65, 128, 70, 48, 52, 54, 128, 70, 48, 52, - 53, 65, 128, 70, 48, 52, 53, 128, 70, 48, 52, 52, 128, 70, 48, 52, 51, - 128, 70, 48, 52, 50, 128, 70, 48, 52, 49, 128, 70, 48, 52, 48, 128, 70, - 48, 51, 57, 128, 70, 48, 51, 56, 65, 128, 70, 48, 51, 56, 128, 70, 48, - 51, 55, 65, 128, 70, 48, 51, 55, 128, 70, 48, 51, 54, 128, 70, 48, 51, - 53, 128, 70, 48, 51, 52, 128, 70, 48, 51, 51, 128, 70, 48, 51, 50, 128, - 70, 48, 51, 49, 65, 128, 70, 48, 51, 49, 128, 70, 48, 51, 48, 128, 70, - 48, 50, 57, 128, 70, 48, 50, 56, 128, 70, 48, 50, 55, 128, 70, 48, 50, - 54, 128, 70, 48, 50, 53, 128, 70, 48, 50, 52, 128, 70, 48, 50, 51, 128, - 70, 48, 50, 50, 128, 70, 48, 50, 49, 65, 128, 70, 48, 50, 49, 128, 70, - 48, 50, 48, 128, 70, 48, 49, 57, 128, 70, 48, 49, 56, 128, 70, 48, 49, - 55, 128, 70, 48, 49, 54, 128, 70, 48, 49, 53, 128, 70, 48, 49, 52, 128, - 70, 48, 49, 51, 65, 128, 70, 48, 49, 51, 128, 70, 48, 49, 50, 128, 70, - 48, 49, 49, 128, 70, 48, 49, 48, 128, 70, 48, 48, 57, 128, 70, 48, 48, - 56, 128, 70, 48, 48, 55, 128, 70, 48, 48, 54, 128, 70, 48, 48, 53, 128, - 70, 48, 48, 52, 128, 70, 48, 48, 51, 128, 70, 48, 48, 50, 128, 70, 48, - 48, 49, 65, 128, 70, 48, 48, 49, 128, 69, 90, 83, 128, 69, 90, 69, 78, - 128, 69, 90, 69, 206, 69, 89, 89, 89, 128, 69, 89, 69, 83, 128, 69, 89, - 69, 211, 69, 89, 69, 76, 65, 83, 72, 69, 211, 69, 89, 69, 71, 76, 65, 83, - 83, 69, 83, 128, 69, 89, 69, 71, 65, 90, 69, 45, 87, 65, 76, 76, 80, 76, - 65, 78, 197, 69, 89, 69, 71, 65, 90, 69, 45, 70, 76, 79, 79, 82, 80, 76, - 65, 78, 197, 69, 89, 69, 66, 82, 79, 87, 211, 69, 89, 69, 66, 82, 79, - 215, 69, 89, 197, 69, 89, 66, 69, 89, 70, 73, 76, 73, 128, 69, 89, 65, - 78, 78, 65, 128, 69, 88, 84, 82, 69, 77, 69, 76, 217, 69, 88, 84, 82, 65, - 84, 69, 82, 82, 69, 83, 84, 82, 73, 65, 204, 69, 88, 84, 82, 65, 45, 76, - 79, 215, 69, 88, 84, 82, 65, 45, 72, 73, 71, 200, 69, 88, 84, 82, 193, - 69, 88, 84, 73, 78, 71, 85, 73, 83, 72, 69, 82, 128, 69, 88, 84, 69, 78, - 83, 73, 79, 78, 128, 69, 88, 84, 69, 78, 68, 69, 68, 128, 69, 88, 84, 69, - 78, 68, 69, 196, 69, 88, 80, 82, 69, 83, 83, 73, 79, 78, 76, 69, 83, 211, - 69, 88, 80, 79, 78, 69, 78, 212, 69, 88, 80, 76, 79, 68, 73, 78, 199, 69, - 88, 79, 128, 69, 88, 207, 69, 88, 73, 83, 84, 83, 128, 69, 88, 73, 83, - 84, 128, 69, 88, 72, 65, 85, 83, 84, 73, 79, 78, 128, 69, 88, 72, 65, 76, - 69, 128, 69, 88, 67, 76, 65, 77, 65, 84, 73, 79, 78, 128, 69, 88, 67, 76, - 65, 77, 65, 84, 73, 79, 206, 69, 88, 67, 73, 84, 69, 77, 69, 78, 84, 128, - 69, 88, 67, 72, 65, 78, 71, 69, 128, 69, 88, 67, 69, 83, 83, 128, 69, 88, - 67, 69, 76, 76, 69, 78, 84, 128, 69, 87, 69, 128, 69, 86, 69, 82, 217, - 69, 86, 69, 82, 71, 82, 69, 69, 206, 69, 86, 69, 78, 73, 78, 71, 128, 69, - 85, 82, 79, 80, 69, 65, 206, 69, 85, 82, 79, 80, 69, 45, 65, 70, 82, 73, - 67, 65, 128, 69, 85, 82, 79, 45, 67, 85, 82, 82, 69, 78, 67, 217, 69, 85, - 82, 207, 69, 85, 76, 69, 210, 69, 85, 45, 85, 128, 69, 85, 45, 79, 128, - 69, 85, 45, 69, 85, 128, 69, 85, 45, 69, 79, 128, 69, 85, 45, 69, 128, - 69, 85, 45, 65, 128, 69, 84, 88, 128, 69, 84, 78, 65, 72, 84, 65, 128, - 69, 84, 72, 69, 204, 69, 84, 69, 82, 79, 206, 69, 84, 69, 82, 78, 73, 84, - 89, 128, 69, 84, 69, 82, 78, 73, 84, 217, 69, 84, 66, 128, 69, 83, 90, - 128, 69, 83, 85, 75, 85, 85, 68, 79, 128, 69, 83, 84, 73, 77, 65, 84, 69, - 83, 128, 69, 83, 84, 73, 77, 65, 84, 69, 196, 69, 83, 72, 69, 51, 128, - 69, 83, 72, 50, 49, 128, 69, 83, 72, 49, 54, 128, 69, 83, 67, 65, 80, 69, + 76, 76, 79, 87, 73, 78, 71, 128, 70, 79, 76, 68, 73, 78, 199, 70, 79, 76, + 68, 69, 82, 128, 70, 79, 76, 68, 69, 196, 70, 79, 71, 71, 89, 128, 70, + 79, 71, 128, 70, 207, 70, 77, 128, 70, 76, 89, 73, 78, 199, 70, 76, 89, + 128, 70, 76, 85, 84, 84, 69, 82, 73, 78, 71, 128, 70, 76, 85, 84, 84, 69, + 82, 73, 78, 199, 70, 76, 85, 84, 69, 128, 70, 76, 85, 83, 72, 69, 196, + 70, 76, 79, 87, 73, 78, 199, 70, 76, 79, 87, 69, 82, 83, 128, 70, 76, 79, + 87, 69, 210, 70, 76, 79, 85, 82, 73, 83, 72, 128, 70, 76, 79, 82, 69, 84, + 84, 69, 128, 70, 76, 79, 82, 65, 204, 70, 76, 79, 80, 80, 217, 70, 76, + 79, 79, 82, 128, 70, 76, 79, 79, 210, 70, 76, 73, 80, 128, 70, 76, 73, + 71, 72, 84, 128, 70, 76, 73, 67, 203, 70, 76, 69, 88, 85, 83, 128, 70, + 76, 69, 88, 69, 196, 70, 76, 69, 88, 128, 70, 76, 69, 85, 82, 79, 78, + 128, 70, 76, 69, 85, 82, 45, 68, 69, 45, 76, 73, 83, 128, 70, 76, 65, 84, + 84, 69, 78, 69, 196, 70, 76, 65, 84, 78, 69, 83, 83, 128, 70, 76, 65, 84, + 66, 82, 69, 65, 68, 128, 70, 76, 65, 83, 72, 128, 70, 76, 65, 77, 73, 78, + 71, 79, 128, 70, 76, 65, 77, 69, 128, 70, 76, 65, 71, 83, 128, 70, 76, + 65, 71, 45, 53, 128, 70, 76, 65, 71, 45, 52, 128, 70, 76, 65, 71, 45, 51, + 128, 70, 76, 65, 71, 45, 50, 128, 70, 76, 65, 71, 45, 49, 128, 70, 76, + 65, 71, 128, 70, 76, 65, 199, 70, 76, 65, 128, 70, 76, 128, 70, 73, 88, + 69, 68, 45, 70, 79, 82, 205, 70, 73, 88, 128, 70, 73, 86, 69, 45, 84, 72, + 73, 82, 84, 89, 128, 70, 73, 86, 69, 45, 76, 73, 78, 197, 70, 73, 86, 69, + 45, 76, 73, 75, 197, 70, 73, 84, 90, 80, 65, 84, 82, 73, 67, 203, 70, 73, + 84, 65, 128, 70, 73, 84, 128, 70, 73, 83, 84, 69, 196, 70, 73, 83, 72, + 73, 78, 199, 70, 73, 83, 72, 72, 79, 79, 75, 128, 70, 73, 83, 72, 72, 79, + 79, 203, 70, 73, 83, 72, 69, 89, 69, 128, 70, 73, 83, 200, 70, 73, 82, + 83, 212, 70, 73, 82, 73, 128, 70, 73, 82, 69, 87, 79, 82, 75, 83, 128, + 70, 73, 82, 69, 87, 79, 82, 203, 70, 73, 82, 69, 67, 82, 65, 67, 75, 69, + 82, 128, 70, 73, 82, 69, 128, 70, 73, 82, 197, 70, 73, 80, 128, 70, 73, + 78, 73, 84, 197, 70, 73, 78, 71, 69, 82, 83, 128, 70, 73, 78, 71, 69, 82, + 211, 70, 73, 78, 71, 69, 82, 78, 65, 73, 76, 83, 128, 70, 73, 78, 71, 69, + 82, 69, 196, 70, 73, 78, 71, 69, 82, 45, 80, 79, 83, 212, 70, 73, 78, 71, + 69, 82, 128, 70, 73, 78, 71, 69, 210, 70, 73, 78, 65, 78, 67, 73, 65, 76, + 128, 70, 73, 78, 65, 76, 128, 70, 73, 76, 205, 70, 73, 76, 76, 69, 82, + 45, 50, 128, 70, 73, 76, 76, 69, 82, 45, 49, 128, 70, 73, 76, 76, 69, 82, + 128, 70, 73, 76, 76, 69, 196, 70, 73, 76, 76, 128, 70, 73, 76, 204, 70, + 73, 76, 197, 70, 73, 73, 128, 70, 73, 71, 85, 82, 69, 45, 51, 128, 70, + 73, 71, 85, 82, 69, 45, 50, 128, 70, 73, 71, 85, 82, 69, 45, 49, 128, 70, + 73, 71, 85, 82, 69, 128, 70, 73, 71, 85, 82, 197, 70, 73, 71, 72, 84, + 128, 70, 73, 70, 84, 89, 128, 70, 73, 70, 84, 217, 70, 73, 70, 84, 72, + 83, 128, 70, 73, 70, 84, 72, 128, 70, 73, 70, 84, 69, 69, 78, 128, 70, + 73, 70, 84, 69, 69, 206, 70, 73, 69, 76, 68, 128, 70, 73, 69, 76, 196, + 70, 72, 84, 79, 82, 193, 70, 70, 76, 128, 70, 70, 73, 128, 70, 69, 85, + 88, 128, 70, 69, 85, 70, 69, 85, 65, 69, 84, 128, 70, 69, 84, 72, 128, + 70, 69, 83, 84, 73, 86, 65, 76, 128, 70, 69, 82, 82, 89, 128, 70, 69, 82, + 82, 73, 211, 70, 69, 82, 77, 65, 84, 65, 128, 70, 69, 82, 77, 65, 84, + 193, 70, 69, 79, 200, 70, 69, 78, 199, 70, 69, 78, 67, 69, 82, 128, 70, + 69, 78, 67, 69, 128, 70, 69, 77, 73, 78, 73, 78, 197, 70, 69, 77, 65, 76, + 69, 128, 70, 69, 77, 65, 76, 197, 70, 69, 76, 76, 79, 87, 83, 72, 73, 80, + 128, 70, 69, 73, 128, 70, 69, 72, 213, 70, 69, 72, 128, 70, 69, 200, 70, + 69, 69, 78, 71, 128, 70, 69, 69, 77, 128, 70, 69, 69, 68, 128, 70, 69, + 69, 196, 70, 69, 69, 128, 70, 69, 66, 82, 85, 65, 82, 89, 128, 70, 69, + 65, 84, 72, 69, 82, 128, 70, 69, 65, 84, 72, 69, 210, 70, 69, 65, 82, 78, + 128, 70, 69, 65, 82, 70, 85, 204, 70, 69, 65, 82, 128, 70, 65, 89, 65, + 78, 78, 65, 128, 70, 65, 89, 128, 70, 65, 88, 128, 70, 65, 216, 70, 65, + 84, 73, 71, 85, 69, 128, 70, 65, 84, 72, 69, 82, 128, 70, 65, 84, 72, 69, + 210, 70, 65, 84, 72, 65, 84, 65, 78, 128, 70, 65, 84, 72, 65, 84, 65, + 206, 70, 65, 84, 72, 65, 128, 70, 65, 84, 72, 193, 70, 65, 84, 128, 70, + 65, 83, 84, 128, 70, 65, 82, 83, 201, 70, 65, 82, 128, 70, 65, 81, 128, + 70, 65, 80, 128, 70, 65, 78, 71, 128, 70, 65, 78, 69, 82, 79, 83, 73, + 211, 70, 65, 78, 128, 70, 65, 77, 73, 76, 89, 128, 70, 65, 77, 128, 70, + 65, 76, 76, 69, 206, 70, 65, 76, 65, 70, 69, 76, 128, 70, 65, 74, 128, + 70, 65, 73, 82, 89, 128, 70, 65, 73, 76, 85, 82, 69, 128, 70, 65, 73, 72, + 85, 128, 70, 65, 73, 66, 128, 70, 65, 72, 82, 69, 78, 72, 69, 73, 84, + 128, 70, 65, 67, 84, 79, 82, 89, 128, 70, 65, 67, 84, 79, 210, 70, 65, + 67, 83, 73, 77, 73, 76, 197, 70, 65, 67, 73, 78, 71, 83, 128, 70, 65, 67, + 69, 45, 54, 128, 70, 65, 67, 69, 45, 53, 128, 70, 65, 67, 69, 45, 52, + 128, 70, 65, 67, 69, 45, 51, 128, 70, 65, 67, 69, 45, 50, 128, 70, 65, + 67, 69, 45, 49, 128, 70, 65, 65, 77, 65, 69, 128, 70, 65, 65, 73, 128, + 70, 65, 65, 70, 85, 128, 70, 48, 53, 51, 128, 70, 48, 53, 50, 128, 70, + 48, 53, 49, 67, 128, 70, 48, 53, 49, 66, 128, 70, 48, 53, 49, 65, 128, + 70, 48, 53, 49, 128, 70, 48, 53, 48, 128, 70, 48, 52, 57, 128, 70, 48, + 52, 56, 128, 70, 48, 52, 55, 65, 128, 70, 48, 52, 55, 128, 70, 48, 52, + 54, 65, 128, 70, 48, 52, 54, 128, 70, 48, 52, 53, 65, 128, 70, 48, 52, + 53, 128, 70, 48, 52, 52, 128, 70, 48, 52, 51, 128, 70, 48, 52, 50, 128, + 70, 48, 52, 49, 128, 70, 48, 52, 48, 128, 70, 48, 51, 57, 128, 70, 48, + 51, 56, 65, 128, 70, 48, 51, 56, 128, 70, 48, 51, 55, 65, 128, 70, 48, + 51, 55, 128, 70, 48, 51, 54, 128, 70, 48, 51, 53, 128, 70, 48, 51, 52, + 128, 70, 48, 51, 51, 128, 70, 48, 51, 50, 128, 70, 48, 51, 49, 65, 128, + 70, 48, 51, 49, 128, 70, 48, 51, 48, 128, 70, 48, 50, 57, 128, 70, 48, + 50, 56, 128, 70, 48, 50, 55, 128, 70, 48, 50, 54, 128, 70, 48, 50, 53, + 128, 70, 48, 50, 52, 128, 70, 48, 50, 51, 128, 70, 48, 50, 50, 128, 70, + 48, 50, 49, 65, 128, 70, 48, 50, 49, 128, 70, 48, 50, 48, 128, 70, 48, + 49, 57, 128, 70, 48, 49, 56, 128, 70, 48, 49, 55, 128, 70, 48, 49, 54, + 128, 70, 48, 49, 53, 128, 70, 48, 49, 52, 128, 70, 48, 49, 51, 65, 128, + 70, 48, 49, 51, 128, 70, 48, 49, 50, 128, 70, 48, 49, 49, 128, 70, 48, + 49, 48, 128, 70, 48, 48, 57, 128, 70, 48, 48, 56, 128, 70, 48, 48, 55, + 128, 70, 48, 48, 54, 128, 70, 48, 48, 53, 128, 70, 48, 48, 52, 128, 70, + 48, 48, 51, 128, 70, 48, 48, 50, 128, 70, 48, 48, 49, 65, 128, 70, 48, + 48, 49, 128, 69, 90, 83, 128, 69, 90, 69, 78, 128, 69, 90, 69, 206, 69, + 89, 89, 89, 128, 69, 89, 69, 83, 128, 69, 89, 69, 211, 69, 89, 69, 76, + 65, 83, 72, 69, 211, 69, 89, 69, 71, 76, 65, 83, 83, 69, 83, 128, 69, 89, + 69, 71, 65, 90, 69, 45, 87, 65, 76, 76, 80, 76, 65, 78, 197, 69, 89, 69, + 71, 65, 90, 69, 45, 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, 69, 89, 69, + 66, 82, 79, 87, 211, 69, 89, 69, 66, 82, 79, 215, 69, 89, 197, 69, 89, + 66, 69, 89, 70, 73, 76, 73, 128, 69, 89, 65, 78, 78, 65, 128, 69, 88, 84, + 82, 69, 77, 69, 76, 217, 69, 88, 84, 82, 65, 84, 69, 82, 82, 69, 83, 84, + 82, 73, 65, 204, 69, 88, 84, 82, 65, 45, 76, 79, 215, 69, 88, 84, 82, 65, + 45, 72, 73, 71, 200, 69, 88, 84, 82, 193, 69, 88, 84, 73, 78, 71, 85, 73, + 83, 72, 69, 82, 128, 69, 88, 84, 69, 78, 83, 73, 79, 78, 128, 69, 88, 84, + 69, 78, 68, 69, 68, 128, 69, 88, 84, 69, 78, 68, 69, 196, 69, 88, 80, 82, + 69, 83, 83, 73, 79, 78, 76, 69, 83, 211, 69, 88, 80, 79, 78, 69, 78, 212, + 69, 88, 80, 76, 79, 68, 73, 78, 199, 69, 88, 79, 128, 69, 88, 207, 69, + 88, 73, 83, 84, 83, 128, 69, 88, 73, 83, 84, 128, 69, 88, 72, 65, 85, 83, + 84, 73, 79, 78, 128, 69, 88, 72, 65, 76, 69, 128, 69, 88, 67, 76, 65, 77, + 65, 84, 73, 79, 78, 128, 69, 88, 67, 76, 65, 77, 65, 84, 73, 79, 206, 69, + 88, 67, 73, 84, 69, 77, 69, 78, 84, 128, 69, 88, 67, 72, 65, 78, 71, 69, + 128, 69, 88, 67, 69, 83, 83, 128, 69, 88, 67, 69, 76, 76, 69, 78, 84, + 128, 69, 87, 69, 128, 69, 86, 69, 82, 217, 69, 86, 69, 82, 71, 82, 69, + 69, 206, 69, 86, 69, 78, 73, 78, 71, 128, 69, 85, 82, 79, 80, 69, 65, + 206, 69, 85, 82, 79, 80, 69, 45, 65, 70, 82, 73, 67, 65, 128, 69, 85, 82, + 79, 45, 67, 85, 82, 82, 69, 78, 67, 217, 69, 85, 82, 207, 69, 85, 76, 69, + 210, 69, 85, 45, 85, 128, 69, 85, 45, 79, 128, 69, 85, 45, 69, 85, 128, + 69, 85, 45, 69, 79, 128, 69, 85, 45, 69, 128, 69, 85, 45, 65, 128, 69, + 84, 88, 128, 69, 84, 84, 128, 69, 84, 78, 65, 72, 84, 65, 128, 69, 84, + 72, 69, 204, 69, 84, 69, 82, 79, 206, 69, 84, 69, 82, 78, 73, 84, 89, + 128, 69, 84, 69, 82, 78, 73, 84, 217, 69, 84, 66, 128, 69, 83, 90, 128, + 69, 83, 85, 75, 85, 85, 68, 79, 128, 69, 83, 84, 73, 77, 65, 84, 69, 83, + 128, 69, 83, 84, 73, 77, 65, 84, 69, 196, 69, 83, 72, 69, 51, 128, 69, + 83, 72, 50, 49, 128, 69, 83, 72, 49, 54, 128, 69, 83, 67, 65, 80, 69, 128, 69, 83, 67, 128, 69, 83, 65, 128, 69, 83, 45, 84, 69, 128, 69, 83, 45, 51, 128, 69, 83, 45, 50, 128, 69, 83, 45, 49, 128, 69, 82, 82, 79, 82, 45, 66, 65, 82, 82, 69, 196, 69, 82, 82, 128, 69, 82, 73, 211, 69, @@ -4464,101 +4481,102 @@ static const unsigned char lexicon[] = { 89, 128, 69, 71, 73, 82, 128, 69, 71, 71, 83, 128, 69, 71, 71, 128, 69, 69, 89, 65, 78, 78, 65, 128, 69, 69, 75, 65, 65, 128, 69, 69, 72, 128, 69, 69, 66, 69, 69, 70, 73, 76, 73, 128, 69, 68, 73, 84, 79, 82, 73, 65, - 204, 69, 68, 73, 78, 128, 69, 68, 68, 128, 69, 67, 83, 128, 69, 66, 69, - 70, 73, 76, 73, 128, 69, 65, 83, 84, 69, 82, 206, 69, 65, 83, 84, 128, - 69, 65, 83, 212, 69, 65, 82, 84, 72, 76, 217, 69, 65, 82, 84, 72, 128, - 69, 65, 82, 84, 200, 69, 65, 82, 76, 217, 69, 65, 77, 72, 65, 78, 67, 72, - 79, 76, 76, 128, 69, 65, 71, 76, 69, 128, 69, 65, 68, 72, 65, 68, 72, - 128, 69, 65, 66, 72, 65, 68, 72, 128, 69, 178, 69, 48, 51, 56, 128, 69, - 48, 51, 55, 128, 69, 48, 51, 54, 128, 69, 48, 51, 52, 65, 128, 69, 48, - 51, 52, 128, 69, 48, 51, 51, 128, 69, 48, 51, 50, 128, 69, 48, 51, 49, - 128, 69, 48, 51, 48, 128, 69, 48, 50, 57, 128, 69, 48, 50, 56, 65, 128, - 69, 48, 50, 56, 128, 69, 48, 50, 55, 128, 69, 48, 50, 54, 128, 69, 48, - 50, 53, 128, 69, 48, 50, 52, 128, 69, 48, 50, 51, 128, 69, 48, 50, 50, - 128, 69, 48, 50, 49, 128, 69, 48, 50, 48, 65, 128, 69, 48, 50, 48, 128, - 69, 48, 49, 57, 128, 69, 48, 49, 56, 128, 69, 48, 49, 55, 65, 128, 69, - 48, 49, 55, 128, 69, 48, 49, 54, 65, 128, 69, 48, 49, 54, 128, 69, 48, - 49, 53, 128, 69, 48, 49, 52, 128, 69, 48, 49, 51, 128, 69, 48, 49, 50, - 128, 69, 48, 49, 49, 128, 69, 48, 49, 48, 128, 69, 48, 48, 57, 65, 128, - 69, 48, 48, 57, 128, 69, 48, 48, 56, 65, 128, 69, 48, 48, 56, 128, 69, - 48, 48, 55, 128, 69, 48, 48, 54, 128, 69, 48, 48, 53, 128, 69, 48, 48, - 52, 128, 69, 48, 48, 51, 128, 69, 48, 48, 50, 128, 69, 48, 48, 49, 128, - 69, 45, 77, 65, 73, 204, 68, 90, 90, 72, 69, 128, 68, 90, 90, 69, 128, - 68, 90, 90, 65, 128, 68, 90, 89, 73, 128, 68, 90, 89, 65, 89, 128, 68, - 90, 87, 69, 128, 68, 90, 85, 128, 68, 90, 79, 128, 68, 90, 74, 69, 128, - 68, 90, 73, 84, 65, 128, 68, 90, 73, 128, 68, 90, 72, 79, 73, 128, 68, - 90, 72, 69, 128, 68, 90, 72, 65, 128, 68, 90, 69, 76, 79, 128, 68, 90, - 69, 69, 128, 68, 90, 69, 128, 68, 90, 65, 89, 128, 68, 90, 65, 65, 128, - 68, 90, 65, 128, 68, 90, 128, 68, 218, 68, 89, 79, 128, 68, 89, 207, 68, - 89, 78, 65, 77, 73, 195, 68, 89, 69, 72, 128, 68, 89, 69, 200, 68, 89, - 65, 78, 128, 68, 87, 79, 128, 68, 87, 69, 128, 68, 87, 65, 128, 68, 86, - 85, 77, 89, 193, 68, 86, 79, 69, 84, 79, 67, 72, 73, 69, 128, 68, 86, 79, - 69, 67, 72, 69, 76, 78, 79, 80, 79, 86, 79, 68, 78, 65, 89, 65, 128, 68, - 86, 79, 69, 67, 72, 69, 76, 78, 79, 80, 79, 86, 79, 68, 78, 65, 89, 193, - 68, 86, 79, 69, 67, 72, 69, 76, 78, 79, 75, 82, 89, 90, 72, 69, 86, 65, - 89, 65, 128, 68, 86, 79, 69, 67, 72, 69, 76, 78, 65, 89, 65, 128, 68, 86, - 79, 69, 67, 72, 69, 76, 78, 65, 89, 193, 68, 86, 73, 83, 86, 65, 82, 65, - 128, 68, 86, 68, 128, 68, 86, 193, 68, 86, 128, 68, 85, 84, 73, 69, 83, - 128, 68, 85, 83, 75, 128, 68, 85, 83, 72, 69, 78, 78, 65, 128, 68, 85, - 82, 65, 84, 73, 79, 78, 128, 68, 85, 82, 50, 128, 68, 85, 80, 79, 78, 68, - 73, 85, 211, 68, 85, 79, 88, 128, 68, 85, 79, 128, 68, 85, 78, 52, 128, - 68, 85, 78, 51, 128, 68, 85, 78, 179, 68, 85, 77, 80, 76, 73, 78, 71, - 128, 68, 85, 77, 128, 68, 85, 204, 68, 85, 72, 128, 68, 85, 71, 85, 68, - 128, 68, 85, 199, 68, 85, 68, 65, 128, 68, 85, 67, 75, 128, 68, 85, 66, - 50, 128, 68, 85, 66, 128, 68, 85, 194, 68, 82, 89, 128, 68, 82, 217, 68, - 82, 85, 77, 83, 84, 73, 67, 75, 83, 128, 68, 82, 85, 77, 128, 68, 82, 85, - 205, 68, 82, 79, 80, 83, 128, 68, 82, 79, 80, 76, 69, 84, 128, 68, 82, - 79, 80, 45, 83, 72, 65, 68, 79, 87, 69, 196, 68, 82, 79, 208, 68, 82, 79, - 79, 76, 73, 78, 199, 68, 82, 79, 77, 69, 68, 65, 82, 217, 68, 82, 73, 86, - 69, 128, 68, 82, 73, 86, 197, 68, 82, 73, 78, 75, 128, 68, 82, 73, 204, - 68, 82, 69, 83, 83, 128, 68, 82, 69, 65, 77, 217, 68, 82, 65, 85, 71, 72, - 84, 211, 68, 82, 65, 77, 128, 68, 82, 65, 205, 68, 82, 65, 71, 79, 78, - 128, 68, 82, 65, 71, 79, 206, 68, 82, 65, 70, 84, 73, 78, 199, 68, 82, - 65, 67, 72, 77, 65, 83, 128, 68, 82, 65, 67, 72, 77, 65, 128, 68, 82, 65, - 67, 72, 77, 193, 68, 79, 87, 78, 87, 65, 82, 68, 83, 128, 68, 79, 87, 78, - 87, 65, 82, 68, 211, 68, 79, 87, 78, 87, 65, 82, 196, 68, 79, 87, 78, 83, - 67, 65, 76, 73, 78, 199, 68, 79, 87, 78, 45, 80, 79, 73, 78, 84, 73, 78, - 199, 68, 79, 87, 78, 128, 68, 79, 86, 69, 128, 68, 79, 86, 197, 68, 79, - 85, 71, 72, 78, 85, 84, 128, 68, 79, 85, 66, 84, 128, 68, 79, 85, 66, 76, - 69, 196, 68, 79, 85, 66, 76, 69, 45, 83, 84, 82, 85, 67, 203, 68, 79, 85, - 66, 76, 69, 45, 76, 73, 78, 69, 196, 68, 79, 85, 66, 76, 69, 45, 76, 73, - 78, 197, 68, 79, 85, 66, 76, 69, 45, 69, 78, 68, 69, 196, 68, 79, 85, 66, - 76, 69, 128, 68, 79, 84, 84, 69, 68, 45, 80, 128, 68, 79, 84, 84, 69, 68, - 45, 78, 128, 68, 79, 84, 84, 69, 68, 45, 76, 128, 68, 79, 84, 84, 69, 68, - 128, 68, 79, 84, 84, 69, 196, 68, 79, 84, 83, 45, 56, 128, 68, 79, 84, - 83, 45, 55, 56, 128, 68, 79, 84, 83, 45, 55, 128, 68, 79, 84, 83, 45, 54, - 56, 128, 68, 79, 84, 83, 45, 54, 55, 56, 128, 68, 79, 84, 83, 45, 54, 55, - 128, 68, 79, 84, 83, 45, 54, 128, 68, 79, 84, 83, 45, 53, 56, 128, 68, - 79, 84, 83, 45, 53, 55, 56, 128, 68, 79, 84, 83, 45, 53, 55, 128, 68, 79, - 84, 83, 45, 53, 54, 56, 128, 68, 79, 84, 83, 45, 53, 54, 55, 56, 128, 68, - 79, 84, 83, 45, 53, 54, 55, 128, 68, 79, 84, 83, 45, 53, 54, 128, 68, 79, - 84, 83, 45, 53, 128, 68, 79, 84, 83, 45, 52, 56, 128, 68, 79, 84, 83, 45, - 52, 55, 56, 128, 68, 79, 84, 83, 45, 52, 55, 128, 68, 79, 84, 83, 45, 52, - 54, 56, 128, 68, 79, 84, 83, 45, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, - 52, 54, 55, 128, 68, 79, 84, 83, 45, 52, 54, 128, 68, 79, 84, 83, 45, 52, - 53, 56, 128, 68, 79, 84, 83, 45, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, - 52, 53, 55, 128, 68, 79, 84, 83, 45, 52, 53, 54, 56, 128, 68, 79, 84, 83, - 45, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 52, 53, 54, 55, 128, 68, - 79, 84, 83, 45, 52, 53, 54, 128, 68, 79, 84, 83, 45, 52, 53, 128, 68, 79, - 84, 83, 45, 52, 128, 68, 79, 84, 83, 45, 51, 56, 128, 68, 79, 84, 83, 45, - 51, 55, 56, 128, 68, 79, 84, 83, 45, 51, 55, 128, 68, 79, 84, 83, 45, 51, - 54, 56, 128, 68, 79, 84, 83, 45, 51, 54, 55, 56, 128, 68, 79, 84, 83, 45, - 51, 54, 55, 128, 68, 79, 84, 83, 45, 51, 54, 128, 68, 79, 84, 83, 45, 51, - 53, 56, 128, 68, 79, 84, 83, 45, 51, 53, 55, 56, 128, 68, 79, 84, 83, 45, - 51, 53, 55, 128, 68, 79, 84, 83, 45, 51, 53, 54, 56, 128, 68, 79, 84, 83, - 45, 51, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 53, 54, 55, 128, 68, - 79, 84, 83, 45, 51, 53, 54, 128, 68, 79, 84, 83, 45, 51, 53, 128, 68, 79, - 84, 83, 45, 51, 52, 56, 128, 68, 79, 84, 83, 45, 51, 52, 55, 56, 128, 68, - 79, 84, 83, 45, 51, 52, 55, 128, 68, 79, 84, 83, 45, 51, 52, 54, 56, 128, - 68, 79, 84, 83, 45, 51, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 52, - 54, 55, 128, 68, 79, 84, 83, 45, 51, 52, 54, 128, 68, 79, 84, 83, 45, 51, - 52, 53, 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, 55, 56, 128, 68, 79, 84, - 83, 45, 51, 52, 53, 55, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 56, 128, - 68, 79, 84, 83, 45, 51, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, - 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 128, 68, 79, 84, - 83, 45, 51, 52, 53, 128, 68, 79, 84, 83, 45, 51, 52, 128, 68, 79, 84, 83, - 45, 51, 128, 68, 79, 84, 83, 45, 50, 56, 128, 68, 79, 84, 83, 45, 50, 55, - 56, 128, 68, 79, 84, 83, 45, 50, 55, 128, 68, 79, 84, 83, 45, 50, 54, 56, + 204, 69, 68, 73, 78, 128, 69, 68, 68, 128, 69, 67, 83, 128, 69, 67, 76, + 73, 80, 83, 69, 128, 69, 66, 69, 70, 73, 76, 73, 128, 69, 65, 83, 84, 69, + 82, 206, 69, 65, 83, 84, 128, 69, 65, 83, 212, 69, 65, 82, 84, 72, 76, + 217, 69, 65, 82, 84, 72, 128, 69, 65, 82, 84, 200, 69, 65, 82, 76, 217, + 69, 65, 77, 72, 65, 78, 67, 72, 79, 76, 76, 128, 69, 65, 71, 76, 69, 128, + 69, 65, 68, 72, 65, 68, 72, 128, 69, 65, 66, 72, 65, 68, 72, 128, 69, + 178, 69, 48, 51, 56, 128, 69, 48, 51, 55, 128, 69, 48, 51, 54, 128, 69, + 48, 51, 52, 65, 128, 69, 48, 51, 52, 128, 69, 48, 51, 51, 128, 69, 48, + 51, 50, 128, 69, 48, 51, 49, 128, 69, 48, 51, 48, 128, 69, 48, 50, 57, + 128, 69, 48, 50, 56, 65, 128, 69, 48, 50, 56, 128, 69, 48, 50, 55, 128, + 69, 48, 50, 54, 128, 69, 48, 50, 53, 128, 69, 48, 50, 52, 128, 69, 48, + 50, 51, 128, 69, 48, 50, 50, 128, 69, 48, 50, 49, 128, 69, 48, 50, 48, + 65, 128, 69, 48, 50, 48, 128, 69, 48, 49, 57, 128, 69, 48, 49, 56, 128, + 69, 48, 49, 55, 65, 128, 69, 48, 49, 55, 128, 69, 48, 49, 54, 65, 128, + 69, 48, 49, 54, 128, 69, 48, 49, 53, 128, 69, 48, 49, 52, 128, 69, 48, + 49, 51, 128, 69, 48, 49, 50, 128, 69, 48, 49, 49, 128, 69, 48, 49, 48, + 128, 69, 48, 48, 57, 65, 128, 69, 48, 48, 57, 128, 69, 48, 48, 56, 65, + 128, 69, 48, 48, 56, 128, 69, 48, 48, 55, 128, 69, 48, 48, 54, 128, 69, + 48, 48, 53, 128, 69, 48, 48, 52, 128, 69, 48, 48, 51, 128, 69, 48, 48, + 50, 128, 69, 48, 48, 49, 128, 69, 45, 77, 65, 73, 204, 68, 90, 90, 72, + 69, 128, 68, 90, 90, 69, 128, 68, 90, 90, 65, 128, 68, 90, 89, 73, 128, + 68, 90, 89, 65, 89, 128, 68, 90, 87, 69, 128, 68, 90, 85, 128, 68, 90, + 79, 128, 68, 90, 74, 69, 128, 68, 90, 73, 84, 65, 128, 68, 90, 73, 128, + 68, 90, 72, 79, 73, 128, 68, 90, 72, 69, 128, 68, 90, 72, 65, 128, 68, + 90, 69, 76, 79, 128, 68, 90, 69, 69, 128, 68, 90, 69, 128, 68, 90, 65, + 89, 128, 68, 90, 65, 65, 128, 68, 90, 65, 128, 68, 90, 128, 68, 218, 68, + 89, 79, 128, 68, 89, 207, 68, 89, 78, 65, 77, 73, 195, 68, 89, 69, 72, + 128, 68, 89, 69, 200, 68, 89, 65, 78, 128, 68, 87, 79, 128, 68, 87, 69, + 128, 68, 87, 65, 128, 68, 86, 85, 77, 89, 193, 68, 86, 79, 69, 84, 79, + 67, 72, 73, 69, 128, 68, 86, 79, 69, 67, 72, 69, 76, 78, 79, 80, 79, 86, + 79, 68, 78, 65, 89, 65, 128, 68, 86, 79, 69, 67, 72, 69, 76, 78, 79, 80, + 79, 86, 79, 68, 78, 65, 89, 193, 68, 86, 79, 69, 67, 72, 69, 76, 78, 79, + 75, 82, 89, 90, 72, 69, 86, 65, 89, 65, 128, 68, 86, 79, 69, 67, 72, 69, + 76, 78, 65, 89, 65, 128, 68, 86, 79, 69, 67, 72, 69, 76, 78, 65, 89, 193, + 68, 86, 73, 83, 86, 65, 82, 65, 128, 68, 86, 68, 128, 68, 86, 193, 68, + 86, 128, 68, 85, 84, 73, 69, 83, 128, 68, 85, 83, 75, 128, 68, 85, 83, + 72, 69, 78, 78, 65, 128, 68, 85, 82, 65, 84, 73, 79, 78, 128, 68, 85, 82, + 50, 128, 68, 85, 80, 79, 78, 68, 73, 85, 211, 68, 85, 79, 88, 128, 68, + 85, 79, 128, 68, 85, 78, 52, 128, 68, 85, 78, 51, 128, 68, 85, 78, 179, + 68, 85, 77, 80, 76, 73, 78, 71, 128, 68, 85, 77, 128, 68, 85, 204, 68, + 85, 72, 128, 68, 85, 71, 85, 68, 128, 68, 85, 199, 68, 85, 68, 65, 128, + 68, 85, 67, 75, 128, 68, 85, 66, 50, 128, 68, 85, 66, 128, 68, 85, 194, + 68, 82, 89, 128, 68, 82, 217, 68, 82, 85, 77, 83, 84, 73, 67, 75, 83, + 128, 68, 82, 85, 77, 128, 68, 82, 85, 205, 68, 82, 79, 80, 83, 128, 68, + 82, 79, 80, 76, 69, 84, 128, 68, 82, 79, 80, 45, 83, 72, 65, 68, 79, 87, + 69, 196, 68, 82, 79, 208, 68, 82, 79, 79, 76, 73, 78, 199, 68, 82, 79, + 77, 69, 68, 65, 82, 217, 68, 82, 73, 86, 69, 128, 68, 82, 73, 86, 197, + 68, 82, 73, 78, 75, 128, 68, 82, 73, 204, 68, 82, 69, 83, 83, 128, 68, + 82, 69, 65, 77, 217, 68, 82, 65, 85, 71, 72, 84, 211, 68, 82, 65, 77, + 128, 68, 82, 65, 205, 68, 82, 65, 71, 79, 78, 128, 68, 82, 65, 71, 79, + 206, 68, 82, 65, 70, 84, 73, 78, 199, 68, 82, 65, 67, 72, 77, 65, 83, + 128, 68, 82, 65, 67, 72, 77, 65, 128, 68, 82, 65, 67, 72, 77, 193, 68, + 79, 87, 78, 87, 65, 82, 68, 83, 128, 68, 79, 87, 78, 87, 65, 82, 68, 211, + 68, 79, 87, 78, 87, 65, 82, 196, 68, 79, 87, 78, 83, 67, 65, 76, 73, 78, + 199, 68, 79, 87, 78, 45, 80, 79, 73, 78, 84, 73, 78, 199, 68, 79, 87, 78, + 128, 68, 79, 86, 69, 128, 68, 79, 86, 197, 68, 79, 85, 71, 72, 78, 85, + 84, 128, 68, 79, 85, 66, 84, 128, 68, 79, 85, 66, 76, 69, 196, 68, 79, + 85, 66, 76, 69, 45, 83, 84, 82, 85, 67, 203, 68, 79, 85, 66, 76, 69, 45, + 76, 73, 78, 69, 196, 68, 79, 85, 66, 76, 69, 45, 76, 73, 78, 197, 68, 79, + 85, 66, 76, 69, 45, 69, 78, 68, 69, 196, 68, 79, 85, 66, 76, 69, 128, 68, + 79, 84, 84, 69, 68, 45, 80, 128, 68, 79, 84, 84, 69, 68, 45, 78, 128, 68, + 79, 84, 84, 69, 68, 45, 76, 128, 68, 79, 84, 84, 69, 68, 128, 68, 79, 84, + 84, 69, 196, 68, 79, 84, 83, 45, 56, 128, 68, 79, 84, 83, 45, 55, 56, + 128, 68, 79, 84, 83, 45, 55, 128, 68, 79, 84, 83, 45, 54, 56, 128, 68, + 79, 84, 83, 45, 54, 55, 56, 128, 68, 79, 84, 83, 45, 54, 55, 128, 68, 79, + 84, 83, 45, 54, 128, 68, 79, 84, 83, 45, 53, 56, 128, 68, 79, 84, 83, 45, + 53, 55, 56, 128, 68, 79, 84, 83, 45, 53, 55, 128, 68, 79, 84, 83, 45, 53, + 54, 56, 128, 68, 79, 84, 83, 45, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, + 53, 54, 55, 128, 68, 79, 84, 83, 45, 53, 54, 128, 68, 79, 84, 83, 45, 53, + 128, 68, 79, 84, 83, 45, 52, 56, 128, 68, 79, 84, 83, 45, 52, 55, 56, + 128, 68, 79, 84, 83, 45, 52, 55, 128, 68, 79, 84, 83, 45, 52, 54, 56, + 128, 68, 79, 84, 83, 45, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 52, 54, + 55, 128, 68, 79, 84, 83, 45, 52, 54, 128, 68, 79, 84, 83, 45, 52, 53, 56, + 128, 68, 79, 84, 83, 45, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, 52, 53, + 55, 128, 68, 79, 84, 83, 45, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 52, + 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 52, 53, 54, 55, 128, 68, 79, 84, + 83, 45, 52, 53, 54, 128, 68, 79, 84, 83, 45, 52, 53, 128, 68, 79, 84, 83, + 45, 52, 128, 68, 79, 84, 83, 45, 51, 56, 128, 68, 79, 84, 83, 45, 51, 55, + 56, 128, 68, 79, 84, 83, 45, 51, 55, 128, 68, 79, 84, 83, 45, 51, 54, 56, + 128, 68, 79, 84, 83, 45, 51, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 54, + 55, 128, 68, 79, 84, 83, 45, 51, 54, 128, 68, 79, 84, 83, 45, 51, 53, 56, + 128, 68, 79, 84, 83, 45, 51, 53, 55, 56, 128, 68, 79, 84, 83, 45, 51, 53, + 55, 128, 68, 79, 84, 83, 45, 51, 53, 54, 56, 128, 68, 79, 84, 83, 45, 51, + 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 53, 54, 55, 128, 68, 79, 84, + 83, 45, 51, 53, 54, 128, 68, 79, 84, 83, 45, 51, 53, 128, 68, 79, 84, 83, + 45, 51, 52, 56, 128, 68, 79, 84, 83, 45, 51, 52, 55, 56, 128, 68, 79, 84, + 83, 45, 51, 52, 55, 128, 68, 79, 84, 83, 45, 51, 52, 54, 56, 128, 68, 79, + 84, 83, 45, 51, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 52, 54, 55, + 128, 68, 79, 84, 83, 45, 51, 52, 54, 128, 68, 79, 84, 83, 45, 51, 52, 53, + 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, + 51, 52, 53, 55, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 56, 128, 68, 79, + 84, 83, 45, 51, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, + 54, 55, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 128, 68, 79, 84, 83, 45, + 51, 52, 53, 128, 68, 79, 84, 83, 45, 51, 52, 128, 68, 79, 84, 83, 45, 51, + 128, 68, 79, 84, 83, 45, 50, 56, 128, 68, 79, 84, 83, 45, 50, 55, 56, + 128, 68, 79, 84, 83, 45, 50, 55, 128, 68, 79, 84, 83, 45, 50, 54, 56, 128, 68, 79, 84, 83, 45, 50, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 54, 55, 128, 68, 79, 84, 83, 45, 50, 54, 128, 68, 79, 84, 83, 45, 50, 53, 56, 128, 68, 79, 84, 83, 45, 50, 53, 55, 56, 128, 68, 79, 84, 83, 45, 50, 53, @@ -4669,172 +4687,173 @@ static const unsigned char lexicon[] = { 128, 68, 79, 84, 83, 45, 49, 50, 51, 128, 68, 79, 84, 83, 45, 49, 50, 128, 68, 79, 84, 83, 45, 49, 128, 68, 79, 84, 83, 128, 68, 79, 84, 76, 69, 83, 211, 68, 79, 82, 85, 128, 68, 79, 82, 79, 77, 197, 68, 79, 79, - 82, 128, 68, 79, 79, 78, 71, 128, 68, 79, 78, 71, 128, 68, 79, 77, 73, - 78, 207, 68, 79, 77, 65, 73, 206, 68, 79, 76, 80, 72, 73, 78, 128, 68, - 79, 76, 76, 83, 128, 68, 79, 76, 76, 65, 210, 68, 79, 76, 73, 85, 77, - 128, 68, 79, 75, 77, 65, 73, 128, 68, 79, 73, 84, 128, 68, 79, 73, 78, - 199, 68, 79, 73, 128, 68, 79, 71, 82, 193, 68, 79, 71, 128, 68, 79, 199, - 68, 79, 69, 211, 68, 79, 68, 79, 128, 68, 79, 68, 69, 75, 65, 84, 65, - 128, 68, 79, 67, 85, 77, 69, 78, 84, 128, 68, 79, 67, 85, 77, 69, 78, - 212, 68, 79, 66, 82, 79, 128, 68, 79, 65, 67, 72, 65, 83, 72, 77, 69, 69, - 128, 68, 79, 65, 67, 72, 65, 83, 72, 77, 69, 197, 68, 79, 65, 128, 68, - 79, 45, 79, 128, 68, 78, 193, 68, 77, 128, 68, 205, 68, 76, 85, 128, 68, - 76, 79, 128, 68, 76, 73, 128, 68, 76, 72, 89, 65, 128, 68, 76, 72, 65, - 128, 68, 76, 69, 69, 128, 68, 76, 65, 128, 68, 76, 128, 68, 75, 65, 82, - 128, 68, 75, 65, 210, 68, 74, 69, 82, 86, 73, 128, 68, 74, 69, 82, 86, - 128, 68, 74, 69, 128, 68, 74, 65, 128, 68, 73, 90, 90, 217, 68, 73, 89, - 193, 68, 73, 86, 79, 82, 67, 197, 68, 73, 86, 73, 83, 73, 79, 78, 128, - 68, 73, 86, 73, 83, 73, 79, 206, 68, 73, 86, 73, 78, 199, 68, 73, 86, 73, - 78, 65, 84, 73, 79, 78, 128, 68, 73, 86, 73, 68, 69, 83, 128, 68, 73, 86, - 73, 68, 69, 82, 83, 128, 68, 73, 86, 73, 68, 69, 82, 128, 68, 73, 86, 73, - 68, 69, 196, 68, 73, 86, 73, 68, 69, 128, 68, 73, 86, 73, 68, 197, 68, - 73, 86, 69, 211, 68, 73, 86, 69, 82, 71, 69, 78, 67, 69, 128, 68, 73, 84, - 84, 207, 68, 73, 83, 84, 79, 82, 84, 73, 79, 78, 128, 68, 73, 83, 84, 73, - 78, 71, 85, 73, 83, 72, 128, 68, 73, 83, 84, 73, 76, 76, 128, 68, 73, 83, - 83, 79, 76, 86, 69, 45, 50, 128, 68, 73, 83, 83, 79, 76, 86, 69, 128, 68, - 73, 83, 80, 85, 84, 69, 196, 68, 73, 83, 80, 69, 82, 83, 73, 79, 78, 128, - 68, 73, 83, 75, 128, 68, 73, 83, 73, 77, 79, 85, 128, 68, 73, 83, 72, - 128, 68, 73, 83, 71, 85, 73, 83, 69, 196, 68, 73, 83, 67, 79, 78, 84, 73, - 78, 85, 79, 85, 211, 68, 73, 83, 195, 68, 73, 83, 65, 80, 80, 79, 73, 78, - 84, 69, 196, 68, 73, 83, 65, 66, 76, 69, 196, 68, 73, 82, 71, 193, 68, - 73, 82, 69, 67, 84, 76, 217, 68, 73, 82, 69, 67, 84, 73, 79, 78, 65, 204, - 68, 73, 82, 69, 67, 84, 73, 79, 206, 68, 73, 80, 84, 69, 128, 68, 73, 80, - 80, 69, 82, 128, 68, 73, 80, 76, 79, 85, 78, 128, 68, 73, 80, 76, 73, - 128, 68, 73, 80, 76, 201, 68, 73, 78, 71, 66, 65, 212, 68, 73, 206, 68, - 73, 77, 77, 73, 78, 71, 128, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, - 51, 128, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, 50, 128, 68, 73, 77, - 73, 78, 85, 84, 73, 79, 78, 45, 49, 128, 68, 73, 77, 73, 78, 73, 83, 72, - 77, 69, 78, 84, 128, 68, 73, 77, 73, 68, 73, 193, 68, 73, 77, 69, 78, 83, - 73, 79, 78, 65, 204, 68, 73, 77, 69, 78, 83, 73, 79, 206, 68, 73, 77, 50, - 128, 68, 73, 77, 178, 68, 73, 76, 128, 68, 73, 71, 82, 65, 80, 72, 128, - 68, 73, 71, 82, 65, 80, 200, 68, 73, 71, 82, 65, 77, 77, 79, 211, 68, 73, - 71, 82, 65, 77, 77, 193, 68, 73, 71, 82, 65, 205, 68, 73, 71, 79, 82, 71, - 79, 78, 128, 68, 73, 71, 79, 82, 71, 79, 206, 68, 73, 71, 73, 84, 83, - 128, 68, 73, 71, 65, 77, 77, 65, 128, 68, 73, 71, 193, 68, 73, 70, 84, - 79, 71, 71, 79, 211, 68, 73, 70, 79, 78, 73, 65, 83, 128, 68, 73, 70, 70, - 73, 67, 85, 76, 84, 217, 68, 73, 70, 70, 73, 67, 85, 76, 84, 73, 69, 83, - 128, 68, 73, 70, 70, 69, 82, 69, 78, 84, 73, 65, 76, 128, 68, 73, 70, 70, - 69, 82, 69, 78, 67, 197, 68, 73, 70, 65, 84, 128, 68, 73, 69, 83, 73, 83, - 128, 68, 73, 69, 83, 73, 211, 68, 73, 69, 83, 69, 204, 68, 73, 69, 80, - 128, 68, 73, 197, 68, 73, 66, 128, 68, 73, 65, 84, 79, 78, 79, 206, 68, - 73, 65, 84, 79, 78, 73, 75, 201, 68, 73, 65, 83, 84, 79, 76, 201, 68, 73, - 65, 77, 79, 78, 68, 83, 128, 68, 73, 65, 77, 79, 78, 68, 128, 68, 73, 65, - 77, 79, 78, 196, 68, 73, 65, 77, 69, 84, 69, 210, 68, 73, 65, 76, 89, 84, - 73, 75, 65, 128, 68, 73, 65, 76, 89, 84, 73, 75, 193, 68, 73, 65, 76, 69, - 67, 84, 45, 208, 68, 73, 65, 71, 79, 78, 65, 76, 128, 68, 73, 65, 69, 82, - 69, 83, 73, 90, 69, 196, 68, 73, 65, 69, 82, 69, 83, 73, 83, 45, 82, 73, - 78, 71, 128, 68, 73, 65, 69, 82, 69, 83, 73, 83, 128, 68, 73, 65, 69, 82, - 69, 83, 73, 211, 68, 72, 79, 85, 128, 68, 72, 79, 79, 128, 68, 72, 79, - 128, 68, 72, 73, 73, 128, 68, 72, 72, 85, 128, 68, 72, 72, 79, 79, 128, - 68, 72, 72, 79, 128, 68, 72, 72, 73, 128, 68, 72, 72, 69, 69, 128, 68, - 72, 72, 69, 128, 68, 72, 72, 65, 128, 68, 72, 69, 69, 128, 68, 72, 65, - 82, 77, 65, 128, 68, 72, 65, 77, 69, 68, 72, 128, 68, 72, 65, 76, 69, 84, - 72, 128, 68, 72, 65, 76, 65, 84, 72, 128, 68, 72, 65, 76, 128, 68, 72, - 65, 68, 72, 69, 128, 68, 72, 65, 65, 76, 85, 128, 68, 72, 65, 65, 128, - 68, 72, 65, 128, 68, 69, 90, 200, 68, 69, 89, 84, 69, 82, 79, 213, 68, - 69, 89, 84, 69, 82, 79, 211, 68, 69, 88, 73, 65, 128, 68, 69, 86, 73, 67, - 197, 68, 69, 86, 69, 76, 79, 80, 77, 69, 78, 84, 128, 68, 69, 85, 78, 71, - 128, 68, 69, 83, 75, 84, 79, 208, 68, 69, 83, 203, 68, 69, 83, 73, 71, - 78, 128, 68, 69, 83, 73, 128, 68, 69, 83, 69, 82, 84, 128, 68, 69, 83, - 69, 82, 212, 68, 69, 83, 69, 82, 69, 212, 68, 69, 83, 67, 82, 73, 80, 84, - 73, 79, 206, 68, 69, 83, 67, 69, 78, 68, 73, 78, 199, 68, 69, 83, 67, 69, - 78, 68, 69, 82, 128, 68, 69, 82, 69, 84, 45, 72, 73, 68, 69, 84, 128, 68, - 69, 82, 69, 84, 128, 68, 69, 82, 69, 76, 73, 67, 212, 68, 69, 82, 66, 73, - 84, 83, 65, 128, 68, 69, 80, 84, 72, 128, 68, 69, 80, 65, 82, 84, 85, 82, - 69, 128, 68, 69, 80, 65, 82, 84, 77, 69, 78, 212, 68, 69, 80, 65, 82, 84, - 73, 78, 199, 68, 69, 78, 84, 73, 83, 84, 82, 217, 68, 69, 78, 84, 65, - 204, 68, 69, 78, 79, 77, 73, 78, 65, 84, 79, 82, 128, 68, 69, 78, 79, 77, - 73, 78, 65, 84, 79, 210, 68, 69, 78, 78, 69, 78, 128, 68, 69, 78, 71, - 128, 68, 69, 78, 197, 68, 69, 78, 65, 82, 73, 85, 211, 68, 69, 77, 69, - 83, 84, 86, 69, 78, 78, 217, 68, 69, 76, 84, 65, 128, 68, 69, 76, 84, - 193, 68, 69, 76, 84, 128, 68, 69, 76, 80, 72, 73, 195, 68, 69, 76, 73, - 86, 69, 82, 217, 68, 69, 76, 73, 86, 69, 82, 65, 78, 67, 69, 128, 68, 69, - 76, 73, 77, 73, 84, 69, 82, 128, 68, 69, 76, 73, 77, 73, 84, 69, 210, 68, - 69, 76, 73, 67, 73, 79, 85, 211, 68, 69, 76, 69, 84, 73, 79, 206, 68, 69, - 76, 69, 84, 69, 128, 68, 69, 76, 69, 84, 197, 68, 69, 75, 65, 128, 68, - 69, 75, 128, 68, 69, 73, 128, 68, 69, 72, 73, 128, 68, 69, 71, 82, 69, - 69, 83, 128, 68, 69, 71, 82, 69, 197, 68, 69, 70, 73, 78, 73, 84, 73, 79, - 78, 128, 68, 69, 70, 69, 67, 84, 73, 86, 69, 78, 69, 83, 211, 68, 69, 69, - 82, 128, 68, 69, 69, 80, 76, 89, 128, 68, 69, 69, 76, 128, 68, 69, 67, - 82, 69, 83, 67, 69, 78, 68, 79, 128, 68, 69, 67, 82, 69, 65, 83, 69, 128, - 68, 69, 67, 82, 69, 65, 83, 197, 68, 69, 67, 79, 82, 65, 84, 73, 86, 197, - 68, 69, 67, 79, 82, 65, 84, 73, 79, 78, 128, 68, 69, 67, 73, 83, 73, 86, - 69, 78, 69, 83, 83, 128, 68, 69, 67, 73, 77, 65, 204, 68, 69, 67, 73, 68, - 85, 79, 85, 211, 68, 69, 67, 69, 77, 66, 69, 82, 128, 68, 69, 67, 65, 89, - 69, 68, 128, 68, 69, 66, 73, 212, 68, 69, 65, 84, 72, 128, 68, 69, 65, - 198, 68, 69, 65, 68, 128, 68, 68, 87, 65, 128, 68, 68, 85, 88, 128, 68, - 68, 85, 84, 128, 68, 68, 85, 82, 88, 128, 68, 68, 85, 82, 128, 68, 68, - 85, 80, 128, 68, 68, 85, 79, 88, 128, 68, 68, 85, 79, 80, 128, 68, 68, - 85, 79, 128, 68, 68, 85, 128, 68, 68, 79, 88, 128, 68, 68, 79, 84, 128, - 68, 68, 79, 80, 128, 68, 68, 79, 65, 128, 68, 68, 73, 88, 128, 68, 68, - 73, 84, 128, 68, 68, 73, 80, 128, 68, 68, 73, 69, 88, 128, 68, 68, 73, - 69, 80, 128, 68, 68, 73, 69, 128, 68, 68, 73, 128, 68, 68, 72, 85, 128, - 68, 68, 72, 79, 128, 68, 68, 72, 69, 69, 128, 68, 68, 72, 69, 128, 68, - 68, 72, 65, 65, 128, 68, 68, 72, 65, 128, 68, 68, 69, 88, 128, 68, 68, - 69, 80, 128, 68, 68, 69, 69, 128, 68, 68, 69, 128, 68, 68, 68, 72, 65, - 128, 68, 68, 68, 65, 128, 68, 68, 65, 89, 65, 78, 78, 65, 128, 68, 68, - 65, 88, 128, 68, 68, 65, 84, 128, 68, 68, 65, 80, 128, 68, 68, 65, 76, - 128, 68, 68, 65, 204, 68, 68, 65, 72, 65, 76, 128, 68, 68, 65, 72, 65, - 204, 68, 68, 65, 65, 128, 68, 67, 83, 128, 68, 67, 72, 69, 128, 68, 67, - 52, 128, 68, 67, 51, 128, 68, 67, 50, 128, 68, 67, 49, 128, 68, 194, 68, - 65, 89, 45, 78, 73, 71, 72, 84, 128, 68, 65, 217, 68, 65, 87, 66, 128, - 68, 65, 86, 73, 89, 65, 78, 73, 128, 68, 65, 86, 73, 68, 128, 68, 65, 84, - 197, 68, 65, 83, 73, 65, 128, 68, 65, 83, 73, 193, 68, 65, 83, 72, 69, - 196, 68, 65, 83, 72, 128, 68, 65, 83, 200, 68, 65, 83, 69, 73, 65, 128, - 68, 65, 82, 84, 128, 68, 65, 82, 75, 69, 78, 73, 78, 71, 128, 68, 65, 82, - 75, 69, 78, 73, 78, 199, 68, 65, 82, 203, 68, 65, 82, 71, 65, 128, 68, - 65, 82, 65, 52, 128, 68, 65, 82, 65, 51, 128, 68, 65, 82, 128, 68, 65, - 80, 45, 80, 82, 65, 205, 68, 65, 80, 45, 80, 73, 201, 68, 65, 80, 45, 77, - 85, 79, 217, 68, 65, 80, 45, 66, 85, 79, 206, 68, 65, 80, 45, 66, 69, - 201, 68, 65, 208, 68, 65, 78, 84, 65, 89, 65, 76, 65, 78, 128, 68, 65, - 78, 84, 65, 74, 193, 68, 65, 78, 71, 79, 128, 68, 65, 78, 71, 128, 68, - 65, 78, 199, 68, 65, 78, 68, 65, 128, 68, 65, 78, 67, 73, 78, 71, 128, - 68, 65, 78, 67, 69, 82, 128, 68, 65, 77, 80, 128, 68, 65, 77, 208, 68, - 65, 77, 77, 65, 84, 65, 78, 128, 68, 65, 77, 77, 65, 84, 65, 206, 68, 65, - 77, 77, 65, 128, 68, 65, 77, 77, 193, 68, 65, 77, 65, 82, 85, 128, 68, - 65, 76, 69, 84, 72, 45, 82, 69, 83, 72, 128, 68, 65, 76, 69, 84, 128, 68, - 65, 76, 69, 212, 68, 65, 76, 68, 65, 128, 68, 65, 76, 65, 84, 72, 128, - 68, 65, 76, 65, 84, 200, 68, 65, 76, 65, 84, 128, 68, 65, 73, 82, 128, - 68, 65, 73, 78, 71, 128, 68, 65, 73, 128, 68, 65, 72, 89, 65, 65, 85, 83, - 72, 45, 50, 128, 68, 65, 72, 89, 65, 65, 85, 83, 72, 128, 68, 65, 71, 83, - 128, 68, 65, 71, 71, 69, 82, 128, 68, 65, 71, 71, 69, 210, 68, 65, 71, - 69, 83, 72, 128, 68, 65, 71, 69, 83, 200, 68, 65, 71, 66, 65, 83, 73, 78, - 78, 65, 128, 68, 65, 71, 65, 218, 68, 65, 71, 65, 76, 71, 65, 128, 68, - 65, 71, 51, 128, 68, 65, 199, 68, 65, 69, 78, 71, 128, 68, 65, 69, 199, - 68, 65, 68, 128, 68, 65, 196, 68, 65, 65, 83, 85, 128, 68, 65, 65, 76, - 73, 128, 68, 65, 65, 68, 72, 85, 128, 68, 48, 54, 55, 72, 128, 68, 48, - 54, 55, 71, 128, 68, 48, 54, 55, 70, 128, 68, 48, 54, 55, 69, 128, 68, - 48, 54, 55, 68, 128, 68, 48, 54, 55, 67, 128, 68, 48, 54, 55, 66, 128, - 68, 48, 54, 55, 65, 128, 68, 48, 54, 55, 128, 68, 48, 54, 54, 128, 68, - 48, 54, 53, 128, 68, 48, 54, 52, 128, 68, 48, 54, 51, 128, 68, 48, 54, - 50, 128, 68, 48, 54, 49, 128, 68, 48, 54, 48, 128, 68, 48, 53, 57, 128, - 68, 48, 53, 56, 128, 68, 48, 53, 55, 128, 68, 48, 53, 54, 128, 68, 48, - 53, 53, 128, 68, 48, 53, 52, 65, 128, 68, 48, 53, 52, 128, 68, 48, 53, - 51, 128, 68, 48, 53, 50, 65, 128, 68, 48, 53, 50, 128, 68, 48, 53, 49, - 128, 68, 48, 53, 48, 73, 128, 68, 48, 53, 48, 72, 128, 68, 48, 53, 48, - 71, 128, 68, 48, 53, 48, 70, 128, 68, 48, 53, 48, 69, 128, 68, 48, 53, - 48, 68, 128, 68, 48, 53, 48, 67, 128, 68, 48, 53, 48, 66, 128, 68, 48, - 53, 48, 65, 128, 68, 48, 53, 48, 128, 68, 48, 52, 57, 128, 68, 48, 52, - 56, 65, 128, 68, 48, 52, 56, 128, 68, 48, 52, 55, 128, 68, 48, 52, 54, - 65, 128, 68, 48, 52, 54, 128, 68, 48, 52, 53, 128, 68, 48, 52, 52, 128, - 68, 48, 52, 51, 128, 68, 48, 52, 50, 128, 68, 48, 52, 49, 128, 68, 48, - 52, 48, 128, 68, 48, 51, 57, 128, 68, 48, 51, 56, 128, 68, 48, 51, 55, - 128, 68, 48, 51, 54, 128, 68, 48, 51, 53, 128, 68, 48, 51, 52, 65, 128, - 68, 48, 51, 52, 128, 68, 48, 51, 51, 128, 68, 48, 51, 50, 128, 68, 48, - 51, 49, 65, 128, 68, 48, 51, 49, 128, 68, 48, 51, 48, 128, 68, 48, 50, - 57, 128, 68, 48, 50, 56, 128, 68, 48, 50, 55, 65, 128, 68, 48, 50, 55, - 128, 68, 48, 50, 54, 128, 68, 48, 50, 53, 128, 68, 48, 50, 52, 128, 68, - 48, 50, 51, 128, 68, 48, 50, 50, 128, 68, 48, 50, 49, 128, 68, 48, 50, - 48, 128, 68, 48, 49, 57, 128, 68, 48, 49, 56, 128, 68, 48, 49, 55, 128, - 68, 48, 49, 54, 128, 68, 48, 49, 53, 128, 68, 48, 49, 52, 128, 68, 48, - 49, 51, 128, 68, 48, 49, 50, 128, 68, 48, 49, 49, 128, 68, 48, 49, 48, - 128, 68, 48, 48, 57, 128, 68, 48, 48, 56, 65, 128, 68, 48, 48, 56, 128, - 68, 48, 48, 55, 128, 68, 48, 48, 54, 128, 68, 48, 48, 53, 128, 68, 48, - 48, 52, 128, 68, 48, 48, 51, 128, 68, 48, 48, 50, 128, 68, 48, 48, 49, - 128, 67, 89, 88, 128, 67, 89, 84, 128, 67, 89, 82, 88, 128, 67, 89, 82, - 69, 78, 65, 73, 195, 67, 89, 82, 128, 67, 89, 80, 82, 79, 45, 77, 73, 78, - 79, 65, 206, 67, 89, 80, 82, 73, 79, 212, 67, 89, 80, 69, 82, 85, 83, - 128, 67, 89, 80, 128, 67, 89, 76, 73, 78, 68, 82, 73, 67, 73, 84, 89, + 82, 128, 68, 79, 79, 78, 71, 128, 68, 79, 78, 75, 69, 89, 128, 68, 79, + 78, 71, 128, 68, 79, 77, 73, 78, 207, 68, 79, 77, 65, 73, 206, 68, 79, + 76, 80, 72, 73, 78, 128, 68, 79, 76, 76, 83, 128, 68, 79, 76, 76, 65, + 210, 68, 79, 76, 73, 85, 77, 128, 68, 79, 75, 77, 65, 73, 128, 68, 79, + 73, 84, 128, 68, 79, 73, 78, 199, 68, 79, 73, 128, 68, 79, 71, 82, 193, + 68, 79, 71, 128, 68, 79, 199, 68, 79, 69, 211, 68, 79, 68, 79, 128, 68, + 79, 68, 69, 75, 65, 84, 65, 128, 68, 79, 67, 85, 77, 69, 78, 84, 128, 68, + 79, 67, 85, 77, 69, 78, 212, 68, 79, 66, 82, 79, 128, 68, 79, 65, 67, 72, + 65, 83, 72, 77, 69, 69, 128, 68, 79, 65, 67, 72, 65, 83, 72, 77, 69, 197, + 68, 79, 65, 128, 68, 79, 45, 79, 128, 68, 78, 193, 68, 77, 128, 68, 205, + 68, 76, 85, 128, 68, 76, 79, 128, 68, 76, 73, 128, 68, 76, 72, 89, 65, + 128, 68, 76, 72, 65, 128, 68, 76, 69, 69, 128, 68, 76, 65, 128, 68, 76, + 128, 68, 75, 65, 82, 128, 68, 75, 65, 210, 68, 74, 69, 82, 86, 73, 128, + 68, 74, 69, 82, 86, 128, 68, 74, 69, 128, 68, 74, 65, 128, 68, 73, 90, + 90, 217, 68, 73, 89, 193, 68, 73, 86, 79, 82, 67, 197, 68, 73, 86, 73, + 83, 73, 79, 78, 128, 68, 73, 86, 73, 83, 73, 79, 206, 68, 73, 86, 73, 78, + 199, 68, 73, 86, 73, 78, 65, 84, 73, 79, 78, 128, 68, 73, 86, 73, 68, 69, + 83, 128, 68, 73, 86, 73, 68, 69, 82, 83, 128, 68, 73, 86, 73, 68, 69, 82, + 128, 68, 73, 86, 73, 68, 69, 196, 68, 73, 86, 73, 68, 69, 128, 68, 73, + 86, 73, 68, 197, 68, 73, 86, 69, 211, 68, 73, 86, 69, 82, 71, 69, 78, 67, + 69, 128, 68, 73, 84, 84, 207, 68, 73, 83, 84, 79, 82, 84, 73, 79, 78, + 128, 68, 73, 83, 84, 73, 78, 71, 85, 73, 83, 72, 128, 68, 73, 83, 84, 73, + 76, 76, 128, 68, 73, 83, 83, 79, 76, 86, 69, 45, 50, 128, 68, 73, 83, 83, + 79, 76, 86, 69, 128, 68, 73, 83, 80, 85, 84, 69, 196, 68, 73, 83, 80, 69, + 82, 83, 73, 79, 78, 128, 68, 73, 83, 75, 128, 68, 73, 83, 73, 77, 79, 85, + 128, 68, 73, 83, 72, 128, 68, 73, 83, 71, 85, 73, 83, 69, 196, 68, 73, + 83, 67, 79, 78, 84, 73, 78, 85, 79, 85, 211, 68, 73, 83, 195, 68, 73, 83, + 65, 80, 80, 79, 73, 78, 84, 69, 196, 68, 73, 83, 65, 66, 76, 69, 196, 68, + 73, 82, 71, 193, 68, 73, 82, 69, 67, 84, 76, 217, 68, 73, 82, 69, 67, 84, + 73, 79, 78, 65, 204, 68, 73, 82, 69, 67, 84, 73, 79, 206, 68, 73, 80, 84, + 69, 128, 68, 73, 80, 80, 69, 82, 128, 68, 73, 80, 76, 79, 85, 78, 128, + 68, 73, 80, 76, 73, 128, 68, 73, 80, 76, 201, 68, 73, 78, 71, 66, 65, + 212, 68, 73, 206, 68, 73, 77, 77, 73, 78, 71, 128, 68, 73, 77, 73, 78, + 85, 84, 73, 79, 78, 45, 51, 128, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, + 45, 50, 128, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, 49, 128, 68, 73, + 77, 73, 78, 73, 83, 72, 77, 69, 78, 84, 128, 68, 73, 77, 73, 68, 73, 193, + 68, 73, 77, 69, 78, 83, 73, 79, 78, 65, 204, 68, 73, 77, 69, 78, 83, 73, + 79, 206, 68, 73, 77, 50, 128, 68, 73, 77, 178, 68, 73, 76, 128, 68, 73, + 71, 82, 65, 80, 72, 128, 68, 73, 71, 82, 65, 80, 200, 68, 73, 71, 82, 65, + 77, 77, 79, 211, 68, 73, 71, 82, 65, 77, 77, 193, 68, 73, 71, 82, 65, + 205, 68, 73, 71, 79, 82, 71, 79, 78, 128, 68, 73, 71, 79, 82, 71, 79, + 206, 68, 73, 71, 73, 84, 83, 128, 68, 73, 71, 65, 77, 77, 65, 128, 68, + 73, 71, 193, 68, 73, 70, 84, 79, 71, 71, 79, 211, 68, 73, 70, 79, 78, 73, + 65, 83, 128, 68, 73, 70, 70, 73, 67, 85, 76, 84, 217, 68, 73, 70, 70, 73, + 67, 85, 76, 84, 73, 69, 83, 128, 68, 73, 70, 70, 69, 82, 69, 78, 84, 73, + 65, 76, 128, 68, 73, 70, 70, 69, 82, 69, 78, 67, 197, 68, 73, 70, 65, 84, + 128, 68, 73, 69, 83, 73, 83, 128, 68, 73, 69, 83, 73, 211, 68, 73, 69, + 83, 69, 204, 68, 73, 69, 80, 128, 68, 73, 197, 68, 73, 66, 128, 68, 73, + 65, 84, 79, 78, 79, 206, 68, 73, 65, 84, 79, 78, 73, 75, 201, 68, 73, 65, + 83, 84, 79, 76, 201, 68, 73, 65, 77, 79, 78, 68, 83, 128, 68, 73, 65, 77, + 79, 78, 68, 128, 68, 73, 65, 77, 79, 78, 196, 68, 73, 65, 77, 69, 84, 69, + 210, 68, 73, 65, 76, 89, 84, 73, 75, 65, 128, 68, 73, 65, 76, 89, 84, 73, + 75, 193, 68, 73, 65, 76, 69, 67, 84, 45, 208, 68, 73, 65, 71, 79, 78, 65, + 76, 128, 68, 73, 65, 69, 82, 69, 83, 73, 90, 69, 196, 68, 73, 65, 69, 82, + 69, 83, 73, 83, 45, 82, 73, 78, 71, 128, 68, 73, 65, 69, 82, 69, 83, 73, + 83, 128, 68, 73, 65, 69, 82, 69, 83, 73, 211, 68, 72, 79, 85, 128, 68, + 72, 79, 79, 128, 68, 72, 79, 128, 68, 72, 73, 73, 128, 68, 72, 72, 85, + 128, 68, 72, 72, 79, 79, 128, 68, 72, 72, 79, 128, 68, 72, 72, 73, 128, + 68, 72, 72, 69, 69, 128, 68, 72, 72, 69, 128, 68, 72, 72, 65, 128, 68, + 72, 69, 69, 128, 68, 72, 65, 82, 77, 65, 128, 68, 72, 65, 77, 69, 68, 72, + 128, 68, 72, 65, 76, 69, 84, 72, 128, 68, 72, 65, 76, 65, 84, 72, 128, + 68, 72, 65, 76, 128, 68, 72, 65, 68, 72, 69, 128, 68, 72, 65, 65, 76, 85, + 128, 68, 72, 65, 65, 128, 68, 72, 65, 128, 68, 69, 90, 200, 68, 69, 89, + 84, 69, 82, 79, 213, 68, 69, 89, 84, 69, 82, 79, 211, 68, 69, 88, 73, 65, + 128, 68, 69, 86, 73, 67, 197, 68, 69, 86, 69, 76, 79, 80, 77, 69, 78, 84, + 128, 68, 69, 85, 78, 71, 128, 68, 69, 83, 75, 84, 79, 208, 68, 69, 83, + 203, 68, 69, 83, 73, 71, 78, 128, 68, 69, 83, 73, 128, 68, 69, 83, 69, + 82, 84, 128, 68, 69, 83, 69, 82, 212, 68, 69, 83, 69, 82, 69, 212, 68, + 69, 83, 67, 82, 73, 80, 84, 73, 79, 206, 68, 69, 83, 67, 69, 78, 68, 73, + 78, 199, 68, 69, 83, 67, 69, 78, 68, 69, 82, 128, 68, 69, 82, 69, 84, 45, + 72, 73, 68, 69, 84, 128, 68, 69, 82, 69, 84, 128, 68, 69, 82, 69, 76, 73, + 67, 212, 68, 69, 82, 66, 73, 84, 83, 65, 128, 68, 69, 80, 84, 72, 128, + 68, 69, 80, 65, 82, 84, 85, 82, 69, 128, 68, 69, 80, 65, 82, 84, 77, 69, + 78, 212, 68, 69, 80, 65, 82, 84, 73, 78, 199, 68, 69, 78, 84, 73, 83, 84, + 82, 217, 68, 69, 78, 84, 65, 204, 68, 69, 78, 79, 77, 73, 78, 65, 84, 79, + 82, 128, 68, 69, 78, 79, 77, 73, 78, 65, 84, 79, 210, 68, 69, 78, 78, 69, + 78, 128, 68, 69, 78, 71, 128, 68, 69, 78, 197, 68, 69, 78, 65, 82, 73, + 85, 211, 68, 69, 77, 69, 83, 84, 86, 69, 78, 78, 217, 68, 69, 76, 84, 65, + 128, 68, 69, 76, 84, 193, 68, 69, 76, 84, 128, 68, 69, 76, 80, 72, 73, + 195, 68, 69, 76, 73, 86, 69, 82, 217, 68, 69, 76, 73, 86, 69, 82, 65, 78, + 67, 69, 128, 68, 69, 76, 73, 77, 73, 84, 69, 82, 128, 68, 69, 76, 73, 77, + 73, 84, 69, 210, 68, 69, 76, 73, 67, 73, 79, 85, 211, 68, 69, 76, 69, 84, + 73, 79, 206, 68, 69, 76, 69, 84, 69, 128, 68, 69, 76, 69, 84, 197, 68, + 69, 75, 65, 128, 68, 69, 75, 128, 68, 69, 73, 128, 68, 69, 72, 73, 128, + 68, 69, 71, 82, 69, 69, 83, 128, 68, 69, 71, 82, 69, 197, 68, 69, 70, 73, + 78, 73, 84, 73, 79, 78, 128, 68, 69, 70, 69, 67, 84, 73, 86, 69, 78, 69, + 83, 211, 68, 69, 69, 82, 128, 68, 69, 69, 80, 76, 89, 128, 68, 69, 69, + 76, 128, 68, 69, 67, 82, 69, 83, 67, 69, 78, 68, 79, 128, 68, 69, 67, 82, + 69, 65, 83, 69, 128, 68, 69, 67, 82, 69, 65, 83, 197, 68, 69, 67, 79, 82, + 65, 84, 73, 86, 197, 68, 69, 67, 79, 82, 65, 84, 73, 79, 78, 128, 68, 69, + 67, 73, 83, 73, 86, 69, 78, 69, 83, 83, 128, 68, 69, 67, 73, 77, 65, 204, + 68, 69, 67, 73, 68, 85, 79, 85, 211, 68, 69, 67, 69, 77, 66, 69, 82, 128, + 68, 69, 67, 65, 89, 69, 68, 128, 68, 69, 66, 73, 212, 68, 69, 65, 84, 72, + 128, 68, 69, 65, 198, 68, 69, 65, 68, 128, 68, 68, 87, 65, 128, 68, 68, + 85, 88, 128, 68, 68, 85, 84, 128, 68, 68, 85, 82, 88, 128, 68, 68, 85, + 82, 128, 68, 68, 85, 80, 128, 68, 68, 85, 79, 88, 128, 68, 68, 85, 79, + 80, 128, 68, 68, 85, 79, 128, 68, 68, 85, 128, 68, 68, 79, 88, 128, 68, + 68, 79, 84, 128, 68, 68, 79, 80, 128, 68, 68, 79, 65, 128, 68, 68, 73, + 88, 128, 68, 68, 73, 84, 128, 68, 68, 73, 80, 128, 68, 68, 73, 69, 88, + 128, 68, 68, 73, 69, 80, 128, 68, 68, 73, 69, 128, 68, 68, 73, 128, 68, + 68, 72, 85, 128, 68, 68, 72, 79, 128, 68, 68, 72, 69, 69, 128, 68, 68, + 72, 69, 128, 68, 68, 72, 65, 65, 128, 68, 68, 72, 65, 128, 68, 68, 69, + 88, 128, 68, 68, 69, 80, 128, 68, 68, 69, 69, 128, 68, 68, 69, 128, 68, + 68, 68, 72, 65, 128, 68, 68, 68, 65, 128, 68, 68, 65, 89, 65, 78, 78, 65, + 128, 68, 68, 65, 88, 128, 68, 68, 65, 84, 128, 68, 68, 65, 80, 128, 68, + 68, 65, 76, 128, 68, 68, 65, 204, 68, 68, 65, 72, 65, 76, 128, 68, 68, + 65, 72, 65, 204, 68, 68, 65, 65, 128, 68, 67, 83, 128, 68, 67, 72, 69, + 128, 68, 67, 52, 128, 68, 67, 51, 128, 68, 67, 50, 128, 68, 67, 49, 128, + 68, 194, 68, 65, 89, 45, 78, 73, 71, 72, 84, 128, 68, 65, 217, 68, 65, + 87, 66, 128, 68, 65, 86, 73, 89, 65, 78, 73, 128, 68, 65, 86, 73, 68, + 128, 68, 65, 84, 197, 68, 65, 83, 73, 65, 128, 68, 65, 83, 73, 193, 68, + 65, 83, 72, 69, 196, 68, 65, 83, 72, 128, 68, 65, 83, 200, 68, 65, 83, + 69, 73, 65, 128, 68, 65, 82, 84, 128, 68, 65, 82, 75, 69, 78, 73, 78, 71, + 128, 68, 65, 82, 75, 69, 78, 73, 78, 199, 68, 65, 82, 203, 68, 65, 82, + 71, 65, 128, 68, 65, 82, 65, 52, 128, 68, 65, 82, 65, 51, 128, 68, 65, + 82, 128, 68, 65, 80, 45, 80, 82, 65, 205, 68, 65, 80, 45, 80, 73, 201, + 68, 65, 80, 45, 77, 85, 79, 217, 68, 65, 80, 45, 66, 85, 79, 206, 68, 65, + 80, 45, 66, 69, 201, 68, 65, 208, 68, 65, 78, 84, 65, 89, 65, 76, 65, 78, + 128, 68, 65, 78, 84, 65, 74, 193, 68, 65, 78, 71, 79, 128, 68, 65, 78, + 71, 128, 68, 65, 78, 199, 68, 65, 78, 68, 65, 128, 68, 65, 78, 67, 73, + 78, 71, 128, 68, 65, 78, 67, 69, 82, 128, 68, 65, 77, 80, 128, 68, 65, + 77, 208, 68, 65, 77, 77, 65, 84, 65, 78, 128, 68, 65, 77, 77, 65, 84, 65, + 206, 68, 65, 77, 77, 65, 128, 68, 65, 77, 77, 193, 68, 65, 77, 65, 82, + 85, 128, 68, 65, 77, 65, 71, 69, 68, 128, 68, 65, 77, 65, 71, 69, 196, + 68, 65, 76, 69, 84, 72, 45, 82, 69, 83, 72, 128, 68, 65, 76, 69, 84, 128, + 68, 65, 76, 69, 212, 68, 65, 76, 68, 65, 128, 68, 65, 76, 65, 84, 72, + 128, 68, 65, 76, 65, 84, 200, 68, 65, 76, 65, 84, 128, 68, 65, 73, 82, + 128, 68, 65, 73, 78, 71, 128, 68, 65, 73, 128, 68, 65, 72, 89, 65, 65, + 85, 83, 72, 45, 50, 128, 68, 65, 72, 89, 65, 65, 85, 83, 72, 128, 68, 65, + 71, 83, 128, 68, 65, 71, 71, 69, 82, 128, 68, 65, 71, 71, 69, 210, 68, + 65, 71, 69, 83, 72, 128, 68, 65, 71, 69, 83, 200, 68, 65, 71, 66, 65, 83, + 73, 78, 78, 65, 128, 68, 65, 71, 65, 218, 68, 65, 71, 65, 76, 71, 65, + 128, 68, 65, 71, 51, 128, 68, 65, 199, 68, 65, 69, 78, 71, 128, 68, 65, + 69, 199, 68, 65, 68, 128, 68, 65, 196, 68, 65, 65, 83, 85, 128, 68, 65, + 65, 76, 73, 128, 68, 65, 65, 68, 72, 85, 128, 68, 48, 54, 55, 72, 128, + 68, 48, 54, 55, 71, 128, 68, 48, 54, 55, 70, 128, 68, 48, 54, 55, 69, + 128, 68, 48, 54, 55, 68, 128, 68, 48, 54, 55, 67, 128, 68, 48, 54, 55, + 66, 128, 68, 48, 54, 55, 65, 128, 68, 48, 54, 55, 128, 68, 48, 54, 54, + 128, 68, 48, 54, 53, 128, 68, 48, 54, 52, 128, 68, 48, 54, 51, 128, 68, + 48, 54, 50, 128, 68, 48, 54, 49, 128, 68, 48, 54, 48, 128, 68, 48, 53, + 57, 128, 68, 48, 53, 56, 128, 68, 48, 53, 55, 128, 68, 48, 53, 54, 128, + 68, 48, 53, 53, 128, 68, 48, 53, 52, 65, 128, 68, 48, 53, 52, 128, 68, + 48, 53, 51, 128, 68, 48, 53, 50, 65, 128, 68, 48, 53, 50, 128, 68, 48, + 53, 49, 128, 68, 48, 53, 48, 73, 128, 68, 48, 53, 48, 72, 128, 68, 48, + 53, 48, 71, 128, 68, 48, 53, 48, 70, 128, 68, 48, 53, 48, 69, 128, 68, + 48, 53, 48, 68, 128, 68, 48, 53, 48, 67, 128, 68, 48, 53, 48, 66, 128, + 68, 48, 53, 48, 65, 128, 68, 48, 53, 48, 128, 68, 48, 52, 57, 128, 68, + 48, 52, 56, 65, 128, 68, 48, 52, 56, 128, 68, 48, 52, 55, 128, 68, 48, + 52, 54, 65, 128, 68, 48, 52, 54, 128, 68, 48, 52, 53, 128, 68, 48, 52, + 52, 128, 68, 48, 52, 51, 128, 68, 48, 52, 50, 128, 68, 48, 52, 49, 128, + 68, 48, 52, 48, 128, 68, 48, 51, 57, 128, 68, 48, 51, 56, 128, 68, 48, + 51, 55, 128, 68, 48, 51, 54, 128, 68, 48, 51, 53, 128, 68, 48, 51, 52, + 65, 128, 68, 48, 51, 52, 128, 68, 48, 51, 51, 128, 68, 48, 51, 50, 128, + 68, 48, 51, 49, 65, 128, 68, 48, 51, 49, 128, 68, 48, 51, 48, 128, 68, + 48, 50, 57, 128, 68, 48, 50, 56, 128, 68, 48, 50, 55, 65, 128, 68, 48, + 50, 55, 128, 68, 48, 50, 54, 128, 68, 48, 50, 53, 128, 68, 48, 50, 52, + 128, 68, 48, 50, 51, 128, 68, 48, 50, 50, 128, 68, 48, 50, 49, 128, 68, + 48, 50, 48, 128, 68, 48, 49, 57, 128, 68, 48, 49, 56, 128, 68, 48, 49, + 55, 128, 68, 48, 49, 54, 128, 68, 48, 49, 53, 128, 68, 48, 49, 52, 128, + 68, 48, 49, 51, 128, 68, 48, 49, 50, 128, 68, 48, 49, 49, 128, 68, 48, + 49, 48, 128, 68, 48, 48, 57, 128, 68, 48, 48, 56, 65, 128, 68, 48, 48, + 56, 128, 68, 48, 48, 55, 128, 68, 48, 48, 54, 128, 68, 48, 48, 53, 128, + 68, 48, 48, 52, 128, 68, 48, 48, 51, 128, 68, 48, 48, 50, 128, 68, 48, + 48, 49, 128, 67, 89, 88, 128, 67, 89, 84, 128, 67, 89, 82, 88, 128, 67, + 89, 82, 69, 78, 65, 73, 195, 67, 89, 82, 128, 67, 89, 80, 82, 79, 45, 77, + 73, 78, 79, 65, 206, 67, 89, 80, 82, 73, 79, 212, 67, 89, 80, 69, 82, 85, + 83, 128, 67, 89, 80, 128, 67, 89, 76, 73, 78, 68, 82, 73, 67, 73, 84, 89, 128, 67, 89, 67, 76, 79, 78, 69, 128, 67, 89, 65, 89, 128, 67, 89, 65, 87, 128, 67, 89, 65, 128, 67, 87, 79, 79, 128, 67, 87, 79, 128, 67, 87, 73, 73, 128, 67, 87, 73, 128, 67, 87, 69, 79, 82, 84, 72, 128, 67, 87, @@ -4899,1671 +4918,1672 @@ static const unsigned char lexicon[] = { 83, 84, 65, 78, 67, 89, 128, 67, 79, 78, 83, 69, 67, 85, 84, 73, 86, 197, 67, 79, 78, 74, 85, 78, 67, 84, 73, 79, 78, 128, 67, 79, 78, 74, 85, 71, 65, 84, 197, 67, 79, 78, 74, 79, 73, 78, 73, 78, 199, 67, 79, 78, 74, 79, - 73, 78, 69, 68, 128, 67, 79, 78, 74, 79, 73, 78, 69, 196, 67, 79, 78, 73, - 67, 65, 204, 67, 79, 78, 71, 82, 85, 69, 78, 212, 67, 79, 78, 71, 82, 65, - 84, 85, 76, 65, 84, 73, 79, 78, 128, 67, 79, 78, 70, 85, 83, 69, 196, 67, - 79, 78, 70, 79, 85, 78, 68, 69, 196, 67, 79, 78, 70, 76, 73, 67, 84, 128, - 67, 79, 78, 70, 69, 84, 84, 201, 67, 79, 78, 67, 65, 86, 69, 45, 83, 73, - 68, 69, 196, 67, 79, 78, 67, 65, 86, 69, 45, 80, 79, 73, 78, 84, 69, 196, - 67, 79, 77, 80, 85, 84, 69, 82, 83, 128, 67, 79, 77, 80, 85, 84, 69, 82, - 128, 67, 79, 77, 80, 82, 69, 83, 83, 73, 79, 78, 128, 67, 79, 77, 80, 82, - 69, 83, 83, 69, 196, 67, 79, 77, 80, 79, 83, 73, 84, 73, 79, 78, 128, 67, - 79, 77, 80, 79, 83, 73, 84, 73, 79, 206, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 55, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 55, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 55, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 55, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 55, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 55, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 55, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 55, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 55, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 55, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 55, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 55, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 55, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 55, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 55, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 55, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 55, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 55, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 55, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 55, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 55, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 48, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 55, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 55, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 55, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 54, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 55, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 55, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, - 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 50, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 49, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 55, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 55, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 56, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 55, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 55, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 55, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, - 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 51, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 50, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 55, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 55, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 57, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 56, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, - 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 52, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 51, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 48, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 57, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, - 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 53, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 52, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 49, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 48, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 48, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 55, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 54, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, - 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 50, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 49, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 56, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 55, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, - 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 51, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 50, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 57, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 56, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, - 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 52, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 51, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 48, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 57, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, - 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 53, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 52, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 49, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 48, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 48, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 55, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 54, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, - 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 50, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 49, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 56, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 55, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, - 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 51, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 50, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 57, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 56, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, - 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 52, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 51, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 48, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 57, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, - 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 53, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 52, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 49, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 48, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 48, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 55, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 54, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, - 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 50, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 49, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 56, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 55, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, - 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 51, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 50, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 57, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 56, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, - 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 52, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 51, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 48, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 57, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, - 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 53, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 52, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 49, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 48, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 48, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 55, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 54, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, - 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 50, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 49, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 56, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 55, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, - 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 51, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 50, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 57, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 56, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, - 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 52, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 51, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 48, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 57, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, - 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 53, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 52, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 49, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 48, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 48, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 55, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 54, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, - 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 50, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 49, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 56, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 55, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, - 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 51, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 50, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 57, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 56, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, - 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 52, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 51, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 48, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 57, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, - 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 53, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 52, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 49, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 48, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 48, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 55, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 54, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, - 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 50, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 49, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 56, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 55, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, - 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 51, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 50, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 57, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 56, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, - 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 52, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 51, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 48, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 57, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, - 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 53, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 52, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 49, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 48, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 48, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 55, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 54, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, - 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 50, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 49, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 56, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 55, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, - 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 51, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 50, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 57, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 56, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, - 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 52, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 51, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 48, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 57, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, - 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 53, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 52, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 49, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 48, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 212, 67, 79, 77, 80, 76, 73, 65, 78, 67, 69, 128, - 67, 79, 77, 80, 76, 69, 84, 73, 79, 78, 128, 67, 79, 77, 80, 76, 69, 84, - 69, 68, 128, 67, 79, 77, 80, 76, 69, 77, 69, 78, 84, 128, 67, 79, 77, 80, - 65, 83, 83, 128, 67, 79, 77, 80, 65, 82, 69, 128, 67, 79, 77, 77, 79, - 206, 67, 79, 77, 77, 69, 82, 67, 73, 65, 204, 67, 79, 77, 77, 65, 78, 68, - 128, 67, 79, 77, 77, 65, 128, 67, 79, 77, 77, 193, 67, 79, 77, 69, 84, - 128, 67, 79, 77, 66, 73, 78, 69, 68, 128, 67, 79, 77, 66, 73, 78, 65, 84, - 73, 79, 78, 128, 67, 79, 77, 66, 128, 67, 79, 76, 85, 77, 78, 128, 67, - 79, 76, 79, 82, 128, 67, 79, 76, 76, 73, 83, 73, 79, 206, 67, 79, 76, 76, - 128, 67, 79, 76, 196, 67, 79, 73, 78, 128, 67, 79, 70, 70, 73, 78, 128, - 67, 79, 69, 78, 71, 128, 67, 79, 69, 78, 199, 67, 79, 68, 65, 128, 67, - 79, 67, 79, 78, 85, 84, 128, 67, 79, 67, 75, 84, 65, 73, 204, 67, 79, 67, - 75, 82, 79, 65, 67, 72, 128, 67, 79, 65, 84, 128, 67, 79, 65, 83, 84, 69, - 82, 128, 67, 79, 65, 128, 67, 77, 51, 48, 50, 128, 67, 77, 51, 48, 49, - 128, 67, 77, 49, 49, 52, 128, 67, 77, 49, 49, 50, 128, 67, 77, 49, 49, - 48, 128, 67, 77, 49, 48, 57, 128, 67, 77, 49, 48, 56, 128, 67, 77, 49, - 48, 55, 128, 67, 77, 49, 48, 53, 128, 67, 77, 49, 48, 52, 128, 67, 77, - 49, 48, 51, 128, 67, 77, 49, 48, 50, 128, 67, 77, 49, 48, 49, 128, 67, - 77, 49, 48, 48, 128, 67, 77, 48, 57, 57, 128, 67, 77, 48, 57, 56, 128, - 67, 77, 48, 57, 55, 128, 67, 77, 48, 57, 54, 128, 67, 77, 48, 57, 53, - 128, 67, 77, 48, 57, 52, 128, 67, 77, 48, 57, 50, 128, 67, 77, 48, 57, - 49, 128, 67, 77, 48, 57, 48, 128, 67, 77, 48, 56, 57, 128, 67, 77, 48, - 56, 56, 128, 67, 77, 48, 56, 55, 128, 67, 77, 48, 56, 54, 128, 67, 77, - 48, 56, 53, 128, 67, 77, 48, 56, 52, 128, 67, 77, 48, 56, 51, 128, 67, - 77, 48, 56, 50, 128, 67, 77, 48, 56, 49, 128, 67, 77, 48, 56, 48, 128, - 67, 77, 48, 55, 57, 128, 67, 77, 48, 55, 56, 128, 67, 77, 48, 55, 54, - 128, 67, 77, 48, 55, 53, 66, 128, 67, 77, 48, 55, 53, 128, 67, 77, 48, - 55, 52, 128, 67, 77, 48, 55, 51, 128, 67, 77, 48, 55, 50, 128, 67, 77, - 48, 55, 49, 128, 67, 77, 48, 55, 48, 128, 67, 77, 48, 54, 57, 128, 67, - 77, 48, 54, 56, 128, 67, 77, 48, 54, 55, 128, 67, 77, 48, 54, 54, 128, - 67, 77, 48, 54, 52, 128, 67, 77, 48, 54, 51, 128, 67, 77, 48, 54, 50, - 128, 67, 77, 48, 54, 49, 128, 67, 77, 48, 54, 48, 128, 67, 77, 48, 53, - 57, 128, 67, 77, 48, 53, 56, 128, 67, 77, 48, 53, 54, 128, 67, 77, 48, - 53, 53, 128, 67, 77, 48, 53, 52, 128, 67, 77, 48, 53, 51, 128, 67, 77, - 48, 53, 50, 128, 67, 77, 48, 53, 49, 128, 67, 77, 48, 53, 48, 128, 67, - 77, 48, 52, 57, 128, 67, 77, 48, 52, 55, 128, 67, 77, 48, 52, 54, 128, - 67, 77, 48, 52, 52, 128, 67, 77, 48, 52, 49, 128, 67, 77, 48, 52, 48, - 128, 67, 77, 48, 51, 57, 128, 67, 77, 48, 51, 56, 128, 67, 77, 48, 51, - 55, 128, 67, 77, 48, 51, 54, 128, 67, 77, 48, 51, 53, 128, 67, 77, 48, - 51, 52, 128, 67, 77, 48, 51, 51, 128, 67, 77, 48, 51, 48, 128, 67, 77, - 48, 50, 57, 128, 67, 77, 48, 50, 56, 128, 67, 77, 48, 50, 55, 128, 67, - 77, 48, 50, 54, 128, 67, 77, 48, 50, 53, 128, 67, 77, 48, 50, 52, 128, - 67, 77, 48, 50, 51, 128, 67, 77, 48, 50, 49, 128, 67, 77, 48, 49, 57, - 128, 67, 77, 48, 49, 55, 128, 67, 77, 48, 49, 53, 128, 67, 77, 48, 49, - 51, 128, 67, 77, 48, 49, 50, 66, 128, 67, 77, 48, 49, 50, 128, 67, 77, - 48, 49, 49, 128, 67, 77, 48, 49, 48, 128, 67, 77, 48, 48, 57, 128, 67, - 77, 48, 48, 56, 128, 67, 77, 48, 48, 55, 128, 67, 77, 48, 48, 54, 128, - 67, 77, 48, 48, 53, 128, 67, 77, 48, 48, 52, 128, 67, 77, 48, 48, 50, - 128, 67, 77, 48, 48, 49, 128, 67, 77, 128, 67, 205, 67, 76, 85, 83, 84, - 69, 82, 45, 73, 78, 73, 84, 73, 65, 204, 67, 76, 85, 83, 84, 69, 82, 45, - 70, 73, 78, 65, 204, 67, 76, 85, 83, 84, 69, 210, 67, 76, 85, 66, 83, - 128, 67, 76, 85, 66, 45, 83, 80, 79, 75, 69, 196, 67, 76, 85, 66, 128, - 67, 76, 85, 194, 67, 76, 79, 87, 206, 67, 76, 79, 86, 69, 82, 128, 67, - 76, 79, 85, 68, 128, 67, 76, 79, 85, 196, 67, 76, 79, 84, 72, 69, 83, - 128, 67, 76, 79, 84, 72, 128, 67, 76, 79, 83, 69, 84, 128, 67, 76, 79, - 83, 69, 78, 69, 83, 83, 128, 67, 76, 79, 83, 69, 68, 128, 67, 76, 79, 83, - 197, 67, 76, 79, 67, 75, 87, 73, 83, 197, 67, 76, 79, 67, 203, 67, 76, - 73, 86, 73, 83, 128, 67, 76, 73, 80, 66, 79, 65, 82, 68, 128, 67, 76, 73, - 78, 75, 73, 78, 199, 67, 76, 73, 78, 71, 73, 78, 199, 67, 76, 73, 77, 66, - 73, 78, 71, 128, 67, 76, 73, 77, 65, 67, 85, 83, 128, 67, 76, 73, 70, 70, - 128, 67, 76, 73, 67, 75, 128, 67, 76, 73, 67, 203, 67, 76, 69, 70, 45, - 50, 128, 67, 76, 69, 70, 45, 49, 128, 67, 76, 69, 70, 128, 67, 76, 69, - 198, 67, 76, 69, 65, 86, 69, 82, 128, 67, 76, 69, 65, 210, 67, 76, 65, - 83, 83, 73, 67, 65, 204, 67, 76, 65, 80, 80, 73, 78, 199, 67, 76, 65, 80, - 80, 69, 210, 67, 76, 65, 78, 128, 67, 76, 65, 206, 67, 76, 65, 77, 83, - 72, 69, 76, 204, 67, 76, 65, 73, 77, 128, 67, 76, 128, 67, 73, 88, 128, - 67, 73, 86, 73, 76, 73, 65, 78, 128, 67, 73, 84, 89, 83, 67, 65, 80, 69, - 128, 67, 73, 84, 89, 83, 67, 65, 80, 197, 67, 73, 84, 201, 67, 73, 84, - 65, 84, 73, 79, 206, 67, 73, 84, 128, 67, 73, 82, 67, 85, 211, 67, 73, - 82, 67, 85, 77, 70, 76, 69, 88, 128, 67, 73, 82, 67, 85, 77, 70, 76, 69, - 216, 67, 73, 82, 67, 85, 76, 65, 84, 73, 79, 206, 67, 73, 82, 67, 76, 73, - 78, 71, 128, 67, 73, 82, 67, 76, 73, 78, 199, 67, 73, 82, 67, 76, 69, 83, - 128, 67, 73, 82, 67, 76, 69, 211, 67, 73, 82, 67, 76, 69, 68, 128, 67, - 73, 80, 128, 67, 73, 78, 78, 65, 66, 65, 82, 128, 67, 73, 78, 69, 77, 65, - 128, 67, 73, 206, 67, 73, 77, 128, 67, 73, 205, 67, 73, 73, 128, 67, 73, - 69, 88, 128, 67, 73, 69, 85, 67, 45, 83, 83, 65, 78, 71, 80, 73, 69, 85, - 80, 128, 67, 73, 69, 85, 67, 45, 80, 73, 69, 85, 80, 128, 67, 73, 69, 85, - 67, 45, 73, 69, 85, 78, 71, 128, 67, 73, 69, 85, 195, 67, 73, 69, 84, - 128, 67, 73, 69, 80, 128, 67, 73, 69, 128, 67, 72, 89, 88, 128, 67, 72, - 89, 84, 128, 67, 72, 89, 82, 88, 128, 67, 72, 89, 82, 128, 67, 72, 89, - 80, 128, 67, 72, 87, 86, 128, 67, 72, 85, 88, 128, 67, 72, 85, 82, 88, - 128, 67, 72, 85, 82, 67, 72, 128, 67, 72, 85, 82, 128, 67, 72, 85, 80, - 128, 67, 72, 85, 79, 88, 128, 67, 72, 85, 79, 84, 128, 67, 72, 85, 79, - 80, 128, 67, 72, 85, 79, 128, 67, 72, 85, 76, 65, 128, 67, 72, 85, 128, - 67, 72, 82, 89, 83, 65, 78, 84, 72, 69, 77, 85, 77, 128, 67, 72, 82, 79, - 78, 79, 85, 128, 67, 72, 82, 79, 78, 79, 78, 128, 67, 72, 82, 79, 77, - 193, 67, 72, 82, 79, 193, 67, 72, 82, 73, 86, 73, 128, 67, 72, 82, 73, - 83, 84, 77, 65, 83, 128, 67, 72, 82, 73, 83, 84, 77, 65, 211, 67, 72, 79, - 89, 128, 67, 72, 79, 88, 128, 67, 72, 79, 84, 128, 67, 72, 79, 82, 69, - 86, 77, 193, 67, 72, 79, 82, 65, 83, 77, 73, 65, 206, 67, 72, 79, 80, 83, - 84, 73, 67, 75, 83, 128, 67, 72, 79, 80, 128, 67, 72, 79, 75, 69, 128, - 67, 72, 79, 69, 128, 67, 72, 79, 67, 79, 76, 65, 84, 197, 67, 72, 79, 65, - 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, 71, 83, 73, 79, 83, - 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, 71, 67, 73, 69, 85, - 67, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 73, 79, 83, 128, 67, 72, 73, - 84, 85, 69, 85, 77, 67, 73, 69, 85, 67, 128, 67, 72, 73, 84, 85, 69, 85, - 77, 67, 72, 73, 69, 85, 67, 72, 128, 67, 72, 73, 82, 79, 78, 128, 67, 72, - 73, 82, 69, 84, 128, 67, 72, 73, 80, 77, 85, 78, 75, 128, 67, 72, 73, 78, - 79, 79, 203, 67, 72, 73, 78, 71, 128, 67, 72, 73, 78, 69, 83, 197, 67, - 72, 73, 78, 128, 67, 72, 73, 77, 69, 128, 67, 72, 73, 77, 128, 67, 72, - 73, 76, 76, 213, 67, 72, 73, 76, 68, 82, 69, 206, 67, 72, 73, 76, 68, - 128, 67, 72, 73, 76, 128, 67, 72, 73, 75, 201, 67, 72, 73, 69, 85, 67, - 72, 45, 75, 72, 73, 69, 85, 75, 72, 128, 67, 72, 73, 69, 85, 67, 72, 45, - 72, 73, 69, 85, 72, 128, 67, 72, 73, 69, 85, 67, 200, 67, 72, 73, 67, 75, - 69, 78, 128, 67, 72, 73, 67, 75, 128, 67, 72, 73, 128, 67, 72, 201, 67, - 72, 72, 73, 77, 128, 67, 72, 72, 65, 128, 67, 72, 69, 88, 128, 67, 72, - 69, 86, 82, 79, 78, 128, 67, 72, 69, 86, 82, 79, 206, 67, 72, 69, 84, - 128, 67, 72, 69, 83, 84, 78, 85, 84, 128, 67, 72, 69, 83, 84, 128, 67, - 72, 69, 83, 211, 67, 72, 69, 82, 89, 128, 67, 72, 69, 82, 82, 217, 67, - 72, 69, 82, 82, 73, 69, 83, 128, 67, 72, 69, 81, 85, 69, 82, 69, 196, 67, - 72, 69, 80, 128, 67, 72, 69, 76, 89, 85, 83, 84, 75, 65, 128, 67, 72, 69, - 76, 78, 85, 128, 67, 72, 69, 73, 78, 65, 80, 128, 67, 72, 69, 73, 75, 72, - 69, 73, 128, 67, 72, 69, 73, 75, 72, 65, 78, 128, 67, 72, 69, 69, 83, - 197, 67, 72, 69, 69, 82, 73, 78, 199, 67, 72, 69, 69, 77, 128, 67, 72, - 69, 69, 75, 211, 67, 72, 69, 69, 75, 128, 67, 72, 69, 69, 128, 67, 72, - 69, 67, 75, 69, 210, 67, 72, 69, 67, 75, 128, 67, 72, 69, 67, 203, 67, - 72, 197, 67, 72, 65, 88, 128, 67, 72, 65, 86, 73, 89, 65, 78, 73, 128, - 67, 72, 65, 84, 84, 65, 87, 65, 128, 67, 72, 65, 84, 128, 67, 72, 65, 83, - 72, 75, 65, 128, 67, 72, 65, 83, 72, 75, 193, 67, 72, 65, 82, 84, 128, - 67, 72, 65, 82, 212, 67, 72, 65, 82, 73, 79, 84, 128, 67, 72, 65, 82, 73, - 79, 212, 67, 72, 65, 82, 65, 67, 84, 69, 82, 83, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 70, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 70, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 70, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 70, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 70, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 70, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 70, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 70, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 69, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 69, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 69, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 69, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 69, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 69, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 69, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 69, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 68, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 68, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 68, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 68, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 68, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 68, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 68, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 68, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 68, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 67, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 67, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 67, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 67, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 67, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 67, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 67, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 67, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 67, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 67, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 66, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 66, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 66, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 66, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 66, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 66, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 66, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 66, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 66, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 65, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 65, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 65, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 65, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 65, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 65, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 65, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 65, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 57, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 57, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 57, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 57, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 57, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 57, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 57, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 57, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 56, 70, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 56, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 56, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 56, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 56, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 65, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 57, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 56, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 55, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 56, 54, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 56, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 56, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 56, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 56, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 49, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 48, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 70, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 69, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 55, 68, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 55, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 55, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 55, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 55, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 56, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 55, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 54, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 53, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 55, 52, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 55, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 55, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 55, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 55, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 70, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 69, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 68, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 67, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 54, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 54, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 54, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 54, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 54, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 54, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 54, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 54, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 53, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 53, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 53, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 53, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 53, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 53, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 53, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 53, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 52, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 52, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 52, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 52, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 52, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 52, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 52, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 52, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 52, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 51, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 51, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 51, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 51, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 51, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 51, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 51, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 51, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 51, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 51, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 50, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 50, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 50, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 50, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 50, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 50, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 50, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 50, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 50, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 49, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 49, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 49, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 49, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 49, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 49, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 49, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 49, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 48, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 48, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 48, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 48, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 48, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 48, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 48, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 48, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 70, 70, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 70, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 70, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 70, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 70, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 65, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 57, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 56, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 55, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 70, 54, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 70, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 70, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 70, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 70, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 49, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 48, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 70, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 69, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 69, 68, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 69, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 69, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 69, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 69, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 56, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 55, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 54, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 53, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 69, 52, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 69, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 69, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 69, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 69, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 70, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 69, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 68, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 67, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 68, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 68, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 68, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 68, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 68, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 68, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 68, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 68, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 67, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 67, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 67, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 67, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 67, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 67, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 67, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 67, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 66, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 66, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 66, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 66, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 66, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 66, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 66, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 66, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 66, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 65, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 65, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 65, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 65, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 65, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 65, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 65, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 65, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 65, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 65, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 57, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 57, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 57, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 57, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 57, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 57, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 57, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 57, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 57, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 56, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 56, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 56, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 56, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 56, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 56, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 56, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 56, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 55, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 55, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 55, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 55, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 55, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 55, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 55, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 55, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 68, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 68, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 68, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 68, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 68, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 68, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 67, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 67, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 67, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 67, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 67, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 67, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 67, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 67, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 67, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 66, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 66, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 66, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 66, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 66, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 66, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 66, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 66, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 65, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 65, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 65, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 65, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 65, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 65, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 65, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 65, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 57, 70, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 57, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 57, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 57, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 57, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 65, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 57, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 56, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 55, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 57, 54, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 57, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 57, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 57, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 57, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 49, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 48, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 70, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 69, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 56, 68, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 56, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 56, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 56, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 56, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 56, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 55, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 54, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 53, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 56, 52, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 56, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 56, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 56, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 56, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 70, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 69, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 68, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 67, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 55, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 55, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 55, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 55, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 55, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 55, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 55, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 55, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 54, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 54, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 54, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 54, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 54, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 54, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 54, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 54, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 53, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 53, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 53, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 53, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 53, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 53, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 53, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 53, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 53, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 52, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 52, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 52, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 52, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 52, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 52, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 52, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 52, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 52, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 52, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 51, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 51, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 51, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 51, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 51, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 51, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 51, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 51, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 51, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 50, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 50, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 50, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 50, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 50, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 50, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 50, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 50, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 49, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 49, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 49, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 49, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 49, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 49, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 49, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 49, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 48, 70, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 48, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 48, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 48, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 48, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 65, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 57, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 56, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 55, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 48, 54, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 48, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 48, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 48, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 48, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 49, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 48, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 70, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 69, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 70, 68, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 70, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 70, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 70, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 70, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 56, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 55, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 54, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 53, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 70, 52, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 70, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 70, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 70, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 70, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 70, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 69, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 68, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 67, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 69, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 69, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 69, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 69, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 69, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 69, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 69, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 69, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 68, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 68, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 68, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 68, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 68, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 68, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 68, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 68, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 67, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 67, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 67, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 67, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 67, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 67, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 67, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 67, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 67, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 66, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 66, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 66, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 66, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 66, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 66, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 66, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 66, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 66, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 66, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 65, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 65, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 65, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 65, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 65, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 65, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 65, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 65, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 65, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 57, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 57, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 57, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 57, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 57, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 57, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 57, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 57, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 56, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 56, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 56, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 56, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 56, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 56, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 56, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 56, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 55, 70, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 55, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 55, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 55, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 55, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 65, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 57, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 56, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 55, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 55, 54, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 55, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 55, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 55, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 55, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 49, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 48, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 70, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 69, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 54, 68, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 54, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 54, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 54, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 54, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 56, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 55, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 54, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 53, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 54, 52, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 54, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 54, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 54, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 54, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 70, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 69, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 68, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 67, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 53, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 53, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 53, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 53, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 53, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 53, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 53, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 53, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 52, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 52, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 52, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 52, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 52, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 52, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 52, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 52, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 51, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 51, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 51, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 51, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 51, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 51, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 51, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 51, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 51, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 50, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 50, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 50, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 50, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 50, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 50, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 50, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 50, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 50, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 50, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 49, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 49, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 49, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 49, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 49, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 49, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 49, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 49, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 49, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 48, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 48, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 48, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 48, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 48, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 48, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 48, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 48, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 210, 67, 72, 65, 82, 128, 67, 72, - 65, 80, 84, 69, 82, 128, 67, 72, 65, 80, 128, 67, 72, 65, 78, 71, 128, - 67, 72, 65, 78, 128, 67, 72, 65, 77, 75, 79, 128, 67, 72, 65, 77, 73, 76, - 79, 78, 128, 67, 72, 65, 77, 73, 76, 73, 128, 67, 72, 65, 205, 67, 72, - 65, 75, 77, 193, 67, 72, 65, 73, 78, 83, 128, 67, 72, 65, 68, 65, 128, - 67, 72, 65, 196, 67, 72, 65, 65, 128, 67, 71, 74, 128, 67, 69, 88, 128, - 67, 69, 86, 73, 84, 85, 128, 67, 69, 82, 69, 83, 128, 67, 69, 82, 69, 77, - 79, 78, 89, 128, 67, 69, 82, 69, 75, 128, 67, 69, 82, 45, 87, 65, 128, - 67, 69, 80, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, 83, 83, 65, - 78, 71, 83, 73, 79, 83, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, - 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, 128, 67, 69, 79, 78, 71, 67, 72, - 73, 69, 85, 77, 83, 73, 79, 83, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, - 85, 77, 67, 73, 69, 85, 67, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, - 77, 67, 72, 73, 69, 85, 67, 72, 128, 67, 69, 78, 84, 85, 82, 73, 65, 204, - 67, 69, 78, 84, 82, 69, 76, 73, 78, 197, 67, 69, 78, 84, 82, 69, 68, 128, - 67, 69, 78, 84, 82, 69, 196, 67, 69, 78, 84, 82, 69, 128, 67, 69, 78, 84, - 82, 197, 67, 69, 78, 84, 82, 65, 76, 73, 90, 65, 84, 73, 79, 206, 67, 69, - 78, 128, 67, 69, 76, 84, 73, 195, 67, 69, 76, 83, 73, 85, 83, 128, 67, - 69, 76, 69, 66, 82, 65, 84, 73, 79, 78, 128, 67, 69, 73, 82, 84, 128, 67, - 69, 73, 76, 73, 78, 71, 128, 67, 69, 73, 76, 73, 78, 199, 67, 69, 69, 86, - 128, 67, 69, 69, 66, 128, 67, 69, 69, 128, 67, 69, 68, 73, 76, 76, 65, - 128, 67, 69, 68, 73, 76, 76, 193, 67, 69, 68, 201, 67, 69, 67, 69, 75, - 128, 67, 69, 67, 65, 75, 128, 67, 69, 67, 65, 203, 67, 69, 65, 76, 67, - 128, 67, 67, 85, 128, 67, 67, 79, 128, 67, 67, 73, 128, 67, 67, 72, 85, - 128, 67, 67, 72, 79, 128, 67, 67, 72, 73, 128, 67, 67, 72, 72, 85, 128, - 67, 67, 72, 72, 79, 128, 67, 67, 72, 72, 73, 128, 67, 67, 72, 72, 69, 69, - 128, 67, 67, 72, 72, 69, 128, 67, 67, 72, 72, 65, 65, 128, 67, 67, 72, - 72, 65, 128, 67, 67, 72, 69, 69, 128, 67, 67, 72, 69, 128, 67, 67, 72, - 65, 65, 128, 67, 67, 72, 65, 128, 67, 67, 72, 128, 67, 67, 69, 69, 128, - 67, 67, 65, 65, 128, 67, 65, 89, 78, 128, 67, 65, 89, 65, 78, 78, 65, - 128, 67, 65, 88, 128, 67, 65, 86, 69, 128, 67, 65, 85, 84, 73, 79, 206, - 67, 65, 85, 76, 68, 82, 79, 78, 128, 67, 65, 85, 68, 65, 84, 197, 67, 65, - 85, 68, 65, 128, 67, 65, 85, 67, 65, 83, 73, 65, 206, 67, 65, 85, 128, - 67, 65, 84, 65, 87, 65, 128, 67, 65, 84, 128, 67, 65, 212, 67, 65, 83, - 84, 76, 69, 128, 67, 65, 83, 75, 69, 212, 67, 65, 82, 89, 83, 84, 73, 65, - 206, 67, 65, 82, 84, 87, 72, 69, 69, 76, 128, 67, 65, 82, 84, 82, 73, 68, - 71, 69, 128, 67, 65, 82, 84, 128, 67, 65, 82, 211, 67, 65, 82, 82, 79, - 84, 128, 67, 65, 82, 82, 73, 65, 71, 197, 67, 65, 82, 80, 69, 78, 84, 82, - 217, 67, 65, 82, 208, 67, 65, 82, 79, 85, 83, 69, 204, 67, 65, 82, 79, - 78, 128, 67, 65, 82, 79, 206, 67, 65, 82, 73, 203, 67, 65, 82, 73, 65, - 206, 67, 65, 82, 69, 84, 128, 67, 65, 82, 69, 212, 67, 65, 82, 197, 67, - 65, 82, 68, 83, 128, 67, 65, 82, 196, 67, 65, 82, 128, 67, 65, 210, 67, - 65, 80, 85, 212, 67, 65, 80, 84, 73, 86, 69, 128, 67, 65, 80, 82, 73, 67, - 79, 82, 78, 128, 67, 65, 80, 80, 69, 196, 67, 65, 80, 79, 128, 67, 65, - 80, 73, 84, 85, 76, 85, 77, 128, 67, 65, 80, 73, 84, 65, 76, 128, 67, 65, - 78, 84, 73, 76, 76, 65, 84, 73, 79, 206, 67, 65, 78, 79, 69, 128, 67, 65, - 78, 78, 79, 78, 128, 67, 65, 78, 78, 69, 196, 67, 65, 78, 199, 67, 65, - 78, 69, 128, 67, 65, 78, 68, 89, 128, 67, 65, 78, 68, 82, 65, 66, 73, 78, - 68, 85, 128, 67, 65, 78, 68, 82, 65, 66, 73, 78, 68, 213, 67, 65, 78, 68, - 82, 65, 128, 67, 65, 78, 68, 82, 193, 67, 65, 78, 68, 76, 69, 128, 67, - 65, 78, 67, 69, 82, 128, 67, 65, 78, 67, 69, 76, 76, 65, 84, 73, 79, 206, - 67, 65, 78, 67, 69, 76, 128, 67, 65, 78, 67, 69, 204, 67, 65, 78, 128, - 67, 65, 77, 80, 73, 78, 71, 128, 67, 65, 77, 78, 85, 195, 67, 65, 77, 69, - 82, 65, 128, 67, 65, 77, 69, 82, 193, 67, 65, 77, 69, 76, 128, 67, 65, - 76, 89, 65, 128, 67, 65, 76, 89, 193, 67, 65, 76, 88, 128, 67, 65, 76, - 76, 128, 67, 65, 76, 204, 67, 65, 76, 69, 78, 68, 65, 82, 128, 67, 65, - 76, 69, 78, 68, 65, 210, 67, 65, 76, 67, 85, 76, 65, 84, 79, 82, 128, 67, - 65, 76, 67, 128, 67, 65, 75, 82, 65, 128, 67, 65, 75, 197, 67, 65, 73, - 128, 67, 65, 72, 128, 67, 65, 69, 83, 85, 82, 65, 128, 67, 65, 68, 85, - 67, 69, 85, 83, 128, 67, 65, 68, 193, 67, 65, 67, 84, 85, 83, 128, 67, - 65, 66, 76, 69, 87, 65, 89, 128, 67, 65, 66, 73, 78, 69, 84, 128, 67, 65, - 66, 66, 65, 71, 69, 45, 84, 82, 69, 69, 128, 67, 65, 65, 78, 71, 128, 67, - 65, 65, 73, 128, 67, 193, 67, 48, 50, 52, 128, 67, 48, 50, 51, 128, 67, - 48, 50, 50, 128, 67, 48, 50, 49, 128, 67, 48, 50, 48, 128, 67, 48, 49, - 57, 128, 67, 48, 49, 56, 128, 67, 48, 49, 55, 128, 67, 48, 49, 54, 128, - 67, 48, 49, 53, 128, 67, 48, 49, 52, 128, 67, 48, 49, 51, 128, 67, 48, - 49, 50, 128, 67, 48, 49, 49, 128, 67, 48, 49, 48, 65, 128, 67, 48, 49, - 48, 128, 67, 48, 48, 57, 128, 67, 48, 48, 56, 128, 67, 48, 48, 55, 128, - 67, 48, 48, 54, 128, 67, 48, 48, 53, 128, 67, 48, 48, 52, 128, 67, 48, - 48, 51, 128, 67, 48, 48, 50, 67, 128, 67, 48, 48, 50, 66, 128, 67, 48, - 48, 50, 65, 128, 67, 48, 48, 50, 128, 67, 48, 48, 49, 128, 67, 45, 83, - 73, 77, 80, 76, 73, 70, 73, 69, 196, 67, 45, 51, 57, 128, 67, 45, 49, 56, - 128, 66, 90, 85, 78, 199, 66, 90, 72, 201, 66, 89, 84, 197, 66, 89, 69, - 76, 79, 82, 85, 83, 83, 73, 65, 78, 45, 85, 75, 82, 65, 73, 78, 73, 65, - 206, 66, 88, 71, 128, 66, 87, 73, 128, 66, 87, 69, 69, 128, 66, 87, 69, - 128, 66, 87, 65, 128, 66, 85, 85, 77, 73, 83, 72, 128, 66, 85, 84, 84, - 79, 78, 128, 66, 85, 84, 84, 79, 206, 66, 85, 84, 84, 69, 82, 70, 76, 89, - 128, 66, 85, 84, 84, 69, 82, 128, 66, 85, 212, 66, 85, 83, 84, 211, 66, - 85, 83, 212, 66, 85, 83, 83, 89, 69, 82, 85, 128, 66, 85, 83, 73, 78, 69, - 83, 211, 66, 85, 211, 66, 85, 82, 213, 66, 85, 82, 82, 73, 84, 79, 128, - 66, 85, 82, 50, 128, 66, 85, 210, 66, 85, 79, 89, 128, 66, 85, 79, 88, - 128, 66, 85, 79, 80, 128, 66, 85, 78, 78, 217, 66, 85, 78, 71, 128, 66, - 85, 77, 80, 217, 66, 85, 76, 85, 71, 128, 66, 85, 76, 85, 199, 66, 85, - 76, 76, 83, 69, 89, 69, 128, 66, 85, 76, 76, 211, 66, 85, 76, 76, 72, 79, - 82, 78, 128, 66, 85, 76, 76, 72, 79, 82, 206, 66, 85, 76, 76, 69, 84, - 128, 66, 85, 76, 76, 69, 212, 66, 85, 76, 76, 128, 66, 85, 76, 66, 128, - 66, 85, 75, 89, 128, 66, 85, 73, 76, 68, 73, 78, 71, 83, 128, 66, 85, 73, - 76, 68, 73, 78, 71, 128, 66, 85, 73, 76, 68, 73, 78, 199, 66, 85, 72, 73, - 196, 66, 85, 71, 73, 78, 69, 83, 197, 66, 85, 71, 128, 66, 85, 70, 70, - 65, 76, 79, 128, 66, 85, 68, 128, 66, 85, 67, 75, 76, 69, 128, 66, 85, - 67, 75, 69, 84, 128, 66, 85, 66, 66, 76, 69, 83, 128, 66, 85, 66, 66, 76, - 69, 128, 66, 85, 66, 66, 76, 197, 66, 83, 84, 65, 82, 128, 66, 83, 75, - 85, 210, 66, 83, 75, 65, 173, 66, 83, 68, 85, 211, 66, 82, 85, 83, 200, - 66, 82, 79, 87, 206, 66, 82, 79, 79, 77, 128, 66, 82, 79, 78, 90, 69, - 128, 66, 82, 79, 75, 69, 206, 66, 82, 79, 67, 67, 79, 76, 73, 128, 66, - 82, 79, 65, 196, 66, 82, 73, 83, 84, 76, 69, 128, 66, 82, 73, 71, 72, 84, - 78, 69, 83, 211, 66, 82, 73, 69, 70, 83, 128, 66, 82, 73, 69, 70, 67, 65, - 83, 69, 128, 66, 82, 73, 68, 71, 197, 66, 82, 73, 68, 197, 66, 82, 73, - 67, 75, 128, 66, 82, 73, 128, 66, 82, 69, 86, 73, 83, 128, 66, 82, 69, - 86, 69, 45, 77, 65, 67, 82, 79, 78, 128, 66, 82, 69, 86, 197, 66, 82, 69, - 65, 84, 72, 217, 66, 82, 69, 65, 84, 200, 66, 82, 69, 65, 83, 84, 45, 70, - 69, 69, 68, 73, 78, 71, 128, 66, 82, 69, 65, 75, 84, 72, 82, 79, 85, 71, - 72, 128, 66, 82, 68, 193, 66, 82, 65, 78, 67, 72, 73, 78, 199, 66, 82, - 65, 78, 67, 72, 69, 83, 128, 66, 82, 65, 78, 67, 72, 128, 66, 82, 65, 78, - 67, 200, 66, 82, 65, 75, 67, 69, 84, 128, 66, 82, 65, 73, 78, 128, 66, - 82, 65, 67, 75, 69, 84, 211, 66, 82, 65, 67, 75, 69, 84, 69, 196, 66, 82, - 65, 67, 75, 69, 84, 128, 66, 82, 65, 67, 75, 69, 212, 66, 82, 65, 67, 69, - 128, 66, 81, 128, 66, 80, 72, 128, 66, 79, 89, 211, 66, 79, 89, 128, 66, - 79, 88, 73, 78, 199, 66, 79, 87, 84, 73, 69, 128, 66, 79, 87, 84, 73, - 197, 66, 79, 87, 76, 73, 78, 71, 128, 66, 79, 87, 76, 128, 66, 79, 87, - 204, 66, 79, 87, 73, 78, 199, 66, 79, 215, 66, 79, 85, 81, 85, 69, 84, - 128, 66, 79, 85, 81, 85, 69, 212, 66, 79, 85, 78, 68, 65, 82, 217, 66, - 79, 84, 84, 79, 77, 45, 83, 72, 65, 68, 69, 196, 66, 79, 84, 84, 79, 77, - 45, 76, 73, 71, 72, 84, 69, 196, 66, 79, 84, 84, 79, 77, 128, 66, 79, 84, - 84, 79, 205, 66, 79, 84, 84, 76, 69, 128, 66, 79, 84, 84, 76, 197, 66, - 79, 84, 200, 66, 79, 82, 90, 89, 128, 66, 79, 82, 90, 65, 89, 65, 128, - 66, 79, 82, 85, 84, 79, 128, 66, 79, 82, 65, 88, 45, 51, 128, 66, 79, 82, - 65, 88, 45, 50, 128, 66, 79, 82, 65, 88, 128, 66, 79, 80, 79, 77, 79, 70, - 207, 66, 79, 79, 84, 83, 128, 66, 79, 79, 84, 128, 66, 79, 79, 77, 69, - 82, 65, 78, 71, 128, 66, 79, 79, 75, 83, 128, 66, 79, 79, 75, 77, 65, 82, - 75, 128, 66, 79, 79, 75, 77, 65, 82, 203, 66, 79, 78, 69, 128, 66, 79, - 77, 66, 128, 66, 79, 77, 128, 66, 79, 76, 84, 128, 66, 79, 76, 212, 66, - 79, 72, 65, 73, 82, 73, 195, 66, 79, 68, 89, 128, 66, 79, 68, 217, 66, - 79, 65, 82, 128, 66, 79, 65, 128, 66, 76, 85, 69, 66, 69, 82, 82, 73, 69, - 83, 128, 66, 76, 85, 69, 128, 66, 76, 85, 197, 66, 76, 79, 87, 73, 78, - 199, 66, 76, 79, 87, 70, 73, 83, 72, 128, 66, 76, 79, 215, 66, 76, 79, - 83, 83, 79, 77, 128, 66, 76, 79, 79, 68, 128, 66, 76, 79, 78, 196, 66, - 76, 79, 67, 75, 45, 55, 128, 66, 76, 79, 67, 75, 45, 54, 128, 66, 76, 79, - 67, 75, 45, 53, 128, 66, 76, 79, 67, 75, 45, 52, 128, 66, 76, 79, 67, 75, - 45, 51, 128, 66, 76, 79, 67, 75, 45, 50, 128, 66, 76, 79, 67, 75, 45, 49, - 51, 53, 56, 128, 66, 76, 79, 67, 75, 128, 66, 76, 73, 78, 203, 66, 76, - 65, 78, 75, 128, 66, 76, 65, 78, 203, 66, 76, 65, 68, 197, 66, 76, 65, - 67, 75, 76, 69, 84, 84, 69, 210, 66, 76, 65, 67, 75, 70, 79, 79, 212, 66, - 76, 65, 67, 75, 45, 76, 69, 84, 84, 69, 210, 66, 76, 65, 67, 75, 45, 70, - 69, 65, 84, 72, 69, 82, 69, 196, 66, 76, 65, 67, 75, 128, 66, 75, 65, - 173, 66, 73, 84, 84, 69, 82, 128, 66, 73, 84, 73, 78, 199, 66, 73, 84, - 197, 66, 73, 84, 67, 79, 73, 206, 66, 73, 83, 79, 78, 128, 66, 73, 83, - 77, 85, 84, 200, 66, 73, 83, 77, 73, 76, 76, 65, 200, 66, 73, 83, 72, 79, - 208, 66, 73, 83, 69, 67, 84, 73, 78, 199, 66, 73, 83, 65, 72, 128, 66, - 73, 82, 85, 128, 66, 73, 82, 84, 72, 68, 65, 217, 66, 73, 82, 71, 65, - 128, 66, 73, 82, 71, 193, 66, 73, 82, 68, 128, 66, 73, 79, 72, 65, 90, - 65, 82, 196, 66, 73, 78, 79, 86, 73, 76, 69, 128, 66, 73, 78, 79, 67, 85, - 76, 65, 210, 66, 73, 78, 68, 73, 78, 199, 66, 73, 78, 68, 73, 128, 66, - 73, 78, 65, 82, 217, 66, 73, 76, 76, 73, 79, 78, 83, 128, 66, 73, 76, 76, - 73, 65, 82, 68, 83, 128, 66, 73, 76, 76, 69, 196, 66, 73, 76, 65, 66, 73, - 65, 204, 66, 73, 75, 73, 78, 73, 128, 66, 73, 71, 128, 66, 73, 199, 66, - 73, 69, 84, 128, 66, 73, 68, 69, 78, 84, 65, 204, 66, 73, 68, 65, 75, 85, - 79, 206, 66, 73, 67, 89, 67, 76, 73, 83, 84, 128, 66, 73, 67, 89, 67, 76, - 69, 83, 128, 66, 73, 67, 89, 67, 76, 69, 128, 66, 73, 67, 69, 80, 83, - 128, 66, 73, 66, 76, 69, 45, 67, 82, 69, 197, 66, 73, 66, 128, 66, 201, - 66, 72, 85, 128, 66, 72, 79, 79, 128, 66, 72, 79, 128, 66, 72, 73, 128, - 66, 72, 69, 84, 72, 128, 66, 72, 69, 69, 128, 66, 72, 69, 128, 66, 72, - 65, 84, 84, 73, 80, 82, 79, 76, 213, 66, 72, 65, 77, 128, 66, 72, 65, 73, - 75, 83, 85, 75, 201, 66, 72, 65, 65, 128, 66, 72, 65, 128, 66, 69, 89, - 89, 65, 76, 128, 66, 69, 88, 128, 66, 69, 86, 69, 82, 65, 71, 69, 128, - 66, 69, 86, 69, 82, 65, 71, 197, 66, 69, 84, 87, 69, 69, 78, 128, 66, 69, - 84, 87, 69, 69, 206, 66, 69, 84, 72, 128, 66, 69, 84, 65, 128, 66, 69, - 84, 193, 66, 69, 212, 66, 69, 83, 73, 68, 197, 66, 69, 82, 75, 65, 78, - 65, 206, 66, 69, 82, 66, 69, 210, 66, 69, 80, 128, 66, 69, 79, 82, 195, - 66, 69, 78, 90, 69, 78, 197, 66, 69, 78, 84, 207, 66, 69, 78, 84, 128, - 66, 69, 78, 212, 66, 69, 78, 71, 65, 76, 201, 66, 69, 78, 68, 69, 128, - 66, 69, 78, 68, 128, 66, 69, 78, 196, 66, 69, 206, 66, 69, 76, 84, 128, - 66, 69, 76, 212, 66, 69, 76, 79, 215, 66, 69, 76, 76, 72, 79, 208, 66, - 69, 76, 76, 128, 66, 69, 76, 204, 66, 69, 76, 71, 84, 72, 79, 210, 66, - 69, 73, 84, 72, 128, 66, 69, 72, 73, 78, 196, 66, 69, 72, 69, 72, 128, - 66, 69, 72, 69, 200, 66, 69, 72, 128, 66, 69, 200, 66, 69, 71, 73, 78, - 78, 73, 78, 71, 128, 66, 69, 71, 73, 78, 78, 69, 82, 128, 66, 69, 71, 73, + 73, 78, 69, 82, 128, 67, 79, 78, 74, 79, 73, 78, 69, 68, 128, 67, 79, 78, + 74, 79, 73, 78, 69, 196, 67, 79, 78, 73, 67, 65, 204, 67, 79, 78, 71, 82, + 85, 69, 78, 212, 67, 79, 78, 71, 82, 65, 84, 85, 76, 65, 84, 73, 79, 78, + 128, 67, 79, 78, 70, 85, 83, 69, 196, 67, 79, 78, 70, 79, 85, 78, 68, 69, + 196, 67, 79, 78, 70, 76, 73, 67, 84, 128, 67, 79, 78, 70, 69, 84, 84, + 201, 67, 79, 78, 67, 65, 86, 69, 45, 83, 73, 68, 69, 196, 67, 79, 78, 67, + 65, 86, 69, 45, 80, 79, 73, 78, 84, 69, 196, 67, 79, 77, 80, 85, 84, 69, + 82, 83, 128, 67, 79, 77, 80, 85, 84, 69, 82, 128, 67, 79, 77, 80, 82, 69, + 83, 83, 73, 79, 78, 128, 67, 79, 77, 80, 82, 69, 83, 83, 69, 196, 67, 79, + 77, 80, 79, 83, 73, 84, 73, 79, 78, 128, 67, 79, 77, 80, 79, 83, 73, 84, + 73, 79, 206, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 55, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 55, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 55, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 55, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, + 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 55, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 55, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 55, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 55, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, + 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 55, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 55, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 55, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 55, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, + 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 55, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 55, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 55, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 55, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, + 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 55, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 55, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 55, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 55, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, + 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 55, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 55, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 57, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 56, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 55, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 55, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, + 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 52, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 51, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 55, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 55, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 48, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 57, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 55, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 55, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, + 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 53, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 52, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 55, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 55, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 49, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 48, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 54, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 53, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 50, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 49, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 55, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 54, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 51, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 50, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 57, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 56, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 52, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 51, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 48, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 57, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 53, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 52, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 49, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 48, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 54, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 53, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 50, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 49, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 55, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 54, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 51, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 50, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 57, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 56, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 52, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 51, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 48, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 57, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 53, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 52, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 49, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 48, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 54, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 53, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 50, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 49, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 55, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 54, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 51, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 50, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 57, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 56, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 52, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 51, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 48, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 57, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 53, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 52, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 49, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 48, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 54, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 53, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 50, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 49, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 55, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 54, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 51, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 50, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 57, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 56, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 52, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 51, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 48, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 57, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 53, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 52, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 49, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 48, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 54, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 53, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 50, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 49, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 55, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 54, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 51, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 50, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 57, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 56, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 52, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 51, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 48, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 57, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 53, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 52, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 49, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 48, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 54, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 53, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 50, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 49, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 55, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 54, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 51, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 50, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 57, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 56, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 52, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 51, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 48, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 57, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 53, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 52, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 49, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 48, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 54, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 53, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 50, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 49, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 55, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 54, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 51, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 50, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 57, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 56, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 52, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 51, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 48, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 57, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 53, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 52, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 49, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 48, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 54, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 53, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 50, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 49, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 55, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 54, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 51, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 50, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 212, + 67, 79, 77, 80, 76, 73, 65, 78, 67, 69, 128, 67, 79, 77, 80, 76, 69, 84, + 73, 79, 78, 128, 67, 79, 77, 80, 76, 69, 84, 69, 68, 128, 67, 79, 77, 80, + 76, 69, 77, 69, 78, 84, 128, 67, 79, 77, 80, 65, 83, 83, 128, 67, 79, 77, + 80, 65, 82, 69, 128, 67, 79, 77, 77, 79, 206, 67, 79, 77, 77, 69, 82, 67, + 73, 65, 204, 67, 79, 77, 77, 65, 78, 68, 128, 67, 79, 77, 77, 65, 128, + 67, 79, 77, 77, 193, 67, 79, 77, 69, 84, 128, 67, 79, 77, 66, 73, 78, 69, + 68, 128, 67, 79, 77, 66, 73, 78, 65, 84, 73, 79, 78, 128, 67, 79, 77, 66, + 128, 67, 79, 76, 85, 77, 78, 128, 67, 79, 76, 79, 82, 128, 67, 79, 76, + 76, 73, 83, 73, 79, 206, 67, 79, 76, 76, 128, 67, 79, 76, 196, 67, 79, + 73, 78, 128, 67, 79, 70, 70, 73, 78, 128, 67, 79, 69, 78, 71, 128, 67, + 79, 69, 78, 199, 67, 79, 68, 65, 128, 67, 79, 67, 79, 78, 85, 84, 128, + 67, 79, 67, 75, 84, 65, 73, 204, 67, 79, 67, 75, 82, 79, 65, 67, 72, 128, + 67, 79, 65, 84, 128, 67, 79, 65, 83, 84, 69, 82, 128, 67, 79, 65, 128, + 67, 77, 51, 48, 50, 128, 67, 77, 51, 48, 49, 128, 67, 77, 49, 49, 52, + 128, 67, 77, 49, 49, 50, 128, 67, 77, 49, 49, 48, 128, 67, 77, 49, 48, + 57, 128, 67, 77, 49, 48, 56, 128, 67, 77, 49, 48, 55, 128, 67, 77, 49, + 48, 53, 128, 67, 77, 49, 48, 52, 128, 67, 77, 49, 48, 51, 128, 67, 77, + 49, 48, 50, 128, 67, 77, 49, 48, 49, 128, 67, 77, 49, 48, 48, 128, 67, + 77, 48, 57, 57, 128, 67, 77, 48, 57, 56, 128, 67, 77, 48, 57, 55, 128, + 67, 77, 48, 57, 54, 128, 67, 77, 48, 57, 53, 128, 67, 77, 48, 57, 52, + 128, 67, 77, 48, 57, 50, 128, 67, 77, 48, 57, 49, 128, 67, 77, 48, 57, + 48, 128, 67, 77, 48, 56, 57, 128, 67, 77, 48, 56, 56, 128, 67, 77, 48, + 56, 55, 128, 67, 77, 48, 56, 54, 128, 67, 77, 48, 56, 53, 128, 67, 77, + 48, 56, 52, 128, 67, 77, 48, 56, 51, 128, 67, 77, 48, 56, 50, 128, 67, + 77, 48, 56, 49, 128, 67, 77, 48, 56, 48, 128, 67, 77, 48, 55, 57, 128, + 67, 77, 48, 55, 56, 128, 67, 77, 48, 55, 54, 128, 67, 77, 48, 55, 53, 66, + 128, 67, 77, 48, 55, 53, 128, 67, 77, 48, 55, 52, 128, 67, 77, 48, 55, + 51, 128, 67, 77, 48, 55, 50, 128, 67, 77, 48, 55, 49, 128, 67, 77, 48, + 55, 48, 128, 67, 77, 48, 54, 57, 128, 67, 77, 48, 54, 56, 128, 67, 77, + 48, 54, 55, 128, 67, 77, 48, 54, 54, 128, 67, 77, 48, 54, 52, 128, 67, + 77, 48, 54, 51, 128, 67, 77, 48, 54, 50, 128, 67, 77, 48, 54, 49, 128, + 67, 77, 48, 54, 48, 128, 67, 77, 48, 53, 57, 128, 67, 77, 48, 53, 56, + 128, 67, 77, 48, 53, 54, 128, 67, 77, 48, 53, 53, 128, 67, 77, 48, 53, + 52, 128, 67, 77, 48, 53, 51, 128, 67, 77, 48, 53, 50, 128, 67, 77, 48, + 53, 49, 128, 67, 77, 48, 53, 48, 128, 67, 77, 48, 52, 57, 128, 67, 77, + 48, 52, 55, 128, 67, 77, 48, 52, 54, 128, 67, 77, 48, 52, 52, 128, 67, + 77, 48, 52, 49, 128, 67, 77, 48, 52, 48, 128, 67, 77, 48, 51, 57, 128, + 67, 77, 48, 51, 56, 128, 67, 77, 48, 51, 55, 128, 67, 77, 48, 51, 54, + 128, 67, 77, 48, 51, 53, 128, 67, 77, 48, 51, 52, 128, 67, 77, 48, 51, + 51, 128, 67, 77, 48, 51, 48, 128, 67, 77, 48, 50, 57, 128, 67, 77, 48, + 50, 56, 128, 67, 77, 48, 50, 55, 128, 67, 77, 48, 50, 54, 128, 67, 77, + 48, 50, 53, 128, 67, 77, 48, 50, 52, 128, 67, 77, 48, 50, 51, 128, 67, + 77, 48, 50, 49, 128, 67, 77, 48, 49, 57, 128, 67, 77, 48, 49, 55, 128, + 67, 77, 48, 49, 53, 128, 67, 77, 48, 49, 51, 128, 67, 77, 48, 49, 50, 66, + 128, 67, 77, 48, 49, 50, 128, 67, 77, 48, 49, 49, 128, 67, 77, 48, 49, + 48, 128, 67, 77, 48, 48, 57, 128, 67, 77, 48, 48, 56, 128, 67, 77, 48, + 48, 55, 128, 67, 77, 48, 48, 54, 128, 67, 77, 48, 48, 53, 128, 67, 77, + 48, 48, 52, 128, 67, 77, 48, 48, 50, 128, 67, 77, 48, 48, 49, 128, 67, + 77, 128, 67, 205, 67, 76, 85, 83, 84, 69, 82, 45, 73, 78, 73, 84, 73, 65, + 204, 67, 76, 85, 83, 84, 69, 82, 45, 70, 73, 78, 65, 204, 67, 76, 85, 83, + 84, 69, 210, 67, 76, 85, 66, 83, 128, 67, 76, 85, 66, 45, 83, 80, 79, 75, + 69, 196, 67, 76, 85, 66, 128, 67, 76, 85, 194, 67, 76, 79, 87, 206, 67, + 76, 79, 86, 69, 82, 128, 67, 76, 79, 85, 68, 128, 67, 76, 79, 85, 196, + 67, 76, 79, 84, 72, 69, 83, 128, 67, 76, 79, 84, 72, 128, 67, 76, 79, 83, + 69, 84, 128, 67, 76, 79, 83, 69, 78, 69, 83, 83, 128, 67, 76, 79, 83, 69, + 68, 128, 67, 76, 79, 83, 197, 67, 76, 79, 67, 75, 87, 73, 83, 197, 67, + 76, 79, 67, 203, 67, 76, 73, 86, 73, 83, 128, 67, 76, 73, 80, 66, 79, 65, + 82, 68, 128, 67, 76, 73, 78, 75, 73, 78, 199, 67, 76, 73, 78, 71, 73, 78, + 199, 67, 76, 73, 77, 66, 73, 78, 71, 128, 67, 76, 73, 77, 65, 67, 85, 83, + 128, 67, 76, 73, 70, 70, 128, 67, 76, 73, 67, 75, 128, 67, 76, 73, 67, + 203, 67, 76, 69, 70, 45, 50, 128, 67, 76, 69, 70, 45, 49, 128, 67, 76, + 69, 70, 128, 67, 76, 69, 198, 67, 76, 69, 65, 86, 69, 82, 128, 67, 76, + 69, 65, 210, 67, 76, 65, 83, 83, 73, 67, 65, 204, 67, 76, 65, 80, 80, 73, + 78, 199, 67, 76, 65, 80, 80, 69, 210, 67, 76, 65, 78, 128, 67, 76, 65, + 206, 67, 76, 65, 77, 83, 72, 69, 76, 204, 67, 76, 65, 73, 77, 128, 67, + 76, 128, 67, 73, 88, 128, 67, 73, 86, 73, 76, 73, 65, 78, 128, 67, 73, + 84, 89, 83, 67, 65, 80, 69, 128, 67, 73, 84, 89, 83, 67, 65, 80, 197, 67, + 73, 84, 201, 67, 73, 84, 65, 84, 73, 79, 206, 67, 73, 84, 128, 67, 73, + 82, 67, 85, 211, 67, 73, 82, 67, 85, 77, 70, 76, 69, 88, 128, 67, 73, 82, + 67, 85, 77, 70, 76, 69, 216, 67, 73, 82, 67, 85, 76, 65, 84, 73, 79, 206, + 67, 73, 82, 67, 76, 73, 78, 71, 128, 67, 73, 82, 67, 76, 73, 78, 199, 67, + 73, 82, 67, 76, 69, 83, 128, 67, 73, 82, 67, 76, 69, 211, 67, 73, 82, 67, + 76, 69, 68, 128, 67, 73, 80, 128, 67, 73, 78, 78, 65, 66, 65, 82, 128, + 67, 73, 78, 69, 77, 65, 128, 67, 73, 206, 67, 73, 77, 128, 67, 73, 205, + 67, 73, 73, 128, 67, 73, 69, 88, 128, 67, 73, 69, 85, 67, 45, 83, 83, 65, + 78, 71, 80, 73, 69, 85, 80, 128, 67, 73, 69, 85, 67, 45, 80, 73, 69, 85, + 80, 128, 67, 73, 69, 85, 67, 45, 73, 69, 85, 78, 71, 128, 67, 73, 69, 85, + 195, 67, 73, 69, 84, 128, 67, 73, 69, 80, 128, 67, 73, 69, 128, 67, 72, + 89, 88, 128, 67, 72, 89, 84, 128, 67, 72, 89, 82, 88, 128, 67, 72, 89, + 82, 128, 67, 72, 89, 80, 128, 67, 72, 87, 86, 128, 67, 72, 85, 88, 128, + 67, 72, 85, 82, 88, 128, 67, 72, 85, 82, 67, 72, 128, 67, 72, 85, 82, + 128, 67, 72, 85, 80, 128, 67, 72, 85, 79, 88, 128, 67, 72, 85, 79, 84, + 128, 67, 72, 85, 79, 80, 128, 67, 72, 85, 79, 128, 67, 72, 85, 76, 65, + 128, 67, 72, 85, 128, 67, 72, 82, 89, 83, 65, 78, 84, 72, 69, 77, 85, 77, + 128, 67, 72, 82, 79, 78, 79, 85, 128, 67, 72, 82, 79, 78, 79, 78, 128, + 67, 72, 82, 79, 77, 193, 67, 72, 82, 79, 193, 67, 72, 82, 73, 86, 73, + 128, 67, 72, 82, 73, 83, 84, 77, 65, 83, 128, 67, 72, 82, 73, 83, 84, 77, + 65, 211, 67, 72, 79, 89, 128, 67, 72, 79, 88, 128, 67, 72, 79, 84, 128, + 67, 72, 79, 82, 69, 86, 77, 193, 67, 72, 79, 82, 65, 83, 77, 73, 65, 206, + 67, 72, 79, 80, 83, 84, 73, 67, 75, 83, 128, 67, 72, 79, 80, 128, 67, 72, + 79, 75, 69, 128, 67, 72, 79, 69, 128, 67, 72, 79, 67, 79, 76, 65, 84, + 197, 67, 72, 79, 65, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, + 71, 83, 73, 79, 83, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, + 71, 67, 73, 69, 85, 67, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 73, 79, + 83, 128, 67, 72, 73, 84, 85, 69, 85, 77, 67, 73, 69, 85, 67, 128, 67, 72, + 73, 84, 85, 69, 85, 77, 67, 72, 73, 69, 85, 67, 72, 128, 67, 72, 73, 82, + 79, 78, 128, 67, 72, 73, 82, 69, 84, 128, 67, 72, 73, 80, 77, 85, 78, 75, + 128, 67, 72, 73, 78, 79, 79, 203, 67, 72, 73, 78, 71, 128, 67, 72, 73, + 78, 69, 83, 197, 67, 72, 73, 78, 128, 67, 72, 73, 77, 69, 128, 67, 72, + 73, 77, 128, 67, 72, 73, 76, 76, 213, 67, 72, 73, 76, 68, 82, 69, 206, + 67, 72, 73, 76, 68, 128, 67, 72, 73, 76, 128, 67, 72, 73, 75, 201, 67, + 72, 73, 69, 85, 67, 72, 45, 75, 72, 73, 69, 85, 75, 72, 128, 67, 72, 73, + 69, 85, 67, 72, 45, 72, 73, 69, 85, 72, 128, 67, 72, 73, 69, 85, 67, 200, + 67, 72, 73, 67, 75, 69, 78, 128, 67, 72, 73, 67, 75, 128, 67, 72, 73, + 128, 67, 72, 201, 67, 72, 72, 73, 77, 128, 67, 72, 72, 65, 128, 67, 72, + 69, 88, 128, 67, 72, 69, 86, 82, 79, 78, 128, 67, 72, 69, 86, 82, 79, + 206, 67, 72, 69, 84, 128, 67, 72, 69, 83, 84, 78, 85, 84, 128, 67, 72, + 69, 83, 84, 128, 67, 72, 69, 83, 211, 67, 72, 69, 82, 89, 128, 67, 72, + 69, 82, 82, 217, 67, 72, 69, 82, 82, 73, 69, 83, 128, 67, 72, 69, 81, 85, + 69, 82, 69, 196, 67, 72, 69, 80, 128, 67, 72, 69, 76, 89, 85, 83, 84, 75, + 65, 128, 67, 72, 69, 76, 78, 85, 128, 67, 72, 69, 73, 78, 65, 80, 128, + 67, 72, 69, 73, 75, 72, 69, 73, 128, 67, 72, 69, 73, 75, 72, 65, 78, 128, + 67, 72, 69, 69, 83, 197, 67, 72, 69, 69, 82, 73, 78, 199, 67, 72, 69, 69, + 77, 128, 67, 72, 69, 69, 75, 211, 67, 72, 69, 69, 75, 128, 67, 72, 69, + 69, 128, 67, 72, 69, 67, 75, 69, 210, 67, 72, 69, 67, 75, 128, 67, 72, + 69, 67, 203, 67, 72, 197, 67, 72, 65, 88, 128, 67, 72, 65, 86, 73, 89, + 65, 78, 73, 128, 67, 72, 65, 84, 84, 65, 87, 65, 128, 67, 72, 65, 84, + 128, 67, 72, 65, 83, 72, 75, 65, 128, 67, 72, 65, 83, 72, 75, 193, 67, + 72, 65, 82, 84, 128, 67, 72, 65, 82, 212, 67, 72, 65, 82, 73, 79, 84, + 128, 67, 72, 65, 82, 73, 79, 212, 67, 72, 65, 82, 65, 67, 84, 69, 82, 83, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 66, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 65, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 57, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 70, 56, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 70, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 70, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 70, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 70, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 51, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 50, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 49, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 48, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 69, 70, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 69, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 69, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 69, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 69, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 65, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 57, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 56, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 55, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 69, 54, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 69, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 69, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 69, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 69, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 49, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 48, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 70, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 69, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 68, 68, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 68, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 68, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 68, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 68, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 56, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 55, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 54, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 53, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 68, 52, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 68, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 68, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 68, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 68, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 70, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 69, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 68, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 67, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 67, 66, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 67, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 67, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 67, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 67, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 54, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 53, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 52, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 51, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 67, 50, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 67, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 67, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 66, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 66, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 68, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 67, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 66, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 65, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 66, 57, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 66, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 66, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 66, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 66, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 52, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 51, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 50, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 49, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 66, 48, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 65, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 65, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 65, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 65, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 66, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 65, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 57, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 56, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 65, 55, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 65, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 65, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 65, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 65, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 50, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 49, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 48, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 70, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 57, 69, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 57, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 57, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 57, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 57, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 57, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 56, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 55, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 54, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 57, 53, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 57, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 57, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 57, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 57, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 48, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 70, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 69, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 68, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 56, 67, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 56, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 56, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 56, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 56, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 55, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 54, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 53, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 52, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 56, 51, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 56, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 56, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 56, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 55, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 69, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 68, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 67, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 66, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 55, 65, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 55, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 55, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 55, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 55, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 53, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 52, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 51, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 50, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 55, 49, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 55, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 54, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 54, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 54, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 67, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 66, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 65, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 57, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 54, 56, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 54, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 54, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 54, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 54, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 51, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 50, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 49, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 48, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 53, 70, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 53, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 53, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 53, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 53, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 65, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 57, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 56, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 55, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 53, 54, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 53, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 53, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 53, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 53, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 49, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 48, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 70, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 69, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 52, 68, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 52, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 52, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 52, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 52, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 56, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 55, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 54, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 53, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 52, 52, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 52, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 52, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 52, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 52, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 70, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 69, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 68, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 67, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 51, 66, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 51, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 51, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 51, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 51, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 54, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 53, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 52, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 51, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 51, 50, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 51, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 51, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 50, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 50, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 68, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 67, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 66, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 65, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 50, 57, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 50, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 50, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 50, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 50, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 52, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 51, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 50, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 49, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 50, 48, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 49, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 49, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 49, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 49, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 66, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 65, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 57, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 56, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 49, 55, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 49, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 49, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 49, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 49, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 50, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 49, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 48, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 70, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 48, 69, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 48, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 48, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 48, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 48, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 57, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 56, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 55, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 54, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 48, 53, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 48, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 48, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 48, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 48, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 48, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 70, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 69, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 68, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 70, 67, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 70, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 70, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 70, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 70, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 55, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 54, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 53, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 52, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 70, 51, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 70, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 70, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 70, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 69, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 69, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 68, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 67, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 66, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 69, 65, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 69, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 69, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 69, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 69, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 53, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 52, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 51, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 50, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 69, 49, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 69, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 68, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 68, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 68, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 67, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 66, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 65, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 57, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 68, 56, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 68, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 68, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 68, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 68, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 51, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 50, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 49, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 48, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 67, 70, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 67, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 67, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 67, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 67, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 65, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 57, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 56, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 55, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 67, 54, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 67, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 67, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 67, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 67, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 49, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 48, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 70, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 69, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 66, 68, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 66, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 66, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 66, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 66, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 56, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 55, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 54, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 53, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 66, 52, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 66, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 66, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 66, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 66, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 70, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 69, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 68, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 67, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 65, 66, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 65, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 65, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 65, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 65, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 54, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 53, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 52, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 51, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 65, 50, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 65, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 65, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 57, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 57, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 68, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 67, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 66, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 65, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 57, 57, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 57, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 57, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 57, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 57, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 52, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 51, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 50, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 49, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 57, 48, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 56, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 56, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 56, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 56, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 66, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 65, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 57, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 56, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 56, 55, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 56, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 56, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 56, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 56, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 50, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 49, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 48, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 70, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 55, 69, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 55, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 55, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 55, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 55, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 57, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 56, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 55, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 54, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 55, 53, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 55, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 55, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 55, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 55, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 48, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 68, 53, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 68, 52, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 68, 51, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 68, 50, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 68, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 68, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 67, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 67, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 68, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 67, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 66, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 65, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 67, 57, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 67, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 67, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 67, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 67, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 52, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 51, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 50, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 49, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 67, 48, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 66, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 66, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 66, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 66, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 66, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 65, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 57, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 56, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 66, 55, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 66, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 66, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 66, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 66, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 50, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 49, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 48, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 70, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 65, 69, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 65, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 65, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 65, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 65, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 57, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 56, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 55, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 54, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 65, 53, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 65, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 65, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 65, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 65, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 48, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 70, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 69, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 68, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 57, 67, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 57, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 57, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 57, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 57, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 55, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 54, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 53, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 52, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 57, 51, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 57, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 57, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 57, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 56, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 69, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 68, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 67, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 66, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 56, 65, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 56, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 56, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 56, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 56, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 53, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 52, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 51, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 50, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 56, 49, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 56, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 55, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 55, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 55, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 67, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 66, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 65, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 57, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 55, 56, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 55, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 55, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 55, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 55, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 51, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 50, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 49, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 48, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 54, 70, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 54, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 54, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 54, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 54, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 65, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 57, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 56, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 55, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 54, 54, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 54, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 54, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 54, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 54, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 49, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 48, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 70, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 69, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 53, 68, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 53, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 53, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 53, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 53, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 56, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 55, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 54, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 53, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 53, 52, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 53, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 53, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 53, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 53, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 70, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 69, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 68, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 67, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 52, 66, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 52, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 52, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 52, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 52, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 54, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 53, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 52, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 51, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 52, 50, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 52, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 52, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 51, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 51, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 68, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 67, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 66, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 65, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 51, 57, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 51, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 51, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 51, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 51, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 52, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 51, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 50, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 49, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 51, 48, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 50, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 50, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 50, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 50, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 66, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 65, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 57, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 56, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 50, 55, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 50, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 50, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 50, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 50, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 50, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 49, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 48, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 70, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 49, 69, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 49, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 49, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 49, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 49, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 57, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 56, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 55, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 54, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 49, 53, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 49, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 49, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 49, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 49, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 48, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 70, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 69, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 68, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 48, 67, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 48, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 48, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 48, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 48, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 55, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 54, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 53, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 52, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 48, 51, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 48, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 48, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 48, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 70, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 69, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 68, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 67, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 66, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 70, 65, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 70, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 70, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 70, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 70, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 53, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 52, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 51, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 50, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 70, 49, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 70, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 69, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 69, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 69, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 67, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 66, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 65, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 57, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 69, 56, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 69, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 69, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 69, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 69, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 51, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 50, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 49, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 48, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 68, 70, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 68, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 68, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 68, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 68, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 65, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 57, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 56, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 55, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 68, 54, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 68, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 68, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 68, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 68, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 49, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 48, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 70, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 69, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 67, 68, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 67, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 67, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 67, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 67, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 56, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 55, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 54, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 53, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 67, 52, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 67, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 67, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 67, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 67, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 70, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 69, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 68, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 67, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 66, 66, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 66, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 66, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 66, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 66, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 54, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 53, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 52, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 51, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 66, 50, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 66, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 66, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 65, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 65, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 68, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 67, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 66, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 65, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 65, 57, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 65, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 65, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 65, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 65, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 52, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 51, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 50, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 49, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 65, 48, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 57, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 57, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 57, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 57, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 66, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 65, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 57, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 56, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 57, 55, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 57, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 57, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 57, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 57, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 50, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 49, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 48, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 70, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 56, 69, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 56, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 56, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 56, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 56, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 57, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 56, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 55, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 54, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 56, 53, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 56, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 56, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 56, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 56, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 48, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 70, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 69, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 68, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 55, 67, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 55, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 55, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 55, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 55, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 55, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 54, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 53, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 52, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 55, 51, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 55, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 55, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 55, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 54, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 69, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 68, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 67, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 66, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 54, 65, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 54, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 54, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 54, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 54, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 53, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 52, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 51, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 50, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 54, 49, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 54, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 53, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 53, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 53, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 67, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 66, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 65, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 57, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 53, 56, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 53, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 53, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 53, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 53, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 51, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 50, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 49, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 48, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 52, 70, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 52, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 52, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 52, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 52, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 65, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 57, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 56, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 55, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 52, 54, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 52, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 52, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 52, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 52, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 49, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 48, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 70, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 69, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 51, 68, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 51, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 51, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 51, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 51, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 56, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 55, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 54, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 53, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 51, 52, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 51, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 51, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 51, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 51, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 70, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 69, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 68, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 67, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 50, 66, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 50, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 50, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 50, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 50, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 54, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 53, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 52, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 51, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 50, 50, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 50, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 50, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 49, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 49, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 68, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 67, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 66, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 65, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 49, 57, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 49, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 49, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 49, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 49, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 52, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 51, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 50, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 49, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 49, 48, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 48, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 48, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 48, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 48, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 66, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 65, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 57, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 56, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 48, 55, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 48, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 48, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 48, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 48, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 50, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 49, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 48, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 128, 67, 72, 65, 82, 65, 67, 84, 69, 210, 67, 72, + 65, 82, 128, 67, 72, 65, 80, 84, 69, 82, 128, 67, 72, 65, 80, 128, 67, + 72, 65, 78, 71, 128, 67, 72, 65, 78, 128, 67, 72, 65, 77, 75, 79, 128, + 67, 72, 65, 77, 73, 76, 79, 78, 128, 67, 72, 65, 77, 73, 76, 73, 128, 67, + 72, 65, 205, 67, 72, 65, 75, 77, 193, 67, 72, 65, 73, 78, 83, 128, 67, + 72, 65, 68, 65, 128, 67, 72, 65, 196, 67, 72, 65, 65, 128, 67, 71, 74, + 128, 67, 69, 88, 128, 67, 69, 86, 73, 84, 85, 128, 67, 69, 82, 69, 83, + 128, 67, 69, 82, 69, 77, 79, 78, 89, 128, 67, 69, 82, 69, 75, 128, 67, + 69, 82, 45, 87, 65, 128, 67, 69, 80, 128, 67, 69, 79, 78, 71, 67, 72, 73, + 69, 85, 77, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 67, 69, 79, 78, 71, + 67, 72, 73, 69, 85, 77, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, 128, 67, + 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, 83, 73, 79, 83, 128, 67, 69, 79, + 78, 71, 67, 72, 73, 69, 85, 77, 67, 73, 69, 85, 67, 128, 67, 69, 79, 78, + 71, 67, 72, 73, 69, 85, 77, 67, 72, 73, 69, 85, 67, 72, 128, 67, 69, 78, + 84, 85, 82, 73, 65, 204, 67, 69, 78, 84, 82, 69, 76, 73, 78, 197, 67, 69, + 78, 84, 82, 69, 68, 128, 67, 69, 78, 84, 82, 69, 196, 67, 69, 78, 84, 82, + 69, 128, 67, 69, 78, 84, 82, 197, 67, 69, 78, 84, 82, 65, 76, 73, 90, 65, + 84, 73, 79, 206, 67, 69, 78, 128, 67, 69, 76, 84, 73, 195, 67, 69, 76, + 83, 73, 85, 83, 128, 67, 69, 76, 69, 66, 82, 65, 84, 73, 79, 78, 128, 67, + 69, 73, 82, 84, 128, 67, 69, 73, 76, 73, 78, 71, 128, 67, 69, 73, 76, 73, + 78, 199, 67, 69, 69, 86, 128, 67, 69, 69, 66, 128, 67, 69, 69, 128, 67, + 69, 68, 73, 76, 76, 65, 128, 67, 69, 68, 73, 76, 76, 193, 67, 69, 68, + 201, 67, 69, 67, 69, 75, 128, 67, 69, 67, 65, 75, 128, 67, 69, 67, 65, + 203, 67, 69, 65, 76, 67, 128, 67, 67, 85, 128, 67, 67, 79, 128, 67, 67, + 73, 128, 67, 67, 72, 85, 128, 67, 67, 72, 79, 128, 67, 67, 72, 73, 128, + 67, 67, 72, 72, 85, 128, 67, 67, 72, 72, 79, 128, 67, 67, 72, 72, 73, + 128, 67, 67, 72, 72, 69, 69, 128, 67, 67, 72, 72, 69, 128, 67, 67, 72, + 72, 65, 65, 128, 67, 67, 72, 72, 65, 128, 67, 67, 72, 69, 69, 128, 67, + 67, 72, 69, 128, 67, 67, 72, 65, 65, 128, 67, 67, 72, 65, 128, 67, 67, + 72, 128, 67, 67, 69, 69, 128, 67, 67, 65, 65, 128, 67, 65, 89, 78, 128, + 67, 65, 89, 65, 78, 78, 65, 128, 67, 65, 88, 128, 67, 65, 86, 69, 128, + 67, 65, 85, 84, 73, 79, 206, 67, 65, 85, 76, 68, 82, 79, 78, 128, 67, 65, + 85, 68, 65, 84, 197, 67, 65, 85, 68, 65, 128, 67, 65, 85, 67, 65, 83, 73, + 65, 206, 67, 65, 85, 128, 67, 65, 84, 65, 87, 65, 128, 67, 65, 84, 128, + 67, 65, 212, 67, 65, 83, 84, 76, 69, 128, 67, 65, 83, 75, 69, 212, 67, + 65, 82, 89, 83, 84, 73, 65, 206, 67, 65, 82, 84, 87, 72, 69, 69, 76, 128, + 67, 65, 82, 84, 82, 73, 68, 71, 69, 128, 67, 65, 82, 84, 128, 67, 65, 82, + 211, 67, 65, 82, 82, 79, 84, 128, 67, 65, 82, 82, 73, 65, 71, 197, 67, + 65, 82, 80, 69, 78, 84, 82, 217, 67, 65, 82, 208, 67, 65, 82, 79, 85, 83, + 69, 204, 67, 65, 82, 79, 78, 128, 67, 65, 82, 79, 206, 67, 65, 82, 73, + 203, 67, 65, 82, 73, 65, 206, 67, 65, 82, 69, 84, 128, 67, 65, 82, 69, + 212, 67, 65, 82, 197, 67, 65, 82, 68, 83, 128, 67, 65, 82, 196, 67, 65, + 82, 128, 67, 65, 210, 67, 65, 80, 85, 212, 67, 65, 80, 84, 73, 86, 69, + 128, 67, 65, 80, 82, 73, 67, 79, 82, 78, 128, 67, 65, 80, 80, 69, 196, + 67, 65, 80, 79, 128, 67, 65, 80, 73, 84, 85, 76, 85, 77, 128, 67, 65, 80, + 73, 84, 65, 76, 128, 67, 65, 78, 84, 73, 76, 76, 65, 84, 73, 79, 206, 67, + 65, 78, 79, 69, 128, 67, 65, 78, 78, 79, 78, 128, 67, 65, 78, 78, 69, + 196, 67, 65, 78, 199, 67, 65, 78, 69, 128, 67, 65, 78, 68, 89, 128, 67, + 65, 78, 68, 82, 65, 66, 73, 78, 68, 85, 128, 67, 65, 78, 68, 82, 65, 66, + 73, 78, 68, 213, 67, 65, 78, 68, 82, 65, 128, 67, 65, 78, 68, 82, 193, + 67, 65, 78, 68, 76, 69, 128, 67, 65, 78, 67, 69, 82, 128, 67, 65, 78, 67, + 69, 76, 76, 65, 84, 73, 79, 206, 67, 65, 78, 67, 69, 76, 128, 67, 65, 78, + 67, 69, 204, 67, 65, 78, 128, 67, 65, 77, 80, 73, 78, 71, 128, 67, 65, + 77, 78, 85, 195, 67, 65, 77, 69, 82, 65, 128, 67, 65, 77, 69, 82, 193, + 67, 65, 77, 69, 76, 128, 67, 65, 76, 89, 65, 128, 67, 65, 76, 89, 193, + 67, 65, 76, 88, 128, 67, 65, 76, 76, 128, 67, 65, 76, 204, 67, 65, 76, + 69, 78, 68, 65, 82, 128, 67, 65, 76, 69, 78, 68, 65, 210, 67, 65, 76, 67, + 85, 76, 65, 84, 79, 82, 128, 67, 65, 76, 67, 128, 67, 65, 75, 82, 65, + 128, 67, 65, 75, 197, 67, 65, 73, 128, 67, 65, 72, 128, 67, 65, 69, 83, + 85, 82, 65, 128, 67, 65, 68, 85, 67, 69, 85, 83, 128, 67, 65, 68, 193, + 67, 65, 67, 84, 85, 83, 128, 67, 65, 66, 76, 69, 87, 65, 89, 128, 67, 65, + 66, 73, 78, 69, 84, 128, 67, 65, 66, 66, 65, 71, 69, 45, 84, 82, 69, 69, + 128, 67, 65, 65, 78, 71, 128, 67, 65, 65, 73, 128, 67, 193, 67, 48, 50, + 52, 128, 67, 48, 50, 51, 128, 67, 48, 50, 50, 128, 67, 48, 50, 49, 128, + 67, 48, 50, 48, 128, 67, 48, 49, 57, 128, 67, 48, 49, 56, 128, 67, 48, + 49, 55, 128, 67, 48, 49, 54, 128, 67, 48, 49, 53, 128, 67, 48, 49, 52, + 128, 67, 48, 49, 51, 128, 67, 48, 49, 50, 128, 67, 48, 49, 49, 128, 67, + 48, 49, 48, 65, 128, 67, 48, 49, 48, 128, 67, 48, 48, 57, 128, 67, 48, + 48, 56, 128, 67, 48, 48, 55, 128, 67, 48, 48, 54, 128, 67, 48, 48, 53, + 128, 67, 48, 48, 52, 128, 67, 48, 48, 51, 128, 67, 48, 48, 50, 67, 128, + 67, 48, 48, 50, 66, 128, 67, 48, 48, 50, 65, 128, 67, 48, 48, 50, 128, + 67, 48, 48, 49, 128, 67, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 67, + 45, 51, 57, 128, 67, 45, 49, 56, 128, 66, 90, 85, 78, 199, 66, 90, 72, + 201, 66, 89, 84, 197, 66, 89, 69, 76, 79, 82, 85, 83, 83, 73, 65, 78, 45, + 85, 75, 82, 65, 73, 78, 73, 65, 206, 66, 88, 71, 128, 66, 87, 73, 128, + 66, 87, 69, 69, 128, 66, 87, 69, 128, 66, 87, 65, 128, 66, 85, 85, 77, + 73, 83, 72, 128, 66, 85, 84, 84, 79, 78, 128, 66, 85, 84, 84, 79, 206, + 66, 85, 84, 84, 69, 82, 70, 76, 89, 128, 66, 85, 84, 84, 69, 82, 128, 66, + 85, 212, 66, 85, 83, 84, 211, 66, 85, 83, 212, 66, 85, 83, 83, 89, 69, + 82, 85, 128, 66, 85, 83, 73, 78, 69, 83, 211, 66, 85, 211, 66, 85, 82, + 213, 66, 85, 82, 82, 73, 84, 79, 128, 66, 85, 82, 50, 128, 66, 85, 210, + 66, 85, 79, 89, 128, 66, 85, 79, 88, 128, 66, 85, 79, 80, 128, 66, 85, + 78, 78, 217, 66, 85, 78, 71, 128, 66, 85, 77, 80, 217, 66, 85, 76, 85, + 71, 128, 66, 85, 76, 85, 199, 66, 85, 76, 76, 83, 69, 89, 69, 128, 66, + 85, 76, 76, 211, 66, 85, 76, 76, 72, 79, 82, 78, 128, 66, 85, 76, 76, 72, + 79, 82, 206, 66, 85, 76, 76, 69, 84, 128, 66, 85, 76, 76, 69, 212, 66, + 85, 76, 76, 128, 66, 85, 76, 66, 128, 66, 85, 75, 89, 128, 66, 85, 73, + 76, 68, 73, 78, 71, 83, 128, 66, 85, 73, 76, 68, 73, 78, 71, 128, 66, 85, + 73, 76, 68, 73, 78, 199, 66, 85, 72, 73, 196, 66, 85, 71, 73, 78, 69, 83, + 197, 66, 85, 71, 128, 66, 85, 70, 70, 65, 76, 79, 128, 66, 85, 68, 128, + 66, 85, 67, 75, 76, 69, 128, 66, 85, 67, 75, 69, 84, 128, 66, 85, 66, 66, + 76, 69, 83, 128, 66, 85, 66, 66, 76, 69, 128, 66, 85, 66, 66, 76, 197, + 66, 83, 84, 65, 82, 128, 66, 83, 75, 85, 210, 66, 83, 75, 65, 173, 66, + 83, 68, 85, 211, 66, 82, 85, 83, 200, 66, 82, 79, 87, 206, 66, 82, 79, + 79, 77, 128, 66, 82, 79, 78, 90, 69, 128, 66, 82, 79, 75, 69, 206, 66, + 82, 79, 67, 67, 79, 76, 73, 128, 66, 82, 79, 65, 196, 66, 82, 73, 83, 84, + 76, 69, 128, 66, 82, 73, 71, 72, 84, 78, 69, 83, 211, 66, 82, 73, 69, 70, + 83, 128, 66, 82, 73, 69, 70, 67, 65, 83, 69, 128, 66, 82, 73, 68, 71, + 197, 66, 82, 73, 68, 197, 66, 82, 73, 67, 75, 128, 66, 82, 73, 128, 66, + 82, 69, 86, 73, 83, 128, 66, 82, 69, 86, 69, 45, 77, 65, 67, 82, 79, 78, + 128, 66, 82, 69, 86, 197, 66, 82, 69, 65, 84, 72, 217, 66, 82, 69, 65, + 84, 200, 66, 82, 69, 65, 83, 84, 45, 70, 69, 69, 68, 73, 78, 71, 128, 66, + 82, 69, 65, 75, 84, 72, 82, 79, 85, 71, 72, 128, 66, 82, 68, 193, 66, 82, + 65, 78, 67, 72, 73, 78, 199, 66, 82, 65, 78, 67, 72, 69, 83, 128, 66, 82, + 65, 78, 67, 72, 128, 66, 82, 65, 78, 67, 200, 66, 82, 65, 75, 67, 69, 84, + 128, 66, 82, 65, 73, 78, 128, 66, 82, 65, 67, 75, 69, 84, 211, 66, 82, + 65, 67, 75, 69, 84, 69, 196, 66, 82, 65, 67, 75, 69, 84, 128, 66, 82, 65, + 67, 75, 69, 212, 66, 82, 65, 67, 69, 128, 66, 81, 128, 66, 80, 72, 128, + 66, 79, 89, 211, 66, 79, 89, 128, 66, 79, 88, 73, 78, 199, 66, 79, 87, + 84, 73, 69, 128, 66, 79, 87, 84, 73, 197, 66, 79, 87, 76, 73, 78, 71, + 128, 66, 79, 87, 76, 128, 66, 79, 87, 204, 66, 79, 87, 73, 78, 199, 66, + 79, 215, 66, 79, 85, 81, 85, 69, 84, 128, 66, 79, 85, 81, 85, 69, 212, + 66, 79, 85, 78, 68, 65, 82, 217, 66, 79, 84, 84, 79, 77, 45, 83, 72, 65, + 68, 69, 196, 66, 79, 84, 84, 79, 77, 45, 76, 73, 71, 72, 84, 69, 196, 66, + 79, 84, 84, 79, 77, 128, 66, 79, 84, 84, 79, 205, 66, 79, 84, 84, 76, 69, + 128, 66, 79, 84, 84, 76, 197, 66, 79, 84, 200, 66, 79, 82, 90, 89, 128, + 66, 79, 82, 90, 65, 89, 65, 128, 66, 79, 82, 85, 84, 79, 128, 66, 79, 82, + 65, 88, 45, 51, 128, 66, 79, 82, 65, 88, 45, 50, 128, 66, 79, 82, 65, 88, + 128, 66, 79, 80, 79, 77, 79, 70, 207, 66, 79, 79, 84, 83, 128, 66, 79, + 79, 84, 128, 66, 79, 79, 77, 69, 82, 65, 78, 71, 128, 66, 79, 79, 75, 83, + 128, 66, 79, 79, 75, 77, 65, 82, 75, 128, 66, 79, 79, 75, 77, 65, 82, + 203, 66, 79, 78, 69, 128, 66, 79, 77, 66, 128, 66, 79, 77, 128, 66, 79, + 76, 84, 128, 66, 79, 76, 212, 66, 79, 72, 65, 73, 82, 73, 195, 66, 79, + 68, 89, 128, 66, 79, 68, 217, 66, 79, 65, 82, 128, 66, 79, 65, 128, 66, + 76, 85, 69, 66, 69, 82, 82, 73, 69, 83, 128, 66, 76, 85, 69, 128, 66, 76, + 85, 197, 66, 76, 79, 87, 73, 78, 199, 66, 76, 79, 87, 70, 73, 83, 72, + 128, 66, 76, 79, 215, 66, 76, 79, 83, 83, 79, 77, 128, 66, 76, 79, 79, + 68, 128, 66, 76, 79, 78, 196, 66, 76, 79, 67, 75, 45, 55, 128, 66, 76, + 79, 67, 75, 45, 54, 128, 66, 76, 79, 67, 75, 45, 53, 128, 66, 76, 79, 67, + 75, 45, 52, 128, 66, 76, 79, 67, 75, 45, 51, 128, 66, 76, 79, 67, 75, 45, + 50, 128, 66, 76, 79, 67, 75, 45, 49, 51, 53, 56, 128, 66, 76, 79, 67, 75, + 128, 66, 76, 73, 78, 203, 66, 76, 65, 78, 75, 128, 66, 76, 65, 78, 203, + 66, 76, 65, 68, 197, 66, 76, 65, 67, 75, 76, 69, 84, 84, 69, 210, 66, 76, + 65, 67, 75, 70, 79, 79, 212, 66, 76, 65, 67, 75, 45, 76, 69, 84, 84, 69, + 210, 66, 76, 65, 67, 75, 45, 70, 69, 65, 84, 72, 69, 82, 69, 196, 66, 76, + 65, 67, 75, 128, 66, 75, 65, 173, 66, 73, 84, 84, 69, 82, 128, 66, 73, + 84, 73, 78, 199, 66, 73, 84, 197, 66, 73, 84, 67, 79, 73, 206, 66, 73, + 83, 79, 78, 128, 66, 73, 83, 77, 85, 84, 200, 66, 73, 83, 77, 73, 76, 76, + 65, 200, 66, 73, 83, 72, 79, 208, 66, 73, 83, 69, 67, 84, 73, 78, 199, + 66, 73, 83, 65, 72, 128, 66, 73, 82, 85, 128, 66, 73, 82, 84, 72, 68, 65, + 217, 66, 73, 82, 71, 65, 128, 66, 73, 82, 71, 193, 66, 73, 82, 68, 128, + 66, 73, 79, 72, 65, 90, 65, 82, 196, 66, 73, 78, 79, 86, 73, 76, 69, 128, + 66, 73, 78, 79, 67, 85, 76, 65, 210, 66, 73, 78, 68, 73, 78, 199, 66, 73, + 78, 68, 73, 128, 66, 73, 78, 65, 82, 217, 66, 73, 76, 76, 73, 79, 78, 83, + 128, 66, 73, 76, 76, 73, 65, 82, 68, 83, 128, 66, 73, 76, 76, 69, 196, + 66, 73, 76, 65, 66, 73, 65, 204, 66, 73, 75, 73, 78, 73, 128, 66, 73, 71, + 128, 66, 73, 199, 66, 73, 69, 84, 128, 66, 73, 68, 69, 78, 84, 65, 204, + 66, 73, 68, 65, 75, 85, 79, 206, 66, 73, 67, 89, 67, 76, 73, 83, 84, 128, + 66, 73, 67, 89, 67, 76, 69, 83, 128, 66, 73, 67, 89, 67, 76, 69, 128, 66, + 73, 67, 69, 80, 83, 128, 66, 73, 66, 76, 69, 45, 67, 82, 69, 197, 66, 73, + 66, 128, 66, 201, 66, 72, 85, 128, 66, 72, 79, 79, 128, 66, 72, 79, 128, + 66, 72, 73, 128, 66, 72, 69, 84, 72, 128, 66, 72, 69, 69, 128, 66, 72, + 69, 128, 66, 72, 65, 84, 84, 73, 80, 82, 79, 76, 213, 66, 72, 65, 77, + 128, 66, 72, 65, 76, 69, 128, 66, 72, 65, 76, 197, 66, 72, 65, 73, 75, + 83, 85, 75, 201, 66, 72, 65, 65, 128, 66, 72, 65, 128, 66, 69, 89, 89, + 65, 76, 128, 66, 69, 88, 128, 66, 69, 86, 69, 82, 65, 71, 69, 128, 66, + 69, 86, 69, 82, 65, 71, 197, 66, 69, 84, 87, 69, 69, 78, 128, 66, 69, 84, + 87, 69, 69, 206, 66, 69, 84, 72, 128, 66, 69, 84, 65, 128, 66, 69, 84, + 193, 66, 69, 212, 66, 69, 83, 73, 68, 197, 66, 69, 82, 75, 65, 78, 65, + 206, 66, 69, 82, 66, 69, 210, 66, 69, 80, 128, 66, 69, 79, 82, 195, 66, + 69, 78, 90, 69, 78, 197, 66, 69, 78, 84, 207, 66, 69, 78, 84, 128, 66, + 69, 78, 212, 66, 69, 78, 71, 65, 76, 201, 66, 69, 78, 68, 69, 128, 66, + 69, 78, 68, 128, 66, 69, 78, 196, 66, 69, 206, 66, 69, 76, 84, 128, 66, + 69, 76, 212, 66, 69, 76, 79, 215, 66, 69, 76, 76, 72, 79, 208, 66, 69, + 76, 76, 128, 66, 69, 76, 204, 66, 69, 76, 71, 84, 72, 79, 210, 66, 69, + 73, 84, 72, 128, 66, 69, 72, 73, 78, 196, 66, 69, 72, 69, 72, 128, 66, + 69, 72, 69, 200, 66, 69, 72, 128, 66, 69, 200, 66, 69, 71, 73, 78, 78, + 73, 78, 71, 128, 66, 69, 71, 73, 78, 78, 69, 82, 128, 66, 69, 71, 73, 206, 66, 69, 70, 79, 82, 197, 66, 69, 69, 84, 76, 69, 128, 66, 69, 69, 84, 65, 128, 66, 69, 69, 210, 66, 69, 69, 72, 73, 86, 69, 128, 66, 69, 69, 72, 128, 66, 69, 69, 200, 66, 69, 67, 65, 85, 83, 69, 128, 66, 69, @@ -6729,10083 +6749,10122 @@ static const unsigned char lexicon[] = { 68, 69, 82, 77, 193, 65, 80, 76, 79, 85, 78, 128, 65, 80, 76, 201, 65, 80, 204, 65, 80, 73, 78, 128, 65, 80, 69, 83, 207, 65, 80, 67, 128, 65, 80, 65, 82, 84, 128, 65, 80, 65, 65, 84, 79, 128, 65, 79, 85, 128, 65, - 79, 82, 128, 65, 78, 85, 83, 86, 65, 82, 65, 89, 65, 128, 65, 78, 85, 83, - 86, 65, 82, 65, 128, 65, 78, 85, 83, 86, 65, 82, 193, 65, 78, 85, 68, 65, - 84, 84, 65, 128, 65, 78, 85, 68, 65, 84, 84, 193, 65, 78, 84, 73, 82, 69, - 83, 84, 82, 73, 67, 84, 73, 79, 78, 128, 65, 78, 84, 73, 77, 79, 78, 89, - 45, 50, 128, 65, 78, 84, 73, 77, 79, 78, 89, 128, 65, 78, 84, 73, 77, 79, - 78, 217, 65, 78, 84, 73, 77, 79, 78, 73, 65, 84, 69, 128, 65, 78, 84, 73, - 75, 69, 78, 79, 77, 65, 128, 65, 78, 84, 73, 75, 69, 78, 79, 75, 89, 76, - 73, 83, 77, 65, 128, 65, 78, 84, 73, 70, 79, 78, 73, 65, 128, 65, 78, 84, - 73, 67, 76, 79, 67, 75, 87, 73, 83, 69, 45, 82, 79, 84, 65, 84, 69, 196, - 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, 83, 69, 128, 65, 78, 84, 73, - 67, 76, 79, 67, 75, 87, 73, 83, 197, 65, 78, 84, 69, 78, 78, 65, 128, 65, - 78, 84, 69, 78, 78, 193, 65, 78, 84, 65, 82, 71, 79, 77, 85, 75, 72, 65, - 128, 65, 78, 83, 85, 218, 65, 78, 83, 72, 69, 128, 65, 78, 80, 69, 65, - 128, 65, 78, 207, 65, 78, 78, 85, 73, 84, 217, 65, 78, 78, 79, 84, 65, - 84, 73, 79, 206, 65, 78, 78, 65, 65, 85, 128, 65, 78, 75, 72, 128, 65, - 78, 74, 73, 128, 65, 78, 73, 77, 65, 76, 128, 65, 78, 72, 85, 78, 78, 65, - 128, 65, 78, 72, 85, 77, 65, 65, 128, 65, 78, 72, 85, 77, 128, 65, 78, - 72, 85, 128, 65, 78, 72, 65, 65, 128, 65, 78, 72, 128, 65, 78, 71, 85, - 76, 65, 82, 128, 65, 78, 71, 85, 73, 83, 72, 69, 196, 65, 78, 71, 83, 84, - 82, 79, 205, 65, 78, 71, 82, 217, 65, 78, 71, 76, 73, 67, 65, 78, 193, - 65, 78, 71, 76, 69, 68, 128, 65, 78, 71, 76, 69, 196, 65, 78, 71, 75, 72, - 65, 78, 75, 72, 85, 128, 65, 78, 71, 75, 65, 128, 65, 78, 71, 69, 210, - 65, 78, 71, 69, 76, 128, 65, 78, 71, 69, 68, 128, 65, 78, 68, 65, 80, - 128, 65, 78, 67, 79, 82, 65, 128, 65, 78, 67, 72, 79, 82, 128, 65, 78, - 65, 84, 82, 73, 67, 72, 73, 83, 77, 65, 128, 65, 78, 65, 84, 79, 77, 73, - 67, 65, 204, 65, 78, 65, 80, 128, 65, 78, 45, 78, 73, 83, 70, 128, 65, - 77, 85, 76, 69, 84, 128, 65, 77, 80, 83, 128, 65, 77, 80, 72, 79, 82, 65, - 128, 65, 77, 80, 69, 82, 83, 65, 78, 68, 128, 65, 77, 80, 69, 82, 83, 65, - 78, 196, 65, 77, 79, 85, 78, 212, 65, 77, 69, 82, 73, 67, 65, 83, 128, - 65, 77, 69, 82, 73, 67, 65, 206, 65, 77, 66, 85, 76, 65, 78, 67, 69, 128, - 65, 77, 66, 193, 65, 77, 66, 128, 65, 77, 65, 82, 128, 65, 77, 65, 210, - 65, 77, 65, 76, 71, 65, 77, 65, 84, 73, 79, 206, 65, 77, 65, 76, 71, 65, - 77, 128, 65, 76, 86, 69, 79, 76, 65, 210, 65, 76, 85, 77, 128, 65, 76, - 84, 69, 82, 78, 65, 84, 73, 86, 197, 65, 76, 84, 69, 82, 78, 65, 84, 73, - 79, 206, 65, 76, 84, 69, 82, 78, 65, 84, 73, 78, 71, 128, 65, 76, 84, 69, - 82, 78, 65, 84, 73, 78, 199, 65, 76, 84, 69, 82, 78, 65, 84, 69, 128, 65, - 76, 84, 69, 82, 78, 65, 84, 197, 65, 76, 84, 65, 128, 65, 76, 80, 72, 65, - 128, 65, 76, 80, 72, 193, 65, 76, 80, 65, 80, 82, 65, 78, 65, 128, 65, - 76, 80, 65, 80, 82, 65, 65, 78, 193, 65, 76, 80, 65, 128, 65, 76, 77, 79, - 83, 212, 65, 76, 76, 79, 128, 65, 76, 76, 73, 65, 78, 67, 69, 128, 65, - 76, 76, 201, 65, 76, 76, 65, 200, 65, 76, 76, 65, 65, 72, 128, 65, 76, - 75, 65, 76, 73, 45, 50, 128, 65, 76, 75, 65, 76, 73, 128, 65, 76, 73, 71, - 78, 69, 196, 65, 76, 73, 70, 85, 128, 65, 76, 73, 70, 128, 65, 76, 73, - 198, 65, 76, 73, 69, 78, 128, 65, 76, 73, 69, 206, 65, 76, 71, 73, 218, - 65, 76, 70, 65, 128, 65, 76, 69, 85, 212, 65, 76, 69, 82, 84, 128, 65, - 76, 69, 80, 72, 128, 65, 76, 69, 77, 66, 73, 67, 128, 65, 76, 69, 70, - 128, 65, 76, 66, 65, 78, 73, 65, 206, 65, 76, 65, 89, 78, 65, 65, 128, - 65, 76, 65, 89, 72, 73, 77, 65, 193, 65, 76, 65, 89, 72, 73, 205, 65, 76, - 65, 89, 72, 201, 65, 76, 65, 89, 72, 69, 128, 65, 76, 65, 89, 72, 197, - 65, 76, 65, 89, 72, 65, 193, 65, 76, 65, 82, 205, 65, 76, 65, 80, 72, - 128, 65, 76, 45, 76, 65, 75, 85, 78, 65, 128, 65, 76, 45, 74, 85, 90, - 128, 65, 75, 85, 82, 213, 65, 75, 84, 73, 69, 83, 69, 76, 83, 75, 65, 66, - 128, 65, 75, 83, 65, 128, 65, 75, 72, 77, 73, 77, 73, 195, 65, 75, 66, - 65, 210, 65, 75, 65, 82, 65, 128, 65, 75, 65, 82, 193, 65, 73, 89, 65, - 78, 78, 65, 128, 65, 73, 86, 73, 76, 73, 203, 65, 73, 86, 65, 128, 65, - 73, 84, 79, 206, 65, 73, 82, 80, 76, 65, 78, 69, 128, 65, 73, 82, 80, 76, - 65, 78, 197, 65, 73, 78, 213, 65, 73, 78, 78, 128, 65, 73, 76, 77, 128, - 65, 73, 75, 65, 82, 65, 128, 65, 73, 72, 86, 85, 83, 128, 65, 72, 83, 68, - 65, 128, 65, 72, 83, 65, 128, 65, 72, 79, 205, 65, 72, 65, 78, 199, 65, - 72, 65, 71, 71, 65, 210, 65, 72, 65, 68, 128, 65, 71, 85, 78, 71, 128, - 65, 71, 79, 71, 201, 65, 71, 71, 82, 65, 86, 65, 84, 73, 79, 78, 128, 65, - 71, 71, 82, 65, 86, 65, 84, 69, 196, 65, 71, 65, 73, 78, 83, 212, 65, 71, - 65, 73, 78, 128, 65, 70, 84, 69, 210, 65, 70, 83, 65, 65, 81, 128, 65, - 70, 82, 73, 67, 65, 206, 65, 70, 79, 82, 69, 77, 69, 78, 84, 73, 79, 78, - 69, 68, 128, 65, 70, 71, 72, 65, 78, 201, 65, 70, 70, 82, 73, 67, 65, 84, - 73, 79, 206, 65, 70, 70, 73, 216, 65, 69, 89, 65, 78, 78, 65, 128, 65, - 69, 89, 128, 65, 69, 83, 67, 85, 76, 65, 80, 73, 85, 83, 128, 65, 69, 83, - 67, 128, 65, 69, 83, 128, 65, 69, 82, 73, 65, 204, 65, 69, 82, 128, 65, - 69, 76, 65, 45, 80, 73, 76, 76, 65, 128, 65, 69, 76, 128, 65, 69, 75, - 128, 65, 69, 71, 69, 65, 206, 65, 69, 71, 128, 65, 69, 69, 89, 65, 78, - 78, 65, 128, 65, 69, 69, 128, 65, 69, 68, 65, 45, 80, 73, 76, 76, 65, - 128, 65, 69, 68, 128, 65, 69, 66, 128, 65, 68, 86, 65, 78, 84, 65, 71, - 69, 128, 65, 68, 86, 65, 78, 67, 69, 128, 65, 68, 85, 76, 84, 128, 65, - 68, 77, 73, 83, 83, 73, 79, 206, 65, 68, 77, 69, 84, 79, 83, 128, 65, 68, - 76, 65, 205, 65, 68, 72, 69, 83, 73, 86, 197, 65, 68, 69, 71, 128, 65, - 68, 69, 199, 65, 68, 68, 82, 69, 83, 83, 69, 196, 65, 68, 68, 82, 69, 83, - 211, 65, 68, 68, 65, 75, 128, 65, 68, 65, 203, 65, 67, 85, 84, 69, 45, - 77, 65, 67, 82, 79, 78, 128, 65, 67, 85, 84, 69, 45, 71, 82, 65, 86, 69, - 45, 65, 67, 85, 84, 69, 128, 65, 67, 85, 84, 197, 65, 67, 84, 85, 65, 76, - 76, 217, 65, 67, 84, 73, 86, 65, 84, 197, 65, 67, 82, 79, 80, 72, 79, 78, - 73, 195, 65, 67, 75, 78, 79, 87, 76, 69, 68, 71, 69, 128, 65, 67, 67, 85, - 77, 85, 76, 65, 84, 73, 79, 78, 128, 65, 67, 67, 79, 85, 78, 212, 65, 67, - 67, 79, 82, 68, 73, 79, 78, 128, 65, 67, 67, 79, 77, 77, 79, 68, 65, 84, - 73, 79, 78, 128, 65, 67, 67, 69, 80, 84, 128, 65, 67, 67, 69, 78, 84, 45, - 83, 84, 65, 67, 67, 65, 84, 79, 128, 65, 67, 67, 69, 78, 84, 128, 65, 67, - 67, 69, 78, 212, 65, 67, 65, 68, 69, 77, 217, 65, 66, 89, 83, 77, 65, - 204, 65, 66, 85, 78, 68, 65, 78, 67, 69, 128, 65, 66, 75, 72, 65, 83, 73, - 65, 206, 65, 66, 66, 82, 69, 86, 73, 65, 84, 73, 79, 206, 65, 66, 65, 70, - 73, 76, 73, 128, 65, 66, 65, 67, 85, 83, 128, 65, 66, 178, 65, 66, 49, - 57, 49, 128, 65, 66, 49, 56, 56, 128, 65, 66, 49, 56, 48, 128, 65, 66, - 49, 55, 49, 128, 65, 66, 49, 54, 52, 128, 65, 66, 49, 51, 49, 66, 128, - 65, 66, 49, 51, 49, 65, 128, 65, 66, 49, 50, 51, 128, 65, 66, 49, 50, 50, - 128, 65, 66, 49, 50, 48, 128, 65, 66, 49, 49, 56, 128, 65, 66, 48, 56, - 55, 128, 65, 66, 48, 56, 54, 128, 65, 66, 48, 56, 53, 128, 65, 66, 48, - 56, 50, 128, 65, 66, 48, 56, 49, 128, 65, 66, 48, 56, 48, 128, 65, 66, - 48, 55, 57, 128, 65, 66, 48, 55, 56, 128, 65, 66, 48, 55, 55, 128, 65, - 66, 48, 55, 54, 128, 65, 66, 48, 55, 52, 128, 65, 66, 48, 55, 51, 128, - 65, 66, 48, 55, 48, 128, 65, 66, 48, 54, 57, 128, 65, 66, 48, 54, 55, - 128, 65, 66, 48, 54, 54, 128, 65, 66, 48, 54, 53, 128, 65, 66, 48, 54, - 49, 128, 65, 66, 48, 54, 48, 128, 65, 66, 48, 53, 57, 128, 65, 66, 48, - 53, 56, 128, 65, 66, 48, 53, 55, 128, 65, 66, 48, 53, 54, 128, 65, 66, - 48, 53, 53, 128, 65, 66, 48, 53, 52, 128, 65, 66, 48, 53, 51, 128, 65, - 66, 48, 53, 49, 128, 65, 66, 48, 53, 48, 128, 65, 66, 48, 52, 57, 128, - 65, 66, 48, 52, 56, 128, 65, 66, 48, 52, 55, 128, 65, 66, 48, 52, 54, - 128, 65, 66, 48, 52, 53, 128, 65, 66, 48, 52, 52, 128, 65, 66, 48, 52, - 49, 128, 65, 66, 48, 52, 48, 128, 65, 66, 48, 51, 57, 128, 65, 66, 48, - 51, 56, 128, 65, 66, 48, 51, 55, 128, 65, 66, 48, 51, 52, 128, 65, 66, - 48, 51, 49, 128, 65, 66, 48, 51, 48, 128, 65, 66, 48, 50, 57, 128, 65, - 66, 48, 50, 56, 128, 65, 66, 48, 50, 55, 128, 65, 66, 48, 50, 54, 128, - 65, 66, 48, 50, 52, 128, 65, 66, 48, 50, 51, 77, 128, 65, 66, 48, 50, 51, - 128, 65, 66, 48, 50, 50, 77, 128, 65, 66, 48, 50, 50, 70, 128, 65, 66, - 48, 50, 50, 128, 65, 66, 48, 50, 49, 77, 128, 65, 66, 48, 50, 49, 70, - 128, 65, 66, 48, 50, 49, 128, 65, 66, 48, 50, 48, 128, 65, 66, 48, 49, - 55, 128, 65, 66, 48, 49, 54, 128, 65, 66, 48, 49, 51, 128, 65, 66, 48, - 49, 49, 128, 65, 66, 48, 49, 48, 128, 65, 66, 48, 48, 57, 128, 65, 66, - 48, 48, 56, 128, 65, 66, 48, 48, 55, 128, 65, 66, 48, 48, 54, 128, 65, - 66, 48, 48, 53, 128, 65, 66, 48, 48, 52, 128, 65, 66, 48, 48, 51, 128, - 65, 66, 48, 48, 50, 128, 65, 66, 48, 48, 49, 128, 65, 65, 90, 72, 65, 65, - 75, 75, 85, 128, 65, 65, 89, 73, 78, 128, 65, 65, 89, 65, 78, 78, 65, - 128, 65, 65, 89, 128, 65, 65, 87, 128, 65, 65, 79, 128, 65, 65, 74, 128, - 65, 65, 66, 65, 65, 70, 73, 76, 73, 128, 65, 65, 48, 51, 50, 128, 65, 65, - 48, 51, 49, 128, 65, 65, 48, 51, 48, 128, 65, 65, 48, 50, 57, 128, 65, - 65, 48, 50, 56, 128, 65, 65, 48, 50, 55, 128, 65, 65, 48, 50, 54, 128, - 65, 65, 48, 50, 53, 128, 65, 65, 48, 50, 52, 128, 65, 65, 48, 50, 51, - 128, 65, 65, 48, 50, 50, 128, 65, 65, 48, 50, 49, 128, 65, 65, 48, 50, - 48, 128, 65, 65, 48, 49, 57, 128, 65, 65, 48, 49, 56, 128, 65, 65, 48, - 49, 55, 128, 65, 65, 48, 49, 54, 128, 65, 65, 48, 49, 53, 128, 65, 65, - 48, 49, 52, 128, 65, 65, 48, 49, 51, 128, 65, 65, 48, 49, 50, 128, 65, - 65, 48, 49, 49, 128, 65, 65, 48, 49, 48, 128, 65, 65, 48, 48, 57, 128, - 65, 65, 48, 48, 56, 128, 65, 65, 48, 48, 55, 66, 128, 65, 65, 48, 48, 55, - 65, 128, 65, 65, 48, 48, 55, 128, 65, 65, 48, 48, 54, 128, 65, 65, 48, - 48, 53, 128, 65, 65, 48, 48, 52, 128, 65, 65, 48, 48, 51, 128, 65, 65, - 48, 48, 50, 128, 65, 65, 48, 48, 49, 128, 65, 56, 48, 55, 128, 65, 56, - 48, 54, 128, 65, 56, 48, 53, 128, 65, 56, 48, 52, 128, 65, 56, 48, 51, - 128, 65, 56, 48, 50, 128, 65, 56, 48, 49, 128, 65, 56, 48, 48, 128, 65, - 55, 51, 178, 65, 55, 50, 182, 65, 55, 49, 183, 65, 55, 49, 181, 65, 55, - 49, 180, 65, 55, 49, 179, 65, 55, 49, 178, 65, 55, 49, 177, 65, 55, 49, - 176, 65, 55, 48, 57, 45, 182, 65, 55, 48, 57, 45, 180, 65, 55, 48, 57, - 45, 179, 65, 55, 48, 57, 45, 178, 65, 55, 48, 185, 65, 55, 48, 184, 65, - 55, 48, 183, 65, 55, 48, 182, 65, 55, 48, 181, 65, 55, 48, 180, 65, 55, - 48, 179, 65, 55, 48, 178, 65, 55, 48, 177, 65, 54, 54, 52, 128, 65, 54, - 54, 51, 128, 65, 54, 54, 50, 128, 65, 54, 54, 49, 128, 65, 54, 54, 48, - 128, 65, 54, 53, 57, 128, 65, 54, 53, 56, 128, 65, 54, 53, 55, 128, 65, - 54, 53, 54, 128, 65, 54, 53, 53, 128, 65, 54, 53, 52, 128, 65, 54, 53, - 51, 128, 65, 54, 53, 50, 128, 65, 54, 53, 49, 128, 65, 54, 52, 57, 128, - 65, 54, 52, 56, 128, 65, 54, 52, 54, 128, 65, 54, 52, 53, 128, 65, 54, - 52, 52, 128, 65, 54, 52, 51, 128, 65, 54, 52, 50, 128, 65, 54, 52, 48, - 128, 65, 54, 51, 56, 128, 65, 54, 51, 55, 128, 65, 54, 51, 52, 128, 65, - 54, 50, 57, 128, 65, 54, 50, 56, 128, 65, 54, 50, 55, 128, 65, 54, 50, - 54, 128, 65, 54, 50, 52, 128, 65, 54, 50, 51, 128, 65, 54, 50, 50, 128, - 65, 54, 50, 49, 128, 65, 54, 50, 48, 128, 65, 54, 49, 57, 128, 65, 54, - 49, 56, 128, 65, 54, 49, 55, 128, 65, 54, 49, 54, 128, 65, 54, 49, 53, - 128, 65, 54, 49, 52, 128, 65, 54, 49, 51, 128, 65, 54, 49, 50, 128, 65, - 54, 49, 49, 128, 65, 54, 49, 48, 128, 65, 54, 48, 57, 128, 65, 54, 48, - 56, 128, 65, 54, 48, 54, 128, 65, 54, 48, 52, 128, 65, 54, 48, 51, 128, - 65, 54, 48, 50, 128, 65, 54, 48, 49, 128, 65, 54, 48, 48, 128, 65, 53, - 57, 56, 128, 65, 53, 57, 54, 128, 65, 53, 57, 53, 128, 65, 53, 57, 52, - 128, 65, 53, 57, 50, 128, 65, 53, 57, 49, 128, 65, 53, 56, 57, 128, 65, - 53, 56, 56, 128, 65, 53, 56, 55, 128, 65, 53, 56, 54, 128, 65, 53, 56, - 53, 128, 65, 53, 56, 52, 128, 65, 53, 56, 51, 128, 65, 53, 56, 50, 128, - 65, 53, 56, 49, 128, 65, 53, 56, 48, 128, 65, 53, 55, 57, 128, 65, 53, - 55, 56, 128, 65, 53, 55, 55, 128, 65, 53, 55, 54, 128, 65, 53, 55, 53, - 128, 65, 53, 55, 52, 128, 65, 53, 55, 51, 128, 65, 53, 55, 50, 128, 65, - 53, 55, 49, 128, 65, 53, 55, 48, 128, 65, 53, 54, 57, 128, 65, 53, 54, - 56, 128, 65, 53, 54, 54, 128, 65, 53, 54, 53, 128, 65, 53, 54, 52, 128, - 65, 53, 54, 51, 128, 65, 53, 53, 57, 128, 65, 53, 53, 55, 128, 65, 53, - 53, 54, 128, 65, 53, 53, 53, 128, 65, 53, 53, 52, 128, 65, 53, 53, 51, - 128, 65, 53, 53, 50, 128, 65, 53, 53, 49, 128, 65, 53, 53, 48, 128, 65, - 53, 52, 57, 128, 65, 53, 52, 56, 128, 65, 53, 52, 55, 128, 65, 53, 52, - 53, 128, 65, 53, 52, 50, 128, 65, 53, 52, 49, 128, 65, 53, 52, 48, 128, - 65, 53, 51, 57, 128, 65, 53, 51, 56, 128, 65, 53, 51, 55, 128, 65, 53, - 51, 54, 128, 65, 53, 51, 53, 128, 65, 53, 51, 52, 128, 65, 53, 51, 50, - 128, 65, 53, 51, 49, 128, 65, 53, 51, 48, 128, 65, 53, 50, 57, 128, 65, - 53, 50, 56, 128, 65, 53, 50, 55, 128, 65, 53, 50, 54, 128, 65, 53, 50, - 53, 128, 65, 53, 50, 52, 128, 65, 53, 50, 51, 128, 65, 53, 50, 50, 128, - 65, 53, 50, 49, 128, 65, 53, 50, 48, 128, 65, 53, 49, 57, 128, 65, 53, - 49, 56, 128, 65, 53, 49, 55, 128, 65, 53, 49, 54, 128, 65, 53, 49, 53, - 128, 65, 53, 49, 52, 128, 65, 53, 49, 51, 128, 65, 53, 49, 50, 128, 65, - 53, 49, 49, 128, 65, 53, 49, 48, 128, 65, 53, 48, 57, 128, 65, 53, 48, - 56, 128, 65, 53, 48, 55, 128, 65, 53, 48, 54, 128, 65, 53, 48, 53, 128, - 65, 53, 48, 52, 128, 65, 53, 48, 51, 128, 65, 53, 48, 50, 128, 65, 53, - 48, 49, 128, 65, 52, 57, 55, 128, 65, 52, 57, 54, 128, 65, 52, 57, 53, - 128, 65, 52, 57, 52, 128, 65, 52, 57, 51, 128, 65, 52, 57, 50, 128, 65, - 52, 57, 49, 128, 65, 52, 57, 48, 128, 65, 52, 56, 57, 128, 65, 52, 56, - 56, 128, 65, 52, 56, 55, 128, 65, 52, 56, 54, 128, 65, 52, 56, 53, 128, - 65, 52, 56, 52, 128, 65, 52, 56, 51, 128, 65, 52, 56, 50, 128, 65, 52, - 56, 49, 128, 65, 52, 56, 48, 128, 65, 52, 55, 57, 128, 65, 52, 55, 56, - 128, 65, 52, 55, 55, 128, 65, 52, 55, 54, 128, 65, 52, 55, 53, 128, 65, - 52, 55, 52, 128, 65, 52, 55, 51, 128, 65, 52, 55, 50, 128, 65, 52, 55, - 49, 128, 65, 52, 55, 48, 128, 65, 52, 54, 57, 128, 65, 52, 54, 56, 128, - 65, 52, 54, 55, 128, 65, 52, 54, 54, 128, 65, 52, 54, 53, 128, 65, 52, - 54, 52, 128, 65, 52, 54, 51, 128, 65, 52, 54, 50, 128, 65, 52, 54, 49, - 128, 65, 52, 54, 48, 128, 65, 52, 53, 57, 128, 65, 52, 53, 56, 128, 65, - 52, 53, 55, 65, 128, 65, 52, 53, 55, 128, 65, 52, 53, 54, 128, 65, 52, - 53, 53, 128, 65, 52, 53, 52, 128, 65, 52, 53, 51, 128, 65, 52, 53, 50, - 128, 65, 52, 53, 49, 128, 65, 52, 53, 48, 65, 128, 65, 52, 53, 48, 128, - 65, 52, 52, 57, 128, 65, 52, 52, 56, 128, 65, 52, 52, 55, 128, 65, 52, - 52, 54, 128, 65, 52, 52, 53, 128, 65, 52, 52, 52, 128, 65, 52, 52, 51, - 128, 65, 52, 52, 50, 128, 65, 52, 52, 49, 128, 65, 52, 52, 48, 128, 65, - 52, 51, 57, 128, 65, 52, 51, 56, 128, 65, 52, 51, 55, 128, 65, 52, 51, - 54, 128, 65, 52, 51, 53, 128, 65, 52, 51, 52, 128, 65, 52, 51, 51, 128, - 65, 52, 51, 50, 128, 65, 52, 51, 49, 128, 65, 52, 51, 48, 128, 65, 52, - 50, 57, 128, 65, 52, 50, 56, 128, 65, 52, 50, 55, 128, 65, 52, 50, 54, - 128, 65, 52, 50, 53, 128, 65, 52, 50, 52, 128, 65, 52, 50, 51, 128, 65, - 52, 50, 50, 128, 65, 52, 50, 49, 128, 65, 52, 50, 48, 128, 65, 52, 49, - 57, 128, 65, 52, 49, 56, 45, 86, 65, 83, 128, 65, 52, 49, 56, 128, 65, - 52, 49, 55, 45, 86, 65, 83, 128, 65, 52, 49, 55, 128, 65, 52, 49, 54, 45, - 86, 65, 83, 128, 65, 52, 49, 54, 128, 65, 52, 49, 53, 45, 86, 65, 83, - 128, 65, 52, 49, 53, 128, 65, 52, 49, 52, 45, 86, 65, 83, 128, 65, 52, - 49, 52, 128, 65, 52, 49, 51, 45, 86, 65, 83, 128, 65, 52, 49, 51, 128, - 65, 52, 49, 50, 45, 86, 65, 83, 128, 65, 52, 49, 50, 128, 65, 52, 49, 49, - 45, 86, 65, 83, 128, 65, 52, 49, 49, 128, 65, 52, 49, 48, 193, 65, 52, - 49, 48, 45, 86, 65, 83, 128, 65, 52, 49, 176, 65, 52, 48, 57, 45, 86, 65, - 83, 128, 65, 52, 48, 57, 128, 65, 52, 48, 56, 45, 86, 65, 83, 128, 65, - 52, 48, 56, 128, 65, 52, 48, 55, 45, 86, 65, 83, 128, 65, 52, 48, 55, - 128, 65, 52, 48, 54, 45, 86, 65, 83, 128, 65, 52, 48, 54, 128, 65, 52, - 48, 53, 45, 86, 65, 83, 128, 65, 52, 48, 53, 128, 65, 52, 48, 52, 45, 86, - 65, 83, 128, 65, 52, 48, 52, 128, 65, 52, 48, 51, 45, 86, 65, 83, 128, - 65, 52, 48, 51, 128, 65, 52, 48, 50, 45, 86, 65, 83, 128, 65, 52, 48, 50, - 128, 65, 52, 48, 49, 45, 86, 65, 83, 128, 65, 52, 48, 49, 128, 65, 52, - 48, 48, 45, 86, 65, 83, 128, 65, 52, 48, 48, 128, 65, 51, 57, 57, 128, - 65, 51, 57, 56, 128, 65, 51, 57, 55, 128, 65, 51, 57, 54, 128, 65, 51, - 57, 53, 128, 65, 51, 57, 52, 128, 65, 51, 57, 179, 65, 51, 57, 50, 128, - 65, 51, 57, 49, 128, 65, 51, 57, 48, 128, 65, 51, 56, 57, 128, 65, 51, - 56, 56, 128, 65, 51, 56, 55, 128, 65, 51, 56, 54, 65, 128, 65, 51, 56, - 54, 128, 65, 51, 56, 53, 128, 65, 51, 56, 52, 128, 65, 51, 56, 51, 65, - 128, 65, 51, 56, 179, 65, 51, 56, 50, 128, 65, 51, 56, 49, 65, 128, 65, - 51, 56, 49, 128, 65, 51, 56, 48, 128, 65, 51, 55, 57, 128, 65, 51, 55, - 56, 128, 65, 51, 55, 55, 128, 65, 51, 55, 54, 128, 65, 51, 55, 53, 128, - 65, 51, 55, 52, 128, 65, 51, 55, 51, 128, 65, 51, 55, 50, 128, 65, 51, - 55, 49, 65, 128, 65, 51, 55, 49, 128, 65, 51, 55, 48, 128, 65, 51, 54, - 57, 128, 65, 51, 54, 56, 65, 128, 65, 51, 54, 56, 128, 65, 51, 54, 55, - 128, 65, 51, 54, 54, 128, 65, 51, 54, 53, 128, 65, 51, 54, 52, 65, 128, - 65, 51, 54, 52, 128, 65, 51, 54, 51, 128, 65, 51, 54, 50, 128, 65, 51, - 54, 49, 128, 65, 51, 54, 48, 128, 65, 51, 53, 57, 65, 128, 65, 51, 53, - 57, 128, 65, 51, 53, 56, 128, 65, 51, 53, 55, 128, 65, 51, 53, 54, 128, - 65, 51, 53, 53, 128, 65, 51, 53, 52, 128, 65, 51, 53, 51, 128, 65, 51, - 53, 50, 128, 65, 51, 53, 49, 128, 65, 51, 53, 48, 128, 65, 51, 52, 57, - 128, 65, 51, 52, 56, 128, 65, 51, 52, 55, 128, 65, 51, 52, 54, 128, 65, - 51, 52, 53, 128, 65, 51, 52, 52, 128, 65, 51, 52, 51, 128, 65, 51, 52, - 50, 128, 65, 51, 52, 49, 128, 65, 51, 52, 48, 128, 65, 51, 51, 57, 128, - 65, 51, 51, 56, 128, 65, 51, 51, 55, 128, 65, 51, 51, 54, 67, 128, 65, - 51, 51, 54, 66, 128, 65, 51, 51, 54, 65, 128, 65, 51, 51, 54, 128, 65, - 51, 51, 53, 128, 65, 51, 51, 52, 128, 65, 51, 51, 51, 128, 65, 51, 51, - 50, 67, 128, 65, 51, 51, 50, 66, 128, 65, 51, 51, 50, 65, 128, 65, 51, - 51, 50, 128, 65, 51, 51, 49, 128, 65, 51, 51, 48, 128, 65, 51, 50, 57, - 65, 128, 65, 51, 50, 57, 128, 65, 51, 50, 56, 128, 65, 51, 50, 55, 128, - 65, 51, 50, 54, 128, 65, 51, 50, 53, 128, 65, 51, 50, 52, 128, 65, 51, - 50, 51, 128, 65, 51, 50, 50, 128, 65, 51, 50, 49, 128, 65, 51, 50, 48, - 128, 65, 51, 49, 57, 128, 65, 51, 49, 56, 128, 65, 51, 49, 55, 128, 65, - 51, 49, 54, 128, 65, 51, 49, 53, 128, 65, 51, 49, 52, 128, 65, 51, 49, - 51, 67, 128, 65, 51, 49, 51, 66, 128, 65, 51, 49, 51, 65, 128, 65, 51, - 49, 51, 128, 65, 51, 49, 50, 128, 65, 51, 49, 49, 128, 65, 51, 49, 48, - 128, 65, 51, 48, 57, 67, 128, 65, 51, 48, 57, 66, 128, 65, 51, 48, 57, - 65, 128, 65, 51, 48, 57, 128, 65, 51, 48, 56, 128, 65, 51, 48, 55, 128, - 65, 51, 48, 54, 128, 65, 51, 48, 53, 128, 65, 51, 48, 52, 128, 65, 51, - 48, 51, 128, 65, 51, 48, 50, 128, 65, 51, 48, 49, 128, 65, 51, 48, 48, - 128, 65, 50, 57, 57, 65, 128, 65, 50, 57, 57, 128, 65, 50, 57, 56, 128, - 65, 50, 57, 55, 128, 65, 50, 57, 54, 128, 65, 50, 57, 53, 128, 65, 50, - 57, 52, 65, 128, 65, 50, 57, 52, 128, 65, 50, 57, 51, 128, 65, 50, 57, - 50, 128, 65, 50, 57, 49, 128, 65, 50, 57, 48, 128, 65, 50, 56, 57, 65, - 128, 65, 50, 56, 57, 128, 65, 50, 56, 56, 128, 65, 50, 56, 55, 128, 65, - 50, 56, 54, 128, 65, 50, 56, 53, 128, 65, 50, 56, 52, 128, 65, 50, 56, - 51, 128, 65, 50, 56, 50, 128, 65, 50, 56, 49, 128, 65, 50, 56, 48, 128, - 65, 50, 55, 57, 128, 65, 50, 55, 56, 128, 65, 50, 55, 55, 128, 65, 50, - 55, 54, 128, 65, 50, 55, 53, 128, 65, 50, 55, 52, 128, 65, 50, 55, 51, - 128, 65, 50, 55, 50, 128, 65, 50, 55, 49, 128, 65, 50, 55, 48, 128, 65, - 50, 54, 57, 128, 65, 50, 54, 56, 128, 65, 50, 54, 55, 65, 128, 65, 50, - 54, 55, 128, 65, 50, 54, 54, 128, 65, 50, 54, 53, 128, 65, 50, 54, 52, - 128, 65, 50, 54, 51, 128, 65, 50, 54, 50, 128, 65, 50, 54, 49, 128, 65, - 50, 54, 48, 128, 65, 50, 53, 57, 128, 65, 50, 53, 56, 128, 65, 50, 53, - 55, 128, 65, 50, 53, 54, 128, 65, 50, 53, 53, 128, 65, 50, 53, 52, 128, - 65, 50, 53, 51, 128, 65, 50, 53, 50, 128, 65, 50, 53, 49, 128, 65, 50, - 53, 48, 128, 65, 50, 52, 57, 128, 65, 50, 52, 56, 128, 65, 50, 52, 55, - 128, 65, 50, 52, 54, 128, 65, 50, 52, 53, 128, 65, 50, 52, 52, 128, 65, - 50, 52, 51, 128, 65, 50, 52, 50, 128, 65, 50, 52, 49, 128, 65, 50, 52, - 48, 128, 65, 50, 51, 57, 128, 65, 50, 51, 56, 128, 65, 50, 51, 55, 128, - 65, 50, 51, 54, 128, 65, 50, 51, 53, 128, 65, 50, 51, 52, 128, 65, 50, - 51, 51, 128, 65, 50, 51, 50, 128, 65, 50, 51, 49, 128, 65, 50, 51, 48, - 128, 65, 50, 50, 57, 128, 65, 50, 50, 56, 128, 65, 50, 50, 55, 65, 128, - 65, 50, 50, 55, 128, 65, 50, 50, 54, 128, 65, 50, 50, 53, 128, 65, 50, - 50, 52, 128, 65, 50, 50, 51, 128, 65, 50, 50, 50, 128, 65, 50, 50, 49, - 128, 65, 50, 50, 48, 128, 65, 50, 49, 57, 128, 65, 50, 49, 56, 128, 65, - 50, 49, 55, 128, 65, 50, 49, 54, 65, 128, 65, 50, 49, 54, 128, 65, 50, - 49, 53, 65, 128, 65, 50, 49, 53, 128, 65, 50, 49, 52, 128, 65, 50, 49, - 51, 128, 65, 50, 49, 50, 128, 65, 50, 49, 49, 128, 65, 50, 49, 48, 128, - 65, 50, 48, 57, 65, 128, 65, 50, 48, 57, 128, 65, 50, 48, 56, 128, 65, - 50, 48, 55, 65, 128, 65, 50, 48, 55, 128, 65, 50, 48, 54, 128, 65, 50, - 48, 53, 128, 65, 50, 48, 52, 128, 65, 50, 48, 51, 128, 65, 50, 48, 50, - 66, 128, 65, 50, 48, 50, 65, 128, 65, 50, 48, 50, 128, 65, 50, 48, 49, - 128, 65, 50, 48, 48, 128, 65, 49, 57, 57, 128, 65, 49, 57, 56, 128, 65, - 49, 57, 55, 128, 65, 49, 57, 54, 128, 65, 49, 57, 53, 128, 65, 49, 57, - 52, 128, 65, 49, 57, 51, 128, 65, 49, 57, 50, 128, 65, 49, 57, 49, 128, - 65, 49, 57, 48, 128, 65, 49, 56, 57, 128, 65, 49, 56, 56, 128, 65, 49, - 56, 55, 128, 65, 49, 56, 54, 128, 65, 49, 56, 53, 128, 65, 49, 56, 52, - 128, 65, 49, 56, 51, 128, 65, 49, 56, 50, 128, 65, 49, 56, 49, 128, 65, - 49, 56, 48, 128, 65, 49, 55, 57, 128, 65, 49, 55, 56, 128, 65, 49, 55, - 55, 128, 65, 49, 55, 54, 128, 65, 49, 55, 53, 128, 65, 49, 55, 52, 128, - 65, 49, 55, 51, 128, 65, 49, 55, 50, 128, 65, 49, 55, 49, 128, 65, 49, - 55, 48, 128, 65, 49, 54, 57, 128, 65, 49, 54, 56, 128, 65, 49, 54, 55, - 128, 65, 49, 54, 54, 128, 65, 49, 54, 53, 128, 65, 49, 54, 52, 128, 65, - 49, 54, 51, 128, 65, 49, 54, 50, 128, 65, 49, 54, 49, 128, 65, 49, 54, - 48, 128, 65, 49, 53, 57, 128, 65, 49, 53, 56, 128, 65, 49, 53, 55, 128, - 65, 49, 53, 54, 128, 65, 49, 53, 53, 128, 65, 49, 53, 52, 128, 65, 49, - 53, 51, 128, 65, 49, 53, 50, 128, 65, 49, 53, 49, 128, 65, 49, 53, 48, - 128, 65, 49, 52, 57, 128, 65, 49, 52, 56, 128, 65, 49, 52, 55, 128, 65, - 49, 52, 54, 128, 65, 49, 52, 53, 128, 65, 49, 52, 52, 128, 65, 49, 52, - 51, 128, 65, 49, 52, 50, 128, 65, 49, 52, 49, 128, 65, 49, 52, 48, 128, - 65, 49, 51, 57, 128, 65, 49, 51, 56, 128, 65, 49, 51, 55, 128, 65, 49, - 51, 54, 128, 65, 49, 51, 53, 65, 128, 65, 49, 51, 53, 128, 65, 49, 51, - 52, 128, 65, 49, 51, 51, 128, 65, 49, 51, 50, 128, 65, 49, 51, 49, 67, - 128, 65, 49, 51, 49, 128, 65, 49, 51, 48, 128, 65, 49, 50, 57, 128, 65, - 49, 50, 56, 128, 65, 49, 50, 55, 128, 65, 49, 50, 54, 128, 65, 49, 50, - 53, 65, 128, 65, 49, 50, 53, 128, 65, 49, 50, 52, 128, 65, 49, 50, 51, - 128, 65, 49, 50, 50, 128, 65, 49, 50, 49, 128, 65, 49, 50, 48, 66, 128, - 65, 49, 50, 48, 128, 65, 49, 49, 57, 128, 65, 49, 49, 56, 128, 65, 49, - 49, 55, 128, 65, 49, 49, 54, 128, 65, 49, 49, 53, 65, 128, 65, 49, 49, - 53, 128, 65, 49, 49, 52, 128, 65, 49, 49, 51, 128, 65, 49, 49, 50, 128, - 65, 49, 49, 49, 128, 65, 49, 49, 48, 66, 128, 65, 49, 49, 48, 65, 128, - 65, 49, 49, 48, 128, 65, 49, 48, 57, 128, 65, 49, 48, 56, 128, 65, 49, - 48, 55, 67, 128, 65, 49, 48, 55, 66, 128, 65, 49, 48, 55, 65, 128, 65, - 49, 48, 55, 128, 65, 49, 48, 54, 128, 65, 49, 48, 53, 66, 128, 65, 49, - 48, 53, 65, 128, 65, 49, 48, 53, 128, 65, 49, 48, 52, 67, 128, 65, 49, - 48, 52, 66, 128, 65, 49, 48, 52, 65, 128, 65, 49, 48, 52, 128, 65, 49, - 48, 51, 128, 65, 49, 48, 50, 65, 128, 65, 49, 48, 50, 128, 65, 49, 48, - 49, 65, 128, 65, 49, 48, 49, 128, 65, 49, 48, 48, 65, 128, 65, 49, 48, - 48, 45, 49, 48, 50, 128, 65, 49, 48, 48, 128, 65, 48, 57, 57, 128, 65, - 48, 57, 56, 65, 128, 65, 48, 57, 56, 128, 65, 48, 57, 55, 65, 128, 65, - 48, 57, 55, 128, 65, 48, 57, 54, 128, 65, 48, 57, 53, 128, 65, 48, 57, - 52, 128, 65, 48, 57, 51, 128, 65, 48, 57, 50, 128, 65, 48, 57, 49, 128, - 65, 48, 57, 48, 128, 65, 48, 56, 57, 128, 65, 48, 56, 56, 128, 65, 48, - 56, 55, 128, 65, 48, 56, 54, 128, 65, 48, 56, 53, 128, 65, 48, 56, 52, - 128, 65, 48, 56, 51, 128, 65, 48, 56, 50, 128, 65, 48, 56, 49, 128, 65, - 48, 56, 48, 128, 65, 48, 55, 57, 128, 65, 48, 55, 56, 128, 65, 48, 55, - 55, 128, 65, 48, 55, 54, 128, 65, 48, 55, 53, 128, 65, 48, 55, 52, 128, - 65, 48, 55, 51, 128, 65, 48, 55, 50, 128, 65, 48, 55, 49, 128, 65, 48, - 55, 48, 128, 65, 48, 54, 57, 128, 65, 48, 54, 56, 128, 65, 48, 54, 55, - 128, 65, 48, 54, 54, 67, 128, 65, 48, 54, 54, 66, 128, 65, 48, 54, 54, - 65, 128, 65, 48, 54, 54, 128, 65, 48, 54, 53, 128, 65, 48, 54, 52, 128, - 65, 48, 54, 51, 128, 65, 48, 54, 50, 128, 65, 48, 54, 49, 128, 65, 48, - 54, 48, 128, 65, 48, 53, 57, 128, 65, 48, 53, 56, 128, 65, 48, 53, 55, - 128, 65, 48, 53, 54, 128, 65, 48, 53, 53, 128, 65, 48, 53, 52, 128, 65, - 48, 53, 51, 128, 65, 48, 53, 50, 128, 65, 48, 53, 49, 128, 65, 48, 53, - 48, 128, 65, 48, 52, 57, 128, 65, 48, 52, 56, 128, 65, 48, 52, 55, 128, - 65, 48, 52, 54, 66, 128, 65, 48, 52, 54, 65, 128, 65, 48, 52, 54, 128, - 65, 48, 52, 53, 65, 128, 65, 48, 52, 53, 128, 65, 48, 52, 52, 128, 65, - 48, 52, 51, 65, 128, 65, 48, 52, 51, 128, 65, 48, 52, 50, 65, 128, 65, - 48, 52, 50, 128, 65, 48, 52, 49, 65, 128, 65, 48, 52, 49, 128, 65, 48, - 52, 48, 65, 128, 65, 48, 52, 48, 128, 65, 48, 51, 57, 65, 128, 65, 48, - 51, 57, 128, 65, 48, 51, 56, 128, 65, 48, 51, 55, 128, 65, 48, 51, 54, - 128, 65, 48, 51, 53, 128, 65, 48, 51, 52, 128, 65, 48, 51, 51, 128, 65, - 48, 51, 50, 65, 128, 65, 48, 50, 56, 66, 128, 65, 48, 50, 54, 65, 128, - 65, 48, 49, 55, 65, 128, 65, 48, 49, 52, 65, 128, 65, 48, 49, 48, 65, - 128, 65, 48, 48, 54, 66, 128, 65, 48, 48, 54, 65, 128, 65, 48, 48, 53, - 65, 128, 65, 45, 87, 79, 128, 65, 45, 69, 85, 128, 45, 85, 205, 45, 80, - 72, 82, 85, 128, 45, 75, 72, 89, 85, 196, 45, 75, 72, 89, 73, 76, 128, - 45, 68, 90, 85, 196, 45, 67, 72, 65, 210, 45, 67, 72, 65, 76, 128, + 79, 82, 128, 65, 78, 89, 128, 65, 78, 85, 83, 86, 65, 82, 65, 89, 65, + 128, 65, 78, 85, 83, 86, 65, 82, 65, 128, 65, 78, 85, 83, 86, 65, 82, + 193, 65, 78, 85, 68, 65, 84, 84, 65, 128, 65, 78, 85, 68, 65, 84, 84, + 193, 65, 78, 84, 73, 82, 69, 83, 84, 82, 73, 67, 84, 73, 79, 78, 128, 65, + 78, 84, 73, 77, 79, 78, 89, 45, 50, 128, 65, 78, 84, 73, 77, 79, 78, 89, + 128, 65, 78, 84, 73, 77, 79, 78, 217, 65, 78, 84, 73, 77, 79, 78, 73, 65, + 84, 69, 128, 65, 78, 84, 73, 75, 69, 78, 79, 77, 65, 128, 65, 78, 84, 73, + 75, 69, 78, 79, 75, 89, 76, 73, 83, 77, 65, 128, 65, 78, 84, 73, 70, 79, + 78, 73, 65, 128, 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, 83, 69, 45, + 82, 79, 84, 65, 84, 69, 196, 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, + 83, 69, 128, 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, 83, 197, 65, 78, + 84, 69, 78, 78, 65, 128, 65, 78, 84, 69, 78, 78, 193, 65, 78, 84, 65, 82, + 71, 79, 77, 85, 75, 72, 65, 128, 65, 78, 83, 85, 218, 65, 78, 83, 72, 69, + 128, 65, 78, 80, 69, 65, 128, 65, 78, 207, 65, 78, 78, 85, 73, 84, 217, + 65, 78, 78, 79, 84, 65, 84, 73, 79, 206, 65, 78, 78, 65, 65, 85, 128, 65, + 78, 75, 72, 128, 65, 78, 74, 73, 128, 65, 78, 73, 77, 65, 76, 128, 65, + 78, 72, 85, 78, 78, 65, 128, 65, 78, 72, 85, 77, 65, 65, 128, 65, 78, 72, + 85, 77, 128, 65, 78, 72, 85, 128, 65, 78, 72, 65, 65, 128, 65, 78, 72, + 128, 65, 78, 71, 85, 76, 65, 82, 128, 65, 78, 71, 85, 73, 83, 72, 69, + 196, 65, 78, 71, 83, 84, 82, 79, 205, 65, 78, 71, 82, 217, 65, 78, 71, + 76, 73, 67, 65, 78, 193, 65, 78, 71, 76, 69, 68, 128, 65, 78, 71, 76, 69, + 196, 65, 78, 71, 75, 72, 65, 78, 75, 72, 85, 128, 65, 78, 71, 75, 65, + 128, 65, 78, 71, 69, 210, 65, 78, 71, 69, 76, 128, 65, 78, 71, 69, 68, + 128, 65, 78, 68, 65, 80, 128, 65, 78, 67, 79, 82, 65, 128, 65, 78, 67, + 72, 79, 82, 128, 65, 78, 65, 84, 82, 73, 67, 72, 73, 83, 77, 65, 128, 65, + 78, 65, 84, 79, 77, 73, 67, 65, 204, 65, 78, 65, 80, 128, 65, 78, 45, 78, + 73, 83, 70, 128, 65, 77, 85, 76, 69, 84, 128, 65, 77, 80, 83, 128, 65, + 77, 80, 72, 79, 82, 65, 128, 65, 77, 80, 69, 82, 83, 65, 78, 68, 128, 65, + 77, 80, 69, 82, 83, 65, 78, 196, 65, 77, 79, 85, 78, 212, 65, 77, 69, 82, + 73, 67, 65, 83, 128, 65, 77, 69, 82, 73, 67, 65, 206, 65, 77, 66, 85, 76, + 65, 78, 67, 69, 128, 65, 77, 66, 193, 65, 77, 66, 128, 65, 77, 65, 82, + 128, 65, 77, 65, 210, 65, 77, 65, 76, 71, 65, 77, 65, 84, 73, 79, 206, + 65, 77, 65, 76, 71, 65, 77, 128, 65, 76, 86, 69, 79, 76, 65, 210, 65, 76, + 85, 77, 128, 65, 76, 84, 69, 82, 78, 65, 84, 73, 86, 197, 65, 76, 84, 69, + 82, 78, 65, 84, 73, 79, 206, 65, 76, 84, 69, 82, 78, 65, 84, 73, 78, 71, + 128, 65, 76, 84, 69, 82, 78, 65, 84, 73, 78, 199, 65, 76, 84, 69, 82, 78, + 65, 84, 69, 128, 65, 76, 84, 69, 82, 78, 65, 84, 197, 65, 76, 84, 65, + 128, 65, 76, 80, 72, 65, 128, 65, 76, 80, 72, 193, 65, 76, 80, 65, 80, + 82, 65, 78, 65, 128, 65, 76, 80, 65, 80, 82, 65, 65, 78, 193, 65, 76, 80, + 65, 128, 65, 76, 77, 79, 83, 212, 65, 76, 76, 79, 128, 65, 76, 76, 73, + 65, 78, 67, 69, 128, 65, 76, 76, 201, 65, 76, 76, 65, 200, 65, 76, 76, + 65, 65, 72, 128, 65, 76, 75, 65, 76, 73, 45, 50, 128, 65, 76, 75, 65, 76, + 73, 128, 65, 76, 73, 71, 78, 69, 196, 65, 76, 73, 70, 85, 128, 65, 76, + 73, 70, 128, 65, 76, 73, 198, 65, 76, 73, 69, 78, 128, 65, 76, 73, 69, + 206, 65, 76, 71, 73, 218, 65, 76, 70, 65, 128, 65, 76, 69, 85, 212, 65, + 76, 69, 82, 84, 128, 65, 76, 69, 80, 72, 128, 65, 76, 69, 77, 66, 73, 67, + 128, 65, 76, 69, 70, 128, 65, 76, 66, 65, 78, 73, 65, 206, 65, 76, 65, + 89, 78, 65, 65, 128, 65, 76, 65, 89, 72, 73, 77, 65, 193, 65, 76, 65, 89, + 72, 73, 205, 65, 76, 65, 89, 72, 201, 65, 76, 65, 89, 72, 69, 128, 65, + 76, 65, 89, 72, 197, 65, 76, 65, 89, 72, 65, 193, 65, 76, 65, 82, 205, + 65, 76, 65, 80, 72, 128, 65, 76, 45, 76, 65, 75, 85, 78, 65, 128, 65, 76, + 45, 74, 85, 90, 128, 65, 75, 85, 82, 213, 65, 75, 84, 73, 69, 83, 69, 76, + 83, 75, 65, 66, 128, 65, 75, 83, 65, 128, 65, 75, 72, 77, 73, 77, 73, + 195, 65, 75, 66, 65, 210, 65, 75, 65, 82, 65, 128, 65, 75, 65, 82, 193, + 65, 73, 89, 65, 78, 78, 65, 128, 65, 73, 86, 73, 76, 73, 203, 65, 73, 86, + 65, 128, 65, 73, 84, 79, 206, 65, 73, 82, 80, 76, 65, 78, 69, 128, 65, + 73, 82, 80, 76, 65, 78, 197, 65, 73, 78, 213, 65, 73, 78, 78, 128, 65, + 73, 76, 77, 128, 65, 73, 75, 65, 82, 65, 128, 65, 73, 72, 86, 85, 83, + 128, 65, 72, 83, 68, 65, 128, 65, 72, 83, 65, 128, 65, 72, 79, 205, 65, + 72, 65, 78, 199, 65, 72, 65, 71, 71, 65, 210, 65, 72, 65, 68, 128, 65, + 71, 85, 78, 71, 128, 65, 71, 79, 71, 201, 65, 71, 71, 82, 65, 86, 65, 84, + 73, 79, 78, 128, 65, 71, 71, 82, 65, 86, 65, 84, 69, 196, 65, 71, 65, 73, + 78, 83, 212, 65, 71, 65, 73, 78, 128, 65, 70, 84, 69, 210, 65, 70, 83, + 65, 65, 81, 128, 65, 70, 82, 73, 67, 65, 206, 65, 70, 79, 82, 69, 77, 69, + 78, 84, 73, 79, 78, 69, 68, 128, 65, 70, 71, 72, 65, 78, 201, 65, 70, 70, + 82, 73, 67, 65, 84, 73, 79, 206, 65, 70, 70, 73, 216, 65, 69, 89, 65, 78, + 78, 65, 128, 65, 69, 89, 128, 65, 69, 83, 67, 85, 76, 65, 80, 73, 85, 83, + 128, 65, 69, 83, 67, 128, 65, 69, 83, 128, 65, 69, 82, 73, 65, 204, 65, + 69, 82, 128, 65, 69, 76, 65, 45, 80, 73, 76, 76, 65, 128, 65, 69, 76, + 128, 65, 69, 75, 128, 65, 69, 71, 69, 65, 206, 65, 69, 71, 128, 65, 69, + 69, 89, 65, 78, 78, 65, 128, 65, 69, 69, 128, 65, 69, 68, 65, 45, 80, 73, + 76, 76, 65, 128, 65, 69, 68, 128, 65, 69, 66, 128, 65, 68, 86, 65, 78, + 84, 65, 71, 69, 128, 65, 68, 86, 65, 78, 67, 69, 128, 65, 68, 85, 76, 84, + 128, 65, 68, 77, 73, 83, 83, 73, 79, 206, 65, 68, 77, 69, 84, 79, 83, + 128, 65, 68, 76, 65, 205, 65, 68, 72, 69, 83, 73, 86, 197, 65, 68, 69, + 71, 128, 65, 68, 69, 199, 65, 68, 68, 82, 69, 83, 83, 69, 196, 65, 68, + 68, 82, 69, 83, 211, 65, 68, 68, 65, 75, 128, 65, 68, 65, 203, 65, 67, + 85, 84, 69, 45, 77, 65, 67, 82, 79, 78, 128, 65, 67, 85, 84, 69, 45, 71, + 82, 65, 86, 69, 45, 65, 67, 85, 84, 69, 128, 65, 67, 85, 84, 197, 65, 67, + 84, 85, 65, 76, 76, 217, 65, 67, 84, 73, 86, 65, 84, 197, 65, 67, 82, 79, + 80, 72, 79, 78, 73, 195, 65, 67, 75, 78, 79, 87, 76, 69, 68, 71, 69, 128, + 65, 67, 67, 85, 77, 85, 76, 65, 84, 73, 79, 78, 128, 65, 67, 67, 79, 85, + 78, 212, 65, 67, 67, 79, 82, 68, 73, 79, 78, 128, 65, 67, 67, 79, 77, 77, + 79, 68, 65, 84, 73, 79, 78, 128, 65, 67, 67, 69, 80, 84, 128, 65, 67, 67, + 69, 78, 84, 45, 83, 84, 65, 67, 67, 65, 84, 79, 128, 65, 67, 67, 69, 78, + 84, 128, 65, 67, 67, 69, 78, 212, 65, 67, 65, 68, 69, 77, 217, 65, 66, + 89, 83, 77, 65, 204, 65, 66, 85, 78, 68, 65, 78, 67, 69, 128, 65, 66, 75, + 72, 65, 83, 73, 65, 206, 65, 66, 66, 82, 69, 86, 73, 65, 84, 73, 79, 206, + 65, 66, 65, 70, 73, 76, 73, 128, 65, 66, 65, 67, 85, 83, 128, 65, 66, + 178, 65, 66, 49, 57, 49, 128, 65, 66, 49, 56, 56, 128, 65, 66, 49, 56, + 48, 128, 65, 66, 49, 55, 49, 128, 65, 66, 49, 54, 52, 128, 65, 66, 49, + 51, 49, 66, 128, 65, 66, 49, 51, 49, 65, 128, 65, 66, 49, 50, 51, 128, + 65, 66, 49, 50, 50, 128, 65, 66, 49, 50, 48, 128, 65, 66, 49, 49, 56, + 128, 65, 66, 48, 56, 55, 128, 65, 66, 48, 56, 54, 128, 65, 66, 48, 56, + 53, 128, 65, 66, 48, 56, 50, 128, 65, 66, 48, 56, 49, 128, 65, 66, 48, + 56, 48, 128, 65, 66, 48, 55, 57, 128, 65, 66, 48, 55, 56, 128, 65, 66, + 48, 55, 55, 128, 65, 66, 48, 55, 54, 128, 65, 66, 48, 55, 52, 128, 65, + 66, 48, 55, 51, 128, 65, 66, 48, 55, 48, 128, 65, 66, 48, 54, 57, 128, + 65, 66, 48, 54, 55, 128, 65, 66, 48, 54, 54, 128, 65, 66, 48, 54, 53, + 128, 65, 66, 48, 54, 49, 128, 65, 66, 48, 54, 48, 128, 65, 66, 48, 53, + 57, 128, 65, 66, 48, 53, 56, 128, 65, 66, 48, 53, 55, 128, 65, 66, 48, + 53, 54, 128, 65, 66, 48, 53, 53, 128, 65, 66, 48, 53, 52, 128, 65, 66, + 48, 53, 51, 128, 65, 66, 48, 53, 49, 128, 65, 66, 48, 53, 48, 128, 65, + 66, 48, 52, 57, 128, 65, 66, 48, 52, 56, 128, 65, 66, 48, 52, 55, 128, + 65, 66, 48, 52, 54, 128, 65, 66, 48, 52, 53, 128, 65, 66, 48, 52, 52, + 128, 65, 66, 48, 52, 49, 128, 65, 66, 48, 52, 48, 128, 65, 66, 48, 51, + 57, 128, 65, 66, 48, 51, 56, 128, 65, 66, 48, 51, 55, 128, 65, 66, 48, + 51, 52, 128, 65, 66, 48, 51, 49, 128, 65, 66, 48, 51, 48, 128, 65, 66, + 48, 50, 57, 128, 65, 66, 48, 50, 56, 128, 65, 66, 48, 50, 55, 128, 65, + 66, 48, 50, 54, 128, 65, 66, 48, 50, 52, 128, 65, 66, 48, 50, 51, 77, + 128, 65, 66, 48, 50, 51, 128, 65, 66, 48, 50, 50, 77, 128, 65, 66, 48, + 50, 50, 70, 128, 65, 66, 48, 50, 50, 128, 65, 66, 48, 50, 49, 77, 128, + 65, 66, 48, 50, 49, 70, 128, 65, 66, 48, 50, 49, 128, 65, 66, 48, 50, 48, + 128, 65, 66, 48, 49, 55, 128, 65, 66, 48, 49, 54, 128, 65, 66, 48, 49, + 51, 128, 65, 66, 48, 49, 49, 128, 65, 66, 48, 49, 48, 128, 65, 66, 48, + 48, 57, 128, 65, 66, 48, 48, 56, 128, 65, 66, 48, 48, 55, 128, 65, 66, + 48, 48, 54, 128, 65, 66, 48, 48, 53, 128, 65, 66, 48, 48, 52, 128, 65, + 66, 48, 48, 51, 128, 65, 66, 48, 48, 50, 128, 65, 66, 48, 48, 49, 128, + 65, 65, 90, 72, 65, 65, 75, 75, 85, 128, 65, 65, 89, 73, 78, 128, 65, 65, + 89, 65, 78, 78, 65, 128, 65, 65, 89, 128, 65, 65, 87, 128, 65, 65, 79, + 128, 65, 65, 74, 128, 65, 65, 66, 65, 65, 70, 73, 76, 73, 128, 65, 65, + 48, 51, 50, 128, 65, 65, 48, 51, 49, 128, 65, 65, 48, 51, 48, 128, 65, + 65, 48, 50, 57, 128, 65, 65, 48, 50, 56, 128, 65, 65, 48, 50, 55, 128, + 65, 65, 48, 50, 54, 128, 65, 65, 48, 50, 53, 128, 65, 65, 48, 50, 52, + 128, 65, 65, 48, 50, 51, 128, 65, 65, 48, 50, 50, 128, 65, 65, 48, 50, + 49, 128, 65, 65, 48, 50, 48, 128, 65, 65, 48, 49, 57, 128, 65, 65, 48, + 49, 56, 128, 65, 65, 48, 49, 55, 128, 65, 65, 48, 49, 54, 128, 65, 65, + 48, 49, 53, 128, 65, 65, 48, 49, 52, 128, 65, 65, 48, 49, 51, 128, 65, + 65, 48, 49, 50, 128, 65, 65, 48, 49, 49, 128, 65, 65, 48, 49, 48, 128, + 65, 65, 48, 48, 57, 128, 65, 65, 48, 48, 56, 128, 65, 65, 48, 48, 55, 66, + 128, 65, 65, 48, 48, 55, 65, 128, 65, 65, 48, 48, 55, 128, 65, 65, 48, + 48, 54, 128, 65, 65, 48, 48, 53, 128, 65, 65, 48, 48, 52, 128, 65, 65, + 48, 48, 51, 128, 65, 65, 48, 48, 50, 128, 65, 65, 48, 48, 49, 128, 65, + 56, 48, 55, 128, 65, 56, 48, 54, 128, 65, 56, 48, 53, 128, 65, 56, 48, + 52, 128, 65, 56, 48, 51, 128, 65, 56, 48, 50, 128, 65, 56, 48, 49, 128, + 65, 56, 48, 48, 128, 65, 55, 51, 178, 65, 55, 50, 182, 65, 55, 49, 183, + 65, 55, 49, 181, 65, 55, 49, 180, 65, 55, 49, 179, 65, 55, 49, 178, 65, + 55, 49, 177, 65, 55, 49, 176, 65, 55, 48, 57, 45, 182, 65, 55, 48, 57, + 45, 180, 65, 55, 48, 57, 45, 179, 65, 55, 48, 57, 45, 178, 65, 55, 48, + 185, 65, 55, 48, 184, 65, 55, 48, 183, 65, 55, 48, 182, 65, 55, 48, 181, + 65, 55, 48, 180, 65, 55, 48, 179, 65, 55, 48, 178, 65, 55, 48, 177, 65, + 54, 54, 52, 128, 65, 54, 54, 51, 128, 65, 54, 54, 50, 128, 65, 54, 54, + 49, 128, 65, 54, 54, 48, 128, 65, 54, 53, 57, 128, 65, 54, 53, 56, 128, + 65, 54, 53, 55, 128, 65, 54, 53, 54, 128, 65, 54, 53, 53, 128, 65, 54, + 53, 52, 128, 65, 54, 53, 51, 128, 65, 54, 53, 50, 128, 65, 54, 53, 49, + 128, 65, 54, 52, 57, 128, 65, 54, 52, 56, 128, 65, 54, 52, 54, 128, 65, + 54, 52, 53, 128, 65, 54, 52, 52, 128, 65, 54, 52, 51, 128, 65, 54, 52, + 50, 128, 65, 54, 52, 48, 128, 65, 54, 51, 56, 128, 65, 54, 51, 55, 128, + 65, 54, 51, 52, 128, 65, 54, 50, 57, 128, 65, 54, 50, 56, 128, 65, 54, + 50, 55, 128, 65, 54, 50, 54, 128, 65, 54, 50, 52, 128, 65, 54, 50, 51, + 128, 65, 54, 50, 50, 128, 65, 54, 50, 49, 128, 65, 54, 50, 48, 128, 65, + 54, 49, 57, 128, 65, 54, 49, 56, 128, 65, 54, 49, 55, 128, 65, 54, 49, + 54, 128, 65, 54, 49, 53, 128, 65, 54, 49, 52, 128, 65, 54, 49, 51, 128, + 65, 54, 49, 50, 128, 65, 54, 49, 49, 128, 65, 54, 49, 48, 128, 65, 54, + 48, 57, 128, 65, 54, 48, 56, 128, 65, 54, 48, 54, 128, 65, 54, 48, 52, + 128, 65, 54, 48, 51, 128, 65, 54, 48, 50, 128, 65, 54, 48, 49, 128, 65, + 54, 48, 48, 128, 65, 53, 57, 56, 128, 65, 53, 57, 54, 128, 65, 53, 57, + 53, 128, 65, 53, 57, 52, 128, 65, 53, 57, 50, 128, 65, 53, 57, 49, 128, + 65, 53, 56, 57, 128, 65, 53, 56, 56, 128, 65, 53, 56, 55, 128, 65, 53, + 56, 54, 128, 65, 53, 56, 53, 128, 65, 53, 56, 52, 128, 65, 53, 56, 51, + 128, 65, 53, 56, 50, 128, 65, 53, 56, 49, 128, 65, 53, 56, 48, 128, 65, + 53, 55, 57, 128, 65, 53, 55, 56, 128, 65, 53, 55, 55, 128, 65, 53, 55, + 54, 128, 65, 53, 55, 53, 128, 65, 53, 55, 52, 128, 65, 53, 55, 51, 128, + 65, 53, 55, 50, 128, 65, 53, 55, 49, 128, 65, 53, 55, 48, 128, 65, 53, + 54, 57, 128, 65, 53, 54, 56, 128, 65, 53, 54, 54, 128, 65, 53, 54, 53, + 128, 65, 53, 54, 52, 128, 65, 53, 54, 51, 128, 65, 53, 53, 57, 128, 65, + 53, 53, 55, 128, 65, 53, 53, 54, 128, 65, 53, 53, 53, 128, 65, 53, 53, + 52, 128, 65, 53, 53, 51, 128, 65, 53, 53, 50, 128, 65, 53, 53, 49, 128, + 65, 53, 53, 48, 128, 65, 53, 52, 57, 128, 65, 53, 52, 56, 128, 65, 53, + 52, 55, 128, 65, 53, 52, 53, 128, 65, 53, 52, 50, 128, 65, 53, 52, 49, + 128, 65, 53, 52, 48, 128, 65, 53, 51, 57, 128, 65, 53, 51, 56, 128, 65, + 53, 51, 55, 128, 65, 53, 51, 54, 128, 65, 53, 51, 53, 128, 65, 53, 51, + 52, 128, 65, 53, 51, 50, 128, 65, 53, 51, 49, 128, 65, 53, 51, 48, 128, + 65, 53, 50, 57, 128, 65, 53, 50, 56, 128, 65, 53, 50, 55, 128, 65, 53, + 50, 54, 128, 65, 53, 50, 53, 128, 65, 53, 50, 52, 128, 65, 53, 50, 51, + 128, 65, 53, 50, 50, 128, 65, 53, 50, 49, 128, 65, 53, 50, 48, 128, 65, + 53, 49, 57, 128, 65, 53, 49, 56, 128, 65, 53, 49, 55, 128, 65, 53, 49, + 54, 128, 65, 53, 49, 53, 128, 65, 53, 49, 52, 128, 65, 53, 49, 51, 128, + 65, 53, 49, 50, 128, 65, 53, 49, 49, 128, 65, 53, 49, 48, 128, 65, 53, + 48, 57, 128, 65, 53, 48, 56, 128, 65, 53, 48, 55, 128, 65, 53, 48, 54, + 128, 65, 53, 48, 53, 128, 65, 53, 48, 52, 128, 65, 53, 48, 51, 128, 65, + 53, 48, 50, 128, 65, 53, 48, 49, 128, 65, 52, 57, 55, 128, 65, 52, 57, + 54, 128, 65, 52, 57, 53, 128, 65, 52, 57, 52, 128, 65, 52, 57, 51, 128, + 65, 52, 57, 50, 128, 65, 52, 57, 49, 128, 65, 52, 57, 48, 128, 65, 52, + 56, 57, 128, 65, 52, 56, 56, 128, 65, 52, 56, 55, 128, 65, 52, 56, 54, + 128, 65, 52, 56, 53, 128, 65, 52, 56, 52, 128, 65, 52, 56, 51, 128, 65, + 52, 56, 50, 128, 65, 52, 56, 49, 128, 65, 52, 56, 48, 128, 65, 52, 55, + 57, 128, 65, 52, 55, 56, 128, 65, 52, 55, 55, 128, 65, 52, 55, 54, 128, + 65, 52, 55, 53, 128, 65, 52, 55, 52, 128, 65, 52, 55, 51, 128, 65, 52, + 55, 50, 128, 65, 52, 55, 49, 128, 65, 52, 55, 48, 128, 65, 52, 54, 57, + 128, 65, 52, 54, 56, 128, 65, 52, 54, 55, 128, 65, 52, 54, 54, 128, 65, + 52, 54, 53, 128, 65, 52, 54, 52, 128, 65, 52, 54, 51, 128, 65, 52, 54, + 50, 128, 65, 52, 54, 49, 128, 65, 52, 54, 48, 128, 65, 52, 53, 57, 128, + 65, 52, 53, 56, 128, 65, 52, 53, 55, 65, 128, 65, 52, 53, 55, 128, 65, + 52, 53, 54, 128, 65, 52, 53, 53, 128, 65, 52, 53, 52, 128, 65, 52, 53, + 51, 128, 65, 52, 53, 50, 128, 65, 52, 53, 49, 128, 65, 52, 53, 48, 65, + 128, 65, 52, 53, 48, 128, 65, 52, 52, 57, 128, 65, 52, 52, 56, 128, 65, + 52, 52, 55, 128, 65, 52, 52, 54, 128, 65, 52, 52, 53, 128, 65, 52, 52, + 52, 128, 65, 52, 52, 51, 128, 65, 52, 52, 50, 128, 65, 52, 52, 49, 128, + 65, 52, 52, 48, 128, 65, 52, 51, 57, 128, 65, 52, 51, 56, 128, 65, 52, + 51, 55, 128, 65, 52, 51, 54, 128, 65, 52, 51, 53, 128, 65, 52, 51, 52, + 128, 65, 52, 51, 51, 128, 65, 52, 51, 50, 128, 65, 52, 51, 49, 128, 65, + 52, 51, 48, 128, 65, 52, 50, 57, 128, 65, 52, 50, 56, 128, 65, 52, 50, + 55, 128, 65, 52, 50, 54, 128, 65, 52, 50, 53, 128, 65, 52, 50, 52, 128, + 65, 52, 50, 51, 128, 65, 52, 50, 50, 128, 65, 52, 50, 49, 128, 65, 52, + 50, 48, 128, 65, 52, 49, 57, 128, 65, 52, 49, 56, 45, 86, 65, 83, 128, + 65, 52, 49, 56, 128, 65, 52, 49, 55, 45, 86, 65, 83, 128, 65, 52, 49, 55, + 128, 65, 52, 49, 54, 45, 86, 65, 83, 128, 65, 52, 49, 54, 128, 65, 52, + 49, 53, 45, 86, 65, 83, 128, 65, 52, 49, 53, 128, 65, 52, 49, 52, 45, 86, + 65, 83, 128, 65, 52, 49, 52, 128, 65, 52, 49, 51, 45, 86, 65, 83, 128, + 65, 52, 49, 51, 128, 65, 52, 49, 50, 45, 86, 65, 83, 128, 65, 52, 49, 50, + 128, 65, 52, 49, 49, 45, 86, 65, 83, 128, 65, 52, 49, 49, 128, 65, 52, + 49, 48, 193, 65, 52, 49, 48, 45, 86, 65, 83, 128, 65, 52, 49, 176, 65, + 52, 48, 57, 45, 86, 65, 83, 128, 65, 52, 48, 57, 128, 65, 52, 48, 56, 45, + 86, 65, 83, 128, 65, 52, 48, 56, 128, 65, 52, 48, 55, 45, 86, 65, 83, + 128, 65, 52, 48, 55, 128, 65, 52, 48, 54, 45, 86, 65, 83, 128, 65, 52, + 48, 54, 128, 65, 52, 48, 53, 45, 86, 65, 83, 128, 65, 52, 48, 53, 128, + 65, 52, 48, 52, 45, 86, 65, 83, 128, 65, 52, 48, 52, 128, 65, 52, 48, 51, + 45, 86, 65, 83, 128, 65, 52, 48, 51, 128, 65, 52, 48, 50, 45, 86, 65, 83, + 128, 65, 52, 48, 50, 128, 65, 52, 48, 49, 45, 86, 65, 83, 128, 65, 52, + 48, 49, 128, 65, 52, 48, 48, 45, 86, 65, 83, 128, 65, 52, 48, 48, 128, + 65, 51, 57, 57, 128, 65, 51, 57, 56, 128, 65, 51, 57, 55, 128, 65, 51, + 57, 54, 128, 65, 51, 57, 53, 128, 65, 51, 57, 52, 128, 65, 51, 57, 179, + 65, 51, 57, 50, 128, 65, 51, 57, 49, 128, 65, 51, 57, 48, 128, 65, 51, + 56, 57, 128, 65, 51, 56, 56, 128, 65, 51, 56, 55, 128, 65, 51, 56, 54, + 65, 128, 65, 51, 56, 54, 128, 65, 51, 56, 53, 128, 65, 51, 56, 52, 128, + 65, 51, 56, 51, 65, 128, 65, 51, 56, 179, 65, 51, 56, 50, 128, 65, 51, + 56, 49, 65, 128, 65, 51, 56, 49, 128, 65, 51, 56, 48, 128, 65, 51, 55, + 57, 128, 65, 51, 55, 56, 128, 65, 51, 55, 55, 128, 65, 51, 55, 54, 128, + 65, 51, 55, 53, 128, 65, 51, 55, 52, 128, 65, 51, 55, 51, 128, 65, 51, + 55, 50, 128, 65, 51, 55, 49, 65, 128, 65, 51, 55, 49, 128, 65, 51, 55, + 48, 128, 65, 51, 54, 57, 128, 65, 51, 54, 56, 65, 128, 65, 51, 54, 56, + 128, 65, 51, 54, 55, 128, 65, 51, 54, 54, 128, 65, 51, 54, 53, 128, 65, + 51, 54, 52, 65, 128, 65, 51, 54, 52, 128, 65, 51, 54, 51, 128, 65, 51, + 54, 50, 128, 65, 51, 54, 49, 128, 65, 51, 54, 48, 128, 65, 51, 53, 57, + 65, 128, 65, 51, 53, 57, 128, 65, 51, 53, 56, 128, 65, 51, 53, 55, 128, + 65, 51, 53, 54, 128, 65, 51, 53, 53, 128, 65, 51, 53, 52, 128, 65, 51, + 53, 51, 128, 65, 51, 53, 50, 128, 65, 51, 53, 49, 128, 65, 51, 53, 48, + 128, 65, 51, 52, 57, 128, 65, 51, 52, 56, 128, 65, 51, 52, 55, 128, 65, + 51, 52, 54, 128, 65, 51, 52, 53, 128, 65, 51, 52, 52, 128, 65, 51, 52, + 51, 128, 65, 51, 52, 50, 128, 65, 51, 52, 49, 128, 65, 51, 52, 48, 128, + 65, 51, 51, 57, 128, 65, 51, 51, 56, 128, 65, 51, 51, 55, 128, 65, 51, + 51, 54, 67, 128, 65, 51, 51, 54, 66, 128, 65, 51, 51, 54, 65, 128, 65, + 51, 51, 54, 128, 65, 51, 51, 53, 128, 65, 51, 51, 52, 128, 65, 51, 51, + 51, 128, 65, 51, 51, 50, 67, 128, 65, 51, 51, 50, 66, 128, 65, 51, 51, + 50, 65, 128, 65, 51, 51, 50, 128, 65, 51, 51, 49, 128, 65, 51, 51, 48, + 128, 65, 51, 50, 57, 65, 128, 65, 51, 50, 57, 128, 65, 51, 50, 56, 128, + 65, 51, 50, 55, 128, 65, 51, 50, 54, 128, 65, 51, 50, 53, 128, 65, 51, + 50, 52, 128, 65, 51, 50, 51, 128, 65, 51, 50, 50, 128, 65, 51, 50, 49, + 128, 65, 51, 50, 48, 128, 65, 51, 49, 57, 128, 65, 51, 49, 56, 128, 65, + 51, 49, 55, 128, 65, 51, 49, 54, 128, 65, 51, 49, 53, 128, 65, 51, 49, + 52, 128, 65, 51, 49, 51, 67, 128, 65, 51, 49, 51, 66, 128, 65, 51, 49, + 51, 65, 128, 65, 51, 49, 51, 128, 65, 51, 49, 50, 128, 65, 51, 49, 49, + 128, 65, 51, 49, 48, 128, 65, 51, 48, 57, 67, 128, 65, 51, 48, 57, 66, + 128, 65, 51, 48, 57, 65, 128, 65, 51, 48, 57, 128, 65, 51, 48, 56, 128, + 65, 51, 48, 55, 128, 65, 51, 48, 54, 128, 65, 51, 48, 53, 128, 65, 51, + 48, 52, 128, 65, 51, 48, 51, 128, 65, 51, 48, 50, 128, 65, 51, 48, 49, + 128, 65, 51, 48, 48, 128, 65, 50, 57, 57, 65, 128, 65, 50, 57, 57, 128, + 65, 50, 57, 56, 128, 65, 50, 57, 55, 128, 65, 50, 57, 54, 128, 65, 50, + 57, 53, 128, 65, 50, 57, 52, 65, 128, 65, 50, 57, 52, 128, 65, 50, 57, + 51, 128, 65, 50, 57, 50, 128, 65, 50, 57, 49, 128, 65, 50, 57, 48, 128, + 65, 50, 56, 57, 65, 128, 65, 50, 56, 57, 128, 65, 50, 56, 56, 128, 65, + 50, 56, 55, 128, 65, 50, 56, 54, 128, 65, 50, 56, 53, 128, 65, 50, 56, + 52, 128, 65, 50, 56, 51, 128, 65, 50, 56, 50, 128, 65, 50, 56, 49, 128, + 65, 50, 56, 48, 128, 65, 50, 55, 57, 128, 65, 50, 55, 56, 128, 65, 50, + 55, 55, 128, 65, 50, 55, 54, 128, 65, 50, 55, 53, 128, 65, 50, 55, 52, + 128, 65, 50, 55, 51, 128, 65, 50, 55, 50, 128, 65, 50, 55, 49, 128, 65, + 50, 55, 48, 128, 65, 50, 54, 57, 128, 65, 50, 54, 56, 128, 65, 50, 54, + 55, 65, 128, 65, 50, 54, 55, 128, 65, 50, 54, 54, 128, 65, 50, 54, 53, + 128, 65, 50, 54, 52, 128, 65, 50, 54, 51, 128, 65, 50, 54, 50, 128, 65, + 50, 54, 49, 128, 65, 50, 54, 48, 128, 65, 50, 53, 57, 128, 65, 50, 53, + 56, 128, 65, 50, 53, 55, 128, 65, 50, 53, 54, 128, 65, 50, 53, 53, 128, + 65, 50, 53, 52, 128, 65, 50, 53, 51, 128, 65, 50, 53, 50, 128, 65, 50, + 53, 49, 128, 65, 50, 53, 48, 128, 65, 50, 52, 57, 128, 65, 50, 52, 56, + 128, 65, 50, 52, 55, 128, 65, 50, 52, 54, 128, 65, 50, 52, 53, 128, 65, + 50, 52, 52, 128, 65, 50, 52, 51, 128, 65, 50, 52, 50, 128, 65, 50, 52, + 49, 128, 65, 50, 52, 48, 128, 65, 50, 51, 57, 128, 65, 50, 51, 56, 128, + 65, 50, 51, 55, 128, 65, 50, 51, 54, 128, 65, 50, 51, 53, 128, 65, 50, + 51, 52, 128, 65, 50, 51, 51, 128, 65, 50, 51, 50, 128, 65, 50, 51, 49, + 128, 65, 50, 51, 48, 128, 65, 50, 50, 57, 128, 65, 50, 50, 56, 128, 65, + 50, 50, 55, 65, 128, 65, 50, 50, 55, 128, 65, 50, 50, 54, 128, 65, 50, + 50, 53, 128, 65, 50, 50, 52, 128, 65, 50, 50, 51, 128, 65, 50, 50, 50, + 128, 65, 50, 50, 49, 128, 65, 50, 50, 48, 128, 65, 50, 49, 57, 128, 65, + 50, 49, 56, 128, 65, 50, 49, 55, 128, 65, 50, 49, 54, 65, 128, 65, 50, + 49, 54, 128, 65, 50, 49, 53, 65, 128, 65, 50, 49, 53, 128, 65, 50, 49, + 52, 128, 65, 50, 49, 51, 128, 65, 50, 49, 50, 128, 65, 50, 49, 49, 128, + 65, 50, 49, 48, 128, 65, 50, 48, 57, 65, 128, 65, 50, 48, 57, 128, 65, + 50, 48, 56, 128, 65, 50, 48, 55, 65, 128, 65, 50, 48, 55, 128, 65, 50, + 48, 54, 128, 65, 50, 48, 53, 128, 65, 50, 48, 52, 128, 65, 50, 48, 51, + 128, 65, 50, 48, 50, 66, 128, 65, 50, 48, 50, 65, 128, 65, 50, 48, 50, + 128, 65, 50, 48, 49, 128, 65, 50, 48, 48, 128, 65, 49, 57, 57, 128, 65, + 49, 57, 56, 128, 65, 49, 57, 55, 128, 65, 49, 57, 54, 128, 65, 49, 57, + 53, 128, 65, 49, 57, 52, 128, 65, 49, 57, 51, 128, 65, 49, 57, 50, 128, + 65, 49, 57, 49, 128, 65, 49, 57, 48, 128, 65, 49, 56, 57, 128, 65, 49, + 56, 56, 128, 65, 49, 56, 55, 128, 65, 49, 56, 54, 128, 65, 49, 56, 53, + 128, 65, 49, 56, 52, 128, 65, 49, 56, 51, 128, 65, 49, 56, 50, 128, 65, + 49, 56, 49, 128, 65, 49, 56, 48, 128, 65, 49, 55, 57, 128, 65, 49, 55, + 56, 128, 65, 49, 55, 55, 128, 65, 49, 55, 54, 128, 65, 49, 55, 53, 128, + 65, 49, 55, 52, 128, 65, 49, 55, 51, 128, 65, 49, 55, 50, 128, 65, 49, + 55, 49, 128, 65, 49, 55, 48, 128, 65, 49, 54, 57, 128, 65, 49, 54, 56, + 128, 65, 49, 54, 55, 128, 65, 49, 54, 54, 128, 65, 49, 54, 53, 128, 65, + 49, 54, 52, 128, 65, 49, 54, 51, 128, 65, 49, 54, 50, 128, 65, 49, 54, + 49, 128, 65, 49, 54, 48, 128, 65, 49, 53, 57, 128, 65, 49, 53, 56, 128, + 65, 49, 53, 55, 128, 65, 49, 53, 54, 128, 65, 49, 53, 53, 128, 65, 49, + 53, 52, 128, 65, 49, 53, 51, 128, 65, 49, 53, 50, 128, 65, 49, 53, 49, + 128, 65, 49, 53, 48, 128, 65, 49, 52, 57, 128, 65, 49, 52, 56, 128, 65, + 49, 52, 55, 128, 65, 49, 52, 54, 128, 65, 49, 52, 53, 128, 65, 49, 52, + 52, 128, 65, 49, 52, 51, 128, 65, 49, 52, 50, 128, 65, 49, 52, 49, 128, + 65, 49, 52, 48, 128, 65, 49, 51, 57, 128, 65, 49, 51, 56, 128, 65, 49, + 51, 55, 128, 65, 49, 51, 54, 128, 65, 49, 51, 53, 65, 128, 65, 49, 51, + 53, 128, 65, 49, 51, 52, 128, 65, 49, 51, 51, 128, 65, 49, 51, 50, 128, + 65, 49, 51, 49, 67, 128, 65, 49, 51, 49, 128, 65, 49, 51, 48, 128, 65, + 49, 50, 57, 128, 65, 49, 50, 56, 128, 65, 49, 50, 55, 128, 65, 49, 50, + 54, 128, 65, 49, 50, 53, 65, 128, 65, 49, 50, 53, 128, 65, 49, 50, 52, + 128, 65, 49, 50, 51, 128, 65, 49, 50, 50, 128, 65, 49, 50, 49, 128, 65, + 49, 50, 48, 66, 128, 65, 49, 50, 48, 128, 65, 49, 49, 57, 128, 65, 49, + 49, 56, 128, 65, 49, 49, 55, 128, 65, 49, 49, 54, 128, 65, 49, 49, 53, + 65, 128, 65, 49, 49, 53, 128, 65, 49, 49, 52, 128, 65, 49, 49, 51, 128, + 65, 49, 49, 50, 128, 65, 49, 49, 49, 128, 65, 49, 49, 48, 66, 128, 65, + 49, 49, 48, 65, 128, 65, 49, 49, 48, 128, 65, 49, 48, 57, 128, 65, 49, + 48, 56, 128, 65, 49, 48, 55, 67, 128, 65, 49, 48, 55, 66, 128, 65, 49, + 48, 55, 65, 128, 65, 49, 48, 55, 128, 65, 49, 48, 54, 128, 65, 49, 48, + 53, 66, 128, 65, 49, 48, 53, 65, 128, 65, 49, 48, 53, 128, 65, 49, 48, + 52, 67, 128, 65, 49, 48, 52, 66, 128, 65, 49, 48, 52, 65, 128, 65, 49, + 48, 52, 128, 65, 49, 48, 51, 128, 65, 49, 48, 50, 65, 128, 65, 49, 48, + 50, 128, 65, 49, 48, 49, 65, 128, 65, 49, 48, 49, 128, 65, 49, 48, 48, + 65, 128, 65, 49, 48, 48, 45, 49, 48, 50, 128, 65, 49, 48, 48, 128, 65, + 48, 57, 57, 128, 65, 48, 57, 56, 65, 128, 65, 48, 57, 56, 128, 65, 48, + 57, 55, 65, 128, 65, 48, 57, 55, 128, 65, 48, 57, 54, 128, 65, 48, 57, + 53, 128, 65, 48, 57, 52, 128, 65, 48, 57, 51, 128, 65, 48, 57, 50, 128, + 65, 48, 57, 49, 128, 65, 48, 57, 48, 128, 65, 48, 56, 57, 128, 65, 48, + 56, 56, 128, 65, 48, 56, 55, 128, 65, 48, 56, 54, 128, 65, 48, 56, 53, + 128, 65, 48, 56, 52, 128, 65, 48, 56, 51, 128, 65, 48, 56, 50, 128, 65, + 48, 56, 49, 128, 65, 48, 56, 48, 128, 65, 48, 55, 57, 128, 65, 48, 55, + 56, 128, 65, 48, 55, 55, 128, 65, 48, 55, 54, 128, 65, 48, 55, 53, 128, + 65, 48, 55, 52, 128, 65, 48, 55, 51, 128, 65, 48, 55, 50, 128, 65, 48, + 55, 49, 128, 65, 48, 55, 48, 128, 65, 48, 54, 57, 128, 65, 48, 54, 56, + 128, 65, 48, 54, 55, 128, 65, 48, 54, 54, 67, 128, 65, 48, 54, 54, 66, + 128, 65, 48, 54, 54, 65, 128, 65, 48, 54, 54, 128, 65, 48, 54, 53, 128, + 65, 48, 54, 52, 128, 65, 48, 54, 51, 128, 65, 48, 54, 50, 128, 65, 48, + 54, 49, 128, 65, 48, 54, 48, 128, 65, 48, 53, 57, 128, 65, 48, 53, 56, + 128, 65, 48, 53, 55, 128, 65, 48, 53, 54, 128, 65, 48, 53, 53, 128, 65, + 48, 53, 52, 128, 65, 48, 53, 51, 128, 65, 48, 53, 50, 128, 65, 48, 53, + 49, 128, 65, 48, 53, 48, 128, 65, 48, 52, 57, 128, 65, 48, 52, 56, 128, + 65, 48, 52, 55, 128, 65, 48, 52, 54, 66, 128, 65, 48, 52, 54, 65, 128, + 65, 48, 52, 54, 128, 65, 48, 52, 53, 65, 128, 65, 48, 52, 53, 128, 65, + 48, 52, 52, 128, 65, 48, 52, 51, 65, 128, 65, 48, 52, 51, 128, 65, 48, + 52, 50, 65, 128, 65, 48, 52, 50, 128, 65, 48, 52, 49, 65, 128, 65, 48, + 52, 49, 128, 65, 48, 52, 48, 65, 128, 65, 48, 52, 48, 128, 65, 48, 51, + 57, 65, 128, 65, 48, 51, 57, 128, 65, 48, 51, 56, 128, 65, 48, 51, 55, + 128, 65, 48, 51, 54, 128, 65, 48, 51, 53, 128, 65, 48, 51, 52, 128, 65, + 48, 51, 51, 128, 65, 48, 51, 50, 65, 128, 65, 48, 50, 56, 66, 128, 65, + 48, 50, 54, 65, 128, 65, 48, 49, 55, 65, 128, 65, 48, 49, 52, 65, 128, + 65, 48, 49, 48, 65, 128, 65, 48, 48, 54, 66, 128, 65, 48, 48, 54, 65, + 128, 65, 48, 48, 53, 65, 128, 65, 45, 87, 79, 128, 65, 45, 69, 85, 128, + 45, 85, 205, 45, 80, 72, 82, 85, 128, 45, 75, 72, 89, 85, 196, 45, 75, + 72, 89, 73, 76, 128, 45, 68, 90, 85, 196, 45, 67, 72, 65, 210, 45, 67, + 72, 65, 76, 128, }; static const unsigned int lexicon_offset[] = { 0, 0, 6, 11, 15, 19, 27, 34, 44, 49, 55, 64, 66, 69, 81, 89, 102, 108, - 113, 118, 124, 129, 137, 146, 157, 160, 165, 170, 176, 180, 189, 195, - 201, 207, 216, 224, 229, 237, 177, 244, 247, 253, 254, 262, 268, 273, - 277, 282, 289, 296, 306, 311, 317, 322, 325, 331, 337, 343, 348, 351, - 359, 365, 375, 380, 385, 390, 392, 401, 408, 415, 417, 419, 427, 341, - 436, 438, 441, 449, 454, 455, 462, 464, 472, 478, 484, 491, 496, 503, - 507, 512, 519, 524, 527, 531, 537, 542, 547, 557, 565, 572, 575, 583, - 591, 600, 603, 613, 620, 625, 629, 633, 637, 642, 645, 652, 659, 666, - 671, 676, 685, 687, 696, 700, 707, 715, 719, 727, 281, 736, 749, 753, - 758, 762, 765, 767, 777, 781, 787, 791, 796, 800, 806, 811, 820, 825, - 829, 832, 838, 846, 794, 854, 863, 872, 880, 886, 891, 902, 907, 915, - 918, 925, 928, 938, 943, 949, 953, 957, 964, 967, 974, 977, 657, 980, - 983, 986, 990, 995, 1004, 1010, 1014, 1018, 1021, 1024, 1030, 1035, 1039, - 1044, 602, 1049, 1055, 1064, 1067, 1076, 1081, 1086, 1092, 1097, 1102, - 1107, 1111, 1116, 1122, 1127, 1132, 1136, 1142, 1147, 1152, 1157, 1161, - 1166, 1171, 1176, 1182, 1188, 1194, 1199, 1203, 1208, 1213, 1218, 1222, - 1227, 1232, 1237, 1242, 1077, 1082, 1087, 1093, 1098, 1246, 1108, 1252, - 1257, 1262, 1269, 1273, 1276, 1285, 1112, 1289, 1117, 1123, 1128, 1293, - 1298, 1303, 1307, 1311, 1317, 1321, 1133, 1324, 1326, 1143, 1331, 1335, - 1148, 1341, 1153, 1345, 1349, 1356, 1158, 1360, 1368, 1373, 1377, 1380, - 1384, 1162, 1167, 1389, 1395, 1172, 1407, 1413, 1419, 1425, 1177, 1189, - 1195, 1429, 1433, 1437, 1440, 1200, 1444, 1446, 1451, 1456, 1462, 1467, - 1472, 1476, 1481, 1486, 1491, 1496, 1502, 1507, 1512, 1518, 1524, 1529, - 1533, 1538, 1543, 1548, 1553, 1558, 1562, 1570, 1575, 1579, 1584, 1589, - 1594, 1599, 1603, 1606, 1613, 1618, 1623, 1628, 1633, 1639, 1644, 1648, - 1204, 1651, 1657, 1662, 1667, 1672, 1209, 1676, 1680, 1687, 1694, 1214, - 1699, 1704, 1219, 1708, 1710, 1715, 1726, 1732, 1223, 1737, 1746, 1228, - 1751, 1757, 1762, 1767, 1777, 1786, 1794, 1233, 1804, 1813, 1822, 1827, - 1831, 1834, 1843, 1853, 1862, 1867, 1871, 1875, 1879, 1882, 1886, 1891, - 1238, 1901, 1243, 1905, 1907, 1913, 1919, 1925, 1931, 1937, 1943, 1949, - 1955, 1960, 1966, 1972, 1978, 1984, 1990, 1996, 2002, 2008, 2014, 2019, - 2024, 2029, 2034, 2039, 2044, 2049, 2054, 2059, 2064, 2070, 2075, 2081, - 2086, 2092, 2098, 2103, 2109, 2115, 2121, 2127, 2132, 2137, 2139, 2140, - 2144, 2148, 2153, 2157, 2161, 2165, 2170, 2174, 2177, 2182, 2186, 2191, - 2195, 2199, 2204, 2208, 2211, 2215, 2221, 2235, 2239, 2243, 2247, 2250, - 2255, 2259, 2263, 2266, 2270, 2275, 2280, 2285, 2290, 2294, 2298, 2302, - 2306, 2310, 2315, 2319, 2324, 2328, 2333, 2339, 2346, 2352, 2357, 2362, - 2367, 2373, 2378, 2384, 2389, 2394, 2399, 2404, 2409, 2412, 2414, 1094, - 2418, 2425, 2433, 2443, 2452, 2466, 2470, 2474, 2479, 2492, 2500, 2503, - 2507, 2510, 2515, 2519, 2522, 2526, 2530, 2535, 1721, 2540, 2544, 2547, - 2551, 2557, 2564, 2571, 2577, 2582, 2587, 2593, 2599, 2604, 2609, 2614, - 2619, 2624, 2629, 2554, 2634, 1712, 2636, 2642, 2646, 2651, 2655, 2659, - 1609, 1734, 2664, 2668, 2672, 2675, 2680, 2685, 2690, 2695, 2699, 2706, - 2711, 2714, 2718, 2722, 2729, 2735, 2739, 2745, 2749, 2753, 2758, 2765, - 2770, 2775, 2782, 2788, 2794, 2800, 2821, 2835, 2852, 2867, 2883, 2900, - 2915, 2924, 2929, 2933, 2938, 2943, 2947, 2959, 2966, 2972, 2342, 2978, - 2985, 2991, 2995, 2998, 3005, 3011, 3016, 3020, 3025, 3029, 3033, 2162, - 3037, 3042, 3047, 3051, 3056, 3064, 3068, 3075, 3080, 3084, 3088, 3092, - 3097, 3102, 3107, 3111, 3116, 3121, 3125, 3130, 3135, 3139, 3142, 3146, - 3150, 3158, 3163, 3167, 3171, 3177, 3186, 3190, 3194, 3200, 3205, 3212, - 3216, 3226, 3230, 3234, 3239, 3243, 3248, 3254, 3259, 3263, 3267, 3271, - 2567, 3279, 3284, 3290, 3295, 3299, 3304, 3309, 3313, 3319, 3324, 2166, - 3330, 3336, 3341, 3346, 3351, 3356, 3361, 3366, 3371, 3376, 3381, 3386, - 3391, 3396, 3401, 3406, 3412, 3417, 1109, 101, 3423, 3427, 3431, 3435, - 3440, 3444, 3448, 3454, 3459, 3463, 3467, 3472, 3477, 3481, 3486, 3490, - 3493, 3497, 3502, 3506, 3511, 3515, 3518, 3520, 3524, 3528, 3533, 3537, - 3540, 3553, 3557, 3561, 3565, 3570, 3574, 3578, 3581, 3585, 3589, 3594, - 3598, 3603, 3608, 3613, 3617, 3624, 3629, 3632, 3638, 3641, 3646, 3652, - 3656, 3660, 3663, 3668, 3672, 3677, 3681, 3685, 3688, 3694, 3699, 3704, - 3710, 3715, 3720, 3726, 3732, 3737, 3742, 3747, 3752, 3755, 988, 644, - 3761, 3764, 3769, 3773, 3777, 3781, 3785, 3788, 3792, 3797, 3802, 3806, - 3811, 3815, 3820, 3824, 3828, 3832, 3838, 3844, 3847, 3850, 150, 3856, - 3861, 3870, 3878, 3887, 3897, 3904, 3910, 3917, 3922, 3926, 3930, 3938, - 3945, 3950, 3955, 3962, 3967, 3971, 3981, 3985, 3989, 3994, 3999, 4009, - 2178, 4014, 4018, 4021, 4027, 4032, 4038, 4044, 4049, 4056, 4060, 4064, - 4068, 4073, 4078, 4083, 4088, 4093, 4098, 634, 601, 1270, 4103, 4110, - 4117, 4123, 4128, 4135, 4142, 4147, 4153, 4159, 4164, 4168, 4174, 4181, - 4186, 4190, 4194, 2187, 4200, 4208, 4214, 4222, 858, 4228, 4236, 4247, - 4251, 4261, 4267, 4272, 4277, 4282, 4287, 2192, 4292, 4297, 4312, 4318, - 4325, 4336, 4346, 4352, 4357, 4363, 4369, 4372, 4375, 4379, 4384, 4387, - 4394, 4403, 4408, 4412, 4416, 4420, 4424, 4429, 4435, 4446, 4450, 3498, - 4455, 4467, 4473, 4481, 4485, 4490, 4497, 4502, 4507, 4512, 1478, 4517, - 4520, 4523, 4527, 4530, 4536, 4540, 4554, 4558, 4561, 4565, 4571, 4577, - 4582, 4586, 4590, 4596, 4607, 4613, 4618, 4624, 4628, 4636, 4648, 4658, - 4664, 4669, 4678, 4686, 4697, 4704, 4710, 4716, 4720, 4726, 4735, 4744, - 4749, 4755, 4759, 4768, 4773, 4777, 4782, 4786, 4794, 4800, 4804, 4811, - 4816, 4820, 4826, 4832, 4839, 2200, 4848, 4859, 4869, 4878, 4883, 4888, - 4893, 4898, 1286, 4903, 4905, 4910, 4916, 4921, 4926, 4931, 4936, 4941, - 4946, 4952, 4957, 4963, 4968, 4973, 4978, 4984, 4989, 4994, 4999, 5004, - 5010, 5015, 5021, 5026, 5031, 5036, 5041, 5046, 5051, 5057, 5062, 5067, - 335, 384, 5072, 5078, 5081, 5085, 5089, 5096, 5102, 5107, 5111, 5115, - 5118, 5121, 5125, 5129, 5132, 5136, 5140, 5144, 5149, 5153, 5157, 5163, - 5172, 4829, 5177, 5181, 5184, 5189, 5194, 5199, 5204, 5209, 5214, 5219, - 5224, 5229, 5234, 5238, 5243, 5248, 5253, 5258, 5263, 5268, 5273, 5278, - 5283, 5288, 5292, 5297, 5302, 5307, 5312, 5317, 5322, 5327, 5332, 5337, - 5342, 5346, 5351, 5356, 5361, 5366, 5371, 5376, 5381, 5386, 5391, 5396, - 5400, 5405, 5410, 5415, 5420, 5425, 5430, 5435, 5440, 5445, 5450, 5454, - 5459, 5464, 5469, 5474, 5479, 5484, 5489, 5494, 5499, 5504, 5508, 5513, - 5518, 5523, 5528, 5533, 5538, 5543, 5548, 5553, 5558, 5562, 5567, 5572, - 5577, 5582, 5588, 5594, 5600, 5606, 5612, 5618, 5624, 5629, 5635, 5641, - 5647, 5653, 5659, 5665, 5671, 5677, 5683, 5689, 5694, 5700, 5706, 5712, - 5718, 5724, 5730, 5736, 5742, 5748, 5754, 5759, 5765, 5771, 5777, 5783, - 5789, 5795, 5801, 5807, 5813, 5819, 5824, 5830, 5836, 5842, 5848, 5854, - 5860, 5866, 5872, 5878, 5884, 5889, 5895, 5901, 5907, 5913, 5919, 5925, - 5931, 5937, 5943, 5949, 5954, 5958, 5964, 5970, 5976, 5982, 5988, 5994, - 6000, 6006, 6012, 6018, 6023, 6029, 6035, 6041, 6047, 6053, 6059, 6065, - 6071, 6077, 6083, 6088, 6094, 6100, 6106, 6112, 6118, 6124, 6130, 6136, - 6142, 6148, 6153, 6159, 6165, 6171, 6177, 6183, 6189, 6195, 6201, 6207, - 6213, 6218, 6224, 6230, 6236, 6242, 6248, 6254, 6260, 6266, 6272, 6278, - 6283, 6289, 6295, 6301, 6307, 6313, 6319, 6325, 6331, 6337, 6343, 6348, - 6354, 6360, 6366, 6372, 6378, 6384, 6390, 6396, 6402, 6408, 6413, 6419, - 6425, 6431, 6437, 6443, 6449, 6455, 6461, 6467, 6473, 6478, 6484, 6490, - 6496, 6502, 6508, 6514, 6520, 6526, 6532, 6538, 6543, 6549, 6555, 6561, - 6567, 6573, 6579, 6585, 6591, 6597, 6603, 6608, 6612, 6615, 6623, 6630, - 6633, 6637, 6650, 6654, 6658, 6662, 6665, 6669, 6674, 6678, 6687, 6691, - 6697, 6704, 6715, 6723, 6730, 6736, 6740, 6748, 6757, 6763, 6767, 6779, - 6784, 6787, 6792, 6796, 6806, 6814, 6822, 6830, 6836, 6840, 6850, 6860, - 6868, 6875, 6882, 6888, 6894, 6901, 6905, 6912, 6922, 6932, 6940, 6947, - 6952, 6956, 6960, 6968, 6972, 6982, 6987, 6994, 7001, 7009, 7019, 7024, - 7028, 7033, 7037, 7044, 7049, 7063, 7068, 7073, 7080, 3774, 7089, 7093, - 7097, 7102, 7106, 7110, 7113, 7118, 7123, 7132, 7138, 7144, 7149, 7155, - 7159, 7170, 7180, 7195, 7210, 7225, 7240, 7255, 7270, 7285, 7300, 7315, - 7330, 7345, 7360, 7375, 7390, 7405, 7420, 7435, 7450, 7465, 7480, 7495, - 7510, 7525, 7540, 7555, 7570, 7585, 7600, 7615, 7630, 7645, 7660, 7675, - 7690, 7705, 7720, 7735, 7750, 7765, 7780, 7795, 7810, 7825, 7840, 7855, - 7870, 7885, 7900, 7915, 7924, 7933, 7938, 7944, 7954, 7958, 7962, 7967, - 7972, 7977, 7985, 7989, 7992, 7996, 3221, 7999, 8004, 340, 545, 8010, - 8013, 8021, 8025, 8029, 8032, 8036, 8042, 8046, 8054, 8060, 8065, 8072, - 8080, 8087, 8093, 8098, 8105, 8111, 8120, 8128, 8132, 8137, 8145, 8157, - 8168, 8175, 8186, 8190, 8194, 8198, 8201, 8207, 3525, 8211, 8213, 8219, - 8224, 8229, 8234, 8240, 8245, 8250, 8255, 8260, 8266, 8271, 8276, 8282, - 8287, 8293, 8298, 8304, 8309, 8315, 8320, 8325, 8330, 8335, 8340, 8346, - 8351, 8356, 8361, 8367, 8373, 8379, 8385, 8391, 8397, 8403, 8409, 8415, - 8421, 8427, 8433, 8438, 8443, 8448, 8453, 8458, 8463, 8468, 8473, 8479, - 8485, 8490, 8496, 8502, 8508, 8513, 8518, 8523, 8528, 8534, 8540, 8545, - 8550, 8555, 8560, 8565, 8571, 8576, 8582, 8588, 8594, 8600, 8606, 8612, - 8618, 8624, 8630, 2209, 8031, 8635, 8639, 8647, 8651, 8654, 8657, 8663, - 8670, 1113, 8673, 8677, 8685, 8690, 8695, 8686, 8700, 2236, 8704, 8710, - 8716, 8721, 8726, 8733, 8741, 8746, 8750, 8753, 8757, 8763, 8769, 8773, - 1659, 627, 8776, 8780, 8785, 8791, 8796, 8800, 8803, 8807, 8813, 8818, - 8822, 8829, 8833, 8837, 8841, 793, 8661, 2260, 8844, 8852, 8859, 8866, - 8872, 8879, 8887, 8894, 8905, 8912, 8918, 8930, 1129, 1294, 1299, 8941, - 8945, 1304, 8949, 8953, 8962, 8970, 8974, 8983, 8989, 8995, 9000, 9004, - 9010, 9015, 9023, 9030, 2920, 9037, 9043, 9047, 9056, 9065, 9074, 9083, - 9089, 9094, 9099, 9110, 9119, 9131, 9136, 9144, 2295, 9148, 9150, 9155, - 9159, 9168, 9176, 1308, 168, 3816, 3821, 9182, 9186, 9195, 9201, 9206, - 9209, 9213, 9217, 9222, 9227, 9232, 9237, 9241, 9250, 9256, 2307, 9260, - 2912, 9264, 9272, 9276, 9280, 2311, 9284, 9288, 9292, 9296, 9300, 2316, - 9304, 9309, 9316, 9322, 9329, 9335, 9338, 9234, 9340, 9348, 9356, 9364, - 9367, 9372, 2329, 9377, 8697, 9380, 9382, 9387, 9392, 9397, 9402, 9407, - 9412, 9417, 9422, 9427, 9432, 9438, 9443, 9448, 9453, 9459, 9464, 9469, - 9474, 9479, 9484, 9489, 9495, 9500, 9505, 9510, 9515, 9520, 9525, 9530, - 9535, 9540, 9545, 9550, 9555, 9560, 9565, 9570, 9575, 9580, 9586, 9592, - 9597, 9602, 9607, 9612, 9617, 2340, 2347, 2353, 9622, 9630, 9636, 9644, - 2379, 2385, 9652, 2390, 2395, 2400, 2405, 9656, 9660, 9665, 9669, 9673, - 9677, 9682, 9686, 9691, 9695, 9698, 9701, 9707, 9714, 9720, 9727, 9733, - 9740, 9746, 9753, 9759, 9765, 9774, 9780, 9784, 9788, 9792, 9796, 9801, - 9805, 9810, 9814, 9820, 9824, 9829, 9836, 9847, 9855, 9865, 9871, 9881, - 9890, 9897, 9902, 9906, 9917, 9927, 9940, 9951, 9964, 9975, 9987, 9999, - 10011, 10022, 10035, 10048, 10055, 10061, 10072, 10082, 10096, 10103, - 10109, 10118, 10126, 10130, 10135, 10139, 10146, 10154, 10161, 10165, - 10171, 10175, 10181, 10191, 10195, 10200, 10205, 10212, 10218, 8874, - 10228, 10232, 10239, 10245, 10252, 10259, 10263, 10266, 10272, 10276, - 10281, 10286, 10291, 10295, 10301, 10309, 10316, 10322, 10326, 10329, - 10335, 10345, 10349, 10355, 10360, 10364, 10369, 10373, 10379, 10385, - 10390, 10396, 10401, 10406, 10411, 2232, 10416, 10418, 10423, 10431, - 10440, 10444, 10450, 10455, 10460, 10465, 10470, 10476, 10481, 10486, - 4592, 10491, 10496, 10500, 10506, 10511, 10517, 10522, 10527, 10533, - 10538, 10445, 10544, 10548, 10555, 10561, 10566, 10570, 7059, 10575, - 10584, 10589, 10594, 9312, 9319, 10599, 3094, 10603, 10608, 10613, 10618, - 10456, 10622, 10627, 10632, 10461, 10636, 10466, 10641, 10648, 10655, - 10661, 10668, 10674, 10680, 10685, 10692, 10697, 10702, 10707, 10713, - 10471, 10477, 10719, 10724, 10730, 10735, 10740, 10748, 1364, 10753, - 1037, 10756, 10764, 10780, 10796, 10811, 10819, 10825, 10831, 10840, - 10848, 10856, 10864, 10872, 10880, 10888, 10896, 10904, 10913, 10922, - 10930, 10939, 10948, 10957, 10966, 10975, 10984, 10993, 11002, 11011, - 11020, 11028, 11033, 11037, 11043, 11051, 11058, 11073, 11090, 11109, - 11118, 11126, 11141, 11152, 11160, 11166, 11176, 11186, 11194, 11200, - 11212, 11221, 11229, 11236, 11243, 11250, 11256, 11261, 11271, 11277, - 11285, 11295, 11302, 11312, 11322, 11332, 11340, 11347, 11356, 11366, - 11380, 11395, 11404, 11412, 11417, 11421, 11431, 11441, 11453, 11462, - 11468, 11473, 11483, 11493, 11503, 11508, 11512, 11522, 11531, 11536, - 11552, 11569, 11579, 11584, 11595, 11608, 11619, 11627, 11640, 11652, - 11660, 11665, 11669, 11675, 11680, 11688, 11696, 11703, 11714, 11719, - 11727, 11737, 11743, 11747, 11750, 11754, 11760, 11767, 11771, 11779, - 11788, 11796, 11803, 11808, 11812, 11817, 11821, 11825, 11833, 11848, - 11864, 11870, 11878, 11887, 11895, 11901, 11905, 11912, 11923, 11927, - 11930, 11941, 11947, 11952, 10487, 11960, 11966, 11973, 11979, 11984, - 11991, 11998, 12005, 12012, 12019, 12026, 12033, 12040, 12047, 12054, - 12061, 12068, 12075, 12082, 12089, 12094, 11086, 12099, 12105, 12112, - 12119, 12124, 12131, 12140, 12144, 12151, 12163, 12167, 12173, 12178, - 12183, 12188, 12193, 12198, 12203, 12206, 12210, 11437, 12214, 12218, - 12224, 12230, 12235, 12241, 12246, 12251, 12257, 12262, 12267, 10208, - 12272, 12276, 12280, 12284, 12289, 12294, 12299, 12307, 12313, 12318, - 12322, 12326, 12333, 12338, 12346, 12353, 12358, 12362, 12365, 12371, - 12378, 12382, 12385, 12390, 12394, 4631, 12400, 12409, 46, 12417, 12423, - 12428, 12433, 12441, 12448, 12453, 6977, 12459, 12465, 12470, 12474, - 12477, 12483, 12491, 12498, 12513, 12532, 12544, 12557, 12570, 12583, - 12597, 12610, 12625, 12632, 10492, 12638, 12652, 12657, 12663, 12668, - 12676, 12681, 9052, 12686, 12689, 12697, 12704, 12709, 12713, 12719, - 12723, 12728, 12733, 12738, 12743, 12748, 12753, 3099, 11174, 12758, - 12762, 12768, 12774, 12779, 12785, 12790, 10501, 12796, 12802, 12807, - 12812, 12820, 12826, 12839, 12847, 12854, 12860, 10507, 12866, 12874, - 12882, 12889, 12902, 12915, 12927, 12937, 12949, 12977, 12985, 12994, - 13001, 13013, 13020, 13030, 13039, 13047, 13054, 13059, 13065, 10512, - 13070, 13076, 13081, 13086, 13091, 10518, 13096, 13099, 13106, 13112, - 13126, 13139, 13150, 9840, 13161, 13167, 13176, 13184, 13191, 13197, - 13208, 13214, 13219, 13227, 4119, 13233, 13238, 12505, 13244, 13251, - 13256, 10523, 13262, 13267, 13274, 13280, 13286, 13291, 13299, 13307, - 13314, 13318, 13330, 13344, 13354, 13359, 13363, 13374, 13380, 13385, - 13390, 10528, 13394, 10534, 13399, 13402, 13407, 13419, 13426, 13431, - 13435, 13443, 13448, 13452, 13457, 13461, 13468, 13474, 10539, 10446, - 13481, 3104, 17, 13488, 13493, 13497, 13501, 13507, 13515, 13525, 13530, - 13535, 13542, 13549, 13553, 13564, 13574, 13583, 13592, 13604, 13609, - 13613, 13621, 13635, 13639, 13642, 13646, 13654, 13661, 13669, 13673, - 13684, 13692, 13696, 13703, 13708, 13712, 13718, 13723, 13729, 13734, - 13739, 13743, 13749, 13754, 13765, 13769, 13772, 13778, 13785, 13791, - 13796, 13802, 13808, 13815, 13826, 13836, 13846, 13855, 13862, 13871, - 13875, 10549, 10556, 10562, 10567, 13881, 13887, 13893, 13898, 13904, - 10571, 13910, 13913, 13920, 13925, 13931, 13936, 13951, 13967, 13982, - 13990, 13995, 14002, 14008, 14012, 14017, 14022, 14027, 14032, 14037, - 14042, 14047, 14052, 14057, 1567, 388, 14062, 14070, 14077, 14083, 14088, - 14093, 10576, 14095, 14099, 14104, 14108, 14118, 14123, 14127, 14130, - 14139, 14143, 14146, 14153, 10585, 14158, 14161, 14169, 14176, 14184, - 14188, 14194, 14202, 14206, 14213, 14222, 14229, 14225, 14236, 14240, - 14246, 14250, 14254, 14258, 14264, 14270, 14280, 14288, 14295, 14299, - 14307, 14312, 14316, 14323, 14328, 14335, 14339, 14344, 14349, 14353, - 14360, 14366, 14374, 14380, 14385, 14395, 14402, 14407, 14412, 14416, - 14420, 14428, 4461, 14436, 14441, 10590, 14445, 14452, 14456, 14459, - 14467, 14474, 14478, 14481, 6832, 14485, 14490, 14495, 14499, 14510, - 14520, 14525, 14531, 14536, 14545, 14549, 14552, 14560, 14565, 14570, - 14577, 14582, 4851, 10595, 14587, 14591, 14598, 14603, 14608, 14613, - 1664, 7007, 14618, 14623, 14628, 14633, 14639, 14644, 14650, 14655, - 14660, 14665, 14670, 14675, 14680, 14685, 14690, 14695, 14700, 14705, - 14710, 14715, 14720, 14725, 14730, 14736, 14741, 14746, 14751, 14756, - 14761, 14767, 14772, 14777, 14783, 14788, 14794, 14799, 14805, 14810, - 14815, 14820, 14825, 14831, 14836, 14841, 14846, 14854, 1008, 112, 14860, - 14864, 14869, 14874, 14878, 14882, 14886, 14891, 14895, 14900, 14904, - 14907, 14911, 14915, 14921, 14926, 14936, 14942, 14950, 14956, 14960, - 14964, 14971, 14979, 14988, 14999, 15009, 15016, 15023, 15027, 15036, - 15045, 15053, 15060, 15069, 15078, 15087, 15096, 15106, 15116, 15126, - 15136, 15146, 15155, 15165, 15175, 15185, 15195, 15205, 15215, 15225, - 15234, 15244, 15254, 15264, 15274, 15284, 15294, 15303, 15313, 15323, - 15333, 15343, 15353, 15363, 15373, 15383, 15393, 15402, 15412, 15422, - 15432, 15442, 15452, 15462, 15472, 15482, 15492, 15502, 15511, 15517, - 1138, 15521, 15524, 15528, 15533, 15540, 15546, 15551, 15555, 15560, - 15569, 15578, 15586, 15591, 15595, 15599, 15605, 15610, 15616, 10604, - 15621, 15626, 15635, 15640, 10614, 15645, 11424, 11434, 11444, 15648, - 15654, 15662, 10619, 15669, 15673, 15677, 15682, 15686, 15696, 15702, - 15708, 15713, 15722, 15730, 15737, 15744, 15749, 15756, 15761, 15765, - 15768, 15779, 15789, 15802, 15811, 15819, 15830, 15842, 15852, 15862, - 15867, 15871, 15876, 15881, 15885, 15891, 15899, 15906, 15917, 15922, - 15932, 15941, 15945, 15948, 15955, 15965, 15974, 15981, 15985, 15992, - 15998, 16003, 16008, 16012, 15564, 16021, 16025, 16031, 16035, 16040, - 16044, 16051, 16058, 16062, 16071, 16079, 16087, 16094, 16102, 16114, - 16125, 16135, 16142, 16148, 16157, 16168, 16177, 16189, 16201, 16213, - 16223, 16232, 16242, 16251, 16259, 16266, 16276, 16285, 16293, 16297, - 16302, 16308, 16314, 16319, 16324, 16328, 16333, 16338, 16343, 16348, - 16353, 16358, 16363, 8718, 16368, 16370, 16374, 16379, 16385, 16392, - 16398, 16404, 16413, 16417, 16423, 16431, 16438, 16447, 16456, 16465, - 16474, 16483, 16492, 16501, 16510, 16520, 16530, 16539, 16545, 16552, - 16559, 16565, 16579, 16585, 16592, 16600, 16609, 16617, 16623, 16632, - 16638, 16647, 16658, 16664, 16674, 16682, 16689, 16697, 16705, 16712, - 16721, 16734, 16743, 16751, 16758, 16771, 16777, 16783, 16793, 16802, - 16811, 16820, 16828, 16833, 16837, 16843, 16849, 16854, 16861, 16868, - 10222, 16873, 16878, 16885, 16893, 16898, 16910, 16917, 16922, 16934, - 14917, 16939, 16945, 16953, 16959, 16964, 16972, 16980, 16987, 16995, - 17002, 17008, 17014, 17022, 17030, 17036, 17044, 17050, 17055, 17061, - 17068, 17074, 17079, 17083, 17094, 17102, 17110, 17116, 17121, 17128, - 17137, 17143, 17148, 17156, 17163, 17172, 17186, 4405, 17190, 17195, - 17200, 17206, 17211, 17216, 17220, 17225, 17230, 17235, 8717, 17240, - 17245, 17250, 17255, 17260, 17264, 17269, 17274, 17279, 17284, 17290, - 17296, 14190, 17301, 17307, 17312, 17317, 17322, 10623, 17327, 17332, - 17337, 17342, 17347, 17361, 17378, 17396, 17408, 17421, 17438, 17454, - 17471, 17481, 17500, 17511, 17522, 17533, 2809, 17544, 17555, 17566, - 17583, 17594, 17605, 17610, 10628, 17615, 17619, 2489, 17623, 17629, - 17632, 17638, 17646, 17654, 17660, 17669, 17676, 17681, 17689, 17697, - 17704, 17708, 17713, 17719, 17726, 17734, 17741, 17753, 17760, 17766, - 17774, 17779, 17785, 17791, 17796, 13945, 17803, 17807, 17816, 17822, - 17827, 17835, 17844, 17852, 17859, 17865, 17873, 17880, 17886, 17892, - 17899, 17906, 17912, 17918, 17922, 17931, 17939, 17944, 17954, 17961, - 17967, 17975, 17981, 17989, 17997, 18004, 18017, 18021, 18028, 18037, - 18046, 18055, 18063, 18073, 18080, 18085, 3975, 18092, 18097, 1254, - 18101, 18108, 17241, 18112, 18118, 18122, 18130, 18142, 18147, 18154, - 18160, 18165, 18172, 17246, 18176, 18180, 18188, 18193, 18197, 17251, - 18201, 17256, 18205, 18212, 18217, 18221, 18228, 18232, 18235, 18243, - 18250, 18255, 18263, 18267, 18274, 18291, 18300, 18309, 18313, 18316, - 18322, 18330, 18336, 18341, 18345, 18350, 18355, 18360, 18365, 18370, - 18375, 4053, 18380, 18382, 18390, 18397, 18407, 18419, 18424, 18428, - 18434, 18439, 18447, 18451, 18457, 18462, 18468, 18471, 18478, 18486, - 18493, 18499, 18504, 18510, 18515, 18522, 18528, 18533, 18543, 18552, - 18559, 18564, 18568, 18574, 18580, 18584, 18591, 18597, 18602, 18608, - 18616, 18624, 18631, 18637, 18643, 18648, 18654, 18660, 18668, 18673, - 18678, 18686, 18692, 18698, 18703, 18710, 18715, 18719, 18725, 18731, - 18736, 18742, 18749, 18754, 18760, 18763, 18769, 18780, 18786, 18795, - 18798, 18802, 18806, 18820, 18833, 18845, 18851, 18856, 18863, 18869, - 18875, 18886, 18898, 18910, 18920, 18929, 18937, 18944, 18955, 18965, - 18975, 18983, 18986, 17270, 18991, 18996, 19003, 17275, 17426, 19011, - 19024, 19039, 19050, 17443, 19068, 19081, 19094, 19105, 12520, 19116, - 19129, 19148, 19159, 19170, 19181, 2830, 19194, 19198, 19206, 19217, - 19228, 19236, 19251, 19266, 19277, 19284, 19290, 19298, 19302, 19308, - 19312, 19315, 19328, 19340, 19350, 19358, 19365, 19373, 19383, 19388, - 19395, 19400, 19407, 19418, 19428, 19434, 19439, 19444, 17280, 19448, - 19454, 19461, 19467, 19472, 19477, 19482, 19486, 17285, 17291, 19490, - 17297, 19495, 19503, 19508, 19512, 19519, 19527, 19534, 19543, 19550, - 19554, 19558, 19563, 19568, 19573, 19578, 19583, 10467, 19588, 19590, - 19595, 19600, 19606, 19611, 19616, 19621, 19626, 19630, 19636, 19642, - 19647, 19653, 19658, 19663, 19667, 19673, 19678, 19682, 19687, 19692, - 19704, 19709, 19715, 19720, 19725, 19731, 19737, 19742, 19747, 19752, - 19759, 19765, 19776, 19783, 19792, 19797, 19801, 279, 19805, 19813, - 19818, 19824, 19830, 19835, 19842, 19849, 19855, 19860, 19866, 19871, - 19876, 19881, 19888, 19898, 19906, 19911, 19916, 19923, 19929, 19938, - 19948, 19958, 19972, 19986, 20000, 20014, 20029, 20044, 20061, 20079, - 20092, 20098, 20103, 20108, 20112, 20120, 20125, 20133, 20139, 20145, - 20150, 20155, 20159, 20165, 20170, 20174, 20181, 20186, 20190, 20201, - 20207, 20212, 20217, 20224, 20229, 20233, 3933, 20238, 20244, 20251, - 17302, 20257, 20261, 20267, 20272, 20277, 20281, 20287, 20292, 20297, - 20304, 20309, 15698, 20313, 20318, 20322, 20327, 20333, 20339, 20346, - 20356, 20364, 20371, 20376, 20380, 20389, 20397, 20404, 20411, 20417, - 20422, 20428, 20433, 20438, 20444, 20449, 20455, 20460, 20466, 20472, - 20479, 20485, 20490, 20495, 10693, 20504, 20507, 20515, 20521, 20526, - 20531, 20541, 20548, 20554, 20559, 20564, 20570, 20575, 20581, 20586, - 20592, 20599, 20605, 20611, 20616, 20624, 20631, 20636, 20641, 20647, - 20652, 20656, 20665, 20676, 20683, 20690, 20698, 20705, 20712, 20717, - 20722, 20728, 20733, 20741, 20747, 20753, 20758, 20765, 20771, 20776, - 20780, 20786, 20791, 20796, 20800, 20805, 1327, 8742, 3118, 20809, 20813, - 20817, 20821, 20825, 20829, 20832, 20837, 20844, 20852, 20862, 20873, - 20883, 20894, 20906, 20917, 20927, 20938, 20950, 20961, 20973, 20986, - 20998, 21009, 21019, 21030, 21042, 21053, 21066, 21078, 21089, 21101, - 21114, 21126, 21139, 21153, 21166, 21178, 21189, 21199, 21210, 21222, - 21233, 21245, 21258, 21270, 21281, 21293, 21306, 21319, 21333, 21346, - 21358, 21369, 21381, 21394, 21406, 21419, 21433, 21446, 21458, 21471, - 21485, 21498, 21512, 21526, 21539, 21551, 21562, 21572, 17313, 21579, - 21585, 21595, 21603, 21610, 21618, 21628, 21637, 21650, 21655, 21660, - 21668, 21675, 15807, 15816, 21682, 21692, 21707, 21713, 21720, 21727, - 21734, 21740, 21746, 21757, 21765, 21773, 21783, 21793, 21802, 17318, - 21811, 21817, 21823, 21832, 21840, 21848, 21853, 21862, 21870, 21882, - 21892, 21902, 21912, 21921, 21933, 21943, 21953, 21964, 21971, 21976, - 21983, 21995, 22007, 22019, 22031, 22043, 22055, 22067, 22079, 22091, - 22103, 22114, 22126, 22138, 22150, 22162, 22174, 22186, 22198, 22210, - 22222, 22234, 22245, 22257, 22269, 22281, 22293, 22305, 22317, 22329, - 22341, 22353, 22365, 22376, 22388, 22400, 22412, 22424, 22436, 22448, - 22460, 22472, 22484, 22496, 22507, 22519, 22531, 22543, 22555, 22567, - 22579, 22591, 22603, 22615, 22627, 22638, 22650, 22662, 22674, 22686, - 22698, 22710, 22722, 22734, 22746, 22758, 22769, 22781, 22793, 22805, - 22817, 22829, 22841, 22853, 22865, 22877, 22889, 22900, 22912, 22924, - 22936, 22948, 22961, 22974, 22987, 23000, 23013, 23026, 23039, 23051, - 23064, 23077, 23090, 23103, 23116, 23129, 23142, 23155, 23168, 23181, - 23193, 23206, 23219, 23232, 23245, 23258, 23271, 23284, 23297, 23310, - 23323, 23335, 23348, 23361, 23374, 23387, 23400, 23413, 23426, 23439, - 23452, 23465, 23477, 23490, 23503, 23516, 23529, 23542, 23555, 23568, - 23581, 23594, 23607, 23619, 23632, 23645, 23658, 23671, 23684, 23697, - 23710, 23723, 23736, 23749, 23761, 23772, 23785, 23798, 23811, 23824, - 23837, 23850, 23863, 23876, 23889, 23902, 23914, 23927, 23940, 23953, - 23966, 23979, 23992, 24005, 24018, 24031, 24044, 24056, 24069, 24082, - 24095, 24108, 24121, 24134, 24147, 24160, 24173, 24186, 24198, 24211, - 24224, 24237, 24250, 24263, 24276, 24289, 24302, 24315, 24328, 24340, - 24353, 24366, 24379, 24392, 24405, 24418, 24431, 24444, 24457, 24470, - 24482, 24495, 24508, 24521, 24534, 24547, 24560, 24573, 24586, 24599, - 24612, 24624, 24637, 24650, 24663, 24676, 24689, 24702, 24715, 24728, - 24741, 24754, 24766, 24779, 24792, 24805, 24818, 24831, 24844, 24857, - 24870, 24883, 24896, 24908, 24921, 24934, 24947, 24960, 24973, 24986, - 24999, 25012, 25025, 25038, 25050, 25063, 25076, 25089, 25102, 25115, - 25128, 25141, 25154, 25167, 25180, 25192, 25203, 25212, 25220, 25228, - 25235, 25241, 25245, 25251, 25257, 25266, 25274, 25279, 25285, 25290, - 25294, 25303, 10472, 25314, 25320, 25327, 25335, 25342, 13119, 13133, - 25349, 25356, 25365, 25370, 25375, 25382, 25387, 25392, 8758, 8764, 8770, - 25397, 25402, 25405, 25410, 25418, 25425, 25432, 25444, 25451, 25457, - 25466, 25471, 25480, 25489, 25495, 25503, 25512, 25516, 25522, 25527, - 25537, 25544, 25550, 25558, 25564, 25571, 25577, 25587, 25596, 25600, - 25607, 25611, 25616, 25622, 25630, 25634, 25644, 17328, 25653, 25659, - 25663, 25672, 25681, 25691, 25697, 17333, 25704, 25711, 25722, 25730, - 25740, 25749, 25757, 10187, 25765, 25770, 25776, 25781, 25785, 25789, - 25793, 11281, 25798, 25806, 25813, 25822, 25830, 25837, 25844, 25853, - 25859, 1059, 25866, 25872, 25876, 25882, 25889, 25895, 25903, 25909, - 25916, 25922, 25928, 25937, 25941, 25949, 25957, 25964, 25973, 25980, - 25985, 25989, 25999, 26010, 26021, 26026, 26031, 26037, 26046, 26051, - 26064, 8980, 26068, 26074, 26080, 26086, 26091, 26099, 26103, 26110, - 26119, 26124, 17606, 26132, 26136, 26148, 26153, 26157, 26160, 26166, - 26172, 26178, 26183, 26188, 26192, 26195, 26206, 26211, 10749, 26218, - 26223, 26228, 26233, 26238, 26243, 26248, 26253, 26258, 10754, 26263, - 26268, 26273, 26278, 26283, 26288, 26293, 26298, 26303, 26308, 26313, - 26318, 26324, 26329, 26334, 26339, 26344, 26349, 26354, 26359, 26364, - 26369, 26375, 26381, 26386, 26391, 26396, 26401, 26406, 26411, 26416, - 26421, 26426, 26432, 26437, 26442, 26447, 26453, 26459, 26464, 26469, - 26474, 26479, 26484, 26489, 26494, 26499, 26505, 26510, 26515, 26520, - 26525, 26531, 26536, 26541, 26545, 1250, 145, 26553, 26557, 26561, 26565, - 26570, 26574, 15704, 2415, 26578, 26583, 26587, 26592, 26596, 26601, - 26605, 26611, 26616, 26620, 26624, 26632, 26636, 26640, 26647, 26652, - 26657, 26661, 26667, 26672, 26676, 26681, 26686, 26690, 26697, 26704, - 26711, 26716, 26720, 26724, 26729, 26733, 26736, 26742, 26755, 26760, - 26766, 26775, 26780, 11029, 26785, 26794, 26799, 26802, 26806, 26811, - 26816, 26821, 26826, 26831, 2926, 2931, 26836, 26842, 26846, 26852, 3894, - 26857, 26862, 26867, 26873, 26878, 16654, 26883, 26888, 26893, 26898, - 26904, 26909, 26914, 26920, 26925, 26929, 26934, 26939, 26944, 26949, - 26954, 26958, 26963, 26967, 26972, 26977, 26982, 26987, 26991, 26996, - 27000, 27005, 27010, 27015, 26930, 3127, 26935, 27020, 27028, 27035, - 11375, 27047, 27055, 27065, 27083, 27102, 27111, 27119, 26940, 27126, - 27131, 27139, 26945, 27144, 27149, 27157, 27162, 27167, 27171, 19826, - 27176, 27184, 27189, 27193, 27200, 27206, 27215, 27219, 27227, 27233, - 27237, 27240, 20660, 27247, 27251, 27255, 27260, 27266, 27273, 27278, - 10214, 27282, 27287, 27292, 27297, 27302, 27307, 1669, 1674, 27312, - 27318, 27324, 27329, 27333, 27337, 27341, 27345, 27349, 27353, 27357, - 27361, 25438, 27364, 27371, 27379, 27385, 27391, 27396, 27401, 27407, - 27411, 27416, 27423, 16554, 16561, 27429, 27441, 27444, 27451, 27455, - 19851, 27462, 27470, 27481, 27490, 27503, 27513, 27527, 27539, 27553, - 27566, 27578, 27588, 27600, 27606, 27621, 27645, 27663, 27682, 27695, - 27709, 27727, 27743, 27760, 27778, 27789, 27808, 27825, 27845, 27863, - 27875, 27889, 27903, 27915, 27932, 27951, 27969, 27981, 27999, 28018, - 17486, 28031, 28051, 28063, 12551, 28075, 28080, 28085, 28090, 28099, - 28105, 28110, 28114, 28121, 28127, 28131, 28136, 28141, 28146, 28151, - 28156, 28161, 2512, 28166, 28172, 28176, 28179, 28190, 28194, 28197, - 28205, 28211, 14856, 28215, 28224, 28235, 28241, 28247, 28262, 28271, - 28279, 28286, 28291, 28295, 28302, 28308, 28317, 28325, 28332, 28342, - 28351, 28361, 28366, 28375, 28384, 28395, 28406, 28416, 28433, 4549, - 28443, 28447, 28457, 28465, 28475, 28486, 28492, 28497, 28507, 28515, - 28522, 28528, 28535, 28540, 26978, 28544, 28553, 28557, 28560, 28565, - 28573, 28580, 28589, 28597, 28605, 28613, 28623, 28632, 28638, 28644, - 28650, 28654, 26983, 26988, 28658, 28668, 28678, 28688, 28696, 28703, - 28713, 28721, 28729, 28735, 28743, 802, 28752, 17693, 649, 28766, 28775, - 28783, 28794, 28805, 28815, 28824, 28836, 28845, 28854, 28861, 28867, - 28877, 28886, 28895, 28903, 28911, 28921, 28929, 28937, 28944, 28950, - 28955, 28960, 28965, 8142, 28970, 28973, 28977, 28982, 28990, 28996, - 29001, 29005, 3757, 27001, 29013, 27006, 29019, 29025, 29031, 29036, - 29041, 29045, 29053, 29059, 29065, 29069, 3918, 29077, 29082, 29087, - 29091, 29095, 11661, 29102, 29110, 29124, 29131, 29138, 29144, 11670, - 11676, 29152, 29160, 29167, 29172, 29177, 27011, 29183, 29194, 29203, - 18999, 29211, 29216, 2761, 29221, 29232, 29238, 29243, 29247, 29251, - 29254, 29261, 29268, 29274, 29282, 29289, 29295, 29299, 8182, 29304, - 29308, 29312, 29320, 29325, 29330, 29335, 1702, 29340, 29345, 29350, - 29355, 29360, 29365, 29370, 29375, 29380, 29385, 29390, 29395, 29400, - 29405, 29411, 29416, 29421, 29426, 29431, 29436, 29441, 29447, 29452, - 29457, 29462, 29467, 29472, 29477, 29482, 29488, 29494, 29499, 29505, - 29510, 29515, 5, 29521, 29525, 29529, 29533, 29538, 29542, 29546, 29550, - 29554, 29559, 29563, 29568, 29572, 29575, 29579, 29584, 29588, 29593, - 29597, 29601, 29605, 29610, 29614, 29618, 29628, 29633, 29637, 29641, - 29646, 29651, 29660, 29665, 29670, 29674, 29678, 29687, 29700, 29712, - 29721, 29730, 29735, 29741, 29746, 29750, 29754, 29764, 29773, 29781, - 29787, 29792, 29796, 29803, 29810, 29820, 29829, 29837, 12908, 29845, - 29853, 29862, 29871, 29879, 29889, 29894, 29898, 29902, 29905, 29907, - 29911, 29915, 29920, 29925, 29929, 29933, 29936, 29940, 29943, 29947, - 29950, 29953, 29957, 29963, 29967, 29971, 29975, 29979, 29984, 29989, - 29994, 29998, 30001, 30006, 30012, 30017, 30023, 30028, 30032, 30038, - 30042, 30046, 30051, 30055, 30060, 30065, 30069, 30073, 30080, 30084, - 30087, 30091, 30095, 30101, 30107, 30111, 30115, 30120, 30127, 30133, - 30137, 30146, 30150, 30154, 30157, 30163, 30168, 30174, 1391, 1754, - 30179, 30184, 30189, 30194, 30199, 30204, 30209, 2219, 824, 30214, 30217, - 30221, 30225, 30230, 30234, 17705, 30238, 30243, 30248, 30252, 30255, - 30260, 30264, 30269, 30273, 17709, 30278, 30281, 30284, 30290, 30294, - 30299, 30303, 30316, 30324, 30328, 30331, 30339, 30348, 30355, 30360, - 30366, 30372, 30380, 30387, 30394, 30398, 30402, 30406, 30411, 30416, - 30420, 30428, 30433, 30440, 30452, 30463, 30468, 30472, 30479, 30483, - 30488, 30494, 30497, 30502, 30507, 30514, 30518, 30522, 30525, 30531, - 8880, 2419, 30535, 30540, 30556, 11080, 30576, 30585, 30601, 30605, - 30612, 30615, 30621, 30631, 30637, 30646, 30655, 30670, 30681, 30693, - 30704, 30712, 30721, 30727, 30736, 30746, 30756, 30767, 30778, 30788, - 30797, 30804, 30813, 30821, 30828, 30835, 30842, 30850, 30857, 30864, - 30877, 30884, 30892, 30899, 30905, 30910, 30919, 30926, 30932, 30937, - 30945, 30953, 30960, 30967, 28467, 30979, 30991, 31005, 31013, 31021, - 31029, 31036, 31048, 31057, 31066, 31074, 31082, 31090, 31097, 31103, - 31112, 31120, 31130, 31139, 31149, 31158, 31167, 31175, 31180, 31184, - 31187, 31191, 31195, 31199, 31203, 31207, 31213, 31219, 31224, 31232, - 31239, 31247, 31254, 10786, 17767, 31262, 31269, 31274, 31281, 31287, - 31293, 31300, 13998, 31307, 31310, 31322, 31330, 31336, 31341, 31345, - 31356, 31366, 31376, 11600, 31385, 31394, 31402, 31412, 31421, 31428, - 31435, 31443, 31447, 17786, 31450, 31457, 31461, 4493, 31467, 31470, - 31477, 31483, 31497, 31502, 31510, 31516, 31527, 31534, 31540, 31546, - 31550, 31555, 31559, 31568, 31575, 31581, 8933, 31588, 31596, 31603, - 31609, 31614, 31620, 31626, 31636, 31648, 31659, 31669, 31677, 31683, - 17804, 31687, 31689, 31192, 11613, 31698, 31703, 31709, 31719, 31724, - 31731, 31739, 31745, 31750, 31755, 31760, 31764, 31769, 31776, 31782, - 31791, 31799, 31803, 31810, 31820, 31826, 31835, 31841, 31848, 4763, - 31854, 31860, 31865, 31872, 31884, 31895, 31900, 31908, 31912, 31922, - 31928, 31932, 31937, 31947, 31956, 31960, 31967, 31975, 31982, 31988, - 31993, 32001, 32008, 32013, 32020, 32032, 32041, 32045, 15630, 32053, - 32063, 32067, 32075, 32082, 32089, 30335, 32100, 32105, 32109, 32116, - 32123, 26663, 31117, 32128, 32132, 32135, 27795, 32140, 32154, 32170, - 32188, 32207, 32224, 32242, 27814, 32259, 32279, 27831, 32291, 32303, - 19055, 32315, 27851, 32329, 32341, 12564, 32355, 32360, 32365, 32370, - 32376, 32382, 32388, 32392, 32400, 32406, 32413, 32418, 32428, 32435, - 32441, 12102, 32447, 32449, 32454, 32462, 32466, 31772, 32472, 32479, - 13840, 13850, 32486, 32493, 32503, 32508, 32512, 32515, 32521, 32529, - 32541, 32551, 32567, 32580, 32594, 19073, 32608, 32615, 32619, 32622, - 32627, 32631, 32638, 32645, 32652, 32659, 32669, 32674, 32679, 32684, - 32692, 32700, 32705, 32714, 28488, 3567, 32719, 32722, 32725, 32730, - 32737, 32742, 32747, 32763, 32771, 32779, 10844, 32787, 32792, 32796, - 32802, 32807, 32813, 32816, 32822, 32834, 32842, 32849, 32855, 32862, - 32873, 32887, 32900, 32906, 32915, 32921, 32930, 32942, 32953, 32963, - 32972, 32981, 32989, 32999, 33008, 33019, 673, 33026, 33033, 33039, - 33044, 33050, 33057, 33063, 33074, 33084, 33094, 33103, 33109, 33116, - 33121, 33129, 33136, 33144, 33152, 33164, 7128, 33171, 33174, 33183, - 33191, 33197, 33203, 33208, 33212, 33215, 33221, 33228, 33233, 33238, - 33245, 33250, 33254, 33266, 33277, 33286, 33294, 17976, 33299, 33307, - 33312, 33320, 33326, 33332, 13833, 9782, 33337, 33341, 33345, 33348, - 33351, 33357, 33365, 33373, 33377, 33381, 33386, 33390, 33393, 33402, - 33407, 33412, 33416, 33419, 33424, 33432, 33443, 33452, 33456, 33462, - 33468, 33472, 33478, 33486, 33508, 33532, 33543, 33552, 33558, 33565, - 33572, 33578, 33586, 33592, 33597, 33608, 33626, 33633, 33641, 33645, - 33652, 33657, 33666, 33679, 33687, 33699, 33710, 33721, 33731, 33745, - 33754, 33762, 33774, 33785, 11097, 33794, 33805, 33816, 33828, 33838, - 33847, 33857, 33862, 33866, 33874, 33885, 33895, 33901, 33906, 33910, - 33913, 33916, 33924, 33932, 33941, 33951, 33960, 33966, 33971, 33985, - 2844, 34007, 34018, 34027, 34037, 34049, 34058, 34067, 34077, 34085, - 34093, 34102, 34107, 34118, 34123, 34132, 34138, 34149, 34153, 34156, - 34166, 34175, 34183, 34193, 34203, 34211, 34220, 34227, 34233, 34241, - 34248, 34257, 34266, 34271, 34276, 34280, 34288, 34295, 34301, 34305, - 34313, 34320, 34331, 34346, 34353, 34359, 34369, 34378, 34384, 34395, - 34399, 34406, 34410, 34417, 34423, 16806, 34429, 34433, 34438, 34444, - 34451, 34455, 34459, 34467, 34475, 34481, 34490, 34497, 34504, 34509, - 34514, 34524, 28542, 34528, 34531, 34536, 34541, 34546, 34551, 34556, - 34561, 34566, 34571, 34577, 34582, 34587, 34593, 1100, 766, 34598, 34601, - 34608, 34617, 1783, 34624, 34629, 34633, 34639, 1149, 643, 34644, 334, - 34648, 34658, 34667, 34675, 34684, 34692, 34699, 34710, 34718, 34727, - 34735, 34745, 34753, 34758, 11768, 34762, 34770, 34778, 34783, 17722, - 4107, 34789, 34795, 34801, 6655, 34806, 34810, 34817, 34823, 34829, - 34833, 34842, 34848, 34853, 34860, 1342, 34866, 34872, 34877, 34884, - 34888, 1249, 6663, 34893, 34903, 34911, 34917, 34927, 34936, 34944, - 34950, 34955, 34963, 34970, 13350, 34976, 34983, 34988, 34995, 35005, - 1410, 245, 2218, 35011, 35017, 35024, 35035, 35046, 35054, 35061, 35071, - 35080, 35088, 35097, 35104, 35111, 35124, 35131, 35137, 35148, 35167, - 35172, 1154, 35176, 35181, 35189, 3990, 35193, 35198, 35202, 35206, 1346, - 29934, 35216, 35220, 35225, 35229, 35235, 3852, 35241, 35249, 35256, - 35267, 35276, 35284, 35309, 35317, 35322, 3991, 399, 35328, 35336, 35344, - 35351, 35356, 35362, 35367, 2287, 12766, 35374, 35380, 31551, 31890, - 35386, 656, 106, 35390, 35394, 35400, 622, 10659, 35405, 35412, 35418, - 35422, 35426, 1555, 35429, 35433, 18264, 35436, 35441, 35448, 35454, - 8946, 35459, 35467, 35474, 35480, 27173, 35484, 35488, 35492, 35496, - 1840, 20172, 35500, 35505, 35509, 35512, 35520, 35528, 35533, 35542, - 35550, 35553, 35560, 35567, 27252, 35577, 35589, 35597, 35602, 35606, - 35614, 35621, 35628, 35637, 35643, 35650, 35657, 35660, 35664, 35668, - 1357, 35678, 35680, 35685, 35691, 35697, 35702, 35707, 35712, 35717, - 35722, 35727, 35732, 35737, 35742, 35747, 35752, 35757, 35762, 35767, - 35773, 35779, 35785, 35791, 35796, 35801, 35806, 35812, 35817, 35822, - 35827, 35833, 35838, 35844, 35849, 35854, 35859, 35864, 35870, 35875, - 35881, 35886, 35891, 35896, 35901, 35907, 35912, 35918, 35923, 35928, - 35933, 35938, 35943, 35948, 35953, 35958, 35963, 35969, 35975, 35981, - 35986, 35991, 35996, 36001, 36007, 36013, 36019, 36025, 36031, 36037, - 36042, 36048, 36053, 36058, 36063, 36068, 36074, 2558, 36079, 2565, 2572, - 2968, 36084, 2578, 2588, 36090, 2620, 2625, 2630, 36094, 36099, 36104, - 36110, 36115, 36120, 36124, 36129, 36135, 36140, 36145, 36150, 36156, - 36161, 36165, 36169, 36174, 36179, 36184, 36189, 36194, 36200, 36206, - 36211, 36215, 36220, 36226, 36230, 36235, 36240, 36245, 36250, 36254, - 36257, 36262, 36267, 36272, 36277, 36282, 36288, 36294, 36299, 36304, - 36309, 36313, 36318, 36323, 36328, 36333, 36338, 36343, 36347, 36352, - 36357, 36362, 36366, 36370, 36374, 36379, 36387, 36392, 36397, 36403, - 36409, 36415, 36420, 36428, 36432, 36435, 36440, 36445, 36449, 36454, - 36459, 36463, 36468, 36472, 36475, 36480, 4203, 21663, 36485, 36490, - 36495, 36500, 36508, 25833, 34881, 10298, 36513, 36518, 36522, 36527, - 36531, 36535, 36540, 36544, 36547, 36550, 36554, 36559, 36563, 36571, - 36575, 36578, 36583, 36587, 36591, 36596, 36601, 36605, 36611, 36616, - 36621, 36628, 36635, 36639, 36642, 36648, 36657, 36664, 36672, 36679, - 36683, 36688, 36692, 36696, 36702, 36707, 36713, 36717, 36723, 36728, - 36733, 36737, 36744, 36750, 36756, 36762, 36768, 36775, 36781, 36787, - 36793, 36799, 36805, 36811, 36817, 36824, 36830, 36837, 36843, 36849, - 36855, 36861, 36867, 36873, 36879, 36885, 36891, 36897, 36902, 36907, - 13705, 36912, 36918, 36923, 36928, 36933, 36938, 36941, 36947, 36952, - 36960, 36965, 36969, 36974, 36980, 36989, 36995, 37000, 37005, 37010, - 37014, 37019, 37023, 37028, 37033, 37038, 37043, 37050, 37057, 37063, - 37069, 37074, 19769, 37081, 37087, 37094, 37100, 37106, 37111, 37119, - 37124, 11268, 37128, 37133, 37138, 37144, 37149, 37154, 37158, 37163, - 37168, 37174, 37179, 37184, 37189, 37193, 37198, 37203, 37207, 37212, - 37217, 37221, 37226, 37230, 37235, 37240, 37245, 37249, 37254, 37258, - 37263, 37267, 37274, 37278, 37282, 18420, 37287, 37294, 37303, 37309, - 37315, 37324, 37332, 37341, 37349, 37354, 37358, 37365, 37371, 37379, - 37383, 37386, 37391, 37395, 37404, 37412, 37430, 37436, 1409, 37442, - 37445, 37449, 27319, 27325, 37455, 37459, 37470, 37481, 37492, 37504, - 37508, 37515, 37522, 37529, 37534, 37538, 37546, 37551, 37556, 37561, - 37566, 6720, 16710, 25832, 37571, 37576, 37580, 16701, 37585, 37591, - 37596, 37602, 37607, 37613, 37618, 37624, 37629, 37635, 37641, 37647, - 37652, 37608, 37614, 37656, 37661, 37667, 37672, 37678, 37683, 37689, - 37694, 37619, 12396, 37698, 37630, 37636, 37642, 3060, 3766, 37704, - 37707, 37712, 37718, 37724, 37730, 37737, 37743, 37749, 37755, 37761, - 37767, 37773, 37779, 37785, 37791, 37797, 37803, 37809, 37816, 37822, - 37828, 37834, 37840, 37846, 37849, 37854, 37857, 37864, 37869, 37877, - 37881, 37886, 37891, 37897, 37902, 37907, 37911, 37916, 37922, 37927, - 37933, 37938, 37944, 37949, 37955, 37961, 37965, 37970, 37975, 37980, - 37985, 37989, 37994, 37999, 38004, 38010, 38016, 38022, 38028, 38033, - 38037, 38040, 38046, 38052, 38061, 38069, 38076, 38081, 38085, 38089, - 38094, 18207, 38099, 38107, 38113, 4149, 1259, 38118, 38123, 38127, 8996, - 38133, 38139, 38146, 9005, 38150, 38156, 38162, 38169, 38175, 38184, - 38192, 38204, 38208, 38215, 38221, 38226, 38230, 38234, 38237, 38247, - 38256, 38264, 37609, 38269, 38279, 38289, 38299, 38305, 38310, 38320, - 38325, 38338, 38352, 38363, 38375, 38387, 38401, 38414, 38426, 38438, - 17527, 38452, 38457, 38462, 38466, 38470, 38474, 38478, 38484, 38489, - 38494, 38499, 38504, 38509, 38514, 1743, 32951, 38519, 38524, 38529, - 37657, 38534, 38537, 38542, 38547, 38552, 38558, 38564, 19379, 11968, - 38569, 38575, 38582, 19007, 38588, 38593, 38598, 38602, 38607, 38612, - 37662, 38617, 38622, 38627, 38633, 37668, 38638, 38641, 38648, 38656, - 38662, 38668, 38674, 38685, 38690, 38697, 38704, 38711, 38719, 38728, - 38737, 38743, 38749, 38757, 37673, 38762, 38768, 38774, 37679, 38779, - 38784, 38792, 38800, 38806, 38813, 38819, 38826, 38833, 38839, 38847, - 38857, 38864, 38870, 38875, 38881, 38886, 38891, 38898, 38907, 38915, - 38920, 38926, 38933, 38941, 38947, 38952, 38958, 38967, 38974, 33946, - 38980, 38984, 38989, 38998, 39003, 39008, 39013, 14946, 39021, 39026, - 39031, 39036, 39040, 39045, 39050, 39057, 39062, 39067, 39072, 37684, - 25761, 39078, 2661, 155, 39081, 39084, 39088, 39092, 39102, 39110, 39117, - 39121, 39125, 39128, 39136, 39143, 39150, 31844, 39159, 39162, 39169, - 39175, 39180, 39184, 39191, 39195, 39203, 39211, 39218, 39233, 39237, - 39241, 39244, 39250, 39257, 39261, 39267, 39271, 39278, 39286, 39294, - 39301, 37620, 39308, 39316, 39321, 39333, 12049, 12056, 12063, 12070, - 12077, 12084, 630, 434, 39339, 39344, 39349, 39355, 39360, 39365, 4170, - 39370, 39373, 39378, 39383, 39388, 39393, 39398, 39405, 27437, 39410, - 39415, 39420, 39425, 39430, 39436, 39441, 39447, 37860, 39453, 39458, - 39464, 39470, 39480, 39485, 39490, 39494, 39499, 39504, 39509, 39514, - 39527, 39532, 27051, 20254, 1061, 39536, 39542, 39546, 39551, 39556, - 39562, 39567, 39572, 39576, 39581, 39586, 39592, 39597, 39602, 1264, - 39606, 39611, 39616, 39621, 39625, 39630, 39635, 39640, 39646, 39652, - 39657, 39661, 39665, 39670, 39675, 39680, 39684, 39689, 39697, 39701, - 39707, 39711, 39718, 39727, 20025, 37631, 39733, 39740, 39748, 39756, - 39763, 39769, 39778, 39791, 39803, 39808, 39814, 39818, 2987, 39822, - 39826, 39252, 39835, 39846, 39857, 39862, 34014, 39867, 39872, 39876, - 34134, 27330, 39881, 39888, 39892, 39897, 37637, 25868, 39901, 39906, - 39912, 39917, 39921, 39925, 39928, 39932, 39938, 39947, 39958, 39970, - 37643, 39975, 39978, 39982, 39986, 39991, 39996, 40001, 40006, 40011, - 40016, 40021, 40026, 373, 40031, 40036, 40041, 40046, 40051, 40056, - 40062, 40067, 40072, 40078, 40083, 40089, 40094, 40100, 40105, 40110, - 40115, 40120, 40125, 40130, 40135, 40140, 40146, 40151, 40156, 40161, - 40166, 40171, 40176, 40181, 40187, 40193, 40198, 40203, 40208, 40213, - 40218, 40223, 40228, 40233, 40238, 40243, 40248, 40253, 40258, 40263, - 40268, 40273, 40278, 40283, 40293, 40303, 40309, 346, 14, 40314, 40317, - 40321, 40325, 40333, 40337, 40341, 31524, 16943, 1824, 40344, 40349, - 40353, 40358, 40362, 40367, 40371, 40376, 40380, 40383, 40385, 40389, - 40394, 40398, 40409, 40412, 40414, 40418, 40430, 40442, 40451, 40455, - 40465, 40469, 40475, 40480, 40489, 40495, 40500, 40505, 40509, 40513, - 40518, 40525, 40530, 40536, 40541, 40545, 40552, 31125, 31135, 40556, - 40561, 40566, 40571, 40578, 40582, 40589, 40595, 9151, 40599, 40608, - 40616, 40631, 40645, 40654, 40662, 40673, 40682, 40687, 40694, 40704, - 8151, 40714, 40719, 40724, 40728, 40731, 40736, 40740, 40745, 40749, - 40756, 40761, 40766, 40771, 40781, 40786, 40791, 40796, 10168, 40801, - 40803, 40811, 40814, 40817, 40825, 40840, 40848, 40858, 40860, 40863, - 40867, 40873, 40877, 40882, 40887, 40905, 40919, 40938, 40955, 40964, - 40972, 40977, 40982, 1402, 40988, 40994, 40999, 41009, 41018, 41026, - 41031, 41037, 41042, 41051, 41060, 41071, 41076, 41083, 41089, 41093, - 41102, 41109, 41117, 41124, 41137, 41145, 41149, 41159, 41164, 41168, - 41176, 41184, 41189, 41193, 41197, 41206, 41212, 41217, 41225, 41235, - 41244, 41253, 41262, 41273, 41281, 41292, 41301, 41309, 41316, 41322, - 41327, 41338, 41349, 41354, 41358, 41361, 41365, 41375, 41383, 41389, - 41400, 41411, 41422, 41433, 41444, 41455, 41466, 41477, 41489, 41501, - 41513, 41525, 41537, 41549, 41561, 41570, 41574, 41582, 41588, 41594, - 41601, 41607, 41612, 41618, 41622, 41627, 41632, 41637, 40288, 40298, - 2532, 41642, 41644, 41649, 41654, 41659, 41662, 41664, 41668, 41671, - 41678, 41682, 11624, 41686, 41692, 41699, 41705, 41715, 41720, 41726, - 41730, 41735, 41748, 31714, 41754, 41760, 41769, 41778, 21886, 41785, - 41794, 38285, 41802, 41807, 41811, 41820, 41828, 41835, 41840, 41844, - 41849, 41854, 41862, 41866, 41874, 41880, 41886, 41891, 41896, 41900, - 41903, 41908, 41921, 41937, 27921, 41954, 41966, 41983, 41995, 42009, - 27938, 27957, 42021, 42033, 2861, 42047, 42052, 42057, 42062, 42066, - 42073, 42085, 42092, 42101, 42104, 42115, 42126, 42134, 42139, 42143, - 42148, 42153, 42158, 42163, 42168, 42173, 1774, 947, 42178, 42182, 42186, - 42189, 42194, 42199, 42205, 42210, 42215, 42221, 42227, 42232, 42236, - 42241, 42246, 42251, 42255, 42258, 42264, 42269, 42274, 42279, 42283, - 42288, 42294, 42302, 32025, 42307, 42312, 42319, 42325, 42331, 42336, - 42344, 27446, 42351, 42356, 42361, 42366, 42370, 42373, 42378, 42382, - 42386, 42393, 42399, 42405, 42411, 42418, 42423, 42429, 41179, 42433, - 42437, 42442, 42455, 42460, 42466, 42474, 42481, 42489, 42499, 42505, - 42511, 42517, 42521, 42530, 42538, 42545, 42550, 42555, 12419, 42560, - 42570, 42577, 42583, 42593, 42598, 42604, 42612, 4023, 42619, 42626, - 42632, 42639, 4029, 42643, 42648, 42659, 42666, 42672, 42681, 42685, - 42688, 4601, 42695, 42702, 42708, 42714, 42722, 42732, 35357, 42739, - 42747, 42753, 42758, 42764, 42769, 42773, 31473, 42779, 42786, 42792, - 42800, 42809, 42816, 42822, 42833, 28740, 42839, 42846, 42852, 42862, - 42867, 42871, 42879, 42887, 42894, 42900, 42905, 11226, 941, 42910, - 42914, 42916, 42920, 42925, 42928, 42930, 42935, 42941, 42946, 42951, - 42958, 39401, 42964, 42969, 42973, 42978, 42982, 42991, 42995, 43001, - 43008, 43014, 43021, 43026, 43035, 43040, 43044, 43049, 43056, 43064, - 43072, 43077, 25924, 43081, 43084, 43088, 43092, 12863, 993, 43096, - 43101, 43109, 43114, 43118, 43127, 43134, 43138, 43142, 43150, 43157, - 16228, 43167, 43171, 43175, 43183, 43191, 43197, 43202, 43206, 43215, - 15976, 43221, 43230, 43237, 43242, 43249, 43256, 43264, 43271, 43279, - 43287, 43296, 43301, 43308, 43315, 43322, 43329, 43336, 43341, 43348, - 43354, 43371, 43379, 43389, 43397, 43404, 459, 43408, 43414, 43418, - 43423, 40678, 43429, 43432, 43436, 43442, 43453, 43461, 4034, 43469, - 43475, 43481, 43491, 43497, 43506, 43515, 43525, 43532, 43538, 43543, - 4040, 4046, 43552, 43560, 43567, 43571, 14330, 43579, 43583, 43590, - 43598, 43605, 43612, 43618, 43627, 43637, 43643, 43651, 43660, 43667, - 43675, 43682, 26726, 43686, 43693, 43699, 43709, 43718, 43726, 43737, - 43741, 43751, 43758, 43763, 43768, 43774, 43781, 43789, 43798, 43807, - 43817, 43828, 43835, 43840, 43847, 3275, 43855, 43861, 43866, 43873, - 43879, 43885, 43890, 43903, 43916, 43929, 43936, 43942, 43950, 43958, - 43963, 43967, 43971, 43976, 43981, 43986, 43991, 43996, 44001, 1371, - 44006, 44010, 44014, 44018, 44022, 44026, 44030, 44034, 44038, 44042, - 44046, 44050, 44054, 44058, 44062, 44066, 44070, 44074, 44078, 44082, - 44086, 44090, 44094, 44098, 44102, 44106, 44110, 44114, 44118, 44122, - 44126, 44130, 44134, 44138, 44142, 44146, 44150, 44154, 44158, 44162, - 44166, 44170, 44174, 44178, 44182, 44186, 44190, 44194, 44198, 44202, - 44206, 44210, 44214, 44218, 44222, 44226, 44230, 44234, 44238, 44242, - 44246, 44250, 44254, 44258, 44262, 44266, 44270, 44274, 44278, 44282, - 44286, 44290, 44294, 44298, 44302, 44306, 44310, 44314, 44318, 44322, - 44326, 44330, 44334, 44338, 44342, 44346, 44350, 44354, 44358, 44362, - 44366, 44370, 44374, 44378, 44382, 44386, 44390, 44394, 44398, 44402, - 44406, 44410, 44414, 44418, 44422, 44426, 44430, 44434, 44438, 44442, - 44446, 44450, 44454, 44458, 44462, 44466, 44470, 44474, 44478, 44482, - 44486, 44490, 44494, 44498, 44502, 44506, 44510, 44514, 44518, 44522, - 44526, 44530, 44534, 44538, 44542, 44546, 44550, 44554, 44558, 44562, - 44566, 44570, 44574, 44578, 44582, 44586, 44590, 44594, 44598, 44602, - 44606, 44610, 44614, 44618, 44623, 44627, 44632, 44636, 44641, 44645, - 44650, 44654, 44660, 44665, 44669, 44674, 44678, 44683, 44687, 44692, - 44696, 44701, 44705, 44710, 44714, 44719, 44723, 44729, 44735, 44740, - 44744, 44749, 44753, 44759, 44764, 44768, 44773, 44777, 44782, 44786, - 44792, 44797, 44801, 44806, 44810, 44815, 44819, 44824, 44828, 44834, - 44839, 44843, 44848, 44852, 44858, 44863, 44867, 44872, 44876, 44881, - 44885, 44890, 44894, 44899, 44903, 44909, 44914, 44918, 44924, 44929, - 44933, 44939, 44944, 44948, 44953, 44957, 44962, 44966, 44972, 44978, - 44984, 44990, 44996, 45002, 45008, 45014, 45019, 45023, 45028, 45032, - 45038, 45043, 45047, 45052, 45056, 45061, 45065, 45070, 45074, 45079, - 45083, 45088, 45092, 45097, 45101, 45107, 45112, 45116, 45121, 45125, - 45131, 45137, 45142, 127, 63, 45146, 45148, 45152, 45156, 45160, 45165, - 45169, 45173, 45178, 11133, 45183, 45189, 1683, 7167, 45195, 45198, - 45203, 45207, 45212, 45216, 45220, 45225, 12207, 45229, 45233, 45237, - 626, 45241, 18529, 45246, 45250, 45255, 45260, 45265, 45269, 45276, - 45282, 31746, 45288, 45291, 45295, 45300, 45306, 45310, 45313, 45321, - 45327, 45332, 45336, 45339, 45343, 45349, 45353, 45357, 3817, 3822, - 15058, 45360, 45364, 45368, 45372, 45376, 45384, 45391, 45395, 15926, - 45402, 45416, 45423, 45434, 361, 45439, 45443, 45449, 45461, 45467, - 45473, 45478, 45484, 45488, 35653, 45497, 45503, 45512, 45516, 45520, - 45525, 45531, 45536, 45540, 45545, 45549, 45553, 45560, 45566, 45571, - 45582, 45597, 45612, 45627, 45643, 45661, 12114, 45675, 45682, 45688, - 45692, 45695, 45704, 45709, 45713, 45721, 19210, 45729, 45733, 45743, - 45754, 35555, 1031, 45767, 45776, 45794, 45813, 45822, 45830, 45838, - 1696, 12316, 45842, 27342, 45845, 31512, 45850, 11458, 45855, 45861, - 45866, 45872, 45877, 45883, 45888, 45894, 45899, 45905, 45911, 45917, - 45922, 45878, 45884, 45926, 45889, 45895, 45900, 45931, 45906, 45912, - 9164, 4426, 45937, 45945, 45949, 45952, 45959, 45963, 45968, 45973, - 45980, 45986, 45992, 45997, 17818, 46001, 31529, 46005, 46009, 46013, - 46020, 46026, 46030, 33880, 46039, 10331, 46043, 10760, 46046, 46053, - 46059, 46063, 14355, 46070, 46076, 46081, 46088, 46095, 46102, 34679, - 9061, 46109, 46116, 46123, 46129, 46134, 46141, 46152, 46158, 46163, - 46168, 46173, 46177, 46182, 46189, 45879, 46193, 46203, 46212, 46223, - 46229, 46237, 46244, 46249, 46254, 46259, 46264, 46269, 46273, 46277, - 46284, 46290, 46298, 2422, 30538, 12219, 12231, 12236, 12242, 46307, - 12247, 12252, 12258, 46312, 46322, 46326, 12263, 46331, 20452, 46334, - 46339, 46343, 46347, 46358, 46366, 42096, 46374, 46379, 46386, 46393, - 46397, 46400, 46408, 12127, 46415, 46418, 46424, 46434, 6753, 46443, - 46448, 46454, 46458, 46466, 46470, 46480, 46486, 46491, 46502, 46511, - 46520, 46529, 46538, 46547, 46556, 46565, 46571, 46577, 46582, 46588, - 46594, 46600, 46605, 46608, 46615, 46621, 46625, 46630, 46637, 46644, - 46648, 46651, 46661, 46674, 46683, 46692, 46703, 46716, 46728, 46739, - 46748, 46759, 46764, 46773, 46778, 12268, 46784, 46791, 46799, 46806, - 46811, 46816, 31792, 46820, 46827, 4366, 25, 46831, 46836, 20301, 46840, - 46843, 46846, 34071, 46850, 34688, 46858, 46862, 46866, 46869, 46875, - 46881, 46886, 37708, 46895, 46903, 46909, 46916, 34054, 46920, 34291, - 46924, 46933, 46937, 46945, 46951, 46957, 46962, 46966, 34714, 46972, - 46975, 46983, 46991, 46999, 4764, 47005, 47009, 47013, 47018, 47025, - 47031, 47036, 47041, 47045, 47051, 47056, 47062, 4654, 817, 47069, 47073, - 47076, 47088, 47095, 47100, 18402, 47104, 47112, 47120, 47128, 47136, - 47143, 47151, 47159, 47166, 47174, 47182, 47190, 47198, 47206, 47214, - 47222, 47230, 47238, 47246, 47254, 47261, 47269, 47277, 47285, 47293, - 47301, 47309, 47317, 47325, 47333, 47341, 47349, 47357, 47365, 47373, - 47381, 47389, 47397, 47405, 47413, 47420, 47428, 47435, 47443, 47451, - 47459, 47467, 47475, 47483, 47491, 47499, 47510, 26762, 47515, 47518, - 47525, 47529, 47535, 47539, 47545, 47550, 47556, 47561, 47566, 47570, - 47574, 47581, 47589, 47594, 47599, 47609, 47615, 47628, 47634, 47640, - 47646, 47649, 47656, 47661, 4692, 47667, 4855, 962, 47672, 47675, 47678, - 47681, 37792, 37798, 47684, 37804, 37817, 37823, 37829, 47690, 37835, - 37841, 47696, 47702, 10, 47710, 47717, 47721, 47725, 47733, 38643, 47737, - 47741, 47748, 47753, 47757, 47762, 47768, 47773, 47779, 47784, 47788, - 47792, 47796, 47801, 47805, 47810, 47814, 47818, 47825, 47830, 47834, - 47838, 47843, 47847, 47852, 47856, 47860, 47865, 47871, 18711, 18716, - 47876, 47880, 47883, 47889, 47893, 47897, 25718, 47902, 47906, 47912, - 47919, 47925, 47930, 40707, 47940, 47945, 47953, 47957, 47960, 47964, - 38658, 47972, 4730, 47977, 47982, 47986, 47991, 47995, 48000, 15994, - 48011, 48015, 48018, 48022, 48030, 48035, 48039, 48044, 48049, 48053, - 48057, 48061, 48064, 48068, 48071, 48076, 48081, 48086, 48091, 48096, - 48101, 8644, 16010, 48106, 48109, 48115, 48120, 48126, 48131, 48137, - 48142, 48148, 48153, 48159, 48165, 48171, 48176, 48180, 48184, 48195, - 48203, 48210, 48216, 48221, 48232, 48242, 48248, 48253, 48260, 48269, - 48285, 48301, 48311, 33956, 48318, 48322, 48327, 48332, 48336, 48340, - 43802, 48346, 48351, 48355, 48362, 48367, 48372, 48376, 48379, 48383, - 48389, 32754, 48393, 26076, 48398, 48405, 48413, 48419, 48425, 48432, - 48440, 48446, 48450, 48455, 48461, 48469, 48474, 48478, 48487, 11114, - 48495, 48499, 48507, 48514, 48519, 48524, 48529, 48533, 48536, 48542, - 48546, 48549, 48553, 48560, 48565, 48572, 48576, 48582, 48586, 48592, - 48597, 48602, 5093, 5100, 48607, 48616, 48624, 48629, 48635, 48647, - 48660, 48674, 48681, 48687, 48693, 48698, 48706, 48709, 48711, 48722, - 48734, 48745, 48760, 48777, 48797, 48819, 48826, 48833, 48840, 48846, - 48850, 8643, 48853, 48857, 48861, 48866, 48870, 48874, 48877, 48881, - 48895, 27987, 48914, 48927, 48940, 48953, 28005, 48968, 2814, 48983, - 48989, 48993, 49003, 49007, 49011, 49016, 49020, 49027, 49032, 49036, - 49043, 49049, 49054, 49060, 49070, 49082, 49093, 49098, 49105, 49109, - 49113, 49116, 49124, 19231, 4138, 49129, 18750, 49142, 49149, 49156, - 49162, 49166, 49170, 49175, 49181, 49186, 49192, 49196, 49200, 49203, - 49208, 49212, 49217, 49222, 49227, 49232, 49237, 49242, 49247, 49252, - 49257, 8707, 18761, 49262, 49266, 49272, 49281, 49286, 49295, 49302, - 43633, 49308, 49313, 49317, 49324, 49329, 49336, 49344, 49350, 49354, - 49357, 49361, 49366, 2892, 49373, 49380, 49384, 49387, 49392, 49397, - 49403, 49408, 49413, 49417, 49422, 49432, 49437, 49443, 49448, 47090, - 49454, 49460, 49468, 49478, 49483, 49488, 49492, 49497, 49502, 8153, - 8165, 49507, 49510, 49517, 49523, 49532, 10248, 41319, 49540, 49544, - 49548, 38706, 49556, 49567, 49575, 43850, 49582, 49587, 49592, 49603, - 49610, 49621, 38730, 26093, 49629, 4644, 49634, 16427, 49640, 34045, - 49646, 49651, 49661, 49670, 49677, 49683, 49687, 49690, 49697, 49703, - 49710, 49716, 49726, 49734, 49740, 49746, 49751, 49755, 49762, 49767, - 49773, 49780, 49786, 48862, 49791, 49795, 16469, 16478, 16487, 16496, - 16505, 16534, 617, 16543, 49801, 49806, 49809, 49815, 49823, 1281, 49828, - 49832, 49837, 49842, 49847, 49854, 49860, 49864, 49869, 49875, 49879, - 37865, 49884, 49889, 49898, 49905, 49915, 49921, 34089, 49938, 49947, - 49955, 49961, 49966, 49973, 49979, 49987, 49996, 50004, 50012, 50018, - 50022, 50027, 50035, 35231, 38739, 50041, 50060, 19134, 50074, 50090, - 50104, 50110, 50115, 50120, 50125, 50131, 38745, 50136, 50139, 50146, - 50153, 50162, 50167, 50171, 423, 3182, 50178, 50183, 50188, 33148, 49976, - 50192, 50197, 50205, 50209, 50212, 50217, 50223, 50229, 50234, 50238, - 34162, 50241, 50246, 50250, 50253, 50258, 50262, 50267, 50272, 50276, - 50281, 50285, 50292, 50296, 50300, 25714, 25725, 50305, 50310, 50316, - 50321, 50327, 50333, 32710, 50338, 50342, 50345, 50351, 50356, 50361, - 50366, 50371, 50376, 50381, 50386, 50391, 50397, 50403, 14543, 19441, - 50408, 50413, 50418, 50423, 50428, 50433, 50438, 50443, 452, 68, 37882, - 37887, 37892, 37898, 37903, 37908, 50448, 37912, 50452, 50456, 50460, - 37917, 37923, 50474, 37934, 37939, 50482, 50487, 37945, 50492, 50497, - 50506, 50511, 50516, 50525, 50531, 50537, 50543, 37962, 50556, 50565, - 50571, 37966, 50575, 37971, 50580, 37976, 37981, 50583, 50588, 50592, - 50598, 16235, 50605, 16245, 50612, 50617, 37986, 50621, 50626, 50631, - 50636, 50641, 50645, 50650, 50655, 50661, 50666, 50671, 50677, 50683, - 50688, 50692, 50697, 50702, 50707, 50711, 50716, 50721, 50726, 50732, - 50738, 50744, 50749, 50753, 50758, 50762, 37990, 37995, 38000, 50766, - 50770, 50775, 50779, 50791, 38005, 38011, 38017, 38029, 50797, 31572, - 50801, 50806, 50810, 50815, 50822, 50827, 50832, 50837, 50841, 50845, - 50855, 50860, 50865, 50869, 50873, 50876, 50884, 50889, 38077, 50893, - 1381, 50899, 50904, 50910, 50918, 50922, 50931, 50939, 50943, 50947, - 50955, 50961, 50969, 50985, 50990, 50994, 50998, 51002, 51007, 51013, - 51028, 38114, 1691, 14575, 51032, 1260, 1275, 51044, 51052, 51059, 51064, - 9210, 51071, 51076, 10745, 987, 2647, 12295, 51083, 10638, 51088, 51091, - 51100, 1168, 51105, 49033, 51112, 51121, 51126, 51130, 51138, 51145, - 27392, 2703, 51153, 12816, 51163, 51169, 2440, 2450, 51178, 51187, 51197, - 51208, 3590, 41716, 51213, 4333, 4344, 9238, 1173, 51217, 51225, 51232, - 51237, 51241, 51245, 51250, 29022, 49368, 12386, 51258, 51267, 51276, - 51284, 51297, 51304, 51315, 51320, 51333, 51346, 51358, 51370, 51382, - 51393, 51406, 51417, 51428, 51438, 51446, 51454, 51466, 51478, 51489, - 51498, 51506, 51513, 51525, 51532, 51538, 51547, 51553, 51560, 51573, - 51578, 51588, 51593, 51599, 51604, 46060, 51608, 48538, 51615, 51622, - 51630, 51637, 2660, 51644, 51655, 51665, 51674, 51682, 51692, 51700, - 51709, 51719, 51728, 51733, 51739, 51745, 4182, 51756, 51766, 51775, - 51784, 51792, 51802, 51810, 51819, 51824, 51829, 51834, 1610, 47, 51842, - 51850, 51861, 51872, 19845, 51882, 51886, 51893, 51899, 51904, 51908, - 51919, 51929, 51938, 51949, 51954, 20274, 20279, 51961, 51970, 51975, - 51985, 51990, 51998, 52006, 52013, 52019, 1572, 271, 52023, 52029, 45941, - 52034, 52037, 2188, 2669, 52045, 52049, 52052, 1426, 52058, 16755, 1178, - 52063, 52076, 2803, 2824, 52090, 52102, 52114, 2838, 2855, 2870, 2886, - 2903, 52128, 52140, 2918, 52154, 1184, 1190, 1196, 12687, 52159, 52164, - 52169, 52173, 52188, 52203, 52218, 52233, 52248, 52263, 52278, 52293, - 52308, 52323, 52338, 52353, 52368, 52383, 52398, 52413, 52428, 52443, - 52458, 52473, 52488, 52503, 52518, 52533, 52548, 52563, 52578, 52593, - 52608, 52623, 52638, 52653, 52668, 52683, 52698, 52713, 52728, 52743, - 52758, 52773, 52788, 52803, 52818, 52833, 52848, 52863, 52878, 52893, - 52908, 52923, 52938, 52953, 52968, 52983, 52998, 53013, 53028, 53043, - 53058, 53073, 53088, 53103, 53118, 53133, 53148, 53163, 53178, 53193, - 53208, 53223, 53238, 53253, 53268, 53283, 53298, 53313, 53328, 53343, - 53358, 53373, 53388, 53403, 53418, 53433, 53448, 53463, 53478, 53493, - 53508, 53523, 53538, 53553, 53568, 53583, 53598, 53613, 53628, 53643, - 53658, 53673, 53688, 53703, 53718, 53733, 53748, 53763, 53778, 53793, - 53808, 53823, 53838, 53853, 53868, 53883, 53898, 53913, 53928, 53943, - 53958, 53973, 53988, 54003, 54018, 54033, 54048, 54063, 54078, 54093, - 54108, 54123, 54138, 54153, 54168, 54183, 54198, 54213, 54228, 54243, - 54258, 54273, 54288, 54303, 54318, 54333, 54348, 54363, 54378, 54393, - 54408, 54423, 54438, 54453, 54468, 54483, 54498, 54513, 54528, 54543, - 54558, 54573, 54588, 54603, 54618, 54633, 54648, 54663, 54678, 54693, - 54708, 54723, 54738, 54753, 54768, 54783, 54798, 54813, 54828, 54843, - 54858, 54873, 54888, 54903, 54918, 54933, 54948, 54963, 54978, 54993, - 55008, 55023, 55038, 55053, 55068, 55083, 55098, 55113, 55128, 55143, - 55158, 55173, 55188, 55203, 55218, 55233, 55248, 55263, 55278, 55293, - 55308, 55323, 55338, 55353, 55368, 55383, 55398, 55413, 55428, 55443, - 55458, 55473, 55488, 55503, 55518, 55533, 55548, 55563, 55578, 55593, - 55608, 55623, 55638, 55653, 55668, 55683, 55698, 55713, 55728, 55743, - 55758, 55773, 55788, 55803, 55818, 55833, 55848, 55863, 55878, 55893, - 55908, 55923, 55938, 55953, 55968, 55983, 55998, 56013, 56028, 56043, - 56058, 56073, 56088, 56103, 56118, 56133, 56148, 56163, 56178, 56193, - 56208, 56223, 56238, 56253, 56268, 56283, 56298, 56313, 56328, 56343, - 56358, 56373, 56388, 56403, 56418, 56433, 56448, 56463, 56478, 56493, - 56508, 56523, 56538, 56553, 56568, 56583, 56598, 56613, 56628, 56643, - 56658, 56673, 56688, 56703, 56718, 56733, 56748, 56763, 56778, 56793, - 56808, 56823, 56838, 56853, 56868, 56883, 56898, 56913, 56928, 56943, - 56958, 56973, 56988, 57003, 57018, 57033, 57048, 57063, 57078, 57093, - 57108, 57123, 57138, 57153, 57168, 57183, 57198, 57213, 57228, 57243, - 57258, 57273, 57288, 57303, 57318, 57333, 57348, 57363, 57378, 57393, - 57408, 57423, 57438, 57453, 57468, 57483, 57498, 57513, 57528, 57543, - 57558, 57573, 57588, 57603, 57618, 57633, 57648, 57663, 57678, 57693, - 57708, 57723, 57738, 57753, 57768, 57783, 57798, 57813, 57828, 57843, - 57858, 57873, 57888, 57903, 57918, 57933, 57948, 57963, 57978, 57993, - 58008, 58023, 58038, 58053, 58068, 58083, 58098, 58113, 58128, 58143, - 58158, 58173, 58188, 58203, 58218, 58233, 58248, 58263, 58278, 58293, - 58308, 58323, 58338, 58353, 58368, 58383, 58398, 58413, 58428, 58443, - 58458, 58473, 58488, 58503, 58518, 58533, 58548, 58563, 58578, 58593, - 58608, 58623, 58638, 58653, 58668, 58683, 58698, 58713, 58728, 58743, - 58758, 58773, 58788, 58803, 58818, 58833, 58848, 58863, 58878, 58893, - 58908, 58923, 58938, 58953, 58968, 58983, 58998, 59013, 59028, 59043, - 59058, 59073, 59088, 59103, 59118, 59133, 59148, 59163, 59178, 59193, - 59208, 59223, 59238, 59253, 59268, 59283, 59298, 59313, 59328, 59343, - 59358, 59373, 59388, 59403, 59418, 59433, 59448, 59463, 59478, 59493, - 59508, 59523, 59538, 59553, 59568, 59583, 59598, 59613, 59628, 59643, - 59658, 59673, 59688, 59703, 59718, 59733, 59748, 59763, 59778, 59793, - 59808, 59823, 59838, 59853, 59868, 59883, 59898, 59913, 59928, 59943, - 59958, 59973, 59988, 60004, 60020, 60036, 60052, 60068, 60084, 60100, - 60116, 60132, 60148, 60164, 60180, 60196, 60212, 60228, 60244, 60260, - 60276, 60292, 60308, 60324, 60340, 60356, 60372, 60388, 60404, 60420, - 60436, 60452, 60468, 60484, 60500, 60516, 60532, 60548, 60564, 60580, - 60596, 60612, 60628, 60644, 60660, 60676, 60692, 60708, 60724, 60740, - 60756, 60772, 60788, 60804, 60820, 60836, 60852, 60868, 60884, 60900, - 60916, 60932, 60948, 60964, 60980, 60996, 61012, 61028, 61044, 61060, - 61076, 61092, 61108, 61124, 61140, 61156, 61172, 61188, 61204, 61220, - 61236, 61252, 61268, 61284, 61300, 61316, 61332, 61348, 61364, 61380, - 61396, 61412, 61428, 61444, 61460, 61476, 61492, 61508, 61524, 61540, - 61556, 61572, 61588, 61604, 61620, 61636, 61652, 61668, 61684, 61700, - 61716, 61732, 61748, 61764, 61780, 61796, 61812, 61828, 61844, 61860, - 61876, 61892, 61908, 61924, 61940, 61956, 61972, 61988, 62004, 62020, - 62036, 62052, 62068, 62084, 62100, 62116, 62132, 62148, 62164, 62180, - 62196, 62212, 62228, 62244, 62260, 62276, 62292, 62308, 62324, 62340, - 62356, 62372, 62388, 62404, 62420, 62436, 62452, 62468, 62484, 62500, - 62516, 62532, 62548, 62564, 62580, 62596, 62612, 62628, 62644, 62660, - 62676, 62692, 62708, 62724, 62740, 62756, 62772, 62788, 62804, 62820, - 62836, 62852, 62868, 62884, 62900, 62916, 62932, 62948, 62964, 62980, - 62996, 63012, 63028, 63044, 63060, 63076, 63092, 63108, 63124, 63140, - 63156, 63172, 63188, 63204, 63220, 63236, 63252, 63268, 63284, 63300, - 63316, 63332, 63348, 63364, 63380, 63396, 63412, 63428, 63444, 63460, - 63476, 63492, 63508, 63524, 63540, 63556, 63572, 63588, 63604, 63620, - 63636, 63652, 63668, 63684, 63700, 63716, 63732, 63748, 63764, 63780, - 63796, 63812, 63828, 63844, 63860, 63876, 63892, 63908, 63924, 63940, - 63956, 63972, 63988, 64004, 64020, 64036, 64052, 64068, 64084, 64100, - 64116, 64132, 64148, 64164, 64180, 64196, 64212, 64228, 64244, 64260, - 64276, 64292, 64308, 64324, 64340, 64356, 64372, 64388, 64404, 64420, - 64436, 64452, 64468, 64484, 64500, 64516, 64532, 64548, 64564, 64580, - 64596, 64612, 64628, 64644, 64660, 64676, 64692, 64708, 64724, 64740, - 64756, 64772, 64788, 64804, 64820, 64836, 64852, 64868, 64884, 64900, - 64916, 64932, 64948, 64964, 64980, 64996, 65012, 65028, 65044, 65060, - 65076, 65092, 65108, 65124, 65140, 65156, 65172, 65188, 65204, 65220, - 65236, 65252, 65268, 65284, 65300, 65316, 65332, 65348, 65364, 65380, - 65396, 65412, 65428, 65444, 65460, 65476, 65492, 65508, 65524, 65540, - 65556, 65572, 65588, 65604, 65620, 65636, 65652, 65668, 65684, 65700, - 65716, 65732, 65748, 65764, 65780, 65796, 65812, 65828, 65844, 65860, - 65876, 65892, 65908, 65924, 65940, 65956, 65972, 65988, 66004, 66020, - 66036, 66052, 66068, 66084, 66100, 66116, 66132, 66148, 66164, 66180, - 66196, 66212, 66228, 66244, 66260, 66276, 66292, 66308, 66324, 66340, - 66356, 66372, 66388, 66404, 66420, 66436, 66452, 66468, 66484, 66500, - 66516, 66532, 66548, 66564, 66580, 66596, 66612, 66628, 66644, 66660, - 66676, 66692, 66708, 66724, 66740, 66756, 66772, 66788, 66804, 66820, - 66836, 66852, 66868, 66884, 66900, 66916, 66932, 66948, 66964, 66980, - 66996, 67012, 67028, 67044, 67060, 67076, 67092, 67108, 67124, 67140, - 67156, 67172, 67188, 67204, 67220, 67236, 67252, 67268, 67284, 67300, - 67316, 67332, 67348, 67364, 67380, 67396, 67412, 67428, 67444, 67460, - 67476, 67492, 67508, 67524, 67540, 67556, 67572, 67588, 67604, 67620, - 67636, 67652, 67668, 67684, 67700, 67716, 67732, 67748, 67764, 67780, - 67796, 67812, 67828, 67844, 67860, 67876, 67892, 67908, 67924, 67940, - 67956, 67972, 67988, 68004, 68020, 68036, 68052, 68068, 68084, 68100, - 68116, 68132, 68148, 68164, 68180, 68196, 68212, 68228, 68244, 68260, - 68276, 68292, 68308, 68324, 68340, 68356, 68372, 68388, 68404, 68420, - 68436, 68452, 68468, 68484, 68500, 68516, 68532, 68548, 68564, 68580, - 68596, 68612, 68628, 68644, 68660, 68669, 68684, 68698, 17657, 68707, - 68712, 68718, 68724, 68734, 68742, 17914, 18645, 9257, 68755, 1434, 1438, - 68763, 4262, 33273, 8090, 68769, 68774, 68779, 68784, 68789, 68795, - 68800, 68806, 68811, 68817, 68822, 68827, 68832, 68837, 68843, 68848, - 68853, 68858, 68863, 68868, 68873, 68878, 68884, 68889, 68895, 68902, - 2707, 68907, 68913, 9632, 68917, 68922, 68929, 68937, 4273, 4278, 4283, - 4288, 65, 68941, 68947, 68952, 68957, 68961, 68966, 68970, 68974, 12759, - 68978, 68988, 69001, 69012, 69025, 69032, 69038, 69046, 12220, 69053, - 69058, 69064, 69070, 69076, 69081, 69086, 69091, 69096, 69100, 69105, - 69110, 69115, 69121, 69127, 69133, 69138, 69142, 69147, 69152, 69156, - 69161, 69166, 69171, 69175, 12775, 12786, 12791, 1477, 69179, 69185, - 1482, 19679, 69190, 19688, 1492, 69195, 69201, 69206, 1513, 69212, 1519, - 1525, 12821, 69217, 69226, 69234, 69242, 69249, 69253, 69257, 69263, - 69268, 37525, 69273, 69280, 69288, 69295, 69300, 69304, 69308, 69317, - 69322, 69327, 69332, 1530, 280, 69337, 69342, 69346, 19814, 1007, 69350, - 69357, 69362, 69366, 19872, 1534, 46217, 69369, 69374, 69384, 69393, - 69398, 69402, 69408, 1539, 49314, 69413, 69422, 69428, 69433, 69438, - 13060, 13066, 69444, 69456, 69473, 69490, 69507, 69524, 69541, 69558, - 69575, 69592, 69609, 69626, 69643, 69660, 69677, 69694, 69711, 69728, - 69745, 69762, 69779, 69796, 69813, 69830, 69847, 69864, 69881, 69898, - 69915, 69932, 69949, 69966, 69983, 70000, 70017, 70034, 70051, 70068, - 70085, 70102, 70119, 70136, 70153, 70170, 70187, 70204, 70221, 70238, - 70255, 70272, 70289, 70300, 70310, 70315, 1544, 70319, 70324, 70330, - 70335, 70340, 70347, 10657, 1549, 70353, 70362, 33662, 70367, 70378, - 13082, 70388, 70393, 70399, 70404, 70411, 70417, 70422, 1554, 20166, - 70427, 70433, 13092, 70439, 70444, 70449, 70454, 70459, 70464, 70469, - 70474, 1559, 4753, 70479, 70484, 70490, 70495, 70500, 70505, 70510, - 70515, 70520, 70525, 70530, 70536, 70542, 70548, 70553, 70557, 70562, - 70567, 70571, 70576, 70581, 70586, 70591, 70595, 70600, 70606, 70611, - 70616, 70620, 70625, 70630, 70636, 70641, 70646, 70652, 70658, 70663, - 70667, 70672, 70677, 70682, 70686, 70691, 70696, 70701, 70707, 70713, - 70718, 70722, 70726, 70731, 70736, 70741, 35430, 70745, 70750, 70755, - 70761, 70766, 70771, 70775, 70780, 70785, 70791, 70796, 70801, 70807, - 70813, 70818, 70822, 70827, 70832, 70836, 70841, 70846, 70851, 70857, - 70863, 70868, 70872, 70877, 70882, 70886, 70891, 70896, 70901, 70906, - 70910, 70913, 70916, 70921, 70926, 38252, 70933, 70941, 49930, 70947, - 3934, 33605, 70960, 70967, 70973, 70979, 4113, 70984, 13234, 70990, - 71000, 71015, 71023, 13239, 71034, 71039, 71050, 71062, 71074, 71086, - 2909, 71098, 71103, 31655, 71115, 71121, 71127, 71132, 71141, 71148, - 71153, 71158, 71163, 71168, 71173, 71178, 1576, 19306, 71183, 71188, - 71193, 71198, 71204, 71209, 71215, 71220, 71225, 71231, 71236, 71241, - 49388, 71245, 71249, 71254, 71258, 20314, 71263, 71266, 71271, 71279, - 71287, 1580, 13275, 13281, 1585, 71295, 71302, 71307, 71316, 71326, - 71333, 71338, 71343, 1590, 71350, 71355, 20434, 71359, 71364, 71371, - 71377, 71381, 71394, 71400, 71411, 71421, 71428, 20456, 10551, 10558, - 4347, 4353, 71435, 1595, 71440, 71449, 71455, 71463, 71470, 71476, 71483, - 71495, 71501, 71506, 71513, 71525, 71536, 71546, 71555, 71565, 71575, - 4241, 71583, 37319, 37328, 20496, 71596, 71601, 71606, 71611, 71616, - 71621, 71626, 1600, 1604, 71631, 71635, 71638, 71649, 71654, 20522, 1614, - 71662, 71667, 71672, 20555, 71684, 71687, 71693, 71699, 71704, 71712, - 1619, 71717, 71722, 71730, 71738, 71745, 71754, 71762, 71771, 71775, - 1624, 71784, 1629, 25899, 71789, 71796, 71802, 20642, 71810, 71820, - 71826, 71831, 71839, 71846, 71855, 71863, 71873, 71882, 71892, 71901, - 71912, 71922, 71932, 71941, 71951, 71965, 71978, 71987, 71995, 72005, - 72014, 72026, 72037, 72048, 72058, 19934, 72063, 13427, 72072, 72078, - 72083, 72090, 72096, 72103, 72109, 19523, 72119, 72125, 72130, 72141, - 72148, 72155, 72160, 72168, 13444, 13449, 72176, 72182, 72186, 4331, - 4342, 20718, 49484, 72194, 72200, 72205, 72213, 72220, 14556, 72225, - 72231, 72237, 1640, 72242, 72245, 72251, 72256, 72261, 72266, 72271, - 72276, 72281, 72286, 72291, 72297, 72303, 1339, 72308, 72313, 72318, - 72324, 72329, 72334, 72339, 72344, 72349, 72354, 1649, 18, 72360, 72364, - 72369, 72373, 72377, 72381, 38538, 72386, 28206, 72391, 72396, 72400, - 72403, 72407, 72411, 72416, 72420, 72425, 72429, 72432, 72438, 42190, - 42195, 42200, 72441, 72448, 72454, 72462, 49086, 72472, 72478, 42206, - 38802, 38553, 38559, 42222, 38565, 72483, 72488, 72492, 38835, 72499, - 72502, 72506, 72514, 72521, 72526, 72529, 72534, 72539, 72543, 72547, - 72550, 72560, 72572, 72579, 72585, 38570, 72592, 40521, 72595, 9649, - 13789, 72598, 72602, 72607, 4156, 72611, 72614, 16288, 72621, 72628, - 72641, 72656, 72670, 72686, 72701, 72710, 72718, 72726, 72735, 72744, - 72750, 72755, 72765, 72778, 72790, 72797, 72802, 72811, 72824, 43897, - 72842, 72847, 72854, 72860, 72865, 895, 72870, 72878, 72885, 72892, - 33089, 911, 72898, 72904, 72909, 72919, 72927, 72933, 72938, 38589, 6844, - 38603, 72942, 72952, 72957, 72965, 72975, 72990, 72996, 73002, 73009, - 38613, 73014, 37663, 73018, 73023, 73032, 73039, 73044, 73048, 73053, - 73061, 20499, 73068, 73073, 73077, 6885, 38639, 73081, 73087, 345, 73097, - 73104, 73111, 73117, 73124, 73129, 73138, 15909, 69378, 69388, 73144, - 73152, 73156, 73160, 73164, 73168, 73173, 73177, 73183, 73191, 73196, - 73201, 73208, 73213, 73217, 73222, 73226, 73230, 73236, 73247, 73253, - 73258, 73262, 73267, 73271, 38763, 73275, 38769, 38775, 73280, 73286, - 73293, 73298, 73302, 37680, 20153, 73305, 73309, 73314, 73321, 73327, - 73331, 73336, 48555, 73342, 73346, 73353, 73357, 73362, 73368, 73374, - 73380, 73392, 73401, 73411, 73417, 73424, 73429, 73434, 73438, 73441, - 73447, 73454, 73459, 73464, 73471, 73478, 73485, 73491, 73496, 73501, - 73509, 38780, 2537, 73514, 73519, 73525, 73530, 73536, 73541, 73546, - 73551, 73557, 38801, 73562, 73568, 73574, 73580, 38871, 73585, 73590, - 73595, 38882, 73600, 73605, 73610, 73616, 73622, 38887, 73627, 73632, - 73637, 38942, 38948, 73642, 73647, 38953, 38975, 33947, 38981, 38985, - 73652, 14232, 73656, 73664, 73670, 73678, 73685, 73691, 73701, 73707, - 73714, 12659, 38999, 73720, 73733, 73742, 73748, 73757, 73763, 73769, - 73776, 28549, 73784, 73791, 73801, 73809, 73812, 38943, 73817, 73824, - 73829, 73833, 73837, 73842, 73846, 4470, 73851, 73856, 73861, 42284, - 42289, 73865, 42303, 73870, 42308, 73875, 73881, 42320, 42326, 42332, - 73886, 73892, 27447, 73903, 73906, 73918, 73926, 39022, 73930, 73939, - 73949, 73958, 39032, 73963, 73970, 73979, 73985, 73993, 74000, 74007, - 6936, 5160, 74012, 38954, 74018, 74021, 74027, 74034, 74039, 74044, - 28453, 74048, 74054, 74060, 74065, 74070, 74074, 74080, 74086, 40405, - 74091, 43500, 45323, 45329, 39063, 39068, 74095, 74099, 74103, 74106, - 74119, 74125, 74129, 74132, 74137, 40774, 74141, 37685, 25840, 74147, - 6865, 6873, 10357, 74150, 74155, 74160, 74165, 74170, 74175, 74180, - 74185, 74190, 74195, 74201, 74206, 74211, 74217, 74222, 74227, 74232, - 74237, 74242, 74247, 74253, 74258, 74264, 74269, 74274, 74279, 74284, - 74289, 74294, 74299, 74304, 74309, 74314, 74320, 74325, 74330, 74335, - 74340, 74345, 74350, 74356, 74361, 74366, 74371, 74376, 74381, 74386, - 74391, 74396, 74401, 74407, 74412, 74417, 74422, 74427, 74433, 74439, - 74444, 74450, 74455, 74460, 74465, 74470, 74475, 1427, 156, 74480, 74484, - 74488, 74492, 30391, 74496, 74500, 74505, 74509, 74514, 74518, 74523, - 74528, 74533, 74538, 74542, 74546, 74551, 74555, 15988, 74560, 74564, - 74571, 74581, 18283, 74590, 74599, 74603, 74608, 74613, 74617, 74621, - 30171, 3265, 74625, 74631, 21731, 74635, 74644, 74652, 74658, 74663, - 74675, 74687, 74692, 74696, 74701, 74705, 74711, 74717, 74722, 74732, - 74742, 74748, 74756, 74761, 74765, 74771, 74776, 74783, 74789, 74794, - 74801, 74810, 74819, 74827, 74831, 18839, 74834, 74843, 74851, 74863, - 74874, 74885, 74894, 74898, 74907, 74915, 74925, 74933, 74940, 74950, - 74956, 74961, 74968, 74977, 74983, 74988, 74995, 75001, 75012, 60, 37462, - 75018, 31942, 31952, 75024, 75032, 75039, 75045, 75049, 75059, 75070, - 75078, 75087, 75092, 75097, 75102, 75106, 75110, 75118, 21678, 75125, - 75129, 75135, 75145, 75152, 75158, 75164, 42383, 75168, 75170, 75173, - 75179, 75183, 75194, 75204, 75210, 75217, 75224, 15925, 75232, 75238, - 75247, 75256, 75262, 11559, 75268, 75274, 75279, 75284, 75291, 75296, - 75303, 75309, 75314, 75322, 75335, 75344, 75353, 71927, 71937, 75363, - 75369, 75378, 75384, 75390, 75397, 75404, 75411, 75418, 75425, 75430, - 75434, 75438, 75441, 75451, 75455, 75467, 10018, 75476, 75487, 75492, - 75496, 71946, 75502, 75509, 75518, 75526, 75534, 75539, 75543, 75548, - 75553, 75563, 75571, 75583, 75588, 75592, 75596, 75602, 75610, 75617, - 75629, 75637, 75648, 75655, 75661, 75671, 75677, 75681, 75690, 75699, - 75706, 75712, 75717, 75721, 75725, 75729, 75738, 75747, 75756, 75763, - 75769, 75775, 75781, 75786, 75793, 75799, 75807, 75814, 75820, 15020, - 75825, 75831, 75835, 17140, 75839, 75844, 75854, 75859, 75868, 75874, - 75880, 75888, 75895, 75899, 75903, 75910, 75916, 75924, 75931, 75937, - 75948, 75952, 75956, 75960, 75963, 75969, 75974, 75979, 75983, 75987, - 75996, 76004, 76011, 76017, 76024, 29213, 48696, 76029, 76037, 76041, - 76045, 76048, 76056, 76063, 76069, 76078, 76086, 76092, 76097, 76101, - 76106, 76111, 76115, 76119, 76123, 76128, 76137, 76141, 76148, 45427, - 76152, 76158, 76166, 76170, 76176, 76184, 76190, 76195, 76206, 76214, - 76220, 76229, 27594, 76237, 76244, 76251, 76258, 76265, 76272, 52348, - 15740, 76279, 76286, 76291, 42419, 4713, 76297, 76302, 76307, 76313, - 76319, 76325, 76330, 76335, 76340, 76345, 76351, 76356, 76362, 76367, - 76373, 76378, 76383, 76388, 76393, 76398, 76403, 76408, 76414, 76419, - 76425, 76430, 76435, 76440, 76445, 76450, 76455, 76461, 76466, 76471, - 76476, 76481, 76486, 76491, 76496, 76501, 76506, 76511, 76517, 76522, - 76527, 76532, 76537, 76542, 76547, 76552, 76557, 76563, 76568, 76573, - 76578, 76583, 76588, 76593, 76598, 76603, 76608, 76613, 76618, 76623, - 76629, 1889, 305, 76634, 46335, 46340, 76638, 76643, 9273, 76647, 3634, - 76652, 76657, 76661, 76670, 76681, 76698, 76716, 76724, 75530, 76731, - 76734, 76744, 76751, 76760, 76776, 76785, 76795, 76800, 76813, 76823, - 76832, 76840, 76854, 76862, 76871, 76875, 76878, 76885, 76891, 76902, - 76909, 76921, 76932, 76943, 76952, 76959, 1179, 809, 76969, 2750, 76973, - 76978, 76987, 1025, 9039, 25276, 76995, 77003, 77017, 77030, 77034, - 77039, 77044, 77049, 77055, 77061, 77066, 9641, 18326, 77071, 77075, - 77083, 10078, 77088, 77094, 77103, 77111, 1663, 13288, 1185, 4385, 77115, - 77119, 77128, 77138, 2488, 32788, 77147, 77153, 20406, 32803, 77159, - 4550, 13670, 77165, 77172, 71644, 77176, 77180, 77186, 77191, 77196, - 3867, 163, 3893, 77201, 77213, 77217, 77221, 77227, 77232, 33682, 77236, - 13658, 2944, 4, 77241, 77251, 77262, 77273, 77283, 77289, 77300, 77307, - 77313, 77319, 2312, 77324, 77332, 77339, 77345, 77355, 77365, 77375, - 77384, 28536, 1191, 77389, 77393, 77397, 77403, 77407, 2967, 2973, 9638, - 2343, 77411, 77415, 77424, 77432, 77443, 77451, 77459, 77465, 77470, - 77481, 77492, 77500, 77506, 77511, 11336, 77521, 77529, 77533, 77537, - 77542, 77546, 77558, 34145, 18225, 77565, 77575, 77581, 77587, 7963, - 11470, 77597, 77608, 77619, 77629, 77638, 77642, 77649, 1027, 2737, - 77659, 77664, 77672, 71360, 77680, 77685, 77696, 77703, 77717, 16936, - 529, 77727, 77734, 77738, 77742, 77750, 77759, 77767, 77773, 20451, - 77778, 77792, 77799, 77805, 77813, 77822, 77831, 77838, 77850, 77860, - 77868, 77875, 77883, 77890, 4349, 116, 77898, 77909, 77913, 77925, 77931, - 1810, 227, 77936, 10689, 77941, 3012, 77945, 77952, 77958, 77969, 77979, - 77987, 77994, 10029, 78001, 78010, 78018, 4430, 78031, 4447, 78035, - 78040, 78046, 78051, 78056, 78061, 3017, 573, 78067, 78080, 78084, 78089, - 78094, 3022, 1888, 760, 78098, 4451, 78106, 78112, 78116, 803, 78126, - 78135, 78140, 3884, 78144, 17957, 17964, 9297, 78148, 4482, 4359, 15618, - 78156, 78163, 78168, 28600, 78172, 78179, 78185, 13926, 78190, 13991, - 204, 78195, 78207, 78213, 78221, 3034, 1705, 78229, 78231, 78236, 78241, - 78246, 78252, 78257, 78262, 78267, 78272, 78277, 78282, 78288, 78293, - 78298, 78303, 78308, 78313, 78318, 78323, 78328, 78334, 78339, 78344, - 78349, 78355, 78360, 78366, 78371, 78376, 78381, 78386, 78391, 78396, - 78401, 78407, 78412, 78418, 78423, 78428, 78433, 78438, 78443, 78448, - 78453, 78458, 9710, 9723, 4498, 4503, 4508, 4513, 26, 78464, 78470, - 78475, 78480, 78485, 78491, 78496, 78500, 78504, 78509, 78515, 78519, - 78525, 78530, 78535, 78541, 78546, 78550, 78555, 78560, 78564, 78567, - 78569, 78573, 78576, 78583, 78588, 78592, 78597, 78601, 78605, 78609, - 78615, 78626, 78646, 78665, 78686, 78699, 78711, 78720, 78724, 78727, - 39340, 78730, 39345, 78737, 78742, 39350, 78751, 78760, 39356, 78765, - 39361, 78774, 78779, 13915, 78783, 78788, 78793, 39366, 78797, 78806, - 50533, 78810, 78813, 78817, 9305, 78823, 78826, 78831, 78836, 78841, - 78845, 4171, 39371, 78848, 78852, 78855, 78866, 78871, 78875, 78881, - 78889, 78902, 78906, 78914, 78923, 78929, 78934, 78940, 78944, 78950, - 78956, 78964, 78969, 78973, 78980, 78986, 78994, 79003, 79011, 39374, - 79018, 79028, 79037, 79045, 79056, 79069, 79074, 79079, 79083, 79092, - 79098, 79105, 79118, 79130, 79141, 79153, 79160, 79169, 79178, 79187, - 79194, 79200, 79207, 79215, 79222, 79230, 79239, 79247, 79254, 79262, - 79271, 79279, 79288, 79298, 79307, 79315, 79322, 79330, 79339, 79347, - 79356, 79366, 79375, 79383, 79392, 79402, 79411, 79421, 79432, 79442, - 79451, 79459, 79466, 79474, 79483, 79491, 79500, 79510, 79519, 79527, - 79536, 79546, 79555, 79565, 79576, 79586, 79595, 79603, 79612, 79622, - 79631, 79641, 79652, 79662, 79671, 79681, 79692, 79702, 79713, 79725, - 79736, 79746, 79755, 79763, 79770, 79778, 79787, 79795, 79804, 79814, - 79823, 79831, 79840, 79850, 79859, 79869, 79880, 79890, 79899, 79907, - 79916, 79926, 79935, 79945, 79956, 79966, 79975, 79985, 79996, 80006, - 80017, 80029, 80040, 80050, 80059, 80067, 80076, 80086, 80095, 80105, - 80116, 80126, 80135, 80145, 80156, 80166, 80177, 80189, 80200, 80210, - 80219, 80229, 80240, 80250, 80261, 80273, 80284, 80294, 80305, 80317, - 80328, 80340, 80353, 80365, 80376, 80386, 80395, 80403, 80410, 80418, - 80427, 80435, 80444, 80454, 80463, 80471, 80480, 80490, 80499, 80509, - 80520, 80530, 80539, 80547, 80556, 80566, 80575, 80585, 80596, 80606, - 80615, 80625, 80636, 80646, 80657, 80669, 80680, 80690, 80699, 80707, - 80716, 80726, 80735, 80745, 80756, 80766, 80775, 80785, 80796, 80806, - 80817, 80829, 80840, 80850, 80859, 80869, 80880, 80890, 80901, 80913, - 80924, 80934, 80945, 80957, 80968, 80980, 80993, 81005, 81016, 81026, - 81035, 81043, 81052, 81062, 81071, 81081, 81092, 81102, 81111, 81121, - 81132, 81142, 81153, 81165, 81176, 81186, 81195, 81205, 81216, 81226, - 81237, 81249, 81260, 81270, 81281, 81293, 81304, 81316, 81329, 81341, - 81352, 81362, 81371, 81381, 81392, 81402, 81413, 81425, 81436, 81446, - 81457, 81469, 81480, 81492, 81505, 81517, 81528, 81538, 81549, 81561, - 81572, 81584, 81597, 81609, 81620, 81632, 81645, 81657, 81670, 81684, - 81697, 81709, 81720, 81730, 81739, 81747, 81754, 81759, 9070, 81766, - 81771, 39384, 81777, 81782, 39389, 81788, 25398, 31390, 81793, 81799, - 81805, 81813, 81819, 81825, 81832, 81839, 81844, 81849, 81853, 81858, - 81862, 81865, 81869, 81874, 81883, 81892, 81900, 81906, 81918, 81929, - 81933, 3327, 9045, 81938, 81941, 81944, 81946, 81950, 81954, 81958, - 81964, 81969, 31453, 81974, 81978, 81981, 81986, 81990, 81997, 82003, - 82007, 7046, 82011, 82016, 39411, 82020, 82027, 82036, 82044, 82050, - 82061, 82069, 82078, 82086, 82093, 82100, 82106, 82111, 82122, 39416, - 82127, 82138, 82150, 82158, 82169, 82178, 82186, 82197, 82202, 82210, - 2702, 82215, 82224, 41789, 82237, 82241, 82253, 82261, 82266, 82274, - 82285, 21896, 82294, 82300, 82307, 82315, 82321, 39426, 82326, 4476, - 68738, 82333, 82336, 82344, 82357, 82370, 82383, 82396, 82403, 82414, - 82423, 82428, 52165, 52170, 82432, 82436, 82444, 82451, 82460, 82468, - 82474, 82483, 82491, 82498, 82506, 82510, 82519, 82528, 82538, 82551, - 82564, 82574, 39431, 82580, 82587, 82593, 82599, 39437, 82604, 82607, - 82611, 82619, 82628, 51941, 82636, 82645, 82653, 82660, 82668, 82678, - 82687, 82696, 40947, 82705, 82716, 82731, 82741, 10727, 26214, 82750, - 82755, 82760, 82764, 19515, 82769, 82774, 82780, 82785, 82790, 82796, - 82801, 82806, 26174, 82811, 82818, 82826, 82834, 82842, 82847, 82854, - 82861, 82866, 1723, 82870, 82874, 82882, 82890, 39454, 82896, 82902, - 82914, 82920, 82927, 82931, 82938, 82943, 82950, 82956, 82963, 82974, - 82984, 82994, 83006, 83012, 83020, 83029, 83035, 83045, 83055, 39481, - 83064, 83073, 83079, 83091, 83102, 83109, 83114, 83118, 83126, 83137, - 83143, 83148, 83153, 83160, 83168, 83180, 83190, 83199, 83208, 83216, - 83223, 41603, 28974, 83229, 83234, 83238, 83242, 83247, 83255, 83261, - 83272, 83285, 83290, 83297, 39486, 83302, 83314, 83323, 83331, 83341, - 83352, 83365, 83372, 83381, 83390, 83398, 83403, 83409, 83413, 1416, - 83418, 83423, 83428, 83433, 83439, 83444, 83449, 83455, 83461, 83466, - 83470, 83475, 83480, 83485, 69313, 83490, 83495, 83500, 83505, 83511, - 83517, 83522, 83526, 83531, 19514, 83536, 83542, 83547, 83553, 83558, - 83563, 83568, 83573, 83577, 83583, 83588, 83597, 83602, 83607, 83612, - 83617, 83621, 83628, 83634, 4822, 20768, 3292, 83639, 83643, 83648, - 83652, 83656, 83660, 55965, 83664, 83589, 83666, 83676, 39495, 83679, - 83684, 83693, 83699, 7005, 39500, 83703, 83709, 83714, 83720, 83725, - 83729, 83736, 83741, 83751, 83760, 83764, 83770, 83776, 83782, 83786, - 83794, 83801, 83809, 83817, 39505, 83824, 83827, 83838, 83845, 83851, - 83856, 83860, 83866, 83874, 83881, 83886, 83890, 83899, 83907, 83913, - 83918, 39510, 83925, 28426, 83937, 83943, 83948, 83954, 83961, 83967, - 25862, 33296, 83973, 83978, 83984, 83988, 84000, 83622, 83629, 26106, - 84010, 84015, 84022, 84028, 84035, 84041, 84052, 84057, 84065, 10427, - 84070, 84073, 84079, 84083, 84087, 84090, 84096, 84102, 39199, 4823, - 1431, 16037, 84109, 84115, 84121, 84127, 84133, 84139, 84145, 84151, - 84157, 84162, 84167, 84172, 84177, 84182, 84187, 84192, 84197, 84202, - 84207, 84212, 84217, 84222, 84228, 84233, 84238, 84244, 84249, 84254, - 84260, 84266, 84272, 84278, 84284, 84290, 84296, 84302, 84308, 84313, - 84318, 84324, 84329, 84334, 84340, 84345, 84350, 84355, 84360, 84365, - 84370, 84375, 84380, 84385, 84390, 84395, 84400, 84406, 84411, 84416, - 84421, 84427, 84432, 84437, 84442, 84447, 84453, 84458, 84463, 84468, - 84473, 84478, 84483, 84488, 84493, 84498, 84503, 84508, 84513, 84518, - 84523, 84528, 84533, 84538, 84543, 84548, 84554, 84559, 84564, 84569, - 84574, 84579, 84584, 84589, 1062, 159, 84594, 84598, 84602, 84607, 84615, - 84619, 84631, 84638, 84646, 84650, 84663, 84671, 84676, 84681, 32005, - 84685, 84690, 84694, 84699, 84703, 84711, 84715, 25406, 84720, 84724, - 72190, 84728, 84731, 84739, 84747, 84755, 84760, 84765, 84772, 84779, - 84785, 84791, 84796, 84803, 84808, 84816, 77022, 84823, 84828, 71956, - 84835, 84841, 84846, 84850, 84857, 84863, 84870, 71983, 14005, 84878, - 84883, 84888, 84892, 84895, 84906, 84915, 84921, 84926, 84930, 84940, - 84949, 50324, 84953, 84957, 84964, 84977, 84983, 84991, 84998, 85007, - 85018, 85029, 85040, 85051, 85060, 85066, 85075, 85083, 85093, 85106, - 85114, 85121, 85132, 85141, 85147, 85152, 85157, 85163, 85173, 85179, - 85189, 85197, 85204, 85214, 85223, 83304, 85231, 85237, 85245, 85251, - 75575, 85258, 85263, 85266, 85270, 85276, 85280, 85283, 85291, 85297, - 85303, 85311, 85323, 85335, 85342, 85347, 85351, 85362, 85370, 85377, - 85389, 85397, 85404, 85412, 85419, 85425, 85430, 85436, 85446, 85455, - 85463, 85468, 85478, 85487, 51202, 85494, 85498, 85503, 85511, 85518, - 85524, 85528, 85538, 85549, 85557, 85564, 85576, 85588, 85597, 82227, - 85604, 85614, 85626, 85637, 85651, 85659, 85669, 85676, 85684, 85697, - 85709, 85718, 85726, 85736, 85747, 85759, 85768, 85778, 85788, 85797, - 85804, 85813, 85828, 85836, 85846, 85855, 85863, 85876, 68708, 85891, - 85901, 85910, 85922, 85932, 85944, 85955, 85969, 85983, 85997, 86011, - 86025, 86039, 86053, 86067, 86081, 86095, 86109, 86123, 86137, 86151, - 86165, 86179, 86193, 86207, 86221, 86235, 86249, 86263, 86277, 86291, - 86305, 86319, 86333, 86347, 86361, 86375, 86389, 86403, 86417, 86431, - 86445, 86459, 86473, 86487, 86501, 86515, 86529, 86543, 86557, 86571, - 86585, 86599, 86613, 86627, 86641, 86655, 86669, 86683, 86697, 86711, - 86725, 86739, 86753, 86767, 86781, 86795, 86809, 86823, 86837, 86851, - 86865, 86879, 86893, 86907, 86921, 86935, 86949, 86963, 86977, 86991, - 87005, 87019, 87033, 87047, 87061, 87075, 87089, 87103, 87117, 87131, - 87145, 87159, 87173, 87187, 87201, 87215, 87229, 87243, 87257, 87271, - 87285, 87299, 87313, 87327, 87341, 87355, 87369, 87383, 87397, 87411, - 87425, 87439, 87453, 87467, 87481, 87495, 87509, 87523, 87537, 87551, - 87565, 87579, 87593, 87607, 87621, 87635, 87649, 87663, 87677, 87691, - 87705, 87719, 87733, 87747, 87761, 87775, 87789, 87803, 87817, 87831, - 87845, 87859, 87873, 87887, 87901, 87915, 87929, 87943, 87957, 87971, - 87985, 87999, 88013, 88027, 88041, 88055, 88069, 88083, 88097, 88111, - 88125, 88139, 88153, 88167, 88181, 88195, 88209, 88223, 88237, 88251, - 88265, 88279, 88293, 88307, 88321, 88335, 88349, 88363, 88377, 88391, - 88405, 88419, 88433, 88447, 88461, 88475, 88489, 88503, 88517, 88531, - 88545, 88559, 88573, 88587, 88601, 88615, 88629, 88643, 88657, 88671, - 88685, 88699, 88713, 88727, 88741, 88755, 88769, 88783, 88797, 88811, - 88825, 88839, 88853, 88867, 88881, 88895, 88909, 88923, 88937, 88951, - 88965, 88979, 88993, 89007, 89021, 89035, 89049, 89063, 89077, 89091, - 89105, 89119, 89133, 89147, 89161, 89175, 89189, 89203, 89217, 89231, - 89245, 89259, 89273, 89287, 89301, 89315, 89329, 89343, 89357, 89371, - 89385, 89399, 89413, 89427, 89441, 89455, 89469, 89483, 89497, 89511, - 89525, 89539, 89553, 89567, 89581, 89595, 89609, 89623, 89637, 89651, - 89665, 89679, 89693, 89707, 89721, 89735, 89749, 89763, 89777, 89791, - 89805, 89819, 89833, 89847, 89861, 89875, 89889, 89903, 89917, 89931, - 89945, 89959, 89973, 89987, 90001, 90015, 90029, 90043, 90057, 90071, - 90085, 90099, 90113, 90127, 90141, 90155, 90169, 90183, 90197, 90211, - 90225, 90239, 90253, 90267, 90281, 90295, 90309, 90323, 90337, 90351, - 90365, 90379, 90393, 90407, 90421, 90435, 90449, 90463, 90477, 90491, - 90505, 90519, 90533, 90547, 90561, 90575, 90589, 90603, 90617, 90631, - 90645, 90659, 90673, 90687, 90701, 90715, 90729, 90743, 90757, 90771, - 90785, 90799, 90813, 90827, 90841, 90855, 90869, 90883, 90897, 90911, - 90925, 90939, 90953, 90967, 90981, 90995, 91009, 91023, 91037, 91051, - 91065, 91079, 91093, 91107, 91121, 91135, 91149, 91163, 91177, 91191, - 91205, 91219, 91233, 91247, 91261, 91275, 91289, 91303, 91317, 91331, - 91345, 91359, 91373, 91387, 91401, 91415, 91429, 91443, 91457, 91471, - 91485, 91499, 91513, 91527, 91541, 91555, 91569, 91583, 91597, 91611, - 91625, 91639, 91653, 91667, 91681, 91695, 91709, 91723, 91737, 91751, - 91765, 91779, 91793, 91807, 91821, 91835, 91849, 91863, 91877, 91891, - 91905, 91919, 91933, 91947, 91961, 91975, 91989, 92003, 92017, 92031, - 92045, 92059, 92073, 92087, 92101, 92115, 92129, 92143, 92157, 92171, - 92185, 92199, 92213, 92227, 92241, 92255, 92269, 92283, 92297, 92311, - 92325, 92339, 92353, 92367, 92381, 92395, 92409, 92423, 92437, 92451, - 92465, 92479, 92493, 92507, 92521, 92535, 92549, 92563, 92577, 92591, - 92605, 92619, 92633, 92647, 92661, 92675, 92689, 92703, 92717, 92731, - 92745, 92759, 92773, 92787, 92801, 92815, 92829, 92843, 92857, 92871, - 92885, 92899, 92913, 92927, 92941, 92955, 92969, 92983, 92997, 93011, - 93025, 93039, 93053, 93067, 93081, 93095, 93109, 93123, 93137, 93151, - 93165, 93179, 93193, 93207, 93221, 93235, 93249, 93263, 93277, 93291, - 93305, 93319, 93333, 93347, 93361, 93375, 93389, 93403, 93417, 93431, - 93445, 93459, 93473, 93487, 93501, 93515, 93529, 93543, 93557, 93571, - 93585, 93599, 93613, 93627, 93641, 93655, 93669, 93683, 93697, 93711, - 93725, 93739, 93753, 93767, 93781, 93795, 93809, 93823, 93837, 93851, - 93865, 93879, 93893, 93907, 93921, 93935, 93949, 93963, 93977, 93991, - 94005, 94019, 94033, 94047, 94061, 94075, 94089, 94103, 94117, 94131, - 94145, 94159, 94173, 94187, 94201, 94215, 94229, 94243, 94257, 94271, - 94285, 94299, 94313, 94327, 94341, 94355, 94369, 94383, 94397, 94411, - 94425, 94439, 94453, 94467, 94481, 94495, 94509, 94523, 94537, 94551, - 94565, 94579, 94593, 94607, 94621, 94635, 94649, 94663, 94677, 94691, - 94705, 94719, 94733, 94747, 94761, 94775, 94789, 94803, 94817, 94831, - 94845, 94859, 94873, 94887, 94901, 94915, 94929, 94943, 94957, 94971, - 94985, 94999, 95013, 95027, 95041, 95055, 95069, 95083, 95097, 95111, - 95125, 95139, 95153, 95167, 95181, 95195, 95209, 95223, 95237, 95251, - 95265, 95279, 95293, 95307, 95321, 95335, 95349, 95363, 95377, 95391, - 95405, 95419, 95433, 95447, 95461, 95475, 95489, 95503, 95517, 95531, - 95545, 95559, 95573, 95587, 95601, 95615, 95629, 95643, 95657, 95671, - 95685, 95699, 95713, 95727, 95741, 95755, 95769, 95783, 95797, 95811, - 95825, 95839, 95853, 95867, 95881, 95895, 95909, 95923, 95937, 95951, - 95965, 95979, 95993, 96007, 96021, 96035, 96049, 96063, 96077, 96091, - 96105, 96119, 96133, 96147, 96161, 96175, 96189, 96203, 96217, 96231, - 96245, 96259, 96273, 96287, 96301, 96315, 96329, 96343, 96357, 96371, - 96385, 96399, 96413, 96427, 96441, 96455, 96469, 96483, 96497, 96511, - 96525, 96539, 96553, 96567, 96581, 96595, 96609, 96623, 96637, 96651, - 96665, 96679, 96693, 96707, 96716, 96727, 96738, 96748, 96759, 96767, - 96775, 96781, 96791, 96799, 96805, 35311, 96810, 96816, 96825, 96837, - 96842, 96849, 11350, 21916, 96855, 96864, 96869, 96873, 96878, 96885, - 96891, 96896, 96901, 96909, 96917, 96927, 96932, 96940, 14487, 96944, - 96950, 96956, 96962, 96968, 96974, 96980, 96986, 96992, 96998, 97004, - 97010, 97016, 97022, 97028, 97034, 97040, 97046, 97052, 97058, 97064, - 97070, 97076, 97082, 97088, 97094, 97100, 97106, 97112, 97118, 97124, - 97130, 97136, 97142, 97148, 97154, 97160, 97167, 97173, 97179, 97185, - 97191, 97197, 97203, 97209, 97215, 97221, 97227, 97233, 97239, 97245, - 97251, 97257, 97263, 97269, 97275, 97281, 97287, 97293, 97299, 97305, - 97311, 97317, 97323, 97329, 97335, 97341, 97347, 97353, 97359, 97365, - 97371, 97377, 97383, 97389, 97395, 97401, 97407, 97413, 97419, 97425, - 97431, 97437, 97443, 97449, 97455, 97461, 97467, 97474, 97480, 97486, - 97492, 97498, 97504, 97510, 97516, 97522, 97528, 97534, 97540, 97543, - 97545, 97560, 97573, 97580, 97586, 97597, 97602, 97606, 97611, 97618, - 97624, 97629, 97637, 77621, 77631, 97643, 97650, 97660, 12646, 97667, - 97672, 35554, 97681, 97686, 97693, 97703, 97711, 97719, 97728, 97737, - 97743, 97749, 97754, 97761, 97768, 97773, 97777, 97785, 72000, 97790, - 97799, 97807, 97814, 97819, 97823, 97832, 97838, 97841, 97845, 97854, - 97864, 84658, 97873, 97877, 97885, 97889, 97895, 97906, 97916, 21925, - 97927, 97936, 97944, 97952, 97959, 72019, 9875, 97967, 97971, 97980, - 97987, 97990, 97994, 33167, 97997, 98001, 98006, 98023, 98035, 12604, - 98047, 98052, 98057, 98062, 25513, 98066, 98071, 98076, 98082, 98087, - 6626, 98092, 25517, 98097, 98102, 98108, 98115, 98120, 98125, 98131, - 98137, 98143, 98148, 98154, 98158, 98172, 98180, 98188, 98194, 98199, - 98206, 98216, 98225, 98230, 98235, 98240, 98248, 98258, 98269, 98274, - 98280, 98285, 98294, 70435, 4752, 98299, 98317, 98336, 98349, 98363, - 98379, 98386, 98393, 98402, 98409, 98415, 98422, 98427, 98433, 98438, - 98444, 98452, 98458, 98463, 98468, 98484, 12617, 98498, 98505, 98513, - 98519, 98523, 98526, 98532, 98537, 98542, 98550, 98557, 98562, 98571, - 98577, 98582, 98588, 98594, 98603, 98612, 43344, 98617, 98628, 98635, - 98643, 98652, 14078, 98661, 98667, 98675, 98681, 98687, 98693, 98698, - 98705, 98711, 14089, 98716, 98719, 98724, 39537, 98734, 98743, 98748, - 98756, 98763, 98769, 98774, 98782, 98789, 98800, 98816, 98832, 98848, - 98864, 98880, 98896, 98912, 98928, 98944, 98960, 98976, 98992, 99008, - 99024, 99040, 99056, 99072, 99088, 99104, 99120, 99136, 99152, 99168, - 99184, 99200, 99216, 99232, 99248, 99264, 99280, 99296, 99312, 99328, - 99344, 99360, 99376, 99392, 99408, 99424, 99440, 99456, 99472, 99488, - 99504, 99520, 99536, 99552, 99568, 99584, 99600, 99616, 99632, 99648, - 99664, 99680, 99696, 99712, 99728, 99744, 99760, 99776, 99792, 99808, - 99824, 99840, 99856, 99872, 99888, 99904, 99920, 99936, 99952, 99968, - 99984, 100000, 100016, 100032, 100048, 100064, 100080, 100096, 100112, - 100128, 100144, 100160, 100176, 100192, 100208, 100224, 100240, 100256, - 100272, 100288, 100304, 100320, 100336, 100352, 100368, 100384, 100400, - 100416, 100432, 100448, 100464, 100480, 100496, 100512, 100528, 100544, - 100560, 100576, 100592, 100608, 100624, 100640, 100656, 100672, 100688, - 100704, 100720, 100736, 100752, 100768, 100784, 100800, 100816, 100832, - 100848, 100864, 100880, 100896, 100912, 100928, 100944, 100960, 100976, - 100992, 101008, 101024, 101040, 101056, 101072, 101088, 101104, 101120, - 101136, 101152, 101168, 101184, 101200, 101216, 101232, 101248, 101264, - 101280, 101296, 101312, 101328, 101344, 101360, 101376, 101392, 101408, - 101424, 101440, 101456, 101472, 101488, 101504, 101520, 101536, 101552, - 101568, 101584, 101600, 101616, 101632, 101648, 101664, 101680, 101696, - 101712, 101728, 101744, 101760, 101776, 101792, 101808, 101824, 101840, - 101856, 101872, 101888, 101904, 101920, 101936, 101952, 101968, 101984, - 102000, 102016, 102032, 102048, 102064, 102080, 102096, 102112, 102128, - 102144, 102160, 102176, 102192, 102208, 102224, 102240, 102256, 102272, - 102288, 102304, 102320, 102336, 102352, 102368, 102384, 102400, 102416, - 102432, 102448, 102464, 102480, 102496, 102512, 102528, 102544, 102560, - 102576, 102592, 102608, 102624, 102640, 102656, 102672, 102688, 102704, - 102720, 102736, 102752, 102768, 102784, 102800, 102816, 102832, 102848, - 102864, 102880, 102896, 102912, 102928, 102944, 102960, 102976, 102992, - 103008, 103024, 103040, 103056, 103072, 103088, 103104, 103120, 103136, - 103152, 103168, 103184, 103200, 103216, 103232, 103248, 103264, 103280, - 103296, 103312, 103328, 103344, 103360, 103376, 103392, 103408, 103424, - 103440, 103456, 103472, 103488, 103504, 103520, 103536, 103552, 103568, - 103584, 103600, 103616, 103632, 103648, 103664, 103680, 103696, 103712, - 103728, 103744, 103760, 103776, 103792, 103808, 103824, 103840, 103856, - 103872, 103888, 103904, 103920, 103936, 103952, 103968, 103984, 104000, - 104016, 104032, 104048, 104064, 104080, 104096, 104112, 104128, 104144, - 104160, 104176, 104192, 104208, 104224, 104240, 104256, 104272, 104288, - 104304, 104320, 104336, 104352, 104368, 104384, 104400, 104416, 104432, - 104448, 104464, 104480, 104496, 104512, 104528, 104544, 104560, 104576, - 104592, 104608, 104624, 104640, 104656, 104672, 104688, 104704, 104720, - 104736, 104752, 104768, 104784, 104800, 104816, 104832, 104848, 104864, - 104880, 104896, 104912, 104928, 104944, 104960, 104976, 104992, 105008, - 105024, 105040, 105056, 105072, 105088, 105104, 105120, 105136, 105152, - 105168, 105184, 105200, 105216, 105232, 105248, 105264, 105280, 105296, - 105312, 105328, 105344, 105360, 105376, 105392, 105408, 105424, 105440, - 105456, 105472, 105488, 105504, 105520, 105536, 105552, 105568, 105584, - 105600, 105616, 105632, 105648, 105664, 105680, 105696, 105712, 105728, - 105744, 105760, 105776, 105792, 105808, 105824, 105840, 105856, 105872, - 105888, 105904, 105920, 105936, 105952, 105968, 105984, 106000, 106016, - 106032, 106048, 106064, 106080, 106096, 106112, 106128, 106144, 106160, - 106176, 106192, 106208, 106224, 106240, 106256, 106272, 106288, 106304, - 106320, 106336, 106352, 106368, 106384, 106400, 106416, 106432, 106448, - 106464, 106480, 106496, 106512, 106528, 106544, 106560, 106576, 106592, - 106608, 106624, 106640, 106656, 106672, 106688, 106704, 106720, 106736, - 106752, 106768, 106784, 106800, 106816, 106832, 106848, 106864, 106880, - 106896, 106912, 106928, 106944, 106960, 106976, 106992, 107008, 107024, - 107040, 107056, 107072, 107088, 107104, 107120, 107136, 107152, 107168, - 107184, 107200, 107216, 107232, 107248, 107264, 107280, 107296, 107312, - 107328, 107344, 107360, 107376, 107392, 107408, 107424, 107440, 107456, - 107472, 107488, 107504, 107520, 107536, 107552, 107568, 107584, 107600, - 107616, 107632, 107648, 107664, 107680, 107696, 107712, 107728, 107744, - 107760, 107776, 107792, 107808, 107824, 107840, 107856, 107872, 107888, - 107904, 107920, 107936, 107952, 107968, 107984, 108000, 108016, 108032, - 108048, 108064, 108080, 108096, 108112, 108128, 108144, 108160, 108176, - 108192, 108208, 108224, 108240, 108256, 108272, 108288, 108304, 108320, - 108336, 108352, 108368, 108384, 108400, 108416, 108432, 108448, 108464, - 108480, 108496, 108512, 108528, 108544, 108560, 108576, 108592, 108608, - 108624, 108640, 108656, 108672, 108688, 108704, 108720, 108736, 108752, - 108768, 108784, 108800, 108816, 108832, 108848, 108864, 108880, 108896, - 108912, 108928, 108944, 108960, 108976, 108992, 109008, 109024, 109040, - 109056, 109072, 109088, 109104, 109120, 109136, 109152, 109168, 109184, - 109200, 109216, 109232, 109248, 109264, 109280, 109296, 109312, 109328, - 109344, 109360, 109376, 109392, 109408, 109424, 109440, 109456, 109472, - 109488, 109504, 109520, 109536, 109552, 109568, 109584, 109600, 109616, - 109632, 109648, 109664, 109680, 109696, 109712, 109728, 109744, 109760, - 109776, 109792, 109808, 109824, 109840, 109856, 109872, 109888, 109904, - 109920, 109936, 109952, 109968, 109984, 110000, 110016, 110032, 110048, - 110064, 110080, 110096, 110112, 110128, 110144, 110160, 110176, 110192, - 110208, 110224, 110240, 110256, 110272, 110288, 110304, 110320, 110336, - 110352, 110368, 110384, 110400, 110416, 110432, 110448, 110464, 110480, - 110496, 110512, 110528, 110544, 110560, 110576, 110592, 110608, 110624, - 110640, 110656, 110672, 110688, 110704, 110720, 110736, 110752, 110768, - 110784, 110800, 110816, 110832, 110848, 110864, 110880, 110896, 110912, - 110928, 110944, 110960, 110976, 110992, 111008, 111024, 111040, 111056, - 111072, 111088, 111104, 111120, 111136, 111152, 111168, 111184, 111200, - 111216, 111232, 111248, 111264, 111280, 111296, 111312, 111328, 111344, - 111360, 111376, 111392, 111408, 111424, 111440, 111456, 111472, 111488, - 111504, 111520, 111536, 111552, 111568, 111584, 111600, 111616, 111632, - 111648, 111664, 111680, 111696, 111712, 111728, 111744, 111760, 111776, - 111792, 111808, 111824, 111840, 111856, 111872, 111888, 111904, 111920, - 111936, 111952, 111968, 111984, 112000, 112016, 112032, 112048, 112064, - 112080, 112096, 112112, 112128, 112144, 112160, 112176, 112192, 112208, - 112224, 112240, 112256, 112272, 112288, 112304, 112320, 112336, 112352, - 112368, 112384, 112400, 112416, 112432, 112448, 112464, 112480, 112496, - 112512, 112528, 112544, 112560, 112576, 112592, 112608, 112624, 112640, - 112656, 112666, 112675, 112680, 112688, 76945, 112693, 112699, 112704, - 112711, 112720, 112728, 112732, 4330, 112738, 112745, 112751, 112755, - 20517, 46451, 3301, 112760, 112764, 112768, 112775, 112781, 112790, - 112796, 112803, 112807, 112828, 112850, 112866, 112883, 112902, 112911, - 112921, 112929, 112936, 112943, 112949, 33022, 112963, 112967, 112973, - 112981, 112993, 112999, 113007, 113014, 113019, 113024, 113028, 113036, - 113043, 113047, 113053, 113059, 113064, 3978, 52365, 113070, 113074, - 113078, 113082, 113087, 113092, 113097, 113103, 113109, 113115, 113122, - 113128, 113135, 113141, 113147, 113152, 113158, 113163, 113167, 105260, - 113172, 105324, 52380, 113177, 113182, 113190, 113194, 113199, 113206, - 113215, 113222, 113228, 113237, 113241, 113248, 113252, 113255, 113262, - 113268, 113277, 113287, 113297, 113302, 113306, 113313, 113321, 113330, - 113334, 113342, 113348, 113353, 113358, 113364, 113370, 113375, 113379, - 31903, 113385, 113389, 113393, 113396, 113401, 113409, 113419, 113425, - 113430, 113440, 49513, 113448, 113460, 113466, 113473, 113479, 113483, - 113488, 113494, 113506, 113517, 113524, 113530, 113537, 113544, 113556, - 113563, 113569, 25597, 113573, 113581, 113587, 113594, 113600, 113606, - 113612, 113617, 113622, 113627, 113631, 113640, 113648, 113659, 7920, - 113664, 19953, 113670, 113674, 113678, 113682, 113690, 113699, 113703, - 113710, 113719, 113727, 113740, 113746, 105836, 36477, 113751, 113753, - 113758, 113763, 113768, 113773, 113778, 113783, 113788, 113793, 113798, - 113803, 113808, 113813, 113818, 113823, 113829, 113834, 113839, 113844, - 113849, 113854, 113859, 113864, 113869, 113875, 113881, 113887, 113892, - 113897, 113909, 113914, 1941, 54, 113919, 113924, 39547, 113928, 39552, - 39557, 39563, 39568, 113932, 39573, 26783, 113954, 113958, 113962, - 113967, 113971, 39577, 113975, 113983, 113990, 113996, 114006, 39582, - 114013, 114016, 114021, 114025, 114034, 11148, 114042, 39587, 26627, - 114045, 114049, 114057, 1313, 114062, 39598, 114065, 114070, 114075, - 31144, 31154, 42942, 114080, 114085, 114090, 114095, 114101, 114106, - 114115, 114120, 114129, 114137, 114144, 114150, 114155, 114160, 114165, - 114175, 114184, 114192, 114197, 114205, 114209, 114217, 114221, 114228, - 114235, 114243, 114250, 39402, 46166, 114256, 114262, 114267, 114272, - 14522, 11935, 114277, 114282, 114287, 114293, 114300, 114306, 114315, - 114320, 114328, 114338, 114345, 114355, 114361, 114366, 114372, 114376, - 21947, 114383, 43910, 114396, 114401, 114408, 114414, 114429, 37541, - 75357, 114442, 114446, 114455, 114464, 114471, 114477, 114485, 114491, - 114499, 114508, 114516, 114523, 46286, 114529, 114532, 114536, 114540, - 114544, 11956, 114550, 114557, 114563, 114571, 114576, 114580, 29148, - 114586, 114589, 114597, 114604, 114612, 114625, 114639, 114646, 114652, - 114659, 114665, 39612, 114669, 114675, 114683, 114690, 114698, 114706, - 114712, 39617, 114720, 114726, 114731, 114741, 114747, 114756, 37336, - 42290, 114764, 114769, 114774, 114778, 114783, 114787, 114795, 114800, - 17949, 18774, 49535, 114804, 114809, 39622, 18106, 114813, 114825, - 114830, 114834, 114841, 114850, 114854, 114862, 114868, 114873, 114881, - 114889, 114897, 114905, 114913, 114921, 114932, 114938, 9112, 114943, - 114949, 114954, 114959, 114970, 114979, 114991, 115006, 39934, 115012, - 20072, 39626, 115016, 115023, 115029, 115033, 29285, 115040, 115046, - 115053, 48667, 115062, 115068, 115077, 115083, 115088, 115096, 115102, - 115107, 39636, 115112, 115121, 115130, 113512, 115139, 115146, 115152, - 115158, 115167, 115177, 115183, 115191, 115198, 115202, 39641, 115205, - 39647, 1352, 115210, 115218, 115226, 115236, 115245, 115253, 115260, - 115270, 39658, 115274, 115276, 115280, 115285, 115289, 115293, 115299, - 115304, 115308, 115319, 115324, 115333, 115338, 3306, 115342, 115349, - 115353, 115362, 115370, 115378, 115385, 115390, 115395, 73882, 115399, - 115402, 115408, 115416, 115422, 115426, 115431, 115438, 115443, 115448, - 115452, 115459, 115465, 115470, 42321, 115474, 115477, 115482, 115486, - 115491, 115498, 115503, 115507, 47636, 115515, 31163, 31172, 115521, - 115527, 115533, 115538, 115542, 115545, 115555, 115564, 115569, 115575, - 115582, 115588, 115592, 115600, 115605, 42327, 84917, 115609, 115617, - 115624, 115630, 115637, 115642, 115649, 115654, 115658, 115664, 115669, - 68924, 115675, 115681, 10366, 115686, 115691, 115695, 115700, 115705, - 115710, 115714, 115719, 115724, 115730, 115735, 115740, 115746, 115752, - 115757, 115761, 115766, 115771, 115776, 115780, 29284, 115785, 115790, - 115796, 115802, 115808, 115813, 115817, 115822, 115827, 109612, 115832, - 115837, 115842, 115847, 109676, 52635, 115852, 39666, 115860, 115864, - 115872, 115880, 115891, 115896, 115900, 27262, 82330, 115905, 115911, - 115916, 4641, 115926, 115933, 115938, 115946, 115955, 115960, 115964, - 115969, 115973, 115981, 115989, 115996, 77207, 116002, 116010, 116017, - 116028, 116034, 116040, 39676, 116043, 116050, 116058, 116063, 116067, - 33538, 71588, 116073, 116078, 116085, 116090, 10255, 116094, 116102, - 116109, 116116, 116125, 116132, 116138, 116152, 116160, 6710, 115922, - 116166, 116171, 116177, 116181, 116184, 116192, 116199, 116204, 116217, - 116224, 116230, 116234, 116242, 116247, 116254, 116260, 116265, 71859, - 116270, 116273, 116282, 116289, 109884, 116295, 116298, 116306, 116312, - 116321, 116331, 116341, 116350, 116361, 116369, 116380, 116385, 116389, - 116394, 116398, 43073, 116406, 18739, 43082, 116411, 101403, 101419, - 101435, 101451, 101467, 116416, 101499, 101515, 101531, 101547, 101659, - 101675, 116420, 101707, 101723, 116424, 116428, 116432, 116436, 101963, - 101995, 116440, 102027, 116444, 116448, 102171, 102187, 102203, 102219, - 116452, 102283, 102299, 116456, 102427, 102443, 102459, 102475, 102491, - 102507, 102523, 102539, 102555, 102571, 102683, 102699, 102715, 102731, - 102747, 102763, 102779, 102795, 102811, 102827, 116460, 104619, 104731, - 104795, 104811, 104827, 104843, 104859, 104875, 104987, 105003, 105019, - 116464, 105067, 116468, 105099, 105115, 105131, 116472, 116477, 116482, - 116487, 116492, 116497, 116502, 116506, 116510, 116515, 116520, 116524, - 116529, 116534, 116538, 116543, 116548, 116553, 116558, 116562, 116567, - 116572, 116576, 116581, 116585, 116589, 116593, 116597, 116602, 116606, - 116610, 116614, 116618, 116622, 116626, 116630, 116634, 116638, 116643, - 116648, 116653, 116658, 116663, 116668, 116673, 116678, 116683, 116688, - 116692, 116696, 116700, 116704, 116708, 116712, 116717, 116721, 116726, - 116730, 116735, 116740, 116744, 116748, 116753, 116757, 116761, 116765, - 116769, 116773, 116777, 116781, 116785, 116789, 116793, 116797, 116801, - 116805, 116809, 116814, 116819, 116823, 116827, 116831, 116835, 116839, - 116843, 116848, 116852, 116856, 116860, 116864, 116868, 116872, 116877, - 116881, 116886, 116890, 116894, 116898, 116902, 116906, 116910, 116914, - 116918, 116922, 116926, 116930, 116935, 116939, 116943, 116947, 116951, - 116955, 116959, 116963, 116967, 116971, 116975, 116979, 116984, 116988, - 116992, 116997, 117002, 117006, 117010, 117014, 117018, 117022, 117026, - 117030, 117034, 117039, 117043, 117048, 117052, 117057, 117061, 117066, - 117070, 117076, 117081, 117085, 117090, 117094, 117099, 117103, 117108, - 117112, 117117, 1435, 117121, 117125, 3048, 1711, 28421, 1608, 31099, - 117129, 3057, 117133, 1282, 117138, 1224, 117142, 117146, 117150, 117154, - 117158, 117162, 3081, 117166, 117174, 117181, 117188, 117202, 3085, 8030, - 117211, 117219, 117226, 117237, 117246, 117250, 117257, 117269, 117282, - 117295, 117306, 117311, 117318, 117330, 117334, 3089, 14159, 117344, - 117349, 117358, 117368, 117373, 117382, 3093, 117390, 117394, 117399, - 117406, 117412, 117417, 117426, 117434, 117446, 117456, 1229, 15619, - 117469, 117473, 117479, 117493, 117505, 117517, 117525, 117535, 117544, - 117553, 117562, 117570, 117581, 117589, 4649, 117599, 117610, 117619, - 117625, 117640, 117647, 117653, 117658, 43216, 117663, 3117, 15623, - 117667, 117672, 117679, 10186, 117688, 117694, 4687, 117704, 3122, 39038, - 117713, 71478, 117720, 117724, 117730, 117741, 117747, 117752, 117759, - 117765, 117773, 117780, 117786, 117797, 117813, 117823, 117832, 117843, - 117852, 117859, 117865, 117875, 117883, 117889, 117904, 117910, 117915, - 117919, 117926, 117934, 117938, 117941, 117947, 117954, 117960, 117968, - 117977, 117985, 117991, 118000, 51943, 118014, 118019, 118025, 17700, - 118030, 118043, 118055, 118064, 118072, 118079, 118083, 118087, 118090, - 118097, 118104, 118112, 118120, 118129, 118137, 17599, 118145, 118150, - 118154, 118166, 118173, 118180, 118189, 954, 118199, 118208, 118219, - 3143, 118223, 118227, 118233, 118246, 118258, 118268, 118277, 118289, - 32057, 118300, 118308, 118317, 118328, 118339, 118349, 118359, 118367, - 118376, 118384, 13578, 118391, 118395, 118398, 118403, 118408, 118412, - 118418, 1234, 118425, 118429, 14255, 118433, 118444, 118453, 118461, - 118470, 118478, 118494, 118505, 118514, 118522, 118534, 118545, 118561, - 118571, 118592, 118606, 118619, 118627, 118634, 8076, 118647, 118652, - 118658, 6719, 118664, 118667, 118674, 118684, 9246, 118691, 118696, - 118701, 118708, 118716, 118724, 118730, 118735, 118741, 118745, 118753, - 118762, 118770, 118775, 118784, 118791, 11398, 11407, 118797, 118808, - 118814, 118819, 118825, 3159, 3164, 118831, 1060, 118837, 118844, 118851, - 118864, 118874, 118879, 2330, 87, 118887, 118894, 118899, 118907, 118917, - 118926, 118932, 118941, 118949, 118959, 118963, 118967, 118972, 118976, - 118988, 3187, 118996, 119004, 119009, 119020, 119031, 119043, 119054, - 119064, 119073, 25981, 119078, 119084, 119089, 119099, 119109, 119114, - 34272, 119120, 119125, 119134, 26003, 119138, 26014, 119143, 4769, 8, - 119150, 119159, 119166, 119173, 119179, 119184, 119188, 119194, 34302, - 119199, 119204, 72156, 119209, 119214, 119220, 119226, 119234, 119239, - 119247, 119255, 119264, 119271, 119277, 119284, 119290, 119297, 119302, - 47505, 51837, 119308, 119318, 1828, 32, 119325, 119330, 119343, 119348, - 119356, 119361, 119367, 3213, 30840, 119372, 119380, 119387, 119392, - 119397, 119406, 4332, 4343, 73480, 119414, 119418, 1635, 1868, 119423, - 119428, 119435, 34723, 1872, 323, 119442, 119448, 119453, 3235, 119457, - 119462, 119469, 1876, 119474, 119480, 119485, 119497, 6964, 119507, - 119514, 1883, 119520, 119525, 119532, 119539, 119554, 119561, 119572, - 119577, 119585, 2778, 119589, 119601, 119606, 119610, 119616, 34144, - 2335, 119620, 119631, 119635, 119639, 119645, 119649, 119658, 119662, - 119673, 119677, 2381, 38855, 119681, 119691, 119699, 3326, 119705, - 119714, 119722, 10732, 119727, 119735, 119740, 119744, 119753, 119760, - 119766, 3296, 17764, 119770, 119783, 43923, 119801, 119806, 119814, - 119822, 119832, 11739, 15741, 119844, 119857, 119864, 119874, 119888, - 119895, 119911, 119918, 119924, 26061, 14954, 119931, 119938, 119948, - 119957, 52634, 119969, 119977, 52769, 119984, 119987, 119993, 119999, - 120005, 120011, 120017, 120024, 120031, 120037, 120043, 120049, 120055, - 120061, 120067, 120073, 120079, 120085, 120091, 120097, 120103, 120109, - 120115, 120121, 120127, 120133, 120139, 120145, 120151, 120157, 120163, - 120169, 120175, 120181, 120187, 120193, 120199, 120205, 120211, 120217, - 120223, 120229, 120235, 120241, 120247, 120253, 120259, 120265, 120271, - 120277, 120283, 120289, 120295, 120301, 120307, 120313, 120319, 120325, - 120331, 120337, 120344, 120350, 120357, 120364, 120370, 120377, 120384, - 120390, 120396, 120402, 120408, 120414, 120420, 120426, 120432, 120438, - 120444, 120450, 120456, 120462, 120468, 120474, 3310, 10700, 120480, - 120490, 120496, 120504, 120508, 117402, 3314, 120512, 113741, 25726, - 4693, 4257, 120516, 3320, 120520, 120530, 120536, 120542, 120548, 120554, - 120560, 120566, 120572, 120578, 120584, 120590, 120596, 120602, 120608, - 120614, 120620, 120626, 120632, 120638, 120644, 120650, 120656, 120662, - 120668, 120674, 120680, 120687, 120694, 120700, 120706, 120712, 120718, - 120724, 120730, 1239, 120736, 120741, 120746, 120751, 120756, 120761, - 120766, 120771, 120776, 120780, 120784, 120788, 120792, 120796, 120800, - 120804, 120808, 120812, 120818, 120824, 120830, 120836, 120840, 120844, - 120848, 120852, 120856, 120860, 120864, 120868, 120872, 120877, 120882, - 120887, 120892, 120897, 120902, 120907, 120912, 120917, 120922, 120927, - 120932, 120937, 120942, 120947, 120952, 120957, 120962, 120967, 120972, - 120977, 120982, 120987, 120992, 120997, 121002, 121007, 121012, 121017, - 121022, 121027, 121032, 121037, 121042, 121047, 121052, 121057, 121062, - 121067, 121072, 121077, 121082, 121087, 121092, 121097, 121102, 121107, - 121112, 121117, 121122, 121127, 121132, 121137, 121142, 121147, 121152, - 121157, 121162, 121167, 121172, 121177, 121182, 121187, 121192, 121197, - 121202, 121207, 121212, 121217, 121222, 121227, 121232, 121237, 121242, - 121247, 121252, 121257, 121262, 121267, 121272, 121277, 121282, 121287, - 121292, 121297, 121302, 121307, 121312, 121317, 121322, 121327, 121332, - 121337, 121342, 121347, 121352, 121357, 121362, 121367, 121372, 121377, - 121382, 121387, 121392, 121397, 121402, 121407, 121412, 121417, 121422, - 121427, 121432, 121437, 121442, 121447, 121452, 121457, 121462, 121467, - 121472, 121477, 121482, 121487, 121492, 121497, 121502, 121507, 121512, - 121517, 121522, 121527, 121532, 121537, 121542, 121547, 121552, 121557, - 121562, 121567, 121572, 121577, 121582, 121587, 121592, 121597, 121602, - 121607, 121612, 121617, 121622, 121627, 121632, 121637, 121642, 121647, - 121652, 121657, 121662, 121667, 121672, 121677, 121682, 121687, 121692, - 121697, 121702, 121707, 121712, 121717, 121722, 121727, 121732, 121737, - 121742, 121747, 121752, 121757, 121762, 121768, 121773, 121778, 121783, - 121788, 121793, 121798, 121803, 121809, 121814, 121819, 121824, 121829, - 121834, 121839, 121844, 121849, 121854, 121859, 121864, 121869, 121874, - 121879, 121884, 121889, 121894, 121899, 121904, 121909, 121914, 121919, - 121924, 121929, 121934, 121939, 121944, 121949, 121954, 121959, 121964, - 121969, 121978, 121983, 121992, 121997, 122006, 122011, 122020, 122025, - 122034, 122039, 122048, 122053, 122062, 122067, 122076, 122081, 122086, - 122095, 122099, 122108, 122113, 122122, 122127, 122136, 122141, 122150, - 122155, 122164, 122169, 122178, 122183, 122192, 122197, 122206, 122211, - 122220, 122225, 122234, 122239, 122244, 122249, 122254, 122259, 122264, - 122269, 122273, 122278, 122283, 122288, 122293, 122298, 122303, 122309, - 122314, 122319, 122324, 122330, 122334, 122339, 122345, 122350, 122355, - 122360, 122365, 122370, 122375, 122380, 122385, 122390, 122395, 122401, - 122406, 122411, 122416, 122422, 122427, 122432, 122437, 122442, 122448, - 122453, 122458, 122463, 122468, 122473, 122479, 122484, 122489, 122494, - 122499, 122504, 122509, 122514, 122519, 122524, 122529, 122534, 122539, - 122544, 122549, 122554, 122559, 122564, 122569, 122574, 122579, 122584, - 122589, 122594, 122600, 122606, 122612, 122617, 122622, 122627, 122632, - 122638, 122644, 122650, 122655, 122660, 122665, 122671, 122676, 122681, - 122686, 122691, 122696, 122701, 122706, 122711, 122716, 122721, 122726, - 122731, 122736, 122741, 122746, 122751, 122757, 122763, 122769, 122774, - 122779, 122784, 122789, 122795, 122801, 122807, 122812, 122817, 122822, - 122827, 122832, 122837, 122842, 122847, 122852, 19431, 122857, 122863, - 122868, 122873, 122878, 122883, 122888, 122894, 122899, 122904, 122909, - 122914, 122919, 122925, 122930, 122935, 122940, 122945, 122950, 122955, - 122960, 122965, 122970, 122975, 122980, 122985, 122990, 122995, 123000, - 123005, 123010, 123015, 123020, 123025, 123030, 123035, 123041, 123046, - 123051, 123056, 123061, 123066, 123071, 123076, 123081, 123086, 123091, - 123096, 123101, 123106, 123111, 123116, 123121, 123126, 123131, 123136, - 123141, 123146, 123151, 123156, 123161, 123166, 123171, 123176, 123181, - 123186, 123191, 123196, 123201, 123206, 123211, 123216, 123221, 123226, - 123231, 123236, 123241, 123247, 123252, 123257, 123262, 123267, 123272, - 123277, 123282, 123287, 123292, 123297, 123302, 123308, 123313, 123319, - 123324, 123329, 123334, 123339, 123344, 123349, 123355, 123360, 123365, - 123371, 123376, 123381, 123386, 123391, 123396, 123402, 123408, 123413, - 123418, 14588, 123423, 123428, 123433, 123438, 123443, 123448, 123453, - 123458, 123463, 123468, 123473, 123478, 123483, 123488, 123493, 123498, - 123503, 123508, 123513, 123518, 123523, 123528, 123533, 123538, 123543, - 123548, 123553, 123558, 123563, 123568, 123573, 123578, 123583, 123588, - 123593, 123598, 123603, 123608, 123613, 123618, 123623, 123628, 123633, - 123638, 123643, 123648, 123653, 123658, 123663, 123668, 123673, 123678, - 123683, 123688, 123693, 123698, 123703, 123708, 123713, 123718, 123723, - 123728, 123733, 123738, 123743, 123749, 123754, 123759, 123764, 123769, - 123775, 123780, 123785, 123790, 123795, 123800, 123805, 123811, 123816, - 123821, 123826, 123831, 123836, 123842, 123847, 123852, 123857, 123862, - 123867, 123873, 123878, 123883, 123888, 123893, 123898, 123904, 123910, - 123915, 123920, 123925, 123931, 123937, 123943, 123948, 123953, 123959, - 123965, 123970, 123976, 123982, 123988, 123993, 123998, 124004, 124009, - 124015, 124020, 124026, 124035, 124040, 124045, 124051, 124056, 124062, - 124067, 124072, 124077, 124082, 124087, 124092, 124097, 124102, 124107, - 124112, 124117, 124122, 124127, 124132, 124137, 124142, 124147, 124152, - 124157, 124162, 124167, 124172, 124177, 124182, 124187, 124192, 124197, - 124202, 124207, 124212, 124217, 124223, 124229, 124235, 124240, 124245, - 124250, 124255, 124260, 124265, 124270, 124275, 124280, 124285, 124290, - 124295, 124300, 124305, 124310, 124315, 124320, 124325, 124330, 124335, - 124341, 124347, 124352, 124358, 124363, 124368, 124374, 124379, 124385, - 124390, 124396, 124401, 124407, 124412, 124418, 124423, 124428, 124433, - 124438, 124443, 124448, 124453, 120531, 120537, 120543, 120549, 124459, - 120555, 120561, 124465, 120567, 120573, 120579, 120585, 120591, 120597, - 120603, 120609, 120615, 124471, 120621, 120627, 120633, 124477, 120639, - 120645, 120651, 120657, 124483, 120663, 120669, 120675, 120695, 124489, - 124495, 120701, 124501, 120707, 120713, 120719, 120725, 120731, 124507, - 3337, 3342, 124512, 3357, 3362, 3367, 124517, 124520, 124526, 124532, - 124539, 124544, 124549, 2386, + 113, 118, 124, 129, 137, 146, 149, 160, 165, 170, 176, 180, 189, 195, + 201, 207, 216, 224, 229, 237, 244, 177, 252, 255, 261, 262, 268, 273, + 277, 282, 289, 296, 306, 311, 317, 325, 330, 333, 339, 344, 350, 356, + 359, 365, 375, 380, 385, 390, 392, 394, 403, 405, 412, 354, 419, 427, + 436, 438, 441, 449, 454, 455, 457, 464, 472, 478, 484, 491, 496, 503, + 507, 512, 519, 524, 527, 531, 536, 542, 547, 557, 565, 572, 575, 585, + 593, 598, 606, 615, 618, 625, 629, 633, 637, 642, 645, 652, 659, 666, + 671, 676, 683, 692, 694, 703, 707, 715, 719, 727, 281, 736, 749, 753, + 758, 761, 765, 769, 771, 776, 786, 792, 796, 802, 806, 809, 814, 823, + 828, 832, 774, 838, 846, 854, 859, 868, 877, 885, 891, 902, 905, 910, + 918, 925, 928, 938, 943, 949, 953, 957, 960, 967, 974, 977, 981, 984, + 657, 990, 993, 996, 1002, 1007, 1016, 1021, 1025, 1028, 1032, 1035, 1041, + 1046, 1050, 617, 1055, 1058, 1067, 1070, 1075, 1080, 1086, 1091, 1096, + 1101, 1105, 1110, 1116, 1121, 1126, 1130, 1136, 1141, 1146, 1151, 1155, + 1160, 1165, 1170, 1176, 1182, 1188, 1193, 1197, 1202, 1207, 1212, 1216, + 1221, 1226, 1231, 1236, 1071, 1076, 1081, 1087, 1092, 1240, 1102, 1246, + 1251, 1256, 1263, 1267, 1270, 1279, 1106, 1283, 1111, 1117, 1122, 1287, + 1292, 1297, 1301, 1305, 1311, 1315, 1127, 1318, 1320, 1137, 1325, 1329, + 1142, 1335, 1147, 1339, 1343, 1350, 1152, 1354, 1362, 1367, 1371, 1374, + 1378, 1156, 1161, 1383, 1389, 1166, 1401, 1407, 1413, 1419, 1171, 1183, + 1189, 1423, 1427, 1431, 1434, 1194, 1438, 1440, 1445, 1450, 1456, 1461, + 1466, 1470, 1475, 1480, 1485, 1490, 1496, 1501, 1506, 1512, 1518, 1523, + 1527, 1532, 1537, 1542, 1547, 1552, 1556, 1564, 1569, 1573, 1578, 1583, + 1588, 1593, 1597, 1600, 1607, 1612, 1617, 1622, 1627, 1633, 1638, 1642, + 1198, 1645, 1651, 1656, 1661, 1666, 1203, 1670, 1674, 1681, 1688, 1208, + 1693, 1698, 1213, 1702, 1704, 1709, 1720, 1726, 1217, 1731, 1740, 1222, + 1745, 1751, 1756, 1761, 1771, 1780, 1788, 1227, 1798, 1807, 1816, 1821, + 1825, 1828, 1837, 1847, 1856, 1861, 1865, 1869, 1873, 1876, 1880, 1885, + 1232, 1895, 1237, 1899, 1901, 1907, 1913, 1919, 1925, 1931, 1937, 1943, + 1949, 1954, 1960, 1966, 1972, 1978, 1984, 1990, 1996, 2002, 2008, 2013, + 2018, 2023, 2028, 2033, 2038, 2043, 2048, 2053, 2058, 2064, 2069, 2075, + 2080, 2086, 2092, 2097, 2103, 2109, 2115, 2121, 2126, 2131, 2133, 2134, + 2138, 2142, 2147, 2151, 2155, 2159, 2164, 2168, 2171, 2176, 2180, 2185, + 2189, 2193, 2198, 2202, 2205, 2209, 2215, 2229, 2233, 2237, 2241, 2244, + 2249, 2253, 2257, 2260, 2264, 2269, 2274, 2279, 2284, 2288, 2292, 2296, + 2300, 2304, 2309, 2313, 2318, 2322, 2327, 2333, 2340, 2346, 2351, 2356, + 2361, 2367, 2372, 2378, 2383, 2388, 2393, 2398, 2403, 2406, 2408, 1088, + 2412, 2419, 2427, 2437, 2446, 2460, 2464, 2468, 2473, 2486, 2494, 2497, + 2501, 2504, 2509, 2513, 2516, 2520, 2524, 2529, 1715, 2534, 2538, 2541, + 2545, 2551, 2558, 2565, 2571, 2576, 2581, 2587, 2593, 2598, 2603, 2608, + 2613, 2618, 2623, 2548, 2628, 1706, 2630, 2636, 2640, 2645, 2649, 2653, + 1603, 1728, 2658, 2662, 2666, 2669, 2674, 2679, 2684, 2689, 2693, 2700, + 2705, 2708, 2712, 2716, 2723, 2729, 2733, 2739, 2743, 2747, 2752, 2759, + 2764, 2769, 2776, 2782, 2788, 2794, 2815, 2829, 2846, 2861, 2877, 2894, + 2909, 2918, 2923, 2927, 2932, 2937, 2941, 2953, 2960, 2966, 2336, 2972, + 2979, 2985, 2989, 2992, 2999, 3005, 3010, 3014, 3019, 3023, 3027, 2156, + 3031, 3036, 3041, 3045, 3050, 3058, 3062, 3069, 3074, 3078, 3082, 3086, + 3091, 3096, 3101, 3105, 3110, 3115, 3119, 3124, 3129, 3133, 3136, 3140, + 3144, 3152, 3157, 3161, 3165, 3171, 3180, 3184, 3188, 3194, 3199, 3206, + 3210, 3220, 3224, 3228, 3233, 3237, 3242, 3248, 3253, 3257, 3261, 3265, + 2561, 3273, 3278, 3284, 3289, 3293, 3298, 3303, 3307, 3313, 3318, 2160, + 3324, 3330, 3335, 3340, 3345, 3350, 3355, 3360, 3365, 3370, 3375, 3380, + 3385, 3390, 3395, 3400, 3406, 3411, 1103, 101, 3417, 3421, 3425, 3429, + 3434, 3438, 3442, 3448, 3453, 3457, 3461, 3466, 3471, 3475, 3480, 3484, + 3487, 3491, 3496, 3500, 3505, 3509, 3512, 3514, 3518, 3522, 3527, 3531, + 3534, 3547, 3551, 3555, 3559, 3564, 3568, 3572, 3575, 3579, 3583, 3588, + 3592, 3597, 3602, 3607, 3611, 3618, 3623, 3626, 3632, 3635, 3640, 3646, + 3650, 3654, 3657, 3662, 3666, 3671, 3675, 3679, 3682, 3688, 3693, 3698, + 3704, 3709, 3714, 3720, 3726, 3731, 3736, 3741, 3746, 3749, 979, 644, + 3755, 3758, 3763, 3767, 3771, 3775, 3779, 3782, 3786, 3791, 3796, 3800, + 3805, 3809, 3814, 3818, 3822, 3826, 3832, 3838, 3841, 3844, 153, 3850, + 3855, 3864, 3872, 3881, 3891, 3898, 3904, 3911, 3916, 3920, 3924, 3932, + 3939, 3944, 3949, 3956, 3961, 3965, 3975, 3979, 3983, 3988, 3993, 4003, + 2172, 4008, 4012, 4015, 4021, 4026, 4032, 4038, 4043, 4050, 4054, 4058, + 4062, 4067, 4072, 4077, 4082, 4087, 4092, 634, 616, 1264, 4097, 4104, + 4111, 4117, 4126, 4131, 4138, 4145, 4150, 4156, 4162, 4167, 4172, 4176, + 4182, 4189, 4194, 4198, 4202, 2181, 4208, 4216, 4222, 4230, 863, 4236, + 4244, 4255, 4259, 4269, 4275, 4280, 4285, 4290, 4295, 2186, 4300, 4305, + 4320, 4326, 4333, 4344, 4354, 4360, 4365, 4371, 4377, 4380, 4383, 4387, + 4392, 4395, 4402, 4411, 4416, 4420, 4424, 4428, 4432, 4437, 4443, 4454, + 4458, 3492, 4463, 4475, 4481, 4489, 4493, 4498, 4505, 4510, 4515, 4520, + 1472, 4525, 4528, 4531, 4535, 4538, 4544, 4548, 4562, 4566, 4569, 4573, + 4579, 4585, 4590, 4594, 4598, 4604, 4615, 4621, 4626, 4632, 4636, 4644, + 4656, 4666, 4672, 4677, 4686, 4694, 4705, 4712, 4718, 4724, 4728, 4734, + 4743, 4752, 4757, 4763, 4767, 4776, 4782, 4787, 4791, 4796, 4800, 4808, + 4814, 4818, 4825, 4830, 4834, 4840, 4846, 4853, 2194, 4862, 4873, 4883, + 4892, 4897, 4902, 4907, 4912, 1280, 4917, 4919, 4924, 4930, 4935, 4940, + 4945, 4950, 4955, 4960, 4966, 4971, 4977, 4982, 4987, 4992, 4998, 5003, + 5008, 5013, 5018, 5024, 5029, 5035, 5040, 5045, 5050, 5055, 5060, 5065, + 5071, 5076, 5081, 348, 389, 5086, 5092, 5095, 5099, 5103, 5110, 5116, + 5121, 5125, 5129, 5132, 5135, 5139, 5143, 5146, 5150, 5154, 5158, 5163, + 5167, 5171, 5177, 5186, 4843, 5191, 5195, 5198, 5203, 5208, 5213, 5218, + 5223, 5228, 5233, 5238, 5243, 5248, 5252, 5257, 5262, 5267, 5272, 5277, + 5282, 5287, 5292, 5297, 5302, 5306, 5311, 5316, 5321, 5326, 5331, 5336, + 5341, 5346, 5351, 5356, 5360, 5365, 5370, 5375, 5380, 5385, 5390, 5395, + 5400, 5405, 5410, 5414, 5419, 5424, 5429, 5434, 5439, 5444, 5449, 5454, + 5459, 5464, 5468, 5473, 5478, 5483, 5488, 5493, 5498, 5503, 5508, 5513, + 5518, 5522, 5527, 5532, 5537, 5542, 5547, 5552, 5557, 5562, 5567, 5572, + 5576, 5581, 5586, 5591, 5596, 5602, 5608, 5614, 5620, 5626, 5632, 5638, + 5643, 5649, 5655, 5661, 5667, 5673, 5679, 5685, 5691, 5697, 5703, 5708, + 5714, 5720, 5726, 5732, 5738, 5744, 5750, 5756, 5762, 5768, 5773, 5779, + 5785, 5791, 5797, 5803, 5809, 5815, 5821, 5827, 5833, 5838, 5844, 5850, + 5856, 5862, 5868, 5874, 5880, 5886, 5892, 5898, 5903, 5909, 5915, 5921, + 5927, 5933, 5939, 5945, 5951, 5957, 5963, 5968, 5972, 5978, 5984, 5990, + 5996, 6002, 6008, 6014, 6020, 6026, 6032, 6037, 6043, 6049, 6055, 6061, + 6067, 6073, 6079, 6085, 6091, 6097, 6102, 6108, 6114, 6120, 6126, 6132, + 6138, 6144, 6150, 6156, 6162, 6167, 6173, 6179, 6185, 6191, 6197, 6203, + 6209, 6215, 6221, 6227, 6232, 6238, 6244, 6250, 6256, 6262, 6268, 6274, + 6280, 6286, 6292, 6297, 6303, 6309, 6315, 6321, 6327, 6333, 6339, 6345, + 6351, 6357, 6362, 6368, 6374, 6380, 6386, 6392, 6398, 6404, 6410, 6416, + 6422, 6427, 6433, 6439, 6445, 6451, 6457, 6463, 6469, 6475, 6481, 6487, + 6492, 6498, 6504, 6510, 6516, 6522, 6528, 6534, 6540, 6546, 6552, 6557, + 6563, 6569, 6575, 6581, 6587, 6593, 6599, 6605, 6611, 6617, 6622, 6626, + 6629, 6637, 6644, 6647, 6651, 6664, 6668, 6672, 6676, 6679, 6683, 6688, + 6692, 6701, 6705, 6711, 6718, 6729, 6737, 6744, 6750, 6754, 6762, 6771, + 6777, 6781, 6793, 6798, 6801, 6806, 6810, 6820, 6828, 6836, 6844, 6850, + 6854, 6864, 6874, 6882, 6889, 6896, 6902, 6908, 6915, 6919, 6926, 6936, + 6946, 6954, 6961, 6966, 6970, 6974, 6982, 6986, 6996, 7001, 7008, 7015, + 7023, 7033, 7038, 7042, 7047, 7051, 7058, 7063, 7077, 7082, 7087, 7094, + 3768, 7103, 7107, 7111, 7116, 7120, 7124, 7127, 7132, 7137, 7146, 7152, + 7158, 7163, 7169, 7173, 7184, 7194, 7209, 7224, 7239, 7254, 7269, 7284, + 7299, 7314, 7329, 7344, 7359, 7374, 7389, 7404, 7419, 7434, 7449, 7464, + 7479, 7494, 7509, 7524, 7539, 7554, 7569, 7584, 7599, 7614, 7629, 7644, + 7659, 7674, 7689, 7704, 7719, 7734, 7749, 7764, 7779, 7794, 7809, 7824, + 7839, 7854, 7869, 7884, 7899, 7914, 7929, 7938, 7947, 7952, 7958, 7968, + 7972, 7976, 7981, 7986, 7991, 7999, 8003, 8006, 8010, 3215, 8013, 8018, + 353, 534, 8024, 8027, 8035, 8039, 8043, 8046, 8050, 8056, 8060, 8068, + 8074, 8079, 8086, 8094, 8101, 8107, 8112, 8119, 8125, 8134, 8142, 8146, + 8151, 8159, 8171, 8182, 8189, 8200, 8204, 8208, 8212, 8215, 8221, 3519, + 8225, 8227, 8233, 8238, 8243, 8248, 8254, 8259, 8264, 8269, 8274, 8280, + 8285, 8290, 8296, 8301, 8307, 8312, 8318, 8323, 8329, 8334, 8339, 8344, + 8349, 8354, 8360, 8365, 8370, 8375, 8381, 8387, 8393, 8399, 8405, 8411, + 8417, 8423, 8429, 8435, 8441, 8447, 8452, 8457, 8462, 8467, 8472, 8477, + 8482, 8487, 8493, 8499, 8504, 8510, 8516, 8522, 8528, 8533, 8538, 8543, + 8548, 8554, 8560, 8565, 8570, 8575, 8580, 8585, 8591, 8596, 8602, 8608, + 8614, 8620, 8626, 8632, 8638, 8644, 8650, 2203, 8045, 8655, 8659, 8667, + 8671, 8674, 8677, 8683, 8690, 1107, 8693, 8697, 8705, 8710, 8715, 8706, + 8720, 2230, 8724, 8730, 8736, 8741, 8746, 8753, 8761, 8766, 8770, 8773, + 8777, 8783, 8789, 8793, 1653, 631, 8796, 8800, 8805, 8811, 8816, 8820, + 8823, 8827, 8833, 8838, 8842, 8849, 8853, 8857, 8861, 773, 8681, 2254, + 8864, 8872, 8879, 8886, 8892, 8899, 8907, 8914, 8925, 8932, 8938, 8950, + 1123, 1288, 1293, 8961, 8965, 1298, 8969, 8973, 8982, 8990, 8994, 9003, + 9009, 9015, 9020, 9024, 9030, 9035, 9043, 9050, 2914, 9057, 9063, 9067, + 9076, 9085, 9094, 9103, 9109, 9114, 9119, 9130, 9139, 9151, 9156, 9164, + 2289, 9168, 9170, 9175, 9179, 9188, 9196, 1302, 168, 3810, 3815, 9202, + 9206, 9215, 9221, 9226, 9229, 9233, 9237, 9242, 9247, 9252, 9257, 9261, + 9270, 9276, 2301, 9280, 2906, 9284, 9292, 9296, 9300, 2305, 9304, 9308, + 9312, 9316, 9320, 2310, 9324, 9329, 9336, 9342, 9349, 9355, 9358, 9254, + 9360, 9368, 9376, 9384, 9387, 9392, 2323, 9397, 8717, 9400, 9402, 9407, + 9412, 9417, 9422, 9427, 9432, 9437, 9442, 9447, 9452, 9458, 9463, 9468, + 9473, 9479, 9484, 9489, 9494, 9499, 9504, 9509, 9515, 9520, 9525, 9530, + 9535, 9540, 9545, 9550, 9555, 9560, 9565, 9570, 9575, 9580, 9585, 9590, + 9595, 9600, 9606, 9612, 9617, 9622, 9627, 9632, 9637, 2334, 2341, 2347, + 9642, 9650, 9656, 9664, 2373, 2379, 9672, 2384, 2389, 2394, 2399, 9676, + 9680, 9685, 9689, 9693, 9697, 9702, 9706, 9711, 9715, 9718, 9721, 9727, + 9734, 9740, 9747, 9753, 9760, 9766, 9773, 9779, 9785, 9794, 9800, 9804, + 9808, 9812, 9816, 9821, 9825, 9830, 9834, 9840, 9844, 9849, 9856, 9867, + 9875, 9885, 9891, 9901, 9910, 9917, 9922, 9926, 9937, 9947, 9960, 9971, + 9984, 9995, 10007, 10019, 10031, 10042, 10055, 10068, 10075, 10081, + 10092, 10102, 10116, 10123, 10129, 10138, 10146, 10150, 10155, 10159, + 10166, 10174, 10181, 10185, 10191, 10195, 10201, 10211, 10215, 10220, + 10225, 10232, 10238, 8894, 10248, 10252, 10259, 10265, 10272, 10279, + 10283, 10286, 10292, 10296, 10301, 10306, 10311, 10315, 10321, 10329, + 10336, 10342, 10346, 10349, 10355, 10365, 10369, 10375, 10380, 10384, + 10389, 10393, 10399, 10405, 10410, 10416, 10421, 10426, 10431, 2226, + 10436, 10438, 10443, 10451, 10460, 10464, 10470, 10475, 10480, 10485, + 10490, 10496, 10501, 10506, 4600, 10511, 10516, 10520, 10526, 10531, + 10537, 10542, 10547, 10553, 10558, 10465, 10564, 10568, 10575, 10581, + 10586, 10590, 7073, 10595, 10604, 10609, 10614, 9332, 9339, 10619, 3088, + 10623, 10628, 10633, 10638, 10476, 10642, 10647, 10652, 10481, 10656, + 10486, 10661, 10668, 10675, 10681, 10688, 10694, 10700, 10705, 10712, + 10717, 10722, 10727, 10733, 10491, 10497, 10739, 10744, 10750, 10755, + 10760, 10768, 1358, 10773, 1048, 10776, 10784, 10800, 10816, 10831, + 10839, 10845, 10851, 10860, 10868, 10876, 10884, 10892, 10900, 10908, + 10916, 10924, 10933, 10942, 10950, 10959, 10968, 10977, 10986, 10995, + 11004, 11013, 11022, 11031, 11040, 11048, 11053, 11057, 11063, 11071, + 11078, 11093, 11110, 11129, 11138, 11146, 11161, 11172, 11180, 11186, + 11196, 11206, 11214, 11220, 11232, 11241, 11249, 11256, 11263, 11270, + 11276, 11281, 11291, 11297, 11305, 11315, 11322, 11332, 11342, 11352, + 11360, 11367, 11376, 11386, 11400, 11415, 11424, 11432, 11437, 11441, + 11451, 11461, 11473, 11482, 11488, 11493, 11503, 11513, 11523, 11528, + 11532, 11542, 11551, 11556, 11572, 11589, 11599, 11604, 11615, 11628, + 11639, 11647, 11660, 11672, 11680, 11685, 11689, 11695, 11700, 11708, + 11716, 11723, 11734, 11739, 11747, 11757, 11763, 11767, 11770, 11776, + 11780, 11786, 11793, 11797, 11805, 11814, 11822, 11829, 11834, 11838, + 11843, 11847, 11851, 11859, 11874, 11890, 11896, 11904, 11913, 11921, + 11927, 11931, 11938, 11949, 11953, 11956, 11967, 11973, 11978, 10507, + 11986, 11992, 11999, 12005, 12010, 12017, 12024, 12031, 12038, 12045, + 12052, 12059, 12066, 12073, 12080, 12087, 12094, 12101, 12108, 12115, + 12120, 11106, 12125, 12131, 12138, 12145, 12150, 12157, 12166, 12170, + 12177, 12189, 12193, 12199, 12204, 12209, 12214, 12219, 12224, 12229, + 12232, 12236, 11457, 12240, 12244, 12250, 12256, 12261, 12267, 12272, + 12277, 12283, 12288, 12293, 10228, 12298, 12302, 12306, 12310, 12315, + 12320, 12325, 12333, 12339, 12344, 12348, 12352, 12359, 12364, 12372, + 12379, 12384, 12388, 12391, 12397, 12404, 12408, 12411, 12416, 12420, + 4639, 12426, 12435, 46, 12443, 12449, 12454, 12459, 12467, 12474, 12479, + 6991, 12485, 12491, 12496, 12500, 12503, 12509, 12517, 12524, 12539, + 12558, 12570, 12583, 12596, 12609, 12623, 12636, 12651, 12658, 10512, + 12664, 12678, 12683, 12689, 12694, 12702, 12707, 9072, 12712, 12715, + 12723, 12730, 12735, 12739, 12745, 12749, 12754, 12759, 12764, 12769, + 12774, 12779, 3093, 11194, 12784, 12788, 12794, 12800, 12805, 12811, + 12816, 10521, 12822, 12828, 12833, 12838, 12846, 12852, 12865, 12873, + 12880, 12886, 10527, 12892, 12900, 12908, 12915, 12928, 12941, 12953, + 12963, 12975, 13003, 13011, 13020, 13027, 13039, 13046, 13056, 13065, + 13073, 13080, 13085, 13091, 10532, 13096, 13102, 13107, 13112, 13117, + 10538, 13122, 13125, 13132, 13138, 13152, 13165, 13176, 9860, 13187, + 13193, 13202, 13210, 13217, 13223, 13234, 13240, 13245, 13253, 4113, + 13259, 13264, 12531, 13270, 13277, 13282, 10543, 13288, 13293, 13300, + 13306, 13312, 13317, 13325, 13333, 13340, 13344, 13356, 13370, 13380, + 13385, 13389, 13400, 13406, 13411, 13416, 10548, 13420, 10554, 13425, + 13428, 13433, 13445, 13452, 13457, 13461, 13469, 13474, 13478, 13483, + 13487, 13494, 13500, 10559, 10466, 13507, 3098, 17, 13514, 13519, 13523, + 13527, 13533, 13541, 13551, 13556, 13561, 13568, 13575, 13579, 13590, + 13600, 13609, 13618, 13630, 13635, 13639, 13647, 13661, 13665, 13668, + 13672, 13680, 13687, 13695, 13699, 13710, 13718, 13722, 13729, 13734, + 13738, 13744, 13749, 13755, 13760, 13765, 13769, 13775, 13780, 13791, + 13795, 13798, 13804, 13811, 13817, 13822, 13828, 13834, 13841, 13852, + 13862, 13872, 13881, 13888, 13897, 13901, 10569, 10576, 10582, 10587, + 13907, 13913, 13919, 13924, 13930, 10591, 13936, 13939, 13946, 13951, + 13957, 13962, 13977, 13993, 14008, 14016, 14021, 14028, 14034, 14038, + 14043, 14048, 14053, 14058, 14063, 14068, 14073, 14078, 14083, 1561, 383, + 14088, 14096, 14103, 14109, 14114, 14119, 10596, 14121, 14125, 14130, + 14134, 14144, 14149, 14153, 14156, 14165, 14169, 14172, 14179, 10605, + 14184, 14187, 14195, 14202, 14210, 14214, 14220, 14228, 14232, 14239, + 14248, 14255, 14251, 14262, 14266, 14272, 14276, 14280, 14284, 14290, + 14296, 14306, 14314, 14321, 14325, 14333, 14338, 14342, 14349, 14354, + 14361, 14365, 14370, 14375, 14379, 14386, 14392, 14400, 14406, 14411, + 14421, 14428, 14433, 14438, 14442, 14446, 14454, 4469, 14462, 14467, + 10610, 14471, 14478, 14482, 14485, 14493, 14500, 14504, 14507, 6846, + 14511, 14516, 14521, 14525, 14536, 14546, 14551, 14557, 14562, 14571, + 14575, 14578, 14586, 14591, 14596, 14603, 14608, 4865, 10615, 14613, + 14617, 14624, 14629, 14634, 14639, 7021, 14644, 14649, 14654, 14659, + 14665, 14670, 14676, 14681, 14686, 14691, 14696, 14701, 14706, 14711, + 14716, 14721, 14726, 14731, 14736, 14741, 14746, 14751, 14756, 14762, + 14767, 14772, 14777, 14782, 14787, 14793, 14798, 14803, 14809, 14814, + 14820, 14825, 14831, 14836, 14841, 14846, 14851, 14857, 14862, 14867, + 14872, 14880, 988, 112, 14886, 14890, 14895, 14900, 14904, 14908, 14912, + 14917, 14921, 14926, 14930, 14933, 14937, 14941, 14947, 14952, 14962, + 14968, 14976, 14982, 14986, 14990, 14997, 15005, 15014, 15025, 15035, + 15042, 15049, 15053, 15062, 15071, 15079, 15086, 15095, 15104, 15113, + 15122, 15132, 15142, 15152, 15162, 15172, 15181, 15191, 15201, 15211, + 15221, 15231, 15241, 15251, 15260, 15270, 15280, 15290, 15300, 15310, + 15320, 15329, 15339, 15349, 15359, 15369, 15379, 15389, 15399, 15409, + 15419, 15428, 15438, 15448, 15458, 15468, 15478, 15488, 15498, 15508, + 15518, 15528, 15537, 15543, 1132, 15547, 15550, 15554, 15559, 15566, + 15572, 15577, 15581, 15586, 15595, 15604, 15612, 15617, 15621, 15625, + 15631, 15636, 15642, 10624, 15647, 15652, 15661, 15666, 10634, 15671, + 11444, 11454, 11464, 15674, 15680, 15688, 10639, 15695, 15699, 15703, + 15709, 15714, 15718, 15728, 15734, 15740, 15745, 15754, 15762, 15769, + 15776, 15781, 15788, 15793, 15797, 15800, 15811, 15821, 15834, 15843, + 15851, 15862, 15874, 15884, 15894, 15899, 15903, 15908, 15913, 15917, + 15923, 15931, 15938, 15949, 15954, 15964, 15973, 15977, 15980, 15987, + 15997, 16006, 16013, 16017, 16024, 16030, 16035, 16040, 16044, 15590, + 16053, 16057, 16063, 16067, 16072, 16076, 16083, 16090, 16094, 16103, + 16111, 16119, 16126, 16134, 16146, 16157, 16167, 16174, 16180, 16189, + 16200, 16209, 16221, 16233, 16245, 16255, 16264, 16274, 16283, 16291, + 16298, 16308, 16317, 16325, 16329, 16334, 16340, 16346, 16351, 16356, + 16360, 16365, 16370, 16375, 16380, 16385, 16390, 16395, 8738, 16400, + 16402, 16406, 16411, 16417, 16424, 16430, 16436, 16445, 16449, 16455, + 16463, 16470, 16479, 16488, 16497, 16506, 16515, 16524, 16533, 16542, + 16552, 16562, 16571, 16577, 16584, 16591, 16597, 16611, 16617, 16624, + 16632, 16641, 16649, 16655, 16664, 16670, 16679, 16690, 16696, 16706, + 16714, 16721, 16729, 16737, 16744, 16753, 16766, 16775, 16783, 16790, + 16803, 16809, 16815, 16825, 16834, 16843, 16852, 16860, 16865, 16869, + 16875, 16881, 16886, 16893, 16900, 10242, 16905, 16910, 16917, 16925, + 16930, 16942, 16949, 16954, 16966, 14943, 16971, 16977, 16985, 16991, + 16996, 17004, 17012, 17019, 17027, 17034, 17040, 17046, 17054, 17062, + 17068, 17076, 17082, 17087, 17093, 17100, 17106, 17111, 17115, 17126, + 17134, 17142, 17148, 17153, 17160, 17169, 17175, 17180, 17188, 17195, + 17204, 17218, 4413, 17222, 17227, 17232, 17238, 17243, 17248, 17252, + 17257, 17262, 17267, 8737, 17272, 17277, 17282, 17287, 17292, 17296, + 17301, 17306, 17311, 17316, 17322, 17328, 14216, 17333, 17339, 17344, + 17349, 17354, 10643, 17359, 17364, 17369, 17374, 17379, 17393, 17410, + 17428, 17440, 17453, 17470, 17486, 17503, 17513, 17532, 17543, 17554, + 17565, 2803, 17576, 17587, 17598, 17615, 17626, 17637, 17642, 10648, + 17647, 17651, 2483, 17655, 17661, 17664, 17670, 17678, 17686, 17692, + 17701, 17708, 17713, 17721, 17729, 17736, 17740, 17745, 17751, 17758, + 17766, 17773, 17785, 17792, 17798, 17806, 17811, 17817, 17823, 17828, + 13971, 17835, 17839, 17848, 17854, 17859, 17867, 17876, 17884, 17891, + 17897, 17905, 17912, 17918, 17924, 17931, 17938, 17944, 17950, 17954, + 17963, 17971, 17976, 17986, 17993, 17999, 18007, 18013, 18021, 18029, + 18036, 18049, 18053, 18060, 18069, 18078, 18087, 18095, 18105, 18112, + 18117, 3969, 18124, 18129, 1248, 18133, 18140, 17273, 18144, 18150, + 18154, 18162, 18174, 18179, 18186, 18192, 18197, 18204, 17278, 18208, + 18212, 18220, 18225, 18229, 17283, 18233, 17288, 18237, 18244, 18249, + 18253, 18260, 18264, 18267, 18275, 18282, 18287, 18295, 18299, 18306, + 18323, 18332, 18341, 18345, 18348, 18354, 18362, 18368, 18373, 18377, + 18382, 18387, 18392, 18397, 18402, 18407, 4047, 18412, 18414, 18422, + 18429, 18439, 18451, 18456, 18460, 18466, 18471, 18479, 18483, 18489, + 18494, 18500, 18503, 18510, 18518, 18525, 18531, 18536, 18542, 18547, + 18554, 18560, 18565, 18575, 18584, 18591, 18596, 18600, 18606, 18612, + 18616, 18623, 18629, 18634, 18640, 18648, 18656, 18663, 18669, 18675, + 18680, 18686, 18692, 18700, 18705, 18710, 18718, 18724, 18730, 18735, + 18742, 18747, 18751, 18757, 18763, 18768, 18774, 18781, 18786, 18792, + 18795, 18801, 18812, 18818, 18827, 18830, 18834, 18838, 18852, 18865, + 18877, 18883, 18888, 18895, 18901, 18907, 18918, 18930, 18942, 18952, + 18961, 18969, 18976, 18987, 18997, 19007, 19015, 19018, 17302, 19023, + 19028, 19035, 17307, 17458, 19043, 19056, 19071, 19082, 17475, 19100, + 19113, 19126, 19137, 12546, 19148, 19161, 19180, 19191, 19202, 19213, + 2824, 19226, 19230, 19238, 19249, 19260, 19268, 19283, 19298, 19309, + 19316, 19322, 19330, 19334, 19340, 19344, 19347, 19360, 19372, 19382, + 19390, 19397, 19405, 19415, 19420, 19427, 19432, 19439, 19450, 19460, + 19466, 19471, 19476, 17312, 19480, 19486, 19493, 19499, 19504, 19509, + 19514, 19518, 17317, 17323, 19522, 17329, 19527, 19535, 19540, 19544, + 19551, 19559, 19566, 19575, 19582, 19586, 19590, 19595, 19600, 19605, + 19610, 19615, 10487, 19620, 19622, 19627, 19632, 19638, 19643, 19648, + 19653, 19658, 19662, 19668, 19674, 19679, 19685, 19690, 19695, 19699, + 19705, 19710, 19714, 19719, 19724, 19736, 19741, 19747, 19752, 19757, + 19763, 19769, 19774, 19779, 19784, 19791, 19797, 19808, 19815, 19824, + 19829, 19833, 279, 19837, 19845, 19850, 19856, 19862, 19867, 19874, + 19881, 19887, 19892, 19898, 19903, 19908, 19913, 19920, 19930, 19938, + 19943, 19948, 19955, 19961, 19970, 19980, 19990, 20004, 20018, 20032, + 20046, 20061, 20076, 20093, 20111, 20124, 20130, 20135, 20140, 20144, + 20152, 20157, 20165, 20171, 20177, 20182, 20187, 20191, 20197, 20202, + 20206, 20213, 20218, 20222, 20233, 20239, 20244, 20249, 20256, 20261, + 20265, 3927, 20270, 20276, 20283, 17334, 20289, 20293, 20299, 20304, + 20309, 20313, 20319, 20324, 20329, 20336, 20341, 15730, 20345, 20350, + 20354, 20359, 20365, 20371, 20378, 20388, 20396, 20403, 20408, 20412, + 20421, 20429, 20436, 20443, 20449, 20454, 20460, 20465, 20470, 20476, + 20481, 20487, 20492, 20498, 20504, 20511, 20517, 20522, 20527, 10713, + 20536, 20539, 20547, 20553, 20558, 20563, 20573, 20580, 20586, 20591, + 20596, 20602, 20607, 20613, 20618, 20624, 20631, 20637, 20643, 20648, + 20656, 20663, 20668, 20673, 20679, 20684, 20688, 20697, 20708, 20715, + 20722, 20730, 20737, 20744, 20749, 20754, 20760, 20765, 20773, 20779, + 20785, 20790, 20797, 20803, 20808, 20812, 20818, 20823, 20828, 20832, + 20837, 1321, 8762, 3112, 20841, 20845, 20849, 20853, 20857, 20861, 20864, + 20869, 20876, 20884, 20894, 20905, 20915, 20926, 20938, 20949, 20959, + 20970, 20982, 20993, 21005, 21018, 21030, 21041, 21051, 21062, 21074, + 21085, 21098, 21110, 21121, 21133, 21146, 21158, 21171, 21185, 21198, + 21210, 21221, 21231, 21242, 21254, 21265, 21277, 21290, 21302, 21313, + 21325, 21338, 21351, 21365, 21378, 21390, 21401, 21413, 21426, 21438, + 21451, 21465, 21478, 21490, 21503, 21517, 21530, 21544, 21558, 21571, + 21583, 21594, 21604, 17345, 21611, 21617, 21627, 21635, 21642, 21650, + 21660, 21669, 21682, 21687, 21692, 21700, 21707, 15839, 15848, 21714, + 21724, 21739, 21745, 21752, 21759, 21766, 21772, 21778, 21789, 21797, + 21805, 21815, 21825, 21834, 17350, 21843, 21849, 21855, 21864, 21872, + 21880, 21885, 21894, 21902, 21914, 21924, 21934, 21944, 21953, 21965, + 21975, 21985, 21996, 22003, 22008, 22015, 22027, 22039, 22051, 22063, + 22075, 22087, 22099, 22111, 22123, 22135, 22146, 22158, 22170, 22182, + 22194, 22206, 22218, 22230, 22242, 22254, 22266, 22277, 22289, 22301, + 22313, 22325, 22337, 22349, 22361, 22373, 22385, 22397, 22408, 22420, + 22432, 22444, 22456, 22468, 22480, 22492, 22504, 22516, 22528, 22539, + 22551, 22563, 22575, 22587, 22599, 22611, 22623, 22635, 22647, 22659, + 22670, 22682, 22694, 22706, 22718, 22730, 22742, 22754, 22766, 22778, + 22790, 22801, 22813, 22825, 22837, 22849, 22861, 22873, 22885, 22897, + 22909, 22921, 22932, 22944, 22956, 22968, 22980, 22993, 23006, 23019, + 23032, 23045, 23058, 23071, 23083, 23096, 23109, 23122, 23135, 23148, + 23161, 23174, 23187, 23200, 23213, 23225, 23238, 23251, 23264, 23277, + 23290, 23303, 23316, 23329, 23342, 23355, 23367, 23380, 23393, 23406, + 23419, 23432, 23445, 23458, 23471, 23484, 23497, 23509, 23522, 23535, + 23548, 23561, 23574, 23587, 23600, 23613, 23626, 23639, 23651, 23664, + 23677, 23690, 23703, 23716, 23729, 23742, 23755, 23768, 23781, 23793, + 23804, 23817, 23830, 23843, 23856, 23869, 23882, 23895, 23908, 23921, + 23934, 23946, 23959, 23972, 23985, 23998, 24011, 24024, 24037, 24050, + 24063, 24076, 24088, 24101, 24114, 24127, 24140, 24153, 24166, 24179, + 24192, 24205, 24218, 24230, 24243, 24256, 24269, 24282, 24295, 24308, + 24321, 24334, 24347, 24360, 24372, 24385, 24398, 24411, 24424, 24437, + 24450, 24463, 24476, 24489, 24502, 24514, 24527, 24540, 24553, 24566, + 24579, 24592, 24605, 24618, 24631, 24644, 24656, 24669, 24682, 24695, + 24708, 24721, 24734, 24747, 24760, 24773, 24786, 24798, 24811, 24824, + 24837, 24850, 24863, 24876, 24889, 24902, 24915, 24928, 24940, 24953, + 24966, 24979, 24992, 25005, 25018, 25031, 25044, 25057, 25070, 25082, + 25095, 25108, 25121, 25134, 25147, 25160, 25173, 25186, 25199, 25212, + 25224, 25235, 25244, 25252, 25260, 25267, 25273, 25277, 25283, 25289, + 25298, 25306, 25311, 25317, 25322, 25326, 25335, 10492, 25346, 25352, + 25359, 25367, 25374, 13145, 13159, 25381, 25388, 25397, 25402, 25407, + 25414, 25419, 25424, 8778, 8784, 8790, 25429, 25434, 25437, 25442, 25450, + 25457, 25464, 25476, 25483, 25489, 25498, 25503, 25512, 25521, 25527, + 25535, 25544, 25548, 25554, 25559, 25569, 25576, 25582, 25590, 25596, + 25603, 25609, 25619, 25628, 25632, 25639, 25643, 25648, 25654, 25662, + 25666, 25676, 17360, 25685, 25691, 25695, 25704, 25713, 25723, 25729, + 17365, 25736, 25743, 25754, 25762, 25772, 25781, 25789, 10207, 25797, + 25802, 25808, 25813, 25817, 25821, 25825, 11301, 25830, 25838, 25845, + 25854, 25862, 25869, 25876, 25885, 25891, 1062, 25898, 25904, 25908, + 25914, 25921, 25927, 25935, 25941, 25948, 25954, 25960, 25969, 25973, + 25981, 25989, 25996, 26005, 26012, 26017, 26021, 26031, 26042, 26053, + 26058, 26063, 26069, 26078, 26083, 26096, 9000, 26100, 26106, 26112, + 26118, 26123, 26131, 26135, 26142, 26151, 26156, 17638, 26164, 26168, + 26180, 26185, 26189, 26192, 26198, 26204, 26210, 26215, 26220, 26224, + 26227, 26238, 26243, 10769, 26250, 26255, 26260, 26265, 26270, 26275, + 26280, 26285, 26290, 10774, 26295, 26300, 26305, 26310, 26315, 26320, + 26325, 26330, 26335, 26340, 26345, 26350, 26356, 26361, 26366, 26371, + 26376, 26381, 26386, 26391, 26396, 26401, 26407, 26413, 26418, 26423, + 26428, 26433, 26438, 26443, 26448, 26453, 26458, 26464, 26469, 26474, + 26479, 26485, 26491, 26496, 26501, 26506, 26511, 26516, 26521, 26526, + 26531, 26537, 26542, 26547, 26552, 26557, 26563, 26568, 26573, 26577, + 1244, 145, 26585, 26589, 26593, 26597, 26602, 26606, 15736, 2409, 26610, + 26615, 26619, 26624, 26628, 26633, 26637, 26643, 26648, 26652, 26656, + 26664, 26668, 26672, 26679, 26684, 26689, 26693, 26699, 26704, 26708, + 26713, 26718, 26722, 26729, 26736, 26743, 26748, 26752, 26756, 26761, + 26765, 26768, 26774, 26787, 26792, 26798, 26807, 26812, 11049, 26817, + 26826, 26831, 26834, 26838, 26843, 26848, 26853, 26858, 26863, 2920, + 2925, 26868, 26874, 26878, 26884, 3888, 26889, 26894, 26899, 26905, + 26910, 16686, 26915, 26920, 26925, 26930, 26936, 26941, 26946, 26952, + 26957, 26961, 26966, 26971, 26976, 26981, 26986, 26990, 26995, 26999, + 27004, 27009, 27014, 27019, 27023, 27028, 27032, 27037, 27042, 27047, + 26962, 3121, 26967, 27052, 27060, 27067, 11395, 27079, 27087, 27097, + 27115, 27134, 27143, 27151, 26972, 27158, 27163, 27171, 26977, 27176, + 27181, 27189, 27194, 27199, 27203, 19858, 27208, 27216, 27221, 27225, + 27232, 27238, 27247, 27251, 27259, 27265, 27269, 27272, 20692, 27279, + 27283, 27287, 27292, 27298, 27305, 27310, 10234, 27314, 27319, 27324, + 27329, 27334, 27339, 1663, 1668, 27344, 27350, 27356, 27361, 27365, + 27369, 27373, 27377, 27381, 27385, 27389, 27393, 25470, 27396, 27403, + 27411, 27417, 27423, 27428, 27433, 27439, 27443, 27448, 27455, 16586, + 16593, 27461, 27473, 27476, 27483, 27487, 19883, 27494, 27502, 27513, + 27522, 27535, 27545, 27559, 27571, 27585, 27598, 27610, 27620, 27632, + 27638, 27653, 27677, 27695, 27714, 27727, 27741, 27759, 27775, 27792, + 27810, 27821, 27840, 27857, 27877, 27895, 27907, 27921, 27935, 27947, + 27964, 27983, 28001, 28013, 28031, 28050, 17518, 28063, 28083, 28095, + 12577, 28107, 28112, 28117, 28122, 28131, 28137, 28142, 28146, 28153, + 28159, 28163, 28168, 28173, 28178, 28183, 28188, 28193, 2506, 28198, + 28204, 28208, 28211, 28222, 28226, 28229, 28237, 28243, 14882, 28247, + 28256, 28267, 28273, 28279, 28294, 28303, 28311, 28318, 28323, 28327, + 28334, 28340, 28349, 28357, 28364, 28374, 28383, 28393, 28398, 28407, + 28416, 28427, 28438, 28448, 28465, 4557, 28475, 28479, 28489, 28497, + 28507, 28518, 28524, 28529, 28539, 28547, 28554, 28560, 28567, 28572, + 27010, 28576, 28585, 28589, 28592, 28597, 28605, 28612, 28621, 28629, + 28637, 28645, 28655, 28664, 28670, 28676, 28682, 28686, 27015, 27020, + 28690, 28700, 28710, 28720, 28728, 28735, 28745, 28753, 28761, 28767, + 28775, 798, 28784, 17725, 649, 28798, 28807, 28815, 28826, 28837, 28847, + 28856, 28868, 28877, 28886, 28893, 28899, 28909, 28918, 28927, 28935, + 28943, 28953, 28961, 28969, 28976, 28982, 28987, 28992, 28997, 8156, + 29002, 29005, 29009, 29014, 29022, 29028, 29033, 29037, 3751, 27033, + 29045, 27038, 29051, 29057, 29063, 29068, 29073, 29077, 29085, 29091, + 29097, 29101, 3912, 29109, 29114, 29119, 29123, 29127, 11681, 29134, + 29142, 29156, 29163, 29170, 29176, 11690, 11696, 29184, 29192, 29199, + 29204, 29209, 27043, 29215, 29226, 29235, 19031, 29243, 29248, 2755, + 29253, 29264, 29270, 29275, 29279, 29283, 29286, 29293, 29300, 29306, + 29314, 29321, 29327, 29331, 8196, 29336, 29340, 29344, 29352, 29357, + 29362, 29367, 1696, 29372, 29377, 29382, 29387, 29392, 29397, 29402, + 29407, 29412, 29417, 29422, 29427, 29432, 29437, 29443, 29448, 29453, + 29458, 29463, 29468, 29473, 29479, 29484, 29489, 29494, 29499, 29504, + 29509, 29514, 29520, 29526, 29531, 29537, 29542, 29547, 5, 29553, 29557, + 29561, 29565, 29570, 29574, 29578, 29582, 29586, 29591, 29595, 29600, + 29604, 29607, 29611, 29616, 29620, 29625, 29629, 29633, 29637, 29642, + 29646, 29650, 29660, 29665, 29669, 29673, 29678, 29683, 29692, 29697, + 29702, 29706, 29710, 29719, 29732, 29744, 29753, 29762, 29767, 29773, + 29778, 29782, 29786, 29796, 29805, 29813, 29819, 29824, 29828, 29835, + 29842, 29852, 29861, 29869, 12934, 29877, 29884, 29892, 29901, 29910, + 29918, 29928, 29933, 29937, 29941, 29944, 29946, 29950, 29954, 29959, + 29964, 29968, 29972, 29975, 29979, 29982, 29986, 29989, 29992, 29996, + 30002, 30006, 30010, 30014, 30018, 30023, 30028, 30033, 30037, 30040, + 30045, 30051, 30056, 30062, 30067, 30071, 30077, 30081, 30085, 30090, + 30094, 30099, 30104, 30108, 30112, 30119, 30123, 30126, 30130, 30134, + 30140, 30145, 30151, 30155, 30159, 30164, 30171, 30177, 30181, 30190, + 30194, 30198, 30201, 30207, 30212, 30218, 1385, 1748, 30223, 30228, + 30233, 30238, 30243, 30248, 30253, 2213, 827, 30258, 30261, 30265, 30269, + 30274, 30278, 17737, 30282, 30287, 30292, 30296, 30299, 30304, 30308, + 30313, 30317, 17741, 30322, 30325, 30328, 30334, 30338, 30343, 30347, + 30360, 30368, 30372, 30375, 30383, 30392, 30399, 30404, 30410, 30416, + 30424, 30431, 30438, 30442, 30446, 30450, 30455, 30460, 30464, 30472, + 30477, 30484, 30496, 30507, 30512, 30516, 30523, 30527, 30532, 30538, + 30541, 30546, 30551, 30558, 30562, 30566, 30569, 30575, 8900, 2413, + 30579, 30584, 30600, 11100, 30620, 30629, 30645, 30649, 30656, 30659, + 30665, 30675, 30681, 30690, 30699, 30714, 30725, 30737, 30748, 30756, + 30765, 30771, 30780, 30790, 30800, 30811, 30822, 30832, 30841, 30848, + 30857, 30865, 30872, 30879, 30886, 30894, 30901, 30908, 30921, 30928, + 30936, 30943, 30949, 30954, 30963, 30970, 30976, 30981, 30989, 30997, + 31004, 31011, 28499, 31023, 31035, 31049, 31057, 31065, 31073, 31080, + 31092, 31101, 31110, 31118, 31126, 31134, 31141, 31147, 31156, 31164, + 31174, 31183, 31193, 31202, 31211, 31219, 31224, 31228, 31231, 31235, + 31239, 31243, 31247, 31251, 31257, 31263, 31268, 31276, 31283, 31291, + 31298, 10806, 17799, 31306, 31313, 31318, 31325, 31331, 31337, 31344, + 14024, 31351, 31354, 31366, 31374, 31380, 31385, 31389, 31400, 31410, + 31420, 11620, 31429, 31438, 31446, 31456, 31465, 31472, 31479, 31487, + 31491, 17818, 31494, 31501, 31505, 4501, 31511, 31514, 31521, 31527, + 31541, 31546, 31554, 31560, 31571, 31578, 31584, 31590, 31594, 31599, + 31603, 31612, 31619, 31625, 8953, 31632, 31640, 31647, 31653, 31658, + 31664, 31670, 31680, 31692, 31703, 31713, 11252, 31721, 31727, 17836, + 31731, 31733, 31236, 11633, 31742, 31747, 31753, 31763, 31768, 31775, + 31783, 31789, 31794, 31799, 31804, 31808, 31813, 31820, 31826, 31835, + 31843, 31847, 31854, 31864, 31870, 31879, 31885, 31892, 4771, 31898, + 31904, 31909, 31916, 31928, 31939, 31944, 31952, 31956, 31966, 31972, + 31976, 31981, 31991, 32000, 32004, 32011, 32019, 32026, 32032, 32037, + 32045, 32052, 32057, 32064, 32076, 32085, 32089, 32097, 15656, 32101, + 32111, 32115, 32123, 32130, 32137, 30379, 32148, 32153, 32157, 32164, + 32171, 26695, 31161, 32176, 32180, 32183, 27827, 32188, 32202, 32218, + 32236, 32255, 32272, 32290, 27846, 32307, 32327, 27863, 32339, 32351, + 19087, 32363, 27883, 32377, 32389, 12590, 32403, 32408, 32413, 32418, + 32424, 32430, 32436, 32440, 32448, 32454, 32461, 32466, 32476, 32483, + 32489, 12128, 32495, 32497, 32502, 32510, 32514, 31816, 32520, 32527, + 13866, 13876, 32534, 32541, 32551, 32556, 32560, 32563, 32569, 32577, + 32589, 32599, 32615, 32628, 32642, 19105, 32656, 32663, 32667, 32670, + 32675, 32679, 32686, 32693, 32700, 32707, 32717, 32722, 32727, 32732, + 32740, 32748, 32753, 32762, 28520, 3561, 32767, 32770, 32773, 32778, + 32785, 32790, 32795, 32811, 32819, 32827, 10864, 32835, 32840, 32844, + 32850, 32855, 32861, 32864, 32870, 32882, 32890, 32897, 32903, 32910, + 32921, 32935, 32948, 32954, 32963, 32969, 32978, 32990, 33001, 33011, + 33020, 33029, 33037, 33047, 33056, 33067, 673, 33074, 33081, 33087, + 33092, 33098, 33105, 33111, 33122, 33132, 33142, 33151, 33157, 33164, + 33169, 33177, 33184, 33192, 33200, 33212, 7142, 33219, 33222, 33231, + 33239, 33245, 33251, 33256, 33260, 33263, 33269, 33276, 33281, 33286, + 33293, 33298, 33302, 33314, 33325, 33334, 33342, 18008, 33347, 33355, + 33360, 33368, 33374, 33380, 33385, 13859, 9802, 33388, 33392, 33396, + 33399, 33402, 33408, 33416, 33424, 33428, 33432, 33437, 33441, 33444, + 33453, 33458, 33463, 33467, 33470, 33475, 33483, 33494, 33503, 33507, + 33513, 33519, 33523, 33529, 33537, 33559, 33583, 33594, 33603, 33609, + 33616, 33623, 33629, 33637, 33643, 33648, 33659, 33677, 33684, 33692, + 33696, 33703, 33708, 33717, 33730, 33738, 33750, 33761, 33772, 33782, + 33796, 33805, 33813, 33825, 33836, 11117, 33845, 33856, 33867, 33879, + 33889, 33898, 33908, 33913, 33917, 33925, 33936, 33946, 33952, 33957, + 33961, 33964, 33967, 33975, 33983, 33992, 34002, 34011, 34017, 34022, + 34036, 2838, 34058, 34069, 34078, 34088, 34100, 34109, 34118, 34128, + 34136, 34144, 34153, 34158, 34169, 34174, 34183, 34189, 34200, 34204, + 34207, 34217, 34226, 34234, 34244, 34254, 34262, 34271, 34278, 34284, + 34292, 34299, 34308, 34317, 34322, 34327, 34331, 34339, 34346, 34352, + 34356, 34364, 34371, 34382, 34397, 34404, 34410, 34420, 34429, 34435, + 34446, 34450, 34457, 34461, 34468, 34474, 16838, 34480, 34484, 34489, + 34495, 34502, 34506, 34510, 34518, 34526, 34532, 34541, 34548, 34555, + 34560, 34565, 34575, 28574, 34579, 34582, 34587, 34592, 34597, 34602, + 34607, 34612, 34617, 34622, 34628, 34633, 34638, 34644, 1094, 770, 34649, + 34652, 34659, 34668, 1777, 34675, 34680, 34684, 34690, 1143, 643, 34695, + 347, 34699, 34709, 34718, 34726, 34735, 34743, 34750, 34761, 34769, + 34778, 34786, 34796, 34804, 34809, 11794, 34813, 34821, 34829, 34834, + 17754, 4101, 34840, 34846, 34852, 6669, 34857, 34861, 34868, 34874, + 34880, 34884, 34893, 34899, 34904, 34911, 1336, 34917, 34923, 34928, + 34935, 34939, 1243, 6677, 34944, 34954, 34962, 34968, 34978, 34987, + 34995, 35001, 35006, 35014, 35021, 13376, 35027, 35034, 35039, 35045, + 35052, 35062, 1404, 253, 2212, 35068, 35074, 35081, 35092, 35103, 35111, + 35118, 35128, 35137, 35145, 35154, 35161, 35168, 35181, 35188, 35194, + 35205, 35224, 35229, 1148, 35233, 35238, 35246, 3984, 35250, 35255, + 35259, 35263, 1340, 29973, 35273, 35277, 35282, 35286, 35292, 3846, + 35298, 35306, 35313, 35324, 35333, 35341, 35366, 35374, 35379, 3985, 401, + 35385, 35393, 35401, 35408, 35413, 35419, 35424, 2281, 12792, 35431, + 35437, 31595, 31934, 35443, 656, 106, 35447, 35451, 35457, 595, 10679, + 35462, 35467, 35474, 35480, 35484, 35488, 1549, 35491, 35495, 18296, + 35498, 35503, 35510, 35516, 8966, 35521, 35529, 35536, 35542, 27205, + 35546, 35550, 35554, 35558, 1834, 20204, 35562, 35567, 35571, 35574, + 35582, 35590, 35595, 35604, 35612, 35615, 35622, 35629, 35641, 27284, + 35651, 35663, 35671, 35676, 35680, 35688, 35695, 35702, 35711, 35717, + 35724, 35731, 35734, 35738, 35742, 1351, 35752, 35754, 35759, 35765, + 35771, 35776, 35781, 35786, 35791, 35796, 35801, 35806, 35811, 35816, + 35821, 35826, 35831, 35836, 35841, 35847, 35853, 35859, 35865, 35870, + 35875, 35880, 35886, 35891, 35896, 35901, 35907, 35912, 35918, 35923, + 35928, 35933, 35938, 35944, 35949, 35955, 35960, 35965, 35970, 35975, + 35981, 35986, 35992, 35997, 36002, 36007, 36012, 36017, 36022, 36027, + 36032, 36037, 36043, 36049, 36055, 36060, 36065, 36070, 36075, 36081, + 36087, 36093, 36099, 36105, 36111, 36116, 36122, 36127, 36132, 36137, + 36142, 36148, 2552, 36153, 2559, 2566, 2962, 36158, 2572, 2582, 36164, + 2614, 2619, 2624, 36168, 36173, 36178, 36184, 36189, 36194, 36198, 36203, + 36209, 36214, 36219, 36224, 36230, 36235, 36239, 36243, 36248, 36253, + 36258, 36263, 36268, 36274, 36280, 36285, 36289, 36294, 36300, 36304, + 36309, 36314, 36319, 36324, 36328, 36331, 36336, 36341, 36346, 36351, + 36356, 36362, 36368, 36373, 36378, 36383, 36387, 36392, 36397, 36402, + 36407, 36412, 36417, 36421, 36426, 36431, 36436, 36440, 36444, 36448, + 36453, 36461, 36466, 36471, 36477, 36483, 36489, 36494, 36502, 36506, + 36509, 36514, 36519, 36523, 36528, 36533, 36537, 36542, 36546, 36549, + 36554, 4211, 21695, 36559, 36564, 36569, 36574, 36582, 25865, 34932, + 10318, 36587, 36592, 36596, 36601, 36605, 36609, 36614, 36618, 36621, + 36624, 36628, 36633, 36637, 36645, 36649, 36652, 36657, 36661, 36665, + 36670, 36675, 36679, 36685, 36690, 36695, 36702, 36709, 36713, 36716, + 36722, 36731, 36738, 36746, 36753, 36757, 36762, 36766, 36770, 36776, + 36781, 36787, 36791, 36797, 36802, 36807, 36811, 36818, 36824, 36830, + 36836, 36842, 36849, 36855, 36861, 36867, 36873, 36879, 36885, 36891, + 36898, 36904, 36911, 36917, 36923, 36929, 36935, 36941, 36947, 36953, + 36959, 36965, 36971, 36976, 36981, 13731, 36986, 36992, 36997, 37002, + 37007, 37012, 37015, 37021, 37026, 37034, 37039, 37043, 37048, 37054, + 37063, 37069, 37074, 37079, 37084, 37088, 37093, 37097, 37102, 37107, + 37112, 37117, 37124, 37131, 37137, 37143, 37148, 19801, 37155, 37161, + 37168, 37174, 37180, 37185, 37193, 37198, 11288, 37202, 37207, 37212, + 37218, 37223, 37228, 37232, 37237, 37242, 37248, 37253, 37258, 37263, + 37267, 37272, 37277, 37281, 37286, 37291, 37295, 37300, 37304, 37309, + 37314, 37319, 37323, 37328, 37332, 37337, 37341, 37348, 37352, 37356, + 18452, 37361, 37368, 37377, 37383, 37389, 37398, 37406, 37415, 37423, + 37428, 37432, 37439, 37445, 37453, 37457, 37460, 37465, 37469, 37478, + 37486, 37504, 37510, 1403, 37516, 37519, 37523, 27351, 27357, 37529, + 37533, 37544, 37555, 37566, 37578, 37582, 37589, 37596, 37603, 37608, + 37612, 37620, 37625, 37630, 37635, 37640, 6734, 16742, 25864, 37645, + 37650, 37654, 16733, 37659, 37665, 37670, 37676, 37681, 37687, 37692, + 37698, 37703, 37709, 37715, 37721, 37726, 37682, 37688, 37730, 37735, + 37741, 37746, 37752, 37757, 37763, 37768, 37693, 12422, 37772, 37704, + 37710, 37716, 3054, 3760, 37778, 37781, 37786, 37792, 37798, 37804, + 37811, 37817, 37823, 37829, 37835, 37841, 37847, 37853, 37859, 37865, + 37871, 37877, 37883, 37890, 37896, 37902, 37908, 37914, 37920, 37923, + 37928, 37931, 37938, 37943, 37951, 37955, 37960, 37965, 37971, 37976, + 37981, 37985, 37990, 37996, 38001, 38007, 38012, 38018, 38023, 38029, + 38035, 38039, 38044, 38049, 38054, 38059, 38063, 38068, 38073, 38078, + 38084, 38090, 38096, 38102, 38107, 38111, 38114, 38120, 38126, 38135, + 38143, 38150, 38155, 38159, 38163, 38168, 18239, 38173, 38181, 38187, + 4152, 1253, 38192, 38197, 38201, 9016, 38207, 38213, 38220, 9025, 38224, + 38230, 38236, 38243, 38249, 38258, 38266, 38278, 38287, 38291, 38298, + 38304, 38309, 38313, 38317, 38320, 38330, 38339, 38347, 37683, 38352, + 38362, 38372, 38382, 38388, 38393, 38403, 38408, 38421, 38435, 38446, + 38458, 38470, 38484, 38497, 38509, 38521, 17559, 38535, 38540, 38545, + 38549, 38553, 38557, 38561, 38567, 38572, 38577, 38582, 38587, 38592, + 38597, 1737, 32999, 38602, 38607, 38612, 37731, 38617, 38620, 38625, + 38630, 38635, 38641, 38647, 19411, 11994, 38652, 38658, 38665, 19039, + 38671, 38676, 38681, 38685, 38690, 38695, 37736, 38700, 38705, 38710, + 38716, 37742, 38721, 38724, 38731, 38739, 38745, 38751, 38757, 38768, + 38773, 38780, 38787, 38794, 38802, 38811, 38820, 38826, 38832, 38840, + 37747, 38845, 38851, 38857, 37753, 38862, 38867, 38875, 38883, 38889, + 38896, 38902, 38909, 38916, 38922, 38930, 38940, 38947, 38953, 38958, + 38964, 38969, 38974, 38981, 38990, 38998, 39003, 39009, 39016, 39024, + 39030, 39035, 39041, 39050, 39057, 33997, 39063, 39067, 39072, 39081, + 39086, 39091, 39096, 14972, 39104, 39109, 39114, 39119, 39123, 39128, + 39133, 39140, 39145, 39150, 39155, 37758, 25793, 39161, 2655, 158, 39164, + 39167, 39171, 39175, 39185, 39193, 39200, 39204, 39208, 39211, 39219, + 39226, 39233, 31888, 39242, 39245, 39252, 39258, 39263, 39267, 39274, + 39278, 39286, 39294, 39301, 39316, 39320, 39324, 39327, 39333, 39340, + 39344, 39350, 39354, 39361, 39369, 39377, 39384, 37694, 39391, 39399, + 39404, 39416, 12075, 12082, 12089, 12096, 12103, 12110, 626, 434, 39422, + 39427, 39432, 39438, 39443, 39448, 4178, 39453, 39456, 39461, 39466, + 39471, 39476, 39481, 39488, 27469, 39493, 39498, 39503, 39508, 39513, + 39519, 39524, 39530, 37934, 39536, 39541, 39547, 39553, 39563, 39568, + 39573, 39577, 39582, 39587, 39592, 39597, 39610, 39615, 27083, 20286, + 1064, 39619, 39625, 39629, 39634, 39639, 39645, 39650, 39655, 39659, + 39664, 39669, 39675, 39680, 39685, 1258, 39689, 39694, 39699, 39704, + 39708, 39713, 39718, 39723, 39729, 39735, 39740, 39744, 39748, 39753, + 39758, 39763, 39767, 39772, 39780, 39784, 39790, 39794, 39801, 39810, + 20057, 37705, 39816, 39823, 39831, 39839, 39846, 39852, 39861, 39874, + 39886, 39891, 39897, 39901, 2981, 39905, 39909, 39335, 39918, 39929, + 39940, 39945, 34065, 39950, 39955, 39959, 34185, 27362, 39964, 39971, + 39975, 39980, 37711, 25900, 39984, 39989, 39995, 40000, 40004, 40008, + 40011, 40015, 40021, 40030, 40041, 40053, 37717, 40058, 40061, 40065, + 40069, 40074, 40079, 40084, 40089, 40094, 40099, 40104, 40109, 373, + 40114, 40119, 40124, 40129, 40134, 40139, 40145, 40150, 40155, 40161, + 40166, 40172, 40177, 40183, 40188, 40193, 40198, 40203, 40208, 40213, + 40218, 40223, 40229, 40234, 40239, 40244, 40249, 40254, 40259, 40264, + 40270, 40276, 40281, 40286, 40291, 40296, 40301, 40306, 40311, 40316, + 40321, 40326, 40331, 40336, 40341, 40346, 40351, 40356, 40361, 40366, + 40376, 40386, 40392, 342, 14, 40397, 40400, 40404, 40408, 40416, 40420, + 40424, 31568, 16975, 1818, 40427, 40432, 40436, 40441, 40445, 40450, + 40454, 40459, 40463, 40466, 40468, 40472, 40477, 40481, 40492, 40495, + 40497, 40501, 40513, 40525, 40534, 40538, 40548, 40552, 40558, 40563, + 40572, 40578, 40583, 40588, 40592, 40596, 40601, 40608, 40613, 40619, + 40624, 40628, 40635, 31169, 31179, 40639, 40644, 40649, 40654, 40661, + 40665, 40672, 40679, 40685, 9171, 40689, 40698, 40706, 40721, 40735, + 40744, 40752, 40763, 40772, 40777, 40784, 40794, 8165, 40804, 40809, + 40815, 40820, 40824, 40827, 40832, 40836, 40841, 40845, 40852, 40857, + 40862, 40867, 40877, 40882, 40887, 40892, 10188, 40897, 40899, 40907, + 40910, 40913, 40921, 40936, 40944, 40954, 40956, 40959, 40963, 40969, + 40973, 40978, 40983, 41001, 41015, 41034, 41051, 41060, 41068, 41073, + 41078, 1396, 41084, 41090, 41095, 41105, 41114, 41122, 41127, 41133, + 41138, 41147, 41156, 41167, 41172, 41179, 41185, 41189, 41198, 41205, + 41213, 41220, 41233, 41241, 41245, 41255, 41261, 41266, 41270, 41278, + 41286, 41291, 41295, 41299, 41308, 41314, 41319, 41327, 41337, 41346, + 41355, 41364, 41375, 41383, 41394, 41403, 41411, 41418, 41424, 41429, + 41440, 41451, 41456, 41460, 41463, 41467, 41477, 41485, 41491, 41502, + 41513, 41524, 41535, 41546, 41557, 41568, 41579, 41591, 41603, 41615, + 41627, 41639, 41651, 41663, 41672, 41676, 41684, 41690, 41696, 41703, + 41709, 41714, 41720, 41724, 41729, 41734, 41739, 40371, 40381, 2526, + 41744, 41746, 41751, 41756, 41761, 41764, 41766, 41770, 41773, 41780, + 41784, 11644, 41788, 41794, 41801, 41807, 41817, 41822, 41828, 41832, + 41837, 41850, 31758, 41856, 41862, 41871, 41880, 21918, 41887, 41896, + 41904, 38368, 41910, 41915, 41919, 41928, 41936, 41943, 41948, 41952, + 41957, 41962, 41970, 41974, 41982, 41988, 41994, 41999, 42004, 42008, + 42011, 42016, 42029, 42045, 27953, 42062, 42074, 42091, 42103, 42117, + 27970, 27989, 42129, 42141, 2855, 42155, 42160, 42165, 42170, 42174, + 42181, 42193, 42200, 42209, 42219, 42222, 42233, 42244, 42252, 42257, + 42261, 42266, 42271, 42276, 42281, 42286, 42291, 1768, 947, 42296, 42300, + 42304, 42307, 42312, 42317, 42323, 42328, 42333, 42339, 42345, 42350, + 42354, 42359, 42364, 42369, 42373, 42376, 42382, 42387, 42392, 42397, + 42401, 42406, 42412, 42420, 32069, 42425, 42430, 42437, 42443, 42449, + 42454, 42462, 27478, 42469, 42474, 42479, 42484, 42488, 42491, 42496, + 42500, 42504, 42511, 42517, 42523, 42529, 42536, 42541, 42547, 41281, + 42551, 42555, 42560, 42573, 42578, 42584, 42592, 42599, 42607, 42617, + 42623, 42629, 42635, 42639, 42648, 42656, 42663, 42668, 42673, 12445, + 42678, 42688, 42695, 42701, 42711, 42716, 42722, 42730, 4017, 42737, + 42744, 42750, 42757, 4023, 42761, 42766, 42777, 42784, 42790, 42799, + 42803, 42806, 4609, 42813, 42820, 42826, 42832, 42840, 42850, 35414, + 42857, 42865, 42871, 42876, 42882, 42887, 42891, 31517, 42897, 42904, + 42910, 42918, 42927, 42934, 42940, 42951, 28772, 42957, 42964, 42970, + 42980, 42985, 42989, 42997, 43005, 43012, 43018, 43023, 11246, 941, + 43028, 43032, 43034, 43038, 43043, 43046, 43048, 43053, 43059, 43064, + 43069, 43076, 39484, 43082, 43087, 43091, 43096, 43100, 43109, 43113, + 43119, 43126, 43132, 43139, 43144, 43153, 43158, 43162, 43167, 43174, + 43182, 43190, 43195, 25956, 43199, 43202, 43206, 43210, 12889, 1005, + 43214, 43219, 43227, 43232, 43236, 43245, 43252, 43256, 43260, 43268, + 43275, 16260, 43285, 43289, 43293, 43301, 43309, 43315, 43320, 43324, + 43333, 16008, 43339, 43348, 43355, 43360, 43367, 43374, 43382, 43389, + 43397, 43405, 43414, 43419, 43426, 43433, 43440, 43447, 43454, 43459, + 43466, 43472, 43489, 43497, 43507, 43515, 43522, 43530, 461, 43534, + 43540, 43544, 43549, 40768, 43555, 43558, 43562, 43568, 43579, 43587, + 4028, 43595, 43601, 43607, 43617, 43623, 43632, 43641, 43651, 43658, + 43664, 43669, 4034, 4040, 43678, 43686, 43693, 43697, 14356, 43705, + 43709, 43716, 43724, 43731, 43740, 43747, 43753, 43762, 43772, 43778, + 43786, 43795, 43802, 43810, 43817, 26758, 43821, 43828, 43834, 43844, + 43853, 43861, 43872, 43876, 43886, 43893, 43898, 43903, 43909, 43916, + 43924, 43933, 43942, 43952, 43963, 43970, 43975, 43982, 3269, 43990, + 43996, 44001, 44008, 44014, 44020, 44025, 44038, 44051, 44064, 44071, + 44077, 44085, 44093, 44098, 44102, 44106, 44111, 44116, 44121, 44126, + 44131, 44136, 1365, 44141, 44145, 44149, 44153, 44157, 44161, 44165, + 44169, 44173, 44177, 44181, 44185, 44189, 44193, 44197, 44201, 44205, + 44209, 44213, 44217, 44221, 44225, 44229, 44233, 44237, 44241, 44245, + 44249, 44253, 44257, 44261, 44265, 44269, 44273, 44277, 44281, 44285, + 44289, 44293, 44297, 44301, 44305, 44309, 44313, 44317, 44321, 44325, + 44329, 44333, 44337, 44341, 44345, 44349, 44353, 44357, 44361, 44365, + 44369, 44373, 44377, 44381, 44385, 44389, 44393, 44397, 44401, 44405, + 44409, 44413, 44417, 44421, 44425, 44429, 44433, 44437, 44441, 44445, + 44449, 44453, 44457, 44461, 44465, 44469, 44473, 44477, 44481, 44485, + 44489, 44493, 44497, 44501, 44505, 44509, 44513, 44517, 44521, 44525, + 44529, 44533, 44537, 44541, 44545, 44549, 44553, 44557, 44561, 44565, + 44569, 44573, 44577, 44581, 44585, 44589, 44593, 44597, 44601, 44605, + 44609, 44613, 44617, 44621, 44625, 44629, 44633, 44637, 44641, 44645, + 44649, 44653, 44657, 44661, 44665, 44669, 44673, 44677, 44681, 44685, + 44689, 44693, 44697, 44701, 44705, 44709, 44713, 44717, 44721, 44725, + 44729, 44733, 44737, 44741, 44745, 44749, 44753, 44758, 44762, 44767, + 44771, 44776, 44780, 44785, 44789, 44795, 44800, 44804, 44809, 44813, + 44818, 44822, 44827, 44831, 44836, 44840, 44845, 44849, 44854, 44858, + 44864, 44870, 44875, 44879, 44884, 44888, 44894, 44899, 44903, 44908, + 44912, 44917, 44921, 44927, 44932, 44936, 44941, 44945, 44950, 44954, + 44959, 44963, 44969, 44974, 44978, 44983, 44987, 44993, 44998, 45002, + 45007, 45011, 45016, 45020, 45025, 45029, 45034, 45038, 45044, 45049, + 45053, 45059, 45064, 45068, 45074, 45079, 45083, 45088, 45092, 45097, + 45101, 45107, 45113, 45119, 45125, 45131, 45137, 45143, 45149, 45154, + 45158, 45163, 45167, 45173, 45178, 45182, 45187, 45191, 45196, 45200, + 45205, 45209, 45214, 45218, 45223, 45227, 45232, 45236, 45242, 45247, + 45251, 45256, 45260, 45266, 45272, 45277, 127, 63, 45281, 45283, 45287, + 45291, 45295, 45300, 45304, 45308, 45313, 11153, 45318, 45324, 1677, + 7181, 45330, 45333, 45338, 45342, 45347, 45351, 45355, 45360, 12233, + 45364, 45368, 45372, 630, 45376, 18561, 45381, 45385, 45390, 45395, + 45400, 45404, 45411, 45417, 45423, 31790, 45428, 45431, 45435, 45440, + 45446, 45450, 45453, 45461, 45467, 45472, 45476, 45479, 45483, 45489, + 45493, 45497, 3811, 3816, 15084, 45500, 45504, 45508, 45512, 45516, + 45524, 45531, 45535, 15958, 45542, 45556, 45563, 45574, 361, 45579, + 45583, 45589, 45601, 45607, 45613, 45618, 45624, 18613, 45628, 45632, + 35727, 45641, 45647, 45656, 45660, 45664, 45669, 45675, 45680, 45684, + 45689, 45693, 45697, 45704, 45710, 45715, 45726, 45741, 45756, 45771, + 45787, 45805, 12140, 45819, 45826, 45832, 45836, 45839, 45848, 45853, + 45857, 45865, 19242, 45873, 45877, 45887, 45898, 35617, 1042, 45911, + 45920, 45938, 45957, 45966, 45974, 45982, 1690, 12342, 45986, 27374, + 45989, 31556, 45994, 11478, 45999, 46005, 46010, 46016, 46021, 46027, + 46032, 46038, 46043, 46049, 46055, 46061, 46066, 46022, 46028, 46070, + 46033, 46039, 46044, 46075, 46050, 46056, 9184, 4434, 46081, 46089, + 46093, 46096, 46103, 46107, 46112, 46117, 46124, 46130, 46136, 46141, + 17850, 46145, 31573, 46149, 46153, 46157, 46164, 46170, 46174, 33931, + 46183, 10351, 46187, 10780, 46190, 46197, 46203, 46207, 14381, 46214, + 46220, 46225, 46232, 46239, 46246, 34730, 9081, 46253, 46260, 46267, + 46273, 46278, 46285, 46296, 46302, 46307, 46312, 46317, 46321, 46326, + 46333, 46023, 46337, 46347, 46356, 46367, 46373, 46381, 46388, 46393, + 46398, 46403, 46408, 46413, 46417, 46421, 46428, 46434, 46442, 2416, + 30582, 12245, 12257, 12262, 12268, 46451, 12273, 12278, 12284, 46456, + 46466, 46470, 12289, 46475, 20484, 46478, 46483, 46487, 46491, 46502, + 46510, 42204, 46518, 46523, 46530, 46537, 46541, 46544, 46552, 12153, + 46559, 46562, 46568, 46578, 6767, 46587, 46592, 46598, 46602, 46610, + 46614, 46624, 46630, 46635, 46646, 46655, 46664, 46673, 46682, 46691, + 46700, 46709, 46715, 46721, 46726, 46732, 46738, 46744, 46749, 46752, + 46759, 46765, 46769, 46774, 46781, 46788, 46792, 46795, 46805, 46818, + 46827, 46836, 46847, 46860, 46872, 46883, 46892, 46903, 46908, 46917, + 46922, 12294, 46928, 46935, 46943, 46950, 46955, 46960, 31836, 46964, + 46971, 4374, 25, 46975, 46980, 20333, 46984, 46987, 46990, 34122, 46994, + 34739, 47002, 47006, 47010, 47013, 47019, 47025, 47030, 37782, 47039, + 47047, 47053, 47060, 34105, 47064, 34342, 47068, 47077, 47081, 47089, + 47095, 47101, 47106, 47110, 34765, 47116, 47119, 47127, 47135, 47143, + 4772, 47149, 47153, 47157, 47162, 47169, 47175, 47180, 47185, 47189, + 47195, 47200, 47206, 4662, 820, 47213, 47217, 47220, 47232, 47239, 47244, + 18434, 47248, 47256, 47264, 47272, 47280, 47287, 47295, 47303, 47310, + 47318, 47326, 47334, 47342, 47350, 47358, 47366, 47374, 47382, 47390, + 47398, 47405, 47413, 47421, 47429, 47437, 47445, 47453, 47461, 47469, + 47477, 47485, 47493, 47501, 47509, 47517, 47525, 47533, 47541, 47549, + 47557, 47564, 47572, 47579, 47587, 47595, 47603, 47611, 47619, 47627, + 47635, 47643, 47654, 26794, 47659, 47662, 47669, 47673, 47679, 47683, + 47689, 47694, 47700, 47705, 47710, 47714, 47718, 47725, 47733, 47738, + 47743, 47753, 47759, 47772, 47778, 47784, 47790, 47793, 47800, 47805, + 4700, 47811, 4869, 965, 47816, 47819, 47822, 47825, 37866, 37872, 47828, + 37878, 37891, 37897, 37903, 47834, 37909, 37915, 47840, 47846, 10, 47854, + 47861, 47865, 47869, 47877, 38726, 47881, 47885, 47892, 47897, 47901, + 47906, 47912, 47917, 47923, 47928, 47932, 47936, 47940, 47945, 47949, + 47954, 47958, 47962, 47969, 47974, 47978, 47982, 47987, 47991, 47996, + 48000, 48004, 48009, 48015, 18743, 18748, 48020, 48024, 48027, 48033, + 48037, 48041, 25750, 48046, 48050, 48056, 48063, 48069, 48074, 40797, + 48084, 48089, 48097, 48101, 48104, 48108, 38741, 48116, 4738, 48121, + 48126, 48130, 48135, 48139, 48144, 16026, 48155, 48159, 48162, 48166, + 48174, 48179, 48183, 48188, 48193, 48197, 48201, 48205, 48208, 48212, + 48215, 48220, 48225, 48230, 48235, 48240, 48245, 8664, 16042, 48250, + 48253, 48259, 48264, 48270, 48275, 48281, 48286, 48292, 48297, 48303, + 48309, 48315, 48320, 48324, 48328, 48339, 48347, 48354, 48360, 48365, + 48376, 48386, 48392, 48397, 48404, 48413, 48429, 48445, 48455, 34007, + 48462, 48466, 48471, 48476, 48480, 48484, 43937, 48490, 48495, 48499, + 48506, 48511, 48516, 48520, 48523, 48527, 48533, 32802, 48537, 26108, + 48542, 48549, 48557, 48563, 48569, 48576, 48584, 48590, 48594, 48599, + 48605, 48613, 48618, 48622, 48631, 11134, 48639, 48643, 48651, 48658, + 48663, 48668, 48673, 48677, 48680, 48686, 48690, 48693, 48697, 48704, + 48709, 48716, 48720, 48726, 48730, 48736, 48741, 48746, 5107, 5114, + 48751, 48760, 48768, 48773, 48779, 48791, 48804, 48818, 48825, 48831, + 48837, 48842, 48850, 48853, 48855, 48866, 48878, 48889, 48904, 48921, + 48941, 48963, 48970, 48977, 48984, 48990, 48994, 8663, 48997, 49001, + 49005, 49010, 49014, 49018, 49021, 49025, 49039, 28019, 49058, 49071, + 49084, 49097, 28037, 49112, 2808, 49127, 49133, 49137, 49147, 49151, + 49155, 49160, 49164, 49171, 49176, 49180, 49187, 49193, 49198, 49204, + 49214, 49226, 49237, 49242, 49249, 49253, 49257, 49260, 49268, 19263, + 4141, 49273, 18782, 49286, 49293, 49300, 49306, 49310, 49314, 49319, + 49325, 49330, 49336, 49340, 49344, 49347, 49352, 49356, 49361, 49366, + 49371, 49376, 49381, 49386, 49391, 49396, 49401, 8727, 18793, 49406, + 49410, 49416, 49425, 49430, 49439, 49446, 43768, 49452, 49457, 49461, + 49468, 49473, 49480, 49488, 49494, 49498, 49501, 49505, 49510, 2886, + 49517, 49524, 49528, 49531, 49536, 49541, 49547, 49552, 49557, 49561, + 49566, 49576, 49581, 49587, 49592, 49599, 47234, 49605, 49611, 49619, + 49629, 49634, 49639, 49643, 49648, 49653, 8167, 8179, 49658, 49661, + 49668, 49674, 49683, 10268, 41421, 49691, 49695, 49699, 38789, 49707, + 49718, 49726, 43985, 49733, 49738, 49743, 49754, 49761, 49772, 38813, + 26125, 49780, 4652, 49785, 16459, 49791, 34096, 49797, 49802, 49812, + 49821, 49828, 49834, 49838, 49841, 49848, 49854, 49861, 49867, 49877, + 49885, 49891, 49897, 49902, 49906, 49913, 49918, 49924, 49931, 49937, + 49006, 49942, 49946, 16501, 16510, 16519, 16528, 16537, 16566, 622, + 16575, 49952, 49957, 49960, 49966, 49974, 1275, 49979, 49983, 49988, + 49993, 49997, 50002, 50009, 50015, 50019, 50024, 50030, 50034, 37939, + 50039, 50044, 50053, 50060, 50070, 50076, 34140, 50093, 50102, 50110, + 50116, 50121, 50128, 50134, 50142, 50151, 50159, 50167, 50173, 50177, + 50182, 50190, 35288, 38822, 50196, 50215, 19166, 50229, 50245, 50259, + 50265, 50270, 50275, 50280, 50286, 38828, 50291, 50294, 50301, 50308, + 50317, 50322, 50326, 423, 3176, 50333, 50338, 50343, 33196, 50131, 50347, + 50355, 50360, 50368, 50372, 50375, 50380, 50386, 50392, 50397, 50401, + 34213, 50404, 50409, 50413, 50416, 50421, 50425, 50430, 50435, 50439, + 50444, 50448, 50455, 50459, 50463, 25746, 25757, 50468, 50473, 50479, + 50484, 50490, 50496, 32758, 50501, 50505, 50508, 50514, 50519, 50524, + 50529, 50534, 50539, 50544, 50549, 50554, 50560, 50566, 14569, 19473, + 50571, 50576, 50581, 50586, 50591, 50596, 50601, 50606, 452, 68, 37956, + 37961, 37966, 37972, 37977, 37982, 50611, 37986, 50615, 50619, 50623, + 37991, 37997, 50637, 38008, 38013, 50645, 50650, 38019, 50655, 50660, + 50669, 50674, 50679, 50688, 50694, 50700, 50706, 38036, 50719, 50728, + 50734, 38040, 50738, 38045, 50743, 38050, 38055, 50746, 50751, 50755, + 50761, 16267, 50768, 16277, 50775, 50780, 38060, 50784, 50789, 50794, + 50799, 50804, 50808, 50813, 50818, 50824, 50829, 50834, 50840, 50846, + 50851, 50855, 50860, 50865, 50870, 50874, 50879, 50884, 50889, 50895, + 50901, 50907, 50912, 50916, 50921, 50925, 38064, 38069, 38074, 50929, + 50933, 50938, 50942, 50954, 38079, 38085, 38091, 38103, 50960, 31616, + 50964, 50969, 50973, 50978, 50985, 50990, 50995, 51000, 51004, 51008, + 51018, 51023, 51028, 51032, 51042, 51046, 51049, 51057, 51062, 38151, + 51066, 1375, 51072, 51077, 51083, 51091, 51095, 51104, 51112, 51116, + 51120, 51128, 51134, 51142, 51158, 51163, 51167, 51171, 51175, 51180, + 51186, 51201, 38188, 1685, 14601, 51205, 1254, 1269, 51217, 51225, 51232, + 51237, 9230, 51244, 51249, 10765, 978, 2641, 12321, 51256, 10658, 51261, + 51264, 51273, 1162, 51278, 49177, 51285, 51294, 51299, 51303, 51311, + 51318, 27424, 2697, 51326, 12842, 51336, 51342, 2434, 2444, 51351, 51360, + 51370, 51381, 3584, 41818, 51386, 4341, 4352, 9258, 1167, 51390, 51398, + 51405, 51410, 51414, 51418, 51423, 29054, 49512, 12412, 51431, 51440, + 51449, 51457, 51470, 51477, 51488, 51493, 51506, 51519, 51531, 51543, + 51555, 51566, 51579, 51590, 51601, 51611, 51619, 51627, 51639, 51651, + 51662, 51671, 51679, 51686, 51698, 51705, 51711, 51720, 51726, 51733, + 51746, 51751, 51761, 51766, 51772, 51777, 32098, 51781, 48682, 51788, + 51795, 51803, 51810, 2654, 51817, 51828, 51838, 51847, 51855, 51865, + 51873, 51882, 51892, 51901, 51906, 51912, 51918, 4190, 51929, 51939, + 51948, 51957, 51965, 51975, 51983, 51992, 51997, 52002, 52007, 1604, 47, + 52015, 52023, 52034, 52045, 19877, 52055, 52059, 52066, 52072, 52077, + 52081, 52092, 52102, 52111, 52122, 52127, 20306, 20311, 52134, 52143, + 52148, 52158, 52163, 52171, 52179, 52186, 52192, 1566, 271, 52196, 52201, + 52207, 46085, 52212, 52215, 2182, 2663, 52223, 52227, 52230, 1420, 52236, + 16787, 1172, 52241, 52254, 2797, 2818, 52268, 52280, 52292, 2832, 2849, + 2864, 2880, 2897, 52306, 52318, 2912, 52332, 1178, 1184, 1190, 12713, + 52337, 52342, 52347, 52351, 52366, 52381, 52396, 52411, 52426, 52441, + 52456, 52471, 52486, 52501, 52516, 52531, 52546, 52561, 52576, 52591, + 52606, 52621, 52636, 52651, 52666, 52681, 52696, 52711, 52726, 52741, + 52756, 52771, 52786, 52801, 52816, 52831, 52846, 52861, 52876, 52891, + 52906, 52921, 52936, 52951, 52966, 52981, 52996, 53011, 53026, 53041, + 53056, 53071, 53086, 53101, 53116, 53131, 53146, 53161, 53176, 53191, + 53206, 53221, 53236, 53251, 53266, 53281, 53296, 53311, 53326, 53341, + 53356, 53371, 53386, 53401, 53416, 53431, 53446, 53461, 53476, 53491, + 53506, 53521, 53536, 53551, 53566, 53581, 53596, 53611, 53626, 53641, + 53656, 53671, 53686, 53701, 53716, 53731, 53746, 53761, 53776, 53791, + 53806, 53821, 53836, 53851, 53866, 53881, 53896, 53911, 53926, 53941, + 53956, 53971, 53986, 54001, 54016, 54031, 54046, 54061, 54076, 54091, + 54106, 54121, 54136, 54151, 54166, 54181, 54196, 54211, 54226, 54241, + 54256, 54271, 54286, 54301, 54316, 54331, 54346, 54361, 54376, 54391, + 54406, 54421, 54436, 54451, 54466, 54481, 54496, 54511, 54526, 54541, + 54556, 54571, 54586, 54601, 54616, 54631, 54646, 54661, 54676, 54691, + 54706, 54721, 54736, 54751, 54766, 54781, 54796, 54811, 54826, 54841, + 54856, 54871, 54886, 54901, 54916, 54931, 54946, 54961, 54976, 54991, + 55006, 55021, 55036, 55051, 55066, 55081, 55096, 55111, 55126, 55141, + 55156, 55171, 55186, 55201, 55216, 55231, 55246, 55261, 55276, 55291, + 55306, 55321, 55336, 55351, 55366, 55381, 55396, 55411, 55426, 55441, + 55456, 55471, 55486, 55501, 55516, 55531, 55546, 55561, 55576, 55591, + 55606, 55621, 55636, 55651, 55666, 55681, 55696, 55711, 55726, 55741, + 55756, 55771, 55786, 55801, 55816, 55831, 55846, 55861, 55876, 55891, + 55906, 55921, 55936, 55951, 55966, 55981, 55996, 56011, 56026, 56041, + 56056, 56071, 56086, 56101, 56116, 56131, 56146, 56161, 56176, 56191, + 56206, 56221, 56236, 56251, 56266, 56281, 56296, 56311, 56326, 56341, + 56356, 56371, 56386, 56401, 56416, 56431, 56446, 56461, 56476, 56491, + 56506, 56521, 56536, 56551, 56566, 56581, 56596, 56611, 56626, 56641, + 56656, 56671, 56686, 56701, 56716, 56731, 56746, 56761, 56776, 56791, + 56806, 56821, 56836, 56851, 56866, 56881, 56896, 56911, 56926, 56941, + 56956, 56971, 56986, 57001, 57016, 57031, 57046, 57061, 57076, 57091, + 57106, 57121, 57136, 57151, 57166, 57181, 57196, 57211, 57226, 57241, + 57256, 57271, 57286, 57301, 57316, 57331, 57346, 57361, 57376, 57391, + 57406, 57421, 57436, 57451, 57466, 57481, 57496, 57511, 57526, 57541, + 57556, 57571, 57586, 57601, 57616, 57631, 57646, 57661, 57676, 57691, + 57706, 57721, 57736, 57751, 57766, 57781, 57796, 57811, 57826, 57841, + 57856, 57871, 57886, 57901, 57916, 57931, 57946, 57961, 57976, 57991, + 58006, 58021, 58036, 58051, 58066, 58081, 58096, 58111, 58126, 58141, + 58156, 58171, 58186, 58201, 58216, 58231, 58246, 58261, 58276, 58291, + 58306, 58321, 58336, 58351, 58366, 58381, 58396, 58411, 58426, 58441, + 58456, 58471, 58486, 58501, 58516, 58531, 58546, 58561, 58576, 58591, + 58606, 58621, 58636, 58651, 58666, 58681, 58696, 58711, 58726, 58741, + 58756, 58771, 58786, 58801, 58816, 58831, 58846, 58861, 58876, 58891, + 58906, 58921, 58936, 58951, 58966, 58981, 58996, 59011, 59026, 59041, + 59056, 59071, 59086, 59101, 59116, 59131, 59146, 59161, 59176, 59191, + 59206, 59221, 59236, 59251, 59266, 59281, 59296, 59311, 59326, 59341, + 59356, 59371, 59386, 59401, 59416, 59431, 59446, 59461, 59476, 59491, + 59506, 59521, 59536, 59551, 59566, 59581, 59596, 59611, 59626, 59641, + 59656, 59671, 59686, 59701, 59716, 59731, 59746, 59761, 59776, 59791, + 59806, 59821, 59836, 59851, 59866, 59881, 59896, 59911, 59926, 59941, + 59956, 59971, 59986, 60001, 60016, 60031, 60046, 60061, 60076, 60091, + 60106, 60121, 60136, 60151, 60166, 60182, 60198, 60214, 60230, 60246, + 60262, 60278, 60294, 60310, 60326, 60342, 60358, 60374, 60390, 60406, + 60422, 60438, 60454, 60470, 60486, 60502, 60518, 60534, 60550, 60566, + 60582, 60598, 60614, 60630, 60646, 60662, 60678, 60694, 60710, 60726, + 60742, 60758, 60774, 60790, 60806, 60822, 60838, 60854, 60870, 60886, + 60902, 60918, 60934, 60950, 60966, 60982, 60998, 61014, 61030, 61046, + 61062, 61078, 61094, 61110, 61126, 61142, 61158, 61174, 61190, 61206, + 61222, 61238, 61254, 61270, 61286, 61302, 61318, 61334, 61350, 61366, + 61382, 61398, 61414, 61430, 61446, 61462, 61478, 61494, 61510, 61526, + 61542, 61558, 61574, 61590, 61606, 61622, 61638, 61654, 61670, 61686, + 61702, 61718, 61734, 61750, 61766, 61782, 61798, 61814, 61830, 61846, + 61862, 61878, 61894, 61910, 61926, 61942, 61958, 61974, 61990, 62006, + 62022, 62038, 62054, 62070, 62086, 62102, 62118, 62134, 62150, 62166, + 62182, 62198, 62214, 62230, 62246, 62262, 62278, 62294, 62310, 62326, + 62342, 62358, 62374, 62390, 62406, 62422, 62438, 62454, 62470, 62486, + 62502, 62518, 62534, 62550, 62566, 62582, 62598, 62614, 62630, 62646, + 62662, 62678, 62694, 62710, 62726, 62742, 62758, 62774, 62790, 62806, + 62822, 62838, 62854, 62870, 62886, 62902, 62918, 62934, 62950, 62966, + 62982, 62998, 63014, 63030, 63046, 63062, 63078, 63094, 63110, 63126, + 63142, 63158, 63174, 63190, 63206, 63222, 63238, 63254, 63270, 63286, + 63302, 63318, 63334, 63350, 63366, 63382, 63398, 63414, 63430, 63446, + 63462, 63478, 63494, 63510, 63526, 63542, 63558, 63574, 63590, 63606, + 63622, 63638, 63654, 63670, 63686, 63702, 63718, 63734, 63750, 63766, + 63782, 63798, 63814, 63830, 63846, 63862, 63878, 63894, 63910, 63926, + 63942, 63958, 63974, 63990, 64006, 64022, 64038, 64054, 64070, 64086, + 64102, 64118, 64134, 64150, 64166, 64182, 64198, 64214, 64230, 64246, + 64262, 64278, 64294, 64310, 64326, 64342, 64358, 64374, 64390, 64406, + 64422, 64438, 64454, 64470, 64486, 64502, 64518, 64534, 64550, 64566, + 64582, 64598, 64614, 64630, 64646, 64662, 64678, 64694, 64710, 64726, + 64742, 64758, 64774, 64790, 64806, 64822, 64838, 64854, 64870, 64886, + 64902, 64918, 64934, 64950, 64966, 64982, 64998, 65014, 65030, 65046, + 65062, 65078, 65094, 65110, 65126, 65142, 65158, 65174, 65190, 65206, + 65222, 65238, 65254, 65270, 65286, 65302, 65318, 65334, 65350, 65366, + 65382, 65398, 65414, 65430, 65446, 65462, 65478, 65494, 65510, 65526, + 65542, 65558, 65574, 65590, 65606, 65622, 65638, 65654, 65670, 65686, + 65702, 65718, 65734, 65750, 65766, 65782, 65798, 65814, 65830, 65846, + 65862, 65878, 65894, 65910, 65926, 65942, 65958, 65974, 65990, 66006, + 66022, 66038, 66054, 66070, 66086, 66102, 66118, 66134, 66150, 66166, + 66182, 66198, 66214, 66230, 66246, 66262, 66278, 66294, 66310, 66326, + 66342, 66358, 66374, 66390, 66406, 66422, 66438, 66454, 66470, 66486, + 66502, 66518, 66534, 66550, 66566, 66582, 66598, 66614, 66630, 66646, + 66662, 66678, 66694, 66710, 66726, 66742, 66758, 66774, 66790, 66806, + 66822, 66838, 66854, 66870, 66886, 66902, 66918, 66934, 66950, 66966, + 66982, 66998, 67014, 67030, 67046, 67062, 67078, 67094, 67110, 67126, + 67142, 67158, 67174, 67190, 67206, 67222, 67238, 67254, 67270, 67286, + 67302, 67318, 67334, 67350, 67366, 67382, 67398, 67414, 67430, 67446, + 67462, 67478, 67494, 67510, 67526, 67542, 67558, 67574, 67590, 67606, + 67622, 67638, 67654, 67670, 67686, 67702, 67718, 67734, 67750, 67766, + 67782, 67798, 67814, 67830, 67846, 67862, 67878, 67894, 67910, 67926, + 67942, 67958, 67974, 67990, 68006, 68022, 68038, 68054, 68070, 68086, + 68102, 68118, 68134, 68150, 68166, 68182, 68198, 68214, 68230, 68246, + 68262, 68278, 68294, 68310, 68326, 68342, 68358, 68374, 68390, 68406, + 68422, 68438, 68454, 68470, 68486, 68502, 68518, 68534, 68550, 68566, + 68582, 68598, 68614, 68630, 68646, 68662, 68678, 68694, 68710, 68726, + 68742, 68758, 68774, 68790, 68806, 68822, 68838, 68847, 68862, 68876, + 68885, 17689, 68889, 68894, 68900, 68906, 68916, 68924, 17946, 18677, + 9277, 68937, 1428, 1432, 68945, 4270, 33321, 8104, 68951, 68956, 68961, + 68966, 68971, 68977, 68982, 68988, 68993, 68999, 69004, 69009, 69014, + 69019, 69025, 69030, 69035, 69040, 69045, 69050, 69055, 69060, 69066, + 69071, 69077, 69084, 2701, 69089, 69095, 9652, 69099, 69104, 69111, + 69119, 4281, 4286, 4291, 4296, 65, 69123, 69129, 69134, 69139, 69143, + 69148, 69152, 69156, 12785, 69160, 69170, 69183, 69194, 69207, 69214, + 69220, 69228, 69235, 12246, 69244, 69249, 69255, 69261, 69267, 69272, + 69277, 69282, 69287, 69291, 69296, 69301, 69306, 69312, 69318, 69324, + 69329, 69333, 69338, 69343, 69347, 69352, 69357, 69362, 69366, 12801, + 12812, 12817, 1471, 69370, 69376, 1476, 19711, 69381, 19720, 1486, 69386, + 69392, 69397, 1507, 69403, 1513, 1519, 12847, 69408, 69417, 69425, 69433, + 69440, 69444, 69448, 69454, 69459, 37599, 69464, 69471, 69479, 69486, + 69491, 69495, 69499, 69508, 69513, 69518, 69523, 1524, 280, 69528, 69533, + 69537, 19846, 987, 69541, 69548, 69553, 69557, 19904, 1528, 46361, 69560, + 69565, 69575, 69584, 69589, 69593, 69599, 1533, 49458, 69604, 69613, + 69619, 69624, 69629, 13086, 13092, 69635, 69648, 69660, 69677, 69694, + 69711, 69728, 69745, 69762, 69779, 69796, 69813, 69830, 69847, 69864, + 69881, 69898, 69915, 69932, 69949, 69966, 69983, 70000, 70017, 70034, + 70051, 70068, 70085, 70102, 70119, 70136, 70153, 70170, 70187, 70204, + 70221, 70238, 70255, 70272, 70289, 70306, 70323, 70340, 70357, 70374, + 70391, 70408, 70425, 70442, 70459, 70476, 70493, 70504, 70514, 70519, + 1538, 70523, 70528, 70534, 70539, 70544, 70551, 10677, 1543, 70557, + 70566, 33713, 70571, 70582, 13108, 70592, 70597, 70603, 70608, 70615, + 70621, 70626, 1548, 20198, 70631, 70637, 13118, 70643, 70648, 70653, + 70658, 70663, 70668, 70673, 70678, 1553, 4761, 70683, 70688, 70694, + 70699, 70704, 70709, 70714, 70719, 70724, 70729, 70734, 70740, 70746, + 70752, 70757, 70761, 70766, 70771, 70775, 70780, 70785, 70790, 70795, + 70799, 70804, 70810, 70815, 70820, 70824, 70829, 70834, 70840, 70845, + 70850, 70856, 70862, 70867, 70871, 70876, 70881, 70886, 70890, 70895, + 70900, 70905, 70911, 70917, 70922, 70926, 70930, 70935, 70940, 70945, + 35492, 70949, 70954, 70959, 70965, 70970, 70975, 70979, 70984, 70989, + 70995, 71000, 71005, 71011, 71017, 71022, 71026, 71031, 71036, 71040, + 71045, 71050, 71055, 71061, 71067, 71072, 71076, 71081, 71086, 71090, + 71095, 71100, 71105, 71110, 71114, 71117, 71120, 71125, 71130, 38335, + 71137, 71145, 50085, 71151, 3928, 33656, 71164, 71171, 71177, 71183, + 4107, 71188, 13260, 71194, 71204, 71219, 71227, 13265, 71238, 71243, + 71254, 71266, 71278, 71290, 2903, 71302, 71307, 31699, 71319, 71325, + 71331, 71336, 71345, 71352, 71357, 71362, 71367, 71372, 71377, 71382, + 1570, 19338, 71387, 71392, 71397, 71402, 71408, 71413, 71419, 71424, + 71429, 71435, 71440, 71445, 49532, 71449, 71453, 71458, 71462, 20346, + 71467, 71470, 71475, 71483, 71491, 1574, 13301, 13307, 1579, 71499, + 71506, 71511, 71520, 71530, 71537, 71542, 71547, 1584, 71554, 71559, + 20466, 71563, 71568, 71575, 71581, 71585, 71598, 71604, 71615, 71625, + 71632, 20488, 10571, 10578, 4355, 4361, 71639, 1589, 71644, 71653, 71659, + 71667, 71674, 71680, 71687, 71699, 71705, 71710, 71717, 71729, 71740, + 71750, 71759, 71769, 71779, 4249, 71787, 37393, 37402, 20528, 71800, + 71805, 71810, 71815, 71820, 71825, 71830, 1594, 1598, 71835, 71839, + 71842, 71853, 71858, 20554, 1608, 71866, 71871, 71876, 71888, 20587, + 71895, 71898, 71904, 71910, 71915, 71923, 1613, 71928, 71933, 71941, + 71949, 71956, 71965, 71973, 71982, 71986, 1618, 71995, 1623, 25931, + 72000, 72007, 72013, 20674, 72021, 72031, 72037, 72042, 72050, 72057, + 72066, 72074, 72084, 72093, 72103, 72112, 72123, 72133, 72143, 72152, + 72162, 72176, 72189, 72198, 72206, 72216, 72225, 72237, 72248, 72259, + 72269, 19966, 72274, 13453, 72283, 72289, 72294, 72301, 72307, 72314, + 72320, 19555, 72330, 72336, 72341, 72352, 72359, 72366, 72371, 72379, + 13470, 13475, 72387, 72393, 72397, 4339, 4350, 20750, 49635, 72405, + 72411, 72416, 72424, 72431, 14582, 72436, 72442, 72448, 1634, 72453, + 72456, 72462, 72467, 72472, 72477, 72482, 72487, 72492, 72497, 72502, + 72508, 72514, 1333, 72519, 72524, 72529, 72535, 72540, 72545, 72550, + 72555, 72560, 72565, 1643, 18, 72571, 72575, 72580, 72584, 72588, 72592, + 38621, 72597, 28238, 72602, 72607, 72611, 72614, 72618, 72622, 72627, + 72631, 72636, 72640, 72643, 72649, 42308, 42313, 42318, 72652, 72659, + 72665, 72673, 49230, 72683, 72689, 42324, 38885, 38636, 38642, 42340, + 38648, 72694, 72699, 72703, 38918, 72710, 72713, 72717, 72725, 72732, + 72737, 72740, 72745, 72750, 72754, 72758, 72761, 72771, 72783, 72790, + 72796, 38653, 72803, 40604, 72806, 9669, 13815, 72809, 72813, 72818, + 4159, 72822, 72825, 16320, 72832, 72839, 72852, 72867, 72881, 72897, + 72912, 72921, 72929, 72937, 72946, 72950, 72959, 72965, 72970, 72980, + 72993, 73005, 73012, 73017, 73026, 73039, 44032, 73057, 73062, 73069, + 73075, 73080, 895, 73085, 73093, 73100, 73107, 33137, 914, 73113, 73119, + 73124, 73134, 73142, 73148, 73153, 38672, 6858, 38686, 73157, 73167, + 73172, 73180, 73190, 73205, 73211, 73217, 73224, 38696, 73229, 73235, + 37737, 73239, 73243, 73248, 73257, 73264, 73269, 73273, 73278, 73286, + 20531, 73293, 73298, 73302, 6899, 38722, 73306, 73312, 341, 73322, 73329, + 73336, 73342, 73349, 73354, 73363, 15941, 69569, 69579, 73369, 73377, + 73381, 73385, 73389, 73393, 73398, 73402, 73408, 73416, 73421, 73426, + 73433, 73438, 73442, 73447, 73451, 73455, 73461, 73467, 73478, 73484, + 73489, 73493, 73498, 73502, 38846, 73506, 38852, 38858, 73511, 73517, + 73524, 73529, 73533, 37754, 20185, 73536, 73540, 73545, 73552, 73558, + 73562, 73567, 48699, 73573, 73577, 73584, 73588, 73593, 73599, 73605, + 73611, 73623, 73632, 73642, 73648, 73655, 73660, 73665, 73669, 73672, + 73678, 73685, 73690, 73695, 73702, 73709, 73716, 73722, 73727, 73732, + 73740, 38863, 2531, 73745, 73750, 73756, 73761, 73767, 73772, 73777, + 73782, 73788, 38884, 73793, 73799, 73805, 73811, 38954, 73816, 73821, + 73826, 38965, 73831, 73836, 73841, 73847, 73853, 38970, 73858, 73863, + 73868, 39025, 39031, 73873, 73878, 39036, 39058, 33998, 39064, 39068, + 73883, 14258, 73887, 73895, 73901, 73909, 73916, 73922, 73932, 73938, + 73945, 12685, 39082, 73951, 73964, 73973, 73979, 73988, 73994, 74000, + 74007, 28581, 74015, 74022, 74032, 74040, 74043, 39026, 74048, 74055, + 74060, 74064, 74068, 74073, 74077, 4478, 74082, 74087, 74092, 42402, + 42407, 74096, 42421, 74101, 42426, 74106, 74112, 42438, 42444, 42450, + 74117, 74123, 27479, 74134, 74137, 74149, 74157, 39105, 74161, 74170, + 74180, 74189, 39115, 74194, 74201, 74210, 74216, 74224, 74231, 74238, + 6950, 5174, 74243, 39037, 74249, 74252, 74258, 74265, 74270, 74275, + 28485, 74279, 74285, 74291, 74296, 74301, 74305, 74311, 74317, 40488, + 74322, 43626, 45463, 45469, 39146, 39151, 74326, 74330, 74334, 74337, + 74350, 74356, 74360, 74363, 74368, 40870, 74372, 37759, 25872, 74378, + 6879, 6887, 10377, 74381, 74386, 74391, 74396, 74401, 74406, 74411, + 74416, 74421, 74426, 74432, 74437, 74442, 74448, 74453, 74458, 74463, + 74468, 74473, 74478, 74484, 74489, 74495, 74500, 74505, 74510, 74515, + 74520, 74525, 74530, 74535, 74540, 74545, 74551, 74556, 74561, 74566, + 74571, 74576, 74581, 74587, 74592, 74597, 74602, 74607, 74612, 74617, + 74622, 74627, 74632, 74638, 74643, 74648, 74653, 74658, 74664, 74670, + 74675, 74681, 74686, 74691, 74696, 74701, 74706, 1421, 159, 74711, 74715, + 74719, 74723, 30435, 74727, 74731, 74736, 74740, 74745, 74749, 74754, + 74759, 74764, 74769, 74773, 74777, 74782, 74786, 16020, 74791, 74795, + 74802, 74812, 18315, 74821, 74830, 74839, 74843, 74848, 74853, 74857, + 74861, 30215, 3259, 74865, 74871, 21763, 74875, 74884, 74892, 74898, + 74903, 74915, 74927, 74932, 74936, 74941, 74945, 74951, 74957, 74962, + 74972, 74982, 74988, 74996, 75001, 75005, 75011, 75016, 75023, 75029, + 75034, 75041, 75050, 75059, 75067, 75071, 18871, 75074, 75083, 75091, + 75103, 75114, 75125, 75134, 75138, 75147, 75155, 75165, 75173, 75180, + 75190, 75196, 75201, 75209, 75216, 75225, 75231, 75236, 75243, 75249, + 75260, 60, 37536, 75266, 31986, 31996, 75272, 75280, 75287, 75293, 75297, + 75307, 75318, 75326, 75335, 75340, 75345, 75350, 75354, 75358, 75366, + 21710, 75373, 75377, 75383, 75393, 75400, 75407, 75413, 75419, 42501, + 75423, 75425, 75428, 75434, 75438, 75449, 75459, 75465, 75472, 75479, + 15957, 75487, 75493, 75502, 75511, 75517, 11579, 75523, 75529, 75534, + 75539, 75546, 75551, 75558, 75564, 75569, 75577, 75590, 75599, 75608, + 72138, 72148, 75618, 75624, 75633, 75639, 75645, 75652, 75659, 75666, + 75673, 75680, 75685, 75689, 75693, 75696, 75706, 75710, 75722, 75731, + 10038, 75740, 75751, 75756, 75760, 72157, 75766, 75773, 75782, 75790, + 51037, 75798, 75802, 75807, 75812, 75822, 75830, 75842, 75847, 75851, + 75855, 75861, 75869, 75876, 75888, 75896, 75907, 75914, 75920, 75930, + 75936, 75940, 75949, 75958, 75965, 75971, 75976, 75980, 75984, 75988, + 75997, 76006, 76015, 76022, 76028, 76034, 76040, 76045, 76052, 76058, + 76066, 76073, 76079, 15046, 76084, 76090, 76094, 17172, 76098, 76103, + 76113, 76118, 76127, 76133, 76139, 76147, 76154, 76158, 76162, 76169, + 76175, 76183, 76190, 76196, 76207, 76211, 76215, 76219, 76222, 76228, + 76233, 76238, 76242, 76246, 76255, 76263, 76270, 76276, 76283, 29245, + 48840, 76288, 76296, 76300, 76304, 76307, 76315, 76322, 76328, 76337, + 76345, 76351, 76356, 76360, 76365, 76370, 76374, 76378, 76382, 76387, + 76396, 76400, 76407, 45567, 76411, 76417, 76425, 76429, 76435, 76443, + 76449, 76454, 76465, 76473, 76479, 76488, 27626, 76496, 76503, 76510, + 76517, 76524, 76531, 52526, 15772, 76538, 76545, 76550, 42537, 4721, + 76556, 76561, 76566, 76572, 76578, 76584, 76589, 76594, 76599, 76604, + 76610, 76615, 76621, 76626, 76632, 76637, 76642, 76647, 76652, 76657, + 76662, 76667, 76673, 76678, 76684, 76689, 76694, 76699, 76704, 76709, + 76714, 76720, 76725, 76730, 76735, 76740, 76745, 76750, 76755, 76760, + 76765, 76770, 76776, 76781, 76786, 76791, 76796, 76801, 76806, 76811, + 76816, 76822, 76827, 76832, 76837, 76842, 76847, 76852, 76857, 76862, + 76867, 76872, 76877, 76882, 76888, 1883, 305, 76893, 46479, 46484, 76897, + 76902, 9293, 76906, 3628, 76911, 76916, 76920, 76929, 76940, 76957, + 76975, 76983, 75794, 76990, 76993, 77003, 77010, 77019, 77035, 77044, + 77054, 77059, 77072, 77082, 77091, 77099, 77113, 77121, 77130, 77134, + 77137, 77144, 77150, 77161, 77168, 77180, 77191, 77202, 77211, 77218, + 1173, 812, 77228, 2744, 77232, 77237, 77246, 997, 9059, 25308, 77254, + 77262, 77276, 77289, 77293, 77298, 77303, 77308, 77314, 77320, 77325, + 9661, 18358, 77330, 77334, 77338, 77346, 10098, 77351, 77357, 77366, + 77374, 1657, 13314, 1179, 4393, 77378, 77382, 77391, 77401, 2482, 32836, + 77410, 77416, 20438, 32851, 77422, 4558, 13696, 77428, 77435, 71848, + 77439, 77443, 77449, 77454, 77459, 3861, 163, 3887, 77464, 77476, 77480, + 77484, 77490, 77495, 33733, 77499, 13684, 2938, 4, 77504, 77514, 77525, + 77536, 77546, 77552, 77563, 77570, 77576, 77582, 2306, 77587, 77595, + 77602, 77608, 77618, 77628, 77638, 77647, 28568, 1185, 77652, 77656, + 77660, 77666, 77670, 2961, 2967, 9658, 2337, 77674, 77678, 77687, 77695, + 77706, 77714, 77722, 77728, 77733, 77744, 77755, 77763, 77769, 77774, + 11356, 77784, 77792, 77796, 77800, 77805, 77809, 77821, 34196, 18257, + 77828, 77838, 77844, 77850, 7977, 11490, 77860, 77871, 77882, 77892, + 77901, 77905, 77912, 999, 2731, 77922, 77927, 77935, 71564, 77943, 77948, + 77959, 77966, 77980, 16968, 529, 77990, 77997, 78001, 78005, 78013, + 78022, 4433, 78030, 78036, 20483, 78041, 78055, 78062, 78068, 78076, + 78085, 78094, 78101, 78113, 78123, 78131, 78138, 78146, 78153, 4357, 116, + 78161, 78172, 78176, 78188, 78194, 1804, 227, 78199, 10709, 78204, 3006, + 78208, 78215, 78221, 78232, 78242, 78250, 78257, 10049, 78264, 78273, + 78281, 4438, 78294, 4455, 78298, 78303, 78309, 78314, 78319, 78324, 3011, + 573, 78330, 78343, 78347, 78352, 78357, 3016, 1882, 763, 78361, 4459, + 78369, 78375, 78379, 799, 78389, 78398, 78403, 3878, 78407, 78411, 17989, + 17996, 9317, 78419, 4490, 4367, 15644, 78427, 78434, 78439, 28632, 78443, + 78450, 78456, 13952, 78461, 14017, 204, 78466, 78478, 78484, 78492, 3028, + 1699, 78500, 78502, 78507, 78512, 78517, 78523, 78528, 78533, 78538, + 78543, 78548, 78553, 78559, 78564, 78569, 78574, 78579, 78584, 78589, + 78594, 78599, 78605, 78610, 78615, 78620, 78626, 78631, 78637, 78642, + 78647, 78652, 78657, 78662, 78667, 78672, 78678, 78683, 78689, 78694, + 78699, 78704, 78709, 78714, 78719, 78724, 78729, 9730, 9743, 4506, 4511, + 4516, 4521, 26, 78735, 78741, 78746, 78751, 78756, 78762, 78767, 78771, + 78775, 78780, 78786, 78790, 78796, 78801, 78806, 78812, 78817, 78821, + 78826, 78831, 78835, 78838, 78840, 78844, 78847, 78854, 78859, 78863, + 78868, 78872, 78876, 78880, 78886, 78897, 78917, 78936, 78957, 78970, + 78982, 78991, 78995, 78998, 39423, 79001, 39428, 79008, 79013, 39433, + 79022, 79031, 39439, 79036, 39444, 79045, 79050, 13941, 79054, 79059, + 79064, 39449, 79068, 79077, 50696, 79081, 79084, 79088, 9325, 79094, + 79097, 79102, 79107, 79112, 79116, 4179, 39454, 79119, 79123, 79126, + 79137, 79142, 79146, 79152, 79160, 79173, 79177, 79185, 79194, 79200, + 79205, 79211, 79215, 79221, 79227, 79235, 79240, 79244, 79251, 79257, + 79265, 79274, 79282, 39457, 79289, 79299, 79308, 79316, 79327, 79340, + 79345, 79350, 79354, 79363, 79369, 79376, 79389, 79401, 79412, 79424, + 79431, 79440, 79449, 79458, 79465, 79471, 79478, 79486, 79493, 79501, + 79510, 79518, 79525, 79533, 79542, 79550, 79559, 79569, 79578, 79586, + 79593, 79601, 79610, 79618, 79627, 79637, 79646, 79654, 79663, 79673, + 79682, 79692, 79703, 79713, 79722, 79730, 79737, 79745, 79754, 79762, + 79771, 79781, 79790, 79798, 79807, 79817, 79826, 79836, 79847, 79857, + 79866, 79874, 79883, 79893, 79902, 79912, 79923, 79933, 79942, 79952, + 79963, 79973, 79984, 79996, 80007, 80017, 80026, 80034, 80041, 80049, + 80058, 80066, 80075, 80085, 80094, 80102, 80111, 80121, 80130, 80140, + 80151, 80161, 80170, 80178, 80187, 80197, 80206, 80216, 80227, 80237, + 80246, 80256, 80267, 80277, 80288, 80300, 80311, 80321, 80330, 80338, + 80347, 80357, 80366, 80376, 80387, 80397, 80406, 80416, 80427, 80437, + 80448, 80460, 80471, 80481, 80490, 80500, 80511, 80521, 80532, 80544, + 80555, 80565, 80576, 80588, 80599, 80611, 80624, 80636, 80647, 80657, + 80666, 80674, 80681, 80689, 80698, 80706, 80715, 80725, 80734, 80742, + 80751, 80761, 80770, 80780, 80791, 80801, 80810, 80818, 80827, 80837, + 80846, 80856, 80867, 80877, 80886, 80896, 80907, 80917, 80928, 80940, + 80951, 80961, 80970, 80978, 80987, 80997, 81006, 81016, 81027, 81037, + 81046, 81056, 81067, 81077, 81088, 81100, 81111, 81121, 81130, 81140, + 81151, 81161, 81172, 81184, 81195, 81205, 81216, 81228, 81239, 81251, + 81264, 81276, 81287, 81297, 81306, 81314, 81323, 81333, 81342, 81352, + 81363, 81373, 81382, 81392, 81403, 81413, 81424, 81436, 81447, 81457, + 81466, 81476, 81487, 81497, 81508, 81520, 81531, 81541, 81552, 81564, + 81575, 81587, 81600, 81612, 81623, 81633, 81642, 81652, 81663, 81673, + 81684, 81696, 81707, 81717, 81728, 81740, 81751, 81763, 81776, 81788, + 81799, 81809, 81820, 81832, 81843, 81855, 81868, 81880, 81891, 81903, + 81916, 81928, 81941, 81955, 81968, 81980, 81991, 82001, 82010, 82018, + 82025, 82030, 9090, 82037, 82042, 39467, 82048, 82053, 39472, 82059, + 82066, 25430, 31434, 82071, 82077, 82083, 82091, 82097, 82103, 82110, + 82117, 82122, 82127, 82131, 82136, 82140, 82143, 82147, 82152, 82161, + 82170, 82178, 82184, 82196, 82207, 82211, 3321, 9065, 82216, 82219, + 82222, 82224, 82228, 82232, 82236, 82242, 82247, 31497, 82252, 82256, + 82259, 82264, 82268, 82275, 82281, 82285, 7060, 82289, 82294, 39494, + 82298, 82305, 82314, 82322, 82328, 82339, 82347, 82356, 82364, 82371, + 82378, 82384, 82389, 82400, 39499, 82405, 82416, 82428, 82436, 82447, + 82456, 82464, 82475, 82480, 82488, 2696, 82493, 82502, 41891, 82515, + 82519, 82531, 82539, 82544, 82552, 82563, 21928, 82572, 82578, 82585, + 82593, 82599, 39509, 82604, 4484, 68920, 82611, 82614, 82622, 82635, + 82648, 82661, 82674, 82681, 82692, 82701, 82706, 52343, 52348, 82710, + 82714, 82722, 82729, 82738, 82746, 82752, 82761, 82769, 82776, 82784, + 82788, 82797, 82806, 82816, 82829, 82842, 82852, 39514, 82858, 82865, + 82871, 82877, 39520, 82882, 82885, 82889, 82897, 82906, 52114, 82914, + 82923, 82931, 82938, 82946, 82956, 82965, 82974, 41043, 82983, 82994, + 83009, 83019, 10747, 26246, 83028, 83033, 83038, 83042, 19547, 83047, + 83052, 83058, 83063, 83068, 83074, 83079, 83084, 26206, 83089, 83096, + 83104, 83112, 83120, 83125, 83132, 83139, 83144, 1717, 83148, 83152, + 83160, 83168, 39537, 83174, 83180, 83192, 83198, 83205, 83209, 83216, + 83221, 83228, 83234, 83241, 83252, 83262, 83272, 83284, 83290, 83298, + 83307, 83313, 83323, 83333, 39564, 83342, 83351, 83357, 83369, 83380, + 83387, 83392, 83396, 83404, 83415, 83421, 83426, 83431, 83438, 83446, + 83458, 83468, 83477, 83486, 83494, 83501, 41705, 29006, 83507, 83512, + 83516, 83520, 83525, 83533, 83539, 83550, 83563, 83568, 83575, 39569, + 83580, 83592, 83601, 83609, 83619, 83630, 83643, 83650, 83659, 83668, + 83676, 83681, 83687, 83691, 1410, 83696, 83701, 83706, 83711, 83717, + 83722, 83727, 83733, 83739, 83744, 83748, 83753, 83758, 83763, 69504, + 83768, 83773, 83778, 83783, 83789, 83795, 83800, 83804, 83809, 19546, + 83814, 83820, 83825, 83831, 83836, 83841, 83846, 83851, 83855, 83861, + 83866, 83875, 83880, 83885, 83890, 83895, 83899, 83906, 83912, 4836, + 20800, 3286, 83917, 83921, 83926, 83930, 83934, 83938, 56143, 83942, + 83867, 83944, 83954, 39578, 83957, 83962, 83971, 83977, 7019, 39583, + 83981, 83987, 83992, 83998, 84003, 84007, 84014, 84019, 84029, 84038, + 84042, 84048, 84054, 84060, 84064, 84072, 84079, 84087, 84095, 39588, + 84102, 84105, 84116, 84123, 84129, 84134, 84138, 84144, 84152, 84159, + 84164, 84168, 84177, 84185, 84191, 84196, 84203, 84211, 39593, 84218, + 28458, 84230, 84236, 84241, 84247, 84254, 84260, 25894, 33344, 84266, + 84271, 84277, 84281, 84293, 83900, 83907, 26138, 84303, 84308, 84315, + 84321, 84328, 84334, 84345, 84350, 84358, 10447, 84363, 84366, 84372, + 84376, 84380, 84383, 84389, 84395, 39282, 4837, 1425, 16069, 84402, + 84408, 84414, 84420, 84426, 84432, 84438, 84444, 84450, 84455, 84460, + 84465, 84470, 84475, 84480, 84485, 84490, 84495, 84500, 84505, 84510, + 84515, 84521, 84526, 84531, 84537, 84542, 84547, 84553, 84559, 84565, + 84571, 84577, 84583, 84589, 84595, 84601, 84606, 84611, 84617, 84622, + 84627, 84633, 84638, 84643, 84648, 84653, 84658, 84663, 84668, 84673, + 84678, 84683, 84688, 84693, 84699, 84704, 84709, 84714, 84720, 84725, + 84730, 84735, 84740, 84746, 84751, 84756, 84761, 84766, 84771, 84776, + 84781, 84786, 84791, 84796, 84801, 84806, 84811, 84816, 84821, 84826, + 84831, 84836, 84841, 84847, 84852, 84857, 84862, 84867, 84872, 84877, + 84882, 1065, 148, 84887, 84891, 84895, 84900, 84908, 84912, 84924, 84931, + 84939, 84943, 84956, 84964, 84969, 84974, 32049, 84978, 84983, 84987, + 84992, 84996, 85004, 85008, 25438, 85013, 85017, 72401, 85021, 85024, + 85032, 85040, 85048, 85053, 85058, 85065, 85072, 85078, 85084, 85089, + 85096, 85101, 85109, 77281, 85116, 85121, 72167, 85128, 85134, 85139, + 85143, 85150, 85156, 85163, 72194, 14031, 85171, 85176, 85181, 85185, + 85188, 85199, 85208, 85214, 85219, 85223, 85233, 85242, 50487, 85246, + 85250, 85257, 85270, 85276, 85284, 85291, 85300, 85311, 85322, 85333, + 85344, 85353, 85359, 85368, 85376, 85386, 85399, 85407, 85414, 85425, + 85434, 85440, 85445, 85450, 85456, 85466, 85472, 85482, 85490, 85497, + 85507, 85516, 83582, 85524, 85530, 85538, 85544, 75834, 85551, 85556, + 85559, 85563, 85569, 85573, 85576, 85584, 85590, 85596, 85604, 85616, + 85628, 85635, 85640, 85644, 85655, 85663, 85670, 85682, 85690, 85697, + 85705, 85712, 85718, 85723, 85729, 85739, 85748, 85756, 85761, 85771, + 85780, 51375, 85787, 85791, 85796, 85804, 85811, 85817, 85821, 85831, + 85842, 85850, 85857, 85869, 85881, 85890, 82505, 85897, 85907, 85919, + 85930, 85944, 85952, 85962, 85969, 85977, 85990, 86002, 86011, 86019, + 86029, 86040, 86052, 86061, 86071, 86081, 86091, 86100, 86107, 86116, + 86131, 86139, 86149, 86158, 86166, 86179, 68890, 86194, 86204, 86213, + 86225, 86235, 86247, 86258, 86272, 86286, 86300, 86314, 86328, 86342, + 86356, 86370, 86384, 86398, 86412, 86426, 86440, 86454, 86468, 86482, + 86496, 86510, 86524, 86538, 86552, 86566, 86580, 86594, 86608, 86622, + 86636, 86650, 86664, 86678, 86692, 86706, 86720, 86734, 86748, 86762, + 86776, 86790, 86804, 86818, 86832, 86846, 86860, 86874, 86888, 86902, + 86916, 86930, 86944, 86958, 86972, 86986, 87000, 87014, 87028, 87042, + 87056, 87070, 87084, 87098, 87112, 87126, 87140, 87154, 87168, 87182, + 87196, 87210, 87224, 87238, 87252, 87266, 87280, 87294, 87308, 87322, + 87336, 87350, 87364, 87378, 87392, 87406, 87420, 87434, 87448, 87462, + 87476, 87490, 87504, 87518, 87532, 87546, 87560, 87574, 87588, 87602, + 87616, 87630, 87644, 87658, 87672, 87686, 87700, 87714, 87728, 87742, + 87756, 87770, 87784, 87798, 87812, 87826, 87840, 87854, 87868, 87882, + 87896, 87910, 87924, 87938, 87952, 87966, 87980, 87994, 88008, 88022, + 88036, 88050, 88064, 88078, 88092, 88106, 88120, 88134, 88148, 88162, + 88176, 88190, 88204, 88218, 88232, 88246, 88260, 88274, 88288, 88302, + 88316, 88330, 88344, 88358, 88372, 88386, 88400, 88414, 88428, 88442, + 88456, 88470, 88484, 88498, 88512, 88526, 88540, 88554, 88568, 88582, + 88596, 88610, 88624, 88638, 88652, 88666, 88680, 88694, 88708, 88722, + 88736, 88750, 88764, 88778, 88792, 88806, 88820, 88834, 88848, 88862, + 88876, 88890, 88904, 88918, 88932, 88946, 88960, 88974, 88988, 89002, + 89016, 89030, 89044, 89058, 89072, 89086, 89100, 89114, 89128, 89142, + 89156, 89170, 89184, 89198, 89212, 89226, 89240, 89254, 89268, 89282, + 89296, 89310, 89324, 89338, 89352, 89366, 89380, 89394, 89408, 89422, + 89436, 89450, 89464, 89478, 89492, 89506, 89520, 89534, 89548, 89562, + 89576, 89590, 89604, 89618, 89632, 89646, 89660, 89674, 89688, 89702, + 89716, 89730, 89744, 89758, 89772, 89786, 89800, 89814, 89828, 89842, + 89856, 89870, 89884, 89898, 89912, 89926, 89940, 89954, 89968, 89982, + 89996, 90010, 90024, 90038, 90052, 90066, 90080, 90094, 90108, 90122, + 90136, 90150, 90164, 90178, 90192, 90206, 90220, 90234, 90248, 90262, + 90276, 90290, 90304, 90318, 90332, 90346, 90360, 90374, 90388, 90402, + 90416, 90430, 90444, 90458, 90472, 90486, 90500, 90514, 90528, 90542, + 90556, 90570, 90584, 90598, 90612, 90626, 90640, 90654, 90668, 90682, + 90696, 90710, 90724, 90738, 90752, 90766, 90780, 90794, 90808, 90822, + 90836, 90850, 90864, 90878, 90892, 90906, 90920, 90934, 90948, 90962, + 90976, 90990, 91004, 91018, 91032, 91046, 91060, 91074, 91088, 91102, + 91116, 91130, 91144, 91158, 91172, 91186, 91200, 91214, 91228, 91242, + 91256, 91270, 91284, 91298, 91312, 91326, 91340, 91354, 91368, 91382, + 91396, 91410, 91424, 91438, 91452, 91466, 91480, 91494, 91508, 91522, + 91536, 91550, 91564, 91578, 91592, 91606, 91620, 91634, 91648, 91662, + 91676, 91690, 91704, 91718, 91732, 91746, 91760, 91774, 91788, 91802, + 91816, 91830, 91844, 91858, 91872, 91886, 91900, 91914, 91928, 91942, + 91956, 91970, 91984, 91998, 92012, 92026, 92040, 92054, 92068, 92082, + 92096, 92110, 92124, 92138, 92152, 92166, 92180, 92194, 92208, 92222, + 92236, 92250, 92264, 92278, 92292, 92306, 92320, 92334, 92348, 92362, + 92376, 92390, 92404, 92418, 92432, 92446, 92460, 92474, 92488, 92502, + 92516, 92530, 92544, 92558, 92572, 92586, 92600, 92614, 92628, 92642, + 92656, 92670, 92684, 92698, 92712, 92726, 92740, 92754, 92768, 92782, + 92796, 92810, 92824, 92838, 92852, 92866, 92880, 92894, 92908, 92922, + 92936, 92950, 92964, 92978, 92992, 93006, 93020, 93034, 93048, 93062, + 93076, 93090, 93104, 93118, 93132, 93146, 93160, 93174, 93188, 93202, + 93216, 93230, 93244, 93258, 93272, 93286, 93300, 93314, 93328, 93342, + 93356, 93370, 93384, 93398, 93412, 93426, 93440, 93454, 93468, 93482, + 93496, 93510, 93524, 93538, 93552, 93566, 93580, 93594, 93608, 93622, + 93636, 93650, 93664, 93678, 93692, 93706, 93720, 93734, 93748, 93762, + 93776, 93790, 93804, 93818, 93832, 93846, 93860, 93874, 93888, 93902, + 93916, 93930, 93944, 93958, 93972, 93986, 94000, 94014, 94028, 94042, + 94056, 94070, 94084, 94098, 94112, 94126, 94140, 94154, 94168, 94182, + 94196, 94210, 94224, 94238, 94252, 94266, 94280, 94294, 94308, 94322, + 94336, 94350, 94364, 94378, 94392, 94406, 94420, 94434, 94448, 94462, + 94476, 94490, 94504, 94518, 94532, 94546, 94560, 94574, 94588, 94602, + 94616, 94630, 94644, 94658, 94672, 94686, 94700, 94714, 94728, 94742, + 94756, 94770, 94784, 94798, 94812, 94826, 94840, 94854, 94868, 94882, + 94896, 94910, 94924, 94938, 94952, 94966, 94980, 94994, 95008, 95022, + 95036, 95050, 95064, 95078, 95092, 95106, 95120, 95134, 95148, 95162, + 95176, 95190, 95204, 95218, 95232, 95246, 95260, 95274, 95288, 95302, + 95316, 95330, 95344, 95358, 95372, 95386, 95400, 95414, 95428, 95442, + 95456, 95470, 95484, 95498, 95512, 95526, 95540, 95554, 95568, 95582, + 95596, 95610, 95624, 95638, 95652, 95666, 95680, 95694, 95708, 95722, + 95736, 95750, 95764, 95778, 95792, 95806, 95820, 95834, 95848, 95862, + 95876, 95890, 95904, 95918, 95932, 95946, 95960, 95974, 95988, 96002, + 96016, 96030, 96044, 96058, 96072, 96086, 96100, 96114, 96128, 96142, + 96156, 96170, 96184, 96198, 96212, 96226, 96240, 96254, 96268, 96282, + 96296, 96310, 96324, 96338, 96352, 96366, 96380, 96394, 96408, 96422, + 96436, 96450, 96464, 96478, 96492, 96506, 96520, 96534, 96548, 96562, + 96576, 96590, 96604, 96618, 96632, 96646, 96660, 96674, 96688, 96702, + 96716, 96730, 96744, 96758, 96772, 96786, 96800, 96814, 96828, 96842, + 96856, 96870, 96884, 96898, 96912, 96926, 96940, 96954, 96968, 96982, + 96996, 97010, 97019, 97030, 97041, 97051, 97062, 97070, 97078, 97084, + 97094, 97102, 97108, 35368, 97113, 97119, 97128, 97140, 97145, 97152, + 11370, 21948, 97158, 97167, 97172, 97176, 97181, 97188, 97194, 97199, + 97204, 97212, 97220, 97230, 97235, 97243, 14513, 97247, 97253, 97259, + 97265, 97271, 97277, 97283, 97289, 97295, 97301, 97307, 97313, 97319, + 97325, 97331, 97337, 97343, 97349, 97355, 97361, 97367, 97373, 97379, + 97385, 97391, 97397, 97403, 97409, 97415, 97421, 97427, 97433, 97439, + 97445, 97451, 97457, 97463, 97470, 97476, 97482, 97488, 97494, 97500, + 97506, 97512, 97518, 97524, 97530, 97536, 97542, 97548, 97554, 97560, + 97566, 97572, 97578, 97584, 97590, 97596, 97602, 97608, 97614, 97620, + 97626, 97632, 97638, 97644, 97650, 97656, 97662, 97668, 97674, 97680, + 97686, 97692, 97698, 97704, 97710, 97716, 97722, 97728, 97734, 97740, + 97746, 97752, 97758, 97764, 97770, 97777, 97783, 97789, 97795, 97801, + 97807, 97813, 97819, 97825, 97831, 97837, 97843, 97846, 97848, 97863, + 97876, 97883, 97889, 97900, 97905, 97909, 97914, 97921, 97927, 97932, + 97940, 77884, 77894, 97946, 97953, 97963, 12672, 97970, 97975, 35616, + 97984, 97989, 97996, 98006, 98014, 98022, 98031, 98040, 98046, 98052, + 98057, 98064, 98071, 98076, 98080, 98088, 72211, 98093, 98102, 98110, + 98117, 98122, 98126, 98135, 98141, 98144, 98148, 98157, 98167, 84951, + 98176, 98180, 98188, 98192, 98198, 98209, 98219, 21957, 98230, 98239, + 98247, 98255, 98262, 72230, 9895, 98270, 98274, 98283, 98290, 98293, + 98297, 33215, 98300, 98304, 98309, 98326, 98338, 12630, 98350, 98355, + 98360, 98365, 25545, 98369, 98374, 98379, 98385, 98390, 6640, 98395, + 25549, 98400, 98405, 98411, 98418, 98423, 98428, 98434, 98440, 98446, + 98451, 98457, 98461, 98475, 98483, 98491, 98497, 98502, 98509, 98519, + 98528, 98533, 98538, 98543, 98551, 98561, 98572, 98577, 98583, 98588, + 98597, 70639, 4760, 98602, 98620, 98639, 98652, 98666, 98682, 98689, + 98696, 98705, 98712, 98718, 98725, 98730, 98736, 98741, 98747, 98755, + 98761, 98766, 98771, 98787, 12643, 98801, 98808, 98816, 98822, 98826, + 98829, 98835, 98840, 98845, 98853, 98860, 98865, 98874, 98880, 98885, + 98891, 98897, 98906, 98915, 43462, 98920, 98931, 98938, 98946, 98955, + 14104, 98964, 98970, 98978, 98984, 98990, 98996, 99001, 99008, 99014, + 14115, 99019, 99022, 99027, 39620, 99037, 99046, 99051, 99059, 99066, + 99072, 99077, 99085, 99092, 99103, 99119, 99135, 99151, 99167, 99183, + 99199, 99215, 99231, 99247, 99263, 99279, 99295, 99311, 99327, 99343, + 99359, 99375, 99391, 99407, 99423, 99439, 99455, 99471, 99487, 99503, + 99519, 99535, 99551, 99567, 99583, 99599, 99615, 99631, 99647, 99663, + 99679, 99695, 99711, 99727, 99743, 99759, 99775, 99791, 99807, 99823, + 99839, 99855, 99871, 99887, 99903, 99919, 99935, 99951, 99967, 99983, + 99999, 100015, 100031, 100047, 100063, 100079, 100095, 100111, 100127, + 100143, 100159, 100175, 100191, 100207, 100223, 100239, 100255, 100271, + 100287, 100303, 100319, 100335, 100351, 100367, 100383, 100399, 100415, + 100431, 100447, 100463, 100479, 100495, 100511, 100527, 100543, 100559, + 100575, 100591, 100607, 100623, 100639, 100655, 100671, 100687, 100703, + 100719, 100735, 100751, 100767, 100783, 100799, 100815, 100831, 100847, + 100863, 100879, 100895, 100911, 100927, 100943, 100959, 100975, 100991, + 101007, 101023, 101039, 101055, 101071, 101087, 101103, 101119, 101135, + 101151, 101167, 101183, 101199, 101215, 101231, 101247, 101263, 101279, + 101295, 101311, 101327, 101343, 101359, 101375, 101391, 101407, 101423, + 101439, 101455, 101471, 101487, 101503, 101519, 101535, 101551, 101567, + 101583, 101599, 101615, 101631, 101647, 101663, 101679, 101695, 101711, + 101727, 101743, 101759, 101775, 101791, 101807, 101823, 101839, 101855, + 101871, 101887, 101903, 101919, 101935, 101951, 101967, 101983, 101999, + 102015, 102031, 102047, 102063, 102079, 102095, 102111, 102127, 102143, + 102159, 102175, 102191, 102207, 102223, 102239, 102255, 102271, 102287, + 102303, 102319, 102335, 102351, 102367, 102383, 102399, 102415, 102431, + 102447, 102463, 102479, 102495, 102511, 102527, 102543, 102559, 102575, + 102591, 102607, 102623, 102639, 102655, 102671, 102687, 102703, 102719, + 102735, 102751, 102767, 102783, 102799, 102815, 102831, 102847, 102863, + 102879, 102895, 102911, 102927, 102943, 102959, 102975, 102991, 103007, + 103023, 103039, 103055, 103071, 103087, 103103, 103119, 103135, 103151, + 103167, 103183, 103199, 103215, 103231, 103247, 103263, 103279, 103295, + 103311, 103327, 103343, 103359, 103375, 103391, 103407, 103423, 103439, + 103455, 103471, 103487, 103503, 103519, 103535, 103551, 103567, 103583, + 103599, 103615, 103631, 103647, 103663, 103679, 103695, 103711, 103727, + 103743, 103759, 103775, 103791, 103807, 103823, 103839, 103855, 103871, + 103887, 103903, 103919, 103935, 103951, 103967, 103983, 103999, 104015, + 104031, 104047, 104063, 104079, 104095, 104111, 104127, 104143, 104159, + 104175, 104191, 104207, 104223, 104239, 104255, 104271, 104287, 104303, + 104319, 104335, 104351, 104367, 104383, 104399, 104415, 104431, 104447, + 104463, 104479, 104495, 104511, 104527, 104543, 104559, 104575, 104591, + 104607, 104623, 104639, 104655, 104671, 104687, 104703, 104719, 104735, + 104751, 104767, 104783, 104799, 104815, 104831, 104847, 104863, 104879, + 104895, 104911, 104927, 104943, 104959, 104975, 104991, 105007, 105023, + 105039, 105055, 105071, 105087, 105103, 105119, 105135, 105151, 105167, + 105183, 105199, 105215, 105231, 105247, 105263, 105279, 105295, 105311, + 105327, 105343, 105359, 105375, 105391, 105407, 105423, 105439, 105455, + 105471, 105487, 105503, 105519, 105535, 105551, 105567, 105583, 105599, + 105615, 105631, 105647, 105663, 105679, 105695, 105711, 105727, 105743, + 105759, 105775, 105791, 105807, 105823, 105839, 105855, 105871, 105887, + 105903, 105919, 105935, 105951, 105967, 105983, 105999, 106015, 106031, + 106047, 106063, 106079, 106095, 106111, 106127, 106143, 106159, 106175, + 106191, 106207, 106223, 106239, 106255, 106271, 106287, 106303, 106319, + 106335, 106351, 106367, 106383, 106399, 106415, 106431, 106447, 106463, + 106479, 106495, 106511, 106527, 106543, 106559, 106575, 106591, 106607, + 106623, 106639, 106655, 106671, 106687, 106703, 106719, 106735, 106751, + 106767, 106783, 106799, 106815, 106831, 106847, 106863, 106879, 106895, + 106911, 106927, 106943, 106959, 106975, 106991, 107007, 107023, 107039, + 107055, 107071, 107087, 107103, 107119, 107135, 107151, 107167, 107183, + 107199, 107215, 107231, 107247, 107263, 107279, 107295, 107311, 107327, + 107343, 107359, 107375, 107391, 107407, 107423, 107439, 107455, 107471, + 107487, 107503, 107519, 107535, 107551, 107567, 107583, 107599, 107615, + 107631, 107647, 107663, 107679, 107695, 107711, 107727, 107743, 107759, + 107775, 107791, 107807, 107823, 107839, 107855, 107871, 107887, 107903, + 107919, 107935, 107951, 107967, 107983, 107999, 108015, 108031, 108047, + 108063, 108079, 108095, 108111, 108127, 108143, 108159, 108175, 108191, + 108207, 108223, 108239, 108255, 108271, 108287, 108303, 108319, 108335, + 108351, 108367, 108383, 108399, 108415, 108431, 108447, 108463, 108479, + 108495, 108511, 108527, 108543, 108559, 108575, 108591, 108607, 108623, + 108639, 108655, 108671, 108687, 108703, 108719, 108735, 108751, 108767, + 108783, 108799, 108815, 108831, 108847, 108863, 108879, 108895, 108911, + 108927, 108943, 108959, 108975, 108991, 109007, 109023, 109039, 109055, + 109071, 109087, 109103, 109119, 109135, 109151, 109167, 109183, 109199, + 109215, 109231, 109247, 109263, 109279, 109295, 109311, 109327, 109343, + 109359, 109375, 109391, 109407, 109423, 109439, 109455, 109471, 109487, + 109503, 109519, 109535, 109551, 109567, 109583, 109599, 109615, 109631, + 109647, 109663, 109679, 109695, 109711, 109727, 109743, 109759, 109775, + 109791, 109807, 109823, 109839, 109855, 109871, 109887, 109903, 109919, + 109935, 109951, 109967, 109983, 109999, 110015, 110031, 110047, 110063, + 110079, 110095, 110111, 110127, 110143, 110159, 110175, 110191, 110207, + 110223, 110239, 110255, 110271, 110287, 110303, 110319, 110335, 110351, + 110367, 110383, 110399, 110415, 110431, 110447, 110463, 110479, 110495, + 110511, 110527, 110543, 110559, 110575, 110591, 110607, 110623, 110639, + 110655, 110671, 110687, 110703, 110719, 110735, 110751, 110767, 110783, + 110799, 110815, 110831, 110847, 110863, 110879, 110895, 110911, 110927, + 110943, 110959, 110975, 110991, 111007, 111023, 111039, 111055, 111071, + 111087, 111103, 111119, 111135, 111151, 111167, 111183, 111199, 111215, + 111231, 111247, 111263, 111279, 111295, 111311, 111327, 111343, 111359, + 111375, 111391, 111407, 111423, 111439, 111455, 111471, 111487, 111503, + 111519, 111535, 111551, 111567, 111583, 111599, 111615, 111631, 111647, + 111663, 111679, 111695, 111711, 111727, 111743, 111759, 111775, 111791, + 111807, 111823, 111839, 111855, 111871, 111887, 111903, 111919, 111935, + 111951, 111967, 111983, 111999, 112015, 112031, 112047, 112063, 112079, + 112095, 112111, 112127, 112143, 112159, 112175, 112191, 112207, 112223, + 112239, 112255, 112271, 112287, 112303, 112319, 112335, 112351, 112367, + 112383, 112399, 112415, 112431, 112447, 112463, 112479, 112495, 112511, + 112527, 112543, 112559, 112575, 112591, 112607, 112623, 112639, 112655, + 112671, 112687, 112703, 112719, 112735, 112751, 112767, 112783, 112799, + 112815, 112831, 112847, 112863, 112879, 112895, 112911, 112927, 112943, + 112959, 112969, 112978, 112983, 112991, 77204, 112996, 113002, 113007, + 113014, 113023, 113031, 113035, 4338, 113041, 113048, 113054, 113058, + 20549, 46595, 3295, 113063, 113067, 113071, 113078, 113084, 113093, + 113099, 113106, 113110, 113131, 113153, 113169, 113186, 113205, 113214, + 113224, 113232, 113239, 113246, 113252, 33070, 113266, 113270, 113276, + 113284, 113296, 113302, 113310, 113317, 113322, 113327, 113331, 113339, + 113346, 113350, 113356, 113362, 113367, 3972, 52543, 113373, 113377, + 113381, 113385, 113390, 113395, 113400, 113406, 113412, 113418, 113425, + 113431, 113438, 113444, 113450, 113455, 113461, 113466, 113470, 105563, + 113475, 105627, 52558, 113480, 113485, 113493, 113497, 113502, 113509, + 113518, 113525, 113531, 113540, 113544, 113551, 113555, 113558, 113565, + 113571, 113580, 113590, 113600, 113605, 113609, 113616, 113624, 113633, + 113637, 113645, 113651, 113656, 113661, 113667, 113673, 113678, 113682, + 31947, 113688, 113692, 113696, 113699, 113704, 113712, 113722, 113728, + 113733, 113743, 49664, 113751, 113763, 113769, 113776, 113782, 113786, + 113791, 113797, 113809, 113820, 113827, 113833, 113840, 113847, 113859, + 113866, 113872, 25629, 113876, 113884, 113890, 113897, 113903, 113909, + 113915, 113920, 113925, 113930, 113934, 113943, 113951, 113962, 7934, + 113967, 19985, 113973, 113977, 113981, 113985, 113993, 114002, 114006, + 114013, 114022, 114030, 114043, 114049, 106139, 36551, 114054, 114056, + 114061, 114066, 114071, 114076, 114081, 114086, 114091, 114096, 114101, + 114106, 114111, 114116, 114121, 114126, 114132, 114137, 114142, 114147, + 114152, 114157, 114162, 114167, 114172, 114178, 114184, 114190, 114195, + 114200, 114212, 114217, 1935, 54, 114222, 114227, 39630, 114231, 39635, + 39640, 39646, 39651, 114235, 39656, 26815, 114257, 114261, 114265, + 114270, 114274, 39660, 114278, 114286, 114293, 114299, 114309, 39665, + 114316, 114319, 114324, 114328, 114337, 11168, 114345, 39670, 26659, + 114348, 114352, 114360, 1307, 114365, 39681, 114368, 114373, 114378, + 31188, 31198, 43060, 114383, 114388, 114393, 114398, 114404, 114409, + 114418, 114423, 114432, 114440, 114447, 114453, 114458, 114463, 114468, + 114478, 114487, 114495, 114500, 114508, 114512, 114520, 114524, 114531, + 114538, 114546, 114553, 39485, 46310, 114559, 114565, 114570, 114575, + 14548, 11961, 114580, 114585, 114590, 114596, 114603, 114609, 114618, + 114623, 114631, 114641, 114648, 114658, 114664, 114669, 114675, 114679, + 21979, 114686, 44045, 114699, 114704, 114711, 114717, 114732, 37615, + 75612, 114745, 114749, 114758, 114767, 114774, 114780, 114788, 114794, + 114802, 114811, 114819, 114826, 46430, 114832, 114835, 114839, 114843, + 114847, 11982, 114853, 114860, 114866, 114874, 114879, 114883, 29180, + 114889, 114892, 114900, 114907, 114915, 114928, 114942, 114949, 114955, + 114962, 114968, 39695, 114972, 114978, 114986, 114993, 115001, 115009, + 115015, 39700, 115023, 115029, 115034, 115044, 115050, 115059, 37410, + 42408, 115067, 115072, 115077, 115081, 115086, 115090, 115098, 115103, + 17981, 18806, 49686, 115107, 115112, 39705, 18138, 115116, 115128, + 115133, 115137, 115144, 115153, 115157, 115165, 115171, 115176, 115184, + 115192, 115200, 115208, 115216, 115224, 115235, 115241, 9132, 115246, + 115252, 115257, 115262, 115273, 115282, 115294, 115309, 40017, 115315, + 20104, 39709, 115319, 115326, 115332, 115336, 29317, 115343, 115349, + 115356, 48811, 115365, 115371, 115380, 115386, 115391, 115399, 115405, + 115410, 39719, 115415, 115424, 115433, 113815, 115442, 115449, 115455, + 115461, 115470, 115480, 115486, 115494, 115501, 115505, 39724, 115508, + 39730, 1346, 115513, 115521, 115529, 115539, 115548, 115556, 115563, + 115573, 39741, 115577, 115579, 115583, 115588, 115592, 115596, 115602, + 115607, 115611, 115622, 115627, 115633, 115638, 115647, 115652, 3300, + 115656, 115663, 115667, 115676, 115684, 115692, 115699, 115704, 115709, + 74113, 115713, 115716, 115722, 115730, 115736, 115740, 115745, 115752, + 115757, 115762, 115766, 115773, 115779, 115784, 42439, 115788, 115791, + 115796, 115800, 115805, 115812, 115817, 115821, 47780, 115829, 31207, + 31216, 115835, 115841, 115847, 115852, 115856, 115859, 115869, 115878, + 115883, 115889, 115896, 115902, 115906, 115914, 115919, 42445, 85210, + 115923, 115931, 115938, 115944, 115951, 115956, 115963, 115968, 115972, + 115978, 115983, 69106, 115989, 115995, 10386, 116000, 116005, 116009, + 116014, 116019, 116024, 116028, 116033, 116038, 116044, 116049, 116054, + 116060, 116066, 116071, 116075, 116080, 116085, 116090, 116094, 29316, + 116099, 116104, 116110, 116116, 116122, 116127, 116131, 116136, 116141, + 109915, 116146, 116151, 116156, 116161, 109979, 52813, 116166, 39749, + 116174, 116178, 116186, 116194, 116205, 116210, 116214, 27294, 82608, + 116219, 116225, 116230, 4649, 116240, 116247, 116252, 116260, 116269, + 116274, 116278, 116283, 116287, 116295, 116303, 116310, 77470, 116316, + 116324, 116331, 116342, 116348, 116354, 39759, 116357, 116364, 116372, + 116377, 116381, 33589, 71792, 116387, 116392, 116399, 116404, 10275, + 116408, 116416, 116423, 116430, 116439, 116446, 116452, 116466, 116474, + 6724, 116236, 116480, 116485, 116491, 116495, 116498, 116506, 116513, + 116518, 116531, 116538, 116544, 116548, 116556, 116561, 116568, 116574, + 116579, 72070, 116584, 116587, 116596, 116603, 110187, 116609, 116612, + 116620, 116626, 116635, 116645, 116655, 116664, 116675, 116683, 116694, + 116699, 116703, 116708, 116712, 43191, 116720, 18771, 43200, 116725, + 101706, 101722, 101738, 101754, 101770, 116730, 101802, 101818, 101834, + 101850, 101962, 101978, 116734, 102010, 102026, 116738, 116742, 116746, + 116750, 102266, 102298, 116754, 102330, 116758, 116762, 102474, 102490, + 102506, 102522, 116766, 102586, 102602, 116770, 102730, 102746, 102762, + 102778, 102794, 102810, 102826, 102842, 102858, 102874, 102986, 103002, + 103018, 103034, 103050, 103066, 103082, 103098, 103114, 103130, 116774, + 104922, 105034, 105098, 105114, 105130, 105146, 105162, 105178, 105290, + 105306, 105322, 116778, 105370, 116782, 105402, 105418, 105434, 116786, + 116791, 116796, 116801, 116806, 116811, 116816, 116820, 116824, 116829, + 116834, 116838, 116843, 116848, 116852, 116857, 116862, 116867, 116872, + 116876, 116881, 116886, 116890, 116895, 116899, 116903, 116907, 116911, + 116916, 116920, 116924, 116928, 116932, 116936, 116940, 116944, 116948, + 116952, 116957, 116962, 116967, 116972, 116977, 116982, 116987, 116992, + 116997, 117002, 117006, 117010, 117014, 117018, 117022, 117026, 117031, + 117035, 117040, 117044, 117049, 117054, 117058, 117062, 117067, 117071, + 117075, 117079, 117083, 117087, 117091, 117095, 117099, 117103, 117107, + 117111, 117115, 117119, 117123, 117128, 117133, 117137, 117141, 117145, + 117149, 117153, 117157, 117162, 117166, 117170, 117174, 117178, 117182, + 117186, 117191, 117195, 117200, 117204, 117208, 117212, 117216, 117220, + 117224, 117228, 117232, 117236, 117240, 117244, 117249, 117253, 117257, + 117261, 117265, 117269, 117273, 117277, 117281, 117285, 117289, 117293, + 117298, 117302, 117306, 117311, 117316, 117320, 117324, 117328, 117332, + 117336, 117340, 117344, 117348, 117353, 117357, 117362, 117366, 117371, + 117375, 117380, 117384, 117390, 117395, 117399, 117404, 117408, 117413, + 117417, 117422, 117426, 117431, 1429, 117435, 117439, 3042, 1705, 28453, + 1602, 31143, 117443, 3051, 117447, 1276, 117452, 1218, 117456, 117460, + 117464, 117468, 117472, 117476, 3075, 117480, 117488, 117495, 117502, + 117516, 3079, 8044, 117525, 117533, 117540, 117551, 117560, 117564, + 117571, 117583, 117596, 117609, 117620, 117625, 117632, 117644, 117648, + 3083, 14185, 117658, 117663, 117672, 117682, 117687, 117696, 3087, + 117704, 117708, 117713, 117720, 117726, 117731, 117740, 117748, 117760, + 117770, 1223, 15645, 117783, 117787, 117793, 117807, 117819, 117831, + 117839, 117849, 117858, 117867, 117876, 117884, 117895, 117903, 4657, + 117913, 117924, 117933, 117939, 117954, 117961, 117967, 117972, 43334, + 117977, 3111, 15649, 117981, 117986, 117993, 10206, 118002, 118008, 4695, + 118018, 3116, 39121, 118027, 71682, 118034, 118038, 118044, 118055, + 118061, 118066, 118073, 118079, 118087, 118094, 118100, 118111, 118127, + 118137, 118146, 118157, 118166, 118173, 118179, 118189, 118197, 118203, + 118218, 118224, 118229, 118233, 118240, 118248, 118252, 118255, 118261, + 118268, 118274, 118282, 118291, 118299, 118305, 118314, 52116, 118328, + 118333, 118339, 17732, 118344, 118357, 118369, 118378, 118386, 118393, + 118397, 118401, 118404, 118411, 118418, 118426, 118434, 118443, 118451, + 17631, 118459, 118464, 118468, 118480, 118487, 118494, 118503, 954, + 118513, 118522, 118533, 3137, 118537, 118541, 118547, 118560, 118572, + 118582, 118591, 118603, 32105, 118614, 118622, 118631, 118642, 118653, + 118663, 118673, 118681, 118690, 118698, 13604, 118705, 118709, 118712, + 118717, 118722, 118726, 118732, 1228, 118739, 118743, 14281, 118747, + 118751, 118762, 118771, 118779, 118788, 118796, 118812, 118823, 118832, + 118840, 118852, 118863, 118879, 118889, 118910, 118924, 118937, 118945, + 118952, 8090, 118965, 118970, 118976, 6733, 118982, 118985, 118992, + 119002, 9266, 119009, 119014, 119019, 119026, 119034, 119042, 119048, + 119053, 119059, 119063, 119071, 119080, 119088, 119093, 119102, 119109, + 11418, 11427, 119115, 119126, 119132, 119137, 119143, 3153, 3158, 119149, + 1063, 119155, 119162, 119169, 119182, 119192, 119197, 2324, 87, 119205, + 119212, 119217, 119225, 119235, 119244, 119250, 119259, 119267, 119277, + 119281, 119285, 119290, 119294, 119306, 3181, 119314, 119322, 119327, + 119338, 119349, 119361, 119372, 119382, 119391, 26013, 119396, 119402, + 119407, 119417, 119427, 119432, 34323, 119438, 119443, 119452, 26035, + 119456, 26046, 119461, 4783, 8, 119468, 119477, 119484, 119491, 119497, + 119502, 119506, 119512, 34353, 119517, 119522, 72367, 119527, 119532, + 119538, 119544, 119552, 119557, 119565, 119573, 119582, 119589, 119595, + 119602, 119608, 119615, 119620, 47649, 52010, 119626, 119636, 1822, 32, + 119643, 119648, 119661, 119666, 119674, 119679, 119685, 3207, 30884, + 3221, 119690, 119698, 119705, 119710, 119715, 119724, 4340, 4351, 73711, + 119732, 119736, 1629, 1862, 119741, 119746, 119753, 34774, 1866, 331, + 119760, 119766, 119771, 3229, 119775, 119780, 119787, 1870, 119792, + 119798, 119803, 119815, 6978, 119825, 119832, 1877, 119838, 119843, + 119850, 119857, 119872, 119879, 119890, 119895, 119903, 2772, 119907, + 119919, 119924, 119928, 119934, 34195, 2329, 119938, 119949, 119953, + 119957, 119963, 119967, 119976, 119980, 119991, 119995, 2375, 38938, + 119999, 120009, 120017, 3320, 120023, 120032, 120040, 10752, 120045, + 120053, 120058, 120062, 120071, 120078, 120084, 3290, 17796, 120088, + 120101, 44058, 120119, 120124, 120132, 120140, 120150, 11759, 15773, + 120162, 120175, 120182, 120192, 120206, 120213, 120229, 120236, 120242, + 26093, 14980, 120249, 120256, 120266, 120275, 52812, 120287, 120295, + 52947, 120302, 120305, 120311, 120317, 120323, 120329, 120335, 120342, + 120349, 120355, 120361, 120367, 120373, 120379, 120385, 120391, 120397, + 120403, 120409, 120415, 120421, 120427, 120433, 120439, 120445, 120451, + 120457, 120463, 120469, 120475, 120481, 120487, 120493, 120499, 120505, + 120511, 120517, 120523, 120529, 120535, 120541, 120547, 120553, 120559, + 120565, 120571, 120577, 120583, 120589, 120595, 120601, 120607, 120613, + 120619, 120625, 120631, 120637, 120643, 120649, 120655, 120662, 120668, + 120675, 120682, 120688, 120695, 120702, 120708, 120714, 120720, 120726, + 120732, 120738, 120744, 120750, 120756, 120762, 120768, 120774, 120780, + 120786, 120792, 3304, 10720, 120798, 120808, 120814, 120822, 120826, + 117716, 3308, 120830, 114044, 25758, 4701, 4265, 120834, 3314, 120838, + 120848, 120854, 120860, 120866, 120872, 120878, 120884, 120890, 120896, + 120902, 120908, 120914, 120920, 120926, 120932, 120938, 120944, 120950, + 120956, 120962, 120968, 120974, 120980, 120986, 120992, 120998, 121005, + 121012, 121018, 121024, 121030, 121036, 121042, 121048, 1233, 121054, + 121059, 121064, 121069, 121074, 121079, 121084, 121089, 121094, 121098, + 121102, 121106, 121110, 121114, 121118, 121122, 121126, 121130, 121136, + 121142, 121148, 121154, 121158, 121162, 121166, 121170, 121174, 121178, + 121182, 121186, 121190, 121195, 121200, 121205, 121210, 121215, 121220, + 121225, 121230, 121235, 121240, 121245, 121250, 121255, 121260, 121265, + 121270, 121275, 121280, 121285, 121290, 121295, 121300, 121305, 121310, + 121315, 121320, 121325, 121330, 121335, 121340, 121345, 121350, 121355, + 121360, 121365, 121370, 121375, 121380, 121385, 121390, 121395, 121400, + 121405, 121410, 121415, 121420, 121425, 121430, 121435, 121440, 121445, + 121450, 121455, 121460, 121465, 121470, 121475, 121480, 121485, 121490, + 121495, 121500, 121505, 121510, 121515, 121520, 121525, 121530, 121535, + 121540, 121545, 121550, 121555, 121560, 121565, 121570, 121575, 121580, + 121585, 121590, 121595, 121600, 121605, 121610, 121615, 121620, 121625, + 121630, 121635, 121640, 121645, 121650, 121655, 121660, 121665, 121670, + 121675, 121680, 121685, 121690, 121695, 121700, 121705, 121710, 121715, + 121720, 121725, 121730, 121735, 121740, 121745, 121750, 121755, 121760, + 121765, 121770, 121775, 121780, 121785, 121790, 121795, 121800, 121805, + 121810, 121815, 121820, 121825, 121830, 121835, 121840, 121845, 121850, + 121855, 121860, 121865, 121870, 121875, 121880, 121885, 121890, 121895, + 121900, 121905, 121910, 121915, 121920, 121925, 121930, 121935, 121940, + 121945, 121950, 121955, 121960, 121965, 121970, 121975, 121980, 121985, + 121990, 121995, 122000, 122005, 122010, 122015, 122020, 122025, 122030, + 122035, 122040, 122045, 122050, 122055, 122060, 122065, 122070, 122075, + 122080, 122086, 122091, 122096, 122101, 122106, 122111, 122116, 122121, + 122127, 122132, 122137, 122142, 122147, 122152, 122157, 122162, 122167, + 122172, 122177, 122182, 122187, 122192, 122197, 122202, 122207, 122212, + 122217, 122222, 122227, 122232, 122237, 122242, 122247, 122252, 122257, + 122262, 122267, 122272, 122277, 122282, 122287, 122296, 122301, 122310, + 122315, 122324, 122329, 122338, 122343, 122352, 122357, 122366, 122371, + 122380, 122385, 122394, 122399, 122404, 122413, 122417, 122426, 122431, + 122440, 122445, 122454, 122459, 122468, 122473, 122482, 122487, 122496, + 122501, 122510, 122515, 122524, 122529, 122538, 122543, 122552, 122557, + 122562, 122567, 122572, 122577, 122582, 122587, 122591, 122596, 122601, + 122606, 122611, 122616, 122621, 122627, 122632, 122637, 122642, 122648, + 122652, 122657, 122663, 122668, 122673, 122678, 122683, 122688, 122693, + 122698, 122703, 122708, 122713, 122719, 122724, 122729, 122734, 122740, + 122745, 122750, 122755, 122760, 122766, 122771, 122776, 122781, 122786, + 122791, 122797, 122802, 122807, 122812, 122817, 122822, 122827, 122832, + 122837, 122842, 122847, 122852, 122857, 122862, 122867, 122872, 122877, + 122882, 122887, 122892, 122897, 122902, 122907, 122912, 122918, 122924, + 122930, 122935, 122940, 122945, 122950, 122956, 122962, 122968, 122973, + 122978, 122983, 122989, 122994, 122999, 123004, 123009, 123014, 123019, + 123024, 123029, 123034, 123039, 123044, 123049, 123054, 123059, 123064, + 123069, 123075, 123081, 123087, 123092, 123097, 123102, 123107, 123113, + 123119, 123125, 123130, 123135, 123140, 123145, 123150, 123155, 123160, + 123165, 123170, 19463, 123175, 123181, 123186, 123191, 123196, 123201, + 123206, 123212, 123217, 123222, 123227, 123232, 123237, 123243, 123248, + 123253, 123258, 123263, 123268, 123273, 123278, 123283, 123288, 123293, + 123298, 123303, 123308, 123313, 123318, 123323, 123328, 123333, 123338, + 123343, 123348, 123353, 123359, 123364, 123369, 123374, 123379, 123384, + 123389, 123394, 123399, 123404, 123409, 123414, 123419, 123424, 123429, + 123434, 123439, 123444, 123449, 123454, 123459, 123464, 123469, 123474, + 123479, 123484, 123489, 123494, 123499, 123504, 123509, 123514, 123519, + 123524, 123529, 123534, 123539, 123544, 123549, 123554, 123559, 123565, + 123570, 123575, 123580, 123585, 123590, 123595, 123600, 123605, 123610, + 123615, 123620, 123626, 123631, 123637, 123642, 123647, 123652, 123657, + 123662, 123667, 123673, 123678, 123683, 123689, 123694, 123699, 123704, + 123709, 123714, 123720, 123726, 123731, 123736, 14614, 123741, 123746, + 123751, 123756, 123761, 123766, 123771, 123776, 123781, 123786, 123791, + 123796, 123801, 123806, 123811, 123816, 123821, 123826, 123831, 123836, + 123841, 123846, 123851, 123856, 123861, 123866, 123871, 123876, 123881, + 123886, 123891, 123896, 123901, 123906, 123911, 123916, 123921, 123926, + 123931, 123936, 123941, 123946, 123951, 123956, 123961, 123966, 123971, + 123976, 123981, 123986, 123991, 123996, 124001, 124006, 124011, 124016, + 124021, 124026, 124031, 124036, 124041, 124046, 124051, 124056, 124061, + 124067, 124072, 124077, 124082, 124087, 124093, 124098, 124103, 124108, + 124113, 124118, 124123, 124129, 124134, 124139, 124144, 124149, 124154, + 124160, 124165, 124170, 124175, 124180, 124185, 124191, 124196, 124201, + 124206, 124211, 124216, 124222, 124228, 124233, 124238, 124243, 124249, + 124255, 124261, 124266, 124271, 124277, 124283, 124288, 124294, 124300, + 124306, 124311, 124316, 124322, 124327, 124333, 124338, 124344, 124353, + 124358, 124363, 124369, 124374, 124380, 124385, 124390, 124395, 124400, + 124405, 124410, 124415, 124420, 124425, 124430, 124435, 124440, 124445, + 124450, 124455, 124460, 124465, 124470, 124475, 124480, 124485, 124490, + 124495, 124500, 124505, 124510, 124515, 124520, 124525, 124530, 124535, + 124541, 124547, 124553, 124558, 124563, 124568, 124573, 124578, 124583, + 124588, 124593, 124598, 124603, 124608, 124613, 124618, 124623, 124628, + 124633, 124638, 124643, 124648, 124653, 124659, 124665, 124670, 124676, + 124681, 124686, 124692, 124697, 124703, 124708, 124714, 124719, 124725, + 124730, 124736, 124741, 124746, 124751, 124756, 124761, 124766, 124771, + 120849, 120855, 120861, 120867, 124777, 120873, 120879, 124783, 120885, + 120891, 120897, 120903, 120909, 120915, 120921, 120927, 120933, 124789, + 120939, 120945, 120951, 124795, 120957, 120963, 120969, 120975, 124801, + 120981, 120987, 120993, 121013, 124807, 124813, 121019, 124819, 121025, + 121031, 121037, 121043, 121049, 124825, 3331, 3336, 124830, 3351, 3356, + 3361, 124835, 124838, 124844, 124850, 124857, 124862, 124867, 2380, }; /* code->name phrasebook */ #define phrasebook_shift 7 #define phrasebook_short 190 static const unsigned char phrasebook[] = { - 0, 201, 242, 233, 175, 77, 207, 247, 77, 31, 57, 236, 110, 57, 210, 4, - 57, 251, 86, 250, 255, 45, 210, 103, 50, 210, 103, 250, 143, 107, 57, - 242, 26, 228, 57, 232, 42, 201, 58, 202, 18, 17, 191, 77, 17, 108, 17, - 109, 17, 139, 17, 137, 17, 153, 17, 173, 17, 181, 17, 176, 17, 184, 242, - 35, 204, 20, 219, 156, 57, 234, 1, 57, 230, 170, 57, 208, 8, 77, 242, 24, - 250, 132, 8, 6, 1, 65, 8, 6, 1, 250, 70, 8, 6, 1, 247, 145, 8, 6, 1, 238, - 80, 8, 6, 1, 73, 8, 6, 1, 233, 134, 8, 6, 1, 232, 14, 8, 6, 1, 230, 83, - 8, 6, 1, 70, 8, 6, 1, 223, 7, 8, 6, 1, 222, 125, 8, 6, 1, 170, 8, 6, 1, - 218, 147, 8, 6, 1, 215, 47, 8, 6, 1, 74, 8, 6, 1, 210, 226, 8, 6, 1, 208, - 97, 8, 6, 1, 148, 8, 6, 1, 206, 3, 8, 6, 1, 200, 39, 8, 6, 1, 69, 8, 6, - 1, 196, 8, 8, 6, 1, 193, 221, 8, 6, 1, 192, 235, 8, 6, 1, 192, 159, 8, 6, - 1, 191, 166, 45, 51, 248, 5, 207, 14, 202, 18, 50, 51, 248, 5, 242, 210, - 252, 8, 131, 219, 88, 230, 177, 252, 8, 8, 2, 1, 65, 8, 2, 1, 250, 70, 8, - 2, 1, 247, 145, 8, 2, 1, 238, 80, 8, 2, 1, 73, 8, 2, 1, 233, 134, 8, 2, - 1, 232, 14, 8, 2, 1, 230, 83, 8, 2, 1, 70, 8, 2, 1, 223, 7, 8, 2, 1, 222, - 125, 8, 2, 1, 170, 8, 2, 1, 218, 147, 8, 2, 1, 215, 47, 8, 2, 1, 74, 8, - 2, 1, 210, 226, 8, 2, 1, 208, 97, 8, 2, 1, 148, 8, 2, 1, 206, 3, 8, 2, 1, - 200, 39, 8, 2, 1, 69, 8, 2, 1, 196, 8, 8, 2, 1, 193, 221, 8, 2, 1, 192, - 235, 8, 2, 1, 192, 159, 8, 2, 1, 191, 166, 45, 238, 124, 248, 5, 81, 219, - 88, 50, 238, 124, 248, 5, 198, 147, 213, 24, 201, 242, 223, 65, 233, 175, - 77, 246, 232, 57, 209, 1, 57, 238, 123, 57, 192, 71, 57, 247, 230, 164, - 205, 49, 57, 236, 253, 238, 215, 57, 232, 255, 211, 40, 223, 116, 219, - 195, 54, 251, 65, 207, 247, 77, 212, 255, 57, 202, 27, 228, 58, 207, 73, - 57, 217, 125, 237, 80, 57, 209, 72, 57, 200, 177, 109, 200, 177, 139, - 251, 251, 252, 8, 216, 72, 57, 209, 133, 57, 82, 236, 96, 246, 243, 200, - 177, 108, 217, 21, 211, 40, 223, 116, 206, 198, 54, 251, 65, 207, 247, - 77, 193, 243, 232, 80, 91, 208, 17, 193, 243, 232, 80, 91, 230, 37, 193, - 243, 232, 80, 115, 208, 15, 223, 65, 208, 8, 77, 8, 6, 1, 41, 4, 230, - 176, 8, 6, 1, 41, 4, 251, 250, 8, 6, 1, 41, 4, 242, 209, 8, 6, 1, 41, 4, - 198, 147, 8, 6, 1, 41, 4, 236, 253, 8, 6, 1, 41, 4, 206, 184, 56, 8, 6, - 1, 251, 229, 8, 6, 1, 247, 146, 4, 246, 243, 8, 6, 1, 234, 227, 4, 230, - 176, 8, 6, 1, 234, 227, 4, 251, 250, 8, 6, 1, 234, 227, 4, 242, 209, 8, - 6, 1, 234, 227, 4, 236, 253, 8, 6, 1, 228, 44, 4, 230, 176, 8, 6, 1, 228, - 44, 4, 251, 250, 8, 6, 1, 228, 44, 4, 242, 209, 8, 6, 1, 228, 44, 4, 236, - 253, 8, 6, 1, 233, 206, 8, 6, 1, 215, 48, 4, 198, 147, 8, 6, 1, 186, 4, - 230, 176, 8, 6, 1, 186, 4, 251, 250, 8, 6, 1, 186, 4, 242, 209, 8, 6, 1, - 186, 4, 198, 147, 8, 6, 1, 186, 4, 236, 253, 215, 112, 57, 8, 6, 1, 186, - 4, 105, 8, 6, 1, 126, 4, 230, 176, 8, 6, 1, 126, 4, 251, 250, 8, 6, 1, - 126, 4, 242, 209, 8, 6, 1, 126, 4, 236, 253, 8, 6, 1, 192, 160, 4, 251, - 250, 8, 6, 1, 198, 228, 8, 2, 1, 203, 122, 206, 3, 8, 2, 1, 41, 4, 230, - 176, 8, 2, 1, 41, 4, 251, 250, 8, 2, 1, 41, 4, 242, 209, 8, 2, 1, 41, 4, - 198, 147, 8, 2, 1, 41, 4, 236, 253, 8, 2, 1, 41, 4, 206, 184, 56, 8, 2, - 1, 251, 229, 8, 2, 1, 247, 146, 4, 246, 243, 8, 2, 1, 234, 227, 4, 230, - 176, 8, 2, 1, 234, 227, 4, 251, 250, 8, 2, 1, 234, 227, 4, 242, 209, 8, - 2, 1, 234, 227, 4, 236, 253, 8, 2, 1, 228, 44, 4, 230, 176, 8, 2, 1, 228, - 44, 4, 251, 250, 8, 2, 1, 228, 44, 4, 242, 209, 8, 2, 1, 228, 44, 4, 236, - 253, 8, 2, 1, 233, 206, 8, 2, 1, 215, 48, 4, 198, 147, 8, 2, 1, 186, 4, - 230, 176, 8, 2, 1, 186, 4, 251, 250, 8, 2, 1, 186, 4, 242, 209, 8, 2, 1, - 186, 4, 198, 147, 8, 2, 1, 186, 4, 236, 253, 236, 155, 57, 8, 2, 1, 186, - 4, 105, 8, 2, 1, 126, 4, 230, 176, 8, 2, 1, 126, 4, 251, 250, 8, 2, 1, - 126, 4, 242, 209, 8, 2, 1, 126, 4, 236, 253, 8, 2, 1, 192, 160, 4, 251, - 250, 8, 2, 1, 198, 228, 8, 2, 1, 192, 160, 4, 236, 253, 8, 6, 1, 41, 4, - 217, 125, 8, 2, 1, 41, 4, 217, 125, 8, 6, 1, 41, 4, 247, 244, 8, 2, 1, - 41, 4, 247, 244, 8, 6, 1, 41, 4, 211, 126, 8, 2, 1, 41, 4, 211, 126, 8, - 6, 1, 247, 146, 4, 251, 250, 8, 2, 1, 247, 146, 4, 251, 250, 8, 6, 1, - 247, 146, 4, 242, 209, 8, 2, 1, 247, 146, 4, 242, 209, 8, 6, 1, 247, 146, - 4, 75, 56, 8, 2, 1, 247, 146, 4, 75, 56, 8, 6, 1, 247, 146, 4, 247, 44, - 8, 2, 1, 247, 146, 4, 247, 44, 8, 6, 1, 238, 81, 4, 247, 44, 8, 2, 1, - 238, 81, 4, 247, 44, 8, 6, 1, 238, 81, 4, 105, 8, 2, 1, 238, 81, 4, 105, - 8, 6, 1, 234, 227, 4, 217, 125, 8, 2, 1, 234, 227, 4, 217, 125, 8, 6, 1, - 234, 227, 4, 247, 244, 8, 2, 1, 234, 227, 4, 247, 244, 8, 6, 1, 234, 227, - 4, 75, 56, 8, 2, 1, 234, 227, 4, 75, 56, 8, 6, 1, 234, 227, 4, 211, 126, - 8, 2, 1, 234, 227, 4, 211, 126, 8, 6, 1, 234, 227, 4, 247, 44, 8, 2, 1, - 234, 227, 4, 247, 44, 8, 6, 1, 232, 15, 4, 242, 209, 8, 2, 1, 232, 15, 4, - 242, 209, 8, 6, 1, 232, 15, 4, 247, 244, 8, 2, 1, 232, 15, 4, 247, 244, - 8, 6, 1, 232, 15, 4, 75, 56, 8, 2, 1, 232, 15, 4, 75, 56, 8, 6, 1, 232, - 15, 4, 246, 243, 8, 2, 1, 232, 15, 4, 246, 243, 8, 6, 1, 230, 84, 4, 242, - 209, 8, 2, 1, 230, 84, 4, 242, 209, 8, 6, 1, 230, 84, 4, 105, 8, 2, 1, - 230, 84, 4, 105, 8, 6, 1, 228, 44, 4, 198, 147, 8, 2, 1, 228, 44, 4, 198, - 147, 8, 6, 1, 228, 44, 4, 217, 125, 8, 2, 1, 228, 44, 4, 217, 125, 8, 6, - 1, 228, 44, 4, 247, 244, 8, 2, 1, 228, 44, 4, 247, 244, 8, 6, 1, 228, 44, - 4, 211, 126, 8, 2, 1, 228, 44, 4, 211, 126, 8, 6, 1, 228, 44, 4, 75, 56, - 8, 2, 1, 236, 95, 70, 8, 6, 34, 223, 168, 8, 2, 34, 223, 168, 8, 6, 1, - 223, 8, 4, 242, 209, 8, 2, 1, 223, 8, 4, 242, 209, 8, 6, 1, 222, 126, 4, - 246, 243, 8, 2, 1, 222, 126, 4, 246, 243, 8, 2, 1, 220, 240, 8, 6, 1, - 220, 119, 4, 251, 250, 8, 2, 1, 220, 119, 4, 251, 250, 8, 6, 1, 220, 119, - 4, 246, 243, 8, 2, 1, 220, 119, 4, 246, 243, 8, 6, 1, 220, 119, 4, 247, - 44, 8, 2, 1, 220, 119, 4, 247, 44, 8, 6, 1, 220, 119, 4, 82, 236, 96, 8, - 2, 1, 220, 119, 4, 82, 236, 96, 8, 6, 1, 220, 119, 4, 105, 8, 2, 1, 220, - 119, 4, 105, 8, 6, 1, 215, 48, 4, 251, 250, 8, 2, 1, 215, 48, 4, 251, - 250, 8, 6, 1, 215, 48, 4, 246, 243, 8, 2, 1, 215, 48, 4, 246, 243, 8, 6, - 1, 215, 48, 4, 247, 44, 8, 2, 1, 215, 48, 4, 247, 44, 8, 2, 1, 215, 48, - 208, 226, 247, 157, 250, 255, 8, 6, 1, 234, 46, 8, 2, 1, 234, 46, 8, 6, - 1, 186, 4, 217, 125, 8, 2, 1, 186, 4, 217, 125, 8, 6, 1, 186, 4, 247, - 244, 8, 2, 1, 186, 4, 247, 244, 8, 6, 1, 186, 4, 54, 251, 250, 8, 2, 1, - 186, 4, 54, 251, 250, 8, 6, 34, 211, 139, 8, 2, 34, 211, 139, 8, 6, 1, - 207, 217, 4, 251, 250, 8, 2, 1, 207, 217, 4, 251, 250, 8, 6, 1, 207, 217, - 4, 246, 243, 8, 2, 1, 207, 217, 4, 246, 243, 8, 6, 1, 207, 217, 4, 247, - 44, 8, 2, 1, 207, 217, 4, 247, 44, 8, 6, 1, 206, 4, 4, 251, 250, 8, 2, 1, - 206, 4, 4, 251, 250, 8, 6, 1, 206, 4, 4, 242, 209, 8, 2, 1, 206, 4, 4, - 242, 209, 8, 6, 1, 206, 4, 4, 246, 243, 8, 2, 1, 206, 4, 4, 246, 243, 8, - 6, 1, 206, 4, 4, 247, 44, 8, 2, 1, 206, 4, 4, 247, 44, 8, 6, 1, 200, 40, - 4, 246, 243, 8, 2, 1, 200, 40, 4, 246, 243, 8, 6, 1, 200, 40, 4, 247, 44, - 8, 2, 1, 200, 40, 4, 247, 44, 8, 6, 1, 200, 40, 4, 105, 8, 2, 1, 200, 40, - 4, 105, 8, 6, 1, 126, 4, 198, 147, 8, 2, 1, 126, 4, 198, 147, 8, 6, 1, - 126, 4, 217, 125, 8, 2, 1, 126, 4, 217, 125, 8, 6, 1, 126, 4, 247, 244, - 8, 2, 1, 126, 4, 247, 244, 8, 6, 1, 126, 4, 206, 184, 56, 8, 2, 1, 126, - 4, 206, 184, 56, 8, 6, 1, 126, 4, 54, 251, 250, 8, 2, 1, 126, 4, 54, 251, - 250, 8, 6, 1, 126, 4, 211, 126, 8, 2, 1, 126, 4, 211, 126, 8, 6, 1, 193, - 222, 4, 242, 209, 8, 2, 1, 193, 222, 4, 242, 209, 8, 6, 1, 192, 160, 4, - 242, 209, 8, 2, 1, 192, 160, 4, 242, 209, 8, 6, 1, 192, 160, 4, 236, 253, - 8, 6, 1, 191, 167, 4, 251, 250, 8, 2, 1, 191, 167, 4, 251, 250, 8, 6, 1, - 191, 167, 4, 75, 56, 8, 2, 1, 191, 167, 4, 75, 56, 8, 6, 1, 191, 167, 4, - 247, 44, 8, 2, 1, 191, 167, 4, 247, 44, 8, 2, 1, 177, 206, 3, 8, 2, 1, - 78, 4, 105, 8, 6, 1, 78, 4, 106, 8, 6, 1, 78, 4, 198, 46, 8, 2, 1, 78, 4, - 198, 46, 8, 6, 1, 163, 173, 8, 2, 1, 163, 173, 8, 6, 1, 211, 66, 74, 8, - 6, 1, 247, 146, 4, 106, 8, 2, 1, 247, 146, 4, 106, 8, 6, 1, 251, 204, - 238, 80, 8, 6, 1, 238, 81, 4, 106, 8, 6, 1, 238, 81, 4, 198, 46, 8, 2, 1, - 238, 81, 4, 198, 46, 8, 2, 1, 152, 237, 61, 8, 6, 1, 207, 13, 73, 8, 6, - 1, 205, 81, 8, 6, 1, 211, 66, 73, 8, 6, 1, 233, 135, 4, 106, 8, 2, 1, - 233, 135, 4, 106, 8, 6, 1, 232, 15, 4, 106, 8, 6, 1, 231, 174, 8, 2, 1, - 228, 95, 8, 6, 1, 223, 55, 8, 6, 1, 228, 44, 4, 105, 8, 6, 1, 222, 126, - 4, 106, 8, 2, 1, 222, 126, 4, 106, 8, 2, 1, 220, 119, 4, 164, 8, 2, 1, - 220, 9, 4, 105, 8, 6, 1, 152, 218, 147, 8, 6, 1, 215, 48, 4, 45, 106, 8, - 2, 1, 215, 48, 4, 177, 50, 219, 188, 8, 6, 1, 186, 4, 82, 198, 147, 8, 6, - 1, 186, 4, 228, 156, 8, 2, 1, 186, 4, 228, 156, 8, 6, 1, 211, 121, 8, 2, - 1, 211, 121, 8, 6, 1, 210, 227, 4, 106, 8, 2, 1, 210, 227, 4, 106, 8, 1, - 191, 228, 8, 6, 1, 163, 109, 8, 2, 1, 163, 109, 8, 6, 1, 233, 226, 8, 1, - 207, 13, 233, 227, 218, 236, 8, 2, 1, 200, 40, 4, 210, 182, 106, 8, 6, 1, - 200, 40, 4, 106, 8, 2, 1, 200, 40, 4, 106, 8, 6, 1, 200, 40, 4, 207, 19, - 106, 8, 6, 1, 126, 4, 228, 156, 8, 2, 1, 126, 4, 228, 156, 8, 6, 1, 196, - 66, 8, 6, 1, 196, 9, 4, 106, 8, 6, 1, 192, 160, 4, 106, 8, 2, 1, 192, - 160, 4, 106, 8, 6, 1, 191, 167, 4, 105, 8, 2, 1, 191, 167, 4, 105, 8, 6, - 1, 233, 137, 8, 6, 1, 233, 138, 207, 12, 8, 2, 1, 233, 138, 207, 12, 8, - 2, 1, 233, 138, 4, 199, 210, 8, 1, 103, 4, 105, 8, 6, 1, 163, 153, 8, 2, - 1, 163, 153, 8, 1, 223, 65, 230, 231, 201, 59, 4, 105, 8, 1, 192, 238, 8, - 1, 237, 53, 242, 183, 8, 1, 219, 235, 242, 183, 8, 1, 251, 99, 242, 183, - 8, 1, 207, 19, 242, 183, 8, 6, 1, 234, 249, 4, 247, 44, 8, 6, 1, 238, 81, - 4, 2, 1, 191, 167, 4, 247, 44, 8, 2, 1, 234, 249, 4, 247, 44, 8, 6, 1, - 219, 53, 8, 6, 1, 220, 119, 4, 2, 1, 223, 7, 8, 2, 1, 219, 53, 8, 6, 1, - 213, 145, 8, 6, 1, 215, 48, 4, 2, 1, 223, 7, 8, 2, 1, 213, 145, 8, 6, 1, - 41, 4, 247, 44, 8, 2, 1, 41, 4, 247, 44, 8, 6, 1, 228, 44, 4, 247, 44, 8, - 2, 1, 228, 44, 4, 247, 44, 8, 6, 1, 186, 4, 247, 44, 8, 2, 1, 186, 4, - 247, 44, 8, 6, 1, 126, 4, 247, 44, 8, 2, 1, 126, 4, 247, 44, 8, 6, 1, - 126, 4, 236, 254, 24, 217, 125, 8, 2, 1, 126, 4, 236, 254, 24, 217, 125, - 8, 6, 1, 126, 4, 236, 254, 24, 251, 250, 8, 2, 1, 126, 4, 236, 254, 24, - 251, 250, 8, 6, 1, 126, 4, 236, 254, 24, 247, 44, 8, 2, 1, 126, 4, 236, - 254, 24, 247, 44, 8, 6, 1, 126, 4, 236, 254, 24, 230, 176, 8, 2, 1, 126, - 4, 236, 254, 24, 230, 176, 8, 2, 1, 152, 73, 8, 6, 1, 41, 4, 236, 254, - 24, 217, 125, 8, 2, 1, 41, 4, 236, 254, 24, 217, 125, 8, 6, 1, 41, 4, 75, - 95, 24, 217, 125, 8, 2, 1, 41, 4, 75, 95, 24, 217, 125, 8, 6, 1, 251, - 230, 4, 217, 125, 8, 2, 1, 251, 230, 4, 217, 125, 8, 6, 1, 232, 15, 4, - 105, 8, 2, 1, 232, 15, 4, 105, 8, 6, 1, 232, 15, 4, 247, 44, 8, 2, 1, - 232, 15, 4, 247, 44, 8, 6, 1, 222, 126, 4, 247, 44, 8, 2, 1, 222, 126, 4, - 247, 44, 8, 6, 1, 186, 4, 211, 126, 8, 2, 1, 186, 4, 211, 126, 8, 6, 1, - 186, 4, 211, 127, 24, 217, 125, 8, 2, 1, 186, 4, 211, 127, 24, 217, 125, - 8, 6, 1, 233, 138, 4, 247, 44, 8, 2, 1, 233, 138, 4, 247, 44, 8, 2, 1, - 223, 8, 4, 247, 44, 8, 6, 1, 234, 248, 8, 6, 1, 238, 81, 4, 2, 1, 191, - 166, 8, 2, 1, 234, 248, 8, 6, 1, 232, 15, 4, 251, 250, 8, 2, 1, 232, 15, - 4, 251, 250, 8, 6, 1, 228, 92, 8, 6, 1, 192, 238, 8, 6, 1, 215, 48, 4, - 230, 176, 8, 2, 1, 215, 48, 4, 230, 176, 8, 6, 1, 41, 4, 206, 184, 95, - 24, 251, 250, 8, 2, 1, 41, 4, 206, 184, 95, 24, 251, 250, 8, 6, 1, 251, - 230, 4, 251, 250, 8, 2, 1, 251, 230, 4, 251, 250, 8, 6, 1, 186, 4, 201, - 23, 24, 251, 250, 8, 2, 1, 186, 4, 201, 23, 24, 251, 250, 8, 6, 1, 41, 4, - 54, 230, 176, 8, 2, 1, 41, 4, 54, 230, 176, 8, 6, 1, 41, 4, 223, 65, 247, - 244, 8, 2, 1, 41, 4, 223, 65, 247, 244, 8, 6, 1, 234, 227, 4, 54, 230, - 176, 8, 2, 1, 234, 227, 4, 54, 230, 176, 8, 6, 1, 234, 227, 4, 223, 65, - 247, 244, 8, 2, 1, 234, 227, 4, 223, 65, 247, 244, 8, 6, 1, 228, 44, 4, - 54, 230, 176, 8, 2, 1, 228, 44, 4, 54, 230, 176, 8, 6, 1, 228, 44, 4, - 223, 65, 247, 244, 8, 2, 1, 228, 44, 4, 223, 65, 247, 244, 8, 6, 1, 186, - 4, 54, 230, 176, 8, 2, 1, 186, 4, 54, 230, 176, 8, 6, 1, 186, 4, 223, 65, - 247, 244, 8, 2, 1, 186, 4, 223, 65, 247, 244, 8, 6, 1, 207, 217, 4, 54, - 230, 176, 8, 2, 1, 207, 217, 4, 54, 230, 176, 8, 6, 1, 207, 217, 4, 223, - 65, 247, 244, 8, 2, 1, 207, 217, 4, 223, 65, 247, 244, 8, 6, 1, 126, 4, - 54, 230, 176, 8, 2, 1, 126, 4, 54, 230, 176, 8, 6, 1, 126, 4, 223, 65, - 247, 244, 8, 2, 1, 126, 4, 223, 65, 247, 244, 8, 6, 1, 206, 4, 4, 242, - 27, 60, 8, 2, 1, 206, 4, 4, 242, 27, 60, 8, 6, 1, 200, 40, 4, 242, 27, - 60, 8, 2, 1, 200, 40, 4, 242, 27, 60, 8, 6, 1, 191, 248, 8, 2, 1, 191, - 248, 8, 6, 1, 230, 84, 4, 247, 44, 8, 2, 1, 230, 84, 4, 247, 44, 8, 6, 1, - 215, 48, 4, 177, 50, 219, 188, 8, 2, 1, 238, 81, 4, 238, 128, 8, 6, 1, - 211, 9, 8, 2, 1, 211, 9, 8, 6, 1, 191, 167, 4, 106, 8, 2, 1, 191, 167, 4, - 106, 8, 6, 1, 41, 4, 75, 56, 8, 2, 1, 41, 4, 75, 56, 8, 6, 1, 234, 227, - 4, 246, 243, 8, 2, 1, 234, 227, 4, 246, 243, 8, 6, 1, 186, 4, 236, 254, - 24, 217, 125, 8, 2, 1, 186, 4, 236, 254, 24, 217, 125, 8, 6, 1, 186, 4, - 198, 148, 24, 217, 125, 8, 2, 1, 186, 4, 198, 148, 24, 217, 125, 8, 6, 1, - 186, 4, 75, 56, 8, 2, 1, 186, 4, 75, 56, 8, 6, 1, 186, 4, 75, 95, 24, - 217, 125, 8, 2, 1, 186, 4, 75, 95, 24, 217, 125, 8, 6, 1, 192, 160, 4, - 217, 125, 8, 2, 1, 192, 160, 4, 217, 125, 8, 2, 1, 220, 119, 4, 238, 128, - 8, 2, 1, 215, 48, 4, 238, 128, 8, 2, 1, 200, 40, 4, 238, 128, 8, 2, 1, - 236, 95, 223, 7, 8, 2, 1, 237, 156, 236, 213, 8, 2, 1, 208, 28, 236, 213, - 8, 6, 1, 41, 4, 105, 8, 6, 1, 247, 146, 4, 105, 8, 2, 1, 247, 146, 4, - 105, 8, 6, 1, 220, 119, 4, 164, 8, 6, 1, 200, 40, 4, 236, 250, 105, 8, 2, - 1, 206, 4, 4, 200, 142, 199, 210, 8, 2, 1, 191, 167, 4, 200, 142, 199, - 210, 8, 6, 1, 230, 231, 201, 58, 8, 2, 1, 230, 231, 201, 58, 8, 6, 1, 78, - 4, 105, 8, 6, 1, 126, 164, 8, 6, 1, 152, 196, 8, 8, 6, 1, 234, 227, 4, - 105, 8, 2, 1, 234, 227, 4, 105, 8, 6, 1, 223, 8, 4, 105, 8, 2, 1, 223, 8, - 4, 105, 8, 6, 1, 2, 208, 98, 4, 228, 219, 199, 210, 8, 2, 1, 208, 98, 4, - 228, 219, 199, 210, 8, 6, 1, 207, 217, 4, 105, 8, 2, 1, 207, 217, 4, 105, - 8, 6, 1, 192, 160, 4, 105, 8, 2, 1, 192, 160, 4, 105, 8, 2, 1, 152, 65, - 8, 2, 1, 251, 109, 8, 2, 1, 152, 251, 109, 8, 2, 1, 78, 4, 106, 8, 2, 1, - 211, 66, 74, 8, 2, 1, 247, 146, 4, 238, 128, 8, 2, 1, 238, 81, 4, 199, - 210, 8, 2, 1, 238, 81, 4, 106, 8, 2, 1, 207, 13, 73, 8, 2, 1, 205, 81, 8, - 2, 1, 205, 82, 4, 106, 8, 2, 1, 211, 66, 73, 8, 2, 1, 207, 13, 211, 66, - 73, 8, 2, 1, 207, 13, 211, 66, 234, 227, 4, 106, 8, 2, 1, 242, 171, 207, - 13, 211, 66, 73, 8, 2, 1, 236, 95, 223, 8, 4, 105, 8, 2, 1, 232, 15, 4, - 106, 8, 2, 1, 27, 232, 14, 8, 1, 2, 6, 232, 14, 8, 2, 1, 231, 174, 8, 2, - 1, 207, 135, 228, 156, 8, 2, 1, 152, 230, 83, 8, 2, 1, 230, 84, 4, 106, - 8, 2, 1, 229, 165, 4, 106, 8, 2, 1, 228, 44, 4, 105, 8, 2, 1, 223, 55, 8, - 1, 2, 6, 70, 8, 2, 1, 220, 119, 4, 82, 198, 147, 8, 2, 1, 220, 119, 4, - 248, 181, 8, 2, 1, 220, 119, 4, 207, 19, 106, 8, 2, 1, 219, 138, 8, 2, 1, - 152, 218, 147, 8, 2, 1, 152, 218, 148, 4, 177, 219, 188, 8, 2, 1, 218, - 148, 4, 106, 8, 2, 1, 215, 48, 4, 45, 106, 8, 2, 1, 215, 48, 4, 207, 19, - 106, 8, 1, 2, 6, 215, 47, 8, 2, 1, 249, 32, 74, 8, 1, 2, 6, 211, 139, 8, - 2, 1, 242, 171, 211, 99, 8, 2, 1, 209, 202, 8, 2, 1, 152, 148, 8, 2, 1, - 152, 207, 217, 4, 177, 219, 188, 8, 2, 1, 152, 207, 217, 4, 106, 8, 2, 1, - 207, 217, 4, 177, 219, 188, 8, 2, 1, 207, 217, 4, 199, 210, 8, 2, 1, 207, - 217, 4, 232, 192, 8, 2, 1, 207, 13, 207, 217, 4, 232, 192, 8, 1, 2, 6, - 148, 8, 1, 2, 6, 223, 65, 148, 8, 2, 1, 206, 4, 4, 106, 8, 2, 1, 233, - 226, 8, 2, 1, 236, 95, 223, 8, 4, 201, 23, 24, 106, 8, 2, 1, 201, 182, - 207, 13, 233, 226, 8, 2, 1, 233, 227, 4, 238, 128, 8, 2, 1, 152, 200, 39, - 8, 2, 1, 200, 40, 4, 207, 19, 106, 8, 2, 1, 126, 164, 8, 2, 1, 196, 66, - 8, 2, 1, 196, 9, 4, 106, 8, 2, 1, 152, 196, 8, 8, 2, 1, 152, 193, 221, 8, - 2, 1, 152, 192, 159, 8, 1, 2, 6, 192, 159, 8, 2, 1, 191, 167, 4, 207, 19, - 106, 8, 2, 1, 191, 167, 4, 238, 128, 8, 2, 1, 233, 137, 8, 2, 1, 233, - 138, 4, 238, 128, 8, 1, 230, 231, 201, 58, 8, 1, 209, 210, 195, 17, 232, - 66, 8, 1, 223, 65, 230, 231, 201, 58, 8, 1, 201, 31, 247, 145, 8, 1, 248, - 124, 242, 183, 8, 1, 2, 6, 250, 70, 8, 2, 1, 242, 171, 211, 66, 73, 8, 1, - 2, 6, 232, 15, 4, 106, 8, 1, 2, 6, 230, 83, 8, 2, 1, 223, 8, 4, 238, 165, - 8, 2, 1, 152, 222, 125, 8, 1, 2, 6, 170, 8, 2, 1, 208, 98, 4, 106, 8, 1, - 230, 231, 201, 59, 4, 105, 8, 1, 207, 13, 230, 231, 201, 59, 4, 105, 8, - 2, 1, 234, 249, 236, 213, 8, 2, 1, 237, 25, 236, 213, 8, 2, 1, 234, 249, - 236, 214, 4, 238, 128, 8, 2, 1, 197, 166, 236, 213, 8, 2, 1, 199, 74, - 236, 213, 8, 2, 1, 199, 147, 236, 214, 4, 238, 128, 8, 2, 1, 232, 252, - 236, 213, 8, 2, 1, 218, 205, 236, 213, 8, 2, 1, 218, 149, 236, 213, 8, 1, - 248, 124, 210, 3, 8, 1, 248, 132, 210, 3, 8, 2, 1, 152, 230, 84, 4, 232, - 192, 8, 2, 1, 152, 230, 84, 4, 232, 193, 24, 199, 210, 59, 1, 2, 230, 83, - 59, 1, 2, 230, 84, 4, 106, 59, 1, 2, 223, 7, 59, 1, 2, 148, 59, 1, 2, - 152, 148, 59, 1, 2, 152, 207, 217, 4, 106, 59, 1, 2, 6, 223, 65, 148, 59, - 1, 2, 193, 221, 59, 1, 2, 192, 159, 59, 1, 208, 208, 59, 1, 54, 208, 208, - 59, 1, 152, 242, 26, 59, 1, 250, 255, 59, 1, 207, 13, 242, 26, 59, 1, 50, - 134, 206, 183, 59, 1, 45, 134, 206, 183, 59, 1, 230, 231, 201, 58, 59, 1, - 207, 13, 230, 231, 201, 58, 59, 1, 45, 250, 185, 59, 1, 50, 250, 185, 59, - 1, 132, 250, 185, 59, 1, 143, 250, 185, 59, 1, 242, 210, 252, 8, 247, 44, - 59, 1, 81, 219, 88, 59, 1, 217, 125, 59, 1, 251, 251, 252, 8, 59, 1, 230, - 177, 252, 8, 59, 1, 131, 81, 219, 88, 59, 1, 131, 217, 125, 59, 1, 131, - 230, 177, 252, 8, 59, 1, 131, 251, 251, 252, 8, 59, 1, 197, 234, 242, 35, - 59, 1, 134, 197, 234, 242, 35, 59, 1, 246, 228, 50, 134, 206, 183, 59, 1, - 246, 228, 45, 134, 206, 183, 59, 1, 132, 199, 223, 59, 1, 143, 199, 223, - 59, 1, 107, 57, 59, 1, 216, 18, 57, 247, 244, 75, 56, 206, 184, 56, 211, - 126, 2, 198, 147, 54, 251, 251, 252, 8, 59, 1, 206, 253, 106, 59, 1, 238, - 171, 252, 8, 59, 1, 2, 231, 174, 59, 1, 2, 170, 59, 1, 2, 206, 3, 59, 1, - 2, 192, 235, 59, 1, 2, 207, 13, 230, 231, 201, 58, 59, 1, 233, 159, 163, - 164, 59, 1, 136, 163, 164, 59, 1, 216, 68, 163, 164, 59, 1, 131, 163, - 164, 59, 1, 233, 158, 163, 164, 59, 1, 192, 22, 237, 50, 163, 77, 59, 1, - 192, 107, 237, 50, 163, 77, 59, 1, 195, 15, 59, 1, 196, 105, 59, 1, 54, - 250, 255, 59, 1, 131, 143, 250, 185, 59, 1, 131, 132, 250, 185, 59, 1, - 131, 45, 250, 185, 59, 1, 131, 50, 250, 185, 59, 1, 131, 206, 183, 59, 1, - 82, 230, 177, 252, 8, 59, 1, 82, 54, 230, 177, 252, 8, 59, 1, 82, 54, - 251, 251, 252, 8, 59, 1, 131, 198, 147, 59, 1, 207, 142, 242, 35, 59, 1, - 248, 199, 136, 198, 74, 59, 1, 234, 53, 136, 198, 74, 59, 1, 248, 199, - 131, 198, 74, 59, 1, 234, 53, 131, 198, 74, 59, 1, 203, 99, 59, 1, 211, - 66, 203, 99, 59, 1, 131, 45, 55, 33, 230, 177, 252, 8, 33, 251, 251, 252, - 8, 33, 242, 210, 252, 8, 33, 198, 147, 33, 217, 125, 33, 210, 244, 33, - 247, 244, 33, 75, 56, 33, 236, 253, 33, 228, 219, 56, 33, 206, 184, 56, - 33, 54, 251, 251, 252, 8, 33, 247, 44, 33, 81, 219, 89, 56, 33, 54, 81, - 219, 89, 56, 33, 54, 230, 177, 252, 8, 33, 247, 71, 33, 223, 65, 247, - 244, 33, 152, 242, 27, 56, 33, 242, 27, 56, 33, 207, 13, 242, 27, 56, 33, - 242, 27, 95, 187, 33, 230, 177, 252, 9, 60, 33, 251, 251, 252, 9, 60, 33, - 45, 199, 224, 60, 33, 50, 199, 224, 60, 33, 45, 251, 65, 56, 33, 228, - 156, 33, 45, 134, 206, 184, 60, 33, 132, 199, 224, 60, 33, 143, 199, 224, - 60, 33, 107, 3, 60, 33, 216, 18, 3, 60, 33, 210, 180, 228, 219, 60, 33, - 207, 19, 228, 219, 60, 33, 75, 60, 33, 236, 254, 60, 33, 206, 184, 60, - 33, 242, 27, 60, 33, 246, 243, 33, 211, 126, 33, 81, 219, 89, 60, 33, - 247, 237, 60, 33, 223, 65, 54, 250, 221, 60, 33, 247, 45, 60, 33, 242, - 210, 252, 9, 60, 33, 247, 245, 60, 33, 223, 65, 247, 245, 60, 33, 198, - 148, 60, 33, 217, 126, 60, 33, 131, 219, 88, 33, 54, 131, 219, 88, 33, - 198, 148, 210, 245, 33, 203, 35, 201, 23, 210, 245, 33, 177, 201, 23, - 210, 245, 33, 203, 35, 202, 19, 210, 245, 33, 177, 202, 19, 210, 245, 33, - 50, 134, 206, 184, 60, 33, 223, 65, 247, 237, 60, 33, 51, 60, 33, 205, - 57, 60, 33, 192, 236, 56, 33, 81, 198, 147, 33, 54, 210, 244, 33, 230, - 177, 163, 77, 33, 251, 251, 163, 77, 33, 35, 209, 251, 33, 35, 221, 6, - 33, 35, 236, 247, 198, 55, 33, 35, 191, 233, 33, 247, 237, 56, 33, 234, - 1, 3, 60, 33, 54, 81, 219, 89, 60, 33, 45, 251, 65, 60, 33, 212, 255, - 198, 148, 56, 33, 228, 225, 56, 33, 251, 114, 234, 3, 118, 56, 33, 45, - 50, 63, 60, 33, 196, 62, 63, 60, 33, 230, 183, 222, 169, 33, 50, 250, - 186, 56, 33, 45, 134, 206, 184, 56, 33, 232, 249, 33, 192, 236, 60, 33, - 45, 250, 186, 60, 33, 50, 250, 186, 60, 33, 50, 250, 186, 24, 132, 250, - 186, 60, 33, 50, 134, 206, 184, 56, 33, 75, 95, 187, 33, 250, 144, 60, - 33, 54, 206, 184, 60, 33, 191, 21, 56, 33, 54, 247, 245, 60, 33, 54, 247, - 244, 33, 54, 217, 125, 33, 54, 217, 126, 60, 33, 54, 198, 147, 33, 54, - 223, 65, 247, 244, 33, 54, 96, 63, 60, 33, 8, 2, 1, 65, 33, 8, 2, 1, 73, - 33, 8, 2, 1, 70, 33, 8, 2, 1, 74, 33, 8, 2, 1, 69, 33, 8, 2, 1, 247, 145, - 33, 8, 2, 1, 238, 80, 33, 8, 2, 1, 230, 83, 33, 8, 2, 1, 218, 147, 33, 8, - 2, 1, 148, 33, 8, 2, 1, 200, 39, 33, 8, 2, 1, 196, 8, 33, 8, 2, 1, 192, - 235, 35, 6, 1, 229, 153, 35, 2, 1, 229, 153, 35, 6, 1, 250, 220, 205, - 140, 35, 2, 1, 250, 220, 205, 140, 35, 212, 121, 57, 35, 110, 212, 121, - 57, 35, 6, 1, 210, 161, 236, 221, 35, 2, 1, 210, 161, 236, 221, 35, 191, - 233, 35, 2, 207, 13, 218, 185, 202, 192, 113, 35, 2, 235, 94, 218, 185, - 202, 192, 113, 35, 2, 207, 13, 235, 94, 218, 185, 202, 192, 113, 35, 208, - 8, 77, 35, 6, 1, 191, 240, 35, 198, 55, 35, 236, 247, 198, 55, 35, 6, 1, - 251, 110, 4, 198, 55, 35, 251, 43, 199, 103, 35, 6, 1, 234, 6, 4, 198, - 55, 35, 6, 1, 233, 212, 4, 198, 55, 35, 6, 1, 223, 56, 4, 198, 55, 35, 6, - 1, 211, 97, 4, 198, 55, 35, 6, 1, 196, 67, 4, 198, 55, 35, 6, 1, 211, - 100, 4, 198, 55, 35, 2, 1, 223, 56, 4, 236, 247, 24, 198, 55, 35, 6, 1, - 251, 109, 35, 6, 1, 248, 162, 35, 6, 1, 231, 174, 35, 6, 1, 237, 61, 35, - 6, 1, 234, 5, 35, 6, 1, 191, 76, 35, 6, 1, 233, 211, 35, 6, 1, 199, 10, - 35, 6, 1, 223, 55, 35, 6, 1, 222, 46, 35, 6, 1, 220, 7, 35, 6, 1, 215, - 139, 35, 6, 1, 212, 165, 35, 6, 1, 192, 207, 35, 6, 1, 211, 96, 35, 6, 1, - 209, 176, 35, 6, 1, 206, 254, 35, 6, 1, 202, 191, 35, 6, 1, 199, 161, 35, - 6, 1, 196, 66, 35, 6, 1, 209, 202, 35, 6, 1, 243, 47, 35, 6, 1, 208, 169, - 35, 6, 1, 211, 99, 35, 6, 1, 223, 56, 4, 236, 246, 35, 6, 1, 196, 67, 4, - 236, 246, 35, 2, 1, 251, 110, 4, 198, 55, 35, 2, 1, 234, 6, 4, 198, 55, - 35, 2, 1, 233, 212, 4, 198, 55, 35, 2, 1, 223, 56, 4, 198, 55, 35, 2, 1, - 196, 67, 4, 236, 247, 24, 198, 55, 35, 2, 1, 251, 109, 35, 2, 1, 248, - 162, 35, 2, 1, 231, 174, 35, 2, 1, 237, 61, 35, 2, 1, 234, 5, 35, 2, 1, - 191, 76, 35, 2, 1, 233, 211, 35, 2, 1, 199, 10, 35, 2, 1, 223, 55, 35, 2, - 1, 222, 46, 35, 2, 1, 220, 7, 35, 2, 1, 215, 139, 35, 2, 1, 212, 165, 35, - 2, 1, 192, 207, 35, 2, 1, 211, 96, 35, 2, 1, 209, 176, 35, 2, 1, 206, - 254, 35, 2, 1, 52, 202, 191, 35, 2, 1, 202, 191, 35, 2, 1, 199, 161, 35, - 2, 1, 196, 66, 35, 2, 1, 209, 202, 35, 2, 1, 243, 47, 35, 2, 1, 208, 169, - 35, 2, 1, 211, 99, 35, 2, 1, 223, 56, 4, 236, 246, 35, 2, 1, 196, 67, 4, - 236, 246, 35, 2, 1, 211, 97, 4, 198, 55, 35, 2, 1, 196, 67, 4, 198, 55, - 35, 2, 1, 211, 100, 4, 198, 55, 35, 6, 222, 76, 113, 35, 248, 163, 113, - 35, 199, 11, 113, 35, 196, 67, 4, 228, 219, 113, 35, 196, 67, 4, 251, - 251, 24, 228, 219, 113, 35, 196, 67, 4, 236, 254, 24, 228, 219, 113, 35, - 209, 203, 113, 35, 209, 177, 113, 35, 222, 76, 113, 35, 1, 250, 220, 221, - 11, 35, 2, 1, 250, 220, 221, 11, 35, 1, 201, 68, 35, 2, 1, 201, 68, 35, - 1, 236, 221, 35, 2, 1, 236, 221, 35, 1, 221, 11, 35, 2, 1, 221, 11, 35, - 1, 205, 140, 35, 2, 1, 205, 140, 93, 6, 1, 203, 100, 93, 2, 1, 203, 100, - 93, 6, 1, 233, 3, 93, 2, 1, 233, 3, 93, 6, 1, 221, 171, 93, 2, 1, 221, - 171, 93, 6, 1, 228, 210, 93, 2, 1, 228, 210, 93, 6, 1, 231, 169, 93, 2, - 1, 231, 169, 93, 6, 1, 203, 66, 93, 2, 1, 203, 66, 93, 6, 1, 237, 77, 93, - 2, 1, 237, 77, 35, 222, 47, 113, 35, 206, 255, 113, 35, 218, 185, 202, - 192, 113, 35, 1, 191, 240, 35, 6, 199, 11, 113, 35, 218, 185, 234, 6, - 113, 35, 207, 13, 218, 185, 234, 6, 113, 35, 6, 1, 203, 51, 35, 2, 1, - 203, 51, 35, 6, 218, 185, 202, 192, 113, 35, 6, 1, 205, 137, 35, 2, 1, - 205, 137, 35, 206, 255, 4, 201, 23, 113, 35, 6, 207, 13, 218, 185, 202, - 192, 113, 35, 6, 235, 94, 218, 185, 202, 192, 113, 35, 6, 207, 13, 235, - 94, 218, 185, 202, 192, 113, 42, 6, 1, 223, 198, 4, 230, 176, 42, 6, 1, - 223, 60, 42, 6, 1, 236, 147, 42, 6, 1, 230, 240, 42, 6, 1, 196, 121, 223, - 197, 42, 6, 1, 234, 244, 42, 6, 1, 247, 155, 70, 42, 6, 1, 192, 33, 42, - 6, 1, 222, 238, 42, 6, 1, 219, 52, 42, 6, 1, 213, 137, 42, 6, 1, 197, - 151, 42, 6, 1, 221, 79, 42, 6, 1, 228, 44, 4, 230, 176, 42, 6, 1, 203, - 35, 69, 42, 6, 1, 234, 240, 42, 6, 1, 65, 42, 6, 1, 248, 223, 42, 6, 1, - 195, 150, 42, 6, 1, 231, 40, 42, 6, 1, 237, 101, 42, 6, 1, 223, 197, 42, - 6, 1, 191, 62, 42, 6, 1, 191, 87, 42, 6, 1, 70, 42, 6, 1, 203, 35, 70, - 42, 6, 1, 157, 42, 6, 1, 234, 97, 42, 6, 1, 234, 72, 42, 6, 1, 234, 61, - 42, 6, 1, 74, 42, 6, 1, 210, 53, 42, 6, 1, 233, 248, 42, 6, 1, 233, 236, - 42, 6, 1, 199, 140, 42, 6, 1, 69, 42, 6, 1, 234, 138, 42, 6, 1, 144, 42, - 6, 1, 197, 157, 42, 6, 1, 243, 79, 42, 6, 1, 203, 160, 42, 6, 1, 203, - 111, 42, 6, 1, 229, 240, 57, 42, 6, 1, 192, 58, 42, 6, 1, 202, 27, 57, - 42, 6, 1, 73, 42, 6, 1, 191, 225, 42, 6, 1, 169, 42, 2, 1, 65, 42, 2, 1, - 248, 223, 42, 2, 1, 195, 150, 42, 2, 1, 231, 40, 42, 2, 1, 237, 101, 42, - 2, 1, 223, 197, 42, 2, 1, 191, 62, 42, 2, 1, 191, 87, 42, 2, 1, 70, 42, - 2, 1, 203, 35, 70, 42, 2, 1, 157, 42, 2, 1, 234, 97, 42, 2, 1, 234, 72, - 42, 2, 1, 234, 61, 42, 2, 1, 74, 42, 2, 1, 210, 53, 42, 2, 1, 233, 248, - 42, 2, 1, 233, 236, 42, 2, 1, 199, 140, 42, 2, 1, 69, 42, 2, 1, 234, 138, - 42, 2, 1, 144, 42, 2, 1, 197, 157, 42, 2, 1, 243, 79, 42, 2, 1, 203, 160, - 42, 2, 1, 203, 111, 42, 2, 1, 229, 240, 57, 42, 2, 1, 192, 58, 42, 2, 1, - 202, 27, 57, 42, 2, 1, 73, 42, 2, 1, 191, 225, 42, 2, 1, 169, 42, 2, 1, - 223, 198, 4, 230, 176, 42, 2, 1, 223, 60, 42, 2, 1, 236, 147, 42, 2, 1, - 230, 240, 42, 2, 1, 196, 121, 223, 197, 42, 2, 1, 234, 244, 42, 2, 1, - 247, 155, 70, 42, 2, 1, 192, 33, 42, 2, 1, 222, 238, 42, 2, 1, 219, 52, - 42, 2, 1, 213, 137, 42, 2, 1, 197, 151, 42, 2, 1, 221, 79, 42, 2, 1, 228, - 44, 4, 230, 176, 42, 2, 1, 203, 35, 69, 42, 2, 1, 234, 240, 42, 6, 1, - 211, 99, 42, 2, 1, 211, 99, 42, 6, 1, 192, 95, 42, 2, 1, 192, 95, 42, 6, - 1, 223, 53, 73, 42, 2, 1, 223, 53, 73, 42, 6, 1, 219, 59, 191, 190, 42, - 2, 1, 219, 59, 191, 190, 42, 6, 1, 223, 53, 219, 59, 191, 190, 42, 2, 1, - 223, 53, 219, 59, 191, 190, 42, 6, 1, 248, 127, 191, 190, 42, 2, 1, 248, - 127, 191, 190, 42, 6, 1, 223, 53, 248, 127, 191, 190, 42, 2, 1, 223, 53, - 248, 127, 191, 190, 42, 6, 1, 220, 224, 42, 2, 1, 220, 224, 42, 6, 1, - 208, 169, 42, 2, 1, 208, 169, 42, 6, 1, 232, 187, 42, 2, 1, 232, 187, 42, - 6, 1, 223, 9, 42, 2, 1, 223, 9, 42, 6, 1, 223, 10, 4, 54, 230, 177, 252, - 8, 42, 2, 1, 223, 10, 4, 54, 230, 177, 252, 8, 42, 6, 1, 196, 124, 42, 2, - 1, 196, 124, 42, 6, 1, 206, 110, 211, 99, 42, 2, 1, 206, 110, 211, 99, - 42, 6, 1, 211, 100, 4, 198, 117, 42, 2, 1, 211, 100, 4, 198, 117, 42, 6, - 1, 211, 20, 42, 2, 1, 211, 20, 42, 6, 1, 221, 11, 42, 2, 1, 221, 11, 42, - 198, 224, 57, 33, 42, 198, 117, 33, 42, 210, 181, 33, 42, 237, 168, 209, - 67, 33, 42, 208, 163, 209, 67, 33, 42, 209, 47, 33, 42, 228, 110, 198, - 224, 57, 33, 42, 216, 30, 57, 42, 6, 1, 203, 35, 228, 44, 4, 199, 210, - 42, 2, 1, 203, 35, 228, 44, 4, 199, 210, 42, 6, 1, 204, 16, 57, 42, 2, 1, - 204, 16, 57, 42, 6, 1, 233, 249, 4, 198, 177, 42, 2, 1, 233, 249, 4, 198, - 177, 42, 6, 1, 231, 41, 4, 196, 65, 42, 2, 1, 231, 41, 4, 196, 65, 42, 6, - 1, 231, 41, 4, 105, 42, 2, 1, 231, 41, 4, 105, 42, 6, 1, 231, 41, 4, 82, - 106, 42, 2, 1, 231, 41, 4, 82, 106, 42, 6, 1, 191, 63, 4, 237, 42, 42, 2, - 1, 191, 63, 4, 237, 42, 42, 6, 1, 191, 88, 4, 237, 42, 42, 2, 1, 191, 88, - 4, 237, 42, 42, 6, 1, 222, 115, 4, 237, 42, 42, 2, 1, 222, 115, 4, 237, - 42, 42, 6, 1, 222, 115, 4, 81, 105, 42, 2, 1, 222, 115, 4, 81, 105, 42, - 6, 1, 222, 115, 4, 105, 42, 2, 1, 222, 115, 4, 105, 42, 6, 1, 249, 20, - 157, 42, 2, 1, 249, 20, 157, 42, 6, 1, 234, 62, 4, 237, 42, 42, 2, 1, - 234, 62, 4, 237, 42, 42, 6, 34, 234, 62, 231, 40, 42, 2, 34, 234, 62, - 231, 40, 42, 6, 1, 210, 54, 4, 82, 106, 42, 2, 1, 210, 54, 4, 82, 106, - 42, 6, 1, 252, 15, 144, 42, 2, 1, 252, 15, 144, 42, 6, 1, 233, 237, 4, - 237, 42, 42, 2, 1, 233, 237, 4, 237, 42, 42, 6, 1, 199, 141, 4, 237, 42, - 42, 2, 1, 199, 141, 4, 237, 42, 42, 6, 1, 201, 48, 69, 42, 2, 1, 201, 48, - 69, 42, 6, 1, 201, 48, 126, 4, 105, 42, 2, 1, 201, 48, 126, 4, 105, 42, - 6, 1, 230, 72, 4, 237, 42, 42, 2, 1, 230, 72, 4, 237, 42, 42, 6, 34, 199, - 141, 197, 157, 42, 2, 34, 199, 141, 197, 157, 42, 6, 1, 243, 80, 4, 237, - 42, 42, 2, 1, 243, 80, 4, 237, 42, 42, 6, 1, 243, 80, 4, 81, 105, 42, 2, - 1, 243, 80, 4, 81, 105, 42, 6, 1, 203, 77, 42, 2, 1, 203, 77, 42, 6, 1, - 252, 15, 243, 79, 42, 2, 1, 252, 15, 243, 79, 42, 6, 1, 252, 15, 243, 80, - 4, 237, 42, 42, 2, 1, 252, 15, 243, 80, 4, 237, 42, 42, 1, 210, 169, 42, - 6, 1, 191, 63, 4, 247, 244, 42, 2, 1, 191, 63, 4, 247, 244, 42, 6, 1, - 222, 115, 4, 106, 42, 2, 1, 222, 115, 4, 106, 42, 6, 1, 234, 98, 4, 199, - 210, 42, 2, 1, 234, 98, 4, 199, 210, 42, 6, 1, 234, 62, 4, 106, 42, 2, 1, - 234, 62, 4, 106, 42, 6, 1, 234, 62, 4, 199, 210, 42, 2, 1, 234, 62, 4, - 199, 210, 42, 6, 1, 221, 183, 243, 79, 42, 2, 1, 221, 183, 243, 79, 42, - 6, 1, 234, 73, 4, 199, 210, 42, 2, 1, 234, 73, 4, 199, 210, 42, 2, 1, - 210, 169, 42, 6, 1, 41, 4, 247, 244, 42, 2, 1, 41, 4, 247, 244, 42, 6, 1, - 41, 4, 236, 253, 42, 2, 1, 41, 4, 236, 253, 42, 6, 34, 41, 223, 197, 42, - 2, 34, 41, 223, 197, 42, 6, 1, 223, 198, 4, 247, 244, 42, 2, 1, 223, 198, - 4, 247, 244, 42, 6, 1, 205, 81, 42, 2, 1, 205, 81, 42, 6, 1, 205, 82, 4, - 236, 253, 42, 2, 1, 205, 82, 4, 236, 253, 42, 6, 1, 191, 63, 4, 236, 253, - 42, 2, 1, 191, 63, 4, 236, 253, 42, 6, 1, 191, 88, 4, 236, 253, 42, 2, 1, - 191, 88, 4, 236, 253, 42, 6, 1, 252, 15, 234, 244, 42, 2, 1, 252, 15, - 234, 244, 42, 6, 1, 228, 44, 4, 217, 125, 42, 2, 1, 228, 44, 4, 217, 125, - 42, 6, 1, 228, 44, 4, 236, 253, 42, 2, 1, 228, 44, 4, 236, 253, 42, 6, 1, - 186, 4, 236, 253, 42, 2, 1, 186, 4, 236, 253, 42, 6, 1, 249, 32, 74, 42, - 2, 1, 249, 32, 74, 42, 6, 1, 249, 32, 186, 4, 236, 253, 42, 2, 1, 249, - 32, 186, 4, 236, 253, 42, 6, 1, 234, 227, 4, 236, 253, 42, 2, 1, 234, - 227, 4, 236, 253, 42, 6, 1, 126, 4, 217, 125, 42, 2, 1, 126, 4, 217, 125, - 42, 6, 1, 126, 4, 236, 253, 42, 2, 1, 126, 4, 236, 253, 42, 6, 1, 126, 4, - 54, 251, 250, 42, 2, 1, 126, 4, 54, 251, 250, 42, 6, 1, 243, 80, 4, 236, - 253, 42, 2, 1, 243, 80, 4, 236, 253, 42, 6, 1, 231, 41, 4, 237, 42, 42, - 2, 1, 231, 41, 4, 237, 42, 42, 6, 1, 192, 59, 4, 236, 253, 42, 2, 1, 192, - 59, 4, 236, 253, 42, 6, 1, 231, 41, 4, 201, 23, 24, 106, 42, 2, 1, 231, - 41, 4, 201, 23, 24, 106, 42, 6, 1, 230, 72, 4, 106, 42, 2, 1, 230, 72, 4, - 106, 42, 6, 1, 230, 72, 4, 105, 42, 2, 1, 230, 72, 4, 105, 42, 6, 1, 221, - 21, 237, 101, 42, 2, 1, 221, 21, 237, 101, 42, 6, 1, 221, 21, 236, 147, - 42, 2, 1, 221, 21, 236, 147, 42, 6, 1, 221, 21, 191, 12, 42, 2, 1, 221, - 21, 191, 12, 42, 6, 1, 221, 21, 234, 236, 42, 2, 1, 221, 21, 234, 236, - 42, 6, 1, 221, 21, 219, 52, 42, 2, 1, 221, 21, 219, 52, 42, 6, 1, 221, - 21, 213, 137, 42, 2, 1, 221, 21, 213, 137, 42, 6, 1, 221, 21, 202, 110, - 42, 2, 1, 221, 21, 202, 110, 42, 6, 1, 221, 21, 198, 111, 42, 2, 1, 221, - 21, 198, 111, 42, 6, 1, 207, 13, 191, 87, 42, 2, 1, 207, 13, 191, 87, 42, - 6, 1, 234, 98, 4, 106, 42, 2, 1, 234, 98, 4, 106, 42, 6, 1, 219, 135, 42, - 2, 1, 219, 135, 42, 6, 1, 207, 1, 42, 2, 1, 207, 1, 42, 6, 1, 192, 129, - 42, 2, 1, 192, 129, 42, 6, 1, 208, 89, 42, 2, 1, 208, 89, 42, 6, 1, 193, - 123, 42, 2, 1, 193, 123, 42, 6, 1, 251, 137, 157, 42, 2, 1, 251, 137, - 157, 42, 6, 1, 234, 98, 4, 82, 106, 42, 2, 1, 234, 98, 4, 82, 106, 42, 6, - 1, 234, 62, 4, 82, 106, 42, 2, 1, 234, 62, 4, 82, 106, 42, 6, 1, 210, 54, - 4, 237, 42, 42, 2, 1, 210, 54, 4, 237, 42, 42, 6, 1, 203, 78, 4, 237, 42, - 42, 2, 1, 203, 78, 4, 237, 42, 42, 6, 1, 234, 62, 4, 45, 106, 42, 2, 1, - 234, 62, 4, 45, 106, 42, 6, 1, 234, 228, 42, 2, 1, 234, 228, 42, 6, 1, - 237, 150, 42, 2, 1, 237, 150, 42, 6, 1, 234, 98, 4, 237, 42, 42, 2, 1, - 234, 98, 4, 237, 42, 250, 199, 6, 1, 250, 78, 250, 199, 6, 1, 248, 179, - 250, 199, 6, 1, 231, 3, 250, 199, 6, 1, 237, 241, 250, 199, 6, 1, 234, - 151, 250, 199, 6, 1, 191, 123, 250, 199, 6, 1, 234, 130, 250, 199, 6, 1, - 233, 213, 250, 199, 6, 1, 159, 250, 199, 6, 1, 191, 62, 250, 199, 6, 1, - 223, 103, 250, 199, 6, 1, 219, 56, 250, 199, 6, 1, 192, 212, 250, 199, 6, - 1, 247, 112, 250, 199, 6, 1, 221, 226, 250, 199, 6, 1, 228, 247, 250, - 199, 6, 1, 223, 4, 250, 199, 6, 1, 231, 51, 250, 199, 6, 1, 243, 69, 250, - 199, 6, 1, 216, 167, 250, 199, 6, 1, 192, 33, 250, 199, 6, 1, 212, 240, - 250, 199, 6, 1, 203, 160, 250, 199, 6, 1, 195, 21, 250, 199, 6, 1, 246, - 209, 250, 199, 6, 1, 210, 32, 250, 199, 6, 1, 222, 220, 250, 199, 6, 1, - 166, 250, 199, 6, 1, 205, 34, 250, 199, 6, 1, 195, 71, 250, 199, 6, 1, - 198, 114, 250, 199, 6, 1, 207, 66, 250, 199, 6, 1, 242, 51, 250, 199, 6, - 1, 192, 17, 250, 199, 6, 1, 209, 106, 250, 199, 6, 1, 221, 237, 250, 199, - 6, 1, 211, 124, 250, 199, 6, 1, 233, 5, 250, 199, 59, 1, 45, 134, 206, - 183, 250, 199, 250, 255, 250, 199, 234, 65, 77, 250, 199, 233, 175, 77, - 250, 199, 242, 26, 250, 199, 208, 8, 77, 250, 199, 252, 16, 77, 250, 199, - 2, 1, 152, 250, 78, 250, 199, 2, 1, 250, 78, 250, 199, 2, 1, 248, 179, - 250, 199, 2, 1, 231, 3, 250, 199, 2, 1, 237, 241, 250, 199, 2, 1, 234, - 151, 250, 199, 2, 1, 191, 123, 250, 199, 2, 1, 234, 130, 250, 199, 2, 1, - 233, 213, 250, 199, 2, 1, 159, 250, 199, 2, 1, 191, 62, 250, 199, 2, 1, - 223, 103, 250, 199, 2, 1, 219, 56, 250, 199, 2, 1, 192, 212, 250, 199, 2, - 1, 247, 112, 250, 199, 2, 1, 221, 226, 250, 199, 2, 1, 228, 247, 250, - 199, 2, 1, 223, 4, 250, 199, 2, 1, 231, 51, 250, 199, 2, 1, 243, 69, 250, - 199, 2, 1, 216, 167, 250, 199, 2, 1, 192, 33, 250, 199, 2, 1, 212, 240, - 250, 199, 2, 1, 203, 160, 250, 199, 2, 1, 195, 21, 250, 199, 2, 1, 246, - 209, 250, 199, 2, 1, 210, 32, 250, 199, 2, 1, 222, 220, 250, 199, 2, 1, - 166, 250, 199, 2, 1, 205, 34, 250, 199, 2, 1, 195, 71, 250, 199, 2, 1, - 198, 114, 250, 199, 2, 1, 207, 66, 250, 199, 2, 1, 242, 51, 250, 199, 2, - 1, 192, 17, 250, 199, 2, 1, 209, 106, 250, 199, 2, 1, 221, 237, 250, 199, - 2, 1, 211, 124, 250, 199, 2, 1, 233, 5, 250, 199, 2, 34, 234, 152, 192, - 17, 250, 199, 2, 1, 11, 4, 105, 250, 199, 232, 42, 201, 58, 250, 199, - 228, 58, 206, 202, 250, 199, 233, 209, 57, 219, 199, 250, 199, 233, 209, - 57, 250, 199, 235, 66, 57, 135, 252, 9, 233, 204, 135, 252, 9, 205, 35, - 135, 252, 9, 203, 136, 135, 252, 9, 191, 99, 208, 72, 135, 252, 9, 191, - 99, 231, 193, 135, 252, 9, 198, 129, 135, 252, 9, 207, 10, 135, 252, 9, - 191, 97, 135, 252, 9, 210, 87, 135, 252, 9, 192, 48, 135, 252, 9, 199, - 51, 135, 252, 9, 231, 102, 135, 252, 9, 231, 103, 215, 96, 135, 252, 9, - 231, 100, 135, 252, 9, 208, 73, 210, 120, 135, 252, 9, 199, 98, 231, 121, - 135, 252, 9, 210, 59, 135, 252, 9, 250, 123, 230, 52, 135, 252, 9, 215, - 106, 135, 252, 9, 217, 96, 135, 252, 9, 216, 156, 135, 252, 9, 216, 157, - 221, 238, 135, 252, 9, 237, 177, 135, 252, 9, 208, 84, 135, 252, 9, 199, - 98, 208, 67, 135, 252, 9, 192, 61, 248, 180, 191, 247, 135, 252, 9, 211, - 106, 135, 252, 9, 223, 155, 135, 252, 9, 237, 78, 135, 252, 9, 191, 19, - 135, 87, 217, 15, 242, 218, 135, 209, 55, 203, 80, 135, 209, 55, 229, - 231, 205, 35, 135, 209, 55, 229, 231, 210, 78, 135, 209, 55, 229, 231, - 208, 77, 135, 209, 55, 229, 87, 135, 209, 55, 197, 154, 135, 209, 55, - 205, 35, 135, 209, 55, 210, 78, 135, 209, 55, 208, 77, 135, 209, 55, 228, - 231, 135, 209, 55, 228, 232, 229, 233, 39, 195, 155, 135, 209, 55, 208, - 13, 135, 209, 55, 237, 226, 211, 46, 217, 50, 135, 209, 55, 216, 145, - 135, 208, 145, 217, 47, 135, 209, 55, 207, 156, 135, 208, 145, 210, 89, - 135, 209, 55, 203, 65, 236, 96, 135, 209, 55, 202, 170, 236, 96, 135, - 208, 145, 202, 28, 210, 80, 135, 87, 116, 236, 96, 135, 87, 110, 236, 96, - 135, 208, 145, 212, 118, 230, 51, 135, 209, 55, 208, 78, 208, 72, 135, 1, - 251, 141, 135, 1, 248, 164, 135, 1, 231, 1, 135, 1, 237, 206, 135, 1, - 229, 213, 135, 1, 195, 155, 135, 1, 191, 91, 135, 1, 229, 154, 135, 1, - 199, 68, 135, 1, 191, 250, 135, 1, 52, 222, 79, 135, 1, 222, 79, 135, 1, - 220, 3, 135, 1, 52, 216, 174, 135, 1, 216, 174, 135, 1, 52, 212, 117, - 135, 1, 212, 117, 135, 1, 205, 143, 135, 1, 250, 76, 135, 1, 52, 210, 53, - 135, 1, 210, 53, 135, 1, 52, 197, 159, 135, 1, 197, 159, 135, 1, 208, 36, - 135, 1, 207, 33, 135, 1, 203, 64, 135, 1, 199, 157, 135, 191, 251, 197, - 237, 135, 34, 192, 31, 54, 195, 155, 135, 34, 192, 31, 195, 156, 191, - 250, 135, 34, 192, 31, 54, 191, 250, 135, 208, 145, 231, 102, 135, 208, - 145, 231, 100, 9, 31, 57, 9, 3, 205, 136, 9, 232, 118, 217, 32, 9, 3, - 205, 182, 9, 3, 205, 139, 9, 31, 87, 56, 250, 234, 238, 144, 206, 123, - 250, 234, 232, 83, 206, 123, 9, 207, 117, 250, 234, 210, 5, 216, 32, 57, - 250, 234, 210, 5, 199, 91, 198, 225, 57, 251, 206, 57, 9, 242, 26, 9, - 237, 164, 204, 5, 9, 209, 57, 195, 134, 57, 9, 3, 216, 8, 9, 3, 205, 156, - 251, 148, 193, 147, 9, 3, 251, 148, 250, 148, 9, 3, 207, 152, 251, 147, - 9, 3, 207, 162, 251, 119, 251, 54, 9, 3, 199, 201, 9, 2, 136, 199, 214, - 9, 2, 136, 34, 130, 4, 220, 12, 4, 192, 75, 9, 2, 136, 191, 113, 9, 2, - 233, 29, 9, 2, 237, 200, 9, 2, 222, 26, 9, 204, 20, 9, 1, 77, 9, 234, 53, - 80, 199, 49, 77, 9, 197, 221, 75, 208, 145, 77, 9, 208, 8, 77, 9, 1, 222, - 30, 192, 75, 9, 1, 230, 24, 9, 1, 130, 4, 217, 121, 56, 9, 1, 130, 4, - 230, 25, 56, 9, 1, 193, 132, 4, 230, 25, 56, 9, 1, 130, 4, 230, 25, 60, - 9, 1, 99, 4, 230, 25, 56, 9, 1, 251, 141, 9, 1, 248, 195, 9, 1, 199, 110, - 217, 43, 9, 1, 199, 109, 9, 1, 199, 24, 9, 1, 222, 234, 9, 1, 230, 48, 9, - 1, 221, 185, 9, 1, 237, 212, 9, 1, 199, 36, 9, 1, 207, 66, 9, 1, 191, - 113, 9, 1, 205, 41, 9, 1, 203, 104, 9, 1, 205, 187, 9, 1, 237, 235, 9, 1, - 199, 214, 9, 1, 191, 116, 9, 1, 251, 178, 9, 1, 231, 49, 9, 1, 221, 236, - 4, 103, 183, 56, 9, 1, 221, 236, 4, 115, 183, 60, 9, 1, 233, 33, 99, 4, - 223, 65, 196, 8, 9, 1, 233, 33, 99, 4, 103, 183, 56, 9, 1, 233, 33, 99, - 4, 115, 183, 56, 9, 199, 163, 9, 1, 233, 5, 9, 1, 208, 82, 9, 1, 222, 79, - 9, 1, 220, 11, 9, 1, 216, 189, 9, 1, 213, 11, 9, 1, 229, 178, 9, 1, 193, - 131, 9, 1, 130, 217, 79, 9, 1, 192, 75, 9, 233, 27, 9, 237, 198, 9, 222, - 24, 9, 233, 29, 9, 237, 200, 9, 222, 26, 9, 203, 150, 9, 200, 201, 9, - 217, 119, 56, 9, 230, 25, 56, 9, 230, 25, 60, 9, 200, 225, 251, 141, 9, - 223, 65, 237, 200, 9, 87, 213, 12, 231, 20, 9, 190, 237, 9, 18, 3, 2, - 196, 9, 56, 9, 18, 3, 223, 65, 2, 196, 9, 56, 9, 18, 3, 75, 60, 9, 207, - 13, 237, 200, 9, 233, 30, 4, 103, 236, 94, 9, 193, 133, 230, 25, 60, 250, - 234, 17, 191, 77, 250, 234, 17, 108, 250, 234, 17, 109, 250, 234, 17, - 139, 250, 234, 17, 137, 250, 234, 17, 153, 250, 234, 17, 173, 250, 234, - 17, 181, 250, 234, 17, 176, 250, 234, 17, 184, 9, 210, 4, 57, 9, 237, 93, - 204, 5, 9, 198, 224, 204, 5, 9, 232, 185, 209, 53, 201, 97, 9, 1, 236, - 95, 248, 195, 9, 1, 236, 95, 208, 82, 9, 1, 200, 177, 251, 141, 9, 1, - 130, 193, 148, 9, 1, 130, 4, 193, 133, 230, 25, 56, 9, 1, 130, 4, 193, - 133, 230, 25, 60, 9, 1, 136, 230, 24, 9, 1, 136, 230, 25, 251, 141, 9, 1, - 136, 230, 25, 193, 131, 9, 1, 126, 4, 230, 25, 56, 9, 1, 136, 230, 25, - 192, 75, 9, 1, 197, 120, 9, 1, 197, 118, 9, 1, 248, 205, 9, 1, 199, 110, - 4, 206, 183, 9, 1, 199, 110, 4, 115, 183, 95, 235, 74, 9, 1, 210, 32, 9, - 1, 199, 107, 9, 1, 248, 193, 9, 1, 179, 4, 230, 25, 56, 9, 1, 179, 4, - 103, 183, 81, 56, 9, 1, 212, 74, 9, 1, 234, 253, 9, 1, 179, 4, 115, 183, - 56, 9, 1, 199, 144, 9, 1, 199, 142, 9, 1, 237, 141, 9, 1, 237, 213, 4, - 206, 183, 9, 1, 237, 213, 4, 75, 60, 9, 1, 237, 213, 4, 75, 248, 183, 24, - 2, 199, 214, 9, 1, 237, 219, 9, 1, 237, 143, 9, 1, 235, 34, 9, 1, 237, - 213, 4, 115, 183, 95, 235, 74, 9, 1, 237, 213, 4, 232, 90, 183, 56, 9, 1, - 206, 96, 9, 1, 207, 67, 4, 2, 196, 8, 9, 1, 207, 67, 4, 206, 183, 9, 1, - 207, 67, 4, 75, 60, 9, 1, 207, 67, 4, 2, 196, 9, 60, 9, 1, 207, 67, 4, - 75, 248, 183, 24, 75, 56, 9, 1, 207, 67, 4, 103, 183, 56, 9, 1, 222, 231, - 9, 1, 207, 67, 4, 232, 90, 183, 56, 9, 1, 205, 42, 4, 75, 248, 183, 24, - 75, 56, 9, 1, 205, 42, 4, 115, 183, 60, 9, 1, 205, 42, 4, 115, 183, 248, - 183, 24, 115, 183, 56, 9, 1, 205, 188, 4, 103, 183, 60, 9, 1, 205, 188, - 4, 115, 183, 56, 9, 1, 199, 215, 4, 115, 183, 56, 9, 1, 251, 179, 4, 115, - 183, 56, 9, 1, 236, 95, 233, 5, 9, 1, 233, 6, 4, 75, 215, 161, 60, 9, 1, - 233, 6, 4, 75, 60, 9, 1, 195, 143, 9, 1, 233, 6, 4, 115, 183, 60, 9, 1, - 210, 30, 9, 1, 208, 83, 4, 75, 56, 9, 1, 208, 83, 4, 115, 183, 56, 9, 1, - 221, 235, 9, 1, 200, 142, 222, 79, 9, 1, 222, 80, 4, 206, 183, 9, 1, 222, - 80, 4, 75, 56, 9, 1, 214, 56, 9, 1, 222, 80, 4, 115, 183, 60, 9, 1, 231, - 190, 9, 1, 231, 191, 4, 206, 183, 9, 1, 213, 233, 9, 1, 231, 191, 4, 103, - 183, 60, 9, 1, 230, 133, 9, 1, 231, 191, 4, 115, 183, 56, 9, 1, 220, 12, - 4, 2, 196, 8, 9, 1, 220, 12, 4, 75, 56, 9, 1, 220, 12, 4, 115, 183, 56, - 9, 1, 220, 12, 4, 115, 183, 60, 9, 1, 213, 12, 4, 75, 60, 9, 1, 213, 12, - 231, 20, 9, 1, 206, 160, 9, 1, 213, 12, 4, 206, 183, 9, 1, 213, 12, 4, - 115, 183, 56, 9, 1, 229, 179, 236, 125, 9, 1, 199, 145, 4, 75, 56, 9, 1, - 229, 179, 4, 99, 56, 9, 1, 229, 179, 230, 220, 9, 1, 229, 179, 230, 221, - 4, 230, 25, 56, 9, 1, 199, 110, 217, 44, 230, 220, 9, 1, 193, 132, 4, - 206, 183, 9, 1, 221, 108, 211, 139, 9, 1, 211, 139, 9, 1, 69, 9, 1, 191, - 225, 9, 1, 221, 108, 191, 225, 9, 1, 193, 132, 4, 103, 183, 56, 9, 1, - 195, 150, 9, 1, 233, 33, 192, 75, 9, 1, 99, 4, 199, 210, 9, 1, 99, 4, 2, - 196, 8, 9, 1, 193, 132, 4, 75, 56, 9, 1, 73, 9, 1, 99, 4, 115, 183, 60, - 9, 1, 99, 249, 30, 9, 1, 99, 249, 31, 4, 230, 25, 56, 9, 232, 42, 201, - 58, 9, 1, 251, 229, 9, 2, 136, 34, 205, 188, 4, 220, 12, 4, 130, 217, 79, - 9, 2, 136, 34, 208, 83, 4, 220, 12, 4, 130, 217, 79, 9, 2, 136, 92, 89, - 20, 9, 2, 136, 220, 12, 251, 141, 9, 2, 136, 222, 234, 9, 2, 136, 115, - 236, 94, 9, 2, 136, 205, 41, 9, 234, 53, 80, 250, 80, 9, 201, 93, 80, - 206, 55, 234, 98, 229, 82, 9, 2, 136, 206, 108, 191, 77, 9, 2, 136, 196, - 69, 207, 86, 191, 77, 9, 2, 136, 236, 95, 229, 204, 80, 221, 185, 9, 2, - 136, 92, 76, 20, 9, 2, 131, 205, 41, 9, 2, 136, 217, 120, 9, 2, 193, 131, - 9, 2, 192, 75, 9, 2, 136, 192, 75, 9, 2, 136, 213, 11, 9, 209, 100, 80, - 205, 172, 9, 234, 63, 246, 230, 131, 201, 58, 9, 234, 63, 246, 230, 136, - 201, 58, 9, 206, 108, 136, 201, 59, 4, 232, 219, 246, 229, 9, 2, 131, - 216, 189, 9, 1, 237, 213, 4, 223, 65, 196, 8, 9, 1, 207, 67, 4, 223, 65, - 196, 8, 233, 164, 250, 234, 17, 191, 77, 233, 164, 250, 234, 17, 108, - 233, 164, 250, 234, 17, 109, 233, 164, 250, 234, 17, 139, 233, 164, 250, - 234, 17, 137, 233, 164, 250, 234, 17, 153, 233, 164, 250, 234, 17, 173, - 233, 164, 250, 234, 17, 181, 233, 164, 250, 234, 17, 176, 233, 164, 250, - 234, 17, 184, 9, 1, 203, 105, 4, 75, 60, 9, 1, 237, 236, 4, 75, 60, 9, 1, - 231, 50, 4, 75, 60, 9, 3, 202, 168, 251, 86, 9, 3, 202, 168, 209, 9, 216, - 167, 9, 1, 229, 179, 4, 223, 65, 196, 8, 200, 59, 234, 53, 80, 210, 117, - 200, 59, 200, 172, 232, 42, 201, 58, 200, 59, 200, 227, 232, 42, 201, 58, - 200, 59, 200, 172, 242, 35, 200, 59, 200, 227, 242, 35, 200, 59, 228, - 209, 242, 35, 200, 59, 242, 36, 202, 105, 219, 200, 200, 59, 242, 36, - 202, 105, 187, 200, 59, 200, 172, 242, 36, 202, 105, 219, 200, 200, 59, - 200, 227, 242, 36, 202, 105, 187, 200, 59, 238, 233, 200, 59, 229, 238, - 211, 163, 200, 59, 229, 238, 216, 143, 200, 59, 229, 238, 250, 145, 200, - 59, 252, 16, 77, 200, 59, 1, 251, 151, 200, 59, 1, 200, 177, 251, 151, - 200, 59, 1, 248, 161, 200, 59, 1, 231, 180, 200, 59, 1, 231, 181, 231, - 157, 200, 59, 1, 237, 209, 200, 59, 1, 236, 95, 237, 210, 206, 176, 200, - 59, 1, 229, 213, 200, 59, 1, 193, 131, 200, 59, 1, 191, 113, 200, 59, 1, - 229, 152, 200, 59, 1, 199, 64, 200, 59, 1, 199, 65, 231, 157, 200, 59, 1, - 191, 208, 200, 59, 1, 191, 209, 229, 213, 200, 59, 1, 222, 49, 200, 59, - 1, 220, 10, 200, 59, 1, 216, 28, 200, 59, 1, 212, 117, 200, 59, 1, 204, - 13, 200, 59, 1, 52, 204, 13, 200, 59, 1, 73, 200, 59, 1, 210, 53, 200, - 59, 1, 207, 13, 210, 53, 200, 59, 1, 205, 184, 200, 59, 1, 208, 76, 200, - 59, 1, 206, 176, 200, 59, 1, 203, 64, 200, 59, 1, 199, 154, 200, 59, 1, - 209, 243, 248, 146, 200, 59, 1, 209, 243, 231, 47, 200, 59, 1, 209, 243, - 237, 18, 200, 59, 208, 159, 56, 200, 59, 208, 159, 60, 200, 59, 208, 159, - 235, 93, 200, 59, 191, 0, 56, 200, 59, 191, 0, 60, 200, 59, 191, 0, 235, - 93, 200, 59, 207, 111, 56, 200, 59, 207, 111, 60, 200, 59, 235, 94, 191, - 9, 228, 208, 200, 59, 235, 94, 191, 9, 251, 57, 200, 59, 229, 218, 56, - 200, 59, 229, 218, 60, 200, 59, 229, 217, 235, 93, 200, 59, 233, 230, 56, - 200, 59, 233, 230, 60, 200, 59, 206, 19, 200, 59, 232, 255, 236, 96, 200, - 59, 207, 241, 200, 59, 206, 49, 200, 59, 103, 81, 183, 56, 200, 59, 103, - 81, 183, 60, 200, 59, 115, 183, 56, 200, 59, 115, 183, 60, 200, 59, 211, - 159, 219, 89, 56, 200, 59, 211, 159, 219, 89, 60, 200, 59, 215, 82, 200, - 59, 249, 29, 200, 59, 1, 202, 23, 191, 69, 200, 59, 1, 202, 23, 221, 177, - 200, 59, 1, 202, 23, 233, 18, 9, 1, 248, 196, 4, 115, 183, 228, 158, 60, - 9, 1, 248, 196, 4, 75, 248, 183, 24, 115, 183, 56, 9, 1, 248, 196, 4, - 115, 183, 209, 51, 196, 62, 60, 9, 1, 248, 196, 4, 115, 183, 209, 51, - 196, 62, 248, 183, 24, 103, 183, 56, 9, 1, 248, 196, 4, 103, 183, 248, - 183, 24, 75, 56, 9, 1, 248, 196, 4, 223, 65, 2, 196, 9, 60, 9, 1, 248, - 196, 4, 2, 196, 8, 9, 1, 179, 4, 103, 183, 56, 9, 1, 179, 4, 115, 183, - 209, 51, 196, 62, 60, 9, 1, 237, 213, 4, 103, 183, 195, 82, 248, 183, 24, - 2, 199, 214, 9, 1, 237, 213, 4, 223, 65, 2, 196, 9, 60, 9, 1, 207, 67, 4, - 105, 9, 1, 205, 42, 4, 232, 90, 183, 56, 9, 1, 251, 179, 4, 103, 183, 56, - 9, 1, 251, 179, 4, 115, 183, 209, 51, 235, 75, 56, 9, 1, 251, 179, 4, - 103, 183, 195, 82, 56, 9, 1, 233, 6, 4, 103, 183, 60, 9, 1, 233, 6, 4, - 115, 183, 209, 51, 196, 62, 60, 9, 1, 221, 236, 4, 75, 56, 9, 1, 221, - 236, 4, 115, 183, 56, 9, 1, 221, 236, 4, 115, 183, 209, 51, 196, 62, 60, - 9, 1, 92, 4, 75, 56, 9, 1, 92, 4, 75, 60, 9, 1, 213, 12, 4, 103, 183, 60, - 9, 1, 213, 12, 4, 2, 199, 214, 9, 1, 213, 12, 4, 2, 196, 8, 9, 1, 220, - 12, 4, 164, 9, 1, 207, 67, 4, 103, 183, 195, 82, 56, 9, 1, 207, 67, 4, - 230, 25, 56, 9, 1, 205, 42, 4, 103, 183, 195, 82, 56, 9, 1, 179, 4, 2, 9, - 1, 199, 215, 60, 9, 1, 179, 4, 2, 9, 1, 199, 215, 24, 103, 236, 94, 9, 1, - 205, 42, 4, 2, 9, 1, 199, 215, 24, 103, 236, 94, 9, 1, 207, 67, 4, 2, 9, - 1, 199, 215, 24, 103, 236, 94, 9, 1, 179, 4, 2, 9, 1, 199, 215, 56, 9, 1, - 130, 4, 233, 164, 250, 234, 17, 103, 56, 9, 1, 130, 4, 233, 164, 250, - 234, 17, 115, 56, 9, 1, 233, 33, 99, 4, 233, 164, 250, 234, 17, 103, 56, - 9, 1, 233, 33, 99, 4, 233, 164, 250, 234, 17, 115, 56, 9, 1, 233, 33, 99, - 4, 233, 164, 250, 234, 17, 232, 90, 60, 9, 1, 193, 132, 4, 233, 164, 250, - 234, 17, 103, 56, 9, 1, 193, 132, 4, 233, 164, 250, 234, 17, 115, 56, 9, - 1, 99, 249, 31, 4, 233, 164, 250, 234, 17, 103, 56, 9, 1, 99, 249, 31, 4, - 233, 164, 250, 234, 17, 115, 56, 9, 1, 179, 4, 233, 164, 250, 234, 17, - 232, 90, 60, 9, 1, 205, 42, 4, 233, 164, 250, 234, 17, 232, 90, 56, 9, 1, - 205, 42, 4, 223, 65, 196, 8, 9, 1, 222, 80, 4, 103, 183, 56, 199, 41, 1, - 230, 58, 199, 41, 1, 203, 114, 199, 41, 1, 213, 10, 199, 41, 1, 207, 173, - 199, 41, 1, 249, 101, 199, 41, 1, 219, 132, 199, 41, 1, 222, 95, 199, 41, - 1, 251, 128, 199, 41, 1, 195, 183, 199, 41, 1, 216, 188, 199, 41, 1, 233, - 66, 199, 41, 1, 237, 21, 199, 41, 1, 199, 43, 199, 41, 1, 220, 98, 199, - 41, 1, 231, 199, 199, 41, 1, 230, 226, 199, 41, 1, 205, 40, 199, 41, 1, - 237, 162, 199, 41, 1, 191, 94, 199, 41, 1, 199, 156, 199, 41, 1, 192, - 140, 199, 41, 1, 210, 67, 199, 41, 1, 222, 243, 199, 41, 1, 243, 82, 199, - 41, 1, 197, 127, 199, 41, 1, 229, 144, 199, 41, 1, 221, 189, 199, 41, 1, - 199, 42, 199, 41, 1, 191, 121, 199, 41, 1, 203, 103, 199, 41, 1, 205, - 191, 199, 41, 1, 237, 239, 199, 41, 1, 159, 199, 41, 1, 191, 7, 199, 41, - 1, 251, 175, 199, 41, 1, 231, 48, 199, 41, 1, 208, 86, 199, 41, 1, 193, - 175, 199, 41, 252, 18, 199, 41, 252, 119, 199, 41, 227, 255, 199, 41, - 234, 144, 199, 41, 196, 157, 199, 41, 211, 75, 199, 41, 234, 154, 199, - 41, 233, 154, 199, 41, 211, 158, 199, 41, 211, 168, 199, 41, 200, 201, - 199, 41, 1, 214, 236, 213, 94, 17, 191, 77, 213, 94, 17, 108, 213, 94, - 17, 109, 213, 94, 17, 139, 213, 94, 17, 137, 213, 94, 17, 153, 213, 94, - 17, 173, 213, 94, 17, 181, 213, 94, 17, 176, 213, 94, 17, 184, 213, 94, - 1, 65, 213, 94, 1, 234, 145, 213, 94, 1, 70, 213, 94, 1, 73, 213, 94, 1, - 69, 213, 94, 1, 211, 76, 213, 94, 1, 74, 213, 94, 1, 237, 227, 213, 94, - 1, 215, 47, 213, 94, 1, 249, 103, 213, 94, 1, 168, 213, 94, 1, 199, 247, - 213, 94, 1, 223, 4, 213, 94, 1, 246, 209, 213, 94, 1, 237, 241, 213, 94, - 1, 166, 213, 94, 1, 206, 104, 213, 94, 1, 189, 213, 94, 1, 231, 145, 213, - 94, 1, 233, 68, 213, 94, 1, 157, 213, 94, 1, 171, 213, 94, 1, 214, 249, - 193, 37, 213, 94, 1, 172, 213, 94, 1, 212, 88, 213, 94, 1, 180, 213, 94, - 1, 144, 213, 94, 1, 193, 187, 213, 94, 1, 169, 213, 94, 1, 212, 89, 193, - 37, 213, 94, 1, 222, 166, 223, 4, 213, 94, 1, 222, 166, 246, 209, 213, - 94, 1, 222, 166, 166, 213, 94, 33, 203, 35, 136, 198, 74, 213, 94, 33, - 203, 35, 131, 198, 74, 213, 94, 33, 203, 35, 206, 175, 198, 74, 213, 94, - 33, 177, 237, 41, 198, 74, 213, 94, 33, 177, 136, 198, 74, 213, 94, 33, - 177, 131, 198, 74, 213, 94, 33, 177, 206, 175, 198, 74, 213, 94, 33, 214, - 199, 77, 213, 94, 33, 54, 75, 56, 213, 94, 136, 163, 250, 255, 213, 94, - 131, 163, 250, 255, 213, 94, 16, 211, 77, 237, 56, 213, 94, 16, 231, 144, - 213, 94, 242, 26, 213, 94, 233, 175, 77, 213, 94, 220, 70, 213, 94, 237, - 188, 213, 94, 236, 98, 57, 213, 94, 199, 190, 57, 205, 146, 1, 251, 153, - 205, 146, 1, 248, 100, 205, 146, 1, 231, 179, 205, 146, 1, 237, 211, 205, - 146, 1, 223, 16, 205, 146, 1, 249, 101, 205, 146, 1, 191, 80, 205, 146, - 1, 223, 25, 205, 146, 1, 198, 120, 205, 146, 1, 191, 189, 205, 146, 1, - 222, 96, 205, 146, 1, 220, 94, 205, 146, 1, 216, 28, 205, 146, 1, 212, - 117, 205, 146, 1, 202, 166, 205, 146, 1, 223, 134, 205, 146, 1, 232, 238, - 205, 146, 1, 197, 162, 205, 146, 1, 208, 5, 205, 146, 1, 206, 176, 205, - 146, 1, 203, 133, 205, 146, 1, 199, 238, 205, 146, 87, 223, 134, 205, - 146, 87, 223, 133, 205, 146, 87, 211, 152, 205, 146, 87, 237, 225, 205, - 146, 59, 1, 234, 10, 191, 189, 205, 146, 87, 234, 10, 191, 189, 205, 146, - 18, 3, 177, 73, 205, 146, 18, 3, 73, 205, 146, 18, 3, 210, 243, 252, 154, - 205, 146, 18, 3, 177, 252, 154, 205, 146, 18, 3, 252, 154, 205, 146, 18, - 3, 210, 243, 65, 205, 146, 18, 3, 177, 65, 205, 146, 18, 3, 65, 205, 146, - 59, 1, 203, 35, 65, 205, 146, 18, 3, 203, 35, 65, 205, 146, 18, 3, 177, - 69, 205, 146, 18, 3, 69, 205, 146, 59, 1, 70, 205, 146, 18, 3, 177, 70, - 205, 146, 18, 3, 70, 205, 146, 18, 3, 74, 205, 146, 18, 3, 200, 201, 205, - 146, 87, 214, 79, 205, 146, 208, 145, 214, 79, 205, 146, 208, 145, 251, - 203, 205, 146, 208, 145, 251, 70, 205, 146, 208, 145, 249, 7, 205, 146, - 208, 145, 250, 124, 205, 146, 208, 145, 203, 52, 205, 146, 252, 16, 77, - 205, 146, 208, 145, 216, 178, 208, 42, 205, 146, 208, 145, 191, 16, 205, - 146, 208, 145, 208, 42, 205, 146, 208, 145, 191, 119, 205, 146, 208, 145, - 197, 50, 205, 146, 208, 145, 250, 205, 205, 146, 208, 145, 202, 28, 217, - 18, 205, 146, 208, 145, 251, 46, 217, 66, 1, 230, 32, 217, 66, 1, 252, - 103, 217, 66, 1, 251, 201, 217, 66, 1, 251, 246, 217, 66, 1, 251, 193, - 217, 66, 1, 196, 32, 217, 66, 1, 250, 73, 217, 66, 1, 223, 25, 217, 66, - 1, 250, 121, 217, 66, 1, 251, 160, 217, 66, 1, 251, 165, 217, 66, 1, 251, - 156, 217, 66, 1, 251, 98, 217, 66, 1, 251, 81, 217, 66, 1, 250, 169, 217, - 66, 1, 223, 134, 217, 66, 1, 251, 15, 217, 66, 1, 250, 134, 217, 66, 1, - 250, 243, 217, 66, 1, 250, 239, 217, 66, 1, 250, 159, 217, 66, 1, 250, - 132, 217, 66, 1, 235, 18, 217, 66, 1, 222, 87, 217, 66, 1, 251, 178, 217, - 66, 251, 207, 77, 217, 66, 195, 19, 77, 217, 66, 231, 116, 77, 217, 66, - 208, 144, 200, 59, 1, 141, 214, 54, 200, 59, 1, 141, 223, 4, 200, 59, 1, - 141, 212, 88, 200, 59, 1, 141, 197, 128, 200, 59, 1, 141, 213, 66, 200, - 59, 1, 141, 213, 48, 200, 59, 1, 141, 248, 153, 200, 59, 1, 141, 166, - 200, 59, 1, 141, 219, 49, 200, 59, 1, 141, 219, 38, 200, 59, 1, 141, 201, - 170, 9, 1, 130, 4, 250, 120, 233, 29, 9, 1, 130, 4, 250, 120, 198, 49, - 50, 233, 29, 9, 1, 130, 4, 50, 82, 105, 9, 1, 130, 4, 45, 82, 105, 9, 1, - 130, 4, 250, 120, 222, 26, 9, 1, 130, 4, 250, 120, 248, 29, 50, 222, 26, - 9, 1, 130, 4, 250, 120, 206, 110, 75, 56, 9, 1, 130, 4, 250, 120, 50, - 206, 110, 236, 96, 9, 1, 130, 4, 250, 120, 45, 206, 110, 236, 96, 9, 1, - 130, 4, 250, 120, 206, 110, 75, 60, 9, 1, 130, 4, 75, 56, 9, 1, 130, 4, - 250, 120, 198, 49, 50, 233, 30, 24, 75, 56, 9, 1, 130, 4, 50, 82, 201, - 23, 24, 75, 56, 9, 1, 130, 4, 250, 120, 248, 29, 50, 222, 27, 24, 75, 56, - 9, 1, 130, 4, 250, 120, 198, 49, 50, 233, 30, 24, 45, 206, 183, 9, 1, - 130, 4, 50, 82, 201, 23, 24, 45, 206, 183, 9, 1, 130, 4, 250, 120, 248, - 29, 50, 222, 27, 24, 45, 206, 183, 9, 1, 130, 4, 250, 120, 50, 230, 24, - 9, 1, 130, 4, 250, 120, 45, 230, 24, 9, 199, 164, 4, 210, 241, 230, 24, - 9, 199, 164, 4, 210, 241, 193, 131, 9, 199, 164, 4, 103, 183, 60, 9, 1, - 198, 255, 192, 75, 9, 249, 22, 206, 110, 236, 96, 9, 207, 142, 206, 110, - 236, 96, 9, 1, 213, 12, 4, 223, 65, 2, 196, 8, 9, 1, 179, 4, 223, 65, 2, - 196, 9, 60, 9, 1, 199, 215, 4, 75, 60, 9, 1, 199, 215, 4, 115, 183, 60, - 9, 1, 221, 236, 4, 103, 183, 195, 82, 60, 9, 81, 199, 210, 9, 209, 1, 87, - 56, 9, 209, 173, 87, 56, 9, 2, 136, 193, 23, 251, 155, 9, 2, 131, 193, - 23, 223, 33, 9, 2, 131, 193, 23, 223, 151, 9, 2, 131, 193, 23, 199, 168, - 9, 217, 121, 193, 176, 9, 200, 177, 130, 215, 217, 9, 235, 84, 217, 120, - 9, 134, 217, 121, 138, 217, 120, 9, 1, 248, 196, 4, 2, 196, 9, 60, 9, 1, - 248, 196, 4, 230, 25, 56, 9, 1, 222, 235, 4, 103, 183, 56, 9, 1, 199, - 215, 4, 103, 183, 56, 9, 1, 233, 6, 4, 75, 248, 183, 24, 115, 183, 56, 9, - 1, 208, 83, 4, 75, 60, 9, 1, 220, 12, 4, 54, 164, 9, 1, 92, 4, 115, 183, - 56, 9, 1, 99, 4, 103, 183, 248, 183, 24, 230, 25, 56, 9, 1, 99, 4, 103, - 183, 248, 183, 24, 75, 56, 9, 1, 207, 67, 4, 218, 236, 9, 1, 193, 132, 4, - 75, 193, 52, 9, 1, 206, 137, 192, 75, 9, 1, 131, 251, 141, 9, 1, 237, - 213, 4, 115, 183, 60, 9, 1, 205, 188, 4, 115, 183, 60, 9, 1, 231, 191, 4, - 223, 65, 105, 9, 1, 201, 48, 193, 131, 9, 1, 191, 114, 4, 223, 65, 196, - 9, 56, 9, 1, 251, 179, 4, 115, 183, 60, 9, 1, 222, 80, 4, 75, 60, 9, 1, - 208, 83, 4, 75, 248, 183, 24, 213, 31, 183, 56, 9, 1, 248, 196, 4, 2, 92, - 56, 9, 1, 210, 33, 4, 2, 92, 56, 9, 1, 199, 110, 4, 2, 199, 110, 56, 9, - 1, 207, 67, 4, 2, 213, 12, 56, 9, 1, 99, 4, 103, 183, 248, 183, 24, 2, - 213, 12, 56, 9, 1, 251, 204, 233, 5, 9, 1, 251, 204, 208, 82, 9, 1, 251, - 204, 213, 11, 9, 1, 210, 33, 4, 2, 196, 8, 9, 1, 199, 110, 4, 2, 196, 8, - 9, 1, 197, 121, 4, 2, 196, 8, 9, 1, 199, 145, 4, 2, 196, 8, 9, 1, 221, - 236, 4, 2, 196, 8, 9, 1, 231, 50, 4, 115, 183, 56, 9, 1, 251, 204, 208, - 83, 4, 115, 183, 56, 9, 1, 222, 235, 4, 115, 183, 56, 9, 1, 222, 235, 4, - 115, 183, 60, 9, 1, 220, 12, 4, 2, 9, 1, 199, 215, 56, 9, 1, 230, 190, 9, - 2, 233, 33, 192, 75, 9, 2, 136, 233, 33, 192, 75, 9, 2, 136, 99, 249, 31, - 4, 103, 183, 60, 9, 2, 136, 193, 23, 205, 177, 9, 2, 136, 191, 116, 9, - 219, 245, 206, 110, 75, 56, 9, 219, 245, 206, 110, 75, 60, 9, 200, 202, - 60, 9, 219, 245, 242, 219, 60, 9, 219, 245, 206, 110, 75, 223, 90, 242, - 219, 60, 9, 2, 131, 193, 131, 9, 2, 136, 193, 23, 250, 236, 9, 2, 136, - 205, 187, 9, 2, 136, 251, 178, 9, 2, 136, 208, 82, 9, 2, 136, 213, 12, 4, - 222, 26, 9, 2, 131, 213, 12, 4, 222, 26, 9, 2, 136, 193, 23, 250, 131, 9, - 2, 136, 193, 23, 250, 168, 9, 2, 136, 193, 23, 251, 80, 9, 2, 136, 193, - 23, 205, 166, 9, 2, 136, 193, 23, 208, 46, 9, 2, 136, 193, 23, 193, 155, - 9, 2, 136, 232, 118, 217, 32, 9, 2, 136, 3, 205, 182, 9, 236, 173, 234, - 53, 80, 250, 80, 9, 152, 237, 201, 60, 9, 238, 124, 233, 29, 9, 238, 124, - 237, 200, 9, 238, 124, 222, 26, 9, 238, 124, 233, 27, 9, 238, 124, 237, - 198, 9, 238, 124, 222, 24, 9, 163, 91, 75, 56, 9, 163, 103, 183, 56, 9, - 163, 218, 237, 56, 9, 163, 91, 75, 60, 9, 163, 103, 183, 60, 9, 163, 218, - 237, 60, 9, 211, 66, 233, 27, 9, 211, 66, 237, 198, 9, 211, 66, 222, 24, - 9, 2, 136, 193, 131, 9, 233, 30, 4, 206, 183, 9, 233, 30, 4, 75, 56, 9, - 222, 27, 4, 75, 60, 9, 45, 250, 186, 56, 9, 50, 250, 186, 56, 9, 45, 250, - 186, 60, 9, 50, 250, 186, 60, 9, 54, 50, 250, 186, 56, 9, 54, 50, 250, - 186, 95, 4, 236, 96, 9, 50, 250, 186, 95, 4, 236, 96, 9, 237, 201, 4, - 236, 96, 9, 87, 202, 201, 213, 12, 231, 20, 104, 3, 223, 65, 247, 71, - 104, 3, 247, 71, 104, 3, 251, 20, 104, 3, 195, 32, 104, 1, 203, 35, 65, - 104, 1, 65, 104, 1, 252, 154, 104, 1, 70, 104, 1, 223, 170, 104, 1, 69, - 104, 1, 196, 26, 104, 1, 121, 148, 104, 1, 121, 170, 104, 1, 247, 74, 73, - 104, 1, 203, 35, 73, 104, 1, 73, 104, 1, 251, 184, 104, 1, 247, 74, 74, - 104, 1, 203, 35, 74, 104, 1, 74, 104, 1, 250, 113, 104, 1, 157, 104, 1, - 221, 190, 104, 1, 231, 203, 104, 1, 231, 54, 104, 1, 214, 54, 104, 1, - 247, 112, 104, 1, 246, 209, 104, 1, 223, 4, 104, 1, 222, 225, 104, 1, - 212, 88, 104, 1, 197, 128, 104, 1, 197, 116, 104, 1, 237, 146, 104, 1, - 237, 130, 104, 1, 213, 66, 104, 1, 199, 247, 104, 1, 199, 44, 104, 1, - 237, 241, 104, 1, 237, 23, 104, 1, 180, 104, 1, 213, 48, 104, 1, 168, - 104, 1, 209, 219, 104, 1, 249, 103, 104, 1, 248, 153, 104, 1, 172, 104, - 1, 169, 104, 1, 166, 104, 1, 206, 104, 104, 1, 171, 104, 1, 219, 49, 104, - 1, 219, 38, 104, 1, 195, 185, 104, 1, 203, 160, 104, 1, 201, 170, 104, 1, - 189, 104, 1, 144, 104, 18, 3, 211, 139, 104, 18, 3, 211, 74, 104, 3, 212, - 128, 104, 3, 250, 95, 104, 18, 3, 252, 154, 104, 18, 3, 70, 104, 18, 3, - 223, 170, 104, 18, 3, 69, 104, 18, 3, 196, 26, 104, 18, 3, 121, 148, 104, - 18, 3, 121, 206, 105, 104, 18, 3, 247, 74, 73, 104, 18, 3, 203, 35, 73, - 104, 18, 3, 73, 104, 18, 3, 251, 184, 104, 18, 3, 247, 74, 74, 104, 18, - 3, 203, 35, 74, 104, 18, 3, 74, 104, 18, 3, 250, 113, 104, 3, 195, 37, - 104, 18, 3, 208, 200, 73, 104, 18, 3, 250, 90, 104, 211, 102, 104, 201, - 33, 3, 196, 150, 104, 201, 33, 3, 251, 22, 104, 230, 177, 252, 8, 104, - 251, 251, 252, 8, 104, 18, 3, 247, 74, 177, 73, 104, 18, 3, 196, 148, - 104, 18, 3, 196, 25, 104, 1, 208, 89, 104, 1, 221, 169, 104, 1, 231, 29, - 104, 1, 191, 123, 104, 1, 237, 135, 104, 1, 207, 1, 104, 1, 233, 68, 104, - 1, 191, 175, 104, 1, 121, 206, 105, 104, 1, 121, 219, 50, 104, 18, 3, - 121, 170, 104, 18, 3, 121, 219, 50, 104, 237, 193, 104, 54, 237, 193, - 104, 17, 191, 77, 104, 17, 108, 104, 17, 109, 104, 17, 139, 104, 17, 137, - 104, 17, 153, 104, 17, 173, 104, 17, 181, 104, 17, 176, 104, 17, 184, - 104, 252, 16, 57, 104, 3, 136, 201, 241, 236, 96, 104, 1, 247, 74, 65, - 104, 1, 211, 139, 104, 1, 211, 74, 104, 1, 250, 90, 104, 1, 196, 148, - 104, 1, 196, 25, 104, 1, 217, 24, 237, 146, 104, 1, 191, 71, 104, 1, 88, - 169, 104, 1, 231, 90, 104, 1, 222, 203, 104, 1, 230, 231, 201, 58, 104, - 1, 237, 136, 104, 1, 249, 3, 248, 175, 251, 49, 248, 175, 3, 247, 71, - 248, 175, 3, 251, 20, 248, 175, 3, 195, 32, 248, 175, 1, 65, 248, 175, 1, - 252, 154, 248, 175, 1, 70, 248, 175, 1, 223, 170, 248, 175, 1, 69, 248, - 175, 1, 196, 26, 248, 175, 1, 121, 148, 248, 175, 1, 121, 170, 248, 175, - 1, 73, 248, 175, 1, 251, 184, 248, 175, 1, 74, 248, 175, 1, 250, 113, - 248, 175, 1, 157, 248, 175, 1, 221, 190, 248, 175, 1, 231, 203, 248, 175, - 1, 231, 54, 248, 175, 1, 214, 54, 248, 175, 1, 247, 112, 248, 175, 1, - 246, 209, 248, 175, 1, 223, 4, 248, 175, 1, 222, 225, 248, 175, 1, 212, - 88, 248, 175, 1, 197, 128, 248, 175, 1, 197, 116, 248, 175, 1, 237, 146, - 248, 175, 1, 237, 130, 248, 175, 1, 213, 66, 248, 175, 1, 199, 247, 248, - 175, 1, 199, 44, 248, 175, 1, 237, 241, 248, 175, 1, 237, 23, 248, 175, - 1, 180, 248, 175, 1, 168, 248, 175, 1, 209, 219, 248, 175, 1, 249, 103, - 248, 175, 1, 248, 153, 248, 175, 1, 172, 248, 175, 1, 169, 248, 175, 1, - 166, 248, 175, 1, 171, 248, 175, 1, 203, 160, 248, 175, 1, 201, 170, 248, - 175, 1, 189, 248, 175, 1, 144, 248, 175, 3, 212, 128, 248, 175, 3, 250, - 95, 248, 175, 18, 3, 252, 154, 248, 175, 18, 3, 70, 248, 175, 18, 3, 223, - 170, 248, 175, 18, 3, 69, 248, 175, 18, 3, 196, 26, 248, 175, 18, 3, 121, - 148, 248, 175, 18, 3, 121, 206, 105, 248, 175, 18, 3, 73, 248, 175, 18, - 3, 251, 184, 248, 175, 18, 3, 74, 248, 175, 18, 3, 250, 113, 248, 175, 3, - 195, 37, 248, 175, 1, 221, 179, 199, 247, 248, 175, 250, 114, 219, 174, - 77, 248, 175, 1, 206, 104, 248, 175, 1, 207, 1, 248, 175, 1, 191, 175, - 248, 175, 1, 121, 206, 105, 248, 175, 1, 121, 219, 50, 248, 175, 18, 3, - 121, 170, 248, 175, 18, 3, 121, 219, 50, 248, 175, 17, 191, 77, 248, 175, - 17, 108, 248, 175, 17, 109, 248, 175, 17, 139, 248, 175, 17, 137, 248, - 175, 17, 153, 248, 175, 17, 173, 248, 175, 17, 181, 248, 175, 17, 176, - 248, 175, 17, 184, 248, 175, 1, 207, 181, 4, 82, 236, 249, 248, 175, 1, - 207, 181, 4, 110, 236, 249, 248, 175, 206, 31, 77, 248, 175, 206, 31, 57, - 248, 175, 238, 123, 212, 120, 108, 248, 175, 238, 123, 212, 120, 109, - 248, 175, 238, 123, 212, 120, 139, 248, 175, 238, 123, 212, 120, 137, - 248, 175, 238, 123, 212, 120, 91, 219, 157, 199, 34, 199, 29, 237, 54, - 248, 175, 238, 123, 237, 55, 202, 125, 248, 175, 223, 26, 248, 175, 231, - 170, 77, 248, 175, 1, 195, 147, 251, 20, 248, 175, 252, 16, 57, 248, 175, - 205, 133, 77, 230, 111, 3, 251, 245, 248, 119, 230, 111, 3, 248, 119, - 230, 111, 3, 195, 32, 230, 111, 1, 65, 230, 111, 1, 252, 154, 230, 111, - 1, 70, 230, 111, 1, 223, 170, 230, 111, 1, 69, 230, 111, 1, 196, 26, 230, - 111, 1, 234, 145, 230, 111, 1, 251, 184, 230, 111, 1, 211, 76, 230, 111, - 1, 250, 113, 230, 111, 1, 157, 230, 111, 1, 221, 190, 230, 111, 1, 231, - 203, 230, 111, 1, 231, 54, 230, 111, 1, 214, 54, 230, 111, 1, 247, 112, - 230, 111, 1, 246, 209, 230, 111, 1, 223, 4, 230, 111, 1, 222, 225, 230, - 111, 1, 212, 88, 230, 111, 1, 197, 128, 230, 111, 1, 197, 116, 230, 111, - 1, 237, 146, 230, 111, 1, 237, 130, 230, 111, 1, 213, 66, 230, 111, 1, - 199, 247, 230, 111, 1, 199, 44, 230, 111, 1, 237, 241, 230, 111, 1, 237, - 23, 230, 111, 1, 180, 230, 111, 1, 168, 230, 111, 1, 209, 219, 230, 111, - 1, 249, 103, 230, 111, 1, 248, 153, 230, 111, 1, 172, 230, 111, 1, 169, - 230, 111, 1, 166, 230, 111, 1, 171, 230, 111, 1, 219, 49, 230, 111, 1, - 195, 185, 230, 111, 1, 203, 160, 230, 111, 1, 189, 230, 111, 1, 144, 230, - 111, 3, 212, 128, 230, 111, 18, 3, 252, 154, 230, 111, 18, 3, 70, 230, - 111, 18, 3, 223, 170, 230, 111, 18, 3, 69, 230, 111, 18, 3, 196, 26, 230, - 111, 18, 3, 234, 145, 230, 111, 18, 3, 251, 184, 230, 111, 18, 3, 211, - 76, 230, 111, 18, 3, 250, 113, 230, 111, 3, 195, 37, 230, 111, 3, 196, - 153, 230, 111, 1, 221, 169, 230, 111, 1, 231, 29, 230, 111, 1, 191, 123, - 230, 111, 1, 206, 104, 230, 111, 1, 233, 68, 230, 111, 17, 191, 77, 230, - 111, 17, 108, 230, 111, 17, 109, 230, 111, 17, 139, 230, 111, 17, 137, - 230, 111, 17, 153, 230, 111, 17, 173, 230, 111, 17, 181, 230, 111, 17, - 176, 230, 111, 17, 184, 230, 111, 198, 128, 230, 111, 251, 244, 230, 111, - 223, 47, 230, 111, 196, 54, 230, 111, 234, 105, 211, 81, 230, 111, 3, - 192, 115, 230, 111, 252, 16, 57, 230, 128, 3, 247, 71, 230, 128, 3, 251, - 20, 230, 128, 3, 195, 32, 230, 128, 1, 65, 230, 128, 1, 252, 154, 230, - 128, 1, 70, 230, 128, 1, 223, 170, 230, 128, 1, 69, 230, 128, 1, 196, 26, - 230, 128, 1, 121, 148, 230, 128, 1, 121, 170, 230, 128, 18, 247, 74, 73, - 230, 128, 1, 73, 230, 128, 1, 251, 184, 230, 128, 18, 247, 74, 74, 230, - 128, 1, 74, 230, 128, 1, 250, 113, 230, 128, 1, 157, 230, 128, 1, 221, - 190, 230, 128, 1, 231, 203, 230, 128, 1, 231, 54, 230, 128, 1, 214, 54, - 230, 128, 1, 247, 112, 230, 128, 1, 246, 209, 230, 128, 1, 223, 4, 230, - 128, 1, 222, 225, 230, 128, 1, 212, 88, 230, 128, 1, 197, 128, 230, 128, - 1, 197, 116, 230, 128, 1, 237, 146, 230, 128, 1, 237, 130, 230, 128, 1, - 213, 66, 230, 128, 1, 199, 247, 230, 128, 1, 199, 44, 230, 128, 1, 237, - 241, 230, 128, 1, 237, 23, 230, 128, 1, 180, 230, 128, 1, 168, 230, 128, - 1, 209, 219, 230, 128, 1, 249, 103, 230, 128, 1, 248, 153, 230, 128, 1, - 172, 230, 128, 1, 169, 230, 128, 1, 166, 230, 128, 1, 171, 230, 128, 1, - 219, 49, 230, 128, 1, 195, 185, 230, 128, 1, 203, 160, 230, 128, 1, 201, - 170, 230, 128, 1, 189, 230, 128, 1, 144, 230, 128, 3, 212, 128, 230, 128, - 3, 250, 95, 230, 128, 18, 3, 252, 154, 230, 128, 18, 3, 70, 230, 128, 18, - 3, 223, 170, 230, 128, 18, 3, 69, 230, 128, 18, 3, 196, 26, 230, 128, 18, - 3, 121, 148, 230, 128, 18, 3, 121, 206, 105, 230, 128, 18, 3, 247, 74, - 73, 230, 128, 18, 3, 73, 230, 128, 18, 3, 251, 184, 230, 128, 18, 3, 247, - 74, 74, 230, 128, 18, 3, 74, 230, 128, 18, 3, 250, 113, 230, 128, 3, 195, - 37, 230, 128, 211, 102, 230, 128, 1, 121, 206, 105, 230, 128, 1, 121, - 219, 50, 230, 128, 18, 3, 121, 170, 230, 128, 18, 3, 121, 219, 50, 230, - 128, 17, 191, 77, 230, 128, 17, 108, 230, 128, 17, 109, 230, 128, 17, - 139, 230, 128, 17, 137, 230, 128, 17, 153, 230, 128, 17, 173, 230, 128, - 17, 181, 230, 128, 17, 176, 230, 128, 17, 184, 230, 128, 252, 16, 57, - 230, 128, 206, 31, 57, 230, 128, 1, 191, 71, 230, 128, 3, 200, 201, 230, - 128, 3, 203, 150, 230, 128, 3, 217, 118, 230, 128, 3, 198, 219, 212, 129, - 56, 230, 128, 3, 242, 219, 212, 129, 56, 230, 128, 3, 197, 11, 212, 129, - 56, 211, 35, 3, 247, 71, 211, 35, 3, 251, 20, 211, 35, 3, 195, 32, 211, - 35, 1, 65, 211, 35, 1, 252, 154, 211, 35, 1, 70, 211, 35, 1, 223, 170, - 211, 35, 1, 69, 211, 35, 1, 196, 26, 211, 35, 1, 121, 148, 211, 35, 1, - 121, 170, 211, 35, 1, 73, 211, 35, 1, 251, 184, 211, 35, 1, 74, 211, 35, - 1, 250, 113, 211, 35, 1, 157, 211, 35, 1, 221, 190, 211, 35, 1, 231, 203, - 211, 35, 1, 231, 54, 211, 35, 1, 214, 54, 211, 35, 1, 247, 112, 211, 35, - 1, 246, 209, 211, 35, 1, 223, 4, 211, 35, 1, 222, 225, 211, 35, 1, 212, - 88, 211, 35, 1, 197, 128, 211, 35, 1, 197, 116, 211, 35, 1, 237, 146, - 211, 35, 1, 237, 130, 211, 35, 1, 213, 66, 211, 35, 1, 199, 247, 211, 35, - 1, 199, 44, 211, 35, 1, 237, 241, 211, 35, 1, 237, 23, 211, 35, 1, 180, - 211, 35, 1, 168, 211, 35, 1, 209, 219, 211, 35, 1, 249, 103, 211, 35, 1, - 248, 153, 211, 35, 1, 172, 211, 35, 1, 169, 211, 35, 1, 166, 211, 35, 1, - 171, 211, 35, 1, 219, 49, 211, 35, 1, 195, 185, 211, 35, 1, 203, 160, - 211, 35, 1, 201, 170, 211, 35, 1, 189, 211, 35, 1, 144, 211, 35, 3, 212, - 128, 211, 35, 3, 250, 95, 211, 35, 18, 3, 252, 154, 211, 35, 18, 3, 70, - 211, 35, 18, 3, 223, 170, 211, 35, 18, 3, 69, 211, 35, 18, 3, 196, 26, - 211, 35, 18, 3, 121, 148, 211, 35, 18, 3, 121, 206, 105, 211, 35, 18, 3, - 73, 211, 35, 18, 3, 251, 184, 211, 35, 18, 3, 74, 211, 35, 18, 3, 250, - 113, 211, 35, 3, 195, 37, 211, 35, 3, 210, 244, 211, 35, 251, 185, 219, - 174, 77, 211, 35, 250, 114, 219, 174, 77, 211, 35, 1, 206, 104, 211, 35, - 1, 207, 1, 211, 35, 1, 191, 175, 211, 35, 1, 121, 206, 105, 211, 35, 1, - 121, 219, 50, 211, 35, 18, 3, 121, 170, 211, 35, 18, 3, 121, 219, 50, - 211, 35, 17, 191, 77, 211, 35, 17, 108, 211, 35, 17, 109, 211, 35, 17, - 139, 211, 35, 17, 137, 211, 35, 17, 153, 211, 35, 17, 173, 211, 35, 17, - 181, 211, 35, 17, 176, 211, 35, 17, 184, 211, 35, 223, 26, 211, 35, 1, - 193, 187, 211, 35, 232, 80, 91, 208, 17, 211, 35, 232, 80, 91, 230, 37, - 211, 35, 232, 80, 115, 208, 15, 211, 35, 232, 80, 91, 202, 123, 211, 35, - 232, 80, 91, 234, 116, 211, 35, 232, 80, 115, 202, 120, 44, 3, 251, 20, - 44, 3, 195, 32, 44, 1, 65, 44, 1, 252, 154, 44, 1, 70, 44, 1, 223, 170, - 44, 1, 69, 44, 1, 196, 26, 44, 1, 73, 44, 1, 234, 145, 44, 1, 251, 184, - 44, 1, 74, 44, 1, 211, 76, 44, 1, 250, 113, 44, 1, 157, 44, 1, 214, 54, - 44, 1, 247, 112, 44, 1, 223, 4, 44, 1, 212, 88, 44, 1, 197, 128, 44, 1, - 213, 66, 44, 1, 199, 247, 44, 1, 180, 44, 1, 213, 48, 44, 1, 168, 44, 1, - 172, 44, 1, 169, 44, 1, 166, 44, 1, 206, 104, 44, 1, 171, 44, 1, 219, 49, - 44, 1, 219, 38, 44, 1, 195, 185, 44, 1, 203, 160, 44, 1, 201, 170, 44, 1, - 189, 44, 1, 144, 44, 18, 3, 252, 154, 44, 18, 3, 70, 44, 18, 3, 223, 170, - 44, 18, 3, 69, 44, 18, 3, 196, 26, 44, 18, 3, 73, 44, 18, 3, 234, 145, - 44, 18, 3, 251, 184, 44, 18, 3, 74, 44, 18, 3, 211, 76, 44, 18, 3, 250, - 113, 44, 3, 195, 37, 44, 211, 102, 44, 250, 114, 219, 174, 77, 44, 17, - 191, 77, 44, 17, 108, 44, 17, 109, 44, 17, 139, 44, 17, 137, 44, 17, 153, - 44, 17, 173, 44, 17, 181, 44, 17, 176, 44, 17, 184, 44, 31, 199, 90, 44, - 31, 91, 228, 109, 44, 31, 91, 188, 44, 237, 159, 57, 44, 215, 197, 57, - 44, 192, 78, 57, 44, 237, 97, 57, 44, 238, 183, 57, 44, 250, 170, 95, 57, - 44, 206, 31, 57, 44, 31, 57, 199, 94, 3, 33, 247, 72, 56, 199, 94, 3, - 247, 71, 199, 94, 3, 251, 20, 199, 94, 3, 195, 32, 199, 94, 3, 33, 251, - 21, 56, 199, 94, 1, 65, 199, 94, 1, 252, 154, 199, 94, 1, 70, 199, 94, 1, - 223, 170, 199, 94, 1, 69, 199, 94, 1, 196, 26, 199, 94, 1, 121, 148, 199, - 94, 1, 121, 170, 199, 94, 1, 73, 199, 94, 1, 234, 145, 199, 94, 1, 251, - 184, 199, 94, 1, 74, 199, 94, 1, 211, 76, 199, 94, 1, 250, 113, 199, 94, - 1, 157, 199, 94, 1, 221, 190, 199, 94, 1, 231, 203, 199, 94, 1, 231, 54, - 199, 94, 1, 214, 54, 199, 94, 1, 247, 112, 199, 94, 1, 246, 209, 199, 94, - 1, 223, 4, 199, 94, 1, 222, 225, 199, 94, 1, 212, 88, 199, 94, 1, 197, - 128, 199, 94, 1, 197, 116, 199, 94, 1, 237, 146, 199, 94, 1, 237, 130, - 199, 94, 1, 213, 66, 199, 94, 1, 199, 247, 199, 94, 1, 199, 44, 199, 94, - 1, 237, 241, 199, 94, 1, 237, 23, 199, 94, 1, 180, 199, 94, 1, 168, 199, - 94, 1, 209, 219, 199, 94, 1, 249, 103, 199, 94, 1, 248, 153, 199, 94, 1, - 172, 199, 94, 1, 169, 199, 94, 1, 166, 199, 94, 1, 206, 104, 199, 94, 1, - 171, 199, 94, 1, 219, 49, 199, 94, 1, 219, 38, 199, 94, 1, 195, 185, 199, - 94, 1, 203, 160, 199, 94, 1, 201, 170, 199, 94, 1, 189, 199, 94, 1, 144, - 199, 94, 3, 212, 128, 199, 94, 3, 250, 95, 199, 94, 18, 3, 252, 154, 199, - 94, 18, 3, 70, 199, 94, 18, 3, 223, 170, 199, 94, 18, 3, 69, 199, 94, 18, - 3, 196, 26, 199, 94, 18, 3, 121, 148, 199, 94, 18, 3, 121, 206, 105, 199, - 94, 18, 3, 73, 199, 94, 18, 3, 234, 145, 199, 94, 18, 3, 251, 184, 199, - 94, 18, 3, 74, 199, 94, 18, 3, 211, 76, 199, 94, 18, 3, 250, 113, 199, - 94, 3, 195, 37, 199, 94, 219, 174, 77, 199, 94, 251, 185, 219, 174, 77, - 199, 94, 1, 197, 164, 199, 94, 1, 234, 247, 199, 94, 1, 206, 85, 199, 94, - 1, 214, 218, 209, 39, 199, 94, 1, 121, 206, 105, 199, 94, 1, 121, 219, - 50, 199, 94, 18, 3, 121, 170, 199, 94, 18, 3, 121, 219, 50, 199, 94, 17, - 191, 77, 199, 94, 17, 108, 199, 94, 17, 109, 199, 94, 17, 139, 199, 94, - 17, 137, 199, 94, 17, 153, 199, 94, 17, 173, 199, 94, 17, 181, 199, 94, - 17, 176, 199, 94, 17, 184, 199, 94, 3, 202, 205, 199, 94, 232, 80, 17, - 191, 78, 39, 211, 143, 208, 246, 80, 137, 199, 94, 232, 80, 17, 91, 39, - 211, 143, 208, 246, 80, 137, 199, 94, 232, 80, 17, 103, 39, 211, 143, - 208, 246, 80, 137, 199, 94, 232, 80, 17, 115, 39, 211, 143, 208, 246, 80, - 137, 199, 94, 232, 80, 17, 91, 39, 233, 188, 208, 246, 80, 137, 199, 94, - 232, 80, 17, 103, 39, 233, 188, 208, 246, 80, 137, 199, 94, 232, 80, 17, - 115, 39, 233, 188, 208, 246, 80, 137, 199, 94, 3, 197, 44, 222, 55, 3, - 201, 241, 247, 71, 222, 55, 3, 247, 71, 222, 55, 3, 251, 20, 222, 55, 3, - 195, 32, 222, 55, 3, 202, 205, 222, 55, 1, 65, 222, 55, 1, 252, 154, 222, - 55, 1, 70, 222, 55, 1, 223, 170, 222, 55, 1, 69, 222, 55, 1, 196, 26, - 222, 55, 1, 121, 148, 222, 55, 1, 121, 170, 222, 55, 1, 73, 222, 55, 1, - 234, 145, 222, 55, 1, 251, 184, 222, 55, 1, 74, 222, 55, 1, 211, 76, 222, - 55, 1, 250, 113, 222, 55, 1, 157, 222, 55, 1, 221, 190, 222, 55, 1, 231, - 203, 222, 55, 1, 231, 54, 222, 55, 1, 214, 54, 222, 55, 1, 247, 112, 222, - 55, 1, 246, 209, 222, 55, 1, 223, 4, 222, 55, 1, 222, 225, 222, 55, 1, - 212, 88, 222, 55, 1, 197, 128, 222, 55, 1, 197, 116, 222, 55, 1, 237, - 146, 222, 55, 1, 237, 130, 222, 55, 1, 213, 66, 222, 55, 1, 199, 247, - 222, 55, 1, 199, 44, 222, 55, 1, 237, 241, 222, 55, 1, 237, 23, 222, 55, - 1, 180, 222, 55, 1, 168, 222, 55, 1, 209, 219, 222, 55, 1, 249, 103, 222, - 55, 1, 248, 153, 222, 55, 1, 172, 222, 55, 1, 169, 222, 55, 1, 166, 222, - 55, 1, 206, 104, 222, 55, 1, 171, 222, 55, 1, 219, 49, 222, 55, 1, 195, - 185, 222, 55, 1, 203, 160, 222, 55, 1, 201, 170, 222, 55, 1, 189, 222, - 55, 1, 144, 222, 55, 3, 212, 128, 222, 55, 3, 250, 95, 222, 55, 18, 3, - 252, 154, 222, 55, 18, 3, 70, 222, 55, 18, 3, 223, 170, 222, 55, 18, 3, - 69, 222, 55, 18, 3, 196, 26, 222, 55, 18, 3, 121, 148, 222, 55, 18, 3, - 121, 206, 105, 222, 55, 18, 3, 73, 222, 55, 18, 3, 234, 145, 222, 55, 18, - 3, 251, 184, 222, 55, 18, 3, 74, 222, 55, 18, 3, 211, 76, 222, 55, 18, 3, - 250, 113, 222, 55, 3, 195, 37, 222, 55, 219, 174, 77, 222, 55, 251, 185, - 219, 174, 77, 222, 55, 1, 214, 218, 209, 39, 222, 55, 1, 233, 68, 222, - 55, 1, 121, 206, 105, 222, 55, 1, 121, 219, 50, 222, 55, 18, 3, 121, 170, - 222, 55, 18, 3, 121, 219, 50, 222, 55, 17, 191, 77, 222, 55, 17, 108, - 222, 55, 17, 109, 222, 55, 17, 139, 222, 55, 17, 137, 222, 55, 17, 153, - 222, 55, 17, 173, 222, 55, 17, 181, 222, 55, 17, 176, 222, 55, 17, 184, - 222, 55, 3, 222, 210, 222, 55, 3, 196, 71, 141, 3, 33, 251, 21, 56, 141, - 3, 247, 71, 141, 3, 251, 20, 141, 3, 195, 32, 141, 1, 195, 147, 251, 20, - 141, 1, 65, 141, 1, 252, 154, 141, 1, 70, 141, 1, 223, 170, 141, 1, 69, - 141, 1, 196, 26, 141, 1, 121, 148, 141, 1, 121, 170, 141, 1, 73, 141, 1, - 234, 145, 141, 1, 251, 184, 141, 1, 74, 141, 1, 211, 76, 141, 1, 250, - 113, 141, 1, 157, 141, 1, 221, 190, 141, 1, 231, 203, 141, 1, 231, 54, - 141, 1, 214, 54, 141, 1, 247, 112, 141, 1, 246, 209, 141, 1, 223, 4, 141, - 1, 222, 225, 141, 1, 212, 88, 141, 1, 197, 128, 141, 1, 197, 116, 141, 1, - 237, 146, 141, 1, 237, 130, 141, 1, 213, 66, 141, 1, 199, 247, 141, 1, - 199, 44, 141, 1, 237, 241, 141, 1, 237, 23, 141, 1, 180, 141, 1, 213, 48, - 141, 1, 168, 141, 1, 209, 219, 141, 1, 249, 103, 141, 1, 248, 153, 141, - 1, 172, 141, 1, 169, 141, 1, 166, 141, 1, 206, 104, 141, 1, 171, 141, 1, - 219, 49, 141, 1, 219, 38, 141, 1, 195, 185, 141, 1, 203, 160, 141, 1, - 201, 170, 141, 1, 189, 141, 1, 144, 141, 1, 197, 97, 141, 3, 81, 249, 38, - 195, 37, 141, 3, 242, 212, 195, 37, 141, 3, 250, 95, 141, 18, 3, 252, - 154, 141, 18, 3, 70, 141, 18, 3, 223, 170, 141, 18, 3, 69, 141, 18, 3, - 196, 26, 141, 18, 3, 121, 148, 141, 18, 3, 121, 206, 105, 141, 18, 3, 73, - 141, 18, 3, 234, 145, 141, 18, 3, 251, 184, 141, 18, 3, 74, 141, 18, 3, - 211, 76, 141, 18, 3, 250, 113, 141, 3, 195, 37, 141, 1, 75, 207, 40, 141, - 3, 210, 120, 141, 1, 243, 36, 218, 147, 141, 1, 243, 36, 192, 159, 141, - 1, 243, 36, 219, 39, 141, 250, 114, 219, 174, 77, 141, 232, 80, 91, 211, - 89, 141, 232, 80, 91, 232, 100, 141, 232, 80, 115, 234, 112, 141, 232, - 80, 91, 197, 31, 141, 232, 80, 91, 199, 81, 141, 232, 80, 115, 197, 30, - 141, 232, 80, 91, 232, 233, 141, 1, 250, 220, 223, 170, 141, 1, 121, 206, - 105, 141, 1, 121, 219, 50, 141, 18, 3, 121, 170, 141, 18, 3, 121, 219, - 50, 141, 17, 191, 77, 141, 17, 108, 141, 17, 109, 141, 17, 139, 141, 17, - 137, 141, 17, 153, 141, 17, 173, 141, 17, 181, 141, 17, 176, 141, 17, - 184, 141, 31, 199, 90, 141, 31, 91, 228, 109, 141, 31, 91, 188, 141, 232, - 80, 91, 208, 17, 141, 232, 80, 91, 230, 37, 141, 232, 80, 115, 208, 15, - 141, 232, 80, 91, 202, 123, 141, 232, 80, 91, 234, 116, 141, 232, 80, - 115, 202, 120, 141, 237, 164, 77, 141, 1, 243, 36, 213, 67, 141, 1, 243, - 36, 215, 47, 141, 1, 243, 36, 206, 105, 141, 1, 243, 36, 170, 141, 1, - 243, 36, 219, 50, 141, 1, 243, 36, 222, 125, 165, 3, 247, 71, 165, 3, - 251, 19, 165, 3, 195, 31, 165, 1, 250, 79, 165, 1, 252, 107, 165, 1, 251, - 209, 165, 1, 251, 224, 165, 1, 223, 15, 165, 1, 223, 169, 165, 1, 196, - 16, 165, 1, 196, 20, 165, 1, 223, 42, 165, 1, 223, 43, 165, 1, 223, 154, - 165, 1, 223, 156, 165, 1, 233, 155, 165, 1, 234, 140, 165, 1, 251, 167, - 165, 1, 210, 231, 165, 1, 211, 69, 165, 1, 250, 98, 165, 1, 251, 112, - 222, 2, 165, 1, 217, 98, 222, 2, 165, 1, 251, 112, 231, 148, 165, 1, 217, - 98, 231, 148, 165, 1, 222, 54, 214, 233, 165, 1, 205, 127, 231, 148, 165, - 1, 251, 112, 247, 20, 165, 1, 217, 98, 247, 20, 165, 1, 251, 112, 222, - 241, 165, 1, 217, 98, 222, 241, 165, 1, 199, 236, 214, 233, 165, 1, 199, - 236, 205, 126, 214, 234, 165, 1, 205, 127, 222, 241, 165, 1, 251, 112, - 197, 124, 165, 1, 217, 98, 197, 124, 165, 1, 251, 112, 237, 137, 165, 1, - 217, 98, 237, 137, 165, 1, 215, 78, 214, 183, 165, 1, 205, 127, 237, 137, - 165, 1, 251, 112, 199, 148, 165, 1, 217, 98, 199, 148, 165, 1, 251, 112, - 237, 157, 165, 1, 217, 98, 237, 157, 165, 1, 237, 189, 214, 183, 165, 1, - 205, 127, 237, 157, 165, 1, 251, 112, 210, 61, 165, 1, 217, 98, 210, 61, - 165, 1, 251, 112, 249, 5, 165, 1, 217, 98, 249, 5, 165, 1, 217, 0, 165, - 1, 251, 92, 249, 5, 165, 1, 192, 85, 165, 1, 207, 116, 165, 1, 237, 189, - 219, 223, 165, 1, 195, 153, 165, 1, 199, 236, 205, 97, 165, 1, 215, 78, - 205, 97, 165, 1, 237, 189, 205, 97, 165, 1, 229, 219, 165, 1, 215, 78, - 219, 223, 165, 1, 233, 20, 165, 3, 251, 154, 165, 18, 3, 251, 219, 165, - 18, 3, 221, 215, 251, 226, 165, 18, 3, 236, 222, 251, 226, 165, 18, 3, - 221, 215, 223, 39, 165, 18, 3, 236, 222, 223, 39, 165, 18, 3, 221, 215, - 210, 209, 165, 18, 3, 236, 222, 210, 209, 165, 18, 3, 231, 192, 165, 18, - 3, 221, 22, 165, 18, 3, 236, 222, 221, 22, 165, 18, 3, 221, 24, 237, 75, - 165, 18, 3, 221, 23, 230, 59, 251, 219, 165, 18, 3, 221, 23, 230, 59, - 236, 222, 251, 219, 165, 18, 3, 221, 23, 230, 59, 231, 147, 165, 18, 3, - 231, 147, 165, 219, 62, 17, 191, 77, 165, 219, 62, 17, 108, 165, 219, 62, - 17, 109, 165, 219, 62, 17, 139, 165, 219, 62, 17, 137, 165, 219, 62, 17, - 153, 165, 219, 62, 17, 173, 165, 219, 62, 17, 181, 165, 219, 62, 17, 176, - 165, 219, 62, 17, 184, 165, 18, 3, 236, 222, 231, 192, 165, 18, 3, 236, - 222, 231, 147, 165, 208, 145, 220, 185, 199, 39, 246, 192, 221, 44, 222, - 75, 199, 39, 246, 192, 221, 160, 221, 184, 199, 39, 246, 192, 221, 160, - 221, 150, 199, 39, 246, 192, 221, 160, 221, 145, 199, 39, 246, 192, 221, - 160, 221, 155, 199, 39, 246, 192, 221, 160, 207, 138, 199, 39, 246, 192, - 213, 236, 213, 223, 199, 39, 246, 192, 243, 21, 246, 198, 199, 39, 246, - 192, 243, 21, 243, 31, 199, 39, 246, 192, 243, 21, 246, 197, 199, 39, - 246, 192, 202, 42, 202, 41, 199, 39, 246, 192, 243, 21, 243, 17, 199, 39, - 246, 192, 192, 13, 192, 20, 199, 39, 246, 192, 236, 130, 246, 206, 199, - 39, 246, 192, 118, 210, 77, 199, 39, 246, 192, 198, 237, 199, 33, 199, - 39, 246, 192, 198, 237, 214, 208, 199, 39, 246, 192, 198, 237, 209, 179, - 199, 39, 246, 192, 213, 31, 214, 88, 199, 39, 246, 192, 236, 130, 237, - 76, 199, 39, 246, 192, 118, 199, 179, 199, 39, 246, 192, 198, 237, 198, - 202, 199, 39, 246, 192, 198, 237, 199, 40, 199, 39, 246, 192, 198, 237, - 198, 231, 199, 39, 246, 192, 213, 31, 212, 165, 199, 39, 246, 192, 248, - 64, 249, 68, 199, 39, 246, 192, 209, 66, 209, 102, 199, 39, 246, 192, - 209, 191, 209, 181, 199, 39, 246, 192, 232, 136, 233, 68, 199, 39, 246, - 192, 209, 191, 209, 212, 199, 39, 246, 192, 232, 136, 233, 39, 199, 39, - 246, 192, 209, 191, 205, 141, 199, 39, 246, 192, 215, 252, 172, 199, 39, - 246, 192, 192, 13, 192, 116, 199, 39, 246, 192, 206, 158, 206, 56, 199, - 39, 246, 192, 206, 63, 199, 39, 246, 192, 219, 20, 219, 81, 199, 39, 246, - 192, 218, 203, 199, 39, 246, 192, 193, 49, 193, 172, 199, 39, 246, 192, - 202, 42, 205, 162, 199, 39, 246, 192, 202, 42, 206, 27, 199, 39, 246, - 192, 202, 42, 200, 246, 199, 39, 246, 192, 228, 248, 229, 90, 199, 39, - 246, 192, 219, 20, 242, 255, 199, 39, 246, 192, 186, 251, 71, 199, 39, - 246, 192, 228, 248, 213, 21, 199, 39, 246, 192, 210, 184, 199, 39, 246, - 192, 205, 121, 65, 199, 39, 246, 192, 217, 92, 230, 22, 199, 39, 246, - 192, 205, 121, 252, 154, 199, 39, 246, 192, 205, 121, 251, 98, 199, 39, - 246, 192, 205, 121, 70, 199, 39, 246, 192, 205, 121, 223, 170, 199, 39, - 246, 192, 205, 121, 196, 148, 199, 39, 246, 192, 205, 121, 196, 145, 199, - 39, 246, 192, 205, 121, 69, 199, 39, 246, 192, 205, 121, 196, 26, 199, - 39, 246, 192, 209, 193, 199, 39, 238, 123, 16, 249, 69, 199, 39, 246, - 192, 205, 121, 73, 199, 39, 246, 192, 205, 121, 251, 229, 199, 39, 246, - 192, 205, 121, 74, 199, 39, 246, 192, 205, 121, 251, 185, 217, 86, 199, - 39, 246, 192, 205, 121, 251, 185, 217, 87, 199, 39, 246, 192, 220, 15, - 199, 39, 246, 192, 217, 83, 199, 39, 246, 192, 217, 84, 199, 39, 246, - 192, 217, 92, 234, 104, 199, 39, 246, 192, 217, 92, 198, 236, 199, 39, - 246, 192, 217, 92, 197, 240, 199, 39, 246, 192, 217, 92, 243, 84, 199, - 39, 246, 192, 199, 31, 199, 39, 246, 192, 213, 169, 199, 39, 246, 192, - 192, 110, 199, 39, 246, 192, 232, 125, 199, 39, 17, 191, 77, 199, 39, 17, - 108, 199, 39, 17, 109, 199, 39, 17, 139, 199, 39, 17, 137, 199, 39, 17, - 153, 199, 39, 17, 173, 199, 39, 17, 181, 199, 39, 17, 176, 199, 39, 17, - 184, 199, 39, 246, 192, 251, 66, 199, 39, 246, 192, 221, 156, 219, 249, - 1, 221, 43, 219, 249, 1, 221, 160, 200, 190, 219, 249, 1, 221, 160, 199, - 192, 219, 249, 1, 210, 177, 231, 54, 219, 249, 1, 213, 235, 219, 249, 1, - 242, 51, 219, 249, 1, 210, 177, 246, 209, 219, 249, 1, 202, 42, 199, 192, - 219, 249, 1, 210, 177, 222, 225, 219, 249, 1, 212, 52, 219, 249, 1, 210, - 177, 212, 88, 219, 249, 1, 210, 177, 197, 128, 219, 249, 1, 210, 177, - 197, 116, 219, 249, 1, 210, 177, 237, 146, 219, 249, 1, 210, 177, 237, - 130, 219, 249, 1, 210, 177, 213, 66, 219, 249, 1, 236, 129, 219, 249, 1, - 159, 219, 249, 1, 198, 237, 200, 190, 219, 249, 1, 198, 237, 199, 192, - 219, 249, 1, 210, 177, 237, 23, 219, 249, 1, 213, 30, 219, 249, 1, 248, - 63, 219, 249, 1, 209, 65, 219, 249, 1, 209, 191, 200, 190, 219, 249, 1, - 232, 136, 199, 192, 219, 249, 1, 209, 191, 199, 192, 219, 249, 1, 232, - 136, 200, 190, 219, 249, 1, 210, 177, 248, 153, 219, 249, 1, 215, 251, - 219, 249, 1, 192, 12, 219, 249, 1, 219, 20, 219, 81, 219, 249, 1, 219, - 20, 218, 234, 219, 249, 1, 193, 48, 219, 249, 1, 205, 129, 203, 160, 219, - 249, 1, 205, 129, 201, 170, 219, 249, 1, 202, 42, 200, 190, 219, 249, 1, - 228, 248, 200, 190, 219, 249, 1, 210, 177, 219, 49, 219, 249, 1, 74, 219, - 249, 1, 228, 248, 199, 192, 219, 249, 234, 78, 219, 249, 18, 3, 65, 219, - 249, 18, 3, 217, 92, 222, 61, 219, 249, 18, 3, 252, 154, 219, 249, 18, 3, - 251, 98, 219, 249, 18, 3, 70, 219, 249, 18, 3, 223, 170, 219, 249, 18, 3, - 192, 159, 219, 249, 18, 3, 191, 176, 219, 249, 18, 3, 69, 219, 249, 18, - 3, 196, 26, 219, 249, 3, 210, 177, 195, 37, 219, 249, 18, 3, 217, 92, - 221, 20, 219, 249, 204, 15, 3, 219, 19, 219, 249, 204, 15, 3, 212, 52, - 219, 249, 18, 3, 73, 219, 249, 18, 3, 234, 123, 219, 249, 18, 3, 74, 219, - 249, 18, 3, 250, 81, 219, 249, 18, 3, 251, 184, 219, 249, 221, 44, 171, - 219, 249, 163, 217, 92, 234, 104, 219, 249, 163, 217, 92, 198, 236, 219, - 249, 163, 217, 92, 198, 188, 219, 249, 163, 217, 92, 247, 29, 219, 249, - 247, 77, 77, 219, 249, 213, 178, 219, 249, 17, 191, 77, 219, 249, 17, - 108, 219, 249, 17, 109, 219, 249, 17, 139, 219, 249, 17, 137, 219, 249, - 17, 153, 219, 249, 17, 173, 219, 249, 17, 181, 219, 249, 17, 176, 219, - 249, 17, 184, 219, 249, 228, 248, 213, 30, 219, 249, 228, 248, 215, 251, - 219, 249, 1, 221, 161, 230, 223, 219, 249, 1, 221, 161, 212, 52, 86, 5, - 211, 102, 86, 87, 230, 148, 192, 25, 216, 99, 197, 174, 65, 86, 87, 230, - 148, 192, 25, 216, 99, 255, 155, 206, 162, 248, 225, 172, 86, 87, 230, - 148, 192, 25, 216, 99, 255, 155, 230, 148, 197, 149, 172, 86, 87, 89, - 192, 25, 216, 99, 216, 215, 172, 86, 87, 242, 167, 192, 25, 216, 99, 203, - 167, 172, 86, 87, 247, 49, 192, 25, 216, 99, 209, 180, 203, 153, 172, 86, - 87, 192, 25, 216, 99, 197, 149, 203, 153, 172, 86, 87, 205, 95, 203, 152, - 86, 87, 247, 221, 192, 25, 216, 98, 86, 87, 248, 93, 203, 45, 192, 25, - 216, 98, 86, 87, 223, 70, 197, 148, 86, 87, 237, 68, 197, 149, 247, 220, - 86, 87, 203, 152, 86, 87, 212, 57, 203, 152, 86, 87, 197, 149, 203, 152, - 86, 87, 212, 57, 197, 149, 203, 152, 86, 87, 206, 186, 243, 63, 201, 188, - 203, 152, 86, 87, 207, 5, 230, 188, 203, 152, 86, 87, 247, 49, 255, 159, - 206, 68, 216, 214, 177, 247, 80, 86, 87, 230, 148, 197, 148, 86, 219, 3, - 3, 246, 207, 206, 67, 86, 219, 3, 3, 219, 133, 206, 67, 86, 250, 138, 3, - 203, 163, 231, 131, 255, 160, 206, 67, 86, 250, 138, 3, 255, 157, 168, - 86, 250, 138, 3, 205, 64, 197, 143, 86, 3, 207, 110, 236, 144, 231, 130, - 86, 3, 207, 110, 236, 144, 230, 225, 86, 3, 207, 110, 236, 144, 230, 149, - 86, 3, 207, 110, 214, 229, 231, 130, 86, 3, 207, 110, 214, 229, 230, 225, - 86, 3, 207, 110, 236, 144, 207, 110, 214, 228, 86, 17, 191, 77, 86, 17, - 108, 86, 17, 109, 86, 17, 139, 86, 17, 137, 86, 17, 153, 86, 17, 173, 86, - 17, 181, 86, 17, 176, 86, 17, 184, 86, 17, 134, 108, 86, 17, 134, 109, - 86, 17, 134, 139, 86, 17, 134, 137, 86, 17, 134, 153, 86, 17, 134, 173, - 86, 17, 134, 181, 86, 17, 134, 176, 86, 17, 134, 184, 86, 17, 134, 191, - 77, 86, 87, 247, 223, 206, 67, 86, 87, 214, 45, 247, 147, 212, 69, 191, - 10, 86, 87, 247, 49, 255, 159, 206, 68, 247, 148, 216, 44, 247, 80, 86, - 87, 214, 45, 247, 147, 203, 164, 206, 67, 86, 87, 243, 80, 216, 98, 86, - 87, 197, 165, 255, 156, 86, 87, 230, 131, 206, 68, 230, 86, 86, 87, 230, - 131, 206, 68, 230, 92, 86, 87, 251, 72, 221, 178, 230, 86, 86, 87, 251, - 72, 221, 178, 230, 92, 86, 3, 192, 102, 197, 147, 86, 3, 217, 46, 197, - 147, 86, 1, 157, 86, 1, 221, 190, 86, 1, 231, 203, 86, 1, 231, 54, 86, 1, - 214, 54, 86, 1, 247, 112, 86, 1, 246, 209, 86, 1, 223, 4, 86, 1, 212, 88, - 86, 1, 197, 128, 86, 1, 197, 116, 86, 1, 237, 146, 86, 1, 237, 130, 86, - 1, 213, 66, 86, 1, 199, 247, 86, 1, 199, 44, 86, 1, 237, 241, 86, 1, 237, - 23, 86, 1, 180, 86, 1, 168, 86, 1, 209, 219, 86, 1, 249, 103, 86, 1, 248, - 153, 86, 1, 172, 86, 1, 197, 164, 86, 1, 197, 153, 86, 1, 234, 247, 86, - 1, 234, 241, 86, 1, 193, 187, 86, 1, 191, 71, 86, 1, 191, 123, 86, 1, - 255, 162, 86, 1, 169, 86, 1, 166, 86, 1, 171, 86, 1, 203, 160, 86, 1, - 201, 170, 86, 1, 189, 86, 1, 144, 86, 1, 65, 86, 1, 220, 222, 86, 1, 232, - 181, 166, 86, 1, 221, 77, 86, 1, 206, 104, 86, 18, 3, 252, 154, 86, 18, - 3, 70, 86, 18, 3, 223, 170, 86, 18, 3, 69, 86, 18, 3, 196, 26, 86, 18, 3, - 121, 148, 86, 18, 3, 121, 206, 105, 86, 18, 3, 121, 170, 86, 18, 3, 121, - 219, 50, 86, 18, 3, 73, 86, 18, 3, 234, 145, 86, 18, 3, 74, 86, 18, 3, - 211, 76, 86, 3, 206, 168, 201, 0, 214, 55, 206, 157, 86, 3, 206, 162, - 248, 224, 86, 18, 3, 207, 13, 70, 86, 18, 3, 207, 13, 223, 170, 86, 3, - 212, 69, 191, 11, 214, 237, 237, 241, 86, 3, 202, 56, 219, 216, 86, 87, - 230, 39, 86, 87, 210, 168, 86, 3, 219, 219, 206, 67, 86, 3, 192, 107, - 206, 67, 86, 3, 219, 220, 197, 165, 247, 80, 86, 3, 216, 217, 247, 80, - 86, 3, 230, 152, 247, 81, 207, 3, 86, 3, 230, 152, 216, 201, 207, 3, 86, - 3, 223, 65, 216, 217, 247, 80, 86, 200, 234, 3, 219, 220, 197, 165, 247, - 80, 86, 200, 234, 3, 216, 217, 247, 80, 86, 200, 234, 3, 223, 65, 216, - 217, 247, 80, 86, 200, 234, 1, 157, 86, 200, 234, 1, 221, 190, 86, 200, - 234, 1, 231, 203, 86, 200, 234, 1, 231, 54, 86, 200, 234, 1, 214, 54, 86, - 200, 234, 1, 247, 112, 86, 200, 234, 1, 246, 209, 86, 200, 234, 1, 223, - 4, 86, 200, 234, 1, 212, 88, 86, 200, 234, 1, 197, 128, 86, 200, 234, 1, - 197, 116, 86, 200, 234, 1, 237, 146, 86, 200, 234, 1, 237, 130, 86, 200, - 234, 1, 213, 66, 86, 200, 234, 1, 199, 247, 86, 200, 234, 1, 199, 44, 86, - 200, 234, 1, 237, 241, 86, 200, 234, 1, 237, 23, 86, 200, 234, 1, 180, - 86, 200, 234, 1, 168, 86, 200, 234, 1, 209, 219, 86, 200, 234, 1, 249, - 103, 86, 200, 234, 1, 248, 153, 86, 200, 234, 1, 172, 86, 200, 234, 1, - 197, 164, 86, 200, 234, 1, 197, 153, 86, 200, 234, 1, 234, 247, 86, 200, - 234, 1, 234, 241, 86, 200, 234, 1, 193, 187, 86, 200, 234, 1, 191, 71, - 86, 200, 234, 1, 191, 123, 86, 200, 234, 1, 255, 162, 86, 200, 234, 1, - 169, 86, 200, 234, 1, 166, 86, 200, 234, 1, 171, 86, 200, 234, 1, 203, - 160, 86, 200, 234, 1, 201, 170, 86, 200, 234, 1, 189, 86, 200, 234, 1, - 144, 86, 200, 234, 1, 65, 86, 200, 234, 1, 220, 222, 86, 200, 234, 1, - 232, 181, 193, 187, 86, 200, 234, 1, 232, 181, 169, 86, 200, 234, 1, 232, - 181, 166, 86, 220, 209, 206, 64, 221, 190, 86, 220, 209, 206, 64, 221, - 191, 247, 148, 216, 44, 247, 80, 86, 247, 64, 3, 88, 248, 213, 86, 247, - 64, 3, 155, 248, 213, 86, 247, 64, 3, 247, 68, 199, 130, 86, 247, 64, 3, - 205, 94, 255, 161, 86, 16, 235, 61, 247, 218, 86, 16, 207, 109, 206, 169, - 86, 16, 210, 196, 231, 129, 86, 16, 207, 109, 206, 170, 207, 5, 230, 187, - 86, 16, 209, 180, 168, 86, 16, 213, 8, 247, 218, 86, 16, 213, 8, 247, - 219, 212, 57, 255, 158, 86, 16, 213, 8, 247, 219, 230, 150, 255, 158, 86, - 16, 213, 8, 247, 219, 247, 148, 255, 158, 86, 3, 207, 110, 214, 229, 207, - 110, 236, 143, 86, 3, 207, 110, 214, 229, 230, 149, 86, 87, 247, 222, - 203, 45, 231, 17, 216, 99, 207, 4, 86, 87, 215, 253, 192, 25, 231, 17, - 216, 99, 207, 4, 86, 87, 212, 57, 197, 148, 86, 87, 89, 247, 252, 206, - 159, 192, 25, 216, 99, 216, 215, 172, 86, 87, 242, 167, 247, 252, 206, - 159, 192, 25, 216, 99, 203, 167, 172, 206, 202, 200, 151, 57, 219, 199, - 200, 151, 57, 206, 202, 200, 151, 3, 4, 236, 94, 219, 199, 200, 151, 3, - 4, 236, 94, 86, 87, 219, 211, 216, 218, 206, 67, 86, 87, 198, 14, 216, - 218, 206, 67, 79, 1, 157, 79, 1, 221, 190, 79, 1, 231, 203, 79, 1, 231, - 54, 79, 1, 214, 54, 79, 1, 247, 112, 79, 1, 246, 209, 79, 1, 223, 4, 79, - 1, 222, 225, 79, 1, 212, 88, 79, 1, 213, 32, 79, 1, 197, 128, 79, 1, 197, - 116, 79, 1, 237, 146, 79, 1, 237, 130, 79, 1, 213, 66, 79, 1, 199, 247, - 79, 1, 199, 44, 79, 1, 237, 241, 79, 1, 237, 23, 79, 1, 180, 79, 1, 168, - 79, 1, 209, 219, 79, 1, 249, 103, 79, 1, 248, 153, 79, 1, 172, 79, 1, - 169, 79, 1, 166, 79, 1, 171, 79, 1, 193, 187, 79, 1, 189, 79, 1, 144, 79, - 1, 219, 49, 79, 1, 65, 79, 1, 203, 134, 65, 79, 1, 70, 79, 1, 223, 170, - 79, 1, 69, 79, 1, 196, 26, 79, 1, 73, 79, 1, 215, 215, 73, 79, 1, 74, 79, - 1, 250, 113, 79, 18, 3, 199, 195, 252, 154, 79, 18, 3, 252, 154, 79, 18, - 3, 70, 79, 18, 3, 223, 170, 79, 18, 3, 69, 79, 18, 3, 196, 26, 79, 18, 3, - 73, 79, 18, 3, 251, 184, 79, 18, 3, 215, 215, 223, 170, 79, 18, 3, 215, - 215, 74, 79, 18, 3, 234, 227, 56, 79, 3, 251, 20, 79, 3, 75, 60, 79, 3, - 195, 32, 79, 3, 195, 37, 79, 3, 250, 164, 79, 119, 3, 216, 198, 169, 79, - 119, 3, 216, 198, 166, 79, 119, 3, 216, 198, 193, 187, 79, 119, 3, 216, - 198, 144, 79, 1, 230, 172, 189, 79, 17, 191, 77, 79, 17, 108, 79, 17, - 109, 79, 17, 139, 79, 17, 137, 79, 17, 153, 79, 17, 173, 79, 17, 181, 79, - 17, 176, 79, 17, 184, 79, 3, 219, 59, 205, 48, 79, 3, 205, 48, 79, 16, - 219, 12, 79, 16, 242, 19, 79, 16, 251, 205, 79, 16, 231, 109, 79, 1, 203, - 160, 79, 1, 201, 170, 79, 1, 121, 148, 79, 1, 121, 206, 105, 79, 1, 121, - 170, 79, 1, 121, 219, 50, 79, 18, 3, 121, 148, 79, 18, 3, 121, 206, 105, - 79, 18, 3, 121, 170, 79, 18, 3, 121, 219, 50, 79, 1, 215, 215, 214, 54, - 79, 1, 215, 215, 222, 225, 79, 1, 215, 215, 249, 3, 79, 1, 215, 215, 248, - 254, 79, 119, 3, 215, 215, 216, 198, 180, 79, 119, 3, 215, 215, 216, 198, - 172, 79, 119, 3, 215, 215, 216, 198, 171, 79, 1, 203, 166, 222, 36, 203, - 160, 79, 18, 3, 203, 166, 222, 36, 233, 201, 79, 163, 87, 203, 166, 222, - 36, 229, 228, 79, 163, 87, 203, 166, 222, 36, 221, 254, 209, 190, 79, 1, - 193, 100, 208, 109, 222, 36, 199, 44, 79, 1, 193, 100, 208, 109, 222, 36, - 208, 115, 79, 18, 3, 193, 100, 208, 109, 222, 36, 233, 201, 79, 18, 3, - 193, 100, 208, 109, 222, 36, 196, 148, 79, 3, 193, 100, 208, 109, 222, - 36, 198, 73, 79, 3, 193, 100, 208, 109, 222, 36, 198, 72, 79, 3, 193, - 100, 208, 109, 222, 36, 198, 71, 79, 3, 193, 100, 208, 109, 222, 36, 198, - 70, 79, 3, 193, 100, 208, 109, 222, 36, 198, 69, 79, 1, 234, 158, 208, - 109, 222, 36, 213, 66, 79, 1, 234, 158, 208, 109, 222, 36, 191, 183, 79, - 1, 234, 158, 208, 109, 222, 36, 231, 19, 79, 18, 3, 231, 124, 222, 36, - 70, 79, 18, 3, 222, 3, 211, 139, 79, 18, 3, 222, 3, 69, 79, 18, 3, 222, - 3, 234, 145, 79, 1, 203, 134, 157, 79, 1, 203, 134, 221, 190, 79, 1, 203, - 134, 231, 203, 79, 1, 203, 134, 247, 112, 79, 1, 203, 134, 191, 123, 79, - 1, 203, 134, 212, 88, 79, 1, 203, 134, 237, 241, 79, 1, 203, 134, 180, - 79, 1, 203, 134, 209, 219, 79, 1, 203, 134, 233, 68, 79, 1, 203, 134, - 249, 103, 79, 1, 203, 134, 199, 44, 79, 1, 203, 134, 144, 79, 119, 3, - 203, 134, 216, 198, 193, 187, 79, 18, 3, 203, 134, 252, 154, 79, 18, 3, - 203, 134, 73, 79, 18, 3, 203, 134, 234, 227, 56, 79, 18, 3, 203, 134, 52, - 192, 159, 79, 3, 203, 134, 198, 72, 79, 3, 203, 134, 198, 71, 79, 3, 203, - 134, 198, 69, 79, 3, 203, 134, 198, 68, 79, 3, 203, 134, 238, 200, 198, - 72, 79, 3, 203, 134, 238, 200, 198, 71, 79, 3, 203, 134, 238, 200, 234, - 64, 198, 74, 79, 1, 206, 42, 210, 179, 233, 68, 79, 3, 206, 42, 210, 179, - 198, 69, 79, 203, 134, 17, 191, 77, 79, 203, 134, 17, 108, 79, 203, 134, - 17, 109, 79, 203, 134, 17, 139, 79, 203, 134, 17, 137, 79, 203, 134, 17, - 153, 79, 203, 134, 17, 173, 79, 203, 134, 17, 181, 79, 203, 134, 17, 176, - 79, 203, 134, 17, 184, 79, 3, 221, 181, 198, 73, 79, 3, 221, 181, 198, - 71, 79, 18, 3, 251, 170, 65, 79, 18, 3, 251, 170, 251, 184, 79, 16, 203, - 134, 108, 79, 16, 203, 134, 233, 174, 100, 6, 1, 251, 81, 100, 6, 1, 249, - 51, 100, 6, 1, 231, 173, 100, 6, 1, 236, 105, 100, 6, 1, 234, 61, 100, 6, - 1, 195, 46, 100, 6, 1, 191, 80, 100, 6, 1, 199, 188, 100, 6, 1, 223, 134, - 100, 6, 1, 222, 61, 100, 6, 1, 219, 239, 100, 6, 1, 217, 70, 100, 6, 1, - 214, 202, 100, 6, 1, 211, 93, 100, 6, 1, 210, 121, 100, 6, 1, 191, 67, - 100, 6, 1, 207, 158, 100, 6, 1, 205, 137, 100, 6, 1, 199, 174, 100, 6, 1, - 196, 109, 100, 6, 1, 209, 211, 100, 6, 1, 221, 176, 100, 6, 1, 231, 45, - 100, 6, 1, 208, 74, 100, 6, 1, 203, 64, 100, 6, 1, 243, 33, 100, 6, 1, - 247, 80, 100, 6, 1, 222, 207, 100, 6, 1, 242, 226, 100, 6, 1, 246, 193, - 100, 6, 1, 192, 218, 100, 6, 1, 222, 222, 100, 6, 1, 230, 54, 100, 6, 1, - 229, 213, 100, 6, 1, 229, 113, 100, 6, 1, 193, 123, 100, 6, 1, 229, 242, - 100, 6, 1, 228, 235, 100, 6, 1, 192, 14, 100, 6, 1, 251, 218, 100, 1, - 251, 81, 100, 1, 249, 51, 100, 1, 231, 173, 100, 1, 236, 105, 100, 1, - 234, 61, 100, 1, 195, 46, 100, 1, 191, 80, 100, 1, 199, 188, 100, 1, 223, - 134, 100, 1, 222, 61, 100, 1, 219, 239, 100, 1, 217, 70, 100, 1, 214, - 202, 100, 1, 211, 93, 100, 1, 210, 121, 100, 1, 191, 67, 100, 1, 207, - 158, 100, 1, 205, 137, 100, 1, 199, 174, 100, 1, 196, 109, 100, 1, 209, - 211, 100, 1, 221, 176, 100, 1, 231, 45, 100, 1, 208, 74, 100, 1, 203, 64, - 100, 1, 243, 33, 100, 1, 247, 80, 100, 1, 222, 207, 100, 1, 242, 226, - 100, 1, 246, 193, 100, 1, 192, 218, 100, 1, 222, 222, 100, 1, 230, 54, - 100, 1, 229, 213, 100, 1, 229, 113, 100, 1, 193, 123, 100, 1, 229, 242, - 100, 1, 228, 235, 100, 1, 232, 238, 100, 1, 192, 14, 100, 1, 234, 80, - 100, 1, 152, 231, 173, 100, 1, 251, 178, 100, 210, 118, 204, 5, 59, 1, - 100, 214, 202, 100, 1, 251, 218, 100, 1, 229, 240, 57, 100, 1, 220, 92, - 57, 30, 146, 221, 89, 30, 146, 201, 162, 30, 146, 213, 190, 30, 146, 198, - 163, 30, 146, 201, 151, 30, 146, 206, 234, 30, 146, 216, 59, 30, 146, - 209, 160, 30, 146, 201, 159, 30, 146, 202, 155, 30, 146, 201, 156, 30, - 146, 223, 193, 30, 146, 242, 232, 30, 146, 201, 166, 30, 146, 243, 43, - 30, 146, 221, 164, 30, 146, 199, 2, 30, 146, 209, 200, 30, 146, 229, 110, - 30, 146, 213, 186, 30, 146, 201, 160, 30, 146, 213, 180, 30, 146, 213, - 184, 30, 146, 198, 160, 30, 146, 206, 222, 30, 146, 201, 158, 30, 146, - 206, 232, 30, 146, 222, 42, 30, 146, 216, 52, 30, 146, 222, 45, 30, 146, - 209, 155, 30, 146, 209, 153, 30, 146, 209, 141, 30, 146, 209, 149, 30, - 146, 209, 147, 30, 146, 209, 144, 30, 146, 209, 146, 30, 146, 209, 143, - 30, 146, 209, 148, 30, 146, 209, 158, 30, 146, 209, 159, 30, 146, 209, - 142, 30, 146, 209, 152, 30, 146, 222, 43, 30, 146, 222, 41, 30, 146, 202, - 148, 30, 146, 202, 146, 30, 146, 202, 138, 30, 146, 202, 141, 30, 146, - 202, 147, 30, 146, 202, 143, 30, 146, 202, 142, 30, 146, 202, 140, 30, - 146, 202, 151, 30, 146, 202, 153, 30, 146, 202, 154, 30, 146, 202, 149, - 30, 146, 202, 139, 30, 146, 202, 144, 30, 146, 202, 152, 30, 146, 243, - 24, 30, 146, 243, 22, 30, 146, 246, 222, 30, 146, 246, 220, 30, 146, 210, - 139, 30, 146, 223, 188, 30, 146, 223, 179, 30, 146, 223, 187, 30, 146, - 223, 184, 30, 146, 223, 182, 30, 146, 223, 186, 30, 146, 201, 163, 30, - 146, 223, 191, 30, 146, 223, 192, 30, 146, 223, 180, 30, 146, 223, 185, - 30, 146, 192, 57, 30, 146, 242, 231, 30, 146, 243, 25, 30, 146, 243, 23, - 30, 146, 246, 223, 30, 146, 246, 221, 30, 146, 243, 41, 30, 146, 243, 42, - 30, 146, 243, 26, 30, 146, 246, 224, 30, 146, 209, 198, 30, 146, 222, 44, - 30, 146, 201, 164, 30, 146, 192, 63, 30, 146, 221, 80, 30, 146, 213, 182, - 30, 146, 213, 188, 30, 146, 213, 187, 30, 146, 198, 157, 30, 146, 232, - 218, 30, 222, 147, 232, 218, 30, 222, 147, 65, 30, 222, 147, 251, 229, - 30, 222, 147, 169, 30, 222, 147, 192, 129, 30, 222, 147, 234, 23, 30, - 222, 147, 73, 30, 222, 147, 192, 67, 30, 222, 147, 192, 80, 30, 222, 147, - 74, 30, 222, 147, 193, 187, 30, 222, 147, 193, 173, 30, 222, 147, 211, - 139, 30, 222, 147, 192, 12, 30, 222, 147, 69, 30, 222, 147, 193, 105, 30, - 222, 147, 193, 123, 30, 222, 147, 193, 84, 30, 222, 147, 191, 225, 30, - 222, 147, 233, 201, 30, 222, 147, 192, 33, 30, 222, 147, 70, 30, 222, - 147, 255, 150, 30, 222, 147, 255, 149, 30, 222, 147, 192, 143, 30, 222, - 147, 192, 141, 30, 222, 147, 234, 21, 30, 222, 147, 234, 20, 30, 222, - 147, 234, 22, 30, 222, 147, 192, 66, 30, 222, 147, 192, 65, 30, 222, 147, - 211, 253, 30, 222, 147, 211, 254, 30, 222, 147, 211, 247, 30, 222, 147, - 211, 252, 30, 222, 147, 211, 250, 30, 222, 147, 192, 0, 30, 222, 147, - 191, 255, 30, 222, 147, 191, 254, 30, 222, 147, 192, 1, 30, 222, 147, - 192, 2, 30, 222, 147, 196, 222, 30, 222, 147, 196, 221, 30, 222, 147, - 196, 219, 30, 222, 147, 196, 215, 30, 222, 147, 196, 216, 30, 222, 147, - 191, 220, 30, 222, 147, 191, 217, 30, 222, 147, 191, 218, 30, 222, 147, - 191, 212, 30, 222, 147, 191, 213, 30, 222, 147, 191, 214, 30, 222, 147, - 191, 216, 30, 222, 147, 233, 195, 30, 222, 147, 233, 197, 30, 222, 147, - 192, 32, 30, 222, 147, 228, 39, 30, 222, 147, 228, 31, 30, 222, 147, 228, - 34, 30, 222, 147, 228, 32, 30, 222, 147, 228, 36, 30, 222, 147, 228, 38, - 30, 222, 147, 250, 231, 30, 222, 147, 250, 228, 30, 222, 147, 250, 226, - 30, 222, 147, 250, 227, 30, 222, 147, 201, 167, 30, 222, 147, 255, 151, - 30, 222, 147, 192, 142, 30, 222, 147, 192, 64, 30, 222, 147, 211, 249, - 30, 222, 147, 211, 248, 30, 125, 221, 89, 30, 125, 201, 162, 30, 125, - 221, 82, 30, 125, 213, 190, 30, 125, 213, 188, 30, 125, 213, 187, 30, - 125, 198, 163, 30, 125, 206, 234, 30, 125, 206, 229, 30, 125, 206, 226, - 30, 125, 206, 219, 30, 125, 206, 214, 30, 125, 206, 209, 30, 125, 206, - 220, 30, 125, 206, 232, 30, 125, 216, 59, 30, 125, 209, 160, 30, 125, - 209, 149, 30, 125, 202, 155, 30, 125, 201, 156, 30, 125, 223, 193, 30, - 125, 242, 232, 30, 125, 243, 43, 30, 125, 221, 164, 30, 125, 199, 2, 30, - 125, 209, 200, 30, 125, 229, 110, 30, 125, 221, 83, 30, 125, 221, 81, 30, - 125, 213, 186, 30, 125, 213, 180, 30, 125, 213, 182, 30, 125, 213, 185, - 30, 125, 213, 181, 30, 125, 198, 160, 30, 125, 198, 157, 30, 125, 206, - 227, 30, 125, 206, 222, 30, 125, 206, 208, 30, 125, 206, 207, 30, 125, - 201, 158, 30, 125, 206, 224, 30, 125, 206, 223, 30, 125, 206, 216, 30, - 125, 206, 218, 30, 125, 206, 231, 30, 125, 206, 211, 30, 125, 206, 221, - 30, 125, 206, 230, 30, 125, 206, 206, 30, 125, 216, 55, 30, 125, 216, 50, - 30, 125, 216, 52, 30, 125, 216, 49, 30, 125, 216, 47, 30, 125, 216, 53, - 30, 125, 216, 58, 30, 125, 216, 56, 30, 125, 222, 45, 30, 125, 209, 151, - 30, 125, 209, 152, 30, 125, 209, 157, 30, 125, 222, 43, 30, 125, 202, - 148, 30, 125, 202, 138, 30, 125, 202, 141, 30, 125, 202, 143, 30, 125, - 210, 139, 30, 125, 223, 188, 30, 125, 223, 181, 30, 125, 201, 163, 30, - 125, 223, 189, 30, 125, 192, 57, 30, 125, 192, 51, 30, 125, 192, 52, 30, - 125, 209, 198, 30, 125, 222, 44, 30, 125, 229, 108, 30, 125, 229, 106, - 30, 125, 229, 109, 30, 125, 229, 107, 30, 125, 192, 63, 30, 125, 221, 85, - 30, 125, 221, 84, 30, 125, 221, 88, 30, 125, 221, 86, 30, 125, 221, 87, - 30, 125, 201, 160, 36, 5, 144, 36, 5, 228, 128, 36, 5, 229, 126, 36, 5, - 230, 58, 36, 5, 229, 183, 36, 5, 229, 213, 36, 5, 228, 247, 36, 5, 228, - 238, 36, 5, 171, 36, 5, 218, 203, 36, 5, 219, 122, 36, 5, 220, 101, 36, - 5, 219, 204, 36, 5, 219, 214, 36, 5, 219, 19, 36, 5, 218, 170, 36, 5, - 229, 145, 36, 5, 229, 139, 36, 5, 229, 141, 36, 5, 229, 144, 36, 5, 229, - 142, 36, 5, 229, 143, 36, 5, 229, 140, 36, 5, 229, 138, 36, 5, 172, 36, - 5, 215, 139, 36, 5, 216, 81, 36, 5, 217, 130, 36, 5, 216, 192, 36, 5, - 216, 213, 36, 5, 215, 251, 36, 5, 215, 66, 36, 5, 200, 50, 36, 5, 200, - 44, 36, 5, 200, 46, 36, 5, 200, 49, 36, 5, 200, 47, 36, 5, 200, 48, 36, - 5, 200, 45, 36, 5, 200, 43, 36, 5, 166, 36, 5, 206, 63, 36, 5, 206, 252, - 36, 5, 207, 173, 36, 5, 207, 79, 36, 5, 207, 108, 36, 5, 206, 157, 36, 5, - 206, 21, 36, 5, 189, 36, 5, 200, 255, 36, 5, 202, 217, 36, 5, 205, 192, - 36, 5, 205, 45, 36, 5, 205, 63, 36, 5, 202, 41, 36, 5, 200, 146, 36, 5, - 203, 160, 36, 5, 203, 0, 36, 5, 203, 76, 36, 5, 203, 155, 36, 5, 203, - 106, 36, 5, 203, 108, 36, 5, 203, 51, 36, 5, 202, 235, 36, 5, 208, 89, - 36, 5, 208, 27, 36, 5, 208, 51, 36, 5, 208, 88, 36, 5, 208, 68, 36, 5, - 208, 69, 36, 5, 208, 39, 36, 5, 208, 38, 36, 5, 207, 235, 36, 5, 207, - 231, 36, 5, 207, 234, 36, 5, 207, 232, 36, 5, 207, 233, 36, 5, 208, 65, - 36, 5, 208, 57, 36, 5, 208, 60, 36, 5, 208, 64, 36, 5, 208, 61, 36, 5, - 208, 62, 36, 5, 208, 59, 36, 5, 208, 56, 36, 5, 208, 52, 36, 5, 208, 55, - 36, 5, 208, 53, 36, 5, 208, 54, 36, 5, 249, 103, 36, 5, 247, 218, 36, 5, - 248, 140, 36, 5, 249, 101, 36, 5, 248, 207, 36, 5, 248, 223, 36, 5, 248, - 63, 36, 5, 247, 162, 36, 5, 195, 185, 36, 5, 193, 246, 36, 5, 195, 66, - 36, 5, 195, 184, 36, 5, 195, 145, 36, 5, 195, 150, 36, 5, 195, 21, 36, 5, - 193, 235, 36, 5, 199, 247, 36, 5, 197, 90, 36, 5, 198, 188, 36, 5, 199, - 240, 36, 5, 199, 116, 36, 5, 199, 140, 36, 5, 159, 36, 5, 197, 39, 36, 5, - 247, 112, 36, 5, 238, 148, 36, 5, 242, 237, 36, 5, 247, 111, 36, 5, 246, - 242, 36, 5, 246, 250, 36, 5, 242, 51, 36, 5, 238, 104, 36, 5, 192, 220, - 36, 5, 192, 188, 36, 5, 192, 207, 36, 5, 192, 219, 36, 5, 192, 213, 36, - 5, 192, 214, 36, 5, 192, 196, 36, 5, 192, 195, 36, 5, 192, 181, 36, 5, - 192, 177, 36, 5, 192, 180, 36, 5, 192, 178, 36, 5, 192, 179, 36, 5, 180, - 36, 5, 212, 165, 36, 5, 213, 205, 36, 5, 214, 236, 36, 5, 214, 96, 36, 5, - 214, 107, 36, 5, 213, 30, 36, 5, 212, 97, 36, 5, 212, 88, 36, 5, 212, 45, - 36, 5, 212, 68, 36, 5, 212, 87, 36, 5, 212, 76, 36, 5, 212, 77, 36, 5, - 212, 52, 36, 5, 212, 35, 36, 5, 230, 231, 65, 36, 5, 230, 231, 69, 36, 5, - 230, 231, 70, 36, 5, 230, 231, 252, 154, 36, 5, 230, 231, 234, 145, 36, - 5, 230, 231, 73, 36, 5, 230, 231, 74, 36, 5, 230, 231, 193, 187, 36, 5, - 157, 36, 5, 220, 208, 36, 5, 221, 142, 36, 5, 222, 100, 36, 5, 221, 244, - 36, 5, 221, 253, 36, 5, 221, 43, 36, 5, 221, 38, 36, 5, 220, 155, 36, 5, - 220, 148, 36, 5, 220, 154, 36, 5, 220, 149, 36, 5, 220, 150, 36, 5, 220, - 141, 36, 5, 220, 135, 36, 5, 220, 137, 36, 5, 220, 140, 36, 5, 220, 138, - 36, 5, 220, 139, 36, 5, 220, 136, 36, 5, 220, 134, 36, 5, 220, 130, 36, - 5, 220, 133, 36, 5, 220, 131, 36, 5, 220, 132, 36, 5, 193, 187, 36, 5, - 193, 0, 36, 5, 193, 84, 36, 5, 193, 178, 36, 5, 193, 112, 36, 5, 193, - 123, 36, 5, 193, 48, 36, 5, 193, 40, 36, 5, 209, 210, 65, 36, 5, 209, - 210, 69, 36, 5, 209, 210, 70, 36, 5, 209, 210, 252, 154, 36, 5, 209, 210, - 234, 145, 36, 5, 209, 210, 73, 36, 5, 209, 210, 74, 36, 5, 191, 123, 36, - 5, 190, 251, 36, 5, 191, 30, 36, 5, 191, 121, 36, 5, 191, 84, 36, 5, 191, - 87, 36, 5, 191, 7, 36, 5, 190, 238, 36, 5, 191, 71, 36, 5, 191, 48, 36, - 5, 191, 57, 36, 5, 191, 70, 36, 5, 191, 61, 36, 5, 191, 62, 36, 5, 191, - 54, 36, 5, 191, 39, 36, 5, 169, 36, 5, 191, 225, 36, 5, 192, 33, 36, 5, - 192, 140, 36, 5, 192, 77, 36, 5, 192, 80, 36, 5, 192, 12, 36, 5, 191, - 252, 36, 5, 237, 241, 36, 5, 235, 45, 36, 5, 236, 255, 36, 5, 237, 240, - 36, 5, 237, 86, 36, 5, 237, 101, 36, 5, 236, 129, 36, 5, 235, 2, 36, 5, - 237, 146, 36, 5, 237, 111, 36, 5, 237, 123, 36, 5, 237, 145, 36, 5, 237, - 133, 36, 5, 237, 134, 36, 5, 237, 116, 36, 5, 237, 102, 36, 5, 223, 4, - 36, 5, 222, 155, 36, 5, 222, 217, 36, 5, 223, 3, 36, 5, 222, 236, 36, 5, - 222, 238, 36, 5, 222, 174, 36, 5, 222, 133, 36, 5, 231, 203, 36, 5, 230, - 146, 36, 5, 231, 16, 36, 5, 231, 200, 36, 5, 231, 120, 36, 5, 231, 128, - 36, 5, 230, 223, 36, 5, 230, 222, 36, 5, 230, 102, 36, 5, 230, 98, 36, 5, - 230, 101, 36, 5, 230, 99, 36, 5, 230, 100, 36, 5, 231, 90, 36, 5, 231, - 70, 36, 5, 231, 80, 36, 5, 231, 89, 36, 5, 231, 84, 36, 5, 231, 85, 36, - 5, 231, 74, 36, 5, 231, 59, 36, 5, 199, 44, 36, 5, 198, 208, 36, 5, 199, - 6, 36, 5, 199, 43, 36, 5, 199, 26, 36, 5, 199, 28, 36, 5, 198, 236, 36, - 5, 198, 199, 36, 5, 246, 209, 36, 5, 243, 0, 36, 5, 243, 47, 36, 5, 246, - 208, 36, 5, 243, 75, 36, 5, 243, 79, 36, 5, 243, 20, 36, 5, 242, 245, 36, - 5, 209, 219, 36, 5, 209, 182, 36, 5, 209, 202, 36, 5, 209, 218, 36, 5, - 209, 204, 36, 5, 209, 205, 36, 5, 209, 190, 36, 5, 209, 178, 36, 5, 197, - 164, 36, 5, 197, 136, 36, 5, 197, 142, 36, 5, 197, 163, 36, 5, 197, 156, - 36, 5, 197, 157, 36, 5, 197, 140, 36, 5, 197, 134, 36, 5, 196, 236, 36, - 5, 196, 228, 36, 5, 196, 232, 36, 5, 196, 235, 36, 5, 196, 233, 36, 5, - 196, 234, 36, 5, 196, 230, 36, 5, 196, 229, 36, 5, 233, 68, 36, 5, 232, - 48, 36, 5, 232, 238, 36, 5, 233, 67, 36, 5, 233, 11, 36, 5, 233, 18, 36, - 5, 232, 135, 36, 5, 232, 25, 36, 5, 168, 36, 5, 208, 158, 36, 5, 209, - 176, 36, 5, 210, 210, 36, 5, 210, 40, 36, 5, 210, 53, 36, 5, 209, 65, 36, - 5, 208, 115, 36, 5, 206, 11, 36, 5, 215, 54, 36, 5, 232, 19, 36, 33, 231, - 116, 24, 18, 219, 174, 77, 36, 33, 18, 219, 174, 77, 36, 33, 231, 116, - 77, 36, 205, 49, 77, 36, 193, 22, 36, 232, 42, 201, 58, 36, 242, 26, 36, - 204, 20, 36, 242, 35, 36, 208, 221, 242, 35, 36, 208, 8, 77, 36, 210, - 118, 204, 5, 36, 17, 108, 36, 17, 109, 36, 17, 139, 36, 17, 137, 36, 17, - 153, 36, 17, 173, 36, 17, 181, 36, 17, 176, 36, 17, 184, 36, 31, 199, 90, - 36, 31, 197, 28, 36, 31, 198, 244, 36, 31, 232, 97, 36, 31, 232, 230, 36, - 31, 202, 115, 36, 31, 203, 236, 36, 31, 234, 110, 36, 31, 213, 156, 36, - 31, 228, 109, 36, 31, 199, 91, 188, 36, 5, 205, 54, 215, 66, 36, 5, 215, - 62, 36, 5, 215, 63, 36, 5, 215, 64, 36, 5, 205, 54, 247, 162, 36, 5, 247, - 159, 36, 5, 247, 160, 36, 5, 247, 161, 36, 5, 205, 54, 232, 25, 36, 5, - 232, 21, 36, 5, 232, 22, 36, 5, 232, 23, 36, 5, 205, 54, 208, 115, 36, 5, - 208, 111, 36, 5, 208, 112, 36, 5, 208, 113, 36, 198, 75, 87, 192, 15, 36, - 198, 75, 87, 237, 44, 36, 198, 75, 87, 206, 189, 36, 198, 75, 87, 203, - 35, 206, 189, 36, 198, 75, 87, 236, 229, 36, 198, 75, 87, 221, 225, 36, - 198, 75, 87, 243, 28, 36, 198, 75, 87, 229, 115, 36, 198, 75, 87, 237, - 43, 36, 198, 75, 87, 220, 171, 101, 1, 65, 101, 1, 73, 101, 1, 70, 101, - 1, 74, 101, 1, 69, 101, 1, 196, 8, 101, 1, 231, 203, 101, 1, 157, 101, 1, - 231, 128, 101, 1, 231, 16, 101, 1, 230, 223, 101, 1, 230, 146, 101, 1, - 230, 105, 101, 1, 144, 101, 1, 229, 213, 101, 1, 229, 126, 101, 1, 228, - 247, 101, 1, 228, 128, 101, 1, 228, 95, 101, 1, 171, 101, 1, 219, 214, - 101, 1, 219, 122, 101, 1, 219, 19, 101, 1, 218, 203, 101, 1, 218, 171, - 101, 1, 172, 101, 1, 216, 213, 101, 1, 216, 81, 101, 1, 215, 251, 101, 1, - 215, 139, 101, 1, 180, 101, 1, 229, 15, 101, 1, 214, 223, 101, 1, 214, - 107, 101, 1, 213, 205, 101, 1, 213, 30, 101, 1, 212, 165, 101, 1, 212, - 99, 101, 1, 208, 26, 101, 1, 208, 11, 101, 1, 208, 4, 101, 1, 207, 250, - 101, 1, 207, 239, 101, 1, 207, 237, 101, 1, 189, 101, 1, 206, 3, 101, 1, - 205, 63, 101, 1, 202, 217, 101, 1, 202, 41, 101, 1, 200, 255, 101, 1, - 200, 154, 101, 1, 237, 241, 101, 1, 199, 247, 101, 1, 237, 101, 101, 1, - 199, 140, 101, 1, 236, 255, 101, 1, 198, 188, 101, 1, 236, 129, 101, 1, - 235, 45, 101, 1, 235, 13, 101, 1, 236, 141, 101, 1, 198, 110, 101, 1, - 198, 109, 101, 1, 198, 98, 101, 1, 198, 97, 101, 1, 198, 96, 101, 1, 198, - 95, 101, 1, 197, 164, 101, 1, 197, 157, 101, 1, 197, 142, 101, 1, 197, - 140, 101, 1, 197, 136, 101, 1, 197, 135, 101, 1, 193, 187, 101, 1, 193, - 123, 101, 1, 193, 84, 101, 1, 193, 48, 101, 1, 193, 0, 101, 1, 192, 243, - 101, 1, 169, 101, 1, 192, 80, 101, 1, 192, 33, 101, 1, 192, 12, 101, 1, - 191, 225, 101, 1, 191, 184, 101, 1, 215, 73, 101, 2, 1, 192, 80, 101, 2, - 1, 192, 33, 101, 2, 1, 192, 12, 101, 2, 1, 191, 225, 101, 2, 1, 191, 184, - 101, 2, 1, 215, 73, 21, 22, 228, 58, 21, 22, 73, 21, 22, 252, 118, 21, - 22, 70, 21, 22, 223, 170, 21, 22, 74, 21, 22, 211, 76, 21, 22, 192, 158, - 211, 76, 21, 22, 98, 234, 145, 21, 22, 98, 70, 21, 22, 65, 21, 22, 252, - 154, 21, 22, 193, 123, 21, 22, 193, 101, 193, 123, 21, 22, 193, 84, 21, - 22, 193, 101, 193, 84, 21, 22, 193, 68, 21, 22, 193, 101, 193, 68, 21, - 22, 193, 48, 21, 22, 193, 101, 193, 48, 21, 22, 193, 29, 21, 22, 193, - 101, 193, 29, 21, 22, 214, 195, 193, 29, 21, 22, 193, 187, 21, 22, 193, - 101, 193, 187, 21, 22, 193, 178, 21, 22, 193, 101, 193, 178, 21, 22, 214, - 195, 193, 178, 21, 22, 251, 184, 21, 22, 192, 158, 193, 221, 21, 22, 230, - 231, 201, 58, 21, 22, 52, 251, 250, 21, 22, 52, 230, 176, 21, 22, 52, - 248, 29, 134, 206, 183, 21, 22, 52, 198, 49, 134, 206, 183, 21, 22, 52, - 50, 134, 206, 183, 21, 22, 52, 206, 183, 21, 22, 52, 54, 251, 250, 21, - 22, 52, 54, 203, 35, 81, 201, 10, 21, 22, 52, 82, 236, 96, 21, 22, 52, - 203, 35, 228, 209, 105, 21, 22, 52, 209, 73, 21, 22, 52, 143, 199, 223, - 21, 22, 234, 61, 21, 22, 223, 134, 21, 22, 211, 93, 21, 22, 251, 81, 21, - 22, 210, 53, 21, 22, 210, 208, 21, 22, 209, 176, 21, 22, 209, 136, 21, - 22, 209, 65, 21, 22, 209, 30, 21, 22, 192, 158, 209, 30, 21, 22, 98, 229, - 183, 21, 22, 98, 229, 126, 21, 22, 168, 21, 22, 210, 210, 21, 22, 208, - 113, 21, 22, 193, 101, 208, 113, 21, 22, 208, 111, 21, 22, 193, 101, 208, - 111, 21, 22, 208, 110, 21, 22, 193, 101, 208, 110, 21, 22, 208, 108, 21, - 22, 193, 101, 208, 108, 21, 22, 208, 107, 21, 22, 193, 101, 208, 107, 21, - 22, 208, 115, 21, 22, 193, 101, 208, 115, 21, 22, 208, 114, 21, 22, 193, - 101, 208, 114, 21, 22, 192, 158, 208, 114, 21, 22, 210, 226, 21, 22, 193, - 101, 210, 226, 21, 22, 98, 230, 83, 21, 22, 199, 140, 21, 22, 199, 237, - 21, 22, 198, 188, 21, 22, 198, 165, 21, 22, 159, 21, 22, 198, 54, 21, 22, - 192, 158, 198, 54, 21, 22, 98, 237, 86, 21, 22, 98, 236, 255, 21, 22, - 199, 247, 21, 22, 199, 240, 21, 22, 197, 37, 21, 22, 193, 101, 197, 37, - 21, 22, 197, 15, 21, 22, 193, 101, 197, 15, 21, 22, 197, 14, 21, 22, 193, - 101, 197, 14, 21, 22, 109, 21, 22, 193, 101, 109, 21, 22, 197, 5, 21, 22, - 193, 101, 197, 5, 21, 22, 197, 39, 21, 22, 193, 101, 197, 39, 21, 22, - 197, 38, 21, 22, 193, 101, 197, 38, 21, 22, 214, 195, 197, 38, 21, 22, - 200, 39, 21, 22, 197, 123, 21, 22, 197, 107, 21, 22, 197, 105, 21, 22, - 197, 128, 21, 22, 221, 253, 21, 22, 222, 94, 21, 22, 221, 142, 21, 22, - 221, 121, 21, 22, 221, 43, 21, 22, 221, 17, 21, 22, 192, 158, 221, 17, - 21, 22, 157, 21, 22, 222, 100, 21, 22, 220, 150, 21, 22, 193, 101, 220, - 150, 21, 22, 220, 148, 21, 22, 193, 101, 220, 148, 21, 22, 220, 147, 21, - 22, 193, 101, 220, 147, 21, 22, 220, 145, 21, 22, 193, 101, 220, 145, 21, - 22, 220, 144, 21, 22, 193, 101, 220, 144, 21, 22, 220, 155, 21, 22, 193, - 101, 220, 155, 21, 22, 220, 154, 21, 22, 193, 101, 220, 154, 21, 22, 214, - 195, 220, 154, 21, 22, 222, 125, 21, 22, 220, 156, 21, 22, 201, 252, 221, - 237, 21, 22, 201, 252, 221, 122, 21, 22, 201, 252, 221, 32, 21, 22, 201, - 252, 222, 77, 21, 22, 246, 250, 21, 22, 247, 110, 21, 22, 242, 237, 21, - 22, 242, 227, 21, 22, 242, 51, 21, 22, 238, 227, 21, 22, 192, 158, 238, - 227, 21, 22, 247, 112, 21, 22, 247, 111, 21, 22, 238, 102, 21, 22, 193, - 101, 238, 102, 21, 22, 238, 100, 21, 22, 193, 101, 238, 100, 21, 22, 238, - 99, 21, 22, 193, 101, 238, 99, 21, 22, 238, 98, 21, 22, 193, 101, 238, - 98, 21, 22, 238, 97, 21, 22, 193, 101, 238, 97, 21, 22, 238, 104, 21, 22, - 193, 101, 238, 104, 21, 22, 238, 103, 21, 22, 193, 101, 238, 103, 21, 22, - 214, 195, 238, 103, 21, 22, 247, 145, 21, 22, 205, 96, 199, 46, 21, 22, - 216, 213, 21, 22, 217, 129, 21, 22, 216, 81, 21, 22, 216, 43, 21, 22, - 215, 251, 21, 22, 215, 194, 21, 22, 192, 158, 215, 194, 21, 22, 172, 21, - 22, 217, 130, 21, 22, 215, 64, 21, 22, 193, 101, 215, 64, 21, 22, 215, - 62, 21, 22, 193, 101, 215, 62, 21, 22, 215, 61, 21, 22, 193, 101, 215, - 61, 21, 22, 215, 60, 21, 22, 193, 101, 215, 60, 21, 22, 215, 59, 21, 22, - 193, 101, 215, 59, 21, 22, 215, 66, 21, 22, 193, 101, 215, 66, 21, 22, - 215, 65, 21, 22, 193, 101, 215, 65, 21, 22, 214, 195, 215, 65, 21, 22, - 218, 147, 21, 22, 193, 101, 218, 147, 21, 22, 216, 85, 21, 22, 250, 130, - 218, 147, 21, 22, 205, 96, 218, 147, 21, 22, 214, 107, 21, 22, 214, 235, - 21, 22, 213, 205, 21, 22, 213, 172, 21, 22, 213, 30, 21, 22, 213, 13, 21, - 22, 192, 158, 213, 13, 21, 22, 180, 21, 22, 214, 236, 21, 22, 212, 95, - 21, 22, 193, 101, 212, 95, 21, 22, 212, 97, 21, 22, 193, 101, 212, 97, - 21, 22, 212, 96, 21, 22, 193, 101, 212, 96, 21, 22, 214, 195, 212, 96, - 21, 22, 215, 47, 21, 22, 98, 214, 56, 21, 22, 213, 211, 21, 22, 219, 214, - 21, 22, 220, 100, 21, 22, 219, 122, 21, 22, 219, 104, 21, 22, 219, 19, - 21, 22, 218, 240, 21, 22, 192, 158, 218, 240, 21, 22, 171, 21, 22, 220, - 101, 21, 22, 218, 168, 21, 22, 193, 101, 218, 168, 21, 22, 218, 167, 21, - 22, 193, 101, 218, 167, 21, 22, 218, 166, 21, 22, 193, 101, 218, 166, 21, - 22, 218, 165, 21, 22, 193, 101, 218, 165, 21, 22, 218, 164, 21, 22, 193, - 101, 218, 164, 21, 22, 218, 170, 21, 22, 193, 101, 218, 170, 21, 22, 218, - 169, 21, 22, 193, 101, 218, 169, 21, 22, 170, 21, 22, 193, 101, 170, 21, - 22, 216, 198, 170, 21, 22, 205, 63, 21, 22, 205, 190, 21, 22, 202, 217, - 21, 22, 202, 188, 21, 22, 202, 41, 21, 22, 202, 11, 21, 22, 192, 158, - 202, 11, 21, 22, 189, 21, 22, 205, 192, 21, 22, 200, 141, 21, 22, 193, - 101, 200, 141, 21, 22, 200, 135, 21, 22, 193, 101, 200, 135, 21, 22, 200, - 134, 21, 22, 193, 101, 200, 134, 21, 22, 200, 129, 21, 22, 193, 101, 200, - 129, 21, 22, 200, 128, 21, 22, 193, 101, 200, 128, 21, 22, 200, 146, 21, - 22, 193, 101, 200, 146, 21, 22, 200, 145, 21, 22, 193, 101, 200, 145, 21, - 22, 214, 195, 200, 145, 21, 22, 206, 3, 21, 22, 250, 130, 206, 3, 21, 22, - 200, 147, 21, 22, 248, 88, 206, 3, 21, 22, 215, 187, 202, 109, 21, 22, - 214, 195, 202, 96, 21, 22, 214, 195, 206, 1, 21, 22, 214, 195, 201, 187, - 21, 22, 214, 195, 201, 2, 21, 22, 214, 195, 202, 95, 21, 22, 214, 195, - 205, 66, 21, 22, 203, 108, 21, 22, 203, 76, 21, 22, 203, 71, 21, 22, 203, - 51, 21, 22, 203, 43, 21, 22, 203, 160, 21, 22, 203, 155, 21, 22, 202, - 232, 21, 22, 193, 101, 202, 232, 21, 22, 202, 231, 21, 22, 193, 101, 202, - 231, 21, 22, 202, 230, 21, 22, 193, 101, 202, 230, 21, 22, 202, 229, 21, - 22, 193, 101, 202, 229, 21, 22, 202, 228, 21, 22, 193, 101, 202, 228, 21, - 22, 202, 235, 21, 22, 193, 101, 202, 235, 21, 22, 202, 234, 21, 22, 193, - 101, 202, 234, 21, 22, 203, 162, 21, 22, 192, 80, 21, 22, 192, 138, 21, - 22, 192, 33, 21, 22, 192, 23, 21, 22, 192, 12, 21, 22, 191, 246, 21, 22, - 192, 158, 191, 246, 21, 22, 169, 21, 22, 192, 140, 21, 22, 191, 181, 21, - 22, 193, 101, 191, 181, 21, 22, 191, 180, 21, 22, 193, 101, 191, 180, 21, - 22, 191, 179, 21, 22, 193, 101, 191, 179, 21, 22, 191, 178, 21, 22, 193, - 101, 191, 178, 21, 22, 191, 177, 21, 22, 193, 101, 191, 177, 21, 22, 191, - 183, 21, 22, 193, 101, 191, 183, 21, 22, 191, 182, 21, 22, 193, 101, 191, - 182, 21, 22, 214, 195, 191, 182, 21, 22, 192, 159, 21, 22, 248, 138, 192, - 159, 21, 22, 193, 101, 192, 159, 21, 22, 205, 96, 192, 33, 21, 22, 207, - 108, 21, 22, 207, 216, 207, 108, 21, 22, 193, 101, 219, 214, 21, 22, 207, - 172, 21, 22, 206, 252, 21, 22, 206, 190, 21, 22, 206, 157, 21, 22, 206, - 129, 21, 22, 193, 101, 219, 19, 21, 22, 166, 21, 22, 207, 173, 21, 22, - 193, 101, 171, 21, 22, 206, 20, 21, 22, 193, 101, 206, 20, 21, 22, 148, - 21, 22, 193, 101, 148, 21, 22, 216, 198, 148, 21, 22, 233, 18, 21, 22, - 233, 65, 21, 22, 232, 238, 21, 22, 232, 223, 21, 22, 232, 135, 21, 22, - 232, 123, 21, 22, 233, 68, 21, 22, 233, 67, 21, 22, 232, 24, 21, 22, 193, - 101, 232, 24, 21, 22, 233, 134, 21, 22, 199, 28, 21, 22, 215, 45, 199, - 28, 21, 22, 199, 6, 21, 22, 215, 45, 199, 6, 21, 22, 199, 0, 21, 22, 215, - 45, 199, 0, 21, 22, 198, 236, 21, 22, 198, 230, 21, 22, 199, 44, 21, 22, - 199, 43, 21, 22, 198, 198, 21, 22, 193, 101, 198, 198, 21, 22, 199, 46, - 21, 22, 197, 114, 21, 22, 197, 112, 21, 22, 197, 111, 21, 22, 197, 116, - 21, 22, 197, 117, 21, 22, 196, 254, 21, 22, 196, 253, 21, 22, 196, 252, - 21, 22, 197, 0, 21, 22, 212, 116, 229, 213, 21, 22, 212, 116, 229, 126, - 21, 22, 212, 116, 229, 98, 21, 22, 212, 116, 228, 247, 21, 22, 212, 116, - 228, 220, 21, 22, 212, 116, 144, 21, 22, 212, 116, 230, 58, 21, 22, 212, - 116, 230, 83, 21, 22, 212, 115, 230, 83, 21, 22, 229, 81, 21, 22, 208, - 85, 21, 22, 208, 51, 21, 22, 208, 45, 21, 22, 208, 39, 21, 22, 208, 34, - 21, 22, 208, 89, 21, 22, 208, 88, 21, 22, 208, 97, 21, 22, 198, 106, 21, - 22, 198, 104, 21, 22, 198, 103, 21, 22, 198, 107, 21, 22, 193, 101, 207, - 108, 21, 22, 193, 101, 206, 252, 21, 22, 193, 101, 206, 157, 21, 22, 193, - 101, 166, 21, 22, 214, 52, 21, 22, 214, 2, 21, 22, 213, 254, 21, 22, 213, - 235, 21, 22, 213, 230, 21, 22, 214, 54, 21, 22, 214, 53, 21, 22, 214, 56, - 21, 22, 213, 59, 21, 22, 205, 96, 203, 108, 21, 22, 205, 96, 203, 76, 21, - 22, 205, 96, 203, 51, 21, 22, 205, 96, 203, 160, 21, 22, 193, 27, 199, - 28, 21, 22, 193, 27, 199, 6, 21, 22, 193, 27, 198, 236, 21, 22, 193, 27, - 199, 44, 21, 22, 193, 27, 199, 46, 21, 22, 219, 129, 21, 22, 219, 128, - 21, 22, 219, 127, 21, 22, 219, 126, 21, 22, 219, 135, 21, 22, 219, 134, - 21, 22, 219, 136, 21, 22, 199, 45, 199, 28, 21, 22, 199, 45, 199, 6, 21, - 22, 199, 45, 199, 0, 21, 22, 199, 45, 198, 236, 21, 22, 199, 45, 198, - 230, 21, 22, 199, 45, 199, 44, 21, 22, 199, 45, 199, 43, 21, 22, 199, 45, - 199, 46, 21, 22, 251, 168, 250, 70, 21, 22, 248, 88, 73, 21, 22, 248, 88, - 70, 21, 22, 248, 88, 74, 21, 22, 248, 88, 65, 21, 22, 248, 88, 193, 123, - 21, 22, 248, 88, 193, 84, 21, 22, 248, 88, 193, 48, 21, 22, 248, 88, 193, - 187, 21, 22, 248, 88, 214, 107, 21, 22, 248, 88, 213, 205, 21, 22, 248, - 88, 213, 30, 21, 22, 248, 88, 180, 21, 22, 248, 88, 221, 253, 21, 22, - 248, 88, 221, 142, 21, 22, 248, 88, 221, 43, 21, 22, 248, 88, 157, 21, - 22, 205, 96, 229, 213, 21, 22, 205, 96, 229, 126, 21, 22, 205, 96, 228, - 247, 21, 22, 205, 96, 144, 21, 22, 98, 231, 22, 21, 22, 98, 231, 26, 21, - 22, 98, 231, 40, 21, 22, 98, 231, 39, 21, 22, 98, 231, 28, 21, 22, 98, - 231, 54, 21, 22, 98, 206, 63, 21, 22, 98, 206, 157, 21, 22, 98, 207, 108, - 21, 22, 98, 207, 79, 21, 22, 98, 206, 252, 21, 22, 98, 166, 21, 22, 98, - 193, 0, 21, 22, 98, 193, 48, 21, 22, 98, 193, 123, 21, 22, 98, 193, 112, - 21, 22, 98, 193, 84, 21, 22, 98, 193, 187, 21, 22, 98, 228, 87, 21, 22, - 98, 228, 88, 21, 22, 98, 228, 91, 21, 22, 98, 228, 90, 21, 22, 98, 228, - 89, 21, 22, 98, 228, 94, 21, 22, 98, 198, 208, 21, 22, 98, 198, 236, 21, - 22, 98, 199, 28, 21, 22, 98, 199, 26, 21, 22, 98, 199, 6, 21, 22, 98, - 199, 44, 21, 22, 98, 197, 95, 21, 22, 98, 197, 105, 21, 22, 98, 197, 123, - 21, 22, 98, 197, 122, 21, 22, 98, 197, 107, 21, 22, 98, 197, 128, 21, 22, - 98, 208, 158, 21, 22, 98, 209, 65, 21, 22, 98, 210, 53, 21, 22, 98, 210, - 40, 21, 22, 98, 209, 176, 21, 22, 98, 168, 21, 22, 98, 210, 226, 21, 22, - 98, 230, 146, 21, 22, 98, 230, 223, 21, 22, 98, 231, 128, 21, 22, 98, - 231, 120, 21, 22, 98, 231, 16, 21, 22, 98, 231, 203, 21, 22, 98, 221, - 151, 21, 22, 98, 221, 159, 21, 22, 98, 221, 173, 21, 22, 98, 221, 172, - 21, 22, 98, 221, 166, 21, 22, 98, 221, 190, 21, 22, 98, 221, 72, 21, 22, - 98, 221, 73, 21, 22, 98, 221, 76, 21, 22, 98, 221, 75, 21, 22, 98, 221, - 74, 21, 22, 98, 221, 77, 21, 22, 98, 221, 78, 21, 22, 98, 212, 165, 21, - 22, 98, 213, 30, 21, 22, 98, 214, 107, 21, 22, 98, 214, 96, 21, 22, 98, - 213, 205, 21, 22, 98, 180, 21, 22, 98, 215, 139, 21, 22, 98, 215, 251, - 21, 22, 98, 216, 213, 21, 22, 98, 216, 192, 21, 22, 98, 216, 81, 21, 22, - 98, 172, 21, 22, 98, 191, 225, 21, 22, 98, 192, 12, 21, 22, 98, 192, 80, - 21, 22, 98, 192, 77, 21, 22, 98, 192, 33, 21, 22, 98, 169, 21, 22, 98, - 222, 155, 21, 22, 205, 96, 222, 155, 21, 22, 98, 222, 174, 21, 22, 98, - 222, 238, 21, 22, 98, 222, 236, 21, 22, 98, 222, 217, 21, 22, 205, 96, - 222, 217, 21, 22, 98, 223, 4, 21, 22, 98, 222, 188, 21, 22, 98, 222, 192, - 21, 22, 98, 222, 202, 21, 22, 98, 222, 201, 21, 22, 98, 222, 200, 21, 22, - 98, 222, 203, 21, 22, 98, 218, 203, 21, 22, 98, 219, 19, 21, 22, 98, 219, - 214, 21, 22, 98, 219, 204, 21, 22, 98, 219, 122, 21, 22, 98, 171, 21, 22, - 98, 236, 134, 21, 22, 98, 236, 135, 21, 22, 98, 236, 140, 21, 22, 98, - 236, 139, 21, 22, 98, 236, 136, 21, 22, 98, 236, 141, 21, 22, 98, 219, - 125, 21, 22, 98, 219, 127, 21, 22, 98, 219, 131, 21, 22, 98, 219, 130, - 21, 22, 98, 219, 129, 21, 22, 98, 219, 135, 21, 22, 98, 198, 101, 21, 22, - 98, 198, 103, 21, 22, 98, 198, 106, 21, 22, 98, 198, 105, 21, 22, 98, - 198, 104, 21, 22, 98, 198, 107, 21, 22, 98, 198, 96, 21, 22, 98, 198, 97, - 21, 22, 98, 198, 109, 21, 22, 98, 198, 108, 21, 22, 98, 198, 98, 21, 22, - 98, 198, 110, 21, 22, 98, 190, 251, 21, 22, 98, 191, 7, 21, 22, 98, 191, - 87, 21, 22, 98, 191, 84, 21, 22, 98, 191, 30, 21, 22, 98, 191, 123, 21, - 22, 98, 191, 166, 21, 22, 98, 89, 191, 166, 21, 22, 98, 234, 234, 21, 22, - 98, 234, 235, 21, 22, 98, 234, 244, 21, 22, 98, 234, 243, 21, 22, 98, - 234, 238, 21, 22, 98, 234, 247, 21, 22, 98, 200, 255, 21, 22, 98, 202, - 41, 21, 22, 98, 205, 63, 21, 22, 98, 205, 45, 21, 22, 98, 202, 217, 21, - 22, 98, 189, 21, 22, 98, 203, 0, 21, 22, 98, 203, 51, 21, 22, 98, 203, - 108, 21, 22, 98, 203, 106, 21, 22, 98, 203, 76, 21, 22, 98, 203, 160, 21, - 22, 98, 203, 162, 21, 22, 98, 197, 136, 21, 22, 98, 197, 140, 21, 22, 98, - 197, 157, 21, 22, 98, 197, 156, 21, 22, 98, 197, 142, 21, 22, 98, 197, - 164, 21, 22, 98, 243, 0, 21, 22, 98, 243, 20, 21, 22, 98, 243, 79, 21, - 22, 98, 243, 75, 21, 22, 98, 243, 47, 21, 22, 98, 246, 209, 21, 22, 98, - 197, 98, 21, 22, 98, 197, 99, 21, 22, 98, 197, 102, 21, 22, 98, 197, 101, - 21, 22, 98, 197, 100, 21, 22, 98, 197, 103, 21, 22, 243, 48, 57, 21, 22, - 232, 42, 201, 58, 21, 22, 208, 81, 21, 22, 214, 50, 21, 22, 213, 56, 21, - 22, 213, 55, 21, 22, 213, 54, 21, 22, 213, 53, 21, 22, 213, 58, 21, 22, - 213, 57, 21, 22, 193, 27, 198, 196, 21, 22, 193, 27, 198, 195, 21, 22, - 193, 27, 198, 194, 21, 22, 193, 27, 198, 193, 21, 22, 193, 27, 198, 192, - 21, 22, 193, 27, 198, 199, 21, 22, 193, 27, 198, 198, 21, 22, 193, 27, - 52, 199, 46, 21, 22, 248, 88, 193, 221, 211, 128, 201, 243, 77, 211, 128, - 1, 248, 189, 211, 128, 1, 218, 189, 211, 128, 1, 233, 15, 211, 128, 1, - 205, 174, 211, 128, 1, 213, 153, 211, 128, 1, 196, 161, 211, 128, 1, 237, - 214, 211, 128, 1, 198, 134, 211, 128, 1, 242, 38, 211, 128, 1, 246, 237, - 211, 128, 1, 215, 122, 211, 128, 1, 230, 200, 211, 128, 1, 214, 40, 211, - 128, 1, 201, 49, 211, 128, 1, 206, 50, 211, 128, 1, 251, 180, 211, 128, - 1, 211, 80, 211, 128, 1, 196, 58, 211, 128, 1, 234, 171, 211, 128, 1, - 223, 59, 211, 128, 1, 234, 172, 211, 128, 1, 211, 45, 211, 128, 1, 196, - 132, 211, 128, 1, 223, 176, 211, 128, 1, 234, 169, 211, 128, 1, 210, 29, - 211, 128, 233, 14, 77, 211, 128, 207, 13, 233, 14, 77, 206, 39, 1, 233, - 4, 232, 251, 233, 19, 233, 134, 206, 39, 1, 196, 8, 206, 39, 1, 196, 43, - 196, 59, 69, 206, 39, 1, 191, 228, 206, 39, 1, 192, 159, 206, 39, 1, 193, - 221, 206, 39, 1, 198, 201, 198, 200, 198, 228, 206, 39, 1, 233, 206, 206, - 39, 1, 251, 39, 65, 206, 39, 1, 211, 27, 74, 206, 39, 1, 252, 12, 65, - 206, 39, 1, 251, 213, 206, 39, 1, 218, 247, 74, 206, 39, 1, 203, 28, 74, - 206, 39, 1, 74, 206, 39, 1, 211, 139, 206, 39, 1, 211, 93, 206, 39, 1, - 207, 149, 207, 164, 207, 64, 148, 206, 39, 1, 222, 13, 206, 39, 1, 246, - 233, 206, 39, 1, 222, 14, 222, 125, 206, 39, 1, 232, 14, 206, 39, 1, 234, - 46, 206, 39, 1, 231, 123, 230, 89, 232, 14, 206, 39, 1, 231, 163, 206, - 39, 1, 192, 248, 192, 239, 193, 221, 206, 39, 1, 230, 49, 230, 83, 206, - 39, 1, 230, 53, 230, 83, 206, 39, 1, 218, 249, 230, 83, 206, 39, 1, 203, - 31, 230, 83, 206, 39, 1, 214, 189, 212, 78, 214, 190, 215, 47, 206, 39, - 1, 203, 29, 215, 47, 206, 39, 1, 235, 91, 206, 39, 1, 223, 37, 223, 41, - 223, 27, 70, 206, 39, 1, 73, 206, 39, 1, 222, 228, 223, 7, 206, 39, 1, - 231, 104, 206, 39, 1, 218, 250, 251, 229, 206, 39, 1, 203, 33, 65, 206, - 39, 1, 223, 19, 234, 19, 206, 39, 1, 209, 238, 210, 9, 210, 226, 206, 39, - 1, 251, 134, 234, 17, 206, 39, 1, 201, 249, 206, 3, 206, 39, 1, 202, 193, - 218, 246, 206, 3, 206, 39, 1, 203, 27, 206, 3, 206, 39, 1, 247, 145, 206, - 39, 1, 191, 166, 206, 39, 1, 198, 115, 198, 127, 196, 238, 200, 39, 206, - 39, 1, 203, 26, 200, 39, 206, 39, 1, 238, 80, 206, 39, 1, 248, 167, 248, - 170, 248, 94, 250, 70, 206, 39, 1, 203, 32, 250, 70, 206, 39, 1, 235, 90, - 206, 39, 1, 211, 59, 206, 39, 1, 234, 124, 234, 131, 73, 206, 39, 1, 217, - 59, 217, 71, 218, 147, 206, 39, 1, 218, 248, 218, 147, 206, 39, 1, 203, - 30, 218, 147, 206, 39, 1, 219, 229, 220, 77, 219, 2, 170, 206, 39, 1, - 235, 92, 206, 39, 1, 223, 107, 206, 39, 1, 223, 108, 206, 39, 1, 237, - 228, 237, 234, 238, 80, 206, 39, 1, 211, 18, 233, 205, 74, 206, 39, 1, - 234, 167, 206, 39, 1, 223, 57, 206, 39, 1, 238, 101, 206, 39, 1, 247, 95, - 206, 39, 1, 246, 249, 206, 39, 1, 201, 103, 206, 39, 1, 218, 245, 206, - 39, 1, 203, 25, 206, 39, 1, 227, 251, 206, 39, 1, 208, 97, 206, 39, 1, - 192, 235, 206, 39, 202, 165, 208, 144, 206, 39, 215, 114, 208, 144, 206, - 39, 238, 171, 208, 144, 206, 39, 250, 202, 113, 206, 39, 197, 41, 113, - 206, 39, 248, 187, 113, 206, 39, 1, 222, 125, 206, 39, 1, 203, 162, 206, - 39, 1, 211, 76, 206, 39, 1, 232, 72, 247, 33, 211, 26, 206, 39, 1, 232, - 72, 247, 33, 223, 40, 206, 39, 1, 232, 72, 247, 33, 234, 130, 206, 39, 1, - 232, 72, 247, 33, 252, 11, 206, 39, 1, 232, 72, 247, 33, 251, 213, 199, - 217, 1, 65, 199, 217, 1, 70, 199, 217, 1, 69, 199, 217, 1, 157, 199, 217, - 1, 231, 203, 199, 217, 1, 214, 54, 199, 217, 1, 199, 247, 199, 217, 1, - 237, 241, 199, 217, 1, 180, 199, 217, 1, 168, 199, 217, 1, 249, 103, 199, - 217, 1, 172, 199, 217, 1, 169, 199, 217, 1, 166, 199, 217, 1, 171, 199, - 217, 1, 193, 187, 199, 217, 1, 189, 199, 217, 1, 144, 199, 217, 18, 3, - 70, 199, 217, 18, 3, 69, 199, 217, 3, 195, 37, 199, 217, 3, 210, 159, - 199, 217, 1, 250, 220, 166, 229, 246, 1, 65, 229, 246, 1, 70, 229, 246, - 1, 69, 229, 246, 1, 157, 229, 246, 1, 231, 203, 229, 246, 1, 214, 54, - 229, 246, 1, 199, 247, 229, 246, 1, 237, 241, 229, 246, 1, 180, 229, 246, - 1, 168, 229, 246, 1, 249, 103, 229, 246, 1, 172, 229, 246, 1, 169, 229, - 246, 1, 166, 229, 246, 1, 171, 229, 246, 1, 193, 187, 229, 246, 1, 189, - 229, 246, 1, 144, 229, 246, 18, 3, 70, 229, 246, 18, 3, 69, 229, 246, 3, - 210, 159, 209, 195, 202, 165, 208, 144, 209, 195, 54, 208, 144, 247, 208, - 1, 65, 247, 208, 1, 70, 247, 208, 1, 69, 247, 208, 1, 157, 247, 208, 1, - 231, 203, 247, 208, 1, 214, 54, 247, 208, 1, 199, 247, 247, 208, 1, 237, - 241, 247, 208, 1, 180, 247, 208, 1, 168, 247, 208, 1, 249, 103, 247, 208, - 1, 172, 247, 208, 1, 169, 247, 208, 1, 166, 247, 208, 1, 171, 247, 208, - 1, 193, 187, 247, 208, 1, 189, 247, 208, 1, 144, 247, 208, 18, 3, 70, - 247, 208, 18, 3, 69, 199, 216, 1, 65, 199, 216, 1, 70, 199, 216, 1, 69, - 199, 216, 1, 157, 199, 216, 1, 231, 203, 199, 216, 1, 214, 54, 199, 216, - 1, 199, 247, 199, 216, 1, 237, 241, 199, 216, 1, 180, 199, 216, 1, 168, - 199, 216, 1, 249, 103, 199, 216, 1, 172, 199, 216, 1, 169, 199, 216, 1, - 171, 199, 216, 1, 193, 187, 199, 216, 1, 189, 199, 216, 18, 3, 70, 199, - 216, 18, 3, 69, 94, 1, 157, 94, 1, 221, 190, 94, 1, 221, 43, 94, 1, 221, - 159, 94, 1, 213, 235, 94, 1, 247, 112, 94, 1, 246, 209, 94, 1, 242, 51, - 94, 1, 243, 20, 94, 1, 212, 52, 94, 1, 237, 241, 94, 1, 197, 116, 94, 1, - 236, 129, 94, 1, 197, 111, 94, 1, 213, 36, 94, 1, 199, 247, 94, 1, 199, - 44, 94, 1, 159, 94, 1, 198, 236, 94, 1, 213, 30, 94, 1, 249, 103, 94, 1, - 209, 219, 94, 1, 209, 65, 94, 1, 209, 190, 94, 1, 215, 251, 94, 1, 192, - 12, 94, 1, 206, 157, 94, 1, 219, 19, 94, 1, 195, 21, 94, 1, 203, 160, 94, - 1, 201, 129, 94, 1, 189, 94, 1, 144, 94, 1, 171, 94, 1, 208, 89, 94, 223, - 121, 18, 208, 75, 94, 223, 121, 18, 208, 88, 94, 223, 121, 18, 208, 51, - 94, 223, 121, 18, 208, 45, 94, 223, 121, 18, 208, 27, 94, 223, 121, 18, - 207, 251, 94, 223, 121, 18, 207, 239, 94, 223, 121, 18, 207, 238, 94, - 223, 121, 18, 206, 12, 94, 223, 121, 18, 206, 5, 94, 223, 121, 18, 218, - 162, 94, 223, 121, 18, 218, 150, 94, 223, 121, 18, 208, 69, 94, 223, 121, - 18, 208, 81, 94, 223, 121, 18, 208, 35, 196, 251, 108, 94, 223, 121, 18, - 208, 35, 196, 251, 109, 94, 223, 121, 18, 208, 71, 94, 18, 223, 105, 250, - 243, 94, 18, 223, 105, 252, 154, 94, 18, 3, 252, 154, 94, 18, 3, 70, 94, - 18, 3, 223, 170, 94, 18, 3, 192, 159, 94, 18, 3, 191, 176, 94, 18, 3, 69, - 94, 18, 3, 196, 26, 94, 18, 3, 196, 164, 94, 18, 3, 211, 139, 94, 18, 3, - 169, 94, 18, 3, 223, 197, 94, 18, 3, 73, 94, 18, 3, 251, 229, 94, 18, 3, - 251, 184, 94, 18, 3, 211, 76, 94, 18, 3, 250, 113, 94, 3, 213, 170, 94, - 3, 207, 101, 94, 3, 191, 187, 94, 3, 215, 77, 94, 3, 197, 225, 94, 3, - 249, 40, 94, 3, 206, 146, 94, 3, 198, 85, 94, 3, 222, 68, 94, 3, 251, - 186, 94, 3, 205, 138, 205, 130, 94, 3, 195, 34, 94, 3, 242, 42, 94, 3, - 249, 10, 94, 3, 221, 180, 94, 3, 249, 35, 94, 3, 247, 83, 209, 137, 220, - 162, 94, 3, 219, 181, 198, 54, 94, 3, 248, 155, 94, 3, 209, 192, 215, - 132, 94, 3, 221, 15, 94, 238, 123, 16, 206, 236, 94, 3, 250, 94, 94, 3, - 250, 116, 94, 17, 191, 77, 94, 17, 108, 94, 17, 109, 94, 17, 139, 94, 17, - 137, 94, 17, 153, 94, 17, 173, 94, 17, 181, 94, 17, 176, 94, 17, 184, 94, - 16, 219, 181, 250, 118, 202, 14, 94, 16, 219, 181, 250, 118, 215, 98, 94, - 16, 219, 181, 250, 118, 209, 136, 94, 16, 219, 181, 250, 118, 248, 190, - 94, 16, 219, 181, 250, 118, 247, 188, 94, 16, 219, 181, 250, 118, 208, - 238, 94, 16, 219, 181, 250, 118, 208, 232, 94, 16, 219, 181, 250, 118, - 208, 230, 94, 16, 219, 181, 250, 118, 208, 236, 94, 16, 219, 181, 250, - 118, 208, 234, 102, 248, 110, 102, 234, 78, 102, 242, 26, 102, 232, 42, - 201, 58, 102, 242, 35, 102, 232, 90, 236, 94, 102, 198, 83, 202, 27, 228, - 58, 102, 202, 209, 5, 248, 25, 217, 32, 102, 217, 67, 242, 26, 102, 217, - 67, 232, 42, 201, 58, 102, 213, 151, 102, 232, 71, 66, 205, 30, 108, 102, - 232, 71, 66, 205, 30, 109, 102, 232, 71, 66, 205, 30, 139, 102, 18, 204, - 5, 102, 232, 71, 66, 205, 30, 137, 102, 17, 191, 77, 102, 17, 108, 102, - 17, 109, 102, 17, 139, 102, 17, 137, 102, 17, 153, 102, 17, 173, 102, 17, - 181, 102, 17, 176, 102, 17, 184, 102, 1, 65, 102, 1, 73, 102, 1, 70, 102, - 1, 74, 102, 1, 69, 102, 1, 211, 139, 102, 1, 196, 148, 102, 1, 234, 145, - 102, 1, 180, 102, 1, 251, 71, 102, 1, 249, 103, 102, 1, 168, 102, 1, 208, - 89, 102, 1, 231, 203, 102, 1, 172, 102, 1, 171, 102, 1, 189, 102, 1, 203, - 160, 102, 1, 199, 247, 102, 1, 237, 241, 102, 1, 246, 209, 102, 1, 223, - 4, 102, 1, 169, 102, 1, 166, 102, 1, 193, 187, 102, 1, 233, 68, 102, 1, - 157, 102, 1, 221, 190, 102, 1, 197, 164, 102, 1, 191, 123, 102, 1, 230, - 58, 102, 1, 190, 255, 102, 1, 219, 135, 102, 1, 191, 57, 102, 1, 243, 47, - 102, 1, 198, 83, 177, 18, 57, 102, 1, 198, 83, 73, 102, 1, 198, 83, 70, - 102, 1, 198, 83, 74, 102, 1, 198, 83, 69, 102, 1, 198, 83, 211, 139, 102, - 1, 198, 83, 196, 148, 102, 1, 198, 83, 251, 71, 102, 1, 198, 83, 249, - 103, 102, 1, 198, 83, 168, 102, 1, 198, 83, 208, 89, 102, 1, 198, 83, - 231, 203, 102, 1, 198, 83, 172, 102, 1, 198, 83, 199, 247, 102, 1, 198, - 83, 237, 241, 102, 1, 198, 83, 246, 209, 102, 1, 198, 83, 223, 4, 102, 1, - 198, 83, 197, 164, 102, 1, 198, 83, 169, 102, 1, 198, 83, 193, 187, 102, - 1, 198, 83, 157, 102, 1, 198, 83, 231, 200, 102, 1, 198, 83, 230, 58, - 102, 1, 198, 83, 222, 216, 102, 1, 198, 83, 213, 195, 102, 1, 198, 83, - 234, 247, 102, 1, 202, 209, 73, 102, 1, 202, 209, 70, 102, 1, 202, 209, - 223, 16, 102, 1, 202, 209, 196, 148, 102, 1, 202, 209, 69, 102, 1, 202, - 209, 251, 71, 102, 1, 202, 209, 157, 102, 1, 202, 209, 231, 203, 102, 1, - 202, 209, 144, 102, 1, 202, 209, 168, 102, 1, 202, 209, 203, 160, 102, 1, - 202, 209, 199, 247, 102, 1, 202, 209, 237, 241, 102, 1, 202, 209, 223, 4, - 102, 1, 202, 209, 233, 68, 102, 1, 202, 209, 231, 200, 102, 1, 202, 209, - 230, 58, 102, 1, 202, 209, 197, 164, 102, 1, 202, 209, 191, 123, 102, 1, - 202, 209, 207, 173, 102, 1, 202, 209, 246, 209, 102, 1, 202, 209, 191, - 71, 102, 1, 217, 67, 70, 102, 1, 217, 67, 157, 102, 1, 217, 67, 166, 102, - 1, 217, 67, 233, 68, 102, 1, 217, 67, 191, 71, 102, 1, 246, 210, 4, 103, - 236, 94, 102, 1, 251, 133, 231, 183, 251, 21, 108, 102, 1, 251, 133, 231, - 183, 195, 33, 108, 102, 1, 251, 133, 231, 183, 237, 202, 102, 1, 251, - 133, 231, 183, 196, 159, 102, 1, 251, 133, 231, 183, 223, 65, 196, 159, - 102, 1, 251, 133, 231, 183, 249, 54, 102, 1, 251, 133, 231, 183, 115, - 249, 54, 102, 1, 251, 133, 231, 183, 65, 102, 1, 251, 133, 231, 183, 70, - 102, 1, 251, 133, 231, 183, 157, 102, 1, 251, 133, 231, 183, 214, 54, - 102, 1, 251, 133, 231, 183, 247, 112, 102, 1, 251, 133, 231, 183, 197, - 128, 102, 1, 251, 133, 231, 183, 197, 116, 102, 1, 251, 133, 231, 183, - 237, 146, 102, 1, 251, 133, 231, 183, 213, 66, 102, 1, 251, 133, 231, - 183, 199, 247, 102, 1, 251, 133, 231, 183, 237, 241, 102, 1, 251, 133, - 231, 183, 168, 102, 1, 251, 133, 231, 183, 209, 219, 102, 1, 251, 133, - 231, 183, 201, 170, 102, 1, 251, 133, 231, 183, 191, 71, 102, 1, 251, - 133, 231, 183, 191, 123, 102, 1, 251, 133, 231, 183, 251, 193, 102, 1, - 198, 83, 251, 133, 231, 183, 199, 247, 102, 1, 198, 83, 251, 133, 231, - 183, 191, 71, 102, 1, 217, 67, 251, 133, 231, 183, 231, 54, 102, 1, 217, - 67, 251, 133, 231, 183, 214, 54, 102, 1, 217, 67, 251, 133, 231, 183, - 247, 112, 102, 1, 217, 67, 251, 133, 231, 183, 222, 225, 102, 1, 217, 67, - 251, 133, 231, 183, 197, 128, 102, 1, 217, 67, 251, 133, 231, 183, 237, - 130, 102, 1, 217, 67, 251, 133, 231, 183, 199, 247, 102, 1, 217, 67, 251, - 133, 231, 183, 237, 23, 102, 1, 217, 67, 251, 133, 231, 183, 201, 170, - 102, 1, 217, 67, 251, 133, 231, 183, 238, 95, 102, 1, 217, 67, 251, 133, - 231, 183, 191, 71, 102, 1, 217, 67, 251, 133, 231, 183, 191, 123, 102, 1, - 251, 133, 231, 183, 134, 69, 102, 1, 251, 133, 231, 183, 134, 169, 102, - 1, 217, 67, 251, 133, 231, 183, 248, 153, 102, 1, 251, 133, 231, 183, - 237, 229, 102, 1, 217, 67, 251, 133, 231, 183, 219, 135, 21, 22, 210, - 232, 21, 22, 250, 81, 21, 22, 252, 108, 21, 22, 193, 126, 21, 22, 208, - 244, 21, 22, 210, 62, 21, 22, 208, 106, 21, 22, 199, 149, 21, 22, 222, 4, - 21, 22, 220, 152, 21, 22, 217, 2, 21, 22, 212, 237, 21, 22, 214, 184, 21, - 22, 219, 224, 21, 22, 201, 247, 21, 22, 205, 98, 21, 22, 203, 13, 21, 22, - 203, 112, 21, 22, 202, 227, 21, 22, 191, 234, 21, 22, 192, 86, 21, 22, - 207, 117, 21, 22, 212, 94, 21, 22, 211, 116, 212, 94, 21, 22, 212, 93, - 21, 22, 211, 116, 212, 93, 21, 22, 212, 92, 21, 22, 211, 116, 212, 92, - 21, 22, 212, 91, 21, 22, 211, 116, 212, 91, 21, 22, 206, 17, 21, 22, 206, - 16, 21, 22, 206, 15, 21, 22, 206, 14, 21, 22, 206, 13, 21, 22, 206, 21, - 21, 22, 211, 116, 210, 226, 21, 22, 211, 116, 200, 39, 21, 22, 211, 116, - 222, 125, 21, 22, 211, 116, 247, 145, 21, 22, 211, 116, 218, 147, 21, 22, - 211, 116, 215, 47, 21, 22, 211, 116, 206, 3, 21, 22, 211, 116, 203, 162, - 21, 22, 234, 158, 193, 221, 21, 22, 193, 100, 193, 221, 21, 22, 52, 2, - 206, 183, 21, 22, 52, 207, 142, 236, 96, 21, 22, 207, 216, 206, 18, 21, - 22, 193, 101, 218, 240, 21, 22, 193, 101, 220, 101, 21, 22, 198, 197, 21, - 22, 198, 199, 21, 22, 197, 108, 21, 22, 197, 110, 21, 22, 197, 115, 21, - 22, 198, 100, 21, 22, 198, 102, 21, 22, 205, 96, 202, 232, 21, 22, 205, - 96, 203, 43, 21, 22, 205, 96, 228, 220, 21, 22, 98, 230, 97, 21, 22, 98, - 237, 58, 231, 120, 21, 22, 98, 231, 200, 21, 22, 98, 230, 102, 21, 22, - 205, 96, 222, 135, 21, 22, 98, 222, 133, 21, 22, 248, 211, 237, 58, 170, - 21, 22, 248, 211, 237, 58, 148, 21, 22, 98, 237, 53, 206, 3, 219, 98, - 194, 254, 219, 151, 219, 98, 1, 157, 219, 98, 1, 221, 190, 219, 98, 1, - 231, 203, 219, 98, 1, 231, 54, 219, 98, 1, 214, 54, 219, 98, 1, 247, 112, - 219, 98, 1, 246, 209, 219, 98, 1, 223, 4, 219, 98, 1, 222, 225, 219, 98, - 1, 192, 108, 219, 98, 1, 199, 247, 219, 98, 1, 199, 44, 219, 98, 1, 237, - 241, 219, 98, 1, 237, 23, 219, 98, 1, 180, 219, 98, 1, 168, 219, 98, 1, - 209, 219, 219, 98, 1, 249, 103, 219, 98, 1, 248, 153, 219, 98, 1, 172, - 219, 98, 1, 169, 219, 98, 1, 166, 219, 98, 1, 171, 219, 98, 1, 193, 187, - 219, 98, 1, 203, 160, 219, 98, 1, 201, 170, 219, 98, 1, 189, 219, 98, 1, - 144, 219, 98, 1, 230, 93, 219, 98, 1, 198, 22, 219, 98, 18, 3, 65, 219, - 98, 18, 3, 70, 219, 98, 18, 3, 69, 219, 98, 18, 3, 234, 145, 219, 98, 18, - 3, 251, 184, 219, 98, 18, 3, 211, 76, 219, 98, 18, 3, 250, 113, 219, 98, - 18, 3, 73, 219, 98, 18, 3, 74, 219, 98, 200, 234, 1, 169, 219, 98, 200, - 234, 1, 166, 219, 98, 200, 234, 1, 193, 187, 219, 98, 2, 1, 157, 219, 98, - 2, 1, 214, 54, 219, 98, 2, 1, 251, 20, 219, 98, 2, 1, 199, 247, 219, 98, - 2, 1, 180, 219, 98, 2, 1, 168, 219, 98, 2, 1, 172, 219, 98, 2, 1, 166, - 219, 98, 2, 1, 171, 219, 98, 3, 215, 119, 219, 98, 3, 221, 232, 219, 98, - 3, 205, 193, 219, 98, 3, 218, 240, 219, 98, 233, 175, 77, 219, 98, 208, - 8, 77, 219, 98, 17, 191, 77, 219, 98, 17, 108, 219, 98, 17, 109, 219, 98, - 17, 139, 219, 98, 17, 137, 219, 98, 17, 153, 219, 98, 17, 173, 219, 98, - 17, 181, 219, 98, 17, 176, 219, 98, 17, 184, 53, 219, 215, 1, 157, 53, - 219, 215, 1, 192, 220, 53, 219, 215, 1, 214, 54, 53, 219, 215, 1, 197, - 164, 53, 219, 215, 1, 189, 53, 219, 215, 1, 169, 53, 219, 215, 1, 199, - 247, 53, 219, 215, 1, 199, 44, 53, 219, 215, 1, 171, 53, 219, 215, 1, - 168, 53, 219, 215, 1, 209, 219, 53, 219, 215, 1, 172, 53, 219, 215, 1, - 233, 68, 53, 219, 215, 1, 195, 185, 53, 219, 215, 1, 144, 53, 219, 215, - 1, 208, 89, 53, 219, 215, 1, 221, 190, 53, 219, 215, 1, 197, 153, 53, - 219, 215, 1, 180, 53, 219, 215, 1, 65, 53, 219, 215, 1, 70, 53, 219, 215, - 1, 234, 145, 53, 219, 215, 1, 234, 130, 53, 219, 215, 1, 69, 53, 219, - 215, 1, 211, 76, 53, 219, 215, 1, 74, 53, 219, 215, 1, 196, 148, 53, 219, - 215, 1, 73, 53, 219, 215, 1, 250, 111, 53, 219, 215, 1, 251, 184, 53, - 219, 215, 1, 198, 72, 53, 219, 215, 1, 198, 71, 53, 219, 215, 1, 198, 70, - 53, 219, 215, 1, 198, 69, 53, 219, 215, 1, 198, 68, 214, 66, 53, 218, - 197, 1, 136, 208, 89, 214, 66, 53, 218, 197, 1, 131, 208, 89, 214, 66, - 53, 218, 197, 1, 136, 157, 214, 66, 53, 218, 197, 1, 136, 192, 220, 214, - 66, 53, 218, 197, 1, 136, 214, 54, 214, 66, 53, 218, 197, 1, 131, 157, - 214, 66, 53, 218, 197, 1, 131, 192, 220, 214, 66, 53, 218, 197, 1, 131, - 214, 54, 214, 66, 53, 218, 197, 1, 136, 197, 164, 214, 66, 53, 218, 197, - 1, 136, 189, 214, 66, 53, 218, 197, 1, 136, 169, 214, 66, 53, 218, 197, - 1, 131, 197, 164, 214, 66, 53, 218, 197, 1, 131, 189, 214, 66, 53, 218, - 197, 1, 131, 169, 214, 66, 53, 218, 197, 1, 136, 199, 247, 214, 66, 53, - 218, 197, 1, 136, 199, 44, 214, 66, 53, 218, 197, 1, 136, 180, 214, 66, - 53, 218, 197, 1, 131, 199, 247, 214, 66, 53, 218, 197, 1, 131, 199, 44, - 214, 66, 53, 218, 197, 1, 131, 180, 214, 66, 53, 218, 197, 1, 136, 168, - 214, 66, 53, 218, 197, 1, 136, 209, 219, 214, 66, 53, 218, 197, 1, 136, - 172, 214, 66, 53, 218, 197, 1, 131, 168, 214, 66, 53, 218, 197, 1, 131, - 209, 219, 214, 66, 53, 218, 197, 1, 131, 172, 214, 66, 53, 218, 197, 1, - 136, 233, 68, 214, 66, 53, 218, 197, 1, 136, 195, 185, 214, 66, 53, 218, - 197, 1, 136, 171, 214, 66, 53, 218, 197, 1, 131, 233, 68, 214, 66, 53, - 218, 197, 1, 131, 195, 185, 214, 66, 53, 218, 197, 1, 131, 171, 214, 66, - 53, 218, 197, 1, 136, 144, 214, 66, 53, 218, 197, 1, 136, 237, 241, 214, - 66, 53, 218, 197, 1, 136, 249, 103, 214, 66, 53, 218, 197, 1, 131, 144, - 214, 66, 53, 218, 197, 1, 131, 237, 241, 214, 66, 53, 218, 197, 1, 131, - 249, 103, 214, 66, 53, 218, 197, 1, 136, 220, 157, 214, 66, 53, 218, 197, - 1, 136, 192, 185, 214, 66, 53, 218, 197, 1, 131, 220, 157, 214, 66, 53, - 218, 197, 1, 131, 192, 185, 214, 66, 53, 218, 197, 1, 136, 200, 246, 214, - 66, 53, 218, 197, 1, 131, 200, 246, 214, 66, 53, 218, 197, 18, 3, 18, - 203, 23, 214, 66, 53, 218, 197, 18, 3, 252, 154, 214, 66, 53, 218, 197, - 18, 3, 223, 170, 214, 66, 53, 218, 197, 18, 3, 69, 214, 66, 53, 218, 197, - 18, 3, 196, 26, 214, 66, 53, 218, 197, 18, 3, 73, 214, 66, 53, 218, 197, - 18, 3, 251, 229, 214, 66, 53, 218, 197, 18, 3, 74, 214, 66, 53, 218, 197, - 18, 3, 211, 169, 214, 66, 53, 218, 197, 18, 3, 196, 148, 214, 66, 53, - 218, 197, 18, 3, 250, 81, 214, 66, 53, 218, 197, 18, 3, 252, 108, 214, - 66, 53, 218, 197, 18, 3, 196, 17, 214, 66, 53, 218, 197, 18, 3, 210, 232, - 214, 66, 53, 218, 197, 18, 3, 211, 166, 214, 66, 53, 218, 197, 18, 3, - 196, 140, 214, 66, 53, 218, 197, 18, 3, 223, 16, 214, 66, 53, 218, 197, - 1, 52, 196, 8, 214, 66, 53, 218, 197, 1, 52, 214, 56, 214, 66, 53, 218, - 197, 1, 52, 215, 47, 214, 66, 53, 218, 197, 1, 52, 218, 147, 214, 66, 53, - 218, 197, 1, 52, 222, 125, 214, 66, 53, 218, 197, 1, 52, 238, 80, 214, - 66, 53, 218, 197, 1, 52, 250, 70, 214, 66, 53, 218, 197, 163, 217, 36, - 214, 66, 53, 218, 197, 163, 217, 35, 214, 66, 53, 218, 197, 17, 191, 77, - 214, 66, 53, 218, 197, 17, 108, 214, 66, 53, 218, 197, 17, 109, 214, 66, - 53, 218, 197, 17, 139, 214, 66, 53, 218, 197, 17, 137, 214, 66, 53, 218, - 197, 17, 153, 214, 66, 53, 218, 197, 17, 173, 214, 66, 53, 218, 197, 17, - 181, 214, 66, 53, 218, 197, 17, 176, 214, 66, 53, 218, 197, 17, 184, 214, - 66, 53, 218, 197, 128, 17, 108, 214, 66, 53, 218, 197, 3, 220, 83, 214, - 66, 53, 218, 197, 3, 220, 82, 94, 16, 210, 74, 94, 16, 215, 99, 221, 34, - 94, 16, 209, 137, 221, 34, 94, 16, 248, 191, 221, 34, 94, 16, 247, 189, - 221, 34, 94, 16, 208, 239, 221, 34, 94, 16, 208, 233, 221, 34, 94, 16, - 208, 231, 221, 34, 94, 16, 208, 237, 221, 34, 94, 16, 208, 235, 221, 34, - 94, 16, 237, 187, 221, 34, 94, 16, 237, 183, 221, 34, 94, 16, 237, 182, - 221, 34, 94, 16, 237, 185, 221, 34, 94, 16, 237, 184, 221, 34, 94, 16, - 237, 181, 221, 34, 94, 16, 197, 47, 94, 16, 215, 99, 206, 144, 94, 16, - 209, 137, 206, 144, 94, 16, 248, 191, 206, 144, 94, 16, 247, 189, 206, - 144, 94, 16, 208, 239, 206, 144, 94, 16, 208, 233, 206, 144, 94, 16, 208, - 231, 206, 144, 94, 16, 208, 237, 206, 144, 94, 16, 208, 235, 206, 144, - 94, 16, 237, 187, 206, 144, 94, 16, 237, 183, 206, 144, 94, 16, 237, 182, - 206, 144, 94, 16, 237, 185, 206, 144, 94, 16, 237, 184, 206, 144, 94, 16, - 237, 181, 206, 144, 247, 209, 1, 157, 247, 209, 1, 231, 203, 247, 209, 1, - 214, 54, 247, 209, 1, 213, 253, 247, 209, 1, 168, 247, 209, 1, 249, 103, - 247, 209, 1, 172, 247, 209, 1, 215, 150, 247, 209, 1, 199, 247, 247, 209, - 1, 237, 241, 247, 209, 1, 180, 247, 209, 1, 212, 231, 247, 209, 1, 247, - 112, 247, 209, 1, 223, 4, 247, 209, 1, 212, 88, 247, 209, 1, 212, 79, - 247, 209, 1, 169, 247, 209, 1, 166, 247, 209, 1, 171, 247, 209, 1, 195, - 185, 247, 209, 1, 189, 247, 209, 1, 65, 247, 209, 1, 144, 247, 209, 18, - 3, 70, 247, 209, 18, 3, 69, 247, 209, 18, 3, 73, 247, 209, 18, 3, 74, - 247, 209, 18, 3, 251, 229, 247, 209, 210, 174, 247, 209, 234, 53, 80, - 205, 48, 53, 128, 1, 136, 157, 53, 128, 1, 136, 221, 190, 53, 128, 1, - 136, 220, 141, 53, 128, 1, 131, 157, 53, 128, 1, 131, 220, 141, 53, 128, - 1, 131, 221, 190, 53, 128, 1, 214, 54, 53, 128, 1, 136, 247, 112, 53, - 128, 1, 136, 246, 209, 53, 128, 1, 131, 247, 112, 53, 128, 1, 131, 189, - 53, 128, 1, 131, 246, 209, 53, 128, 1, 212, 88, 53, 128, 1, 207, 124, 53, - 128, 1, 136, 207, 122, 53, 128, 1, 237, 241, 53, 128, 1, 131, 207, 122, - 53, 128, 1, 207, 133, 53, 128, 1, 136, 199, 247, 53, 128, 1, 136, 199, - 44, 53, 128, 1, 131, 199, 247, 53, 128, 1, 131, 199, 44, 53, 128, 1, 180, - 53, 128, 1, 249, 103, 53, 128, 1, 136, 168, 53, 128, 1, 136, 209, 219, - 53, 128, 1, 136, 233, 68, 53, 128, 1, 131, 168, 53, 128, 1, 131, 233, 68, - 53, 128, 1, 131, 209, 219, 53, 128, 1, 172, 53, 128, 1, 131, 169, 53, - 128, 1, 136, 169, 53, 128, 1, 166, 53, 128, 1, 206, 52, 53, 128, 1, 171, - 53, 128, 1, 218, 196, 53, 128, 1, 193, 187, 53, 128, 1, 136, 203, 160, - 53, 128, 1, 136, 201, 170, 53, 128, 1, 136, 189, 53, 128, 1, 136, 144, - 53, 128, 1, 219, 49, 53, 128, 1, 65, 53, 128, 1, 131, 144, 53, 128, 1, - 70, 53, 128, 1, 223, 170, 53, 128, 1, 69, 53, 128, 1, 196, 26, 53, 128, - 1, 234, 145, 53, 128, 1, 211, 76, 53, 128, 1, 220, 83, 53, 128, 1, 230, - 172, 189, 53, 128, 119, 3, 216, 198, 166, 53, 128, 119, 3, 216, 198, 171, - 53, 128, 119, 3, 220, 102, 199, 185, 220, 72, 53, 128, 3, 217, 92, 222, - 58, 220, 72, 53, 128, 119, 3, 52, 214, 54, 53, 128, 119, 3, 131, 168, 53, - 128, 119, 3, 136, 207, 123, 211, 46, 131, 168, 53, 128, 119, 3, 172, 53, - 128, 119, 3, 249, 103, 53, 128, 119, 3, 189, 53, 128, 3, 205, 167, 53, - 128, 18, 3, 65, 53, 128, 18, 3, 217, 92, 205, 117, 53, 128, 18, 3, 252, - 154, 53, 128, 18, 3, 199, 195, 252, 154, 53, 128, 18, 3, 70, 53, 128, 18, - 3, 223, 170, 53, 128, 18, 3, 196, 148, 53, 128, 18, 3, 196, 25, 53, 128, - 18, 3, 69, 53, 128, 18, 3, 196, 26, 53, 128, 18, 3, 74, 53, 128, 18, 3, - 211, 170, 60, 53, 128, 18, 3, 210, 232, 53, 128, 18, 3, 73, 53, 128, 18, - 3, 251, 229, 53, 128, 18, 3, 211, 76, 53, 128, 18, 3, 251, 184, 53, 128, - 18, 3, 128, 251, 184, 53, 128, 18, 3, 211, 170, 56, 53, 128, 3, 217, 92, - 222, 57, 53, 128, 3, 198, 73, 53, 128, 3, 198, 72, 53, 128, 3, 221, 147, - 198, 71, 53, 128, 3, 221, 147, 198, 70, 53, 128, 3, 221, 147, 198, 69, - 53, 128, 3, 207, 181, 230, 57, 53, 128, 3, 217, 92, 205, 147, 53, 128, 3, - 221, 146, 222, 38, 53, 128, 33, 238, 151, 236, 96, 53, 128, 228, 211, 17, - 191, 77, 53, 128, 228, 211, 17, 108, 53, 128, 228, 211, 17, 109, 53, 128, - 228, 211, 17, 139, 53, 128, 228, 211, 17, 137, 53, 128, 228, 211, 17, - 153, 53, 128, 228, 211, 17, 173, 53, 128, 228, 211, 17, 181, 53, 128, - 228, 211, 17, 176, 53, 128, 228, 211, 17, 184, 53, 128, 128, 17, 191, 77, - 53, 128, 128, 17, 108, 53, 128, 128, 17, 109, 53, 128, 128, 17, 139, 53, - 128, 128, 17, 137, 53, 128, 128, 17, 153, 53, 128, 128, 17, 173, 53, 128, - 128, 17, 181, 53, 128, 128, 17, 176, 53, 128, 128, 17, 184, 53, 128, 3, - 193, 78, 53, 128, 3, 193, 77, 53, 128, 3, 205, 102, 53, 128, 3, 221, 221, - 53, 128, 3, 228, 139, 53, 128, 3, 236, 112, 53, 128, 3, 207, 13, 206, - 117, 207, 133, 53, 128, 3, 217, 92, 192, 109, 53, 128, 3, 222, 93, 53, - 128, 3, 222, 92, 53, 128, 3, 205, 112, 53, 128, 3, 205, 111, 53, 128, 3, - 229, 249, 53, 128, 3, 247, 109, 33, 235, 84, 242, 210, 252, 8, 33, 236, - 252, 33, 223, 111, 33, 235, 75, 55, 33, 197, 221, 236, 96, 33, 192, 233, - 60, 33, 193, 70, 219, 89, 60, 33, 211, 66, 87, 60, 33, 54, 211, 66, 87, - 60, 33, 155, 246, 231, 201, 23, 60, 33, 201, 9, 246, 231, 201, 23, 60, - 33, 210, 105, 56, 33, 54, 210, 105, 56, 33, 210, 105, 60, 33, 210, 105, - 210, 245, 33, 8, 2, 1, 193, 222, 60, 33, 8, 2, 1, 152, 193, 222, 60, 33, - 45, 210, 104, 95, 219, 200, 33, 50, 210, 104, 95, 187, 33, 45, 210, 104, - 248, 183, 219, 200, 33, 50, 210, 104, 248, 183, 187, 33, 51, 248, 3, 56, - 33, 31, 3, 56, 33, 223, 65, 54, 250, 221, 56, 33, 107, 3, 56, 33, 54, - 107, 3, 56, 33, 54, 107, 3, 60, 33, 197, 221, 251, 251, 252, 8, 33, 8, 2, - 1, 223, 87, 232, 14, 33, 8, 2, 1, 223, 87, 148, 33, 8, 2, 1, 223, 87, - 200, 39, 147, 3, 196, 119, 206, 239, 147, 3, 196, 119, 247, 73, 147, 3, - 246, 246, 147, 3, 200, 168, 147, 3, 248, 107, 147, 1, 251, 163, 147, 1, - 251, 164, 199, 118, 147, 1, 223, 165, 147, 1, 223, 166, 199, 118, 147, 1, - 196, 122, 147, 1, 196, 123, 199, 118, 147, 1, 207, 181, 207, 46, 147, 1, - 207, 181, 207, 47, 199, 118, 147, 1, 220, 102, 219, 175, 147, 1, 220, - 102, 219, 176, 199, 118, 147, 1, 234, 102, 147, 1, 251, 181, 147, 1, 211, - 112, 147, 1, 211, 113, 199, 118, 147, 1, 157, 147, 1, 222, 115, 217, 95, - 147, 1, 231, 203, 147, 1, 231, 204, 230, 207, 147, 1, 214, 54, 147, 1, - 247, 112, 147, 1, 247, 113, 220, 88, 147, 1, 223, 4, 147, 1, 223, 5, 222, - 229, 147, 1, 212, 88, 147, 1, 199, 248, 219, 234, 147, 1, 199, 248, 215, - 94, 217, 95, 147, 1, 237, 242, 215, 94, 251, 111, 147, 1, 237, 242, 215, - 94, 217, 95, 147, 1, 214, 249, 207, 136, 147, 1, 199, 247, 147, 1, 199, - 248, 199, 153, 147, 1, 237, 241, 147, 1, 237, 242, 217, 117, 147, 1, 180, - 147, 1, 168, 147, 1, 210, 211, 222, 50, 147, 1, 249, 103, 147, 1, 249, - 104, 221, 233, 147, 1, 172, 147, 1, 169, 147, 1, 166, 147, 1, 171, 147, - 1, 193, 187, 147, 1, 205, 202, 205, 179, 147, 1, 205, 202, 205, 124, 147, - 1, 189, 147, 1, 144, 147, 3, 207, 36, 147, 18, 3, 199, 118, 147, 18, 3, - 196, 118, 147, 18, 3, 196, 119, 205, 120, 147, 18, 3, 200, 203, 147, 18, - 3, 200, 204, 223, 157, 147, 18, 3, 207, 181, 207, 46, 147, 18, 3, 207, - 181, 207, 47, 199, 118, 147, 18, 3, 220, 102, 219, 175, 147, 18, 3, 220, - 102, 219, 176, 199, 118, 147, 18, 3, 199, 196, 147, 18, 3, 199, 197, 207, - 46, 147, 18, 3, 199, 197, 199, 118, 147, 18, 3, 199, 197, 207, 47, 199, - 118, 147, 18, 3, 210, 7, 147, 18, 3, 210, 8, 199, 118, 147, 251, 241, - 251, 240, 147, 1, 222, 80, 205, 119, 147, 1, 221, 153, 205, 119, 147, 1, - 196, 231, 205, 119, 147, 1, 234, 139, 205, 119, 147, 1, 195, 151, 205, - 119, 147, 1, 191, 109, 205, 119, 147, 1, 250, 135, 205, 119, 147, 1, 250, - 220, 222, 175, 147, 17, 191, 77, 147, 17, 108, 147, 17, 109, 147, 17, - 139, 147, 17, 137, 147, 17, 153, 147, 17, 173, 147, 17, 181, 147, 17, - 176, 147, 17, 184, 147, 210, 135, 147, 210, 165, 147, 193, 62, 147, 247, - 46, 210, 158, 147, 247, 46, 202, 185, 147, 247, 46, 210, 102, 147, 210, - 164, 147, 37, 16, 236, 103, 147, 37, 16, 237, 57, 147, 37, 16, 235, 27, - 147, 37, 16, 237, 191, 147, 37, 16, 237, 192, 200, 168, 147, 37, 16, 236, - 197, 147, 37, 16, 237, 233, 147, 37, 16, 237, 32, 147, 37, 16, 237, 215, - 147, 37, 16, 237, 192, 231, 122, 147, 37, 16, 33, 199, 111, 147, 37, 16, - 33, 234, 50, 147, 37, 16, 33, 221, 228, 147, 37, 16, 33, 221, 230, 147, - 37, 16, 33, 222, 233, 147, 37, 16, 33, 221, 229, 4, 222, 233, 147, 37, - 16, 33, 221, 231, 4, 222, 233, 147, 37, 16, 33, 248, 176, 147, 37, 16, - 33, 230, 211, 147, 37, 16, 206, 201, 211, 66, 235, 38, 147, 37, 16, 206, - 201, 211, 66, 237, 231, 147, 37, 16, 206, 201, 242, 171, 197, 76, 147, - 37, 16, 206, 201, 242, 171, 199, 206, 147, 37, 16, 219, 198, 211, 66, - 210, 150, 147, 37, 16, 219, 198, 211, 66, 208, 142, 147, 37, 16, 219, - 198, 242, 171, 209, 96, 147, 37, 16, 219, 198, 242, 171, 209, 78, 147, - 37, 16, 219, 198, 211, 66, 209, 123, 147, 210, 136, 219, 251, 147, 210, - 166, 219, 251, 200, 192, 3, 210, 132, 200, 192, 3, 210, 146, 200, 192, 3, - 210, 142, 200, 192, 1, 65, 200, 192, 1, 70, 200, 192, 1, 69, 200, 192, 1, - 251, 229, 200, 192, 1, 74, 200, 192, 1, 73, 200, 192, 1, 233, 201, 200, - 192, 1, 157, 200, 192, 1, 208, 89, 200, 192, 1, 231, 203, 200, 192, 1, - 214, 54, 200, 192, 1, 247, 112, 200, 192, 1, 223, 4, 200, 192, 1, 191, - 123, 200, 192, 1, 212, 88, 200, 192, 1, 199, 247, 200, 192, 1, 237, 241, - 200, 192, 1, 180, 200, 192, 1, 168, 200, 192, 1, 233, 68, 200, 192, 1, - 195, 185, 200, 192, 1, 249, 103, 200, 192, 1, 172, 200, 192, 1, 169, 200, - 192, 1, 166, 200, 192, 1, 171, 200, 192, 1, 193, 187, 200, 192, 1, 189, - 200, 192, 1, 192, 220, 200, 192, 1, 144, 200, 192, 119, 3, 210, 162, 200, - 192, 119, 3, 210, 134, 200, 192, 119, 3, 210, 131, 200, 192, 18, 3, 210, - 149, 200, 192, 18, 3, 210, 130, 200, 192, 18, 3, 210, 155, 200, 192, 18, - 3, 210, 141, 200, 192, 18, 3, 210, 163, 200, 192, 18, 3, 210, 151, 200, - 192, 3, 210, 167, 200, 192, 3, 195, 37, 200, 192, 119, 3, 210, 90, 172, - 200, 192, 119, 3, 210, 90, 193, 187, 200, 192, 1, 221, 190, 200, 192, 1, - 200, 122, 200, 192, 17, 191, 77, 200, 192, 17, 108, 200, 192, 17, 109, - 200, 192, 17, 139, 200, 192, 17, 137, 200, 192, 17, 153, 200, 192, 17, - 173, 200, 192, 17, 181, 200, 192, 17, 176, 200, 192, 17, 184, 200, 192, - 250, 95, 200, 192, 1, 207, 16, 200, 192, 1, 219, 148, 200, 192, 1, 248, - 153, 200, 192, 1, 52, 222, 125, 200, 192, 1, 52, 218, 147, 249, 13, 1, - 65, 249, 13, 1, 202, 177, 65, 249, 13, 1, 144, 249, 13, 1, 202, 177, 144, - 249, 13, 1, 217, 65, 144, 249, 13, 1, 249, 103, 249, 13, 1, 222, 35, 249, - 103, 249, 13, 1, 168, 249, 13, 1, 202, 177, 168, 249, 13, 1, 180, 249, - 13, 1, 217, 65, 180, 249, 13, 1, 193, 187, 249, 13, 1, 202, 177, 193, - 187, 249, 13, 1, 210, 183, 193, 187, 249, 13, 1, 231, 203, 249, 13, 1, - 202, 177, 231, 203, 249, 13, 1, 223, 4, 249, 13, 1, 237, 241, 249, 13, 1, - 166, 249, 13, 1, 202, 177, 166, 249, 13, 1, 172, 249, 13, 1, 202, 177, - 172, 249, 13, 1, 201, 251, 199, 247, 249, 13, 1, 213, 3, 199, 247, 249, - 13, 1, 189, 249, 13, 1, 202, 177, 189, 249, 13, 1, 217, 65, 189, 249, 13, - 1, 169, 249, 13, 1, 202, 177, 169, 249, 13, 1, 214, 54, 249, 13, 1, 171, - 249, 13, 1, 202, 177, 171, 249, 13, 1, 212, 88, 249, 13, 1, 247, 112, - 249, 13, 1, 214, 148, 249, 13, 1, 216, 248, 249, 13, 1, 70, 249, 13, 1, - 69, 249, 13, 3, 198, 77, 249, 13, 18, 3, 73, 249, 13, 18, 3, 210, 183, - 73, 249, 13, 18, 3, 234, 145, 249, 13, 18, 3, 70, 249, 13, 18, 3, 222, - 35, 70, 249, 13, 18, 3, 74, 249, 13, 18, 3, 222, 35, 74, 249, 13, 18, 3, - 69, 249, 13, 18, 3, 126, 39, 202, 177, 189, 249, 13, 119, 3, 214, 56, - 249, 13, 119, 3, 230, 83, 249, 13, 210, 144, 249, 13, 210, 140, 249, 13, - 16, 248, 117, 214, 249, 216, 144, 249, 13, 16, 248, 117, 209, 129, 249, - 13, 16, 248, 117, 222, 152, 249, 13, 16, 248, 117, 210, 144, 219, 159, 1, - 157, 219, 159, 1, 221, 70, 219, 159, 1, 221, 190, 219, 159, 1, 231, 203, - 219, 159, 1, 230, 239, 219, 159, 1, 214, 54, 219, 159, 1, 247, 112, 219, - 159, 1, 246, 209, 219, 159, 1, 223, 4, 219, 159, 1, 212, 88, 219, 159, 1, - 199, 247, 219, 159, 1, 199, 44, 219, 159, 1, 237, 241, 219, 159, 1, 180, - 219, 159, 1, 168, 219, 159, 1, 209, 102, 219, 159, 1, 209, 219, 219, 159, - 1, 233, 68, 219, 159, 1, 232, 179, 219, 159, 1, 249, 103, 219, 159, 1, - 248, 92, 219, 159, 1, 172, 219, 159, 1, 216, 2, 219, 159, 1, 197, 164, - 219, 159, 1, 197, 153, 219, 159, 1, 234, 247, 219, 159, 1, 169, 219, 159, - 1, 166, 219, 159, 1, 171, 219, 159, 1, 144, 219, 159, 1, 229, 79, 219, - 159, 1, 195, 185, 219, 159, 1, 189, 219, 159, 1, 203, 160, 219, 159, 1, - 193, 187, 219, 159, 1, 65, 219, 159, 200, 234, 1, 169, 219, 159, 200, - 234, 1, 166, 219, 159, 18, 3, 252, 154, 219, 159, 18, 3, 70, 219, 159, - 18, 3, 74, 219, 159, 18, 3, 211, 76, 219, 159, 18, 3, 69, 219, 159, 18, - 3, 196, 26, 219, 159, 18, 3, 73, 219, 159, 119, 3, 222, 125, 219, 159, - 119, 3, 218, 147, 219, 159, 119, 3, 170, 219, 159, 119, 3, 215, 47, 219, - 159, 119, 3, 210, 226, 219, 159, 119, 3, 148, 219, 159, 119, 3, 200, 39, - 219, 159, 119, 3, 212, 60, 219, 159, 119, 3, 222, 57, 219, 159, 3, 207, - 134, 219, 159, 3, 212, 128, 219, 159, 208, 145, 199, 242, 219, 159, 208, - 145, 212, 72, 198, 191, 199, 242, 219, 159, 208, 145, 246, 218, 219, 159, - 208, 145, 197, 145, 246, 218, 219, 159, 208, 145, 197, 144, 219, 159, 17, - 191, 77, 219, 159, 17, 108, 219, 159, 17, 109, 219, 159, 17, 139, 219, - 159, 17, 137, 219, 159, 17, 153, 219, 159, 17, 173, 219, 159, 17, 181, - 219, 159, 17, 176, 219, 159, 17, 184, 219, 159, 1, 197, 128, 219, 159, 1, - 197, 116, 219, 159, 1, 237, 146, 211, 110, 243, 40, 17, 191, 77, 211, - 110, 243, 40, 17, 108, 211, 110, 243, 40, 17, 109, 211, 110, 243, 40, 17, - 139, 211, 110, 243, 40, 17, 137, 211, 110, 243, 40, 17, 153, 211, 110, - 243, 40, 17, 173, 211, 110, 243, 40, 17, 181, 211, 110, 243, 40, 17, 176, - 211, 110, 243, 40, 17, 184, 211, 110, 243, 40, 1, 171, 211, 110, 243, 40, - 1, 250, 132, 211, 110, 243, 40, 1, 251, 201, 211, 110, 243, 40, 1, 251, - 71, 211, 110, 243, 40, 1, 251, 156, 211, 110, 243, 40, 1, 220, 101, 211, - 110, 243, 40, 1, 252, 116, 211, 110, 243, 40, 1, 252, 117, 211, 110, 243, - 40, 1, 252, 115, 211, 110, 243, 40, 1, 252, 109, 211, 110, 243, 40, 1, - 219, 122, 211, 110, 243, 40, 1, 223, 40, 211, 110, 243, 40, 1, 223, 171, - 211, 110, 243, 40, 1, 223, 62, 211, 110, 243, 40, 1, 223, 49, 211, 110, - 243, 40, 1, 218, 203, 211, 110, 243, 40, 1, 196, 156, 211, 110, 243, 40, - 1, 196, 154, 211, 110, 243, 40, 1, 196, 79, 211, 110, 243, 40, 1, 196, - 17, 211, 110, 243, 40, 1, 219, 214, 211, 110, 243, 40, 1, 234, 14, 211, - 110, 243, 40, 1, 234, 148, 211, 110, 243, 40, 1, 234, 61, 211, 110, 243, - 40, 1, 233, 240, 211, 110, 243, 40, 1, 219, 19, 211, 110, 243, 40, 1, - 211, 14, 211, 110, 243, 40, 1, 211, 165, 211, 110, 243, 40, 1, 210, 255, - 211, 110, 243, 40, 1, 211, 124, 211, 110, 243, 40, 215, 140, 197, 93, - 211, 110, 243, 40, 231, 198, 197, 94, 211, 110, 243, 40, 215, 134, 197, - 94, 211, 110, 243, 40, 207, 61, 211, 110, 243, 40, 209, 217, 211, 110, - 243, 40, 251, 192, 211, 110, 243, 40, 208, 145, 215, 130, 211, 110, 243, - 40, 208, 145, 54, 215, 130, 42, 2, 1, 206, 108, 195, 150, 42, 2, 1, 218, - 244, 237, 101, 42, 2, 1, 214, 201, 74, 42, 2, 1, 193, 76, 233, 236, 42, - 2, 1, 199, 195, 199, 140, 42, 2, 1, 198, 216, 199, 140, 42, 2, 1, 199, - 195, 229, 240, 57, 42, 2, 1, 199, 195, 192, 95, 42, 2, 1, 196, 104, 196, - 124, 100, 215, 141, 6, 1, 251, 81, 100, 215, 141, 6, 1, 249, 51, 100, - 215, 141, 6, 1, 231, 173, 100, 215, 141, 6, 1, 236, 105, 100, 215, 141, - 6, 1, 234, 61, 100, 215, 141, 6, 1, 195, 46, 100, 215, 141, 6, 1, 191, - 80, 100, 215, 141, 6, 1, 199, 188, 100, 215, 141, 6, 1, 223, 134, 100, - 215, 141, 6, 1, 222, 61, 100, 215, 141, 6, 1, 219, 239, 100, 215, 141, 6, - 1, 217, 70, 100, 215, 141, 6, 1, 214, 202, 100, 215, 141, 6, 1, 211, 93, - 100, 215, 141, 6, 1, 210, 121, 100, 215, 141, 6, 1, 191, 67, 100, 215, - 141, 6, 1, 207, 158, 100, 215, 141, 6, 1, 205, 137, 100, 215, 141, 6, 1, - 199, 174, 100, 215, 141, 6, 1, 196, 109, 100, 215, 141, 6, 1, 209, 211, - 100, 215, 141, 6, 1, 221, 176, 100, 215, 141, 6, 1, 231, 45, 100, 215, - 141, 6, 1, 208, 74, 100, 215, 141, 6, 1, 203, 64, 100, 215, 141, 6, 1, - 243, 33, 100, 215, 141, 6, 1, 247, 80, 100, 215, 141, 6, 1, 222, 207, - 100, 215, 141, 6, 1, 242, 226, 100, 215, 141, 6, 1, 246, 193, 100, 215, - 141, 6, 1, 192, 218, 100, 215, 141, 6, 1, 222, 222, 100, 215, 141, 6, 1, - 230, 54, 100, 215, 141, 6, 1, 229, 213, 100, 215, 141, 6, 1, 229, 113, - 100, 215, 141, 6, 1, 193, 123, 100, 215, 141, 6, 1, 229, 242, 100, 215, - 141, 6, 1, 228, 235, 100, 215, 141, 6, 1, 232, 238, 100, 215, 141, 6, 1, - 192, 14, 100, 215, 141, 6, 1, 234, 80, 100, 215, 141, 6, 1, 152, 231, - 173, 100, 215, 141, 6, 1, 251, 178, 100, 215, 141, 6, 1, 251, 218, 100, - 215, 141, 6, 1, 229, 240, 57, 100, 215, 141, 6, 1, 220, 92, 57, 200, 192, - 208, 145, 248, 117, 200, 161, 200, 192, 208, 145, 248, 117, 210, 145, - 200, 192, 208, 145, 248, 117, 208, 132, 200, 192, 208, 145, 248, 117, - 247, 97, 200, 192, 208, 145, 248, 117, 219, 149, 205, 116, 200, 192, 208, - 145, 248, 117, 222, 115, 205, 116, 200, 192, 208, 145, 248, 117, 237, - 242, 205, 116, 200, 192, 208, 145, 248, 117, 249, 104, 205, 116, 195, - 147, 163, 222, 31, 195, 147, 163, 203, 125, 195, 147, 163, 208, 218, 195, - 147, 3, 213, 173, 195, 147, 3, 192, 117, 216, 64, 200, 152, 195, 147, - 163, 192, 117, 251, 197, 223, 121, 200, 152, 195, 147, 163, 192, 117, - 223, 121, 200, 152, 195, 147, 163, 192, 117, 222, 19, 223, 121, 200, 152, - 195, 147, 163, 247, 74, 60, 195, 147, 163, 192, 117, 222, 19, 223, 121, - 200, 153, 205, 83, 195, 147, 163, 54, 200, 152, 195, 147, 163, 197, 221, - 200, 152, 195, 147, 163, 222, 19, 251, 22, 195, 147, 163, 75, 60, 195, - 147, 163, 103, 183, 60, 195, 147, 163, 115, 183, 60, 195, 147, 163, 206, - 191, 222, 30, 223, 121, 200, 152, 195, 147, 163, 250, 129, 223, 121, 200, - 152, 195, 147, 3, 195, 33, 200, 152, 195, 147, 3, 195, 33, 196, 150, 195, - 147, 3, 207, 13, 195, 33, 196, 150, 195, 147, 3, 195, 33, 251, 22, 195, - 147, 3, 207, 13, 195, 33, 251, 22, 195, 147, 3, 195, 33, 196, 151, 4, - 199, 210, 195, 147, 3, 195, 33, 251, 23, 4, 199, 210, 195, 147, 3, 251, - 21, 251, 37, 195, 147, 3, 251, 21, 249, 70, 195, 147, 3, 251, 21, 195, - 175, 195, 147, 3, 251, 21, 195, 176, 4, 199, 210, 195, 147, 3, 198, 121, - 195, 147, 3, 229, 148, 177, 251, 20, 195, 147, 3, 177, 251, 20, 195, 147, - 3, 206, 65, 177, 251, 20, 195, 147, 3, 251, 21, 196, 158, 215, 121, 195, - 147, 3, 250, 216, 195, 147, 3, 206, 117, 250, 216, 195, 147, 163, 247, - 74, 56, 195, 147, 3, 222, 210, 195, 147, 3, 196, 71, 195, 147, 3, 250, - 127, 195, 147, 163, 206, 184, 56, 195, 147, 163, 54, 206, 184, 56, 195, - 147, 3, 54, 251, 21, 251, 37, 8, 1, 2, 6, 65, 8, 1, 2, 6, 251, 229, 8, 2, - 1, 152, 251, 229, 8, 1, 2, 6, 249, 32, 250, 70, 8, 1, 2, 6, 247, 145, 8, - 1, 2, 6, 238, 80, 8, 1, 2, 6, 233, 206, 8, 1, 2, 6, 73, 8, 2, 1, 152, - 211, 66, 73, 8, 2, 1, 152, 70, 8, 1, 2, 6, 223, 7, 8, 1, 2, 6, 222, 125, - 8, 1, 2, 6, 220, 119, 4, 105, 8, 1, 2, 6, 218, 147, 8, 1, 2, 6, 207, 13, - 215, 47, 8, 1, 2, 6, 74, 8, 1, 2, 6, 211, 66, 74, 8, 2, 1, 202, 201, 74, - 8, 2, 1, 202, 201, 211, 66, 74, 8, 2, 1, 202, 201, 186, 4, 105, 8, 2, 1, - 152, 211, 139, 8, 1, 2, 6, 211, 9, 8, 2, 1, 198, 49, 134, 74, 8, 2, 1, - 248, 29, 134, 74, 8, 1, 2, 6, 210, 226, 8, 1, 2, 6, 207, 13, 148, 8, 1, - 2, 6, 152, 148, 8, 1, 2, 6, 200, 39, 8, 1, 2, 6, 69, 8, 2, 1, 202, 201, - 69, 8, 2, 1, 202, 201, 236, 251, 69, 8, 2, 1, 202, 201, 152, 218, 147, 8, - 1, 2, 6, 196, 8, 8, 1, 2, 6, 193, 221, 8, 1, 2, 6, 191, 166, 8, 1, 2, 6, - 233, 137, 8, 1, 195, 17, 219, 240, 201, 211, 8, 1, 251, 178, 35, 1, 2, 6, - 231, 174, 35, 1, 2, 6, 220, 7, 35, 1, 2, 6, 209, 176, 35, 1, 2, 6, 206, - 254, 35, 1, 2, 6, 208, 169, 42, 1, 2, 6, 234, 97, 59, 1, 6, 65, 59, 1, 6, - 251, 229, 59, 1, 6, 250, 70, 59, 1, 6, 249, 32, 250, 70, 59, 1, 6, 238, - 80, 59, 1, 6, 73, 59, 1, 6, 207, 13, 73, 59, 1, 6, 232, 14, 59, 1, 6, - 230, 83, 59, 1, 6, 70, 59, 1, 6, 223, 7, 59, 1, 6, 222, 125, 59, 1, 6, - 170, 59, 1, 6, 218, 147, 59, 1, 6, 215, 47, 59, 1, 6, 207, 13, 215, 47, - 59, 1, 6, 74, 59, 1, 6, 211, 9, 59, 1, 6, 210, 226, 59, 1, 6, 148, 59, 1, - 6, 200, 39, 59, 1, 6, 69, 59, 1, 6, 193, 221, 59, 1, 2, 65, 59, 1, 2, - 152, 65, 59, 1, 2, 251, 109, 59, 1, 2, 152, 251, 229, 59, 1, 2, 250, 70, - 59, 1, 2, 238, 80, 59, 1, 2, 73, 59, 1, 2, 205, 81, 59, 1, 2, 211, 66, - 73, 59, 1, 2, 152, 211, 66, 73, 59, 1, 2, 232, 14, 59, 1, 2, 152, 70, 59, - 1, 2, 222, 125, 59, 1, 2, 218, 147, 59, 1, 2, 234, 46, 59, 1, 2, 74, 59, - 1, 2, 211, 66, 74, 59, 1, 2, 198, 49, 134, 74, 59, 1, 2, 248, 29, 134, - 74, 59, 1, 2, 210, 226, 59, 1, 2, 200, 39, 59, 1, 2, 69, 59, 1, 2, 202, - 201, 69, 59, 1, 2, 152, 218, 147, 59, 1, 2, 196, 8, 59, 1, 2, 251, 178, - 59, 1, 2, 248, 162, 59, 1, 2, 35, 231, 174, 59, 1, 2, 237, 61, 59, 1, 2, - 35, 209, 202, 59, 1, 2, 243, 47, 8, 200, 225, 2, 1, 70, 8, 200, 225, 2, - 1, 148, 8, 200, 225, 2, 1, 69, 8, 200, 225, 2, 1, 196, 8, 35, 200, 225, - 2, 1, 248, 162, 35, 200, 225, 2, 1, 231, 174, 35, 200, 225, 2, 1, 206, - 254, 35, 200, 225, 2, 1, 209, 202, 35, 200, 225, 2, 1, 243, 47, 8, 2, 1, - 196, 148, 8, 2, 1, 78, 4, 82, 198, 147, 8, 2, 1, 238, 81, 4, 82, 198, - 147, 8, 2, 1, 233, 135, 4, 82, 198, 147, 8, 2, 1, 218, 148, 4, 82, 198, - 147, 8, 2, 1, 215, 48, 4, 82, 198, 147, 8, 2, 1, 210, 227, 4, 82, 198, - 147, 8, 2, 1, 207, 217, 4, 82, 198, 147, 8, 2, 1, 207, 217, 4, 232, 193, - 24, 82, 198, 147, 8, 2, 1, 206, 4, 4, 82, 198, 147, 8, 2, 1, 200, 40, 4, - 82, 198, 147, 8, 2, 1, 191, 167, 4, 82, 198, 147, 8, 2, 1, 152, 232, 14, - 59, 1, 42, 234, 61, 8, 2, 1, 223, 87, 232, 14, 8, 2, 1, 199, 47, 4, 201, - 27, 8, 2, 6, 1, 228, 44, 4, 105, 8, 2, 1, 223, 56, 4, 105, 8, 2, 1, 210, - 227, 4, 105, 8, 2, 6, 1, 126, 4, 105, 8, 2, 1, 196, 67, 4, 105, 8, 2, 1, - 78, 4, 210, 182, 106, 8, 2, 1, 238, 81, 4, 210, 182, 106, 8, 2, 1, 233, - 135, 4, 210, 182, 106, 8, 2, 1, 232, 15, 4, 210, 182, 106, 8, 2, 1, 222, - 126, 4, 210, 182, 106, 8, 2, 1, 220, 119, 4, 210, 182, 106, 8, 2, 1, 218, - 148, 4, 210, 182, 106, 8, 2, 1, 215, 48, 4, 210, 182, 106, 8, 2, 1, 210, - 227, 4, 210, 182, 106, 8, 2, 1, 207, 217, 4, 210, 182, 106, 8, 2, 1, 206, - 4, 4, 210, 182, 106, 8, 2, 1, 233, 227, 4, 210, 182, 106, 8, 2, 1, 196, - 9, 4, 210, 182, 106, 8, 2, 1, 192, 236, 4, 210, 182, 106, 8, 2, 1, 191, - 167, 4, 210, 182, 106, 8, 2, 1, 41, 4, 207, 19, 106, 8, 2, 1, 251, 110, - 4, 207, 19, 106, 8, 2, 1, 238, 81, 4, 228, 219, 24, 199, 210, 8, 2, 1, - 234, 227, 4, 207, 19, 106, 8, 2, 1, 211, 66, 234, 227, 4, 207, 19, 106, - 8, 2, 1, 207, 13, 211, 66, 234, 227, 4, 207, 19, 106, 8, 2, 1, 205, 82, - 4, 207, 19, 106, 8, 2, 1, 228, 44, 4, 207, 19, 106, 8, 2, 1, 211, 66, - 186, 4, 207, 19, 106, 8, 2, 1, 233, 227, 4, 207, 19, 106, 8, 2, 1, 126, - 4, 207, 19, 106, 8, 2, 1, 233, 138, 4, 207, 19, 106, 59, 1, 2, 152, 251, - 109, 59, 1, 2, 247, 145, 59, 1, 2, 247, 146, 4, 238, 128, 59, 1, 2, 233, - 206, 59, 1, 2, 207, 13, 211, 66, 73, 59, 1, 2, 233, 134, 59, 1, 2, 236, - 95, 223, 8, 4, 105, 59, 1, 2, 27, 232, 14, 59, 1, 2, 152, 230, 83, 59, 1, - 2, 228, 44, 4, 105, 59, 1, 2, 223, 55, 59, 1, 2, 6, 70, 59, 1, 2, 6, 228, - 44, 4, 105, 59, 1, 2, 223, 8, 4, 238, 165, 59, 1, 2, 220, 119, 4, 207, - 19, 106, 59, 1, 2, 220, 119, 4, 210, 182, 106, 59, 1, 2, 6, 170, 59, 1, - 2, 218, 148, 4, 106, 59, 1, 2, 152, 218, 148, 4, 177, 219, 188, 59, 1, 2, - 215, 48, 4, 45, 106, 59, 1, 2, 215, 48, 4, 207, 19, 106, 59, 1, 2, 6, - 215, 47, 59, 1, 2, 249, 32, 74, 59, 1, 2, 209, 202, 59, 1, 2, 206, 4, 4, - 106, 59, 1, 2, 233, 226, 59, 1, 2, 200, 40, 4, 210, 182, 106, 59, 1, 2, - 126, 164, 59, 1, 2, 196, 66, 59, 1, 2, 6, 69, 59, 1, 2, 196, 9, 4, 106, - 59, 1, 2, 152, 196, 8, 59, 1, 2, 191, 166, 59, 1, 2, 191, 167, 4, 207, - 19, 106, 59, 1, 2, 191, 167, 4, 238, 128, 59, 1, 2, 233, 137, 59, 1, 2, - 199, 10, 33, 235, 94, 230, 177, 252, 8, 33, 235, 94, 251, 251, 252, 8, - 33, 202, 54, 60, 33, 200, 159, 77, 33, 217, 124, 33, 230, 174, 33, 217, - 122, 33, 251, 248, 33, 230, 175, 33, 251, 249, 33, 8, 2, 1, 207, 217, 60, - 33, 247, 243, 33, 217, 123, 33, 54, 242, 210, 56, 33, 211, 127, 56, 33, - 191, 21, 60, 33, 223, 41, 60, 33, 196, 59, 56, 33, 196, 42, 56, 33, 8, 2, - 1, 232, 163, 211, 66, 41, 56, 33, 8, 2, 1, 251, 229, 33, 8, 2, 1, 251, - 18, 33, 8, 2, 1, 250, 96, 33, 8, 2, 1, 247, 146, 246, 243, 33, 8, 2, 1, - 223, 87, 238, 80, 33, 8, 2, 1, 233, 206, 33, 8, 2, 1, 232, 14, 33, 8, 1, - 2, 6, 232, 14, 33, 8, 2, 1, 222, 125, 33, 8, 2, 1, 170, 33, 8, 1, 2, 6, - 170, 33, 8, 1, 2, 6, 218, 147, 33, 8, 2, 1, 215, 47, 33, 8, 1, 2, 6, 215, - 47, 33, 8, 1, 2, 6, 148, 33, 8, 2, 1, 207, 217, 206, 111, 33, 8, 2, 1, - 206, 3, 33, 8, 2, 1, 177, 206, 3, 33, 8, 2, 1, 191, 166, 33, 8, 2, 1, - 251, 109, 33, 8, 2, 1, 250, 70, 33, 8, 2, 1, 248, 162, 33, 8, 2, 1, 205, - 81, 33, 8, 2, 1, 233, 134, 33, 8, 2, 1, 220, 119, 4, 54, 82, 198, 147, - 33, 8, 2, 1, 186, 4, 155, 246, 231, 105, 33, 8, 2, 1, 210, 226, 33, 8, 2, - 1, 233, 226, 33, 8, 2, 1, 126, 4, 155, 246, 231, 105, 33, 8, 2, 1, 193, - 221, 33, 8, 2, 1, 41, 4, 236, 253, 33, 8, 2, 1, 186, 4, 236, 253, 33, 8, - 2, 1, 126, 4, 236, 253, 33, 132, 199, 224, 56, 33, 222, 10, 95, 187, 33, - 222, 10, 95, 219, 200, 33, 75, 95, 219, 200, 33, 193, 76, 223, 65, 247, - 237, 60, 33, 75, 248, 183, 219, 200, 33, 237, 70, 77, 33, 54, 223, 65, - 247, 245, 60, 33, 251, 114, 234, 3, 118, 60, 33, 45, 250, 186, 56, 33, - 50, 250, 186, 24, 143, 250, 186, 60, 8, 6, 1, 41, 4, 206, 184, 60, 8, 2, - 1, 41, 4, 206, 184, 60, 8, 6, 1, 78, 4, 75, 56, 8, 2, 1, 78, 4, 75, 56, - 8, 6, 1, 78, 4, 75, 60, 8, 2, 1, 78, 4, 75, 60, 8, 6, 1, 78, 4, 219, 89, - 60, 8, 2, 1, 78, 4, 219, 89, 60, 8, 6, 1, 247, 146, 4, 246, 244, 24, 251, - 250, 8, 2, 1, 247, 146, 4, 246, 244, 24, 251, 250, 8, 6, 1, 238, 81, 4, - 75, 56, 8, 2, 1, 238, 81, 4, 75, 56, 8, 6, 1, 238, 81, 4, 75, 60, 8, 2, - 1, 238, 81, 4, 75, 60, 8, 6, 1, 238, 81, 4, 219, 89, 60, 8, 2, 1, 238, - 81, 4, 219, 89, 60, 8, 6, 1, 238, 81, 4, 246, 243, 8, 2, 1, 238, 81, 4, - 246, 243, 8, 6, 1, 238, 81, 4, 242, 210, 60, 8, 2, 1, 238, 81, 4, 242, - 210, 60, 8, 6, 1, 234, 227, 4, 217, 126, 24, 230, 176, 8, 2, 1, 234, 227, - 4, 217, 126, 24, 230, 176, 8, 6, 1, 234, 227, 4, 217, 126, 24, 251, 250, - 8, 2, 1, 234, 227, 4, 217, 126, 24, 251, 250, 8, 6, 1, 234, 227, 4, 242, - 210, 60, 8, 2, 1, 234, 227, 4, 242, 210, 60, 8, 6, 1, 234, 227, 4, 198, - 148, 60, 8, 2, 1, 234, 227, 4, 198, 148, 60, 8, 6, 1, 234, 227, 4, 246, - 244, 24, 247, 244, 8, 2, 1, 234, 227, 4, 246, 244, 24, 247, 244, 8, 6, 1, - 233, 135, 4, 75, 56, 8, 2, 1, 233, 135, 4, 75, 56, 8, 6, 1, 232, 15, 4, - 217, 125, 8, 2, 1, 232, 15, 4, 217, 125, 8, 6, 1, 230, 84, 4, 75, 56, 8, - 2, 1, 230, 84, 4, 75, 56, 8, 6, 1, 230, 84, 4, 75, 60, 8, 2, 1, 230, 84, - 4, 75, 60, 8, 6, 1, 230, 84, 4, 236, 253, 8, 2, 1, 230, 84, 4, 236, 253, - 8, 6, 1, 230, 84, 4, 246, 243, 8, 2, 1, 230, 84, 4, 246, 243, 8, 6, 1, - 230, 84, 4, 247, 245, 60, 8, 2, 1, 230, 84, 4, 247, 245, 60, 8, 6, 1, - 228, 44, 4, 198, 148, 60, 8, 2, 1, 228, 44, 4, 198, 148, 60, 8, 6, 1, - 228, 44, 4, 236, 254, 24, 251, 250, 8, 2, 1, 228, 44, 4, 236, 254, 24, - 251, 250, 8, 6, 1, 222, 126, 4, 251, 250, 8, 2, 1, 222, 126, 4, 251, 250, - 8, 6, 1, 222, 126, 4, 75, 60, 8, 2, 1, 222, 126, 4, 75, 60, 8, 6, 1, 222, - 126, 4, 219, 89, 60, 8, 2, 1, 222, 126, 4, 219, 89, 60, 8, 6, 1, 220, - 119, 4, 75, 60, 8, 2, 1, 220, 119, 4, 75, 60, 8, 6, 1, 220, 119, 4, 75, - 248, 183, 24, 217, 125, 8, 2, 1, 220, 119, 4, 75, 248, 183, 24, 217, 125, - 8, 6, 1, 220, 119, 4, 219, 89, 60, 8, 2, 1, 220, 119, 4, 219, 89, 60, 8, - 6, 1, 220, 119, 4, 242, 210, 60, 8, 2, 1, 220, 119, 4, 242, 210, 60, 8, - 6, 1, 218, 148, 4, 251, 250, 8, 2, 1, 218, 148, 4, 251, 250, 8, 6, 1, - 218, 148, 4, 75, 56, 8, 2, 1, 218, 148, 4, 75, 56, 8, 6, 1, 218, 148, 4, - 75, 60, 8, 2, 1, 218, 148, 4, 75, 60, 8, 6, 1, 215, 48, 4, 75, 56, 8, 2, - 1, 215, 48, 4, 75, 56, 8, 6, 1, 215, 48, 4, 75, 60, 8, 2, 1, 215, 48, 4, - 75, 60, 8, 6, 1, 215, 48, 4, 219, 89, 60, 8, 2, 1, 215, 48, 4, 219, 89, - 60, 8, 6, 1, 215, 48, 4, 242, 210, 60, 8, 2, 1, 215, 48, 4, 242, 210, 60, - 8, 6, 1, 186, 4, 198, 148, 24, 251, 250, 8, 2, 1, 186, 4, 198, 148, 24, - 251, 250, 8, 6, 1, 186, 4, 198, 148, 24, 236, 253, 8, 2, 1, 186, 4, 198, - 148, 24, 236, 253, 8, 6, 1, 186, 4, 217, 126, 24, 230, 176, 8, 2, 1, 186, - 4, 217, 126, 24, 230, 176, 8, 6, 1, 186, 4, 217, 126, 24, 251, 250, 8, 2, - 1, 186, 4, 217, 126, 24, 251, 250, 8, 6, 1, 210, 227, 4, 251, 250, 8, 2, - 1, 210, 227, 4, 251, 250, 8, 6, 1, 210, 227, 4, 75, 56, 8, 2, 1, 210, - 227, 4, 75, 56, 8, 6, 1, 207, 217, 4, 75, 56, 8, 2, 1, 207, 217, 4, 75, - 56, 8, 6, 1, 207, 217, 4, 75, 60, 8, 2, 1, 207, 217, 4, 75, 60, 8, 6, 1, - 207, 217, 4, 75, 248, 183, 24, 217, 125, 8, 2, 1, 207, 217, 4, 75, 248, - 183, 24, 217, 125, 8, 6, 1, 207, 217, 4, 219, 89, 60, 8, 2, 1, 207, 217, - 4, 219, 89, 60, 8, 6, 1, 206, 4, 4, 75, 56, 8, 2, 1, 206, 4, 4, 75, 56, - 8, 6, 1, 206, 4, 4, 75, 60, 8, 2, 1, 206, 4, 4, 75, 60, 8, 6, 1, 206, 4, - 4, 251, 251, 24, 75, 56, 8, 2, 1, 206, 4, 4, 251, 251, 24, 75, 56, 8, 6, - 1, 206, 4, 4, 247, 45, 24, 75, 56, 8, 2, 1, 206, 4, 4, 247, 45, 24, 75, - 56, 8, 6, 1, 206, 4, 4, 75, 248, 183, 24, 75, 56, 8, 2, 1, 206, 4, 4, 75, - 248, 183, 24, 75, 56, 8, 6, 1, 200, 40, 4, 75, 56, 8, 2, 1, 200, 40, 4, - 75, 56, 8, 6, 1, 200, 40, 4, 75, 60, 8, 2, 1, 200, 40, 4, 75, 60, 8, 6, - 1, 200, 40, 4, 219, 89, 60, 8, 2, 1, 200, 40, 4, 219, 89, 60, 8, 6, 1, - 200, 40, 4, 242, 210, 60, 8, 2, 1, 200, 40, 4, 242, 210, 60, 8, 6, 1, - 126, 4, 236, 254, 60, 8, 2, 1, 126, 4, 236, 254, 60, 8, 6, 1, 126, 4, - 198, 148, 60, 8, 2, 1, 126, 4, 198, 148, 60, 8, 6, 1, 126, 4, 242, 210, - 60, 8, 2, 1, 126, 4, 242, 210, 60, 8, 6, 1, 126, 4, 198, 148, 24, 251, - 250, 8, 2, 1, 126, 4, 198, 148, 24, 251, 250, 8, 6, 1, 126, 4, 217, 126, - 24, 236, 253, 8, 2, 1, 126, 4, 217, 126, 24, 236, 253, 8, 6, 1, 196, 9, - 4, 198, 147, 8, 2, 1, 196, 9, 4, 198, 147, 8, 6, 1, 196, 9, 4, 75, 60, 8, - 2, 1, 196, 9, 4, 75, 60, 8, 6, 1, 193, 222, 4, 230, 176, 8, 2, 1, 193, - 222, 4, 230, 176, 8, 6, 1, 193, 222, 4, 251, 250, 8, 2, 1, 193, 222, 4, - 251, 250, 8, 6, 1, 193, 222, 4, 236, 253, 8, 2, 1, 193, 222, 4, 236, 253, - 8, 6, 1, 193, 222, 4, 75, 56, 8, 2, 1, 193, 222, 4, 75, 56, 8, 6, 1, 193, - 222, 4, 75, 60, 8, 2, 1, 193, 222, 4, 75, 60, 8, 6, 1, 192, 236, 4, 75, - 56, 8, 2, 1, 192, 236, 4, 75, 56, 8, 6, 1, 192, 236, 4, 236, 253, 8, 2, - 1, 192, 236, 4, 236, 253, 8, 6, 1, 192, 160, 4, 75, 56, 8, 2, 1, 192, - 160, 4, 75, 56, 8, 6, 1, 191, 167, 4, 242, 209, 8, 2, 1, 191, 167, 4, - 242, 209, 8, 6, 1, 191, 167, 4, 75, 60, 8, 2, 1, 191, 167, 4, 75, 60, 8, - 6, 1, 191, 167, 4, 219, 89, 60, 8, 2, 1, 191, 167, 4, 219, 89, 60, 8, 2, - 1, 230, 84, 4, 219, 89, 60, 8, 2, 1, 200, 40, 4, 236, 253, 8, 2, 1, 193, - 222, 4, 206, 184, 56, 8, 2, 1, 192, 160, 4, 206, 184, 56, 8, 2, 1, 41, 4, - 50, 134, 206, 183, 8, 2, 1, 177, 206, 4, 4, 75, 56, 8, 2, 1, 177, 206, 4, - 4, 236, 250, 105, 8, 2, 1, 177, 206, 4, 4, 136, 105, 8, 6, 1, 203, 122, - 206, 3, 8, 2, 1, 237, 61, 8, 6, 1, 41, 4, 75, 60, 8, 2, 1, 41, 4, 75, 60, - 8, 6, 1, 41, 4, 228, 219, 56, 8, 2, 1, 41, 4, 228, 219, 56, 8, 6, 1, 41, - 4, 242, 210, 24, 251, 250, 8, 2, 1, 41, 4, 242, 210, 24, 251, 250, 8, 6, - 1, 41, 4, 242, 210, 24, 230, 176, 8, 2, 1, 41, 4, 242, 210, 24, 230, 176, - 8, 6, 1, 41, 4, 242, 210, 24, 228, 219, 56, 8, 2, 1, 41, 4, 242, 210, 24, - 228, 219, 56, 8, 6, 1, 41, 4, 242, 210, 24, 198, 147, 8, 2, 1, 41, 4, - 242, 210, 24, 198, 147, 8, 6, 1, 41, 4, 242, 210, 24, 75, 60, 8, 2, 1, - 41, 4, 242, 210, 24, 75, 60, 8, 6, 1, 41, 4, 247, 245, 24, 251, 250, 8, - 2, 1, 41, 4, 247, 245, 24, 251, 250, 8, 6, 1, 41, 4, 247, 245, 24, 230, - 176, 8, 2, 1, 41, 4, 247, 245, 24, 230, 176, 8, 6, 1, 41, 4, 247, 245, - 24, 228, 219, 56, 8, 2, 1, 41, 4, 247, 245, 24, 228, 219, 56, 8, 6, 1, - 41, 4, 247, 245, 24, 198, 147, 8, 2, 1, 41, 4, 247, 245, 24, 198, 147, 8, - 6, 1, 41, 4, 247, 245, 24, 75, 60, 8, 2, 1, 41, 4, 247, 245, 24, 75, 60, - 8, 6, 1, 234, 227, 4, 75, 60, 8, 2, 1, 234, 227, 4, 75, 60, 8, 6, 1, 234, - 227, 4, 228, 219, 56, 8, 2, 1, 234, 227, 4, 228, 219, 56, 8, 6, 1, 234, - 227, 4, 198, 147, 8, 2, 1, 234, 227, 4, 198, 147, 8, 6, 1, 234, 227, 4, - 242, 210, 24, 251, 250, 8, 2, 1, 234, 227, 4, 242, 210, 24, 251, 250, 8, - 6, 1, 234, 227, 4, 242, 210, 24, 230, 176, 8, 2, 1, 234, 227, 4, 242, - 210, 24, 230, 176, 8, 6, 1, 234, 227, 4, 242, 210, 24, 228, 219, 56, 8, - 2, 1, 234, 227, 4, 242, 210, 24, 228, 219, 56, 8, 6, 1, 234, 227, 4, 242, - 210, 24, 198, 147, 8, 2, 1, 234, 227, 4, 242, 210, 24, 198, 147, 8, 6, 1, - 234, 227, 4, 242, 210, 24, 75, 60, 8, 2, 1, 234, 227, 4, 242, 210, 24, - 75, 60, 8, 6, 1, 228, 44, 4, 228, 219, 56, 8, 2, 1, 228, 44, 4, 228, 219, - 56, 8, 6, 1, 228, 44, 4, 75, 60, 8, 2, 1, 228, 44, 4, 75, 60, 8, 6, 1, - 186, 4, 75, 60, 8, 2, 1, 186, 4, 75, 60, 8, 6, 1, 186, 4, 228, 219, 56, - 8, 2, 1, 186, 4, 228, 219, 56, 8, 6, 1, 186, 4, 242, 210, 24, 251, 250, - 8, 2, 1, 186, 4, 242, 210, 24, 251, 250, 8, 6, 1, 186, 4, 242, 210, 24, - 230, 176, 8, 2, 1, 186, 4, 242, 210, 24, 230, 176, 8, 6, 1, 186, 4, 242, - 210, 24, 228, 219, 56, 8, 2, 1, 186, 4, 242, 210, 24, 228, 219, 56, 8, 6, - 1, 186, 4, 242, 210, 24, 198, 147, 8, 2, 1, 186, 4, 242, 210, 24, 198, - 147, 8, 6, 1, 186, 4, 242, 210, 24, 75, 60, 8, 2, 1, 186, 4, 242, 210, - 24, 75, 60, 8, 6, 1, 186, 4, 228, 157, 24, 251, 250, 8, 2, 1, 186, 4, - 228, 157, 24, 251, 250, 8, 6, 1, 186, 4, 228, 157, 24, 230, 176, 8, 2, 1, - 186, 4, 228, 157, 24, 230, 176, 8, 6, 1, 186, 4, 228, 157, 24, 228, 219, - 56, 8, 2, 1, 186, 4, 228, 157, 24, 228, 219, 56, 8, 6, 1, 186, 4, 228, - 157, 24, 198, 147, 8, 2, 1, 186, 4, 228, 157, 24, 198, 147, 8, 6, 1, 186, - 4, 228, 157, 24, 75, 60, 8, 2, 1, 186, 4, 228, 157, 24, 75, 60, 8, 6, 1, - 126, 4, 75, 60, 8, 2, 1, 126, 4, 75, 60, 8, 6, 1, 126, 4, 228, 219, 56, - 8, 2, 1, 126, 4, 228, 219, 56, 8, 6, 1, 126, 4, 228, 157, 24, 251, 250, - 8, 2, 1, 126, 4, 228, 157, 24, 251, 250, 8, 6, 1, 126, 4, 228, 157, 24, - 230, 176, 8, 2, 1, 126, 4, 228, 157, 24, 230, 176, 8, 6, 1, 126, 4, 228, - 157, 24, 228, 219, 56, 8, 2, 1, 126, 4, 228, 157, 24, 228, 219, 56, 8, 6, - 1, 126, 4, 228, 157, 24, 198, 147, 8, 2, 1, 126, 4, 228, 157, 24, 198, - 147, 8, 6, 1, 126, 4, 228, 157, 24, 75, 60, 8, 2, 1, 126, 4, 228, 157, - 24, 75, 60, 8, 6, 1, 192, 160, 4, 230, 176, 8, 2, 1, 192, 160, 4, 230, - 176, 8, 6, 1, 192, 160, 4, 75, 60, 8, 2, 1, 192, 160, 4, 75, 60, 8, 6, 1, - 192, 160, 4, 228, 219, 56, 8, 2, 1, 192, 160, 4, 228, 219, 56, 8, 6, 1, - 192, 160, 4, 198, 147, 8, 2, 1, 192, 160, 4, 198, 147, 8, 6, 1, 216, 65, - 219, 50, 8, 2, 1, 216, 65, 219, 50, 8, 6, 1, 216, 65, 196, 8, 8, 2, 1, - 216, 65, 196, 8, 8, 6, 1, 192, 160, 4, 218, 236, 8, 2, 1, 192, 160, 4, - 218, 236, 35, 2, 1, 251, 110, 4, 208, 162, 35, 2, 1, 251, 110, 4, 237, - 167, 35, 2, 1, 251, 110, 4, 208, 163, 24, 195, 166, 35, 2, 1, 251, 110, - 4, 237, 168, 24, 195, 166, 35, 2, 1, 251, 110, 4, 208, 163, 24, 210, 233, - 35, 2, 1, 251, 110, 4, 237, 168, 24, 210, 233, 35, 2, 1, 251, 110, 4, - 208, 163, 24, 209, 251, 35, 2, 1, 251, 110, 4, 237, 168, 24, 209, 251, - 35, 6, 1, 251, 110, 4, 208, 162, 35, 6, 1, 251, 110, 4, 237, 167, 35, 6, - 1, 251, 110, 4, 208, 163, 24, 195, 166, 35, 6, 1, 251, 110, 4, 237, 168, - 24, 195, 166, 35, 6, 1, 251, 110, 4, 208, 163, 24, 210, 233, 35, 6, 1, - 251, 110, 4, 237, 168, 24, 210, 233, 35, 6, 1, 251, 110, 4, 208, 163, 24, - 209, 251, 35, 6, 1, 251, 110, 4, 237, 168, 24, 209, 251, 35, 2, 1, 234, - 6, 4, 208, 162, 35, 2, 1, 234, 6, 4, 237, 167, 35, 2, 1, 234, 6, 4, 208, - 163, 24, 195, 166, 35, 2, 1, 234, 6, 4, 237, 168, 24, 195, 166, 35, 2, 1, - 234, 6, 4, 208, 163, 24, 210, 233, 35, 2, 1, 234, 6, 4, 237, 168, 24, - 210, 233, 35, 6, 1, 234, 6, 4, 208, 162, 35, 6, 1, 234, 6, 4, 237, 167, - 35, 6, 1, 234, 6, 4, 208, 163, 24, 195, 166, 35, 6, 1, 234, 6, 4, 237, - 168, 24, 195, 166, 35, 6, 1, 234, 6, 4, 208, 163, 24, 210, 233, 35, 6, 1, - 234, 6, 4, 237, 168, 24, 210, 233, 35, 2, 1, 233, 212, 4, 208, 162, 35, - 2, 1, 233, 212, 4, 237, 167, 35, 2, 1, 233, 212, 4, 208, 163, 24, 195, - 166, 35, 2, 1, 233, 212, 4, 237, 168, 24, 195, 166, 35, 2, 1, 233, 212, - 4, 208, 163, 24, 210, 233, 35, 2, 1, 233, 212, 4, 237, 168, 24, 210, 233, - 35, 2, 1, 233, 212, 4, 208, 163, 24, 209, 251, 35, 2, 1, 233, 212, 4, - 237, 168, 24, 209, 251, 35, 6, 1, 233, 212, 4, 208, 162, 35, 6, 1, 233, - 212, 4, 237, 167, 35, 6, 1, 233, 212, 4, 208, 163, 24, 195, 166, 35, 6, - 1, 233, 212, 4, 237, 168, 24, 195, 166, 35, 6, 1, 233, 212, 4, 208, 163, - 24, 210, 233, 35, 6, 1, 233, 212, 4, 237, 168, 24, 210, 233, 35, 6, 1, - 233, 212, 4, 208, 163, 24, 209, 251, 35, 6, 1, 233, 212, 4, 237, 168, 24, - 209, 251, 35, 2, 1, 223, 56, 4, 208, 162, 35, 2, 1, 223, 56, 4, 237, 167, - 35, 2, 1, 223, 56, 4, 208, 163, 24, 195, 166, 35, 2, 1, 223, 56, 4, 237, - 168, 24, 195, 166, 35, 2, 1, 223, 56, 4, 208, 163, 24, 210, 233, 35, 2, - 1, 223, 56, 4, 237, 168, 24, 210, 233, 35, 2, 1, 223, 56, 4, 208, 163, - 24, 209, 251, 35, 2, 1, 223, 56, 4, 237, 168, 24, 209, 251, 35, 6, 1, - 223, 56, 4, 208, 162, 35, 6, 1, 223, 56, 4, 237, 167, 35, 6, 1, 223, 56, - 4, 208, 163, 24, 195, 166, 35, 6, 1, 223, 56, 4, 237, 168, 24, 195, 166, - 35, 6, 1, 223, 56, 4, 208, 163, 24, 210, 233, 35, 6, 1, 223, 56, 4, 237, - 168, 24, 210, 233, 35, 6, 1, 223, 56, 4, 208, 163, 24, 209, 251, 35, 6, - 1, 223, 56, 4, 237, 168, 24, 209, 251, 35, 2, 1, 211, 97, 4, 208, 162, - 35, 2, 1, 211, 97, 4, 237, 167, 35, 2, 1, 211, 97, 4, 208, 163, 24, 195, - 166, 35, 2, 1, 211, 97, 4, 237, 168, 24, 195, 166, 35, 2, 1, 211, 97, 4, - 208, 163, 24, 210, 233, 35, 2, 1, 211, 97, 4, 237, 168, 24, 210, 233, 35, - 6, 1, 211, 97, 4, 208, 162, 35, 6, 1, 211, 97, 4, 237, 167, 35, 6, 1, - 211, 97, 4, 208, 163, 24, 195, 166, 35, 6, 1, 211, 97, 4, 237, 168, 24, - 195, 166, 35, 6, 1, 211, 97, 4, 208, 163, 24, 210, 233, 35, 6, 1, 211, - 97, 4, 237, 168, 24, 210, 233, 35, 2, 1, 196, 67, 4, 208, 162, 35, 2, 1, - 196, 67, 4, 237, 167, 35, 2, 1, 196, 67, 4, 208, 163, 24, 195, 166, 35, - 2, 1, 196, 67, 4, 237, 168, 24, 195, 166, 35, 2, 1, 196, 67, 4, 208, 163, - 24, 210, 233, 35, 2, 1, 196, 67, 4, 237, 168, 24, 210, 233, 35, 2, 1, - 196, 67, 4, 208, 163, 24, 209, 251, 35, 2, 1, 196, 67, 4, 237, 168, 24, - 209, 251, 35, 6, 1, 196, 67, 4, 237, 167, 35, 6, 1, 196, 67, 4, 237, 168, - 24, 195, 166, 35, 6, 1, 196, 67, 4, 237, 168, 24, 210, 233, 35, 6, 1, - 196, 67, 4, 237, 168, 24, 209, 251, 35, 2, 1, 211, 100, 4, 208, 162, 35, - 2, 1, 211, 100, 4, 237, 167, 35, 2, 1, 211, 100, 4, 208, 163, 24, 195, - 166, 35, 2, 1, 211, 100, 4, 237, 168, 24, 195, 166, 35, 2, 1, 211, 100, - 4, 208, 163, 24, 210, 233, 35, 2, 1, 211, 100, 4, 237, 168, 24, 210, 233, - 35, 2, 1, 211, 100, 4, 208, 163, 24, 209, 251, 35, 2, 1, 211, 100, 4, - 237, 168, 24, 209, 251, 35, 6, 1, 211, 100, 4, 208, 162, 35, 6, 1, 211, - 100, 4, 237, 167, 35, 6, 1, 211, 100, 4, 208, 163, 24, 195, 166, 35, 6, - 1, 211, 100, 4, 237, 168, 24, 195, 166, 35, 6, 1, 211, 100, 4, 208, 163, - 24, 210, 233, 35, 6, 1, 211, 100, 4, 237, 168, 24, 210, 233, 35, 6, 1, - 211, 100, 4, 208, 163, 24, 209, 251, 35, 6, 1, 211, 100, 4, 237, 168, 24, - 209, 251, 35, 2, 1, 251, 110, 4, 195, 166, 35, 2, 1, 251, 110, 4, 210, - 233, 35, 2, 1, 234, 6, 4, 195, 166, 35, 2, 1, 234, 6, 4, 210, 233, 35, 2, - 1, 233, 212, 4, 195, 166, 35, 2, 1, 233, 212, 4, 210, 233, 35, 2, 1, 223, - 56, 4, 195, 166, 35, 2, 1, 223, 56, 4, 210, 233, 35, 2, 1, 211, 97, 4, - 195, 166, 35, 2, 1, 211, 97, 4, 210, 233, 35, 2, 1, 196, 67, 4, 195, 166, - 35, 2, 1, 196, 67, 4, 210, 233, 35, 2, 1, 211, 100, 4, 195, 166, 35, 2, - 1, 211, 100, 4, 210, 233, 35, 2, 1, 251, 110, 4, 208, 163, 24, 191, 233, - 35, 2, 1, 251, 110, 4, 237, 168, 24, 191, 233, 35, 2, 1, 251, 110, 4, - 208, 163, 24, 195, 167, 24, 191, 233, 35, 2, 1, 251, 110, 4, 237, 168, - 24, 195, 167, 24, 191, 233, 35, 2, 1, 251, 110, 4, 208, 163, 24, 210, - 234, 24, 191, 233, 35, 2, 1, 251, 110, 4, 237, 168, 24, 210, 234, 24, - 191, 233, 35, 2, 1, 251, 110, 4, 208, 163, 24, 209, 252, 24, 191, 233, - 35, 2, 1, 251, 110, 4, 237, 168, 24, 209, 252, 24, 191, 233, 35, 6, 1, - 251, 110, 4, 208, 163, 24, 208, 177, 35, 6, 1, 251, 110, 4, 237, 168, 24, - 208, 177, 35, 6, 1, 251, 110, 4, 208, 163, 24, 195, 167, 24, 208, 177, - 35, 6, 1, 251, 110, 4, 237, 168, 24, 195, 167, 24, 208, 177, 35, 6, 1, - 251, 110, 4, 208, 163, 24, 210, 234, 24, 208, 177, 35, 6, 1, 251, 110, 4, - 237, 168, 24, 210, 234, 24, 208, 177, 35, 6, 1, 251, 110, 4, 208, 163, - 24, 209, 252, 24, 208, 177, 35, 6, 1, 251, 110, 4, 237, 168, 24, 209, - 252, 24, 208, 177, 35, 2, 1, 233, 212, 4, 208, 163, 24, 191, 233, 35, 2, - 1, 233, 212, 4, 237, 168, 24, 191, 233, 35, 2, 1, 233, 212, 4, 208, 163, - 24, 195, 167, 24, 191, 233, 35, 2, 1, 233, 212, 4, 237, 168, 24, 195, - 167, 24, 191, 233, 35, 2, 1, 233, 212, 4, 208, 163, 24, 210, 234, 24, - 191, 233, 35, 2, 1, 233, 212, 4, 237, 168, 24, 210, 234, 24, 191, 233, - 35, 2, 1, 233, 212, 4, 208, 163, 24, 209, 252, 24, 191, 233, 35, 2, 1, - 233, 212, 4, 237, 168, 24, 209, 252, 24, 191, 233, 35, 6, 1, 233, 212, 4, - 208, 163, 24, 208, 177, 35, 6, 1, 233, 212, 4, 237, 168, 24, 208, 177, - 35, 6, 1, 233, 212, 4, 208, 163, 24, 195, 167, 24, 208, 177, 35, 6, 1, - 233, 212, 4, 237, 168, 24, 195, 167, 24, 208, 177, 35, 6, 1, 233, 212, 4, - 208, 163, 24, 210, 234, 24, 208, 177, 35, 6, 1, 233, 212, 4, 237, 168, - 24, 210, 234, 24, 208, 177, 35, 6, 1, 233, 212, 4, 208, 163, 24, 209, - 252, 24, 208, 177, 35, 6, 1, 233, 212, 4, 237, 168, 24, 209, 252, 24, - 208, 177, 35, 2, 1, 211, 100, 4, 208, 163, 24, 191, 233, 35, 2, 1, 211, - 100, 4, 237, 168, 24, 191, 233, 35, 2, 1, 211, 100, 4, 208, 163, 24, 195, - 167, 24, 191, 233, 35, 2, 1, 211, 100, 4, 237, 168, 24, 195, 167, 24, - 191, 233, 35, 2, 1, 211, 100, 4, 208, 163, 24, 210, 234, 24, 191, 233, - 35, 2, 1, 211, 100, 4, 237, 168, 24, 210, 234, 24, 191, 233, 35, 2, 1, - 211, 100, 4, 208, 163, 24, 209, 252, 24, 191, 233, 35, 2, 1, 211, 100, 4, - 237, 168, 24, 209, 252, 24, 191, 233, 35, 6, 1, 211, 100, 4, 208, 163, - 24, 208, 177, 35, 6, 1, 211, 100, 4, 237, 168, 24, 208, 177, 35, 6, 1, - 211, 100, 4, 208, 163, 24, 195, 167, 24, 208, 177, 35, 6, 1, 211, 100, 4, - 237, 168, 24, 195, 167, 24, 208, 177, 35, 6, 1, 211, 100, 4, 208, 163, - 24, 210, 234, 24, 208, 177, 35, 6, 1, 211, 100, 4, 237, 168, 24, 210, - 234, 24, 208, 177, 35, 6, 1, 211, 100, 4, 208, 163, 24, 209, 252, 24, - 208, 177, 35, 6, 1, 211, 100, 4, 237, 168, 24, 209, 252, 24, 208, 177, - 35, 2, 1, 251, 110, 4, 194, 251, 35, 2, 1, 251, 110, 4, 217, 125, 35, 2, - 1, 251, 110, 4, 195, 167, 24, 191, 233, 35, 2, 1, 251, 110, 4, 191, 233, - 35, 2, 1, 251, 110, 4, 210, 234, 24, 191, 233, 35, 2, 1, 251, 110, 4, - 209, 251, 35, 2, 1, 251, 110, 4, 209, 252, 24, 191, 233, 35, 6, 1, 251, - 110, 4, 194, 251, 35, 6, 1, 251, 110, 4, 217, 125, 35, 6, 1, 251, 110, 4, - 195, 166, 35, 6, 1, 251, 110, 4, 210, 233, 35, 6, 1, 251, 110, 4, 208, - 177, 35, 221, 6, 35, 208, 177, 35, 208, 162, 35, 209, 251, 35, 236, 247, - 24, 209, 251, 35, 2, 1, 233, 212, 4, 195, 167, 24, 191, 233, 35, 2, 1, - 233, 212, 4, 191, 233, 35, 2, 1, 233, 212, 4, 210, 234, 24, 191, 233, 35, - 2, 1, 233, 212, 4, 209, 251, 35, 2, 1, 233, 212, 4, 209, 252, 24, 191, - 233, 35, 6, 1, 234, 6, 4, 195, 166, 35, 6, 1, 234, 6, 4, 210, 233, 35, 6, - 1, 233, 212, 4, 195, 166, 35, 6, 1, 233, 212, 4, 210, 233, 35, 6, 1, 233, - 212, 4, 208, 177, 35, 208, 163, 24, 195, 166, 35, 208, 163, 24, 210, 233, - 35, 208, 163, 24, 209, 251, 35, 2, 1, 223, 56, 4, 194, 251, 35, 2, 1, - 223, 56, 4, 217, 125, 35, 2, 1, 223, 56, 4, 236, 247, 24, 195, 166, 35, - 2, 1, 223, 56, 4, 236, 247, 24, 210, 233, 35, 2, 1, 223, 56, 4, 209, 251, - 35, 2, 1, 223, 56, 4, 236, 247, 24, 209, 251, 35, 6, 1, 223, 56, 4, 194, - 251, 35, 6, 1, 223, 56, 4, 217, 125, 35, 6, 1, 223, 56, 4, 195, 166, 35, - 6, 1, 223, 56, 4, 210, 233, 35, 237, 168, 24, 195, 166, 35, 237, 168, 24, - 210, 233, 35, 237, 168, 24, 209, 251, 35, 2, 1, 196, 67, 4, 194, 251, 35, - 2, 1, 196, 67, 4, 217, 125, 35, 2, 1, 196, 67, 4, 236, 247, 24, 195, 166, - 35, 2, 1, 196, 67, 4, 236, 247, 24, 210, 233, 35, 2, 1, 206, 255, 4, 208, - 162, 35, 2, 1, 206, 255, 4, 237, 167, 35, 2, 1, 196, 67, 4, 209, 251, 35, - 2, 1, 196, 67, 4, 236, 247, 24, 209, 251, 35, 6, 1, 196, 67, 4, 194, 251, - 35, 6, 1, 196, 67, 4, 217, 125, 35, 6, 1, 196, 67, 4, 195, 166, 35, 6, 1, - 196, 67, 4, 210, 233, 35, 6, 1, 206, 255, 4, 237, 167, 35, 236, 247, 24, - 195, 166, 35, 236, 247, 24, 210, 233, 35, 195, 166, 35, 2, 1, 211, 100, - 4, 195, 167, 24, 191, 233, 35, 2, 1, 211, 100, 4, 191, 233, 35, 2, 1, - 211, 100, 4, 210, 234, 24, 191, 233, 35, 2, 1, 211, 100, 4, 209, 251, 35, - 2, 1, 211, 100, 4, 209, 252, 24, 191, 233, 35, 6, 1, 211, 97, 4, 195, - 166, 35, 6, 1, 211, 97, 4, 210, 233, 35, 6, 1, 211, 100, 4, 195, 166, 35, - 6, 1, 211, 100, 4, 210, 233, 35, 6, 1, 211, 100, 4, 208, 177, 35, 210, - 233, 35, 237, 167, 234, 62, 208, 24, 234, 73, 208, 24, 234, 62, 201, 242, - 234, 73, 201, 242, 198, 214, 201, 242, 232, 88, 201, 242, 202, 129, 201, - 242, 232, 228, 201, 242, 208, 145, 201, 242, 198, 255, 201, 242, 230, 46, - 201, 242, 191, 78, 193, 73, 201, 242, 191, 78, 193, 73, 213, 16, 191, 78, - 193, 73, 222, 169, 219, 191, 77, 206, 194, 77, 228, 58, 213, 17, 228, 58, - 232, 228, 237, 170, 234, 62, 237, 170, 234, 73, 237, 170, 228, 209, 164, - 54, 81, 219, 88, 54, 131, 219, 88, 45, 202, 165, 207, 247, 77, 50, 202, - 165, 207, 247, 77, 202, 165, 218, 218, 207, 247, 77, 202, 165, 229, 100, - 207, 247, 77, 45, 54, 207, 247, 77, 50, 54, 207, 247, 77, 54, 218, 218, - 207, 247, 77, 54, 229, 100, 207, 247, 77, 237, 223, 54, 237, 223, 247, - 200, 197, 234, 247, 200, 91, 75, 219, 212, 103, 75, 219, 212, 228, 209, - 234, 78, 228, 56, 209, 54, 219, 89, 204, 5, 210, 118, 204, 5, 219, 191, - 234, 71, 206, 194, 234, 71, 209, 27, 236, 187, 232, 105, 219, 191, 210, - 242, 206, 194, 210, 242, 214, 201, 213, 24, 201, 242, 210, 5, 216, 32, - 57, 210, 5, 199, 91, 198, 225, 57, 208, 208, 54, 208, 208, 197, 221, 208, - 208, 207, 13, 208, 208, 207, 13, 54, 208, 208, 207, 13, 197, 221, 208, - 208, 247, 48, 202, 165, 219, 195, 251, 65, 207, 247, 77, 202, 165, 206, - 198, 251, 65, 207, 247, 77, 207, 78, 77, 54, 233, 175, 77, 223, 74, 210, - 244, 196, 96, 246, 192, 198, 173, 247, 49, 223, 91, 209, 54, 250, 141, - 228, 59, 247, 200, 232, 80, 202, 92, 45, 51, 248, 6, 4, 208, 2, 50, 51, - 248, 6, 4, 208, 2, 54, 208, 8, 77, 208, 8, 233, 175, 77, 233, 175, 208, - 8, 77, 198, 123, 3, 233, 213, 207, 13, 209, 133, 57, 62, 117, 247, 200, - 62, 96, 247, 200, 131, 250, 143, 207, 13, 204, 20, 242, 172, 196, 73, - 103, 250, 142, 251, 127, 195, 81, 242, 24, 216, 18, 57, 200, 125, 237, - 170, 223, 65, 196, 96, 232, 147, 208, 145, 77, 115, 75, 208, 144, 208, - 20, 208, 208, 232, 90, 75, 208, 144, 232, 185, 75, 208, 144, 103, 75, - 208, 144, 232, 90, 75, 77, 235, 94, 238, 170, 197, 233, 81, 232, 90, 236, - 94, 216, 194, 13, 201, 242, 193, 23, 222, 169, 232, 40, 250, 250, 223, - 63, 198, 139, 223, 63, 204, 5, 223, 63, 209, 73, 219, 191, 223, 31, 206, - 194, 223, 31, 232, 197, 201, 9, 223, 31, 209, 27, 236, 187, 223, 31, 223, - 104, 200, 71, 200, 143, 251, 253, 200, 71, 200, 143, 223, 104, 9, 232, - 107, 203, 128, 251, 253, 9, 232, 107, 203, 128, 214, 194, 17, 203, 129, - 213, 20, 17, 203, 129, 200, 177, 191, 77, 200, 177, 8, 2, 1, 70, 200, - 177, 137, 200, 177, 153, 200, 177, 173, 200, 177, 181, 200, 177, 176, - 200, 177, 184, 200, 177, 107, 57, 200, 177, 216, 17, 200, 177, 234, 1, - 57, 200, 177, 45, 210, 103, 200, 177, 50, 210, 103, 200, 177, 8, 2, 1, - 215, 47, 200, 225, 191, 77, 200, 225, 108, 200, 225, 109, 200, 225, 139, - 200, 225, 137, 200, 225, 153, 200, 225, 173, 200, 225, 181, 200, 225, - 176, 200, 225, 184, 200, 225, 107, 57, 200, 225, 216, 17, 200, 225, 234, - 1, 57, 200, 225, 45, 210, 103, 200, 225, 50, 210, 103, 8, 200, 225, 2, 1, - 65, 8, 200, 225, 2, 1, 73, 8, 200, 225, 2, 1, 74, 8, 200, 225, 2, 1, 192, - 235, 8, 200, 225, 2, 1, 205, 81, 8, 200, 225, 2, 1, 230, 83, 8, 200, 225, - 2, 1, 222, 125, 8, 200, 225, 2, 1, 170, 8, 200, 225, 2, 1, 218, 147, 8, - 200, 225, 2, 1, 215, 47, 8, 200, 225, 2, 1, 210, 226, 8, 200, 225, 2, 1, - 206, 3, 8, 200, 225, 2, 1, 200, 39, 233, 192, 57, 242, 36, 57, 238, 153, - 57, 232, 68, 232, 73, 57, 219, 67, 57, 216, 33, 57, 214, 220, 57, 209, - 236, 57, 206, 31, 57, 193, 31, 57, 214, 66, 203, 94, 57, 236, 104, 57, - 233, 193, 57, 221, 111, 57, 197, 77, 57, 235, 72, 57, 231, 101, 210, 18, - 57, 209, 233, 57, 230, 141, 57, 250, 103, 57, 228, 135, 57, 246, 245, 57, - 219, 57, 198, 28, 57, 201, 221, 57, 199, 88, 57, 223, 119, 206, 31, 57, - 197, 56, 219, 67, 57, 213, 6, 87, 57, 217, 68, 57, 206, 54, 57, 219, 241, - 57, 248, 99, 57, 202, 17, 57, 33, 45, 229, 236, 56, 33, 50, 229, 236, 56, - 33, 177, 81, 219, 89, 210, 245, 33, 203, 35, 81, 219, 89, 210, 245, 33, - 251, 34, 63, 56, 33, 242, 173, 63, 56, 33, 45, 63, 56, 33, 50, 63, 56, - 33, 206, 184, 210, 245, 33, 242, 173, 206, 184, 210, 245, 33, 251, 34, - 206, 184, 210, 245, 33, 115, 183, 56, 33, 232, 90, 183, 56, 33, 234, 57, - 242, 218, 33, 234, 57, 201, 185, 33, 234, 57, 236, 243, 33, 234, 57, 242, - 219, 249, 91, 33, 45, 50, 63, 56, 33, 234, 57, 205, 71, 33, 234, 57, 221, - 193, 33, 234, 57, 196, 64, 209, 51, 197, 237, 33, 207, 14, 202, 19, 210, - 245, 33, 54, 81, 201, 23, 210, 245, 33, 251, 44, 113, 33, 197, 221, 196, - 98, 33, 193, 76, 247, 237, 56, 33, 117, 63, 210, 245, 33, 177, 54, 202, - 19, 210, 245, 33, 96, 229, 236, 4, 178, 235, 74, 33, 117, 229, 236, 4, - 178, 235, 74, 33, 45, 63, 60, 33, 50, 63, 60, 33, 250, 144, 56, 252, 3, - 211, 134, 251, 242, 118, 199, 29, 200, 235, 235, 85, 6, 247, 145, 237, - 80, 246, 235, 246, 230, 219, 89, 113, 247, 50, 211, 134, 247, 104, 196, - 108, 233, 194, 238, 247, 205, 67, 237, 80, 233, 50, 27, 2, 232, 14, 27, - 6, 230, 83, 248, 89, 6, 230, 83, 235, 85, 6, 230, 83, 209, 95, 238, 247, - 209, 95, 238, 248, 138, 103, 209, 176, 27, 6, 70, 248, 89, 6, 70, 27, 6, - 170, 27, 2, 170, 220, 119, 78, 249, 38, 113, 235, 85, 6, 215, 47, 212, - 119, 57, 202, 0, 207, 90, 238, 214, 27, 6, 210, 226, 235, 85, 6, 210, - 226, 235, 85, 6, 208, 97, 27, 6, 148, 248, 89, 6, 148, 235, 85, 6, 148, - 208, 216, 199, 203, 207, 26, 203, 252, 77, 199, 102, 57, 198, 18, 87, 57, - 195, 133, 235, 85, 6, 191, 166, 211, 8, 57, 211, 123, 57, 223, 65, 211, - 123, 57, 248, 89, 6, 191, 166, 152, 35, 2, 1, 223, 55, 221, 234, 57, 251, - 59, 57, 27, 6, 250, 70, 248, 89, 6, 247, 145, 233, 218, 113, 27, 2, 73, - 27, 6, 73, 27, 6, 233, 134, 152, 6, 233, 134, 27, 6, 218, 147, 27, 2, 74, - 130, 113, 248, 165, 113, 231, 2, 113, 237, 207, 113, 223, 109, 201, 254, - 206, 117, 6, 208, 97, 233, 53, 57, 235, 85, 2, 209, 176, 235, 85, 2, 231, - 174, 235, 85, 6, 231, 174, 235, 85, 6, 209, 176, 235, 85, 215, 46, 200, - 196, 152, 49, 6, 232, 14, 152, 49, 6, 170, 207, 13, 49, 6, 170, 152, 49, - 6, 192, 159, 235, 85, 43, 6, 238, 80, 235, 85, 43, 2, 238, 80, 235, 85, - 43, 2, 73, 235, 85, 43, 2, 70, 235, 85, 43, 2, 223, 7, 208, 181, 219, 88, - 152, 251, 86, 210, 5, 57, 251, 159, 152, 2, 233, 134, 16, 39, 205, 146, - 201, 254, 193, 243, 232, 80, 91, 203, 238, 193, 243, 232, 80, 91, 213, - 154, 193, 243, 232, 80, 91, 199, 81, 193, 243, 232, 80, 91, 198, 251, - 193, 243, 232, 80, 103, 198, 248, 193, 243, 232, 80, 91, 232, 233, 193, - 243, 232, 80, 103, 232, 232, 193, 243, 232, 80, 115, 232, 232, 193, 243, - 232, 80, 232, 90, 232, 232, 193, 243, 232, 80, 91, 202, 119, 193, 243, - 232, 80, 232, 185, 202, 117, 193, 243, 232, 80, 91, 234, 116, 193, 243, - 232, 80, 115, 234, 114, 193, 243, 232, 80, 232, 185, 234, 114, 193, 243, - 232, 80, 203, 242, 234, 114, 232, 80, 212, 120, 108, 206, 131, 212, 121, - 108, 206, 131, 212, 121, 109, 206, 131, 212, 121, 139, 206, 131, 212, - 121, 137, 206, 131, 212, 121, 153, 206, 131, 212, 121, 173, 206, 131, - 212, 121, 181, 206, 131, 212, 121, 176, 206, 131, 212, 121, 184, 206, - 131, 212, 121, 199, 90, 206, 131, 212, 121, 234, 84, 206, 131, 212, 121, - 197, 33, 206, 131, 212, 121, 232, 230, 206, 131, 212, 121, 91, 228, 109, - 206, 131, 212, 121, 232, 185, 228, 109, 206, 131, 212, 121, 91, 188, 2, - 206, 131, 212, 121, 108, 2, 206, 131, 212, 121, 109, 2, 206, 131, 212, - 121, 139, 2, 206, 131, 212, 121, 137, 2, 206, 131, 212, 121, 153, 2, 206, - 131, 212, 121, 173, 2, 206, 131, 212, 121, 181, 2, 206, 131, 212, 121, - 176, 2, 206, 131, 212, 121, 184, 2, 206, 131, 212, 121, 199, 90, 2, 206, - 131, 212, 121, 234, 84, 2, 206, 131, 212, 121, 197, 33, 2, 206, 131, 212, - 121, 232, 230, 2, 206, 131, 212, 121, 91, 228, 109, 2, 206, 131, 212, - 121, 232, 185, 228, 109, 2, 206, 131, 212, 121, 91, 188, 206, 131, 212, - 121, 91, 198, 225, 247, 146, 238, 80, 206, 131, 212, 121, 232, 185, 188, - 206, 131, 212, 121, 199, 91, 188, 206, 131, 212, 121, 207, 13, 91, 228, - 109, 8, 2, 1, 207, 13, 247, 145, 206, 131, 212, 121, 202, 131, 219, 236, - 20, 206, 131, 212, 121, 232, 231, 234, 166, 20, 206, 131, 212, 121, 232, - 231, 188, 206, 131, 212, 121, 91, 228, 110, 188, 193, 243, 232, 80, 191, - 78, 198, 248, 152, 17, 109, 152, 17, 139, 117, 55, 196, 62, 55, 96, 55, - 235, 75, 55, 45, 50, 55, 132, 143, 55, 185, 193, 103, 55, 185, 234, 160, - 55, 201, 253, 234, 160, 55, 201, 253, 193, 103, 55, 117, 63, 4, 105, 96, - 63, 4, 105, 117, 193, 137, 55, 96, 193, 137, 55, 117, 103, 229, 201, 55, - 196, 62, 103, 229, 201, 55, 96, 103, 229, 201, 55, 235, 75, 103, 229, - 201, 55, 117, 63, 4, 199, 210, 96, 63, 4, 199, 210, 117, 63, 232, 60, - 164, 196, 62, 63, 232, 60, 164, 96, 63, 232, 60, 164, 235, 75, 63, 232, - 60, 164, 132, 143, 63, 4, 249, 24, 117, 63, 4, 106, 96, 63, 4, 106, 117, - 63, 4, 218, 236, 96, 63, 4, 218, 236, 45, 50, 193, 137, 55, 45, 50, 63, - 4, 105, 235, 75, 191, 21, 55, 196, 62, 63, 4, 198, 131, 219, 190, 196, - 62, 63, 4, 198, 131, 206, 192, 235, 75, 63, 4, 198, 131, 219, 190, 235, - 75, 63, 4, 198, 131, 206, 192, 96, 63, 4, 238, 211, 235, 74, 235, 75, 63, - 4, 238, 211, 219, 190, 251, 34, 198, 49, 204, 23, 55, 242, 173, 198, 49, - 204, 23, 55, 185, 193, 103, 63, 118, 177, 164, 117, 63, 118, 249, 38, - 138, 96, 63, 118, 164, 251, 34, 211, 66, 242, 219, 55, 242, 173, 211, 66, - 242, 219, 55, 117, 229, 236, 4, 178, 196, 61, 117, 229, 236, 4, 178, 235, - 74, 196, 62, 229, 236, 4, 178, 206, 192, 196, 62, 229, 236, 4, 178, 219, - 190, 96, 229, 236, 4, 178, 196, 61, 96, 229, 236, 4, 178, 235, 74, 235, - 75, 229, 236, 4, 178, 206, 192, 235, 75, 229, 236, 4, 178, 219, 190, 96, - 63, 138, 117, 55, 196, 62, 63, 117, 80, 235, 75, 55, 117, 63, 138, 96, - 55, 117, 210, 186, 250, 181, 196, 62, 210, 186, 250, 181, 96, 210, 186, - 250, 181, 235, 75, 210, 186, 250, 181, 117, 229, 236, 138, 96, 229, 235, - 96, 229, 236, 138, 117, 229, 235, 117, 54, 63, 4, 105, 45, 50, 54, 63, 4, - 105, 96, 54, 63, 4, 105, 117, 54, 55, 196, 62, 54, 55, 96, 54, 55, 235, - 75, 54, 55, 45, 50, 54, 55, 132, 143, 54, 55, 185, 193, 103, 54, 55, 185, - 234, 160, 54, 55, 201, 253, 234, 160, 54, 55, 201, 253, 193, 103, 54, 55, - 117, 197, 221, 55, 96, 197, 221, 55, 117, 201, 178, 55, 96, 201, 178, 55, - 196, 62, 63, 4, 54, 105, 235, 75, 63, 4, 54, 105, 117, 237, 169, 55, 196, - 62, 237, 169, 55, 96, 237, 169, 55, 235, 75, 237, 169, 55, 117, 63, 118, - 164, 96, 63, 118, 164, 117, 64, 55, 196, 62, 64, 55, 96, 64, 55, 235, 75, - 64, 55, 196, 62, 64, 63, 232, 60, 164, 196, 62, 64, 63, 211, 94, 210, 43, - 196, 62, 64, 63, 211, 94, 210, 44, 4, 228, 209, 164, 196, 62, 64, 63, - 211, 94, 210, 44, 4, 81, 164, 196, 62, 64, 54, 55, 196, 62, 64, 54, 63, - 211, 94, 210, 43, 96, 64, 63, 232, 60, 193, 164, 185, 193, 103, 63, 118, - 238, 210, 201, 253, 234, 160, 63, 118, 238, 210, 132, 143, 64, 55, 50, - 63, 4, 2, 242, 218, 235, 75, 63, 117, 80, 196, 62, 55, 115, 96, 250, 181, - 117, 63, 4, 81, 105, 96, 63, 4, 81, 105, 45, 50, 63, 4, 81, 105, 117, 63, - 4, 54, 81, 105, 96, 63, 4, 54, 81, 105, 45, 50, 63, 4, 54, 81, 105, 117, - 211, 63, 55, 96, 211, 63, 55, 45, 50, 211, 63, 55, 39, 251, 123, 242, 20, - 210, 95, 236, 227, 199, 19, 233, 170, 199, 19, 236, 119, 212, 255, 233, - 171, 234, 63, 203, 247, 223, 123, 214, 231, 234, 89, 211, 134, 212, 255, - 251, 82, 234, 89, 211, 134, 2, 234, 89, 211, 134, 238, 241, 250, 170, - 216, 171, 236, 119, 212, 255, 238, 243, 250, 170, 216, 171, 2, 238, 241, - 250, 170, 216, 171, 234, 53, 80, 208, 183, 215, 46, 208, 193, 215, 46, - 238, 218, 215, 46, 200, 196, 216, 18, 57, 216, 16, 57, 75, 209, 73, 236, - 155, 202, 92, 203, 248, 216, 17, 250, 144, 211, 55, 206, 184, 211, 55, - 247, 201, 211, 55, 51, 206, 123, 238, 144, 206, 123, 232, 83, 206, 123, - 208, 179, 159, 223, 111, 50, 251, 64, 251, 64, 216, 207, 251, 64, 201, - 220, 251, 64, 236, 158, 236, 119, 212, 255, 236, 162, 210, 109, 159, 212, - 255, 210, 109, 159, 219, 5, 251, 74, 219, 5, 211, 45, 223, 71, 196, 88, - 223, 85, 54, 223, 85, 197, 221, 223, 85, 238, 235, 223, 85, 200, 166, - 223, 85, 195, 8, 223, 85, 242, 173, 223, 85, 242, 173, 238, 235, 223, 85, - 251, 34, 238, 235, 223, 85, 199, 18, 248, 209, 207, 121, 208, 180, 75, - 216, 17, 233, 178, 231, 107, 208, 180, 228, 224, 198, 148, 211, 55, 207, - 13, 198, 147, 223, 65, 219, 221, 206, 3, 202, 167, 193, 136, 193, 10, - 208, 193, 212, 255, 198, 147, 216, 18, 198, 147, 250, 136, 234, 3, 159, - 212, 255, 250, 136, 234, 3, 159, 250, 246, 234, 3, 159, 250, 246, 247, - 170, 212, 255, 251, 252, 234, 3, 159, 214, 91, 250, 246, 213, 8, 251, - 252, 234, 3, 159, 251, 114, 234, 3, 159, 212, 255, 251, 114, 234, 3, 159, - 251, 114, 234, 3, 211, 46, 234, 3, 159, 197, 221, 198, 147, 251, 124, - 234, 3, 159, 233, 250, 159, 231, 106, 233, 250, 159, 236, 228, 248, 159, - 250, 248, 199, 29, 219, 96, 231, 106, 234, 3, 159, 250, 246, 234, 3, 118, - 211, 46, 199, 29, 223, 150, 211, 134, 223, 150, 80, 211, 46, 250, 246, - 234, 3, 159, 242, 36, 234, 0, 234, 1, 242, 35, 206, 184, 223, 135, 234, - 3, 159, 206, 184, 234, 3, 159, 238, 203, 159, 233, 217, 233, 255, 159, - 201, 98, 234, 0, 237, 62, 234, 3, 159, 234, 3, 118, 247, 157, 237, 81, - 216, 207, 247, 156, 208, 6, 234, 3, 159, 212, 255, 234, 3, 159, 227, 244, - 159, 212, 255, 227, 244, 159, 201, 30, 233, 250, 159, 219, 156, 211, 46, - 234, 3, 159, 230, 170, 211, 46, 234, 3, 159, 219, 156, 138, 234, 3, 159, - 230, 170, 138, 234, 3, 159, 219, 156, 247, 170, 212, 255, 234, 3, 159, - 230, 170, 247, 170, 212, 255, 234, 3, 159, 215, 129, 219, 155, 215, 129, - 230, 169, 248, 159, 212, 255, 233, 250, 159, 212, 255, 219, 155, 212, - 255, 230, 169, 214, 91, 219, 156, 213, 8, 234, 3, 159, 214, 91, 230, 170, - 213, 8, 234, 3, 159, 219, 156, 211, 46, 233, 250, 159, 230, 170, 211, 46, - 233, 250, 159, 214, 91, 219, 156, 213, 8, 233, 250, 159, 214, 91, 230, - 170, 213, 8, 233, 250, 159, 219, 156, 211, 46, 230, 169, 230, 170, 211, - 46, 219, 155, 214, 91, 219, 156, 213, 8, 230, 169, 214, 91, 230, 170, - 213, 8, 219, 155, 208, 224, 200, 215, 208, 225, 211, 46, 234, 3, 159, - 200, 216, 211, 46, 234, 3, 159, 208, 225, 211, 46, 233, 250, 159, 200, - 216, 211, 46, 233, 250, 159, 236, 119, 212, 255, 208, 227, 236, 119, 212, - 255, 200, 217, 200, 224, 211, 134, 200, 176, 211, 134, 212, 255, 41, 200, - 224, 211, 134, 212, 255, 41, 200, 176, 211, 134, 200, 224, 80, 211, 46, - 234, 3, 159, 200, 176, 80, 211, 46, 234, 3, 159, 214, 91, 41, 200, 224, - 80, 213, 8, 234, 3, 159, 214, 91, 41, 200, 176, 80, 213, 8, 234, 3, 159, - 200, 224, 80, 4, 212, 255, 234, 3, 159, 200, 176, 80, 4, 212, 255, 234, - 3, 159, 215, 109, 215, 110, 215, 111, 215, 110, 196, 88, 51, 223, 150, - 211, 134, 51, 211, 36, 211, 134, 51, 223, 150, 80, 211, 46, 234, 3, 159, - 51, 211, 36, 80, 211, 46, 234, 3, 159, 51, 247, 63, 51, 238, 134, 47, - 209, 73, 47, 216, 17, 47, 198, 139, 47, 236, 155, 202, 92, 47, 75, 211, - 55, 47, 206, 184, 211, 55, 47, 250, 144, 211, 55, 47, 234, 0, 47, 237, - 170, 112, 209, 73, 112, 216, 17, 112, 198, 139, 112, 75, 211, 55, 50, - 199, 223, 45, 199, 223, 143, 199, 223, 132, 199, 223, 250, 147, 215, 240, - 197, 197, 232, 113, 197, 221, 81, 249, 38, 50, 197, 53, 54, 81, 249, 38, - 54, 50, 197, 53, 236, 119, 212, 255, 208, 172, 212, 255, 197, 197, 236, - 119, 212, 255, 232, 114, 214, 94, 54, 81, 249, 38, 54, 50, 197, 53, 208, - 225, 196, 101, 207, 60, 200, 216, 196, 101, 207, 60, 213, 5, 200, 239, - 211, 134, 238, 241, 250, 170, 213, 5, 200, 238, 213, 5, 200, 239, 80, - 211, 46, 234, 3, 159, 238, 241, 250, 170, 213, 5, 200, 239, 211, 46, 234, - 3, 159, 211, 36, 211, 134, 223, 150, 211, 134, 215, 116, 229, 157, 238, - 252, 217, 8, 223, 82, 192, 192, 214, 210, 213, 7, 50, 251, 65, 4, 250, - 222, 50, 197, 237, 215, 46, 219, 5, 251, 74, 215, 46, 219, 5, 211, 45, - 215, 46, 223, 71, 215, 46, 196, 88, 236, 244, 211, 55, 75, 211, 55, 201, - 98, 211, 55, 236, 155, 198, 139, 248, 15, 45, 213, 5, 233, 52, 204, 19, - 208, 193, 50, 213, 5, 233, 52, 204, 19, 208, 193, 45, 204, 19, 208, 193, - 50, 204, 19, 208, 193, 207, 13, 198, 148, 234, 0, 238, 124, 219, 5, 211, - 45, 238, 124, 219, 5, 251, 74, 54, 200, 223, 54, 200, 175, 54, 223, 71, - 54, 196, 88, 209, 107, 234, 3, 24, 210, 109, 159, 219, 156, 4, 236, 96, - 230, 170, 4, 236, 96, 195, 80, 215, 129, 219, 155, 195, 80, 215, 129, - 230, 169, 219, 156, 234, 3, 118, 211, 46, 230, 169, 230, 170, 234, 3, - 118, 211, 46, 219, 155, 234, 3, 118, 211, 46, 219, 155, 234, 3, 118, 211, - 46, 230, 169, 234, 3, 118, 211, 46, 208, 224, 234, 3, 118, 211, 46, 200, - 215, 236, 119, 212, 255, 208, 228, 211, 46, 234, 2, 236, 119, 212, 255, - 200, 218, 211, 46, 234, 2, 212, 255, 51, 223, 150, 80, 211, 46, 234, 3, - 159, 212, 255, 51, 211, 36, 80, 211, 46, 234, 3, 159, 51, 223, 150, 80, - 211, 46, 212, 255, 234, 3, 159, 51, 211, 36, 80, 211, 46, 212, 255, 234, - 3, 159, 219, 156, 247, 170, 212, 255, 233, 250, 159, 230, 170, 247, 170, - 212, 255, 233, 250, 159, 208, 225, 247, 170, 212, 255, 233, 250, 159, - 200, 216, 247, 170, 212, 255, 233, 250, 159, 212, 255, 213, 5, 200, 239, - 211, 134, 236, 119, 212, 255, 238, 243, 250, 170, 213, 5, 200, 238, 212, - 255, 213, 5, 200, 239, 80, 211, 46, 234, 3, 159, 236, 119, 212, 255, 238, - 243, 250, 170, 213, 5, 200, 239, 211, 46, 234, 2, 81, 234, 78, 216, 64, - 228, 209, 234, 78, 132, 50, 236, 250, 234, 78, 143, 50, 236, 250, 234, - 78, 234, 89, 80, 4, 177, 228, 209, 105, 234, 89, 80, 4, 81, 249, 38, 250, - 133, 234, 53, 80, 228, 209, 105, 2, 234, 89, 80, 4, 81, 249, 38, 250, - 133, 234, 53, 80, 228, 209, 105, 234, 89, 80, 4, 75, 56, 234, 89, 80, 4, - 210, 252, 2, 234, 89, 80, 4, 210, 252, 234, 89, 80, 4, 196, 99, 234, 89, - 80, 4, 103, 228, 209, 201, 10, 238, 241, 4, 177, 228, 209, 105, 238, 241, - 4, 81, 249, 38, 250, 133, 234, 53, 80, 228, 209, 105, 2, 238, 241, 4, 81, - 249, 38, 250, 133, 234, 53, 80, 228, 209, 105, 238, 241, 4, 210, 252, 2, - 238, 241, 4, 210, 252, 191, 167, 212, 253, 249, 81, 216, 170, 236, 245, - 57, 234, 92, 55, 228, 141, 132, 250, 185, 143, 250, 185, 208, 187, 209, - 239, 193, 133, 219, 88, 45, 246, 238, 50, 246, 238, 45, 232, 153, 50, - 232, 153, 248, 29, 50, 238, 172, 248, 29, 45, 238, 172, 198, 49, 50, 238, - 172, 198, 49, 45, 238, 172, 207, 13, 212, 255, 57, 51, 218, 210, 250, - 222, 205, 38, 205, 47, 199, 102, 207, 91, 209, 18, 223, 116, 195, 53, - 201, 185, 209, 100, 80, 223, 81, 57, 152, 212, 255, 57, 193, 143, 228, - 143, 198, 49, 45, 238, 210, 198, 49, 50, 238, 210, 248, 29, 45, 238, 210, - 248, 29, 50, 238, 210, 198, 49, 134, 223, 85, 248, 29, 134, 223, 85, 232, - 55, 202, 60, 132, 250, 186, 248, 160, 103, 228, 209, 249, 26, 211, 48, - 221, 197, 233, 246, 118, 199, 29, 187, 192, 236, 223, 135, 41, 207, 88, - 248, 14, 221, 195, 219, 195, 251, 65, 248, 5, 206, 198, 251, 65, 248, 5, - 233, 246, 118, 199, 29, 219, 200, 248, 171, 206, 183, 238, 91, 251, 124, - 250, 194, 200, 70, 198, 34, 206, 36, 236, 207, 211, 37, 239, 0, 199, 176, - 202, 76, 238, 199, 238, 198, 251, 9, 232, 38, 16, 228, 37, 251, 9, 232, - 38, 16, 201, 176, 208, 24, 251, 9, 232, 38, 16, 208, 25, 234, 2, 251, 9, - 232, 38, 16, 208, 25, 236, 162, 251, 9, 232, 38, 16, 208, 25, 236, 243, - 251, 9, 232, 38, 16, 208, 25, 222, 161, 251, 9, 232, 38, 16, 208, 25, - 242, 218, 251, 9, 232, 38, 16, 242, 219, 201, 66, 251, 9, 232, 38, 16, - 242, 219, 222, 161, 251, 9, 232, 38, 16, 202, 93, 164, 251, 9, 232, 38, - 16, 249, 92, 164, 251, 9, 232, 38, 16, 208, 25, 202, 92, 251, 9, 232, 38, - 16, 208, 25, 249, 91, 251, 9, 232, 38, 16, 208, 25, 219, 155, 251, 9, - 232, 38, 16, 208, 25, 230, 169, 251, 9, 232, 38, 16, 117, 195, 173, 251, - 9, 232, 38, 16, 96, 195, 173, 251, 9, 232, 38, 16, 208, 25, 117, 55, 251, - 9, 232, 38, 16, 208, 25, 96, 55, 251, 9, 232, 38, 16, 242, 219, 249, 91, - 251, 9, 232, 38, 16, 143, 199, 224, 196, 99, 251, 9, 232, 38, 16, 237, - 62, 201, 66, 251, 9, 232, 38, 16, 208, 25, 143, 247, 48, 251, 9, 232, 38, - 16, 208, 25, 237, 61, 251, 9, 232, 38, 16, 143, 199, 224, 222, 161, 251, - 9, 232, 38, 16, 196, 62, 195, 173, 251, 9, 232, 38, 16, 208, 25, 196, 62, - 55, 251, 9, 232, 38, 16, 132, 199, 224, 210, 252, 251, 9, 232, 38, 16, - 237, 74, 201, 66, 251, 9, 232, 38, 16, 208, 25, 132, 247, 48, 251, 9, - 232, 38, 16, 208, 25, 237, 73, 251, 9, 232, 38, 16, 132, 199, 224, 222, - 161, 251, 9, 232, 38, 16, 235, 75, 195, 173, 251, 9, 232, 38, 16, 208, - 25, 235, 75, 55, 251, 9, 232, 38, 16, 207, 246, 196, 99, 251, 9, 232, 38, - 16, 237, 62, 196, 99, 251, 9, 232, 38, 16, 236, 244, 196, 99, 251, 9, - 232, 38, 16, 222, 162, 196, 99, 251, 9, 232, 38, 16, 242, 219, 196, 99, - 251, 9, 232, 38, 16, 132, 203, 48, 222, 161, 251, 9, 232, 38, 16, 207, - 246, 208, 24, 251, 9, 232, 38, 16, 242, 219, 201, 97, 251, 9, 232, 38, - 16, 208, 25, 242, 35, 251, 9, 232, 38, 16, 132, 199, 224, 236, 253, 251, - 9, 232, 38, 16, 237, 74, 236, 253, 251, 9, 232, 38, 16, 201, 98, 236, - 253, 251, 9, 232, 38, 16, 222, 162, 236, 253, 251, 9, 232, 38, 16, 242, - 219, 236, 253, 251, 9, 232, 38, 16, 143, 203, 48, 201, 66, 251, 9, 232, - 38, 16, 45, 203, 48, 201, 66, 251, 9, 232, 38, 16, 198, 148, 236, 253, - 251, 9, 232, 38, 16, 230, 170, 236, 253, 251, 9, 232, 38, 16, 242, 27, - 164, 251, 9, 232, 38, 16, 237, 74, 198, 147, 251, 9, 232, 38, 16, 191, - 20, 251, 9, 232, 38, 16, 201, 67, 198, 147, 251, 9, 232, 38, 16, 204, 21, - 196, 99, 251, 9, 232, 38, 16, 208, 25, 212, 255, 234, 2, 251, 9, 232, 38, - 16, 208, 25, 208, 7, 251, 9, 232, 38, 16, 143, 247, 49, 198, 147, 251, 9, - 232, 38, 16, 132, 247, 49, 198, 147, 251, 9, 232, 38, 16, 223, 55, 251, - 9, 232, 38, 16, 206, 254, 251, 9, 232, 38, 16, 211, 99, 251, 9, 232, 38, - 16, 251, 110, 196, 99, 251, 9, 232, 38, 16, 234, 6, 196, 99, 251, 9, 232, - 38, 16, 223, 56, 196, 99, 251, 9, 232, 38, 16, 211, 100, 196, 99, 251, 9, - 232, 38, 16, 251, 109, 212, 255, 243, 78, 77, 50, 251, 65, 4, 235, 75, - 191, 21, 55, 203, 16, 211, 66, 248, 14, 248, 186, 113, 81, 219, 89, 4, - 82, 236, 96, 223, 91, 113, 238, 236, 196, 97, 113, 236, 180, 196, 97, - 113, 234, 65, 113, 239, 15, 113, 64, 51, 4, 246, 230, 81, 219, 88, 234, - 36, 113, 251, 101, 221, 198, 113, 229, 170, 113, 47, 228, 209, 249, 38, - 4, 212, 252, 47, 197, 238, 235, 79, 247, 230, 242, 219, 4, 213, 2, 55, - 196, 95, 113, 215, 199, 113, 228, 54, 113, 211, 64, 230, 82, 113, 211, - 64, 220, 117, 113, 210, 83, 113, 210, 82, 113, 236, 189, 238, 122, 16, - 232, 107, 109, 202, 24, 113, 251, 9, 232, 38, 16, 208, 24, 237, 93, 204, - 6, 221, 198, 113, 208, 210, 210, 194, 214, 59, 210, 194, 208, 205, 205, - 72, 113, 242, 190, 205, 72, 113, 45, 210, 104, 116, 106, 45, 210, 104, - 233, 162, 45, 210, 104, 110, 106, 50, 210, 104, 116, 106, 50, 210, 104, - 233, 162, 50, 210, 104, 110, 106, 45, 51, 248, 6, 116, 238, 210, 45, 51, - 248, 6, 233, 162, 45, 51, 248, 6, 110, 238, 210, 50, 51, 248, 6, 116, - 238, 210, 50, 51, 248, 6, 233, 162, 50, 51, 248, 6, 110, 238, 210, 45, - 238, 124, 248, 6, 116, 106, 45, 238, 124, 248, 6, 82, 209, 166, 45, 238, - 124, 248, 6, 110, 106, 238, 124, 248, 6, 233, 162, 50, 238, 124, 248, 6, - 116, 106, 50, 238, 124, 248, 6, 82, 209, 166, 50, 238, 124, 248, 6, 110, - 106, 223, 86, 233, 162, 228, 209, 219, 89, 233, 162, 116, 45, 211, 46, - 110, 50, 238, 124, 248, 6, 205, 48, 116, 50, 211, 46, 110, 45, 238, 124, - 248, 6, 205, 48, 200, 197, 198, 48, 200, 197, 248, 28, 198, 49, 51, 248, - 5, 248, 29, 51, 248, 5, 248, 29, 51, 248, 6, 138, 198, 49, 51, 248, 5, - 48, 16, 248, 28, 45, 81, 111, 219, 88, 50, 81, 111, 219, 88, 228, 209, - 205, 92, 219, 87, 228, 209, 205, 92, 219, 86, 228, 209, 205, 92, 219, 85, - 228, 209, 205, 92, 219, 84, 237, 52, 16, 155, 81, 24, 198, 49, 187, 237, - 52, 16, 155, 81, 24, 248, 29, 187, 237, 52, 16, 155, 81, 4, 242, 218, - 237, 52, 16, 155, 143, 24, 228, 209, 4, 242, 218, 237, 52, 16, 155, 132, - 24, 228, 209, 4, 242, 218, 237, 52, 16, 155, 81, 4, 197, 237, 237, 52, - 16, 155, 143, 24, 228, 209, 4, 197, 237, 237, 52, 16, 155, 132, 24, 228, - 209, 4, 197, 237, 237, 52, 16, 155, 81, 24, 193, 136, 237, 52, 16, 155, - 143, 24, 228, 209, 4, 193, 136, 237, 52, 16, 155, 132, 24, 228, 209, 4, - 193, 136, 237, 52, 16, 155, 143, 24, 228, 208, 237, 52, 16, 155, 132, 24, - 228, 208, 237, 52, 16, 155, 81, 24, 198, 49, 219, 200, 237, 52, 16, 155, - 81, 24, 248, 29, 219, 200, 51, 232, 120, 207, 18, 113, 234, 106, 113, 81, - 219, 89, 233, 162, 216, 140, 247, 244, 216, 140, 177, 138, 203, 34, 216, - 140, 203, 35, 138, 218, 251, 216, 140, 177, 138, 103, 203, 20, 216, 140, - 103, 203, 21, 138, 218, 251, 216, 140, 103, 203, 21, 222, 170, 216, 140, - 197, 217, 216, 140, 199, 60, 216, 140, 210, 13, 234, 164, 230, 155, 232, - 32, 198, 49, 210, 103, 248, 29, 210, 103, 198, 49, 238, 124, 248, 5, 248, - 29, 238, 124, 248, 5, 198, 49, 198, 37, 203, 98, 248, 5, 248, 29, 198, - 37, 203, 98, 248, 5, 64, 198, 1, 248, 171, 206, 184, 4, 242, 218, 201, - 46, 232, 164, 252, 12, 238, 121, 234, 91, 223, 71, 237, 93, 233, 166, - 113, 62, 206, 198, 54, 197, 237, 62, 219, 195, 54, 197, 237, 62, 196, 72, - 54, 197, 237, 62, 235, 78, 54, 197, 237, 62, 206, 198, 54, 197, 238, 4, - 81, 164, 62, 219, 195, 54, 197, 238, 4, 81, 164, 62, 206, 198, 197, 238, - 4, 54, 81, 164, 251, 150, 242, 174, 201, 53, 198, 140, 242, 174, 228, - 144, 4, 232, 144, 205, 135, 62, 216, 194, 219, 195, 197, 237, 62, 216, - 194, 206, 198, 197, 237, 62, 216, 194, 196, 72, 197, 237, 62, 216, 194, - 235, 78, 197, 237, 54, 81, 164, 62, 51, 39, 201, 58, 62, 242, 219, 39, - 207, 92, 208, 248, 113, 208, 248, 211, 92, 113, 208, 248, 211, 94, 113, - 208, 248, 202, 88, 113, 211, 155, 233, 153, 113, 16, 39, 212, 125, 16, - 39, 201, 93, 80, 229, 200, 16, 39, 201, 93, 80, 199, 48, 16, 39, 234, 53, - 80, 199, 48, 16, 39, 234, 53, 80, 198, 7, 16, 39, 234, 39, 16, 39, 251, - 255, 16, 39, 248, 185, 16, 39, 249, 90, 16, 39, 228, 209, 199, 225, 16, - 39, 219, 89, 233, 9, 16, 39, 81, 199, 225, 16, 39, 232, 107, 233, 9, 16, - 39, 247, 40, 207, 17, 16, 39, 203, 72, 211, 4, 16, 39, 203, 72, 223, 134, - 16, 39, 237, 165, 219, 79, 233, 228, 16, 39, 237, 30, 238, 231, 108, 16, - 39, 237, 30, 238, 231, 109, 16, 39, 237, 30, 238, 231, 139, 16, 39, 237, - 30, 238, 231, 137, 16, 39, 214, 92, 251, 255, 16, 39, 200, 65, 223, 199, - 16, 39, 234, 53, 80, 198, 8, 248, 81, 16, 39, 247, 78, 16, 39, 234, 53, - 80, 216, 193, 16, 39, 200, 221, 16, 39, 233, 228, 16, 39, 232, 222, 204, - 5, 16, 39, 230, 154, 204, 5, 16, 39, 207, 93, 204, 5, 16, 39, 196, 87, - 204, 5, 16, 39, 201, 242, 16, 39, 237, 71, 248, 85, 113, 211, 66, 248, - 14, 16, 39, 214, 62, 16, 39, 237, 72, 232, 107, 109, 16, 39, 200, 222, - 232, 107, 109, 211, 149, 106, 211, 149, 246, 204, 211, 149, 232, 110, - 211, 149, 223, 65, 232, 110, 211, 149, 248, 182, 247, 213, 211, 149, 248, - 22, 198, 173, 211, 149, 248, 0, 249, 43, 227, 242, 211, 149, 251, 88, 80, - 243, 77, 211, 149, 237, 170, 211, 149, 238, 110, 252, 3, 212, 123, 211, - 149, 54, 249, 91, 47, 17, 108, 47, 17, 109, 47, 17, 139, 47, 17, 137, 47, - 17, 153, 47, 17, 173, 47, 17, 181, 47, 17, 176, 47, 17, 184, 47, 31, 199, - 90, 47, 31, 234, 84, 47, 31, 197, 33, 47, 31, 198, 246, 47, 31, 232, 84, - 47, 31, 232, 234, 47, 31, 202, 125, 47, 31, 203, 239, 47, 31, 234, 118, - 47, 31, 213, 158, 47, 31, 197, 28, 127, 17, 108, 127, 17, 109, 127, 17, - 139, 127, 17, 137, 127, 17, 153, 127, 17, 173, 127, 17, 181, 127, 17, - 176, 127, 17, 184, 127, 31, 199, 90, 127, 31, 234, 84, 127, 31, 197, 33, - 127, 31, 198, 246, 127, 31, 232, 84, 127, 31, 232, 234, 127, 31, 202, - 125, 127, 31, 203, 239, 127, 31, 234, 118, 127, 31, 213, 158, 127, 31, - 197, 28, 17, 91, 232, 42, 201, 58, 17, 103, 232, 42, 201, 58, 17, 115, - 232, 42, 201, 58, 17, 232, 90, 232, 42, 201, 58, 17, 232, 185, 232, 42, - 201, 58, 17, 202, 131, 232, 42, 201, 58, 17, 203, 242, 232, 42, 201, 58, - 17, 234, 121, 232, 42, 201, 58, 17, 213, 161, 232, 42, 201, 58, 31, 199, - 91, 232, 42, 201, 58, 31, 234, 85, 232, 42, 201, 58, 31, 197, 34, 232, - 42, 201, 58, 31, 198, 247, 232, 42, 201, 58, 31, 232, 85, 232, 42, 201, - 58, 31, 232, 235, 232, 42, 201, 58, 31, 202, 126, 232, 42, 201, 58, 31, - 203, 240, 232, 42, 201, 58, 31, 234, 119, 232, 42, 201, 58, 31, 213, 159, - 232, 42, 201, 58, 31, 197, 29, 232, 42, 201, 58, 127, 8, 2, 1, 65, 127, - 8, 2, 1, 250, 70, 127, 8, 2, 1, 247, 145, 127, 8, 2, 1, 238, 80, 127, 8, - 2, 1, 73, 127, 8, 2, 1, 233, 134, 127, 8, 2, 1, 232, 14, 127, 8, 2, 1, - 230, 83, 127, 8, 2, 1, 70, 127, 8, 2, 1, 223, 7, 127, 8, 2, 1, 222, 125, - 127, 8, 2, 1, 170, 127, 8, 2, 1, 218, 147, 127, 8, 2, 1, 215, 47, 127, 8, - 2, 1, 74, 127, 8, 2, 1, 210, 226, 127, 8, 2, 1, 208, 97, 127, 8, 2, 1, - 148, 127, 8, 2, 1, 206, 3, 127, 8, 2, 1, 200, 39, 127, 8, 2, 1, 69, 127, - 8, 2, 1, 196, 8, 127, 8, 2, 1, 193, 221, 127, 8, 2, 1, 192, 235, 127, 8, - 2, 1, 192, 159, 127, 8, 2, 1, 191, 166, 47, 8, 6, 1, 65, 47, 8, 6, 1, - 250, 70, 47, 8, 6, 1, 247, 145, 47, 8, 6, 1, 238, 80, 47, 8, 6, 1, 73, - 47, 8, 6, 1, 233, 134, 47, 8, 6, 1, 232, 14, 47, 8, 6, 1, 230, 83, 47, 8, - 6, 1, 70, 47, 8, 6, 1, 223, 7, 47, 8, 6, 1, 222, 125, 47, 8, 6, 1, 170, - 47, 8, 6, 1, 218, 147, 47, 8, 6, 1, 215, 47, 47, 8, 6, 1, 74, 47, 8, 6, - 1, 210, 226, 47, 8, 6, 1, 208, 97, 47, 8, 6, 1, 148, 47, 8, 6, 1, 206, 3, - 47, 8, 6, 1, 200, 39, 47, 8, 6, 1, 69, 47, 8, 6, 1, 196, 8, 47, 8, 6, 1, - 193, 221, 47, 8, 6, 1, 192, 235, 47, 8, 6, 1, 192, 159, 47, 8, 6, 1, 191, - 166, 47, 8, 2, 1, 65, 47, 8, 2, 1, 250, 70, 47, 8, 2, 1, 247, 145, 47, 8, - 2, 1, 238, 80, 47, 8, 2, 1, 73, 47, 8, 2, 1, 233, 134, 47, 8, 2, 1, 232, - 14, 47, 8, 2, 1, 230, 83, 47, 8, 2, 1, 70, 47, 8, 2, 1, 223, 7, 47, 8, 2, - 1, 222, 125, 47, 8, 2, 1, 170, 47, 8, 2, 1, 218, 147, 47, 8, 2, 1, 215, - 47, 47, 8, 2, 1, 74, 47, 8, 2, 1, 210, 226, 47, 8, 2, 1, 208, 97, 47, 8, - 2, 1, 148, 47, 8, 2, 1, 206, 3, 47, 8, 2, 1, 200, 39, 47, 8, 2, 1, 69, - 47, 8, 2, 1, 196, 8, 47, 8, 2, 1, 193, 221, 47, 8, 2, 1, 192, 235, 47, 8, - 2, 1, 192, 159, 47, 8, 2, 1, 191, 166, 47, 17, 191, 77, 214, 92, 47, 31, - 234, 84, 214, 92, 47, 31, 197, 33, 214, 92, 47, 31, 198, 246, 214, 92, - 47, 31, 232, 84, 214, 92, 47, 31, 232, 234, 214, 92, 47, 31, 202, 125, - 214, 92, 47, 31, 203, 239, 214, 92, 47, 31, 234, 118, 214, 92, 47, 31, - 213, 158, 214, 92, 47, 31, 197, 28, 54, 47, 17, 108, 54, 47, 17, 109, 54, - 47, 17, 139, 54, 47, 17, 137, 54, 47, 17, 153, 54, 47, 17, 173, 54, 47, - 17, 181, 54, 47, 17, 176, 54, 47, 17, 184, 54, 47, 31, 199, 90, 214, 92, - 47, 17, 191, 77, 111, 122, 155, 228, 208, 111, 122, 88, 228, 208, 111, - 122, 155, 195, 132, 111, 122, 88, 195, 132, 111, 122, 155, 197, 221, 237, - 171, 228, 208, 111, 122, 88, 197, 221, 237, 171, 228, 208, 111, 122, 155, - 197, 221, 237, 171, 195, 132, 111, 122, 88, 197, 221, 237, 171, 195, 132, - 111, 122, 155, 208, 20, 237, 171, 228, 208, 111, 122, 88, 208, 20, 237, - 171, 228, 208, 111, 122, 155, 208, 20, 237, 171, 195, 132, 111, 122, 88, - 208, 20, 237, 171, 195, 132, 111, 122, 155, 143, 24, 187, 111, 122, 143, - 155, 24, 50, 229, 185, 111, 122, 143, 88, 24, 50, 219, 108, 111, 122, 88, - 143, 24, 187, 111, 122, 155, 143, 24, 219, 200, 111, 122, 143, 155, 24, - 45, 229, 185, 111, 122, 143, 88, 24, 45, 219, 108, 111, 122, 88, 143, 24, - 219, 200, 111, 122, 155, 132, 24, 187, 111, 122, 132, 155, 24, 50, 229, - 185, 111, 122, 132, 88, 24, 50, 219, 108, 111, 122, 88, 132, 24, 187, - 111, 122, 155, 132, 24, 219, 200, 111, 122, 132, 155, 24, 45, 229, 185, - 111, 122, 132, 88, 24, 45, 219, 108, 111, 122, 88, 132, 24, 219, 200, - 111, 122, 155, 81, 24, 187, 111, 122, 81, 155, 24, 50, 229, 185, 111, - 122, 132, 88, 24, 50, 143, 219, 108, 111, 122, 143, 88, 24, 50, 132, 219, - 108, 111, 122, 81, 88, 24, 50, 219, 108, 111, 122, 143, 155, 24, 50, 132, - 229, 185, 111, 122, 132, 155, 24, 50, 143, 229, 185, 111, 122, 88, 81, - 24, 187, 111, 122, 155, 81, 24, 219, 200, 111, 122, 81, 155, 24, 45, 229, - 185, 111, 122, 132, 88, 24, 45, 143, 219, 108, 111, 122, 143, 88, 24, 45, - 132, 219, 108, 111, 122, 81, 88, 24, 45, 219, 108, 111, 122, 143, 155, - 24, 45, 132, 229, 185, 111, 122, 132, 155, 24, 45, 143, 229, 185, 111, - 122, 88, 81, 24, 219, 200, 111, 122, 155, 143, 24, 228, 208, 111, 122, - 45, 88, 24, 50, 143, 219, 108, 111, 122, 50, 88, 24, 45, 143, 219, 108, - 111, 122, 143, 155, 24, 228, 209, 229, 185, 111, 122, 143, 88, 24, 228, - 209, 219, 108, 111, 122, 50, 155, 24, 45, 143, 229, 185, 111, 122, 45, - 155, 24, 50, 143, 229, 185, 111, 122, 88, 143, 24, 228, 208, 111, 122, - 155, 132, 24, 228, 208, 111, 122, 45, 88, 24, 50, 132, 219, 108, 111, - 122, 50, 88, 24, 45, 132, 219, 108, 111, 122, 132, 155, 24, 228, 209, - 229, 185, 111, 122, 132, 88, 24, 228, 209, 219, 108, 111, 122, 50, 155, - 24, 45, 132, 229, 185, 111, 122, 45, 155, 24, 50, 132, 229, 185, 111, - 122, 88, 132, 24, 228, 208, 111, 122, 155, 81, 24, 228, 208, 111, 122, - 45, 88, 24, 50, 81, 219, 108, 111, 122, 50, 88, 24, 45, 81, 219, 108, - 111, 122, 81, 155, 24, 228, 209, 229, 185, 111, 122, 132, 88, 24, 143, - 228, 209, 219, 108, 111, 122, 143, 88, 24, 132, 228, 209, 219, 108, 111, - 122, 81, 88, 24, 228, 209, 219, 108, 111, 122, 45, 132, 88, 24, 50, 143, - 219, 108, 111, 122, 50, 132, 88, 24, 45, 143, 219, 108, 111, 122, 45, - 143, 88, 24, 50, 132, 219, 108, 111, 122, 50, 143, 88, 24, 45, 132, 219, - 108, 111, 122, 143, 155, 24, 132, 228, 209, 229, 185, 111, 122, 132, 155, - 24, 143, 228, 209, 229, 185, 111, 122, 50, 155, 24, 45, 81, 229, 185, - 111, 122, 45, 155, 24, 50, 81, 229, 185, 111, 122, 88, 81, 24, 228, 208, - 111, 122, 155, 54, 237, 171, 228, 208, 111, 122, 88, 54, 237, 171, 228, - 208, 111, 122, 155, 54, 237, 171, 195, 132, 111, 122, 88, 54, 237, 171, - 195, 132, 111, 122, 54, 228, 208, 111, 122, 54, 195, 132, 111, 122, 143, - 202, 165, 24, 50, 235, 89, 111, 122, 143, 54, 24, 50, 202, 164, 111, 122, - 54, 143, 24, 187, 111, 122, 143, 202, 165, 24, 45, 235, 89, 111, 122, - 143, 54, 24, 45, 202, 164, 111, 122, 54, 143, 24, 219, 200, 111, 122, - 132, 202, 165, 24, 50, 235, 89, 111, 122, 132, 54, 24, 50, 202, 164, 111, - 122, 54, 132, 24, 187, 111, 122, 132, 202, 165, 24, 45, 235, 89, 111, - 122, 132, 54, 24, 45, 202, 164, 111, 122, 54, 132, 24, 219, 200, 111, - 122, 81, 202, 165, 24, 50, 235, 89, 111, 122, 81, 54, 24, 50, 202, 164, - 111, 122, 54, 81, 24, 187, 111, 122, 81, 202, 165, 24, 45, 235, 89, 111, - 122, 81, 54, 24, 45, 202, 164, 111, 122, 54, 81, 24, 219, 200, 111, 122, - 143, 202, 165, 24, 228, 209, 235, 89, 111, 122, 143, 54, 24, 228, 209, - 202, 164, 111, 122, 54, 143, 24, 228, 208, 111, 122, 132, 202, 165, 24, - 228, 209, 235, 89, 111, 122, 132, 54, 24, 228, 209, 202, 164, 111, 122, - 54, 132, 24, 228, 208, 111, 122, 81, 202, 165, 24, 228, 209, 235, 89, - 111, 122, 81, 54, 24, 228, 209, 202, 164, 111, 122, 54, 81, 24, 228, 208, - 111, 122, 155, 250, 223, 143, 24, 187, 111, 122, 155, 250, 223, 143, 24, - 219, 200, 111, 122, 155, 250, 223, 132, 24, 219, 200, 111, 122, 155, 250, - 223, 132, 24, 187, 111, 122, 155, 236, 250, 116, 50, 118, 110, 219, 200, - 111, 122, 155, 236, 250, 116, 45, 118, 110, 187, 111, 122, 155, 236, 250, - 238, 170, 111, 122, 155, 219, 200, 111, 122, 155, 196, 73, 111, 122, 155, - 187, 111, 122, 155, 235, 79, 111, 122, 88, 219, 200, 111, 122, 88, 196, - 73, 111, 122, 88, 187, 111, 122, 88, 235, 79, 111, 122, 155, 45, 24, 88, - 187, 111, 122, 155, 132, 24, 88, 235, 79, 111, 122, 88, 45, 24, 155, 187, - 111, 122, 88, 132, 24, 155, 235, 79, 116, 134, 248, 81, 110, 91, 234, - 117, 248, 81, 110, 91, 208, 18, 248, 81, 110, 115, 234, 115, 248, 81, - 110, 134, 248, 81, 110, 232, 185, 234, 115, 248, 81, 110, 115, 208, 16, - 248, 81, 110, 203, 242, 234, 115, 248, 81, 232, 42, 248, 81, 45, 203, - 242, 234, 115, 248, 81, 45, 115, 208, 16, 248, 81, 45, 232, 185, 234, - 115, 248, 81, 45, 134, 248, 81, 45, 115, 234, 115, 248, 81, 45, 91, 208, - 18, 248, 81, 45, 91, 234, 117, 248, 81, 50, 134, 248, 81, 155, 203, 148, - 216, 194, 203, 148, 237, 176, 203, 148, 116, 91, 234, 117, 248, 81, 50, - 91, 234, 117, 248, 81, 208, 22, 110, 219, 200, 208, 22, 110, 187, 208, - 22, 116, 219, 200, 208, 22, 116, 45, 24, 110, 45, 24, 110, 187, 208, 22, - 116, 45, 24, 110, 187, 208, 22, 116, 45, 24, 116, 50, 24, 110, 219, 200, - 208, 22, 116, 45, 24, 116, 50, 24, 110, 187, 208, 22, 116, 187, 208, 22, - 116, 50, 24, 110, 219, 200, 208, 22, 116, 50, 24, 110, 45, 24, 110, 187, - 62, 201, 185, 64, 201, 185, 64, 51, 4, 206, 108, 238, 209, 64, 51, 238, - 242, 62, 2, 201, 185, 51, 4, 228, 209, 232, 220, 51, 4, 81, 232, 220, 51, - 4, 211, 28, 238, 164, 232, 220, 51, 4, 116, 45, 118, 110, 50, 232, 220, - 51, 4, 116, 50, 118, 110, 45, 232, 220, 51, 4, 236, 250, 238, 164, 232, - 220, 62, 2, 201, 185, 64, 2, 201, 185, 62, 207, 87, 64, 207, 87, 62, 81, - 207, 87, 64, 81, 207, 87, 62, 210, 107, 64, 210, 107, 62, 196, 72, 197, - 237, 64, 196, 72, 197, 237, 62, 196, 72, 2, 197, 237, 64, 196, 72, 2, - 197, 237, 62, 206, 198, 197, 237, 64, 206, 198, 197, 237, 62, 206, 198, - 2, 197, 237, 64, 206, 198, 2, 197, 237, 62, 206, 198, 209, 52, 64, 206, - 198, 209, 52, 62, 235, 78, 197, 237, 64, 235, 78, 197, 237, 62, 235, 78, - 2, 197, 237, 64, 235, 78, 2, 197, 237, 62, 219, 195, 197, 237, 64, 219, - 195, 197, 237, 62, 219, 195, 2, 197, 237, 64, 219, 195, 2, 197, 237, 62, - 219, 195, 209, 52, 64, 219, 195, 209, 52, 62, 236, 243, 64, 236, 243, 64, - 236, 244, 238, 242, 62, 2, 236, 243, 232, 194, 218, 210, 64, 242, 218, - 235, 94, 242, 218, 242, 219, 4, 81, 232, 220, 247, 196, 62, 242, 218, - 242, 219, 4, 45, 134, 248, 91, 242, 219, 4, 50, 134, 248, 91, 242, 219, - 4, 110, 134, 248, 91, 242, 219, 4, 116, 134, 248, 91, 242, 219, 4, 116, - 50, 208, 22, 248, 91, 242, 219, 4, 251, 124, 247, 170, 116, 45, 208, 22, - 248, 91, 45, 134, 62, 242, 218, 50, 134, 62, 242, 218, 223, 67, 247, 200, - 223, 67, 64, 242, 218, 116, 134, 223, 67, 64, 242, 218, 110, 134, 223, - 67, 64, 242, 218, 116, 45, 208, 22, 242, 212, 250, 222, 116, 50, 208, 22, - 242, 212, 250, 222, 110, 50, 208, 22, 242, 212, 250, 222, 110, 45, 208, - 22, 242, 212, 250, 222, 116, 134, 242, 218, 110, 134, 242, 218, 62, 110, - 50, 197, 237, 62, 110, 45, 197, 237, 62, 116, 45, 197, 237, 62, 116, 50, - 197, 237, 64, 247, 200, 51, 4, 45, 134, 248, 91, 51, 4, 50, 134, 248, 91, - 51, 4, 116, 45, 236, 250, 134, 248, 91, 51, 4, 110, 50, 236, 250, 134, - 248, 91, 64, 51, 4, 81, 248, 106, 219, 88, 64, 196, 72, 197, 238, 4, 236, - 96, 196, 72, 197, 238, 4, 45, 134, 248, 91, 196, 72, 197, 238, 4, 50, - 134, 248, 91, 219, 245, 242, 218, 64, 51, 4, 116, 45, 208, 21, 64, 51, 4, - 110, 45, 208, 21, 64, 51, 4, 110, 50, 208, 21, 64, 51, 4, 116, 50, 208, - 21, 64, 242, 219, 4, 116, 45, 208, 21, 64, 242, 219, 4, 110, 45, 208, 21, - 64, 242, 219, 4, 110, 50, 208, 21, 64, 242, 219, 4, 116, 50, 208, 21, - 116, 45, 197, 237, 116, 50, 197, 237, 110, 45, 197, 237, 64, 216, 194, - 201, 185, 62, 216, 194, 201, 185, 64, 216, 194, 2, 201, 185, 62, 216, - 194, 2, 201, 185, 110, 50, 197, 237, 62, 200, 194, 4, 207, 114, 242, 162, - 196, 113, 202, 43, 242, 29, 62, 201, 97, 64, 201, 97, 219, 105, 198, 203, - 200, 193, 250, 163, 213, 22, 237, 41, 213, 22, 238, 251, 211, 51, 62, - 199, 101, 64, 199, 101, 249, 57, 248, 14, 249, 57, 111, 4, 243, 77, 249, - 57, 111, 4, 192, 235, 205, 149, 196, 114, 4, 207, 145, 235, 52, 228, 150, - 248, 157, 64, 203, 44, 209, 166, 62, 203, 44, 209, 166, 203, 135, 207, - 13, 206, 117, 232, 150, 229, 192, 247, 200, 62, 45, 209, 51, 223, 120, - 62, 50, 209, 51, 223, 120, 64, 45, 209, 51, 223, 120, 64, 132, 209, 51, - 223, 120, 64, 50, 209, 51, 223, 120, 64, 143, 209, 51, 223, 120, 202, 99, - 24, 238, 168, 247, 23, 57, 207, 159, 57, 248, 114, 57, 247, 103, 251, 48, - 211, 29, 238, 170, 243, 48, 206, 254, 238, 171, 80, 218, 231, 238, 171, - 80, 222, 227, 201, 98, 24, 238, 180, 233, 33, 113, 251, 238, 203, 138, - 230, 29, 24, 202, 208, 210, 52, 113, 192, 22, 192, 106, 197, 227, 39, - 229, 187, 197, 227, 39, 220, 19, 197, 227, 39, 232, 202, 197, 227, 39, - 198, 204, 197, 227, 39, 193, 64, 197, 227, 39, 193, 141, 197, 227, 39, - 215, 168, 197, 227, 39, 234, 163, 193, 92, 80, 237, 15, 64, 232, 54, 233, - 62, 64, 202, 59, 233, 62, 62, 202, 59, 233, 62, 64, 200, 194, 4, 207, - 114, 232, 197, 208, 18, 215, 188, 219, 238, 208, 18, 215, 188, 216, 161, - 233, 1, 57, 234, 163, 217, 77, 57, 222, 140, 205, 110, 196, 53, 214, 80, - 209, 69, 250, 208, 199, 159, 231, 115, 247, 76, 219, 162, 195, 35, 219, - 119, 205, 75, 205, 178, 247, 58, 250, 240, 209, 112, 64, 243, 57, 221, - 114, 64, 243, 57, 208, 9, 64, 243, 57, 206, 126, 64, 243, 57, 248, 104, - 64, 243, 57, 221, 52, 64, 243, 57, 210, 64, 62, 243, 57, 221, 114, 62, - 243, 57, 208, 9, 62, 243, 57, 206, 126, 62, 243, 57, 248, 104, 62, 243, - 57, 221, 52, 62, 243, 57, 210, 64, 62, 201, 240, 200, 206, 64, 229, 192, - 200, 206, 64, 236, 244, 200, 206, 62, 242, 159, 200, 206, 64, 201, 240, - 200, 206, 62, 229, 192, 200, 206, 62, 236, 244, 200, 206, 64, 242, 159, - 200, 206, 228, 150, 201, 190, 208, 18, 212, 249, 234, 117, 212, 249, 248, - 219, 234, 117, 212, 244, 248, 219, 202, 124, 212, 244, 215, 83, 232, 167, - 57, 215, 83, 214, 192, 57, 215, 83, 203, 122, 57, 193, 103, 200, 59, 238, - 170, 234, 160, 200, 59, 238, 170, 196, 83, 207, 83, 113, 207, 83, 16, 39, - 196, 250, 209, 90, 207, 83, 16, 39, 196, 248, 209, 90, 207, 83, 16, 39, - 196, 247, 209, 90, 207, 83, 16, 39, 196, 245, 209, 90, 207, 83, 16, 39, - 196, 243, 209, 90, 207, 83, 16, 39, 196, 241, 209, 90, 207, 83, 16, 39, - 196, 239, 209, 90, 207, 83, 16, 39, 231, 112, 217, 9, 62, 196, 83, 207, - 83, 113, 207, 84, 210, 126, 113, 210, 94, 210, 126, 113, 209, 250, 210, - 126, 57, 193, 90, 113, 236, 236, 233, 61, 236, 236, 233, 60, 236, 236, - 233, 59, 236, 236, 233, 58, 236, 236, 233, 57, 236, 236, 233, 56, 64, - 242, 219, 4, 75, 187, 64, 242, 219, 4, 103, 236, 94, 62, 242, 219, 4, 64, - 75, 187, 62, 242, 219, 4, 103, 64, 236, 94, 215, 204, 39, 192, 106, 215, - 204, 39, 192, 21, 236, 217, 39, 230, 171, 192, 106, 236, 217, 39, 219, - 154, 192, 21, 236, 217, 39, 219, 154, 192, 106, 236, 217, 39, 230, 171, - 192, 21, 64, 232, 177, 62, 232, 177, 230, 29, 24, 209, 171, 251, 76, 238, - 167, 200, 126, 201, 107, 80, 251, 212, 205, 93, 251, 140, 232, 146, 231, - 125, 201, 107, 80, 229, 159, 250, 122, 113, 232, 162, 211, 0, 64, 201, - 97, 115, 219, 83, 238, 228, 187, 115, 219, 83, 238, 228, 219, 200, 193, - 153, 57, 136, 195, 9, 57, 235, 84, 233, 1, 57, 235, 84, 217, 77, 57, 223, - 77, 233, 1, 24, 217, 77, 57, 217, 77, 24, 233, 1, 57, 217, 77, 4, 201, - 23, 57, 217, 77, 4, 201, 23, 24, 217, 77, 24, 233, 1, 57, 81, 217, 77, 4, - 201, 23, 57, 228, 209, 217, 77, 4, 201, 23, 57, 216, 194, 64, 242, 218, - 216, 194, 62, 242, 218, 216, 194, 2, 64, 242, 218, 217, 29, 113, 236, - 153, 113, 196, 80, 210, 93, 113, 242, 41, 232, 37, 196, 49, 214, 69, 246, - 215, 210, 175, 222, 146, 195, 77, 243, 27, 62, 215, 189, 219, 102, 203, - 171, 204, 17, 207, 255, 203, 250, 202, 31, 249, 61, 249, 23, 112, 221, - 197, 64, 235, 64, 217, 70, 64, 235, 64, 221, 114, 62, 235, 64, 217, 70, - 62, 235, 64, 221, 114, 202, 44, 193, 51, 202, 47, 200, 194, 248, 192, - 242, 162, 207, 144, 62, 202, 43, 198, 205, 242, 163, 24, 207, 144, 152, - 64, 203, 44, 209, 166, 152, 62, 203, 44, 209, 166, 64, 236, 244, 223, - 135, 201, 185, 238, 163, 219, 253, 236, 184, 247, 54, 211, 54, 209, 171, - 247, 55, 202, 80, 229, 169, 4, 64, 238, 170, 47, 238, 163, 219, 253, 246, - 205, 213, 31, 234, 30, 251, 106, 211, 85, 45, 193, 127, 198, 15, 62, 197, - 6, 45, 193, 127, 198, 15, 64, 197, 6, 45, 193, 127, 198, 15, 62, 45, 219, - 254, 216, 160, 64, 45, 219, 254, 216, 160, 235, 59, 202, 71, 57, 88, 64, - 235, 78, 197, 237, 45, 242, 171, 234, 30, 112, 205, 149, 233, 42, 236, - 250, 223, 135, 64, 242, 219, 223, 135, 62, 201, 185, 62, 197, 199, 207, - 24, 45, 234, 29, 207, 24, 45, 234, 28, 250, 137, 16, 39, 196, 53, 88, - 242, 219, 4, 201, 23, 24, 103, 183, 56, 210, 14, 206, 200, 223, 79, 210, - 14, 219, 197, 223, 79, 210, 14, 223, 65, 210, 14, 62, 238, 171, 211, 94, - 203, 73, 203, 61, 203, 7, 242, 248, 247, 32, 229, 86, 202, 132, 231, 126, - 193, 51, 228, 122, 231, 126, 4, 229, 253, 217, 52, 16, 39, 219, 107, 215, - 168, 196, 114, 211, 94, 230, 155, 232, 91, 232, 178, 223, 135, 228, 229, - 232, 247, 205, 173, 51, 232, 90, 238, 209, 202, 103, 227, 253, 202, 107, - 209, 242, 4, 249, 61, 199, 82, 222, 247, 249, 43, 113, 229, 197, 230, - 173, 113, 232, 45, 208, 146, 238, 135, 211, 94, 62, 201, 185, 64, 232, - 178, 4, 228, 209, 82, 62, 201, 24, 62, 205, 183, 205, 79, 116, 248, 86, - 205, 79, 62, 205, 79, 110, 248, 86, 205, 79, 64, 205, 79, 64, 88, 243, - 78, 77, 199, 102, 219, 16, 57, 199, 177, 235, 58, 251, 171, 234, 25, 207, - 142, 232, 190, 207, 142, 230, 20, 195, 64, 230, 20, 193, 3, 230, 20, 110, - 50, 210, 24, 210, 24, 116, 50, 210, 24, 64, 213, 194, 62, 213, 194, 243, - 78, 77, 88, 243, 78, 77, 215, 112, 192, 235, 88, 215, 112, 192, 235, 249, - 57, 192, 235, 88, 249, 57, 192, 235, 211, 0, 35, 238, 170, 88, 35, 238, - 170, 211, 66, 246, 230, 238, 170, 88, 211, 66, 246, 230, 238, 170, 8, - 238, 170, 203, 146, 64, 8, 238, 170, 211, 0, 8, 238, 170, 217, 73, 238, - 170, 201, 98, 80, 237, 163, 232, 90, 199, 122, 250, 143, 232, 90, 249, - 58, 250, 143, 88, 232, 90, 249, 58, 250, 143, 232, 90, 242, 157, 250, - 143, 62, 232, 90, 209, 53, 201, 97, 64, 232, 90, 209, 53, 201, 97, 201, - 235, 201, 33, 211, 0, 64, 201, 97, 47, 64, 201, 97, 211, 66, 246, 230, - 62, 201, 97, 62, 246, 230, 64, 201, 97, 211, 0, 62, 201, 97, 88, 211, 0, - 62, 201, 97, 209, 122, 201, 97, 203, 146, 64, 201, 97, 88, 250, 143, 211, - 66, 246, 230, 250, 143, 234, 121, 201, 201, 250, 143, 234, 121, 209, 53, - 62, 201, 97, 234, 121, 209, 53, 209, 122, 201, 97, 202, 131, 209, 53, 62, - 201, 97, 234, 121, 209, 53, 207, 85, 62, 201, 97, 88, 234, 121, 209, 53, - 207, 85, 62, 201, 97, 197, 34, 209, 53, 62, 201, 97, 202, 126, 209, 53, - 250, 143, 199, 122, 250, 143, 211, 66, 246, 230, 199, 122, 250, 143, 88, - 199, 122, 250, 143, 202, 131, 209, 230, 62, 24, 64, 232, 149, 62, 232, - 149, 64, 232, 149, 234, 121, 209, 230, 211, 0, 62, 232, 149, 47, 211, 66, - 246, 230, 234, 121, 209, 53, 201, 97, 88, 199, 122, 209, 122, 250, 143, - 202, 45, 198, 167, 197, 230, 202, 45, 88, 243, 53, 202, 45, 201, 237, 88, - 201, 237, 249, 58, 250, 143, 234, 121, 199, 122, 208, 182, 250, 143, 88, - 234, 121, 199, 122, 208, 182, 250, 143, 238, 171, 77, 203, 146, 64, 242, - 218, 214, 92, 112, 238, 171, 77, 110, 50, 235, 54, 64, 201, 185, 116, 50, - 235, 54, 64, 201, 185, 110, 50, 203, 146, 64, 201, 185, 116, 50, 203, - 146, 64, 201, 185, 62, 208, 8, 87, 211, 32, 64, 208, 8, 87, 211, 32, 64, - 233, 175, 87, 211, 32, 62, 236, 244, 216, 18, 64, 192, 235, 88, 233, 175, - 87, 113, 155, 81, 164, 216, 194, 81, 164, 88, 81, 164, 88, 202, 165, 152, - 242, 27, 207, 247, 87, 211, 32, 88, 202, 165, 242, 27, 207, 247, 87, 211, - 32, 88, 54, 152, 242, 27, 207, 247, 87, 211, 32, 88, 54, 242, 27, 207, - 247, 87, 211, 32, 88, 131, 202, 165, 242, 27, 207, 247, 87, 211, 32, 88, - 131, 54, 242, 27, 207, 247, 87, 211, 32, 238, 116, 201, 76, 210, 118, 3, - 211, 32, 88, 233, 175, 87, 211, 32, 88, 229, 192, 233, 175, 87, 211, 32, - 88, 62, 229, 191, 206, 117, 88, 62, 229, 192, 247, 200, 232, 150, 229, - 191, 206, 117, 232, 150, 229, 192, 247, 200, 216, 194, 45, 210, 104, 211, - 32, 216, 194, 50, 210, 104, 211, 32, 216, 194, 232, 163, 45, 210, 104, - 211, 32, 216, 194, 232, 163, 50, 210, 104, 211, 32, 216, 194, 219, 195, - 251, 65, 248, 6, 211, 32, 216, 194, 206, 198, 251, 65, 248, 6, 211, 32, - 88, 219, 195, 251, 65, 207, 247, 87, 211, 32, 88, 206, 198, 251, 65, 207, - 247, 87, 211, 32, 88, 219, 195, 251, 65, 248, 6, 211, 32, 88, 206, 198, - 251, 65, 248, 6, 211, 32, 155, 45, 198, 37, 203, 98, 248, 6, 211, 32, - 155, 50, 198, 37, 203, 98, 248, 6, 211, 32, 216, 194, 45, 238, 124, 248, - 6, 211, 32, 216, 194, 50, 238, 124, 248, 6, 211, 32, 236, 196, 214, 92, - 47, 17, 108, 236, 196, 214, 92, 47, 17, 109, 236, 196, 214, 92, 47, 17, - 139, 236, 196, 214, 92, 47, 17, 137, 236, 196, 214, 92, 47, 17, 153, 236, - 196, 214, 92, 47, 17, 173, 236, 196, 214, 92, 47, 17, 181, 236, 196, 214, - 92, 47, 17, 176, 236, 196, 214, 92, 47, 17, 184, 236, 196, 214, 92, 47, - 31, 199, 90, 236, 196, 47, 49, 17, 108, 236, 196, 47, 49, 17, 109, 236, - 196, 47, 49, 17, 139, 236, 196, 47, 49, 17, 137, 236, 196, 47, 49, 17, - 153, 236, 196, 47, 49, 17, 173, 236, 196, 47, 49, 17, 181, 236, 196, 47, - 49, 17, 176, 236, 196, 47, 49, 17, 184, 236, 196, 47, 49, 31, 199, 90, - 236, 196, 214, 92, 47, 49, 17, 108, 236, 196, 214, 92, 47, 49, 17, 109, - 236, 196, 214, 92, 47, 49, 17, 139, 236, 196, 214, 92, 47, 49, 17, 137, - 236, 196, 214, 92, 47, 49, 17, 153, 236, 196, 214, 92, 47, 49, 17, 173, - 236, 196, 214, 92, 47, 49, 17, 181, 236, 196, 214, 92, 47, 49, 17, 176, - 236, 196, 214, 92, 47, 49, 17, 184, 236, 196, 214, 92, 47, 49, 31, 199, - 90, 88, 193, 75, 96, 55, 88, 107, 57, 88, 216, 18, 57, 88, 236, 155, 57, - 88, 201, 253, 234, 160, 55, 88, 96, 55, 88, 185, 234, 160, 55, 235, 69, - 209, 55, 96, 55, 88, 206, 109, 96, 55, 197, 236, 96, 55, 88, 197, 236, - 96, 55, 237, 169, 197, 236, 96, 55, 88, 237, 169, 197, 236, 96, 55, 62, - 96, 55, 198, 220, 198, 47, 96, 250, 185, 198, 220, 248, 27, 96, 250, 185, - 62, 96, 250, 185, 88, 62, 238, 116, 235, 75, 24, 96, 55, 88, 62, 238, - 116, 196, 62, 24, 96, 55, 201, 182, 62, 96, 55, 88, 239, 8, 62, 96, 55, - 206, 197, 64, 96, 55, 219, 194, 64, 96, 55, 249, 95, 203, 146, 64, 96, - 55, 232, 57, 203, 146, 64, 96, 55, 88, 110, 206, 196, 64, 96, 55, 88, - 116, 206, 196, 64, 96, 55, 212, 251, 110, 206, 196, 64, 96, 55, 238, 124, - 218, 236, 212, 251, 116, 206, 196, 64, 96, 55, 47, 88, 64, 96, 55, 193, - 86, 96, 55, 248, 90, 201, 253, 234, 160, 55, 248, 90, 96, 55, 248, 90, - 185, 234, 160, 55, 88, 248, 90, 201, 253, 234, 160, 55, 88, 248, 90, 96, - 55, 88, 248, 90, 185, 234, 160, 55, 199, 124, 96, 55, 88, 199, 123, 96, - 55, 193, 113, 96, 55, 88, 193, 113, 96, 55, 211, 60, 96, 55, 54, 238, - 124, 218, 236, 115, 236, 206, 251, 64, 64, 197, 238, 238, 242, 2, 64, - 197, 237, 209, 245, 211, 66, 200, 223, 211, 66, 200, 175, 45, 206, 2, - 249, 81, 237, 67, 50, 206, 2, 249, 81, 237, 67, 211, 46, 4, 75, 223, 89, - 207, 14, 202, 19, 208, 223, 200, 223, 200, 176, 208, 223, 202, 18, 81, - 249, 38, 4, 228, 209, 105, 13, 206, 175, 236, 249, 177, 236, 154, 13, - 233, 42, 236, 249, 112, 219, 5, 251, 74, 112, 219, 5, 211, 45, 64, 236, - 244, 4, 246, 228, 236, 96, 24, 4, 236, 96, 234, 89, 80, 211, 58, 196, 61, - 110, 50, 238, 211, 4, 236, 96, 116, 45, 238, 211, 4, 236, 96, 45, 211, 2, - 222, 172, 50, 211, 2, 222, 172, 232, 42, 211, 2, 222, 172, 219, 245, 132, - 199, 223, 219, 245, 143, 199, 223, 45, 24, 50, 54, 197, 53, 45, 24, 50, - 199, 223, 45, 215, 116, 177, 50, 199, 223, 177, 45, 199, 223, 132, 199, - 224, 4, 242, 219, 56, 218, 211, 236, 161, 247, 157, 228, 209, 206, 47, - 64, 239, 7, 236, 243, 64, 239, 7, 236, 244, 4, 117, 198, 177, 64, 239, 7, - 236, 244, 4, 96, 198, 177, 64, 51, 4, 117, 198, 177, 64, 51, 4, 96, 198, - 177, 13, 45, 64, 51, 248, 5, 13, 50, 64, 51, 248, 5, 13, 45, 251, 65, - 248, 5, 13, 50, 251, 65, 248, 5, 13, 45, 54, 251, 65, 248, 5, 13, 50, 54, - 251, 65, 248, 5, 13, 45, 64, 198, 37, 203, 98, 248, 5, 13, 50, 64, 198, - 37, 203, 98, 248, 5, 13, 45, 232, 163, 210, 103, 13, 50, 232, 163, 210, - 103, 196, 62, 208, 20, 55, 235, 75, 208, 20, 55, 251, 34, 231, 165, 242, - 219, 55, 242, 173, 231, 165, 242, 219, 55, 50, 63, 4, 47, 209, 73, 177, - 117, 55, 177, 96, 55, 177, 45, 50, 55, 177, 117, 54, 55, 177, 96, 54, 55, - 177, 45, 50, 54, 55, 177, 117, 63, 232, 60, 164, 177, 96, 63, 232, 60, - 164, 177, 117, 54, 63, 232, 60, 164, 177, 96, 54, 63, 232, 60, 164, 177, - 96, 201, 178, 55, 67, 68, 248, 84, 67, 68, 236, 93, 67, 68, 235, 221, 67, - 68, 236, 92, 67, 68, 235, 157, 67, 68, 236, 28, 67, 68, 235, 220, 67, 68, - 236, 91, 67, 68, 235, 125, 67, 68, 235, 252, 67, 68, 235, 188, 67, 68, - 236, 59, 67, 68, 235, 156, 67, 68, 236, 27, 67, 68, 235, 219, 67, 68, - 236, 90, 67, 68, 235, 109, 67, 68, 235, 236, 67, 68, 235, 172, 67, 68, - 236, 43, 67, 68, 235, 140, 67, 68, 236, 11, 67, 68, 235, 203, 67, 68, - 236, 74, 67, 68, 235, 124, 67, 68, 235, 251, 67, 68, 235, 187, 67, 68, - 236, 58, 67, 68, 235, 155, 67, 68, 236, 26, 67, 68, 235, 218, 67, 68, - 236, 89, 67, 68, 235, 101, 67, 68, 235, 228, 67, 68, 235, 164, 67, 68, - 236, 35, 67, 68, 235, 132, 67, 68, 236, 3, 67, 68, 235, 195, 67, 68, 236, - 66, 67, 68, 235, 116, 67, 68, 235, 243, 67, 68, 235, 179, 67, 68, 236, - 50, 67, 68, 235, 147, 67, 68, 236, 18, 67, 68, 235, 210, 67, 68, 236, 81, - 67, 68, 235, 108, 67, 68, 235, 235, 67, 68, 235, 171, 67, 68, 236, 42, - 67, 68, 235, 139, 67, 68, 236, 10, 67, 68, 235, 202, 67, 68, 236, 73, 67, - 68, 235, 123, 67, 68, 235, 250, 67, 68, 235, 186, 67, 68, 236, 57, 67, - 68, 235, 154, 67, 68, 236, 25, 67, 68, 235, 217, 67, 68, 236, 88, 67, 68, - 235, 97, 67, 68, 235, 224, 67, 68, 235, 160, 67, 68, 236, 31, 67, 68, - 235, 128, 67, 68, 235, 255, 67, 68, 235, 191, 67, 68, 236, 62, 67, 68, - 235, 112, 67, 68, 235, 239, 67, 68, 235, 175, 67, 68, 236, 46, 67, 68, - 235, 143, 67, 68, 236, 14, 67, 68, 235, 206, 67, 68, 236, 77, 67, 68, - 235, 104, 67, 68, 235, 231, 67, 68, 235, 167, 67, 68, 236, 38, 67, 68, - 235, 135, 67, 68, 236, 6, 67, 68, 235, 198, 67, 68, 236, 69, 67, 68, 235, - 119, 67, 68, 235, 246, 67, 68, 235, 182, 67, 68, 236, 53, 67, 68, 235, - 150, 67, 68, 236, 21, 67, 68, 235, 213, 67, 68, 236, 84, 67, 68, 235, - 100, 67, 68, 235, 227, 67, 68, 235, 163, 67, 68, 236, 34, 67, 68, 235, - 131, 67, 68, 236, 2, 67, 68, 235, 194, 67, 68, 236, 65, 67, 68, 235, 115, - 67, 68, 235, 242, 67, 68, 235, 178, 67, 68, 236, 49, 67, 68, 235, 146, - 67, 68, 236, 17, 67, 68, 235, 209, 67, 68, 236, 80, 67, 68, 235, 107, 67, - 68, 235, 234, 67, 68, 235, 170, 67, 68, 236, 41, 67, 68, 235, 138, 67, - 68, 236, 9, 67, 68, 235, 201, 67, 68, 236, 72, 67, 68, 235, 122, 67, 68, - 235, 249, 67, 68, 235, 185, 67, 68, 236, 56, 67, 68, 235, 153, 67, 68, - 236, 24, 67, 68, 235, 216, 67, 68, 236, 87, 67, 68, 235, 95, 67, 68, 235, - 222, 67, 68, 235, 158, 67, 68, 236, 29, 67, 68, 235, 126, 67, 68, 235, - 253, 67, 68, 235, 189, 67, 68, 236, 60, 67, 68, 235, 110, 67, 68, 235, - 237, 67, 68, 235, 173, 67, 68, 236, 44, 67, 68, 235, 141, 67, 68, 236, - 12, 67, 68, 235, 204, 67, 68, 236, 75, 67, 68, 235, 102, 67, 68, 235, - 229, 67, 68, 235, 165, 67, 68, 236, 36, 67, 68, 235, 133, 67, 68, 236, 4, - 67, 68, 235, 196, 67, 68, 236, 67, 67, 68, 235, 117, 67, 68, 235, 244, - 67, 68, 235, 180, 67, 68, 236, 51, 67, 68, 235, 148, 67, 68, 236, 19, 67, - 68, 235, 211, 67, 68, 236, 82, 67, 68, 235, 98, 67, 68, 235, 225, 67, 68, - 235, 161, 67, 68, 236, 32, 67, 68, 235, 129, 67, 68, 236, 0, 67, 68, 235, - 192, 67, 68, 236, 63, 67, 68, 235, 113, 67, 68, 235, 240, 67, 68, 235, - 176, 67, 68, 236, 47, 67, 68, 235, 144, 67, 68, 236, 15, 67, 68, 235, - 207, 67, 68, 236, 78, 67, 68, 235, 105, 67, 68, 235, 232, 67, 68, 235, - 168, 67, 68, 236, 39, 67, 68, 235, 136, 67, 68, 236, 7, 67, 68, 235, 199, - 67, 68, 236, 70, 67, 68, 235, 120, 67, 68, 235, 247, 67, 68, 235, 183, - 67, 68, 236, 54, 67, 68, 235, 151, 67, 68, 236, 22, 67, 68, 235, 214, 67, - 68, 236, 85, 67, 68, 235, 96, 67, 68, 235, 223, 67, 68, 235, 159, 67, 68, - 236, 30, 67, 68, 235, 127, 67, 68, 235, 254, 67, 68, 235, 190, 67, 68, - 236, 61, 67, 68, 235, 111, 67, 68, 235, 238, 67, 68, 235, 174, 67, 68, - 236, 45, 67, 68, 235, 142, 67, 68, 236, 13, 67, 68, 235, 205, 67, 68, - 236, 76, 67, 68, 235, 103, 67, 68, 235, 230, 67, 68, 235, 166, 67, 68, - 236, 37, 67, 68, 235, 134, 67, 68, 236, 5, 67, 68, 235, 197, 67, 68, 236, - 68, 67, 68, 235, 118, 67, 68, 235, 245, 67, 68, 235, 181, 67, 68, 236, - 52, 67, 68, 235, 149, 67, 68, 236, 20, 67, 68, 235, 212, 67, 68, 236, 83, - 67, 68, 235, 99, 67, 68, 235, 226, 67, 68, 235, 162, 67, 68, 236, 33, 67, - 68, 235, 130, 67, 68, 236, 1, 67, 68, 235, 193, 67, 68, 236, 64, 67, 68, - 235, 114, 67, 68, 235, 241, 67, 68, 235, 177, 67, 68, 236, 48, 67, 68, - 235, 145, 67, 68, 236, 16, 67, 68, 235, 208, 67, 68, 236, 79, 67, 68, - 235, 106, 67, 68, 235, 233, 67, 68, 235, 169, 67, 68, 236, 40, 67, 68, - 235, 137, 67, 68, 236, 8, 67, 68, 235, 200, 67, 68, 236, 71, 67, 68, 235, - 121, 67, 68, 235, 248, 67, 68, 235, 184, 67, 68, 236, 55, 67, 68, 235, - 152, 67, 68, 236, 23, 67, 68, 235, 215, 67, 68, 236, 86, 96, 197, 9, 63, - 4, 81, 105, 96, 197, 9, 63, 4, 54, 81, 105, 117, 54, 63, 4, 81, 105, 96, - 54, 63, 4, 81, 105, 45, 50, 54, 63, 4, 81, 105, 96, 197, 9, 63, 232, 60, - 164, 117, 54, 63, 232, 60, 164, 96, 54, 63, 232, 60, 164, 235, 75, 63, 4, - 228, 209, 105, 196, 62, 63, 4, 228, 209, 105, 196, 62, 197, 221, 55, 235, - 75, 197, 221, 55, 117, 54, 237, 171, 55, 96, 54, 237, 171, 55, 117, 197, - 221, 237, 171, 55, 96, 197, 221, 237, 171, 55, 96, 197, 9, 197, 221, 237, - 171, 55, 96, 63, 4, 235, 94, 201, 75, 196, 62, 63, 118, 164, 235, 75, 63, - 118, 164, 96, 63, 4, 199, 211, 4, 81, 105, 96, 63, 4, 199, 211, 4, 54, - 81, 105, 96, 197, 9, 63, 4, 199, 210, 96, 197, 9, 63, 4, 199, 211, 4, 81, - 105, 96, 197, 9, 63, 4, 199, 211, 4, 54, 81, 105, 117, 250, 187, 96, 250, - 187, 117, 54, 250, 187, 96, 54, 250, 187, 117, 63, 118, 62, 236, 243, 96, - 63, 118, 62, 236, 243, 117, 63, 232, 60, 249, 38, 118, 62, 236, 243, 96, - 63, 232, 60, 249, 38, 118, 62, 236, 243, 185, 193, 103, 24, 201, 253, - 234, 160, 55, 185, 234, 160, 24, 201, 253, 193, 103, 55, 185, 193, 103, - 63, 4, 106, 185, 234, 160, 63, 4, 106, 201, 253, 234, 160, 63, 4, 106, - 201, 253, 193, 103, 63, 4, 106, 185, 193, 103, 63, 24, 185, 234, 160, 55, - 185, 234, 160, 63, 24, 201, 253, 234, 160, 55, 201, 253, 234, 160, 63, - 24, 201, 253, 193, 103, 55, 201, 253, 193, 103, 63, 24, 185, 193, 103, - 55, 206, 175, 236, 250, 238, 163, 233, 42, 236, 249, 233, 42, 236, 250, - 238, 163, 206, 175, 236, 249, 201, 253, 234, 160, 63, 238, 163, 185, 234, - 160, 55, 185, 234, 160, 63, 238, 163, 201, 253, 234, 160, 55, 233, 42, - 236, 250, 238, 163, 185, 234, 160, 55, 206, 175, 236, 250, 238, 163, 201, - 253, 234, 160, 55, 185, 234, 160, 63, 238, 163, 185, 193, 103, 55, 185, - 193, 103, 63, 238, 163, 185, 234, 160, 55, 193, 137, 63, 209, 51, 236, - 186, 187, 63, 209, 51, 96, 199, 20, 238, 114, 196, 61, 63, 209, 51, 96, - 199, 20, 238, 114, 235, 74, 63, 209, 51, 235, 75, 199, 20, 238, 114, 219, - 190, 63, 209, 51, 235, 75, 199, 20, 238, 114, 206, 192, 206, 195, 250, - 223, 242, 173, 55, 219, 193, 250, 223, 251, 34, 55, 198, 49, 250, 223, - 251, 34, 55, 248, 29, 250, 223, 251, 34, 55, 198, 49, 250, 223, 242, 173, - 63, 4, 216, 17, 198, 49, 250, 223, 251, 34, 63, 4, 209, 73, 110, 50, 204, - 22, 242, 173, 55, 110, 45, 204, 22, 251, 34, 55, 251, 34, 242, 171, 242, - 219, 55, 242, 173, 242, 171, 242, 219, 55, 96, 63, 95, 203, 35, 117, 55, - 117, 63, 95, 203, 35, 96, 55, 203, 35, 96, 63, 95, 117, 55, 96, 63, 4, - 107, 60, 117, 63, 4, 107, 60, 96, 63, 198, 211, 192, 235, 45, 50, 63, - 198, 211, 2, 242, 218, 196, 62, 197, 9, 63, 232, 60, 2, 242, 218, 45, - 178, 132, 50, 178, 143, 229, 235, 45, 178, 143, 50, 178, 132, 229, 235, - 132, 178, 50, 143, 178, 45, 229, 235, 132, 178, 45, 143, 178, 50, 229, - 235, 45, 178, 132, 50, 178, 132, 229, 235, 132, 178, 50, 143, 178, 50, - 229, 235, 45, 178, 143, 50, 178, 143, 229, 235, 132, 178, 45, 143, 178, - 45, 229, 235, 117, 229, 236, 4, 178, 132, 118, 164, 96, 229, 236, 4, 178, - 132, 118, 164, 196, 62, 229, 236, 4, 178, 50, 118, 164, 235, 75, 229, - 236, 4, 178, 50, 118, 164, 117, 229, 236, 4, 178, 143, 118, 164, 96, 229, - 236, 4, 178, 143, 118, 164, 196, 62, 229, 236, 4, 178, 45, 118, 164, 235, - 75, 229, 236, 4, 178, 45, 118, 164, 117, 229, 236, 4, 178, 132, 232, 60, - 164, 96, 229, 236, 4, 178, 132, 232, 60, 164, 196, 62, 229, 236, 4, 178, - 50, 232, 60, 164, 235, 75, 229, 236, 4, 178, 50, 232, 60, 164, 117, 229, - 236, 4, 178, 143, 232, 60, 164, 96, 229, 236, 4, 178, 143, 232, 60, 164, - 196, 62, 229, 236, 4, 178, 45, 232, 60, 164, 235, 75, 229, 236, 4, 178, - 45, 232, 60, 164, 117, 229, 236, 4, 178, 132, 95, 117, 229, 236, 4, 178, - 235, 79, 196, 62, 229, 236, 4, 178, 45, 248, 166, 196, 62, 229, 236, 4, - 178, 187, 96, 229, 236, 4, 178, 132, 95, 96, 229, 236, 4, 178, 235, 79, - 235, 75, 229, 236, 4, 178, 45, 248, 166, 235, 75, 229, 236, 4, 178, 187, - 117, 229, 236, 4, 178, 132, 95, 96, 229, 236, 4, 178, 196, 73, 117, 229, - 236, 4, 178, 143, 95, 96, 229, 236, 4, 178, 235, 79, 96, 229, 236, 4, - 178, 132, 95, 117, 229, 236, 4, 178, 196, 73, 96, 229, 236, 4, 178, 143, - 95, 117, 229, 236, 4, 178, 235, 79, 117, 229, 236, 4, 178, 132, 95, 177, - 237, 170, 117, 229, 236, 4, 178, 143, 248, 183, 177, 237, 170, 96, 229, - 236, 4, 178, 132, 95, 177, 237, 170, 96, 229, 236, 4, 178, 143, 248, 183, - 177, 237, 170, 196, 62, 229, 236, 4, 178, 45, 248, 166, 235, 75, 229, - 236, 4, 178, 187, 235, 75, 229, 236, 4, 178, 45, 248, 166, 196, 62, 229, - 236, 4, 178, 187, 50, 54, 63, 4, 206, 108, 229, 203, 234, 1, 3, 95, 96, - 55, 198, 148, 211, 56, 95, 96, 55, 117, 63, 95, 198, 148, 211, 55, 96, - 63, 95, 198, 148, 211, 55, 96, 63, 95, 251, 114, 234, 3, 159, 219, 156, - 95, 117, 55, 117, 63, 198, 211, 219, 155, 230, 170, 95, 96, 55, 200, 224, - 95, 96, 55, 117, 63, 198, 211, 200, 223, 200, 176, 95, 117, 55, 45, 232, - 196, 199, 210, 50, 232, 196, 199, 210, 132, 232, 196, 199, 210, 143, 232, - 196, 199, 210, 197, 221, 81, 249, 38, 237, 67, 191, 167, 212, 253, 201, - 196, 191, 167, 212, 253, 196, 251, 242, 35, 45, 64, 238, 124, 248, 5, 50, - 64, 238, 124, 248, 5, 45, 64, 210, 103, 50, 64, 210, 103, 191, 167, 212, - 253, 45, 223, 150, 248, 5, 191, 167, 212, 253, 50, 223, 150, 248, 5, 191, - 167, 212, 253, 45, 248, 118, 248, 5, 191, 167, 212, 253, 50, 248, 118, - 248, 5, 45, 51, 248, 6, 4, 196, 99, 50, 51, 248, 6, 4, 196, 99, 45, 51, - 248, 6, 4, 198, 178, 223, 135, 198, 49, 238, 210, 50, 51, 248, 6, 4, 198, - 178, 223, 135, 248, 29, 238, 210, 45, 51, 248, 6, 4, 198, 178, 223, 135, - 248, 29, 238, 210, 50, 51, 248, 6, 4, 198, 178, 223, 135, 198, 49, 238, - 210, 45, 251, 65, 248, 6, 4, 236, 96, 50, 251, 65, 248, 6, 4, 236, 96, - 45, 250, 223, 219, 156, 248, 5, 50, 250, 223, 230, 170, 248, 5, 54, 45, - 250, 223, 230, 170, 248, 5, 54, 50, 250, 223, 219, 156, 248, 5, 45, 62, - 198, 37, 203, 98, 248, 5, 50, 62, 198, 37, 203, 98, 248, 5, 235, 94, 232, - 254, 81, 191, 21, 219, 88, 216, 207, 251, 65, 211, 58, 219, 200, 50, 251, - 65, 195, 165, 4, 201, 185, 216, 207, 50, 251, 65, 4, 236, 96, 251, 65, 4, - 206, 4, 223, 89, 251, 251, 251, 64, 201, 220, 251, 65, 211, 58, 219, 200, - 201, 220, 251, 65, 211, 58, 196, 73, 152, 251, 64, 207, 13, 251, 64, 251, - 65, 4, 196, 99, 207, 13, 251, 65, 4, 196, 99, 211, 159, 251, 65, 211, 58, - 196, 73, 211, 159, 251, 65, 211, 58, 235, 79, 216, 207, 251, 65, 4, 211, - 66, 250, 201, 234, 49, 223, 135, 63, 209, 51, 132, 24, 187, 216, 207, - 251, 65, 4, 211, 66, 250, 201, 234, 49, 223, 135, 63, 209, 51, 132, 24, - 219, 200, 216, 207, 251, 65, 4, 211, 66, 250, 201, 234, 49, 223, 135, 63, - 209, 51, 143, 24, 187, 216, 207, 251, 65, 4, 211, 66, 250, 201, 234, 49, - 223, 135, 63, 209, 51, 143, 24, 219, 200, 216, 207, 251, 65, 4, 211, 66, - 250, 201, 234, 49, 223, 135, 63, 209, 51, 50, 24, 196, 73, 216, 207, 251, - 65, 4, 211, 66, 250, 201, 234, 49, 223, 135, 63, 209, 51, 45, 24, 196, - 73, 216, 207, 251, 65, 4, 211, 66, 250, 201, 234, 49, 223, 135, 63, 209, - 51, 50, 24, 235, 79, 216, 207, 251, 65, 4, 211, 66, 250, 201, 234, 49, - 223, 135, 63, 209, 51, 45, 24, 235, 79, 207, 13, 234, 63, 203, 247, 234, - 63, 203, 248, 4, 210, 252, 234, 63, 203, 248, 4, 2, 242, 219, 56, 234, - 63, 203, 248, 4, 50, 63, 56, 234, 63, 203, 248, 4, 45, 63, 56, 242, 219, - 4, 228, 209, 164, 47, 81, 164, 47, 210, 108, 47, 207, 14, 202, 18, 47, - 209, 245, 242, 219, 236, 161, 247, 157, 228, 209, 249, 38, 24, 198, 49, - 134, 236, 161, 247, 157, 81, 164, 242, 219, 4, 200, 178, 192, 235, 47, - 251, 32, 236, 155, 57, 132, 63, 198, 211, 242, 218, 47, 64, 247, 200, 47, - 247, 200, 47, 219, 155, 47, 230, 169, 242, 219, 4, 2, 242, 219, 118, 199, - 29, 187, 242, 219, 4, 103, 228, 209, 201, 11, 118, 199, 29, 187, 112, - 206, 175, 236, 250, 202, 92, 112, 233, 42, 236, 250, 202, 92, 112, 250, - 143, 112, 2, 242, 218, 112, 201, 185, 103, 222, 171, 201, 183, 197, 238, - 4, 75, 56, 197, 238, 4, 196, 99, 206, 4, 223, 135, 197, 237, 197, 238, 4, - 203, 255, 250, 133, 248, 28, 50, 197, 238, 95, 45, 197, 237, 45, 197, - 238, 248, 166, 81, 164, 81, 249, 38, 248, 166, 50, 197, 237, 248, 16, 4, - 45, 134, 248, 91, 248, 16, 4, 50, 134, 248, 91, 62, 248, 15, 25, 4, 45, - 134, 248, 91, 25, 4, 50, 134, 248, 91, 64, 228, 143, 62, 228, 143, 45, - 193, 70, 232, 254, 50, 193, 70, 232, 254, 45, 54, 193, 70, 232, 254, 50, - 54, 193, 70, 232, 254, 223, 127, 223, 111, 198, 174, 138, 223, 111, 223, - 112, 214, 94, 4, 81, 164, 235, 88, 215, 116, 51, 4, 238, 234, 211, 1, - 223, 124, 250, 169, 202, 249, 208, 193, 234, 1, 3, 24, 202, 94, 210, 108, - 234, 1, 3, 24, 202, 94, 210, 109, 4, 198, 148, 56, 227, 244, 118, 24, - 202, 94, 210, 108, 230, 234, 201, 96, 199, 17, 235, 78, 197, 238, 4, 45, - 134, 248, 91, 235, 78, 197, 238, 4, 50, 134, 248, 91, 62, 236, 244, 4, - 143, 55, 62, 218, 210, 64, 242, 219, 4, 143, 55, 62, 242, 219, 4, 143, - 55, 233, 239, 64, 201, 185, 233, 239, 62, 201, 185, 233, 239, 64, 236, - 243, 233, 239, 62, 236, 243, 233, 239, 64, 242, 218, 233, 239, 62, 242, - 218, 206, 46, 207, 14, 202, 19, 211, 55, 202, 19, 4, 210, 252, 207, 14, - 202, 19, 4, 228, 209, 105, 248, 127, 202, 18, 248, 127, 207, 14, 202, 18, - 54, 209, 73, 197, 221, 209, 73, 219, 195, 238, 116, 251, 65, 248, 5, 206, - 198, 238, 116, 251, 65, 248, 5, 198, 132, 216, 15, 215, 46, 47, 75, 211, - 55, 215, 46, 47, 107, 211, 55, 215, 46, 47, 25, 211, 55, 215, 46, 196, - 89, 211, 56, 4, 236, 96, 215, 46, 196, 89, 211, 56, 4, 209, 73, 215, 46, - 51, 223, 72, 211, 55, 215, 46, 51, 196, 89, 211, 55, 103, 219, 5, 24, - 211, 55, 103, 219, 5, 211, 46, 211, 55, 215, 46, 25, 211, 55, 215, 219, - 103, 200, 199, 200, 197, 4, 223, 85, 208, 20, 223, 86, 211, 55, 232, 205, - 210, 97, 223, 85, 223, 86, 4, 54, 105, 223, 86, 250, 93, 4, 202, 92, 242, - 211, 232, 39, 251, 34, 223, 83, 219, 89, 223, 84, 4, 207, 86, 210, 76, - 250, 195, 209, 45, 219, 89, 223, 84, 4, 204, 22, 210, 76, 250, 195, 209, - 45, 219, 89, 223, 84, 212, 255, 223, 129, 199, 29, 209, 45, 223, 86, 250, - 195, 41, 209, 55, 211, 55, 208, 14, 223, 86, 211, 55, 223, 86, 4, 117, - 63, 4, 106, 223, 86, 4, 25, 57, 223, 86, 4, 223, 71, 223, 86, 4, 196, 88, - 223, 86, 4, 210, 252, 223, 86, 4, 196, 99, 222, 172, 219, 245, 45, 197, - 238, 211, 55, 191, 167, 212, 253, 205, 87, 239, 14, 191, 167, 212, 253, - 205, 87, 209, 118, 191, 167, 212, 253, 205, 87, 208, 188, 107, 3, 4, 2, - 242, 219, 56, 107, 3, 4, 242, 210, 252, 9, 56, 107, 3, 4, 198, 148, 56, - 107, 3, 4, 75, 60, 107, 3, 4, 198, 148, 60, 107, 3, 4, 200, 225, 109, - 107, 3, 4, 62, 197, 237, 216, 18, 3, 4, 242, 27, 56, 216, 18, 3, 4, 75, - 60, 216, 18, 3, 4, 233, 42, 236, 94, 216, 18, 3, 4, 206, 175, 236, 94, - 107, 3, 223, 135, 45, 134, 242, 218, 107, 3, 223, 135, 50, 134, 242, 218, - 195, 149, 211, 46, 238, 171, 208, 193, 215, 112, 3, 4, 75, 56, 215, 112, - 3, 4, 196, 99, 204, 19, 208, 194, 4, 248, 29, 242, 170, 202, 63, 208, - 193, 215, 112, 3, 223, 135, 45, 134, 242, 218, 215, 112, 3, 223, 135, 50, - 134, 242, 218, 47, 215, 112, 3, 4, 242, 210, 252, 8, 215, 112, 3, 223, - 135, 54, 242, 218, 47, 236, 155, 57, 107, 3, 223, 135, 197, 237, 216, 18, - 3, 223, 135, 197, 237, 215, 112, 3, 223, 135, 197, 237, 223, 80, 208, - 193, 206, 193, 223, 80, 208, 193, 191, 167, 212, 253, 207, 59, 239, 14, - 251, 96, 211, 46, 238, 218, 223, 72, 4, 236, 96, 196, 89, 4, 216, 18, 57, - 196, 89, 4, 210, 252, 223, 72, 4, 210, 252, 223, 72, 4, 219, 5, 251, 74, - 196, 89, 4, 219, 5, 211, 45, 196, 89, 95, 223, 71, 223, 72, 95, 196, 88, - 196, 89, 95, 249, 38, 95, 223, 71, 223, 72, 95, 249, 38, 95, 196, 88, - 196, 89, 248, 166, 24, 222, 171, 4, 196, 88, 223, 72, 248, 166, 24, 222, - 171, 4, 223, 71, 242, 171, 196, 89, 4, 203, 254, 242, 171, 223, 72, 4, - 203, 254, 54, 51, 223, 71, 54, 51, 196, 88, 242, 171, 196, 89, 4, 203, - 255, 24, 202, 63, 208, 193, 219, 5, 24, 4, 75, 56, 219, 5, 211, 46, 4, - 75, 56, 54, 219, 5, 251, 74, 54, 219, 5, 211, 45, 103, 223, 73, 219, 5, - 251, 74, 103, 223, 73, 219, 5, 211, 45, 202, 75, 219, 245, 211, 45, 202, - 75, 219, 245, 251, 74, 219, 5, 211, 46, 210, 247, 219, 5, 251, 74, 219, - 5, 24, 4, 82, 201, 75, 219, 5, 211, 46, 4, 82, 201, 75, 219, 5, 24, 4, - 228, 209, 237, 170, 219, 5, 211, 46, 4, 228, 209, 237, 170, 219, 5, 24, - 4, 54, 210, 252, 219, 5, 24, 4, 196, 99, 219, 5, 24, 4, 54, 196, 99, 2, - 195, 146, 4, 196, 99, 219, 5, 211, 46, 4, 54, 210, 252, 219, 5, 211, 46, - 4, 54, 196, 99, 191, 167, 212, 253, 236, 107, 251, 24, 191, 167, 212, - 253, 207, 132, 251, 24, 234, 1, 3, 4, 75, 60, 227, 244, 4, 75, 56, 197, - 221, 228, 209, 249, 38, 4, 54, 81, 105, 197, 221, 228, 209, 249, 38, 4, - 197, 221, 81, 105, 198, 148, 211, 56, 4, 75, 56, 198, 148, 211, 56, 4, - 206, 175, 236, 94, 202, 175, 216, 18, 202, 174, 239, 1, 4, 75, 56, 234, - 1, 4, 250, 143, 251, 114, 234, 3, 118, 4, 242, 210, 252, 8, 250, 246, - 234, 3, 211, 46, 234, 3, 159, 234, 1, 3, 95, 107, 57, 107, 3, 95, 234, 1, - 57, 234, 1, 3, 95, 198, 148, 211, 55, 54, 242, 36, 234, 2, 103, 238, 250, - 234, 1, 202, 189, 115, 238, 250, 234, 1, 202, 189, 234, 1, 3, 4, 103, - 183, 95, 24, 103, 183, 60, 233, 250, 4, 232, 90, 183, 56, 219, 156, 4, - 242, 219, 223, 89, 230, 170, 4, 242, 219, 223, 89, 219, 156, 4, 208, 8, - 87, 56, 230, 170, 4, 208, 8, 87, 56, 219, 156, 211, 46, 202, 94, 234, 3, - 159, 230, 170, 211, 46, 202, 94, 234, 3, 159, 219, 156, 211, 46, 202, 94, - 234, 3, 118, 4, 75, 223, 89, 230, 170, 211, 46, 202, 94, 234, 3, 118, 4, - 75, 223, 89, 219, 156, 211, 46, 202, 94, 234, 3, 118, 4, 75, 56, 230, - 170, 211, 46, 202, 94, 234, 3, 118, 4, 75, 56, 219, 156, 211, 46, 202, - 94, 234, 3, 118, 4, 75, 95, 187, 230, 170, 211, 46, 202, 94, 234, 3, 118, - 4, 75, 95, 219, 200, 219, 156, 211, 46, 250, 247, 230, 170, 211, 46, 250, - 247, 219, 156, 24, 202, 163, 212, 255, 234, 3, 159, 230, 170, 24, 202, - 163, 212, 255, 234, 3, 159, 219, 156, 24, 212, 255, 250, 247, 230, 170, - 24, 212, 255, 250, 247, 219, 156, 95, 235, 87, 234, 3, 95, 230, 169, 230, - 170, 95, 235, 87, 234, 3, 95, 219, 155, 219, 156, 95, 202, 175, 211, 46, - 234, 2, 230, 170, 95, 202, 175, 211, 46, 234, 2, 219, 156, 95, 202, 175, - 95, 230, 169, 230, 170, 95, 202, 175, 95, 219, 155, 219, 156, 95, 230, - 170, 95, 235, 87, 234, 2, 230, 170, 95, 219, 156, 95, 235, 87, 234, 2, - 219, 156, 95, 202, 94, 234, 3, 95, 230, 170, 95, 202, 94, 234, 2, 230, - 170, 95, 202, 94, 234, 3, 95, 219, 156, 95, 202, 94, 234, 2, 202, 94, - 234, 3, 118, 211, 46, 219, 155, 202, 94, 234, 3, 118, 211, 46, 230, 169, - 202, 94, 234, 3, 118, 211, 46, 219, 156, 4, 75, 223, 89, 202, 94, 234, 3, - 118, 211, 46, 230, 170, 4, 75, 223, 89, 235, 87, 234, 3, 118, 211, 46, - 219, 155, 235, 87, 234, 3, 118, 211, 46, 230, 169, 235, 87, 202, 94, 234, - 3, 118, 211, 46, 219, 155, 235, 87, 202, 94, 234, 3, 118, 211, 46, 230, - 169, 202, 175, 211, 46, 219, 155, 202, 175, 211, 46, 230, 169, 202, 175, - 95, 219, 156, 95, 234, 1, 57, 202, 175, 95, 230, 170, 95, 234, 1, 57, 54, - 214, 74, 219, 155, 54, 214, 74, 230, 169, 54, 214, 74, 219, 156, 4, 196, - 99, 230, 170, 210, 247, 219, 155, 230, 170, 248, 166, 219, 155, 219, 156, - 242, 171, 247, 157, 238, 117, 230, 170, 242, 171, 247, 157, 238, 117, - 219, 156, 242, 171, 247, 157, 238, 118, 95, 202, 94, 234, 2, 230, 170, - 242, 171, 247, 157, 238, 118, 95, 202, 94, 234, 2, 202, 64, 199, 33, 219, - 243, 199, 33, 202, 64, 199, 34, 211, 46, 234, 3, 159, 219, 243, 199, 34, - 211, 46, 234, 3, 159, 234, 1, 3, 4, 247, 193, 56, 208, 225, 95, 202, 163, - 234, 1, 57, 200, 216, 95, 202, 163, 234, 1, 57, 208, 225, 95, 202, 163, - 212, 255, 234, 3, 159, 200, 216, 95, 202, 163, 212, 255, 234, 3, 159, - 208, 225, 95, 234, 1, 57, 200, 216, 95, 234, 1, 57, 208, 225, 95, 212, - 255, 234, 3, 159, 200, 216, 95, 212, 255, 234, 3, 159, 208, 225, 95, 251, - 114, 234, 3, 159, 200, 216, 95, 251, 114, 234, 3, 159, 208, 225, 95, 212, - 255, 251, 114, 234, 3, 159, 200, 216, 95, 212, 255, 251, 114, 234, 3, - 159, 54, 208, 224, 54, 200, 215, 200, 224, 4, 236, 96, 200, 176, 4, 236, - 96, 200, 224, 4, 107, 3, 60, 200, 176, 4, 107, 3, 60, 200, 224, 4, 215, - 112, 3, 60, 200, 176, 4, 215, 112, 3, 60, 200, 224, 80, 211, 46, 234, 3, - 118, 4, 75, 56, 200, 176, 80, 211, 46, 234, 3, 118, 4, 75, 56, 200, 224, - 80, 95, 234, 1, 57, 200, 176, 80, 95, 234, 1, 57, 200, 224, 80, 95, 198, - 148, 211, 55, 200, 176, 80, 95, 198, 148, 211, 55, 200, 224, 80, 95, 251, - 114, 234, 3, 159, 200, 176, 80, 95, 251, 114, 234, 3, 159, 200, 224, 80, - 95, 212, 255, 234, 3, 159, 200, 176, 80, 95, 212, 255, 234, 3, 159, 51, - 45, 211, 66, 111, 211, 55, 51, 50, 211, 66, 111, 211, 55, 242, 171, 200, - 223, 242, 171, 200, 175, 242, 171, 200, 224, 211, 46, 234, 3, 159, 242, - 171, 200, 176, 211, 46, 234, 3, 159, 200, 224, 95, 200, 175, 200, 176, - 95, 200, 223, 200, 224, 95, 200, 223, 200, 176, 95, 200, 175, 200, 176, - 248, 166, 200, 223, 200, 176, 248, 166, 24, 222, 171, 247, 157, 237, 171, - 4, 200, 223, 234, 89, 80, 211, 58, 235, 74, 209, 108, 4, 199, 117, 198, - 48, 198, 3, 223, 71, 232, 108, 213, 14, 203, 35, 45, 199, 223, 203, 35, - 143, 199, 223, 203, 35, 132, 199, 223, 209, 246, 4, 206, 3, 81, 249, 38, - 197, 221, 50, 197, 53, 54, 81, 249, 38, 45, 197, 53, 81, 249, 38, 54, 45, - 197, 53, 54, 81, 249, 38, 54, 45, 197, 53, 177, 237, 171, 232, 60, 45, - 216, 172, 80, 54, 195, 132, 203, 35, 143, 199, 224, 4, 210, 252, 203, 35, - 132, 199, 224, 4, 196, 99, 203, 35, 132, 199, 224, 95, 203, 35, 143, 199, - 223, 54, 143, 199, 223, 54, 132, 199, 223, 54, 201, 23, 212, 255, 57, - 207, 13, 54, 201, 23, 212, 255, 57, 236, 119, 212, 255, 236, 163, 4, 207, - 13, 214, 93, 202, 92, 81, 219, 89, 4, 242, 219, 56, 81, 219, 89, 4, 242, - 219, 60, 143, 199, 224, 4, 242, 219, 60, 210, 109, 4, 228, 209, 105, 210, - 109, 4, 198, 148, 211, 55, 197, 221, 81, 249, 38, 248, 120, 207, 60, 197, - 221, 81, 249, 38, 4, 228, 209, 105, 197, 221, 242, 36, 211, 55, 197, 221, - 214, 74, 219, 155, 197, 221, 214, 74, 230, 169, 235, 87, 202, 94, 219, - 156, 211, 46, 234, 3, 159, 235, 87, 202, 94, 230, 170, 211, 46, 234, 3, - 159, 197, 221, 202, 19, 248, 120, 207, 60, 219, 245, 197, 221, 81, 249, - 38, 211, 55, 54, 202, 19, 211, 55, 64, 81, 164, 215, 46, 64, 81, 164, - 185, 234, 160, 64, 55, 185, 193, 103, 64, 55, 201, 253, 234, 160, 64, 55, - 201, 253, 193, 103, 64, 55, 45, 50, 64, 55, 117, 62, 55, 196, 62, 62, 55, - 235, 75, 62, 55, 185, 234, 160, 62, 55, 185, 193, 103, 62, 55, 201, 253, - 234, 160, 62, 55, 201, 253, 193, 103, 62, 55, 45, 50, 62, 55, 132, 143, - 62, 55, 96, 63, 4, 198, 131, 235, 74, 96, 63, 4, 198, 131, 196, 61, 117, - 63, 4, 198, 131, 235, 74, 117, 63, 4, 198, 131, 196, 61, 51, 4, 198, 49, - 134, 248, 91, 51, 4, 248, 29, 134, 248, 91, 51, 4, 116, 50, 236, 250, - 134, 248, 91, 51, 4, 110, 45, 236, 250, 134, 248, 91, 236, 244, 4, 45, - 134, 248, 91, 236, 244, 4, 50, 134, 248, 91, 236, 244, 4, 198, 49, 134, - 248, 91, 236, 244, 4, 248, 29, 134, 248, 91, 235, 94, 201, 185, 62, 219, - 245, 201, 185, 64, 219, 245, 201, 185, 62, 195, 80, 2, 201, 185, 64, 195, - 80, 2, 201, 185, 62, 210, 15, 64, 210, 15, 64, 229, 150, 62, 229, 150, - 228, 209, 62, 229, 150, 62, 219, 245, 242, 218, 62, 216, 194, 236, 243, - 64, 216, 194, 236, 243, 62, 216, 194, 218, 210, 64, 216, 194, 218, 210, - 62, 2, 236, 243, 62, 2, 218, 210, 64, 2, 218, 210, 62, 228, 209, 234, 79, - 64, 228, 209, 234, 79, 62, 81, 234, 79, 64, 81, 234, 79, 45, 63, 4, 2, - 242, 218, 115, 117, 250, 181, 45, 63, 4, 47, 209, 73, 177, 117, 201, 178, - 55, 117, 197, 9, 63, 4, 81, 105, 117, 197, 9, 63, 4, 54, 81, 105, 117, - 197, 9, 63, 232, 60, 164, 117, 197, 9, 197, 221, 237, 171, 55, 117, 63, - 4, 235, 94, 201, 75, 117, 63, 4, 199, 211, 4, 81, 105, 117, 63, 4, 199, - 211, 4, 54, 81, 105, 117, 197, 9, 63, 4, 199, 210, 117, 197, 9, 63, 4, - 199, 211, 4, 81, 105, 117, 197, 9, 63, 4, 199, 211, 4, 54, 81, 105, 117, - 63, 198, 211, 192, 235, 193, 137, 63, 209, 51, 236, 186, 219, 200, 234, - 1, 3, 95, 117, 55, 207, 14, 198, 148, 211, 56, 95, 117, 55, 117, 63, 95, - 207, 14, 251, 114, 234, 3, 159, 96, 63, 198, 211, 230, 169, 96, 63, 198, - 211, 200, 175, 117, 208, 20, 55, 96, 208, 20, 55, 207, 14, 198, 148, 211, - 56, 95, 96, 55, 96, 63, 95, 207, 14, 251, 114, 234, 3, 159, 198, 148, - 211, 56, 95, 117, 55, 117, 63, 95, 251, 114, 234, 3, 159, 117, 63, 95, - 207, 14, 198, 148, 211, 55, 96, 63, 95, 207, 14, 198, 148, 211, 55, 235, - 75, 197, 236, 191, 21, 55, 203, 35, 202, 94, 185, 55, 203, 35, 249, 93, - 201, 253, 55, 64, 216, 194, 201, 97, 62, 2, 201, 97, 64, 2, 201, 97, 62, - 206, 198, 210, 15, 64, 206, 198, 210, 15, 88, 219, 245, 242, 218, 88, - 210, 254, 4, 210, 254, 223, 89, 88, 242, 219, 4, 242, 219, 223, 89, 88, - 242, 218, 88, 47, 205, 149, 202, 94, 185, 63, 4, 228, 218, 229, 203, 249, - 93, 201, 253, 63, 4, 228, 218, 199, 210, 202, 94, 185, 63, 4, 228, 209, - 199, 210, 249, 93, 201, 253, 63, 4, 228, 209, 199, 210, 248, 174, 63, - 209, 51, 235, 75, 199, 20, 185, 234, 159, 203, 35, 248, 174, 63, 209, 51, - 235, 75, 199, 20, 185, 234, 159, 117, 197, 236, 55, 196, 62, 197, 236, - 55, 96, 197, 236, 55, 235, 75, 197, 236, 55, 45, 50, 197, 236, 55, 132, - 143, 197, 236, 55, 185, 193, 103, 197, 236, 55, 185, 234, 160, 197, 236, - 55, 201, 253, 234, 160, 197, 236, 55, 201, 253, 193, 103, 197, 236, 55, - 117, 197, 236, 237, 169, 55, 196, 62, 197, 236, 237, 169, 55, 96, 197, - 236, 237, 169, 55, 235, 75, 197, 236, 237, 169, 55, 242, 173, 197, 236, - 211, 66, 242, 219, 55, 251, 34, 197, 236, 211, 66, 242, 219, 55, 117, - 197, 236, 63, 118, 164, 196, 62, 197, 236, 63, 118, 164, 96, 197, 236, - 63, 118, 164, 235, 75, 197, 236, 63, 118, 164, 185, 193, 103, 197, 236, - 63, 118, 164, 185, 234, 160, 197, 236, 63, 118, 164, 201, 253, 234, 160, - 197, 236, 63, 118, 164, 201, 253, 193, 103, 197, 236, 63, 118, 164, 117, - 197, 236, 63, 4, 54, 228, 209, 105, 196, 62, 197, 236, 63, 4, 54, 228, - 209, 105, 96, 197, 236, 63, 4, 54, 228, 209, 105, 235, 75, 197, 236, 63, - 4, 54, 228, 209, 105, 228, 209, 199, 232, 221, 197, 81, 199, 232, 221, - 197, 117, 197, 236, 63, 138, 96, 197, 236, 55, 196, 62, 197, 236, 63, - 117, 80, 235, 75, 197, 236, 55, 96, 197, 236, 63, 138, 117, 197, 236, 55, - 235, 75, 197, 236, 63, 117, 80, 196, 62, 197, 236, 55, 117, 197, 236, - 210, 186, 250, 181, 196, 62, 197, 236, 210, 186, 250, 181, 96, 197, 236, - 210, 186, 250, 181, 235, 75, 197, 236, 210, 186, 250, 181, 117, 62, 47, - 64, 55, 196, 62, 62, 47, 64, 55, 96, 62, 47, 64, 55, 235, 75, 62, 47, 64, - 55, 251, 34, 197, 236, 50, 196, 217, 55, 251, 34, 197, 236, 248, 29, 196, - 217, 55, 251, 34, 197, 236, 45, 196, 217, 55, 251, 34, 197, 236, 198, 49, - 196, 217, 55, 207, 18, 219, 200, 207, 18, 187, 214, 63, 219, 200, 214, - 63, 187, 232, 90, 238, 211, 250, 182, 242, 214, 251, 33, 96, 62, 55, 16, - 39, 196, 251, 41, 234, 90, 198, 220, 198, 47, 117, 233, 251, 250, 185, - 198, 220, 206, 199, 196, 62, 233, 251, 250, 185, 198, 220, 198, 47, 96, - 233, 251, 250, 185, 198, 220, 219, 196, 235, 75, 233, 251, 250, 185, 62, - 117, 233, 251, 250, 185, 62, 196, 62, 233, 251, 250, 185, 62, 96, 233, - 251, 250, 185, 62, 235, 75, 233, 251, 250, 185, 235, 75, 197, 236, 63, 4, - 177, 198, 131, 219, 190, 235, 75, 197, 236, 63, 4, 177, 198, 131, 206, - 192, 196, 62, 197, 236, 63, 4, 177, 198, 131, 219, 190, 196, 62, 197, - 236, 63, 4, 177, 198, 131, 206, 192, 117, 197, 236, 63, 4, 177, 198, 131, - 196, 61, 96, 197, 236, 63, 4, 177, 198, 131, 196, 61, 117, 197, 236, 63, - 4, 177, 198, 131, 235, 74, 96, 197, 236, 63, 4, 177, 198, 131, 235, 74, - 62, 238, 116, 235, 75, 24, 117, 55, 62, 238, 116, 235, 75, 24, 96, 55, - 62, 238, 116, 196, 62, 24, 117, 55, 62, 238, 116, 196, 62, 24, 96, 55, - 62, 238, 116, 117, 24, 196, 62, 55, 62, 238, 116, 96, 24, 196, 62, 55, - 62, 238, 116, 117, 24, 235, 75, 55, 62, 238, 116, 96, 24, 235, 75, 55, - 206, 243, 63, 143, 219, 200, 206, 243, 63, 143, 187, 206, 243, 63, 132, - 219, 200, 206, 243, 63, 132, 187, 206, 243, 63, 45, 196, 73, 206, 243, - 63, 50, 196, 73, 206, 243, 63, 45, 235, 79, 206, 243, 63, 50, 235, 79, - 196, 62, 64, 63, 232, 60, 249, 38, 4, 228, 209, 164, 132, 250, 186, 223, - 135, 41, 207, 88, 248, 14, 210, 247, 64, 201, 183, 210, 247, 64, 24, 62, - 201, 183, 210, 247, 62, 201, 183, 249, 57, 111, 4, 155, 192, 235, 47, - 192, 235, 47, 28, 192, 235, 62, 51, 246, 227, 62, 236, 244, 246, 227, - 152, 62, 210, 15, 228, 209, 62, 211, 148, 62, 211, 148, 62, 216, 194, - 196, 72, 197, 238, 246, 227, 62, 216, 194, 235, 78, 197, 238, 246, 227, - 62, 216, 194, 219, 195, 197, 238, 246, 227, 62, 216, 194, 206, 198, 197, - 238, 246, 227, 214, 81, 232, 107, 109, 198, 49, 134, 62, 242, 218, 248, - 29, 134, 62, 242, 218, 155, 232, 90, 209, 53, 62, 238, 112, 206, 117, - 155, 232, 90, 209, 53, 62, 238, 112, 64, 232, 90, 209, 53, 238, 112, 206, - 117, 64, 232, 90, 209, 53, 238, 112, 51, 209, 18, 223, 116, 196, 103, 57, - 230, 154, 77, 209, 70, 232, 107, 109, 209, 70, 232, 107, 139, 209, 70, - 232, 107, 137, 209, 70, 232, 107, 153, 198, 5, 208, 178, 250, 139, 228, - 61, 209, 187, 214, 77, 64, 215, 189, 204, 28, 62, 236, 244, 211, 94, 238, - 170, 197, 198, 155, 215, 189, 250, 177, 238, 132, 230, 55, 191, 75, 220, - 234, 251, 3, 251, 236, 193, 244, 209, 19, 45, 134, 62, 201, 97, 50, 134, - 62, 201, 97, 201, 98, 4, 45, 134, 248, 91, 201, 98, 4, 50, 134, 248, 91, - 117, 197, 9, 63, 4, 197, 238, 250, 183, 196, 62, 197, 9, 63, 4, 197, 238, - 250, 183, 96, 197, 9, 63, 4, 197, 238, 250, 183, 235, 75, 197, 9, 63, 4, - 197, 238, 250, 183, 233, 241, 232, 107, 108, 233, 241, 232, 107, 109, - 205, 46, 206, 26, 250, 138, 16, 195, 49, 206, 26, 250, 138, 16, 212, 241, - 206, 26, 250, 138, 16, 207, 252, 206, 26, 250, 138, 16, 248, 115, 206, - 26, 250, 138, 16, 204, 11, 206, 26, 250, 138, 16, 197, 252, 234, 1, 3, 4, - 223, 112, 60, 196, 85, 113, 204, 7, 113, 235, 84, 113, 210, 86, 113, 207, - 13, 50, 251, 64, 229, 171, 210, 68, 113, 133, 6, 1, 250, 72, 133, 6, 1, - 247, 204, 133, 6, 1, 195, 148, 133, 6, 1, 230, 238, 133, 6, 1, 236, 124, - 133, 6, 1, 192, 49, 133, 6, 1, 191, 55, 133, 6, 1, 234, 242, 133, 6, 1, - 191, 82, 133, 6, 1, 223, 11, 133, 6, 1, 89, 223, 11, 133, 6, 1, 70, 133, - 6, 1, 236, 145, 133, 6, 1, 222, 67, 133, 6, 1, 219, 51, 133, 6, 1, 215, - 52, 133, 6, 1, 214, 196, 133, 6, 1, 211, 78, 133, 6, 1, 209, 48, 133, 6, - 1, 206, 174, 133, 6, 1, 202, 72, 133, 6, 1, 197, 40, 133, 6, 1, 196, 120, - 133, 6, 1, 232, 63, 133, 6, 1, 229, 156, 133, 6, 1, 211, 10, 133, 6, 1, - 210, 53, 133, 6, 1, 203, 3, 133, 6, 1, 197, 142, 133, 6, 1, 243, 6, 133, - 6, 1, 203, 160, 133, 6, 1, 192, 58, 133, 6, 1, 192, 60, 133, 6, 1, 192, - 93, 133, 6, 1, 201, 215, 144, 133, 6, 1, 191, 225, 133, 6, 1, 2, 191, - 190, 133, 6, 1, 2, 191, 191, 4, 199, 210, 133, 6, 1, 192, 12, 133, 6, 1, - 223, 54, 2, 191, 190, 133, 6, 1, 248, 127, 191, 190, 133, 6, 1, 223, 54, - 248, 127, 191, 190, 133, 6, 1, 232, 187, 133, 6, 1, 223, 9, 133, 6, 1, - 203, 2, 133, 6, 1, 197, 211, 65, 133, 6, 1, 219, 233, 215, 52, 133, 6, 1, - 247, 25, 243, 6, 133, 2, 1, 250, 72, 133, 2, 1, 247, 204, 133, 2, 1, 195, - 148, 133, 2, 1, 230, 238, 133, 2, 1, 236, 124, 133, 2, 1, 192, 49, 133, - 2, 1, 191, 55, 133, 2, 1, 234, 242, 133, 2, 1, 191, 82, 133, 2, 1, 223, - 11, 133, 2, 1, 89, 223, 11, 133, 2, 1, 70, 133, 2, 1, 236, 145, 133, 2, - 1, 222, 67, 133, 2, 1, 219, 51, 133, 2, 1, 215, 52, 133, 2, 1, 214, 196, - 133, 2, 1, 211, 78, 133, 2, 1, 209, 48, 133, 2, 1, 206, 174, 133, 2, 1, - 202, 72, 133, 2, 1, 197, 40, 133, 2, 1, 196, 120, 133, 2, 1, 232, 63, - 133, 2, 1, 229, 156, 133, 2, 1, 211, 10, 133, 2, 1, 210, 53, 133, 2, 1, - 203, 3, 133, 2, 1, 197, 142, 133, 2, 1, 243, 6, 133, 2, 1, 203, 160, 133, - 2, 1, 192, 58, 133, 2, 1, 192, 60, 133, 2, 1, 192, 93, 133, 2, 1, 201, - 215, 144, 133, 2, 1, 191, 225, 133, 2, 1, 2, 191, 190, 133, 2, 1, 2, 191, - 191, 4, 199, 210, 133, 2, 1, 192, 12, 133, 2, 1, 223, 54, 2, 191, 190, - 133, 2, 1, 248, 127, 191, 190, 133, 2, 1, 223, 54, 248, 127, 191, 190, - 133, 2, 1, 232, 187, 133, 2, 1, 223, 9, 133, 2, 1, 203, 2, 133, 2, 1, - 197, 211, 65, 133, 2, 1, 219, 233, 215, 52, 133, 2, 1, 247, 25, 243, 6, - 8, 6, 1, 220, 119, 4, 54, 164, 8, 2, 1, 220, 119, 4, 54, 164, 8, 6, 1, - 220, 119, 4, 82, 198, 147, 8, 6, 1, 210, 227, 4, 105, 8, 6, 1, 207, 217, - 4, 199, 210, 8, 2, 1, 41, 4, 105, 8, 2, 1, 200, 40, 4, 236, 250, 105, 8, - 6, 1, 230, 84, 4, 237, 42, 8, 2, 1, 230, 84, 4, 237, 42, 8, 6, 1, 222, - 126, 4, 237, 42, 8, 2, 1, 222, 126, 4, 237, 42, 8, 6, 1, 191, 167, 4, - 237, 42, 8, 2, 1, 191, 167, 4, 237, 42, 8, 6, 1, 251, 109, 8, 6, 1, 218, - 148, 4, 106, 8, 6, 1, 152, 65, 8, 6, 1, 152, 251, 109, 8, 2, 1, 196, 9, - 4, 50, 106, 8, 6, 1, 193, 222, 4, 106, 8, 2, 1, 193, 222, 4, 106, 8, 2, - 1, 196, 9, 4, 238, 128, 8, 6, 1, 134, 230, 83, 8, 2, 1, 134, 230, 83, 8, - 2, 1, 199, 208, 209, 202, 8, 2, 1, 234, 227, 4, 212, 252, 8, 2, 1, 152, - 207, 217, 4, 199, 210, 8, 2, 1, 186, 4, 131, 206, 184, 223, 89, 8, 1, 2, - 6, 152, 73, 8, 200, 225, 2, 1, 223, 7, 59, 1, 6, 196, 8, 8, 6, 1, 206, 4, - 4, 200, 142, 199, 210, 8, 6, 1, 191, 167, 4, 200, 142, 199, 210, 93, 6, - 1, 251, 135, 93, 2, 1, 251, 135, 93, 6, 1, 195, 63, 93, 2, 1, 195, 63, - 93, 6, 1, 231, 174, 93, 2, 1, 231, 174, 93, 6, 1, 237, 208, 93, 2, 1, - 237, 208, 93, 6, 1, 234, 122, 93, 2, 1, 234, 122, 93, 6, 1, 202, 2, 93, - 2, 1, 202, 2, 93, 6, 1, 191, 95, 93, 2, 1, 191, 95, 93, 6, 1, 229, 229, - 93, 2, 1, 229, 229, 93, 6, 1, 199, 8, 93, 2, 1, 199, 8, 93, 6, 1, 228, 2, - 93, 2, 1, 228, 2, 93, 6, 1, 222, 51, 93, 2, 1, 222, 51, 93, 6, 1, 219, - 228, 93, 2, 1, 219, 228, 93, 6, 1, 216, 81, 93, 2, 1, 216, 81, 93, 6, 1, - 213, 205, 93, 2, 1, 213, 205, 93, 6, 1, 220, 224, 93, 2, 1, 220, 224, 93, - 6, 1, 74, 93, 2, 1, 74, 93, 6, 1, 209, 176, 93, 2, 1, 209, 176, 93, 6, 1, - 206, 157, 93, 2, 1, 206, 157, 93, 6, 1, 202, 178, 93, 2, 1, 202, 178, 93, - 6, 1, 199, 161, 93, 2, 1, 199, 161, 93, 6, 1, 196, 164, 93, 2, 1, 196, - 164, 93, 6, 1, 232, 238, 93, 2, 1, 232, 238, 93, 6, 1, 221, 166, 93, 2, - 1, 221, 166, 93, 6, 1, 208, 169, 93, 2, 1, 208, 169, 93, 6, 1, 211, 70, - 93, 2, 1, 211, 70, 93, 6, 1, 236, 248, 251, 141, 93, 2, 1, 236, 248, 251, - 141, 93, 6, 1, 38, 93, 251, 178, 93, 2, 1, 38, 93, 251, 178, 93, 6, 1, - 238, 151, 234, 122, 93, 2, 1, 238, 151, 234, 122, 93, 6, 1, 236, 248, - 222, 51, 93, 2, 1, 236, 248, 222, 51, 93, 6, 1, 236, 248, 213, 205, 93, - 2, 1, 236, 248, 213, 205, 93, 6, 1, 238, 151, 213, 205, 93, 2, 1, 238, - 151, 213, 205, 93, 6, 1, 38, 93, 211, 70, 93, 2, 1, 38, 93, 211, 70, 93, - 6, 1, 205, 140, 93, 2, 1, 205, 140, 93, 6, 1, 238, 167, 203, 100, 93, 2, - 1, 238, 167, 203, 100, 93, 6, 1, 38, 93, 203, 100, 93, 2, 1, 38, 93, 203, - 100, 93, 6, 1, 38, 93, 233, 226, 93, 2, 1, 38, 93, 233, 226, 93, 6, 1, - 251, 161, 221, 171, 93, 2, 1, 251, 161, 221, 171, 93, 6, 1, 236, 248, - 228, 210, 93, 2, 1, 236, 248, 228, 210, 93, 6, 1, 38, 93, 228, 210, 93, - 2, 1, 38, 93, 228, 210, 93, 6, 1, 38, 93, 144, 93, 2, 1, 38, 93, 144, 93, - 6, 1, 220, 118, 144, 93, 2, 1, 220, 118, 144, 93, 6, 1, 38, 93, 229, 177, - 93, 2, 1, 38, 93, 229, 177, 93, 6, 1, 38, 93, 229, 232, 93, 2, 1, 38, 93, - 229, 232, 93, 6, 1, 38, 93, 231, 169, 93, 2, 1, 38, 93, 231, 169, 93, 6, - 1, 38, 93, 236, 148, 93, 2, 1, 38, 93, 236, 148, 93, 6, 1, 38, 93, 203, - 66, 93, 2, 1, 38, 93, 203, 66, 93, 6, 1, 38, 212, 132, 203, 66, 93, 2, 1, - 38, 212, 132, 203, 66, 93, 6, 1, 38, 212, 132, 214, 2, 93, 2, 1, 38, 212, - 132, 214, 2, 93, 6, 1, 38, 212, 132, 212, 68, 93, 2, 1, 38, 212, 132, - 212, 68, 93, 6, 1, 38, 212, 132, 193, 138, 93, 2, 1, 38, 212, 132, 193, - 138, 93, 16, 222, 75, 93, 16, 216, 82, 206, 157, 93, 16, 209, 177, 206, - 157, 93, 16, 201, 84, 93, 16, 199, 162, 206, 157, 93, 16, 221, 167, 206, - 157, 93, 16, 203, 67, 202, 178, 93, 6, 1, 238, 151, 203, 100, 93, 2, 1, - 238, 151, 203, 100, 93, 6, 1, 238, 151, 231, 169, 93, 2, 1, 238, 151, - 231, 169, 93, 33, 213, 206, 56, 93, 33, 201, 208, 250, 151, 93, 33, 201, - 208, 219, 164, 93, 6, 1, 248, 55, 221, 171, 93, 2, 1, 248, 55, 221, 171, - 93, 38, 212, 132, 232, 42, 201, 58, 93, 38, 212, 132, 236, 189, 208, 8, - 77, 93, 38, 212, 132, 223, 114, 208, 8, 77, 93, 38, 212, 132, 195, 134, - 236, 160, 93, 232, 80, 91, 230, 37, 93, 232, 42, 201, 58, 93, 215, 184, - 236, 160, 100, 2, 1, 251, 81, 100, 2, 1, 249, 51, 100, 2, 1, 231, 173, - 100, 2, 1, 236, 105, 100, 2, 1, 234, 61, 100, 2, 1, 195, 46, 100, 2, 1, - 191, 80, 100, 2, 1, 199, 188, 100, 2, 1, 223, 134, 100, 2, 1, 222, 61, - 100, 2, 1, 219, 239, 100, 2, 1, 217, 70, 100, 2, 1, 214, 202, 100, 2, 1, - 211, 93, 100, 2, 1, 210, 121, 100, 2, 1, 191, 67, 100, 2, 1, 207, 158, - 100, 2, 1, 205, 137, 100, 2, 1, 199, 174, 100, 2, 1, 196, 109, 100, 2, 1, - 209, 211, 100, 2, 1, 221, 176, 100, 2, 1, 231, 45, 100, 2, 1, 208, 74, - 100, 2, 1, 203, 64, 100, 2, 1, 243, 33, 100, 2, 1, 247, 80, 100, 2, 1, - 222, 207, 100, 2, 1, 242, 226, 100, 2, 1, 246, 193, 100, 2, 1, 192, 218, - 100, 2, 1, 222, 222, 100, 2, 1, 230, 54, 100, 2, 1, 229, 213, 100, 2, 1, - 229, 113, 100, 2, 1, 193, 123, 100, 2, 1, 229, 242, 100, 2, 1, 228, 235, - 100, 2, 1, 192, 14, 100, 2, 1, 251, 218, 198, 170, 1, 169, 198, 170, 1, - 192, 136, 198, 170, 1, 192, 135, 198, 170, 1, 192, 125, 198, 170, 1, 192, - 123, 198, 170, 1, 248, 168, 252, 10, 192, 118, 198, 170, 1, 192, 118, - 198, 170, 1, 192, 133, 198, 170, 1, 192, 130, 198, 170, 1, 192, 132, 198, - 170, 1, 192, 131, 198, 170, 1, 192, 40, 198, 170, 1, 192, 127, 198, 170, - 1, 192, 116, 198, 170, 1, 197, 82, 192, 116, 198, 170, 1, 192, 113, 198, - 170, 1, 192, 121, 198, 170, 1, 248, 168, 252, 10, 192, 121, 198, 170, 1, - 197, 82, 192, 121, 198, 170, 1, 192, 120, 198, 170, 1, 192, 140, 198, - 170, 1, 192, 114, 198, 170, 1, 197, 82, 192, 114, 198, 170, 1, 192, 103, - 198, 170, 1, 197, 82, 192, 103, 198, 170, 1, 192, 33, 198, 170, 1, 192, - 82, 198, 170, 1, 251, 191, 192, 82, 198, 170, 1, 197, 82, 192, 82, 198, - 170, 1, 192, 112, 198, 170, 1, 192, 111, 198, 170, 1, 192, 108, 198, 170, - 1, 197, 82, 192, 122, 198, 170, 1, 197, 82, 192, 106, 198, 170, 1, 192, - 104, 198, 170, 1, 191, 225, 198, 170, 1, 192, 101, 198, 170, 1, 192, 99, - 198, 170, 1, 192, 124, 198, 170, 1, 197, 82, 192, 124, 198, 170, 1, 250, - 77, 192, 124, 198, 170, 1, 192, 98, 198, 170, 1, 192, 96, 198, 170, 1, - 192, 97, 198, 170, 1, 192, 95, 198, 170, 1, 192, 94, 198, 170, 1, 192, - 134, 198, 170, 1, 192, 92, 198, 170, 1, 192, 90, 198, 170, 1, 192, 89, - 198, 170, 1, 192, 86, 198, 170, 1, 192, 83, 198, 170, 1, 199, 152, 192, - 83, 198, 170, 1, 192, 81, 198, 170, 1, 192, 80, 198, 170, 1, 192, 12, - 198, 170, 59, 1, 220, 91, 77, 198, 170, 204, 6, 77, 198, 170, 119, 222, - 169, 36, 5, 219, 18, 36, 5, 215, 244, 36, 5, 206, 149, 36, 5, 202, 33, - 36, 5, 203, 50, 36, 5, 248, 62, 36, 5, 198, 86, 36, 5, 242, 50, 36, 5, - 213, 23, 36, 5, 212, 51, 36, 5, 230, 231, 211, 169, 36, 5, 191, 6, 36, 5, - 236, 127, 36, 5, 237, 115, 36, 5, 222, 173, 36, 5, 198, 235, 36, 5, 243, - 19, 36, 5, 209, 189, 36, 5, 209, 64, 36, 5, 231, 60, 36, 5, 231, 56, 36, - 5, 231, 57, 36, 5, 231, 58, 36, 5, 201, 170, 36, 5, 201, 124, 36, 5, 201, - 137, 36, 5, 201, 169, 36, 5, 201, 142, 36, 5, 201, 143, 36, 5, 201, 129, - 36, 5, 247, 17, 36, 5, 246, 252, 36, 5, 246, 254, 36, 5, 247, 16, 36, 5, - 247, 14, 36, 5, 247, 15, 36, 5, 246, 253, 36, 5, 190, 224, 36, 5, 190, - 202, 36, 5, 190, 215, 36, 5, 190, 223, 36, 5, 190, 218, 36, 5, 190, 219, - 36, 5, 190, 207, 36, 5, 247, 12, 36, 5, 246, 255, 36, 5, 247, 1, 36, 5, - 247, 11, 36, 5, 247, 9, 36, 5, 247, 10, 36, 5, 247, 0, 36, 5, 207, 229, - 36, 5, 207, 219, 36, 5, 207, 225, 36, 5, 207, 228, 36, 5, 207, 226, 36, - 5, 207, 227, 36, 5, 207, 224, 36, 5, 220, 129, 36, 5, 220, 121, 36, 5, - 220, 124, 36, 5, 220, 128, 36, 5, 220, 125, 36, 5, 220, 126, 36, 5, 220, - 122, 36, 5, 192, 175, 36, 5, 192, 162, 36, 5, 192, 170, 36, 5, 192, 174, - 36, 5, 192, 172, 36, 5, 192, 173, 36, 5, 192, 169, 36, 5, 230, 95, 36, 5, - 230, 85, 36, 5, 230, 88, 36, 5, 230, 94, 36, 5, 230, 90, 36, 5, 230, 91, - 36, 5, 230, 87, 33, 42, 1, 248, 223, 33, 42, 1, 195, 150, 33, 42, 1, 231, - 40, 33, 42, 1, 237, 101, 33, 42, 1, 191, 62, 33, 42, 1, 191, 87, 33, 42, - 1, 157, 33, 42, 1, 234, 97, 33, 42, 1, 234, 72, 33, 42, 1, 234, 61, 33, - 42, 1, 74, 33, 42, 1, 210, 53, 33, 42, 1, 233, 248, 33, 42, 1, 233, 236, - 33, 42, 1, 199, 140, 33, 42, 1, 144, 33, 42, 1, 197, 157, 33, 42, 1, 243, - 79, 33, 42, 1, 203, 160, 33, 42, 1, 203, 111, 33, 42, 1, 232, 187, 33, - 42, 1, 233, 232, 33, 42, 1, 65, 33, 42, 1, 223, 197, 33, 42, 1, 236, 146, - 33, 42, 1, 215, 202, 196, 124, 33, 42, 1, 192, 95, 33, 42, 1, 191, 225, - 33, 42, 1, 223, 53, 65, 33, 42, 1, 219, 59, 191, 190, 33, 42, 1, 248, - 127, 191, 190, 33, 42, 1, 223, 53, 248, 127, 191, 190, 50, 251, 65, 200, - 220, 217, 32, 50, 251, 65, 235, 94, 200, 220, 217, 32, 45, 200, 220, 248, - 5, 50, 200, 220, 248, 5, 45, 235, 94, 200, 220, 248, 5, 50, 235, 94, 200, - 220, 248, 5, 207, 142, 223, 76, 217, 32, 207, 142, 235, 94, 223, 76, 217, - 32, 235, 94, 198, 4, 217, 32, 45, 198, 4, 248, 5, 50, 198, 4, 248, 5, - 207, 142, 201, 185, 45, 207, 142, 211, 95, 248, 5, 50, 207, 142, 211, 95, - 248, 5, 234, 146, 238, 207, 210, 116, 232, 109, 210, 116, 207, 13, 232, - 109, 210, 116, 228, 55, 235, 94, 211, 164, 235, 75, 251, 75, 196, 62, - 251, 75, 235, 94, 206, 198, 251, 64, 54, 211, 159, 228, 58, 223, 65, 223, - 74, 210, 173, 247, 255, 228, 59, 4, 236, 253, 198, 148, 4, 206, 184, 56, - 45, 131, 210, 106, 248, 5, 50, 131, 210, 106, 248, 5, 198, 148, 4, 75, - 56, 198, 148, 4, 75, 60, 45, 81, 249, 38, 4, 208, 2, 50, 81, 249, 38, 4, - 208, 2, 198, 49, 45, 134, 248, 5, 198, 49, 50, 134, 248, 5, 248, 29, 45, - 134, 248, 5, 248, 29, 50, 134, 248, 5, 45, 202, 201, 126, 248, 5, 50, - 202, 201, 126, 248, 5, 45, 54, 210, 103, 50, 54, 210, 103, 103, 183, 138, - 91, 75, 208, 144, 91, 75, 138, 103, 183, 208, 144, 112, 232, 90, 75, 208, - 144, 232, 185, 75, 77, 207, 13, 208, 8, 77, 81, 198, 147, 206, 184, 209, - 54, 193, 23, 204, 6, 82, 236, 96, 152, 242, 26, 207, 142, 236, 96, 207, - 142, 242, 26, 152, 204, 20, 237, 224, 4, 45, 230, 140, 237, 224, 4, 50, - 230, 140, 152, 237, 223, 198, 49, 134, 205, 49, 57, 197, 10, 237, 170, - 198, 218, 237, 170, 201, 74, 232, 42, 201, 58, 81, 202, 131, 236, 94, - 193, 70, 81, 219, 88, 247, 61, 54, 228, 58, 207, 13, 242, 26, 54, 218, - 215, 207, 247, 77, 237, 171, 4, 45, 196, 65, 54, 200, 159, 77, 223, 65, - 131, 222, 9, 223, 65, 131, 222, 10, 4, 222, 10, 56, 131, 222, 9, 131, - 222, 10, 4, 236, 96, 54, 201, 109, 242, 26, 235, 94, 202, 18, 197, 221, - 237, 223, 216, 195, 242, 26, 210, 115, 77, 208, 143, 234, 86, 77, 238, - 208, 195, 134, 236, 160, 238, 171, 210, 72, 4, 50, 238, 169, 238, 171, - 210, 72, 4, 45, 238, 169, 198, 123, 3, 6, 233, 213, 216, 195, 233, 175, - 77, 216, 195, 208, 8, 77, 45, 51, 248, 6, 4, 105, 50, 51, 248, 6, 4, 105, - 45, 51, 248, 6, 4, 54, 105, 50, 51, 248, 6, 4, 54, 105, 198, 49, 134, 45, - 210, 103, 198, 49, 134, 50, 210, 103, 248, 29, 134, 45, 210, 103, 248, - 29, 134, 50, 210, 103, 211, 159, 228, 58, 12, 48, 207, 43, 12, 48, 242, - 182, 12, 48, 205, 52, 108, 12, 48, 205, 52, 109, 12, 48, 205, 52, 139, - 12, 48, 209, 241, 12, 48, 248, 14, 12, 48, 199, 228, 12, 48, 221, 55, - 108, 12, 48, 221, 55, 109, 12, 48, 236, 157, 12, 48, 205, 56, 12, 48, 2, - 108, 12, 48, 2, 109, 12, 48, 220, 6, 108, 12, 48, 220, 6, 109, 12, 48, - 220, 6, 139, 12, 48, 220, 6, 137, 12, 48, 202, 53, 12, 48, 198, 222, 12, - 48, 202, 50, 108, 12, 48, 202, 50, 109, 12, 48, 229, 192, 108, 12, 48, - 229, 192, 109, 12, 48, 230, 20, 12, 48, 207, 131, 12, 48, 243, 16, 12, - 48, 200, 193, 12, 48, 215, 188, 12, 48, 237, 98, 12, 48, 215, 177, 12, - 48, 242, 201, 12, 48, 193, 142, 108, 12, 48, 193, 142, 109, 12, 48, 232, - 202, 12, 48, 210, 66, 108, 12, 48, 210, 66, 109, 12, 48, 202, 173, 134, - 197, 251, 197, 173, 12, 48, 238, 192, 12, 48, 236, 117, 12, 48, 222, 255, - 12, 48, 248, 54, 80, 242, 165, 12, 48, 233, 152, 12, 48, 201, 210, 108, - 12, 48, 201, 210, 109, 12, 48, 249, 53, 12, 48, 202, 180, 12, 48, 247, - 142, 202, 180, 12, 48, 214, 72, 108, 12, 48, 214, 72, 109, 12, 48, 214, - 72, 139, 12, 48, 214, 72, 137, 12, 48, 216, 153, 12, 48, 203, 102, 12, - 48, 207, 137, 12, 48, 233, 182, 12, 48, 211, 108, 12, 48, 247, 226, 108, - 12, 48, 247, 226, 109, 12, 48, 216, 205, 12, 48, 215, 183, 12, 48, 230, - 180, 108, 12, 48, 230, 180, 109, 12, 48, 230, 180, 139, 12, 48, 198, 168, - 12, 48, 242, 164, 12, 48, 193, 103, 108, 12, 48, 193, 103, 109, 12, 48, - 247, 142, 205, 45, 12, 48, 202, 173, 228, 156, 12, 48, 228, 156, 12, 48, - 247, 142, 201, 224, 12, 48, 247, 142, 203, 97, 12, 48, 232, 120, 12, 48, - 247, 142, 247, 37, 12, 48, 202, 173, 193, 166, 12, 48, 193, 167, 108, 12, - 48, 193, 167, 109, 12, 48, 242, 204, 12, 48, 247, 142, 230, 214, 12, 48, - 177, 108, 12, 48, 177, 109, 12, 48, 247, 142, 218, 251, 12, 48, 247, 142, - 231, 154, 12, 48, 215, 172, 108, 12, 48, 215, 172, 109, 12, 48, 207, 144, - 12, 48, 248, 66, 12, 48, 247, 142, 199, 180, 219, 206, 12, 48, 247, 142, - 219, 209, 12, 48, 247, 142, 193, 64, 12, 48, 247, 142, 232, 139, 12, 48, - 234, 157, 108, 12, 48, 234, 157, 109, 12, 48, 234, 157, 139, 12, 48, 247, - 142, 234, 156, 12, 48, 229, 203, 12, 48, 247, 142, 228, 152, 12, 48, 248, - 50, 12, 48, 231, 24, 12, 48, 247, 142, 232, 195, 12, 48, 247, 142, 248, - 112, 12, 48, 247, 142, 205, 153, 12, 48, 202, 173, 193, 93, 12, 48, 202, - 173, 192, 72, 12, 48, 247, 142, 232, 61, 12, 48, 223, 6, 233, 187, 12, - 48, 247, 142, 233, 187, 12, 48, 223, 6, 198, 51, 12, 48, 247, 142, 198, - 51, 12, 48, 223, 6, 235, 67, 12, 48, 247, 142, 235, 67, 12, 48, 197, 51, - 12, 48, 223, 6, 197, 51, 12, 48, 247, 142, 197, 51, 83, 48, 108, 83, 48, - 219, 88, 83, 48, 236, 96, 83, 48, 202, 92, 83, 48, 205, 51, 83, 48, 106, - 83, 48, 109, 83, 48, 219, 117, 83, 48, 217, 70, 83, 48, 219, 185, 83, 48, - 234, 35, 83, 48, 176, 83, 48, 143, 248, 14, 83, 48, 238, 195, 83, 48, - 227, 252, 83, 48, 199, 228, 83, 48, 211, 66, 248, 14, 83, 48, 221, 54, - 83, 48, 208, 247, 83, 48, 193, 12, 83, 48, 201, 198, 83, 48, 50, 211, 66, - 248, 14, 83, 48, 229, 114, 234, 56, 83, 48, 199, 90, 83, 48, 236, 157, - 83, 48, 205, 56, 83, 48, 242, 182, 83, 48, 208, 197, 83, 48, 251, 200, - 83, 48, 215, 163, 83, 48, 234, 56, 83, 48, 234, 163, 83, 48, 205, 86, 83, - 48, 230, 223, 83, 48, 230, 224, 202, 69, 83, 48, 233, 186, 83, 48, 248, - 126, 83, 48, 193, 35, 83, 48, 243, 38, 83, 48, 206, 128, 83, 48, 223, - 130, 83, 48, 202, 65, 83, 48, 220, 5, 83, 48, 238, 205, 83, 48, 201, 189, - 83, 48, 215, 168, 83, 48, 206, 171, 83, 48, 193, 20, 83, 48, 211, 84, 83, - 48, 197, 59, 83, 48, 235, 47, 83, 48, 203, 35, 198, 222, 83, 48, 235, 94, - 242, 182, 83, 48, 177, 201, 29, 83, 48, 103, 229, 251, 83, 48, 203, 41, - 83, 48, 248, 21, 83, 48, 202, 49, 83, 48, 247, 233, 83, 48, 201, 73, 83, - 48, 229, 191, 83, 48, 230, 38, 83, 48, 236, 100, 83, 48, 230, 20, 83, 48, - 247, 255, 83, 48, 207, 131, 83, 48, 205, 69, 83, 48, 236, 191, 83, 48, - 250, 82, 83, 48, 201, 185, 83, 48, 212, 254, 83, 48, 200, 193, 83, 48, - 205, 98, 83, 48, 215, 188, 83, 48, 197, 250, 83, 48, 220, 87, 83, 48, - 201, 58, 83, 48, 237, 98, 83, 48, 193, 118, 83, 48, 236, 130, 212, 254, - 83, 48, 242, 22, 83, 48, 232, 35, 83, 48, 242, 195, 83, 48, 201, 79, 83, - 48, 193, 141, 83, 48, 232, 202, 83, 48, 242, 191, 83, 48, 233, 25, 83, - 48, 54, 192, 235, 83, 48, 134, 197, 251, 197, 173, 83, 48, 202, 83, 83, - 48, 233, 37, 83, 48, 238, 192, 83, 48, 236, 117, 83, 48, 208, 192, 83, - 48, 222, 255, 83, 48, 216, 177, 83, 48, 198, 146, 83, 48, 200, 137, 83, - 48, 219, 111, 83, 48, 196, 39, 83, 48, 232, 236, 83, 48, 248, 54, 80, - 242, 165, 83, 48, 202, 207, 83, 48, 235, 94, 199, 82, 83, 48, 193, 87, - 83, 48, 202, 102, 83, 48, 236, 177, 83, 48, 233, 152, 83, 48, 201, 227, - 83, 48, 55, 83, 48, 201, 60, 83, 48, 201, 209, 83, 48, 198, 21, 83, 48, - 230, 189, 83, 48, 247, 22, 83, 48, 201, 102, 83, 48, 249, 53, 83, 48, - 206, 240, 83, 48, 202, 180, 83, 48, 222, 246, 83, 48, 214, 71, 83, 48, - 203, 102, 83, 48, 233, 13, 83, 48, 211, 108, 83, 48, 251, 74, 83, 48, - 209, 81, 83, 48, 234, 167, 83, 48, 247, 225, 83, 48, 216, 205, 83, 48, - 216, 20, 83, 48, 204, 27, 83, 48, 250, 189, 83, 48, 215, 183, 83, 48, - 198, 56, 83, 48, 211, 53, 83, 48, 248, 58, 83, 48, 201, 54, 83, 48, 242, - 34, 83, 48, 230, 179, 83, 48, 198, 168, 83, 48, 223, 93, 83, 48, 248, 72, - 83, 48, 193, 167, 234, 56, 83, 48, 242, 164, 83, 48, 193, 102, 83, 48, - 205, 45, 83, 48, 228, 156, 83, 48, 201, 224, 83, 48, 195, 177, 83, 48, - 248, 218, 83, 48, 209, 138, 83, 48, 249, 83, 83, 48, 203, 97, 83, 48, - 207, 81, 83, 48, 206, 40, 83, 48, 232, 120, 83, 48, 248, 56, 83, 48, 247, - 37, 83, 48, 248, 96, 83, 48, 215, 185, 83, 48, 193, 166, 83, 48, 242, - 204, 83, 48, 193, 60, 83, 48, 236, 169, 83, 48, 195, 47, 83, 48, 230, - 214, 83, 48, 218, 251, 83, 48, 231, 154, 83, 48, 215, 171, 83, 48, 202, - 91, 83, 48, 203, 35, 199, 209, 248, 112, 83, 48, 207, 144, 83, 48, 248, - 66, 83, 48, 193, 2, 83, 48, 233, 62, 83, 48, 219, 206, 83, 48, 199, 180, - 219, 206, 83, 48, 219, 202, 83, 48, 201, 255, 83, 48, 219, 209, 83, 48, - 193, 64, 83, 48, 232, 139, 83, 48, 234, 156, 83, 48, 229, 203, 83, 48, - 232, 78, 83, 48, 228, 152, 83, 48, 248, 50, 83, 48, 199, 194, 83, 48, - 230, 45, 83, 48, 232, 229, 83, 48, 205, 189, 193, 60, 83, 48, 247, 24, - 83, 48, 231, 24, 83, 48, 232, 195, 83, 48, 248, 112, 83, 48, 205, 153, - 83, 48, 237, 83, 83, 48, 193, 93, 83, 48, 229, 167, 83, 48, 192, 72, 83, - 48, 216, 31, 83, 48, 248, 91, 83, 48, 234, 68, 83, 48, 232, 61, 83, 48, - 197, 218, 83, 48, 235, 50, 83, 48, 207, 125, 83, 48, 213, 0, 83, 48, 233, - 187, 83, 48, 198, 51, 83, 48, 235, 67, 83, 48, 197, 51, 83, 48, 232, 142, - 154, 237, 40, 246, 192, 45, 118, 187, 154, 237, 40, 246, 192, 95, 118, - 60, 154, 237, 40, 246, 192, 45, 118, 82, 24, 187, 154, 237, 40, 246, 192, - 95, 118, 82, 24, 60, 154, 237, 40, 246, 192, 232, 42, 200, 163, 154, 237, - 40, 246, 192, 200, 164, 232, 60, 56, 154, 237, 40, 246, 192, 200, 164, - 232, 60, 60, 154, 237, 40, 246, 192, 200, 164, 232, 60, 219, 200, 154, - 237, 40, 246, 192, 200, 164, 232, 60, 116, 219, 200, 154, 237, 40, 246, - 192, 200, 164, 232, 60, 116, 187, 154, 237, 40, 246, 192, 200, 164, 232, - 60, 110, 219, 200, 154, 237, 40, 246, 192, 210, 249, 154, 201, 242, 154, - 242, 26, 154, 232, 42, 201, 58, 236, 166, 77, 222, 247, 223, 113, 201, - 101, 113, 154, 223, 23, 77, 154, 242, 167, 77, 154, 31, 191, 77, 45, 251, - 65, 248, 5, 50, 251, 65, 248, 5, 45, 54, 251, 65, 248, 5, 50, 54, 251, - 65, 248, 5, 45, 238, 211, 248, 5, 50, 238, 211, 248, 5, 45, 64, 238, 211, - 248, 5, 50, 64, 238, 211, 248, 5, 45, 62, 219, 163, 248, 5, 50, 62, 219, - 163, 248, 5, 209, 11, 77, 231, 93, 77, 45, 198, 37, 203, 98, 248, 5, 50, - 198, 37, 203, 98, 248, 5, 45, 64, 219, 163, 248, 5, 50, 64, 219, 163, - 248, 5, 45, 64, 198, 37, 203, 98, 248, 5, 50, 64, 198, 37, 203, 98, 248, - 5, 45, 64, 51, 248, 5, 50, 64, 51, 248, 5, 193, 137, 237, 170, 207, 13, - 54, 208, 209, 207, 247, 77, 54, 208, 209, 207, 247, 77, 131, 54, 208, - 209, 207, 247, 77, 209, 11, 87, 233, 62, 229, 248, 212, 121, 108, 229, - 248, 212, 121, 109, 229, 248, 212, 121, 139, 229, 248, 212, 121, 137, - 229, 248, 212, 121, 153, 229, 248, 212, 121, 173, 229, 248, 212, 121, - 181, 229, 248, 212, 121, 176, 229, 248, 212, 121, 184, 154, 219, 144, - 163, 77, 154, 206, 175, 163, 77, 154, 237, 50, 163, 77, 154, 234, 34, - 163, 77, 30, 202, 165, 75, 163, 77, 30, 54, 75, 163, 77, 193, 133, 237, - 170, 81, 222, 60, 207, 44, 77, 81, 222, 60, 207, 44, 4, 195, 17, 202, 0, - 77, 81, 222, 60, 207, 44, 87, 116, 230, 37, 81, 222, 60, 207, 44, 4, 195, - 17, 202, 0, 87, 116, 230, 37, 81, 222, 60, 207, 44, 87, 110, 230, 37, 47, - 209, 11, 77, 154, 199, 104, 219, 89, 233, 10, 204, 6, 113, 229, 248, 212, - 121, 199, 90, 229, 248, 212, 121, 197, 28, 229, 248, 212, 121, 198, 244, - 81, 154, 223, 23, 77, 217, 12, 77, 210, 97, 251, 102, 77, 154, 66, 223, - 116, 154, 134, 232, 221, 201, 242, 229, 88, 1, 2, 65, 229, 88, 1, 65, - 229, 88, 1, 2, 70, 229, 88, 1, 70, 229, 88, 1, 2, 69, 229, 88, 1, 69, - 229, 88, 1, 2, 73, 229, 88, 1, 73, 229, 88, 1, 2, 74, 229, 88, 1, 74, - 229, 88, 1, 157, 229, 88, 1, 231, 203, 229, 88, 1, 221, 142, 229, 88, 1, - 231, 16, 229, 88, 1, 220, 208, 229, 88, 1, 230, 146, 229, 88, 1, 221, - 253, 229, 88, 1, 231, 128, 229, 88, 1, 221, 43, 229, 88, 1, 230, 223, - 229, 88, 1, 189, 229, 88, 1, 191, 123, 229, 88, 1, 202, 217, 229, 88, 1, - 191, 30, 229, 88, 1, 200, 255, 229, 88, 1, 190, 251, 229, 88, 1, 205, 63, - 229, 88, 1, 191, 87, 229, 88, 1, 202, 41, 229, 88, 1, 191, 7, 229, 88, 1, - 199, 247, 229, 88, 1, 237, 241, 229, 88, 1, 198, 188, 229, 88, 1, 236, - 255, 229, 88, 1, 2, 197, 90, 229, 88, 1, 197, 90, 229, 88, 1, 235, 45, - 229, 88, 1, 199, 140, 229, 88, 1, 237, 101, 229, 88, 1, 159, 229, 88, 1, - 236, 129, 229, 88, 1, 180, 229, 88, 1, 213, 205, 229, 88, 1, 212, 165, - 229, 88, 1, 214, 107, 229, 88, 1, 213, 30, 229, 88, 1, 144, 229, 88, 1, - 249, 103, 229, 88, 1, 168, 229, 88, 1, 229, 126, 229, 88, 1, 248, 140, - 229, 88, 1, 209, 176, 229, 88, 1, 228, 128, 229, 88, 1, 247, 218, 229, - 88, 1, 208, 158, 229, 88, 1, 229, 213, 229, 88, 1, 248, 223, 229, 88, 1, - 210, 53, 229, 88, 1, 228, 247, 229, 88, 1, 248, 63, 229, 88, 1, 209, 65, - 229, 88, 1, 172, 229, 88, 1, 216, 81, 229, 88, 1, 215, 139, 229, 88, 1, - 216, 213, 229, 88, 1, 215, 251, 229, 88, 1, 2, 169, 229, 88, 1, 169, 229, - 88, 1, 2, 191, 225, 229, 88, 1, 191, 225, 229, 88, 1, 2, 192, 12, 229, - 88, 1, 192, 12, 229, 88, 1, 166, 229, 88, 1, 206, 252, 229, 88, 1, 206, - 63, 229, 88, 1, 207, 108, 229, 88, 1, 206, 157, 229, 88, 1, 2, 193, 187, - 229, 88, 1, 193, 187, 229, 88, 1, 193, 84, 229, 88, 1, 193, 123, 229, 88, - 1, 193, 48, 229, 88, 1, 215, 47, 229, 88, 1, 193, 246, 229, 88, 1, 2, - 157, 229, 88, 1, 2, 221, 253, 33, 222, 22, 195, 17, 202, 0, 77, 33, 222, - 22, 204, 25, 202, 0, 77, 222, 22, 195, 17, 202, 0, 77, 222, 22, 204, 25, - 202, 0, 77, 229, 88, 223, 23, 77, 229, 88, 195, 17, 223, 23, 77, 229, 88, - 236, 214, 191, 242, 222, 22, 54, 228, 58, 71, 1, 2, 65, 71, 1, 65, 71, 1, - 2, 70, 71, 1, 70, 71, 1, 2, 69, 71, 1, 69, 71, 1, 2, 73, 71, 1, 73, 71, - 1, 2, 74, 71, 1, 74, 71, 1, 157, 71, 1, 231, 203, 71, 1, 221, 142, 71, 1, - 231, 16, 71, 1, 220, 208, 71, 1, 230, 146, 71, 1, 221, 253, 71, 1, 231, - 128, 71, 1, 221, 43, 71, 1, 230, 223, 71, 1, 189, 71, 1, 191, 123, 71, 1, - 202, 217, 71, 1, 191, 30, 71, 1, 200, 255, 71, 1, 190, 251, 71, 1, 205, - 63, 71, 1, 191, 87, 71, 1, 202, 41, 71, 1, 191, 7, 71, 1, 199, 247, 71, - 1, 237, 241, 71, 1, 198, 188, 71, 1, 236, 255, 71, 1, 2, 197, 90, 71, 1, - 197, 90, 71, 1, 235, 45, 71, 1, 199, 140, 71, 1, 237, 101, 71, 1, 159, - 71, 1, 236, 129, 71, 1, 180, 71, 1, 213, 205, 71, 1, 212, 165, 71, 1, - 214, 107, 71, 1, 213, 30, 71, 1, 144, 71, 1, 249, 103, 71, 1, 168, 71, 1, - 229, 126, 71, 1, 248, 140, 71, 1, 209, 176, 71, 1, 228, 128, 71, 1, 247, - 218, 71, 1, 208, 158, 71, 1, 229, 213, 71, 1, 248, 223, 71, 1, 210, 53, - 71, 1, 228, 247, 71, 1, 248, 63, 71, 1, 209, 65, 71, 1, 172, 71, 1, 216, - 81, 71, 1, 215, 139, 71, 1, 216, 213, 71, 1, 215, 251, 71, 1, 2, 169, 71, - 1, 169, 71, 1, 2, 191, 225, 71, 1, 191, 225, 71, 1, 2, 192, 12, 71, 1, - 192, 12, 71, 1, 166, 71, 1, 206, 252, 71, 1, 206, 63, 71, 1, 207, 108, - 71, 1, 206, 157, 71, 1, 2, 193, 187, 71, 1, 193, 187, 71, 1, 193, 84, 71, - 1, 193, 123, 71, 1, 193, 48, 71, 1, 215, 47, 71, 1, 193, 246, 71, 1, 2, - 157, 71, 1, 2, 221, 253, 71, 1, 195, 185, 71, 1, 195, 66, 71, 1, 195, - 150, 71, 1, 195, 21, 71, 82, 236, 96, 222, 22, 208, 184, 202, 0, 77, 71, - 223, 23, 77, 71, 195, 17, 223, 23, 77, 71, 236, 214, 221, 3, 248, 40, 1, - 250, 70, 248, 40, 1, 210, 226, 248, 40, 1, 218, 147, 248, 40, 1, 233, - 134, 248, 40, 1, 238, 80, 248, 40, 1, 200, 39, 248, 40, 1, 215, 47, 248, - 40, 1, 170, 248, 40, 1, 232, 14, 248, 40, 1, 222, 125, 248, 40, 1, 230, - 83, 248, 40, 1, 223, 7, 248, 40, 1, 208, 97, 248, 40, 1, 192, 235, 248, - 40, 1, 191, 72, 248, 40, 1, 246, 211, 248, 40, 1, 203, 162, 248, 40, 1, - 148, 248, 40, 1, 191, 166, 248, 40, 1, 247, 145, 248, 40, 1, 206, 3, 248, - 40, 1, 65, 248, 40, 1, 74, 248, 40, 1, 73, 248, 40, 1, 234, 130, 248, 40, - 1, 251, 184, 248, 40, 1, 234, 123, 248, 40, 1, 250, 113, 248, 40, 1, 211, - 9, 248, 40, 1, 251, 81, 248, 40, 1, 234, 61, 248, 40, 1, 251, 71, 248, - 40, 1, 234, 46, 248, 40, 1, 233, 248, 248, 40, 1, 70, 248, 40, 1, 69, - 248, 40, 1, 223, 21, 248, 40, 1, 196, 8, 248, 40, 1, 214, 56, 248, 40, 1, - 230, 227, 248, 40, 1, 223, 171, 248, 40, 1, 186, 4, 75, 56, 248, 40, 1, - 213, 67, 30, 1, 221, 89, 30, 1, 201, 162, 30, 1, 221, 82, 30, 1, 213, - 190, 30, 1, 213, 188, 30, 1, 213, 187, 30, 1, 198, 163, 30, 1, 201, 151, - 30, 1, 206, 234, 30, 1, 206, 229, 30, 1, 206, 226, 30, 1, 206, 219, 30, - 1, 206, 214, 30, 1, 206, 209, 30, 1, 206, 220, 30, 1, 206, 232, 30, 1, - 216, 59, 30, 1, 209, 160, 30, 1, 201, 159, 30, 1, 209, 149, 30, 1, 202, - 155, 30, 1, 201, 156, 30, 1, 223, 193, 30, 1, 242, 232, 30, 1, 201, 166, - 30, 1, 243, 43, 30, 1, 221, 164, 30, 1, 199, 2, 30, 1, 209, 200, 30, 1, - 229, 110, 30, 1, 65, 30, 1, 251, 229, 30, 1, 169, 30, 1, 192, 129, 30, 1, - 234, 23, 30, 1, 73, 30, 1, 192, 67, 30, 1, 192, 80, 30, 1, 74, 30, 1, - 193, 187, 30, 1, 193, 173, 30, 1, 211, 139, 30, 1, 192, 12, 30, 1, 69, - 30, 1, 193, 105, 30, 1, 193, 123, 30, 1, 193, 84, 30, 1, 191, 225, 30, 1, - 233, 201, 30, 1, 192, 33, 30, 1, 70, 30, 232, 218, 30, 1, 201, 160, 30, - 1, 213, 180, 30, 1, 213, 182, 30, 1, 213, 185, 30, 1, 206, 227, 30, 1, - 206, 208, 30, 1, 206, 216, 30, 1, 206, 221, 30, 1, 206, 206, 30, 1, 216, - 52, 30, 1, 216, 49, 30, 1, 216, 53, 30, 1, 222, 45, 30, 1, 209, 155, 30, - 1, 209, 141, 30, 1, 209, 147, 30, 1, 209, 144, 30, 1, 209, 158, 30, 1, - 209, 142, 30, 1, 222, 43, 30, 1, 222, 41, 30, 1, 202, 148, 30, 1, 202, - 146, 30, 1, 202, 138, 30, 1, 202, 143, 30, 1, 202, 153, 30, 1, 210, 139, - 30, 1, 201, 163, 30, 1, 192, 57, 30, 1, 192, 51, 30, 1, 192, 52, 30, 1, - 222, 44, 30, 1, 201, 164, 30, 1, 192, 63, 30, 1, 192, 0, 30, 1, 191, 255, - 30, 1, 192, 2, 30, 1, 191, 212, 30, 1, 191, 213, 30, 1, 191, 216, 30, 1, - 250, 231, 30, 1, 250, 225, 154, 251, 45, 219, 77, 77, 154, 251, 45, 207, - 14, 77, 154, 251, 45, 91, 77, 154, 251, 45, 103, 77, 154, 251, 45, 115, - 77, 154, 251, 45, 232, 90, 77, 154, 251, 45, 198, 49, 77, 154, 251, 45, - 82, 77, 154, 251, 45, 248, 29, 77, 154, 251, 45, 232, 197, 77, 154, 251, - 45, 205, 52, 77, 154, 251, 45, 198, 252, 77, 154, 251, 45, 232, 83, 77, - 154, 251, 45, 229, 188, 77, 154, 251, 45, 234, 164, 77, 154, 251, 45, - 217, 71, 77, 248, 40, 1, 247, 218, 248, 40, 1, 191, 30, 248, 40, 1, 222, - 217, 248, 40, 1, 230, 146, 248, 40, 1, 234, 145, 248, 40, 1, 234, 43, - 248, 40, 1, 211, 76, 248, 40, 1, 211, 80, 248, 40, 1, 223, 49, 248, 40, - 1, 251, 47, 248, 40, 1, 223, 100, 248, 40, 1, 196, 79, 248, 40, 1, 223, - 152, 248, 40, 1, 214, 34, 248, 40, 1, 251, 177, 248, 40, 1, 250, 108, - 248, 40, 1, 251, 98, 248, 40, 1, 211, 102, 248, 40, 1, 211, 83, 248, 40, - 1, 223, 97, 248, 40, 52, 1, 210, 226, 248, 40, 52, 1, 200, 39, 248, 40, - 52, 1, 222, 125, 248, 40, 52, 1, 230, 83, 248, 40, 1, 231, 55, 248, 40, - 1, 219, 136, 248, 40, 1, 190, 231, 248, 40, 52, 1, 232, 14, 248, 40, 1, - 230, 103, 248, 40, 1, 220, 156, 248, 40, 1, 211, 139, 248, 40, 1, 251, - 193, 12, 201, 23, 200, 39, 12, 201, 23, 193, 96, 12, 201, 23, 192, 209, - 12, 201, 23, 247, 158, 12, 201, 23, 200, 147, 12, 201, 23, 228, 48, 12, - 201, 23, 228, 52, 12, 201, 23, 228, 138, 12, 201, 23, 228, 49, 12, 201, - 23, 200, 42, 12, 201, 23, 228, 51, 12, 201, 23, 228, 47, 12, 201, 23, - 228, 136, 12, 201, 23, 228, 50, 12, 201, 23, 228, 46, 12, 201, 23, 215, - 47, 12, 201, 23, 230, 83, 12, 201, 23, 206, 3, 12, 201, 23, 210, 226, 12, - 201, 23, 201, 245, 12, 201, 23, 238, 80, 12, 201, 23, 228, 53, 12, 201, - 23, 229, 146, 12, 201, 23, 200, 51, 12, 201, 23, 200, 124, 12, 201, 23, - 201, 113, 12, 201, 23, 203, 168, 12, 201, 23, 210, 57, 12, 201, 23, 208, - 99, 12, 201, 23, 198, 94, 12, 201, 23, 200, 41, 12, 201, 23, 200, 136, - 12, 201, 23, 228, 63, 12, 201, 23, 228, 45, 12, 201, 23, 209, 221, 12, - 201, 23, 208, 97, 71, 1, 2, 220, 208, 71, 1, 2, 202, 217, 71, 1, 2, 200, - 255, 71, 1, 2, 159, 71, 1, 2, 212, 165, 71, 1, 2, 144, 71, 1, 2, 229, - 126, 71, 1, 2, 228, 128, 71, 1, 2, 229, 213, 71, 1, 2, 228, 247, 71, 1, - 2, 215, 139, 71, 1, 2, 166, 71, 1, 2, 206, 252, 71, 1, 2, 206, 63, 71, 1, - 2, 207, 108, 71, 1, 2, 206, 157, 127, 30, 221, 89, 127, 30, 213, 190, - 127, 30, 198, 163, 127, 30, 206, 234, 127, 30, 216, 59, 127, 30, 209, - 160, 127, 30, 202, 155, 127, 30, 223, 193, 127, 30, 242, 232, 127, 30, - 243, 43, 127, 30, 221, 164, 127, 30, 199, 2, 127, 30, 209, 200, 127, 30, - 229, 110, 127, 30, 221, 90, 65, 127, 30, 213, 191, 65, 127, 30, 198, 164, - 65, 127, 30, 206, 235, 65, 127, 30, 216, 60, 65, 127, 30, 209, 161, 65, - 127, 30, 202, 156, 65, 127, 30, 223, 194, 65, 127, 30, 242, 233, 65, 127, - 30, 243, 44, 65, 127, 30, 221, 165, 65, 127, 30, 199, 3, 65, 127, 30, - 209, 201, 65, 127, 30, 229, 111, 65, 127, 30, 242, 233, 69, 127, 221, 8, - 246, 192, 211, 117, 127, 221, 8, 246, 192, 186, 228, 128, 127, 227, 241, - 108, 127, 227, 241, 109, 127, 227, 241, 139, 127, 227, 241, 137, 127, - 227, 241, 153, 127, 227, 241, 173, 127, 227, 241, 181, 127, 227, 241, - 176, 127, 227, 241, 184, 127, 227, 241, 199, 90, 127, 227, 241, 215, 188, - 127, 227, 241, 232, 202, 127, 227, 241, 193, 141, 127, 227, 241, 193, 28, - 127, 227, 241, 216, 146, 127, 227, 241, 234, 163, 127, 227, 241, 200, - 193, 127, 227, 241, 201, 61, 127, 227, 241, 229, 223, 127, 227, 241, 202, - 30, 127, 227, 241, 214, 213, 127, 227, 241, 201, 226, 127, 227, 241, 232, - 213, 127, 227, 241, 239, 2, 127, 227, 241, 220, 90, 127, 227, 241, 207, - 37, 127, 227, 241, 247, 90, 127, 227, 241, 201, 5, 127, 227, 241, 200, - 173, 127, 227, 241, 234, 33, 127, 227, 241, 207, 27, 127, 227, 241, 251, - 117, 127, 227, 241, 232, 246, 127, 227, 241, 207, 25, 127, 227, 241, 204, - 27, 127, 227, 241, 207, 103, 47, 227, 241, 208, 7, 47, 227, 241, 221, - 116, 47, 227, 241, 205, 84, 47, 227, 241, 221, 3, 47, 31, 199, 91, 211, - 94, 62, 201, 185, 47, 31, 197, 29, 211, 94, 62, 201, 185, 47, 31, 198, - 245, 211, 94, 62, 201, 185, 47, 31, 232, 98, 211, 94, 62, 201, 185, 47, - 31, 232, 231, 211, 94, 62, 201, 185, 47, 31, 202, 116, 211, 94, 62, 201, - 185, 47, 31, 203, 237, 211, 94, 62, 201, 185, 47, 31, 234, 111, 211, 94, - 62, 201, 185, 210, 93, 57, 47, 31, 197, 29, 108, 47, 31, 197, 29, 109, - 47, 31, 197, 29, 139, 47, 31, 197, 29, 137, 47, 31, 197, 29, 153, 47, 31, - 197, 29, 173, 47, 31, 197, 29, 181, 47, 31, 197, 29, 176, 47, 31, 197, - 29, 184, 47, 31, 198, 244, 47, 31, 198, 245, 108, 47, 31, 198, 245, 109, - 47, 31, 198, 245, 139, 47, 31, 198, 245, 137, 47, 31, 198, 245, 153, 47, - 30, 221, 89, 47, 30, 213, 190, 47, 30, 198, 163, 47, 30, 206, 234, 47, - 30, 216, 59, 47, 30, 209, 160, 47, 30, 202, 155, 47, 30, 223, 193, 47, - 30, 242, 232, 47, 30, 243, 43, 47, 30, 221, 164, 47, 30, 199, 2, 47, 30, - 209, 200, 47, 30, 229, 110, 47, 30, 221, 90, 65, 47, 30, 213, 191, 65, - 47, 30, 198, 164, 65, 47, 30, 206, 235, 65, 47, 30, 216, 60, 65, 47, 30, - 209, 161, 65, 47, 30, 202, 156, 65, 47, 30, 223, 194, 65, 47, 30, 242, - 233, 65, 47, 30, 243, 44, 65, 47, 30, 221, 165, 65, 47, 30, 199, 3, 65, - 47, 30, 209, 201, 65, 47, 30, 229, 111, 65, 47, 221, 8, 246, 192, 246, - 199, 47, 221, 8, 246, 192, 222, 151, 47, 30, 223, 194, 69, 221, 8, 201, - 101, 113, 47, 227, 241, 108, 47, 227, 241, 109, 47, 227, 241, 139, 47, - 227, 241, 137, 47, 227, 241, 153, 47, 227, 241, 173, 47, 227, 241, 181, - 47, 227, 241, 176, 47, 227, 241, 184, 47, 227, 241, 199, 90, 47, 227, - 241, 215, 188, 47, 227, 241, 232, 202, 47, 227, 241, 193, 141, 47, 227, - 241, 193, 28, 47, 227, 241, 216, 146, 47, 227, 241, 234, 163, 47, 227, - 241, 200, 193, 47, 227, 241, 201, 61, 47, 227, 241, 229, 223, 47, 227, - 241, 202, 30, 47, 227, 241, 214, 213, 47, 227, 241, 201, 226, 47, 227, - 241, 232, 213, 47, 227, 241, 239, 2, 47, 227, 241, 220, 90, 47, 227, 241, - 205, 50, 47, 227, 241, 217, 76, 47, 227, 241, 233, 0, 47, 227, 241, 200, - 205, 47, 227, 241, 233, 179, 47, 227, 241, 208, 204, 47, 227, 241, 250, - 117, 47, 227, 241, 223, 24, 47, 227, 241, 207, 25, 47, 227, 241, 238, - 217, 47, 227, 241, 238, 204, 47, 227, 241, 229, 103, 47, 227, 241, 246, - 229, 47, 227, 241, 218, 219, 47, 227, 241, 219, 200, 47, 227, 241, 187, - 47, 227, 241, 216, 196, 47, 227, 241, 207, 55, 47, 227, 241, 201, 5, 47, - 227, 241, 200, 173, 47, 227, 241, 234, 33, 47, 227, 241, 207, 27, 47, - 227, 241, 251, 117, 47, 227, 241, 213, 176, 47, 31, 198, 245, 173, 47, - 31, 198, 245, 181, 47, 31, 198, 245, 176, 47, 31, 198, 245, 184, 47, 31, - 232, 97, 47, 31, 232, 98, 108, 47, 31, 232, 98, 109, 47, 31, 232, 98, - 139, 47, 31, 232, 98, 137, 47, 31, 232, 98, 153, 47, 31, 232, 98, 173, - 47, 31, 232, 98, 181, 47, 31, 232, 98, 176, 47, 31, 232, 98, 184, 47, 31, - 232, 230, 154, 199, 104, 16, 39, 222, 249, 154, 199, 104, 16, 39, 233, - 12, 154, 199, 104, 16, 39, 217, 39, 154, 199, 104, 16, 39, 250, 245, 154, - 199, 104, 16, 39, 217, 2, 154, 199, 104, 16, 39, 222, 148, 154, 199, 104, - 16, 39, 222, 149, 154, 199, 104, 16, 39, 250, 109, 154, 199, 104, 16, 39, - 204, 4, 154, 199, 104, 16, 39, 211, 145, 154, 199, 104, 16, 39, 212, 242, - 154, 199, 104, 16, 39, 237, 95, 51, 229, 146, 51, 233, 244, 51, 233, 189, - 219, 94, 219, 121, 57, 47, 71, 65, 47, 71, 70, 47, 71, 69, 47, 71, 73, - 47, 71, 74, 47, 71, 157, 47, 71, 221, 142, 47, 71, 220, 208, 47, 71, 221, - 253, 47, 71, 221, 43, 47, 71, 189, 47, 71, 202, 217, 47, 71, 200, 255, - 47, 71, 205, 63, 47, 71, 202, 41, 47, 71, 199, 247, 47, 71, 198, 188, 47, - 71, 197, 90, 47, 71, 199, 140, 47, 71, 159, 47, 71, 180, 47, 71, 213, - 205, 47, 71, 212, 165, 47, 71, 214, 107, 47, 71, 213, 30, 47, 71, 144, - 47, 71, 229, 126, 47, 71, 228, 128, 47, 71, 229, 213, 47, 71, 228, 247, - 47, 71, 172, 47, 71, 216, 81, 47, 71, 215, 139, 47, 71, 216, 213, 47, 71, - 215, 251, 47, 71, 169, 47, 71, 191, 225, 47, 71, 192, 12, 47, 71, 166, - 47, 71, 206, 252, 47, 71, 206, 63, 47, 71, 207, 108, 47, 71, 206, 157, - 47, 71, 193, 187, 47, 71, 193, 84, 47, 71, 193, 123, 47, 71, 193, 48, 51, - 233, 247, 214, 214, 207, 63, 51, 251, 14, 51, 250, 171, 51, 251, 41, 51, - 252, 111, 51, 223, 102, 51, 223, 69, 51, 196, 76, 51, 233, 216, 51, 234, - 142, 51, 211, 79, 51, 211, 72, 51, 222, 73, 51, 222, 37, 51, 222, 32, 51, - 231, 158, 51, 231, 168, 51, 231, 4, 51, 230, 255, 51, 220, 120, 51, 230, - 246, 51, 221, 107, 51, 221, 106, 51, 221, 105, 51, 221, 104, 51, 230, - 113, 51, 230, 112, 51, 220, 169, 51, 220, 172, 51, 221, 240, 51, 221, 5, - 51, 221, 14, 51, 205, 175, 51, 205, 128, 51, 202, 136, 51, 204, 10, 51, - 204, 9, 51, 237, 237, 51, 237, 36, 51, 236, 97, 51, 198, 76, 51, 214, - 207, 51, 212, 243, 51, 230, 42, 51, 210, 204, 51, 210, 203, 51, 249, 100, - 51, 209, 172, 51, 209, 134, 51, 209, 135, 51, 248, 108, 51, 228, 123, 51, - 228, 117, 51, 247, 173, 51, 228, 101, 51, 229, 174, 51, 209, 232, 51, - 210, 20, 51, 229, 155, 51, 210, 16, 51, 210, 34, 51, 248, 202, 51, 209, - 50, 51, 248, 36, 51, 228, 223, 51, 209, 31, 51, 228, 214, 51, 228, 216, - 51, 217, 89, 51, 217, 85, 51, 217, 94, 51, 217, 25, 51, 217, 56, 51, 216, - 38, 51, 216, 12, 51, 216, 11, 51, 216, 184, 51, 216, 181, 51, 216, 185, - 51, 192, 139, 51, 192, 137, 51, 191, 210, 51, 206, 173, 51, 206, 177, 51, - 206, 30, 51, 206, 23, 51, 207, 52, 51, 207, 49, 51, 193, 139, 154, 199, - 104, 16, 39, 228, 146, 191, 77, 154, 199, 104, 16, 39, 228, 146, 108, - 154, 199, 104, 16, 39, 228, 146, 109, 154, 199, 104, 16, 39, 228, 146, - 139, 154, 199, 104, 16, 39, 228, 146, 137, 154, 199, 104, 16, 39, 228, - 146, 153, 154, 199, 104, 16, 39, 228, 146, 173, 154, 199, 104, 16, 39, - 228, 146, 181, 154, 199, 104, 16, 39, 228, 146, 176, 154, 199, 104, 16, - 39, 228, 146, 184, 154, 199, 104, 16, 39, 228, 146, 199, 90, 154, 199, - 104, 16, 39, 228, 146, 234, 84, 154, 199, 104, 16, 39, 228, 146, 197, 33, - 154, 199, 104, 16, 39, 228, 146, 198, 246, 154, 199, 104, 16, 39, 228, - 146, 232, 84, 154, 199, 104, 16, 39, 228, 146, 232, 234, 154, 199, 104, - 16, 39, 228, 146, 202, 125, 154, 199, 104, 16, 39, 228, 146, 203, 239, - 154, 199, 104, 16, 39, 228, 146, 234, 118, 154, 199, 104, 16, 39, 228, - 146, 213, 158, 154, 199, 104, 16, 39, 228, 146, 197, 28, 154, 199, 104, - 16, 39, 228, 146, 197, 21, 154, 199, 104, 16, 39, 228, 146, 197, 16, 154, - 199, 104, 16, 39, 228, 146, 197, 18, 154, 199, 104, 16, 39, 228, 146, - 197, 23, 51, 228, 137, 51, 237, 241, 51, 250, 113, 51, 164, 51, 210, 255, - 51, 210, 58, 51, 236, 132, 51, 236, 133, 201, 184, 51, 236, 133, 238, - 142, 51, 223, 21, 51, 233, 247, 214, 214, 229, 175, 51, 233, 247, 214, - 214, 200, 62, 51, 233, 247, 214, 214, 199, 207, 51, 233, 247, 214, 214, - 216, 180, 51, 238, 206, 51, 210, 211, 251, 84, 51, 180, 51, 215, 140, 65, - 51, 172, 51, 157, 51, 222, 0, 51, 216, 253, 51, 231, 146, 51, 247, 96, - 51, 221, 255, 51, 209, 222, 51, 214, 58, 51, 215, 140, 233, 134, 51, 215, - 140, 232, 14, 51, 216, 122, 51, 221, 192, 51, 228, 53, 51, 221, 144, 51, - 216, 83, 51, 231, 18, 51, 198, 190, 51, 215, 140, 170, 51, 216, 3, 51, - 236, 142, 51, 221, 71, 51, 232, 137, 51, 213, 68, 51, 215, 140, 218, 147, - 51, 216, 0, 51, 242, 151, 51, 221, 57, 51, 216, 1, 201, 184, 51, 242, - 152, 201, 184, 51, 218, 148, 201, 184, 51, 221, 58, 201, 184, 51, 216, 1, - 238, 142, 51, 242, 152, 238, 142, 51, 218, 148, 238, 142, 51, 221, 58, - 238, 142, 51, 218, 148, 138, 206, 3, 51, 218, 148, 138, 206, 4, 201, 184, - 51, 168, 51, 220, 253, 51, 215, 150, 51, 230, 195, 51, 207, 163, 51, 207, - 164, 138, 206, 3, 51, 207, 164, 138, 206, 4, 201, 184, 51, 208, 171, 51, - 212, 206, 51, 215, 140, 206, 3, 51, 215, 142, 51, 208, 117, 51, 212, 99, - 51, 215, 140, 196, 8, 51, 215, 73, 51, 220, 158, 51, 215, 74, 216, 184, - 51, 208, 116, 51, 212, 98, 51, 215, 140, 193, 221, 51, 215, 67, 51, 220, - 156, 51, 215, 68, 216, 184, 51, 222, 126, 211, 122, 51, 218, 148, 211, - 122, 51, 251, 98, 51, 248, 9, 51, 247, 18, 51, 246, 251, 51, 247, 146, - 138, 221, 192, 51, 242, 51, 51, 237, 155, 51, 230, 96, 51, 144, 51, 228, - 138, 51, 223, 134, 51, 221, 78, 51, 221, 58, 247, 62, 51, 220, 210, 51, - 219, 22, 51, 219, 21, 51, 219, 6, 51, 218, 163, 51, 216, 254, 202, 65, - 51, 216, 37, 51, 215, 216, 51, 209, 220, 51, 209, 68, 51, 208, 242, 51, - 208, 240, 51, 201, 175, 51, 200, 154, 51, 193, 125, 51, 196, 9, 138, 218, - 147, 51, 41, 138, 218, 147, 154, 199, 104, 16, 39, 237, 159, 108, 154, - 199, 104, 16, 39, 237, 159, 109, 154, 199, 104, 16, 39, 237, 159, 139, - 154, 199, 104, 16, 39, 237, 159, 137, 154, 199, 104, 16, 39, 237, 159, - 153, 154, 199, 104, 16, 39, 237, 159, 173, 154, 199, 104, 16, 39, 237, - 159, 181, 154, 199, 104, 16, 39, 237, 159, 176, 154, 199, 104, 16, 39, - 237, 159, 184, 154, 199, 104, 16, 39, 237, 159, 199, 90, 154, 199, 104, - 16, 39, 237, 159, 234, 84, 154, 199, 104, 16, 39, 237, 159, 197, 33, 154, - 199, 104, 16, 39, 237, 159, 198, 246, 154, 199, 104, 16, 39, 237, 159, - 232, 84, 154, 199, 104, 16, 39, 237, 159, 232, 234, 154, 199, 104, 16, - 39, 237, 159, 202, 125, 154, 199, 104, 16, 39, 237, 159, 203, 239, 154, - 199, 104, 16, 39, 237, 159, 234, 118, 154, 199, 104, 16, 39, 237, 159, - 213, 158, 154, 199, 104, 16, 39, 237, 159, 197, 28, 154, 199, 104, 16, - 39, 237, 159, 197, 21, 154, 199, 104, 16, 39, 237, 159, 197, 16, 154, - 199, 104, 16, 39, 237, 159, 197, 18, 154, 199, 104, 16, 39, 237, 159, - 197, 23, 154, 199, 104, 16, 39, 237, 159, 197, 24, 154, 199, 104, 16, 39, - 237, 159, 197, 19, 154, 199, 104, 16, 39, 237, 159, 197, 20, 154, 199, - 104, 16, 39, 237, 159, 197, 27, 154, 199, 104, 16, 39, 237, 159, 197, 22, - 154, 199, 104, 16, 39, 237, 159, 198, 244, 154, 199, 104, 16, 39, 237, - 159, 198, 242, 51, 231, 185, 229, 149, 39, 199, 29, 238, 184, 229, 187, - 229, 149, 39, 199, 29, 207, 95, 234, 163, 229, 149, 39, 236, 225, 250, - 133, 199, 29, 248, 197, 229, 149, 39, 191, 238, 232, 129, 229, 149, 39, - 193, 168, 229, 149, 39, 239, 5, 229, 149, 39, 199, 29, 250, 196, 229, - 149, 39, 228, 230, 198, 82, 229, 149, 39, 2, 199, 189, 229, 149, 39, 197, - 253, 229, 149, 39, 210, 51, 229, 149, 39, 201, 99, 229, 149, 39, 233, 2, - 229, 149, 39, 230, 172, 209, 14, 229, 149, 39, 215, 237, 229, 149, 39, - 234, 32, 229, 149, 39, 232, 130, 229, 149, 39, 193, 21, 211, 94, 199, 29, - 237, 96, 229, 149, 39, 250, 249, 229, 149, 39, 238, 240, 229, 149, 39, - 248, 97, 198, 210, 229, 149, 39, 230, 193, 229, 149, 39, 201, 203, 251, - 13, 229, 149, 39, 207, 17, 229, 149, 39, 223, 96, 229, 149, 39, 230, 172, - 199, 189, 229, 149, 39, 215, 164, 238, 209, 229, 149, 39, 230, 172, 208, - 217, 229, 149, 39, 199, 29, 252, 13, 193, 141, 229, 149, 39, 199, 29, - 242, 179, 232, 202, 229, 149, 39, 223, 110, 229, 149, 39, 235, 20, 229, - 149, 39, 207, 20, 229, 149, 39, 230, 172, 208, 247, 229, 149, 39, 208, - 190, 229, 149, 39, 237, 175, 80, 199, 29, 219, 108, 229, 149, 39, 199, - 29, 233, 40, 229, 149, 39, 211, 51, 229, 149, 39, 211, 154, 229, 149, 39, - 237, 66, 229, 149, 39, 237, 88, 229, 149, 39, 223, 125, 229, 149, 39, - 247, 249, 229, 149, 39, 242, 28, 118, 216, 187, 229, 149, 39, 231, 153, - 198, 82, 229, 149, 39, 208, 128, 196, 63, 229, 149, 39, 211, 50, 229, - 149, 39, 199, 29, 193, 107, 229, 149, 39, 207, 8, 229, 149, 39, 199, 29, - 247, 24, 229, 149, 39, 199, 29, 250, 192, 198, 204, 229, 149, 39, 199, - 29, 221, 241, 201, 65, 215, 168, 229, 149, 39, 237, 31, 229, 149, 39, - 199, 29, 217, 28, 217, 90, 229, 149, 39, 252, 14, 229, 149, 39, 199, 29, - 193, 159, 229, 149, 39, 199, 29, 231, 108, 193, 64, 229, 149, 39, 199, - 29, 222, 157, 220, 19, 229, 149, 39, 236, 174, 229, 149, 39, 219, 95, - 229, 149, 39, 223, 99, 197, 172, 229, 149, 39, 2, 208, 217, 229, 149, 39, - 251, 202, 242, 18, 229, 149, 39, 248, 200, 242, 18, 11, 5, 223, 25, 11, - 5, 223, 17, 11, 5, 70, 11, 5, 223, 52, 11, 5, 223, 195, 11, 5, 223, 178, - 11, 5, 223, 197, 11, 5, 223, 196, 11, 5, 250, 132, 11, 5, 250, 83, 11, 5, - 65, 11, 5, 251, 15, 11, 5, 196, 74, 11, 5, 196, 78, 11, 5, 196, 75, 11, - 5, 211, 20, 11, 5, 210, 237, 11, 5, 74, 11, 5, 211, 67, 11, 5, 233, 180, - 11, 5, 73, 11, 5, 193, 0, 11, 5, 248, 100, 11, 5, 248, 95, 11, 5, 248, - 140, 11, 5, 248, 113, 11, 5, 248, 129, 11, 5, 248, 128, 11, 5, 248, 131, - 11, 5, 248, 130, 11, 5, 249, 14, 11, 5, 249, 6, 11, 5, 249, 103, 11, 5, - 249, 39, 11, 5, 247, 186, 11, 5, 247, 190, 11, 5, 247, 187, 11, 5, 248, - 33, 11, 5, 248, 14, 11, 5, 248, 63, 11, 5, 248, 41, 11, 5, 248, 156, 11, - 5, 248, 223, 11, 5, 248, 169, 11, 5, 247, 169, 11, 5, 247, 163, 11, 5, - 247, 218, 11, 5, 247, 184, 11, 5, 247, 177, 11, 5, 247, 182, 11, 5, 247, - 151, 11, 5, 247, 149, 11, 5, 247, 156, 11, 5, 247, 154, 11, 5, 247, 152, - 11, 5, 247, 153, 11, 5, 209, 109, 11, 5, 209, 105, 11, 5, 209, 176, 11, - 5, 209, 121, 11, 5, 209, 140, 11, 5, 209, 167, 11, 5, 209, 163, 11, 5, - 210, 79, 11, 5, 210, 63, 11, 5, 168, 11, 5, 210, 127, 11, 5, 208, 138, - 11, 5, 208, 140, 11, 5, 208, 139, 11, 5, 209, 7, 11, 5, 208, 245, 11, 5, - 209, 65, 11, 5, 209, 26, 11, 5, 208, 124, 11, 5, 208, 119, 11, 5, 208, - 158, 11, 5, 208, 137, 11, 5, 208, 129, 11, 5, 208, 135, 11, 5, 208, 101, - 11, 5, 208, 100, 11, 5, 208, 105, 11, 5, 208, 104, 11, 5, 208, 102, 11, - 5, 208, 103, 11, 5, 248, 244, 11, 5, 248, 243, 11, 5, 248, 250, 11, 5, - 248, 245, 11, 5, 248, 247, 11, 5, 248, 246, 11, 5, 248, 249, 11, 5, 248, - 248, 11, 5, 249, 0, 11, 5, 248, 255, 11, 5, 249, 3, 11, 5, 249, 1, 11, 5, - 248, 235, 11, 5, 248, 237, 11, 5, 248, 236, 11, 5, 248, 240, 11, 5, 248, - 239, 11, 5, 248, 242, 11, 5, 248, 241, 11, 5, 248, 251, 11, 5, 248, 254, - 11, 5, 248, 252, 11, 5, 248, 231, 11, 5, 248, 230, 11, 5, 248, 238, 11, - 5, 248, 234, 11, 5, 248, 232, 11, 5, 248, 233, 11, 5, 248, 227, 11, 5, - 248, 226, 11, 5, 248, 229, 11, 5, 248, 228, 11, 5, 214, 171, 11, 5, 214, - 170, 11, 5, 214, 176, 11, 5, 214, 172, 11, 5, 214, 173, 11, 5, 214, 175, - 11, 5, 214, 174, 11, 5, 214, 179, 11, 5, 214, 178, 11, 5, 214, 181, 11, - 5, 214, 180, 11, 5, 214, 167, 11, 5, 214, 166, 11, 5, 214, 169, 11, 5, - 214, 168, 11, 5, 214, 160, 11, 5, 214, 159, 11, 5, 214, 164, 11, 5, 214, - 163, 11, 5, 214, 161, 11, 5, 214, 162, 11, 5, 214, 154, 11, 5, 214, 153, - 11, 5, 214, 158, 11, 5, 214, 157, 11, 5, 214, 155, 11, 5, 214, 156, 11, - 5, 229, 35, 11, 5, 229, 34, 11, 5, 229, 40, 11, 5, 229, 36, 11, 5, 229, - 37, 11, 5, 229, 39, 11, 5, 229, 38, 11, 5, 229, 43, 11, 5, 229, 42, 11, - 5, 229, 45, 11, 5, 229, 44, 11, 5, 229, 26, 11, 5, 229, 28, 11, 5, 229, - 27, 11, 5, 229, 31, 11, 5, 229, 30, 11, 5, 229, 33, 11, 5, 229, 32, 11, - 5, 229, 22, 11, 5, 229, 21, 11, 5, 229, 29, 11, 5, 229, 25, 11, 5, 229, - 23, 11, 5, 229, 24, 11, 5, 229, 16, 11, 5, 229, 20, 11, 5, 229, 19, 11, - 5, 229, 17, 11, 5, 229, 18, 11, 5, 216, 6, 11, 5, 216, 5, 11, 5, 216, 81, - 11, 5, 216, 14, 11, 5, 216, 45, 11, 5, 216, 63, 11, 5, 216, 61, 11, 5, - 217, 11, 11, 5, 217, 5, 11, 5, 172, 11, 5, 217, 51, 11, 5, 215, 101, 11, - 5, 215, 100, 11, 5, 215, 104, 11, 5, 215, 102, 11, 5, 215, 179, 11, 5, - 215, 152, 11, 5, 215, 251, 11, 5, 215, 186, 11, 5, 216, 133, 11, 5, 216, - 213, 11, 5, 215, 81, 11, 5, 215, 75, 11, 5, 215, 139, 11, 5, 215, 97, 11, - 5, 215, 90, 11, 5, 215, 95, 11, 5, 215, 51, 11, 5, 215, 50, 11, 5, 215, - 56, 11, 5, 215, 53, 11, 5, 232, 188, 11, 5, 232, 182, 11, 5, 232, 238, - 11, 5, 232, 204, 11, 5, 233, 31, 11, 5, 233, 22, 11, 5, 233, 68, 11, 5, - 233, 36, 11, 5, 232, 81, 11, 5, 232, 135, 11, 5, 232, 115, 11, 5, 232, - 31, 11, 5, 232, 30, 11, 5, 232, 48, 11, 5, 232, 36, 11, 5, 232, 34, 11, - 5, 232, 35, 11, 5, 232, 17, 11, 5, 232, 16, 11, 5, 232, 20, 11, 5, 232, - 18, 11, 5, 195, 29, 11, 5, 195, 23, 11, 5, 195, 66, 11, 5, 195, 38, 11, - 5, 195, 55, 11, 5, 195, 50, 11, 5, 195, 58, 11, 5, 195, 57, 11, 5, 195, - 159, 11, 5, 195, 154, 11, 5, 195, 185, 11, 5, 195, 172, 11, 5, 195, 1, - 11, 5, 194, 253, 11, 5, 195, 21, 11, 5, 195, 3, 11, 5, 195, 70, 11, 5, - 195, 138, 11, 5, 193, 239, 11, 5, 193, 237, 11, 5, 193, 246, 11, 5, 193, - 242, 11, 5, 193, 240, 11, 5, 193, 241, 11, 5, 193, 226, 11, 5, 193, 225, - 11, 5, 193, 232, 11, 5, 193, 231, 11, 5, 193, 229, 11, 5, 193, 230, 11, - 5, 236, 167, 11, 5, 236, 152, 11, 5, 236, 255, 11, 5, 236, 195, 11, 5, - 236, 230, 11, 5, 236, 235, 11, 5, 236, 234, 11, 5, 237, 166, 11, 5, 237, - 160, 11, 5, 237, 241, 11, 5, 237, 186, 11, 5, 235, 25, 11, 5, 235, 26, - 11, 5, 236, 96, 11, 5, 235, 73, 11, 5, 236, 129, 11, 5, 236, 99, 11, 5, - 237, 29, 11, 5, 237, 101, 11, 5, 237, 51, 11, 5, 235, 16, 11, 5, 235, 14, - 11, 5, 235, 45, 11, 5, 235, 24, 11, 5, 235, 19, 11, 5, 235, 22, 11, 5, - 198, 120, 11, 5, 198, 112, 11, 5, 198, 188, 11, 5, 198, 130, 11, 5, 198, - 171, 11, 5, 198, 173, 11, 5, 198, 172, 11, 5, 199, 166, 11, 5, 199, 151, - 11, 5, 199, 247, 11, 5, 199, 178, 11, 5, 197, 65, 11, 5, 197, 64, 11, 5, - 197, 67, 11, 5, 197, 66, 11, 5, 198, 35, 11, 5, 198, 24, 11, 5, 159, 11, - 5, 198, 48, 11, 5, 199, 50, 11, 5, 199, 140, 11, 5, 199, 77, 11, 5, 197, - 48, 11, 5, 197, 43, 11, 5, 197, 90, 11, 5, 197, 63, 11, 5, 197, 49, 11, - 5, 197, 60, 11, 5, 237, 118, 11, 5, 237, 117, 11, 5, 237, 123, 11, 5, - 237, 119, 11, 5, 237, 120, 11, 5, 237, 122, 11, 5, 237, 121, 11, 5, 237, - 139, 11, 5, 237, 138, 11, 5, 237, 146, 11, 5, 237, 140, 11, 5, 237, 108, - 11, 5, 237, 110, 11, 5, 237, 109, 11, 5, 237, 113, 11, 5, 237, 112, 11, - 5, 237, 116, 11, 5, 237, 114, 11, 5, 237, 131, 11, 5, 237, 134, 11, 5, - 237, 132, 11, 5, 237, 104, 11, 5, 237, 103, 11, 5, 237, 111, 11, 5, 237, - 107, 11, 5, 237, 105, 11, 5, 237, 106, 11, 5, 214, 126, 11, 5, 214, 125, - 11, 5, 214, 133, 11, 5, 214, 128, 11, 5, 214, 129, 11, 5, 214, 130, 11, - 5, 214, 142, 11, 5, 214, 141, 11, 5, 214, 148, 11, 5, 214, 143, 11, 5, - 214, 118, 11, 5, 214, 117, 11, 5, 214, 124, 11, 5, 214, 119, 11, 5, 214, - 134, 11, 5, 214, 140, 11, 5, 214, 138, 11, 5, 214, 110, 11, 5, 214, 109, - 11, 5, 214, 115, 11, 5, 214, 113, 11, 5, 214, 111, 11, 5, 214, 112, 11, - 5, 229, 1, 11, 5, 229, 0, 11, 5, 229, 7, 11, 5, 229, 2, 11, 5, 229, 4, - 11, 5, 229, 3, 11, 5, 229, 6, 11, 5, 229, 5, 11, 5, 229, 13, 11, 5, 229, - 11, 11, 5, 229, 15, 11, 5, 229, 14, 11, 5, 228, 250, 11, 5, 228, 251, 11, - 5, 228, 254, 11, 5, 228, 253, 11, 5, 228, 255, 11, 5, 229, 8, 11, 5, 229, - 10, 11, 5, 229, 9, 11, 5, 228, 249, 11, 5, 213, 149, 11, 5, 213, 147, 11, - 5, 213, 205, 11, 5, 213, 152, 11, 5, 213, 179, 11, 5, 213, 193, 11, 5, - 213, 192, 11, 5, 214, 186, 11, 5, 180, 11, 5, 214, 204, 11, 5, 212, 109, - 11, 5, 212, 111, 11, 5, 212, 110, 11, 5, 212, 254, 11, 5, 212, 238, 11, - 5, 213, 30, 11, 5, 213, 9, 11, 5, 214, 60, 11, 5, 214, 107, 11, 5, 214, - 83, 11, 5, 212, 104, 11, 5, 212, 100, 11, 5, 212, 165, 11, 5, 212, 108, - 11, 5, 212, 106, 11, 5, 212, 107, 11, 5, 229, 66, 11, 5, 229, 65, 11, 5, - 229, 71, 11, 5, 229, 67, 11, 5, 229, 68, 11, 5, 229, 70, 11, 5, 229, 69, - 11, 5, 229, 77, 11, 5, 229, 75, 11, 5, 229, 79, 11, 5, 229, 78, 11, 5, - 229, 58, 11, 5, 229, 60, 11, 5, 229, 59, 11, 5, 229, 62, 11, 5, 229, 64, - 11, 5, 229, 63, 11, 5, 229, 72, 11, 5, 229, 74, 11, 5, 229, 73, 11, 5, - 229, 54, 11, 5, 229, 53, 11, 5, 229, 61, 11, 5, 229, 57, 11, 5, 229, 55, - 11, 5, 229, 56, 11, 5, 229, 48, 11, 5, 229, 47, 11, 5, 229, 52, 11, 5, - 229, 51, 11, 5, 229, 49, 11, 5, 229, 50, 11, 5, 219, 63, 11, 5, 219, 55, - 11, 5, 219, 122, 11, 5, 219, 74, 11, 5, 219, 113, 11, 5, 219, 112, 11, 5, - 219, 116, 11, 5, 219, 114, 11, 5, 219, 237, 11, 5, 219, 225, 11, 5, 171, - 11, 5, 219, 248, 11, 5, 218, 180, 11, 5, 218, 179, 11, 5, 218, 182, 11, - 5, 218, 181, 11, 5, 218, 227, 11, 5, 218, 212, 11, 5, 219, 19, 11, 5, - 218, 233, 11, 5, 219, 140, 11, 5, 219, 214, 11, 5, 219, 160, 11, 5, 218, - 174, 11, 5, 218, 172, 11, 5, 218, 203, 11, 5, 218, 178, 11, 5, 218, 176, - 11, 5, 218, 177, 11, 5, 218, 152, 11, 5, 218, 151, 11, 5, 218, 162, 11, - 5, 218, 155, 11, 5, 218, 153, 11, 5, 218, 154, 11, 5, 230, 242, 11, 5, - 230, 241, 11, 5, 231, 16, 11, 5, 230, 254, 11, 5, 231, 8, 11, 5, 231, 7, - 11, 5, 231, 10, 11, 5, 231, 9, 11, 5, 231, 155, 11, 5, 231, 150, 11, 5, - 231, 203, 11, 5, 231, 166, 11, 5, 230, 119, 11, 5, 230, 118, 11, 5, 230, - 121, 11, 5, 230, 120, 11, 5, 230, 198, 11, 5, 230, 196, 11, 5, 230, 223, - 11, 5, 230, 208, 11, 5, 231, 94, 11, 5, 231, 92, 11, 5, 231, 128, 11, 5, - 231, 105, 11, 5, 230, 107, 11, 5, 230, 106, 11, 5, 230, 146, 11, 5, 230, - 117, 11, 5, 230, 108, 11, 5, 230, 116, 11, 5, 221, 96, 11, 5, 221, 91, - 11, 5, 221, 142, 11, 5, 221, 110, 11, 5, 221, 123, 11, 5, 221, 127, 11, - 5, 221, 125, 11, 5, 222, 23, 11, 5, 222, 5, 11, 5, 157, 11, 5, 222, 52, - 11, 5, 220, 178, 11, 5, 220, 183, 11, 5, 220, 180, 11, 5, 221, 4, 11, 5, - 220, 255, 11, 5, 221, 43, 11, 5, 221, 12, 11, 5, 221, 216, 11, 5, 221, - 199, 11, 5, 221, 253, 11, 5, 221, 220, 11, 5, 220, 164, 11, 5, 220, 160, - 11, 5, 220, 208, 11, 5, 220, 177, 11, 5, 220, 168, 11, 5, 220, 173, 11, - 5, 231, 76, 11, 5, 231, 75, 11, 5, 231, 80, 11, 5, 231, 77, 11, 5, 231, - 79, 11, 5, 231, 78, 11, 5, 231, 87, 11, 5, 231, 86, 11, 5, 231, 90, 11, - 5, 231, 88, 11, 5, 231, 67, 11, 5, 231, 66, 11, 5, 231, 69, 11, 5, 231, - 68, 11, 5, 231, 72, 11, 5, 231, 71, 11, 5, 231, 74, 11, 5, 231, 73, 11, - 5, 231, 82, 11, 5, 231, 81, 11, 5, 231, 85, 11, 5, 231, 83, 11, 5, 231, - 62, 11, 5, 231, 61, 11, 5, 231, 70, 11, 5, 231, 65, 11, 5, 231, 63, 11, - 5, 231, 64, 11, 5, 216, 100, 11, 5, 216, 101, 11, 5, 216, 119, 11, 5, - 216, 118, 11, 5, 216, 121, 11, 5, 216, 120, 11, 5, 216, 91, 11, 5, 216, - 93, 11, 5, 216, 92, 11, 5, 216, 96, 11, 5, 216, 95, 11, 5, 216, 98, 11, - 5, 216, 97, 11, 5, 216, 102, 11, 5, 216, 104, 11, 5, 216, 103, 11, 5, - 216, 87, 11, 5, 216, 86, 11, 5, 216, 94, 11, 5, 216, 90, 11, 5, 216, 88, - 11, 5, 216, 89, 11, 5, 228, 73, 11, 5, 228, 72, 11, 5, 228, 79, 11, 5, - 228, 74, 11, 5, 228, 76, 11, 5, 228, 75, 11, 5, 228, 78, 11, 5, 228, 77, - 11, 5, 228, 84, 11, 5, 228, 83, 11, 5, 228, 86, 11, 5, 228, 85, 11, 5, - 228, 65, 11, 5, 228, 64, 11, 5, 228, 67, 11, 5, 228, 66, 11, 5, 228, 69, - 11, 5, 228, 68, 11, 5, 228, 71, 11, 5, 228, 70, 11, 5, 228, 80, 11, 5, - 228, 82, 11, 5, 228, 81, 11, 5, 213, 255, 11, 5, 214, 1, 11, 5, 214, 0, - 11, 5, 214, 44, 11, 5, 214, 42, 11, 5, 214, 54, 11, 5, 214, 47, 11, 5, - 213, 216, 11, 5, 213, 215, 11, 5, 213, 217, 11, 5, 213, 227, 11, 5, 213, - 224, 11, 5, 213, 235, 11, 5, 213, 229, 11, 5, 214, 35, 11, 5, 214, 41, - 11, 5, 214, 37, 11, 5, 229, 85, 11, 5, 229, 104, 11, 5, 229, 113, 11, 5, - 229, 232, 11, 5, 229, 221, 11, 5, 144, 11, 5, 229, 244, 11, 5, 228, 103, - 11, 5, 228, 102, 11, 5, 228, 105, 11, 5, 228, 104, 11, 5, 228, 149, 11, - 5, 228, 140, 11, 5, 228, 247, 11, 5, 228, 212, 11, 5, 229, 151, 11, 5, - 229, 213, 11, 5, 229, 163, 11, 5, 193, 144, 11, 5, 193, 129, 11, 5, 193, - 187, 11, 5, 193, 156, 11, 5, 192, 245, 11, 5, 192, 247, 11, 5, 192, 246, - 11, 5, 193, 13, 11, 5, 193, 48, 11, 5, 193, 24, 11, 5, 193, 97, 11, 5, - 193, 123, 11, 5, 193, 104, 11, 5, 191, 15, 11, 5, 191, 14, 11, 5, 191, - 30, 11, 5, 191, 18, 11, 5, 191, 23, 11, 5, 191, 25, 11, 5, 191, 24, 11, - 5, 191, 96, 11, 5, 191, 93, 11, 5, 191, 123, 11, 5, 191, 104, 11, 5, 190, - 244, 11, 5, 190, 246, 11, 5, 190, 245, 11, 5, 191, 2, 11, 5, 191, 1, 11, - 5, 191, 7, 11, 5, 191, 3, 11, 5, 191, 73, 11, 5, 191, 87, 11, 5, 191, 79, - 11, 5, 190, 240, 11, 5, 190, 239, 11, 5, 190, 251, 11, 5, 190, 243, 11, - 5, 190, 241, 11, 5, 190, 242, 11, 5, 190, 226, 11, 5, 190, 225, 11, 5, - 190, 231, 11, 5, 190, 229, 11, 5, 190, 227, 11, 5, 190, 228, 11, 5, 242, - 207, 11, 5, 242, 200, 11, 5, 242, 237, 11, 5, 242, 220, 11, 5, 242, 234, - 11, 5, 242, 228, 11, 5, 242, 236, 11, 5, 242, 235, 11, 5, 247, 30, 11, 5, - 247, 21, 11, 5, 247, 112, 11, 5, 247, 63, 11, 5, 238, 136, 11, 5, 238, - 138, 11, 5, 238, 137, 11, 5, 238, 202, 11, 5, 238, 190, 11, 5, 242, 51, - 11, 5, 238, 222, 11, 5, 246, 213, 11, 5, 246, 250, 11, 5, 246, 219, 11, - 5, 238, 107, 11, 5, 238, 105, 11, 5, 238, 148, 11, 5, 238, 134, 11, 5, - 238, 113, 11, 5, 238, 129, 11, 5, 238, 83, 11, 5, 238, 82, 11, 5, 238, - 96, 11, 5, 238, 90, 11, 5, 238, 84, 11, 5, 238, 86, 11, 5, 190, 209, 11, - 5, 190, 208, 11, 5, 190, 215, 11, 5, 190, 210, 11, 5, 190, 212, 11, 5, - 190, 211, 11, 5, 190, 214, 11, 5, 190, 213, 11, 5, 190, 221, 11, 5, 190, - 220, 11, 5, 190, 224, 11, 5, 190, 222, 11, 5, 190, 205, 11, 5, 190, 207, - 11, 5, 190, 206, 11, 5, 190, 216, 11, 5, 190, 219, 11, 5, 190, 217, 11, - 5, 190, 198, 11, 5, 190, 202, 11, 5, 190, 201, 11, 5, 190, 199, 11, 5, - 190, 200, 11, 5, 190, 192, 11, 5, 190, 191, 11, 5, 190, 197, 11, 5, 190, - 195, 11, 5, 190, 193, 11, 5, 190, 194, 11, 5, 212, 20, 11, 5, 212, 19, - 11, 5, 212, 25, 11, 5, 212, 21, 11, 5, 212, 22, 11, 5, 212, 24, 11, 5, - 212, 23, 11, 5, 212, 30, 11, 5, 212, 29, 11, 5, 212, 33, 11, 5, 212, 32, - 11, 5, 212, 13, 11, 5, 212, 14, 11, 5, 212, 17, 11, 5, 212, 18, 11, 5, - 212, 26, 11, 5, 212, 28, 11, 5, 212, 8, 11, 5, 212, 16, 11, 5, 212, 12, - 11, 5, 212, 9, 11, 5, 212, 10, 11, 5, 212, 3, 11, 5, 212, 2, 11, 5, 212, - 7, 11, 5, 212, 6, 11, 5, 212, 4, 11, 5, 212, 5, 11, 5, 202, 133, 11, 5, - 173, 11, 5, 202, 217, 11, 5, 202, 137, 11, 5, 202, 197, 11, 5, 202, 200, - 11, 5, 202, 198, 11, 5, 205, 117, 11, 5, 205, 101, 11, 5, 189, 11, 5, - 205, 125, 11, 5, 200, 183, 11, 5, 200, 185, 11, 5, 200, 184, 11, 5, 202, - 3, 11, 5, 201, 248, 11, 5, 202, 41, 11, 5, 202, 9, 11, 5, 203, 233, 11, - 5, 205, 63, 11, 5, 204, 8, 11, 5, 200, 158, 11, 5, 200, 155, 11, 5, 200, - 255, 11, 5, 200, 182, 11, 5, 200, 162, 11, 5, 200, 170, 11, 5, 200, 53, - 11, 5, 200, 52, 11, 5, 200, 123, 11, 5, 200, 61, 11, 5, 200, 55, 11, 5, - 200, 60, 11, 5, 201, 131, 11, 5, 201, 130, 11, 5, 201, 137, 11, 5, 201, - 132, 11, 5, 201, 134, 11, 5, 201, 136, 11, 5, 201, 135, 11, 5, 201, 146, - 11, 5, 201, 144, 11, 5, 201, 170, 11, 5, 201, 147, 11, 5, 201, 126, 11, - 5, 201, 125, 11, 5, 201, 129, 11, 5, 201, 127, 11, 5, 201, 140, 11, 5, - 201, 143, 11, 5, 201, 141, 11, 5, 201, 122, 11, 5, 201, 120, 11, 5, 201, - 124, 11, 5, 201, 123, 11, 5, 201, 115, 11, 5, 201, 114, 11, 5, 201, 119, - 11, 5, 201, 118, 11, 5, 201, 116, 11, 5, 201, 117, 11, 5, 191, 66, 11, 5, - 191, 65, 11, 5, 191, 71, 11, 5, 191, 68, 11, 5, 191, 45, 11, 5, 191, 47, - 11, 5, 191, 46, 11, 5, 191, 50, 11, 5, 191, 49, 11, 5, 191, 54, 11, 5, - 191, 51, 11, 5, 191, 59, 11, 5, 191, 58, 11, 5, 191, 62, 11, 5, 191, 60, - 11, 5, 191, 41, 11, 5, 191, 40, 11, 5, 191, 48, 11, 5, 191, 44, 11, 5, - 191, 42, 11, 5, 191, 43, 11, 5, 191, 33, 11, 5, 191, 32, 11, 5, 191, 37, - 11, 5, 191, 36, 11, 5, 191, 34, 11, 5, 191, 35, 11, 5, 243, 85, 11, 5, - 243, 81, 11, 5, 246, 209, 11, 5, 246, 195, 11, 5, 242, 252, 11, 5, 242, - 251, 11, 5, 242, 254, 11, 5, 242, 253, 11, 5, 243, 11, 11, 5, 243, 10, - 11, 5, 243, 20, 11, 5, 243, 15, 11, 5, 243, 54, 11, 5, 243, 51, 11, 5, - 243, 79, 11, 5, 243, 62, 11, 5, 242, 246, 11, 5, 243, 0, 11, 5, 242, 250, - 11, 5, 242, 247, 11, 5, 242, 249, 11, 5, 242, 239, 11, 5, 242, 238, 11, - 5, 242, 243, 11, 5, 242, 242, 11, 5, 242, 240, 11, 5, 242, 241, 11, 5, - 206, 100, 11, 5, 206, 104, 11, 5, 206, 82, 11, 5, 206, 83, 11, 5, 206, - 87, 11, 5, 206, 86, 11, 5, 206, 90, 11, 5, 206, 88, 11, 5, 206, 94, 11, - 5, 206, 93, 11, 5, 206, 99, 11, 5, 206, 95, 11, 5, 206, 78, 11, 5, 206, - 76, 11, 5, 206, 84, 11, 5, 206, 81, 11, 5, 206, 79, 11, 5, 206, 80, 11, - 5, 206, 71, 11, 5, 206, 70, 11, 5, 206, 75, 11, 5, 206, 74, 11, 5, 206, - 72, 11, 5, 206, 73, 11, 5, 212, 229, 11, 5, 212, 228, 11, 5, 212, 231, - 11, 5, 212, 230, 11, 5, 212, 220, 11, 5, 212, 222, 11, 5, 212, 221, 11, - 5, 212, 224, 11, 5, 212, 223, 11, 5, 212, 227, 11, 5, 212, 226, 11, 5, - 212, 214, 11, 5, 212, 213, 11, 5, 212, 219, 11, 5, 212, 217, 11, 5, 212, - 215, 11, 5, 212, 216, 11, 5, 212, 208, 11, 5, 212, 207, 11, 5, 212, 212, - 11, 5, 212, 211, 11, 5, 212, 209, 11, 5, 212, 210, 11, 5, 203, 118, 11, - 5, 203, 113, 11, 5, 203, 160, 11, 5, 203, 131, 11, 5, 202, 244, 11, 5, - 202, 246, 11, 5, 202, 245, 11, 5, 203, 19, 11, 5, 203, 14, 11, 5, 203, - 51, 11, 5, 203, 39, 11, 5, 203, 86, 11, 5, 203, 79, 11, 5, 203, 108, 11, - 5, 203, 95, 11, 5, 202, 240, 11, 5, 202, 237, 11, 5, 203, 0, 11, 5, 202, - 243, 11, 5, 202, 241, 11, 5, 202, 242, 11, 5, 202, 220, 11, 5, 202, 219, - 11, 5, 202, 226, 11, 5, 202, 223, 11, 5, 202, 221, 11, 5, 202, 222, 11, - 5, 207, 125, 11, 5, 207, 118, 11, 5, 166, 11, 5, 207, 131, 11, 5, 206, - 33, 11, 5, 206, 35, 11, 5, 206, 34, 11, 5, 206, 118, 11, 5, 206, 106, 11, - 5, 206, 157, 11, 5, 206, 122, 11, 5, 207, 6, 11, 5, 207, 108, 11, 5, 207, - 48, 11, 5, 206, 25, 11, 5, 206, 22, 11, 5, 206, 63, 11, 5, 206, 32, 11, - 5, 206, 28, 11, 5, 206, 29, 11, 5, 206, 7, 11, 5, 206, 6, 11, 5, 206, 12, - 11, 5, 206, 10, 11, 5, 206, 8, 11, 5, 206, 9, 11, 5, 222, 205, 11, 5, - 222, 204, 11, 5, 222, 217, 11, 5, 222, 206, 11, 5, 222, 213, 11, 5, 222, - 212, 11, 5, 222, 215, 11, 5, 222, 214, 11, 5, 222, 143, 11, 5, 222, 142, - 11, 5, 222, 145, 11, 5, 222, 144, 11, 5, 222, 161, 11, 5, 222, 159, 11, - 5, 222, 174, 11, 5, 222, 163, 11, 5, 222, 136, 11, 5, 222, 134, 11, 5, - 222, 155, 11, 5, 222, 141, 11, 5, 222, 138, 11, 5, 222, 139, 11, 5, 222, - 128, 11, 5, 222, 127, 11, 5, 222, 132, 11, 5, 222, 131, 11, 5, 222, 129, - 11, 5, 222, 130, 11, 5, 208, 43, 11, 5, 208, 41, 11, 5, 208, 51, 11, 5, - 208, 44, 11, 5, 208, 48, 11, 5, 208, 47, 11, 5, 208, 50, 11, 5, 208, 49, - 11, 5, 207, 248, 11, 5, 207, 245, 11, 5, 207, 250, 11, 5, 207, 249, 11, - 5, 208, 30, 11, 5, 208, 29, 11, 5, 208, 39, 11, 5, 208, 33, 11, 5, 207, - 240, 11, 5, 207, 236, 11, 5, 208, 27, 11, 5, 207, 244, 11, 5, 207, 242, - 11, 5, 207, 243, 11, 5, 207, 220, 11, 5, 207, 218, 11, 5, 207, 230, 11, - 5, 207, 223, 11, 5, 207, 221, 11, 5, 207, 222, 11, 5, 222, 194, 11, 5, - 222, 193, 11, 5, 222, 200, 11, 5, 222, 195, 11, 5, 222, 197, 11, 5, 222, - 196, 11, 5, 222, 199, 11, 5, 222, 198, 11, 5, 222, 185, 11, 5, 222, 187, - 11, 5, 222, 186, 11, 5, 222, 190, 11, 5, 222, 189, 11, 5, 222, 192, 11, - 5, 222, 191, 11, 5, 222, 181, 11, 5, 222, 180, 11, 5, 222, 188, 11, 5, - 222, 184, 11, 5, 222, 182, 11, 5, 222, 183, 11, 5, 222, 177, 11, 5, 222, - 176, 11, 5, 222, 179, 11, 5, 222, 178, 11, 5, 213, 121, 11, 5, 213, 120, - 11, 5, 213, 128, 11, 5, 213, 122, 11, 5, 213, 124, 11, 5, 213, 123, 11, - 5, 213, 127, 11, 5, 213, 125, 11, 5, 213, 110, 11, 5, 213, 111, 11, 5, - 213, 116, 11, 5, 213, 115, 11, 5, 213, 119, 11, 5, 213, 117, 11, 5, 213, - 105, 11, 5, 213, 114, 11, 5, 213, 109, 11, 5, 213, 106, 11, 5, 213, 107, - 11, 5, 213, 100, 11, 5, 213, 99, 11, 5, 213, 104, 11, 5, 213, 103, 11, 5, - 213, 101, 11, 5, 213, 102, 11, 5, 212, 55, 11, 5, 212, 54, 11, 5, 212, - 68, 11, 5, 212, 59, 11, 5, 212, 64, 11, 5, 212, 63, 11, 5, 212, 66, 11, - 5, 212, 65, 11, 5, 212, 40, 11, 5, 212, 42, 11, 5, 212, 41, 11, 5, 212, - 47, 11, 5, 212, 46, 11, 5, 212, 52, 11, 5, 212, 48, 11, 5, 212, 38, 11, - 5, 212, 36, 11, 5, 212, 45, 11, 5, 212, 39, 11, 5, 192, 198, 11, 5, 192, - 197, 11, 5, 192, 207, 11, 5, 192, 200, 11, 5, 192, 202, 11, 5, 192, 201, - 11, 5, 192, 204, 11, 5, 192, 203, 11, 5, 192, 186, 11, 5, 192, 187, 11, - 5, 192, 191, 11, 5, 192, 190, 11, 5, 192, 196, 11, 5, 192, 194, 11, 5, - 192, 163, 11, 5, 192, 161, 11, 5, 192, 176, 11, 5, 192, 166, 11, 5, 192, - 164, 11, 5, 192, 165, 11, 5, 192, 18, 11, 5, 192, 16, 11, 5, 192, 33, 11, - 5, 192, 19, 11, 5, 192, 27, 11, 5, 192, 26, 11, 5, 192, 30, 11, 5, 192, - 28, 11, 5, 191, 198, 11, 5, 191, 197, 11, 5, 191, 201, 11, 5, 191, 199, - 11, 5, 191, 240, 11, 5, 191, 235, 11, 5, 192, 12, 11, 5, 191, 245, 11, 5, - 191, 189, 11, 5, 191, 185, 11, 5, 191, 225, 11, 5, 191, 196, 11, 5, 191, - 192, 11, 5, 191, 193, 11, 5, 191, 169, 11, 5, 191, 168, 11, 5, 191, 176, - 11, 5, 191, 172, 11, 5, 191, 170, 11, 5, 191, 171, 11, 48, 208, 30, 11, - 48, 219, 122, 11, 48, 221, 96, 11, 48, 212, 59, 11, 48, 238, 90, 11, 48, - 201, 137, 11, 48, 231, 73, 11, 48, 231, 105, 11, 48, 216, 81, 11, 48, - 228, 73, 11, 48, 218, 154, 11, 48, 248, 231, 11, 48, 215, 186, 11, 48, - 192, 12, 11, 48, 208, 124, 11, 48, 228, 67, 11, 48, 199, 166, 11, 48, - 231, 203, 11, 48, 190, 243, 11, 48, 238, 83, 11, 48, 237, 106, 11, 48, - 247, 182, 11, 48, 231, 69, 11, 48, 212, 48, 11, 48, 197, 90, 11, 48, 211, - 67, 11, 48, 222, 181, 11, 48, 191, 2, 11, 48, 208, 101, 11, 48, 229, 33, - 11, 48, 192, 18, 11, 48, 193, 241, 11, 48, 202, 226, 11, 48, 195, 138, - 11, 48, 191, 123, 11, 48, 222, 174, 11, 48, 212, 12, 11, 48, 222, 179, - 11, 48, 230, 198, 11, 48, 222, 199, 11, 48, 193, 48, 11, 48, 235, 45, 11, - 48, 202, 242, 11, 48, 219, 116, 11, 48, 238, 96, 11, 48, 238, 137, 11, - 48, 242, 220, 11, 48, 228, 70, 11, 48, 203, 118, 11, 48, 190, 242, 11, - 48, 203, 39, 11, 48, 243, 79, 11, 48, 190, 212, 11, 48, 214, 175, 11, 48, - 221, 253, 219, 64, 1, 249, 103, 219, 64, 1, 168, 219, 64, 1, 209, 219, - 219, 64, 1, 237, 241, 219, 64, 1, 199, 247, 219, 64, 1, 199, 44, 219, 64, - 1, 231, 203, 219, 64, 1, 157, 219, 64, 1, 221, 190, 219, 64, 1, 223, 4, - 219, 64, 1, 247, 112, 219, 64, 1, 246, 209, 219, 64, 1, 234, 247, 219, - 64, 1, 197, 164, 219, 64, 1, 197, 153, 219, 64, 1, 172, 219, 64, 1, 180, - 219, 64, 1, 171, 219, 64, 1, 189, 219, 64, 1, 191, 71, 219, 64, 1, 191, - 123, 219, 64, 1, 214, 54, 219, 64, 1, 144, 219, 64, 1, 192, 220, 219, 64, - 1, 229, 145, 219, 64, 1, 233, 68, 219, 64, 1, 193, 187, 219, 64, 1, 203, - 160, 219, 64, 1, 169, 219, 64, 1, 231, 54, 219, 64, 1, 65, 219, 64, 1, - 251, 229, 219, 64, 1, 73, 219, 64, 1, 233, 201, 219, 64, 1, 70, 219, 64, - 1, 74, 219, 64, 1, 69, 219, 64, 1, 196, 148, 219, 64, 1, 196, 137, 219, - 64, 1, 211, 139, 219, 64, 1, 163, 215, 55, 198, 188, 219, 64, 1, 163, - 214, 249, 209, 65, 219, 64, 1, 163, 215, 55, 238, 95, 219, 64, 1, 163, - 215, 55, 248, 63, 219, 64, 1, 163, 215, 55, 180, 219, 64, 1, 163, 215, - 55, 222, 226, 219, 64, 208, 145, 242, 26, 219, 64, 208, 145, 232, 42, - 201, 58, 58, 5, 234, 145, 58, 5, 234, 141, 58, 5, 229, 183, 58, 5, 193, - 112, 58, 5, 193, 111, 58, 5, 210, 40, 58, 5, 248, 147, 58, 5, 248, 207, - 58, 5, 216, 240, 58, 5, 220, 248, 58, 5, 216, 113, 58, 5, 231, 141, 58, - 5, 233, 11, 58, 5, 195, 145, 58, 5, 199, 116, 58, 5, 199, 26, 58, 5, 237, - 13, 58, 5, 237, 10, 58, 5, 219, 204, 58, 5, 207, 79, 58, 5, 237, 86, 58, - 5, 214, 139, 58, 5, 205, 45, 58, 5, 203, 106, 58, 5, 191, 84, 58, 5, 191, - 61, 58, 5, 246, 242, 58, 5, 222, 236, 58, 5, 213, 135, 58, 5, 192, 77, - 58, 5, 221, 244, 58, 5, 214, 27, 58, 5, 231, 120, 58, 5, 216, 192, 58, 5, - 214, 96, 58, 5, 212, 76, 58, 5, 70, 58, 5, 223, 134, 58, 5, 229, 126, 58, - 5, 229, 96, 58, 5, 193, 84, 58, 5, 193, 66, 58, 5, 209, 176, 58, 5, 248, - 145, 58, 5, 248, 140, 58, 5, 216, 233, 58, 5, 220, 245, 58, 5, 216, 110, - 58, 5, 231, 137, 58, 5, 232, 238, 58, 5, 195, 66, 58, 5, 198, 188, 58, 5, - 199, 6, 58, 5, 237, 5, 58, 5, 237, 9, 58, 5, 219, 122, 58, 5, 206, 252, - 58, 5, 236, 255, 58, 5, 214, 133, 58, 5, 202, 217, 58, 5, 203, 76, 58, 5, - 191, 30, 58, 5, 191, 57, 58, 5, 242, 237, 58, 5, 222, 217, 58, 5, 213, - 128, 58, 5, 192, 33, 58, 5, 221, 142, 58, 5, 214, 19, 58, 5, 231, 16, 58, - 5, 216, 81, 58, 5, 213, 205, 58, 5, 212, 68, 58, 5, 65, 58, 5, 251, 81, - 58, 5, 214, 49, 58, 5, 144, 58, 5, 230, 23, 58, 5, 193, 187, 58, 5, 193, - 162, 58, 5, 168, 58, 5, 248, 153, 58, 5, 249, 103, 58, 5, 216, 248, 58, - 5, 220, 253, 58, 5, 220, 251, 58, 5, 216, 117, 58, 5, 231, 145, 58, 5, - 233, 68, 58, 5, 195, 185, 58, 5, 199, 247, 58, 5, 199, 44, 58, 5, 237, - 23, 58, 5, 237, 12, 58, 5, 171, 58, 5, 166, 58, 5, 237, 241, 58, 5, 214, - 148, 58, 5, 189, 58, 5, 203, 160, 58, 5, 191, 123, 58, 5, 191, 71, 58, 5, - 247, 112, 58, 5, 223, 4, 58, 5, 213, 144, 58, 5, 169, 58, 5, 157, 58, 5, - 222, 61, 58, 5, 214, 33, 58, 5, 231, 203, 58, 5, 172, 58, 5, 180, 58, 5, - 212, 88, 58, 5, 211, 76, 58, 5, 211, 71, 58, 5, 228, 220, 58, 5, 193, 29, - 58, 5, 193, 25, 58, 5, 209, 30, 58, 5, 248, 143, 58, 5, 248, 49, 58, 5, - 216, 228, 58, 5, 220, 243, 58, 5, 216, 106, 58, 5, 231, 133, 58, 5, 232, - 123, 58, 5, 195, 5, 58, 5, 198, 54, 58, 5, 198, 230, 58, 5, 237, 2, 58, - 5, 237, 7, 58, 5, 218, 240, 58, 5, 206, 129, 58, 5, 236, 102, 58, 5, 214, - 120, 58, 5, 202, 11, 58, 5, 203, 43, 58, 5, 191, 4, 58, 5, 191, 52, 58, - 5, 238, 227, 58, 5, 222, 164, 58, 5, 213, 118, 58, 5, 191, 246, 58, 5, - 221, 17, 58, 5, 214, 17, 58, 5, 230, 210, 58, 5, 215, 194, 58, 5, 213, - 13, 58, 5, 212, 49, 58, 5, 69, 58, 5, 196, 109, 58, 5, 228, 128, 58, 5, - 228, 111, 58, 5, 193, 0, 58, 5, 192, 249, 58, 5, 208, 158, 58, 5, 248, - 142, 58, 5, 247, 218, 58, 5, 216, 227, 58, 5, 220, 241, 58, 5, 216, 105, - 58, 5, 231, 132, 58, 5, 232, 48, 58, 5, 193, 246, 58, 5, 197, 90, 58, 5, - 198, 208, 58, 5, 237, 0, 58, 5, 237, 6, 58, 5, 218, 203, 58, 5, 206, 63, - 58, 5, 235, 45, 58, 5, 214, 115, 58, 5, 200, 255, 58, 5, 203, 0, 58, 5, - 190, 251, 58, 5, 191, 48, 58, 5, 238, 148, 58, 5, 222, 155, 58, 5, 213, - 114, 58, 5, 191, 225, 58, 5, 220, 208, 58, 5, 214, 16, 58, 5, 230, 146, - 58, 5, 215, 139, 58, 5, 212, 165, 58, 5, 212, 45, 58, 5, 74, 58, 5, 211, - 93, 58, 5, 213, 231, 58, 5, 228, 247, 58, 5, 228, 223, 58, 5, 193, 48, - 58, 5, 193, 30, 58, 5, 209, 65, 58, 5, 248, 144, 58, 5, 248, 63, 58, 5, - 216, 229, 58, 5, 220, 244, 58, 5, 216, 108, 58, 5, 231, 135, 58, 5, 231, - 134, 58, 5, 232, 135, 58, 5, 195, 21, 58, 5, 159, 58, 5, 198, 236, 58, 5, - 237, 3, 58, 5, 237, 8, 58, 5, 219, 19, 58, 5, 206, 157, 58, 5, 236, 129, - 58, 5, 214, 124, 58, 5, 202, 41, 58, 5, 203, 51, 58, 5, 191, 7, 58, 5, - 191, 54, 58, 5, 242, 51, 58, 5, 222, 174, 58, 5, 213, 119, 58, 5, 192, - 12, 58, 5, 221, 43, 58, 5, 214, 18, 58, 5, 230, 223, 58, 5, 215, 251, 58, - 5, 213, 30, 58, 5, 212, 52, 58, 5, 73, 58, 5, 234, 61, 58, 5, 214, 38, - 58, 5, 229, 213, 58, 5, 229, 166, 58, 5, 193, 123, 58, 5, 193, 106, 58, - 5, 210, 53, 58, 5, 248, 148, 58, 5, 248, 223, 58, 5, 216, 241, 58, 5, - 220, 249, 58, 5, 220, 247, 58, 5, 216, 114, 58, 5, 231, 142, 58, 5, 231, - 140, 58, 5, 233, 18, 58, 5, 195, 150, 58, 5, 199, 140, 58, 5, 199, 28, - 58, 5, 237, 14, 58, 5, 237, 11, 58, 5, 219, 214, 58, 5, 207, 108, 58, 5, - 237, 101, 58, 5, 214, 140, 58, 5, 205, 63, 58, 5, 203, 108, 58, 5, 191, - 87, 58, 5, 191, 62, 58, 5, 246, 250, 58, 5, 222, 238, 58, 5, 213, 137, - 58, 5, 192, 80, 58, 5, 221, 253, 58, 5, 214, 28, 58, 5, 214, 24, 58, 5, - 231, 128, 58, 5, 231, 114, 58, 5, 216, 213, 58, 5, 214, 107, 58, 5, 212, - 77, 58, 5, 214, 56, 58, 5, 219, 166, 58, 242, 26, 58, 232, 42, 201, 58, - 58, 208, 8, 77, 58, 5, 214, 123, 233, 68, 58, 5, 214, 123, 157, 58, 5, - 214, 123, 202, 11, 58, 16, 233, 7, 58, 16, 221, 242, 58, 16, 198, 135, - 58, 16, 213, 172, 58, 16, 249, 45, 58, 16, 233, 67, 58, 16, 199, 240, 58, - 16, 237, 191, 58, 16, 236, 101, 58, 16, 220, 184, 58, 16, 198, 58, 58, - 16, 236, 128, 58, 16, 222, 165, 58, 17, 191, 77, 58, 17, 108, 58, 17, - 109, 58, 17, 139, 58, 17, 137, 58, 17, 153, 58, 17, 173, 58, 17, 181, 58, - 17, 176, 58, 17, 184, 58, 5, 214, 123, 172, 58, 5, 214, 123, 236, 129, - 42, 6, 1, 191, 81, 42, 2, 1, 191, 81, 42, 6, 1, 234, 242, 42, 2, 1, 234, - 242, 42, 6, 1, 207, 13, 234, 244, 42, 2, 1, 207, 13, 234, 244, 42, 6, 1, - 223, 55, 42, 2, 1, 223, 55, 42, 6, 1, 236, 146, 42, 2, 1, 236, 146, 42, - 6, 1, 215, 202, 196, 124, 42, 2, 1, 215, 202, 196, 124, 42, 6, 1, 247, - 232, 211, 99, 42, 2, 1, 247, 232, 211, 99, 42, 6, 1, 214, 68, 192, 62, - 42, 2, 1, 214, 68, 192, 62, 42, 6, 1, 192, 59, 4, 249, 97, 192, 62, 42, - 2, 1, 192, 59, 4, 249, 97, 192, 62, 42, 6, 1, 223, 53, 192, 95, 42, 2, 1, - 223, 53, 192, 95, 42, 6, 1, 207, 13, 191, 225, 42, 2, 1, 207, 13, 191, - 225, 42, 6, 1, 223, 53, 65, 42, 2, 1, 223, 53, 65, 42, 6, 1, 242, 171, - 219, 59, 191, 190, 42, 2, 1, 242, 171, 219, 59, 191, 190, 42, 6, 1, 248, - 83, 191, 190, 42, 2, 1, 248, 83, 191, 190, 42, 6, 1, 223, 53, 242, 171, - 219, 59, 191, 190, 42, 2, 1, 223, 53, 242, 171, 219, 59, 191, 190, 42, 6, - 1, 192, 14, 42, 2, 1, 192, 14, 42, 6, 1, 207, 13, 197, 157, 42, 2, 1, - 207, 13, 197, 157, 42, 6, 1, 202, 27, 237, 101, 42, 2, 1, 202, 27, 237, - 101, 42, 6, 1, 202, 27, 234, 97, 42, 2, 1, 202, 27, 234, 97, 42, 6, 1, - 202, 27, 234, 72, 42, 2, 1, 202, 27, 234, 72, 42, 6, 1, 215, 206, 74, 42, - 2, 1, 215, 206, 74, 42, 6, 1, 248, 116, 74, 42, 2, 1, 248, 116, 74, 42, - 6, 1, 54, 215, 206, 74, 42, 2, 1, 54, 215, 206, 74, 42, 1, 215, 115, 74, - 33, 42, 193, 223, 33, 42, 199, 91, 216, 30, 57, 33, 42, 228, 110, 216, - 30, 57, 33, 42, 198, 225, 216, 30, 57, 202, 90, 250, 143, 33, 42, 1, 196, - 121, 223, 197, 33, 42, 1, 70, 33, 42, 1, 192, 33, 33, 42, 1, 69, 33, 42, - 1, 229, 240, 57, 33, 42, 1, 192, 58, 33, 42, 1, 202, 27, 57, 33, 42, 1, - 211, 99, 33, 42, 222, 9, 33, 42, 210, 60, 42, 222, 9, 42, 210, 60, 42, 6, - 1, 235, 1, 42, 2, 1, 235, 1, 42, 6, 1, 234, 233, 42, 2, 1, 234, 233, 42, - 6, 1, 191, 38, 42, 2, 1, 191, 38, 42, 6, 1, 247, 10, 42, 2, 1, 247, 10, - 42, 6, 1, 234, 229, 42, 2, 1, 234, 229, 42, 6, 1, 199, 141, 4, 82, 106, - 42, 2, 1, 199, 141, 4, 82, 106, 42, 6, 1, 197, 37, 42, 2, 1, 197, 37, 42, - 6, 1, 197, 132, 42, 2, 1, 197, 132, 42, 6, 1, 197, 137, 42, 2, 1, 197, - 137, 42, 6, 1, 199, 146, 42, 2, 1, 199, 146, 42, 6, 1, 228, 91, 42, 2, 1, - 228, 91, 42, 6, 1, 202, 232, 42, 2, 1, 202, 232, 42, 6, 1, 54, 74, 42, 2, - 1, 54, 74, 42, 6, 1, 238, 167, 74, 42, 2, 1, 238, 167, 74, 59, 1, 42, - 229, 240, 57, 59, 1, 42, 202, 27, 57, 33, 42, 1, 234, 138, 33, 42, 1, - 223, 53, 73, 26, 1, 65, 26, 1, 157, 26, 1, 69, 26, 1, 220, 208, 26, 1, - 234, 145, 26, 1, 207, 79, 26, 1, 199, 221, 26, 1, 74, 26, 1, 212, 68, 26, - 1, 70, 26, 1, 171, 26, 1, 168, 26, 1, 206, 190, 26, 1, 206, 237, 26, 1, - 219, 203, 26, 1, 216, 191, 26, 1, 199, 240, 26, 1, 214, 146, 26, 1, 213, - 142, 26, 1, 218, 147, 26, 1, 200, 156, 26, 1, 215, 139, 26, 1, 203, 71, - 26, 1, 202, 217, 26, 1, 203, 81, 26, 1, 203, 243, 26, 1, 220, 125, 26, 1, - 221, 216, 26, 1, 212, 133, 26, 1, 212, 165, 26, 1, 213, 113, 26, 1, 191, - 243, 26, 1, 203, 0, 26, 1, 191, 194, 26, 1, 169, 26, 1, 212, 202, 26, 1, - 221, 202, 26, 1, 209, 223, 26, 1, 213, 135, 26, 1, 212, 182, 26, 1, 208, - 149, 26, 1, 192, 253, 26, 1, 210, 40, 26, 1, 233, 11, 26, 1, 206, 63, 26, - 1, 218, 203, 26, 1, 216, 81, 26, 1, 213, 205, 26, 1, 207, 15, 26, 1, 207, - 158, 26, 1, 221, 226, 26, 1, 213, 238, 26, 1, 214, 33, 26, 1, 214, 54, - 26, 1, 203, 51, 26, 1, 208, 154, 26, 1, 232, 48, 26, 1, 232, 128, 26, 1, - 193, 187, 26, 1, 180, 26, 1, 219, 122, 26, 1, 209, 176, 26, 1, 218, 232, - 26, 1, 221, 43, 26, 1, 216, 238, 26, 1, 207, 50, 26, 1, 216, 167, 26, 1, - 172, 26, 1, 198, 188, 26, 1, 221, 142, 26, 1, 215, 251, 26, 1, 216, 246, - 26, 1, 199, 68, 26, 1, 220, 253, 26, 1, 199, 90, 26, 1, 212, 168, 26, 1, - 205, 145, 26, 1, 233, 64, 26, 1, 221, 0, 26, 1, 221, 33, 26, 33, 87, 221, - 10, 26, 33, 87, 197, 75, 26, 213, 141, 26, 232, 42, 201, 58, 26, 242, 35, - 26, 242, 26, 26, 204, 20, 26, 208, 8, 77, 59, 1, 243, 32, 163, 192, 22, - 209, 123, 59, 1, 243, 32, 163, 192, 107, 209, 123, 59, 1, 243, 32, 163, - 192, 22, 203, 132, 59, 1, 243, 32, 163, 192, 107, 203, 132, 59, 1, 243, - 32, 163, 192, 22, 208, 27, 59, 1, 243, 32, 163, 192, 107, 208, 27, 59, 1, - 243, 32, 163, 192, 22, 206, 63, 59, 1, 243, 32, 163, 192, 107, 206, 63, - 59, 1, 233, 159, 235, 94, 163, 164, 59, 1, 136, 235, 94, 163, 164, 59, 1, - 216, 68, 235, 94, 163, 164, 59, 1, 131, 235, 94, 163, 164, 59, 1, 233, - 158, 235, 94, 163, 164, 59, 1, 233, 159, 235, 94, 219, 192, 163, 164, 59, - 1, 136, 235, 94, 219, 192, 163, 164, 59, 1, 216, 68, 235, 94, 219, 192, - 163, 164, 59, 1, 131, 235, 94, 219, 192, 163, 164, 59, 1, 233, 158, 235, - 94, 219, 192, 163, 164, 59, 1, 233, 159, 219, 192, 163, 164, 59, 1, 136, - 219, 192, 163, 164, 59, 1, 216, 68, 219, 192, 163, 164, 59, 1, 131, 219, - 192, 163, 164, 59, 1, 233, 158, 219, 192, 163, 164, 59, 1, 75, 81, 164, - 59, 1, 75, 202, 92, 59, 1, 75, 228, 209, 164, 59, 1, 110, 50, 238, 211, - 251, 64, 59, 1, 207, 142, 132, 55, 59, 1, 207, 142, 143, 55, 59, 1, 207, - 142, 233, 175, 77, 59, 1, 207, 142, 223, 65, 233, 175, 77, 59, 1, 131, - 223, 65, 233, 175, 77, 59, 1, 201, 33, 24, 136, 198, 74, 59, 1, 201, 33, - 24, 131, 198, 74, 8, 6, 1, 234, 132, 251, 141, 8, 2, 1, 234, 132, 251, - 141, 8, 6, 1, 234, 132, 251, 178, 8, 2, 1, 234, 132, 251, 178, 8, 6, 1, - 229, 164, 8, 2, 1, 229, 164, 8, 6, 1, 196, 237, 8, 2, 1, 196, 237, 8, 6, - 1, 197, 244, 8, 2, 1, 197, 244, 8, 6, 1, 238, 145, 8, 2, 1, 238, 145, 8, - 6, 1, 238, 146, 4, 242, 26, 8, 2, 1, 238, 146, 4, 242, 26, 8, 1, 2, 6, - 233, 134, 8, 1, 2, 6, 206, 3, 8, 6, 1, 252, 154, 8, 2, 1, 252, 154, 8, 6, - 1, 251, 18, 8, 2, 1, 251, 18, 8, 6, 1, 250, 113, 8, 2, 1, 250, 113, 8, 6, - 1, 250, 96, 8, 2, 1, 250, 96, 8, 6, 1, 250, 97, 4, 228, 209, 164, 8, 2, - 1, 250, 97, 4, 228, 209, 164, 8, 6, 1, 250, 81, 8, 2, 1, 250, 81, 8, 6, - 1, 207, 13, 247, 146, 4, 236, 96, 8, 2, 1, 207, 13, 247, 146, 4, 236, 96, - 8, 6, 1, 222, 126, 4, 105, 8, 2, 1, 222, 126, 4, 105, 8, 6, 1, 222, 126, - 4, 236, 250, 105, 8, 2, 1, 222, 126, 4, 236, 250, 105, 8, 6, 1, 222, 126, - 4, 201, 23, 24, 236, 250, 105, 8, 2, 1, 222, 126, 4, 201, 23, 24, 236, - 250, 105, 8, 6, 1, 247, 230, 170, 8, 2, 1, 247, 230, 170, 8, 6, 1, 220, - 119, 4, 136, 105, 8, 2, 1, 220, 119, 4, 136, 105, 8, 6, 1, 186, 4, 177, - 201, 23, 210, 245, 8, 2, 1, 186, 4, 177, 201, 23, 210, 245, 8, 6, 1, 186, - 4, 218, 236, 8, 2, 1, 186, 4, 218, 236, 8, 6, 1, 211, 76, 8, 2, 1, 211, - 76, 8, 6, 1, 210, 227, 4, 201, 23, 198, 211, 237, 42, 8, 2, 1, 210, 227, - 4, 201, 23, 198, 211, 237, 42, 8, 6, 1, 210, 227, 4, 232, 148, 8, 2, 1, - 210, 227, 4, 232, 148, 8, 6, 1, 210, 227, 4, 201, 177, 199, 210, 8, 2, 1, - 210, 227, 4, 201, 177, 199, 210, 8, 6, 1, 208, 98, 4, 201, 23, 198, 211, - 237, 42, 8, 2, 1, 208, 98, 4, 201, 23, 198, 211, 237, 42, 8, 6, 1, 208, - 98, 4, 236, 250, 105, 8, 2, 1, 208, 98, 4, 236, 250, 105, 8, 6, 1, 207, - 217, 206, 111, 8, 2, 1, 207, 217, 206, 111, 8, 6, 1, 206, 44, 206, 111, - 8, 2, 1, 206, 44, 206, 111, 8, 6, 1, 196, 9, 4, 236, 250, 105, 8, 2, 1, - 196, 9, 4, 236, 250, 105, 8, 6, 1, 193, 232, 8, 2, 1, 193, 232, 8, 6, 1, - 195, 30, 191, 166, 8, 2, 1, 195, 30, 191, 166, 8, 6, 1, 198, 229, 4, 105, - 8, 2, 1, 198, 229, 4, 105, 8, 6, 1, 198, 229, 4, 201, 23, 198, 211, 237, - 42, 8, 2, 1, 198, 229, 4, 201, 23, 198, 211, 237, 42, 8, 6, 1, 195, 139, - 8, 2, 1, 195, 139, 8, 6, 1, 233, 213, 8, 2, 1, 233, 213, 8, 6, 1, 223, - 40, 8, 2, 1, 223, 40, 8, 6, 1, 239, 9, 8, 2, 1, 239, 9, 59, 1, 196, 41, - 8, 2, 1, 235, 33, 8, 2, 1, 218, 186, 8, 2, 1, 215, 108, 8, 2, 1, 212, - 124, 8, 2, 1, 206, 43, 8, 1, 2, 6, 206, 43, 8, 2, 1, 197, 72, 8, 2, 1, - 196, 116, 8, 6, 1, 223, 87, 238, 80, 8, 2, 1, 223, 87, 238, 80, 8, 6, 1, - 223, 87, 233, 134, 8, 2, 1, 223, 87, 233, 134, 8, 6, 1, 223, 87, 232, 14, - 8, 6, 1, 152, 223, 87, 232, 14, 8, 2, 1, 152, 223, 87, 232, 14, 8, 6, 1, - 152, 170, 8, 2, 1, 152, 170, 8, 6, 1, 223, 87, 148, 8, 2, 1, 223, 87, - 148, 8, 6, 1, 223, 87, 206, 3, 8, 2, 1, 223, 87, 206, 3, 8, 6, 1, 223, - 87, 200, 39, 8, 2, 1, 223, 87, 200, 39, 59, 1, 131, 242, 210, 252, 8, 59, - 1, 242, 35, 59, 1, 203, 35, 234, 1, 57, 8, 6, 1, 205, 151, 8, 2, 1, 205, - 151, 8, 6, 1, 152, 230, 83, 8, 2, 1, 220, 119, 4, 207, 19, 228, 219, 24, - 248, 181, 8, 1, 202, 158, 236, 96, 8, 6, 1, 215, 48, 4, 237, 42, 8, 2, 1, - 215, 48, 4, 237, 42, 8, 6, 1, 247, 146, 4, 164, 8, 2, 1, 247, 146, 4, - 164, 8, 2, 1, 247, 146, 4, 210, 182, 106, 8, 2, 1, 230, 84, 4, 210, 182, - 106, 8, 6, 1, 78, 4, 232, 148, 8, 2, 1, 78, 4, 232, 148, 8, 6, 1, 233, - 135, 4, 105, 8, 2, 1, 233, 135, 4, 105, 8, 6, 1, 195, 12, 251, 229, 8, 2, - 1, 195, 12, 251, 229, 8, 6, 1, 195, 12, 211, 139, 8, 2, 1, 195, 12, 211, - 139, 8, 6, 1, 195, 12, 196, 148, 8, 2, 1, 195, 12, 196, 148, 8, 6, 1, - 232, 15, 4, 211, 159, 105, 8, 2, 1, 232, 15, 4, 211, 159, 105, 8, 6, 1, - 222, 126, 4, 211, 159, 105, 8, 2, 1, 222, 126, 4, 211, 159, 105, 8, 6, 1, - 215, 48, 4, 211, 159, 105, 8, 2, 1, 215, 48, 4, 211, 159, 105, 8, 6, 1, - 207, 217, 4, 211, 159, 105, 8, 2, 1, 207, 217, 4, 211, 159, 105, 8, 6, 1, - 206, 4, 4, 211, 159, 105, 8, 2, 1, 206, 4, 4, 211, 159, 105, 8, 6, 1, - 230, 84, 4, 106, 8, 6, 1, 207, 13, 211, 66, 73, 8, 6, 1, 27, 232, 14, 8, - 6, 1, 220, 119, 4, 248, 181, 8, 6, 1, 2, 6, 70, 8, 1, 2, 6, 208, 97, 8, - 6, 1, 152, 222, 125, 8, 6, 1, 152, 200, 39, 8, 6, 1, 223, 8, 4, 238, 165, - 8, 6, 1, 243, 47, 8, 6, 1, 248, 162, 8, 2, 1, 248, 162, 8, 6, 1, 211, 99, - 8, 2, 1, 211, 99, 8, 6, 1, 126, 4, 105, 8, 2, 1, 126, 4, 105, 8, 6, 1, - 230, 231, 65, 8, 2, 1, 230, 231, 65, 8, 6, 1, 230, 231, 70, 8, 2, 1, 230, - 231, 70, 8, 6, 1, 230, 231, 69, 8, 2, 1, 230, 231, 69, 8, 6, 1, 38, 209, - 42, 74, 8, 2, 1, 38, 209, 42, 74, 8, 6, 1, 251, 61, 193, 221, 8, 2, 1, - 251, 61, 193, 221, 8, 6, 1, 247, 146, 4, 210, 182, 106, 8, 6, 1, 206, 4, - 4, 106, 8, 6, 1, 191, 167, 4, 210, 182, 106, 8, 6, 1, 238, 81, 4, 203, - 35, 201, 23, 210, 245, 8, 2, 1, 238, 81, 4, 203, 35, 201, 23, 210, 245, - 8, 6, 1, 206, 4, 4, 203, 35, 201, 23, 210, 245, 8, 2, 1, 206, 4, 4, 203, - 35, 201, 23, 210, 245, 8, 6, 1, 242, 171, 223, 87, 232, 14, 8, 2, 1, 242, - 171, 223, 87, 232, 14, 8, 2, 1, 54, 198, 228, 8, 2, 1, 54, 192, 238, 8, - 6, 1, 82, 205, 74, 206, 3, 8, 2, 1, 82, 205, 74, 206, 3, 8, 6, 1, 202, - 190, 206, 3, 8, 2, 1, 202, 190, 206, 3, 59, 1, 6, 247, 145, 59, 1, 6, - 233, 134, 59, 1, 6, 208, 97, 8, 6, 1, 207, 13, 134, 230, 83, 8, 2, 1, - 207, 13, 134, 230, 83, 8, 234, 8, 1, 202, 201, 70, 59, 1, 6, 230, 84, 4, - 105, 59, 1, 2, 34, 211, 139, 8, 1, 2, 6, 152, 218, 147, 8, 234, 8, 1, - 207, 13, 233, 134, 8, 234, 8, 1, 207, 13, 210, 226, 8, 234, 8, 1, 223, - 65, 218, 147, 8, 234, 8, 1, 228, 44, 218, 242, 8, 234, 8, 1, 250, 220, - 218, 147, 200, 120, 214, 224, 1, 65, 200, 120, 214, 224, 1, 70, 200, 120, - 214, 224, 3, 235, 10, 200, 120, 214, 224, 1, 69, 200, 120, 214, 224, 1, - 73, 200, 120, 214, 224, 1, 74, 200, 120, 214, 224, 3, 229, 234, 200, 120, - 214, 224, 1, 221, 43, 200, 120, 214, 224, 1, 221, 159, 200, 120, 214, - 224, 1, 230, 223, 200, 120, 214, 224, 1, 231, 26, 200, 120, 214, 224, 3, - 251, 20, 200, 120, 214, 224, 1, 242, 51, 200, 120, 214, 224, 1, 243, 20, - 200, 120, 214, 224, 1, 222, 174, 200, 120, 214, 224, 1, 222, 219, 200, - 120, 214, 224, 1, 197, 105, 200, 120, 214, 224, 1, 197, 111, 200, 120, - 214, 224, 1, 237, 116, 200, 120, 214, 224, 1, 237, 125, 200, 120, 214, - 224, 1, 159, 200, 120, 214, 224, 1, 198, 236, 200, 120, 214, 224, 1, 236, - 129, 200, 120, 214, 224, 1, 237, 3, 200, 120, 214, 224, 1, 213, 30, 200, - 120, 214, 224, 1, 209, 65, 200, 120, 214, 224, 1, 209, 190, 200, 120, - 214, 224, 1, 248, 63, 200, 120, 214, 224, 1, 248, 144, 200, 120, 214, - 224, 1, 215, 251, 200, 120, 214, 224, 1, 206, 157, 200, 120, 214, 224, 1, - 219, 19, 200, 120, 214, 224, 1, 206, 90, 200, 120, 214, 224, 1, 202, 41, - 200, 120, 214, 224, 1, 228, 247, 200, 120, 214, 224, 18, 3, 65, 200, 120, - 214, 224, 18, 3, 70, 200, 120, 214, 224, 18, 3, 69, 200, 120, 214, 224, - 18, 3, 73, 200, 120, 214, 224, 18, 3, 211, 76, 200, 120, 214, 224, 209, - 56, 217, 36, 200, 120, 214, 224, 209, 56, 217, 35, 200, 120, 214, 224, - 209, 56, 217, 34, 200, 120, 214, 224, 209, 56, 217, 33, 200, 120, 214, - 224, 3, 251, 106, 229, 234, 185, 223, 118, 232, 80, 91, 208, 17, 185, - 223, 118, 232, 80, 91, 230, 37, 185, 223, 118, 232, 80, 115, 208, 15, - 185, 223, 118, 232, 80, 91, 202, 123, 185, 223, 118, 232, 80, 91, 234, - 116, 185, 223, 118, 232, 80, 115, 202, 120, 185, 223, 118, 208, 18, 77, - 185, 223, 118, 209, 99, 77, 185, 223, 118, 206, 31, 77, 185, 223, 118, - 208, 19, 77, 209, 215, 1, 157, 209, 215, 1, 221, 190, 209, 215, 1, 231, - 203, 209, 215, 1, 214, 54, 209, 215, 1, 247, 112, 209, 215, 1, 246, 209, - 209, 215, 1, 223, 4, 209, 215, 1, 212, 88, 209, 215, 1, 199, 247, 209, - 215, 1, 199, 44, 209, 215, 1, 237, 241, 209, 215, 1, 180, 209, 215, 1, - 168, 209, 215, 1, 209, 219, 209, 215, 1, 249, 103, 209, 215, 1, 172, 209, - 215, 1, 197, 164, 209, 215, 1, 197, 153, 209, 215, 1, 234, 247, 209, 215, - 1, 193, 187, 209, 215, 1, 191, 71, 209, 215, 1, 191, 123, 209, 215, 1, 2, - 65, 209, 215, 1, 169, 209, 215, 1, 166, 209, 215, 1, 171, 209, 215, 1, - 203, 160, 209, 215, 1, 189, 209, 215, 1, 144, 209, 215, 1, 65, 209, 215, - 1, 70, 209, 215, 1, 69, 209, 215, 1, 73, 209, 215, 1, 74, 209, 215, 1, - 208, 89, 209, 215, 1, 192, 220, 209, 215, 1, 233, 68, 209, 215, 1, 231, - 90, 209, 215, 1, 234, 145, 209, 215, 200, 234, 1, 193, 187, 209, 215, - 200, 234, 1, 169, 209, 215, 1, 197, 128, 209, 215, 1, 197, 116, 209, 215, - 1, 237, 146, 209, 215, 1, 213, 66, 209, 215, 1, 251, 106, 169, 209, 215, - 1, 195, 16, 203, 160, 209, 215, 1, 195, 17, 144, 209, 215, 1, 250, 150, - 233, 68, 209, 215, 200, 234, 1, 166, 209, 215, 200, 180, 1, 166, 209, - 215, 1, 247, 71, 209, 215, 202, 165, 229, 204, 77, 209, 215, 54, 229, - 204, 77, 209, 215, 87, 203, 152, 209, 215, 87, 54, 203, 152, 205, 106, 3, - 251, 20, 205, 106, 3, 195, 32, 205, 106, 1, 65, 205, 106, 1, 252, 154, - 205, 106, 1, 70, 205, 106, 1, 223, 170, 205, 106, 1, 69, 205, 106, 1, - 196, 26, 205, 106, 1, 121, 148, 205, 106, 1, 121, 206, 105, 205, 106, 1, - 121, 170, 205, 106, 1, 121, 219, 50, 205, 106, 1, 73, 205, 106, 1, 234, - 145, 205, 106, 1, 251, 184, 205, 106, 1, 74, 205, 106, 1, 211, 76, 205, - 106, 1, 250, 113, 205, 106, 1, 157, 205, 106, 1, 221, 190, 205, 106, 1, - 231, 203, 205, 106, 1, 231, 54, 205, 106, 1, 214, 54, 205, 106, 1, 247, - 112, 205, 106, 1, 246, 209, 205, 106, 1, 223, 4, 205, 106, 1, 222, 225, - 205, 106, 1, 212, 88, 205, 106, 1, 197, 128, 205, 106, 1, 197, 116, 205, - 106, 1, 237, 146, 205, 106, 1, 237, 130, 205, 106, 1, 213, 66, 205, 106, - 1, 199, 247, 205, 106, 1, 199, 44, 205, 106, 1, 237, 241, 205, 106, 1, - 237, 23, 205, 106, 1, 180, 205, 106, 1, 168, 205, 106, 1, 209, 219, 205, - 106, 1, 249, 103, 205, 106, 1, 248, 153, 205, 106, 1, 172, 205, 106, 1, - 169, 205, 106, 1, 166, 205, 106, 1, 171, 205, 106, 1, 195, 185, 205, 106, - 1, 203, 160, 205, 106, 1, 201, 170, 205, 106, 1, 189, 205, 106, 1, 144, - 205, 106, 1, 219, 49, 205, 106, 119, 3, 230, 56, 205, 106, 18, 3, 252, - 154, 205, 106, 18, 3, 70, 205, 106, 18, 3, 223, 170, 205, 106, 18, 3, 69, - 205, 106, 18, 3, 196, 26, 205, 106, 18, 3, 121, 148, 205, 106, 18, 3, - 121, 206, 105, 205, 106, 18, 3, 121, 170, 205, 106, 18, 3, 121, 219, 50, - 205, 106, 18, 3, 73, 205, 106, 18, 3, 234, 145, 205, 106, 18, 3, 251, - 184, 205, 106, 18, 3, 74, 205, 106, 18, 3, 211, 76, 205, 106, 18, 3, 250, - 113, 205, 106, 3, 195, 37, 205, 106, 3, 247, 71, 205, 106, 237, 193, 205, - 106, 54, 237, 193, 205, 106, 17, 191, 77, 205, 106, 17, 108, 205, 106, - 17, 109, 205, 106, 17, 139, 205, 106, 17, 137, 205, 106, 17, 153, 205, - 106, 17, 173, 205, 106, 17, 181, 205, 106, 17, 176, 205, 106, 17, 184, - 33, 104, 17, 191, 77, 33, 104, 17, 108, 33, 104, 17, 109, 33, 104, 17, - 139, 33, 104, 17, 137, 33, 104, 17, 153, 33, 104, 17, 173, 33, 104, 17, - 181, 33, 104, 17, 176, 33, 104, 17, 184, 33, 104, 1, 65, 33, 104, 1, 69, - 33, 104, 1, 157, 33, 104, 1, 180, 33, 104, 1, 168, 33, 104, 1, 166, 33, - 104, 1, 195, 66, 33, 104, 3, 250, 95, 104, 3, 201, 241, 247, 71, 104, 3, - 247, 72, 195, 37, 104, 3, 54, 247, 72, 195, 37, 104, 3, 247, 72, 109, - 104, 3, 247, 72, 139, 104, 3, 247, 72, 250, 95, 104, 3, 208, 127, 104, - 231, 167, 232, 218, 104, 247, 48, 104, 229, 195, 104, 3, 202, 205, 104, - 222, 252, 211, 102, 104, 1, 250, 81, 104, 18, 3, 250, 81, 222, 3, 219, - 123, 17, 191, 77, 222, 3, 219, 123, 17, 108, 222, 3, 219, 123, 17, 109, - 222, 3, 219, 123, 17, 139, 222, 3, 219, 123, 17, 137, 222, 3, 219, 123, - 17, 153, 222, 3, 219, 123, 17, 173, 222, 3, 219, 123, 17, 181, 222, 3, - 219, 123, 17, 176, 222, 3, 219, 123, 17, 184, 222, 3, 219, 123, 1, 157, - 222, 3, 219, 123, 1, 221, 190, 222, 3, 219, 123, 1, 231, 203, 222, 3, - 219, 123, 1, 214, 54, 222, 3, 219, 123, 1, 189, 222, 3, 219, 123, 1, 203, - 160, 222, 3, 219, 123, 1, 191, 123, 222, 3, 219, 123, 1, 212, 88, 222, 3, - 219, 123, 1, 199, 247, 222, 3, 219, 123, 1, 228, 133, 222, 3, 219, 123, - 1, 180, 222, 3, 219, 123, 1, 168, 222, 3, 219, 123, 1, 209, 219, 222, 3, - 219, 123, 1, 172, 222, 3, 219, 123, 1, 237, 241, 222, 3, 219, 123, 1, - 249, 103, 222, 3, 219, 123, 1, 166, 222, 3, 219, 123, 1, 169, 222, 3, - 219, 123, 1, 171, 222, 3, 219, 123, 1, 193, 187, 222, 3, 219, 123, 1, - 199, 44, 222, 3, 219, 123, 1, 144, 222, 3, 219, 123, 1, 195, 185, 222, 3, - 219, 123, 1, 247, 112, 222, 3, 219, 123, 1, 65, 222, 3, 219, 123, 1, 211, - 139, 222, 3, 219, 123, 1, 70, 222, 3, 219, 123, 1, 211, 76, 222, 3, 219, - 123, 18, 196, 148, 222, 3, 219, 123, 18, 73, 222, 3, 219, 123, 18, 69, - 222, 3, 219, 123, 18, 234, 145, 222, 3, 219, 123, 18, 74, 222, 3, 219, - 123, 163, 209, 82, 222, 3, 219, 123, 163, 247, 87, 222, 3, 219, 123, 163, - 247, 88, 209, 82, 222, 3, 219, 123, 3, 238, 100, 222, 3, 219, 123, 3, - 202, 225, 207, 62, 1, 157, 207, 62, 1, 231, 203, 207, 62, 1, 214, 54, - 207, 62, 1, 199, 247, 207, 62, 1, 237, 241, 207, 62, 1, 180, 207, 62, 1, - 168, 207, 62, 1, 249, 103, 207, 62, 1, 172, 207, 62, 1, 247, 112, 207, - 62, 1, 223, 4, 207, 62, 1, 212, 88, 207, 62, 1, 189, 207, 62, 1, 166, - 207, 62, 1, 171, 207, 62, 1, 169, 207, 62, 1, 193, 187, 207, 62, 1, 144, - 207, 62, 1, 216, 248, 207, 62, 1, 214, 33, 207, 62, 1, 214, 148, 207, 62, - 1, 212, 53, 207, 62, 1, 65, 207, 62, 18, 3, 70, 207, 62, 18, 3, 69, 207, - 62, 18, 3, 73, 207, 62, 18, 3, 251, 184, 207, 62, 18, 3, 74, 207, 62, 18, - 3, 250, 113, 207, 62, 18, 3, 233, 201, 207, 62, 18, 3, 234, 173, 207, 62, - 119, 3, 214, 56, 207, 62, 119, 3, 215, 47, 207, 62, 119, 3, 148, 207, 62, - 119, 3, 230, 83, 207, 62, 195, 37, 207, 62, 205, 49, 77, 30, 146, 198, - 159, 30, 146, 198, 158, 30, 146, 198, 156, 30, 146, 198, 161, 30, 146, - 206, 229, 30, 146, 206, 213, 30, 146, 206, 208, 30, 146, 206, 210, 30, - 146, 206, 226, 30, 146, 206, 219, 30, 146, 206, 212, 30, 146, 206, 231, - 30, 146, 206, 214, 30, 146, 206, 233, 30, 146, 206, 230, 30, 146, 216, - 55, 30, 146, 216, 46, 30, 146, 216, 49, 30, 146, 209, 145, 30, 146, 209, - 156, 30, 146, 209, 157, 30, 146, 201, 154, 30, 146, 223, 183, 30, 146, - 223, 190, 30, 146, 201, 165, 30, 146, 201, 152, 30, 146, 209, 199, 30, - 146, 229, 105, 30, 146, 201, 149, 222, 244, 3, 210, 133, 222, 244, 3, - 246, 247, 222, 244, 3, 219, 222, 222, 244, 3, 193, 69, 222, 244, 1, 65, - 222, 244, 1, 228, 44, 222, 7, 222, 244, 1, 70, 222, 244, 1, 223, 170, - 222, 244, 1, 69, 222, 244, 1, 210, 211, 246, 217, 222, 244, 1, 214, 55, - 219, 179, 222, 244, 1, 214, 55, 219, 180, 207, 126, 222, 244, 1, 73, 222, - 244, 1, 251, 184, 222, 244, 1, 74, 222, 244, 1, 157, 222, 244, 1, 222, - 115, 205, 119, 222, 244, 1, 222, 115, 215, 93, 222, 244, 1, 231, 203, - 222, 244, 1, 231, 204, 215, 93, 222, 244, 1, 214, 54, 222, 244, 1, 247, - 112, 222, 244, 1, 247, 113, 215, 93, 222, 244, 1, 223, 4, 222, 244, 1, - 212, 89, 215, 93, 222, 244, 1, 223, 5, 217, 95, 222, 244, 1, 212, 88, - 222, 244, 1, 197, 128, 222, 244, 1, 197, 129, 217, 95, 222, 244, 1, 237, - 146, 222, 244, 1, 237, 147, 217, 95, 222, 244, 1, 214, 249, 215, 93, 222, - 244, 1, 199, 247, 222, 244, 1, 199, 248, 215, 93, 222, 244, 1, 237, 241, - 222, 244, 1, 237, 242, 217, 95, 222, 244, 1, 180, 222, 244, 1, 168, 222, - 244, 1, 210, 211, 215, 93, 222, 244, 1, 249, 103, 222, 244, 1, 249, 104, - 215, 93, 222, 244, 1, 172, 222, 244, 1, 169, 222, 244, 1, 166, 222, 244, - 1, 207, 181, 251, 194, 222, 244, 1, 171, 222, 244, 1, 193, 187, 222, 244, - 1, 205, 202, 215, 93, 222, 244, 1, 205, 202, 217, 95, 222, 244, 1, 189, - 222, 244, 1, 144, 222, 244, 3, 246, 248, 199, 95, 222, 244, 18, 3, 199, - 170, 222, 244, 18, 3, 198, 79, 222, 244, 18, 3, 192, 250, 222, 244, 18, - 3, 192, 251, 216, 179, 222, 244, 18, 3, 200, 203, 222, 244, 18, 3, 200, - 204, 216, 166, 222, 244, 18, 3, 199, 196, 222, 244, 18, 3, 236, 185, 215, - 92, 222, 244, 18, 3, 210, 7, 222, 244, 119, 3, 221, 219, 222, 244, 119, - 3, 210, 22, 222, 244, 119, 3, 247, 97, 222, 244, 210, 147, 222, 244, 45, - 207, 35, 222, 244, 50, 207, 35, 222, 244, 210, 199, 251, 73, 222, 244, - 210, 199, 217, 116, 222, 244, 210, 199, 218, 190, 222, 244, 210, 199, - 193, 62, 222, 244, 210, 199, 210, 148, 222, 244, 210, 199, 219, 80, 222, - 244, 210, 199, 218, 183, 222, 244, 210, 199, 251, 240, 222, 244, 210, - 199, 251, 241, 251, 240, 222, 244, 210, 199, 209, 111, 222, 244, 152, - 210, 199, 209, 111, 222, 244, 210, 143, 222, 244, 17, 191, 77, 222, 244, - 17, 108, 222, 244, 17, 109, 222, 244, 17, 139, 222, 244, 17, 137, 222, - 244, 17, 153, 222, 244, 17, 173, 222, 244, 17, 181, 222, 244, 17, 176, - 222, 244, 17, 184, 222, 244, 210, 199, 198, 122, 197, 69, 222, 244, 210, - 199, 223, 36, 79, 1, 203, 134, 231, 54, 79, 1, 203, 134, 246, 209, 79, 1, - 203, 134, 222, 225, 79, 1, 203, 134, 213, 66, 79, 1, 203, 134, 248, 153, - 79, 3, 203, 134, 205, 103, 79, 59, 1, 203, 134, 207, 80, 79, 1, 53, 220, - 71, 212, 88, 79, 1, 53, 220, 71, 233, 68, 79, 1, 53, 220, 71, 231, 203, - 79, 1, 53, 220, 71, 231, 54, 79, 1, 53, 220, 71, 223, 4, 79, 1, 53, 220, - 71, 222, 225, 79, 1, 53, 220, 71, 237, 146, 79, 1, 53, 220, 71, 237, 130, - 79, 1, 53, 220, 71, 213, 66, 79, 53, 220, 71, 17, 191, 77, 79, 53, 220, - 71, 17, 108, 79, 53, 220, 71, 17, 109, 79, 53, 220, 71, 17, 139, 79, 53, - 220, 71, 17, 137, 79, 53, 220, 71, 17, 153, 79, 53, 220, 71, 17, 173, 79, - 53, 220, 71, 17, 181, 79, 53, 220, 71, 17, 176, 79, 53, 220, 71, 17, 184, - 79, 1, 53, 220, 71, 219, 49, 79, 1, 53, 220, 71, 237, 241, 79, 1, 53, - 220, 71, 237, 23, 79, 1, 53, 220, 71, 249, 103, 79, 1, 53, 220, 71, 248, - 153, 246, 202, 1, 65, 246, 202, 1, 70, 246, 202, 1, 69, 246, 202, 1, 73, - 246, 202, 1, 251, 184, 246, 202, 1, 74, 246, 202, 1, 157, 246, 202, 1, - 221, 190, 246, 202, 1, 231, 203, 246, 202, 1, 231, 54, 246, 202, 1, 213, - 219, 246, 202, 1, 214, 54, 246, 202, 1, 246, 209, 246, 202, 1, 243, 50, - 246, 202, 1, 223, 4, 246, 202, 1, 222, 225, 246, 202, 1, 213, 207, 246, - 202, 1, 213, 210, 246, 202, 1, 213, 208, 246, 202, 1, 199, 247, 246, 202, - 1, 199, 44, 246, 202, 1, 237, 241, 246, 202, 1, 237, 23, 246, 202, 1, - 212, 131, 246, 202, 1, 180, 246, 202, 1, 237, 146, 246, 202, 1, 168, 246, - 202, 1, 208, 243, 246, 202, 1, 209, 219, 246, 202, 1, 249, 103, 246, 202, - 1, 248, 153, 246, 202, 1, 215, 127, 246, 202, 1, 172, 246, 202, 1, 249, - 3, 246, 202, 1, 169, 246, 202, 1, 166, 246, 202, 1, 171, 246, 202, 1, - 195, 185, 246, 202, 1, 201, 170, 246, 202, 1, 189, 246, 202, 1, 144, 246, - 202, 18, 3, 252, 154, 246, 202, 18, 3, 70, 246, 202, 18, 3, 223, 170, - 246, 202, 18, 3, 234, 123, 246, 202, 18, 3, 69, 246, 202, 18, 3, 211, - 139, 246, 202, 18, 3, 74, 246, 202, 18, 3, 251, 184, 246, 202, 18, 3, - 250, 113, 246, 202, 18, 3, 196, 148, 246, 202, 119, 3, 169, 246, 202, - 119, 3, 166, 246, 202, 119, 3, 171, 246, 202, 119, 3, 193, 187, 246, 202, - 1, 52, 222, 125, 246, 202, 1, 52, 232, 14, 246, 202, 1, 52, 214, 56, 246, - 202, 119, 3, 52, 214, 56, 246, 202, 1, 52, 246, 211, 246, 202, 1, 52, - 200, 39, 246, 202, 1, 52, 215, 47, 246, 202, 1, 52, 210, 226, 246, 202, - 1, 52, 192, 159, 246, 202, 1, 52, 148, 246, 202, 1, 52, 170, 246, 202, 1, - 52, 201, 173, 246, 202, 119, 3, 52, 218, 147, 246, 202, 119, 3, 52, 230, - 83, 246, 202, 17, 191, 77, 246, 202, 17, 108, 246, 202, 17, 109, 246, - 202, 17, 139, 246, 202, 17, 137, 246, 202, 17, 153, 246, 202, 17, 173, - 246, 202, 17, 181, 246, 202, 17, 176, 246, 202, 17, 184, 246, 202, 208, - 145, 201, 212, 246, 202, 208, 145, 237, 193, 246, 202, 208, 145, 54, 237, - 193, 246, 202, 208, 145, 197, 221, 237, 193, 79, 1, 221, 181, 231, 203, - 79, 1, 221, 181, 247, 112, 79, 1, 221, 181, 246, 209, 79, 1, 221, 181, - 223, 4, 79, 1, 221, 181, 222, 225, 79, 1, 221, 181, 212, 88, 79, 1, 221, - 181, 197, 128, 79, 1, 221, 181, 197, 116, 79, 1, 221, 181, 237, 146, 79, - 1, 221, 181, 237, 130, 79, 1, 221, 181, 237, 23, 79, 1, 221, 181, 180, - 79, 1, 221, 181, 189, 79, 1, 221, 181, 144, 79, 1, 221, 181, 229, 145, - 79, 1, 221, 181, 233, 68, 79, 59, 1, 221, 181, 207, 80, 79, 1, 221, 181, - 192, 220, 79, 1, 221, 181, 191, 123, 79, 1, 221, 181, 166, 79, 219, 4, - 221, 181, 211, 166, 79, 219, 4, 221, 181, 208, 40, 79, 219, 4, 221, 181, - 229, 46, 79, 16, 251, 170, 233, 174, 79, 16, 251, 170, 108, 79, 16, 251, - 170, 109, 79, 1, 251, 170, 166, 79, 3, 210, 129, 222, 36, 198, 74, 79, 3, - 53, 220, 71, 198, 72, 79, 3, 53, 220, 71, 198, 69, 79, 1, 202, 233, 210, - 179, 246, 209, 79, 1, 202, 233, 210, 179, 203, 160, 53, 195, 56, 1, 131, - 221, 43, 53, 195, 56, 1, 136, 221, 43, 53, 195, 56, 1, 131, 221, 159, 53, - 195, 56, 1, 136, 221, 159, 53, 195, 56, 1, 131, 221, 168, 53, 195, 56, 1, - 136, 221, 168, 53, 195, 56, 1, 131, 230, 223, 53, 195, 56, 1, 136, 230, - 223, 53, 195, 56, 1, 131, 213, 235, 53, 195, 56, 1, 136, 213, 235, 53, - 195, 56, 1, 131, 242, 51, 53, 195, 56, 1, 136, 242, 51, 53, 195, 56, 1, - 131, 243, 20, 53, 195, 56, 1, 136, 243, 20, 53, 195, 56, 1, 131, 202, 41, - 53, 195, 56, 1, 136, 202, 41, 53, 195, 56, 1, 131, 212, 52, 53, 195, 56, - 1, 136, 212, 52, 53, 195, 56, 1, 131, 236, 129, 53, 195, 56, 1, 136, 236, - 129, 53, 195, 56, 1, 131, 159, 53, 195, 56, 1, 136, 159, 53, 195, 56, 1, - 131, 198, 236, 53, 195, 56, 1, 136, 198, 236, 53, 195, 56, 1, 131, 213, - 30, 53, 195, 56, 1, 136, 213, 30, 53, 195, 56, 1, 131, 248, 63, 53, 195, - 56, 1, 136, 248, 63, 53, 195, 56, 1, 131, 209, 65, 53, 195, 56, 1, 136, - 209, 65, 53, 195, 56, 1, 131, 209, 190, 53, 195, 56, 1, 136, 209, 190, - 53, 195, 56, 1, 131, 232, 135, 53, 195, 56, 1, 136, 232, 135, 53, 195, - 56, 1, 131, 215, 251, 53, 195, 56, 1, 136, 215, 251, 53, 195, 56, 1, 131, - 192, 12, 53, 195, 56, 1, 136, 192, 12, 53, 195, 56, 1, 131, 206, 157, 53, - 195, 56, 1, 136, 206, 157, 53, 195, 56, 1, 131, 219, 19, 53, 195, 56, 1, - 136, 219, 19, 53, 195, 56, 1, 131, 195, 21, 53, 195, 56, 1, 136, 195, 21, - 53, 195, 56, 1, 131, 228, 247, 53, 195, 56, 1, 136, 228, 247, 53, 195, - 56, 1, 131, 74, 53, 195, 56, 1, 136, 74, 53, 195, 56, 217, 92, 222, 57, - 53, 195, 56, 18, 252, 154, 53, 195, 56, 18, 70, 53, 195, 56, 18, 196, - 148, 53, 195, 56, 18, 69, 53, 195, 56, 18, 73, 53, 195, 56, 18, 74, 53, - 195, 56, 217, 92, 221, 162, 53, 195, 56, 18, 228, 5, 53, 195, 56, 18, - 196, 147, 53, 195, 56, 18, 196, 164, 53, 195, 56, 18, 250, 111, 53, 195, - 56, 18, 250, 81, 53, 195, 56, 18, 251, 81, 53, 195, 56, 18, 251, 98, 53, - 195, 56, 163, 217, 92, 234, 104, 53, 195, 56, 163, 217, 92, 212, 130, 53, - 195, 56, 163, 217, 92, 198, 236, 53, 195, 56, 163, 217, 92, 202, 13, 53, - 195, 56, 16, 221, 20, 53, 195, 56, 16, 212, 130, 53, 195, 56, 16, 205, - 147, 53, 195, 56, 16, 228, 248, 228, 234, 53, 195, 56, 16, 221, 31, 221, - 30, 216, 186, 216, 255, 1, 73, 216, 186, 216, 255, 1, 74, 216, 186, 216, - 255, 1, 246, 209, 216, 186, 216, 255, 1, 212, 88, 216, 186, 216, 255, 1, - 197, 128, 216, 186, 216, 255, 1, 197, 116, 216, 186, 216, 255, 1, 237, - 146, 216, 186, 216, 255, 1, 237, 130, 216, 186, 216, 255, 1, 213, 66, - 216, 186, 216, 255, 1, 203, 160, 216, 186, 216, 255, 1, 201, 170, 216, - 186, 216, 255, 18, 3, 223, 170, 216, 186, 216, 255, 18, 3, 196, 26, 216, - 186, 216, 255, 18, 3, 252, 118, 216, 186, 216, 255, 18, 3, 250, 113, 216, - 186, 216, 255, 18, 3, 252, 110, 216, 186, 216, 255, 243, 68, 216, 186, - 216, 255, 251, 190, 221, 149, 216, 186, 216, 255, 251, 49, 216, 186, 216, - 255, 5, 207, 41, 77, 216, 186, 216, 255, 193, 23, 207, 41, 77, 216, 186, - 216, 255, 18, 3, 195, 32, 216, 186, 216, 255, 195, 37, 36, 5, 197, 109, - 36, 5, 197, 112, 36, 5, 197, 115, 36, 5, 197, 113, 36, 5, 197, 114, 36, - 5, 197, 111, 36, 5, 237, 124, 36, 5, 237, 126, 36, 5, 237, 129, 36, 5, - 237, 127, 36, 5, 237, 128, 36, 5, 237, 125, 36, 5, 234, 234, 36, 5, 234, - 238, 36, 5, 234, 246, 36, 5, 234, 243, 36, 5, 234, 244, 36, 5, 234, 235, - 36, 5, 247, 8, 36, 5, 247, 2, 36, 5, 247, 4, 36, 5, 247, 7, 36, 5, 247, - 5, 36, 5, 247, 6, 36, 5, 247, 3, 36, 5, 249, 3, 36, 5, 248, 238, 36, 5, - 248, 250, 36, 5, 249, 2, 36, 5, 248, 253, 36, 5, 248, 254, 36, 5, 248, - 242, 8, 2, 1, 249, 32, 251, 109, 8, 2, 1, 41, 207, 11, 8, 2, 1, 248, 87, - 73, 8, 2, 1, 249, 32, 73, 8, 2, 1, 234, 227, 4, 232, 148, 8, 2, 1, 219, - 165, 233, 134, 8, 2, 1, 27, 232, 15, 4, 238, 165, 8, 2, 1, 220, 119, 4, - 223, 65, 219, 221, 206, 3, 8, 2, 1, 220, 119, 4, 54, 82, 198, 147, 8, 2, - 1, 220, 119, 4, 82, 206, 183, 8, 2, 1, 218, 148, 4, 238, 165, 8, 2, 1, - 215, 48, 4, 238, 165, 8, 2, 1, 234, 47, 4, 238, 165, 8, 2, 1, 248, 87, - 74, 8, 2, 1, 248, 87, 186, 4, 105, 8, 2, 1, 211, 66, 186, 4, 105, 8, 2, - 1, 223, 65, 211, 139, 8, 2, 1, 152, 211, 140, 4, 105, 8, 2, 1, 152, 211, - 140, 4, 228, 209, 105, 8, 2, 1, 152, 186, 211, 61, 8, 2, 1, 152, 186, - 211, 62, 4, 105, 8, 2, 1, 201, 63, 148, 8, 1, 2, 6, 207, 217, 4, 50, 219, - 188, 8, 2, 1, 207, 217, 193, 51, 229, 254, 8, 2, 1, 54, 148, 8, 2, 1, - 207, 217, 4, 238, 165, 8, 2, 1, 54, 207, 217, 4, 238, 165, 8, 2, 1, 27, - 148, 8, 2, 1, 27, 207, 217, 4, 206, 183, 8, 2, 1, 249, 22, 233, 226, 8, - 2, 1, 126, 4, 203, 35, 50, 219, 188, 8, 2, 1, 126, 249, 38, 4, 203, 35, - 50, 219, 188, 8, 2, 1, 196, 135, 8, 2, 1, 152, 196, 135, 8, 2, 1, 126, 4, - 45, 106, 8, 2, 1, 243, 47, 8, 2, 1, 243, 48, 4, 131, 50, 206, 183, 8, 2, - 1, 243, 48, 4, 131, 45, 204, 0, 8, 2, 1, 192, 236, 4, 131, 50, 206, 183, - 8, 2, 1, 192, 236, 4, 177, 45, 219, 188, 8, 2, 1, 192, 236, 4, 177, 45, - 219, 189, 24, 131, 50, 206, 183, 8, 2, 1, 192, 236, 4, 177, 45, 219, 189, - 4, 204, 0, 8, 2, 1, 192, 160, 4, 203, 35, 50, 219, 188, 59, 247, 245, 4, - 223, 65, 247, 244, 59, 1, 2, 229, 164, 59, 1, 2, 220, 119, 4, 223, 65, - 219, 221, 206, 3, 59, 1, 2, 220, 119, 4, 82, 198, 147, 59, 1, 2, 126, 4, - 45, 106, 8, 2, 1, 205, 169, 192, 95, 8, 2, 1, 223, 53, 73, 8, 2, 1, 211, - 66, 211, 139, 8, 2, 1, 196, 78, 8, 2, 1, 223, 65, 251, 109, 35, 1, 2, 6, - 211, 99, 8, 2, 1, 234, 249, 236, 214, 4, 207, 19, 106, 8, 2, 1, 197, 166, - 236, 214, 4, 207, 19, 106, 8, 2, 1, 152, 207, 217, 4, 82, 198, 147, 59, - 1, 2, 152, 193, 221, 59, 1, 45, 199, 223, 59, 1, 50, 199, 223, 101, 2, 1, - 65, 101, 2, 1, 73, 101, 2, 1, 70, 101, 2, 1, 74, 101, 2, 1, 69, 101, 2, - 1, 196, 8, 101, 2, 1, 231, 203, 101, 2, 1, 157, 101, 2, 1, 231, 128, 101, - 2, 1, 231, 16, 101, 2, 1, 230, 223, 101, 2, 1, 230, 146, 101, 2, 1, 230, - 105, 101, 2, 1, 144, 101, 2, 1, 229, 213, 101, 2, 1, 229, 126, 101, 2, 1, - 228, 247, 101, 2, 1, 228, 128, 101, 2, 1, 228, 95, 101, 2, 1, 171, 101, - 2, 1, 219, 214, 101, 2, 1, 219, 122, 101, 2, 1, 219, 19, 101, 2, 1, 218, - 203, 101, 2, 1, 218, 171, 101, 2, 1, 172, 101, 2, 1, 216, 213, 101, 2, 1, - 216, 81, 101, 2, 1, 215, 251, 101, 2, 1, 215, 139, 101, 2, 1, 180, 101, - 2, 1, 229, 15, 101, 2, 1, 214, 223, 101, 2, 1, 214, 107, 101, 2, 1, 213, - 205, 101, 2, 1, 213, 30, 101, 2, 1, 212, 165, 101, 2, 1, 212, 99, 101, 2, - 1, 208, 26, 101, 2, 1, 208, 11, 101, 2, 1, 208, 4, 101, 2, 1, 207, 250, - 101, 2, 1, 207, 239, 101, 2, 1, 207, 237, 101, 2, 1, 189, 101, 2, 1, 206, - 3, 101, 2, 1, 205, 63, 101, 2, 1, 202, 217, 101, 2, 1, 202, 41, 101, 2, - 1, 200, 255, 101, 2, 1, 200, 154, 101, 2, 1, 237, 241, 101, 2, 1, 199, - 247, 101, 2, 1, 237, 101, 101, 2, 1, 199, 140, 101, 2, 1, 236, 255, 101, - 2, 1, 198, 188, 101, 2, 1, 236, 129, 101, 2, 1, 235, 45, 101, 2, 1, 235, - 13, 101, 2, 1, 236, 141, 101, 2, 1, 198, 110, 101, 2, 1, 198, 109, 101, - 2, 1, 198, 98, 101, 2, 1, 198, 97, 101, 2, 1, 198, 96, 101, 2, 1, 198, - 95, 101, 2, 1, 197, 164, 101, 2, 1, 197, 157, 101, 2, 1, 197, 142, 101, - 2, 1, 197, 140, 101, 2, 1, 197, 136, 101, 2, 1, 197, 135, 101, 2, 1, 193, - 187, 101, 2, 1, 193, 123, 101, 2, 1, 193, 84, 101, 2, 1, 193, 48, 101, 2, - 1, 193, 0, 101, 2, 1, 192, 243, 101, 2, 1, 169, 216, 186, 216, 255, 1, - 221, 27, 216, 186, 216, 255, 1, 205, 147, 216, 186, 216, 255, 1, 220, 72, - 216, 186, 216, 255, 1, 216, 6, 216, 186, 216, 255, 1, 168, 216, 186, 216, - 255, 1, 180, 216, 186, 216, 255, 1, 243, 39, 216, 186, 216, 255, 1, 198, - 149, 216, 186, 216, 255, 1, 221, 152, 216, 186, 216, 255, 1, 213, 225, - 216, 186, 216, 255, 1, 198, 227, 216, 186, 216, 255, 1, 193, 170, 216, - 186, 216, 255, 1, 192, 106, 216, 186, 216, 255, 1, 228, 116, 216, 186, - 216, 255, 1, 196, 109, 216, 186, 216, 255, 1, 70, 216, 186, 216, 255, 1, - 209, 213, 216, 186, 216, 255, 1, 250, 125, 216, 186, 216, 255, 1, 230, - 215, 216, 186, 216, 255, 1, 222, 223, 216, 186, 216, 255, 1, 207, 151, - 216, 186, 216, 255, 1, 249, 103, 216, 186, 216, 255, 1, 222, 207, 216, - 186, 216, 255, 1, 236, 212, 216, 186, 216, 255, 1, 231, 23, 216, 186, - 216, 255, 1, 237, 1, 216, 186, 216, 255, 1, 248, 150, 216, 186, 216, 255, - 1, 221, 28, 218, 241, 216, 186, 216, 255, 1, 220, 73, 218, 241, 216, 186, - 216, 255, 1, 216, 7, 218, 241, 216, 186, 216, 255, 1, 210, 211, 218, 241, - 216, 186, 216, 255, 1, 214, 249, 218, 241, 216, 186, 216, 255, 1, 198, - 150, 218, 241, 216, 186, 216, 255, 1, 213, 226, 218, 241, 216, 186, 216, - 255, 1, 228, 44, 218, 241, 216, 186, 216, 255, 18, 3, 211, 91, 216, 186, - 216, 255, 18, 3, 223, 132, 216, 186, 216, 255, 18, 3, 251, 79, 216, 186, - 216, 255, 18, 3, 192, 69, 216, 186, 216, 255, 18, 3, 202, 1, 216, 186, - 216, 255, 18, 3, 196, 106, 216, 186, 216, 255, 18, 3, 243, 66, 216, 186, - 216, 255, 18, 3, 212, 114, 216, 186, 216, 255, 243, 67, 216, 186, 216, - 255, 218, 187, 223, 14, 216, 186, 216, 255, 250, 244, 223, 14, 216, 186, - 216, 255, 17, 191, 77, 216, 186, 216, 255, 17, 108, 216, 186, 216, 255, - 17, 109, 216, 186, 216, 255, 17, 139, 216, 186, 216, 255, 17, 137, 216, - 186, 216, 255, 17, 153, 216, 186, 216, 255, 17, 173, 216, 186, 216, 255, - 17, 181, 216, 186, 216, 255, 17, 176, 216, 186, 216, 255, 17, 184, 30, - 222, 147, 211, 246, 30, 222, 147, 211, 251, 30, 222, 147, 192, 5, 30, - 222, 147, 192, 4, 30, 222, 147, 192, 3, 30, 222, 147, 196, 214, 30, 222, - 147, 196, 218, 30, 222, 147, 191, 219, 30, 222, 147, 191, 215, 30, 222, - 147, 233, 200, 30, 222, 147, 233, 198, 30, 222, 147, 233, 199, 30, 222, - 147, 233, 196, 30, 222, 147, 228, 30, 30, 222, 147, 228, 29, 30, 222, - 147, 228, 27, 30, 222, 147, 228, 28, 30, 222, 147, 228, 33, 30, 222, 147, - 228, 26, 30, 222, 147, 228, 25, 30, 222, 147, 228, 35, 30, 222, 147, 250, - 230, 30, 222, 147, 250, 229, 30, 125, 213, 183, 30, 125, 213, 189, 30, - 125, 201, 151, 30, 125, 201, 150, 30, 125, 198, 158, 30, 125, 198, 156, - 30, 125, 198, 155, 30, 125, 198, 161, 30, 125, 198, 162, 30, 125, 198, - 154, 30, 125, 206, 213, 30, 125, 206, 228, 30, 125, 201, 157, 30, 125, - 206, 225, 30, 125, 206, 215, 30, 125, 206, 217, 30, 125, 206, 204, 30, - 125, 206, 205, 30, 125, 222, 42, 30, 125, 216, 54, 30, 125, 216, 48, 30, - 125, 201, 161, 30, 125, 216, 51, 30, 125, 216, 57, 30, 125, 209, 141, 30, - 125, 209, 150, 30, 125, 209, 154, 30, 125, 201, 159, 30, 125, 209, 144, - 30, 125, 209, 158, 30, 125, 209, 159, 30, 125, 202, 147, 30, 125, 202, - 150, 30, 125, 201, 155, 30, 125, 201, 153, 30, 125, 202, 145, 30, 125, - 202, 153, 30, 125, 202, 154, 30, 125, 202, 139, 30, 125, 202, 152, 30, - 125, 210, 137, 30, 125, 210, 138, 30, 125, 192, 53, 30, 125, 192, 56, 30, - 125, 242, 230, 30, 125, 242, 229, 30, 125, 201, 166, 30, 125, 209, 197, - 30, 125, 209, 196, 12, 15, 225, 161, 12, 15, 225, 160, 12, 15, 225, 159, - 12, 15, 225, 158, 12, 15, 225, 157, 12, 15, 225, 156, 12, 15, 225, 155, - 12, 15, 225, 154, 12, 15, 225, 153, 12, 15, 225, 152, 12, 15, 225, 151, - 12, 15, 225, 150, 12, 15, 225, 149, 12, 15, 225, 148, 12, 15, 225, 147, - 12, 15, 225, 146, 12, 15, 225, 145, 12, 15, 225, 144, 12, 15, 225, 143, - 12, 15, 225, 142, 12, 15, 225, 141, 12, 15, 225, 140, 12, 15, 225, 139, - 12, 15, 225, 138, 12, 15, 225, 137, 12, 15, 225, 136, 12, 15, 225, 135, - 12, 15, 225, 134, 12, 15, 225, 133, 12, 15, 225, 132, 12, 15, 225, 131, - 12, 15, 225, 130, 12, 15, 225, 129, 12, 15, 225, 128, 12, 15, 225, 127, - 12, 15, 225, 126, 12, 15, 225, 125, 12, 15, 225, 124, 12, 15, 225, 123, - 12, 15, 225, 122, 12, 15, 225, 121, 12, 15, 225, 120, 12, 15, 225, 119, - 12, 15, 225, 118, 12, 15, 225, 117, 12, 15, 225, 116, 12, 15, 225, 115, - 12, 15, 225, 114, 12, 15, 225, 113, 12, 15, 225, 112, 12, 15, 225, 111, - 12, 15, 225, 110, 12, 15, 225, 109, 12, 15, 225, 108, 12, 15, 225, 107, - 12, 15, 225, 106, 12, 15, 225, 105, 12, 15, 225, 104, 12, 15, 225, 103, - 12, 15, 225, 102, 12, 15, 225, 101, 12, 15, 225, 100, 12, 15, 225, 99, - 12, 15, 225, 98, 12, 15, 225, 97, 12, 15, 225, 96, 12, 15, 225, 95, 12, - 15, 225, 94, 12, 15, 225, 93, 12, 15, 225, 92, 12, 15, 225, 91, 12, 15, - 225, 90, 12, 15, 225, 89, 12, 15, 225, 88, 12, 15, 225, 87, 12, 15, 225, - 86, 12, 15, 225, 85, 12, 15, 225, 84, 12, 15, 225, 83, 12, 15, 225, 82, - 12, 15, 225, 81, 12, 15, 225, 80, 12, 15, 225, 79, 12, 15, 225, 78, 12, - 15, 225, 77, 12, 15, 225, 76, 12, 15, 225, 75, 12, 15, 225, 74, 12, 15, - 225, 73, 12, 15, 225, 72, 12, 15, 225, 71, 12, 15, 225, 70, 12, 15, 225, - 69, 12, 15, 225, 68, 12, 15, 225, 67, 12, 15, 225, 66, 12, 15, 225, 65, - 12, 15, 225, 64, 12, 15, 225, 63, 12, 15, 225, 62, 12, 15, 225, 61, 12, - 15, 225, 60, 12, 15, 225, 59, 12, 15, 225, 58, 12, 15, 225, 57, 12, 15, - 225, 56, 12, 15, 225, 55, 12, 15, 225, 54, 12, 15, 225, 53, 12, 15, 225, - 52, 12, 15, 225, 51, 12, 15, 225, 50, 12, 15, 225, 49, 12, 15, 225, 48, - 12, 15, 225, 47, 12, 15, 225, 46, 12, 15, 225, 45, 12, 15, 225, 44, 12, - 15, 225, 43, 12, 15, 225, 42, 12, 15, 225, 41, 12, 15, 225, 40, 12, 15, - 225, 39, 12, 15, 225, 38, 12, 15, 225, 37, 12, 15, 225, 36, 12, 15, 225, - 35, 12, 15, 225, 34, 12, 15, 225, 33, 12, 15, 225, 32, 12, 15, 225, 31, - 12, 15, 225, 30, 12, 15, 225, 29, 12, 15, 225, 28, 12, 15, 225, 27, 12, - 15, 225, 26, 12, 15, 225, 25, 12, 15, 225, 24, 12, 15, 225, 23, 12, 15, - 225, 22, 12, 15, 225, 21, 12, 15, 225, 20, 12, 15, 225, 19, 12, 15, 225, - 18, 12, 15, 225, 17, 12, 15, 225, 16, 12, 15, 225, 15, 12, 15, 225, 14, - 12, 15, 225, 13, 12, 15, 225, 12, 12, 15, 225, 11, 12, 15, 225, 10, 12, - 15, 225, 9, 12, 15, 225, 8, 12, 15, 225, 7, 12, 15, 225, 6, 12, 15, 225, - 5, 12, 15, 225, 4, 12, 15, 225, 3, 12, 15, 225, 2, 12, 15, 225, 1, 12, - 15, 225, 0, 12, 15, 224, 255, 12, 15, 224, 254, 12, 15, 224, 253, 12, 15, - 224, 252, 12, 15, 224, 251, 12, 15, 224, 250, 12, 15, 224, 249, 12, 15, - 224, 248, 12, 15, 224, 247, 12, 15, 224, 246, 12, 15, 224, 245, 12, 15, - 224, 244, 12, 15, 224, 243, 12, 15, 224, 242, 12, 15, 224, 241, 12, 15, - 224, 240, 12, 15, 224, 239, 12, 15, 224, 238, 12, 15, 224, 237, 12, 15, - 224, 236, 12, 15, 224, 235, 12, 15, 224, 234, 12, 15, 224, 233, 12, 15, - 224, 232, 12, 15, 224, 231, 12, 15, 224, 230, 12, 15, 224, 229, 12, 15, - 224, 228, 12, 15, 224, 227, 12, 15, 224, 226, 12, 15, 224, 225, 12, 15, - 224, 224, 12, 15, 224, 223, 12, 15, 224, 222, 12, 15, 224, 221, 12, 15, - 224, 220, 12, 15, 224, 219, 12, 15, 224, 218, 12, 15, 224, 217, 12, 15, - 224, 216, 12, 15, 224, 215, 12, 15, 224, 214, 12, 15, 224, 213, 12, 15, - 224, 212, 12, 15, 224, 211, 12, 15, 224, 210, 12, 15, 224, 209, 12, 15, - 224, 208, 12, 15, 224, 207, 12, 15, 224, 206, 12, 15, 224, 205, 12, 15, - 224, 204, 12, 15, 224, 203, 12, 15, 224, 202, 12, 15, 224, 201, 12, 15, - 224, 200, 12, 15, 224, 199, 12, 15, 224, 198, 12, 15, 224, 197, 12, 15, - 224, 196, 12, 15, 224, 195, 12, 15, 224, 194, 12, 15, 224, 193, 12, 15, - 224, 192, 12, 15, 224, 191, 12, 15, 224, 190, 12, 15, 224, 189, 12, 15, - 224, 188, 12, 15, 224, 187, 12, 15, 224, 186, 12, 15, 224, 185, 12, 15, - 224, 184, 12, 15, 224, 183, 12, 15, 224, 182, 12, 15, 224, 181, 12, 15, - 224, 180, 12, 15, 224, 179, 12, 15, 224, 178, 12, 15, 224, 177, 12, 15, - 224, 176, 12, 15, 224, 175, 12, 15, 224, 174, 12, 15, 224, 173, 12, 15, - 224, 172, 12, 15, 224, 171, 12, 15, 224, 170, 12, 15, 224, 169, 12, 15, - 224, 168, 12, 15, 224, 167, 12, 15, 224, 166, 12, 15, 224, 165, 12, 15, - 224, 164, 12, 15, 224, 163, 12, 15, 224, 162, 12, 15, 224, 161, 12, 15, - 224, 160, 12, 15, 224, 159, 12, 15, 224, 158, 12, 15, 224, 157, 12, 15, - 224, 156, 12, 15, 224, 155, 12, 15, 224, 154, 12, 15, 224, 153, 12, 15, - 224, 152, 12, 15, 224, 151, 12, 15, 224, 150, 12, 15, 224, 149, 12, 15, - 224, 148, 12, 15, 224, 147, 12, 15, 224, 146, 12, 15, 224, 145, 12, 15, - 224, 144, 12, 15, 224, 143, 12, 15, 224, 142, 12, 15, 224, 141, 12, 15, - 224, 140, 12, 15, 224, 139, 12, 15, 224, 138, 12, 15, 224, 137, 12, 15, - 224, 136, 12, 15, 224, 135, 12, 15, 224, 134, 12, 15, 224, 133, 12, 15, - 224, 132, 12, 15, 224, 131, 12, 15, 224, 130, 12, 15, 224, 129, 12, 15, - 224, 128, 12, 15, 224, 127, 12, 15, 224, 126, 12, 15, 224, 125, 12, 15, - 224, 124, 12, 15, 224, 123, 12, 15, 224, 122, 12, 15, 224, 121, 12, 15, - 224, 120, 12, 15, 224, 119, 12, 15, 224, 118, 12, 15, 224, 117, 12, 15, - 224, 116, 12, 15, 224, 115, 12, 15, 224, 114, 12, 15, 224, 113, 12, 15, - 224, 112, 12, 15, 224, 111, 12, 15, 224, 110, 12, 15, 224, 109, 12, 15, - 224, 108, 12, 15, 224, 107, 12, 15, 224, 106, 12, 15, 224, 105, 12, 15, - 224, 104, 12, 15, 224, 103, 12, 15, 224, 102, 12, 15, 224, 101, 12, 15, - 224, 100, 12, 15, 224, 99, 12, 15, 224, 98, 12, 15, 224, 97, 12, 15, 224, - 96, 12, 15, 224, 95, 12, 15, 224, 94, 12, 15, 224, 93, 12, 15, 224, 92, - 12, 15, 224, 91, 12, 15, 224, 90, 12, 15, 224, 89, 12, 15, 224, 88, 12, - 15, 224, 87, 12, 15, 224, 86, 12, 15, 224, 85, 12, 15, 224, 84, 12, 15, - 224, 83, 12, 15, 224, 82, 12, 15, 224, 81, 12, 15, 224, 80, 12, 15, 224, - 79, 12, 15, 224, 78, 12, 15, 224, 77, 12, 15, 224, 76, 12, 15, 224, 75, - 12, 15, 224, 74, 12, 15, 224, 73, 12, 15, 224, 72, 12, 15, 224, 71, 12, - 15, 224, 70, 12, 15, 224, 69, 12, 15, 224, 68, 12, 15, 224, 67, 12, 15, - 224, 66, 12, 15, 224, 65, 12, 15, 224, 64, 12, 15, 224, 63, 12, 15, 224, - 62, 12, 15, 224, 61, 12, 15, 224, 60, 12, 15, 224, 59, 12, 15, 224, 58, - 12, 15, 224, 57, 12, 15, 224, 56, 12, 15, 224, 55, 12, 15, 224, 54, 12, - 15, 224, 53, 12, 15, 224, 52, 12, 15, 224, 51, 12, 15, 224, 50, 12, 15, - 224, 49, 12, 15, 224, 48, 12, 15, 224, 47, 12, 15, 224, 46, 12, 15, 224, - 45, 12, 15, 224, 44, 12, 15, 224, 43, 12, 15, 224, 42, 12, 15, 224, 41, - 12, 15, 224, 40, 12, 15, 224, 39, 12, 15, 224, 38, 12, 15, 224, 37, 12, - 15, 224, 36, 12, 15, 224, 35, 12, 15, 224, 34, 12, 15, 224, 33, 12, 15, - 224, 32, 12, 15, 224, 31, 12, 15, 224, 30, 12, 15, 224, 29, 12, 15, 224, - 28, 12, 15, 224, 27, 12, 15, 224, 26, 12, 15, 224, 25, 12, 15, 224, 24, - 12, 15, 224, 23, 12, 15, 224, 22, 12, 15, 224, 21, 12, 15, 224, 20, 12, - 15, 224, 19, 12, 15, 224, 18, 12, 15, 224, 17, 12, 15, 224, 16, 12, 15, - 224, 15, 12, 15, 224, 14, 12, 15, 224, 13, 12, 15, 224, 12, 12, 15, 224, - 11, 12, 15, 224, 10, 12, 15, 224, 9, 12, 15, 224, 8, 12, 15, 224, 7, 12, - 15, 224, 6, 12, 15, 224, 5, 12, 15, 224, 4, 12, 15, 224, 3, 12, 15, 224, - 2, 12, 15, 224, 1, 12, 15, 224, 0, 12, 15, 223, 255, 12, 15, 223, 254, - 12, 15, 223, 253, 12, 15, 223, 252, 12, 15, 223, 251, 12, 15, 223, 250, - 12, 15, 223, 249, 12, 15, 223, 248, 12, 15, 223, 247, 12, 15, 223, 246, - 12, 15, 223, 245, 12, 15, 223, 244, 12, 15, 223, 243, 12, 15, 223, 242, - 12, 15, 223, 241, 12, 15, 223, 240, 12, 15, 223, 239, 12, 15, 223, 238, - 12, 15, 223, 237, 12, 15, 223, 236, 12, 15, 223, 235, 12, 15, 223, 234, - 12, 15, 223, 233, 12, 15, 223, 232, 12, 15, 223, 231, 12, 15, 223, 230, - 12, 15, 223, 229, 12, 15, 223, 228, 12, 15, 223, 227, 12, 15, 223, 226, - 12, 15, 223, 225, 12, 15, 223, 224, 12, 15, 223, 223, 12, 15, 223, 222, - 12, 15, 223, 221, 12, 15, 223, 220, 12, 15, 223, 219, 12, 15, 223, 218, - 12, 15, 223, 217, 12, 15, 223, 216, 12, 15, 223, 215, 12, 15, 223, 214, - 12, 15, 223, 213, 12, 15, 223, 212, 12, 15, 223, 211, 12, 15, 223, 210, - 12, 15, 223, 209, 12, 15, 223, 208, 12, 15, 223, 207, 12, 15, 223, 206, - 12, 15, 223, 205, 12, 15, 223, 204, 12, 15, 223, 203, 12, 15, 223, 202, - 8, 2, 34, 232, 242, 8, 2, 34, 232, 238, 8, 2, 34, 232, 180, 8, 2, 34, - 232, 241, 8, 2, 34, 232, 240, 8, 2, 34, 177, 206, 4, 200, 39, 8, 2, 34, - 201, 113, 250, 199, 2, 34, 216, 168, 212, 240, 250, 199, 2, 34, 216, 168, - 234, 151, 250, 199, 2, 34, 216, 168, 223, 103, 250, 199, 2, 34, 195, 72, - 212, 240, 250, 199, 2, 34, 216, 168, 192, 212, 135, 1, 191, 251, 4, 229, - 87, 135, 209, 55, 222, 154, 195, 163, 135, 34, 192, 31, 191, 251, 191, - 251, 210, 78, 135, 1, 251, 101, 250, 76, 135, 1, 193, 76, 251, 141, 135, - 1, 193, 76, 237, 206, 135, 1, 193, 76, 229, 213, 135, 1, 193, 76, 222, - 79, 135, 1, 193, 76, 220, 3, 135, 1, 193, 76, 52, 216, 174, 135, 1, 193, - 76, 207, 33, 135, 1, 193, 76, 199, 157, 135, 1, 251, 101, 107, 57, 135, - 1, 203, 65, 4, 203, 65, 236, 96, 135, 1, 203, 65, 4, 202, 170, 236, 96, - 135, 1, 203, 65, 4, 237, 226, 24, 203, 65, 236, 96, 135, 1, 203, 65, 4, - 237, 226, 24, 202, 170, 236, 96, 135, 1, 130, 4, 210, 78, 135, 1, 130, 4, - 208, 77, 135, 1, 130, 4, 217, 50, 135, 1, 248, 165, 4, 237, 225, 135, 1, - 231, 2, 4, 237, 225, 135, 1, 237, 207, 4, 237, 225, 135, 1, 229, 214, 4, - 217, 50, 135, 1, 195, 156, 4, 237, 225, 135, 1, 191, 92, 4, 237, 225, - 135, 1, 199, 69, 4, 237, 225, 135, 1, 191, 251, 4, 237, 225, 135, 1, 52, - 222, 80, 4, 237, 225, 135, 1, 222, 80, 4, 237, 225, 135, 1, 220, 4, 4, - 237, 225, 135, 1, 216, 175, 4, 237, 225, 135, 1, 212, 118, 4, 237, 225, - 135, 1, 205, 144, 4, 237, 225, 135, 1, 52, 210, 54, 4, 237, 225, 135, 1, - 210, 54, 4, 237, 225, 135, 1, 197, 160, 4, 237, 225, 135, 1, 208, 37, 4, - 237, 225, 135, 1, 207, 34, 4, 237, 225, 135, 1, 203, 65, 4, 237, 225, - 135, 1, 199, 158, 4, 237, 225, 135, 1, 195, 156, 4, 228, 231, 135, 1, - 248, 165, 4, 207, 156, 135, 1, 222, 80, 4, 207, 156, 135, 1, 210, 54, 4, - 207, 156, 135, 34, 130, 220, 3, 9, 1, 130, 193, 149, 76, 20, 9, 1, 130, - 193, 149, 52, 20, 9, 1, 248, 206, 76, 20, 9, 1, 248, 206, 52, 20, 9, 1, - 248, 206, 89, 20, 9, 1, 248, 206, 216, 198, 20, 9, 1, 210, 33, 76, 20, 9, - 1, 210, 33, 52, 20, 9, 1, 210, 33, 89, 20, 9, 1, 210, 33, 216, 198, 20, - 9, 1, 248, 194, 76, 20, 9, 1, 248, 194, 52, 20, 9, 1, 248, 194, 89, 20, - 9, 1, 248, 194, 216, 198, 20, 9, 1, 197, 119, 76, 20, 9, 1, 197, 119, 52, - 20, 9, 1, 197, 119, 89, 20, 9, 1, 197, 119, 216, 198, 20, 9, 1, 199, 108, - 76, 20, 9, 1, 199, 108, 52, 20, 9, 1, 199, 108, 89, 20, 9, 1, 199, 108, - 216, 198, 20, 9, 1, 197, 121, 76, 20, 9, 1, 197, 121, 52, 20, 9, 1, 197, - 121, 89, 20, 9, 1, 197, 121, 216, 198, 20, 9, 1, 195, 144, 76, 20, 9, 1, - 195, 144, 52, 20, 9, 1, 195, 144, 89, 20, 9, 1, 195, 144, 216, 198, 20, - 9, 1, 210, 31, 76, 20, 9, 1, 210, 31, 52, 20, 9, 1, 210, 31, 89, 20, 9, - 1, 210, 31, 216, 198, 20, 9, 1, 234, 254, 76, 20, 9, 1, 234, 254, 52, 20, - 9, 1, 234, 254, 89, 20, 9, 1, 234, 254, 216, 198, 20, 9, 1, 212, 75, 76, - 20, 9, 1, 212, 75, 52, 20, 9, 1, 212, 75, 89, 20, 9, 1, 212, 75, 216, - 198, 20, 9, 1, 199, 145, 76, 20, 9, 1, 199, 145, 52, 20, 9, 1, 199, 145, - 89, 20, 9, 1, 199, 145, 216, 198, 20, 9, 1, 199, 143, 76, 20, 9, 1, 199, - 143, 52, 20, 9, 1, 199, 143, 89, 20, 9, 1, 199, 143, 216, 198, 20, 9, 1, - 237, 144, 76, 20, 9, 1, 237, 144, 52, 20, 9, 1, 237, 220, 76, 20, 9, 1, - 237, 220, 52, 20, 9, 1, 235, 35, 76, 20, 9, 1, 235, 35, 52, 20, 9, 1, - 237, 142, 76, 20, 9, 1, 237, 142, 52, 20, 9, 1, 222, 232, 76, 20, 9, 1, - 222, 232, 52, 20, 9, 1, 206, 97, 76, 20, 9, 1, 206, 97, 52, 20, 9, 1, - 221, 236, 76, 20, 9, 1, 221, 236, 52, 20, 9, 1, 221, 236, 89, 20, 9, 1, - 221, 236, 216, 198, 20, 9, 1, 231, 191, 76, 20, 9, 1, 231, 191, 52, 20, - 9, 1, 231, 191, 89, 20, 9, 1, 231, 191, 216, 198, 20, 9, 1, 230, 134, 76, - 20, 9, 1, 230, 134, 52, 20, 9, 1, 230, 134, 89, 20, 9, 1, 230, 134, 216, - 198, 20, 9, 1, 213, 234, 76, 20, 9, 1, 213, 234, 52, 20, 9, 1, 213, 234, - 89, 20, 9, 1, 213, 234, 216, 198, 20, 9, 1, 213, 12, 231, 21, 76, 20, 9, - 1, 213, 12, 231, 21, 52, 20, 9, 1, 206, 161, 76, 20, 9, 1, 206, 161, 52, - 20, 9, 1, 206, 161, 89, 20, 9, 1, 206, 161, 216, 198, 20, 9, 1, 229, 179, - 4, 99, 95, 76, 20, 9, 1, 229, 179, 4, 99, 95, 52, 20, 9, 1, 229, 179, - 230, 221, 76, 20, 9, 1, 229, 179, 230, 221, 52, 20, 9, 1, 229, 179, 230, - 221, 89, 20, 9, 1, 229, 179, 230, 221, 216, 198, 20, 9, 1, 229, 179, 236, - 126, 76, 20, 9, 1, 229, 179, 236, 126, 52, 20, 9, 1, 229, 179, 236, 126, - 89, 20, 9, 1, 229, 179, 236, 126, 216, 198, 20, 9, 1, 99, 249, 31, 76, - 20, 9, 1, 99, 249, 31, 52, 20, 9, 1, 99, 249, 31, 4, 230, 25, 95, 76, 20, - 9, 1, 99, 249, 31, 4, 230, 25, 95, 52, 20, 9, 16, 75, 56, 9, 16, 75, 60, - 9, 16, 103, 183, 56, 9, 16, 103, 183, 60, 9, 16, 115, 183, 56, 9, 16, - 115, 183, 60, 9, 16, 115, 183, 209, 51, 235, 75, 56, 9, 16, 115, 183, - 209, 51, 235, 75, 60, 9, 16, 232, 90, 183, 56, 9, 16, 232, 90, 183, 60, - 9, 16, 54, 81, 249, 38, 60, 9, 16, 103, 183, 195, 82, 56, 9, 16, 103, - 183, 195, 82, 60, 9, 16, 206, 183, 9, 16, 2, 199, 215, 56, 9, 16, 2, 199, - 215, 60, 9, 16, 193, 149, 56, 9, 1, 214, 57, 76, 20, 9, 1, 214, 57, 52, - 20, 9, 1, 214, 57, 89, 20, 9, 1, 214, 57, 216, 198, 20, 9, 1, 126, 76, - 20, 9, 1, 126, 52, 20, 9, 1, 211, 140, 76, 20, 9, 1, 211, 140, 52, 20, 9, - 1, 191, 226, 76, 20, 9, 1, 191, 226, 52, 20, 9, 1, 126, 4, 230, 25, 95, - 76, 20, 9, 1, 195, 151, 76, 20, 9, 1, 195, 151, 52, 20, 9, 1, 221, 108, - 211, 140, 76, 20, 9, 1, 221, 108, 211, 140, 52, 20, 9, 1, 221, 108, 191, - 226, 76, 20, 9, 1, 221, 108, 191, 226, 52, 20, 9, 1, 234, 227, 76, 20, 9, - 1, 234, 227, 52, 20, 9, 1, 234, 227, 89, 20, 9, 1, 234, 227, 216, 198, - 20, 9, 1, 196, 133, 222, 1, 221, 108, 130, 217, 80, 89, 20, 9, 1, 196, - 133, 222, 1, 221, 108, 130, 217, 80, 216, 198, 20, 9, 34, 99, 4, 230, 25, - 95, 4, 130, 76, 20, 9, 34, 99, 4, 230, 25, 95, 4, 130, 52, 20, 9, 34, 99, - 4, 230, 25, 95, 4, 251, 230, 76, 20, 9, 34, 99, 4, 230, 25, 95, 4, 251, - 230, 52, 20, 9, 34, 99, 4, 230, 25, 95, 4, 193, 132, 76, 20, 9, 34, 99, - 4, 230, 25, 95, 4, 193, 132, 52, 20, 9, 34, 99, 4, 230, 25, 95, 4, 126, - 76, 20, 9, 34, 99, 4, 230, 25, 95, 4, 126, 52, 20, 9, 34, 99, 4, 230, 25, - 95, 4, 211, 140, 76, 20, 9, 34, 99, 4, 230, 25, 95, 4, 211, 140, 52, 20, - 9, 34, 99, 4, 230, 25, 95, 4, 191, 226, 76, 20, 9, 34, 99, 4, 230, 25, - 95, 4, 191, 226, 52, 20, 9, 34, 99, 4, 230, 25, 95, 4, 234, 227, 76, 20, - 9, 34, 99, 4, 230, 25, 95, 4, 234, 227, 52, 20, 9, 34, 99, 4, 230, 25, - 95, 4, 234, 227, 89, 20, 9, 34, 196, 133, 221, 108, 99, 4, 230, 25, 95, - 4, 130, 217, 80, 76, 20, 9, 34, 196, 133, 221, 108, 99, 4, 230, 25, 95, - 4, 130, 217, 80, 52, 20, 9, 34, 196, 133, 221, 108, 99, 4, 230, 25, 95, - 4, 130, 217, 80, 89, 20, 9, 1, 233, 33, 99, 76, 20, 9, 1, 233, 33, 99, - 52, 20, 9, 1, 233, 33, 99, 89, 20, 9, 1, 233, 33, 99, 216, 198, 20, 9, - 34, 99, 4, 230, 25, 95, 4, 222, 235, 76, 20, 9, 34, 99, 4, 230, 25, 95, - 4, 179, 76, 20, 9, 34, 99, 4, 230, 25, 95, 4, 92, 76, 20, 9, 34, 99, 4, - 230, 25, 95, 4, 130, 217, 80, 76, 20, 9, 34, 99, 4, 230, 25, 95, 4, 99, - 76, 20, 9, 34, 248, 196, 4, 222, 235, 76, 20, 9, 34, 248, 196, 4, 179, - 76, 20, 9, 34, 248, 196, 4, 221, 186, 76, 20, 9, 34, 248, 196, 4, 92, 76, - 20, 9, 34, 248, 196, 4, 130, 217, 80, 76, 20, 9, 34, 248, 196, 4, 99, 76, - 20, 9, 34, 199, 110, 4, 222, 235, 76, 20, 9, 34, 199, 110, 4, 179, 76, - 20, 9, 34, 199, 110, 4, 221, 186, 76, 20, 9, 34, 199, 110, 4, 92, 76, 20, - 9, 34, 199, 110, 4, 130, 217, 80, 76, 20, 9, 34, 199, 110, 4, 99, 76, 20, - 9, 34, 199, 25, 4, 222, 235, 76, 20, 9, 34, 199, 25, 4, 92, 76, 20, 9, - 34, 199, 25, 4, 130, 217, 80, 76, 20, 9, 34, 199, 25, 4, 99, 76, 20, 9, - 34, 222, 235, 4, 179, 76, 20, 9, 34, 222, 235, 4, 92, 76, 20, 9, 34, 179, - 4, 222, 235, 76, 20, 9, 34, 179, 4, 92, 76, 20, 9, 34, 221, 186, 4, 222, - 235, 76, 20, 9, 34, 221, 186, 4, 179, 76, 20, 9, 34, 221, 186, 4, 92, 76, - 20, 9, 34, 205, 42, 4, 222, 235, 76, 20, 9, 34, 205, 42, 4, 179, 76, 20, - 9, 34, 205, 42, 4, 221, 186, 76, 20, 9, 34, 205, 42, 4, 92, 76, 20, 9, - 34, 205, 188, 4, 179, 76, 20, 9, 34, 205, 188, 4, 92, 76, 20, 9, 34, 237, - 236, 4, 222, 235, 76, 20, 9, 34, 237, 236, 4, 179, 76, 20, 9, 34, 237, - 236, 4, 221, 186, 76, 20, 9, 34, 237, 236, 4, 92, 76, 20, 9, 34, 199, - 215, 4, 179, 76, 20, 9, 34, 199, 215, 4, 92, 76, 20, 9, 34, 191, 117, 4, - 92, 76, 20, 9, 34, 251, 179, 4, 222, 235, 76, 20, 9, 34, 251, 179, 4, 92, - 76, 20, 9, 34, 231, 50, 4, 222, 235, 76, 20, 9, 34, 231, 50, 4, 92, 76, - 20, 9, 34, 233, 6, 4, 222, 235, 76, 20, 9, 34, 233, 6, 4, 179, 76, 20, 9, - 34, 233, 6, 4, 221, 186, 76, 20, 9, 34, 233, 6, 4, 92, 76, 20, 9, 34, - 233, 6, 4, 130, 217, 80, 76, 20, 9, 34, 233, 6, 4, 99, 76, 20, 9, 34, - 208, 83, 4, 179, 76, 20, 9, 34, 208, 83, 4, 92, 76, 20, 9, 34, 208, 83, - 4, 130, 217, 80, 76, 20, 9, 34, 208, 83, 4, 99, 76, 20, 9, 34, 222, 80, - 4, 130, 76, 20, 9, 34, 222, 80, 4, 222, 235, 76, 20, 9, 34, 222, 80, 4, - 179, 76, 20, 9, 34, 222, 80, 4, 221, 186, 76, 20, 9, 34, 222, 80, 4, 220, - 12, 76, 20, 9, 34, 222, 80, 4, 92, 76, 20, 9, 34, 222, 80, 4, 130, 217, - 80, 76, 20, 9, 34, 222, 80, 4, 99, 76, 20, 9, 34, 220, 12, 4, 222, 235, - 76, 20, 9, 34, 220, 12, 4, 179, 76, 20, 9, 34, 220, 12, 4, 221, 186, 76, - 20, 9, 34, 220, 12, 4, 92, 76, 20, 9, 34, 220, 12, 4, 130, 217, 80, 76, - 20, 9, 34, 220, 12, 4, 99, 76, 20, 9, 34, 92, 4, 222, 235, 76, 20, 9, 34, - 92, 4, 179, 76, 20, 9, 34, 92, 4, 221, 186, 76, 20, 9, 34, 92, 4, 92, 76, - 20, 9, 34, 92, 4, 130, 217, 80, 76, 20, 9, 34, 92, 4, 99, 76, 20, 9, 34, - 213, 12, 4, 222, 235, 76, 20, 9, 34, 213, 12, 4, 179, 76, 20, 9, 34, 213, - 12, 4, 221, 186, 76, 20, 9, 34, 213, 12, 4, 92, 76, 20, 9, 34, 213, 12, - 4, 130, 217, 80, 76, 20, 9, 34, 213, 12, 4, 99, 76, 20, 9, 34, 229, 179, - 4, 222, 235, 76, 20, 9, 34, 229, 179, 4, 92, 76, 20, 9, 34, 229, 179, 4, - 130, 217, 80, 76, 20, 9, 34, 229, 179, 4, 99, 76, 20, 9, 34, 99, 4, 222, - 235, 76, 20, 9, 34, 99, 4, 179, 76, 20, 9, 34, 99, 4, 221, 186, 76, 20, - 9, 34, 99, 4, 92, 76, 20, 9, 34, 99, 4, 130, 217, 80, 76, 20, 9, 34, 99, - 4, 99, 76, 20, 9, 34, 199, 37, 4, 200, 177, 130, 76, 20, 9, 34, 207, 67, - 4, 200, 177, 130, 76, 20, 9, 34, 130, 217, 80, 4, 200, 177, 130, 76, 20, - 9, 34, 203, 151, 4, 237, 199, 76, 20, 9, 34, 203, 151, 4, 222, 25, 76, - 20, 9, 34, 203, 151, 4, 233, 30, 76, 20, 9, 34, 203, 151, 4, 237, 201, - 76, 20, 9, 34, 203, 151, 4, 222, 27, 76, 20, 9, 34, 203, 151, 4, 200, - 177, 130, 76, 20, 9, 34, 99, 4, 230, 25, 95, 4, 207, 67, 52, 20, 9, 34, - 99, 4, 230, 25, 95, 4, 191, 114, 52, 20, 9, 34, 99, 4, 230, 25, 95, 4, - 92, 52, 20, 9, 34, 99, 4, 230, 25, 95, 4, 213, 12, 52, 20, 9, 34, 99, 4, - 230, 25, 95, 4, 130, 217, 80, 52, 20, 9, 34, 99, 4, 230, 25, 95, 4, 99, - 52, 20, 9, 34, 248, 196, 4, 207, 67, 52, 20, 9, 34, 248, 196, 4, 191, - 114, 52, 20, 9, 34, 248, 196, 4, 92, 52, 20, 9, 34, 248, 196, 4, 213, 12, - 52, 20, 9, 34, 248, 196, 4, 130, 217, 80, 52, 20, 9, 34, 248, 196, 4, 99, - 52, 20, 9, 34, 199, 110, 4, 207, 67, 52, 20, 9, 34, 199, 110, 4, 191, - 114, 52, 20, 9, 34, 199, 110, 4, 92, 52, 20, 9, 34, 199, 110, 4, 213, 12, - 52, 20, 9, 34, 199, 110, 4, 130, 217, 80, 52, 20, 9, 34, 199, 110, 4, 99, - 52, 20, 9, 34, 199, 25, 4, 207, 67, 52, 20, 9, 34, 199, 25, 4, 191, 114, - 52, 20, 9, 34, 199, 25, 4, 92, 52, 20, 9, 34, 199, 25, 4, 213, 12, 52, - 20, 9, 34, 199, 25, 4, 130, 217, 80, 52, 20, 9, 34, 199, 25, 4, 99, 52, - 20, 9, 34, 233, 6, 4, 130, 217, 80, 52, 20, 9, 34, 233, 6, 4, 99, 52, 20, - 9, 34, 208, 83, 4, 130, 217, 80, 52, 20, 9, 34, 208, 83, 4, 99, 52, 20, - 9, 34, 222, 80, 4, 130, 52, 20, 9, 34, 222, 80, 4, 220, 12, 52, 20, 9, - 34, 222, 80, 4, 92, 52, 20, 9, 34, 222, 80, 4, 130, 217, 80, 52, 20, 9, - 34, 222, 80, 4, 99, 52, 20, 9, 34, 220, 12, 4, 92, 52, 20, 9, 34, 220, - 12, 4, 130, 217, 80, 52, 20, 9, 34, 220, 12, 4, 99, 52, 20, 9, 34, 92, 4, - 130, 52, 20, 9, 34, 92, 4, 92, 52, 20, 9, 34, 213, 12, 4, 207, 67, 52, - 20, 9, 34, 213, 12, 4, 191, 114, 52, 20, 9, 34, 213, 12, 4, 92, 52, 20, - 9, 34, 213, 12, 4, 213, 12, 52, 20, 9, 34, 213, 12, 4, 130, 217, 80, 52, - 20, 9, 34, 213, 12, 4, 99, 52, 20, 9, 34, 130, 217, 80, 4, 200, 177, 130, - 52, 20, 9, 34, 99, 4, 207, 67, 52, 20, 9, 34, 99, 4, 191, 114, 52, 20, 9, - 34, 99, 4, 92, 52, 20, 9, 34, 99, 4, 213, 12, 52, 20, 9, 34, 99, 4, 130, - 217, 80, 52, 20, 9, 34, 99, 4, 99, 52, 20, 9, 34, 99, 4, 230, 25, 95, 4, - 222, 235, 89, 20, 9, 34, 99, 4, 230, 25, 95, 4, 179, 89, 20, 9, 34, 99, - 4, 230, 25, 95, 4, 221, 186, 89, 20, 9, 34, 99, 4, 230, 25, 95, 4, 92, - 89, 20, 9, 34, 99, 4, 230, 25, 95, 4, 229, 179, 89, 20, 9, 34, 248, 196, - 4, 222, 235, 89, 20, 9, 34, 248, 196, 4, 179, 89, 20, 9, 34, 248, 196, 4, - 221, 186, 89, 20, 9, 34, 248, 196, 4, 92, 89, 20, 9, 34, 248, 196, 4, - 229, 179, 89, 20, 9, 34, 199, 110, 4, 222, 235, 89, 20, 9, 34, 199, 110, - 4, 179, 89, 20, 9, 34, 199, 110, 4, 221, 186, 89, 20, 9, 34, 199, 110, 4, - 92, 89, 20, 9, 34, 199, 110, 4, 229, 179, 89, 20, 9, 34, 199, 25, 4, 92, - 89, 20, 9, 34, 222, 235, 4, 179, 89, 20, 9, 34, 222, 235, 4, 92, 89, 20, - 9, 34, 179, 4, 222, 235, 89, 20, 9, 34, 179, 4, 92, 89, 20, 9, 34, 221, - 186, 4, 222, 235, 89, 20, 9, 34, 221, 186, 4, 92, 89, 20, 9, 34, 205, 42, - 4, 222, 235, 89, 20, 9, 34, 205, 42, 4, 179, 89, 20, 9, 34, 205, 42, 4, - 221, 186, 89, 20, 9, 34, 205, 42, 4, 92, 89, 20, 9, 34, 205, 188, 4, 179, - 89, 20, 9, 34, 205, 188, 4, 221, 186, 89, 20, 9, 34, 205, 188, 4, 92, 89, - 20, 9, 34, 237, 236, 4, 222, 235, 89, 20, 9, 34, 237, 236, 4, 179, 89, - 20, 9, 34, 237, 236, 4, 221, 186, 89, 20, 9, 34, 237, 236, 4, 92, 89, 20, - 9, 34, 199, 215, 4, 179, 89, 20, 9, 34, 191, 117, 4, 92, 89, 20, 9, 34, - 251, 179, 4, 222, 235, 89, 20, 9, 34, 251, 179, 4, 92, 89, 20, 9, 34, - 231, 50, 4, 222, 235, 89, 20, 9, 34, 231, 50, 4, 92, 89, 20, 9, 34, 233, - 6, 4, 222, 235, 89, 20, 9, 34, 233, 6, 4, 179, 89, 20, 9, 34, 233, 6, 4, - 221, 186, 89, 20, 9, 34, 233, 6, 4, 92, 89, 20, 9, 34, 208, 83, 4, 179, - 89, 20, 9, 34, 208, 83, 4, 92, 89, 20, 9, 34, 222, 80, 4, 222, 235, 89, - 20, 9, 34, 222, 80, 4, 179, 89, 20, 9, 34, 222, 80, 4, 221, 186, 89, 20, - 9, 34, 222, 80, 4, 220, 12, 89, 20, 9, 34, 222, 80, 4, 92, 89, 20, 9, 34, - 220, 12, 4, 222, 235, 89, 20, 9, 34, 220, 12, 4, 179, 89, 20, 9, 34, 220, - 12, 4, 221, 186, 89, 20, 9, 34, 220, 12, 4, 92, 89, 20, 9, 34, 220, 12, - 4, 229, 179, 89, 20, 9, 34, 92, 4, 222, 235, 89, 20, 9, 34, 92, 4, 179, - 89, 20, 9, 34, 92, 4, 221, 186, 89, 20, 9, 34, 92, 4, 92, 89, 20, 9, 34, - 213, 12, 4, 222, 235, 89, 20, 9, 34, 213, 12, 4, 179, 89, 20, 9, 34, 213, - 12, 4, 221, 186, 89, 20, 9, 34, 213, 12, 4, 92, 89, 20, 9, 34, 213, 12, - 4, 229, 179, 89, 20, 9, 34, 229, 179, 4, 222, 235, 89, 20, 9, 34, 229, - 179, 4, 92, 89, 20, 9, 34, 229, 179, 4, 200, 177, 130, 89, 20, 9, 34, 99, - 4, 222, 235, 89, 20, 9, 34, 99, 4, 179, 89, 20, 9, 34, 99, 4, 221, 186, - 89, 20, 9, 34, 99, 4, 92, 89, 20, 9, 34, 99, 4, 229, 179, 89, 20, 9, 34, - 99, 4, 230, 25, 95, 4, 92, 216, 198, 20, 9, 34, 99, 4, 230, 25, 95, 4, - 229, 179, 216, 198, 20, 9, 34, 248, 196, 4, 92, 216, 198, 20, 9, 34, 248, - 196, 4, 229, 179, 216, 198, 20, 9, 34, 199, 110, 4, 92, 216, 198, 20, 9, - 34, 199, 110, 4, 229, 179, 216, 198, 20, 9, 34, 199, 25, 4, 92, 216, 198, - 20, 9, 34, 199, 25, 4, 229, 179, 216, 198, 20, 9, 34, 205, 42, 4, 92, - 216, 198, 20, 9, 34, 205, 42, 4, 229, 179, 216, 198, 20, 9, 34, 203, 105, - 4, 92, 216, 198, 20, 9, 34, 203, 105, 4, 229, 179, 216, 198, 20, 9, 34, - 222, 80, 4, 220, 12, 216, 198, 20, 9, 34, 222, 80, 4, 92, 216, 198, 20, - 9, 34, 220, 12, 4, 92, 216, 198, 20, 9, 34, 213, 12, 4, 92, 216, 198, 20, - 9, 34, 213, 12, 4, 229, 179, 216, 198, 20, 9, 34, 99, 4, 92, 216, 198, - 20, 9, 34, 99, 4, 229, 179, 216, 198, 20, 9, 34, 203, 151, 4, 233, 30, - 216, 198, 20, 9, 34, 203, 151, 4, 237, 201, 216, 198, 20, 9, 34, 203, - 151, 4, 222, 27, 216, 198, 20, 9, 34, 199, 215, 4, 130, 217, 80, 76, 20, - 9, 34, 199, 215, 4, 99, 76, 20, 9, 34, 251, 179, 4, 130, 217, 80, 76, 20, - 9, 34, 251, 179, 4, 99, 76, 20, 9, 34, 231, 50, 4, 130, 217, 80, 76, 20, - 9, 34, 231, 50, 4, 99, 76, 20, 9, 34, 205, 42, 4, 130, 217, 80, 76, 20, - 9, 34, 205, 42, 4, 99, 76, 20, 9, 34, 203, 105, 4, 130, 217, 80, 76, 20, - 9, 34, 203, 105, 4, 99, 76, 20, 9, 34, 179, 4, 130, 217, 80, 76, 20, 9, - 34, 179, 4, 99, 76, 20, 9, 34, 222, 235, 4, 130, 217, 80, 76, 20, 9, 34, - 222, 235, 4, 99, 76, 20, 9, 34, 221, 186, 4, 130, 217, 80, 76, 20, 9, 34, - 221, 186, 4, 99, 76, 20, 9, 34, 205, 188, 4, 130, 217, 80, 76, 20, 9, 34, - 205, 188, 4, 99, 76, 20, 9, 34, 237, 236, 4, 130, 217, 80, 76, 20, 9, 34, - 237, 236, 4, 99, 76, 20, 9, 34, 203, 105, 4, 222, 235, 76, 20, 9, 34, - 203, 105, 4, 179, 76, 20, 9, 34, 203, 105, 4, 221, 186, 76, 20, 9, 34, - 203, 105, 4, 92, 76, 20, 9, 34, 203, 105, 4, 207, 67, 76, 20, 9, 34, 205, - 42, 4, 207, 67, 76, 20, 9, 34, 205, 188, 4, 207, 67, 76, 20, 9, 34, 237, - 236, 4, 207, 67, 76, 20, 9, 34, 199, 215, 4, 130, 217, 80, 52, 20, 9, 34, - 199, 215, 4, 99, 52, 20, 9, 34, 251, 179, 4, 130, 217, 80, 52, 20, 9, 34, - 251, 179, 4, 99, 52, 20, 9, 34, 231, 50, 4, 130, 217, 80, 52, 20, 9, 34, - 231, 50, 4, 99, 52, 20, 9, 34, 205, 42, 4, 130, 217, 80, 52, 20, 9, 34, - 205, 42, 4, 99, 52, 20, 9, 34, 203, 105, 4, 130, 217, 80, 52, 20, 9, 34, - 203, 105, 4, 99, 52, 20, 9, 34, 179, 4, 130, 217, 80, 52, 20, 9, 34, 179, - 4, 99, 52, 20, 9, 34, 222, 235, 4, 130, 217, 80, 52, 20, 9, 34, 222, 235, - 4, 99, 52, 20, 9, 34, 221, 186, 4, 130, 217, 80, 52, 20, 9, 34, 221, 186, - 4, 99, 52, 20, 9, 34, 205, 188, 4, 130, 217, 80, 52, 20, 9, 34, 205, 188, - 4, 99, 52, 20, 9, 34, 237, 236, 4, 130, 217, 80, 52, 20, 9, 34, 237, 236, - 4, 99, 52, 20, 9, 34, 203, 105, 4, 222, 235, 52, 20, 9, 34, 203, 105, 4, - 179, 52, 20, 9, 34, 203, 105, 4, 221, 186, 52, 20, 9, 34, 203, 105, 4, - 92, 52, 20, 9, 34, 203, 105, 4, 207, 67, 52, 20, 9, 34, 205, 42, 4, 207, - 67, 52, 20, 9, 34, 205, 188, 4, 207, 67, 52, 20, 9, 34, 237, 236, 4, 207, - 67, 52, 20, 9, 34, 203, 105, 4, 222, 235, 89, 20, 9, 34, 203, 105, 4, - 179, 89, 20, 9, 34, 203, 105, 4, 221, 186, 89, 20, 9, 34, 203, 105, 4, - 92, 89, 20, 9, 34, 205, 42, 4, 229, 179, 89, 20, 9, 34, 203, 105, 4, 229, - 179, 89, 20, 9, 34, 199, 215, 4, 92, 89, 20, 9, 34, 205, 42, 4, 222, 235, - 216, 198, 20, 9, 34, 205, 42, 4, 179, 216, 198, 20, 9, 34, 205, 42, 4, - 221, 186, 216, 198, 20, 9, 34, 203, 105, 4, 222, 235, 216, 198, 20, 9, - 34, 203, 105, 4, 179, 216, 198, 20, 9, 34, 203, 105, 4, 221, 186, 216, - 198, 20, 9, 34, 199, 215, 4, 92, 216, 198, 20, 9, 34, 191, 117, 4, 92, - 216, 198, 20, 9, 34, 130, 4, 233, 28, 52, 20, 9, 34, 130, 4, 233, 28, 76, - 20, 211, 30, 45, 210, 103, 211, 30, 50, 210, 103, 9, 34, 207, 154, 251, - 122, 9, 34, 207, 162, 251, 121, 251, 56, 9, 34, 207, 162, 251, 121, 251, - 55, 9, 34, 207, 162, 251, 121, 251, 53, 9, 34, 207, 162, 251, 121, 251, - 52, 9, 34, 207, 162, 251, 121, 251, 51, 9, 34, 205, 157, 251, 146, 193, - 181, 9, 34, 251, 146, 250, 167, 9, 34, 251, 145, 250, 167, 9, 34, 251, - 144, 250, 167, 9, 34, 251, 146, 250, 166, 193, 152, 9, 34, 208, 12, 202, - 135, 9, 34, 205, 155, 251, 146, 193, 177, 193, 180, 9, 34, 251, 149, 250, - 167, 9, 34, 199, 230, 193, 179, 9, 34, 207, 153, 251, 122, 9, 34, 199, - 110, 4, 222, 235, 4, 92, 89, 20, 9, 34, 199, 110, 4, 179, 4, 222, 235, - 52, 20, 9, 34, 199, 110, 4, 179, 4, 222, 235, 89, 20, 9, 34, 199, 110, 4, - 179, 4, 92, 89, 20, 9, 34, 199, 110, 4, 221, 186, 4, 92, 89, 20, 9, 34, - 199, 110, 4, 92, 4, 222, 235, 89, 20, 9, 34, 199, 110, 4, 92, 4, 179, 89, - 20, 9, 34, 199, 110, 4, 92, 4, 221, 186, 89, 20, 9, 34, 222, 235, 4, 92, - 4, 179, 52, 20, 9, 34, 222, 235, 4, 92, 4, 179, 89, 20, 9, 34, 179, 4, - 92, 4, 99, 52, 20, 9, 34, 179, 4, 92, 4, 130, 217, 80, 52, 20, 9, 34, - 205, 42, 4, 179, 4, 222, 235, 89, 20, 9, 34, 205, 42, 4, 222, 235, 4, - 179, 89, 20, 9, 34, 205, 42, 4, 222, 235, 4, 130, 217, 80, 52, 20, 9, 34, - 205, 42, 4, 92, 4, 179, 52, 20, 9, 34, 205, 42, 4, 92, 4, 179, 89, 20, 9, - 34, 205, 42, 4, 92, 4, 222, 235, 89, 20, 9, 34, 205, 42, 4, 92, 4, 92, - 52, 20, 9, 34, 205, 42, 4, 92, 4, 92, 89, 20, 9, 34, 205, 188, 4, 179, 4, - 179, 52, 20, 9, 34, 205, 188, 4, 179, 4, 179, 89, 20, 9, 34, 205, 188, 4, - 92, 4, 92, 52, 20, 9, 34, 203, 105, 4, 179, 4, 92, 52, 20, 9, 34, 203, - 105, 4, 179, 4, 92, 89, 20, 9, 34, 203, 105, 4, 222, 235, 4, 99, 52, 20, - 9, 34, 203, 105, 4, 92, 4, 221, 186, 52, 20, 9, 34, 203, 105, 4, 92, 4, - 221, 186, 89, 20, 9, 34, 203, 105, 4, 92, 4, 92, 52, 20, 9, 34, 203, 105, - 4, 92, 4, 92, 89, 20, 9, 34, 237, 236, 4, 179, 4, 130, 217, 80, 52, 20, - 9, 34, 237, 236, 4, 221, 186, 4, 92, 52, 20, 9, 34, 237, 236, 4, 221, - 186, 4, 92, 89, 20, 9, 34, 199, 215, 4, 92, 4, 179, 52, 20, 9, 34, 199, - 215, 4, 92, 4, 179, 89, 20, 9, 34, 199, 215, 4, 92, 4, 92, 89, 20, 9, 34, - 199, 215, 4, 92, 4, 99, 52, 20, 9, 34, 251, 179, 4, 222, 235, 4, 92, 52, - 20, 9, 34, 251, 179, 4, 92, 4, 92, 52, 20, 9, 34, 251, 179, 4, 92, 4, 92, - 89, 20, 9, 34, 251, 179, 4, 92, 4, 130, 217, 80, 52, 20, 9, 34, 231, 50, - 4, 92, 4, 92, 52, 20, 9, 34, 231, 50, 4, 92, 4, 99, 52, 20, 9, 34, 231, - 50, 4, 92, 4, 130, 217, 80, 52, 20, 9, 34, 233, 6, 4, 221, 186, 4, 92, - 52, 20, 9, 34, 233, 6, 4, 221, 186, 4, 92, 89, 20, 9, 34, 208, 83, 4, 92, - 4, 179, 52, 20, 9, 34, 208, 83, 4, 92, 4, 92, 52, 20, 9, 34, 220, 12, 4, - 179, 4, 92, 52, 20, 9, 34, 220, 12, 4, 179, 4, 99, 52, 20, 9, 34, 220, - 12, 4, 179, 4, 130, 217, 80, 52, 20, 9, 34, 220, 12, 4, 222, 235, 4, 222, - 235, 89, 20, 9, 34, 220, 12, 4, 222, 235, 4, 222, 235, 52, 20, 9, 34, - 220, 12, 4, 221, 186, 4, 92, 52, 20, 9, 34, 220, 12, 4, 221, 186, 4, 92, - 89, 20, 9, 34, 220, 12, 4, 92, 4, 179, 52, 20, 9, 34, 220, 12, 4, 92, 4, - 179, 89, 20, 9, 34, 92, 4, 179, 4, 222, 235, 89, 20, 9, 34, 92, 4, 179, - 4, 92, 89, 20, 9, 34, 92, 4, 179, 4, 99, 52, 20, 9, 34, 92, 4, 222, 235, - 4, 179, 89, 20, 9, 34, 92, 4, 222, 235, 4, 92, 89, 20, 9, 34, 92, 4, 221, - 186, 4, 222, 235, 89, 20, 9, 34, 92, 4, 221, 186, 4, 92, 89, 20, 9, 34, - 92, 4, 222, 235, 4, 221, 186, 89, 20, 9, 34, 229, 179, 4, 92, 4, 222, - 235, 89, 20, 9, 34, 229, 179, 4, 92, 4, 92, 89, 20, 9, 34, 213, 12, 4, - 179, 4, 92, 89, 20, 9, 34, 213, 12, 4, 179, 4, 130, 217, 80, 52, 20, 9, - 34, 213, 12, 4, 222, 235, 4, 92, 52, 20, 9, 34, 213, 12, 4, 222, 235, 4, - 92, 89, 20, 9, 34, 213, 12, 4, 222, 235, 4, 130, 217, 80, 52, 20, 9, 34, - 213, 12, 4, 92, 4, 99, 52, 20, 9, 34, 213, 12, 4, 92, 4, 130, 217, 80, - 52, 20, 9, 34, 99, 4, 92, 4, 92, 52, 20, 9, 34, 99, 4, 92, 4, 92, 89, 20, - 9, 34, 248, 196, 4, 221, 186, 4, 99, 52, 20, 9, 34, 199, 110, 4, 222, - 235, 4, 99, 52, 20, 9, 34, 199, 110, 4, 222, 235, 4, 130, 217, 80, 52, - 20, 9, 34, 199, 110, 4, 221, 186, 4, 99, 52, 20, 9, 34, 199, 110, 4, 221, - 186, 4, 130, 217, 80, 52, 20, 9, 34, 199, 110, 4, 92, 4, 99, 52, 20, 9, - 34, 199, 110, 4, 92, 4, 130, 217, 80, 52, 20, 9, 34, 222, 235, 4, 92, 4, - 99, 52, 20, 9, 34, 222, 235, 4, 179, 4, 130, 217, 80, 52, 20, 9, 34, 222, - 235, 4, 92, 4, 130, 217, 80, 52, 20, 9, 34, 205, 42, 4, 221, 186, 4, 130, - 217, 80, 52, 20, 9, 34, 205, 188, 4, 179, 4, 99, 52, 20, 9, 34, 203, 105, - 4, 179, 4, 99, 52, 20, 9, 34, 237, 236, 4, 179, 4, 99, 52, 20, 9, 34, - 220, 12, 4, 222, 235, 4, 99, 52, 20, 9, 34, 220, 12, 4, 92, 4, 99, 52, - 20, 9, 34, 99, 4, 179, 4, 99, 52, 20, 9, 34, 99, 4, 222, 235, 4, 99, 52, - 20, 9, 34, 99, 4, 92, 4, 99, 52, 20, 9, 34, 92, 4, 92, 4, 99, 52, 20, 9, - 34, 208, 83, 4, 92, 4, 99, 52, 20, 9, 34, 213, 12, 4, 179, 4, 99, 52, 20, - 9, 34, 208, 83, 4, 92, 4, 179, 89, 20, 9, 34, 220, 12, 4, 179, 4, 92, 89, - 20, 9, 34, 251, 179, 4, 92, 4, 99, 52, 20, 9, 34, 222, 80, 4, 92, 4, 99, - 52, 20, 9, 34, 213, 12, 4, 222, 235, 4, 179, 89, 20, 9, 34, 92, 4, 221, - 186, 4, 99, 52, 20, 9, 34, 220, 12, 4, 222, 235, 4, 92, 89, 20, 9, 34, - 222, 80, 4, 92, 4, 92, 52, 20, 9, 34, 220, 12, 4, 222, 235, 4, 92, 52, - 20, 9, 34, 213, 12, 4, 222, 235, 4, 179, 52, 20, 9, 34, 222, 235, 4, 179, - 4, 99, 52, 20, 9, 34, 179, 4, 222, 235, 4, 99, 52, 20, 9, 34, 92, 4, 222, - 235, 4, 99, 52, 20, 9, 34, 233, 6, 4, 92, 4, 99, 52, 20, 9, 34, 248, 196, - 4, 179, 4, 99, 52, 20, 9, 34, 222, 80, 4, 92, 4, 92, 89, 20, 9, 34, 251, - 179, 4, 222, 235, 4, 92, 89, 20, 9, 34, 205, 188, 4, 92, 4, 92, 89, 20, - 9, 34, 205, 42, 4, 221, 186, 4, 99, 52, 20, 9, 34, 213, 12, 4, 222, 235, - 4, 99, 52, 20, 9, 34, 205, 161, 251, 143, 9, 34, 205, 158, 196, 36, 250, - 170, 221, 9, 201, 59, 3, 76, 20, 9, 34, 208, 79, 196, 36, 250, 170, 221, - 9, 201, 59, 3, 76, 20, 9, 34, 251, 120, 76, 20, 9, 34, 251, 162, 76, 20, - 9, 34, 215, 218, 76, 20, 9, 34, 205, 159, 76, 20, 9, 34, 207, 127, 76, - 20, 9, 34, 251, 148, 76, 20, 9, 34, 193, 151, 76, 20, 9, 34, 205, 158, - 76, 20, 9, 34, 205, 156, 251, 148, 193, 150, 9, 34, 222, 250, 206, 244, - 57, 9, 34, 248, 103, 250, 237, 250, 238, 9, 34, 200, 237, 193, 188, 199, - 239, 9, 34, 250, 71, 193, 188, 222, 251, 66, 205, 28, 66, 204, 173, 66, - 204, 105, 66, 204, 94, 66, 204, 83, 66, 204, 72, 66, 204, 61, 66, 204, - 50, 66, 204, 39, 66, 205, 27, 66, 205, 16, 66, 205, 5, 66, 204, 250, 66, - 204, 239, 66, 204, 228, 66, 204, 217, 208, 214, 232, 107, 39, 81, 242, - 26, 208, 214, 232, 107, 39, 81, 154, 242, 26, 208, 214, 232, 107, 39, 81, - 154, 232, 42, 201, 58, 208, 214, 232, 107, 39, 81, 242, 35, 208, 214, - 232, 107, 39, 81, 204, 20, 208, 214, 232, 107, 39, 81, 233, 175, 77, 208, - 214, 232, 107, 39, 81, 208, 8, 77, 208, 214, 232, 107, 39, 81, 45, 64, - 219, 163, 248, 5, 208, 214, 232, 107, 39, 81, 50, 64, 219, 163, 248, 1, - 208, 214, 232, 107, 39, 81, 228, 209, 234, 78, 33, 34, 45, 230, 37, 33, - 34, 50, 230, 37, 33, 54, 198, 148, 45, 230, 37, 33, 54, 198, 148, 50, - 230, 37, 33, 217, 126, 45, 230, 37, 33, 217, 126, 50, 230, 37, 33, 238, - 253, 217, 125, 33, 34, 45, 134, 60, 33, 34, 50, 134, 60, 33, 198, 148, - 45, 134, 60, 33, 198, 148, 50, 134, 60, 33, 217, 126, 45, 134, 60, 33, - 217, 126, 50, 134, 60, 33, 238, 253, 217, 126, 60, 33, 42, 198, 118, 45, - 230, 37, 33, 42, 198, 118, 50, 230, 37, 208, 214, 232, 107, 39, 81, 103, - 75, 219, 212, 208, 214, 232, 107, 39, 81, 234, 73, 237, 170, 208, 214, - 232, 107, 39, 81, 234, 62, 237, 170, 208, 214, 232, 107, 39, 81, 131, - 219, 88, 208, 214, 232, 107, 39, 81, 193, 133, 131, 219, 88, 208, 214, - 232, 107, 39, 81, 45, 210, 103, 208, 214, 232, 107, 39, 81, 50, 210, 103, - 208, 214, 232, 107, 39, 81, 45, 238, 124, 248, 5, 208, 214, 232, 107, 39, - 81, 50, 238, 124, 248, 5, 208, 214, 232, 107, 39, 81, 45, 198, 37, 203, - 98, 248, 5, 208, 214, 232, 107, 39, 81, 50, 198, 37, 203, 98, 248, 5, - 208, 214, 232, 107, 39, 81, 45, 62, 219, 163, 248, 5, 208, 214, 232, 107, - 39, 81, 50, 62, 219, 163, 248, 5, 208, 214, 232, 107, 39, 81, 45, 54, - 251, 65, 248, 5, 208, 214, 232, 107, 39, 81, 50, 54, 251, 65, 248, 5, - 208, 214, 232, 107, 39, 81, 45, 251, 65, 248, 5, 208, 214, 232, 107, 39, - 81, 50, 251, 65, 248, 5, 208, 214, 232, 107, 39, 81, 45, 238, 211, 248, - 5, 208, 214, 232, 107, 39, 81, 50, 238, 211, 248, 5, 208, 214, 232, 107, - 39, 81, 45, 64, 238, 211, 248, 5, 208, 214, 232, 107, 39, 81, 50, 64, - 238, 211, 248, 5, 203, 251, 236, 96, 64, 203, 251, 236, 96, 208, 214, - 232, 107, 39, 81, 45, 51, 248, 5, 208, 214, 232, 107, 39, 81, 50, 51, - 248, 5, 237, 169, 210, 244, 246, 226, 210, 244, 193, 133, 210, 244, 54, - 193, 133, 210, 244, 237, 169, 131, 219, 88, 246, 226, 131, 219, 88, 193, - 133, 131, 219, 88, 2, 242, 26, 2, 154, 242, 26, 2, 232, 42, 201, 58, 2, - 204, 20, 2, 242, 35, 2, 208, 8, 77, 2, 233, 175, 77, 2, 234, 73, 237, - 170, 2, 45, 210, 103, 2, 50, 210, 103, 2, 45, 238, 124, 248, 5, 2, 50, - 238, 124, 248, 5, 2, 45, 198, 37, 203, 98, 248, 5, 2, 50, 198, 37, 203, - 98, 248, 5, 2, 31, 57, 2, 251, 86, 2, 250, 143, 2, 107, 57, 2, 228, 57, - 2, 219, 156, 57, 2, 230, 170, 57, 2, 234, 1, 57, 2, 207, 14, 202, 18, 2, - 236, 110, 57, 2, 210, 4, 57, 2, 242, 24, 250, 132, 9, 233, 28, 76, 20, 9, - 199, 164, 4, 233, 28, 56, 9, 237, 199, 76, 20, 9, 199, 211, 232, 79, 9, - 222, 25, 76, 20, 9, 233, 30, 76, 20, 9, 233, 30, 216, 198, 20, 9, 237, - 201, 76, 20, 9, 237, 201, 216, 198, 20, 9, 222, 27, 76, 20, 9, 222, 27, - 216, 198, 20, 9, 203, 151, 76, 20, 9, 203, 151, 216, 198, 20, 9, 200, - 202, 76, 20, 9, 200, 202, 216, 198, 20, 9, 1, 230, 25, 76, 20, 9, 1, 130, - 4, 217, 121, 95, 76, 20, 9, 1, 130, 4, 217, 121, 95, 52, 20, 9, 1, 130, - 4, 230, 25, 95, 76, 20, 9, 1, 130, 4, 230, 25, 95, 52, 20, 9, 1, 193, - 132, 4, 230, 25, 95, 76, 20, 9, 1, 193, 132, 4, 230, 25, 95, 52, 20, 9, - 1, 130, 4, 230, 25, 248, 183, 76, 20, 9, 1, 130, 4, 230, 25, 248, 183, - 52, 20, 9, 1, 99, 4, 230, 25, 95, 76, 20, 9, 1, 99, 4, 230, 25, 95, 52, - 20, 9, 1, 99, 4, 230, 25, 95, 89, 20, 9, 1, 99, 4, 230, 25, 95, 216, 198, - 20, 9, 1, 130, 76, 20, 9, 1, 130, 52, 20, 9, 1, 248, 196, 76, 20, 9, 1, - 248, 196, 52, 20, 9, 1, 248, 196, 89, 20, 9, 1, 248, 196, 216, 198, 20, - 9, 1, 199, 110, 217, 44, 76, 20, 9, 1, 199, 110, 217, 44, 52, 20, 9, 1, - 199, 110, 76, 20, 9, 1, 199, 110, 52, 20, 9, 1, 199, 110, 89, 20, 9, 1, - 199, 110, 216, 198, 20, 9, 1, 199, 25, 76, 20, 9, 1, 199, 25, 52, 20, 9, - 1, 199, 25, 89, 20, 9, 1, 199, 25, 216, 198, 20, 9, 1, 222, 235, 76, 20, - 9, 1, 222, 235, 52, 20, 9, 1, 222, 235, 89, 20, 9, 1, 222, 235, 216, 198, - 20, 9, 1, 179, 76, 20, 9, 1, 179, 52, 20, 9, 1, 179, 89, 20, 9, 1, 179, - 216, 198, 20, 9, 1, 221, 186, 76, 20, 9, 1, 221, 186, 52, 20, 9, 1, 221, - 186, 89, 20, 9, 1, 221, 186, 216, 198, 20, 9, 1, 237, 213, 76, 20, 9, 1, - 237, 213, 52, 20, 9, 1, 199, 37, 76, 20, 9, 1, 199, 37, 52, 20, 9, 1, - 207, 67, 76, 20, 9, 1, 207, 67, 52, 20, 9, 1, 191, 114, 76, 20, 9, 1, - 191, 114, 52, 20, 9, 1, 205, 42, 76, 20, 9, 1, 205, 42, 52, 20, 9, 1, - 205, 42, 89, 20, 9, 1, 205, 42, 216, 198, 20, 9, 1, 203, 105, 76, 20, 9, - 1, 203, 105, 52, 20, 9, 1, 203, 105, 89, 20, 9, 1, 203, 105, 216, 198, - 20, 9, 1, 205, 188, 76, 20, 9, 1, 205, 188, 52, 20, 9, 1, 205, 188, 89, - 20, 9, 1, 205, 188, 216, 198, 20, 9, 1, 237, 236, 76, 20, 9, 1, 237, 236, - 52, 20, 9, 1, 237, 236, 89, 20, 9, 1, 237, 236, 216, 198, 20, 9, 1, 199, - 215, 76, 20, 9, 1, 199, 215, 52, 20, 9, 1, 199, 215, 89, 20, 9, 1, 199, - 215, 216, 198, 20, 9, 1, 191, 117, 76, 20, 9, 1, 191, 117, 52, 20, 9, 1, - 191, 117, 89, 20, 9, 1, 191, 117, 216, 198, 20, 9, 1, 251, 179, 76, 20, - 9, 1, 251, 179, 52, 20, 9, 1, 251, 179, 89, 20, 9, 1, 251, 179, 216, 198, - 20, 9, 1, 231, 50, 76, 20, 9, 1, 231, 50, 52, 20, 9, 1, 231, 50, 89, 20, - 9, 1, 231, 50, 216, 198, 20, 9, 1, 233, 6, 76, 20, 9, 1, 233, 6, 52, 20, - 9, 1, 233, 6, 89, 20, 9, 1, 233, 6, 216, 198, 20, 9, 1, 208, 83, 76, 20, - 9, 1, 208, 83, 52, 20, 9, 1, 208, 83, 89, 20, 9, 1, 208, 83, 216, 198, - 20, 9, 1, 222, 80, 76, 20, 9, 1, 222, 80, 52, 20, 9, 1, 222, 80, 89, 20, - 9, 1, 222, 80, 216, 198, 20, 9, 1, 220, 12, 76, 20, 9, 1, 220, 12, 52, - 20, 9, 1, 220, 12, 89, 20, 9, 1, 220, 12, 216, 198, 20, 9, 1, 92, 76, 20, - 9, 1, 92, 52, 20, 9, 1, 92, 89, 20, 9, 1, 92, 216, 198, 20, 9, 1, 213, - 12, 76, 20, 9, 1, 213, 12, 52, 20, 9, 1, 213, 12, 89, 20, 9, 1, 213, 12, - 216, 198, 20, 9, 1, 229, 179, 76, 20, 9, 1, 229, 179, 52, 20, 9, 1, 229, - 179, 89, 20, 9, 1, 229, 179, 216, 198, 20, 9, 1, 193, 132, 76, 20, 9, 1, - 193, 132, 52, 20, 9, 1, 130, 217, 80, 76, 20, 9, 1, 130, 217, 80, 52, 20, - 9, 1, 99, 76, 20, 9, 1, 99, 52, 20, 9, 1, 99, 89, 20, 9, 1, 99, 216, 198, - 20, 9, 34, 220, 12, 4, 130, 4, 217, 121, 95, 76, 20, 9, 34, 220, 12, 4, - 130, 4, 217, 121, 95, 52, 20, 9, 34, 220, 12, 4, 130, 4, 230, 25, 95, 76, - 20, 9, 34, 220, 12, 4, 130, 4, 230, 25, 95, 52, 20, 9, 34, 220, 12, 4, - 130, 4, 230, 25, 248, 183, 76, 20, 9, 34, 220, 12, 4, 130, 4, 230, 25, - 248, 183, 52, 20, 9, 34, 220, 12, 4, 130, 76, 20, 9, 34, 220, 12, 4, 130, - 52, 20, 191, 78, 193, 73, 213, 24, 201, 242, 190, 190, 233, 175, 77, 190, - 190, 207, 247, 77, 190, 190, 31, 57, 190, 190, 236, 110, 57, 190, 190, - 210, 4, 57, 190, 190, 251, 86, 190, 190, 250, 255, 190, 190, 45, 210, - 103, 190, 190, 50, 210, 103, 190, 190, 250, 143, 190, 190, 107, 57, 190, - 190, 242, 26, 190, 190, 228, 57, 190, 190, 232, 42, 201, 58, 190, 190, - 202, 18, 190, 190, 17, 191, 77, 190, 190, 17, 108, 190, 190, 17, 109, - 190, 190, 17, 139, 190, 190, 17, 137, 190, 190, 17, 153, 190, 190, 17, - 173, 190, 190, 17, 181, 190, 190, 17, 176, 190, 190, 17, 184, 190, 190, - 242, 35, 190, 190, 204, 20, 190, 190, 219, 156, 57, 190, 190, 234, 1, 57, - 190, 190, 230, 170, 57, 190, 190, 208, 8, 77, 190, 190, 242, 24, 250, - 132, 190, 190, 8, 6, 1, 65, 190, 190, 8, 6, 1, 250, 70, 190, 190, 8, 6, - 1, 247, 145, 190, 190, 8, 6, 1, 238, 80, 190, 190, 8, 6, 1, 73, 190, 190, - 8, 6, 1, 233, 134, 190, 190, 8, 6, 1, 232, 14, 190, 190, 8, 6, 1, 230, - 83, 190, 190, 8, 6, 1, 70, 190, 190, 8, 6, 1, 223, 7, 190, 190, 8, 6, 1, - 222, 125, 190, 190, 8, 6, 1, 170, 190, 190, 8, 6, 1, 218, 147, 190, 190, - 8, 6, 1, 215, 47, 190, 190, 8, 6, 1, 74, 190, 190, 8, 6, 1, 210, 226, - 190, 190, 8, 6, 1, 208, 97, 190, 190, 8, 6, 1, 148, 190, 190, 8, 6, 1, - 206, 3, 190, 190, 8, 6, 1, 200, 39, 190, 190, 8, 6, 1, 69, 190, 190, 8, - 6, 1, 196, 8, 190, 190, 8, 6, 1, 193, 221, 190, 190, 8, 6, 1, 192, 235, - 190, 190, 8, 6, 1, 192, 159, 190, 190, 8, 6, 1, 191, 166, 190, 190, 45, - 51, 248, 5, 190, 190, 207, 14, 202, 18, 190, 190, 50, 51, 248, 5, 190, - 190, 242, 210, 252, 8, 190, 190, 131, 219, 88, 190, 190, 230, 177, 252, - 8, 190, 190, 8, 2, 1, 65, 190, 190, 8, 2, 1, 250, 70, 190, 190, 8, 2, 1, - 247, 145, 190, 190, 8, 2, 1, 238, 80, 190, 190, 8, 2, 1, 73, 190, 190, 8, - 2, 1, 233, 134, 190, 190, 8, 2, 1, 232, 14, 190, 190, 8, 2, 1, 230, 83, - 190, 190, 8, 2, 1, 70, 190, 190, 8, 2, 1, 223, 7, 190, 190, 8, 2, 1, 222, - 125, 190, 190, 8, 2, 1, 170, 190, 190, 8, 2, 1, 218, 147, 190, 190, 8, 2, - 1, 215, 47, 190, 190, 8, 2, 1, 74, 190, 190, 8, 2, 1, 210, 226, 190, 190, - 8, 2, 1, 208, 97, 190, 190, 8, 2, 1, 148, 190, 190, 8, 2, 1, 206, 3, 190, - 190, 8, 2, 1, 200, 39, 190, 190, 8, 2, 1, 69, 190, 190, 8, 2, 1, 196, 8, - 190, 190, 8, 2, 1, 193, 221, 190, 190, 8, 2, 1, 192, 235, 190, 190, 8, 2, - 1, 192, 159, 190, 190, 8, 2, 1, 191, 166, 190, 190, 45, 238, 124, 248, 5, - 190, 190, 81, 219, 88, 190, 190, 50, 238, 124, 248, 5, 190, 190, 198, - 147, 190, 190, 45, 64, 210, 103, 190, 190, 50, 64, 210, 103, 149, 154, - 232, 42, 201, 58, 149, 45, 238, 211, 248, 5, 149, 50, 238, 211, 248, 5, - 149, 154, 242, 26, 149, 71, 82, 236, 96, 149, 71, 1, 193, 48, 149, 71, 1, - 2, 65, 149, 71, 1, 2, 70, 149, 71, 1, 2, 69, 149, 71, 1, 2, 73, 149, 71, - 1, 2, 74, 149, 71, 1, 2, 169, 149, 71, 1, 2, 191, 225, 149, 71, 1, 2, - 192, 12, 149, 71, 1, 2, 197, 90, 149, 222, 22, 208, 184, 202, 0, 77, 149, - 71, 1, 65, 149, 71, 1, 70, 149, 71, 1, 69, 149, 71, 1, 73, 149, 71, 1, - 74, 149, 71, 1, 157, 149, 71, 1, 221, 142, 149, 71, 1, 220, 208, 149, 71, - 1, 221, 253, 149, 71, 1, 221, 43, 149, 71, 1, 189, 149, 71, 1, 202, 217, - 149, 71, 1, 200, 255, 149, 71, 1, 205, 63, 149, 71, 1, 202, 41, 149, 71, - 1, 199, 247, 149, 71, 1, 198, 188, 149, 71, 1, 197, 90, 149, 71, 1, 199, - 140, 149, 71, 1, 159, 149, 71, 1, 180, 149, 71, 1, 213, 205, 149, 71, 1, - 212, 165, 149, 71, 1, 214, 107, 149, 71, 1, 213, 30, 149, 71, 1, 144, - 149, 71, 1, 229, 126, 149, 71, 1, 228, 128, 149, 71, 1, 229, 213, 149, - 71, 1, 228, 247, 149, 71, 1, 172, 149, 71, 1, 216, 81, 149, 71, 1, 215, - 139, 149, 71, 1, 216, 213, 149, 71, 1, 215, 251, 149, 71, 1, 169, 149, - 71, 1, 191, 225, 149, 71, 1, 192, 12, 149, 71, 1, 166, 149, 71, 1, 206, - 252, 149, 71, 1, 206, 63, 149, 71, 1, 207, 108, 149, 71, 1, 206, 157, - 149, 71, 1, 193, 187, 149, 71, 1, 215, 47, 149, 71, 195, 17, 202, 0, 77, - 149, 71, 204, 25, 202, 0, 77, 149, 30, 232, 218, 149, 30, 1, 221, 89, - 149, 30, 1, 201, 162, 149, 30, 1, 221, 82, 149, 30, 1, 213, 190, 149, 30, - 1, 213, 188, 149, 30, 1, 213, 187, 149, 30, 1, 198, 163, 149, 30, 1, 201, - 151, 149, 30, 1, 206, 234, 149, 30, 1, 206, 229, 149, 30, 1, 206, 226, - 149, 30, 1, 206, 219, 149, 30, 1, 206, 214, 149, 30, 1, 206, 209, 149, - 30, 1, 206, 220, 149, 30, 1, 206, 232, 149, 30, 1, 216, 59, 149, 30, 1, - 209, 160, 149, 30, 1, 201, 159, 149, 30, 1, 209, 149, 149, 30, 1, 202, - 155, 149, 30, 1, 201, 156, 149, 30, 1, 223, 193, 149, 30, 1, 242, 232, - 149, 30, 1, 201, 166, 149, 30, 1, 243, 43, 149, 30, 1, 221, 164, 149, 30, - 1, 199, 2, 149, 30, 1, 209, 200, 149, 30, 1, 229, 110, 149, 30, 1, 65, - 149, 30, 1, 251, 229, 149, 30, 1, 169, 149, 30, 1, 192, 129, 149, 30, 1, - 234, 23, 149, 30, 1, 73, 149, 30, 1, 192, 67, 149, 30, 1, 192, 80, 149, - 30, 1, 74, 149, 30, 1, 193, 187, 149, 30, 1, 193, 173, 149, 30, 1, 211, - 139, 149, 30, 1, 192, 12, 149, 30, 1, 69, 149, 30, 1, 193, 105, 149, 30, - 1, 193, 123, 149, 30, 1, 193, 84, 149, 30, 1, 191, 225, 149, 30, 1, 233, - 201, 149, 30, 1, 192, 33, 149, 30, 1, 70, 190, 190, 246, 232, 57, 190, - 190, 209, 1, 57, 190, 190, 212, 255, 57, 190, 190, 217, 125, 190, 190, - 247, 230, 164, 190, 190, 192, 71, 57, 190, 190, 193, 31, 57, 149, 232, - 102, 155, 195, 132, 149, 117, 55, 149, 196, 62, 55, 149, 96, 55, 149, - 235, 75, 55, 149, 62, 201, 185, 149, 64, 242, 218, 223, 78, 251, 45, 251, - 76, 223, 78, 251, 45, 204, 5, 223, 78, 251, 45, 199, 75, 211, 162, 207, - 38, 246, 191, 207, 38, 246, 191, 32, 78, 5, 250, 54, 65, 32, 78, 5, 250, - 23, 73, 32, 78, 5, 250, 32, 70, 32, 78, 5, 250, 0, 74, 32, 78, 5, 250, - 50, 69, 32, 78, 5, 250, 69, 237, 241, 32, 78, 5, 250, 16, 237, 101, 32, - 78, 5, 250, 56, 236, 255, 32, 78, 5, 250, 46, 236, 129, 32, 78, 5, 250, - 10, 235, 45, 32, 78, 5, 250, 4, 223, 4, 32, 78, 5, 250, 15, 222, 238, 32, - 78, 5, 250, 25, 222, 174, 32, 78, 5, 249, 252, 222, 155, 32, 78, 5, 249, - 240, 157, 32, 78, 5, 250, 17, 221, 253, 32, 78, 5, 249, 250, 221, 142, - 32, 78, 5, 249, 247, 221, 43, 32, 78, 5, 249, 236, 220, 208, 32, 78, 5, - 249, 237, 172, 32, 78, 5, 250, 47, 216, 213, 32, 78, 5, 249, 244, 216, - 81, 32, 78, 5, 250, 45, 215, 251, 32, 78, 5, 250, 37, 215, 139, 32, 78, - 5, 250, 58, 180, 32, 78, 5, 250, 36, 214, 107, 32, 78, 5, 250, 30, 213, - 205, 32, 78, 5, 250, 9, 213, 30, 32, 78, 5, 250, 6, 212, 165, 32, 78, 5, - 250, 65, 168, 32, 78, 5, 249, 245, 210, 53, 32, 78, 5, 250, 22, 209, 176, - 32, 78, 5, 250, 49, 209, 65, 32, 78, 5, 250, 11, 208, 158, 32, 78, 5, - 250, 44, 208, 89, 32, 78, 5, 249, 239, 208, 69, 32, 78, 5, 250, 39, 208, - 51, 32, 78, 5, 250, 28, 208, 39, 32, 78, 5, 250, 1, 166, 32, 78, 5, 250, - 33, 207, 108, 32, 78, 5, 250, 8, 206, 252, 32, 78, 5, 250, 67, 206, 157, - 32, 78, 5, 250, 34, 206, 63, 32, 78, 5, 250, 29, 189, 32, 78, 5, 250, 52, - 205, 63, 32, 78, 5, 250, 20, 202, 217, 32, 78, 5, 250, 48, 202, 41, 32, - 78, 5, 250, 3, 200, 255, 32, 78, 5, 250, 2, 199, 247, 32, 78, 5, 250, 63, - 199, 140, 32, 78, 5, 250, 24, 198, 188, 32, 78, 5, 250, 61, 159, 32, 78, - 5, 249, 248, 197, 90, 32, 78, 5, 250, 7, 193, 187, 32, 78, 5, 249, 242, - 193, 123, 32, 78, 5, 250, 21, 193, 84, 32, 78, 5, 250, 19, 193, 48, 32, - 78, 5, 250, 43, 191, 123, 32, 78, 5, 249, 243, 191, 87, 32, 78, 5, 250, - 40, 191, 7, 32, 78, 5, 250, 35, 254, 163, 32, 78, 5, 250, 18, 254, 51, - 32, 78, 5, 249, 233, 250, 113, 32, 78, 5, 249, 246, 235, 1, 32, 78, 5, - 249, 229, 235, 0, 32, 78, 5, 250, 13, 212, 97, 32, 78, 5, 250, 31, 208, - 156, 32, 78, 5, 249, 255, 208, 160, 32, 78, 5, 249, 241, 207, 175, 32, - 78, 5, 250, 27, 207, 174, 32, 78, 5, 249, 249, 206, 150, 32, 78, 5, 249, - 251, 199, 241, 32, 78, 5, 249, 231, 197, 37, 32, 78, 5, 249, 228, 109, - 32, 78, 16, 250, 42, 32, 78, 16, 250, 41, 32, 78, 16, 250, 38, 32, 78, - 16, 250, 26, 32, 78, 16, 250, 14, 32, 78, 16, 250, 12, 32, 78, 16, 250, - 5, 32, 78, 16, 249, 254, 32, 78, 16, 249, 253, 32, 78, 16, 249, 238, 32, - 78, 16, 249, 235, 32, 78, 16, 249, 234, 32, 78, 16, 249, 232, 32, 78, 16, - 249, 230, 32, 78, 156, 249, 227, 217, 70, 32, 78, 156, 249, 226, 193, 35, - 32, 78, 156, 249, 225, 237, 83, 32, 78, 156, 249, 224, 233, 254, 32, 78, - 156, 249, 223, 217, 37, 32, 78, 156, 249, 222, 201, 105, 32, 78, 156, - 249, 221, 233, 182, 32, 78, 156, 249, 220, 207, 137, 32, 78, 156, 249, - 219, 203, 107, 32, 78, 156, 249, 218, 229, 205, 32, 78, 156, 249, 217, - 201, 250, 32, 78, 156, 249, 216, 248, 61, 32, 78, 156, 249, 215, 238, - 192, 32, 78, 156, 249, 214, 247, 202, 32, 78, 156, 249, 213, 193, 93, 32, - 78, 156, 249, 212, 249, 34, 32, 78, 156, 249, 211, 211, 104, 32, 78, 156, - 249, 210, 201, 218, 32, 78, 156, 249, 209, 238, 89, 32, 78, 215, 204, - 249, 208, 222, 48, 32, 78, 215, 204, 249, 207, 222, 59, 32, 78, 156, 249, - 206, 211, 119, 32, 78, 156, 249, 205, 193, 60, 32, 78, 156, 249, 204, 32, - 78, 215, 204, 249, 203, 250, 213, 32, 78, 215, 204, 249, 202, 216, 159, - 32, 78, 156, 249, 201, 247, 229, 32, 78, 156, 249, 200, 230, 214, 32, 78, - 156, 249, 199, 32, 78, 156, 249, 198, 193, 26, 32, 78, 156, 249, 197, 32, - 78, 156, 249, 196, 32, 78, 156, 249, 195, 228, 156, 32, 78, 156, 249, - 194, 32, 78, 156, 249, 193, 32, 78, 156, 249, 192, 32, 78, 215, 204, 249, - 190, 197, 52, 32, 78, 156, 249, 189, 32, 78, 156, 249, 188, 32, 78, 156, - 249, 187, 242, 165, 32, 78, 156, 249, 186, 32, 78, 156, 249, 185, 32, 78, - 156, 249, 184, 231, 159, 32, 78, 156, 249, 183, 250, 198, 32, 78, 156, - 249, 182, 32, 78, 156, 249, 181, 32, 78, 156, 249, 180, 32, 78, 156, 249, - 179, 32, 78, 156, 249, 178, 32, 78, 156, 249, 177, 32, 78, 156, 249, 176, - 32, 78, 156, 249, 175, 32, 78, 156, 249, 174, 32, 78, 156, 249, 173, 215, - 196, 32, 78, 156, 249, 172, 32, 78, 156, 249, 171, 197, 250, 32, 78, 156, - 249, 170, 32, 78, 156, 249, 169, 32, 78, 156, 249, 168, 32, 78, 156, 249, - 167, 32, 78, 156, 249, 166, 32, 78, 156, 249, 165, 32, 78, 156, 249, 164, - 32, 78, 156, 249, 163, 32, 78, 156, 249, 162, 32, 78, 156, 249, 161, 32, - 78, 156, 249, 160, 32, 78, 156, 249, 159, 229, 168, 32, 78, 156, 249, - 138, 232, 116, 32, 78, 156, 249, 135, 249, 9, 32, 78, 156, 249, 130, 201, - 227, 32, 78, 156, 249, 129, 55, 32, 78, 156, 249, 128, 32, 78, 156, 249, - 127, 200, 127, 32, 78, 156, 249, 126, 32, 78, 156, 249, 125, 32, 78, 156, - 249, 124, 193, 88, 243, 90, 32, 78, 156, 249, 123, 243, 90, 32, 78, 156, - 249, 122, 243, 91, 232, 75, 32, 78, 156, 249, 121, 193, 91, 32, 78, 156, - 249, 120, 32, 78, 156, 249, 119, 32, 78, 215, 204, 249, 118, 236, 190, - 32, 78, 156, 249, 117, 32, 78, 156, 249, 116, 32, 78, 156, 249, 114, 32, - 78, 156, 249, 113, 32, 78, 156, 249, 112, 32, 78, 156, 249, 111, 237, - 173, 32, 78, 156, 249, 110, 32, 78, 156, 249, 109, 32, 78, 156, 249, 108, - 32, 78, 156, 249, 107, 32, 78, 156, 249, 106, 32, 78, 156, 195, 79, 249, - 191, 32, 78, 156, 195, 79, 249, 158, 32, 78, 156, 195, 79, 249, 157, 32, - 78, 156, 195, 79, 249, 156, 32, 78, 156, 195, 79, 249, 155, 32, 78, 156, - 195, 79, 249, 154, 32, 78, 156, 195, 79, 249, 153, 32, 78, 156, 195, 79, - 249, 152, 32, 78, 156, 195, 79, 249, 151, 32, 78, 156, 195, 79, 249, 150, - 32, 78, 156, 195, 79, 249, 149, 32, 78, 156, 195, 79, 249, 148, 32, 78, - 156, 195, 79, 249, 147, 32, 78, 156, 195, 79, 249, 146, 32, 78, 156, 195, - 79, 249, 145, 32, 78, 156, 195, 79, 249, 144, 32, 78, 156, 195, 79, 249, - 143, 32, 78, 156, 195, 79, 249, 142, 32, 78, 156, 195, 79, 249, 141, 32, - 78, 156, 195, 79, 249, 140, 32, 78, 156, 195, 79, 249, 139, 32, 78, 156, - 195, 79, 249, 137, 32, 78, 156, 195, 79, 249, 136, 32, 78, 156, 195, 79, - 249, 134, 32, 78, 156, 195, 79, 249, 133, 32, 78, 156, 195, 79, 249, 132, - 32, 78, 156, 195, 79, 249, 131, 32, 78, 156, 195, 79, 249, 115, 32, 78, - 156, 195, 79, 249, 105, 251, 222, 193, 23, 204, 6, 219, 88, 251, 222, - 193, 23, 204, 6, 236, 96, 251, 222, 243, 78, 77, 251, 222, 31, 108, 251, - 222, 31, 109, 251, 222, 31, 139, 251, 222, 31, 137, 251, 222, 31, 153, - 251, 222, 31, 173, 251, 222, 31, 181, 251, 222, 31, 176, 251, 222, 31, - 184, 251, 222, 31, 199, 90, 251, 222, 31, 197, 28, 251, 222, 31, 198, - 244, 251, 222, 31, 232, 97, 251, 222, 31, 232, 230, 251, 222, 31, 202, - 115, 251, 222, 31, 203, 236, 251, 222, 31, 234, 110, 251, 222, 31, 213, - 156, 251, 222, 31, 91, 228, 109, 251, 222, 31, 103, 228, 109, 251, 222, - 31, 115, 228, 109, 251, 222, 31, 232, 90, 228, 109, 251, 222, 31, 232, - 185, 228, 109, 251, 222, 31, 202, 131, 228, 109, 251, 222, 31, 203, 242, - 228, 109, 251, 222, 31, 234, 121, 228, 109, 251, 222, 31, 213, 161, 228, - 109, 251, 222, 31, 91, 188, 251, 222, 31, 103, 188, 251, 222, 31, 115, - 188, 251, 222, 31, 232, 90, 188, 251, 222, 31, 232, 185, 188, 251, 222, - 31, 202, 131, 188, 251, 222, 31, 203, 242, 188, 251, 222, 31, 234, 121, - 188, 251, 222, 31, 213, 161, 188, 251, 222, 31, 199, 91, 188, 251, 222, - 31, 197, 29, 188, 251, 222, 31, 198, 245, 188, 251, 222, 31, 232, 98, - 188, 251, 222, 31, 232, 231, 188, 251, 222, 31, 202, 116, 188, 251, 222, - 31, 203, 237, 188, 251, 222, 31, 234, 111, 188, 251, 222, 31, 213, 157, - 188, 251, 222, 193, 108, 249, 25, 196, 86, 251, 222, 193, 108, 232, 197, - 200, 219, 251, 222, 193, 108, 205, 52, 200, 219, 251, 222, 193, 108, 198, - 252, 200, 219, 251, 222, 193, 108, 232, 83, 200, 219, 251, 222, 235, 48, - 216, 209, 232, 197, 200, 219, 251, 222, 219, 69, 216, 209, 232, 197, 200, - 219, 251, 222, 216, 209, 205, 52, 200, 219, 251, 222, 216, 209, 198, 252, - 200, 219, 35, 251, 254, 250, 115, 91, 208, 17, 35, 251, 254, 250, 115, - 91, 230, 37, 35, 251, 254, 250, 115, 91, 235, 71, 35, 251, 254, 250, 115, - 153, 35, 251, 254, 250, 115, 232, 230, 35, 251, 254, 250, 115, 232, 185, - 228, 109, 35, 251, 254, 250, 115, 232, 185, 188, 35, 251, 254, 250, 115, - 232, 231, 188, 35, 251, 254, 250, 115, 232, 185, 199, 198, 35, 251, 254, - 250, 115, 199, 91, 199, 198, 35, 251, 254, 250, 115, 232, 231, 199, 198, - 35, 251, 254, 250, 115, 91, 228, 110, 199, 198, 35, 251, 254, 250, 115, - 232, 185, 228, 110, 199, 198, 35, 251, 254, 250, 115, 91, 198, 225, 199, - 198, 35, 251, 254, 250, 115, 232, 185, 198, 225, 199, 198, 35, 251, 254, - 250, 115, 232, 185, 201, 89, 35, 251, 254, 250, 115, 199, 91, 201, 89, - 35, 251, 254, 250, 115, 232, 231, 201, 89, 35, 251, 254, 250, 115, 91, - 228, 110, 201, 89, 35, 251, 254, 250, 115, 232, 185, 228, 110, 201, 89, - 35, 251, 254, 250, 115, 91, 198, 225, 201, 89, 35, 251, 254, 250, 115, - 199, 91, 198, 225, 201, 89, 35, 251, 254, 250, 115, 232, 231, 198, 225, - 201, 89, 35, 251, 254, 250, 115, 199, 91, 215, 254, 35, 251, 254, 229, - 162, 91, 209, 84, 35, 251, 254, 199, 12, 108, 35, 251, 254, 229, 158, - 108, 35, 251, 254, 234, 9, 109, 35, 251, 254, 199, 12, 109, 35, 251, 254, - 238, 85, 103, 235, 70, 35, 251, 254, 234, 9, 103, 235, 70, 35, 251, 254, - 197, 212, 153, 35, 251, 254, 197, 212, 199, 90, 35, 251, 254, 197, 212, - 199, 91, 251, 106, 20, 35, 251, 254, 229, 158, 199, 90, 35, 251, 254, - 216, 148, 199, 90, 35, 251, 254, 199, 12, 199, 90, 35, 251, 254, 199, 12, - 198, 244, 35, 251, 254, 197, 212, 232, 230, 35, 251, 254, 197, 212, 232, - 231, 251, 106, 20, 35, 251, 254, 229, 158, 232, 230, 35, 251, 254, 199, - 12, 232, 230, 35, 251, 254, 199, 12, 91, 228, 109, 35, 251, 254, 199, 12, - 115, 228, 109, 35, 251, 254, 234, 9, 232, 185, 228, 109, 35, 251, 254, - 197, 212, 232, 185, 228, 109, 35, 251, 254, 199, 12, 232, 185, 228, 109, - 35, 251, 254, 247, 34, 232, 185, 228, 109, 35, 251, 254, 214, 185, 232, - 185, 228, 109, 35, 251, 254, 199, 12, 91, 188, 35, 251, 254, 199, 12, - 232, 185, 188, 35, 251, 254, 237, 64, 232, 185, 215, 254, 35, 251, 254, - 201, 42, 232, 231, 215, 254, 35, 91, 134, 57, 35, 91, 134, 3, 251, 106, - 20, 35, 103, 198, 249, 57, 35, 115, 208, 16, 57, 35, 192, 78, 57, 35, - 199, 199, 57, 35, 235, 72, 57, 35, 211, 157, 57, 35, 103, 211, 156, 57, - 35, 115, 211, 156, 57, 35, 232, 90, 211, 156, 57, 35, 232, 185, 211, 156, - 57, 35, 216, 142, 57, 35, 220, 127, 249, 25, 57, 35, 219, 61, 57, 35, - 211, 6, 57, 35, 192, 211, 57, 35, 250, 176, 57, 35, 250, 193, 57, 35, - 230, 186, 57, 35, 197, 167, 249, 25, 57, 35, 191, 78, 57, 35, 91, 208, - 18, 57, 35, 202, 157, 57, 35, 223, 115, 57, 213, 19, 57, 206, 131, 203, - 232, 57, 206, 131, 196, 102, 57, 206, 131, 204, 12, 57, 206, 131, 203, - 170, 57, 206, 131, 236, 205, 203, 170, 57, 206, 131, 202, 181, 57, 206, - 131, 237, 59, 57, 206, 131, 208, 0, 57, 206, 131, 203, 249, 57, 206, 131, - 235, 23, 57, 206, 131, 250, 170, 57, 206, 131, 246, 225, 57, 250, 161, - 113, 35, 16, 199, 162, 206, 254, 209, 214, 236, 182, 3, 210, 42, 209, - 214, 236, 182, 3, 209, 76, 229, 203, 209, 214, 236, 182, 3, 199, 165, - 229, 203, 209, 214, 236, 182, 3, 247, 57, 209, 214, 236, 182, 3, 243, 38, - 209, 214, 236, 182, 3, 193, 35, 209, 214, 236, 182, 3, 229, 168, 209, - 214, 236, 182, 3, 231, 151, 209, 214, 236, 182, 3, 198, 179, 209, 214, - 236, 182, 3, 55, 209, 214, 236, 182, 3, 248, 21, 209, 214, 236, 182, 3, - 203, 73, 209, 214, 236, 182, 3, 242, 158, 209, 214, 236, 182, 3, 217, 69, - 209, 214, 236, 182, 3, 217, 7, 209, 214, 236, 182, 3, 205, 103, 209, 214, - 236, 182, 3, 219, 117, 209, 214, 236, 182, 3, 248, 44, 209, 214, 236, - 182, 3, 247, 41, 209, 93, 209, 214, 236, 182, 3, 236, 111, 209, 214, 236, - 182, 3, 242, 32, 209, 214, 236, 182, 3, 202, 78, 209, 214, 236, 182, 3, - 242, 33, 209, 214, 236, 182, 3, 248, 204, 209, 214, 236, 182, 3, 203, 60, - 209, 214, 236, 182, 3, 228, 156, 209, 214, 236, 182, 3, 229, 116, 209, - 214, 236, 182, 3, 247, 197, 219, 188, 209, 214, 236, 182, 3, 247, 30, - 209, 214, 236, 182, 3, 207, 137, 209, 214, 236, 182, 3, 234, 170, 209, - 214, 236, 182, 3, 235, 80, 209, 214, 236, 182, 3, 197, 68, 209, 214, 236, - 182, 3, 248, 207, 209, 214, 236, 182, 3, 209, 94, 197, 250, 209, 214, - 236, 182, 3, 195, 44, 209, 214, 236, 182, 3, 210, 122, 209, 214, 236, - 182, 3, 206, 120, 209, 214, 236, 182, 3, 219, 101, 209, 214, 236, 182, 3, - 210, 238, 249, 96, 209, 214, 236, 182, 3, 232, 142, 209, 214, 236, 182, - 3, 230, 178, 209, 214, 236, 182, 3, 201, 45, 209, 214, 236, 182, 3, 2, - 250, 82, 209, 214, 236, 182, 3, 193, 133, 249, 47, 209, 214, 236, 182, 3, - 33, 211, 159, 105, 218, 160, 1, 65, 218, 160, 1, 73, 218, 160, 1, 250, - 70, 218, 160, 1, 248, 154, 218, 160, 1, 232, 14, 218, 160, 1, 238, 80, - 218, 160, 1, 70, 218, 160, 1, 193, 221, 218, 160, 1, 191, 166, 218, 160, - 1, 199, 46, 218, 160, 1, 223, 7, 218, 160, 1, 222, 125, 218, 160, 1, 208, - 97, 218, 160, 1, 170, 218, 160, 1, 218, 147, 218, 160, 1, 215, 47, 218, - 160, 1, 216, 0, 218, 160, 1, 213, 67, 218, 160, 1, 69, 218, 160, 1, 210, - 226, 218, 160, 1, 221, 78, 218, 160, 1, 148, 218, 160, 1, 206, 3, 218, - 160, 1, 200, 39, 218, 160, 1, 197, 131, 218, 160, 1, 251, 81, 218, 160, - 1, 234, 61, 218, 160, 1, 230, 83, 218, 160, 1, 192, 235, 247, 47, 1, 65, - 247, 47, 1, 210, 212, 247, 47, 1, 238, 80, 247, 47, 1, 170, 247, 47, 1, - 196, 24, 247, 47, 1, 148, 247, 47, 1, 219, 218, 247, 47, 1, 254, 163, - 247, 47, 1, 208, 97, 247, 47, 1, 250, 70, 247, 47, 1, 218, 147, 247, 47, - 1, 74, 247, 47, 1, 237, 243, 247, 47, 1, 200, 39, 247, 47, 1, 203, 162, - 247, 47, 1, 203, 161, 247, 47, 1, 206, 3, 247, 47, 1, 247, 144, 247, 47, - 1, 69, 247, 47, 1, 213, 67, 247, 47, 1, 192, 235, 247, 47, 1, 215, 47, - 247, 47, 1, 197, 130, 247, 47, 1, 210, 226, 247, 47, 1, 201, 173, 247, - 47, 1, 70, 247, 47, 1, 73, 247, 47, 1, 196, 21, 247, 47, 1, 222, 125, - 247, 47, 1, 222, 116, 247, 47, 1, 214, 150, 247, 47, 1, 196, 26, 247, 47, - 1, 232, 14, 247, 47, 1, 231, 205, 247, 47, 1, 201, 113, 247, 47, 1, 201, - 112, 247, 47, 1, 214, 56, 247, 47, 1, 223, 170, 247, 47, 1, 247, 143, - 247, 47, 1, 197, 131, 247, 47, 1, 196, 23, 247, 47, 1, 206, 105, 247, 47, - 1, 216, 253, 247, 47, 1, 216, 252, 247, 47, 1, 216, 251, 247, 47, 1, 216, - 250, 247, 47, 1, 219, 217, 247, 47, 1, 234, 174, 247, 47, 1, 196, 22, 93, - 234, 12, 198, 224, 77, 93, 234, 12, 17, 108, 93, 234, 12, 17, 109, 93, - 234, 12, 17, 139, 93, 234, 12, 17, 137, 93, 234, 12, 17, 153, 93, 234, - 12, 17, 173, 93, 234, 12, 17, 181, 93, 234, 12, 17, 176, 93, 234, 12, 17, - 184, 93, 234, 12, 31, 199, 90, 93, 234, 12, 31, 197, 28, 93, 234, 12, 31, - 198, 244, 93, 234, 12, 31, 232, 97, 93, 234, 12, 31, 232, 230, 93, 234, - 12, 31, 202, 115, 93, 234, 12, 31, 203, 236, 93, 234, 12, 31, 234, 110, - 93, 234, 12, 31, 213, 156, 93, 234, 12, 31, 91, 228, 109, 93, 234, 12, - 31, 103, 228, 109, 93, 234, 12, 31, 115, 228, 109, 93, 234, 12, 31, 232, - 90, 228, 109, 93, 234, 12, 31, 232, 185, 228, 109, 93, 234, 12, 31, 202, - 131, 228, 109, 93, 234, 12, 31, 203, 242, 228, 109, 93, 234, 12, 31, 234, - 121, 228, 109, 93, 234, 12, 31, 213, 161, 228, 109, 38, 43, 1, 65, 38, - 43, 1, 248, 223, 38, 43, 1, 221, 253, 38, 43, 1, 237, 101, 38, 43, 1, 73, - 38, 43, 1, 195, 150, 38, 43, 1, 191, 87, 38, 43, 1, 229, 213, 38, 43, 1, - 199, 28, 38, 43, 1, 70, 38, 43, 1, 157, 38, 43, 1, 234, 97, 38, 43, 1, - 234, 72, 38, 43, 1, 234, 61, 38, 43, 1, 233, 226, 38, 43, 1, 74, 38, 43, - 1, 210, 53, 38, 43, 1, 203, 108, 38, 43, 1, 220, 208, 38, 43, 1, 233, - 248, 38, 43, 1, 233, 236, 38, 43, 1, 199, 140, 38, 43, 1, 69, 38, 43, 1, - 234, 100, 38, 43, 1, 209, 205, 38, 43, 1, 221, 173, 38, 43, 1, 234, 138, - 38, 43, 1, 233, 238, 38, 43, 1, 243, 79, 38, 43, 1, 223, 170, 38, 43, 1, - 196, 26, 38, 43, 1, 233, 219, 38, 43, 212, 121, 108, 38, 43, 212, 121, - 153, 38, 43, 212, 121, 199, 90, 38, 43, 212, 121, 232, 230, 38, 43, 1, - 192, 80, 38, 43, 1, 213, 3, 197, 157, 38, 43, 1, 201, 251, 197, 157, 230, - 197, 1, 251, 187, 230, 197, 1, 249, 67, 230, 197, 1, 231, 13, 230, 197, - 1, 237, 222, 230, 197, 1, 251, 182, 230, 197, 1, 208, 80, 230, 197, 1, - 223, 20, 230, 197, 1, 230, 50, 230, 197, 1, 198, 238, 230, 197, 1, 234, - 108, 230, 197, 1, 220, 165, 230, 197, 1, 220, 76, 230, 197, 1, 217, 60, - 230, 197, 1, 214, 187, 230, 197, 1, 222, 230, 230, 197, 1, 196, 44, 230, - 197, 1, 210, 185, 230, 197, 1, 213, 156, 230, 197, 1, 207, 150, 230, 197, - 1, 205, 107, 230, 197, 1, 199, 106, 230, 197, 1, 193, 58, 230, 197, 1, - 233, 48, 230, 197, 1, 223, 174, 230, 197, 1, 228, 92, 230, 197, 1, 211, - 19, 230, 197, 1, 213, 161, 228, 109, 38, 209, 249, 1, 251, 81, 38, 209, - 249, 1, 247, 182, 38, 209, 249, 1, 231, 187, 38, 209, 249, 1, 236, 115, - 38, 209, 249, 1, 73, 38, 209, 249, 1, 191, 53, 38, 209, 249, 1, 234, 239, - 38, 209, 249, 1, 191, 95, 38, 209, 249, 1, 234, 237, 38, 209, 249, 1, 70, - 38, 209, 249, 1, 221, 26, 38, 209, 249, 1, 219, 184, 38, 209, 249, 1, - 216, 165, 38, 209, 249, 1, 214, 86, 38, 209, 249, 1, 195, 4, 38, 209, - 249, 1, 210, 39, 38, 209, 249, 1, 207, 65, 38, 209, 249, 1, 202, 188, 38, - 209, 249, 1, 199, 212, 38, 209, 249, 1, 69, 38, 209, 249, 1, 243, 58, 38, - 209, 249, 1, 203, 42, 38, 209, 249, 1, 203, 110, 38, 209, 249, 1, 191, - 227, 38, 209, 249, 1, 192, 58, 38, 209, 249, 1, 74, 38, 209, 249, 1, 211, - 76, 38, 209, 249, 1, 234, 138, 38, 209, 249, 1, 144, 38, 209, 249, 1, - 197, 141, 38, 209, 249, 1, 195, 137, 38, 209, 249, 1, 192, 62, 38, 209, - 249, 1, 192, 60, 38, 209, 249, 1, 192, 95, 38, 209, 249, 1, 223, 197, 38, - 209, 249, 1, 191, 225, 38, 209, 249, 1, 169, 38, 209, 249, 1, 228, 5, 33, - 38, 209, 249, 1, 251, 81, 33, 38, 209, 249, 1, 236, 115, 33, 38, 209, - 249, 1, 191, 95, 33, 38, 209, 249, 1, 214, 86, 33, 38, 209, 249, 1, 202, - 188, 196, 138, 1, 251, 113, 196, 138, 1, 248, 162, 196, 138, 1, 231, 175, - 196, 138, 1, 221, 190, 196, 138, 1, 237, 61, 196, 138, 1, 228, 247, 196, - 138, 1, 193, 48, 196, 138, 1, 191, 76, 196, 138, 1, 228, 148, 196, 138, - 1, 199, 68, 196, 138, 1, 191, 250, 196, 138, 1, 222, 79, 196, 138, 1, - 203, 64, 196, 138, 1, 220, 7, 196, 138, 1, 216, 174, 196, 138, 1, 237, - 19, 196, 138, 1, 212, 117, 196, 138, 1, 190, 251, 196, 138, 1, 205, 142, - 196, 138, 1, 251, 178, 196, 138, 1, 208, 158, 196, 138, 1, 205, 186, 196, - 138, 1, 208, 32, 196, 138, 1, 207, 128, 196, 138, 1, 199, 32, 196, 138, - 1, 231, 49, 196, 138, 1, 159, 196, 138, 1, 70, 196, 138, 1, 69, 196, 138, - 1, 201, 124, 196, 138, 193, 23, 236, 160, 38, 209, 243, 3, 65, 38, 209, - 243, 3, 70, 38, 209, 243, 3, 69, 38, 209, 243, 3, 157, 38, 209, 243, 3, - 220, 208, 38, 209, 243, 3, 231, 203, 38, 209, 243, 3, 230, 146, 38, 209, - 243, 3, 192, 220, 38, 209, 243, 3, 247, 112, 38, 209, 243, 3, 223, 4, 38, - 209, 243, 3, 222, 217, 38, 209, 243, 3, 199, 247, 38, 209, 243, 3, 197, - 90, 38, 209, 243, 3, 237, 241, 38, 209, 243, 3, 236, 255, 38, 209, 243, - 3, 235, 45, 38, 209, 243, 3, 199, 44, 38, 209, 243, 3, 168, 38, 209, 243, - 3, 249, 103, 38, 209, 243, 3, 233, 68, 38, 209, 243, 3, 180, 38, 209, - 243, 3, 212, 165, 38, 209, 243, 3, 172, 38, 209, 243, 3, 216, 81, 38, - 209, 243, 3, 215, 139, 38, 209, 243, 3, 169, 38, 209, 243, 3, 195, 185, - 38, 209, 243, 3, 195, 66, 38, 209, 243, 3, 166, 38, 209, 243, 3, 206, 63, - 38, 209, 243, 3, 171, 38, 209, 243, 3, 189, 38, 209, 243, 3, 191, 123, - 38, 209, 243, 3, 203, 160, 38, 209, 243, 3, 201, 170, 38, 209, 243, 3, - 144, 38, 209, 243, 3, 250, 107, 38, 209, 243, 3, 250, 106, 38, 209, 243, - 3, 250, 105, 38, 209, 243, 3, 192, 189, 38, 209, 243, 3, 237, 218, 38, - 209, 243, 3, 237, 217, 38, 209, 243, 3, 249, 78, 38, 209, 243, 3, 247, - 164, 38, 209, 243, 193, 23, 236, 160, 38, 209, 243, 31, 108, 38, 209, - 243, 31, 109, 38, 209, 243, 31, 199, 90, 38, 209, 243, 31, 197, 28, 38, - 209, 243, 31, 228, 109, 237, 39, 6, 1, 177, 70, 237, 39, 6, 1, 177, 73, - 237, 39, 6, 1, 177, 65, 237, 39, 6, 1, 177, 251, 193, 237, 39, 6, 1, 177, - 74, 237, 39, 6, 1, 177, 211, 76, 237, 39, 6, 1, 203, 35, 70, 237, 39, 6, - 1, 203, 35, 73, 237, 39, 6, 1, 203, 35, 65, 237, 39, 6, 1, 203, 35, 251, - 193, 237, 39, 6, 1, 203, 35, 74, 237, 39, 6, 1, 203, 35, 211, 76, 237, - 39, 6, 1, 250, 81, 237, 39, 6, 1, 210, 240, 237, 39, 6, 1, 193, 0, 237, - 39, 6, 1, 192, 77, 237, 39, 6, 1, 230, 83, 237, 39, 6, 1, 210, 40, 237, - 39, 6, 1, 248, 207, 237, 39, 6, 1, 199, 116, 237, 39, 6, 1, 237, 86, 237, - 39, 6, 1, 243, 75, 237, 39, 6, 1, 222, 236, 237, 39, 6, 1, 222, 4, 237, - 39, 6, 1, 231, 149, 237, 39, 6, 1, 234, 138, 237, 39, 6, 1, 195, 145, - 237, 39, 6, 1, 233, 206, 237, 39, 6, 1, 199, 26, 237, 39, 6, 1, 233, 236, - 237, 39, 6, 1, 191, 84, 237, 39, 6, 1, 233, 226, 237, 39, 6, 1, 191, 61, - 237, 39, 6, 1, 233, 248, 237, 39, 6, 1, 234, 97, 237, 39, 6, 1, 234, 72, - 237, 39, 6, 1, 234, 61, 237, 39, 6, 1, 234, 46, 237, 39, 6, 1, 211, 121, - 237, 39, 6, 1, 233, 183, 237, 39, 2, 1, 177, 70, 237, 39, 2, 1, 177, 73, - 237, 39, 2, 1, 177, 65, 237, 39, 2, 1, 177, 251, 193, 237, 39, 2, 1, 177, - 74, 237, 39, 2, 1, 177, 211, 76, 237, 39, 2, 1, 203, 35, 70, 237, 39, 2, - 1, 203, 35, 73, 237, 39, 2, 1, 203, 35, 65, 237, 39, 2, 1, 203, 35, 251, - 193, 237, 39, 2, 1, 203, 35, 74, 237, 39, 2, 1, 203, 35, 211, 76, 237, - 39, 2, 1, 250, 81, 237, 39, 2, 1, 210, 240, 237, 39, 2, 1, 193, 0, 237, - 39, 2, 1, 192, 77, 237, 39, 2, 1, 230, 83, 237, 39, 2, 1, 210, 40, 237, - 39, 2, 1, 248, 207, 237, 39, 2, 1, 199, 116, 237, 39, 2, 1, 237, 86, 237, - 39, 2, 1, 243, 75, 237, 39, 2, 1, 222, 236, 237, 39, 2, 1, 222, 4, 237, - 39, 2, 1, 231, 149, 237, 39, 2, 1, 234, 138, 237, 39, 2, 1, 195, 145, - 237, 39, 2, 1, 233, 206, 237, 39, 2, 1, 199, 26, 237, 39, 2, 1, 233, 236, - 237, 39, 2, 1, 191, 84, 237, 39, 2, 1, 233, 226, 237, 39, 2, 1, 191, 61, - 237, 39, 2, 1, 233, 248, 237, 39, 2, 1, 234, 97, 237, 39, 2, 1, 234, 72, - 237, 39, 2, 1, 234, 61, 237, 39, 2, 1, 234, 46, 237, 39, 2, 1, 211, 121, - 237, 39, 2, 1, 233, 183, 203, 115, 1, 210, 36, 203, 115, 1, 198, 35, 203, - 115, 1, 221, 130, 203, 115, 1, 233, 11, 203, 115, 1, 199, 1, 203, 115, 1, - 202, 41, 203, 115, 1, 200, 167, 203, 115, 1, 242, 248, 203, 115, 1, 192, - 79, 203, 115, 1, 228, 106, 203, 115, 1, 248, 139, 203, 115, 1, 237, 100, - 203, 115, 1, 231, 189, 203, 115, 1, 194, 255, 203, 115, 1, 199, 7, 203, - 115, 1, 191, 4, 203, 115, 1, 216, 208, 203, 115, 1, 222, 153, 203, 115, - 1, 193, 39, 203, 115, 1, 230, 60, 203, 115, 1, 219, 1, 203, 115, 1, 216, - 27, 203, 115, 1, 223, 177, 203, 115, 1, 234, 136, 203, 115, 1, 250, 159, - 203, 115, 1, 251, 234, 203, 115, 1, 211, 93, 203, 115, 1, 193, 26, 203, - 115, 1, 211, 4, 203, 115, 1, 251, 193, 203, 115, 1, 206, 148, 203, 115, - 1, 212, 117, 203, 115, 1, 234, 156, 203, 115, 1, 251, 198, 203, 115, 1, - 227, 252, 203, 115, 1, 196, 73, 203, 115, 1, 211, 167, 203, 115, 1, 211, - 68, 203, 115, 1, 211, 119, 203, 115, 1, 250, 87, 203, 115, 1, 250, 215, - 203, 115, 1, 211, 45, 203, 115, 1, 251, 173, 203, 115, 1, 233, 240, 203, - 115, 1, 250, 190, 203, 115, 1, 234, 167, 203, 115, 1, 228, 4, 203, 115, - 1, 192, 41, 211, 23, 1, 251, 141, 211, 23, 1, 249, 103, 211, 23, 1, 199, - 247, 211, 23, 1, 223, 4, 211, 23, 1, 192, 220, 211, 23, 1, 221, 190, 211, - 23, 1, 237, 85, 211, 23, 1, 166, 211, 23, 1, 189, 211, 23, 1, 203, 70, - 211, 23, 1, 237, 23, 211, 23, 1, 247, 19, 211, 23, 1, 231, 203, 211, 23, - 1, 233, 68, 211, 23, 1, 208, 87, 211, 23, 1, 222, 96, 211, 23, 1, 220, - 97, 211, 23, 1, 216, 41, 211, 23, 1, 212, 101, 211, 23, 1, 193, 131, 211, - 23, 1, 144, 211, 23, 1, 169, 211, 23, 1, 65, 211, 23, 1, 73, 211, 23, 1, - 70, 211, 23, 1, 74, 211, 23, 1, 69, 211, 23, 1, 252, 154, 211, 23, 1, - 234, 145, 211, 23, 1, 211, 76, 211, 23, 17, 191, 77, 211, 23, 17, 108, - 211, 23, 17, 109, 211, 23, 17, 139, 211, 23, 17, 137, 211, 23, 17, 153, - 211, 23, 17, 173, 211, 23, 17, 181, 211, 23, 17, 176, 211, 23, 17, 184, - 211, 25, 6, 1, 65, 211, 25, 6, 1, 251, 184, 211, 25, 6, 1, 251, 178, 211, - 25, 6, 1, 251, 193, 211, 25, 6, 1, 248, 8, 211, 25, 6, 1, 246, 209, 211, - 25, 6, 1, 234, 129, 211, 25, 6, 1, 73, 211, 25, 6, 1, 234, 109, 211, 25, - 6, 1, 144, 211, 25, 6, 1, 228, 62, 211, 25, 6, 1, 70, 211, 25, 6, 1, 157, - 211, 25, 6, 1, 234, 128, 211, 25, 6, 1, 220, 129, 211, 25, 6, 1, 171, - 211, 25, 6, 1, 172, 211, 25, 6, 1, 180, 211, 25, 6, 1, 74, 211, 25, 6, 1, - 211, 118, 211, 25, 6, 1, 168, 211, 25, 6, 1, 234, 127, 211, 25, 6, 1, - 189, 211, 25, 6, 1, 203, 160, 211, 25, 6, 1, 199, 247, 211, 25, 6, 1, - 234, 126, 211, 25, 6, 1, 197, 164, 211, 25, 6, 1, 234, 125, 211, 25, 6, - 1, 197, 153, 211, 25, 6, 1, 237, 23, 211, 25, 6, 1, 69, 211, 25, 6, 1, - 193, 187, 211, 25, 6, 1, 221, 190, 211, 25, 6, 1, 231, 54, 211, 25, 6, 1, - 191, 123, 211, 25, 6, 1, 191, 71, 211, 25, 2, 1, 65, 211, 25, 2, 1, 251, - 184, 211, 25, 2, 1, 251, 178, 211, 25, 2, 1, 251, 193, 211, 25, 2, 1, - 248, 8, 211, 25, 2, 1, 246, 209, 211, 25, 2, 1, 234, 129, 211, 25, 2, 1, - 73, 211, 25, 2, 1, 234, 109, 211, 25, 2, 1, 144, 211, 25, 2, 1, 228, 62, - 211, 25, 2, 1, 70, 211, 25, 2, 1, 157, 211, 25, 2, 1, 234, 128, 211, 25, - 2, 1, 220, 129, 211, 25, 2, 1, 171, 211, 25, 2, 1, 172, 211, 25, 2, 1, - 180, 211, 25, 2, 1, 74, 211, 25, 2, 1, 211, 118, 211, 25, 2, 1, 168, 211, - 25, 2, 1, 234, 127, 211, 25, 2, 1, 189, 211, 25, 2, 1, 203, 160, 211, 25, - 2, 1, 199, 247, 211, 25, 2, 1, 234, 126, 211, 25, 2, 1, 197, 164, 211, - 25, 2, 1, 234, 125, 211, 25, 2, 1, 197, 153, 211, 25, 2, 1, 237, 23, 211, - 25, 2, 1, 69, 211, 25, 2, 1, 193, 187, 211, 25, 2, 1, 221, 190, 211, 25, - 2, 1, 231, 54, 211, 25, 2, 1, 191, 123, 211, 25, 2, 1, 191, 71, 234, 93, - 1, 65, 234, 93, 1, 248, 223, 234, 93, 1, 246, 250, 234, 93, 1, 243, 79, - 234, 93, 1, 237, 101, 234, 93, 1, 214, 140, 234, 93, 1, 237, 14, 234, 93, - 1, 234, 123, 234, 93, 1, 73, 234, 93, 1, 233, 18, 234, 93, 1, 231, 128, - 234, 93, 1, 230, 240, 234, 93, 1, 229, 213, 234, 93, 1, 70, 234, 93, 1, - 222, 238, 234, 93, 1, 221, 253, 234, 93, 1, 219, 214, 234, 93, 1, 219, - 44, 234, 93, 1, 216, 213, 234, 93, 1, 214, 107, 234, 93, 1, 180, 234, 93, - 1, 213, 137, 234, 93, 1, 74, 234, 93, 1, 210, 53, 234, 93, 1, 208, 69, - 234, 93, 1, 207, 108, 234, 93, 1, 206, 99, 234, 93, 1, 205, 63, 234, 93, - 1, 203, 108, 234, 93, 1, 199, 140, 234, 93, 1, 199, 28, 234, 93, 1, 69, - 234, 93, 1, 195, 150, 234, 93, 1, 192, 214, 234, 93, 1, 192, 159, 234, - 93, 1, 191, 87, 234, 93, 1, 191, 62, 234, 93, 1, 231, 40, 234, 93, 1, - 231, 46, 234, 93, 1, 221, 173, 247, 27, 251, 142, 1, 251, 108, 247, 27, - 251, 142, 1, 248, 164, 247, 27, 251, 142, 1, 231, 3, 247, 27, 251, 142, - 1, 237, 166, 247, 27, 251, 142, 1, 234, 155, 247, 27, 251, 142, 1, 191, - 98, 247, 27, 251, 142, 1, 233, 143, 247, 27, 251, 142, 1, 191, 56, 247, - 27, 251, 142, 1, 199, 169, 247, 27, 251, 142, 1, 246, 209, 247, 27, 251, - 142, 1, 191, 236, 247, 27, 251, 142, 1, 191, 71, 247, 27, 251, 142, 1, - 223, 48, 247, 27, 251, 142, 1, 203, 160, 247, 27, 251, 142, 1, 220, 0, - 247, 27, 251, 142, 1, 223, 61, 247, 27, 251, 142, 1, 192, 210, 247, 27, - 251, 142, 1, 234, 255, 247, 27, 251, 142, 1, 247, 54, 247, 27, 251, 142, - 1, 222, 218, 247, 27, 251, 142, 1, 222, 39, 247, 27, 251, 142, 1, 218, - 156, 247, 27, 251, 142, 1, 229, 147, 247, 27, 251, 142, 1, 208, 70, 247, - 27, 251, 142, 1, 251, 17, 247, 27, 251, 142, 1, 243, 9, 247, 27, 251, - 142, 1, 243, 47, 247, 27, 251, 142, 1, 238, 93, 247, 27, 251, 142, 1, - 217, 48, 247, 27, 251, 142, 1, 208, 74, 247, 27, 251, 142, 1, 212, 239, - 247, 27, 251, 142, 1, 234, 232, 247, 27, 251, 142, 1, 203, 142, 247, 27, - 251, 142, 1, 222, 239, 247, 27, 251, 142, 1, 211, 93, 247, 27, 251, 142, - 1, 196, 255, 247, 27, 251, 142, 1, 233, 41, 247, 27, 251, 142, 1, 234, - 245, 247, 27, 251, 142, 1, 243, 85, 247, 27, 251, 142, 1, 210, 25, 247, - 27, 251, 142, 1, 231, 30, 247, 27, 251, 142, 1, 207, 125, 247, 27, 251, - 142, 1, 203, 169, 247, 27, 251, 142, 1, 195, 69, 247, 27, 251, 142, 1, - 198, 113, 247, 27, 251, 142, 1, 203, 13, 247, 27, 251, 142, 1, 223, 18, - 247, 27, 251, 142, 1, 238, 94, 247, 27, 251, 142, 1, 247, 19, 247, 27, - 251, 142, 1, 192, 84, 247, 27, 251, 142, 1, 209, 106, 247, 27, 251, 142, - 1, 221, 93, 247, 27, 251, 142, 242, 206, 77, 195, 26, 6, 1, 65, 195, 26, - 6, 1, 248, 254, 195, 26, 6, 1, 248, 223, 195, 26, 6, 1, 246, 250, 195, - 26, 6, 1, 243, 79, 195, 26, 6, 1, 237, 101, 195, 26, 6, 1, 237, 14, 195, - 26, 6, 1, 234, 123, 195, 26, 6, 1, 73, 195, 26, 6, 1, 233, 18, 195, 26, - 6, 1, 231, 203, 195, 26, 6, 1, 144, 195, 26, 6, 1, 229, 145, 195, 26, 6, - 1, 70, 195, 26, 6, 1, 223, 167, 195, 26, 6, 1, 222, 238, 195, 26, 6, 1, - 157, 195, 26, 6, 1, 171, 195, 26, 6, 1, 219, 49, 195, 26, 6, 1, 216, 213, - 195, 26, 6, 1, 214, 107, 195, 26, 6, 1, 213, 137, 195, 26, 6, 1, 74, 195, - 26, 6, 1, 210, 53, 195, 26, 6, 1, 208, 89, 195, 26, 6, 1, 207, 108, 195, - 26, 6, 1, 205, 63, 195, 26, 6, 1, 203, 108, 195, 26, 6, 1, 199, 140, 195, - 26, 6, 1, 199, 28, 195, 26, 6, 1, 69, 195, 26, 6, 1, 195, 150, 195, 26, - 6, 1, 192, 214, 195, 26, 6, 1, 192, 159, 195, 26, 6, 1, 191, 87, 195, 26, - 2, 1, 65, 195, 26, 2, 1, 248, 254, 195, 26, 2, 1, 248, 223, 195, 26, 2, - 1, 246, 250, 195, 26, 2, 1, 243, 79, 195, 26, 2, 1, 237, 101, 195, 26, 2, - 1, 237, 14, 195, 26, 2, 1, 234, 123, 195, 26, 2, 1, 73, 195, 26, 2, 1, - 233, 18, 195, 26, 2, 1, 231, 203, 195, 26, 2, 1, 144, 195, 26, 2, 1, 229, - 145, 195, 26, 2, 1, 70, 195, 26, 2, 1, 223, 167, 195, 26, 2, 1, 222, 238, - 195, 26, 2, 1, 157, 195, 26, 2, 1, 171, 195, 26, 2, 1, 219, 49, 195, 26, - 2, 1, 216, 213, 195, 26, 2, 1, 214, 107, 195, 26, 2, 1, 213, 137, 195, - 26, 2, 1, 74, 195, 26, 2, 1, 210, 53, 195, 26, 2, 1, 208, 89, 195, 26, 2, - 1, 207, 108, 195, 26, 2, 1, 205, 63, 195, 26, 2, 1, 203, 108, 195, 26, 2, - 1, 199, 140, 195, 26, 2, 1, 199, 28, 195, 26, 2, 1, 69, 195, 26, 2, 1, - 195, 150, 195, 26, 2, 1, 192, 214, 195, 26, 2, 1, 192, 159, 195, 26, 2, - 1, 191, 87, 32, 41, 3, 252, 102, 32, 41, 3, 252, 101, 32, 41, 3, 252, - 100, 32, 41, 3, 252, 99, 32, 41, 3, 252, 98, 32, 41, 3, 252, 97, 32, 41, - 3, 252, 96, 32, 41, 3, 252, 95, 32, 41, 3, 252, 94, 32, 41, 3, 252, 93, - 32, 41, 3, 252, 92, 32, 41, 3, 252, 91, 32, 41, 3, 252, 90, 32, 41, 3, - 252, 89, 32, 41, 3, 252, 88, 32, 41, 3, 252, 87, 32, 41, 3, 252, 86, 32, - 41, 3, 252, 85, 32, 41, 3, 252, 84, 32, 41, 3, 252, 83, 32, 41, 3, 252, - 82, 32, 41, 3, 252, 81, 32, 41, 3, 252, 80, 32, 41, 3, 252, 79, 32, 41, - 3, 252, 78, 32, 41, 3, 252, 77, 32, 41, 3, 252, 76, 32, 41, 3, 255, 112, - 32, 41, 3, 252, 75, 32, 41, 3, 252, 74, 32, 41, 3, 252, 73, 32, 41, 3, - 252, 72, 32, 41, 3, 252, 71, 32, 41, 3, 252, 70, 32, 41, 3, 252, 69, 32, - 41, 3, 252, 68, 32, 41, 3, 252, 67, 32, 41, 3, 252, 66, 32, 41, 3, 252, - 65, 32, 41, 3, 252, 64, 32, 41, 3, 252, 63, 32, 41, 3, 252, 62, 32, 41, - 3, 252, 61, 32, 41, 3, 252, 60, 32, 41, 3, 252, 59, 32, 41, 3, 252, 58, - 32, 41, 3, 252, 57, 32, 41, 3, 252, 56, 32, 41, 3, 252, 55, 32, 41, 3, - 252, 54, 32, 41, 3, 252, 53, 32, 41, 3, 252, 52, 32, 41, 3, 252, 51, 32, - 41, 3, 252, 50, 32, 41, 3, 252, 49, 32, 41, 3, 252, 48, 32, 41, 3, 252, - 47, 32, 41, 3, 252, 46, 32, 41, 3, 252, 45, 32, 41, 3, 252, 44, 32, 41, - 3, 252, 43, 32, 41, 3, 252, 42, 32, 41, 3, 252, 41, 32, 41, 3, 252, 40, - 32, 41, 3, 252, 39, 32, 41, 3, 252, 38, 32, 41, 3, 252, 37, 32, 41, 3, - 252, 36, 32, 41, 3, 252, 35, 32, 41, 3, 252, 34, 32, 41, 3, 252, 33, 32, - 41, 3, 255, 25, 32, 41, 3, 252, 32, 32, 41, 3, 252, 31, 32, 41, 3, 254, - 246, 32, 41, 3, 252, 30, 32, 41, 3, 252, 29, 32, 41, 3, 252, 28, 32, 41, - 3, 252, 27, 32, 41, 3, 254, 233, 32, 41, 3, 252, 26, 32, 41, 3, 252, 25, - 32, 41, 3, 252, 24, 32, 41, 3, 252, 23, 32, 41, 3, 252, 22, 32, 41, 3, - 254, 49, 32, 41, 3, 254, 48, 32, 41, 3, 254, 47, 32, 41, 3, 254, 46, 32, - 41, 3, 254, 45, 32, 41, 3, 254, 44, 32, 41, 3, 254, 43, 32, 41, 3, 254, - 42, 32, 41, 3, 254, 40, 32, 41, 3, 254, 39, 32, 41, 3, 254, 38, 32, 41, - 3, 254, 37, 32, 41, 3, 254, 36, 32, 41, 3, 254, 35, 32, 41, 3, 254, 33, - 32, 41, 3, 254, 32, 32, 41, 3, 254, 31, 32, 41, 3, 254, 30, 32, 41, 3, - 254, 29, 32, 41, 3, 254, 28, 32, 41, 3, 254, 27, 32, 41, 3, 254, 26, 32, - 41, 3, 254, 25, 32, 41, 3, 254, 24, 32, 41, 3, 254, 23, 32, 41, 3, 254, - 22, 32, 41, 3, 254, 21, 32, 41, 3, 254, 20, 32, 41, 3, 254, 19, 32, 41, - 3, 254, 18, 32, 41, 3, 254, 17, 32, 41, 3, 254, 16, 32, 41, 3, 254, 15, - 32, 41, 3, 254, 13, 32, 41, 3, 254, 12, 32, 41, 3, 254, 11, 32, 41, 3, - 254, 7, 32, 41, 3, 254, 6, 32, 41, 3, 254, 5, 32, 41, 3, 254, 4, 32, 41, - 3, 254, 0, 32, 41, 3, 253, 255, 32, 41, 3, 253, 254, 32, 41, 3, 253, 253, - 32, 41, 3, 253, 252, 32, 41, 3, 253, 251, 32, 41, 3, 253, 250, 32, 41, 3, - 253, 249, 32, 41, 3, 253, 248, 32, 41, 3, 253, 247, 32, 41, 3, 253, 246, - 32, 41, 3, 253, 245, 32, 41, 3, 253, 244, 32, 41, 3, 253, 243, 32, 41, 3, - 253, 242, 32, 41, 3, 253, 241, 32, 41, 3, 253, 240, 32, 41, 3, 253, 239, - 32, 41, 3, 253, 238, 32, 41, 3, 253, 237, 32, 41, 3, 253, 236, 32, 41, 3, - 253, 235, 32, 41, 3, 253, 234, 32, 41, 3, 253, 232, 32, 41, 3, 253, 231, - 32, 41, 3, 253, 230, 32, 41, 3, 253, 229, 32, 41, 3, 253, 228, 32, 41, 3, - 253, 226, 32, 41, 3, 253, 225, 32, 41, 3, 253, 224, 32, 41, 3, 253, 223, - 32, 41, 3, 253, 221, 32, 41, 3, 253, 220, 32, 41, 3, 253, 219, 32, 41, 3, - 253, 185, 32, 41, 3, 253, 183, 32, 41, 3, 253, 181, 32, 41, 3, 253, 179, - 32, 41, 3, 253, 177, 32, 41, 3, 253, 175, 32, 41, 3, 253, 173, 32, 41, 3, - 253, 171, 32, 41, 3, 253, 169, 32, 41, 3, 253, 167, 32, 41, 3, 253, 165, - 32, 41, 3, 253, 162, 32, 41, 3, 253, 160, 32, 41, 3, 253, 158, 32, 41, 3, - 253, 156, 32, 41, 3, 253, 154, 32, 41, 3, 253, 152, 32, 41, 3, 253, 150, - 32, 41, 3, 253, 148, 32, 41, 3, 253, 66, 32, 41, 3, 253, 65, 32, 41, 3, - 253, 64, 32, 41, 3, 253, 63, 32, 41, 3, 253, 62, 32, 41, 3, 253, 61, 32, - 41, 3, 253, 59, 32, 41, 3, 253, 58, 32, 41, 3, 253, 57, 32, 41, 3, 253, - 56, 32, 41, 3, 253, 55, 32, 41, 3, 253, 54, 32, 41, 3, 253, 52, 32, 41, - 3, 253, 51, 32, 41, 3, 253, 47, 32, 41, 3, 253, 46, 32, 41, 3, 253, 44, - 32, 41, 3, 253, 43, 32, 41, 3, 253, 42, 32, 41, 3, 253, 41, 32, 41, 3, - 253, 40, 32, 41, 3, 253, 39, 32, 41, 3, 253, 38, 32, 41, 3, 253, 37, 32, - 41, 3, 253, 36, 32, 41, 3, 253, 35, 32, 41, 3, 253, 34, 32, 41, 3, 253, - 33, 32, 41, 3, 253, 32, 32, 41, 3, 253, 31, 32, 41, 3, 253, 30, 32, 41, - 3, 253, 29, 32, 41, 3, 253, 28, 32, 41, 3, 253, 27, 32, 41, 3, 253, 26, - 32, 41, 3, 253, 25, 32, 41, 3, 253, 24, 32, 41, 3, 253, 23, 32, 41, 3, - 253, 22, 32, 41, 3, 253, 21, 32, 41, 3, 253, 20, 32, 41, 3, 253, 19, 32, - 41, 3, 253, 18, 32, 41, 3, 253, 17, 32, 41, 3, 253, 16, 32, 41, 3, 253, - 15, 32, 41, 3, 253, 14, 32, 41, 3, 253, 13, 32, 41, 3, 253, 12, 32, 41, - 3, 253, 11, 32, 41, 3, 253, 10, 32, 41, 3, 253, 9, 32, 41, 3, 253, 8, 32, - 41, 3, 253, 7, 32, 41, 3, 253, 6, 32, 41, 3, 253, 5, 32, 41, 3, 253, 4, - 32, 41, 3, 253, 3, 32, 41, 3, 253, 2, 32, 41, 3, 253, 1, 32, 41, 3, 253, - 0, 32, 41, 3, 252, 255, 32, 41, 3, 252, 254, 32, 41, 3, 252, 253, 32, 41, - 3, 252, 252, 32, 41, 3, 252, 251, 32, 41, 3, 252, 250, 32, 41, 3, 252, - 249, 32, 41, 3, 252, 248, 32, 41, 3, 252, 247, 32, 41, 3, 252, 246, 32, - 41, 3, 252, 245, 32, 41, 3, 252, 244, 32, 41, 3, 252, 243, 32, 41, 3, - 252, 242, 32, 41, 3, 252, 241, 32, 41, 3, 252, 240, 32, 41, 3, 252, 239, - 32, 41, 3, 252, 238, 32, 41, 3, 252, 237, 32, 41, 3, 252, 236, 32, 41, 3, - 252, 235, 32, 41, 3, 252, 234, 32, 41, 3, 252, 233, 32, 41, 3, 252, 232, - 32, 41, 3, 252, 231, 32, 41, 3, 252, 230, 32, 41, 3, 252, 229, 32, 41, 3, - 252, 228, 32, 41, 3, 252, 227, 32, 41, 3, 252, 226, 32, 41, 3, 252, 225, - 32, 41, 3, 252, 224, 32, 41, 3, 252, 223, 32, 41, 3, 252, 222, 32, 41, 3, - 252, 221, 32, 41, 3, 252, 220, 32, 41, 3, 252, 219, 32, 41, 3, 252, 218, - 32, 41, 3, 252, 217, 32, 41, 3, 252, 216, 32, 41, 3, 252, 215, 32, 41, 3, - 252, 214, 32, 41, 3, 252, 213, 32, 41, 3, 252, 212, 32, 41, 3, 252, 211, - 32, 41, 3, 252, 210, 32, 41, 3, 252, 209, 32, 41, 3, 252, 208, 32, 41, 3, - 252, 207, 32, 41, 3, 252, 206, 32, 41, 3, 252, 205, 32, 41, 3, 252, 204, - 32, 41, 3, 252, 203, 32, 41, 3, 252, 202, 32, 41, 3, 252, 201, 32, 41, 3, - 252, 200, 32, 41, 3, 252, 199, 32, 41, 3, 252, 198, 32, 41, 3, 252, 197, - 32, 41, 3, 252, 196, 32, 41, 3, 252, 195, 32, 41, 3, 252, 194, 32, 41, 3, - 252, 193, 32, 41, 3, 252, 192, 32, 41, 3, 252, 191, 32, 41, 3, 252, 190, - 32, 41, 3, 252, 189, 32, 41, 3, 252, 188, 32, 41, 3, 252, 187, 32, 41, 3, - 252, 186, 32, 41, 3, 252, 185, 32, 41, 3, 252, 184, 65, 32, 41, 3, 252, - 183, 250, 70, 32, 41, 3, 252, 182, 238, 80, 32, 41, 3, 252, 181, 73, 32, - 41, 3, 252, 180, 233, 134, 32, 41, 3, 252, 179, 230, 83, 32, 41, 3, 252, - 178, 223, 7, 32, 41, 3, 252, 177, 222, 125, 32, 41, 3, 252, 176, 170, 32, - 41, 3, 252, 175, 220, 106, 32, 41, 3, 252, 174, 220, 105, 32, 41, 3, 252, - 173, 220, 104, 32, 41, 3, 252, 172, 220, 103, 32, 41, 3, 252, 171, 193, - 221, 32, 41, 3, 252, 170, 192, 235, 32, 41, 3, 252, 169, 192, 159, 32, - 41, 3, 252, 168, 211, 99, 32, 41, 3, 252, 167, 252, 17, 32, 41, 3, 252, - 166, 249, 4, 32, 41, 3, 252, 165, 237, 148, 32, 41, 3, 252, 164, 233, - 142, 32, 41, 3, 252, 163, 222, 238, 32, 41, 3, 252, 162, 32, 41, 3, 252, - 161, 32, 41, 3, 252, 160, 32, 41, 3, 252, 159, 32, 41, 3, 252, 158, 32, - 41, 3, 252, 157, 32, 41, 3, 252, 156, 32, 41, 3, 252, 155, 59, 1, 2, 6, - 252, 154, 59, 1, 200, 177, 197, 234, 242, 35, 59, 1, 200, 177, 134, 197, - 234, 242, 35, 59, 1, 2, 251, 229, 59, 1, 2, 6, 250, 70, 59, 1, 2, 78, 4, - 106, 59, 1, 2, 234, 249, 236, 213, 59, 1, 2, 234, 249, 236, 214, 4, 207, - 19, 106, 59, 1, 2, 234, 249, 236, 214, 4, 238, 128, 59, 1, 2, 237, 25, - 236, 213, 59, 1, 2, 238, 81, 4, 199, 210, 59, 1, 2, 238, 81, 4, 106, 59, - 1, 2, 238, 81, 4, 228, 219, 24, 199, 210, 59, 1, 2, 207, 13, 73, 59, 1, - 2, 242, 171, 207, 13, 211, 66, 73, 59, 1, 2, 232, 252, 236, 213, 59, 1, - 2, 207, 135, 228, 156, 59, 1, 2, 6, 232, 14, 59, 1, 2, 232, 15, 4, 106, - 59, 1, 2, 6, 232, 15, 4, 106, 59, 1, 2, 230, 84, 4, 105, 59, 1, 2, 6, - 230, 83, 59, 1, 2, 229, 165, 4, 106, 59, 1, 2, 236, 95, 223, 8, 4, 201, - 23, 24, 106, 59, 1, 2, 218, 205, 236, 213, 59, 1, 2, 218, 149, 236, 213, - 59, 1, 2, 220, 119, 4, 248, 181, 59, 1, 2, 6, 220, 119, 4, 248, 181, 59, - 1, 2, 220, 119, 4, 207, 19, 228, 219, 24, 248, 181, 59, 1, 2, 219, 138, - 59, 1, 2, 219, 139, 4, 207, 19, 106, 59, 1, 2, 152, 192, 159, 59, 1, 2, - 152, 192, 160, 4, 248, 181, 59, 1, 2, 186, 4, 105, 59, 1, 2, 6, 211, 139, - 59, 1, 2, 242, 171, 211, 99, 59, 1, 2, 208, 97, 59, 1, 2, 152, 207, 217, - 4, 177, 219, 188, 59, 1, 2, 152, 207, 217, 4, 177, 219, 189, 24, 207, 19, - 106, 59, 1, 2, 207, 217, 4, 199, 210, 59, 1, 2, 207, 217, 4, 232, 192, - 59, 1, 2, 6, 148, 59, 1, 2, 199, 147, 236, 214, 4, 238, 128, 59, 1, 2, - 197, 166, 236, 213, 59, 1, 2, 197, 166, 236, 214, 4, 207, 19, 106, 59, 1, - 2, 199, 74, 236, 213, 59, 1, 2, 200, 40, 4, 207, 19, 106, 59, 1, 2, 196, - 9, 4, 50, 106, 59, 1, 2, 6, 192, 159, 59, 1, 230, 231, 201, 59, 4, 105, - 59, 1, 207, 13, 230, 231, 201, 59, 4, 105, 59, 1, 248, 124, 242, 183, 59, - 1, 237, 53, 242, 183, 59, 1, 219, 235, 242, 183, 59, 1, 251, 99, 242, - 183, 59, 1, 207, 19, 242, 184, 4, 207, 19, 106, 59, 1, 2, 206, 4, 4, 238, - 128, 238, 88, 5, 65, 238, 88, 5, 73, 238, 88, 5, 70, 238, 88, 5, 74, 238, - 88, 5, 69, 238, 88, 5, 223, 4, 238, 88, 5, 222, 174, 238, 88, 5, 157, - 238, 88, 5, 221, 253, 238, 88, 5, 221, 142, 238, 88, 5, 221, 43, 238, 88, - 5, 220, 208, 238, 88, 5, 171, 238, 88, 5, 219, 214, 238, 88, 5, 219, 122, - 238, 88, 5, 219, 19, 238, 88, 5, 218, 203, 238, 88, 5, 172, 238, 88, 5, - 216, 213, 238, 88, 5, 216, 81, 238, 88, 5, 215, 251, 238, 88, 5, 215, - 139, 238, 88, 5, 180, 238, 88, 5, 214, 107, 238, 88, 5, 213, 205, 238, - 88, 5, 213, 30, 238, 88, 5, 212, 165, 238, 88, 5, 168, 238, 88, 5, 210, - 53, 238, 88, 5, 209, 176, 238, 88, 5, 209, 65, 238, 88, 5, 208, 158, 238, - 88, 5, 166, 238, 88, 5, 207, 108, 238, 88, 5, 206, 252, 238, 88, 5, 206, - 157, 238, 88, 5, 206, 63, 238, 88, 5, 189, 238, 88, 5, 205, 63, 238, 88, - 5, 202, 217, 238, 88, 5, 202, 41, 238, 88, 5, 200, 255, 238, 88, 5, 199, - 247, 238, 88, 5, 199, 140, 238, 88, 5, 198, 188, 238, 88, 5, 159, 238, - 88, 5, 197, 90, 238, 88, 5, 193, 187, 238, 88, 5, 193, 123, 238, 88, 5, - 193, 84, 238, 88, 5, 193, 48, 238, 88, 5, 192, 220, 238, 88, 5, 192, 214, - 238, 88, 5, 191, 123, 238, 88, 5, 191, 7, 223, 136, 250, 224, 1, 251, - 139, 223, 136, 250, 224, 1, 248, 161, 223, 136, 250, 224, 1, 231, 1, 223, - 136, 250, 224, 1, 237, 205, 223, 136, 250, 224, 1, 229, 213, 223, 136, - 250, 224, 1, 193, 131, 223, 136, 250, 224, 1, 191, 91, 223, 136, 250, - 224, 1, 229, 152, 223, 136, 250, 224, 1, 199, 64, 223, 136, 250, 224, 1, - 191, 249, 223, 136, 250, 224, 1, 222, 49, 223, 136, 250, 224, 1, 220, 2, - 223, 136, 250, 224, 1, 216, 174, 223, 136, 250, 224, 1, 212, 117, 223, - 136, 250, 224, 1, 205, 143, 223, 136, 250, 224, 1, 250, 76, 223, 136, - 250, 224, 1, 210, 53, 223, 136, 250, 224, 1, 205, 184, 223, 136, 250, - 224, 1, 208, 31, 223, 136, 250, 224, 1, 207, 33, 223, 136, 250, 224, 1, - 203, 64, 223, 136, 250, 224, 1, 199, 154, 223, 136, 250, 224, 205, 49, - 57, 223, 136, 250, 224, 31, 108, 223, 136, 250, 224, 31, 109, 223, 136, - 250, 224, 31, 139, 223, 136, 250, 224, 31, 199, 90, 223, 136, 250, 224, - 31, 197, 28, 223, 136, 250, 224, 31, 91, 228, 109, 223, 136, 250, 224, - 31, 91, 188, 223, 136, 250, 224, 31, 199, 91, 188, 210, 170, 1, 251, 139, - 210, 170, 1, 248, 161, 210, 170, 1, 231, 1, 210, 170, 1, 237, 205, 210, - 170, 1, 229, 213, 210, 170, 1, 193, 131, 210, 170, 1, 191, 91, 210, 170, - 1, 229, 152, 210, 170, 1, 199, 64, 210, 170, 1, 191, 249, 210, 170, 1, - 222, 49, 210, 170, 1, 220, 2, 210, 170, 1, 216, 174, 210, 170, 1, 52, - 212, 117, 210, 170, 1, 212, 117, 210, 170, 1, 205, 143, 210, 170, 1, 250, - 76, 210, 170, 1, 210, 53, 210, 170, 1, 205, 184, 210, 170, 1, 208, 31, - 210, 170, 1, 207, 33, 210, 170, 1, 203, 64, 210, 170, 1, 199, 154, 210, - 170, 219, 195, 232, 161, 210, 170, 206, 198, 232, 161, 210, 170, 31, 108, - 210, 170, 31, 109, 210, 170, 31, 139, 210, 170, 31, 137, 210, 170, 31, - 153, 210, 170, 31, 199, 90, 210, 170, 31, 197, 28, 214, 232, 1, 52, 251, - 139, 214, 232, 1, 251, 139, 214, 232, 1, 52, 248, 161, 214, 232, 1, 248, - 161, 214, 232, 1, 231, 1, 214, 232, 1, 237, 205, 214, 232, 1, 52, 229, - 213, 214, 232, 1, 229, 213, 214, 232, 1, 193, 131, 214, 232, 1, 191, 91, - 214, 232, 1, 229, 152, 214, 232, 1, 199, 64, 214, 232, 1, 52, 191, 249, - 214, 232, 1, 191, 249, 214, 232, 1, 52, 222, 49, 214, 232, 1, 222, 49, - 214, 232, 1, 52, 220, 2, 214, 232, 1, 220, 2, 214, 232, 1, 52, 216, 174, - 214, 232, 1, 216, 174, 214, 232, 1, 52, 212, 117, 214, 232, 1, 212, 117, - 214, 232, 1, 205, 143, 214, 232, 1, 250, 76, 214, 232, 1, 210, 53, 214, - 232, 1, 205, 184, 214, 232, 1, 208, 31, 214, 232, 1, 207, 33, 214, 232, - 1, 52, 203, 64, 214, 232, 1, 203, 64, 214, 232, 1, 199, 154, 214, 232, - 31, 108, 214, 232, 31, 109, 214, 232, 31, 139, 214, 232, 31, 137, 214, - 232, 238, 155, 31, 137, 214, 232, 31, 153, 214, 232, 31, 199, 90, 214, - 232, 31, 197, 28, 214, 232, 31, 91, 228, 109, 229, 227, 1, 251, 139, 229, - 227, 1, 248, 161, 229, 227, 1, 231, 1, 229, 227, 1, 237, 204, 229, 227, - 1, 229, 213, 229, 227, 1, 193, 131, 229, 227, 1, 191, 89, 229, 227, 1, - 229, 152, 229, 227, 1, 199, 64, 229, 227, 1, 191, 249, 229, 227, 1, 222, - 49, 229, 227, 1, 220, 2, 229, 227, 1, 216, 174, 229, 227, 1, 212, 117, - 229, 227, 1, 205, 143, 229, 227, 1, 250, 74, 229, 227, 1, 210, 53, 229, - 227, 1, 205, 184, 229, 227, 1, 208, 31, 229, 227, 1, 203, 64, 229, 227, - 1, 199, 154, 229, 227, 31, 108, 229, 227, 31, 153, 229, 227, 31, 199, 90, - 229, 227, 31, 197, 28, 229, 227, 31, 91, 228, 109, 209, 188, 1, 251, 136, - 209, 188, 1, 248, 164, 209, 188, 1, 231, 176, 209, 188, 1, 237, 63, 209, - 188, 1, 229, 213, 209, 188, 1, 193, 138, 209, 188, 1, 191, 115, 209, 188, - 1, 229, 154, 209, 188, 1, 199, 68, 209, 188, 1, 191, 250, 209, 188, 1, - 222, 79, 209, 188, 1, 220, 8, 209, 188, 1, 216, 174, 209, 188, 1, 212, - 117, 209, 188, 1, 204, 14, 209, 188, 1, 251, 178, 209, 188, 1, 210, 53, - 209, 188, 1, 205, 186, 209, 188, 1, 208, 36, 209, 188, 1, 206, 119, 209, - 188, 1, 203, 64, 209, 188, 1, 199, 161, 209, 188, 31, 108, 209, 188, 31, - 199, 90, 209, 188, 31, 197, 28, 209, 188, 31, 91, 228, 109, 209, 188, 31, - 109, 209, 188, 31, 139, 209, 188, 193, 23, 204, 5, 218, 159, 1, 65, 218, - 159, 1, 250, 70, 218, 159, 1, 232, 14, 218, 159, 1, 238, 80, 218, 159, 1, - 73, 218, 159, 1, 196, 8, 218, 159, 1, 70, 218, 159, 1, 192, 159, 218, - 159, 1, 222, 125, 218, 159, 1, 170, 218, 159, 1, 218, 147, 218, 159, 1, - 215, 47, 218, 159, 1, 74, 218, 159, 1, 148, 218, 159, 1, 201, 173, 218, - 159, 1, 200, 39, 218, 159, 1, 69, 218, 159, 1, 233, 134, 218, 159, 1, - 208, 97, 218, 159, 1, 206, 3, 218, 159, 1, 197, 131, 218, 159, 1, 251, - 81, 218, 159, 1, 234, 61, 218, 159, 1, 218, 162, 218, 159, 1, 213, 67, - 218, 159, 1, 247, 145, 218, 159, 197, 234, 77, 151, 229, 112, 1, 65, 151, - 229, 112, 1, 73, 151, 229, 112, 1, 70, 151, 229, 112, 1, 74, 151, 229, - 112, 1, 169, 151, 229, 112, 1, 193, 187, 151, 229, 112, 1, 249, 103, 151, - 229, 112, 1, 249, 102, 151, 229, 112, 1, 168, 151, 229, 112, 1, 172, 151, - 229, 112, 1, 180, 151, 229, 112, 1, 214, 247, 151, 229, 112, 1, 214, 107, - 151, 229, 112, 1, 214, 105, 151, 229, 112, 1, 166, 151, 229, 112, 1, 207, - 179, 151, 229, 112, 1, 171, 151, 229, 112, 1, 221, 190, 151, 229, 112, 1, - 229, 145, 151, 229, 112, 1, 189, 151, 229, 112, 1, 205, 200, 151, 229, - 112, 1, 205, 63, 151, 229, 112, 1, 157, 151, 229, 112, 1, 208, 89, 151, - 229, 112, 1, 199, 247, 151, 229, 112, 1, 199, 245, 151, 229, 112, 1, 199, - 140, 151, 229, 112, 1, 199, 138, 151, 229, 112, 1, 159, 151, 229, 112, 1, - 237, 241, 151, 229, 112, 16, 195, 60, 151, 229, 112, 16, 195, 59, 151, - 238, 119, 1, 65, 151, 238, 119, 1, 73, 151, 238, 119, 1, 70, 151, 238, - 119, 1, 74, 151, 238, 119, 1, 169, 151, 238, 119, 1, 193, 187, 151, 238, - 119, 1, 249, 103, 151, 238, 119, 1, 168, 151, 238, 119, 1, 172, 151, 238, - 119, 1, 180, 151, 238, 119, 1, 214, 107, 151, 238, 119, 1, 166, 151, 238, - 119, 1, 171, 151, 238, 119, 1, 221, 190, 151, 238, 119, 1, 229, 145, 151, - 238, 119, 1, 189, 151, 238, 119, 1, 250, 220, 189, 151, 238, 119, 1, 205, - 63, 151, 238, 119, 1, 157, 151, 238, 119, 1, 208, 89, 151, 238, 119, 1, - 199, 247, 151, 238, 119, 1, 199, 140, 151, 238, 119, 1, 159, 151, 238, - 119, 1, 237, 241, 151, 238, 119, 232, 80, 234, 85, 197, 35, 151, 238, - 119, 232, 80, 91, 230, 37, 151, 238, 119, 219, 4, 206, 163, 151, 238, - 119, 219, 4, 223, 141, 151, 238, 119, 31, 108, 151, 238, 119, 31, 109, - 151, 238, 119, 31, 139, 151, 238, 119, 31, 137, 151, 238, 119, 31, 153, - 151, 238, 119, 31, 173, 151, 238, 119, 31, 181, 151, 238, 119, 31, 176, - 151, 238, 119, 31, 184, 151, 238, 119, 31, 199, 90, 151, 238, 119, 31, - 197, 28, 151, 238, 119, 31, 198, 244, 151, 238, 119, 31, 232, 97, 151, - 238, 119, 31, 232, 230, 151, 238, 119, 31, 202, 115, 151, 238, 119, 31, - 203, 236, 151, 238, 119, 31, 91, 228, 109, 151, 238, 119, 31, 103, 228, - 109, 151, 238, 119, 31, 115, 228, 109, 151, 238, 119, 31, 232, 90, 228, - 109, 151, 238, 119, 31, 232, 185, 228, 109, 151, 238, 119, 31, 202, 131, - 228, 109, 151, 238, 119, 31, 203, 242, 228, 109, 151, 238, 119, 31, 234, - 121, 228, 109, 151, 238, 119, 31, 213, 161, 228, 109, 151, 238, 119, 31, - 91, 188, 151, 238, 119, 31, 103, 188, 151, 238, 119, 31, 115, 188, 151, - 238, 119, 31, 232, 90, 188, 151, 238, 119, 31, 232, 185, 188, 151, 238, - 119, 31, 202, 131, 188, 151, 238, 119, 31, 203, 242, 188, 151, 238, 119, - 31, 234, 121, 188, 151, 238, 119, 31, 213, 161, 188, 151, 238, 119, 31, - 199, 91, 188, 151, 238, 119, 31, 197, 29, 188, 151, 238, 119, 31, 198, - 245, 188, 151, 238, 119, 31, 232, 98, 188, 151, 238, 119, 31, 232, 231, - 188, 151, 238, 119, 31, 202, 116, 188, 151, 238, 119, 31, 203, 237, 188, - 151, 238, 119, 31, 234, 111, 188, 151, 238, 119, 31, 213, 157, 188, 151, - 238, 119, 31, 91, 228, 110, 188, 151, 238, 119, 31, 103, 228, 110, 188, - 151, 238, 119, 31, 115, 228, 110, 188, 151, 238, 119, 31, 232, 90, 228, - 110, 188, 151, 238, 119, 31, 232, 185, 228, 110, 188, 151, 238, 119, 31, - 202, 131, 228, 110, 188, 151, 238, 119, 31, 203, 242, 228, 110, 188, 151, - 238, 119, 31, 234, 121, 228, 110, 188, 151, 238, 119, 31, 213, 161, 228, - 110, 188, 151, 238, 119, 232, 80, 91, 197, 36, 151, 238, 119, 232, 80, - 103, 197, 35, 151, 238, 119, 232, 80, 115, 197, 35, 151, 238, 119, 232, - 80, 232, 90, 197, 35, 151, 238, 119, 232, 80, 232, 185, 197, 35, 151, - 238, 119, 232, 80, 202, 131, 197, 35, 151, 238, 119, 232, 80, 203, 242, - 197, 35, 151, 238, 119, 232, 80, 234, 121, 197, 35, 151, 238, 119, 232, - 80, 213, 161, 197, 35, 151, 238, 119, 232, 80, 199, 91, 197, 35, 221, - 175, 1, 65, 221, 175, 18, 3, 70, 221, 175, 18, 3, 69, 221, 175, 18, 3, - 121, 148, 221, 175, 18, 3, 73, 221, 175, 18, 3, 74, 221, 175, 18, 219, - 174, 77, 221, 175, 3, 54, 206, 184, 60, 221, 175, 3, 251, 20, 221, 175, - 3, 195, 32, 221, 175, 1, 157, 221, 175, 1, 221, 190, 221, 175, 1, 231, - 203, 221, 175, 1, 231, 54, 221, 175, 1, 247, 112, 221, 175, 1, 246, 209, - 221, 175, 1, 223, 4, 221, 175, 1, 212, 88, 221, 175, 1, 197, 128, 221, - 175, 1, 197, 116, 221, 175, 1, 237, 146, 221, 175, 1, 237, 130, 221, 175, - 1, 213, 66, 221, 175, 1, 199, 247, 221, 175, 1, 199, 44, 221, 175, 1, - 237, 241, 221, 175, 1, 237, 23, 221, 175, 1, 180, 221, 175, 1, 168, 221, - 175, 1, 209, 219, 221, 175, 1, 249, 103, 221, 175, 1, 248, 153, 221, 175, - 1, 172, 221, 175, 1, 169, 221, 175, 1, 166, 221, 175, 1, 171, 221, 175, - 1, 195, 185, 221, 175, 1, 203, 160, 221, 175, 1, 201, 170, 221, 175, 1, - 189, 221, 175, 1, 191, 123, 221, 175, 1, 144, 221, 175, 1, 221, 77, 221, - 175, 1, 197, 96, 221, 175, 1, 197, 97, 221, 175, 1, 195, 67, 221, 175, 3, - 249, 38, 56, 221, 175, 3, 247, 26, 221, 175, 3, 75, 60, 221, 175, 195, - 37, 221, 175, 17, 108, 221, 175, 17, 109, 221, 175, 17, 139, 221, 175, - 17, 137, 221, 175, 31, 199, 90, 221, 175, 31, 197, 28, 221, 175, 31, 91, - 228, 109, 221, 175, 31, 91, 188, 221, 175, 232, 80, 91, 230, 37, 221, - 175, 208, 145, 236, 96, 221, 175, 208, 145, 2, 242, 218, 221, 175, 208, - 145, 242, 218, 221, 175, 208, 145, 238, 181, 164, 221, 175, 208, 145, - 217, 63, 221, 175, 208, 145, 218, 224, 221, 175, 208, 145, 237, 193, 221, - 175, 208, 145, 54, 237, 193, 221, 175, 208, 145, 219, 82, 38, 201, 253, - 250, 235, 1, 229, 213, 38, 201, 253, 250, 235, 1, 220, 2, 38, 201, 253, - 250, 235, 1, 229, 152, 38, 201, 253, 250, 235, 1, 216, 174, 38, 201, 253, - 250, 235, 1, 208, 31, 38, 201, 253, 250, 235, 1, 193, 131, 38, 201, 253, - 250, 235, 1, 203, 64, 38, 201, 253, 250, 235, 1, 207, 33, 38, 201, 253, - 250, 235, 1, 248, 161, 38, 201, 253, 250, 235, 1, 199, 154, 38, 201, 253, - 250, 235, 1, 205, 117, 38, 201, 253, 250, 235, 1, 222, 49, 38, 201, 253, - 250, 235, 1, 212, 117, 38, 201, 253, 250, 235, 1, 221, 170, 38, 201, 253, - 250, 235, 1, 205, 184, 38, 201, 253, 250, 235, 1, 205, 143, 38, 201, 253, - 250, 235, 1, 233, 18, 38, 201, 253, 250, 235, 1, 251, 141, 38, 201, 253, - 250, 235, 1, 250, 74, 38, 201, 253, 250, 235, 1, 237, 20, 38, 201, 253, - 250, 235, 1, 231, 1, 38, 201, 253, 250, 235, 1, 237, 205, 38, 201, 253, - 250, 235, 1, 231, 42, 38, 201, 253, 250, 235, 1, 199, 64, 38, 201, 253, - 250, 235, 1, 191, 89, 38, 201, 253, 250, 235, 1, 237, 17, 38, 201, 253, - 250, 235, 1, 191, 249, 38, 201, 253, 250, 235, 1, 199, 30, 38, 201, 253, - 250, 235, 1, 199, 9, 38, 201, 253, 250, 235, 31, 108, 38, 201, 253, 250, - 235, 31, 232, 230, 38, 201, 253, 250, 235, 167, 223, 116, 38, 185, 250, - 235, 1, 229, 178, 38, 185, 250, 235, 1, 220, 11, 38, 185, 250, 235, 1, - 230, 48, 38, 185, 250, 235, 1, 216, 189, 38, 185, 250, 235, 1, 208, 82, - 38, 185, 250, 235, 1, 193, 131, 38, 185, 250, 235, 1, 233, 234, 38, 185, - 250, 235, 1, 207, 66, 38, 185, 250, 235, 1, 248, 195, 38, 185, 250, 235, - 1, 199, 109, 38, 185, 250, 235, 1, 233, 235, 38, 185, 250, 235, 1, 222, - 79, 38, 185, 250, 235, 1, 213, 11, 38, 185, 250, 235, 1, 221, 185, 38, - 185, 250, 235, 1, 205, 187, 38, 185, 250, 235, 1, 233, 233, 38, 185, 250, - 235, 1, 233, 5, 38, 185, 250, 235, 1, 251, 141, 38, 185, 250, 235, 1, - 251, 178, 38, 185, 250, 235, 1, 237, 235, 38, 185, 250, 235, 1, 231, 119, - 38, 185, 250, 235, 1, 237, 212, 38, 185, 250, 235, 1, 231, 49, 38, 185, - 250, 235, 1, 199, 214, 38, 185, 250, 235, 1, 191, 113, 38, 185, 250, 235, - 1, 199, 36, 38, 185, 250, 235, 1, 192, 75, 38, 185, 250, 235, 1, 199, 24, - 38, 185, 250, 235, 1, 191, 116, 38, 185, 250, 235, 31, 108, 38, 185, 250, - 235, 31, 199, 90, 38, 185, 250, 235, 31, 197, 28, 217, 61, 1, 251, 139, - 217, 61, 1, 248, 161, 217, 61, 1, 248, 146, 217, 61, 1, 231, 1, 217, 61, - 1, 231, 27, 217, 61, 1, 237, 205, 217, 61, 1, 229, 213, 217, 61, 1, 193, - 131, 217, 61, 3, 196, 154, 217, 61, 1, 191, 91, 217, 61, 1, 191, 64, 217, - 61, 1, 222, 240, 217, 61, 1, 222, 221, 217, 61, 1, 229, 152, 217, 61, 1, - 199, 64, 217, 61, 1, 191, 249, 217, 61, 1, 222, 49, 217, 61, 1, 192, 217, - 217, 61, 1, 221, 177, 217, 61, 1, 220, 2, 217, 61, 1, 237, 16, 217, 61, - 1, 199, 35, 217, 61, 1, 216, 174, 217, 61, 1, 212, 117, 217, 61, 1, 205, - 143, 217, 61, 1, 250, 76, 217, 61, 1, 252, 106, 217, 61, 1, 210, 53, 217, - 61, 1, 233, 18, 217, 61, 1, 205, 184, 217, 61, 1, 208, 31, 217, 61, 1, - 192, 193, 217, 61, 1, 208, 58, 217, 61, 1, 207, 33, 217, 61, 1, 203, 64, - 217, 61, 1, 201, 138, 217, 61, 1, 199, 154, 217, 61, 252, 16, 87, 56, - 217, 61, 252, 16, 87, 60, 217, 61, 31, 108, 217, 61, 31, 153, 217, 61, - 31, 199, 90, 217, 61, 31, 197, 28, 217, 61, 31, 91, 228, 109, 217, 61, - 208, 145, 201, 97, 217, 61, 208, 145, 232, 161, 217, 61, 208, 145, 54, - 75, 193, 53, 236, 96, 217, 61, 208, 145, 75, 193, 53, 236, 96, 217, 61, - 208, 145, 236, 96, 217, 61, 208, 145, 103, 236, 94, 217, 61, 208, 145, - 219, 89, 232, 218, 250, 92, 1, 65, 250, 92, 1, 252, 154, 250, 92, 1, 251, - 18, 250, 92, 1, 252, 112, 250, 92, 1, 251, 81, 250, 92, 1, 252, 114, 250, - 92, 1, 251, 229, 250, 92, 1, 251, 225, 250, 92, 1, 73, 250, 92, 1, 234, - 145, 250, 92, 1, 74, 250, 92, 1, 211, 76, 250, 92, 1, 70, 250, 92, 1, - 223, 170, 250, 92, 1, 69, 250, 92, 1, 196, 26, 250, 92, 1, 221, 253, 250, - 92, 1, 192, 214, 250, 92, 1, 192, 173, 250, 92, 1, 192, 184, 250, 92, 1, - 231, 128, 250, 92, 1, 231, 85, 250, 92, 1, 231, 40, 250, 92, 1, 246, 250, - 250, 92, 1, 222, 238, 250, 92, 1, 199, 140, 250, 92, 1, 199, 28, 250, 92, - 1, 237, 101, 250, 92, 1, 237, 14, 250, 92, 1, 197, 123, 250, 92, 1, 210, - 53, 250, 92, 1, 233, 18, 250, 92, 1, 248, 223, 250, 92, 1, 248, 148, 250, - 92, 1, 214, 41, 250, 92, 1, 213, 212, 250, 92, 1, 213, 213, 250, 92, 1, - 214, 107, 250, 92, 1, 212, 77, 250, 92, 1, 213, 61, 250, 92, 1, 216, 213, - 250, 92, 1, 229, 41, 250, 92, 1, 191, 173, 250, 92, 1, 192, 80, 250, 92, - 1, 195, 150, 250, 92, 1, 207, 108, 250, 92, 1, 219, 214, 250, 92, 1, 205, - 63, 250, 92, 1, 191, 87, 250, 92, 1, 203, 108, 250, 92, 1, 191, 62, 250, - 92, 1, 202, 224, 250, 92, 1, 201, 139, 250, 92, 1, 229, 213, 250, 92, - 252, 16, 77, 198, 133, 103, 183, 138, 91, 75, 208, 144, 2, 103, 183, 138, - 91, 75, 208, 144, 219, 245, 103, 183, 138, 91, 75, 208, 144, 219, 245, - 91, 75, 138, 103, 183, 208, 144, 219, 245, 103, 206, 180, 138, 91, 206, - 184, 208, 144, 219, 245, 91, 206, 184, 138, 103, 206, 180, 208, 144, 223, - 94, 210, 96, 1, 251, 139, 223, 94, 210, 96, 1, 248, 161, 223, 94, 210, - 96, 1, 231, 1, 223, 94, 210, 96, 1, 237, 205, 223, 94, 210, 96, 1, 229, - 213, 223, 94, 210, 96, 1, 193, 131, 223, 94, 210, 96, 1, 191, 91, 223, - 94, 210, 96, 1, 229, 152, 223, 94, 210, 96, 1, 199, 64, 223, 94, 210, 96, - 1, 191, 249, 223, 94, 210, 96, 1, 222, 49, 223, 94, 210, 96, 1, 220, 2, - 223, 94, 210, 96, 1, 216, 174, 223, 94, 210, 96, 1, 212, 117, 223, 94, - 210, 96, 1, 205, 143, 223, 94, 210, 96, 1, 250, 76, 223, 94, 210, 96, 1, - 210, 53, 223, 94, 210, 96, 1, 205, 184, 223, 94, 210, 96, 1, 208, 31, - 223, 94, 210, 96, 1, 207, 33, 223, 94, 210, 96, 1, 203, 64, 223, 94, 210, - 96, 1, 199, 154, 223, 94, 210, 96, 31, 108, 223, 94, 210, 96, 31, 109, - 223, 94, 210, 96, 31, 139, 223, 94, 210, 96, 31, 137, 223, 94, 210, 96, - 31, 199, 90, 223, 94, 210, 96, 31, 197, 28, 223, 94, 210, 96, 31, 91, - 228, 109, 223, 94, 210, 96, 31, 91, 188, 223, 94, 210, 189, 1, 251, 139, - 223, 94, 210, 189, 1, 248, 161, 223, 94, 210, 189, 1, 231, 1, 223, 94, - 210, 189, 1, 237, 205, 223, 94, 210, 189, 1, 229, 213, 223, 94, 210, 189, - 1, 193, 130, 223, 94, 210, 189, 1, 191, 91, 223, 94, 210, 189, 1, 229, - 152, 223, 94, 210, 189, 1, 199, 64, 223, 94, 210, 189, 1, 191, 249, 223, - 94, 210, 189, 1, 222, 49, 223, 94, 210, 189, 1, 220, 2, 223, 94, 210, - 189, 1, 216, 173, 223, 94, 210, 189, 1, 212, 117, 223, 94, 210, 189, 1, - 205, 143, 223, 94, 210, 189, 1, 210, 53, 223, 94, 210, 189, 1, 205, 184, - 223, 94, 210, 189, 1, 203, 64, 223, 94, 210, 189, 1, 199, 154, 223, 94, - 210, 189, 31, 108, 223, 94, 210, 189, 31, 109, 223, 94, 210, 189, 31, - 139, 223, 94, 210, 189, 31, 137, 223, 94, 210, 189, 31, 199, 90, 223, 94, - 210, 189, 31, 197, 28, 223, 94, 210, 189, 31, 91, 228, 109, 223, 94, 210, - 189, 31, 91, 188, 208, 170, 210, 189, 1, 251, 139, 208, 170, 210, 189, 1, - 248, 161, 208, 170, 210, 189, 1, 231, 1, 208, 170, 210, 189, 1, 237, 205, - 208, 170, 210, 189, 1, 229, 213, 208, 170, 210, 189, 1, 193, 130, 208, - 170, 210, 189, 1, 191, 91, 208, 170, 210, 189, 1, 229, 152, 208, 170, - 210, 189, 1, 191, 249, 208, 170, 210, 189, 1, 222, 49, 208, 170, 210, - 189, 1, 220, 2, 208, 170, 210, 189, 1, 216, 173, 208, 170, 210, 189, 1, - 212, 117, 208, 170, 210, 189, 1, 205, 143, 208, 170, 210, 189, 1, 210, - 53, 208, 170, 210, 189, 1, 205, 184, 208, 170, 210, 189, 1, 203, 64, 208, - 170, 210, 189, 1, 199, 154, 208, 170, 210, 189, 205, 49, 77, 208, 170, - 210, 189, 152, 205, 49, 77, 208, 170, 210, 189, 232, 90, 183, 4, 238, - 170, 208, 170, 210, 189, 232, 90, 183, 4, 236, 96, 208, 170, 210, 189, - 31, 108, 208, 170, 210, 189, 31, 109, 208, 170, 210, 189, 31, 139, 208, - 170, 210, 189, 31, 137, 208, 170, 210, 189, 31, 199, 90, 208, 170, 210, - 189, 31, 197, 28, 208, 170, 210, 189, 31, 91, 228, 109, 38, 197, 57, 1, - 211, 34, 65, 38, 197, 57, 1, 192, 68, 65, 38, 197, 57, 1, 192, 68, 251, - 229, 38, 197, 57, 1, 211, 34, 70, 38, 197, 57, 1, 192, 68, 70, 38, 197, - 57, 1, 192, 68, 73, 38, 197, 57, 1, 211, 34, 74, 38, 197, 57, 1, 211, 34, - 211, 139, 38, 197, 57, 1, 192, 68, 211, 139, 38, 197, 57, 1, 211, 34, - 252, 103, 38, 197, 57, 1, 192, 68, 252, 103, 38, 197, 57, 1, 211, 34, - 251, 228, 38, 197, 57, 1, 192, 68, 251, 228, 38, 197, 57, 1, 211, 34, - 251, 201, 38, 197, 57, 1, 192, 68, 251, 201, 38, 197, 57, 1, 211, 34, - 251, 223, 38, 197, 57, 1, 192, 68, 251, 223, 38, 197, 57, 1, 211, 34, - 251, 246, 38, 197, 57, 1, 192, 68, 251, 246, 38, 197, 57, 1, 211, 34, - 251, 227, 38, 197, 57, 1, 211, 34, 233, 141, 38, 197, 57, 1, 192, 68, - 233, 141, 38, 197, 57, 1, 211, 34, 250, 81, 38, 197, 57, 1, 192, 68, 250, - 81, 38, 197, 57, 1, 211, 34, 251, 210, 38, 197, 57, 1, 192, 68, 251, 210, - 38, 197, 57, 1, 211, 34, 251, 221, 38, 197, 57, 1, 192, 68, 251, 221, 38, - 197, 57, 1, 211, 34, 211, 137, 38, 197, 57, 1, 192, 68, 211, 137, 38, - 197, 57, 1, 211, 34, 251, 156, 38, 197, 57, 1, 192, 68, 251, 156, 38, - 197, 57, 1, 211, 34, 251, 220, 38, 197, 57, 1, 211, 34, 234, 76, 38, 197, - 57, 1, 211, 34, 234, 72, 38, 197, 57, 1, 211, 34, 251, 81, 38, 197, 57, - 1, 211, 34, 251, 218, 38, 197, 57, 1, 192, 68, 251, 218, 38, 197, 57, 1, - 211, 34, 234, 38, 38, 197, 57, 1, 192, 68, 234, 38, 38, 197, 57, 1, 211, - 34, 234, 58, 38, 197, 57, 1, 192, 68, 234, 58, 38, 197, 57, 1, 211, 34, - 234, 24, 38, 197, 57, 1, 192, 68, 234, 24, 38, 197, 57, 1, 192, 68, 251, - 71, 38, 197, 57, 1, 211, 34, 234, 46, 38, 197, 57, 1, 192, 68, 251, 217, - 38, 197, 57, 1, 211, 34, 234, 14, 38, 197, 57, 1, 211, 34, 211, 67, 38, - 197, 57, 1, 211, 34, 227, 254, 38, 197, 57, 1, 211, 34, 234, 153, 38, - 197, 57, 1, 192, 68, 234, 153, 38, 197, 57, 1, 211, 34, 250, 243, 38, - 197, 57, 1, 192, 68, 250, 243, 38, 197, 57, 1, 211, 34, 223, 51, 38, 197, - 57, 1, 192, 68, 223, 51, 38, 197, 57, 1, 211, 34, 211, 47, 38, 197, 57, - 1, 192, 68, 211, 47, 38, 197, 57, 1, 211, 34, 250, 239, 38, 197, 57, 1, - 192, 68, 250, 239, 38, 197, 57, 1, 211, 34, 251, 216, 38, 197, 57, 1, - 211, 34, 250, 169, 38, 197, 57, 1, 211, 34, 251, 214, 38, 197, 57, 1, - 211, 34, 250, 159, 38, 197, 57, 1, 192, 68, 250, 159, 38, 197, 57, 1, - 211, 34, 233, 226, 38, 197, 57, 1, 192, 68, 233, 226, 38, 197, 57, 1, - 211, 34, 250, 132, 38, 197, 57, 1, 192, 68, 250, 132, 38, 197, 57, 1, - 211, 34, 251, 211, 38, 197, 57, 1, 192, 68, 251, 211, 38, 197, 57, 1, - 211, 34, 211, 20, 38, 197, 57, 1, 211, 34, 249, 21, 38, 175, 6, 1, 65, - 38, 175, 6, 1, 252, 154, 38, 175, 6, 1, 234, 155, 38, 175, 6, 1, 251, 93, - 38, 175, 6, 1, 234, 153, 38, 175, 6, 1, 234, 58, 38, 175, 6, 1, 234, 150, - 38, 175, 6, 1, 234, 149, 38, 175, 6, 1, 251, 74, 38, 175, 6, 1, 73, 38, - 175, 6, 1, 242, 172, 73, 38, 175, 6, 1, 234, 145, 38, 175, 6, 1, 234, - 138, 38, 175, 6, 1, 234, 137, 38, 175, 6, 1, 234, 133, 38, 175, 6, 1, - 234, 130, 38, 175, 6, 1, 70, 38, 175, 6, 1, 223, 170, 38, 175, 6, 1, 234, - 107, 38, 175, 6, 1, 234, 104, 38, 175, 6, 1, 251, 165, 38, 175, 6, 1, - 196, 82, 38, 175, 6, 1, 234, 97, 38, 175, 6, 1, 234, 75, 38, 175, 6, 1, - 234, 72, 38, 175, 6, 1, 234, 61, 38, 175, 6, 1, 234, 24, 38, 175, 6, 1, - 74, 38, 175, 6, 1, 211, 76, 38, 175, 6, 1, 213, 168, 211, 139, 38, 175, - 6, 1, 206, 53, 211, 139, 38, 175, 6, 1, 211, 138, 38, 175, 6, 1, 234, 14, - 38, 175, 6, 1, 234, 66, 38, 175, 6, 1, 233, 248, 38, 175, 6, 1, 203, 35, - 233, 248, 38, 175, 6, 1, 233, 236, 38, 175, 6, 1, 233, 215, 38, 175, 6, - 1, 233, 213, 38, 175, 6, 1, 234, 38, 38, 175, 6, 1, 233, 202, 38, 175, 6, - 1, 234, 151, 38, 175, 6, 1, 69, 38, 175, 6, 1, 196, 26, 38, 175, 6, 1, - 213, 168, 196, 148, 38, 175, 6, 1, 206, 53, 196, 148, 38, 175, 6, 1, 233, - 189, 38, 175, 6, 1, 233, 141, 38, 175, 6, 1, 233, 136, 38, 175, 6, 1, - 234, 37, 57, 38, 175, 6, 1, 196, 41, 38, 175, 2, 1, 65, 38, 175, 2, 1, - 252, 154, 38, 175, 2, 1, 234, 155, 38, 175, 2, 1, 251, 93, 38, 175, 2, 1, - 234, 153, 38, 175, 2, 1, 234, 58, 38, 175, 2, 1, 234, 150, 38, 175, 2, 1, - 234, 149, 38, 175, 2, 1, 251, 74, 38, 175, 2, 1, 73, 38, 175, 2, 1, 242, - 172, 73, 38, 175, 2, 1, 234, 145, 38, 175, 2, 1, 234, 138, 38, 175, 2, 1, - 234, 137, 38, 175, 2, 1, 234, 133, 38, 175, 2, 1, 234, 130, 38, 175, 2, - 1, 70, 38, 175, 2, 1, 223, 170, 38, 175, 2, 1, 234, 107, 38, 175, 2, 1, - 234, 104, 38, 175, 2, 1, 251, 165, 38, 175, 2, 1, 196, 82, 38, 175, 2, 1, - 234, 97, 38, 175, 2, 1, 234, 75, 38, 175, 2, 1, 234, 72, 38, 175, 2, 1, - 234, 61, 38, 175, 2, 1, 234, 24, 38, 175, 2, 1, 74, 38, 175, 2, 1, 211, - 76, 38, 175, 2, 1, 213, 168, 211, 139, 38, 175, 2, 1, 206, 53, 211, 139, - 38, 175, 2, 1, 211, 138, 38, 175, 2, 1, 234, 14, 38, 175, 2, 1, 234, 66, - 38, 175, 2, 1, 233, 248, 38, 175, 2, 1, 203, 35, 233, 248, 38, 175, 2, 1, - 233, 236, 38, 175, 2, 1, 233, 215, 38, 175, 2, 1, 233, 213, 38, 175, 2, - 1, 234, 38, 38, 175, 2, 1, 233, 202, 38, 175, 2, 1, 234, 151, 38, 175, 2, - 1, 69, 38, 175, 2, 1, 196, 26, 38, 175, 2, 1, 213, 168, 196, 148, 38, - 175, 2, 1, 206, 53, 196, 148, 38, 175, 2, 1, 233, 189, 38, 175, 2, 1, - 233, 141, 38, 175, 2, 1, 233, 136, 38, 175, 2, 1, 234, 37, 57, 38, 175, - 2, 1, 196, 41, 38, 175, 31, 108, 38, 175, 31, 153, 38, 175, 31, 199, 90, - 38, 175, 31, 232, 230, 38, 175, 31, 91, 228, 109, 38, 175, 31, 91, 188, - 229, 247, 206, 137, 1, 65, 229, 247, 206, 137, 1, 249, 103, 229, 247, - 206, 137, 1, 168, 229, 247, 206, 137, 1, 199, 247, 229, 247, 206, 137, 1, - 197, 128, 229, 247, 206, 137, 1, 223, 4, 229, 247, 206, 137, 1, 247, 112, - 229, 247, 206, 137, 1, 144, 229, 247, 206, 137, 1, 221, 190, 229, 247, - 206, 137, 1, 233, 68, 229, 247, 206, 137, 1, 237, 241, 229, 247, 206, - 137, 1, 237, 146, 229, 247, 206, 137, 1, 166, 229, 247, 206, 137, 1, 206, - 104, 229, 247, 206, 137, 1, 191, 123, 229, 247, 206, 137, 1, 189, 229, - 247, 206, 137, 1, 203, 160, 229, 247, 206, 137, 1, 157, 229, 247, 206, - 137, 1, 231, 203, 229, 247, 206, 137, 1, 171, 229, 247, 206, 137, 1, 172, - 229, 247, 206, 137, 1, 180, 229, 247, 206, 137, 1, 193, 187, 229, 247, - 206, 137, 1, 221, 113, 193, 187, 229, 247, 206, 137, 1, 169, 229, 247, - 206, 137, 1, 221, 113, 169, 229, 247, 206, 137, 1, 214, 54, 229, 247, - 206, 137, 1, 212, 88, 229, 247, 206, 137, 1, 195, 185, 229, 247, 206, - 137, 18, 65, 229, 247, 206, 137, 18, 70, 229, 247, 206, 137, 18, 69, 229, - 247, 206, 137, 18, 73, 229, 247, 206, 137, 18, 74, 229, 247, 206, 137, - 87, 205, 168, 229, 247, 206, 137, 87, 214, 249, 221, 154, 229, 247, 206, - 137, 3, 229, 241, 229, 247, 206, 137, 3, 199, 213, 229, 247, 206, 137, 3, - 199, 187, 229, 247, 206, 137, 3, 199, 167, 229, 247, 206, 137, 17, 191, - 77, 229, 247, 206, 137, 17, 108, 229, 247, 206, 137, 17, 109, 229, 247, - 206, 137, 17, 139, 229, 247, 206, 137, 17, 137, 229, 247, 206, 137, 17, - 153, 229, 247, 206, 137, 17, 173, 229, 247, 206, 137, 17, 181, 229, 247, - 206, 137, 17, 176, 229, 247, 206, 137, 17, 184, 206, 41, 17, 108, 206, - 41, 17, 109, 206, 41, 17, 139, 206, 41, 17, 137, 206, 41, 17, 153, 206, - 41, 17, 173, 206, 41, 17, 181, 206, 41, 17, 176, 206, 41, 17, 184, 206, - 41, 31, 199, 90, 206, 41, 31, 197, 28, 206, 41, 31, 198, 244, 206, 41, - 31, 232, 97, 206, 41, 31, 232, 230, 206, 41, 31, 202, 115, 206, 41, 31, - 203, 236, 206, 41, 31, 234, 110, 206, 41, 31, 213, 156, 206, 41, 31, 91, - 228, 109, 206, 41, 31, 103, 228, 109, 206, 41, 31, 115, 228, 109, 206, - 41, 31, 232, 90, 228, 109, 206, 41, 31, 232, 185, 228, 109, 206, 41, 31, - 202, 131, 228, 109, 206, 41, 31, 203, 242, 228, 109, 206, 41, 31, 234, - 121, 228, 109, 206, 41, 31, 213, 161, 228, 109, 206, 41, 232, 80, 91, - 230, 37, 206, 41, 232, 80, 91, 208, 17, 206, 41, 232, 80, 91, 198, 251, - 206, 41, 232, 80, 103, 198, 248, 192, 39, 1, 234, 81, 192, 39, 1, 248, - 223, 192, 39, 1, 210, 53, 192, 39, 1, 209, 205, 192, 39, 1, 199, 28, 192, - 39, 1, 205, 63, 192, 39, 1, 242, 224, 192, 39, 1, 243, 35, 192, 39, 1, - 243, 49, 192, 39, 1, 229, 145, 192, 39, 1, 192, 220, 192, 39, 1, 237, - 212, 192, 39, 1, 191, 108, 192, 39, 1, 166, 192, 39, 1, 207, 1, 192, 39, - 1, 191, 123, 192, 39, 1, 223, 4, 192, 39, 1, 202, 169, 192, 39, 1, 203, - 64, 192, 39, 1, 205, 187, 192, 39, 1, 237, 235, 192, 39, 1, 199, 247, - 192, 39, 1, 191, 87, 192, 39, 1, 233, 143, 192, 39, 1, 192, 208, 192, 39, - 1, 233, 68, 192, 39, 1, 195, 185, 192, 39, 1, 195, 186, 251, 106, 20, - 192, 39, 1, 208, 82, 192, 39, 1, 222, 79, 192, 39, 1, 221, 187, 192, 39, - 1, 231, 190, 192, 39, 1, 220, 11, 192, 39, 1, 216, 28, 192, 39, 1, 212, - 117, 192, 39, 1, 196, 116, 192, 39, 1, 193, 131, 192, 39, 1, 210, 240, - 192, 39, 1, 233, 183, 192, 39, 1, 229, 220, 192, 39, 1, 191, 240, 192, - 39, 1, 233, 213, 192, 39, 33, 230, 25, 77, 192, 39, 33, 217, 121, 77, - 192, 39, 228, 56, 77, 192, 39, 1, 220, 12, 4, 75, 56, 192, 39, 1, 191, - 241, 4, 242, 210, 56, 38, 202, 23, 1, 251, 139, 38, 202, 23, 1, 52, 251, - 139, 38, 202, 23, 1, 248, 161, 38, 202, 23, 1, 52, 248, 161, 38, 202, 23, - 1, 231, 1, 38, 202, 23, 1, 229, 213, 38, 202, 23, 1, 52, 229, 213, 38, - 202, 23, 1, 193, 131, 38, 202, 23, 1, 191, 91, 38, 202, 23, 1, 229, 152, - 38, 202, 23, 1, 191, 249, 38, 202, 23, 1, 222, 49, 38, 202, 23, 1, 220, - 2, 38, 202, 23, 1, 216, 174, 38, 202, 23, 1, 212, 117, 38, 202, 23, 1, - 52, 212, 117, 38, 202, 23, 1, 52, 212, 118, 4, 81, 199, 210, 38, 202, 23, - 1, 205, 143, 38, 202, 23, 1, 250, 76, 38, 202, 23, 1, 251, 106, 250, 76, - 38, 202, 23, 1, 210, 53, 38, 202, 23, 1, 205, 184, 38, 202, 23, 1, 52, - 205, 184, 38, 202, 23, 1, 52, 205, 185, 4, 81, 199, 210, 38, 202, 23, 1, - 207, 31, 38, 202, 23, 1, 203, 64, 38, 202, 23, 1, 199, 154, 38, 202, 23, - 1, 52, 199, 154, 38, 202, 23, 1, 52, 199, 155, 4, 81, 199, 210, 38, 202, - 23, 31, 108, 38, 202, 23, 31, 109, 38, 202, 23, 31, 139, 38, 202, 23, 31, - 137, 38, 202, 23, 31, 153, 38, 202, 23, 31, 199, 90, 38, 202, 23, 31, - 197, 28, 38, 202, 23, 31, 198, 244, 38, 202, 23, 31, 91, 228, 109, 38, - 202, 23, 232, 80, 91, 230, 37, 38, 202, 23, 34, 250, 75, 202, 23, 1, 251, - 139, 202, 23, 1, 248, 161, 202, 23, 1, 231, 1, 202, 23, 1, 229, 213, 202, - 23, 1, 193, 131, 202, 23, 1, 191, 91, 202, 23, 1, 229, 152, 202, 23, 1, - 191, 249, 202, 23, 1, 222, 49, 202, 23, 1, 220, 2, 202, 23, 1, 216, 174, - 202, 23, 1, 212, 117, 202, 23, 1, 205, 143, 202, 23, 1, 250, 76, 202, 23, - 1, 210, 53, 202, 23, 1, 205, 184, 202, 23, 1, 207, 32, 202, 23, 1, 203, - 64, 202, 23, 1, 199, 154, 202, 23, 1, 232, 245, 202, 23, 1, 219, 158, - 202, 23, 223, 121, 203, 64, 202, 23, 33, 75, 60, 202, 23, 33, 103, 183, - 60, 202, 23, 33, 75, 56, 202, 23, 33, 103, 183, 56, 202, 23, 33, 238, - 118, 56, 202, 23, 33, 238, 118, 60, 202, 23, 33, 228, 219, 56, 202, 23, - 33, 228, 219, 60, 202, 23, 33, 177, 228, 219, 60, 202, 23, 33, 207, 34, - 60, 202, 23, 33, 201, 23, 60, 202, 23, 31, 108, 202, 23, 31, 199, 90, - 202, 23, 31, 197, 28, 202, 23, 31, 91, 228, 109, 202, 23, 208, 145, 103, - 81, 249, 26, 202, 23, 208, 145, 103, 81, 249, 27, 4, 236, 94, 202, 23, - 208, 145, 242, 219, 4, 236, 96, 202, 23, 208, 145, 103, 242, 216, 4, 236, - 94, 202, 23, 208, 145, 134, 242, 219, 4, 236, 96, 38, 196, 15, 1, 251, - 139, 38, 196, 15, 1, 248, 161, 38, 196, 15, 1, 231, 0, 38, 196, 15, 1, - 193, 131, 38, 196, 15, 1, 191, 91, 38, 196, 15, 1, 52, 229, 152, 38, 196, - 15, 1, 191, 249, 38, 196, 15, 1, 222, 49, 38, 196, 15, 1, 220, 2, 38, - 196, 15, 1, 216, 174, 38, 196, 15, 1, 212, 117, 38, 196, 15, 1, 205, 143, - 38, 196, 15, 1, 210, 53, 38, 196, 15, 1, 205, 184, 38, 196, 15, 1, 207, - 33, 38, 196, 15, 1, 203, 64, 38, 196, 15, 1, 199, 154, 38, 196, 15, 1, - 219, 158, 38, 196, 15, 33, 75, 56, 38, 196, 15, 33, 75, 60, 38, 196, 15, - 33, 103, 183, 56, 38, 196, 15, 33, 103, 183, 60, 38, 196, 15, 208, 145, - 164, 38, 196, 15, 208, 145, 103, 249, 26, 38, 196, 15, 208, 145, 103, - 236, 94, 38, 196, 15, 208, 145, 232, 90, 236, 94, 243, 13, 1, 251, 139, - 243, 13, 1, 2, 251, 139, 243, 13, 1, 248, 161, 243, 13, 1, 231, 1, 243, - 13, 1, 237, 205, 243, 13, 1, 229, 213, 243, 13, 1, 193, 131, 243, 13, 1, - 238, 127, 193, 131, 243, 13, 1, 191, 91, 243, 13, 1, 229, 152, 243, 13, - 1, 191, 249, 243, 13, 1, 222, 49, 243, 13, 1, 220, 2, 243, 13, 1, 216, - 174, 243, 13, 1, 212, 117, 243, 13, 1, 205, 143, 243, 13, 1, 250, 76, - 243, 13, 1, 210, 53, 243, 13, 1, 207, 33, 243, 13, 1, 203, 64, 243, 13, - 1, 199, 154, 243, 13, 31, 108, 243, 13, 31, 109, 243, 13, 31, 139, 243, - 13, 31, 137, 243, 13, 31, 199, 90, 243, 13, 31, 197, 28, 243, 13, 31, 91, - 228, 109, 234, 74, 1, 251, 139, 234, 74, 1, 248, 161, 234, 74, 1, 231, 1, - 234, 74, 1, 237, 205, 234, 74, 1, 229, 213, 234, 74, 1, 193, 131, 234, - 74, 1, 191, 91, 234, 74, 1, 229, 152, 234, 74, 1, 199, 64, 234, 74, 1, - 191, 249, 234, 74, 1, 222, 49, 234, 74, 1, 220, 2, 234, 74, 1, 216, 174, - 234, 74, 1, 212, 117, 234, 74, 1, 205, 143, 234, 74, 1, 250, 76, 234, 74, - 1, 210, 53, 234, 74, 1, 205, 184, 234, 74, 1, 208, 31, 234, 74, 1, 207, - 33, 234, 74, 1, 203, 64, 234, 74, 1, 199, 154, 234, 74, 34, 191, 90, 162, - 3, 247, 71, 162, 3, 251, 20, 162, 3, 195, 32, 162, 3, 222, 210, 162, 3, - 196, 71, 162, 1, 65, 162, 1, 252, 154, 162, 1, 70, 162, 1, 223, 170, 162, - 1, 69, 162, 1, 196, 26, 162, 1, 121, 148, 162, 1, 121, 206, 105, 162, 1, - 121, 170, 162, 1, 121, 219, 50, 162, 1, 73, 162, 1, 251, 184, 162, 1, 74, - 162, 1, 250, 113, 162, 1, 157, 162, 1, 221, 190, 162, 1, 231, 203, 162, - 1, 231, 54, 162, 1, 214, 54, 162, 1, 247, 112, 162, 1, 246, 209, 162, 1, - 223, 4, 162, 1, 222, 225, 162, 1, 212, 88, 162, 1, 197, 128, 162, 1, 197, - 116, 162, 1, 237, 146, 162, 1, 237, 130, 162, 1, 213, 66, 162, 1, 199, - 247, 162, 1, 199, 44, 162, 1, 237, 241, 162, 1, 237, 23, 162, 1, 180, - 162, 1, 168, 162, 1, 209, 219, 162, 1, 249, 103, 162, 1, 248, 153, 162, - 1, 172, 162, 1, 169, 162, 1, 166, 162, 1, 171, 162, 1, 195, 185, 162, 1, - 203, 160, 162, 1, 201, 170, 162, 1, 189, 162, 1, 144, 162, 1, 219, 49, - 162, 1, 38, 44, 219, 38, 162, 1, 38, 44, 206, 104, 162, 1, 38, 44, 213, - 48, 162, 18, 3, 252, 154, 162, 18, 3, 248, 149, 252, 154, 162, 18, 3, 70, - 162, 18, 3, 223, 170, 162, 18, 3, 69, 162, 18, 3, 196, 26, 162, 18, 3, - 121, 148, 162, 18, 3, 121, 206, 105, 162, 18, 3, 121, 170, 162, 18, 3, - 121, 219, 50, 162, 18, 3, 73, 162, 18, 3, 251, 184, 162, 18, 3, 74, 162, - 18, 3, 250, 113, 162, 195, 37, 162, 237, 193, 162, 54, 237, 193, 162, - 208, 145, 236, 96, 162, 208, 145, 54, 236, 96, 162, 208, 145, 219, 88, - 162, 208, 145, 238, 181, 164, 162, 208, 145, 218, 224, 162, 31, 108, 162, - 31, 109, 162, 31, 139, 162, 31, 137, 162, 31, 153, 162, 31, 173, 162, 31, - 181, 162, 31, 176, 162, 31, 184, 162, 31, 199, 90, 162, 31, 197, 28, 162, - 31, 198, 244, 162, 31, 232, 97, 162, 31, 232, 230, 162, 31, 202, 115, - 162, 31, 203, 236, 162, 31, 234, 110, 162, 31, 213, 156, 162, 31, 91, - 228, 109, 162, 31, 91, 188, 162, 17, 191, 77, 162, 17, 108, 162, 17, 109, - 162, 17, 139, 162, 17, 137, 162, 17, 153, 162, 17, 173, 162, 17, 181, - 162, 17, 176, 162, 17, 184, 162, 3, 38, 44, 195, 37, 162, 1, 38, 44, 203, - 35, 73, 162, 1, 38, 44, 203, 35, 74, 162, 18, 3, 38, 44, 203, 35, 73, - 162, 18, 3, 38, 44, 203, 35, 74, 162, 1, 38, 44, 219, 49, 162, 31, 222, - 169, 222, 72, 3, 247, 71, 222, 72, 3, 251, 20, 222, 72, 3, 195, 32, 222, - 72, 1, 65, 222, 72, 1, 252, 154, 222, 72, 1, 70, 222, 72, 1, 223, 170, - 222, 72, 1, 69, 222, 72, 1, 196, 26, 222, 72, 1, 73, 222, 72, 1, 251, - 184, 222, 72, 1, 74, 222, 72, 1, 250, 113, 222, 72, 1, 157, 222, 72, 1, - 221, 190, 222, 72, 1, 231, 203, 222, 72, 1, 231, 54, 222, 72, 1, 214, 54, - 222, 72, 1, 247, 112, 222, 72, 1, 246, 209, 222, 72, 1, 223, 4, 222, 72, - 1, 222, 225, 222, 72, 1, 212, 88, 222, 72, 1, 197, 128, 222, 72, 1, 197, - 116, 222, 72, 1, 237, 146, 222, 72, 1, 237, 135, 222, 72, 1, 237, 130, - 222, 72, 1, 207, 1, 222, 72, 1, 213, 66, 222, 72, 1, 199, 247, 222, 72, - 1, 199, 44, 222, 72, 1, 237, 241, 222, 72, 1, 237, 23, 222, 72, 1, 180, - 222, 72, 1, 168, 222, 72, 1, 209, 219, 222, 72, 1, 249, 103, 222, 72, 1, - 248, 153, 222, 72, 1, 172, 222, 72, 1, 169, 222, 72, 1, 166, 222, 72, 1, - 171, 222, 72, 1, 195, 185, 222, 72, 1, 203, 160, 222, 72, 1, 201, 170, - 222, 72, 1, 189, 222, 72, 1, 144, 222, 72, 18, 3, 252, 154, 222, 72, 18, - 3, 70, 222, 72, 18, 3, 223, 170, 222, 72, 18, 3, 69, 222, 72, 18, 3, 196, - 26, 222, 72, 18, 3, 73, 222, 72, 18, 3, 251, 184, 222, 72, 18, 3, 74, - 222, 72, 18, 3, 250, 113, 222, 72, 3, 195, 37, 222, 72, 3, 212, 128, 222, - 72, 252, 16, 57, 222, 72, 234, 27, 57, 222, 72, 31, 57, 222, 72, 205, 49, - 77, 222, 72, 54, 205, 49, 77, 222, 72, 237, 193, 222, 72, 54, 237, 193, - 222, 72, 18, 3, 121, 148, 222, 72, 31, 3, 56, 202, 7, 202, 15, 1, 205, - 177, 202, 7, 202, 15, 1, 199, 214, 202, 7, 202, 15, 1, 249, 73, 202, 7, - 202, 15, 1, 247, 101, 202, 7, 202, 15, 1, 237, 221, 202, 7, 202, 15, 1, - 231, 188, 202, 7, 202, 15, 1, 217, 99, 202, 7, 202, 15, 1, 214, 51, 202, - 7, 202, 15, 1, 220, 75, 202, 7, 202, 15, 1, 214, 223, 202, 7, 202, 15, 1, - 195, 181, 202, 7, 202, 15, 1, 210, 190, 202, 7, 202, 15, 1, 192, 121, - 202, 7, 202, 15, 1, 207, 155, 202, 7, 202, 15, 1, 230, 48, 202, 7, 202, - 15, 1, 222, 77, 202, 7, 202, 15, 1, 222, 254, 202, 7, 202, 15, 1, 212, - 85, 202, 7, 202, 15, 1, 251, 193, 202, 7, 202, 15, 1, 234, 143, 202, 7, - 202, 15, 1, 223, 171, 202, 7, 202, 15, 1, 196, 137, 202, 7, 202, 15, 1, - 211, 124, 202, 7, 202, 15, 1, 234, 130, 202, 7, 202, 15, 1, 217, 115, - 202, 7, 202, 15, 17, 191, 77, 202, 7, 202, 15, 17, 108, 202, 7, 202, 15, - 17, 109, 202, 7, 202, 15, 17, 139, 202, 7, 202, 15, 17, 137, 202, 7, 202, - 15, 17, 153, 202, 7, 202, 15, 17, 173, 202, 7, 202, 15, 17, 181, 202, 7, - 202, 15, 17, 176, 202, 7, 202, 15, 17, 184, 246, 203, 3, 247, 71, 246, - 203, 3, 251, 20, 246, 203, 3, 195, 32, 246, 203, 1, 252, 154, 246, 203, - 1, 70, 246, 203, 1, 69, 246, 203, 1, 73, 246, 203, 1, 222, 100, 246, 203, - 1, 221, 189, 246, 203, 1, 231, 200, 246, 203, 1, 231, 53, 246, 203, 1, - 214, 53, 246, 203, 1, 247, 111, 246, 203, 1, 246, 208, 246, 203, 1, 223, - 3, 246, 203, 1, 222, 224, 246, 203, 1, 212, 87, 246, 203, 1, 197, 127, - 246, 203, 1, 197, 115, 246, 203, 1, 237, 145, 246, 203, 1, 237, 129, 246, - 203, 1, 213, 65, 246, 203, 1, 199, 240, 246, 203, 1, 199, 43, 246, 203, - 1, 237, 240, 246, 203, 1, 237, 22, 246, 203, 1, 214, 236, 246, 203, 1, - 210, 210, 246, 203, 1, 209, 218, 246, 203, 1, 249, 101, 246, 203, 1, 248, - 152, 246, 203, 1, 217, 130, 246, 203, 1, 191, 174, 246, 203, 1, 192, 140, - 246, 203, 1, 207, 173, 246, 203, 1, 220, 101, 246, 203, 1, 193, 178, 246, - 203, 1, 205, 192, 246, 203, 1, 230, 58, 246, 203, 18, 3, 65, 246, 203, - 18, 3, 70, 246, 203, 18, 3, 223, 170, 246, 203, 18, 3, 69, 246, 203, 18, - 3, 196, 26, 246, 203, 18, 3, 73, 246, 203, 18, 3, 251, 184, 246, 203, 18, - 3, 74, 246, 203, 18, 3, 250, 113, 246, 203, 18, 3, 211, 121, 246, 203, - 186, 77, 246, 203, 250, 114, 77, 246, 203, 195, 37, 246, 203, 217, 128, - 246, 203, 17, 191, 77, 246, 203, 17, 108, 246, 203, 17, 109, 246, 203, - 17, 139, 246, 203, 17, 137, 246, 203, 17, 153, 246, 203, 17, 173, 246, - 203, 17, 181, 246, 203, 17, 176, 246, 203, 17, 184, 246, 203, 205, 49, - 77, 246, 203, 237, 193, 246, 203, 54, 237, 193, 246, 203, 208, 8, 77, - 246, 203, 1, 219, 134, 246, 203, 18, 3, 252, 154, 246, 203, 18, 3, 234, - 123, 246, 203, 1, 195, 184, 217, 97, 1, 65, 217, 97, 1, 70, 217, 97, 1, - 69, 217, 97, 1, 73, 217, 97, 1, 74, 217, 97, 1, 157, 217, 97, 1, 221, - 190, 217, 97, 1, 231, 203, 217, 97, 1, 231, 54, 217, 97, 1, 247, 112, - 217, 97, 1, 246, 209, 217, 97, 1, 223, 4, 217, 97, 1, 222, 225, 217, 97, - 1, 212, 88, 217, 97, 1, 197, 128, 217, 97, 1, 197, 116, 217, 97, 1, 237, - 146, 217, 97, 1, 237, 130, 217, 97, 1, 213, 66, 217, 97, 1, 199, 247, - 217, 97, 1, 199, 44, 217, 97, 1, 237, 241, 217, 97, 1, 237, 23, 217, 97, - 1, 180, 217, 97, 1, 168, 217, 97, 1, 209, 219, 217, 97, 1, 249, 103, 217, - 97, 1, 248, 153, 217, 97, 1, 172, 217, 97, 1, 166, 217, 97, 1, 171, 217, - 97, 1, 195, 185, 217, 97, 1, 189, 217, 97, 1, 144, 217, 97, 1, 206, 104, - 217, 97, 3, 212, 128, 217, 97, 252, 16, 57, 217, 97, 205, 49, 77, 217, - 97, 34, 203, 10, 203, 124, 3, 247, 71, 203, 124, 3, 251, 20, 203, 124, 3, - 195, 32, 203, 124, 1, 65, 203, 124, 1, 252, 154, 203, 124, 1, 70, 203, - 124, 1, 223, 170, 203, 124, 1, 69, 203, 124, 1, 196, 26, 203, 124, 1, - 121, 148, 203, 124, 1, 121, 206, 105, 203, 124, 1, 121, 170, 203, 124, 1, - 121, 219, 50, 203, 124, 1, 73, 203, 124, 1, 251, 184, 203, 124, 1, 74, - 203, 124, 1, 250, 113, 203, 124, 1, 157, 203, 124, 1, 221, 190, 203, 124, - 1, 231, 203, 203, 124, 1, 231, 54, 203, 124, 1, 214, 54, 203, 124, 1, - 247, 112, 203, 124, 1, 246, 209, 203, 124, 1, 223, 4, 203, 124, 1, 222, - 225, 203, 124, 1, 212, 88, 203, 124, 1, 197, 128, 203, 124, 1, 197, 116, - 203, 124, 1, 237, 146, 203, 124, 1, 237, 130, 203, 124, 1, 213, 66, 203, - 124, 1, 199, 247, 203, 124, 1, 199, 44, 203, 124, 1, 237, 241, 203, 124, - 1, 237, 23, 203, 124, 1, 180, 203, 124, 1, 168, 203, 124, 1, 209, 219, - 203, 124, 1, 249, 103, 203, 124, 1, 248, 153, 203, 124, 1, 172, 203, 124, - 1, 169, 203, 124, 1, 166, 203, 124, 1, 171, 203, 124, 1, 219, 49, 203, - 124, 1, 195, 185, 203, 124, 1, 203, 160, 203, 124, 1, 201, 170, 203, 124, - 1, 189, 203, 124, 1, 144, 203, 124, 18, 3, 252, 154, 203, 124, 18, 3, 70, - 203, 124, 18, 3, 223, 170, 203, 124, 18, 3, 69, 203, 124, 18, 3, 196, 26, - 203, 124, 18, 3, 121, 148, 203, 124, 18, 3, 121, 206, 105, 203, 124, 18, - 3, 121, 170, 203, 124, 18, 3, 121, 219, 50, 203, 124, 18, 3, 73, 203, - 124, 18, 3, 251, 184, 203, 124, 18, 3, 74, 203, 124, 18, 3, 250, 113, - 203, 124, 3, 195, 37, 203, 124, 3, 250, 95, 203, 124, 3, 222, 210, 203, - 124, 3, 196, 71, 203, 124, 211, 102, 203, 124, 237, 193, 203, 124, 54, - 237, 193, 203, 124, 252, 16, 57, 203, 124, 204, 5, 203, 124, 205, 133, - 77, 203, 124, 3, 212, 128, 203, 124, 18, 59, 77, 203, 124, 233, 160, 203, - 35, 18, 77, 203, 124, 200, 157, 77, 203, 124, 18, 3, 208, 200, 73, 203, - 124, 3, 223, 65, 247, 71, 203, 124, 17, 191, 77, 203, 124, 17, 108, 203, - 124, 17, 109, 203, 124, 17, 139, 203, 124, 17, 137, 203, 124, 17, 153, - 203, 124, 17, 173, 203, 124, 17, 181, 203, 124, 17, 176, 203, 124, 17, - 184, 203, 124, 234, 103, 203, 124, 3, 202, 205, 203, 124, 229, 195, 203, - 124, 238, 238, 57, 203, 124, 205, 49, 217, 36, 203, 124, 205, 49, 217, - 35, 165, 250, 220, 17, 108, 165, 250, 220, 17, 109, 165, 250, 220, 17, - 139, 165, 250, 220, 17, 137, 165, 250, 220, 17, 153, 165, 250, 220, 17, - 173, 165, 250, 220, 17, 181, 165, 250, 220, 17, 176, 165, 250, 220, 17, - 184, 165, 250, 220, 31, 199, 90, 165, 250, 220, 31, 197, 28, 165, 250, - 220, 31, 198, 244, 165, 250, 220, 31, 232, 97, 165, 250, 220, 31, 232, - 230, 165, 250, 220, 31, 202, 115, 165, 250, 220, 31, 203, 236, 165, 250, - 220, 31, 234, 110, 165, 250, 220, 31, 213, 156, 165, 250, 220, 31, 91, - 228, 109, 165, 250, 220, 31, 91, 188, 221, 158, 1, 65, 221, 158, 1, 252, - 154, 221, 158, 1, 70, 221, 158, 1, 69, 221, 158, 1, 73, 221, 158, 1, 251, - 184, 221, 158, 1, 74, 221, 158, 1, 250, 113, 221, 158, 1, 157, 221, 158, - 1, 221, 190, 221, 158, 1, 231, 203, 221, 158, 1, 231, 90, 221, 158, 1, - 231, 54, 221, 158, 1, 214, 54, 221, 158, 1, 247, 112, 221, 158, 1, 246, - 209, 221, 158, 1, 223, 4, 221, 158, 1, 222, 203, 221, 158, 1, 212, 88, - 221, 158, 1, 197, 128, 221, 158, 1, 197, 116, 221, 158, 1, 237, 146, 221, - 158, 1, 237, 130, 221, 158, 1, 213, 66, 221, 158, 1, 199, 247, 221, 158, - 1, 199, 44, 221, 158, 1, 237, 241, 221, 158, 1, 237, 136, 221, 158, 1, - 237, 23, 221, 158, 1, 180, 221, 158, 1, 168, 221, 158, 1, 209, 219, 221, - 158, 1, 249, 103, 221, 158, 1, 249, 3, 221, 158, 1, 248, 153, 221, 158, - 1, 172, 221, 158, 1, 169, 221, 158, 1, 166, 221, 158, 1, 171, 221, 158, - 1, 195, 185, 221, 158, 1, 189, 221, 158, 1, 144, 221, 158, 1, 219, 49, - 221, 158, 18, 3, 252, 154, 221, 158, 18, 3, 70, 221, 158, 18, 3, 223, - 170, 221, 158, 18, 3, 69, 221, 158, 18, 3, 73, 221, 158, 18, 3, 251, 184, - 221, 158, 18, 3, 74, 221, 158, 18, 3, 250, 113, 221, 158, 3, 251, 20, - 221, 158, 3, 195, 37, 221, 158, 3, 212, 128, 221, 158, 3, 203, 150, 221, - 158, 237, 193, 221, 158, 54, 237, 193, 221, 158, 193, 23, 204, 5, 221, - 158, 205, 49, 77, 221, 158, 54, 205, 49, 77, 221, 158, 252, 16, 57, 221, - 158, 3, 200, 201, 215, 118, 1, 65, 215, 118, 1, 70, 215, 118, 1, 69, 215, - 118, 1, 73, 215, 118, 1, 157, 215, 118, 1, 221, 190, 215, 118, 1, 231, - 203, 215, 118, 1, 231, 54, 215, 118, 1, 247, 112, 215, 118, 1, 246, 209, - 215, 118, 1, 223, 4, 215, 118, 1, 222, 203, 215, 118, 1, 212, 88, 215, - 118, 1, 197, 128, 215, 118, 1, 197, 116, 215, 118, 1, 237, 146, 215, 118, - 1, 237, 136, 215, 118, 1, 237, 130, 215, 118, 1, 213, 66, 215, 118, 1, - 199, 247, 215, 118, 1, 199, 44, 215, 118, 1, 237, 241, 215, 118, 1, 237, - 23, 215, 118, 1, 180, 215, 118, 1, 168, 215, 118, 1, 209, 219, 215, 118, - 1, 249, 103, 215, 118, 1, 248, 153, 215, 118, 1, 172, 215, 118, 1, 169, - 215, 118, 1, 166, 215, 118, 1, 171, 215, 118, 1, 195, 185, 215, 118, 1, - 189, 215, 118, 1, 144, 215, 118, 1, 206, 104, 215, 118, 1, 207, 1, 215, - 118, 205, 49, 77, 221, 148, 1, 65, 221, 148, 1, 252, 154, 221, 148, 1, - 70, 221, 148, 1, 223, 170, 221, 148, 1, 69, 221, 148, 1, 196, 26, 221, - 148, 1, 73, 221, 148, 1, 251, 184, 221, 148, 1, 74, 221, 148, 1, 250, - 113, 221, 148, 1, 157, 221, 148, 1, 221, 190, 221, 148, 1, 231, 203, 221, - 148, 1, 231, 90, 221, 148, 1, 231, 54, 221, 148, 1, 214, 54, 221, 148, 1, - 247, 112, 221, 148, 1, 246, 209, 221, 148, 1, 223, 4, 221, 148, 1, 222, - 203, 221, 148, 1, 222, 225, 221, 148, 1, 212, 88, 221, 148, 1, 197, 128, - 221, 148, 1, 197, 116, 221, 148, 1, 237, 146, 221, 148, 1, 237, 136, 221, - 148, 1, 206, 104, 221, 148, 1, 237, 130, 221, 148, 1, 213, 66, 221, 148, - 1, 199, 247, 221, 148, 1, 199, 44, 221, 148, 1, 237, 241, 221, 148, 1, - 237, 23, 221, 148, 1, 180, 221, 148, 1, 168, 221, 148, 1, 209, 219, 221, - 148, 1, 249, 103, 221, 148, 1, 249, 3, 221, 148, 1, 248, 153, 221, 148, - 1, 172, 221, 148, 1, 169, 221, 148, 1, 166, 221, 148, 1, 171, 221, 148, - 1, 195, 185, 221, 148, 1, 203, 160, 221, 148, 1, 189, 221, 148, 1, 144, - 221, 148, 3, 251, 20, 221, 148, 18, 3, 252, 154, 221, 148, 18, 3, 70, - 221, 148, 18, 3, 223, 170, 221, 148, 18, 3, 69, 221, 148, 18, 3, 196, 26, - 221, 148, 18, 3, 73, 221, 148, 18, 3, 251, 184, 221, 148, 18, 3, 74, 221, - 148, 18, 3, 250, 113, 221, 148, 3, 212, 128, 221, 148, 3, 195, 37, 221, - 148, 17, 191, 77, 221, 148, 17, 108, 221, 148, 17, 109, 221, 148, 17, - 139, 221, 148, 17, 137, 221, 148, 17, 153, 221, 148, 17, 173, 221, 148, - 17, 181, 221, 148, 17, 176, 221, 148, 17, 184, 230, 185, 3, 33, 251, 21, - 56, 230, 185, 3, 247, 71, 230, 185, 3, 251, 20, 230, 185, 3, 195, 32, - 230, 185, 1, 65, 230, 185, 1, 252, 154, 230, 185, 1, 70, 230, 185, 1, - 223, 170, 230, 185, 1, 69, 230, 185, 1, 196, 26, 230, 185, 1, 121, 148, - 230, 185, 1, 121, 170, 230, 185, 1, 234, 145, 230, 185, 1, 251, 184, 230, - 185, 1, 211, 76, 230, 185, 1, 250, 113, 230, 185, 1, 157, 230, 185, 1, - 221, 190, 230, 185, 1, 231, 203, 230, 185, 1, 231, 54, 230, 185, 1, 214, - 54, 230, 185, 1, 247, 112, 230, 185, 1, 246, 209, 230, 185, 1, 223, 4, - 230, 185, 1, 222, 225, 230, 185, 1, 212, 88, 230, 185, 1, 197, 128, 230, - 185, 1, 197, 116, 230, 185, 1, 237, 146, 230, 185, 1, 237, 130, 230, 185, - 1, 213, 66, 230, 185, 1, 199, 247, 230, 185, 1, 199, 44, 230, 185, 1, - 237, 241, 230, 185, 1, 237, 23, 230, 185, 1, 180, 230, 185, 1, 168, 230, - 185, 1, 209, 219, 230, 185, 1, 249, 103, 230, 185, 1, 248, 153, 230, 185, - 1, 172, 230, 185, 1, 169, 230, 185, 1, 166, 230, 185, 1, 171, 230, 185, - 1, 219, 49, 230, 185, 1, 195, 185, 230, 185, 1, 203, 160, 230, 185, 1, - 201, 170, 230, 185, 1, 189, 230, 185, 1, 144, 33, 248, 117, 60, 230, 185, - 3, 212, 128, 230, 185, 3, 250, 95, 230, 185, 18, 3, 252, 154, 230, 185, - 18, 3, 70, 230, 185, 18, 3, 223, 170, 230, 185, 18, 3, 69, 230, 185, 18, - 3, 196, 26, 230, 185, 18, 3, 121, 148, 230, 185, 18, 3, 121, 206, 105, - 230, 185, 18, 3, 234, 145, 230, 185, 18, 3, 251, 184, 230, 185, 18, 3, - 211, 76, 230, 185, 18, 3, 250, 113, 230, 185, 3, 195, 37, 230, 185, 211, - 102, 230, 185, 250, 114, 219, 174, 77, 230, 185, 3, 209, 71, 230, 185, 1, - 195, 147, 251, 20, 230, 185, 1, 195, 147, 54, 251, 20, 230, 185, 1, 121, - 206, 105, 230, 185, 1, 121, 219, 50, 230, 185, 18, 3, 121, 170, 230, 185, - 18, 3, 121, 219, 50, 33, 230, 185, 17, 191, 77, 33, 230, 185, 17, 108, - 33, 230, 185, 17, 109, 33, 230, 185, 17, 139, 33, 230, 185, 17, 137, 33, - 230, 185, 17, 153, 33, 230, 185, 17, 173, 33, 230, 185, 1, 65, 33, 230, - 185, 1, 157, 33, 230, 185, 1, 180, 33, 230, 185, 1, 195, 66, 33, 230, - 185, 1, 168, 214, 64, 1, 65, 214, 64, 1, 252, 154, 214, 64, 1, 70, 214, - 64, 1, 223, 170, 214, 64, 1, 69, 214, 64, 1, 196, 26, 214, 64, 1, 121, - 148, 214, 64, 1, 121, 206, 105, 214, 64, 1, 121, 170, 214, 64, 1, 121, - 219, 50, 214, 64, 1, 73, 214, 64, 1, 251, 184, 214, 64, 1, 74, 214, 64, - 1, 250, 113, 214, 64, 1, 157, 214, 64, 1, 221, 190, 214, 64, 1, 231, 203, - 214, 64, 1, 231, 54, 214, 64, 1, 214, 54, 214, 64, 1, 214, 3, 214, 64, 1, - 247, 112, 214, 64, 1, 246, 209, 214, 64, 1, 223, 4, 214, 64, 1, 222, 225, - 214, 64, 1, 212, 88, 214, 64, 1, 212, 70, 214, 64, 1, 197, 128, 214, 64, - 1, 197, 116, 214, 64, 1, 237, 146, 214, 64, 1, 237, 130, 214, 64, 1, 213, - 66, 214, 64, 1, 199, 247, 214, 64, 1, 199, 44, 214, 64, 1, 237, 241, 214, - 64, 1, 237, 23, 214, 64, 1, 180, 214, 64, 1, 213, 210, 214, 64, 1, 168, - 214, 64, 1, 209, 219, 214, 64, 1, 249, 103, 214, 64, 1, 248, 153, 214, - 64, 1, 172, 214, 64, 1, 216, 84, 214, 64, 1, 169, 214, 64, 1, 166, 214, - 64, 1, 207, 1, 214, 64, 1, 171, 214, 64, 1, 219, 135, 214, 64, 1, 193, - 187, 214, 64, 1, 203, 160, 214, 64, 1, 201, 170, 214, 64, 1, 189, 214, - 64, 1, 144, 214, 64, 18, 3, 252, 154, 214, 64, 18, 3, 70, 214, 64, 18, 3, - 223, 170, 214, 64, 18, 3, 69, 214, 64, 18, 3, 196, 26, 214, 64, 18, 3, - 121, 148, 214, 64, 18, 3, 121, 206, 105, 214, 64, 18, 3, 121, 170, 214, - 64, 18, 3, 121, 219, 50, 214, 64, 18, 3, 73, 214, 64, 18, 3, 251, 184, - 214, 64, 18, 3, 74, 214, 64, 18, 3, 250, 113, 214, 64, 3, 195, 37, 214, - 64, 3, 247, 71, 214, 64, 3, 251, 20, 214, 64, 3, 195, 32, 214, 64, 3, - 212, 128, 214, 64, 3, 250, 95, 214, 64, 3, 52, 251, 20, 214, 64, 211, - 102, 214, 64, 202, 204, 214, 64, 237, 193, 214, 64, 54, 237, 193, 214, - 64, 242, 26, 214, 64, 231, 167, 232, 218, 214, 64, 252, 16, 57, 214, 64, - 17, 191, 77, 214, 64, 17, 108, 214, 64, 17, 109, 214, 64, 17, 139, 214, - 64, 17, 137, 214, 64, 17, 153, 214, 64, 17, 173, 214, 64, 17, 181, 214, - 64, 17, 176, 214, 64, 17, 184, 214, 64, 54, 242, 26, 214, 64, 209, 99, - 77, 214, 64, 223, 91, 57, 214, 64, 205, 133, 77, 214, 64, 1, 195, 147, - 251, 20, 214, 64, 3, 222, 210, 214, 64, 3, 196, 71, 198, 124, 251, 49, - 198, 124, 1, 65, 198, 124, 1, 252, 154, 198, 124, 1, 70, 198, 124, 1, - 223, 170, 198, 124, 1, 69, 198, 124, 1, 196, 26, 198, 124, 1, 121, 148, - 198, 124, 1, 121, 206, 105, 198, 124, 1, 121, 170, 198, 124, 1, 121, 219, - 50, 198, 124, 1, 73, 198, 124, 1, 251, 184, 198, 124, 1, 74, 198, 124, 1, - 250, 113, 198, 124, 1, 157, 198, 124, 1, 221, 190, 198, 124, 1, 231, 203, - 198, 124, 1, 231, 54, 198, 124, 1, 214, 54, 198, 124, 1, 247, 112, 198, - 124, 1, 246, 209, 198, 124, 1, 223, 4, 198, 124, 1, 222, 225, 198, 124, - 1, 212, 88, 198, 124, 1, 197, 128, 198, 124, 1, 197, 116, 198, 124, 1, - 237, 146, 198, 124, 1, 237, 130, 198, 124, 1, 213, 66, 198, 124, 1, 199, - 247, 198, 124, 1, 199, 44, 198, 124, 1, 237, 241, 198, 124, 1, 237, 23, - 198, 124, 1, 180, 198, 124, 1, 168, 198, 124, 1, 209, 219, 198, 124, 1, - 249, 103, 198, 124, 1, 248, 153, 198, 124, 1, 172, 198, 124, 1, 169, 198, - 124, 1, 166, 198, 124, 1, 171, 198, 124, 1, 195, 185, 198, 124, 1, 203, - 160, 198, 124, 1, 201, 170, 198, 124, 1, 189, 198, 124, 1, 144, 198, 124, - 18, 3, 252, 154, 198, 124, 18, 3, 70, 198, 124, 18, 3, 223, 170, 198, - 124, 18, 3, 69, 198, 124, 18, 3, 196, 26, 198, 124, 18, 3, 121, 148, 198, - 124, 18, 3, 121, 206, 105, 198, 124, 18, 3, 121, 170, 198, 124, 18, 3, - 121, 219, 50, 198, 124, 18, 3, 73, 198, 124, 18, 3, 203, 35, 73, 198, - 124, 18, 3, 251, 184, 198, 124, 18, 3, 74, 198, 124, 18, 3, 203, 35, 74, - 198, 124, 18, 3, 250, 113, 198, 124, 3, 247, 71, 198, 124, 3, 251, 20, - 198, 124, 3, 195, 32, 198, 124, 3, 195, 37, 198, 124, 3, 212, 128, 198, - 124, 3, 250, 95, 198, 124, 230, 104, 198, 124, 252, 16, 57, 198, 124, - 211, 102, 198, 124, 17, 191, 77, 198, 124, 17, 108, 198, 124, 17, 109, - 198, 124, 17, 139, 198, 124, 17, 137, 198, 124, 17, 153, 198, 124, 17, - 173, 198, 124, 17, 181, 198, 124, 17, 176, 198, 124, 17, 184, 202, 206, - 1, 65, 202, 206, 1, 252, 154, 202, 206, 1, 70, 202, 206, 1, 223, 170, - 202, 206, 1, 69, 202, 206, 1, 196, 26, 202, 206, 1, 121, 148, 202, 206, - 1, 121, 206, 105, 202, 206, 1, 121, 170, 202, 206, 1, 121, 219, 50, 202, - 206, 1, 73, 202, 206, 1, 251, 184, 202, 206, 1, 74, 202, 206, 1, 250, - 113, 202, 206, 1, 157, 202, 206, 1, 221, 190, 202, 206, 1, 231, 203, 202, - 206, 1, 231, 54, 202, 206, 1, 214, 54, 202, 206, 1, 247, 112, 202, 206, - 1, 246, 209, 202, 206, 1, 223, 4, 202, 206, 1, 222, 225, 202, 206, 1, - 212, 88, 202, 206, 1, 197, 128, 202, 206, 1, 197, 116, 202, 206, 1, 237, - 146, 202, 206, 1, 237, 130, 202, 206, 1, 213, 66, 202, 206, 1, 199, 247, - 202, 206, 1, 199, 44, 202, 206, 1, 237, 241, 202, 206, 1, 237, 23, 202, - 206, 1, 180, 202, 206, 1, 168, 202, 206, 1, 209, 219, 202, 206, 1, 249, - 103, 202, 206, 1, 248, 153, 202, 206, 1, 172, 202, 206, 1, 169, 202, 206, - 1, 166, 202, 206, 1, 171, 202, 206, 1, 195, 185, 202, 206, 1, 203, 160, - 202, 206, 1, 201, 170, 202, 206, 1, 189, 202, 206, 1, 144, 202, 206, 18, - 3, 252, 154, 202, 206, 18, 3, 70, 202, 206, 18, 3, 223, 170, 202, 206, - 18, 3, 69, 202, 206, 18, 3, 196, 26, 202, 206, 18, 3, 121, 148, 202, 206, - 18, 3, 121, 206, 105, 202, 206, 18, 3, 73, 202, 206, 18, 3, 251, 184, - 202, 206, 18, 3, 74, 202, 206, 18, 3, 250, 113, 202, 206, 3, 247, 71, - 202, 206, 3, 251, 20, 202, 206, 3, 195, 32, 202, 206, 3, 195, 37, 202, - 206, 3, 212, 128, 202, 206, 3, 202, 205, 202, 206, 237, 193, 202, 206, - 54, 237, 193, 202, 206, 204, 6, 236, 96, 202, 206, 204, 6, 164, 202, 206, - 207, 41, 217, 36, 202, 206, 207, 41, 217, 35, 202, 206, 207, 41, 217, 34, - 202, 206, 234, 53, 80, 199, 49, 77, 202, 206, 205, 49, 87, 4, 197, 232, - 24, 196, 217, 211, 31, 202, 206, 205, 49, 87, 4, 197, 232, 24, 235, 94, - 238, 179, 202, 206, 205, 49, 87, 4, 207, 115, 24, 235, 94, 238, 179, 202, - 206, 205, 49, 87, 4, 207, 115, 24, 235, 94, 54, 238, 179, 202, 206, 205, - 49, 87, 4, 207, 115, 24, 235, 94, 197, 221, 238, 179, 202, 206, 205, 49, - 87, 54, 206, 183, 202, 206, 205, 49, 87, 54, 206, 184, 4, 207, 114, 202, - 206, 205, 49, 87, 4, 54, 238, 179, 202, 206, 205, 49, 87, 4, 197, 221, - 238, 179, 202, 206, 205, 49, 87, 4, 208, 20, 238, 179, 202, 206, 205, 49, - 87, 4, 204, 3, 238, 179, 202, 206, 205, 49, 87, 4, 242, 216, 24, 207, - 114, 202, 206, 205, 49, 87, 4, 242, 216, 24, 103, 234, 55, 202, 206, 205, - 49, 87, 4, 242, 216, 24, 232, 90, 234, 55, 202, 206, 1, 198, 221, 251, - 106, 70, 202, 206, 1, 197, 11, 251, 106, 70, 202, 206, 1, 197, 11, 251, - 106, 223, 170, 202, 206, 1, 251, 106, 69, 202, 206, 18, 3, 251, 106, 69, - 202, 206, 18, 3, 251, 106, 196, 26, 215, 236, 1, 65, 215, 236, 1, 252, - 154, 215, 236, 1, 70, 215, 236, 1, 223, 170, 215, 236, 1, 69, 215, 236, - 1, 196, 26, 215, 236, 1, 121, 148, 215, 236, 1, 121, 206, 105, 215, 236, - 1, 121, 170, 215, 236, 1, 121, 219, 50, 215, 236, 1, 73, 215, 236, 1, - 251, 184, 215, 236, 1, 74, 215, 236, 1, 250, 113, 215, 236, 1, 157, 215, - 236, 1, 221, 190, 215, 236, 1, 231, 203, 215, 236, 1, 231, 54, 215, 236, - 1, 214, 54, 215, 236, 1, 247, 112, 215, 236, 1, 246, 209, 215, 236, 1, - 223, 4, 215, 236, 1, 222, 225, 215, 236, 1, 212, 88, 215, 236, 1, 197, - 128, 215, 236, 1, 197, 116, 215, 236, 1, 237, 146, 215, 236, 1, 237, 130, - 215, 236, 1, 213, 66, 215, 236, 1, 199, 247, 215, 236, 1, 199, 44, 215, - 236, 1, 237, 241, 215, 236, 1, 237, 23, 215, 236, 1, 180, 215, 236, 1, - 168, 215, 236, 1, 209, 219, 215, 236, 1, 249, 103, 215, 236, 1, 248, 153, - 215, 236, 1, 172, 215, 236, 1, 169, 215, 236, 1, 166, 215, 236, 1, 171, - 215, 236, 1, 195, 185, 215, 236, 1, 203, 160, 215, 236, 1, 201, 170, 215, - 236, 1, 189, 215, 236, 1, 144, 215, 236, 1, 219, 49, 215, 236, 18, 3, - 252, 154, 215, 236, 18, 3, 70, 215, 236, 18, 3, 223, 170, 215, 236, 18, - 3, 69, 215, 236, 18, 3, 196, 26, 215, 236, 18, 3, 121, 148, 215, 236, 18, - 3, 121, 206, 105, 215, 236, 18, 3, 121, 170, 215, 236, 18, 3, 121, 219, - 50, 215, 236, 18, 3, 73, 215, 236, 18, 3, 251, 184, 215, 236, 18, 3, 74, - 215, 236, 18, 3, 250, 113, 215, 236, 3, 251, 20, 215, 236, 3, 195, 32, - 215, 236, 3, 195, 37, 215, 236, 3, 250, 217, 215, 236, 237, 193, 215, - 236, 54, 237, 193, 215, 236, 252, 16, 57, 215, 236, 3, 228, 96, 215, 236, - 17, 191, 77, 215, 236, 17, 108, 215, 236, 17, 109, 215, 236, 17, 139, - 215, 236, 17, 137, 215, 236, 17, 153, 215, 236, 17, 173, 215, 236, 17, - 181, 215, 236, 17, 176, 215, 236, 17, 184, 102, 248, 111, 4, 211, 32, - 102, 206, 117, 248, 110, 102, 54, 248, 111, 4, 211, 32, 102, 197, 221, - 248, 111, 4, 211, 32, 102, 248, 111, 4, 54, 211, 32, 102, 206, 117, 248, - 111, 4, 211, 32, 102, 206, 117, 248, 111, 4, 54, 211, 32, 102, 223, 65, - 248, 110, 102, 223, 65, 248, 111, 4, 54, 211, 32, 102, 200, 130, 248, - 110, 102, 200, 130, 248, 111, 4, 211, 32, 102, 200, 130, 248, 111, 4, 54, - 211, 32, 102, 152, 200, 130, 248, 111, 4, 54, 211, 32, 199, 200, 1, 65, - 199, 200, 1, 252, 154, 199, 200, 1, 70, 199, 200, 1, 223, 170, 199, 200, - 1, 69, 199, 200, 1, 196, 26, 199, 200, 1, 73, 199, 200, 1, 251, 184, 199, - 200, 1, 74, 199, 200, 1, 250, 113, 199, 200, 1, 157, 199, 200, 1, 221, - 190, 199, 200, 1, 231, 203, 199, 200, 1, 231, 54, 199, 200, 1, 214, 54, - 199, 200, 1, 247, 112, 199, 200, 1, 246, 209, 199, 200, 1, 223, 4, 199, - 200, 1, 222, 225, 199, 200, 1, 212, 88, 199, 200, 1, 197, 128, 199, 200, - 1, 197, 116, 199, 200, 1, 237, 146, 199, 200, 1, 237, 130, 199, 200, 1, - 213, 66, 199, 200, 1, 199, 247, 199, 200, 1, 199, 44, 199, 200, 1, 237, - 241, 199, 200, 1, 237, 23, 199, 200, 1, 180, 199, 200, 1, 168, 199, 200, - 1, 209, 219, 199, 200, 1, 249, 103, 199, 200, 1, 248, 153, 199, 200, 1, - 172, 199, 200, 1, 169, 199, 200, 1, 166, 199, 200, 1, 171, 199, 200, 1, - 195, 185, 199, 200, 1, 203, 160, 199, 200, 1, 189, 199, 200, 1, 144, 199, - 200, 1, 206, 104, 199, 200, 3, 251, 20, 199, 200, 3, 195, 32, 199, 200, - 18, 3, 252, 154, 199, 200, 18, 3, 70, 199, 200, 18, 3, 223, 170, 199, - 200, 18, 3, 69, 199, 200, 18, 3, 196, 26, 199, 200, 18, 3, 73, 199, 200, - 18, 3, 251, 184, 199, 200, 18, 3, 74, 199, 200, 18, 3, 250, 113, 199, - 200, 3, 195, 37, 199, 200, 3, 212, 128, 199, 200, 1, 250, 220, 221, 190, - 199, 200, 252, 16, 57, 199, 200, 17, 191, 77, 199, 200, 17, 108, 199, - 200, 17, 109, 199, 200, 17, 139, 199, 200, 17, 137, 199, 200, 17, 153, - 199, 200, 17, 173, 199, 200, 17, 181, 199, 200, 17, 176, 199, 200, 17, - 184, 251, 188, 1, 157, 251, 188, 1, 221, 190, 251, 188, 1, 214, 54, 251, - 188, 1, 180, 251, 188, 1, 199, 247, 251, 188, 1, 251, 106, 199, 247, 251, - 188, 1, 168, 251, 188, 1, 209, 219, 251, 188, 1, 249, 103, 251, 188, 1, - 172, 251, 188, 1, 223, 4, 251, 188, 1, 246, 209, 251, 188, 1, 199, 44, - 251, 188, 1, 166, 251, 188, 1, 171, 251, 188, 1, 189, 251, 188, 1, 212, - 88, 251, 188, 1, 144, 251, 188, 1, 65, 251, 188, 1, 237, 241, 251, 188, - 1, 237, 23, 251, 188, 1, 231, 203, 251, 188, 1, 251, 106, 231, 203, 251, - 188, 1, 231, 54, 251, 188, 1, 248, 153, 251, 188, 1, 222, 225, 251, 188, - 1, 251, 106, 249, 103, 251, 188, 119, 3, 216, 198, 171, 251, 188, 119, 3, - 216, 198, 166, 251, 188, 119, 3, 216, 198, 219, 109, 166, 251, 188, 18, - 3, 65, 251, 188, 18, 3, 252, 154, 251, 188, 18, 3, 70, 251, 188, 18, 3, - 223, 170, 251, 188, 18, 3, 69, 251, 188, 18, 3, 196, 26, 251, 188, 18, 3, - 73, 251, 188, 18, 3, 250, 90, 251, 188, 18, 3, 74, 251, 188, 18, 3, 251, - 184, 251, 188, 18, 3, 251, 98, 251, 188, 3, 221, 119, 251, 188, 17, 191, - 77, 251, 188, 17, 108, 251, 188, 17, 109, 251, 188, 17, 139, 251, 188, - 17, 137, 251, 188, 17, 153, 251, 188, 17, 173, 251, 188, 17, 181, 251, - 188, 17, 176, 251, 188, 17, 184, 251, 188, 31, 199, 90, 251, 188, 31, - 197, 28, 251, 188, 3, 2, 205, 48, 251, 188, 3, 205, 48, 251, 188, 3, 206, - 48, 251, 188, 16, 195, 66, 251, 188, 1, 247, 112, 251, 188, 1, 197, 128, - 251, 188, 1, 197, 116, 251, 188, 1, 237, 146, 251, 188, 1, 237, 130, 251, - 188, 1, 213, 66, 251, 188, 1, 219, 49, 236, 116, 1, 65, 236, 116, 1, 252, - 154, 236, 116, 1, 70, 236, 116, 1, 223, 170, 236, 116, 1, 69, 236, 116, - 1, 196, 26, 236, 116, 1, 73, 236, 116, 1, 251, 184, 236, 116, 1, 74, 236, - 116, 1, 250, 113, 236, 116, 1, 157, 236, 116, 1, 221, 190, 236, 116, 1, - 231, 203, 236, 116, 1, 231, 54, 236, 116, 1, 214, 54, 236, 116, 1, 247, - 112, 236, 116, 1, 246, 209, 236, 116, 1, 223, 4, 236, 116, 1, 222, 225, - 236, 116, 1, 212, 88, 236, 116, 1, 197, 128, 236, 116, 1, 197, 116, 236, - 116, 1, 237, 146, 236, 116, 1, 237, 130, 236, 116, 1, 213, 66, 236, 116, - 1, 199, 247, 236, 116, 1, 199, 44, 236, 116, 1, 237, 241, 236, 116, 1, - 237, 23, 236, 116, 1, 180, 236, 116, 1, 168, 236, 116, 1, 209, 219, 236, - 116, 1, 249, 103, 236, 116, 1, 248, 153, 236, 116, 1, 172, 236, 116, 1, - 169, 236, 116, 1, 166, 236, 116, 1, 171, 236, 116, 1, 195, 185, 236, 116, - 1, 203, 160, 236, 116, 1, 201, 170, 236, 116, 1, 189, 236, 116, 1, 144, - 236, 116, 1, 206, 104, 236, 116, 18, 3, 252, 154, 236, 116, 18, 3, 70, - 236, 116, 18, 3, 223, 170, 236, 116, 18, 3, 69, 236, 116, 18, 3, 196, 26, - 236, 116, 18, 3, 121, 148, 236, 116, 18, 3, 121, 206, 105, 236, 116, 18, - 3, 73, 236, 116, 18, 3, 251, 184, 236, 116, 18, 3, 74, 236, 116, 18, 3, - 250, 113, 236, 116, 3, 251, 20, 236, 116, 3, 195, 32, 236, 116, 3, 195, - 37, 236, 116, 3, 212, 128, 236, 116, 252, 16, 57, 193, 154, 242, 205, 6, - 1, 214, 53, 193, 154, 242, 205, 6, 1, 65, 193, 154, 242, 205, 6, 1, 193, - 84, 193, 154, 242, 205, 6, 1, 191, 225, 193, 154, 242, 205, 6, 1, 169, - 193, 154, 242, 205, 6, 1, 192, 12, 193, 154, 242, 205, 6, 1, 223, 170, - 193, 154, 242, 205, 6, 1, 196, 26, 193, 154, 242, 205, 6, 1, 73, 193, - 154, 242, 205, 6, 1, 74, 193, 154, 242, 205, 6, 1, 251, 71, 193, 154, - 242, 205, 6, 1, 231, 203, 193, 154, 242, 205, 6, 1, 221, 43, 193, 154, - 242, 205, 6, 1, 234, 24, 193, 154, 242, 205, 6, 1, 191, 204, 193, 154, - 242, 205, 6, 1, 196, 156, 193, 154, 242, 205, 6, 1, 234, 43, 193, 154, - 242, 205, 6, 1, 211, 142, 193, 154, 242, 205, 6, 1, 197, 123, 193, 154, - 242, 205, 6, 1, 212, 114, 193, 154, 242, 205, 6, 1, 237, 241, 193, 154, - 242, 205, 6, 1, 250, 132, 193, 154, 242, 205, 6, 1, 251, 98, 193, 154, - 242, 205, 6, 1, 247, 218, 193, 154, 242, 205, 6, 1, 208, 158, 193, 154, - 242, 205, 6, 1, 229, 83, 193, 154, 242, 205, 6, 1, 228, 227, 193, 154, - 242, 205, 6, 1, 228, 154, 193, 154, 242, 205, 6, 1, 229, 242, 193, 154, - 242, 205, 6, 1, 201, 121, 193, 154, 242, 205, 6, 1, 202, 188, 193, 154, - 242, 205, 6, 1, 195, 22, 193, 154, 242, 205, 2, 1, 214, 53, 193, 154, - 242, 205, 2, 1, 65, 193, 154, 242, 205, 2, 1, 193, 84, 193, 154, 242, - 205, 2, 1, 191, 225, 193, 154, 242, 205, 2, 1, 169, 193, 154, 242, 205, - 2, 1, 192, 12, 193, 154, 242, 205, 2, 1, 223, 170, 193, 154, 242, 205, 2, - 1, 196, 26, 193, 154, 242, 205, 2, 1, 73, 193, 154, 242, 205, 2, 1, 74, - 193, 154, 242, 205, 2, 1, 251, 71, 193, 154, 242, 205, 2, 1, 231, 203, - 193, 154, 242, 205, 2, 1, 221, 43, 193, 154, 242, 205, 2, 1, 234, 24, - 193, 154, 242, 205, 2, 1, 191, 204, 193, 154, 242, 205, 2, 1, 196, 156, - 193, 154, 242, 205, 2, 1, 234, 43, 193, 154, 242, 205, 2, 1, 211, 142, - 193, 154, 242, 205, 2, 1, 197, 123, 193, 154, 242, 205, 2, 1, 212, 114, - 193, 154, 242, 205, 2, 1, 237, 241, 193, 154, 242, 205, 2, 1, 250, 132, - 193, 154, 242, 205, 2, 1, 251, 98, 193, 154, 242, 205, 2, 1, 247, 218, - 193, 154, 242, 205, 2, 1, 208, 158, 193, 154, 242, 205, 2, 1, 229, 83, - 193, 154, 242, 205, 2, 1, 228, 227, 193, 154, 242, 205, 2, 1, 228, 154, - 193, 154, 242, 205, 2, 1, 229, 242, 193, 154, 242, 205, 2, 1, 201, 121, - 193, 154, 242, 205, 2, 1, 202, 188, 193, 154, 242, 205, 2, 1, 195, 22, - 193, 154, 242, 205, 17, 191, 77, 193, 154, 242, 205, 17, 108, 193, 154, - 242, 205, 17, 109, 193, 154, 242, 205, 17, 139, 193, 154, 242, 205, 17, - 137, 193, 154, 242, 205, 17, 153, 193, 154, 242, 205, 17, 173, 193, 154, - 242, 205, 17, 181, 193, 154, 242, 205, 17, 176, 193, 154, 242, 205, 17, - 184, 193, 154, 242, 205, 31, 199, 90, 193, 154, 242, 205, 31, 197, 28, - 193, 154, 242, 205, 31, 198, 244, 193, 154, 242, 205, 31, 232, 97, 193, - 154, 242, 205, 31, 232, 230, 193, 154, 242, 205, 31, 202, 115, 193, 154, - 242, 205, 31, 203, 236, 193, 154, 242, 205, 31, 234, 110, 193, 154, 242, - 205, 31, 213, 156, 193, 154, 242, 205, 211, 102, 236, 164, 251, 158, 1, - 65, 236, 164, 251, 158, 1, 252, 154, 236, 164, 251, 158, 1, 70, 236, 164, - 251, 158, 1, 223, 170, 236, 164, 251, 158, 1, 69, 236, 164, 251, 158, 1, - 196, 26, 236, 164, 251, 158, 1, 73, 236, 164, 251, 158, 1, 74, 236, 164, - 251, 158, 1, 157, 236, 164, 251, 158, 1, 221, 190, 236, 164, 251, 158, 1, - 231, 203, 236, 164, 251, 158, 1, 231, 54, 236, 164, 251, 158, 1, 214, 54, - 236, 164, 251, 158, 1, 247, 112, 236, 164, 251, 158, 1, 246, 209, 236, - 164, 251, 158, 1, 223, 4, 236, 164, 251, 158, 1, 212, 88, 236, 164, 251, - 158, 1, 197, 128, 236, 164, 251, 158, 1, 237, 146, 236, 164, 251, 158, 1, - 237, 130, 236, 164, 251, 158, 1, 213, 66, 236, 164, 251, 158, 1, 199, - 247, 236, 164, 251, 158, 1, 199, 44, 236, 164, 251, 158, 1, 237, 241, - 236, 164, 251, 158, 1, 237, 23, 236, 164, 251, 158, 1, 180, 236, 164, - 251, 158, 1, 168, 236, 164, 251, 158, 1, 209, 219, 236, 164, 251, 158, 1, - 249, 103, 236, 164, 251, 158, 1, 248, 153, 236, 164, 251, 158, 1, 172, - 236, 164, 251, 158, 1, 169, 236, 164, 251, 158, 1, 191, 175, 236, 164, - 251, 158, 1, 166, 236, 164, 251, 158, 1, 171, 236, 164, 251, 158, 1, 195, - 185, 236, 164, 251, 158, 1, 203, 160, 236, 164, 251, 158, 1, 201, 170, - 236, 164, 251, 158, 1, 189, 236, 164, 251, 158, 1, 144, 236, 164, 251, - 158, 1, 219, 49, 236, 164, 251, 158, 1, 191, 123, 236, 164, 251, 158, 18, - 3, 252, 154, 236, 164, 251, 158, 18, 3, 70, 236, 164, 251, 158, 18, 3, - 223, 170, 236, 164, 251, 158, 18, 3, 69, 236, 164, 251, 158, 18, 3, 196, - 26, 236, 164, 251, 158, 18, 3, 73, 236, 164, 251, 158, 18, 3, 251, 184, - 236, 164, 251, 158, 18, 3, 74, 236, 164, 251, 158, 3, 251, 20, 236, 164, - 251, 158, 3, 247, 71, 236, 164, 251, 158, 3, 230, 39, 236, 164, 251, 158, - 195, 37, 236, 164, 251, 158, 208, 220, 214, 200, 57, 236, 164, 251, 158, - 216, 198, 169, 236, 164, 251, 158, 89, 166, 236, 164, 251, 158, 216, 198, - 166, 236, 164, 251, 158, 3, 212, 128, 236, 164, 251, 158, 54, 237, 193, - 236, 164, 251, 158, 231, 167, 232, 218, 236, 164, 251, 158, 234, 53, 80, - 199, 49, 77, 236, 164, 251, 158, 17, 191, 77, 236, 164, 251, 158, 17, - 108, 236, 164, 251, 158, 17, 109, 236, 164, 251, 158, 17, 139, 236, 164, - 251, 158, 17, 137, 236, 164, 251, 158, 17, 153, 236, 164, 251, 158, 17, - 173, 236, 164, 251, 158, 17, 181, 236, 164, 251, 158, 17, 176, 236, 164, - 251, 158, 17, 184, 214, 209, 1, 65, 214, 209, 1, 252, 154, 214, 209, 1, - 70, 214, 209, 1, 223, 170, 214, 209, 1, 69, 214, 209, 1, 196, 26, 214, - 209, 1, 121, 148, 214, 209, 1, 121, 206, 105, 214, 209, 1, 73, 214, 209, - 1, 251, 184, 214, 209, 1, 74, 214, 209, 1, 250, 113, 214, 209, 1, 157, - 214, 209, 1, 221, 190, 214, 209, 1, 231, 203, 214, 209, 1, 231, 54, 214, - 209, 1, 214, 54, 214, 209, 1, 247, 112, 214, 209, 1, 246, 209, 214, 209, - 1, 223, 4, 214, 209, 1, 222, 225, 214, 209, 1, 212, 88, 214, 209, 1, 197, - 128, 214, 209, 1, 197, 116, 214, 209, 1, 237, 146, 214, 209, 1, 237, 130, - 214, 209, 1, 213, 66, 214, 209, 1, 199, 247, 214, 209, 1, 199, 44, 214, - 209, 1, 237, 241, 214, 209, 1, 237, 23, 214, 209, 1, 180, 214, 209, 1, - 168, 214, 209, 1, 209, 219, 214, 209, 1, 249, 103, 214, 209, 1, 248, 153, - 214, 209, 1, 172, 214, 209, 1, 169, 214, 209, 1, 166, 214, 209, 1, 171, - 214, 209, 1, 195, 185, 214, 209, 1, 203, 160, 214, 209, 1, 201, 170, 214, - 209, 1, 189, 214, 209, 1, 144, 214, 209, 1, 219, 49, 214, 209, 1, 206, - 104, 214, 209, 18, 3, 252, 154, 214, 209, 18, 3, 70, 214, 209, 18, 3, - 223, 170, 214, 209, 18, 3, 69, 214, 209, 18, 3, 196, 26, 214, 209, 18, 3, - 121, 148, 214, 209, 18, 3, 121, 206, 105, 214, 209, 18, 3, 73, 214, 209, - 18, 3, 251, 184, 214, 209, 18, 3, 74, 214, 209, 18, 3, 250, 113, 214, - 209, 3, 251, 20, 214, 209, 3, 195, 32, 214, 209, 3, 195, 37, 214, 209, 3, - 250, 95, 214, 209, 3, 202, 205, 214, 209, 229, 195, 214, 209, 18, 3, 208, - 200, 73, 191, 106, 51, 1, 65, 191, 106, 51, 18, 3, 70, 191, 106, 51, 18, - 3, 196, 148, 191, 106, 51, 18, 3, 69, 191, 106, 51, 18, 3, 73, 191, 106, - 51, 18, 3, 211, 139, 191, 106, 51, 18, 3, 74, 191, 106, 51, 18, 3, 251, - 184, 191, 106, 51, 18, 3, 250, 113, 191, 106, 51, 18, 3, 207, 13, 70, - 191, 106, 51, 18, 219, 174, 77, 191, 106, 51, 1, 157, 191, 106, 51, 1, - 221, 190, 191, 106, 51, 1, 231, 203, 191, 106, 51, 1, 231, 54, 191, 106, - 51, 1, 214, 54, 191, 106, 51, 1, 247, 112, 191, 106, 51, 1, 246, 209, - 191, 106, 51, 1, 223, 4, 191, 106, 51, 1, 212, 88, 191, 106, 51, 1, 197, - 128, 191, 106, 51, 1, 197, 116, 191, 106, 51, 1, 237, 146, 191, 106, 51, - 1, 237, 130, 191, 106, 51, 1, 213, 66, 191, 106, 51, 1, 199, 247, 191, - 106, 51, 1, 199, 44, 191, 106, 51, 1, 237, 241, 191, 106, 51, 1, 237, 23, - 191, 106, 51, 1, 180, 191, 106, 51, 1, 168, 191, 106, 51, 1, 209, 219, - 191, 106, 51, 1, 249, 103, 191, 106, 51, 1, 248, 153, 191, 106, 51, 1, - 172, 191, 106, 51, 1, 197, 164, 191, 106, 51, 1, 197, 153, 191, 106, 51, - 1, 234, 247, 191, 106, 51, 1, 234, 241, 191, 106, 51, 1, 191, 71, 191, - 106, 51, 1, 191, 123, 191, 106, 51, 1, 255, 162, 191, 106, 51, 1, 169, - 191, 106, 51, 1, 166, 191, 106, 51, 1, 171, 191, 106, 51, 1, 195, 185, - 191, 106, 51, 1, 203, 160, 191, 106, 51, 1, 201, 170, 191, 106, 51, 1, - 189, 191, 106, 51, 1, 144, 191, 106, 51, 1, 220, 222, 191, 106, 51, 52, - 119, 77, 191, 106, 51, 3, 195, 37, 191, 106, 51, 3, 247, 71, 191, 106, - 51, 3, 247, 72, 4, 211, 32, 191, 106, 51, 3, 247, 74, 4, 211, 32, 191, - 106, 51, 3, 251, 20, 191, 106, 51, 3, 195, 32, 191, 106, 51, 242, 153, 1, - 166, 191, 106, 51, 242, 154, 1, 169, 191, 106, 51, 242, 154, 1, 166, 191, - 106, 51, 242, 154, 1, 171, 191, 106, 51, 242, 154, 1, 195, 185, 191, 106, - 51, 89, 229, 204, 77, 191, 106, 51, 242, 167, 229, 204, 77, 191, 106, 51, - 87, 197, 148, 191, 106, 51, 87, 203, 152, 191, 106, 51, 87, 54, 203, 152, - 191, 106, 51, 87, 177, 197, 148, 191, 106, 51, 89, 235, 86, 229, 204, 77, - 191, 106, 51, 242, 167, 235, 86, 229, 204, 77, 191, 106, 51, 200, 233, - 201, 246, 1, 65, 201, 246, 18, 3, 70, 201, 246, 18, 3, 196, 148, 201, - 246, 18, 3, 69, 201, 246, 18, 3, 73, 201, 246, 18, 3, 74, 201, 246, 18, - 3, 211, 139, 201, 246, 18, 3, 251, 184, 201, 246, 18, 3, 250, 113, 201, - 246, 18, 3, 121, 148, 201, 246, 18, 3, 121, 170, 201, 246, 18, 219, 174, - 77, 201, 246, 1, 157, 201, 246, 1, 221, 190, 201, 246, 1, 231, 203, 201, - 246, 1, 231, 54, 201, 246, 1, 214, 54, 201, 246, 1, 247, 112, 201, 246, - 1, 246, 209, 201, 246, 1, 223, 4, 201, 246, 1, 222, 225, 201, 246, 1, - 212, 88, 201, 246, 1, 197, 128, 201, 246, 1, 197, 116, 201, 246, 1, 237, - 146, 201, 246, 1, 237, 130, 201, 246, 1, 213, 66, 201, 246, 1, 199, 247, - 201, 246, 1, 199, 44, 201, 246, 1, 237, 241, 201, 246, 1, 237, 23, 201, - 246, 1, 180, 201, 246, 1, 168, 201, 246, 1, 209, 219, 201, 246, 1, 249, - 103, 201, 246, 1, 248, 153, 201, 246, 1, 172, 201, 246, 1, 197, 164, 201, - 246, 1, 197, 153, 201, 246, 1, 234, 247, 201, 246, 1, 191, 71, 201, 246, - 1, 191, 123, 201, 246, 1, 255, 162, 201, 246, 1, 169, 201, 246, 1, 166, - 201, 246, 1, 171, 201, 246, 1, 195, 185, 201, 246, 1, 203, 160, 201, 246, - 1, 201, 170, 201, 246, 1, 189, 201, 246, 1, 144, 201, 246, 1, 220, 222, - 201, 246, 3, 222, 210, 201, 246, 3, 196, 71, 201, 246, 242, 153, 1, 166, - 201, 246, 242, 153, 1, 171, 201, 246, 242, 153, 1, 203, 160, 201, 246, - 242, 153, 1, 189, 201, 246, 52, 119, 3, 232, 14, 201, 246, 52, 119, 3, - 222, 125, 201, 246, 52, 119, 3, 214, 56, 201, 246, 52, 119, 3, 238, 80, - 201, 246, 52, 119, 3, 215, 47, 201, 246, 52, 119, 3, 250, 70, 201, 246, - 52, 119, 3, 218, 147, 201, 246, 52, 119, 3, 148, 201, 246, 52, 119, 3, - 170, 201, 246, 52, 119, 3, 203, 162, 201, 246, 52, 119, 3, 206, 3, 201, - 246, 52, 119, 3, 255, 162, 201, 246, 3, 251, 20, 201, 246, 3, 195, 32, - 201, 246, 231, 116, 77, 201, 246, 200, 233, 201, 246, 87, 197, 148, 201, - 246, 87, 203, 152, 201, 246, 87, 54, 203, 152, 201, 246, 87, 209, 71, - 201, 246, 229, 204, 87, 4, 215, 189, 24, 200, 194, 24, 197, 221, 232, - 170, 201, 246, 229, 204, 87, 4, 215, 189, 24, 200, 194, 24, 232, 170, - 201, 246, 229, 204, 87, 4, 215, 189, 24, 200, 193, 201, 246, 199, 76, - 217, 36, 201, 246, 199, 76, 217, 35, 21, 22, 214, 193, 229, 126, 21, 22, - 214, 193, 229, 98, 21, 22, 214, 193, 228, 247, 21, 22, 214, 193, 228, - 220, 21, 22, 214, 193, 144, 21, 22, 214, 193, 230, 58, 21, 22, 214, 193, - 203, 10, 21, 22, 214, 193, 203, 9, 21, 22, 214, 193, 203, 6, 21, 22, 214, - 193, 203, 5, 21, 22, 214, 193, 203, 12, 21, 22, 214, 193, 203, 11, 21, - 22, 201, 232, 21, 22, 201, 219, 21, 22, 201, 202, 21, 22, 201, 244, 210, - 71, 242, 223, 229, 226, 1, 168, 210, 71, 242, 223, 229, 226, 1, 157, 210, - 71, 242, 223, 229, 226, 1, 171, 210, 71, 242, 223, 229, 226, 1, 172, 210, - 71, 242, 223, 229, 226, 1, 237, 241, 210, 71, 242, 223, 229, 226, 1, 191, - 123, 210, 71, 242, 223, 229, 226, 1, 195, 185, 210, 71, 242, 223, 229, - 226, 1, 214, 54, 210, 71, 242, 223, 229, 226, 1, 144, 210, 71, 242, 223, - 229, 226, 1, 231, 203, 210, 71, 242, 223, 229, 226, 1, 221, 190, 210, 71, - 242, 223, 229, 226, 1, 189, 210, 71, 242, 223, 229, 226, 1, 249, 103, - 210, 71, 242, 223, 229, 226, 1, 247, 112, 210, 71, 242, 223, 229, 226, 1, - 199, 247, 210, 71, 242, 223, 229, 226, 1, 199, 44, 210, 71, 242, 223, - 229, 226, 1, 180, 210, 71, 242, 223, 229, 226, 1, 209, 219, 210, 71, 242, - 223, 229, 226, 1, 166, 210, 71, 242, 223, 229, 226, 1, 233, 68, 210, 71, - 242, 223, 229, 226, 1, 246, 209, 210, 71, 242, 223, 229, 226, 1, 65, 210, - 71, 242, 223, 229, 226, 1, 73, 210, 71, 242, 223, 229, 226, 1, 70, 210, - 71, 242, 223, 229, 226, 1, 74, 210, 71, 242, 223, 229, 226, 1, 69, 210, - 71, 242, 223, 229, 226, 1, 196, 164, 210, 71, 242, 223, 229, 226, 1, 228, - 5, 210, 71, 242, 223, 229, 226, 1, 52, 210, 226, 210, 71, 242, 223, 229, - 226, 1, 52, 222, 125, 210, 71, 242, 223, 229, 226, 1, 52, 200, 39, 210, - 71, 242, 223, 229, 226, 1, 52, 218, 147, 210, 71, 242, 223, 229, 226, 1, - 52, 215, 47, 210, 71, 242, 223, 229, 226, 1, 52, 170, 210, 71, 242, 223, - 229, 226, 1, 52, 193, 221, 210, 71, 242, 223, 229, 226, 1, 52, 214, 56, - 210, 71, 242, 223, 229, 226, 1, 52, 192, 159, 210, 71, 242, 223, 229, - 226, 206, 175, 163, 218, 251, 210, 71, 242, 223, 229, 226, 206, 175, 198, - 74, 210, 71, 242, 223, 229, 226, 205, 133, 230, 231, 201, 58, 210, 71, - 242, 223, 229, 226, 206, 175, 163, 177, 232, 214, 210, 71, 242, 223, 229, - 226, 206, 175, 163, 232, 214, 210, 71, 242, 223, 229, 226, 205, 133, 230, - 231, 201, 59, 232, 214, 210, 71, 242, 223, 229, 226, 205, 133, 163, 218, - 251, 210, 71, 242, 223, 229, 226, 205, 133, 198, 74, 210, 71, 242, 223, - 229, 226, 205, 133, 163, 177, 232, 214, 210, 71, 242, 223, 229, 226, 205, - 133, 163, 232, 214, 210, 71, 242, 223, 229, 226, 216, 67, 198, 74, 210, - 71, 242, 223, 229, 226, 230, 231, 201, 59, 195, 164, 210, 71, 242, 223, - 229, 226, 216, 67, 163, 177, 232, 214, 210, 71, 242, 223, 229, 226, 216, - 67, 163, 232, 214, 210, 71, 242, 223, 229, 226, 218, 217, 163, 218, 251, - 210, 71, 242, 223, 229, 226, 218, 217, 198, 74, 210, 71, 242, 223, 229, - 226, 230, 231, 201, 58, 210, 71, 242, 223, 229, 226, 218, 217, 163, 177, - 232, 214, 210, 71, 242, 223, 229, 226, 218, 217, 163, 232, 214, 210, 71, - 242, 223, 229, 226, 230, 231, 201, 59, 232, 214, 248, 151, 1, 65, 248, - 151, 1, 252, 154, 248, 151, 1, 70, 248, 151, 1, 223, 170, 248, 151, 1, - 69, 248, 151, 1, 196, 26, 248, 151, 1, 121, 148, 248, 151, 1, 121, 206, - 105, 248, 151, 1, 121, 170, 248, 151, 1, 73, 248, 151, 1, 251, 184, 248, - 151, 1, 74, 248, 151, 1, 250, 113, 248, 151, 1, 157, 248, 151, 1, 221, - 190, 248, 151, 1, 231, 203, 248, 151, 1, 231, 54, 248, 151, 1, 214, 54, - 248, 151, 1, 247, 112, 248, 151, 1, 246, 209, 248, 151, 1, 223, 4, 248, - 151, 1, 222, 225, 248, 151, 1, 212, 88, 248, 151, 1, 197, 128, 248, 151, - 1, 197, 116, 248, 151, 1, 237, 146, 248, 151, 1, 237, 130, 248, 151, 1, - 213, 66, 248, 151, 1, 199, 247, 248, 151, 1, 199, 44, 248, 151, 1, 237, - 241, 248, 151, 1, 237, 23, 248, 151, 1, 180, 248, 151, 1, 168, 248, 151, - 1, 209, 219, 248, 151, 1, 249, 103, 248, 151, 1, 248, 153, 248, 151, 1, - 172, 248, 151, 1, 169, 248, 151, 1, 166, 248, 151, 1, 171, 248, 151, 1, - 195, 185, 248, 151, 1, 203, 160, 248, 151, 1, 201, 170, 248, 151, 1, 189, - 248, 151, 1, 144, 248, 151, 18, 3, 252, 154, 248, 151, 18, 3, 70, 248, - 151, 18, 3, 223, 170, 248, 151, 18, 3, 69, 248, 151, 18, 3, 196, 26, 248, - 151, 18, 3, 121, 148, 248, 151, 18, 3, 121, 206, 105, 248, 151, 18, 3, - 121, 170, 248, 151, 18, 3, 73, 248, 151, 18, 3, 251, 184, 248, 151, 18, - 3, 74, 248, 151, 18, 3, 250, 113, 248, 151, 3, 247, 71, 248, 151, 3, 251, - 20, 248, 151, 3, 195, 32, 248, 151, 3, 195, 37, 248, 151, 3, 250, 95, - 248, 151, 237, 193, 248, 151, 54, 237, 193, 248, 151, 193, 23, 204, 5, - 248, 151, 231, 167, 232, 217, 248, 151, 231, 167, 232, 216, 248, 151, 17, - 191, 77, 248, 151, 17, 108, 248, 151, 17, 109, 248, 151, 17, 139, 248, - 151, 17, 137, 248, 151, 17, 153, 248, 151, 17, 173, 248, 151, 17, 181, - 248, 151, 17, 176, 248, 151, 17, 184, 248, 151, 31, 108, 248, 151, 31, - 109, 248, 151, 31, 139, 248, 151, 31, 137, 248, 151, 31, 153, 248, 151, - 31, 173, 248, 151, 31, 181, 248, 151, 31, 176, 248, 151, 31, 184, 248, - 151, 31, 199, 90, 248, 151, 31, 197, 28, 248, 151, 31, 198, 244, 248, - 151, 31, 232, 97, 248, 151, 31, 232, 230, 248, 151, 31, 202, 115, 248, - 151, 31, 203, 236, 248, 151, 31, 234, 110, 248, 151, 31, 213, 156, 248, - 151, 228, 108, 196, 87, 77, 217, 38, 229, 204, 77, 217, 38, 87, 203, 152, - 217, 38, 1, 157, 217, 38, 1, 221, 190, 217, 38, 1, 231, 203, 217, 38, 1, - 214, 54, 217, 38, 1, 247, 112, 217, 38, 1, 246, 209, 217, 38, 1, 223, 4, - 217, 38, 1, 212, 88, 217, 38, 1, 199, 247, 217, 38, 1, 199, 44, 217, 38, - 1, 237, 241, 217, 38, 1, 180, 217, 38, 1, 168, 217, 38, 1, 209, 219, 217, - 38, 1, 249, 103, 217, 38, 1, 172, 217, 38, 1, 197, 164, 217, 38, 1, 197, - 153, 217, 38, 1, 234, 247, 217, 38, 1, 193, 187, 217, 38, 1, 191, 71, - 217, 38, 1, 191, 123, 217, 38, 1, 255, 162, 217, 38, 1, 169, 217, 38, 1, - 166, 217, 38, 1, 171, 217, 38, 1, 203, 160, 217, 38, 1, 189, 217, 38, 1, - 144, 217, 38, 1, 65, 217, 38, 200, 234, 1, 157, 217, 38, 200, 234, 1, - 221, 190, 217, 38, 200, 234, 1, 231, 203, 217, 38, 200, 234, 1, 214, 54, - 217, 38, 200, 234, 1, 247, 112, 217, 38, 200, 234, 1, 246, 209, 217, 38, - 200, 234, 1, 223, 4, 217, 38, 200, 234, 1, 212, 88, 217, 38, 200, 234, 1, - 199, 247, 217, 38, 200, 234, 1, 199, 44, 217, 38, 200, 234, 1, 237, 241, - 217, 38, 200, 234, 1, 180, 217, 38, 200, 234, 1, 168, 217, 38, 200, 234, - 1, 209, 219, 217, 38, 200, 234, 1, 249, 103, 217, 38, 200, 234, 1, 172, - 217, 38, 200, 234, 1, 197, 164, 217, 38, 200, 234, 1, 197, 153, 217, 38, - 200, 234, 1, 234, 247, 217, 38, 200, 234, 1, 193, 187, 217, 38, 200, 234, - 1, 191, 71, 217, 38, 200, 234, 1, 191, 123, 217, 38, 200, 234, 1, 169, - 217, 38, 200, 234, 1, 166, 217, 38, 200, 234, 1, 171, 217, 38, 200, 234, - 1, 203, 160, 217, 38, 200, 234, 1, 189, 217, 38, 200, 234, 1, 144, 217, - 38, 200, 234, 1, 65, 217, 38, 18, 3, 252, 154, 217, 38, 18, 3, 70, 217, - 38, 18, 3, 69, 217, 38, 18, 3, 73, 217, 38, 18, 3, 74, 217, 38, 3, 251, - 20, 217, 38, 3, 247, 71, 217, 22, 129, 1, 65, 217, 22, 129, 1, 252, 154, - 217, 22, 129, 1, 70, 217, 22, 129, 1, 223, 170, 217, 22, 129, 1, 69, 217, - 22, 129, 1, 196, 26, 217, 22, 129, 1, 73, 217, 22, 129, 1, 251, 184, 217, - 22, 129, 1, 74, 217, 22, 129, 1, 250, 113, 217, 22, 129, 1, 157, 217, 22, - 129, 1, 221, 190, 217, 22, 129, 1, 231, 203, 217, 22, 129, 1, 231, 54, - 217, 22, 129, 1, 214, 54, 217, 22, 129, 1, 247, 112, 217, 22, 129, 1, - 246, 209, 217, 22, 129, 1, 223, 4, 217, 22, 129, 1, 222, 225, 217, 22, - 129, 1, 212, 88, 217, 22, 129, 1, 197, 128, 217, 22, 129, 1, 197, 116, - 217, 22, 129, 1, 237, 146, 217, 22, 129, 1, 237, 130, 217, 22, 129, 1, - 213, 66, 217, 22, 129, 1, 199, 247, 217, 22, 129, 1, 199, 44, 217, 22, - 129, 1, 237, 241, 217, 22, 129, 1, 237, 23, 217, 22, 129, 1, 180, 217, - 22, 129, 1, 168, 217, 22, 129, 1, 209, 219, 217, 22, 129, 1, 249, 103, - 217, 22, 129, 1, 248, 153, 217, 22, 129, 1, 172, 217, 22, 129, 1, 169, - 217, 22, 129, 1, 166, 217, 22, 129, 1, 171, 217, 22, 129, 1, 195, 185, - 217, 22, 129, 1, 203, 160, 217, 22, 129, 1, 201, 170, 217, 22, 129, 1, - 189, 217, 22, 129, 1, 144, 217, 22, 129, 1, 219, 49, 217, 22, 129, 1, - 220, 222, 217, 22, 129, 1, 222, 175, 217, 22, 129, 1, 198, 22, 217, 22, - 129, 18, 3, 252, 154, 217, 22, 129, 18, 3, 70, 217, 22, 129, 18, 3, 223, - 170, 217, 22, 129, 18, 3, 69, 217, 22, 129, 18, 3, 196, 26, 217, 22, 129, - 18, 3, 121, 148, 217, 22, 129, 18, 3, 73, 217, 22, 129, 18, 3, 251, 184, - 217, 22, 129, 18, 3, 74, 217, 22, 129, 18, 3, 250, 113, 217, 22, 129, 3, - 251, 20, 217, 22, 129, 3, 195, 32, 217, 22, 129, 3, 212, 128, 217, 22, - 129, 3, 247, 73, 217, 22, 129, 3, 230, 39, 217, 22, 129, 195, 37, 217, - 22, 129, 207, 39, 217, 22, 129, 207, 176, 217, 22, 129, 17, 191, 77, 217, - 22, 129, 17, 108, 217, 22, 129, 17, 109, 217, 22, 129, 17, 139, 217, 22, - 129, 17, 137, 217, 22, 129, 17, 153, 217, 22, 129, 17, 173, 217, 22, 129, - 17, 181, 217, 22, 129, 17, 176, 217, 22, 129, 17, 184, 230, 124, 129, 1, - 65, 230, 124, 129, 1, 252, 154, 230, 124, 129, 1, 70, 230, 124, 129, 1, - 223, 170, 230, 124, 129, 1, 69, 230, 124, 129, 1, 196, 26, 230, 124, 129, - 1, 234, 145, 230, 124, 129, 1, 251, 184, 230, 124, 129, 1, 211, 76, 230, - 124, 129, 1, 250, 113, 230, 124, 129, 1, 169, 230, 124, 129, 1, 195, 185, - 230, 124, 129, 1, 249, 103, 230, 124, 129, 1, 248, 153, 230, 124, 129, 1, - 172, 230, 124, 129, 1, 157, 230, 124, 129, 1, 221, 190, 230, 124, 129, 1, - 199, 247, 230, 124, 129, 1, 199, 44, 230, 124, 129, 1, 171, 230, 124, - 129, 1, 231, 203, 230, 124, 129, 1, 231, 54, 230, 124, 129, 1, 237, 241, - 230, 124, 129, 1, 237, 23, 230, 124, 129, 1, 180, 230, 124, 129, 1, 247, - 112, 230, 124, 129, 1, 246, 209, 230, 124, 129, 1, 197, 128, 230, 124, - 129, 1, 197, 116, 230, 124, 129, 1, 219, 49, 230, 124, 129, 1, 223, 4, - 230, 124, 129, 1, 222, 225, 230, 124, 129, 1, 237, 146, 230, 124, 129, 1, - 237, 130, 230, 124, 129, 1, 214, 54, 230, 124, 129, 1, 168, 230, 124, - 129, 1, 209, 219, 230, 124, 129, 1, 144, 230, 124, 129, 1, 166, 230, 124, - 129, 1, 189, 230, 124, 129, 18, 3, 252, 154, 230, 124, 129, 18, 3, 70, - 230, 124, 129, 18, 3, 223, 170, 230, 124, 129, 18, 3, 69, 230, 124, 129, - 18, 3, 196, 26, 230, 124, 129, 18, 3, 234, 145, 230, 124, 129, 18, 3, - 251, 184, 230, 124, 129, 18, 3, 211, 76, 230, 124, 129, 18, 3, 250, 113, - 230, 124, 129, 3, 251, 20, 230, 124, 129, 3, 195, 32, 230, 124, 129, 195, - 37, 230, 124, 129, 211, 102, 230, 124, 129, 17, 191, 77, 230, 124, 129, - 17, 108, 230, 124, 129, 17, 109, 230, 124, 129, 17, 139, 230, 124, 129, - 17, 137, 230, 124, 129, 17, 153, 230, 124, 129, 17, 173, 230, 124, 129, - 17, 181, 230, 124, 129, 17, 176, 230, 124, 129, 17, 184, 217, 81, 1, 157, - 217, 81, 1, 231, 203, 217, 81, 1, 214, 54, 217, 81, 1, 168, 217, 81, 1, - 249, 103, 217, 81, 1, 172, 217, 81, 1, 199, 247, 217, 81, 1, 237, 241, - 217, 81, 1, 180, 217, 81, 1, 247, 112, 217, 81, 1, 223, 4, 217, 81, 1, - 212, 88, 217, 81, 1, 169, 217, 81, 1, 166, 217, 81, 1, 171, 217, 81, 1, - 195, 185, 217, 81, 1, 189, 217, 81, 1, 65, 217, 81, 251, 67, 217, 81, 18, - 3, 70, 217, 81, 18, 3, 69, 217, 81, 18, 3, 73, 217, 81, 18, 3, 74, 217, - 81, 210, 84, 217, 81, 234, 53, 80, 205, 48, 219, 64, 1, 192, 35, 44, 232, - 80, 91, 198, 217, 44, 232, 80, 91, 211, 89, 44, 232, 80, 91, 234, 113, - 44, 232, 80, 91, 202, 113, 44, 232, 80, 91, 232, 100, 44, 232, 80, 91, - 198, 240, 44, 232, 80, 115, 234, 112, 44, 232, 80, 115, 202, 112, 44, - 232, 80, 91, 197, 31, 44, 232, 80, 91, 202, 122, 44, 232, 80, 91, 202, - 121, 44, 232, 80, 91, 199, 81, 44, 232, 80, 91, 234, 116, 44, 232, 80, - 115, 197, 30, 44, 232, 80, 115, 202, 120, 44, 232, 80, 91, 232, 233, 44, - 232, 80, 91, 208, 17, 44, 232, 80, 91, 230, 36, 44, 232, 80, 91, 230, 35, - 44, 232, 80, 115, 208, 15, 44, 232, 80, 235, 77, 233, 52, 221, 120, 44, - 3, 214, 90, 44, 3, 246, 214, 44, 3, 252, 105, 44, 3, 196, 11, 44, 3, 215, - 76, 44, 3, 220, 170, 44, 3, 210, 75, 44, 3, 215, 120, 44, 3, 222, 97, 44, - 3, 210, 154, 44, 3, 209, 32, 44, 3, 195, 170, 44, 3, 210, 205, 44, 3, - 220, 159, 44, 3, 195, 140, 44, 193, 99, 238, 140, 57, 44, 235, 48, 238, - 140, 57, 44, 219, 255, 57, 44, 205, 154, 210, 157, 57, 44, 198, 17, 238, - 183, 57, 44, 198, 17, 31, 57, 44, 238, 122, 57, 44, 24, 211, 143, 57, 44, - 201, 222, 57, 44, 198, 34, 57, 44, 223, 135, 209, 15, 57, 44, 201, 91, - 232, 60, 57, 44, 3, 215, 80, 44, 3, 195, 178, 44, 208, 145, 234, 53, 80, - 199, 48, 10, 3, 65, 10, 3, 41, 25, 65, 10, 3, 41, 25, 249, 85, 10, 3, 41, - 25, 231, 172, 199, 79, 10, 3, 41, 25, 144, 10, 3, 41, 25, 223, 172, 10, - 3, 41, 25, 220, 79, 230, 122, 10, 3, 41, 25, 215, 87, 10, 3, 41, 25, 205, - 180, 10, 3, 254, 163, 10, 3, 252, 103, 10, 3, 252, 104, 25, 250, 157, 10, - 3, 252, 104, 25, 235, 30, 230, 122, 10, 3, 252, 104, 25, 231, 185, 10, 3, - 252, 104, 25, 231, 172, 199, 79, 10, 3, 252, 104, 25, 144, 10, 3, 252, - 104, 25, 223, 173, 230, 122, 10, 3, 252, 104, 25, 223, 144, 10, 3, 252, - 104, 25, 220, 80, 10, 3, 252, 104, 25, 203, 92, 10, 3, 252, 104, 25, 126, - 107, 126, 107, 69, 10, 3, 252, 104, 230, 122, 10, 3, 252, 20, 10, 3, 252, - 21, 25, 249, 64, 10, 3, 252, 21, 25, 231, 172, 199, 79, 10, 3, 252, 21, - 25, 216, 214, 107, 234, 61, 10, 3, 252, 21, 25, 203, 158, 10, 3, 252, 21, - 25, 199, 204, 10, 3, 251, 246, 10, 3, 251, 165, 10, 3, 251, 166, 25, 233, - 242, 10, 3, 251, 166, 25, 203, 54, 107, 230, 243, 10, 3, 251, 156, 10, 3, - 251, 157, 25, 251, 156, 10, 3, 251, 157, 25, 236, 208, 10, 3, 251, 157, - 25, 230, 243, 10, 3, 251, 157, 25, 144, 10, 3, 251, 157, 25, 222, 84, 10, - 3, 251, 157, 25, 221, 142, 10, 3, 251, 157, 25, 203, 108, 10, 3, 251, - 157, 25, 196, 34, 10, 3, 251, 152, 10, 3, 251, 139, 10, 3, 251, 94, 10, - 3, 251, 95, 25, 203, 108, 10, 3, 251, 81, 10, 3, 251, 82, 138, 251, 81, - 10, 3, 251, 82, 115, 198, 139, 10, 3, 251, 82, 107, 214, 227, 211, 52, - 251, 82, 107, 214, 226, 10, 3, 251, 82, 107, 214, 227, 201, 184, 10, 3, - 251, 40, 10, 3, 251, 10, 10, 3, 250, 232, 10, 3, 250, 233, 25, 220, 173, - 10, 3, 250, 204, 10, 3, 250, 165, 10, 3, 250, 159, 10, 3, 250, 160, 191, - 26, 199, 79, 10, 3, 250, 160, 222, 89, 199, 79, 10, 3, 250, 160, 138, - 250, 160, 197, 79, 138, 197, 79, 197, 79, 138, 197, 79, 210, 127, 10, 3, - 250, 160, 138, 250, 160, 138, 250, 159, 10, 3, 250, 160, 138, 250, 160, - 138, 250, 160, 238, 163, 250, 160, 138, 250, 160, 138, 250, 159, 10, 3, - 250, 157, 10, 3, 250, 153, 10, 3, 249, 103, 10, 3, 249, 85, 10, 3, 249, - 79, 10, 3, 249, 71, 10, 3, 249, 65, 10, 3, 249, 66, 138, 249, 65, 10, 3, - 249, 64, 10, 3, 164, 10, 3, 249, 37, 10, 3, 248, 140, 10, 3, 248, 141, - 25, 65, 10, 3, 248, 141, 25, 231, 163, 10, 3, 248, 141, 25, 223, 173, - 230, 122, 10, 3, 247, 218, 10, 3, 247, 219, 138, 247, 219, 252, 103, 10, - 3, 247, 219, 138, 247, 219, 196, 109, 10, 3, 247, 219, 238, 163, 247, - 218, 10, 3, 247, 194, 10, 3, 247, 195, 138, 247, 194, 10, 3, 247, 182, - 10, 3, 247, 181, 10, 3, 237, 241, 10, 3, 237, 231, 10, 3, 237, 232, 221, - 101, 25, 41, 107, 217, 20, 10, 3, 237, 232, 221, 101, 25, 251, 94, 10, 3, - 237, 232, 221, 101, 25, 249, 64, 10, 3, 237, 232, 221, 101, 25, 248, 140, - 10, 3, 237, 232, 221, 101, 25, 231, 203, 10, 3, 237, 232, 221, 101, 25, - 231, 204, 107, 217, 20, 10, 3, 237, 232, 221, 101, 25, 231, 16, 10, 3, - 237, 232, 221, 101, 25, 230, 252, 10, 3, 237, 232, 221, 101, 25, 230, - 135, 10, 3, 237, 232, 221, 101, 25, 144, 10, 3, 237, 232, 221, 101, 25, - 223, 49, 10, 3, 237, 232, 221, 101, 25, 223, 50, 107, 218, 203, 10, 3, - 237, 232, 221, 101, 25, 222, 69, 10, 3, 237, 232, 221, 101, 25, 171, 10, - 3, 237, 232, 221, 101, 25, 218, 203, 10, 3, 237, 232, 221, 101, 25, 218, - 204, 107, 217, 19, 10, 3, 237, 232, 221, 101, 25, 218, 186, 10, 3, 237, - 232, 221, 101, 25, 214, 107, 10, 3, 237, 232, 221, 101, 25, 210, 128, - 107, 210, 127, 10, 3, 237, 232, 221, 101, 25, 202, 217, 10, 3, 237, 232, - 221, 101, 25, 199, 204, 10, 3, 237, 232, 221, 101, 25, 196, 166, 107, - 230, 252, 10, 3, 237, 232, 221, 101, 25, 196, 34, 10, 3, 237, 203, 10, 3, - 237, 180, 10, 3, 237, 179, 10, 3, 237, 178, 10, 3, 236, 255, 10, 3, 236, - 237, 10, 3, 236, 210, 10, 3, 236, 211, 25, 203, 108, 10, 3, 236, 208, 10, - 3, 236, 198, 10, 3, 236, 199, 222, 29, 126, 230, 123, 236, 177, 10, 3, - 236, 177, 10, 3, 235, 45, 10, 3, 235, 46, 138, 235, 45, 10, 3, 235, 46, - 230, 122, 10, 3, 235, 46, 203, 89, 10, 3, 235, 43, 10, 3, 235, 44, 25, - 233, 223, 10, 3, 235, 42, 10, 3, 235, 38, 10, 3, 235, 37, 10, 3, 235, 36, - 10, 3, 235, 31, 10, 3, 235, 29, 10, 3, 235, 30, 230, 122, 10, 3, 235, 30, - 230, 123, 230, 122, 10, 3, 235, 28, 10, 3, 235, 21, 10, 3, 73, 10, 3, - 234, 227, 25, 210, 127, 10, 3, 234, 227, 138, 234, 227, 212, 118, 138, - 212, 117, 10, 3, 234, 174, 10, 3, 234, 175, 25, 41, 107, 230, 72, 107, - 237, 241, 10, 3, 234, 175, 25, 231, 163, 10, 3, 234, 175, 25, 216, 81, - 10, 3, 234, 175, 25, 205, 164, 10, 3, 234, 175, 25, 203, 108, 10, 3, 234, - 175, 25, 69, 10, 3, 234, 147, 10, 3, 234, 134, 10, 3, 234, 97, 10, 3, - 234, 61, 10, 3, 234, 62, 25, 231, 171, 10, 3, 234, 62, 25, 231, 172, 199, - 79, 10, 3, 234, 62, 25, 216, 213, 10, 3, 234, 62, 238, 163, 234, 61, 10, - 3, 234, 62, 211, 52, 234, 61, 10, 3, 234, 62, 201, 184, 10, 3, 233, 245, - 10, 3, 233, 242, 10, 3, 233, 223, 10, 3, 233, 139, 10, 3, 233, 140, 25, - 65, 10, 3, 233, 140, 25, 41, 107, 220, 13, 10, 3, 233, 140, 25, 41, 107, - 220, 14, 25, 220, 13, 10, 3, 233, 140, 25, 251, 81, 10, 3, 233, 140, 25, - 249, 85, 10, 3, 233, 140, 25, 235, 30, 230, 122, 10, 3, 233, 140, 25, - 235, 30, 230, 123, 230, 122, 10, 3, 233, 140, 25, 144, 10, 3, 233, 140, - 25, 230, 72, 230, 122, 10, 3, 233, 140, 25, 223, 173, 230, 122, 10, 3, - 233, 140, 25, 222, 28, 10, 3, 233, 140, 25, 222, 29, 201, 184, 10, 3, - 233, 140, 25, 220, 199, 10, 3, 233, 140, 25, 171, 10, 3, 233, 140, 25, - 220, 14, 25, 220, 13, 10, 3, 233, 140, 25, 219, 122, 10, 3, 233, 140, 25, - 218, 203, 10, 3, 233, 140, 25, 196, 165, 10, 3, 233, 140, 25, 196, 154, - 10, 3, 231, 203, 10, 3, 231, 204, 230, 122, 10, 3, 231, 201, 10, 3, 231, - 202, 25, 41, 107, 237, 242, 107, 144, 10, 3, 231, 202, 25, 41, 107, 144, - 10, 3, 231, 202, 25, 41, 107, 223, 172, 10, 3, 231, 202, 25, 252, 21, - 199, 80, 107, 199, 231, 10, 3, 231, 202, 25, 251, 81, 10, 3, 231, 202, - 25, 250, 159, 10, 3, 231, 202, 25, 250, 158, 107, 231, 185, 10, 3, 231, - 202, 25, 249, 85, 10, 3, 231, 202, 25, 249, 38, 107, 166, 10, 3, 231, - 202, 25, 247, 182, 10, 3, 231, 202, 25, 247, 183, 107, 166, 10, 3, 231, - 202, 25, 237, 241, 10, 3, 231, 202, 25, 236, 255, 10, 3, 231, 202, 25, - 236, 211, 25, 203, 108, 10, 3, 231, 202, 25, 235, 43, 10, 3, 231, 202, - 25, 234, 97, 10, 3, 231, 202, 25, 234, 98, 107, 171, 10, 3, 231, 202, 25, - 234, 61, 10, 3, 231, 202, 25, 234, 62, 25, 231, 172, 199, 79, 10, 3, 231, - 202, 25, 231, 172, 199, 79, 10, 3, 231, 202, 25, 231, 163, 10, 3, 231, - 202, 25, 231, 16, 10, 3, 231, 202, 25, 231, 14, 10, 3, 231, 202, 25, 231, - 15, 107, 65, 10, 3, 231, 202, 25, 230, 253, 107, 200, 255, 10, 3, 231, - 202, 25, 230, 72, 107, 218, 204, 107, 233, 223, 10, 3, 231, 202, 25, 230, - 40, 10, 3, 231, 202, 25, 230, 41, 107, 171, 10, 3, 231, 202, 25, 229, - 127, 107, 219, 122, 10, 3, 231, 202, 25, 228, 120, 10, 3, 231, 202, 25, - 223, 173, 230, 122, 10, 3, 231, 202, 25, 223, 35, 107, 228, 129, 107, - 250, 159, 10, 3, 231, 202, 25, 222, 69, 10, 3, 231, 202, 25, 222, 28, 10, - 3, 231, 202, 25, 221, 128, 10, 3, 231, 202, 25, 221, 129, 107, 220, 13, - 10, 3, 231, 202, 25, 220, 200, 107, 251, 81, 10, 3, 231, 202, 25, 171, - 10, 3, 231, 202, 25, 216, 214, 107, 234, 61, 10, 3, 231, 202, 25, 216, - 81, 10, 3, 231, 202, 25, 212, 117, 10, 3, 231, 202, 25, 212, 118, 138, - 212, 117, 10, 3, 231, 202, 25, 168, 10, 3, 231, 202, 25, 205, 164, 10, 3, - 231, 202, 25, 205, 122, 10, 3, 231, 202, 25, 203, 108, 10, 3, 231, 202, - 25, 203, 109, 107, 197, 60, 10, 3, 231, 202, 25, 203, 74, 10, 3, 231, - 202, 25, 200, 199, 10, 3, 231, 202, 25, 199, 204, 10, 3, 231, 202, 25, - 69, 10, 3, 231, 202, 25, 196, 154, 10, 3, 231, 202, 25, 196, 155, 107, - 235, 45, 10, 3, 231, 202, 138, 231, 201, 10, 3, 231, 196, 10, 3, 231, - 197, 238, 163, 231, 196, 10, 3, 231, 194, 10, 3, 231, 195, 138, 231, 195, - 231, 164, 138, 231, 163, 10, 3, 231, 185, 10, 3, 231, 186, 231, 195, 138, - 231, 195, 231, 164, 138, 231, 163, 10, 3, 231, 184, 10, 3, 231, 182, 10, - 3, 231, 173, 10, 3, 231, 171, 10, 3, 231, 172, 199, 79, 10, 3, 231, 172, - 138, 231, 171, 10, 3, 231, 172, 238, 163, 231, 171, 10, 3, 231, 163, 10, - 3, 231, 162, 10, 3, 231, 156, 10, 3, 231, 97, 10, 3, 231, 98, 25, 220, - 173, 10, 3, 231, 16, 10, 3, 231, 17, 25, 73, 10, 3, 231, 17, 25, 69, 10, - 3, 231, 17, 238, 163, 231, 16, 10, 3, 231, 14, 10, 3, 231, 15, 138, 231, - 14, 10, 3, 231, 15, 238, 163, 231, 14, 10, 3, 231, 11, 10, 3, 230, 252, - 10, 3, 230, 253, 230, 122, 10, 3, 230, 250, 10, 3, 230, 251, 25, 41, 107, - 223, 172, 10, 3, 230, 251, 25, 231, 172, 199, 79, 10, 3, 230, 251, 25, - 223, 172, 10, 3, 230, 251, 25, 218, 204, 107, 223, 172, 10, 3, 230, 251, - 25, 168, 10, 3, 230, 245, 10, 3, 230, 243, 10, 3, 230, 244, 238, 163, - 230, 243, 10, 3, 230, 244, 25, 249, 85, 10, 3, 230, 244, 25, 199, 204, - 10, 3, 230, 244, 199, 79, 10, 3, 230, 146, 10, 3, 230, 147, 238, 163, - 230, 146, 10, 3, 230, 144, 10, 3, 230, 145, 25, 222, 69, 10, 3, 230, 145, - 25, 222, 70, 25, 223, 173, 230, 122, 10, 3, 230, 145, 25, 212, 117, 10, - 3, 230, 145, 25, 205, 165, 107, 197, 78, 10, 3, 230, 145, 230, 122, 10, - 3, 230, 135, 10, 3, 230, 136, 25, 41, 107, 220, 173, 10, 3, 230, 136, 25, - 220, 173, 10, 3, 230, 136, 138, 230, 136, 218, 194, 10, 3, 230, 127, 10, - 3, 230, 125, 10, 3, 230, 126, 25, 203, 108, 10, 3, 230, 116, 10, 3, 230, - 115, 10, 3, 230, 110, 10, 3, 230, 109, 10, 3, 144, 10, 3, 230, 72, 199, - 79, 10, 3, 230, 72, 230, 122, 10, 3, 230, 40, 10, 3, 229, 126, 10, 3, - 229, 127, 25, 250, 159, 10, 3, 229, 127, 25, 250, 157, 10, 3, 229, 127, - 25, 249, 85, 10, 3, 229, 127, 25, 236, 177, 10, 3, 229, 127, 25, 231, - 194, 10, 3, 229, 127, 25, 221, 117, 10, 3, 229, 127, 25, 212, 117, 10, 3, - 229, 127, 25, 203, 108, 10, 3, 229, 127, 25, 69, 10, 3, 228, 128, 10, 3, - 228, 120, 10, 3, 228, 121, 25, 251, 81, 10, 3, 228, 121, 25, 230, 40, 10, - 3, 228, 121, 25, 222, 28, 10, 3, 228, 121, 25, 219, 65, 10, 3, 228, 121, - 25, 196, 154, 10, 3, 228, 115, 10, 3, 70, 10, 3, 228, 44, 65, 10, 3, 228, - 0, 10, 3, 223, 200, 10, 3, 223, 201, 138, 223, 201, 247, 182, 10, 3, 223, - 201, 138, 223, 201, 201, 184, 10, 3, 223, 175, 10, 3, 223, 172, 10, 3, - 223, 173, 236, 237, 10, 3, 223, 173, 206, 252, 10, 3, 223, 173, 138, 223, - 173, 203, 58, 138, 203, 58, 196, 155, 138, 196, 154, 10, 3, 223, 173, - 230, 122, 10, 3, 223, 163, 10, 3, 223, 164, 25, 231, 172, 199, 79, 10, 3, - 223, 162, 10, 3, 223, 152, 10, 3, 223, 153, 25, 199, 204, 10, 3, 223, - 153, 238, 163, 223, 152, 10, 3, 223, 153, 211, 52, 223, 152, 10, 3, 223, - 153, 201, 184, 10, 3, 223, 144, 10, 3, 223, 134, 10, 3, 223, 49, 10, 3, - 223, 34, 10, 3, 157, 10, 3, 222, 115, 25, 65, 10, 3, 222, 115, 25, 251, - 246, 10, 3, 222, 115, 25, 251, 247, 107, 220, 199, 10, 3, 222, 115, 25, - 250, 157, 10, 3, 222, 115, 25, 249, 85, 10, 3, 222, 115, 25, 249, 64, 10, - 3, 222, 115, 25, 164, 10, 3, 222, 115, 25, 248, 140, 10, 3, 222, 115, 25, - 233, 242, 10, 3, 222, 115, 25, 233, 223, 10, 3, 222, 115, 25, 231, 203, - 10, 3, 222, 115, 25, 231, 185, 10, 3, 222, 115, 25, 231, 172, 199, 79, - 10, 3, 222, 115, 25, 231, 163, 10, 3, 222, 115, 25, 231, 164, 107, 203, - 159, 107, 65, 10, 3, 222, 115, 25, 231, 16, 10, 3, 222, 115, 25, 230, - 252, 10, 3, 222, 115, 25, 230, 244, 107, 205, 122, 10, 3, 222, 115, 25, - 230, 244, 238, 163, 230, 243, 10, 3, 222, 115, 25, 230, 146, 10, 3, 222, - 115, 25, 230, 115, 10, 3, 222, 115, 25, 223, 172, 10, 3, 222, 115, 25, - 223, 152, 10, 3, 222, 115, 25, 222, 69, 10, 3, 222, 115, 25, 221, 142, - 10, 3, 222, 115, 25, 221, 128, 10, 3, 222, 115, 25, 219, 122, 10, 3, 222, - 115, 25, 218, 203, 10, 3, 222, 115, 25, 216, 213, 10, 3, 222, 115, 25, - 216, 214, 107, 235, 45, 10, 3, 222, 115, 25, 216, 214, 107, 231, 16, 10, - 3, 222, 115, 25, 216, 214, 107, 199, 140, 10, 3, 222, 115, 25, 216, 81, - 10, 3, 222, 115, 25, 216, 82, 107, 212, 112, 10, 3, 222, 115, 25, 214, - 107, 10, 3, 222, 115, 25, 212, 117, 10, 3, 222, 115, 25, 209, 176, 10, 3, - 222, 115, 25, 206, 63, 10, 3, 222, 115, 25, 189, 10, 3, 222, 115, 25, - 205, 122, 10, 3, 222, 115, 25, 203, 160, 10, 3, 222, 115, 25, 203, 108, - 10, 3, 222, 115, 25, 203, 74, 10, 3, 222, 115, 25, 203, 0, 10, 3, 222, - 115, 25, 202, 196, 10, 3, 222, 115, 25, 200, 208, 10, 3, 222, 115, 25, - 199, 174, 10, 3, 222, 115, 25, 69, 10, 3, 222, 115, 25, 196, 165, 10, 3, - 222, 115, 25, 196, 154, 10, 3, 222, 115, 25, 196, 112, 25, 168, 10, 3, - 222, 115, 25, 196, 34, 10, 3, 222, 115, 25, 191, 30, 10, 3, 222, 101, 10, - 3, 222, 102, 238, 163, 222, 101, 10, 3, 222, 90, 10, 3, 222, 86, 10, 3, - 222, 84, 10, 3, 222, 83, 10, 3, 222, 81, 10, 3, 222, 82, 138, 222, 81, - 10, 3, 222, 69, 10, 3, 222, 70, 25, 223, 173, 230, 122, 10, 3, 222, 65, - 10, 3, 222, 66, 25, 249, 85, 10, 3, 222, 66, 238, 163, 222, 65, 10, 3, - 222, 63, 10, 3, 222, 62, 10, 3, 222, 28, 10, 3, 222, 29, 220, 81, 25, - 126, 138, 220, 81, 25, 69, 10, 3, 222, 29, 138, 222, 29, 220, 81, 25, - 126, 138, 220, 81, 25, 69, 10, 3, 221, 217, 10, 3, 221, 142, 10, 3, 221, - 143, 25, 249, 85, 10, 3, 221, 143, 25, 69, 10, 3, 221, 143, 25, 196, 154, - 10, 3, 221, 128, 10, 3, 221, 117, 10, 3, 221, 103, 10, 3, 221, 102, 10, - 3, 221, 100, 10, 3, 221, 101, 138, 221, 100, 10, 3, 220, 208, 10, 3, 220, - 209, 138, 229, 127, 25, 250, 158, 220, 209, 138, 229, 127, 25, 250, 157, - 10, 3, 220, 199, 10, 3, 220, 197, 10, 3, 220, 198, 195, 165, 20, 10, 3, - 220, 196, 10, 3, 220, 187, 10, 3, 220, 188, 230, 122, 10, 3, 220, 186, - 10, 3, 220, 173, 10, 3, 220, 174, 211, 52, 220, 173, 10, 3, 220, 166, 10, - 3, 220, 143, 10, 3, 171, 10, 3, 220, 80, 10, 3, 220, 81, 25, 65, 10, 3, - 220, 81, 25, 41, 107, 237, 242, 107, 144, 10, 3, 220, 81, 25, 41, 107, - 231, 163, 10, 3, 220, 81, 25, 41, 107, 220, 13, 10, 3, 220, 81, 25, 251, - 156, 10, 3, 220, 81, 25, 251, 81, 10, 3, 220, 81, 25, 250, 160, 191, 26, - 199, 79, 10, 3, 220, 81, 25, 249, 85, 10, 3, 220, 81, 25, 248, 140, 10, - 3, 220, 81, 25, 237, 180, 10, 3, 220, 81, 25, 234, 61, 10, 3, 220, 81, - 25, 231, 203, 10, 3, 220, 81, 25, 231, 163, 10, 3, 220, 81, 25, 230, 135, - 10, 3, 220, 81, 25, 230, 136, 107, 230, 135, 10, 3, 220, 81, 25, 144, 10, - 3, 220, 81, 25, 230, 40, 10, 3, 220, 81, 25, 229, 127, 25, 212, 117, 10, - 3, 220, 81, 25, 223, 173, 230, 122, 10, 3, 220, 81, 25, 223, 152, 10, 3, - 220, 81, 25, 223, 153, 107, 144, 10, 3, 220, 81, 25, 223, 153, 107, 218, - 203, 10, 3, 220, 81, 25, 221, 142, 10, 3, 220, 81, 25, 221, 117, 10, 3, - 220, 81, 25, 220, 199, 10, 3, 220, 81, 25, 220, 187, 10, 3, 220, 81, 25, - 220, 188, 107, 229, 127, 107, 65, 10, 3, 220, 81, 25, 220, 80, 10, 3, - 220, 81, 25, 219, 65, 10, 3, 220, 81, 25, 218, 203, 10, 3, 220, 81, 25, - 218, 188, 10, 3, 220, 81, 25, 216, 213, 10, 3, 220, 81, 25, 216, 214, - 107, 234, 61, 10, 3, 220, 81, 25, 215, 87, 10, 3, 220, 81, 25, 214, 107, - 10, 3, 220, 81, 25, 203, 109, 107, 200, 199, 10, 3, 220, 81, 25, 203, 54, - 107, 230, 244, 107, 233, 242, 10, 3, 220, 81, 25, 203, 54, 107, 230, 244, - 199, 79, 10, 3, 220, 81, 25, 202, 254, 10, 3, 220, 81, 25, 202, 255, 107, - 202, 254, 10, 3, 220, 81, 25, 200, 199, 10, 3, 220, 81, 25, 199, 218, 10, - 3, 220, 81, 25, 199, 204, 10, 3, 220, 81, 25, 199, 141, 107, 41, 107, - 201, 0, 107, 180, 10, 3, 220, 81, 25, 69, 10, 3, 220, 81, 25, 126, 107, - 65, 10, 3, 220, 81, 25, 126, 107, 126, 107, 69, 10, 3, 220, 81, 25, 196, - 166, 107, 250, 159, 10, 3, 220, 81, 25, 196, 154, 10, 3, 220, 81, 25, - 196, 34, 10, 3, 220, 81, 201, 184, 10, 3, 220, 78, 10, 3, 220, 79, 25, - 203, 108, 10, 3, 220, 79, 25, 203, 109, 107, 200, 199, 10, 3, 220, 79, - 230, 122, 10, 3, 220, 79, 230, 123, 138, 220, 79, 230, 123, 203, 108, 10, - 3, 220, 74, 10, 3, 220, 13, 10, 3, 220, 14, 25, 220, 13, 10, 3, 220, 11, - 10, 3, 220, 12, 25, 220, 173, 10, 3, 220, 12, 25, 220, 174, 107, 206, 63, - 10, 3, 219, 122, 10, 3, 219, 103, 10, 3, 219, 91, 10, 3, 219, 65, 10, 3, - 218, 203, 10, 3, 218, 204, 25, 249, 85, 10, 3, 218, 201, 10, 3, 218, 202, - 25, 251, 156, 10, 3, 218, 202, 25, 249, 85, 10, 3, 218, 202, 25, 233, - 223, 10, 3, 218, 202, 25, 233, 224, 199, 79, 10, 3, 218, 202, 25, 231, - 172, 199, 79, 10, 3, 218, 202, 25, 229, 127, 25, 249, 85, 10, 3, 218, - 202, 25, 223, 152, 10, 3, 218, 202, 25, 222, 86, 10, 3, 218, 202, 25, - 222, 84, 10, 3, 218, 202, 25, 222, 85, 107, 250, 159, 10, 3, 218, 202, - 25, 221, 142, 10, 3, 218, 202, 25, 220, 102, 107, 250, 159, 10, 3, 218, - 202, 25, 220, 80, 10, 3, 218, 202, 25, 216, 214, 107, 234, 61, 10, 3, - 218, 202, 25, 214, 107, 10, 3, 218, 202, 25, 212, 165, 10, 3, 218, 202, - 25, 202, 218, 107, 250, 159, 10, 3, 218, 202, 25, 202, 187, 107, 247, - 218, 10, 3, 218, 202, 25, 197, 78, 10, 3, 218, 202, 199, 79, 10, 3, 218, - 202, 238, 163, 218, 201, 10, 3, 218, 202, 211, 52, 218, 201, 10, 3, 218, - 202, 201, 184, 10, 3, 218, 202, 203, 89, 10, 3, 218, 200, 10, 3, 218, - 194, 10, 3, 218, 195, 138, 218, 194, 10, 3, 218, 195, 211, 52, 218, 194, - 10, 3, 218, 195, 203, 89, 10, 3, 218, 191, 10, 3, 218, 188, 10, 3, 218, - 186, 10, 3, 218, 187, 138, 218, 186, 10, 3, 218, 187, 138, 218, 187, 231, - 164, 138, 231, 163, 10, 3, 172, 10, 3, 217, 139, 25, 199, 204, 10, 3, - 217, 139, 230, 122, 10, 3, 217, 131, 10, 3, 217, 99, 10, 3, 217, 45, 10, - 3, 217, 20, 10, 3, 217, 19, 10, 3, 216, 213, 10, 3, 216, 154, 10, 3, 216, - 81, 10, 3, 216, 26, 10, 3, 215, 139, 10, 3, 215, 140, 138, 215, 139, 10, - 3, 215, 124, 10, 3, 215, 125, 230, 122, 10, 3, 215, 105, 10, 3, 215, 91, - 10, 3, 215, 87, 10, 3, 215, 88, 25, 65, 10, 3, 215, 88, 25, 220, 173, 10, - 3, 215, 88, 25, 191, 123, 10, 3, 215, 88, 138, 215, 87, 10, 3, 215, 88, - 138, 215, 88, 25, 41, 107, 180, 10, 3, 215, 88, 238, 163, 215, 87, 10, 3, - 215, 85, 10, 3, 215, 86, 25, 65, 10, 3, 215, 86, 25, 41, 107, 236, 255, - 10, 3, 215, 86, 25, 236, 255, 10, 3, 215, 86, 230, 122, 10, 3, 180, 10, - 3, 214, 239, 10, 3, 214, 226, 10, 3, 214, 227, 223, 64, 10, 3, 214, 227, - 25, 203, 1, 199, 79, 10, 3, 214, 227, 211, 52, 214, 226, 10, 3, 214, 225, - 10, 3, 214, 217, 212, 103, 10, 3, 214, 216, 10, 3, 214, 215, 10, 3, 214, - 107, 10, 3, 214, 108, 25, 65, 10, 3, 214, 108, 25, 196, 154, 10, 3, 214, - 108, 203, 89, 10, 3, 213, 205, 10, 3, 213, 206, 25, 73, 10, 3, 213, 196, - 10, 3, 213, 166, 10, 3, 213, 167, 25, 231, 172, 199, 79, 10, 3, 213, 167, - 25, 231, 164, 107, 231, 172, 199, 79, 10, 3, 213, 162, 10, 3, 213, 163, - 25, 251, 81, 10, 3, 213, 163, 25, 250, 159, 10, 3, 213, 163, 25, 250, - 160, 107, 250, 159, 10, 3, 213, 163, 25, 230, 135, 10, 3, 213, 163, 25, - 216, 214, 107, 231, 172, 199, 79, 10, 3, 213, 163, 25, 214, 107, 10, 3, - 213, 163, 25, 212, 117, 10, 3, 213, 163, 25, 203, 108, 10, 3, 213, 163, - 25, 203, 109, 107, 41, 251, 81, 10, 3, 213, 163, 25, 203, 109, 107, 250, - 159, 10, 3, 213, 163, 25, 203, 109, 107, 250, 160, 107, 250, 159, 10, 3, - 213, 163, 25, 196, 166, 107, 250, 159, 10, 3, 213, 163, 25, 196, 34, 10, - 3, 213, 150, 10, 3, 212, 165, 10, 3, 212, 134, 10, 3, 212, 117, 10, 3, - 212, 118, 220, 79, 25, 231, 163, 10, 3, 212, 118, 220, 79, 25, 217, 20, - 10, 3, 212, 118, 220, 79, 25, 205, 164, 10, 3, 212, 118, 220, 79, 25, - 205, 165, 138, 212, 118, 220, 79, 25, 205, 164, 10, 3, 212, 118, 220, 79, - 25, 196, 34, 10, 3, 212, 118, 199, 79, 10, 3, 212, 118, 138, 212, 117, - 10, 3, 212, 118, 238, 163, 212, 117, 10, 3, 212, 118, 238, 163, 212, 118, - 220, 79, 138, 220, 78, 10, 3, 212, 112, 10, 3, 212, 113, 252, 21, 25, - 250, 153, 10, 3, 212, 113, 252, 21, 25, 248, 140, 10, 3, 212, 113, 252, - 21, 25, 235, 38, 10, 3, 212, 113, 252, 21, 25, 230, 135, 10, 3, 212, 113, - 252, 21, 25, 223, 173, 230, 122, 10, 3, 212, 113, 252, 21, 25, 222, 84, - 10, 3, 212, 113, 252, 21, 25, 171, 10, 3, 212, 113, 252, 21, 25, 214, - 107, 10, 3, 212, 113, 252, 21, 25, 202, 184, 10, 3, 212, 113, 252, 21, - 25, 196, 165, 10, 3, 212, 113, 221, 101, 25, 248, 140, 10, 3, 212, 113, - 221, 101, 25, 248, 141, 69, 10, 3, 168, 10, 3, 210, 200, 10, 3, 210, 156, - 10, 3, 210, 127, 10, 3, 209, 234, 10, 3, 209, 176, 10, 3, 209, 177, 25, - 65, 10, 3, 209, 177, 25, 252, 103, 10, 3, 209, 177, 25, 248, 140, 10, 3, - 209, 177, 25, 247, 218, 10, 3, 209, 177, 25, 73, 10, 3, 209, 177, 25, 70, - 10, 3, 209, 177, 25, 228, 0, 10, 3, 209, 177, 25, 69, 10, 3, 209, 177, - 25, 196, 165, 10, 3, 209, 177, 238, 163, 209, 176, 10, 3, 209, 113, 10, - 3, 209, 114, 25, 222, 65, 10, 3, 209, 114, 25, 196, 154, 10, 3, 209, 114, - 25, 191, 123, 10, 3, 209, 114, 211, 52, 209, 113, 10, 3, 166, 10, 3, 207, - 171, 10, 3, 206, 252, 10, 3, 206, 63, 10, 3, 189, 10, 3, 205, 181, 212, - 103, 10, 3, 205, 180, 10, 3, 205, 181, 25, 65, 10, 3, 205, 181, 25, 235, - 45, 10, 3, 205, 181, 25, 235, 43, 10, 3, 205, 181, 25, 144, 10, 3, 205, - 181, 25, 222, 69, 10, 3, 205, 181, 25, 220, 173, 10, 3, 205, 181, 25, - 218, 186, 10, 3, 205, 181, 25, 216, 81, 10, 3, 205, 181, 25, 212, 117, - 10, 3, 205, 181, 25, 205, 164, 10, 3, 205, 181, 25, 203, 74, 10, 3, 205, - 181, 25, 199, 231, 10, 3, 205, 181, 25, 196, 165, 10, 3, 205, 181, 25, - 196, 160, 10, 3, 205, 181, 25, 196, 116, 10, 3, 205, 181, 25, 196, 58, - 10, 3, 205, 181, 25, 196, 34, 10, 3, 205, 181, 138, 205, 180, 10, 3, 205, - 181, 230, 122, 10, 3, 205, 164, 10, 3, 205, 165, 220, 81, 25, 250, 157, - 10, 3, 205, 131, 10, 3, 205, 122, 10, 3, 203, 160, 10, 3, 203, 158, 10, - 3, 203, 159, 25, 65, 10, 3, 203, 159, 25, 249, 85, 10, 3, 203, 159, 25, - 230, 243, 10, 3, 203, 159, 25, 214, 107, 10, 3, 203, 159, 25, 202, 254, - 10, 3, 203, 159, 25, 197, 60, 10, 3, 203, 159, 25, 69, 10, 3, 203, 159, - 25, 126, 107, 65, 10, 3, 203, 156, 10, 3, 203, 154, 10, 3, 203, 126, 10, - 3, 203, 108, 10, 3, 203, 109, 228, 128, 10, 3, 203, 109, 138, 203, 109, - 231, 195, 138, 231, 195, 231, 164, 138, 231, 163, 10, 3, 203, 109, 138, - 203, 109, 199, 232, 138, 199, 232, 231, 164, 138, 231, 163, 10, 3, 203, - 101, 10, 3, 203, 96, 10, 3, 203, 92, 10, 3, 203, 91, 10, 3, 203, 88, 10, - 3, 203, 74, 10, 3, 203, 75, 25, 65, 10, 3, 203, 75, 25, 223, 152, 10, 3, - 203, 68, 10, 3, 203, 69, 25, 65, 10, 3, 203, 69, 25, 249, 65, 10, 3, 203, - 69, 25, 247, 194, 10, 3, 203, 69, 25, 236, 198, 10, 3, 203, 69, 25, 231, - 163, 10, 3, 203, 69, 25, 223, 172, 10, 3, 203, 69, 25, 223, 173, 230, - 122, 10, 3, 203, 69, 25, 220, 166, 10, 3, 203, 69, 25, 218, 188, 10, 3, - 203, 69, 25, 215, 124, 10, 3, 203, 69, 25, 205, 164, 10, 3, 203, 62, 10, - 3, 203, 57, 10, 3, 203, 58, 199, 79, 10, 3, 203, 58, 138, 203, 58, 247, - 183, 138, 247, 182, 10, 3, 203, 53, 10, 3, 203, 0, 10, 3, 203, 1, 138, - 223, 65, 203, 0, 10, 3, 202, 254, 10, 3, 202, 252, 10, 3, 202, 217, 10, - 3, 202, 218, 230, 122, 10, 3, 202, 196, 10, 3, 202, 194, 10, 3, 202, 195, - 138, 202, 195, 202, 254, 10, 3, 202, 186, 10, 3, 202, 184, 10, 3, 200, - 255, 10, 3, 201, 0, 138, 200, 255, 10, 3, 200, 211, 10, 3, 200, 210, 10, - 3, 200, 208, 10, 3, 200, 199, 10, 3, 200, 198, 10, 3, 200, 170, 10, 3, - 200, 169, 10, 3, 199, 247, 10, 3, 199, 248, 250, 143, 10, 3, 199, 248, - 25, 229, 126, 10, 3, 199, 248, 25, 216, 81, 10, 3, 199, 248, 230, 122, - 10, 3, 199, 231, 10, 3, 199, 232, 138, 199, 232, 213, 206, 138, 213, 206, - 236, 178, 138, 236, 177, 10, 3, 199, 232, 201, 184, 10, 3, 199, 218, 10, - 3, 199, 219, 25, 248, 140, 10, 3, 199, 219, 25, 230, 135, 10, 3, 199, - 219, 25, 203, 108, 10, 3, 199, 219, 25, 203, 0, 10, 3, 199, 219, 25, 197, - 78, 10, 3, 199, 219, 25, 196, 154, 10, 3, 199, 204, 10, 3, 199, 174, 10, - 3, 199, 140, 10, 3, 199, 141, 230, 122, 10, 3, 198, 188, 10, 3, 198, 189, - 199, 79, 10, 3, 198, 149, 10, 3, 198, 126, 10, 3, 198, 127, 25, 199, 204, - 10, 3, 198, 127, 138, 198, 126, 10, 3, 198, 127, 138, 198, 127, 231, 195, - 138, 231, 195, 231, 164, 138, 231, 163, 10, 3, 197, 90, 10, 3, 197, 78, - 10, 3, 197, 76, 10, 3, 197, 72, 10, 3, 197, 60, 10, 3, 197, 61, 138, 197, - 61, 191, 124, 138, 191, 123, 10, 3, 69, 10, 3, 126, 230, 135, 10, 3, 126, - 126, 69, 10, 3, 126, 138, 126, 210, 211, 138, 210, 211, 231, 164, 138, - 231, 163, 10, 3, 126, 138, 126, 200, 171, 138, 200, 170, 10, 3, 126, 138, - 126, 126, 207, 13, 138, 126, 207, 12, 10, 3, 196, 165, 10, 3, 196, 160, - 10, 3, 196, 154, 10, 3, 196, 155, 220, 166, 10, 3, 196, 155, 25, 249, 85, - 10, 3, 196, 155, 25, 216, 81, 10, 3, 196, 155, 25, 126, 107, 126, 107, - 69, 10, 3, 196, 155, 25, 126, 107, 126, 107, 126, 230, 122, 10, 3, 196, - 155, 230, 122, 10, 3, 196, 155, 203, 89, 10, 3, 196, 155, 203, 90, 25, - 249, 85, 10, 3, 196, 149, 10, 3, 196, 116, 10, 3, 196, 117, 25, 220, 80, - 10, 3, 196, 117, 25, 216, 214, 107, 237, 241, 10, 3, 196, 117, 25, 203, - 158, 10, 3, 196, 117, 25, 69, 10, 3, 196, 115, 10, 3, 196, 111, 10, 3, - 196, 112, 25, 222, 28, 10, 3, 196, 112, 25, 168, 10, 3, 196, 109, 10, 3, - 196, 110, 230, 122, 10, 3, 196, 58, 10, 3, 196, 59, 238, 163, 196, 58, - 10, 3, 196, 59, 203, 89, 10, 3, 196, 56, 10, 3, 196, 57, 25, 41, 107, - 144, 10, 3, 196, 57, 25, 41, 107, 180, 10, 3, 196, 57, 25, 251, 156, 10, - 3, 196, 57, 25, 144, 10, 3, 196, 57, 25, 212, 117, 10, 3, 196, 57, 25, - 196, 165, 10, 3, 196, 57, 25, 196, 166, 107, 250, 159, 10, 3, 196, 57, - 25, 196, 166, 107, 248, 140, 10, 3, 196, 55, 10, 3, 196, 52, 10, 3, 196, - 51, 10, 3, 196, 47, 10, 3, 196, 48, 25, 65, 10, 3, 196, 48, 25, 250, 153, - 10, 3, 196, 48, 25, 164, 10, 3, 196, 48, 25, 235, 31, 10, 3, 196, 48, 25, - 231, 203, 10, 3, 196, 48, 25, 231, 185, 10, 3, 196, 48, 25, 231, 172, - 199, 79, 10, 3, 196, 48, 25, 231, 163, 10, 3, 196, 48, 25, 230, 146, 10, - 3, 196, 48, 25, 144, 10, 3, 196, 48, 25, 223, 172, 10, 3, 196, 48, 25, - 223, 152, 10, 3, 196, 48, 25, 223, 34, 10, 3, 196, 48, 25, 221, 142, 10, - 3, 196, 48, 25, 218, 186, 10, 3, 196, 48, 25, 216, 26, 10, 3, 196, 48, - 25, 168, 10, 3, 196, 48, 25, 203, 108, 10, 3, 196, 48, 25, 202, 194, 10, - 3, 196, 48, 25, 197, 90, 10, 3, 196, 48, 25, 126, 107, 230, 135, 10, 3, - 196, 48, 25, 196, 154, 10, 3, 196, 48, 25, 196, 45, 10, 3, 196, 45, 10, - 3, 196, 46, 25, 69, 10, 3, 196, 34, 10, 3, 196, 35, 25, 65, 10, 3, 196, - 35, 25, 220, 208, 10, 3, 196, 35, 25, 220, 173, 10, 3, 196, 35, 25, 199, - 204, 10, 3, 196, 30, 10, 3, 196, 33, 10, 3, 196, 31, 10, 3, 196, 27, 10, - 3, 196, 12, 10, 3, 196, 13, 25, 222, 28, 10, 3, 196, 10, 10, 3, 191, 123, - 10, 3, 191, 124, 199, 79, 10, 3, 191, 124, 112, 25, 220, 173, 10, 3, 191, - 118, 10, 3, 191, 107, 10, 3, 191, 86, 10, 3, 191, 30, 10, 3, 191, 31, - 138, 191, 30, 10, 3, 191, 29, 10, 3, 191, 27, 10, 3, 191, 28, 222, 89, - 199, 79, 10, 3, 191, 22, 10, 3, 191, 13, 10, 3, 190, 251, 10, 3, 190, - 249, 10, 3, 190, 250, 25, 65, 10, 3, 190, 248, 10, 3, 190, 247, 10, 3, - 222, 53, 234, 94, 10, 3, 252, 104, 25, 212, 117, 10, 3, 252, 21, 25, 65, - 10, 3, 251, 95, 25, 220, 189, 10, 3, 237, 232, 221, 101, 25, 196, 166, - 107, 217, 20, 10, 3, 237, 230, 10, 3, 236, 178, 107, 203, 0, 10, 3, 235, - 44, 25, 203, 108, 10, 3, 233, 140, 25, 230, 135, 10, 3, 233, 140, 25, - 203, 108, 10, 3, 231, 202, 25, 251, 82, 107, 222, 70, 107, 65, 10, 3, - 231, 202, 25, 250, 157, 10, 3, 231, 127, 10, 3, 231, 5, 10, 3, 228, 100, - 10, 3, 222, 115, 25, 251, 40, 10, 3, 222, 115, 25, 250, 156, 10, 3, 222, - 115, 25, 230, 243, 10, 3, 222, 115, 25, 230, 135, 10, 3, 222, 115, 25, - 229, 127, 25, 250, 157, 10, 3, 222, 115, 25, 218, 186, 10, 3, 222, 115, - 25, 168, 10, 3, 222, 115, 25, 202, 248, 10, 3, 222, 115, 25, 197, 90, 10, - 3, 222, 115, 25, 196, 56, 10, 3, 220, 81, 25, 231, 16, 10, 3, 218, 202, - 203, 90, 25, 249, 85, 10, 3, 218, 202, 25, 233, 224, 107, 220, 13, 10, 3, - 218, 202, 25, 203, 0, 10, 3, 216, 153, 10, 3, 215, 86, 25, 191, 123, 10, - 3, 214, 238, 10, 3, 213, 165, 10, 3, 213, 164, 10, 3, 213, 163, 25, 249, - 65, 10, 3, 213, 163, 25, 231, 16, 10, 3, 212, 135, 206, 117, 213, 157, - 237, 79, 10, 3, 209, 235, 250, 143, 10, 3, 209, 117, 10, 3, 205, 181, 25, - 223, 173, 230, 122, 10, 3, 198, 180, 10, 3, 196, 117, 25, 216, 213, 10, - 3, 126, 69, 10, 167, 3, 103, 250, 159, 10, 167, 3, 115, 250, 159, 10, - 167, 3, 232, 90, 250, 159, 10, 167, 3, 232, 185, 250, 159, 10, 167, 3, - 202, 131, 250, 159, 10, 167, 3, 203, 242, 250, 159, 10, 167, 3, 234, 121, - 250, 159, 10, 167, 3, 213, 161, 250, 159, 10, 167, 3, 115, 236, 177, 10, - 167, 3, 232, 90, 236, 177, 10, 167, 3, 232, 185, 236, 177, 10, 167, 3, - 202, 131, 236, 177, 10, 167, 3, 203, 242, 236, 177, 10, 167, 3, 234, 121, - 236, 177, 10, 167, 3, 213, 161, 236, 177, 10, 167, 3, 232, 90, 69, 10, - 167, 3, 232, 185, 69, 10, 167, 3, 202, 131, 69, 10, 167, 3, 203, 242, 69, - 10, 167, 3, 234, 121, 69, 10, 167, 3, 213, 161, 69, 10, 167, 3, 91, 231, - 99, 10, 167, 3, 103, 231, 99, 10, 167, 3, 115, 231, 99, 10, 167, 3, 232, - 90, 231, 99, 10, 167, 3, 232, 185, 231, 99, 10, 167, 3, 202, 131, 231, - 99, 10, 167, 3, 203, 242, 231, 99, 10, 167, 3, 234, 121, 231, 99, 10, - 167, 3, 213, 161, 231, 99, 10, 167, 3, 91, 231, 96, 10, 167, 3, 103, 231, - 96, 10, 167, 3, 115, 231, 96, 10, 167, 3, 232, 90, 231, 96, 10, 167, 3, - 232, 185, 231, 96, 10, 167, 3, 103, 203, 126, 10, 167, 3, 115, 203, 126, - 10, 167, 3, 115, 203, 127, 195, 165, 20, 10, 167, 3, 232, 90, 203, 126, - 10, 167, 3, 232, 185, 203, 126, 10, 167, 3, 202, 131, 203, 126, 10, 167, - 3, 203, 242, 203, 126, 10, 167, 3, 234, 121, 203, 126, 10, 167, 3, 213, - 161, 203, 126, 10, 167, 3, 91, 203, 119, 10, 167, 3, 103, 203, 119, 10, - 167, 3, 115, 203, 119, 10, 167, 3, 115, 203, 120, 195, 165, 20, 10, 167, - 3, 232, 90, 203, 119, 10, 167, 3, 232, 185, 203, 119, 10, 167, 3, 203, - 127, 25, 231, 186, 107, 236, 177, 10, 167, 3, 203, 127, 25, 231, 186, - 107, 216, 26, 10, 167, 3, 91, 247, 178, 10, 167, 3, 103, 247, 178, 10, - 167, 3, 115, 247, 178, 10, 167, 3, 115, 247, 179, 195, 165, 20, 10, 167, - 3, 232, 90, 247, 178, 10, 167, 3, 232, 185, 247, 178, 10, 167, 3, 115, - 195, 165, 232, 107, 233, 225, 10, 167, 3, 115, 195, 165, 232, 107, 233, - 222, 10, 167, 3, 232, 90, 195, 165, 232, 107, 219, 92, 10, 167, 3, 232, - 90, 195, 165, 232, 107, 219, 90, 10, 167, 3, 232, 90, 195, 165, 232, 107, - 219, 93, 65, 10, 167, 3, 232, 90, 195, 165, 232, 107, 219, 93, 250, 70, - 10, 167, 3, 202, 131, 195, 165, 232, 107, 250, 155, 10, 167, 3, 203, 242, - 195, 165, 232, 107, 223, 143, 10, 167, 3, 203, 242, 195, 165, 232, 107, - 223, 145, 65, 10, 167, 3, 203, 242, 195, 165, 232, 107, 223, 145, 250, - 70, 10, 167, 3, 234, 121, 195, 165, 232, 107, 196, 29, 10, 167, 3, 234, - 121, 195, 165, 232, 107, 196, 28, 10, 167, 3, 213, 161, 195, 165, 232, - 107, 223, 160, 10, 167, 3, 213, 161, 195, 165, 232, 107, 223, 159, 10, - 167, 3, 213, 161, 195, 165, 232, 107, 223, 158, 10, 167, 3, 213, 161, - 195, 165, 232, 107, 223, 161, 65, 10, 167, 3, 103, 250, 160, 199, 79, 10, - 167, 3, 115, 250, 160, 199, 79, 10, 167, 3, 232, 90, 250, 160, 199, 79, - 10, 167, 3, 232, 185, 250, 160, 199, 79, 10, 167, 3, 202, 131, 250, 160, - 199, 79, 10, 167, 3, 91, 249, 49, 10, 167, 3, 103, 249, 49, 10, 167, 3, - 115, 249, 49, 10, 167, 3, 232, 90, 249, 49, 10, 167, 3, 232, 90, 249, 50, - 195, 165, 20, 10, 167, 3, 232, 185, 249, 49, 10, 167, 3, 232, 185, 249, - 50, 195, 165, 20, 10, 167, 3, 213, 174, 10, 167, 3, 213, 175, 10, 167, 3, - 91, 233, 221, 10, 167, 3, 103, 233, 221, 10, 167, 3, 91, 198, 252, 236, - 177, 10, 167, 3, 103, 198, 249, 236, 177, 10, 167, 3, 232, 185, 202, 118, - 236, 177, 10, 167, 3, 91, 198, 252, 195, 165, 232, 107, 65, 10, 167, 3, - 103, 198, 249, 195, 165, 232, 107, 65, 10, 167, 3, 91, 234, 117, 250, - 159, 10, 167, 3, 91, 208, 18, 250, 159, 10, 167, 3, 38, 250, 146, 91, - 202, 119, 10, 167, 3, 38, 250, 146, 91, 208, 17, 10, 167, 3, 91, 208, 18, - 230, 116, 10, 167, 3, 91, 134, 230, 116, 10, 167, 3, 234, 95, 91, 198, - 251, 10, 167, 3, 234, 95, 103, 198, 248, 10, 167, 3, 234, 95, 232, 97, - 10, 167, 3, 234, 95, 232, 230, 10, 167, 3, 232, 90, 126, 195, 165, 20, - 10, 167, 3, 232, 185, 126, 195, 165, 20, 10, 167, 3, 202, 131, 126, 195, - 165, 20, 10, 167, 3, 203, 242, 126, 195, 165, 20, 10, 167, 3, 234, 121, - 126, 195, 165, 20, 10, 167, 3, 213, 161, 126, 195, 165, 20, 10, 208, 145, - 3, 38, 250, 146, 193, 23, 236, 160, 10, 208, 145, 3, 81, 242, 35, 10, - 208, 145, 3, 236, 250, 242, 35, 10, 208, 145, 3, 236, 250, 197, 233, 10, - 208, 145, 3, 236, 250, 208, 23, 10, 3, 252, 104, 25, 212, 118, 199, 79, - 10, 3, 252, 104, 25, 202, 254, 10, 3, 251, 247, 25, 233, 223, 10, 3, 249, - 86, 25, 236, 178, 199, 79, 10, 3, 249, 72, 25, 252, 20, 10, 3, 249, 72, - 25, 213, 205, 10, 3, 249, 72, 25, 191, 123, 10, 3, 247, 219, 138, 247, - 219, 25, 214, 239, 10, 3, 237, 242, 25, 199, 204, 10, 3, 237, 232, 25, - 220, 173, 10, 3, 236, 211, 25, 223, 172, 10, 3, 236, 211, 25, 126, 126, - 69, 10, 3, 236, 209, 25, 196, 154, 10, 3, 235, 39, 25, 251, 40, 10, 3, - 235, 39, 25, 250, 159, 10, 3, 235, 39, 25, 250, 160, 250, 133, 219, 200, - 10, 3, 235, 39, 25, 236, 198, 10, 3, 235, 39, 25, 235, 31, 10, 3, 235, - 39, 25, 233, 242, 10, 3, 235, 39, 25, 231, 203, 10, 3, 235, 39, 25, 231, - 16, 10, 3, 235, 39, 25, 230, 253, 230, 122, 10, 3, 235, 39, 25, 230, 243, - 10, 3, 235, 39, 25, 144, 10, 3, 235, 39, 25, 229, 126, 10, 3, 235, 39, - 25, 223, 173, 230, 122, 10, 3, 235, 39, 25, 222, 28, 10, 3, 235, 39, 25, - 220, 173, 10, 3, 235, 39, 25, 220, 166, 10, 3, 235, 39, 25, 220, 167, - 107, 222, 28, 10, 3, 235, 39, 25, 220, 68, 10, 3, 235, 39, 25, 220, 11, - 10, 3, 235, 39, 25, 220, 12, 25, 220, 173, 10, 3, 235, 39, 25, 218, 192, - 107, 230, 243, 10, 3, 235, 39, 25, 217, 20, 10, 3, 235, 39, 25, 216, 154, - 10, 3, 235, 39, 25, 216, 81, 10, 3, 235, 39, 25, 213, 205, 10, 3, 235, - 39, 25, 209, 176, 10, 3, 235, 39, 25, 203, 108, 10, 3, 235, 39, 25, 202, - 218, 230, 122, 10, 3, 234, 175, 25, 220, 173, 10, 3, 234, 175, 25, 210, - 127, 10, 3, 233, 243, 192, 235, 10, 3, 233, 224, 238, 163, 233, 223, 10, - 3, 233, 140, 203, 90, 25, 250, 159, 10, 3, 233, 140, 203, 90, 25, 229, - 126, 10, 3, 233, 140, 203, 90, 25, 223, 173, 230, 122, 10, 3, 233, 140, - 203, 90, 25, 171, 10, 3, 233, 140, 203, 90, 25, 220, 13, 10, 3, 233, 140, - 203, 90, 25, 216, 213, 10, 3, 233, 140, 203, 90, 25, 216, 154, 10, 3, - 233, 140, 203, 90, 25, 200, 255, 10, 3, 233, 140, 25, 200, 255, 10, 3, - 231, 202, 25, 249, 71, 10, 3, 231, 202, 25, 236, 211, 230, 122, 10, 3, - 231, 202, 25, 235, 39, 25, 223, 173, 230, 122, 10, 3, 231, 202, 25, 235, - 39, 25, 222, 28, 10, 3, 231, 202, 25, 233, 245, 10, 3, 231, 202, 25, 231, - 203, 10, 3, 231, 202, 25, 231, 164, 107, 236, 255, 10, 3, 231, 202, 25, - 231, 164, 107, 214, 107, 10, 3, 231, 202, 25, 230, 72, 107, 65, 10, 3, - 231, 202, 25, 220, 167, 107, 222, 28, 10, 3, 231, 202, 25, 220, 11, 10, - 3, 231, 202, 25, 220, 12, 25, 220, 173, 10, 3, 231, 202, 25, 218, 191, - 10, 3, 231, 202, 25, 215, 87, 10, 3, 231, 202, 25, 214, 107, 10, 3, 231, - 202, 25, 214, 108, 107, 234, 174, 10, 3, 231, 202, 25, 214, 108, 107, - 231, 16, 10, 3, 231, 202, 25, 203, 68, 10, 3, 231, 202, 25, 191, 13, 10, - 3, 231, 197, 206, 117, 213, 157, 237, 79, 10, 3, 231, 98, 25, 69, 10, 3, - 230, 244, 25, 230, 244, 238, 163, 230, 243, 10, 3, 230, 145, 25, 223, - 173, 230, 122, 10, 3, 230, 136, 107, 230, 244, 25, 199, 204, 10, 3, 230, - 72, 199, 80, 230, 122, 10, 3, 229, 127, 25, 250, 160, 138, 229, 127, 25, - 250, 159, 10, 3, 222, 115, 25, 247, 218, 10, 3, 222, 115, 25, 157, 10, 3, - 222, 115, 25, 126, 126, 69, 10, 3, 222, 115, 25, 196, 58, 10, 3, 220, 81, - 25, 190, 252, 138, 190, 251, 10, 3, 220, 69, 10, 3, 220, 67, 10, 3, 220, - 66, 10, 3, 220, 65, 10, 3, 220, 64, 10, 3, 220, 63, 10, 3, 220, 62, 10, - 3, 220, 61, 138, 220, 61, 230, 122, 10, 3, 220, 60, 10, 3, 220, 59, 138, + 0, 201, 247, 233, 216, 77, 207, 252, 77, 31, 56, 236, 155, 56, 210, 13, + 56, 251, 137, 251, 49, 45, 210, 113, 50, 210, 113, 250, 193, 108, 56, + 242, 74, 228, 87, 232, 80, 201, 63, 202, 23, 17, 191, 77, 17, 107, 17, + 109, 17, 138, 17, 134, 17, 149, 17, 169, 17, 175, 17, 171, 17, 178, 242, + 83, 204, 25, 219, 180, 56, 234, 43, 56, 230, 204, 56, 208, 13, 77, 242, + 72, 250, 182, 8, 6, 1, 65, 8, 6, 1, 250, 120, 8, 6, 1, 247, 193, 8, 6, 1, + 238, 127, 8, 6, 1, 71, 8, 6, 1, 233, 175, 8, 6, 1, 232, 51, 8, 6, 1, 230, + 116, 8, 6, 1, 68, 8, 6, 1, 223, 35, 8, 6, 1, 222, 152, 8, 6, 1, 172, 8, + 6, 1, 218, 168, 8, 6, 1, 215, 61, 8, 6, 1, 74, 8, 6, 1, 210, 236, 8, 6, + 1, 208, 104, 8, 6, 1, 146, 8, 6, 1, 206, 8, 8, 6, 1, 200, 43, 8, 6, 1, + 66, 8, 6, 1, 196, 12, 8, 6, 1, 193, 224, 8, 6, 1, 192, 235, 8, 6, 1, 192, + 159, 8, 6, 1, 191, 166, 45, 51, 248, 53, 207, 19, 202, 23, 50, 51, 248, + 53, 243, 2, 252, 60, 130, 219, 112, 230, 211, 252, 60, 8, 2, 1, 65, 8, 2, + 1, 250, 120, 8, 2, 1, 247, 193, 8, 2, 1, 238, 127, 8, 2, 1, 71, 8, 2, 1, + 233, 175, 8, 2, 1, 232, 51, 8, 2, 1, 230, 116, 8, 2, 1, 68, 8, 2, 1, 223, + 35, 8, 2, 1, 222, 152, 8, 2, 1, 172, 8, 2, 1, 218, 168, 8, 2, 1, 215, 61, + 8, 2, 1, 74, 8, 2, 1, 210, 236, 8, 2, 1, 208, 104, 8, 2, 1, 146, 8, 2, 1, + 206, 8, 8, 2, 1, 200, 43, 8, 2, 1, 66, 8, 2, 1, 196, 12, 8, 2, 1, 193, + 224, 8, 2, 1, 192, 235, 8, 2, 1, 192, 159, 8, 2, 1, 191, 166, 45, 238, + 171, 248, 53, 81, 219, 112, 50, 238, 171, 248, 53, 198, 152, 213, 37, + 201, 247, 223, 93, 233, 216, 77, 247, 24, 56, 209, 8, 56, 238, 170, 56, + 192, 71, 56, 248, 22, 164, 205, 54, 56, 237, 42, 239, 6, 56, 233, 40, + 211, 50, 223, 144, 219, 219, 55, 251, 116, 207, 252, 77, 213, 12, 56, + 202, 32, 228, 88, 207, 78, 56, 217, 146, 237, 125, 56, 209, 80, 56, 200, + 182, 109, 200, 182, 138, 252, 47, 252, 60, 216, 91, 56, 209, 142, 56, 82, + 236, 140, 247, 35, 200, 182, 107, 217, 40, 211, 50, 223, 144, 206, 203, + 55, 251, 116, 207, 252, 77, 193, 246, 232, 118, 91, 208, 22, 193, 246, + 232, 118, 91, 230, 70, 193, 246, 232, 118, 115, 208, 20, 223, 93, 208, + 13, 77, 8, 6, 1, 42, 4, 230, 210, 8, 6, 1, 42, 4, 252, 46, 8, 6, 1, 42, + 4, 243, 1, 8, 6, 1, 42, 4, 198, 152, 8, 6, 1, 42, 4, 237, 42, 8, 6, 1, + 42, 4, 206, 189, 58, 8, 6, 1, 252, 25, 8, 6, 1, 247, 194, 4, 247, 35, 8, + 6, 1, 235, 15, 4, 230, 210, 8, 6, 1, 235, 15, 4, 252, 46, 8, 6, 1, 235, + 15, 4, 243, 1, 8, 6, 1, 235, 15, 4, 237, 42, 8, 6, 1, 228, 74, 4, 230, + 210, 8, 6, 1, 228, 74, 4, 252, 46, 8, 6, 1, 228, 74, 4, 243, 1, 8, 6, 1, + 228, 74, 4, 237, 42, 8, 6, 1, 233, 248, 8, 6, 1, 215, 62, 4, 198, 152, 8, + 6, 1, 187, 4, 230, 210, 8, 6, 1, 187, 4, 252, 46, 8, 6, 1, 187, 4, 243, + 1, 8, 6, 1, 187, 4, 198, 152, 8, 6, 1, 187, 4, 237, 42, 215, 127, 56, 8, + 6, 1, 187, 4, 106, 8, 6, 1, 126, 4, 230, 210, 8, 6, 1, 126, 4, 252, 46, + 8, 6, 1, 126, 4, 243, 1, 8, 6, 1, 126, 4, 237, 42, 8, 6, 1, 192, 160, 4, + 252, 46, 8, 6, 1, 198, 233, 8, 2, 1, 203, 127, 206, 8, 8, 2, 1, 42, 4, + 230, 210, 8, 2, 1, 42, 4, 252, 46, 8, 2, 1, 42, 4, 243, 1, 8, 2, 1, 42, + 4, 198, 152, 8, 2, 1, 42, 4, 237, 42, 8, 2, 1, 42, 4, 206, 189, 58, 8, 2, + 1, 252, 25, 8, 2, 1, 247, 194, 4, 247, 35, 8, 2, 1, 235, 15, 4, 230, 210, + 8, 2, 1, 235, 15, 4, 252, 46, 8, 2, 1, 235, 15, 4, 243, 1, 8, 2, 1, 235, + 15, 4, 237, 42, 8, 2, 1, 228, 74, 4, 230, 210, 8, 2, 1, 228, 74, 4, 252, + 46, 8, 2, 1, 228, 74, 4, 243, 1, 8, 2, 1, 228, 74, 4, 237, 42, 8, 2, 1, + 233, 248, 8, 2, 1, 215, 62, 4, 198, 152, 8, 2, 1, 187, 4, 230, 210, 8, 2, + 1, 187, 4, 252, 46, 8, 2, 1, 187, 4, 243, 1, 8, 2, 1, 187, 4, 198, 152, + 8, 2, 1, 187, 4, 237, 42, 236, 200, 56, 8, 2, 1, 187, 4, 106, 8, 2, 1, + 126, 4, 230, 210, 8, 2, 1, 126, 4, 252, 46, 8, 2, 1, 126, 4, 243, 1, 8, + 2, 1, 126, 4, 237, 42, 8, 2, 1, 192, 160, 4, 252, 46, 8, 2, 1, 198, 233, + 8, 2, 1, 192, 160, 4, 237, 42, 8, 6, 1, 42, 4, 217, 146, 8, 2, 1, 42, 4, + 217, 146, 8, 6, 1, 42, 4, 248, 36, 8, 2, 1, 42, 4, 248, 36, 8, 6, 1, 42, + 4, 211, 138, 8, 2, 1, 42, 4, 211, 138, 8, 6, 1, 247, 194, 4, 252, 46, 8, + 2, 1, 247, 194, 4, 252, 46, 8, 6, 1, 247, 194, 4, 243, 1, 8, 2, 1, 247, + 194, 4, 243, 1, 8, 6, 1, 247, 194, 4, 75, 58, 8, 2, 1, 247, 194, 4, 75, + 58, 8, 6, 1, 247, 194, 4, 247, 92, 8, 2, 1, 247, 194, 4, 247, 92, 8, 6, + 1, 238, 128, 4, 247, 92, 8, 2, 1, 238, 128, 4, 247, 92, 8, 6, 1, 238, + 128, 4, 106, 8, 2, 1, 238, 128, 4, 106, 8, 6, 1, 235, 15, 4, 217, 146, 8, + 2, 1, 235, 15, 4, 217, 146, 8, 6, 1, 235, 15, 4, 248, 36, 8, 2, 1, 235, + 15, 4, 248, 36, 8, 6, 1, 235, 15, 4, 75, 58, 8, 2, 1, 235, 15, 4, 75, 58, + 8, 6, 1, 235, 15, 4, 211, 138, 8, 2, 1, 235, 15, 4, 211, 138, 8, 6, 1, + 235, 15, 4, 247, 92, 8, 2, 1, 235, 15, 4, 247, 92, 8, 6, 1, 232, 52, 4, + 243, 1, 8, 2, 1, 232, 52, 4, 243, 1, 8, 6, 1, 232, 52, 4, 248, 36, 8, 2, + 1, 232, 52, 4, 248, 36, 8, 6, 1, 232, 52, 4, 75, 58, 8, 2, 1, 232, 52, 4, + 75, 58, 8, 6, 1, 232, 52, 4, 247, 35, 8, 2, 1, 232, 52, 4, 247, 35, 8, 6, + 1, 230, 117, 4, 243, 1, 8, 2, 1, 230, 117, 4, 243, 1, 8, 6, 1, 230, 117, + 4, 106, 8, 2, 1, 230, 117, 4, 106, 8, 6, 1, 228, 74, 4, 198, 152, 8, 2, + 1, 228, 74, 4, 198, 152, 8, 6, 1, 228, 74, 4, 217, 146, 8, 2, 1, 228, 74, + 4, 217, 146, 8, 6, 1, 228, 74, 4, 248, 36, 8, 2, 1, 228, 74, 4, 248, 36, + 8, 6, 1, 228, 74, 4, 211, 138, 8, 2, 1, 228, 74, 4, 211, 138, 8, 6, 1, + 228, 74, 4, 75, 58, 8, 2, 1, 236, 139, 68, 8, 6, 34, 223, 197, 8, 2, 34, + 223, 197, 8, 6, 1, 223, 36, 4, 243, 1, 8, 2, 1, 223, 36, 4, 243, 1, 8, 6, + 1, 222, 153, 4, 247, 35, 8, 2, 1, 222, 153, 4, 247, 35, 8, 2, 1, 221, 8, + 8, 6, 1, 220, 143, 4, 252, 46, 8, 2, 1, 220, 143, 4, 252, 46, 8, 6, 1, + 220, 143, 4, 247, 35, 8, 2, 1, 220, 143, 4, 247, 35, 8, 6, 1, 220, 143, + 4, 247, 92, 8, 2, 1, 220, 143, 4, 247, 92, 8, 6, 1, 220, 143, 4, 82, 236, + 140, 8, 2, 1, 220, 143, 4, 82, 236, 140, 8, 6, 1, 220, 143, 4, 106, 8, 2, + 1, 220, 143, 4, 106, 8, 6, 1, 215, 62, 4, 252, 46, 8, 2, 1, 215, 62, 4, + 252, 46, 8, 6, 1, 215, 62, 4, 247, 35, 8, 2, 1, 215, 62, 4, 247, 35, 8, + 6, 1, 215, 62, 4, 247, 92, 8, 2, 1, 215, 62, 4, 247, 92, 8, 2, 1, 215, + 62, 208, 233, 247, 205, 251, 49, 8, 6, 1, 234, 88, 8, 2, 1, 234, 88, 8, + 6, 1, 187, 4, 217, 146, 8, 2, 1, 187, 4, 217, 146, 8, 6, 1, 187, 4, 248, + 36, 8, 2, 1, 187, 4, 248, 36, 8, 6, 1, 187, 4, 55, 252, 46, 8, 2, 1, 187, + 4, 55, 252, 46, 8, 6, 34, 211, 151, 8, 2, 34, 211, 151, 8, 6, 1, 207, + 222, 4, 252, 46, 8, 2, 1, 207, 222, 4, 252, 46, 8, 6, 1, 207, 222, 4, + 247, 35, 8, 2, 1, 207, 222, 4, 247, 35, 8, 6, 1, 207, 222, 4, 247, 92, 8, + 2, 1, 207, 222, 4, 247, 92, 8, 6, 1, 206, 9, 4, 252, 46, 8, 2, 1, 206, 9, + 4, 252, 46, 8, 6, 1, 206, 9, 4, 243, 1, 8, 2, 1, 206, 9, 4, 243, 1, 8, 6, + 1, 206, 9, 4, 247, 35, 8, 2, 1, 206, 9, 4, 247, 35, 8, 6, 1, 206, 9, 4, + 247, 92, 8, 2, 1, 206, 9, 4, 247, 92, 8, 6, 1, 200, 44, 4, 247, 35, 8, 2, + 1, 200, 44, 4, 247, 35, 8, 6, 1, 200, 44, 4, 247, 92, 8, 2, 1, 200, 44, + 4, 247, 92, 8, 6, 1, 200, 44, 4, 106, 8, 2, 1, 200, 44, 4, 106, 8, 6, 1, + 126, 4, 198, 152, 8, 2, 1, 126, 4, 198, 152, 8, 6, 1, 126, 4, 217, 146, + 8, 2, 1, 126, 4, 217, 146, 8, 6, 1, 126, 4, 248, 36, 8, 2, 1, 126, 4, + 248, 36, 8, 6, 1, 126, 4, 206, 189, 58, 8, 2, 1, 126, 4, 206, 189, 58, 8, + 6, 1, 126, 4, 55, 252, 46, 8, 2, 1, 126, 4, 55, 252, 46, 8, 6, 1, 126, 4, + 211, 138, 8, 2, 1, 126, 4, 211, 138, 8, 6, 1, 193, 225, 4, 243, 1, 8, 2, + 1, 193, 225, 4, 243, 1, 8, 6, 1, 192, 160, 4, 243, 1, 8, 2, 1, 192, 160, + 4, 243, 1, 8, 6, 1, 192, 160, 4, 237, 42, 8, 6, 1, 191, 167, 4, 252, 46, + 8, 2, 1, 191, 167, 4, 252, 46, 8, 6, 1, 191, 167, 4, 75, 58, 8, 2, 1, + 191, 167, 4, 75, 58, 8, 6, 1, 191, 167, 4, 247, 92, 8, 2, 1, 191, 167, 4, + 247, 92, 8, 2, 1, 179, 206, 8, 8, 2, 1, 78, 4, 106, 8, 6, 1, 78, 4, 102, + 8, 6, 1, 78, 4, 198, 51, 8, 2, 1, 78, 4, 198, 51, 8, 6, 1, 163, 169, 8, + 2, 1, 163, 169, 8, 6, 1, 211, 77, 74, 8, 6, 1, 247, 194, 4, 102, 8, 2, 1, + 247, 194, 4, 102, 8, 6, 1, 252, 0, 238, 127, 8, 6, 1, 238, 128, 4, 102, + 8, 6, 1, 238, 128, 4, 198, 51, 8, 2, 1, 238, 128, 4, 198, 51, 8, 2, 1, + 153, 237, 106, 8, 6, 1, 207, 18, 71, 8, 6, 1, 205, 86, 8, 6, 1, 211, 77, + 71, 8, 6, 1, 233, 176, 4, 102, 8, 2, 1, 233, 176, 4, 102, 8, 6, 1, 232, + 52, 4, 102, 8, 6, 1, 231, 211, 8, 2, 1, 228, 126, 8, 6, 1, 223, 83, 8, 6, + 1, 228, 74, 4, 106, 8, 6, 1, 222, 153, 4, 102, 8, 2, 1, 222, 153, 4, 102, + 8, 2, 1, 220, 143, 4, 164, 8, 2, 1, 220, 33, 4, 106, 8, 6, 1, 153, 218, + 168, 8, 6, 1, 215, 62, 4, 45, 102, 8, 2, 1, 215, 62, 4, 179, 50, 219, + 212, 8, 6, 1, 187, 4, 82, 198, 152, 8, 6, 1, 187, 4, 228, 187, 8, 2, 1, + 187, 4, 228, 187, 8, 6, 1, 211, 133, 8, 2, 1, 211, 133, 8, 6, 1, 210, + 237, 4, 102, 8, 2, 1, 210, 237, 4, 102, 8, 1, 191, 228, 8, 6, 1, 163, + 109, 8, 2, 1, 163, 109, 8, 6, 1, 234, 12, 8, 1, 207, 18, 234, 13, 219, 4, + 8, 2, 1, 200, 44, 4, 210, 192, 102, 8, 6, 1, 200, 44, 4, 102, 8, 2, 1, + 200, 44, 4, 102, 8, 6, 1, 200, 44, 4, 207, 24, 102, 8, 6, 1, 126, 4, 228, + 187, 8, 2, 1, 126, 4, 228, 187, 8, 6, 1, 196, 70, 8, 6, 1, 196, 13, 4, + 102, 8, 6, 1, 192, 160, 4, 102, 8, 2, 1, 192, 160, 4, 102, 8, 6, 1, 191, + 167, 4, 106, 8, 2, 1, 191, 167, 4, 106, 8, 6, 1, 233, 178, 8, 6, 1, 233, + 179, 207, 17, 8, 2, 1, 233, 179, 207, 17, 8, 2, 1, 233, 179, 4, 199, 215, + 8, 1, 105, 4, 106, 8, 6, 1, 163, 149, 8, 2, 1, 163, 149, 8, 1, 223, 93, + 231, 11, 201, 64, 4, 106, 8, 1, 192, 238, 8, 1, 237, 98, 242, 231, 8, 1, + 220, 3, 242, 231, 8, 1, 251, 150, 242, 231, 8, 1, 207, 24, 242, 231, 8, + 6, 1, 235, 37, 4, 247, 92, 8, 6, 1, 238, 128, 4, 2, 1, 191, 167, 4, 247, + 92, 8, 2, 1, 235, 37, 4, 247, 92, 8, 6, 1, 219, 77, 8, 6, 1, 220, 143, 4, + 2, 1, 223, 35, 8, 2, 1, 219, 77, 8, 6, 1, 213, 158, 8, 6, 1, 215, 62, 4, + 2, 1, 223, 35, 8, 2, 1, 213, 158, 8, 6, 1, 42, 4, 247, 92, 8, 2, 1, 42, + 4, 247, 92, 8, 6, 1, 228, 74, 4, 247, 92, 8, 2, 1, 228, 74, 4, 247, 92, + 8, 6, 1, 187, 4, 247, 92, 8, 2, 1, 187, 4, 247, 92, 8, 6, 1, 126, 4, 247, + 92, 8, 2, 1, 126, 4, 247, 92, 8, 6, 1, 126, 4, 237, 43, 23, 217, 146, 8, + 2, 1, 126, 4, 237, 43, 23, 217, 146, 8, 6, 1, 126, 4, 237, 43, 23, 252, + 46, 8, 2, 1, 126, 4, 237, 43, 23, 252, 46, 8, 6, 1, 126, 4, 237, 43, 23, + 247, 92, 8, 2, 1, 126, 4, 237, 43, 23, 247, 92, 8, 6, 1, 126, 4, 237, 43, + 23, 230, 210, 8, 2, 1, 126, 4, 237, 43, 23, 230, 210, 8, 2, 1, 153, 71, + 8, 6, 1, 42, 4, 237, 43, 23, 217, 146, 8, 2, 1, 42, 4, 237, 43, 23, 217, + 146, 8, 6, 1, 42, 4, 75, 93, 23, 217, 146, 8, 2, 1, 42, 4, 75, 93, 23, + 217, 146, 8, 6, 1, 252, 26, 4, 217, 146, 8, 2, 1, 252, 26, 4, 217, 146, + 8, 6, 1, 232, 52, 4, 106, 8, 2, 1, 232, 52, 4, 106, 8, 6, 1, 232, 52, 4, + 247, 92, 8, 2, 1, 232, 52, 4, 247, 92, 8, 6, 1, 222, 153, 4, 247, 92, 8, + 2, 1, 222, 153, 4, 247, 92, 8, 6, 1, 187, 4, 211, 138, 8, 2, 1, 187, 4, + 211, 138, 8, 6, 1, 187, 4, 211, 139, 23, 217, 146, 8, 2, 1, 187, 4, 211, + 139, 23, 217, 146, 8, 6, 1, 233, 179, 4, 247, 92, 8, 2, 1, 233, 179, 4, + 247, 92, 8, 2, 1, 223, 36, 4, 247, 92, 8, 6, 1, 235, 36, 8, 6, 1, 238, + 128, 4, 2, 1, 191, 166, 8, 2, 1, 235, 36, 8, 6, 1, 232, 52, 4, 252, 46, + 8, 2, 1, 232, 52, 4, 252, 46, 8, 6, 1, 228, 123, 8, 6, 1, 192, 238, 8, 6, + 1, 215, 62, 4, 230, 210, 8, 2, 1, 215, 62, 4, 230, 210, 8, 6, 1, 42, 4, + 206, 189, 93, 23, 252, 46, 8, 2, 1, 42, 4, 206, 189, 93, 23, 252, 46, 8, + 6, 1, 252, 26, 4, 252, 46, 8, 2, 1, 252, 26, 4, 252, 46, 8, 6, 1, 187, 4, + 201, 28, 23, 252, 46, 8, 2, 1, 187, 4, 201, 28, 23, 252, 46, 8, 6, 1, 42, + 4, 55, 230, 210, 8, 2, 1, 42, 4, 55, 230, 210, 8, 6, 1, 42, 4, 223, 93, + 248, 36, 8, 2, 1, 42, 4, 223, 93, 248, 36, 8, 6, 1, 235, 15, 4, 55, 230, + 210, 8, 2, 1, 235, 15, 4, 55, 230, 210, 8, 6, 1, 235, 15, 4, 223, 93, + 248, 36, 8, 2, 1, 235, 15, 4, 223, 93, 248, 36, 8, 6, 1, 228, 74, 4, 55, + 230, 210, 8, 2, 1, 228, 74, 4, 55, 230, 210, 8, 6, 1, 228, 74, 4, 223, + 93, 248, 36, 8, 2, 1, 228, 74, 4, 223, 93, 248, 36, 8, 6, 1, 187, 4, 55, + 230, 210, 8, 2, 1, 187, 4, 55, 230, 210, 8, 6, 1, 187, 4, 223, 93, 248, + 36, 8, 2, 1, 187, 4, 223, 93, 248, 36, 8, 6, 1, 207, 222, 4, 55, 230, + 210, 8, 2, 1, 207, 222, 4, 55, 230, 210, 8, 6, 1, 207, 222, 4, 223, 93, + 248, 36, 8, 2, 1, 207, 222, 4, 223, 93, 248, 36, 8, 6, 1, 126, 4, 55, + 230, 210, 8, 2, 1, 126, 4, 55, 230, 210, 8, 6, 1, 126, 4, 223, 93, 248, + 36, 8, 2, 1, 126, 4, 223, 93, 248, 36, 8, 6, 1, 206, 9, 4, 242, 75, 60, + 8, 2, 1, 206, 9, 4, 242, 75, 60, 8, 6, 1, 200, 44, 4, 242, 75, 60, 8, 2, + 1, 200, 44, 4, 242, 75, 60, 8, 6, 1, 191, 248, 8, 2, 1, 191, 248, 8, 6, + 1, 230, 117, 4, 247, 92, 8, 2, 1, 230, 117, 4, 247, 92, 8, 6, 1, 215, 62, + 4, 179, 50, 219, 212, 8, 2, 1, 238, 128, 4, 238, 175, 8, 6, 1, 211, 19, + 8, 2, 1, 211, 19, 8, 6, 1, 191, 167, 4, 102, 8, 2, 1, 191, 167, 4, 102, + 8, 6, 1, 42, 4, 75, 58, 8, 2, 1, 42, 4, 75, 58, 8, 6, 1, 235, 15, 4, 247, + 35, 8, 2, 1, 235, 15, 4, 247, 35, 8, 6, 1, 187, 4, 237, 43, 23, 217, 146, + 8, 2, 1, 187, 4, 237, 43, 23, 217, 146, 8, 6, 1, 187, 4, 198, 153, 23, + 217, 146, 8, 2, 1, 187, 4, 198, 153, 23, 217, 146, 8, 6, 1, 187, 4, 75, + 58, 8, 2, 1, 187, 4, 75, 58, 8, 6, 1, 187, 4, 75, 93, 23, 217, 146, 8, 2, + 1, 187, 4, 75, 93, 23, 217, 146, 8, 6, 1, 192, 160, 4, 217, 146, 8, 2, 1, + 192, 160, 4, 217, 146, 8, 2, 1, 220, 143, 4, 238, 175, 8, 2, 1, 215, 62, + 4, 238, 175, 8, 2, 1, 200, 44, 4, 238, 175, 8, 2, 1, 236, 139, 223, 35, + 8, 2, 1, 237, 201, 237, 2, 8, 2, 1, 208, 34, 237, 2, 8, 6, 1, 42, 4, 106, + 8, 6, 1, 247, 194, 4, 106, 8, 2, 1, 247, 194, 4, 106, 8, 6, 1, 220, 143, + 4, 164, 8, 6, 1, 200, 44, 4, 237, 39, 106, 8, 2, 1, 206, 9, 4, 200, 146, + 199, 215, 8, 2, 1, 191, 167, 4, 200, 146, 199, 215, 8, 6, 1, 231, 11, + 201, 63, 8, 2, 1, 231, 11, 201, 63, 8, 6, 1, 78, 4, 106, 8, 6, 1, 126, + 164, 8, 6, 1, 153, 196, 12, 8, 6, 1, 235, 15, 4, 106, 8, 2, 1, 235, 15, + 4, 106, 8, 6, 1, 223, 36, 4, 106, 8, 2, 1, 223, 36, 4, 106, 8, 6, 1, 2, + 208, 105, 4, 228, 251, 199, 215, 8, 2, 1, 208, 105, 4, 228, 251, 199, + 215, 8, 6, 1, 207, 222, 4, 106, 8, 2, 1, 207, 222, 4, 106, 8, 6, 1, 192, + 160, 4, 106, 8, 2, 1, 192, 160, 4, 106, 8, 2, 1, 153, 65, 8, 2, 1, 251, + 160, 8, 2, 1, 153, 251, 160, 8, 2, 1, 78, 4, 102, 8, 2, 1, 211, 77, 74, + 8, 2, 1, 247, 194, 4, 238, 175, 8, 2, 1, 238, 128, 4, 199, 215, 8, 2, 1, + 238, 128, 4, 102, 8, 2, 1, 207, 18, 71, 8, 2, 1, 205, 86, 8, 2, 1, 205, + 87, 4, 102, 8, 2, 1, 211, 77, 71, 8, 2, 1, 207, 18, 211, 77, 71, 8, 2, 1, + 207, 18, 211, 77, 235, 15, 4, 102, 8, 2, 1, 242, 219, 207, 18, 211, 77, + 71, 8, 2, 1, 236, 139, 223, 36, 4, 106, 8, 2, 1, 232, 52, 4, 102, 8, 2, + 1, 27, 232, 51, 8, 1, 2, 6, 232, 51, 8, 2, 1, 231, 211, 8, 2, 1, 207, + 140, 228, 187, 8, 2, 1, 153, 230, 116, 8, 2, 1, 230, 117, 4, 102, 8, 2, + 1, 229, 197, 4, 102, 8, 2, 1, 228, 74, 4, 106, 8, 2, 1, 223, 83, 8, 1, 2, + 6, 68, 8, 2, 1, 220, 143, 4, 82, 198, 152, 8, 2, 1, 220, 143, 4, 248, + 231, 8, 2, 1, 220, 143, 4, 207, 24, 102, 8, 2, 1, 219, 162, 8, 2, 1, 153, + 218, 168, 8, 2, 1, 153, 218, 169, 4, 179, 219, 212, 8, 2, 1, 218, 169, 4, + 102, 8, 2, 1, 215, 62, 4, 45, 102, 8, 2, 1, 215, 62, 4, 207, 24, 102, 8, + 1, 2, 6, 215, 61, 8, 2, 1, 249, 82, 74, 8, 1, 2, 6, 211, 151, 8, 2, 1, + 242, 219, 211, 110, 8, 2, 1, 209, 211, 8, 2, 1, 153, 146, 8, 2, 1, 153, + 207, 222, 4, 179, 219, 212, 8, 2, 1, 153, 207, 222, 4, 102, 8, 2, 1, 207, + 222, 4, 179, 219, 212, 8, 2, 1, 207, 222, 4, 199, 215, 8, 2, 1, 207, 222, + 4, 232, 233, 8, 2, 1, 207, 18, 207, 222, 4, 232, 233, 8, 1, 2, 6, 146, 8, + 1, 2, 6, 223, 93, 146, 8, 2, 1, 206, 9, 4, 102, 8, 2, 1, 234, 12, 8, 2, + 1, 236, 139, 223, 36, 4, 201, 28, 23, 102, 8, 2, 1, 201, 187, 207, 18, + 234, 12, 8, 2, 1, 234, 13, 4, 238, 175, 8, 2, 1, 153, 200, 43, 8, 2, 1, + 200, 44, 4, 207, 24, 102, 8, 2, 1, 126, 164, 8, 2, 1, 196, 70, 8, 2, 1, + 196, 13, 4, 102, 8, 2, 1, 153, 196, 12, 8, 2, 1, 153, 193, 224, 8, 2, 1, + 153, 192, 159, 8, 1, 2, 6, 192, 159, 8, 2, 1, 191, 167, 4, 207, 24, 102, + 8, 2, 1, 191, 167, 4, 238, 175, 8, 2, 1, 233, 178, 8, 2, 1, 233, 179, 4, + 238, 175, 8, 1, 231, 11, 201, 63, 8, 1, 209, 219, 195, 20, 232, 104, 8, + 1, 223, 93, 231, 11, 201, 63, 8, 1, 201, 36, 247, 193, 8, 1, 248, 172, + 242, 231, 8, 1, 2, 6, 250, 120, 8, 2, 1, 242, 219, 211, 77, 71, 8, 1, 2, + 6, 232, 52, 4, 102, 8, 1, 2, 6, 230, 116, 8, 2, 1, 223, 36, 4, 238, 212, + 8, 2, 1, 153, 222, 152, 8, 1, 2, 6, 172, 8, 2, 1, 208, 105, 4, 102, 8, 1, + 231, 11, 201, 64, 4, 106, 8, 1, 207, 18, 231, 11, 201, 64, 4, 106, 8, 2, + 1, 235, 37, 237, 2, 8, 2, 1, 237, 70, 237, 2, 8, 2, 1, 235, 37, 237, 3, + 4, 238, 175, 8, 2, 1, 197, 170, 237, 2, 8, 2, 1, 199, 79, 237, 2, 8, 2, + 1, 199, 152, 237, 3, 4, 238, 175, 8, 2, 1, 233, 37, 237, 2, 8, 2, 1, 218, + 227, 237, 2, 8, 2, 1, 218, 170, 237, 2, 8, 1, 248, 172, 210, 12, 8, 1, + 248, 180, 210, 12, 8, 2, 1, 153, 230, 117, 4, 232, 233, 8, 2, 1, 153, + 230, 117, 4, 232, 234, 23, 199, 215, 52, 1, 2, 230, 116, 52, 1, 2, 230, + 117, 4, 102, 52, 1, 2, 223, 35, 52, 1, 2, 146, 52, 1, 2, 153, 146, 52, 1, + 2, 153, 207, 222, 4, 102, 52, 1, 2, 6, 223, 93, 146, 52, 1, 2, 193, 224, + 52, 1, 2, 192, 159, 52, 1, 208, 215, 52, 1, 55, 208, 215, 52, 1, 153, + 242, 74, 52, 1, 251, 49, 52, 1, 207, 18, 242, 74, 52, 1, 50, 132, 206, + 188, 52, 1, 45, 132, 206, 188, 52, 1, 231, 11, 201, 63, 52, 1, 207, 18, + 231, 11, 201, 63, 52, 1, 45, 250, 235, 52, 1, 50, 250, 235, 52, 1, 133, + 250, 235, 52, 1, 144, 250, 235, 52, 1, 243, 2, 252, 60, 247, 92, 52, 1, + 81, 219, 112, 52, 1, 217, 146, 52, 1, 252, 47, 252, 60, 52, 1, 230, 211, + 252, 60, 52, 1, 130, 81, 219, 112, 52, 1, 130, 217, 146, 52, 1, 130, 230, + 211, 252, 60, 52, 1, 130, 252, 47, 252, 60, 52, 1, 197, 238, 242, 83, 52, + 1, 132, 197, 238, 242, 83, 52, 1, 247, 20, 50, 132, 206, 188, 52, 1, 247, + 20, 45, 132, 206, 188, 52, 1, 133, 199, 228, 52, 1, 144, 199, 228, 52, 1, + 108, 56, 52, 1, 216, 35, 56, 248, 36, 75, 58, 206, 189, 58, 211, 138, 2, + 198, 152, 55, 252, 47, 252, 60, 52, 1, 207, 2, 102, 52, 1, 238, 218, 252, + 60, 52, 1, 2, 231, 211, 52, 1, 2, 172, 52, 1, 2, 206, 8, 52, 1, 2, 192, + 235, 52, 1, 2, 207, 18, 231, 11, 201, 63, 52, 1, 233, 200, 163, 164, 52, + 1, 137, 163, 164, 52, 1, 216, 87, 163, 164, 52, 1, 130, 163, 164, 52, 1, + 233, 199, 163, 164, 52, 1, 192, 22, 237, 95, 163, 77, 52, 1, 192, 107, + 237, 95, 163, 77, 52, 1, 195, 18, 52, 1, 196, 109, 52, 1, 55, 251, 49, + 52, 1, 130, 144, 250, 235, 52, 1, 130, 133, 250, 235, 52, 1, 130, 45, + 250, 235, 52, 1, 130, 50, 250, 235, 52, 1, 130, 206, 188, 52, 1, 82, 230, + 211, 252, 60, 52, 1, 82, 55, 230, 211, 252, 60, 52, 1, 82, 55, 252, 47, + 252, 60, 52, 1, 130, 198, 152, 52, 1, 207, 147, 242, 83, 52, 1, 248, 249, + 137, 198, 79, 52, 1, 234, 95, 137, 198, 79, 52, 1, 248, 249, 130, 198, + 79, 52, 1, 234, 95, 130, 198, 79, 52, 1, 203, 104, 52, 1, 211, 77, 203, + 104, 52, 1, 130, 45, 57, 33, 230, 211, 252, 60, 33, 252, 47, 252, 60, 33, + 243, 2, 252, 60, 33, 198, 152, 33, 217, 146, 33, 210, 254, 33, 248, 36, + 33, 75, 58, 33, 237, 42, 33, 228, 251, 58, 33, 206, 189, 58, 33, 55, 252, + 47, 252, 60, 33, 247, 92, 33, 81, 219, 113, 58, 33, 55, 81, 219, 113, 58, + 33, 55, 230, 211, 252, 60, 33, 247, 119, 33, 223, 93, 248, 36, 33, 153, + 242, 75, 58, 33, 242, 75, 58, 33, 207, 18, 242, 75, 58, 33, 242, 75, 93, + 183, 33, 230, 211, 252, 61, 60, 33, 252, 47, 252, 61, 60, 33, 45, 199, + 229, 60, 33, 50, 199, 229, 60, 33, 45, 251, 116, 58, 33, 228, 187, 33, + 45, 132, 206, 189, 60, 33, 133, 199, 229, 60, 33, 144, 199, 229, 60, 33, + 108, 3, 60, 33, 216, 35, 3, 60, 33, 210, 190, 228, 251, 60, 33, 207, 24, + 228, 251, 60, 33, 75, 60, 33, 237, 43, 60, 33, 206, 189, 60, 33, 242, 75, + 60, 33, 247, 35, 33, 211, 138, 33, 81, 219, 113, 60, 33, 248, 29, 60, 33, + 223, 93, 55, 251, 15, 60, 33, 247, 93, 60, 33, 243, 2, 252, 61, 60, 33, + 248, 37, 60, 33, 223, 93, 248, 37, 60, 33, 198, 153, 60, 33, 217, 147, + 60, 33, 130, 219, 112, 33, 55, 130, 219, 112, 33, 198, 153, 210, 255, 33, + 203, 40, 201, 28, 210, 255, 33, 179, 201, 28, 210, 255, 33, 203, 40, 202, + 24, 210, 255, 33, 179, 202, 24, 210, 255, 33, 50, 132, 206, 189, 60, 33, + 223, 93, 248, 29, 60, 33, 51, 60, 33, 205, 62, 60, 33, 192, 236, 58, 33, + 81, 198, 152, 33, 55, 210, 254, 33, 230, 211, 163, 77, 33, 252, 47, 163, + 77, 33, 35, 210, 4, 33, 35, 221, 30, 33, 35, 237, 36, 198, 60, 33, 35, + 191, 233, 33, 248, 29, 58, 33, 234, 43, 3, 60, 33, 55, 81, 219, 113, 60, + 33, 45, 251, 116, 60, 33, 213, 12, 198, 153, 58, 33, 229, 1, 58, 33, 251, + 165, 234, 45, 119, 58, 33, 45, 50, 64, 60, 33, 196, 66, 64, 60, 33, 230, + 217, 222, 196, 33, 50, 250, 236, 58, 33, 45, 132, 206, 189, 58, 33, 233, + 34, 33, 192, 236, 60, 33, 45, 250, 236, 60, 33, 50, 250, 236, 60, 33, 50, + 250, 236, 23, 133, 250, 236, 60, 33, 50, 132, 206, 189, 58, 33, 75, 93, + 183, 33, 250, 194, 60, 33, 55, 206, 189, 60, 33, 191, 21, 58, 33, 55, + 248, 37, 60, 33, 55, 248, 36, 33, 55, 217, 146, 33, 55, 217, 147, 60, 33, + 55, 198, 152, 33, 55, 223, 93, 248, 36, 33, 55, 96, 64, 60, 33, 8, 2, 1, + 65, 33, 8, 2, 1, 71, 33, 8, 2, 1, 68, 33, 8, 2, 1, 74, 33, 8, 2, 1, 66, + 33, 8, 2, 1, 247, 193, 33, 8, 2, 1, 238, 127, 33, 8, 2, 1, 230, 116, 33, + 8, 2, 1, 218, 168, 33, 8, 2, 1, 146, 33, 8, 2, 1, 200, 43, 33, 8, 2, 1, + 196, 12, 33, 8, 2, 1, 192, 235, 35, 6, 1, 229, 185, 35, 2, 1, 229, 185, + 35, 6, 1, 251, 14, 205, 145, 35, 2, 1, 251, 14, 205, 145, 35, 212, 134, + 56, 35, 110, 212, 134, 56, 35, 6, 1, 210, 171, 237, 10, 35, 2, 1, 210, + 171, 237, 10, 35, 191, 233, 35, 2, 207, 18, 218, 206, 202, 197, 113, 35, + 2, 235, 138, 218, 206, 202, 197, 113, 35, 2, 207, 18, 235, 138, 218, 206, + 202, 197, 113, 35, 208, 13, 77, 35, 6, 1, 191, 240, 35, 198, 60, 35, 237, + 36, 198, 60, 35, 6, 1, 251, 161, 4, 198, 60, 35, 251, 94, 199, 108, 35, + 6, 1, 234, 48, 4, 198, 60, 35, 6, 1, 233, 254, 4, 198, 60, 35, 6, 1, 223, + 84, 4, 198, 60, 35, 6, 1, 211, 108, 4, 198, 60, 35, 6, 1, 196, 71, 4, + 198, 60, 35, 6, 1, 211, 111, 4, 198, 60, 35, 2, 1, 223, 84, 4, 237, 36, + 23, 198, 60, 35, 6, 1, 251, 160, 35, 6, 1, 248, 212, 35, 6, 1, 231, 211, + 35, 6, 1, 237, 106, 35, 6, 1, 234, 47, 35, 6, 1, 191, 76, 35, 6, 1, 233, + 253, 35, 6, 1, 199, 15, 35, 6, 1, 223, 83, 35, 6, 1, 222, 72, 35, 6, 1, + 220, 31, 35, 6, 1, 215, 155, 35, 6, 1, 212, 178, 35, 6, 1, 192, 207, 35, + 6, 1, 211, 107, 35, 6, 1, 209, 185, 35, 6, 1, 207, 3, 35, 6, 1, 202, 196, + 35, 6, 1, 199, 166, 35, 6, 1, 196, 70, 35, 6, 1, 209, 211, 35, 6, 1, 243, + 95, 35, 6, 1, 208, 176, 35, 6, 1, 211, 110, 35, 6, 1, 223, 84, 4, 237, + 35, 35, 6, 1, 196, 71, 4, 237, 35, 35, 2, 1, 251, 161, 4, 198, 60, 35, 2, + 1, 234, 48, 4, 198, 60, 35, 2, 1, 233, 254, 4, 198, 60, 35, 2, 1, 223, + 84, 4, 198, 60, 35, 2, 1, 196, 71, 4, 237, 36, 23, 198, 60, 35, 2, 1, + 251, 160, 35, 2, 1, 248, 212, 35, 2, 1, 231, 211, 35, 2, 1, 237, 106, 35, + 2, 1, 234, 47, 35, 2, 1, 191, 76, 35, 2, 1, 233, 253, 35, 2, 1, 199, 15, + 35, 2, 1, 223, 83, 35, 2, 1, 222, 72, 35, 2, 1, 220, 31, 35, 2, 1, 215, + 155, 35, 2, 1, 212, 178, 35, 2, 1, 192, 207, 35, 2, 1, 211, 107, 35, 2, + 1, 209, 185, 35, 2, 1, 207, 3, 35, 2, 1, 53, 202, 196, 35, 2, 1, 202, + 196, 35, 2, 1, 199, 166, 35, 2, 1, 196, 70, 35, 2, 1, 209, 211, 35, 2, 1, + 243, 95, 35, 2, 1, 208, 176, 35, 2, 1, 211, 110, 35, 2, 1, 223, 84, 4, + 237, 35, 35, 2, 1, 196, 71, 4, 237, 35, 35, 2, 1, 211, 108, 4, 198, 60, + 35, 2, 1, 196, 71, 4, 198, 60, 35, 2, 1, 211, 111, 4, 198, 60, 35, 6, + 222, 103, 113, 35, 248, 213, 113, 35, 199, 16, 113, 35, 196, 71, 4, 228, + 251, 113, 35, 196, 71, 4, 252, 47, 23, 228, 251, 113, 35, 196, 71, 4, + 237, 43, 23, 228, 251, 113, 35, 209, 212, 113, 35, 209, 186, 113, 35, + 222, 103, 113, 35, 1, 251, 14, 221, 35, 35, 2, 1, 251, 14, 221, 35, 35, + 1, 201, 73, 35, 2, 1, 201, 73, 35, 1, 237, 10, 35, 2, 1, 237, 10, 35, 1, + 221, 35, 35, 2, 1, 221, 35, 35, 1, 205, 145, 35, 2, 1, 205, 145, 94, 6, + 1, 203, 105, 94, 2, 1, 203, 105, 94, 6, 1, 233, 44, 94, 2, 1, 233, 44, + 94, 6, 1, 221, 195, 94, 2, 1, 221, 195, 94, 6, 1, 228, 242, 94, 2, 1, + 228, 242, 94, 6, 1, 231, 206, 94, 2, 1, 231, 206, 94, 6, 1, 203, 71, 94, + 2, 1, 203, 71, 94, 6, 1, 237, 122, 94, 2, 1, 237, 122, 35, 222, 73, 113, + 35, 207, 4, 113, 35, 218, 206, 202, 197, 113, 35, 1, 191, 240, 35, 6, + 199, 16, 113, 35, 218, 206, 234, 48, 113, 35, 207, 18, 218, 206, 234, 48, + 113, 35, 6, 1, 203, 56, 35, 2, 1, 203, 56, 35, 6, 218, 206, 202, 197, + 113, 35, 6, 1, 205, 142, 35, 2, 1, 205, 142, 35, 207, 4, 4, 201, 28, 113, + 35, 6, 207, 18, 218, 206, 202, 197, 113, 35, 6, 235, 138, 218, 206, 202, + 197, 113, 35, 6, 207, 18, 235, 138, 218, 206, 202, 197, 113, 38, 6, 1, + 223, 227, 4, 230, 210, 38, 6, 1, 223, 88, 38, 6, 1, 236, 192, 38, 6, 1, + 231, 20, 38, 6, 1, 196, 125, 223, 226, 38, 6, 1, 235, 32, 38, 6, 1, 247, + 203, 68, 38, 6, 1, 192, 33, 38, 6, 1, 223, 10, 38, 6, 1, 219, 76, 38, 6, + 1, 213, 150, 38, 6, 1, 197, 155, 38, 6, 1, 221, 103, 38, 6, 1, 228, 74, + 4, 230, 210, 38, 6, 1, 203, 40, 66, 38, 6, 1, 235, 28, 38, 6, 1, 65, 38, + 6, 1, 249, 17, 38, 6, 1, 195, 153, 38, 6, 1, 231, 77, 38, 6, 1, 237, 146, + 38, 6, 1, 223, 226, 38, 6, 1, 191, 62, 38, 6, 1, 191, 87, 38, 6, 1, 68, + 38, 6, 1, 203, 40, 68, 38, 6, 1, 155, 38, 6, 1, 234, 140, 38, 6, 1, 234, + 114, 38, 6, 1, 234, 103, 38, 6, 1, 74, 38, 6, 1, 210, 63, 38, 6, 1, 234, + 34, 38, 6, 1, 234, 22, 38, 6, 1, 199, 145, 38, 6, 1, 66, 38, 6, 1, 234, + 181, 38, 6, 1, 140, 38, 6, 1, 197, 161, 38, 6, 1, 243, 127, 38, 6, 1, + 203, 165, 38, 6, 1, 203, 116, 38, 6, 1, 230, 17, 56, 38, 6, 1, 192, 58, + 38, 6, 1, 202, 32, 56, 38, 6, 1, 71, 38, 6, 1, 191, 225, 38, 6, 1, 170, + 38, 2, 1, 65, 38, 2, 1, 249, 17, 38, 2, 1, 195, 153, 38, 2, 1, 231, 77, + 38, 2, 1, 237, 146, 38, 2, 1, 223, 226, 38, 2, 1, 191, 62, 38, 2, 1, 191, + 87, 38, 2, 1, 68, 38, 2, 1, 203, 40, 68, 38, 2, 1, 155, 38, 2, 1, 234, + 140, 38, 2, 1, 234, 114, 38, 2, 1, 234, 103, 38, 2, 1, 74, 38, 2, 1, 210, + 63, 38, 2, 1, 234, 34, 38, 2, 1, 234, 22, 38, 2, 1, 199, 145, 38, 2, 1, + 66, 38, 2, 1, 234, 181, 38, 2, 1, 140, 38, 2, 1, 197, 161, 38, 2, 1, 243, + 127, 38, 2, 1, 203, 165, 38, 2, 1, 203, 116, 38, 2, 1, 230, 17, 56, 38, + 2, 1, 192, 58, 38, 2, 1, 202, 32, 56, 38, 2, 1, 71, 38, 2, 1, 191, 225, + 38, 2, 1, 170, 38, 2, 1, 223, 227, 4, 230, 210, 38, 2, 1, 223, 88, 38, 2, + 1, 236, 192, 38, 2, 1, 231, 20, 38, 2, 1, 196, 125, 223, 226, 38, 2, 1, + 235, 32, 38, 2, 1, 247, 203, 68, 38, 2, 1, 192, 33, 38, 2, 1, 223, 10, + 38, 2, 1, 219, 76, 38, 2, 1, 213, 150, 38, 2, 1, 197, 155, 38, 2, 1, 221, + 103, 38, 2, 1, 228, 74, 4, 230, 210, 38, 2, 1, 203, 40, 66, 38, 2, 1, + 235, 28, 38, 6, 1, 211, 110, 38, 2, 1, 211, 110, 38, 6, 1, 192, 95, 38, + 2, 1, 192, 95, 38, 6, 1, 223, 81, 71, 38, 2, 1, 223, 81, 71, 38, 6, 1, + 219, 83, 191, 190, 38, 2, 1, 219, 83, 191, 190, 38, 6, 1, 223, 81, 219, + 83, 191, 190, 38, 2, 1, 223, 81, 219, 83, 191, 190, 38, 6, 1, 248, 175, + 191, 190, 38, 2, 1, 248, 175, 191, 190, 38, 6, 1, 223, 81, 248, 175, 191, + 190, 38, 2, 1, 223, 81, 248, 175, 191, 190, 38, 6, 1, 220, 248, 38, 2, 1, + 220, 248, 38, 6, 1, 208, 176, 38, 2, 1, 208, 176, 38, 6, 1, 232, 228, 38, + 2, 1, 232, 228, 38, 6, 1, 223, 37, 38, 2, 1, 223, 37, 38, 6, 1, 223, 38, + 4, 55, 230, 211, 252, 60, 38, 2, 1, 223, 38, 4, 55, 230, 211, 252, 60, + 38, 6, 1, 196, 128, 38, 2, 1, 196, 128, 38, 6, 1, 206, 115, 211, 110, 38, + 2, 1, 206, 115, 211, 110, 38, 6, 1, 211, 111, 4, 198, 122, 38, 2, 1, 211, + 111, 4, 198, 122, 38, 6, 1, 211, 30, 38, 2, 1, 211, 30, 38, 6, 1, 221, + 35, 38, 2, 1, 221, 35, 38, 198, 229, 56, 33, 38, 198, 122, 33, 38, 210, + 191, 33, 38, 237, 213, 209, 75, 33, 38, 208, 170, 209, 75, 33, 38, 209, + 54, 33, 38, 228, 141, 198, 229, 56, 33, 38, 216, 48, 56, 38, 6, 1, 203, + 40, 228, 74, 4, 199, 215, 38, 2, 1, 203, 40, 228, 74, 4, 199, 215, 38, 6, + 1, 204, 21, 56, 38, 2, 1, 204, 21, 56, 38, 6, 1, 234, 35, 4, 198, 182, + 38, 2, 1, 234, 35, 4, 198, 182, 38, 6, 1, 231, 78, 4, 196, 69, 38, 2, 1, + 231, 78, 4, 196, 69, 38, 6, 1, 231, 78, 4, 106, 38, 2, 1, 231, 78, 4, + 106, 38, 6, 1, 231, 78, 4, 82, 102, 38, 2, 1, 231, 78, 4, 82, 102, 38, 6, + 1, 191, 63, 4, 237, 87, 38, 2, 1, 191, 63, 4, 237, 87, 38, 6, 1, 191, 88, + 4, 237, 87, 38, 2, 1, 191, 88, 4, 237, 87, 38, 6, 1, 222, 142, 4, 237, + 87, 38, 2, 1, 222, 142, 4, 237, 87, 38, 6, 1, 222, 142, 4, 81, 106, 38, + 2, 1, 222, 142, 4, 81, 106, 38, 6, 1, 222, 142, 4, 106, 38, 2, 1, 222, + 142, 4, 106, 38, 6, 1, 249, 70, 155, 38, 2, 1, 249, 70, 155, 38, 6, 1, + 234, 104, 4, 237, 87, 38, 2, 1, 234, 104, 4, 237, 87, 38, 6, 34, 234, + 104, 231, 77, 38, 2, 34, 234, 104, 231, 77, 38, 6, 1, 210, 64, 4, 82, + 102, 38, 2, 1, 210, 64, 4, 82, 102, 38, 6, 1, 252, 67, 140, 38, 2, 1, + 252, 67, 140, 38, 6, 1, 234, 23, 4, 237, 87, 38, 2, 1, 234, 23, 4, 237, + 87, 38, 6, 1, 199, 146, 4, 237, 87, 38, 2, 1, 199, 146, 4, 237, 87, 38, + 6, 1, 201, 53, 66, 38, 2, 1, 201, 53, 66, 38, 6, 1, 201, 53, 126, 4, 106, + 38, 2, 1, 201, 53, 126, 4, 106, 38, 6, 1, 230, 105, 4, 237, 87, 38, 2, 1, + 230, 105, 4, 237, 87, 38, 6, 34, 199, 146, 197, 161, 38, 2, 34, 199, 146, + 197, 161, 38, 6, 1, 243, 128, 4, 237, 87, 38, 2, 1, 243, 128, 4, 237, 87, + 38, 6, 1, 243, 128, 4, 81, 106, 38, 2, 1, 243, 128, 4, 81, 106, 38, 6, 1, + 203, 82, 38, 2, 1, 203, 82, 38, 6, 1, 252, 67, 243, 127, 38, 2, 1, 252, + 67, 243, 127, 38, 6, 1, 252, 67, 243, 128, 4, 237, 87, 38, 2, 1, 252, 67, + 243, 128, 4, 237, 87, 38, 1, 210, 179, 38, 6, 1, 191, 63, 4, 248, 36, 38, + 2, 1, 191, 63, 4, 248, 36, 38, 6, 1, 222, 142, 4, 102, 38, 2, 1, 222, + 142, 4, 102, 38, 6, 1, 234, 141, 4, 199, 215, 38, 2, 1, 234, 141, 4, 199, + 215, 38, 6, 1, 234, 104, 4, 102, 38, 2, 1, 234, 104, 4, 102, 38, 6, 1, + 234, 104, 4, 199, 215, 38, 2, 1, 234, 104, 4, 199, 215, 38, 6, 1, 221, + 208, 243, 127, 38, 2, 1, 221, 208, 243, 127, 38, 6, 1, 234, 115, 4, 199, + 215, 38, 2, 1, 234, 115, 4, 199, 215, 38, 2, 1, 210, 179, 38, 6, 1, 42, + 4, 248, 36, 38, 2, 1, 42, 4, 248, 36, 38, 6, 1, 42, 4, 237, 42, 38, 2, 1, + 42, 4, 237, 42, 38, 6, 34, 42, 223, 226, 38, 2, 34, 42, 223, 226, 38, 6, + 1, 223, 227, 4, 248, 36, 38, 2, 1, 223, 227, 4, 248, 36, 38, 6, 1, 205, + 86, 38, 2, 1, 205, 86, 38, 6, 1, 205, 87, 4, 237, 42, 38, 2, 1, 205, 87, + 4, 237, 42, 38, 6, 1, 191, 63, 4, 237, 42, 38, 2, 1, 191, 63, 4, 237, 42, + 38, 6, 1, 191, 88, 4, 237, 42, 38, 2, 1, 191, 88, 4, 237, 42, 38, 6, 1, + 252, 67, 235, 32, 38, 2, 1, 252, 67, 235, 32, 38, 6, 1, 228, 74, 4, 217, + 146, 38, 2, 1, 228, 74, 4, 217, 146, 38, 6, 1, 228, 74, 4, 237, 42, 38, + 2, 1, 228, 74, 4, 237, 42, 38, 6, 1, 187, 4, 237, 42, 38, 2, 1, 187, 4, + 237, 42, 38, 6, 1, 249, 82, 74, 38, 2, 1, 249, 82, 74, 38, 6, 1, 249, 82, + 187, 4, 237, 42, 38, 2, 1, 249, 82, 187, 4, 237, 42, 38, 6, 1, 235, 15, + 4, 237, 42, 38, 2, 1, 235, 15, 4, 237, 42, 38, 6, 1, 126, 4, 217, 146, + 38, 2, 1, 126, 4, 217, 146, 38, 6, 1, 126, 4, 237, 42, 38, 2, 1, 126, 4, + 237, 42, 38, 6, 1, 126, 4, 55, 252, 46, 38, 2, 1, 126, 4, 55, 252, 46, + 38, 6, 1, 243, 128, 4, 237, 42, 38, 2, 1, 243, 128, 4, 237, 42, 38, 6, 1, + 231, 78, 4, 237, 87, 38, 2, 1, 231, 78, 4, 237, 87, 38, 6, 1, 192, 59, 4, + 237, 42, 38, 2, 1, 192, 59, 4, 237, 42, 38, 6, 1, 231, 78, 4, 201, 28, + 23, 102, 38, 2, 1, 231, 78, 4, 201, 28, 23, 102, 38, 6, 1, 230, 105, 4, + 102, 38, 2, 1, 230, 105, 4, 102, 38, 6, 1, 230, 105, 4, 106, 38, 2, 1, + 230, 105, 4, 106, 38, 6, 1, 221, 45, 237, 146, 38, 2, 1, 221, 45, 237, + 146, 38, 6, 1, 221, 45, 236, 192, 38, 2, 1, 221, 45, 236, 192, 38, 6, 1, + 221, 45, 191, 12, 38, 2, 1, 221, 45, 191, 12, 38, 6, 1, 221, 45, 235, 24, + 38, 2, 1, 221, 45, 235, 24, 38, 6, 1, 221, 45, 219, 76, 38, 2, 1, 221, + 45, 219, 76, 38, 6, 1, 221, 45, 213, 150, 38, 2, 1, 221, 45, 213, 150, + 38, 6, 1, 221, 45, 202, 115, 38, 2, 1, 221, 45, 202, 115, 38, 6, 1, 221, + 45, 198, 116, 38, 2, 1, 221, 45, 198, 116, 38, 6, 1, 207, 18, 191, 87, + 38, 2, 1, 207, 18, 191, 87, 38, 6, 1, 234, 141, 4, 102, 38, 2, 1, 234, + 141, 4, 102, 38, 6, 1, 219, 159, 38, 2, 1, 219, 159, 38, 6, 1, 207, 6, + 38, 2, 1, 207, 6, 38, 6, 1, 192, 129, 38, 2, 1, 192, 129, 38, 6, 1, 208, + 96, 38, 2, 1, 208, 96, 38, 6, 1, 193, 125, 38, 2, 1, 193, 125, 38, 6, 1, + 251, 188, 155, 38, 2, 1, 251, 188, 155, 38, 6, 1, 234, 141, 4, 82, 102, + 38, 2, 1, 234, 141, 4, 82, 102, 38, 6, 1, 234, 104, 4, 82, 102, 38, 2, 1, + 234, 104, 4, 82, 102, 38, 6, 1, 210, 64, 4, 237, 87, 38, 2, 1, 210, 64, + 4, 237, 87, 38, 6, 1, 203, 83, 4, 237, 87, 38, 2, 1, 203, 83, 4, 237, 87, + 38, 6, 1, 234, 104, 4, 45, 102, 38, 2, 1, 234, 104, 4, 45, 102, 38, 6, 1, + 235, 16, 38, 2, 1, 235, 16, 38, 6, 1, 237, 195, 38, 2, 1, 237, 195, 38, + 6, 1, 234, 141, 4, 237, 87, 38, 2, 1, 234, 141, 4, 237, 87, 250, 249, 6, + 1, 250, 128, 250, 249, 6, 1, 248, 229, 250, 249, 6, 1, 231, 40, 250, 249, + 6, 1, 238, 32, 250, 249, 6, 1, 234, 195, 250, 249, 6, 1, 191, 123, 250, + 249, 6, 1, 234, 173, 250, 249, 6, 1, 233, 255, 250, 249, 6, 1, 159, 250, + 249, 6, 1, 191, 62, 250, 249, 6, 1, 223, 131, 250, 249, 6, 1, 219, 80, + 250, 249, 6, 1, 192, 212, 250, 249, 6, 1, 247, 160, 250, 249, 6, 1, 221, + 251, 250, 249, 6, 1, 229, 23, 250, 249, 6, 1, 223, 32, 250, 249, 6, 1, + 231, 88, 250, 249, 6, 1, 243, 117, 250, 249, 6, 1, 216, 186, 250, 249, 6, + 1, 192, 33, 250, 249, 6, 1, 212, 253, 250, 249, 6, 1, 203, 165, 250, 249, + 6, 1, 195, 24, 250, 249, 6, 1, 247, 1, 250, 249, 6, 1, 210, 41, 250, 249, + 6, 1, 222, 247, 250, 249, 6, 1, 165, 250, 249, 6, 1, 205, 39, 250, 249, + 6, 1, 195, 74, 250, 249, 6, 1, 198, 119, 250, 249, 6, 1, 207, 71, 250, + 249, 6, 1, 242, 99, 250, 249, 6, 1, 192, 17, 250, 249, 6, 1, 209, 114, + 250, 249, 6, 1, 222, 6, 250, 249, 6, 1, 211, 136, 250, 249, 6, 1, 233, + 46, 250, 249, 52, 1, 45, 132, 206, 188, 250, 249, 251, 49, 250, 249, 234, + 107, 77, 250, 249, 233, 216, 77, 250, 249, 242, 74, 250, 249, 208, 13, + 77, 250, 249, 252, 68, 77, 250, 249, 2, 1, 153, 250, 128, 250, 249, 2, 1, + 250, 128, 250, 249, 2, 1, 248, 229, 250, 249, 2, 1, 231, 40, 250, 249, 2, + 1, 238, 32, 250, 249, 2, 1, 234, 195, 250, 249, 2, 1, 191, 123, 250, 249, + 2, 1, 234, 173, 250, 249, 2, 1, 233, 255, 250, 249, 2, 1, 159, 250, 249, + 2, 1, 191, 62, 250, 249, 2, 1, 223, 131, 250, 249, 2, 1, 219, 80, 250, + 249, 2, 1, 192, 212, 250, 249, 2, 1, 247, 160, 250, 249, 2, 1, 221, 251, + 250, 249, 2, 1, 229, 23, 250, 249, 2, 1, 223, 32, 250, 249, 2, 1, 231, + 88, 250, 249, 2, 1, 243, 117, 250, 249, 2, 1, 216, 186, 250, 249, 2, 1, + 192, 33, 250, 249, 2, 1, 212, 253, 250, 249, 2, 1, 203, 165, 250, 249, 2, + 1, 195, 24, 250, 249, 2, 1, 247, 1, 250, 249, 2, 1, 210, 41, 250, 249, 2, + 1, 222, 247, 250, 249, 2, 1, 165, 250, 249, 2, 1, 205, 39, 250, 249, 2, + 1, 195, 74, 250, 249, 2, 1, 198, 119, 250, 249, 2, 1, 207, 71, 250, 249, + 2, 1, 242, 99, 250, 249, 2, 1, 192, 17, 250, 249, 2, 1, 209, 114, 250, + 249, 2, 1, 222, 6, 250, 249, 2, 1, 211, 136, 250, 249, 2, 1, 233, 46, + 250, 249, 2, 34, 234, 196, 192, 17, 250, 249, 2, 1, 11, 4, 106, 250, 249, + 232, 80, 201, 63, 250, 249, 228, 88, 206, 207, 250, 249, 233, 251, 56, + 219, 223, 250, 249, 233, 251, 56, 250, 249, 235, 110, 56, 136, 252, 61, + 233, 246, 136, 252, 61, 205, 40, 136, 252, 61, 203, 141, 136, 252, 61, + 191, 99, 208, 78, 136, 252, 61, 191, 99, 231, 230, 136, 252, 61, 198, + 134, 136, 252, 61, 207, 15, 136, 252, 61, 191, 97, 136, 252, 61, 210, 97, + 136, 252, 61, 192, 48, 136, 252, 61, 199, 56, 136, 252, 61, 231, 139, + 136, 252, 61, 231, 140, 215, 110, 136, 252, 61, 231, 137, 136, 252, 61, + 208, 80, 210, 130, 136, 252, 61, 199, 103, 231, 158, 136, 252, 61, 210, + 69, 136, 252, 61, 250, 173, 230, 85, 136, 252, 61, 215, 121, 136, 252, + 61, 217, 117, 136, 252, 61, 216, 175, 136, 252, 61, 216, 176, 222, 7, + 136, 252, 61, 237, 222, 136, 252, 61, 208, 91, 136, 252, 61, 199, 103, + 208, 73, 136, 252, 61, 192, 61, 248, 230, 191, 247, 136, 252, 61, 211, + 117, 136, 252, 61, 223, 183, 136, 252, 61, 237, 123, 136, 252, 61, 191, + 19, 136, 87, 217, 34, 243, 10, 136, 209, 62, 203, 85, 136, 209, 62, 230, + 8, 205, 40, 136, 209, 62, 230, 8, 210, 88, 136, 209, 62, 230, 8, 208, 84, + 136, 209, 62, 229, 119, 136, 209, 62, 197, 158, 136, 209, 62, 205, 40, + 136, 209, 62, 210, 88, 136, 209, 62, 208, 84, 136, 209, 62, 229, 7, 136, + 209, 62, 229, 8, 230, 10, 40, 195, 158, 136, 209, 62, 208, 18, 136, 209, + 62, 238, 17, 211, 57, 217, 70, 136, 209, 62, 216, 164, 136, 208, 152, + 217, 67, 136, 209, 62, 207, 161, 136, 208, 152, 210, 99, 136, 209, 62, + 203, 70, 236, 140, 136, 209, 62, 202, 175, 236, 140, 136, 208, 152, 202, + 33, 210, 90, 136, 87, 116, 236, 140, 136, 87, 110, 236, 140, 136, 208, + 152, 212, 131, 230, 84, 136, 209, 62, 208, 85, 208, 78, 136, 1, 251, 192, + 136, 1, 248, 214, 136, 1, 231, 38, 136, 1, 237, 253, 136, 1, 229, 245, + 136, 1, 195, 158, 136, 1, 191, 91, 136, 1, 229, 186, 136, 1, 199, 73, + 136, 1, 191, 250, 136, 1, 53, 222, 106, 136, 1, 222, 106, 136, 1, 220, + 27, 136, 1, 53, 216, 193, 136, 1, 216, 193, 136, 1, 53, 212, 130, 136, 1, + 212, 130, 136, 1, 205, 148, 136, 1, 250, 126, 136, 1, 53, 210, 63, 136, + 1, 210, 63, 136, 1, 53, 197, 163, 136, 1, 197, 163, 136, 1, 208, 42, 136, + 1, 207, 38, 136, 1, 203, 69, 136, 1, 199, 162, 136, 191, 251, 197, 241, + 136, 34, 192, 31, 55, 195, 158, 136, 34, 192, 31, 195, 159, 191, 250, + 136, 34, 192, 31, 55, 191, 250, 136, 208, 152, 231, 139, 136, 208, 152, + 231, 137, 9, 31, 56, 9, 3, 205, 141, 9, 232, 157, 217, 51, 9, 3, 205, + 187, 9, 3, 205, 144, 9, 31, 87, 58, 251, 28, 238, 191, 206, 128, 251, 28, + 232, 121, 206, 128, 9, 207, 122, 251, 28, 210, 14, 216, 50, 56, 251, 28, + 210, 14, 199, 96, 198, 230, 56, 252, 2, 56, 9, 242, 74, 9, 237, 209, 204, + 10, 9, 209, 64, 195, 137, 56, 9, 3, 216, 25, 9, 3, 205, 161, 251, 199, + 193, 149, 9, 3, 251, 199, 250, 198, 9, 3, 207, 157, 251, 198, 9, 3, 207, + 167, 251, 170, 251, 105, 9, 3, 199, 206, 9, 2, 137, 199, 219, 9, 2, 137, + 34, 131, 4, 220, 36, 4, 192, 75, 9, 2, 137, 191, 113, 9, 2, 233, 70, 9, + 2, 237, 245, 9, 2, 222, 52, 9, 204, 25, 9, 1, 77, 9, 234, 95, 79, 199, + 54, 77, 9, 197, 225, 75, 208, 152, 77, 9, 208, 13, 77, 9, 1, 222, 56, + 192, 75, 9, 1, 230, 57, 9, 1, 131, 4, 217, 142, 58, 9, 1, 131, 4, 230, + 58, 58, 9, 1, 193, 134, 4, 230, 58, 58, 9, 1, 131, 4, 230, 58, 60, 9, 1, + 99, 4, 230, 58, 58, 9, 1, 251, 192, 9, 1, 248, 245, 9, 1, 199, 115, 217, + 62, 9, 1, 199, 114, 9, 1, 199, 29, 9, 1, 223, 6, 9, 1, 230, 81, 9, 1, + 221, 210, 9, 1, 238, 3, 9, 1, 199, 41, 9, 1, 207, 71, 9, 1, 191, 113, 9, + 1, 205, 46, 9, 1, 203, 109, 9, 1, 205, 192, 9, 1, 238, 26, 9, 1, 199, + 219, 9, 1, 191, 116, 9, 1, 251, 230, 9, 1, 231, 86, 9, 1, 222, 5, 4, 105, + 185, 58, 9, 1, 222, 5, 4, 115, 185, 60, 9, 1, 233, 74, 99, 4, 223, 93, + 196, 12, 9, 1, 233, 74, 99, 4, 105, 185, 58, 9, 1, 233, 74, 99, 4, 115, + 185, 58, 9, 199, 168, 9, 1, 233, 46, 9, 1, 208, 89, 9, 1, 222, 106, 9, 1, + 220, 35, 9, 1, 216, 208, 9, 1, 213, 24, 9, 1, 229, 210, 9, 1, 193, 133, + 9, 1, 131, 217, 99, 9, 1, 192, 75, 9, 233, 68, 9, 237, 243, 9, 222, 50, + 9, 233, 70, 9, 237, 245, 9, 222, 52, 9, 203, 155, 9, 200, 206, 9, 217, + 140, 58, 9, 230, 58, 58, 9, 230, 58, 60, 9, 200, 230, 251, 192, 9, 223, + 93, 237, 245, 9, 87, 213, 25, 231, 57, 9, 190, 237, 9, 18, 3, 2, 196, 13, + 58, 9, 18, 3, 223, 93, 2, 196, 13, 58, 9, 18, 3, 75, 60, 9, 207, 18, 237, + 245, 9, 233, 71, 4, 105, 236, 138, 9, 193, 135, 230, 58, 60, 251, 28, 17, + 191, 77, 251, 28, 17, 107, 251, 28, 17, 109, 251, 28, 17, 138, 251, 28, + 17, 134, 251, 28, 17, 149, 251, 28, 17, 169, 251, 28, 17, 175, 251, 28, + 17, 171, 251, 28, 17, 178, 9, 210, 13, 56, 9, 237, 138, 204, 10, 9, 198, + 229, 204, 10, 9, 232, 226, 209, 60, 201, 102, 9, 1, 236, 139, 248, 245, + 9, 1, 236, 139, 208, 89, 9, 1, 200, 182, 251, 192, 9, 1, 131, 193, 150, + 9, 1, 131, 4, 193, 135, 230, 58, 58, 9, 1, 131, 4, 193, 135, 230, 58, 60, + 9, 1, 137, 230, 57, 9, 1, 137, 230, 58, 251, 192, 9, 1, 137, 230, 58, + 193, 133, 9, 1, 126, 4, 230, 58, 58, 9, 1, 137, 230, 58, 192, 75, 9, 1, + 197, 124, 9, 1, 197, 122, 9, 1, 248, 255, 9, 1, 199, 115, 4, 206, 188, 9, + 1, 199, 115, 4, 115, 185, 93, 235, 118, 9, 1, 210, 41, 9, 1, 199, 112, 9, + 1, 248, 243, 9, 1, 182, 4, 230, 58, 58, 9, 1, 182, 4, 105, 185, 81, 58, + 9, 1, 212, 87, 9, 1, 235, 41, 9, 1, 182, 4, 115, 185, 58, 9, 1, 199, 149, + 9, 1, 199, 147, 9, 1, 237, 186, 9, 1, 238, 4, 4, 206, 188, 9, 1, 238, 4, + 4, 75, 60, 9, 1, 238, 4, 4, 75, 248, 233, 23, 2, 199, 219, 9, 1, 238, 10, + 9, 1, 237, 188, 9, 1, 235, 78, 9, 1, 238, 4, 4, 115, 185, 93, 235, 118, + 9, 1, 238, 4, 4, 232, 128, 185, 58, 9, 1, 206, 101, 9, 1, 207, 72, 4, 2, + 196, 12, 9, 1, 207, 72, 4, 206, 188, 9, 1, 207, 72, 4, 75, 60, 9, 1, 207, + 72, 4, 2, 196, 13, 60, 9, 1, 207, 72, 4, 75, 248, 233, 23, 75, 58, 9, 1, + 207, 72, 4, 105, 185, 58, 9, 1, 223, 3, 9, 1, 207, 72, 4, 232, 128, 185, + 58, 9, 1, 205, 47, 4, 75, 248, 233, 23, 75, 58, 9, 1, 205, 47, 4, 115, + 185, 60, 9, 1, 205, 47, 4, 115, 185, 248, 233, 23, 115, 185, 58, 9, 1, + 205, 193, 4, 105, 185, 60, 9, 1, 205, 193, 4, 115, 185, 58, 9, 1, 199, + 220, 4, 115, 185, 58, 9, 1, 251, 231, 4, 115, 185, 58, 9, 1, 236, 139, + 233, 46, 9, 1, 233, 47, 4, 75, 215, 177, 60, 9, 1, 233, 47, 4, 75, 60, 9, + 1, 195, 146, 9, 1, 233, 47, 4, 115, 185, 60, 9, 1, 210, 39, 9, 1, 208, + 90, 4, 75, 58, 9, 1, 208, 90, 4, 115, 185, 58, 9, 1, 222, 4, 9, 1, 200, + 146, 222, 106, 9, 1, 222, 107, 4, 206, 188, 9, 1, 222, 107, 4, 75, 58, 9, + 1, 214, 70, 9, 1, 222, 107, 4, 115, 185, 60, 9, 1, 231, 227, 9, 1, 231, + 228, 4, 206, 188, 9, 1, 213, 247, 9, 1, 231, 228, 4, 105, 185, 60, 9, 1, + 230, 166, 9, 1, 231, 228, 4, 115, 185, 58, 9, 1, 220, 36, 4, 2, 196, 12, + 9, 1, 220, 36, 4, 75, 58, 9, 1, 220, 36, 4, 115, 185, 58, 9, 1, 220, 36, + 4, 115, 185, 60, 9, 1, 213, 25, 4, 75, 60, 9, 1, 213, 25, 231, 57, 9, 1, + 206, 165, 9, 1, 213, 25, 4, 206, 188, 9, 1, 213, 25, 4, 115, 185, 58, 9, + 1, 229, 211, 236, 170, 9, 1, 199, 150, 4, 75, 58, 9, 1, 229, 211, 4, 99, + 58, 9, 1, 229, 211, 231, 0, 9, 1, 229, 211, 231, 1, 4, 230, 58, 58, 9, 1, + 199, 115, 217, 63, 231, 0, 9, 1, 193, 134, 4, 206, 188, 9, 1, 221, 132, + 211, 151, 9, 1, 211, 151, 9, 1, 66, 9, 1, 191, 225, 9, 1, 221, 132, 191, + 225, 9, 1, 193, 134, 4, 105, 185, 58, 9, 1, 195, 153, 9, 1, 233, 74, 192, + 75, 9, 1, 99, 4, 199, 215, 9, 1, 99, 4, 2, 196, 12, 9, 1, 193, 134, 4, + 75, 58, 9, 1, 71, 9, 1, 99, 4, 115, 185, 60, 9, 1, 99, 249, 80, 9, 1, 99, + 249, 81, 4, 230, 58, 58, 9, 232, 80, 201, 63, 9, 1, 252, 25, 9, 2, 137, + 34, 205, 193, 4, 220, 36, 4, 131, 217, 99, 9, 2, 137, 34, 208, 90, 4, + 220, 36, 4, 131, 217, 99, 9, 2, 137, 92, 89, 20, 9, 2, 137, 220, 36, 251, + 192, 9, 2, 137, 223, 6, 9, 2, 137, 115, 236, 138, 9, 2, 137, 205, 46, 9, + 234, 95, 79, 250, 130, 9, 201, 98, 79, 206, 60, 234, 141, 229, 114, 9, 2, + 137, 206, 113, 191, 77, 9, 2, 137, 196, 73, 207, 91, 191, 77, 9, 2, 137, + 236, 139, 229, 236, 79, 221, 210, 9, 2, 137, 92, 76, 20, 9, 2, 130, 205, + 46, 9, 2, 137, 217, 141, 9, 2, 193, 133, 9, 2, 192, 75, 9, 2, 137, 192, + 75, 9, 2, 137, 213, 24, 9, 209, 108, 79, 205, 177, 9, 234, 105, 247, 22, + 130, 201, 63, 9, 234, 105, 247, 22, 137, 201, 63, 9, 206, 113, 137, 201, + 64, 4, 233, 4, 247, 21, 9, 2, 130, 216, 208, 9, 1, 238, 4, 4, 223, 93, + 196, 12, 9, 1, 207, 72, 4, 223, 93, 196, 12, 233, 205, 251, 28, 17, 191, + 77, 233, 205, 251, 28, 17, 107, 233, 205, 251, 28, 17, 109, 233, 205, + 251, 28, 17, 138, 233, 205, 251, 28, 17, 134, 233, 205, 251, 28, 17, 149, + 233, 205, 251, 28, 17, 169, 233, 205, 251, 28, 17, 175, 233, 205, 251, + 28, 17, 171, 233, 205, 251, 28, 17, 178, 9, 1, 203, 110, 4, 75, 60, 9, 1, + 238, 27, 4, 75, 60, 9, 1, 231, 87, 4, 75, 60, 9, 3, 202, 173, 251, 137, + 9, 3, 202, 173, 209, 16, 216, 186, 9, 1, 229, 211, 4, 223, 93, 196, 12, + 200, 63, 234, 95, 79, 210, 127, 200, 63, 200, 177, 232, 80, 201, 63, 200, + 63, 200, 232, 232, 80, 201, 63, 200, 63, 200, 177, 242, 83, 200, 63, 200, + 232, 242, 83, 200, 63, 228, 241, 242, 83, 200, 63, 242, 84, 202, 110, + 219, 224, 200, 63, 242, 84, 202, 110, 183, 200, 63, 200, 177, 242, 84, + 202, 110, 219, 224, 200, 63, 200, 232, 242, 84, 202, 110, 183, 200, 63, + 239, 24, 200, 63, 230, 15, 211, 176, 200, 63, 230, 15, 216, 162, 200, 63, + 230, 15, 250, 195, 200, 63, 252, 68, 77, 200, 63, 1, 251, 202, 200, 63, + 1, 200, 182, 251, 202, 200, 63, 1, 248, 211, 200, 63, 1, 231, 217, 200, + 63, 1, 231, 218, 231, 194, 200, 63, 1, 238, 0, 200, 63, 1, 236, 139, 238, + 1, 206, 181, 200, 63, 1, 229, 245, 200, 63, 1, 193, 133, 200, 63, 1, 191, + 113, 200, 63, 1, 229, 184, 200, 63, 1, 199, 69, 200, 63, 1, 199, 70, 231, + 194, 200, 63, 1, 191, 208, 200, 63, 1, 191, 209, 229, 245, 200, 63, 1, + 222, 75, 200, 63, 1, 220, 34, 200, 63, 1, 216, 46, 200, 63, 1, 212, 130, + 200, 63, 1, 204, 18, 200, 63, 1, 53, 204, 18, 200, 63, 1, 71, 200, 63, 1, + 210, 63, 200, 63, 1, 207, 18, 210, 63, 200, 63, 1, 205, 189, 200, 63, 1, + 208, 83, 200, 63, 1, 206, 181, 200, 63, 1, 203, 69, 200, 63, 1, 199, 159, + 200, 63, 1, 209, 252, 248, 194, 200, 63, 1, 209, 252, 231, 84, 200, 63, + 1, 209, 252, 237, 63, 200, 63, 208, 166, 58, 200, 63, 208, 166, 60, 200, + 63, 208, 166, 235, 137, 200, 63, 191, 0, 58, 200, 63, 191, 0, 60, 200, + 63, 191, 0, 235, 137, 200, 63, 207, 116, 58, 200, 63, 207, 116, 60, 200, + 63, 235, 138, 191, 9, 228, 240, 200, 63, 235, 138, 191, 9, 251, 108, 200, + 63, 229, 250, 58, 200, 63, 229, 250, 60, 200, 63, 229, 249, 235, 137, + 200, 63, 234, 16, 58, 200, 63, 234, 16, 60, 200, 63, 206, 24, 200, 63, + 233, 40, 236, 140, 200, 63, 207, 246, 200, 63, 206, 54, 200, 63, 105, 81, + 185, 58, 200, 63, 105, 81, 185, 60, 200, 63, 115, 185, 58, 200, 63, 115, + 185, 60, 200, 63, 211, 172, 219, 113, 58, 200, 63, 211, 172, 219, 113, + 60, 200, 63, 215, 96, 200, 63, 249, 79, 200, 63, 1, 202, 28, 191, 69, + 200, 63, 1, 202, 28, 221, 201, 200, 63, 1, 202, 28, 233, 59, 9, 1, 248, + 246, 4, 115, 185, 228, 190, 60, 9, 1, 248, 246, 4, 75, 248, 233, 23, 115, + 185, 58, 9, 1, 248, 246, 4, 115, 185, 209, 58, 196, 66, 60, 9, 1, 248, + 246, 4, 115, 185, 209, 58, 196, 66, 248, 233, 23, 105, 185, 58, 9, 1, + 248, 246, 4, 105, 185, 248, 233, 23, 75, 58, 9, 1, 248, 246, 4, 223, 93, + 2, 196, 13, 60, 9, 1, 248, 246, 4, 2, 196, 12, 9, 1, 182, 4, 105, 185, + 58, 9, 1, 182, 4, 115, 185, 209, 58, 196, 66, 60, 9, 1, 238, 4, 4, 105, + 185, 195, 85, 248, 233, 23, 2, 199, 219, 9, 1, 238, 4, 4, 223, 93, 2, + 196, 13, 60, 9, 1, 207, 72, 4, 106, 9, 1, 205, 47, 4, 232, 128, 185, 58, + 9, 1, 251, 231, 4, 105, 185, 58, 9, 1, 251, 231, 4, 115, 185, 209, 58, + 235, 119, 58, 9, 1, 251, 231, 4, 105, 185, 195, 85, 58, 9, 1, 233, 47, 4, + 105, 185, 60, 9, 1, 233, 47, 4, 115, 185, 209, 58, 196, 66, 60, 9, 1, + 222, 5, 4, 75, 58, 9, 1, 222, 5, 4, 115, 185, 58, 9, 1, 222, 5, 4, 115, + 185, 209, 58, 196, 66, 60, 9, 1, 92, 4, 75, 58, 9, 1, 92, 4, 75, 60, 9, + 1, 213, 25, 4, 105, 185, 60, 9, 1, 213, 25, 4, 2, 199, 219, 9, 1, 213, + 25, 4, 2, 196, 12, 9, 1, 220, 36, 4, 164, 9, 1, 207, 72, 4, 105, 185, + 195, 85, 58, 9, 1, 207, 72, 4, 230, 58, 58, 9, 1, 205, 47, 4, 105, 185, + 195, 85, 58, 9, 1, 182, 4, 2, 9, 1, 199, 220, 60, 9, 1, 182, 4, 2, 9, 1, + 199, 220, 23, 105, 236, 138, 9, 1, 205, 47, 4, 2, 9, 1, 199, 220, 23, + 105, 236, 138, 9, 1, 207, 72, 4, 2, 9, 1, 199, 220, 23, 105, 236, 138, 9, + 1, 182, 4, 2, 9, 1, 199, 220, 58, 9, 1, 131, 4, 233, 205, 251, 28, 17, + 105, 58, 9, 1, 131, 4, 233, 205, 251, 28, 17, 115, 58, 9, 1, 233, 74, 99, + 4, 233, 205, 251, 28, 17, 105, 58, 9, 1, 233, 74, 99, 4, 233, 205, 251, + 28, 17, 115, 58, 9, 1, 233, 74, 99, 4, 233, 205, 251, 28, 17, 232, 128, + 60, 9, 1, 193, 134, 4, 233, 205, 251, 28, 17, 105, 58, 9, 1, 193, 134, 4, + 233, 205, 251, 28, 17, 115, 58, 9, 1, 99, 249, 81, 4, 233, 205, 251, 28, + 17, 105, 58, 9, 1, 99, 249, 81, 4, 233, 205, 251, 28, 17, 115, 58, 9, 1, + 182, 4, 233, 205, 251, 28, 17, 232, 128, 60, 9, 1, 205, 47, 4, 233, 205, + 251, 28, 17, 232, 128, 58, 9, 1, 205, 47, 4, 223, 93, 196, 12, 9, 1, 222, + 107, 4, 105, 185, 58, 199, 46, 1, 230, 91, 199, 46, 1, 203, 119, 199, 46, + 1, 213, 23, 199, 46, 1, 207, 178, 199, 46, 1, 249, 151, 199, 46, 1, 219, + 156, 199, 46, 1, 222, 122, 199, 46, 1, 251, 179, 199, 46, 1, 195, 186, + 199, 46, 1, 216, 207, 199, 46, 1, 233, 107, 199, 46, 1, 237, 66, 199, 46, + 1, 199, 48, 199, 46, 1, 220, 122, 199, 46, 1, 231, 236, 199, 46, 1, 231, + 6, 199, 46, 1, 205, 45, 199, 46, 1, 237, 207, 199, 46, 1, 191, 94, 199, + 46, 1, 199, 161, 199, 46, 1, 192, 140, 199, 46, 1, 210, 77, 199, 46, 1, + 223, 15, 199, 46, 1, 243, 130, 199, 46, 1, 197, 131, 199, 46, 1, 229, + 176, 199, 46, 1, 221, 214, 199, 46, 1, 199, 47, 199, 46, 1, 191, 121, + 199, 46, 1, 203, 108, 199, 46, 1, 205, 196, 199, 46, 1, 238, 30, 199, 46, + 1, 159, 199, 46, 1, 191, 7, 199, 46, 1, 251, 227, 199, 46, 1, 231, 85, + 199, 46, 1, 208, 93, 199, 46, 1, 193, 178, 199, 46, 252, 70, 199, 46, + 252, 171, 199, 46, 228, 29, 199, 46, 234, 187, 199, 46, 196, 161, 199, + 46, 211, 86, 199, 46, 234, 198, 199, 46, 233, 195, 199, 46, 211, 171, + 199, 46, 211, 181, 199, 46, 200, 206, 199, 46, 1, 214, 250, 213, 107, 17, + 191, 77, 213, 107, 17, 107, 213, 107, 17, 109, 213, 107, 17, 138, 213, + 107, 17, 134, 213, 107, 17, 149, 213, 107, 17, 169, 213, 107, 17, 175, + 213, 107, 17, 171, 213, 107, 17, 178, 213, 107, 1, 65, 213, 107, 1, 234, + 188, 213, 107, 1, 68, 213, 107, 1, 71, 213, 107, 1, 66, 213, 107, 1, 211, + 87, 213, 107, 1, 74, 213, 107, 1, 238, 18, 213, 107, 1, 215, 61, 213, + 107, 1, 249, 153, 213, 107, 1, 168, 213, 107, 1, 190, 190, 213, 107, 1, + 223, 32, 213, 107, 1, 247, 1, 213, 107, 1, 238, 32, 213, 107, 1, 165, + 213, 107, 1, 206, 109, 213, 107, 1, 188, 213, 107, 1, 231, 182, 213, 107, + 1, 233, 109, 213, 107, 1, 155, 213, 107, 1, 173, 213, 107, 1, 215, 7, + 193, 37, 213, 107, 1, 174, 213, 107, 1, 212, 101, 213, 107, 1, 180, 213, + 107, 1, 140, 213, 107, 1, 193, 190, 213, 107, 1, 170, 213, 107, 1, 212, + 102, 193, 37, 213, 107, 1, 222, 193, 223, 32, 213, 107, 1, 222, 193, 247, + 1, 213, 107, 1, 222, 193, 165, 213, 107, 33, 203, 40, 137, 198, 79, 213, + 107, 33, 203, 40, 130, 198, 79, 213, 107, 33, 203, 40, 206, 180, 198, 79, + 213, 107, 33, 179, 237, 86, 198, 79, 213, 107, 33, 179, 137, 198, 79, + 213, 107, 33, 179, 130, 198, 79, 213, 107, 33, 179, 206, 180, 198, 79, + 213, 107, 33, 214, 213, 77, 213, 107, 33, 55, 75, 58, 213, 107, 137, 163, + 251, 49, 213, 107, 130, 163, 251, 49, 213, 107, 16, 211, 88, 237, 101, + 213, 107, 16, 231, 181, 213, 107, 242, 74, 213, 107, 233, 216, 77, 213, + 107, 220, 94, 213, 107, 237, 233, 213, 107, 236, 142, 56, 213, 107, 199, + 195, 56, 205, 151, 1, 251, 204, 205, 151, 1, 248, 148, 205, 151, 1, 231, + 216, 205, 151, 1, 238, 2, 205, 151, 1, 223, 44, 205, 151, 1, 249, 151, + 205, 151, 1, 191, 80, 205, 151, 1, 223, 53, 205, 151, 1, 198, 125, 205, + 151, 1, 191, 189, 205, 151, 1, 222, 123, 205, 151, 1, 220, 118, 205, 151, + 1, 216, 46, 205, 151, 1, 212, 130, 205, 151, 1, 202, 171, 205, 151, 1, + 223, 162, 205, 151, 1, 233, 23, 205, 151, 1, 197, 166, 205, 151, 1, 208, + 10, 205, 151, 1, 206, 181, 205, 151, 1, 203, 138, 205, 151, 1, 199, 243, + 205, 151, 87, 223, 162, 205, 151, 87, 223, 161, 205, 151, 87, 211, 165, + 205, 151, 87, 238, 16, 205, 151, 52, 1, 234, 52, 191, 189, 205, 151, 87, + 234, 52, 191, 189, 205, 151, 18, 3, 179, 71, 205, 151, 18, 3, 71, 205, + 151, 18, 3, 210, 253, 252, 206, 205, 151, 18, 3, 179, 252, 206, 205, 151, + 18, 3, 252, 206, 205, 151, 18, 3, 210, 253, 65, 205, 151, 18, 3, 179, 65, + 205, 151, 18, 3, 65, 205, 151, 52, 1, 203, 40, 65, 205, 151, 18, 3, 203, + 40, 65, 205, 151, 18, 3, 179, 66, 205, 151, 18, 3, 66, 205, 151, 52, 1, + 68, 205, 151, 18, 3, 179, 68, 205, 151, 18, 3, 68, 205, 151, 18, 3, 74, + 205, 151, 18, 3, 200, 206, 205, 151, 87, 214, 93, 205, 151, 208, 152, + 214, 93, 205, 151, 208, 152, 251, 255, 205, 151, 208, 152, 251, 121, 205, + 151, 208, 152, 249, 57, 205, 151, 208, 152, 250, 174, 205, 151, 208, 152, + 203, 57, 205, 151, 252, 68, 77, 205, 151, 208, 152, 216, 197, 208, 48, + 205, 151, 208, 152, 191, 16, 205, 151, 208, 152, 208, 48, 205, 151, 208, + 152, 191, 119, 205, 151, 208, 152, 197, 54, 205, 151, 208, 152, 250, 255, + 205, 151, 208, 152, 202, 33, 217, 37, 205, 151, 208, 152, 251, 97, 217, + 86, 1, 230, 65, 217, 86, 1, 252, 155, 217, 86, 1, 251, 253, 217, 86, 1, + 252, 42, 217, 86, 1, 251, 245, 217, 86, 1, 196, 36, 217, 86, 1, 250, 123, + 217, 86, 1, 223, 53, 217, 86, 1, 250, 171, 217, 86, 1, 251, 211, 217, 86, + 1, 251, 216, 217, 86, 1, 251, 207, 217, 86, 1, 251, 149, 217, 86, 1, 251, + 132, 217, 86, 1, 250, 219, 217, 86, 1, 223, 162, 217, 86, 1, 251, 65, + 217, 86, 1, 250, 184, 217, 86, 1, 251, 37, 217, 86, 1, 251, 33, 217, 86, + 1, 250, 209, 217, 86, 1, 250, 182, 217, 86, 1, 235, 62, 217, 86, 1, 222, + 114, 217, 86, 1, 251, 230, 217, 86, 252, 3, 77, 217, 86, 195, 22, 77, + 217, 86, 231, 153, 77, 217, 86, 208, 151, 200, 63, 1, 142, 214, 68, 200, + 63, 1, 142, 223, 32, 200, 63, 1, 142, 212, 101, 200, 63, 1, 142, 197, + 132, 200, 63, 1, 142, 213, 79, 200, 63, 1, 142, 213, 61, 200, 63, 1, 142, + 248, 203, 200, 63, 1, 142, 165, 200, 63, 1, 142, 219, 73, 200, 63, 1, + 142, 219, 62, 200, 63, 1, 142, 201, 175, 9, 1, 131, 4, 250, 170, 233, 70, + 9, 1, 131, 4, 250, 170, 198, 54, 50, 233, 70, 9, 1, 131, 4, 50, 82, 106, + 9, 1, 131, 4, 45, 82, 106, 9, 1, 131, 4, 250, 170, 222, 52, 9, 1, 131, 4, + 250, 170, 248, 77, 50, 222, 52, 9, 1, 131, 4, 250, 170, 206, 115, 75, 58, + 9, 1, 131, 4, 250, 170, 50, 206, 115, 236, 140, 9, 1, 131, 4, 250, 170, + 45, 206, 115, 236, 140, 9, 1, 131, 4, 250, 170, 206, 115, 75, 60, 9, 1, + 131, 4, 75, 58, 9, 1, 131, 4, 250, 170, 198, 54, 50, 233, 71, 23, 75, 58, + 9, 1, 131, 4, 50, 82, 201, 28, 23, 75, 58, 9, 1, 131, 4, 250, 170, 248, + 77, 50, 222, 53, 23, 75, 58, 9, 1, 131, 4, 250, 170, 198, 54, 50, 233, + 71, 23, 45, 206, 188, 9, 1, 131, 4, 50, 82, 201, 28, 23, 45, 206, 188, 9, + 1, 131, 4, 250, 170, 248, 77, 50, 222, 53, 23, 45, 206, 188, 9, 1, 131, + 4, 250, 170, 50, 230, 57, 9, 1, 131, 4, 250, 170, 45, 230, 57, 9, 199, + 169, 4, 210, 251, 230, 57, 9, 199, 169, 4, 210, 251, 193, 133, 9, 199, + 169, 4, 105, 185, 60, 9, 1, 199, 4, 192, 75, 9, 249, 72, 206, 115, 236, + 140, 9, 207, 147, 206, 115, 236, 140, 9, 1, 213, 25, 4, 223, 93, 2, 196, + 12, 9, 1, 182, 4, 223, 93, 2, 196, 13, 60, 9, 1, 199, 220, 4, 75, 60, 9, + 1, 199, 220, 4, 115, 185, 60, 9, 1, 222, 5, 4, 105, 185, 195, 85, 60, 9, + 81, 199, 215, 9, 209, 8, 87, 58, 9, 209, 182, 87, 58, 9, 2, 137, 193, 23, + 251, 206, 9, 2, 130, 193, 23, 223, 61, 9, 2, 130, 193, 23, 223, 179, 9, + 2, 130, 193, 23, 199, 173, 9, 217, 142, 193, 179, 9, 200, 182, 131, 215, + 234, 9, 235, 128, 217, 141, 9, 132, 217, 142, 139, 217, 141, 9, 1, 248, + 246, 4, 2, 196, 13, 60, 9, 1, 248, 246, 4, 230, 58, 58, 9, 1, 223, 7, 4, + 105, 185, 58, 9, 1, 199, 220, 4, 105, 185, 58, 9, 1, 233, 47, 4, 75, 248, + 233, 23, 115, 185, 58, 9, 1, 208, 90, 4, 75, 60, 9, 1, 220, 36, 4, 55, + 164, 9, 1, 92, 4, 115, 185, 58, 9, 1, 99, 4, 105, 185, 248, 233, 23, 230, + 58, 58, 9, 1, 99, 4, 105, 185, 248, 233, 23, 75, 58, 9, 1, 207, 72, 4, + 219, 4, 9, 1, 193, 134, 4, 75, 193, 52, 9, 1, 206, 142, 192, 75, 9, 1, + 130, 251, 192, 9, 1, 238, 4, 4, 115, 185, 60, 9, 1, 205, 193, 4, 115, + 185, 60, 9, 1, 231, 228, 4, 223, 93, 106, 9, 1, 201, 53, 193, 133, 9, 1, + 191, 114, 4, 223, 93, 196, 13, 58, 9, 1, 251, 231, 4, 115, 185, 60, 9, 1, + 222, 107, 4, 75, 60, 9, 1, 208, 90, 4, 75, 248, 233, 23, 213, 44, 185, + 58, 9, 1, 248, 246, 4, 2, 92, 58, 9, 1, 210, 42, 4, 2, 92, 58, 9, 1, 199, + 115, 4, 2, 199, 115, 58, 9, 1, 207, 72, 4, 2, 213, 25, 58, 9, 1, 99, 4, + 105, 185, 248, 233, 23, 2, 213, 25, 58, 9, 1, 252, 0, 233, 46, 9, 1, 252, + 0, 208, 89, 9, 1, 252, 0, 213, 24, 9, 1, 210, 42, 4, 2, 196, 12, 9, 1, + 199, 115, 4, 2, 196, 12, 9, 1, 197, 125, 4, 2, 196, 12, 9, 1, 199, 150, + 4, 2, 196, 12, 9, 1, 222, 5, 4, 2, 196, 12, 9, 1, 231, 87, 4, 115, 185, + 58, 9, 1, 252, 0, 208, 90, 4, 115, 185, 58, 9, 1, 223, 7, 4, 115, 185, + 58, 9, 1, 223, 7, 4, 115, 185, 60, 9, 1, 220, 36, 4, 2, 9, 1, 199, 220, + 58, 9, 1, 230, 224, 9, 2, 233, 74, 192, 75, 9, 2, 137, 233, 74, 192, 75, + 9, 2, 137, 99, 249, 81, 4, 105, 185, 60, 9, 2, 137, 193, 23, 205, 182, 9, + 2, 137, 191, 116, 9, 220, 13, 206, 115, 75, 58, 9, 220, 13, 206, 115, 75, + 60, 9, 200, 207, 60, 9, 220, 13, 243, 11, 60, 9, 220, 13, 206, 115, 75, + 223, 118, 243, 11, 60, 9, 2, 130, 193, 133, 9, 2, 137, 193, 23, 251, 30, + 9, 2, 137, 205, 192, 9, 2, 137, 251, 230, 9, 2, 137, 208, 89, 9, 2, 137, + 213, 25, 4, 222, 52, 9, 2, 130, 213, 25, 4, 222, 52, 9, 2, 137, 193, 23, + 250, 181, 9, 2, 137, 193, 23, 250, 218, 9, 2, 137, 193, 23, 251, 131, 9, + 2, 137, 193, 23, 205, 171, 9, 2, 137, 193, 23, 208, 52, 9, 2, 137, 193, + 23, 193, 157, 9, 2, 137, 232, 157, 217, 51, 9, 2, 137, 3, 205, 187, 9, + 236, 218, 234, 95, 79, 250, 130, 9, 153, 237, 246, 60, 9, 238, 171, 233, + 70, 9, 238, 171, 237, 245, 9, 238, 171, 222, 52, 9, 238, 171, 233, 68, 9, + 238, 171, 237, 243, 9, 238, 171, 222, 50, 9, 163, 91, 75, 58, 9, 163, + 105, 185, 58, 9, 163, 219, 5, 58, 9, 163, 91, 75, 60, 9, 163, 105, 185, + 60, 9, 163, 219, 5, 60, 9, 211, 77, 233, 68, 9, 211, 77, 237, 243, 9, + 211, 77, 222, 50, 9, 2, 137, 193, 133, 9, 233, 71, 4, 206, 188, 9, 233, + 71, 4, 75, 58, 9, 222, 53, 4, 75, 60, 9, 45, 250, 236, 58, 9, 50, 250, + 236, 58, 9, 45, 250, 236, 60, 9, 50, 250, 236, 60, 9, 55, 50, 250, 236, + 58, 9, 55, 50, 250, 236, 93, 4, 236, 140, 9, 50, 250, 236, 93, 4, 236, + 140, 9, 237, 246, 4, 236, 140, 9, 87, 202, 206, 213, 25, 231, 57, 100, 3, + 223, 93, 247, 119, 100, 3, 247, 119, 100, 3, 251, 71, 100, 3, 195, 35, + 100, 1, 203, 40, 65, 100, 1, 65, 100, 1, 252, 206, 100, 1, 68, 100, 1, + 223, 199, 100, 1, 66, 100, 1, 196, 30, 100, 1, 117, 146, 100, 1, 117, + 172, 100, 1, 247, 122, 71, 100, 1, 203, 40, 71, 100, 1, 71, 100, 1, 251, + 236, 100, 1, 247, 122, 74, 100, 1, 203, 40, 74, 100, 1, 74, 100, 1, 250, + 163, 100, 1, 155, 100, 1, 221, 215, 100, 1, 231, 240, 100, 1, 231, 91, + 100, 1, 214, 68, 100, 1, 247, 160, 100, 1, 247, 1, 100, 1, 223, 32, 100, + 1, 222, 252, 100, 1, 212, 101, 100, 1, 197, 132, 100, 1, 197, 120, 100, + 1, 237, 191, 100, 1, 237, 175, 100, 1, 213, 79, 100, 1, 190, 190, 100, 1, + 199, 49, 100, 1, 238, 32, 100, 1, 237, 68, 100, 1, 180, 100, 1, 213, 61, + 100, 1, 168, 100, 1, 209, 228, 100, 1, 249, 153, 100, 1, 248, 203, 100, + 1, 174, 100, 1, 170, 100, 1, 165, 100, 1, 206, 109, 100, 1, 173, 100, 1, + 219, 73, 100, 1, 219, 62, 100, 1, 195, 188, 100, 1, 203, 165, 100, 1, + 201, 175, 100, 1, 188, 100, 1, 140, 100, 18, 3, 211, 151, 100, 18, 3, + 211, 85, 100, 3, 212, 141, 100, 3, 250, 145, 100, 18, 3, 252, 206, 100, + 18, 3, 68, 100, 18, 3, 223, 199, 100, 18, 3, 66, 100, 18, 3, 196, 30, + 100, 18, 3, 117, 146, 100, 18, 3, 117, 206, 110, 100, 18, 3, 247, 122, + 71, 100, 18, 3, 203, 40, 71, 100, 18, 3, 71, 100, 18, 3, 251, 236, 100, + 18, 3, 247, 122, 74, 100, 18, 3, 203, 40, 74, 100, 18, 3, 74, 100, 18, 3, + 250, 163, 100, 3, 195, 40, 100, 18, 3, 208, 207, 71, 100, 18, 3, 250, + 140, 100, 211, 113, 100, 201, 38, 3, 196, 154, 100, 201, 38, 3, 251, 73, + 100, 230, 211, 252, 60, 100, 252, 47, 252, 60, 100, 18, 3, 247, 122, 179, + 71, 100, 18, 3, 196, 152, 100, 18, 3, 196, 29, 100, 1, 208, 96, 100, 1, + 221, 193, 100, 1, 231, 66, 100, 1, 191, 123, 100, 1, 237, 180, 100, 1, + 207, 6, 100, 1, 233, 109, 100, 1, 191, 175, 100, 1, 117, 206, 110, 100, + 1, 117, 219, 74, 100, 18, 3, 117, 172, 100, 18, 3, 117, 219, 74, 100, + 237, 238, 100, 55, 237, 238, 100, 17, 191, 77, 100, 17, 107, 100, 17, + 109, 100, 17, 138, 100, 17, 134, 100, 17, 149, 100, 17, 169, 100, 17, + 175, 100, 17, 171, 100, 17, 178, 100, 252, 68, 56, 100, 3, 137, 201, 246, + 236, 140, 100, 1, 247, 122, 65, 100, 1, 211, 151, 100, 1, 211, 85, 100, + 1, 250, 140, 100, 1, 196, 152, 100, 1, 196, 29, 100, 1, 217, 43, 237, + 191, 100, 1, 191, 71, 100, 1, 88, 170, 100, 1, 231, 127, 100, 1, 222, + 230, 100, 1, 231, 11, 201, 63, 100, 1, 237, 181, 100, 1, 249, 53, 248, + 225, 251, 100, 248, 225, 3, 247, 119, 248, 225, 3, 251, 71, 248, 225, 3, + 195, 35, 248, 225, 1, 65, 248, 225, 1, 252, 206, 248, 225, 1, 68, 248, + 225, 1, 223, 199, 248, 225, 1, 66, 248, 225, 1, 196, 30, 248, 225, 1, + 117, 146, 248, 225, 1, 117, 172, 248, 225, 1, 71, 248, 225, 1, 251, 236, + 248, 225, 1, 74, 248, 225, 1, 250, 163, 248, 225, 1, 155, 248, 225, 1, + 221, 215, 248, 225, 1, 231, 240, 248, 225, 1, 231, 91, 248, 225, 1, 214, + 68, 248, 225, 1, 247, 160, 248, 225, 1, 247, 1, 248, 225, 1, 223, 32, + 248, 225, 1, 222, 252, 248, 225, 1, 212, 101, 248, 225, 1, 197, 132, 248, + 225, 1, 197, 120, 248, 225, 1, 237, 191, 248, 225, 1, 237, 175, 248, 225, + 1, 213, 79, 248, 225, 1, 190, 190, 248, 225, 1, 199, 49, 248, 225, 1, + 238, 32, 248, 225, 1, 237, 68, 248, 225, 1, 180, 248, 225, 1, 168, 248, + 225, 1, 209, 228, 248, 225, 1, 249, 153, 248, 225, 1, 248, 203, 248, 225, + 1, 174, 248, 225, 1, 170, 248, 225, 1, 165, 248, 225, 1, 173, 248, 225, + 1, 203, 165, 248, 225, 1, 201, 175, 248, 225, 1, 188, 248, 225, 1, 140, + 248, 225, 3, 212, 141, 248, 225, 3, 250, 145, 248, 225, 18, 3, 252, 206, + 248, 225, 18, 3, 68, 248, 225, 18, 3, 223, 199, 248, 225, 18, 3, 66, 248, + 225, 18, 3, 196, 30, 248, 225, 18, 3, 117, 146, 248, 225, 18, 3, 117, + 206, 110, 248, 225, 18, 3, 71, 248, 225, 18, 3, 251, 236, 248, 225, 18, + 3, 74, 248, 225, 18, 3, 250, 163, 248, 225, 3, 195, 40, 248, 225, 1, 221, + 204, 190, 190, 248, 225, 250, 164, 219, 198, 77, 248, 225, 1, 206, 109, + 248, 225, 1, 207, 6, 248, 225, 1, 191, 175, 248, 225, 1, 117, 206, 110, + 248, 225, 1, 117, 219, 74, 248, 225, 18, 3, 117, 172, 248, 225, 18, 3, + 117, 219, 74, 248, 225, 17, 191, 77, 248, 225, 17, 107, 248, 225, 17, + 109, 248, 225, 17, 138, 248, 225, 17, 134, 248, 225, 17, 149, 248, 225, + 17, 169, 248, 225, 17, 175, 248, 225, 17, 171, 248, 225, 17, 178, 248, + 225, 1, 207, 186, 4, 82, 237, 38, 248, 225, 1, 207, 186, 4, 110, 237, 38, + 248, 225, 206, 36, 77, 248, 225, 206, 36, 56, 248, 225, 238, 170, 212, + 133, 107, 248, 225, 238, 170, 212, 133, 109, 248, 225, 238, 170, 212, + 133, 138, 248, 225, 238, 170, 212, 133, 134, 248, 225, 238, 170, 212, + 133, 91, 219, 181, 199, 39, 199, 34, 237, 99, 248, 225, 238, 170, 237, + 100, 202, 130, 248, 225, 223, 54, 248, 225, 231, 207, 77, 248, 225, 1, + 195, 150, 251, 71, 248, 225, 252, 68, 56, 248, 225, 205, 138, 77, 230, + 144, 3, 252, 41, 248, 167, 230, 144, 3, 248, 167, 230, 144, 3, 195, 35, + 230, 144, 1, 65, 230, 144, 1, 252, 206, 230, 144, 1, 68, 230, 144, 1, + 223, 199, 230, 144, 1, 66, 230, 144, 1, 196, 30, 230, 144, 1, 234, 188, + 230, 144, 1, 251, 236, 230, 144, 1, 211, 87, 230, 144, 1, 250, 163, 230, + 144, 1, 155, 230, 144, 1, 221, 215, 230, 144, 1, 231, 240, 230, 144, 1, + 231, 91, 230, 144, 1, 214, 68, 230, 144, 1, 247, 160, 230, 144, 1, 247, + 1, 230, 144, 1, 223, 32, 230, 144, 1, 222, 252, 230, 144, 1, 212, 101, + 230, 144, 1, 197, 132, 230, 144, 1, 197, 120, 230, 144, 1, 237, 191, 230, + 144, 1, 237, 175, 230, 144, 1, 213, 79, 230, 144, 1, 190, 190, 230, 144, + 1, 199, 49, 230, 144, 1, 238, 32, 230, 144, 1, 237, 68, 230, 144, 1, 180, + 230, 144, 1, 168, 230, 144, 1, 209, 228, 230, 144, 1, 249, 153, 230, 144, + 1, 248, 203, 230, 144, 1, 174, 230, 144, 1, 170, 230, 144, 1, 165, 230, + 144, 1, 173, 230, 144, 1, 219, 73, 230, 144, 1, 195, 188, 230, 144, 1, + 203, 165, 230, 144, 1, 188, 230, 144, 1, 140, 230, 144, 3, 212, 141, 230, + 144, 18, 3, 252, 206, 230, 144, 18, 3, 68, 230, 144, 18, 3, 223, 199, + 230, 144, 18, 3, 66, 230, 144, 18, 3, 196, 30, 230, 144, 18, 3, 234, 188, + 230, 144, 18, 3, 251, 236, 230, 144, 18, 3, 211, 87, 230, 144, 18, 3, + 250, 163, 230, 144, 3, 195, 40, 230, 144, 3, 196, 157, 230, 144, 1, 221, + 193, 230, 144, 1, 231, 66, 230, 144, 1, 191, 123, 230, 144, 1, 206, 109, + 230, 144, 1, 233, 109, 230, 144, 17, 191, 77, 230, 144, 17, 107, 230, + 144, 17, 109, 230, 144, 17, 138, 230, 144, 17, 134, 230, 144, 17, 149, + 230, 144, 17, 169, 230, 144, 17, 175, 230, 144, 17, 171, 230, 144, 17, + 178, 230, 144, 198, 133, 230, 144, 252, 40, 230, 144, 223, 75, 230, 144, + 196, 58, 230, 144, 234, 148, 211, 92, 230, 144, 3, 192, 115, 230, 144, + 252, 68, 56, 230, 161, 3, 247, 119, 230, 161, 3, 251, 71, 230, 161, 3, + 195, 35, 230, 161, 1, 65, 230, 161, 1, 252, 206, 230, 161, 1, 68, 230, + 161, 1, 223, 199, 230, 161, 1, 66, 230, 161, 1, 196, 30, 230, 161, 1, + 117, 146, 230, 161, 1, 117, 172, 230, 161, 18, 247, 122, 71, 230, 161, 1, + 71, 230, 161, 1, 251, 236, 230, 161, 18, 247, 122, 74, 230, 161, 1, 74, + 230, 161, 1, 250, 163, 230, 161, 1, 155, 230, 161, 1, 221, 215, 230, 161, + 1, 231, 240, 230, 161, 1, 231, 91, 230, 161, 1, 214, 68, 230, 161, 1, + 247, 160, 230, 161, 1, 247, 1, 230, 161, 1, 223, 32, 230, 161, 1, 222, + 252, 230, 161, 1, 212, 101, 230, 161, 1, 197, 132, 230, 161, 1, 197, 120, + 230, 161, 1, 237, 191, 230, 161, 1, 237, 175, 230, 161, 1, 213, 79, 230, + 161, 1, 190, 190, 230, 161, 1, 199, 49, 230, 161, 1, 238, 32, 230, 161, + 1, 237, 68, 230, 161, 1, 180, 230, 161, 1, 168, 230, 161, 1, 209, 228, + 230, 161, 1, 249, 153, 230, 161, 1, 248, 203, 230, 161, 1, 174, 230, 161, + 1, 170, 230, 161, 1, 165, 230, 161, 1, 173, 230, 161, 1, 219, 73, 230, + 161, 1, 195, 188, 230, 161, 1, 203, 165, 230, 161, 1, 201, 175, 230, 161, + 1, 188, 230, 161, 1, 140, 230, 161, 3, 212, 141, 230, 161, 3, 250, 145, + 230, 161, 18, 3, 252, 206, 230, 161, 18, 3, 68, 230, 161, 18, 3, 223, + 199, 230, 161, 18, 3, 66, 230, 161, 18, 3, 196, 30, 230, 161, 18, 3, 117, + 146, 230, 161, 18, 3, 117, 206, 110, 230, 161, 18, 3, 247, 122, 71, 230, + 161, 18, 3, 71, 230, 161, 18, 3, 251, 236, 230, 161, 18, 3, 247, 122, 74, + 230, 161, 18, 3, 74, 230, 161, 18, 3, 250, 163, 230, 161, 3, 195, 40, + 230, 161, 211, 113, 230, 161, 1, 117, 206, 110, 230, 161, 1, 117, 219, + 74, 230, 161, 18, 3, 117, 172, 230, 161, 18, 3, 117, 219, 74, 230, 161, + 17, 191, 77, 230, 161, 17, 107, 230, 161, 17, 109, 230, 161, 17, 138, + 230, 161, 17, 134, 230, 161, 17, 149, 230, 161, 17, 169, 230, 161, 17, + 175, 230, 161, 17, 171, 230, 161, 17, 178, 230, 161, 252, 68, 56, 230, + 161, 206, 36, 56, 230, 161, 1, 191, 71, 230, 161, 3, 200, 206, 230, 161, + 3, 203, 155, 230, 161, 3, 217, 139, 230, 161, 3, 198, 224, 212, 142, 58, + 230, 161, 3, 243, 11, 212, 142, 58, 230, 161, 3, 197, 15, 212, 142, 58, + 211, 45, 3, 247, 119, 211, 45, 3, 251, 71, 211, 45, 3, 195, 35, 211, 45, + 1, 65, 211, 45, 1, 252, 206, 211, 45, 1, 68, 211, 45, 1, 223, 199, 211, + 45, 1, 66, 211, 45, 1, 196, 30, 211, 45, 1, 117, 146, 211, 45, 1, 117, + 172, 211, 45, 1, 71, 211, 45, 1, 251, 236, 211, 45, 1, 74, 211, 45, 1, + 250, 163, 211, 45, 1, 155, 211, 45, 1, 221, 215, 211, 45, 1, 231, 240, + 211, 45, 1, 231, 91, 211, 45, 1, 214, 68, 211, 45, 1, 247, 160, 211, 45, + 1, 247, 1, 211, 45, 1, 223, 32, 211, 45, 1, 222, 252, 211, 45, 1, 212, + 101, 211, 45, 1, 197, 132, 211, 45, 1, 197, 120, 211, 45, 1, 237, 191, + 211, 45, 1, 237, 175, 211, 45, 1, 213, 79, 211, 45, 1, 190, 190, 211, 45, + 1, 199, 49, 211, 45, 1, 238, 32, 211, 45, 1, 237, 68, 211, 45, 1, 180, + 211, 45, 1, 168, 211, 45, 1, 209, 228, 211, 45, 1, 249, 153, 211, 45, 1, + 248, 203, 211, 45, 1, 174, 211, 45, 1, 170, 211, 45, 1, 165, 211, 45, 1, + 173, 211, 45, 1, 219, 73, 211, 45, 1, 195, 188, 211, 45, 1, 203, 165, + 211, 45, 1, 201, 175, 211, 45, 1, 188, 211, 45, 1, 140, 211, 45, 3, 212, + 141, 211, 45, 3, 250, 145, 211, 45, 18, 3, 252, 206, 211, 45, 18, 3, 68, + 211, 45, 18, 3, 223, 199, 211, 45, 18, 3, 66, 211, 45, 18, 3, 196, 30, + 211, 45, 18, 3, 117, 146, 211, 45, 18, 3, 117, 206, 110, 211, 45, 18, 3, + 71, 211, 45, 18, 3, 251, 236, 211, 45, 18, 3, 74, 211, 45, 18, 3, 250, + 163, 211, 45, 3, 195, 40, 211, 45, 3, 210, 254, 211, 45, 251, 237, 219, + 198, 77, 211, 45, 250, 164, 219, 198, 77, 211, 45, 1, 206, 109, 211, 45, + 1, 207, 6, 211, 45, 1, 191, 175, 211, 45, 1, 117, 206, 110, 211, 45, 1, + 117, 219, 74, 211, 45, 18, 3, 117, 172, 211, 45, 18, 3, 117, 219, 74, + 211, 45, 17, 191, 77, 211, 45, 17, 107, 211, 45, 17, 109, 211, 45, 17, + 138, 211, 45, 17, 134, 211, 45, 17, 149, 211, 45, 17, 169, 211, 45, 17, + 175, 211, 45, 17, 171, 211, 45, 17, 178, 211, 45, 223, 54, 211, 45, 1, + 193, 190, 211, 45, 232, 118, 91, 208, 22, 211, 45, 232, 118, 91, 230, 70, + 211, 45, 232, 118, 115, 208, 20, 211, 45, 232, 118, 91, 202, 128, 211, + 45, 232, 118, 91, 234, 159, 211, 45, 232, 118, 115, 202, 125, 44, 3, 251, + 71, 44, 3, 195, 35, 44, 1, 65, 44, 1, 252, 206, 44, 1, 68, 44, 1, 223, + 199, 44, 1, 66, 44, 1, 196, 30, 44, 1, 71, 44, 1, 234, 188, 44, 1, 251, + 236, 44, 1, 74, 44, 1, 211, 87, 44, 1, 250, 163, 44, 1, 155, 44, 1, 214, + 68, 44, 1, 247, 160, 44, 1, 223, 32, 44, 1, 212, 101, 44, 1, 197, 132, + 44, 1, 213, 79, 44, 1, 190, 190, 44, 1, 180, 44, 1, 213, 61, 44, 1, 168, + 44, 1, 174, 44, 1, 170, 44, 1, 165, 44, 1, 206, 109, 44, 1, 173, 44, 1, + 219, 73, 44, 1, 219, 62, 44, 1, 195, 188, 44, 1, 203, 165, 44, 1, 201, + 175, 44, 1, 188, 44, 1, 140, 44, 18, 3, 252, 206, 44, 18, 3, 68, 44, 18, + 3, 223, 199, 44, 18, 3, 66, 44, 18, 3, 196, 30, 44, 18, 3, 71, 44, 18, 3, + 234, 188, 44, 18, 3, 251, 236, 44, 18, 3, 74, 44, 18, 3, 211, 87, 44, 18, + 3, 250, 163, 44, 3, 195, 40, 44, 211, 113, 44, 250, 164, 219, 198, 77, + 44, 17, 191, 77, 44, 17, 107, 44, 17, 109, 44, 17, 138, 44, 17, 134, 44, + 17, 149, 44, 17, 169, 44, 17, 175, 44, 17, 171, 44, 17, 178, 44, 31, 199, + 95, 44, 31, 91, 228, 140, 44, 31, 91, 189, 44, 237, 204, 56, 44, 215, + 214, 56, 44, 192, 78, 56, 44, 237, 142, 56, 44, 238, 230, 56, 44, 250, + 220, 93, 56, 44, 206, 36, 56, 44, 31, 56, 199, 99, 3, 33, 247, 120, 58, + 199, 99, 3, 247, 119, 199, 99, 3, 251, 71, 199, 99, 3, 195, 35, 199, 99, + 3, 33, 251, 72, 58, 199, 99, 1, 65, 199, 99, 1, 252, 206, 199, 99, 1, 68, + 199, 99, 1, 223, 199, 199, 99, 1, 66, 199, 99, 1, 196, 30, 199, 99, 1, + 117, 146, 199, 99, 1, 117, 172, 199, 99, 1, 71, 199, 99, 1, 234, 188, + 199, 99, 1, 251, 236, 199, 99, 1, 74, 199, 99, 1, 211, 87, 199, 99, 1, + 250, 163, 199, 99, 1, 155, 199, 99, 1, 221, 215, 199, 99, 1, 231, 240, + 199, 99, 1, 231, 91, 199, 99, 1, 214, 68, 199, 99, 1, 247, 160, 199, 99, + 1, 247, 1, 199, 99, 1, 223, 32, 199, 99, 1, 222, 252, 199, 99, 1, 212, + 101, 199, 99, 1, 197, 132, 199, 99, 1, 197, 120, 199, 99, 1, 237, 191, + 199, 99, 1, 237, 175, 199, 99, 1, 213, 79, 199, 99, 1, 190, 190, 199, 99, + 1, 199, 49, 199, 99, 1, 238, 32, 199, 99, 1, 237, 68, 199, 99, 1, 180, + 199, 99, 1, 168, 199, 99, 1, 209, 228, 199, 99, 1, 249, 153, 199, 99, 1, + 248, 203, 199, 99, 1, 174, 199, 99, 1, 170, 199, 99, 1, 165, 199, 99, 1, + 206, 109, 199, 99, 1, 173, 199, 99, 1, 219, 73, 199, 99, 1, 219, 62, 199, + 99, 1, 195, 188, 199, 99, 1, 203, 165, 199, 99, 1, 201, 175, 199, 99, 1, + 188, 199, 99, 1, 140, 199, 99, 3, 212, 141, 199, 99, 3, 250, 145, 199, + 99, 18, 3, 252, 206, 199, 99, 18, 3, 68, 199, 99, 18, 3, 223, 199, 199, + 99, 18, 3, 66, 199, 99, 18, 3, 196, 30, 199, 99, 18, 3, 117, 146, 199, + 99, 18, 3, 117, 206, 110, 199, 99, 18, 3, 71, 199, 99, 18, 3, 234, 188, + 199, 99, 18, 3, 251, 236, 199, 99, 18, 3, 74, 199, 99, 18, 3, 211, 87, + 199, 99, 18, 3, 250, 163, 199, 99, 3, 195, 40, 199, 99, 219, 198, 77, + 199, 99, 251, 237, 219, 198, 77, 199, 99, 1, 197, 168, 199, 99, 1, 235, + 35, 199, 99, 1, 206, 90, 199, 99, 1, 214, 232, 209, 46, 199, 99, 1, 117, + 206, 110, 199, 99, 1, 117, 219, 74, 199, 99, 18, 3, 117, 172, 199, 99, + 18, 3, 117, 219, 74, 199, 99, 17, 191, 77, 199, 99, 17, 107, 199, 99, 17, + 109, 199, 99, 17, 138, 199, 99, 17, 134, 199, 99, 17, 149, 199, 99, 17, + 169, 199, 99, 17, 175, 199, 99, 17, 171, 199, 99, 17, 178, 199, 99, 3, + 202, 210, 199, 99, 232, 118, 17, 191, 78, 40, 211, 155, 208, 253, 79, + 134, 199, 99, 232, 118, 17, 91, 40, 211, 155, 208, 253, 79, 134, 199, 99, + 232, 118, 17, 105, 40, 211, 155, 208, 253, 79, 134, 199, 99, 232, 118, + 17, 115, 40, 211, 155, 208, 253, 79, 134, 199, 99, 232, 118, 17, 91, 40, + 233, 229, 208, 253, 79, 134, 199, 99, 232, 118, 17, 105, 40, 233, 229, + 208, 253, 79, 134, 199, 99, 232, 118, 17, 115, 40, 233, 229, 208, 253, + 79, 134, 199, 99, 3, 197, 48, 222, 81, 3, 201, 246, 247, 119, 222, 81, 3, + 247, 119, 222, 81, 3, 251, 71, 222, 81, 3, 195, 35, 222, 81, 3, 202, 210, + 222, 81, 1, 65, 222, 81, 1, 252, 206, 222, 81, 1, 68, 222, 81, 1, 223, + 199, 222, 81, 1, 66, 222, 81, 1, 196, 30, 222, 81, 1, 117, 146, 222, 81, + 1, 117, 172, 222, 81, 1, 71, 222, 81, 1, 234, 188, 222, 81, 1, 251, 236, + 222, 81, 1, 74, 222, 81, 1, 211, 87, 222, 81, 1, 250, 163, 222, 81, 1, + 155, 222, 81, 1, 221, 215, 222, 81, 1, 231, 240, 222, 81, 1, 231, 91, + 222, 81, 1, 214, 68, 222, 81, 1, 247, 160, 222, 81, 1, 247, 1, 222, 81, + 1, 223, 32, 222, 81, 1, 222, 252, 222, 81, 1, 212, 101, 222, 81, 1, 197, + 132, 222, 81, 1, 197, 120, 222, 81, 1, 237, 191, 222, 81, 1, 237, 175, + 222, 81, 1, 213, 79, 222, 81, 1, 190, 190, 222, 81, 1, 199, 49, 222, 81, + 1, 238, 32, 222, 81, 1, 237, 68, 222, 81, 1, 180, 222, 81, 1, 168, 222, + 81, 1, 209, 228, 222, 81, 1, 249, 153, 222, 81, 1, 248, 203, 222, 81, 1, + 174, 222, 81, 1, 170, 222, 81, 1, 165, 222, 81, 1, 206, 109, 222, 81, 1, + 173, 222, 81, 1, 219, 73, 222, 81, 1, 195, 188, 222, 81, 1, 203, 165, + 222, 81, 1, 201, 175, 222, 81, 1, 188, 222, 81, 1, 140, 222, 81, 3, 212, + 141, 222, 81, 3, 250, 145, 222, 81, 18, 3, 252, 206, 222, 81, 18, 3, 68, + 222, 81, 18, 3, 223, 199, 222, 81, 18, 3, 66, 222, 81, 18, 3, 196, 30, + 222, 81, 18, 3, 117, 146, 222, 81, 18, 3, 117, 206, 110, 222, 81, 18, 3, + 71, 222, 81, 18, 3, 234, 188, 222, 81, 18, 3, 251, 236, 222, 81, 18, 3, + 74, 222, 81, 18, 3, 211, 87, 222, 81, 18, 3, 250, 163, 222, 81, 3, 195, + 40, 222, 81, 219, 198, 77, 222, 81, 251, 237, 219, 198, 77, 222, 81, 1, + 214, 232, 209, 46, 222, 81, 1, 233, 109, 222, 81, 1, 117, 206, 110, 222, + 81, 1, 117, 219, 74, 222, 81, 18, 3, 117, 172, 222, 81, 18, 3, 117, 219, + 74, 222, 81, 17, 191, 77, 222, 81, 17, 107, 222, 81, 17, 109, 222, 81, + 17, 138, 222, 81, 17, 134, 222, 81, 17, 149, 222, 81, 17, 169, 222, 81, + 17, 175, 222, 81, 17, 171, 222, 81, 17, 178, 222, 81, 3, 222, 237, 222, + 81, 3, 196, 75, 222, 81, 3, 33, 251, 72, 93, 183, 142, 3, 33, 251, 72, + 58, 142, 3, 247, 119, 142, 3, 251, 71, 142, 3, 195, 35, 142, 1, 195, 150, + 251, 71, 142, 1, 65, 142, 1, 252, 206, 142, 1, 68, 142, 1, 223, 199, 142, + 1, 66, 142, 1, 196, 30, 142, 1, 117, 146, 142, 1, 117, 172, 142, 1, 71, + 142, 1, 234, 188, 142, 1, 251, 236, 142, 1, 74, 142, 1, 211, 87, 142, 1, + 250, 163, 142, 1, 155, 142, 1, 221, 215, 142, 1, 231, 240, 142, 1, 231, + 91, 142, 1, 214, 68, 142, 1, 247, 160, 142, 1, 247, 1, 142, 1, 223, 32, + 142, 1, 222, 252, 142, 1, 212, 101, 142, 1, 197, 132, 142, 1, 197, 120, + 142, 1, 237, 191, 142, 1, 237, 175, 142, 1, 213, 79, 142, 1, 190, 190, + 142, 1, 199, 49, 142, 1, 238, 32, 142, 1, 237, 68, 142, 1, 180, 142, 1, + 213, 61, 142, 1, 168, 142, 1, 209, 228, 142, 1, 249, 153, 142, 1, 248, + 203, 142, 1, 174, 142, 1, 170, 142, 1, 165, 142, 1, 206, 109, 142, 1, + 173, 142, 1, 219, 73, 142, 1, 219, 62, 142, 1, 195, 188, 142, 1, 203, + 165, 142, 1, 201, 175, 142, 1, 188, 142, 1, 140, 142, 1, 197, 101, 142, + 3, 81, 249, 88, 195, 40, 142, 3, 243, 4, 195, 40, 142, 3, 250, 145, 142, + 18, 3, 252, 206, 142, 18, 3, 68, 142, 18, 3, 223, 199, 142, 18, 3, 66, + 142, 18, 3, 196, 30, 142, 18, 3, 117, 146, 142, 18, 3, 117, 206, 110, + 142, 18, 3, 71, 142, 18, 3, 234, 188, 142, 18, 3, 251, 236, 142, 18, 3, + 74, 142, 18, 3, 211, 87, 142, 18, 3, 250, 163, 142, 3, 195, 40, 142, 1, + 75, 207, 45, 142, 3, 210, 130, 142, 1, 243, 84, 218, 168, 142, 1, 243, + 84, 192, 159, 142, 1, 243, 84, 219, 63, 142, 250, 164, 219, 198, 77, 142, + 232, 118, 91, 211, 100, 142, 232, 118, 91, 232, 139, 142, 232, 118, 115, + 234, 155, 142, 232, 118, 91, 197, 35, 142, 232, 118, 91, 199, 86, 142, + 232, 118, 115, 197, 34, 142, 232, 118, 91, 233, 18, 142, 1, 251, 14, 223, + 199, 142, 1, 117, 206, 110, 142, 1, 117, 219, 74, 142, 18, 3, 117, 172, + 142, 18, 3, 117, 219, 74, 142, 17, 191, 77, 142, 17, 107, 142, 17, 109, + 142, 17, 138, 142, 17, 134, 142, 17, 149, 142, 17, 169, 142, 17, 175, + 142, 17, 171, 142, 17, 178, 142, 31, 199, 95, 142, 31, 91, 228, 140, 142, + 31, 91, 189, 142, 232, 118, 91, 208, 22, 142, 232, 118, 91, 230, 70, 142, + 232, 118, 115, 208, 20, 142, 232, 118, 91, 202, 128, 142, 232, 118, 91, + 234, 159, 142, 232, 118, 115, 202, 125, 142, 237, 209, 77, 142, 1, 243, + 84, 213, 80, 142, 1, 243, 84, 215, 61, 142, 1, 243, 84, 206, 110, 142, 1, + 243, 84, 172, 142, 1, 243, 84, 219, 74, 142, 1, 243, 84, 222, 152, 166, + 3, 247, 119, 166, 3, 251, 70, 166, 3, 195, 34, 166, 1, 250, 129, 166, 1, + 252, 159, 166, 1, 252, 5, 166, 1, 252, 20, 166, 1, 223, 43, 166, 1, 223, + 198, 166, 1, 196, 20, 166, 1, 196, 24, 166, 1, 223, 70, 166, 1, 223, 71, + 166, 1, 223, 182, 166, 1, 223, 184, 166, 1, 233, 196, 166, 1, 234, 183, + 166, 1, 251, 219, 166, 1, 210, 241, 166, 1, 211, 80, 166, 1, 250, 148, + 166, 1, 251, 163, 222, 27, 166, 1, 217, 119, 222, 27, 166, 1, 251, 163, + 231, 185, 166, 1, 217, 119, 231, 185, 166, 1, 222, 80, 214, 247, 166, 1, + 205, 132, 231, 185, 166, 1, 251, 163, 247, 68, 166, 1, 217, 119, 247, 68, + 166, 1, 251, 163, 223, 13, 166, 1, 217, 119, 223, 13, 166, 1, 199, 241, + 214, 247, 166, 1, 199, 241, 205, 131, 214, 248, 166, 1, 205, 132, 223, + 13, 166, 1, 251, 163, 197, 128, 166, 1, 217, 119, 197, 128, 166, 1, 251, + 163, 237, 182, 166, 1, 217, 119, 237, 182, 166, 1, 215, 92, 214, 197, + 166, 1, 205, 132, 237, 182, 166, 1, 251, 163, 199, 153, 166, 1, 217, 119, + 199, 153, 166, 1, 251, 163, 237, 202, 166, 1, 217, 119, 237, 202, 166, 1, + 237, 234, 214, 197, 166, 1, 205, 132, 237, 202, 166, 1, 251, 163, 210, + 71, 166, 1, 217, 119, 210, 71, 166, 1, 251, 163, 249, 55, 166, 1, 217, + 119, 249, 55, 166, 1, 217, 19, 166, 1, 251, 143, 249, 55, 166, 1, 192, + 85, 166, 1, 207, 121, 166, 1, 237, 234, 219, 247, 166, 1, 195, 156, 166, + 1, 199, 241, 205, 102, 166, 1, 215, 92, 205, 102, 166, 1, 237, 234, 205, + 102, 166, 1, 229, 251, 166, 1, 215, 92, 219, 247, 166, 1, 233, 61, 166, + 3, 251, 205, 166, 18, 3, 252, 15, 166, 18, 3, 221, 240, 252, 22, 166, 18, + 3, 237, 11, 252, 22, 166, 18, 3, 221, 240, 223, 67, 166, 18, 3, 237, 11, + 223, 67, 166, 18, 3, 221, 240, 210, 219, 166, 18, 3, 237, 11, 210, 219, + 166, 18, 3, 231, 229, 166, 18, 3, 221, 46, 166, 18, 3, 237, 11, 221, 46, + 166, 18, 3, 221, 48, 237, 120, 166, 18, 3, 221, 47, 230, 92, 252, 15, + 166, 18, 3, 221, 47, 230, 92, 237, 11, 252, 15, 166, 18, 3, 221, 47, 230, + 92, 231, 184, 166, 18, 3, 231, 184, 166, 219, 86, 17, 191, 77, 166, 219, + 86, 17, 107, 166, 219, 86, 17, 109, 166, 219, 86, 17, 138, 166, 219, 86, + 17, 134, 166, 219, 86, 17, 149, 166, 219, 86, 17, 169, 166, 219, 86, 17, + 175, 166, 219, 86, 17, 171, 166, 219, 86, 17, 178, 166, 18, 3, 237, 11, + 231, 229, 166, 18, 3, 237, 11, 231, 184, 166, 208, 152, 220, 209, 199, + 44, 246, 240, 221, 68, 222, 102, 199, 44, 246, 240, 221, 184, 221, 209, + 199, 44, 246, 240, 221, 184, 221, 174, 199, 44, 246, 240, 221, 184, 221, + 169, 199, 44, 246, 240, 221, 184, 221, 179, 199, 44, 246, 240, 221, 184, + 207, 143, 199, 44, 246, 240, 213, 250, 213, 237, 199, 44, 246, 240, 243, + 69, 246, 246, 199, 44, 246, 240, 243, 69, 243, 79, 199, 44, 246, 240, + 243, 69, 246, 245, 199, 44, 246, 240, 202, 47, 202, 46, 199, 44, 246, + 240, 243, 69, 243, 65, 199, 44, 246, 240, 192, 13, 192, 20, 199, 44, 246, + 240, 236, 175, 246, 254, 199, 44, 246, 240, 119, 210, 87, 199, 44, 246, + 240, 198, 242, 199, 38, 199, 44, 246, 240, 198, 242, 214, 222, 199, 44, + 246, 240, 198, 242, 209, 188, 199, 44, 246, 240, 213, 44, 214, 102, 199, + 44, 246, 240, 236, 175, 237, 121, 199, 44, 246, 240, 119, 199, 184, 199, + 44, 246, 240, 198, 242, 198, 207, 199, 44, 246, 240, 198, 242, 199, 45, + 199, 44, 246, 240, 198, 242, 198, 236, 199, 44, 246, 240, 213, 44, 212, + 178, 199, 44, 246, 240, 248, 112, 249, 118, 199, 44, 246, 240, 209, 74, + 209, 110, 199, 44, 246, 240, 209, 200, 209, 190, 199, 44, 246, 240, 232, + 176, 233, 109, 199, 44, 246, 240, 209, 200, 209, 221, 199, 44, 246, 240, + 232, 176, 233, 80, 199, 44, 246, 240, 209, 200, 205, 146, 199, 44, 246, + 240, 216, 13, 174, 199, 44, 246, 240, 192, 13, 192, 116, 199, 44, 246, + 240, 206, 163, 206, 61, 199, 44, 246, 240, 206, 68, 199, 44, 246, 240, + 219, 44, 219, 105, 199, 44, 246, 240, 218, 225, 199, 44, 246, 240, 193, + 49, 193, 175, 199, 44, 246, 240, 202, 47, 205, 167, 199, 44, 246, 240, + 202, 47, 206, 32, 199, 44, 246, 240, 202, 47, 200, 251, 199, 44, 246, + 240, 229, 24, 229, 122, 199, 44, 246, 240, 219, 44, 243, 47, 199, 44, + 246, 240, 187, 251, 122, 199, 44, 246, 240, 229, 24, 213, 34, 199, 44, + 246, 240, 210, 194, 199, 44, 246, 240, 205, 126, 65, 199, 44, 246, 240, + 217, 113, 230, 55, 199, 44, 246, 240, 205, 126, 252, 206, 199, 44, 246, + 240, 205, 126, 251, 149, 199, 44, 246, 240, 205, 126, 68, 199, 44, 246, + 240, 205, 126, 223, 199, 199, 44, 246, 240, 205, 126, 196, 152, 199, 44, + 246, 240, 205, 126, 196, 149, 199, 44, 246, 240, 205, 126, 66, 199, 44, + 246, 240, 205, 126, 196, 30, 199, 44, 246, 240, 209, 202, 199, 44, 238, + 170, 16, 249, 119, 199, 44, 246, 240, 205, 126, 71, 199, 44, 246, 240, + 205, 126, 252, 25, 199, 44, 246, 240, 205, 126, 74, 199, 44, 246, 240, + 205, 126, 251, 237, 217, 107, 199, 44, 246, 240, 205, 126, 251, 237, 217, + 108, 199, 44, 246, 240, 220, 39, 199, 44, 246, 240, 217, 104, 199, 44, + 246, 240, 217, 105, 199, 44, 246, 240, 217, 113, 234, 147, 199, 44, 246, + 240, 217, 113, 198, 241, 199, 44, 246, 240, 217, 113, 197, 244, 199, 44, + 246, 240, 217, 113, 243, 132, 199, 44, 246, 240, 199, 36, 199, 44, 246, + 240, 213, 183, 199, 44, 246, 240, 192, 110, 199, 44, 246, 240, 232, 164, + 199, 44, 17, 191, 77, 199, 44, 17, 107, 199, 44, 17, 109, 199, 44, 17, + 138, 199, 44, 17, 134, 199, 44, 17, 149, 199, 44, 17, 169, 199, 44, 17, + 175, 199, 44, 17, 171, 199, 44, 17, 178, 199, 44, 246, 240, 251, 117, + 199, 44, 246, 240, 221, 180, 220, 17, 1, 221, 67, 220, 17, 1, 221, 184, + 200, 195, 220, 17, 1, 221, 184, 199, 197, 220, 17, 1, 210, 187, 231, 91, + 220, 17, 1, 213, 249, 220, 17, 1, 242, 99, 220, 17, 1, 210, 187, 247, 1, + 220, 17, 1, 202, 47, 199, 197, 220, 17, 1, 210, 187, 222, 252, 220, 17, + 1, 212, 65, 220, 17, 1, 210, 187, 212, 101, 220, 17, 1, 210, 187, 197, + 132, 220, 17, 1, 210, 187, 197, 120, 220, 17, 1, 210, 187, 237, 191, 220, + 17, 1, 210, 187, 237, 175, 220, 17, 1, 210, 187, 213, 79, 220, 17, 1, + 236, 174, 220, 17, 1, 159, 220, 17, 1, 198, 242, 200, 195, 220, 17, 1, + 198, 242, 199, 197, 220, 17, 1, 210, 187, 237, 68, 220, 17, 1, 213, 43, + 220, 17, 1, 248, 111, 220, 17, 1, 209, 73, 220, 17, 1, 209, 200, 200, + 195, 220, 17, 1, 232, 176, 199, 197, 220, 17, 1, 209, 200, 199, 197, 220, + 17, 1, 232, 176, 200, 195, 220, 17, 1, 210, 187, 248, 203, 220, 17, 1, + 216, 12, 220, 17, 1, 192, 12, 220, 17, 1, 219, 44, 219, 105, 220, 17, 1, + 219, 44, 219, 2, 220, 17, 1, 193, 48, 220, 17, 1, 205, 134, 203, 165, + 220, 17, 1, 205, 134, 201, 175, 220, 17, 1, 202, 47, 200, 195, 220, 17, + 1, 229, 24, 200, 195, 220, 17, 1, 210, 187, 219, 73, 220, 17, 1, 74, 220, + 17, 1, 229, 24, 199, 197, 220, 17, 234, 120, 220, 17, 18, 3, 65, 220, 17, + 18, 3, 217, 113, 222, 87, 220, 17, 18, 3, 252, 206, 220, 17, 18, 3, 251, + 149, 220, 17, 18, 3, 68, 220, 17, 18, 3, 223, 199, 220, 17, 18, 3, 192, + 159, 220, 17, 18, 3, 191, 176, 220, 17, 18, 3, 66, 220, 17, 18, 3, 196, + 30, 220, 17, 3, 210, 187, 195, 40, 220, 17, 18, 3, 217, 113, 221, 44, + 220, 17, 204, 20, 3, 219, 43, 220, 17, 204, 20, 3, 212, 65, 220, 17, 18, + 3, 71, 220, 17, 18, 3, 234, 166, 220, 17, 18, 3, 74, 220, 17, 18, 3, 250, + 131, 220, 17, 18, 3, 251, 236, 220, 17, 221, 68, 173, 220, 17, 163, 217, + 113, 234, 147, 220, 17, 163, 217, 113, 198, 241, 220, 17, 163, 217, 113, + 198, 193, 220, 17, 163, 217, 113, 247, 77, 220, 17, 247, 125, 77, 220, + 17, 213, 192, 220, 17, 192, 110, 220, 17, 17, 191, 77, 220, 17, 17, 107, + 220, 17, 17, 109, 220, 17, 17, 138, 220, 17, 17, 134, 220, 17, 17, 149, + 220, 17, 17, 169, 220, 17, 17, 175, 220, 17, 17, 171, 220, 17, 17, 178, + 220, 17, 229, 24, 213, 43, 220, 17, 229, 24, 216, 12, 220, 17, 1, 221, + 185, 231, 3, 220, 17, 1, 221, 185, 212, 65, 86, 5, 211, 113, 86, 87, 230, + 181, 192, 25, 216, 118, 197, 178, 65, 86, 87, 230, 181, 192, 25, 216, + 118, 255, 207, 206, 167, 249, 19, 174, 86, 87, 230, 181, 192, 25, 216, + 118, 255, 207, 230, 181, 197, 153, 174, 86, 87, 89, 192, 25, 216, 118, + 216, 234, 174, 86, 87, 242, 215, 192, 25, 216, 118, 203, 172, 174, 86, + 87, 247, 97, 192, 25, 216, 118, 209, 189, 203, 158, 174, 86, 87, 192, 25, + 216, 118, 197, 153, 203, 158, 174, 86, 87, 205, 100, 203, 157, 86, 87, + 248, 13, 192, 25, 216, 117, 86, 87, 248, 141, 203, 50, 192, 25, 216, 117, + 86, 87, 223, 98, 197, 152, 86, 87, 237, 113, 197, 153, 248, 12, 86, 87, + 203, 157, 86, 87, 212, 70, 203, 157, 86, 87, 197, 153, 203, 157, 86, 87, + 212, 70, 197, 153, 203, 157, 86, 87, 206, 191, 243, 111, 201, 193, 203, + 157, 86, 87, 207, 10, 230, 222, 203, 157, 86, 87, 247, 97, 255, 211, 206, + 73, 216, 233, 179, 247, 128, 86, 87, 230, 181, 197, 152, 86, 219, 27, 3, + 246, 255, 206, 72, 86, 219, 27, 3, 219, 157, 206, 72, 86, 250, 188, 3, + 203, 168, 231, 168, 255, 212, 206, 72, 86, 250, 188, 3, 255, 209, 168, + 86, 250, 188, 3, 205, 69, 197, 147, 86, 3, 207, 115, 236, 189, 231, 167, + 86, 3, 207, 115, 236, 189, 231, 5, 86, 3, 207, 115, 236, 189, 230, 182, + 86, 3, 207, 115, 214, 243, 231, 167, 86, 3, 207, 115, 214, 243, 231, 5, + 86, 3, 207, 115, 236, 189, 207, 115, 214, 242, 86, 17, 191, 77, 86, 17, + 107, 86, 17, 109, 86, 17, 138, 86, 17, 134, 86, 17, 149, 86, 17, 169, 86, + 17, 175, 86, 17, 171, 86, 17, 178, 86, 17, 132, 107, 86, 17, 132, 109, + 86, 17, 132, 138, 86, 17, 132, 134, 86, 17, 132, 149, 86, 17, 132, 169, + 86, 17, 132, 175, 86, 17, 132, 171, 86, 17, 132, 178, 86, 17, 132, 191, + 77, 86, 87, 248, 15, 206, 72, 86, 87, 214, 59, 247, 195, 212, 82, 191, + 10, 86, 87, 247, 97, 255, 211, 206, 73, 247, 196, 216, 62, 247, 128, 86, + 87, 214, 59, 247, 195, 203, 169, 206, 72, 86, 87, 243, 128, 216, 117, 86, + 87, 197, 169, 255, 208, 86, 87, 230, 164, 206, 73, 230, 119, 86, 87, 230, + 164, 206, 73, 230, 125, 86, 87, 251, 123, 221, 202, 230, 119, 86, 87, + 251, 123, 221, 202, 230, 125, 86, 3, 192, 102, 197, 151, 86, 3, 217, 66, + 197, 151, 86, 1, 155, 86, 1, 221, 215, 86, 1, 231, 240, 86, 1, 231, 91, + 86, 1, 214, 68, 86, 1, 247, 160, 86, 1, 247, 1, 86, 1, 223, 32, 86, 1, + 212, 101, 86, 1, 197, 132, 86, 1, 197, 120, 86, 1, 237, 191, 86, 1, 237, + 175, 86, 1, 213, 79, 86, 1, 190, 190, 86, 1, 199, 49, 86, 1, 238, 32, 86, + 1, 237, 68, 86, 1, 180, 86, 1, 168, 86, 1, 209, 228, 86, 1, 249, 153, 86, + 1, 248, 203, 86, 1, 174, 86, 1, 197, 168, 86, 1, 197, 157, 86, 1, 235, + 35, 86, 1, 235, 29, 86, 1, 193, 190, 86, 1, 191, 71, 86, 1, 191, 123, 86, + 1, 255, 214, 86, 1, 170, 86, 1, 165, 86, 1, 173, 86, 1, 203, 165, 86, 1, + 201, 175, 86, 1, 188, 86, 1, 140, 86, 1, 65, 86, 1, 220, 246, 86, 1, 232, + 221, 165, 86, 1, 221, 101, 86, 1, 206, 109, 86, 18, 3, 252, 206, 86, 18, + 3, 68, 86, 18, 3, 223, 199, 86, 18, 3, 66, 86, 18, 3, 196, 30, 86, 18, 3, + 117, 146, 86, 18, 3, 117, 206, 110, 86, 18, 3, 117, 172, 86, 18, 3, 117, + 219, 74, 86, 18, 3, 71, 86, 18, 3, 234, 188, 86, 18, 3, 74, 86, 18, 3, + 211, 87, 86, 3, 206, 173, 201, 5, 214, 69, 206, 162, 86, 3, 206, 167, + 249, 18, 86, 18, 3, 207, 18, 68, 86, 18, 3, 207, 18, 223, 199, 86, 3, + 212, 82, 191, 11, 214, 251, 238, 32, 86, 3, 202, 61, 219, 240, 86, 87, + 230, 72, 86, 87, 210, 178, 86, 3, 219, 243, 206, 72, 86, 3, 192, 107, + 206, 72, 86, 3, 219, 244, 197, 169, 247, 128, 86, 3, 216, 236, 247, 128, + 86, 3, 230, 185, 247, 129, 207, 8, 86, 3, 230, 185, 216, 220, 207, 8, 86, + 3, 223, 93, 216, 236, 247, 128, 86, 200, 239, 3, 219, 244, 197, 169, 247, + 128, 86, 200, 239, 3, 216, 236, 247, 128, 86, 200, 239, 3, 223, 93, 216, + 236, 247, 128, 86, 200, 239, 1, 155, 86, 200, 239, 1, 221, 215, 86, 200, + 239, 1, 231, 240, 86, 200, 239, 1, 231, 91, 86, 200, 239, 1, 214, 68, 86, + 200, 239, 1, 247, 160, 86, 200, 239, 1, 247, 1, 86, 200, 239, 1, 223, 32, + 86, 200, 239, 1, 212, 101, 86, 200, 239, 1, 197, 132, 86, 200, 239, 1, + 197, 120, 86, 200, 239, 1, 237, 191, 86, 200, 239, 1, 237, 175, 86, 200, + 239, 1, 213, 79, 86, 200, 239, 1, 190, 190, 86, 200, 239, 1, 199, 49, 86, + 200, 239, 1, 238, 32, 86, 200, 239, 1, 237, 68, 86, 200, 239, 1, 180, 86, + 200, 239, 1, 168, 86, 200, 239, 1, 209, 228, 86, 200, 239, 1, 249, 153, + 86, 200, 239, 1, 248, 203, 86, 200, 239, 1, 174, 86, 200, 239, 1, 197, + 168, 86, 200, 239, 1, 197, 157, 86, 200, 239, 1, 235, 35, 86, 200, 239, + 1, 235, 29, 86, 200, 239, 1, 193, 190, 86, 200, 239, 1, 191, 71, 86, 200, + 239, 1, 191, 123, 86, 200, 239, 1, 255, 214, 86, 200, 239, 1, 170, 86, + 200, 239, 1, 165, 86, 200, 239, 1, 173, 86, 200, 239, 1, 203, 165, 86, + 200, 239, 1, 201, 175, 86, 200, 239, 1, 188, 86, 200, 239, 1, 140, 86, + 200, 239, 1, 65, 86, 200, 239, 1, 220, 246, 86, 200, 239, 1, 232, 221, + 193, 190, 86, 200, 239, 1, 232, 221, 170, 86, 200, 239, 1, 232, 221, 165, + 86, 220, 233, 206, 69, 221, 215, 86, 220, 233, 206, 69, 221, 216, 247, + 196, 216, 62, 247, 128, 86, 247, 112, 3, 88, 249, 7, 86, 247, 112, 3, + 156, 249, 7, 86, 247, 112, 3, 247, 116, 199, 135, 86, 247, 112, 3, 205, + 99, 255, 213, 86, 16, 235, 105, 248, 10, 86, 16, 207, 114, 206, 174, 86, + 16, 210, 206, 231, 166, 86, 16, 207, 114, 206, 175, 207, 10, 230, 221, + 86, 16, 209, 189, 168, 86, 16, 213, 21, 248, 10, 86, 16, 213, 21, 248, + 11, 212, 70, 255, 210, 86, 16, 213, 21, 248, 11, 230, 183, 255, 210, 86, + 16, 213, 21, 248, 11, 247, 196, 255, 210, 86, 3, 207, 115, 214, 243, 207, + 115, 236, 188, 86, 3, 207, 115, 214, 243, 230, 182, 86, 87, 248, 14, 203, + 50, 231, 54, 216, 118, 207, 9, 86, 87, 216, 14, 192, 25, 231, 54, 216, + 118, 207, 9, 86, 87, 212, 70, 197, 152, 86, 87, 89, 248, 44, 206, 164, + 192, 25, 216, 118, 216, 234, 174, 86, 87, 242, 215, 248, 44, 206, 164, + 192, 25, 216, 118, 203, 172, 174, 206, 207, 200, 155, 56, 219, 223, 200, + 155, 56, 206, 207, 200, 155, 3, 4, 236, 138, 219, 223, 200, 155, 3, 4, + 236, 138, 86, 87, 219, 235, 216, 237, 206, 72, 86, 87, 198, 18, 216, 237, + 206, 72, 80, 1, 155, 80, 1, 221, 215, 80, 1, 231, 240, 80, 1, 231, 91, + 80, 1, 214, 68, 80, 1, 247, 160, 80, 1, 247, 1, 80, 1, 223, 32, 80, 1, + 222, 252, 80, 1, 212, 101, 80, 1, 213, 45, 80, 1, 197, 132, 80, 1, 197, + 120, 80, 1, 237, 191, 80, 1, 237, 175, 80, 1, 213, 79, 80, 1, 190, 190, + 80, 1, 199, 49, 80, 1, 238, 32, 80, 1, 237, 68, 80, 1, 180, 80, 1, 168, + 80, 1, 209, 228, 80, 1, 249, 153, 80, 1, 248, 203, 80, 1, 174, 80, 1, + 170, 80, 1, 165, 80, 1, 173, 80, 1, 193, 190, 80, 1, 188, 80, 1, 140, 80, + 1, 219, 73, 80, 1, 65, 80, 1, 203, 139, 65, 80, 1, 68, 80, 1, 223, 199, + 80, 1, 66, 80, 1, 196, 30, 80, 1, 71, 80, 1, 215, 232, 71, 80, 1, 74, 80, + 1, 250, 163, 80, 18, 3, 199, 200, 252, 206, 80, 18, 3, 252, 206, 80, 18, + 3, 68, 80, 18, 3, 223, 199, 80, 18, 3, 66, 80, 18, 3, 196, 30, 80, 18, 3, + 71, 80, 18, 3, 251, 236, 80, 18, 3, 215, 232, 223, 199, 80, 18, 3, 215, + 232, 74, 80, 18, 3, 235, 15, 58, 80, 3, 251, 71, 80, 3, 75, 60, 80, 3, + 195, 35, 80, 3, 195, 40, 80, 3, 250, 214, 80, 120, 3, 216, 217, 170, 80, + 120, 3, 216, 217, 165, 80, 120, 3, 216, 217, 193, 190, 80, 120, 3, 216, + 217, 140, 80, 1, 230, 206, 188, 80, 17, 191, 77, 80, 17, 107, 80, 17, + 109, 80, 17, 138, 80, 17, 134, 80, 17, 149, 80, 17, 169, 80, 17, 175, 80, + 17, 171, 80, 17, 178, 80, 3, 219, 83, 205, 53, 80, 3, 205, 53, 80, 16, + 219, 36, 80, 16, 242, 67, 80, 16, 252, 1, 80, 16, 231, 146, 80, 1, 203, + 165, 80, 1, 201, 175, 80, 1, 117, 146, 80, 1, 117, 206, 110, 80, 1, 117, + 172, 80, 1, 117, 219, 74, 80, 18, 3, 117, 146, 80, 18, 3, 117, 206, 110, + 80, 18, 3, 117, 172, 80, 18, 3, 117, 219, 74, 80, 1, 215, 232, 214, 68, + 80, 1, 215, 232, 222, 252, 80, 1, 215, 232, 249, 53, 80, 1, 215, 232, + 249, 48, 80, 120, 3, 215, 232, 216, 217, 180, 80, 120, 3, 215, 232, 216, + 217, 174, 80, 120, 3, 215, 232, 216, 217, 173, 80, 1, 203, 171, 222, 62, + 203, 165, 80, 18, 3, 203, 171, 222, 62, 233, 242, 80, 163, 87, 203, 171, + 222, 62, 230, 5, 80, 163, 87, 203, 171, 222, 62, 222, 23, 209, 199, 80, + 1, 193, 102, 208, 116, 222, 62, 199, 49, 80, 1, 193, 102, 208, 116, 222, + 62, 208, 122, 80, 18, 3, 193, 102, 208, 116, 222, 62, 233, 242, 80, 18, + 3, 193, 102, 208, 116, 222, 62, 196, 152, 80, 3, 193, 102, 208, 116, 222, + 62, 198, 78, 80, 3, 193, 102, 208, 116, 222, 62, 198, 77, 80, 3, 193, + 102, 208, 116, 222, 62, 198, 76, 80, 3, 193, 102, 208, 116, 222, 62, 198, + 75, 80, 3, 193, 102, 208, 116, 222, 62, 198, 74, 80, 1, 234, 202, 208, + 116, 222, 62, 213, 79, 80, 1, 234, 202, 208, 116, 222, 62, 191, 183, 80, + 1, 234, 202, 208, 116, 222, 62, 231, 56, 80, 18, 3, 231, 161, 222, 62, + 68, 80, 18, 3, 222, 28, 211, 151, 80, 18, 3, 222, 28, 66, 80, 18, 3, 222, + 28, 234, 188, 80, 1, 203, 139, 155, 80, 1, 203, 139, 221, 215, 80, 1, + 203, 139, 231, 240, 80, 1, 203, 139, 247, 160, 80, 1, 203, 139, 191, 123, + 80, 1, 203, 139, 212, 101, 80, 1, 203, 139, 238, 32, 80, 1, 203, 139, + 180, 80, 1, 203, 139, 209, 228, 80, 1, 203, 139, 233, 109, 80, 1, 203, + 139, 249, 153, 80, 1, 203, 139, 199, 49, 80, 1, 203, 139, 140, 80, 120, + 3, 203, 139, 216, 217, 193, 190, 80, 18, 3, 203, 139, 252, 206, 80, 18, + 3, 203, 139, 71, 80, 18, 3, 203, 139, 235, 15, 58, 80, 18, 3, 203, 139, + 53, 192, 159, 80, 3, 203, 139, 198, 77, 80, 3, 203, 139, 198, 76, 80, 3, + 203, 139, 198, 74, 80, 3, 203, 139, 198, 73, 80, 3, 203, 139, 238, 247, + 198, 77, 80, 3, 203, 139, 238, 247, 198, 76, 80, 3, 203, 139, 238, 247, + 234, 106, 198, 79, 80, 1, 206, 47, 210, 189, 233, 109, 80, 3, 206, 47, + 210, 189, 198, 74, 80, 203, 139, 17, 191, 77, 80, 203, 139, 17, 107, 80, + 203, 139, 17, 109, 80, 203, 139, 17, 138, 80, 203, 139, 17, 134, 80, 203, + 139, 17, 149, 80, 203, 139, 17, 169, 80, 203, 139, 17, 175, 80, 203, 139, + 17, 171, 80, 203, 139, 17, 178, 80, 3, 221, 206, 198, 78, 80, 3, 221, + 206, 198, 76, 80, 18, 3, 251, 222, 65, 80, 18, 3, 251, 222, 251, 236, 80, + 16, 203, 139, 107, 80, 16, 203, 139, 233, 215, 101, 6, 1, 251, 132, 101, + 6, 1, 249, 101, 101, 6, 1, 231, 210, 101, 6, 1, 236, 150, 101, 6, 1, 234, + 103, 101, 6, 1, 195, 49, 101, 6, 1, 191, 80, 101, 6, 1, 199, 193, 101, 6, + 1, 223, 162, 101, 6, 1, 222, 87, 101, 6, 1, 220, 7, 101, 6, 1, 217, 90, + 101, 6, 1, 214, 216, 101, 6, 1, 211, 104, 101, 6, 1, 210, 131, 101, 6, 1, + 191, 67, 101, 6, 1, 207, 163, 101, 6, 1, 205, 142, 101, 6, 1, 199, 179, + 101, 6, 1, 196, 113, 101, 6, 1, 209, 220, 101, 6, 1, 221, 200, 101, 6, 1, + 231, 82, 101, 6, 1, 208, 81, 101, 6, 1, 203, 69, 101, 6, 1, 243, 81, 101, + 6, 1, 247, 128, 101, 6, 1, 222, 234, 101, 6, 1, 243, 18, 101, 6, 1, 246, + 241, 101, 6, 1, 192, 218, 101, 6, 1, 222, 249, 101, 6, 1, 230, 87, 101, + 6, 1, 229, 245, 101, 6, 1, 229, 145, 101, 6, 1, 193, 125, 101, 6, 1, 230, + 19, 101, 6, 1, 229, 11, 101, 6, 1, 192, 14, 101, 6, 1, 252, 14, 101, 1, + 251, 132, 101, 1, 249, 101, 101, 1, 231, 210, 101, 1, 236, 150, 101, 1, + 234, 103, 101, 1, 195, 49, 101, 1, 191, 80, 101, 1, 199, 193, 101, 1, + 223, 162, 101, 1, 222, 87, 101, 1, 220, 7, 101, 1, 217, 90, 101, 1, 214, + 216, 101, 1, 211, 104, 101, 1, 210, 131, 101, 1, 191, 67, 101, 1, 207, + 163, 101, 1, 205, 142, 101, 1, 199, 179, 101, 1, 196, 113, 101, 1, 209, + 220, 101, 1, 221, 200, 101, 1, 231, 82, 101, 1, 208, 81, 101, 1, 203, 69, + 101, 1, 243, 81, 101, 1, 247, 128, 101, 1, 222, 234, 101, 1, 243, 18, + 101, 1, 246, 241, 101, 1, 192, 218, 101, 1, 222, 249, 101, 1, 230, 87, + 101, 1, 229, 245, 101, 1, 229, 145, 101, 1, 193, 125, 101, 1, 230, 19, + 101, 1, 229, 11, 101, 1, 233, 23, 101, 1, 192, 14, 101, 1, 234, 123, 101, + 1, 153, 231, 210, 101, 1, 251, 230, 101, 210, 128, 204, 10, 52, 1, 101, + 214, 216, 101, 1, 252, 14, 101, 1, 230, 17, 56, 101, 1, 220, 116, 56, 30, + 147, 221, 113, 30, 147, 201, 167, 30, 147, 213, 204, 30, 147, 198, 168, + 30, 147, 201, 156, 30, 147, 206, 239, 30, 147, 216, 77, 30, 147, 209, + 169, 30, 147, 201, 164, 30, 147, 202, 160, 30, 147, 201, 161, 30, 147, + 223, 222, 30, 147, 243, 24, 30, 147, 201, 171, 30, 147, 243, 91, 30, 147, + 221, 188, 30, 147, 199, 7, 30, 147, 209, 209, 30, 147, 229, 142, 30, 147, + 213, 200, 30, 147, 201, 165, 30, 147, 213, 194, 30, 147, 213, 198, 30, + 147, 198, 165, 30, 147, 206, 227, 30, 147, 201, 163, 30, 147, 206, 237, + 30, 147, 222, 68, 30, 147, 216, 70, 30, 147, 222, 71, 30, 147, 209, 164, + 30, 147, 209, 162, 30, 147, 209, 150, 30, 147, 209, 158, 30, 147, 209, + 156, 30, 147, 209, 153, 30, 147, 209, 155, 30, 147, 209, 152, 30, 147, + 209, 157, 30, 147, 209, 167, 30, 147, 209, 168, 30, 147, 209, 151, 30, + 147, 209, 161, 30, 147, 222, 69, 30, 147, 222, 67, 30, 147, 202, 153, 30, + 147, 202, 151, 30, 147, 202, 143, 30, 147, 202, 146, 30, 147, 202, 152, + 30, 147, 202, 148, 30, 147, 202, 147, 30, 147, 202, 145, 30, 147, 202, + 156, 30, 147, 202, 158, 30, 147, 202, 159, 30, 147, 202, 154, 30, 147, + 202, 144, 30, 147, 202, 149, 30, 147, 202, 157, 30, 147, 243, 72, 30, + 147, 243, 70, 30, 147, 247, 14, 30, 147, 247, 12, 30, 147, 210, 149, 30, + 147, 223, 217, 30, 147, 223, 208, 30, 147, 223, 216, 30, 147, 223, 213, + 30, 147, 223, 211, 30, 147, 223, 215, 30, 147, 201, 168, 30, 147, 223, + 220, 30, 147, 223, 221, 30, 147, 223, 209, 30, 147, 223, 214, 30, 147, + 192, 57, 30, 147, 243, 23, 30, 147, 243, 73, 30, 147, 243, 71, 30, 147, + 247, 15, 30, 147, 247, 13, 30, 147, 243, 89, 30, 147, 243, 90, 30, 147, + 243, 74, 30, 147, 247, 16, 30, 147, 209, 207, 30, 147, 222, 70, 30, 147, + 201, 169, 30, 147, 192, 63, 30, 147, 221, 104, 30, 147, 213, 196, 30, + 147, 213, 202, 30, 147, 213, 201, 30, 147, 198, 162, 30, 147, 233, 3, 30, + 222, 174, 233, 3, 30, 222, 174, 65, 30, 222, 174, 252, 25, 30, 222, 174, + 170, 30, 222, 174, 192, 129, 30, 222, 174, 234, 65, 30, 222, 174, 71, 30, + 222, 174, 192, 67, 30, 222, 174, 192, 80, 30, 222, 174, 74, 30, 222, 174, + 193, 190, 30, 222, 174, 193, 176, 30, 222, 174, 211, 151, 30, 222, 174, + 192, 12, 30, 222, 174, 66, 30, 222, 174, 193, 107, 30, 222, 174, 193, + 125, 30, 222, 174, 193, 86, 30, 222, 174, 191, 225, 30, 222, 174, 233, + 242, 30, 222, 174, 192, 33, 30, 222, 174, 68, 30, 222, 174, 255, 202, 30, + 222, 174, 255, 201, 30, 222, 174, 192, 143, 30, 222, 174, 192, 141, 30, + 222, 174, 234, 63, 30, 222, 174, 234, 62, 30, 222, 174, 234, 64, 30, 222, + 174, 192, 66, 30, 222, 174, 192, 65, 30, 222, 174, 212, 10, 30, 222, 174, + 212, 11, 30, 222, 174, 212, 4, 30, 222, 174, 212, 9, 30, 222, 174, 212, + 7, 30, 222, 174, 192, 0, 30, 222, 174, 191, 255, 30, 222, 174, 191, 254, + 30, 222, 174, 192, 1, 30, 222, 174, 192, 2, 30, 222, 174, 196, 226, 30, + 222, 174, 196, 225, 30, 222, 174, 196, 223, 30, 222, 174, 196, 219, 30, + 222, 174, 196, 220, 30, 222, 174, 191, 220, 30, 222, 174, 191, 217, 30, + 222, 174, 191, 218, 30, 222, 174, 191, 212, 30, 222, 174, 191, 213, 30, + 222, 174, 191, 214, 30, 222, 174, 191, 216, 30, 222, 174, 233, 236, 30, + 222, 174, 233, 238, 30, 222, 174, 192, 32, 30, 222, 174, 228, 69, 30, + 222, 174, 228, 61, 30, 222, 174, 228, 64, 30, 222, 174, 228, 62, 30, 222, + 174, 228, 66, 30, 222, 174, 228, 68, 30, 222, 174, 251, 25, 30, 222, 174, + 251, 22, 30, 222, 174, 251, 20, 30, 222, 174, 251, 21, 30, 222, 174, 201, + 172, 30, 222, 174, 255, 203, 30, 222, 174, 192, 142, 30, 222, 174, 192, + 64, 30, 222, 174, 212, 6, 30, 222, 174, 212, 5, 30, 125, 221, 113, 30, + 125, 201, 167, 30, 125, 221, 106, 30, 125, 213, 204, 30, 125, 213, 202, + 30, 125, 213, 201, 30, 125, 198, 168, 30, 125, 206, 239, 30, 125, 206, + 234, 30, 125, 206, 231, 30, 125, 206, 224, 30, 125, 206, 219, 30, 125, + 206, 214, 30, 125, 206, 225, 30, 125, 206, 237, 30, 125, 216, 77, 30, + 125, 209, 169, 30, 125, 209, 158, 30, 125, 202, 160, 30, 125, 201, 161, + 30, 125, 223, 222, 30, 125, 243, 24, 30, 125, 243, 91, 30, 125, 221, 188, + 30, 125, 199, 7, 30, 125, 209, 209, 30, 125, 229, 142, 30, 125, 221, 107, + 30, 125, 221, 105, 30, 125, 213, 200, 30, 125, 213, 194, 30, 125, 213, + 196, 30, 125, 213, 199, 30, 125, 213, 195, 30, 125, 198, 165, 30, 125, + 198, 162, 30, 125, 206, 232, 30, 125, 206, 227, 30, 125, 206, 213, 30, + 125, 206, 212, 30, 125, 201, 163, 30, 125, 206, 229, 30, 125, 206, 228, + 30, 125, 206, 221, 30, 125, 206, 223, 30, 125, 206, 236, 30, 125, 206, + 216, 30, 125, 206, 226, 30, 125, 206, 235, 30, 125, 206, 211, 30, 125, + 216, 73, 30, 125, 216, 68, 30, 125, 216, 70, 30, 125, 216, 67, 30, 125, + 216, 65, 30, 125, 216, 71, 30, 125, 216, 76, 30, 125, 216, 74, 30, 125, + 222, 71, 30, 125, 209, 160, 30, 125, 209, 161, 30, 125, 209, 166, 30, + 125, 222, 69, 30, 125, 202, 153, 30, 125, 202, 143, 30, 125, 202, 146, + 30, 125, 202, 148, 30, 125, 210, 149, 30, 125, 223, 217, 30, 125, 223, + 210, 30, 125, 201, 168, 30, 125, 223, 218, 30, 125, 192, 57, 30, 125, + 192, 51, 30, 125, 192, 52, 30, 125, 209, 207, 30, 125, 222, 70, 30, 125, + 229, 140, 30, 125, 229, 138, 30, 125, 229, 141, 30, 125, 229, 139, 30, + 125, 192, 63, 30, 125, 221, 109, 30, 125, 221, 108, 30, 125, 221, 112, + 30, 125, 221, 110, 30, 125, 221, 111, 30, 125, 201, 165, 36, 5, 140, 36, + 5, 228, 159, 36, 5, 229, 158, 36, 5, 230, 91, 36, 5, 229, 215, 36, 5, + 229, 245, 36, 5, 229, 23, 36, 5, 229, 14, 36, 5, 173, 36, 5, 218, 225, + 36, 5, 219, 146, 36, 5, 220, 125, 36, 5, 219, 228, 36, 5, 219, 238, 36, + 5, 219, 43, 36, 5, 218, 191, 36, 5, 229, 177, 36, 5, 229, 171, 36, 5, + 229, 173, 36, 5, 229, 176, 36, 5, 229, 174, 36, 5, 229, 175, 36, 5, 229, + 172, 36, 5, 229, 170, 36, 5, 174, 36, 5, 215, 155, 36, 5, 216, 100, 36, + 5, 217, 151, 36, 5, 216, 211, 36, 5, 216, 232, 36, 5, 216, 12, 36, 5, + 215, 80, 36, 5, 200, 54, 36, 5, 200, 48, 36, 5, 200, 50, 36, 5, 200, 53, + 36, 5, 200, 51, 36, 5, 200, 52, 36, 5, 200, 49, 36, 5, 200, 47, 36, 5, + 165, 36, 5, 206, 68, 36, 5, 207, 1, 36, 5, 207, 178, 36, 5, 207, 84, 36, + 5, 207, 113, 36, 5, 206, 162, 36, 5, 206, 26, 36, 5, 188, 36, 5, 201, 4, + 36, 5, 202, 222, 36, 5, 205, 197, 36, 5, 205, 50, 36, 5, 205, 68, 36, 5, + 202, 46, 36, 5, 200, 150, 36, 5, 203, 165, 36, 5, 203, 5, 36, 5, 203, 81, + 36, 5, 203, 160, 36, 5, 203, 111, 36, 5, 203, 113, 36, 5, 203, 56, 36, 5, + 202, 240, 36, 5, 208, 96, 36, 5, 208, 33, 36, 5, 208, 57, 36, 5, 208, 95, + 36, 5, 208, 74, 36, 5, 208, 75, 36, 5, 208, 45, 36, 5, 208, 44, 36, 5, + 207, 240, 36, 5, 207, 236, 36, 5, 207, 239, 36, 5, 207, 237, 36, 5, 207, + 238, 36, 5, 208, 71, 36, 5, 208, 63, 36, 5, 208, 66, 36, 5, 208, 70, 36, + 5, 208, 67, 36, 5, 208, 68, 36, 5, 208, 65, 36, 5, 208, 62, 36, 5, 208, + 58, 36, 5, 208, 61, 36, 5, 208, 59, 36, 5, 208, 60, 36, 5, 249, 153, 36, + 5, 248, 10, 36, 5, 248, 188, 36, 5, 249, 151, 36, 5, 249, 1, 36, 5, 249, + 17, 36, 5, 248, 111, 36, 5, 247, 210, 36, 5, 195, 188, 36, 5, 193, 249, + 36, 5, 195, 69, 36, 5, 195, 187, 36, 5, 195, 148, 36, 5, 195, 153, 36, 5, + 195, 24, 36, 5, 193, 238, 36, 5, 190, 190, 36, 5, 197, 94, 36, 5, 198, + 193, 36, 5, 199, 245, 36, 5, 199, 121, 36, 5, 199, 145, 36, 5, 159, 36, + 5, 197, 43, 36, 5, 247, 160, 36, 5, 238, 195, 36, 5, 243, 29, 36, 5, 247, + 159, 36, 5, 247, 34, 36, 5, 247, 42, 36, 5, 242, 99, 36, 5, 238, 151, 36, + 5, 192, 220, 36, 5, 192, 188, 36, 5, 192, 207, 36, 5, 192, 219, 36, 5, + 192, 213, 36, 5, 192, 214, 36, 5, 192, 196, 36, 5, 192, 195, 36, 5, 192, + 181, 36, 5, 192, 177, 36, 5, 192, 180, 36, 5, 192, 178, 36, 5, 192, 179, + 36, 5, 180, 36, 5, 212, 178, 36, 5, 213, 219, 36, 5, 214, 250, 36, 5, + 214, 110, 36, 5, 214, 121, 36, 5, 213, 43, 36, 5, 212, 110, 36, 5, 212, + 101, 36, 5, 212, 58, 36, 5, 212, 81, 36, 5, 212, 100, 36, 5, 212, 89, 36, + 5, 212, 90, 36, 5, 212, 65, 36, 5, 212, 48, 36, 5, 231, 11, 65, 36, 5, + 231, 11, 66, 36, 5, 231, 11, 68, 36, 5, 231, 11, 252, 206, 36, 5, 231, + 11, 234, 188, 36, 5, 231, 11, 71, 36, 5, 231, 11, 74, 36, 5, 231, 11, + 193, 190, 36, 5, 155, 36, 5, 220, 232, 36, 5, 221, 166, 36, 5, 222, 127, + 36, 5, 222, 13, 36, 5, 222, 22, 36, 5, 221, 67, 36, 5, 221, 62, 36, 5, + 220, 179, 36, 5, 220, 172, 36, 5, 220, 178, 36, 5, 220, 173, 36, 5, 220, + 174, 36, 5, 220, 165, 36, 5, 220, 159, 36, 5, 220, 161, 36, 5, 220, 164, + 36, 5, 220, 162, 36, 5, 220, 163, 36, 5, 220, 160, 36, 5, 220, 158, 36, + 5, 220, 154, 36, 5, 220, 157, 36, 5, 220, 155, 36, 5, 220, 156, 36, 5, + 193, 190, 36, 5, 193, 0, 36, 5, 193, 86, 36, 5, 193, 181, 36, 5, 193, + 114, 36, 5, 193, 125, 36, 5, 193, 48, 36, 5, 193, 40, 36, 5, 209, 219, + 65, 36, 5, 209, 219, 66, 36, 5, 209, 219, 68, 36, 5, 209, 219, 252, 206, + 36, 5, 209, 219, 234, 188, 36, 5, 209, 219, 71, 36, 5, 209, 219, 74, 36, + 5, 191, 123, 36, 5, 190, 251, 36, 5, 191, 30, 36, 5, 191, 121, 36, 5, + 191, 84, 36, 5, 191, 87, 36, 5, 191, 7, 36, 5, 190, 238, 36, 5, 191, 71, + 36, 5, 191, 48, 36, 5, 191, 57, 36, 5, 191, 70, 36, 5, 191, 61, 36, 5, + 191, 62, 36, 5, 191, 54, 36, 5, 191, 39, 36, 5, 170, 36, 5, 191, 225, 36, + 5, 192, 33, 36, 5, 192, 140, 36, 5, 192, 77, 36, 5, 192, 80, 36, 5, 192, + 12, 36, 5, 191, 252, 36, 5, 238, 32, 36, 5, 235, 89, 36, 5, 237, 44, 36, + 5, 238, 31, 36, 5, 237, 131, 36, 5, 237, 146, 36, 5, 236, 174, 36, 5, + 235, 46, 36, 5, 237, 191, 36, 5, 237, 156, 36, 5, 237, 168, 36, 5, 237, + 190, 36, 5, 237, 178, 36, 5, 237, 179, 36, 5, 237, 161, 36, 5, 237, 147, + 36, 5, 223, 32, 36, 5, 222, 182, 36, 5, 222, 244, 36, 5, 223, 31, 36, 5, + 223, 8, 36, 5, 223, 10, 36, 5, 222, 201, 36, 5, 222, 160, 36, 5, 231, + 240, 36, 5, 230, 179, 36, 5, 231, 53, 36, 5, 231, 237, 36, 5, 231, 157, + 36, 5, 231, 165, 36, 5, 231, 3, 36, 5, 231, 2, 36, 5, 230, 135, 36, 5, + 230, 131, 36, 5, 230, 134, 36, 5, 230, 132, 36, 5, 230, 133, 36, 5, 231, + 127, 36, 5, 231, 107, 36, 5, 231, 117, 36, 5, 231, 126, 36, 5, 231, 121, + 36, 5, 231, 122, 36, 5, 231, 111, 36, 5, 231, 96, 36, 5, 199, 49, 36, 5, + 198, 213, 36, 5, 199, 11, 36, 5, 199, 48, 36, 5, 199, 31, 36, 5, 199, 33, + 36, 5, 198, 241, 36, 5, 198, 204, 36, 5, 247, 1, 36, 5, 243, 48, 36, 5, + 243, 95, 36, 5, 247, 0, 36, 5, 243, 123, 36, 5, 243, 127, 36, 5, 243, 68, + 36, 5, 243, 37, 36, 5, 209, 228, 36, 5, 209, 191, 36, 5, 209, 211, 36, 5, + 209, 227, 36, 5, 209, 213, 36, 5, 209, 214, 36, 5, 209, 199, 36, 5, 209, + 187, 36, 5, 197, 168, 36, 5, 197, 140, 36, 5, 197, 146, 36, 5, 197, 167, + 36, 5, 197, 160, 36, 5, 197, 161, 36, 5, 197, 144, 36, 5, 197, 138, 36, + 5, 196, 240, 36, 5, 196, 232, 36, 5, 196, 236, 36, 5, 196, 239, 36, 5, + 196, 237, 36, 5, 196, 238, 36, 5, 196, 234, 36, 5, 196, 233, 36, 5, 233, + 109, 36, 5, 232, 86, 36, 5, 233, 23, 36, 5, 233, 108, 36, 5, 233, 52, 36, + 5, 233, 59, 36, 5, 232, 175, 36, 5, 232, 62, 36, 5, 168, 36, 5, 208, 165, + 36, 5, 209, 185, 36, 5, 210, 220, 36, 5, 210, 49, 36, 5, 210, 63, 36, 5, + 209, 73, 36, 5, 208, 122, 36, 5, 206, 16, 36, 5, 215, 68, 36, 5, 232, 56, + 36, 33, 231, 153, 23, 18, 219, 198, 77, 36, 33, 18, 219, 198, 77, 36, 33, + 231, 153, 77, 36, 205, 54, 77, 36, 193, 22, 36, 232, 80, 201, 63, 36, + 242, 74, 36, 204, 25, 36, 242, 83, 36, 208, 228, 242, 83, 36, 208, 13, + 77, 36, 210, 128, 204, 10, 36, 17, 107, 36, 17, 109, 36, 17, 138, 36, 17, + 134, 36, 17, 149, 36, 17, 169, 36, 17, 175, 36, 17, 171, 36, 17, 178, 36, + 31, 199, 95, 36, 31, 197, 32, 36, 31, 198, 249, 36, 31, 232, 135, 36, 31, + 233, 15, 36, 31, 202, 120, 36, 31, 203, 241, 36, 31, 234, 153, 36, 31, + 213, 169, 36, 31, 228, 140, 36, 31, 199, 96, 189, 36, 5, 205, 59, 215, + 80, 36, 5, 215, 76, 36, 5, 215, 77, 36, 5, 215, 78, 36, 5, 205, 59, 247, + 210, 36, 5, 247, 207, 36, 5, 247, 208, 36, 5, 247, 209, 36, 5, 205, 59, + 232, 62, 36, 5, 232, 58, 36, 5, 232, 59, 36, 5, 232, 60, 36, 5, 205, 59, + 208, 122, 36, 5, 208, 118, 36, 5, 208, 119, 36, 5, 208, 120, 36, 198, 80, + 87, 192, 15, 36, 198, 80, 87, 237, 89, 36, 198, 80, 87, 206, 194, 36, + 198, 80, 87, 203, 40, 206, 194, 36, 198, 80, 87, 237, 18, 36, 198, 80, + 87, 221, 250, 36, 198, 80, 87, 243, 76, 36, 198, 80, 87, 229, 147, 36, + 198, 80, 87, 237, 88, 36, 198, 80, 87, 220, 195, 103, 1, 65, 103, 1, 71, + 103, 1, 68, 103, 1, 74, 103, 1, 66, 103, 1, 196, 12, 103, 1, 231, 240, + 103, 1, 155, 103, 1, 231, 165, 103, 1, 231, 53, 103, 1, 231, 3, 103, 1, + 230, 179, 103, 1, 230, 138, 103, 1, 140, 103, 1, 229, 245, 103, 1, 229, + 158, 103, 1, 229, 23, 103, 1, 228, 159, 103, 1, 228, 126, 103, 1, 173, + 103, 1, 219, 238, 103, 1, 219, 146, 103, 1, 219, 43, 103, 1, 218, 225, + 103, 1, 218, 192, 103, 1, 174, 103, 1, 216, 232, 103, 1, 216, 100, 103, + 1, 216, 12, 103, 1, 215, 155, 103, 1, 180, 103, 1, 229, 47, 103, 1, 214, + 237, 103, 1, 214, 121, 103, 1, 213, 219, 103, 1, 213, 43, 103, 1, 212, + 178, 103, 1, 212, 112, 103, 1, 208, 32, 103, 1, 208, 16, 103, 1, 208, 9, + 103, 1, 207, 255, 103, 1, 207, 244, 103, 1, 207, 242, 103, 1, 188, 103, + 1, 206, 8, 103, 1, 205, 68, 103, 1, 202, 222, 103, 1, 202, 46, 103, 1, + 201, 4, 103, 1, 200, 158, 103, 1, 238, 32, 103, 1, 190, 190, 103, 1, 237, + 146, 103, 1, 199, 145, 103, 1, 237, 44, 103, 1, 198, 193, 103, 1, 236, + 174, 103, 1, 235, 89, 103, 1, 235, 57, 103, 1, 236, 186, 103, 1, 198, + 115, 103, 1, 198, 114, 103, 1, 198, 103, 103, 1, 198, 102, 103, 1, 198, + 101, 103, 1, 198, 100, 103, 1, 197, 168, 103, 1, 197, 161, 103, 1, 197, + 146, 103, 1, 197, 144, 103, 1, 197, 140, 103, 1, 197, 139, 103, 1, 193, + 190, 103, 1, 193, 125, 103, 1, 193, 86, 103, 1, 193, 48, 103, 1, 193, 0, + 103, 1, 192, 243, 103, 1, 170, 103, 1, 192, 80, 103, 1, 192, 33, 103, 1, + 192, 12, 103, 1, 191, 225, 103, 1, 191, 184, 103, 1, 215, 87, 103, 2, 1, + 192, 80, 103, 2, 1, 192, 33, 103, 2, 1, 192, 12, 103, 2, 1, 191, 225, + 103, 2, 1, 191, 184, 103, 2, 1, 215, 87, 21, 22, 228, 88, 21, 22, 71, 21, + 22, 252, 170, 21, 22, 68, 21, 22, 223, 199, 21, 22, 74, 21, 22, 211, 87, + 21, 22, 192, 158, 211, 87, 21, 22, 98, 234, 188, 21, 22, 98, 68, 21, 22, + 65, 21, 22, 252, 206, 21, 22, 193, 125, 21, 22, 193, 103, 193, 125, 21, + 22, 193, 86, 21, 22, 193, 103, 193, 86, 21, 22, 193, 70, 21, 22, 193, + 103, 193, 70, 21, 22, 193, 48, 21, 22, 193, 103, 193, 48, 21, 22, 193, + 29, 21, 22, 193, 103, 193, 29, 21, 22, 214, 209, 193, 29, 21, 22, 193, + 190, 21, 22, 193, 103, 193, 190, 21, 22, 193, 181, 21, 22, 193, 103, 193, + 181, 21, 22, 214, 209, 193, 181, 21, 22, 251, 236, 21, 22, 192, 158, 193, + 224, 21, 22, 231, 11, 201, 63, 21, 22, 53, 252, 46, 21, 22, 53, 230, 210, + 21, 22, 53, 248, 77, 132, 206, 188, 21, 22, 53, 198, 54, 132, 206, 188, + 21, 22, 53, 50, 132, 206, 188, 21, 22, 53, 206, 188, 21, 22, 53, 55, 252, + 46, 21, 22, 53, 55, 203, 40, 81, 201, 15, 21, 22, 53, 82, 236, 140, 21, + 22, 53, 203, 40, 228, 241, 106, 21, 22, 53, 209, 81, 21, 22, 53, 144, + 199, 228, 21, 22, 234, 103, 21, 22, 223, 162, 21, 22, 211, 104, 21, 22, + 251, 132, 21, 22, 210, 63, 21, 22, 210, 218, 21, 22, 209, 185, 21, 22, + 209, 145, 21, 22, 209, 73, 21, 22, 209, 37, 21, 22, 192, 158, 209, 37, + 21, 22, 98, 229, 215, 21, 22, 98, 229, 158, 21, 22, 168, 21, 22, 210, + 220, 21, 22, 208, 120, 21, 22, 193, 103, 208, 120, 21, 22, 208, 118, 21, + 22, 193, 103, 208, 118, 21, 22, 208, 117, 21, 22, 193, 103, 208, 117, 21, + 22, 208, 115, 21, 22, 193, 103, 208, 115, 21, 22, 208, 114, 21, 22, 193, + 103, 208, 114, 21, 22, 208, 122, 21, 22, 193, 103, 208, 122, 21, 22, 208, + 121, 21, 22, 193, 103, 208, 121, 21, 22, 192, 158, 208, 121, 21, 22, 210, + 236, 21, 22, 193, 103, 210, 236, 21, 22, 98, 230, 116, 21, 22, 199, 145, + 21, 22, 199, 242, 21, 22, 198, 193, 21, 22, 198, 170, 21, 22, 159, 21, + 22, 198, 59, 21, 22, 192, 158, 198, 59, 21, 22, 98, 237, 131, 21, 22, 98, + 237, 44, 21, 22, 190, 190, 21, 22, 199, 245, 21, 22, 197, 41, 21, 22, + 193, 103, 197, 41, 21, 22, 197, 19, 21, 22, 193, 103, 197, 19, 21, 22, + 197, 18, 21, 22, 193, 103, 197, 18, 21, 22, 109, 21, 22, 193, 103, 109, + 21, 22, 197, 9, 21, 22, 193, 103, 197, 9, 21, 22, 197, 43, 21, 22, 193, + 103, 197, 43, 21, 22, 197, 42, 21, 22, 193, 103, 197, 42, 21, 22, 214, + 209, 197, 42, 21, 22, 200, 43, 21, 22, 197, 127, 21, 22, 197, 111, 21, + 22, 197, 109, 21, 22, 197, 132, 21, 22, 222, 22, 21, 22, 222, 121, 21, + 22, 221, 166, 21, 22, 221, 145, 21, 22, 221, 67, 21, 22, 221, 41, 21, 22, + 192, 158, 221, 41, 21, 22, 155, 21, 22, 222, 127, 21, 22, 220, 174, 21, + 22, 193, 103, 220, 174, 21, 22, 220, 172, 21, 22, 193, 103, 220, 172, 21, + 22, 220, 171, 21, 22, 193, 103, 220, 171, 21, 22, 220, 169, 21, 22, 193, + 103, 220, 169, 21, 22, 220, 168, 21, 22, 193, 103, 220, 168, 21, 22, 220, + 179, 21, 22, 193, 103, 220, 179, 21, 22, 220, 178, 21, 22, 193, 103, 220, + 178, 21, 22, 214, 209, 220, 178, 21, 22, 222, 152, 21, 22, 220, 180, 21, + 22, 202, 1, 222, 6, 21, 22, 202, 1, 221, 146, 21, 22, 202, 1, 221, 56, + 21, 22, 202, 1, 222, 104, 21, 22, 247, 42, 21, 22, 247, 158, 21, 22, 243, + 29, 21, 22, 243, 19, 21, 22, 242, 99, 21, 22, 239, 18, 21, 22, 192, 158, + 239, 18, 21, 22, 247, 160, 21, 22, 247, 159, 21, 22, 238, 149, 21, 22, + 193, 103, 238, 149, 21, 22, 238, 147, 21, 22, 193, 103, 238, 147, 21, 22, + 238, 146, 21, 22, 193, 103, 238, 146, 21, 22, 238, 145, 21, 22, 193, 103, + 238, 145, 21, 22, 238, 144, 21, 22, 193, 103, 238, 144, 21, 22, 238, 151, + 21, 22, 193, 103, 238, 151, 21, 22, 238, 150, 21, 22, 193, 103, 238, 150, + 21, 22, 214, 209, 238, 150, 21, 22, 247, 193, 21, 22, 205, 101, 199, 51, + 21, 22, 216, 232, 21, 22, 217, 150, 21, 22, 216, 100, 21, 22, 216, 61, + 21, 22, 216, 12, 21, 22, 215, 211, 21, 22, 192, 158, 215, 211, 21, 22, + 174, 21, 22, 217, 151, 21, 22, 215, 78, 21, 22, 193, 103, 215, 78, 21, + 22, 215, 76, 21, 22, 193, 103, 215, 76, 21, 22, 215, 75, 21, 22, 193, + 103, 215, 75, 21, 22, 215, 74, 21, 22, 193, 103, 215, 74, 21, 22, 215, + 73, 21, 22, 193, 103, 215, 73, 21, 22, 215, 80, 21, 22, 193, 103, 215, + 80, 21, 22, 215, 79, 21, 22, 193, 103, 215, 79, 21, 22, 214, 209, 215, + 79, 21, 22, 218, 168, 21, 22, 193, 103, 218, 168, 21, 22, 216, 104, 21, + 22, 250, 180, 218, 168, 21, 22, 205, 101, 218, 168, 21, 22, 214, 121, 21, + 22, 214, 249, 21, 22, 213, 219, 21, 22, 213, 186, 21, 22, 213, 43, 21, + 22, 213, 26, 21, 22, 192, 158, 213, 26, 21, 22, 180, 21, 22, 214, 250, + 21, 22, 212, 108, 21, 22, 193, 103, 212, 108, 21, 22, 212, 110, 21, 22, + 193, 103, 212, 110, 21, 22, 212, 109, 21, 22, 193, 103, 212, 109, 21, 22, + 214, 209, 212, 109, 21, 22, 215, 61, 21, 22, 98, 214, 70, 21, 22, 213, + 225, 21, 22, 219, 238, 21, 22, 220, 124, 21, 22, 219, 146, 21, 22, 219, + 128, 21, 22, 219, 43, 21, 22, 219, 8, 21, 22, 192, 158, 219, 8, 21, 22, + 173, 21, 22, 220, 125, 21, 22, 218, 189, 21, 22, 193, 103, 218, 189, 21, + 22, 218, 188, 21, 22, 193, 103, 218, 188, 21, 22, 218, 187, 21, 22, 193, + 103, 218, 187, 21, 22, 218, 186, 21, 22, 193, 103, 218, 186, 21, 22, 218, + 185, 21, 22, 193, 103, 218, 185, 21, 22, 218, 191, 21, 22, 193, 103, 218, + 191, 21, 22, 218, 190, 21, 22, 193, 103, 218, 190, 21, 22, 172, 21, 22, + 193, 103, 172, 21, 22, 216, 217, 172, 21, 22, 205, 68, 21, 22, 205, 195, + 21, 22, 202, 222, 21, 22, 202, 193, 21, 22, 202, 46, 21, 22, 202, 16, 21, + 22, 192, 158, 202, 16, 21, 22, 188, 21, 22, 205, 197, 21, 22, 200, 145, + 21, 22, 193, 103, 200, 145, 21, 22, 200, 139, 21, 22, 193, 103, 200, 139, + 21, 22, 200, 138, 21, 22, 193, 103, 200, 138, 21, 22, 200, 133, 21, 22, + 193, 103, 200, 133, 21, 22, 200, 132, 21, 22, 193, 103, 200, 132, 21, 22, + 200, 150, 21, 22, 193, 103, 200, 150, 21, 22, 200, 149, 21, 22, 193, 103, + 200, 149, 21, 22, 214, 209, 200, 149, 21, 22, 206, 8, 21, 22, 250, 180, + 206, 8, 21, 22, 200, 151, 21, 22, 248, 136, 206, 8, 21, 22, 215, 203, + 202, 114, 21, 22, 214, 209, 202, 101, 21, 22, 214, 209, 206, 6, 21, 22, + 214, 209, 201, 192, 21, 22, 214, 209, 201, 7, 21, 22, 214, 209, 202, 100, + 21, 22, 214, 209, 205, 71, 21, 22, 203, 113, 21, 22, 203, 81, 21, 22, + 203, 76, 21, 22, 203, 56, 21, 22, 203, 48, 21, 22, 203, 165, 21, 22, 203, + 160, 21, 22, 202, 237, 21, 22, 193, 103, 202, 237, 21, 22, 202, 236, 21, + 22, 193, 103, 202, 236, 21, 22, 202, 235, 21, 22, 193, 103, 202, 235, 21, + 22, 202, 234, 21, 22, 193, 103, 202, 234, 21, 22, 202, 233, 21, 22, 193, + 103, 202, 233, 21, 22, 202, 240, 21, 22, 193, 103, 202, 240, 21, 22, 202, + 239, 21, 22, 193, 103, 202, 239, 21, 22, 203, 167, 21, 22, 192, 80, 21, + 22, 192, 138, 21, 22, 192, 33, 21, 22, 192, 23, 21, 22, 192, 12, 21, 22, + 191, 246, 21, 22, 192, 158, 191, 246, 21, 22, 170, 21, 22, 192, 140, 21, + 22, 191, 181, 21, 22, 193, 103, 191, 181, 21, 22, 191, 180, 21, 22, 193, + 103, 191, 180, 21, 22, 191, 179, 21, 22, 193, 103, 191, 179, 21, 22, 191, + 178, 21, 22, 193, 103, 191, 178, 21, 22, 191, 177, 21, 22, 193, 103, 191, + 177, 21, 22, 191, 183, 21, 22, 193, 103, 191, 183, 21, 22, 191, 182, 21, + 22, 193, 103, 191, 182, 21, 22, 214, 209, 191, 182, 21, 22, 192, 159, 21, + 22, 248, 186, 192, 159, 21, 22, 193, 103, 192, 159, 21, 22, 205, 101, + 192, 33, 21, 22, 207, 113, 21, 22, 207, 221, 207, 113, 21, 22, 193, 103, + 219, 238, 21, 22, 207, 177, 21, 22, 207, 1, 21, 22, 206, 195, 21, 22, + 206, 162, 21, 22, 206, 134, 21, 22, 193, 103, 219, 43, 21, 22, 165, 21, + 22, 207, 178, 21, 22, 193, 103, 173, 21, 22, 206, 25, 21, 22, 193, 103, + 206, 25, 21, 22, 146, 21, 22, 193, 103, 146, 21, 22, 216, 217, 146, 21, + 22, 233, 59, 21, 22, 233, 106, 21, 22, 233, 23, 21, 22, 233, 8, 21, 22, + 232, 175, 21, 22, 232, 162, 21, 22, 233, 109, 21, 22, 233, 108, 21, 22, + 232, 61, 21, 22, 193, 103, 232, 61, 21, 22, 233, 175, 21, 22, 199, 33, + 21, 22, 215, 59, 199, 33, 21, 22, 199, 11, 21, 22, 215, 59, 199, 11, 21, + 22, 199, 5, 21, 22, 215, 59, 199, 5, 21, 22, 198, 241, 21, 22, 198, 235, + 21, 22, 199, 49, 21, 22, 199, 48, 21, 22, 198, 203, 21, 22, 193, 103, + 198, 203, 21, 22, 199, 51, 21, 22, 197, 118, 21, 22, 197, 116, 21, 22, + 197, 115, 21, 22, 197, 120, 21, 22, 197, 121, 21, 22, 197, 2, 21, 22, + 197, 1, 21, 22, 197, 0, 21, 22, 197, 4, 21, 22, 212, 129, 229, 245, 21, + 22, 212, 129, 229, 158, 21, 22, 212, 129, 229, 130, 21, 22, 212, 129, + 229, 23, 21, 22, 212, 129, 228, 252, 21, 22, 212, 129, 140, 21, 22, 212, + 129, 230, 91, 21, 22, 212, 129, 230, 116, 21, 22, 212, 128, 230, 116, 21, + 22, 229, 113, 21, 22, 208, 92, 21, 22, 208, 57, 21, 22, 208, 51, 21, 22, + 208, 45, 21, 22, 208, 40, 21, 22, 208, 96, 21, 22, 208, 95, 21, 22, 208, + 104, 21, 22, 198, 111, 21, 22, 198, 109, 21, 22, 198, 108, 21, 22, 198, + 112, 21, 22, 193, 103, 207, 113, 21, 22, 193, 103, 207, 1, 21, 22, 193, + 103, 206, 162, 21, 22, 193, 103, 165, 21, 22, 214, 66, 21, 22, 214, 16, + 21, 22, 214, 12, 21, 22, 213, 249, 21, 22, 213, 244, 21, 22, 214, 68, 21, + 22, 214, 67, 21, 22, 214, 70, 21, 22, 213, 72, 21, 22, 205, 101, 203, + 113, 21, 22, 205, 101, 203, 81, 21, 22, 205, 101, 203, 56, 21, 22, 205, + 101, 203, 165, 21, 22, 193, 27, 199, 33, 21, 22, 193, 27, 199, 11, 21, + 22, 193, 27, 198, 241, 21, 22, 193, 27, 199, 49, 21, 22, 193, 27, 199, + 51, 21, 22, 219, 153, 21, 22, 219, 152, 21, 22, 219, 151, 21, 22, 219, + 150, 21, 22, 219, 159, 21, 22, 219, 158, 21, 22, 219, 160, 21, 22, 199, + 50, 199, 33, 21, 22, 199, 50, 199, 11, 21, 22, 199, 50, 199, 5, 21, 22, + 199, 50, 198, 241, 21, 22, 199, 50, 198, 235, 21, 22, 199, 50, 199, 49, + 21, 22, 199, 50, 199, 48, 21, 22, 199, 50, 199, 51, 21, 22, 251, 220, + 250, 120, 21, 22, 248, 136, 71, 21, 22, 248, 136, 68, 21, 22, 248, 136, + 74, 21, 22, 248, 136, 65, 21, 22, 248, 136, 193, 125, 21, 22, 248, 136, + 193, 86, 21, 22, 248, 136, 193, 48, 21, 22, 248, 136, 193, 190, 21, 22, + 248, 136, 214, 121, 21, 22, 248, 136, 213, 219, 21, 22, 248, 136, 213, + 43, 21, 22, 248, 136, 180, 21, 22, 248, 136, 222, 22, 21, 22, 248, 136, + 221, 166, 21, 22, 248, 136, 221, 67, 21, 22, 248, 136, 155, 21, 22, 205, + 101, 229, 245, 21, 22, 205, 101, 229, 158, 21, 22, 205, 101, 229, 23, 21, + 22, 205, 101, 140, 21, 22, 98, 231, 59, 21, 22, 98, 231, 63, 21, 22, 98, + 231, 77, 21, 22, 98, 231, 76, 21, 22, 98, 231, 65, 21, 22, 98, 231, 91, + 21, 22, 98, 206, 68, 21, 22, 98, 206, 162, 21, 22, 98, 207, 113, 21, 22, + 98, 207, 84, 21, 22, 98, 207, 1, 21, 22, 98, 165, 21, 22, 98, 193, 0, 21, + 22, 98, 193, 48, 21, 22, 98, 193, 125, 21, 22, 98, 193, 114, 21, 22, 98, + 193, 86, 21, 22, 98, 193, 190, 21, 22, 98, 228, 118, 21, 22, 98, 228, + 119, 21, 22, 98, 228, 122, 21, 22, 98, 228, 121, 21, 22, 98, 228, 120, + 21, 22, 98, 228, 125, 21, 22, 98, 198, 213, 21, 22, 98, 198, 241, 21, 22, + 98, 199, 33, 21, 22, 98, 199, 31, 21, 22, 98, 199, 11, 21, 22, 98, 199, + 49, 21, 22, 98, 197, 99, 21, 22, 98, 197, 109, 21, 22, 98, 197, 127, 21, + 22, 98, 197, 126, 21, 22, 98, 197, 111, 21, 22, 98, 197, 132, 21, 22, 98, + 208, 165, 21, 22, 98, 209, 73, 21, 22, 98, 210, 63, 21, 22, 98, 210, 49, + 21, 22, 98, 209, 185, 21, 22, 98, 168, 21, 22, 98, 210, 236, 21, 22, 98, + 230, 179, 21, 22, 98, 231, 3, 21, 22, 98, 231, 165, 21, 22, 98, 231, 157, + 21, 22, 98, 231, 53, 21, 22, 98, 231, 240, 21, 22, 98, 221, 175, 21, 22, + 98, 221, 183, 21, 22, 98, 221, 197, 21, 22, 98, 221, 196, 21, 22, 98, + 221, 190, 21, 22, 98, 221, 215, 21, 22, 98, 221, 96, 21, 22, 98, 221, 97, + 21, 22, 98, 221, 100, 21, 22, 98, 221, 99, 21, 22, 98, 221, 98, 21, 22, + 98, 221, 101, 21, 22, 98, 221, 102, 21, 22, 98, 212, 178, 21, 22, 98, + 213, 43, 21, 22, 98, 214, 121, 21, 22, 98, 214, 110, 21, 22, 98, 213, + 219, 21, 22, 98, 180, 21, 22, 98, 215, 155, 21, 22, 98, 216, 12, 21, 22, + 98, 216, 232, 21, 22, 98, 216, 211, 21, 22, 98, 216, 100, 21, 22, 98, + 174, 21, 22, 98, 191, 225, 21, 22, 98, 192, 12, 21, 22, 98, 192, 80, 21, + 22, 98, 192, 77, 21, 22, 98, 192, 33, 21, 22, 98, 170, 21, 22, 98, 222, + 182, 21, 22, 205, 101, 222, 182, 21, 22, 98, 222, 201, 21, 22, 98, 223, + 10, 21, 22, 98, 223, 8, 21, 22, 98, 222, 244, 21, 22, 205, 101, 222, 244, + 21, 22, 98, 223, 32, 21, 22, 98, 222, 215, 21, 22, 98, 222, 219, 21, 22, + 98, 222, 229, 21, 22, 98, 222, 228, 21, 22, 98, 222, 227, 21, 22, 98, + 222, 230, 21, 22, 98, 218, 225, 21, 22, 98, 219, 43, 21, 22, 98, 219, + 238, 21, 22, 98, 219, 228, 21, 22, 98, 219, 146, 21, 22, 98, 173, 21, 22, + 98, 236, 179, 21, 22, 98, 236, 180, 21, 22, 98, 236, 185, 21, 22, 98, + 236, 184, 21, 22, 98, 236, 181, 21, 22, 98, 236, 186, 21, 22, 98, 219, + 149, 21, 22, 98, 219, 151, 21, 22, 98, 219, 155, 21, 22, 98, 219, 154, + 21, 22, 98, 219, 153, 21, 22, 98, 219, 159, 21, 22, 98, 198, 106, 21, 22, + 98, 198, 108, 21, 22, 98, 198, 111, 21, 22, 98, 198, 110, 21, 22, 98, + 198, 109, 21, 22, 98, 198, 112, 21, 22, 98, 198, 101, 21, 22, 98, 198, + 102, 21, 22, 98, 198, 114, 21, 22, 98, 198, 113, 21, 22, 98, 198, 103, + 21, 22, 98, 198, 115, 21, 22, 98, 190, 251, 21, 22, 98, 191, 7, 21, 22, + 98, 191, 87, 21, 22, 98, 191, 84, 21, 22, 98, 191, 30, 21, 22, 98, 191, + 123, 21, 22, 98, 191, 166, 21, 22, 98, 89, 191, 166, 21, 22, 98, 235, 22, + 21, 22, 98, 235, 23, 21, 22, 98, 235, 32, 21, 22, 98, 235, 31, 21, 22, + 98, 235, 26, 21, 22, 98, 235, 35, 21, 22, 98, 201, 4, 21, 22, 98, 202, + 46, 21, 22, 98, 205, 68, 21, 22, 98, 205, 50, 21, 22, 98, 202, 222, 21, + 22, 98, 188, 21, 22, 98, 203, 5, 21, 22, 98, 203, 56, 21, 22, 98, 203, + 113, 21, 22, 98, 203, 111, 21, 22, 98, 203, 81, 21, 22, 98, 203, 165, 21, + 22, 98, 203, 167, 21, 22, 98, 197, 140, 21, 22, 98, 197, 144, 21, 22, 98, + 197, 161, 21, 22, 98, 197, 160, 21, 22, 98, 197, 146, 21, 22, 98, 197, + 168, 21, 22, 98, 243, 48, 21, 22, 98, 243, 68, 21, 22, 98, 243, 127, 21, + 22, 98, 243, 123, 21, 22, 98, 243, 95, 21, 22, 98, 247, 1, 21, 22, 98, + 197, 102, 21, 22, 98, 197, 103, 21, 22, 98, 197, 106, 21, 22, 98, 197, + 105, 21, 22, 98, 197, 104, 21, 22, 98, 197, 107, 21, 22, 243, 96, 56, 21, + 22, 232, 80, 201, 63, 21, 22, 208, 88, 21, 22, 214, 64, 21, 22, 213, 69, + 21, 22, 213, 68, 21, 22, 213, 67, 21, 22, 213, 66, 21, 22, 213, 71, 21, + 22, 213, 70, 21, 22, 193, 27, 198, 201, 21, 22, 193, 27, 198, 200, 21, + 22, 193, 27, 198, 199, 21, 22, 193, 27, 198, 198, 21, 22, 193, 27, 198, + 197, 21, 22, 193, 27, 198, 204, 21, 22, 193, 27, 198, 203, 21, 22, 193, + 27, 53, 199, 51, 21, 22, 248, 136, 193, 224, 211, 140, 201, 248, 77, 211, + 140, 1, 248, 239, 211, 140, 1, 218, 211, 211, 140, 1, 233, 56, 211, 140, + 1, 205, 179, 211, 140, 1, 213, 166, 211, 140, 1, 196, 165, 211, 140, 1, + 238, 5, 211, 140, 1, 198, 139, 211, 140, 1, 242, 86, 211, 140, 1, 247, + 29, 211, 140, 1, 215, 137, 211, 140, 1, 230, 234, 211, 140, 1, 214, 54, + 211, 140, 1, 201, 54, 211, 140, 1, 206, 55, 211, 140, 1, 251, 232, 211, + 140, 1, 211, 91, 211, 140, 1, 196, 62, 211, 140, 1, 234, 215, 211, 140, + 1, 223, 87, 211, 140, 1, 234, 216, 211, 140, 1, 211, 56, 211, 140, 1, + 196, 136, 211, 140, 1, 223, 205, 211, 140, 1, 234, 213, 211, 140, 1, 210, + 38, 211, 140, 233, 55, 77, 211, 140, 207, 18, 233, 55, 77, 206, 44, 1, + 233, 45, 233, 36, 233, 60, 233, 175, 206, 44, 1, 196, 12, 206, 44, 1, + 196, 47, 196, 63, 66, 206, 44, 1, 191, 228, 206, 44, 1, 192, 159, 206, + 44, 1, 193, 224, 206, 44, 1, 198, 206, 198, 205, 198, 233, 206, 44, 1, + 233, 248, 206, 44, 1, 251, 90, 65, 206, 44, 1, 211, 37, 74, 206, 44, 1, + 252, 64, 65, 206, 44, 1, 252, 9, 206, 44, 1, 219, 15, 74, 206, 44, 1, + 203, 33, 74, 206, 44, 1, 74, 206, 44, 1, 211, 151, 206, 44, 1, 211, 104, + 206, 44, 1, 207, 154, 207, 169, 207, 69, 146, 206, 44, 1, 222, 39, 206, + 44, 1, 247, 25, 206, 44, 1, 222, 40, 222, 152, 206, 44, 1, 232, 51, 206, + 44, 1, 234, 88, 206, 44, 1, 231, 160, 230, 122, 232, 51, 206, 44, 1, 231, + 200, 206, 44, 1, 192, 248, 192, 239, 193, 224, 206, 44, 1, 230, 82, 230, + 116, 206, 44, 1, 230, 86, 230, 116, 206, 44, 1, 219, 17, 230, 116, 206, + 44, 1, 203, 36, 230, 116, 206, 44, 1, 214, 203, 212, 91, 214, 204, 215, + 61, 206, 44, 1, 203, 34, 215, 61, 206, 44, 1, 235, 135, 206, 44, 1, 223, + 65, 223, 69, 223, 55, 68, 206, 44, 1, 71, 206, 44, 1, 222, 255, 223, 35, + 206, 44, 1, 231, 141, 206, 44, 1, 219, 18, 252, 25, 206, 44, 1, 203, 38, + 65, 206, 44, 1, 223, 47, 234, 61, 206, 44, 1, 209, 247, 210, 18, 210, + 236, 206, 44, 1, 251, 185, 234, 59, 206, 44, 1, 201, 254, 206, 8, 206, + 44, 1, 202, 198, 219, 14, 206, 8, 206, 44, 1, 203, 32, 206, 8, 206, 44, + 1, 247, 193, 206, 44, 1, 191, 166, 206, 44, 1, 198, 120, 198, 132, 196, + 242, 200, 43, 206, 44, 1, 203, 31, 200, 43, 206, 44, 1, 238, 127, 206, + 44, 1, 248, 217, 248, 220, 248, 142, 250, 120, 206, 44, 1, 203, 37, 250, + 120, 206, 44, 1, 235, 134, 206, 44, 1, 211, 70, 206, 44, 1, 234, 167, + 234, 174, 71, 206, 44, 1, 217, 79, 217, 91, 218, 168, 206, 44, 1, 219, + 16, 218, 168, 206, 44, 1, 203, 35, 218, 168, 206, 44, 1, 219, 253, 220, + 101, 219, 26, 172, 206, 44, 1, 235, 136, 206, 44, 1, 223, 135, 206, 44, + 1, 223, 136, 206, 44, 1, 238, 19, 238, 25, 238, 127, 206, 44, 1, 211, 28, + 233, 247, 74, 206, 44, 1, 234, 211, 206, 44, 1, 223, 85, 206, 44, 1, 238, + 148, 206, 44, 1, 247, 143, 206, 44, 1, 247, 41, 206, 44, 1, 201, 108, + 206, 44, 1, 219, 13, 206, 44, 1, 203, 30, 206, 44, 1, 228, 25, 206, 44, + 1, 208, 104, 206, 44, 1, 192, 235, 206, 44, 202, 170, 208, 151, 206, 44, + 215, 129, 208, 151, 206, 44, 238, 218, 208, 151, 206, 44, 250, 252, 113, + 206, 44, 197, 45, 113, 206, 44, 248, 237, 113, 206, 44, 1, 222, 152, 206, + 44, 1, 203, 167, 206, 44, 1, 211, 87, 206, 44, 1, 232, 110, 247, 81, 211, + 36, 206, 44, 1, 232, 110, 247, 81, 223, 68, 206, 44, 1, 232, 110, 247, + 81, 234, 173, 206, 44, 1, 232, 110, 247, 81, 252, 63, 206, 44, 1, 232, + 110, 247, 81, 252, 9, 199, 222, 1, 65, 199, 222, 1, 68, 199, 222, 1, 66, + 199, 222, 1, 155, 199, 222, 1, 231, 240, 199, 222, 1, 214, 68, 199, 222, + 1, 190, 190, 199, 222, 1, 238, 32, 199, 222, 1, 180, 199, 222, 1, 168, + 199, 222, 1, 249, 153, 199, 222, 1, 174, 199, 222, 1, 170, 199, 222, 1, + 165, 199, 222, 1, 173, 199, 222, 1, 193, 190, 199, 222, 1, 188, 199, 222, + 1, 140, 199, 222, 18, 3, 68, 199, 222, 18, 3, 66, 199, 222, 3, 195, 40, + 199, 222, 3, 210, 169, 199, 222, 1, 251, 14, 165, 230, 23, 1, 65, 230, + 23, 1, 68, 230, 23, 1, 66, 230, 23, 1, 155, 230, 23, 1, 231, 240, 230, + 23, 1, 214, 68, 230, 23, 1, 190, 190, 230, 23, 1, 238, 32, 230, 23, 1, + 180, 230, 23, 1, 168, 230, 23, 1, 249, 153, 230, 23, 1, 174, 230, 23, 1, + 170, 230, 23, 1, 165, 230, 23, 1, 173, 230, 23, 1, 193, 190, 230, 23, 1, + 188, 230, 23, 1, 140, 230, 23, 18, 3, 68, 230, 23, 18, 3, 66, 230, 23, 3, + 210, 169, 209, 204, 202, 170, 208, 151, 209, 204, 55, 208, 151, 248, 0, + 1, 65, 248, 0, 1, 68, 248, 0, 1, 66, 248, 0, 1, 155, 248, 0, 1, 231, 240, + 248, 0, 1, 214, 68, 248, 0, 1, 190, 190, 248, 0, 1, 238, 32, 248, 0, 1, + 180, 248, 0, 1, 168, 248, 0, 1, 249, 153, 248, 0, 1, 174, 248, 0, 1, 170, + 248, 0, 1, 165, 248, 0, 1, 173, 248, 0, 1, 193, 190, 248, 0, 1, 188, 248, + 0, 1, 140, 248, 0, 18, 3, 68, 248, 0, 18, 3, 66, 199, 221, 1, 65, 199, + 221, 1, 68, 199, 221, 1, 66, 199, 221, 1, 155, 199, 221, 1, 231, 240, + 199, 221, 1, 214, 68, 199, 221, 1, 190, 190, 199, 221, 1, 238, 32, 199, + 221, 1, 180, 199, 221, 1, 168, 199, 221, 1, 249, 153, 199, 221, 1, 174, + 199, 221, 1, 170, 199, 221, 1, 173, 199, 221, 1, 193, 190, 199, 221, 1, + 188, 199, 221, 18, 3, 68, 199, 221, 18, 3, 66, 95, 1, 155, 95, 1, 221, + 215, 95, 1, 221, 67, 95, 1, 221, 183, 95, 1, 213, 249, 95, 1, 247, 160, + 95, 1, 247, 1, 95, 1, 242, 99, 95, 1, 243, 68, 95, 1, 212, 65, 95, 1, + 238, 32, 95, 1, 197, 120, 95, 1, 236, 174, 95, 1, 197, 115, 95, 1, 213, + 49, 95, 1, 190, 190, 95, 1, 199, 49, 95, 1, 159, 95, 1, 198, 241, 95, 1, + 213, 43, 95, 1, 249, 153, 95, 1, 209, 228, 95, 1, 209, 73, 95, 1, 209, + 199, 95, 1, 216, 12, 95, 1, 192, 12, 95, 1, 206, 162, 95, 1, 219, 43, 95, + 1, 195, 24, 95, 1, 203, 165, 95, 1, 201, 134, 95, 1, 188, 95, 1, 140, 95, + 1, 173, 95, 1, 208, 96, 95, 223, 149, 18, 208, 82, 95, 223, 149, 18, 208, + 95, 95, 223, 149, 18, 208, 57, 95, 223, 149, 18, 208, 51, 95, 223, 149, + 18, 208, 33, 95, 223, 149, 18, 208, 0, 95, 223, 149, 18, 207, 244, 95, + 223, 149, 18, 207, 243, 95, 223, 149, 18, 206, 17, 95, 223, 149, 18, 206, + 10, 95, 223, 149, 18, 218, 183, 95, 223, 149, 18, 218, 171, 95, 223, 149, + 18, 208, 75, 95, 223, 149, 18, 208, 88, 95, 223, 149, 18, 208, 41, 196, + 255, 107, 95, 223, 149, 18, 208, 41, 196, 255, 109, 95, 223, 149, 18, + 208, 77, 95, 18, 223, 133, 251, 37, 95, 18, 223, 133, 252, 206, 95, 18, + 3, 252, 206, 95, 18, 3, 68, 95, 18, 3, 223, 199, 95, 18, 3, 192, 159, 95, + 18, 3, 191, 176, 95, 18, 3, 66, 95, 18, 3, 196, 30, 95, 18, 3, 196, 168, + 95, 18, 3, 211, 151, 95, 18, 3, 170, 95, 18, 3, 223, 226, 95, 18, 3, 71, + 95, 18, 3, 252, 25, 95, 18, 3, 251, 236, 95, 18, 3, 211, 87, 95, 18, 3, + 250, 163, 95, 3, 213, 184, 95, 3, 207, 106, 95, 3, 191, 187, 95, 3, 215, + 91, 95, 3, 197, 229, 95, 3, 249, 90, 95, 3, 206, 151, 95, 3, 198, 90, 95, + 3, 222, 95, 95, 3, 251, 238, 95, 3, 205, 143, 205, 135, 95, 3, 195, 37, + 95, 3, 242, 90, 95, 3, 249, 60, 95, 3, 221, 205, 95, 3, 249, 85, 95, 3, + 247, 131, 209, 146, 220, 186, 95, 3, 219, 205, 198, 59, 95, 3, 248, 205, + 95, 3, 209, 201, 215, 148, 95, 3, 221, 39, 95, 238, 170, 16, 206, 241, + 95, 3, 250, 144, 95, 3, 250, 166, 95, 17, 191, 77, 95, 17, 107, 95, 17, + 109, 95, 17, 138, 95, 17, 134, 95, 17, 149, 95, 17, 169, 95, 17, 175, 95, + 17, 171, 95, 17, 178, 95, 16, 219, 205, 250, 168, 202, 19, 95, 16, 219, + 205, 250, 168, 215, 112, 95, 16, 219, 205, 250, 168, 209, 145, 95, 16, + 219, 205, 250, 168, 248, 240, 95, 16, 219, 205, 250, 168, 247, 236, 95, + 16, 219, 205, 250, 168, 208, 245, 95, 16, 219, 205, 250, 168, 208, 239, + 95, 16, 219, 205, 250, 168, 208, 237, 95, 16, 219, 205, 250, 168, 208, + 243, 95, 16, 219, 205, 250, 168, 208, 241, 104, 248, 158, 104, 234, 120, + 104, 242, 74, 104, 232, 80, 201, 63, 104, 242, 83, 104, 232, 128, 236, + 138, 104, 198, 88, 202, 32, 228, 88, 104, 202, 214, 5, 248, 73, 217, 51, + 104, 217, 87, 242, 74, 104, 217, 87, 232, 80, 201, 63, 104, 213, 164, + 104, 232, 109, 67, 205, 35, 107, 104, 232, 109, 67, 205, 35, 109, 104, + 232, 109, 67, 205, 35, 138, 104, 18, 204, 10, 104, 232, 109, 67, 205, 35, + 134, 104, 17, 191, 77, 104, 17, 107, 104, 17, 109, 104, 17, 138, 104, 17, + 134, 104, 17, 149, 104, 17, 169, 104, 17, 175, 104, 17, 171, 104, 17, + 178, 104, 1, 65, 104, 1, 71, 104, 1, 68, 104, 1, 74, 104, 1, 66, 104, 1, + 211, 151, 104, 1, 196, 152, 104, 1, 234, 188, 104, 1, 180, 104, 1, 251, + 122, 104, 1, 249, 153, 104, 1, 168, 104, 1, 208, 96, 104, 1, 231, 240, + 104, 1, 174, 104, 1, 173, 104, 1, 188, 104, 1, 203, 165, 104, 1, 190, + 190, 104, 1, 238, 32, 104, 1, 247, 1, 104, 1, 223, 32, 104, 1, 170, 104, + 1, 165, 104, 1, 193, 190, 104, 1, 233, 109, 104, 1, 155, 104, 1, 221, + 215, 104, 1, 197, 168, 104, 1, 191, 123, 104, 1, 230, 91, 104, 1, 190, + 255, 104, 1, 219, 159, 104, 1, 191, 57, 104, 1, 243, 95, 104, 1, 198, 88, + 179, 18, 56, 104, 1, 198, 88, 71, 104, 1, 198, 88, 68, 104, 1, 198, 88, + 74, 104, 1, 198, 88, 66, 104, 1, 198, 88, 211, 151, 104, 1, 198, 88, 196, + 152, 104, 1, 198, 88, 251, 122, 104, 1, 198, 88, 249, 153, 104, 1, 198, + 88, 168, 104, 1, 198, 88, 208, 96, 104, 1, 198, 88, 231, 240, 104, 1, + 198, 88, 174, 104, 1, 198, 88, 190, 190, 104, 1, 198, 88, 238, 32, 104, + 1, 198, 88, 247, 1, 104, 1, 198, 88, 223, 32, 104, 1, 198, 88, 197, 168, + 104, 1, 198, 88, 170, 104, 1, 198, 88, 193, 190, 104, 1, 198, 88, 155, + 104, 1, 198, 88, 231, 237, 104, 1, 198, 88, 230, 91, 104, 1, 198, 88, + 222, 243, 104, 1, 198, 88, 213, 209, 104, 1, 198, 88, 235, 35, 104, 1, + 202, 214, 71, 104, 1, 202, 214, 68, 104, 1, 202, 214, 223, 44, 104, 1, + 202, 214, 196, 152, 104, 1, 202, 214, 66, 104, 1, 202, 214, 251, 122, + 104, 1, 202, 214, 155, 104, 1, 202, 214, 231, 240, 104, 1, 202, 214, 140, + 104, 1, 202, 214, 168, 104, 1, 202, 214, 203, 165, 104, 1, 202, 214, 190, + 190, 104, 1, 202, 214, 238, 32, 104, 1, 202, 214, 223, 32, 104, 1, 202, + 214, 233, 109, 104, 1, 202, 214, 231, 237, 104, 1, 202, 214, 230, 91, + 104, 1, 202, 214, 197, 168, 104, 1, 202, 214, 191, 123, 104, 1, 202, 214, + 207, 178, 104, 1, 202, 214, 247, 1, 104, 1, 202, 214, 191, 71, 104, 1, + 217, 87, 68, 104, 1, 217, 87, 155, 104, 1, 217, 87, 165, 104, 1, 217, 87, + 233, 109, 104, 1, 217, 87, 191, 71, 104, 1, 247, 2, 4, 105, 236, 138, + 104, 1, 251, 184, 231, 220, 251, 72, 107, 104, 1, 251, 184, 231, 220, + 195, 36, 107, 104, 1, 251, 184, 231, 220, 237, 247, 104, 1, 251, 184, + 231, 220, 196, 163, 104, 1, 251, 184, 231, 220, 223, 93, 196, 163, 104, + 1, 251, 184, 231, 220, 249, 104, 104, 1, 251, 184, 231, 220, 115, 249, + 104, 104, 1, 251, 184, 231, 220, 65, 104, 1, 251, 184, 231, 220, 68, 104, + 1, 251, 184, 231, 220, 155, 104, 1, 251, 184, 231, 220, 214, 68, 104, 1, + 251, 184, 231, 220, 247, 160, 104, 1, 251, 184, 231, 220, 197, 132, 104, + 1, 251, 184, 231, 220, 197, 120, 104, 1, 251, 184, 231, 220, 237, 191, + 104, 1, 251, 184, 231, 220, 213, 79, 104, 1, 251, 184, 231, 220, 190, + 190, 104, 1, 251, 184, 231, 220, 238, 32, 104, 1, 251, 184, 231, 220, + 168, 104, 1, 251, 184, 231, 220, 209, 228, 104, 1, 251, 184, 231, 220, + 201, 175, 104, 1, 251, 184, 231, 220, 191, 71, 104, 1, 251, 184, 231, + 220, 191, 123, 104, 1, 251, 184, 231, 220, 251, 245, 104, 1, 198, 88, + 251, 184, 231, 220, 190, 190, 104, 1, 198, 88, 251, 184, 231, 220, 191, + 71, 104, 1, 217, 87, 251, 184, 231, 220, 231, 91, 104, 1, 217, 87, 251, + 184, 231, 220, 214, 68, 104, 1, 217, 87, 251, 184, 231, 220, 247, 160, + 104, 1, 217, 87, 251, 184, 231, 220, 222, 252, 104, 1, 217, 87, 251, 184, + 231, 220, 197, 132, 104, 1, 217, 87, 251, 184, 231, 220, 237, 175, 104, + 1, 217, 87, 251, 184, 231, 220, 190, 190, 104, 1, 217, 87, 251, 184, 231, + 220, 237, 68, 104, 1, 217, 87, 251, 184, 231, 220, 201, 175, 104, 1, 217, + 87, 251, 184, 231, 220, 238, 142, 104, 1, 217, 87, 251, 184, 231, 220, + 191, 71, 104, 1, 217, 87, 251, 184, 231, 220, 191, 123, 104, 1, 251, 184, + 231, 220, 132, 66, 104, 1, 251, 184, 231, 220, 132, 170, 104, 1, 217, 87, + 251, 184, 231, 220, 248, 203, 104, 1, 251, 184, 231, 220, 238, 20, 104, + 1, 217, 87, 251, 184, 231, 220, 219, 159, 21, 22, 210, 242, 21, 22, 250, + 131, 21, 22, 252, 160, 21, 22, 193, 128, 21, 22, 208, 251, 21, 22, 210, + 72, 21, 22, 208, 113, 21, 22, 199, 154, 21, 22, 222, 29, 21, 22, 220, + 176, 21, 22, 217, 21, 21, 22, 212, 250, 21, 22, 214, 198, 21, 22, 219, + 248, 21, 22, 201, 252, 21, 22, 205, 103, 21, 22, 203, 18, 21, 22, 203, + 117, 21, 22, 202, 232, 21, 22, 191, 234, 21, 22, 192, 86, 21, 22, 207, + 122, 21, 22, 212, 107, 21, 22, 211, 128, 212, 107, 21, 22, 212, 106, 21, + 22, 211, 128, 212, 106, 21, 22, 212, 105, 21, 22, 211, 128, 212, 105, 21, + 22, 212, 104, 21, 22, 211, 128, 212, 104, 21, 22, 206, 22, 21, 22, 206, + 21, 21, 22, 206, 20, 21, 22, 206, 19, 21, 22, 206, 18, 21, 22, 206, 26, + 21, 22, 211, 128, 210, 236, 21, 22, 211, 128, 200, 43, 21, 22, 211, 128, + 222, 152, 21, 22, 211, 128, 247, 193, 21, 22, 211, 128, 218, 168, 21, 22, + 211, 128, 215, 61, 21, 22, 211, 128, 206, 8, 21, 22, 211, 128, 203, 167, + 21, 22, 234, 202, 193, 224, 21, 22, 193, 102, 193, 224, 21, 22, 53, 2, + 206, 188, 21, 22, 53, 207, 147, 236, 140, 21, 22, 207, 221, 206, 23, 21, + 22, 193, 103, 219, 8, 21, 22, 193, 103, 220, 125, 21, 22, 198, 202, 21, + 22, 198, 204, 21, 22, 197, 112, 21, 22, 197, 114, 21, 22, 197, 119, 21, + 22, 198, 105, 21, 22, 198, 107, 21, 22, 205, 101, 202, 237, 21, 22, 205, + 101, 203, 48, 21, 22, 205, 101, 228, 252, 21, 22, 98, 230, 130, 21, 22, + 98, 237, 103, 231, 157, 21, 22, 98, 231, 237, 21, 22, 98, 230, 135, 21, + 22, 205, 101, 222, 162, 21, 22, 98, 222, 160, 21, 22, 249, 5, 237, 103, + 172, 21, 22, 249, 5, 237, 103, 146, 21, 22, 98, 237, 98, 206, 8, 219, + 122, 195, 1, 219, 175, 219, 122, 1, 155, 219, 122, 1, 221, 215, 219, 122, + 1, 231, 240, 219, 122, 1, 231, 91, 219, 122, 1, 214, 68, 219, 122, 1, + 247, 160, 219, 122, 1, 247, 1, 219, 122, 1, 223, 32, 219, 122, 1, 222, + 252, 219, 122, 1, 192, 108, 219, 122, 1, 190, 190, 219, 122, 1, 199, 49, + 219, 122, 1, 238, 32, 219, 122, 1, 237, 68, 219, 122, 1, 180, 219, 122, + 1, 168, 219, 122, 1, 209, 228, 219, 122, 1, 249, 153, 219, 122, 1, 248, + 203, 219, 122, 1, 174, 219, 122, 1, 170, 219, 122, 1, 165, 219, 122, 1, + 173, 219, 122, 1, 193, 190, 219, 122, 1, 203, 165, 219, 122, 1, 201, 175, + 219, 122, 1, 188, 219, 122, 1, 140, 219, 122, 1, 230, 126, 219, 122, 1, + 198, 26, 219, 122, 18, 3, 65, 219, 122, 18, 3, 68, 219, 122, 18, 3, 66, + 219, 122, 18, 3, 234, 188, 219, 122, 18, 3, 251, 236, 219, 122, 18, 3, + 211, 87, 219, 122, 18, 3, 250, 163, 219, 122, 18, 3, 71, 219, 122, 18, 3, + 74, 219, 122, 200, 239, 1, 170, 219, 122, 200, 239, 1, 165, 219, 122, + 200, 239, 1, 193, 190, 219, 122, 2, 1, 155, 219, 122, 2, 1, 214, 68, 219, + 122, 2, 1, 251, 71, 219, 122, 2, 1, 190, 190, 219, 122, 2, 1, 180, 219, + 122, 2, 1, 168, 219, 122, 2, 1, 174, 219, 122, 2, 1, 165, 219, 122, 2, 1, + 173, 219, 122, 3, 215, 134, 219, 122, 3, 222, 1, 219, 122, 3, 205, 198, + 219, 122, 3, 219, 8, 219, 122, 233, 216, 77, 219, 122, 208, 13, 77, 219, + 122, 17, 191, 77, 219, 122, 17, 107, 219, 122, 17, 109, 219, 122, 17, + 138, 219, 122, 17, 134, 219, 122, 17, 149, 219, 122, 17, 169, 219, 122, + 17, 175, 219, 122, 17, 171, 219, 122, 17, 178, 54, 219, 239, 1, 155, 54, + 219, 239, 1, 192, 220, 54, 219, 239, 1, 214, 68, 54, 219, 239, 1, 197, + 168, 54, 219, 239, 1, 188, 54, 219, 239, 1, 170, 54, 219, 239, 1, 190, + 190, 54, 219, 239, 1, 199, 49, 54, 219, 239, 1, 173, 54, 219, 239, 1, + 168, 54, 219, 239, 1, 209, 228, 54, 219, 239, 1, 174, 54, 219, 239, 1, + 233, 109, 54, 219, 239, 1, 195, 188, 54, 219, 239, 1, 140, 54, 219, 239, + 1, 208, 96, 54, 219, 239, 1, 221, 215, 54, 219, 239, 1, 197, 157, 54, + 219, 239, 1, 180, 54, 219, 239, 1, 65, 54, 219, 239, 1, 68, 54, 219, 239, + 1, 234, 188, 54, 219, 239, 1, 234, 173, 54, 219, 239, 1, 66, 54, 219, + 239, 1, 211, 87, 54, 219, 239, 1, 74, 54, 219, 239, 1, 196, 152, 54, 219, + 239, 1, 71, 54, 219, 239, 1, 250, 161, 54, 219, 239, 1, 251, 236, 54, + 219, 239, 1, 198, 77, 54, 219, 239, 1, 198, 76, 54, 219, 239, 1, 198, 75, + 54, 219, 239, 1, 198, 74, 54, 219, 239, 1, 198, 73, 214, 80, 54, 218, + 219, 1, 137, 208, 96, 214, 80, 54, 218, 219, 1, 130, 208, 96, 214, 80, + 54, 218, 219, 1, 137, 155, 214, 80, 54, 218, 219, 1, 137, 192, 220, 214, + 80, 54, 218, 219, 1, 137, 214, 68, 214, 80, 54, 218, 219, 1, 130, 155, + 214, 80, 54, 218, 219, 1, 130, 192, 220, 214, 80, 54, 218, 219, 1, 130, + 214, 68, 214, 80, 54, 218, 219, 1, 137, 197, 168, 214, 80, 54, 218, 219, + 1, 137, 188, 214, 80, 54, 218, 219, 1, 137, 170, 214, 80, 54, 218, 219, + 1, 130, 197, 168, 214, 80, 54, 218, 219, 1, 130, 188, 214, 80, 54, 218, + 219, 1, 130, 170, 214, 80, 54, 218, 219, 1, 137, 190, 190, 214, 80, 54, + 218, 219, 1, 137, 199, 49, 214, 80, 54, 218, 219, 1, 137, 180, 214, 80, + 54, 218, 219, 1, 130, 190, 190, 214, 80, 54, 218, 219, 1, 130, 199, 49, + 214, 80, 54, 218, 219, 1, 130, 180, 214, 80, 54, 218, 219, 1, 137, 168, + 214, 80, 54, 218, 219, 1, 137, 209, 228, 214, 80, 54, 218, 219, 1, 137, + 174, 214, 80, 54, 218, 219, 1, 130, 168, 214, 80, 54, 218, 219, 1, 130, + 209, 228, 214, 80, 54, 218, 219, 1, 130, 174, 214, 80, 54, 218, 219, 1, + 137, 233, 109, 214, 80, 54, 218, 219, 1, 137, 195, 188, 214, 80, 54, 218, + 219, 1, 137, 173, 214, 80, 54, 218, 219, 1, 130, 233, 109, 214, 80, 54, + 218, 219, 1, 130, 195, 188, 214, 80, 54, 218, 219, 1, 130, 173, 214, 80, + 54, 218, 219, 1, 137, 140, 214, 80, 54, 218, 219, 1, 137, 238, 32, 214, + 80, 54, 218, 219, 1, 137, 249, 153, 214, 80, 54, 218, 219, 1, 130, 140, + 214, 80, 54, 218, 219, 1, 130, 238, 32, 214, 80, 54, 218, 219, 1, 130, + 249, 153, 214, 80, 54, 218, 219, 1, 137, 220, 181, 214, 80, 54, 218, 219, + 1, 137, 192, 185, 214, 80, 54, 218, 219, 1, 130, 220, 181, 214, 80, 54, + 218, 219, 1, 130, 192, 185, 214, 80, 54, 218, 219, 1, 137, 200, 251, 214, + 80, 54, 218, 219, 1, 130, 200, 251, 214, 80, 54, 218, 219, 18, 3, 18, + 203, 28, 214, 80, 54, 218, 219, 18, 3, 252, 206, 214, 80, 54, 218, 219, + 18, 3, 223, 199, 214, 80, 54, 218, 219, 18, 3, 66, 214, 80, 54, 218, 219, + 18, 3, 196, 30, 214, 80, 54, 218, 219, 18, 3, 71, 214, 80, 54, 218, 219, + 18, 3, 252, 25, 214, 80, 54, 218, 219, 18, 3, 74, 214, 80, 54, 218, 219, + 18, 3, 211, 182, 214, 80, 54, 218, 219, 18, 3, 196, 152, 214, 80, 54, + 218, 219, 18, 3, 250, 131, 214, 80, 54, 218, 219, 18, 3, 252, 160, 214, + 80, 54, 218, 219, 18, 3, 196, 21, 214, 80, 54, 218, 219, 18, 3, 210, 242, + 214, 80, 54, 218, 219, 18, 3, 211, 179, 214, 80, 54, 218, 219, 18, 3, + 196, 144, 214, 80, 54, 218, 219, 18, 3, 223, 44, 214, 80, 54, 218, 219, + 1, 53, 196, 12, 214, 80, 54, 218, 219, 1, 53, 214, 70, 214, 80, 54, 218, + 219, 1, 53, 215, 61, 214, 80, 54, 218, 219, 1, 53, 218, 168, 214, 80, 54, + 218, 219, 1, 53, 222, 152, 214, 80, 54, 218, 219, 1, 53, 238, 127, 214, + 80, 54, 218, 219, 1, 53, 250, 120, 214, 80, 54, 218, 219, 163, 217, 55, + 214, 80, 54, 218, 219, 163, 217, 54, 214, 80, 54, 218, 219, 17, 191, 77, + 214, 80, 54, 218, 219, 17, 107, 214, 80, 54, 218, 219, 17, 109, 214, 80, + 54, 218, 219, 17, 138, 214, 80, 54, 218, 219, 17, 134, 214, 80, 54, 218, + 219, 17, 149, 214, 80, 54, 218, 219, 17, 169, 214, 80, 54, 218, 219, 17, + 175, 214, 80, 54, 218, 219, 17, 171, 214, 80, 54, 218, 219, 17, 178, 214, + 80, 54, 218, 219, 128, 17, 107, 214, 80, 54, 218, 219, 3, 220, 107, 214, + 80, 54, 218, 219, 3, 220, 106, 95, 16, 210, 84, 95, 16, 215, 113, 221, + 58, 95, 16, 209, 146, 221, 58, 95, 16, 248, 241, 221, 58, 95, 16, 247, + 237, 221, 58, 95, 16, 208, 246, 221, 58, 95, 16, 208, 240, 221, 58, 95, + 16, 208, 238, 221, 58, 95, 16, 208, 244, 221, 58, 95, 16, 208, 242, 221, + 58, 95, 16, 237, 232, 221, 58, 95, 16, 237, 228, 221, 58, 95, 16, 237, + 227, 221, 58, 95, 16, 237, 230, 221, 58, 95, 16, 237, 229, 221, 58, 95, + 16, 237, 226, 221, 58, 95, 16, 197, 51, 95, 16, 215, 113, 206, 149, 95, + 16, 209, 146, 206, 149, 95, 16, 248, 241, 206, 149, 95, 16, 247, 237, + 206, 149, 95, 16, 208, 246, 206, 149, 95, 16, 208, 240, 206, 149, 95, 16, + 208, 238, 206, 149, 95, 16, 208, 244, 206, 149, 95, 16, 208, 242, 206, + 149, 95, 16, 237, 232, 206, 149, 95, 16, 237, 228, 206, 149, 95, 16, 237, + 227, 206, 149, 95, 16, 237, 230, 206, 149, 95, 16, 237, 229, 206, 149, + 95, 16, 237, 226, 206, 149, 248, 1, 1, 155, 248, 1, 1, 231, 240, 248, 1, + 1, 214, 68, 248, 1, 1, 214, 11, 248, 1, 1, 168, 248, 1, 1, 249, 153, 248, + 1, 1, 174, 248, 1, 1, 215, 166, 248, 1, 1, 190, 190, 248, 1, 1, 238, 32, + 248, 1, 1, 180, 248, 1, 1, 212, 244, 248, 1, 1, 247, 160, 248, 1, 1, 223, + 32, 248, 1, 1, 212, 101, 248, 1, 1, 212, 92, 248, 1, 1, 170, 248, 1, 1, + 165, 248, 1, 1, 173, 248, 1, 1, 195, 188, 248, 1, 1, 188, 248, 1, 1, 65, + 248, 1, 1, 140, 248, 1, 18, 3, 68, 248, 1, 18, 3, 66, 248, 1, 18, 3, 71, + 248, 1, 18, 3, 74, 248, 1, 18, 3, 252, 25, 248, 1, 210, 184, 248, 1, 234, + 95, 79, 205, 53, 54, 128, 1, 137, 155, 54, 128, 1, 137, 221, 215, 54, + 128, 1, 137, 220, 165, 54, 128, 1, 130, 155, 54, 128, 1, 130, 220, 165, + 54, 128, 1, 130, 221, 215, 54, 128, 1, 214, 68, 54, 128, 1, 137, 247, + 160, 54, 128, 1, 137, 247, 1, 54, 128, 1, 130, 247, 160, 54, 128, 1, 130, + 188, 54, 128, 1, 130, 247, 1, 54, 128, 1, 212, 101, 54, 128, 1, 207, 129, + 54, 128, 1, 137, 207, 127, 54, 128, 1, 238, 32, 54, 128, 1, 130, 207, + 127, 54, 128, 1, 207, 138, 54, 128, 1, 137, 190, 190, 54, 128, 1, 137, + 199, 49, 54, 128, 1, 130, 190, 190, 54, 128, 1, 130, 199, 49, 54, 128, 1, + 180, 54, 128, 1, 249, 153, 54, 128, 1, 137, 168, 54, 128, 1, 137, 209, + 228, 54, 128, 1, 137, 233, 109, 54, 128, 1, 130, 168, 54, 128, 1, 130, + 233, 109, 54, 128, 1, 130, 209, 228, 54, 128, 1, 174, 54, 128, 1, 130, + 170, 54, 128, 1, 137, 170, 54, 128, 1, 165, 54, 128, 1, 206, 57, 54, 128, + 1, 173, 54, 128, 1, 218, 218, 54, 128, 1, 193, 190, 54, 128, 1, 137, 203, + 165, 54, 128, 1, 137, 201, 175, 54, 128, 1, 137, 188, 54, 128, 1, 137, + 140, 54, 128, 1, 219, 73, 54, 128, 1, 65, 54, 128, 1, 130, 140, 54, 128, + 1, 68, 54, 128, 1, 223, 199, 54, 128, 1, 66, 54, 128, 1, 196, 30, 54, + 128, 1, 234, 188, 54, 128, 1, 211, 87, 54, 128, 1, 220, 107, 54, 128, 1, + 230, 206, 188, 54, 128, 120, 3, 216, 217, 165, 54, 128, 120, 3, 216, 217, + 173, 54, 128, 120, 3, 220, 126, 199, 190, 220, 96, 54, 128, 3, 217, 113, + 222, 84, 220, 96, 54, 128, 120, 3, 53, 214, 68, 54, 128, 120, 3, 130, + 168, 54, 128, 120, 3, 137, 207, 128, 211, 57, 130, 168, 54, 128, 120, 3, + 174, 54, 128, 120, 3, 249, 153, 54, 128, 120, 3, 188, 54, 128, 3, 205, + 172, 54, 128, 18, 3, 65, 54, 128, 18, 3, 217, 113, 205, 122, 54, 128, 18, + 3, 252, 206, 54, 128, 18, 3, 199, 200, 252, 206, 54, 128, 18, 3, 68, 54, + 128, 18, 3, 223, 199, 54, 128, 18, 3, 196, 152, 54, 128, 18, 3, 196, 29, + 54, 128, 18, 3, 66, 54, 128, 18, 3, 196, 30, 54, 128, 18, 3, 74, 54, 128, + 18, 3, 211, 183, 60, 54, 128, 18, 3, 210, 242, 54, 128, 18, 3, 71, 54, + 128, 18, 3, 252, 25, 54, 128, 18, 3, 211, 87, 54, 128, 18, 3, 251, 236, + 54, 128, 18, 3, 128, 251, 236, 54, 128, 18, 3, 211, 183, 58, 54, 128, 3, + 217, 113, 222, 83, 54, 128, 3, 198, 78, 54, 128, 3, 198, 77, 54, 128, 3, + 221, 171, 198, 76, 54, 128, 3, 221, 171, 198, 75, 54, 128, 3, 221, 171, + 198, 74, 54, 128, 3, 207, 186, 230, 90, 54, 128, 3, 217, 113, 205, 152, + 54, 128, 3, 221, 170, 222, 64, 54, 128, 33, 238, 198, 236, 140, 54, 128, + 228, 243, 17, 191, 77, 54, 128, 228, 243, 17, 107, 54, 128, 228, 243, 17, + 109, 54, 128, 228, 243, 17, 138, 54, 128, 228, 243, 17, 134, 54, 128, + 228, 243, 17, 149, 54, 128, 228, 243, 17, 169, 54, 128, 228, 243, 17, + 175, 54, 128, 228, 243, 17, 171, 54, 128, 228, 243, 17, 178, 54, 128, + 128, 17, 191, 77, 54, 128, 128, 17, 107, 54, 128, 128, 17, 109, 54, 128, + 128, 17, 138, 54, 128, 128, 17, 134, 54, 128, 128, 17, 149, 54, 128, 128, + 17, 169, 54, 128, 128, 17, 175, 54, 128, 128, 17, 171, 54, 128, 128, 17, + 178, 54, 128, 3, 193, 80, 54, 128, 3, 193, 79, 54, 128, 3, 205, 107, 54, + 128, 3, 221, 246, 54, 128, 3, 228, 170, 54, 128, 3, 236, 157, 54, 128, 3, + 207, 18, 206, 122, 207, 138, 54, 128, 3, 217, 113, 192, 109, 54, 128, 3, + 222, 120, 54, 128, 3, 222, 119, 54, 128, 3, 205, 117, 54, 128, 3, 205, + 116, 54, 128, 3, 230, 26, 54, 128, 3, 247, 157, 33, 235, 128, 243, 2, + 252, 60, 33, 237, 41, 33, 223, 139, 33, 235, 119, 57, 33, 197, 225, 236, + 140, 33, 192, 233, 60, 33, 193, 72, 219, 113, 60, 33, 211, 77, 87, 60, + 33, 55, 211, 77, 87, 60, 33, 156, 247, 23, 201, 28, 60, 33, 201, 14, 247, + 23, 201, 28, 60, 33, 210, 115, 58, 33, 55, 210, 115, 58, 33, 210, 115, + 60, 33, 210, 115, 210, 255, 33, 8, 2, 1, 193, 225, 60, 33, 8, 2, 1, 153, + 193, 225, 60, 33, 45, 210, 114, 93, 219, 224, 33, 50, 210, 114, 93, 183, + 33, 45, 210, 114, 248, 233, 219, 224, 33, 50, 210, 114, 248, 233, 183, + 33, 51, 248, 51, 58, 33, 31, 3, 58, 33, 223, 93, 55, 251, 15, 58, 33, + 108, 3, 58, 33, 55, 108, 3, 58, 33, 55, 108, 3, 60, 33, 197, 225, 252, + 47, 252, 60, 33, 8, 2, 1, 223, 115, 232, 51, 33, 8, 2, 1, 223, 115, 146, + 33, 8, 2, 1, 223, 115, 200, 43, 148, 3, 196, 123, 206, 244, 148, 3, 196, + 123, 247, 121, 148, 3, 247, 38, 148, 3, 200, 173, 148, 3, 248, 155, 148, + 1, 251, 214, 148, 1, 251, 215, 199, 123, 148, 1, 223, 194, 148, 1, 223, + 195, 199, 123, 148, 1, 196, 126, 148, 1, 196, 127, 199, 123, 148, 1, 207, + 186, 207, 51, 148, 1, 207, 186, 207, 52, 199, 123, 148, 1, 220, 126, 219, + 199, 148, 1, 220, 126, 219, 200, 199, 123, 148, 1, 234, 145, 148, 1, 251, + 233, 148, 1, 211, 123, 148, 1, 211, 124, 199, 123, 148, 1, 155, 148, 1, + 222, 142, 217, 116, 148, 1, 231, 240, 148, 1, 231, 241, 230, 241, 148, 1, + 214, 68, 148, 1, 247, 160, 148, 1, 247, 161, 220, 112, 148, 1, 223, 32, + 148, 1, 223, 33, 223, 0, 148, 1, 212, 101, 148, 1, 199, 252, 220, 2, 148, + 1, 199, 252, 215, 108, 217, 116, 148, 1, 238, 33, 215, 108, 251, 162, + 148, 1, 238, 33, 215, 108, 217, 116, 148, 1, 215, 7, 207, 141, 148, 1, + 190, 190, 148, 1, 199, 252, 199, 158, 148, 1, 238, 32, 148, 1, 238, 33, + 217, 138, 148, 1, 180, 148, 1, 168, 148, 1, 210, 221, 222, 76, 148, 1, + 249, 153, 148, 1, 249, 154, 222, 2, 148, 1, 174, 148, 1, 170, 148, 1, + 165, 148, 1, 173, 148, 1, 193, 190, 148, 1, 205, 207, 205, 184, 148, 1, + 205, 207, 205, 129, 148, 1, 188, 148, 1, 140, 148, 3, 207, 41, 148, 18, + 3, 199, 123, 148, 18, 3, 196, 122, 148, 18, 3, 196, 123, 205, 125, 148, + 18, 3, 200, 208, 148, 18, 3, 200, 209, 223, 185, 148, 18, 3, 207, 186, + 207, 51, 148, 18, 3, 207, 186, 207, 52, 199, 123, 148, 18, 3, 220, 126, + 219, 199, 148, 18, 3, 220, 126, 219, 200, 199, 123, 148, 18, 3, 199, 201, + 148, 18, 3, 199, 202, 207, 51, 148, 18, 3, 199, 202, 199, 123, 148, 18, + 3, 199, 202, 207, 52, 199, 123, 148, 18, 3, 210, 16, 148, 18, 3, 210, 17, + 199, 123, 148, 252, 37, 252, 36, 148, 1, 222, 107, 205, 124, 148, 1, 221, + 177, 205, 124, 148, 1, 196, 235, 205, 124, 148, 1, 234, 182, 205, 124, + 148, 1, 195, 154, 205, 124, 148, 1, 191, 109, 205, 124, 148, 1, 250, 185, + 205, 124, 148, 1, 251, 14, 222, 202, 148, 17, 191, 77, 148, 17, 107, 148, + 17, 109, 148, 17, 138, 148, 17, 134, 148, 17, 149, 148, 17, 169, 148, 17, + 175, 148, 17, 171, 148, 17, 178, 148, 210, 145, 148, 210, 175, 148, 193, + 64, 148, 247, 94, 210, 168, 148, 247, 94, 202, 190, 148, 247, 94, 210, + 112, 148, 210, 174, 148, 37, 16, 236, 148, 148, 37, 16, 237, 102, 148, + 37, 16, 235, 71, 148, 37, 16, 237, 236, 148, 37, 16, 237, 237, 200, 173, + 148, 37, 16, 236, 242, 148, 37, 16, 238, 24, 148, 37, 16, 237, 77, 148, + 37, 16, 238, 6, 148, 37, 16, 237, 237, 231, 159, 148, 37, 16, 33, 199, + 116, 148, 37, 16, 33, 234, 92, 148, 37, 16, 33, 221, 253, 148, 37, 16, + 33, 221, 255, 148, 37, 16, 33, 223, 5, 148, 37, 16, 33, 221, 254, 4, 223, + 5, 148, 37, 16, 33, 222, 0, 4, 223, 5, 148, 37, 16, 33, 248, 226, 148, + 37, 16, 33, 230, 247, 148, 37, 16, 206, 206, 211, 77, 235, 82, 148, 37, + 16, 206, 206, 211, 77, 238, 22, 148, 37, 16, 206, 206, 242, 219, 197, 80, + 148, 37, 16, 206, 206, 242, 219, 199, 211, 148, 37, 16, 219, 222, 211, + 77, 210, 160, 148, 37, 16, 219, 222, 211, 77, 208, 149, 148, 37, 16, 219, + 222, 242, 219, 209, 104, 148, 37, 16, 219, 222, 242, 219, 209, 86, 148, + 37, 16, 219, 222, 211, 77, 209, 132, 148, 210, 146, 220, 19, 148, 210, + 176, 220, 19, 200, 197, 3, 210, 142, 200, 197, 3, 210, 156, 200, 197, 3, + 210, 152, 200, 197, 1, 65, 200, 197, 1, 68, 200, 197, 1, 66, 200, 197, 1, + 252, 25, 200, 197, 1, 74, 200, 197, 1, 71, 200, 197, 1, 233, 242, 200, + 197, 1, 155, 200, 197, 1, 208, 96, 200, 197, 1, 231, 240, 200, 197, 1, + 214, 68, 200, 197, 1, 247, 160, 200, 197, 1, 223, 32, 200, 197, 1, 191, + 123, 200, 197, 1, 212, 101, 200, 197, 1, 190, 190, 200, 197, 1, 238, 32, + 200, 197, 1, 180, 200, 197, 1, 168, 200, 197, 1, 233, 109, 200, 197, 1, + 195, 188, 200, 197, 1, 249, 153, 200, 197, 1, 174, 200, 197, 1, 170, 200, + 197, 1, 165, 200, 197, 1, 173, 200, 197, 1, 193, 190, 200, 197, 1, 188, + 200, 197, 1, 192, 220, 200, 197, 1, 140, 200, 197, 120, 3, 210, 172, 200, + 197, 120, 3, 210, 144, 200, 197, 120, 3, 210, 141, 200, 197, 18, 3, 210, + 159, 200, 197, 18, 3, 210, 140, 200, 197, 18, 3, 210, 165, 200, 197, 18, + 3, 210, 151, 200, 197, 18, 3, 210, 173, 200, 197, 18, 3, 210, 161, 200, + 197, 3, 210, 177, 200, 197, 3, 195, 40, 200, 197, 120, 3, 210, 100, 174, + 200, 197, 120, 3, 210, 100, 193, 190, 200, 197, 1, 221, 215, 200, 197, 1, + 200, 126, 200, 197, 17, 191, 77, 200, 197, 17, 107, 200, 197, 17, 109, + 200, 197, 17, 138, 200, 197, 17, 134, 200, 197, 17, 149, 200, 197, 17, + 169, 200, 197, 17, 175, 200, 197, 17, 171, 200, 197, 17, 178, 200, 197, + 250, 145, 200, 197, 1, 207, 21, 200, 197, 1, 219, 172, 200, 197, 1, 248, + 203, 200, 197, 1, 53, 222, 152, 200, 197, 1, 53, 218, 168, 249, 63, 1, + 65, 249, 63, 1, 202, 182, 65, 249, 63, 1, 140, 249, 63, 1, 202, 182, 140, + 249, 63, 1, 217, 85, 140, 249, 63, 1, 249, 153, 249, 63, 1, 222, 61, 249, + 153, 249, 63, 1, 168, 249, 63, 1, 202, 182, 168, 249, 63, 1, 180, 249, + 63, 1, 217, 85, 180, 249, 63, 1, 193, 190, 249, 63, 1, 202, 182, 193, + 190, 249, 63, 1, 210, 193, 193, 190, 249, 63, 1, 231, 240, 249, 63, 1, + 202, 182, 231, 240, 249, 63, 1, 223, 32, 249, 63, 1, 238, 32, 249, 63, 1, + 165, 249, 63, 1, 202, 182, 165, 249, 63, 1, 174, 249, 63, 1, 202, 182, + 174, 249, 63, 1, 202, 0, 190, 190, 249, 63, 1, 213, 16, 190, 190, 249, + 63, 1, 188, 249, 63, 1, 202, 182, 188, 249, 63, 1, 217, 85, 188, 249, 63, + 1, 170, 249, 63, 1, 202, 182, 170, 249, 63, 1, 214, 68, 249, 63, 1, 173, + 249, 63, 1, 202, 182, 173, 249, 63, 1, 212, 101, 249, 63, 1, 247, 160, + 249, 63, 1, 214, 162, 249, 63, 1, 217, 11, 249, 63, 1, 68, 249, 63, 1, + 66, 249, 63, 3, 198, 82, 249, 63, 18, 3, 71, 249, 63, 18, 3, 210, 193, + 71, 249, 63, 18, 3, 234, 188, 249, 63, 18, 3, 68, 249, 63, 18, 3, 222, + 61, 68, 249, 63, 18, 3, 74, 249, 63, 18, 3, 222, 61, 74, 249, 63, 18, 3, + 66, 249, 63, 18, 3, 126, 40, 202, 182, 188, 249, 63, 120, 3, 214, 70, + 249, 63, 120, 3, 230, 116, 249, 63, 210, 154, 249, 63, 210, 150, 249, 63, + 16, 248, 165, 215, 7, 216, 163, 249, 63, 16, 248, 165, 209, 138, 249, 63, + 16, 248, 165, 222, 179, 249, 63, 16, 248, 165, 210, 154, 219, 183, 1, + 155, 219, 183, 1, 221, 94, 219, 183, 1, 221, 215, 219, 183, 1, 231, 240, + 219, 183, 1, 231, 19, 219, 183, 1, 214, 68, 219, 183, 1, 247, 160, 219, + 183, 1, 247, 1, 219, 183, 1, 223, 32, 219, 183, 1, 212, 101, 219, 183, 1, + 190, 190, 219, 183, 1, 199, 49, 219, 183, 1, 238, 32, 219, 183, 1, 180, + 219, 183, 1, 168, 219, 183, 1, 209, 110, 219, 183, 1, 209, 228, 219, 183, + 1, 233, 109, 219, 183, 1, 232, 219, 219, 183, 1, 249, 153, 219, 183, 1, + 248, 140, 219, 183, 1, 174, 219, 183, 1, 216, 19, 219, 183, 1, 197, 168, + 219, 183, 1, 197, 157, 219, 183, 1, 235, 35, 219, 183, 1, 170, 219, 183, + 1, 165, 219, 183, 1, 173, 219, 183, 1, 140, 219, 183, 1, 229, 111, 219, + 183, 1, 195, 188, 219, 183, 1, 188, 219, 183, 1, 203, 165, 219, 183, 1, + 193, 190, 219, 183, 1, 65, 219, 183, 200, 239, 1, 170, 219, 183, 200, + 239, 1, 165, 219, 183, 18, 3, 252, 206, 219, 183, 18, 3, 68, 219, 183, + 18, 3, 74, 219, 183, 18, 3, 211, 87, 219, 183, 18, 3, 66, 219, 183, 18, + 3, 196, 30, 219, 183, 18, 3, 71, 219, 183, 120, 3, 222, 152, 219, 183, + 120, 3, 218, 168, 219, 183, 120, 3, 172, 219, 183, 120, 3, 215, 61, 219, + 183, 120, 3, 210, 236, 219, 183, 120, 3, 146, 219, 183, 120, 3, 200, 43, + 219, 183, 120, 3, 212, 73, 219, 183, 120, 3, 222, 83, 219, 183, 3, 207, + 139, 219, 183, 3, 212, 141, 219, 183, 208, 152, 199, 247, 219, 183, 208, + 152, 212, 85, 198, 196, 199, 247, 219, 183, 208, 152, 247, 10, 219, 183, + 208, 152, 197, 149, 247, 10, 219, 183, 208, 152, 197, 148, 219, 183, 17, + 191, 77, 219, 183, 17, 107, 219, 183, 17, 109, 219, 183, 17, 138, 219, + 183, 17, 134, 219, 183, 17, 149, 219, 183, 17, 169, 219, 183, 17, 175, + 219, 183, 17, 171, 219, 183, 17, 178, 219, 183, 1, 197, 132, 219, 183, 1, + 197, 120, 219, 183, 1, 237, 191, 211, 121, 243, 88, 17, 191, 77, 211, + 121, 243, 88, 17, 107, 211, 121, 243, 88, 17, 109, 211, 121, 243, 88, 17, + 138, 211, 121, 243, 88, 17, 134, 211, 121, 243, 88, 17, 149, 211, 121, + 243, 88, 17, 169, 211, 121, 243, 88, 17, 175, 211, 121, 243, 88, 17, 171, + 211, 121, 243, 88, 17, 178, 211, 121, 243, 88, 1, 173, 211, 121, 243, 88, + 1, 250, 182, 211, 121, 243, 88, 1, 251, 253, 211, 121, 243, 88, 1, 251, + 122, 211, 121, 243, 88, 1, 251, 207, 211, 121, 243, 88, 1, 220, 125, 211, + 121, 243, 88, 1, 252, 168, 211, 121, 243, 88, 1, 252, 169, 211, 121, 243, + 88, 1, 252, 167, 211, 121, 243, 88, 1, 252, 161, 211, 121, 243, 88, 1, + 219, 146, 211, 121, 243, 88, 1, 223, 68, 211, 121, 243, 88, 1, 223, 200, + 211, 121, 243, 88, 1, 223, 90, 211, 121, 243, 88, 1, 223, 77, 211, 121, + 243, 88, 1, 218, 225, 211, 121, 243, 88, 1, 196, 160, 211, 121, 243, 88, + 1, 196, 158, 211, 121, 243, 88, 1, 196, 83, 211, 121, 243, 88, 1, 196, + 21, 211, 121, 243, 88, 1, 219, 238, 211, 121, 243, 88, 1, 234, 56, 211, + 121, 243, 88, 1, 234, 191, 211, 121, 243, 88, 1, 234, 103, 211, 121, 243, + 88, 1, 234, 26, 211, 121, 243, 88, 1, 219, 43, 211, 121, 243, 88, 1, 211, + 24, 211, 121, 243, 88, 1, 211, 178, 211, 121, 243, 88, 1, 211, 9, 211, + 121, 243, 88, 1, 211, 136, 211, 121, 243, 88, 215, 156, 197, 97, 211, + 121, 243, 88, 231, 235, 197, 98, 211, 121, 243, 88, 215, 150, 197, 98, + 211, 121, 243, 88, 207, 66, 211, 121, 243, 88, 209, 226, 211, 121, 243, + 88, 251, 244, 211, 121, 243, 88, 208, 152, 215, 146, 211, 121, 243, 88, + 208, 152, 55, 215, 146, 38, 2, 1, 206, 113, 195, 153, 38, 2, 1, 219, 12, + 237, 146, 38, 2, 1, 214, 215, 74, 38, 2, 1, 193, 78, 234, 22, 38, 2, 1, + 199, 200, 199, 145, 38, 2, 1, 198, 221, 199, 145, 38, 2, 1, 199, 200, + 230, 17, 56, 38, 2, 1, 199, 200, 192, 95, 38, 2, 1, 196, 108, 196, 128, + 101, 215, 157, 6, 1, 251, 132, 101, 215, 157, 6, 1, 249, 101, 101, 215, + 157, 6, 1, 231, 210, 101, 215, 157, 6, 1, 236, 150, 101, 215, 157, 6, 1, + 234, 103, 101, 215, 157, 6, 1, 195, 49, 101, 215, 157, 6, 1, 191, 80, + 101, 215, 157, 6, 1, 199, 193, 101, 215, 157, 6, 1, 223, 162, 101, 215, + 157, 6, 1, 222, 87, 101, 215, 157, 6, 1, 220, 7, 101, 215, 157, 6, 1, + 217, 90, 101, 215, 157, 6, 1, 214, 216, 101, 215, 157, 6, 1, 211, 104, + 101, 215, 157, 6, 1, 210, 131, 101, 215, 157, 6, 1, 191, 67, 101, 215, + 157, 6, 1, 207, 163, 101, 215, 157, 6, 1, 205, 142, 101, 215, 157, 6, 1, + 199, 179, 101, 215, 157, 6, 1, 196, 113, 101, 215, 157, 6, 1, 209, 220, + 101, 215, 157, 6, 1, 221, 200, 101, 215, 157, 6, 1, 231, 82, 101, 215, + 157, 6, 1, 208, 81, 101, 215, 157, 6, 1, 203, 69, 101, 215, 157, 6, 1, + 243, 81, 101, 215, 157, 6, 1, 247, 128, 101, 215, 157, 6, 1, 222, 234, + 101, 215, 157, 6, 1, 243, 18, 101, 215, 157, 6, 1, 246, 241, 101, 215, + 157, 6, 1, 192, 218, 101, 215, 157, 6, 1, 222, 249, 101, 215, 157, 6, 1, + 230, 87, 101, 215, 157, 6, 1, 229, 245, 101, 215, 157, 6, 1, 229, 145, + 101, 215, 157, 6, 1, 193, 125, 101, 215, 157, 6, 1, 230, 19, 101, 215, + 157, 6, 1, 229, 11, 101, 215, 157, 6, 1, 233, 23, 101, 215, 157, 6, 1, + 192, 14, 101, 215, 157, 6, 1, 234, 123, 101, 215, 157, 6, 1, 153, 231, + 210, 101, 215, 157, 6, 1, 251, 230, 101, 215, 157, 6, 1, 252, 14, 101, + 215, 157, 6, 1, 230, 17, 56, 101, 215, 157, 6, 1, 220, 116, 56, 200, 197, + 208, 152, 248, 165, 200, 166, 200, 197, 208, 152, 248, 165, 210, 155, + 200, 197, 208, 152, 248, 165, 208, 139, 200, 197, 208, 152, 248, 165, + 247, 145, 200, 197, 208, 152, 248, 165, 219, 173, 205, 121, 200, 197, + 208, 152, 248, 165, 222, 142, 205, 121, 200, 197, 208, 152, 248, 165, + 238, 33, 205, 121, 200, 197, 208, 152, 248, 165, 249, 154, 205, 121, 195, + 150, 163, 222, 57, 195, 150, 163, 203, 130, 195, 150, 163, 208, 225, 195, + 150, 3, 213, 187, 195, 150, 3, 192, 117, 216, 82, 200, 156, 195, 150, + 163, 192, 117, 251, 249, 223, 149, 200, 156, 195, 150, 163, 192, 117, + 223, 149, 200, 156, 195, 150, 163, 192, 117, 222, 45, 223, 149, 200, 156, + 195, 150, 163, 247, 122, 60, 195, 150, 163, 192, 117, 222, 45, 223, 149, + 200, 157, 205, 88, 195, 150, 163, 55, 200, 156, 195, 150, 163, 197, 225, + 200, 156, 195, 150, 163, 222, 45, 251, 73, 195, 150, 163, 75, 60, 195, + 150, 163, 105, 185, 60, 195, 150, 163, 115, 185, 60, 195, 150, 163, 206, + 196, 222, 56, 223, 149, 200, 156, 195, 150, 163, 250, 179, 223, 149, 200, + 156, 195, 150, 3, 195, 36, 200, 156, 195, 150, 3, 195, 36, 196, 154, 195, + 150, 3, 207, 18, 195, 36, 196, 154, 195, 150, 3, 195, 36, 251, 73, 195, + 150, 3, 207, 18, 195, 36, 251, 73, 195, 150, 3, 195, 36, 196, 155, 4, + 199, 215, 195, 150, 3, 195, 36, 251, 74, 4, 199, 215, 195, 150, 3, 251, + 72, 251, 88, 195, 150, 3, 251, 72, 249, 120, 195, 150, 3, 251, 72, 195, + 178, 195, 150, 3, 251, 72, 195, 179, 4, 199, 215, 195, 150, 3, 198, 126, + 195, 150, 3, 229, 180, 179, 251, 71, 195, 150, 3, 179, 251, 71, 195, 150, + 3, 206, 70, 179, 251, 71, 195, 150, 3, 251, 72, 196, 162, 215, 136, 195, + 150, 3, 251, 10, 195, 150, 3, 206, 122, 251, 10, 195, 150, 163, 247, 122, + 58, 195, 150, 3, 222, 237, 195, 150, 3, 196, 75, 195, 150, 3, 250, 177, + 195, 150, 163, 206, 189, 58, 195, 150, 163, 55, 206, 189, 58, 195, 150, + 3, 55, 251, 72, 251, 88, 8, 1, 2, 6, 65, 8, 1, 2, 6, 252, 25, 8, 2, 1, + 153, 252, 25, 8, 1, 2, 6, 249, 82, 250, 120, 8, 1, 2, 6, 247, 193, 8, 1, + 2, 6, 238, 127, 8, 1, 2, 6, 233, 248, 8, 1, 2, 6, 71, 8, 2, 1, 153, 211, + 77, 71, 8, 2, 1, 153, 68, 8, 1, 2, 6, 223, 35, 8, 1, 2, 6, 222, 152, 8, + 1, 2, 6, 220, 143, 4, 106, 8, 1, 2, 6, 218, 168, 8, 1, 2, 6, 207, 18, + 215, 61, 8, 1, 2, 6, 74, 8, 1, 2, 6, 211, 77, 74, 8, 2, 1, 202, 206, 74, + 8, 2, 1, 202, 206, 211, 77, 74, 8, 2, 1, 202, 206, 187, 4, 106, 8, 2, 1, + 153, 211, 151, 8, 1, 2, 6, 211, 19, 8, 2, 1, 198, 54, 132, 74, 8, 2, 1, + 248, 77, 132, 74, 8, 1, 2, 6, 210, 236, 8, 1, 2, 6, 207, 18, 146, 8, 1, + 2, 6, 153, 146, 8, 1, 2, 6, 200, 43, 8, 1, 2, 6, 66, 8, 2, 1, 202, 206, + 66, 8, 2, 1, 202, 206, 237, 40, 66, 8, 2, 1, 202, 206, 153, 218, 168, 8, + 1, 2, 6, 196, 12, 8, 1, 2, 6, 193, 224, 8, 1, 2, 6, 191, 166, 8, 1, 2, 6, + 233, 178, 8, 1, 195, 20, 220, 8, 201, 216, 8, 1, 251, 230, 35, 1, 2, 6, + 231, 211, 35, 1, 2, 6, 220, 31, 35, 1, 2, 6, 209, 185, 35, 1, 2, 6, 207, + 3, 35, 1, 2, 6, 208, 176, 38, 1, 2, 6, 234, 140, 52, 1, 6, 65, 52, 1, 6, + 252, 25, 52, 1, 6, 250, 120, 52, 1, 6, 249, 82, 250, 120, 52, 1, 6, 238, + 127, 52, 1, 6, 71, 52, 1, 6, 207, 18, 71, 52, 1, 6, 232, 51, 52, 1, 6, + 230, 116, 52, 1, 6, 68, 52, 1, 6, 223, 35, 52, 1, 6, 222, 152, 52, 1, 6, + 172, 52, 1, 6, 218, 168, 52, 1, 6, 215, 61, 52, 1, 6, 207, 18, 215, 61, + 52, 1, 6, 74, 52, 1, 6, 211, 19, 52, 1, 6, 210, 236, 52, 1, 6, 146, 52, + 1, 6, 200, 43, 52, 1, 6, 66, 52, 1, 6, 193, 224, 52, 1, 2, 65, 52, 1, 2, + 153, 65, 52, 1, 2, 251, 160, 52, 1, 2, 153, 252, 25, 52, 1, 2, 250, 120, + 52, 1, 2, 238, 127, 52, 1, 2, 71, 52, 1, 2, 205, 86, 52, 1, 2, 211, 77, + 71, 52, 1, 2, 153, 211, 77, 71, 52, 1, 2, 232, 51, 52, 1, 2, 153, 68, 52, + 1, 2, 222, 152, 52, 1, 2, 218, 168, 52, 1, 2, 234, 88, 52, 1, 2, 74, 52, + 1, 2, 211, 77, 74, 52, 1, 2, 198, 54, 132, 74, 52, 1, 2, 248, 77, 132, + 74, 52, 1, 2, 210, 236, 52, 1, 2, 200, 43, 52, 1, 2, 66, 52, 1, 2, 202, + 206, 66, 52, 1, 2, 153, 218, 168, 52, 1, 2, 196, 12, 52, 1, 2, 251, 230, + 52, 1, 2, 248, 212, 52, 1, 2, 35, 231, 211, 52, 1, 2, 237, 106, 52, 1, 2, + 35, 209, 211, 52, 1, 2, 243, 95, 8, 200, 230, 2, 1, 68, 8, 200, 230, 2, + 1, 146, 8, 200, 230, 2, 1, 66, 8, 200, 230, 2, 1, 196, 12, 35, 200, 230, + 2, 1, 248, 212, 35, 200, 230, 2, 1, 231, 211, 35, 200, 230, 2, 1, 207, 3, + 35, 200, 230, 2, 1, 209, 211, 35, 200, 230, 2, 1, 243, 95, 8, 2, 1, 196, + 152, 8, 2, 1, 78, 4, 82, 198, 152, 8, 2, 1, 238, 128, 4, 82, 198, 152, 8, + 2, 1, 233, 176, 4, 82, 198, 152, 8, 2, 1, 218, 169, 4, 82, 198, 152, 8, + 2, 1, 215, 62, 4, 82, 198, 152, 8, 2, 1, 210, 237, 4, 82, 198, 152, 8, 2, + 1, 207, 222, 4, 82, 198, 152, 8, 2, 1, 207, 222, 4, 232, 234, 23, 82, + 198, 152, 8, 2, 1, 206, 9, 4, 82, 198, 152, 8, 2, 1, 200, 44, 4, 82, 198, + 152, 8, 2, 1, 191, 167, 4, 82, 198, 152, 8, 2, 1, 153, 232, 51, 52, 1, + 38, 234, 103, 8, 2, 1, 223, 115, 232, 51, 8, 2, 1, 199, 52, 4, 201, 32, + 8, 2, 6, 1, 228, 74, 4, 106, 8, 2, 1, 223, 84, 4, 106, 8, 2, 1, 210, 237, + 4, 106, 8, 2, 6, 1, 126, 4, 106, 8, 2, 1, 196, 71, 4, 106, 8, 2, 1, 78, + 4, 210, 192, 102, 8, 2, 1, 238, 128, 4, 210, 192, 102, 8, 2, 1, 233, 176, + 4, 210, 192, 102, 8, 2, 1, 232, 52, 4, 210, 192, 102, 8, 2, 1, 222, 153, + 4, 210, 192, 102, 8, 2, 1, 220, 143, 4, 210, 192, 102, 8, 2, 1, 218, 169, + 4, 210, 192, 102, 8, 2, 1, 215, 62, 4, 210, 192, 102, 8, 2, 1, 210, 237, + 4, 210, 192, 102, 8, 2, 1, 207, 222, 4, 210, 192, 102, 8, 2, 1, 206, 9, + 4, 210, 192, 102, 8, 2, 1, 234, 13, 4, 210, 192, 102, 8, 2, 1, 196, 13, + 4, 210, 192, 102, 8, 2, 1, 192, 236, 4, 210, 192, 102, 8, 2, 1, 191, 167, + 4, 210, 192, 102, 8, 2, 1, 42, 4, 207, 24, 102, 8, 2, 1, 251, 161, 4, + 207, 24, 102, 8, 2, 1, 238, 128, 4, 228, 251, 23, 199, 215, 8, 2, 1, 235, + 15, 4, 207, 24, 102, 8, 2, 1, 211, 77, 235, 15, 4, 207, 24, 102, 8, 2, 1, + 207, 18, 211, 77, 235, 15, 4, 207, 24, 102, 8, 2, 1, 205, 87, 4, 207, 24, + 102, 8, 2, 1, 228, 74, 4, 207, 24, 102, 8, 2, 1, 211, 77, 187, 4, 207, + 24, 102, 8, 2, 1, 234, 13, 4, 207, 24, 102, 8, 2, 1, 126, 4, 207, 24, + 102, 8, 2, 1, 233, 179, 4, 207, 24, 102, 52, 1, 2, 153, 251, 160, 52, 1, + 2, 247, 193, 52, 1, 2, 247, 194, 4, 238, 175, 52, 1, 2, 233, 248, 52, 1, + 2, 207, 18, 211, 77, 71, 52, 1, 2, 233, 175, 52, 1, 2, 236, 139, 223, 36, + 4, 106, 52, 1, 2, 27, 232, 51, 52, 1, 2, 153, 230, 116, 52, 1, 2, 228, + 74, 4, 106, 52, 1, 2, 223, 83, 52, 1, 2, 6, 68, 52, 1, 2, 6, 228, 74, 4, + 106, 52, 1, 2, 223, 36, 4, 238, 212, 52, 1, 2, 220, 143, 4, 207, 24, 102, + 52, 1, 2, 220, 143, 4, 210, 192, 102, 52, 1, 2, 6, 172, 52, 1, 2, 218, + 169, 4, 102, 52, 1, 2, 153, 218, 169, 4, 179, 219, 212, 52, 1, 2, 215, + 62, 4, 45, 102, 52, 1, 2, 215, 62, 4, 207, 24, 102, 52, 1, 2, 6, 215, 61, + 52, 1, 2, 249, 82, 74, 52, 1, 2, 209, 211, 52, 1, 2, 206, 9, 4, 102, 52, + 1, 2, 234, 12, 52, 1, 2, 200, 44, 4, 210, 192, 102, 52, 1, 2, 126, 164, + 52, 1, 2, 196, 70, 52, 1, 2, 6, 66, 52, 1, 2, 196, 13, 4, 102, 52, 1, 2, + 153, 196, 12, 52, 1, 2, 191, 166, 52, 1, 2, 191, 167, 4, 207, 24, 102, + 52, 1, 2, 191, 167, 4, 238, 175, 52, 1, 2, 233, 178, 52, 1, 2, 199, 15, + 33, 235, 138, 230, 211, 252, 60, 33, 235, 138, 252, 47, 252, 60, 33, 202, + 59, 60, 33, 200, 164, 77, 33, 217, 145, 33, 230, 208, 33, 217, 143, 33, + 252, 44, 33, 230, 209, 33, 252, 45, 33, 8, 2, 1, 207, 222, 60, 33, 248, + 35, 33, 217, 144, 33, 55, 243, 2, 58, 33, 211, 139, 58, 33, 191, 21, 60, + 33, 223, 69, 60, 33, 196, 63, 58, 33, 196, 46, 58, 33, 8, 2, 1, 232, 203, + 211, 77, 42, 58, 33, 8, 2, 1, 252, 25, 33, 8, 2, 1, 251, 68, 33, 8, 2, 1, + 250, 146, 33, 8, 2, 1, 247, 194, 247, 35, 33, 8, 2, 1, 223, 115, 238, + 127, 33, 8, 2, 1, 233, 248, 33, 8, 2, 1, 232, 51, 33, 8, 1, 2, 6, 232, + 51, 33, 8, 2, 1, 222, 152, 33, 8, 2, 1, 172, 33, 8, 1, 2, 6, 172, 33, 8, + 1, 2, 6, 218, 168, 33, 8, 2, 1, 215, 61, 33, 8, 1, 2, 6, 215, 61, 33, 8, + 1, 2, 6, 146, 33, 8, 2, 1, 207, 222, 206, 116, 33, 8, 2, 1, 206, 8, 33, + 8, 2, 1, 179, 206, 8, 33, 8, 2, 1, 191, 166, 33, 8, 2, 1, 251, 160, 33, + 8, 2, 1, 250, 120, 33, 8, 2, 1, 248, 212, 33, 8, 2, 1, 205, 86, 33, 8, 2, + 1, 233, 175, 33, 8, 2, 1, 220, 143, 4, 55, 82, 198, 152, 33, 8, 2, 1, + 187, 4, 156, 247, 23, 106, 33, 8, 2, 1, 210, 236, 33, 8, 2, 1, 234, 12, + 33, 8, 2, 1, 126, 4, 156, 247, 23, 106, 33, 8, 2, 1, 193, 224, 33, 8, 2, + 1, 42, 4, 237, 42, 33, 8, 2, 1, 187, 4, 237, 42, 33, 8, 2, 1, 126, 4, + 237, 42, 33, 133, 199, 229, 58, 33, 222, 36, 93, 183, 33, 222, 36, 93, + 219, 224, 33, 75, 93, 219, 224, 33, 193, 78, 223, 93, 248, 29, 60, 33, + 75, 248, 233, 219, 224, 33, 237, 115, 77, 33, 55, 223, 93, 248, 37, 60, + 33, 251, 165, 234, 45, 119, 60, 33, 45, 250, 236, 58, 33, 50, 250, 236, + 23, 144, 250, 236, 60, 8, 6, 1, 42, 4, 206, 189, 60, 8, 2, 1, 42, 4, 206, + 189, 60, 8, 6, 1, 78, 4, 75, 58, 8, 2, 1, 78, 4, 75, 58, 8, 6, 1, 78, 4, + 75, 60, 8, 2, 1, 78, 4, 75, 60, 8, 6, 1, 78, 4, 219, 113, 60, 8, 2, 1, + 78, 4, 219, 113, 60, 8, 6, 1, 247, 194, 4, 247, 36, 23, 252, 46, 8, 2, 1, + 247, 194, 4, 247, 36, 23, 252, 46, 8, 6, 1, 238, 128, 4, 75, 58, 8, 2, 1, + 238, 128, 4, 75, 58, 8, 6, 1, 238, 128, 4, 75, 60, 8, 2, 1, 238, 128, 4, + 75, 60, 8, 6, 1, 238, 128, 4, 219, 113, 60, 8, 2, 1, 238, 128, 4, 219, + 113, 60, 8, 6, 1, 238, 128, 4, 247, 35, 8, 2, 1, 238, 128, 4, 247, 35, 8, + 6, 1, 238, 128, 4, 243, 2, 60, 8, 2, 1, 238, 128, 4, 243, 2, 60, 8, 6, 1, + 235, 15, 4, 217, 147, 23, 230, 210, 8, 2, 1, 235, 15, 4, 217, 147, 23, + 230, 210, 8, 6, 1, 235, 15, 4, 217, 147, 23, 252, 46, 8, 2, 1, 235, 15, + 4, 217, 147, 23, 252, 46, 8, 6, 1, 235, 15, 4, 243, 2, 60, 8, 2, 1, 235, + 15, 4, 243, 2, 60, 8, 6, 1, 235, 15, 4, 198, 153, 60, 8, 2, 1, 235, 15, + 4, 198, 153, 60, 8, 6, 1, 235, 15, 4, 247, 36, 23, 248, 36, 8, 2, 1, 235, + 15, 4, 247, 36, 23, 248, 36, 8, 6, 1, 233, 176, 4, 75, 58, 8, 2, 1, 233, + 176, 4, 75, 58, 8, 6, 1, 232, 52, 4, 217, 146, 8, 2, 1, 232, 52, 4, 217, + 146, 8, 6, 1, 230, 117, 4, 75, 58, 8, 2, 1, 230, 117, 4, 75, 58, 8, 6, 1, + 230, 117, 4, 75, 60, 8, 2, 1, 230, 117, 4, 75, 60, 8, 6, 1, 230, 117, 4, + 237, 42, 8, 2, 1, 230, 117, 4, 237, 42, 8, 6, 1, 230, 117, 4, 247, 35, 8, + 2, 1, 230, 117, 4, 247, 35, 8, 6, 1, 230, 117, 4, 248, 37, 60, 8, 2, 1, + 230, 117, 4, 248, 37, 60, 8, 6, 1, 228, 74, 4, 198, 153, 60, 8, 2, 1, + 228, 74, 4, 198, 153, 60, 8, 6, 1, 228, 74, 4, 237, 43, 23, 252, 46, 8, + 2, 1, 228, 74, 4, 237, 43, 23, 252, 46, 8, 6, 1, 222, 153, 4, 252, 46, 8, + 2, 1, 222, 153, 4, 252, 46, 8, 6, 1, 222, 153, 4, 75, 60, 8, 2, 1, 222, + 153, 4, 75, 60, 8, 6, 1, 222, 153, 4, 219, 113, 60, 8, 2, 1, 222, 153, 4, + 219, 113, 60, 8, 6, 1, 220, 143, 4, 75, 60, 8, 2, 1, 220, 143, 4, 75, 60, + 8, 6, 1, 220, 143, 4, 75, 248, 233, 23, 217, 146, 8, 2, 1, 220, 143, 4, + 75, 248, 233, 23, 217, 146, 8, 6, 1, 220, 143, 4, 219, 113, 60, 8, 2, 1, + 220, 143, 4, 219, 113, 60, 8, 6, 1, 220, 143, 4, 243, 2, 60, 8, 2, 1, + 220, 143, 4, 243, 2, 60, 8, 6, 1, 218, 169, 4, 252, 46, 8, 2, 1, 218, + 169, 4, 252, 46, 8, 6, 1, 218, 169, 4, 75, 58, 8, 2, 1, 218, 169, 4, 75, + 58, 8, 6, 1, 218, 169, 4, 75, 60, 8, 2, 1, 218, 169, 4, 75, 60, 8, 6, 1, + 215, 62, 4, 75, 58, 8, 2, 1, 215, 62, 4, 75, 58, 8, 6, 1, 215, 62, 4, 75, + 60, 8, 2, 1, 215, 62, 4, 75, 60, 8, 6, 1, 215, 62, 4, 219, 113, 60, 8, 2, + 1, 215, 62, 4, 219, 113, 60, 8, 6, 1, 215, 62, 4, 243, 2, 60, 8, 2, 1, + 215, 62, 4, 243, 2, 60, 8, 6, 1, 187, 4, 198, 153, 23, 252, 46, 8, 2, 1, + 187, 4, 198, 153, 23, 252, 46, 8, 6, 1, 187, 4, 198, 153, 23, 237, 42, 8, + 2, 1, 187, 4, 198, 153, 23, 237, 42, 8, 6, 1, 187, 4, 217, 147, 23, 230, + 210, 8, 2, 1, 187, 4, 217, 147, 23, 230, 210, 8, 6, 1, 187, 4, 217, 147, + 23, 252, 46, 8, 2, 1, 187, 4, 217, 147, 23, 252, 46, 8, 6, 1, 210, 237, + 4, 252, 46, 8, 2, 1, 210, 237, 4, 252, 46, 8, 6, 1, 210, 237, 4, 75, 58, + 8, 2, 1, 210, 237, 4, 75, 58, 8, 6, 1, 207, 222, 4, 75, 58, 8, 2, 1, 207, + 222, 4, 75, 58, 8, 6, 1, 207, 222, 4, 75, 60, 8, 2, 1, 207, 222, 4, 75, + 60, 8, 6, 1, 207, 222, 4, 75, 248, 233, 23, 217, 146, 8, 2, 1, 207, 222, + 4, 75, 248, 233, 23, 217, 146, 8, 6, 1, 207, 222, 4, 219, 113, 60, 8, 2, + 1, 207, 222, 4, 219, 113, 60, 8, 6, 1, 206, 9, 4, 75, 58, 8, 2, 1, 206, + 9, 4, 75, 58, 8, 6, 1, 206, 9, 4, 75, 60, 8, 2, 1, 206, 9, 4, 75, 60, 8, + 6, 1, 206, 9, 4, 252, 47, 23, 75, 58, 8, 2, 1, 206, 9, 4, 252, 47, 23, + 75, 58, 8, 6, 1, 206, 9, 4, 247, 93, 23, 75, 58, 8, 2, 1, 206, 9, 4, 247, + 93, 23, 75, 58, 8, 6, 1, 206, 9, 4, 75, 248, 233, 23, 75, 58, 8, 2, 1, + 206, 9, 4, 75, 248, 233, 23, 75, 58, 8, 6, 1, 200, 44, 4, 75, 58, 8, 2, + 1, 200, 44, 4, 75, 58, 8, 6, 1, 200, 44, 4, 75, 60, 8, 2, 1, 200, 44, 4, + 75, 60, 8, 6, 1, 200, 44, 4, 219, 113, 60, 8, 2, 1, 200, 44, 4, 219, 113, + 60, 8, 6, 1, 200, 44, 4, 243, 2, 60, 8, 2, 1, 200, 44, 4, 243, 2, 60, 8, + 6, 1, 126, 4, 237, 43, 60, 8, 2, 1, 126, 4, 237, 43, 60, 8, 6, 1, 126, 4, + 198, 153, 60, 8, 2, 1, 126, 4, 198, 153, 60, 8, 6, 1, 126, 4, 243, 2, 60, + 8, 2, 1, 126, 4, 243, 2, 60, 8, 6, 1, 126, 4, 198, 153, 23, 252, 46, 8, + 2, 1, 126, 4, 198, 153, 23, 252, 46, 8, 6, 1, 126, 4, 217, 147, 23, 237, + 42, 8, 2, 1, 126, 4, 217, 147, 23, 237, 42, 8, 6, 1, 196, 13, 4, 198, + 152, 8, 2, 1, 196, 13, 4, 198, 152, 8, 6, 1, 196, 13, 4, 75, 60, 8, 2, 1, + 196, 13, 4, 75, 60, 8, 6, 1, 193, 225, 4, 230, 210, 8, 2, 1, 193, 225, 4, + 230, 210, 8, 6, 1, 193, 225, 4, 252, 46, 8, 2, 1, 193, 225, 4, 252, 46, + 8, 6, 1, 193, 225, 4, 237, 42, 8, 2, 1, 193, 225, 4, 237, 42, 8, 6, 1, + 193, 225, 4, 75, 58, 8, 2, 1, 193, 225, 4, 75, 58, 8, 6, 1, 193, 225, 4, + 75, 60, 8, 2, 1, 193, 225, 4, 75, 60, 8, 6, 1, 192, 236, 4, 75, 58, 8, 2, + 1, 192, 236, 4, 75, 58, 8, 6, 1, 192, 236, 4, 237, 42, 8, 2, 1, 192, 236, + 4, 237, 42, 8, 6, 1, 192, 160, 4, 75, 58, 8, 2, 1, 192, 160, 4, 75, 58, + 8, 6, 1, 191, 167, 4, 243, 1, 8, 2, 1, 191, 167, 4, 243, 1, 8, 6, 1, 191, + 167, 4, 75, 60, 8, 2, 1, 191, 167, 4, 75, 60, 8, 6, 1, 191, 167, 4, 219, + 113, 60, 8, 2, 1, 191, 167, 4, 219, 113, 60, 8, 2, 1, 230, 117, 4, 219, + 113, 60, 8, 2, 1, 200, 44, 4, 237, 42, 8, 2, 1, 193, 225, 4, 206, 189, + 58, 8, 2, 1, 192, 160, 4, 206, 189, 58, 8, 2, 1, 42, 4, 50, 132, 206, + 188, 8, 2, 1, 179, 206, 9, 4, 75, 58, 8, 2, 1, 179, 206, 9, 4, 237, 39, + 106, 8, 2, 1, 179, 206, 9, 4, 137, 106, 8, 6, 1, 203, 127, 206, 8, 8, 2, + 1, 237, 106, 8, 6, 1, 42, 4, 75, 60, 8, 2, 1, 42, 4, 75, 60, 8, 6, 1, 42, + 4, 228, 251, 58, 8, 2, 1, 42, 4, 228, 251, 58, 8, 6, 1, 42, 4, 243, 2, + 23, 252, 46, 8, 2, 1, 42, 4, 243, 2, 23, 252, 46, 8, 6, 1, 42, 4, 243, 2, + 23, 230, 210, 8, 2, 1, 42, 4, 243, 2, 23, 230, 210, 8, 6, 1, 42, 4, 243, + 2, 23, 228, 251, 58, 8, 2, 1, 42, 4, 243, 2, 23, 228, 251, 58, 8, 6, 1, + 42, 4, 243, 2, 23, 198, 152, 8, 2, 1, 42, 4, 243, 2, 23, 198, 152, 8, 6, + 1, 42, 4, 243, 2, 23, 75, 60, 8, 2, 1, 42, 4, 243, 2, 23, 75, 60, 8, 6, + 1, 42, 4, 248, 37, 23, 252, 46, 8, 2, 1, 42, 4, 248, 37, 23, 252, 46, 8, + 6, 1, 42, 4, 248, 37, 23, 230, 210, 8, 2, 1, 42, 4, 248, 37, 23, 230, + 210, 8, 6, 1, 42, 4, 248, 37, 23, 228, 251, 58, 8, 2, 1, 42, 4, 248, 37, + 23, 228, 251, 58, 8, 6, 1, 42, 4, 248, 37, 23, 198, 152, 8, 2, 1, 42, 4, + 248, 37, 23, 198, 152, 8, 6, 1, 42, 4, 248, 37, 23, 75, 60, 8, 2, 1, 42, + 4, 248, 37, 23, 75, 60, 8, 6, 1, 235, 15, 4, 75, 60, 8, 2, 1, 235, 15, 4, + 75, 60, 8, 6, 1, 235, 15, 4, 228, 251, 58, 8, 2, 1, 235, 15, 4, 228, 251, + 58, 8, 6, 1, 235, 15, 4, 198, 152, 8, 2, 1, 235, 15, 4, 198, 152, 8, 6, + 1, 235, 15, 4, 243, 2, 23, 252, 46, 8, 2, 1, 235, 15, 4, 243, 2, 23, 252, + 46, 8, 6, 1, 235, 15, 4, 243, 2, 23, 230, 210, 8, 2, 1, 235, 15, 4, 243, + 2, 23, 230, 210, 8, 6, 1, 235, 15, 4, 243, 2, 23, 228, 251, 58, 8, 2, 1, + 235, 15, 4, 243, 2, 23, 228, 251, 58, 8, 6, 1, 235, 15, 4, 243, 2, 23, + 198, 152, 8, 2, 1, 235, 15, 4, 243, 2, 23, 198, 152, 8, 6, 1, 235, 15, 4, + 243, 2, 23, 75, 60, 8, 2, 1, 235, 15, 4, 243, 2, 23, 75, 60, 8, 6, 1, + 228, 74, 4, 228, 251, 58, 8, 2, 1, 228, 74, 4, 228, 251, 58, 8, 6, 1, + 228, 74, 4, 75, 60, 8, 2, 1, 228, 74, 4, 75, 60, 8, 6, 1, 187, 4, 75, 60, + 8, 2, 1, 187, 4, 75, 60, 8, 6, 1, 187, 4, 228, 251, 58, 8, 2, 1, 187, 4, + 228, 251, 58, 8, 6, 1, 187, 4, 243, 2, 23, 252, 46, 8, 2, 1, 187, 4, 243, + 2, 23, 252, 46, 8, 6, 1, 187, 4, 243, 2, 23, 230, 210, 8, 2, 1, 187, 4, + 243, 2, 23, 230, 210, 8, 6, 1, 187, 4, 243, 2, 23, 228, 251, 58, 8, 2, 1, + 187, 4, 243, 2, 23, 228, 251, 58, 8, 6, 1, 187, 4, 243, 2, 23, 198, 152, + 8, 2, 1, 187, 4, 243, 2, 23, 198, 152, 8, 6, 1, 187, 4, 243, 2, 23, 75, + 60, 8, 2, 1, 187, 4, 243, 2, 23, 75, 60, 8, 6, 1, 187, 4, 228, 188, 23, + 252, 46, 8, 2, 1, 187, 4, 228, 188, 23, 252, 46, 8, 6, 1, 187, 4, 228, + 188, 23, 230, 210, 8, 2, 1, 187, 4, 228, 188, 23, 230, 210, 8, 6, 1, 187, + 4, 228, 188, 23, 228, 251, 58, 8, 2, 1, 187, 4, 228, 188, 23, 228, 251, + 58, 8, 6, 1, 187, 4, 228, 188, 23, 198, 152, 8, 2, 1, 187, 4, 228, 188, + 23, 198, 152, 8, 6, 1, 187, 4, 228, 188, 23, 75, 60, 8, 2, 1, 187, 4, + 228, 188, 23, 75, 60, 8, 6, 1, 126, 4, 75, 60, 8, 2, 1, 126, 4, 75, 60, + 8, 6, 1, 126, 4, 228, 251, 58, 8, 2, 1, 126, 4, 228, 251, 58, 8, 6, 1, + 126, 4, 228, 188, 23, 252, 46, 8, 2, 1, 126, 4, 228, 188, 23, 252, 46, 8, + 6, 1, 126, 4, 228, 188, 23, 230, 210, 8, 2, 1, 126, 4, 228, 188, 23, 230, + 210, 8, 6, 1, 126, 4, 228, 188, 23, 228, 251, 58, 8, 2, 1, 126, 4, 228, + 188, 23, 228, 251, 58, 8, 6, 1, 126, 4, 228, 188, 23, 198, 152, 8, 2, 1, + 126, 4, 228, 188, 23, 198, 152, 8, 6, 1, 126, 4, 228, 188, 23, 75, 60, 8, + 2, 1, 126, 4, 228, 188, 23, 75, 60, 8, 6, 1, 192, 160, 4, 230, 210, 8, 2, + 1, 192, 160, 4, 230, 210, 8, 6, 1, 192, 160, 4, 75, 60, 8, 2, 1, 192, + 160, 4, 75, 60, 8, 6, 1, 192, 160, 4, 228, 251, 58, 8, 2, 1, 192, 160, 4, + 228, 251, 58, 8, 6, 1, 192, 160, 4, 198, 152, 8, 2, 1, 192, 160, 4, 198, + 152, 8, 6, 1, 216, 83, 219, 74, 8, 2, 1, 216, 83, 219, 74, 8, 6, 1, 216, + 83, 196, 12, 8, 2, 1, 216, 83, 196, 12, 8, 6, 1, 192, 160, 4, 219, 4, 8, + 2, 1, 192, 160, 4, 219, 4, 35, 2, 1, 251, 161, 4, 208, 169, 35, 2, 1, + 251, 161, 4, 237, 212, 35, 2, 1, 251, 161, 4, 208, 170, 23, 195, 169, 35, + 2, 1, 251, 161, 4, 237, 213, 23, 195, 169, 35, 2, 1, 251, 161, 4, 208, + 170, 23, 210, 243, 35, 2, 1, 251, 161, 4, 237, 213, 23, 210, 243, 35, 2, + 1, 251, 161, 4, 208, 170, 23, 210, 4, 35, 2, 1, 251, 161, 4, 237, 213, + 23, 210, 4, 35, 6, 1, 251, 161, 4, 208, 169, 35, 6, 1, 251, 161, 4, 237, + 212, 35, 6, 1, 251, 161, 4, 208, 170, 23, 195, 169, 35, 6, 1, 251, 161, + 4, 237, 213, 23, 195, 169, 35, 6, 1, 251, 161, 4, 208, 170, 23, 210, 243, + 35, 6, 1, 251, 161, 4, 237, 213, 23, 210, 243, 35, 6, 1, 251, 161, 4, + 208, 170, 23, 210, 4, 35, 6, 1, 251, 161, 4, 237, 213, 23, 210, 4, 35, 2, + 1, 234, 48, 4, 208, 169, 35, 2, 1, 234, 48, 4, 237, 212, 35, 2, 1, 234, + 48, 4, 208, 170, 23, 195, 169, 35, 2, 1, 234, 48, 4, 237, 213, 23, 195, + 169, 35, 2, 1, 234, 48, 4, 208, 170, 23, 210, 243, 35, 2, 1, 234, 48, 4, + 237, 213, 23, 210, 243, 35, 6, 1, 234, 48, 4, 208, 169, 35, 6, 1, 234, + 48, 4, 237, 212, 35, 6, 1, 234, 48, 4, 208, 170, 23, 195, 169, 35, 6, 1, + 234, 48, 4, 237, 213, 23, 195, 169, 35, 6, 1, 234, 48, 4, 208, 170, 23, + 210, 243, 35, 6, 1, 234, 48, 4, 237, 213, 23, 210, 243, 35, 2, 1, 233, + 254, 4, 208, 169, 35, 2, 1, 233, 254, 4, 237, 212, 35, 2, 1, 233, 254, 4, + 208, 170, 23, 195, 169, 35, 2, 1, 233, 254, 4, 237, 213, 23, 195, 169, + 35, 2, 1, 233, 254, 4, 208, 170, 23, 210, 243, 35, 2, 1, 233, 254, 4, + 237, 213, 23, 210, 243, 35, 2, 1, 233, 254, 4, 208, 170, 23, 210, 4, 35, + 2, 1, 233, 254, 4, 237, 213, 23, 210, 4, 35, 6, 1, 233, 254, 4, 208, 169, + 35, 6, 1, 233, 254, 4, 237, 212, 35, 6, 1, 233, 254, 4, 208, 170, 23, + 195, 169, 35, 6, 1, 233, 254, 4, 237, 213, 23, 195, 169, 35, 6, 1, 233, + 254, 4, 208, 170, 23, 210, 243, 35, 6, 1, 233, 254, 4, 237, 213, 23, 210, + 243, 35, 6, 1, 233, 254, 4, 208, 170, 23, 210, 4, 35, 6, 1, 233, 254, 4, + 237, 213, 23, 210, 4, 35, 2, 1, 223, 84, 4, 208, 169, 35, 2, 1, 223, 84, + 4, 237, 212, 35, 2, 1, 223, 84, 4, 208, 170, 23, 195, 169, 35, 2, 1, 223, + 84, 4, 237, 213, 23, 195, 169, 35, 2, 1, 223, 84, 4, 208, 170, 23, 210, + 243, 35, 2, 1, 223, 84, 4, 237, 213, 23, 210, 243, 35, 2, 1, 223, 84, 4, + 208, 170, 23, 210, 4, 35, 2, 1, 223, 84, 4, 237, 213, 23, 210, 4, 35, 6, + 1, 223, 84, 4, 208, 169, 35, 6, 1, 223, 84, 4, 237, 212, 35, 6, 1, 223, + 84, 4, 208, 170, 23, 195, 169, 35, 6, 1, 223, 84, 4, 237, 213, 23, 195, + 169, 35, 6, 1, 223, 84, 4, 208, 170, 23, 210, 243, 35, 6, 1, 223, 84, 4, + 237, 213, 23, 210, 243, 35, 6, 1, 223, 84, 4, 208, 170, 23, 210, 4, 35, + 6, 1, 223, 84, 4, 237, 213, 23, 210, 4, 35, 2, 1, 211, 108, 4, 208, 169, + 35, 2, 1, 211, 108, 4, 237, 212, 35, 2, 1, 211, 108, 4, 208, 170, 23, + 195, 169, 35, 2, 1, 211, 108, 4, 237, 213, 23, 195, 169, 35, 2, 1, 211, + 108, 4, 208, 170, 23, 210, 243, 35, 2, 1, 211, 108, 4, 237, 213, 23, 210, + 243, 35, 6, 1, 211, 108, 4, 208, 169, 35, 6, 1, 211, 108, 4, 237, 212, + 35, 6, 1, 211, 108, 4, 208, 170, 23, 195, 169, 35, 6, 1, 211, 108, 4, + 237, 213, 23, 195, 169, 35, 6, 1, 211, 108, 4, 208, 170, 23, 210, 243, + 35, 6, 1, 211, 108, 4, 237, 213, 23, 210, 243, 35, 2, 1, 196, 71, 4, 208, + 169, 35, 2, 1, 196, 71, 4, 237, 212, 35, 2, 1, 196, 71, 4, 208, 170, 23, + 195, 169, 35, 2, 1, 196, 71, 4, 237, 213, 23, 195, 169, 35, 2, 1, 196, + 71, 4, 208, 170, 23, 210, 243, 35, 2, 1, 196, 71, 4, 237, 213, 23, 210, + 243, 35, 2, 1, 196, 71, 4, 208, 170, 23, 210, 4, 35, 2, 1, 196, 71, 4, + 237, 213, 23, 210, 4, 35, 6, 1, 196, 71, 4, 237, 212, 35, 6, 1, 196, 71, + 4, 237, 213, 23, 195, 169, 35, 6, 1, 196, 71, 4, 237, 213, 23, 210, 243, + 35, 6, 1, 196, 71, 4, 237, 213, 23, 210, 4, 35, 2, 1, 211, 111, 4, 208, + 169, 35, 2, 1, 211, 111, 4, 237, 212, 35, 2, 1, 211, 111, 4, 208, 170, + 23, 195, 169, 35, 2, 1, 211, 111, 4, 237, 213, 23, 195, 169, 35, 2, 1, + 211, 111, 4, 208, 170, 23, 210, 243, 35, 2, 1, 211, 111, 4, 237, 213, 23, + 210, 243, 35, 2, 1, 211, 111, 4, 208, 170, 23, 210, 4, 35, 2, 1, 211, + 111, 4, 237, 213, 23, 210, 4, 35, 6, 1, 211, 111, 4, 208, 169, 35, 6, 1, + 211, 111, 4, 237, 212, 35, 6, 1, 211, 111, 4, 208, 170, 23, 195, 169, 35, + 6, 1, 211, 111, 4, 237, 213, 23, 195, 169, 35, 6, 1, 211, 111, 4, 208, + 170, 23, 210, 243, 35, 6, 1, 211, 111, 4, 237, 213, 23, 210, 243, 35, 6, + 1, 211, 111, 4, 208, 170, 23, 210, 4, 35, 6, 1, 211, 111, 4, 237, 213, + 23, 210, 4, 35, 2, 1, 251, 161, 4, 195, 169, 35, 2, 1, 251, 161, 4, 210, + 243, 35, 2, 1, 234, 48, 4, 195, 169, 35, 2, 1, 234, 48, 4, 210, 243, 35, + 2, 1, 233, 254, 4, 195, 169, 35, 2, 1, 233, 254, 4, 210, 243, 35, 2, 1, + 223, 84, 4, 195, 169, 35, 2, 1, 223, 84, 4, 210, 243, 35, 2, 1, 211, 108, + 4, 195, 169, 35, 2, 1, 211, 108, 4, 210, 243, 35, 2, 1, 196, 71, 4, 195, + 169, 35, 2, 1, 196, 71, 4, 210, 243, 35, 2, 1, 211, 111, 4, 195, 169, 35, + 2, 1, 211, 111, 4, 210, 243, 35, 2, 1, 251, 161, 4, 208, 170, 23, 191, + 233, 35, 2, 1, 251, 161, 4, 237, 213, 23, 191, 233, 35, 2, 1, 251, 161, + 4, 208, 170, 23, 195, 170, 23, 191, 233, 35, 2, 1, 251, 161, 4, 237, 213, + 23, 195, 170, 23, 191, 233, 35, 2, 1, 251, 161, 4, 208, 170, 23, 210, + 244, 23, 191, 233, 35, 2, 1, 251, 161, 4, 237, 213, 23, 210, 244, 23, + 191, 233, 35, 2, 1, 251, 161, 4, 208, 170, 23, 210, 5, 23, 191, 233, 35, + 2, 1, 251, 161, 4, 237, 213, 23, 210, 5, 23, 191, 233, 35, 6, 1, 251, + 161, 4, 208, 170, 23, 208, 184, 35, 6, 1, 251, 161, 4, 237, 213, 23, 208, + 184, 35, 6, 1, 251, 161, 4, 208, 170, 23, 195, 170, 23, 208, 184, 35, 6, + 1, 251, 161, 4, 237, 213, 23, 195, 170, 23, 208, 184, 35, 6, 1, 251, 161, + 4, 208, 170, 23, 210, 244, 23, 208, 184, 35, 6, 1, 251, 161, 4, 237, 213, + 23, 210, 244, 23, 208, 184, 35, 6, 1, 251, 161, 4, 208, 170, 23, 210, 5, + 23, 208, 184, 35, 6, 1, 251, 161, 4, 237, 213, 23, 210, 5, 23, 208, 184, + 35, 2, 1, 233, 254, 4, 208, 170, 23, 191, 233, 35, 2, 1, 233, 254, 4, + 237, 213, 23, 191, 233, 35, 2, 1, 233, 254, 4, 208, 170, 23, 195, 170, + 23, 191, 233, 35, 2, 1, 233, 254, 4, 237, 213, 23, 195, 170, 23, 191, + 233, 35, 2, 1, 233, 254, 4, 208, 170, 23, 210, 244, 23, 191, 233, 35, 2, + 1, 233, 254, 4, 237, 213, 23, 210, 244, 23, 191, 233, 35, 2, 1, 233, 254, + 4, 208, 170, 23, 210, 5, 23, 191, 233, 35, 2, 1, 233, 254, 4, 237, 213, + 23, 210, 5, 23, 191, 233, 35, 6, 1, 233, 254, 4, 208, 170, 23, 208, 184, + 35, 6, 1, 233, 254, 4, 237, 213, 23, 208, 184, 35, 6, 1, 233, 254, 4, + 208, 170, 23, 195, 170, 23, 208, 184, 35, 6, 1, 233, 254, 4, 237, 213, + 23, 195, 170, 23, 208, 184, 35, 6, 1, 233, 254, 4, 208, 170, 23, 210, + 244, 23, 208, 184, 35, 6, 1, 233, 254, 4, 237, 213, 23, 210, 244, 23, + 208, 184, 35, 6, 1, 233, 254, 4, 208, 170, 23, 210, 5, 23, 208, 184, 35, + 6, 1, 233, 254, 4, 237, 213, 23, 210, 5, 23, 208, 184, 35, 2, 1, 211, + 111, 4, 208, 170, 23, 191, 233, 35, 2, 1, 211, 111, 4, 237, 213, 23, 191, + 233, 35, 2, 1, 211, 111, 4, 208, 170, 23, 195, 170, 23, 191, 233, 35, 2, + 1, 211, 111, 4, 237, 213, 23, 195, 170, 23, 191, 233, 35, 2, 1, 211, 111, + 4, 208, 170, 23, 210, 244, 23, 191, 233, 35, 2, 1, 211, 111, 4, 237, 213, + 23, 210, 244, 23, 191, 233, 35, 2, 1, 211, 111, 4, 208, 170, 23, 210, 5, + 23, 191, 233, 35, 2, 1, 211, 111, 4, 237, 213, 23, 210, 5, 23, 191, 233, + 35, 6, 1, 211, 111, 4, 208, 170, 23, 208, 184, 35, 6, 1, 211, 111, 4, + 237, 213, 23, 208, 184, 35, 6, 1, 211, 111, 4, 208, 170, 23, 195, 170, + 23, 208, 184, 35, 6, 1, 211, 111, 4, 237, 213, 23, 195, 170, 23, 208, + 184, 35, 6, 1, 211, 111, 4, 208, 170, 23, 210, 244, 23, 208, 184, 35, 6, + 1, 211, 111, 4, 237, 213, 23, 210, 244, 23, 208, 184, 35, 6, 1, 211, 111, + 4, 208, 170, 23, 210, 5, 23, 208, 184, 35, 6, 1, 211, 111, 4, 237, 213, + 23, 210, 5, 23, 208, 184, 35, 2, 1, 251, 161, 4, 194, 254, 35, 2, 1, 251, + 161, 4, 217, 146, 35, 2, 1, 251, 161, 4, 195, 170, 23, 191, 233, 35, 2, + 1, 251, 161, 4, 191, 233, 35, 2, 1, 251, 161, 4, 210, 244, 23, 191, 233, + 35, 2, 1, 251, 161, 4, 210, 4, 35, 2, 1, 251, 161, 4, 210, 5, 23, 191, + 233, 35, 6, 1, 251, 161, 4, 194, 254, 35, 6, 1, 251, 161, 4, 217, 146, + 35, 6, 1, 251, 161, 4, 195, 169, 35, 6, 1, 251, 161, 4, 210, 243, 35, 6, + 1, 251, 161, 4, 208, 184, 35, 221, 30, 35, 208, 184, 35, 208, 169, 35, + 210, 4, 35, 237, 36, 23, 210, 4, 35, 2, 1, 233, 254, 4, 195, 170, 23, + 191, 233, 35, 2, 1, 233, 254, 4, 191, 233, 35, 2, 1, 233, 254, 4, 210, + 244, 23, 191, 233, 35, 2, 1, 233, 254, 4, 210, 4, 35, 2, 1, 233, 254, 4, + 210, 5, 23, 191, 233, 35, 6, 1, 234, 48, 4, 195, 169, 35, 6, 1, 234, 48, + 4, 210, 243, 35, 6, 1, 233, 254, 4, 195, 169, 35, 6, 1, 233, 254, 4, 210, + 243, 35, 6, 1, 233, 254, 4, 208, 184, 35, 208, 170, 23, 195, 169, 35, + 208, 170, 23, 210, 243, 35, 208, 170, 23, 210, 4, 35, 2, 1, 223, 84, 4, + 194, 254, 35, 2, 1, 223, 84, 4, 217, 146, 35, 2, 1, 223, 84, 4, 237, 36, + 23, 195, 169, 35, 2, 1, 223, 84, 4, 237, 36, 23, 210, 243, 35, 2, 1, 223, + 84, 4, 210, 4, 35, 2, 1, 223, 84, 4, 237, 36, 23, 210, 4, 35, 6, 1, 223, + 84, 4, 194, 254, 35, 6, 1, 223, 84, 4, 217, 146, 35, 6, 1, 223, 84, 4, + 195, 169, 35, 6, 1, 223, 84, 4, 210, 243, 35, 237, 213, 23, 195, 169, 35, + 237, 213, 23, 210, 243, 35, 237, 213, 23, 210, 4, 35, 2, 1, 196, 71, 4, + 194, 254, 35, 2, 1, 196, 71, 4, 217, 146, 35, 2, 1, 196, 71, 4, 237, 36, + 23, 195, 169, 35, 2, 1, 196, 71, 4, 237, 36, 23, 210, 243, 35, 2, 1, 207, + 4, 4, 208, 169, 35, 2, 1, 207, 4, 4, 237, 212, 35, 2, 1, 196, 71, 4, 210, + 4, 35, 2, 1, 196, 71, 4, 237, 36, 23, 210, 4, 35, 6, 1, 196, 71, 4, 194, + 254, 35, 6, 1, 196, 71, 4, 217, 146, 35, 6, 1, 196, 71, 4, 195, 169, 35, + 6, 1, 196, 71, 4, 210, 243, 35, 6, 1, 207, 4, 4, 237, 212, 35, 237, 36, + 23, 195, 169, 35, 237, 36, 23, 210, 243, 35, 195, 169, 35, 2, 1, 211, + 111, 4, 195, 170, 23, 191, 233, 35, 2, 1, 211, 111, 4, 191, 233, 35, 2, + 1, 211, 111, 4, 210, 244, 23, 191, 233, 35, 2, 1, 211, 111, 4, 210, 4, + 35, 2, 1, 211, 111, 4, 210, 5, 23, 191, 233, 35, 6, 1, 211, 108, 4, 195, + 169, 35, 6, 1, 211, 108, 4, 210, 243, 35, 6, 1, 211, 111, 4, 195, 169, + 35, 6, 1, 211, 111, 4, 210, 243, 35, 6, 1, 211, 111, 4, 208, 184, 35, + 210, 243, 35, 237, 212, 234, 104, 208, 30, 234, 115, 208, 30, 234, 104, + 201, 247, 234, 115, 201, 247, 198, 219, 201, 247, 232, 126, 201, 247, + 202, 134, 201, 247, 233, 13, 201, 247, 208, 152, 201, 247, 199, 4, 201, + 247, 230, 79, 201, 247, 191, 78, 193, 75, 201, 247, 191, 78, 193, 75, + 213, 29, 191, 78, 193, 75, 222, 196, 219, 215, 77, 206, 199, 77, 228, 88, + 213, 30, 228, 88, 233, 13, 237, 215, 234, 104, 237, 215, 234, 115, 237, + 215, 228, 241, 164, 55, 81, 219, 112, 55, 130, 219, 112, 45, 202, 170, + 207, 252, 77, 50, 202, 170, 207, 252, 77, 202, 170, 218, 240, 207, 252, + 77, 202, 170, 229, 132, 207, 252, 77, 45, 55, 207, 252, 77, 50, 55, 207, + 252, 77, 55, 218, 240, 207, 252, 77, 55, 229, 132, 207, 252, 77, 238, 14, + 55, 238, 14, 247, 248, 197, 238, 247, 248, 91, 75, 219, 236, 105, 75, + 219, 236, 228, 241, 234, 120, 228, 86, 209, 61, 219, 113, 204, 10, 210, + 128, 204, 10, 219, 215, 234, 113, 206, 199, 234, 113, 209, 34, 236, 232, + 232, 144, 219, 215, 210, 252, 206, 199, 210, 252, 214, 215, 213, 37, 201, + 247, 210, 14, 216, 50, 56, 210, 14, 199, 96, 198, 230, 56, 208, 215, 55, + 208, 215, 197, 225, 208, 215, 207, 18, 208, 215, 207, 18, 55, 208, 215, + 207, 18, 197, 225, 208, 215, 247, 96, 202, 170, 219, 219, 251, 116, 207, + 252, 77, 202, 170, 206, 203, 251, 116, 207, 252, 77, 207, 83, 77, 55, + 233, 216, 77, 223, 102, 210, 254, 196, 100, 246, 240, 198, 178, 247, 97, + 223, 119, 209, 61, 250, 191, 228, 89, 247, 248, 232, 118, 202, 97, 45, + 51, 248, 54, 4, 208, 7, 50, 51, 248, 54, 4, 208, 7, 55, 208, 13, 77, 208, + 13, 233, 216, 77, 233, 216, 208, 13, 77, 198, 128, 3, 233, 255, 207, 18, + 209, 142, 56, 62, 118, 247, 248, 62, 96, 247, 248, 130, 250, 193, 207, + 18, 204, 25, 242, 220, 196, 77, 105, 250, 192, 251, 178, 195, 84, 242, + 72, 216, 35, 56, 200, 129, 237, 215, 223, 93, 196, 100, 232, 187, 208, + 152, 77, 115, 75, 208, 151, 208, 26, 208, 215, 232, 128, 75, 208, 151, + 232, 226, 75, 208, 151, 105, 75, 208, 151, 232, 128, 75, 77, 235, 138, + 238, 217, 197, 237, 81, 232, 128, 236, 138, 216, 213, 13, 201, 247, 193, + 23, 222, 196, 232, 77, 251, 44, 223, 91, 198, 144, 223, 91, 204, 10, 223, + 91, 209, 81, 219, 215, 223, 59, 206, 199, 223, 59, 232, 238, 201, 14, + 223, 59, 209, 34, 236, 232, 223, 59, 223, 132, 200, 75, 200, 147, 252, + 49, 200, 75, 200, 147, 223, 132, 9, 232, 146, 203, 133, 252, 49, 9, 232, + 146, 203, 133, 214, 208, 17, 203, 134, 213, 33, 17, 203, 134, 200, 182, + 191, 77, 200, 182, 8, 2, 1, 68, 200, 182, 134, 200, 182, 149, 200, 182, + 169, 200, 182, 175, 200, 182, 171, 200, 182, 178, 200, 182, 108, 56, 200, + 182, 216, 34, 200, 182, 234, 43, 56, 200, 182, 45, 210, 113, 200, 182, + 50, 210, 113, 200, 182, 8, 2, 1, 215, 61, 200, 230, 191, 77, 200, 230, + 107, 200, 230, 109, 200, 230, 138, 200, 230, 134, 200, 230, 149, 200, + 230, 169, 200, 230, 175, 200, 230, 171, 200, 230, 178, 200, 230, 108, 56, + 200, 230, 216, 34, 200, 230, 234, 43, 56, 200, 230, 45, 210, 113, 200, + 230, 50, 210, 113, 8, 200, 230, 2, 1, 65, 8, 200, 230, 2, 1, 71, 8, 200, + 230, 2, 1, 74, 8, 200, 230, 2, 1, 192, 235, 8, 200, 230, 2, 1, 205, 86, + 8, 200, 230, 2, 1, 230, 116, 8, 200, 230, 2, 1, 222, 152, 8, 200, 230, 2, + 1, 172, 8, 200, 230, 2, 1, 218, 168, 8, 200, 230, 2, 1, 215, 61, 8, 200, + 230, 2, 1, 210, 236, 8, 200, 230, 2, 1, 206, 8, 8, 200, 230, 2, 1, 200, + 43, 233, 233, 56, 242, 84, 56, 238, 200, 56, 232, 106, 232, 111, 56, 219, + 91, 56, 216, 51, 56, 214, 234, 56, 209, 245, 56, 206, 36, 56, 193, 31, + 56, 214, 80, 203, 99, 56, 236, 149, 56, 233, 234, 56, 221, 135, 56, 197, + 81, 56, 235, 116, 56, 231, 138, 210, 27, 56, 209, 242, 56, 230, 174, 56, + 250, 153, 56, 228, 166, 56, 247, 37, 56, 219, 81, 198, 33, 56, 201, 226, + 56, 199, 93, 56, 223, 147, 206, 36, 56, 197, 60, 219, 91, 56, 213, 19, + 87, 56, 217, 88, 56, 206, 59, 56, 220, 9, 56, 248, 147, 56, 202, 22, 56, + 33, 45, 230, 13, 58, 33, 50, 230, 13, 58, 33, 179, 81, 219, 113, 210, + 255, 33, 203, 40, 81, 219, 113, 210, 255, 33, 251, 85, 64, 58, 33, 242, + 221, 64, 58, 33, 45, 64, 58, 33, 50, 64, 58, 33, 206, 189, 210, 255, 33, + 242, 221, 206, 189, 210, 255, 33, 251, 85, 206, 189, 210, 255, 33, 115, + 185, 58, 33, 232, 128, 185, 58, 33, 234, 99, 243, 10, 33, 234, 99, 201, + 190, 33, 234, 99, 237, 32, 33, 234, 99, 243, 11, 249, 141, 33, 45, 50, + 64, 58, 33, 234, 99, 205, 76, 33, 234, 99, 221, 218, 33, 234, 99, 196, + 68, 209, 58, 197, 241, 33, 207, 19, 202, 24, 210, 255, 33, 55, 81, 201, + 28, 210, 255, 33, 251, 95, 113, 33, 197, 225, 196, 102, 33, 193, 78, 248, + 29, 58, 33, 118, 64, 210, 255, 33, 179, 55, 202, 24, 210, 255, 33, 96, + 230, 13, 4, 181, 235, 118, 33, 118, 230, 13, 4, 181, 235, 118, 33, 45, + 64, 60, 33, 50, 64, 60, 33, 250, 194, 58, 252, 55, 211, 146, 252, 38, + 119, 199, 34, 200, 240, 235, 129, 6, 247, 193, 237, 125, 247, 27, 247, + 22, 219, 113, 113, 247, 98, 211, 146, 247, 152, 196, 112, 233, 235, 239, + 38, 205, 72, 237, 125, 233, 91, 27, 2, 232, 51, 27, 6, 230, 116, 248, + 137, 6, 230, 116, 235, 129, 6, 230, 116, 209, 103, 239, 38, 209, 103, + 239, 39, 139, 105, 209, 185, 27, 6, 68, 248, 137, 6, 68, 27, 6, 172, 27, + 2, 172, 220, 143, 78, 249, 88, 113, 235, 129, 6, 215, 61, 212, 132, 56, + 202, 5, 207, 95, 239, 5, 27, 6, 210, 236, 235, 129, 6, 210, 236, 235, + 129, 6, 208, 104, 27, 6, 146, 248, 137, 6, 146, 235, 129, 6, 146, 208, + 223, 199, 208, 207, 31, 204, 1, 77, 199, 107, 56, 198, 22, 87, 56, 195, + 136, 235, 129, 6, 191, 166, 211, 18, 56, 211, 135, 56, 223, 93, 211, 135, + 56, 248, 137, 6, 191, 166, 153, 35, 2, 1, 223, 83, 222, 3, 56, 251, 110, + 56, 27, 6, 250, 120, 248, 137, 6, 247, 193, 234, 4, 113, 27, 2, 71, 27, + 6, 71, 27, 6, 233, 175, 153, 6, 233, 175, 27, 6, 218, 168, 27, 2, 74, + 131, 113, 248, 215, 113, 231, 39, 113, 237, 254, 113, 223, 137, 202, 3, + 206, 122, 6, 208, 104, 233, 94, 56, 235, 129, 2, 209, 185, 235, 129, 2, + 231, 211, 235, 129, 6, 231, 211, 235, 129, 6, 209, 185, 235, 129, 215, + 60, 200, 201, 153, 49, 6, 232, 51, 153, 49, 6, 172, 207, 18, 49, 6, 172, + 153, 49, 6, 192, 159, 235, 129, 43, 6, 238, 127, 235, 129, 43, 2, 238, + 127, 235, 129, 43, 2, 71, 235, 129, 43, 2, 68, 235, 129, 43, 2, 223, 35, + 208, 188, 219, 112, 153, 251, 137, 210, 14, 56, 251, 210, 153, 2, 233, + 175, 16, 40, 205, 151, 202, 3, 193, 246, 232, 118, 91, 203, 243, 193, + 246, 232, 118, 91, 213, 167, 193, 246, 232, 118, 91, 199, 86, 193, 246, + 232, 118, 91, 199, 0, 193, 246, 232, 118, 105, 198, 253, 193, 246, 232, + 118, 91, 233, 18, 193, 246, 232, 118, 105, 233, 17, 193, 246, 232, 118, + 115, 233, 17, 193, 246, 232, 118, 232, 128, 233, 17, 193, 246, 232, 118, + 91, 202, 124, 193, 246, 232, 118, 232, 226, 202, 122, 193, 246, 232, 118, + 91, 234, 159, 193, 246, 232, 118, 115, 234, 157, 193, 246, 232, 118, 232, + 226, 234, 157, 193, 246, 232, 118, 203, 247, 234, 157, 232, 118, 212, + 133, 107, 206, 136, 212, 134, 107, 206, 136, 212, 134, 109, 206, 136, + 212, 134, 138, 206, 136, 212, 134, 134, 206, 136, 212, 134, 149, 206, + 136, 212, 134, 169, 206, 136, 212, 134, 175, 206, 136, 212, 134, 171, + 206, 136, 212, 134, 178, 206, 136, 212, 134, 199, 95, 206, 136, 212, 134, + 234, 127, 206, 136, 212, 134, 197, 37, 206, 136, 212, 134, 233, 15, 206, + 136, 212, 134, 91, 228, 140, 206, 136, 212, 134, 232, 226, 228, 140, 206, + 136, 212, 134, 91, 189, 2, 206, 136, 212, 134, 107, 2, 206, 136, 212, + 134, 109, 2, 206, 136, 212, 134, 138, 2, 206, 136, 212, 134, 134, 2, 206, + 136, 212, 134, 149, 2, 206, 136, 212, 134, 169, 2, 206, 136, 212, 134, + 175, 2, 206, 136, 212, 134, 171, 2, 206, 136, 212, 134, 178, 2, 206, 136, + 212, 134, 199, 95, 2, 206, 136, 212, 134, 234, 127, 2, 206, 136, 212, + 134, 197, 37, 2, 206, 136, 212, 134, 233, 15, 2, 206, 136, 212, 134, 91, + 228, 140, 2, 206, 136, 212, 134, 232, 226, 228, 140, 2, 206, 136, 212, + 134, 91, 189, 206, 136, 212, 134, 91, 198, 230, 247, 194, 238, 127, 206, + 136, 212, 134, 232, 226, 189, 206, 136, 212, 134, 199, 96, 189, 206, 136, + 212, 134, 207, 18, 91, 228, 140, 8, 2, 1, 207, 18, 247, 193, 206, 136, + 212, 134, 202, 136, 220, 4, 20, 206, 136, 212, 134, 233, 16, 234, 210, + 20, 206, 136, 212, 134, 233, 16, 189, 206, 136, 212, 134, 91, 228, 141, + 189, 193, 246, 232, 118, 191, 78, 198, 253, 153, 17, 109, 153, 17, 138, + 118, 57, 196, 66, 57, 96, 57, 235, 119, 57, 45, 50, 57, 133, 144, 57, + 186, 193, 105, 57, 186, 234, 204, 57, 202, 2, 234, 204, 57, 202, 2, 193, + 105, 57, 118, 64, 4, 106, 96, 64, 4, 106, 118, 193, 139, 57, 96, 193, + 139, 57, 118, 105, 229, 233, 57, 196, 66, 105, 229, 233, 57, 96, 105, + 229, 233, 57, 235, 119, 105, 229, 233, 57, 118, 64, 4, 199, 215, 96, 64, + 4, 199, 215, 118, 64, 232, 98, 164, 196, 66, 64, 232, 98, 164, 96, 64, + 232, 98, 164, 235, 119, 64, 232, 98, 164, 133, 144, 64, 4, 249, 74, 118, + 64, 4, 102, 96, 64, 4, 102, 118, 64, 4, 219, 4, 96, 64, 4, 219, 4, 45, + 50, 193, 139, 57, 45, 50, 64, 4, 106, 235, 119, 191, 21, 57, 196, 66, 64, + 4, 198, 136, 219, 214, 196, 66, 64, 4, 198, 136, 206, 197, 235, 119, 64, + 4, 198, 136, 219, 214, 235, 119, 64, 4, 198, 136, 206, 197, 96, 64, 4, + 239, 2, 235, 118, 235, 119, 64, 4, 239, 2, 219, 214, 251, 85, 198, 54, + 204, 28, 57, 242, 221, 198, 54, 204, 28, 57, 186, 193, 105, 64, 119, 179, + 164, 118, 64, 119, 249, 88, 139, 96, 64, 119, 164, 251, 85, 211, 77, 243, + 11, 57, 242, 221, 211, 77, 243, 11, 57, 118, 230, 13, 4, 181, 196, 65, + 118, 230, 13, 4, 181, 235, 118, 196, 66, 230, 13, 4, 181, 206, 197, 196, + 66, 230, 13, 4, 181, 219, 214, 96, 230, 13, 4, 181, 196, 65, 96, 230, 13, + 4, 181, 235, 118, 235, 119, 230, 13, 4, 181, 206, 197, 235, 119, 230, 13, + 4, 181, 219, 214, 96, 64, 139, 118, 57, 196, 66, 64, 118, 79, 235, 119, + 57, 118, 64, 139, 96, 57, 118, 210, 196, 250, 231, 196, 66, 210, 196, + 250, 231, 96, 210, 196, 250, 231, 235, 119, 210, 196, 250, 231, 118, 230, + 13, 139, 96, 230, 12, 96, 230, 13, 139, 118, 230, 12, 118, 55, 64, 4, + 106, 45, 50, 55, 64, 4, 106, 96, 55, 64, 4, 106, 118, 55, 57, 196, 66, + 55, 57, 96, 55, 57, 235, 119, 55, 57, 45, 50, 55, 57, 133, 144, 55, 57, + 186, 193, 105, 55, 57, 186, 234, 204, 55, 57, 202, 2, 234, 204, 55, 57, + 202, 2, 193, 105, 55, 57, 118, 197, 225, 57, 96, 197, 225, 57, 118, 201, + 183, 57, 96, 201, 183, 57, 196, 66, 64, 4, 55, 106, 235, 119, 64, 4, 55, + 106, 118, 237, 214, 57, 196, 66, 237, 214, 57, 96, 237, 214, 57, 235, + 119, 237, 214, 57, 118, 64, 119, 164, 96, 64, 119, 164, 118, 63, 57, 196, + 66, 63, 57, 96, 63, 57, 235, 119, 63, 57, 196, 66, 63, 64, 232, 98, 164, + 196, 66, 63, 64, 211, 105, 210, 52, 196, 66, 63, 64, 211, 105, 210, 53, + 4, 228, 241, 164, 196, 66, 63, 64, 211, 105, 210, 53, 4, 81, 164, 196, + 66, 63, 55, 57, 196, 66, 63, 55, 64, 211, 105, 210, 52, 96, 63, 64, 232, + 98, 193, 167, 186, 193, 105, 64, 119, 239, 1, 202, 2, 234, 204, 64, 119, + 239, 1, 133, 144, 63, 57, 50, 64, 4, 2, 243, 10, 235, 119, 64, 118, 79, + 196, 66, 57, 115, 96, 250, 231, 118, 64, 4, 81, 106, 96, 64, 4, 81, 106, + 45, 50, 64, 4, 81, 106, 118, 64, 4, 55, 81, 106, 96, 64, 4, 55, 81, 106, + 45, 50, 64, 4, 55, 81, 106, 118, 211, 74, 57, 96, 211, 74, 57, 45, 50, + 211, 74, 57, 40, 251, 174, 242, 68, 210, 105, 237, 16, 199, 24, 233, 211, + 199, 24, 236, 164, 213, 12, 233, 212, 234, 105, 203, 252, 223, 151, 214, + 245, 234, 132, 211, 146, 213, 12, 251, 133, 234, 132, 211, 146, 2, 234, + 132, 211, 146, 239, 32, 250, 220, 216, 190, 236, 164, 213, 12, 239, 34, + 250, 220, 216, 190, 2, 239, 32, 250, 220, 216, 190, 234, 95, 79, 208, + 190, 215, 60, 208, 200, 215, 60, 239, 9, 215, 60, 200, 201, 216, 35, 56, + 216, 33, 56, 75, 209, 81, 236, 200, 202, 97, 203, 253, 216, 34, 250, 194, + 211, 66, 206, 189, 211, 66, 247, 249, 211, 66, 51, 206, 128, 238, 191, + 206, 128, 232, 121, 206, 128, 208, 186, 159, 223, 139, 50, 251, 115, 251, + 115, 216, 226, 251, 115, 201, 225, 251, 115, 236, 203, 236, 164, 213, 12, + 236, 207, 210, 119, 159, 213, 12, 210, 119, 159, 219, 29, 251, 125, 219, + 29, 211, 56, 223, 99, 196, 92, 223, 113, 55, 223, 113, 197, 225, 223, + 113, 239, 26, 223, 113, 200, 171, 223, 113, 195, 11, 223, 113, 242, 221, + 223, 113, 242, 221, 239, 26, 223, 113, 251, 85, 239, 26, 223, 113, 199, + 23, 249, 3, 207, 126, 208, 187, 75, 216, 34, 233, 219, 231, 144, 208, + 187, 229, 0, 198, 153, 211, 66, 207, 18, 198, 152, 223, 93, 219, 245, + 206, 8, 202, 172, 193, 138, 193, 10, 208, 200, 213, 12, 198, 152, 216, + 35, 198, 152, 250, 186, 234, 45, 159, 213, 12, 250, 186, 234, 45, 159, + 251, 40, 234, 45, 159, 251, 40, 247, 218, 213, 12, 252, 48, 234, 45, 159, + 214, 105, 251, 40, 213, 21, 252, 48, 234, 45, 159, 251, 165, 234, 45, + 159, 213, 12, 251, 165, 234, 45, 159, 251, 165, 234, 45, 211, 57, 234, + 45, 159, 197, 225, 198, 152, 251, 175, 234, 45, 159, 234, 36, 159, 231, + 143, 234, 36, 159, 237, 17, 248, 209, 251, 42, 199, 34, 219, 120, 231, + 143, 234, 45, 159, 251, 40, 234, 45, 119, 211, 57, 199, 34, 223, 178, + 211, 146, 223, 178, 79, 211, 57, 251, 40, 234, 45, 159, 242, 84, 234, 42, + 234, 43, 242, 83, 206, 189, 223, 163, 234, 45, 159, 206, 189, 234, 45, + 159, 238, 250, 159, 234, 3, 234, 41, 159, 201, 103, 234, 42, 237, 107, + 234, 45, 159, 234, 45, 119, 247, 205, 237, 126, 216, 226, 247, 204, 208, + 11, 234, 45, 159, 213, 12, 234, 45, 159, 228, 17, 159, 213, 12, 228, 17, + 159, 201, 35, 234, 36, 159, 219, 180, 211, 57, 234, 45, 159, 230, 204, + 211, 57, 234, 45, 159, 219, 180, 139, 234, 45, 159, 230, 204, 139, 234, + 45, 159, 219, 180, 247, 218, 213, 12, 234, 45, 159, 230, 204, 247, 218, + 213, 12, 234, 45, 159, 215, 145, 219, 179, 215, 145, 230, 203, 248, 209, + 213, 12, 234, 36, 159, 213, 12, 219, 179, 213, 12, 230, 203, 214, 105, + 219, 180, 213, 21, 234, 45, 159, 214, 105, 230, 204, 213, 21, 234, 45, + 159, 219, 180, 211, 57, 234, 36, 159, 230, 204, 211, 57, 234, 36, 159, + 214, 105, 219, 180, 213, 21, 234, 36, 159, 214, 105, 230, 204, 213, 21, + 234, 36, 159, 219, 180, 211, 57, 230, 203, 230, 204, 211, 57, 219, 179, + 214, 105, 219, 180, 213, 21, 230, 203, 214, 105, 230, 204, 213, 21, 219, + 179, 208, 231, 200, 220, 208, 232, 211, 57, 234, 45, 159, 200, 221, 211, + 57, 234, 45, 159, 208, 232, 211, 57, 234, 36, 159, 200, 221, 211, 57, + 234, 36, 159, 236, 164, 213, 12, 208, 234, 236, 164, 213, 12, 200, 222, + 200, 229, 211, 146, 200, 181, 211, 146, 213, 12, 42, 200, 229, 211, 146, + 213, 12, 42, 200, 181, 211, 146, 200, 229, 79, 211, 57, 234, 45, 159, + 200, 181, 79, 211, 57, 234, 45, 159, 214, 105, 42, 200, 229, 79, 213, 21, + 234, 45, 159, 214, 105, 42, 200, 181, 79, 213, 21, 234, 45, 159, 200, + 229, 79, 4, 213, 12, 234, 45, 159, 200, 181, 79, 4, 213, 12, 234, 45, + 159, 215, 124, 215, 125, 215, 126, 215, 125, 196, 92, 51, 223, 178, 211, + 146, 51, 211, 46, 211, 146, 51, 223, 178, 79, 211, 57, 234, 45, 159, 51, + 211, 46, 79, 211, 57, 234, 45, 159, 51, 247, 111, 51, 238, 181, 47, 209, + 81, 47, 216, 34, 47, 198, 144, 47, 236, 200, 202, 97, 47, 75, 211, 66, + 47, 206, 189, 211, 66, 47, 250, 194, 211, 66, 47, 234, 42, 47, 237, 215, + 112, 209, 81, 112, 216, 34, 112, 198, 144, 112, 75, 211, 66, 50, 199, + 228, 45, 199, 228, 144, 199, 228, 133, 199, 228, 250, 197, 216, 1, 197, + 201, 232, 152, 197, 225, 81, 249, 88, 50, 197, 57, 55, 81, 249, 88, 55, + 50, 197, 57, 236, 164, 213, 12, 208, 179, 213, 12, 197, 201, 236, 164, + 213, 12, 232, 153, 214, 108, 55, 81, 249, 88, 55, 50, 197, 57, 208, 232, + 196, 105, 207, 65, 200, 221, 196, 105, 207, 65, 213, 18, 200, 244, 211, + 146, 239, 32, 250, 220, 213, 18, 200, 243, 213, 18, 200, 244, 79, 211, + 57, 234, 45, 159, 239, 32, 250, 220, 213, 18, 200, 244, 211, 57, 234, 45, + 159, 211, 46, 211, 146, 223, 178, 211, 146, 215, 131, 229, 189, 239, 43, + 217, 27, 223, 110, 192, 192, 214, 224, 213, 20, 50, 251, 116, 4, 251, 16, + 50, 197, 241, 215, 60, 219, 29, 251, 125, 215, 60, 219, 29, 211, 56, 215, + 60, 223, 99, 215, 60, 196, 92, 237, 33, 211, 66, 75, 211, 66, 201, 103, + 211, 66, 236, 200, 198, 144, 248, 63, 45, 213, 18, 233, 93, 204, 24, 208, + 200, 50, 213, 18, 233, 93, 204, 24, 208, 200, 45, 204, 24, 208, 200, 50, + 204, 24, 208, 200, 207, 18, 198, 153, 234, 42, 238, 171, 219, 29, 211, + 56, 238, 171, 219, 29, 251, 125, 55, 200, 228, 55, 200, 180, 55, 223, 99, + 55, 196, 92, 209, 115, 234, 45, 23, 210, 119, 159, 219, 180, 4, 236, 140, + 230, 204, 4, 236, 140, 195, 83, 215, 145, 219, 179, 195, 83, 215, 145, + 230, 203, 219, 180, 234, 45, 119, 211, 57, 230, 203, 230, 204, 234, 45, + 119, 211, 57, 219, 179, 234, 45, 119, 211, 57, 219, 179, 234, 45, 119, + 211, 57, 230, 203, 234, 45, 119, 211, 57, 208, 231, 234, 45, 119, 211, + 57, 200, 220, 236, 164, 213, 12, 208, 235, 211, 57, 234, 44, 236, 164, + 213, 12, 200, 223, 211, 57, 234, 44, 213, 12, 51, 223, 178, 79, 211, 57, + 234, 45, 159, 213, 12, 51, 211, 46, 79, 211, 57, 234, 45, 159, 51, 223, + 178, 79, 211, 57, 213, 12, 234, 45, 159, 51, 211, 46, 79, 211, 57, 213, + 12, 234, 45, 159, 219, 180, 247, 218, 213, 12, 234, 36, 159, 230, 204, + 247, 218, 213, 12, 234, 36, 159, 208, 232, 247, 218, 213, 12, 234, 36, + 159, 200, 221, 247, 218, 213, 12, 234, 36, 159, 213, 12, 213, 18, 200, + 244, 211, 146, 236, 164, 213, 12, 239, 34, 250, 220, 213, 18, 200, 243, + 213, 12, 213, 18, 200, 244, 79, 211, 57, 234, 45, 159, 236, 164, 213, 12, + 239, 34, 250, 220, 213, 18, 200, 244, 211, 57, 234, 44, 81, 234, 120, + 216, 82, 228, 241, 234, 120, 133, 50, 237, 39, 234, 120, 144, 50, 237, + 39, 234, 120, 234, 132, 79, 4, 179, 228, 241, 106, 234, 132, 79, 4, 81, + 249, 88, 250, 183, 234, 95, 79, 228, 241, 106, 2, 234, 132, 79, 4, 81, + 249, 88, 250, 183, 234, 95, 79, 228, 241, 106, 234, 132, 79, 4, 75, 58, + 234, 132, 79, 4, 211, 6, 2, 234, 132, 79, 4, 211, 6, 234, 132, 79, 4, + 196, 103, 234, 132, 79, 4, 105, 228, 241, 201, 15, 239, 32, 4, 179, 228, + 241, 106, 239, 32, 4, 81, 249, 88, 250, 183, 234, 95, 79, 228, 241, 106, + 2, 239, 32, 4, 81, 249, 88, 250, 183, 234, 95, 79, 228, 241, 106, 239, + 32, 4, 211, 6, 2, 239, 32, 4, 211, 6, 191, 167, 213, 10, 249, 131, 216, + 189, 237, 34, 56, 234, 135, 57, 228, 172, 133, 250, 235, 144, 250, 235, + 208, 194, 209, 248, 193, 135, 219, 112, 45, 247, 30, 50, 247, 30, 45, + 232, 193, 50, 232, 193, 248, 77, 50, 238, 219, 248, 77, 45, 238, 219, + 198, 54, 50, 238, 219, 198, 54, 45, 238, 219, 207, 18, 213, 12, 56, 51, + 218, 232, 251, 16, 205, 43, 205, 52, 199, 107, 207, 96, 209, 25, 223, + 144, 195, 56, 201, 190, 209, 108, 79, 223, 109, 56, 153, 213, 12, 56, + 193, 145, 228, 174, 198, 54, 45, 239, 1, 198, 54, 50, 239, 1, 248, 77, + 45, 239, 1, 248, 77, 50, 239, 1, 198, 54, 132, 223, 113, 248, 77, 132, + 223, 113, 232, 93, 202, 65, 133, 250, 236, 248, 210, 105, 228, 241, 249, + 76, 211, 59, 221, 222, 234, 32, 119, 199, 34, 183, 192, 236, 223, 163, + 42, 207, 93, 248, 62, 221, 220, 219, 219, 251, 116, 248, 53, 206, 203, + 251, 116, 248, 53, 234, 32, 119, 199, 34, 219, 224, 248, 221, 206, 188, + 238, 138, 251, 175, 250, 244, 200, 74, 198, 39, 206, 41, 236, 252, 211, + 47, 239, 48, 199, 181, 202, 81, 238, 246, 238, 245, 251, 59, 232, 75, 16, + 228, 67, 251, 59, 232, 75, 16, 201, 181, 208, 30, 251, 59, 232, 75, 16, + 208, 31, 234, 44, 251, 59, 232, 75, 16, 208, 31, 236, 207, 251, 59, 232, + 75, 16, 208, 31, 237, 32, 251, 59, 232, 75, 16, 208, 31, 222, 188, 251, + 59, 232, 75, 16, 208, 31, 243, 10, 251, 59, 232, 75, 16, 243, 11, 201, + 71, 251, 59, 232, 75, 16, 243, 11, 222, 188, 251, 59, 232, 75, 16, 202, + 98, 164, 251, 59, 232, 75, 16, 249, 142, 164, 251, 59, 232, 75, 16, 208, + 31, 202, 97, 251, 59, 232, 75, 16, 208, 31, 249, 141, 251, 59, 232, 75, + 16, 208, 31, 219, 179, 251, 59, 232, 75, 16, 208, 31, 230, 203, 251, 59, + 232, 75, 16, 118, 195, 176, 251, 59, 232, 75, 16, 96, 195, 176, 251, 59, + 232, 75, 16, 208, 31, 118, 57, 251, 59, 232, 75, 16, 208, 31, 96, 57, + 251, 59, 232, 75, 16, 243, 11, 249, 141, 251, 59, 232, 75, 16, 144, 199, + 229, 196, 103, 251, 59, 232, 75, 16, 237, 107, 201, 71, 251, 59, 232, 75, + 16, 208, 31, 144, 247, 96, 251, 59, 232, 75, 16, 208, 31, 237, 106, 251, + 59, 232, 75, 16, 144, 199, 229, 222, 188, 251, 59, 232, 75, 16, 196, 66, + 195, 176, 251, 59, 232, 75, 16, 208, 31, 196, 66, 57, 251, 59, 232, 75, + 16, 133, 199, 229, 211, 6, 251, 59, 232, 75, 16, 237, 119, 201, 71, 251, + 59, 232, 75, 16, 208, 31, 133, 247, 96, 251, 59, 232, 75, 16, 208, 31, + 237, 118, 251, 59, 232, 75, 16, 133, 199, 229, 222, 188, 251, 59, 232, + 75, 16, 235, 119, 195, 176, 251, 59, 232, 75, 16, 208, 31, 235, 119, 57, + 251, 59, 232, 75, 16, 207, 251, 196, 103, 251, 59, 232, 75, 16, 237, 107, + 196, 103, 251, 59, 232, 75, 16, 237, 33, 196, 103, 251, 59, 232, 75, 16, + 222, 189, 196, 103, 251, 59, 232, 75, 16, 243, 11, 196, 103, 251, 59, + 232, 75, 16, 133, 203, 53, 222, 188, 251, 59, 232, 75, 16, 207, 251, 208, + 30, 251, 59, 232, 75, 16, 243, 11, 201, 102, 251, 59, 232, 75, 16, 208, + 31, 242, 83, 251, 59, 232, 75, 16, 133, 199, 229, 237, 42, 251, 59, 232, + 75, 16, 237, 119, 237, 42, 251, 59, 232, 75, 16, 201, 103, 237, 42, 251, + 59, 232, 75, 16, 222, 189, 237, 42, 251, 59, 232, 75, 16, 243, 11, 237, + 42, 251, 59, 232, 75, 16, 144, 203, 53, 201, 71, 251, 59, 232, 75, 16, + 45, 203, 53, 201, 71, 251, 59, 232, 75, 16, 198, 153, 237, 42, 251, 59, + 232, 75, 16, 230, 204, 237, 42, 251, 59, 232, 75, 16, 242, 75, 164, 251, + 59, 232, 75, 16, 237, 119, 198, 152, 251, 59, 232, 75, 16, 191, 20, 251, + 59, 232, 75, 16, 201, 72, 198, 152, 251, 59, 232, 75, 16, 204, 26, 196, + 103, 251, 59, 232, 75, 16, 208, 31, 213, 12, 234, 44, 251, 59, 232, 75, + 16, 208, 31, 208, 12, 251, 59, 232, 75, 16, 144, 247, 97, 198, 152, 251, + 59, 232, 75, 16, 133, 247, 97, 198, 152, 251, 59, 232, 75, 16, 223, 83, + 251, 59, 232, 75, 16, 207, 3, 251, 59, 232, 75, 16, 211, 110, 251, 59, + 232, 75, 16, 251, 161, 196, 103, 251, 59, 232, 75, 16, 234, 48, 196, 103, + 251, 59, 232, 75, 16, 223, 84, 196, 103, 251, 59, 232, 75, 16, 211, 111, + 196, 103, 251, 59, 232, 75, 16, 251, 160, 213, 12, 243, 126, 77, 50, 251, + 116, 4, 235, 119, 191, 21, 57, 203, 21, 211, 77, 248, 62, 248, 236, 113, + 81, 219, 113, 4, 82, 236, 140, 223, 119, 113, 239, 27, 196, 101, 113, + 236, 225, 196, 101, 113, 234, 107, 113, 239, 63, 113, 63, 51, 4, 247, 22, + 81, 219, 112, 234, 78, 113, 251, 152, 221, 223, 113, 229, 202, 113, 47, + 228, 241, 249, 88, 4, 213, 9, 47, 197, 242, 235, 123, 248, 22, 243, 11, + 4, 213, 15, 57, 196, 99, 113, 215, 216, 113, 228, 84, 113, 211, 75, 230, + 115, 113, 211, 75, 220, 141, 113, 210, 93, 113, 210, 92, 113, 236, 234, + 238, 169, 16, 232, 146, 109, 202, 29, 113, 251, 59, 232, 75, 16, 208, 30, + 237, 138, 204, 11, 221, 223, 113, 208, 217, 210, 204, 214, 73, 210, 204, + 208, 212, 205, 77, 113, 242, 238, 205, 77, 113, 45, 210, 114, 116, 102, + 45, 210, 114, 233, 203, 45, 210, 114, 110, 102, 50, 210, 114, 116, 102, + 50, 210, 114, 233, 203, 50, 210, 114, 110, 102, 45, 51, 248, 54, 116, + 239, 1, 45, 51, 248, 54, 233, 203, 45, 51, 248, 54, 110, 239, 1, 50, 51, + 248, 54, 116, 239, 1, 50, 51, 248, 54, 233, 203, 50, 51, 248, 54, 110, + 239, 1, 45, 238, 171, 248, 54, 116, 102, 45, 238, 171, 248, 54, 82, 209, + 175, 45, 238, 171, 248, 54, 110, 102, 238, 171, 248, 54, 233, 203, 50, + 238, 171, 248, 54, 116, 102, 50, 238, 171, 248, 54, 82, 209, 175, 50, + 238, 171, 248, 54, 110, 102, 223, 114, 233, 203, 228, 241, 219, 113, 233, + 203, 116, 45, 211, 57, 110, 50, 238, 171, 248, 54, 205, 53, 116, 50, 211, + 57, 110, 45, 238, 171, 248, 54, 205, 53, 200, 202, 198, 53, 200, 202, + 248, 76, 198, 54, 51, 248, 53, 248, 77, 51, 248, 53, 248, 77, 51, 248, + 54, 139, 198, 54, 51, 248, 53, 48, 16, 248, 76, 45, 81, 111, 219, 112, + 50, 81, 111, 219, 112, 228, 241, 205, 97, 219, 111, 228, 241, 205, 97, + 219, 110, 228, 241, 205, 97, 219, 109, 228, 241, 205, 97, 219, 108, 237, + 97, 16, 156, 81, 23, 198, 54, 183, 237, 97, 16, 156, 81, 23, 248, 77, + 183, 237, 97, 16, 156, 81, 4, 243, 10, 237, 97, 16, 156, 144, 23, 228, + 241, 4, 243, 10, 237, 97, 16, 156, 133, 23, 228, 241, 4, 243, 10, 237, + 97, 16, 156, 81, 4, 197, 241, 237, 97, 16, 156, 144, 23, 228, 241, 4, + 197, 241, 237, 97, 16, 156, 133, 23, 228, 241, 4, 197, 241, 237, 97, 16, + 156, 81, 23, 193, 138, 237, 97, 16, 156, 144, 23, 228, 241, 4, 193, 138, + 237, 97, 16, 156, 133, 23, 228, 241, 4, 193, 138, 237, 97, 16, 156, 144, + 23, 228, 240, 237, 97, 16, 156, 133, 23, 228, 240, 237, 97, 16, 156, 81, + 23, 198, 54, 219, 224, 237, 97, 16, 156, 81, 23, 248, 77, 219, 224, 51, + 232, 159, 207, 23, 113, 234, 149, 113, 81, 219, 113, 233, 203, 216, 159, + 248, 36, 216, 159, 179, 139, 203, 39, 216, 159, 203, 40, 139, 219, 19, + 216, 159, 179, 139, 105, 203, 25, 216, 159, 105, 203, 26, 139, 219, 19, + 216, 159, 105, 203, 26, 222, 197, 216, 159, 197, 221, 216, 159, 199, 65, + 216, 159, 210, 22, 234, 208, 230, 188, 232, 69, 198, 54, 210, 113, 248, + 77, 210, 113, 198, 54, 238, 171, 248, 53, 248, 77, 238, 171, 248, 53, + 198, 54, 198, 42, 203, 103, 248, 53, 248, 77, 198, 42, 203, 103, 248, 53, + 63, 198, 5, 248, 221, 206, 189, 4, 243, 10, 201, 51, 232, 204, 252, 64, + 238, 168, 234, 134, 223, 99, 237, 138, 233, 207, 113, 62, 206, 203, 55, + 197, 241, 62, 219, 219, 55, 197, 241, 62, 196, 76, 55, 197, 241, 62, 235, + 122, 55, 197, 241, 62, 206, 203, 55, 197, 242, 4, 81, 164, 62, 219, 219, + 55, 197, 242, 4, 81, 164, 62, 206, 203, 197, 242, 4, 55, 81, 164, 251, + 201, 242, 222, 201, 58, 198, 145, 242, 222, 228, 175, 4, 232, 184, 205, + 140, 62, 216, 213, 219, 219, 197, 241, 62, 216, 213, 206, 203, 197, 241, + 62, 216, 213, 196, 76, 197, 241, 62, 216, 213, 235, 122, 197, 241, 55, + 81, 164, 62, 51, 40, 201, 63, 62, 243, 11, 40, 207, 97, 208, 255, 113, + 208, 255, 211, 103, 113, 208, 255, 211, 105, 113, 208, 255, 202, 93, 113, + 211, 168, 233, 194, 113, 16, 40, 212, 138, 16, 40, 201, 98, 79, 229, 232, + 16, 40, 201, 98, 79, 199, 53, 16, 40, 234, 95, 79, 199, 53, 16, 40, 234, + 95, 79, 198, 11, 16, 40, 234, 81, 16, 40, 252, 51, 16, 40, 248, 235, 16, + 40, 249, 140, 16, 40, 228, 241, 199, 230, 16, 40, 219, 113, 233, 50, 16, + 40, 81, 199, 230, 16, 40, 232, 146, 233, 50, 16, 40, 247, 88, 207, 22, + 16, 40, 203, 77, 211, 14, 16, 40, 203, 77, 223, 162, 16, 40, 237, 210, + 219, 103, 234, 14, 16, 40, 237, 75, 239, 22, 107, 16, 40, 237, 75, 239, + 22, 109, 16, 40, 237, 75, 239, 22, 138, 16, 40, 237, 75, 239, 22, 134, + 16, 40, 214, 106, 252, 51, 16, 40, 200, 69, 223, 228, 16, 40, 234, 95, + 79, 198, 12, 248, 129, 16, 40, 247, 126, 16, 40, 234, 95, 79, 216, 212, + 16, 40, 200, 226, 16, 40, 234, 14, 16, 40, 233, 7, 204, 10, 16, 40, 230, + 187, 204, 10, 16, 40, 207, 98, 204, 10, 16, 40, 196, 91, 204, 10, 16, 40, + 201, 247, 16, 40, 237, 116, 248, 133, 113, 211, 77, 248, 62, 16, 40, 214, + 76, 16, 40, 237, 117, 232, 146, 109, 16, 40, 200, 227, 232, 146, 109, + 211, 161, 102, 211, 161, 246, 252, 211, 161, 232, 149, 211, 161, 223, 93, + 232, 149, 211, 161, 248, 232, 248, 5, 211, 161, 248, 70, 198, 178, 211, + 161, 248, 48, 249, 93, 228, 15, 211, 161, 251, 139, 79, 243, 125, 211, + 161, 237, 215, 211, 161, 238, 157, 252, 55, 212, 136, 211, 161, 55, 249, + 141, 47, 17, 107, 47, 17, 109, 47, 17, 138, 47, 17, 134, 47, 17, 149, 47, + 17, 169, 47, 17, 175, 47, 17, 171, 47, 17, 178, 47, 31, 199, 95, 47, 31, + 234, 127, 47, 31, 197, 37, 47, 31, 198, 251, 47, 31, 232, 122, 47, 31, + 233, 19, 47, 31, 202, 130, 47, 31, 203, 244, 47, 31, 234, 161, 47, 31, + 213, 171, 47, 31, 197, 32, 127, 17, 107, 127, 17, 109, 127, 17, 138, 127, + 17, 134, 127, 17, 149, 127, 17, 169, 127, 17, 175, 127, 17, 171, 127, 17, + 178, 127, 31, 199, 95, 127, 31, 234, 127, 127, 31, 197, 37, 127, 31, 198, + 251, 127, 31, 232, 122, 127, 31, 233, 19, 127, 31, 202, 130, 127, 31, + 203, 244, 127, 31, 234, 161, 127, 31, 213, 171, 127, 31, 197, 32, 17, 91, + 232, 80, 201, 63, 17, 105, 232, 80, 201, 63, 17, 115, 232, 80, 201, 63, + 17, 232, 128, 232, 80, 201, 63, 17, 232, 226, 232, 80, 201, 63, 17, 202, + 136, 232, 80, 201, 63, 17, 203, 247, 232, 80, 201, 63, 17, 234, 164, 232, + 80, 201, 63, 17, 213, 175, 232, 80, 201, 63, 31, 199, 96, 232, 80, 201, + 63, 31, 234, 128, 232, 80, 201, 63, 31, 197, 38, 232, 80, 201, 63, 31, + 198, 252, 232, 80, 201, 63, 31, 232, 123, 232, 80, 201, 63, 31, 233, 20, + 232, 80, 201, 63, 31, 202, 131, 232, 80, 201, 63, 31, 203, 245, 232, 80, + 201, 63, 31, 234, 162, 232, 80, 201, 63, 31, 213, 172, 232, 80, 201, 63, + 31, 197, 33, 232, 80, 201, 63, 127, 8, 2, 1, 65, 127, 8, 2, 1, 250, 120, + 127, 8, 2, 1, 247, 193, 127, 8, 2, 1, 238, 127, 127, 8, 2, 1, 71, 127, 8, + 2, 1, 233, 175, 127, 8, 2, 1, 232, 51, 127, 8, 2, 1, 230, 116, 127, 8, 2, + 1, 68, 127, 8, 2, 1, 223, 35, 127, 8, 2, 1, 222, 152, 127, 8, 2, 1, 172, + 127, 8, 2, 1, 218, 168, 127, 8, 2, 1, 215, 61, 127, 8, 2, 1, 74, 127, 8, + 2, 1, 210, 236, 127, 8, 2, 1, 208, 104, 127, 8, 2, 1, 146, 127, 8, 2, 1, + 206, 8, 127, 8, 2, 1, 200, 43, 127, 8, 2, 1, 66, 127, 8, 2, 1, 196, 12, + 127, 8, 2, 1, 193, 224, 127, 8, 2, 1, 192, 235, 127, 8, 2, 1, 192, 159, + 127, 8, 2, 1, 191, 166, 47, 8, 6, 1, 65, 47, 8, 6, 1, 250, 120, 47, 8, 6, + 1, 247, 193, 47, 8, 6, 1, 238, 127, 47, 8, 6, 1, 71, 47, 8, 6, 1, 233, + 175, 47, 8, 6, 1, 232, 51, 47, 8, 6, 1, 230, 116, 47, 8, 6, 1, 68, 47, 8, + 6, 1, 223, 35, 47, 8, 6, 1, 222, 152, 47, 8, 6, 1, 172, 47, 8, 6, 1, 218, + 168, 47, 8, 6, 1, 215, 61, 47, 8, 6, 1, 74, 47, 8, 6, 1, 210, 236, 47, 8, + 6, 1, 208, 104, 47, 8, 6, 1, 146, 47, 8, 6, 1, 206, 8, 47, 8, 6, 1, 200, + 43, 47, 8, 6, 1, 66, 47, 8, 6, 1, 196, 12, 47, 8, 6, 1, 193, 224, 47, 8, + 6, 1, 192, 235, 47, 8, 6, 1, 192, 159, 47, 8, 6, 1, 191, 166, 47, 8, 2, + 1, 65, 47, 8, 2, 1, 250, 120, 47, 8, 2, 1, 247, 193, 47, 8, 2, 1, 238, + 127, 47, 8, 2, 1, 71, 47, 8, 2, 1, 233, 175, 47, 8, 2, 1, 232, 51, 47, 8, + 2, 1, 230, 116, 47, 8, 2, 1, 68, 47, 8, 2, 1, 223, 35, 47, 8, 2, 1, 222, + 152, 47, 8, 2, 1, 172, 47, 8, 2, 1, 218, 168, 47, 8, 2, 1, 215, 61, 47, + 8, 2, 1, 74, 47, 8, 2, 1, 210, 236, 47, 8, 2, 1, 208, 104, 47, 8, 2, 1, + 146, 47, 8, 2, 1, 206, 8, 47, 8, 2, 1, 200, 43, 47, 8, 2, 1, 66, 47, 8, + 2, 1, 196, 12, 47, 8, 2, 1, 193, 224, 47, 8, 2, 1, 192, 235, 47, 8, 2, 1, + 192, 159, 47, 8, 2, 1, 191, 166, 47, 17, 191, 77, 214, 106, 47, 31, 234, + 127, 214, 106, 47, 31, 197, 37, 214, 106, 47, 31, 198, 251, 214, 106, 47, + 31, 232, 122, 214, 106, 47, 31, 233, 19, 214, 106, 47, 31, 202, 130, 214, + 106, 47, 31, 203, 244, 214, 106, 47, 31, 234, 161, 214, 106, 47, 31, 213, + 171, 214, 106, 47, 31, 197, 32, 55, 47, 17, 107, 55, 47, 17, 109, 55, 47, + 17, 138, 55, 47, 17, 134, 55, 47, 17, 149, 55, 47, 17, 169, 55, 47, 17, + 175, 55, 47, 17, 171, 55, 47, 17, 178, 55, 47, 31, 199, 95, 214, 106, 47, + 17, 191, 77, 111, 122, 156, 228, 240, 111, 122, 88, 228, 240, 111, 122, + 156, 195, 135, 111, 122, 88, 195, 135, 111, 122, 156, 197, 225, 237, 216, + 228, 240, 111, 122, 88, 197, 225, 237, 216, 228, 240, 111, 122, 156, 197, + 225, 237, 216, 195, 135, 111, 122, 88, 197, 225, 237, 216, 195, 135, 111, + 122, 156, 208, 26, 237, 216, 228, 240, 111, 122, 88, 208, 26, 237, 216, + 228, 240, 111, 122, 156, 208, 26, 237, 216, 195, 135, 111, 122, 88, 208, + 26, 237, 216, 195, 135, 111, 122, 156, 144, 23, 183, 111, 122, 144, 156, + 23, 50, 229, 217, 111, 122, 144, 88, 23, 50, 219, 132, 111, 122, 88, 144, + 23, 183, 111, 122, 156, 144, 23, 219, 224, 111, 122, 144, 156, 23, 45, + 229, 217, 111, 122, 144, 88, 23, 45, 219, 132, 111, 122, 88, 144, 23, + 219, 224, 111, 122, 156, 133, 23, 183, 111, 122, 133, 156, 23, 50, 229, + 217, 111, 122, 133, 88, 23, 50, 219, 132, 111, 122, 88, 133, 23, 183, + 111, 122, 156, 133, 23, 219, 224, 111, 122, 133, 156, 23, 45, 229, 217, + 111, 122, 133, 88, 23, 45, 219, 132, 111, 122, 88, 133, 23, 219, 224, + 111, 122, 156, 81, 23, 183, 111, 122, 81, 156, 23, 50, 229, 217, 111, + 122, 133, 88, 23, 50, 144, 219, 132, 111, 122, 144, 88, 23, 50, 133, 219, + 132, 111, 122, 81, 88, 23, 50, 219, 132, 111, 122, 144, 156, 23, 50, 133, + 229, 217, 111, 122, 133, 156, 23, 50, 144, 229, 217, 111, 122, 88, 81, + 23, 183, 111, 122, 156, 81, 23, 219, 224, 111, 122, 81, 156, 23, 45, 229, + 217, 111, 122, 133, 88, 23, 45, 144, 219, 132, 111, 122, 144, 88, 23, 45, + 133, 219, 132, 111, 122, 81, 88, 23, 45, 219, 132, 111, 122, 144, 156, + 23, 45, 133, 229, 217, 111, 122, 133, 156, 23, 45, 144, 229, 217, 111, + 122, 88, 81, 23, 219, 224, 111, 122, 156, 144, 23, 228, 240, 111, 122, + 45, 88, 23, 50, 144, 219, 132, 111, 122, 50, 88, 23, 45, 144, 219, 132, + 111, 122, 144, 156, 23, 228, 241, 229, 217, 111, 122, 144, 88, 23, 228, + 241, 219, 132, 111, 122, 50, 156, 23, 45, 144, 229, 217, 111, 122, 45, + 156, 23, 50, 144, 229, 217, 111, 122, 88, 144, 23, 228, 240, 111, 122, + 156, 133, 23, 228, 240, 111, 122, 45, 88, 23, 50, 133, 219, 132, 111, + 122, 50, 88, 23, 45, 133, 219, 132, 111, 122, 133, 156, 23, 228, 241, + 229, 217, 111, 122, 133, 88, 23, 228, 241, 219, 132, 111, 122, 50, 156, + 23, 45, 133, 229, 217, 111, 122, 45, 156, 23, 50, 133, 229, 217, 111, + 122, 88, 133, 23, 228, 240, 111, 122, 156, 81, 23, 228, 240, 111, 122, + 45, 88, 23, 50, 81, 219, 132, 111, 122, 50, 88, 23, 45, 81, 219, 132, + 111, 122, 81, 156, 23, 228, 241, 229, 217, 111, 122, 133, 88, 23, 144, + 228, 241, 219, 132, 111, 122, 144, 88, 23, 133, 228, 241, 219, 132, 111, + 122, 81, 88, 23, 228, 241, 219, 132, 111, 122, 45, 133, 88, 23, 50, 144, + 219, 132, 111, 122, 50, 133, 88, 23, 45, 144, 219, 132, 111, 122, 45, + 144, 88, 23, 50, 133, 219, 132, 111, 122, 50, 144, 88, 23, 45, 133, 219, + 132, 111, 122, 144, 156, 23, 133, 228, 241, 229, 217, 111, 122, 133, 156, + 23, 144, 228, 241, 229, 217, 111, 122, 50, 156, 23, 45, 81, 229, 217, + 111, 122, 45, 156, 23, 50, 81, 229, 217, 111, 122, 88, 81, 23, 228, 240, + 111, 122, 156, 55, 237, 216, 228, 240, 111, 122, 88, 55, 237, 216, 228, + 240, 111, 122, 156, 55, 237, 216, 195, 135, 111, 122, 88, 55, 237, 216, + 195, 135, 111, 122, 55, 228, 240, 111, 122, 55, 195, 135, 111, 122, 144, + 202, 170, 23, 50, 235, 133, 111, 122, 144, 55, 23, 50, 202, 169, 111, + 122, 55, 144, 23, 183, 111, 122, 144, 202, 170, 23, 45, 235, 133, 111, + 122, 144, 55, 23, 45, 202, 169, 111, 122, 55, 144, 23, 219, 224, 111, + 122, 133, 202, 170, 23, 50, 235, 133, 111, 122, 133, 55, 23, 50, 202, + 169, 111, 122, 55, 133, 23, 183, 111, 122, 133, 202, 170, 23, 45, 235, + 133, 111, 122, 133, 55, 23, 45, 202, 169, 111, 122, 55, 133, 23, 219, + 224, 111, 122, 81, 202, 170, 23, 50, 235, 133, 111, 122, 81, 55, 23, 50, + 202, 169, 111, 122, 55, 81, 23, 183, 111, 122, 81, 202, 170, 23, 45, 235, + 133, 111, 122, 81, 55, 23, 45, 202, 169, 111, 122, 55, 81, 23, 219, 224, + 111, 122, 144, 202, 170, 23, 228, 241, 235, 133, 111, 122, 144, 55, 23, + 228, 241, 202, 169, 111, 122, 55, 144, 23, 228, 240, 111, 122, 133, 202, + 170, 23, 228, 241, 235, 133, 111, 122, 133, 55, 23, 228, 241, 202, 169, + 111, 122, 55, 133, 23, 228, 240, 111, 122, 81, 202, 170, 23, 228, 241, + 235, 133, 111, 122, 81, 55, 23, 228, 241, 202, 169, 111, 122, 55, 81, 23, + 228, 240, 111, 122, 156, 251, 17, 144, 23, 183, 111, 122, 156, 251, 17, + 144, 23, 219, 224, 111, 122, 156, 251, 17, 133, 23, 219, 224, 111, 122, + 156, 251, 17, 133, 23, 183, 111, 122, 156, 237, 39, 116, 50, 119, 110, + 219, 224, 111, 122, 156, 237, 39, 116, 45, 119, 110, 183, 111, 122, 156, + 237, 39, 238, 217, 111, 122, 156, 219, 224, 111, 122, 156, 196, 77, 111, + 122, 156, 183, 111, 122, 156, 235, 123, 111, 122, 88, 219, 224, 111, 122, + 88, 196, 77, 111, 122, 88, 183, 111, 122, 88, 235, 123, 111, 122, 156, + 45, 23, 88, 183, 111, 122, 156, 133, 23, 88, 235, 123, 111, 122, 88, 45, + 23, 156, 183, 111, 122, 88, 133, 23, 156, 235, 123, 116, 132, 248, 129, + 110, 91, 234, 160, 248, 129, 110, 91, 208, 23, 248, 129, 110, 115, 234, + 158, 248, 129, 110, 132, 248, 129, 110, 232, 226, 234, 158, 248, 129, + 110, 115, 208, 21, 248, 129, 110, 203, 247, 234, 158, 248, 129, 232, 80, + 248, 129, 45, 203, 247, 234, 158, 248, 129, 45, 115, 208, 21, 248, 129, + 45, 232, 226, 234, 158, 248, 129, 45, 132, 248, 129, 45, 115, 234, 158, + 248, 129, 45, 91, 208, 23, 248, 129, 45, 91, 234, 160, 248, 129, 50, 132, + 248, 129, 156, 203, 153, 216, 213, 203, 153, 237, 221, 203, 153, 116, 91, + 234, 160, 248, 129, 50, 91, 234, 160, 248, 129, 208, 28, 110, 219, 224, + 208, 28, 110, 183, 208, 28, 116, 219, 224, 208, 28, 116, 45, 23, 110, 45, + 23, 110, 183, 208, 28, 116, 45, 23, 110, 183, 208, 28, 116, 45, 23, 116, + 50, 23, 110, 219, 224, 208, 28, 116, 45, 23, 116, 50, 23, 110, 183, 208, + 28, 116, 183, 208, 28, 116, 50, 23, 110, 219, 224, 208, 28, 116, 50, 23, + 110, 45, 23, 110, 183, 62, 201, 190, 63, 201, 190, 63, 51, 4, 206, 113, + 239, 0, 63, 51, 239, 33, 62, 2, 201, 190, 51, 4, 228, 241, 233, 5, 51, 4, + 81, 233, 5, 51, 4, 211, 38, 238, 211, 233, 5, 51, 4, 116, 45, 119, 110, + 50, 233, 5, 51, 4, 116, 50, 119, 110, 45, 233, 5, 51, 4, 237, 39, 238, + 211, 233, 5, 62, 2, 201, 190, 63, 2, 201, 190, 62, 207, 92, 63, 207, 92, + 62, 81, 207, 92, 63, 81, 207, 92, 62, 210, 117, 63, 210, 117, 62, 196, + 76, 197, 241, 63, 196, 76, 197, 241, 62, 196, 76, 2, 197, 241, 63, 196, + 76, 2, 197, 241, 62, 206, 203, 197, 241, 63, 206, 203, 197, 241, 62, 206, + 203, 2, 197, 241, 63, 206, 203, 2, 197, 241, 62, 206, 203, 209, 59, 63, + 206, 203, 209, 59, 62, 235, 122, 197, 241, 63, 235, 122, 197, 241, 62, + 235, 122, 2, 197, 241, 63, 235, 122, 2, 197, 241, 62, 219, 219, 197, 241, + 63, 219, 219, 197, 241, 62, 219, 219, 2, 197, 241, 63, 219, 219, 2, 197, + 241, 62, 219, 219, 209, 59, 63, 219, 219, 209, 59, 62, 237, 32, 63, 237, + 32, 63, 237, 33, 239, 33, 62, 2, 237, 32, 232, 235, 218, 232, 63, 243, + 10, 235, 138, 243, 10, 243, 11, 4, 81, 233, 5, 247, 244, 62, 243, 10, + 243, 11, 4, 45, 132, 248, 139, 243, 11, 4, 50, 132, 248, 139, 243, 11, 4, + 110, 132, 248, 139, 243, 11, 4, 116, 132, 248, 139, 243, 11, 4, 116, 50, + 208, 28, 248, 139, 243, 11, 4, 251, 175, 247, 218, 116, 45, 208, 28, 248, + 139, 45, 132, 62, 243, 10, 50, 132, 62, 243, 10, 223, 95, 247, 248, 223, + 95, 63, 243, 10, 116, 132, 223, 95, 63, 243, 10, 110, 132, 223, 95, 63, + 243, 10, 116, 45, 208, 28, 243, 4, 251, 16, 116, 50, 208, 28, 243, 4, + 251, 16, 110, 50, 208, 28, 243, 4, 251, 16, 110, 45, 208, 28, 243, 4, + 251, 16, 116, 132, 243, 10, 110, 132, 243, 10, 62, 110, 50, 197, 241, 62, + 110, 45, 197, 241, 62, 116, 45, 197, 241, 62, 116, 50, 197, 241, 63, 247, + 248, 51, 4, 45, 132, 248, 139, 51, 4, 50, 132, 248, 139, 51, 4, 116, 45, + 237, 39, 132, 248, 139, 51, 4, 110, 50, 237, 39, 132, 248, 139, 63, 51, + 4, 81, 248, 154, 219, 112, 63, 196, 76, 197, 242, 4, 236, 140, 196, 76, + 197, 242, 4, 45, 132, 248, 139, 196, 76, 197, 242, 4, 50, 132, 248, 139, + 220, 13, 243, 10, 63, 51, 4, 116, 45, 208, 27, 63, 51, 4, 110, 45, 208, + 27, 63, 51, 4, 110, 50, 208, 27, 63, 51, 4, 116, 50, 208, 27, 63, 243, + 11, 4, 116, 45, 208, 27, 63, 243, 11, 4, 110, 45, 208, 27, 63, 243, 11, + 4, 110, 50, 208, 27, 63, 243, 11, 4, 116, 50, 208, 27, 116, 45, 197, 241, + 116, 50, 197, 241, 110, 45, 197, 241, 63, 216, 213, 201, 190, 62, 216, + 213, 201, 190, 63, 216, 213, 2, 201, 190, 62, 216, 213, 2, 201, 190, 110, + 50, 197, 241, 62, 200, 199, 4, 207, 119, 242, 210, 196, 117, 202, 48, + 242, 77, 62, 201, 102, 63, 201, 102, 219, 129, 198, 208, 200, 198, 250, + 213, 213, 35, 237, 86, 213, 35, 239, 42, 211, 62, 62, 199, 106, 63, 199, + 106, 249, 107, 248, 62, 249, 107, 111, 4, 243, 125, 249, 107, 111, 4, + 192, 235, 205, 154, 196, 118, 4, 207, 150, 235, 96, 228, 181, 248, 207, + 63, 203, 49, 209, 175, 62, 203, 49, 209, 175, 203, 140, 207, 18, 206, + 122, 232, 190, 229, 224, 247, 248, 62, 45, 209, 58, 223, 148, 62, 50, + 209, 58, 223, 148, 63, 45, 209, 58, 223, 148, 63, 133, 209, 58, 223, 148, + 63, 50, 209, 58, 223, 148, 63, 144, 209, 58, 223, 148, 202, 104, 23, 238, + 215, 247, 71, 56, 207, 164, 56, 248, 162, 56, 247, 151, 251, 99, 211, 39, + 238, 217, 243, 96, 207, 3, 238, 218, 79, 218, 255, 238, 218, 79, 222, + 254, 201, 103, 23, 238, 227, 233, 74, 113, 252, 34, 203, 143, 230, 62, + 23, 202, 213, 210, 61, 113, 192, 22, 192, 106, 197, 231, 40, 229, 219, + 197, 231, 40, 220, 43, 197, 231, 40, 232, 243, 197, 231, 40, 198, 209, + 197, 231, 40, 193, 66, 197, 231, 40, 193, 143, 197, 231, 40, 215, 184, + 197, 231, 40, 234, 207, 193, 94, 79, 237, 60, 63, 232, 92, 233, 103, 63, + 202, 64, 233, 103, 62, 202, 64, 233, 103, 63, 200, 199, 4, 207, 119, 232, + 238, 208, 23, 215, 205, 220, 6, 208, 23, 215, 205, 216, 180, 233, 42, 56, + 234, 207, 217, 97, 56, 222, 167, 205, 115, 196, 57, 214, 94, 209, 77, + 251, 2, 199, 164, 231, 152, 247, 124, 219, 186, 195, 38, 219, 143, 205, + 80, 205, 183, 247, 106, 251, 34, 209, 120, 63, 243, 105, 221, 138, 63, + 243, 105, 208, 14, 63, 243, 105, 206, 131, 63, 243, 105, 248, 152, 63, + 243, 105, 221, 76, 63, 243, 105, 210, 74, 62, 243, 105, 221, 138, 62, + 243, 105, 208, 14, 62, 243, 105, 206, 131, 62, 243, 105, 248, 152, 62, + 243, 105, 221, 76, 62, 243, 105, 210, 74, 62, 201, 245, 200, 211, 63, + 229, 224, 200, 211, 63, 237, 33, 200, 211, 62, 242, 207, 200, 211, 63, + 201, 245, 200, 211, 62, 229, 224, 200, 211, 62, 237, 33, 200, 211, 63, + 242, 207, 200, 211, 228, 181, 201, 195, 208, 23, 213, 6, 234, 160, 213, + 6, 249, 13, 234, 160, 213, 1, 249, 13, 202, 129, 213, 1, 215, 97, 232, + 207, 56, 215, 97, 214, 206, 56, 215, 97, 203, 127, 56, 193, 105, 200, 63, + 238, 217, 234, 204, 200, 63, 238, 217, 196, 87, 207, 88, 113, 207, 88, + 16, 40, 196, 254, 209, 98, 207, 88, 16, 40, 196, 252, 209, 98, 207, 88, + 16, 40, 196, 251, 209, 98, 207, 88, 16, 40, 196, 249, 209, 98, 207, 88, + 16, 40, 196, 247, 209, 98, 207, 88, 16, 40, 196, 245, 209, 98, 207, 88, + 16, 40, 196, 243, 209, 98, 207, 88, 16, 40, 231, 149, 217, 28, 62, 196, + 87, 207, 88, 113, 207, 89, 210, 136, 113, 210, 104, 210, 136, 113, 210, + 3, 210, 136, 56, 193, 92, 113, 237, 25, 233, 102, 237, 25, 233, 101, 237, + 25, 233, 100, 237, 25, 233, 99, 237, 25, 233, 98, 237, 25, 233, 97, 63, + 243, 11, 4, 75, 183, 63, 243, 11, 4, 105, 236, 138, 62, 243, 11, 4, 63, + 75, 183, 62, 243, 11, 4, 105, 63, 236, 138, 215, 221, 40, 192, 106, 215, + 221, 40, 192, 21, 237, 6, 40, 230, 205, 192, 106, 237, 6, 40, 219, 178, + 192, 21, 237, 6, 40, 219, 178, 192, 106, 237, 6, 40, 230, 205, 192, 21, + 63, 232, 217, 62, 232, 217, 230, 62, 23, 209, 180, 251, 127, 238, 214, + 200, 130, 201, 112, 79, 252, 8, 205, 98, 251, 191, 232, 186, 231, 162, + 201, 112, 79, 229, 191, 250, 172, 113, 232, 202, 211, 10, 63, 201, 102, + 115, 219, 107, 239, 19, 183, 115, 219, 107, 239, 19, 219, 224, 193, 155, + 56, 137, 195, 12, 56, 235, 128, 233, 42, 56, 235, 128, 217, 97, 56, 223, + 105, 233, 42, 23, 217, 97, 56, 217, 97, 23, 233, 42, 56, 217, 97, 4, 201, + 28, 56, 217, 97, 4, 201, 28, 23, 217, 97, 23, 233, 42, 56, 81, 217, 97, + 4, 201, 28, 56, 228, 241, 217, 97, 4, 201, 28, 56, 216, 213, 63, 243, 10, + 216, 213, 62, 243, 10, 216, 213, 2, 63, 243, 10, 217, 48, 113, 236, 198, + 113, 196, 84, 210, 103, 113, 242, 89, 232, 74, 196, 53, 214, 83, 247, 7, + 210, 185, 222, 173, 195, 80, 243, 75, 62, 215, 206, 219, 126, 203, 176, + 204, 22, 208, 4, 203, 255, 202, 36, 249, 111, 249, 73, 112, 221, 222, 63, + 235, 108, 217, 90, 63, 235, 108, 221, 138, 62, 235, 108, 217, 90, 62, + 235, 108, 221, 138, 202, 49, 193, 51, 202, 52, 200, 199, 248, 242, 242, + 210, 207, 149, 62, 202, 48, 198, 210, 242, 211, 23, 207, 149, 153, 63, + 203, 49, 209, 175, 153, 62, 203, 49, 209, 175, 63, 237, 33, 223, 163, + 201, 190, 238, 210, 220, 21, 236, 229, 247, 102, 211, 65, 209, 180, 247, + 103, 202, 85, 229, 201, 4, 63, 238, 217, 47, 238, 210, 220, 21, 246, 253, + 213, 44, 234, 72, 251, 157, 211, 96, 45, 193, 129, 198, 19, 62, 197, 10, + 45, 193, 129, 198, 19, 63, 197, 10, 45, 193, 129, 198, 19, 62, 45, 220, + 22, 216, 179, 63, 45, 220, 22, 216, 179, 235, 103, 202, 76, 56, 88, 63, + 235, 122, 197, 241, 45, 242, 219, 234, 72, 112, 205, 154, 233, 83, 237, + 39, 223, 163, 63, 243, 11, 223, 163, 62, 201, 190, 62, 197, 203, 207, 29, + 45, 234, 71, 207, 29, 45, 234, 70, 250, 187, 16, 40, 196, 57, 88, 243, + 11, 4, 201, 28, 23, 105, 185, 58, 210, 23, 206, 205, 223, 107, 210, 23, + 219, 221, 223, 107, 210, 23, 223, 93, 210, 23, 62, 238, 218, 211, 105, + 203, 78, 203, 66, 203, 12, 243, 40, 247, 80, 229, 118, 202, 137, 231, + 163, 193, 51, 228, 153, 231, 163, 4, 230, 30, 217, 72, 16, 40, 219, 131, + 215, 184, 196, 118, 211, 105, 230, 188, 232, 129, 232, 218, 223, 163, + 229, 5, 233, 32, 205, 178, 51, 232, 128, 239, 0, 202, 108, 228, 27, 202, + 112, 209, 251, 4, 249, 111, 199, 87, 223, 19, 249, 93, 113, 229, 229, + 230, 207, 113, 232, 83, 208, 153, 238, 182, 211, 105, 62, 201, 190, 63, + 232, 218, 4, 228, 241, 82, 62, 201, 29, 62, 205, 188, 205, 84, 116, 248, + 134, 205, 84, 62, 205, 84, 110, 248, 134, 205, 84, 63, 205, 84, 63, 88, + 243, 126, 77, 199, 107, 219, 40, 56, 199, 182, 235, 102, 251, 223, 234, + 67, 207, 147, 232, 231, 207, 147, 230, 53, 195, 67, 230, 53, 193, 3, 230, + 53, 110, 50, 210, 33, 210, 33, 116, 50, 210, 33, 63, 213, 208, 62, 213, + 208, 243, 126, 77, 88, 243, 126, 77, 215, 127, 192, 235, 88, 215, 127, + 192, 235, 249, 107, 192, 235, 88, 249, 107, 192, 235, 211, 10, 35, 238, + 217, 88, 35, 238, 217, 211, 77, 247, 22, 238, 217, 88, 211, 77, 247, 22, + 238, 217, 8, 238, 217, 203, 151, 63, 8, 238, 217, 211, 10, 8, 238, 217, + 217, 93, 238, 217, 201, 103, 79, 237, 208, 232, 128, 199, 127, 250, 193, + 232, 128, 249, 108, 250, 193, 88, 232, 128, 249, 108, 250, 193, 232, 128, + 242, 205, 250, 193, 62, 232, 128, 209, 60, 201, 102, 63, 232, 128, 209, + 60, 201, 102, 201, 240, 201, 38, 211, 10, 63, 201, 102, 47, 63, 201, 102, + 211, 77, 247, 22, 62, 201, 102, 62, 247, 22, 63, 201, 102, 211, 10, 62, + 201, 102, 88, 211, 10, 62, 201, 102, 209, 130, 201, 102, 203, 151, 63, + 201, 102, 88, 250, 193, 211, 77, 247, 22, 250, 193, 234, 164, 201, 206, + 250, 193, 234, 164, 209, 60, 62, 201, 102, 234, 164, 209, 60, 209, 130, + 201, 102, 202, 136, 209, 60, 62, 201, 102, 234, 164, 209, 60, 207, 90, + 62, 201, 102, 88, 234, 164, 209, 60, 207, 90, 62, 201, 102, 197, 38, 209, + 60, 62, 201, 102, 202, 131, 209, 60, 250, 193, 199, 127, 250, 193, 211, + 77, 247, 22, 199, 127, 250, 193, 88, 199, 127, 250, 193, 202, 136, 209, + 239, 62, 23, 63, 232, 189, 62, 232, 189, 63, 232, 189, 234, 164, 209, + 239, 211, 10, 62, 232, 189, 47, 211, 77, 247, 22, 234, 164, 209, 60, 201, + 102, 88, 199, 127, 209, 130, 250, 193, 202, 50, 198, 172, 197, 234, 202, + 50, 88, 243, 101, 202, 50, 201, 242, 88, 201, 242, 249, 108, 250, 193, + 234, 164, 199, 127, 208, 189, 250, 193, 88, 234, 164, 199, 127, 208, 189, + 250, 193, 238, 218, 77, 203, 151, 63, 243, 10, 214, 106, 112, 238, 218, + 77, 110, 50, 235, 98, 63, 201, 190, 116, 50, 235, 98, 63, 201, 190, 110, + 50, 203, 151, 63, 201, 190, 116, 50, 203, 151, 63, 201, 190, 62, 208, 13, + 87, 211, 42, 63, 208, 13, 87, 211, 42, 63, 233, 216, 87, 211, 42, 62, + 237, 33, 216, 35, 63, 192, 235, 88, 233, 216, 87, 113, 156, 81, 164, 216, + 213, 81, 164, 88, 81, 164, 88, 202, 170, 153, 242, 75, 207, 252, 87, 211, + 42, 88, 202, 170, 242, 75, 207, 252, 87, 211, 42, 88, 55, 153, 242, 75, + 207, 252, 87, 211, 42, 88, 55, 242, 75, 207, 252, 87, 211, 42, 88, 130, + 202, 170, 242, 75, 207, 252, 87, 211, 42, 88, 130, 55, 242, 75, 207, 252, + 87, 211, 42, 238, 163, 201, 81, 210, 128, 3, 211, 42, 88, 233, 216, 87, + 211, 42, 88, 229, 224, 233, 216, 87, 211, 42, 88, 62, 229, 223, 206, 122, + 88, 62, 229, 224, 247, 248, 232, 190, 229, 223, 206, 122, 232, 190, 229, + 224, 247, 248, 216, 213, 45, 210, 114, 211, 42, 216, 213, 50, 210, 114, + 211, 42, 216, 213, 232, 203, 45, 210, 114, 211, 42, 216, 213, 232, 203, + 50, 210, 114, 211, 42, 216, 213, 219, 219, 251, 116, 248, 54, 211, 42, + 216, 213, 206, 203, 251, 116, 248, 54, 211, 42, 88, 219, 219, 251, 116, + 207, 252, 87, 211, 42, 88, 206, 203, 251, 116, 207, 252, 87, 211, 42, 88, + 219, 219, 251, 116, 248, 54, 211, 42, 88, 206, 203, 251, 116, 248, 54, + 211, 42, 156, 45, 198, 42, 203, 103, 248, 54, 211, 42, 156, 50, 198, 42, + 203, 103, 248, 54, 211, 42, 216, 213, 45, 238, 171, 248, 54, 211, 42, + 216, 213, 50, 238, 171, 248, 54, 211, 42, 236, 241, 214, 106, 47, 17, + 107, 236, 241, 214, 106, 47, 17, 109, 236, 241, 214, 106, 47, 17, 138, + 236, 241, 214, 106, 47, 17, 134, 236, 241, 214, 106, 47, 17, 149, 236, + 241, 214, 106, 47, 17, 169, 236, 241, 214, 106, 47, 17, 175, 236, 241, + 214, 106, 47, 17, 171, 236, 241, 214, 106, 47, 17, 178, 236, 241, 214, + 106, 47, 31, 199, 95, 236, 241, 47, 49, 17, 107, 236, 241, 47, 49, 17, + 109, 236, 241, 47, 49, 17, 138, 236, 241, 47, 49, 17, 134, 236, 241, 47, + 49, 17, 149, 236, 241, 47, 49, 17, 169, 236, 241, 47, 49, 17, 175, 236, + 241, 47, 49, 17, 171, 236, 241, 47, 49, 17, 178, 236, 241, 47, 49, 31, + 199, 95, 236, 241, 214, 106, 47, 49, 17, 107, 236, 241, 214, 106, 47, 49, + 17, 109, 236, 241, 214, 106, 47, 49, 17, 138, 236, 241, 214, 106, 47, 49, + 17, 134, 236, 241, 214, 106, 47, 49, 17, 149, 236, 241, 214, 106, 47, 49, + 17, 169, 236, 241, 214, 106, 47, 49, 17, 175, 236, 241, 214, 106, 47, 49, + 17, 171, 236, 241, 214, 106, 47, 49, 17, 178, 236, 241, 214, 106, 47, 49, + 31, 199, 95, 88, 193, 77, 96, 57, 88, 108, 56, 88, 216, 35, 56, 88, 236, + 200, 56, 88, 202, 2, 234, 204, 57, 88, 96, 57, 88, 186, 234, 204, 57, + 235, 113, 209, 62, 96, 57, 88, 206, 114, 96, 57, 197, 240, 96, 57, 88, + 197, 240, 96, 57, 237, 214, 197, 240, 96, 57, 88, 237, 214, 197, 240, 96, + 57, 62, 96, 57, 198, 225, 198, 52, 96, 250, 235, 198, 225, 248, 75, 96, + 250, 235, 62, 96, 250, 235, 88, 62, 238, 163, 235, 119, 23, 96, 57, 88, + 62, 238, 163, 196, 66, 23, 96, 57, 201, 187, 62, 96, 57, 88, 239, 56, 62, + 96, 57, 206, 202, 63, 96, 57, 219, 218, 63, 96, 57, 249, 145, 203, 151, + 63, 96, 57, 232, 95, 203, 151, 63, 96, 57, 88, 110, 206, 201, 63, 96, 57, + 88, 116, 206, 201, 63, 96, 57, 213, 8, 110, 206, 201, 63, 96, 57, 238, + 171, 219, 4, 213, 8, 116, 206, 201, 63, 96, 57, 47, 88, 63, 96, 57, 193, + 88, 96, 57, 248, 138, 202, 2, 234, 204, 57, 248, 138, 96, 57, 248, 138, + 186, 234, 204, 57, 88, 248, 138, 202, 2, 234, 204, 57, 88, 248, 138, 96, + 57, 88, 248, 138, 186, 234, 204, 57, 199, 129, 96, 57, 88, 199, 128, 96, + 57, 193, 115, 96, 57, 88, 193, 115, 96, 57, 211, 71, 96, 57, 55, 238, + 171, 219, 4, 115, 236, 251, 251, 115, 63, 197, 242, 239, 33, 2, 63, 197, + 241, 209, 254, 211, 77, 200, 228, 211, 77, 200, 180, 45, 206, 7, 249, + 131, 237, 112, 50, 206, 7, 249, 131, 237, 112, 211, 57, 4, 75, 223, 117, + 207, 19, 202, 24, 208, 230, 200, 228, 200, 181, 208, 230, 202, 23, 81, + 249, 88, 4, 228, 241, 106, 13, 206, 180, 237, 38, 179, 236, 199, 13, 233, + 83, 237, 38, 112, 219, 29, 251, 125, 112, 219, 29, 211, 56, 63, 237, 33, + 4, 247, 20, 236, 140, 23, 4, 236, 140, 234, 132, 79, 211, 69, 196, 65, + 110, 50, 239, 2, 4, 236, 140, 116, 45, 239, 2, 4, 236, 140, 45, 211, 12, + 222, 199, 50, 211, 12, 222, 199, 232, 80, 211, 12, 222, 199, 220, 13, + 133, 199, 228, 220, 13, 144, 199, 228, 45, 23, 50, 55, 197, 57, 45, 23, + 50, 199, 228, 45, 215, 131, 179, 50, 199, 228, 179, 45, 199, 228, 133, + 199, 229, 4, 243, 11, 58, 218, 233, 236, 206, 247, 205, 228, 241, 206, + 52, 63, 239, 55, 237, 32, 63, 239, 55, 237, 33, 4, 118, 198, 182, 63, + 239, 55, 237, 33, 4, 96, 198, 182, 63, 51, 4, 118, 198, 182, 63, 51, 4, + 96, 198, 182, 13, 45, 63, 51, 248, 53, 13, 50, 63, 51, 248, 53, 13, 45, + 251, 116, 248, 53, 13, 50, 251, 116, 248, 53, 13, 45, 55, 251, 116, 248, + 53, 13, 50, 55, 251, 116, 248, 53, 13, 45, 63, 198, 42, 203, 103, 248, + 53, 13, 50, 63, 198, 42, 203, 103, 248, 53, 13, 45, 232, 203, 210, 113, + 13, 50, 232, 203, 210, 113, 196, 66, 208, 26, 57, 235, 119, 208, 26, 57, + 251, 85, 231, 202, 243, 11, 57, 242, 221, 231, 202, 243, 11, 57, 50, 64, + 4, 47, 209, 81, 179, 118, 57, 179, 96, 57, 179, 45, 50, 57, 179, 118, 55, + 57, 179, 96, 55, 57, 179, 45, 50, 55, 57, 179, 118, 64, 232, 98, 164, + 179, 96, 64, 232, 98, 164, 179, 118, 55, 64, 232, 98, 164, 179, 96, 55, + 64, 232, 98, 164, 179, 96, 201, 183, 57, 69, 70, 248, 132, 69, 70, 236, + 137, 69, 70, 236, 9, 69, 70, 236, 136, 69, 70, 235, 201, 69, 70, 236, 72, + 69, 70, 236, 8, 69, 70, 236, 135, 69, 70, 235, 169, 69, 70, 236, 40, 69, + 70, 235, 232, 69, 70, 236, 103, 69, 70, 235, 200, 69, 70, 236, 71, 69, + 70, 236, 7, 69, 70, 236, 134, 69, 70, 235, 153, 69, 70, 236, 24, 69, 70, + 235, 216, 69, 70, 236, 87, 69, 70, 235, 184, 69, 70, 236, 55, 69, 70, + 235, 247, 69, 70, 236, 118, 69, 70, 235, 168, 69, 70, 236, 39, 69, 70, + 235, 231, 69, 70, 236, 102, 69, 70, 235, 199, 69, 70, 236, 70, 69, 70, + 236, 6, 69, 70, 236, 133, 69, 70, 235, 145, 69, 70, 236, 16, 69, 70, 235, + 208, 69, 70, 236, 79, 69, 70, 235, 176, 69, 70, 236, 47, 69, 70, 235, + 239, 69, 70, 236, 110, 69, 70, 235, 160, 69, 70, 236, 31, 69, 70, 235, + 223, 69, 70, 236, 94, 69, 70, 235, 191, 69, 70, 236, 62, 69, 70, 235, + 254, 69, 70, 236, 125, 69, 70, 235, 152, 69, 70, 236, 23, 69, 70, 235, + 215, 69, 70, 236, 86, 69, 70, 235, 183, 69, 70, 236, 54, 69, 70, 235, + 246, 69, 70, 236, 117, 69, 70, 235, 167, 69, 70, 236, 38, 69, 70, 235, + 230, 69, 70, 236, 101, 69, 70, 235, 198, 69, 70, 236, 69, 69, 70, 236, 5, + 69, 70, 236, 132, 69, 70, 235, 141, 69, 70, 236, 12, 69, 70, 235, 204, + 69, 70, 236, 75, 69, 70, 235, 172, 69, 70, 236, 43, 69, 70, 235, 235, 69, + 70, 236, 106, 69, 70, 235, 156, 69, 70, 236, 27, 69, 70, 235, 219, 69, + 70, 236, 90, 69, 70, 235, 187, 69, 70, 236, 58, 69, 70, 235, 250, 69, 70, + 236, 121, 69, 70, 235, 148, 69, 70, 236, 19, 69, 70, 235, 211, 69, 70, + 236, 82, 69, 70, 235, 179, 69, 70, 236, 50, 69, 70, 235, 242, 69, 70, + 236, 113, 69, 70, 235, 163, 69, 70, 236, 34, 69, 70, 235, 226, 69, 70, + 236, 97, 69, 70, 235, 194, 69, 70, 236, 65, 69, 70, 236, 1, 69, 70, 236, + 128, 69, 70, 235, 144, 69, 70, 236, 15, 69, 70, 235, 207, 69, 70, 236, + 78, 69, 70, 235, 175, 69, 70, 236, 46, 69, 70, 235, 238, 69, 70, 236, + 109, 69, 70, 235, 159, 69, 70, 236, 30, 69, 70, 235, 222, 69, 70, 236, + 93, 69, 70, 235, 190, 69, 70, 236, 61, 69, 70, 235, 253, 69, 70, 236, + 124, 69, 70, 235, 151, 69, 70, 236, 22, 69, 70, 235, 214, 69, 70, 236, + 85, 69, 70, 235, 182, 69, 70, 236, 53, 69, 70, 235, 245, 69, 70, 236, + 116, 69, 70, 235, 166, 69, 70, 236, 37, 69, 70, 235, 229, 69, 70, 236, + 100, 69, 70, 235, 197, 69, 70, 236, 68, 69, 70, 236, 4, 69, 70, 236, 131, + 69, 70, 235, 139, 69, 70, 236, 10, 69, 70, 235, 202, 69, 70, 236, 73, 69, + 70, 235, 170, 69, 70, 236, 41, 69, 70, 235, 233, 69, 70, 236, 104, 69, + 70, 235, 154, 69, 70, 236, 25, 69, 70, 235, 217, 69, 70, 236, 88, 69, 70, + 235, 185, 69, 70, 236, 56, 69, 70, 235, 248, 69, 70, 236, 119, 69, 70, + 235, 146, 69, 70, 236, 17, 69, 70, 235, 209, 69, 70, 236, 80, 69, 70, + 235, 177, 69, 70, 236, 48, 69, 70, 235, 240, 69, 70, 236, 111, 69, 70, + 235, 161, 69, 70, 236, 32, 69, 70, 235, 224, 69, 70, 236, 95, 69, 70, + 235, 192, 69, 70, 236, 63, 69, 70, 235, 255, 69, 70, 236, 126, 69, 70, + 235, 142, 69, 70, 236, 13, 69, 70, 235, 205, 69, 70, 236, 76, 69, 70, + 235, 173, 69, 70, 236, 44, 69, 70, 235, 236, 69, 70, 236, 107, 69, 70, + 235, 157, 69, 70, 236, 28, 69, 70, 235, 220, 69, 70, 236, 91, 69, 70, + 235, 188, 69, 70, 236, 59, 69, 70, 235, 251, 69, 70, 236, 122, 69, 70, + 235, 149, 69, 70, 236, 20, 69, 70, 235, 212, 69, 70, 236, 83, 69, 70, + 235, 180, 69, 70, 236, 51, 69, 70, 235, 243, 69, 70, 236, 114, 69, 70, + 235, 164, 69, 70, 236, 35, 69, 70, 235, 227, 69, 70, 236, 98, 69, 70, + 235, 195, 69, 70, 236, 66, 69, 70, 236, 2, 69, 70, 236, 129, 69, 70, 235, + 140, 69, 70, 236, 11, 69, 70, 235, 203, 69, 70, 236, 74, 69, 70, 235, + 171, 69, 70, 236, 42, 69, 70, 235, 234, 69, 70, 236, 105, 69, 70, 235, + 155, 69, 70, 236, 26, 69, 70, 235, 218, 69, 70, 236, 89, 69, 70, 235, + 186, 69, 70, 236, 57, 69, 70, 235, 249, 69, 70, 236, 120, 69, 70, 235, + 147, 69, 70, 236, 18, 69, 70, 235, 210, 69, 70, 236, 81, 69, 70, 235, + 178, 69, 70, 236, 49, 69, 70, 235, 241, 69, 70, 236, 112, 69, 70, 235, + 162, 69, 70, 236, 33, 69, 70, 235, 225, 69, 70, 236, 96, 69, 70, 235, + 193, 69, 70, 236, 64, 69, 70, 236, 0, 69, 70, 236, 127, 69, 70, 235, 143, + 69, 70, 236, 14, 69, 70, 235, 206, 69, 70, 236, 77, 69, 70, 235, 174, 69, + 70, 236, 45, 69, 70, 235, 237, 69, 70, 236, 108, 69, 70, 235, 158, 69, + 70, 236, 29, 69, 70, 235, 221, 69, 70, 236, 92, 69, 70, 235, 189, 69, 70, + 236, 60, 69, 70, 235, 252, 69, 70, 236, 123, 69, 70, 235, 150, 69, 70, + 236, 21, 69, 70, 235, 213, 69, 70, 236, 84, 69, 70, 235, 181, 69, 70, + 236, 52, 69, 70, 235, 244, 69, 70, 236, 115, 69, 70, 235, 165, 69, 70, + 236, 36, 69, 70, 235, 228, 69, 70, 236, 99, 69, 70, 235, 196, 69, 70, + 236, 67, 69, 70, 236, 3, 69, 70, 236, 130, 96, 197, 13, 64, 4, 81, 106, + 96, 197, 13, 64, 4, 55, 81, 106, 118, 55, 64, 4, 81, 106, 96, 55, 64, 4, + 81, 106, 45, 50, 55, 64, 4, 81, 106, 96, 197, 13, 64, 232, 98, 164, 118, + 55, 64, 232, 98, 164, 96, 55, 64, 232, 98, 164, 235, 119, 64, 4, 228, + 241, 106, 196, 66, 64, 4, 228, 241, 106, 196, 66, 197, 225, 57, 235, 119, + 197, 225, 57, 118, 55, 237, 216, 57, 96, 55, 237, 216, 57, 118, 197, 225, + 237, 216, 57, 96, 197, 225, 237, 216, 57, 96, 197, 13, 197, 225, 237, + 216, 57, 96, 64, 4, 235, 138, 201, 80, 196, 66, 64, 119, 164, 235, 119, + 64, 119, 164, 96, 64, 4, 199, 216, 4, 81, 106, 96, 64, 4, 199, 216, 4, + 55, 81, 106, 96, 197, 13, 64, 4, 199, 215, 96, 197, 13, 64, 4, 199, 216, + 4, 81, 106, 96, 197, 13, 64, 4, 199, 216, 4, 55, 81, 106, 118, 250, 237, + 96, 250, 237, 118, 55, 250, 237, 96, 55, 250, 237, 118, 64, 119, 62, 237, + 32, 96, 64, 119, 62, 237, 32, 118, 64, 232, 98, 249, 88, 119, 62, 237, + 32, 96, 64, 232, 98, 249, 88, 119, 62, 237, 32, 186, 193, 105, 23, 202, + 2, 234, 204, 57, 186, 234, 204, 23, 202, 2, 193, 105, 57, 186, 193, 105, + 64, 4, 102, 186, 234, 204, 64, 4, 102, 202, 2, 234, 204, 64, 4, 102, 202, + 2, 193, 105, 64, 4, 102, 186, 193, 105, 64, 23, 186, 234, 204, 57, 186, + 234, 204, 64, 23, 202, 2, 234, 204, 57, 202, 2, 234, 204, 64, 23, 202, 2, + 193, 105, 57, 202, 2, 193, 105, 64, 23, 186, 193, 105, 57, 206, 180, 237, + 39, 238, 210, 233, 83, 237, 38, 233, 83, 237, 39, 238, 210, 206, 180, + 237, 38, 202, 2, 234, 204, 64, 238, 210, 186, 234, 204, 57, 186, 234, + 204, 64, 238, 210, 202, 2, 234, 204, 57, 233, 83, 237, 39, 238, 210, 186, + 234, 204, 57, 206, 180, 237, 39, 238, 210, 202, 2, 234, 204, 57, 186, + 234, 204, 64, 238, 210, 186, 193, 105, 57, 186, 193, 105, 64, 238, 210, + 186, 234, 204, 57, 193, 139, 64, 209, 58, 236, 231, 183, 64, 209, 58, 96, + 199, 25, 238, 161, 196, 65, 64, 209, 58, 96, 199, 25, 238, 161, 235, 118, + 64, 209, 58, 235, 119, 199, 25, 238, 161, 219, 214, 64, 209, 58, 235, + 119, 199, 25, 238, 161, 206, 197, 206, 200, 251, 17, 242, 221, 57, 219, + 217, 251, 17, 251, 85, 57, 198, 54, 251, 17, 251, 85, 57, 248, 77, 251, + 17, 251, 85, 57, 198, 54, 251, 17, 242, 221, 64, 4, 216, 34, 198, 54, + 251, 17, 251, 85, 64, 4, 209, 81, 110, 50, 204, 27, 242, 221, 57, 110, + 45, 204, 27, 251, 85, 57, 251, 85, 242, 219, 243, 11, 57, 242, 221, 242, + 219, 243, 11, 57, 96, 64, 93, 203, 40, 118, 57, 118, 64, 93, 203, 40, 96, + 57, 203, 40, 96, 64, 93, 118, 57, 96, 64, 4, 108, 60, 118, 64, 4, 108, + 60, 96, 64, 198, 216, 192, 235, 45, 50, 64, 198, 216, 2, 243, 10, 196, + 66, 197, 13, 64, 232, 98, 2, 243, 10, 45, 181, 133, 50, 181, 144, 230, + 12, 45, 181, 144, 50, 181, 133, 230, 12, 133, 181, 50, 144, 181, 45, 230, + 12, 133, 181, 45, 144, 181, 50, 230, 12, 45, 181, 133, 50, 181, 133, 230, + 12, 133, 181, 50, 144, 181, 50, 230, 12, 45, 181, 144, 50, 181, 144, 230, + 12, 133, 181, 45, 144, 181, 45, 230, 12, 118, 230, 13, 4, 181, 133, 119, + 164, 96, 230, 13, 4, 181, 133, 119, 164, 196, 66, 230, 13, 4, 181, 50, + 119, 164, 235, 119, 230, 13, 4, 181, 50, 119, 164, 118, 230, 13, 4, 181, + 144, 119, 164, 96, 230, 13, 4, 181, 144, 119, 164, 196, 66, 230, 13, 4, + 181, 45, 119, 164, 235, 119, 230, 13, 4, 181, 45, 119, 164, 118, 230, 13, + 4, 181, 133, 232, 98, 164, 96, 230, 13, 4, 181, 133, 232, 98, 164, 196, + 66, 230, 13, 4, 181, 50, 232, 98, 164, 235, 119, 230, 13, 4, 181, 50, + 232, 98, 164, 118, 230, 13, 4, 181, 144, 232, 98, 164, 96, 230, 13, 4, + 181, 144, 232, 98, 164, 196, 66, 230, 13, 4, 181, 45, 232, 98, 164, 235, + 119, 230, 13, 4, 181, 45, 232, 98, 164, 118, 230, 13, 4, 181, 133, 93, + 118, 230, 13, 4, 181, 235, 123, 196, 66, 230, 13, 4, 181, 45, 248, 216, + 196, 66, 230, 13, 4, 181, 183, 96, 230, 13, 4, 181, 133, 93, 96, 230, 13, + 4, 181, 235, 123, 235, 119, 230, 13, 4, 181, 45, 248, 216, 235, 119, 230, + 13, 4, 181, 183, 118, 230, 13, 4, 181, 133, 93, 96, 230, 13, 4, 181, 196, + 77, 118, 230, 13, 4, 181, 144, 93, 96, 230, 13, 4, 181, 235, 123, 96, + 230, 13, 4, 181, 133, 93, 118, 230, 13, 4, 181, 196, 77, 96, 230, 13, 4, + 181, 144, 93, 118, 230, 13, 4, 181, 235, 123, 118, 230, 13, 4, 181, 133, + 93, 179, 237, 215, 118, 230, 13, 4, 181, 144, 248, 233, 179, 237, 215, + 96, 230, 13, 4, 181, 133, 93, 179, 237, 215, 96, 230, 13, 4, 181, 144, + 248, 233, 179, 237, 215, 196, 66, 230, 13, 4, 181, 45, 248, 216, 235, + 119, 230, 13, 4, 181, 183, 235, 119, 230, 13, 4, 181, 45, 248, 216, 196, + 66, 230, 13, 4, 181, 183, 50, 55, 64, 4, 206, 113, 229, 235, 234, 43, 3, + 93, 96, 57, 198, 153, 211, 67, 93, 96, 57, 118, 64, 93, 198, 153, 211, + 66, 96, 64, 93, 198, 153, 211, 66, 96, 64, 93, 251, 165, 234, 45, 159, + 219, 180, 93, 118, 57, 118, 64, 198, 216, 219, 179, 230, 204, 93, 96, 57, + 200, 229, 93, 96, 57, 118, 64, 198, 216, 200, 228, 200, 181, 93, 118, 57, + 45, 232, 237, 199, 215, 50, 232, 237, 199, 215, 133, 232, 237, 199, 215, + 144, 232, 237, 199, 215, 197, 225, 81, 249, 88, 237, 112, 191, 167, 213, + 10, 201, 201, 191, 167, 213, 10, 196, 255, 242, 83, 45, 63, 238, 171, + 248, 53, 50, 63, 238, 171, 248, 53, 45, 63, 210, 113, 50, 63, 210, 113, + 191, 167, 213, 10, 45, 223, 178, 248, 53, 191, 167, 213, 10, 50, 223, + 178, 248, 53, 191, 167, 213, 10, 45, 248, 166, 248, 53, 191, 167, 213, + 10, 50, 248, 166, 248, 53, 45, 51, 248, 54, 4, 196, 103, 50, 51, 248, 54, + 4, 196, 103, 45, 51, 248, 54, 4, 198, 183, 223, 163, 198, 54, 239, 1, 50, + 51, 248, 54, 4, 198, 183, 223, 163, 248, 77, 239, 1, 45, 51, 248, 54, 4, + 198, 183, 223, 163, 248, 77, 239, 1, 50, 51, 248, 54, 4, 198, 183, 223, + 163, 198, 54, 239, 1, 45, 251, 116, 248, 54, 4, 236, 140, 50, 251, 116, + 248, 54, 4, 236, 140, 45, 251, 17, 219, 180, 248, 53, 50, 251, 17, 230, + 204, 248, 53, 55, 45, 251, 17, 230, 204, 248, 53, 55, 50, 251, 17, 219, + 180, 248, 53, 45, 62, 198, 42, 203, 103, 248, 53, 50, 62, 198, 42, 203, + 103, 248, 53, 235, 138, 233, 39, 81, 191, 21, 219, 112, 216, 226, 251, + 116, 211, 69, 219, 224, 50, 251, 116, 195, 168, 4, 201, 190, 216, 226, + 50, 251, 116, 4, 236, 140, 251, 116, 4, 206, 9, 223, 117, 252, 47, 251, + 115, 201, 225, 251, 116, 211, 69, 219, 224, 201, 225, 251, 116, 211, 69, + 196, 77, 153, 251, 115, 207, 18, 251, 115, 251, 116, 4, 196, 103, 207, + 18, 251, 116, 4, 196, 103, 211, 172, 251, 116, 211, 69, 196, 77, 211, + 172, 251, 116, 211, 69, 235, 123, 216, 226, 251, 116, 4, 211, 77, 250, + 251, 234, 91, 223, 163, 64, 209, 58, 133, 23, 183, 216, 226, 251, 116, 4, + 211, 77, 250, 251, 234, 91, 223, 163, 64, 209, 58, 133, 23, 219, 224, + 216, 226, 251, 116, 4, 211, 77, 250, 251, 234, 91, 223, 163, 64, 209, 58, + 144, 23, 183, 216, 226, 251, 116, 4, 211, 77, 250, 251, 234, 91, 223, + 163, 64, 209, 58, 144, 23, 219, 224, 216, 226, 251, 116, 4, 211, 77, 250, + 251, 234, 91, 223, 163, 64, 209, 58, 50, 23, 196, 77, 216, 226, 251, 116, + 4, 211, 77, 250, 251, 234, 91, 223, 163, 64, 209, 58, 45, 23, 196, 77, + 216, 226, 251, 116, 4, 211, 77, 250, 251, 234, 91, 223, 163, 64, 209, 58, + 50, 23, 235, 123, 216, 226, 251, 116, 4, 211, 77, 250, 251, 234, 91, 223, + 163, 64, 209, 58, 45, 23, 235, 123, 207, 18, 234, 105, 203, 252, 234, + 105, 203, 253, 4, 211, 6, 234, 105, 203, 253, 4, 2, 243, 11, 58, 234, + 105, 203, 253, 4, 50, 64, 58, 234, 105, 203, 253, 4, 45, 64, 58, 243, 11, + 4, 228, 241, 164, 47, 81, 164, 47, 210, 118, 47, 207, 19, 202, 23, 47, + 209, 254, 243, 11, 236, 206, 247, 205, 228, 241, 249, 88, 23, 198, 54, + 132, 236, 206, 247, 205, 81, 164, 243, 11, 4, 200, 183, 192, 235, 47, + 251, 83, 236, 200, 56, 133, 64, 198, 216, 243, 10, 47, 63, 247, 248, 47, + 247, 248, 47, 219, 179, 47, 230, 203, 243, 11, 4, 2, 243, 11, 119, 199, + 34, 183, 243, 11, 4, 105, 228, 241, 201, 16, 119, 199, 34, 183, 112, 206, + 180, 237, 39, 202, 97, 112, 233, 83, 237, 39, 202, 97, 112, 250, 193, + 112, 2, 243, 10, 112, 201, 190, 105, 222, 198, 201, 188, 197, 242, 4, 75, + 58, 197, 242, 4, 196, 103, 206, 9, 223, 163, 197, 241, 197, 242, 4, 204, + 4, 250, 183, 248, 76, 50, 197, 242, 93, 45, 197, 241, 45, 197, 242, 248, + 216, 81, 164, 81, 249, 88, 248, 216, 50, 197, 241, 248, 64, 4, 45, 132, + 248, 139, 248, 64, 4, 50, 132, 248, 139, 62, 248, 63, 25, 4, 45, 132, + 248, 139, 25, 4, 50, 132, 248, 139, 63, 228, 174, 62, 228, 174, 45, 193, + 72, 233, 39, 50, 193, 72, 233, 39, 45, 55, 193, 72, 233, 39, 50, 55, 193, + 72, 233, 39, 223, 155, 223, 139, 198, 179, 139, 223, 139, 223, 140, 214, + 108, 4, 81, 164, 235, 132, 215, 131, 51, 4, 239, 25, 211, 11, 223, 152, + 250, 219, 202, 254, 208, 200, 234, 43, 3, 23, 202, 99, 210, 118, 234, 43, + 3, 23, 202, 99, 210, 119, 4, 198, 153, 58, 228, 17, 119, 23, 202, 99, + 210, 118, 231, 14, 201, 101, 199, 22, 235, 122, 197, 242, 4, 45, 132, + 248, 139, 235, 122, 197, 242, 4, 50, 132, 248, 139, 62, 237, 33, 4, 144, + 57, 62, 218, 232, 63, 243, 11, 4, 144, 57, 62, 243, 11, 4, 144, 57, 234, + 25, 63, 201, 190, 234, 25, 62, 201, 190, 234, 25, 63, 237, 32, 234, 25, + 62, 237, 32, 234, 25, 63, 243, 10, 234, 25, 62, 243, 10, 206, 51, 207, + 19, 202, 24, 211, 66, 202, 24, 4, 211, 6, 207, 19, 202, 24, 4, 228, 241, + 106, 248, 175, 202, 23, 248, 175, 207, 19, 202, 23, 55, 209, 81, 197, + 225, 209, 81, 219, 219, 238, 163, 251, 116, 248, 53, 206, 203, 238, 163, + 251, 116, 248, 53, 198, 137, 216, 32, 215, 60, 47, 75, 211, 66, 215, 60, + 47, 108, 211, 66, 215, 60, 47, 25, 211, 66, 215, 60, 196, 93, 211, 67, 4, + 236, 140, 215, 60, 196, 93, 211, 67, 4, 209, 81, 215, 60, 51, 223, 100, + 211, 66, 215, 60, 51, 196, 93, 211, 66, 105, 219, 29, 23, 211, 66, 105, + 219, 29, 211, 57, 211, 66, 215, 60, 25, 211, 66, 215, 236, 105, 200, 204, + 200, 202, 4, 223, 113, 208, 26, 223, 114, 211, 66, 232, 246, 210, 107, + 223, 113, 223, 114, 4, 55, 106, 223, 114, 250, 143, 4, 202, 97, 243, 3, + 232, 76, 251, 85, 223, 111, 219, 113, 223, 112, 4, 207, 91, 210, 86, 250, + 245, 209, 52, 219, 113, 223, 112, 4, 204, 27, 210, 86, 250, 245, 209, 52, + 219, 113, 223, 112, 213, 12, 223, 157, 199, 34, 209, 52, 223, 114, 250, + 245, 42, 209, 62, 211, 66, 208, 19, 223, 114, 211, 66, 223, 114, 4, 118, + 64, 4, 102, 223, 114, 4, 25, 56, 223, 114, 4, 223, 99, 223, 114, 4, 196, + 92, 223, 114, 4, 211, 6, 223, 114, 4, 196, 103, 222, 199, 220, 13, 45, + 197, 242, 211, 66, 191, 167, 213, 10, 205, 92, 239, 62, 191, 167, 213, + 10, 205, 92, 209, 126, 191, 167, 213, 10, 205, 92, 208, 195, 108, 3, 4, + 2, 243, 11, 58, 108, 3, 4, 243, 2, 252, 61, 58, 108, 3, 4, 198, 153, 58, + 108, 3, 4, 75, 60, 108, 3, 4, 198, 153, 60, 108, 3, 4, 200, 230, 109, + 108, 3, 4, 62, 197, 241, 216, 35, 3, 4, 242, 75, 58, 216, 35, 3, 4, 75, + 60, 216, 35, 3, 4, 233, 83, 236, 138, 216, 35, 3, 4, 206, 180, 236, 138, + 108, 3, 223, 163, 45, 132, 243, 10, 108, 3, 223, 163, 50, 132, 243, 10, + 195, 152, 211, 57, 238, 218, 208, 200, 215, 127, 3, 4, 75, 58, 215, 127, + 3, 4, 196, 103, 204, 24, 208, 201, 4, 248, 77, 242, 218, 202, 68, 208, + 200, 215, 127, 3, 223, 163, 45, 132, 243, 10, 215, 127, 3, 223, 163, 50, + 132, 243, 10, 47, 215, 127, 3, 4, 243, 2, 252, 60, 215, 127, 3, 223, 163, + 55, 243, 10, 47, 236, 200, 56, 108, 3, 223, 163, 197, 241, 216, 35, 3, + 223, 163, 197, 241, 215, 127, 3, 223, 163, 197, 241, 223, 108, 208, 200, + 206, 198, 223, 108, 208, 200, 191, 167, 213, 10, 207, 64, 239, 62, 251, + 147, 211, 57, 239, 9, 223, 100, 4, 236, 140, 196, 93, 4, 216, 35, 56, + 196, 93, 4, 211, 6, 223, 100, 4, 211, 6, 223, 100, 4, 219, 29, 251, 125, + 196, 93, 4, 219, 29, 211, 56, 196, 93, 93, 223, 99, 223, 100, 93, 196, + 92, 196, 93, 93, 249, 88, 93, 223, 99, 223, 100, 93, 249, 88, 93, 196, + 92, 196, 93, 248, 216, 23, 222, 198, 4, 196, 92, 223, 100, 248, 216, 23, + 222, 198, 4, 223, 99, 242, 219, 196, 93, 4, 204, 3, 242, 219, 223, 100, + 4, 204, 3, 55, 51, 223, 99, 55, 51, 196, 92, 242, 219, 196, 93, 4, 204, + 4, 23, 202, 68, 208, 200, 219, 29, 23, 4, 75, 58, 219, 29, 211, 57, 4, + 75, 58, 55, 219, 29, 251, 125, 55, 219, 29, 211, 56, 105, 223, 101, 219, + 29, 251, 125, 105, 223, 101, 219, 29, 211, 56, 202, 80, 220, 13, 211, 56, + 202, 80, 220, 13, 251, 125, 219, 29, 211, 57, 211, 1, 219, 29, 251, 125, + 219, 29, 23, 4, 82, 201, 80, 219, 29, 211, 57, 4, 82, 201, 80, 219, 29, + 23, 4, 228, 241, 237, 215, 219, 29, 211, 57, 4, 228, 241, 237, 215, 219, + 29, 23, 4, 55, 211, 6, 219, 29, 23, 4, 196, 103, 219, 29, 23, 4, 55, 196, + 103, 2, 195, 149, 4, 196, 103, 219, 29, 211, 57, 4, 55, 211, 6, 219, 29, + 211, 57, 4, 55, 196, 103, 191, 167, 213, 10, 236, 152, 251, 75, 191, 167, + 213, 10, 207, 137, 251, 75, 234, 43, 3, 4, 75, 60, 228, 17, 4, 75, 58, + 197, 225, 228, 241, 249, 88, 4, 55, 81, 106, 197, 225, 228, 241, 249, 88, + 4, 197, 225, 81, 106, 198, 153, 211, 67, 4, 75, 58, 198, 153, 211, 67, 4, + 206, 180, 236, 138, 202, 180, 216, 35, 202, 179, 239, 49, 4, 75, 58, 234, + 43, 4, 250, 193, 251, 165, 234, 45, 119, 4, 243, 2, 252, 60, 251, 40, + 234, 45, 211, 57, 234, 45, 159, 234, 43, 3, 93, 108, 56, 108, 3, 93, 234, + 43, 56, 234, 43, 3, 93, 198, 153, 211, 66, 55, 242, 84, 234, 44, 105, + 239, 41, 234, 43, 202, 194, 115, 239, 41, 234, 43, 202, 194, 234, 43, 3, + 4, 105, 185, 93, 23, 105, 185, 60, 234, 36, 4, 232, 128, 185, 58, 219, + 180, 4, 243, 11, 223, 117, 230, 204, 4, 243, 11, 223, 117, 219, 180, 4, + 208, 13, 87, 58, 230, 204, 4, 208, 13, 87, 58, 219, 180, 211, 57, 202, + 99, 234, 45, 159, 230, 204, 211, 57, 202, 99, 234, 45, 159, 219, 180, + 211, 57, 202, 99, 234, 45, 119, 4, 75, 223, 117, 230, 204, 211, 57, 202, + 99, 234, 45, 119, 4, 75, 223, 117, 219, 180, 211, 57, 202, 99, 234, 45, + 119, 4, 75, 58, 230, 204, 211, 57, 202, 99, 234, 45, 119, 4, 75, 58, 219, + 180, 211, 57, 202, 99, 234, 45, 119, 4, 75, 93, 183, 230, 204, 211, 57, + 202, 99, 234, 45, 119, 4, 75, 93, 219, 224, 219, 180, 211, 57, 251, 41, + 230, 204, 211, 57, 251, 41, 219, 180, 23, 202, 168, 213, 12, 234, 45, + 159, 230, 204, 23, 202, 168, 213, 12, 234, 45, 159, 219, 180, 23, 213, + 12, 251, 41, 230, 204, 23, 213, 12, 251, 41, 219, 180, 93, 235, 131, 234, + 45, 93, 230, 203, 230, 204, 93, 235, 131, 234, 45, 93, 219, 179, 219, + 180, 93, 202, 180, 211, 57, 234, 44, 230, 204, 93, 202, 180, 211, 57, + 234, 44, 219, 180, 93, 202, 180, 93, 230, 203, 230, 204, 93, 202, 180, + 93, 219, 179, 219, 180, 93, 230, 204, 93, 235, 131, 234, 44, 230, 204, + 93, 219, 180, 93, 235, 131, 234, 44, 219, 180, 93, 202, 99, 234, 45, 93, + 230, 204, 93, 202, 99, 234, 44, 230, 204, 93, 202, 99, 234, 45, 93, 219, + 180, 93, 202, 99, 234, 44, 202, 99, 234, 45, 119, 211, 57, 219, 179, 202, + 99, 234, 45, 119, 211, 57, 230, 203, 202, 99, 234, 45, 119, 211, 57, 219, + 180, 4, 75, 223, 117, 202, 99, 234, 45, 119, 211, 57, 230, 204, 4, 75, + 223, 117, 235, 131, 234, 45, 119, 211, 57, 219, 179, 235, 131, 234, 45, + 119, 211, 57, 230, 203, 235, 131, 202, 99, 234, 45, 119, 211, 57, 219, + 179, 235, 131, 202, 99, 234, 45, 119, 211, 57, 230, 203, 202, 180, 211, + 57, 219, 179, 202, 180, 211, 57, 230, 203, 202, 180, 93, 219, 180, 93, + 234, 43, 56, 202, 180, 93, 230, 204, 93, 234, 43, 56, 55, 214, 88, 219, + 179, 55, 214, 88, 230, 203, 55, 214, 88, 219, 180, 4, 196, 103, 230, 204, + 211, 1, 219, 179, 230, 204, 248, 216, 219, 179, 219, 180, 242, 219, 247, + 205, 238, 164, 230, 204, 242, 219, 247, 205, 238, 164, 219, 180, 242, + 219, 247, 205, 238, 165, 93, 202, 99, 234, 44, 230, 204, 242, 219, 247, + 205, 238, 165, 93, 202, 99, 234, 44, 202, 69, 199, 38, 220, 11, 199, 38, + 202, 69, 199, 39, 211, 57, 234, 45, 159, 220, 11, 199, 39, 211, 57, 234, + 45, 159, 234, 43, 3, 4, 247, 241, 58, 208, 232, 93, 202, 168, 234, 43, + 56, 200, 221, 93, 202, 168, 234, 43, 56, 208, 232, 93, 202, 168, 213, 12, + 234, 45, 159, 200, 221, 93, 202, 168, 213, 12, 234, 45, 159, 208, 232, + 93, 234, 43, 56, 200, 221, 93, 234, 43, 56, 208, 232, 93, 213, 12, 234, + 45, 159, 200, 221, 93, 213, 12, 234, 45, 159, 208, 232, 93, 251, 165, + 234, 45, 159, 200, 221, 93, 251, 165, 234, 45, 159, 208, 232, 93, 213, + 12, 251, 165, 234, 45, 159, 200, 221, 93, 213, 12, 251, 165, 234, 45, + 159, 55, 208, 231, 55, 200, 220, 200, 229, 4, 236, 140, 200, 181, 4, 236, + 140, 200, 229, 4, 108, 3, 60, 200, 181, 4, 108, 3, 60, 200, 229, 4, 215, + 127, 3, 60, 200, 181, 4, 215, 127, 3, 60, 200, 229, 79, 211, 57, 234, 45, + 119, 4, 75, 58, 200, 181, 79, 211, 57, 234, 45, 119, 4, 75, 58, 200, 229, + 79, 93, 234, 43, 56, 200, 181, 79, 93, 234, 43, 56, 200, 229, 79, 93, + 198, 153, 211, 66, 200, 181, 79, 93, 198, 153, 211, 66, 200, 229, 79, 93, + 251, 165, 234, 45, 159, 200, 181, 79, 93, 251, 165, 234, 45, 159, 200, + 229, 79, 93, 213, 12, 234, 45, 159, 200, 181, 79, 93, 213, 12, 234, 45, + 159, 51, 45, 211, 77, 111, 211, 66, 51, 50, 211, 77, 111, 211, 66, 242, + 219, 200, 228, 242, 219, 200, 180, 242, 219, 200, 229, 211, 57, 234, 45, + 159, 242, 219, 200, 181, 211, 57, 234, 45, 159, 200, 229, 93, 200, 180, + 200, 181, 93, 200, 228, 200, 229, 93, 200, 228, 200, 181, 93, 200, 180, + 200, 181, 248, 216, 200, 228, 200, 181, 248, 216, 23, 222, 198, 247, 205, + 237, 216, 4, 200, 228, 234, 132, 79, 211, 69, 235, 118, 209, 116, 4, 199, + 122, 198, 53, 198, 7, 223, 99, 232, 147, 213, 27, 203, 40, 45, 199, 228, + 203, 40, 144, 199, 228, 203, 40, 133, 199, 228, 209, 255, 4, 206, 8, 81, + 249, 88, 197, 225, 50, 197, 57, 55, 81, 249, 88, 45, 197, 57, 81, 249, + 88, 55, 45, 197, 57, 55, 81, 249, 88, 55, 45, 197, 57, 179, 237, 216, + 232, 98, 45, 216, 191, 79, 55, 195, 135, 203, 40, 144, 199, 229, 4, 211, + 6, 203, 40, 133, 199, 229, 4, 196, 103, 203, 40, 133, 199, 229, 93, 203, + 40, 144, 199, 228, 55, 144, 199, 228, 55, 133, 199, 228, 55, 201, 28, + 213, 12, 56, 207, 18, 55, 201, 28, 213, 12, 56, 236, 164, 213, 12, 236, + 208, 4, 207, 18, 214, 107, 202, 97, 81, 219, 113, 4, 243, 11, 58, 81, + 219, 113, 4, 243, 11, 60, 144, 199, 229, 4, 243, 11, 60, 210, 119, 4, + 228, 241, 106, 210, 119, 4, 198, 153, 211, 66, 197, 225, 81, 249, 88, + 248, 168, 207, 65, 197, 225, 81, 249, 88, 4, 228, 241, 106, 197, 225, + 242, 84, 211, 66, 197, 225, 214, 88, 219, 179, 197, 225, 214, 88, 230, + 203, 235, 131, 202, 99, 219, 180, 211, 57, 234, 45, 159, 235, 131, 202, + 99, 230, 204, 211, 57, 234, 45, 159, 197, 225, 202, 24, 248, 168, 207, + 65, 220, 13, 197, 225, 81, 249, 88, 211, 66, 55, 202, 24, 211, 66, 63, + 81, 164, 215, 60, 63, 81, 164, 186, 234, 204, 63, 57, 186, 193, 105, 63, + 57, 202, 2, 234, 204, 63, 57, 202, 2, 193, 105, 63, 57, 45, 50, 63, 57, + 118, 62, 57, 196, 66, 62, 57, 235, 119, 62, 57, 186, 234, 204, 62, 57, + 186, 193, 105, 62, 57, 202, 2, 234, 204, 62, 57, 202, 2, 193, 105, 62, + 57, 45, 50, 62, 57, 133, 144, 62, 57, 96, 64, 4, 198, 136, 235, 118, 96, + 64, 4, 198, 136, 196, 65, 118, 64, 4, 198, 136, 235, 118, 118, 64, 4, + 198, 136, 196, 65, 51, 4, 198, 54, 132, 248, 139, 51, 4, 248, 77, 132, + 248, 139, 51, 4, 116, 50, 237, 39, 132, 248, 139, 51, 4, 110, 45, 237, + 39, 132, 248, 139, 237, 33, 4, 45, 132, 248, 139, 237, 33, 4, 50, 132, + 248, 139, 237, 33, 4, 198, 54, 132, 248, 139, 237, 33, 4, 248, 77, 132, + 248, 139, 235, 138, 201, 190, 62, 220, 13, 201, 190, 63, 220, 13, 201, + 190, 62, 195, 83, 2, 201, 190, 63, 195, 83, 2, 201, 190, 62, 210, 24, 63, + 210, 24, 63, 229, 182, 62, 229, 182, 228, 241, 62, 229, 182, 62, 220, 13, + 243, 10, 62, 216, 213, 237, 32, 63, 216, 213, 237, 32, 62, 216, 213, 218, + 232, 63, 216, 213, 218, 232, 62, 2, 237, 32, 62, 2, 218, 232, 63, 2, 218, + 232, 62, 228, 241, 234, 121, 63, 228, 241, 234, 121, 62, 81, 234, 121, + 63, 81, 234, 121, 45, 64, 4, 2, 243, 10, 115, 118, 250, 231, 45, 64, 4, + 47, 209, 81, 179, 118, 201, 183, 57, 118, 197, 13, 64, 4, 81, 106, 118, + 197, 13, 64, 4, 55, 81, 106, 118, 197, 13, 64, 232, 98, 164, 118, 197, + 13, 197, 225, 237, 216, 57, 118, 64, 4, 235, 138, 201, 80, 118, 64, 4, + 199, 216, 4, 81, 106, 118, 64, 4, 199, 216, 4, 55, 81, 106, 118, 197, 13, + 64, 4, 199, 215, 118, 197, 13, 64, 4, 199, 216, 4, 81, 106, 118, 197, 13, + 64, 4, 199, 216, 4, 55, 81, 106, 118, 64, 198, 216, 192, 235, 193, 139, + 64, 209, 58, 236, 231, 219, 224, 234, 43, 3, 93, 118, 57, 207, 19, 198, + 153, 211, 67, 93, 118, 57, 118, 64, 93, 207, 19, 251, 165, 234, 45, 159, + 96, 64, 198, 216, 230, 203, 96, 64, 198, 216, 200, 180, 118, 208, 26, 57, + 96, 208, 26, 57, 207, 19, 198, 153, 211, 67, 93, 96, 57, 96, 64, 93, 207, + 19, 251, 165, 234, 45, 159, 198, 153, 211, 67, 93, 118, 57, 118, 64, 93, + 251, 165, 234, 45, 159, 118, 64, 93, 207, 19, 198, 153, 211, 66, 96, 64, + 93, 207, 19, 198, 153, 211, 66, 235, 119, 197, 240, 191, 21, 57, 203, 40, + 202, 99, 186, 57, 203, 40, 249, 143, 202, 2, 57, 63, 216, 213, 201, 102, + 62, 2, 201, 102, 63, 2, 201, 102, 62, 206, 203, 210, 24, 63, 206, 203, + 210, 24, 88, 220, 13, 243, 10, 88, 211, 8, 4, 211, 8, 223, 117, 88, 243, + 11, 4, 243, 11, 223, 117, 88, 243, 10, 88, 47, 205, 154, 202, 99, 186, + 64, 4, 228, 250, 229, 235, 249, 143, 202, 2, 64, 4, 228, 250, 199, 215, + 202, 99, 186, 64, 4, 228, 241, 199, 215, 249, 143, 202, 2, 64, 4, 228, + 241, 199, 215, 248, 224, 64, 209, 58, 235, 119, 199, 25, 186, 234, 203, + 203, 40, 248, 224, 64, 209, 58, 235, 119, 199, 25, 186, 234, 203, 118, + 197, 240, 57, 196, 66, 197, 240, 57, 96, 197, 240, 57, 235, 119, 197, + 240, 57, 45, 50, 197, 240, 57, 133, 144, 197, 240, 57, 186, 193, 105, + 197, 240, 57, 186, 234, 204, 197, 240, 57, 202, 2, 234, 204, 197, 240, + 57, 202, 2, 193, 105, 197, 240, 57, 118, 197, 240, 237, 214, 57, 196, 66, + 197, 240, 237, 214, 57, 96, 197, 240, 237, 214, 57, 235, 119, 197, 240, + 237, 214, 57, 242, 221, 197, 240, 211, 77, 243, 11, 57, 251, 85, 197, + 240, 211, 77, 243, 11, 57, 118, 197, 240, 64, 119, 164, 196, 66, 197, + 240, 64, 119, 164, 96, 197, 240, 64, 119, 164, 235, 119, 197, 240, 64, + 119, 164, 186, 193, 105, 197, 240, 64, 119, 164, 186, 234, 204, 197, 240, + 64, 119, 164, 202, 2, 234, 204, 197, 240, 64, 119, 164, 202, 2, 193, 105, + 197, 240, 64, 119, 164, 118, 197, 240, 64, 4, 55, 228, 241, 106, 196, 66, + 197, 240, 64, 4, 55, 228, 241, 106, 96, 197, 240, 64, 4, 55, 228, 241, + 106, 235, 119, 197, 240, 64, 4, 55, 228, 241, 106, 228, 241, 199, 237, + 221, 222, 81, 199, 237, 221, 222, 118, 197, 240, 64, 139, 96, 197, 240, + 57, 196, 66, 197, 240, 64, 118, 79, 235, 119, 197, 240, 57, 96, 197, 240, + 64, 139, 118, 197, 240, 57, 235, 119, 197, 240, 64, 118, 79, 196, 66, + 197, 240, 57, 118, 197, 240, 210, 196, 250, 231, 196, 66, 197, 240, 210, + 196, 250, 231, 96, 197, 240, 210, 196, 250, 231, 235, 119, 197, 240, 210, + 196, 250, 231, 118, 62, 47, 63, 57, 196, 66, 62, 47, 63, 57, 96, 62, 47, + 63, 57, 235, 119, 62, 47, 63, 57, 251, 85, 197, 240, 50, 196, 221, 57, + 251, 85, 197, 240, 248, 77, 196, 221, 57, 251, 85, 197, 240, 45, 196, + 221, 57, 251, 85, 197, 240, 198, 54, 196, 221, 57, 207, 23, 219, 224, + 207, 23, 183, 214, 77, 219, 224, 214, 77, 183, 232, 128, 239, 2, 250, + 232, 243, 6, 251, 84, 96, 62, 57, 16, 40, 196, 255, 42, 234, 133, 198, + 225, 198, 52, 118, 234, 37, 250, 235, 198, 225, 206, 204, 196, 66, 234, + 37, 250, 235, 198, 225, 198, 52, 96, 234, 37, 250, 235, 198, 225, 219, + 220, 235, 119, 234, 37, 250, 235, 62, 118, 234, 37, 250, 235, 62, 196, + 66, 234, 37, 250, 235, 62, 96, 234, 37, 250, 235, 62, 235, 119, 234, 37, + 250, 235, 235, 119, 197, 240, 64, 4, 179, 198, 136, 219, 214, 235, 119, + 197, 240, 64, 4, 179, 198, 136, 206, 197, 196, 66, 197, 240, 64, 4, 179, + 198, 136, 219, 214, 196, 66, 197, 240, 64, 4, 179, 198, 136, 206, 197, + 118, 197, 240, 64, 4, 179, 198, 136, 196, 65, 96, 197, 240, 64, 4, 179, + 198, 136, 196, 65, 118, 197, 240, 64, 4, 179, 198, 136, 235, 118, 96, + 197, 240, 64, 4, 179, 198, 136, 235, 118, 62, 238, 163, 235, 119, 23, + 118, 57, 62, 238, 163, 235, 119, 23, 96, 57, 62, 238, 163, 196, 66, 23, + 118, 57, 62, 238, 163, 196, 66, 23, 96, 57, 62, 238, 163, 118, 23, 196, + 66, 57, 62, 238, 163, 96, 23, 196, 66, 57, 62, 238, 163, 118, 23, 235, + 119, 57, 62, 238, 163, 96, 23, 235, 119, 57, 206, 248, 64, 144, 219, 224, + 206, 248, 64, 144, 183, 206, 248, 64, 133, 219, 224, 206, 248, 64, 133, + 183, 206, 248, 64, 45, 196, 77, 206, 248, 64, 50, 196, 77, 206, 248, 64, + 45, 235, 123, 206, 248, 64, 50, 235, 123, 196, 66, 63, 64, 232, 98, 249, + 88, 4, 228, 241, 164, 133, 250, 236, 223, 163, 42, 207, 93, 248, 62, 211, + 1, 63, 201, 188, 211, 1, 63, 23, 62, 201, 188, 211, 1, 62, 201, 188, 249, + 107, 111, 4, 156, 192, 235, 47, 192, 235, 47, 28, 192, 235, 62, 51, 247, + 19, 62, 237, 33, 247, 19, 153, 62, 210, 24, 228, 241, 62, 211, 160, 62, + 211, 160, 62, 216, 213, 196, 76, 197, 242, 247, 19, 62, 216, 213, 235, + 122, 197, 242, 247, 19, 62, 216, 213, 219, 219, 197, 242, 247, 19, 62, + 216, 213, 206, 203, 197, 242, 247, 19, 214, 95, 232, 146, 109, 198, 54, + 132, 62, 243, 10, 248, 77, 132, 62, 243, 10, 156, 232, 128, 209, 60, 62, + 238, 159, 206, 122, 156, 232, 128, 209, 60, 62, 238, 159, 63, 232, 128, + 209, 60, 238, 159, 206, 122, 63, 232, 128, 209, 60, 238, 159, 51, 209, + 25, 223, 144, 196, 107, 56, 230, 187, 77, 209, 78, 232, 146, 109, 209, + 78, 232, 146, 138, 209, 78, 232, 146, 134, 209, 78, 232, 146, 149, 198, + 9, 208, 185, 250, 189, 228, 91, 209, 196, 214, 91, 63, 215, 206, 204, 33, + 62, 237, 33, 211, 105, 238, 217, 197, 202, 156, 215, 206, 250, 227, 238, + 179, 230, 88, 191, 75, 221, 2, 251, 53, 252, 32, 193, 247, 209, 26, 45, + 132, 62, 201, 102, 50, 132, 62, 201, 102, 201, 103, 4, 45, 132, 248, 139, + 201, 103, 4, 50, 132, 248, 139, 118, 197, 13, 64, 4, 197, 242, 250, 233, + 196, 66, 197, 13, 64, 4, 197, 242, 250, 233, 96, 197, 13, 64, 4, 197, + 242, 250, 233, 235, 119, 197, 13, 64, 4, 197, 242, 250, 233, 234, 27, + 232, 146, 107, 234, 27, 232, 146, 109, 205, 51, 206, 31, 250, 188, 16, + 195, 52, 206, 31, 250, 188, 16, 212, 254, 206, 31, 250, 188, 16, 208, 1, + 206, 31, 250, 188, 16, 248, 163, 206, 31, 250, 188, 16, 204, 16, 206, 31, + 250, 188, 16, 198, 0, 234, 43, 3, 4, 223, 140, 60, 196, 89, 113, 204, 12, + 113, 235, 128, 113, 210, 96, 113, 207, 18, 50, 251, 115, 229, 203, 210, + 78, 113, 135, 6, 1, 250, 122, 135, 6, 1, 247, 252, 135, 6, 1, 195, 151, + 135, 6, 1, 231, 18, 135, 6, 1, 236, 169, 135, 6, 1, 192, 49, 135, 6, 1, + 191, 55, 135, 6, 1, 235, 30, 135, 6, 1, 191, 82, 135, 6, 1, 223, 39, 135, + 6, 1, 89, 223, 39, 135, 6, 1, 68, 135, 6, 1, 236, 190, 135, 6, 1, 222, + 94, 135, 6, 1, 219, 75, 135, 6, 1, 215, 66, 135, 6, 1, 214, 210, 135, 6, + 1, 211, 89, 135, 6, 1, 209, 55, 135, 6, 1, 206, 179, 135, 6, 1, 202, 77, + 135, 6, 1, 197, 44, 135, 6, 1, 196, 124, 135, 6, 1, 232, 101, 135, 6, 1, + 229, 188, 135, 6, 1, 211, 20, 135, 6, 1, 210, 63, 135, 6, 1, 203, 8, 135, + 6, 1, 197, 146, 135, 6, 1, 243, 54, 135, 6, 1, 203, 165, 135, 6, 1, 192, + 58, 135, 6, 1, 192, 60, 135, 6, 1, 192, 93, 135, 6, 1, 201, 220, 140, + 135, 6, 1, 191, 225, 135, 6, 1, 2, 191, 190, 135, 6, 1, 2, 191, 191, 4, + 199, 215, 135, 6, 1, 192, 12, 135, 6, 1, 223, 82, 2, 191, 190, 135, 6, 1, + 248, 175, 191, 190, 135, 6, 1, 223, 82, 248, 175, 191, 190, 135, 6, 1, + 232, 228, 135, 6, 1, 223, 37, 135, 6, 1, 203, 7, 135, 6, 1, 197, 215, 65, + 135, 6, 1, 220, 1, 215, 66, 135, 6, 1, 247, 73, 243, 54, 135, 2, 1, 250, + 122, 135, 2, 1, 247, 252, 135, 2, 1, 195, 151, 135, 2, 1, 231, 18, 135, + 2, 1, 236, 169, 135, 2, 1, 192, 49, 135, 2, 1, 191, 55, 135, 2, 1, 235, + 30, 135, 2, 1, 191, 82, 135, 2, 1, 223, 39, 135, 2, 1, 89, 223, 39, 135, + 2, 1, 68, 135, 2, 1, 236, 190, 135, 2, 1, 222, 94, 135, 2, 1, 219, 75, + 135, 2, 1, 215, 66, 135, 2, 1, 214, 210, 135, 2, 1, 211, 89, 135, 2, 1, + 209, 55, 135, 2, 1, 206, 179, 135, 2, 1, 202, 77, 135, 2, 1, 197, 44, + 135, 2, 1, 196, 124, 135, 2, 1, 232, 101, 135, 2, 1, 229, 188, 135, 2, 1, + 211, 20, 135, 2, 1, 210, 63, 135, 2, 1, 203, 8, 135, 2, 1, 197, 146, 135, + 2, 1, 243, 54, 135, 2, 1, 203, 165, 135, 2, 1, 192, 58, 135, 2, 1, 192, + 60, 135, 2, 1, 192, 93, 135, 2, 1, 201, 220, 140, 135, 2, 1, 191, 225, + 135, 2, 1, 2, 191, 190, 135, 2, 1, 2, 191, 191, 4, 199, 215, 135, 2, 1, + 192, 12, 135, 2, 1, 223, 82, 2, 191, 190, 135, 2, 1, 248, 175, 191, 190, + 135, 2, 1, 223, 82, 248, 175, 191, 190, 135, 2, 1, 232, 228, 135, 2, 1, + 223, 37, 135, 2, 1, 203, 7, 135, 2, 1, 197, 215, 65, 135, 2, 1, 220, 1, + 215, 66, 135, 2, 1, 247, 73, 243, 54, 8, 6, 1, 220, 143, 4, 55, 164, 8, + 2, 1, 220, 143, 4, 55, 164, 8, 6, 1, 220, 143, 4, 82, 198, 152, 8, 6, 1, + 210, 237, 4, 106, 8, 6, 1, 207, 222, 4, 199, 215, 8, 2, 1, 42, 4, 106, 8, + 2, 1, 200, 44, 4, 237, 39, 106, 8, 6, 1, 230, 117, 4, 237, 87, 8, 2, 1, + 230, 117, 4, 237, 87, 8, 6, 1, 222, 153, 4, 237, 87, 8, 2, 1, 222, 153, + 4, 237, 87, 8, 6, 1, 191, 167, 4, 237, 87, 8, 2, 1, 191, 167, 4, 237, 87, + 8, 6, 1, 251, 160, 8, 6, 1, 218, 169, 4, 102, 8, 6, 1, 153, 65, 8, 6, 1, + 153, 251, 160, 8, 2, 1, 196, 13, 4, 50, 102, 8, 6, 1, 193, 225, 4, 102, + 8, 2, 1, 193, 225, 4, 102, 8, 2, 1, 196, 13, 4, 238, 175, 8, 6, 1, 132, + 230, 116, 8, 2, 1, 132, 230, 116, 8, 2, 1, 199, 213, 209, 211, 8, 2, 1, + 235, 15, 4, 213, 9, 8, 2, 1, 153, 207, 222, 4, 199, 215, 8, 2, 1, 187, 4, + 130, 206, 189, 223, 117, 8, 1, 2, 6, 153, 71, 8, 200, 230, 2, 1, 223, 35, + 52, 1, 6, 196, 12, 8, 6, 1, 206, 9, 4, 200, 146, 199, 215, 8, 6, 1, 191, + 167, 4, 200, 146, 199, 215, 94, 6, 1, 251, 186, 94, 2, 1, 251, 186, 94, + 6, 1, 195, 66, 94, 2, 1, 195, 66, 94, 6, 1, 231, 211, 94, 2, 1, 231, 211, + 94, 6, 1, 237, 255, 94, 2, 1, 237, 255, 94, 6, 1, 234, 165, 94, 2, 1, + 234, 165, 94, 6, 1, 202, 7, 94, 2, 1, 202, 7, 94, 6, 1, 191, 95, 94, 2, + 1, 191, 95, 94, 6, 1, 230, 6, 94, 2, 1, 230, 6, 94, 6, 1, 199, 13, 94, 2, + 1, 199, 13, 94, 6, 1, 228, 32, 94, 2, 1, 228, 32, 94, 6, 1, 222, 77, 94, + 2, 1, 222, 77, 94, 6, 1, 219, 252, 94, 2, 1, 219, 252, 94, 6, 1, 216, + 100, 94, 2, 1, 216, 100, 94, 6, 1, 213, 219, 94, 2, 1, 213, 219, 94, 6, + 1, 220, 248, 94, 2, 1, 220, 248, 94, 6, 1, 74, 94, 2, 1, 74, 94, 6, 1, + 209, 185, 94, 2, 1, 209, 185, 94, 6, 1, 206, 162, 94, 2, 1, 206, 162, 94, + 6, 1, 202, 183, 94, 2, 1, 202, 183, 94, 6, 1, 199, 166, 94, 2, 1, 199, + 166, 94, 6, 1, 196, 168, 94, 2, 1, 196, 168, 94, 6, 1, 233, 23, 94, 2, 1, + 233, 23, 94, 6, 1, 221, 190, 94, 2, 1, 221, 190, 94, 6, 1, 208, 176, 94, + 2, 1, 208, 176, 94, 6, 1, 211, 81, 94, 2, 1, 211, 81, 94, 6, 1, 237, 37, + 251, 192, 94, 2, 1, 237, 37, 251, 192, 94, 6, 1, 39, 94, 251, 230, 94, 2, + 1, 39, 94, 251, 230, 94, 6, 1, 238, 198, 234, 165, 94, 2, 1, 238, 198, + 234, 165, 94, 6, 1, 237, 37, 222, 77, 94, 2, 1, 237, 37, 222, 77, 94, 6, + 1, 237, 37, 213, 219, 94, 2, 1, 237, 37, 213, 219, 94, 6, 1, 238, 198, + 213, 219, 94, 2, 1, 238, 198, 213, 219, 94, 6, 1, 39, 94, 211, 81, 94, 2, + 1, 39, 94, 211, 81, 94, 6, 1, 205, 145, 94, 2, 1, 205, 145, 94, 6, 1, + 238, 214, 203, 105, 94, 2, 1, 238, 214, 203, 105, 94, 6, 1, 39, 94, 203, + 105, 94, 2, 1, 39, 94, 203, 105, 94, 6, 1, 39, 94, 234, 12, 94, 2, 1, 39, + 94, 234, 12, 94, 6, 1, 251, 212, 221, 195, 94, 2, 1, 251, 212, 221, 195, + 94, 6, 1, 237, 37, 228, 242, 94, 2, 1, 237, 37, 228, 242, 94, 6, 1, 39, + 94, 228, 242, 94, 2, 1, 39, 94, 228, 242, 94, 6, 1, 39, 94, 140, 94, 2, + 1, 39, 94, 140, 94, 6, 1, 220, 142, 140, 94, 2, 1, 220, 142, 140, 94, 6, + 1, 39, 94, 229, 209, 94, 2, 1, 39, 94, 229, 209, 94, 6, 1, 39, 94, 230, + 9, 94, 2, 1, 39, 94, 230, 9, 94, 6, 1, 39, 94, 231, 206, 94, 2, 1, 39, + 94, 231, 206, 94, 6, 1, 39, 94, 236, 193, 94, 2, 1, 39, 94, 236, 193, 94, + 6, 1, 39, 94, 203, 71, 94, 2, 1, 39, 94, 203, 71, 94, 6, 1, 39, 212, 145, + 203, 71, 94, 2, 1, 39, 212, 145, 203, 71, 94, 6, 1, 39, 212, 145, 214, + 16, 94, 2, 1, 39, 212, 145, 214, 16, 94, 6, 1, 39, 212, 145, 212, 81, 94, + 2, 1, 39, 212, 145, 212, 81, 94, 6, 1, 39, 212, 145, 193, 140, 94, 2, 1, + 39, 212, 145, 193, 140, 94, 16, 222, 102, 94, 16, 216, 101, 206, 162, 94, + 16, 209, 186, 206, 162, 94, 16, 201, 89, 94, 16, 199, 167, 206, 162, 94, + 16, 221, 191, 206, 162, 94, 16, 203, 72, 202, 183, 94, 6, 1, 238, 198, + 203, 105, 94, 2, 1, 238, 198, 203, 105, 94, 6, 1, 238, 198, 231, 206, 94, + 2, 1, 238, 198, 231, 206, 94, 33, 213, 220, 58, 94, 33, 201, 213, 250, + 201, 94, 33, 201, 213, 219, 188, 94, 6, 1, 248, 103, 221, 195, 94, 2, 1, + 248, 103, 221, 195, 94, 39, 212, 145, 232, 80, 201, 63, 94, 39, 212, 145, + 236, 234, 208, 13, 77, 94, 39, 212, 145, 223, 142, 208, 13, 77, 94, 39, + 212, 145, 195, 137, 236, 205, 94, 232, 118, 91, 230, 70, 94, 232, 80, + 201, 63, 94, 215, 200, 236, 205, 101, 2, 1, 251, 132, 101, 2, 1, 249, + 101, 101, 2, 1, 231, 210, 101, 2, 1, 236, 150, 101, 2, 1, 234, 103, 101, + 2, 1, 195, 49, 101, 2, 1, 191, 80, 101, 2, 1, 199, 193, 101, 2, 1, 223, + 162, 101, 2, 1, 222, 87, 101, 2, 1, 220, 7, 101, 2, 1, 217, 90, 101, 2, + 1, 214, 216, 101, 2, 1, 211, 104, 101, 2, 1, 210, 131, 101, 2, 1, 191, + 67, 101, 2, 1, 207, 163, 101, 2, 1, 205, 142, 101, 2, 1, 199, 179, 101, + 2, 1, 196, 113, 101, 2, 1, 209, 220, 101, 2, 1, 221, 200, 101, 2, 1, 231, + 82, 101, 2, 1, 208, 81, 101, 2, 1, 203, 69, 101, 2, 1, 243, 81, 101, 2, + 1, 247, 128, 101, 2, 1, 222, 234, 101, 2, 1, 243, 18, 101, 2, 1, 246, + 241, 101, 2, 1, 192, 218, 101, 2, 1, 222, 249, 101, 2, 1, 230, 87, 101, + 2, 1, 229, 245, 101, 2, 1, 229, 145, 101, 2, 1, 193, 125, 101, 2, 1, 230, + 19, 101, 2, 1, 229, 11, 101, 2, 1, 192, 14, 101, 2, 1, 252, 14, 198, 175, + 1, 170, 198, 175, 1, 192, 136, 198, 175, 1, 192, 135, 198, 175, 1, 192, + 125, 198, 175, 1, 192, 123, 198, 175, 1, 248, 218, 252, 62, 192, 118, + 198, 175, 1, 192, 118, 198, 175, 1, 192, 133, 198, 175, 1, 192, 130, 198, + 175, 1, 192, 132, 198, 175, 1, 192, 131, 198, 175, 1, 192, 40, 198, 175, + 1, 192, 127, 198, 175, 1, 192, 116, 198, 175, 1, 197, 86, 192, 116, 198, + 175, 1, 192, 113, 198, 175, 1, 192, 121, 198, 175, 1, 248, 218, 252, 62, + 192, 121, 198, 175, 1, 197, 86, 192, 121, 198, 175, 1, 192, 120, 198, + 175, 1, 192, 140, 198, 175, 1, 192, 114, 198, 175, 1, 197, 86, 192, 114, + 198, 175, 1, 192, 103, 198, 175, 1, 197, 86, 192, 103, 198, 175, 1, 192, + 33, 198, 175, 1, 192, 82, 198, 175, 1, 251, 243, 192, 82, 198, 175, 1, + 197, 86, 192, 82, 198, 175, 1, 192, 112, 198, 175, 1, 192, 111, 198, 175, + 1, 192, 108, 198, 175, 1, 197, 86, 192, 122, 198, 175, 1, 197, 86, 192, + 106, 198, 175, 1, 192, 104, 198, 175, 1, 191, 225, 198, 175, 1, 192, 101, + 198, 175, 1, 192, 99, 198, 175, 1, 192, 124, 198, 175, 1, 197, 86, 192, + 124, 198, 175, 1, 250, 127, 192, 124, 198, 175, 1, 192, 98, 198, 175, 1, + 192, 96, 198, 175, 1, 192, 97, 198, 175, 1, 192, 95, 198, 175, 1, 192, + 94, 198, 175, 1, 192, 134, 198, 175, 1, 192, 92, 198, 175, 1, 192, 90, + 198, 175, 1, 192, 89, 198, 175, 1, 192, 86, 198, 175, 1, 192, 83, 198, + 175, 1, 199, 157, 192, 83, 198, 175, 1, 192, 81, 198, 175, 1, 192, 80, + 198, 175, 1, 192, 12, 198, 175, 52, 1, 220, 115, 77, 198, 175, 204, 11, + 77, 198, 175, 120, 222, 196, 36, 5, 219, 42, 36, 5, 216, 5, 36, 5, 206, + 154, 36, 5, 202, 38, 36, 5, 203, 55, 36, 5, 248, 110, 36, 5, 198, 91, 36, + 5, 242, 98, 36, 5, 213, 36, 36, 5, 212, 64, 36, 5, 231, 11, 211, 182, 36, + 5, 191, 6, 36, 5, 236, 172, 36, 5, 237, 160, 36, 5, 222, 200, 36, 5, 198, + 240, 36, 5, 243, 67, 36, 5, 209, 198, 36, 5, 209, 72, 36, 5, 231, 97, 36, + 5, 231, 93, 36, 5, 231, 94, 36, 5, 231, 95, 36, 5, 201, 175, 36, 5, 201, + 129, 36, 5, 201, 142, 36, 5, 201, 174, 36, 5, 201, 147, 36, 5, 201, 148, + 36, 5, 201, 134, 36, 5, 247, 65, 36, 5, 247, 44, 36, 5, 247, 46, 36, 5, + 247, 64, 36, 5, 247, 62, 36, 5, 247, 63, 36, 5, 247, 45, 36, 5, 190, 224, + 36, 5, 190, 202, 36, 5, 190, 215, 36, 5, 190, 223, 36, 5, 190, 218, 36, + 5, 190, 219, 36, 5, 190, 207, 36, 5, 247, 60, 36, 5, 247, 47, 36, 5, 247, + 49, 36, 5, 247, 59, 36, 5, 247, 57, 36, 5, 247, 58, 36, 5, 247, 48, 36, + 5, 207, 234, 36, 5, 207, 224, 36, 5, 207, 230, 36, 5, 207, 233, 36, 5, + 207, 231, 36, 5, 207, 232, 36, 5, 207, 229, 36, 5, 220, 153, 36, 5, 220, + 145, 36, 5, 220, 148, 36, 5, 220, 152, 36, 5, 220, 149, 36, 5, 220, 150, + 36, 5, 220, 146, 36, 5, 192, 175, 36, 5, 192, 162, 36, 5, 192, 170, 36, + 5, 192, 174, 36, 5, 192, 172, 36, 5, 192, 173, 36, 5, 192, 169, 36, 5, + 230, 128, 36, 5, 230, 118, 36, 5, 230, 121, 36, 5, 230, 127, 36, 5, 230, + 123, 36, 5, 230, 124, 36, 5, 230, 120, 33, 38, 1, 249, 17, 33, 38, 1, + 195, 153, 33, 38, 1, 231, 77, 33, 38, 1, 237, 146, 33, 38, 1, 191, 62, + 33, 38, 1, 191, 87, 33, 38, 1, 155, 33, 38, 1, 234, 140, 33, 38, 1, 234, + 114, 33, 38, 1, 234, 103, 33, 38, 1, 74, 33, 38, 1, 210, 63, 33, 38, 1, + 234, 34, 33, 38, 1, 234, 22, 33, 38, 1, 199, 145, 33, 38, 1, 140, 33, 38, + 1, 197, 161, 33, 38, 1, 243, 127, 33, 38, 1, 203, 165, 33, 38, 1, 203, + 116, 33, 38, 1, 232, 228, 33, 38, 1, 234, 18, 33, 38, 1, 65, 33, 38, 1, + 223, 226, 33, 38, 1, 236, 191, 33, 38, 1, 215, 219, 196, 128, 33, 38, 1, + 192, 95, 33, 38, 1, 191, 225, 33, 38, 1, 223, 81, 65, 33, 38, 1, 219, 83, + 191, 190, 33, 38, 1, 248, 175, 191, 190, 33, 38, 1, 223, 81, 248, 175, + 191, 190, 50, 251, 116, 200, 225, 217, 51, 50, 251, 116, 235, 138, 200, + 225, 217, 51, 45, 200, 225, 248, 53, 50, 200, 225, 248, 53, 45, 235, 138, + 200, 225, 248, 53, 50, 235, 138, 200, 225, 248, 53, 207, 147, 223, 104, + 217, 51, 207, 147, 235, 138, 223, 104, 217, 51, 235, 138, 198, 8, 217, + 51, 45, 198, 8, 248, 53, 50, 198, 8, 248, 53, 207, 147, 201, 190, 45, + 207, 147, 211, 106, 248, 53, 50, 207, 147, 211, 106, 248, 53, 234, 189, + 238, 254, 210, 126, 232, 148, 210, 126, 207, 18, 232, 148, 210, 126, 228, + 85, 235, 138, 211, 177, 235, 119, 251, 126, 196, 66, 251, 126, 235, 138, + 206, 203, 251, 115, 55, 211, 172, 228, 88, 223, 93, 223, 102, 210, 183, + 248, 47, 228, 89, 4, 237, 42, 198, 153, 4, 206, 189, 58, 45, 130, 210, + 116, 248, 53, 50, 130, 210, 116, 248, 53, 198, 153, 4, 75, 58, 198, 153, + 4, 75, 60, 45, 81, 249, 88, 4, 208, 7, 50, 81, 249, 88, 4, 208, 7, 198, + 54, 45, 132, 248, 53, 198, 54, 50, 132, 248, 53, 248, 77, 45, 132, 248, + 53, 248, 77, 50, 132, 248, 53, 45, 202, 206, 126, 248, 53, 50, 202, 206, + 126, 248, 53, 45, 55, 210, 113, 50, 55, 210, 113, 105, 185, 139, 91, 75, + 208, 151, 91, 75, 139, 105, 185, 208, 151, 112, 232, 128, 75, 208, 151, + 232, 226, 75, 77, 207, 18, 208, 13, 77, 81, 198, 152, 206, 189, 209, 61, + 193, 23, 204, 11, 82, 236, 140, 153, 242, 74, 207, 147, 236, 140, 207, + 147, 242, 74, 153, 204, 25, 238, 15, 4, 45, 230, 173, 238, 15, 4, 50, + 230, 173, 153, 238, 14, 198, 54, 132, 205, 54, 56, 197, 14, 237, 215, + 198, 223, 237, 215, 201, 79, 232, 80, 201, 63, 81, 202, 136, 236, 138, + 193, 72, 81, 219, 112, 247, 109, 55, 228, 88, 207, 18, 242, 74, 55, 218, + 237, 207, 252, 77, 237, 216, 4, 45, 196, 69, 55, 200, 164, 77, 223, 93, + 130, 222, 35, 223, 93, 130, 222, 36, 4, 222, 36, 58, 130, 222, 35, 130, + 222, 36, 4, 236, 140, 55, 201, 114, 242, 74, 235, 138, 202, 23, 197, 225, + 238, 14, 216, 214, 242, 74, 210, 125, 77, 208, 150, 234, 129, 77, 238, + 255, 195, 137, 236, 205, 238, 218, 210, 82, 4, 50, 238, 216, 238, 218, + 210, 82, 4, 45, 238, 216, 198, 128, 3, 6, 233, 255, 216, 214, 233, 216, + 77, 216, 214, 208, 13, 77, 45, 51, 248, 54, 4, 106, 50, 51, 248, 54, 4, + 106, 45, 51, 248, 54, 4, 55, 106, 50, 51, 248, 54, 4, 55, 106, 198, 54, + 132, 45, 210, 113, 198, 54, 132, 50, 210, 113, 248, 77, 132, 45, 210, + 113, 248, 77, 132, 50, 210, 113, 211, 172, 228, 88, 12, 48, 207, 48, 12, + 48, 242, 230, 12, 48, 205, 57, 107, 12, 48, 205, 57, 109, 12, 48, 205, + 57, 138, 12, 48, 209, 250, 12, 48, 248, 62, 12, 48, 199, 233, 12, 48, + 221, 79, 107, 12, 48, 221, 79, 109, 12, 48, 236, 202, 12, 48, 205, 61, + 12, 48, 2, 107, 12, 48, 2, 109, 12, 48, 220, 30, 107, 12, 48, 220, 30, + 109, 12, 48, 220, 30, 138, 12, 48, 220, 30, 134, 12, 48, 202, 58, 12, 48, + 198, 227, 12, 48, 202, 55, 107, 12, 48, 202, 55, 109, 12, 48, 229, 224, + 107, 12, 48, 229, 224, 109, 12, 48, 230, 53, 12, 48, 207, 136, 12, 48, + 243, 64, 12, 48, 200, 198, 12, 48, 215, 205, 12, 48, 237, 143, 12, 48, + 215, 193, 12, 48, 242, 249, 12, 48, 193, 144, 107, 12, 48, 193, 144, 109, + 12, 48, 232, 243, 12, 48, 210, 76, 107, 12, 48, 210, 76, 109, 12, 48, + 202, 178, 132, 197, 255, 197, 177, 12, 48, 238, 239, 12, 48, 236, 162, + 12, 48, 223, 27, 12, 48, 248, 102, 79, 242, 213, 12, 48, 233, 193, 12, + 48, 201, 215, 107, 12, 48, 201, 215, 109, 12, 48, 249, 103, 12, 48, 202, + 185, 12, 48, 247, 190, 202, 185, 12, 48, 214, 86, 107, 12, 48, 214, 86, + 109, 12, 48, 214, 86, 138, 12, 48, 214, 86, 134, 12, 48, 216, 172, 12, + 48, 203, 107, 12, 48, 207, 142, 12, 48, 233, 223, 12, 48, 211, 119, 12, + 48, 248, 18, 107, 12, 48, 248, 18, 109, 12, 48, 216, 224, 12, 48, 215, + 199, 12, 48, 230, 214, 107, 12, 48, 230, 214, 109, 12, 48, 230, 214, 138, + 12, 48, 198, 173, 12, 48, 242, 212, 12, 48, 193, 105, 107, 12, 48, 193, + 105, 109, 12, 48, 247, 190, 205, 50, 12, 48, 202, 178, 228, 187, 12, 48, + 228, 187, 12, 48, 247, 190, 201, 229, 12, 48, 247, 190, 203, 102, 12, 48, + 232, 159, 12, 48, 247, 190, 247, 85, 12, 48, 202, 178, 193, 169, 12, 48, + 193, 170, 107, 12, 48, 193, 170, 109, 12, 48, 242, 252, 12, 48, 247, 190, + 230, 250, 12, 48, 179, 107, 12, 48, 179, 109, 12, 48, 247, 190, 219, 19, + 12, 48, 247, 190, 231, 191, 12, 48, 215, 188, 107, 12, 48, 215, 188, 109, + 12, 48, 207, 149, 12, 48, 248, 114, 12, 48, 247, 190, 199, 185, 219, 230, + 12, 48, 247, 190, 219, 233, 12, 48, 247, 190, 193, 66, 12, 48, 247, 190, + 232, 179, 12, 48, 234, 201, 107, 12, 48, 234, 201, 109, 12, 48, 234, 201, + 138, 12, 48, 247, 190, 234, 200, 12, 48, 229, 235, 12, 48, 247, 190, 228, + 183, 12, 48, 248, 98, 12, 48, 231, 61, 12, 48, 247, 190, 232, 236, 12, + 48, 247, 190, 248, 160, 12, 48, 247, 190, 205, 158, 12, 48, 202, 178, + 193, 95, 12, 48, 202, 178, 192, 72, 12, 48, 247, 190, 232, 99, 12, 48, + 223, 34, 233, 228, 12, 48, 247, 190, 233, 228, 12, 48, 223, 34, 198, 56, + 12, 48, 247, 190, 198, 56, 12, 48, 223, 34, 235, 111, 12, 48, 247, 190, + 235, 111, 12, 48, 197, 55, 12, 48, 223, 34, 197, 55, 12, 48, 247, 190, + 197, 55, 83, 48, 107, 83, 48, 219, 112, 83, 48, 236, 140, 83, 48, 202, + 97, 83, 48, 205, 56, 83, 48, 102, 83, 48, 109, 83, 48, 219, 141, 83, 48, + 217, 90, 83, 48, 219, 209, 83, 48, 234, 77, 83, 48, 171, 83, 48, 144, + 248, 62, 83, 48, 238, 242, 83, 48, 228, 26, 83, 48, 199, 233, 83, 48, + 211, 77, 248, 62, 83, 48, 221, 78, 83, 48, 208, 254, 83, 48, 193, 12, 83, + 48, 201, 203, 83, 48, 50, 211, 77, 248, 62, 83, 48, 229, 146, 234, 98, + 83, 48, 199, 95, 83, 48, 236, 202, 83, 48, 205, 61, 83, 48, 242, 230, 83, + 48, 208, 204, 83, 48, 251, 252, 83, 48, 215, 179, 83, 48, 234, 98, 83, + 48, 234, 207, 83, 48, 205, 91, 83, 48, 231, 3, 83, 48, 231, 4, 202, 74, + 83, 48, 233, 227, 83, 48, 248, 174, 83, 48, 193, 35, 83, 48, 243, 86, 83, + 48, 206, 133, 83, 48, 223, 158, 83, 48, 202, 70, 83, 48, 220, 29, 83, 48, + 238, 252, 83, 48, 201, 194, 83, 48, 215, 184, 83, 48, 206, 176, 83, 48, + 193, 20, 83, 48, 211, 95, 83, 48, 197, 63, 83, 48, 235, 91, 83, 48, 203, + 40, 198, 227, 83, 48, 235, 138, 242, 230, 83, 48, 179, 201, 34, 83, 48, + 105, 230, 28, 83, 48, 203, 46, 83, 48, 248, 69, 83, 48, 202, 54, 83, 48, + 248, 25, 83, 48, 201, 78, 83, 48, 229, 223, 83, 48, 230, 71, 83, 48, 236, + 144, 83, 48, 230, 53, 83, 48, 248, 47, 83, 48, 207, 136, 83, 48, 205, 74, + 83, 48, 236, 236, 83, 48, 250, 132, 83, 48, 201, 190, 83, 48, 213, 11, + 83, 48, 200, 198, 83, 48, 205, 103, 83, 48, 215, 205, 83, 48, 197, 254, + 83, 48, 220, 111, 83, 48, 201, 63, 83, 48, 237, 143, 83, 48, 193, 120, + 83, 48, 236, 175, 213, 11, 83, 48, 242, 70, 83, 48, 232, 72, 83, 48, 242, + 243, 83, 48, 201, 84, 83, 48, 193, 143, 83, 48, 232, 243, 83, 48, 242, + 239, 83, 48, 233, 66, 83, 48, 55, 192, 235, 83, 48, 132, 197, 255, 197, + 177, 83, 48, 202, 88, 83, 48, 233, 78, 83, 48, 238, 239, 83, 48, 236, + 162, 83, 48, 208, 199, 83, 48, 223, 27, 83, 48, 216, 196, 83, 48, 198, + 151, 83, 48, 200, 141, 83, 48, 219, 135, 83, 48, 196, 43, 83, 48, 233, + 21, 83, 48, 248, 102, 79, 242, 213, 83, 48, 202, 212, 83, 48, 235, 138, + 199, 87, 83, 48, 193, 89, 83, 48, 202, 107, 83, 48, 236, 222, 83, 48, + 233, 193, 83, 48, 201, 232, 83, 48, 57, 83, 48, 201, 65, 83, 48, 201, + 214, 83, 48, 198, 25, 83, 48, 230, 223, 83, 48, 247, 70, 83, 48, 201, + 107, 83, 48, 249, 103, 83, 48, 206, 245, 83, 48, 202, 185, 83, 48, 223, + 18, 83, 48, 214, 85, 83, 48, 203, 107, 83, 48, 233, 54, 83, 48, 211, 119, + 83, 48, 251, 125, 83, 48, 209, 89, 83, 48, 234, 211, 83, 48, 248, 17, 83, + 48, 216, 224, 83, 48, 216, 37, 83, 48, 204, 32, 83, 48, 250, 239, 83, 48, + 215, 199, 83, 48, 198, 61, 83, 48, 211, 64, 83, 48, 248, 106, 83, 48, + 201, 59, 83, 48, 242, 82, 83, 48, 230, 213, 83, 48, 198, 173, 83, 48, + 223, 121, 83, 48, 248, 120, 83, 48, 193, 170, 234, 98, 83, 48, 242, 212, + 83, 48, 193, 104, 83, 48, 205, 50, 83, 48, 228, 187, 83, 48, 201, 229, + 83, 48, 195, 180, 83, 48, 249, 12, 83, 48, 209, 147, 83, 48, 249, 133, + 83, 48, 203, 102, 83, 48, 207, 86, 83, 48, 206, 45, 83, 48, 232, 159, 83, + 48, 248, 104, 83, 48, 247, 85, 83, 48, 248, 144, 83, 48, 215, 201, 83, + 48, 193, 169, 83, 48, 242, 252, 83, 48, 193, 62, 83, 48, 236, 214, 83, + 48, 195, 50, 83, 48, 230, 250, 83, 48, 219, 19, 83, 48, 231, 191, 83, 48, + 215, 187, 83, 48, 202, 96, 83, 48, 203, 40, 199, 214, 248, 160, 83, 48, + 207, 149, 83, 48, 248, 114, 83, 48, 193, 2, 83, 48, 233, 103, 83, 48, + 219, 230, 83, 48, 199, 185, 219, 230, 83, 48, 219, 226, 83, 48, 202, 4, + 83, 48, 219, 233, 83, 48, 193, 66, 83, 48, 232, 179, 83, 48, 234, 200, + 83, 48, 229, 235, 83, 48, 232, 116, 83, 48, 228, 183, 83, 48, 248, 98, + 83, 48, 199, 199, 83, 48, 230, 78, 83, 48, 233, 14, 83, 48, 205, 194, + 193, 62, 83, 48, 247, 72, 83, 48, 231, 61, 83, 48, 232, 236, 83, 48, 248, + 160, 83, 48, 205, 158, 83, 48, 237, 128, 83, 48, 193, 95, 83, 48, 229, + 199, 83, 48, 192, 72, 83, 48, 216, 49, 83, 48, 248, 139, 83, 48, 234, + 110, 83, 48, 232, 99, 83, 48, 197, 222, 83, 48, 235, 94, 83, 48, 207, + 130, 83, 48, 213, 13, 83, 48, 233, 228, 83, 48, 198, 56, 83, 48, 235, + 111, 83, 48, 197, 55, 83, 48, 232, 182, 154, 237, 85, 246, 240, 45, 119, + 183, 154, 237, 85, 246, 240, 93, 119, 60, 154, 237, 85, 246, 240, 45, + 119, 82, 23, 183, 154, 237, 85, 246, 240, 93, 119, 82, 23, 60, 154, 237, + 85, 246, 240, 232, 80, 200, 168, 154, 237, 85, 246, 240, 200, 169, 232, + 98, 58, 154, 237, 85, 246, 240, 200, 169, 232, 98, 60, 154, 237, 85, 246, + 240, 200, 169, 232, 98, 219, 224, 154, 237, 85, 246, 240, 200, 169, 232, + 98, 116, 219, 224, 154, 237, 85, 246, 240, 200, 169, 232, 98, 116, 183, + 154, 237, 85, 246, 240, 200, 169, 232, 98, 110, 219, 224, 154, 237, 85, + 246, 240, 211, 3, 154, 201, 247, 154, 242, 74, 154, 232, 80, 201, 63, + 236, 211, 77, 223, 19, 223, 141, 201, 106, 113, 154, 223, 51, 77, 154, + 242, 215, 77, 154, 31, 191, 77, 45, 251, 116, 248, 53, 50, 251, 116, 248, + 53, 45, 55, 251, 116, 248, 53, 50, 55, 251, 116, 248, 53, 45, 239, 2, + 248, 53, 50, 239, 2, 248, 53, 45, 63, 239, 2, 248, 53, 50, 63, 239, 2, + 248, 53, 45, 62, 219, 187, 248, 53, 50, 62, 219, 187, 248, 53, 209, 18, + 77, 231, 130, 77, 45, 198, 42, 203, 103, 248, 53, 50, 198, 42, 203, 103, + 248, 53, 45, 63, 219, 187, 248, 53, 50, 63, 219, 187, 248, 53, 45, 63, + 198, 42, 203, 103, 248, 53, 50, 63, 198, 42, 203, 103, 248, 53, 45, 63, + 51, 248, 53, 50, 63, 51, 248, 53, 193, 139, 237, 215, 207, 18, 55, 208, + 216, 207, 252, 77, 55, 208, 216, 207, 252, 77, 130, 55, 208, 216, 207, + 252, 77, 209, 18, 87, 233, 103, 230, 25, 212, 134, 107, 230, 25, 212, + 134, 109, 230, 25, 212, 134, 138, 230, 25, 212, 134, 134, 230, 25, 212, + 134, 149, 230, 25, 212, 134, 169, 230, 25, 212, 134, 175, 230, 25, 212, + 134, 171, 230, 25, 212, 134, 178, 154, 219, 168, 163, 77, 154, 206, 180, + 163, 77, 154, 237, 95, 163, 77, 154, 234, 76, 163, 77, 30, 202, 170, 75, + 163, 77, 30, 55, 75, 163, 77, 193, 135, 237, 215, 81, 222, 86, 207, 49, + 77, 81, 222, 86, 207, 49, 4, 195, 20, 202, 5, 77, 81, 222, 86, 207, 49, + 87, 116, 230, 70, 81, 222, 86, 207, 49, 4, 195, 20, 202, 5, 87, 116, 230, + 70, 81, 222, 86, 207, 49, 87, 110, 230, 70, 47, 209, 18, 77, 154, 199, + 109, 219, 113, 233, 51, 204, 11, 113, 230, 25, 212, 134, 199, 95, 230, + 25, 212, 134, 197, 32, 230, 25, 212, 134, 198, 249, 81, 154, 223, 51, 77, + 217, 31, 77, 210, 107, 251, 153, 77, 154, 67, 223, 144, 154, 132, 233, 6, + 201, 247, 229, 120, 1, 2, 65, 229, 120, 1, 65, 229, 120, 1, 2, 68, 229, + 120, 1, 68, 229, 120, 1, 2, 66, 229, 120, 1, 66, 229, 120, 1, 2, 71, 229, + 120, 1, 71, 229, 120, 1, 2, 74, 229, 120, 1, 74, 229, 120, 1, 155, 229, + 120, 1, 231, 240, 229, 120, 1, 221, 166, 229, 120, 1, 231, 53, 229, 120, + 1, 220, 232, 229, 120, 1, 230, 179, 229, 120, 1, 222, 22, 229, 120, 1, + 231, 165, 229, 120, 1, 221, 67, 229, 120, 1, 231, 3, 229, 120, 1, 188, + 229, 120, 1, 191, 123, 229, 120, 1, 202, 222, 229, 120, 1, 191, 30, 229, + 120, 1, 201, 4, 229, 120, 1, 190, 251, 229, 120, 1, 205, 68, 229, 120, 1, + 191, 87, 229, 120, 1, 202, 46, 229, 120, 1, 191, 7, 229, 120, 1, 190, + 190, 229, 120, 1, 238, 32, 229, 120, 1, 198, 193, 229, 120, 1, 237, 44, + 229, 120, 1, 2, 197, 94, 229, 120, 1, 197, 94, 229, 120, 1, 235, 89, 229, + 120, 1, 199, 145, 229, 120, 1, 237, 146, 229, 120, 1, 159, 229, 120, 1, + 236, 174, 229, 120, 1, 180, 229, 120, 1, 213, 219, 229, 120, 1, 212, 178, + 229, 120, 1, 214, 121, 229, 120, 1, 213, 43, 229, 120, 1, 140, 229, 120, + 1, 249, 153, 229, 120, 1, 168, 229, 120, 1, 229, 158, 229, 120, 1, 248, + 188, 229, 120, 1, 209, 185, 229, 120, 1, 228, 159, 229, 120, 1, 248, 10, + 229, 120, 1, 208, 165, 229, 120, 1, 229, 245, 229, 120, 1, 249, 17, 229, + 120, 1, 210, 63, 229, 120, 1, 229, 23, 229, 120, 1, 248, 111, 229, 120, + 1, 209, 73, 229, 120, 1, 174, 229, 120, 1, 216, 100, 229, 120, 1, 215, + 155, 229, 120, 1, 216, 232, 229, 120, 1, 216, 12, 229, 120, 1, 2, 170, + 229, 120, 1, 170, 229, 120, 1, 2, 191, 225, 229, 120, 1, 191, 225, 229, + 120, 1, 2, 192, 12, 229, 120, 1, 192, 12, 229, 120, 1, 165, 229, 120, 1, + 207, 1, 229, 120, 1, 206, 68, 229, 120, 1, 207, 113, 229, 120, 1, 206, + 162, 229, 120, 1, 2, 193, 190, 229, 120, 1, 193, 190, 229, 120, 1, 193, + 86, 229, 120, 1, 193, 125, 229, 120, 1, 193, 48, 229, 120, 1, 215, 61, + 229, 120, 1, 193, 249, 229, 120, 1, 2, 155, 229, 120, 1, 2, 222, 22, 33, + 222, 48, 195, 20, 202, 5, 77, 33, 222, 48, 204, 30, 202, 5, 77, 222, 48, + 195, 20, 202, 5, 77, 222, 48, 204, 30, 202, 5, 77, 229, 120, 223, 51, 77, + 229, 120, 195, 20, 223, 51, 77, 229, 120, 237, 3, 191, 242, 222, 48, 55, + 228, 88, 72, 1, 2, 65, 72, 1, 65, 72, 1, 2, 68, 72, 1, 68, 72, 1, 2, 66, + 72, 1, 66, 72, 1, 2, 71, 72, 1, 71, 72, 1, 2, 74, 72, 1, 74, 72, 1, 155, + 72, 1, 231, 240, 72, 1, 221, 166, 72, 1, 231, 53, 72, 1, 220, 232, 72, 1, + 230, 179, 72, 1, 222, 22, 72, 1, 231, 165, 72, 1, 221, 67, 72, 1, 231, 3, + 72, 1, 188, 72, 1, 191, 123, 72, 1, 202, 222, 72, 1, 191, 30, 72, 1, 201, + 4, 72, 1, 190, 251, 72, 1, 205, 68, 72, 1, 191, 87, 72, 1, 202, 46, 72, + 1, 191, 7, 72, 1, 190, 190, 72, 1, 238, 32, 72, 1, 198, 193, 72, 1, 237, + 44, 72, 1, 2, 197, 94, 72, 1, 197, 94, 72, 1, 235, 89, 72, 1, 199, 145, + 72, 1, 237, 146, 72, 1, 159, 72, 1, 236, 174, 72, 1, 180, 72, 1, 213, + 219, 72, 1, 212, 178, 72, 1, 214, 121, 72, 1, 213, 43, 72, 1, 140, 72, 1, + 249, 153, 72, 1, 168, 72, 1, 229, 158, 72, 1, 248, 188, 72, 1, 209, 185, + 72, 1, 228, 159, 72, 1, 248, 10, 72, 1, 208, 165, 72, 1, 229, 245, 72, 1, + 249, 17, 72, 1, 210, 63, 72, 1, 229, 23, 72, 1, 248, 111, 72, 1, 209, 73, + 72, 1, 174, 72, 1, 216, 100, 72, 1, 215, 155, 72, 1, 216, 232, 72, 1, + 216, 12, 72, 1, 2, 170, 72, 1, 170, 72, 1, 2, 191, 225, 72, 1, 191, 225, + 72, 1, 2, 192, 12, 72, 1, 192, 12, 72, 1, 165, 72, 1, 207, 1, 72, 1, 206, + 68, 72, 1, 207, 113, 72, 1, 206, 162, 72, 1, 2, 193, 190, 72, 1, 193, + 190, 72, 1, 193, 86, 72, 1, 193, 125, 72, 1, 193, 48, 72, 1, 215, 61, 72, + 1, 193, 249, 72, 1, 2, 155, 72, 1, 2, 222, 22, 72, 1, 195, 188, 72, 1, + 195, 69, 72, 1, 195, 153, 72, 1, 195, 24, 72, 82, 236, 140, 222, 48, 208, + 191, 202, 5, 77, 72, 223, 51, 77, 72, 195, 20, 223, 51, 77, 72, 237, 3, + 221, 27, 248, 88, 1, 250, 120, 248, 88, 1, 210, 236, 248, 88, 1, 218, + 168, 248, 88, 1, 233, 175, 248, 88, 1, 238, 127, 248, 88, 1, 200, 43, + 248, 88, 1, 215, 61, 248, 88, 1, 172, 248, 88, 1, 232, 51, 248, 88, 1, + 222, 152, 248, 88, 1, 230, 116, 248, 88, 1, 223, 35, 248, 88, 1, 208, + 104, 248, 88, 1, 192, 235, 248, 88, 1, 191, 72, 248, 88, 1, 247, 3, 248, + 88, 1, 203, 167, 248, 88, 1, 146, 248, 88, 1, 191, 166, 248, 88, 1, 247, + 193, 248, 88, 1, 206, 8, 248, 88, 1, 65, 248, 88, 1, 74, 248, 88, 1, 71, + 248, 88, 1, 234, 173, 248, 88, 1, 251, 236, 248, 88, 1, 234, 166, 248, + 88, 1, 250, 163, 248, 88, 1, 211, 19, 248, 88, 1, 251, 132, 248, 88, 1, + 234, 103, 248, 88, 1, 251, 122, 248, 88, 1, 234, 88, 248, 88, 1, 234, 34, + 248, 88, 1, 68, 248, 88, 1, 66, 248, 88, 1, 223, 49, 248, 88, 1, 196, 12, + 248, 88, 1, 214, 70, 248, 88, 1, 231, 7, 248, 88, 1, 223, 200, 248, 88, + 1, 187, 4, 75, 58, 248, 88, 1, 213, 80, 30, 1, 221, 113, 30, 1, 201, 167, + 30, 1, 221, 106, 30, 1, 213, 204, 30, 1, 213, 202, 30, 1, 213, 201, 30, + 1, 198, 168, 30, 1, 201, 156, 30, 1, 206, 239, 30, 1, 206, 234, 30, 1, + 206, 231, 30, 1, 206, 224, 30, 1, 206, 219, 30, 1, 206, 214, 30, 1, 206, + 225, 30, 1, 206, 237, 30, 1, 216, 77, 30, 1, 209, 169, 30, 1, 201, 164, + 30, 1, 209, 158, 30, 1, 202, 160, 30, 1, 201, 161, 30, 1, 223, 222, 30, + 1, 243, 24, 30, 1, 201, 171, 30, 1, 243, 91, 30, 1, 221, 188, 30, 1, 199, + 7, 30, 1, 209, 209, 30, 1, 229, 142, 30, 1, 65, 30, 1, 252, 25, 30, 1, + 170, 30, 1, 192, 129, 30, 1, 234, 65, 30, 1, 71, 30, 1, 192, 67, 30, 1, + 192, 80, 30, 1, 74, 30, 1, 193, 190, 30, 1, 193, 176, 30, 1, 211, 151, + 30, 1, 192, 12, 30, 1, 66, 30, 1, 193, 107, 30, 1, 193, 125, 30, 1, 193, + 86, 30, 1, 191, 225, 30, 1, 233, 242, 30, 1, 192, 33, 30, 1, 68, 30, 233, + 3, 30, 1, 201, 165, 30, 1, 213, 194, 30, 1, 213, 196, 30, 1, 213, 199, + 30, 1, 206, 232, 30, 1, 206, 213, 30, 1, 206, 221, 30, 1, 206, 226, 30, + 1, 206, 211, 30, 1, 216, 70, 30, 1, 216, 67, 30, 1, 216, 71, 30, 1, 222, + 71, 30, 1, 209, 164, 30, 1, 209, 150, 30, 1, 209, 156, 30, 1, 209, 153, + 30, 1, 209, 167, 30, 1, 209, 151, 30, 1, 222, 69, 30, 1, 222, 67, 30, 1, + 202, 153, 30, 1, 202, 151, 30, 1, 202, 143, 30, 1, 202, 148, 30, 1, 202, + 158, 30, 1, 210, 149, 30, 1, 201, 168, 30, 1, 192, 57, 30, 1, 192, 51, + 30, 1, 192, 52, 30, 1, 222, 70, 30, 1, 201, 169, 30, 1, 192, 63, 30, 1, + 192, 0, 30, 1, 191, 255, 30, 1, 192, 2, 30, 1, 191, 212, 30, 1, 191, 213, + 30, 1, 191, 216, 30, 1, 251, 25, 30, 1, 251, 19, 154, 251, 96, 219, 101, + 77, 154, 251, 96, 207, 19, 77, 154, 251, 96, 91, 77, 154, 251, 96, 105, + 77, 154, 251, 96, 115, 77, 154, 251, 96, 232, 128, 77, 154, 251, 96, 198, + 54, 77, 154, 251, 96, 82, 77, 154, 251, 96, 248, 77, 77, 154, 251, 96, + 232, 238, 77, 154, 251, 96, 205, 57, 77, 154, 251, 96, 199, 1, 77, 154, + 251, 96, 232, 121, 77, 154, 251, 96, 229, 220, 77, 154, 251, 96, 234, + 208, 77, 154, 251, 96, 217, 91, 77, 248, 88, 1, 248, 10, 248, 88, 1, 191, + 30, 248, 88, 1, 222, 244, 248, 88, 1, 230, 179, 248, 88, 1, 234, 188, + 248, 88, 1, 234, 85, 248, 88, 1, 211, 87, 248, 88, 1, 211, 91, 248, 88, + 1, 223, 77, 248, 88, 1, 251, 98, 248, 88, 1, 223, 128, 248, 88, 1, 196, + 83, 248, 88, 1, 223, 180, 248, 88, 1, 214, 48, 248, 88, 1, 251, 229, 248, + 88, 1, 250, 158, 248, 88, 1, 251, 149, 248, 88, 1, 211, 113, 248, 88, 1, + 211, 94, 248, 88, 1, 223, 125, 248, 88, 53, 1, 210, 236, 248, 88, 53, 1, + 200, 43, 248, 88, 53, 1, 222, 152, 248, 88, 53, 1, 230, 116, 248, 88, 1, + 231, 92, 248, 88, 1, 219, 160, 248, 88, 1, 190, 231, 248, 88, 53, 1, 232, + 51, 248, 88, 1, 230, 136, 248, 88, 1, 220, 180, 248, 88, 1, 211, 151, + 248, 88, 1, 251, 245, 12, 201, 28, 200, 43, 12, 201, 28, 193, 98, 12, + 201, 28, 192, 209, 12, 201, 28, 247, 206, 12, 201, 28, 200, 151, 12, 201, + 28, 228, 78, 12, 201, 28, 228, 82, 12, 201, 28, 228, 169, 12, 201, 28, + 228, 79, 12, 201, 28, 200, 46, 12, 201, 28, 228, 81, 12, 201, 28, 228, + 77, 12, 201, 28, 228, 167, 12, 201, 28, 228, 80, 12, 201, 28, 228, 76, + 12, 201, 28, 215, 61, 12, 201, 28, 230, 116, 12, 201, 28, 206, 8, 12, + 201, 28, 210, 236, 12, 201, 28, 201, 250, 12, 201, 28, 238, 127, 12, 201, + 28, 228, 83, 12, 201, 28, 229, 178, 12, 201, 28, 200, 55, 12, 201, 28, + 200, 128, 12, 201, 28, 201, 118, 12, 201, 28, 203, 173, 12, 201, 28, 210, + 67, 12, 201, 28, 208, 106, 12, 201, 28, 198, 99, 12, 201, 28, 200, 45, + 12, 201, 28, 200, 140, 12, 201, 28, 228, 94, 12, 201, 28, 228, 75, 12, + 201, 28, 209, 230, 12, 201, 28, 208, 104, 72, 1, 2, 220, 232, 72, 1, 2, + 202, 222, 72, 1, 2, 201, 4, 72, 1, 2, 159, 72, 1, 2, 212, 178, 72, 1, 2, + 140, 72, 1, 2, 229, 158, 72, 1, 2, 228, 159, 72, 1, 2, 229, 245, 72, 1, + 2, 229, 23, 72, 1, 2, 215, 155, 72, 1, 2, 165, 72, 1, 2, 207, 1, 72, 1, + 2, 206, 68, 72, 1, 2, 207, 113, 72, 1, 2, 206, 162, 127, 30, 221, 113, + 127, 30, 213, 204, 127, 30, 198, 168, 127, 30, 206, 239, 127, 30, 216, + 77, 127, 30, 209, 169, 127, 30, 202, 160, 127, 30, 223, 222, 127, 30, + 243, 24, 127, 30, 243, 91, 127, 30, 221, 188, 127, 30, 199, 7, 127, 30, + 209, 209, 127, 30, 229, 142, 127, 30, 221, 114, 65, 127, 30, 213, 205, + 65, 127, 30, 198, 169, 65, 127, 30, 206, 240, 65, 127, 30, 216, 78, 65, + 127, 30, 209, 170, 65, 127, 30, 202, 161, 65, 127, 30, 223, 223, 65, 127, + 30, 243, 25, 65, 127, 30, 243, 92, 65, 127, 30, 221, 189, 65, 127, 30, + 199, 8, 65, 127, 30, 209, 210, 65, 127, 30, 229, 143, 65, 127, 30, 243, + 25, 66, 127, 221, 32, 246, 240, 211, 129, 127, 221, 32, 246, 240, 187, + 228, 159, 127, 228, 14, 107, 127, 228, 14, 109, 127, 228, 14, 138, 127, + 228, 14, 134, 127, 228, 14, 149, 127, 228, 14, 169, 127, 228, 14, 175, + 127, 228, 14, 171, 127, 228, 14, 178, 127, 228, 14, 199, 95, 127, 228, + 14, 215, 205, 127, 228, 14, 232, 243, 127, 228, 14, 193, 143, 127, 228, + 14, 193, 28, 127, 228, 14, 216, 165, 127, 228, 14, 234, 207, 127, 228, + 14, 200, 198, 127, 228, 14, 201, 66, 127, 228, 14, 229, 255, 127, 228, + 14, 202, 35, 127, 228, 14, 214, 227, 127, 228, 14, 201, 231, 127, 228, + 14, 232, 254, 127, 228, 14, 239, 50, 127, 228, 14, 220, 114, 127, 228, + 14, 207, 42, 127, 228, 14, 247, 138, 127, 228, 14, 201, 10, 127, 228, 14, + 200, 178, 127, 228, 14, 234, 75, 127, 228, 14, 207, 32, 127, 228, 14, + 251, 168, 127, 228, 14, 233, 31, 127, 228, 14, 207, 30, 127, 228, 14, + 204, 32, 127, 228, 14, 207, 108, 47, 228, 14, 208, 12, 47, 228, 14, 221, + 140, 47, 228, 14, 205, 89, 47, 228, 14, 221, 27, 47, 31, 199, 96, 211, + 105, 62, 201, 190, 47, 31, 197, 33, 211, 105, 62, 201, 190, 47, 31, 198, + 250, 211, 105, 62, 201, 190, 47, 31, 232, 136, 211, 105, 62, 201, 190, + 47, 31, 233, 16, 211, 105, 62, 201, 190, 47, 31, 202, 121, 211, 105, 62, + 201, 190, 47, 31, 203, 242, 211, 105, 62, 201, 190, 47, 31, 234, 154, + 211, 105, 62, 201, 190, 210, 103, 56, 47, 31, 197, 33, 107, 47, 31, 197, + 33, 109, 47, 31, 197, 33, 138, 47, 31, 197, 33, 134, 47, 31, 197, 33, + 149, 47, 31, 197, 33, 169, 47, 31, 197, 33, 175, 47, 31, 197, 33, 171, + 47, 31, 197, 33, 178, 47, 31, 198, 249, 47, 31, 198, 250, 107, 47, 31, + 198, 250, 109, 47, 31, 198, 250, 138, 47, 31, 198, 250, 134, 47, 31, 198, + 250, 149, 47, 30, 221, 113, 47, 30, 213, 204, 47, 30, 198, 168, 47, 30, + 206, 239, 47, 30, 216, 77, 47, 30, 209, 169, 47, 30, 202, 160, 47, 30, + 223, 222, 47, 30, 243, 24, 47, 30, 243, 91, 47, 30, 221, 188, 47, 30, + 199, 7, 47, 30, 209, 209, 47, 30, 229, 142, 47, 30, 221, 114, 65, 47, 30, + 213, 205, 65, 47, 30, 198, 169, 65, 47, 30, 206, 240, 65, 47, 30, 216, + 78, 65, 47, 30, 209, 170, 65, 47, 30, 202, 161, 65, 47, 30, 223, 223, 65, + 47, 30, 243, 25, 65, 47, 30, 243, 92, 65, 47, 30, 221, 189, 65, 47, 30, + 199, 8, 65, 47, 30, 209, 210, 65, 47, 30, 229, 143, 65, 47, 221, 32, 246, + 240, 246, 247, 47, 221, 32, 246, 240, 222, 178, 47, 30, 223, 223, 66, + 221, 32, 201, 106, 113, 47, 228, 14, 107, 47, 228, 14, 109, 47, 228, 14, + 138, 47, 228, 14, 134, 47, 228, 14, 149, 47, 228, 14, 169, 47, 228, 14, + 175, 47, 228, 14, 171, 47, 228, 14, 178, 47, 228, 14, 199, 95, 47, 228, + 14, 215, 205, 47, 228, 14, 232, 243, 47, 228, 14, 193, 143, 47, 228, 14, + 193, 28, 47, 228, 14, 216, 165, 47, 228, 14, 234, 207, 47, 228, 14, 200, + 198, 47, 228, 14, 201, 66, 47, 228, 14, 229, 255, 47, 228, 14, 202, 35, + 47, 228, 14, 214, 227, 47, 228, 14, 201, 231, 47, 228, 14, 232, 254, 47, + 228, 14, 239, 50, 47, 228, 14, 220, 114, 47, 228, 14, 205, 55, 47, 228, + 14, 217, 96, 47, 228, 14, 233, 41, 47, 228, 14, 200, 210, 47, 228, 14, + 233, 220, 47, 228, 14, 208, 211, 47, 228, 14, 250, 167, 47, 228, 14, 223, + 52, 47, 228, 14, 207, 30, 47, 228, 14, 239, 8, 47, 228, 14, 238, 251, 47, + 228, 14, 229, 135, 47, 228, 14, 247, 21, 47, 228, 14, 218, 241, 47, 228, + 14, 219, 224, 47, 228, 14, 183, 47, 228, 14, 216, 215, 47, 228, 14, 207, + 60, 47, 228, 14, 201, 10, 47, 228, 14, 200, 178, 47, 228, 14, 234, 75, + 47, 228, 14, 207, 32, 47, 228, 14, 251, 168, 47, 228, 14, 213, 190, 47, + 31, 198, 250, 169, 47, 31, 198, 250, 175, 47, 31, 198, 250, 171, 47, 31, + 198, 250, 178, 47, 31, 232, 135, 47, 31, 232, 136, 107, 47, 31, 232, 136, + 109, 47, 31, 232, 136, 138, 47, 31, 232, 136, 134, 47, 31, 232, 136, 149, + 47, 31, 232, 136, 169, 47, 31, 232, 136, 175, 47, 31, 232, 136, 171, 47, + 31, 232, 136, 178, 47, 31, 233, 15, 154, 199, 109, 16, 40, 223, 21, 154, + 199, 109, 16, 40, 233, 53, 154, 199, 109, 16, 40, 217, 58, 154, 199, 109, + 16, 40, 251, 39, 154, 199, 109, 16, 40, 217, 21, 154, 199, 109, 16, 40, + 222, 175, 154, 199, 109, 16, 40, 222, 176, 154, 199, 109, 16, 40, 250, + 159, 154, 199, 109, 16, 40, 204, 9, 154, 199, 109, 16, 40, 211, 157, 154, + 199, 109, 16, 40, 212, 255, 154, 199, 109, 16, 40, 237, 140, 51, 229, + 178, 51, 234, 30, 51, 233, 230, 219, 118, 219, 145, 56, 47, 72, 65, 47, + 72, 68, 47, 72, 66, 47, 72, 71, 47, 72, 74, 47, 72, 155, 47, 72, 221, + 166, 47, 72, 220, 232, 47, 72, 222, 22, 47, 72, 221, 67, 47, 72, 188, 47, + 72, 202, 222, 47, 72, 201, 4, 47, 72, 205, 68, 47, 72, 202, 46, 47, 72, + 190, 190, 47, 72, 198, 193, 47, 72, 197, 94, 47, 72, 199, 145, 47, 72, + 159, 47, 72, 180, 47, 72, 213, 219, 47, 72, 212, 178, 47, 72, 214, 121, + 47, 72, 213, 43, 47, 72, 140, 47, 72, 229, 158, 47, 72, 228, 159, 47, 72, + 229, 245, 47, 72, 229, 23, 47, 72, 174, 47, 72, 216, 100, 47, 72, 215, + 155, 47, 72, 216, 232, 47, 72, 216, 12, 47, 72, 170, 47, 72, 191, 225, + 47, 72, 192, 12, 47, 72, 165, 47, 72, 207, 1, 47, 72, 206, 68, 47, 72, + 207, 113, 47, 72, 206, 162, 47, 72, 193, 190, 47, 72, 193, 86, 47, 72, + 193, 125, 47, 72, 193, 48, 51, 234, 33, 214, 228, 207, 68, 51, 251, 64, + 51, 250, 221, 51, 251, 92, 51, 252, 163, 51, 223, 130, 51, 223, 97, 51, + 196, 80, 51, 234, 2, 51, 234, 185, 51, 211, 90, 51, 211, 83, 51, 222, + 100, 51, 222, 63, 51, 222, 58, 51, 231, 195, 51, 231, 205, 51, 231, 41, + 51, 231, 35, 51, 220, 144, 51, 231, 26, 51, 221, 131, 51, 221, 130, 51, + 221, 129, 51, 221, 128, 51, 230, 146, 51, 230, 145, 51, 220, 193, 51, + 220, 196, 51, 222, 9, 51, 221, 29, 51, 221, 38, 51, 205, 180, 51, 205, + 133, 51, 202, 141, 51, 204, 15, 51, 204, 14, 51, 238, 28, 51, 237, 81, + 51, 236, 141, 51, 198, 81, 51, 214, 221, 51, 213, 0, 51, 230, 75, 51, + 210, 214, 51, 210, 213, 51, 249, 150, 51, 209, 181, 51, 209, 143, 51, + 209, 144, 51, 248, 156, 51, 228, 154, 51, 228, 148, 51, 247, 221, 51, + 228, 132, 51, 229, 206, 51, 209, 241, 51, 210, 29, 51, 229, 187, 51, 210, + 25, 51, 210, 43, 51, 248, 252, 51, 209, 57, 51, 248, 84, 51, 228, 255, + 51, 209, 38, 51, 228, 246, 51, 228, 248, 51, 217, 110, 51, 217, 106, 51, + 217, 115, 51, 217, 44, 51, 217, 76, 51, 216, 56, 51, 216, 29, 51, 216, + 28, 51, 216, 203, 51, 216, 200, 51, 216, 204, 51, 192, 139, 51, 192, 137, + 51, 191, 210, 51, 206, 178, 51, 206, 182, 51, 206, 35, 51, 206, 28, 51, + 207, 57, 51, 207, 54, 51, 193, 141, 154, 199, 109, 16, 40, 228, 177, 191, + 77, 154, 199, 109, 16, 40, 228, 177, 107, 154, 199, 109, 16, 40, 228, + 177, 109, 154, 199, 109, 16, 40, 228, 177, 138, 154, 199, 109, 16, 40, + 228, 177, 134, 154, 199, 109, 16, 40, 228, 177, 149, 154, 199, 109, 16, + 40, 228, 177, 169, 154, 199, 109, 16, 40, 228, 177, 175, 154, 199, 109, + 16, 40, 228, 177, 171, 154, 199, 109, 16, 40, 228, 177, 178, 154, 199, + 109, 16, 40, 228, 177, 199, 95, 154, 199, 109, 16, 40, 228, 177, 234, + 127, 154, 199, 109, 16, 40, 228, 177, 197, 37, 154, 199, 109, 16, 40, + 228, 177, 198, 251, 154, 199, 109, 16, 40, 228, 177, 232, 122, 154, 199, + 109, 16, 40, 228, 177, 233, 19, 154, 199, 109, 16, 40, 228, 177, 202, + 130, 154, 199, 109, 16, 40, 228, 177, 203, 244, 154, 199, 109, 16, 40, + 228, 177, 234, 161, 154, 199, 109, 16, 40, 228, 177, 213, 171, 154, 199, + 109, 16, 40, 228, 177, 197, 32, 154, 199, 109, 16, 40, 228, 177, 197, 25, + 154, 199, 109, 16, 40, 228, 177, 197, 20, 154, 199, 109, 16, 40, 228, + 177, 197, 22, 154, 199, 109, 16, 40, 228, 177, 197, 27, 51, 228, 168, 51, + 238, 32, 51, 250, 163, 51, 164, 51, 211, 9, 51, 210, 68, 51, 236, 177, + 51, 236, 178, 201, 189, 51, 236, 178, 238, 189, 51, 223, 49, 51, 234, 33, + 214, 228, 229, 207, 51, 234, 33, 214, 228, 200, 66, 51, 234, 33, 214, + 228, 199, 212, 51, 234, 33, 214, 228, 216, 199, 51, 238, 253, 51, 210, + 221, 251, 135, 51, 180, 51, 215, 156, 65, 51, 174, 51, 155, 51, 222, 25, + 51, 217, 16, 51, 231, 183, 51, 247, 144, 51, 222, 24, 51, 209, 231, 51, + 214, 72, 51, 215, 156, 233, 175, 51, 215, 156, 232, 51, 51, 216, 141, 51, + 221, 217, 51, 228, 83, 51, 221, 168, 51, 216, 102, 51, 231, 55, 51, 198, + 195, 51, 215, 156, 172, 51, 216, 20, 51, 236, 187, 51, 221, 95, 51, 232, + 177, 51, 213, 81, 51, 215, 156, 218, 168, 51, 216, 17, 51, 242, 199, 51, + 221, 81, 51, 216, 18, 201, 189, 51, 242, 200, 201, 189, 51, 218, 169, + 201, 189, 51, 221, 82, 201, 189, 51, 216, 18, 238, 189, 51, 242, 200, + 238, 189, 51, 218, 169, 238, 189, 51, 221, 82, 238, 189, 51, 218, 169, + 139, 206, 8, 51, 218, 169, 139, 206, 9, 201, 189, 51, 168, 51, 221, 21, + 51, 215, 166, 51, 230, 229, 51, 207, 168, 51, 207, 169, 139, 206, 8, 51, + 207, 169, 139, 206, 9, 201, 189, 51, 208, 178, 51, 212, 219, 51, 215, + 156, 206, 8, 51, 215, 158, 51, 208, 124, 51, 212, 112, 51, 215, 156, 196, + 12, 51, 215, 87, 51, 220, 182, 51, 215, 88, 216, 203, 51, 208, 123, 51, + 212, 111, 51, 215, 156, 193, 224, 51, 215, 81, 51, 220, 180, 51, 215, 82, + 216, 203, 51, 222, 153, 211, 134, 51, 218, 169, 211, 134, 51, 251, 149, + 51, 248, 57, 51, 247, 66, 51, 247, 43, 51, 247, 194, 139, 221, 217, 51, + 242, 99, 51, 237, 200, 51, 230, 129, 51, 140, 51, 228, 169, 51, 223, 162, + 51, 221, 102, 51, 221, 82, 247, 110, 51, 220, 234, 51, 219, 46, 51, 219, + 45, 51, 219, 30, 51, 218, 184, 51, 217, 17, 202, 70, 51, 216, 55, 51, + 215, 233, 51, 209, 229, 51, 209, 76, 51, 208, 249, 51, 208, 247, 51, 201, + 180, 51, 200, 158, 51, 193, 127, 51, 196, 13, 139, 218, 168, 51, 42, 139, + 218, 168, 154, 199, 109, 16, 40, 237, 204, 107, 154, 199, 109, 16, 40, + 237, 204, 109, 154, 199, 109, 16, 40, 237, 204, 138, 154, 199, 109, 16, + 40, 237, 204, 134, 154, 199, 109, 16, 40, 237, 204, 149, 154, 199, 109, + 16, 40, 237, 204, 169, 154, 199, 109, 16, 40, 237, 204, 175, 154, 199, + 109, 16, 40, 237, 204, 171, 154, 199, 109, 16, 40, 237, 204, 178, 154, + 199, 109, 16, 40, 237, 204, 199, 95, 154, 199, 109, 16, 40, 237, 204, + 234, 127, 154, 199, 109, 16, 40, 237, 204, 197, 37, 154, 199, 109, 16, + 40, 237, 204, 198, 251, 154, 199, 109, 16, 40, 237, 204, 232, 122, 154, + 199, 109, 16, 40, 237, 204, 233, 19, 154, 199, 109, 16, 40, 237, 204, + 202, 130, 154, 199, 109, 16, 40, 237, 204, 203, 244, 154, 199, 109, 16, + 40, 237, 204, 234, 161, 154, 199, 109, 16, 40, 237, 204, 213, 171, 154, + 199, 109, 16, 40, 237, 204, 197, 32, 154, 199, 109, 16, 40, 237, 204, + 197, 25, 154, 199, 109, 16, 40, 237, 204, 197, 20, 154, 199, 109, 16, 40, + 237, 204, 197, 22, 154, 199, 109, 16, 40, 237, 204, 197, 27, 154, 199, + 109, 16, 40, 237, 204, 197, 28, 154, 199, 109, 16, 40, 237, 204, 197, 23, + 154, 199, 109, 16, 40, 237, 204, 197, 24, 154, 199, 109, 16, 40, 237, + 204, 197, 31, 154, 199, 109, 16, 40, 237, 204, 197, 26, 154, 199, 109, + 16, 40, 237, 204, 198, 249, 154, 199, 109, 16, 40, 237, 204, 198, 247, + 51, 231, 222, 229, 181, 40, 199, 34, 238, 231, 229, 219, 229, 181, 40, + 199, 34, 207, 100, 234, 207, 229, 181, 40, 237, 14, 250, 183, 199, 34, + 248, 247, 229, 181, 40, 191, 238, 232, 168, 229, 181, 40, 193, 171, 229, + 181, 40, 239, 53, 229, 181, 40, 199, 34, 250, 246, 229, 181, 40, 229, 6, + 198, 87, 229, 181, 40, 2, 199, 194, 229, 181, 40, 198, 1, 229, 181, 40, + 210, 60, 229, 181, 40, 201, 104, 229, 181, 40, 233, 43, 229, 181, 40, + 230, 206, 209, 21, 229, 181, 40, 215, 254, 229, 181, 40, 234, 74, 229, + 181, 40, 232, 169, 229, 181, 40, 193, 21, 211, 105, 199, 34, 237, 141, + 229, 181, 40, 251, 43, 229, 181, 40, 239, 31, 229, 181, 40, 248, 145, + 198, 215, 229, 181, 40, 230, 227, 229, 181, 40, 201, 208, 251, 63, 229, + 181, 40, 207, 22, 229, 181, 40, 223, 124, 229, 181, 40, 230, 206, 199, + 194, 229, 181, 40, 215, 180, 239, 0, 229, 181, 40, 230, 206, 208, 224, + 229, 181, 40, 199, 34, 252, 65, 193, 143, 229, 181, 40, 199, 34, 242, + 227, 232, 243, 229, 181, 40, 223, 138, 229, 181, 40, 235, 64, 229, 181, + 40, 207, 25, 229, 181, 40, 230, 206, 208, 254, 229, 181, 40, 208, 197, + 229, 181, 40, 237, 220, 79, 199, 34, 219, 132, 229, 181, 40, 199, 34, + 233, 81, 229, 181, 40, 211, 62, 229, 181, 40, 211, 167, 229, 181, 40, + 237, 111, 229, 181, 40, 237, 133, 229, 181, 40, 223, 153, 229, 181, 40, + 248, 41, 229, 181, 40, 242, 76, 119, 216, 206, 229, 181, 40, 231, 190, + 198, 87, 229, 181, 40, 208, 135, 196, 67, 229, 181, 40, 211, 61, 229, + 181, 40, 199, 34, 193, 109, 229, 181, 40, 207, 13, 229, 181, 40, 199, 34, + 247, 72, 229, 181, 40, 199, 34, 250, 242, 198, 209, 229, 181, 40, 199, + 34, 222, 10, 201, 70, 215, 184, 229, 181, 40, 237, 76, 229, 181, 40, 199, + 34, 217, 47, 217, 111, 229, 181, 40, 252, 66, 229, 181, 40, 199, 34, 193, + 161, 229, 181, 40, 199, 34, 231, 145, 193, 66, 229, 181, 40, 199, 34, + 222, 184, 220, 43, 229, 181, 40, 236, 219, 229, 181, 40, 219, 119, 229, + 181, 40, 223, 127, 197, 176, 229, 181, 40, 2, 208, 224, 229, 181, 40, + 251, 254, 242, 66, 229, 181, 40, 248, 250, 242, 66, 11, 5, 223, 53, 11, + 5, 223, 45, 11, 5, 68, 11, 5, 223, 80, 11, 5, 223, 224, 11, 5, 223, 207, + 11, 5, 223, 226, 11, 5, 223, 225, 11, 5, 250, 182, 11, 5, 250, 133, 11, + 5, 65, 11, 5, 251, 65, 11, 5, 196, 78, 11, 5, 196, 82, 11, 5, 196, 79, + 11, 5, 211, 30, 11, 5, 210, 247, 11, 5, 74, 11, 5, 211, 78, 11, 5, 233, + 221, 11, 5, 71, 11, 5, 193, 0, 11, 5, 248, 148, 11, 5, 248, 143, 11, 5, + 248, 188, 11, 5, 248, 161, 11, 5, 248, 177, 11, 5, 248, 176, 11, 5, 248, + 179, 11, 5, 248, 178, 11, 5, 249, 64, 11, 5, 249, 56, 11, 5, 249, 153, + 11, 5, 249, 89, 11, 5, 247, 234, 11, 5, 247, 238, 11, 5, 247, 235, 11, 5, + 248, 81, 11, 5, 248, 62, 11, 5, 248, 111, 11, 5, 248, 89, 11, 5, 248, + 206, 11, 5, 249, 17, 11, 5, 248, 219, 11, 5, 247, 217, 11, 5, 247, 211, + 11, 5, 248, 10, 11, 5, 247, 232, 11, 5, 247, 225, 11, 5, 247, 230, 11, 5, + 247, 199, 11, 5, 247, 197, 11, 5, 247, 204, 11, 5, 247, 202, 11, 5, 247, + 200, 11, 5, 247, 201, 11, 5, 209, 117, 11, 5, 209, 113, 11, 5, 209, 185, + 11, 5, 209, 129, 11, 5, 209, 149, 11, 5, 209, 176, 11, 5, 209, 172, 11, + 5, 210, 89, 11, 5, 210, 73, 11, 5, 168, 11, 5, 210, 137, 11, 5, 208, 145, + 11, 5, 208, 147, 11, 5, 208, 146, 11, 5, 209, 14, 11, 5, 208, 252, 11, 5, + 209, 73, 11, 5, 209, 33, 11, 5, 208, 131, 11, 5, 208, 126, 11, 5, 208, + 165, 11, 5, 208, 144, 11, 5, 208, 136, 11, 5, 208, 142, 11, 5, 208, 108, + 11, 5, 208, 107, 11, 5, 208, 112, 11, 5, 208, 111, 11, 5, 208, 109, 11, + 5, 208, 110, 11, 5, 249, 38, 11, 5, 249, 37, 11, 5, 249, 44, 11, 5, 249, + 39, 11, 5, 249, 41, 11, 5, 249, 40, 11, 5, 249, 43, 11, 5, 249, 42, 11, + 5, 249, 50, 11, 5, 249, 49, 11, 5, 249, 53, 11, 5, 249, 51, 11, 5, 249, + 29, 11, 5, 249, 31, 11, 5, 249, 30, 11, 5, 249, 34, 11, 5, 249, 33, 11, + 5, 249, 36, 11, 5, 249, 35, 11, 5, 249, 45, 11, 5, 249, 48, 11, 5, 249, + 46, 11, 5, 249, 25, 11, 5, 249, 24, 11, 5, 249, 32, 11, 5, 249, 28, 11, + 5, 249, 26, 11, 5, 249, 27, 11, 5, 249, 21, 11, 5, 249, 20, 11, 5, 249, + 23, 11, 5, 249, 22, 11, 5, 214, 185, 11, 5, 214, 184, 11, 5, 214, 190, + 11, 5, 214, 186, 11, 5, 214, 187, 11, 5, 214, 189, 11, 5, 214, 188, 11, + 5, 214, 193, 11, 5, 214, 192, 11, 5, 214, 195, 11, 5, 214, 194, 11, 5, + 214, 181, 11, 5, 214, 180, 11, 5, 214, 183, 11, 5, 214, 182, 11, 5, 214, + 174, 11, 5, 214, 173, 11, 5, 214, 178, 11, 5, 214, 177, 11, 5, 214, 175, + 11, 5, 214, 176, 11, 5, 214, 168, 11, 5, 214, 167, 11, 5, 214, 172, 11, + 5, 214, 171, 11, 5, 214, 169, 11, 5, 214, 170, 11, 5, 229, 67, 11, 5, + 229, 66, 11, 5, 229, 72, 11, 5, 229, 68, 11, 5, 229, 69, 11, 5, 229, 71, + 11, 5, 229, 70, 11, 5, 229, 75, 11, 5, 229, 74, 11, 5, 229, 77, 11, 5, + 229, 76, 11, 5, 229, 58, 11, 5, 229, 60, 11, 5, 229, 59, 11, 5, 229, 63, + 11, 5, 229, 62, 11, 5, 229, 65, 11, 5, 229, 64, 11, 5, 229, 54, 11, 5, + 229, 53, 11, 5, 229, 61, 11, 5, 229, 57, 11, 5, 229, 55, 11, 5, 229, 56, + 11, 5, 229, 48, 11, 5, 229, 52, 11, 5, 229, 51, 11, 5, 229, 49, 11, 5, + 229, 50, 11, 5, 216, 23, 11, 5, 216, 22, 11, 5, 216, 100, 11, 5, 216, 31, + 11, 5, 216, 63, 11, 5, 216, 81, 11, 5, 216, 79, 11, 5, 217, 30, 11, 5, + 217, 24, 11, 5, 174, 11, 5, 217, 71, 11, 5, 215, 115, 11, 5, 215, 114, + 11, 5, 215, 118, 11, 5, 215, 116, 11, 5, 215, 195, 11, 5, 215, 168, 11, + 5, 216, 12, 11, 5, 215, 202, 11, 5, 216, 152, 11, 5, 216, 232, 11, 5, + 215, 95, 11, 5, 215, 89, 11, 5, 215, 155, 11, 5, 215, 111, 11, 5, 215, + 104, 11, 5, 215, 109, 11, 5, 215, 65, 11, 5, 215, 64, 11, 5, 215, 70, 11, + 5, 215, 67, 11, 5, 232, 229, 11, 5, 232, 222, 11, 5, 233, 23, 11, 5, 232, + 245, 11, 5, 233, 72, 11, 5, 233, 63, 11, 5, 233, 109, 11, 5, 233, 77, 11, + 5, 232, 119, 11, 5, 232, 175, 11, 5, 232, 154, 11, 5, 232, 68, 11, 5, + 232, 67, 11, 5, 232, 86, 11, 5, 232, 73, 11, 5, 232, 71, 11, 5, 232, 72, + 11, 5, 232, 54, 11, 5, 232, 53, 11, 5, 232, 57, 11, 5, 232, 55, 11, 5, + 195, 32, 11, 5, 195, 26, 11, 5, 195, 69, 11, 5, 195, 41, 11, 5, 195, 58, + 11, 5, 195, 53, 11, 5, 195, 61, 11, 5, 195, 60, 11, 5, 195, 162, 11, 5, + 195, 157, 11, 5, 195, 188, 11, 5, 195, 175, 11, 5, 195, 4, 11, 5, 195, 0, + 11, 5, 195, 24, 11, 5, 195, 6, 11, 5, 195, 73, 11, 5, 195, 141, 11, 5, + 193, 242, 11, 5, 193, 240, 11, 5, 193, 249, 11, 5, 193, 245, 11, 5, 193, + 243, 11, 5, 193, 244, 11, 5, 193, 229, 11, 5, 193, 228, 11, 5, 193, 235, + 11, 5, 193, 234, 11, 5, 193, 232, 11, 5, 193, 233, 11, 5, 236, 212, 11, + 5, 236, 197, 11, 5, 237, 44, 11, 5, 236, 240, 11, 5, 237, 19, 11, 5, 237, + 24, 11, 5, 237, 23, 11, 5, 237, 211, 11, 5, 237, 205, 11, 5, 238, 32, 11, + 5, 237, 231, 11, 5, 235, 69, 11, 5, 235, 70, 11, 5, 236, 140, 11, 5, 235, + 117, 11, 5, 236, 174, 11, 5, 236, 143, 11, 5, 237, 74, 11, 5, 237, 146, + 11, 5, 237, 96, 11, 5, 235, 60, 11, 5, 235, 58, 11, 5, 235, 89, 11, 5, + 235, 68, 11, 5, 235, 63, 11, 5, 235, 66, 11, 5, 198, 125, 11, 5, 198, + 117, 11, 5, 198, 193, 11, 5, 198, 135, 11, 5, 198, 176, 11, 5, 198, 178, + 11, 5, 198, 177, 11, 5, 199, 171, 11, 5, 199, 156, 11, 5, 190, 190, 11, + 5, 199, 183, 11, 5, 197, 69, 11, 5, 197, 68, 11, 5, 197, 71, 11, 5, 197, + 70, 11, 5, 198, 40, 11, 5, 198, 29, 11, 5, 159, 11, 5, 198, 53, 11, 5, + 199, 55, 11, 5, 199, 145, 11, 5, 199, 82, 11, 5, 197, 52, 11, 5, 197, 47, + 11, 5, 197, 94, 11, 5, 197, 67, 11, 5, 197, 53, 11, 5, 197, 64, 11, 5, + 237, 163, 11, 5, 237, 162, 11, 5, 237, 168, 11, 5, 237, 164, 11, 5, 237, + 165, 11, 5, 237, 167, 11, 5, 237, 166, 11, 5, 237, 184, 11, 5, 237, 183, + 11, 5, 237, 191, 11, 5, 237, 185, 11, 5, 237, 153, 11, 5, 237, 155, 11, + 5, 237, 154, 11, 5, 237, 158, 11, 5, 237, 157, 11, 5, 237, 161, 11, 5, + 237, 159, 11, 5, 237, 176, 11, 5, 237, 179, 11, 5, 237, 177, 11, 5, 237, + 149, 11, 5, 237, 148, 11, 5, 237, 156, 11, 5, 237, 152, 11, 5, 237, 150, + 11, 5, 237, 151, 11, 5, 214, 140, 11, 5, 214, 139, 11, 5, 214, 147, 11, + 5, 214, 142, 11, 5, 214, 143, 11, 5, 214, 144, 11, 5, 214, 156, 11, 5, + 214, 155, 11, 5, 214, 162, 11, 5, 214, 157, 11, 5, 214, 132, 11, 5, 214, + 131, 11, 5, 214, 138, 11, 5, 214, 133, 11, 5, 214, 148, 11, 5, 214, 154, + 11, 5, 214, 152, 11, 5, 214, 124, 11, 5, 214, 123, 11, 5, 214, 129, 11, + 5, 214, 127, 11, 5, 214, 125, 11, 5, 214, 126, 11, 5, 229, 33, 11, 5, + 229, 32, 11, 5, 229, 39, 11, 5, 229, 34, 11, 5, 229, 36, 11, 5, 229, 35, + 11, 5, 229, 38, 11, 5, 229, 37, 11, 5, 229, 45, 11, 5, 229, 43, 11, 5, + 229, 47, 11, 5, 229, 46, 11, 5, 229, 26, 11, 5, 229, 27, 11, 5, 229, 30, + 11, 5, 229, 29, 11, 5, 229, 31, 11, 5, 229, 40, 11, 5, 229, 42, 11, 5, + 229, 41, 11, 5, 229, 25, 11, 5, 213, 162, 11, 5, 213, 160, 11, 5, 213, + 219, 11, 5, 213, 165, 11, 5, 213, 193, 11, 5, 213, 207, 11, 5, 213, 206, + 11, 5, 214, 200, 11, 5, 180, 11, 5, 214, 218, 11, 5, 212, 122, 11, 5, + 212, 124, 11, 5, 212, 123, 11, 5, 213, 11, 11, 5, 212, 251, 11, 5, 213, + 43, 11, 5, 213, 22, 11, 5, 214, 74, 11, 5, 214, 121, 11, 5, 214, 97, 11, + 5, 212, 117, 11, 5, 212, 113, 11, 5, 212, 178, 11, 5, 212, 121, 11, 5, + 212, 119, 11, 5, 212, 120, 11, 5, 229, 98, 11, 5, 229, 97, 11, 5, 229, + 103, 11, 5, 229, 99, 11, 5, 229, 100, 11, 5, 229, 102, 11, 5, 229, 101, + 11, 5, 229, 109, 11, 5, 229, 107, 11, 5, 229, 111, 11, 5, 229, 110, 11, + 5, 229, 90, 11, 5, 229, 92, 11, 5, 229, 91, 11, 5, 229, 94, 11, 5, 229, + 96, 11, 5, 229, 95, 11, 5, 229, 104, 11, 5, 229, 106, 11, 5, 229, 105, + 11, 5, 229, 86, 11, 5, 229, 85, 11, 5, 229, 93, 11, 5, 229, 89, 11, 5, + 229, 87, 11, 5, 229, 88, 11, 5, 229, 80, 11, 5, 229, 79, 11, 5, 229, 84, + 11, 5, 229, 83, 11, 5, 229, 81, 11, 5, 229, 82, 11, 5, 219, 87, 11, 5, + 219, 79, 11, 5, 219, 146, 11, 5, 219, 98, 11, 5, 219, 137, 11, 5, 219, + 136, 11, 5, 219, 140, 11, 5, 219, 138, 11, 5, 220, 5, 11, 5, 219, 249, + 11, 5, 173, 11, 5, 220, 16, 11, 5, 218, 201, 11, 5, 218, 200, 11, 5, 218, + 203, 11, 5, 218, 202, 11, 5, 218, 249, 11, 5, 218, 234, 11, 5, 219, 43, + 11, 5, 219, 1, 11, 5, 219, 164, 11, 5, 219, 238, 11, 5, 219, 184, 11, 5, + 218, 195, 11, 5, 218, 193, 11, 5, 218, 225, 11, 5, 218, 199, 11, 5, 218, + 197, 11, 5, 218, 198, 11, 5, 218, 173, 11, 5, 218, 172, 11, 5, 218, 183, + 11, 5, 218, 176, 11, 5, 218, 174, 11, 5, 218, 175, 11, 5, 231, 22, 11, 5, + 231, 21, 11, 5, 231, 53, 11, 5, 231, 34, 11, 5, 231, 45, 11, 5, 231, 44, + 11, 5, 231, 47, 11, 5, 231, 46, 11, 5, 231, 192, 11, 5, 231, 187, 11, 5, + 231, 240, 11, 5, 231, 203, 11, 5, 230, 152, 11, 5, 230, 151, 11, 5, 230, + 154, 11, 5, 230, 153, 11, 5, 230, 232, 11, 5, 230, 230, 11, 5, 231, 3, + 11, 5, 230, 242, 11, 5, 231, 131, 11, 5, 231, 129, 11, 5, 231, 165, 11, + 5, 231, 142, 11, 5, 230, 140, 11, 5, 230, 139, 11, 5, 230, 179, 11, 5, + 230, 150, 11, 5, 230, 141, 11, 5, 230, 149, 11, 5, 221, 120, 11, 5, 221, + 115, 11, 5, 221, 166, 11, 5, 221, 134, 11, 5, 221, 147, 11, 5, 221, 151, + 11, 5, 221, 149, 11, 5, 222, 49, 11, 5, 222, 30, 11, 5, 155, 11, 5, 222, + 78, 11, 5, 220, 202, 11, 5, 220, 207, 11, 5, 220, 204, 11, 5, 221, 28, + 11, 5, 221, 23, 11, 5, 221, 67, 11, 5, 221, 36, 11, 5, 221, 241, 11, 5, + 221, 224, 11, 5, 222, 22, 11, 5, 221, 245, 11, 5, 220, 188, 11, 5, 220, + 184, 11, 5, 220, 232, 11, 5, 220, 201, 11, 5, 220, 192, 11, 5, 220, 197, + 11, 5, 231, 113, 11, 5, 231, 112, 11, 5, 231, 117, 11, 5, 231, 114, 11, + 5, 231, 116, 11, 5, 231, 115, 11, 5, 231, 124, 11, 5, 231, 123, 11, 5, + 231, 127, 11, 5, 231, 125, 11, 5, 231, 104, 11, 5, 231, 103, 11, 5, 231, + 106, 11, 5, 231, 105, 11, 5, 231, 109, 11, 5, 231, 108, 11, 5, 231, 111, + 11, 5, 231, 110, 11, 5, 231, 119, 11, 5, 231, 118, 11, 5, 231, 122, 11, + 5, 231, 120, 11, 5, 231, 99, 11, 5, 231, 98, 11, 5, 231, 107, 11, 5, 231, + 102, 11, 5, 231, 100, 11, 5, 231, 101, 11, 5, 216, 119, 11, 5, 216, 120, + 11, 5, 216, 138, 11, 5, 216, 137, 11, 5, 216, 140, 11, 5, 216, 139, 11, + 5, 216, 110, 11, 5, 216, 112, 11, 5, 216, 111, 11, 5, 216, 115, 11, 5, + 216, 114, 11, 5, 216, 117, 11, 5, 216, 116, 11, 5, 216, 121, 11, 5, 216, + 123, 11, 5, 216, 122, 11, 5, 216, 106, 11, 5, 216, 105, 11, 5, 216, 113, + 11, 5, 216, 109, 11, 5, 216, 107, 11, 5, 216, 108, 11, 5, 228, 104, 11, + 5, 228, 103, 11, 5, 228, 110, 11, 5, 228, 105, 11, 5, 228, 107, 11, 5, + 228, 106, 11, 5, 228, 109, 11, 5, 228, 108, 11, 5, 228, 115, 11, 5, 228, + 114, 11, 5, 228, 117, 11, 5, 228, 116, 11, 5, 228, 96, 11, 5, 228, 95, + 11, 5, 228, 98, 11, 5, 228, 97, 11, 5, 228, 100, 11, 5, 228, 99, 11, 5, + 228, 102, 11, 5, 228, 101, 11, 5, 228, 111, 11, 5, 228, 113, 11, 5, 228, + 112, 11, 5, 214, 13, 11, 5, 214, 15, 11, 5, 214, 14, 11, 5, 214, 58, 11, + 5, 214, 56, 11, 5, 214, 68, 11, 5, 214, 61, 11, 5, 213, 230, 11, 5, 213, + 229, 11, 5, 213, 231, 11, 5, 213, 241, 11, 5, 213, 238, 11, 5, 213, 249, + 11, 5, 213, 243, 11, 5, 214, 49, 11, 5, 214, 55, 11, 5, 214, 51, 11, 5, + 229, 117, 11, 5, 229, 136, 11, 5, 229, 145, 11, 5, 230, 9, 11, 5, 229, + 253, 11, 5, 140, 11, 5, 230, 21, 11, 5, 228, 134, 11, 5, 228, 133, 11, 5, + 228, 136, 11, 5, 228, 135, 11, 5, 228, 180, 11, 5, 228, 171, 11, 5, 229, + 23, 11, 5, 228, 244, 11, 5, 229, 183, 11, 5, 229, 245, 11, 5, 229, 195, + 11, 5, 193, 146, 11, 5, 193, 131, 11, 5, 193, 190, 11, 5, 193, 158, 11, + 5, 192, 245, 11, 5, 192, 247, 11, 5, 192, 246, 11, 5, 193, 13, 11, 5, + 193, 48, 11, 5, 193, 24, 11, 5, 193, 99, 11, 5, 193, 125, 11, 5, 193, + 106, 11, 5, 191, 15, 11, 5, 191, 14, 11, 5, 191, 30, 11, 5, 191, 18, 11, + 5, 191, 23, 11, 5, 191, 25, 11, 5, 191, 24, 11, 5, 191, 96, 11, 5, 191, + 93, 11, 5, 191, 123, 11, 5, 191, 104, 11, 5, 190, 244, 11, 5, 190, 246, + 11, 5, 190, 245, 11, 5, 191, 2, 11, 5, 191, 1, 11, 5, 191, 7, 11, 5, 191, + 3, 11, 5, 191, 73, 11, 5, 191, 87, 11, 5, 191, 79, 11, 5, 190, 240, 11, + 5, 190, 239, 11, 5, 190, 251, 11, 5, 190, 243, 11, 5, 190, 241, 11, 5, + 190, 242, 11, 5, 190, 226, 11, 5, 190, 225, 11, 5, 190, 231, 11, 5, 190, + 229, 11, 5, 190, 227, 11, 5, 190, 228, 11, 5, 242, 255, 11, 5, 242, 248, + 11, 5, 243, 29, 11, 5, 243, 12, 11, 5, 243, 26, 11, 5, 243, 20, 11, 5, + 243, 28, 11, 5, 243, 27, 11, 5, 247, 78, 11, 5, 247, 69, 11, 5, 247, 160, + 11, 5, 247, 111, 11, 5, 238, 183, 11, 5, 238, 185, 11, 5, 238, 184, 11, + 5, 238, 249, 11, 5, 238, 237, 11, 5, 242, 99, 11, 5, 239, 13, 11, 5, 247, + 5, 11, 5, 247, 42, 11, 5, 247, 11, 11, 5, 238, 154, 11, 5, 238, 152, 11, + 5, 238, 195, 11, 5, 238, 181, 11, 5, 238, 160, 11, 5, 238, 176, 11, 5, + 238, 130, 11, 5, 238, 129, 11, 5, 238, 143, 11, 5, 238, 137, 11, 5, 238, + 131, 11, 5, 238, 133, 11, 5, 190, 209, 11, 5, 190, 208, 11, 5, 190, 215, + 11, 5, 190, 210, 11, 5, 190, 212, 11, 5, 190, 211, 11, 5, 190, 214, 11, + 5, 190, 213, 11, 5, 190, 221, 11, 5, 190, 220, 11, 5, 190, 224, 11, 5, + 190, 222, 11, 5, 190, 205, 11, 5, 190, 207, 11, 5, 190, 206, 11, 5, 190, + 216, 11, 5, 190, 219, 11, 5, 190, 217, 11, 5, 190, 198, 11, 5, 190, 202, + 11, 5, 190, 201, 11, 5, 190, 199, 11, 5, 190, 200, 11, 5, 190, 192, 11, + 5, 190, 191, 11, 5, 190, 197, 11, 5, 190, 195, 11, 5, 190, 193, 11, 5, + 190, 194, 11, 5, 212, 33, 11, 5, 212, 32, 11, 5, 212, 38, 11, 5, 212, 34, + 11, 5, 212, 35, 11, 5, 212, 37, 11, 5, 212, 36, 11, 5, 212, 43, 11, 5, + 212, 42, 11, 5, 212, 46, 11, 5, 212, 45, 11, 5, 212, 26, 11, 5, 212, 27, + 11, 5, 212, 30, 11, 5, 212, 31, 11, 5, 212, 39, 11, 5, 212, 41, 11, 5, + 212, 21, 11, 5, 212, 29, 11, 5, 212, 25, 11, 5, 212, 22, 11, 5, 212, 23, + 11, 5, 212, 16, 11, 5, 212, 15, 11, 5, 212, 20, 11, 5, 212, 19, 11, 5, + 212, 17, 11, 5, 212, 18, 11, 5, 202, 138, 11, 5, 169, 11, 5, 202, 222, + 11, 5, 202, 142, 11, 5, 202, 202, 11, 5, 202, 205, 11, 5, 202, 203, 11, + 5, 205, 122, 11, 5, 205, 106, 11, 5, 188, 11, 5, 205, 130, 11, 5, 200, + 188, 11, 5, 200, 190, 11, 5, 200, 189, 11, 5, 202, 8, 11, 5, 201, 253, + 11, 5, 202, 46, 11, 5, 202, 14, 11, 5, 203, 238, 11, 5, 205, 68, 11, 5, + 204, 13, 11, 5, 200, 163, 11, 5, 200, 159, 11, 5, 201, 4, 11, 5, 200, + 187, 11, 5, 200, 167, 11, 5, 200, 175, 11, 5, 200, 57, 11, 5, 200, 56, + 11, 5, 200, 127, 11, 5, 200, 65, 11, 5, 200, 59, 11, 5, 200, 64, 11, 5, + 201, 136, 11, 5, 201, 135, 11, 5, 201, 142, 11, 5, 201, 137, 11, 5, 201, + 139, 11, 5, 201, 141, 11, 5, 201, 140, 11, 5, 201, 151, 11, 5, 201, 149, + 11, 5, 201, 175, 11, 5, 201, 152, 11, 5, 201, 131, 11, 5, 201, 130, 11, + 5, 201, 134, 11, 5, 201, 132, 11, 5, 201, 145, 11, 5, 201, 148, 11, 5, + 201, 146, 11, 5, 201, 127, 11, 5, 201, 125, 11, 5, 201, 129, 11, 5, 201, + 128, 11, 5, 201, 120, 11, 5, 201, 119, 11, 5, 201, 124, 11, 5, 201, 123, + 11, 5, 201, 121, 11, 5, 201, 122, 11, 5, 191, 66, 11, 5, 191, 65, 11, 5, + 191, 71, 11, 5, 191, 68, 11, 5, 191, 45, 11, 5, 191, 47, 11, 5, 191, 46, + 11, 5, 191, 50, 11, 5, 191, 49, 11, 5, 191, 54, 11, 5, 191, 51, 11, 5, + 191, 59, 11, 5, 191, 58, 11, 5, 191, 62, 11, 5, 191, 60, 11, 5, 191, 41, + 11, 5, 191, 40, 11, 5, 191, 48, 11, 5, 191, 44, 11, 5, 191, 42, 11, 5, + 191, 43, 11, 5, 191, 33, 11, 5, 191, 32, 11, 5, 191, 37, 11, 5, 191, 36, + 11, 5, 191, 34, 11, 5, 191, 35, 11, 5, 243, 133, 11, 5, 243, 129, 11, 5, + 247, 1, 11, 5, 246, 243, 11, 5, 243, 44, 11, 5, 243, 43, 11, 5, 243, 46, + 11, 5, 243, 45, 11, 5, 243, 59, 11, 5, 243, 58, 11, 5, 243, 68, 11, 5, + 243, 63, 11, 5, 243, 102, 11, 5, 243, 99, 11, 5, 243, 127, 11, 5, 243, + 110, 11, 5, 243, 38, 11, 5, 243, 48, 11, 5, 243, 42, 11, 5, 243, 39, 11, + 5, 243, 41, 11, 5, 243, 31, 11, 5, 243, 30, 11, 5, 243, 35, 11, 5, 243, + 34, 11, 5, 243, 32, 11, 5, 243, 33, 11, 5, 206, 105, 11, 5, 206, 109, 11, + 5, 206, 87, 11, 5, 206, 88, 11, 5, 206, 92, 11, 5, 206, 91, 11, 5, 206, + 95, 11, 5, 206, 93, 11, 5, 206, 99, 11, 5, 206, 98, 11, 5, 206, 104, 11, + 5, 206, 100, 11, 5, 206, 83, 11, 5, 206, 81, 11, 5, 206, 89, 11, 5, 206, + 86, 11, 5, 206, 84, 11, 5, 206, 85, 11, 5, 206, 76, 11, 5, 206, 75, 11, + 5, 206, 80, 11, 5, 206, 79, 11, 5, 206, 77, 11, 5, 206, 78, 11, 5, 212, + 242, 11, 5, 212, 241, 11, 5, 212, 244, 11, 5, 212, 243, 11, 5, 212, 233, + 11, 5, 212, 235, 11, 5, 212, 234, 11, 5, 212, 237, 11, 5, 212, 236, 11, + 5, 212, 240, 11, 5, 212, 239, 11, 5, 212, 227, 11, 5, 212, 226, 11, 5, + 212, 232, 11, 5, 212, 230, 11, 5, 212, 228, 11, 5, 212, 229, 11, 5, 212, + 221, 11, 5, 212, 220, 11, 5, 212, 225, 11, 5, 212, 224, 11, 5, 212, 222, + 11, 5, 212, 223, 11, 5, 203, 123, 11, 5, 203, 118, 11, 5, 203, 165, 11, + 5, 203, 136, 11, 5, 202, 249, 11, 5, 202, 251, 11, 5, 202, 250, 11, 5, + 203, 24, 11, 5, 203, 19, 11, 5, 203, 56, 11, 5, 203, 44, 11, 5, 203, 91, + 11, 5, 203, 84, 11, 5, 203, 113, 11, 5, 203, 100, 11, 5, 202, 245, 11, 5, + 202, 242, 11, 5, 203, 5, 11, 5, 202, 248, 11, 5, 202, 246, 11, 5, 202, + 247, 11, 5, 202, 225, 11, 5, 202, 224, 11, 5, 202, 231, 11, 5, 202, 228, + 11, 5, 202, 226, 11, 5, 202, 227, 11, 5, 207, 130, 11, 5, 207, 123, 11, + 5, 165, 11, 5, 207, 136, 11, 5, 206, 38, 11, 5, 206, 40, 11, 5, 206, 39, + 11, 5, 206, 123, 11, 5, 206, 111, 11, 5, 206, 162, 11, 5, 206, 127, 11, + 5, 207, 11, 11, 5, 207, 113, 11, 5, 207, 53, 11, 5, 206, 30, 11, 5, 206, + 27, 11, 5, 206, 68, 11, 5, 206, 37, 11, 5, 206, 33, 11, 5, 206, 34, 11, + 5, 206, 12, 11, 5, 206, 11, 11, 5, 206, 17, 11, 5, 206, 15, 11, 5, 206, + 13, 11, 5, 206, 14, 11, 5, 222, 232, 11, 5, 222, 231, 11, 5, 222, 244, + 11, 5, 222, 233, 11, 5, 222, 240, 11, 5, 222, 239, 11, 5, 222, 242, 11, + 5, 222, 241, 11, 5, 222, 170, 11, 5, 222, 169, 11, 5, 222, 172, 11, 5, + 222, 171, 11, 5, 222, 188, 11, 5, 222, 186, 11, 5, 222, 201, 11, 5, 222, + 190, 11, 5, 222, 163, 11, 5, 222, 161, 11, 5, 222, 182, 11, 5, 222, 168, + 11, 5, 222, 165, 11, 5, 222, 166, 11, 5, 222, 155, 11, 5, 222, 154, 11, + 5, 222, 159, 11, 5, 222, 158, 11, 5, 222, 156, 11, 5, 222, 157, 11, 5, + 208, 49, 11, 5, 208, 47, 11, 5, 208, 57, 11, 5, 208, 50, 11, 5, 208, 54, + 11, 5, 208, 53, 11, 5, 208, 56, 11, 5, 208, 55, 11, 5, 207, 253, 11, 5, + 207, 250, 11, 5, 207, 255, 11, 5, 207, 254, 11, 5, 208, 36, 11, 5, 208, + 35, 11, 5, 208, 45, 11, 5, 208, 39, 11, 5, 207, 245, 11, 5, 207, 241, 11, + 5, 208, 33, 11, 5, 207, 249, 11, 5, 207, 247, 11, 5, 207, 248, 11, 5, + 207, 225, 11, 5, 207, 223, 11, 5, 207, 235, 11, 5, 207, 228, 11, 5, 207, + 226, 11, 5, 207, 227, 11, 5, 222, 221, 11, 5, 222, 220, 11, 5, 222, 227, + 11, 5, 222, 222, 11, 5, 222, 224, 11, 5, 222, 223, 11, 5, 222, 226, 11, + 5, 222, 225, 11, 5, 222, 212, 11, 5, 222, 214, 11, 5, 222, 213, 11, 5, + 222, 217, 11, 5, 222, 216, 11, 5, 222, 219, 11, 5, 222, 218, 11, 5, 222, + 208, 11, 5, 222, 207, 11, 5, 222, 215, 11, 5, 222, 211, 11, 5, 222, 209, + 11, 5, 222, 210, 11, 5, 222, 204, 11, 5, 222, 203, 11, 5, 222, 206, 11, + 5, 222, 205, 11, 5, 213, 134, 11, 5, 213, 133, 11, 5, 213, 141, 11, 5, + 213, 135, 11, 5, 213, 137, 11, 5, 213, 136, 11, 5, 213, 140, 11, 5, 213, + 138, 11, 5, 213, 123, 11, 5, 213, 124, 11, 5, 213, 129, 11, 5, 213, 128, + 11, 5, 213, 132, 11, 5, 213, 130, 11, 5, 213, 118, 11, 5, 213, 127, 11, + 5, 213, 122, 11, 5, 213, 119, 11, 5, 213, 120, 11, 5, 213, 113, 11, 5, + 213, 112, 11, 5, 213, 117, 11, 5, 213, 116, 11, 5, 213, 114, 11, 5, 213, + 115, 11, 5, 212, 68, 11, 5, 212, 67, 11, 5, 212, 81, 11, 5, 212, 72, 11, + 5, 212, 77, 11, 5, 212, 76, 11, 5, 212, 79, 11, 5, 212, 78, 11, 5, 212, + 53, 11, 5, 212, 55, 11, 5, 212, 54, 11, 5, 212, 60, 11, 5, 212, 59, 11, + 5, 212, 65, 11, 5, 212, 61, 11, 5, 212, 51, 11, 5, 212, 49, 11, 5, 212, + 58, 11, 5, 212, 52, 11, 5, 192, 198, 11, 5, 192, 197, 11, 5, 192, 207, + 11, 5, 192, 200, 11, 5, 192, 202, 11, 5, 192, 201, 11, 5, 192, 204, 11, + 5, 192, 203, 11, 5, 192, 186, 11, 5, 192, 187, 11, 5, 192, 191, 11, 5, + 192, 190, 11, 5, 192, 196, 11, 5, 192, 194, 11, 5, 192, 163, 11, 5, 192, + 161, 11, 5, 192, 176, 11, 5, 192, 166, 11, 5, 192, 164, 11, 5, 192, 165, + 11, 5, 192, 18, 11, 5, 192, 16, 11, 5, 192, 33, 11, 5, 192, 19, 11, 5, + 192, 27, 11, 5, 192, 26, 11, 5, 192, 30, 11, 5, 192, 28, 11, 5, 191, 198, + 11, 5, 191, 197, 11, 5, 191, 201, 11, 5, 191, 199, 11, 5, 191, 240, 11, + 5, 191, 235, 11, 5, 192, 12, 11, 5, 191, 245, 11, 5, 191, 189, 11, 5, + 191, 185, 11, 5, 191, 225, 11, 5, 191, 196, 11, 5, 191, 192, 11, 5, 191, + 193, 11, 5, 191, 169, 11, 5, 191, 168, 11, 5, 191, 176, 11, 5, 191, 172, + 11, 5, 191, 170, 11, 5, 191, 171, 11, 48, 208, 36, 11, 48, 219, 146, 11, + 48, 221, 120, 11, 48, 212, 72, 11, 48, 238, 137, 11, 48, 201, 142, 11, + 48, 231, 110, 11, 48, 231, 142, 11, 48, 216, 100, 11, 48, 228, 104, 11, + 48, 218, 175, 11, 48, 249, 25, 11, 48, 215, 202, 11, 48, 192, 12, 11, 48, + 208, 131, 11, 48, 228, 98, 11, 48, 199, 171, 11, 48, 231, 240, 11, 48, + 190, 243, 11, 48, 238, 130, 11, 48, 237, 151, 11, 48, 247, 230, 11, 48, + 231, 106, 11, 48, 212, 61, 11, 48, 197, 94, 11, 48, 211, 78, 11, 48, 222, + 208, 11, 48, 191, 2, 11, 48, 208, 108, 11, 48, 229, 65, 11, 48, 192, 18, + 11, 48, 193, 244, 11, 48, 202, 231, 11, 48, 195, 141, 11, 48, 191, 123, + 11, 48, 222, 201, 11, 48, 212, 25, 11, 48, 222, 206, 11, 48, 230, 232, + 11, 48, 222, 226, 11, 48, 193, 48, 11, 48, 235, 89, 11, 48, 202, 247, 11, + 48, 219, 140, 11, 48, 238, 143, 11, 48, 238, 184, 11, 48, 243, 12, 11, + 48, 228, 101, 11, 48, 203, 123, 11, 48, 190, 242, 11, 48, 203, 44, 11, + 48, 243, 127, 11, 48, 190, 212, 11, 48, 214, 189, 11, 48, 222, 22, 219, + 88, 1, 249, 153, 219, 88, 1, 168, 219, 88, 1, 209, 228, 219, 88, 1, 238, + 32, 219, 88, 1, 190, 190, 219, 88, 1, 199, 49, 219, 88, 1, 231, 240, 219, + 88, 1, 155, 219, 88, 1, 221, 215, 219, 88, 1, 223, 32, 219, 88, 1, 247, + 160, 219, 88, 1, 247, 1, 219, 88, 1, 235, 35, 219, 88, 1, 197, 168, 219, + 88, 1, 197, 157, 219, 88, 1, 174, 219, 88, 1, 180, 219, 88, 1, 173, 219, + 88, 1, 188, 219, 88, 1, 191, 71, 219, 88, 1, 191, 123, 219, 88, 1, 214, + 68, 219, 88, 1, 140, 219, 88, 1, 192, 220, 219, 88, 1, 229, 177, 219, 88, + 1, 233, 109, 219, 88, 1, 193, 190, 219, 88, 1, 203, 165, 219, 88, 1, 170, + 219, 88, 1, 231, 91, 219, 88, 1, 65, 219, 88, 1, 252, 25, 219, 88, 1, 71, + 219, 88, 1, 233, 242, 219, 88, 1, 68, 219, 88, 1, 74, 219, 88, 1, 66, + 219, 88, 1, 196, 152, 219, 88, 1, 196, 141, 219, 88, 1, 211, 151, 219, + 88, 1, 163, 215, 69, 198, 193, 219, 88, 1, 163, 215, 7, 209, 73, 219, 88, + 1, 163, 215, 69, 238, 142, 219, 88, 1, 163, 215, 69, 248, 111, 219, 88, + 1, 163, 215, 69, 180, 219, 88, 1, 163, 215, 69, 222, 253, 219, 88, 208, + 152, 242, 74, 219, 88, 208, 152, 232, 80, 201, 63, 59, 5, 234, 188, 59, + 5, 234, 184, 59, 5, 229, 215, 59, 5, 193, 114, 59, 5, 193, 113, 59, 5, + 210, 49, 59, 5, 248, 195, 59, 5, 249, 1, 59, 5, 217, 3, 59, 5, 221, 16, + 59, 5, 216, 132, 59, 5, 231, 178, 59, 5, 233, 52, 59, 5, 195, 148, 59, 5, + 199, 121, 59, 5, 199, 31, 59, 5, 237, 58, 59, 5, 237, 55, 59, 5, 219, + 228, 59, 5, 207, 84, 59, 5, 237, 131, 59, 5, 214, 153, 59, 5, 205, 50, + 59, 5, 203, 111, 59, 5, 191, 84, 59, 5, 191, 61, 59, 5, 247, 34, 59, 5, + 223, 8, 59, 5, 213, 148, 59, 5, 192, 77, 59, 5, 222, 13, 59, 5, 214, 41, + 59, 5, 231, 157, 59, 5, 216, 211, 59, 5, 214, 110, 59, 5, 212, 89, 59, 5, + 68, 59, 5, 223, 162, 59, 5, 229, 158, 59, 5, 229, 128, 59, 5, 193, 86, + 59, 5, 193, 68, 59, 5, 209, 185, 59, 5, 248, 193, 59, 5, 248, 188, 59, 5, + 216, 252, 59, 5, 221, 13, 59, 5, 216, 129, 59, 5, 231, 174, 59, 5, 233, + 23, 59, 5, 195, 69, 59, 5, 198, 193, 59, 5, 199, 11, 59, 5, 237, 50, 59, + 5, 237, 54, 59, 5, 219, 146, 59, 5, 207, 1, 59, 5, 237, 44, 59, 5, 214, + 147, 59, 5, 202, 222, 59, 5, 203, 81, 59, 5, 191, 30, 59, 5, 191, 57, 59, + 5, 243, 29, 59, 5, 222, 244, 59, 5, 213, 141, 59, 5, 192, 33, 59, 5, 221, + 166, 59, 5, 214, 33, 59, 5, 231, 53, 59, 5, 216, 100, 59, 5, 213, 219, + 59, 5, 212, 81, 59, 5, 65, 59, 5, 251, 132, 59, 5, 214, 63, 59, 5, 140, + 59, 5, 230, 56, 59, 5, 193, 190, 59, 5, 193, 164, 59, 5, 168, 59, 5, 248, + 203, 59, 5, 249, 153, 59, 5, 217, 11, 59, 5, 221, 21, 59, 5, 221, 19, 59, + 5, 216, 136, 59, 5, 231, 182, 59, 5, 233, 109, 59, 5, 195, 188, 59, 5, + 190, 190, 59, 5, 199, 49, 59, 5, 237, 68, 59, 5, 237, 57, 59, 5, 173, 59, + 5, 165, 59, 5, 238, 32, 59, 5, 214, 162, 59, 5, 188, 59, 5, 203, 165, 59, + 5, 191, 123, 59, 5, 191, 71, 59, 5, 247, 160, 59, 5, 223, 32, 59, 5, 213, + 157, 59, 5, 170, 59, 5, 155, 59, 5, 222, 87, 59, 5, 214, 47, 59, 5, 231, + 240, 59, 5, 174, 59, 5, 180, 59, 5, 212, 101, 59, 5, 211, 87, 59, 5, 211, + 82, 59, 5, 228, 252, 59, 5, 193, 29, 59, 5, 193, 25, 59, 5, 209, 37, 59, + 5, 248, 191, 59, 5, 248, 97, 59, 5, 216, 247, 59, 5, 221, 11, 59, 5, 216, + 125, 59, 5, 231, 170, 59, 5, 232, 162, 59, 5, 195, 8, 59, 5, 198, 59, 59, + 5, 198, 235, 59, 5, 237, 47, 59, 5, 237, 52, 59, 5, 219, 8, 59, 5, 206, + 134, 59, 5, 236, 146, 59, 5, 214, 134, 59, 5, 202, 16, 59, 5, 203, 48, + 59, 5, 191, 4, 59, 5, 191, 52, 59, 5, 239, 18, 59, 5, 222, 191, 59, 5, + 213, 131, 59, 5, 191, 246, 59, 5, 221, 41, 59, 5, 214, 31, 59, 5, 230, + 245, 59, 5, 215, 211, 59, 5, 213, 26, 59, 5, 212, 62, 59, 5, 66, 59, 5, + 196, 113, 59, 5, 228, 159, 59, 5, 228, 142, 59, 5, 193, 0, 59, 5, 192, + 249, 59, 5, 208, 165, 59, 5, 248, 190, 59, 5, 248, 10, 59, 5, 216, 246, + 59, 5, 221, 9, 59, 5, 216, 124, 59, 5, 231, 169, 59, 5, 232, 86, 59, 5, + 193, 249, 59, 5, 197, 94, 59, 5, 198, 213, 59, 5, 237, 45, 59, 5, 237, + 51, 59, 5, 218, 225, 59, 5, 206, 68, 59, 5, 235, 89, 59, 5, 214, 129, 59, + 5, 201, 4, 59, 5, 203, 5, 59, 5, 190, 251, 59, 5, 191, 48, 59, 5, 238, + 195, 59, 5, 222, 182, 59, 5, 213, 127, 59, 5, 191, 225, 59, 5, 220, 232, + 59, 5, 214, 30, 59, 5, 230, 179, 59, 5, 215, 155, 59, 5, 212, 178, 59, 5, + 212, 58, 59, 5, 74, 59, 5, 211, 104, 59, 5, 213, 245, 59, 5, 229, 23, 59, + 5, 228, 255, 59, 5, 193, 48, 59, 5, 193, 30, 59, 5, 209, 73, 59, 5, 248, + 192, 59, 5, 248, 111, 59, 5, 216, 248, 59, 5, 221, 12, 59, 5, 216, 127, + 59, 5, 231, 172, 59, 5, 231, 171, 59, 5, 232, 175, 59, 5, 195, 24, 59, 5, + 159, 59, 5, 198, 241, 59, 5, 237, 48, 59, 5, 237, 53, 59, 5, 219, 43, 59, + 5, 206, 162, 59, 5, 236, 174, 59, 5, 214, 138, 59, 5, 202, 46, 59, 5, + 203, 56, 59, 5, 191, 7, 59, 5, 191, 54, 59, 5, 242, 99, 59, 5, 222, 201, + 59, 5, 213, 132, 59, 5, 192, 12, 59, 5, 221, 67, 59, 5, 214, 32, 59, 5, + 231, 3, 59, 5, 216, 12, 59, 5, 213, 43, 59, 5, 212, 65, 59, 5, 71, 59, 5, + 234, 103, 59, 5, 214, 52, 59, 5, 229, 245, 59, 5, 229, 198, 59, 5, 193, + 125, 59, 5, 193, 108, 59, 5, 210, 63, 59, 5, 248, 196, 59, 5, 249, 17, + 59, 5, 217, 4, 59, 5, 221, 17, 59, 5, 221, 15, 59, 5, 216, 133, 59, 5, + 231, 179, 59, 5, 231, 177, 59, 5, 233, 59, 59, 5, 195, 153, 59, 5, 199, + 145, 59, 5, 199, 33, 59, 5, 237, 59, 59, 5, 237, 56, 59, 5, 219, 238, 59, + 5, 207, 113, 59, 5, 237, 146, 59, 5, 214, 154, 59, 5, 205, 68, 59, 5, + 203, 113, 59, 5, 191, 87, 59, 5, 191, 62, 59, 5, 247, 42, 59, 5, 223, 10, + 59, 5, 213, 150, 59, 5, 192, 80, 59, 5, 222, 22, 59, 5, 214, 42, 59, 5, + 214, 38, 59, 5, 231, 165, 59, 5, 231, 151, 59, 5, 216, 232, 59, 5, 214, + 121, 59, 5, 212, 90, 59, 5, 214, 70, 59, 5, 219, 190, 59, 242, 74, 59, + 232, 80, 201, 63, 59, 208, 13, 77, 59, 5, 214, 137, 233, 109, 59, 5, 214, + 137, 155, 59, 5, 214, 137, 202, 16, 59, 16, 233, 48, 59, 16, 222, 11, 59, + 16, 198, 140, 59, 16, 213, 186, 59, 16, 249, 95, 59, 16, 233, 108, 59, + 16, 199, 245, 59, 16, 237, 236, 59, 16, 236, 145, 59, 16, 220, 208, 59, + 16, 198, 63, 59, 16, 236, 173, 59, 16, 222, 192, 59, 17, 191, 77, 59, 17, + 107, 59, 17, 109, 59, 17, 138, 59, 17, 134, 59, 17, 149, 59, 17, 169, 59, + 17, 175, 59, 17, 171, 59, 17, 178, 59, 5, 214, 137, 174, 59, 5, 214, 137, + 236, 174, 38, 6, 1, 191, 81, 38, 2, 1, 191, 81, 38, 6, 1, 235, 30, 38, 2, + 1, 235, 30, 38, 6, 1, 207, 18, 235, 32, 38, 2, 1, 207, 18, 235, 32, 38, + 6, 1, 223, 83, 38, 2, 1, 223, 83, 38, 6, 1, 236, 191, 38, 2, 1, 236, 191, + 38, 6, 1, 215, 219, 196, 128, 38, 2, 1, 215, 219, 196, 128, 38, 6, 1, + 248, 24, 211, 110, 38, 2, 1, 248, 24, 211, 110, 38, 6, 1, 214, 82, 192, + 62, 38, 2, 1, 214, 82, 192, 62, 38, 6, 1, 192, 59, 4, 249, 147, 192, 62, + 38, 2, 1, 192, 59, 4, 249, 147, 192, 62, 38, 6, 1, 223, 81, 192, 95, 38, + 2, 1, 223, 81, 192, 95, 38, 6, 1, 207, 18, 191, 225, 38, 2, 1, 207, 18, + 191, 225, 38, 6, 1, 223, 81, 65, 38, 2, 1, 223, 81, 65, 38, 6, 1, 242, + 219, 219, 83, 191, 190, 38, 2, 1, 242, 219, 219, 83, 191, 190, 38, 6, 1, + 248, 131, 191, 190, 38, 2, 1, 248, 131, 191, 190, 38, 6, 1, 223, 81, 242, + 219, 219, 83, 191, 190, 38, 2, 1, 223, 81, 242, 219, 219, 83, 191, 190, + 38, 6, 1, 192, 14, 38, 2, 1, 192, 14, 38, 6, 1, 207, 18, 197, 161, 38, 2, + 1, 207, 18, 197, 161, 38, 6, 1, 202, 32, 237, 146, 38, 2, 1, 202, 32, + 237, 146, 38, 6, 1, 202, 32, 234, 140, 38, 2, 1, 202, 32, 234, 140, 38, + 6, 1, 202, 32, 234, 114, 38, 2, 1, 202, 32, 234, 114, 38, 6, 1, 215, 223, + 74, 38, 2, 1, 215, 223, 74, 38, 6, 1, 248, 164, 74, 38, 2, 1, 248, 164, + 74, 38, 6, 1, 55, 215, 223, 74, 38, 2, 1, 55, 215, 223, 74, 38, 1, 215, + 130, 74, 33, 38, 193, 226, 33, 38, 199, 96, 216, 48, 56, 33, 38, 228, + 141, 216, 48, 56, 33, 38, 198, 230, 216, 48, 56, 202, 95, 250, 193, 33, + 38, 1, 196, 125, 223, 226, 33, 38, 1, 68, 33, 38, 1, 192, 33, 33, 38, 1, + 66, 33, 38, 1, 230, 17, 56, 33, 38, 1, 192, 58, 33, 38, 1, 202, 32, 56, + 33, 38, 1, 211, 110, 33, 38, 222, 35, 33, 38, 210, 70, 38, 222, 35, 38, + 210, 70, 38, 6, 1, 235, 45, 38, 2, 1, 235, 45, 38, 6, 1, 235, 21, 38, 2, + 1, 235, 21, 38, 6, 1, 191, 38, 38, 2, 1, 191, 38, 38, 6, 1, 247, 58, 38, + 2, 1, 247, 58, 38, 6, 1, 235, 17, 38, 2, 1, 235, 17, 38, 6, 1, 199, 146, + 4, 82, 102, 38, 2, 1, 199, 146, 4, 82, 102, 38, 6, 1, 197, 41, 38, 2, 1, + 197, 41, 38, 6, 1, 197, 136, 38, 2, 1, 197, 136, 38, 6, 1, 197, 141, 38, + 2, 1, 197, 141, 38, 6, 1, 199, 151, 38, 2, 1, 199, 151, 38, 6, 1, 228, + 122, 38, 2, 1, 228, 122, 38, 6, 1, 202, 237, 38, 2, 1, 202, 237, 38, 6, + 1, 55, 74, 38, 2, 1, 55, 74, 38, 6, 1, 238, 214, 74, 38, 2, 1, 238, 214, + 74, 52, 1, 38, 230, 17, 56, 52, 1, 38, 202, 32, 56, 33, 38, 1, 234, 181, + 33, 38, 1, 223, 81, 71, 26, 1, 65, 26, 1, 155, 26, 1, 66, 26, 1, 220, + 232, 26, 1, 234, 188, 26, 1, 207, 84, 26, 1, 199, 226, 26, 1, 74, 26, 1, + 212, 81, 26, 1, 68, 26, 1, 173, 26, 1, 168, 26, 1, 206, 195, 26, 1, 206, + 242, 26, 1, 219, 227, 26, 1, 216, 210, 26, 1, 199, 245, 26, 1, 214, 160, + 26, 1, 213, 155, 26, 1, 218, 168, 26, 1, 200, 160, 26, 1, 215, 155, 26, + 1, 203, 76, 26, 1, 202, 222, 26, 1, 203, 86, 26, 1, 203, 248, 26, 1, 220, + 149, 26, 1, 221, 241, 26, 1, 212, 146, 26, 1, 212, 178, 26, 1, 213, 126, + 26, 1, 191, 243, 26, 1, 203, 5, 26, 1, 191, 194, 26, 1, 170, 26, 1, 212, + 215, 26, 1, 221, 227, 26, 1, 209, 232, 26, 1, 213, 148, 26, 1, 212, 195, + 26, 1, 208, 156, 26, 1, 192, 253, 26, 1, 210, 49, 26, 1, 233, 52, 26, 1, + 206, 68, 26, 1, 218, 225, 26, 1, 216, 100, 26, 1, 213, 219, 26, 1, 207, + 20, 26, 1, 207, 163, 26, 1, 221, 251, 26, 1, 213, 252, 26, 1, 214, 47, + 26, 1, 214, 68, 26, 1, 203, 56, 26, 1, 208, 161, 26, 1, 232, 86, 26, 1, + 232, 167, 26, 1, 193, 190, 26, 1, 180, 26, 1, 219, 146, 26, 1, 209, 185, + 26, 1, 219, 0, 26, 1, 221, 67, 26, 1, 217, 1, 26, 1, 207, 55, 26, 1, 216, + 186, 26, 1, 174, 26, 1, 198, 193, 26, 1, 221, 166, 26, 1, 216, 12, 26, 1, + 217, 9, 26, 1, 199, 73, 26, 1, 221, 21, 26, 1, 199, 95, 26, 1, 212, 181, + 26, 1, 205, 150, 26, 1, 233, 105, 26, 1, 221, 24, 26, 1, 221, 57, 26, 33, + 87, 221, 34, 26, 33, 87, 197, 79, 26, 213, 154, 26, 232, 80, 201, 63, 26, + 242, 83, 26, 242, 74, 26, 204, 25, 26, 208, 13, 77, 52, 1, 243, 80, 163, + 192, 22, 209, 132, 52, 1, 243, 80, 163, 192, 107, 209, 132, 52, 1, 243, + 80, 163, 192, 22, 203, 137, 52, 1, 243, 80, 163, 192, 107, 203, 137, 52, + 1, 243, 80, 163, 192, 22, 208, 33, 52, 1, 243, 80, 163, 192, 107, 208, + 33, 52, 1, 243, 80, 163, 192, 22, 206, 68, 52, 1, 243, 80, 163, 192, 107, + 206, 68, 52, 1, 233, 200, 235, 138, 163, 164, 52, 1, 137, 235, 138, 163, + 164, 52, 1, 216, 87, 235, 138, 163, 164, 52, 1, 130, 235, 138, 163, 164, + 52, 1, 233, 199, 235, 138, 163, 164, 52, 1, 233, 200, 235, 138, 219, 216, + 163, 164, 52, 1, 137, 235, 138, 219, 216, 163, 164, 52, 1, 216, 87, 235, + 138, 219, 216, 163, 164, 52, 1, 130, 235, 138, 219, 216, 163, 164, 52, 1, + 233, 199, 235, 138, 219, 216, 163, 164, 52, 1, 233, 200, 219, 216, 163, + 164, 52, 1, 137, 219, 216, 163, 164, 52, 1, 216, 87, 219, 216, 163, 164, + 52, 1, 130, 219, 216, 163, 164, 52, 1, 233, 199, 219, 216, 163, 164, 52, + 1, 75, 81, 164, 52, 1, 75, 202, 97, 52, 1, 75, 228, 241, 164, 52, 1, 110, + 50, 239, 2, 251, 115, 52, 1, 207, 147, 133, 57, 52, 1, 207, 147, 144, 57, + 52, 1, 207, 147, 233, 216, 77, 52, 1, 207, 147, 223, 93, 233, 216, 77, + 52, 1, 130, 223, 93, 233, 216, 77, 52, 1, 201, 38, 23, 137, 198, 79, 52, + 1, 201, 38, 23, 130, 198, 79, 8, 6, 1, 234, 175, 251, 192, 8, 2, 1, 234, + 175, 251, 192, 8, 6, 1, 234, 175, 251, 230, 8, 2, 1, 234, 175, 251, 230, + 8, 6, 1, 229, 196, 8, 2, 1, 229, 196, 8, 6, 1, 196, 241, 8, 2, 1, 196, + 241, 8, 6, 1, 197, 248, 8, 2, 1, 197, 248, 8, 6, 1, 238, 192, 8, 2, 1, + 238, 192, 8, 6, 1, 238, 193, 4, 242, 74, 8, 2, 1, 238, 193, 4, 242, 74, + 8, 1, 2, 6, 233, 175, 8, 1, 2, 6, 206, 8, 8, 6, 1, 252, 206, 8, 2, 1, + 252, 206, 8, 6, 1, 251, 68, 8, 2, 1, 251, 68, 8, 6, 1, 250, 163, 8, 2, 1, + 250, 163, 8, 6, 1, 250, 146, 8, 2, 1, 250, 146, 8, 6, 1, 250, 147, 4, + 228, 241, 164, 8, 2, 1, 250, 147, 4, 228, 241, 164, 8, 6, 1, 250, 131, 8, + 2, 1, 250, 131, 8, 6, 1, 207, 18, 247, 194, 4, 236, 140, 8, 2, 1, 207, + 18, 247, 194, 4, 236, 140, 8, 6, 1, 222, 153, 4, 106, 8, 2, 1, 222, 153, + 4, 106, 8, 6, 1, 222, 153, 4, 237, 39, 106, 8, 2, 1, 222, 153, 4, 237, + 39, 106, 8, 6, 1, 222, 153, 4, 201, 28, 23, 237, 39, 106, 8, 2, 1, 222, + 153, 4, 201, 28, 23, 237, 39, 106, 8, 6, 1, 248, 22, 172, 8, 2, 1, 248, + 22, 172, 8, 6, 1, 220, 143, 4, 137, 106, 8, 2, 1, 220, 143, 4, 137, 106, + 8, 6, 1, 187, 4, 179, 201, 28, 210, 255, 8, 2, 1, 187, 4, 179, 201, 28, + 210, 255, 8, 6, 1, 187, 4, 219, 4, 8, 2, 1, 187, 4, 219, 4, 8, 6, 1, 211, + 87, 8, 2, 1, 211, 87, 8, 6, 1, 210, 237, 4, 201, 28, 198, 216, 237, 87, + 8, 2, 1, 210, 237, 4, 201, 28, 198, 216, 237, 87, 8, 6, 1, 210, 237, 4, + 232, 188, 8, 2, 1, 210, 237, 4, 232, 188, 8, 6, 1, 210, 237, 4, 201, 182, + 199, 215, 8, 2, 1, 210, 237, 4, 201, 182, 199, 215, 8, 6, 1, 208, 105, 4, + 201, 28, 198, 216, 237, 87, 8, 2, 1, 208, 105, 4, 201, 28, 198, 216, 237, + 87, 8, 6, 1, 208, 105, 4, 237, 39, 106, 8, 2, 1, 208, 105, 4, 237, 39, + 106, 8, 6, 1, 207, 222, 206, 116, 8, 2, 1, 207, 222, 206, 116, 8, 6, 1, + 206, 49, 206, 116, 8, 2, 1, 206, 49, 206, 116, 8, 6, 1, 196, 13, 4, 237, + 39, 106, 8, 2, 1, 196, 13, 4, 237, 39, 106, 8, 6, 1, 193, 235, 8, 2, 1, + 193, 235, 8, 6, 1, 195, 33, 191, 166, 8, 2, 1, 195, 33, 191, 166, 8, 6, + 1, 198, 234, 4, 106, 8, 2, 1, 198, 234, 4, 106, 8, 6, 1, 198, 234, 4, + 201, 28, 198, 216, 237, 87, 8, 2, 1, 198, 234, 4, 201, 28, 198, 216, 237, + 87, 8, 6, 1, 195, 142, 8, 2, 1, 195, 142, 8, 6, 1, 233, 255, 8, 2, 1, + 233, 255, 8, 6, 1, 223, 68, 8, 2, 1, 223, 68, 8, 6, 1, 239, 57, 8, 2, 1, + 239, 57, 52, 1, 196, 45, 8, 2, 1, 235, 77, 8, 2, 1, 218, 208, 8, 2, 1, + 215, 123, 8, 2, 1, 212, 137, 8, 2, 1, 206, 48, 8, 1, 2, 6, 206, 48, 8, 2, + 1, 197, 76, 8, 2, 1, 196, 120, 8, 6, 1, 223, 115, 238, 127, 8, 2, 1, 223, + 115, 238, 127, 8, 6, 1, 223, 115, 233, 175, 8, 2, 1, 223, 115, 233, 175, + 8, 6, 1, 223, 115, 232, 51, 8, 6, 1, 153, 223, 115, 232, 51, 8, 2, 1, + 153, 223, 115, 232, 51, 8, 6, 1, 153, 172, 8, 2, 1, 153, 172, 8, 6, 1, + 223, 115, 146, 8, 2, 1, 223, 115, 146, 8, 6, 1, 223, 115, 206, 8, 8, 2, + 1, 223, 115, 206, 8, 8, 6, 1, 223, 115, 200, 43, 8, 2, 1, 223, 115, 200, + 43, 52, 1, 130, 243, 2, 252, 60, 52, 1, 242, 83, 52, 1, 203, 40, 234, 43, + 56, 8, 6, 1, 205, 156, 8, 2, 1, 205, 156, 8, 6, 1, 153, 230, 116, 8, 2, + 1, 220, 143, 4, 207, 24, 228, 251, 23, 248, 231, 8, 1, 202, 163, 236, + 140, 8, 6, 1, 215, 62, 4, 237, 87, 8, 2, 1, 215, 62, 4, 237, 87, 8, 6, 1, + 247, 194, 4, 164, 8, 2, 1, 247, 194, 4, 164, 8, 2, 1, 247, 194, 4, 210, + 192, 102, 8, 2, 1, 230, 117, 4, 210, 192, 102, 8, 6, 1, 78, 4, 232, 188, + 8, 2, 1, 78, 4, 232, 188, 8, 6, 1, 233, 176, 4, 106, 8, 2, 1, 233, 176, + 4, 106, 8, 6, 1, 195, 15, 252, 25, 8, 2, 1, 195, 15, 252, 25, 8, 6, 1, + 195, 15, 211, 151, 8, 2, 1, 195, 15, 211, 151, 8, 6, 1, 195, 15, 196, + 152, 8, 2, 1, 195, 15, 196, 152, 8, 6, 1, 232, 52, 4, 211, 172, 106, 8, + 2, 1, 232, 52, 4, 211, 172, 106, 8, 6, 1, 222, 153, 4, 211, 172, 106, 8, + 2, 1, 222, 153, 4, 211, 172, 106, 8, 6, 1, 215, 62, 4, 211, 172, 106, 8, + 2, 1, 215, 62, 4, 211, 172, 106, 8, 6, 1, 207, 222, 4, 211, 172, 106, 8, + 2, 1, 207, 222, 4, 211, 172, 106, 8, 6, 1, 206, 9, 4, 211, 172, 106, 8, + 2, 1, 206, 9, 4, 211, 172, 106, 8, 6, 1, 230, 117, 4, 102, 8, 6, 1, 207, + 18, 211, 77, 71, 8, 6, 1, 27, 232, 51, 8, 6, 1, 220, 143, 4, 248, 231, 8, + 6, 1, 2, 6, 68, 8, 1, 2, 6, 208, 104, 8, 6, 1, 153, 222, 152, 8, 6, 1, + 153, 200, 43, 8, 6, 1, 223, 36, 4, 238, 212, 8, 6, 1, 243, 95, 8, 6, 1, + 248, 212, 8, 2, 1, 248, 212, 8, 6, 1, 211, 110, 8, 2, 1, 211, 110, 8, 6, + 1, 126, 4, 106, 8, 2, 1, 126, 4, 106, 8, 6, 1, 231, 11, 65, 8, 2, 1, 231, + 11, 65, 8, 6, 1, 231, 11, 68, 8, 2, 1, 231, 11, 68, 8, 6, 1, 231, 11, 66, + 8, 2, 1, 231, 11, 66, 8, 6, 1, 39, 209, 49, 74, 8, 2, 1, 39, 209, 49, 74, + 8, 6, 1, 251, 112, 193, 224, 8, 2, 1, 251, 112, 193, 224, 8, 6, 1, 247, + 194, 4, 210, 192, 102, 8, 6, 1, 206, 9, 4, 102, 8, 6, 1, 191, 167, 4, + 210, 192, 102, 8, 6, 1, 238, 128, 4, 203, 40, 201, 28, 210, 255, 8, 2, 1, + 238, 128, 4, 203, 40, 201, 28, 210, 255, 8, 6, 1, 206, 9, 4, 203, 40, + 201, 28, 210, 255, 8, 2, 1, 206, 9, 4, 203, 40, 201, 28, 210, 255, 8, 6, + 1, 242, 219, 223, 115, 232, 51, 8, 2, 1, 242, 219, 223, 115, 232, 51, 8, + 2, 1, 55, 198, 233, 8, 2, 1, 55, 192, 238, 8, 6, 1, 82, 205, 79, 206, 8, + 8, 2, 1, 82, 205, 79, 206, 8, 8, 6, 1, 202, 195, 206, 8, 8, 2, 1, 202, + 195, 206, 8, 52, 1, 6, 247, 193, 52, 1, 6, 233, 175, 52, 1, 6, 208, 104, + 8, 6, 1, 207, 18, 132, 230, 116, 8, 2, 1, 207, 18, 132, 230, 116, 8, 234, + 50, 1, 202, 206, 68, 52, 1, 6, 230, 117, 4, 106, 52, 1, 2, 34, 211, 151, + 8, 1, 2, 6, 153, 218, 168, 8, 234, 50, 1, 207, 18, 233, 175, 8, 234, 50, + 1, 207, 18, 210, 236, 8, 234, 50, 1, 223, 93, 218, 168, 8, 234, 50, 1, + 228, 74, 219, 10, 8, 234, 50, 1, 251, 14, 218, 168, 200, 124, 214, 238, + 1, 65, 200, 124, 214, 238, 1, 68, 200, 124, 214, 238, 3, 235, 54, 200, + 124, 214, 238, 1, 66, 200, 124, 214, 238, 1, 71, 200, 124, 214, 238, 1, + 74, 200, 124, 214, 238, 3, 230, 11, 200, 124, 214, 238, 1, 221, 67, 200, + 124, 214, 238, 1, 221, 183, 200, 124, 214, 238, 1, 231, 3, 200, 124, 214, + 238, 1, 231, 63, 200, 124, 214, 238, 3, 251, 71, 200, 124, 214, 238, 1, + 242, 99, 200, 124, 214, 238, 1, 243, 68, 200, 124, 214, 238, 1, 222, 201, + 200, 124, 214, 238, 1, 222, 246, 200, 124, 214, 238, 1, 197, 109, 200, + 124, 214, 238, 1, 197, 115, 200, 124, 214, 238, 1, 237, 161, 200, 124, + 214, 238, 1, 237, 170, 200, 124, 214, 238, 1, 159, 200, 124, 214, 238, 1, + 198, 241, 200, 124, 214, 238, 1, 236, 174, 200, 124, 214, 238, 1, 237, + 48, 200, 124, 214, 238, 1, 213, 43, 200, 124, 214, 238, 1, 209, 73, 200, + 124, 214, 238, 1, 209, 199, 200, 124, 214, 238, 1, 248, 111, 200, 124, + 214, 238, 1, 248, 192, 200, 124, 214, 238, 1, 216, 12, 200, 124, 214, + 238, 1, 206, 162, 200, 124, 214, 238, 1, 219, 43, 200, 124, 214, 238, 1, + 206, 95, 200, 124, 214, 238, 1, 202, 46, 200, 124, 214, 238, 1, 229, 23, + 200, 124, 214, 238, 18, 3, 65, 200, 124, 214, 238, 18, 3, 68, 200, 124, + 214, 238, 18, 3, 66, 200, 124, 214, 238, 18, 3, 71, 200, 124, 214, 238, + 18, 3, 211, 87, 200, 124, 214, 238, 209, 63, 217, 55, 200, 124, 214, 238, + 209, 63, 217, 54, 200, 124, 214, 238, 209, 63, 217, 53, 200, 124, 214, + 238, 209, 63, 217, 52, 200, 124, 214, 238, 3, 251, 157, 230, 11, 186, + 223, 146, 232, 118, 91, 208, 22, 186, 223, 146, 232, 118, 91, 230, 70, + 186, 223, 146, 232, 118, 115, 208, 20, 186, 223, 146, 232, 118, 91, 202, + 128, 186, 223, 146, 232, 118, 91, 234, 159, 186, 223, 146, 232, 118, 115, + 202, 125, 186, 223, 146, 208, 23, 77, 186, 223, 146, 209, 107, 77, 186, + 223, 146, 206, 36, 77, 186, 223, 146, 208, 25, 77, 209, 224, 1, 155, 209, + 224, 1, 221, 215, 209, 224, 1, 231, 240, 209, 224, 1, 214, 68, 209, 224, + 1, 247, 160, 209, 224, 1, 247, 1, 209, 224, 1, 223, 32, 209, 224, 1, 212, + 101, 209, 224, 1, 190, 190, 209, 224, 1, 199, 49, 209, 224, 1, 238, 32, + 209, 224, 1, 180, 209, 224, 1, 168, 209, 224, 1, 209, 228, 209, 224, 1, + 249, 153, 209, 224, 1, 174, 209, 224, 1, 197, 168, 209, 224, 1, 197, 157, + 209, 224, 1, 235, 35, 209, 224, 1, 193, 190, 209, 224, 1, 191, 71, 209, + 224, 1, 191, 123, 209, 224, 1, 2, 65, 209, 224, 1, 170, 209, 224, 1, 165, + 209, 224, 1, 173, 209, 224, 1, 203, 165, 209, 224, 1, 188, 209, 224, 1, + 140, 209, 224, 1, 65, 209, 224, 1, 68, 209, 224, 1, 66, 209, 224, 1, 71, + 209, 224, 1, 74, 209, 224, 1, 208, 96, 209, 224, 1, 192, 220, 209, 224, + 1, 233, 109, 209, 224, 1, 231, 127, 209, 224, 1, 234, 188, 209, 224, 200, + 239, 1, 193, 190, 209, 224, 200, 239, 1, 170, 209, 224, 1, 197, 132, 209, + 224, 1, 197, 120, 209, 224, 1, 237, 191, 209, 224, 1, 213, 79, 209, 224, + 1, 251, 157, 170, 209, 224, 1, 195, 19, 203, 165, 209, 224, 1, 195, 20, + 140, 209, 224, 1, 250, 200, 233, 109, 209, 224, 200, 239, 1, 165, 209, + 224, 200, 185, 1, 165, 209, 224, 1, 247, 119, 209, 224, 202, 170, 229, + 236, 77, 209, 224, 55, 229, 236, 77, 209, 224, 87, 203, 157, 209, 224, + 87, 55, 203, 157, 205, 111, 3, 251, 71, 205, 111, 3, 195, 35, 205, 111, + 1, 65, 205, 111, 1, 252, 206, 205, 111, 1, 68, 205, 111, 1, 223, 199, + 205, 111, 1, 66, 205, 111, 1, 196, 30, 205, 111, 1, 117, 146, 205, 111, + 1, 117, 206, 110, 205, 111, 1, 117, 172, 205, 111, 1, 117, 219, 74, 205, + 111, 1, 71, 205, 111, 1, 234, 188, 205, 111, 1, 251, 236, 205, 111, 1, + 74, 205, 111, 1, 211, 87, 205, 111, 1, 250, 163, 205, 111, 1, 155, 205, + 111, 1, 221, 215, 205, 111, 1, 231, 240, 205, 111, 1, 231, 91, 205, 111, + 1, 214, 68, 205, 111, 1, 247, 160, 205, 111, 1, 247, 1, 205, 111, 1, 223, + 32, 205, 111, 1, 222, 252, 205, 111, 1, 212, 101, 205, 111, 1, 197, 132, + 205, 111, 1, 197, 120, 205, 111, 1, 237, 191, 205, 111, 1, 237, 175, 205, + 111, 1, 213, 79, 205, 111, 1, 190, 190, 205, 111, 1, 199, 49, 205, 111, + 1, 238, 32, 205, 111, 1, 237, 68, 205, 111, 1, 180, 205, 111, 1, 168, + 205, 111, 1, 209, 228, 205, 111, 1, 249, 153, 205, 111, 1, 248, 203, 205, + 111, 1, 174, 205, 111, 1, 170, 205, 111, 1, 165, 205, 111, 1, 173, 205, + 111, 1, 195, 188, 205, 111, 1, 203, 165, 205, 111, 1, 201, 175, 205, 111, + 1, 188, 205, 111, 1, 140, 205, 111, 1, 219, 73, 205, 111, 120, 3, 230, + 89, 205, 111, 18, 3, 252, 206, 205, 111, 18, 3, 68, 205, 111, 18, 3, 223, + 199, 205, 111, 18, 3, 66, 205, 111, 18, 3, 196, 30, 205, 111, 18, 3, 117, + 146, 205, 111, 18, 3, 117, 206, 110, 205, 111, 18, 3, 117, 172, 205, 111, + 18, 3, 117, 219, 74, 205, 111, 18, 3, 71, 205, 111, 18, 3, 234, 188, 205, + 111, 18, 3, 251, 236, 205, 111, 18, 3, 74, 205, 111, 18, 3, 211, 87, 205, + 111, 18, 3, 250, 163, 205, 111, 3, 195, 40, 205, 111, 3, 247, 119, 205, + 111, 237, 238, 205, 111, 55, 237, 238, 205, 111, 17, 191, 77, 205, 111, + 17, 107, 205, 111, 17, 109, 205, 111, 17, 138, 205, 111, 17, 134, 205, + 111, 17, 149, 205, 111, 17, 169, 205, 111, 17, 175, 205, 111, 17, 171, + 205, 111, 17, 178, 33, 100, 17, 191, 77, 33, 100, 17, 107, 33, 100, 17, + 109, 33, 100, 17, 138, 33, 100, 17, 134, 33, 100, 17, 149, 33, 100, 17, + 169, 33, 100, 17, 175, 33, 100, 17, 171, 33, 100, 17, 178, 33, 100, 1, + 65, 33, 100, 1, 66, 33, 100, 1, 155, 33, 100, 1, 180, 33, 100, 1, 168, + 33, 100, 1, 165, 33, 100, 1, 195, 69, 33, 100, 3, 250, 145, 100, 3, 201, + 246, 247, 119, 100, 3, 247, 120, 195, 40, 100, 3, 55, 247, 120, 195, 40, + 100, 3, 247, 120, 109, 100, 3, 247, 120, 138, 100, 3, 247, 120, 250, 145, + 100, 3, 208, 134, 100, 231, 204, 233, 3, 100, 247, 96, 100, 229, 227, + 100, 3, 202, 210, 100, 223, 24, 211, 113, 100, 1, 250, 131, 100, 18, 3, + 250, 131, 222, 28, 219, 147, 17, 191, 77, 222, 28, 219, 147, 17, 107, + 222, 28, 219, 147, 17, 109, 222, 28, 219, 147, 17, 138, 222, 28, 219, + 147, 17, 134, 222, 28, 219, 147, 17, 149, 222, 28, 219, 147, 17, 169, + 222, 28, 219, 147, 17, 175, 222, 28, 219, 147, 17, 171, 222, 28, 219, + 147, 17, 178, 222, 28, 219, 147, 1, 155, 222, 28, 219, 147, 1, 221, 215, + 222, 28, 219, 147, 1, 231, 240, 222, 28, 219, 147, 1, 214, 68, 222, 28, + 219, 147, 1, 188, 222, 28, 219, 147, 1, 203, 165, 222, 28, 219, 147, 1, + 191, 123, 222, 28, 219, 147, 1, 212, 101, 222, 28, 219, 147, 1, 190, 190, + 222, 28, 219, 147, 1, 228, 164, 222, 28, 219, 147, 1, 180, 222, 28, 219, + 147, 1, 168, 222, 28, 219, 147, 1, 209, 228, 222, 28, 219, 147, 1, 174, + 222, 28, 219, 147, 1, 238, 32, 222, 28, 219, 147, 1, 249, 153, 222, 28, + 219, 147, 1, 165, 222, 28, 219, 147, 1, 170, 222, 28, 219, 147, 1, 173, + 222, 28, 219, 147, 1, 193, 190, 222, 28, 219, 147, 1, 199, 49, 222, 28, + 219, 147, 1, 140, 222, 28, 219, 147, 1, 195, 188, 222, 28, 219, 147, 1, + 247, 160, 222, 28, 219, 147, 1, 65, 222, 28, 219, 147, 1, 211, 151, 222, + 28, 219, 147, 1, 68, 222, 28, 219, 147, 1, 211, 87, 222, 28, 219, 147, + 18, 196, 152, 222, 28, 219, 147, 18, 71, 222, 28, 219, 147, 18, 66, 222, + 28, 219, 147, 18, 234, 188, 222, 28, 219, 147, 18, 74, 222, 28, 219, 147, + 163, 209, 90, 222, 28, 219, 147, 163, 247, 135, 222, 28, 219, 147, 163, + 247, 136, 209, 90, 222, 28, 219, 147, 3, 238, 147, 222, 28, 219, 147, 3, + 202, 230, 207, 67, 1, 155, 207, 67, 1, 231, 240, 207, 67, 1, 214, 68, + 207, 67, 1, 190, 190, 207, 67, 1, 238, 32, 207, 67, 1, 180, 207, 67, 1, + 168, 207, 67, 1, 249, 153, 207, 67, 1, 174, 207, 67, 1, 247, 160, 207, + 67, 1, 223, 32, 207, 67, 1, 212, 101, 207, 67, 1, 188, 207, 67, 1, 165, + 207, 67, 1, 173, 207, 67, 1, 170, 207, 67, 1, 193, 190, 207, 67, 1, 140, + 207, 67, 1, 217, 11, 207, 67, 1, 214, 47, 207, 67, 1, 214, 162, 207, 67, + 1, 212, 66, 207, 67, 1, 65, 207, 67, 18, 3, 68, 207, 67, 18, 3, 66, 207, + 67, 18, 3, 71, 207, 67, 18, 3, 251, 236, 207, 67, 18, 3, 74, 207, 67, 18, + 3, 250, 163, 207, 67, 18, 3, 233, 242, 207, 67, 18, 3, 234, 217, 207, 67, + 120, 3, 214, 70, 207, 67, 120, 3, 215, 61, 207, 67, 120, 3, 146, 207, 67, + 120, 3, 230, 116, 207, 67, 195, 40, 207, 67, 205, 54, 77, 30, 147, 198, + 164, 30, 147, 198, 163, 30, 147, 198, 161, 30, 147, 198, 166, 30, 147, + 206, 234, 30, 147, 206, 218, 30, 147, 206, 213, 30, 147, 206, 215, 30, + 147, 206, 231, 30, 147, 206, 224, 30, 147, 206, 217, 30, 147, 206, 236, + 30, 147, 206, 219, 30, 147, 206, 238, 30, 147, 206, 235, 30, 147, 216, + 73, 30, 147, 216, 64, 30, 147, 216, 67, 30, 147, 209, 154, 30, 147, 209, + 165, 30, 147, 209, 166, 30, 147, 201, 159, 30, 147, 223, 212, 30, 147, + 223, 219, 30, 147, 201, 170, 30, 147, 201, 157, 30, 147, 209, 208, 30, + 147, 229, 137, 30, 147, 201, 154, 223, 16, 3, 210, 143, 223, 16, 3, 247, + 39, 223, 16, 3, 219, 246, 223, 16, 3, 193, 71, 223, 16, 1, 65, 223, 16, + 1, 228, 74, 222, 32, 223, 16, 1, 68, 223, 16, 1, 223, 199, 223, 16, 1, + 66, 223, 16, 1, 210, 221, 247, 9, 223, 16, 1, 214, 69, 219, 203, 223, 16, + 1, 214, 69, 219, 204, 207, 131, 223, 16, 1, 71, 223, 16, 1, 251, 236, + 223, 16, 1, 74, 223, 16, 1, 155, 223, 16, 1, 222, 142, 205, 124, 223, 16, + 1, 222, 142, 215, 107, 223, 16, 1, 231, 240, 223, 16, 1, 231, 241, 215, + 107, 223, 16, 1, 214, 68, 223, 16, 1, 247, 160, 223, 16, 1, 247, 161, + 215, 107, 223, 16, 1, 223, 32, 223, 16, 1, 212, 102, 215, 107, 223, 16, + 1, 223, 33, 217, 116, 223, 16, 1, 212, 101, 223, 16, 1, 197, 132, 223, + 16, 1, 197, 133, 217, 116, 223, 16, 1, 237, 191, 223, 16, 1, 237, 192, + 217, 116, 223, 16, 1, 215, 7, 215, 107, 223, 16, 1, 190, 190, 223, 16, 1, + 199, 252, 215, 107, 223, 16, 1, 238, 32, 223, 16, 1, 238, 33, 217, 116, + 223, 16, 1, 180, 223, 16, 1, 168, 223, 16, 1, 210, 221, 215, 107, 223, + 16, 1, 249, 153, 223, 16, 1, 249, 154, 215, 107, 223, 16, 1, 174, 223, + 16, 1, 170, 223, 16, 1, 165, 223, 16, 1, 207, 186, 251, 246, 223, 16, 1, + 173, 223, 16, 1, 193, 190, 223, 16, 1, 205, 207, 215, 107, 223, 16, 1, + 205, 207, 217, 116, 223, 16, 1, 188, 223, 16, 1, 140, 223, 16, 3, 247, + 40, 199, 100, 223, 16, 18, 3, 199, 175, 223, 16, 18, 3, 198, 84, 223, 16, + 18, 3, 192, 250, 223, 16, 18, 3, 192, 251, 216, 198, 223, 16, 18, 3, 200, + 208, 223, 16, 18, 3, 200, 209, 216, 185, 223, 16, 18, 3, 199, 201, 223, + 16, 18, 3, 236, 230, 215, 106, 223, 16, 18, 3, 210, 16, 223, 16, 120, 3, + 221, 244, 223, 16, 120, 3, 210, 31, 223, 16, 120, 3, 247, 145, 223, 16, + 210, 157, 223, 16, 45, 207, 40, 223, 16, 50, 207, 40, 223, 16, 210, 209, + 251, 124, 223, 16, 210, 209, 217, 137, 223, 16, 210, 209, 218, 212, 223, + 16, 210, 209, 193, 64, 223, 16, 210, 209, 210, 158, 223, 16, 210, 209, + 219, 104, 223, 16, 210, 209, 218, 204, 223, 16, 210, 209, 252, 36, 223, + 16, 210, 209, 252, 37, 252, 36, 223, 16, 210, 209, 209, 119, 223, 16, + 153, 210, 209, 209, 119, 223, 16, 210, 153, 223, 16, 17, 191, 77, 223, + 16, 17, 107, 223, 16, 17, 109, 223, 16, 17, 138, 223, 16, 17, 134, 223, + 16, 17, 149, 223, 16, 17, 169, 223, 16, 17, 175, 223, 16, 17, 171, 223, + 16, 17, 178, 223, 16, 210, 209, 198, 127, 197, 73, 223, 16, 210, 209, + 223, 64, 80, 1, 203, 139, 231, 91, 80, 1, 203, 139, 247, 1, 80, 1, 203, + 139, 222, 252, 80, 1, 203, 139, 213, 79, 80, 1, 203, 139, 248, 203, 80, + 3, 203, 139, 205, 108, 80, 52, 1, 203, 139, 207, 85, 80, 1, 54, 220, 95, + 212, 101, 80, 1, 54, 220, 95, 233, 109, 80, 1, 54, 220, 95, 231, 240, 80, + 1, 54, 220, 95, 231, 91, 80, 1, 54, 220, 95, 223, 32, 80, 1, 54, 220, 95, + 222, 252, 80, 1, 54, 220, 95, 237, 191, 80, 1, 54, 220, 95, 237, 175, 80, + 1, 54, 220, 95, 213, 79, 80, 54, 220, 95, 17, 191, 77, 80, 54, 220, 95, + 17, 107, 80, 54, 220, 95, 17, 109, 80, 54, 220, 95, 17, 138, 80, 54, 220, + 95, 17, 134, 80, 54, 220, 95, 17, 149, 80, 54, 220, 95, 17, 169, 80, 54, + 220, 95, 17, 175, 80, 54, 220, 95, 17, 171, 80, 54, 220, 95, 17, 178, 80, + 1, 54, 220, 95, 219, 73, 80, 1, 54, 220, 95, 238, 32, 80, 1, 54, 220, 95, + 237, 68, 80, 1, 54, 220, 95, 249, 153, 80, 1, 54, 220, 95, 248, 203, 246, + 250, 1, 65, 246, 250, 1, 68, 246, 250, 1, 66, 246, 250, 1, 71, 246, 250, + 1, 251, 236, 246, 250, 1, 74, 246, 250, 1, 155, 246, 250, 1, 221, 215, + 246, 250, 1, 231, 240, 246, 250, 1, 231, 91, 246, 250, 1, 213, 233, 246, + 250, 1, 214, 68, 246, 250, 1, 247, 1, 246, 250, 1, 243, 98, 246, 250, 1, + 223, 32, 246, 250, 1, 222, 252, 246, 250, 1, 213, 221, 246, 250, 1, 213, + 224, 246, 250, 1, 213, 222, 246, 250, 1, 190, 190, 246, 250, 1, 199, 49, + 246, 250, 1, 238, 32, 246, 250, 1, 237, 68, 246, 250, 1, 212, 144, 246, + 250, 1, 180, 246, 250, 1, 237, 191, 246, 250, 1, 168, 246, 250, 1, 208, + 250, 246, 250, 1, 209, 228, 246, 250, 1, 249, 153, 246, 250, 1, 248, 203, + 246, 250, 1, 215, 143, 246, 250, 1, 174, 246, 250, 1, 249, 53, 246, 250, + 1, 170, 246, 250, 1, 165, 246, 250, 1, 173, 246, 250, 1, 195, 188, 246, + 250, 1, 201, 175, 246, 250, 1, 188, 246, 250, 1, 140, 246, 250, 18, 3, + 252, 206, 246, 250, 18, 3, 68, 246, 250, 18, 3, 223, 199, 246, 250, 18, + 3, 234, 166, 246, 250, 18, 3, 66, 246, 250, 18, 3, 211, 151, 246, 250, + 18, 3, 74, 246, 250, 18, 3, 251, 236, 246, 250, 18, 3, 250, 163, 246, + 250, 18, 3, 196, 152, 246, 250, 120, 3, 170, 246, 250, 120, 3, 165, 246, + 250, 120, 3, 173, 246, 250, 120, 3, 193, 190, 246, 250, 1, 53, 222, 152, + 246, 250, 1, 53, 232, 51, 246, 250, 1, 53, 214, 70, 246, 250, 120, 3, 53, + 214, 70, 246, 250, 1, 53, 247, 3, 246, 250, 1, 53, 200, 43, 246, 250, 1, + 53, 215, 61, 246, 250, 1, 53, 210, 236, 246, 250, 1, 53, 192, 159, 246, + 250, 1, 53, 146, 246, 250, 1, 53, 172, 246, 250, 1, 53, 201, 178, 246, + 250, 120, 3, 53, 218, 168, 246, 250, 120, 3, 53, 230, 116, 246, 250, 17, + 191, 77, 246, 250, 17, 107, 246, 250, 17, 109, 246, 250, 17, 138, 246, + 250, 17, 134, 246, 250, 17, 149, 246, 250, 17, 169, 246, 250, 17, 175, + 246, 250, 17, 171, 246, 250, 17, 178, 246, 250, 208, 152, 201, 217, 246, + 250, 208, 152, 237, 238, 246, 250, 208, 152, 55, 237, 238, 246, 250, 208, + 152, 197, 225, 237, 238, 80, 1, 221, 206, 231, 240, 80, 1, 221, 206, 247, + 160, 80, 1, 221, 206, 247, 1, 80, 1, 221, 206, 223, 32, 80, 1, 221, 206, + 222, 252, 80, 1, 221, 206, 212, 101, 80, 1, 221, 206, 197, 132, 80, 1, + 221, 206, 197, 120, 80, 1, 221, 206, 237, 191, 80, 1, 221, 206, 237, 175, + 80, 1, 221, 206, 237, 68, 80, 1, 221, 206, 180, 80, 1, 221, 206, 188, 80, + 1, 221, 206, 140, 80, 1, 221, 206, 229, 177, 80, 1, 221, 206, 233, 109, + 80, 52, 1, 221, 206, 207, 85, 80, 1, 221, 206, 192, 220, 80, 1, 221, 206, + 191, 123, 80, 1, 221, 206, 165, 80, 219, 28, 221, 206, 211, 179, 80, 219, + 28, 221, 206, 208, 46, 80, 219, 28, 221, 206, 229, 78, 80, 16, 251, 222, + 233, 215, 80, 16, 251, 222, 107, 80, 16, 251, 222, 109, 80, 1, 251, 222, + 165, 80, 3, 210, 139, 222, 62, 198, 79, 80, 3, 54, 220, 95, 198, 77, 80, + 3, 54, 220, 95, 198, 74, 80, 1, 202, 238, 210, 189, 247, 1, 80, 1, 202, + 238, 210, 189, 203, 165, 54, 195, 59, 1, 130, 221, 67, 54, 195, 59, 1, + 137, 221, 67, 54, 195, 59, 1, 130, 221, 183, 54, 195, 59, 1, 137, 221, + 183, 54, 195, 59, 1, 130, 221, 192, 54, 195, 59, 1, 137, 221, 192, 54, + 195, 59, 1, 130, 231, 3, 54, 195, 59, 1, 137, 231, 3, 54, 195, 59, 1, + 130, 213, 249, 54, 195, 59, 1, 137, 213, 249, 54, 195, 59, 1, 130, 242, + 99, 54, 195, 59, 1, 137, 242, 99, 54, 195, 59, 1, 130, 243, 68, 54, 195, + 59, 1, 137, 243, 68, 54, 195, 59, 1, 130, 202, 46, 54, 195, 59, 1, 137, + 202, 46, 54, 195, 59, 1, 130, 212, 65, 54, 195, 59, 1, 137, 212, 65, 54, + 195, 59, 1, 130, 236, 174, 54, 195, 59, 1, 137, 236, 174, 54, 195, 59, 1, + 130, 159, 54, 195, 59, 1, 137, 159, 54, 195, 59, 1, 130, 198, 241, 54, + 195, 59, 1, 137, 198, 241, 54, 195, 59, 1, 130, 213, 43, 54, 195, 59, 1, + 137, 213, 43, 54, 195, 59, 1, 130, 248, 111, 54, 195, 59, 1, 137, 248, + 111, 54, 195, 59, 1, 130, 209, 73, 54, 195, 59, 1, 137, 209, 73, 54, 195, + 59, 1, 130, 209, 199, 54, 195, 59, 1, 137, 209, 199, 54, 195, 59, 1, 130, + 232, 175, 54, 195, 59, 1, 137, 232, 175, 54, 195, 59, 1, 130, 216, 12, + 54, 195, 59, 1, 137, 216, 12, 54, 195, 59, 1, 130, 192, 12, 54, 195, 59, + 1, 137, 192, 12, 54, 195, 59, 1, 130, 206, 162, 54, 195, 59, 1, 137, 206, + 162, 54, 195, 59, 1, 130, 219, 43, 54, 195, 59, 1, 137, 219, 43, 54, 195, + 59, 1, 130, 195, 24, 54, 195, 59, 1, 137, 195, 24, 54, 195, 59, 1, 130, + 229, 23, 54, 195, 59, 1, 137, 229, 23, 54, 195, 59, 1, 130, 74, 54, 195, + 59, 1, 137, 74, 54, 195, 59, 217, 113, 222, 83, 54, 195, 59, 18, 252, + 206, 54, 195, 59, 18, 68, 54, 195, 59, 18, 196, 152, 54, 195, 59, 18, 66, + 54, 195, 59, 18, 71, 54, 195, 59, 18, 74, 54, 195, 59, 217, 113, 221, + 186, 54, 195, 59, 18, 228, 35, 54, 195, 59, 18, 196, 151, 54, 195, 59, + 18, 196, 168, 54, 195, 59, 18, 250, 161, 54, 195, 59, 18, 250, 131, 54, + 195, 59, 18, 251, 132, 54, 195, 59, 18, 251, 149, 54, 195, 59, 163, 217, + 113, 234, 147, 54, 195, 59, 163, 217, 113, 212, 143, 54, 195, 59, 163, + 217, 113, 198, 241, 54, 195, 59, 163, 217, 113, 202, 18, 54, 195, 59, 16, + 221, 44, 54, 195, 59, 16, 212, 143, 54, 195, 59, 16, 205, 152, 54, 195, + 59, 16, 229, 24, 229, 10, 54, 195, 59, 16, 221, 55, 221, 54, 216, 205, + 217, 18, 1, 71, 216, 205, 217, 18, 1, 74, 216, 205, 217, 18, 1, 247, 1, + 216, 205, 217, 18, 1, 212, 101, 216, 205, 217, 18, 1, 197, 132, 216, 205, + 217, 18, 1, 197, 120, 216, 205, 217, 18, 1, 237, 191, 216, 205, 217, 18, + 1, 237, 175, 216, 205, 217, 18, 1, 213, 79, 216, 205, 217, 18, 1, 203, + 165, 216, 205, 217, 18, 1, 201, 175, 216, 205, 217, 18, 18, 3, 223, 199, + 216, 205, 217, 18, 18, 3, 196, 30, 216, 205, 217, 18, 18, 3, 252, 170, + 216, 205, 217, 18, 18, 3, 250, 163, 216, 205, 217, 18, 18, 3, 252, 162, + 216, 205, 217, 18, 243, 116, 216, 205, 217, 18, 251, 242, 221, 173, 216, + 205, 217, 18, 251, 100, 216, 205, 217, 18, 5, 207, 46, 77, 216, 205, 217, + 18, 193, 23, 207, 46, 77, 216, 205, 217, 18, 18, 3, 195, 35, 216, 205, + 217, 18, 195, 40, 36, 5, 197, 113, 36, 5, 197, 116, 36, 5, 197, 119, 36, + 5, 197, 117, 36, 5, 197, 118, 36, 5, 197, 115, 36, 5, 237, 169, 36, 5, + 237, 171, 36, 5, 237, 174, 36, 5, 237, 172, 36, 5, 237, 173, 36, 5, 237, + 170, 36, 5, 235, 22, 36, 5, 235, 26, 36, 5, 235, 34, 36, 5, 235, 31, 36, + 5, 235, 32, 36, 5, 235, 23, 36, 5, 247, 56, 36, 5, 247, 50, 36, 5, 247, + 52, 36, 5, 247, 55, 36, 5, 247, 53, 36, 5, 247, 54, 36, 5, 247, 51, 36, + 5, 249, 53, 36, 5, 249, 32, 36, 5, 249, 44, 36, 5, 249, 52, 36, 5, 249, + 47, 36, 5, 249, 48, 36, 5, 249, 36, 8, 2, 1, 249, 82, 251, 160, 8, 2, 1, + 42, 207, 16, 8, 2, 1, 248, 135, 71, 8, 2, 1, 249, 82, 71, 8, 2, 1, 235, + 15, 4, 232, 188, 8, 2, 1, 219, 189, 233, 175, 8, 2, 1, 27, 232, 52, 4, + 238, 212, 8, 2, 1, 220, 143, 4, 223, 93, 219, 245, 206, 8, 8, 2, 1, 220, + 143, 4, 55, 82, 198, 152, 8, 2, 1, 220, 143, 4, 82, 206, 188, 8, 2, 1, + 218, 169, 4, 238, 212, 8, 2, 1, 215, 62, 4, 238, 212, 8, 2, 1, 234, 89, + 4, 238, 212, 8, 2, 1, 248, 135, 74, 8, 2, 1, 248, 135, 187, 4, 106, 8, 2, + 1, 211, 77, 187, 4, 106, 8, 2, 1, 223, 93, 211, 151, 8, 2, 1, 153, 211, + 152, 4, 106, 8, 2, 1, 153, 211, 152, 4, 228, 241, 106, 8, 2, 1, 153, 187, + 211, 72, 8, 2, 1, 153, 187, 211, 73, 4, 106, 8, 2, 1, 201, 68, 146, 8, 1, + 2, 6, 207, 222, 4, 50, 219, 212, 8, 2, 1, 207, 222, 193, 51, 230, 31, 8, + 2, 1, 55, 146, 8, 2, 1, 207, 222, 4, 238, 212, 8, 2, 1, 55, 207, 222, 4, + 238, 212, 8, 2, 1, 27, 146, 8, 2, 1, 27, 207, 222, 4, 206, 188, 8, 2, 1, + 249, 72, 234, 12, 8, 2, 1, 126, 4, 203, 40, 50, 219, 212, 8, 2, 1, 126, + 249, 88, 4, 203, 40, 50, 219, 212, 8, 2, 1, 196, 139, 8, 2, 1, 153, 196, + 139, 8, 2, 1, 126, 4, 45, 102, 8, 2, 1, 243, 95, 8, 2, 1, 243, 96, 4, + 130, 50, 206, 188, 8, 2, 1, 243, 96, 4, 130, 45, 204, 5, 8, 2, 1, 192, + 236, 4, 130, 50, 206, 188, 8, 2, 1, 192, 236, 4, 179, 45, 219, 212, 8, 2, + 1, 192, 236, 4, 179, 45, 219, 213, 23, 130, 50, 206, 188, 8, 2, 1, 192, + 236, 4, 179, 45, 219, 213, 4, 204, 5, 8, 2, 1, 192, 160, 4, 203, 40, 50, + 219, 212, 52, 248, 37, 4, 223, 93, 248, 36, 52, 1, 2, 229, 196, 52, 1, 2, + 220, 143, 4, 223, 93, 219, 245, 206, 8, 52, 1, 2, 220, 143, 4, 82, 198, + 152, 52, 1, 2, 126, 4, 45, 102, 8, 2, 1, 205, 174, 192, 95, 8, 2, 1, 223, + 81, 71, 8, 2, 1, 211, 77, 211, 151, 8, 2, 1, 196, 82, 8, 2, 1, 223, 93, + 251, 160, 35, 1, 2, 6, 211, 110, 8, 2, 1, 235, 37, 237, 3, 4, 207, 24, + 102, 8, 2, 1, 197, 170, 237, 3, 4, 207, 24, 102, 8, 2, 1, 153, 207, 222, + 4, 82, 198, 152, 52, 1, 2, 153, 193, 224, 52, 1, 45, 199, 228, 52, 1, 50, + 199, 228, 103, 2, 1, 65, 103, 2, 1, 71, 103, 2, 1, 68, 103, 2, 1, 74, + 103, 2, 1, 66, 103, 2, 1, 196, 12, 103, 2, 1, 231, 240, 103, 2, 1, 155, + 103, 2, 1, 231, 165, 103, 2, 1, 231, 53, 103, 2, 1, 231, 3, 103, 2, 1, + 230, 179, 103, 2, 1, 230, 138, 103, 2, 1, 140, 103, 2, 1, 229, 245, 103, + 2, 1, 229, 158, 103, 2, 1, 229, 23, 103, 2, 1, 228, 159, 103, 2, 1, 228, + 126, 103, 2, 1, 173, 103, 2, 1, 219, 238, 103, 2, 1, 219, 146, 103, 2, 1, + 219, 43, 103, 2, 1, 218, 225, 103, 2, 1, 218, 192, 103, 2, 1, 174, 103, + 2, 1, 216, 232, 103, 2, 1, 216, 100, 103, 2, 1, 216, 12, 103, 2, 1, 215, + 155, 103, 2, 1, 180, 103, 2, 1, 229, 47, 103, 2, 1, 214, 237, 103, 2, 1, + 214, 121, 103, 2, 1, 213, 219, 103, 2, 1, 213, 43, 103, 2, 1, 212, 178, + 103, 2, 1, 212, 112, 103, 2, 1, 208, 32, 103, 2, 1, 208, 16, 103, 2, 1, + 208, 9, 103, 2, 1, 207, 255, 103, 2, 1, 207, 244, 103, 2, 1, 207, 242, + 103, 2, 1, 188, 103, 2, 1, 206, 8, 103, 2, 1, 205, 68, 103, 2, 1, 202, + 222, 103, 2, 1, 202, 46, 103, 2, 1, 201, 4, 103, 2, 1, 200, 158, 103, 2, + 1, 238, 32, 103, 2, 1, 190, 190, 103, 2, 1, 237, 146, 103, 2, 1, 199, + 145, 103, 2, 1, 237, 44, 103, 2, 1, 198, 193, 103, 2, 1, 236, 174, 103, + 2, 1, 235, 89, 103, 2, 1, 235, 57, 103, 2, 1, 236, 186, 103, 2, 1, 198, + 115, 103, 2, 1, 198, 114, 103, 2, 1, 198, 103, 103, 2, 1, 198, 102, 103, + 2, 1, 198, 101, 103, 2, 1, 198, 100, 103, 2, 1, 197, 168, 103, 2, 1, 197, + 161, 103, 2, 1, 197, 146, 103, 2, 1, 197, 144, 103, 2, 1, 197, 140, 103, + 2, 1, 197, 139, 103, 2, 1, 193, 190, 103, 2, 1, 193, 125, 103, 2, 1, 193, + 86, 103, 2, 1, 193, 48, 103, 2, 1, 193, 0, 103, 2, 1, 192, 243, 103, 2, + 1, 170, 216, 205, 217, 18, 1, 221, 51, 216, 205, 217, 18, 1, 205, 152, + 216, 205, 217, 18, 1, 220, 96, 216, 205, 217, 18, 1, 216, 23, 216, 205, + 217, 18, 1, 168, 216, 205, 217, 18, 1, 180, 216, 205, 217, 18, 1, 243, + 87, 216, 205, 217, 18, 1, 198, 154, 216, 205, 217, 18, 1, 221, 176, 216, + 205, 217, 18, 1, 213, 239, 216, 205, 217, 18, 1, 198, 232, 216, 205, 217, + 18, 1, 193, 173, 216, 205, 217, 18, 1, 192, 106, 216, 205, 217, 18, 1, + 228, 147, 216, 205, 217, 18, 1, 196, 113, 216, 205, 217, 18, 1, 68, 216, + 205, 217, 18, 1, 209, 222, 216, 205, 217, 18, 1, 250, 175, 216, 205, 217, + 18, 1, 230, 251, 216, 205, 217, 18, 1, 222, 250, 216, 205, 217, 18, 1, + 207, 156, 216, 205, 217, 18, 1, 249, 153, 216, 205, 217, 18, 1, 222, 234, + 216, 205, 217, 18, 1, 237, 1, 216, 205, 217, 18, 1, 231, 60, 216, 205, + 217, 18, 1, 237, 46, 216, 205, 217, 18, 1, 248, 198, 216, 205, 217, 18, + 1, 221, 52, 219, 9, 216, 205, 217, 18, 1, 220, 97, 219, 9, 216, 205, 217, + 18, 1, 216, 24, 219, 9, 216, 205, 217, 18, 1, 210, 221, 219, 9, 216, 205, + 217, 18, 1, 215, 7, 219, 9, 216, 205, 217, 18, 1, 198, 155, 219, 9, 216, + 205, 217, 18, 1, 213, 240, 219, 9, 216, 205, 217, 18, 1, 228, 74, 219, 9, + 216, 205, 217, 18, 18, 3, 211, 102, 216, 205, 217, 18, 18, 3, 223, 160, + 216, 205, 217, 18, 18, 3, 251, 130, 216, 205, 217, 18, 18, 3, 192, 69, + 216, 205, 217, 18, 18, 3, 202, 6, 216, 205, 217, 18, 18, 3, 196, 110, + 216, 205, 217, 18, 18, 3, 243, 114, 216, 205, 217, 18, 18, 3, 212, 127, + 216, 205, 217, 18, 243, 115, 216, 205, 217, 18, 218, 209, 223, 42, 216, + 205, 217, 18, 251, 38, 223, 42, 216, 205, 217, 18, 17, 191, 77, 216, 205, + 217, 18, 17, 107, 216, 205, 217, 18, 17, 109, 216, 205, 217, 18, 17, 138, + 216, 205, 217, 18, 17, 134, 216, 205, 217, 18, 17, 149, 216, 205, 217, + 18, 17, 169, 216, 205, 217, 18, 17, 175, 216, 205, 217, 18, 17, 171, 216, + 205, 217, 18, 17, 178, 30, 222, 174, 212, 3, 30, 222, 174, 212, 8, 30, + 222, 174, 192, 5, 30, 222, 174, 192, 4, 30, 222, 174, 192, 3, 30, 222, + 174, 196, 218, 30, 222, 174, 196, 222, 30, 222, 174, 191, 219, 30, 222, + 174, 191, 215, 30, 222, 174, 233, 241, 30, 222, 174, 233, 239, 30, 222, + 174, 233, 240, 30, 222, 174, 233, 237, 30, 222, 174, 228, 60, 30, 222, + 174, 228, 59, 30, 222, 174, 228, 57, 30, 222, 174, 228, 58, 30, 222, 174, + 228, 63, 30, 222, 174, 228, 56, 30, 222, 174, 228, 55, 30, 222, 174, 228, + 65, 30, 222, 174, 251, 24, 30, 222, 174, 251, 23, 30, 125, 213, 197, 30, + 125, 213, 203, 30, 125, 201, 156, 30, 125, 201, 155, 30, 125, 198, 163, + 30, 125, 198, 161, 30, 125, 198, 160, 30, 125, 198, 166, 30, 125, 198, + 167, 30, 125, 198, 159, 30, 125, 206, 218, 30, 125, 206, 233, 30, 125, + 201, 162, 30, 125, 206, 230, 30, 125, 206, 220, 30, 125, 206, 222, 30, + 125, 206, 209, 30, 125, 206, 210, 30, 125, 222, 68, 30, 125, 216, 72, 30, + 125, 216, 66, 30, 125, 201, 166, 30, 125, 216, 69, 30, 125, 216, 75, 30, + 125, 209, 150, 30, 125, 209, 159, 30, 125, 209, 163, 30, 125, 201, 164, + 30, 125, 209, 153, 30, 125, 209, 167, 30, 125, 209, 168, 30, 125, 202, + 152, 30, 125, 202, 155, 30, 125, 201, 160, 30, 125, 201, 158, 30, 125, + 202, 150, 30, 125, 202, 158, 30, 125, 202, 159, 30, 125, 202, 144, 30, + 125, 202, 157, 30, 125, 210, 147, 30, 125, 210, 148, 30, 125, 192, 53, + 30, 125, 192, 56, 30, 125, 243, 22, 30, 125, 243, 21, 30, 125, 201, 171, + 30, 125, 209, 206, 30, 125, 209, 205, 12, 15, 225, 190, 12, 15, 225, 189, + 12, 15, 225, 188, 12, 15, 225, 187, 12, 15, 225, 186, 12, 15, 225, 185, + 12, 15, 225, 184, 12, 15, 225, 183, 12, 15, 225, 182, 12, 15, 225, 181, + 12, 15, 225, 180, 12, 15, 225, 179, 12, 15, 225, 178, 12, 15, 225, 177, + 12, 15, 225, 176, 12, 15, 225, 175, 12, 15, 225, 174, 12, 15, 225, 173, + 12, 15, 225, 172, 12, 15, 225, 171, 12, 15, 225, 170, 12, 15, 225, 169, + 12, 15, 225, 168, 12, 15, 225, 167, 12, 15, 225, 166, 12, 15, 225, 165, + 12, 15, 225, 164, 12, 15, 225, 163, 12, 15, 225, 162, 12, 15, 225, 161, + 12, 15, 225, 160, 12, 15, 225, 159, 12, 15, 225, 158, 12, 15, 225, 157, + 12, 15, 225, 156, 12, 15, 225, 155, 12, 15, 225, 154, 12, 15, 225, 153, + 12, 15, 225, 152, 12, 15, 225, 151, 12, 15, 225, 150, 12, 15, 225, 149, + 12, 15, 225, 148, 12, 15, 225, 147, 12, 15, 225, 146, 12, 15, 225, 145, + 12, 15, 225, 144, 12, 15, 225, 143, 12, 15, 225, 142, 12, 15, 225, 141, + 12, 15, 225, 140, 12, 15, 225, 139, 12, 15, 225, 138, 12, 15, 225, 137, + 12, 15, 225, 136, 12, 15, 225, 135, 12, 15, 225, 134, 12, 15, 225, 133, + 12, 15, 225, 132, 12, 15, 225, 131, 12, 15, 225, 130, 12, 15, 225, 129, + 12, 15, 225, 128, 12, 15, 225, 127, 12, 15, 225, 126, 12, 15, 225, 125, + 12, 15, 225, 124, 12, 15, 225, 123, 12, 15, 225, 122, 12, 15, 225, 121, + 12, 15, 225, 120, 12, 15, 225, 119, 12, 15, 225, 118, 12, 15, 225, 117, + 12, 15, 225, 116, 12, 15, 225, 115, 12, 15, 225, 114, 12, 15, 225, 113, + 12, 15, 225, 112, 12, 15, 225, 111, 12, 15, 225, 110, 12, 15, 225, 109, + 12, 15, 225, 108, 12, 15, 225, 107, 12, 15, 225, 106, 12, 15, 225, 105, + 12, 15, 225, 104, 12, 15, 225, 103, 12, 15, 225, 102, 12, 15, 225, 101, + 12, 15, 225, 100, 12, 15, 225, 99, 12, 15, 225, 98, 12, 15, 225, 97, 12, + 15, 225, 96, 12, 15, 225, 95, 12, 15, 225, 94, 12, 15, 225, 93, 12, 15, + 225, 92, 12, 15, 225, 91, 12, 15, 225, 90, 12, 15, 225, 89, 12, 15, 225, + 88, 12, 15, 225, 87, 12, 15, 225, 86, 12, 15, 225, 85, 12, 15, 225, 84, + 12, 15, 225, 83, 12, 15, 225, 82, 12, 15, 225, 81, 12, 15, 225, 80, 12, + 15, 225, 79, 12, 15, 225, 78, 12, 15, 225, 77, 12, 15, 225, 76, 12, 15, + 225, 75, 12, 15, 225, 74, 12, 15, 225, 73, 12, 15, 225, 72, 12, 15, 225, + 71, 12, 15, 225, 70, 12, 15, 225, 69, 12, 15, 225, 68, 12, 15, 225, 67, + 12, 15, 225, 66, 12, 15, 225, 65, 12, 15, 225, 64, 12, 15, 225, 63, 12, + 15, 225, 62, 12, 15, 225, 61, 12, 15, 225, 60, 12, 15, 225, 59, 12, 15, + 225, 58, 12, 15, 225, 57, 12, 15, 225, 56, 12, 15, 225, 55, 12, 15, 225, + 54, 12, 15, 225, 53, 12, 15, 225, 52, 12, 15, 225, 51, 12, 15, 225, 50, + 12, 15, 225, 49, 12, 15, 225, 48, 12, 15, 225, 47, 12, 15, 225, 46, 12, + 15, 225, 45, 12, 15, 225, 44, 12, 15, 225, 43, 12, 15, 225, 42, 12, 15, + 225, 41, 12, 15, 225, 40, 12, 15, 225, 39, 12, 15, 225, 38, 12, 15, 225, + 37, 12, 15, 225, 36, 12, 15, 225, 35, 12, 15, 225, 34, 12, 15, 225, 33, + 12, 15, 225, 32, 12, 15, 225, 31, 12, 15, 225, 30, 12, 15, 225, 29, 12, + 15, 225, 28, 12, 15, 225, 27, 12, 15, 225, 26, 12, 15, 225, 25, 12, 15, + 225, 24, 12, 15, 225, 23, 12, 15, 225, 22, 12, 15, 225, 21, 12, 15, 225, + 20, 12, 15, 225, 19, 12, 15, 225, 18, 12, 15, 225, 17, 12, 15, 225, 16, + 12, 15, 225, 15, 12, 15, 225, 14, 12, 15, 225, 13, 12, 15, 225, 12, 12, + 15, 225, 11, 12, 15, 225, 10, 12, 15, 225, 9, 12, 15, 225, 8, 12, 15, + 225, 7, 12, 15, 225, 6, 12, 15, 225, 5, 12, 15, 225, 4, 12, 15, 225, 3, + 12, 15, 225, 2, 12, 15, 225, 1, 12, 15, 225, 0, 12, 15, 224, 255, 12, 15, + 224, 254, 12, 15, 224, 253, 12, 15, 224, 252, 12, 15, 224, 251, 12, 15, + 224, 250, 12, 15, 224, 249, 12, 15, 224, 248, 12, 15, 224, 247, 12, 15, + 224, 246, 12, 15, 224, 245, 12, 15, 224, 244, 12, 15, 224, 243, 12, 15, + 224, 242, 12, 15, 224, 241, 12, 15, 224, 240, 12, 15, 224, 239, 12, 15, + 224, 238, 12, 15, 224, 237, 12, 15, 224, 236, 12, 15, 224, 235, 12, 15, + 224, 234, 12, 15, 224, 233, 12, 15, 224, 232, 12, 15, 224, 231, 12, 15, + 224, 230, 12, 15, 224, 229, 12, 15, 224, 228, 12, 15, 224, 227, 12, 15, + 224, 226, 12, 15, 224, 225, 12, 15, 224, 224, 12, 15, 224, 223, 12, 15, + 224, 222, 12, 15, 224, 221, 12, 15, 224, 220, 12, 15, 224, 219, 12, 15, + 224, 218, 12, 15, 224, 217, 12, 15, 224, 216, 12, 15, 224, 215, 12, 15, + 224, 214, 12, 15, 224, 213, 12, 15, 224, 212, 12, 15, 224, 211, 12, 15, + 224, 210, 12, 15, 224, 209, 12, 15, 224, 208, 12, 15, 224, 207, 12, 15, + 224, 206, 12, 15, 224, 205, 12, 15, 224, 204, 12, 15, 224, 203, 12, 15, + 224, 202, 12, 15, 224, 201, 12, 15, 224, 200, 12, 15, 224, 199, 12, 15, + 224, 198, 12, 15, 224, 197, 12, 15, 224, 196, 12, 15, 224, 195, 12, 15, + 224, 194, 12, 15, 224, 193, 12, 15, 224, 192, 12, 15, 224, 191, 12, 15, + 224, 190, 12, 15, 224, 189, 12, 15, 224, 188, 12, 15, 224, 187, 12, 15, + 224, 186, 12, 15, 224, 185, 12, 15, 224, 184, 12, 15, 224, 183, 12, 15, + 224, 182, 12, 15, 224, 181, 12, 15, 224, 180, 12, 15, 224, 179, 12, 15, + 224, 178, 12, 15, 224, 177, 12, 15, 224, 176, 12, 15, 224, 175, 12, 15, + 224, 174, 12, 15, 224, 173, 12, 15, 224, 172, 12, 15, 224, 171, 12, 15, + 224, 170, 12, 15, 224, 169, 12, 15, 224, 168, 12, 15, 224, 167, 12, 15, + 224, 166, 12, 15, 224, 165, 12, 15, 224, 164, 12, 15, 224, 163, 12, 15, + 224, 162, 12, 15, 224, 161, 12, 15, 224, 160, 12, 15, 224, 159, 12, 15, + 224, 158, 12, 15, 224, 157, 12, 15, 224, 156, 12, 15, 224, 155, 12, 15, + 224, 154, 12, 15, 224, 153, 12, 15, 224, 152, 12, 15, 224, 151, 12, 15, + 224, 150, 12, 15, 224, 149, 12, 15, 224, 148, 12, 15, 224, 147, 12, 15, + 224, 146, 12, 15, 224, 145, 12, 15, 224, 144, 12, 15, 224, 143, 12, 15, + 224, 142, 12, 15, 224, 141, 12, 15, 224, 140, 12, 15, 224, 139, 12, 15, + 224, 138, 12, 15, 224, 137, 12, 15, 224, 136, 12, 15, 224, 135, 12, 15, + 224, 134, 12, 15, 224, 133, 12, 15, 224, 132, 12, 15, 224, 131, 12, 15, + 224, 130, 12, 15, 224, 129, 12, 15, 224, 128, 12, 15, 224, 127, 12, 15, + 224, 126, 12, 15, 224, 125, 12, 15, 224, 124, 12, 15, 224, 123, 12, 15, + 224, 122, 12, 15, 224, 121, 12, 15, 224, 120, 12, 15, 224, 119, 12, 15, + 224, 118, 12, 15, 224, 117, 12, 15, 224, 116, 12, 15, 224, 115, 12, 15, + 224, 114, 12, 15, 224, 113, 12, 15, 224, 112, 12, 15, 224, 111, 12, 15, + 224, 110, 12, 15, 224, 109, 12, 15, 224, 108, 12, 15, 224, 107, 12, 15, + 224, 106, 12, 15, 224, 105, 12, 15, 224, 104, 12, 15, 224, 103, 12, 15, + 224, 102, 12, 15, 224, 101, 12, 15, 224, 100, 12, 15, 224, 99, 12, 15, + 224, 98, 12, 15, 224, 97, 12, 15, 224, 96, 12, 15, 224, 95, 12, 15, 224, + 94, 12, 15, 224, 93, 12, 15, 224, 92, 12, 15, 224, 91, 12, 15, 224, 90, + 12, 15, 224, 89, 12, 15, 224, 88, 12, 15, 224, 87, 12, 15, 224, 86, 12, + 15, 224, 85, 12, 15, 224, 84, 12, 15, 224, 83, 12, 15, 224, 82, 12, 15, + 224, 81, 12, 15, 224, 80, 12, 15, 224, 79, 12, 15, 224, 78, 12, 15, 224, + 77, 12, 15, 224, 76, 12, 15, 224, 75, 12, 15, 224, 74, 12, 15, 224, 73, + 12, 15, 224, 72, 12, 15, 224, 71, 12, 15, 224, 70, 12, 15, 224, 69, 12, + 15, 224, 68, 12, 15, 224, 67, 12, 15, 224, 66, 12, 15, 224, 65, 12, 15, + 224, 64, 12, 15, 224, 63, 12, 15, 224, 62, 12, 15, 224, 61, 12, 15, 224, + 60, 12, 15, 224, 59, 12, 15, 224, 58, 12, 15, 224, 57, 12, 15, 224, 56, + 12, 15, 224, 55, 12, 15, 224, 54, 12, 15, 224, 53, 12, 15, 224, 52, 12, + 15, 224, 51, 12, 15, 224, 50, 12, 15, 224, 49, 12, 15, 224, 48, 12, 15, + 224, 47, 12, 15, 224, 46, 12, 15, 224, 45, 12, 15, 224, 44, 12, 15, 224, + 43, 12, 15, 224, 42, 12, 15, 224, 41, 12, 15, 224, 40, 12, 15, 224, 39, + 12, 15, 224, 38, 12, 15, 224, 37, 12, 15, 224, 36, 12, 15, 224, 35, 12, + 15, 224, 34, 12, 15, 224, 33, 12, 15, 224, 32, 12, 15, 224, 31, 12, 15, + 224, 30, 12, 15, 224, 29, 12, 15, 224, 28, 12, 15, 224, 27, 12, 15, 224, + 26, 12, 15, 224, 25, 12, 15, 224, 24, 12, 15, 224, 23, 12, 15, 224, 22, + 12, 15, 224, 21, 12, 15, 224, 20, 12, 15, 224, 19, 12, 15, 224, 18, 12, + 15, 224, 17, 12, 15, 224, 16, 12, 15, 224, 15, 12, 15, 224, 14, 12, 15, + 224, 13, 12, 15, 224, 12, 12, 15, 224, 11, 12, 15, 224, 10, 12, 15, 224, + 9, 12, 15, 224, 8, 12, 15, 224, 7, 12, 15, 224, 6, 12, 15, 224, 5, 12, + 15, 224, 4, 12, 15, 224, 3, 12, 15, 224, 2, 12, 15, 224, 1, 12, 15, 224, + 0, 12, 15, 223, 255, 12, 15, 223, 254, 12, 15, 223, 253, 12, 15, 223, + 252, 12, 15, 223, 251, 12, 15, 223, 250, 12, 15, 223, 249, 12, 15, 223, + 248, 12, 15, 223, 247, 12, 15, 223, 246, 12, 15, 223, 245, 12, 15, 223, + 244, 12, 15, 223, 243, 12, 15, 223, 242, 12, 15, 223, 241, 12, 15, 223, + 240, 12, 15, 223, 239, 12, 15, 223, 238, 12, 15, 223, 237, 12, 15, 223, + 236, 12, 15, 223, 235, 12, 15, 223, 234, 12, 15, 223, 233, 12, 15, 223, + 232, 12, 15, 223, 231, 8, 2, 34, 233, 27, 8, 2, 34, 233, 23, 8, 2, 34, + 232, 220, 8, 2, 34, 233, 26, 8, 2, 34, 233, 25, 8, 2, 34, 179, 206, 9, + 200, 43, 8, 2, 34, 201, 118, 250, 249, 2, 34, 216, 187, 212, 253, 250, + 249, 2, 34, 216, 187, 234, 195, 250, 249, 2, 34, 216, 187, 223, 131, 250, + 249, 2, 34, 195, 75, 212, 253, 250, 249, 2, 34, 216, 187, 192, 212, 136, + 1, 191, 251, 4, 229, 119, 136, 209, 62, 222, 181, 195, 166, 136, 34, 192, + 31, 191, 251, 191, 251, 210, 88, 136, 1, 251, 152, 250, 126, 136, 1, 193, + 78, 251, 192, 136, 1, 193, 78, 237, 253, 136, 1, 193, 78, 229, 245, 136, + 1, 193, 78, 222, 106, 136, 1, 193, 78, 220, 27, 136, 1, 193, 78, 53, 216, + 193, 136, 1, 193, 78, 207, 38, 136, 1, 193, 78, 199, 162, 136, 1, 251, + 152, 108, 56, 136, 1, 203, 70, 4, 203, 70, 236, 140, 136, 1, 203, 70, 4, + 202, 175, 236, 140, 136, 1, 203, 70, 4, 238, 17, 23, 203, 70, 236, 140, + 136, 1, 203, 70, 4, 238, 17, 23, 202, 175, 236, 140, 136, 1, 131, 4, 210, + 88, 136, 1, 131, 4, 208, 84, 136, 1, 131, 4, 217, 70, 136, 1, 248, 215, + 4, 238, 16, 136, 1, 231, 39, 4, 238, 16, 136, 1, 237, 254, 4, 238, 16, + 136, 1, 229, 246, 4, 217, 70, 136, 1, 195, 159, 4, 238, 16, 136, 1, 191, + 92, 4, 238, 16, 136, 1, 199, 74, 4, 238, 16, 136, 1, 191, 251, 4, 238, + 16, 136, 1, 53, 222, 107, 4, 238, 16, 136, 1, 222, 107, 4, 238, 16, 136, + 1, 220, 28, 4, 238, 16, 136, 1, 216, 194, 4, 238, 16, 136, 1, 212, 131, + 4, 238, 16, 136, 1, 205, 149, 4, 238, 16, 136, 1, 53, 210, 64, 4, 238, + 16, 136, 1, 210, 64, 4, 238, 16, 136, 1, 197, 164, 4, 238, 16, 136, 1, + 208, 43, 4, 238, 16, 136, 1, 207, 39, 4, 238, 16, 136, 1, 203, 70, 4, + 238, 16, 136, 1, 199, 163, 4, 238, 16, 136, 1, 195, 159, 4, 229, 7, 136, + 1, 248, 215, 4, 207, 161, 136, 1, 222, 107, 4, 207, 161, 136, 1, 210, 64, + 4, 207, 161, 136, 34, 131, 220, 27, 9, 1, 131, 193, 151, 76, 20, 9, 1, + 131, 193, 151, 53, 20, 9, 1, 249, 0, 76, 20, 9, 1, 249, 0, 53, 20, 9, 1, + 249, 0, 89, 20, 9, 1, 249, 0, 216, 217, 20, 9, 1, 210, 42, 76, 20, 9, 1, + 210, 42, 53, 20, 9, 1, 210, 42, 89, 20, 9, 1, 210, 42, 216, 217, 20, 9, + 1, 248, 244, 76, 20, 9, 1, 248, 244, 53, 20, 9, 1, 248, 244, 89, 20, 9, + 1, 248, 244, 216, 217, 20, 9, 1, 197, 123, 76, 20, 9, 1, 197, 123, 53, + 20, 9, 1, 197, 123, 89, 20, 9, 1, 197, 123, 216, 217, 20, 9, 1, 199, 113, + 76, 20, 9, 1, 199, 113, 53, 20, 9, 1, 199, 113, 89, 20, 9, 1, 199, 113, + 216, 217, 20, 9, 1, 197, 125, 76, 20, 9, 1, 197, 125, 53, 20, 9, 1, 197, + 125, 89, 20, 9, 1, 197, 125, 216, 217, 20, 9, 1, 195, 147, 76, 20, 9, 1, + 195, 147, 53, 20, 9, 1, 195, 147, 89, 20, 9, 1, 195, 147, 216, 217, 20, + 9, 1, 210, 40, 76, 20, 9, 1, 210, 40, 53, 20, 9, 1, 210, 40, 89, 20, 9, + 1, 210, 40, 216, 217, 20, 9, 1, 235, 42, 76, 20, 9, 1, 235, 42, 53, 20, + 9, 1, 235, 42, 89, 20, 9, 1, 235, 42, 216, 217, 20, 9, 1, 212, 88, 76, + 20, 9, 1, 212, 88, 53, 20, 9, 1, 212, 88, 89, 20, 9, 1, 212, 88, 216, + 217, 20, 9, 1, 199, 150, 76, 20, 9, 1, 199, 150, 53, 20, 9, 1, 199, 150, + 89, 20, 9, 1, 199, 150, 216, 217, 20, 9, 1, 199, 148, 76, 20, 9, 1, 199, + 148, 53, 20, 9, 1, 199, 148, 89, 20, 9, 1, 199, 148, 216, 217, 20, 9, 1, + 237, 189, 76, 20, 9, 1, 237, 189, 53, 20, 9, 1, 238, 11, 76, 20, 9, 1, + 238, 11, 53, 20, 9, 1, 235, 79, 76, 20, 9, 1, 235, 79, 53, 20, 9, 1, 237, + 187, 76, 20, 9, 1, 237, 187, 53, 20, 9, 1, 223, 4, 76, 20, 9, 1, 223, 4, + 53, 20, 9, 1, 206, 102, 76, 20, 9, 1, 206, 102, 53, 20, 9, 1, 222, 5, 76, + 20, 9, 1, 222, 5, 53, 20, 9, 1, 222, 5, 89, 20, 9, 1, 222, 5, 216, 217, + 20, 9, 1, 231, 228, 76, 20, 9, 1, 231, 228, 53, 20, 9, 1, 231, 228, 89, + 20, 9, 1, 231, 228, 216, 217, 20, 9, 1, 230, 167, 76, 20, 9, 1, 230, 167, + 53, 20, 9, 1, 230, 167, 89, 20, 9, 1, 230, 167, 216, 217, 20, 9, 1, 213, + 248, 76, 20, 9, 1, 213, 248, 53, 20, 9, 1, 213, 248, 89, 20, 9, 1, 213, + 248, 216, 217, 20, 9, 1, 213, 25, 231, 58, 76, 20, 9, 1, 213, 25, 231, + 58, 53, 20, 9, 1, 206, 166, 76, 20, 9, 1, 206, 166, 53, 20, 9, 1, 206, + 166, 89, 20, 9, 1, 206, 166, 216, 217, 20, 9, 1, 229, 211, 4, 99, 93, 76, + 20, 9, 1, 229, 211, 4, 99, 93, 53, 20, 9, 1, 229, 211, 231, 1, 76, 20, 9, + 1, 229, 211, 231, 1, 53, 20, 9, 1, 229, 211, 231, 1, 89, 20, 9, 1, 229, + 211, 231, 1, 216, 217, 20, 9, 1, 229, 211, 236, 171, 76, 20, 9, 1, 229, + 211, 236, 171, 53, 20, 9, 1, 229, 211, 236, 171, 89, 20, 9, 1, 229, 211, + 236, 171, 216, 217, 20, 9, 1, 99, 249, 81, 76, 20, 9, 1, 99, 249, 81, 53, + 20, 9, 1, 99, 249, 81, 4, 230, 58, 93, 76, 20, 9, 1, 99, 249, 81, 4, 230, + 58, 93, 53, 20, 9, 16, 75, 58, 9, 16, 75, 60, 9, 16, 105, 185, 58, 9, 16, + 105, 185, 60, 9, 16, 115, 185, 58, 9, 16, 115, 185, 60, 9, 16, 115, 185, + 209, 58, 235, 119, 58, 9, 16, 115, 185, 209, 58, 235, 119, 60, 9, 16, + 232, 128, 185, 58, 9, 16, 232, 128, 185, 60, 9, 16, 55, 81, 249, 88, 60, + 9, 16, 105, 185, 195, 85, 58, 9, 16, 105, 185, 195, 85, 60, 9, 16, 206, + 188, 9, 16, 2, 199, 220, 58, 9, 16, 2, 199, 220, 60, 9, 16, 193, 151, 58, + 9, 1, 214, 71, 76, 20, 9, 1, 214, 71, 53, 20, 9, 1, 214, 71, 89, 20, 9, + 1, 214, 71, 216, 217, 20, 9, 1, 126, 76, 20, 9, 1, 126, 53, 20, 9, 1, + 211, 152, 76, 20, 9, 1, 211, 152, 53, 20, 9, 1, 191, 226, 76, 20, 9, 1, + 191, 226, 53, 20, 9, 1, 126, 4, 230, 58, 93, 76, 20, 9, 1, 195, 154, 76, + 20, 9, 1, 195, 154, 53, 20, 9, 1, 221, 132, 211, 152, 76, 20, 9, 1, 221, + 132, 211, 152, 53, 20, 9, 1, 221, 132, 191, 226, 76, 20, 9, 1, 221, 132, + 191, 226, 53, 20, 9, 1, 235, 15, 76, 20, 9, 1, 235, 15, 53, 20, 9, 1, + 235, 15, 89, 20, 9, 1, 235, 15, 216, 217, 20, 9, 1, 196, 137, 222, 26, + 221, 132, 131, 217, 100, 89, 20, 9, 1, 196, 137, 222, 26, 221, 132, 131, + 217, 100, 216, 217, 20, 9, 34, 99, 4, 230, 58, 93, 4, 131, 76, 20, 9, 34, + 99, 4, 230, 58, 93, 4, 131, 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 252, + 26, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, 252, 26, 53, 20, 9, 34, 99, 4, + 230, 58, 93, 4, 193, 134, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, 193, 134, + 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 126, 76, 20, 9, 34, 99, 4, 230, 58, + 93, 4, 126, 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 211, 152, 76, 20, 9, + 34, 99, 4, 230, 58, 93, 4, 211, 152, 53, 20, 9, 34, 99, 4, 230, 58, 93, + 4, 191, 226, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, 191, 226, 53, 20, 9, + 34, 99, 4, 230, 58, 93, 4, 235, 15, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, + 235, 15, 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 235, 15, 89, 20, 9, 34, + 196, 137, 221, 132, 99, 4, 230, 58, 93, 4, 131, 217, 100, 76, 20, 9, 34, + 196, 137, 221, 132, 99, 4, 230, 58, 93, 4, 131, 217, 100, 53, 20, 9, 34, + 196, 137, 221, 132, 99, 4, 230, 58, 93, 4, 131, 217, 100, 89, 20, 9, 1, + 233, 74, 99, 76, 20, 9, 1, 233, 74, 99, 53, 20, 9, 1, 233, 74, 99, 89, + 20, 9, 1, 233, 74, 99, 216, 217, 20, 9, 34, 99, 4, 230, 58, 93, 4, 223, + 7, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, 182, 76, 20, 9, 34, 99, 4, 230, + 58, 93, 4, 92, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, 131, 217, 100, 76, + 20, 9, 34, 99, 4, 230, 58, 93, 4, 99, 76, 20, 9, 34, 248, 246, 4, 223, 7, + 76, 20, 9, 34, 248, 246, 4, 182, 76, 20, 9, 34, 248, 246, 4, 221, 211, + 76, 20, 9, 34, 248, 246, 4, 92, 76, 20, 9, 34, 248, 246, 4, 131, 217, + 100, 76, 20, 9, 34, 248, 246, 4, 99, 76, 20, 9, 34, 199, 115, 4, 223, 7, + 76, 20, 9, 34, 199, 115, 4, 182, 76, 20, 9, 34, 199, 115, 4, 221, 211, + 76, 20, 9, 34, 199, 115, 4, 92, 76, 20, 9, 34, 199, 115, 4, 131, 217, + 100, 76, 20, 9, 34, 199, 115, 4, 99, 76, 20, 9, 34, 199, 30, 4, 223, 7, + 76, 20, 9, 34, 199, 30, 4, 92, 76, 20, 9, 34, 199, 30, 4, 131, 217, 100, + 76, 20, 9, 34, 199, 30, 4, 99, 76, 20, 9, 34, 223, 7, 4, 182, 76, 20, 9, + 34, 223, 7, 4, 92, 76, 20, 9, 34, 182, 4, 223, 7, 76, 20, 9, 34, 182, 4, + 92, 76, 20, 9, 34, 221, 211, 4, 223, 7, 76, 20, 9, 34, 221, 211, 4, 182, + 76, 20, 9, 34, 221, 211, 4, 92, 76, 20, 9, 34, 205, 47, 4, 223, 7, 76, + 20, 9, 34, 205, 47, 4, 182, 76, 20, 9, 34, 205, 47, 4, 221, 211, 76, 20, + 9, 34, 205, 47, 4, 92, 76, 20, 9, 34, 205, 193, 4, 182, 76, 20, 9, 34, + 205, 193, 4, 92, 76, 20, 9, 34, 238, 27, 4, 223, 7, 76, 20, 9, 34, 238, + 27, 4, 182, 76, 20, 9, 34, 238, 27, 4, 221, 211, 76, 20, 9, 34, 238, 27, + 4, 92, 76, 20, 9, 34, 199, 220, 4, 182, 76, 20, 9, 34, 199, 220, 4, 92, + 76, 20, 9, 34, 191, 117, 4, 92, 76, 20, 9, 34, 251, 231, 4, 223, 7, 76, + 20, 9, 34, 251, 231, 4, 92, 76, 20, 9, 34, 231, 87, 4, 223, 7, 76, 20, 9, + 34, 231, 87, 4, 92, 76, 20, 9, 34, 233, 47, 4, 223, 7, 76, 20, 9, 34, + 233, 47, 4, 182, 76, 20, 9, 34, 233, 47, 4, 221, 211, 76, 20, 9, 34, 233, + 47, 4, 92, 76, 20, 9, 34, 233, 47, 4, 131, 217, 100, 76, 20, 9, 34, 233, + 47, 4, 99, 76, 20, 9, 34, 208, 90, 4, 182, 76, 20, 9, 34, 208, 90, 4, 92, + 76, 20, 9, 34, 208, 90, 4, 131, 217, 100, 76, 20, 9, 34, 208, 90, 4, 99, + 76, 20, 9, 34, 222, 107, 4, 131, 76, 20, 9, 34, 222, 107, 4, 223, 7, 76, + 20, 9, 34, 222, 107, 4, 182, 76, 20, 9, 34, 222, 107, 4, 221, 211, 76, + 20, 9, 34, 222, 107, 4, 220, 36, 76, 20, 9, 34, 222, 107, 4, 92, 76, 20, + 9, 34, 222, 107, 4, 131, 217, 100, 76, 20, 9, 34, 222, 107, 4, 99, 76, + 20, 9, 34, 220, 36, 4, 223, 7, 76, 20, 9, 34, 220, 36, 4, 182, 76, 20, 9, + 34, 220, 36, 4, 221, 211, 76, 20, 9, 34, 220, 36, 4, 92, 76, 20, 9, 34, + 220, 36, 4, 131, 217, 100, 76, 20, 9, 34, 220, 36, 4, 99, 76, 20, 9, 34, + 92, 4, 223, 7, 76, 20, 9, 34, 92, 4, 182, 76, 20, 9, 34, 92, 4, 221, 211, + 76, 20, 9, 34, 92, 4, 92, 76, 20, 9, 34, 92, 4, 131, 217, 100, 76, 20, 9, + 34, 92, 4, 99, 76, 20, 9, 34, 213, 25, 4, 223, 7, 76, 20, 9, 34, 213, 25, + 4, 182, 76, 20, 9, 34, 213, 25, 4, 221, 211, 76, 20, 9, 34, 213, 25, 4, + 92, 76, 20, 9, 34, 213, 25, 4, 131, 217, 100, 76, 20, 9, 34, 213, 25, 4, + 99, 76, 20, 9, 34, 229, 211, 4, 223, 7, 76, 20, 9, 34, 229, 211, 4, 92, + 76, 20, 9, 34, 229, 211, 4, 131, 217, 100, 76, 20, 9, 34, 229, 211, 4, + 99, 76, 20, 9, 34, 99, 4, 223, 7, 76, 20, 9, 34, 99, 4, 182, 76, 20, 9, + 34, 99, 4, 221, 211, 76, 20, 9, 34, 99, 4, 92, 76, 20, 9, 34, 99, 4, 131, + 217, 100, 76, 20, 9, 34, 99, 4, 99, 76, 20, 9, 34, 199, 42, 4, 200, 182, + 131, 76, 20, 9, 34, 207, 72, 4, 200, 182, 131, 76, 20, 9, 34, 131, 217, + 100, 4, 200, 182, 131, 76, 20, 9, 34, 203, 156, 4, 237, 244, 76, 20, 9, + 34, 203, 156, 4, 222, 51, 76, 20, 9, 34, 203, 156, 4, 233, 71, 76, 20, 9, + 34, 203, 156, 4, 237, 246, 76, 20, 9, 34, 203, 156, 4, 222, 53, 76, 20, + 9, 34, 203, 156, 4, 200, 182, 131, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, + 207, 72, 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 191, 114, 53, 20, 9, 34, + 99, 4, 230, 58, 93, 4, 92, 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 213, 25, + 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 131, 217, 100, 53, 20, 9, 34, 99, + 4, 230, 58, 93, 4, 99, 53, 20, 9, 34, 248, 246, 4, 207, 72, 53, 20, 9, + 34, 248, 246, 4, 191, 114, 53, 20, 9, 34, 248, 246, 4, 92, 53, 20, 9, 34, + 248, 246, 4, 213, 25, 53, 20, 9, 34, 248, 246, 4, 131, 217, 100, 53, 20, + 9, 34, 248, 246, 4, 99, 53, 20, 9, 34, 199, 115, 4, 207, 72, 53, 20, 9, + 34, 199, 115, 4, 191, 114, 53, 20, 9, 34, 199, 115, 4, 92, 53, 20, 9, 34, + 199, 115, 4, 213, 25, 53, 20, 9, 34, 199, 115, 4, 131, 217, 100, 53, 20, + 9, 34, 199, 115, 4, 99, 53, 20, 9, 34, 199, 30, 4, 207, 72, 53, 20, 9, + 34, 199, 30, 4, 191, 114, 53, 20, 9, 34, 199, 30, 4, 92, 53, 20, 9, 34, + 199, 30, 4, 213, 25, 53, 20, 9, 34, 199, 30, 4, 131, 217, 100, 53, 20, 9, + 34, 199, 30, 4, 99, 53, 20, 9, 34, 233, 47, 4, 131, 217, 100, 53, 20, 9, + 34, 233, 47, 4, 99, 53, 20, 9, 34, 208, 90, 4, 131, 217, 100, 53, 20, 9, + 34, 208, 90, 4, 99, 53, 20, 9, 34, 222, 107, 4, 131, 53, 20, 9, 34, 222, + 107, 4, 220, 36, 53, 20, 9, 34, 222, 107, 4, 92, 53, 20, 9, 34, 222, 107, + 4, 131, 217, 100, 53, 20, 9, 34, 222, 107, 4, 99, 53, 20, 9, 34, 220, 36, + 4, 92, 53, 20, 9, 34, 220, 36, 4, 131, 217, 100, 53, 20, 9, 34, 220, 36, + 4, 99, 53, 20, 9, 34, 92, 4, 131, 53, 20, 9, 34, 92, 4, 92, 53, 20, 9, + 34, 213, 25, 4, 207, 72, 53, 20, 9, 34, 213, 25, 4, 191, 114, 53, 20, 9, + 34, 213, 25, 4, 92, 53, 20, 9, 34, 213, 25, 4, 213, 25, 53, 20, 9, 34, + 213, 25, 4, 131, 217, 100, 53, 20, 9, 34, 213, 25, 4, 99, 53, 20, 9, 34, + 131, 217, 100, 4, 200, 182, 131, 53, 20, 9, 34, 99, 4, 207, 72, 53, 20, + 9, 34, 99, 4, 191, 114, 53, 20, 9, 34, 99, 4, 92, 53, 20, 9, 34, 99, 4, + 213, 25, 53, 20, 9, 34, 99, 4, 131, 217, 100, 53, 20, 9, 34, 99, 4, 99, + 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 223, 7, 89, 20, 9, 34, 99, 4, 230, + 58, 93, 4, 182, 89, 20, 9, 34, 99, 4, 230, 58, 93, 4, 221, 211, 89, 20, + 9, 34, 99, 4, 230, 58, 93, 4, 92, 89, 20, 9, 34, 99, 4, 230, 58, 93, 4, + 229, 211, 89, 20, 9, 34, 248, 246, 4, 223, 7, 89, 20, 9, 34, 248, 246, 4, + 182, 89, 20, 9, 34, 248, 246, 4, 221, 211, 89, 20, 9, 34, 248, 246, 4, + 92, 89, 20, 9, 34, 248, 246, 4, 229, 211, 89, 20, 9, 34, 199, 115, 4, + 223, 7, 89, 20, 9, 34, 199, 115, 4, 182, 89, 20, 9, 34, 199, 115, 4, 221, + 211, 89, 20, 9, 34, 199, 115, 4, 92, 89, 20, 9, 34, 199, 115, 4, 229, + 211, 89, 20, 9, 34, 199, 30, 4, 92, 89, 20, 9, 34, 223, 7, 4, 182, 89, + 20, 9, 34, 223, 7, 4, 92, 89, 20, 9, 34, 182, 4, 223, 7, 89, 20, 9, 34, + 182, 4, 92, 89, 20, 9, 34, 221, 211, 4, 223, 7, 89, 20, 9, 34, 221, 211, + 4, 92, 89, 20, 9, 34, 205, 47, 4, 223, 7, 89, 20, 9, 34, 205, 47, 4, 182, + 89, 20, 9, 34, 205, 47, 4, 221, 211, 89, 20, 9, 34, 205, 47, 4, 92, 89, + 20, 9, 34, 205, 193, 4, 182, 89, 20, 9, 34, 205, 193, 4, 221, 211, 89, + 20, 9, 34, 205, 193, 4, 92, 89, 20, 9, 34, 238, 27, 4, 223, 7, 89, 20, 9, + 34, 238, 27, 4, 182, 89, 20, 9, 34, 238, 27, 4, 221, 211, 89, 20, 9, 34, + 238, 27, 4, 92, 89, 20, 9, 34, 199, 220, 4, 182, 89, 20, 9, 34, 191, 117, + 4, 92, 89, 20, 9, 34, 251, 231, 4, 223, 7, 89, 20, 9, 34, 251, 231, 4, + 92, 89, 20, 9, 34, 231, 87, 4, 223, 7, 89, 20, 9, 34, 231, 87, 4, 92, 89, + 20, 9, 34, 233, 47, 4, 223, 7, 89, 20, 9, 34, 233, 47, 4, 182, 89, 20, 9, + 34, 233, 47, 4, 221, 211, 89, 20, 9, 34, 233, 47, 4, 92, 89, 20, 9, 34, + 208, 90, 4, 182, 89, 20, 9, 34, 208, 90, 4, 92, 89, 20, 9, 34, 222, 107, + 4, 223, 7, 89, 20, 9, 34, 222, 107, 4, 182, 89, 20, 9, 34, 222, 107, 4, + 221, 211, 89, 20, 9, 34, 222, 107, 4, 220, 36, 89, 20, 9, 34, 222, 107, + 4, 92, 89, 20, 9, 34, 220, 36, 4, 223, 7, 89, 20, 9, 34, 220, 36, 4, 182, + 89, 20, 9, 34, 220, 36, 4, 221, 211, 89, 20, 9, 34, 220, 36, 4, 92, 89, + 20, 9, 34, 220, 36, 4, 229, 211, 89, 20, 9, 34, 92, 4, 223, 7, 89, 20, 9, + 34, 92, 4, 182, 89, 20, 9, 34, 92, 4, 221, 211, 89, 20, 9, 34, 92, 4, 92, + 89, 20, 9, 34, 213, 25, 4, 223, 7, 89, 20, 9, 34, 213, 25, 4, 182, 89, + 20, 9, 34, 213, 25, 4, 221, 211, 89, 20, 9, 34, 213, 25, 4, 92, 89, 20, + 9, 34, 213, 25, 4, 229, 211, 89, 20, 9, 34, 229, 211, 4, 223, 7, 89, 20, + 9, 34, 229, 211, 4, 92, 89, 20, 9, 34, 229, 211, 4, 200, 182, 131, 89, + 20, 9, 34, 99, 4, 223, 7, 89, 20, 9, 34, 99, 4, 182, 89, 20, 9, 34, 99, + 4, 221, 211, 89, 20, 9, 34, 99, 4, 92, 89, 20, 9, 34, 99, 4, 229, 211, + 89, 20, 9, 34, 99, 4, 230, 58, 93, 4, 92, 216, 217, 20, 9, 34, 99, 4, + 230, 58, 93, 4, 229, 211, 216, 217, 20, 9, 34, 248, 246, 4, 92, 216, 217, + 20, 9, 34, 248, 246, 4, 229, 211, 216, 217, 20, 9, 34, 199, 115, 4, 92, + 216, 217, 20, 9, 34, 199, 115, 4, 229, 211, 216, 217, 20, 9, 34, 199, 30, + 4, 92, 216, 217, 20, 9, 34, 199, 30, 4, 229, 211, 216, 217, 20, 9, 34, + 205, 47, 4, 92, 216, 217, 20, 9, 34, 205, 47, 4, 229, 211, 216, 217, 20, + 9, 34, 203, 110, 4, 92, 216, 217, 20, 9, 34, 203, 110, 4, 229, 211, 216, + 217, 20, 9, 34, 222, 107, 4, 220, 36, 216, 217, 20, 9, 34, 222, 107, 4, + 92, 216, 217, 20, 9, 34, 220, 36, 4, 92, 216, 217, 20, 9, 34, 213, 25, 4, + 92, 216, 217, 20, 9, 34, 213, 25, 4, 229, 211, 216, 217, 20, 9, 34, 99, + 4, 92, 216, 217, 20, 9, 34, 99, 4, 229, 211, 216, 217, 20, 9, 34, 203, + 156, 4, 233, 71, 216, 217, 20, 9, 34, 203, 156, 4, 237, 246, 216, 217, + 20, 9, 34, 203, 156, 4, 222, 53, 216, 217, 20, 9, 34, 199, 220, 4, 131, + 217, 100, 76, 20, 9, 34, 199, 220, 4, 99, 76, 20, 9, 34, 251, 231, 4, + 131, 217, 100, 76, 20, 9, 34, 251, 231, 4, 99, 76, 20, 9, 34, 231, 87, 4, + 131, 217, 100, 76, 20, 9, 34, 231, 87, 4, 99, 76, 20, 9, 34, 205, 47, 4, + 131, 217, 100, 76, 20, 9, 34, 205, 47, 4, 99, 76, 20, 9, 34, 203, 110, 4, + 131, 217, 100, 76, 20, 9, 34, 203, 110, 4, 99, 76, 20, 9, 34, 182, 4, + 131, 217, 100, 76, 20, 9, 34, 182, 4, 99, 76, 20, 9, 34, 223, 7, 4, 131, + 217, 100, 76, 20, 9, 34, 223, 7, 4, 99, 76, 20, 9, 34, 221, 211, 4, 131, + 217, 100, 76, 20, 9, 34, 221, 211, 4, 99, 76, 20, 9, 34, 205, 193, 4, + 131, 217, 100, 76, 20, 9, 34, 205, 193, 4, 99, 76, 20, 9, 34, 238, 27, 4, + 131, 217, 100, 76, 20, 9, 34, 238, 27, 4, 99, 76, 20, 9, 34, 203, 110, 4, + 223, 7, 76, 20, 9, 34, 203, 110, 4, 182, 76, 20, 9, 34, 203, 110, 4, 221, + 211, 76, 20, 9, 34, 203, 110, 4, 92, 76, 20, 9, 34, 203, 110, 4, 207, 72, + 76, 20, 9, 34, 205, 47, 4, 207, 72, 76, 20, 9, 34, 205, 193, 4, 207, 72, + 76, 20, 9, 34, 238, 27, 4, 207, 72, 76, 20, 9, 34, 199, 220, 4, 131, 217, + 100, 53, 20, 9, 34, 199, 220, 4, 99, 53, 20, 9, 34, 251, 231, 4, 131, + 217, 100, 53, 20, 9, 34, 251, 231, 4, 99, 53, 20, 9, 34, 231, 87, 4, 131, + 217, 100, 53, 20, 9, 34, 231, 87, 4, 99, 53, 20, 9, 34, 205, 47, 4, 131, + 217, 100, 53, 20, 9, 34, 205, 47, 4, 99, 53, 20, 9, 34, 203, 110, 4, 131, + 217, 100, 53, 20, 9, 34, 203, 110, 4, 99, 53, 20, 9, 34, 182, 4, 131, + 217, 100, 53, 20, 9, 34, 182, 4, 99, 53, 20, 9, 34, 223, 7, 4, 131, 217, + 100, 53, 20, 9, 34, 223, 7, 4, 99, 53, 20, 9, 34, 221, 211, 4, 131, 217, + 100, 53, 20, 9, 34, 221, 211, 4, 99, 53, 20, 9, 34, 205, 193, 4, 131, + 217, 100, 53, 20, 9, 34, 205, 193, 4, 99, 53, 20, 9, 34, 238, 27, 4, 131, + 217, 100, 53, 20, 9, 34, 238, 27, 4, 99, 53, 20, 9, 34, 203, 110, 4, 223, + 7, 53, 20, 9, 34, 203, 110, 4, 182, 53, 20, 9, 34, 203, 110, 4, 221, 211, + 53, 20, 9, 34, 203, 110, 4, 92, 53, 20, 9, 34, 203, 110, 4, 207, 72, 53, + 20, 9, 34, 205, 47, 4, 207, 72, 53, 20, 9, 34, 205, 193, 4, 207, 72, 53, + 20, 9, 34, 238, 27, 4, 207, 72, 53, 20, 9, 34, 203, 110, 4, 223, 7, 89, + 20, 9, 34, 203, 110, 4, 182, 89, 20, 9, 34, 203, 110, 4, 221, 211, 89, + 20, 9, 34, 203, 110, 4, 92, 89, 20, 9, 34, 205, 47, 4, 229, 211, 89, 20, + 9, 34, 203, 110, 4, 229, 211, 89, 20, 9, 34, 199, 220, 4, 92, 89, 20, 9, + 34, 205, 47, 4, 223, 7, 216, 217, 20, 9, 34, 205, 47, 4, 182, 216, 217, + 20, 9, 34, 205, 47, 4, 221, 211, 216, 217, 20, 9, 34, 203, 110, 4, 223, + 7, 216, 217, 20, 9, 34, 203, 110, 4, 182, 216, 217, 20, 9, 34, 203, 110, + 4, 221, 211, 216, 217, 20, 9, 34, 199, 220, 4, 92, 216, 217, 20, 9, 34, + 191, 117, 4, 92, 216, 217, 20, 9, 34, 131, 4, 233, 69, 53, 20, 9, 34, + 131, 4, 233, 69, 76, 20, 211, 40, 45, 210, 113, 211, 40, 50, 210, 113, 9, + 34, 207, 159, 251, 173, 9, 34, 207, 167, 251, 172, 251, 107, 9, 34, 207, + 167, 251, 172, 251, 106, 9, 34, 207, 167, 251, 172, 251, 104, 9, 34, 207, + 167, 251, 172, 251, 103, 9, 34, 207, 167, 251, 172, 251, 102, 9, 34, 205, + 162, 251, 197, 193, 184, 9, 34, 251, 197, 250, 217, 9, 34, 251, 196, 250, + 217, 9, 34, 251, 195, 250, 217, 9, 34, 251, 197, 250, 216, 193, 154, 9, + 34, 208, 17, 202, 140, 9, 34, 205, 160, 251, 197, 193, 180, 193, 183, 9, + 34, 251, 200, 250, 217, 9, 34, 199, 235, 193, 182, 9, 34, 207, 158, 251, + 173, 9, 34, 199, 115, 4, 223, 7, 4, 92, 89, 20, 9, 34, 199, 115, 4, 182, + 4, 223, 7, 53, 20, 9, 34, 199, 115, 4, 182, 4, 223, 7, 89, 20, 9, 34, + 199, 115, 4, 182, 4, 92, 89, 20, 9, 34, 199, 115, 4, 221, 211, 4, 92, 89, + 20, 9, 34, 199, 115, 4, 92, 4, 223, 7, 89, 20, 9, 34, 199, 115, 4, 92, 4, + 182, 89, 20, 9, 34, 199, 115, 4, 92, 4, 221, 211, 89, 20, 9, 34, 223, 7, + 4, 92, 4, 182, 53, 20, 9, 34, 223, 7, 4, 92, 4, 182, 89, 20, 9, 34, 182, + 4, 92, 4, 99, 53, 20, 9, 34, 182, 4, 92, 4, 131, 217, 100, 53, 20, 9, 34, + 205, 47, 4, 182, 4, 223, 7, 89, 20, 9, 34, 205, 47, 4, 223, 7, 4, 182, + 89, 20, 9, 34, 205, 47, 4, 223, 7, 4, 131, 217, 100, 53, 20, 9, 34, 205, + 47, 4, 92, 4, 182, 53, 20, 9, 34, 205, 47, 4, 92, 4, 182, 89, 20, 9, 34, + 205, 47, 4, 92, 4, 223, 7, 89, 20, 9, 34, 205, 47, 4, 92, 4, 92, 53, 20, + 9, 34, 205, 47, 4, 92, 4, 92, 89, 20, 9, 34, 205, 193, 4, 182, 4, 182, + 53, 20, 9, 34, 205, 193, 4, 182, 4, 182, 89, 20, 9, 34, 205, 193, 4, 92, + 4, 92, 53, 20, 9, 34, 203, 110, 4, 182, 4, 92, 53, 20, 9, 34, 203, 110, + 4, 182, 4, 92, 89, 20, 9, 34, 203, 110, 4, 223, 7, 4, 99, 53, 20, 9, 34, + 203, 110, 4, 92, 4, 221, 211, 53, 20, 9, 34, 203, 110, 4, 92, 4, 221, + 211, 89, 20, 9, 34, 203, 110, 4, 92, 4, 92, 53, 20, 9, 34, 203, 110, 4, + 92, 4, 92, 89, 20, 9, 34, 238, 27, 4, 182, 4, 131, 217, 100, 53, 20, 9, + 34, 238, 27, 4, 221, 211, 4, 92, 53, 20, 9, 34, 238, 27, 4, 221, 211, 4, + 92, 89, 20, 9, 34, 199, 220, 4, 92, 4, 182, 53, 20, 9, 34, 199, 220, 4, + 92, 4, 182, 89, 20, 9, 34, 199, 220, 4, 92, 4, 92, 89, 20, 9, 34, 199, + 220, 4, 92, 4, 99, 53, 20, 9, 34, 251, 231, 4, 223, 7, 4, 92, 53, 20, 9, + 34, 251, 231, 4, 92, 4, 92, 53, 20, 9, 34, 251, 231, 4, 92, 4, 92, 89, + 20, 9, 34, 251, 231, 4, 92, 4, 131, 217, 100, 53, 20, 9, 34, 231, 87, 4, + 92, 4, 92, 53, 20, 9, 34, 231, 87, 4, 92, 4, 99, 53, 20, 9, 34, 231, 87, + 4, 92, 4, 131, 217, 100, 53, 20, 9, 34, 233, 47, 4, 221, 211, 4, 92, 53, + 20, 9, 34, 233, 47, 4, 221, 211, 4, 92, 89, 20, 9, 34, 208, 90, 4, 92, 4, + 182, 53, 20, 9, 34, 208, 90, 4, 92, 4, 92, 53, 20, 9, 34, 220, 36, 4, + 182, 4, 92, 53, 20, 9, 34, 220, 36, 4, 182, 4, 99, 53, 20, 9, 34, 220, + 36, 4, 182, 4, 131, 217, 100, 53, 20, 9, 34, 220, 36, 4, 223, 7, 4, 223, + 7, 89, 20, 9, 34, 220, 36, 4, 223, 7, 4, 223, 7, 53, 20, 9, 34, 220, 36, + 4, 221, 211, 4, 92, 53, 20, 9, 34, 220, 36, 4, 221, 211, 4, 92, 89, 20, + 9, 34, 220, 36, 4, 92, 4, 182, 53, 20, 9, 34, 220, 36, 4, 92, 4, 182, 89, + 20, 9, 34, 92, 4, 182, 4, 223, 7, 89, 20, 9, 34, 92, 4, 182, 4, 92, 89, + 20, 9, 34, 92, 4, 182, 4, 99, 53, 20, 9, 34, 92, 4, 223, 7, 4, 182, 89, + 20, 9, 34, 92, 4, 223, 7, 4, 92, 89, 20, 9, 34, 92, 4, 221, 211, 4, 223, + 7, 89, 20, 9, 34, 92, 4, 221, 211, 4, 92, 89, 20, 9, 34, 92, 4, 223, 7, + 4, 221, 211, 89, 20, 9, 34, 229, 211, 4, 92, 4, 223, 7, 89, 20, 9, 34, + 229, 211, 4, 92, 4, 92, 89, 20, 9, 34, 213, 25, 4, 182, 4, 92, 89, 20, 9, + 34, 213, 25, 4, 182, 4, 131, 217, 100, 53, 20, 9, 34, 213, 25, 4, 223, 7, + 4, 92, 53, 20, 9, 34, 213, 25, 4, 223, 7, 4, 92, 89, 20, 9, 34, 213, 25, + 4, 223, 7, 4, 131, 217, 100, 53, 20, 9, 34, 213, 25, 4, 92, 4, 99, 53, + 20, 9, 34, 213, 25, 4, 92, 4, 131, 217, 100, 53, 20, 9, 34, 99, 4, 92, 4, + 92, 53, 20, 9, 34, 99, 4, 92, 4, 92, 89, 20, 9, 34, 248, 246, 4, 221, + 211, 4, 99, 53, 20, 9, 34, 199, 115, 4, 223, 7, 4, 99, 53, 20, 9, 34, + 199, 115, 4, 223, 7, 4, 131, 217, 100, 53, 20, 9, 34, 199, 115, 4, 221, + 211, 4, 99, 53, 20, 9, 34, 199, 115, 4, 221, 211, 4, 131, 217, 100, 53, + 20, 9, 34, 199, 115, 4, 92, 4, 99, 53, 20, 9, 34, 199, 115, 4, 92, 4, + 131, 217, 100, 53, 20, 9, 34, 223, 7, 4, 92, 4, 99, 53, 20, 9, 34, 223, + 7, 4, 182, 4, 131, 217, 100, 53, 20, 9, 34, 223, 7, 4, 92, 4, 131, 217, + 100, 53, 20, 9, 34, 205, 47, 4, 221, 211, 4, 131, 217, 100, 53, 20, 9, + 34, 205, 193, 4, 182, 4, 99, 53, 20, 9, 34, 203, 110, 4, 182, 4, 99, 53, + 20, 9, 34, 238, 27, 4, 182, 4, 99, 53, 20, 9, 34, 220, 36, 4, 223, 7, 4, + 99, 53, 20, 9, 34, 220, 36, 4, 92, 4, 99, 53, 20, 9, 34, 99, 4, 182, 4, + 99, 53, 20, 9, 34, 99, 4, 223, 7, 4, 99, 53, 20, 9, 34, 99, 4, 92, 4, 99, + 53, 20, 9, 34, 92, 4, 92, 4, 99, 53, 20, 9, 34, 208, 90, 4, 92, 4, 99, + 53, 20, 9, 34, 213, 25, 4, 182, 4, 99, 53, 20, 9, 34, 208, 90, 4, 92, 4, + 182, 89, 20, 9, 34, 220, 36, 4, 182, 4, 92, 89, 20, 9, 34, 251, 231, 4, + 92, 4, 99, 53, 20, 9, 34, 222, 107, 4, 92, 4, 99, 53, 20, 9, 34, 213, 25, + 4, 223, 7, 4, 182, 89, 20, 9, 34, 92, 4, 221, 211, 4, 99, 53, 20, 9, 34, + 220, 36, 4, 223, 7, 4, 92, 89, 20, 9, 34, 222, 107, 4, 92, 4, 92, 53, 20, + 9, 34, 220, 36, 4, 223, 7, 4, 92, 53, 20, 9, 34, 213, 25, 4, 223, 7, 4, + 182, 53, 20, 9, 34, 223, 7, 4, 182, 4, 99, 53, 20, 9, 34, 182, 4, 223, 7, + 4, 99, 53, 20, 9, 34, 92, 4, 223, 7, 4, 99, 53, 20, 9, 34, 233, 47, 4, + 92, 4, 99, 53, 20, 9, 34, 248, 246, 4, 182, 4, 99, 53, 20, 9, 34, 222, + 107, 4, 92, 4, 92, 89, 20, 9, 34, 251, 231, 4, 223, 7, 4, 92, 89, 20, 9, + 34, 205, 193, 4, 92, 4, 92, 89, 20, 9, 34, 205, 47, 4, 221, 211, 4, 99, + 53, 20, 9, 34, 213, 25, 4, 223, 7, 4, 99, 53, 20, 9, 34, 205, 166, 251, + 194, 9, 34, 205, 163, 196, 40, 250, 220, 221, 33, 201, 64, 3, 76, 20, 9, + 34, 208, 86, 196, 40, 250, 220, 221, 33, 201, 64, 3, 76, 20, 9, 34, 251, + 171, 76, 20, 9, 34, 251, 213, 76, 20, 9, 34, 215, 235, 76, 20, 9, 34, + 205, 164, 76, 20, 9, 34, 207, 132, 76, 20, 9, 34, 251, 199, 76, 20, 9, + 34, 193, 153, 76, 20, 9, 34, 205, 163, 76, 20, 9, 34, 205, 161, 251, 199, + 193, 152, 9, 34, 223, 22, 206, 249, 56, 9, 34, 248, 151, 251, 31, 251, + 32, 9, 34, 200, 242, 193, 191, 199, 244, 9, 34, 250, 121, 193, 191, 223, + 23, 67, 205, 33, 67, 204, 178, 67, 204, 110, 67, 204, 99, 67, 204, 88, + 67, 204, 77, 67, 204, 66, 67, 204, 55, 67, 204, 44, 67, 205, 32, 67, 205, + 21, 67, 205, 10, 67, 204, 255, 67, 204, 244, 67, 204, 233, 67, 204, 222, + 208, 221, 232, 146, 40, 81, 242, 74, 208, 221, 232, 146, 40, 81, 154, + 242, 74, 208, 221, 232, 146, 40, 81, 154, 232, 80, 201, 63, 208, 221, + 232, 146, 40, 81, 242, 83, 208, 221, 232, 146, 40, 81, 204, 25, 208, 221, + 232, 146, 40, 81, 233, 216, 77, 208, 221, 232, 146, 40, 81, 208, 13, 77, + 208, 221, 232, 146, 40, 81, 45, 63, 219, 187, 248, 53, 208, 221, 232, + 146, 40, 81, 50, 63, 219, 187, 248, 49, 208, 221, 232, 146, 40, 81, 228, + 241, 234, 120, 33, 34, 45, 230, 70, 33, 34, 50, 230, 70, 33, 55, 198, + 153, 45, 230, 70, 33, 55, 198, 153, 50, 230, 70, 33, 217, 147, 45, 230, + 70, 33, 217, 147, 50, 230, 70, 33, 239, 44, 217, 146, 33, 34, 45, 132, + 60, 33, 34, 50, 132, 60, 33, 198, 153, 45, 132, 60, 33, 198, 153, 50, + 132, 60, 33, 217, 147, 45, 132, 60, 33, 217, 147, 50, 132, 60, 33, 239, + 44, 217, 147, 60, 33, 38, 198, 123, 45, 230, 70, 33, 38, 198, 123, 50, + 230, 70, 208, 221, 232, 146, 40, 81, 105, 75, 219, 236, 208, 221, 232, + 146, 40, 81, 234, 115, 237, 215, 208, 221, 232, 146, 40, 81, 234, 104, + 237, 215, 208, 221, 232, 146, 40, 81, 130, 219, 112, 208, 221, 232, 146, + 40, 81, 193, 135, 130, 219, 112, 208, 221, 232, 146, 40, 81, 45, 210, + 113, 208, 221, 232, 146, 40, 81, 50, 210, 113, 208, 221, 232, 146, 40, + 81, 45, 238, 171, 248, 53, 208, 221, 232, 146, 40, 81, 50, 238, 171, 248, + 53, 208, 221, 232, 146, 40, 81, 45, 198, 42, 203, 103, 248, 53, 208, 221, + 232, 146, 40, 81, 50, 198, 42, 203, 103, 248, 53, 208, 221, 232, 146, 40, + 81, 45, 62, 219, 187, 248, 53, 208, 221, 232, 146, 40, 81, 50, 62, 219, + 187, 248, 53, 208, 221, 232, 146, 40, 81, 45, 55, 251, 116, 248, 53, 208, + 221, 232, 146, 40, 81, 50, 55, 251, 116, 248, 53, 208, 221, 232, 146, 40, + 81, 45, 251, 116, 248, 53, 208, 221, 232, 146, 40, 81, 50, 251, 116, 248, + 53, 208, 221, 232, 146, 40, 81, 45, 239, 2, 248, 53, 208, 221, 232, 146, + 40, 81, 50, 239, 2, 248, 53, 208, 221, 232, 146, 40, 81, 45, 63, 239, 2, + 248, 53, 208, 221, 232, 146, 40, 81, 50, 63, 239, 2, 248, 53, 204, 0, + 236, 140, 63, 204, 0, 236, 140, 208, 221, 232, 146, 40, 81, 45, 51, 248, + 53, 208, 221, 232, 146, 40, 81, 50, 51, 248, 53, 237, 214, 210, 254, 247, + 18, 210, 254, 193, 135, 210, 254, 55, 193, 135, 210, 254, 237, 214, 130, + 219, 112, 247, 18, 130, 219, 112, 193, 135, 130, 219, 112, 2, 242, 74, 2, + 154, 242, 74, 2, 232, 80, 201, 63, 2, 204, 25, 2, 242, 83, 2, 208, 13, + 77, 2, 233, 216, 77, 2, 234, 115, 237, 215, 2, 45, 210, 113, 2, 50, 210, + 113, 2, 45, 238, 171, 248, 53, 2, 50, 238, 171, 248, 53, 2, 45, 198, 42, + 203, 103, 248, 53, 2, 50, 198, 42, 203, 103, 248, 53, 2, 31, 56, 2, 251, + 137, 2, 250, 193, 2, 108, 56, 2, 228, 87, 2, 219, 180, 56, 2, 230, 204, + 56, 2, 234, 43, 56, 2, 207, 19, 202, 23, 2, 236, 155, 56, 2, 210, 13, 56, + 2, 242, 72, 250, 182, 9, 233, 69, 76, 20, 9, 199, 169, 4, 233, 69, 58, 9, + 237, 244, 76, 20, 9, 199, 216, 232, 117, 9, 222, 51, 76, 20, 9, 233, 71, + 76, 20, 9, 233, 71, 216, 217, 20, 9, 237, 246, 76, 20, 9, 237, 246, 216, + 217, 20, 9, 222, 53, 76, 20, 9, 222, 53, 216, 217, 20, 9, 203, 156, 76, + 20, 9, 203, 156, 216, 217, 20, 9, 200, 207, 76, 20, 9, 200, 207, 216, + 217, 20, 9, 1, 230, 58, 76, 20, 9, 1, 131, 4, 217, 142, 93, 76, 20, 9, 1, + 131, 4, 217, 142, 93, 53, 20, 9, 1, 131, 4, 230, 58, 93, 76, 20, 9, 1, + 131, 4, 230, 58, 93, 53, 20, 9, 1, 193, 134, 4, 230, 58, 93, 76, 20, 9, + 1, 193, 134, 4, 230, 58, 93, 53, 20, 9, 1, 131, 4, 230, 58, 248, 233, 76, + 20, 9, 1, 131, 4, 230, 58, 248, 233, 53, 20, 9, 1, 99, 4, 230, 58, 93, + 76, 20, 9, 1, 99, 4, 230, 58, 93, 53, 20, 9, 1, 99, 4, 230, 58, 93, 89, + 20, 9, 1, 99, 4, 230, 58, 93, 216, 217, 20, 9, 1, 131, 76, 20, 9, 1, 131, + 53, 20, 9, 1, 248, 246, 76, 20, 9, 1, 248, 246, 53, 20, 9, 1, 248, 246, + 89, 20, 9, 1, 248, 246, 216, 217, 20, 9, 1, 199, 115, 217, 63, 76, 20, 9, + 1, 199, 115, 217, 63, 53, 20, 9, 1, 199, 115, 76, 20, 9, 1, 199, 115, 53, + 20, 9, 1, 199, 115, 89, 20, 9, 1, 199, 115, 216, 217, 20, 9, 1, 199, 30, + 76, 20, 9, 1, 199, 30, 53, 20, 9, 1, 199, 30, 89, 20, 9, 1, 199, 30, 216, + 217, 20, 9, 1, 223, 7, 76, 20, 9, 1, 223, 7, 53, 20, 9, 1, 223, 7, 89, + 20, 9, 1, 223, 7, 216, 217, 20, 9, 1, 182, 76, 20, 9, 1, 182, 53, 20, 9, + 1, 182, 89, 20, 9, 1, 182, 216, 217, 20, 9, 1, 221, 211, 76, 20, 9, 1, + 221, 211, 53, 20, 9, 1, 221, 211, 89, 20, 9, 1, 221, 211, 216, 217, 20, + 9, 1, 238, 4, 76, 20, 9, 1, 238, 4, 53, 20, 9, 1, 199, 42, 76, 20, 9, 1, + 199, 42, 53, 20, 9, 1, 207, 72, 76, 20, 9, 1, 207, 72, 53, 20, 9, 1, 191, + 114, 76, 20, 9, 1, 191, 114, 53, 20, 9, 1, 205, 47, 76, 20, 9, 1, 205, + 47, 53, 20, 9, 1, 205, 47, 89, 20, 9, 1, 205, 47, 216, 217, 20, 9, 1, + 203, 110, 76, 20, 9, 1, 203, 110, 53, 20, 9, 1, 203, 110, 89, 20, 9, 1, + 203, 110, 216, 217, 20, 9, 1, 205, 193, 76, 20, 9, 1, 205, 193, 53, 20, + 9, 1, 205, 193, 89, 20, 9, 1, 205, 193, 216, 217, 20, 9, 1, 238, 27, 76, + 20, 9, 1, 238, 27, 53, 20, 9, 1, 238, 27, 89, 20, 9, 1, 238, 27, 216, + 217, 20, 9, 1, 199, 220, 76, 20, 9, 1, 199, 220, 53, 20, 9, 1, 199, 220, + 89, 20, 9, 1, 199, 220, 216, 217, 20, 9, 1, 191, 117, 76, 20, 9, 1, 191, + 117, 53, 20, 9, 1, 191, 117, 89, 20, 9, 1, 191, 117, 216, 217, 20, 9, 1, + 251, 231, 76, 20, 9, 1, 251, 231, 53, 20, 9, 1, 251, 231, 89, 20, 9, 1, + 251, 231, 216, 217, 20, 9, 1, 231, 87, 76, 20, 9, 1, 231, 87, 53, 20, 9, + 1, 231, 87, 89, 20, 9, 1, 231, 87, 216, 217, 20, 9, 1, 233, 47, 76, 20, + 9, 1, 233, 47, 53, 20, 9, 1, 233, 47, 89, 20, 9, 1, 233, 47, 216, 217, + 20, 9, 1, 208, 90, 76, 20, 9, 1, 208, 90, 53, 20, 9, 1, 208, 90, 89, 20, + 9, 1, 208, 90, 216, 217, 20, 9, 1, 222, 107, 76, 20, 9, 1, 222, 107, 53, + 20, 9, 1, 222, 107, 89, 20, 9, 1, 222, 107, 216, 217, 20, 9, 1, 220, 36, + 76, 20, 9, 1, 220, 36, 53, 20, 9, 1, 220, 36, 89, 20, 9, 1, 220, 36, 216, + 217, 20, 9, 1, 92, 76, 20, 9, 1, 92, 53, 20, 9, 1, 92, 89, 20, 9, 1, 92, + 216, 217, 20, 9, 1, 213, 25, 76, 20, 9, 1, 213, 25, 53, 20, 9, 1, 213, + 25, 89, 20, 9, 1, 213, 25, 216, 217, 20, 9, 1, 229, 211, 76, 20, 9, 1, + 229, 211, 53, 20, 9, 1, 229, 211, 89, 20, 9, 1, 229, 211, 216, 217, 20, + 9, 1, 193, 134, 76, 20, 9, 1, 193, 134, 53, 20, 9, 1, 131, 217, 100, 76, + 20, 9, 1, 131, 217, 100, 53, 20, 9, 1, 99, 76, 20, 9, 1, 99, 53, 20, 9, + 1, 99, 89, 20, 9, 1, 99, 216, 217, 20, 9, 34, 220, 36, 4, 131, 4, 217, + 142, 93, 76, 20, 9, 34, 220, 36, 4, 131, 4, 217, 142, 93, 53, 20, 9, 34, + 220, 36, 4, 131, 4, 230, 58, 93, 76, 20, 9, 34, 220, 36, 4, 131, 4, 230, + 58, 93, 53, 20, 9, 34, 220, 36, 4, 131, 4, 230, 58, 248, 233, 76, 20, 9, + 34, 220, 36, 4, 131, 4, 230, 58, 248, 233, 53, 20, 9, 34, 220, 36, 4, + 131, 76, 20, 9, 34, 220, 36, 4, 131, 53, 20, 191, 78, 193, 75, 213, 37, + 201, 247, 232, 78, 233, 216, 77, 232, 78, 207, 252, 77, 232, 78, 31, 56, + 232, 78, 236, 155, 56, 232, 78, 210, 13, 56, 232, 78, 251, 137, 232, 78, + 251, 49, 232, 78, 45, 210, 113, 232, 78, 50, 210, 113, 232, 78, 250, 193, + 232, 78, 108, 56, 232, 78, 242, 74, 232, 78, 228, 87, 232, 78, 232, 80, + 201, 63, 232, 78, 202, 23, 232, 78, 17, 191, 77, 232, 78, 17, 107, 232, + 78, 17, 109, 232, 78, 17, 138, 232, 78, 17, 134, 232, 78, 17, 149, 232, + 78, 17, 169, 232, 78, 17, 175, 232, 78, 17, 171, 232, 78, 17, 178, 232, + 78, 242, 83, 232, 78, 204, 25, 232, 78, 219, 180, 56, 232, 78, 234, 43, + 56, 232, 78, 230, 204, 56, 232, 78, 208, 13, 77, 232, 78, 242, 72, 250, + 182, 232, 78, 8, 6, 1, 65, 232, 78, 8, 6, 1, 250, 120, 232, 78, 8, 6, 1, + 247, 193, 232, 78, 8, 6, 1, 238, 127, 232, 78, 8, 6, 1, 71, 232, 78, 8, + 6, 1, 233, 175, 232, 78, 8, 6, 1, 232, 51, 232, 78, 8, 6, 1, 230, 116, + 232, 78, 8, 6, 1, 68, 232, 78, 8, 6, 1, 223, 35, 232, 78, 8, 6, 1, 222, + 152, 232, 78, 8, 6, 1, 172, 232, 78, 8, 6, 1, 218, 168, 232, 78, 8, 6, 1, + 215, 61, 232, 78, 8, 6, 1, 74, 232, 78, 8, 6, 1, 210, 236, 232, 78, 8, 6, + 1, 208, 104, 232, 78, 8, 6, 1, 146, 232, 78, 8, 6, 1, 206, 8, 232, 78, 8, + 6, 1, 200, 43, 232, 78, 8, 6, 1, 66, 232, 78, 8, 6, 1, 196, 12, 232, 78, + 8, 6, 1, 193, 224, 232, 78, 8, 6, 1, 192, 235, 232, 78, 8, 6, 1, 192, + 159, 232, 78, 8, 6, 1, 191, 166, 232, 78, 45, 51, 248, 53, 232, 78, 207, + 19, 202, 23, 232, 78, 50, 51, 248, 53, 232, 78, 243, 2, 252, 60, 232, 78, + 130, 219, 112, 232, 78, 230, 211, 252, 60, 232, 78, 8, 2, 1, 65, 232, 78, + 8, 2, 1, 250, 120, 232, 78, 8, 2, 1, 247, 193, 232, 78, 8, 2, 1, 238, + 127, 232, 78, 8, 2, 1, 71, 232, 78, 8, 2, 1, 233, 175, 232, 78, 8, 2, 1, + 232, 51, 232, 78, 8, 2, 1, 230, 116, 232, 78, 8, 2, 1, 68, 232, 78, 8, 2, + 1, 223, 35, 232, 78, 8, 2, 1, 222, 152, 232, 78, 8, 2, 1, 172, 232, 78, + 8, 2, 1, 218, 168, 232, 78, 8, 2, 1, 215, 61, 232, 78, 8, 2, 1, 74, 232, + 78, 8, 2, 1, 210, 236, 232, 78, 8, 2, 1, 208, 104, 232, 78, 8, 2, 1, 146, + 232, 78, 8, 2, 1, 206, 8, 232, 78, 8, 2, 1, 200, 43, 232, 78, 8, 2, 1, + 66, 232, 78, 8, 2, 1, 196, 12, 232, 78, 8, 2, 1, 193, 224, 232, 78, 8, 2, + 1, 192, 235, 232, 78, 8, 2, 1, 192, 159, 232, 78, 8, 2, 1, 191, 166, 232, + 78, 45, 238, 171, 248, 53, 232, 78, 81, 219, 112, 232, 78, 50, 238, 171, + 248, 53, 232, 78, 198, 152, 232, 78, 45, 63, 210, 113, 232, 78, 50, 63, + 210, 113, 150, 154, 232, 80, 201, 63, 150, 45, 239, 2, 248, 53, 150, 50, + 239, 2, 248, 53, 150, 154, 242, 74, 150, 72, 82, 236, 140, 150, 72, 1, + 193, 48, 150, 72, 1, 2, 65, 150, 72, 1, 2, 68, 150, 72, 1, 2, 66, 150, + 72, 1, 2, 71, 150, 72, 1, 2, 74, 150, 72, 1, 2, 170, 150, 72, 1, 2, 191, + 225, 150, 72, 1, 2, 192, 12, 150, 72, 1, 2, 197, 94, 150, 222, 48, 208, + 191, 202, 5, 77, 150, 72, 1, 65, 150, 72, 1, 68, 150, 72, 1, 66, 150, 72, + 1, 71, 150, 72, 1, 74, 150, 72, 1, 155, 150, 72, 1, 221, 166, 150, 72, 1, + 220, 232, 150, 72, 1, 222, 22, 150, 72, 1, 221, 67, 150, 72, 1, 188, 150, + 72, 1, 202, 222, 150, 72, 1, 201, 4, 150, 72, 1, 205, 68, 150, 72, 1, + 202, 46, 150, 72, 1, 190, 190, 150, 72, 1, 198, 193, 150, 72, 1, 197, 94, + 150, 72, 1, 199, 145, 150, 72, 1, 159, 150, 72, 1, 180, 150, 72, 1, 213, + 219, 150, 72, 1, 212, 178, 150, 72, 1, 214, 121, 150, 72, 1, 213, 43, + 150, 72, 1, 140, 150, 72, 1, 229, 158, 150, 72, 1, 228, 159, 150, 72, 1, + 229, 245, 150, 72, 1, 229, 23, 150, 72, 1, 174, 150, 72, 1, 216, 100, + 150, 72, 1, 215, 155, 150, 72, 1, 216, 232, 150, 72, 1, 216, 12, 150, 72, + 1, 170, 150, 72, 1, 191, 225, 150, 72, 1, 192, 12, 150, 72, 1, 165, 150, + 72, 1, 207, 1, 150, 72, 1, 206, 68, 150, 72, 1, 207, 113, 150, 72, 1, + 206, 162, 150, 72, 1, 193, 190, 150, 72, 1, 215, 61, 150, 72, 195, 20, + 202, 5, 77, 150, 72, 204, 30, 202, 5, 77, 150, 30, 233, 3, 150, 30, 1, + 221, 113, 150, 30, 1, 201, 167, 150, 30, 1, 221, 106, 150, 30, 1, 213, + 204, 150, 30, 1, 213, 202, 150, 30, 1, 213, 201, 150, 30, 1, 198, 168, + 150, 30, 1, 201, 156, 150, 30, 1, 206, 239, 150, 30, 1, 206, 234, 150, + 30, 1, 206, 231, 150, 30, 1, 206, 224, 150, 30, 1, 206, 219, 150, 30, 1, + 206, 214, 150, 30, 1, 206, 225, 150, 30, 1, 206, 237, 150, 30, 1, 216, + 77, 150, 30, 1, 209, 169, 150, 30, 1, 201, 164, 150, 30, 1, 209, 158, + 150, 30, 1, 202, 160, 150, 30, 1, 201, 161, 150, 30, 1, 223, 222, 150, + 30, 1, 243, 24, 150, 30, 1, 201, 171, 150, 30, 1, 243, 91, 150, 30, 1, + 221, 188, 150, 30, 1, 199, 7, 150, 30, 1, 209, 209, 150, 30, 1, 229, 142, + 150, 30, 1, 65, 150, 30, 1, 252, 25, 150, 30, 1, 170, 150, 30, 1, 192, + 129, 150, 30, 1, 234, 65, 150, 30, 1, 71, 150, 30, 1, 192, 67, 150, 30, + 1, 192, 80, 150, 30, 1, 74, 150, 30, 1, 193, 190, 150, 30, 1, 193, 176, + 150, 30, 1, 211, 151, 150, 30, 1, 192, 12, 150, 30, 1, 66, 150, 30, 1, + 193, 107, 150, 30, 1, 193, 125, 150, 30, 1, 193, 86, 150, 30, 1, 191, + 225, 150, 30, 1, 233, 242, 150, 30, 1, 192, 33, 150, 30, 1, 68, 232, 78, + 247, 24, 56, 232, 78, 209, 8, 56, 232, 78, 213, 12, 56, 232, 78, 217, + 146, 232, 78, 248, 22, 164, 232, 78, 192, 71, 56, 232, 78, 193, 31, 56, + 150, 232, 141, 156, 195, 135, 150, 118, 57, 150, 196, 66, 57, 150, 96, + 57, 150, 235, 119, 57, 150, 62, 201, 190, 150, 63, 243, 10, 223, 106, + 251, 96, 251, 127, 223, 106, 251, 96, 204, 10, 223, 106, 251, 96, 199, + 80, 211, 175, 207, 43, 246, 239, 207, 43, 246, 239, 32, 78, 5, 250, 104, + 65, 32, 78, 5, 250, 73, 71, 32, 78, 5, 250, 82, 68, 32, 78, 5, 250, 50, + 74, 32, 78, 5, 250, 100, 66, 32, 78, 5, 250, 119, 238, 32, 32, 78, 5, + 250, 66, 237, 146, 32, 78, 5, 250, 106, 237, 44, 32, 78, 5, 250, 96, 236, + 174, 32, 78, 5, 250, 60, 235, 89, 32, 78, 5, 250, 54, 223, 32, 32, 78, 5, + 250, 65, 223, 10, 32, 78, 5, 250, 75, 222, 201, 32, 78, 5, 250, 46, 222, + 182, 32, 78, 5, 250, 34, 155, 32, 78, 5, 250, 67, 222, 22, 32, 78, 5, + 250, 44, 221, 166, 32, 78, 5, 250, 41, 221, 67, 32, 78, 5, 250, 30, 220, + 232, 32, 78, 5, 250, 31, 174, 32, 78, 5, 250, 97, 216, 232, 32, 78, 5, + 250, 38, 216, 100, 32, 78, 5, 250, 95, 216, 12, 32, 78, 5, 250, 87, 215, + 155, 32, 78, 5, 250, 108, 180, 32, 78, 5, 250, 86, 214, 121, 32, 78, 5, + 250, 80, 213, 219, 32, 78, 5, 250, 59, 213, 43, 32, 78, 5, 250, 56, 212, + 178, 32, 78, 5, 250, 115, 168, 32, 78, 5, 250, 39, 210, 63, 32, 78, 5, + 250, 72, 209, 185, 32, 78, 5, 250, 99, 209, 73, 32, 78, 5, 250, 61, 208, + 165, 32, 78, 5, 250, 94, 208, 96, 32, 78, 5, 250, 33, 208, 75, 32, 78, 5, + 250, 89, 208, 57, 32, 78, 5, 250, 78, 208, 45, 32, 78, 5, 250, 51, 165, + 32, 78, 5, 250, 83, 207, 113, 32, 78, 5, 250, 58, 207, 1, 32, 78, 5, 250, + 117, 206, 162, 32, 78, 5, 250, 84, 206, 68, 32, 78, 5, 250, 79, 188, 32, + 78, 5, 250, 102, 205, 68, 32, 78, 5, 250, 70, 202, 222, 32, 78, 5, 250, + 98, 202, 46, 32, 78, 5, 250, 53, 201, 4, 32, 78, 5, 250, 52, 190, 190, + 32, 78, 5, 250, 113, 199, 145, 32, 78, 5, 250, 74, 198, 193, 32, 78, 5, + 250, 111, 159, 32, 78, 5, 250, 42, 197, 94, 32, 78, 5, 250, 57, 193, 190, + 32, 78, 5, 250, 36, 193, 125, 32, 78, 5, 250, 71, 193, 86, 32, 78, 5, + 250, 69, 193, 48, 32, 78, 5, 250, 93, 191, 123, 32, 78, 5, 250, 37, 191, + 87, 32, 78, 5, 250, 90, 191, 7, 32, 78, 5, 250, 85, 254, 215, 32, 78, 5, + 250, 68, 254, 103, 32, 78, 5, 250, 27, 250, 163, 32, 78, 5, 250, 40, 235, + 45, 32, 78, 5, 250, 23, 235, 44, 32, 78, 5, 250, 63, 212, 110, 32, 78, 5, + 250, 81, 208, 163, 32, 78, 5, 250, 49, 208, 167, 32, 78, 5, 250, 35, 207, + 180, 32, 78, 5, 250, 77, 207, 179, 32, 78, 5, 250, 43, 206, 155, 32, 78, + 5, 250, 45, 199, 246, 32, 78, 5, 250, 25, 197, 41, 32, 78, 5, 250, 22, + 109, 32, 78, 16, 250, 92, 32, 78, 16, 250, 91, 32, 78, 16, 250, 88, 32, + 78, 16, 250, 76, 32, 78, 16, 250, 64, 32, 78, 16, 250, 62, 32, 78, 16, + 250, 55, 32, 78, 16, 250, 48, 32, 78, 16, 250, 47, 32, 78, 16, 250, 32, + 32, 78, 16, 250, 29, 32, 78, 16, 250, 28, 32, 78, 16, 250, 26, 32, 78, + 16, 250, 24, 32, 78, 157, 250, 21, 217, 90, 32, 78, 157, 250, 20, 193, + 35, 32, 78, 157, 250, 19, 237, 128, 32, 78, 157, 250, 18, 234, 40, 32, + 78, 157, 250, 17, 217, 56, 32, 78, 157, 250, 16, 201, 110, 32, 78, 157, + 250, 15, 233, 223, 32, 78, 157, 250, 14, 207, 142, 32, 78, 157, 250, 13, + 203, 112, 32, 78, 157, 250, 12, 229, 237, 32, 78, 157, 250, 11, 201, 255, + 32, 78, 157, 250, 10, 248, 109, 32, 78, 157, 250, 9, 238, 239, 32, 78, + 157, 250, 8, 247, 250, 32, 78, 157, 250, 7, 193, 95, 32, 78, 157, 250, 6, + 249, 84, 32, 78, 157, 250, 5, 211, 115, 32, 78, 157, 250, 4, 201, 223, + 32, 78, 157, 250, 3, 238, 136, 32, 78, 215, 221, 250, 2, 222, 74, 32, 78, + 215, 221, 250, 1, 222, 85, 32, 78, 157, 250, 0, 211, 131, 32, 78, 157, + 249, 255, 193, 62, 32, 78, 157, 249, 254, 32, 78, 215, 221, 249, 253, + 251, 7, 32, 78, 215, 221, 249, 252, 216, 178, 32, 78, 157, 249, 251, 248, + 21, 32, 78, 157, 249, 250, 230, 250, 32, 78, 157, 249, 249, 32, 78, 157, + 249, 248, 193, 26, 32, 78, 157, 249, 247, 32, 78, 157, 249, 246, 32, 78, + 157, 249, 245, 228, 187, 32, 78, 157, 249, 244, 32, 78, 157, 249, 243, + 32, 78, 157, 249, 242, 32, 78, 215, 221, 249, 240, 197, 56, 32, 78, 157, + 249, 239, 32, 78, 157, 249, 238, 32, 78, 157, 249, 237, 242, 213, 32, 78, + 157, 249, 236, 32, 78, 157, 249, 235, 32, 78, 157, 249, 234, 231, 196, + 32, 78, 157, 249, 233, 250, 248, 32, 78, 157, 249, 232, 32, 78, 157, 249, + 231, 32, 78, 157, 249, 230, 32, 78, 157, 249, 229, 32, 78, 157, 249, 228, + 32, 78, 157, 249, 227, 32, 78, 157, 249, 226, 32, 78, 157, 249, 225, 32, + 78, 157, 249, 224, 32, 78, 157, 249, 223, 215, 213, 32, 78, 157, 249, + 222, 32, 78, 157, 249, 221, 197, 254, 32, 78, 157, 249, 220, 32, 78, 157, + 249, 219, 32, 78, 157, 249, 218, 32, 78, 157, 249, 217, 32, 78, 157, 249, + 216, 32, 78, 157, 249, 215, 32, 78, 157, 249, 214, 32, 78, 157, 249, 213, + 32, 78, 157, 249, 212, 32, 78, 157, 249, 211, 32, 78, 157, 249, 210, 32, + 78, 157, 249, 209, 229, 200, 32, 78, 157, 249, 188, 232, 155, 32, 78, + 157, 249, 185, 249, 59, 32, 78, 157, 249, 180, 201, 232, 32, 78, 157, + 249, 179, 57, 32, 78, 157, 249, 178, 32, 78, 157, 249, 177, 200, 131, 32, + 78, 157, 249, 176, 32, 78, 157, 249, 175, 32, 78, 157, 249, 174, 193, 90, + 243, 138, 32, 78, 157, 249, 173, 243, 138, 32, 78, 157, 249, 172, 243, + 139, 232, 113, 32, 78, 157, 249, 171, 193, 93, 32, 78, 157, 249, 170, 32, + 78, 157, 249, 169, 32, 78, 215, 221, 249, 168, 236, 235, 32, 78, 157, + 249, 167, 32, 78, 157, 249, 166, 32, 78, 157, 249, 164, 32, 78, 157, 249, + 163, 32, 78, 157, 249, 162, 32, 78, 157, 249, 161, 237, 218, 32, 78, 157, + 249, 160, 32, 78, 157, 249, 159, 32, 78, 157, 249, 158, 32, 78, 157, 249, + 157, 32, 78, 157, 249, 156, 32, 78, 157, 195, 82, 249, 241, 32, 78, 157, + 195, 82, 249, 208, 32, 78, 157, 195, 82, 249, 207, 32, 78, 157, 195, 82, + 249, 206, 32, 78, 157, 195, 82, 249, 205, 32, 78, 157, 195, 82, 249, 204, + 32, 78, 157, 195, 82, 249, 203, 32, 78, 157, 195, 82, 249, 202, 32, 78, + 157, 195, 82, 249, 201, 32, 78, 157, 195, 82, 249, 200, 32, 78, 157, 195, + 82, 249, 199, 32, 78, 157, 195, 82, 249, 198, 32, 78, 157, 195, 82, 249, + 197, 32, 78, 157, 195, 82, 249, 196, 32, 78, 157, 195, 82, 249, 195, 32, + 78, 157, 195, 82, 249, 194, 32, 78, 157, 195, 82, 249, 193, 32, 78, 157, + 195, 82, 249, 192, 32, 78, 157, 195, 82, 249, 191, 32, 78, 157, 195, 82, + 249, 190, 32, 78, 157, 195, 82, 249, 189, 32, 78, 157, 195, 82, 249, 187, + 32, 78, 157, 195, 82, 249, 186, 32, 78, 157, 195, 82, 249, 184, 32, 78, + 157, 195, 82, 249, 183, 32, 78, 157, 195, 82, 249, 182, 32, 78, 157, 195, + 82, 249, 181, 32, 78, 157, 195, 82, 249, 165, 32, 78, 157, 195, 82, 249, + 155, 252, 18, 193, 23, 204, 11, 219, 112, 252, 18, 193, 23, 204, 11, 236, + 140, 252, 18, 243, 126, 77, 252, 18, 31, 107, 252, 18, 31, 109, 252, 18, + 31, 138, 252, 18, 31, 134, 252, 18, 31, 149, 252, 18, 31, 169, 252, 18, + 31, 175, 252, 18, 31, 171, 252, 18, 31, 178, 252, 18, 31, 199, 95, 252, + 18, 31, 197, 32, 252, 18, 31, 198, 249, 252, 18, 31, 232, 135, 252, 18, + 31, 233, 15, 252, 18, 31, 202, 120, 252, 18, 31, 203, 241, 252, 18, 31, + 234, 153, 252, 18, 31, 213, 169, 252, 18, 31, 91, 228, 140, 252, 18, 31, + 105, 228, 140, 252, 18, 31, 115, 228, 140, 252, 18, 31, 232, 128, 228, + 140, 252, 18, 31, 232, 226, 228, 140, 252, 18, 31, 202, 136, 228, 140, + 252, 18, 31, 203, 247, 228, 140, 252, 18, 31, 234, 164, 228, 140, 252, + 18, 31, 213, 175, 228, 140, 252, 18, 31, 91, 189, 252, 18, 31, 105, 189, + 252, 18, 31, 115, 189, 252, 18, 31, 232, 128, 189, 252, 18, 31, 232, 226, + 189, 252, 18, 31, 202, 136, 189, 252, 18, 31, 203, 247, 189, 252, 18, 31, + 234, 164, 189, 252, 18, 31, 213, 175, 189, 252, 18, 31, 199, 96, 189, + 252, 18, 31, 197, 33, 189, 252, 18, 31, 198, 250, 189, 252, 18, 31, 232, + 136, 189, 252, 18, 31, 233, 16, 189, 252, 18, 31, 202, 121, 189, 252, 18, + 31, 203, 242, 189, 252, 18, 31, 234, 154, 189, 252, 18, 31, 213, 170, + 189, 252, 18, 193, 110, 249, 75, 196, 90, 252, 18, 193, 110, 232, 238, + 200, 224, 252, 18, 193, 110, 205, 57, 200, 224, 252, 18, 193, 110, 199, + 1, 200, 224, 252, 18, 193, 110, 232, 121, 200, 224, 252, 18, 235, 92, + 216, 228, 232, 238, 200, 224, 252, 18, 219, 93, 216, 228, 232, 238, 200, + 224, 252, 18, 216, 228, 205, 57, 200, 224, 252, 18, 216, 228, 199, 1, + 200, 224, 35, 252, 50, 250, 165, 91, 208, 22, 35, 252, 50, 250, 165, 91, + 230, 70, 35, 252, 50, 250, 165, 91, 235, 115, 35, 252, 50, 250, 165, 149, + 35, 252, 50, 250, 165, 233, 15, 35, 252, 50, 250, 165, 232, 226, 228, + 140, 35, 252, 50, 250, 165, 232, 226, 189, 35, 252, 50, 250, 165, 233, + 16, 189, 35, 252, 50, 250, 165, 232, 226, 199, 203, 35, 252, 50, 250, + 165, 199, 96, 199, 203, 35, 252, 50, 250, 165, 233, 16, 199, 203, 35, + 252, 50, 250, 165, 91, 228, 141, 199, 203, 35, 252, 50, 250, 165, 232, + 226, 228, 141, 199, 203, 35, 252, 50, 250, 165, 91, 198, 230, 199, 203, + 35, 252, 50, 250, 165, 232, 226, 198, 230, 199, 203, 35, 252, 50, 250, + 165, 232, 226, 201, 94, 35, 252, 50, 250, 165, 199, 96, 201, 94, 35, 252, + 50, 250, 165, 233, 16, 201, 94, 35, 252, 50, 250, 165, 91, 228, 141, 201, + 94, 35, 252, 50, 250, 165, 232, 226, 228, 141, 201, 94, 35, 252, 50, 250, + 165, 91, 198, 230, 201, 94, 35, 252, 50, 250, 165, 199, 96, 198, 230, + 201, 94, 35, 252, 50, 250, 165, 233, 16, 198, 230, 201, 94, 35, 252, 50, + 250, 165, 199, 96, 216, 15, 35, 252, 50, 229, 194, 91, 209, 92, 35, 252, + 50, 199, 17, 107, 35, 252, 50, 229, 190, 107, 35, 252, 50, 234, 51, 109, + 35, 252, 50, 199, 17, 109, 35, 252, 50, 238, 132, 105, 235, 114, 35, 252, + 50, 234, 51, 105, 235, 114, 35, 252, 50, 197, 216, 149, 35, 252, 50, 197, + 216, 199, 95, 35, 252, 50, 197, 216, 199, 96, 251, 157, 20, 35, 252, 50, + 229, 190, 199, 95, 35, 252, 50, 216, 167, 199, 95, 35, 252, 50, 199, 17, + 199, 95, 35, 252, 50, 199, 17, 198, 249, 35, 252, 50, 197, 216, 233, 15, + 35, 252, 50, 197, 216, 233, 16, 251, 157, 20, 35, 252, 50, 229, 190, 233, + 15, 35, 252, 50, 199, 17, 233, 15, 35, 252, 50, 199, 17, 91, 228, 140, + 35, 252, 50, 199, 17, 115, 228, 140, 35, 252, 50, 234, 51, 232, 226, 228, + 140, 35, 252, 50, 197, 216, 232, 226, 228, 140, 35, 252, 50, 199, 17, + 232, 226, 228, 140, 35, 252, 50, 247, 82, 232, 226, 228, 140, 35, 252, + 50, 214, 199, 232, 226, 228, 140, 35, 252, 50, 199, 17, 91, 189, 35, 252, + 50, 199, 17, 232, 226, 189, 35, 252, 50, 237, 109, 232, 226, 216, 15, 35, + 252, 50, 201, 47, 233, 16, 216, 15, 35, 91, 132, 56, 35, 91, 132, 3, 251, + 157, 20, 35, 105, 198, 254, 56, 35, 115, 208, 21, 56, 35, 192, 78, 56, + 35, 199, 204, 56, 35, 235, 116, 56, 35, 211, 170, 56, 35, 105, 211, 169, + 56, 35, 115, 211, 169, 56, 35, 232, 128, 211, 169, 56, 35, 232, 226, 211, + 169, 56, 35, 216, 161, 56, 35, 220, 151, 249, 75, 56, 35, 219, 85, 56, + 35, 211, 16, 56, 35, 192, 211, 56, 35, 250, 226, 56, 35, 250, 243, 56, + 35, 230, 220, 56, 35, 197, 171, 249, 75, 56, 35, 191, 78, 56, 35, 91, + 208, 23, 56, 35, 202, 162, 56, 35, 223, 143, 56, 213, 32, 56, 206, 136, + 203, 237, 56, 206, 136, 196, 106, 56, 206, 136, 204, 17, 56, 206, 136, + 203, 175, 56, 206, 136, 236, 250, 203, 175, 56, 206, 136, 202, 186, 56, + 206, 136, 237, 104, 56, 206, 136, 208, 5, 56, 206, 136, 203, 254, 56, + 206, 136, 235, 67, 56, 206, 136, 250, 220, 56, 206, 136, 247, 17, 56, + 250, 211, 113, 35, 16, 199, 167, 207, 3, 209, 223, 236, 227, 3, 210, 51, + 209, 223, 236, 227, 3, 209, 84, 229, 235, 209, 223, 236, 227, 3, 199, + 170, 229, 235, 209, 223, 236, 227, 3, 247, 105, 209, 223, 236, 227, 3, + 243, 86, 209, 223, 236, 227, 3, 193, 35, 209, 223, 236, 227, 3, 229, 200, + 209, 223, 236, 227, 3, 231, 188, 209, 223, 236, 227, 3, 198, 184, 209, + 223, 236, 227, 3, 57, 209, 223, 236, 227, 3, 248, 69, 209, 223, 236, 227, + 3, 203, 78, 209, 223, 236, 227, 3, 242, 206, 209, 223, 236, 227, 3, 217, + 89, 209, 223, 236, 227, 3, 217, 26, 209, 223, 236, 227, 3, 205, 108, 209, + 223, 236, 227, 3, 219, 141, 209, 223, 236, 227, 3, 248, 92, 209, 223, + 236, 227, 3, 247, 89, 209, 101, 209, 223, 236, 227, 3, 236, 156, 209, + 223, 236, 227, 3, 242, 80, 209, 223, 236, 227, 3, 202, 83, 209, 223, 236, + 227, 3, 242, 81, 209, 223, 236, 227, 3, 248, 254, 209, 223, 236, 227, 3, + 203, 65, 209, 223, 236, 227, 3, 228, 187, 209, 223, 236, 227, 3, 229, + 148, 209, 223, 236, 227, 3, 247, 245, 219, 212, 209, 223, 236, 227, 3, + 247, 78, 209, 223, 236, 227, 3, 207, 142, 209, 223, 236, 227, 3, 234, + 214, 209, 223, 236, 227, 3, 235, 124, 209, 223, 236, 227, 3, 197, 72, + 209, 223, 236, 227, 3, 249, 1, 209, 223, 236, 227, 3, 209, 102, 197, 254, + 209, 223, 236, 227, 3, 195, 47, 209, 223, 236, 227, 3, 210, 132, 209, + 223, 236, 227, 3, 206, 125, 209, 223, 236, 227, 3, 219, 125, 209, 223, + 236, 227, 3, 210, 248, 249, 146, 209, 223, 236, 227, 3, 232, 182, 209, + 223, 236, 227, 3, 230, 212, 209, 223, 236, 227, 3, 201, 50, 209, 223, + 236, 227, 3, 2, 250, 132, 209, 223, 236, 227, 3, 193, 135, 249, 97, 209, + 223, 236, 227, 3, 33, 211, 172, 106, 218, 181, 1, 65, 218, 181, 1, 71, + 218, 181, 1, 250, 120, 218, 181, 1, 248, 204, 218, 181, 1, 232, 51, 218, + 181, 1, 238, 127, 218, 181, 1, 68, 218, 181, 1, 193, 224, 218, 181, 1, + 191, 166, 218, 181, 1, 199, 51, 218, 181, 1, 223, 35, 218, 181, 1, 222, + 152, 218, 181, 1, 208, 104, 218, 181, 1, 172, 218, 181, 1, 218, 168, 218, + 181, 1, 215, 61, 218, 181, 1, 216, 17, 218, 181, 1, 213, 80, 218, 181, 1, + 66, 218, 181, 1, 210, 236, 218, 181, 1, 221, 102, 218, 181, 1, 146, 218, + 181, 1, 206, 8, 218, 181, 1, 200, 43, 218, 181, 1, 197, 135, 218, 181, 1, + 251, 132, 218, 181, 1, 234, 103, 218, 181, 1, 230, 116, 218, 181, 1, 192, + 235, 247, 95, 1, 65, 247, 95, 1, 210, 222, 247, 95, 1, 238, 127, 247, 95, + 1, 172, 247, 95, 1, 196, 28, 247, 95, 1, 146, 247, 95, 1, 219, 242, 247, + 95, 1, 254, 215, 247, 95, 1, 208, 104, 247, 95, 1, 250, 120, 247, 95, 1, + 218, 168, 247, 95, 1, 74, 247, 95, 1, 238, 34, 247, 95, 1, 200, 43, 247, + 95, 1, 203, 167, 247, 95, 1, 203, 166, 247, 95, 1, 206, 8, 247, 95, 1, + 247, 192, 247, 95, 1, 66, 247, 95, 1, 213, 80, 247, 95, 1, 192, 235, 247, + 95, 1, 215, 61, 247, 95, 1, 197, 134, 247, 95, 1, 210, 236, 247, 95, 1, + 201, 178, 247, 95, 1, 68, 247, 95, 1, 71, 247, 95, 1, 196, 25, 247, 95, + 1, 222, 152, 247, 95, 1, 222, 143, 247, 95, 1, 214, 164, 247, 95, 1, 196, + 30, 247, 95, 1, 232, 51, 247, 95, 1, 231, 242, 247, 95, 1, 201, 118, 247, + 95, 1, 201, 117, 247, 95, 1, 214, 70, 247, 95, 1, 223, 199, 247, 95, 1, + 247, 191, 247, 95, 1, 197, 135, 247, 95, 1, 196, 27, 247, 95, 1, 206, + 110, 247, 95, 1, 217, 16, 247, 95, 1, 217, 15, 247, 95, 1, 217, 14, 247, + 95, 1, 217, 13, 247, 95, 1, 219, 241, 247, 95, 1, 234, 218, 247, 95, 1, + 196, 26, 94, 234, 54, 198, 229, 77, 94, 234, 54, 17, 107, 94, 234, 54, + 17, 109, 94, 234, 54, 17, 138, 94, 234, 54, 17, 134, 94, 234, 54, 17, + 149, 94, 234, 54, 17, 169, 94, 234, 54, 17, 175, 94, 234, 54, 17, 171, + 94, 234, 54, 17, 178, 94, 234, 54, 31, 199, 95, 94, 234, 54, 31, 197, 32, + 94, 234, 54, 31, 198, 249, 94, 234, 54, 31, 232, 135, 94, 234, 54, 31, + 233, 15, 94, 234, 54, 31, 202, 120, 94, 234, 54, 31, 203, 241, 94, 234, + 54, 31, 234, 153, 94, 234, 54, 31, 213, 169, 94, 234, 54, 31, 91, 228, + 140, 94, 234, 54, 31, 105, 228, 140, 94, 234, 54, 31, 115, 228, 140, 94, + 234, 54, 31, 232, 128, 228, 140, 94, 234, 54, 31, 232, 226, 228, 140, 94, + 234, 54, 31, 202, 136, 228, 140, 94, 234, 54, 31, 203, 247, 228, 140, 94, + 234, 54, 31, 234, 164, 228, 140, 94, 234, 54, 31, 213, 175, 228, 140, 39, + 43, 1, 65, 39, 43, 1, 249, 17, 39, 43, 1, 222, 22, 39, 43, 1, 237, 146, + 39, 43, 1, 71, 39, 43, 1, 195, 153, 39, 43, 1, 191, 87, 39, 43, 1, 229, + 245, 39, 43, 1, 199, 33, 39, 43, 1, 68, 39, 43, 1, 155, 39, 43, 1, 234, + 140, 39, 43, 1, 234, 114, 39, 43, 1, 234, 103, 39, 43, 1, 234, 12, 39, + 43, 1, 74, 39, 43, 1, 210, 63, 39, 43, 1, 203, 113, 39, 43, 1, 220, 232, + 39, 43, 1, 234, 34, 39, 43, 1, 234, 22, 39, 43, 1, 199, 145, 39, 43, 1, + 66, 39, 43, 1, 234, 143, 39, 43, 1, 209, 214, 39, 43, 1, 221, 197, 39, + 43, 1, 234, 181, 39, 43, 1, 234, 24, 39, 43, 1, 243, 127, 39, 43, 1, 223, + 199, 39, 43, 1, 196, 30, 39, 43, 1, 234, 5, 39, 43, 212, 134, 107, 39, + 43, 212, 134, 149, 39, 43, 212, 134, 199, 95, 39, 43, 212, 134, 233, 15, + 39, 43, 1, 192, 80, 39, 43, 1, 213, 16, 197, 161, 39, 43, 1, 202, 0, 197, + 161, 230, 231, 1, 251, 239, 230, 231, 1, 249, 117, 230, 231, 1, 231, 50, + 230, 231, 1, 238, 13, 230, 231, 1, 251, 234, 230, 231, 1, 208, 87, 230, + 231, 1, 223, 48, 230, 231, 1, 230, 83, 230, 231, 1, 198, 243, 230, 231, + 1, 234, 151, 230, 231, 1, 220, 189, 230, 231, 1, 220, 100, 230, 231, 1, + 217, 80, 230, 231, 1, 214, 201, 230, 231, 1, 223, 1, 230, 231, 1, 196, + 48, 230, 231, 1, 210, 195, 230, 231, 1, 213, 169, 230, 231, 1, 207, 155, + 230, 231, 1, 205, 112, 230, 231, 1, 199, 111, 230, 231, 1, 193, 59, 230, + 231, 1, 233, 89, 230, 231, 1, 223, 203, 230, 231, 1, 228, 123, 230, 231, + 1, 211, 29, 230, 231, 1, 213, 175, 228, 140, 39, 210, 2, 1, 251, 132, 39, + 210, 2, 1, 247, 230, 39, 210, 2, 1, 231, 224, 39, 210, 2, 1, 236, 160, + 39, 210, 2, 1, 71, 39, 210, 2, 1, 191, 53, 39, 210, 2, 1, 235, 27, 39, + 210, 2, 1, 191, 95, 39, 210, 2, 1, 235, 25, 39, 210, 2, 1, 68, 39, 210, + 2, 1, 221, 50, 39, 210, 2, 1, 219, 208, 39, 210, 2, 1, 216, 184, 39, 210, + 2, 1, 214, 100, 39, 210, 2, 1, 195, 7, 39, 210, 2, 1, 210, 48, 39, 210, + 2, 1, 207, 70, 39, 210, 2, 1, 202, 193, 39, 210, 2, 1, 199, 217, 39, 210, + 2, 1, 66, 39, 210, 2, 1, 243, 106, 39, 210, 2, 1, 203, 47, 39, 210, 2, 1, + 203, 115, 39, 210, 2, 1, 191, 227, 39, 210, 2, 1, 192, 58, 39, 210, 2, 1, + 74, 39, 210, 2, 1, 211, 87, 39, 210, 2, 1, 234, 181, 39, 210, 2, 1, 140, + 39, 210, 2, 1, 197, 145, 39, 210, 2, 1, 195, 140, 39, 210, 2, 1, 192, 62, + 39, 210, 2, 1, 192, 60, 39, 210, 2, 1, 192, 95, 39, 210, 2, 1, 223, 226, + 39, 210, 2, 1, 191, 225, 39, 210, 2, 1, 170, 39, 210, 2, 1, 228, 35, 33, + 39, 210, 2, 1, 251, 132, 33, 39, 210, 2, 1, 236, 160, 33, 39, 210, 2, 1, + 191, 95, 33, 39, 210, 2, 1, 214, 100, 33, 39, 210, 2, 1, 202, 193, 196, + 142, 1, 251, 164, 196, 142, 1, 248, 212, 196, 142, 1, 231, 212, 196, 142, + 1, 221, 215, 196, 142, 1, 237, 106, 196, 142, 1, 229, 23, 196, 142, 1, + 193, 48, 196, 142, 1, 191, 76, 196, 142, 1, 228, 179, 196, 142, 1, 199, + 73, 196, 142, 1, 191, 250, 196, 142, 1, 222, 106, 196, 142, 1, 203, 69, + 196, 142, 1, 220, 31, 196, 142, 1, 216, 193, 196, 142, 1, 237, 64, 196, + 142, 1, 212, 130, 196, 142, 1, 190, 251, 196, 142, 1, 205, 147, 196, 142, + 1, 251, 230, 196, 142, 1, 208, 165, 196, 142, 1, 205, 191, 196, 142, 1, + 208, 38, 196, 142, 1, 207, 133, 196, 142, 1, 199, 37, 196, 142, 1, 231, + 86, 196, 142, 1, 159, 196, 142, 1, 68, 196, 142, 1, 66, 196, 142, 1, 201, + 129, 196, 142, 193, 23, 236, 205, 39, 209, 252, 3, 65, 39, 209, 252, 3, + 68, 39, 209, 252, 3, 66, 39, 209, 252, 3, 155, 39, 209, 252, 3, 220, 232, + 39, 209, 252, 3, 231, 240, 39, 209, 252, 3, 230, 179, 39, 209, 252, 3, + 192, 220, 39, 209, 252, 3, 247, 160, 39, 209, 252, 3, 223, 32, 39, 209, + 252, 3, 222, 244, 39, 209, 252, 3, 190, 190, 39, 209, 252, 3, 197, 94, + 39, 209, 252, 3, 238, 32, 39, 209, 252, 3, 237, 44, 39, 209, 252, 3, 235, + 89, 39, 209, 252, 3, 199, 49, 39, 209, 252, 3, 168, 39, 209, 252, 3, 249, + 153, 39, 209, 252, 3, 233, 109, 39, 209, 252, 3, 180, 39, 209, 252, 3, + 212, 178, 39, 209, 252, 3, 174, 39, 209, 252, 3, 216, 100, 39, 209, 252, + 3, 215, 155, 39, 209, 252, 3, 170, 39, 209, 252, 3, 195, 188, 39, 209, + 252, 3, 195, 69, 39, 209, 252, 3, 165, 39, 209, 252, 3, 206, 68, 39, 209, + 252, 3, 173, 39, 209, 252, 3, 188, 39, 209, 252, 3, 191, 123, 39, 209, + 252, 3, 203, 165, 39, 209, 252, 3, 201, 175, 39, 209, 252, 3, 140, 39, + 209, 252, 3, 250, 157, 39, 209, 252, 3, 250, 156, 39, 209, 252, 3, 250, + 155, 39, 209, 252, 3, 192, 189, 39, 209, 252, 3, 238, 9, 39, 209, 252, 3, + 238, 8, 39, 209, 252, 3, 249, 128, 39, 209, 252, 3, 247, 212, 39, 209, + 252, 193, 23, 236, 205, 39, 209, 252, 31, 107, 39, 209, 252, 31, 109, 39, + 209, 252, 31, 199, 95, 39, 209, 252, 31, 197, 32, 39, 209, 252, 31, 228, + 140, 237, 84, 6, 1, 179, 68, 237, 84, 6, 1, 179, 71, 237, 84, 6, 1, 179, + 65, 237, 84, 6, 1, 179, 251, 245, 237, 84, 6, 1, 179, 74, 237, 84, 6, 1, + 179, 211, 87, 237, 84, 6, 1, 203, 40, 68, 237, 84, 6, 1, 203, 40, 71, + 237, 84, 6, 1, 203, 40, 65, 237, 84, 6, 1, 203, 40, 251, 245, 237, 84, 6, + 1, 203, 40, 74, 237, 84, 6, 1, 203, 40, 211, 87, 237, 84, 6, 1, 250, 131, + 237, 84, 6, 1, 210, 250, 237, 84, 6, 1, 193, 0, 237, 84, 6, 1, 192, 77, + 237, 84, 6, 1, 230, 116, 237, 84, 6, 1, 210, 49, 237, 84, 6, 1, 249, 1, + 237, 84, 6, 1, 199, 121, 237, 84, 6, 1, 237, 131, 237, 84, 6, 1, 243, + 123, 237, 84, 6, 1, 223, 8, 237, 84, 6, 1, 222, 29, 237, 84, 6, 1, 231, + 186, 237, 84, 6, 1, 234, 181, 237, 84, 6, 1, 195, 148, 237, 84, 6, 1, + 233, 248, 237, 84, 6, 1, 199, 31, 237, 84, 6, 1, 234, 22, 237, 84, 6, 1, + 191, 84, 237, 84, 6, 1, 234, 12, 237, 84, 6, 1, 191, 61, 237, 84, 6, 1, + 234, 34, 237, 84, 6, 1, 234, 140, 237, 84, 6, 1, 234, 114, 237, 84, 6, 1, + 234, 103, 237, 84, 6, 1, 234, 88, 237, 84, 6, 1, 211, 133, 237, 84, 6, 1, + 233, 224, 237, 84, 2, 1, 179, 68, 237, 84, 2, 1, 179, 71, 237, 84, 2, 1, + 179, 65, 237, 84, 2, 1, 179, 251, 245, 237, 84, 2, 1, 179, 74, 237, 84, + 2, 1, 179, 211, 87, 237, 84, 2, 1, 203, 40, 68, 237, 84, 2, 1, 203, 40, + 71, 237, 84, 2, 1, 203, 40, 65, 237, 84, 2, 1, 203, 40, 251, 245, 237, + 84, 2, 1, 203, 40, 74, 237, 84, 2, 1, 203, 40, 211, 87, 237, 84, 2, 1, + 250, 131, 237, 84, 2, 1, 210, 250, 237, 84, 2, 1, 193, 0, 237, 84, 2, 1, + 192, 77, 237, 84, 2, 1, 230, 116, 237, 84, 2, 1, 210, 49, 237, 84, 2, 1, + 249, 1, 237, 84, 2, 1, 199, 121, 237, 84, 2, 1, 237, 131, 237, 84, 2, 1, + 243, 123, 237, 84, 2, 1, 223, 8, 237, 84, 2, 1, 222, 29, 237, 84, 2, 1, + 231, 186, 237, 84, 2, 1, 234, 181, 237, 84, 2, 1, 195, 148, 237, 84, 2, + 1, 233, 248, 237, 84, 2, 1, 199, 31, 237, 84, 2, 1, 234, 22, 237, 84, 2, + 1, 191, 84, 237, 84, 2, 1, 234, 12, 237, 84, 2, 1, 191, 61, 237, 84, 2, + 1, 234, 34, 237, 84, 2, 1, 234, 140, 237, 84, 2, 1, 234, 114, 237, 84, 2, + 1, 234, 103, 237, 84, 2, 1, 234, 88, 237, 84, 2, 1, 211, 133, 237, 84, 2, + 1, 233, 224, 203, 120, 1, 210, 45, 203, 120, 1, 198, 40, 203, 120, 1, + 221, 154, 203, 120, 1, 233, 52, 203, 120, 1, 199, 6, 203, 120, 1, 202, + 46, 203, 120, 1, 200, 172, 203, 120, 1, 243, 40, 203, 120, 1, 192, 79, + 203, 120, 1, 228, 137, 203, 120, 1, 248, 187, 203, 120, 1, 237, 145, 203, + 120, 1, 231, 226, 203, 120, 1, 195, 2, 203, 120, 1, 199, 12, 203, 120, 1, + 191, 4, 203, 120, 1, 216, 227, 203, 120, 1, 222, 180, 203, 120, 1, 193, + 39, 203, 120, 1, 230, 93, 203, 120, 1, 219, 25, 203, 120, 1, 216, 45, + 203, 120, 1, 223, 206, 203, 120, 1, 234, 179, 203, 120, 1, 250, 209, 203, + 120, 1, 252, 30, 203, 120, 1, 211, 104, 203, 120, 1, 193, 26, 203, 120, + 1, 211, 14, 203, 120, 1, 251, 245, 203, 120, 1, 206, 153, 203, 120, 1, + 212, 130, 203, 120, 1, 234, 200, 203, 120, 1, 251, 250, 203, 120, 1, 228, + 26, 203, 120, 1, 196, 77, 203, 120, 1, 211, 180, 203, 120, 1, 211, 79, + 203, 120, 1, 211, 131, 203, 120, 1, 250, 137, 203, 120, 1, 251, 9, 203, + 120, 1, 211, 56, 203, 120, 1, 251, 225, 203, 120, 1, 234, 26, 203, 120, + 1, 250, 240, 203, 120, 1, 234, 211, 203, 120, 1, 228, 34, 203, 120, 1, + 192, 41, 211, 33, 1, 251, 192, 211, 33, 1, 249, 153, 211, 33, 1, 190, + 190, 211, 33, 1, 223, 32, 211, 33, 1, 192, 220, 211, 33, 1, 221, 215, + 211, 33, 1, 237, 130, 211, 33, 1, 165, 211, 33, 1, 188, 211, 33, 1, 203, + 75, 211, 33, 1, 237, 68, 211, 33, 1, 247, 67, 211, 33, 1, 231, 240, 211, + 33, 1, 233, 109, 211, 33, 1, 208, 94, 211, 33, 1, 222, 123, 211, 33, 1, + 220, 121, 211, 33, 1, 216, 59, 211, 33, 1, 212, 114, 211, 33, 1, 193, + 133, 211, 33, 1, 140, 211, 33, 1, 170, 211, 33, 1, 65, 211, 33, 1, 71, + 211, 33, 1, 68, 211, 33, 1, 74, 211, 33, 1, 66, 211, 33, 1, 252, 206, + 211, 33, 1, 234, 188, 211, 33, 1, 211, 87, 211, 33, 17, 191, 77, 211, 33, + 17, 107, 211, 33, 17, 109, 211, 33, 17, 138, 211, 33, 17, 134, 211, 33, + 17, 149, 211, 33, 17, 169, 211, 33, 17, 175, 211, 33, 17, 171, 211, 33, + 17, 178, 211, 35, 6, 1, 65, 211, 35, 6, 1, 251, 236, 211, 35, 6, 1, 251, + 230, 211, 35, 6, 1, 251, 245, 211, 35, 6, 1, 248, 56, 211, 35, 6, 1, 247, + 1, 211, 35, 6, 1, 234, 172, 211, 35, 6, 1, 71, 211, 35, 6, 1, 234, 152, + 211, 35, 6, 1, 140, 211, 35, 6, 1, 228, 93, 211, 35, 6, 1, 68, 211, 35, + 6, 1, 155, 211, 35, 6, 1, 234, 171, 211, 35, 6, 1, 220, 153, 211, 35, 6, + 1, 173, 211, 35, 6, 1, 174, 211, 35, 6, 1, 180, 211, 35, 6, 1, 74, 211, + 35, 6, 1, 211, 130, 211, 35, 6, 1, 168, 211, 35, 6, 1, 234, 170, 211, 35, + 6, 1, 188, 211, 35, 6, 1, 203, 165, 211, 35, 6, 1, 190, 190, 211, 35, 6, + 1, 234, 169, 211, 35, 6, 1, 197, 168, 211, 35, 6, 1, 234, 168, 211, 35, + 6, 1, 197, 157, 211, 35, 6, 1, 237, 68, 211, 35, 6, 1, 66, 211, 35, 6, 1, + 193, 190, 211, 35, 6, 1, 221, 215, 211, 35, 6, 1, 231, 91, 211, 35, 6, 1, + 191, 123, 211, 35, 6, 1, 191, 71, 211, 35, 2, 1, 65, 211, 35, 2, 1, 251, + 236, 211, 35, 2, 1, 251, 230, 211, 35, 2, 1, 251, 245, 211, 35, 2, 1, + 248, 56, 211, 35, 2, 1, 247, 1, 211, 35, 2, 1, 234, 172, 211, 35, 2, 1, + 71, 211, 35, 2, 1, 234, 152, 211, 35, 2, 1, 140, 211, 35, 2, 1, 228, 93, + 211, 35, 2, 1, 68, 211, 35, 2, 1, 155, 211, 35, 2, 1, 234, 171, 211, 35, + 2, 1, 220, 153, 211, 35, 2, 1, 173, 211, 35, 2, 1, 174, 211, 35, 2, 1, + 180, 211, 35, 2, 1, 74, 211, 35, 2, 1, 211, 130, 211, 35, 2, 1, 168, 211, + 35, 2, 1, 234, 170, 211, 35, 2, 1, 188, 211, 35, 2, 1, 203, 165, 211, 35, + 2, 1, 190, 190, 211, 35, 2, 1, 234, 169, 211, 35, 2, 1, 197, 168, 211, + 35, 2, 1, 234, 168, 211, 35, 2, 1, 197, 157, 211, 35, 2, 1, 237, 68, 211, + 35, 2, 1, 66, 211, 35, 2, 1, 193, 190, 211, 35, 2, 1, 221, 215, 211, 35, + 2, 1, 231, 91, 211, 35, 2, 1, 191, 123, 211, 35, 2, 1, 191, 71, 234, 136, + 1, 65, 234, 136, 1, 249, 17, 234, 136, 1, 247, 42, 234, 136, 1, 243, 127, + 234, 136, 1, 237, 146, 234, 136, 1, 214, 154, 234, 136, 1, 237, 59, 234, + 136, 1, 234, 166, 234, 136, 1, 71, 234, 136, 1, 233, 59, 234, 136, 1, + 231, 165, 234, 136, 1, 231, 20, 234, 136, 1, 229, 245, 234, 136, 1, 68, + 234, 136, 1, 223, 10, 234, 136, 1, 222, 22, 234, 136, 1, 219, 238, 234, + 136, 1, 219, 68, 234, 136, 1, 216, 232, 234, 136, 1, 214, 121, 234, 136, + 1, 180, 234, 136, 1, 213, 150, 234, 136, 1, 74, 234, 136, 1, 210, 63, + 234, 136, 1, 208, 75, 234, 136, 1, 207, 113, 234, 136, 1, 206, 104, 234, + 136, 1, 205, 68, 234, 136, 1, 203, 113, 234, 136, 1, 199, 145, 234, 136, + 1, 199, 33, 234, 136, 1, 66, 234, 136, 1, 195, 153, 234, 136, 1, 192, + 214, 234, 136, 1, 192, 159, 234, 136, 1, 191, 87, 234, 136, 1, 191, 62, + 234, 136, 1, 231, 77, 234, 136, 1, 231, 83, 234, 136, 1, 221, 197, 247, + 75, 251, 193, 1, 251, 159, 247, 75, 251, 193, 1, 248, 214, 247, 75, 251, + 193, 1, 231, 40, 247, 75, 251, 193, 1, 237, 211, 247, 75, 251, 193, 1, + 234, 199, 247, 75, 251, 193, 1, 191, 98, 247, 75, 251, 193, 1, 233, 184, + 247, 75, 251, 193, 1, 191, 56, 247, 75, 251, 193, 1, 199, 174, 247, 75, + 251, 193, 1, 247, 1, 247, 75, 251, 193, 1, 191, 236, 247, 75, 251, 193, + 1, 191, 71, 247, 75, 251, 193, 1, 223, 76, 247, 75, 251, 193, 1, 203, + 165, 247, 75, 251, 193, 1, 220, 24, 247, 75, 251, 193, 1, 223, 89, 247, + 75, 251, 193, 1, 192, 210, 247, 75, 251, 193, 1, 235, 43, 247, 75, 251, + 193, 1, 247, 102, 247, 75, 251, 193, 1, 222, 245, 247, 75, 251, 193, 1, + 222, 65, 247, 75, 251, 193, 1, 218, 177, 247, 75, 251, 193, 1, 229, 179, + 247, 75, 251, 193, 1, 208, 76, 247, 75, 251, 193, 1, 251, 67, 247, 75, + 251, 193, 1, 243, 57, 247, 75, 251, 193, 1, 243, 95, 247, 75, 251, 193, + 1, 238, 140, 247, 75, 251, 193, 1, 217, 68, 247, 75, 251, 193, 1, 208, + 81, 247, 75, 251, 193, 1, 212, 252, 247, 75, 251, 193, 1, 235, 20, 247, + 75, 251, 193, 1, 203, 147, 247, 75, 251, 193, 1, 223, 11, 247, 75, 251, + 193, 1, 211, 104, 247, 75, 251, 193, 1, 197, 3, 247, 75, 251, 193, 1, + 233, 82, 247, 75, 251, 193, 1, 235, 33, 247, 75, 251, 193, 1, 243, 133, + 247, 75, 251, 193, 1, 210, 34, 247, 75, 251, 193, 1, 231, 67, 247, 75, + 251, 193, 1, 207, 130, 247, 75, 251, 193, 1, 203, 174, 247, 75, 251, 193, + 1, 195, 72, 247, 75, 251, 193, 1, 198, 118, 247, 75, 251, 193, 1, 203, + 18, 247, 75, 251, 193, 1, 223, 46, 247, 75, 251, 193, 1, 238, 141, 247, + 75, 251, 193, 1, 247, 67, 247, 75, 251, 193, 1, 192, 84, 247, 75, 251, + 193, 1, 209, 114, 247, 75, 251, 193, 1, 221, 117, 247, 75, 251, 193, 242, + 254, 77, 195, 29, 6, 1, 65, 195, 29, 6, 1, 249, 48, 195, 29, 6, 1, 249, + 17, 195, 29, 6, 1, 247, 42, 195, 29, 6, 1, 243, 127, 195, 29, 6, 1, 237, + 146, 195, 29, 6, 1, 237, 59, 195, 29, 6, 1, 234, 166, 195, 29, 6, 1, 71, + 195, 29, 6, 1, 233, 59, 195, 29, 6, 1, 231, 240, 195, 29, 6, 1, 140, 195, + 29, 6, 1, 229, 177, 195, 29, 6, 1, 68, 195, 29, 6, 1, 223, 196, 195, 29, + 6, 1, 223, 10, 195, 29, 6, 1, 155, 195, 29, 6, 1, 173, 195, 29, 6, 1, + 219, 73, 195, 29, 6, 1, 216, 232, 195, 29, 6, 1, 214, 121, 195, 29, 6, 1, + 213, 150, 195, 29, 6, 1, 74, 195, 29, 6, 1, 210, 63, 195, 29, 6, 1, 208, + 96, 195, 29, 6, 1, 207, 113, 195, 29, 6, 1, 205, 68, 195, 29, 6, 1, 203, + 113, 195, 29, 6, 1, 199, 145, 195, 29, 6, 1, 199, 33, 195, 29, 6, 1, 66, + 195, 29, 6, 1, 195, 153, 195, 29, 6, 1, 192, 214, 195, 29, 6, 1, 192, + 159, 195, 29, 6, 1, 191, 87, 195, 29, 2, 1, 65, 195, 29, 2, 1, 249, 48, + 195, 29, 2, 1, 249, 17, 195, 29, 2, 1, 247, 42, 195, 29, 2, 1, 243, 127, + 195, 29, 2, 1, 237, 146, 195, 29, 2, 1, 237, 59, 195, 29, 2, 1, 234, 166, + 195, 29, 2, 1, 71, 195, 29, 2, 1, 233, 59, 195, 29, 2, 1, 231, 240, 195, + 29, 2, 1, 140, 195, 29, 2, 1, 229, 177, 195, 29, 2, 1, 68, 195, 29, 2, 1, + 223, 196, 195, 29, 2, 1, 223, 10, 195, 29, 2, 1, 155, 195, 29, 2, 1, 173, + 195, 29, 2, 1, 219, 73, 195, 29, 2, 1, 216, 232, 195, 29, 2, 1, 214, 121, + 195, 29, 2, 1, 213, 150, 195, 29, 2, 1, 74, 195, 29, 2, 1, 210, 63, 195, + 29, 2, 1, 208, 96, 195, 29, 2, 1, 207, 113, 195, 29, 2, 1, 205, 68, 195, + 29, 2, 1, 203, 113, 195, 29, 2, 1, 199, 145, 195, 29, 2, 1, 199, 33, 195, + 29, 2, 1, 66, 195, 29, 2, 1, 195, 153, 195, 29, 2, 1, 192, 214, 195, 29, + 2, 1, 192, 159, 195, 29, 2, 1, 191, 87, 32, 42, 3, 252, 154, 32, 42, 3, + 252, 153, 32, 42, 3, 252, 152, 32, 42, 3, 252, 151, 32, 42, 3, 252, 150, + 32, 42, 3, 252, 149, 32, 42, 3, 252, 148, 32, 42, 3, 252, 147, 32, 42, 3, + 252, 146, 32, 42, 3, 252, 145, 32, 42, 3, 252, 144, 32, 42, 3, 252, 143, + 32, 42, 3, 252, 142, 32, 42, 3, 252, 141, 32, 42, 3, 252, 140, 32, 42, 3, + 252, 139, 32, 42, 3, 252, 138, 32, 42, 3, 252, 137, 32, 42, 3, 252, 136, + 32, 42, 3, 252, 135, 32, 42, 3, 252, 134, 32, 42, 3, 252, 133, 32, 42, 3, + 252, 132, 32, 42, 3, 252, 131, 32, 42, 3, 252, 130, 32, 42, 3, 252, 129, + 32, 42, 3, 252, 128, 32, 42, 3, 255, 164, 32, 42, 3, 252, 127, 32, 42, 3, + 252, 126, 32, 42, 3, 252, 125, 32, 42, 3, 252, 124, 32, 42, 3, 252, 123, + 32, 42, 3, 252, 122, 32, 42, 3, 252, 121, 32, 42, 3, 252, 120, 32, 42, 3, + 252, 119, 32, 42, 3, 252, 118, 32, 42, 3, 252, 117, 32, 42, 3, 252, 116, + 32, 42, 3, 252, 115, 32, 42, 3, 252, 114, 32, 42, 3, 252, 113, 32, 42, 3, + 252, 112, 32, 42, 3, 252, 111, 32, 42, 3, 252, 110, 32, 42, 3, 252, 109, + 32, 42, 3, 252, 108, 32, 42, 3, 252, 107, 32, 42, 3, 252, 106, 32, 42, 3, + 252, 105, 32, 42, 3, 252, 104, 32, 42, 3, 252, 103, 32, 42, 3, 252, 102, + 32, 42, 3, 252, 101, 32, 42, 3, 252, 100, 32, 42, 3, 252, 99, 32, 42, 3, + 252, 98, 32, 42, 3, 252, 97, 32, 42, 3, 252, 96, 32, 42, 3, 252, 95, 32, + 42, 3, 252, 94, 32, 42, 3, 252, 93, 32, 42, 3, 252, 92, 32, 42, 3, 252, + 91, 32, 42, 3, 252, 90, 32, 42, 3, 252, 89, 32, 42, 3, 252, 88, 32, 42, + 3, 252, 87, 32, 42, 3, 252, 86, 32, 42, 3, 252, 85, 32, 42, 3, 255, 77, + 32, 42, 3, 252, 84, 32, 42, 3, 252, 83, 32, 42, 3, 255, 42, 32, 42, 3, + 252, 82, 32, 42, 3, 252, 81, 32, 42, 3, 252, 80, 32, 42, 3, 252, 79, 32, + 42, 3, 255, 29, 32, 42, 3, 252, 78, 32, 42, 3, 252, 77, 32, 42, 3, 252, + 76, 32, 42, 3, 252, 75, 32, 42, 3, 252, 74, 32, 42, 3, 254, 101, 32, 42, + 3, 254, 100, 32, 42, 3, 254, 99, 32, 42, 3, 254, 98, 32, 42, 3, 254, 97, + 32, 42, 3, 254, 96, 32, 42, 3, 254, 95, 32, 42, 3, 254, 94, 32, 42, 3, + 254, 92, 32, 42, 3, 254, 91, 32, 42, 3, 254, 90, 32, 42, 3, 254, 89, 32, + 42, 3, 254, 88, 32, 42, 3, 254, 87, 32, 42, 3, 254, 85, 32, 42, 3, 254, + 84, 32, 42, 3, 254, 83, 32, 42, 3, 254, 82, 32, 42, 3, 254, 81, 32, 42, + 3, 254, 80, 32, 42, 3, 254, 79, 32, 42, 3, 254, 78, 32, 42, 3, 254, 77, + 32, 42, 3, 254, 76, 32, 42, 3, 254, 75, 32, 42, 3, 254, 74, 32, 42, 3, + 254, 73, 32, 42, 3, 254, 72, 32, 42, 3, 254, 71, 32, 42, 3, 254, 70, 32, + 42, 3, 254, 69, 32, 42, 3, 254, 68, 32, 42, 3, 254, 67, 32, 42, 3, 254, + 65, 32, 42, 3, 254, 64, 32, 42, 3, 254, 63, 32, 42, 3, 254, 59, 32, 42, + 3, 254, 58, 32, 42, 3, 254, 57, 32, 42, 3, 254, 56, 32, 42, 3, 254, 52, + 32, 42, 3, 254, 51, 32, 42, 3, 254, 50, 32, 42, 3, 254, 49, 32, 42, 3, + 254, 48, 32, 42, 3, 254, 47, 32, 42, 3, 254, 46, 32, 42, 3, 254, 45, 32, + 42, 3, 254, 44, 32, 42, 3, 254, 43, 32, 42, 3, 254, 42, 32, 42, 3, 254, + 41, 32, 42, 3, 254, 40, 32, 42, 3, 254, 39, 32, 42, 3, 254, 38, 32, 42, + 3, 254, 37, 32, 42, 3, 254, 36, 32, 42, 3, 254, 35, 32, 42, 3, 254, 34, + 32, 42, 3, 254, 33, 32, 42, 3, 254, 32, 32, 42, 3, 254, 31, 32, 42, 3, + 254, 30, 32, 42, 3, 254, 28, 32, 42, 3, 254, 27, 32, 42, 3, 254, 26, 32, + 42, 3, 254, 25, 32, 42, 3, 254, 24, 32, 42, 3, 254, 22, 32, 42, 3, 254, + 21, 32, 42, 3, 254, 20, 32, 42, 3, 254, 19, 32, 42, 3, 254, 17, 32, 42, + 3, 254, 16, 32, 42, 3, 254, 15, 32, 42, 3, 253, 237, 32, 42, 3, 253, 235, + 32, 42, 3, 253, 233, 32, 42, 3, 253, 231, 32, 42, 3, 253, 229, 32, 42, 3, + 253, 227, 32, 42, 3, 253, 225, 32, 42, 3, 253, 223, 32, 42, 3, 253, 221, + 32, 42, 3, 253, 219, 32, 42, 3, 253, 217, 32, 42, 3, 253, 214, 32, 42, 3, + 253, 212, 32, 42, 3, 253, 210, 32, 42, 3, 253, 208, 32, 42, 3, 253, 206, + 32, 42, 3, 253, 204, 32, 42, 3, 253, 202, 32, 42, 3, 253, 200, 32, 42, 3, + 253, 118, 32, 42, 3, 253, 117, 32, 42, 3, 253, 116, 32, 42, 3, 253, 115, + 32, 42, 3, 253, 114, 32, 42, 3, 253, 113, 32, 42, 3, 253, 111, 32, 42, 3, + 253, 110, 32, 42, 3, 253, 109, 32, 42, 3, 253, 108, 32, 42, 3, 253, 107, + 32, 42, 3, 253, 106, 32, 42, 3, 253, 104, 32, 42, 3, 253, 103, 32, 42, 3, + 253, 99, 32, 42, 3, 253, 98, 32, 42, 3, 253, 96, 32, 42, 3, 253, 95, 32, + 42, 3, 253, 94, 32, 42, 3, 253, 93, 32, 42, 3, 253, 92, 32, 42, 3, 253, + 91, 32, 42, 3, 253, 90, 32, 42, 3, 253, 89, 32, 42, 3, 253, 88, 32, 42, + 3, 253, 87, 32, 42, 3, 253, 86, 32, 42, 3, 253, 85, 32, 42, 3, 253, 84, + 32, 42, 3, 253, 83, 32, 42, 3, 253, 82, 32, 42, 3, 253, 81, 32, 42, 3, + 253, 80, 32, 42, 3, 253, 79, 32, 42, 3, 253, 78, 32, 42, 3, 253, 77, 32, + 42, 3, 253, 76, 32, 42, 3, 253, 75, 32, 42, 3, 253, 74, 32, 42, 3, 253, + 73, 32, 42, 3, 253, 72, 32, 42, 3, 253, 71, 32, 42, 3, 253, 70, 32, 42, + 3, 253, 69, 32, 42, 3, 253, 68, 32, 42, 3, 253, 67, 32, 42, 3, 253, 66, + 32, 42, 3, 253, 65, 32, 42, 3, 253, 64, 32, 42, 3, 253, 63, 32, 42, 3, + 253, 62, 32, 42, 3, 253, 61, 32, 42, 3, 253, 60, 32, 42, 3, 253, 59, 32, + 42, 3, 253, 58, 32, 42, 3, 253, 57, 32, 42, 3, 253, 56, 32, 42, 3, 253, + 55, 32, 42, 3, 253, 54, 32, 42, 3, 253, 53, 32, 42, 3, 253, 52, 32, 42, + 3, 253, 51, 32, 42, 3, 253, 50, 32, 42, 3, 253, 49, 32, 42, 3, 253, 48, + 32, 42, 3, 253, 47, 32, 42, 3, 253, 46, 32, 42, 3, 253, 45, 32, 42, 3, + 253, 44, 32, 42, 3, 253, 43, 32, 42, 3, 253, 42, 32, 42, 3, 253, 41, 32, + 42, 3, 253, 40, 32, 42, 3, 253, 39, 32, 42, 3, 253, 38, 32, 42, 3, 253, + 37, 32, 42, 3, 253, 36, 32, 42, 3, 253, 35, 32, 42, 3, 253, 34, 32, 42, + 3, 253, 33, 32, 42, 3, 253, 32, 32, 42, 3, 253, 31, 32, 42, 3, 253, 30, + 32, 42, 3, 253, 29, 32, 42, 3, 253, 28, 32, 42, 3, 253, 27, 32, 42, 3, + 253, 26, 32, 42, 3, 253, 25, 32, 42, 3, 253, 24, 32, 42, 3, 253, 23, 32, + 42, 3, 253, 22, 32, 42, 3, 253, 21, 32, 42, 3, 253, 20, 32, 42, 3, 253, + 19, 32, 42, 3, 253, 18, 32, 42, 3, 253, 17, 32, 42, 3, 253, 16, 32, 42, + 3, 253, 15, 32, 42, 3, 253, 14, 32, 42, 3, 253, 13, 32, 42, 3, 253, 12, + 32, 42, 3, 253, 11, 32, 42, 3, 253, 10, 32, 42, 3, 253, 9, 32, 42, 3, + 253, 8, 32, 42, 3, 253, 7, 32, 42, 3, 253, 6, 32, 42, 3, 253, 5, 32, 42, + 3, 253, 4, 32, 42, 3, 253, 3, 32, 42, 3, 253, 2, 32, 42, 3, 253, 1, 32, + 42, 3, 253, 0, 32, 42, 3, 252, 255, 32, 42, 3, 252, 254, 32, 42, 3, 252, + 253, 32, 42, 3, 252, 252, 32, 42, 3, 252, 251, 32, 42, 3, 252, 250, 32, + 42, 3, 252, 249, 32, 42, 3, 252, 248, 32, 42, 3, 252, 247, 32, 42, 3, + 252, 246, 32, 42, 3, 252, 245, 32, 42, 3, 252, 244, 32, 42, 3, 252, 243, + 32, 42, 3, 252, 242, 32, 42, 3, 252, 241, 32, 42, 3, 252, 240, 32, 42, 3, + 252, 239, 32, 42, 3, 252, 238, 32, 42, 3, 252, 237, 32, 42, 3, 252, 236, + 65, 32, 42, 3, 252, 235, 250, 120, 32, 42, 3, 252, 234, 238, 127, 32, 42, + 3, 252, 233, 71, 32, 42, 3, 252, 232, 233, 175, 32, 42, 3, 252, 231, 230, + 116, 32, 42, 3, 252, 230, 223, 35, 32, 42, 3, 252, 229, 222, 152, 32, 42, + 3, 252, 228, 172, 32, 42, 3, 252, 227, 220, 130, 32, 42, 3, 252, 226, + 220, 129, 32, 42, 3, 252, 225, 220, 128, 32, 42, 3, 252, 224, 220, 127, + 32, 42, 3, 252, 223, 193, 224, 32, 42, 3, 252, 222, 192, 235, 32, 42, 3, + 252, 221, 192, 159, 32, 42, 3, 252, 220, 211, 110, 32, 42, 3, 252, 219, + 252, 69, 32, 42, 3, 252, 218, 249, 54, 32, 42, 3, 252, 217, 237, 193, 32, + 42, 3, 252, 216, 233, 183, 32, 42, 3, 252, 215, 223, 10, 32, 42, 3, 252, + 214, 32, 42, 3, 252, 213, 32, 42, 3, 252, 212, 32, 42, 3, 252, 211, 32, + 42, 3, 252, 210, 32, 42, 3, 252, 209, 32, 42, 3, 252, 208, 32, 42, 3, + 252, 207, 52, 1, 2, 6, 252, 206, 52, 1, 200, 182, 197, 238, 242, 83, 52, + 1, 200, 182, 132, 197, 238, 242, 83, 52, 1, 2, 252, 25, 52, 1, 2, 6, 250, + 120, 52, 1, 2, 78, 4, 102, 52, 1, 2, 235, 37, 237, 2, 52, 1, 2, 235, 37, + 237, 3, 4, 207, 24, 102, 52, 1, 2, 235, 37, 237, 3, 4, 238, 175, 52, 1, + 2, 237, 70, 237, 2, 52, 1, 2, 238, 128, 4, 199, 215, 52, 1, 2, 238, 128, + 4, 102, 52, 1, 2, 238, 128, 4, 228, 251, 23, 199, 215, 52, 1, 2, 207, 18, + 71, 52, 1, 2, 242, 219, 207, 18, 211, 77, 71, 52, 1, 2, 233, 37, 237, 2, + 52, 1, 2, 207, 140, 228, 187, 52, 1, 2, 6, 232, 51, 52, 1, 2, 232, 52, 4, + 102, 52, 1, 2, 6, 232, 52, 4, 102, 52, 1, 2, 230, 117, 4, 106, 52, 1, 2, + 6, 230, 116, 52, 1, 2, 229, 197, 4, 102, 52, 1, 2, 236, 139, 223, 36, 4, + 201, 28, 23, 102, 52, 1, 2, 218, 227, 237, 2, 52, 1, 2, 218, 170, 237, 2, + 52, 1, 2, 220, 143, 4, 248, 231, 52, 1, 2, 6, 220, 143, 4, 248, 231, 52, + 1, 2, 220, 143, 4, 207, 24, 228, 251, 23, 248, 231, 52, 1, 2, 219, 162, + 52, 1, 2, 219, 163, 4, 207, 24, 102, 52, 1, 2, 153, 192, 159, 52, 1, 2, + 153, 192, 160, 4, 248, 231, 52, 1, 2, 187, 4, 106, 52, 1, 2, 6, 211, 151, + 52, 1, 2, 242, 219, 211, 110, 52, 1, 2, 208, 104, 52, 1, 2, 153, 207, + 222, 4, 179, 219, 212, 52, 1, 2, 153, 207, 222, 4, 179, 219, 213, 23, + 207, 24, 102, 52, 1, 2, 207, 222, 4, 199, 215, 52, 1, 2, 207, 222, 4, + 232, 233, 52, 1, 2, 6, 146, 52, 1, 2, 199, 152, 237, 3, 4, 238, 175, 52, + 1, 2, 197, 170, 237, 2, 52, 1, 2, 197, 170, 237, 3, 4, 207, 24, 102, 52, + 1, 2, 199, 79, 237, 2, 52, 1, 2, 200, 44, 4, 207, 24, 102, 52, 1, 2, 196, + 13, 4, 50, 102, 52, 1, 2, 6, 192, 159, 52, 1, 231, 11, 201, 64, 4, 106, + 52, 1, 207, 18, 231, 11, 201, 64, 4, 106, 52, 1, 248, 172, 242, 231, 52, + 1, 237, 98, 242, 231, 52, 1, 220, 3, 242, 231, 52, 1, 251, 150, 242, 231, + 52, 1, 207, 24, 242, 232, 4, 207, 24, 102, 52, 1, 2, 206, 9, 4, 238, 175, + 238, 135, 5, 65, 238, 135, 5, 71, 238, 135, 5, 68, 238, 135, 5, 74, 238, + 135, 5, 66, 238, 135, 5, 223, 32, 238, 135, 5, 222, 201, 238, 135, 5, + 155, 238, 135, 5, 222, 22, 238, 135, 5, 221, 166, 238, 135, 5, 221, 67, + 238, 135, 5, 220, 232, 238, 135, 5, 173, 238, 135, 5, 219, 238, 238, 135, + 5, 219, 146, 238, 135, 5, 219, 43, 238, 135, 5, 218, 225, 238, 135, 5, + 174, 238, 135, 5, 216, 232, 238, 135, 5, 216, 100, 238, 135, 5, 216, 12, + 238, 135, 5, 215, 155, 238, 135, 5, 180, 238, 135, 5, 214, 121, 238, 135, + 5, 213, 219, 238, 135, 5, 213, 43, 238, 135, 5, 212, 178, 238, 135, 5, + 168, 238, 135, 5, 210, 63, 238, 135, 5, 209, 185, 238, 135, 5, 209, 73, + 238, 135, 5, 208, 165, 238, 135, 5, 165, 238, 135, 5, 207, 113, 238, 135, + 5, 207, 1, 238, 135, 5, 206, 162, 238, 135, 5, 206, 68, 238, 135, 5, 188, + 238, 135, 5, 205, 68, 238, 135, 5, 202, 222, 238, 135, 5, 202, 46, 238, + 135, 5, 201, 4, 238, 135, 5, 190, 190, 238, 135, 5, 199, 145, 238, 135, + 5, 198, 193, 238, 135, 5, 159, 238, 135, 5, 197, 94, 238, 135, 5, 193, + 190, 238, 135, 5, 193, 125, 238, 135, 5, 193, 86, 238, 135, 5, 193, 48, + 238, 135, 5, 192, 220, 238, 135, 5, 192, 214, 238, 135, 5, 191, 123, 238, + 135, 5, 191, 7, 223, 164, 251, 18, 1, 251, 190, 223, 164, 251, 18, 1, + 248, 211, 223, 164, 251, 18, 1, 231, 38, 223, 164, 251, 18, 1, 237, 252, + 223, 164, 251, 18, 1, 229, 245, 223, 164, 251, 18, 1, 193, 133, 223, 164, + 251, 18, 1, 191, 91, 223, 164, 251, 18, 1, 229, 184, 223, 164, 251, 18, + 1, 199, 69, 223, 164, 251, 18, 1, 191, 249, 223, 164, 251, 18, 1, 222, + 75, 223, 164, 251, 18, 1, 220, 26, 223, 164, 251, 18, 1, 216, 193, 223, + 164, 251, 18, 1, 212, 130, 223, 164, 251, 18, 1, 205, 148, 223, 164, 251, + 18, 1, 250, 126, 223, 164, 251, 18, 1, 210, 63, 223, 164, 251, 18, 1, + 205, 189, 223, 164, 251, 18, 1, 208, 37, 223, 164, 251, 18, 1, 207, 38, + 223, 164, 251, 18, 1, 203, 69, 223, 164, 251, 18, 1, 199, 159, 223, 164, + 251, 18, 205, 54, 56, 223, 164, 251, 18, 31, 107, 223, 164, 251, 18, 31, + 109, 223, 164, 251, 18, 31, 138, 223, 164, 251, 18, 31, 199, 95, 223, + 164, 251, 18, 31, 197, 32, 223, 164, 251, 18, 31, 91, 228, 140, 223, 164, + 251, 18, 31, 91, 189, 223, 164, 251, 18, 31, 199, 96, 189, 210, 180, 1, + 251, 190, 210, 180, 1, 248, 211, 210, 180, 1, 231, 38, 210, 180, 1, 237, + 252, 210, 180, 1, 229, 245, 210, 180, 1, 193, 133, 210, 180, 1, 191, 91, + 210, 180, 1, 229, 184, 210, 180, 1, 199, 69, 210, 180, 1, 191, 249, 210, + 180, 1, 222, 75, 210, 180, 1, 220, 26, 210, 180, 1, 216, 193, 210, 180, + 1, 53, 212, 130, 210, 180, 1, 212, 130, 210, 180, 1, 205, 148, 210, 180, + 1, 250, 126, 210, 180, 1, 210, 63, 210, 180, 1, 205, 189, 210, 180, 1, + 208, 37, 210, 180, 1, 207, 38, 210, 180, 1, 203, 69, 210, 180, 1, 199, + 159, 210, 180, 219, 219, 232, 201, 210, 180, 206, 203, 232, 201, 210, + 180, 31, 107, 210, 180, 31, 109, 210, 180, 31, 138, 210, 180, 31, 134, + 210, 180, 31, 149, 210, 180, 31, 199, 95, 210, 180, 31, 197, 32, 214, + 246, 1, 53, 251, 190, 214, 246, 1, 251, 190, 214, 246, 1, 53, 248, 211, + 214, 246, 1, 248, 211, 214, 246, 1, 231, 38, 214, 246, 1, 237, 252, 214, + 246, 1, 53, 229, 245, 214, 246, 1, 229, 245, 214, 246, 1, 193, 133, 214, + 246, 1, 191, 91, 214, 246, 1, 229, 184, 214, 246, 1, 199, 69, 214, 246, + 1, 53, 191, 249, 214, 246, 1, 191, 249, 214, 246, 1, 53, 222, 75, 214, + 246, 1, 222, 75, 214, 246, 1, 53, 220, 26, 214, 246, 1, 220, 26, 214, + 246, 1, 53, 216, 193, 214, 246, 1, 216, 193, 214, 246, 1, 53, 212, 130, + 214, 246, 1, 212, 130, 214, 246, 1, 205, 148, 214, 246, 1, 250, 126, 214, + 246, 1, 210, 63, 214, 246, 1, 205, 189, 214, 246, 1, 208, 37, 214, 246, + 1, 207, 38, 214, 246, 1, 53, 203, 69, 214, 246, 1, 203, 69, 214, 246, 1, + 199, 159, 214, 246, 31, 107, 214, 246, 31, 109, 214, 246, 31, 138, 214, + 246, 31, 134, 214, 246, 238, 202, 31, 134, 214, 246, 31, 149, 214, 246, + 31, 199, 95, 214, 246, 31, 197, 32, 214, 246, 31, 91, 228, 140, 230, 4, + 1, 251, 190, 230, 4, 1, 248, 211, 230, 4, 1, 231, 38, 230, 4, 1, 237, + 251, 230, 4, 1, 229, 245, 230, 4, 1, 193, 133, 230, 4, 1, 191, 89, 230, + 4, 1, 229, 184, 230, 4, 1, 199, 69, 230, 4, 1, 191, 249, 230, 4, 1, 222, + 75, 230, 4, 1, 220, 26, 230, 4, 1, 216, 193, 230, 4, 1, 212, 130, 230, 4, + 1, 205, 148, 230, 4, 1, 250, 124, 230, 4, 1, 210, 63, 230, 4, 1, 205, + 189, 230, 4, 1, 208, 37, 230, 4, 1, 203, 69, 230, 4, 1, 199, 159, 230, 4, + 31, 107, 230, 4, 31, 149, 230, 4, 31, 199, 95, 230, 4, 31, 197, 32, 230, + 4, 31, 91, 228, 140, 209, 197, 1, 251, 187, 209, 197, 1, 248, 214, 209, + 197, 1, 231, 213, 209, 197, 1, 237, 108, 209, 197, 1, 229, 245, 209, 197, + 1, 193, 140, 209, 197, 1, 191, 115, 209, 197, 1, 229, 186, 209, 197, 1, + 199, 73, 209, 197, 1, 191, 250, 209, 197, 1, 222, 106, 209, 197, 1, 220, + 32, 209, 197, 1, 216, 193, 209, 197, 1, 212, 130, 209, 197, 1, 204, 19, + 209, 197, 1, 251, 230, 209, 197, 1, 210, 63, 209, 197, 1, 205, 191, 209, + 197, 1, 208, 42, 209, 197, 1, 206, 124, 209, 197, 1, 203, 69, 209, 197, + 1, 199, 166, 209, 197, 31, 107, 209, 197, 31, 199, 95, 209, 197, 31, 197, + 32, 209, 197, 31, 91, 228, 140, 209, 197, 31, 109, 209, 197, 31, 138, + 209, 197, 193, 23, 204, 10, 218, 180, 1, 65, 218, 180, 1, 250, 120, 218, + 180, 1, 232, 51, 218, 180, 1, 238, 127, 218, 180, 1, 71, 218, 180, 1, + 196, 12, 218, 180, 1, 68, 218, 180, 1, 192, 159, 218, 180, 1, 222, 152, + 218, 180, 1, 172, 218, 180, 1, 218, 168, 218, 180, 1, 215, 61, 218, 180, + 1, 74, 218, 180, 1, 146, 218, 180, 1, 201, 178, 218, 180, 1, 200, 43, + 218, 180, 1, 66, 218, 180, 1, 233, 175, 218, 180, 1, 208, 104, 218, 180, + 1, 206, 8, 218, 180, 1, 197, 135, 218, 180, 1, 251, 132, 218, 180, 1, + 234, 103, 218, 180, 1, 218, 183, 218, 180, 1, 213, 80, 218, 180, 1, 247, + 193, 218, 180, 197, 238, 77, 152, 229, 144, 1, 65, 152, 229, 144, 1, 71, + 152, 229, 144, 1, 68, 152, 229, 144, 1, 74, 152, 229, 144, 1, 170, 152, + 229, 144, 1, 193, 190, 152, 229, 144, 1, 249, 153, 152, 229, 144, 1, 249, + 152, 152, 229, 144, 1, 168, 152, 229, 144, 1, 174, 152, 229, 144, 1, 180, + 152, 229, 144, 1, 215, 5, 152, 229, 144, 1, 214, 121, 152, 229, 144, 1, + 214, 119, 152, 229, 144, 1, 165, 152, 229, 144, 1, 207, 184, 152, 229, + 144, 1, 173, 152, 229, 144, 1, 221, 215, 152, 229, 144, 1, 229, 177, 152, + 229, 144, 1, 188, 152, 229, 144, 1, 205, 205, 152, 229, 144, 1, 205, 68, + 152, 229, 144, 1, 155, 152, 229, 144, 1, 208, 96, 152, 229, 144, 1, 190, + 190, 152, 229, 144, 1, 199, 250, 152, 229, 144, 1, 199, 145, 152, 229, + 144, 1, 199, 143, 152, 229, 144, 1, 159, 152, 229, 144, 1, 238, 32, 152, + 229, 144, 16, 195, 63, 152, 229, 144, 16, 195, 62, 152, 238, 166, 1, 65, + 152, 238, 166, 1, 71, 152, 238, 166, 1, 68, 152, 238, 166, 1, 74, 152, + 238, 166, 1, 170, 152, 238, 166, 1, 193, 190, 152, 238, 166, 1, 249, 153, + 152, 238, 166, 1, 168, 152, 238, 166, 1, 174, 152, 238, 166, 1, 180, 152, + 238, 166, 1, 214, 121, 152, 238, 166, 1, 165, 152, 238, 166, 1, 173, 152, + 238, 166, 1, 221, 215, 152, 238, 166, 1, 229, 177, 152, 238, 166, 1, 188, + 152, 238, 166, 1, 251, 14, 188, 152, 238, 166, 1, 205, 68, 152, 238, 166, + 1, 155, 152, 238, 166, 1, 208, 96, 152, 238, 166, 1, 190, 190, 152, 238, + 166, 1, 199, 145, 152, 238, 166, 1, 159, 152, 238, 166, 1, 238, 32, 152, + 238, 166, 232, 118, 234, 128, 197, 39, 152, 238, 166, 232, 118, 91, 230, + 70, 152, 238, 166, 219, 28, 206, 168, 152, 238, 166, 219, 28, 223, 169, + 152, 238, 166, 31, 107, 152, 238, 166, 31, 109, 152, 238, 166, 31, 138, + 152, 238, 166, 31, 134, 152, 238, 166, 31, 149, 152, 238, 166, 31, 169, + 152, 238, 166, 31, 175, 152, 238, 166, 31, 171, 152, 238, 166, 31, 178, + 152, 238, 166, 31, 199, 95, 152, 238, 166, 31, 197, 32, 152, 238, 166, + 31, 198, 249, 152, 238, 166, 31, 232, 135, 152, 238, 166, 31, 233, 15, + 152, 238, 166, 31, 202, 120, 152, 238, 166, 31, 203, 241, 152, 238, 166, + 31, 91, 228, 140, 152, 238, 166, 31, 105, 228, 140, 152, 238, 166, 31, + 115, 228, 140, 152, 238, 166, 31, 232, 128, 228, 140, 152, 238, 166, 31, + 232, 226, 228, 140, 152, 238, 166, 31, 202, 136, 228, 140, 152, 238, 166, + 31, 203, 247, 228, 140, 152, 238, 166, 31, 234, 164, 228, 140, 152, 238, + 166, 31, 213, 175, 228, 140, 152, 238, 166, 31, 91, 189, 152, 238, 166, + 31, 105, 189, 152, 238, 166, 31, 115, 189, 152, 238, 166, 31, 232, 128, + 189, 152, 238, 166, 31, 232, 226, 189, 152, 238, 166, 31, 202, 136, 189, + 152, 238, 166, 31, 203, 247, 189, 152, 238, 166, 31, 234, 164, 189, 152, + 238, 166, 31, 213, 175, 189, 152, 238, 166, 31, 199, 96, 189, 152, 238, + 166, 31, 197, 33, 189, 152, 238, 166, 31, 198, 250, 189, 152, 238, 166, + 31, 232, 136, 189, 152, 238, 166, 31, 233, 16, 189, 152, 238, 166, 31, + 202, 121, 189, 152, 238, 166, 31, 203, 242, 189, 152, 238, 166, 31, 234, + 154, 189, 152, 238, 166, 31, 213, 170, 189, 152, 238, 166, 31, 91, 228, + 141, 189, 152, 238, 166, 31, 105, 228, 141, 189, 152, 238, 166, 31, 115, + 228, 141, 189, 152, 238, 166, 31, 232, 128, 228, 141, 189, 152, 238, 166, + 31, 232, 226, 228, 141, 189, 152, 238, 166, 31, 202, 136, 228, 141, 189, + 152, 238, 166, 31, 203, 247, 228, 141, 189, 152, 238, 166, 31, 234, 164, + 228, 141, 189, 152, 238, 166, 31, 213, 175, 228, 141, 189, 152, 238, 166, + 232, 118, 91, 197, 40, 152, 238, 166, 232, 118, 105, 197, 39, 152, 238, + 166, 232, 118, 115, 197, 39, 152, 238, 166, 232, 118, 232, 128, 197, 39, + 152, 238, 166, 232, 118, 232, 226, 197, 39, 152, 238, 166, 232, 118, 202, + 136, 197, 39, 152, 238, 166, 232, 118, 203, 247, 197, 39, 152, 238, 166, + 232, 118, 234, 164, 197, 39, 152, 238, 166, 232, 118, 213, 175, 197, 39, + 152, 238, 166, 232, 118, 199, 96, 197, 39, 221, 199, 1, 65, 221, 199, 18, + 3, 68, 221, 199, 18, 3, 66, 221, 199, 18, 3, 117, 146, 221, 199, 18, 3, + 71, 221, 199, 18, 3, 74, 221, 199, 18, 219, 198, 77, 221, 199, 3, 55, + 206, 189, 60, 221, 199, 3, 251, 71, 221, 199, 3, 195, 35, 221, 199, 1, + 155, 221, 199, 1, 221, 215, 221, 199, 1, 231, 240, 221, 199, 1, 231, 91, + 221, 199, 1, 247, 160, 221, 199, 1, 247, 1, 221, 199, 1, 223, 32, 221, + 199, 1, 212, 101, 221, 199, 1, 197, 132, 221, 199, 1, 197, 120, 221, 199, + 1, 237, 191, 221, 199, 1, 237, 175, 221, 199, 1, 213, 79, 221, 199, 1, + 190, 190, 221, 199, 1, 199, 49, 221, 199, 1, 238, 32, 221, 199, 1, 237, + 68, 221, 199, 1, 180, 221, 199, 1, 168, 221, 199, 1, 209, 228, 221, 199, + 1, 249, 153, 221, 199, 1, 248, 203, 221, 199, 1, 174, 221, 199, 1, 170, + 221, 199, 1, 165, 221, 199, 1, 173, 221, 199, 1, 195, 188, 221, 199, 1, + 203, 165, 221, 199, 1, 201, 175, 221, 199, 1, 188, 221, 199, 1, 191, 123, + 221, 199, 1, 140, 221, 199, 1, 221, 101, 221, 199, 1, 197, 100, 221, 199, + 1, 197, 101, 221, 199, 1, 195, 70, 221, 199, 3, 249, 88, 58, 221, 199, 3, + 247, 74, 221, 199, 3, 75, 60, 221, 199, 195, 40, 221, 199, 17, 107, 221, + 199, 17, 109, 221, 199, 17, 138, 221, 199, 17, 134, 221, 199, 31, 199, + 95, 221, 199, 31, 197, 32, 221, 199, 31, 91, 228, 140, 221, 199, 31, 91, + 189, 221, 199, 232, 118, 91, 230, 70, 221, 199, 208, 152, 236, 140, 221, + 199, 208, 152, 2, 243, 10, 221, 199, 208, 152, 243, 10, 221, 199, 208, + 152, 238, 228, 164, 221, 199, 208, 152, 217, 83, 221, 199, 208, 152, 218, + 246, 221, 199, 208, 152, 237, 238, 221, 199, 208, 152, 55, 237, 238, 221, + 199, 208, 152, 219, 106, 39, 202, 2, 251, 29, 1, 229, 245, 39, 202, 2, + 251, 29, 1, 220, 26, 39, 202, 2, 251, 29, 1, 229, 184, 39, 202, 2, 251, + 29, 1, 216, 193, 39, 202, 2, 251, 29, 1, 208, 37, 39, 202, 2, 251, 29, 1, + 193, 133, 39, 202, 2, 251, 29, 1, 203, 69, 39, 202, 2, 251, 29, 1, 207, + 38, 39, 202, 2, 251, 29, 1, 248, 211, 39, 202, 2, 251, 29, 1, 199, 159, + 39, 202, 2, 251, 29, 1, 205, 122, 39, 202, 2, 251, 29, 1, 222, 75, 39, + 202, 2, 251, 29, 1, 212, 130, 39, 202, 2, 251, 29, 1, 221, 194, 39, 202, + 2, 251, 29, 1, 205, 189, 39, 202, 2, 251, 29, 1, 205, 148, 39, 202, 2, + 251, 29, 1, 233, 59, 39, 202, 2, 251, 29, 1, 251, 192, 39, 202, 2, 251, + 29, 1, 250, 124, 39, 202, 2, 251, 29, 1, 237, 65, 39, 202, 2, 251, 29, 1, + 231, 38, 39, 202, 2, 251, 29, 1, 237, 252, 39, 202, 2, 251, 29, 1, 231, + 79, 39, 202, 2, 251, 29, 1, 199, 69, 39, 202, 2, 251, 29, 1, 191, 89, 39, + 202, 2, 251, 29, 1, 237, 62, 39, 202, 2, 251, 29, 1, 191, 249, 39, 202, + 2, 251, 29, 1, 199, 35, 39, 202, 2, 251, 29, 1, 199, 14, 39, 202, 2, 251, + 29, 31, 107, 39, 202, 2, 251, 29, 31, 233, 15, 39, 202, 2, 251, 29, 167, + 223, 144, 39, 186, 251, 29, 1, 229, 210, 39, 186, 251, 29, 1, 220, 35, + 39, 186, 251, 29, 1, 230, 81, 39, 186, 251, 29, 1, 216, 208, 39, 186, + 251, 29, 1, 208, 89, 39, 186, 251, 29, 1, 193, 133, 39, 186, 251, 29, 1, + 234, 20, 39, 186, 251, 29, 1, 207, 71, 39, 186, 251, 29, 1, 248, 245, 39, + 186, 251, 29, 1, 199, 114, 39, 186, 251, 29, 1, 234, 21, 39, 186, 251, + 29, 1, 222, 106, 39, 186, 251, 29, 1, 213, 24, 39, 186, 251, 29, 1, 221, + 210, 39, 186, 251, 29, 1, 205, 192, 39, 186, 251, 29, 1, 234, 19, 39, + 186, 251, 29, 1, 233, 46, 39, 186, 251, 29, 1, 251, 192, 39, 186, 251, + 29, 1, 251, 230, 39, 186, 251, 29, 1, 238, 26, 39, 186, 251, 29, 1, 231, + 156, 39, 186, 251, 29, 1, 238, 3, 39, 186, 251, 29, 1, 231, 86, 39, 186, + 251, 29, 1, 199, 219, 39, 186, 251, 29, 1, 191, 113, 39, 186, 251, 29, 1, + 199, 41, 39, 186, 251, 29, 1, 192, 75, 39, 186, 251, 29, 1, 199, 29, 39, + 186, 251, 29, 1, 191, 116, 39, 186, 251, 29, 31, 107, 39, 186, 251, 29, + 31, 199, 95, 39, 186, 251, 29, 31, 197, 32, 217, 81, 1, 251, 190, 217, + 81, 1, 248, 211, 217, 81, 1, 248, 194, 217, 81, 1, 231, 38, 217, 81, 1, + 231, 64, 217, 81, 1, 237, 252, 217, 81, 1, 229, 245, 217, 81, 1, 193, + 133, 217, 81, 3, 196, 158, 217, 81, 1, 191, 91, 217, 81, 1, 191, 64, 217, + 81, 1, 223, 12, 217, 81, 1, 222, 248, 217, 81, 1, 229, 184, 217, 81, 1, + 199, 69, 217, 81, 1, 191, 249, 217, 81, 1, 222, 75, 217, 81, 1, 192, 217, + 217, 81, 1, 221, 201, 217, 81, 1, 220, 26, 217, 81, 1, 237, 61, 217, 81, + 1, 199, 40, 217, 81, 1, 216, 193, 217, 81, 1, 212, 130, 217, 81, 1, 205, + 148, 217, 81, 1, 250, 126, 217, 81, 1, 252, 158, 217, 81, 1, 210, 63, + 217, 81, 1, 233, 59, 217, 81, 1, 205, 189, 217, 81, 1, 208, 37, 217, 81, + 1, 192, 193, 217, 81, 1, 208, 64, 217, 81, 1, 207, 38, 217, 81, 1, 203, + 69, 217, 81, 1, 201, 143, 217, 81, 1, 199, 159, 217, 81, 252, 68, 87, 58, + 217, 81, 252, 68, 87, 60, 217, 81, 31, 107, 217, 81, 31, 149, 217, 81, + 31, 199, 95, 217, 81, 31, 197, 32, 217, 81, 31, 91, 228, 140, 217, 81, + 208, 152, 201, 102, 217, 81, 208, 152, 232, 201, 217, 81, 208, 152, 55, + 75, 193, 53, 236, 140, 217, 81, 208, 152, 75, 193, 53, 236, 140, 217, 81, + 208, 152, 236, 140, 217, 81, 208, 152, 105, 236, 138, 217, 81, 208, 152, + 219, 113, 233, 3, 250, 142, 1, 65, 250, 142, 1, 252, 206, 250, 142, 1, + 251, 68, 250, 142, 1, 252, 164, 250, 142, 1, 251, 132, 250, 142, 1, 252, + 166, 250, 142, 1, 252, 25, 250, 142, 1, 252, 21, 250, 142, 1, 71, 250, + 142, 1, 234, 188, 250, 142, 1, 74, 250, 142, 1, 211, 87, 250, 142, 1, 68, + 250, 142, 1, 223, 199, 250, 142, 1, 66, 250, 142, 1, 196, 30, 250, 142, + 1, 222, 22, 250, 142, 1, 192, 214, 250, 142, 1, 192, 173, 250, 142, 1, + 192, 184, 250, 142, 1, 231, 165, 250, 142, 1, 231, 122, 250, 142, 1, 231, + 77, 250, 142, 1, 247, 42, 250, 142, 1, 223, 10, 250, 142, 1, 199, 145, + 250, 142, 1, 199, 33, 250, 142, 1, 237, 146, 250, 142, 1, 237, 59, 250, + 142, 1, 197, 127, 250, 142, 1, 210, 63, 250, 142, 1, 233, 59, 250, 142, + 1, 249, 17, 250, 142, 1, 248, 196, 250, 142, 1, 214, 55, 250, 142, 1, + 213, 226, 250, 142, 1, 213, 227, 250, 142, 1, 214, 121, 250, 142, 1, 212, + 90, 250, 142, 1, 213, 74, 250, 142, 1, 216, 232, 250, 142, 1, 229, 73, + 250, 142, 1, 191, 173, 250, 142, 1, 192, 80, 250, 142, 1, 195, 153, 250, + 142, 1, 207, 113, 250, 142, 1, 219, 238, 250, 142, 1, 205, 68, 250, 142, + 1, 191, 87, 250, 142, 1, 203, 113, 250, 142, 1, 191, 62, 250, 142, 1, + 202, 229, 250, 142, 1, 201, 144, 250, 142, 1, 229, 245, 250, 142, 252, + 68, 77, 198, 138, 105, 185, 139, 91, 75, 208, 151, 2, 105, 185, 139, 91, + 75, 208, 151, 220, 13, 105, 185, 139, 91, 75, 208, 151, 220, 13, 91, 75, + 139, 105, 185, 208, 151, 220, 13, 105, 206, 185, 139, 91, 206, 189, 208, + 151, 220, 13, 91, 206, 189, 139, 105, 206, 185, 208, 151, 223, 122, 210, + 106, 1, 251, 190, 223, 122, 210, 106, 1, 248, 211, 223, 122, 210, 106, 1, + 231, 38, 223, 122, 210, 106, 1, 237, 252, 223, 122, 210, 106, 1, 229, + 245, 223, 122, 210, 106, 1, 193, 133, 223, 122, 210, 106, 1, 191, 91, + 223, 122, 210, 106, 1, 229, 184, 223, 122, 210, 106, 1, 199, 69, 223, + 122, 210, 106, 1, 191, 249, 223, 122, 210, 106, 1, 222, 75, 223, 122, + 210, 106, 1, 220, 26, 223, 122, 210, 106, 1, 216, 193, 223, 122, 210, + 106, 1, 212, 130, 223, 122, 210, 106, 1, 205, 148, 223, 122, 210, 106, 1, + 250, 126, 223, 122, 210, 106, 1, 210, 63, 223, 122, 210, 106, 1, 205, + 189, 223, 122, 210, 106, 1, 208, 37, 223, 122, 210, 106, 1, 207, 38, 223, + 122, 210, 106, 1, 203, 69, 223, 122, 210, 106, 1, 199, 159, 223, 122, + 210, 106, 31, 107, 223, 122, 210, 106, 31, 109, 223, 122, 210, 106, 31, + 138, 223, 122, 210, 106, 31, 134, 223, 122, 210, 106, 31, 199, 95, 223, + 122, 210, 106, 31, 197, 32, 223, 122, 210, 106, 31, 91, 228, 140, 223, + 122, 210, 106, 31, 91, 189, 223, 122, 210, 199, 1, 251, 190, 223, 122, + 210, 199, 1, 248, 211, 223, 122, 210, 199, 1, 231, 38, 223, 122, 210, + 199, 1, 237, 252, 223, 122, 210, 199, 1, 229, 245, 223, 122, 210, 199, 1, + 193, 132, 223, 122, 210, 199, 1, 191, 91, 223, 122, 210, 199, 1, 229, + 184, 223, 122, 210, 199, 1, 199, 69, 223, 122, 210, 199, 1, 191, 249, + 223, 122, 210, 199, 1, 222, 75, 223, 122, 210, 199, 1, 220, 26, 223, 122, + 210, 199, 1, 216, 192, 223, 122, 210, 199, 1, 212, 130, 223, 122, 210, + 199, 1, 205, 148, 223, 122, 210, 199, 1, 210, 63, 223, 122, 210, 199, 1, + 205, 189, 223, 122, 210, 199, 1, 203, 69, 223, 122, 210, 199, 1, 199, + 159, 223, 122, 210, 199, 31, 107, 223, 122, 210, 199, 31, 109, 223, 122, + 210, 199, 31, 138, 223, 122, 210, 199, 31, 134, 223, 122, 210, 199, 31, + 199, 95, 223, 122, 210, 199, 31, 197, 32, 223, 122, 210, 199, 31, 91, + 228, 140, 223, 122, 210, 199, 31, 91, 189, 208, 177, 210, 199, 1, 251, + 190, 208, 177, 210, 199, 1, 248, 211, 208, 177, 210, 199, 1, 231, 38, + 208, 177, 210, 199, 1, 237, 252, 208, 177, 210, 199, 1, 229, 245, 208, + 177, 210, 199, 1, 193, 132, 208, 177, 210, 199, 1, 191, 91, 208, 177, + 210, 199, 1, 229, 184, 208, 177, 210, 199, 1, 191, 249, 208, 177, 210, + 199, 1, 222, 75, 208, 177, 210, 199, 1, 220, 26, 208, 177, 210, 199, 1, + 216, 192, 208, 177, 210, 199, 1, 212, 130, 208, 177, 210, 199, 1, 205, + 148, 208, 177, 210, 199, 1, 210, 63, 208, 177, 210, 199, 1, 205, 189, + 208, 177, 210, 199, 1, 203, 69, 208, 177, 210, 199, 1, 199, 159, 208, + 177, 210, 199, 205, 54, 77, 208, 177, 210, 199, 153, 205, 54, 77, 208, + 177, 210, 199, 232, 128, 185, 4, 238, 217, 208, 177, 210, 199, 232, 128, + 185, 4, 236, 140, 208, 177, 210, 199, 31, 107, 208, 177, 210, 199, 31, + 109, 208, 177, 210, 199, 31, 138, 208, 177, 210, 199, 31, 134, 208, 177, + 210, 199, 31, 199, 95, 208, 177, 210, 199, 31, 197, 32, 208, 177, 210, + 199, 31, 91, 228, 140, 39, 197, 61, 1, 211, 44, 65, 39, 197, 61, 1, 192, + 68, 65, 39, 197, 61, 1, 192, 68, 252, 25, 39, 197, 61, 1, 211, 44, 68, + 39, 197, 61, 1, 192, 68, 68, 39, 197, 61, 1, 192, 68, 71, 39, 197, 61, 1, + 211, 44, 74, 39, 197, 61, 1, 211, 44, 211, 151, 39, 197, 61, 1, 192, 68, + 211, 151, 39, 197, 61, 1, 211, 44, 252, 155, 39, 197, 61, 1, 192, 68, + 252, 155, 39, 197, 61, 1, 211, 44, 252, 24, 39, 197, 61, 1, 192, 68, 252, + 24, 39, 197, 61, 1, 211, 44, 251, 253, 39, 197, 61, 1, 192, 68, 251, 253, + 39, 197, 61, 1, 211, 44, 252, 19, 39, 197, 61, 1, 192, 68, 252, 19, 39, + 197, 61, 1, 211, 44, 252, 42, 39, 197, 61, 1, 192, 68, 252, 42, 39, 197, + 61, 1, 211, 44, 252, 23, 39, 197, 61, 1, 211, 44, 233, 182, 39, 197, 61, + 1, 192, 68, 233, 182, 39, 197, 61, 1, 211, 44, 250, 131, 39, 197, 61, 1, + 192, 68, 250, 131, 39, 197, 61, 1, 211, 44, 252, 6, 39, 197, 61, 1, 192, + 68, 252, 6, 39, 197, 61, 1, 211, 44, 252, 17, 39, 197, 61, 1, 192, 68, + 252, 17, 39, 197, 61, 1, 211, 44, 211, 149, 39, 197, 61, 1, 192, 68, 211, + 149, 39, 197, 61, 1, 211, 44, 251, 207, 39, 197, 61, 1, 192, 68, 251, + 207, 39, 197, 61, 1, 211, 44, 252, 16, 39, 197, 61, 1, 211, 44, 234, 118, + 39, 197, 61, 1, 211, 44, 234, 114, 39, 197, 61, 1, 211, 44, 251, 132, 39, + 197, 61, 1, 211, 44, 252, 14, 39, 197, 61, 1, 192, 68, 252, 14, 39, 197, + 61, 1, 211, 44, 234, 80, 39, 197, 61, 1, 192, 68, 234, 80, 39, 197, 61, + 1, 211, 44, 234, 100, 39, 197, 61, 1, 192, 68, 234, 100, 39, 197, 61, 1, + 211, 44, 234, 66, 39, 197, 61, 1, 192, 68, 234, 66, 39, 197, 61, 1, 192, + 68, 251, 122, 39, 197, 61, 1, 211, 44, 234, 88, 39, 197, 61, 1, 192, 68, + 252, 13, 39, 197, 61, 1, 211, 44, 234, 56, 39, 197, 61, 1, 211, 44, 211, + 78, 39, 197, 61, 1, 211, 44, 228, 28, 39, 197, 61, 1, 211, 44, 234, 197, + 39, 197, 61, 1, 192, 68, 234, 197, 39, 197, 61, 1, 211, 44, 251, 37, 39, + 197, 61, 1, 192, 68, 251, 37, 39, 197, 61, 1, 211, 44, 223, 79, 39, 197, + 61, 1, 192, 68, 223, 79, 39, 197, 61, 1, 211, 44, 211, 58, 39, 197, 61, + 1, 192, 68, 211, 58, 39, 197, 61, 1, 211, 44, 251, 33, 39, 197, 61, 1, + 192, 68, 251, 33, 39, 197, 61, 1, 211, 44, 252, 12, 39, 197, 61, 1, 211, + 44, 250, 219, 39, 197, 61, 1, 211, 44, 252, 10, 39, 197, 61, 1, 211, 44, + 250, 209, 39, 197, 61, 1, 192, 68, 250, 209, 39, 197, 61, 1, 211, 44, + 234, 12, 39, 197, 61, 1, 192, 68, 234, 12, 39, 197, 61, 1, 211, 44, 250, + 182, 39, 197, 61, 1, 192, 68, 250, 182, 39, 197, 61, 1, 211, 44, 252, 7, + 39, 197, 61, 1, 192, 68, 252, 7, 39, 197, 61, 1, 211, 44, 211, 30, 39, + 197, 61, 1, 211, 44, 249, 71, 39, 177, 6, 1, 65, 39, 177, 6, 1, 252, 206, + 39, 177, 6, 1, 234, 199, 39, 177, 6, 1, 251, 144, 39, 177, 6, 1, 234, + 197, 39, 177, 6, 1, 234, 100, 39, 177, 6, 1, 234, 193, 39, 177, 6, 1, + 234, 192, 39, 177, 6, 1, 251, 125, 39, 177, 6, 1, 71, 39, 177, 6, 1, 242, + 220, 71, 39, 177, 6, 1, 234, 188, 39, 177, 6, 1, 234, 181, 39, 177, 6, 1, + 234, 180, 39, 177, 6, 1, 234, 176, 39, 177, 6, 1, 234, 173, 39, 177, 6, + 1, 68, 39, 177, 6, 1, 223, 199, 39, 177, 6, 1, 234, 150, 39, 177, 6, 1, + 234, 147, 39, 177, 6, 1, 251, 216, 39, 177, 6, 1, 196, 86, 39, 177, 6, 1, + 234, 140, 39, 177, 6, 1, 234, 117, 39, 177, 6, 1, 234, 114, 39, 177, 6, + 1, 234, 103, 39, 177, 6, 1, 234, 66, 39, 177, 6, 1, 74, 39, 177, 6, 1, + 211, 87, 39, 177, 6, 1, 213, 182, 211, 151, 39, 177, 6, 1, 206, 58, 211, + 151, 39, 177, 6, 1, 211, 150, 39, 177, 6, 1, 234, 56, 39, 177, 6, 1, 234, + 108, 39, 177, 6, 1, 234, 34, 39, 177, 6, 1, 203, 40, 234, 34, 39, 177, 6, + 1, 234, 22, 39, 177, 6, 1, 234, 1, 39, 177, 6, 1, 233, 255, 39, 177, 6, + 1, 234, 80, 39, 177, 6, 1, 233, 243, 39, 177, 6, 1, 234, 195, 39, 177, 6, + 1, 66, 39, 177, 6, 1, 196, 30, 39, 177, 6, 1, 213, 182, 196, 152, 39, + 177, 6, 1, 206, 58, 196, 152, 39, 177, 6, 1, 233, 230, 39, 177, 6, 1, + 233, 182, 39, 177, 6, 1, 233, 177, 39, 177, 6, 1, 234, 79, 56, 39, 177, + 6, 1, 196, 45, 39, 177, 2, 1, 65, 39, 177, 2, 1, 252, 206, 39, 177, 2, 1, + 234, 199, 39, 177, 2, 1, 251, 144, 39, 177, 2, 1, 234, 197, 39, 177, 2, + 1, 234, 100, 39, 177, 2, 1, 234, 193, 39, 177, 2, 1, 234, 192, 39, 177, + 2, 1, 251, 125, 39, 177, 2, 1, 71, 39, 177, 2, 1, 242, 220, 71, 39, 177, + 2, 1, 234, 188, 39, 177, 2, 1, 234, 181, 39, 177, 2, 1, 234, 180, 39, + 177, 2, 1, 234, 176, 39, 177, 2, 1, 234, 173, 39, 177, 2, 1, 68, 39, 177, + 2, 1, 223, 199, 39, 177, 2, 1, 234, 150, 39, 177, 2, 1, 234, 147, 39, + 177, 2, 1, 251, 216, 39, 177, 2, 1, 196, 86, 39, 177, 2, 1, 234, 140, 39, + 177, 2, 1, 234, 117, 39, 177, 2, 1, 234, 114, 39, 177, 2, 1, 234, 103, + 39, 177, 2, 1, 234, 66, 39, 177, 2, 1, 74, 39, 177, 2, 1, 211, 87, 39, + 177, 2, 1, 213, 182, 211, 151, 39, 177, 2, 1, 206, 58, 211, 151, 39, 177, + 2, 1, 211, 150, 39, 177, 2, 1, 234, 56, 39, 177, 2, 1, 234, 108, 39, 177, + 2, 1, 234, 34, 39, 177, 2, 1, 203, 40, 234, 34, 39, 177, 2, 1, 234, 22, + 39, 177, 2, 1, 234, 1, 39, 177, 2, 1, 233, 255, 39, 177, 2, 1, 234, 80, + 39, 177, 2, 1, 233, 243, 39, 177, 2, 1, 234, 195, 39, 177, 2, 1, 66, 39, + 177, 2, 1, 196, 30, 39, 177, 2, 1, 213, 182, 196, 152, 39, 177, 2, 1, + 206, 58, 196, 152, 39, 177, 2, 1, 233, 230, 39, 177, 2, 1, 233, 182, 39, + 177, 2, 1, 233, 177, 39, 177, 2, 1, 234, 79, 56, 39, 177, 2, 1, 196, 45, + 39, 177, 31, 107, 39, 177, 31, 149, 39, 177, 31, 199, 95, 39, 177, 31, + 233, 15, 39, 177, 31, 91, 228, 140, 39, 177, 31, 91, 189, 230, 24, 206, + 142, 1, 65, 230, 24, 206, 142, 1, 249, 153, 230, 24, 206, 142, 1, 168, + 230, 24, 206, 142, 1, 190, 190, 230, 24, 206, 142, 1, 197, 132, 230, 24, + 206, 142, 1, 223, 32, 230, 24, 206, 142, 1, 247, 160, 230, 24, 206, 142, + 1, 140, 230, 24, 206, 142, 1, 221, 215, 230, 24, 206, 142, 1, 233, 109, + 230, 24, 206, 142, 1, 238, 32, 230, 24, 206, 142, 1, 237, 191, 230, 24, + 206, 142, 1, 165, 230, 24, 206, 142, 1, 206, 109, 230, 24, 206, 142, 1, + 191, 123, 230, 24, 206, 142, 1, 188, 230, 24, 206, 142, 1, 203, 165, 230, + 24, 206, 142, 1, 155, 230, 24, 206, 142, 1, 231, 240, 230, 24, 206, 142, + 1, 173, 230, 24, 206, 142, 1, 174, 230, 24, 206, 142, 1, 180, 230, 24, + 206, 142, 1, 193, 190, 230, 24, 206, 142, 1, 221, 137, 193, 190, 230, 24, + 206, 142, 1, 170, 230, 24, 206, 142, 1, 221, 137, 170, 230, 24, 206, 142, + 1, 214, 68, 230, 24, 206, 142, 1, 212, 101, 230, 24, 206, 142, 1, 195, + 188, 230, 24, 206, 142, 18, 65, 230, 24, 206, 142, 18, 68, 230, 24, 206, + 142, 18, 66, 230, 24, 206, 142, 18, 71, 230, 24, 206, 142, 18, 74, 230, + 24, 206, 142, 87, 205, 173, 230, 24, 206, 142, 87, 215, 7, 221, 178, 230, + 24, 206, 142, 3, 230, 18, 230, 24, 206, 142, 3, 199, 218, 230, 24, 206, + 142, 3, 199, 192, 230, 24, 206, 142, 3, 199, 172, 230, 24, 206, 142, 17, + 191, 77, 230, 24, 206, 142, 17, 107, 230, 24, 206, 142, 17, 109, 230, 24, + 206, 142, 17, 138, 230, 24, 206, 142, 17, 134, 230, 24, 206, 142, 17, + 149, 230, 24, 206, 142, 17, 169, 230, 24, 206, 142, 17, 175, 230, 24, + 206, 142, 17, 171, 230, 24, 206, 142, 17, 178, 206, 46, 17, 107, 206, 46, + 17, 109, 206, 46, 17, 138, 206, 46, 17, 134, 206, 46, 17, 149, 206, 46, + 17, 169, 206, 46, 17, 175, 206, 46, 17, 171, 206, 46, 17, 178, 206, 46, + 31, 199, 95, 206, 46, 31, 197, 32, 206, 46, 31, 198, 249, 206, 46, 31, + 232, 135, 206, 46, 31, 233, 15, 206, 46, 31, 202, 120, 206, 46, 31, 203, + 241, 206, 46, 31, 234, 153, 206, 46, 31, 213, 169, 206, 46, 31, 91, 228, + 140, 206, 46, 31, 105, 228, 140, 206, 46, 31, 115, 228, 140, 206, 46, 31, + 232, 128, 228, 140, 206, 46, 31, 232, 226, 228, 140, 206, 46, 31, 202, + 136, 228, 140, 206, 46, 31, 203, 247, 228, 140, 206, 46, 31, 234, 164, + 228, 140, 206, 46, 31, 213, 175, 228, 140, 206, 46, 232, 118, 91, 230, + 70, 206, 46, 232, 118, 91, 208, 22, 206, 46, 232, 118, 91, 199, 0, 206, + 46, 232, 118, 105, 198, 253, 192, 39, 1, 234, 124, 192, 39, 1, 249, 17, + 192, 39, 1, 210, 63, 192, 39, 1, 209, 214, 192, 39, 1, 199, 33, 192, 39, + 1, 205, 68, 192, 39, 1, 243, 16, 192, 39, 1, 243, 83, 192, 39, 1, 243, + 97, 192, 39, 1, 229, 177, 192, 39, 1, 192, 220, 192, 39, 1, 238, 3, 192, + 39, 1, 191, 108, 192, 39, 1, 165, 192, 39, 1, 207, 6, 192, 39, 1, 191, + 123, 192, 39, 1, 223, 32, 192, 39, 1, 202, 174, 192, 39, 1, 203, 69, 192, + 39, 1, 205, 192, 192, 39, 1, 238, 26, 192, 39, 1, 190, 190, 192, 39, 1, + 191, 87, 192, 39, 1, 233, 184, 192, 39, 1, 192, 208, 192, 39, 1, 233, + 109, 192, 39, 1, 195, 188, 192, 39, 1, 195, 189, 251, 157, 20, 192, 39, + 1, 208, 89, 192, 39, 1, 222, 106, 192, 39, 1, 221, 212, 192, 39, 1, 231, + 227, 192, 39, 1, 220, 35, 192, 39, 1, 216, 46, 192, 39, 1, 212, 130, 192, + 39, 1, 196, 120, 192, 39, 1, 193, 133, 192, 39, 1, 210, 250, 192, 39, 1, + 233, 224, 192, 39, 1, 229, 252, 192, 39, 1, 191, 240, 192, 39, 1, 233, + 255, 192, 39, 33, 230, 58, 77, 192, 39, 33, 217, 142, 77, 192, 39, 228, + 86, 77, 192, 39, 1, 220, 36, 4, 75, 58, 192, 39, 1, 191, 241, 4, 243, 2, + 58, 9, 2, 130, 193, 23, 205, 171, 9, 2, 130, 193, 23, 208, 79, 9, 2, 130, + 193, 23, 217, 141, 39, 202, 28, 1, 251, 190, 39, 202, 28, 1, 53, 251, + 190, 39, 202, 28, 1, 248, 211, 39, 202, 28, 1, 53, 248, 211, 39, 202, 28, + 1, 231, 38, 39, 202, 28, 1, 229, 245, 39, 202, 28, 1, 53, 229, 245, 39, + 202, 28, 1, 193, 133, 39, 202, 28, 1, 191, 91, 39, 202, 28, 1, 229, 184, + 39, 202, 28, 1, 191, 249, 39, 202, 28, 1, 222, 75, 39, 202, 28, 1, 220, + 26, 39, 202, 28, 1, 216, 193, 39, 202, 28, 1, 212, 130, 39, 202, 28, 1, + 53, 212, 130, 39, 202, 28, 1, 53, 212, 131, 4, 81, 199, 215, 39, 202, 28, + 1, 205, 148, 39, 202, 28, 1, 250, 126, 39, 202, 28, 1, 251, 157, 250, + 126, 39, 202, 28, 1, 210, 63, 39, 202, 28, 1, 205, 189, 39, 202, 28, 1, + 53, 205, 189, 39, 202, 28, 1, 53, 205, 190, 4, 81, 199, 215, 39, 202, 28, + 1, 207, 36, 39, 202, 28, 1, 203, 69, 39, 202, 28, 1, 199, 159, 39, 202, + 28, 1, 53, 199, 159, 39, 202, 28, 1, 53, 199, 160, 4, 81, 199, 215, 39, + 202, 28, 31, 107, 39, 202, 28, 31, 109, 39, 202, 28, 31, 138, 39, 202, + 28, 31, 134, 39, 202, 28, 31, 149, 39, 202, 28, 31, 199, 95, 39, 202, 28, + 31, 197, 32, 39, 202, 28, 31, 198, 249, 39, 202, 28, 31, 91, 228, 140, + 39, 202, 28, 232, 118, 91, 230, 70, 39, 202, 28, 34, 250, 125, 202, 28, + 1, 251, 190, 202, 28, 1, 248, 211, 202, 28, 1, 231, 38, 202, 28, 1, 229, + 245, 202, 28, 1, 193, 133, 202, 28, 1, 191, 91, 202, 28, 1, 229, 184, + 202, 28, 1, 191, 249, 202, 28, 1, 222, 75, 202, 28, 1, 220, 26, 202, 28, + 1, 216, 193, 202, 28, 1, 212, 130, 202, 28, 1, 205, 148, 202, 28, 1, 250, + 126, 202, 28, 1, 210, 63, 202, 28, 1, 205, 189, 202, 28, 1, 207, 37, 202, + 28, 1, 203, 69, 202, 28, 1, 199, 159, 202, 28, 1, 233, 30, 202, 28, 1, + 219, 182, 202, 28, 223, 149, 203, 69, 202, 28, 33, 75, 60, 202, 28, 33, + 105, 185, 60, 202, 28, 33, 75, 58, 202, 28, 33, 105, 185, 58, 202, 28, + 33, 238, 165, 58, 202, 28, 33, 238, 165, 60, 202, 28, 33, 228, 251, 58, + 202, 28, 33, 228, 251, 60, 202, 28, 33, 179, 228, 251, 60, 202, 28, 33, + 207, 39, 60, 202, 28, 33, 201, 28, 60, 202, 28, 31, 107, 202, 28, 31, + 199, 95, 202, 28, 31, 197, 32, 202, 28, 31, 91, 228, 140, 202, 28, 208, + 152, 105, 81, 249, 76, 202, 28, 208, 152, 105, 81, 249, 77, 4, 236, 138, + 202, 28, 208, 152, 243, 11, 4, 236, 140, 202, 28, 208, 152, 105, 243, 8, + 4, 236, 138, 202, 28, 208, 152, 132, 243, 11, 4, 236, 140, 39, 196, 19, + 1, 251, 190, 39, 196, 19, 1, 248, 211, 39, 196, 19, 1, 231, 37, 39, 196, + 19, 1, 193, 133, 39, 196, 19, 1, 191, 91, 39, 196, 19, 1, 53, 229, 184, + 39, 196, 19, 1, 191, 249, 39, 196, 19, 1, 222, 75, 39, 196, 19, 1, 220, + 26, 39, 196, 19, 1, 216, 193, 39, 196, 19, 1, 212, 130, 39, 196, 19, 1, + 205, 148, 39, 196, 19, 1, 210, 63, 39, 196, 19, 1, 205, 189, 39, 196, 19, + 1, 207, 38, 39, 196, 19, 1, 203, 69, 39, 196, 19, 1, 199, 159, 39, 196, + 19, 1, 219, 182, 39, 196, 19, 33, 75, 58, 39, 196, 19, 33, 75, 60, 39, + 196, 19, 33, 105, 185, 58, 39, 196, 19, 33, 105, 185, 60, 39, 196, 19, + 208, 152, 164, 39, 196, 19, 208, 152, 105, 249, 76, 39, 196, 19, 208, + 152, 105, 236, 138, 39, 196, 19, 208, 152, 232, 128, 236, 138, 243, 61, + 1, 251, 190, 243, 61, 1, 2, 251, 190, 243, 61, 1, 248, 211, 243, 61, 1, + 231, 38, 243, 61, 1, 237, 252, 243, 61, 1, 229, 245, 243, 61, 1, 193, + 133, 243, 61, 1, 238, 174, 193, 133, 243, 61, 1, 191, 91, 243, 61, 1, + 229, 184, 243, 61, 1, 191, 249, 243, 61, 1, 222, 75, 243, 61, 1, 220, 26, + 243, 61, 1, 216, 193, 243, 61, 1, 212, 130, 243, 61, 1, 205, 148, 243, + 61, 1, 250, 126, 243, 61, 1, 210, 63, 243, 61, 1, 207, 38, 243, 61, 1, + 203, 69, 243, 61, 1, 199, 159, 243, 61, 31, 107, 243, 61, 31, 109, 243, + 61, 31, 138, 243, 61, 31, 134, 243, 61, 31, 199, 95, 243, 61, 31, 197, + 32, 243, 61, 31, 91, 228, 140, 234, 116, 1, 251, 190, 234, 116, 1, 248, + 211, 234, 116, 1, 231, 38, 234, 116, 1, 237, 252, 234, 116, 1, 229, 245, + 234, 116, 1, 193, 133, 234, 116, 1, 191, 91, 234, 116, 1, 229, 184, 234, + 116, 1, 199, 69, 234, 116, 1, 191, 249, 234, 116, 1, 222, 75, 234, 116, + 1, 220, 26, 234, 116, 1, 216, 193, 234, 116, 1, 212, 130, 234, 116, 1, + 205, 148, 234, 116, 1, 250, 126, 234, 116, 1, 210, 63, 234, 116, 1, 205, + 189, 234, 116, 1, 208, 37, 234, 116, 1, 207, 38, 234, 116, 1, 203, 69, + 234, 116, 1, 199, 159, 234, 116, 34, 191, 90, 162, 3, 247, 119, 162, 3, + 251, 71, 162, 3, 195, 35, 162, 3, 222, 237, 162, 3, 196, 75, 162, 1, 65, + 162, 1, 252, 206, 162, 1, 68, 162, 1, 223, 199, 162, 1, 66, 162, 1, 196, + 30, 162, 1, 117, 146, 162, 1, 117, 206, 110, 162, 1, 117, 172, 162, 1, + 117, 219, 74, 162, 1, 71, 162, 1, 251, 236, 162, 1, 74, 162, 1, 250, 163, + 162, 1, 155, 162, 1, 221, 215, 162, 1, 231, 240, 162, 1, 231, 91, 162, 1, + 214, 68, 162, 1, 247, 160, 162, 1, 247, 1, 162, 1, 223, 32, 162, 1, 222, + 252, 162, 1, 212, 101, 162, 1, 197, 132, 162, 1, 197, 120, 162, 1, 237, + 191, 162, 1, 237, 175, 162, 1, 213, 79, 162, 1, 190, 190, 162, 1, 199, + 49, 162, 1, 238, 32, 162, 1, 237, 68, 162, 1, 180, 162, 1, 168, 162, 1, + 209, 228, 162, 1, 249, 153, 162, 1, 248, 203, 162, 1, 174, 162, 1, 170, + 162, 1, 165, 162, 1, 173, 162, 1, 195, 188, 162, 1, 203, 165, 162, 1, + 201, 175, 162, 1, 188, 162, 1, 140, 162, 1, 219, 73, 162, 1, 39, 44, 219, + 62, 162, 1, 39, 44, 206, 109, 162, 1, 39, 44, 213, 61, 162, 18, 3, 252, + 206, 162, 18, 3, 248, 197, 252, 206, 162, 18, 3, 68, 162, 18, 3, 223, + 199, 162, 18, 3, 66, 162, 18, 3, 196, 30, 162, 18, 3, 117, 146, 162, 18, + 3, 117, 206, 110, 162, 18, 3, 117, 172, 162, 18, 3, 117, 219, 74, 162, + 18, 3, 71, 162, 18, 3, 251, 236, 162, 18, 3, 74, 162, 18, 3, 250, 163, + 162, 195, 40, 162, 237, 238, 162, 55, 237, 238, 162, 208, 152, 236, 140, + 162, 208, 152, 55, 236, 140, 162, 208, 152, 219, 112, 162, 208, 152, 238, + 228, 164, 162, 208, 152, 218, 246, 162, 31, 107, 162, 31, 109, 162, 31, + 138, 162, 31, 134, 162, 31, 149, 162, 31, 169, 162, 31, 175, 162, 31, + 171, 162, 31, 178, 162, 31, 199, 95, 162, 31, 197, 32, 162, 31, 198, 249, + 162, 31, 232, 135, 162, 31, 233, 15, 162, 31, 202, 120, 162, 31, 203, + 241, 162, 31, 234, 153, 162, 31, 213, 169, 162, 31, 91, 228, 140, 162, + 31, 91, 189, 162, 17, 191, 77, 162, 17, 107, 162, 17, 109, 162, 17, 138, + 162, 17, 134, 162, 17, 149, 162, 17, 169, 162, 17, 175, 162, 17, 171, + 162, 17, 178, 162, 3, 39, 44, 195, 40, 162, 1, 39, 44, 203, 40, 71, 162, + 1, 39, 44, 203, 40, 74, 162, 18, 3, 39, 44, 203, 40, 71, 162, 18, 3, 39, + 44, 203, 40, 74, 162, 1, 39, 44, 219, 73, 162, 31, 222, 196, 222, 99, 3, + 247, 119, 222, 99, 3, 251, 71, 222, 99, 3, 195, 35, 222, 99, 1, 65, 222, + 99, 1, 252, 206, 222, 99, 1, 68, 222, 99, 1, 223, 199, 222, 99, 1, 66, + 222, 99, 1, 196, 30, 222, 99, 1, 71, 222, 99, 1, 251, 236, 222, 99, 1, + 74, 222, 99, 1, 250, 163, 222, 99, 1, 155, 222, 99, 1, 221, 215, 222, 99, + 1, 231, 240, 222, 99, 1, 231, 91, 222, 99, 1, 214, 68, 222, 99, 1, 247, + 160, 222, 99, 1, 247, 1, 222, 99, 1, 223, 32, 222, 99, 1, 222, 252, 222, + 99, 1, 212, 101, 222, 99, 1, 197, 132, 222, 99, 1, 197, 120, 222, 99, 1, + 237, 191, 222, 99, 1, 237, 180, 222, 99, 1, 237, 175, 222, 99, 1, 207, 6, + 222, 99, 1, 213, 79, 222, 99, 1, 190, 190, 222, 99, 1, 199, 49, 222, 99, + 1, 238, 32, 222, 99, 1, 237, 68, 222, 99, 1, 180, 222, 99, 1, 168, 222, + 99, 1, 209, 228, 222, 99, 1, 249, 153, 222, 99, 1, 248, 203, 222, 99, 1, + 174, 222, 99, 1, 170, 222, 99, 1, 165, 222, 99, 1, 173, 222, 99, 1, 195, + 188, 222, 99, 1, 203, 165, 222, 99, 1, 201, 175, 222, 99, 1, 188, 222, + 99, 1, 140, 222, 99, 18, 3, 252, 206, 222, 99, 18, 3, 68, 222, 99, 18, 3, + 223, 199, 222, 99, 18, 3, 66, 222, 99, 18, 3, 196, 30, 222, 99, 18, 3, + 71, 222, 99, 18, 3, 251, 236, 222, 99, 18, 3, 74, 222, 99, 18, 3, 250, + 163, 222, 99, 3, 195, 40, 222, 99, 3, 212, 141, 222, 99, 252, 68, 56, + 222, 99, 234, 69, 56, 222, 99, 31, 56, 222, 99, 205, 54, 77, 222, 99, 55, + 205, 54, 77, 222, 99, 237, 238, 222, 99, 55, 237, 238, 222, 99, 18, 3, + 117, 146, 222, 99, 31, 3, 58, 202, 12, 202, 20, 1, 205, 182, 202, 12, + 202, 20, 1, 199, 219, 202, 12, 202, 20, 1, 249, 123, 202, 12, 202, 20, 1, + 247, 149, 202, 12, 202, 20, 1, 238, 12, 202, 12, 202, 20, 1, 231, 225, + 202, 12, 202, 20, 1, 217, 120, 202, 12, 202, 20, 1, 214, 65, 202, 12, + 202, 20, 1, 220, 99, 202, 12, 202, 20, 1, 214, 237, 202, 12, 202, 20, 1, + 195, 184, 202, 12, 202, 20, 1, 210, 200, 202, 12, 202, 20, 1, 192, 121, + 202, 12, 202, 20, 1, 207, 160, 202, 12, 202, 20, 1, 230, 81, 202, 12, + 202, 20, 1, 222, 104, 202, 12, 202, 20, 1, 223, 26, 202, 12, 202, 20, 1, + 212, 98, 202, 12, 202, 20, 1, 251, 245, 202, 12, 202, 20, 1, 234, 186, + 202, 12, 202, 20, 1, 223, 200, 202, 12, 202, 20, 1, 196, 141, 202, 12, + 202, 20, 1, 211, 136, 202, 12, 202, 20, 1, 234, 173, 202, 12, 202, 20, 1, + 217, 136, 202, 12, 202, 20, 17, 191, 77, 202, 12, 202, 20, 17, 107, 202, + 12, 202, 20, 17, 109, 202, 12, 202, 20, 17, 138, 202, 12, 202, 20, 17, + 134, 202, 12, 202, 20, 17, 149, 202, 12, 202, 20, 17, 169, 202, 12, 202, + 20, 17, 175, 202, 12, 202, 20, 17, 171, 202, 12, 202, 20, 17, 178, 246, + 251, 3, 247, 119, 246, 251, 3, 251, 71, 246, 251, 3, 195, 35, 246, 251, + 1, 252, 206, 246, 251, 1, 68, 246, 251, 1, 66, 246, 251, 1, 71, 246, 251, + 1, 222, 127, 246, 251, 1, 221, 214, 246, 251, 1, 231, 237, 246, 251, 1, + 231, 90, 246, 251, 1, 214, 67, 246, 251, 1, 247, 159, 246, 251, 1, 247, + 0, 246, 251, 1, 223, 31, 246, 251, 1, 222, 251, 246, 251, 1, 212, 100, + 246, 251, 1, 197, 131, 246, 251, 1, 197, 119, 246, 251, 1, 237, 190, 246, + 251, 1, 237, 174, 246, 251, 1, 213, 78, 246, 251, 1, 199, 245, 246, 251, + 1, 199, 48, 246, 251, 1, 238, 31, 246, 251, 1, 237, 67, 246, 251, 1, 214, + 250, 246, 251, 1, 210, 220, 246, 251, 1, 209, 227, 246, 251, 1, 249, 151, + 246, 251, 1, 248, 202, 246, 251, 1, 217, 151, 246, 251, 1, 191, 174, 246, + 251, 1, 192, 140, 246, 251, 1, 207, 178, 246, 251, 1, 220, 125, 246, 251, + 1, 193, 181, 246, 251, 1, 205, 197, 246, 251, 1, 230, 91, 246, 251, 18, + 3, 65, 246, 251, 18, 3, 68, 246, 251, 18, 3, 223, 199, 246, 251, 18, 3, + 66, 246, 251, 18, 3, 196, 30, 246, 251, 18, 3, 71, 246, 251, 18, 3, 251, + 236, 246, 251, 18, 3, 74, 246, 251, 18, 3, 250, 163, 246, 251, 18, 3, + 211, 133, 246, 251, 187, 77, 246, 251, 250, 164, 77, 246, 251, 195, 40, + 246, 251, 217, 149, 246, 251, 17, 191, 77, 246, 251, 17, 107, 246, 251, + 17, 109, 246, 251, 17, 138, 246, 251, 17, 134, 246, 251, 17, 149, 246, + 251, 17, 169, 246, 251, 17, 175, 246, 251, 17, 171, 246, 251, 17, 178, + 246, 251, 205, 54, 77, 246, 251, 237, 238, 246, 251, 55, 237, 238, 246, + 251, 208, 13, 77, 246, 251, 1, 219, 158, 246, 251, 18, 3, 252, 206, 246, + 251, 18, 3, 234, 166, 246, 251, 1, 195, 187, 217, 118, 1, 65, 217, 118, + 1, 68, 217, 118, 1, 66, 217, 118, 1, 71, 217, 118, 1, 74, 217, 118, 1, + 155, 217, 118, 1, 221, 215, 217, 118, 1, 231, 240, 217, 118, 1, 231, 91, + 217, 118, 1, 247, 160, 217, 118, 1, 247, 1, 217, 118, 1, 223, 32, 217, + 118, 1, 222, 252, 217, 118, 1, 212, 101, 217, 118, 1, 197, 132, 217, 118, + 1, 197, 120, 217, 118, 1, 237, 191, 217, 118, 1, 237, 175, 217, 118, 1, + 213, 79, 217, 118, 1, 190, 190, 217, 118, 1, 199, 49, 217, 118, 1, 238, + 32, 217, 118, 1, 237, 68, 217, 118, 1, 180, 217, 118, 1, 168, 217, 118, + 1, 209, 228, 217, 118, 1, 249, 153, 217, 118, 1, 248, 203, 217, 118, 1, + 174, 217, 118, 1, 165, 217, 118, 1, 173, 217, 118, 1, 195, 188, 217, 118, + 1, 188, 217, 118, 1, 140, 217, 118, 1, 206, 109, 217, 118, 3, 212, 141, + 217, 118, 252, 68, 56, 217, 118, 205, 54, 77, 217, 118, 34, 203, 15, 203, + 129, 3, 247, 119, 203, 129, 3, 251, 71, 203, 129, 3, 195, 35, 203, 129, + 1, 65, 203, 129, 1, 252, 206, 203, 129, 1, 68, 203, 129, 1, 223, 199, + 203, 129, 1, 66, 203, 129, 1, 196, 30, 203, 129, 1, 117, 146, 203, 129, + 1, 117, 206, 110, 203, 129, 1, 117, 172, 203, 129, 1, 117, 219, 74, 203, + 129, 1, 71, 203, 129, 1, 251, 236, 203, 129, 1, 74, 203, 129, 1, 250, + 163, 203, 129, 1, 155, 203, 129, 1, 221, 215, 203, 129, 1, 231, 240, 203, + 129, 1, 231, 91, 203, 129, 1, 214, 68, 203, 129, 1, 247, 160, 203, 129, + 1, 247, 1, 203, 129, 1, 223, 32, 203, 129, 1, 222, 252, 203, 129, 1, 212, + 101, 203, 129, 1, 197, 132, 203, 129, 1, 197, 120, 203, 129, 1, 237, 191, + 203, 129, 1, 237, 175, 203, 129, 1, 213, 79, 203, 129, 1, 190, 190, 203, + 129, 1, 199, 49, 203, 129, 1, 238, 32, 203, 129, 1, 237, 68, 203, 129, 1, + 180, 203, 129, 1, 168, 203, 129, 1, 209, 228, 203, 129, 1, 249, 153, 203, + 129, 1, 248, 203, 203, 129, 1, 174, 203, 129, 1, 170, 203, 129, 1, 165, + 203, 129, 1, 173, 203, 129, 1, 219, 73, 203, 129, 1, 195, 188, 203, 129, + 1, 203, 165, 203, 129, 1, 201, 175, 203, 129, 1, 188, 203, 129, 1, 140, + 203, 129, 18, 3, 252, 206, 203, 129, 18, 3, 68, 203, 129, 18, 3, 223, + 199, 203, 129, 18, 3, 66, 203, 129, 18, 3, 196, 30, 203, 129, 18, 3, 117, + 146, 203, 129, 18, 3, 117, 206, 110, 203, 129, 18, 3, 117, 172, 203, 129, + 18, 3, 117, 219, 74, 203, 129, 18, 3, 71, 203, 129, 18, 3, 251, 236, 203, + 129, 18, 3, 74, 203, 129, 18, 3, 250, 163, 203, 129, 3, 195, 40, 203, + 129, 3, 250, 145, 203, 129, 3, 222, 237, 203, 129, 3, 196, 75, 203, 129, + 211, 113, 203, 129, 237, 238, 203, 129, 55, 237, 238, 203, 129, 252, 68, + 56, 203, 129, 204, 10, 203, 129, 205, 138, 77, 203, 129, 3, 212, 141, + 203, 129, 18, 52, 77, 203, 129, 233, 201, 203, 40, 18, 77, 203, 129, 200, + 162, 77, 203, 129, 18, 3, 208, 207, 71, 203, 129, 3, 223, 93, 247, 119, + 203, 129, 17, 191, 77, 203, 129, 17, 107, 203, 129, 17, 109, 203, 129, + 17, 138, 203, 129, 17, 134, 203, 129, 17, 149, 203, 129, 17, 169, 203, + 129, 17, 175, 203, 129, 17, 171, 203, 129, 17, 178, 203, 129, 234, 146, + 203, 129, 3, 202, 210, 203, 129, 229, 227, 203, 129, 239, 29, 56, 203, + 129, 205, 54, 217, 55, 203, 129, 205, 54, 217, 54, 166, 251, 14, 17, 107, + 166, 251, 14, 17, 109, 166, 251, 14, 17, 138, 166, 251, 14, 17, 134, 166, + 251, 14, 17, 149, 166, 251, 14, 17, 169, 166, 251, 14, 17, 175, 166, 251, + 14, 17, 171, 166, 251, 14, 17, 178, 166, 251, 14, 31, 199, 95, 166, 251, + 14, 31, 197, 32, 166, 251, 14, 31, 198, 249, 166, 251, 14, 31, 232, 135, + 166, 251, 14, 31, 233, 15, 166, 251, 14, 31, 202, 120, 166, 251, 14, 31, + 203, 241, 166, 251, 14, 31, 234, 153, 166, 251, 14, 31, 213, 169, 166, + 251, 14, 31, 91, 228, 140, 166, 251, 14, 31, 91, 189, 221, 182, 1, 65, + 221, 182, 1, 252, 206, 221, 182, 1, 68, 221, 182, 1, 66, 221, 182, 1, 71, + 221, 182, 1, 251, 236, 221, 182, 1, 74, 221, 182, 1, 250, 163, 221, 182, + 1, 155, 221, 182, 1, 221, 215, 221, 182, 1, 231, 240, 221, 182, 1, 231, + 127, 221, 182, 1, 231, 91, 221, 182, 1, 214, 68, 221, 182, 1, 247, 160, + 221, 182, 1, 247, 1, 221, 182, 1, 223, 32, 221, 182, 1, 222, 230, 221, + 182, 1, 212, 101, 221, 182, 1, 197, 132, 221, 182, 1, 197, 120, 221, 182, + 1, 237, 191, 221, 182, 1, 237, 175, 221, 182, 1, 213, 79, 221, 182, 1, + 190, 190, 221, 182, 1, 199, 49, 221, 182, 1, 238, 32, 221, 182, 1, 237, + 181, 221, 182, 1, 237, 68, 221, 182, 1, 180, 221, 182, 1, 168, 221, 182, + 1, 209, 228, 221, 182, 1, 249, 153, 221, 182, 1, 249, 53, 221, 182, 1, + 248, 203, 221, 182, 1, 174, 221, 182, 1, 170, 221, 182, 1, 165, 221, 182, + 1, 173, 221, 182, 1, 195, 188, 221, 182, 1, 188, 221, 182, 1, 140, 221, + 182, 1, 219, 73, 221, 182, 18, 3, 252, 206, 221, 182, 18, 3, 68, 221, + 182, 18, 3, 223, 199, 221, 182, 18, 3, 66, 221, 182, 18, 3, 71, 221, 182, + 18, 3, 251, 236, 221, 182, 18, 3, 74, 221, 182, 18, 3, 250, 163, 221, + 182, 3, 251, 71, 221, 182, 3, 195, 40, 221, 182, 3, 212, 141, 221, 182, + 3, 203, 155, 221, 182, 237, 238, 221, 182, 55, 237, 238, 221, 182, 193, + 23, 204, 10, 221, 182, 205, 54, 77, 221, 182, 55, 205, 54, 77, 221, 182, + 252, 68, 56, 221, 182, 3, 200, 206, 221, 182, 1, 208, 96, 221, 182, 1, + 203, 40, 68, 221, 182, 18, 3, 117, 146, 215, 133, 1, 65, 215, 133, 1, 68, + 215, 133, 1, 66, 215, 133, 1, 71, 215, 133, 1, 155, 215, 133, 1, 221, + 215, 215, 133, 1, 231, 240, 215, 133, 1, 231, 91, 215, 133, 1, 247, 160, + 215, 133, 1, 247, 1, 215, 133, 1, 223, 32, 215, 133, 1, 222, 230, 215, + 133, 1, 212, 101, 215, 133, 1, 197, 132, 215, 133, 1, 197, 120, 215, 133, + 1, 237, 191, 215, 133, 1, 237, 181, 215, 133, 1, 237, 175, 215, 133, 1, + 213, 79, 215, 133, 1, 190, 190, 215, 133, 1, 199, 49, 215, 133, 1, 238, + 32, 215, 133, 1, 237, 68, 215, 133, 1, 180, 215, 133, 1, 168, 215, 133, + 1, 209, 228, 215, 133, 1, 249, 153, 215, 133, 1, 248, 203, 215, 133, 1, + 174, 215, 133, 1, 170, 215, 133, 1, 165, 215, 133, 1, 173, 215, 133, 1, + 195, 188, 215, 133, 1, 188, 215, 133, 1, 140, 215, 133, 1, 206, 109, 215, + 133, 1, 207, 6, 215, 133, 205, 54, 77, 221, 172, 1, 65, 221, 172, 1, 252, + 206, 221, 172, 1, 68, 221, 172, 1, 223, 199, 221, 172, 1, 66, 221, 172, + 1, 196, 30, 221, 172, 1, 71, 221, 172, 1, 251, 236, 221, 172, 1, 74, 221, + 172, 1, 250, 163, 221, 172, 1, 155, 221, 172, 1, 221, 215, 221, 172, 1, + 231, 240, 221, 172, 1, 231, 127, 221, 172, 1, 231, 91, 221, 172, 1, 214, + 68, 221, 172, 1, 247, 160, 221, 172, 1, 247, 1, 221, 172, 1, 223, 32, + 221, 172, 1, 222, 230, 221, 172, 1, 222, 252, 221, 172, 1, 212, 101, 221, + 172, 1, 197, 132, 221, 172, 1, 197, 120, 221, 172, 1, 237, 191, 221, 172, + 1, 237, 181, 221, 172, 1, 206, 109, 221, 172, 1, 237, 175, 221, 172, 1, + 213, 79, 221, 172, 1, 190, 190, 221, 172, 1, 199, 49, 221, 172, 1, 238, + 32, 221, 172, 1, 237, 68, 221, 172, 1, 180, 221, 172, 1, 168, 221, 172, + 1, 209, 228, 221, 172, 1, 249, 153, 221, 172, 1, 249, 53, 221, 172, 1, + 248, 203, 221, 172, 1, 174, 221, 172, 1, 170, 221, 172, 1, 165, 221, 172, + 1, 173, 221, 172, 1, 195, 188, 221, 172, 1, 203, 165, 221, 172, 1, 188, + 221, 172, 1, 140, 221, 172, 3, 251, 71, 221, 172, 18, 3, 252, 206, 221, + 172, 18, 3, 68, 221, 172, 18, 3, 223, 199, 221, 172, 18, 3, 66, 221, 172, + 18, 3, 196, 30, 221, 172, 18, 3, 71, 221, 172, 18, 3, 251, 236, 221, 172, + 18, 3, 74, 221, 172, 18, 3, 250, 163, 221, 172, 3, 212, 141, 221, 172, 3, + 195, 40, 221, 172, 17, 191, 77, 221, 172, 17, 107, 221, 172, 17, 109, + 221, 172, 17, 138, 221, 172, 17, 134, 221, 172, 17, 149, 221, 172, 17, + 169, 221, 172, 17, 175, 221, 172, 17, 171, 221, 172, 17, 178, 230, 219, + 3, 33, 251, 72, 58, 230, 219, 3, 247, 119, 230, 219, 3, 251, 71, 230, + 219, 3, 195, 35, 230, 219, 1, 65, 230, 219, 1, 252, 206, 230, 219, 1, 68, + 230, 219, 1, 223, 199, 230, 219, 1, 66, 230, 219, 1, 196, 30, 230, 219, + 1, 117, 146, 230, 219, 1, 117, 172, 230, 219, 1, 234, 188, 230, 219, 1, + 251, 236, 230, 219, 1, 211, 87, 230, 219, 1, 250, 163, 230, 219, 1, 155, + 230, 219, 1, 221, 215, 230, 219, 1, 231, 240, 230, 219, 1, 231, 91, 230, + 219, 1, 214, 68, 230, 219, 1, 247, 160, 230, 219, 1, 247, 1, 230, 219, 1, + 223, 32, 230, 219, 1, 222, 252, 230, 219, 1, 212, 101, 230, 219, 1, 197, + 132, 230, 219, 1, 197, 120, 230, 219, 1, 237, 191, 230, 219, 1, 237, 175, + 230, 219, 1, 213, 79, 230, 219, 1, 190, 190, 230, 219, 1, 199, 49, 230, + 219, 1, 238, 32, 230, 219, 1, 237, 68, 230, 219, 1, 180, 230, 219, 1, + 168, 230, 219, 1, 209, 228, 230, 219, 1, 249, 153, 230, 219, 1, 248, 203, + 230, 219, 1, 174, 230, 219, 1, 170, 230, 219, 1, 165, 230, 219, 1, 173, + 230, 219, 1, 219, 73, 230, 219, 1, 195, 188, 230, 219, 1, 203, 165, 230, + 219, 1, 201, 175, 230, 219, 1, 188, 230, 219, 1, 140, 33, 248, 165, 60, + 230, 219, 3, 212, 141, 230, 219, 3, 250, 145, 230, 219, 18, 3, 252, 206, + 230, 219, 18, 3, 68, 230, 219, 18, 3, 223, 199, 230, 219, 18, 3, 66, 230, + 219, 18, 3, 196, 30, 230, 219, 18, 3, 117, 146, 230, 219, 18, 3, 117, + 206, 110, 230, 219, 18, 3, 234, 188, 230, 219, 18, 3, 251, 236, 230, 219, + 18, 3, 211, 87, 230, 219, 18, 3, 250, 163, 230, 219, 3, 195, 40, 230, + 219, 211, 113, 230, 219, 250, 164, 219, 198, 77, 230, 219, 3, 209, 79, + 230, 219, 1, 195, 150, 251, 71, 230, 219, 1, 195, 150, 55, 251, 71, 230, + 219, 1, 117, 206, 110, 230, 219, 1, 117, 219, 74, 230, 219, 18, 3, 117, + 172, 230, 219, 18, 3, 117, 219, 74, 33, 230, 219, 17, 191, 77, 33, 230, + 219, 17, 107, 33, 230, 219, 17, 109, 33, 230, 219, 17, 138, 33, 230, 219, + 17, 134, 33, 230, 219, 17, 149, 33, 230, 219, 17, 169, 33, 230, 219, 1, + 65, 33, 230, 219, 1, 155, 33, 230, 219, 1, 180, 33, 230, 219, 1, 195, 69, + 33, 230, 219, 1, 168, 214, 78, 1, 65, 214, 78, 1, 252, 206, 214, 78, 1, + 68, 214, 78, 1, 223, 199, 214, 78, 1, 66, 214, 78, 1, 196, 30, 214, 78, + 1, 117, 146, 214, 78, 1, 117, 206, 110, 214, 78, 1, 117, 172, 214, 78, 1, + 117, 219, 74, 214, 78, 1, 71, 214, 78, 1, 251, 236, 214, 78, 1, 74, 214, + 78, 1, 250, 163, 214, 78, 1, 155, 214, 78, 1, 221, 215, 214, 78, 1, 231, + 240, 214, 78, 1, 231, 91, 214, 78, 1, 214, 68, 214, 78, 1, 214, 17, 214, + 78, 1, 247, 160, 214, 78, 1, 247, 1, 214, 78, 1, 223, 32, 214, 78, 1, + 222, 252, 214, 78, 1, 212, 101, 214, 78, 1, 212, 83, 214, 78, 1, 197, + 132, 214, 78, 1, 197, 120, 214, 78, 1, 237, 191, 214, 78, 1, 237, 175, + 214, 78, 1, 213, 79, 214, 78, 1, 190, 190, 214, 78, 1, 199, 49, 214, 78, + 1, 238, 32, 214, 78, 1, 237, 68, 214, 78, 1, 180, 214, 78, 1, 213, 224, + 214, 78, 1, 168, 214, 78, 1, 209, 228, 214, 78, 1, 249, 153, 214, 78, 1, + 248, 203, 214, 78, 1, 174, 214, 78, 1, 216, 103, 214, 78, 1, 170, 214, + 78, 1, 165, 214, 78, 1, 207, 6, 214, 78, 1, 173, 214, 78, 1, 219, 159, + 214, 78, 1, 193, 190, 214, 78, 1, 203, 165, 214, 78, 1, 201, 175, 214, + 78, 1, 188, 214, 78, 1, 140, 214, 78, 18, 3, 252, 206, 214, 78, 18, 3, + 68, 214, 78, 18, 3, 223, 199, 214, 78, 18, 3, 66, 214, 78, 18, 3, 196, + 30, 214, 78, 18, 3, 117, 146, 214, 78, 18, 3, 117, 206, 110, 214, 78, 18, + 3, 117, 172, 214, 78, 18, 3, 117, 219, 74, 214, 78, 18, 3, 71, 214, 78, + 18, 3, 251, 236, 214, 78, 18, 3, 74, 214, 78, 18, 3, 250, 163, 214, 78, + 3, 195, 40, 214, 78, 3, 247, 119, 214, 78, 3, 251, 71, 214, 78, 3, 195, + 35, 214, 78, 3, 212, 141, 214, 78, 3, 250, 145, 214, 78, 3, 53, 251, 71, + 214, 78, 211, 113, 214, 78, 202, 209, 214, 78, 237, 238, 214, 78, 55, + 237, 238, 214, 78, 242, 74, 214, 78, 231, 204, 233, 3, 214, 78, 252, 68, + 56, 214, 78, 17, 191, 77, 214, 78, 17, 107, 214, 78, 17, 109, 214, 78, + 17, 138, 214, 78, 17, 134, 214, 78, 17, 149, 214, 78, 17, 169, 214, 78, + 17, 175, 214, 78, 17, 171, 214, 78, 17, 178, 214, 78, 55, 242, 74, 214, + 78, 209, 107, 77, 214, 78, 223, 119, 56, 214, 78, 205, 138, 77, 214, 78, + 1, 195, 150, 251, 71, 214, 78, 3, 222, 237, 214, 78, 3, 196, 75, 198, + 129, 251, 100, 198, 129, 1, 65, 198, 129, 1, 252, 206, 198, 129, 1, 68, + 198, 129, 1, 223, 199, 198, 129, 1, 66, 198, 129, 1, 196, 30, 198, 129, + 1, 117, 146, 198, 129, 1, 117, 206, 110, 198, 129, 1, 117, 172, 198, 129, + 1, 117, 219, 74, 198, 129, 1, 71, 198, 129, 1, 251, 236, 198, 129, 1, 74, + 198, 129, 1, 250, 163, 198, 129, 1, 155, 198, 129, 1, 221, 215, 198, 129, + 1, 231, 240, 198, 129, 1, 231, 91, 198, 129, 1, 214, 68, 198, 129, 1, + 247, 160, 198, 129, 1, 247, 1, 198, 129, 1, 223, 32, 198, 129, 1, 222, + 252, 198, 129, 1, 212, 101, 198, 129, 1, 197, 132, 198, 129, 1, 197, 120, + 198, 129, 1, 237, 191, 198, 129, 1, 237, 175, 198, 129, 1, 213, 79, 198, + 129, 1, 190, 190, 198, 129, 1, 199, 49, 198, 129, 1, 238, 32, 198, 129, + 1, 237, 68, 198, 129, 1, 180, 198, 129, 1, 168, 198, 129, 1, 209, 228, + 198, 129, 1, 249, 153, 198, 129, 1, 248, 203, 198, 129, 1, 174, 198, 129, + 1, 170, 198, 129, 1, 165, 198, 129, 1, 173, 198, 129, 1, 195, 188, 198, + 129, 1, 203, 165, 198, 129, 1, 201, 175, 198, 129, 1, 188, 198, 129, 1, + 140, 198, 129, 18, 3, 252, 206, 198, 129, 18, 3, 68, 198, 129, 18, 3, + 223, 199, 198, 129, 18, 3, 66, 198, 129, 18, 3, 196, 30, 198, 129, 18, 3, + 117, 146, 198, 129, 18, 3, 117, 206, 110, 198, 129, 18, 3, 117, 172, 198, + 129, 18, 3, 117, 219, 74, 198, 129, 18, 3, 71, 198, 129, 18, 3, 203, 40, + 71, 198, 129, 18, 3, 251, 236, 198, 129, 18, 3, 74, 198, 129, 18, 3, 203, + 40, 74, 198, 129, 18, 3, 250, 163, 198, 129, 3, 247, 119, 198, 129, 3, + 251, 71, 198, 129, 3, 195, 35, 198, 129, 3, 195, 40, 198, 129, 3, 212, + 141, 198, 129, 3, 250, 145, 198, 129, 230, 137, 198, 129, 252, 68, 56, + 198, 129, 211, 113, 198, 129, 17, 191, 77, 198, 129, 17, 107, 198, 129, + 17, 109, 198, 129, 17, 138, 198, 129, 17, 134, 198, 129, 17, 149, 198, + 129, 17, 169, 198, 129, 17, 175, 198, 129, 17, 171, 198, 129, 17, 178, + 202, 211, 1, 65, 202, 211, 1, 252, 206, 202, 211, 1, 68, 202, 211, 1, + 223, 199, 202, 211, 1, 66, 202, 211, 1, 196, 30, 202, 211, 1, 117, 146, + 202, 211, 1, 117, 206, 110, 202, 211, 1, 117, 172, 202, 211, 1, 117, 219, + 74, 202, 211, 1, 71, 202, 211, 1, 251, 236, 202, 211, 1, 74, 202, 211, 1, + 250, 163, 202, 211, 1, 155, 202, 211, 1, 221, 215, 202, 211, 1, 231, 240, + 202, 211, 1, 231, 91, 202, 211, 1, 214, 68, 202, 211, 1, 247, 160, 202, + 211, 1, 247, 1, 202, 211, 1, 223, 32, 202, 211, 1, 222, 252, 202, 211, 1, + 212, 101, 202, 211, 1, 197, 132, 202, 211, 1, 197, 120, 202, 211, 1, 237, + 191, 202, 211, 1, 237, 175, 202, 211, 1, 213, 79, 202, 211, 1, 190, 190, + 202, 211, 1, 199, 49, 202, 211, 1, 238, 32, 202, 211, 1, 237, 68, 202, + 211, 1, 180, 202, 211, 1, 168, 202, 211, 1, 209, 228, 202, 211, 1, 249, + 153, 202, 211, 1, 248, 203, 202, 211, 1, 174, 202, 211, 1, 170, 202, 211, + 1, 165, 202, 211, 1, 173, 202, 211, 1, 195, 188, 202, 211, 1, 203, 165, + 202, 211, 1, 201, 175, 202, 211, 1, 188, 202, 211, 1, 140, 202, 211, 18, + 3, 252, 206, 202, 211, 18, 3, 68, 202, 211, 18, 3, 223, 199, 202, 211, + 18, 3, 66, 202, 211, 18, 3, 196, 30, 202, 211, 18, 3, 117, 146, 202, 211, + 18, 3, 117, 206, 110, 202, 211, 18, 3, 71, 202, 211, 18, 3, 251, 236, + 202, 211, 18, 3, 74, 202, 211, 18, 3, 250, 163, 202, 211, 3, 247, 119, + 202, 211, 3, 251, 71, 202, 211, 3, 195, 35, 202, 211, 3, 195, 40, 202, + 211, 3, 212, 141, 202, 211, 3, 202, 210, 202, 211, 237, 238, 202, 211, + 55, 237, 238, 202, 211, 204, 11, 236, 140, 202, 211, 204, 11, 164, 202, + 211, 207, 46, 217, 55, 202, 211, 207, 46, 217, 54, 202, 211, 207, 46, + 217, 53, 202, 211, 234, 95, 79, 199, 54, 77, 202, 211, 205, 54, 87, 4, + 197, 236, 23, 196, 221, 211, 41, 202, 211, 205, 54, 87, 4, 197, 236, 23, + 235, 138, 238, 226, 202, 211, 205, 54, 87, 4, 207, 120, 23, 235, 138, + 238, 226, 202, 211, 205, 54, 87, 4, 207, 120, 23, 235, 138, 55, 238, 226, + 202, 211, 205, 54, 87, 4, 207, 120, 23, 235, 138, 197, 225, 238, 226, + 202, 211, 205, 54, 87, 55, 206, 188, 202, 211, 205, 54, 87, 55, 206, 189, + 4, 207, 119, 202, 211, 205, 54, 87, 4, 55, 238, 226, 202, 211, 205, 54, + 87, 4, 197, 225, 238, 226, 202, 211, 205, 54, 87, 4, 208, 26, 238, 226, + 202, 211, 205, 54, 87, 4, 204, 8, 238, 226, 202, 211, 205, 54, 87, 4, + 243, 8, 23, 207, 119, 202, 211, 205, 54, 87, 4, 243, 8, 23, 105, 234, 97, + 202, 211, 205, 54, 87, 4, 243, 8, 23, 232, 128, 234, 97, 202, 211, 1, + 198, 226, 251, 157, 68, 202, 211, 1, 197, 15, 251, 157, 68, 202, 211, 1, + 197, 15, 251, 157, 223, 199, 202, 211, 1, 251, 157, 66, 202, 211, 18, 3, + 251, 157, 66, 202, 211, 18, 3, 251, 157, 196, 30, 215, 253, 1, 65, 215, + 253, 1, 252, 206, 215, 253, 1, 68, 215, 253, 1, 223, 199, 215, 253, 1, + 66, 215, 253, 1, 196, 30, 215, 253, 1, 117, 146, 215, 253, 1, 117, 206, + 110, 215, 253, 1, 117, 172, 215, 253, 1, 117, 219, 74, 215, 253, 1, 71, + 215, 253, 1, 251, 236, 215, 253, 1, 74, 215, 253, 1, 250, 163, 215, 253, + 1, 155, 215, 253, 1, 221, 215, 215, 253, 1, 231, 240, 215, 253, 1, 231, + 91, 215, 253, 1, 214, 68, 215, 253, 1, 247, 160, 215, 253, 1, 247, 1, + 215, 253, 1, 223, 32, 215, 253, 1, 222, 252, 215, 253, 1, 212, 101, 215, + 253, 1, 197, 132, 215, 253, 1, 197, 120, 215, 253, 1, 237, 191, 215, 253, + 1, 237, 175, 215, 253, 1, 213, 79, 215, 253, 1, 190, 190, 215, 253, 1, + 199, 49, 215, 253, 1, 238, 32, 215, 253, 1, 237, 68, 215, 253, 1, 180, + 215, 253, 1, 168, 215, 253, 1, 209, 228, 215, 253, 1, 249, 153, 215, 253, + 1, 248, 203, 215, 253, 1, 174, 215, 253, 1, 170, 215, 253, 1, 165, 215, + 253, 1, 173, 215, 253, 1, 195, 188, 215, 253, 1, 203, 165, 215, 253, 1, + 201, 175, 215, 253, 1, 188, 215, 253, 1, 140, 215, 253, 1, 219, 73, 215, + 253, 18, 3, 252, 206, 215, 253, 18, 3, 68, 215, 253, 18, 3, 223, 199, + 215, 253, 18, 3, 66, 215, 253, 18, 3, 196, 30, 215, 253, 18, 3, 117, 146, + 215, 253, 18, 3, 117, 206, 110, 215, 253, 18, 3, 117, 172, 215, 253, 18, + 3, 117, 219, 74, 215, 253, 18, 3, 71, 215, 253, 18, 3, 251, 236, 215, + 253, 18, 3, 74, 215, 253, 18, 3, 250, 163, 215, 253, 3, 251, 71, 215, + 253, 3, 195, 35, 215, 253, 3, 195, 40, 215, 253, 3, 251, 11, 215, 253, + 237, 238, 215, 253, 55, 237, 238, 215, 253, 252, 68, 56, 215, 253, 3, + 228, 127, 215, 253, 17, 191, 77, 215, 253, 17, 107, 215, 253, 17, 109, + 215, 253, 17, 138, 215, 253, 17, 134, 215, 253, 17, 149, 215, 253, 17, + 169, 215, 253, 17, 175, 215, 253, 17, 171, 215, 253, 17, 178, 104, 248, + 159, 4, 211, 42, 104, 206, 122, 248, 158, 104, 55, 248, 159, 4, 211, 42, + 104, 197, 225, 248, 159, 4, 211, 42, 104, 248, 159, 4, 55, 211, 42, 104, + 206, 122, 248, 159, 4, 211, 42, 104, 206, 122, 248, 159, 4, 55, 211, 42, + 104, 223, 93, 248, 158, 104, 223, 93, 248, 159, 4, 55, 211, 42, 104, 200, + 134, 248, 158, 104, 200, 134, 248, 159, 4, 211, 42, 104, 200, 134, 248, + 159, 4, 55, 211, 42, 104, 153, 200, 134, 248, 159, 4, 55, 211, 42, 199, + 205, 1, 65, 199, 205, 1, 252, 206, 199, 205, 1, 68, 199, 205, 1, 223, + 199, 199, 205, 1, 66, 199, 205, 1, 196, 30, 199, 205, 1, 71, 199, 205, 1, + 251, 236, 199, 205, 1, 74, 199, 205, 1, 250, 163, 199, 205, 1, 155, 199, + 205, 1, 221, 215, 199, 205, 1, 231, 240, 199, 205, 1, 231, 91, 199, 205, + 1, 214, 68, 199, 205, 1, 247, 160, 199, 205, 1, 247, 1, 199, 205, 1, 223, + 32, 199, 205, 1, 222, 252, 199, 205, 1, 212, 101, 199, 205, 1, 197, 132, + 199, 205, 1, 197, 120, 199, 205, 1, 237, 191, 199, 205, 1, 237, 175, 199, + 205, 1, 213, 79, 199, 205, 1, 190, 190, 199, 205, 1, 199, 49, 199, 205, + 1, 238, 32, 199, 205, 1, 237, 68, 199, 205, 1, 180, 199, 205, 1, 168, + 199, 205, 1, 209, 228, 199, 205, 1, 249, 153, 199, 205, 1, 248, 203, 199, + 205, 1, 174, 199, 205, 1, 170, 199, 205, 1, 165, 199, 205, 1, 173, 199, + 205, 1, 195, 188, 199, 205, 1, 203, 165, 199, 205, 1, 188, 199, 205, 1, + 140, 199, 205, 1, 206, 109, 199, 205, 3, 251, 71, 199, 205, 3, 195, 35, + 199, 205, 18, 3, 252, 206, 199, 205, 18, 3, 68, 199, 205, 18, 3, 223, + 199, 199, 205, 18, 3, 66, 199, 205, 18, 3, 196, 30, 199, 205, 18, 3, 71, + 199, 205, 18, 3, 251, 236, 199, 205, 18, 3, 74, 199, 205, 18, 3, 250, + 163, 199, 205, 3, 195, 40, 199, 205, 3, 212, 141, 199, 205, 1, 251, 14, + 221, 215, 199, 205, 252, 68, 56, 199, 205, 17, 191, 77, 199, 205, 17, + 107, 199, 205, 17, 109, 199, 205, 17, 138, 199, 205, 17, 134, 199, 205, + 17, 149, 199, 205, 17, 169, 199, 205, 17, 175, 199, 205, 17, 171, 199, + 205, 17, 178, 251, 240, 1, 155, 251, 240, 1, 221, 215, 251, 240, 1, 214, + 68, 251, 240, 1, 180, 251, 240, 1, 190, 190, 251, 240, 1, 251, 157, 190, + 190, 251, 240, 1, 168, 251, 240, 1, 209, 228, 251, 240, 1, 249, 153, 251, + 240, 1, 174, 251, 240, 1, 223, 32, 251, 240, 1, 247, 1, 251, 240, 1, 199, + 49, 251, 240, 1, 165, 251, 240, 1, 173, 251, 240, 1, 188, 251, 240, 1, + 212, 101, 251, 240, 1, 140, 251, 240, 1, 65, 251, 240, 1, 238, 32, 251, + 240, 1, 237, 68, 251, 240, 1, 231, 240, 251, 240, 1, 251, 157, 231, 240, + 251, 240, 1, 231, 91, 251, 240, 1, 248, 203, 251, 240, 1, 222, 252, 251, + 240, 1, 251, 157, 249, 153, 251, 240, 120, 3, 216, 217, 173, 251, 240, + 120, 3, 216, 217, 165, 251, 240, 120, 3, 216, 217, 219, 133, 165, 251, + 240, 18, 3, 65, 251, 240, 18, 3, 252, 206, 251, 240, 18, 3, 68, 251, 240, + 18, 3, 223, 199, 251, 240, 18, 3, 66, 251, 240, 18, 3, 196, 30, 251, 240, + 18, 3, 71, 251, 240, 18, 3, 250, 140, 251, 240, 18, 3, 74, 251, 240, 18, + 3, 251, 236, 251, 240, 18, 3, 251, 149, 251, 240, 3, 221, 143, 251, 240, + 17, 191, 77, 251, 240, 17, 107, 251, 240, 17, 109, 251, 240, 17, 138, + 251, 240, 17, 134, 251, 240, 17, 149, 251, 240, 17, 169, 251, 240, 17, + 175, 251, 240, 17, 171, 251, 240, 17, 178, 251, 240, 31, 199, 95, 251, + 240, 31, 197, 32, 251, 240, 3, 2, 205, 53, 251, 240, 3, 205, 53, 251, + 240, 3, 206, 53, 251, 240, 16, 195, 69, 251, 240, 1, 247, 160, 251, 240, + 1, 197, 132, 251, 240, 1, 197, 120, 251, 240, 1, 237, 191, 251, 240, 1, + 237, 175, 251, 240, 1, 213, 79, 251, 240, 1, 219, 73, 236, 161, 1, 65, + 236, 161, 1, 252, 206, 236, 161, 1, 68, 236, 161, 1, 223, 199, 236, 161, + 1, 66, 236, 161, 1, 196, 30, 236, 161, 1, 71, 236, 161, 1, 251, 236, 236, + 161, 1, 74, 236, 161, 1, 250, 163, 236, 161, 1, 155, 236, 161, 1, 221, + 215, 236, 161, 1, 231, 240, 236, 161, 1, 231, 91, 236, 161, 1, 214, 68, + 236, 161, 1, 247, 160, 236, 161, 1, 247, 1, 236, 161, 1, 223, 32, 236, + 161, 1, 222, 252, 236, 161, 1, 212, 101, 236, 161, 1, 197, 132, 236, 161, + 1, 197, 120, 236, 161, 1, 237, 191, 236, 161, 1, 237, 175, 236, 161, 1, + 213, 79, 236, 161, 1, 190, 190, 236, 161, 1, 199, 49, 236, 161, 1, 238, + 32, 236, 161, 1, 237, 68, 236, 161, 1, 180, 236, 161, 1, 168, 236, 161, + 1, 209, 228, 236, 161, 1, 249, 153, 236, 161, 1, 248, 203, 236, 161, 1, + 174, 236, 161, 1, 170, 236, 161, 1, 165, 236, 161, 1, 173, 236, 161, 1, + 195, 188, 236, 161, 1, 203, 165, 236, 161, 1, 201, 175, 236, 161, 1, 188, + 236, 161, 1, 140, 236, 161, 1, 206, 109, 236, 161, 18, 3, 252, 206, 236, + 161, 18, 3, 68, 236, 161, 18, 3, 223, 199, 236, 161, 18, 3, 66, 236, 161, + 18, 3, 196, 30, 236, 161, 18, 3, 117, 146, 236, 161, 18, 3, 117, 206, + 110, 236, 161, 18, 3, 71, 236, 161, 18, 3, 251, 236, 236, 161, 18, 3, 74, + 236, 161, 18, 3, 250, 163, 236, 161, 3, 251, 71, 236, 161, 3, 195, 35, + 236, 161, 3, 195, 40, 236, 161, 3, 212, 141, 236, 161, 252, 68, 56, 193, + 156, 242, 253, 6, 1, 214, 67, 193, 156, 242, 253, 6, 1, 65, 193, 156, + 242, 253, 6, 1, 193, 86, 193, 156, 242, 253, 6, 1, 191, 225, 193, 156, + 242, 253, 6, 1, 170, 193, 156, 242, 253, 6, 1, 192, 12, 193, 156, 242, + 253, 6, 1, 223, 199, 193, 156, 242, 253, 6, 1, 196, 30, 193, 156, 242, + 253, 6, 1, 71, 193, 156, 242, 253, 6, 1, 74, 193, 156, 242, 253, 6, 1, + 251, 122, 193, 156, 242, 253, 6, 1, 231, 240, 193, 156, 242, 253, 6, 1, + 221, 67, 193, 156, 242, 253, 6, 1, 234, 66, 193, 156, 242, 253, 6, 1, + 191, 204, 193, 156, 242, 253, 6, 1, 196, 160, 193, 156, 242, 253, 6, 1, + 234, 85, 193, 156, 242, 253, 6, 1, 211, 154, 193, 156, 242, 253, 6, 1, + 197, 127, 193, 156, 242, 253, 6, 1, 212, 127, 193, 156, 242, 253, 6, 1, + 238, 32, 193, 156, 242, 253, 6, 1, 250, 182, 193, 156, 242, 253, 6, 1, + 251, 149, 193, 156, 242, 253, 6, 1, 248, 10, 193, 156, 242, 253, 6, 1, + 208, 165, 193, 156, 242, 253, 6, 1, 229, 115, 193, 156, 242, 253, 6, 1, + 229, 3, 193, 156, 242, 253, 6, 1, 228, 185, 193, 156, 242, 253, 6, 1, + 230, 19, 193, 156, 242, 253, 6, 1, 201, 126, 193, 156, 242, 253, 6, 1, + 202, 193, 193, 156, 242, 253, 6, 1, 195, 25, 193, 156, 242, 253, 2, 1, + 214, 67, 193, 156, 242, 253, 2, 1, 65, 193, 156, 242, 253, 2, 1, 193, 86, + 193, 156, 242, 253, 2, 1, 191, 225, 193, 156, 242, 253, 2, 1, 170, 193, + 156, 242, 253, 2, 1, 192, 12, 193, 156, 242, 253, 2, 1, 223, 199, 193, + 156, 242, 253, 2, 1, 196, 30, 193, 156, 242, 253, 2, 1, 71, 193, 156, + 242, 253, 2, 1, 74, 193, 156, 242, 253, 2, 1, 251, 122, 193, 156, 242, + 253, 2, 1, 231, 240, 193, 156, 242, 253, 2, 1, 221, 67, 193, 156, 242, + 253, 2, 1, 234, 66, 193, 156, 242, 253, 2, 1, 191, 204, 193, 156, 242, + 253, 2, 1, 196, 160, 193, 156, 242, 253, 2, 1, 234, 85, 193, 156, 242, + 253, 2, 1, 211, 154, 193, 156, 242, 253, 2, 1, 197, 127, 193, 156, 242, + 253, 2, 1, 212, 127, 193, 156, 242, 253, 2, 1, 238, 32, 193, 156, 242, + 253, 2, 1, 250, 182, 193, 156, 242, 253, 2, 1, 251, 149, 193, 156, 242, + 253, 2, 1, 248, 10, 193, 156, 242, 253, 2, 1, 208, 165, 193, 156, 242, + 253, 2, 1, 229, 115, 193, 156, 242, 253, 2, 1, 229, 3, 193, 156, 242, + 253, 2, 1, 228, 185, 193, 156, 242, 253, 2, 1, 230, 19, 193, 156, 242, + 253, 2, 1, 201, 126, 193, 156, 242, 253, 2, 1, 202, 193, 193, 156, 242, + 253, 2, 1, 195, 25, 193, 156, 242, 253, 17, 191, 77, 193, 156, 242, 253, + 17, 107, 193, 156, 242, 253, 17, 109, 193, 156, 242, 253, 17, 138, 193, + 156, 242, 253, 17, 134, 193, 156, 242, 253, 17, 149, 193, 156, 242, 253, + 17, 169, 193, 156, 242, 253, 17, 175, 193, 156, 242, 253, 17, 171, 193, + 156, 242, 253, 17, 178, 193, 156, 242, 253, 31, 199, 95, 193, 156, 242, + 253, 31, 197, 32, 193, 156, 242, 253, 31, 198, 249, 193, 156, 242, 253, + 31, 232, 135, 193, 156, 242, 253, 31, 233, 15, 193, 156, 242, 253, 31, + 202, 120, 193, 156, 242, 253, 31, 203, 241, 193, 156, 242, 253, 31, 234, + 153, 193, 156, 242, 253, 31, 213, 169, 193, 156, 242, 253, 211, 113, 236, + 209, 251, 209, 1, 65, 236, 209, 251, 209, 1, 252, 206, 236, 209, 251, + 209, 1, 68, 236, 209, 251, 209, 1, 223, 199, 236, 209, 251, 209, 1, 66, + 236, 209, 251, 209, 1, 196, 30, 236, 209, 251, 209, 1, 71, 236, 209, 251, + 209, 1, 74, 236, 209, 251, 209, 1, 155, 236, 209, 251, 209, 1, 221, 215, + 236, 209, 251, 209, 1, 231, 240, 236, 209, 251, 209, 1, 231, 91, 236, + 209, 251, 209, 1, 214, 68, 236, 209, 251, 209, 1, 247, 160, 236, 209, + 251, 209, 1, 247, 1, 236, 209, 251, 209, 1, 223, 32, 236, 209, 251, 209, + 1, 212, 101, 236, 209, 251, 209, 1, 197, 132, 236, 209, 251, 209, 1, 237, + 191, 236, 209, 251, 209, 1, 237, 175, 236, 209, 251, 209, 1, 213, 79, + 236, 209, 251, 209, 1, 190, 190, 236, 209, 251, 209, 1, 199, 49, 236, + 209, 251, 209, 1, 238, 32, 236, 209, 251, 209, 1, 237, 68, 236, 209, 251, + 209, 1, 180, 236, 209, 251, 209, 1, 168, 236, 209, 251, 209, 1, 209, 228, + 236, 209, 251, 209, 1, 249, 153, 236, 209, 251, 209, 1, 248, 203, 236, + 209, 251, 209, 1, 174, 236, 209, 251, 209, 1, 170, 236, 209, 251, 209, 1, + 191, 175, 236, 209, 251, 209, 1, 165, 236, 209, 251, 209, 1, 173, 236, + 209, 251, 209, 1, 195, 188, 236, 209, 251, 209, 1, 203, 165, 236, 209, + 251, 209, 1, 201, 175, 236, 209, 251, 209, 1, 188, 236, 209, 251, 209, 1, + 140, 236, 209, 251, 209, 1, 219, 73, 236, 209, 251, 209, 1, 191, 123, + 236, 209, 251, 209, 18, 3, 252, 206, 236, 209, 251, 209, 18, 3, 68, 236, + 209, 251, 209, 18, 3, 223, 199, 236, 209, 251, 209, 18, 3, 66, 236, 209, + 251, 209, 18, 3, 196, 30, 236, 209, 251, 209, 18, 3, 71, 236, 209, 251, + 209, 18, 3, 251, 236, 236, 209, 251, 209, 18, 3, 74, 236, 209, 251, 209, + 3, 251, 71, 236, 209, 251, 209, 3, 247, 119, 236, 209, 251, 209, 3, 230, + 72, 236, 209, 251, 209, 195, 40, 236, 209, 251, 209, 208, 227, 214, 214, + 56, 236, 209, 251, 209, 216, 217, 170, 236, 209, 251, 209, 89, 165, 236, + 209, 251, 209, 216, 217, 165, 236, 209, 251, 209, 3, 212, 141, 236, 209, + 251, 209, 55, 237, 238, 236, 209, 251, 209, 231, 204, 233, 3, 236, 209, + 251, 209, 234, 95, 79, 199, 54, 77, 236, 209, 251, 209, 17, 191, 77, 236, + 209, 251, 209, 17, 107, 236, 209, 251, 209, 17, 109, 236, 209, 251, 209, + 17, 138, 236, 209, 251, 209, 17, 134, 236, 209, 251, 209, 17, 149, 236, + 209, 251, 209, 17, 169, 236, 209, 251, 209, 17, 175, 236, 209, 251, 209, + 17, 171, 236, 209, 251, 209, 17, 178, 214, 223, 1, 65, 214, 223, 1, 252, + 206, 214, 223, 1, 68, 214, 223, 1, 223, 199, 214, 223, 1, 66, 214, 223, + 1, 196, 30, 214, 223, 1, 117, 146, 214, 223, 1, 117, 206, 110, 214, 223, + 1, 71, 214, 223, 1, 251, 236, 214, 223, 1, 74, 214, 223, 1, 250, 163, + 214, 223, 1, 155, 214, 223, 1, 221, 215, 214, 223, 1, 231, 240, 214, 223, + 1, 231, 91, 214, 223, 1, 214, 68, 214, 223, 1, 247, 160, 214, 223, 1, + 247, 1, 214, 223, 1, 223, 32, 214, 223, 1, 222, 252, 214, 223, 1, 212, + 101, 214, 223, 1, 197, 132, 214, 223, 1, 197, 120, 214, 223, 1, 237, 191, + 214, 223, 1, 237, 175, 214, 223, 1, 213, 79, 214, 223, 1, 190, 190, 214, + 223, 1, 199, 49, 214, 223, 1, 238, 32, 214, 223, 1, 237, 68, 214, 223, 1, + 180, 214, 223, 1, 168, 214, 223, 1, 209, 228, 214, 223, 1, 249, 153, 214, + 223, 1, 248, 203, 214, 223, 1, 174, 214, 223, 1, 170, 214, 223, 1, 165, + 214, 223, 1, 173, 214, 223, 1, 195, 188, 214, 223, 1, 203, 165, 214, 223, + 1, 201, 175, 214, 223, 1, 188, 214, 223, 1, 140, 214, 223, 1, 219, 73, + 214, 223, 1, 206, 109, 214, 223, 18, 3, 252, 206, 214, 223, 18, 3, 68, + 214, 223, 18, 3, 223, 199, 214, 223, 18, 3, 66, 214, 223, 18, 3, 196, 30, + 214, 223, 18, 3, 117, 146, 214, 223, 18, 3, 117, 206, 110, 214, 223, 18, + 3, 71, 214, 223, 18, 3, 251, 236, 214, 223, 18, 3, 74, 214, 223, 18, 3, + 250, 163, 214, 223, 3, 251, 71, 214, 223, 3, 195, 35, 214, 223, 3, 195, + 40, 214, 223, 3, 250, 145, 214, 223, 3, 202, 210, 214, 223, 229, 227, + 214, 223, 18, 3, 208, 207, 71, 191, 106, 51, 1, 65, 191, 106, 51, 18, 3, + 68, 191, 106, 51, 18, 3, 196, 152, 191, 106, 51, 18, 3, 66, 191, 106, 51, + 18, 3, 71, 191, 106, 51, 18, 3, 211, 151, 191, 106, 51, 18, 3, 74, 191, + 106, 51, 18, 3, 251, 236, 191, 106, 51, 18, 3, 250, 163, 191, 106, 51, + 18, 3, 207, 18, 68, 191, 106, 51, 18, 219, 198, 77, 191, 106, 51, 1, 155, + 191, 106, 51, 1, 221, 215, 191, 106, 51, 1, 231, 240, 191, 106, 51, 1, + 231, 91, 191, 106, 51, 1, 214, 68, 191, 106, 51, 1, 247, 160, 191, 106, + 51, 1, 247, 1, 191, 106, 51, 1, 223, 32, 191, 106, 51, 1, 212, 101, 191, + 106, 51, 1, 197, 132, 191, 106, 51, 1, 197, 120, 191, 106, 51, 1, 237, + 191, 191, 106, 51, 1, 237, 175, 191, 106, 51, 1, 213, 79, 191, 106, 51, + 1, 190, 190, 191, 106, 51, 1, 199, 49, 191, 106, 51, 1, 238, 32, 191, + 106, 51, 1, 237, 68, 191, 106, 51, 1, 180, 191, 106, 51, 1, 168, 191, + 106, 51, 1, 209, 228, 191, 106, 51, 1, 249, 153, 191, 106, 51, 1, 248, + 203, 191, 106, 51, 1, 174, 191, 106, 51, 1, 197, 168, 191, 106, 51, 1, + 197, 157, 191, 106, 51, 1, 235, 35, 191, 106, 51, 1, 235, 29, 191, 106, + 51, 1, 191, 71, 191, 106, 51, 1, 191, 123, 191, 106, 51, 1, 255, 214, + 191, 106, 51, 1, 170, 191, 106, 51, 1, 165, 191, 106, 51, 1, 173, 191, + 106, 51, 1, 195, 188, 191, 106, 51, 1, 203, 165, 191, 106, 51, 1, 201, + 175, 191, 106, 51, 1, 188, 191, 106, 51, 1, 140, 191, 106, 51, 1, 220, + 246, 191, 106, 51, 53, 120, 77, 191, 106, 51, 3, 195, 40, 191, 106, 51, + 3, 247, 119, 191, 106, 51, 3, 247, 120, 4, 211, 42, 191, 106, 51, 3, 247, + 122, 4, 211, 42, 191, 106, 51, 3, 251, 71, 191, 106, 51, 3, 195, 35, 191, + 106, 51, 242, 201, 1, 165, 191, 106, 51, 242, 202, 1, 170, 191, 106, 51, + 242, 202, 1, 165, 191, 106, 51, 242, 202, 1, 173, 191, 106, 51, 242, 202, + 1, 195, 188, 191, 106, 51, 89, 229, 236, 77, 191, 106, 51, 242, 215, 229, + 236, 77, 191, 106, 51, 87, 197, 152, 191, 106, 51, 87, 203, 157, 191, + 106, 51, 87, 55, 203, 157, 191, 106, 51, 87, 179, 197, 152, 191, 106, 51, + 89, 235, 130, 229, 236, 77, 191, 106, 51, 242, 215, 235, 130, 229, 236, + 77, 191, 106, 51, 200, 238, 201, 251, 1, 65, 201, 251, 18, 3, 68, 201, + 251, 18, 3, 196, 152, 201, 251, 18, 3, 66, 201, 251, 18, 3, 71, 201, 251, + 18, 3, 74, 201, 251, 18, 3, 211, 151, 201, 251, 18, 3, 251, 236, 201, + 251, 18, 3, 250, 163, 201, 251, 18, 3, 117, 146, 201, 251, 18, 3, 117, + 172, 201, 251, 18, 219, 198, 77, 201, 251, 1, 155, 201, 251, 1, 221, 215, + 201, 251, 1, 231, 240, 201, 251, 1, 231, 91, 201, 251, 1, 214, 68, 201, + 251, 1, 247, 160, 201, 251, 1, 247, 1, 201, 251, 1, 223, 32, 201, 251, 1, + 222, 252, 201, 251, 1, 212, 101, 201, 251, 1, 197, 132, 201, 251, 1, 197, + 120, 201, 251, 1, 237, 191, 201, 251, 1, 237, 175, 201, 251, 1, 213, 79, + 201, 251, 1, 190, 190, 201, 251, 1, 199, 49, 201, 251, 1, 238, 32, 201, + 251, 1, 237, 68, 201, 251, 1, 180, 201, 251, 1, 168, 201, 251, 1, 209, + 228, 201, 251, 1, 249, 153, 201, 251, 1, 248, 203, 201, 251, 1, 174, 201, + 251, 1, 197, 168, 201, 251, 1, 197, 157, 201, 251, 1, 235, 35, 201, 251, + 1, 191, 71, 201, 251, 1, 191, 123, 201, 251, 1, 255, 214, 201, 251, 1, + 170, 201, 251, 1, 165, 201, 251, 1, 173, 201, 251, 1, 195, 188, 201, 251, + 1, 203, 165, 201, 251, 1, 201, 175, 201, 251, 1, 188, 201, 251, 1, 140, + 201, 251, 1, 220, 246, 201, 251, 3, 222, 237, 201, 251, 3, 196, 75, 201, + 251, 242, 201, 1, 165, 201, 251, 242, 201, 1, 173, 201, 251, 242, 201, 1, + 203, 165, 201, 251, 242, 201, 1, 188, 201, 251, 53, 120, 3, 232, 51, 201, + 251, 53, 120, 3, 222, 152, 201, 251, 53, 120, 3, 214, 70, 201, 251, 53, + 120, 3, 238, 127, 201, 251, 53, 120, 3, 215, 61, 201, 251, 53, 120, 3, + 250, 120, 201, 251, 53, 120, 3, 218, 168, 201, 251, 53, 120, 3, 146, 201, + 251, 53, 120, 3, 172, 201, 251, 53, 120, 3, 203, 167, 201, 251, 53, 120, + 3, 206, 8, 201, 251, 53, 120, 3, 255, 214, 201, 251, 3, 251, 71, 201, + 251, 3, 195, 35, 201, 251, 231, 153, 77, 201, 251, 200, 238, 201, 251, + 87, 197, 152, 201, 251, 87, 203, 157, 201, 251, 87, 55, 203, 157, 201, + 251, 87, 209, 79, 201, 251, 229, 236, 87, 4, 215, 206, 23, 200, 199, 23, + 197, 225, 232, 210, 201, 251, 229, 236, 87, 4, 215, 206, 23, 200, 199, + 23, 232, 210, 201, 251, 229, 236, 87, 4, 215, 206, 23, 200, 198, 201, + 251, 199, 81, 217, 55, 201, 251, 199, 81, 217, 54, 21, 22, 214, 207, 229, + 158, 21, 22, 214, 207, 229, 130, 21, 22, 214, 207, 229, 23, 21, 22, 214, + 207, 228, 252, 21, 22, 214, 207, 140, 21, 22, 214, 207, 230, 91, 21, 22, + 214, 207, 203, 15, 21, 22, 214, 207, 203, 14, 21, 22, 214, 207, 203, 11, + 21, 22, 214, 207, 203, 10, 21, 22, 214, 207, 203, 17, 21, 22, 214, 207, + 203, 16, 21, 22, 201, 237, 21, 22, 201, 224, 21, 22, 201, 207, 21, 22, + 201, 249, 210, 81, 243, 15, 230, 3, 1, 168, 210, 81, 243, 15, 230, 3, 1, + 155, 210, 81, 243, 15, 230, 3, 1, 173, 210, 81, 243, 15, 230, 3, 1, 174, + 210, 81, 243, 15, 230, 3, 1, 238, 32, 210, 81, 243, 15, 230, 3, 1, 191, + 123, 210, 81, 243, 15, 230, 3, 1, 195, 188, 210, 81, 243, 15, 230, 3, 1, + 214, 68, 210, 81, 243, 15, 230, 3, 1, 140, 210, 81, 243, 15, 230, 3, 1, + 231, 240, 210, 81, 243, 15, 230, 3, 1, 221, 215, 210, 81, 243, 15, 230, + 3, 1, 188, 210, 81, 243, 15, 230, 3, 1, 249, 153, 210, 81, 243, 15, 230, + 3, 1, 247, 160, 210, 81, 243, 15, 230, 3, 1, 190, 190, 210, 81, 243, 15, + 230, 3, 1, 199, 49, 210, 81, 243, 15, 230, 3, 1, 180, 210, 81, 243, 15, + 230, 3, 1, 209, 228, 210, 81, 243, 15, 230, 3, 1, 165, 210, 81, 243, 15, + 230, 3, 1, 233, 109, 210, 81, 243, 15, 230, 3, 1, 247, 1, 210, 81, 243, + 15, 230, 3, 1, 65, 210, 81, 243, 15, 230, 3, 1, 71, 210, 81, 243, 15, + 230, 3, 1, 68, 210, 81, 243, 15, 230, 3, 1, 74, 210, 81, 243, 15, 230, 3, + 1, 66, 210, 81, 243, 15, 230, 3, 1, 196, 168, 210, 81, 243, 15, 230, 3, + 1, 228, 35, 210, 81, 243, 15, 230, 3, 1, 53, 210, 236, 210, 81, 243, 15, + 230, 3, 1, 53, 222, 152, 210, 81, 243, 15, 230, 3, 1, 53, 200, 43, 210, + 81, 243, 15, 230, 3, 1, 53, 218, 168, 210, 81, 243, 15, 230, 3, 1, 53, + 215, 61, 210, 81, 243, 15, 230, 3, 1, 53, 172, 210, 81, 243, 15, 230, 3, + 1, 53, 193, 224, 210, 81, 243, 15, 230, 3, 1, 53, 214, 70, 210, 81, 243, + 15, 230, 3, 1, 53, 192, 159, 210, 81, 243, 15, 230, 3, 206, 180, 163, + 219, 19, 210, 81, 243, 15, 230, 3, 206, 180, 198, 79, 210, 81, 243, 15, + 230, 3, 205, 138, 231, 11, 201, 63, 210, 81, 243, 15, 230, 3, 206, 180, + 163, 179, 232, 255, 210, 81, 243, 15, 230, 3, 206, 180, 163, 232, 255, + 210, 81, 243, 15, 230, 3, 205, 138, 231, 11, 201, 64, 232, 255, 210, 81, + 243, 15, 230, 3, 205, 138, 163, 219, 19, 210, 81, 243, 15, 230, 3, 205, + 138, 198, 79, 210, 81, 243, 15, 230, 3, 205, 138, 163, 179, 232, 255, + 210, 81, 243, 15, 230, 3, 205, 138, 163, 232, 255, 210, 81, 243, 15, 230, + 3, 216, 85, 198, 79, 210, 81, 243, 15, 230, 3, 231, 11, 201, 64, 195, + 167, 210, 81, 243, 15, 230, 3, 216, 85, 163, 179, 232, 255, 210, 81, 243, + 15, 230, 3, 216, 85, 163, 232, 255, 210, 81, 243, 15, 230, 3, 218, 239, + 163, 219, 19, 210, 81, 243, 15, 230, 3, 218, 239, 198, 79, 210, 81, 243, + 15, 230, 3, 231, 11, 201, 63, 210, 81, 243, 15, 230, 3, 218, 239, 163, + 179, 232, 255, 210, 81, 243, 15, 230, 3, 218, 239, 163, 232, 255, 210, + 81, 243, 15, 230, 3, 231, 11, 201, 64, 232, 255, 100, 229, 236, 77, 100, + 229, 236, 87, 4, 229, 227, 100, 3, 248, 199, 100, 3, 248, 200, 4, 102, + 100, 3, 233, 205, 248, 199, 100, 3, 233, 205, 248, 200, 4, 102, 100, 3, + 193, 102, 232, 225, 248, 199, 100, 3, 193, 102, 213, 174, 248, 199, 100, + 3, 207, 18, 213, 174, 248, 199, 100, 3, 216, 43, 248, 201, 1, 65, 248, + 201, 1, 252, 206, 248, 201, 1, 68, 248, 201, 1, 223, 199, 248, 201, 1, + 66, 248, 201, 1, 196, 30, 248, 201, 1, 117, 146, 248, 201, 1, 117, 206, + 110, 248, 201, 1, 117, 172, 248, 201, 1, 71, 248, 201, 1, 251, 236, 248, + 201, 1, 74, 248, 201, 1, 250, 163, 248, 201, 1, 155, 248, 201, 1, 221, + 215, 248, 201, 1, 231, 240, 248, 201, 1, 231, 91, 248, 201, 1, 214, 68, + 248, 201, 1, 247, 160, 248, 201, 1, 247, 1, 248, 201, 1, 223, 32, 248, + 201, 1, 222, 252, 248, 201, 1, 212, 101, 248, 201, 1, 197, 132, 248, 201, + 1, 197, 120, 248, 201, 1, 237, 191, 248, 201, 1, 237, 175, 248, 201, 1, + 213, 79, 248, 201, 1, 190, 190, 248, 201, 1, 199, 49, 248, 201, 1, 238, + 32, 248, 201, 1, 237, 68, 248, 201, 1, 180, 248, 201, 1, 168, 248, 201, + 1, 209, 228, 248, 201, 1, 249, 153, 248, 201, 1, 248, 203, 248, 201, 1, + 174, 248, 201, 1, 170, 248, 201, 1, 165, 248, 201, 1, 173, 248, 201, 1, + 195, 188, 248, 201, 1, 203, 165, 248, 201, 1, 201, 175, 248, 201, 1, 188, + 248, 201, 1, 140, 248, 201, 18, 3, 252, 206, 248, 201, 18, 3, 68, 248, + 201, 18, 3, 223, 199, 248, 201, 18, 3, 66, 248, 201, 18, 3, 196, 30, 248, + 201, 18, 3, 117, 146, 248, 201, 18, 3, 117, 206, 110, 248, 201, 18, 3, + 117, 172, 248, 201, 18, 3, 71, 248, 201, 18, 3, 251, 236, 248, 201, 18, + 3, 74, 248, 201, 18, 3, 250, 163, 248, 201, 3, 247, 119, 248, 201, 3, + 251, 71, 248, 201, 3, 195, 35, 248, 201, 3, 195, 40, 248, 201, 3, 250, + 145, 248, 201, 237, 238, 248, 201, 55, 237, 238, 248, 201, 193, 23, 204, + 10, 248, 201, 231, 204, 233, 2, 248, 201, 231, 204, 233, 1, 248, 201, 17, + 191, 77, 248, 201, 17, 107, 248, 201, 17, 109, 248, 201, 17, 138, 248, + 201, 17, 134, 248, 201, 17, 149, 248, 201, 17, 169, 248, 201, 17, 175, + 248, 201, 17, 171, 248, 201, 17, 178, 248, 201, 31, 107, 248, 201, 31, + 109, 248, 201, 31, 138, 248, 201, 31, 134, 248, 201, 31, 149, 248, 201, + 31, 169, 248, 201, 31, 175, 248, 201, 31, 171, 248, 201, 31, 178, 248, + 201, 31, 199, 95, 248, 201, 31, 197, 32, 248, 201, 31, 198, 249, 248, + 201, 31, 232, 135, 248, 201, 31, 233, 15, 248, 201, 31, 202, 120, 248, + 201, 31, 203, 241, 248, 201, 31, 234, 153, 248, 201, 31, 213, 169, 248, + 201, 228, 139, 196, 91, 77, 217, 57, 229, 236, 77, 217, 57, 87, 203, 157, + 217, 57, 1, 155, 217, 57, 1, 221, 215, 217, 57, 1, 231, 240, 217, 57, 1, + 214, 68, 217, 57, 1, 247, 160, 217, 57, 1, 247, 1, 217, 57, 1, 223, 32, + 217, 57, 1, 212, 101, 217, 57, 1, 190, 190, 217, 57, 1, 199, 49, 217, 57, + 1, 238, 32, 217, 57, 1, 180, 217, 57, 1, 168, 217, 57, 1, 209, 228, 217, + 57, 1, 249, 153, 217, 57, 1, 174, 217, 57, 1, 197, 168, 217, 57, 1, 197, + 157, 217, 57, 1, 235, 35, 217, 57, 1, 193, 190, 217, 57, 1, 191, 71, 217, + 57, 1, 191, 123, 217, 57, 1, 255, 214, 217, 57, 1, 170, 217, 57, 1, 165, + 217, 57, 1, 173, 217, 57, 1, 203, 165, 217, 57, 1, 188, 217, 57, 1, 140, + 217, 57, 1, 65, 217, 57, 200, 239, 1, 155, 217, 57, 200, 239, 1, 221, + 215, 217, 57, 200, 239, 1, 231, 240, 217, 57, 200, 239, 1, 214, 68, 217, + 57, 200, 239, 1, 247, 160, 217, 57, 200, 239, 1, 247, 1, 217, 57, 200, + 239, 1, 223, 32, 217, 57, 200, 239, 1, 212, 101, 217, 57, 200, 239, 1, + 190, 190, 217, 57, 200, 239, 1, 199, 49, 217, 57, 200, 239, 1, 238, 32, + 217, 57, 200, 239, 1, 180, 217, 57, 200, 239, 1, 168, 217, 57, 200, 239, + 1, 209, 228, 217, 57, 200, 239, 1, 249, 153, 217, 57, 200, 239, 1, 174, + 217, 57, 200, 239, 1, 197, 168, 217, 57, 200, 239, 1, 197, 157, 217, 57, + 200, 239, 1, 235, 35, 217, 57, 200, 239, 1, 193, 190, 217, 57, 200, 239, + 1, 191, 71, 217, 57, 200, 239, 1, 191, 123, 217, 57, 200, 239, 1, 170, + 217, 57, 200, 239, 1, 165, 217, 57, 200, 239, 1, 173, 217, 57, 200, 239, + 1, 203, 165, 217, 57, 200, 239, 1, 188, 217, 57, 200, 239, 1, 140, 217, + 57, 200, 239, 1, 65, 217, 57, 18, 3, 252, 206, 217, 57, 18, 3, 68, 217, + 57, 18, 3, 66, 217, 57, 18, 3, 71, 217, 57, 18, 3, 74, 217, 57, 3, 251, + 71, 217, 57, 3, 247, 119, 217, 41, 129, 1, 65, 217, 41, 129, 1, 252, 206, + 217, 41, 129, 1, 68, 217, 41, 129, 1, 223, 199, 217, 41, 129, 1, 66, 217, + 41, 129, 1, 196, 30, 217, 41, 129, 1, 71, 217, 41, 129, 1, 251, 236, 217, + 41, 129, 1, 74, 217, 41, 129, 1, 250, 163, 217, 41, 129, 1, 155, 217, 41, + 129, 1, 221, 215, 217, 41, 129, 1, 231, 240, 217, 41, 129, 1, 231, 91, + 217, 41, 129, 1, 214, 68, 217, 41, 129, 1, 247, 160, 217, 41, 129, 1, + 247, 1, 217, 41, 129, 1, 223, 32, 217, 41, 129, 1, 222, 252, 217, 41, + 129, 1, 212, 101, 217, 41, 129, 1, 197, 132, 217, 41, 129, 1, 197, 120, + 217, 41, 129, 1, 237, 191, 217, 41, 129, 1, 237, 175, 217, 41, 129, 1, + 213, 79, 217, 41, 129, 1, 190, 190, 217, 41, 129, 1, 199, 49, 217, 41, + 129, 1, 238, 32, 217, 41, 129, 1, 237, 68, 217, 41, 129, 1, 180, 217, 41, + 129, 1, 168, 217, 41, 129, 1, 209, 228, 217, 41, 129, 1, 249, 153, 217, + 41, 129, 1, 248, 203, 217, 41, 129, 1, 174, 217, 41, 129, 1, 170, 217, + 41, 129, 1, 165, 217, 41, 129, 1, 173, 217, 41, 129, 1, 195, 188, 217, + 41, 129, 1, 203, 165, 217, 41, 129, 1, 201, 175, 217, 41, 129, 1, 188, + 217, 41, 129, 1, 140, 217, 41, 129, 1, 219, 73, 217, 41, 129, 1, 220, + 246, 217, 41, 129, 1, 222, 202, 217, 41, 129, 1, 198, 26, 217, 41, 129, + 18, 3, 252, 206, 217, 41, 129, 18, 3, 68, 217, 41, 129, 18, 3, 223, 199, + 217, 41, 129, 18, 3, 66, 217, 41, 129, 18, 3, 196, 30, 217, 41, 129, 18, + 3, 117, 146, 217, 41, 129, 18, 3, 71, 217, 41, 129, 18, 3, 251, 236, 217, + 41, 129, 18, 3, 74, 217, 41, 129, 18, 3, 250, 163, 217, 41, 129, 3, 251, + 71, 217, 41, 129, 3, 195, 35, 217, 41, 129, 3, 212, 141, 217, 41, 129, 3, + 247, 121, 217, 41, 129, 3, 230, 72, 217, 41, 129, 195, 40, 217, 41, 129, + 207, 44, 217, 41, 129, 207, 181, 217, 41, 129, 17, 191, 77, 217, 41, 129, + 17, 107, 217, 41, 129, 17, 109, 217, 41, 129, 17, 138, 217, 41, 129, 17, + 134, 217, 41, 129, 17, 149, 217, 41, 129, 17, 169, 217, 41, 129, 17, 175, + 217, 41, 129, 17, 171, 217, 41, 129, 17, 178, 230, 157, 129, 1, 65, 230, + 157, 129, 1, 252, 206, 230, 157, 129, 1, 68, 230, 157, 129, 1, 223, 199, + 230, 157, 129, 1, 66, 230, 157, 129, 1, 196, 30, 230, 157, 129, 1, 234, + 188, 230, 157, 129, 1, 251, 236, 230, 157, 129, 1, 211, 87, 230, 157, + 129, 1, 250, 163, 230, 157, 129, 1, 170, 230, 157, 129, 1, 195, 188, 230, + 157, 129, 1, 249, 153, 230, 157, 129, 1, 248, 203, 230, 157, 129, 1, 174, + 230, 157, 129, 1, 155, 230, 157, 129, 1, 221, 215, 230, 157, 129, 1, 190, + 190, 230, 157, 129, 1, 199, 49, 230, 157, 129, 1, 173, 230, 157, 129, 1, + 231, 240, 230, 157, 129, 1, 231, 91, 230, 157, 129, 1, 238, 32, 230, 157, + 129, 1, 237, 68, 230, 157, 129, 1, 180, 230, 157, 129, 1, 247, 160, 230, + 157, 129, 1, 247, 1, 230, 157, 129, 1, 197, 132, 230, 157, 129, 1, 197, + 120, 230, 157, 129, 1, 219, 73, 230, 157, 129, 1, 223, 32, 230, 157, 129, + 1, 222, 252, 230, 157, 129, 1, 237, 191, 230, 157, 129, 1, 237, 175, 230, + 157, 129, 1, 214, 68, 230, 157, 129, 1, 168, 230, 157, 129, 1, 209, 228, + 230, 157, 129, 1, 140, 230, 157, 129, 1, 165, 230, 157, 129, 1, 188, 230, + 157, 129, 18, 3, 252, 206, 230, 157, 129, 18, 3, 68, 230, 157, 129, 18, + 3, 223, 199, 230, 157, 129, 18, 3, 66, 230, 157, 129, 18, 3, 196, 30, + 230, 157, 129, 18, 3, 234, 188, 230, 157, 129, 18, 3, 251, 236, 230, 157, + 129, 18, 3, 211, 87, 230, 157, 129, 18, 3, 250, 163, 230, 157, 129, 3, + 251, 71, 230, 157, 129, 3, 195, 35, 230, 157, 129, 195, 40, 230, 157, + 129, 211, 113, 230, 157, 129, 17, 191, 77, 230, 157, 129, 17, 107, 230, + 157, 129, 17, 109, 230, 157, 129, 17, 138, 230, 157, 129, 17, 134, 230, + 157, 129, 17, 149, 230, 157, 129, 17, 169, 230, 157, 129, 17, 175, 230, + 157, 129, 17, 171, 230, 157, 129, 17, 178, 217, 102, 1, 155, 217, 102, 1, + 231, 240, 217, 102, 1, 214, 68, 217, 102, 1, 168, 217, 102, 1, 249, 153, + 217, 102, 1, 174, 217, 102, 1, 190, 190, 217, 102, 1, 238, 32, 217, 102, + 1, 180, 217, 102, 1, 247, 160, 217, 102, 1, 223, 32, 217, 102, 1, 212, + 101, 217, 102, 1, 170, 217, 102, 1, 165, 217, 102, 1, 173, 217, 102, 1, + 195, 188, 217, 102, 1, 188, 217, 102, 1, 65, 217, 102, 251, 118, 217, + 102, 18, 3, 68, 217, 102, 18, 3, 66, 217, 102, 18, 3, 71, 217, 102, 18, + 3, 74, 217, 102, 210, 94, 217, 102, 234, 95, 79, 205, 53, 222, 33, 3, + 247, 119, 222, 33, 3, 251, 71, 222, 33, 3, 207, 44, 222, 33, 3, 195, 35, + 222, 33, 1, 65, 222, 33, 1, 252, 206, 222, 33, 1, 68, 222, 33, 1, 223, + 199, 222, 33, 1, 66, 222, 33, 1, 196, 30, 222, 33, 1, 117, 146, 222, 33, + 1, 117, 206, 110, 222, 33, 1, 117, 172, 222, 33, 1, 117, 219, 74, 222, + 33, 1, 71, 222, 33, 1, 251, 236, 222, 33, 1, 74, 222, 33, 1, 155, 222, + 33, 1, 221, 215, 222, 33, 1, 231, 240, 222, 33, 1, 231, 91, 222, 33, 1, + 214, 68, 222, 33, 1, 247, 160, 222, 33, 1, 247, 1, 222, 33, 1, 223, 32, + 222, 33, 1, 222, 252, 222, 33, 1, 212, 101, 222, 33, 1, 197, 132, 222, + 33, 1, 197, 120, 222, 33, 1, 237, 191, 222, 33, 1, 237, 175, 222, 33, 1, + 213, 79, 222, 33, 1, 190, 190, 222, 33, 1, 199, 49, 222, 33, 1, 238, 32, + 222, 33, 1, 237, 68, 222, 33, 1, 180, 222, 33, 1, 168, 222, 33, 1, 209, + 228, 222, 33, 1, 249, 153, 222, 33, 1, 248, 203, 222, 33, 1, 174, 222, + 33, 1, 170, 222, 33, 1, 165, 222, 33, 1, 173, 222, 33, 1, 193, 190, 222, + 33, 1, 203, 165, 222, 33, 1, 201, 175, 222, 33, 1, 188, 222, 33, 1, 140, + 222, 33, 1, 222, 202, 222, 33, 18, 3, 252, 206, 222, 33, 18, 3, 251, 157, + 252, 206, 222, 33, 18, 3, 68, 222, 33, 18, 3, 223, 199, 222, 33, 18, 3, + 66, 222, 33, 18, 3, 196, 30, 222, 33, 18, 3, 117, 146, 222, 33, 18, 3, + 71, 222, 33, 18, 3, 251, 236, 222, 33, 18, 3, 233, 242, 222, 33, 3, 221, + 143, 222, 33, 239, 45, 222, 33, 237, 238, 222, 33, 55, 237, 238, 222, 33, + 208, 152, 205, 54, 217, 51, 222, 33, 208, 152, 251, 157, 205, 54, 217, + 51, 222, 33, 208, 152, 232, 186, 222, 33, 208, 152, 201, 248, 233, 3, + 222, 33, 208, 152, 236, 140, 222, 33, 208, 152, 55, 236, 140, 222, 33, + 208, 152, 197, 225, 236, 140, 222, 33, 208, 152, 243, 10, 222, 33, 208, + 152, 233, 4, 243, 10, 222, 33, 208, 152, 201, 217, 222, 33, 208, 152, + 242, 215, 201, 217, 222, 33, 17, 191, 77, 222, 33, 17, 107, 222, 33, 17, + 109, 222, 33, 17, 138, 222, 33, 17, 134, 222, 33, 17, 149, 222, 33, 17, + 169, 222, 33, 17, 175, 222, 33, 17, 171, 222, 33, 17, 178, 219, 88, 1, + 192, 35, 44, 232, 118, 91, 198, 222, 44, 232, 118, 91, 211, 100, 44, 232, + 118, 91, 234, 156, 44, 232, 118, 91, 202, 118, 44, 232, 118, 91, 232, + 139, 44, 232, 118, 91, 198, 245, 44, 232, 118, 115, 234, 155, 44, 232, + 118, 115, 202, 117, 44, 232, 118, 91, 197, 35, 44, 232, 118, 91, 202, + 127, 44, 232, 118, 91, 202, 126, 44, 232, 118, 91, 199, 86, 44, 232, 118, + 91, 234, 159, 44, 232, 118, 115, 197, 34, 44, 232, 118, 115, 202, 125, + 44, 232, 118, 91, 233, 18, 44, 232, 118, 91, 208, 22, 44, 232, 118, 91, + 230, 69, 44, 232, 118, 91, 230, 68, 44, 232, 118, 115, 208, 20, 44, 232, + 118, 235, 121, 233, 93, 221, 144, 44, 3, 214, 104, 44, 3, 247, 6, 44, 3, + 252, 157, 44, 3, 196, 15, 44, 3, 215, 90, 44, 3, 220, 194, 44, 3, 210, + 85, 44, 3, 215, 135, 44, 3, 222, 124, 44, 3, 210, 164, 44, 3, 209, 39, + 44, 3, 195, 173, 44, 3, 210, 215, 44, 3, 220, 183, 44, 3, 195, 143, 44, + 193, 101, 238, 187, 56, 44, 235, 92, 238, 187, 56, 44, 220, 23, 56, 44, + 205, 159, 210, 167, 56, 44, 198, 21, 238, 230, 56, 44, 198, 21, 31, 56, + 44, 238, 169, 56, 44, 23, 211, 155, 56, 44, 201, 227, 56, 44, 198, 39, + 56, 44, 223, 163, 209, 22, 56, 44, 201, 96, 232, 98, 56, 44, 3, 215, 94, + 44, 3, 195, 181, 44, 208, 152, 234, 95, 79, 199, 53, 10, 3, 65, 10, 3, + 42, 25, 65, 10, 3, 42, 25, 249, 135, 10, 3, 42, 25, 231, 209, 199, 84, + 10, 3, 42, 25, 140, 10, 3, 42, 25, 223, 201, 10, 3, 42, 25, 220, 103, + 230, 155, 10, 3, 42, 25, 215, 101, 10, 3, 42, 25, 205, 185, 10, 3, 254, + 215, 10, 3, 252, 155, 10, 3, 252, 156, 25, 250, 207, 10, 3, 252, 156, 25, + 235, 74, 230, 155, 10, 3, 252, 156, 25, 231, 222, 10, 3, 252, 156, 25, + 231, 209, 199, 84, 10, 3, 252, 156, 25, 140, 10, 3, 252, 156, 25, 223, + 202, 230, 155, 10, 3, 252, 156, 25, 223, 172, 10, 3, 252, 156, 25, 220, + 104, 10, 3, 252, 156, 25, 203, 97, 10, 3, 252, 156, 25, 126, 108, 126, + 108, 66, 10, 3, 252, 156, 230, 155, 10, 3, 252, 72, 10, 3, 252, 73, 25, + 249, 114, 10, 3, 252, 73, 25, 231, 209, 199, 84, 10, 3, 252, 73, 25, 216, + 233, 108, 234, 103, 10, 3, 252, 73, 25, 203, 163, 10, 3, 252, 73, 25, + 199, 209, 10, 3, 252, 42, 10, 3, 251, 216, 10, 3, 251, 217, 25, 234, 28, + 10, 3, 251, 217, 25, 203, 59, 108, 231, 23, 10, 3, 251, 207, 10, 3, 251, + 208, 25, 251, 207, 10, 3, 251, 208, 25, 236, 253, 10, 3, 251, 208, 25, + 231, 23, 10, 3, 251, 208, 25, 140, 10, 3, 251, 208, 25, 222, 111, 10, 3, + 251, 208, 25, 221, 166, 10, 3, 251, 208, 25, 203, 113, 10, 3, 251, 208, + 25, 196, 38, 10, 3, 251, 203, 10, 3, 251, 190, 10, 3, 251, 145, 10, 3, + 251, 146, 25, 203, 113, 10, 3, 251, 132, 10, 3, 251, 133, 139, 251, 132, + 10, 3, 251, 133, 115, 198, 144, 10, 3, 251, 133, 108, 214, 241, 211, 63, + 251, 133, 108, 214, 240, 10, 3, 251, 133, 108, 214, 241, 201, 189, 10, 3, + 251, 91, 10, 3, 251, 60, 10, 3, 251, 26, 10, 3, 251, 27, 25, 220, 197, + 10, 3, 250, 254, 10, 3, 250, 215, 10, 3, 250, 209, 10, 3, 250, 210, 191, + 26, 199, 84, 10, 3, 250, 210, 222, 116, 199, 84, 10, 3, 250, 210, 139, + 250, 210, 197, 83, 139, 197, 83, 197, 83, 139, 197, 83, 210, 137, 10, 3, + 250, 210, 139, 250, 210, 139, 250, 209, 10, 3, 250, 210, 139, 250, 210, + 139, 250, 210, 238, 210, 250, 210, 139, 250, 210, 139, 250, 209, 10, 3, + 250, 207, 10, 3, 250, 203, 10, 3, 249, 153, 10, 3, 249, 135, 10, 3, 249, + 129, 10, 3, 249, 121, 10, 3, 249, 115, 10, 3, 249, 116, 139, 249, 115, + 10, 3, 249, 114, 10, 3, 164, 10, 3, 249, 87, 10, 3, 248, 188, 10, 3, 248, + 189, 25, 65, 10, 3, 248, 189, 25, 231, 200, 10, 3, 248, 189, 25, 223, + 202, 230, 155, 10, 3, 248, 10, 10, 3, 248, 11, 139, 248, 11, 252, 155, + 10, 3, 248, 11, 139, 248, 11, 196, 113, 10, 3, 248, 11, 238, 210, 248, + 10, 10, 3, 247, 242, 10, 3, 247, 243, 139, 247, 242, 10, 3, 247, 230, 10, + 3, 247, 229, 10, 3, 238, 32, 10, 3, 238, 22, 10, 3, 238, 23, 221, 125, + 25, 42, 108, 217, 39, 10, 3, 238, 23, 221, 125, 25, 251, 145, 10, 3, 238, + 23, 221, 125, 25, 249, 114, 10, 3, 238, 23, 221, 125, 25, 248, 188, 10, + 3, 238, 23, 221, 125, 25, 231, 240, 10, 3, 238, 23, 221, 125, 25, 231, + 241, 108, 217, 39, 10, 3, 238, 23, 221, 125, 25, 231, 53, 10, 3, 238, 23, + 221, 125, 25, 231, 32, 10, 3, 238, 23, 221, 125, 25, 230, 168, 10, 3, + 238, 23, 221, 125, 25, 140, 10, 3, 238, 23, 221, 125, 25, 223, 77, 10, 3, + 238, 23, 221, 125, 25, 223, 78, 108, 218, 225, 10, 3, 238, 23, 221, 125, + 25, 222, 96, 10, 3, 238, 23, 221, 125, 25, 173, 10, 3, 238, 23, 221, 125, + 25, 218, 225, 10, 3, 238, 23, 221, 125, 25, 218, 226, 108, 217, 38, 10, + 3, 238, 23, 221, 125, 25, 218, 208, 10, 3, 238, 23, 221, 125, 25, 214, + 121, 10, 3, 238, 23, 221, 125, 25, 210, 138, 108, 210, 137, 10, 3, 238, + 23, 221, 125, 25, 202, 222, 10, 3, 238, 23, 221, 125, 25, 199, 209, 10, + 3, 238, 23, 221, 125, 25, 196, 170, 108, 231, 32, 10, 3, 238, 23, 221, + 125, 25, 196, 38, 10, 3, 237, 250, 10, 3, 237, 225, 10, 3, 237, 224, 10, + 3, 237, 223, 10, 3, 237, 44, 10, 3, 237, 26, 10, 3, 236, 255, 10, 3, 237, + 0, 25, 203, 113, 10, 3, 236, 253, 10, 3, 236, 243, 10, 3, 236, 244, 222, + 55, 126, 230, 156, 236, 222, 10, 3, 236, 222, 10, 3, 235, 89, 10, 3, 235, + 90, 139, 235, 89, 10, 3, 235, 90, 230, 155, 10, 3, 235, 90, 203, 94, 10, + 3, 235, 87, 10, 3, 235, 88, 25, 234, 9, 10, 3, 235, 86, 10, 3, 235, 82, + 10, 3, 235, 81, 10, 3, 235, 80, 10, 3, 235, 75, 10, 3, 235, 73, 10, 3, + 235, 74, 230, 155, 10, 3, 235, 74, 230, 156, 230, 155, 10, 3, 235, 72, + 10, 3, 235, 65, 10, 3, 71, 10, 3, 235, 15, 25, 210, 137, 10, 3, 235, 15, + 139, 235, 15, 212, 131, 139, 212, 130, 10, 3, 234, 218, 10, 3, 234, 219, + 25, 42, 108, 230, 105, 108, 238, 32, 10, 3, 234, 219, 25, 231, 200, 10, + 3, 234, 219, 25, 216, 100, 10, 3, 234, 219, 25, 205, 169, 10, 3, 234, + 219, 25, 203, 113, 10, 3, 234, 219, 25, 66, 10, 3, 234, 190, 10, 3, 234, + 177, 10, 3, 234, 140, 10, 3, 234, 103, 10, 3, 234, 104, 25, 231, 208, 10, + 3, 234, 104, 25, 231, 209, 199, 84, 10, 3, 234, 104, 25, 216, 232, 10, 3, + 234, 104, 238, 210, 234, 103, 10, 3, 234, 104, 211, 63, 234, 103, 10, 3, + 234, 104, 201, 189, 10, 3, 234, 31, 10, 3, 234, 28, 10, 3, 234, 9, 10, 3, + 233, 180, 10, 3, 233, 181, 25, 65, 10, 3, 233, 181, 25, 42, 108, 220, 37, + 10, 3, 233, 181, 25, 42, 108, 220, 38, 25, 220, 37, 10, 3, 233, 181, 25, + 251, 132, 10, 3, 233, 181, 25, 249, 135, 10, 3, 233, 181, 25, 235, 74, + 230, 155, 10, 3, 233, 181, 25, 235, 74, 230, 156, 230, 155, 10, 3, 233, + 181, 25, 140, 10, 3, 233, 181, 25, 230, 105, 230, 155, 10, 3, 233, 181, + 25, 223, 202, 230, 155, 10, 3, 233, 181, 25, 222, 54, 10, 3, 233, 181, + 25, 222, 55, 201, 189, 10, 3, 233, 181, 25, 220, 223, 10, 3, 233, 181, + 25, 173, 10, 3, 233, 181, 25, 220, 38, 25, 220, 37, 10, 3, 233, 181, 25, + 219, 146, 10, 3, 233, 181, 25, 218, 225, 10, 3, 233, 181, 25, 196, 169, + 10, 3, 233, 181, 25, 196, 158, 10, 3, 231, 240, 10, 3, 231, 241, 230, + 155, 10, 3, 231, 238, 10, 3, 231, 239, 25, 42, 108, 238, 33, 108, 140, + 10, 3, 231, 239, 25, 42, 108, 140, 10, 3, 231, 239, 25, 42, 108, 223, + 201, 10, 3, 231, 239, 25, 252, 73, 199, 85, 108, 199, 236, 10, 3, 231, + 239, 25, 251, 132, 10, 3, 231, 239, 25, 250, 209, 10, 3, 231, 239, 25, + 250, 208, 108, 231, 222, 10, 3, 231, 239, 25, 249, 135, 10, 3, 231, 239, + 25, 249, 88, 108, 165, 10, 3, 231, 239, 25, 247, 230, 10, 3, 231, 239, + 25, 247, 231, 108, 165, 10, 3, 231, 239, 25, 238, 32, 10, 3, 231, 239, + 25, 237, 44, 10, 3, 231, 239, 25, 237, 0, 25, 203, 113, 10, 3, 231, 239, + 25, 235, 87, 10, 3, 231, 239, 25, 234, 140, 10, 3, 231, 239, 25, 234, + 141, 108, 173, 10, 3, 231, 239, 25, 234, 103, 10, 3, 231, 239, 25, 234, + 104, 25, 231, 209, 199, 84, 10, 3, 231, 239, 25, 231, 209, 199, 84, 10, + 3, 231, 239, 25, 231, 200, 10, 3, 231, 239, 25, 231, 53, 10, 3, 231, 239, + 25, 231, 51, 10, 3, 231, 239, 25, 231, 52, 108, 65, 10, 3, 231, 239, 25, + 231, 33, 108, 201, 4, 10, 3, 231, 239, 25, 230, 105, 108, 218, 226, 108, + 234, 9, 10, 3, 231, 239, 25, 230, 73, 10, 3, 231, 239, 25, 230, 74, 108, + 173, 10, 3, 231, 239, 25, 229, 159, 108, 219, 146, 10, 3, 231, 239, 25, + 228, 151, 10, 3, 231, 239, 25, 223, 202, 230, 155, 10, 3, 231, 239, 25, + 223, 63, 108, 228, 160, 108, 250, 209, 10, 3, 231, 239, 25, 222, 96, 10, + 3, 231, 239, 25, 222, 54, 10, 3, 231, 239, 25, 221, 152, 10, 3, 231, 239, + 25, 221, 153, 108, 220, 37, 10, 3, 231, 239, 25, 220, 224, 108, 251, 132, + 10, 3, 231, 239, 25, 173, 10, 3, 231, 239, 25, 216, 233, 108, 234, 103, + 10, 3, 231, 239, 25, 216, 100, 10, 3, 231, 239, 25, 212, 130, 10, 3, 231, + 239, 25, 212, 131, 139, 212, 130, 10, 3, 231, 239, 25, 168, 10, 3, 231, + 239, 25, 205, 169, 10, 3, 231, 239, 25, 205, 127, 10, 3, 231, 239, 25, + 203, 113, 10, 3, 231, 239, 25, 203, 114, 108, 197, 64, 10, 3, 231, 239, + 25, 203, 79, 10, 3, 231, 239, 25, 200, 204, 10, 3, 231, 239, 25, 199, + 209, 10, 3, 231, 239, 25, 66, 10, 3, 231, 239, 25, 196, 158, 10, 3, 231, + 239, 25, 196, 159, 108, 235, 89, 10, 3, 231, 239, 139, 231, 238, 10, 3, + 231, 233, 10, 3, 231, 234, 238, 210, 231, 233, 10, 3, 231, 231, 10, 3, + 231, 232, 139, 231, 232, 231, 201, 139, 231, 200, 10, 3, 231, 222, 10, 3, + 231, 223, 231, 232, 139, 231, 232, 231, 201, 139, 231, 200, 10, 3, 231, + 221, 10, 3, 231, 219, 10, 3, 231, 210, 10, 3, 231, 208, 10, 3, 231, 209, + 199, 84, 10, 3, 231, 209, 139, 231, 208, 10, 3, 231, 209, 238, 210, 231, + 208, 10, 3, 231, 200, 10, 3, 231, 199, 10, 3, 231, 193, 10, 3, 231, 134, + 10, 3, 231, 135, 25, 220, 197, 10, 3, 231, 53, 10, 3, 231, 54, 25, 71, + 10, 3, 231, 54, 25, 66, 10, 3, 231, 54, 238, 210, 231, 53, 10, 3, 231, + 51, 10, 3, 231, 52, 139, 231, 51, 10, 3, 231, 52, 238, 210, 231, 51, 10, + 3, 231, 48, 10, 3, 231, 32, 10, 3, 231, 33, 230, 155, 10, 3, 231, 30, 10, + 3, 231, 31, 25, 42, 108, 223, 201, 10, 3, 231, 31, 25, 231, 209, 199, 84, + 10, 3, 231, 31, 25, 223, 201, 10, 3, 231, 31, 25, 218, 226, 108, 223, + 201, 10, 3, 231, 31, 25, 168, 10, 3, 231, 25, 10, 3, 231, 23, 10, 3, 231, + 24, 238, 210, 231, 23, 10, 3, 231, 24, 25, 249, 135, 10, 3, 231, 24, 25, + 199, 209, 10, 3, 231, 24, 199, 84, 10, 3, 230, 179, 10, 3, 230, 180, 238, + 210, 230, 179, 10, 3, 230, 177, 10, 3, 230, 178, 25, 222, 96, 10, 3, 230, + 178, 25, 222, 97, 25, 223, 202, 230, 155, 10, 3, 230, 178, 25, 212, 130, + 10, 3, 230, 178, 25, 205, 170, 108, 197, 82, 10, 3, 230, 178, 230, 155, + 10, 3, 230, 168, 10, 3, 230, 169, 25, 42, 108, 220, 197, 10, 3, 230, 169, + 25, 220, 197, 10, 3, 230, 169, 139, 230, 169, 218, 216, 10, 3, 230, 160, + 10, 3, 230, 158, 10, 3, 230, 159, 25, 203, 113, 10, 3, 230, 149, 10, 3, + 230, 148, 10, 3, 230, 143, 10, 3, 230, 142, 10, 3, 140, 10, 3, 230, 105, + 199, 84, 10, 3, 230, 105, 230, 155, 10, 3, 230, 73, 10, 3, 229, 158, 10, + 3, 229, 159, 25, 250, 209, 10, 3, 229, 159, 25, 250, 207, 10, 3, 229, + 159, 25, 249, 135, 10, 3, 229, 159, 25, 236, 222, 10, 3, 229, 159, 25, + 231, 231, 10, 3, 229, 159, 25, 221, 141, 10, 3, 229, 159, 25, 212, 130, + 10, 3, 229, 159, 25, 203, 113, 10, 3, 229, 159, 25, 66, 10, 3, 228, 159, + 10, 3, 228, 151, 10, 3, 228, 152, 25, 251, 132, 10, 3, 228, 152, 25, 230, + 73, 10, 3, 228, 152, 25, 222, 54, 10, 3, 228, 152, 25, 219, 89, 10, 3, + 228, 152, 25, 196, 158, 10, 3, 228, 146, 10, 3, 68, 10, 3, 228, 74, 65, + 10, 3, 228, 30, 10, 3, 223, 229, 10, 3, 223, 230, 139, 223, 230, 247, + 230, 10, 3, 223, 230, 139, 223, 230, 201, 189, 10, 3, 223, 204, 10, 3, + 223, 201, 10, 3, 223, 202, 237, 26, 10, 3, 223, 202, 207, 1, 10, 3, 223, + 202, 139, 223, 202, 203, 63, 139, 203, 63, 196, 159, 139, 196, 158, 10, + 3, 223, 202, 230, 155, 10, 3, 223, 191, 10, 3, 223, 192, 25, 231, 209, + 199, 84, 10, 3, 223, 190, 10, 3, 223, 180, 10, 3, 223, 181, 25, 199, 209, + 10, 3, 223, 181, 238, 210, 223, 180, 10, 3, 223, 181, 211, 63, 223, 180, + 10, 3, 223, 181, 201, 189, 10, 3, 223, 172, 10, 3, 223, 162, 10, 3, 223, + 77, 10, 3, 223, 62, 10, 3, 155, 10, 3, 222, 142, 25, 65, 10, 3, 222, 142, + 25, 252, 42, 10, 3, 222, 142, 25, 252, 43, 108, 220, 223, 10, 3, 222, + 142, 25, 250, 207, 10, 3, 222, 142, 25, 249, 135, 10, 3, 222, 142, 25, + 249, 114, 10, 3, 222, 142, 25, 164, 10, 3, 222, 142, 25, 248, 188, 10, 3, + 222, 142, 25, 234, 28, 10, 3, 222, 142, 25, 234, 9, 10, 3, 222, 142, 25, + 231, 240, 10, 3, 222, 142, 25, 231, 222, 10, 3, 222, 142, 25, 231, 209, + 199, 84, 10, 3, 222, 142, 25, 231, 200, 10, 3, 222, 142, 25, 231, 201, + 108, 203, 164, 108, 65, 10, 3, 222, 142, 25, 231, 53, 10, 3, 222, 142, + 25, 231, 32, 10, 3, 222, 142, 25, 231, 24, 108, 205, 127, 10, 3, 222, + 142, 25, 231, 24, 238, 210, 231, 23, 10, 3, 222, 142, 25, 230, 179, 10, + 3, 222, 142, 25, 230, 148, 10, 3, 222, 142, 25, 223, 201, 10, 3, 222, + 142, 25, 223, 180, 10, 3, 222, 142, 25, 222, 96, 10, 3, 222, 142, 25, + 221, 166, 10, 3, 222, 142, 25, 221, 152, 10, 3, 222, 142, 25, 219, 146, + 10, 3, 222, 142, 25, 218, 225, 10, 3, 222, 142, 25, 216, 232, 10, 3, 222, + 142, 25, 216, 233, 108, 235, 89, 10, 3, 222, 142, 25, 216, 233, 108, 231, + 53, 10, 3, 222, 142, 25, 216, 233, 108, 199, 145, 10, 3, 222, 142, 25, + 216, 100, 10, 3, 222, 142, 25, 216, 101, 108, 212, 125, 10, 3, 222, 142, + 25, 214, 121, 10, 3, 222, 142, 25, 212, 130, 10, 3, 222, 142, 25, 209, + 185, 10, 3, 222, 142, 25, 206, 68, 10, 3, 222, 142, 25, 188, 10, 3, 222, + 142, 25, 205, 127, 10, 3, 222, 142, 25, 203, 165, 10, 3, 222, 142, 25, + 203, 113, 10, 3, 222, 142, 25, 203, 79, 10, 3, 222, 142, 25, 203, 5, 10, + 3, 222, 142, 25, 202, 201, 10, 3, 222, 142, 25, 200, 213, 10, 3, 222, + 142, 25, 199, 179, 10, 3, 222, 142, 25, 66, 10, 3, 222, 142, 25, 196, + 169, 10, 3, 222, 142, 25, 196, 158, 10, 3, 222, 142, 25, 196, 116, 25, + 168, 10, 3, 222, 142, 25, 196, 38, 10, 3, 222, 142, 25, 191, 30, 10, 3, + 222, 128, 10, 3, 222, 129, 238, 210, 222, 128, 10, 3, 222, 117, 10, 3, + 222, 113, 10, 3, 222, 111, 10, 3, 222, 110, 10, 3, 222, 108, 10, 3, 222, + 109, 139, 222, 108, 10, 3, 222, 96, 10, 3, 222, 97, 25, 223, 202, 230, + 155, 10, 3, 222, 91, 10, 3, 222, 92, 25, 249, 135, 10, 3, 222, 92, 238, + 210, 222, 91, 10, 3, 222, 89, 10, 3, 222, 88, 10, 3, 222, 54, 10, 3, 222, + 55, 220, 105, 25, 126, 139, 220, 105, 25, 66, 10, 3, 222, 55, 139, 222, + 55, 220, 105, 25, 126, 139, 220, 105, 25, 66, 10, 3, 221, 242, 10, 3, + 221, 166, 10, 3, 221, 167, 25, 249, 135, 10, 3, 221, 167, 25, 66, 10, 3, + 221, 167, 25, 196, 158, 10, 3, 221, 152, 10, 3, 221, 141, 10, 3, 221, + 127, 10, 3, 221, 126, 10, 3, 221, 124, 10, 3, 221, 125, 139, 221, 124, + 10, 3, 220, 232, 10, 3, 220, 233, 139, 229, 159, 25, 250, 208, 220, 233, + 139, 229, 159, 25, 250, 207, 10, 3, 220, 223, 10, 3, 220, 221, 10, 3, + 220, 222, 195, 168, 20, 10, 3, 220, 220, 10, 3, 220, 211, 10, 3, 220, + 212, 230, 155, 10, 3, 220, 210, 10, 3, 220, 197, 10, 3, 220, 198, 211, + 63, 220, 197, 10, 3, 220, 190, 10, 3, 220, 167, 10, 3, 173, 10, 3, 220, + 104, 10, 3, 220, 105, 25, 65, 10, 3, 220, 105, 25, 42, 108, 238, 33, 108, + 140, 10, 3, 220, 105, 25, 42, 108, 231, 200, 10, 3, 220, 105, 25, 42, + 108, 220, 37, 10, 3, 220, 105, 25, 251, 207, 10, 3, 220, 105, 25, 251, + 132, 10, 3, 220, 105, 25, 250, 210, 191, 26, 199, 84, 10, 3, 220, 105, + 25, 249, 135, 10, 3, 220, 105, 25, 248, 188, 10, 3, 220, 105, 25, 237, + 225, 10, 3, 220, 105, 25, 234, 103, 10, 3, 220, 105, 25, 231, 240, 10, 3, + 220, 105, 25, 231, 200, 10, 3, 220, 105, 25, 230, 168, 10, 3, 220, 105, + 25, 230, 169, 108, 230, 168, 10, 3, 220, 105, 25, 140, 10, 3, 220, 105, + 25, 230, 73, 10, 3, 220, 105, 25, 229, 159, 25, 212, 130, 10, 3, 220, + 105, 25, 223, 202, 230, 155, 10, 3, 220, 105, 25, 223, 180, 10, 3, 220, + 105, 25, 223, 181, 108, 140, 10, 3, 220, 105, 25, 223, 181, 108, 218, + 225, 10, 3, 220, 105, 25, 221, 166, 10, 3, 220, 105, 25, 221, 141, 10, 3, + 220, 105, 25, 220, 223, 10, 3, 220, 105, 25, 220, 211, 10, 3, 220, 105, + 25, 220, 212, 108, 229, 159, 108, 65, 10, 3, 220, 105, 25, 220, 104, 10, + 3, 220, 105, 25, 219, 89, 10, 3, 220, 105, 25, 218, 225, 10, 3, 220, 105, + 25, 218, 210, 10, 3, 220, 105, 25, 216, 232, 10, 3, 220, 105, 25, 216, + 233, 108, 234, 103, 10, 3, 220, 105, 25, 215, 101, 10, 3, 220, 105, 25, + 214, 121, 10, 3, 220, 105, 25, 203, 114, 108, 200, 204, 10, 3, 220, 105, + 25, 203, 59, 108, 231, 24, 108, 234, 28, 10, 3, 220, 105, 25, 203, 59, + 108, 231, 24, 199, 84, 10, 3, 220, 105, 25, 203, 3, 10, 3, 220, 105, 25, + 203, 4, 108, 203, 3, 10, 3, 220, 105, 25, 200, 204, 10, 3, 220, 105, 25, + 199, 223, 10, 3, 220, 105, 25, 199, 209, 10, 3, 220, 105, 25, 199, 146, + 108, 42, 108, 201, 5, 108, 180, 10, 3, 220, 105, 25, 66, 10, 3, 220, 105, + 25, 126, 108, 65, 10, 3, 220, 105, 25, 126, 108, 126, 108, 66, 10, 3, + 220, 105, 25, 196, 170, 108, 250, 209, 10, 3, 220, 105, 25, 196, 158, 10, + 3, 220, 105, 25, 196, 38, 10, 3, 220, 105, 201, 189, 10, 3, 220, 102, 10, + 3, 220, 103, 25, 203, 113, 10, 3, 220, 103, 25, 203, 114, 108, 200, 204, + 10, 3, 220, 103, 230, 155, 10, 3, 220, 103, 230, 156, 139, 220, 103, 230, + 156, 203, 113, 10, 3, 220, 98, 10, 3, 220, 37, 10, 3, 220, 38, 25, 220, + 37, 10, 3, 220, 35, 10, 3, 220, 36, 25, 220, 197, 10, 3, 220, 36, 25, + 220, 198, 108, 206, 68, 10, 3, 219, 146, 10, 3, 219, 127, 10, 3, 219, + 115, 10, 3, 219, 89, 10, 3, 218, 225, 10, 3, 218, 226, 25, 249, 135, 10, + 3, 218, 223, 10, 3, 218, 224, 25, 251, 207, 10, 3, 218, 224, 25, 249, + 135, 10, 3, 218, 224, 25, 234, 9, 10, 3, 218, 224, 25, 234, 10, 199, 84, + 10, 3, 218, 224, 25, 231, 209, 199, 84, 10, 3, 218, 224, 25, 229, 159, + 25, 249, 135, 10, 3, 218, 224, 25, 223, 180, 10, 3, 218, 224, 25, 222, + 113, 10, 3, 218, 224, 25, 222, 111, 10, 3, 218, 224, 25, 222, 112, 108, + 250, 209, 10, 3, 218, 224, 25, 221, 166, 10, 3, 218, 224, 25, 220, 126, + 108, 250, 209, 10, 3, 218, 224, 25, 220, 104, 10, 3, 218, 224, 25, 216, + 233, 108, 234, 103, 10, 3, 218, 224, 25, 214, 121, 10, 3, 218, 224, 25, + 212, 178, 10, 3, 218, 224, 25, 202, 223, 108, 250, 209, 10, 3, 218, 224, + 25, 202, 192, 108, 248, 10, 10, 3, 218, 224, 25, 197, 82, 10, 3, 218, + 224, 199, 84, 10, 3, 218, 224, 238, 210, 218, 223, 10, 3, 218, 224, 211, + 63, 218, 223, 10, 3, 218, 224, 201, 189, 10, 3, 218, 224, 203, 94, 10, 3, + 218, 222, 10, 3, 218, 216, 10, 3, 218, 217, 139, 218, 216, 10, 3, 218, + 217, 211, 63, 218, 216, 10, 3, 218, 217, 203, 94, 10, 3, 218, 213, 10, 3, + 218, 210, 10, 3, 218, 208, 10, 3, 218, 209, 139, 218, 208, 10, 3, 218, + 209, 139, 218, 209, 231, 201, 139, 231, 200, 10, 3, 174, 10, 3, 217, 160, + 25, 199, 209, 10, 3, 217, 160, 230, 155, 10, 3, 217, 152, 10, 3, 217, + 120, 10, 3, 217, 65, 10, 3, 217, 39, 10, 3, 217, 38, 10, 3, 216, 232, 10, + 3, 216, 173, 10, 3, 216, 100, 10, 3, 216, 44, 10, 3, 215, 155, 10, 3, + 215, 156, 139, 215, 155, 10, 3, 215, 140, 10, 3, 215, 141, 230, 155, 10, + 3, 215, 119, 10, 3, 215, 105, 10, 3, 215, 101, 10, 3, 215, 102, 25, 65, + 10, 3, 215, 102, 25, 220, 197, 10, 3, 215, 102, 25, 191, 123, 10, 3, 215, + 102, 139, 215, 101, 10, 3, 215, 102, 139, 215, 102, 25, 42, 108, 180, 10, + 3, 215, 102, 238, 210, 215, 101, 10, 3, 215, 99, 10, 3, 215, 100, 25, 65, + 10, 3, 215, 100, 25, 42, 108, 237, 44, 10, 3, 215, 100, 25, 237, 44, 10, + 3, 215, 100, 230, 155, 10, 3, 180, 10, 3, 214, 253, 10, 3, 214, 240, 10, + 3, 214, 241, 223, 92, 10, 3, 214, 241, 25, 203, 6, 199, 84, 10, 3, 214, + 241, 211, 63, 214, 240, 10, 3, 214, 239, 10, 3, 214, 231, 212, 116, 10, + 3, 214, 230, 10, 3, 214, 229, 10, 3, 214, 121, 10, 3, 214, 122, 25, 65, + 10, 3, 214, 122, 25, 196, 158, 10, 3, 214, 122, 203, 94, 10, 3, 213, 219, + 10, 3, 213, 220, 25, 71, 10, 3, 213, 210, 10, 3, 213, 180, 10, 3, 213, + 181, 25, 231, 209, 199, 84, 10, 3, 213, 181, 25, 231, 201, 108, 231, 209, + 199, 84, 10, 3, 213, 176, 10, 3, 213, 177, 25, 251, 132, 10, 3, 213, 177, + 25, 250, 209, 10, 3, 213, 177, 25, 250, 210, 108, 250, 209, 10, 3, 213, + 177, 25, 230, 168, 10, 3, 213, 177, 25, 216, 233, 108, 231, 209, 199, 84, + 10, 3, 213, 177, 25, 214, 121, 10, 3, 213, 177, 25, 212, 130, 10, 3, 213, + 177, 25, 203, 113, 10, 3, 213, 177, 25, 203, 114, 108, 42, 251, 132, 10, + 3, 213, 177, 25, 203, 114, 108, 250, 209, 10, 3, 213, 177, 25, 203, 114, + 108, 250, 210, 108, 250, 209, 10, 3, 213, 177, 25, 196, 170, 108, 250, + 209, 10, 3, 213, 177, 25, 196, 38, 10, 3, 213, 163, 10, 3, 212, 178, 10, + 3, 212, 147, 10, 3, 212, 130, 10, 3, 212, 131, 220, 103, 25, 231, 200, + 10, 3, 212, 131, 220, 103, 25, 217, 39, 10, 3, 212, 131, 220, 103, 25, + 205, 169, 10, 3, 212, 131, 220, 103, 25, 205, 170, 139, 212, 131, 220, + 103, 25, 205, 169, 10, 3, 212, 131, 220, 103, 25, 196, 38, 10, 3, 212, + 131, 199, 84, 10, 3, 212, 131, 139, 212, 130, 10, 3, 212, 131, 238, 210, + 212, 130, 10, 3, 212, 131, 238, 210, 212, 131, 220, 103, 139, 220, 102, + 10, 3, 212, 125, 10, 3, 212, 126, 252, 73, 25, 250, 203, 10, 3, 212, 126, + 252, 73, 25, 248, 188, 10, 3, 212, 126, 252, 73, 25, 235, 82, 10, 3, 212, + 126, 252, 73, 25, 230, 168, 10, 3, 212, 126, 252, 73, 25, 223, 202, 230, + 155, 10, 3, 212, 126, 252, 73, 25, 222, 111, 10, 3, 212, 126, 252, 73, + 25, 173, 10, 3, 212, 126, 252, 73, 25, 214, 121, 10, 3, 212, 126, 252, + 73, 25, 202, 189, 10, 3, 212, 126, 252, 73, 25, 196, 169, 10, 3, 212, + 126, 221, 125, 25, 248, 188, 10, 3, 212, 126, 221, 125, 25, 248, 189, 66, + 10, 3, 168, 10, 3, 210, 210, 10, 3, 210, 166, 10, 3, 210, 137, 10, 3, + 209, 243, 10, 3, 209, 185, 10, 3, 209, 186, 25, 65, 10, 3, 209, 186, 25, + 252, 155, 10, 3, 209, 186, 25, 248, 188, 10, 3, 209, 186, 25, 248, 10, + 10, 3, 209, 186, 25, 71, 10, 3, 209, 186, 25, 68, 10, 3, 209, 186, 25, + 228, 30, 10, 3, 209, 186, 25, 66, 10, 3, 209, 186, 25, 196, 169, 10, 3, + 209, 186, 238, 210, 209, 185, 10, 3, 209, 121, 10, 3, 209, 122, 25, 222, + 91, 10, 3, 209, 122, 25, 196, 158, 10, 3, 209, 122, 25, 191, 123, 10, 3, + 209, 122, 211, 63, 209, 121, 10, 3, 165, 10, 3, 207, 176, 10, 3, 207, 1, + 10, 3, 206, 68, 10, 3, 188, 10, 3, 205, 186, 212, 116, 10, 3, 205, 185, + 10, 3, 205, 186, 25, 65, 10, 3, 205, 186, 25, 235, 89, 10, 3, 205, 186, + 25, 235, 87, 10, 3, 205, 186, 25, 140, 10, 3, 205, 186, 25, 222, 96, 10, + 3, 205, 186, 25, 220, 197, 10, 3, 205, 186, 25, 218, 208, 10, 3, 205, + 186, 25, 216, 100, 10, 3, 205, 186, 25, 212, 130, 10, 3, 205, 186, 25, + 205, 169, 10, 3, 205, 186, 25, 203, 79, 10, 3, 205, 186, 25, 199, 236, + 10, 3, 205, 186, 25, 196, 169, 10, 3, 205, 186, 25, 196, 164, 10, 3, 205, + 186, 25, 196, 120, 10, 3, 205, 186, 25, 196, 62, 10, 3, 205, 186, 25, + 196, 38, 10, 3, 205, 186, 139, 205, 185, 10, 3, 205, 186, 230, 155, 10, + 3, 205, 169, 10, 3, 205, 170, 220, 105, 25, 250, 207, 10, 3, 205, 136, + 10, 3, 205, 127, 10, 3, 203, 165, 10, 3, 203, 163, 10, 3, 203, 164, 25, + 65, 10, 3, 203, 164, 25, 249, 135, 10, 3, 203, 164, 25, 231, 23, 10, 3, + 203, 164, 25, 214, 121, 10, 3, 203, 164, 25, 203, 3, 10, 3, 203, 164, 25, + 197, 64, 10, 3, 203, 164, 25, 66, 10, 3, 203, 164, 25, 126, 108, 65, 10, + 3, 203, 161, 10, 3, 203, 159, 10, 3, 203, 131, 10, 3, 203, 113, 10, 3, + 203, 114, 228, 159, 10, 3, 203, 114, 139, 203, 114, 231, 232, 139, 231, + 232, 231, 201, 139, 231, 200, 10, 3, 203, 114, 139, 203, 114, 199, 237, + 139, 199, 237, 231, 201, 139, 231, 200, 10, 3, 203, 106, 10, 3, 203, 101, + 10, 3, 203, 97, 10, 3, 203, 96, 10, 3, 203, 93, 10, 3, 203, 79, 10, 3, + 203, 80, 25, 65, 10, 3, 203, 80, 25, 223, 180, 10, 3, 203, 73, 10, 3, + 203, 74, 25, 65, 10, 3, 203, 74, 25, 249, 115, 10, 3, 203, 74, 25, 247, + 242, 10, 3, 203, 74, 25, 236, 243, 10, 3, 203, 74, 25, 231, 200, 10, 3, + 203, 74, 25, 223, 201, 10, 3, 203, 74, 25, 223, 202, 230, 155, 10, 3, + 203, 74, 25, 220, 190, 10, 3, 203, 74, 25, 218, 210, 10, 3, 203, 74, 25, + 215, 140, 10, 3, 203, 74, 25, 205, 169, 10, 3, 203, 67, 10, 3, 203, 62, + 10, 3, 203, 63, 199, 84, 10, 3, 203, 63, 139, 203, 63, 247, 231, 139, + 247, 230, 10, 3, 203, 58, 10, 3, 203, 5, 10, 3, 203, 6, 139, 223, 93, + 203, 5, 10, 3, 203, 3, 10, 3, 203, 1, 10, 3, 202, 222, 10, 3, 202, 223, + 230, 155, 10, 3, 202, 201, 10, 3, 202, 199, 10, 3, 202, 200, 139, 202, + 200, 203, 3, 10, 3, 202, 191, 10, 3, 202, 189, 10, 3, 201, 4, 10, 3, 201, + 5, 139, 201, 4, 10, 3, 200, 216, 10, 3, 200, 215, 10, 3, 200, 213, 10, 3, + 200, 204, 10, 3, 200, 203, 10, 3, 200, 175, 10, 3, 200, 174, 10, 3, 190, + 190, 10, 3, 199, 252, 250, 193, 10, 3, 199, 252, 25, 229, 158, 10, 3, + 199, 252, 25, 216, 100, 10, 3, 199, 252, 230, 155, 10, 3, 199, 236, 10, + 3, 199, 237, 139, 199, 237, 213, 220, 139, 213, 220, 236, 223, 139, 236, + 222, 10, 3, 199, 237, 201, 189, 10, 3, 199, 223, 10, 3, 199, 224, 25, + 248, 188, 10, 3, 199, 224, 25, 230, 168, 10, 3, 199, 224, 25, 203, 113, + 10, 3, 199, 224, 25, 203, 5, 10, 3, 199, 224, 25, 197, 82, 10, 3, 199, + 224, 25, 196, 158, 10, 3, 199, 209, 10, 3, 199, 179, 10, 3, 199, 145, 10, + 3, 199, 146, 230, 155, 10, 3, 198, 193, 10, 3, 198, 194, 199, 84, 10, 3, + 198, 154, 10, 3, 198, 131, 10, 3, 198, 132, 25, 199, 209, 10, 3, 198, + 132, 139, 198, 131, 10, 3, 198, 132, 139, 198, 132, 231, 232, 139, 231, + 232, 231, 201, 139, 231, 200, 10, 3, 197, 94, 10, 3, 197, 82, 10, 3, 197, + 80, 10, 3, 197, 76, 10, 3, 197, 64, 10, 3, 197, 65, 139, 197, 65, 191, + 124, 139, 191, 123, 10, 3, 66, 10, 3, 126, 230, 168, 10, 3, 126, 126, 66, + 10, 3, 126, 139, 126, 210, 221, 139, 210, 221, 231, 201, 139, 231, 200, + 10, 3, 126, 139, 126, 200, 176, 139, 200, 175, 10, 3, 126, 139, 126, 126, + 207, 18, 139, 126, 207, 17, 10, 3, 196, 169, 10, 3, 196, 164, 10, 3, 196, + 158, 10, 3, 196, 159, 220, 190, 10, 3, 196, 159, 25, 249, 135, 10, 3, + 196, 159, 25, 216, 100, 10, 3, 196, 159, 25, 126, 108, 126, 108, 66, 10, + 3, 196, 159, 25, 126, 108, 126, 108, 126, 230, 155, 10, 3, 196, 159, 230, + 155, 10, 3, 196, 159, 203, 94, 10, 3, 196, 159, 203, 95, 25, 249, 135, + 10, 3, 196, 153, 10, 3, 196, 120, 10, 3, 196, 121, 25, 220, 104, 10, 3, + 196, 121, 25, 216, 233, 108, 238, 32, 10, 3, 196, 121, 25, 203, 163, 10, + 3, 196, 121, 25, 66, 10, 3, 196, 119, 10, 3, 196, 115, 10, 3, 196, 116, + 25, 222, 54, 10, 3, 196, 116, 25, 168, 10, 3, 196, 113, 10, 3, 196, 114, + 230, 155, 10, 3, 196, 62, 10, 3, 196, 63, 238, 210, 196, 62, 10, 3, 196, + 63, 203, 94, 10, 3, 196, 60, 10, 3, 196, 61, 25, 42, 108, 140, 10, 3, + 196, 61, 25, 42, 108, 180, 10, 3, 196, 61, 25, 251, 207, 10, 3, 196, 61, + 25, 140, 10, 3, 196, 61, 25, 212, 130, 10, 3, 196, 61, 25, 196, 169, 10, + 3, 196, 61, 25, 196, 170, 108, 250, 209, 10, 3, 196, 61, 25, 196, 170, + 108, 248, 188, 10, 3, 196, 59, 10, 3, 196, 56, 10, 3, 196, 55, 10, 3, + 196, 51, 10, 3, 196, 52, 25, 65, 10, 3, 196, 52, 25, 250, 203, 10, 3, + 196, 52, 25, 164, 10, 3, 196, 52, 25, 235, 75, 10, 3, 196, 52, 25, 231, + 240, 10, 3, 196, 52, 25, 231, 222, 10, 3, 196, 52, 25, 231, 209, 199, 84, + 10, 3, 196, 52, 25, 231, 200, 10, 3, 196, 52, 25, 230, 179, 10, 3, 196, + 52, 25, 140, 10, 3, 196, 52, 25, 223, 201, 10, 3, 196, 52, 25, 223, 180, + 10, 3, 196, 52, 25, 223, 62, 10, 3, 196, 52, 25, 221, 166, 10, 3, 196, + 52, 25, 218, 208, 10, 3, 196, 52, 25, 216, 44, 10, 3, 196, 52, 25, 168, + 10, 3, 196, 52, 25, 203, 113, 10, 3, 196, 52, 25, 202, 199, 10, 3, 196, + 52, 25, 197, 94, 10, 3, 196, 52, 25, 126, 108, 230, 168, 10, 3, 196, 52, + 25, 196, 158, 10, 3, 196, 52, 25, 196, 49, 10, 3, 196, 49, 10, 3, 196, + 50, 25, 66, 10, 3, 196, 38, 10, 3, 196, 39, 25, 65, 10, 3, 196, 39, 25, + 220, 232, 10, 3, 196, 39, 25, 220, 197, 10, 3, 196, 39, 25, 199, 209, 10, + 3, 196, 34, 10, 3, 196, 37, 10, 3, 196, 35, 10, 3, 196, 31, 10, 3, 196, + 16, 10, 3, 196, 17, 25, 222, 54, 10, 3, 196, 14, 10, 3, 191, 123, 10, 3, + 191, 124, 199, 84, 10, 3, 191, 124, 112, 25, 220, 197, 10, 3, 191, 118, + 10, 3, 191, 107, 10, 3, 191, 86, 10, 3, 191, 30, 10, 3, 191, 31, 139, + 191, 30, 10, 3, 191, 29, 10, 3, 191, 27, 10, 3, 191, 28, 222, 116, 199, + 84, 10, 3, 191, 22, 10, 3, 191, 13, 10, 3, 190, 251, 10, 3, 190, 249, 10, + 3, 190, 250, 25, 65, 10, 3, 190, 248, 10, 3, 190, 247, 10, 3, 222, 79, + 234, 137, 10, 3, 252, 156, 25, 212, 130, 10, 3, 252, 73, 25, 65, 10, 3, + 251, 146, 25, 220, 213, 10, 3, 238, 23, 221, 125, 25, 196, 170, 108, 217, + 39, 10, 3, 238, 21, 10, 3, 236, 223, 108, 203, 5, 10, 3, 235, 88, 25, + 203, 113, 10, 3, 233, 181, 25, 230, 168, 10, 3, 233, 181, 25, 203, 113, + 10, 3, 231, 239, 25, 251, 133, 108, 222, 97, 108, 65, 10, 3, 231, 239, + 25, 250, 207, 10, 3, 231, 164, 10, 3, 231, 42, 10, 3, 228, 131, 10, 3, + 222, 142, 25, 251, 91, 10, 3, 222, 142, 25, 250, 206, 10, 3, 222, 142, + 25, 231, 23, 10, 3, 222, 142, 25, 230, 168, 10, 3, 222, 142, 25, 229, + 159, 25, 250, 207, 10, 3, 222, 142, 25, 218, 208, 10, 3, 222, 142, 25, + 168, 10, 3, 222, 142, 25, 202, 253, 10, 3, 222, 142, 25, 197, 94, 10, 3, + 222, 142, 25, 196, 60, 10, 3, 220, 105, 25, 231, 53, 10, 3, 218, 224, + 203, 95, 25, 249, 135, 10, 3, 218, 224, 25, 234, 10, 108, 220, 37, 10, 3, + 218, 224, 25, 203, 5, 10, 3, 216, 172, 10, 3, 215, 100, 25, 191, 123, 10, + 3, 214, 252, 10, 3, 213, 179, 10, 3, 213, 178, 10, 3, 213, 177, 25, 249, + 115, 10, 3, 213, 177, 25, 231, 53, 10, 3, 212, 148, 206, 122, 213, 170, + 237, 124, 10, 3, 209, 244, 250, 193, 10, 3, 209, 125, 10, 3, 205, 186, + 25, 223, 202, 230, 155, 10, 3, 198, 185, 10, 3, 196, 121, 25, 216, 232, + 10, 3, 126, 66, 10, 167, 3, 105, 250, 209, 10, 167, 3, 115, 250, 209, 10, + 167, 3, 232, 128, 250, 209, 10, 167, 3, 232, 226, 250, 209, 10, 167, 3, + 202, 136, 250, 209, 10, 167, 3, 203, 247, 250, 209, 10, 167, 3, 234, 164, + 250, 209, 10, 167, 3, 213, 175, 250, 209, 10, 167, 3, 115, 236, 222, 10, + 167, 3, 232, 128, 236, 222, 10, 167, 3, 232, 226, 236, 222, 10, 167, 3, + 202, 136, 236, 222, 10, 167, 3, 203, 247, 236, 222, 10, 167, 3, 234, 164, + 236, 222, 10, 167, 3, 213, 175, 236, 222, 10, 167, 3, 232, 128, 66, 10, + 167, 3, 232, 226, 66, 10, 167, 3, 202, 136, 66, 10, 167, 3, 203, 247, 66, + 10, 167, 3, 234, 164, 66, 10, 167, 3, 213, 175, 66, 10, 167, 3, 91, 231, + 136, 10, 167, 3, 105, 231, 136, 10, 167, 3, 115, 231, 136, 10, 167, 3, + 232, 128, 231, 136, 10, 167, 3, 232, 226, 231, 136, 10, 167, 3, 202, 136, + 231, 136, 10, 167, 3, 203, 247, 231, 136, 10, 167, 3, 234, 164, 231, 136, + 10, 167, 3, 213, 175, 231, 136, 10, 167, 3, 91, 231, 133, 10, 167, 3, + 105, 231, 133, 10, 167, 3, 115, 231, 133, 10, 167, 3, 232, 128, 231, 133, + 10, 167, 3, 232, 226, 231, 133, 10, 167, 3, 105, 203, 131, 10, 167, 3, + 115, 203, 131, 10, 167, 3, 115, 203, 132, 195, 168, 20, 10, 167, 3, 232, + 128, 203, 131, 10, 167, 3, 232, 226, 203, 131, 10, 167, 3, 202, 136, 203, + 131, 10, 167, 3, 203, 247, 203, 131, 10, 167, 3, 234, 164, 203, 131, 10, + 167, 3, 213, 175, 203, 131, 10, 167, 3, 91, 203, 124, 10, 167, 3, 105, + 203, 124, 10, 167, 3, 115, 203, 124, 10, 167, 3, 115, 203, 125, 195, 168, + 20, 10, 167, 3, 232, 128, 203, 124, 10, 167, 3, 232, 226, 203, 124, 10, + 167, 3, 203, 132, 25, 231, 223, 108, 236, 222, 10, 167, 3, 203, 132, 25, + 231, 223, 108, 216, 44, 10, 167, 3, 91, 247, 226, 10, 167, 3, 105, 247, + 226, 10, 167, 3, 115, 247, 226, 10, 167, 3, 115, 247, 227, 195, 168, 20, + 10, 167, 3, 232, 128, 247, 226, 10, 167, 3, 232, 226, 247, 226, 10, 167, + 3, 115, 195, 168, 232, 146, 234, 11, 10, 167, 3, 115, 195, 168, 232, 146, + 234, 8, 10, 167, 3, 232, 128, 195, 168, 232, 146, 219, 116, 10, 167, 3, + 232, 128, 195, 168, 232, 146, 219, 114, 10, 167, 3, 232, 128, 195, 168, + 232, 146, 219, 117, 65, 10, 167, 3, 232, 128, 195, 168, 232, 146, 219, + 117, 250, 120, 10, 167, 3, 202, 136, 195, 168, 232, 146, 250, 205, 10, + 167, 3, 203, 247, 195, 168, 232, 146, 223, 171, 10, 167, 3, 203, 247, + 195, 168, 232, 146, 223, 173, 65, 10, 167, 3, 203, 247, 195, 168, 232, + 146, 223, 173, 250, 120, 10, 167, 3, 234, 164, 195, 168, 232, 146, 196, + 33, 10, 167, 3, 234, 164, 195, 168, 232, 146, 196, 32, 10, 167, 3, 213, + 175, 195, 168, 232, 146, 223, 188, 10, 167, 3, 213, 175, 195, 168, 232, + 146, 223, 187, 10, 167, 3, 213, 175, 195, 168, 232, 146, 223, 186, 10, + 167, 3, 213, 175, 195, 168, 232, 146, 223, 189, 65, 10, 167, 3, 105, 250, + 210, 199, 84, 10, 167, 3, 115, 250, 210, 199, 84, 10, 167, 3, 232, 128, + 250, 210, 199, 84, 10, 167, 3, 232, 226, 250, 210, 199, 84, 10, 167, 3, + 202, 136, 250, 210, 199, 84, 10, 167, 3, 91, 249, 99, 10, 167, 3, 105, + 249, 99, 10, 167, 3, 115, 249, 99, 10, 167, 3, 232, 128, 249, 99, 10, + 167, 3, 232, 128, 249, 100, 195, 168, 20, 10, 167, 3, 232, 226, 249, 99, + 10, 167, 3, 232, 226, 249, 100, 195, 168, 20, 10, 167, 3, 213, 188, 10, + 167, 3, 213, 189, 10, 167, 3, 91, 234, 7, 10, 167, 3, 105, 234, 7, 10, + 167, 3, 91, 199, 1, 236, 222, 10, 167, 3, 105, 198, 254, 236, 222, 10, + 167, 3, 232, 226, 202, 123, 236, 222, 10, 167, 3, 91, 199, 1, 195, 168, + 232, 146, 65, 10, 167, 3, 105, 198, 254, 195, 168, 232, 146, 65, 10, 167, + 3, 91, 234, 160, 250, 209, 10, 167, 3, 91, 208, 23, 250, 209, 10, 167, 3, + 39, 250, 196, 91, 202, 124, 10, 167, 3, 39, 250, 196, 91, 208, 22, 10, + 167, 3, 91, 208, 23, 230, 149, 10, 167, 3, 91, 132, 230, 149, 10, 167, 3, + 234, 138, 91, 199, 0, 10, 167, 3, 234, 138, 105, 198, 253, 10, 167, 3, + 234, 138, 232, 135, 10, 167, 3, 234, 138, 233, 15, 10, 167, 3, 232, 128, + 126, 195, 168, 20, 10, 167, 3, 232, 226, 126, 195, 168, 20, 10, 167, 3, + 202, 136, 126, 195, 168, 20, 10, 167, 3, 203, 247, 126, 195, 168, 20, 10, + 167, 3, 234, 164, 126, 195, 168, 20, 10, 167, 3, 213, 175, 126, 195, 168, + 20, 10, 208, 152, 3, 39, 250, 196, 193, 23, 236, 205, 10, 208, 152, 3, + 81, 242, 83, 10, 208, 152, 3, 237, 39, 242, 83, 10, 208, 152, 3, 237, 39, + 197, 237, 10, 208, 152, 3, 237, 39, 208, 29, 10, 3, 252, 156, 25, 212, + 131, 199, 84, 10, 3, 252, 156, 25, 203, 3, 10, 3, 252, 43, 25, 234, 9, + 10, 3, 249, 136, 25, 236, 223, 199, 84, 10, 3, 249, 122, 25, 252, 72, 10, + 3, 249, 122, 25, 213, 219, 10, 3, 249, 122, 25, 191, 123, 10, 3, 248, 11, + 139, 248, 11, 25, 214, 253, 10, 3, 238, 33, 25, 199, 209, 10, 3, 238, 23, + 25, 220, 197, 10, 3, 237, 0, 25, 223, 201, 10, 3, 237, 0, 25, 126, 126, + 66, 10, 3, 236, 254, 25, 196, 158, 10, 3, 235, 83, 25, 251, 91, 10, 3, + 235, 83, 25, 250, 209, 10, 3, 235, 83, 25, 250, 210, 250, 183, 219, 224, + 10, 3, 235, 83, 25, 236, 243, 10, 3, 235, 83, 25, 235, 75, 10, 3, 235, + 83, 25, 234, 28, 10, 3, 235, 83, 25, 231, 240, 10, 3, 235, 83, 25, 231, + 53, 10, 3, 235, 83, 25, 231, 33, 230, 155, 10, 3, 235, 83, 25, 231, 23, + 10, 3, 235, 83, 25, 140, 10, 3, 235, 83, 25, 229, 158, 10, 3, 235, 83, + 25, 223, 202, 230, 155, 10, 3, 235, 83, 25, 222, 54, 10, 3, 235, 83, 25, + 220, 197, 10, 3, 235, 83, 25, 220, 190, 10, 3, 235, 83, 25, 220, 191, + 108, 222, 54, 10, 3, 235, 83, 25, 220, 92, 10, 3, 235, 83, 25, 220, 35, + 10, 3, 235, 83, 25, 220, 36, 25, 220, 197, 10, 3, 235, 83, 25, 218, 214, + 108, 231, 23, 10, 3, 235, 83, 25, 217, 39, 10, 3, 235, 83, 25, 216, 173, + 10, 3, 235, 83, 25, 216, 100, 10, 3, 235, 83, 25, 213, 219, 10, 3, 235, + 83, 25, 209, 185, 10, 3, 235, 83, 25, 203, 113, 10, 3, 235, 83, 25, 202, + 223, 230, 155, 10, 3, 234, 219, 25, 220, 197, 10, 3, 234, 219, 25, 210, + 137, 10, 3, 234, 29, 192, 235, 10, 3, 234, 10, 238, 210, 234, 9, 10, 3, + 233, 181, 203, 95, 25, 250, 209, 10, 3, 233, 181, 203, 95, 25, 229, 158, + 10, 3, 233, 181, 203, 95, 25, 223, 202, 230, 155, 10, 3, 233, 181, 203, + 95, 25, 173, 10, 3, 233, 181, 203, 95, 25, 220, 37, 10, 3, 233, 181, 203, + 95, 25, 216, 232, 10, 3, 233, 181, 203, 95, 25, 216, 173, 10, 3, 233, + 181, 203, 95, 25, 201, 4, 10, 3, 233, 181, 25, 201, 4, 10, 3, 231, 239, + 25, 249, 121, 10, 3, 231, 239, 25, 237, 0, 230, 155, 10, 3, 231, 239, 25, + 235, 83, 25, 223, 202, 230, 155, 10, 3, 231, 239, 25, 235, 83, 25, 222, + 54, 10, 3, 231, 239, 25, 234, 31, 10, 3, 231, 239, 25, 231, 240, 10, 3, + 231, 239, 25, 231, 201, 108, 237, 44, 10, 3, 231, 239, 25, 231, 201, 108, + 214, 121, 10, 3, 231, 239, 25, 230, 105, 108, 65, 10, 3, 231, 239, 25, + 220, 191, 108, 222, 54, 10, 3, 231, 239, 25, 220, 35, 10, 3, 231, 239, + 25, 220, 36, 25, 220, 197, 10, 3, 231, 239, 25, 218, 213, 10, 3, 231, + 239, 25, 215, 101, 10, 3, 231, 239, 25, 214, 121, 10, 3, 231, 239, 25, + 214, 122, 108, 234, 218, 10, 3, 231, 239, 25, 214, 122, 108, 231, 53, 10, + 3, 231, 239, 25, 203, 73, 10, 3, 231, 239, 25, 191, 13, 10, 3, 231, 234, + 206, 122, 213, 170, 237, 124, 10, 3, 231, 135, 25, 66, 10, 3, 231, 24, + 25, 231, 24, 238, 210, 231, 23, 10, 3, 230, 178, 25, 223, 202, 230, 155, + 10, 3, 230, 169, 108, 231, 24, 25, 199, 209, 10, 3, 230, 105, 199, 85, + 230, 155, 10, 3, 229, 159, 25, 250, 210, 139, 229, 159, 25, 250, 209, 10, + 3, 222, 142, 25, 248, 10, 10, 3, 222, 142, 25, 155, 10, 3, 222, 142, 25, + 126, 126, 66, 10, 3, 222, 142, 25, 196, 62, 10, 3, 220, 105, 25, 190, + 252, 139, 190, 251, 10, 3, 220, 93, 10, 3, 220, 91, 10, 3, 220, 90, 10, + 3, 220, 89, 10, 3, 220, 88, 10, 3, 220, 87, 10, 3, 220, 86, 10, 3, 220, + 85, 139, 220, 85, 230, 155, 10, 3, 220, 84, 10, 3, 220, 83, 139, 220, 82, + 10, 3, 220, 81, 10, 3, 220, 80, 10, 3, 220, 79, 10, 3, 220, 78, 10, 3, + 220, 77, 10, 3, 220, 76, 10, 3, 220, 75, 10, 3, 220, 74, 10, 3, 220, 73, + 10, 3, 220, 72, 10, 3, 220, 71, 10, 3, 220, 70, 10, 3, 220, 69, 10, 3, + 220, 68, 10, 3, 220, 67, 10, 3, 220, 66, 10, 3, 220, 65, 10, 3, 220, 64, + 10, 3, 220, 62, 10, 3, 220, 63, 25, 230, 179, 10, 3, 220, 63, 25, 223, + 201, 10, 3, 220, 63, 25, 210, 138, 108, 218, 222, 10, 3, 220, 63, 25, + 210, 138, 108, 210, 138, 108, 218, 222, 10, 3, 220, 63, 25, 196, 170, + 108, 249, 153, 10, 3, 220, 61, 10, 3, 220, 60, 10, 3, 220, 59, 10, 3, 220, 58, 10, 3, 220, 57, 10, 3, 220, 56, 10, 3, 220, 55, 10, 3, 220, 54, - 10, 3, 220, 53, 10, 3, 220, 52, 10, 3, 220, 51, 10, 3, 220, 50, 10, 3, - 220, 49, 10, 3, 220, 48, 10, 3, 220, 47, 10, 3, 220, 46, 10, 3, 220, 45, - 10, 3, 220, 44, 10, 3, 220, 43, 10, 3, 220, 42, 10, 3, 220, 41, 10, 3, - 220, 40, 10, 3, 220, 38, 10, 3, 220, 39, 25, 230, 146, 10, 3, 220, 39, - 25, 223, 172, 10, 3, 220, 39, 25, 210, 128, 107, 218, 200, 10, 3, 220, - 39, 25, 210, 128, 107, 210, 128, 107, 218, 200, 10, 3, 220, 39, 25, 196, - 166, 107, 249, 103, 10, 3, 220, 37, 10, 3, 220, 36, 10, 3, 220, 35, 10, - 3, 220, 34, 10, 3, 220, 33, 10, 3, 220, 32, 10, 3, 220, 31, 10, 3, 220, - 30, 10, 3, 220, 29, 10, 3, 220, 28, 10, 3, 220, 26, 10, 3, 220, 27, 25, - 250, 159, 10, 3, 220, 27, 25, 249, 85, 10, 3, 220, 27, 25, 235, 30, 230, - 123, 230, 122, 10, 3, 220, 27, 25, 220, 199, 10, 3, 220, 27, 25, 171, 10, - 3, 220, 27, 25, 199, 174, 10, 3, 220, 27, 25, 199, 140, 10, 3, 220, 27, - 25, 196, 165, 10, 3, 220, 27, 25, 196, 154, 10, 3, 220, 27, 25, 196, 45, - 10, 3, 220, 25, 10, 3, 220, 23, 10, 3, 220, 24, 25, 235, 43, 10, 3, 220, - 24, 25, 231, 203, 10, 3, 220, 24, 25, 223, 172, 10, 3, 220, 24, 25, 223, - 173, 230, 122, 10, 3, 220, 24, 25, 213, 205, 10, 3, 220, 24, 25, 210, - 128, 107, 210, 128, 107, 218, 200, 10, 3, 220, 24, 25, 203, 93, 107, 221, - 142, 10, 3, 220, 24, 25, 196, 154, 10, 3, 220, 24, 25, 196, 45, 10, 3, - 220, 21, 10, 3, 220, 20, 10, 3, 218, 202, 230, 123, 25, 250, 159, 10, 3, - 218, 202, 25, 236, 177, 10, 3, 218, 202, 25, 230, 40, 10, 3, 218, 202, - 25, 210, 127, 10, 3, 218, 202, 25, 210, 128, 107, 210, 128, 107, 218, - 200, 10, 3, 218, 202, 25, 199, 204, 10, 3, 216, 82, 107, 191, 122, 10, 3, - 215, 88, 138, 215, 88, 25, 231, 203, 10, 3, 215, 88, 138, 215, 88, 25, - 222, 69, 10, 3, 213, 163, 25, 236, 211, 230, 122, 10, 3, 213, 163, 25, - 230, 243, 10, 3, 213, 163, 25, 230, 127, 10, 3, 213, 163, 25, 229, 126, - 10, 3, 213, 163, 25, 221, 217, 10, 3, 213, 163, 25, 220, 64, 10, 3, 213, - 163, 25, 217, 20, 10, 3, 213, 163, 25, 210, 128, 107, 210, 127, 10, 3, - 213, 163, 25, 69, 10, 3, 213, 163, 25, 126, 107, 69, 10, 3, 213, 163, 25, - 196, 45, 10, 3, 205, 181, 230, 123, 25, 144, 10, 3, 205, 181, 25, 234, - 61, 10, 3, 205, 181, 25, 203, 109, 250, 133, 219, 200, 10, 3, 205, 181, - 25, 199, 204, 10, 3, 203, 157, 199, 79, 10, 3, 203, 109, 138, 203, 108, - 10, 3, 203, 109, 107, 228, 120, 10, 3, 203, 109, 107, 214, 215, 10, 3, - 203, 109, 107, 205, 122, 10, 3, 202, 255, 107, 235, 39, 25, 213, 205, 10, - 3, 202, 255, 107, 234, 175, 25, 251, 81, 10, 3, 202, 218, 25, 199, 204, - 10, 3, 199, 205, 107, 205, 180, 10, 3, 197, 73, 25, 231, 172, 199, 79, - 10, 3, 197, 73, 25, 115, 236, 177, 10, 3, 196, 57, 223, 64, 10, 3, 196, - 57, 25, 196, 154, 10, 3, 196, 48, 25, 237, 179, 10, 3, 196, 48, 25, 220, - 22, 10, 3, 196, 48, 25, 218, 200, 10, 3, 191, 122, 10, 3, 190, 252, 138, - 190, 252, 107, 205, 122, 10, 3, 190, 250, 25, 115, 236, 178, 199, 79, - 238, 87, 3, 242, 150, 238, 87, 3, 242, 149, 238, 87, 3, 242, 148, 238, - 87, 3, 242, 147, 238, 87, 3, 242, 146, 238, 87, 3, 242, 145, 238, 87, 3, - 242, 144, 238, 87, 3, 242, 143, 238, 87, 3, 242, 142, 238, 87, 3, 242, - 141, 238, 87, 3, 242, 140, 238, 87, 3, 242, 139, 238, 87, 3, 242, 138, - 238, 87, 3, 242, 137, 238, 87, 3, 242, 136, 238, 87, 3, 242, 135, 238, - 87, 3, 242, 134, 238, 87, 3, 242, 133, 238, 87, 3, 242, 132, 238, 87, 3, - 242, 131, 238, 87, 3, 242, 130, 238, 87, 3, 242, 129, 238, 87, 3, 242, - 128, 238, 87, 3, 242, 127, 238, 87, 3, 242, 126, 238, 87, 3, 242, 125, - 238, 87, 3, 242, 124, 238, 87, 3, 242, 123, 238, 87, 3, 242, 122, 238, - 87, 3, 242, 121, 238, 87, 3, 242, 120, 238, 87, 3, 242, 119, 238, 87, 3, - 242, 118, 238, 87, 3, 242, 117, 238, 87, 3, 242, 116, 238, 87, 3, 242, - 115, 238, 87, 3, 242, 114, 238, 87, 3, 242, 113, 238, 87, 3, 242, 112, - 238, 87, 3, 242, 111, 238, 87, 3, 242, 110, 238, 87, 3, 242, 109, 238, - 87, 3, 242, 108, 238, 87, 3, 242, 107, 238, 87, 3, 242, 106, 238, 87, 3, - 242, 105, 238, 87, 3, 242, 104, 238, 87, 3, 242, 103, 238, 87, 3, 242, - 102, 238, 87, 3, 242, 101, 238, 87, 3, 242, 100, 238, 87, 3, 242, 99, - 238, 87, 3, 242, 98, 238, 87, 3, 242, 97, 238, 87, 3, 242, 96, 238, 87, - 3, 242, 95, 238, 87, 3, 242, 94, 238, 87, 3, 242, 93, 238, 87, 3, 242, - 92, 238, 87, 3, 242, 91, 238, 87, 3, 242, 90, 238, 87, 3, 242, 89, 238, - 87, 3, 242, 88, 238, 87, 3, 242, 87, 238, 87, 3, 242, 86, 238, 87, 3, - 242, 85, 238, 87, 3, 242, 84, 238, 87, 3, 242, 83, 238, 87, 3, 242, 82, - 238, 87, 3, 242, 81, 238, 87, 3, 242, 80, 238, 87, 3, 242, 79, 238, 87, - 3, 242, 78, 238, 87, 3, 242, 77, 238, 87, 3, 242, 76, 238, 87, 3, 242, - 75, 238, 87, 3, 242, 74, 238, 87, 3, 242, 73, 238, 87, 3, 242, 72, 238, - 87, 3, 242, 71, 238, 87, 3, 242, 70, 238, 87, 3, 242, 69, 238, 87, 3, - 242, 68, 238, 87, 3, 242, 67, 238, 87, 3, 242, 66, 238, 87, 3, 242, 65, - 238, 87, 3, 242, 64, 238, 87, 3, 242, 63, 238, 87, 3, 242, 62, 238, 87, - 3, 242, 61, 238, 87, 3, 242, 60, 238, 87, 3, 242, 59, 238, 87, 3, 242, - 58, 238, 87, 3, 242, 57, 238, 87, 3, 242, 56, 238, 87, 3, 242, 55, 238, - 87, 3, 242, 54, 238, 87, 3, 242, 53, 238, 87, 3, 242, 52, 14, 7, 255, - 147, 14, 7, 255, 146, 14, 7, 255, 145, 14, 7, 255, 144, 14, 7, 255, 143, - 14, 7, 255, 142, 14, 7, 255, 141, 14, 7, 255, 140, 14, 7, 255, 139, 14, - 7, 255, 138, 14, 7, 255, 137, 14, 7, 255, 136, 14, 7, 255, 135, 14, 7, - 255, 133, 14, 7, 255, 132, 14, 7, 255, 131, 14, 7, 255, 130, 14, 7, 255, - 129, 14, 7, 255, 128, 14, 7, 255, 127, 14, 7, 255, 126, 14, 7, 255, 125, - 14, 7, 255, 124, 14, 7, 255, 123, 14, 7, 255, 122, 14, 7, 255, 121, 14, - 7, 255, 120, 14, 7, 255, 119, 14, 7, 255, 118, 14, 7, 255, 117, 14, 7, - 255, 116, 14, 7, 255, 114, 14, 7, 255, 113, 14, 7, 255, 111, 14, 7, 255, - 110, 14, 7, 255, 109, 14, 7, 255, 108, 14, 7, 255, 107, 14, 7, 255, 106, - 14, 7, 255, 105, 14, 7, 255, 104, 14, 7, 255, 103, 14, 7, 255, 102, 14, - 7, 255, 101, 14, 7, 255, 100, 14, 7, 255, 98, 14, 7, 255, 97, 14, 7, 255, - 96, 14, 7, 255, 94, 14, 7, 255, 93, 14, 7, 255, 92, 14, 7, 255, 91, 14, - 7, 255, 90, 14, 7, 255, 89, 14, 7, 255, 88, 14, 7, 255, 87, 14, 7, 255, - 84, 14, 7, 255, 83, 14, 7, 255, 82, 14, 7, 255, 81, 14, 7, 255, 80, 14, - 7, 255, 79, 14, 7, 255, 78, 14, 7, 255, 77, 14, 7, 255, 76, 14, 7, 255, - 75, 14, 7, 255, 74, 14, 7, 255, 73, 14, 7, 255, 72, 14, 7, 255, 71, 14, - 7, 255, 70, 14, 7, 255, 69, 14, 7, 255, 68, 14, 7, 255, 67, 14, 7, 255, - 66, 14, 7, 255, 65, 14, 7, 255, 61, 14, 7, 255, 60, 14, 7, 255, 59, 14, - 7, 255, 58, 14, 7, 250, 68, 14, 7, 250, 66, 14, 7, 250, 64, 14, 7, 250, - 62, 14, 7, 250, 60, 14, 7, 250, 59, 14, 7, 250, 57, 14, 7, 250, 55, 14, - 7, 250, 53, 14, 7, 250, 51, 14, 7, 247, 141, 14, 7, 247, 140, 14, 7, 247, - 139, 14, 7, 247, 138, 14, 7, 247, 137, 14, 7, 247, 136, 14, 7, 247, 135, - 14, 7, 247, 134, 14, 7, 247, 133, 14, 7, 247, 132, 14, 7, 247, 131, 14, - 7, 247, 130, 14, 7, 247, 129, 14, 7, 247, 128, 14, 7, 247, 127, 14, 7, - 247, 126, 14, 7, 247, 125, 14, 7, 247, 124, 14, 7, 247, 123, 14, 7, 247, - 122, 14, 7, 247, 121, 14, 7, 247, 120, 14, 7, 247, 119, 14, 7, 247, 118, - 14, 7, 247, 117, 14, 7, 247, 116, 14, 7, 247, 115, 14, 7, 247, 114, 14, - 7, 238, 79, 14, 7, 238, 78, 14, 7, 238, 77, 14, 7, 238, 76, 14, 7, 238, - 75, 14, 7, 238, 74, 14, 7, 238, 73, 14, 7, 238, 72, 14, 7, 238, 71, 14, - 7, 238, 70, 14, 7, 238, 69, 14, 7, 238, 68, 14, 7, 238, 67, 14, 7, 238, - 66, 14, 7, 238, 65, 14, 7, 238, 64, 14, 7, 238, 63, 14, 7, 238, 62, 14, - 7, 238, 61, 14, 7, 238, 60, 14, 7, 238, 59, 14, 7, 238, 58, 14, 7, 238, - 57, 14, 7, 238, 56, 14, 7, 238, 55, 14, 7, 238, 54, 14, 7, 238, 53, 14, - 7, 238, 52, 14, 7, 238, 51, 14, 7, 238, 50, 14, 7, 238, 49, 14, 7, 238, - 48, 14, 7, 238, 47, 14, 7, 238, 46, 14, 7, 238, 45, 14, 7, 238, 44, 14, - 7, 238, 43, 14, 7, 238, 42, 14, 7, 238, 41, 14, 7, 238, 40, 14, 7, 238, - 39, 14, 7, 238, 38, 14, 7, 238, 37, 14, 7, 238, 36, 14, 7, 238, 35, 14, - 7, 238, 34, 14, 7, 238, 33, 14, 7, 238, 32, 14, 7, 238, 31, 14, 7, 238, - 30, 14, 7, 238, 29, 14, 7, 238, 28, 14, 7, 238, 27, 14, 7, 238, 26, 14, - 7, 238, 25, 14, 7, 238, 24, 14, 7, 238, 23, 14, 7, 238, 22, 14, 7, 238, - 21, 14, 7, 238, 20, 14, 7, 238, 19, 14, 7, 238, 18, 14, 7, 238, 17, 14, - 7, 238, 16, 14, 7, 238, 15, 14, 7, 238, 14, 14, 7, 238, 13, 14, 7, 238, - 12, 14, 7, 238, 11, 14, 7, 238, 10, 14, 7, 238, 9, 14, 7, 238, 8, 14, 7, - 238, 7, 14, 7, 238, 6, 14, 7, 238, 5, 14, 7, 238, 4, 14, 7, 238, 3, 14, - 7, 238, 2, 14, 7, 238, 1, 14, 7, 238, 0, 14, 7, 237, 255, 14, 7, 237, - 254, 14, 7, 237, 253, 14, 7, 237, 252, 14, 7, 237, 251, 14, 7, 237, 250, - 14, 7, 237, 249, 14, 7, 237, 248, 14, 7, 237, 247, 14, 7, 237, 246, 14, - 7, 237, 245, 14, 7, 237, 244, 14, 7, 234, 219, 14, 7, 234, 218, 14, 7, - 234, 217, 14, 7, 234, 216, 14, 7, 234, 215, 14, 7, 234, 214, 14, 7, 234, - 213, 14, 7, 234, 212, 14, 7, 234, 211, 14, 7, 234, 210, 14, 7, 234, 209, - 14, 7, 234, 208, 14, 7, 234, 207, 14, 7, 234, 206, 14, 7, 234, 205, 14, - 7, 234, 204, 14, 7, 234, 203, 14, 7, 234, 202, 14, 7, 234, 201, 14, 7, - 234, 200, 14, 7, 234, 199, 14, 7, 234, 198, 14, 7, 234, 197, 14, 7, 234, - 196, 14, 7, 234, 195, 14, 7, 234, 194, 14, 7, 234, 193, 14, 7, 234, 192, - 14, 7, 234, 191, 14, 7, 234, 190, 14, 7, 234, 189, 14, 7, 234, 188, 14, - 7, 234, 187, 14, 7, 234, 186, 14, 7, 234, 185, 14, 7, 234, 184, 14, 7, - 234, 183, 14, 7, 234, 182, 14, 7, 234, 181, 14, 7, 234, 180, 14, 7, 234, - 179, 14, 7, 234, 178, 14, 7, 234, 177, 14, 7, 234, 176, 14, 7, 233, 133, - 14, 7, 233, 132, 14, 7, 233, 131, 14, 7, 233, 130, 14, 7, 233, 129, 14, - 7, 233, 128, 14, 7, 233, 127, 14, 7, 233, 126, 14, 7, 233, 125, 14, 7, - 233, 124, 14, 7, 233, 123, 14, 7, 233, 122, 14, 7, 233, 121, 14, 7, 233, - 120, 14, 7, 233, 119, 14, 7, 233, 118, 14, 7, 233, 117, 14, 7, 233, 116, - 14, 7, 233, 115, 14, 7, 233, 114, 14, 7, 233, 113, 14, 7, 233, 112, 14, - 7, 233, 111, 14, 7, 233, 110, 14, 7, 233, 109, 14, 7, 233, 108, 14, 7, - 233, 107, 14, 7, 233, 106, 14, 7, 233, 105, 14, 7, 233, 104, 14, 7, 233, - 103, 14, 7, 233, 102, 14, 7, 233, 101, 14, 7, 233, 100, 14, 7, 233, 99, - 14, 7, 233, 98, 14, 7, 233, 97, 14, 7, 233, 96, 14, 7, 233, 95, 14, 7, - 233, 94, 14, 7, 233, 93, 14, 7, 233, 92, 14, 7, 233, 91, 14, 7, 233, 90, - 14, 7, 233, 89, 14, 7, 233, 88, 14, 7, 233, 87, 14, 7, 233, 86, 14, 7, - 233, 85, 14, 7, 233, 84, 14, 7, 233, 83, 14, 7, 233, 82, 14, 7, 233, 81, - 14, 7, 233, 80, 14, 7, 233, 79, 14, 7, 233, 78, 14, 7, 233, 77, 14, 7, - 233, 76, 14, 7, 233, 75, 14, 7, 233, 74, 14, 7, 233, 73, 14, 7, 233, 72, - 14, 7, 233, 71, 14, 7, 233, 70, 14, 7, 233, 69, 14, 7, 232, 13, 14, 7, - 232, 12, 14, 7, 232, 11, 14, 7, 232, 10, 14, 7, 232, 9, 14, 7, 232, 8, - 14, 7, 232, 7, 14, 7, 232, 6, 14, 7, 232, 5, 14, 7, 232, 4, 14, 7, 232, - 3, 14, 7, 232, 2, 14, 7, 232, 1, 14, 7, 232, 0, 14, 7, 231, 255, 14, 7, - 231, 254, 14, 7, 231, 253, 14, 7, 231, 252, 14, 7, 231, 251, 14, 7, 231, - 250, 14, 7, 231, 249, 14, 7, 231, 248, 14, 7, 231, 247, 14, 7, 231, 246, - 14, 7, 231, 245, 14, 7, 231, 244, 14, 7, 231, 243, 14, 7, 231, 242, 14, - 7, 231, 241, 14, 7, 231, 240, 14, 7, 231, 239, 14, 7, 231, 238, 14, 7, - 231, 237, 14, 7, 231, 236, 14, 7, 231, 235, 14, 7, 231, 234, 14, 7, 231, - 233, 14, 7, 231, 232, 14, 7, 231, 231, 14, 7, 231, 230, 14, 7, 231, 229, - 14, 7, 231, 228, 14, 7, 231, 227, 14, 7, 231, 226, 14, 7, 231, 225, 14, - 7, 231, 224, 14, 7, 231, 223, 14, 7, 231, 222, 14, 7, 231, 221, 14, 7, - 231, 220, 14, 7, 231, 219, 14, 7, 231, 218, 14, 7, 231, 217, 14, 7, 231, - 216, 14, 7, 231, 215, 14, 7, 231, 214, 14, 7, 231, 213, 14, 7, 231, 212, - 14, 7, 231, 211, 14, 7, 231, 210, 14, 7, 231, 209, 14, 7, 231, 208, 14, - 7, 231, 207, 14, 7, 231, 206, 14, 7, 230, 81, 14, 7, 230, 80, 14, 7, 230, - 79, 14, 7, 230, 78, 14, 7, 230, 77, 14, 7, 230, 76, 14, 7, 230, 75, 14, - 7, 230, 74, 14, 7, 230, 73, 14, 7, 228, 24, 14, 7, 228, 23, 14, 7, 228, - 22, 14, 7, 228, 21, 14, 7, 228, 20, 14, 7, 228, 19, 14, 7, 228, 18, 14, - 7, 228, 17, 14, 7, 228, 16, 14, 7, 228, 15, 14, 7, 228, 14, 14, 7, 228, - 13, 14, 7, 228, 12, 14, 7, 228, 11, 14, 7, 228, 10, 14, 7, 228, 9, 14, 7, - 228, 8, 14, 7, 228, 7, 14, 7, 228, 6, 14, 7, 222, 124, 14, 7, 222, 123, - 14, 7, 222, 122, 14, 7, 222, 121, 14, 7, 222, 120, 14, 7, 222, 119, 14, - 7, 222, 118, 14, 7, 222, 117, 14, 7, 220, 116, 14, 7, 220, 115, 14, 7, - 220, 114, 14, 7, 220, 113, 14, 7, 220, 112, 14, 7, 220, 111, 14, 7, 220, - 110, 14, 7, 220, 109, 14, 7, 220, 108, 14, 7, 220, 107, 14, 7, 218, 145, - 14, 7, 218, 144, 14, 7, 218, 143, 14, 7, 218, 141, 14, 7, 218, 139, 14, - 7, 218, 138, 14, 7, 218, 136, 14, 7, 218, 134, 14, 7, 218, 132, 14, 7, - 218, 130, 14, 7, 218, 128, 14, 7, 218, 126, 14, 7, 218, 124, 14, 7, 218, - 123, 14, 7, 218, 121, 14, 7, 218, 119, 14, 7, 218, 118, 14, 7, 218, 117, - 14, 7, 218, 116, 14, 7, 218, 115, 14, 7, 218, 114, 14, 7, 218, 113, 14, - 7, 218, 112, 14, 7, 218, 111, 14, 7, 218, 109, 14, 7, 218, 107, 14, 7, - 218, 105, 14, 7, 218, 104, 14, 7, 218, 102, 14, 7, 218, 101, 14, 7, 218, - 99, 14, 7, 218, 98, 14, 7, 218, 96, 14, 7, 218, 94, 14, 7, 218, 92, 14, - 7, 218, 90, 14, 7, 218, 88, 14, 7, 218, 87, 14, 7, 218, 85, 14, 7, 218, - 83, 14, 7, 218, 82, 14, 7, 218, 80, 14, 7, 218, 78, 14, 7, 218, 76, 14, - 7, 218, 74, 14, 7, 218, 73, 14, 7, 218, 71, 14, 7, 218, 69, 14, 7, 218, - 67, 14, 7, 218, 66, 14, 7, 218, 64, 14, 7, 218, 62, 14, 7, 218, 61, 14, - 7, 218, 60, 14, 7, 218, 58, 14, 7, 218, 56, 14, 7, 218, 54, 14, 7, 218, - 52, 14, 7, 218, 50, 14, 7, 218, 48, 14, 7, 218, 46, 14, 7, 218, 45, 14, - 7, 218, 43, 14, 7, 218, 41, 14, 7, 218, 39, 14, 7, 218, 37, 14, 7, 215, - 42, 14, 7, 215, 41, 14, 7, 215, 40, 14, 7, 215, 39, 14, 7, 215, 38, 14, - 7, 215, 37, 14, 7, 215, 36, 14, 7, 215, 35, 14, 7, 215, 34, 14, 7, 215, - 33, 14, 7, 215, 32, 14, 7, 215, 31, 14, 7, 215, 30, 14, 7, 215, 29, 14, - 7, 215, 28, 14, 7, 215, 27, 14, 7, 215, 26, 14, 7, 215, 25, 14, 7, 215, - 24, 14, 7, 215, 23, 14, 7, 215, 22, 14, 7, 215, 21, 14, 7, 215, 20, 14, - 7, 215, 19, 14, 7, 215, 18, 14, 7, 215, 17, 14, 7, 215, 16, 14, 7, 215, - 15, 14, 7, 215, 14, 14, 7, 215, 13, 14, 7, 215, 12, 14, 7, 215, 11, 14, - 7, 215, 10, 14, 7, 215, 9, 14, 7, 215, 8, 14, 7, 215, 7, 14, 7, 215, 6, - 14, 7, 215, 5, 14, 7, 215, 4, 14, 7, 215, 3, 14, 7, 215, 2, 14, 7, 215, - 1, 14, 7, 215, 0, 14, 7, 214, 255, 14, 7, 214, 254, 14, 7, 214, 253, 14, - 7, 214, 252, 14, 7, 214, 251, 14, 7, 214, 250, 14, 7, 213, 91, 14, 7, - 213, 90, 14, 7, 213, 89, 14, 7, 213, 88, 14, 7, 213, 87, 14, 7, 213, 86, - 14, 7, 213, 85, 14, 7, 213, 84, 14, 7, 213, 83, 14, 7, 213, 82, 14, 7, - 213, 81, 14, 7, 213, 80, 14, 7, 213, 79, 14, 7, 213, 78, 14, 7, 213, 77, - 14, 7, 213, 76, 14, 7, 213, 75, 14, 7, 213, 74, 14, 7, 213, 73, 14, 7, - 213, 72, 14, 7, 213, 71, 14, 7, 213, 70, 14, 7, 212, 161, 14, 7, 212, - 160, 14, 7, 212, 159, 14, 7, 212, 158, 14, 7, 212, 157, 14, 7, 212, 156, - 14, 7, 212, 155, 14, 7, 212, 154, 14, 7, 212, 153, 14, 7, 212, 152, 14, - 7, 212, 151, 14, 7, 212, 150, 14, 7, 212, 149, 14, 7, 212, 148, 14, 7, - 212, 147, 14, 7, 212, 146, 14, 7, 212, 145, 14, 7, 212, 144, 14, 7, 212, - 143, 14, 7, 212, 142, 14, 7, 212, 141, 14, 7, 212, 140, 14, 7, 212, 139, - 14, 7, 212, 138, 14, 7, 212, 137, 14, 7, 212, 136, 14, 7, 211, 245, 14, - 7, 211, 244, 14, 7, 211, 243, 14, 7, 211, 242, 14, 7, 211, 241, 14, 7, - 211, 240, 14, 7, 211, 239, 14, 7, 211, 238, 14, 7, 211, 237, 14, 7, 211, - 236, 14, 7, 211, 235, 14, 7, 211, 234, 14, 7, 211, 233, 14, 7, 211, 232, - 14, 7, 211, 231, 14, 7, 211, 230, 14, 7, 211, 229, 14, 7, 211, 228, 14, - 7, 211, 227, 14, 7, 211, 226, 14, 7, 211, 225, 14, 7, 211, 224, 14, 7, - 211, 223, 14, 7, 211, 222, 14, 7, 211, 221, 14, 7, 211, 220, 14, 7, 211, - 219, 14, 7, 211, 218, 14, 7, 211, 217, 14, 7, 211, 216, 14, 7, 211, 215, - 14, 7, 211, 214, 14, 7, 211, 213, 14, 7, 211, 212, 14, 7, 211, 211, 14, - 7, 211, 210, 14, 7, 211, 209, 14, 7, 211, 208, 14, 7, 211, 207, 14, 7, - 211, 206, 14, 7, 211, 205, 14, 7, 211, 204, 14, 7, 211, 203, 14, 7, 211, - 202, 14, 7, 211, 201, 14, 7, 211, 200, 14, 7, 211, 199, 14, 7, 211, 198, - 14, 7, 211, 197, 14, 7, 211, 196, 14, 7, 211, 195, 14, 7, 211, 194, 14, - 7, 211, 193, 14, 7, 211, 192, 14, 7, 211, 191, 14, 7, 211, 190, 14, 7, - 211, 189, 14, 7, 211, 188, 14, 7, 211, 187, 14, 7, 211, 186, 14, 7, 211, - 185, 14, 7, 211, 184, 14, 7, 211, 183, 14, 7, 211, 182, 14, 7, 211, 181, - 14, 7, 211, 180, 14, 7, 211, 179, 14, 7, 211, 178, 14, 7, 211, 177, 14, - 7, 211, 176, 14, 7, 211, 175, 14, 7, 211, 174, 14, 7, 211, 173, 14, 7, - 211, 172, 14, 7, 211, 171, 14, 7, 210, 225, 14, 7, 210, 224, 14, 7, 210, - 223, 14, 7, 210, 222, 14, 7, 210, 221, 14, 7, 210, 220, 14, 7, 210, 219, - 14, 7, 210, 218, 14, 7, 210, 217, 14, 7, 210, 216, 14, 7, 210, 215, 14, - 7, 210, 214, 14, 7, 210, 213, 14, 7, 208, 96, 14, 7, 208, 95, 14, 7, 208, - 94, 14, 7, 208, 93, 14, 7, 208, 92, 14, 7, 208, 91, 14, 7, 208, 90, 14, - 7, 207, 215, 14, 7, 207, 214, 14, 7, 207, 213, 14, 7, 207, 212, 14, 7, - 207, 211, 14, 7, 207, 210, 14, 7, 207, 209, 14, 7, 207, 208, 14, 7, 207, - 207, 14, 7, 207, 206, 14, 7, 207, 205, 14, 7, 207, 204, 14, 7, 207, 203, - 14, 7, 207, 202, 14, 7, 207, 201, 14, 7, 207, 200, 14, 7, 207, 199, 14, - 7, 207, 198, 14, 7, 207, 197, 14, 7, 207, 196, 14, 7, 207, 195, 14, 7, - 207, 194, 14, 7, 207, 193, 14, 7, 207, 192, 14, 7, 207, 191, 14, 7, 207, - 190, 14, 7, 207, 189, 14, 7, 207, 188, 14, 7, 207, 187, 14, 7, 207, 186, - 14, 7, 207, 185, 14, 7, 207, 184, 14, 7, 207, 183, 14, 7, 207, 182, 14, - 7, 206, 0, 14, 7, 205, 255, 14, 7, 205, 254, 14, 7, 205, 253, 14, 7, 205, - 252, 14, 7, 205, 251, 14, 7, 205, 250, 14, 7, 205, 249, 14, 7, 205, 248, - 14, 7, 205, 247, 14, 7, 205, 246, 14, 7, 205, 245, 14, 7, 205, 244, 14, - 7, 205, 243, 14, 7, 205, 242, 14, 7, 205, 241, 14, 7, 205, 240, 14, 7, - 205, 239, 14, 7, 205, 238, 14, 7, 205, 237, 14, 7, 205, 236, 14, 7, 205, - 235, 14, 7, 205, 234, 14, 7, 205, 233, 14, 7, 205, 232, 14, 7, 205, 231, - 14, 7, 205, 230, 14, 7, 205, 229, 14, 7, 205, 228, 14, 7, 205, 227, 14, - 7, 205, 226, 14, 7, 205, 225, 14, 7, 205, 224, 14, 7, 205, 223, 14, 7, - 205, 222, 14, 7, 205, 221, 14, 7, 205, 220, 14, 7, 205, 219, 14, 7, 205, - 218, 14, 7, 205, 217, 14, 7, 205, 216, 14, 7, 205, 215, 14, 7, 205, 214, - 14, 7, 205, 213, 14, 7, 205, 212, 14, 7, 205, 211, 14, 7, 205, 210, 14, - 7, 205, 209, 14, 7, 205, 208, 14, 7, 205, 207, 14, 7, 205, 206, 14, 7, - 205, 205, 14, 7, 205, 204, 14, 7, 205, 203, 14, 7, 200, 36, 14, 7, 200, - 35, 14, 7, 200, 34, 14, 7, 200, 33, 14, 7, 200, 32, 14, 7, 200, 31, 14, - 7, 200, 30, 14, 7, 200, 29, 14, 7, 200, 28, 14, 7, 200, 27, 14, 7, 200, - 26, 14, 7, 200, 25, 14, 7, 200, 24, 14, 7, 200, 23, 14, 7, 200, 22, 14, - 7, 200, 21, 14, 7, 200, 20, 14, 7, 200, 19, 14, 7, 200, 18, 14, 7, 200, - 17, 14, 7, 200, 16, 14, 7, 200, 15, 14, 7, 200, 14, 14, 7, 200, 13, 14, - 7, 200, 12, 14, 7, 200, 11, 14, 7, 200, 10, 14, 7, 200, 9, 14, 7, 200, 8, + 10, 3, 220, 53, 10, 3, 220, 52, 10, 3, 220, 50, 10, 3, 220, 51, 25, 250, + 209, 10, 3, 220, 51, 25, 249, 135, 10, 3, 220, 51, 25, 235, 74, 230, 156, + 230, 155, 10, 3, 220, 51, 25, 220, 223, 10, 3, 220, 51, 25, 173, 10, 3, + 220, 51, 25, 199, 179, 10, 3, 220, 51, 25, 199, 145, 10, 3, 220, 51, 25, + 196, 169, 10, 3, 220, 51, 25, 196, 158, 10, 3, 220, 51, 25, 196, 49, 10, + 3, 220, 49, 10, 3, 220, 47, 10, 3, 220, 48, 25, 235, 87, 10, 3, 220, 48, + 25, 231, 240, 10, 3, 220, 48, 25, 223, 201, 10, 3, 220, 48, 25, 223, 202, + 230, 155, 10, 3, 220, 48, 25, 213, 219, 10, 3, 220, 48, 25, 210, 138, + 108, 210, 138, 108, 218, 222, 10, 3, 220, 48, 25, 203, 98, 108, 221, 166, + 10, 3, 220, 48, 25, 196, 158, 10, 3, 220, 48, 25, 196, 49, 10, 3, 220, + 45, 10, 3, 220, 44, 10, 3, 218, 224, 230, 156, 25, 250, 209, 10, 3, 218, + 224, 25, 236, 222, 10, 3, 218, 224, 25, 230, 73, 10, 3, 218, 224, 25, + 210, 137, 10, 3, 218, 224, 25, 210, 138, 108, 210, 138, 108, 218, 222, + 10, 3, 218, 224, 25, 199, 209, 10, 3, 216, 101, 108, 191, 122, 10, 3, + 215, 102, 139, 215, 102, 25, 231, 240, 10, 3, 215, 102, 139, 215, 102, + 25, 222, 96, 10, 3, 213, 177, 25, 237, 0, 230, 155, 10, 3, 213, 177, 25, + 231, 23, 10, 3, 213, 177, 25, 230, 160, 10, 3, 213, 177, 25, 229, 158, + 10, 3, 213, 177, 25, 221, 242, 10, 3, 213, 177, 25, 220, 88, 10, 3, 213, + 177, 25, 217, 39, 10, 3, 213, 177, 25, 210, 138, 108, 210, 137, 10, 3, + 213, 177, 25, 66, 10, 3, 213, 177, 25, 126, 108, 66, 10, 3, 213, 177, 25, + 196, 49, 10, 3, 205, 186, 230, 156, 25, 140, 10, 3, 205, 186, 25, 234, + 103, 10, 3, 205, 186, 25, 203, 114, 250, 183, 219, 224, 10, 3, 205, 186, + 25, 199, 209, 10, 3, 203, 162, 199, 84, 10, 3, 203, 114, 139, 203, 113, + 10, 3, 203, 114, 108, 228, 151, 10, 3, 203, 114, 108, 214, 229, 10, 3, + 203, 114, 108, 205, 127, 10, 3, 203, 4, 108, 235, 83, 25, 213, 219, 10, + 3, 203, 4, 108, 234, 219, 25, 251, 132, 10, 3, 202, 223, 25, 199, 209, + 10, 3, 199, 210, 108, 205, 185, 10, 3, 197, 77, 25, 231, 209, 199, 84, + 10, 3, 197, 77, 25, 115, 236, 222, 10, 3, 196, 61, 223, 92, 10, 3, 196, + 61, 25, 196, 158, 10, 3, 196, 52, 25, 237, 224, 10, 3, 196, 52, 25, 220, + 46, 10, 3, 196, 52, 25, 218, 222, 10, 3, 191, 122, 10, 3, 190, 252, 139, + 190, 252, 108, 205, 127, 10, 3, 190, 250, 25, 115, 236, 223, 199, 84, + 238, 134, 3, 242, 198, 238, 134, 3, 242, 197, 238, 134, 3, 242, 196, 238, + 134, 3, 242, 195, 238, 134, 3, 242, 194, 238, 134, 3, 242, 193, 238, 134, + 3, 242, 192, 238, 134, 3, 242, 191, 238, 134, 3, 242, 190, 238, 134, 3, + 242, 189, 238, 134, 3, 242, 188, 238, 134, 3, 242, 187, 238, 134, 3, 242, + 186, 238, 134, 3, 242, 185, 238, 134, 3, 242, 184, 238, 134, 3, 242, 183, + 238, 134, 3, 242, 182, 238, 134, 3, 242, 181, 238, 134, 3, 242, 180, 238, + 134, 3, 242, 179, 238, 134, 3, 242, 178, 238, 134, 3, 242, 177, 238, 134, + 3, 242, 176, 238, 134, 3, 242, 175, 238, 134, 3, 242, 174, 238, 134, 3, + 242, 173, 238, 134, 3, 242, 172, 238, 134, 3, 242, 171, 238, 134, 3, 242, + 170, 238, 134, 3, 242, 169, 238, 134, 3, 242, 168, 238, 134, 3, 242, 167, + 238, 134, 3, 242, 166, 238, 134, 3, 242, 165, 238, 134, 3, 242, 164, 238, + 134, 3, 242, 163, 238, 134, 3, 242, 162, 238, 134, 3, 242, 161, 238, 134, + 3, 242, 160, 238, 134, 3, 242, 159, 238, 134, 3, 242, 158, 238, 134, 3, + 242, 157, 238, 134, 3, 242, 156, 238, 134, 3, 242, 155, 238, 134, 3, 242, + 154, 238, 134, 3, 242, 153, 238, 134, 3, 242, 152, 238, 134, 3, 242, 151, + 238, 134, 3, 242, 150, 238, 134, 3, 242, 149, 238, 134, 3, 242, 148, 238, + 134, 3, 242, 147, 238, 134, 3, 242, 146, 238, 134, 3, 242, 145, 238, 134, + 3, 242, 144, 238, 134, 3, 242, 143, 238, 134, 3, 242, 142, 238, 134, 3, + 242, 141, 238, 134, 3, 242, 140, 238, 134, 3, 242, 139, 238, 134, 3, 242, + 138, 238, 134, 3, 242, 137, 238, 134, 3, 242, 136, 238, 134, 3, 242, 135, + 238, 134, 3, 242, 134, 238, 134, 3, 242, 133, 238, 134, 3, 242, 132, 238, + 134, 3, 242, 131, 238, 134, 3, 242, 130, 238, 134, 3, 242, 129, 238, 134, + 3, 242, 128, 238, 134, 3, 242, 127, 238, 134, 3, 242, 126, 238, 134, 3, + 242, 125, 238, 134, 3, 242, 124, 238, 134, 3, 242, 123, 238, 134, 3, 242, + 122, 238, 134, 3, 242, 121, 238, 134, 3, 242, 120, 238, 134, 3, 242, 119, + 238, 134, 3, 242, 118, 238, 134, 3, 242, 117, 238, 134, 3, 242, 116, 238, + 134, 3, 242, 115, 238, 134, 3, 242, 114, 238, 134, 3, 242, 113, 238, 134, + 3, 242, 112, 238, 134, 3, 242, 111, 238, 134, 3, 242, 110, 238, 134, 3, + 242, 109, 238, 134, 3, 242, 108, 238, 134, 3, 242, 107, 238, 134, 3, 242, + 106, 238, 134, 3, 242, 105, 238, 134, 3, 242, 104, 238, 134, 3, 242, 103, + 238, 134, 3, 242, 102, 238, 134, 3, 242, 101, 238, 134, 3, 242, 100, 14, + 7, 255, 199, 14, 7, 255, 198, 14, 7, 255, 197, 14, 7, 255, 196, 14, 7, + 255, 195, 14, 7, 255, 194, 14, 7, 255, 193, 14, 7, 255, 192, 14, 7, 255, + 191, 14, 7, 255, 190, 14, 7, 255, 189, 14, 7, 255, 188, 14, 7, 255, 187, + 14, 7, 255, 185, 14, 7, 255, 184, 14, 7, 255, 183, 14, 7, 255, 182, 14, + 7, 255, 181, 14, 7, 255, 180, 14, 7, 255, 179, 14, 7, 255, 178, 14, 7, + 255, 177, 14, 7, 255, 176, 14, 7, 255, 175, 14, 7, 255, 174, 14, 7, 255, + 173, 14, 7, 255, 172, 14, 7, 255, 171, 14, 7, 255, 170, 14, 7, 255, 169, + 14, 7, 255, 168, 14, 7, 255, 166, 14, 7, 255, 165, 14, 7, 255, 163, 14, + 7, 255, 162, 14, 7, 255, 161, 14, 7, 255, 160, 14, 7, 255, 159, 14, 7, + 255, 158, 14, 7, 255, 157, 14, 7, 255, 156, 14, 7, 255, 155, 14, 7, 255, + 154, 14, 7, 255, 153, 14, 7, 255, 152, 14, 7, 255, 150, 14, 7, 255, 149, + 14, 7, 255, 148, 14, 7, 255, 146, 14, 7, 255, 145, 14, 7, 255, 144, 14, + 7, 255, 143, 14, 7, 255, 142, 14, 7, 255, 141, 14, 7, 255, 140, 14, 7, + 255, 139, 14, 7, 255, 136, 14, 7, 255, 135, 14, 7, 255, 134, 14, 7, 255, + 133, 14, 7, 255, 132, 14, 7, 255, 131, 14, 7, 255, 130, 14, 7, 255, 129, + 14, 7, 255, 128, 14, 7, 255, 127, 14, 7, 255, 126, 14, 7, 255, 125, 14, + 7, 255, 124, 14, 7, 255, 123, 14, 7, 255, 122, 14, 7, 255, 121, 14, 7, + 255, 120, 14, 7, 255, 119, 14, 7, 255, 118, 14, 7, 255, 117, 14, 7, 255, + 113, 14, 7, 255, 112, 14, 7, 255, 111, 14, 7, 255, 110, 14, 7, 250, 118, + 14, 7, 250, 116, 14, 7, 250, 114, 14, 7, 250, 112, 14, 7, 250, 110, 14, + 7, 250, 109, 14, 7, 250, 107, 14, 7, 250, 105, 14, 7, 250, 103, 14, 7, + 250, 101, 14, 7, 247, 189, 14, 7, 247, 188, 14, 7, 247, 187, 14, 7, 247, + 186, 14, 7, 247, 185, 14, 7, 247, 184, 14, 7, 247, 183, 14, 7, 247, 182, + 14, 7, 247, 181, 14, 7, 247, 180, 14, 7, 247, 179, 14, 7, 247, 178, 14, + 7, 247, 177, 14, 7, 247, 176, 14, 7, 247, 175, 14, 7, 247, 174, 14, 7, + 247, 173, 14, 7, 247, 172, 14, 7, 247, 171, 14, 7, 247, 170, 14, 7, 247, + 169, 14, 7, 247, 168, 14, 7, 247, 167, 14, 7, 247, 166, 14, 7, 247, 165, + 14, 7, 247, 164, 14, 7, 247, 163, 14, 7, 247, 162, 14, 7, 238, 126, 14, + 7, 238, 125, 14, 7, 238, 124, 14, 7, 238, 123, 14, 7, 238, 122, 14, 7, + 238, 121, 14, 7, 238, 120, 14, 7, 238, 119, 14, 7, 238, 118, 14, 7, 238, + 117, 14, 7, 238, 116, 14, 7, 238, 115, 14, 7, 238, 114, 14, 7, 238, 113, + 14, 7, 238, 112, 14, 7, 238, 111, 14, 7, 238, 110, 14, 7, 238, 109, 14, + 7, 238, 108, 14, 7, 238, 107, 14, 7, 238, 106, 14, 7, 238, 105, 14, 7, + 238, 104, 14, 7, 238, 103, 14, 7, 238, 102, 14, 7, 238, 101, 14, 7, 238, + 100, 14, 7, 238, 99, 14, 7, 238, 98, 14, 7, 238, 97, 14, 7, 238, 96, 14, + 7, 238, 95, 14, 7, 238, 94, 14, 7, 238, 93, 14, 7, 238, 92, 14, 7, 238, + 91, 14, 7, 238, 90, 14, 7, 238, 89, 14, 7, 238, 88, 14, 7, 238, 87, 14, + 7, 238, 86, 14, 7, 238, 85, 14, 7, 238, 84, 14, 7, 238, 83, 14, 7, 238, + 82, 14, 7, 238, 81, 14, 7, 238, 80, 14, 7, 238, 79, 14, 7, 238, 78, 14, + 7, 238, 77, 14, 7, 238, 76, 14, 7, 238, 75, 14, 7, 238, 74, 14, 7, 238, + 73, 14, 7, 238, 72, 14, 7, 238, 71, 14, 7, 238, 70, 14, 7, 238, 69, 14, + 7, 238, 68, 14, 7, 238, 67, 14, 7, 238, 66, 14, 7, 238, 65, 14, 7, 238, + 64, 14, 7, 238, 63, 14, 7, 238, 62, 14, 7, 238, 61, 14, 7, 238, 60, 14, + 7, 238, 59, 14, 7, 238, 58, 14, 7, 238, 57, 14, 7, 238, 56, 14, 7, 238, + 55, 14, 7, 238, 54, 14, 7, 238, 53, 14, 7, 238, 52, 14, 7, 238, 51, 14, + 7, 238, 50, 14, 7, 238, 49, 14, 7, 238, 48, 14, 7, 238, 47, 14, 7, 238, + 46, 14, 7, 238, 45, 14, 7, 238, 44, 14, 7, 238, 43, 14, 7, 238, 42, 14, + 7, 238, 41, 14, 7, 238, 40, 14, 7, 238, 39, 14, 7, 238, 38, 14, 7, 238, + 37, 14, 7, 238, 36, 14, 7, 238, 35, 14, 7, 235, 7, 14, 7, 235, 6, 14, 7, + 235, 5, 14, 7, 235, 4, 14, 7, 235, 3, 14, 7, 235, 2, 14, 7, 235, 1, 14, + 7, 235, 0, 14, 7, 234, 255, 14, 7, 234, 254, 14, 7, 234, 253, 14, 7, 234, + 252, 14, 7, 234, 251, 14, 7, 234, 250, 14, 7, 234, 249, 14, 7, 234, 248, + 14, 7, 234, 247, 14, 7, 234, 246, 14, 7, 234, 245, 14, 7, 234, 244, 14, + 7, 234, 243, 14, 7, 234, 242, 14, 7, 234, 241, 14, 7, 234, 240, 14, 7, + 234, 239, 14, 7, 234, 238, 14, 7, 234, 237, 14, 7, 234, 236, 14, 7, 234, + 235, 14, 7, 234, 234, 14, 7, 234, 233, 14, 7, 234, 232, 14, 7, 234, 231, + 14, 7, 234, 230, 14, 7, 234, 229, 14, 7, 234, 228, 14, 7, 234, 227, 14, + 7, 234, 226, 14, 7, 234, 225, 14, 7, 234, 224, 14, 7, 234, 223, 14, 7, + 234, 222, 14, 7, 234, 221, 14, 7, 234, 220, 14, 7, 233, 174, 14, 7, 233, + 173, 14, 7, 233, 172, 14, 7, 233, 171, 14, 7, 233, 170, 14, 7, 233, 169, + 14, 7, 233, 168, 14, 7, 233, 167, 14, 7, 233, 166, 14, 7, 233, 165, 14, + 7, 233, 164, 14, 7, 233, 163, 14, 7, 233, 162, 14, 7, 233, 161, 14, 7, + 233, 160, 14, 7, 233, 159, 14, 7, 233, 158, 14, 7, 233, 157, 14, 7, 233, + 156, 14, 7, 233, 155, 14, 7, 233, 154, 14, 7, 233, 153, 14, 7, 233, 152, + 14, 7, 233, 151, 14, 7, 233, 150, 14, 7, 233, 149, 14, 7, 233, 148, 14, + 7, 233, 147, 14, 7, 233, 146, 14, 7, 233, 145, 14, 7, 233, 144, 14, 7, + 233, 143, 14, 7, 233, 142, 14, 7, 233, 141, 14, 7, 233, 140, 14, 7, 233, + 139, 14, 7, 233, 138, 14, 7, 233, 137, 14, 7, 233, 136, 14, 7, 233, 135, + 14, 7, 233, 134, 14, 7, 233, 133, 14, 7, 233, 132, 14, 7, 233, 131, 14, + 7, 233, 130, 14, 7, 233, 129, 14, 7, 233, 128, 14, 7, 233, 127, 14, 7, + 233, 126, 14, 7, 233, 125, 14, 7, 233, 124, 14, 7, 233, 123, 14, 7, 233, + 122, 14, 7, 233, 121, 14, 7, 233, 120, 14, 7, 233, 119, 14, 7, 233, 118, + 14, 7, 233, 117, 14, 7, 233, 116, 14, 7, 233, 115, 14, 7, 233, 114, 14, + 7, 233, 113, 14, 7, 233, 112, 14, 7, 233, 111, 14, 7, 233, 110, 14, 7, + 232, 50, 14, 7, 232, 49, 14, 7, 232, 48, 14, 7, 232, 47, 14, 7, 232, 46, + 14, 7, 232, 45, 14, 7, 232, 44, 14, 7, 232, 43, 14, 7, 232, 42, 14, 7, + 232, 41, 14, 7, 232, 40, 14, 7, 232, 39, 14, 7, 232, 38, 14, 7, 232, 37, + 14, 7, 232, 36, 14, 7, 232, 35, 14, 7, 232, 34, 14, 7, 232, 33, 14, 7, + 232, 32, 14, 7, 232, 31, 14, 7, 232, 30, 14, 7, 232, 29, 14, 7, 232, 28, + 14, 7, 232, 27, 14, 7, 232, 26, 14, 7, 232, 25, 14, 7, 232, 24, 14, 7, + 232, 23, 14, 7, 232, 22, 14, 7, 232, 21, 14, 7, 232, 20, 14, 7, 232, 19, + 14, 7, 232, 18, 14, 7, 232, 17, 14, 7, 232, 16, 14, 7, 232, 15, 14, 7, + 232, 14, 14, 7, 232, 13, 14, 7, 232, 12, 14, 7, 232, 11, 14, 7, 232, 10, + 14, 7, 232, 9, 14, 7, 232, 8, 14, 7, 232, 7, 14, 7, 232, 6, 14, 7, 232, + 5, 14, 7, 232, 4, 14, 7, 232, 3, 14, 7, 232, 2, 14, 7, 232, 1, 14, 7, + 232, 0, 14, 7, 231, 255, 14, 7, 231, 254, 14, 7, 231, 253, 14, 7, 231, + 252, 14, 7, 231, 251, 14, 7, 231, 250, 14, 7, 231, 249, 14, 7, 231, 248, + 14, 7, 231, 247, 14, 7, 231, 246, 14, 7, 231, 245, 14, 7, 231, 244, 14, + 7, 231, 243, 14, 7, 230, 114, 14, 7, 230, 113, 14, 7, 230, 112, 14, 7, + 230, 111, 14, 7, 230, 110, 14, 7, 230, 109, 14, 7, 230, 108, 14, 7, 230, + 107, 14, 7, 230, 106, 14, 7, 228, 54, 14, 7, 228, 53, 14, 7, 228, 52, 14, + 7, 228, 51, 14, 7, 228, 50, 14, 7, 228, 49, 14, 7, 228, 48, 14, 7, 228, + 47, 14, 7, 228, 46, 14, 7, 228, 45, 14, 7, 228, 44, 14, 7, 228, 43, 14, + 7, 228, 42, 14, 7, 228, 41, 14, 7, 228, 40, 14, 7, 228, 39, 14, 7, 228, + 38, 14, 7, 228, 37, 14, 7, 228, 36, 14, 7, 222, 151, 14, 7, 222, 150, 14, + 7, 222, 149, 14, 7, 222, 148, 14, 7, 222, 147, 14, 7, 222, 146, 14, 7, + 222, 145, 14, 7, 222, 144, 14, 7, 220, 140, 14, 7, 220, 139, 14, 7, 220, + 138, 14, 7, 220, 137, 14, 7, 220, 136, 14, 7, 220, 135, 14, 7, 220, 134, + 14, 7, 220, 133, 14, 7, 220, 132, 14, 7, 220, 131, 14, 7, 218, 166, 14, + 7, 218, 165, 14, 7, 218, 164, 14, 7, 218, 162, 14, 7, 218, 160, 14, 7, + 218, 159, 14, 7, 218, 157, 14, 7, 218, 155, 14, 7, 218, 153, 14, 7, 218, + 151, 14, 7, 218, 149, 14, 7, 218, 147, 14, 7, 218, 145, 14, 7, 218, 144, + 14, 7, 218, 142, 14, 7, 218, 140, 14, 7, 218, 139, 14, 7, 218, 138, 14, + 7, 218, 137, 14, 7, 218, 136, 14, 7, 218, 135, 14, 7, 218, 134, 14, 7, + 218, 133, 14, 7, 218, 132, 14, 7, 218, 130, 14, 7, 218, 128, 14, 7, 218, + 126, 14, 7, 218, 125, 14, 7, 218, 123, 14, 7, 218, 122, 14, 7, 218, 120, + 14, 7, 218, 119, 14, 7, 218, 117, 14, 7, 218, 115, 14, 7, 218, 113, 14, + 7, 218, 111, 14, 7, 218, 109, 14, 7, 218, 108, 14, 7, 218, 106, 14, 7, + 218, 104, 14, 7, 218, 103, 14, 7, 218, 101, 14, 7, 218, 99, 14, 7, 218, + 97, 14, 7, 218, 95, 14, 7, 218, 94, 14, 7, 218, 92, 14, 7, 218, 90, 14, + 7, 218, 88, 14, 7, 218, 87, 14, 7, 218, 85, 14, 7, 218, 83, 14, 7, 218, + 82, 14, 7, 218, 81, 14, 7, 218, 79, 14, 7, 218, 77, 14, 7, 218, 75, 14, + 7, 218, 73, 14, 7, 218, 71, 14, 7, 218, 69, 14, 7, 218, 67, 14, 7, 218, + 66, 14, 7, 218, 64, 14, 7, 218, 62, 14, 7, 218, 60, 14, 7, 218, 58, 14, + 7, 215, 56, 14, 7, 215, 55, 14, 7, 215, 54, 14, 7, 215, 53, 14, 7, 215, + 52, 14, 7, 215, 51, 14, 7, 215, 50, 14, 7, 215, 49, 14, 7, 215, 48, 14, + 7, 215, 47, 14, 7, 215, 46, 14, 7, 215, 45, 14, 7, 215, 44, 14, 7, 215, + 43, 14, 7, 215, 42, 14, 7, 215, 41, 14, 7, 215, 40, 14, 7, 215, 39, 14, + 7, 215, 38, 14, 7, 215, 37, 14, 7, 215, 36, 14, 7, 215, 35, 14, 7, 215, + 34, 14, 7, 215, 33, 14, 7, 215, 32, 14, 7, 215, 31, 14, 7, 215, 30, 14, + 7, 215, 29, 14, 7, 215, 28, 14, 7, 215, 27, 14, 7, 215, 26, 14, 7, 215, + 25, 14, 7, 215, 24, 14, 7, 215, 23, 14, 7, 215, 22, 14, 7, 215, 21, 14, + 7, 215, 20, 14, 7, 215, 19, 14, 7, 215, 18, 14, 7, 215, 17, 14, 7, 215, + 16, 14, 7, 215, 15, 14, 7, 215, 14, 14, 7, 215, 13, 14, 7, 215, 12, 14, + 7, 215, 11, 14, 7, 215, 10, 14, 7, 215, 9, 14, 7, 215, 8, 14, 7, 213, + 104, 14, 7, 213, 103, 14, 7, 213, 102, 14, 7, 213, 101, 14, 7, 213, 100, + 14, 7, 213, 99, 14, 7, 213, 98, 14, 7, 213, 97, 14, 7, 213, 96, 14, 7, + 213, 95, 14, 7, 213, 94, 14, 7, 213, 93, 14, 7, 213, 92, 14, 7, 213, 91, + 14, 7, 213, 90, 14, 7, 213, 89, 14, 7, 213, 88, 14, 7, 213, 87, 14, 7, + 213, 86, 14, 7, 213, 85, 14, 7, 213, 84, 14, 7, 213, 83, 14, 7, 212, 174, + 14, 7, 212, 173, 14, 7, 212, 172, 14, 7, 212, 171, 14, 7, 212, 170, 14, + 7, 212, 169, 14, 7, 212, 168, 14, 7, 212, 167, 14, 7, 212, 166, 14, 7, + 212, 165, 14, 7, 212, 164, 14, 7, 212, 163, 14, 7, 212, 162, 14, 7, 212, + 161, 14, 7, 212, 160, 14, 7, 212, 159, 14, 7, 212, 158, 14, 7, 212, 157, + 14, 7, 212, 156, 14, 7, 212, 155, 14, 7, 212, 154, 14, 7, 212, 153, 14, + 7, 212, 152, 14, 7, 212, 151, 14, 7, 212, 150, 14, 7, 212, 149, 14, 7, + 212, 2, 14, 7, 212, 1, 14, 7, 212, 0, 14, 7, 211, 255, 14, 7, 211, 254, + 14, 7, 211, 253, 14, 7, 211, 252, 14, 7, 211, 251, 14, 7, 211, 250, 14, + 7, 211, 249, 14, 7, 211, 248, 14, 7, 211, 247, 14, 7, 211, 246, 14, 7, + 211, 245, 14, 7, 211, 244, 14, 7, 211, 243, 14, 7, 211, 242, 14, 7, 211, + 241, 14, 7, 211, 240, 14, 7, 211, 239, 14, 7, 211, 238, 14, 7, 211, 237, + 14, 7, 211, 236, 14, 7, 211, 235, 14, 7, 211, 234, 14, 7, 211, 233, 14, + 7, 211, 232, 14, 7, 211, 231, 14, 7, 211, 230, 14, 7, 211, 229, 14, 7, + 211, 228, 14, 7, 211, 227, 14, 7, 211, 226, 14, 7, 211, 225, 14, 7, 211, + 224, 14, 7, 211, 223, 14, 7, 211, 222, 14, 7, 211, 221, 14, 7, 211, 220, + 14, 7, 211, 219, 14, 7, 211, 218, 14, 7, 211, 217, 14, 7, 211, 216, 14, + 7, 211, 215, 14, 7, 211, 214, 14, 7, 211, 213, 14, 7, 211, 212, 14, 7, + 211, 211, 14, 7, 211, 210, 14, 7, 211, 209, 14, 7, 211, 208, 14, 7, 211, + 207, 14, 7, 211, 206, 14, 7, 211, 205, 14, 7, 211, 204, 14, 7, 211, 203, + 14, 7, 211, 202, 14, 7, 211, 201, 14, 7, 211, 200, 14, 7, 211, 199, 14, + 7, 211, 198, 14, 7, 211, 197, 14, 7, 211, 196, 14, 7, 211, 195, 14, 7, + 211, 194, 14, 7, 211, 193, 14, 7, 211, 192, 14, 7, 211, 191, 14, 7, 211, + 190, 14, 7, 211, 189, 14, 7, 211, 188, 14, 7, 211, 187, 14, 7, 211, 186, + 14, 7, 211, 185, 14, 7, 211, 184, 14, 7, 210, 235, 14, 7, 210, 234, 14, + 7, 210, 233, 14, 7, 210, 232, 14, 7, 210, 231, 14, 7, 210, 230, 14, 7, + 210, 229, 14, 7, 210, 228, 14, 7, 210, 227, 14, 7, 210, 226, 14, 7, 210, + 225, 14, 7, 210, 224, 14, 7, 210, 223, 14, 7, 208, 103, 14, 7, 208, 102, + 14, 7, 208, 101, 14, 7, 208, 100, 14, 7, 208, 99, 14, 7, 208, 98, 14, 7, + 208, 97, 14, 7, 207, 220, 14, 7, 207, 219, 14, 7, 207, 218, 14, 7, 207, + 217, 14, 7, 207, 216, 14, 7, 207, 215, 14, 7, 207, 214, 14, 7, 207, 213, + 14, 7, 207, 212, 14, 7, 207, 211, 14, 7, 207, 210, 14, 7, 207, 209, 14, + 7, 207, 208, 14, 7, 207, 207, 14, 7, 207, 206, 14, 7, 207, 205, 14, 7, + 207, 204, 14, 7, 207, 203, 14, 7, 207, 202, 14, 7, 207, 201, 14, 7, 207, + 200, 14, 7, 207, 199, 14, 7, 207, 198, 14, 7, 207, 197, 14, 7, 207, 196, + 14, 7, 207, 195, 14, 7, 207, 194, 14, 7, 207, 193, 14, 7, 207, 192, 14, + 7, 207, 191, 14, 7, 207, 190, 14, 7, 207, 189, 14, 7, 207, 188, 14, 7, + 207, 187, 14, 7, 206, 5, 14, 7, 206, 4, 14, 7, 206, 3, 14, 7, 206, 2, 14, + 7, 206, 1, 14, 7, 206, 0, 14, 7, 205, 255, 14, 7, 205, 254, 14, 7, 205, + 253, 14, 7, 205, 252, 14, 7, 205, 251, 14, 7, 205, 250, 14, 7, 205, 249, + 14, 7, 205, 248, 14, 7, 205, 247, 14, 7, 205, 246, 14, 7, 205, 245, 14, + 7, 205, 244, 14, 7, 205, 243, 14, 7, 205, 242, 14, 7, 205, 241, 14, 7, + 205, 240, 14, 7, 205, 239, 14, 7, 205, 238, 14, 7, 205, 237, 14, 7, 205, + 236, 14, 7, 205, 235, 14, 7, 205, 234, 14, 7, 205, 233, 14, 7, 205, 232, + 14, 7, 205, 231, 14, 7, 205, 230, 14, 7, 205, 229, 14, 7, 205, 228, 14, + 7, 205, 227, 14, 7, 205, 226, 14, 7, 205, 225, 14, 7, 205, 224, 14, 7, + 205, 223, 14, 7, 205, 222, 14, 7, 205, 221, 14, 7, 205, 220, 14, 7, 205, + 219, 14, 7, 205, 218, 14, 7, 205, 217, 14, 7, 205, 216, 14, 7, 205, 215, + 14, 7, 205, 214, 14, 7, 205, 213, 14, 7, 205, 212, 14, 7, 205, 211, 14, + 7, 205, 210, 14, 7, 205, 209, 14, 7, 205, 208, 14, 7, 200, 40, 14, 7, + 200, 39, 14, 7, 200, 38, 14, 7, 200, 37, 14, 7, 200, 36, 14, 7, 200, 35, + 14, 7, 200, 34, 14, 7, 200, 33, 14, 7, 200, 32, 14, 7, 200, 31, 14, 7, + 200, 30, 14, 7, 200, 29, 14, 7, 200, 28, 14, 7, 200, 27, 14, 7, 200, 26, + 14, 7, 200, 25, 14, 7, 200, 24, 14, 7, 200, 23, 14, 7, 200, 22, 14, 7, + 200, 21, 14, 7, 200, 20, 14, 7, 200, 19, 14, 7, 200, 18, 14, 7, 200, 17, + 14, 7, 200, 16, 14, 7, 200, 15, 14, 7, 200, 14, 14, 7, 200, 13, 14, 7, + 200, 12, 14, 7, 200, 11, 14, 7, 200, 10, 14, 7, 200, 9, 14, 7, 200, 8, 14, 7, 200, 7, 14, 7, 200, 6, 14, 7, 200, 5, 14, 7, 200, 4, 14, 7, 200, 3, 14, 7, 200, 2, 14, 7, 200, 1, 14, 7, 200, 0, 14, 7, 199, 255, 14, 7, - 199, 254, 14, 7, 199, 253, 14, 7, 199, 252, 14, 7, 199, 251, 14, 7, 199, - 250, 14, 7, 199, 249, 14, 7, 196, 213, 14, 7, 196, 212, 14, 7, 196, 211, + 199, 254, 14, 7, 199, 253, 14, 7, 196, 217, 14, 7, 196, 216, 14, 7, 196, + 215, 14, 7, 196, 214, 14, 7, 196, 213, 14, 7, 196, 212, 14, 7, 196, 211, 14, 7, 196, 210, 14, 7, 196, 209, 14, 7, 196, 208, 14, 7, 196, 207, 14, 7, 196, 206, 14, 7, 196, 205, 14, 7, 196, 204, 14, 7, 196, 203, 14, 7, 196, 202, 14, 7, 196, 201, 14, 7, 196, 200, 14, 7, 196, 199, 14, 7, 196, @@ -16815,74 +16874,101 @@ static const unsigned char phrasebook[] = { 196, 185, 14, 7, 196, 184, 14, 7, 196, 183, 14, 7, 196, 182, 14, 7, 196, 181, 14, 7, 196, 180, 14, 7, 196, 179, 14, 7, 196, 178, 14, 7, 196, 177, 14, 7, 196, 176, 14, 7, 196, 175, 14, 7, 196, 174, 14, 7, 196, 173, 14, - 7, 196, 172, 14, 7, 196, 171, 14, 7, 196, 170, 14, 7, 196, 169, 14, 7, - 196, 168, 14, 7, 196, 167, 14, 7, 196, 7, 14, 7, 196, 6, 14, 7, 196, 5, - 14, 7, 196, 4, 14, 7, 196, 3, 14, 7, 196, 2, 14, 7, 196, 1, 14, 7, 196, - 0, 14, 7, 195, 255, 14, 7, 195, 254, 14, 7, 195, 253, 14, 7, 195, 252, - 14, 7, 195, 251, 14, 7, 195, 250, 14, 7, 195, 249, 14, 7, 195, 248, 14, - 7, 195, 247, 14, 7, 195, 246, 14, 7, 195, 245, 14, 7, 195, 244, 14, 7, - 195, 243, 14, 7, 195, 242, 14, 7, 195, 241, 14, 7, 195, 240, 14, 7, 195, - 239, 14, 7, 195, 238, 14, 7, 195, 237, 14, 7, 195, 236, 14, 7, 195, 235, - 14, 7, 195, 234, 14, 7, 195, 233, 14, 7, 195, 232, 14, 7, 195, 231, 14, - 7, 195, 230, 14, 7, 195, 229, 14, 7, 195, 228, 14, 7, 195, 227, 14, 7, - 195, 226, 14, 7, 195, 225, 14, 7, 195, 224, 14, 7, 195, 223, 14, 7, 195, - 222, 14, 7, 195, 221, 14, 7, 195, 220, 14, 7, 195, 219, 14, 7, 195, 218, - 14, 7, 195, 217, 14, 7, 195, 216, 14, 7, 195, 215, 14, 7, 195, 214, 14, - 7, 195, 213, 14, 7, 195, 212, 14, 7, 195, 211, 14, 7, 195, 210, 14, 7, - 195, 209, 14, 7, 195, 208, 14, 7, 195, 207, 14, 7, 195, 206, 14, 7, 195, - 205, 14, 7, 195, 204, 14, 7, 195, 203, 14, 7, 195, 202, 14, 7, 195, 201, - 14, 7, 195, 200, 14, 7, 195, 199, 14, 7, 195, 198, 14, 7, 195, 197, 14, - 7, 195, 196, 14, 7, 195, 195, 14, 7, 195, 194, 14, 7, 195, 193, 14, 7, - 195, 192, 14, 7, 195, 191, 14, 7, 195, 190, 14, 7, 195, 189, 14, 7, 195, - 188, 14, 7, 195, 187, 14, 7, 193, 220, 14, 7, 193, 219, 14, 7, 193, 218, - 14, 7, 193, 217, 14, 7, 193, 216, 14, 7, 193, 215, 14, 7, 193, 214, 14, - 7, 193, 213, 14, 7, 193, 212, 14, 7, 193, 211, 14, 7, 193, 210, 14, 7, - 193, 209, 14, 7, 193, 208, 14, 7, 193, 207, 14, 7, 193, 206, 14, 7, 193, - 205, 14, 7, 193, 204, 14, 7, 193, 203, 14, 7, 193, 202, 14, 7, 193, 201, - 14, 7, 193, 200, 14, 7, 193, 199, 14, 7, 193, 198, 14, 7, 193, 197, 14, - 7, 193, 196, 14, 7, 193, 195, 14, 7, 193, 194, 14, 7, 193, 193, 14, 7, - 193, 192, 14, 7, 193, 191, 14, 7, 193, 190, 14, 7, 193, 189, 14, 7, 192, - 232, 14, 7, 192, 231, 14, 7, 192, 230, 14, 7, 192, 229, 14, 7, 192, 228, - 14, 7, 192, 227, 14, 7, 192, 226, 14, 7, 192, 225, 14, 7, 192, 224, 14, - 7, 192, 223, 14, 7, 192, 222, 14, 7, 192, 221, 14, 7, 192, 157, 14, 7, - 192, 156, 14, 7, 192, 155, 14, 7, 192, 154, 14, 7, 192, 153, 14, 7, 192, - 152, 14, 7, 192, 151, 14, 7, 192, 150, 14, 7, 192, 149, 14, 7, 191, 165, - 14, 7, 191, 164, 14, 7, 191, 163, 14, 7, 191, 162, 14, 7, 191, 161, 14, - 7, 191, 160, 14, 7, 191, 159, 14, 7, 191, 158, 14, 7, 191, 157, 14, 7, - 191, 156, 14, 7, 191, 155, 14, 7, 191, 154, 14, 7, 191, 153, 14, 7, 191, - 152, 14, 7, 191, 151, 14, 7, 191, 150, 14, 7, 191, 149, 14, 7, 191, 148, - 14, 7, 191, 147, 14, 7, 191, 146, 14, 7, 191, 145, 14, 7, 191, 144, 14, - 7, 191, 143, 14, 7, 191, 142, 14, 7, 191, 141, 14, 7, 191, 140, 14, 7, - 191, 139, 14, 7, 191, 138, 14, 7, 191, 137, 14, 7, 191, 136, 14, 7, 191, - 135, 14, 7, 191, 134, 14, 7, 191, 133, 14, 7, 191, 132, 14, 7, 191, 131, - 14, 7, 191, 130, 14, 7, 191, 129, 14, 7, 191, 128, 14, 7, 191, 127, 14, - 7, 191, 126, 14, 7, 191, 125, 14, 7, 252, 153, 14, 7, 252, 152, 14, 7, - 252, 151, 14, 7, 252, 150, 14, 7, 252, 149, 14, 7, 252, 148, 14, 7, 252, - 147, 14, 7, 252, 146, 14, 7, 252, 145, 14, 7, 252, 144, 14, 7, 252, 143, - 14, 7, 252, 142, 14, 7, 252, 141, 14, 7, 252, 140, 14, 7, 252, 139, 14, - 7, 252, 138, 14, 7, 252, 137, 14, 7, 252, 136, 14, 7, 252, 135, 14, 7, - 252, 134, 14, 7, 252, 133, 14, 7, 252, 132, 14, 7, 252, 131, 14, 7, 252, - 130, 14, 7, 252, 129, 14, 7, 252, 128, 14, 7, 252, 127, 14, 7, 252, 126, - 14, 7, 252, 125, 14, 7, 252, 124, 14, 7, 252, 123, 14, 7, 252, 122, 14, - 7, 252, 121, 14, 7, 252, 120, 14, 7, 81, 222, 169, 14, 7, 228, 209, 222, - 169, 14, 7, 223, 92, 250, 133, 198, 49, 201, 92, 14, 7, 223, 92, 250, - 133, 248, 29, 201, 92, 14, 7, 223, 92, 250, 133, 198, 49, 234, 52, 14, 7, - 223, 92, 250, 133, 248, 29, 234, 52, 14, 7, 210, 246, 216, 66, 14, 7, - 248, 199, 205, 38, 14, 7, 234, 53, 205, 38, 29, 7, 255, 147, 29, 7, 255, - 146, 29, 7, 255, 145, 29, 7, 255, 144, 29, 7, 255, 143, 29, 7, 255, 141, - 29, 7, 255, 138, 29, 7, 255, 137, 29, 7, 255, 136, 29, 7, 255, 135, 29, - 7, 255, 134, 29, 7, 255, 133, 29, 7, 255, 132, 29, 7, 255, 131, 29, 7, - 255, 130, 29, 7, 255, 128, 29, 7, 255, 127, 29, 7, 255, 126, 29, 7, 255, - 124, 29, 7, 255, 123, 29, 7, 255, 122, 29, 7, 255, 121, 29, 7, 255, 120, - 29, 7, 255, 119, 29, 7, 255, 118, 29, 7, 255, 117, 29, 7, 255, 116, 29, - 7, 255, 115, 29, 7, 255, 114, 29, 7, 255, 113, 29, 7, 255, 111, 29, 7, - 255, 110, 29, 7, 255, 109, 29, 7, 255, 108, 29, 7, 255, 106, 29, 7, 255, - 105, 29, 7, 255, 104, 29, 7, 255, 103, 29, 7, 255, 102, 29, 7, 255, 101, - 29, 7, 255, 100, 29, 7, 255, 99, 29, 7, 255, 98, 29, 7, 255, 96, 29, 7, - 255, 95, 29, 7, 255, 94, 29, 7, 255, 92, 29, 7, 255, 90, 29, 7, 255, 89, - 29, 7, 255, 88, 29, 7, 255, 87, 29, 7, 255, 86, 29, 7, 255, 85, 29, 7, - 255, 84, 29, 7, 255, 83, 29, 7, 255, 82, 29, 7, 255, 81, 29, 7, 255, 80, - 29, 7, 255, 79, 29, 7, 255, 78, 29, 7, 255, 77, 29, 7, 255, 76, 29, 7, + 7, 196, 172, 14, 7, 196, 171, 14, 7, 196, 11, 14, 7, 196, 10, 14, 7, 196, + 9, 14, 7, 196, 8, 14, 7, 196, 7, 14, 7, 196, 6, 14, 7, 196, 5, 14, 7, + 196, 4, 14, 7, 196, 3, 14, 7, 196, 2, 14, 7, 196, 1, 14, 7, 196, 0, 14, + 7, 195, 255, 14, 7, 195, 254, 14, 7, 195, 253, 14, 7, 195, 252, 14, 7, + 195, 251, 14, 7, 195, 250, 14, 7, 195, 249, 14, 7, 195, 248, 14, 7, 195, + 247, 14, 7, 195, 246, 14, 7, 195, 245, 14, 7, 195, 244, 14, 7, 195, 243, + 14, 7, 195, 242, 14, 7, 195, 240, 14, 7, 195, 239, 14, 7, 195, 238, 14, + 7, 195, 237, 14, 7, 195, 236, 14, 7, 195, 235, 14, 7, 195, 234, 14, 7, + 195, 233, 14, 7, 195, 232, 14, 7, 195, 231, 14, 7, 195, 230, 14, 7, 195, + 229, 14, 7, 195, 228, 14, 7, 195, 227, 14, 7, 195, 226, 14, 7, 195, 225, + 14, 7, 195, 224, 14, 7, 195, 223, 14, 7, 195, 222, 14, 7, 195, 221, 14, + 7, 195, 220, 14, 7, 195, 219, 14, 7, 195, 218, 14, 7, 195, 217, 14, 7, + 195, 216, 14, 7, 195, 215, 14, 7, 195, 214, 14, 7, 195, 213, 14, 7, 195, + 212, 14, 7, 195, 211, 14, 7, 195, 210, 14, 7, 195, 209, 14, 7, 195, 208, + 14, 7, 195, 207, 14, 7, 195, 206, 14, 7, 195, 205, 14, 7, 195, 204, 14, + 7, 195, 203, 14, 7, 195, 202, 14, 7, 195, 201, 14, 7, 195, 200, 14, 7, + 195, 199, 14, 7, 195, 198, 14, 7, 195, 197, 14, 7, 195, 196, 14, 7, 195, + 195, 14, 7, 195, 194, 14, 7, 195, 193, 14, 7, 195, 192, 14, 7, 195, 191, + 14, 7, 195, 190, 14, 7, 193, 223, 14, 7, 193, 222, 14, 7, 193, 221, 14, + 7, 193, 220, 14, 7, 193, 219, 14, 7, 193, 218, 14, 7, 193, 217, 14, 7, + 193, 216, 14, 7, 193, 215, 14, 7, 193, 214, 14, 7, 193, 213, 14, 7, 193, + 212, 14, 7, 193, 211, 14, 7, 193, 210, 14, 7, 193, 209, 14, 7, 193, 208, + 14, 7, 193, 207, 14, 7, 193, 206, 14, 7, 193, 205, 14, 7, 193, 204, 14, + 7, 193, 203, 14, 7, 193, 202, 14, 7, 193, 201, 14, 7, 193, 200, 14, 7, + 193, 199, 14, 7, 193, 198, 14, 7, 193, 197, 14, 7, 193, 196, 14, 7, 193, + 195, 14, 7, 193, 194, 14, 7, 193, 193, 14, 7, 193, 192, 14, 7, 192, 232, + 14, 7, 192, 231, 14, 7, 192, 230, 14, 7, 192, 229, 14, 7, 192, 228, 14, + 7, 192, 227, 14, 7, 192, 226, 14, 7, 192, 225, 14, 7, 192, 224, 14, 7, + 192, 223, 14, 7, 192, 222, 14, 7, 192, 221, 14, 7, 192, 157, 14, 7, 192, + 156, 14, 7, 192, 155, 14, 7, 192, 154, 14, 7, 192, 153, 14, 7, 192, 152, + 14, 7, 192, 151, 14, 7, 192, 150, 14, 7, 192, 149, 14, 7, 191, 165, 14, + 7, 191, 164, 14, 7, 191, 163, 14, 7, 191, 162, 14, 7, 191, 161, 14, 7, + 191, 160, 14, 7, 191, 159, 14, 7, 191, 158, 14, 7, 191, 157, 14, 7, 191, + 156, 14, 7, 191, 155, 14, 7, 191, 154, 14, 7, 191, 153, 14, 7, 191, 152, + 14, 7, 191, 151, 14, 7, 191, 150, 14, 7, 191, 149, 14, 7, 191, 148, 14, + 7, 191, 147, 14, 7, 191, 146, 14, 7, 191, 145, 14, 7, 191, 144, 14, 7, + 191, 143, 14, 7, 191, 142, 14, 7, 191, 141, 14, 7, 191, 140, 14, 7, 191, + 139, 14, 7, 191, 138, 14, 7, 191, 137, 14, 7, 191, 136, 14, 7, 191, 135, + 14, 7, 191, 134, 14, 7, 191, 133, 14, 7, 191, 132, 14, 7, 191, 131, 14, + 7, 191, 130, 14, 7, 191, 129, 14, 7, 191, 128, 14, 7, 191, 127, 14, 7, + 191, 126, 14, 7, 191, 125, 14, 7, 252, 205, 14, 7, 252, 204, 14, 7, 252, + 203, 14, 7, 252, 202, 14, 7, 252, 201, 14, 7, 252, 200, 14, 7, 252, 199, + 14, 7, 252, 198, 14, 7, 252, 197, 14, 7, 252, 196, 14, 7, 252, 195, 14, + 7, 252, 194, 14, 7, 252, 193, 14, 7, 252, 192, 14, 7, 252, 191, 14, 7, + 252, 190, 14, 7, 252, 189, 14, 7, 252, 188, 14, 7, 252, 187, 14, 7, 252, + 186, 14, 7, 252, 185, 14, 7, 252, 184, 14, 7, 252, 183, 14, 7, 252, 182, + 14, 7, 252, 181, 14, 7, 252, 180, 14, 7, 252, 179, 14, 7, 252, 178, 14, + 7, 252, 177, 14, 7, 252, 176, 14, 7, 252, 175, 14, 7, 252, 174, 14, 7, + 252, 173, 14, 7, 252, 172, 14, 7, 195, 241, 14, 7, 81, 222, 196, 14, 7, + 228, 241, 222, 196, 14, 7, 223, 120, 250, 183, 198, 54, 201, 97, 14, 7, + 223, 120, 250, 183, 248, 77, 201, 97, 14, 7, 223, 120, 250, 183, 198, 54, + 234, 94, 14, 7, 223, 120, 250, 183, 248, 77, 234, 94, 14, 7, 211, 0, 216, + 84, 14, 7, 248, 249, 205, 43, 14, 7, 234, 95, 205, 43, 14, 7, 223, 120, + 250, 183, 216, 84, 14, 7, 223, 120, 250, 183, 198, 53, 14, 7, 223, 120, + 250, 183, 248, 76, 14, 7, 248, 249, 234, 98, 14, 7, 234, 95, 234, 98, 14, + 7, 248, 249, 193, 166, 234, 98, 14, 7, 234, 95, 193, 166, 234, 98, 14, 7, + 216, 27, 228, 189, 14, 7, 232, 80, 248, 132, 14, 7, 132, 248, 132, 14, 7, + 218, 251, 56, 14, 7, 132, 218, 251, 56, 14, 7, 199, 200, 218, 251, 56, + 14, 7, 193, 78, 218, 251, 56, 14, 7, 52, 237, 249, 250, 183, 198, 54, + 201, 97, 14, 7, 52, 237, 249, 250, 183, 248, 77, 201, 97, 14, 7, 52, 237, + 249, 250, 183, 201, 97, 14, 7, 52, 237, 249, 250, 183, 198, 54, 234, 94, + 14, 7, 52, 237, 249, 250, 183, 198, 53, 14, 7, 52, 237, 249, 250, 183, + 248, 77, 201, 98, 23, 198, 54, 234, 94, 14, 7, 52, 237, 249, 250, 183, + 201, 98, 23, 198, 53, 14, 7, 52, 237, 249, 250, 183, 248, 77, 234, 94, + 14, 7, 52, 237, 249, 250, 183, 198, 54, 201, 98, 23, 248, 77, 234, 94, + 14, 7, 52, 237, 249, 250, 183, 248, 76, 14, 7, 52, 237, 249, 250, 183, + 201, 98, 23, 248, 76, 14, 7, 52, 237, 249, 250, 183, 234, 94, 14, 7, 52, + 237, 249, 250, 183, 198, 54, 23, 234, 94, 14, 7, 52, 237, 249, 250, 183, + 248, 77, 23, 234, 94, 14, 7, 52, 237, 248, 29, 7, 255, 199, 29, 7, 255, + 198, 29, 7, 255, 197, 29, 7, 255, 196, 29, 7, 255, 195, 29, 7, 255, 193, + 29, 7, 255, 190, 29, 7, 255, 189, 29, 7, 255, 188, 29, 7, 255, 187, 29, + 7, 255, 186, 29, 7, 255, 185, 29, 7, 255, 184, 29, 7, 255, 183, 29, 7, + 255, 182, 29, 7, 255, 180, 29, 7, 255, 179, 29, 7, 255, 178, 29, 7, 255, + 176, 29, 7, 255, 175, 29, 7, 255, 174, 29, 7, 255, 173, 29, 7, 255, 172, + 29, 7, 255, 171, 29, 7, 255, 170, 29, 7, 255, 169, 29, 7, 255, 168, 29, + 7, 255, 167, 29, 7, 255, 166, 29, 7, 255, 165, 29, 7, 255, 163, 29, 7, + 255, 162, 29, 7, 255, 161, 29, 7, 255, 160, 29, 7, 255, 158, 29, 7, 255, + 157, 29, 7, 255, 156, 29, 7, 255, 155, 29, 7, 255, 154, 29, 7, 255, 153, + 29, 7, 255, 152, 29, 7, 255, 151, 29, 7, 255, 150, 29, 7, 255, 148, 29, + 7, 255, 147, 29, 7, 255, 146, 29, 7, 255, 144, 29, 7, 255, 142, 29, 7, + 255, 141, 29, 7, 255, 140, 29, 7, 255, 139, 29, 7, 255, 138, 29, 7, 255, + 137, 29, 7, 255, 136, 29, 7, 255, 135, 29, 7, 255, 134, 29, 7, 255, 133, + 29, 7, 255, 132, 29, 7, 255, 131, 29, 7, 255, 130, 29, 7, 255, 129, 29, + 7, 255, 128, 29, 7, 255, 127, 29, 7, 255, 126, 29, 7, 255, 125, 29, 7, + 255, 124, 29, 7, 255, 123, 29, 7, 255, 122, 29, 7, 255, 121, 29, 7, 255, + 120, 29, 7, 255, 119, 29, 7, 255, 118, 29, 7, 255, 117, 29, 7, 255, 116, + 29, 7, 255, 115, 29, 7, 255, 114, 29, 7, 255, 113, 29, 7, 255, 112, 29, + 7, 255, 111, 29, 7, 255, 110, 29, 7, 255, 109, 29, 7, 255, 108, 29, 7, + 255, 107, 29, 7, 255, 106, 29, 7, 255, 105, 29, 7, 255, 104, 29, 7, 255, + 103, 29, 7, 255, 102, 29, 7, 255, 101, 29, 7, 255, 100, 29, 7, 255, 99, + 29, 7, 255, 98, 29, 7, 255, 97, 29, 7, 255, 96, 29, 7, 255, 95, 29, 7, + 255, 94, 29, 7, 255, 93, 29, 7, 255, 92, 29, 7, 255, 91, 29, 7, 255, 90, + 29, 7, 255, 89, 29, 7, 255, 88, 29, 7, 255, 87, 29, 7, 255, 86, 29, 7, + 255, 85, 29, 7, 255, 84, 29, 7, 255, 83, 29, 7, 255, 82, 29, 7, 255, 81, + 29, 7, 255, 80, 29, 7, 255, 79, 29, 7, 255, 78, 29, 7, 255, 76, 29, 7, 255, 75, 29, 7, 255, 74, 29, 7, 255, 73, 29, 7, 255, 72, 29, 7, 255, 71, 29, 7, 255, 70, 29, 7, 255, 69, 29, 7, 255, 68, 29, 7, 255, 67, 29, 7, 255, 66, 29, 7, 255, 65, 29, 7, 255, 64, 29, 7, 255, 63, 29, 7, 255, 62, @@ -16890,25 +16976,25 @@ static const unsigned char phrasebook[] = { 255, 57, 29, 7, 255, 56, 29, 7, 255, 55, 29, 7, 255, 54, 29, 7, 255, 53, 29, 7, 255, 52, 29, 7, 255, 51, 29, 7, 255, 50, 29, 7, 255, 49, 29, 7, 255, 48, 29, 7, 255, 47, 29, 7, 255, 46, 29, 7, 255, 45, 29, 7, 255, 44, - 29, 7, 255, 43, 29, 7, 255, 42, 29, 7, 255, 41, 29, 7, 255, 40, 29, 7, - 255, 39, 29, 7, 255, 38, 29, 7, 255, 37, 29, 7, 255, 36, 29, 7, 255, 35, - 29, 7, 255, 34, 29, 7, 255, 33, 29, 7, 255, 32, 29, 7, 255, 31, 29, 7, - 255, 30, 29, 7, 255, 29, 29, 7, 255, 28, 29, 7, 255, 27, 29, 7, 255, 26, - 29, 7, 255, 24, 29, 7, 255, 23, 29, 7, 255, 22, 29, 7, 255, 21, 29, 7, - 255, 20, 29, 7, 255, 19, 29, 7, 255, 18, 29, 7, 255, 17, 29, 7, 255, 16, - 29, 7, 255, 15, 29, 7, 255, 14, 29, 7, 255, 13, 29, 7, 255, 12, 29, 7, - 255, 11, 29, 7, 255, 10, 29, 7, 255, 9, 29, 7, 255, 8, 29, 7, 255, 7, 29, - 7, 255, 6, 29, 7, 255, 5, 29, 7, 255, 4, 29, 7, 255, 3, 29, 7, 255, 2, - 29, 7, 255, 1, 29, 7, 255, 0, 29, 7, 254, 255, 29, 7, 254, 254, 29, 7, - 254, 253, 29, 7, 254, 252, 29, 7, 254, 251, 29, 7, 254, 250, 29, 7, 254, - 249, 29, 7, 254, 248, 29, 7, 254, 247, 29, 7, 254, 245, 29, 7, 254, 244, + 29, 7, 255, 43, 29, 7, 255, 41, 29, 7, 255, 40, 29, 7, 255, 39, 29, 7, + 255, 38, 29, 7, 255, 37, 29, 7, 255, 36, 29, 7, 255, 35, 29, 7, 255, 34, + 29, 7, 255, 33, 29, 7, 255, 32, 29, 7, 255, 31, 29, 7, 255, 30, 29, 7, + 255, 28, 29, 7, 255, 27, 29, 7, 255, 26, 29, 7, 255, 25, 29, 7, 255, 24, + 29, 7, 255, 23, 29, 7, 255, 22, 29, 7, 255, 21, 29, 7, 255, 20, 29, 7, + 255, 19, 29, 7, 255, 18, 29, 7, 255, 17, 29, 7, 255, 16, 29, 7, 255, 15, + 29, 7, 255, 14, 29, 7, 255, 13, 29, 7, 255, 12, 29, 7, 255, 11, 29, 7, + 255, 10, 29, 7, 255, 9, 29, 7, 255, 8, 29, 7, 255, 7, 29, 7, 255, 6, 29, + 7, 255, 5, 29, 7, 255, 4, 29, 7, 255, 3, 29, 7, 255, 2, 29, 7, 255, 1, + 29, 7, 255, 0, 29, 7, 254, 255, 29, 7, 254, 254, 29, 7, 254, 253, 29, 7, + 254, 252, 29, 7, 254, 251, 29, 7, 254, 250, 29, 7, 254, 249, 29, 7, 254, + 248, 29, 7, 254, 247, 29, 7, 254, 246, 29, 7, 254, 245, 29, 7, 254, 244, 29, 7, 254, 243, 29, 7, 254, 242, 29, 7, 254, 241, 29, 7, 254, 240, 29, 7, 254, 239, 29, 7, 254, 238, 29, 7, 254, 237, 29, 7, 254, 236, 29, 7, - 254, 235, 29, 7, 254, 234, 29, 7, 254, 232, 29, 7, 254, 231, 29, 7, 254, - 230, 29, 7, 254, 229, 29, 7, 254, 228, 29, 7, 254, 227, 29, 7, 254, 226, - 29, 7, 254, 225, 29, 7, 254, 224, 29, 7, 254, 223, 29, 7, 254, 222, 29, - 7, 254, 221, 29, 7, 254, 220, 29, 7, 254, 219, 29, 7, 254, 218, 29, 7, - 254, 217, 29, 7, 254, 216, 29, 7, 254, 215, 29, 7, 254, 214, 29, 7, 254, + 254, 235, 29, 7, 254, 234, 29, 7, 254, 233, 29, 7, 254, 232, 29, 7, 254, + 231, 29, 7, 254, 230, 29, 7, 254, 229, 29, 7, 254, 228, 29, 7, 254, 227, + 29, 7, 254, 226, 29, 7, 254, 225, 29, 7, 254, 224, 29, 7, 254, 223, 29, + 7, 254, 222, 29, 7, 254, 221, 29, 7, 254, 220, 29, 7, 254, 219, 29, 7, + 254, 218, 29, 7, 254, 217, 29, 7, 254, 216, 29, 7, 254, 214, 29, 7, 254, 213, 29, 7, 254, 212, 29, 7, 254, 211, 29, 7, 254, 210, 29, 7, 254, 209, 29, 7, 254, 208, 29, 7, 254, 207, 29, 7, 254, 206, 29, 7, 254, 205, 29, 7, 254, 204, 29, 7, 254, 203, 29, 7, 254, 202, 29, 7, 254, 201, 29, 7, @@ -16920,472 +17006,469 @@ static const unsigned char phrasebook[] = { 179, 29, 7, 254, 178, 29, 7, 254, 177, 29, 7, 254, 176, 29, 7, 254, 175, 29, 7, 254, 174, 29, 7, 254, 173, 29, 7, 254, 172, 29, 7, 254, 171, 29, 7, 254, 170, 29, 7, 254, 169, 29, 7, 254, 168, 29, 7, 254, 167, 29, 7, - 254, 166, 29, 7, 254, 165, 29, 7, 254, 164, 29, 7, 254, 162, 29, 7, 254, - 161, 29, 7, 254, 160, 29, 7, 254, 159, 29, 7, 254, 158, 29, 7, 254, 157, - 29, 7, 254, 156, 29, 7, 254, 155, 29, 7, 254, 154, 29, 7, 254, 153, 29, - 7, 254, 152, 29, 7, 254, 151, 29, 7, 254, 150, 29, 7, 254, 149, 29, 7, - 254, 148, 29, 7, 254, 147, 29, 7, 254, 146, 29, 7, 254, 145, 29, 7, 254, - 144, 29, 7, 254, 143, 29, 7, 254, 142, 29, 7, 254, 141, 29, 7, 254, 140, - 29, 7, 254, 139, 29, 7, 254, 138, 29, 7, 254, 137, 29, 7, 254, 136, 29, - 7, 254, 135, 29, 7, 254, 134, 29, 7, 254, 133, 29, 7, 254, 132, 29, 7, - 254, 131, 29, 7, 254, 130, 29, 7, 254, 129, 29, 7, 254, 128, 29, 7, 254, - 127, 29, 7, 254, 126, 29, 7, 254, 125, 29, 7, 254, 124, 29, 7, 254, 123, - 29, 7, 254, 122, 29, 7, 254, 121, 29, 7, 254, 120, 29, 7, 254, 119, 29, - 7, 254, 118, 29, 7, 254, 117, 29, 7, 254, 116, 29, 7, 254, 115, 29, 7, - 254, 114, 29, 7, 254, 113, 29, 7, 254, 112, 29, 7, 254, 111, 29, 7, 254, - 110, 29, 7, 254, 109, 29, 7, 254, 108, 29, 7, 254, 107, 29, 7, 254, 106, - 29, 7, 254, 105, 29, 7, 254, 104, 29, 7, 254, 103, 29, 7, 254, 102, 29, + 254, 166, 29, 7, 254, 165, 29, 7, 254, 164, 29, 7, 254, 163, 29, 7, 254, + 162, 29, 7, 254, 161, 29, 7, 254, 160, 29, 7, 254, 159, 29, 7, 254, 158, + 29, 7, 254, 157, 29, 7, 254, 156, 29, 7, 254, 155, 29, 7, 254, 154, 29, + 7, 254, 153, 29, 7, 254, 152, 29, 7, 254, 151, 29, 7, 254, 150, 29, 7, + 254, 149, 29, 7, 254, 148, 29, 7, 254, 147, 29, 7, 254, 146, 29, 7, 254, + 145, 29, 7, 254, 144, 29, 7, 254, 143, 29, 7, 254, 142, 29, 7, 254, 141, + 29, 7, 254, 140, 29, 7, 254, 139, 29, 7, 254, 138, 29, 7, 254, 137, 29, + 7, 254, 136, 29, 7, 254, 135, 29, 7, 254, 134, 29, 7, 254, 133, 29, 7, + 254, 132, 29, 7, 254, 131, 29, 7, 254, 130, 29, 7, 254, 129, 29, 7, 254, + 128, 29, 7, 254, 127, 29, 7, 254, 126, 29, 7, 254, 125, 29, 7, 254, 124, + 29, 7, 254, 123, 29, 7, 254, 122, 29, 7, 254, 121, 29, 7, 254, 120, 29, + 7, 254, 119, 29, 7, 254, 118, 29, 7, 254, 117, 29, 7, 254, 116, 29, 7, + 254, 115, 29, 7, 254, 114, 29, 7, 254, 113, 29, 7, 254, 112, 29, 7, 254, + 111, 29, 7, 254, 110, 29, 7, 254, 109, 29, 7, 254, 108, 29, 7, 254, 107, + 29, 7, 254, 106, 29, 7, 254, 105, 29, 7, 254, 104, 29, 7, 254, 102, 29, 7, 254, 101, 29, 7, 254, 100, 29, 7, 254, 99, 29, 7, 254, 98, 29, 7, 254, 97, 29, 7, 254, 96, 29, 7, 254, 95, 29, 7, 254, 94, 29, 7, 254, 93, 29, - 7, 254, 92, 29, 7, 254, 91, 29, 7, 254, 90, 29, 7, 254, 89, 29, 7, 254, - 88, 29, 7, 254, 87, 29, 7, 254, 86, 29, 7, 254, 85, 29, 7, 254, 84, 29, - 7, 254, 83, 29, 7, 254, 82, 29, 7, 254, 81, 29, 7, 254, 80, 29, 7, 254, - 79, 29, 7, 254, 78, 29, 7, 254, 77, 29, 7, 254, 76, 29, 7, 254, 75, 29, - 7, 254, 74, 29, 7, 254, 73, 29, 7, 254, 72, 29, 7, 254, 71, 29, 7, 254, - 70, 29, 7, 254, 69, 29, 7, 254, 68, 29, 7, 254, 67, 29, 7, 254, 66, 29, - 7, 254, 65, 29, 7, 254, 64, 29, 7, 254, 63, 29, 7, 254, 62, 29, 7, 254, - 61, 29, 7, 254, 60, 29, 7, 254, 59, 29, 7, 254, 58, 29, 7, 254, 57, 29, - 7, 254, 56, 29, 7, 254, 55, 29, 7, 254, 54, 29, 7, 254, 53, 29, 7, 254, - 52, 29, 7, 254, 50, 29, 7, 254, 49, 29, 7, 254, 48, 29, 7, 254, 47, 29, - 7, 254, 46, 29, 7, 254, 45, 29, 7, 254, 44, 29, 7, 254, 43, 29, 7, 254, - 42, 29, 7, 254, 41, 29, 7, 254, 40, 29, 7, 254, 37, 29, 7, 254, 36, 29, - 7, 254, 35, 29, 7, 254, 34, 29, 7, 254, 30, 29, 7, 254, 29, 29, 7, 254, + 7, 254, 92, 29, 7, 254, 89, 29, 7, 254, 88, 29, 7, 254, 87, 29, 7, 254, + 86, 29, 7, 254, 82, 29, 7, 254, 81, 29, 7, 254, 80, 29, 7, 254, 79, 29, + 7, 254, 78, 29, 7, 254, 77, 29, 7, 254, 76, 29, 7, 254, 75, 29, 7, 254, + 74, 29, 7, 254, 73, 29, 7, 254, 72, 29, 7, 254, 71, 29, 7, 254, 70, 29, + 7, 254, 69, 29, 7, 254, 68, 29, 7, 254, 67, 29, 7, 254, 66, 29, 7, 254, + 65, 29, 7, 254, 64, 29, 7, 254, 62, 29, 7, 254, 61, 29, 7, 254, 60, 29, + 7, 254, 59, 29, 7, 254, 58, 29, 7, 254, 57, 29, 7, 254, 56, 29, 7, 254, + 55, 29, 7, 254, 54, 29, 7, 254, 53, 29, 7, 254, 52, 29, 7, 254, 51, 29, + 7, 254, 50, 29, 7, 254, 49, 29, 7, 254, 48, 29, 7, 254, 47, 29, 7, 254, + 46, 29, 7, 254, 45, 29, 7, 254, 44, 29, 7, 254, 43, 29, 7, 254, 42, 29, + 7, 254, 41, 29, 7, 254, 40, 29, 7, 254, 39, 29, 7, 254, 38, 29, 7, 254, + 37, 29, 7, 254, 36, 29, 7, 254, 35, 29, 7, 254, 34, 29, 7, 254, 33, 29, + 7, 254, 32, 29, 7, 254, 31, 29, 7, 254, 30, 29, 7, 254, 29, 29, 7, 254, 28, 29, 7, 254, 27, 29, 7, 254, 26, 29, 7, 254, 25, 29, 7, 254, 24, 29, 7, 254, 23, 29, 7, 254, 22, 29, 7, 254, 21, 29, 7, 254, 20, 29, 7, 254, 19, 29, 7, 254, 18, 29, 7, 254, 17, 29, 7, 254, 16, 29, 7, 254, 15, 29, - 7, 254, 14, 29, 7, 254, 13, 29, 7, 254, 12, 29, 7, 254, 10, 29, 7, 254, - 9, 29, 7, 254, 8, 29, 7, 254, 7, 29, 7, 254, 6, 29, 7, 254, 5, 29, 7, - 254, 4, 29, 7, 254, 3, 29, 7, 254, 2, 29, 7, 254, 1, 29, 7, 254, 0, 29, - 7, 253, 255, 29, 7, 253, 254, 29, 7, 253, 253, 29, 7, 253, 252, 29, 7, - 253, 251, 29, 7, 253, 250, 29, 7, 253, 249, 29, 7, 253, 248, 29, 7, 253, - 247, 29, 7, 253, 246, 29, 7, 253, 245, 29, 7, 253, 244, 29, 7, 253, 243, - 29, 7, 253, 242, 29, 7, 253, 241, 29, 7, 253, 240, 29, 7, 253, 239, 29, - 7, 253, 238, 29, 7, 253, 237, 29, 7, 253, 236, 29, 7, 253, 235, 29, 7, - 253, 234, 29, 7, 253, 233, 29, 7, 253, 232, 29, 7, 253, 231, 29, 7, 253, - 230, 29, 7, 253, 229, 29, 7, 253, 228, 29, 7, 253, 227, 29, 7, 253, 226, - 29, 7, 253, 225, 29, 7, 253, 224, 29, 7, 253, 223, 29, 7, 253, 222, 29, - 7, 253, 221, 29, 7, 253, 220, 29, 7, 253, 219, 29, 7, 253, 218, 29, 7, - 253, 217, 29, 7, 253, 216, 29, 7, 253, 215, 29, 7, 253, 214, 29, 7, 253, - 213, 29, 7, 253, 212, 29, 7, 253, 211, 29, 7, 253, 210, 29, 7, 253, 209, - 29, 7, 253, 208, 29, 7, 253, 207, 29, 7, 253, 206, 29, 7, 253, 205, 207, - 181, 211, 46, 206, 252, 29, 7, 253, 204, 29, 7, 253, 203, 29, 7, 253, - 202, 29, 7, 253, 201, 29, 7, 253, 200, 29, 7, 253, 199, 29, 7, 253, 198, - 29, 7, 253, 197, 29, 7, 253, 196, 29, 7, 253, 195, 29, 7, 253, 194, 29, - 7, 253, 193, 176, 29, 7, 253, 192, 29, 7, 253, 191, 29, 7, 253, 190, 29, - 7, 253, 189, 29, 7, 253, 188, 29, 7, 253, 187, 29, 7, 253, 186, 29, 7, - 253, 184, 29, 7, 253, 182, 29, 7, 253, 180, 29, 7, 253, 178, 29, 7, 253, - 176, 29, 7, 253, 174, 29, 7, 253, 172, 29, 7, 253, 170, 29, 7, 253, 168, - 29, 7, 253, 166, 248, 199, 219, 4, 77, 29, 7, 253, 164, 234, 53, 219, 4, - 77, 29, 7, 253, 163, 29, 7, 253, 161, 29, 7, 253, 159, 29, 7, 253, 157, - 29, 7, 253, 155, 29, 7, 253, 153, 29, 7, 253, 151, 29, 7, 253, 149, 29, - 7, 253, 147, 29, 7, 253, 146, 29, 7, 253, 145, 29, 7, 253, 144, 29, 7, - 253, 143, 29, 7, 253, 142, 29, 7, 253, 141, 29, 7, 253, 140, 29, 7, 253, - 139, 29, 7, 253, 138, 29, 7, 253, 137, 29, 7, 253, 136, 29, 7, 253, 135, - 29, 7, 253, 134, 29, 7, 253, 133, 29, 7, 253, 132, 29, 7, 253, 131, 29, - 7, 253, 130, 29, 7, 253, 129, 29, 7, 253, 128, 29, 7, 253, 127, 29, 7, - 253, 126, 29, 7, 253, 125, 29, 7, 253, 124, 29, 7, 253, 123, 29, 7, 253, - 122, 29, 7, 253, 121, 29, 7, 253, 120, 29, 7, 253, 119, 29, 7, 253, 118, - 29, 7, 253, 117, 29, 7, 253, 116, 29, 7, 253, 115, 29, 7, 253, 114, 29, - 7, 253, 113, 29, 7, 253, 112, 29, 7, 253, 111, 29, 7, 253, 110, 29, 7, - 253, 109, 29, 7, 253, 108, 29, 7, 253, 107, 29, 7, 253, 106, 29, 7, 253, - 105, 29, 7, 253, 104, 29, 7, 253, 103, 29, 7, 253, 102, 29, 7, 253, 101, - 29, 7, 253, 100, 29, 7, 253, 99, 29, 7, 253, 98, 29, 7, 253, 97, 29, 7, - 253, 96, 29, 7, 253, 95, 29, 7, 253, 94, 29, 7, 253, 93, 29, 7, 253, 92, - 29, 7, 253, 91, 29, 7, 253, 90, 29, 7, 253, 89, 29, 7, 253, 88, 29, 7, - 253, 87, 29, 7, 253, 86, 29, 7, 253, 85, 29, 7, 253, 84, 29, 7, 253, 83, - 29, 7, 253, 82, 29, 7, 253, 81, 29, 7, 253, 80, 29, 7, 253, 79, 29, 7, - 253, 78, 29, 7, 253, 77, 29, 7, 253, 76, 29, 7, 253, 75, 29, 7, 253, 74, - 29, 7, 253, 73, 29, 7, 253, 72, 29, 7, 253, 71, 29, 7, 253, 70, 29, 7, - 253, 69, 29, 7, 253, 68, 29, 7, 253, 67, 29, 7, 253, 66, 29, 7, 253, 65, - 29, 7, 253, 64, 29, 7, 253, 63, 29, 7, 253, 62, 29, 7, 253, 61, 29, 7, - 253, 60, 29, 7, 253, 59, 29, 7, 253, 58, 29, 7, 253, 57, 29, 7, 253, 56, - 29, 7, 253, 55, 29, 7, 253, 54, 29, 7, 253, 53, 29, 7, 253, 52, 29, 7, - 253, 51, 29, 7, 253, 50, 29, 7, 253, 49, 29, 7, 253, 48, 29, 7, 253, 47, - 29, 7, 253, 46, 29, 7, 253, 45, 29, 7, 253, 44, 29, 7, 253, 43, 29, 7, - 253, 42, 29, 7, 253, 41, 29, 7, 253, 40, 29, 7, 253, 39, 29, 7, 253, 38, - 29, 7, 253, 37, 26, 1, 209, 209, 213, 243, 216, 123, 26, 1, 209, 209, - 231, 136, 232, 127, 26, 1, 209, 209, 209, 33, 216, 124, 209, 119, 26, 1, - 209, 209, 209, 33, 216, 124, 209, 120, 26, 1, 209, 209, 214, 237, 216, - 123, 26, 1, 209, 209, 202, 251, 26, 1, 209, 209, 198, 119, 216, 123, 26, - 1, 209, 209, 212, 34, 216, 123, 26, 1, 209, 209, 203, 63, 210, 211, 213, - 128, 26, 1, 209, 209, 209, 33, 210, 211, 213, 129, 209, 119, 26, 1, 209, - 209, 209, 33, 210, 211, 213, 129, 209, 120, 26, 1, 209, 209, 217, 110, - 26, 1, 209, 209, 197, 91, 217, 111, 26, 1, 209, 209, 214, 48, 26, 1, 209, - 209, 217, 107, 26, 1, 209, 209, 217, 57, 26, 1, 209, 209, 215, 72, 26, 1, - 209, 209, 203, 244, 26, 1, 209, 209, 212, 174, 26, 1, 209, 209, 221, 209, - 26, 1, 209, 209, 213, 95, 26, 1, 209, 209, 200, 156, 26, 1, 209, 209, - 213, 242, 26, 1, 209, 209, 219, 247, 26, 1, 209, 209, 219, 153, 220, 164, - 26, 1, 209, 209, 212, 184, 216, 131, 26, 1, 209, 209, 217, 114, 26, 1, - 209, 209, 210, 88, 26, 1, 209, 209, 231, 35, 26, 1, 209, 209, 210, 160, - 26, 1, 209, 209, 215, 215, 214, 21, 26, 1, 209, 209, 212, 15, 216, 134, - 26, 1, 209, 209, 126, 191, 195, 214, 230, 26, 1, 209, 209, 231, 36, 26, - 1, 209, 209, 212, 184, 212, 185, 26, 1, 209, 209, 202, 134, 26, 1, 209, - 209, 216, 116, 26, 1, 209, 209, 216, 137, 26, 1, 209, 209, 215, 190, 26, - 1, 209, 209, 222, 78, 26, 1, 209, 209, 210, 211, 219, 201, 26, 1, 209, - 209, 214, 149, 219, 201, 26, 1, 209, 209, 209, 231, 26, 1, 209, 209, 217, - 108, 26, 1, 209, 209, 213, 171, 26, 1, 209, 209, 208, 137, 26, 1, 209, - 209, 197, 83, 26, 1, 209, 209, 218, 199, 26, 1, 209, 209, 202, 12, 26, 1, - 209, 209, 199, 53, 26, 1, 209, 209, 217, 105, 26, 1, 209, 209, 221, 216, - 26, 1, 209, 209, 214, 145, 26, 1, 209, 209, 220, 179, 26, 1, 209, 209, - 215, 191, 26, 1, 209, 209, 202, 247, 26, 1, 209, 209, 218, 252, 26, 1, - 209, 209, 232, 198, 26, 1, 209, 209, 206, 132, 26, 1, 209, 209, 220, 242, - 26, 1, 209, 209, 202, 8, 26, 1, 209, 209, 217, 52, 209, 164, 26, 1, 209, - 209, 203, 56, 26, 1, 209, 209, 212, 183, 26, 1, 209, 209, 203, 37, 212, - 195, 191, 203, 26, 1, 209, 209, 212, 56, 215, 211, 26, 1, 209, 209, 210, - 206, 26, 1, 209, 209, 213, 97, 26, 1, 209, 209, 196, 81, 26, 1, 209, 209, - 214, 24, 26, 1, 209, 209, 217, 104, 26, 1, 209, 209, 213, 140, 26, 1, - 209, 209, 216, 243, 26, 1, 209, 209, 212, 71, 26, 1, 209, 209, 199, 57, - 26, 1, 209, 209, 202, 3, 26, 1, 209, 209, 210, 207, 26, 1, 209, 209, 212, - 199, 26, 1, 209, 209, 217, 112, 26, 1, 209, 209, 212, 68, 26, 1, 209, - 209, 222, 40, 26, 1, 209, 209, 212, 202, 26, 1, 209, 209, 195, 145, 26, - 1, 209, 209, 218, 203, 26, 1, 209, 209, 214, 88, 26, 1, 209, 209, 214, - 203, 26, 1, 209, 209, 216, 242, 26, 1, 209, 208, 212, 197, 26, 1, 209, - 208, 197, 91, 217, 109, 26, 1, 209, 208, 202, 199, 26, 1, 209, 208, 203, - 248, 197, 90, 26, 1, 209, 208, 218, 255, 212, 180, 26, 1, 209, 208, 216, - 249, 217, 113, 26, 1, 209, 208, 221, 126, 26, 1, 209, 208, 192, 43, 26, - 1, 209, 208, 216, 244, 26, 1, 209, 208, 222, 64, 26, 1, 209, 208, 210, - 35, 26, 1, 209, 208, 192, 126, 219, 201, 26, 1, 209, 208, 220, 12, 212, - 195, 212, 82, 26, 1, 209, 208, 212, 177, 203, 82, 26, 1, 209, 208, 214, - 116, 213, 143, 26, 1, 209, 208, 231, 33, 26, 1, 209, 208, 209, 109, 26, - 1, 209, 208, 197, 91, 212, 193, 26, 1, 209, 208, 203, 87, 213, 138, 26, - 1, 209, 208, 203, 83, 26, 1, 209, 208, 216, 124, 199, 56, 26, 1, 209, - 208, 216, 231, 216, 245, 26, 1, 209, 208, 212, 69, 212, 180, 26, 1, 209, - 208, 221, 205, 26, 1, 209, 208, 231, 34, 26, 1, 209, 208, 221, 201, 26, - 1, 209, 208, 220, 96, 26, 1, 209, 208, 210, 91, 26, 1, 209, 208, 195, 74, - 26, 1, 209, 208, 213, 244, 215, 70, 26, 1, 209, 208, 214, 23, 216, 227, - 26, 1, 209, 208, 192, 254, 26, 1, 209, 208, 205, 170, 26, 1, 209, 208, - 199, 235, 26, 1, 209, 208, 216, 136, 26, 1, 209, 208, 214, 7, 26, 1, 209, - 208, 214, 8, 219, 244, 26, 1, 209, 208, 216, 126, 26, 1, 209, 208, 200, - 209, 26, 1, 209, 208, 216, 235, 26, 1, 209, 208, 215, 195, 26, 1, 209, - 208, 212, 86, 26, 1, 209, 208, 208, 141, 26, 1, 209, 208, 216, 135, 214, - 25, 26, 1, 209, 208, 232, 243, 26, 1, 209, 208, 216, 222, 26, 1, 209, - 208, 233, 11, 26, 1, 209, 208, 221, 213, 26, 1, 209, 208, 217, 139, 213, - 132, 26, 1, 209, 208, 217, 139, 213, 108, 26, 1, 209, 208, 219, 152, 26, - 1, 209, 208, 214, 31, 26, 1, 209, 208, 212, 204, 26, 1, 209, 208, 172, - 26, 1, 209, 208, 221, 109, 26, 1, 209, 208, 213, 232, 26, 1, 209, 207, - 213, 243, 217, 111, 26, 1, 209, 207, 212, 33, 26, 1, 209, 207, 191, 203, - 26, 1, 209, 207, 193, 158, 26, 1, 209, 207, 214, 24, 26, 1, 209, 207, - 214, 137, 26, 1, 209, 207, 213, 250, 26, 1, 209, 207, 231, 43, 26, 1, - 209, 207, 216, 239, 26, 1, 209, 207, 231, 143, 26, 1, 209, 207, 212, 58, - 216, 4, 216, 138, 26, 1, 209, 207, 212, 171, 216, 230, 26, 1, 209, 207, - 216, 236, 26, 1, 209, 207, 209, 115, 26, 1, 209, 207, 214, 122, 26, 1, - 209, 207, 216, 247, 247, 108, 26, 1, 209, 207, 221, 203, 26, 1, 209, 207, - 231, 44, 26, 1, 209, 207, 221, 210, 26, 1, 209, 207, 191, 226, 215, 103, - 26, 1, 209, 207, 212, 27, 26, 1, 209, 207, 216, 224, 26, 1, 209, 207, - 212, 203, 26, 1, 209, 207, 216, 230, 26, 1, 209, 207, 192, 44, 26, 1, - 209, 207, 220, 250, 26, 1, 209, 207, 222, 100, 26, 1, 209, 207, 203, 243, - 26, 1, 209, 207, 214, 131, 26, 1, 209, 207, 199, 233, 26, 1, 209, 207, - 213, 112, 26, 1, 209, 207, 198, 119, 191, 207, 26, 1, 209, 207, 200, 242, - 26, 1, 209, 207, 214, 14, 212, 82, 26, 1, 209, 207, 195, 73, 26, 1, 209, - 207, 214, 206, 26, 1, 209, 207, 217, 139, 221, 212, 26, 1, 209, 207, 212, - 185, 26, 1, 209, 207, 214, 9, 26, 1, 209, 207, 219, 248, 26, 1, 209, 207, - 216, 232, 26, 1, 209, 207, 216, 115, 26, 1, 209, 207, 212, 179, 26, 1, - 209, 207, 199, 52, 26, 1, 209, 207, 214, 11, 26, 1, 209, 207, 232, 46, - 26, 1, 209, 207, 214, 136, 26, 1, 209, 207, 212, 205, 26, 1, 209, 207, - 212, 201, 26, 1, 209, 207, 247, 192, 26, 1, 209, 207, 195, 75, 26, 1, - 209, 207, 216, 237, 26, 1, 209, 207, 206, 63, 26, 1, 209, 207, 213, 142, - 26, 1, 209, 207, 220, 11, 26, 1, 209, 207, 198, 116, 26, 1, 209, 207, - 212, 187, 213, 232, 26, 1, 209, 207, 213, 134, 26, 1, 209, 207, 221, 216, - 26, 1, 209, 207, 214, 16, 26, 1, 209, 207, 217, 104, 26, 1, 209, 207, - 216, 225, 26, 1, 209, 207, 218, 203, 26, 1, 209, 207, 220, 164, 26, 1, - 209, 207, 213, 140, 26, 1, 209, 207, 213, 232, 26, 1, 209, 207, 192, 244, - 26, 1, 209, 207, 214, 12, 26, 1, 209, 207, 212, 190, 26, 1, 209, 207, - 212, 181, 26, 1, 209, 207, 220, 181, 213, 97, 26, 1, 209, 207, 212, 188, - 26, 1, 209, 207, 214, 144, 26, 1, 209, 207, 217, 139, 212, 193, 26, 1, - 209, 207, 192, 140, 26, 1, 209, 207, 214, 143, 26, 1, 209, 207, 202, 250, - 26, 1, 209, 207, 203, 246, 26, 1, 209, 207, 216, 233, 26, 1, 209, 207, - 217, 111, 26, 1, 209, 207, 216, 243, 26, 1, 209, 207, 221, 204, 26, 1, - 209, 207, 216, 234, 26, 1, 209, 207, 221, 208, 26, 1, 209, 207, 216, 247, - 209, 170, 26, 1, 209, 207, 191, 186, 26, 1, 209, 207, 213, 130, 26, 1, - 209, 207, 216, 62, 26, 1, 209, 207, 215, 133, 26, 1, 209, 207, 203, 59, - 26, 1, 209, 207, 221, 227, 219, 226, 26, 1, 209, 207, 221, 227, 233, 24, - 26, 1, 209, 207, 214, 46, 26, 1, 209, 207, 214, 203, 26, 1, 209, 207, - 219, 70, 26, 1, 209, 207, 209, 130, 26, 1, 209, 207, 210, 25, 26, 1, 209, - 207, 199, 68, 26, 1, 158, 216, 223, 26, 1, 158, 193, 156, 26, 1, 158, - 213, 128, 26, 1, 158, 216, 123, 26, 1, 158, 213, 126, 26, 1, 158, 219, - 115, 26, 1, 158, 213, 131, 26, 1, 158, 212, 200, 26, 1, 158, 214, 30, 26, - 1, 158, 212, 82, 26, 1, 158, 192, 255, 26, 1, 158, 213, 240, 26, 1, 158, - 203, 106, 26, 1, 158, 213, 251, 26, 1, 158, 221, 211, 26, 1, 158, 199, - 54, 26, 1, 158, 203, 85, 26, 1, 158, 213, 139, 26, 1, 158, 200, 209, 26, - 1, 158, 221, 216, 26, 1, 158, 192, 128, 26, 1, 158, 220, 182, 26, 1, 158, - 205, 125, 26, 1, 158, 216, 128, 26, 1, 158, 214, 135, 26, 1, 158, 217, - 75, 26, 1, 158, 216, 134, 26, 1, 158, 203, 245, 26, 1, 158, 192, 70, 26, - 1, 158, 213, 133, 26, 1, 158, 221, 207, 216, 226, 26, 1, 158, 213, 247, - 26, 1, 158, 197, 90, 26, 1, 158, 231, 53, 26, 1, 158, 213, 237, 26, 1, - 158, 232, 244, 26, 1, 158, 214, 139, 26, 1, 158, 216, 107, 26, 1, 158, - 219, 146, 26, 1, 158, 214, 121, 26, 1, 158, 215, 210, 26, 1, 158, 216, - 111, 26, 1, 158, 208, 120, 26, 1, 158, 216, 109, 26, 1, 158, 216, 125, - 26, 1, 158, 218, 186, 26, 1, 158, 212, 192, 26, 1, 158, 216, 246, 26, 1, - 158, 220, 153, 26, 1, 158, 212, 71, 26, 1, 158, 199, 57, 26, 1, 158, 202, - 3, 26, 1, 158, 191, 186, 26, 1, 158, 221, 208, 26, 1, 158, 207, 157, 26, - 1, 158, 199, 115, 26, 1, 158, 213, 248, 26, 1, 158, 216, 130, 26, 1, 158, - 212, 191, 26, 1, 158, 221, 206, 26, 1, 158, 209, 121, 26, 1, 158, 209, - 224, 26, 1, 158, 212, 44, 26, 1, 158, 219, 152, 26, 1, 158, 214, 31, 26, - 1, 158, 216, 127, 26, 1, 158, 214, 4, 26, 1, 158, 191, 200, 26, 1, 158, - 210, 127, 26, 1, 158, 191, 199, 26, 1, 158, 214, 144, 26, 1, 158, 212, - 180, 26, 1, 158, 200, 244, 26, 1, 158, 220, 186, 26, 1, 158, 214, 20, 26, - 1, 158, 213, 245, 26, 1, 158, 197, 65, 26, 1, 158, 216, 138, 26, 1, 158, - 220, 175, 26, 1, 158, 212, 189, 26, 1, 158, 199, 55, 26, 1, 158, 217, - 106, 26, 1, 158, 214, 29, 26, 1, 158, 219, 145, 26, 1, 158, 214, 10, 26, - 1, 158, 212, 194, 26, 1, 158, 213, 112, 26, 1, 158, 231, 37, 26, 1, 158, - 220, 208, 26, 1, 158, 207, 51, 211, 108, 26, 1, 158, 199, 221, 26, 1, - 158, 198, 45, 26, 1, 158, 212, 68, 26, 1, 158, 206, 190, 26, 1, 158, 219, - 203, 26, 1, 158, 216, 191, 26, 1, 158, 218, 147, 26, 1, 158, 200, 156, - 26, 1, 158, 215, 139, 26, 1, 158, 203, 71, 26, 1, 158, 203, 81, 26, 1, - 158, 220, 125, 26, 1, 158, 212, 165, 26, 1, 158, 203, 0, 26, 1, 158, 212, - 182, 26, 1, 158, 210, 40, 26, 1, 158, 213, 205, 26, 1, 158, 203, 36, 26, - 1, 158, 208, 136, 26, 1, 158, 215, 70, 26, 1, 158, 218, 232, 26, 1, 158, - 207, 51, 215, 128, 26, 1, 158, 198, 188, 26, 1, 158, 212, 168, 26, 1, - 158, 216, 247, 181, 26, 1, 158, 205, 123, 26, 1, 158, 233, 67, 26, 1, - 114, 214, 143, 26, 1, 114, 198, 52, 26, 1, 114, 216, 236, 26, 1, 114, - 219, 248, 26, 1, 114, 195, 7, 26, 1, 114, 218, 238, 26, 1, 114, 210, 210, - 26, 1, 114, 202, 16, 26, 1, 114, 207, 129, 26, 1, 114, 212, 196, 26, 1, - 114, 214, 114, 26, 1, 114, 208, 154, 26, 1, 114, 199, 192, 26, 1, 114, - 213, 253, 26, 1, 114, 220, 246, 26, 1, 114, 192, 247, 26, 1, 114, 205, - 45, 26, 1, 114, 214, 21, 26, 1, 114, 210, 207, 26, 1, 114, 198, 54, 26, - 1, 114, 220, 180, 26, 1, 114, 218, 254, 26, 1, 114, 212, 199, 26, 1, 114, - 213, 229, 26, 1, 114, 217, 112, 26, 1, 114, 213, 246, 26, 1, 114, 213, - 228, 26, 1, 114, 212, 198, 26, 1, 114, 206, 187, 26, 1, 114, 213, 130, - 26, 1, 114, 210, 37, 26, 1, 114, 205, 192, 26, 1, 114, 214, 5, 26, 1, - 114, 216, 117, 26, 1, 114, 231, 31, 26, 1, 114, 213, 249, 26, 1, 114, - 213, 141, 26, 1, 114, 217, 51, 26, 1, 114, 218, 234, 26, 1, 114, 214, 26, - 26, 1, 114, 214, 127, 26, 1, 114, 199, 220, 212, 180, 26, 1, 114, 203, - 247, 26, 1, 114, 208, 147, 26, 1, 114, 214, 147, 202, 25, 26, 1, 114, - 214, 13, 212, 82, 26, 1, 114, 192, 29, 26, 1, 114, 231, 32, 26, 1, 114, - 197, 84, 26, 1, 114, 192, 47, 26, 1, 114, 209, 65, 26, 1, 114, 197, 71, - 26, 1, 114, 221, 214, 26, 1, 114, 200, 243, 26, 1, 114, 199, 56, 26, 1, - 114, 195, 76, 26, 1, 114, 193, 98, 26, 1, 114, 220, 99, 26, 1, 114, 208, - 158, 26, 1, 114, 199, 234, 26, 1, 114, 231, 52, 26, 1, 114, 214, 36, 26, - 1, 114, 203, 84, 26, 1, 114, 216, 112, 26, 1, 114, 216, 240, 26, 1, 114, - 212, 31, 26, 1, 114, 213, 93, 26, 1, 114, 231, 139, 26, 1, 114, 197, 72, - 26, 1, 114, 220, 191, 26, 1, 114, 192, 104, 26, 1, 114, 212, 69, 242, - 189, 26, 1, 114, 192, 18, 26, 1, 114, 216, 129, 26, 1, 114, 214, 132, 26, - 1, 114, 209, 165, 26, 1, 114, 191, 206, 26, 1, 114, 219, 147, 26, 1, 114, - 232, 46, 26, 1, 114, 231, 138, 26, 1, 114, 213, 239, 26, 1, 114, 221, - 216, 26, 1, 114, 217, 115, 26, 1, 114, 213, 252, 26, 1, 114, 231, 38, 26, - 1, 114, 233, 68, 26, 1, 114, 212, 169, 26, 1, 114, 209, 225, 26, 1, 114, - 192, 45, 26, 1, 114, 214, 22, 26, 1, 114, 212, 69, 248, 159, 26, 1, 114, - 212, 11, 26, 1, 114, 209, 28, 26, 1, 114, 216, 62, 26, 1, 114, 232, 44, - 26, 1, 114, 214, 230, 26, 1, 114, 215, 133, 26, 1, 114, 231, 37, 26, 1, - 114, 232, 49, 70, 26, 1, 114, 215, 71, 26, 1, 114, 208, 153, 26, 1, 114, - 213, 241, 26, 1, 114, 220, 164, 26, 1, 114, 209, 162, 26, 1, 114, 212, - 183, 26, 1, 114, 192, 46, 26, 1, 114, 214, 6, 26, 1, 114, 210, 211, 210, - 10, 26, 1, 114, 232, 49, 247, 90, 26, 1, 114, 232, 128, 26, 1, 114, 213, - 135, 26, 1, 114, 65, 26, 1, 114, 198, 45, 26, 1, 114, 74, 26, 1, 114, 70, - 26, 1, 114, 219, 246, 26, 1, 114, 210, 211, 209, 74, 26, 1, 114, 199, - 240, 26, 1, 114, 199, 175, 26, 1, 114, 214, 147, 215, 57, 228, 141, 26, - 1, 114, 203, 59, 26, 1, 114, 192, 42, 26, 1, 114, 213, 222, 26, 1, 114, - 191, 211, 26, 1, 114, 191, 244, 200, 132, 26, 1, 114, 191, 244, 238, 195, - 26, 1, 114, 191, 194, 26, 1, 114, 191, 202, 26, 1, 114, 221, 202, 26, 1, - 114, 209, 223, 26, 1, 114, 213, 136, 234, 7, 26, 1, 114, 208, 149, 26, 1, - 114, 192, 253, 26, 1, 114, 233, 11, 26, 1, 114, 195, 145, 26, 1, 114, - 218, 203, 26, 1, 114, 216, 81, 26, 1, 114, 207, 15, 26, 1, 114, 207, 158, - 26, 1, 114, 213, 221, 26, 1, 114, 214, 54, 26, 1, 114, 203, 51, 26, 1, - 114, 203, 36, 26, 1, 114, 232, 49, 207, 54, 26, 1, 114, 180, 26, 1, 114, - 209, 176, 26, 1, 114, 218, 232, 26, 1, 114, 221, 43, 26, 1, 114, 216, - 167, 26, 1, 114, 172, 26, 1, 114, 217, 48, 26, 1, 114, 199, 58, 26, 1, - 114, 221, 142, 26, 1, 114, 215, 214, 26, 1, 114, 199, 90, 26, 1, 114, - 233, 35, 26, 1, 114, 231, 25, 26, 1, 209, 206, 157, 26, 1, 209, 206, 69, - 26, 1, 209, 206, 220, 208, 26, 1, 209, 206, 234, 145, 26, 1, 209, 206, - 207, 79, 26, 1, 209, 206, 199, 221, 26, 1, 209, 206, 212, 68, 26, 1, 209, - 206, 171, 26, 1, 209, 206, 206, 190, 26, 1, 209, 206, 206, 237, 26, 1, - 209, 206, 216, 191, 26, 1, 209, 206, 199, 240, 26, 1, 209, 206, 214, 146, - 26, 1, 209, 206, 213, 142, 26, 1, 209, 206, 218, 147, 26, 1, 209, 206, - 200, 156, 26, 1, 209, 206, 203, 71, 26, 1, 209, 206, 202, 217, 26, 1, - 209, 206, 203, 243, 26, 1, 209, 206, 220, 125, 26, 1, 209, 206, 221, 216, - 26, 1, 209, 206, 212, 133, 26, 1, 209, 206, 212, 165, 26, 1, 209, 206, - 213, 113, 26, 1, 209, 206, 191, 243, 26, 1, 209, 206, 203, 0, 26, 1, 209, - 206, 169, 26, 1, 209, 206, 212, 202, 26, 1, 209, 206, 209, 223, 26, 1, - 209, 206, 212, 182, 26, 1, 209, 206, 192, 253, 26, 1, 209, 206, 210, 40, - 26, 1, 209, 206, 206, 63, 26, 1, 209, 206, 213, 205, 26, 1, 209, 206, - 207, 15, 26, 1, 209, 206, 221, 226, 26, 1, 209, 206, 213, 238, 26, 1, - 209, 206, 214, 33, 26, 1, 209, 206, 203, 51, 26, 1, 209, 206, 208, 154, - 26, 1, 209, 206, 232, 128, 26, 1, 209, 206, 193, 187, 26, 1, 209, 206, - 219, 122, 26, 1, 209, 206, 218, 232, 26, 1, 209, 206, 221, 43, 26, 1, - 209, 206, 216, 238, 26, 1, 209, 206, 207, 50, 26, 1, 209, 206, 172, 26, - 1, 209, 206, 215, 251, 26, 1, 209, 206, 216, 246, 26, 1, 209, 206, 199, - 68, 26, 1, 209, 206, 220, 253, 26, 1, 209, 206, 205, 145, 26, 1, 209, - 206, 193, 245, 215, 143, 1, 199, 247, 215, 143, 1, 214, 2, 215, 143, 1, - 192, 12, 215, 143, 1, 216, 28, 215, 143, 1, 249, 103, 215, 143, 1, 237, - 241, 215, 143, 1, 65, 215, 143, 1, 209, 202, 215, 143, 1, 221, 184, 215, - 143, 1, 229, 245, 215, 143, 1, 237, 216, 215, 143, 1, 243, 0, 215, 143, - 1, 221, 246, 215, 143, 1, 211, 109, 215, 143, 1, 217, 112, 215, 143, 1, - 213, 165, 215, 143, 1, 168, 215, 143, 1, 211, 76, 215, 143, 1, 74, 215, - 143, 1, 206, 157, 215, 143, 1, 203, 76, 215, 143, 1, 199, 27, 215, 143, - 1, 234, 173, 215, 143, 1, 193, 187, 215, 143, 1, 73, 215, 143, 1, 221, - 43, 215, 143, 1, 220, 0, 215, 143, 1, 171, 215, 143, 1, 230, 47, 215, - 143, 1, 206, 252, 215, 143, 1, 199, 105, 215, 143, 17, 191, 77, 215, 143, - 17, 108, 215, 143, 17, 109, 215, 143, 17, 139, 215, 143, 17, 137, 215, - 143, 17, 153, 215, 143, 17, 173, 215, 143, 17, 181, 215, 143, 17, 176, - 215, 143, 17, 184, 215, 143, 237, 193, 215, 143, 54, 237, 193, 199, 181, - 1, 210, 228, 199, 181, 1, 211, 153, 199, 181, 1, 211, 47, 199, 181, 1, - 210, 237, 199, 181, 1, 250, 73, 199, 181, 1, 252, 11, 199, 181, 1, 250, - 243, 199, 181, 1, 250, 83, 199, 181, 1, 193, 224, 199, 181, 1, 195, 152, - 199, 181, 1, 194, 252, 199, 181, 1, 193, 233, 199, 181, 1, 233, 141, 199, - 181, 1, 234, 153, 199, 181, 1, 234, 4, 199, 181, 1, 233, 180, 199, 181, - 1, 223, 13, 199, 181, 1, 227, 254, 199, 181, 1, 223, 51, 199, 181, 1, - 223, 17, 199, 181, 1, 196, 14, 199, 181, 1, 196, 156, 199, 181, 1, 196, - 60, 199, 181, 1, 196, 18, 199, 181, 1, 250, 84, 199, 181, 1, 250, 88, - 199, 181, 1, 250, 86, 199, 181, 1, 250, 85, 199, 181, 1, 196, 125, 199, - 181, 1, 196, 134, 199, 181, 1, 196, 131, 199, 181, 1, 196, 126, 199, 181, - 1, 52, 214, 56, 199, 181, 1, 177, 196, 141, 199, 181, 1, 203, 35, 196, - 139, 199, 181, 1, 203, 35, 250, 85, 199, 181, 1, 196, 146, 199, 181, 1, - 196, 139, 199, 181, 1, 196, 142, 199, 181, 1, 196, 141, 199, 181, 1, 196, - 127, 199, 181, 1, 196, 130, 199, 181, 1, 196, 129, 199, 181, 1, 196, 128, - 199, 181, 1, 215, 49, 199, 181, 1, 216, 219, 199, 181, 1, 215, 149, 199, - 181, 1, 215, 58, 199, 181, 1, 157, 199, 181, 1, 221, 190, 199, 181, 1, - 231, 203, 199, 181, 1, 214, 54, 199, 181, 1, 189, 199, 181, 1, 169, 199, - 181, 1, 193, 187, 199, 181, 1, 168, 199, 181, 1, 212, 88, 199, 181, 1, - 209, 219, 199, 181, 1, 249, 103, 199, 181, 1, 172, 199, 181, 1, 180, 199, - 181, 1, 144, 199, 181, 1, 171, 199, 181, 1, 228, 133, 199, 181, 1, 199, - 247, 199, 181, 1, 237, 241, 199, 181, 1, 166, 199, 181, 1, 213, 210, 199, - 181, 1, 203, 160, 199, 181, 1, 247, 112, 199, 181, 1, 197, 164, 199, 181, - 1, 231, 54, 199, 181, 1, 228, 130, 199, 181, 1, 199, 44, 199, 181, 1, - 192, 220, 199, 181, 1, 233, 68, 199, 181, 1, 237, 23, 199, 181, 1, 246, - 209, 199, 181, 1, 191, 123, 199, 181, 17, 191, 77, 199, 181, 17, 108, - 199, 181, 17, 109, 199, 181, 17, 139, 199, 181, 17, 137, 199, 181, 17, - 153, 199, 181, 17, 173, 199, 181, 17, 181, 199, 181, 17, 176, 199, 181, - 17, 184, 249, 17, 195, 182, 1, 234, 42, 249, 17, 195, 182, 1, 157, 249, - 17, 195, 182, 1, 205, 63, 249, 17, 195, 182, 1, 233, 68, 249, 17, 195, - 182, 1, 216, 241, 249, 17, 195, 182, 1, 192, 30, 249, 17, 195, 182, 1, - 231, 188, 249, 17, 195, 182, 1, 237, 4, 249, 17, 195, 182, 1, 220, 252, - 249, 17, 195, 182, 1, 222, 174, 249, 17, 195, 182, 1, 228, 93, 249, 17, - 195, 182, 1, 193, 187, 249, 17, 195, 182, 1, 191, 7, 249, 17, 195, 182, - 1, 231, 132, 249, 17, 195, 182, 1, 236, 129, 249, 17, 195, 182, 1, 246, - 250, 249, 17, 195, 182, 1, 196, 19, 249, 17, 195, 182, 1, 159, 249, 17, - 195, 182, 1, 249, 103, 249, 17, 195, 182, 1, 193, 246, 249, 17, 195, 182, - 1, 192, 74, 249, 17, 195, 182, 1, 168, 249, 17, 195, 182, 1, 193, 174, - 249, 17, 195, 182, 1, 65, 249, 17, 195, 182, 1, 74, 249, 17, 195, 182, 1, - 211, 76, 249, 17, 195, 182, 1, 69, 249, 17, 195, 182, 1, 234, 145, 249, - 17, 195, 182, 1, 73, 249, 17, 195, 182, 1, 70, 249, 17, 195, 182, 33, - 136, 198, 74, 249, 17, 195, 182, 33, 131, 198, 74, 249, 17, 195, 182, 33, - 216, 68, 198, 74, 249, 17, 195, 182, 33, 218, 216, 198, 74, 249, 17, 195, - 182, 33, 229, 101, 198, 74, 249, 17, 195, 182, 232, 42, 201, 58, 145, 90, - 18, 221, 243, 145, 90, 18, 221, 239, 145, 90, 18, 221, 131, 145, 90, 18, - 221, 94, 145, 90, 18, 222, 15, 145, 90, 18, 222, 12, 145, 90, 18, 220, - 192, 145, 90, 18, 220, 161, 145, 90, 18, 221, 245, 145, 90, 18, 221, 200, - 145, 90, 18, 222, 74, 145, 90, 18, 222, 71, 145, 90, 18, 221, 16, 145, - 90, 18, 221, 13, 145, 90, 18, 222, 8, 145, 90, 18, 222, 6, 145, 90, 18, - 220, 194, 145, 90, 18, 220, 193, 145, 90, 18, 221, 36, 145, 90, 18, 221, - 1, 145, 90, 18, 221, 133, 145, 90, 18, 221, 132, 145, 90, 18, 222, 90, - 145, 90, 18, 222, 11, 145, 90, 18, 220, 151, 145, 90, 18, 220, 142, 145, - 90, 18, 222, 99, 145, 90, 18, 222, 91, 145, 90, 119, 195, 157, 145, 90, - 119, 212, 172, 145, 90, 119, 219, 232, 145, 90, 119, 229, 225, 145, 90, - 119, 213, 69, 145, 90, 119, 207, 120, 145, 90, 119, 213, 96, 145, 90, - 119, 208, 63, 145, 90, 119, 192, 91, 145, 90, 119, 229, 76, 145, 90, 119, - 217, 6, 145, 90, 119, 243, 83, 145, 90, 119, 214, 151, 145, 90, 119, 229, - 12, 145, 90, 119, 209, 83, 145, 90, 119, 212, 178, 145, 90, 119, 214, - 191, 145, 90, 119, 250, 113, 145, 90, 119, 192, 216, 145, 90, 119, 247, - 28, 145, 90, 87, 242, 225, 197, 81, 145, 90, 87, 242, 225, 202, 41, 145, - 90, 87, 242, 225, 221, 218, 145, 90, 87, 242, 225, 221, 174, 145, 90, 87, - 242, 225, 200, 241, 145, 90, 87, 242, 225, 228, 226, 145, 90, 87, 242, - 225, 199, 160, 145, 90, 3, 195, 2, 198, 233, 145, 90, 3, 195, 2, 197, - 152, 246, 241, 145, 90, 3, 242, 225, 243, 72, 145, 90, 3, 195, 2, 199, 5, - 145, 90, 3, 195, 2, 233, 8, 145, 90, 3, 192, 171, 212, 166, 145, 90, 3, - 192, 171, 206, 254, 145, 90, 3, 192, 171, 198, 27, 145, 90, 3, 192, 171, - 233, 49, 145, 90, 3, 195, 2, 205, 39, 145, 90, 3, 216, 190, 200, 245, - 145, 90, 3, 195, 2, 212, 218, 145, 90, 3, 228, 1, 192, 111, 145, 90, 3, - 192, 215, 145, 90, 3, 242, 225, 197, 139, 206, 139, 145, 90, 17, 191, 77, - 145, 90, 17, 108, 145, 90, 17, 109, 145, 90, 17, 139, 145, 90, 17, 137, - 145, 90, 17, 153, 145, 90, 17, 173, 145, 90, 17, 181, 145, 90, 17, 176, - 145, 90, 17, 184, 145, 90, 31, 199, 85, 145, 90, 31, 228, 107, 145, 90, - 31, 199, 91, 198, 223, 145, 90, 31, 216, 29, 145, 90, 31, 228, 110, 216, - 29, 145, 90, 31, 199, 91, 248, 121, 145, 90, 31, 197, 223, 145, 90, 3, - 195, 2, 218, 198, 145, 90, 3, 192, 168, 145, 90, 3, 229, 71, 145, 90, 3, - 198, 250, 229, 71, 145, 90, 3, 190, 236, 199, 38, 145, 90, 3, 228, 252, - 145, 90, 3, 212, 232, 145, 90, 3, 192, 206, 145, 90, 3, 212, 170, 145, - 90, 3, 250, 96, 145, 90, 3, 197, 3, 246, 240, 145, 90, 3, 216, 190, 197, - 155, 145, 90, 3, 199, 161, 145, 90, 3, 218, 229, 145, 90, 3, 215, 89, - 145, 90, 3, 242, 225, 230, 43, 218, 175, 212, 176, 212, 175, 145, 90, 3, - 242, 225, 238, 147, 197, 146, 145, 90, 3, 242, 225, 197, 1, 145, 90, 3, - 242, 225, 197, 2, 242, 244, 145, 90, 3, 242, 225, 208, 152, 237, 161, - 145, 90, 3, 242, 225, 212, 225, 198, 36, 145, 90, 242, 196, 3, 197, 150, - 145, 90, 242, 196, 3, 192, 76, 145, 90, 242, 196, 3, 219, 66, 145, 90, - 242, 196, 3, 219, 230, 145, 90, 242, 196, 3, 192, 167, 145, 90, 242, 196, - 3, 221, 17, 145, 90, 242, 196, 3, 229, 222, 145, 90, 242, 196, 3, 215, - 131, 145, 90, 242, 196, 3, 198, 234, 145, 90, 242, 196, 3, 197, 161, 145, - 90, 242, 196, 3, 209, 216, 145, 90, 242, 196, 3, 221, 188, 145, 90, 242, - 196, 3, 230, 31, 145, 90, 242, 196, 3, 195, 179, 145, 90, 242, 196, 3, - 233, 45, 145, 90, 242, 196, 3, 192, 118, 145, 90, 242, 196, 3, 197, 133, - 145, 90, 242, 196, 3, 220, 146, 145, 90, 242, 196, 3, 193, 234, 216, 199, - 6, 1, 218, 147, 216, 199, 6, 1, 206, 3, 216, 199, 6, 1, 196, 8, 216, 199, - 6, 1, 193, 221, 216, 199, 6, 1, 250, 126, 216, 199, 6, 1, 191, 166, 216, - 199, 6, 1, 220, 254, 216, 199, 6, 1, 210, 226, 216, 199, 6, 1, 200, 39, - 216, 199, 6, 1, 232, 14, 216, 199, 6, 1, 233, 134, 216, 199, 6, 1, 70, - 216, 199, 6, 1, 222, 125, 216, 199, 6, 1, 65, 216, 199, 6, 1, 223, 7, - 216, 199, 6, 1, 73, 216, 199, 6, 1, 250, 70, 216, 199, 6, 1, 247, 145, - 216, 199, 6, 1, 69, 216, 199, 6, 1, 191, 225, 216, 199, 6, 1, 170, 216, - 199, 6, 1, 208, 97, 216, 199, 6, 1, 228, 138, 216, 199, 6, 1, 212, 90, - 216, 199, 6, 1, 192, 235, 216, 199, 6, 1, 238, 80, 216, 199, 6, 1, 211, - 139, 216, 199, 6, 1, 215, 47, 216, 199, 6, 1, 148, 216, 199, 6, 1, 74, - 216, 199, 6, 1, 251, 184, 216, 199, 6, 1, 192, 159, 216, 199, 2, 1, 218, - 147, 216, 199, 2, 1, 206, 3, 216, 199, 2, 1, 196, 8, 216, 199, 2, 1, 193, - 221, 216, 199, 2, 1, 250, 126, 216, 199, 2, 1, 191, 166, 216, 199, 2, 1, - 220, 254, 216, 199, 2, 1, 210, 226, 216, 199, 2, 1, 200, 39, 216, 199, 2, - 1, 232, 14, 216, 199, 2, 1, 233, 134, 216, 199, 2, 1, 70, 216, 199, 2, 1, - 222, 125, 216, 199, 2, 1, 65, 216, 199, 2, 1, 223, 7, 216, 199, 2, 1, 73, - 216, 199, 2, 1, 250, 70, 216, 199, 2, 1, 247, 145, 216, 199, 2, 1, 69, - 216, 199, 2, 1, 191, 225, 216, 199, 2, 1, 170, 216, 199, 2, 1, 208, 97, - 216, 199, 2, 1, 228, 138, 216, 199, 2, 1, 212, 90, 216, 199, 2, 1, 192, - 235, 216, 199, 2, 1, 238, 80, 216, 199, 2, 1, 211, 139, 216, 199, 2, 1, - 215, 47, 216, 199, 2, 1, 148, 216, 199, 2, 1, 74, 216, 199, 2, 1, 251, - 184, 216, 199, 2, 1, 192, 159, 216, 199, 17, 191, 77, 216, 199, 17, 108, - 216, 199, 17, 109, 216, 199, 17, 139, 216, 199, 17, 137, 216, 199, 17, - 153, 216, 199, 17, 173, 216, 199, 17, 181, 216, 199, 17, 176, 216, 199, - 17, 184, 216, 199, 31, 199, 90, 216, 199, 31, 234, 84, 216, 199, 31, 197, - 33, 216, 199, 31, 198, 246, 216, 199, 31, 232, 84, 216, 199, 31, 232, - 234, 216, 199, 31, 202, 125, 216, 199, 31, 203, 239, 216, 199, 31, 234, - 118, 216, 199, 31, 213, 158, 216, 199, 17, 91, 251, 106, 20, 216, 199, - 17, 103, 251, 106, 20, 216, 199, 17, 115, 251, 106, 20, 216, 199, 242, - 26, 216, 199, 232, 42, 201, 58, 216, 199, 16, 251, 169, 216, 199, 233, - 175, 211, 124, 120, 1, 168, 120, 1, 249, 103, 120, 1, 11, 168, 120, 1, - 209, 102, 120, 1, 172, 120, 1, 216, 84, 120, 1, 250, 220, 172, 120, 1, - 233, 68, 120, 1, 195, 185, 120, 1, 195, 68, 120, 1, 199, 247, 120, 1, - 237, 241, 120, 1, 11, 197, 128, 120, 1, 11, 199, 247, 120, 1, 197, 128, - 120, 1, 237, 146, 120, 1, 180, 120, 1, 213, 210, 120, 1, 11, 213, 66, - 120, 1, 250, 220, 180, 120, 1, 213, 66, 120, 1, 213, 52, 120, 1, 171, - 120, 1, 218, 161, 120, 1, 219, 135, 120, 1, 219, 124, 120, 1, 198, 107, - 120, 1, 236, 138, 120, 1, 198, 99, 120, 1, 236, 137, 120, 1, 157, 120, 1, - 231, 203, 120, 1, 11, 157, 120, 1, 208, 89, 120, 1, 208, 66, 120, 1, 214, - 54, 120, 1, 214, 3, 120, 1, 250, 220, 214, 54, 120, 1, 144, 120, 1, 192, - 220, 120, 1, 231, 54, 120, 1, 231, 29, 120, 1, 197, 138, 120, 1, 234, - 230, 120, 1, 212, 88, 120, 1, 212, 70, 120, 1, 197, 153, 120, 1, 234, - 241, 120, 1, 11, 197, 153, 120, 1, 11, 234, 241, 120, 1, 207, 77, 197, - 153, 120, 1, 203, 160, 120, 1, 201, 170, 120, 1, 191, 71, 120, 1, 190, - 253, 120, 1, 197, 164, 120, 1, 234, 247, 120, 1, 11, 197, 164, 120, 1, - 189, 120, 1, 191, 123, 120, 1, 190, 254, 120, 1, 190, 224, 120, 1, 190, - 204, 120, 1, 250, 220, 190, 224, 120, 1, 190, 196, 120, 1, 190, 203, 120, - 1, 193, 187, 120, 1, 251, 193, 120, 1, 229, 145, 120, 1, 247, 240, 120, - 1, 200, 121, 120, 1, 234, 231, 120, 1, 199, 140, 120, 1, 197, 157, 120, - 1, 206, 66, 120, 3, 119, 59, 164, 120, 1, 214, 198, 120, 3, 250, 149, - 120, 3, 207, 77, 195, 15, 120, 3, 207, 77, 250, 149, 120, 18, 3, 65, 120, - 18, 3, 252, 154, 120, 18, 3, 251, 189, 120, 18, 3, 251, 81, 120, 18, 3, - 251, 71, 120, 18, 3, 74, 120, 18, 3, 211, 76, 120, 18, 3, 193, 48, 120, - 18, 3, 193, 221, 120, 18, 3, 73, 120, 18, 3, 234, 61, 120, 18, 3, 234, - 46, 120, 18, 3, 211, 135, 120, 18, 3, 70, 120, 18, 3, 228, 5, 120, 18, 3, - 228, 4, 120, 18, 3, 228, 3, 120, 18, 3, 223, 60, 120, 18, 3, 223, 197, - 120, 18, 3, 223, 170, 120, 18, 3, 223, 21, 120, 18, 3, 223, 108, 120, 18, - 3, 69, 120, 18, 3, 196, 164, 120, 18, 3, 196, 163, 120, 18, 3, 196, 162, - 120, 18, 3, 196, 26, 120, 18, 3, 196, 144, 120, 18, 3, 196, 93, 120, 18, - 3, 192, 159, 120, 18, 3, 192, 33, 120, 18, 3, 251, 229, 120, 18, 3, 251, - 225, 120, 18, 3, 233, 240, 120, 18, 3, 206, 108, 233, 240, 120, 18, 3, - 233, 248, 120, 18, 3, 206, 108, 233, 248, 120, 18, 3, 251, 184, 120, 18, - 3, 234, 123, 120, 18, 3, 250, 113, 120, 18, 3, 211, 9, 120, 18, 3, 215, - 47, 120, 18, 3, 214, 56, 120, 18, 3, 196, 77, 120, 18, 3, 191, 205, 120, - 18, 3, 211, 129, 120, 18, 3, 211, 136, 120, 18, 3, 193, 236, 120, 18, 3, - 223, 175, 120, 18, 3, 234, 173, 120, 18, 3, 223, 58, 120, 18, 3, 196, - 135, 120, 163, 187, 120, 163, 198, 49, 187, 120, 163, 56, 120, 163, 60, - 120, 1, 198, 72, 120, 1, 198, 71, 120, 1, 198, 70, 120, 1, 198, 69, 120, - 1, 198, 68, 120, 1, 198, 67, 120, 1, 198, 66, 120, 1, 207, 77, 198, 73, - 120, 1, 207, 77, 198, 72, 120, 1, 207, 77, 198, 70, 120, 1, 207, 77, 198, - 69, 120, 1, 207, 77, 198, 68, 120, 1, 207, 77, 198, 66, 19, 223, 23, 77, - 46, 223, 23, 77, 38, 243, 32, 228, 219, 77, 38, 243, 32, 223, 23, 77, 40, - 2, 27, 232, 218, 195, 54, 251, 106, 207, 102, 87, 247, 112, 195, 54, 251, - 106, 207, 102, 87, 213, 209, 19, 242, 15, 19, 242, 14, 19, 242, 13, 19, - 242, 12, 19, 242, 11, 19, 242, 10, 19, 242, 9, 19, 242, 8, 19, 242, 7, - 19, 242, 6, 19, 242, 5, 19, 242, 4, 19, 242, 3, 19, 242, 2, 19, 242, 1, - 19, 242, 0, 19, 241, 255, 19, 241, 254, 19, 241, 253, 19, 241, 252, 19, - 241, 251, 19, 241, 250, 19, 241, 249, 19, 241, 248, 19, 241, 247, 19, + 7, 254, 14, 29, 7, 254, 13, 29, 7, 254, 12, 29, 7, 254, 11, 29, 7, 254, + 10, 29, 7, 254, 9, 29, 7, 254, 8, 29, 7, 254, 7, 29, 7, 254, 6, 29, 7, + 254, 5, 29, 7, 254, 4, 29, 7, 254, 3, 29, 7, 254, 2, 29, 7, 254, 1, 207, + 186, 211, 57, 207, 1, 29, 7, 254, 0, 29, 7, 253, 255, 29, 7, 253, 254, + 29, 7, 253, 253, 29, 7, 253, 252, 29, 7, 253, 251, 29, 7, 253, 250, 29, + 7, 253, 249, 29, 7, 253, 248, 29, 7, 253, 247, 29, 7, 253, 246, 29, 7, + 253, 245, 171, 29, 7, 253, 244, 29, 7, 253, 243, 29, 7, 253, 242, 29, 7, + 253, 241, 29, 7, 253, 240, 29, 7, 253, 239, 29, 7, 253, 238, 29, 7, 253, + 236, 29, 7, 253, 234, 29, 7, 253, 232, 29, 7, 253, 230, 29, 7, 253, 228, + 29, 7, 253, 226, 29, 7, 253, 224, 29, 7, 253, 222, 29, 7, 253, 220, 29, + 7, 253, 218, 248, 249, 219, 28, 77, 29, 7, 253, 216, 234, 95, 219, 28, + 77, 29, 7, 253, 215, 29, 7, 253, 213, 29, 7, 253, 211, 29, 7, 253, 209, + 29, 7, 253, 207, 29, 7, 253, 205, 29, 7, 253, 203, 29, 7, 253, 201, 29, + 7, 253, 199, 29, 7, 253, 198, 29, 7, 253, 197, 29, 7, 253, 196, 29, 7, + 253, 195, 29, 7, 253, 194, 29, 7, 253, 193, 29, 7, 253, 192, 29, 7, 253, + 191, 29, 7, 253, 190, 29, 7, 253, 189, 29, 7, 253, 188, 29, 7, 253, 187, + 29, 7, 253, 186, 29, 7, 253, 185, 29, 7, 253, 184, 29, 7, 253, 183, 29, + 7, 253, 182, 29, 7, 253, 181, 29, 7, 253, 180, 29, 7, 253, 179, 29, 7, + 253, 178, 29, 7, 253, 177, 29, 7, 253, 176, 29, 7, 253, 175, 29, 7, 253, + 174, 29, 7, 253, 173, 29, 7, 253, 172, 29, 7, 253, 171, 29, 7, 253, 170, + 29, 7, 253, 169, 29, 7, 253, 168, 29, 7, 253, 167, 29, 7, 253, 166, 29, + 7, 253, 165, 29, 7, 253, 164, 29, 7, 253, 163, 29, 7, 253, 162, 29, 7, + 253, 161, 29, 7, 253, 160, 29, 7, 253, 159, 29, 7, 253, 158, 29, 7, 253, + 157, 29, 7, 253, 156, 29, 7, 253, 155, 29, 7, 253, 154, 29, 7, 253, 153, + 29, 7, 253, 152, 29, 7, 253, 151, 29, 7, 253, 150, 29, 7, 253, 149, 29, + 7, 253, 148, 29, 7, 253, 147, 29, 7, 253, 146, 29, 7, 253, 145, 29, 7, + 253, 144, 29, 7, 253, 143, 29, 7, 253, 142, 29, 7, 253, 141, 29, 7, 253, + 140, 29, 7, 253, 139, 29, 7, 253, 138, 29, 7, 253, 137, 29, 7, 253, 136, + 29, 7, 253, 135, 29, 7, 253, 134, 29, 7, 253, 133, 29, 7, 253, 132, 29, + 7, 253, 131, 29, 7, 253, 130, 29, 7, 253, 129, 29, 7, 253, 128, 29, 7, + 253, 127, 29, 7, 253, 126, 29, 7, 253, 125, 29, 7, 253, 124, 29, 7, 253, + 123, 29, 7, 253, 122, 29, 7, 253, 121, 29, 7, 253, 120, 29, 7, 253, 119, + 29, 7, 253, 118, 29, 7, 253, 117, 29, 7, 253, 116, 29, 7, 253, 115, 29, + 7, 253, 114, 29, 7, 253, 113, 29, 7, 253, 112, 29, 7, 253, 111, 29, 7, + 253, 110, 29, 7, 253, 109, 29, 7, 253, 108, 29, 7, 253, 107, 29, 7, 253, + 106, 29, 7, 253, 105, 29, 7, 253, 104, 29, 7, 253, 103, 29, 7, 253, 102, + 29, 7, 253, 101, 29, 7, 253, 100, 29, 7, 253, 99, 29, 7, 253, 98, 29, 7, + 253, 97, 29, 7, 253, 96, 29, 7, 253, 95, 29, 7, 253, 94, 29, 7, 253, 93, + 29, 7, 253, 92, 29, 7, 253, 91, 29, 7, 253, 90, 29, 7, 253, 89, 26, 1, + 209, 218, 214, 1, 216, 142, 26, 1, 209, 218, 231, 173, 232, 166, 26, 1, + 209, 218, 209, 40, 216, 143, 209, 127, 26, 1, 209, 218, 209, 40, 216, + 143, 209, 128, 26, 1, 209, 218, 214, 251, 216, 142, 26, 1, 209, 218, 203, + 0, 26, 1, 209, 218, 198, 124, 216, 142, 26, 1, 209, 218, 212, 47, 216, + 142, 26, 1, 209, 218, 203, 68, 210, 221, 213, 141, 26, 1, 209, 218, 209, + 40, 210, 221, 213, 142, 209, 127, 26, 1, 209, 218, 209, 40, 210, 221, + 213, 142, 209, 128, 26, 1, 209, 218, 217, 131, 26, 1, 209, 218, 197, 95, + 217, 132, 26, 1, 209, 218, 214, 62, 26, 1, 209, 218, 217, 128, 26, 1, + 209, 218, 217, 77, 26, 1, 209, 218, 215, 86, 26, 1, 209, 218, 203, 249, + 26, 1, 209, 218, 212, 187, 26, 1, 209, 218, 221, 234, 26, 1, 209, 218, + 213, 108, 26, 1, 209, 218, 200, 160, 26, 1, 209, 218, 214, 0, 26, 1, 209, + 218, 220, 15, 26, 1, 209, 218, 219, 177, 220, 188, 26, 1, 209, 218, 212, + 197, 216, 150, 26, 1, 209, 218, 217, 135, 26, 1, 209, 218, 210, 98, 26, + 1, 209, 218, 231, 72, 26, 1, 209, 218, 210, 170, 26, 1, 209, 218, 215, + 232, 214, 35, 26, 1, 209, 218, 212, 28, 216, 153, 26, 1, 209, 218, 126, + 191, 195, 214, 244, 26, 1, 209, 218, 231, 73, 26, 1, 209, 218, 212, 197, + 212, 198, 26, 1, 209, 218, 202, 139, 26, 1, 209, 218, 216, 135, 26, 1, + 209, 218, 216, 156, 26, 1, 209, 218, 215, 207, 26, 1, 209, 218, 222, 105, + 26, 1, 209, 218, 210, 221, 219, 225, 26, 1, 209, 218, 214, 163, 219, 225, + 26, 1, 209, 218, 209, 240, 26, 1, 209, 218, 217, 129, 26, 1, 209, 218, + 213, 185, 26, 1, 209, 218, 208, 144, 26, 1, 209, 218, 197, 87, 26, 1, + 209, 218, 218, 221, 26, 1, 209, 218, 202, 17, 26, 1, 209, 218, 199, 58, + 26, 1, 209, 218, 217, 126, 26, 1, 209, 218, 221, 241, 26, 1, 209, 218, + 214, 159, 26, 1, 209, 218, 220, 203, 26, 1, 209, 218, 215, 208, 26, 1, + 209, 218, 202, 252, 26, 1, 209, 218, 219, 20, 26, 1, 209, 218, 232, 239, + 26, 1, 209, 218, 206, 137, 26, 1, 209, 218, 221, 10, 26, 1, 209, 218, + 202, 13, 26, 1, 209, 218, 217, 72, 209, 173, 26, 1, 209, 218, 203, 61, + 26, 1, 209, 218, 212, 196, 26, 1, 209, 218, 203, 42, 212, 208, 191, 203, + 26, 1, 209, 218, 212, 69, 215, 228, 26, 1, 209, 218, 210, 216, 26, 1, + 209, 218, 213, 110, 26, 1, 209, 218, 196, 85, 26, 1, 209, 218, 214, 38, + 26, 1, 209, 218, 217, 125, 26, 1, 209, 218, 213, 153, 26, 1, 209, 218, + 217, 6, 26, 1, 209, 218, 212, 84, 26, 1, 209, 218, 199, 62, 26, 1, 209, + 218, 202, 8, 26, 1, 209, 218, 210, 217, 26, 1, 209, 218, 212, 212, 26, 1, + 209, 218, 217, 133, 26, 1, 209, 218, 212, 81, 26, 1, 209, 218, 222, 66, + 26, 1, 209, 218, 212, 215, 26, 1, 209, 218, 195, 148, 26, 1, 209, 218, + 218, 225, 26, 1, 209, 218, 214, 102, 26, 1, 209, 218, 214, 217, 26, 1, + 209, 218, 217, 5, 26, 1, 209, 217, 212, 210, 26, 1, 209, 217, 197, 95, + 217, 130, 26, 1, 209, 217, 202, 204, 26, 1, 209, 217, 203, 253, 197, 94, + 26, 1, 209, 217, 219, 23, 212, 193, 26, 1, 209, 217, 217, 12, 217, 134, + 26, 1, 209, 217, 221, 150, 26, 1, 209, 217, 192, 43, 26, 1, 209, 217, + 217, 7, 26, 1, 209, 217, 222, 90, 26, 1, 209, 217, 210, 44, 26, 1, 209, + 217, 192, 126, 219, 225, 26, 1, 209, 217, 220, 36, 212, 208, 212, 95, 26, + 1, 209, 217, 212, 190, 203, 87, 26, 1, 209, 217, 214, 130, 213, 156, 26, + 1, 209, 217, 231, 70, 26, 1, 209, 217, 209, 117, 26, 1, 209, 217, 197, + 95, 212, 206, 26, 1, 209, 217, 203, 92, 213, 151, 26, 1, 209, 217, 203, + 88, 26, 1, 209, 217, 216, 143, 199, 61, 26, 1, 209, 217, 216, 250, 217, + 8, 26, 1, 209, 217, 212, 82, 212, 193, 26, 1, 209, 217, 221, 230, 26, 1, + 209, 217, 231, 71, 26, 1, 209, 217, 221, 226, 26, 1, 209, 217, 220, 120, + 26, 1, 209, 217, 210, 101, 26, 1, 209, 217, 195, 77, 26, 1, 209, 217, + 214, 2, 215, 84, 26, 1, 209, 217, 214, 37, 216, 246, 26, 1, 209, 217, + 192, 254, 26, 1, 209, 217, 205, 175, 26, 1, 209, 217, 199, 240, 26, 1, + 209, 217, 216, 155, 26, 1, 209, 217, 214, 21, 26, 1, 209, 217, 214, 22, + 220, 12, 26, 1, 209, 217, 216, 145, 26, 1, 209, 217, 200, 214, 26, 1, + 209, 217, 216, 254, 26, 1, 209, 217, 215, 212, 26, 1, 209, 217, 212, 99, + 26, 1, 209, 217, 208, 148, 26, 1, 209, 217, 216, 154, 214, 39, 26, 1, + 209, 217, 233, 28, 26, 1, 209, 217, 216, 241, 26, 1, 209, 217, 233, 52, + 26, 1, 209, 217, 221, 238, 26, 1, 209, 217, 217, 160, 213, 145, 26, 1, + 209, 217, 217, 160, 213, 121, 26, 1, 209, 217, 219, 176, 26, 1, 209, 217, + 214, 45, 26, 1, 209, 217, 212, 217, 26, 1, 209, 217, 174, 26, 1, 209, + 217, 221, 133, 26, 1, 209, 217, 213, 246, 26, 1, 209, 216, 214, 1, 217, + 132, 26, 1, 209, 216, 212, 46, 26, 1, 209, 216, 191, 203, 26, 1, 209, + 216, 193, 160, 26, 1, 209, 216, 214, 38, 26, 1, 209, 216, 214, 151, 26, + 1, 209, 216, 214, 8, 26, 1, 209, 216, 231, 80, 26, 1, 209, 216, 217, 2, + 26, 1, 209, 216, 231, 180, 26, 1, 209, 216, 212, 71, 216, 21, 216, 157, + 26, 1, 209, 216, 212, 184, 216, 249, 26, 1, 209, 216, 216, 255, 26, 1, + 209, 216, 209, 123, 26, 1, 209, 216, 214, 136, 26, 1, 209, 216, 217, 10, + 247, 156, 26, 1, 209, 216, 221, 228, 26, 1, 209, 216, 231, 81, 26, 1, + 209, 216, 221, 235, 26, 1, 209, 216, 191, 226, 215, 117, 26, 1, 209, 216, + 212, 40, 26, 1, 209, 216, 216, 243, 26, 1, 209, 216, 212, 216, 26, 1, + 209, 216, 216, 249, 26, 1, 209, 216, 192, 44, 26, 1, 209, 216, 221, 18, + 26, 1, 209, 216, 222, 127, 26, 1, 209, 216, 203, 248, 26, 1, 209, 216, + 214, 145, 26, 1, 209, 216, 199, 238, 26, 1, 209, 216, 213, 125, 26, 1, + 209, 216, 198, 124, 191, 207, 26, 1, 209, 216, 200, 247, 26, 1, 209, 216, + 214, 28, 212, 95, 26, 1, 209, 216, 195, 76, 26, 1, 209, 216, 214, 220, + 26, 1, 209, 216, 217, 160, 221, 237, 26, 1, 209, 216, 212, 198, 26, 1, + 209, 216, 214, 23, 26, 1, 209, 216, 220, 16, 26, 1, 209, 216, 216, 251, + 26, 1, 209, 216, 216, 134, 26, 1, 209, 216, 212, 192, 26, 1, 209, 216, + 199, 57, 26, 1, 209, 216, 214, 25, 26, 1, 209, 216, 232, 84, 26, 1, 209, + 216, 214, 150, 26, 1, 209, 216, 212, 218, 26, 1, 209, 216, 212, 214, 26, + 1, 209, 216, 247, 240, 26, 1, 209, 216, 195, 78, 26, 1, 209, 216, 217, 0, + 26, 1, 209, 216, 206, 68, 26, 1, 209, 216, 213, 155, 26, 1, 209, 216, + 220, 35, 26, 1, 209, 216, 198, 121, 26, 1, 209, 216, 212, 200, 213, 246, + 26, 1, 209, 216, 213, 147, 26, 1, 209, 216, 221, 241, 26, 1, 209, 216, + 214, 30, 26, 1, 209, 216, 217, 125, 26, 1, 209, 216, 216, 244, 26, 1, + 209, 216, 218, 225, 26, 1, 209, 216, 220, 188, 26, 1, 209, 216, 213, 153, + 26, 1, 209, 216, 213, 246, 26, 1, 209, 216, 192, 244, 26, 1, 209, 216, + 214, 26, 26, 1, 209, 216, 212, 203, 26, 1, 209, 216, 212, 194, 26, 1, + 209, 216, 220, 205, 213, 110, 26, 1, 209, 216, 212, 201, 26, 1, 209, 216, + 214, 158, 26, 1, 209, 216, 217, 160, 212, 206, 26, 1, 209, 216, 192, 140, + 26, 1, 209, 216, 214, 157, 26, 1, 209, 216, 202, 255, 26, 1, 209, 216, + 203, 251, 26, 1, 209, 216, 216, 252, 26, 1, 209, 216, 217, 132, 26, 1, + 209, 216, 217, 6, 26, 1, 209, 216, 221, 229, 26, 1, 209, 216, 216, 253, + 26, 1, 209, 216, 221, 233, 26, 1, 209, 216, 217, 10, 209, 179, 26, 1, + 209, 216, 191, 186, 26, 1, 209, 216, 213, 143, 26, 1, 209, 216, 216, 80, + 26, 1, 209, 216, 215, 149, 26, 1, 209, 216, 203, 64, 26, 1, 209, 216, + 221, 252, 219, 250, 26, 1, 209, 216, 221, 252, 233, 65, 26, 1, 209, 216, + 214, 60, 26, 1, 209, 216, 214, 217, 26, 1, 209, 216, 219, 94, 26, 1, 209, + 216, 209, 139, 26, 1, 209, 216, 210, 34, 26, 1, 209, 216, 199, 73, 26, 1, + 158, 216, 242, 26, 1, 158, 193, 158, 26, 1, 158, 213, 141, 26, 1, 158, + 216, 142, 26, 1, 158, 213, 139, 26, 1, 158, 219, 139, 26, 1, 158, 213, + 144, 26, 1, 158, 212, 213, 26, 1, 158, 214, 44, 26, 1, 158, 212, 95, 26, + 1, 158, 192, 255, 26, 1, 158, 213, 254, 26, 1, 158, 203, 111, 26, 1, 158, + 214, 9, 26, 1, 158, 221, 236, 26, 1, 158, 199, 59, 26, 1, 158, 203, 90, + 26, 1, 158, 213, 152, 26, 1, 158, 200, 214, 26, 1, 158, 221, 241, 26, 1, + 158, 192, 128, 26, 1, 158, 220, 206, 26, 1, 158, 205, 130, 26, 1, 158, + 216, 147, 26, 1, 158, 214, 149, 26, 1, 158, 217, 95, 26, 1, 158, 216, + 153, 26, 1, 158, 203, 250, 26, 1, 158, 192, 70, 26, 1, 158, 213, 146, 26, + 1, 158, 221, 232, 216, 245, 26, 1, 158, 214, 5, 26, 1, 158, 197, 94, 26, + 1, 158, 231, 90, 26, 1, 158, 213, 251, 26, 1, 158, 233, 29, 26, 1, 158, + 214, 153, 26, 1, 158, 216, 126, 26, 1, 158, 219, 170, 26, 1, 158, 214, + 135, 26, 1, 158, 215, 227, 26, 1, 158, 216, 130, 26, 1, 158, 208, 127, + 26, 1, 158, 216, 128, 26, 1, 158, 216, 144, 26, 1, 158, 218, 208, 26, 1, + 158, 212, 205, 26, 1, 158, 217, 9, 26, 1, 158, 220, 177, 26, 1, 158, 212, + 84, 26, 1, 158, 199, 62, 26, 1, 158, 202, 8, 26, 1, 158, 191, 186, 26, 1, + 158, 221, 233, 26, 1, 158, 207, 162, 26, 1, 158, 199, 120, 26, 1, 158, + 214, 6, 26, 1, 158, 216, 149, 26, 1, 158, 212, 204, 26, 1, 158, 221, 231, + 26, 1, 158, 209, 129, 26, 1, 158, 209, 233, 26, 1, 158, 212, 57, 26, 1, + 158, 219, 176, 26, 1, 158, 214, 45, 26, 1, 158, 216, 146, 26, 1, 158, + 214, 18, 26, 1, 158, 191, 200, 26, 1, 158, 210, 137, 26, 1, 158, 191, + 199, 26, 1, 158, 214, 158, 26, 1, 158, 212, 193, 26, 1, 158, 200, 249, + 26, 1, 158, 220, 210, 26, 1, 158, 214, 34, 26, 1, 158, 214, 3, 26, 1, + 158, 197, 69, 26, 1, 158, 216, 157, 26, 1, 158, 220, 199, 26, 1, 158, + 212, 202, 26, 1, 158, 199, 60, 26, 1, 158, 217, 127, 26, 1, 158, 214, 43, + 26, 1, 158, 219, 169, 26, 1, 158, 214, 24, 26, 1, 158, 212, 207, 26, 1, + 158, 213, 125, 26, 1, 158, 231, 74, 26, 1, 158, 220, 232, 26, 1, 158, + 207, 56, 211, 119, 26, 1, 158, 199, 226, 26, 1, 158, 198, 50, 26, 1, 158, + 212, 81, 26, 1, 158, 206, 195, 26, 1, 158, 219, 227, 26, 1, 158, 216, + 210, 26, 1, 158, 218, 168, 26, 1, 158, 200, 160, 26, 1, 158, 215, 155, + 26, 1, 158, 203, 76, 26, 1, 158, 203, 86, 26, 1, 158, 220, 149, 26, 1, + 158, 212, 178, 26, 1, 158, 203, 5, 26, 1, 158, 212, 195, 26, 1, 158, 210, + 49, 26, 1, 158, 213, 219, 26, 1, 158, 203, 41, 26, 1, 158, 208, 143, 26, + 1, 158, 215, 84, 26, 1, 158, 219, 0, 26, 1, 158, 207, 56, 215, 144, 26, + 1, 158, 198, 193, 26, 1, 158, 212, 181, 26, 1, 158, 217, 10, 175, 26, 1, + 158, 205, 128, 26, 1, 158, 233, 108, 26, 1, 114, 214, 157, 26, 1, 114, + 198, 57, 26, 1, 114, 216, 255, 26, 1, 114, 220, 16, 26, 1, 114, 195, 10, + 26, 1, 114, 219, 6, 26, 1, 114, 210, 220, 26, 1, 114, 202, 21, 26, 1, + 114, 207, 134, 26, 1, 114, 212, 209, 26, 1, 114, 214, 128, 26, 1, 114, + 208, 161, 26, 1, 114, 199, 197, 26, 1, 114, 214, 11, 26, 1, 114, 221, 14, + 26, 1, 114, 192, 247, 26, 1, 114, 205, 50, 26, 1, 114, 214, 35, 26, 1, + 114, 210, 217, 26, 1, 114, 198, 59, 26, 1, 114, 220, 204, 26, 1, 114, + 219, 22, 26, 1, 114, 212, 212, 26, 1, 114, 213, 243, 26, 1, 114, 217, + 133, 26, 1, 114, 214, 4, 26, 1, 114, 213, 242, 26, 1, 114, 212, 211, 26, + 1, 114, 206, 192, 26, 1, 114, 213, 143, 26, 1, 114, 210, 46, 26, 1, 114, + 205, 197, 26, 1, 114, 214, 19, 26, 1, 114, 216, 136, 26, 1, 114, 231, 68, + 26, 1, 114, 214, 7, 26, 1, 114, 213, 154, 26, 1, 114, 217, 71, 26, 1, + 114, 219, 2, 26, 1, 114, 214, 40, 26, 1, 114, 214, 141, 26, 1, 114, 199, + 225, 212, 193, 26, 1, 114, 203, 252, 26, 1, 114, 208, 154, 26, 1, 114, + 214, 161, 202, 30, 26, 1, 114, 214, 27, 212, 95, 26, 1, 114, 192, 29, 26, + 1, 114, 231, 69, 26, 1, 114, 197, 88, 26, 1, 114, 192, 47, 26, 1, 114, + 209, 73, 26, 1, 114, 197, 75, 26, 1, 114, 221, 239, 26, 1, 114, 200, 248, + 26, 1, 114, 199, 61, 26, 1, 114, 195, 79, 26, 1, 114, 193, 100, 26, 1, + 114, 220, 123, 26, 1, 114, 208, 165, 26, 1, 114, 199, 239, 26, 1, 114, + 231, 89, 26, 1, 114, 214, 50, 26, 1, 114, 203, 89, 26, 1, 114, 216, 131, + 26, 1, 114, 217, 3, 26, 1, 114, 212, 44, 26, 1, 114, 213, 106, 26, 1, + 114, 231, 176, 26, 1, 114, 197, 76, 26, 1, 114, 220, 215, 26, 1, 114, + 192, 104, 26, 1, 114, 212, 82, 242, 237, 26, 1, 114, 192, 18, 26, 1, 114, + 216, 148, 26, 1, 114, 214, 146, 26, 1, 114, 209, 174, 26, 1, 114, 191, + 206, 26, 1, 114, 219, 171, 26, 1, 114, 232, 84, 26, 1, 114, 231, 175, 26, + 1, 114, 213, 253, 26, 1, 114, 221, 241, 26, 1, 114, 217, 136, 26, 1, 114, + 214, 10, 26, 1, 114, 231, 75, 26, 1, 114, 233, 109, 26, 1, 114, 212, 182, + 26, 1, 114, 209, 234, 26, 1, 114, 192, 45, 26, 1, 114, 214, 36, 26, 1, + 114, 212, 82, 248, 209, 26, 1, 114, 212, 24, 26, 1, 114, 209, 35, 26, 1, + 114, 216, 80, 26, 1, 114, 232, 82, 26, 1, 114, 214, 244, 26, 1, 114, 215, + 149, 26, 1, 114, 231, 74, 26, 1, 114, 232, 87, 68, 26, 1, 114, 215, 85, + 26, 1, 114, 208, 160, 26, 1, 114, 213, 255, 26, 1, 114, 220, 188, 26, 1, + 114, 209, 171, 26, 1, 114, 212, 196, 26, 1, 114, 192, 46, 26, 1, 114, + 214, 20, 26, 1, 114, 210, 221, 210, 19, 26, 1, 114, 232, 87, 247, 138, + 26, 1, 114, 232, 167, 26, 1, 114, 213, 148, 26, 1, 114, 65, 26, 1, 114, + 198, 50, 26, 1, 114, 74, 26, 1, 114, 68, 26, 1, 114, 220, 14, 26, 1, 114, + 210, 221, 209, 82, 26, 1, 114, 199, 245, 26, 1, 114, 199, 180, 26, 1, + 114, 214, 161, 215, 71, 228, 172, 26, 1, 114, 203, 64, 26, 1, 114, 192, + 42, 26, 1, 114, 213, 236, 26, 1, 114, 191, 211, 26, 1, 114, 191, 244, + 200, 136, 26, 1, 114, 191, 244, 238, 242, 26, 1, 114, 191, 194, 26, 1, + 114, 191, 202, 26, 1, 114, 221, 227, 26, 1, 114, 209, 232, 26, 1, 114, + 213, 149, 234, 49, 26, 1, 114, 208, 156, 26, 1, 114, 192, 253, 26, 1, + 114, 233, 52, 26, 1, 114, 195, 148, 26, 1, 114, 218, 225, 26, 1, 114, + 216, 100, 26, 1, 114, 207, 20, 26, 1, 114, 207, 163, 26, 1, 114, 213, + 235, 26, 1, 114, 214, 68, 26, 1, 114, 203, 56, 26, 1, 114, 203, 41, 26, + 1, 114, 232, 87, 207, 59, 26, 1, 114, 180, 26, 1, 114, 209, 185, 26, 1, + 114, 219, 0, 26, 1, 114, 221, 67, 26, 1, 114, 216, 186, 26, 1, 114, 174, + 26, 1, 114, 217, 68, 26, 1, 114, 199, 63, 26, 1, 114, 221, 166, 26, 1, + 114, 215, 231, 26, 1, 114, 199, 95, 26, 1, 114, 233, 76, 26, 1, 114, 231, + 62, 26, 1, 209, 215, 155, 26, 1, 209, 215, 66, 26, 1, 209, 215, 220, 232, + 26, 1, 209, 215, 234, 188, 26, 1, 209, 215, 207, 84, 26, 1, 209, 215, + 199, 226, 26, 1, 209, 215, 212, 81, 26, 1, 209, 215, 173, 26, 1, 209, + 215, 206, 195, 26, 1, 209, 215, 206, 242, 26, 1, 209, 215, 216, 210, 26, + 1, 209, 215, 199, 245, 26, 1, 209, 215, 214, 160, 26, 1, 209, 215, 213, + 155, 26, 1, 209, 215, 218, 168, 26, 1, 209, 215, 200, 160, 26, 1, 209, + 215, 203, 76, 26, 1, 209, 215, 202, 222, 26, 1, 209, 215, 203, 248, 26, + 1, 209, 215, 220, 149, 26, 1, 209, 215, 221, 241, 26, 1, 209, 215, 212, + 146, 26, 1, 209, 215, 212, 178, 26, 1, 209, 215, 213, 126, 26, 1, 209, + 215, 191, 243, 26, 1, 209, 215, 203, 5, 26, 1, 209, 215, 170, 26, 1, 209, + 215, 212, 215, 26, 1, 209, 215, 209, 232, 26, 1, 209, 215, 212, 195, 26, + 1, 209, 215, 192, 253, 26, 1, 209, 215, 210, 49, 26, 1, 209, 215, 206, + 68, 26, 1, 209, 215, 213, 219, 26, 1, 209, 215, 207, 20, 26, 1, 209, 215, + 221, 251, 26, 1, 209, 215, 213, 252, 26, 1, 209, 215, 214, 47, 26, 1, + 209, 215, 203, 56, 26, 1, 209, 215, 208, 161, 26, 1, 209, 215, 232, 167, + 26, 1, 209, 215, 193, 190, 26, 1, 209, 215, 219, 146, 26, 1, 209, 215, + 219, 0, 26, 1, 209, 215, 221, 67, 26, 1, 209, 215, 217, 1, 26, 1, 209, + 215, 207, 55, 26, 1, 209, 215, 174, 26, 1, 209, 215, 216, 12, 26, 1, 209, + 215, 217, 9, 26, 1, 209, 215, 199, 73, 26, 1, 209, 215, 221, 21, 26, 1, + 209, 215, 205, 150, 26, 1, 209, 215, 193, 248, 215, 159, 1, 190, 190, + 215, 159, 1, 214, 16, 215, 159, 1, 192, 12, 215, 159, 1, 216, 46, 215, + 159, 1, 249, 153, 215, 159, 1, 238, 32, 215, 159, 1, 65, 215, 159, 1, + 209, 211, 215, 159, 1, 221, 209, 215, 159, 1, 230, 22, 215, 159, 1, 238, + 7, 215, 159, 1, 243, 48, 215, 159, 1, 222, 15, 215, 159, 1, 211, 120, + 215, 159, 1, 217, 133, 215, 159, 1, 213, 179, 215, 159, 1, 168, 215, 159, + 1, 211, 87, 215, 159, 1, 74, 215, 159, 1, 206, 162, 215, 159, 1, 203, 81, + 215, 159, 1, 199, 32, 215, 159, 1, 234, 217, 215, 159, 1, 193, 190, 215, + 159, 1, 71, 215, 159, 1, 221, 67, 215, 159, 1, 220, 24, 215, 159, 1, 173, + 215, 159, 1, 230, 80, 215, 159, 1, 207, 1, 215, 159, 1, 199, 110, 215, + 159, 17, 191, 77, 215, 159, 17, 107, 215, 159, 17, 109, 215, 159, 17, + 138, 215, 159, 17, 134, 215, 159, 17, 149, 215, 159, 17, 169, 215, 159, + 17, 175, 215, 159, 17, 171, 215, 159, 17, 178, 215, 159, 237, 238, 215, + 159, 55, 237, 238, 199, 186, 1, 210, 238, 199, 186, 1, 211, 166, 199, + 186, 1, 211, 58, 199, 186, 1, 210, 247, 199, 186, 1, 250, 123, 199, 186, + 1, 252, 63, 199, 186, 1, 251, 37, 199, 186, 1, 250, 133, 199, 186, 1, + 193, 227, 199, 186, 1, 195, 155, 199, 186, 1, 194, 255, 199, 186, 1, 193, + 236, 199, 186, 1, 233, 182, 199, 186, 1, 234, 197, 199, 186, 1, 234, 46, + 199, 186, 1, 233, 221, 199, 186, 1, 223, 41, 199, 186, 1, 228, 28, 199, + 186, 1, 223, 79, 199, 186, 1, 223, 45, 199, 186, 1, 196, 18, 199, 186, 1, + 196, 160, 199, 186, 1, 196, 64, 199, 186, 1, 196, 22, 199, 186, 1, 250, + 134, 199, 186, 1, 250, 138, 199, 186, 1, 250, 136, 199, 186, 1, 250, 135, + 199, 186, 1, 196, 129, 199, 186, 1, 196, 138, 199, 186, 1, 196, 135, 199, + 186, 1, 196, 130, 199, 186, 1, 53, 214, 70, 199, 186, 1, 179, 196, 145, + 199, 186, 1, 203, 40, 196, 143, 199, 186, 1, 203, 40, 250, 135, 199, 186, + 1, 196, 150, 199, 186, 1, 196, 143, 199, 186, 1, 196, 146, 199, 186, 1, + 196, 145, 199, 186, 1, 196, 131, 199, 186, 1, 196, 134, 199, 186, 1, 196, + 133, 199, 186, 1, 196, 132, 199, 186, 1, 215, 63, 199, 186, 1, 216, 238, + 199, 186, 1, 215, 165, 199, 186, 1, 215, 72, 199, 186, 1, 155, 199, 186, + 1, 221, 215, 199, 186, 1, 231, 240, 199, 186, 1, 214, 68, 199, 186, 1, + 188, 199, 186, 1, 170, 199, 186, 1, 193, 190, 199, 186, 1, 168, 199, 186, + 1, 212, 101, 199, 186, 1, 209, 228, 199, 186, 1, 249, 153, 199, 186, 1, + 174, 199, 186, 1, 180, 199, 186, 1, 140, 199, 186, 1, 173, 199, 186, 1, + 228, 164, 199, 186, 1, 190, 190, 199, 186, 1, 238, 32, 199, 186, 1, 165, + 199, 186, 1, 213, 224, 199, 186, 1, 203, 165, 199, 186, 1, 247, 160, 199, + 186, 1, 197, 168, 199, 186, 1, 231, 91, 199, 186, 1, 228, 161, 199, 186, + 1, 199, 49, 199, 186, 1, 192, 220, 199, 186, 1, 233, 109, 199, 186, 1, + 237, 68, 199, 186, 1, 247, 1, 199, 186, 1, 191, 123, 199, 186, 17, 191, + 77, 199, 186, 17, 107, 199, 186, 17, 109, 199, 186, 17, 138, 199, 186, + 17, 134, 199, 186, 17, 149, 199, 186, 17, 169, 199, 186, 17, 175, 199, + 186, 17, 171, 199, 186, 17, 178, 249, 67, 195, 185, 1, 234, 84, 249, 67, + 195, 185, 1, 155, 249, 67, 195, 185, 1, 205, 68, 249, 67, 195, 185, 1, + 233, 109, 249, 67, 195, 185, 1, 217, 4, 249, 67, 195, 185, 1, 192, 30, + 249, 67, 195, 185, 1, 231, 225, 249, 67, 195, 185, 1, 237, 49, 249, 67, + 195, 185, 1, 221, 20, 249, 67, 195, 185, 1, 222, 201, 249, 67, 195, 185, + 1, 228, 124, 249, 67, 195, 185, 1, 193, 190, 249, 67, 195, 185, 1, 191, + 7, 249, 67, 195, 185, 1, 231, 169, 249, 67, 195, 185, 1, 236, 174, 249, + 67, 195, 185, 1, 247, 42, 249, 67, 195, 185, 1, 196, 23, 249, 67, 195, + 185, 1, 159, 249, 67, 195, 185, 1, 249, 153, 249, 67, 195, 185, 1, 193, + 249, 249, 67, 195, 185, 1, 192, 74, 249, 67, 195, 185, 1, 168, 249, 67, + 195, 185, 1, 193, 177, 249, 67, 195, 185, 1, 65, 249, 67, 195, 185, 1, + 74, 249, 67, 195, 185, 1, 211, 87, 249, 67, 195, 185, 1, 66, 249, 67, + 195, 185, 1, 234, 188, 249, 67, 195, 185, 1, 71, 249, 67, 195, 185, 1, + 68, 249, 67, 195, 185, 33, 137, 198, 79, 249, 67, 195, 185, 33, 130, 198, + 79, 249, 67, 195, 185, 33, 216, 87, 198, 79, 249, 67, 195, 185, 33, 218, + 238, 198, 79, 249, 67, 195, 185, 33, 229, 133, 198, 79, 249, 67, 195, + 185, 232, 80, 201, 63, 145, 90, 18, 222, 12, 145, 90, 18, 222, 8, 145, + 90, 18, 221, 155, 145, 90, 18, 221, 118, 145, 90, 18, 222, 41, 145, 90, + 18, 222, 38, 145, 90, 18, 220, 216, 145, 90, 18, 220, 185, 145, 90, 18, + 222, 14, 145, 90, 18, 221, 225, 145, 90, 18, 222, 101, 145, 90, 18, 222, + 98, 145, 90, 18, 221, 40, 145, 90, 18, 221, 37, 145, 90, 18, 222, 34, + 145, 90, 18, 222, 31, 145, 90, 18, 220, 218, 145, 90, 18, 220, 217, 145, + 90, 18, 221, 60, 145, 90, 18, 221, 25, 145, 90, 18, 221, 157, 145, 90, + 18, 221, 156, 145, 90, 18, 222, 117, 145, 90, 18, 222, 37, 145, 90, 18, + 220, 175, 145, 90, 18, 220, 166, 145, 90, 18, 222, 126, 145, 90, 18, 222, + 118, 145, 90, 120, 195, 160, 145, 90, 120, 212, 185, 145, 90, 120, 220, + 0, 145, 90, 120, 230, 2, 145, 90, 120, 213, 82, 145, 90, 120, 207, 125, + 145, 90, 120, 213, 109, 145, 90, 120, 208, 69, 145, 90, 120, 192, 91, + 145, 90, 120, 229, 108, 145, 90, 120, 217, 25, 145, 90, 120, 243, 131, + 145, 90, 120, 214, 165, 145, 90, 120, 229, 44, 145, 90, 120, 209, 91, + 145, 90, 120, 212, 191, 145, 90, 120, 214, 205, 145, 90, 120, 250, 163, + 145, 90, 120, 192, 216, 145, 90, 120, 247, 76, 145, 90, 87, 243, 17, 197, + 85, 145, 90, 87, 243, 17, 202, 46, 145, 90, 87, 243, 17, 221, 243, 145, + 90, 87, 243, 17, 221, 198, 145, 90, 87, 243, 17, 200, 246, 145, 90, 87, + 243, 17, 229, 2, 145, 90, 87, 243, 17, 199, 165, 145, 90, 3, 195, 5, 198, + 238, 145, 90, 3, 195, 5, 197, 156, 247, 33, 145, 90, 3, 243, 17, 243, + 120, 145, 90, 3, 195, 5, 199, 10, 145, 90, 3, 195, 5, 233, 49, 145, 90, + 3, 192, 171, 212, 179, 145, 90, 3, 192, 171, 207, 3, 145, 90, 3, 192, + 171, 198, 32, 145, 90, 3, 192, 171, 233, 90, 145, 90, 3, 195, 5, 205, 44, + 145, 90, 3, 216, 209, 200, 250, 145, 90, 3, 195, 5, 212, 231, 145, 90, 3, + 228, 31, 192, 111, 145, 90, 3, 192, 215, 145, 90, 3, 243, 17, 197, 143, + 206, 144, 145, 90, 17, 191, 77, 145, 90, 17, 107, 145, 90, 17, 109, 145, + 90, 17, 138, 145, 90, 17, 134, 145, 90, 17, 149, 145, 90, 17, 169, 145, + 90, 17, 175, 145, 90, 17, 171, 145, 90, 17, 178, 145, 90, 31, 199, 90, + 145, 90, 31, 228, 138, 145, 90, 31, 199, 96, 198, 228, 145, 90, 31, 216, + 47, 145, 90, 31, 228, 141, 216, 47, 145, 90, 31, 199, 96, 248, 169, 145, + 90, 31, 197, 227, 145, 90, 3, 195, 5, 218, 220, 145, 90, 3, 192, 168, + 145, 90, 3, 229, 103, 145, 90, 3, 198, 255, 229, 103, 145, 90, 3, 190, + 236, 199, 43, 145, 90, 3, 229, 28, 145, 90, 3, 212, 245, 145, 90, 3, 192, + 206, 145, 90, 3, 212, 183, 145, 90, 3, 250, 146, 145, 90, 3, 197, 7, 247, + 32, 145, 90, 3, 216, 209, 197, 159, 145, 90, 3, 199, 166, 145, 90, 3, + 218, 253, 145, 90, 3, 215, 103, 145, 90, 3, 243, 17, 230, 76, 218, 196, + 212, 189, 212, 188, 145, 90, 3, 243, 17, 238, 194, 197, 150, 145, 90, 3, + 243, 17, 197, 5, 145, 90, 3, 243, 17, 197, 6, 243, 36, 145, 90, 3, 243, + 17, 208, 159, 237, 206, 145, 90, 3, 243, 17, 212, 238, 198, 41, 145, 90, + 242, 244, 3, 197, 154, 145, 90, 242, 244, 3, 192, 76, 145, 90, 242, 244, + 3, 219, 90, 145, 90, 242, 244, 3, 219, 254, 145, 90, 242, 244, 3, 192, + 167, 145, 90, 242, 244, 3, 221, 41, 145, 90, 242, 244, 3, 229, 254, 145, + 90, 242, 244, 3, 215, 147, 145, 90, 242, 244, 3, 198, 239, 145, 90, 242, + 244, 3, 197, 165, 145, 90, 242, 244, 3, 209, 225, 145, 90, 242, 244, 3, + 221, 213, 145, 90, 242, 244, 3, 230, 64, 145, 90, 242, 244, 3, 195, 182, + 145, 90, 242, 244, 3, 233, 86, 145, 90, 242, 244, 3, 192, 118, 145, 90, + 242, 244, 3, 197, 137, 145, 90, 242, 244, 3, 220, 170, 145, 90, 242, 244, + 3, 193, 237, 216, 218, 6, 1, 218, 168, 216, 218, 6, 1, 206, 8, 216, 218, + 6, 1, 196, 12, 216, 218, 6, 1, 193, 224, 216, 218, 6, 1, 250, 176, 216, + 218, 6, 1, 191, 166, 216, 218, 6, 1, 221, 22, 216, 218, 6, 1, 210, 236, + 216, 218, 6, 1, 200, 43, 216, 218, 6, 1, 232, 51, 216, 218, 6, 1, 233, + 175, 216, 218, 6, 1, 68, 216, 218, 6, 1, 222, 152, 216, 218, 6, 1, 65, + 216, 218, 6, 1, 223, 35, 216, 218, 6, 1, 71, 216, 218, 6, 1, 250, 120, + 216, 218, 6, 1, 247, 193, 216, 218, 6, 1, 66, 216, 218, 6, 1, 191, 225, + 216, 218, 6, 1, 172, 216, 218, 6, 1, 208, 104, 216, 218, 6, 1, 228, 169, + 216, 218, 6, 1, 212, 103, 216, 218, 6, 1, 192, 235, 216, 218, 6, 1, 238, + 127, 216, 218, 6, 1, 211, 151, 216, 218, 6, 1, 215, 61, 216, 218, 6, 1, + 146, 216, 218, 6, 1, 74, 216, 218, 6, 1, 251, 236, 216, 218, 6, 1, 192, + 159, 216, 218, 2, 1, 218, 168, 216, 218, 2, 1, 206, 8, 216, 218, 2, 1, + 196, 12, 216, 218, 2, 1, 193, 224, 216, 218, 2, 1, 250, 176, 216, 218, 2, + 1, 191, 166, 216, 218, 2, 1, 221, 22, 216, 218, 2, 1, 210, 236, 216, 218, + 2, 1, 200, 43, 216, 218, 2, 1, 232, 51, 216, 218, 2, 1, 233, 175, 216, + 218, 2, 1, 68, 216, 218, 2, 1, 222, 152, 216, 218, 2, 1, 65, 216, 218, 2, + 1, 223, 35, 216, 218, 2, 1, 71, 216, 218, 2, 1, 250, 120, 216, 218, 2, 1, + 247, 193, 216, 218, 2, 1, 66, 216, 218, 2, 1, 191, 225, 216, 218, 2, 1, + 172, 216, 218, 2, 1, 208, 104, 216, 218, 2, 1, 228, 169, 216, 218, 2, 1, + 212, 103, 216, 218, 2, 1, 192, 235, 216, 218, 2, 1, 238, 127, 216, 218, + 2, 1, 211, 151, 216, 218, 2, 1, 215, 61, 216, 218, 2, 1, 146, 216, 218, + 2, 1, 74, 216, 218, 2, 1, 251, 236, 216, 218, 2, 1, 192, 159, 216, 218, + 17, 191, 77, 216, 218, 17, 107, 216, 218, 17, 109, 216, 218, 17, 138, + 216, 218, 17, 134, 216, 218, 17, 149, 216, 218, 17, 169, 216, 218, 17, + 175, 216, 218, 17, 171, 216, 218, 17, 178, 216, 218, 31, 199, 95, 216, + 218, 31, 234, 127, 216, 218, 31, 197, 37, 216, 218, 31, 198, 251, 216, + 218, 31, 232, 122, 216, 218, 31, 233, 19, 216, 218, 31, 202, 130, 216, + 218, 31, 203, 244, 216, 218, 31, 234, 161, 216, 218, 31, 213, 171, 216, + 218, 17, 91, 251, 157, 20, 216, 218, 17, 105, 251, 157, 20, 216, 218, 17, + 115, 251, 157, 20, 216, 218, 242, 74, 216, 218, 232, 80, 201, 63, 216, + 218, 16, 251, 221, 216, 218, 233, 216, 211, 136, 121, 1, 168, 121, 1, + 249, 153, 121, 1, 11, 168, 121, 1, 209, 110, 121, 1, 174, 121, 1, 216, + 103, 121, 1, 251, 14, 174, 121, 1, 233, 109, 121, 1, 195, 188, 121, 1, + 195, 71, 121, 1, 190, 190, 121, 1, 238, 32, 121, 1, 11, 197, 132, 121, 1, + 11, 190, 190, 121, 1, 197, 132, 121, 1, 237, 191, 121, 1, 180, 121, 1, + 213, 224, 121, 1, 11, 213, 79, 121, 1, 251, 14, 180, 121, 1, 213, 79, + 121, 1, 213, 65, 121, 1, 173, 121, 1, 218, 182, 121, 1, 219, 159, 121, 1, + 219, 148, 121, 1, 198, 112, 121, 1, 236, 183, 121, 1, 198, 104, 121, 1, + 236, 182, 121, 1, 155, 121, 1, 231, 240, 121, 1, 11, 155, 121, 1, 208, + 96, 121, 1, 208, 72, 121, 1, 214, 68, 121, 1, 214, 17, 121, 1, 251, 14, + 214, 68, 121, 1, 140, 121, 1, 192, 220, 121, 1, 231, 91, 121, 1, 231, 66, + 121, 1, 197, 142, 121, 1, 235, 18, 121, 1, 212, 101, 121, 1, 212, 83, + 121, 1, 197, 157, 121, 1, 235, 29, 121, 1, 11, 197, 157, 121, 1, 11, 235, + 29, 121, 1, 207, 82, 197, 157, 121, 1, 203, 165, 121, 1, 201, 175, 121, + 1, 191, 71, 121, 1, 190, 253, 121, 1, 197, 168, 121, 1, 235, 35, 121, 1, + 11, 197, 168, 121, 1, 188, 121, 1, 191, 123, 121, 1, 190, 254, 121, 1, + 190, 224, 121, 1, 190, 204, 121, 1, 251, 14, 190, 224, 121, 1, 190, 196, + 121, 1, 190, 203, 121, 1, 193, 190, 121, 1, 251, 245, 121, 1, 229, 177, + 121, 1, 248, 32, 121, 1, 200, 125, 121, 1, 235, 19, 121, 1, 199, 145, + 121, 1, 197, 161, 121, 1, 206, 71, 121, 3, 120, 52, 164, 121, 1, 214, + 212, 121, 3, 250, 199, 121, 3, 207, 82, 195, 18, 121, 3, 207, 82, 250, + 199, 121, 18, 3, 65, 121, 18, 3, 252, 206, 121, 18, 3, 251, 241, 121, 18, + 3, 251, 132, 121, 18, 3, 251, 122, 121, 18, 3, 74, 121, 18, 3, 211, 87, + 121, 18, 3, 193, 48, 121, 18, 3, 193, 224, 121, 18, 3, 71, 121, 18, 3, + 234, 103, 121, 18, 3, 234, 88, 121, 18, 3, 211, 147, 121, 18, 3, 68, 121, + 18, 3, 228, 35, 121, 18, 3, 228, 34, 121, 18, 3, 228, 33, 121, 18, 3, + 223, 88, 121, 18, 3, 223, 226, 121, 18, 3, 223, 199, 121, 18, 3, 223, 49, + 121, 18, 3, 223, 136, 121, 18, 3, 66, 121, 18, 3, 196, 168, 121, 18, 3, + 196, 167, 121, 18, 3, 196, 166, 121, 18, 3, 196, 30, 121, 18, 3, 196, + 148, 121, 18, 3, 196, 97, 121, 18, 3, 192, 159, 121, 18, 3, 192, 33, 121, + 18, 3, 252, 25, 121, 18, 3, 252, 21, 121, 18, 3, 234, 26, 121, 18, 3, + 206, 113, 234, 26, 121, 18, 3, 234, 34, 121, 18, 3, 206, 113, 234, 34, + 121, 18, 3, 251, 236, 121, 18, 3, 234, 166, 121, 18, 3, 250, 163, 121, + 18, 3, 211, 19, 121, 18, 3, 215, 61, 121, 18, 3, 214, 70, 121, 18, 3, + 196, 81, 121, 18, 3, 191, 205, 121, 18, 3, 211, 141, 121, 18, 3, 211, + 148, 121, 18, 3, 193, 239, 121, 18, 3, 223, 204, 121, 18, 3, 234, 217, + 121, 18, 3, 223, 86, 121, 18, 3, 196, 139, 121, 163, 183, 121, 163, 198, + 54, 183, 121, 163, 58, 121, 163, 60, 121, 1, 198, 77, 121, 1, 198, 76, + 121, 1, 198, 75, 121, 1, 198, 74, 121, 1, 198, 73, 121, 1, 198, 72, 121, + 1, 198, 71, 121, 1, 207, 82, 198, 78, 121, 1, 207, 82, 198, 77, 121, 1, + 207, 82, 198, 75, 121, 1, 207, 82, 198, 74, 121, 1, 207, 82, 198, 73, + 121, 1, 207, 82, 198, 71, 19, 223, 51, 77, 46, 223, 51, 77, 39, 243, 80, + 228, 251, 77, 39, 243, 80, 223, 51, 77, 41, 2, 27, 233, 3, 195, 57, 251, + 157, 207, 107, 87, 247, 160, 195, 57, 251, 157, 207, 107, 87, 213, 223, + 19, 242, 63, 19, 242, 62, 19, 242, 61, 19, 242, 60, 19, 242, 59, 19, 242, + 58, 19, 242, 57, 19, 242, 56, 19, 242, 55, 19, 242, 54, 19, 242, 53, 19, + 242, 52, 19, 242, 51, 19, 242, 50, 19, 242, 49, 19, 242, 48, 19, 242, 47, + 19, 242, 46, 19, 242, 45, 19, 242, 44, 19, 242, 43, 19, 242, 42, 19, 242, + 41, 19, 242, 40, 19, 242, 39, 19, 242, 38, 19, 242, 37, 19, 242, 36, 19, + 242, 35, 19, 242, 34, 19, 242, 33, 19, 242, 32, 19, 242, 31, 19, 242, 30, + 19, 242, 29, 19, 242, 28, 19, 242, 27, 19, 242, 26, 19, 242, 25, 19, 242, + 24, 19, 242, 23, 19, 242, 22, 19, 242, 21, 19, 242, 20, 19, 242, 19, 19, + 242, 18, 19, 242, 17, 19, 242, 16, 19, 242, 15, 19, 242, 14, 19, 242, 13, + 19, 242, 12, 19, 242, 11, 19, 242, 10, 19, 242, 9, 19, 242, 8, 19, 242, + 7, 19, 242, 6, 19, 242, 5, 19, 242, 4, 19, 242, 3, 19, 242, 2, 19, 242, + 1, 19, 242, 0, 19, 241, 255, 19, 241, 254, 19, 241, 253, 19, 241, 252, + 19, 241, 251, 19, 241, 250, 19, 241, 249, 19, 241, 248, 19, 241, 247, 19, 241, 246, 19, 241, 245, 19, 241, 244, 19, 241, 243, 19, 241, 242, 19, 241, 241, 19, 241, 240, 19, 241, 239, 19, 241, 238, 19, 241, 237, 19, 241, 236, 19, 241, 235, 19, 241, 234, 19, 241, 233, 19, 241, 232, 19, @@ -17519,3030 +17602,3084 @@ static const unsigned char phrasebook[] = { 81, 19, 239, 80, 19, 239, 79, 19, 239, 78, 19, 239, 77, 19, 239, 76, 19, 239, 75, 19, 239, 74, 19, 239, 73, 19, 239, 72, 19, 239, 71, 19, 239, 70, 19, 239, 69, 19, 239, 68, 19, 239, 67, 19, 239, 66, 19, 239, 65, 19, 239, - 64, 19, 239, 63, 19, 239, 62, 19, 239, 61, 19, 239, 60, 19, 239, 59, 19, - 239, 58, 19, 239, 57, 19, 239, 56, 19, 239, 55, 19, 239, 54, 19, 239, 53, - 19, 239, 52, 19, 239, 51, 19, 239, 50, 19, 239, 49, 19, 239, 48, 19, 239, - 47, 19, 239, 46, 19, 239, 45, 19, 239, 44, 19, 239, 43, 19, 239, 42, 19, - 239, 41, 19, 239, 40, 19, 239, 39, 19, 239, 38, 19, 239, 37, 19, 239, 36, - 19, 239, 35, 19, 239, 34, 19, 239, 33, 19, 239, 32, 19, 239, 31, 19, 239, - 30, 19, 239, 29, 19, 239, 28, 19, 239, 27, 19, 239, 26, 19, 239, 25, 19, - 239, 24, 19, 239, 23, 19, 239, 22, 19, 239, 21, 19, 239, 20, 19, 239, 19, - 19, 239, 18, 19, 239, 17, 19, 239, 16, 40, 2, 27, 246, 190, 40, 2, 27, - 246, 189, 40, 2, 27, 246, 188, 40, 2, 27, 246, 187, 40, 2, 27, 246, 186, - 40, 2, 27, 246, 185, 40, 2, 27, 246, 184, 40, 2, 27, 246, 183, 40, 2, 27, - 246, 182, 40, 2, 27, 246, 181, 40, 2, 27, 246, 180, 40, 2, 27, 246, 179, - 40, 2, 27, 246, 178, 40, 2, 27, 246, 177, 40, 2, 27, 246, 176, 40, 2, 27, - 246, 175, 40, 2, 27, 246, 174, 40, 2, 27, 246, 173, 40, 2, 27, 246, 172, - 40, 2, 27, 246, 171, 40, 2, 27, 246, 170, 40, 2, 27, 246, 169, 40, 2, 27, - 246, 168, 40, 2, 27, 246, 167, 40, 2, 27, 246, 166, 40, 2, 27, 246, 165, - 40, 2, 27, 246, 164, 40, 2, 27, 246, 163, 40, 2, 27, 246, 162, 40, 2, 27, - 246, 161, 40, 2, 27, 246, 160, 40, 2, 27, 246, 159, 40, 2, 27, 246, 158, - 40, 2, 27, 246, 157, 40, 2, 27, 246, 156, 40, 2, 27, 246, 155, 40, 2, 27, - 246, 154, 40, 2, 27, 246, 153, 40, 2, 27, 246, 152, 40, 2, 27, 246, 151, - 40, 2, 27, 246, 150, 40, 2, 27, 246, 149, 40, 2, 27, 246, 148, 40, 2, 27, - 246, 147, 40, 2, 27, 246, 146, 40, 2, 27, 246, 145, 40, 2, 27, 246, 144, - 40, 2, 27, 246, 143, 40, 2, 27, 246, 142, 40, 2, 27, 246, 141, 40, 2, 27, - 246, 140, 40, 2, 27, 246, 139, 40, 2, 27, 246, 138, 40, 2, 27, 246, 137, - 40, 2, 27, 246, 136, 40, 2, 27, 246, 135, 40, 2, 27, 246, 134, 40, 2, 27, - 246, 133, 40, 2, 27, 246, 132, 40, 2, 27, 246, 131, 40, 2, 27, 246, 130, - 40, 2, 27, 246, 129, 40, 2, 27, 246, 128, 40, 2, 27, 246, 127, 40, 2, 27, - 246, 126, 40, 2, 27, 246, 125, 40, 2, 27, 246, 124, 40, 2, 27, 246, 123, - 40, 2, 27, 246, 122, 40, 2, 27, 246, 121, 40, 2, 27, 246, 120, 40, 2, 27, - 246, 119, 40, 2, 27, 246, 118, 40, 2, 27, 246, 117, 40, 2, 27, 246, 116, - 40, 2, 27, 246, 115, 40, 2, 27, 246, 114, 40, 2, 27, 246, 113, 40, 2, 27, - 246, 112, 40, 2, 27, 246, 111, 40, 2, 27, 246, 110, 40, 2, 27, 246, 109, - 40, 2, 27, 246, 108, 40, 2, 27, 246, 107, 40, 2, 27, 246, 106, 40, 2, 27, - 246, 105, 40, 2, 27, 246, 104, 40, 2, 27, 246, 103, 40, 2, 27, 246, 102, - 40, 2, 27, 246, 101, 40, 2, 27, 246, 100, 40, 2, 27, 246, 99, 40, 2, 27, - 246, 98, 40, 2, 27, 246, 97, 40, 2, 27, 246, 96, 40, 2, 27, 246, 95, 40, - 2, 27, 246, 94, 40, 2, 27, 246, 93, 40, 2, 27, 246, 92, 40, 2, 27, 246, - 91, 40, 2, 27, 246, 90, 40, 2, 27, 246, 89, 40, 2, 27, 246, 88, 40, 2, - 27, 246, 87, 40, 2, 27, 246, 86, 40, 2, 27, 246, 85, 40, 2, 27, 246, 84, - 40, 2, 27, 246, 83, 40, 2, 27, 246, 82, 40, 2, 27, 246, 81, 40, 2, 27, - 246, 80, 40, 2, 27, 246, 79, 40, 2, 27, 246, 78, 40, 2, 27, 246, 77, 40, - 2, 27, 246, 76, 40, 2, 27, 246, 75, 40, 2, 27, 246, 74, 40, 2, 27, 246, - 73, 40, 2, 27, 246, 72, 40, 2, 27, 246, 71, 40, 2, 27, 246, 70, 40, 2, - 27, 246, 69, 40, 2, 27, 246, 68, 40, 2, 27, 246, 67, 40, 2, 27, 246, 66, - 40, 2, 27, 246, 65, 40, 2, 27, 246, 64, 40, 2, 27, 246, 63, 40, 2, 27, - 246, 62, 40, 2, 27, 246, 61, 40, 2, 27, 246, 60, 40, 2, 27, 246, 59, 40, - 2, 27, 246, 58, 40, 2, 27, 246, 57, 40, 2, 27, 246, 56, 40, 2, 27, 246, - 55, 40, 2, 27, 246, 54, 40, 2, 27, 246, 53, 40, 2, 27, 246, 52, 40, 2, - 27, 246, 51, 40, 2, 27, 246, 50, 40, 2, 27, 246, 49, 40, 2, 27, 246, 48, - 40, 2, 27, 246, 47, 40, 2, 27, 246, 46, 40, 2, 27, 246, 45, 40, 2, 27, - 246, 44, 40, 2, 27, 246, 43, 40, 2, 27, 246, 42, 40, 2, 27, 246, 41, 40, - 2, 27, 246, 40, 40, 2, 27, 246, 39, 40, 2, 27, 246, 38, 40, 2, 27, 246, - 37, 40, 2, 27, 246, 36, 40, 2, 27, 246, 35, 40, 2, 27, 246, 34, 40, 2, - 27, 246, 33, 40, 2, 27, 246, 32, 40, 2, 27, 246, 31, 40, 2, 27, 246, 30, - 40, 2, 27, 246, 29, 40, 2, 27, 246, 28, 40, 2, 27, 246, 27, 40, 2, 27, - 246, 26, 40, 2, 27, 246, 25, 40, 2, 27, 246, 24, 40, 2, 27, 246, 23, 40, - 2, 27, 246, 22, 40, 2, 27, 246, 21, 40, 2, 27, 246, 20, 40, 2, 27, 246, - 19, 40, 2, 27, 246, 18, 40, 2, 27, 246, 17, 40, 2, 27, 246, 16, 40, 2, - 27, 246, 15, 40, 2, 27, 246, 14, 40, 2, 27, 246, 13, 40, 2, 27, 246, 12, - 40, 2, 27, 246, 11, 40, 2, 27, 246, 10, 40, 2, 27, 246, 9, 40, 2, 27, - 246, 8, 40, 2, 27, 246, 7, 40, 2, 27, 246, 6, 40, 2, 27, 246, 5, 40, 2, - 27, 246, 4, 40, 2, 27, 246, 3, 40, 2, 27, 246, 2, 40, 2, 27, 246, 1, 40, - 2, 27, 246, 0, 40, 2, 27, 245, 255, 40, 2, 27, 245, 254, 40, 2, 27, 245, - 253, 40, 2, 27, 245, 252, 40, 2, 27, 245, 251, 40, 2, 27, 245, 250, 40, - 2, 27, 245, 249, 40, 2, 27, 245, 248, 40, 2, 27, 245, 247, 40, 2, 27, - 245, 246, 40, 2, 27, 245, 245, 40, 2, 27, 245, 244, 40, 2, 27, 245, 243, - 40, 2, 27, 245, 242, 40, 2, 27, 245, 241, 40, 2, 27, 245, 240, 40, 2, 27, - 245, 239, 40, 2, 27, 245, 238, 40, 2, 27, 245, 237, 40, 2, 27, 245, 236, - 40, 2, 27, 245, 235, 40, 2, 27, 245, 234, 40, 2, 27, 245, 233, 40, 2, 27, - 245, 232, 40, 2, 27, 245, 231, 40, 2, 27, 245, 230, 40, 2, 27, 245, 229, - 40, 2, 27, 245, 228, 40, 2, 27, 245, 227, 40, 2, 27, 245, 226, 40, 2, 27, - 245, 225, 40, 2, 27, 245, 224, 40, 2, 27, 245, 223, 40, 2, 27, 245, 222, - 40, 2, 27, 245, 221, 40, 2, 27, 245, 220, 40, 2, 27, 245, 219, 40, 2, 27, - 245, 218, 40, 2, 27, 245, 217, 40, 2, 27, 245, 216, 40, 2, 27, 245, 215, - 40, 2, 27, 245, 214, 40, 2, 27, 245, 213, 40, 2, 27, 245, 212, 40, 2, 27, - 245, 211, 40, 2, 27, 245, 210, 40, 2, 27, 245, 209, 40, 2, 27, 245, 208, - 40, 2, 27, 245, 207, 40, 2, 27, 245, 206, 40, 2, 27, 245, 205, 40, 2, 27, - 245, 204, 40, 2, 27, 245, 203, 40, 2, 27, 245, 202, 40, 2, 27, 245, 201, - 40, 2, 27, 245, 200, 40, 2, 27, 245, 199, 40, 2, 27, 245, 198, 40, 2, 27, - 245, 197, 40, 2, 27, 245, 196, 40, 2, 27, 245, 195, 40, 2, 27, 245, 194, - 40, 2, 27, 245, 193, 40, 2, 27, 245, 192, 40, 2, 27, 245, 191, 40, 2, 27, - 245, 190, 40, 2, 27, 245, 189, 40, 2, 27, 245, 188, 40, 2, 27, 245, 187, - 40, 2, 27, 245, 186, 40, 2, 27, 245, 185, 40, 2, 27, 245, 184, 40, 2, 27, - 245, 183, 40, 2, 27, 245, 182, 40, 2, 27, 245, 181, 40, 2, 27, 245, 180, - 40, 2, 27, 245, 179, 40, 2, 27, 245, 178, 40, 2, 27, 245, 177, 40, 2, 27, - 245, 176, 40, 2, 27, 245, 175, 40, 2, 27, 245, 174, 40, 2, 27, 245, 173, - 40, 2, 27, 245, 172, 40, 2, 27, 245, 171, 40, 2, 27, 245, 170, 40, 2, 27, - 245, 169, 40, 2, 27, 245, 168, 40, 2, 27, 245, 167, 40, 2, 27, 245, 166, - 40, 2, 27, 245, 165, 40, 2, 27, 245, 164, 40, 2, 27, 245, 163, 40, 2, 27, - 245, 162, 40, 2, 27, 245, 161, 40, 2, 27, 245, 160, 40, 2, 27, 245, 159, - 40, 2, 27, 245, 158, 40, 2, 27, 245, 157, 40, 2, 27, 245, 156, 40, 2, 27, - 245, 155, 40, 2, 27, 245, 154, 40, 2, 27, 245, 153, 40, 2, 27, 245, 152, - 40, 2, 27, 245, 151, 40, 2, 27, 245, 150, 40, 2, 27, 245, 149, 40, 2, 27, - 245, 148, 40, 2, 27, 245, 147, 40, 2, 27, 245, 146, 40, 2, 27, 245, 145, - 40, 2, 27, 245, 144, 40, 2, 27, 245, 143, 40, 2, 27, 245, 142, 40, 2, 27, - 245, 141, 40, 2, 27, 245, 140, 40, 2, 27, 245, 139, 40, 2, 27, 245, 138, - 40, 2, 27, 245, 137, 40, 2, 27, 245, 136, 40, 2, 27, 245, 135, 40, 2, 27, - 245, 134, 40, 2, 27, 245, 133, 40, 2, 27, 245, 132, 40, 2, 27, 245, 131, - 40, 2, 27, 245, 130, 40, 2, 27, 245, 129, 40, 2, 27, 245, 128, 40, 2, 27, - 245, 127, 40, 2, 27, 245, 126, 40, 2, 27, 245, 125, 40, 2, 27, 245, 124, - 40, 2, 27, 245, 123, 40, 2, 27, 245, 122, 40, 2, 27, 245, 121, 40, 2, 27, - 245, 120, 40, 2, 27, 245, 119, 40, 2, 27, 245, 118, 40, 2, 27, 245, 117, - 40, 2, 27, 245, 116, 40, 2, 27, 245, 115, 40, 2, 27, 245, 114, 40, 2, 27, - 245, 113, 40, 2, 27, 245, 112, 40, 2, 27, 245, 111, 40, 2, 27, 245, 110, - 40, 2, 27, 245, 109, 40, 2, 27, 245, 108, 40, 2, 27, 245, 107, 40, 2, 27, - 245, 106, 40, 2, 27, 245, 105, 40, 2, 27, 245, 104, 40, 2, 27, 245, 103, - 40, 2, 27, 245, 102, 40, 2, 27, 245, 101, 40, 2, 27, 245, 100, 40, 2, 27, - 245, 99, 40, 2, 27, 245, 98, 40, 2, 27, 245, 97, 40, 2, 27, 245, 96, 40, - 2, 27, 245, 95, 40, 2, 27, 245, 94, 40, 2, 27, 245, 93, 40, 2, 27, 245, - 92, 40, 2, 27, 245, 91, 40, 2, 27, 245, 90, 40, 2, 27, 245, 89, 40, 2, - 27, 245, 88, 40, 2, 27, 245, 87, 40, 2, 27, 245, 86, 40, 2, 27, 245, 85, - 40, 2, 27, 245, 84, 40, 2, 27, 245, 83, 40, 2, 27, 245, 82, 40, 2, 27, - 245, 81, 40, 2, 27, 245, 80, 40, 2, 27, 245, 79, 40, 2, 27, 245, 78, 40, - 2, 27, 245, 77, 40, 2, 27, 245, 76, 40, 2, 27, 245, 75, 40, 2, 27, 245, - 74, 40, 2, 27, 245, 73, 40, 2, 27, 245, 72, 40, 2, 27, 245, 71, 40, 2, - 27, 245, 70, 40, 2, 27, 245, 69, 40, 2, 27, 245, 68, 40, 2, 27, 245, 67, - 40, 2, 27, 245, 66, 40, 2, 27, 245, 65, 40, 2, 27, 245, 64, 40, 2, 27, - 245, 63, 40, 2, 27, 245, 62, 40, 2, 27, 245, 61, 40, 2, 27, 245, 60, 40, - 2, 27, 245, 59, 40, 2, 27, 245, 58, 40, 2, 27, 245, 57, 40, 2, 27, 245, - 56, 40, 2, 27, 245, 55, 40, 2, 27, 245, 54, 40, 2, 27, 245, 53, 40, 2, - 27, 245, 52, 40, 2, 27, 245, 51, 40, 2, 27, 245, 50, 40, 2, 27, 245, 49, - 40, 2, 27, 245, 48, 40, 2, 27, 245, 47, 40, 2, 27, 245, 46, 40, 2, 27, - 245, 45, 40, 2, 27, 245, 44, 40, 2, 27, 245, 43, 40, 2, 27, 245, 42, 40, - 2, 27, 245, 41, 40, 2, 27, 245, 40, 40, 2, 27, 245, 39, 40, 2, 27, 245, - 38, 40, 2, 27, 245, 37, 40, 2, 27, 245, 36, 40, 2, 27, 245, 35, 40, 2, - 27, 245, 34, 40, 2, 27, 245, 33, 40, 2, 27, 245, 32, 40, 2, 27, 245, 31, - 40, 2, 27, 245, 30, 40, 2, 27, 245, 29, 40, 2, 27, 245, 28, 40, 2, 27, - 245, 27, 40, 2, 27, 245, 26, 40, 2, 27, 245, 25, 40, 2, 27, 245, 24, 40, - 2, 27, 245, 23, 40, 2, 27, 245, 22, 40, 2, 27, 245, 21, 40, 2, 27, 245, - 20, 40, 2, 27, 245, 19, 40, 2, 27, 245, 18, 40, 2, 27, 245, 17, 40, 2, - 27, 245, 16, 40, 2, 27, 245, 15, 40, 2, 27, 245, 14, 40, 2, 27, 245, 13, - 40, 2, 27, 245, 12, 40, 2, 27, 245, 11, 40, 2, 27, 245, 10, 40, 2, 27, - 245, 9, 40, 2, 27, 245, 8, 40, 2, 27, 245, 7, 40, 2, 27, 245, 6, 40, 2, - 27, 245, 5, 40, 2, 27, 245, 4, 40, 2, 27, 245, 3, 40, 2, 27, 245, 2, 40, - 2, 27, 245, 1, 40, 2, 27, 245, 0, 40, 2, 27, 244, 255, 40, 2, 27, 244, - 254, 40, 2, 27, 244, 253, 40, 2, 27, 244, 252, 40, 2, 27, 244, 251, 40, - 2, 27, 244, 250, 40, 2, 27, 244, 249, 40, 2, 27, 244, 248, 40, 2, 27, - 244, 247, 40, 2, 27, 244, 246, 40, 2, 27, 244, 245, 40, 2, 27, 244, 244, - 40, 2, 27, 244, 243, 40, 2, 27, 244, 242, 40, 2, 27, 244, 241, 40, 2, 27, - 244, 240, 40, 2, 27, 244, 239, 40, 2, 27, 244, 238, 40, 2, 27, 244, 237, - 40, 2, 27, 244, 236, 40, 2, 27, 244, 235, 40, 2, 27, 244, 234, 40, 2, 27, - 244, 233, 71, 1, 216, 19, 198, 72, 71, 1, 216, 19, 198, 71, 71, 1, 216, - 19, 198, 70, 71, 1, 216, 19, 198, 69, 71, 1, 216, 19, 198, 67, 71, 1, - 216, 19, 198, 66, 71, 1, 216, 19, 214, 197, 198, 73, 71, 1, 216, 19, 214, - 197, 198, 72, 71, 1, 216, 19, 214, 197, 198, 71, 71, 1, 216, 19, 214, - 197, 198, 70, 71, 1, 216, 19, 214, 197, 198, 69, 71, 1, 216, 19, 214, - 197, 198, 67, 71, 1, 216, 19, 214, 197, 198, 66, 71, 1, 250, 220, 73, - 229, 88, 1, 250, 220, 192, 80, 61, 1, 255, 154, 61, 1, 255, 153, 61, 1, - 255, 152, 61, 1, 255, 148, 61, 1, 228, 43, 61, 1, 228, 42, 61, 1, 228, - 41, 61, 1, 228, 40, 61, 1, 196, 227, 61, 1, 196, 226, 61, 1, 196, 225, - 61, 1, 196, 224, 61, 1, 196, 223, 61, 1, 234, 225, 61, 1, 234, 224, 61, - 1, 234, 223, 61, 1, 234, 222, 61, 1, 234, 221, 61, 1, 212, 1, 61, 1, 212, - 0, 61, 1, 211, 255, 61, 1, 222, 114, 61, 1, 222, 111, 61, 1, 222, 110, - 61, 1, 222, 109, 61, 1, 222, 108, 61, 1, 222, 107, 61, 1, 222, 106, 61, - 1, 222, 105, 61, 1, 222, 104, 61, 1, 222, 113, 61, 1, 222, 112, 61, 1, - 222, 103, 61, 1, 221, 141, 61, 1, 221, 140, 61, 1, 221, 139, 61, 1, 221, - 138, 61, 1, 221, 137, 61, 1, 221, 136, 61, 1, 221, 135, 61, 1, 221, 134, - 61, 1, 220, 207, 61, 1, 220, 206, 61, 1, 220, 205, 61, 1, 220, 204, 61, - 1, 220, 203, 61, 1, 220, 202, 61, 1, 220, 201, 61, 1, 221, 252, 61, 1, - 221, 251, 61, 1, 221, 250, 61, 1, 221, 249, 61, 1, 221, 248, 61, 1, 221, - 247, 61, 1, 221, 42, 61, 1, 221, 41, 61, 1, 221, 40, 61, 1, 221, 39, 61, - 1, 205, 201, 61, 1, 205, 200, 61, 1, 205, 199, 61, 1, 205, 198, 61, 1, - 205, 197, 61, 1, 205, 196, 61, 1, 205, 195, 61, 1, 205, 194, 61, 1, 202, - 216, 61, 1, 202, 215, 61, 1, 202, 214, 61, 1, 202, 213, 61, 1, 202, 212, - 61, 1, 202, 211, 61, 1, 200, 254, 61, 1, 200, 253, 61, 1, 200, 252, 61, - 1, 200, 251, 61, 1, 200, 250, 61, 1, 200, 249, 61, 1, 200, 248, 61, 1, - 200, 247, 61, 1, 205, 62, 61, 1, 205, 61, 61, 1, 205, 60, 61, 1, 205, 59, - 61, 1, 205, 58, 61, 1, 202, 40, 61, 1, 202, 39, 61, 1, 202, 38, 61, 1, - 202, 37, 61, 1, 202, 36, 61, 1, 202, 35, 61, 1, 202, 34, 61, 1, 199, 246, - 61, 1, 199, 245, 61, 1, 199, 244, 61, 1, 199, 243, 61, 1, 198, 187, 61, - 1, 198, 186, 61, 1, 198, 185, 61, 1, 198, 184, 61, 1, 198, 183, 61, 1, - 198, 182, 61, 1, 198, 181, 61, 1, 197, 89, 61, 1, 197, 88, 61, 1, 197, - 87, 61, 1, 197, 86, 61, 1, 197, 85, 61, 1, 199, 139, 61, 1, 199, 138, 61, - 1, 199, 137, 61, 1, 199, 136, 61, 1, 199, 135, 61, 1, 199, 134, 61, 1, - 199, 133, 61, 1, 199, 132, 61, 1, 199, 131, 61, 1, 198, 93, 61, 1, 198, - 92, 61, 1, 198, 91, 61, 1, 198, 90, 61, 1, 198, 89, 61, 1, 198, 88, 61, - 1, 198, 87, 61, 1, 214, 248, 61, 1, 214, 247, 61, 1, 214, 246, 61, 1, - 214, 245, 61, 1, 214, 244, 61, 1, 214, 243, 61, 1, 214, 242, 61, 1, 214, - 241, 61, 1, 214, 240, 61, 1, 213, 204, 61, 1, 213, 203, 61, 1, 213, 202, - 61, 1, 213, 201, 61, 1, 213, 200, 61, 1, 213, 199, 61, 1, 213, 198, 61, - 1, 213, 197, 61, 1, 212, 164, 61, 1, 212, 163, 61, 1, 212, 162, 61, 1, - 214, 106, 61, 1, 214, 105, 61, 1, 214, 104, 61, 1, 214, 103, 61, 1, 214, - 102, 61, 1, 214, 101, 61, 1, 214, 100, 61, 1, 213, 29, 61, 1, 213, 28, - 61, 1, 213, 27, 61, 1, 213, 26, 61, 1, 213, 25, 61, 1, 230, 71, 61, 1, - 230, 68, 61, 1, 230, 67, 61, 1, 230, 66, 61, 1, 230, 65, 61, 1, 230, 64, - 61, 1, 230, 63, 61, 1, 230, 62, 61, 1, 230, 61, 61, 1, 230, 70, 61, 1, - 230, 69, 61, 1, 229, 125, 61, 1, 229, 124, 61, 1, 229, 123, 61, 1, 229, - 122, 61, 1, 229, 121, 61, 1, 229, 120, 61, 1, 229, 119, 61, 1, 228, 127, - 61, 1, 228, 126, 61, 1, 228, 125, 61, 1, 229, 212, 61, 1, 229, 211, 61, - 1, 229, 210, 61, 1, 229, 209, 61, 1, 229, 208, 61, 1, 229, 207, 61, 1, - 229, 206, 61, 1, 228, 246, 61, 1, 228, 245, 61, 1, 228, 244, 61, 1, 228, - 243, 61, 1, 228, 242, 61, 1, 228, 241, 61, 1, 228, 240, 61, 1, 228, 239, - 61, 1, 217, 138, 61, 1, 217, 137, 61, 1, 217, 136, 61, 1, 217, 135, 61, - 1, 217, 134, 61, 1, 217, 133, 61, 1, 217, 132, 61, 1, 216, 80, 61, 1, - 216, 79, 61, 1, 216, 78, 61, 1, 216, 77, 61, 1, 216, 76, 61, 1, 216, 75, - 61, 1, 216, 74, 61, 1, 215, 138, 61, 1, 215, 137, 61, 1, 215, 136, 61, 1, - 215, 135, 61, 1, 216, 212, 61, 1, 216, 211, 61, 1, 216, 210, 61, 1, 215, - 250, 61, 1, 215, 249, 61, 1, 215, 248, 61, 1, 215, 247, 61, 1, 215, 246, - 61, 1, 215, 245, 61, 1, 192, 148, 61, 1, 192, 147, 61, 1, 192, 146, 61, - 1, 192, 145, 61, 1, 192, 144, 61, 1, 192, 141, 61, 1, 191, 224, 61, 1, - 191, 223, 61, 1, 191, 222, 61, 1, 191, 221, 61, 1, 192, 11, 61, 1, 192, - 10, 61, 1, 192, 9, 61, 1, 192, 8, 61, 1, 192, 7, 61, 1, 192, 6, 61, 1, - 207, 180, 61, 1, 207, 179, 61, 1, 207, 178, 61, 1, 207, 177, 61, 1, 206, - 251, 61, 1, 206, 250, 61, 1, 206, 249, 61, 1, 206, 248, 61, 1, 206, 247, - 61, 1, 206, 246, 61, 1, 206, 245, 61, 1, 206, 62, 61, 1, 206, 61, 61, 1, - 206, 60, 61, 1, 206, 59, 61, 1, 206, 58, 61, 1, 206, 57, 61, 1, 207, 107, - 61, 1, 207, 106, 61, 1, 207, 105, 61, 1, 207, 104, 61, 1, 206, 156, 61, - 1, 206, 155, 61, 1, 206, 154, 61, 1, 206, 153, 61, 1, 206, 152, 61, 1, - 206, 151, 61, 1, 193, 186, 61, 1, 193, 185, 61, 1, 193, 184, 61, 1, 193, - 183, 61, 1, 193, 182, 61, 1, 193, 83, 61, 1, 193, 82, 61, 1, 193, 81, 61, - 1, 193, 80, 61, 1, 193, 79, 61, 1, 193, 122, 61, 1, 193, 121, 61, 1, 193, - 120, 61, 1, 193, 119, 61, 1, 193, 47, 61, 1, 193, 46, 61, 1, 193, 45, 61, - 1, 193, 44, 61, 1, 193, 43, 61, 1, 193, 42, 61, 1, 193, 41, 61, 1, 215, - 44, 61, 1, 215, 43, 229, 88, 1, 250, 220, 193, 0, 71, 1, 250, 220, 192, - 33, 71, 1, 250, 220, 192, 80, 71, 1, 250, 220, 193, 0, 229, 88, 1, 2, - 193, 84, 229, 88, 1, 2, 193, 123, 229, 88, 1, 2, 193, 48, 71, 1, 2, 193, - 84, 71, 1, 2, 193, 123, 71, 1, 2, 193, 48, 71, 1, 2, 215, 47, 46, 244, - 232, 46, 244, 231, 46, 244, 230, 46, 244, 229, 46, 244, 228, 46, 244, - 227, 46, 244, 226, 46, 244, 225, 46, 244, 224, 46, 244, 223, 46, 244, - 222, 46, 244, 221, 46, 244, 220, 46, 244, 219, 46, 244, 218, 46, 244, - 217, 46, 244, 216, 46, 244, 215, 46, 244, 214, 46, 244, 213, 46, 244, - 212, 46, 244, 211, 46, 244, 210, 46, 244, 209, 46, 244, 208, 46, 244, - 207, 46, 244, 206, 46, 244, 205, 46, 244, 204, 46, 244, 203, 46, 244, - 202, 46, 244, 201, 46, 244, 200, 46, 244, 199, 46, 244, 198, 46, 244, - 197, 46, 244, 196, 46, 244, 195, 46, 244, 194, 46, 244, 193, 46, 244, - 192, 46, 244, 191, 46, 244, 190, 46, 244, 189, 46, 244, 188, 46, 244, - 187, 46, 244, 186, 46, 244, 185, 46, 244, 184, 46, 244, 183, 46, 244, - 182, 46, 244, 181, 46, 244, 180, 46, 244, 179, 46, 244, 178, 46, 244, - 177, 46, 244, 176, 46, 244, 175, 46, 244, 174, 46, 244, 173, 46, 244, - 172, 46, 244, 171, 46, 244, 170, 46, 244, 169, 46, 244, 168, 46, 244, - 167, 46, 244, 166, 46, 244, 165, 46, 244, 164, 46, 244, 163, 46, 244, - 162, 46, 244, 161, 46, 244, 160, 46, 244, 159, 46, 244, 158, 46, 244, - 157, 46, 244, 156, 46, 244, 155, 46, 244, 154, 46, 244, 153, 46, 244, - 152, 46, 244, 151, 46, 244, 150, 46, 244, 149, 46, 244, 148, 46, 244, - 147, 46, 244, 146, 46, 244, 145, 46, 244, 144, 46, 244, 143, 46, 244, - 142, 46, 244, 141, 46, 244, 140, 46, 244, 139, 46, 244, 138, 46, 244, - 137, 46, 244, 136, 46, 244, 135, 46, 244, 134, 46, 244, 133, 46, 244, - 132, 46, 244, 131, 46, 244, 130, 46, 244, 129, 46, 244, 128, 46, 244, - 127, 46, 244, 126, 46, 244, 125, 46, 244, 124, 46, 244, 123, 46, 244, - 122, 46, 244, 121, 46, 244, 120, 46, 244, 119, 46, 244, 118, 46, 244, - 117, 46, 244, 116, 46, 244, 115, 46, 244, 114, 46, 244, 113, 46, 244, - 112, 46, 244, 111, 46, 244, 110, 46, 244, 109, 46, 244, 108, 46, 244, - 107, 46, 244, 106, 46, 244, 105, 46, 244, 104, 46, 244, 103, 46, 244, - 102, 46, 244, 101, 46, 244, 100, 46, 244, 99, 46, 244, 98, 46, 244, 97, - 46, 244, 96, 46, 244, 95, 46, 244, 94, 46, 244, 93, 46, 244, 92, 46, 244, - 91, 46, 244, 90, 46, 244, 89, 46, 244, 88, 46, 244, 87, 46, 244, 86, 46, - 244, 85, 46, 244, 84, 46, 244, 83, 46, 244, 82, 46, 244, 81, 46, 244, 80, - 46, 244, 79, 46, 244, 78, 46, 244, 77, 46, 244, 76, 46, 244, 75, 46, 244, - 74, 46, 244, 73, 46, 244, 72, 46, 244, 71, 46, 244, 70, 46, 244, 69, 46, - 244, 68, 46, 244, 67, 46, 244, 66, 46, 244, 65, 46, 244, 64, 46, 244, 63, - 46, 244, 62, 46, 244, 61, 46, 244, 60, 46, 244, 59, 46, 244, 58, 46, 244, - 57, 46, 244, 56, 46, 244, 55, 46, 244, 54, 46, 244, 53, 46, 244, 52, 46, - 244, 51, 46, 244, 50, 46, 244, 49, 46, 244, 48, 46, 244, 47, 46, 244, 46, - 46, 244, 45, 46, 244, 44, 46, 244, 43, 46, 244, 42, 46, 244, 41, 46, 244, - 40, 46, 244, 39, 46, 244, 38, 46, 244, 37, 46, 244, 36, 46, 244, 35, 46, - 244, 34, 46, 244, 33, 46, 244, 32, 46, 244, 31, 46, 244, 30, 46, 244, 29, - 46, 244, 28, 46, 244, 27, 46, 244, 26, 46, 244, 25, 46, 244, 24, 46, 244, - 23, 46, 244, 22, 46, 244, 21, 46, 244, 20, 46, 244, 19, 46, 244, 18, 46, - 244, 17, 46, 244, 16, 46, 244, 15, 46, 244, 14, 46, 244, 13, 46, 244, 12, - 46, 244, 11, 46, 244, 10, 46, 244, 9, 46, 244, 8, 46, 244, 7, 46, 244, 6, - 46, 244, 5, 46, 244, 4, 46, 244, 3, 46, 244, 2, 46, 244, 1, 46, 244, 0, - 46, 243, 255, 46, 243, 254, 46, 243, 253, 46, 243, 252, 46, 243, 251, 46, - 243, 250, 46, 243, 249, 46, 243, 248, 46, 243, 247, 46, 243, 246, 46, - 243, 245, 46, 243, 244, 46, 243, 243, 46, 243, 242, 46, 243, 241, 46, - 243, 240, 46, 243, 239, 46, 243, 238, 46, 243, 237, 46, 243, 236, 46, - 243, 235, 46, 243, 234, 46, 243, 233, 46, 243, 232, 46, 243, 231, 46, - 243, 230, 46, 243, 229, 46, 243, 228, 46, 243, 227, 46, 243, 226, 46, - 243, 225, 46, 243, 224, 46, 243, 223, 46, 243, 222, 46, 243, 221, 46, - 243, 220, 46, 243, 219, 46, 243, 218, 46, 243, 217, 46, 243, 216, 46, - 243, 215, 46, 243, 214, 46, 243, 213, 46, 243, 212, 46, 243, 211, 46, - 243, 210, 46, 243, 209, 46, 243, 208, 46, 243, 207, 46, 243, 206, 46, - 243, 205, 46, 243, 204, 46, 243, 203, 46, 243, 202, 46, 243, 201, 46, - 243, 200, 46, 243, 199, 46, 243, 198, 46, 243, 197, 46, 243, 196, 46, - 243, 195, 46, 243, 194, 46, 243, 193, 46, 243, 192, 46, 243, 191, 46, - 243, 190, 46, 243, 189, 46, 243, 188, 46, 243, 187, 46, 243, 186, 46, - 243, 185, 46, 243, 184, 46, 243, 183, 46, 243, 182, 46, 243, 181, 46, - 243, 180, 46, 243, 179, 46, 243, 178, 46, 243, 177, 46, 243, 176, 46, - 243, 175, 46, 243, 174, 46, 243, 173, 46, 243, 172, 46, 243, 171, 46, - 243, 170, 46, 243, 169, 46, 243, 168, 46, 243, 167, 46, 243, 166, 46, - 243, 165, 46, 243, 164, 46, 243, 163, 46, 243, 162, 46, 243, 161, 46, - 243, 160, 46, 243, 159, 46, 243, 158, 46, 243, 157, 46, 243, 156, 46, - 243, 155, 46, 243, 154, 46, 243, 153, 46, 243, 152, 46, 243, 151, 46, - 243, 150, 46, 243, 149, 46, 243, 148, 46, 243, 147, 46, 243, 146, 46, - 243, 145, 46, 243, 144, 46, 243, 143, 46, 243, 142, 46, 243, 141, 46, - 243, 140, 46, 243, 139, 46, 243, 138, 46, 243, 137, 46, 243, 136, 46, - 243, 135, 46, 243, 134, 46, 243, 133, 46, 243, 132, 46, 243, 131, 46, - 243, 130, 46, 243, 129, 46, 243, 128, 46, 243, 127, 46, 243, 126, 46, - 243, 125, 46, 243, 124, 46, 243, 123, 46, 243, 122, 46, 243, 121, 46, - 243, 120, 46, 243, 119, 46, 243, 118, 46, 243, 117, 46, 243, 116, 46, - 243, 115, 46, 243, 114, 46, 243, 113, 46, 243, 112, 46, 243, 111, 46, - 243, 110, 46, 243, 109, 46, 243, 108, 46, 243, 107, 46, 243, 106, 46, - 243, 105, 46, 243, 104, 46, 243, 103, 46, 243, 102, 46, 243, 101, 46, - 243, 100, 46, 243, 99, 46, 243, 98, 46, 243, 97, 46, 243, 96, 46, 243, - 95, 46, 243, 94, 46, 243, 93, 124, 1, 230, 83, 124, 1, 192, 235, 124, 1, - 210, 226, 124, 1, 200, 39, 124, 1, 233, 134, 124, 1, 222, 125, 124, 1, - 170, 124, 1, 250, 70, 124, 1, 238, 80, 124, 1, 196, 8, 124, 1, 232, 14, - 124, 1, 148, 124, 1, 210, 227, 215, 47, 124, 1, 238, 81, 206, 3, 124, 1, - 233, 135, 215, 47, 124, 1, 222, 126, 218, 147, 124, 1, 207, 217, 206, 3, - 124, 1, 199, 46, 124, 1, 202, 77, 237, 24, 124, 1, 237, 24, 124, 1, 221, - 78, 124, 1, 202, 77, 223, 7, 124, 1, 229, 80, 124, 1, 219, 136, 124, 1, - 207, 2, 124, 1, 218, 147, 124, 1, 215, 47, 124, 1, 223, 7, 124, 1, 206, - 3, 124, 1, 218, 148, 215, 47, 124, 1, 215, 48, 218, 147, 124, 1, 223, 8, - 218, 147, 124, 1, 206, 4, 223, 7, 124, 1, 218, 148, 4, 236, 96, 124, 1, - 215, 48, 4, 236, 96, 124, 1, 223, 8, 4, 236, 96, 124, 1, 223, 8, 4, 183, - 223, 90, 24, 56, 124, 1, 206, 4, 4, 236, 96, 124, 1, 206, 4, 4, 75, 60, - 124, 1, 218, 148, 206, 3, 124, 1, 215, 48, 206, 3, 124, 1, 223, 8, 206, - 3, 124, 1, 206, 4, 206, 3, 124, 1, 218, 148, 215, 48, 206, 3, 124, 1, - 215, 48, 218, 148, 206, 3, 124, 1, 223, 8, 218, 148, 206, 3, 124, 1, 206, - 4, 223, 8, 206, 3, 124, 1, 223, 8, 206, 4, 4, 236, 96, 124, 1, 223, 8, - 215, 47, 124, 1, 223, 8, 215, 48, 206, 3, 124, 1, 206, 4, 200, 39, 124, - 1, 206, 4, 200, 40, 148, 124, 1, 206, 4, 210, 226, 124, 1, 206, 4, 210, - 227, 148, 124, 1, 200, 40, 206, 3, 124, 1, 200, 40, 207, 217, 206, 3, - 124, 1, 193, 221, 124, 1, 193, 95, 124, 1, 193, 222, 148, 124, 1, 206, 4, - 215, 47, 124, 1, 206, 4, 218, 147, 124, 1, 222, 126, 207, 217, 206, 3, - 124, 1, 232, 15, 207, 217, 206, 3, 124, 1, 206, 4, 222, 125, 124, 1, 206, - 4, 222, 126, 148, 124, 1, 65, 124, 1, 202, 77, 210, 240, 124, 1, 211, - 169, 124, 1, 74, 124, 1, 251, 16, 124, 1, 70, 124, 1, 73, 124, 1, 223, - 197, 124, 1, 203, 35, 70, 124, 1, 196, 135, 124, 1, 234, 145, 124, 1, - 202, 77, 234, 130, 124, 1, 206, 130, 70, 124, 1, 202, 77, 234, 145, 124, - 1, 177, 70, 124, 1, 192, 80, 124, 1, 69, 124, 1, 233, 201, 124, 1, 192, - 182, 124, 1, 126, 215, 47, 124, 1, 177, 69, 124, 1, 206, 130, 69, 124, 1, - 196, 137, 124, 1, 202, 77, 69, 124, 1, 211, 73, 124, 1, 210, 240, 124, 1, - 211, 9, 124, 1, 193, 187, 124, 1, 193, 48, 124, 1, 193, 84, 124, 1, 193, - 110, 124, 1, 193, 14, 124, 1, 214, 200, 69, 124, 1, 214, 200, 74, 124, 1, - 214, 200, 70, 124, 1, 214, 200, 65, 124, 1, 209, 247, 251, 81, 124, 1, - 209, 247, 251, 98, 124, 1, 202, 77, 234, 61, 124, 1, 202, 77, 251, 81, - 124, 1, 202, 77, 211, 93, 124, 1, 121, 218, 147, 124, 251, 208, 45, 228, - 209, 205, 53, 124, 251, 208, 216, 68, 228, 209, 205, 53, 124, 251, 208, - 50, 228, 209, 205, 53, 124, 251, 208, 131, 81, 205, 53, 124, 251, 208, - 216, 68, 81, 205, 53, 124, 251, 208, 136, 81, 205, 53, 124, 251, 208, - 250, 120, 205, 53, 124, 251, 208, 250, 120, 219, 191, 205, 53, 124, 251, - 208, 250, 120, 199, 183, 124, 251, 208, 250, 120, 199, 210, 124, 251, - 208, 250, 120, 234, 227, 106, 124, 251, 208, 250, 120, 228, 44, 106, 124, - 251, 208, 250, 120, 199, 184, 106, 124, 251, 208, 136, 251, 250, 124, - 251, 208, 136, 198, 167, 251, 250, 124, 251, 208, 136, 230, 176, 124, - 251, 208, 136, 177, 230, 176, 124, 251, 208, 136, 236, 96, 124, 251, 208, - 136, 242, 218, 124, 251, 208, 136, 219, 88, 124, 251, 208, 136, 193, 136, - 124, 251, 208, 136, 195, 132, 124, 251, 208, 131, 251, 250, 124, 251, - 208, 131, 198, 167, 251, 250, 124, 251, 208, 131, 230, 176, 124, 251, - 208, 131, 177, 230, 176, 124, 251, 208, 131, 236, 96, 124, 251, 208, 131, - 242, 218, 124, 251, 208, 131, 219, 88, 124, 251, 208, 131, 193, 136, 124, - 251, 208, 131, 195, 132, 124, 251, 208, 131, 55, 124, 3, 186, 4, 238, - 170, 124, 199, 4, 1, 205, 29, 124, 54, 77, 124, 208, 145, 243, 30, 232, - 42, 201, 58, 203, 22, 232, 106, 1, 210, 248, 203, 22, 232, 106, 238, 237, - 210, 248, 203, 22, 232, 106, 143, 201, 73, 203, 22, 232, 106, 132, 201, - 73, 97, 33, 87, 230, 206, 213, 146, 206, 4, 220, 227, 211, 94, 219, 200, - 97, 33, 87, 213, 146, 206, 4, 220, 227, 211, 94, 219, 200, 97, 33, 87, - 197, 158, 211, 94, 219, 200, 97, 33, 87, 230, 206, 213, 146, 211, 94, - 219, 200, 97, 33, 87, 213, 146, 211, 94, 219, 200, 97, 33, 87, 201, 174, - 211, 94, 219, 200, 97, 33, 87, 217, 74, 208, 252, 211, 94, 219, 200, 97, - 33, 87, 208, 252, 211, 94, 219, 200, 97, 33, 87, 193, 228, 211, 94, 219, - 200, 97, 33, 87, 217, 74, 208, 252, 206, 4, 221, 157, 211, 94, 219, 200, - 97, 33, 87, 208, 252, 206, 4, 221, 157, 211, 94, 219, 200, 97, 33, 87, - 193, 228, 206, 4, 221, 157, 211, 94, 219, 200, 97, 33, 87, 230, 206, 213, - 146, 206, 4, 220, 227, 211, 94, 187, 97, 33, 87, 213, 146, 206, 4, 220, - 227, 211, 94, 187, 97, 33, 87, 197, 158, 211, 94, 187, 97, 33, 87, 230, - 206, 213, 146, 211, 94, 187, 97, 33, 87, 213, 146, 211, 94, 187, 97, 33, - 87, 201, 174, 211, 94, 187, 97, 33, 87, 217, 74, 208, 252, 211, 94, 187, - 97, 33, 87, 208, 252, 211, 94, 187, 97, 33, 87, 193, 228, 211, 94, 187, - 97, 33, 87, 217, 74, 208, 252, 206, 4, 221, 157, 211, 94, 187, 97, 33, - 87, 208, 252, 206, 4, 221, 157, 211, 94, 187, 97, 33, 87, 193, 228, 206, - 4, 221, 157, 211, 94, 187, 97, 33, 87, 197, 158, 206, 4, 220, 226, 97, - 33, 87, 217, 74, 208, 252, 206, 4, 220, 226, 97, 33, 87, 201, 44, 217, - 74, 208, 251, 97, 33, 87, 208, 252, 206, 4, 220, 226, 97, 33, 87, 208, - 252, 201, 43, 97, 33, 87, 193, 228, 206, 4, 220, 226, 97, 33, 87, 217, - 74, 208, 252, 201, 43, 97, 33, 87, 230, 206, 193, 227, 97, 33, 87, 191, - 83, 97, 33, 87, 211, 93, 97, 33, 87, 207, 119, 97, 33, 87, 198, 152, 97, - 33, 87, 248, 35, 97, 33, 87, 196, 152, 97, 33, 87, 209, 58, 97, 33, 87, - 218, 253, 97, 33, 87, 220, 176, 97, 33, 87, 222, 88, 97, 33, 87, 191, 74, - 97, 33, 87, 202, 100, 97, 33, 87, 207, 112, 97, 33, 87, 220, 229, 211, - 94, 219, 200, 97, 33, 198, 75, 207, 132, 87, 215, 146, 97, 33, 198, 75, - 207, 132, 87, 200, 149, 97, 33, 198, 75, 207, 132, 87, 197, 242, 97, 33, - 87, 191, 120, 97, 33, 87, 237, 60, 191, 120, 97, 33, 87, 211, 15, 97, 33, - 87, 209, 60, 97, 33, 87, 209, 61, 4, 81, 105, 97, 33, 87, 243, 86, 97, - 33, 87, 243, 87, 209, 38, 97, 33, 87, 211, 161, 97, 33, 87, 202, 5, 212, - 236, 97, 33, 87, 198, 84, 97, 33, 87, 235, 4, 97, 33, 250, 119, 81, 211, - 98, 97, 33, 87, 238, 116, 211, 98, 97, 33, 87, 220, 228, 97, 33, 110, - 198, 75, 207, 132, 223, 116, 97, 208, 196, 59, 219, 143, 97, 208, 196, - 59, 219, 142, 97, 208, 196, 59, 236, 188, 232, 155, 97, 208, 196, 59, - 220, 228, 97, 208, 196, 59, 206, 139, 97, 161, 220, 232, 97, 161, 220, - 233, 198, 151, 97, 161, 210, 112, 97, 161, 235, 12, 196, 9, 243, 65, 97, - 161, 221, 66, 97, 161, 191, 105, 97, 161, 201, 56, 97, 161, 201, 57, 206, - 4, 211, 151, 97, 161, 210, 1, 97, 161, 210, 2, 214, 82, 97, 161, 201, 57, - 4, 202, 5, 212, 236, 97, 161, 243, 64, 97, 161, 210, 176, 97, 161, 191, - 103, 97, 161, 230, 212, 248, 34, 97, 161, 230, 212, 198, 151, 97, 161, - 230, 212, 215, 144, 97, 161, 230, 212, 200, 148, 97, 161, 230, 212, 197, - 241, 97, 161, 194, 250, 208, 176, 97, 161, 194, 250, 215, 147, 97, 161, - 194, 250, 200, 150, 97, 161, 194, 250, 197, 243, 97, 161, 194, 250, 221, - 61, 208, 176, 97, 161, 194, 250, 221, 61, 215, 147, 97, 161, 194, 250, - 221, 61, 200, 150, 97, 161, 194, 250, 221, 61, 197, 243, 97, 161, 54, - 191, 103, 97, 161, 207, 13, 243, 64, 97, 161, 237, 46, 97, 161, 221, 182, - 97, 161, 243, 86, 97, 161, 209, 60, 97, 161, 202, 108, 215, 147, 97, 161, - 202, 108, 200, 150, 97, 161, 202, 108, 197, 243, 97, 161, 202, 108, 198, - 152, 97, 161, 237, 60, 221, 66, 97, 161, 202, 108, 221, 61, 200, 150, 97, - 161, 202, 108, 221, 65, 97, 161, 202, 108, 221, 61, 198, 152, 97, 161, - 202, 108, 235, 9, 208, 176, 97, 161, 202, 108, 235, 9, 200, 150, 97, 161, - 202, 108, 235, 9, 214, 82, 97, 161, 202, 108, 235, 9, 221, 60, 97, 161, - 202, 67, 97, 161, 202, 68, 206, 4, 191, 101, 97, 161, 202, 68, 191, 110, - 97, 161, 202, 68, 206, 4, 220, 226, 97, 161, 220, 228, 97, 161, 206, 139, - 97, 161, 232, 187, 97, 161, 221, 35, 97, 161, 191, 8, 97, 161, 201, 85, - 97, 161, 201, 86, 206, 4, 191, 101, 97, 161, 201, 86, 206, 4, 220, 226, - 97, 161, 201, 86, 206, 4, 191, 102, 228, 44, 220, 226, 97, 161, 201, 86, - 206, 4, 220, 227, 228, 44, 191, 101, 97, 161, 201, 86, 191, 111, 97, 161, - 201, 86, 191, 112, 206, 4, 191, 101, 97, 161, 201, 86, 206, 4, 206, 138, - 97, 161, 201, 86, 206, 4, 235, 3, 191, 100, 97, 161, 201, 86, 206, 4, - 191, 102, 228, 44, 209, 59, 97, 161, 209, 40, 97, 161, 201, 86, 214, 82, - 97, 161, 201, 35, 208, 176, 97, 161, 201, 35, 215, 145, 97, 161, 201, 35, - 220, 225, 97, 161, 201, 35, 209, 36, 97, 161, 201, 35, 208, 254, 97, 161, - 201, 35, 214, 82, 97, 161, 201, 35, 221, 63, 97, 161, 201, 35, 221, 65, - 97, 161, 201, 35, 198, 153, 208, 123, 97, 161, 201, 35, 235, 8, 97, 161, - 201, 35, 235, 7, 97, 161, 201, 35, 235, 5, 97, 161, 201, 35, 235, 9, 221, - 60, 97, 161, 201, 35, 235, 6, 221, 60, 97, 161, 201, 35, 230, 162, 4, - 202, 165, 191, 103, 97, 161, 201, 35, 230, 158, 4, 202, 165, 191, 103, - 97, 161, 201, 35, 230, 161, 97, 161, 201, 35, 230, 157, 97, 161, 201, 35, - 230, 158, 4, 54, 191, 103, 97, 161, 201, 35, 230, 159, 97, 161, 201, 35, - 230, 160, 208, 254, 97, 161, 216, 202, 97, 161, 216, 203, 208, 253, 97, - 161, 216, 203, 221, 59, 97, 161, 216, 203, 221, 62, 97, 161, 216, 203, - 221, 64, 97, 161, 201, 35, 197, 170, 97, 161, 201, 35, 197, 169, 97, 161, - 201, 35, 197, 168, 97, 161, 211, 21, 97, 161, 211, 22, 200, 150, 97, 161, - 211, 22, 197, 243, 97, 161, 211, 22, 220, 231, 200, 150, 97, 161, 211, - 22, 221, 61, 200, 150, 97, 161, 211, 22, 221, 61, 214, 82, 97, 161, 201, - 35, 220, 230, 97, 161, 201, 35, 220, 231, 208, 254, 97, 161, 201, 35, - 220, 231, 230, 162, 4, 202, 165, 191, 103, 97, 161, 201, 35, 220, 231, - 230, 158, 4, 202, 165, 191, 103, 97, 161, 201, 35, 220, 231, 230, 161, - 97, 161, 201, 35, 220, 231, 230, 157, 97, 161, 201, 35, 220, 231, 230, - 158, 4, 54, 191, 103, 97, 161, 201, 35, 220, 231, 230, 159, 97, 161, 201, - 35, 220, 231, 230, 160, 208, 254, 97, 161, 201, 35, 220, 231, 197, 171, - 97, 161, 220, 190, 97, 161, 211, 160, 97, 161, 235, 40, 97, 161, 214, 89, - 97, 161, 210, 69, 72, 37, 16, 208, 162, 72, 37, 16, 237, 172, 72, 37, 16, - 209, 251, 72, 37, 16, 210, 236, 234, 101, 72, 37, 16, 210, 236, 236, 193, - 72, 37, 16, 195, 169, 234, 101, 72, 37, 16, 195, 169, 236, 193, 72, 37, - 16, 222, 18, 72, 37, 16, 200, 56, 72, 37, 16, 210, 110, 72, 37, 16, 191, - 231, 72, 37, 16, 191, 232, 236, 193, 72, 37, 16, 220, 235, 72, 37, 16, - 251, 11, 234, 101, 72, 37, 16, 233, 169, 234, 101, 72, 37, 16, 199, 103, - 72, 37, 16, 221, 222, 72, 37, 16, 251, 0, 72, 37, 16, 251, 1, 236, 193, - 72, 37, 16, 200, 63, 72, 37, 16, 198, 239, 72, 37, 16, 211, 105, 250, - 218, 72, 37, 16, 230, 204, 250, 218, 72, 37, 16, 208, 161, 72, 37, 16, - 246, 200, 72, 37, 16, 195, 158, 72, 37, 16, 223, 30, 250, 218, 72, 37, - 16, 221, 224, 250, 218, 72, 37, 16, 221, 223, 250, 218, 72, 37, 16, 205, - 100, 72, 37, 16, 210, 100, 72, 37, 16, 201, 83, 251, 4, 72, 37, 16, 210, - 235, 250, 218, 72, 37, 16, 195, 168, 250, 218, 72, 37, 16, 251, 5, 250, - 218, 72, 37, 16, 250, 254, 72, 37, 16, 221, 68, 72, 37, 16, 207, 9, 72, - 37, 16, 209, 174, 250, 218, 72, 37, 16, 198, 137, 72, 37, 16, 251, 77, - 72, 37, 16, 205, 32, 72, 37, 16, 200, 67, 250, 218, 72, 37, 16, 200, 67, - 216, 147, 201, 81, 72, 37, 16, 210, 230, 250, 218, 72, 37, 16, 199, 22, - 72, 37, 16, 219, 178, 72, 37, 16, 234, 250, 72, 37, 16, 197, 239, 72, 37, - 16, 199, 71, 72, 37, 16, 220, 238, 72, 37, 16, 251, 11, 233, 169, 214, - 84, 72, 37, 16, 232, 50, 250, 218, 72, 37, 16, 223, 147, 72, 37, 16, 197, - 206, 250, 218, 72, 37, 16, 222, 21, 197, 205, 72, 37, 16, 210, 27, 72, - 37, 16, 208, 166, 72, 37, 16, 221, 18, 72, 37, 16, 243, 12, 250, 218, 72, - 37, 16, 207, 130, 72, 37, 16, 210, 114, 250, 218, 72, 37, 16, 210, 111, - 250, 218, 72, 37, 16, 227, 250, 72, 37, 16, 214, 211, 72, 37, 16, 209, - 229, 72, 37, 16, 221, 19, 251, 116, 72, 37, 16, 197, 206, 251, 116, 72, - 37, 16, 201, 50, 72, 37, 16, 230, 156, 72, 37, 16, 223, 30, 214, 84, 72, - 37, 16, 211, 105, 214, 84, 72, 37, 16, 210, 236, 214, 84, 72, 37, 16, - 209, 228, 72, 37, 16, 221, 2, 72, 37, 16, 209, 227, 72, 37, 16, 220, 237, - 72, 37, 16, 210, 28, 214, 84, 72, 37, 16, 221, 223, 214, 85, 251, 42, 72, - 37, 16, 221, 224, 214, 85, 251, 42, 72, 37, 16, 191, 229, 72, 37, 16, - 251, 1, 214, 84, 72, 37, 16, 251, 2, 200, 64, 214, 84, 72, 37, 16, 191, - 230, 72, 37, 16, 220, 236, 72, 37, 16, 234, 96, 72, 37, 16, 246, 201, 72, - 37, 16, 216, 39, 223, 29, 72, 37, 16, 195, 169, 214, 84, 72, 37, 16, 209, - 174, 214, 84, 72, 37, 16, 208, 167, 214, 84, 72, 37, 16, 211, 101, 72, - 37, 16, 251, 29, 72, 37, 16, 218, 158, 72, 37, 16, 210, 111, 214, 84, 72, - 37, 16, 210, 114, 214, 84, 72, 37, 16, 233, 207, 210, 113, 72, 37, 16, - 220, 123, 72, 37, 16, 251, 30, 72, 37, 16, 197, 206, 214, 84, 72, 37, 16, - 234, 99, 72, 37, 16, 200, 67, 214, 84, 72, 37, 16, 200, 57, 72, 37, 16, - 243, 12, 214, 84, 72, 37, 16, 234, 11, 72, 37, 16, 205, 33, 214, 84, 72, - 37, 16, 192, 199, 221, 68, 72, 37, 16, 197, 203, 72, 37, 16, 208, 168, - 72, 37, 16, 197, 207, 72, 37, 16, 197, 204, 72, 37, 16, 208, 165, 72, 37, - 16, 197, 202, 72, 37, 16, 208, 164, 72, 37, 16, 230, 203, 72, 37, 16, - 250, 210, 72, 37, 16, 233, 207, 250, 210, 72, 37, 16, 210, 230, 214, 84, - 72, 37, 16, 199, 21, 233, 220, 72, 37, 16, 199, 21, 233, 168, 72, 37, 16, - 199, 23, 251, 6, 72, 37, 16, 199, 15, 222, 76, 250, 253, 72, 37, 16, 222, - 20, 72, 37, 16, 234, 48, 72, 37, 16, 192, 38, 222, 17, 72, 37, 16, 192, - 38, 251, 42, 72, 37, 16, 201, 82, 72, 37, 16, 221, 69, 251, 42, 72, 37, - 16, 236, 194, 250, 218, 72, 37, 16, 220, 239, 250, 218, 72, 37, 16, 220, - 239, 251, 116, 72, 37, 16, 220, 239, 214, 84, 72, 37, 16, 251, 5, 214, - 84, 72, 37, 16, 251, 7, 72, 37, 16, 236, 193, 72, 37, 16, 197, 219, 72, - 37, 16, 199, 61, 72, 37, 16, 221, 6, 72, 37, 16, 219, 183, 234, 41, 243, - 2, 72, 37, 16, 219, 183, 234, 251, 243, 3, 72, 37, 16, 219, 183, 197, - 222, 243, 3, 72, 37, 16, 219, 183, 199, 73, 243, 3, 72, 37, 16, 219, 183, - 223, 142, 243, 2, 72, 37, 16, 230, 204, 214, 85, 251, 42, 72, 37, 16, - 230, 204, 210, 101, 250, 206, 72, 37, 16, 230, 204, 210, 101, 237, 28, - 72, 37, 16, 236, 218, 72, 37, 16, 236, 219, 210, 101, 250, 207, 222, 17, - 72, 37, 16, 236, 219, 210, 101, 250, 207, 251, 42, 72, 37, 16, 236, 219, - 210, 101, 237, 28, 72, 37, 16, 197, 228, 72, 37, 16, 250, 211, 72, 37, - 16, 223, 149, 72, 37, 16, 236, 241, 72, 37, 16, 251, 195, 209, 44, 250, - 212, 72, 37, 16, 251, 195, 250, 209, 72, 37, 16, 251, 195, 250, 212, 72, - 37, 16, 251, 195, 216, 141, 72, 37, 16, 251, 195, 216, 152, 72, 37, 16, - 251, 195, 230, 205, 72, 37, 16, 251, 195, 230, 202, 72, 37, 16, 251, 195, - 209, 44, 230, 205, 72, 37, 16, 217, 26, 208, 174, 227, 248, 72, 37, 16, - 217, 26, 251, 118, 208, 174, 227, 248, 72, 37, 16, 217, 26, 237, 27, 227, - 248, 72, 37, 16, 217, 26, 251, 118, 237, 27, 227, 248, 72, 37, 16, 217, - 26, 197, 214, 227, 248, 72, 37, 16, 217, 26, 197, 229, 72, 37, 16, 217, - 26, 199, 66, 227, 248, 72, 37, 16, 217, 26, 199, 66, 219, 187, 227, 248, - 72, 37, 16, 217, 26, 219, 187, 227, 248, 72, 37, 16, 217, 26, 209, 97, - 227, 248, 72, 37, 16, 223, 38, 199, 96, 227, 249, 72, 37, 16, 251, 2, - 199, 96, 227, 249, 72, 37, 16, 233, 38, 199, 63, 72, 37, 16, 233, 38, - 215, 205, 72, 37, 16, 233, 38, 236, 224, 72, 37, 16, 217, 26, 195, 162, - 227, 248, 72, 37, 16, 217, 26, 208, 173, 227, 248, 72, 37, 16, 217, 26, - 209, 97, 199, 66, 227, 248, 72, 37, 16, 230, 199, 215, 48, 251, 6, 72, - 37, 16, 230, 199, 215, 48, 236, 192, 72, 37, 16, 234, 59, 222, 76, 232, - 50, 195, 0, 72, 37, 16, 223, 148, 72, 37, 16, 223, 146, 72, 37, 16, 232, - 50, 250, 219, 237, 26, 227, 247, 72, 37, 16, 232, 50, 236, 239, 168, 72, - 37, 16, 232, 50, 236, 239, 214, 211, 72, 37, 16, 232, 50, 214, 205, 227, - 248, 72, 37, 16, 232, 50, 236, 239, 236, 255, 72, 37, 16, 232, 50, 202, - 101, 236, 238, 236, 255, 72, 37, 16, 232, 50, 236, 239, 221, 253, 72, 37, - 16, 232, 50, 236, 239, 191, 7, 72, 37, 16, 232, 50, 236, 239, 213, 206, - 222, 17, 72, 37, 16, 232, 50, 236, 239, 213, 206, 251, 42, 72, 37, 16, - 232, 50, 217, 78, 243, 4, 236, 224, 72, 37, 16, 232, 50, 217, 78, 243, 4, - 215, 205, 72, 37, 16, 232, 239, 202, 101, 243, 4, 195, 161, 72, 37, 16, - 232, 50, 202, 101, 243, 4, 200, 68, 72, 37, 16, 232, 50, 214, 87, 72, 37, - 16, 243, 5, 190, 230, 72, 37, 16, 243, 5, 221, 67, 72, 37, 16, 243, 5, - 201, 233, 72, 37, 16, 232, 50, 228, 44, 192, 37, 199, 67, 72, 37, 16, - 232, 50, 234, 60, 251, 31, 72, 37, 16, 192, 37, 197, 215, 72, 37, 16, - 236, 232, 197, 215, 72, 37, 16, 236, 232, 199, 67, 72, 37, 16, 236, 232, - 251, 8, 234, 251, 236, 121, 72, 37, 16, 236, 232, 215, 203, 199, 72, 236, - 121, 72, 37, 16, 236, 232, 236, 215, 233, 181, 236, 121, 72, 37, 16, 236, - 232, 197, 226, 211, 111, 236, 121, 72, 37, 16, 192, 37, 251, 8, 234, 251, - 236, 121, 72, 37, 16, 192, 37, 215, 203, 199, 72, 236, 121, 72, 37, 16, - 192, 37, 236, 215, 233, 181, 236, 121, 72, 37, 16, 192, 37, 197, 226, - 211, 111, 236, 121, 72, 37, 16, 231, 110, 236, 231, 72, 37, 16, 231, 110, - 192, 36, 72, 37, 16, 236, 240, 251, 8, 216, 40, 72, 37, 16, 236, 240, - 251, 8, 216, 183, 72, 37, 16, 236, 240, 236, 193, 72, 37, 16, 236, 240, - 199, 13, 72, 37, 16, 202, 176, 199, 13, 72, 37, 16, 202, 176, 199, 14, - 236, 176, 72, 37, 16, 202, 176, 199, 14, 197, 216, 72, 37, 16, 202, 176, - 199, 14, 199, 59, 72, 37, 16, 202, 176, 250, 178, 72, 37, 16, 202, 176, - 250, 179, 236, 176, 72, 37, 16, 202, 176, 250, 179, 197, 216, 72, 37, 16, - 202, 176, 250, 179, 199, 59, 72, 37, 16, 236, 216, 231, 91, 72, 37, 16, - 236, 223, 211, 9, 72, 37, 16, 201, 68, 72, 37, 16, 250, 203, 168, 72, 37, - 16, 250, 203, 195, 0, 72, 37, 16, 250, 203, 231, 203, 72, 37, 16, 250, - 203, 236, 255, 72, 37, 16, 250, 203, 221, 253, 72, 37, 16, 250, 203, 191, - 7, 72, 37, 16, 250, 203, 213, 205, 72, 37, 16, 221, 223, 214, 85, 216, - 151, 72, 37, 16, 221, 224, 214, 85, 216, 151, 72, 37, 16, 221, 223, 214, - 85, 222, 17, 72, 37, 16, 221, 224, 214, 85, 222, 17, 72, 37, 16, 221, 69, - 222, 17, 72, 37, 16, 230, 204, 214, 85, 222, 17, 37, 16, 202, 165, 249, - 33, 37, 16, 54, 249, 33, 37, 16, 52, 249, 33, 37, 16, 207, 14, 52, 249, - 33, 37, 16, 237, 169, 249, 33, 37, 16, 203, 35, 249, 33, 37, 16, 45, 207, - 44, 57, 37, 16, 50, 207, 44, 57, 37, 16, 207, 44, 236, 94, 37, 16, 237, - 213, 205, 36, 37, 16, 237, 242, 247, 60, 37, 16, 205, 36, 37, 16, 242, - 44, 37, 16, 207, 42, 232, 226, 37, 16, 207, 42, 232, 225, 37, 16, 207, - 42, 232, 224, 37, 16, 232, 249, 37, 16, 232, 250, 60, 37, 16, 247, 247, - 77, 37, 16, 247, 102, 37, 16, 248, 7, 37, 16, 248, 5, 37, 16, 211, 88, - 201, 106, 37, 16, 197, 8, 201, 106, 37, 16, 198, 215, 201, 106, 37, 16, - 232, 89, 201, 106, 37, 16, 232, 184, 201, 106, 37, 16, 202, 130, 201, - 106, 37, 16, 202, 128, 232, 67, 37, 16, 232, 87, 232, 67, 37, 16, 232, - 15, 242, 187, 37, 16, 232, 15, 242, 188, 211, 13, 251, 107, 37, 16, 232, - 15, 242, 188, 211, 13, 249, 16, 37, 16, 247, 146, 242, 187, 37, 16, 233, - 135, 242, 187, 37, 16, 233, 135, 242, 188, 211, 13, 251, 107, 37, 16, - 233, 135, 242, 188, 211, 13, 249, 16, 37, 16, 235, 51, 242, 186, 37, 16, - 235, 51, 242, 185, 37, 16, 215, 114, 216, 209, 207, 25, 37, 16, 54, 203, - 121, 37, 16, 54, 232, 166, 37, 16, 232, 167, 196, 73, 37, 16, 232, 167, - 235, 79, 37, 16, 214, 192, 196, 73, 37, 16, 214, 192, 235, 79, 37, 16, - 203, 122, 196, 73, 37, 16, 203, 122, 235, 79, 37, 16, 208, 18, 163, 203, - 121, 37, 16, 208, 18, 163, 232, 166, 37, 16, 242, 23, 198, 141, 37, 16, - 238, 108, 198, 141, 37, 16, 211, 13, 251, 107, 37, 16, 211, 13, 249, 16, - 37, 16, 207, 254, 251, 107, 37, 16, 207, 254, 249, 16, 37, 16, 215, 117, - 207, 25, 37, 16, 193, 85, 207, 25, 37, 16, 134, 207, 25, 37, 16, 208, 18, - 207, 25, 37, 16, 234, 117, 207, 25, 37, 16, 202, 124, 207, 25, 37, 16, - 198, 241, 207, 25, 37, 16, 202, 114, 207, 25, 37, 16, 91, 228, 110, 197, - 26, 207, 25, 37, 16, 192, 236, 212, 245, 37, 16, 107, 212, 245, 37, 16, - 242, 219, 192, 236, 212, 245, 37, 16, 51, 212, 246, 193, 87, 37, 16, 51, - 212, 246, 248, 91, 37, 16, 197, 238, 212, 246, 132, 193, 87, 37, 16, 197, - 238, 212, 246, 132, 248, 91, 37, 16, 197, 238, 212, 246, 45, 193, 87, 37, - 16, 197, 238, 212, 246, 45, 248, 91, 37, 16, 197, 238, 212, 246, 50, 193, - 87, 37, 16, 197, 238, 212, 246, 50, 248, 91, 37, 16, 197, 238, 212, 246, - 143, 193, 87, 37, 16, 197, 238, 212, 246, 143, 248, 91, 37, 16, 197, 238, - 212, 246, 132, 50, 193, 87, 37, 16, 197, 238, 212, 246, 132, 50, 248, 91, - 37, 16, 215, 189, 212, 246, 193, 87, 37, 16, 215, 189, 212, 246, 248, 91, - 37, 16, 197, 235, 212, 246, 143, 193, 87, 37, 16, 197, 235, 212, 246, - 143, 248, 91, 37, 16, 210, 104, 212, 245, 37, 16, 195, 14, 212, 245, 37, - 16, 212, 246, 248, 91, 37, 16, 212, 126, 212, 245, 37, 16, 242, 155, 212, - 246, 193, 87, 37, 16, 242, 155, 212, 246, 248, 91, 37, 16, 247, 244, 37, - 16, 193, 85, 212, 249, 37, 16, 134, 212, 249, 37, 16, 208, 18, 212, 249, - 37, 16, 234, 117, 212, 249, 37, 16, 202, 124, 212, 249, 37, 16, 198, 241, - 212, 249, 37, 16, 202, 114, 212, 249, 37, 16, 91, 228, 110, 197, 26, 212, - 249, 37, 16, 33, 201, 75, 37, 16, 33, 201, 192, 201, 75, 37, 16, 33, 197, - 249, 37, 16, 33, 197, 248, 37, 16, 33, 197, 247, 37, 16, 232, 209, 197, - 249, 37, 16, 232, 209, 197, 248, 37, 16, 232, 209, 197, 247, 37, 16, 33, - 250, 110, 236, 96, 37, 16, 33, 232, 176, 37, 16, 33, 232, 175, 37, 16, - 33, 232, 174, 37, 16, 33, 232, 173, 37, 16, 33, 232, 172, 37, 16, 248, - 199, 248, 220, 37, 16, 234, 53, 248, 220, 37, 16, 248, 199, 198, 173, 37, - 16, 234, 53, 198, 173, 37, 16, 248, 199, 202, 66, 37, 16, 234, 53, 202, - 66, 37, 16, 248, 199, 209, 183, 37, 16, 234, 53, 209, 183, 37, 16, 33, - 252, 8, 37, 16, 33, 201, 110, 37, 16, 33, 199, 78, 37, 16, 33, 201, 111, - 37, 16, 33, 217, 41, 37, 16, 33, 217, 40, 37, 16, 33, 252, 7, 37, 16, 33, - 218, 221, 37, 16, 250, 191, 196, 73, 37, 16, 250, 191, 235, 79, 37, 16, - 33, 236, 113, 37, 16, 33, 206, 179, 37, 16, 33, 232, 155, 37, 16, 33, - 202, 62, 37, 16, 33, 248, 177, 37, 16, 33, 54, 198, 56, 37, 16, 33, 197, - 221, 198, 56, 37, 16, 206, 185, 37, 16, 200, 236, 37, 16, 191, 166, 37, - 16, 209, 175, 37, 16, 216, 132, 37, 16, 232, 101, 37, 16, 238, 182, 37, - 16, 237, 87, 37, 16, 230, 194, 212, 250, 202, 92, 37, 16, 230, 194, 212, - 250, 213, 31, 202, 92, 37, 16, 198, 23, 37, 16, 197, 54, 37, 16, 223, 65, - 197, 54, 37, 16, 197, 55, 202, 92, 37, 16, 197, 55, 196, 73, 37, 16, 211, - 33, 201, 22, 37, 16, 211, 33, 201, 19, 37, 16, 211, 33, 201, 18, 37, 16, - 211, 33, 201, 17, 37, 16, 211, 33, 201, 16, 37, 16, 211, 33, 201, 15, 37, - 16, 211, 33, 201, 14, 37, 16, 211, 33, 201, 13, 37, 16, 211, 33, 201, 12, - 37, 16, 211, 33, 201, 21, 37, 16, 211, 33, 201, 20, 37, 16, 229, 224, 37, - 16, 214, 99, 37, 16, 234, 53, 80, 201, 64, 37, 16, 237, 80, 202, 92, 37, - 16, 33, 143, 248, 21, 37, 16, 33, 132, 248, 21, 37, 16, 33, 229, 237, 37, - 16, 33, 202, 52, 209, 103, 37, 16, 210, 45, 77, 37, 16, 210, 45, 132, 77, - 37, 16, 134, 210, 45, 77, 37, 16, 230, 233, 196, 73, 37, 16, 230, 233, - 235, 79, 37, 16, 4, 232, 208, 37, 16, 237, 196, 37, 16, 237, 197, 251, - 123, 37, 16, 217, 4, 37, 16, 218, 242, 37, 16, 247, 241, 37, 16, 204, 24, - 193, 87, 37, 16, 204, 24, 248, 91, 37, 16, 216, 22, 37, 16, 216, 23, 248, - 91, 37, 16, 204, 18, 193, 87, 37, 16, 204, 18, 248, 91, 37, 16, 232, 33, - 193, 87, 37, 16, 232, 33, 248, 91, 37, 16, 218, 243, 210, 0, 207, 25, 37, - 16, 218, 243, 223, 139, 207, 25, 37, 16, 247, 242, 207, 25, 37, 16, 204, - 24, 207, 25, 37, 16, 216, 23, 207, 25, 37, 16, 204, 18, 207, 25, 37, 16, - 199, 92, 209, 254, 238, 139, 208, 185, 209, 255, 37, 16, 199, 92, 209, - 254, 238, 139, 208, 185, 223, 138, 37, 16, 199, 92, 209, 254, 238, 139, - 208, 185, 210, 0, 236, 203, 37, 16, 199, 92, 223, 137, 238, 139, 208, - 185, 209, 255, 37, 16, 199, 92, 223, 137, 238, 139, 208, 185, 223, 138, - 37, 16, 199, 92, 223, 137, 238, 139, 208, 185, 223, 139, 236, 203, 37, - 16, 199, 92, 223, 137, 238, 139, 208, 185, 223, 139, 236, 202, 37, 16, - 199, 92, 223, 137, 238, 139, 208, 185, 223, 139, 236, 201, 37, 16, 238, - 173, 37, 16, 230, 165, 247, 146, 242, 187, 37, 16, 230, 165, 233, 135, - 242, 187, 37, 16, 51, 250, 70, 37, 16, 195, 36, 37, 16, 209, 62, 37, 16, - 242, 176, 37, 16, 205, 90, 37, 16, 242, 181, 37, 16, 198, 42, 37, 16, - 209, 21, 37, 16, 209, 22, 232, 158, 37, 16, 205, 91, 232, 158, 37, 16, - 198, 43, 207, 22, 37, 16, 209, 237, 200, 226, 37, 16, 221, 124, 247, 146, - 242, 187, 37, 16, 221, 124, 234, 53, 80, 209, 166, 37, 16, 221, 124, 52, - 212, 249, 37, 16, 221, 124, 207, 94, 77, 37, 16, 221, 124, 193, 85, 212, - 249, 37, 16, 221, 124, 134, 212, 249, 37, 16, 221, 124, 208, 18, 212, - 250, 201, 76, 235, 79, 37, 16, 221, 124, 208, 18, 212, 250, 201, 76, 196, - 73, 37, 16, 221, 124, 234, 117, 212, 250, 201, 76, 235, 79, 37, 16, 221, - 124, 234, 117, 212, 250, 201, 76, 196, 73, 37, 16, 221, 124, 232, 167, - 57, 37, 16, 202, 6, 37, 16, 221, 7, 35, 195, 20, 212, 253, 200, 119, 35, - 195, 20, 212, 253, 200, 108, 35, 195, 20, 212, 253, 200, 98, 35, 195, 20, - 212, 253, 200, 91, 35, 195, 20, 212, 253, 200, 83, 35, 195, 20, 212, 253, - 200, 77, 35, 195, 20, 212, 253, 200, 76, 35, 195, 20, 212, 253, 200, 75, - 35, 195, 20, 212, 253, 200, 74, 35, 195, 20, 212, 253, 200, 118, 35, 195, - 20, 212, 253, 200, 117, 35, 195, 20, 212, 253, 200, 116, 35, 195, 20, - 212, 253, 200, 115, 35, 195, 20, 212, 253, 200, 114, 35, 195, 20, 212, - 253, 200, 113, 35, 195, 20, 212, 253, 200, 112, 35, 195, 20, 212, 253, - 200, 111, 35, 195, 20, 212, 253, 200, 110, 35, 195, 20, 212, 253, 200, - 109, 35, 195, 20, 212, 253, 200, 107, 35, 195, 20, 212, 253, 200, 106, - 35, 195, 20, 212, 253, 200, 105, 35, 195, 20, 212, 253, 200, 104, 35, - 195, 20, 212, 253, 200, 103, 35, 195, 20, 212, 253, 200, 82, 35, 195, 20, - 212, 253, 200, 81, 35, 195, 20, 212, 253, 200, 80, 35, 195, 20, 212, 253, - 200, 79, 35, 195, 20, 212, 253, 200, 78, 35, 223, 88, 212, 253, 200, 119, - 35, 223, 88, 212, 253, 200, 108, 35, 223, 88, 212, 253, 200, 91, 35, 223, - 88, 212, 253, 200, 83, 35, 223, 88, 212, 253, 200, 76, 35, 223, 88, 212, - 253, 200, 75, 35, 223, 88, 212, 253, 200, 117, 35, 223, 88, 212, 253, - 200, 116, 35, 223, 88, 212, 253, 200, 115, 35, 223, 88, 212, 253, 200, - 114, 35, 223, 88, 212, 253, 200, 111, 35, 223, 88, 212, 253, 200, 110, - 35, 223, 88, 212, 253, 200, 109, 35, 223, 88, 212, 253, 200, 104, 35, - 223, 88, 212, 253, 200, 103, 35, 223, 88, 212, 253, 200, 102, 35, 223, - 88, 212, 253, 200, 101, 35, 223, 88, 212, 253, 200, 100, 35, 223, 88, - 212, 253, 200, 99, 35, 223, 88, 212, 253, 200, 97, 35, 223, 88, 212, 253, - 200, 96, 35, 223, 88, 212, 253, 200, 95, 35, 223, 88, 212, 253, 200, 94, - 35, 223, 88, 212, 253, 200, 93, 35, 223, 88, 212, 253, 200, 92, 35, 223, - 88, 212, 253, 200, 90, 35, 223, 88, 212, 253, 200, 89, 35, 223, 88, 212, - 253, 200, 88, 35, 223, 88, 212, 253, 200, 87, 35, 223, 88, 212, 253, 200, - 86, 35, 223, 88, 212, 253, 200, 85, 35, 223, 88, 212, 253, 200, 84, 35, - 223, 88, 212, 253, 200, 82, 35, 223, 88, 212, 253, 200, 81, 35, 223, 88, - 212, 253, 200, 80, 35, 223, 88, 212, 253, 200, 79, 35, 223, 88, 212, 253, - 200, 78, 33, 35, 37, 197, 217, 33, 35, 37, 199, 60, 33, 35, 37, 210, 13, - 35, 37, 219, 182, 217, 1, 212, 121, 191, 77, 217, 1, 212, 121, 108, 217, - 1, 212, 121, 109, 217, 1, 212, 121, 139, 217, 1, 212, 121, 137, 217, 1, - 212, 121, 153, 217, 1, 212, 121, 173, 217, 1, 212, 121, 181, 217, 1, 212, - 121, 176, 217, 1, 212, 121, 184, 217, 1, 212, 121, 199, 90, 217, 1, 212, - 121, 234, 84, 217, 1, 212, 121, 197, 33, 217, 1, 212, 121, 198, 246, 217, - 1, 212, 121, 232, 84, 217, 1, 212, 121, 232, 234, 217, 1, 212, 121, 202, - 125, 217, 1, 212, 121, 203, 239, 217, 1, 212, 121, 234, 118, 217, 1, 212, - 121, 213, 158, 215, 204, 39, 234, 163, 236, 217, 39, 229, 186, 234, 163, - 236, 217, 39, 228, 114, 234, 163, 236, 217, 39, 234, 162, 229, 187, 236, - 217, 39, 234, 162, 228, 113, 236, 217, 39, 234, 163, 199, 62, 39, 246, - 229, 199, 62, 39, 232, 42, 242, 218, 199, 62, 39, 216, 13, 199, 62, 39, - 249, 28, 199, 62, 39, 221, 241, 202, 65, 199, 62, 39, 238, 232, 199, 62, - 39, 250, 162, 199, 62, 39, 211, 51, 199, 62, 39, 247, 253, 211, 4, 199, - 62, 39, 237, 82, 211, 46, 236, 168, 199, 62, 39, 236, 165, 199, 62, 39, - 191, 237, 199, 62, 39, 223, 125, 199, 62, 39, 210, 23, 199, 62, 39, 207, - 103, 199, 62, 39, 238, 244, 199, 62, 39, 228, 230, 249, 96, 199, 62, 39, - 193, 168, 199, 62, 39, 232, 130, 199, 62, 39, 251, 232, 199, 62, 39, 207, - 57, 199, 62, 39, 207, 29, 199, 62, 39, 234, 161, 199, 62, 39, 222, 158, - 199, 62, 39, 238, 239, 199, 62, 39, 234, 51, 199, 62, 39, 235, 15, 199, - 62, 39, 246, 196, 199, 62, 39, 237, 92, 199, 62, 39, 28, 207, 28, 199, - 62, 39, 210, 201, 199, 62, 39, 219, 186, 199, 62, 39, 242, 169, 199, 62, - 39, 221, 112, 199, 62, 39, 231, 152, 199, 62, 39, 201, 34, 199, 62, 39, - 208, 133, 199, 62, 39, 232, 41, 199, 62, 39, 207, 30, 199, 62, 39, 219, - 227, 211, 46, 215, 241, 199, 62, 39, 207, 26, 199, 62, 39, 230, 216, 118, - 216, 187, 199, 62, 39, 234, 54, 199, 62, 39, 201, 51, 199, 62, 39, 230, - 168, 199, 62, 39, 234, 44, 199, 62, 39, 210, 73, 199, 62, 39, 206, 172, - 199, 62, 39, 232, 156, 199, 62, 39, 195, 160, 211, 46, 193, 145, 199, 62, - 39, 238, 249, 199, 62, 39, 216, 208, 199, 62, 39, 233, 208, 199, 62, 39, - 196, 84, 199, 62, 39, 236, 204, 199, 62, 39, 242, 171, 215, 163, 199, 62, - 39, 230, 138, 199, 62, 39, 231, 153, 223, 134, 199, 62, 39, 217, 13, 199, - 62, 39, 252, 2, 199, 62, 39, 234, 70, 199, 62, 39, 235, 83, 199, 62, 39, - 193, 143, 199, 62, 39, 202, 160, 199, 62, 39, 223, 98, 199, 62, 39, 237, - 48, 199, 62, 39, 237, 174, 199, 62, 39, 236, 200, 199, 62, 39, 233, 172, - 199, 62, 39, 203, 235, 199, 62, 39, 201, 55, 199, 62, 39, 229, 239, 199, - 62, 39, 242, 18, 199, 62, 39, 242, 166, 199, 62, 39, 233, 47, 199, 62, - 39, 251, 196, 199, 62, 39, 242, 17, 199, 62, 39, 211, 94, 199, 29, 195, - 135, 199, 62, 39, 236, 226, 199, 62, 39, 220, 89, 199, 62, 39, 232, 93, - 238, 197, 206, 140, 196, 87, 17, 108, 238, 197, 206, 140, 196, 87, 17, - 109, 238, 197, 206, 140, 196, 87, 17, 139, 238, 197, 206, 140, 196, 87, - 17, 137, 238, 197, 206, 140, 196, 87, 17, 153, 238, 197, 206, 140, 196, - 87, 17, 173, 238, 197, 206, 140, 196, 87, 17, 181, 238, 197, 206, 140, - 196, 87, 17, 176, 238, 197, 206, 140, 196, 87, 17, 184, 238, 197, 206, - 140, 199, 86, 17, 108, 238, 197, 206, 140, 199, 86, 17, 109, 238, 197, - 206, 140, 199, 86, 17, 139, 238, 197, 206, 140, 199, 86, 17, 137, 238, - 197, 206, 140, 199, 86, 17, 153, 238, 197, 206, 140, 199, 86, 17, 173, - 238, 197, 206, 140, 199, 86, 17, 181, 238, 197, 206, 140, 199, 86, 17, - 176, 238, 197, 206, 140, 199, 86, 17, 184, 154, 199, 193, 87, 108, 154, - 199, 193, 87, 109, 154, 199, 193, 87, 139, 154, 199, 193, 87, 137, 154, - 199, 193, 87, 153, 199, 193, 87, 108, 199, 193, 87, 153, 13, 28, 6, 65, - 13, 28, 6, 250, 70, 13, 28, 6, 247, 145, 13, 28, 6, 238, 80, 13, 28, 6, - 73, 13, 28, 6, 233, 134, 13, 28, 6, 232, 14, 13, 28, 6, 230, 83, 13, 28, - 6, 70, 13, 28, 6, 223, 7, 13, 28, 6, 222, 125, 13, 28, 6, 170, 13, 28, 6, - 218, 147, 13, 28, 6, 215, 47, 13, 28, 6, 74, 13, 28, 6, 210, 226, 13, 28, - 6, 208, 97, 13, 28, 6, 148, 13, 28, 6, 206, 3, 13, 28, 6, 200, 39, 13, - 28, 6, 69, 13, 28, 6, 196, 8, 13, 28, 6, 193, 221, 13, 28, 6, 192, 235, - 13, 28, 6, 192, 159, 13, 28, 6, 191, 166, 13, 28, 2, 65, 13, 28, 2, 250, - 70, 13, 28, 2, 247, 145, 13, 28, 2, 238, 80, 13, 28, 2, 73, 13, 28, 2, - 233, 134, 13, 28, 2, 232, 14, 13, 28, 2, 230, 83, 13, 28, 2, 70, 13, 28, - 2, 223, 7, 13, 28, 2, 222, 125, 13, 28, 2, 170, 13, 28, 2, 218, 147, 13, - 28, 2, 215, 47, 13, 28, 2, 74, 13, 28, 2, 210, 226, 13, 28, 2, 208, 97, - 13, 28, 2, 148, 13, 28, 2, 206, 3, 13, 28, 2, 200, 39, 13, 28, 2, 69, 13, - 28, 2, 196, 8, 13, 28, 2, 193, 221, 13, 28, 2, 192, 235, 13, 28, 2, 192, - 159, 13, 28, 2, 191, 166, 13, 43, 6, 65, 13, 43, 6, 250, 70, 13, 43, 6, - 247, 145, 13, 43, 6, 238, 80, 13, 43, 6, 73, 13, 43, 6, 233, 134, 13, 43, - 6, 232, 14, 13, 43, 6, 230, 83, 13, 43, 6, 70, 13, 43, 6, 223, 7, 13, 43, - 6, 222, 125, 13, 43, 6, 170, 13, 43, 6, 218, 147, 13, 43, 6, 215, 47, 13, - 43, 6, 74, 13, 43, 6, 210, 226, 13, 43, 6, 208, 97, 13, 43, 6, 148, 13, - 43, 6, 206, 3, 13, 43, 6, 200, 39, 13, 43, 6, 69, 13, 43, 6, 196, 8, 13, - 43, 6, 193, 221, 13, 43, 6, 192, 235, 13, 43, 6, 192, 159, 13, 43, 6, - 191, 166, 13, 43, 2, 65, 13, 43, 2, 250, 70, 13, 43, 2, 247, 145, 13, 43, - 2, 238, 80, 13, 43, 2, 73, 13, 43, 2, 233, 134, 13, 43, 2, 232, 14, 13, - 43, 2, 70, 13, 43, 2, 223, 7, 13, 43, 2, 222, 125, 13, 43, 2, 170, 13, - 43, 2, 218, 147, 13, 43, 2, 215, 47, 13, 43, 2, 74, 13, 43, 2, 210, 226, - 13, 43, 2, 208, 97, 13, 43, 2, 148, 13, 43, 2, 206, 3, 13, 43, 2, 200, - 39, 13, 43, 2, 69, 13, 43, 2, 196, 8, 13, 43, 2, 193, 221, 13, 43, 2, - 192, 235, 13, 43, 2, 192, 159, 13, 43, 2, 191, 166, 13, 28, 43, 6, 65, - 13, 28, 43, 6, 250, 70, 13, 28, 43, 6, 247, 145, 13, 28, 43, 6, 238, 80, - 13, 28, 43, 6, 73, 13, 28, 43, 6, 233, 134, 13, 28, 43, 6, 232, 14, 13, - 28, 43, 6, 230, 83, 13, 28, 43, 6, 70, 13, 28, 43, 6, 223, 7, 13, 28, 43, - 6, 222, 125, 13, 28, 43, 6, 170, 13, 28, 43, 6, 218, 147, 13, 28, 43, 6, - 215, 47, 13, 28, 43, 6, 74, 13, 28, 43, 6, 210, 226, 13, 28, 43, 6, 208, - 97, 13, 28, 43, 6, 148, 13, 28, 43, 6, 206, 3, 13, 28, 43, 6, 200, 39, - 13, 28, 43, 6, 69, 13, 28, 43, 6, 196, 8, 13, 28, 43, 6, 193, 221, 13, + 64, 41, 2, 27, 246, 238, 41, 2, 27, 246, 237, 41, 2, 27, 246, 236, 41, 2, + 27, 246, 235, 41, 2, 27, 246, 234, 41, 2, 27, 246, 233, 41, 2, 27, 246, + 232, 41, 2, 27, 246, 231, 41, 2, 27, 246, 230, 41, 2, 27, 246, 229, 41, + 2, 27, 246, 228, 41, 2, 27, 246, 227, 41, 2, 27, 246, 226, 41, 2, 27, + 246, 225, 41, 2, 27, 246, 224, 41, 2, 27, 246, 223, 41, 2, 27, 246, 222, + 41, 2, 27, 246, 221, 41, 2, 27, 246, 220, 41, 2, 27, 246, 219, 41, 2, 27, + 246, 218, 41, 2, 27, 246, 217, 41, 2, 27, 246, 216, 41, 2, 27, 246, 215, + 41, 2, 27, 246, 214, 41, 2, 27, 246, 213, 41, 2, 27, 246, 212, 41, 2, 27, + 246, 211, 41, 2, 27, 246, 210, 41, 2, 27, 246, 209, 41, 2, 27, 246, 208, + 41, 2, 27, 246, 207, 41, 2, 27, 246, 206, 41, 2, 27, 246, 205, 41, 2, 27, + 246, 204, 41, 2, 27, 246, 203, 41, 2, 27, 246, 202, 41, 2, 27, 246, 201, + 41, 2, 27, 246, 200, 41, 2, 27, 246, 199, 41, 2, 27, 246, 198, 41, 2, 27, + 246, 197, 41, 2, 27, 246, 196, 41, 2, 27, 246, 195, 41, 2, 27, 246, 194, + 41, 2, 27, 246, 193, 41, 2, 27, 246, 192, 41, 2, 27, 246, 191, 41, 2, 27, + 246, 190, 41, 2, 27, 246, 189, 41, 2, 27, 246, 188, 41, 2, 27, 246, 187, + 41, 2, 27, 246, 186, 41, 2, 27, 246, 185, 41, 2, 27, 246, 184, 41, 2, 27, + 246, 183, 41, 2, 27, 246, 182, 41, 2, 27, 246, 181, 41, 2, 27, 246, 180, + 41, 2, 27, 246, 179, 41, 2, 27, 246, 178, 41, 2, 27, 246, 177, 41, 2, 27, + 246, 176, 41, 2, 27, 246, 175, 41, 2, 27, 246, 174, 41, 2, 27, 246, 173, + 41, 2, 27, 246, 172, 41, 2, 27, 246, 171, 41, 2, 27, 246, 170, 41, 2, 27, + 246, 169, 41, 2, 27, 246, 168, 41, 2, 27, 246, 167, 41, 2, 27, 246, 166, + 41, 2, 27, 246, 165, 41, 2, 27, 246, 164, 41, 2, 27, 246, 163, 41, 2, 27, + 246, 162, 41, 2, 27, 246, 161, 41, 2, 27, 246, 160, 41, 2, 27, 246, 159, + 41, 2, 27, 246, 158, 41, 2, 27, 246, 157, 41, 2, 27, 246, 156, 41, 2, 27, + 246, 155, 41, 2, 27, 246, 154, 41, 2, 27, 246, 153, 41, 2, 27, 246, 152, + 41, 2, 27, 246, 151, 41, 2, 27, 246, 150, 41, 2, 27, 246, 149, 41, 2, 27, + 246, 148, 41, 2, 27, 246, 147, 41, 2, 27, 246, 146, 41, 2, 27, 246, 145, + 41, 2, 27, 246, 144, 41, 2, 27, 246, 143, 41, 2, 27, 246, 142, 41, 2, 27, + 246, 141, 41, 2, 27, 246, 140, 41, 2, 27, 246, 139, 41, 2, 27, 246, 138, + 41, 2, 27, 246, 137, 41, 2, 27, 246, 136, 41, 2, 27, 246, 135, 41, 2, 27, + 246, 134, 41, 2, 27, 246, 133, 41, 2, 27, 246, 132, 41, 2, 27, 246, 131, + 41, 2, 27, 246, 130, 41, 2, 27, 246, 129, 41, 2, 27, 246, 128, 41, 2, 27, + 246, 127, 41, 2, 27, 246, 126, 41, 2, 27, 246, 125, 41, 2, 27, 246, 124, + 41, 2, 27, 246, 123, 41, 2, 27, 246, 122, 41, 2, 27, 246, 121, 41, 2, 27, + 246, 120, 41, 2, 27, 246, 119, 41, 2, 27, 246, 118, 41, 2, 27, 246, 117, + 41, 2, 27, 246, 116, 41, 2, 27, 246, 115, 41, 2, 27, 246, 114, 41, 2, 27, + 246, 113, 41, 2, 27, 246, 112, 41, 2, 27, 246, 111, 41, 2, 27, 246, 110, + 41, 2, 27, 246, 109, 41, 2, 27, 246, 108, 41, 2, 27, 246, 107, 41, 2, 27, + 246, 106, 41, 2, 27, 246, 105, 41, 2, 27, 246, 104, 41, 2, 27, 246, 103, + 41, 2, 27, 246, 102, 41, 2, 27, 246, 101, 41, 2, 27, 246, 100, 41, 2, 27, + 246, 99, 41, 2, 27, 246, 98, 41, 2, 27, 246, 97, 41, 2, 27, 246, 96, 41, + 2, 27, 246, 95, 41, 2, 27, 246, 94, 41, 2, 27, 246, 93, 41, 2, 27, 246, + 92, 41, 2, 27, 246, 91, 41, 2, 27, 246, 90, 41, 2, 27, 246, 89, 41, 2, + 27, 246, 88, 41, 2, 27, 246, 87, 41, 2, 27, 246, 86, 41, 2, 27, 246, 85, + 41, 2, 27, 246, 84, 41, 2, 27, 246, 83, 41, 2, 27, 246, 82, 41, 2, 27, + 246, 81, 41, 2, 27, 246, 80, 41, 2, 27, 246, 79, 41, 2, 27, 246, 78, 41, + 2, 27, 246, 77, 41, 2, 27, 246, 76, 41, 2, 27, 246, 75, 41, 2, 27, 246, + 74, 41, 2, 27, 246, 73, 41, 2, 27, 246, 72, 41, 2, 27, 246, 71, 41, 2, + 27, 246, 70, 41, 2, 27, 246, 69, 41, 2, 27, 246, 68, 41, 2, 27, 246, 67, + 41, 2, 27, 246, 66, 41, 2, 27, 246, 65, 41, 2, 27, 246, 64, 41, 2, 27, + 246, 63, 41, 2, 27, 246, 62, 41, 2, 27, 246, 61, 41, 2, 27, 246, 60, 41, + 2, 27, 246, 59, 41, 2, 27, 246, 58, 41, 2, 27, 246, 57, 41, 2, 27, 246, + 56, 41, 2, 27, 246, 55, 41, 2, 27, 246, 54, 41, 2, 27, 246, 53, 41, 2, + 27, 246, 52, 41, 2, 27, 246, 51, 41, 2, 27, 246, 50, 41, 2, 27, 246, 49, + 41, 2, 27, 246, 48, 41, 2, 27, 246, 47, 41, 2, 27, 246, 46, 41, 2, 27, + 246, 45, 41, 2, 27, 246, 44, 41, 2, 27, 246, 43, 41, 2, 27, 246, 42, 41, + 2, 27, 246, 41, 41, 2, 27, 246, 40, 41, 2, 27, 246, 39, 41, 2, 27, 246, + 38, 41, 2, 27, 246, 37, 41, 2, 27, 246, 36, 41, 2, 27, 246, 35, 41, 2, + 27, 246, 34, 41, 2, 27, 246, 33, 41, 2, 27, 246, 32, 41, 2, 27, 246, 31, + 41, 2, 27, 246, 30, 41, 2, 27, 246, 29, 41, 2, 27, 246, 28, 41, 2, 27, + 246, 27, 41, 2, 27, 246, 26, 41, 2, 27, 246, 25, 41, 2, 27, 246, 24, 41, + 2, 27, 246, 23, 41, 2, 27, 246, 22, 41, 2, 27, 246, 21, 41, 2, 27, 246, + 20, 41, 2, 27, 246, 19, 41, 2, 27, 246, 18, 41, 2, 27, 246, 17, 41, 2, + 27, 246, 16, 41, 2, 27, 246, 15, 41, 2, 27, 246, 14, 41, 2, 27, 246, 13, + 41, 2, 27, 246, 12, 41, 2, 27, 246, 11, 41, 2, 27, 246, 10, 41, 2, 27, + 246, 9, 41, 2, 27, 246, 8, 41, 2, 27, 246, 7, 41, 2, 27, 246, 6, 41, 2, + 27, 246, 5, 41, 2, 27, 246, 4, 41, 2, 27, 246, 3, 41, 2, 27, 246, 2, 41, + 2, 27, 246, 1, 41, 2, 27, 246, 0, 41, 2, 27, 245, 255, 41, 2, 27, 245, + 254, 41, 2, 27, 245, 253, 41, 2, 27, 245, 252, 41, 2, 27, 245, 251, 41, + 2, 27, 245, 250, 41, 2, 27, 245, 249, 41, 2, 27, 245, 248, 41, 2, 27, + 245, 247, 41, 2, 27, 245, 246, 41, 2, 27, 245, 245, 41, 2, 27, 245, 244, + 41, 2, 27, 245, 243, 41, 2, 27, 245, 242, 41, 2, 27, 245, 241, 41, 2, 27, + 245, 240, 41, 2, 27, 245, 239, 41, 2, 27, 245, 238, 41, 2, 27, 245, 237, + 41, 2, 27, 245, 236, 41, 2, 27, 245, 235, 41, 2, 27, 245, 234, 41, 2, 27, + 245, 233, 41, 2, 27, 245, 232, 41, 2, 27, 245, 231, 41, 2, 27, 245, 230, + 41, 2, 27, 245, 229, 41, 2, 27, 245, 228, 41, 2, 27, 245, 227, 41, 2, 27, + 245, 226, 41, 2, 27, 245, 225, 41, 2, 27, 245, 224, 41, 2, 27, 245, 223, + 41, 2, 27, 245, 222, 41, 2, 27, 245, 221, 41, 2, 27, 245, 220, 41, 2, 27, + 245, 219, 41, 2, 27, 245, 218, 41, 2, 27, 245, 217, 41, 2, 27, 245, 216, + 41, 2, 27, 245, 215, 41, 2, 27, 245, 214, 41, 2, 27, 245, 213, 41, 2, 27, + 245, 212, 41, 2, 27, 245, 211, 41, 2, 27, 245, 210, 41, 2, 27, 245, 209, + 41, 2, 27, 245, 208, 41, 2, 27, 245, 207, 41, 2, 27, 245, 206, 41, 2, 27, + 245, 205, 41, 2, 27, 245, 204, 41, 2, 27, 245, 203, 41, 2, 27, 245, 202, + 41, 2, 27, 245, 201, 41, 2, 27, 245, 200, 41, 2, 27, 245, 199, 41, 2, 27, + 245, 198, 41, 2, 27, 245, 197, 41, 2, 27, 245, 196, 41, 2, 27, 245, 195, + 41, 2, 27, 245, 194, 41, 2, 27, 245, 193, 41, 2, 27, 245, 192, 41, 2, 27, + 245, 191, 41, 2, 27, 245, 190, 41, 2, 27, 245, 189, 41, 2, 27, 245, 188, + 41, 2, 27, 245, 187, 41, 2, 27, 245, 186, 41, 2, 27, 245, 185, 41, 2, 27, + 245, 184, 41, 2, 27, 245, 183, 41, 2, 27, 245, 182, 41, 2, 27, 245, 181, + 41, 2, 27, 245, 180, 41, 2, 27, 245, 179, 41, 2, 27, 245, 178, 41, 2, 27, + 245, 177, 41, 2, 27, 245, 176, 41, 2, 27, 245, 175, 41, 2, 27, 245, 174, + 41, 2, 27, 245, 173, 41, 2, 27, 245, 172, 41, 2, 27, 245, 171, 41, 2, 27, + 245, 170, 41, 2, 27, 245, 169, 41, 2, 27, 245, 168, 41, 2, 27, 245, 167, + 41, 2, 27, 245, 166, 41, 2, 27, 245, 165, 41, 2, 27, 245, 164, 41, 2, 27, + 245, 163, 41, 2, 27, 245, 162, 41, 2, 27, 245, 161, 41, 2, 27, 245, 160, + 41, 2, 27, 245, 159, 41, 2, 27, 245, 158, 41, 2, 27, 245, 157, 41, 2, 27, + 245, 156, 41, 2, 27, 245, 155, 41, 2, 27, 245, 154, 41, 2, 27, 245, 153, + 41, 2, 27, 245, 152, 41, 2, 27, 245, 151, 41, 2, 27, 245, 150, 41, 2, 27, + 245, 149, 41, 2, 27, 245, 148, 41, 2, 27, 245, 147, 41, 2, 27, 245, 146, + 41, 2, 27, 245, 145, 41, 2, 27, 245, 144, 41, 2, 27, 245, 143, 41, 2, 27, + 245, 142, 41, 2, 27, 245, 141, 41, 2, 27, 245, 140, 41, 2, 27, 245, 139, + 41, 2, 27, 245, 138, 41, 2, 27, 245, 137, 41, 2, 27, 245, 136, 41, 2, 27, + 245, 135, 41, 2, 27, 245, 134, 41, 2, 27, 245, 133, 41, 2, 27, 245, 132, + 41, 2, 27, 245, 131, 41, 2, 27, 245, 130, 41, 2, 27, 245, 129, 41, 2, 27, + 245, 128, 41, 2, 27, 245, 127, 41, 2, 27, 245, 126, 41, 2, 27, 245, 125, + 41, 2, 27, 245, 124, 41, 2, 27, 245, 123, 41, 2, 27, 245, 122, 41, 2, 27, + 245, 121, 41, 2, 27, 245, 120, 41, 2, 27, 245, 119, 41, 2, 27, 245, 118, + 41, 2, 27, 245, 117, 41, 2, 27, 245, 116, 41, 2, 27, 245, 115, 41, 2, 27, + 245, 114, 41, 2, 27, 245, 113, 41, 2, 27, 245, 112, 41, 2, 27, 245, 111, + 41, 2, 27, 245, 110, 41, 2, 27, 245, 109, 41, 2, 27, 245, 108, 41, 2, 27, + 245, 107, 41, 2, 27, 245, 106, 41, 2, 27, 245, 105, 41, 2, 27, 245, 104, + 41, 2, 27, 245, 103, 41, 2, 27, 245, 102, 41, 2, 27, 245, 101, 41, 2, 27, + 245, 100, 41, 2, 27, 245, 99, 41, 2, 27, 245, 98, 41, 2, 27, 245, 97, 41, + 2, 27, 245, 96, 41, 2, 27, 245, 95, 41, 2, 27, 245, 94, 41, 2, 27, 245, + 93, 41, 2, 27, 245, 92, 41, 2, 27, 245, 91, 41, 2, 27, 245, 90, 41, 2, + 27, 245, 89, 41, 2, 27, 245, 88, 41, 2, 27, 245, 87, 41, 2, 27, 245, 86, + 41, 2, 27, 245, 85, 41, 2, 27, 245, 84, 41, 2, 27, 245, 83, 41, 2, 27, + 245, 82, 41, 2, 27, 245, 81, 41, 2, 27, 245, 80, 41, 2, 27, 245, 79, 41, + 2, 27, 245, 78, 41, 2, 27, 245, 77, 41, 2, 27, 245, 76, 41, 2, 27, 245, + 75, 41, 2, 27, 245, 74, 41, 2, 27, 245, 73, 41, 2, 27, 245, 72, 41, 2, + 27, 245, 71, 41, 2, 27, 245, 70, 41, 2, 27, 245, 69, 41, 2, 27, 245, 68, + 41, 2, 27, 245, 67, 41, 2, 27, 245, 66, 41, 2, 27, 245, 65, 41, 2, 27, + 245, 64, 41, 2, 27, 245, 63, 41, 2, 27, 245, 62, 41, 2, 27, 245, 61, 41, + 2, 27, 245, 60, 41, 2, 27, 245, 59, 41, 2, 27, 245, 58, 41, 2, 27, 245, + 57, 41, 2, 27, 245, 56, 41, 2, 27, 245, 55, 41, 2, 27, 245, 54, 41, 2, + 27, 245, 53, 41, 2, 27, 245, 52, 41, 2, 27, 245, 51, 41, 2, 27, 245, 50, + 41, 2, 27, 245, 49, 41, 2, 27, 245, 48, 41, 2, 27, 245, 47, 41, 2, 27, + 245, 46, 41, 2, 27, 245, 45, 41, 2, 27, 245, 44, 41, 2, 27, 245, 43, 41, + 2, 27, 245, 42, 41, 2, 27, 245, 41, 41, 2, 27, 245, 40, 41, 2, 27, 245, + 39, 41, 2, 27, 245, 38, 41, 2, 27, 245, 37, 41, 2, 27, 245, 36, 41, 2, + 27, 245, 35, 41, 2, 27, 245, 34, 41, 2, 27, 245, 33, 41, 2, 27, 245, 32, + 41, 2, 27, 245, 31, 41, 2, 27, 245, 30, 41, 2, 27, 245, 29, 41, 2, 27, + 245, 28, 41, 2, 27, 245, 27, 41, 2, 27, 245, 26, 41, 2, 27, 245, 25, 72, + 1, 216, 36, 198, 77, 72, 1, 216, 36, 198, 76, 72, 1, 216, 36, 198, 75, + 72, 1, 216, 36, 198, 74, 72, 1, 216, 36, 198, 72, 72, 1, 216, 36, 198, + 71, 72, 1, 216, 36, 214, 211, 198, 78, 72, 1, 216, 36, 214, 211, 198, 77, + 72, 1, 216, 36, 214, 211, 198, 76, 72, 1, 216, 36, 214, 211, 198, 75, 72, + 1, 216, 36, 214, 211, 198, 74, 72, 1, 216, 36, 214, 211, 198, 72, 72, 1, + 216, 36, 214, 211, 198, 71, 72, 1, 251, 14, 71, 229, 120, 1, 251, 14, + 192, 80, 61, 1, 255, 206, 61, 1, 255, 205, 61, 1, 255, 204, 61, 1, 255, + 200, 61, 1, 228, 73, 61, 1, 228, 72, 61, 1, 228, 71, 61, 1, 228, 70, 61, + 1, 196, 231, 61, 1, 196, 230, 61, 1, 196, 229, 61, 1, 196, 228, 61, 1, + 196, 227, 61, 1, 235, 13, 61, 1, 235, 12, 61, 1, 235, 11, 61, 1, 235, 10, + 61, 1, 235, 9, 61, 1, 212, 14, 61, 1, 212, 13, 61, 1, 212, 12, 61, 1, + 222, 141, 61, 1, 222, 138, 61, 1, 222, 137, 61, 1, 222, 136, 61, 1, 222, + 135, 61, 1, 222, 134, 61, 1, 222, 133, 61, 1, 222, 132, 61, 1, 222, 131, + 61, 1, 222, 140, 61, 1, 222, 139, 61, 1, 222, 130, 61, 1, 221, 165, 61, + 1, 221, 164, 61, 1, 221, 163, 61, 1, 221, 162, 61, 1, 221, 161, 61, 1, + 221, 160, 61, 1, 221, 159, 61, 1, 221, 158, 61, 1, 220, 231, 61, 1, 220, + 230, 61, 1, 220, 229, 61, 1, 220, 228, 61, 1, 220, 227, 61, 1, 220, 226, + 61, 1, 220, 225, 61, 1, 222, 21, 61, 1, 222, 20, 61, 1, 222, 19, 61, 1, + 222, 18, 61, 1, 222, 17, 61, 1, 222, 16, 61, 1, 221, 66, 61, 1, 221, 65, + 61, 1, 221, 64, 61, 1, 221, 63, 61, 1, 205, 206, 61, 1, 205, 205, 61, 1, + 205, 204, 61, 1, 205, 203, 61, 1, 205, 202, 61, 1, 205, 201, 61, 1, 205, + 200, 61, 1, 205, 199, 61, 1, 202, 221, 61, 1, 202, 220, 61, 1, 202, 219, + 61, 1, 202, 218, 61, 1, 202, 217, 61, 1, 202, 216, 61, 1, 201, 3, 61, 1, + 201, 2, 61, 1, 201, 1, 61, 1, 201, 0, 61, 1, 200, 255, 61, 1, 200, 254, + 61, 1, 200, 253, 61, 1, 200, 252, 61, 1, 205, 67, 61, 1, 205, 66, 61, 1, + 205, 65, 61, 1, 205, 64, 61, 1, 205, 63, 61, 1, 202, 45, 61, 1, 202, 44, + 61, 1, 202, 43, 61, 1, 202, 42, 61, 1, 202, 41, 61, 1, 202, 40, 61, 1, + 202, 39, 61, 1, 199, 251, 61, 1, 199, 250, 61, 1, 199, 249, 61, 1, 199, + 248, 61, 1, 198, 192, 61, 1, 198, 191, 61, 1, 198, 190, 61, 1, 198, 189, + 61, 1, 198, 188, 61, 1, 198, 187, 61, 1, 198, 186, 61, 1, 197, 93, 61, 1, + 197, 92, 61, 1, 197, 91, 61, 1, 197, 90, 61, 1, 197, 89, 61, 1, 199, 144, + 61, 1, 199, 143, 61, 1, 199, 142, 61, 1, 199, 141, 61, 1, 199, 140, 61, + 1, 199, 139, 61, 1, 199, 138, 61, 1, 199, 137, 61, 1, 199, 136, 61, 1, + 198, 98, 61, 1, 198, 97, 61, 1, 198, 96, 61, 1, 198, 95, 61, 1, 198, 94, + 61, 1, 198, 93, 61, 1, 198, 92, 61, 1, 215, 6, 61, 1, 215, 5, 61, 1, 215, + 4, 61, 1, 215, 3, 61, 1, 215, 2, 61, 1, 215, 1, 61, 1, 215, 0, 61, 1, + 214, 255, 61, 1, 214, 254, 61, 1, 213, 218, 61, 1, 213, 217, 61, 1, 213, + 216, 61, 1, 213, 215, 61, 1, 213, 214, 61, 1, 213, 213, 61, 1, 213, 212, + 61, 1, 213, 211, 61, 1, 212, 177, 61, 1, 212, 176, 61, 1, 212, 175, 61, + 1, 214, 120, 61, 1, 214, 119, 61, 1, 214, 118, 61, 1, 214, 117, 61, 1, + 214, 116, 61, 1, 214, 115, 61, 1, 214, 114, 61, 1, 213, 42, 61, 1, 213, + 41, 61, 1, 213, 40, 61, 1, 213, 39, 61, 1, 213, 38, 61, 1, 230, 104, 61, + 1, 230, 101, 61, 1, 230, 100, 61, 1, 230, 99, 61, 1, 230, 98, 61, 1, 230, + 97, 61, 1, 230, 96, 61, 1, 230, 95, 61, 1, 230, 94, 61, 1, 230, 103, 61, + 1, 230, 102, 61, 1, 229, 157, 61, 1, 229, 156, 61, 1, 229, 155, 61, 1, + 229, 154, 61, 1, 229, 153, 61, 1, 229, 152, 61, 1, 229, 151, 61, 1, 228, + 158, 61, 1, 228, 157, 61, 1, 228, 156, 61, 1, 229, 244, 61, 1, 229, 243, + 61, 1, 229, 242, 61, 1, 229, 241, 61, 1, 229, 240, 61, 1, 229, 239, 61, + 1, 229, 238, 61, 1, 229, 22, 61, 1, 229, 21, 61, 1, 229, 20, 61, 1, 229, + 19, 61, 1, 229, 18, 61, 1, 229, 17, 61, 1, 229, 16, 61, 1, 229, 15, 61, + 1, 217, 159, 61, 1, 217, 158, 61, 1, 217, 157, 61, 1, 217, 156, 61, 1, + 217, 155, 61, 1, 217, 154, 61, 1, 217, 153, 61, 1, 216, 99, 61, 1, 216, + 98, 61, 1, 216, 97, 61, 1, 216, 96, 61, 1, 216, 95, 61, 1, 216, 94, 61, + 1, 216, 93, 61, 1, 215, 154, 61, 1, 215, 153, 61, 1, 215, 152, 61, 1, + 215, 151, 61, 1, 216, 231, 61, 1, 216, 230, 61, 1, 216, 229, 61, 1, 216, + 11, 61, 1, 216, 10, 61, 1, 216, 9, 61, 1, 216, 8, 61, 1, 216, 7, 61, 1, + 216, 6, 61, 1, 192, 148, 61, 1, 192, 147, 61, 1, 192, 146, 61, 1, 192, + 145, 61, 1, 192, 144, 61, 1, 192, 141, 61, 1, 191, 224, 61, 1, 191, 223, + 61, 1, 191, 222, 61, 1, 191, 221, 61, 1, 192, 11, 61, 1, 192, 10, 61, 1, + 192, 9, 61, 1, 192, 8, 61, 1, 192, 7, 61, 1, 192, 6, 61, 1, 207, 185, 61, + 1, 207, 184, 61, 1, 207, 183, 61, 1, 207, 182, 61, 1, 207, 0, 61, 1, 206, + 255, 61, 1, 206, 254, 61, 1, 206, 253, 61, 1, 206, 252, 61, 1, 206, 251, + 61, 1, 206, 250, 61, 1, 206, 67, 61, 1, 206, 66, 61, 1, 206, 65, 61, 1, + 206, 64, 61, 1, 206, 63, 61, 1, 206, 62, 61, 1, 207, 112, 61, 1, 207, + 111, 61, 1, 207, 110, 61, 1, 207, 109, 61, 1, 206, 161, 61, 1, 206, 160, + 61, 1, 206, 159, 61, 1, 206, 158, 61, 1, 206, 157, 61, 1, 206, 156, 61, + 1, 193, 189, 61, 1, 193, 188, 61, 1, 193, 187, 61, 1, 193, 186, 61, 1, + 193, 185, 61, 1, 193, 85, 61, 1, 193, 84, 61, 1, 193, 83, 61, 1, 193, 82, + 61, 1, 193, 81, 61, 1, 193, 124, 61, 1, 193, 123, 61, 1, 193, 122, 61, 1, + 193, 121, 61, 1, 193, 47, 61, 1, 193, 46, 61, 1, 193, 45, 61, 1, 193, 44, + 61, 1, 193, 43, 61, 1, 193, 42, 61, 1, 193, 41, 61, 1, 215, 58, 61, 1, + 215, 57, 229, 120, 1, 251, 14, 193, 0, 72, 1, 251, 14, 192, 33, 72, 1, + 251, 14, 192, 80, 72, 1, 251, 14, 193, 0, 229, 120, 1, 2, 221, 67, 229, + 120, 1, 2, 193, 86, 229, 120, 1, 2, 193, 125, 229, 120, 1, 2, 193, 48, + 72, 1, 2, 221, 67, 72, 1, 2, 193, 86, 72, 1, 2, 193, 125, 72, 1, 2, 193, + 48, 72, 1, 2, 215, 61, 46, 245, 24, 46, 245, 23, 46, 245, 22, 46, 245, + 21, 46, 245, 20, 46, 245, 19, 46, 245, 18, 46, 245, 17, 46, 245, 16, 46, + 245, 15, 46, 245, 14, 46, 245, 13, 46, 245, 12, 46, 245, 11, 46, 245, 10, + 46, 245, 9, 46, 245, 8, 46, 245, 7, 46, 245, 6, 46, 245, 5, 46, 245, 4, + 46, 245, 3, 46, 245, 2, 46, 245, 1, 46, 245, 0, 46, 244, 255, 46, 244, + 254, 46, 244, 253, 46, 244, 252, 46, 244, 251, 46, 244, 250, 46, 244, + 249, 46, 244, 248, 46, 244, 247, 46, 244, 246, 46, 244, 245, 46, 244, + 244, 46, 244, 243, 46, 244, 242, 46, 244, 241, 46, 244, 240, 46, 244, + 239, 46, 244, 238, 46, 244, 237, 46, 244, 236, 46, 244, 235, 46, 244, + 234, 46, 244, 233, 46, 244, 232, 46, 244, 231, 46, 244, 230, 46, 244, + 229, 46, 244, 228, 46, 244, 227, 46, 244, 226, 46, 244, 225, 46, 244, + 224, 46, 244, 223, 46, 244, 222, 46, 244, 221, 46, 244, 220, 46, 244, + 219, 46, 244, 218, 46, 244, 217, 46, 244, 216, 46, 244, 215, 46, 244, + 214, 46, 244, 213, 46, 244, 212, 46, 244, 211, 46, 244, 210, 46, 244, + 209, 46, 244, 208, 46, 244, 207, 46, 244, 206, 46, 244, 205, 46, 244, + 204, 46, 244, 203, 46, 244, 202, 46, 244, 201, 46, 244, 200, 46, 244, + 199, 46, 244, 198, 46, 244, 197, 46, 244, 196, 46, 244, 195, 46, 244, + 194, 46, 244, 193, 46, 244, 192, 46, 244, 191, 46, 244, 190, 46, 244, + 189, 46, 244, 188, 46, 244, 187, 46, 244, 186, 46, 244, 185, 46, 244, + 184, 46, 244, 183, 46, 244, 182, 46, 244, 181, 46, 244, 180, 46, 244, + 179, 46, 244, 178, 46, 244, 177, 46, 244, 176, 46, 244, 175, 46, 244, + 174, 46, 244, 173, 46, 244, 172, 46, 244, 171, 46, 244, 170, 46, 244, + 169, 46, 244, 168, 46, 244, 167, 46, 244, 166, 46, 244, 165, 46, 244, + 164, 46, 244, 163, 46, 244, 162, 46, 244, 161, 46, 244, 160, 46, 244, + 159, 46, 244, 158, 46, 244, 157, 46, 244, 156, 46, 244, 155, 46, 244, + 154, 46, 244, 153, 46, 244, 152, 46, 244, 151, 46, 244, 150, 46, 244, + 149, 46, 244, 148, 46, 244, 147, 46, 244, 146, 46, 244, 145, 46, 244, + 144, 46, 244, 143, 46, 244, 142, 46, 244, 141, 46, 244, 140, 46, 244, + 139, 46, 244, 138, 46, 244, 137, 46, 244, 136, 46, 244, 135, 46, 244, + 134, 46, 244, 133, 46, 244, 132, 46, 244, 131, 46, 244, 130, 46, 244, + 129, 46, 244, 128, 46, 244, 127, 46, 244, 126, 46, 244, 125, 46, 244, + 124, 46, 244, 123, 46, 244, 122, 46, 244, 121, 46, 244, 120, 46, 244, + 119, 46, 244, 118, 46, 244, 117, 46, 244, 116, 46, 244, 115, 46, 244, + 114, 46, 244, 113, 46, 244, 112, 46, 244, 111, 46, 244, 110, 46, 244, + 109, 46, 244, 108, 46, 244, 107, 46, 244, 106, 46, 244, 105, 46, 244, + 104, 46, 244, 103, 46, 244, 102, 46, 244, 101, 46, 244, 100, 46, 244, 99, + 46, 244, 98, 46, 244, 97, 46, 244, 96, 46, 244, 95, 46, 244, 94, 46, 244, + 93, 46, 244, 92, 46, 244, 91, 46, 244, 90, 46, 244, 89, 46, 244, 88, 46, + 244, 87, 46, 244, 86, 46, 244, 85, 46, 244, 84, 46, 244, 83, 46, 244, 82, + 46, 244, 81, 46, 244, 80, 46, 244, 79, 46, 244, 78, 46, 244, 77, 46, 244, + 76, 46, 244, 75, 46, 244, 74, 46, 244, 73, 46, 244, 72, 46, 244, 71, 46, + 244, 70, 46, 244, 69, 46, 244, 68, 46, 244, 67, 46, 244, 66, 46, 244, 65, + 46, 244, 64, 46, 244, 63, 46, 244, 62, 46, 244, 61, 46, 244, 60, 46, 244, + 59, 46, 244, 58, 46, 244, 57, 46, 244, 56, 46, 244, 55, 46, 244, 54, 46, + 244, 53, 46, 244, 52, 46, 244, 51, 46, 244, 50, 46, 244, 49, 46, 244, 48, + 46, 244, 47, 46, 244, 46, 46, 244, 45, 46, 244, 44, 46, 244, 43, 46, 244, + 42, 46, 244, 41, 46, 244, 40, 46, 244, 39, 46, 244, 38, 46, 244, 37, 46, + 244, 36, 46, 244, 35, 46, 244, 34, 46, 244, 33, 46, 244, 32, 46, 244, 31, + 46, 244, 30, 46, 244, 29, 46, 244, 28, 46, 244, 27, 46, 244, 26, 46, 244, + 25, 46, 244, 24, 46, 244, 23, 46, 244, 22, 46, 244, 21, 46, 244, 20, 46, + 244, 19, 46, 244, 18, 46, 244, 17, 46, 244, 16, 46, 244, 15, 46, 244, 14, + 46, 244, 13, 46, 244, 12, 46, 244, 11, 46, 244, 10, 46, 244, 9, 46, 244, + 8, 46, 244, 7, 46, 244, 6, 46, 244, 5, 46, 244, 4, 46, 244, 3, 46, 244, + 2, 46, 244, 1, 46, 244, 0, 46, 243, 255, 46, 243, 254, 46, 243, 253, 46, + 243, 252, 46, 243, 251, 46, 243, 250, 46, 243, 249, 46, 243, 248, 46, + 243, 247, 46, 243, 246, 46, 243, 245, 46, 243, 244, 46, 243, 243, 46, + 243, 242, 46, 243, 241, 46, 243, 240, 46, 243, 239, 46, 243, 238, 46, + 243, 237, 46, 243, 236, 46, 243, 235, 46, 243, 234, 46, 243, 233, 46, + 243, 232, 46, 243, 231, 46, 243, 230, 46, 243, 229, 46, 243, 228, 46, + 243, 227, 46, 243, 226, 46, 243, 225, 46, 243, 224, 46, 243, 223, 46, + 243, 222, 46, 243, 221, 46, 243, 220, 46, 243, 219, 46, 243, 218, 46, + 243, 217, 46, 243, 216, 46, 243, 215, 46, 243, 214, 46, 243, 213, 46, + 243, 212, 46, 243, 211, 46, 243, 210, 46, 243, 209, 46, 243, 208, 46, + 243, 207, 46, 243, 206, 46, 243, 205, 46, 243, 204, 46, 243, 203, 46, + 243, 202, 46, 243, 201, 46, 243, 200, 46, 243, 199, 46, 243, 198, 46, + 243, 197, 46, 243, 196, 46, 243, 195, 46, 243, 194, 46, 243, 193, 46, + 243, 192, 46, 243, 191, 46, 243, 190, 46, 243, 189, 46, 243, 188, 46, + 243, 187, 46, 243, 186, 46, 243, 185, 46, 243, 184, 46, 243, 183, 46, + 243, 182, 46, 243, 181, 46, 243, 180, 46, 243, 179, 46, 243, 178, 46, + 243, 177, 46, 243, 176, 46, 243, 175, 46, 243, 174, 46, 243, 173, 46, + 243, 172, 46, 243, 171, 46, 243, 170, 46, 243, 169, 46, 243, 168, 46, + 243, 167, 46, 243, 166, 46, 243, 165, 46, 243, 164, 46, 243, 163, 46, + 243, 162, 46, 243, 161, 46, 243, 160, 46, 243, 159, 46, 243, 158, 46, + 243, 157, 46, 243, 156, 46, 243, 155, 46, 243, 154, 46, 243, 153, 46, + 243, 152, 46, 243, 151, 46, 243, 150, 46, 243, 149, 46, 243, 148, 46, + 243, 147, 46, 243, 146, 46, 243, 145, 46, 243, 144, 46, 243, 143, 46, + 243, 142, 46, 243, 141, 124, 1, 230, 116, 124, 1, 192, 235, 124, 1, 210, + 236, 124, 1, 200, 43, 124, 1, 233, 175, 124, 1, 222, 152, 124, 1, 172, + 124, 1, 250, 120, 124, 1, 238, 127, 124, 1, 196, 12, 124, 1, 232, 51, + 124, 1, 146, 124, 1, 210, 237, 215, 61, 124, 1, 238, 128, 206, 8, 124, 1, + 233, 176, 215, 61, 124, 1, 222, 153, 218, 168, 124, 1, 207, 222, 206, 8, + 124, 1, 199, 51, 124, 1, 202, 82, 237, 69, 124, 1, 237, 69, 124, 1, 221, + 102, 124, 1, 202, 82, 223, 35, 124, 1, 229, 112, 124, 1, 219, 160, 124, + 1, 207, 7, 124, 1, 218, 168, 124, 1, 215, 61, 124, 1, 223, 35, 124, 1, + 206, 8, 124, 1, 218, 169, 215, 61, 124, 1, 215, 62, 218, 168, 124, 1, + 223, 36, 218, 168, 124, 1, 206, 9, 223, 35, 124, 1, 218, 169, 4, 236, + 140, 124, 1, 215, 62, 4, 236, 140, 124, 1, 223, 36, 4, 236, 140, 124, 1, + 223, 36, 4, 185, 223, 118, 23, 58, 124, 1, 206, 9, 4, 236, 140, 124, 1, + 206, 9, 4, 75, 60, 124, 1, 218, 169, 206, 8, 124, 1, 215, 62, 206, 8, + 124, 1, 223, 36, 206, 8, 124, 1, 206, 9, 206, 8, 124, 1, 218, 169, 215, + 62, 206, 8, 124, 1, 215, 62, 218, 169, 206, 8, 124, 1, 223, 36, 218, 169, + 206, 8, 124, 1, 206, 9, 223, 36, 206, 8, 124, 1, 223, 36, 206, 9, 4, 236, + 140, 124, 1, 223, 36, 215, 61, 124, 1, 223, 36, 215, 62, 206, 8, 124, 1, + 206, 9, 200, 43, 124, 1, 206, 9, 200, 44, 146, 124, 1, 206, 9, 210, 236, + 124, 1, 206, 9, 210, 237, 146, 124, 1, 200, 44, 206, 8, 124, 1, 200, 44, + 207, 222, 206, 8, 124, 1, 193, 224, 124, 1, 193, 97, 124, 1, 193, 225, + 146, 124, 1, 206, 9, 215, 61, 124, 1, 206, 9, 218, 168, 124, 1, 222, 153, + 207, 222, 206, 8, 124, 1, 232, 52, 207, 222, 206, 8, 124, 1, 206, 9, 222, + 152, 124, 1, 206, 9, 222, 153, 146, 124, 1, 65, 124, 1, 202, 82, 210, + 250, 124, 1, 211, 182, 124, 1, 74, 124, 1, 251, 66, 124, 1, 68, 124, 1, + 71, 124, 1, 223, 226, 124, 1, 203, 40, 68, 124, 1, 196, 139, 124, 1, 234, + 188, 124, 1, 202, 82, 234, 173, 124, 1, 206, 135, 68, 124, 1, 202, 82, + 234, 188, 124, 1, 179, 68, 124, 1, 192, 80, 124, 1, 66, 124, 1, 233, 242, + 124, 1, 192, 182, 124, 1, 126, 215, 61, 124, 1, 179, 66, 124, 1, 206, + 135, 66, 124, 1, 196, 141, 124, 1, 202, 82, 66, 124, 1, 211, 84, 124, 1, + 210, 250, 124, 1, 211, 19, 124, 1, 193, 190, 124, 1, 193, 48, 124, 1, + 193, 86, 124, 1, 193, 112, 124, 1, 193, 14, 124, 1, 214, 214, 66, 124, 1, + 214, 214, 74, 124, 1, 214, 214, 68, 124, 1, 214, 214, 65, 124, 1, 210, 0, + 251, 132, 124, 1, 210, 0, 251, 149, 124, 1, 202, 82, 234, 103, 124, 1, + 202, 82, 251, 132, 124, 1, 202, 82, 211, 104, 124, 1, 117, 218, 168, 124, + 252, 4, 45, 228, 241, 205, 58, 124, 252, 4, 216, 87, 228, 241, 205, 58, + 124, 252, 4, 50, 228, 241, 205, 58, 124, 252, 4, 130, 81, 205, 58, 124, + 252, 4, 216, 87, 81, 205, 58, 124, 252, 4, 137, 81, 205, 58, 124, 252, 4, + 250, 170, 205, 58, 124, 252, 4, 250, 170, 219, 215, 205, 58, 124, 252, 4, + 250, 170, 199, 188, 124, 252, 4, 250, 170, 199, 215, 124, 252, 4, 250, + 170, 235, 15, 102, 124, 252, 4, 250, 170, 228, 74, 102, 124, 252, 4, 250, + 170, 199, 189, 102, 124, 252, 4, 137, 252, 46, 124, 252, 4, 137, 198, + 172, 252, 46, 124, 252, 4, 137, 230, 210, 124, 252, 4, 137, 179, 230, + 210, 124, 252, 4, 137, 236, 140, 124, 252, 4, 137, 243, 10, 124, 252, 4, + 137, 219, 112, 124, 252, 4, 137, 193, 138, 124, 252, 4, 137, 195, 135, + 124, 252, 4, 130, 252, 46, 124, 252, 4, 130, 198, 172, 252, 46, 124, 252, + 4, 130, 230, 210, 124, 252, 4, 130, 179, 230, 210, 124, 252, 4, 130, 236, + 140, 124, 252, 4, 130, 243, 10, 124, 252, 4, 130, 219, 112, 124, 252, 4, + 130, 193, 138, 124, 252, 4, 130, 195, 135, 124, 252, 4, 130, 57, 124, 3, + 187, 4, 238, 217, 124, 199, 9, 1, 205, 34, 124, 55, 77, 124, 208, 152, + 243, 78, 232, 80, 201, 63, 203, 27, 232, 145, 1, 211, 2, 203, 27, 232, + 145, 239, 28, 211, 2, 203, 27, 232, 145, 144, 201, 78, 203, 27, 232, 145, + 133, 201, 78, 97, 33, 87, 230, 240, 213, 159, 206, 9, 220, 251, 211, 105, + 219, 224, 97, 33, 87, 213, 159, 206, 9, 220, 251, 211, 105, 219, 224, 97, + 33, 87, 197, 162, 211, 105, 219, 224, 97, 33, 87, 230, 240, 213, 159, + 211, 105, 219, 224, 97, 33, 87, 213, 159, 211, 105, 219, 224, 97, 33, 87, + 201, 179, 211, 105, 219, 224, 97, 33, 87, 217, 94, 209, 3, 211, 105, 219, + 224, 97, 33, 87, 209, 3, 211, 105, 219, 224, 97, 33, 87, 193, 231, 211, + 105, 219, 224, 97, 33, 87, 217, 94, 209, 3, 206, 9, 221, 181, 211, 105, + 219, 224, 97, 33, 87, 209, 3, 206, 9, 221, 181, 211, 105, 219, 224, 97, + 33, 87, 193, 231, 206, 9, 221, 181, 211, 105, 219, 224, 97, 33, 87, 230, + 240, 213, 159, 206, 9, 220, 251, 211, 105, 183, 97, 33, 87, 213, 159, + 206, 9, 220, 251, 211, 105, 183, 97, 33, 87, 197, 162, 211, 105, 183, 97, + 33, 87, 230, 240, 213, 159, 211, 105, 183, 97, 33, 87, 213, 159, 211, + 105, 183, 97, 33, 87, 201, 179, 211, 105, 183, 97, 33, 87, 217, 94, 209, + 3, 211, 105, 183, 97, 33, 87, 209, 3, 211, 105, 183, 97, 33, 87, 193, + 231, 211, 105, 183, 97, 33, 87, 217, 94, 209, 3, 206, 9, 221, 181, 211, + 105, 183, 97, 33, 87, 209, 3, 206, 9, 221, 181, 211, 105, 183, 97, 33, + 87, 193, 231, 206, 9, 221, 181, 211, 105, 183, 97, 33, 87, 197, 162, 206, + 9, 220, 250, 97, 33, 87, 217, 94, 209, 3, 206, 9, 220, 250, 97, 33, 87, + 201, 49, 217, 94, 209, 2, 97, 33, 87, 209, 3, 206, 9, 220, 250, 97, 33, + 87, 209, 3, 201, 48, 97, 33, 87, 193, 231, 206, 9, 220, 250, 97, 33, 87, + 217, 94, 209, 3, 201, 48, 97, 33, 87, 230, 240, 193, 230, 97, 33, 87, + 191, 83, 97, 33, 87, 211, 104, 97, 33, 87, 207, 124, 97, 33, 87, 198, + 157, 97, 33, 87, 248, 83, 97, 33, 87, 196, 156, 97, 33, 87, 209, 65, 97, + 33, 87, 219, 21, 97, 33, 87, 220, 200, 97, 33, 87, 222, 115, 97, 33, 87, + 191, 74, 97, 33, 87, 202, 105, 97, 33, 87, 207, 117, 97, 33, 87, 220, + 253, 211, 105, 219, 224, 97, 33, 198, 80, 207, 137, 87, 215, 162, 97, 33, + 198, 80, 207, 137, 87, 200, 153, 97, 33, 198, 80, 207, 137, 87, 197, 246, + 97, 33, 87, 191, 120, 97, 33, 87, 237, 105, 191, 120, 97, 33, 87, 211, + 25, 97, 33, 87, 209, 67, 97, 33, 87, 209, 68, 4, 81, 106, 97, 33, 87, + 243, 134, 97, 33, 87, 243, 135, 209, 45, 97, 33, 87, 211, 174, 97, 33, + 87, 202, 10, 212, 249, 97, 33, 87, 198, 89, 97, 33, 87, 235, 48, 97, 33, + 250, 169, 81, 211, 109, 97, 33, 87, 238, 163, 211, 109, 97, 33, 87, 220, + 252, 97, 33, 110, 198, 80, 207, 137, 223, 144, 97, 208, 203, 52, 219, + 167, 97, 208, 203, 52, 219, 166, 97, 208, 203, 52, 236, 233, 232, 195, + 97, 208, 203, 52, 220, 252, 97, 208, 203, 52, 206, 144, 97, 161, 221, 0, + 97, 161, 221, 1, 198, 156, 97, 161, 210, 122, 97, 161, 235, 56, 196, 13, + 243, 113, 97, 161, 221, 90, 97, 161, 191, 105, 97, 161, 201, 61, 97, 161, + 201, 62, 206, 9, 211, 163, 97, 161, 210, 10, 97, 161, 210, 11, 214, 96, + 97, 161, 201, 62, 4, 202, 10, 212, 249, 97, 161, 243, 112, 97, 161, 210, + 186, 97, 161, 191, 103, 97, 161, 230, 248, 248, 82, 97, 161, 230, 248, + 198, 156, 97, 161, 230, 248, 215, 160, 97, 161, 230, 248, 200, 152, 97, + 161, 230, 248, 197, 245, 97, 161, 194, 253, 208, 183, 97, 161, 194, 253, + 215, 163, 97, 161, 194, 253, 200, 154, 97, 161, 194, 253, 197, 247, 97, + 161, 194, 253, 221, 85, 208, 183, 97, 161, 194, 253, 221, 85, 215, 163, + 97, 161, 194, 253, 221, 85, 200, 154, 97, 161, 194, 253, 221, 85, 197, + 247, 97, 161, 55, 191, 103, 97, 161, 207, 18, 243, 112, 97, 161, 237, 91, + 97, 161, 221, 207, 97, 161, 243, 134, 97, 161, 209, 67, 97, 161, 202, + 113, 215, 163, 97, 161, 202, 113, 200, 154, 97, 161, 202, 113, 197, 247, + 97, 161, 202, 113, 198, 157, 97, 161, 237, 105, 221, 90, 97, 161, 202, + 113, 221, 85, 200, 154, 97, 161, 202, 113, 221, 89, 97, 161, 202, 113, + 221, 85, 198, 157, 97, 161, 202, 113, 235, 53, 208, 183, 97, 161, 202, + 113, 235, 53, 200, 154, 97, 161, 202, 113, 235, 53, 214, 96, 97, 161, + 202, 113, 235, 53, 221, 84, 97, 161, 202, 72, 97, 161, 202, 73, 206, 9, + 191, 101, 97, 161, 202, 73, 191, 110, 97, 161, 202, 73, 206, 9, 220, 250, + 97, 161, 220, 252, 97, 161, 206, 144, 97, 161, 232, 228, 97, 161, 221, + 59, 97, 161, 191, 8, 97, 161, 201, 90, 97, 161, 201, 91, 206, 9, 191, + 101, 97, 161, 201, 91, 206, 9, 220, 250, 97, 161, 201, 91, 206, 9, 191, + 102, 228, 74, 220, 250, 97, 161, 201, 91, 206, 9, 220, 251, 228, 74, 191, + 101, 97, 161, 201, 91, 191, 111, 97, 161, 201, 91, 191, 112, 206, 9, 191, + 101, 97, 161, 201, 91, 206, 9, 206, 143, 97, 161, 201, 91, 206, 9, 235, + 47, 191, 100, 97, 161, 201, 91, 206, 9, 191, 102, 228, 74, 209, 66, 97, + 161, 209, 47, 97, 161, 201, 91, 214, 96, 97, 161, 201, 40, 208, 183, 97, + 161, 201, 40, 215, 161, 97, 161, 201, 40, 220, 249, 97, 161, 201, 40, + 209, 43, 97, 161, 201, 40, 209, 5, 97, 161, 201, 40, 214, 96, 97, 161, + 201, 40, 221, 87, 97, 161, 201, 40, 221, 89, 97, 161, 201, 40, 198, 158, + 208, 130, 97, 161, 201, 40, 235, 52, 97, 161, 201, 40, 235, 51, 97, 161, + 201, 40, 235, 49, 97, 161, 201, 40, 235, 53, 221, 84, 97, 161, 201, 40, + 235, 50, 221, 84, 97, 161, 201, 40, 230, 195, 4, 202, 170, 191, 103, 97, + 161, 201, 40, 230, 191, 4, 202, 170, 191, 103, 97, 161, 201, 40, 230, + 194, 97, 161, 201, 40, 230, 190, 97, 161, 201, 40, 230, 191, 4, 55, 191, + 103, 97, 161, 201, 40, 230, 192, 97, 161, 201, 40, 230, 193, 209, 5, 97, + 161, 216, 221, 97, 161, 216, 222, 209, 4, 97, 161, 216, 222, 221, 83, 97, + 161, 216, 222, 221, 86, 97, 161, 216, 222, 221, 88, 97, 161, 201, 40, + 197, 174, 97, 161, 201, 40, 197, 173, 97, 161, 201, 40, 197, 172, 97, + 161, 211, 31, 97, 161, 211, 32, 200, 154, 97, 161, 211, 32, 197, 247, 97, + 161, 211, 32, 220, 255, 200, 154, 97, 161, 211, 32, 221, 85, 200, 154, + 97, 161, 211, 32, 221, 85, 214, 96, 97, 161, 201, 40, 220, 254, 97, 161, + 201, 40, 220, 255, 209, 5, 97, 161, 201, 40, 220, 255, 230, 195, 4, 202, + 170, 191, 103, 97, 161, 201, 40, 220, 255, 230, 191, 4, 202, 170, 191, + 103, 97, 161, 201, 40, 220, 255, 230, 194, 97, 161, 201, 40, 220, 255, + 230, 190, 97, 161, 201, 40, 220, 255, 230, 191, 4, 55, 191, 103, 97, 161, + 201, 40, 220, 255, 230, 192, 97, 161, 201, 40, 220, 255, 230, 193, 209, + 5, 97, 161, 201, 40, 220, 255, 197, 175, 97, 161, 220, 214, 97, 161, 211, + 173, 97, 161, 235, 84, 97, 161, 214, 103, 97, 161, 210, 79, 73, 37, 16, + 208, 169, 73, 37, 16, 237, 217, 73, 37, 16, 210, 4, 73, 37, 16, 210, 246, + 234, 144, 73, 37, 16, 210, 246, 236, 238, 73, 37, 16, 195, 172, 234, 144, + 73, 37, 16, 195, 172, 236, 238, 73, 37, 16, 222, 44, 73, 37, 16, 200, 60, + 73, 37, 16, 210, 120, 73, 37, 16, 191, 231, 73, 37, 16, 191, 232, 236, + 238, 73, 37, 16, 221, 3, 73, 37, 16, 251, 61, 234, 144, 73, 37, 16, 233, + 210, 234, 144, 73, 37, 16, 199, 108, 73, 37, 16, 221, 247, 73, 37, 16, + 251, 50, 73, 37, 16, 251, 51, 236, 238, 73, 37, 16, 200, 67, 73, 37, 16, + 198, 244, 73, 37, 16, 211, 116, 251, 12, 73, 37, 16, 230, 238, 251, 12, + 73, 37, 16, 208, 168, 73, 37, 16, 246, 248, 73, 37, 16, 195, 161, 73, 37, + 16, 223, 58, 251, 12, 73, 37, 16, 221, 249, 251, 12, 73, 37, 16, 221, + 248, 251, 12, 73, 37, 16, 205, 105, 73, 37, 16, 210, 110, 73, 37, 16, + 201, 88, 251, 54, 73, 37, 16, 210, 245, 251, 12, 73, 37, 16, 195, 171, + 251, 12, 73, 37, 16, 251, 55, 251, 12, 73, 37, 16, 251, 48, 73, 37, 16, + 221, 92, 73, 37, 16, 207, 14, 73, 37, 16, 209, 183, 251, 12, 73, 37, 16, + 198, 142, 73, 37, 16, 251, 128, 73, 37, 16, 205, 37, 73, 37, 16, 200, 71, + 251, 12, 73, 37, 16, 200, 71, 216, 166, 201, 86, 73, 37, 16, 210, 240, + 251, 12, 73, 37, 16, 199, 27, 73, 37, 16, 219, 202, 73, 37, 16, 235, 38, + 73, 37, 16, 197, 243, 73, 37, 16, 199, 76, 73, 37, 16, 221, 6, 73, 37, + 16, 251, 61, 233, 210, 214, 98, 73, 37, 16, 232, 88, 251, 12, 73, 37, 16, + 223, 175, 73, 37, 16, 197, 210, 251, 12, 73, 37, 16, 222, 47, 197, 209, + 73, 37, 16, 210, 36, 73, 37, 16, 208, 173, 73, 37, 16, 221, 42, 73, 37, + 16, 243, 60, 251, 12, 73, 37, 16, 207, 135, 73, 37, 16, 210, 124, 251, + 12, 73, 37, 16, 210, 121, 251, 12, 73, 37, 16, 228, 24, 73, 37, 16, 214, + 225, 73, 37, 16, 209, 238, 73, 37, 16, 221, 43, 251, 167, 73, 37, 16, + 197, 210, 251, 167, 73, 37, 16, 201, 55, 73, 37, 16, 230, 189, 73, 37, + 16, 223, 58, 214, 98, 73, 37, 16, 211, 116, 214, 98, 73, 37, 16, 210, + 246, 214, 98, 73, 37, 16, 209, 237, 73, 37, 16, 221, 26, 73, 37, 16, 209, + 236, 73, 37, 16, 221, 5, 73, 37, 16, 210, 37, 214, 98, 73, 37, 16, 221, + 248, 214, 99, 251, 93, 73, 37, 16, 221, 249, 214, 99, 251, 93, 73, 37, + 16, 191, 229, 73, 37, 16, 251, 51, 214, 98, 73, 37, 16, 251, 52, 200, 68, + 214, 98, 73, 37, 16, 191, 230, 73, 37, 16, 221, 4, 73, 37, 16, 234, 139, + 73, 37, 16, 246, 249, 73, 37, 16, 216, 57, 223, 57, 73, 37, 16, 195, 172, + 214, 98, 73, 37, 16, 209, 183, 214, 98, 73, 37, 16, 208, 174, 214, 98, + 73, 37, 16, 211, 112, 73, 37, 16, 251, 80, 73, 37, 16, 218, 179, 73, 37, + 16, 210, 121, 214, 98, 73, 37, 16, 210, 124, 214, 98, 73, 37, 16, 233, + 249, 210, 123, 73, 37, 16, 220, 147, 73, 37, 16, 251, 81, 73, 37, 16, + 197, 210, 214, 98, 73, 37, 16, 234, 142, 73, 37, 16, 200, 71, 214, 98, + 73, 37, 16, 200, 61, 73, 37, 16, 243, 60, 214, 98, 73, 37, 16, 234, 53, + 73, 37, 16, 205, 38, 214, 98, 73, 37, 16, 192, 199, 221, 92, 73, 37, 16, + 197, 207, 73, 37, 16, 208, 175, 73, 37, 16, 197, 211, 73, 37, 16, 197, + 208, 73, 37, 16, 208, 172, 73, 37, 16, 197, 206, 73, 37, 16, 208, 171, + 73, 37, 16, 230, 237, 73, 37, 16, 251, 4, 73, 37, 16, 233, 249, 251, 4, + 73, 37, 16, 210, 240, 214, 98, 73, 37, 16, 199, 26, 234, 6, 73, 37, 16, + 199, 26, 233, 209, 73, 37, 16, 199, 28, 251, 56, 73, 37, 16, 199, 20, + 222, 103, 251, 47, 73, 37, 16, 222, 46, 73, 37, 16, 234, 90, 73, 37, 16, + 192, 38, 222, 43, 73, 37, 16, 192, 38, 251, 93, 73, 37, 16, 201, 87, 73, + 37, 16, 221, 93, 251, 93, 73, 37, 16, 236, 239, 251, 12, 73, 37, 16, 221, + 7, 251, 12, 73, 37, 16, 221, 7, 251, 167, 73, 37, 16, 221, 7, 214, 98, + 73, 37, 16, 251, 55, 214, 98, 73, 37, 16, 251, 57, 73, 37, 16, 236, 238, + 73, 37, 16, 197, 223, 73, 37, 16, 199, 66, 73, 37, 16, 221, 30, 73, 37, + 16, 219, 207, 234, 83, 243, 50, 73, 37, 16, 219, 207, 235, 39, 243, 51, + 73, 37, 16, 219, 207, 197, 226, 243, 51, 73, 37, 16, 219, 207, 199, 78, + 243, 51, 73, 37, 16, 219, 207, 223, 170, 243, 50, 73, 37, 16, 230, 238, + 214, 99, 251, 93, 73, 37, 16, 230, 238, 210, 111, 251, 0, 73, 37, 16, + 230, 238, 210, 111, 237, 73, 73, 37, 16, 237, 7, 73, 37, 16, 237, 8, 210, + 111, 251, 1, 222, 43, 73, 37, 16, 237, 8, 210, 111, 251, 1, 251, 93, 73, + 37, 16, 237, 8, 210, 111, 237, 73, 73, 37, 16, 197, 232, 73, 37, 16, 251, + 5, 73, 37, 16, 223, 177, 73, 37, 16, 237, 30, 73, 37, 16, 251, 247, 209, + 51, 251, 6, 73, 37, 16, 251, 247, 251, 3, 73, 37, 16, 251, 247, 251, 6, + 73, 37, 16, 251, 247, 216, 160, 73, 37, 16, 251, 247, 216, 171, 73, 37, + 16, 251, 247, 230, 239, 73, 37, 16, 251, 247, 230, 236, 73, 37, 16, 251, + 247, 209, 51, 230, 239, 73, 37, 16, 217, 45, 208, 181, 228, 22, 73, 37, + 16, 217, 45, 251, 169, 208, 181, 228, 22, 73, 37, 16, 217, 45, 237, 72, + 228, 22, 73, 37, 16, 217, 45, 251, 169, 237, 72, 228, 22, 73, 37, 16, + 217, 45, 197, 218, 228, 22, 73, 37, 16, 217, 45, 197, 233, 73, 37, 16, + 217, 45, 199, 71, 228, 22, 73, 37, 16, 217, 45, 199, 71, 219, 211, 228, + 22, 73, 37, 16, 217, 45, 219, 211, 228, 22, 73, 37, 16, 217, 45, 209, + 105, 228, 22, 73, 37, 16, 223, 66, 199, 101, 228, 23, 73, 37, 16, 251, + 52, 199, 101, 228, 23, 73, 37, 16, 233, 79, 199, 68, 73, 37, 16, 233, 79, + 215, 222, 73, 37, 16, 233, 79, 237, 13, 73, 37, 16, 217, 45, 195, 165, + 228, 22, 73, 37, 16, 217, 45, 208, 180, 228, 22, 73, 37, 16, 217, 45, + 209, 105, 199, 71, 228, 22, 73, 37, 16, 230, 233, 215, 62, 251, 56, 73, + 37, 16, 230, 233, 215, 62, 236, 237, 73, 37, 16, 234, 101, 222, 103, 232, + 88, 195, 3, 73, 37, 16, 223, 176, 73, 37, 16, 223, 174, 73, 37, 16, 232, + 88, 251, 13, 237, 71, 228, 21, 73, 37, 16, 232, 88, 237, 28, 168, 73, 37, + 16, 232, 88, 237, 28, 214, 225, 73, 37, 16, 232, 88, 214, 219, 228, 22, + 73, 37, 16, 232, 88, 237, 28, 237, 44, 73, 37, 16, 232, 88, 202, 106, + 237, 27, 237, 44, 73, 37, 16, 232, 88, 237, 28, 222, 22, 73, 37, 16, 232, + 88, 237, 28, 191, 7, 73, 37, 16, 232, 88, 237, 28, 213, 220, 222, 43, 73, + 37, 16, 232, 88, 237, 28, 213, 220, 251, 93, 73, 37, 16, 232, 88, 217, + 98, 243, 52, 237, 13, 73, 37, 16, 232, 88, 217, 98, 243, 52, 215, 222, + 73, 37, 16, 233, 24, 202, 106, 243, 52, 195, 164, 73, 37, 16, 232, 88, + 202, 106, 243, 52, 200, 72, 73, 37, 16, 232, 88, 214, 101, 73, 37, 16, + 243, 53, 190, 230, 73, 37, 16, 243, 53, 221, 91, 73, 37, 16, 243, 53, + 201, 238, 73, 37, 16, 232, 88, 228, 74, 192, 37, 199, 72, 73, 37, 16, + 232, 88, 234, 102, 251, 82, 73, 37, 16, 192, 37, 197, 219, 73, 37, 16, + 237, 21, 197, 219, 73, 37, 16, 237, 21, 199, 72, 73, 37, 16, 237, 21, + 251, 58, 235, 39, 236, 166, 73, 37, 16, 237, 21, 215, 220, 199, 77, 236, + 166, 73, 37, 16, 237, 21, 237, 4, 233, 222, 236, 166, 73, 37, 16, 237, + 21, 197, 230, 211, 122, 236, 166, 73, 37, 16, 192, 37, 251, 58, 235, 39, + 236, 166, 73, 37, 16, 192, 37, 215, 220, 199, 77, 236, 166, 73, 37, 16, + 192, 37, 237, 4, 233, 222, 236, 166, 73, 37, 16, 192, 37, 197, 230, 211, + 122, 236, 166, 73, 37, 16, 231, 147, 237, 20, 73, 37, 16, 231, 147, 192, + 36, 73, 37, 16, 237, 29, 251, 58, 216, 58, 73, 37, 16, 237, 29, 251, 58, + 216, 202, 73, 37, 16, 237, 29, 236, 238, 73, 37, 16, 237, 29, 199, 18, + 73, 37, 16, 202, 181, 199, 18, 73, 37, 16, 202, 181, 199, 19, 236, 221, + 73, 37, 16, 202, 181, 199, 19, 197, 220, 73, 37, 16, 202, 181, 199, 19, + 199, 64, 73, 37, 16, 202, 181, 250, 228, 73, 37, 16, 202, 181, 250, 229, + 236, 221, 73, 37, 16, 202, 181, 250, 229, 197, 220, 73, 37, 16, 202, 181, + 250, 229, 199, 64, 73, 37, 16, 237, 5, 231, 128, 73, 37, 16, 237, 12, + 211, 19, 73, 37, 16, 201, 73, 73, 37, 16, 250, 253, 168, 73, 37, 16, 250, + 253, 195, 3, 73, 37, 16, 250, 253, 231, 240, 73, 37, 16, 250, 253, 237, + 44, 73, 37, 16, 250, 253, 222, 22, 73, 37, 16, 250, 253, 191, 7, 73, 37, + 16, 250, 253, 213, 219, 73, 37, 16, 221, 248, 214, 99, 216, 170, 73, 37, + 16, 221, 249, 214, 99, 216, 170, 73, 37, 16, 221, 248, 214, 99, 222, 43, + 73, 37, 16, 221, 249, 214, 99, 222, 43, 73, 37, 16, 221, 93, 222, 43, 73, + 37, 16, 230, 238, 214, 99, 222, 43, 37, 16, 202, 170, 249, 83, 37, 16, + 55, 249, 83, 37, 16, 53, 249, 83, 37, 16, 207, 19, 53, 249, 83, 37, 16, + 237, 214, 249, 83, 37, 16, 203, 40, 249, 83, 37, 16, 45, 207, 49, 56, 37, + 16, 50, 207, 49, 56, 37, 16, 207, 49, 236, 138, 37, 16, 238, 4, 205, 41, + 37, 16, 238, 33, 247, 108, 37, 16, 205, 41, 37, 16, 242, 92, 37, 16, 207, + 47, 233, 11, 37, 16, 207, 47, 233, 10, 37, 16, 207, 47, 233, 9, 37, 16, + 233, 34, 37, 16, 233, 35, 60, 37, 16, 248, 39, 77, 37, 16, 247, 150, 37, + 16, 248, 55, 37, 16, 248, 53, 37, 16, 211, 99, 201, 111, 37, 16, 197, 12, + 201, 111, 37, 16, 198, 220, 201, 111, 37, 16, 232, 127, 201, 111, 37, 16, + 232, 224, 201, 111, 37, 16, 202, 135, 201, 111, 37, 16, 202, 133, 232, + 105, 37, 16, 232, 125, 232, 105, 37, 16, 232, 52, 242, 235, 37, 16, 232, + 52, 242, 236, 211, 23, 251, 158, 37, 16, 232, 52, 242, 236, 211, 23, 249, + 66, 37, 16, 247, 194, 242, 235, 37, 16, 233, 176, 242, 235, 37, 16, 233, + 176, 242, 236, 211, 23, 251, 158, 37, 16, 233, 176, 242, 236, 211, 23, + 249, 66, 37, 16, 235, 95, 242, 234, 37, 16, 235, 95, 242, 233, 37, 16, + 215, 129, 216, 228, 207, 30, 37, 16, 55, 203, 126, 37, 16, 55, 232, 206, + 37, 16, 232, 207, 196, 77, 37, 16, 232, 207, 235, 123, 37, 16, 214, 206, + 196, 77, 37, 16, 214, 206, 235, 123, 37, 16, 203, 127, 196, 77, 37, 16, + 203, 127, 235, 123, 37, 16, 208, 23, 163, 203, 126, 37, 16, 208, 23, 163, + 232, 206, 37, 16, 242, 71, 198, 146, 37, 16, 238, 155, 198, 146, 37, 16, + 211, 23, 251, 158, 37, 16, 211, 23, 249, 66, 37, 16, 208, 3, 251, 158, + 37, 16, 208, 3, 249, 66, 37, 16, 215, 132, 207, 30, 37, 16, 193, 87, 207, + 30, 37, 16, 132, 207, 30, 37, 16, 208, 23, 207, 30, 37, 16, 234, 160, + 207, 30, 37, 16, 202, 129, 207, 30, 37, 16, 198, 246, 207, 30, 37, 16, + 202, 119, 207, 30, 37, 16, 91, 228, 141, 197, 30, 207, 30, 37, 16, 192, + 236, 213, 2, 37, 16, 108, 213, 2, 37, 16, 243, 11, 192, 236, 213, 2, 37, + 16, 51, 213, 3, 193, 89, 37, 16, 51, 213, 3, 248, 139, 37, 16, 197, 242, + 213, 3, 133, 193, 89, 37, 16, 197, 242, 213, 3, 133, 248, 139, 37, 16, + 197, 242, 213, 3, 45, 193, 89, 37, 16, 197, 242, 213, 3, 45, 248, 139, + 37, 16, 197, 242, 213, 3, 50, 193, 89, 37, 16, 197, 242, 213, 3, 50, 248, + 139, 37, 16, 197, 242, 213, 3, 144, 193, 89, 37, 16, 197, 242, 213, 3, + 144, 248, 139, 37, 16, 197, 242, 213, 3, 133, 50, 193, 89, 37, 16, 197, + 242, 213, 3, 133, 50, 248, 139, 37, 16, 215, 206, 213, 3, 193, 89, 37, + 16, 215, 206, 213, 3, 248, 139, 37, 16, 197, 239, 213, 3, 144, 193, 89, + 37, 16, 197, 239, 213, 3, 144, 248, 139, 37, 16, 210, 114, 213, 2, 37, + 16, 195, 17, 213, 2, 37, 16, 213, 3, 248, 139, 37, 16, 212, 139, 213, 2, + 37, 16, 242, 203, 213, 3, 193, 89, 37, 16, 242, 203, 213, 3, 248, 139, + 37, 16, 248, 36, 37, 16, 193, 87, 213, 6, 37, 16, 132, 213, 6, 37, 16, + 208, 23, 213, 6, 37, 16, 234, 160, 213, 6, 37, 16, 202, 129, 213, 6, 37, + 16, 198, 246, 213, 6, 37, 16, 202, 119, 213, 6, 37, 16, 91, 228, 141, + 197, 30, 213, 6, 37, 16, 33, 201, 80, 37, 16, 33, 201, 197, 201, 80, 37, + 16, 33, 197, 253, 37, 16, 33, 197, 252, 37, 16, 33, 197, 251, 37, 16, + 232, 250, 197, 253, 37, 16, 232, 250, 197, 252, 37, 16, 232, 250, 197, + 251, 37, 16, 33, 250, 160, 236, 140, 37, 16, 33, 232, 216, 37, 16, 33, + 232, 215, 37, 16, 33, 232, 214, 37, 16, 33, 232, 213, 37, 16, 33, 232, + 212, 37, 16, 248, 249, 249, 14, 37, 16, 234, 95, 249, 14, 37, 16, 248, + 249, 198, 178, 37, 16, 234, 95, 198, 178, 37, 16, 248, 249, 202, 71, 37, + 16, 234, 95, 202, 71, 37, 16, 248, 249, 209, 192, 37, 16, 234, 95, 209, + 192, 37, 16, 33, 252, 60, 37, 16, 33, 201, 115, 37, 16, 33, 199, 83, 37, + 16, 33, 201, 116, 37, 16, 33, 217, 60, 37, 16, 33, 217, 59, 37, 16, 33, + 252, 59, 37, 16, 33, 218, 243, 37, 16, 250, 241, 196, 77, 37, 16, 250, + 241, 235, 123, 37, 16, 33, 236, 158, 37, 16, 33, 206, 184, 37, 16, 33, + 232, 195, 37, 16, 33, 202, 67, 37, 16, 33, 248, 227, 37, 16, 33, 55, 198, + 61, 37, 16, 33, 197, 225, 198, 61, 37, 16, 206, 190, 37, 16, 200, 241, + 37, 16, 191, 166, 37, 16, 209, 184, 37, 16, 216, 151, 37, 16, 232, 140, + 37, 16, 238, 229, 37, 16, 237, 132, 37, 16, 230, 228, 213, 7, 202, 97, + 37, 16, 230, 228, 213, 7, 213, 44, 202, 97, 37, 16, 198, 27, 37, 16, 197, + 58, 37, 16, 223, 93, 197, 58, 37, 16, 197, 59, 202, 97, 37, 16, 197, 59, + 196, 77, 37, 16, 211, 43, 201, 27, 37, 16, 211, 43, 201, 24, 37, 16, 211, + 43, 201, 23, 37, 16, 211, 43, 201, 22, 37, 16, 211, 43, 201, 21, 37, 16, + 211, 43, 201, 20, 37, 16, 211, 43, 201, 19, 37, 16, 211, 43, 201, 18, 37, + 16, 211, 43, 201, 17, 37, 16, 211, 43, 201, 26, 37, 16, 211, 43, 201, 25, + 37, 16, 230, 0, 37, 16, 214, 113, 37, 16, 234, 95, 79, 201, 69, 37, 16, + 237, 125, 202, 97, 37, 16, 33, 144, 248, 69, 37, 16, 33, 133, 248, 69, + 37, 16, 33, 230, 14, 37, 16, 33, 202, 57, 209, 111, 37, 16, 210, 54, 77, + 37, 16, 210, 54, 133, 77, 37, 16, 132, 210, 54, 77, 37, 16, 231, 13, 196, + 77, 37, 16, 231, 13, 235, 123, 37, 16, 4, 232, 249, 37, 16, 237, 241, 37, + 16, 237, 242, 251, 174, 37, 16, 217, 23, 37, 16, 219, 10, 37, 16, 248, + 33, 37, 16, 204, 29, 193, 89, 37, 16, 204, 29, 248, 139, 37, 16, 216, 39, + 37, 16, 216, 40, 248, 139, 37, 16, 204, 23, 193, 89, 37, 16, 204, 23, + 248, 139, 37, 16, 232, 70, 193, 89, 37, 16, 232, 70, 248, 139, 37, 16, + 219, 11, 210, 9, 207, 30, 37, 16, 219, 11, 223, 167, 207, 30, 37, 16, + 248, 34, 207, 30, 37, 16, 204, 29, 207, 30, 37, 16, 216, 40, 207, 30, 37, + 16, 204, 23, 207, 30, 37, 16, 199, 97, 210, 7, 238, 186, 208, 192, 210, + 8, 37, 16, 199, 97, 210, 7, 238, 186, 208, 192, 223, 166, 37, 16, 199, + 97, 210, 7, 238, 186, 208, 192, 210, 9, 236, 248, 37, 16, 199, 97, 223, + 165, 238, 186, 208, 192, 210, 8, 37, 16, 199, 97, 223, 165, 238, 186, + 208, 192, 223, 166, 37, 16, 199, 97, 223, 165, 238, 186, 208, 192, 223, + 167, 236, 248, 37, 16, 199, 97, 223, 165, 238, 186, 208, 192, 223, 167, + 236, 247, 37, 16, 199, 97, 223, 165, 238, 186, 208, 192, 223, 167, 236, + 246, 37, 16, 238, 220, 37, 16, 230, 199, 247, 194, 242, 235, 37, 16, 230, + 199, 233, 176, 242, 235, 37, 16, 51, 250, 120, 37, 16, 195, 39, 37, 16, + 209, 69, 37, 16, 242, 224, 37, 16, 205, 95, 37, 16, 242, 229, 37, 16, + 198, 47, 37, 16, 209, 28, 37, 16, 209, 29, 232, 198, 37, 16, 205, 96, + 232, 198, 37, 16, 198, 48, 207, 27, 37, 16, 209, 246, 200, 231, 37, 16, + 221, 148, 247, 194, 242, 235, 37, 16, 221, 148, 234, 95, 79, 209, 175, + 37, 16, 221, 148, 53, 213, 6, 37, 16, 221, 148, 207, 99, 77, 37, 16, 221, + 148, 193, 87, 213, 6, 37, 16, 221, 148, 132, 213, 6, 37, 16, 221, 148, + 208, 23, 213, 7, 201, 81, 235, 123, 37, 16, 221, 148, 208, 23, 213, 7, + 201, 81, 196, 77, 37, 16, 221, 148, 234, 160, 213, 7, 201, 81, 235, 123, + 37, 16, 221, 148, 234, 160, 213, 7, 201, 81, 196, 77, 37, 16, 221, 148, + 232, 207, 56, 37, 16, 202, 11, 37, 16, 221, 31, 35, 195, 23, 213, 10, + 200, 123, 35, 195, 23, 213, 10, 200, 112, 35, 195, 23, 213, 10, 200, 102, + 35, 195, 23, 213, 10, 200, 95, 35, 195, 23, 213, 10, 200, 87, 35, 195, + 23, 213, 10, 200, 81, 35, 195, 23, 213, 10, 200, 80, 35, 195, 23, 213, + 10, 200, 79, 35, 195, 23, 213, 10, 200, 78, 35, 195, 23, 213, 10, 200, + 122, 35, 195, 23, 213, 10, 200, 121, 35, 195, 23, 213, 10, 200, 120, 35, + 195, 23, 213, 10, 200, 119, 35, 195, 23, 213, 10, 200, 118, 35, 195, 23, + 213, 10, 200, 117, 35, 195, 23, 213, 10, 200, 116, 35, 195, 23, 213, 10, + 200, 115, 35, 195, 23, 213, 10, 200, 114, 35, 195, 23, 213, 10, 200, 113, + 35, 195, 23, 213, 10, 200, 111, 35, 195, 23, 213, 10, 200, 110, 35, 195, + 23, 213, 10, 200, 109, 35, 195, 23, 213, 10, 200, 108, 35, 195, 23, 213, + 10, 200, 107, 35, 195, 23, 213, 10, 200, 86, 35, 195, 23, 213, 10, 200, + 85, 35, 195, 23, 213, 10, 200, 84, 35, 195, 23, 213, 10, 200, 83, 35, + 195, 23, 213, 10, 200, 82, 35, 223, 116, 213, 10, 200, 123, 35, 223, 116, + 213, 10, 200, 112, 35, 223, 116, 213, 10, 200, 95, 35, 223, 116, 213, 10, + 200, 87, 35, 223, 116, 213, 10, 200, 80, 35, 223, 116, 213, 10, 200, 79, + 35, 223, 116, 213, 10, 200, 121, 35, 223, 116, 213, 10, 200, 120, 35, + 223, 116, 213, 10, 200, 119, 35, 223, 116, 213, 10, 200, 118, 35, 223, + 116, 213, 10, 200, 115, 35, 223, 116, 213, 10, 200, 114, 35, 223, 116, + 213, 10, 200, 113, 35, 223, 116, 213, 10, 200, 108, 35, 223, 116, 213, + 10, 200, 107, 35, 223, 116, 213, 10, 200, 106, 35, 223, 116, 213, 10, + 200, 105, 35, 223, 116, 213, 10, 200, 104, 35, 223, 116, 213, 10, 200, + 103, 35, 223, 116, 213, 10, 200, 101, 35, 223, 116, 213, 10, 200, 100, + 35, 223, 116, 213, 10, 200, 99, 35, 223, 116, 213, 10, 200, 98, 35, 223, + 116, 213, 10, 200, 97, 35, 223, 116, 213, 10, 200, 96, 35, 223, 116, 213, + 10, 200, 94, 35, 223, 116, 213, 10, 200, 93, 35, 223, 116, 213, 10, 200, + 92, 35, 223, 116, 213, 10, 200, 91, 35, 223, 116, 213, 10, 200, 90, 35, + 223, 116, 213, 10, 200, 89, 35, 223, 116, 213, 10, 200, 88, 35, 223, 116, + 213, 10, 200, 86, 35, 223, 116, 213, 10, 200, 85, 35, 223, 116, 213, 10, + 200, 84, 35, 223, 116, 213, 10, 200, 83, 35, 223, 116, 213, 10, 200, 82, + 33, 35, 37, 197, 221, 33, 35, 37, 199, 65, 33, 35, 37, 210, 22, 35, 37, + 219, 206, 222, 93, 212, 134, 191, 77, 222, 93, 212, 134, 107, 222, 93, + 212, 134, 109, 222, 93, 212, 134, 138, 222, 93, 212, 134, 134, 222, 93, + 212, 134, 149, 222, 93, 212, 134, 169, 222, 93, 212, 134, 175, 222, 93, + 212, 134, 171, 222, 93, 212, 134, 178, 222, 93, 212, 134, 199, 95, 222, + 93, 212, 134, 234, 127, 222, 93, 212, 134, 197, 37, 222, 93, 212, 134, + 198, 251, 222, 93, 212, 134, 232, 122, 222, 93, 212, 134, 233, 19, 222, + 93, 212, 134, 202, 130, 222, 93, 212, 134, 203, 244, 222, 93, 212, 134, + 234, 161, 222, 93, 212, 134, 213, 171, 217, 20, 212, 134, 191, 77, 217, + 20, 212, 134, 107, 217, 20, 212, 134, 109, 217, 20, 212, 134, 138, 217, + 20, 212, 134, 134, 217, 20, 212, 134, 149, 217, 20, 212, 134, 169, 217, + 20, 212, 134, 175, 217, 20, 212, 134, 171, 217, 20, 212, 134, 178, 217, + 20, 212, 134, 199, 95, 217, 20, 212, 134, 234, 127, 217, 20, 212, 134, + 197, 37, 217, 20, 212, 134, 198, 251, 217, 20, 212, 134, 232, 122, 217, + 20, 212, 134, 233, 19, 217, 20, 212, 134, 202, 130, 217, 20, 212, 134, + 203, 244, 217, 20, 212, 134, 234, 161, 217, 20, 212, 134, 213, 171, 215, + 221, 40, 234, 207, 237, 6, 40, 229, 218, 234, 207, 237, 6, 40, 228, 145, + 234, 207, 237, 6, 40, 234, 206, 229, 219, 237, 6, 40, 234, 206, 228, 144, + 237, 6, 40, 234, 207, 199, 67, 40, 247, 21, 199, 67, 40, 232, 80, 243, + 10, 199, 67, 40, 216, 30, 199, 67, 40, 249, 78, 199, 67, 40, 222, 10, + 202, 70, 199, 67, 40, 239, 23, 199, 67, 40, 250, 212, 199, 67, 40, 211, + 62, 199, 67, 40, 248, 45, 211, 14, 199, 67, 40, 237, 127, 211, 57, 236, + 213, 199, 67, 40, 236, 210, 199, 67, 40, 191, 237, 199, 67, 40, 223, 153, + 199, 67, 40, 210, 32, 199, 67, 40, 207, 108, 199, 67, 40, 239, 35, 199, + 67, 40, 229, 6, 249, 146, 199, 67, 40, 193, 171, 199, 67, 40, 232, 169, + 199, 67, 40, 252, 28, 199, 67, 40, 207, 62, 199, 67, 40, 207, 34, 199, + 67, 40, 234, 205, 199, 67, 40, 222, 185, 199, 67, 40, 239, 30, 199, 67, + 40, 234, 93, 199, 67, 40, 235, 59, 199, 67, 40, 246, 244, 199, 67, 40, + 237, 137, 199, 67, 40, 28, 207, 33, 199, 67, 40, 210, 211, 199, 67, 40, + 219, 210, 199, 67, 40, 242, 217, 199, 67, 40, 221, 136, 199, 67, 40, 231, + 189, 199, 67, 40, 201, 39, 199, 67, 40, 208, 140, 199, 67, 40, 232, 79, + 199, 67, 40, 207, 35, 199, 67, 40, 219, 251, 211, 57, 216, 2, 199, 67, + 40, 207, 31, 199, 67, 40, 230, 252, 119, 216, 206, 199, 67, 40, 234, 96, + 199, 67, 40, 201, 56, 199, 67, 40, 230, 202, 199, 67, 40, 234, 86, 199, + 67, 40, 210, 83, 199, 67, 40, 206, 177, 199, 67, 40, 232, 196, 199, 67, + 40, 195, 163, 211, 57, 193, 147, 199, 67, 40, 239, 40, 199, 67, 40, 216, + 227, 199, 67, 40, 233, 250, 199, 67, 40, 196, 88, 199, 67, 40, 236, 249, + 199, 67, 40, 242, 219, 215, 179, 199, 67, 40, 230, 171, 199, 67, 40, 231, + 190, 223, 162, 199, 67, 40, 217, 32, 199, 67, 40, 252, 54, 199, 67, 40, + 234, 112, 199, 67, 40, 235, 127, 199, 67, 40, 193, 145, 199, 67, 40, 202, + 165, 199, 67, 40, 223, 126, 199, 67, 40, 237, 93, 199, 67, 40, 237, 219, + 199, 67, 40, 236, 245, 199, 67, 40, 233, 213, 199, 67, 40, 203, 240, 199, + 67, 40, 201, 60, 199, 67, 40, 230, 16, 199, 67, 40, 242, 66, 199, 67, 40, + 242, 214, 199, 67, 40, 233, 88, 199, 67, 40, 251, 248, 199, 67, 40, 242, + 65, 199, 67, 40, 211, 105, 199, 34, 195, 138, 199, 67, 40, 237, 15, 199, + 67, 40, 220, 113, 199, 67, 40, 232, 131, 238, 244, 206, 145, 196, 91, 17, + 107, 238, 244, 206, 145, 196, 91, 17, 109, 238, 244, 206, 145, 196, 91, + 17, 138, 238, 244, 206, 145, 196, 91, 17, 134, 238, 244, 206, 145, 196, + 91, 17, 149, 238, 244, 206, 145, 196, 91, 17, 169, 238, 244, 206, 145, + 196, 91, 17, 175, 238, 244, 206, 145, 196, 91, 17, 171, 238, 244, 206, + 145, 196, 91, 17, 178, 238, 244, 206, 145, 199, 91, 17, 107, 238, 244, + 206, 145, 199, 91, 17, 109, 238, 244, 206, 145, 199, 91, 17, 138, 238, + 244, 206, 145, 199, 91, 17, 134, 238, 244, 206, 145, 199, 91, 17, 149, + 238, 244, 206, 145, 199, 91, 17, 169, 238, 244, 206, 145, 199, 91, 17, + 175, 238, 244, 206, 145, 199, 91, 17, 171, 238, 244, 206, 145, 199, 91, + 17, 178, 154, 199, 198, 87, 107, 154, 199, 198, 87, 109, 154, 199, 198, + 87, 138, 154, 199, 198, 87, 134, 154, 199, 198, 87, 149, 199, 198, 87, + 107, 199, 198, 87, 149, 13, 28, 6, 65, 13, 28, 6, 250, 120, 13, 28, 6, + 247, 193, 13, 28, 6, 238, 127, 13, 28, 6, 71, 13, 28, 6, 233, 175, 13, + 28, 6, 232, 51, 13, 28, 6, 230, 116, 13, 28, 6, 68, 13, 28, 6, 223, 35, + 13, 28, 6, 222, 152, 13, 28, 6, 172, 13, 28, 6, 218, 168, 13, 28, 6, 215, + 61, 13, 28, 6, 74, 13, 28, 6, 210, 236, 13, 28, 6, 208, 104, 13, 28, 6, + 146, 13, 28, 6, 206, 8, 13, 28, 6, 200, 43, 13, 28, 6, 66, 13, 28, 6, + 196, 12, 13, 28, 6, 193, 224, 13, 28, 6, 192, 235, 13, 28, 6, 192, 159, + 13, 28, 6, 191, 166, 13, 28, 2, 65, 13, 28, 2, 250, 120, 13, 28, 2, 247, + 193, 13, 28, 2, 238, 127, 13, 28, 2, 71, 13, 28, 2, 233, 175, 13, 28, 2, + 232, 51, 13, 28, 2, 230, 116, 13, 28, 2, 68, 13, 28, 2, 223, 35, 13, 28, + 2, 222, 152, 13, 28, 2, 172, 13, 28, 2, 218, 168, 13, 28, 2, 215, 61, 13, + 28, 2, 74, 13, 28, 2, 210, 236, 13, 28, 2, 208, 104, 13, 28, 2, 146, 13, + 28, 2, 206, 8, 13, 28, 2, 200, 43, 13, 28, 2, 66, 13, 28, 2, 196, 12, 13, + 28, 2, 193, 224, 13, 28, 2, 192, 235, 13, 28, 2, 192, 159, 13, 28, 2, + 191, 166, 13, 43, 6, 65, 13, 43, 6, 250, 120, 13, 43, 6, 247, 193, 13, + 43, 6, 238, 127, 13, 43, 6, 71, 13, 43, 6, 233, 175, 13, 43, 6, 232, 51, + 13, 43, 6, 230, 116, 13, 43, 6, 68, 13, 43, 6, 223, 35, 13, 43, 6, 222, + 152, 13, 43, 6, 172, 13, 43, 6, 218, 168, 13, 43, 6, 215, 61, 13, 43, 6, + 74, 13, 43, 6, 210, 236, 13, 43, 6, 208, 104, 13, 43, 6, 146, 13, 43, 6, + 206, 8, 13, 43, 6, 200, 43, 13, 43, 6, 66, 13, 43, 6, 196, 12, 13, 43, 6, + 193, 224, 13, 43, 6, 192, 235, 13, 43, 6, 192, 159, 13, 43, 6, 191, 166, + 13, 43, 2, 65, 13, 43, 2, 250, 120, 13, 43, 2, 247, 193, 13, 43, 2, 238, + 127, 13, 43, 2, 71, 13, 43, 2, 233, 175, 13, 43, 2, 232, 51, 13, 43, 2, + 68, 13, 43, 2, 223, 35, 13, 43, 2, 222, 152, 13, 43, 2, 172, 13, 43, 2, + 218, 168, 13, 43, 2, 215, 61, 13, 43, 2, 74, 13, 43, 2, 210, 236, 13, 43, + 2, 208, 104, 13, 43, 2, 146, 13, 43, 2, 206, 8, 13, 43, 2, 200, 43, 13, + 43, 2, 66, 13, 43, 2, 196, 12, 13, 43, 2, 193, 224, 13, 43, 2, 192, 235, + 13, 43, 2, 192, 159, 13, 43, 2, 191, 166, 13, 28, 43, 6, 65, 13, 28, 43, + 6, 250, 120, 13, 28, 43, 6, 247, 193, 13, 28, 43, 6, 238, 127, 13, 28, + 43, 6, 71, 13, 28, 43, 6, 233, 175, 13, 28, 43, 6, 232, 51, 13, 28, 43, + 6, 230, 116, 13, 28, 43, 6, 68, 13, 28, 43, 6, 223, 35, 13, 28, 43, 6, + 222, 152, 13, 28, 43, 6, 172, 13, 28, 43, 6, 218, 168, 13, 28, 43, 6, + 215, 61, 13, 28, 43, 6, 74, 13, 28, 43, 6, 210, 236, 13, 28, 43, 6, 208, + 104, 13, 28, 43, 6, 146, 13, 28, 43, 6, 206, 8, 13, 28, 43, 6, 200, 43, + 13, 28, 43, 6, 66, 13, 28, 43, 6, 196, 12, 13, 28, 43, 6, 193, 224, 13, 28, 43, 6, 192, 235, 13, 28, 43, 6, 192, 159, 13, 28, 43, 6, 191, 166, - 13, 28, 43, 2, 65, 13, 28, 43, 2, 250, 70, 13, 28, 43, 2, 247, 145, 13, - 28, 43, 2, 238, 80, 13, 28, 43, 2, 73, 13, 28, 43, 2, 233, 134, 13, 28, - 43, 2, 232, 14, 13, 28, 43, 2, 230, 83, 13, 28, 43, 2, 70, 13, 28, 43, 2, - 223, 7, 13, 28, 43, 2, 222, 125, 13, 28, 43, 2, 170, 13, 28, 43, 2, 218, - 147, 13, 28, 43, 2, 215, 47, 13, 28, 43, 2, 74, 13, 28, 43, 2, 210, 226, - 13, 28, 43, 2, 208, 97, 13, 28, 43, 2, 148, 13, 28, 43, 2, 206, 3, 13, - 28, 43, 2, 200, 39, 13, 28, 43, 2, 69, 13, 28, 43, 2, 196, 8, 13, 28, 43, - 2, 193, 221, 13, 28, 43, 2, 192, 235, 13, 28, 43, 2, 192, 159, 13, 28, - 43, 2, 191, 166, 13, 27, 6, 65, 13, 27, 6, 247, 145, 13, 27, 6, 238, 80, - 13, 27, 6, 232, 14, 13, 27, 6, 223, 7, 13, 27, 6, 222, 125, 13, 27, 6, - 215, 47, 13, 27, 6, 74, 13, 27, 6, 210, 226, 13, 27, 6, 208, 97, 13, 27, - 6, 206, 3, 13, 27, 6, 200, 39, 13, 27, 6, 69, 13, 27, 6, 196, 8, 13, 27, - 6, 193, 221, 13, 27, 6, 192, 235, 13, 27, 6, 192, 159, 13, 27, 6, 191, - 166, 13, 27, 2, 65, 13, 27, 2, 250, 70, 13, 27, 2, 247, 145, 13, 27, 2, - 238, 80, 13, 27, 2, 233, 134, 13, 27, 2, 230, 83, 13, 27, 2, 70, 13, 27, - 2, 223, 7, 13, 27, 2, 222, 125, 13, 27, 2, 170, 13, 27, 2, 218, 147, 13, - 27, 2, 215, 47, 13, 27, 2, 210, 226, 13, 27, 2, 208, 97, 13, 27, 2, 148, - 13, 27, 2, 206, 3, 13, 27, 2, 200, 39, 13, 27, 2, 69, 13, 27, 2, 196, 8, - 13, 27, 2, 193, 221, 13, 27, 2, 192, 235, 13, 27, 2, 192, 159, 13, 27, 2, - 191, 166, 13, 28, 27, 6, 65, 13, 28, 27, 6, 250, 70, 13, 28, 27, 6, 247, - 145, 13, 28, 27, 6, 238, 80, 13, 28, 27, 6, 73, 13, 28, 27, 6, 233, 134, - 13, 28, 27, 6, 232, 14, 13, 28, 27, 6, 230, 83, 13, 28, 27, 6, 70, 13, - 28, 27, 6, 223, 7, 13, 28, 27, 6, 222, 125, 13, 28, 27, 6, 170, 13, 28, - 27, 6, 218, 147, 13, 28, 27, 6, 215, 47, 13, 28, 27, 6, 74, 13, 28, 27, - 6, 210, 226, 13, 28, 27, 6, 208, 97, 13, 28, 27, 6, 148, 13, 28, 27, 6, - 206, 3, 13, 28, 27, 6, 200, 39, 13, 28, 27, 6, 69, 13, 28, 27, 6, 196, 8, - 13, 28, 27, 6, 193, 221, 13, 28, 27, 6, 192, 235, 13, 28, 27, 6, 192, - 159, 13, 28, 27, 6, 191, 166, 13, 28, 27, 2, 65, 13, 28, 27, 2, 250, 70, - 13, 28, 27, 2, 247, 145, 13, 28, 27, 2, 238, 80, 13, 28, 27, 2, 73, 13, - 28, 27, 2, 233, 134, 13, 28, 27, 2, 232, 14, 13, 28, 27, 2, 230, 83, 13, - 28, 27, 2, 70, 13, 28, 27, 2, 223, 7, 13, 28, 27, 2, 222, 125, 13, 28, - 27, 2, 170, 13, 28, 27, 2, 218, 147, 13, 28, 27, 2, 215, 47, 13, 28, 27, - 2, 74, 13, 28, 27, 2, 210, 226, 13, 28, 27, 2, 208, 97, 13, 28, 27, 2, - 148, 13, 28, 27, 2, 206, 3, 13, 28, 27, 2, 200, 39, 13, 28, 27, 2, 69, - 13, 28, 27, 2, 196, 8, 13, 28, 27, 2, 193, 221, 13, 28, 27, 2, 192, 235, - 13, 28, 27, 2, 192, 159, 13, 28, 27, 2, 191, 166, 13, 232, 77, 6, 65, 13, - 232, 77, 6, 250, 70, 13, 232, 77, 6, 238, 80, 13, 232, 77, 6, 73, 13, - 232, 77, 6, 233, 134, 13, 232, 77, 6, 232, 14, 13, 232, 77, 6, 223, 7, - 13, 232, 77, 6, 222, 125, 13, 232, 77, 6, 170, 13, 232, 77, 6, 218, 147, - 13, 232, 77, 6, 215, 47, 13, 232, 77, 6, 74, 13, 232, 77, 6, 210, 226, - 13, 232, 77, 6, 208, 97, 13, 232, 77, 6, 206, 3, 13, 232, 77, 6, 200, 39, - 13, 232, 77, 6, 69, 13, 232, 77, 6, 196, 8, 13, 232, 77, 6, 193, 221, 13, - 232, 77, 6, 192, 235, 13, 232, 77, 6, 192, 159, 13, 232, 77, 2, 65, 13, - 232, 77, 2, 250, 70, 13, 232, 77, 2, 247, 145, 13, 232, 77, 2, 238, 80, - 13, 232, 77, 2, 73, 13, 232, 77, 2, 233, 134, 13, 232, 77, 2, 232, 14, - 13, 232, 77, 2, 230, 83, 13, 232, 77, 2, 70, 13, 232, 77, 2, 223, 7, 13, - 232, 77, 2, 222, 125, 13, 232, 77, 2, 170, 13, 232, 77, 2, 218, 147, 13, - 232, 77, 2, 215, 47, 13, 232, 77, 2, 74, 13, 232, 77, 2, 210, 226, 13, - 232, 77, 2, 208, 97, 13, 232, 77, 2, 148, 13, 232, 77, 2, 206, 3, 13, - 232, 77, 2, 200, 39, 13, 232, 77, 2, 69, 13, 232, 77, 2, 196, 8, 13, 232, - 77, 2, 193, 221, 13, 232, 77, 2, 192, 235, 13, 232, 77, 2, 192, 159, 13, - 232, 77, 2, 191, 166, 13, 235, 85, 6, 65, 13, 235, 85, 6, 250, 70, 13, - 235, 85, 6, 238, 80, 13, 235, 85, 6, 73, 13, 235, 85, 6, 233, 134, 13, - 235, 85, 6, 232, 14, 13, 235, 85, 6, 70, 13, 235, 85, 6, 223, 7, 13, 235, - 85, 6, 222, 125, 13, 235, 85, 6, 170, 13, 235, 85, 6, 218, 147, 13, 235, - 85, 6, 74, 13, 235, 85, 6, 206, 3, 13, 235, 85, 6, 200, 39, 13, 235, 85, - 6, 69, 13, 235, 85, 6, 196, 8, 13, 235, 85, 6, 193, 221, 13, 235, 85, 6, - 192, 235, 13, 235, 85, 6, 192, 159, 13, 235, 85, 2, 65, 13, 235, 85, 2, - 250, 70, 13, 235, 85, 2, 247, 145, 13, 235, 85, 2, 238, 80, 13, 235, 85, - 2, 73, 13, 235, 85, 2, 233, 134, 13, 235, 85, 2, 232, 14, 13, 235, 85, 2, - 230, 83, 13, 235, 85, 2, 70, 13, 235, 85, 2, 223, 7, 13, 235, 85, 2, 222, - 125, 13, 235, 85, 2, 170, 13, 235, 85, 2, 218, 147, 13, 235, 85, 2, 215, - 47, 13, 235, 85, 2, 74, 13, 235, 85, 2, 210, 226, 13, 235, 85, 2, 208, - 97, 13, 235, 85, 2, 148, 13, 235, 85, 2, 206, 3, 13, 235, 85, 2, 200, 39, - 13, 235, 85, 2, 69, 13, 235, 85, 2, 196, 8, 13, 235, 85, 2, 193, 221, 13, - 235, 85, 2, 192, 235, 13, 235, 85, 2, 192, 159, 13, 235, 85, 2, 191, 166, - 13, 28, 232, 77, 6, 65, 13, 28, 232, 77, 6, 250, 70, 13, 28, 232, 77, 6, - 247, 145, 13, 28, 232, 77, 6, 238, 80, 13, 28, 232, 77, 6, 73, 13, 28, - 232, 77, 6, 233, 134, 13, 28, 232, 77, 6, 232, 14, 13, 28, 232, 77, 6, - 230, 83, 13, 28, 232, 77, 6, 70, 13, 28, 232, 77, 6, 223, 7, 13, 28, 232, - 77, 6, 222, 125, 13, 28, 232, 77, 6, 170, 13, 28, 232, 77, 6, 218, 147, - 13, 28, 232, 77, 6, 215, 47, 13, 28, 232, 77, 6, 74, 13, 28, 232, 77, 6, - 210, 226, 13, 28, 232, 77, 6, 208, 97, 13, 28, 232, 77, 6, 148, 13, 28, - 232, 77, 6, 206, 3, 13, 28, 232, 77, 6, 200, 39, 13, 28, 232, 77, 6, 69, - 13, 28, 232, 77, 6, 196, 8, 13, 28, 232, 77, 6, 193, 221, 13, 28, 232, - 77, 6, 192, 235, 13, 28, 232, 77, 6, 192, 159, 13, 28, 232, 77, 6, 191, - 166, 13, 28, 232, 77, 2, 65, 13, 28, 232, 77, 2, 250, 70, 13, 28, 232, - 77, 2, 247, 145, 13, 28, 232, 77, 2, 238, 80, 13, 28, 232, 77, 2, 73, 13, - 28, 232, 77, 2, 233, 134, 13, 28, 232, 77, 2, 232, 14, 13, 28, 232, 77, - 2, 230, 83, 13, 28, 232, 77, 2, 70, 13, 28, 232, 77, 2, 223, 7, 13, 28, - 232, 77, 2, 222, 125, 13, 28, 232, 77, 2, 170, 13, 28, 232, 77, 2, 218, - 147, 13, 28, 232, 77, 2, 215, 47, 13, 28, 232, 77, 2, 74, 13, 28, 232, - 77, 2, 210, 226, 13, 28, 232, 77, 2, 208, 97, 13, 28, 232, 77, 2, 148, - 13, 28, 232, 77, 2, 206, 3, 13, 28, 232, 77, 2, 200, 39, 13, 28, 232, 77, - 2, 69, 13, 28, 232, 77, 2, 196, 8, 13, 28, 232, 77, 2, 193, 221, 13, 28, - 232, 77, 2, 192, 235, 13, 28, 232, 77, 2, 192, 159, 13, 28, 232, 77, 2, - 191, 166, 13, 49, 6, 65, 13, 49, 6, 250, 70, 13, 49, 6, 247, 145, 13, 49, - 6, 238, 80, 13, 49, 6, 73, 13, 49, 6, 233, 134, 13, 49, 6, 232, 14, 13, - 49, 6, 230, 83, 13, 49, 6, 70, 13, 49, 6, 223, 7, 13, 49, 6, 222, 125, - 13, 49, 6, 170, 13, 49, 6, 218, 147, 13, 49, 6, 215, 47, 13, 49, 6, 74, - 13, 49, 6, 210, 226, 13, 49, 6, 208, 97, 13, 49, 6, 148, 13, 49, 6, 206, - 3, 13, 49, 6, 200, 39, 13, 49, 6, 69, 13, 49, 6, 196, 8, 13, 49, 6, 193, - 221, 13, 49, 6, 192, 235, 13, 49, 6, 192, 159, 13, 49, 6, 191, 166, 13, - 49, 2, 65, 13, 49, 2, 250, 70, 13, 49, 2, 247, 145, 13, 49, 2, 238, 80, - 13, 49, 2, 73, 13, 49, 2, 233, 134, 13, 49, 2, 232, 14, 13, 49, 2, 230, - 83, 13, 49, 2, 70, 13, 49, 2, 223, 7, 13, 49, 2, 222, 125, 13, 49, 2, - 170, 13, 49, 2, 218, 147, 13, 49, 2, 215, 47, 13, 49, 2, 74, 13, 49, 2, - 210, 226, 13, 49, 2, 208, 97, 13, 49, 2, 148, 13, 49, 2, 206, 3, 13, 49, - 2, 200, 39, 13, 49, 2, 69, 13, 49, 2, 196, 8, 13, 49, 2, 193, 221, 13, - 49, 2, 192, 235, 13, 49, 2, 192, 159, 13, 49, 2, 191, 166, 13, 49, 28, 6, - 65, 13, 49, 28, 6, 250, 70, 13, 49, 28, 6, 247, 145, 13, 49, 28, 6, 238, - 80, 13, 49, 28, 6, 73, 13, 49, 28, 6, 233, 134, 13, 49, 28, 6, 232, 14, - 13, 49, 28, 6, 230, 83, 13, 49, 28, 6, 70, 13, 49, 28, 6, 223, 7, 13, 49, - 28, 6, 222, 125, 13, 49, 28, 6, 170, 13, 49, 28, 6, 218, 147, 13, 49, 28, - 6, 215, 47, 13, 49, 28, 6, 74, 13, 49, 28, 6, 210, 226, 13, 49, 28, 6, - 208, 97, 13, 49, 28, 6, 148, 13, 49, 28, 6, 206, 3, 13, 49, 28, 6, 200, - 39, 13, 49, 28, 6, 69, 13, 49, 28, 6, 196, 8, 13, 49, 28, 6, 193, 221, - 13, 49, 28, 6, 192, 235, 13, 49, 28, 6, 192, 159, 13, 49, 28, 6, 191, - 166, 13, 49, 28, 2, 65, 13, 49, 28, 2, 250, 70, 13, 49, 28, 2, 247, 145, - 13, 49, 28, 2, 238, 80, 13, 49, 28, 2, 73, 13, 49, 28, 2, 233, 134, 13, - 49, 28, 2, 232, 14, 13, 49, 28, 2, 230, 83, 13, 49, 28, 2, 70, 13, 49, - 28, 2, 223, 7, 13, 49, 28, 2, 222, 125, 13, 49, 28, 2, 170, 13, 49, 28, - 2, 218, 147, 13, 49, 28, 2, 215, 47, 13, 49, 28, 2, 74, 13, 49, 28, 2, - 210, 226, 13, 49, 28, 2, 208, 97, 13, 49, 28, 2, 148, 13, 49, 28, 2, 206, - 3, 13, 49, 28, 2, 200, 39, 13, 49, 28, 2, 69, 13, 49, 28, 2, 196, 8, 13, - 49, 28, 2, 193, 221, 13, 49, 28, 2, 192, 235, 13, 49, 28, 2, 192, 159, - 13, 49, 28, 2, 191, 166, 13, 49, 43, 6, 65, 13, 49, 43, 6, 250, 70, 13, - 49, 43, 6, 247, 145, 13, 49, 43, 6, 238, 80, 13, 49, 43, 6, 73, 13, 49, - 43, 6, 233, 134, 13, 49, 43, 6, 232, 14, 13, 49, 43, 6, 230, 83, 13, 49, - 43, 6, 70, 13, 49, 43, 6, 223, 7, 13, 49, 43, 6, 222, 125, 13, 49, 43, 6, - 170, 13, 49, 43, 6, 218, 147, 13, 49, 43, 6, 215, 47, 13, 49, 43, 6, 74, - 13, 49, 43, 6, 210, 226, 13, 49, 43, 6, 208, 97, 13, 49, 43, 6, 148, 13, - 49, 43, 6, 206, 3, 13, 49, 43, 6, 200, 39, 13, 49, 43, 6, 69, 13, 49, 43, - 6, 196, 8, 13, 49, 43, 6, 193, 221, 13, 49, 43, 6, 192, 235, 13, 49, 43, - 6, 192, 159, 13, 49, 43, 6, 191, 166, 13, 49, 43, 2, 65, 13, 49, 43, 2, - 250, 70, 13, 49, 43, 2, 247, 145, 13, 49, 43, 2, 238, 80, 13, 49, 43, 2, - 73, 13, 49, 43, 2, 233, 134, 13, 49, 43, 2, 232, 14, 13, 49, 43, 2, 230, - 83, 13, 49, 43, 2, 70, 13, 49, 43, 2, 223, 7, 13, 49, 43, 2, 222, 125, - 13, 49, 43, 2, 170, 13, 49, 43, 2, 218, 147, 13, 49, 43, 2, 215, 47, 13, - 49, 43, 2, 74, 13, 49, 43, 2, 210, 226, 13, 49, 43, 2, 208, 97, 13, 49, - 43, 2, 148, 13, 49, 43, 2, 206, 3, 13, 49, 43, 2, 200, 39, 13, 49, 43, 2, - 69, 13, 49, 43, 2, 196, 8, 13, 49, 43, 2, 193, 221, 13, 49, 43, 2, 192, - 235, 13, 49, 43, 2, 192, 159, 13, 49, 43, 2, 191, 166, 13, 49, 28, 43, 6, - 65, 13, 49, 28, 43, 6, 250, 70, 13, 49, 28, 43, 6, 247, 145, 13, 49, 28, - 43, 6, 238, 80, 13, 49, 28, 43, 6, 73, 13, 49, 28, 43, 6, 233, 134, 13, - 49, 28, 43, 6, 232, 14, 13, 49, 28, 43, 6, 230, 83, 13, 49, 28, 43, 6, - 70, 13, 49, 28, 43, 6, 223, 7, 13, 49, 28, 43, 6, 222, 125, 13, 49, 28, - 43, 6, 170, 13, 49, 28, 43, 6, 218, 147, 13, 49, 28, 43, 6, 215, 47, 13, - 49, 28, 43, 6, 74, 13, 49, 28, 43, 6, 210, 226, 13, 49, 28, 43, 6, 208, - 97, 13, 49, 28, 43, 6, 148, 13, 49, 28, 43, 6, 206, 3, 13, 49, 28, 43, 6, - 200, 39, 13, 49, 28, 43, 6, 69, 13, 49, 28, 43, 6, 196, 8, 13, 49, 28, - 43, 6, 193, 221, 13, 49, 28, 43, 6, 192, 235, 13, 49, 28, 43, 6, 192, - 159, 13, 49, 28, 43, 6, 191, 166, 13, 49, 28, 43, 2, 65, 13, 49, 28, 43, - 2, 250, 70, 13, 49, 28, 43, 2, 247, 145, 13, 49, 28, 43, 2, 238, 80, 13, - 49, 28, 43, 2, 73, 13, 49, 28, 43, 2, 233, 134, 13, 49, 28, 43, 2, 232, - 14, 13, 49, 28, 43, 2, 230, 83, 13, 49, 28, 43, 2, 70, 13, 49, 28, 43, 2, - 223, 7, 13, 49, 28, 43, 2, 222, 125, 13, 49, 28, 43, 2, 170, 13, 49, 28, - 43, 2, 218, 147, 13, 49, 28, 43, 2, 215, 47, 13, 49, 28, 43, 2, 74, 13, - 49, 28, 43, 2, 210, 226, 13, 49, 28, 43, 2, 208, 97, 13, 49, 28, 43, 2, - 148, 13, 49, 28, 43, 2, 206, 3, 13, 49, 28, 43, 2, 200, 39, 13, 49, 28, - 43, 2, 69, 13, 49, 28, 43, 2, 196, 8, 13, 49, 28, 43, 2, 193, 221, 13, - 49, 28, 43, 2, 192, 235, 13, 49, 28, 43, 2, 192, 159, 13, 49, 28, 43, 2, - 191, 166, 13, 215, 200, 6, 65, 13, 215, 200, 6, 250, 70, 13, 215, 200, 6, - 247, 145, 13, 215, 200, 6, 238, 80, 13, 215, 200, 6, 73, 13, 215, 200, 6, - 233, 134, 13, 215, 200, 6, 232, 14, 13, 215, 200, 6, 230, 83, 13, 215, - 200, 6, 70, 13, 215, 200, 6, 223, 7, 13, 215, 200, 6, 222, 125, 13, 215, - 200, 6, 170, 13, 215, 200, 6, 218, 147, 13, 215, 200, 6, 215, 47, 13, - 215, 200, 6, 74, 13, 215, 200, 6, 210, 226, 13, 215, 200, 6, 208, 97, 13, - 215, 200, 6, 148, 13, 215, 200, 6, 206, 3, 13, 215, 200, 6, 200, 39, 13, - 215, 200, 6, 69, 13, 215, 200, 6, 196, 8, 13, 215, 200, 6, 193, 221, 13, - 215, 200, 6, 192, 235, 13, 215, 200, 6, 192, 159, 13, 215, 200, 6, 191, - 166, 13, 215, 200, 2, 65, 13, 215, 200, 2, 250, 70, 13, 215, 200, 2, 247, - 145, 13, 215, 200, 2, 238, 80, 13, 215, 200, 2, 73, 13, 215, 200, 2, 233, - 134, 13, 215, 200, 2, 232, 14, 13, 215, 200, 2, 230, 83, 13, 215, 200, 2, - 70, 13, 215, 200, 2, 223, 7, 13, 215, 200, 2, 222, 125, 13, 215, 200, 2, - 170, 13, 215, 200, 2, 218, 147, 13, 215, 200, 2, 215, 47, 13, 215, 200, - 2, 74, 13, 215, 200, 2, 210, 226, 13, 215, 200, 2, 208, 97, 13, 215, 200, - 2, 148, 13, 215, 200, 2, 206, 3, 13, 215, 200, 2, 200, 39, 13, 215, 200, - 2, 69, 13, 215, 200, 2, 196, 8, 13, 215, 200, 2, 193, 221, 13, 215, 200, - 2, 192, 235, 13, 215, 200, 2, 192, 159, 13, 215, 200, 2, 191, 166, 13, - 43, 2, 236, 95, 70, 13, 43, 2, 236, 95, 223, 7, 13, 28, 6, 251, 109, 13, - 28, 6, 248, 162, 13, 28, 6, 231, 174, 13, 28, 6, 237, 61, 13, 28, 6, 234, - 5, 13, 28, 6, 191, 76, 13, 28, 6, 233, 211, 13, 28, 6, 199, 10, 13, 28, - 6, 223, 55, 13, 28, 6, 222, 46, 13, 28, 6, 220, 7, 13, 28, 6, 215, 139, - 13, 28, 6, 212, 165, 13, 28, 6, 192, 207, 13, 28, 6, 211, 96, 13, 28, 6, - 209, 176, 13, 28, 6, 206, 254, 13, 28, 6, 199, 11, 113, 13, 28, 6, 202, - 191, 13, 28, 6, 199, 161, 13, 28, 6, 196, 66, 13, 28, 6, 209, 202, 13, - 28, 6, 243, 47, 13, 28, 6, 208, 169, 13, 28, 6, 211, 99, 13, 28, 214, - 231, 13, 28, 2, 251, 109, 13, 28, 2, 248, 162, 13, 28, 2, 231, 174, 13, - 28, 2, 237, 61, 13, 28, 2, 234, 5, 13, 28, 2, 191, 76, 13, 28, 2, 233, - 211, 13, 28, 2, 199, 10, 13, 28, 2, 223, 55, 13, 28, 2, 222, 46, 13, 28, - 2, 220, 7, 13, 28, 2, 215, 139, 13, 28, 2, 212, 165, 13, 28, 2, 192, 207, - 13, 28, 2, 211, 96, 13, 28, 2, 209, 176, 13, 28, 2, 206, 254, 13, 28, 2, - 52, 202, 191, 13, 28, 2, 202, 191, 13, 28, 2, 199, 161, 13, 28, 2, 196, - 66, 13, 28, 2, 209, 202, 13, 28, 2, 243, 47, 13, 28, 2, 208, 169, 13, 28, - 2, 211, 99, 13, 28, 210, 95, 236, 227, 13, 28, 234, 6, 113, 13, 28, 199, - 11, 113, 13, 28, 222, 47, 113, 13, 28, 209, 203, 113, 13, 28, 206, 255, - 113, 13, 28, 209, 177, 113, 13, 43, 6, 251, 109, 13, 43, 6, 248, 162, 13, - 43, 6, 231, 174, 13, 43, 6, 237, 61, 13, 43, 6, 234, 5, 13, 43, 6, 191, - 76, 13, 43, 6, 233, 211, 13, 43, 6, 199, 10, 13, 43, 6, 223, 55, 13, 43, - 6, 222, 46, 13, 43, 6, 220, 7, 13, 43, 6, 215, 139, 13, 43, 6, 212, 165, - 13, 43, 6, 192, 207, 13, 43, 6, 211, 96, 13, 43, 6, 209, 176, 13, 43, 6, - 206, 254, 13, 43, 6, 199, 11, 113, 13, 43, 6, 202, 191, 13, 43, 6, 199, - 161, 13, 43, 6, 196, 66, 13, 43, 6, 209, 202, 13, 43, 6, 243, 47, 13, 43, - 6, 208, 169, 13, 43, 6, 211, 99, 13, 43, 214, 231, 13, 43, 2, 251, 109, - 13, 43, 2, 248, 162, 13, 43, 2, 231, 174, 13, 43, 2, 237, 61, 13, 43, 2, - 234, 5, 13, 43, 2, 191, 76, 13, 43, 2, 233, 211, 13, 43, 2, 199, 10, 13, - 43, 2, 223, 55, 13, 43, 2, 222, 46, 13, 43, 2, 220, 7, 13, 43, 2, 215, - 139, 13, 43, 2, 212, 165, 13, 43, 2, 192, 207, 13, 43, 2, 211, 96, 13, - 43, 2, 209, 176, 13, 43, 2, 206, 254, 13, 43, 2, 52, 202, 191, 13, 43, 2, - 202, 191, 13, 43, 2, 199, 161, 13, 43, 2, 196, 66, 13, 43, 2, 209, 202, - 13, 43, 2, 243, 47, 13, 43, 2, 208, 169, 13, 43, 2, 211, 99, 13, 43, 210, - 95, 236, 227, 13, 43, 234, 6, 113, 13, 43, 199, 11, 113, 13, 43, 222, 47, - 113, 13, 43, 209, 203, 113, 13, 43, 206, 255, 113, 13, 43, 209, 177, 113, - 13, 28, 43, 6, 251, 109, 13, 28, 43, 6, 248, 162, 13, 28, 43, 6, 231, - 174, 13, 28, 43, 6, 237, 61, 13, 28, 43, 6, 234, 5, 13, 28, 43, 6, 191, - 76, 13, 28, 43, 6, 233, 211, 13, 28, 43, 6, 199, 10, 13, 28, 43, 6, 223, - 55, 13, 28, 43, 6, 222, 46, 13, 28, 43, 6, 220, 7, 13, 28, 43, 6, 215, - 139, 13, 28, 43, 6, 212, 165, 13, 28, 43, 6, 192, 207, 13, 28, 43, 6, - 211, 96, 13, 28, 43, 6, 209, 176, 13, 28, 43, 6, 206, 254, 13, 28, 43, 6, - 199, 11, 113, 13, 28, 43, 6, 202, 191, 13, 28, 43, 6, 199, 161, 13, 28, - 43, 6, 196, 66, 13, 28, 43, 6, 209, 202, 13, 28, 43, 6, 243, 47, 13, 28, - 43, 6, 208, 169, 13, 28, 43, 6, 211, 99, 13, 28, 43, 214, 231, 13, 28, - 43, 2, 251, 109, 13, 28, 43, 2, 248, 162, 13, 28, 43, 2, 231, 174, 13, - 28, 43, 2, 237, 61, 13, 28, 43, 2, 234, 5, 13, 28, 43, 2, 191, 76, 13, - 28, 43, 2, 233, 211, 13, 28, 43, 2, 199, 10, 13, 28, 43, 2, 223, 55, 13, - 28, 43, 2, 222, 46, 13, 28, 43, 2, 220, 7, 13, 28, 43, 2, 215, 139, 13, - 28, 43, 2, 212, 165, 13, 28, 43, 2, 192, 207, 13, 28, 43, 2, 211, 96, 13, - 28, 43, 2, 209, 176, 13, 28, 43, 2, 206, 254, 13, 28, 43, 2, 52, 202, - 191, 13, 28, 43, 2, 202, 191, 13, 28, 43, 2, 199, 161, 13, 28, 43, 2, - 196, 66, 13, 28, 43, 2, 209, 202, 13, 28, 43, 2, 243, 47, 13, 28, 43, 2, - 208, 169, 13, 28, 43, 2, 211, 99, 13, 28, 43, 210, 95, 236, 227, 13, 28, - 43, 234, 6, 113, 13, 28, 43, 199, 11, 113, 13, 28, 43, 222, 47, 113, 13, - 28, 43, 209, 203, 113, 13, 28, 43, 206, 255, 113, 13, 28, 43, 209, 177, - 113, 13, 49, 28, 6, 251, 109, 13, 49, 28, 6, 248, 162, 13, 49, 28, 6, - 231, 174, 13, 49, 28, 6, 237, 61, 13, 49, 28, 6, 234, 5, 13, 49, 28, 6, - 191, 76, 13, 49, 28, 6, 233, 211, 13, 49, 28, 6, 199, 10, 13, 49, 28, 6, - 223, 55, 13, 49, 28, 6, 222, 46, 13, 49, 28, 6, 220, 7, 13, 49, 28, 6, - 215, 139, 13, 49, 28, 6, 212, 165, 13, 49, 28, 6, 192, 207, 13, 49, 28, - 6, 211, 96, 13, 49, 28, 6, 209, 176, 13, 49, 28, 6, 206, 254, 13, 49, 28, - 6, 199, 11, 113, 13, 49, 28, 6, 202, 191, 13, 49, 28, 6, 199, 161, 13, - 49, 28, 6, 196, 66, 13, 49, 28, 6, 209, 202, 13, 49, 28, 6, 243, 47, 13, - 49, 28, 6, 208, 169, 13, 49, 28, 6, 211, 99, 13, 49, 28, 214, 231, 13, - 49, 28, 2, 251, 109, 13, 49, 28, 2, 248, 162, 13, 49, 28, 2, 231, 174, - 13, 49, 28, 2, 237, 61, 13, 49, 28, 2, 234, 5, 13, 49, 28, 2, 191, 76, - 13, 49, 28, 2, 233, 211, 13, 49, 28, 2, 199, 10, 13, 49, 28, 2, 223, 55, - 13, 49, 28, 2, 222, 46, 13, 49, 28, 2, 220, 7, 13, 49, 28, 2, 215, 139, - 13, 49, 28, 2, 212, 165, 13, 49, 28, 2, 192, 207, 13, 49, 28, 2, 211, 96, - 13, 49, 28, 2, 209, 176, 13, 49, 28, 2, 206, 254, 13, 49, 28, 2, 52, 202, - 191, 13, 49, 28, 2, 202, 191, 13, 49, 28, 2, 199, 161, 13, 49, 28, 2, - 196, 66, 13, 49, 28, 2, 209, 202, 13, 49, 28, 2, 243, 47, 13, 49, 28, 2, - 208, 169, 13, 49, 28, 2, 211, 99, 13, 49, 28, 210, 95, 236, 227, 13, 49, - 28, 234, 6, 113, 13, 49, 28, 199, 11, 113, 13, 49, 28, 222, 47, 113, 13, - 49, 28, 209, 203, 113, 13, 49, 28, 206, 255, 113, 13, 49, 28, 209, 177, - 113, 13, 49, 28, 43, 6, 251, 109, 13, 49, 28, 43, 6, 248, 162, 13, 49, - 28, 43, 6, 231, 174, 13, 49, 28, 43, 6, 237, 61, 13, 49, 28, 43, 6, 234, - 5, 13, 49, 28, 43, 6, 191, 76, 13, 49, 28, 43, 6, 233, 211, 13, 49, 28, - 43, 6, 199, 10, 13, 49, 28, 43, 6, 223, 55, 13, 49, 28, 43, 6, 222, 46, - 13, 49, 28, 43, 6, 220, 7, 13, 49, 28, 43, 6, 215, 139, 13, 49, 28, 43, - 6, 212, 165, 13, 49, 28, 43, 6, 192, 207, 13, 49, 28, 43, 6, 211, 96, 13, - 49, 28, 43, 6, 209, 176, 13, 49, 28, 43, 6, 206, 254, 13, 49, 28, 43, 6, - 199, 11, 113, 13, 49, 28, 43, 6, 202, 191, 13, 49, 28, 43, 6, 199, 161, - 13, 49, 28, 43, 6, 196, 66, 13, 49, 28, 43, 6, 209, 202, 13, 49, 28, 43, - 6, 243, 47, 13, 49, 28, 43, 6, 208, 169, 13, 49, 28, 43, 6, 211, 99, 13, - 49, 28, 43, 214, 231, 13, 49, 28, 43, 2, 251, 109, 13, 49, 28, 43, 2, - 248, 162, 13, 49, 28, 43, 2, 231, 174, 13, 49, 28, 43, 2, 237, 61, 13, - 49, 28, 43, 2, 234, 5, 13, 49, 28, 43, 2, 191, 76, 13, 49, 28, 43, 2, - 233, 211, 13, 49, 28, 43, 2, 199, 10, 13, 49, 28, 43, 2, 223, 55, 13, 49, - 28, 43, 2, 222, 46, 13, 49, 28, 43, 2, 220, 7, 13, 49, 28, 43, 2, 215, - 139, 13, 49, 28, 43, 2, 212, 165, 13, 49, 28, 43, 2, 192, 207, 13, 49, - 28, 43, 2, 211, 96, 13, 49, 28, 43, 2, 209, 176, 13, 49, 28, 43, 2, 206, - 254, 13, 49, 28, 43, 2, 52, 202, 191, 13, 49, 28, 43, 2, 202, 191, 13, - 49, 28, 43, 2, 199, 161, 13, 49, 28, 43, 2, 196, 66, 13, 49, 28, 43, 2, - 209, 202, 13, 49, 28, 43, 2, 243, 47, 13, 49, 28, 43, 2, 208, 169, 13, - 49, 28, 43, 2, 211, 99, 13, 49, 28, 43, 210, 95, 236, 227, 13, 49, 28, - 43, 234, 6, 113, 13, 49, 28, 43, 199, 11, 113, 13, 49, 28, 43, 222, 47, - 113, 13, 49, 28, 43, 209, 203, 113, 13, 49, 28, 43, 206, 255, 113, 13, - 49, 28, 43, 209, 177, 113, 13, 28, 6, 236, 221, 13, 28, 2, 236, 221, 13, - 28, 17, 191, 77, 13, 28, 17, 108, 13, 28, 17, 109, 13, 28, 17, 139, 13, - 28, 17, 137, 13, 28, 17, 153, 13, 28, 17, 173, 13, 28, 17, 181, 13, 28, - 17, 176, 13, 28, 17, 184, 13, 235, 85, 17, 191, 77, 13, 235, 85, 17, 108, - 13, 235, 85, 17, 109, 13, 235, 85, 17, 139, 13, 235, 85, 17, 137, 13, - 235, 85, 17, 153, 13, 235, 85, 17, 173, 13, 235, 85, 17, 181, 13, 235, - 85, 17, 176, 13, 235, 85, 17, 184, 13, 49, 17, 191, 77, 13, 49, 17, 108, - 13, 49, 17, 109, 13, 49, 17, 139, 13, 49, 17, 137, 13, 49, 17, 153, 13, - 49, 17, 173, 13, 49, 17, 181, 13, 49, 17, 176, 13, 49, 17, 184, 13, 49, - 28, 17, 191, 77, 13, 49, 28, 17, 108, 13, 49, 28, 17, 109, 13, 49, 28, - 17, 139, 13, 49, 28, 17, 137, 13, 49, 28, 17, 153, 13, 49, 28, 17, 173, - 13, 49, 28, 17, 181, 13, 49, 28, 17, 176, 13, 49, 28, 17, 184, 13, 215, - 200, 17, 191, 77, 13, 215, 200, 17, 108, 13, 215, 200, 17, 109, 13, 215, - 200, 17, 139, 13, 215, 200, 17, 137, 13, 215, 200, 17, 153, 13, 215, 200, - 17, 173, 13, 215, 200, 17, 181, 13, 215, 200, 17, 176, 13, 215, 200, 17, - 184, 23, 150, 223, 120, 23, 230, 17, 223, 120, 23, 230, 13, 223, 120, 23, - 230, 2, 223, 120, 23, 230, 6, 223, 120, 23, 230, 19, 223, 120, 23, 150, - 140, 248, 173, 23, 230, 17, 140, 248, 173, 23, 150, 174, 196, 101, 140, - 248, 173, 23, 150, 140, 207, 142, 221, 46, 23, 150, 140, 238, 130, 23, - 150, 140, 229, 92, 23, 150, 140, 229, 93, 218, 219, 23, 230, 17, 140, - 229, 94, 23, 150, 140, 216, 66, 23, 230, 17, 140, 216, 66, 23, 150, 140, - 82, 248, 173, 23, 150, 140, 82, 207, 142, 221, 45, 23, 150, 140, 82, 229, - 92, 23, 150, 140, 132, 82, 229, 92, 23, 150, 140, 229, 93, 82, 196, 73, - 23, 150, 140, 82, 238, 254, 23, 150, 140, 82, 238, 255, 140, 248, 173, - 23, 150, 140, 82, 238, 255, 82, 248, 173, 23, 150, 140, 82, 238, 255, - 238, 130, 23, 150, 140, 82, 238, 255, 229, 92, 23, 150, 140, 82, 238, - 166, 23, 230, 17, 140, 82, 238, 166, 23, 150, 82, 248, 174, 138, 223, - 120, 23, 150, 140, 248, 174, 138, 216, 66, 23, 150, 140, 82, 198, 207, - 23, 230, 17, 140, 82, 198, 207, 23, 150, 140, 82, 201, 48, 174, 248, 173, - 23, 150, 140, 82, 248, 174, 174, 201, 47, 23, 150, 140, 82, 174, 248, - 173, 23, 150, 140, 82, 229, 93, 201, 194, 174, 202, 202, 23, 150, 140, - 132, 82, 229, 93, 174, 202, 202, 23, 150, 140, 132, 82, 229, 93, 174, - 238, 254, 23, 150, 140, 229, 93, 82, 132, 174, 202, 202, 23, 150, 140, - 82, 132, 201, 194, 174, 232, 94, 23, 150, 140, 82, 174, 238, 130, 23, - 150, 140, 82, 174, 242, 217, 23, 150, 140, 82, 174, 228, 217, 23, 150, - 140, 82, 174, 229, 92, 23, 150, 174, 248, 160, 140, 82, 201, 47, 23, 150, - 140, 82, 238, 255, 174, 202, 202, 23, 150, 140, 82, 238, 255, 174, 202, - 203, 238, 254, 23, 150, 140, 82, 238, 255, 174, 202, 203, 248, 173, 23, - 150, 82, 174, 228, 218, 140, 196, 73, 23, 150, 140, 174, 228, 218, 82, - 196, 73, 23, 150, 140, 82, 238, 255, 229, 93, 174, 202, 202, 23, 150, - 140, 82, 238, 167, 174, 202, 202, 23, 150, 140, 82, 238, 255, 174, 232, - 94, 23, 150, 140, 82, 238, 255, 238, 131, 174, 232, 94, 23, 150, 82, 174, - 238, 131, 140, 196, 73, 23, 150, 140, 174, 238, 131, 82, 196, 73, 23, - 150, 82, 174, 47, 140, 196, 73, 23, 150, 82, 174, 47, 140, 229, 92, 23, - 150, 140, 174, 251, 63, 211, 5, 82, 196, 73, 23, 150, 140, 174, 251, 63, - 223, 135, 82, 196, 73, 23, 150, 140, 174, 47, 82, 196, 73, 23, 150, 140, - 82, 174, 238, 255, 229, 92, 23, 150, 140, 82, 174, 251, 63, 211, 4, 23, - 150, 140, 82, 174, 251, 62, 23, 150, 82, 174, 251, 63, 211, 5, 140, 196, - 73, 23, 150, 82, 174, 251, 63, 211, 5, 140, 238, 166, 23, 150, 82, 174, - 251, 63, 140, 196, 73, 23, 150, 140, 174, 228, 218, 82, 229, 92, 23, 230, - 8, 232, 90, 232, 206, 23, 230, 8, 232, 90, 232, 207, 248, 173, 23, 230, - 8, 232, 90, 232, 207, 229, 92, 23, 230, 8, 232, 90, 232, 207, 238, 254, - 23, 230, 8, 232, 90, 232, 207, 238, 255, 201, 204, 23, 230, 15, 232, 90, - 232, 207, 238, 254, 23, 150, 232, 90, 232, 207, 238, 255, 248, 173, 23, - 230, 6, 232, 90, 232, 207, 238, 254, 23, 230, 8, 232, 185, 232, 207, 201, - 193, 23, 230, 8, 229, 181, 232, 185, 232, 207, 201, 193, 23, 230, 8, 232, - 185, 232, 207, 201, 194, 232, 90, 248, 173, 23, 230, 8, 229, 181, 232, - 185, 232, 207, 201, 194, 232, 90, 248, 173, 23, 230, 8, 232, 185, 232, - 207, 201, 194, 248, 173, 23, 230, 8, 229, 181, 232, 185, 232, 207, 201, - 194, 248, 173, 23, 230, 8, 232, 185, 232, 207, 201, 194, 174, 232, 94, - 23, 230, 13, 232, 185, 232, 207, 201, 193, 23, 230, 13, 232, 185, 232, - 207, 201, 194, 211, 65, 23, 230, 6, 232, 185, 232, 207, 201, 194, 211, - 65, 23, 230, 2, 232, 185, 232, 207, 201, 193, 23, 230, 8, 232, 185, 232, - 207, 201, 194, 229, 92, 23, 230, 8, 232, 185, 232, 207, 201, 194, 229, - 93, 174, 202, 202, 23, 230, 8, 232, 185, 232, 207, 201, 194, 229, 93, - 213, 31, 198, 207, 23, 230, 7, 23, 230, 8, 248, 160, 210, 173, 233, 54, - 23, 230, 8, 229, 180, 23, 230, 8, 174, 202, 202, 23, 230, 8, 229, 181, - 174, 202, 202, 23, 230, 8, 174, 248, 173, 23, 230, 8, 174, 232, 94, 23, - 230, 8, 201, 205, 140, 174, 202, 202, 23, 230, 8, 201, 205, 246, 229, 23, - 230, 8, 201, 205, 246, 230, 174, 202, 202, 23, 230, 8, 201, 205, 246, - 230, 174, 202, 203, 248, 173, 23, 230, 8, 201, 205, 219, 58, 23, 230, 14, - 23, 230, 15, 174, 202, 202, 23, 230, 15, 213, 31, 198, 207, 23, 230, 15, - 174, 232, 94, 23, 230, 4, 238, 126, 23, 230, 3, 23, 230, 13, 211, 65, 23, - 230, 12, 23, 230, 13, 211, 66, 174, 202, 202, 23, 230, 13, 174, 202, 202, - 23, 230, 13, 211, 66, 213, 31, 198, 207, 23, 230, 13, 213, 31, 198, 207, - 23, 230, 13, 211, 66, 174, 232, 94, 23, 230, 13, 174, 232, 94, 23, 230, - 11, 211, 65, 23, 230, 10, 23, 230, 16, 23, 230, 1, 23, 230, 2, 174, 202, - 202, 23, 230, 2, 213, 31, 198, 207, 23, 230, 2, 174, 232, 94, 23, 230, 6, - 211, 65, 23, 230, 6, 211, 66, 174, 232, 94, 23, 230, 5, 23, 230, 6, 202, - 65, 23, 230, 6, 211, 66, 174, 202, 202, 23, 230, 6, 174, 202, 202, 23, - 230, 6, 211, 66, 213, 31, 198, 207, 23, 230, 6, 213, 31, 198, 207, 23, - 230, 6, 174, 202, 203, 198, 30, 223, 120, 23, 230, 6, 174, 248, 160, 82, - 206, 183, 23, 230, 18, 23, 150, 140, 82, 206, 183, 23, 230, 17, 140, 82, - 206, 183, 23, 230, 6, 140, 82, 206, 183, 23, 230, 19, 140, 82, 206, 183, - 23, 230, 6, 219, 58, 23, 150, 140, 82, 206, 184, 248, 173, 23, 150, 140, - 82, 206, 184, 238, 254, 23, 230, 6, 140, 82, 206, 184, 238, 254, 23, 150, - 219, 59, 235, 79, 23, 150, 219, 59, 143, 206, 178, 201, 47, 23, 150, 219, - 59, 143, 206, 178, 238, 115, 23, 150, 219, 59, 143, 211, 16, 242, 217, - 23, 150, 219, 59, 196, 73, 23, 150, 174, 196, 101, 219, 59, 196, 73, 23, - 230, 17, 219, 59, 196, 73, 23, 230, 2, 219, 59, 196, 73, 23, 230, 19, - 219, 59, 196, 73, 23, 150, 219, 59, 207, 142, 221, 46, 23, 150, 219, 59, - 248, 173, 23, 150, 219, 59, 198, 31, 198, 207, 23, 150, 219, 59, 198, - 207, 23, 230, 6, 219, 59, 198, 207, 23, 150, 219, 59, 140, 198, 207, 23, - 230, 6, 219, 59, 140, 198, 207, 23, 230, 19, 219, 59, 140, 174, 140, 174, - 211, 4, 23, 230, 19, 219, 59, 140, 174, 140, 198, 207, 23, 150, 219, 59, - 223, 120, 23, 230, 17, 219, 59, 223, 120, 23, 230, 6, 219, 59, 223, 120, - 23, 230, 19, 219, 59, 223, 120, 23, 150, 140, 82, 219, 58, 23, 230, 17, - 140, 82, 219, 58, 23, 230, 6, 140, 82, 219, 58, 23, 230, 6, 206, 183, 23, - 230, 19, 140, 82, 219, 58, 23, 150, 140, 82, 238, 171, 219, 58, 23, 230, - 17, 140, 82, 238, 171, 219, 58, 23, 150, 206, 184, 235, 79, 23, 230, 6, - 206, 184, 143, 140, 174, 228, 219, 216, 66, 23, 230, 19, 206, 184, 143, - 82, 174, 140, 238, 170, 23, 150, 206, 184, 196, 73, 23, 150, 206, 184, - 207, 142, 221, 46, 23, 150, 206, 184, 219, 58, 23, 230, 17, 206, 184, - 219, 58, 23, 230, 2, 206, 184, 219, 58, 23, 230, 19, 206, 184, 219, 58, - 23, 150, 206, 184, 216, 66, 23, 150, 206, 184, 82, 238, 254, 23, 150, - 206, 184, 82, 207, 142, 221, 45, 23, 150, 206, 184, 223, 120, 23, 150, - 206, 184, 198, 207, 23, 230, 4, 206, 184, 198, 207, 23, 150, 140, 206, - 184, 219, 58, 23, 230, 17, 140, 206, 184, 219, 58, 23, 230, 11, 140, 206, - 184, 219, 59, 211, 93, 23, 230, 4, 140, 206, 184, 219, 59, 211, 4, 23, - 230, 4, 140, 206, 184, 219, 59, 223, 134, 23, 230, 4, 140, 206, 184, 219, - 59, 196, 100, 23, 230, 13, 140, 206, 184, 219, 58, 23, 230, 6, 140, 206, - 184, 219, 58, 23, 230, 19, 140, 206, 184, 219, 59, 211, 4, 23, 230, 19, - 140, 206, 184, 219, 58, 23, 150, 82, 235, 79, 23, 230, 6, 216, 66, 23, - 150, 82, 196, 73, 23, 230, 17, 82, 196, 73, 23, 150, 82, 207, 142, 221, - 46, 23, 150, 82, 132, 174, 202, 202, 23, 230, 4, 82, 198, 207, 23, 150, - 82, 174, 219, 58, 23, 150, 82, 219, 58, 23, 150, 82, 206, 184, 219, 58, - 23, 230, 17, 82, 206, 184, 219, 58, 23, 230, 11, 82, 206, 184, 219, 59, - 211, 93, 23, 230, 13, 82, 206, 184, 219, 58, 23, 230, 6, 82, 206, 184, - 219, 58, 23, 230, 19, 82, 206, 184, 219, 59, 211, 4, 23, 230, 19, 82, - 206, 184, 219, 59, 223, 134, 23, 230, 19, 82, 206, 184, 219, 58, 23, 230, - 17, 82, 206, 184, 219, 59, 248, 173, 23, 230, 15, 82, 206, 184, 219, 59, - 238, 254, 23, 230, 15, 82, 206, 184, 219, 59, 238, 255, 202, 202, 23, - 230, 4, 82, 206, 184, 219, 59, 238, 255, 211, 4, 23, 230, 4, 82, 206, - 184, 219, 59, 238, 255, 223, 134, 23, 230, 4, 82, 206, 184, 219, 59, 238, - 254, 23, 230, 6, 140, 229, 92, 23, 150, 140, 174, 202, 202, 23, 230, 6, - 140, 174, 202, 202, 23, 150, 140, 174, 202, 203, 174, 236, 249, 23, 150, - 140, 174, 202, 203, 174, 238, 254, 23, 150, 140, 174, 202, 203, 174, 248, - 173, 23, 150, 140, 174, 202, 203, 140, 248, 173, 23, 150, 140, 174, 202, - 203, 248, 32, 248, 173, 23, 150, 140, 174, 202, 203, 140, 229, 94, 23, - 150, 140, 174, 232, 95, 140, 201, 47, 23, 150, 140, 174, 232, 95, 140, - 248, 173, 23, 150, 140, 174, 106, 23, 150, 140, 174, 238, 126, 23, 150, - 140, 174, 238, 118, 174, 223, 89, 23, 230, 15, 140, 174, 238, 118, 174, - 223, 89, 23, 150, 140, 174, 238, 118, 174, 196, 100, 23, 150, 140, 174, - 242, 218, 23, 230, 13, 140, 198, 207, 23, 230, 13, 140, 174, 211, 65, 23, - 230, 6, 140, 174, 211, 65, 23, 230, 6, 140, 174, 219, 244, 23, 230, 6, - 140, 198, 207, 23, 230, 6, 140, 174, 202, 65, 23, 230, 19, 140, 174, 211, - 4, 23, 230, 19, 140, 174, 223, 134, 23, 230, 19, 140, 198, 207, 23, 150, - 198, 207, 23, 150, 174, 229, 180, 23, 150, 174, 202, 203, 236, 249, 23, - 150, 174, 202, 203, 238, 254, 23, 150, 174, 202, 203, 248, 173, 23, 150, - 174, 232, 94, 23, 150, 174, 248, 160, 140, 216, 66, 23, 150, 174, 248, - 160, 82, 206, 183, 23, 150, 174, 248, 160, 206, 184, 219, 58, 23, 150, - 174, 196, 101, 103, 232, 206, 23, 150, 174, 138, 103, 232, 206, 23, 150, - 174, 196, 101, 115, 232, 206, 23, 150, 174, 196, 101, 232, 90, 232, 206, - 23, 150, 174, 138, 232, 90, 207, 142, 221, 45, 23, 230, 9, 23, 150, 229, - 180, 23, 198, 32, 202, 164, 23, 198, 32, 215, 113, 23, 198, 32, 248, 159, - 23, 230, 181, 202, 164, 23, 230, 181, 215, 113, 23, 230, 181, 248, 159, - 23, 201, 28, 202, 164, 23, 201, 28, 215, 113, 23, 201, 28, 248, 159, 23, - 247, 226, 202, 164, 23, 247, 226, 215, 113, 23, 247, 226, 248, 159, 23, - 206, 55, 202, 164, 23, 206, 55, 215, 113, 23, 206, 55, 248, 159, 23, 200, - 166, 200, 72, 23, 200, 166, 248, 159, 23, 201, 181, 219, 245, 202, 164, - 23, 201, 181, 2, 202, 164, 23, 201, 181, 219, 245, 215, 113, 23, 201, - 181, 2, 215, 113, 23, 201, 181, 204, 1, 23, 232, 157, 219, 245, 202, 164, - 23, 232, 157, 2, 202, 164, 23, 232, 157, 219, 245, 215, 113, 23, 232, - 157, 2, 215, 113, 23, 232, 157, 204, 1, 23, 201, 181, 232, 157, 251, 103, - 23, 215, 156, 132, 143, 219, 244, 23, 215, 156, 132, 143, 202, 65, 23, - 215, 156, 132, 204, 1, 23, 215, 156, 143, 204, 1, 23, 215, 156, 132, 143, - 251, 104, 219, 244, 23, 215, 156, 132, 143, 251, 104, 202, 65, 23, 215, - 156, 202, 203, 118, 202, 203, 205, 79, 23, 215, 155, 232, 212, 238, 244, - 23, 215, 157, 232, 212, 238, 244, 23, 215, 155, 202, 165, 201, 48, 202, - 65, 23, 215, 155, 202, 165, 201, 48, 216, 193, 23, 215, 155, 202, 165, - 201, 48, 219, 244, 23, 215, 155, 202, 165, 201, 48, 219, 242, 23, 215, - 155, 202, 165, 193, 4, 232, 160, 23, 215, 155, 54, 201, 47, 23, 215, 155, - 54, 193, 4, 232, 160, 23, 215, 155, 54, 251, 103, 23, 215, 155, 54, 251, - 104, 193, 4, 232, 160, 23, 215, 155, 238, 170, 23, 215, 155, 197, 221, - 201, 48, 215, 159, 23, 215, 155, 197, 221, 193, 4, 232, 160, 23, 215, - 155, 197, 221, 251, 103, 23, 215, 155, 197, 221, 251, 104, 193, 4, 232, - 160, 23, 215, 155, 248, 178, 202, 65, 23, 215, 155, 248, 178, 216, 193, - 23, 215, 155, 248, 178, 219, 244, 23, 215, 155, 238, 211, 202, 65, 23, - 215, 155, 238, 211, 216, 193, 23, 215, 155, 238, 211, 219, 244, 23, 215, - 155, 238, 211, 206, 115, 23, 215, 155, 243, 78, 202, 65, 23, 215, 155, - 243, 78, 216, 193, 23, 215, 155, 243, 78, 219, 244, 23, 215, 155, 111, - 202, 65, 23, 215, 155, 111, 216, 193, 23, 215, 155, 111, 219, 244, 23, - 215, 155, 191, 21, 202, 65, 23, 215, 155, 191, 21, 216, 193, 23, 215, - 155, 191, 21, 219, 244, 23, 215, 155, 210, 48, 202, 65, 23, 215, 155, - 210, 48, 216, 193, 23, 215, 155, 210, 48, 219, 244, 23, 197, 255, 206, - 113, 202, 164, 23, 197, 255, 206, 113, 235, 89, 23, 197, 255, 206, 113, - 251, 103, 23, 197, 255, 206, 114, 202, 164, 23, 197, 255, 206, 114, 235, - 89, 23, 197, 255, 206, 114, 251, 103, 23, 197, 255, 203, 139, 23, 197, - 255, 250, 201, 201, 213, 202, 164, 23, 197, 255, 250, 201, 201, 213, 235, - 89, 23, 197, 255, 250, 201, 201, 213, 197, 220, 23, 215, 158, 250, 89, - 202, 65, 23, 215, 158, 250, 89, 216, 193, 23, 215, 158, 250, 89, 219, - 244, 23, 215, 158, 250, 89, 219, 242, 23, 215, 158, 198, 26, 202, 65, 23, - 215, 158, 198, 26, 216, 193, 23, 215, 158, 198, 26, 219, 244, 23, 215, - 158, 198, 26, 219, 242, 23, 215, 158, 248, 160, 250, 89, 202, 65, 23, - 215, 158, 248, 160, 250, 89, 216, 193, 23, 215, 158, 248, 160, 250, 89, - 219, 244, 23, 215, 158, 248, 160, 250, 89, 219, 242, 23, 215, 158, 248, - 160, 198, 26, 202, 65, 23, 215, 158, 248, 160, 198, 26, 216, 193, 23, - 215, 158, 248, 160, 198, 26, 219, 244, 23, 215, 158, 248, 160, 198, 26, - 219, 242, 23, 215, 157, 202, 165, 201, 48, 202, 65, 23, 215, 157, 202, - 165, 201, 48, 216, 193, 23, 215, 157, 202, 165, 201, 48, 219, 244, 23, - 215, 157, 202, 165, 201, 48, 219, 242, 23, 215, 157, 202, 165, 193, 4, - 232, 160, 23, 215, 157, 54, 201, 47, 23, 215, 157, 54, 193, 4, 232, 160, - 23, 215, 157, 54, 251, 103, 23, 215, 157, 54, 251, 104, 193, 4, 232, 160, - 23, 215, 157, 238, 170, 23, 215, 157, 197, 221, 201, 48, 215, 159, 23, - 215, 157, 197, 221, 193, 4, 232, 160, 23, 215, 157, 197, 221, 251, 104, - 215, 159, 23, 215, 157, 197, 221, 251, 104, 193, 4, 232, 160, 23, 215, - 157, 248, 177, 23, 215, 157, 238, 211, 202, 65, 23, 215, 157, 238, 211, - 216, 193, 23, 215, 157, 238, 211, 219, 244, 23, 215, 157, 243, 77, 23, - 215, 157, 111, 202, 65, 23, 215, 157, 111, 216, 193, 23, 215, 157, 111, - 219, 244, 23, 215, 157, 191, 21, 202, 65, 23, 215, 157, 191, 21, 216, - 193, 23, 215, 157, 191, 21, 219, 244, 23, 215, 157, 210, 48, 202, 65, 23, - 215, 157, 210, 48, 216, 193, 23, 215, 157, 210, 48, 219, 244, 23, 198, 0, - 206, 114, 202, 164, 23, 198, 0, 206, 114, 235, 89, 23, 198, 0, 206, 114, - 251, 103, 23, 198, 0, 206, 113, 202, 164, 23, 198, 0, 206, 113, 235, 89, - 23, 198, 0, 206, 113, 251, 103, 23, 198, 0, 203, 139, 23, 215, 155, 238, - 118, 208, 18, 202, 65, 23, 215, 155, 238, 118, 208, 18, 216, 193, 23, - 215, 155, 238, 118, 208, 18, 219, 244, 23, 215, 155, 238, 118, 208, 18, - 219, 242, 23, 215, 155, 238, 118, 230, 34, 202, 65, 23, 215, 155, 238, - 118, 230, 34, 216, 193, 23, 215, 155, 238, 118, 230, 34, 219, 244, 23, - 215, 155, 238, 118, 230, 34, 219, 242, 23, 215, 155, 238, 118, 198, 213, - 242, 219, 202, 65, 23, 215, 155, 238, 118, 198, 213, 242, 219, 216, 193, - 23, 215, 155, 228, 112, 202, 65, 23, 215, 155, 228, 112, 216, 193, 23, - 215, 155, 228, 112, 219, 244, 23, 215, 155, 218, 237, 202, 65, 23, 215, - 155, 218, 237, 216, 193, 23, 215, 155, 218, 237, 219, 244, 23, 215, 155, - 218, 237, 2, 235, 89, 23, 215, 155, 193, 137, 238, 118, 54, 202, 65, 23, - 215, 155, 193, 137, 238, 118, 54, 216, 193, 23, 215, 155, 193, 137, 238, - 118, 54, 219, 244, 23, 215, 155, 193, 137, 238, 118, 197, 221, 202, 65, - 23, 215, 155, 193, 137, 238, 118, 197, 221, 216, 193, 23, 215, 155, 193, - 137, 238, 118, 197, 221, 219, 244, 23, 215, 155, 238, 118, 199, 20, 201, - 47, 23, 215, 155, 238, 116, 238, 171, 202, 65, 23, 215, 155, 238, 116, - 238, 171, 216, 193, 23, 206, 113, 202, 164, 23, 206, 113, 235, 89, 23, - 206, 113, 251, 105, 23, 215, 155, 203, 139, 23, 215, 155, 238, 118, 229, - 84, 232, 59, 193, 164, 23, 215, 155, 228, 112, 229, 84, 232, 59, 193, - 164, 23, 215, 155, 218, 237, 229, 84, 232, 59, 193, 164, 23, 215, 155, - 193, 137, 229, 84, 232, 59, 193, 164, 23, 206, 113, 202, 165, 229, 84, - 232, 59, 193, 164, 23, 206, 113, 54, 229, 84, 232, 59, 193, 164, 23, 206, - 113, 251, 104, 229, 84, 232, 59, 193, 164, 23, 215, 155, 238, 118, 229, - 84, 243, 56, 23, 215, 155, 228, 112, 229, 84, 243, 56, 23, 215, 155, 218, - 237, 229, 84, 243, 56, 23, 215, 155, 193, 137, 229, 84, 243, 56, 23, 206, - 113, 202, 165, 229, 84, 243, 56, 23, 206, 113, 54, 229, 84, 243, 56, 23, - 206, 113, 251, 104, 229, 84, 243, 56, 23, 215, 155, 193, 137, 236, 250, - 210, 76, 202, 65, 23, 215, 155, 193, 137, 236, 250, 210, 76, 216, 193, - 23, 215, 155, 193, 137, 236, 250, 210, 76, 219, 244, 23, 215, 157, 238, - 118, 229, 84, 246, 239, 202, 65, 23, 215, 157, 238, 118, 229, 84, 246, - 239, 219, 244, 23, 215, 157, 228, 112, 229, 84, 246, 239, 2, 235, 89, 23, - 215, 157, 228, 112, 229, 84, 246, 239, 219, 245, 235, 89, 23, 215, 157, - 228, 112, 229, 84, 246, 239, 2, 197, 220, 23, 215, 157, 228, 112, 229, - 84, 246, 239, 219, 245, 197, 220, 23, 215, 157, 218, 237, 229, 84, 246, - 239, 2, 202, 164, 23, 215, 157, 218, 237, 229, 84, 246, 239, 219, 245, - 202, 164, 23, 215, 157, 218, 237, 229, 84, 246, 239, 2, 235, 89, 23, 215, - 157, 218, 237, 229, 84, 246, 239, 219, 245, 235, 89, 23, 215, 157, 193, - 137, 229, 84, 246, 239, 202, 65, 23, 215, 157, 193, 137, 229, 84, 246, - 239, 219, 244, 23, 206, 114, 202, 165, 229, 84, 246, 238, 23, 206, 114, - 54, 229, 84, 246, 238, 23, 206, 114, 251, 104, 229, 84, 246, 238, 23, - 215, 157, 238, 118, 229, 84, 232, 154, 202, 65, 23, 215, 157, 238, 118, - 229, 84, 232, 154, 219, 244, 23, 215, 157, 228, 112, 229, 84, 232, 154, - 2, 235, 89, 23, 215, 157, 228, 112, 229, 84, 232, 154, 219, 245, 235, 89, - 23, 215, 157, 228, 112, 229, 84, 232, 154, 197, 221, 2, 197, 220, 23, - 215, 157, 228, 112, 229, 84, 232, 154, 197, 221, 219, 245, 197, 220, 23, - 215, 157, 218, 237, 229, 84, 232, 154, 2, 202, 164, 23, 215, 157, 218, - 237, 229, 84, 232, 154, 219, 245, 202, 164, 23, 215, 157, 218, 237, 229, - 84, 232, 154, 2, 235, 89, 23, 215, 157, 218, 237, 229, 84, 232, 154, 219, - 245, 235, 89, 23, 215, 157, 193, 137, 229, 84, 232, 154, 202, 65, 23, - 215, 157, 193, 137, 229, 84, 232, 154, 219, 244, 23, 206, 114, 202, 165, - 229, 84, 232, 153, 23, 206, 114, 54, 229, 84, 232, 153, 23, 206, 114, - 251, 104, 229, 84, 232, 153, 23, 215, 157, 238, 118, 202, 65, 23, 215, - 157, 238, 118, 216, 193, 23, 215, 157, 238, 118, 219, 244, 23, 215, 157, - 238, 118, 219, 242, 23, 215, 157, 238, 118, 242, 30, 23, 215, 157, 228, - 112, 202, 65, 23, 215, 157, 218, 237, 202, 65, 23, 215, 157, 193, 137, - 202, 53, 23, 215, 157, 193, 137, 202, 65, 23, 215, 157, 193, 137, 219, - 244, 23, 206, 114, 202, 164, 23, 206, 114, 235, 89, 23, 206, 114, 251, - 103, 23, 215, 157, 203, 140, 210, 108, 23, 215, 155, 250, 201, 242, 219, - 2, 202, 164, 23, 215, 155, 250, 201, 242, 219, 216, 194, 202, 164, 23, - 215, 155, 250, 201, 242, 219, 2, 235, 89, 23, 215, 155, 250, 201, 242, - 219, 216, 194, 235, 89, 23, 215, 157, 250, 201, 242, 219, 229, 84, 193, - 165, 2, 202, 164, 23, 215, 157, 250, 201, 242, 219, 229, 84, 193, 165, - 216, 194, 202, 164, 23, 215, 157, 250, 201, 242, 219, 229, 84, 193, 165, - 219, 245, 202, 164, 23, 215, 157, 250, 201, 242, 219, 229, 84, 193, 165, - 2, 235, 89, 23, 215, 157, 250, 201, 242, 219, 229, 84, 193, 165, 216, - 194, 235, 89, 23, 215, 157, 250, 201, 242, 219, 229, 84, 193, 165, 219, - 245, 235, 89, 23, 215, 155, 193, 4, 242, 219, 232, 59, 202, 164, 23, 215, - 155, 193, 4, 242, 219, 232, 59, 235, 89, 23, 215, 157, 193, 4, 242, 219, - 229, 84, 193, 165, 202, 164, 23, 215, 157, 193, 4, 242, 219, 229, 84, - 193, 165, 235, 89, 23, 215, 155, 232, 212, 242, 216, 202, 164, 23, 215, - 155, 232, 212, 242, 216, 235, 89, 23, 215, 157, 232, 212, 242, 216, 229, - 84, 193, 165, 202, 164, 23, 215, 157, 232, 212, 242, 216, 229, 84, 193, - 165, 235, 89, 23, 234, 252, 250, 186, 202, 65, 23, 234, 252, 250, 186, - 219, 244, 23, 234, 252, 233, 32, 23, 234, 252, 202, 70, 23, 234, 252, - 199, 83, 23, 234, 252, 207, 58, 23, 234, 252, 202, 171, 23, 234, 252, - 202, 172, 251, 103, 23, 234, 252, 233, 184, 211, 17, 198, 141, 23, 234, - 252, 230, 192, 23, 229, 203, 23, 229, 204, 206, 188, 23, 229, 204, 215, - 155, 201, 47, 23, 229, 204, 215, 155, 198, 144, 23, 229, 204, 215, 157, - 201, 47, 23, 229, 204, 215, 155, 238, 117, 23, 229, 204, 215, 157, 238, - 117, 23, 229, 204, 215, 160, 242, 218, 23, 233, 63, 236, 188, 209, 18, - 213, 1, 232, 95, 198, 142, 23, 233, 63, 236, 188, 209, 18, 213, 1, 132, - 211, 46, 235, 79, 23, 233, 63, 236, 188, 209, 18, 213, 1, 132, 211, 46, - 143, 198, 142, 23, 233, 150, 201, 48, 196, 73, 23, 233, 150, 201, 48, - 214, 67, 23, 233, 150, 201, 48, 235, 79, 23, 235, 63, 233, 150, 214, 68, - 235, 79, 23, 235, 63, 233, 150, 143, 214, 67, 23, 235, 63, 233, 150, 132, - 214, 67, 23, 235, 63, 233, 150, 214, 68, 196, 73, 23, 232, 112, 214, 67, - 23, 232, 112, 238, 244, 23, 232, 112, 193, 7, 23, 233, 145, 211, 65, 23, - 233, 145, 201, 180, 23, 233, 145, 242, 170, 23, 233, 153, 248, 82, 202, - 164, 23, 233, 153, 248, 82, 215, 113, 23, 233, 145, 134, 211, 65, 23, - 233, 145, 193, 76, 211, 65, 23, 233, 145, 134, 242, 170, 23, 233, 145, - 193, 74, 215, 159, 23, 233, 153, 193, 57, 23, 233, 146, 196, 73, 23, 233, - 146, 235, 79, 23, 233, 146, 232, 140, 23, 233, 148, 201, 47, 23, 233, - 148, 201, 48, 235, 89, 23, 233, 148, 201, 48, 251, 103, 23, 233, 149, - 201, 47, 23, 233, 149, 201, 48, 235, 89, 23, 233, 149, 201, 48, 251, 103, - 23, 233, 148, 238, 115, 23, 233, 149, 238, 115, 23, 233, 148, 242, 213, - 23, 243, 73, 208, 148, 23, 243, 73, 214, 67, 23, 243, 73, 200, 213, 23, - 199, 84, 243, 73, 229, 103, 23, 199, 84, 243, 73, 216, 66, 23, 199, 84, - 243, 73, 218, 219, 23, 234, 165, 23, 213, 1, 214, 67, 23, 213, 1, 238, - 244, 23, 213, 1, 193, 5, 23, 213, 1, 193, 71, 23, 251, 174, 248, 68, 211, - 4, 23, 251, 174, 200, 212, 223, 134, 23, 251, 174, 248, 70, 2, 206, 112, - 23, 251, 174, 200, 214, 2, 206, 112, 23, 247, 247, 223, 106, 23, 247, - 247, 233, 173, 23, 215, 164, 242, 171, 214, 67, 23, 215, 164, 242, 171, - 232, 94, 23, 215, 164, 242, 171, 238, 244, 23, 215, 164, 202, 60, 23, - 215, 164, 202, 61, 193, 7, 23, 215, 164, 202, 61, 211, 65, 23, 215, 164, - 232, 55, 23, 215, 164, 232, 56, 193, 7, 23, 215, 164, 232, 56, 211, 65, - 23, 215, 164, 211, 66, 242, 218, 23, 215, 164, 211, 66, 232, 94, 23, 215, - 164, 211, 66, 193, 7, 23, 215, 164, 211, 66, 210, 253, 23, 215, 164, 211, - 66, 210, 254, 193, 7, 23, 215, 164, 211, 66, 210, 254, 192, 88, 23, 215, - 164, 211, 66, 207, 87, 23, 215, 164, 211, 66, 207, 88, 193, 7, 23, 215, - 164, 211, 66, 207, 88, 192, 88, 23, 215, 164, 221, 98, 23, 215, 164, 221, - 99, 232, 94, 23, 215, 164, 221, 99, 193, 7, 23, 215, 164, 199, 83, 23, - 215, 164, 199, 84, 232, 94, 23, 215, 164, 199, 84, 200, 213, 23, 219, 73, - 208, 212, 198, 82, 23, 219, 75, 110, 138, 196, 70, 23, 219, 75, 116, 138, - 218, 214, 23, 215, 164, 238, 209, 23, 215, 164, 193, 6, 202, 164, 23, - 215, 164, 193, 6, 235, 89, 23, 198, 57, 201, 69, 211, 5, 233, 34, 23, - 198, 57, 219, 118, 219, 72, 23, 198, 57, 198, 131, 248, 160, 219, 72, 23, - 198, 57, 198, 131, 198, 30, 223, 90, 215, 163, 23, 198, 57, 223, 90, 215, - 164, 207, 58, 23, 198, 57, 215, 154, 251, 199, 243, 74, 23, 198, 57, 246, - 230, 201, 69, 211, 4, 23, 198, 57, 246, 230, 223, 90, 215, 163, 23, 199, - 112, 23, 199, 113, 215, 159, 23, 199, 113, 211, 94, 198, 56, 23, 199, - 113, 211, 94, 198, 57, 215, 159, 23, 199, 113, 211, 94, 219, 72, 23, 199, - 113, 211, 94, 219, 73, 215, 159, 23, 199, 113, 248, 98, 219, 72, 23, 215, - 155, 222, 242, 23, 215, 157, 222, 242, 23, 214, 98, 23, 230, 45, 23, 233, - 176, 23, 203, 17, 229, 91, 201, 214, 23, 203, 17, 229, 91, 209, 16, 23, - 193, 163, 203, 17, 229, 91, 215, 162, 23, 232, 152, 203, 17, 229, 91, - 215, 162, 23, 203, 17, 198, 143, 232, 60, 193, 169, 23, 198, 38, 201, 48, - 201, 32, 23, 198, 38, 238, 116, 248, 177, 23, 198, 39, 197, 12, 23, 116, - 248, 57, 198, 143, 232, 60, 229, 91, 222, 168, 23, 219, 100, 242, 31, 23, - 219, 100, 219, 173, 23, 219, 100, 219, 172, 23, 219, 100, 219, 171, 23, - 219, 100, 219, 170, 23, 219, 100, 219, 169, 23, 219, 100, 219, 168, 23, - 219, 100, 219, 167, 23, 232, 211, 23, 219, 13, 201, 242, 23, 219, 14, - 201, 242, 23, 219, 16, 229, 176, 23, 219, 16, 193, 72, 23, 219, 16, 237, - 47, 23, 219, 16, 229, 204, 214, 98, 23, 219, 16, 198, 40, 23, 219, 16, - 219, 99, 236, 220, 23, 242, 26, 23, 232, 42, 201, 58, 23, 204, 20, 23, - 242, 35, 23, 210, 103, 23, 232, 221, 215, 227, 23, 232, 221, 215, 226, - 23, 232, 221, 215, 225, 23, 232, 221, 215, 224, 23, 232, 221, 215, 223, - 23, 206, 116, 215, 227, 23, 206, 116, 215, 226, 23, 206, 116, 215, 225, - 23, 206, 116, 215, 224, 23, 206, 116, 215, 223, 23, 206, 116, 215, 222, - 23, 206, 116, 215, 221, 23, 206, 116, 215, 220, 23, 206, 116, 215, 234, - 23, 206, 116, 215, 233, 23, 206, 116, 215, 232, 23, 206, 116, 215, 231, - 23, 206, 116, 215, 230, 23, 206, 116, 215, 229, 23, 206, 116, 215, 228, - 8, 2, 1, 232, 252, 236, 214, 4, 197, 224, 8, 2, 1, 207, 13, 27, 232, 14, - 8, 1, 2, 6, 152, 232, 14, 8, 2, 1, 207, 13, 222, 125, 8, 1, 2, 6, 220, - 119, 4, 248, 181, 8, 2, 1, 219, 139, 4, 207, 19, 106, 8, 2, 1, 152, 192, - 160, 4, 248, 181, 8, 2, 1, 207, 13, 234, 46, 8, 2, 1, 152, 207, 217, 4, - 177, 219, 189, 24, 207, 19, 106, 8, 2, 1, 200, 40, 4, 228, 219, 24, 207, - 19, 106, 8, 1, 207, 19, 242, 184, 4, 207, 19, 106, 8, 2, 1, 233, 227, 4, - 54, 164, 8, 2, 1, 233, 227, 4, 54, 249, 38, 24, 238, 128, 8, 2, 1, 152, - 200, 40, 4, 238, 128, 8, 1, 223, 65, 230, 231, 201, 59, 4, 238, 128, 8, - 1, 201, 31, 247, 146, 4, 238, 128, 8, 1, 2, 6, 152, 222, 125, 8, 2, 1, - 220, 119, 4, 232, 192, 8, 2, 1, 237, 25, 236, 214, 4, 210, 182, 106, 8, - 2, 1, 220, 119, 4, 248, 182, 24, 210, 182, 106, 8, 2, 1, 234, 47, 4, 210, - 182, 106, 8, 2, 1, 152, 207, 217, 4, 210, 182, 106, 8, 2, 1, 207, 217, 4, - 232, 193, 24, 210, 182, 106, 8, 2, 1, 199, 74, 236, 214, 4, 210, 182, - 106, 8, 2, 1, 233, 138, 4, 210, 182, 106, 8, 2, 1, 237, 25, 236, 214, 4, - 207, 19, 106, 8, 2, 1, 228, 44, 4, 201, 23, 24, 207, 19, 106, 8, 2, 1, - 186, 4, 207, 19, 106, 8, 2, 1, 199, 74, 236, 214, 4, 207, 19, 106, 8, 2, - 1, 247, 146, 4, 207, 19, 106, 8, 2, 1, 206, 4, 4, 238, 128, 33, 133, 1, - 250, 72, 33, 133, 1, 247, 204, 33, 133, 1, 195, 148, 33, 133, 1, 230, - 238, 33, 133, 1, 236, 124, 33, 133, 1, 192, 49, 33, 133, 1, 191, 55, 33, - 133, 1, 191, 82, 33, 133, 1, 223, 11, 33, 133, 1, 89, 223, 11, 33, 133, - 1, 70, 33, 133, 1, 236, 145, 33, 133, 1, 222, 67, 33, 133, 1, 219, 51, - 33, 133, 1, 215, 52, 33, 133, 1, 214, 196, 33, 133, 1, 211, 78, 33, 133, - 1, 209, 48, 33, 133, 1, 206, 174, 33, 133, 1, 202, 72, 33, 133, 1, 197, - 40, 33, 133, 1, 196, 120, 33, 133, 1, 232, 63, 33, 133, 1, 229, 156, 33, - 133, 1, 203, 3, 33, 133, 1, 197, 142, 33, 133, 1, 243, 6, 33, 133, 1, - 203, 160, 33, 133, 1, 192, 58, 33, 133, 1, 192, 60, 33, 133, 1, 192, 93, - 33, 133, 1, 191, 225, 33, 133, 1, 2, 191, 190, 33, 133, 1, 192, 12, 33, - 133, 1, 223, 54, 2, 191, 190, 33, 133, 1, 248, 127, 191, 190, 33, 133, 1, - 223, 54, 248, 127, 191, 190, 33, 133, 1, 232, 187, 212, 67, 208, 155, 90, - 1, 172, 212, 67, 208, 155, 90, 1, 197, 164, 212, 67, 208, 155, 90, 1, - 212, 186, 212, 67, 208, 155, 90, 1, 199, 247, 212, 67, 208, 155, 90, 1, - 144, 212, 67, 208, 155, 90, 1, 180, 212, 67, 208, 155, 90, 1, 192, 220, - 212, 67, 208, 155, 90, 1, 213, 98, 212, 67, 208, 155, 90, 1, 247, 112, - 212, 67, 208, 155, 90, 1, 171, 212, 67, 208, 155, 90, 1, 189, 212, 67, - 208, 155, 90, 1, 191, 123, 212, 67, 208, 155, 90, 1, 214, 152, 212, 67, - 208, 155, 90, 1, 212, 173, 212, 67, 208, 155, 90, 1, 157, 212, 67, 208, - 155, 90, 1, 237, 241, 212, 67, 208, 155, 90, 1, 212, 88, 212, 67, 208, - 155, 90, 1, 212, 231, 212, 67, 208, 155, 90, 1, 195, 185, 212, 67, 208, - 155, 90, 1, 212, 167, 212, 67, 208, 155, 90, 1, 197, 4, 212, 67, 208, - 155, 90, 1, 233, 68, 212, 67, 208, 155, 90, 1, 166, 212, 67, 208, 155, - 90, 1, 208, 89, 212, 67, 208, 155, 90, 1, 169, 212, 67, 208, 155, 90, 1, - 212, 233, 212, 67, 208, 155, 90, 1, 168, 212, 67, 208, 155, 90, 1, 192, - 175, 212, 67, 208, 155, 90, 1, 212, 235, 212, 67, 208, 155, 90, 1, 236, - 141, 212, 67, 208, 155, 90, 1, 212, 234, 212, 67, 208, 155, 90, 1, 230, - 48, 212, 67, 208, 155, 90, 1, 216, 2, 212, 67, 208, 155, 90, 1, 209, 102, - 212, 67, 208, 155, 90, 1, 231, 203, 212, 67, 208, 155, 90, 1, 206, 104, - 212, 67, 208, 155, 90, 1, 65, 212, 67, 208, 155, 90, 1, 252, 154, 212, - 67, 208, 155, 90, 1, 70, 212, 67, 208, 155, 90, 1, 69, 212, 67, 208, 155, - 90, 1, 74, 212, 67, 208, 155, 90, 1, 211, 76, 212, 67, 208, 155, 90, 1, - 73, 212, 67, 208, 155, 90, 1, 234, 145, 212, 67, 208, 155, 90, 1, 193, - 221, 212, 67, 208, 155, 90, 198, 65, 212, 67, 208, 155, 90, 198, 61, 212, - 67, 208, 155, 90, 198, 62, 212, 67, 208, 155, 90, 198, 59, 212, 67, 208, - 155, 90, 198, 60, 212, 67, 208, 155, 90, 198, 63, 212, 67, 208, 155, 90, - 198, 64, 212, 67, 208, 155, 90, 3, 39, 209, 241, 212, 67, 208, 155, 90, - 3, 39, 198, 254, 212, 67, 208, 155, 90, 3, 39, 219, 15, 212, 67, 208, - 155, 90, 3, 39, 251, 50, 212, 67, 208, 155, 90, 3, 39, 223, 66, 212, 67, - 208, 155, 90, 3, 192, 183, 192, 182, 212, 67, 208, 155, 90, 5, 219, 166, - 212, 67, 208, 155, 90, 17, 191, 77, 212, 67, 208, 155, 90, 17, 108, 212, - 67, 208, 155, 90, 17, 109, 212, 67, 208, 155, 90, 17, 139, 212, 67, 208, - 155, 90, 17, 137, 212, 67, 208, 155, 90, 17, 153, 212, 67, 208, 155, 90, - 17, 173, 212, 67, 208, 155, 90, 17, 181, 212, 67, 208, 155, 90, 17, 176, - 212, 67, 208, 155, 90, 17, 184, 212, 67, 208, 155, 90, 219, 4, 212, 83, - 212, 67, 208, 155, 90, 47, 247, 112, 198, 33, 1, 168, 198, 33, 1, 249, - 103, 198, 33, 1, 199, 247, 198, 33, 1, 237, 241, 198, 33, 1, 157, 198, - 33, 1, 231, 203, 198, 33, 1, 172, 198, 33, 1, 180, 198, 33, 1, 214, 54, - 198, 33, 1, 189, 198, 33, 1, 246, 209, 198, 33, 1, 169, 198, 33, 1, 193, - 187, 198, 33, 1, 223, 4, 198, 33, 1, 144, 198, 33, 1, 166, 198, 33, 1, - 171, 198, 33, 1, 70, 198, 33, 1, 247, 246, 70, 198, 33, 1, 223, 21, 198, - 33, 1, 247, 246, 223, 21, 198, 33, 1, 69, 198, 33, 1, 73, 198, 33, 1, - 247, 246, 73, 198, 33, 1, 234, 23, 198, 33, 1, 247, 246, 234, 23, 198, - 33, 1, 74, 198, 33, 1, 251, 229, 198, 33, 1, 247, 246, 251, 229, 198, 33, - 1, 65, 198, 33, 3, 206, 175, 198, 74, 193, 161, 1, 252, 154, 193, 161, 1, - 65, 193, 161, 1, 249, 103, 193, 161, 1, 247, 112, 193, 161, 1, 237, 241, - 193, 161, 1, 231, 203, 193, 161, 1, 169, 193, 161, 1, 209, 219, 193, 161, - 1, 171, 193, 161, 1, 180, 193, 161, 1, 168, 193, 161, 1, 199, 247, 193, - 161, 1, 199, 44, 193, 161, 1, 233, 68, 193, 161, 1, 189, 193, 161, 1, - 203, 160, 193, 161, 1, 223, 4, 193, 161, 1, 191, 123, 193, 161, 1, 193, - 187, 193, 161, 1, 195, 185, 193, 161, 1, 157, 193, 161, 1, 74, 193, 161, - 1, 250, 113, 193, 161, 1, 166, 193, 161, 1, 172, 193, 161, 1, 221, 190, - 193, 161, 1, 144, 193, 161, 1, 73, 193, 161, 1, 70, 193, 161, 1, 214, 54, - 193, 161, 1, 69, 193, 161, 1, 219, 42, 193, 161, 1, 197, 164, 193, 161, - 1, 198, 22, 193, 161, 1, 211, 83, 193, 161, 1, 252, 113, 193, 161, 1, - 251, 71, 193, 161, 1, 223, 108, 193, 161, 1, 211, 93, 193, 161, 1, 234, - 61, 193, 161, 1, 252, 114, 193, 161, 1, 212, 88, 193, 161, 1, 196, 143, - 193, 161, 1, 192, 24, 193, 161, 163, 197, 63, 193, 161, 163, 197, 62, - 193, 161, 163, 221, 30, 193, 161, 163, 221, 29, 193, 161, 17, 191, 77, - 193, 161, 17, 108, 193, 161, 17, 109, 193, 161, 17, 139, 193, 161, 17, - 137, 193, 161, 17, 153, 193, 161, 17, 173, 193, 161, 17, 181, 193, 161, - 17, 176, 193, 161, 17, 184, 193, 161, 213, 218, 57, 36, 5, 229, 134, 36, - 5, 229, 128, 36, 5, 229, 130, 36, 5, 229, 133, 36, 5, 229, 131, 36, 5, - 229, 132, 36, 5, 229, 129, 36, 5, 230, 114, 229, 138, 36, 5, 229, 135, - 36, 5, 229, 136, 36, 5, 229, 137, 36, 5, 230, 114, 215, 62, 36, 5, 230, - 114, 215, 63, 36, 5, 230, 114, 207, 231, 36, 5, 230, 114, 207, 232, 36, - 5, 230, 114, 207, 233, 36, 5, 230, 114, 247, 159, 36, 5, 230, 114, 247, - 160, 36, 5, 230, 114, 220, 148, 36, 5, 230, 114, 220, 149, 36, 5, 230, - 114, 220, 150, 36, 5, 230, 114, 230, 98, 36, 5, 230, 114, 230, 99, 36, 5, - 230, 114, 230, 100, 36, 5, 230, 114, 232, 21, 36, 5, 230, 114, 232, 22, - 36, 5, 230, 114, 208, 111, 36, 5, 230, 114, 208, 112, 85, 84, 5, 218, - 146, 221, 142, 85, 84, 5, 218, 142, 157, 85, 84, 5, 218, 140, 220, 208, - 85, 84, 5, 218, 16, 221, 244, 85, 84, 5, 217, 242, 221, 253, 85, 84, 5, - 218, 5, 221, 17, 85, 84, 5, 218, 33, 221, 43, 85, 84, 5, 217, 158, 220, - 195, 85, 84, 5, 218, 137, 193, 84, 85, 84, 5, 218, 135, 193, 187, 85, 84, - 5, 218, 133, 193, 0, 85, 84, 5, 217, 211, 193, 112, 85, 84, 5, 217, 219, - 193, 123, 85, 84, 5, 217, 223, 193, 29, 85, 84, 5, 218, 36, 193, 48, 85, - 84, 5, 217, 143, 192, 252, 85, 84, 5, 217, 194, 193, 110, 85, 84, 5, 218, - 20, 192, 240, 85, 84, 5, 218, 32, 192, 242, 85, 84, 5, 217, 198, 192, - 241, 85, 84, 5, 218, 131, 216, 26, 85, 84, 5, 218, 129, 217, 70, 85, 84, - 5, 218, 127, 215, 107, 85, 84, 5, 218, 22, 216, 167, 85, 84, 5, 217, 243, - 215, 214, 85, 84, 5, 217, 183, 215, 132, 85, 84, 5, 217, 148, 215, 126, - 85, 84, 5, 218, 125, 248, 140, 85, 84, 5, 218, 122, 249, 103, 85, 84, 5, - 218, 120, 247, 218, 85, 84, 5, 217, 187, 248, 207, 85, 84, 5, 217, 240, - 248, 223, 85, 84, 5, 217, 234, 248, 49, 85, 84, 5, 217, 199, 248, 63, 85, - 84, 5, 218, 110, 70, 85, 84, 5, 218, 108, 65, 85, 84, 5, 218, 106, 69, - 85, 84, 5, 217, 174, 234, 145, 85, 84, 5, 217, 237, 73, 85, 84, 5, 217, - 172, 211, 76, 85, 84, 5, 217, 190, 74, 85, 84, 5, 217, 200, 234, 123, 85, - 84, 5, 217, 206, 223, 134, 85, 84, 5, 217, 202, 223, 134, 85, 84, 5, 217, - 142, 251, 81, 85, 84, 5, 217, 159, 234, 61, 85, 84, 5, 218, 95, 202, 217, - 85, 84, 5, 218, 93, 189, 85, 84, 5, 218, 91, 200, 255, 85, 84, 5, 217, - 175, 205, 45, 85, 84, 5, 217, 221, 205, 63, 85, 84, 5, 217, 201, 202, 11, - 85, 84, 5, 218, 2, 202, 41, 85, 84, 5, 217, 141, 202, 210, 85, 84, 5, - 218, 81, 219, 122, 85, 84, 5, 218, 79, 171, 85, 84, 5, 218, 77, 218, 203, - 85, 84, 5, 217, 253, 219, 204, 85, 84, 5, 218, 8, 219, 214, 85, 84, 5, - 218, 27, 218, 240, 85, 84, 5, 217, 184, 219, 19, 85, 84, 5, 217, 227, - 177, 219, 214, 85, 84, 5, 218, 103, 236, 255, 85, 84, 5, 218, 100, 237, - 241, 85, 84, 5, 218, 97, 235, 45, 85, 84, 5, 217, 248, 237, 86, 85, 84, - 5, 217, 157, 236, 102, 85, 84, 5, 217, 156, 236, 129, 85, 84, 5, 218, 89, - 198, 188, 85, 84, 5, 218, 86, 199, 247, 85, 84, 5, 218, 84, 197, 90, 85, - 84, 5, 217, 246, 199, 116, 85, 84, 5, 218, 26, 199, 140, 85, 84, 5, 217, - 233, 198, 54, 85, 84, 5, 218, 12, 159, 85, 84, 5, 218, 75, 222, 217, 85, - 84, 5, 218, 72, 223, 4, 85, 84, 5, 218, 70, 222, 155, 85, 84, 5, 217, - 180, 222, 236, 85, 84, 5, 217, 224, 222, 238, 85, 84, 5, 217, 177, 222, - 164, 85, 84, 5, 218, 18, 222, 174, 85, 84, 5, 217, 162, 177, 222, 174, - 85, 84, 5, 218, 68, 192, 33, 85, 84, 5, 218, 65, 169, 85, 84, 5, 218, 63, - 191, 225, 85, 84, 5, 217, 228, 192, 77, 85, 84, 5, 218, 1, 192, 80, 85, - 84, 5, 217, 196, 191, 246, 85, 84, 5, 217, 216, 192, 12, 85, 84, 5, 218, - 59, 232, 238, 85, 84, 5, 218, 57, 233, 68, 85, 84, 5, 218, 55, 232, 48, - 85, 84, 5, 218, 3, 233, 11, 85, 84, 5, 218, 6, 233, 18, 85, 84, 5, 217, - 204, 232, 123, 85, 84, 5, 217, 249, 232, 135, 85, 84, 5, 217, 140, 232, - 47, 85, 84, 5, 217, 236, 233, 39, 85, 84, 5, 218, 53, 213, 165, 85, 84, - 5, 218, 51, 214, 212, 85, 84, 5, 218, 49, 212, 117, 85, 84, 5, 217, 220, - 214, 88, 85, 84, 5, 217, 168, 213, 18, 85, 84, 5, 217, 161, 229, 126, 85, - 84, 5, 218, 44, 144, 85, 84, 5, 217, 151, 228, 128, 85, 84, 5, 218, 47, - 229, 183, 85, 84, 5, 217, 241, 229, 213, 85, 84, 5, 218, 42, 228, 220, - 85, 84, 5, 217, 197, 228, 247, 85, 84, 5, 217, 254, 229, 182, 85, 84, 5, - 217, 209, 228, 213, 85, 84, 5, 218, 28, 229, 96, 85, 84, 5, 217, 207, - 230, 23, 85, 84, 5, 217, 250, 228, 111, 85, 84, 5, 218, 29, 229, 166, 85, - 84, 5, 217, 144, 228, 223, 85, 84, 5, 218, 35, 228, 124, 85, 84, 5, 217, - 247, 214, 19, 85, 84, 5, 218, 40, 214, 33, 85, 84, 5, 217, 255, 214, 16, - 85, 84, 5, 217, 222, 214, 27, 85, 84, 5, 217, 191, 214, 28, 85, 84, 5, - 217, 181, 214, 17, 85, 84, 5, 217, 217, 214, 18, 85, 84, 5, 217, 178, - 214, 32, 85, 84, 5, 217, 210, 214, 15, 85, 84, 5, 217, 251, 177, 214, 28, - 85, 84, 5, 217, 231, 177, 214, 17, 85, 84, 5, 217, 154, 177, 214, 18, 85, - 84, 5, 217, 182, 231, 16, 85, 84, 5, 217, 226, 231, 203, 85, 84, 5, 217, - 169, 230, 146, 85, 84, 5, 217, 147, 231, 120, 85, 84, 5, 217, 171, 230, - 132, 85, 84, 5, 217, 170, 230, 142, 85, 84, 5, 217, 153, 214, 38, 85, 84, - 5, 218, 24, 213, 231, 85, 84, 5, 217, 160, 213, 220, 85, 84, 5, 218, 13, - 209, 176, 85, 84, 5, 217, 238, 168, 85, 84, 5, 218, 31, 208, 158, 85, 84, - 5, 218, 0, 210, 40, 85, 84, 5, 218, 30, 210, 53, 85, 84, 5, 217, 235, - 209, 30, 85, 84, 5, 218, 15, 209, 65, 85, 84, 5, 217, 192, 216, 233, 85, - 84, 5, 218, 19, 216, 248, 85, 84, 5, 217, 215, 216, 227, 85, 84, 5, 218, - 34, 216, 240, 85, 84, 5, 217, 149, 216, 240, 85, 84, 5, 218, 9, 216, 241, - 85, 84, 5, 217, 165, 216, 228, 85, 84, 5, 217, 163, 216, 229, 85, 84, 5, - 217, 150, 216, 221, 85, 84, 5, 217, 176, 177, 216, 241, 85, 84, 5, 217, - 232, 177, 216, 228, 85, 84, 5, 217, 195, 177, 216, 229, 85, 84, 5, 217, - 205, 220, 245, 85, 84, 5, 217, 245, 220, 253, 85, 84, 5, 218, 7, 220, - 241, 85, 84, 5, 218, 38, 220, 248, 85, 84, 5, 217, 229, 220, 249, 85, 84, - 5, 217, 225, 220, 243, 85, 84, 5, 217, 179, 220, 244, 85, 84, 5, 217, - 213, 231, 137, 85, 84, 5, 218, 25, 231, 145, 85, 84, 5, 217, 189, 231, - 132, 85, 84, 5, 217, 244, 231, 141, 85, 84, 5, 217, 230, 231, 142, 85, - 84, 5, 218, 10, 231, 133, 85, 84, 5, 218, 11, 231, 135, 85, 84, 5, 217, - 166, 166, 85, 84, 5, 217, 214, 214, 133, 85, 84, 5, 217, 208, 214, 148, - 85, 84, 5, 217, 212, 214, 115, 85, 84, 5, 217, 146, 214, 139, 85, 84, 5, - 217, 218, 214, 140, 85, 84, 5, 218, 14, 214, 120, 85, 84, 5, 218, 17, - 214, 124, 85, 84, 5, 217, 185, 213, 144, 85, 84, 5, 217, 145, 213, 114, - 85, 84, 5, 217, 188, 213, 135, 85, 84, 5, 217, 203, 213, 118, 85, 84, 5, - 217, 155, 195, 66, 85, 84, 5, 217, 152, 195, 185, 85, 84, 5, 217, 186, - 193, 246, 85, 84, 5, 217, 164, 195, 145, 85, 84, 5, 217, 252, 195, 150, - 85, 84, 5, 217, 193, 195, 5, 85, 84, 5, 218, 4, 195, 21, 85, 84, 5, 217, - 173, 212, 61, 85, 84, 5, 218, 23, 212, 81, 85, 84, 5, 217, 167, 212, 43, - 85, 84, 5, 217, 239, 212, 73, 85, 84, 5, 218, 21, 212, 50, 85, 84, 17, - 108, 85, 84, 17, 109, 85, 84, 17, 139, 85, 84, 17, 137, 85, 84, 17, 153, - 85, 84, 17, 173, 85, 84, 17, 181, 85, 84, 17, 176, 85, 84, 17, 184, 85, - 84, 33, 31, 199, 114, 85, 84, 33, 31, 199, 85, 85, 84, 33, 31, 228, 107, - 85, 84, 33, 31, 198, 223, 85, 84, 33, 31, 199, 91, 198, 223, 85, 84, 33, - 31, 228, 110, 198, 223, 85, 84, 33, 31, 216, 29, 251, 237, 6, 1, 251, - 129, 251, 237, 6, 1, 237, 238, 251, 237, 6, 1, 220, 99, 251, 237, 6, 1, - 216, 42, 251, 237, 6, 1, 249, 103, 251, 237, 6, 1, 202, 159, 251, 237, 6, - 1, 210, 53, 251, 237, 6, 1, 248, 148, 251, 237, 6, 1, 166, 251, 237, 6, - 1, 73, 251, 237, 6, 1, 233, 68, 251, 237, 6, 1, 70, 251, 237, 6, 1, 74, - 251, 237, 6, 1, 237, 23, 251, 237, 6, 1, 192, 34, 251, 237, 6, 1, 193, - 131, 251, 237, 6, 1, 212, 117, 251, 237, 6, 1, 222, 79, 251, 237, 6, 1, - 169, 251, 237, 6, 1, 69, 251, 237, 6, 1, 222, 208, 251, 237, 6, 1, 243, - 47, 251, 237, 6, 1, 144, 251, 237, 6, 1, 208, 87, 251, 237, 6, 1, 231, - 203, 251, 237, 6, 1, 212, 88, 251, 237, 6, 1, 197, 90, 251, 237, 6, 1, - 213, 210, 251, 237, 6, 1, 195, 185, 251, 237, 6, 1, 221, 190, 251, 237, - 6, 1, 231, 142, 251, 237, 6, 1, 191, 108, 251, 237, 6, 1, 220, 244, 251, - 237, 6, 1, 203, 160, 251, 237, 2, 1, 251, 129, 251, 237, 2, 1, 237, 238, - 251, 237, 2, 1, 220, 99, 251, 237, 2, 1, 216, 42, 251, 237, 2, 1, 249, - 103, 251, 237, 2, 1, 202, 159, 251, 237, 2, 1, 210, 53, 251, 237, 2, 1, - 248, 148, 251, 237, 2, 1, 166, 251, 237, 2, 1, 73, 251, 237, 2, 1, 233, - 68, 251, 237, 2, 1, 70, 251, 237, 2, 1, 74, 251, 237, 2, 1, 237, 23, 251, - 237, 2, 1, 192, 34, 251, 237, 2, 1, 193, 131, 251, 237, 2, 1, 212, 117, - 251, 237, 2, 1, 222, 79, 251, 237, 2, 1, 169, 251, 237, 2, 1, 69, 251, - 237, 2, 1, 222, 208, 251, 237, 2, 1, 243, 47, 251, 237, 2, 1, 144, 251, - 237, 2, 1, 208, 87, 251, 237, 2, 1, 231, 203, 251, 237, 2, 1, 212, 88, - 251, 237, 2, 1, 197, 90, 251, 237, 2, 1, 213, 210, 251, 237, 2, 1, 195, - 185, 251, 237, 2, 1, 221, 190, 251, 237, 2, 1, 231, 142, 251, 237, 2, 1, - 191, 108, 251, 237, 2, 1, 220, 244, 251, 237, 2, 1, 203, 160, 251, 237, - 251, 130, 219, 166, 251, 237, 18, 219, 166, 251, 237, 231, 116, 77, 251, - 237, 230, 24, 251, 237, 119, 215, 235, 251, 237, 231, 117, 119, 215, 235, - 251, 237, 212, 128, 251, 237, 214, 199, 77, 251, 237, 17, 191, 77, 251, - 237, 17, 108, 251, 237, 17, 109, 251, 237, 17, 139, 251, 237, 17, 137, - 251, 237, 17, 153, 251, 237, 17, 173, 251, 237, 17, 181, 251, 237, 17, - 176, 251, 237, 17, 184, 251, 237, 89, 233, 175, 77, 251, 237, 89, 208, 8, - 77, 223, 118, 142, 31, 108, 223, 118, 142, 31, 109, 223, 118, 142, 31, - 139, 223, 118, 142, 31, 137, 223, 118, 142, 31, 153, 223, 118, 142, 31, - 173, 223, 118, 142, 31, 181, 223, 118, 142, 31, 176, 223, 118, 142, 31, - 184, 223, 118, 142, 31, 199, 90, 223, 118, 142, 31, 197, 28, 223, 118, - 142, 31, 198, 244, 223, 118, 142, 31, 232, 97, 223, 118, 142, 31, 232, - 230, 223, 118, 142, 31, 202, 115, 223, 118, 142, 31, 203, 236, 223, 118, - 142, 31, 234, 110, 223, 118, 142, 31, 213, 156, 223, 118, 142, 31, 91, - 228, 109, 223, 118, 142, 31, 103, 228, 109, 223, 118, 142, 31, 115, 228, - 109, 223, 118, 142, 31, 232, 90, 228, 109, 223, 118, 142, 31, 232, 185, - 228, 109, 223, 118, 142, 31, 202, 131, 228, 109, 223, 118, 142, 31, 203, - 242, 228, 109, 223, 118, 142, 31, 234, 121, 228, 109, 223, 118, 142, 31, - 213, 161, 228, 109, 223, 118, 142, 31, 91, 188, 223, 118, 142, 31, 103, - 188, 223, 118, 142, 31, 115, 188, 223, 118, 142, 31, 232, 90, 188, 223, - 118, 142, 31, 232, 185, 188, 223, 118, 142, 31, 202, 131, 188, 223, 118, - 142, 31, 203, 242, 188, 223, 118, 142, 31, 234, 121, 188, 223, 118, 142, - 31, 213, 161, 188, 223, 118, 142, 31, 199, 91, 188, 223, 118, 142, 31, - 197, 29, 188, 223, 118, 142, 31, 198, 245, 188, 223, 118, 142, 31, 232, - 98, 188, 223, 118, 142, 31, 232, 231, 188, 223, 118, 142, 31, 202, 116, - 188, 223, 118, 142, 31, 203, 237, 188, 223, 118, 142, 31, 234, 111, 188, - 223, 118, 142, 31, 213, 157, 188, 223, 118, 142, 31, 220, 17, 223, 118, - 142, 31, 220, 16, 223, 118, 142, 220, 18, 77, 223, 118, 142, 31, 222, 34, - 223, 118, 142, 31, 222, 33, 223, 118, 142, 31, 208, 220, 108, 223, 118, - 142, 31, 208, 220, 109, 223, 118, 142, 31, 208, 220, 139, 223, 118, 142, - 31, 208, 220, 137, 223, 118, 142, 31, 208, 220, 153, 223, 118, 142, 31, - 208, 220, 173, 223, 118, 142, 31, 208, 220, 181, 223, 118, 142, 31, 208, - 220, 176, 223, 118, 142, 31, 208, 220, 184, 223, 118, 142, 209, 98, 223, - 118, 142, 232, 80, 91, 208, 17, 223, 118, 142, 232, 80, 91, 230, 37, 223, - 118, 142, 232, 80, 115, 208, 15, 223, 118, 142, 206, 31, 77, 223, 118, - 142, 31, 251, 106, 108, 223, 118, 142, 31, 251, 106, 109, 223, 118, 142, - 31, 251, 106, 199, 91, 188, 223, 118, 142, 251, 106, 220, 18, 77, 211, - 11, 142, 31, 108, 211, 11, 142, 31, 109, 211, 11, 142, 31, 139, 211, 11, - 142, 31, 137, 211, 11, 142, 31, 153, 211, 11, 142, 31, 173, 211, 11, 142, - 31, 181, 211, 11, 142, 31, 176, 211, 11, 142, 31, 184, 211, 11, 142, 31, - 199, 90, 211, 11, 142, 31, 197, 28, 211, 11, 142, 31, 198, 244, 211, 11, - 142, 31, 232, 97, 211, 11, 142, 31, 232, 230, 211, 11, 142, 31, 202, 115, - 211, 11, 142, 31, 203, 236, 211, 11, 142, 31, 234, 110, 211, 11, 142, 31, - 213, 156, 211, 11, 142, 31, 91, 228, 109, 211, 11, 142, 31, 103, 228, - 109, 211, 11, 142, 31, 115, 228, 109, 211, 11, 142, 31, 232, 90, 228, - 109, 211, 11, 142, 31, 232, 185, 228, 109, 211, 11, 142, 31, 202, 131, - 228, 109, 211, 11, 142, 31, 203, 242, 228, 109, 211, 11, 142, 31, 234, - 121, 228, 109, 211, 11, 142, 31, 213, 161, 228, 109, 211, 11, 142, 31, - 91, 188, 211, 11, 142, 31, 103, 188, 211, 11, 142, 31, 115, 188, 211, 11, - 142, 31, 232, 90, 188, 211, 11, 142, 31, 232, 185, 188, 211, 11, 142, 31, - 202, 131, 188, 211, 11, 142, 31, 203, 242, 188, 211, 11, 142, 31, 234, - 121, 188, 211, 11, 142, 31, 213, 161, 188, 211, 11, 142, 31, 199, 91, - 188, 211, 11, 142, 31, 197, 29, 188, 211, 11, 142, 31, 198, 245, 188, - 211, 11, 142, 31, 232, 98, 188, 211, 11, 142, 31, 232, 231, 188, 211, 11, - 142, 31, 202, 116, 188, 211, 11, 142, 31, 203, 237, 188, 211, 11, 142, - 31, 234, 111, 188, 211, 11, 142, 31, 213, 157, 188, 211, 11, 142, 217, - 30, 211, 11, 142, 251, 106, 31, 109, 211, 11, 142, 251, 106, 31, 139, - 211, 11, 142, 251, 106, 31, 137, 211, 11, 142, 251, 106, 31, 153, 211, - 11, 142, 251, 106, 31, 173, 211, 11, 142, 251, 106, 31, 181, 211, 11, - 142, 251, 106, 31, 176, 211, 11, 142, 251, 106, 31, 184, 211, 11, 142, - 251, 106, 31, 199, 90, 211, 11, 142, 251, 106, 31, 232, 90, 228, 109, - 211, 11, 142, 251, 106, 31, 202, 131, 228, 109, 211, 11, 142, 251, 106, - 31, 103, 188, 211, 11, 142, 251, 106, 31, 199, 91, 188, 211, 11, 142, - 232, 80, 91, 230, 37, 211, 11, 142, 232, 80, 91, 202, 119, 9, 13, 251, - 141, 9, 13, 248, 195, 9, 13, 222, 234, 9, 13, 237, 212, 9, 13, 193, 131, - 9, 13, 191, 113, 9, 13, 230, 48, 9, 13, 199, 214, 9, 13, 192, 75, 9, 13, - 222, 79, 9, 13, 220, 11, 9, 13, 216, 189, 9, 13, 213, 11, 9, 13, 205, 41, - 9, 13, 251, 178, 9, 13, 233, 5, 9, 13, 205, 187, 9, 13, 208, 82, 9, 13, - 207, 66, 9, 13, 203, 104, 9, 13, 199, 109, 9, 13, 199, 24, 9, 13, 221, - 185, 9, 13, 199, 36, 9, 13, 237, 235, 9, 13, 191, 116, 9, 13, 231, 49, 9, - 13, 236, 95, 248, 195, 9, 13, 236, 95, 213, 11, 9, 13, 236, 95, 233, 5, - 9, 13, 236, 95, 208, 82, 9, 13, 89, 248, 195, 9, 13, 89, 222, 234, 9, 13, - 89, 229, 178, 9, 13, 89, 230, 48, 9, 13, 89, 192, 75, 9, 13, 89, 222, 79, - 9, 13, 89, 220, 11, 9, 13, 89, 216, 189, 9, 13, 89, 213, 11, 9, 13, 89, - 205, 41, 9, 13, 89, 251, 178, 9, 13, 89, 233, 5, 9, 13, 89, 205, 187, 9, - 13, 89, 208, 82, 9, 13, 89, 203, 104, 9, 13, 89, 199, 109, 9, 13, 89, - 199, 24, 9, 13, 89, 221, 185, 9, 13, 89, 237, 235, 9, 13, 89, 231, 49, 9, - 13, 199, 209, 222, 234, 9, 13, 199, 209, 230, 48, 9, 13, 199, 209, 192, - 75, 9, 13, 199, 209, 220, 11, 9, 13, 199, 209, 213, 11, 9, 13, 199, 209, - 205, 41, 9, 13, 199, 209, 251, 178, 9, 13, 199, 209, 205, 187, 9, 13, - 199, 209, 208, 82, 9, 13, 199, 209, 203, 104, 9, 13, 199, 209, 221, 185, - 9, 13, 199, 209, 237, 235, 9, 13, 199, 209, 231, 49, 9, 13, 199, 209, - 236, 95, 213, 11, 9, 13, 199, 209, 236, 95, 208, 82, 9, 13, 201, 31, 248, - 195, 9, 13, 201, 31, 222, 234, 9, 13, 201, 31, 229, 178, 9, 13, 201, 31, - 230, 48, 9, 13, 201, 31, 199, 214, 9, 13, 201, 31, 192, 75, 9, 13, 201, - 31, 222, 79, 9, 13, 201, 31, 216, 189, 9, 13, 201, 31, 213, 11, 9, 13, - 201, 31, 205, 41, 9, 13, 201, 31, 251, 178, 9, 13, 201, 31, 233, 5, 9, - 13, 201, 31, 205, 187, 9, 13, 201, 31, 208, 82, 9, 13, 201, 31, 203, 104, - 9, 13, 201, 31, 199, 109, 9, 13, 201, 31, 199, 24, 9, 13, 201, 31, 221, - 185, 9, 13, 201, 31, 237, 235, 9, 13, 201, 31, 191, 116, 9, 13, 201, 31, - 231, 49, 9, 13, 201, 31, 236, 95, 248, 195, 9, 13, 201, 31, 236, 95, 233, - 5, 9, 13, 218, 235, 251, 141, 9, 13, 218, 235, 248, 195, 9, 13, 218, 235, - 222, 234, 9, 13, 218, 235, 237, 212, 9, 13, 218, 235, 229, 178, 9, 13, - 218, 235, 193, 131, 9, 13, 218, 235, 191, 113, 9, 13, 218, 235, 230, 48, - 9, 13, 218, 235, 199, 214, 9, 13, 218, 235, 192, 75, 9, 13, 218, 235, - 220, 11, 9, 13, 218, 235, 216, 189, 9, 13, 218, 235, 213, 11, 9, 13, 218, - 235, 205, 41, 9, 13, 218, 235, 251, 178, 9, 13, 218, 235, 233, 5, 9, 13, - 218, 235, 205, 187, 9, 13, 218, 235, 208, 82, 9, 13, 218, 235, 207, 66, - 9, 13, 218, 235, 203, 104, 9, 13, 218, 235, 199, 109, 9, 13, 218, 235, - 199, 24, 9, 13, 218, 235, 221, 185, 9, 13, 218, 235, 199, 36, 9, 13, 218, - 235, 237, 235, 9, 13, 218, 235, 191, 116, 9, 13, 218, 235, 231, 49, 9, - 13, 235, 85, 248, 195, 9, 13, 235, 85, 222, 234, 9, 13, 235, 85, 237, - 212, 9, 13, 235, 85, 193, 131, 9, 13, 235, 85, 191, 113, 9, 13, 235, 85, - 230, 48, 9, 13, 235, 85, 199, 214, 9, 13, 235, 85, 192, 75, 9, 13, 235, - 85, 220, 11, 9, 13, 235, 85, 216, 189, 9, 13, 235, 85, 213, 11, 9, 13, - 235, 85, 205, 41, 9, 13, 235, 85, 251, 178, 9, 13, 235, 85, 233, 5, 9, - 13, 235, 85, 205, 187, 9, 13, 235, 85, 208, 82, 9, 13, 235, 85, 207, 66, - 9, 13, 235, 85, 203, 104, 9, 13, 235, 85, 199, 109, 9, 13, 235, 85, 199, - 24, 9, 13, 235, 85, 221, 185, 9, 13, 235, 85, 199, 36, 9, 13, 235, 85, - 237, 235, 9, 13, 235, 85, 191, 116, 9, 13, 235, 85, 231, 49, 9, 13, 211, - 56, 92, 4, 179, 4, 199, 163, 9, 13, 211, 56, 179, 4, 237, 212, 217, 93, - 123, 234, 160, 193, 64, 217, 93, 123, 201, 253, 193, 64, 217, 93, 123, - 193, 103, 193, 64, 217, 93, 123, 185, 193, 64, 217, 93, 123, 207, 82, - 235, 67, 217, 93, 123, 230, 167, 235, 67, 217, 93, 123, 64, 235, 67, 217, - 93, 123, 91, 80, 243, 92, 217, 93, 123, 103, 80, 243, 92, 217, 93, 123, - 115, 80, 243, 92, 217, 93, 123, 232, 90, 80, 243, 92, 217, 93, 123, 232, - 185, 80, 243, 92, 217, 93, 123, 202, 131, 80, 243, 92, 217, 93, 123, 203, - 242, 80, 243, 92, 217, 93, 123, 234, 121, 80, 243, 92, 217, 93, 123, 213, - 161, 80, 243, 92, 217, 93, 123, 91, 80, 249, 52, 217, 93, 123, 103, 80, - 249, 52, 217, 93, 123, 115, 80, 249, 52, 217, 93, 123, 232, 90, 80, 249, - 52, 217, 93, 123, 232, 185, 80, 249, 52, 217, 93, 123, 202, 131, 80, 249, - 52, 217, 93, 123, 203, 242, 80, 249, 52, 217, 93, 123, 234, 121, 80, 249, - 52, 217, 93, 123, 213, 161, 80, 249, 52, 217, 93, 123, 91, 80, 242, 215, - 217, 93, 123, 103, 80, 242, 215, 217, 93, 123, 115, 80, 242, 215, 217, - 93, 123, 232, 90, 80, 242, 215, 217, 93, 123, 232, 185, 80, 242, 215, - 217, 93, 123, 202, 131, 80, 242, 215, 217, 93, 123, 203, 242, 80, 242, - 215, 217, 93, 123, 234, 121, 80, 242, 215, 217, 93, 123, 213, 161, 80, - 242, 215, 217, 93, 123, 209, 77, 217, 93, 123, 211, 42, 217, 93, 123, - 249, 53, 217, 93, 123, 243, 1, 217, 93, 123, 201, 191, 217, 93, 123, 200, - 195, 217, 93, 123, 250, 99, 217, 93, 123, 193, 55, 217, 93, 123, 222, - 167, 217, 93, 123, 249, 96, 236, 106, 123, 228, 209, 249, 96, 236, 106, - 123, 228, 207, 236, 106, 123, 228, 206, 236, 106, 123, 228, 205, 236, - 106, 123, 228, 204, 236, 106, 123, 228, 203, 236, 106, 123, 228, 202, - 236, 106, 123, 228, 201, 236, 106, 123, 228, 200, 236, 106, 123, 228, - 199, 236, 106, 123, 228, 198, 236, 106, 123, 228, 197, 236, 106, 123, - 228, 196, 236, 106, 123, 228, 195, 236, 106, 123, 228, 194, 236, 106, - 123, 228, 193, 236, 106, 123, 228, 192, 236, 106, 123, 228, 191, 236, - 106, 123, 228, 190, 236, 106, 123, 228, 189, 236, 106, 123, 228, 188, - 236, 106, 123, 228, 187, 236, 106, 123, 228, 186, 236, 106, 123, 228, - 185, 236, 106, 123, 228, 184, 236, 106, 123, 228, 183, 236, 106, 123, - 228, 182, 236, 106, 123, 228, 181, 236, 106, 123, 228, 180, 236, 106, - 123, 228, 179, 236, 106, 123, 228, 178, 236, 106, 123, 228, 177, 236, - 106, 123, 228, 176, 236, 106, 123, 228, 175, 236, 106, 123, 228, 174, - 236, 106, 123, 228, 173, 236, 106, 123, 228, 172, 236, 106, 123, 228, - 171, 236, 106, 123, 228, 170, 236, 106, 123, 228, 169, 236, 106, 123, - 228, 168, 236, 106, 123, 228, 167, 236, 106, 123, 228, 166, 236, 106, - 123, 228, 165, 236, 106, 123, 228, 164, 236, 106, 123, 228, 163, 236, - 106, 123, 228, 162, 236, 106, 123, 228, 161, 236, 106, 123, 228, 160, - 236, 106, 123, 228, 159, 236, 106, 123, 81, 249, 96, 236, 106, 123, 195, - 131, 236, 106, 123, 195, 130, 236, 106, 123, 195, 129, 236, 106, 123, - 195, 128, 236, 106, 123, 195, 127, 236, 106, 123, 195, 126, 236, 106, - 123, 195, 125, 236, 106, 123, 195, 124, 236, 106, 123, 195, 123, 236, - 106, 123, 195, 122, 236, 106, 123, 195, 121, 236, 106, 123, 195, 120, - 236, 106, 123, 195, 119, 236, 106, 123, 195, 118, 236, 106, 123, 195, - 117, 236, 106, 123, 195, 116, 236, 106, 123, 195, 115, 236, 106, 123, - 195, 114, 236, 106, 123, 195, 113, 236, 106, 123, 195, 112, 236, 106, - 123, 195, 111, 236, 106, 123, 195, 110, 236, 106, 123, 195, 109, 236, - 106, 123, 195, 108, 236, 106, 123, 195, 107, 236, 106, 123, 195, 106, - 236, 106, 123, 195, 105, 236, 106, 123, 195, 104, 236, 106, 123, 195, - 103, 236, 106, 123, 195, 102, 236, 106, 123, 195, 101, 236, 106, 123, - 195, 100, 236, 106, 123, 195, 99, 236, 106, 123, 195, 98, 236, 106, 123, - 195, 97, 236, 106, 123, 195, 96, 236, 106, 123, 195, 95, 236, 106, 123, - 195, 94, 236, 106, 123, 195, 93, 236, 106, 123, 195, 92, 236, 106, 123, - 195, 91, 236, 106, 123, 195, 90, 236, 106, 123, 195, 89, 236, 106, 123, - 195, 88, 236, 106, 123, 195, 87, 236, 106, 123, 195, 86, 236, 106, 123, - 195, 85, 236, 106, 123, 195, 84, 236, 106, 123, 195, 83, 209, 87, 247, - 53, 249, 96, 209, 87, 247, 53, 252, 1, 80, 201, 239, 209, 87, 247, 53, - 103, 80, 201, 239, 209, 87, 247, 53, 115, 80, 201, 239, 209, 87, 247, 53, - 232, 90, 80, 201, 239, 209, 87, 247, 53, 232, 185, 80, 201, 239, 209, 87, - 247, 53, 202, 131, 80, 201, 239, 209, 87, 247, 53, 203, 242, 80, 201, - 239, 209, 87, 247, 53, 234, 121, 80, 201, 239, 209, 87, 247, 53, 213, - 161, 80, 201, 239, 209, 87, 247, 53, 199, 91, 80, 201, 239, 209, 87, 247, - 53, 223, 2, 80, 201, 239, 209, 87, 247, 53, 221, 53, 80, 201, 239, 209, - 87, 247, 53, 208, 10, 80, 201, 239, 209, 87, 247, 53, 221, 115, 80, 201, - 239, 209, 87, 247, 53, 252, 1, 80, 229, 189, 209, 87, 247, 53, 103, 80, - 229, 189, 209, 87, 247, 53, 115, 80, 229, 189, 209, 87, 247, 53, 232, 90, - 80, 229, 189, 209, 87, 247, 53, 232, 185, 80, 229, 189, 209, 87, 247, 53, - 202, 131, 80, 229, 189, 209, 87, 247, 53, 203, 242, 80, 229, 189, 209, - 87, 247, 53, 234, 121, 80, 229, 189, 209, 87, 247, 53, 213, 161, 80, 229, - 189, 209, 87, 247, 53, 199, 91, 80, 229, 189, 209, 87, 247, 53, 223, 2, - 80, 229, 189, 209, 87, 247, 53, 221, 53, 80, 229, 189, 209, 87, 247, 53, - 208, 10, 80, 229, 189, 209, 87, 247, 53, 221, 115, 80, 229, 189, 209, 87, - 247, 53, 207, 82, 222, 167, 209, 87, 247, 53, 252, 1, 80, 236, 242, 209, - 87, 247, 53, 103, 80, 236, 242, 209, 87, 247, 53, 115, 80, 236, 242, 209, - 87, 247, 53, 232, 90, 80, 236, 242, 209, 87, 247, 53, 232, 185, 80, 236, - 242, 209, 87, 247, 53, 202, 131, 80, 236, 242, 209, 87, 247, 53, 203, - 242, 80, 236, 242, 209, 87, 247, 53, 234, 121, 80, 236, 242, 209, 87, - 247, 53, 213, 161, 80, 236, 242, 209, 87, 247, 53, 199, 91, 80, 236, 242, - 209, 87, 247, 53, 223, 2, 80, 236, 242, 209, 87, 247, 53, 221, 53, 80, - 236, 242, 209, 87, 247, 53, 208, 10, 80, 236, 242, 209, 87, 247, 53, 221, - 115, 80, 236, 242, 209, 87, 247, 53, 62, 222, 167, 209, 87, 247, 53, 252, - 1, 80, 242, 156, 209, 87, 247, 53, 103, 80, 242, 156, 209, 87, 247, 53, - 115, 80, 242, 156, 209, 87, 247, 53, 232, 90, 80, 242, 156, 209, 87, 247, - 53, 232, 185, 80, 242, 156, 209, 87, 247, 53, 202, 131, 80, 242, 156, - 209, 87, 247, 53, 203, 242, 80, 242, 156, 209, 87, 247, 53, 234, 121, 80, - 242, 156, 209, 87, 247, 53, 213, 161, 80, 242, 156, 209, 87, 247, 53, - 199, 91, 80, 242, 156, 209, 87, 247, 53, 223, 2, 80, 242, 156, 209, 87, - 247, 53, 221, 53, 80, 242, 156, 209, 87, 247, 53, 208, 10, 80, 242, 156, - 209, 87, 247, 53, 221, 115, 80, 242, 156, 209, 87, 247, 53, 64, 222, 167, - 209, 87, 247, 53, 232, 121, 209, 87, 247, 53, 197, 196, 209, 87, 247, 53, - 197, 185, 209, 87, 247, 53, 197, 182, 209, 87, 247, 53, 197, 181, 209, - 87, 247, 53, 197, 180, 209, 87, 247, 53, 197, 179, 209, 87, 247, 53, 197, - 178, 209, 87, 247, 53, 197, 177, 209, 87, 247, 53, 197, 176, 209, 87, - 247, 53, 197, 195, 209, 87, 247, 53, 197, 194, 209, 87, 247, 53, 197, - 193, 209, 87, 247, 53, 197, 192, 209, 87, 247, 53, 197, 191, 209, 87, - 247, 53, 197, 190, 209, 87, 247, 53, 197, 189, 209, 87, 247, 53, 197, - 188, 209, 87, 247, 53, 197, 187, 209, 87, 247, 53, 197, 186, 209, 87, - 247, 53, 197, 184, 209, 87, 247, 53, 197, 183, 17, 191, 78, 232, 42, 201, - 58, 17, 191, 78, 242, 26, 17, 91, 242, 26, 17, 103, 242, 26, 17, 115, - 242, 26, 17, 232, 90, 242, 26, 17, 232, 185, 242, 26, 17, 202, 131, 242, - 26, 17, 203, 242, 242, 26, 17, 234, 121, 242, 26, 17, 213, 161, 242, 26, - 236, 196, 47, 49, 17, 191, 77, 236, 196, 214, 92, 47, 49, 17, 191, 77, - 47, 191, 78, 4, 202, 92, 47, 251, 34, 55, 47, 236, 110, 3, 4, 210, 250, - 249, 91, 127, 8, 6, 1, 65, 127, 8, 6, 1, 250, 70, 127, 8, 6, 1, 247, 145, - 127, 8, 6, 1, 238, 80, 127, 8, 6, 1, 73, 127, 8, 6, 1, 233, 134, 127, 8, - 6, 1, 232, 14, 127, 8, 6, 1, 230, 83, 127, 8, 6, 1, 70, 127, 8, 6, 1, - 223, 7, 127, 8, 6, 1, 222, 125, 127, 8, 6, 1, 170, 127, 8, 6, 1, 218, - 147, 127, 8, 6, 1, 215, 47, 127, 8, 6, 1, 74, 127, 8, 6, 1, 210, 226, - 127, 8, 6, 1, 208, 97, 127, 8, 6, 1, 148, 127, 8, 6, 1, 206, 3, 127, 8, - 6, 1, 200, 39, 127, 8, 6, 1, 69, 127, 8, 6, 1, 196, 8, 127, 8, 6, 1, 193, - 221, 127, 8, 6, 1, 192, 235, 127, 8, 6, 1, 192, 159, 127, 8, 6, 1, 191, - 166, 198, 37, 203, 98, 248, 4, 8, 6, 1, 206, 3, 47, 43, 8, 6, 1, 247, - 145, 47, 43, 8, 6, 1, 148, 47, 246, 251, 47, 192, 237, 238, 216, 113, - 112, 8, 6, 1, 65, 112, 8, 6, 1, 250, 70, 112, 8, 6, 1, 247, 145, 112, 8, - 6, 1, 238, 80, 112, 8, 6, 1, 73, 112, 8, 6, 1, 233, 134, 112, 8, 6, 1, - 232, 14, 112, 8, 6, 1, 230, 83, 112, 8, 6, 1, 70, 112, 8, 6, 1, 223, 7, - 112, 8, 6, 1, 222, 125, 112, 8, 6, 1, 170, 112, 8, 6, 1, 218, 147, 112, - 8, 6, 1, 215, 47, 112, 8, 6, 1, 74, 112, 8, 6, 1, 210, 226, 112, 8, 6, 1, - 208, 97, 112, 8, 6, 1, 148, 112, 8, 6, 1, 206, 3, 112, 8, 6, 1, 200, 39, - 112, 8, 6, 1, 69, 112, 8, 6, 1, 196, 8, 112, 8, 6, 1, 193, 221, 112, 8, - 6, 1, 192, 235, 112, 8, 6, 1, 192, 159, 112, 8, 6, 1, 191, 166, 112, 228, - 95, 112, 215, 73, 112, 205, 65, 112, 201, 173, 112, 208, 241, 112, 193, - 124, 214, 92, 47, 8, 6, 1, 65, 214, 92, 47, 8, 6, 1, 250, 70, 214, 92, - 47, 8, 6, 1, 247, 145, 214, 92, 47, 8, 6, 1, 238, 80, 214, 92, 47, 8, 6, - 1, 73, 214, 92, 47, 8, 6, 1, 233, 134, 214, 92, 47, 8, 6, 1, 232, 14, - 214, 92, 47, 8, 6, 1, 230, 83, 214, 92, 47, 8, 6, 1, 70, 214, 92, 47, 8, - 6, 1, 223, 7, 214, 92, 47, 8, 6, 1, 222, 125, 214, 92, 47, 8, 6, 1, 170, - 214, 92, 47, 8, 6, 1, 218, 147, 214, 92, 47, 8, 6, 1, 215, 47, 214, 92, - 47, 8, 6, 1, 74, 214, 92, 47, 8, 6, 1, 210, 226, 214, 92, 47, 8, 6, 1, - 208, 97, 214, 92, 47, 8, 6, 1, 148, 214, 92, 47, 8, 6, 1, 206, 3, 214, - 92, 47, 8, 6, 1, 200, 39, 214, 92, 47, 8, 6, 1, 69, 214, 92, 47, 8, 6, 1, - 196, 8, 214, 92, 47, 8, 6, 1, 193, 221, 214, 92, 47, 8, 6, 1, 192, 235, - 214, 92, 47, 8, 6, 1, 192, 159, 214, 92, 47, 8, 6, 1, 191, 166, 207, 142, - 216, 220, 57, 207, 142, 216, 216, 57, 207, 142, 215, 148, 57, 47, 247, - 18, 47, 247, 146, 4, 210, 250, 249, 91, 47, 228, 114, 232, 227, 214, 92, - 112, 8, 6, 1, 65, 214, 92, 112, 8, 6, 1, 250, 70, 214, 92, 112, 8, 6, 1, - 247, 145, 214, 92, 112, 8, 6, 1, 238, 80, 214, 92, 112, 8, 6, 1, 73, 214, - 92, 112, 8, 6, 1, 233, 134, 214, 92, 112, 8, 6, 1, 232, 14, 214, 92, 112, - 8, 6, 1, 230, 83, 214, 92, 112, 8, 6, 1, 70, 214, 92, 112, 8, 6, 1, 223, - 7, 214, 92, 112, 8, 6, 1, 222, 125, 214, 92, 112, 8, 6, 1, 170, 214, 92, - 112, 8, 6, 1, 218, 147, 214, 92, 112, 8, 6, 1, 215, 47, 214, 92, 112, 8, - 6, 1, 74, 214, 92, 112, 8, 6, 1, 210, 226, 214, 92, 112, 8, 6, 1, 208, - 97, 214, 92, 112, 8, 6, 1, 148, 214, 92, 112, 8, 6, 1, 206, 3, 214, 92, - 112, 8, 6, 1, 200, 39, 214, 92, 112, 8, 6, 1, 69, 214, 92, 112, 8, 6, 1, - 196, 8, 214, 92, 112, 8, 6, 1, 193, 221, 214, 92, 112, 8, 6, 1, 192, 235, - 214, 92, 112, 8, 6, 1, 192, 159, 214, 92, 112, 8, 6, 1, 191, 166, 238, - 167, 214, 92, 112, 8, 6, 1, 210, 226, 214, 92, 112, 227, 254, 214, 92, - 112, 168, 214, 92, 112, 189, 214, 92, 112, 252, 103, 214, 92, 112, 193, - 124, 51, 236, 149, 112, 242, 199, 112, 238, 223, 112, 232, 70, 112, 227, - 245, 112, 214, 65, 112, 214, 56, 112, 211, 114, 112, 202, 4, 112, 132, 4, - 233, 175, 77, 112, 194, 249, 112, 115, 238, 80, 112, 205, 52, 205, 71, - 112, 103, 222, 125, 112, 232, 90, 222, 125, 112, 234, 121, 222, 125, 112, - 232, 185, 209, 55, 108, 112, 203, 242, 209, 55, 108, 112, 197, 17, 209, - 55, 109, 112, 202, 116, 210, 226, 112, 91, 228, 110, 197, 29, 210, 226, - 112, 8, 2, 1, 238, 80, 112, 229, 216, 112, 229, 215, 112, 229, 118, 112, - 218, 228, 112, 202, 236, 112, 196, 136, 112, 195, 18, 217, 17, 193, 21, - 113, 207, 74, 223, 117, 16, 1, 65, 207, 74, 223, 117, 16, 1, 250, 70, - 207, 74, 223, 117, 16, 1, 247, 145, 207, 74, 223, 117, 16, 1, 238, 80, - 207, 74, 223, 117, 16, 1, 73, 207, 74, 223, 117, 16, 1, 233, 134, 207, - 74, 223, 117, 16, 1, 232, 14, 207, 74, 223, 117, 16, 1, 230, 83, 207, 74, - 223, 117, 16, 1, 70, 207, 74, 223, 117, 16, 1, 223, 7, 207, 74, 223, 117, - 16, 1, 222, 125, 207, 74, 223, 117, 16, 1, 170, 207, 74, 223, 117, 16, 1, - 218, 147, 207, 74, 223, 117, 16, 1, 215, 47, 207, 74, 223, 117, 16, 1, - 74, 207, 74, 223, 117, 16, 1, 210, 226, 207, 74, 223, 117, 16, 1, 208, - 97, 207, 74, 223, 117, 16, 1, 148, 207, 74, 223, 117, 16, 1, 206, 3, 207, - 74, 223, 117, 16, 1, 200, 39, 207, 74, 223, 117, 16, 1, 69, 207, 74, 223, - 117, 16, 1, 196, 8, 207, 74, 223, 117, 16, 1, 193, 221, 207, 74, 223, - 117, 16, 1, 192, 235, 207, 74, 223, 117, 16, 1, 192, 159, 207, 74, 223, - 117, 16, 1, 191, 166, 51, 229, 88, 228, 233, 112, 71, 221, 25, 112, 71, - 189, 112, 12, 196, 91, 225, 188, 112, 12, 196, 91, 225, 192, 112, 12, - 196, 91, 225, 200, 112, 71, 237, 101, 112, 12, 196, 91, 225, 207, 112, - 12, 196, 91, 225, 194, 112, 12, 196, 91, 225, 166, 112, 12, 196, 91, 225, - 193, 112, 12, 196, 91, 225, 206, 112, 12, 196, 91, 225, 180, 112, 12, - 196, 91, 225, 173, 112, 12, 196, 91, 225, 182, 112, 12, 196, 91, 225, - 203, 112, 12, 196, 91, 225, 189, 112, 12, 196, 91, 225, 205, 112, 12, - 196, 91, 225, 181, 112, 12, 196, 91, 225, 204, 112, 12, 196, 91, 225, - 167, 112, 12, 196, 91, 225, 172, 112, 12, 196, 91, 225, 165, 112, 12, - 196, 91, 225, 195, 112, 12, 196, 91, 225, 197, 112, 12, 196, 91, 225, - 175, 112, 12, 196, 91, 225, 186, 112, 12, 196, 91, 225, 184, 112, 12, - 196, 91, 225, 210, 112, 12, 196, 91, 225, 209, 112, 12, 196, 91, 225, - 163, 112, 12, 196, 91, 225, 190, 112, 12, 196, 91, 225, 208, 112, 12, - 196, 91, 225, 199, 112, 12, 196, 91, 225, 185, 112, 12, 196, 91, 225, - 164, 112, 12, 196, 91, 225, 187, 112, 12, 196, 91, 225, 169, 112, 12, - 196, 91, 225, 168, 112, 12, 196, 91, 225, 198, 112, 12, 196, 91, 225, - 176, 112, 12, 196, 91, 225, 178, 112, 12, 196, 91, 225, 179, 112, 12, - 196, 91, 225, 171, 112, 12, 196, 91, 225, 202, 112, 12, 196, 91, 225, - 196, 112, 12, 196, 91, 225, 162, 198, 37, 203, 98, 248, 4, 12, 196, 91, - 225, 177, 198, 37, 203, 98, 248, 4, 12, 196, 91, 225, 209, 198, 37, 203, - 98, 248, 4, 12, 196, 91, 225, 207, 198, 37, 203, 98, 248, 4, 12, 196, 91, - 225, 191, 198, 37, 203, 98, 248, 4, 12, 196, 91, 225, 174, 198, 37, 203, - 98, 248, 4, 12, 196, 91, 225, 187, 198, 37, 203, 98, 248, 4, 12, 196, 91, - 225, 170, 198, 37, 203, 98, 248, 4, 12, 196, 91, 225, 201, 198, 37, 203, - 98, 248, 4, 12, 196, 91, 225, 183, 47, 227, 241, 251, 231, 47, 227, 241, - 252, 6, 206, 108, 16, 39, 232, 48, 206, 108, 16, 39, 218, 203, 206, 108, - 16, 39, 203, 18, 206, 108, 16, 39, 192, 207, 206, 108, 16, 39, 202, 253, - 206, 108, 16, 39, 247, 100, 238, 92, 232, 133, 242, 171, 196, 113, 213, - 177, 4, 201, 94, 200, 188, 138, 215, 167, 200, 187, 242, 203, 250, 133, - 235, 17, 200, 186, 138, 247, 205, 207, 143, 247, 237, 250, 133, 213, 176, - 193, 142, 193, 136, 195, 11, 216, 34, 193, 126, 234, 164, 230, 232, 233, - 191, 234, 164, 230, 232, 251, 89, 234, 164, 230, 232, 250, 152, 230, 232, - 4, 216, 158, 214, 66, 215, 189, 113, 193, 128, 238, 181, 215, 189, 113, - 232, 197, 208, 18, 215, 189, 113, 193, 128, 231, 12, 215, 189, 113, 232, - 42, 215, 189, 113, 193, 157, 231, 12, 215, 189, 113, 219, 238, 208, 18, - 215, 189, 113, 193, 157, 238, 181, 215, 189, 113, 238, 181, 215, 188, - 214, 66, 215, 189, 4, 233, 62, 232, 197, 208, 18, 215, 189, 4, 233, 62, - 219, 238, 208, 18, 215, 189, 4, 233, 62, 232, 42, 215, 189, 4, 233, 62, - 200, 194, 4, 233, 62, 230, 228, 201, 97, 203, 40, 201, 97, 199, 16, 62, - 235, 53, 64, 200, 193, 64, 200, 194, 4, 2, 242, 162, 64, 200, 194, 248, - 192, 242, 162, 64, 200, 194, 248, 192, 242, 163, 4, 207, 144, 242, 163, - 4, 207, 144, 242, 163, 4, 202, 47, 242, 163, 4, 219, 105, 242, 163, 4, - 198, 41, 232, 134, 193, 65, 248, 68, 233, 62, 228, 150, 236, 117, 199, - 222, 247, 180, 243, 55, 205, 43, 233, 185, 197, 250, 237, 94, 197, 250, - 210, 173, 197, 250, 247, 105, 228, 150, 210, 6, 197, 74, 243, 59, 248, - 71, 206, 121, 229, 117, 200, 191, 248, 71, 234, 168, 80, 217, 82, 234, - 168, 80, 206, 240, 229, 161, 232, 90, 219, 210, 242, 161, 217, 49, 219, - 209, 233, 43, 219, 209, 219, 210, 232, 141, 223, 135, 193, 64, 215, 84, - 198, 78, 250, 112, 230, 184, 216, 177, 193, 140, 199, 182, 219, 177, 249, - 48, 209, 124, 207, 82, 250, 252, 230, 167, 250, 252, 210, 46, 210, 50, - 243, 60, 201, 37, 230, 30, 202, 84, 80, 209, 104, 216, 206, 211, 94, 248, - 50, 209, 2, 219, 188, 206, 241, 238, 187, 206, 241, 249, 61, 238, 226, - 206, 240, 238, 120, 24, 206, 240, 201, 78, 248, 18, 201, 238, 247, 251, - 232, 68, 232, 64, 206, 147, 200, 138, 209, 5, 237, 190, 211, 141, 200, - 160, 232, 65, 203, 8, 232, 196, 247, 99, 4, 200, 130, 237, 35, 202, 27, - 227, 253, 238, 185, 203, 116, 227, 252, 227, 253, 238, 185, 235, 82, 238, - 225, 243, 18, 164, 247, 70, 219, 0, 238, 111, 228, 222, 209, 7, 203, 24, - 248, 172, 248, 14, 209, 8, 80, 232, 122, 238, 224, 232, 111, 24, 221, 54, - 199, 128, 193, 51, 229, 254, 205, 171, 248, 31, 24, 238, 134, 193, 61, - 230, 236, 242, 46, 230, 236, 197, 200, 235, 60, 248, 203, 215, 124, 242, - 178, 248, 203, 215, 123, 249, 99, 248, 30, 232, 111, 24, 221, 55, 4, 209, - 89, 248, 31, 4, 209, 23, 238, 212, 209, 25, 206, 242, 193, 11, 208, 215, - 248, 109, 247, 98, 223, 1, 243, 8, 197, 250, 233, 26, 243, 7, 232, 199, - 232, 200, 201, 236, 249, 59, 210, 92, 209, 24, 239, 6, 249, 61, 199, 186, - 197, 250, 238, 167, 232, 171, 209, 125, 237, 91, 222, 247, 236, 109, 247, - 42, 201, 36, 193, 65, 243, 34, 215, 189, 195, 51, 246, 216, 205, 85, 205, - 115, 230, 191, 247, 63, 229, 192, 4, 198, 131, 211, 94, 199, 29, 219, - 200, 248, 24, 80, 232, 145, 216, 36, 216, 200, 207, 53, 206, 242, 37, - 221, 196, 4, 223, 0, 201, 6, 216, 70, 219, 144, 202, 81, 238, 231, 221, - 48, 248, 219, 250, 163, 37, 212, 244, 248, 219, 237, 41, 37, 212, 244, - 232, 215, 232, 74, 251, 235, 198, 175, 247, 43, 228, 152, 232, 248, 193, - 91, 206, 134, 242, 49, 232, 191, 209, 46, 24, 232, 195, 216, 70, 215, - 153, 247, 84, 242, 222, 229, 199, 250, 174, 210, 178, 198, 49, 229, 232, - 242, 208, 199, 82, 198, 176, 242, 194, 248, 59, 209, 253, 250, 172, 195, - 62, 231, 177, 236, 189, 229, 85, 202, 74, 217, 127, 248, 122, 231, 178, - 236, 235, 248, 17, 232, 147, 209, 87, 247, 51, 37, 212, 249, 215, 114, - 37, 212, 244, 205, 99, 230, 129, 37, 221, 195, 197, 175, 195, 39, 37, - 205, 77, 206, 37, 203, 55, 4, 205, 118, 199, 87, 207, 165, 24, 249, 61, - 202, 104, 24, 202, 104, 248, 43, 249, 18, 24, 228, 215, 243, 61, 232, - 177, 202, 46, 206, 38, 200, 165, 201, 197, 216, 200, 197, 201, 228, 153, - 207, 166, 251, 90, 232, 119, 206, 51, 232, 119, 200, 133, 193, 108, 219, - 110, 230, 213, 207, 167, 215, 175, 207, 167, 247, 54, 238, 178, 249, 15, - 24, 249, 61, 195, 10, 232, 237, 228, 236, 201, 70, 24, 249, 61, 227, 253, - 228, 236, 201, 70, 24, 208, 150, 199, 229, 199, 87, 210, 197, 24, 249, - 61, 202, 48, 247, 59, 215, 168, 247, 82, 248, 222, 4, 196, 113, 247, 207, - 238, 245, 228, 142, 247, 205, 242, 202, 237, 45, 228, 142, 247, 206, 242, - 192, 247, 206, 237, 37, 237, 38, 223, 32, 214, 194, 210, 99, 201, 108, - 228, 142, 247, 206, 228, 142, 4, 231, 161, 211, 132, 247, 206, 222, 247, - 209, 13, 211, 131, 233, 190, 209, 13, 211, 131, 228, 151, 249, 42, 250, - 101, 199, 97, 217, 127, 228, 147, 218, 220, 228, 147, 238, 229, 201, 52, - 205, 84, 237, 49, 201, 52, 233, 51, 223, 12, 219, 250, 222, 247, 247, 32, - 233, 190, 247, 32, 64, 210, 19, 62, 210, 19, 193, 134, 64, 232, 177, 193, - 134, 62, 232, 177, 206, 120, 62, 206, 120, 220, 93, 249, 82, 207, 165, - 24, 202, 239, 248, 22, 24, 55, 251, 85, 234, 67, 59, 232, 186, 196, 249, - 234, 67, 59, 232, 186, 196, 246, 234, 67, 59, 232, 186, 196, 244, 234, - 67, 59, 232, 186, 196, 242, 234, 67, 59, 232, 186, 196, 240, 207, 125, - 215, 165, 210, 237, 193, 142, 247, 211, 238, 192, 198, 168, 219, 161, - 207, 169, 247, 30, 235, 67, 238, 176, 193, 94, 202, 55, 202, 53, 228, - 152, 207, 137, 230, 219, 203, 102, 215, 208, 206, 124, 243, 45, 236, 117, - 209, 138, 248, 61, 234, 88, 211, 144, 201, 213, 203, 97, 247, 210, 251, - 38, 228, 221, 220, 84, 248, 201, 232, 195, 197, 200, 232, 195, 248, 69, - 197, 51, 229, 230, 243, 46, 249, 99, 243, 46, 232, 58, 249, 99, 243, 46, - 248, 112, 210, 21, 221, 37, 209, 29, 235, 57, 247, 86, 249, 87, 247, 86, - 236, 108, 215, 166, 233, 62, 238, 193, 233, 62, 198, 169, 233, 62, 207, - 170, 233, 62, 247, 31, 233, 62, 235, 68, 233, 62, 201, 195, 193, 94, 228, - 153, 233, 62, 215, 209, 233, 62, 236, 118, 233, 62, 209, 139, 233, 62, - 232, 62, 233, 62, 230, 26, 233, 62, 193, 38, 233, 62, 248, 216, 233, 62, - 210, 152, 233, 62, 209, 139, 213, 0, 210, 66, 208, 201, 243, 29, 233, - 144, 233, 152, 234, 167, 213, 0, 215, 163, 198, 56, 64, 132, 209, 51, - 249, 94, 223, 120, 64, 143, 209, 51, 249, 94, 223, 120, 64, 45, 209, 51, - 249, 94, 223, 120, 64, 50, 209, 51, 249, 94, 223, 120, 232, 189, 230, 21, - 57, 193, 134, 230, 21, 57, 211, 115, 230, 21, 57, 198, 206, 132, 57, 198, - 206, 143, 57, 242, 193, 229, 252, 57, 211, 66, 229, 252, 57, 238, 161, - 193, 34, 229, 232, 233, 147, 214, 97, 200, 37, 222, 237, 235, 62, 221, - 118, 248, 125, 193, 34, 242, 164, 208, 130, 230, 0, 209, 3, 217, 58, 203, - 47, 250, 128, 203, 47, 229, 102, 203, 47, 193, 34, 205, 134, 193, 34, - 248, 42, 232, 117, 247, 172, 223, 135, 202, 182, 247, 171, 223, 135, 202, - 182, 248, 12, 230, 248, 217, 70, 193, 35, 233, 40, 217, 71, 24, 193, 36, - 228, 230, 229, 251, 103, 216, 168, 228, 230, 229, 251, 103, 193, 33, 228, - 230, 229, 251, 209, 43, 211, 130, 193, 36, 4, 247, 191, 234, 165, 247, - 238, 4, 195, 141, 209, 242, 4, 248, 73, 230, 45, 217, 71, 4, 230, 143, - 209, 177, 217, 53, 217, 71, 4, 197, 59, 211, 107, 217, 70, 211, 107, 193, - 35, 249, 98, 238, 246, 193, 19, 208, 206, 222, 247, 211, 125, 222, 247, - 230, 218, 231, 24, 249, 99, 251, 69, 233, 157, 251, 131, 251, 132, 215, - 198, 223, 140, 202, 98, 223, 109, 237, 34, 209, 241, 230, 137, 237, 195, - 219, 71, 214, 221, 209, 41, 233, 63, 217, 14, 230, 44, 249, 36, 209, 45, - 200, 58, 209, 131, 221, 99, 77, 218, 220, 219, 151, 206, 183, 231, 118, - 201, 60, 221, 98, 248, 23, 238, 196, 4, 229, 191, 193, 115, 248, 212, - 229, 191, 247, 230, 229, 191, 103, 229, 189, 201, 234, 229, 191, 230, - 153, 229, 191, 229, 192, 4, 55, 248, 67, 229, 191, 230, 167, 229, 191, - 192, 73, 229, 191, 208, 131, 229, 191, 229, 192, 4, 206, 242, 207, 7, - 229, 189, 229, 192, 237, 91, 236, 244, 203, 130, 4, 41, 75, 223, 89, 234, - 92, 155, 247, 203, 251, 68, 113, 248, 51, 202, 87, 113, 242, 37, 113, - 201, 207, 200, 140, 113, 235, 53, 237, 171, 113, 209, 132, 80, 209, 30, - 232, 159, 248, 137, 236, 150, 113, 201, 225, 249, 59, 198, 226, 249, 59, - 64, 232, 146, 228, 110, 209, 49, 113, 215, 213, 249, 80, 238, 123, 233, - 177, 88, 236, 110, 57, 238, 183, 247, 52, 249, 41, 4, 192, 71, 57, 249, - 41, 4, 236, 110, 57, 249, 41, 4, 233, 193, 57, 249, 41, 4, 209, 1, 57, - 215, 213, 4, 193, 59, 243, 89, 4, 196, 62, 197, 246, 24, 192, 71, 57, - 205, 55, 209, 240, 239, 11, 247, 236, 216, 24, 232, 151, 236, 175, 211, - 49, 236, 181, 235, 11, 232, 222, 232, 131, 211, 66, 232, 222, 232, 131, - 210, 195, 4, 238, 128, 210, 195, 233, 55, 196, 73, 247, 92, 199, 125, - 247, 92, 247, 53, 223, 120, 243, 89, 4, 196, 62, 197, 245, 243, 89, 4, - 235, 75, 197, 245, 249, 38, 243, 88, 242, 177, 208, 126, 206, 110, 208, - 126, 210, 124, 201, 48, 206, 45, 197, 234, 206, 45, 248, 47, 199, 227, - 219, 205, 212, 247, 212, 248, 4, 237, 90, 238, 195, 242, 171, 248, 48, - 211, 66, 248, 48, 230, 167, 248, 48, 248, 67, 248, 48, 211, 44, 248, 48, - 248, 45, 214, 214, 249, 84, 205, 68, 216, 169, 199, 102, 207, 96, 210, - 193, 233, 23, 217, 127, 205, 114, 251, 35, 208, 151, 251, 243, 218, 222, - 243, 71, 216, 182, 211, 3, 197, 254, 223, 131, 197, 254, 210, 202, 234, - 220, 113, 223, 128, 234, 25, 234, 26, 4, 235, 75, 63, 56, 242, 171, 217, - 88, 4, 218, 213, 232, 177, 242, 171, 217, 88, 4, 207, 142, 232, 177, 211, - 66, 217, 88, 4, 207, 142, 232, 177, 211, 66, 217, 88, 4, 218, 213, 232, - 177, 209, 10, 209, 11, 228, 156, 214, 61, 215, 243, 209, 185, 215, 243, - 209, 186, 4, 96, 63, 250, 133, 219, 200, 195, 65, 215, 242, 215, 243, - 209, 186, 211, 133, 213, 31, 215, 243, 209, 184, 251, 36, 4, 249, 26, - 247, 84, 247, 85, 4, 232, 168, 195, 62, 247, 84, 199, 99, 207, 160, 195, - 61, 232, 215, 208, 186, 209, 20, 201, 72, 208, 229, 248, 221, 197, 13, - 96, 250, 181, 242, 173, 96, 24, 117, 211, 66, 242, 219, 250, 181, 242, - 173, 96, 24, 117, 211, 66, 242, 219, 250, 182, 4, 47, 91, 210, 245, 242, - 173, 235, 75, 24, 196, 62, 211, 66, 242, 219, 250, 181, 251, 34, 235, 75, - 24, 196, 62, 211, 66, 242, 219, 250, 181, 131, 247, 234, 113, 136, 247, - 234, 113, 201, 230, 4, 247, 77, 105, 201, 229, 201, 230, 4, 91, 202, 0, - 193, 136, 201, 230, 4, 115, 202, 0, 193, 135, 249, 8, 234, 92, 209, 79, - 219, 195, 217, 100, 230, 236, 206, 198, 217, 100, 230, 236, 219, 11, 4, - 223, 101, 210, 25, 242, 171, 219, 11, 4, 221, 197, 221, 197, 219, 10, - 211, 66, 219, 10, 248, 185, 248, 186, 4, 247, 77, 105, 248, 46, 219, 79, - 113, 207, 161, 247, 165, 249, 97, 4, 117, 63, 56, 234, 53, 4, 117, 63, - 56, 211, 94, 4, 233, 175, 87, 4, 45, 50, 63, 56, 202, 10, 4, 96, 63, 56, - 198, 49, 4, 196, 62, 63, 56, 213, 31, 91, 196, 101, 234, 119, 113, 221, - 194, 199, 90, 223, 95, 16, 39, 8, 6, 219, 150, 223, 95, 16, 39, 8, 2, - 219, 150, 223, 95, 16, 39, 212, 122, 223, 95, 16, 39, 200, 72, 223, 95, - 16, 39, 8, 219, 150, 232, 202, 234, 92, 198, 44, 193, 9, 230, 28, 212, - 105, 24, 248, 53, 228, 237, 209, 110, 216, 69, 199, 100, 238, 150, 249, - 61, 202, 131, 209, 53, 201, 98, 4, 82, 236, 96, 222, 247, 16, 39, 248, - 198, 197, 232, 234, 69, 62, 51, 247, 165, 64, 51, 247, 165, 219, 245, - 207, 82, 242, 218, 219, 245, 248, 67, 242, 218, 219, 245, 211, 44, 236, - 243, 219, 245, 248, 67, 236, 243, 2, 211, 44, 236, 243, 2, 248, 67, 236, - 243, 196, 72, 207, 82, 197, 237, 235, 78, 207, 82, 197, 237, 196, 72, 2, - 207, 82, 197, 237, 235, 78, 2, 207, 82, 197, 237, 110, 50, 203, 146, 64, - 242, 218, 116, 50, 203, 146, 64, 242, 218, 47, 238, 171, 209, 34, 238, - 171, 209, 35, 4, 230, 34, 60, 238, 171, 209, 34, 212, 251, 45, 204, 23, - 4, 115, 236, 94, 212, 251, 50, 204, 23, 4, 115, 236, 94, 16, 39, 217, 31, - 246, 194, 64, 8, 238, 170, 88, 8, 238, 170, 246, 234, 238, 170, 211, 103, - 113, 235, 81, 80, 210, 51, 222, 98, 215, 181, 200, 66, 216, 164, 4, 213, - 161, 247, 254, 248, 19, 80, 228, 60, 242, 175, 233, 63, 91, 211, 150, - 242, 175, 233, 63, 103, 211, 150, 242, 175, 233, 63, 115, 211, 150, 242, - 175, 233, 63, 232, 90, 211, 150, 242, 175, 233, 63, 232, 185, 211, 150, - 242, 175, 233, 63, 202, 131, 211, 150, 242, 175, 233, 63, 203, 242, 211, - 150, 242, 175, 233, 63, 234, 121, 211, 150, 242, 175, 233, 63, 213, 161, - 211, 150, 242, 175, 233, 63, 199, 91, 211, 150, 242, 175, 233, 63, 234, - 85, 211, 150, 242, 175, 233, 63, 197, 34, 211, 150, 242, 175, 233, 63, - 211, 86, 242, 175, 233, 63, 197, 7, 242, 175, 233, 63, 198, 212, 242, - 175, 233, 63, 232, 86, 242, 175, 233, 63, 232, 183, 242, 175, 233, 63, - 202, 127, 242, 175, 233, 63, 203, 241, 242, 175, 233, 63, 234, 120, 242, - 175, 233, 63, 213, 160, 242, 175, 233, 63, 199, 89, 242, 175, 233, 63, - 234, 83, 242, 175, 233, 63, 197, 32, 50, 201, 229, 50, 201, 230, 4, 91, - 202, 0, 193, 136, 50, 201, 230, 4, 115, 202, 0, 193, 135, 247, 198, 247, - 199, 4, 202, 0, 193, 135, 206, 181, 248, 185, 248, 48, 247, 75, 217, 55, - 242, 174, 62, 202, 99, 24, 238, 168, 213, 31, 209, 116, 228, 229, 217, - 71, 223, 135, 247, 174, 200, 207, 219, 141, 202, 85, 211, 46, 201, 186, - 237, 176, 200, 189, 201, 216, 201, 217, 193, 116, 222, 156, 217, 71, 237, - 194, 45, 230, 21, 199, 102, 207, 96, 199, 102, 207, 97, 4, 210, 194, 50, - 230, 21, 199, 102, 207, 96, 64, 198, 29, 199, 101, 62, 198, 29, 199, 101, - 199, 102, 211, 94, 198, 49, 80, 215, 239, 242, 197, 215, 243, 209, 185, - 249, 97, 80, 234, 25, 201, 104, 234, 25, 234, 26, 4, 219, 105, 232, 138, - 234, 25, 210, 26, 138, 201, 104, 234, 25, 219, 78, 210, 123, 62, 208, - 126, 110, 45, 210, 24, 110, 45, 249, 55, 210, 25, 110, 45, 232, 92, 210, - 25, 110, 45, 210, 187, 110, 45, 238, 186, 45, 193, 3, 230, 20, 152, 211, - 115, 230, 21, 57, 207, 142, 230, 21, 4, 232, 207, 201, 206, 207, 13, 207, - 142, 230, 21, 4, 232, 207, 201, 206, 207, 13, 198, 206, 132, 57, 207, 13, - 198, 206, 143, 57, 207, 13, 195, 64, 230, 20, 207, 13, 230, 21, 4, 82, - 232, 212, 233, 163, 207, 142, 230, 21, 4, 210, 97, 248, 160, 82, 24, 206, - 184, 232, 206, 64, 143, 209, 51, 45, 230, 21, 223, 120, 202, 201, 64, 45, - 209, 51, 223, 120, 202, 201, 64, 50, 209, 51, 223, 120, 202, 201, 62, 45, - 209, 51, 223, 120, 202, 201, 62, 50, 209, 51, 223, 120, 62, 45, 209, 51, - 249, 94, 223, 120, 62, 50, 209, 51, 249, 94, 223, 120, 202, 201, 64, 132, - 209, 51, 223, 120, 202, 201, 64, 143, 209, 51, 223, 120, 202, 201, 62, - 132, 209, 51, 223, 120, 202, 201, 62, 143, 209, 51, 223, 120, 62, 132, - 209, 51, 249, 94, 223, 120, 62, 143, 209, 51, 249, 94, 223, 120, 62, 229, - 191, 237, 33, 239, 11, 221, 196, 24, 215, 165, 115, 214, 70, 239, 10, - 208, 202, 209, 63, 247, 94, 62, 229, 240, 203, 98, 232, 151, 236, 175, - 64, 229, 240, 203, 98, 232, 151, 236, 175, 202, 27, 203, 98, 232, 151, - 236, 175, 199, 177, 247, 36, 193, 54, 221, 195, 91, 247, 166, 215, 165, - 103, 247, 166, 215, 165, 115, 247, 166, 215, 165, 198, 20, 38, 209, 240, - 239, 11, 229, 240, 236, 175, 205, 71, 208, 203, 227, 246, 233, 23, 227, - 246, 211, 49, 236, 182, 227, 246, 236, 123, 4, 199, 48, 236, 123, 4, 199, - 49, 24, 209, 168, 236, 123, 4, 209, 168, 232, 76, 4, 209, 168, 232, 76, - 4, 198, 145, 232, 76, 4, 251, 82, 192, 235, 62, 232, 131, 232, 131, 211, - 66, 232, 131, 247, 53, 140, 236, 159, 247, 53, 232, 222, 248, 14, 232, - 222, 247, 107, 234, 63, 212, 249, 234, 63, 212, 250, 210, 194, 234, 63, - 212, 250, 210, 200, 212, 249, 212, 250, 210, 194, 212, 250, 210, 200, - 234, 63, 236, 122, 234, 63, 210, 194, 234, 63, 210, 192, 236, 122, 210, - 194, 210, 192, 193, 146, 201, 213, 212, 250, 210, 200, 201, 213, 247, 93, - 210, 200, 237, 33, 193, 63, 216, 21, 217, 3, 210, 248, 242, 173, 50, 24, - 45, 204, 23, 250, 181, 247, 77, 192, 235, 223, 126, 232, 124, 202, 111, - 113, 237, 89, 232, 124, 202, 111, 113, 239, 12, 38, 221, 197, 206, 135, - 214, 61, 210, 195, 4, 47, 199, 48, 201, 62, 243, 88, 237, 224, 221, 54, - 219, 72, 201, 228, 229, 204, 223, 135, 202, 182, 115, 207, 115, 56, 115, - 207, 115, 60, 115, 207, 115, 219, 200, 115, 207, 115, 187, 45, 201, 225, - 247, 216, 50, 201, 225, 247, 216, 103, 201, 225, 247, 215, 115, 201, 225, - 247, 215, 45, 198, 226, 247, 216, 50, 198, 226, 247, 216, 45, 251, 68, - 247, 216, 50, 251, 68, 247, 216, 215, 193, 247, 216, 219, 106, 215, 193, - 247, 216, 219, 106, 215, 192, 249, 57, 111, 4, 249, 56, 249, 57, 27, 192, - 235, 249, 57, 111, 4, 27, 192, 235, 249, 57, 28, 27, 192, 235, 249, 57, - 111, 4, 28, 27, 192, 235, 155, 243, 78, 77, 249, 57, 111, 4, 28, 243, 77, - 193, 18, 217, 51, 215, 170, 232, 43, 198, 80, 198, 25, 201, 87, 80, 219, - 120, 202, 183, 80, 222, 248, 215, 151, 230, 163, 233, 62, 230, 163, 233, - 63, 4, 202, 59, 233, 144, 233, 63, 4, 199, 121, 80, 222, 158, 202, 59, - 233, 63, 4, 211, 66, 215, 163, 202, 59, 233, 63, 4, 211, 66, 215, 164, - 24, 202, 59, 233, 144, 202, 59, 233, 63, 4, 211, 66, 215, 164, 24, 242, - 39, 200, 139, 202, 59, 233, 63, 4, 211, 66, 215, 164, 24, 198, 166, 233, - 144, 202, 59, 233, 63, 4, 230, 33, 202, 59, 233, 63, 4, 228, 155, 193, - 56, 233, 62, 202, 59, 233, 63, 4, 202, 59, 233, 144, 233, 63, 205, 104, - 237, 69, 232, 122, 207, 56, 233, 62, 202, 59, 233, 63, 4, 229, 190, 233, - 144, 202, 59, 233, 63, 4, 200, 189, 202, 58, 233, 62, 214, 68, 233, 62, - 233, 165, 233, 62, 196, 107, 233, 62, 233, 63, 4, 242, 39, 200, 139, 210, - 17, 233, 62, 239, 3, 233, 62, 239, 4, 233, 62, 221, 97, 233, 62, 233, 63, - 198, 209, 41, 221, 98, 221, 97, 233, 63, 4, 202, 59, 233, 144, 221, 97, - 233, 63, 4, 242, 171, 233, 144, 233, 63, 4, 201, 7, 198, 56, 233, 63, 4, - 201, 7, 198, 57, 24, 193, 56, 233, 152, 233, 63, 4, 201, 7, 198, 57, 24, - 198, 166, 233, 144, 236, 183, 233, 62, 193, 16, 233, 62, 251, 60, 233, - 62, 208, 255, 233, 62, 238, 152, 233, 62, 209, 244, 233, 62, 233, 63, 4, - 218, 239, 80, 197, 213, 236, 183, 247, 170, 207, 56, 233, 62, 232, 54, - 233, 63, 4, 211, 66, 215, 163, 251, 58, 233, 62, 233, 16, 233, 62, 193, - 117, 233, 62, 202, 86, 233, 62, 198, 125, 233, 62, 230, 164, 233, 62, - 218, 223, 238, 152, 233, 62, 233, 63, 4, 211, 66, 215, 163, 228, 99, 233, - 62, 233, 63, 4, 211, 66, 215, 164, 24, 242, 39, 200, 139, 233, 63, 205, - 73, 223, 135, 233, 17, 250, 140, 233, 62, 232, 143, 233, 62, 202, 87, - 233, 62, 236, 150, 233, 62, 233, 63, 193, 51, 215, 163, 233, 63, 4, 216, - 197, 217, 16, 230, 163, 247, 31, 233, 63, 4, 202, 59, 233, 144, 247, 31, - 233, 63, 4, 199, 121, 80, 222, 158, 202, 59, 247, 31, 233, 63, 4, 211, - 66, 215, 163, 202, 59, 247, 31, 233, 63, 4, 229, 190, 233, 144, 247, 31, - 233, 63, 4, 193, 1, 202, 60, 221, 97, 247, 31, 233, 63, 4, 242, 171, 233, - 144, 208, 255, 247, 31, 233, 62, 238, 152, 247, 31, 233, 62, 193, 117, - 247, 31, 233, 62, 202, 79, 232, 54, 233, 62, 202, 79, 202, 59, 233, 62, - 196, 68, 233, 62, 233, 63, 4, 206, 133, 233, 144, 233, 63, 4, 213, 31, - 230, 209, 231, 95, 233, 63, 4, 211, 115, 231, 95, 209, 242, 248, 20, 237, - 84, 205, 44, 215, 208, 229, 194, 215, 208, 201, 231, 215, 208, 229, 243, - 209, 242, 207, 140, 91, 230, 20, 209, 242, 207, 140, 248, 32, 229, 252, - 223, 135, 246, 236, 209, 242, 232, 53, 209, 242, 4, 208, 255, 233, 62, - 209, 242, 4, 232, 132, 229, 251, 185, 193, 103, 209, 51, 219, 209, 201, - 253, 193, 103, 209, 51, 219, 209, 185, 234, 160, 209, 51, 219, 209, 201, - 253, 234, 160, 209, 51, 219, 209, 152, 185, 193, 103, 209, 51, 219, 209, - 152, 201, 253, 193, 103, 209, 51, 219, 209, 152, 185, 234, 160, 209, 51, - 219, 209, 152, 201, 253, 234, 160, 209, 51, 219, 209, 185, 193, 103, 209, - 51, 195, 45, 219, 209, 201, 253, 193, 103, 209, 51, 195, 45, 219, 209, - 185, 234, 160, 209, 51, 195, 45, 219, 209, 201, 253, 234, 160, 209, 51, - 195, 45, 219, 209, 88, 185, 193, 103, 209, 51, 195, 45, 219, 209, 88, - 201, 253, 193, 103, 209, 51, 195, 45, 219, 209, 88, 185, 234, 160, 209, - 51, 195, 45, 219, 209, 88, 201, 253, 234, 160, 209, 51, 195, 45, 219, - 209, 185, 193, 103, 209, 51, 247, 212, 201, 253, 193, 103, 209, 51, 247, - 212, 185, 234, 160, 209, 51, 247, 212, 201, 253, 234, 160, 209, 51, 247, - 212, 88, 185, 193, 103, 209, 51, 247, 212, 88, 201, 253, 193, 103, 209, - 51, 247, 212, 88, 185, 234, 160, 209, 51, 247, 212, 88, 201, 253, 234, - 160, 209, 51, 247, 212, 228, 228, 208, 1, 51, 211, 32, 228, 228, 208, 1, - 51, 211, 33, 223, 135, 62, 201, 185, 202, 20, 208, 1, 51, 211, 32, 202, - 20, 208, 1, 51, 211, 33, 223, 135, 62, 201, 185, 117, 206, 141, 196, 62, - 206, 141, 96, 206, 141, 235, 75, 206, 141, 27, 34, 233, 214, 211, 32, 88, - 27, 34, 233, 214, 211, 32, 34, 211, 66, 233, 214, 211, 32, 88, 34, 211, - 66, 233, 214, 211, 32, 88, 251, 87, 211, 32, 200, 142, 251, 87, 211, 32, - 49, 88, 54, 152, 242, 27, 207, 247, 87, 211, 32, 49, 88, 54, 242, 27, - 207, 247, 87, 211, 32, 49, 88, 131, 54, 242, 27, 207, 247, 87, 211, 32, - 88, 223, 75, 211, 32, 49, 223, 75, 211, 32, 88, 49, 223, 75, 211, 32, - 195, 80, 88, 202, 18, 195, 80, 88, 207, 14, 202, 18, 243, 76, 248, 59, - 207, 14, 243, 76, 248, 59, 206, 141, 229, 173, 201, 80, 219, 8, 207, 147, - 247, 54, 229, 99, 198, 12, 229, 99, 198, 13, 4, 247, 201, 213, 0, 198, - 12, 216, 139, 155, 207, 148, 201, 88, 198, 10, 198, 11, 247, 54, 247, - 175, 211, 90, 247, 175, 197, 208, 247, 176, 201, 58, 216, 25, 251, 91, - 232, 203, 234, 45, 209, 43, 247, 54, 211, 90, 209, 43, 247, 54, 199, 150, - 211, 90, 199, 150, 250, 100, 211, 90, 250, 100, 207, 89, 195, 142, 237, - 65, 197, 199, 250, 175, 218, 230, 198, 19, 215, 201, 215, 169, 207, 146, - 200, 159, 207, 146, 215, 169, 247, 106, 251, 215, 198, 9, 203, 60, 206, - 107, 201, 223, 228, 209, 198, 16, 219, 108, 81, 198, 16, 219, 108, 238, - 246, 57, 209, 43, 247, 38, 207, 7, 219, 108, 197, 234, 232, 178, 211, 94, - 209, 12, 236, 100, 213, 31, 234, 31, 57, 202, 57, 113, 213, 31, 202, 57, - 113, 208, 125, 219, 60, 223, 135, 223, 22, 209, 100, 113, 236, 130, 212, - 255, 219, 60, 113, 209, 6, 193, 142, 113, 213, 15, 193, 142, 113, 248, - 136, 213, 31, 248, 135, 248, 134, 215, 169, 248, 134, 210, 42, 213, 31, - 210, 41, 243, 37, 238, 162, 216, 163, 113, 193, 32, 113, 207, 23, 249, - 99, 113, 198, 81, 193, 142, 242, 168, 203, 15, 249, 11, 249, 9, 210, 81, - 238, 230, 238, 109, 249, 76, 242, 198, 45, 218, 193, 197, 238, 4, 206, - 108, 238, 209, 208, 189, 57, 47, 223, 109, 201, 254, 248, 11, 113, 230, - 247, 113, 238, 201, 24, 220, 1, 202, 87, 252, 5, 203, 38, 249, 75, 248, - 184, 248, 185, 248, 208, 209, 100, 80, 193, 15, 211, 147, 57, 203, 38, - 197, 209, 201, 3, 210, 191, 229, 95, 199, 93, 228, 98, 234, 87, 209, 88, - 202, 82, 193, 91, 206, 184, 247, 185, 230, 29, 24, 193, 9, 203, 73, 211, - 120, 235, 50, 215, 173, 207, 147, 198, 21, 215, 176, 248, 58, 196, 72, - 216, 36, 251, 171, 196, 72, 251, 171, 196, 72, 2, 251, 171, 2, 251, 171, - 213, 4, 251, 171, 251, 172, 237, 48, 251, 172, 250, 188, 205, 113, 211, - 90, 232, 203, 234, 45, 236, 233, 219, 8, 210, 85, 203, 60, 205, 78, 215, - 176, 205, 78, 247, 65, 202, 89, 232, 138, 205, 108, 202, 106, 250, 102, - 206, 238, 209, 169, 197, 199, 206, 134, 202, 107, 160, 16, 39, 207, 253, - 160, 16, 39, 251, 173, 160, 16, 39, 232, 202, 160, 16, 39, 234, 163, 160, - 16, 39, 193, 141, 160, 16, 39, 250, 241, 160, 16, 39, 250, 242, 207, 76, - 160, 16, 39, 250, 242, 207, 75, 160, 16, 39, 250, 242, 195, 28, 160, 16, - 39, 250, 242, 195, 27, 160, 16, 39, 195, 42, 160, 16, 39, 195, 41, 160, - 16, 39, 195, 40, 160, 16, 39, 200, 200, 160, 16, 39, 209, 194, 200, 200, - 160, 16, 39, 62, 200, 200, 160, 16, 39, 216, 162, 200, 231, 160, 16, 39, - 216, 162, 200, 230, 160, 16, 39, 216, 162, 200, 229, 160, 16, 39, 242, - 221, 160, 16, 39, 205, 153, 160, 16, 39, 213, 148, 160, 16, 39, 195, 25, - 160, 16, 39, 195, 24, 160, 16, 39, 206, 143, 205, 153, 160, 16, 39, 206, - 143, 205, 152, 160, 16, 39, 230, 214, 160, 16, 39, 202, 179, 160, 16, 39, - 223, 46, 211, 39, 160, 16, 39, 223, 46, 211, 38, 160, 16, 39, 238, 175, - 80, 223, 45, 160, 16, 39, 207, 72, 80, 223, 45, 160, 16, 39, 238, 221, - 211, 39, 160, 16, 39, 223, 44, 211, 39, 160, 16, 39, 200, 232, 80, 238, - 220, 160, 16, 39, 238, 175, 80, 238, 220, 160, 16, 39, 238, 175, 80, 238, - 219, 160, 16, 39, 238, 221, 251, 28, 160, 16, 39, 205, 154, 80, 238, 221, - 251, 28, 160, 16, 39, 200, 232, 80, 205, 154, 80, 238, 220, 160, 16, 39, - 195, 136, 160, 16, 39, 198, 138, 211, 39, 160, 16, 39, 219, 213, 211, 39, - 160, 16, 39, 251, 27, 211, 39, 160, 16, 39, 200, 232, 80, 251, 26, 160, - 16, 39, 205, 154, 80, 251, 26, 160, 16, 39, 200, 232, 80, 205, 154, 80, - 251, 26, 160, 16, 39, 195, 43, 80, 251, 26, 160, 16, 39, 207, 72, 80, - 251, 26, 160, 16, 39, 207, 72, 80, 251, 25, 160, 16, 39, 207, 71, 160, - 16, 39, 207, 70, 160, 16, 39, 207, 69, 160, 16, 39, 207, 68, 160, 16, 39, - 251, 126, 160, 16, 39, 251, 125, 160, 16, 39, 217, 42, 160, 16, 39, 205, - 163, 160, 16, 39, 250, 180, 160, 16, 39, 207, 100, 160, 16, 39, 207, 99, - 160, 16, 39, 250, 104, 160, 16, 39, 248, 102, 211, 39, 160, 16, 39, 199, - 172, 160, 16, 39, 199, 171, 160, 16, 39, 208, 3, 219, 97, 160, 16, 39, - 248, 39, 160, 16, 39, 248, 38, 160, 16, 39, 248, 37, 160, 16, 39, 251, - 100, 160, 16, 39, 211, 119, 160, 16, 39, 201, 209, 160, 16, 39, 198, 136, - 160, 16, 39, 230, 125, 160, 16, 39, 193, 129, 160, 16, 39, 208, 250, 160, - 16, 39, 247, 89, 160, 16, 39, 197, 46, 160, 16, 39, 247, 56, 215, 182, - 160, 16, 39, 205, 88, 80, 222, 160, 160, 16, 39, 247, 103, 160, 16, 39, - 197, 231, 160, 16, 39, 201, 95, 197, 231, 160, 16, 39, 219, 7, 160, 16, - 39, 202, 32, 160, 16, 39, 196, 50, 160, 16, 39, 228, 153, 235, 27, 160, - 16, 39, 250, 154, 160, 16, 39, 209, 8, 250, 154, 160, 16, 39, 247, 239, - 160, 16, 39, 208, 249, 247, 239, 160, 16, 39, 251, 97, 160, 16, 39, 201, - 41, 200, 181, 201, 40, 160, 16, 39, 201, 41, 200, 181, 201, 39, 160, 16, - 39, 200, 228, 160, 16, 39, 208, 222, 160, 16, 39, 236, 170, 160, 16, 39, - 236, 172, 160, 16, 39, 236, 171, 160, 16, 39, 208, 134, 160, 16, 39, 208, - 122, 160, 16, 39, 238, 160, 160, 16, 39, 238, 159, 160, 16, 39, 238, 158, - 160, 16, 39, 238, 157, 160, 16, 39, 238, 156, 160, 16, 39, 251, 140, 160, - 16, 39, 249, 12, 80, 217, 23, 160, 16, 39, 249, 12, 80, 195, 171, 160, - 16, 39, 207, 21, 160, 16, 39, 228, 145, 160, 16, 39, 213, 176, 160, 16, - 39, 237, 158, 160, 16, 39, 215, 196, 160, 16, 39, 134, 235, 65, 160, 16, - 39, 134, 211, 7, 62, 219, 195, 223, 28, 50, 197, 237, 62, 196, 72, 223, - 28, 50, 197, 237, 62, 206, 198, 223, 28, 50, 197, 237, 62, 235, 78, 223, - 28, 50, 197, 237, 62, 202, 79, 2, 242, 218, 216, 194, 28, 64, 242, 218, - 28, 64, 242, 218, 88, 64, 242, 218, 195, 80, 88, 64, 242, 218, 233, 156, - 88, 64, 242, 218, 64, 242, 219, 238, 242, 62, 2, 242, 218, 206, 110, 199, - 173, 62, 198, 133, 201, 185, 62, 202, 79, 2, 201, 185, 155, 64, 201, 185, - 216, 194, 64, 201, 185, 28, 64, 201, 185, 88, 64, 201, 185, 195, 80, 88, - 64, 201, 185, 233, 156, 88, 64, 201, 185, 64, 51, 238, 242, 62, 195, 80, - 2, 201, 185, 64, 51, 238, 242, 62, 216, 194, 201, 185, 51, 199, 173, 62, - 198, 133, 236, 243, 62, 195, 80, 2, 236, 243, 62, 216, 194, 2, 236, 243, - 64, 236, 244, 238, 242, 62, 195, 80, 2, 236, 243, 64, 236, 244, 238, 242, - 62, 216, 194, 236, 243, 236, 244, 199, 173, 62, 198, 133, 218, 210, 62, - 195, 80, 2, 218, 210, 62, 216, 194, 2, 218, 210, 64, 218, 211, 238, 242, - 62, 2, 218, 210, 198, 255, 35, 238, 170, 155, 35, 238, 170, 216, 194, 35, - 238, 170, 28, 35, 238, 170, 195, 80, 28, 35, 238, 170, 195, 80, 88, 35, - 238, 170, 233, 156, 88, 35, 238, 170, 198, 255, 205, 149, 155, 205, 149, - 216, 194, 205, 149, 28, 205, 149, 88, 205, 149, 195, 80, 88, 205, 149, - 233, 156, 88, 205, 149, 155, 232, 185, 201, 201, 250, 143, 216, 194, 232, - 185, 201, 201, 250, 143, 28, 232, 185, 201, 201, 250, 143, 88, 232, 185, - 201, 201, 250, 143, 195, 80, 88, 232, 185, 201, 201, 250, 143, 233, 156, - 88, 232, 185, 201, 201, 250, 143, 155, 202, 131, 201, 201, 250, 143, 216, - 194, 202, 131, 201, 201, 250, 143, 28, 202, 131, 201, 201, 250, 143, 88, - 202, 131, 201, 201, 250, 143, 195, 80, 88, 202, 131, 201, 201, 250, 143, - 233, 156, 88, 202, 131, 201, 201, 250, 143, 155, 234, 121, 201, 201, 250, - 143, 216, 194, 234, 121, 201, 201, 250, 143, 28, 234, 121, 201, 201, 250, - 143, 88, 234, 121, 201, 201, 250, 143, 195, 80, 88, 234, 121, 201, 201, - 250, 143, 155, 115, 209, 53, 62, 201, 97, 216, 194, 115, 209, 53, 62, - 201, 97, 115, 209, 53, 62, 201, 97, 216, 194, 115, 209, 53, 209, 122, - 201, 97, 155, 232, 90, 209, 53, 62, 201, 97, 216, 194, 232, 90, 209, 53, - 62, 201, 97, 232, 90, 209, 53, 62, 201, 97, 216, 194, 232, 90, 209, 53, - 209, 122, 201, 97, 207, 14, 155, 232, 90, 209, 53, 209, 122, 201, 97, - 155, 232, 185, 209, 53, 62, 201, 97, 88, 232, 185, 209, 53, 62, 201, 97, - 216, 194, 202, 131, 209, 53, 62, 201, 97, 88, 202, 131, 209, 53, 62, 201, - 97, 202, 131, 209, 53, 209, 122, 201, 97, 216, 194, 234, 121, 209, 53, - 62, 201, 97, 88, 234, 121, 209, 53, 62, 201, 97, 195, 80, 88, 234, 121, - 209, 53, 62, 201, 97, 88, 234, 121, 209, 53, 209, 122, 201, 97, 155, 197, - 34, 209, 53, 62, 201, 97, 88, 197, 34, 209, 53, 62, 201, 97, 88, 197, 34, - 209, 53, 209, 122, 201, 97, 47, 197, 237, 214, 92, 47, 197, 237, 47, 201, - 185, 214, 92, 47, 201, 185, 219, 245, 211, 44, 242, 218, 219, 245, 192, - 73, 242, 218, 219, 245, 230, 167, 242, 218, 219, 245, 208, 131, 242, 218, - 219, 245, 247, 227, 242, 218, 219, 245, 207, 82, 201, 185, 219, 245, 248, - 67, 201, 185, 219, 245, 211, 44, 201, 185, 219, 245, 192, 73, 201, 185, - 219, 245, 230, 167, 201, 185, 219, 245, 208, 131, 201, 185, 219, 245, - 247, 227, 201, 185, 88, 234, 1, 57, 117, 63, 4, 2, 197, 238, 250, 185, - 196, 62, 63, 4, 2, 197, 238, 250, 185, 96, 63, 4, 2, 197, 238, 250, 185, - 235, 75, 63, 4, 2, 197, 238, 250, 185, 117, 63, 4, 216, 194, 197, 238, - 250, 185, 196, 62, 63, 4, 216, 194, 197, 238, 250, 185, 96, 63, 4, 216, - 194, 197, 238, 250, 185, 235, 75, 63, 4, 216, 194, 197, 238, 250, 185, - 117, 63, 4, 219, 245, 197, 238, 250, 185, 196, 62, 63, 4, 219, 245, 197, - 238, 250, 185, 96, 63, 4, 219, 245, 197, 238, 250, 185, 235, 75, 63, 4, - 219, 245, 197, 238, 250, 185, 117, 63, 4, 2, 233, 251, 250, 185, 196, 62, - 63, 4, 2, 233, 251, 250, 185, 96, 63, 4, 2, 233, 251, 250, 185, 235, 75, - 63, 4, 2, 233, 251, 250, 185, 117, 63, 4, 233, 251, 250, 185, 196, 62, - 63, 4, 233, 251, 250, 185, 96, 63, 4, 233, 251, 250, 185, 235, 75, 63, 4, - 233, 251, 250, 185, 88, 117, 63, 4, 233, 251, 250, 185, 88, 196, 62, 63, - 4, 233, 251, 250, 185, 88, 96, 63, 4, 233, 251, 250, 185, 88, 235, 75, - 63, 4, 233, 251, 250, 185, 88, 117, 63, 4, 219, 245, 233, 251, 250, 185, - 88, 196, 62, 63, 4, 219, 245, 233, 251, 250, 185, 88, 96, 63, 4, 219, - 245, 233, 251, 250, 185, 88, 235, 75, 63, 4, 219, 245, 233, 251, 250, - 185, 117, 197, 236, 63, 4, 214, 201, 203, 144, 196, 62, 197, 236, 63, 4, - 214, 201, 203, 144, 96, 197, 236, 63, 4, 214, 201, 203, 144, 235, 75, - 197, 236, 63, 4, 214, 201, 203, 144, 117, 197, 236, 63, 4, 216, 194, 203, - 144, 196, 62, 197, 236, 63, 4, 216, 194, 203, 144, 96, 197, 236, 63, 4, - 216, 194, 203, 144, 235, 75, 197, 236, 63, 4, 216, 194, 203, 144, 117, - 197, 236, 63, 4, 28, 203, 144, 196, 62, 197, 236, 63, 4, 28, 203, 144, - 96, 197, 236, 63, 4, 28, 203, 144, 235, 75, 197, 236, 63, 4, 28, 203, - 144, 117, 197, 236, 63, 4, 88, 203, 144, 196, 62, 197, 236, 63, 4, 88, - 203, 144, 96, 197, 236, 63, 4, 88, 203, 144, 235, 75, 197, 236, 63, 4, - 88, 203, 144, 117, 197, 236, 63, 4, 195, 80, 88, 203, 144, 196, 62, 197, - 236, 63, 4, 195, 80, 88, 203, 144, 96, 197, 236, 63, 4, 195, 80, 88, 203, - 144, 235, 75, 197, 236, 63, 4, 195, 80, 88, 203, 144, 117, 232, 210, 55, - 196, 62, 232, 210, 55, 96, 232, 210, 55, 235, 75, 232, 210, 55, 117, 112, - 55, 196, 62, 112, 55, 96, 112, 55, 235, 75, 112, 55, 117, 239, 13, 55, - 196, 62, 239, 13, 55, 96, 239, 13, 55, 235, 75, 239, 13, 55, 117, 88, - 239, 13, 55, 196, 62, 88, 239, 13, 55, 96, 88, 239, 13, 55, 235, 75, 88, - 239, 13, 55, 117, 88, 55, 196, 62, 88, 55, 96, 88, 55, 235, 75, 88, 55, - 117, 49, 55, 196, 62, 49, 55, 96, 49, 55, 235, 75, 49, 55, 185, 193, 103, - 49, 55, 185, 234, 160, 49, 55, 201, 253, 234, 160, 49, 55, 201, 253, 193, - 103, 49, 55, 45, 50, 49, 55, 132, 143, 49, 55, 193, 75, 117, 155, 178, - 55, 193, 75, 196, 62, 155, 178, 55, 193, 75, 96, 155, 178, 55, 193, 75, - 235, 75, 155, 178, 55, 193, 75, 185, 193, 103, 155, 178, 55, 193, 75, - 185, 234, 160, 155, 178, 55, 193, 75, 201, 253, 234, 160, 155, 178, 55, - 193, 75, 201, 253, 193, 103, 155, 178, 55, 193, 75, 117, 178, 55, 193, - 75, 196, 62, 178, 55, 193, 75, 96, 178, 55, 193, 75, 235, 75, 178, 55, - 193, 75, 185, 193, 103, 178, 55, 193, 75, 185, 234, 160, 178, 55, 193, - 75, 201, 253, 234, 160, 178, 55, 193, 75, 201, 253, 193, 103, 178, 55, - 193, 75, 117, 216, 194, 178, 55, 193, 75, 196, 62, 216, 194, 178, 55, - 193, 75, 96, 216, 194, 178, 55, 193, 75, 235, 75, 216, 194, 178, 55, 193, - 75, 185, 193, 103, 216, 194, 178, 55, 193, 75, 185, 234, 160, 216, 194, - 178, 55, 193, 75, 201, 253, 234, 160, 216, 194, 178, 55, 193, 75, 201, - 253, 193, 103, 216, 194, 178, 55, 193, 75, 117, 88, 178, 55, 193, 75, - 196, 62, 88, 178, 55, 193, 75, 96, 88, 178, 55, 193, 75, 235, 75, 88, - 178, 55, 193, 75, 185, 193, 103, 88, 178, 55, 193, 75, 185, 234, 160, 88, - 178, 55, 193, 75, 201, 253, 234, 160, 88, 178, 55, 193, 75, 201, 253, - 193, 103, 88, 178, 55, 193, 75, 117, 195, 80, 88, 178, 55, 193, 75, 196, - 62, 195, 80, 88, 178, 55, 193, 75, 96, 195, 80, 88, 178, 55, 193, 75, - 235, 75, 195, 80, 88, 178, 55, 193, 75, 185, 193, 103, 195, 80, 88, 178, - 55, 193, 75, 185, 234, 160, 195, 80, 88, 178, 55, 193, 75, 201, 253, 234, - 160, 195, 80, 88, 178, 55, 193, 75, 201, 253, 193, 103, 195, 80, 88, 178, - 55, 117, 197, 238, 250, 185, 196, 62, 197, 238, 250, 185, 96, 197, 238, - 250, 185, 235, 75, 197, 238, 250, 185, 117, 64, 63, 193, 53, 197, 238, - 250, 185, 196, 62, 64, 63, 193, 53, 197, 238, 250, 185, 96, 64, 63, 193, - 53, 197, 238, 250, 185, 235, 75, 64, 63, 193, 53, 197, 238, 250, 185, - 117, 63, 4, 212, 251, 199, 210, 196, 62, 63, 4, 212, 251, 199, 210, 96, - 63, 4, 212, 251, 199, 210, 235, 75, 63, 4, 212, 251, 199, 210, 88, 63, - 203, 145, 193, 73, 108, 88, 63, 203, 145, 193, 73, 103, 198, 248, 88, 63, - 203, 145, 193, 73, 91, 230, 37, 88, 63, 203, 145, 193, 73, 91, 198, 251, - 117, 248, 26, 64, 55, 96, 248, 29, 203, 147, 64, 55, 117, 198, 49, 203, - 147, 64, 55, 96, 198, 49, 203, 147, 64, 55, 117, 219, 194, 64, 55, 96, - 206, 197, 64, 55, 117, 206, 197, 64, 55, 96, 219, 194, 64, 55, 117, 249, - 95, 203, 146, 64, 55, 96, 249, 95, 203, 146, 64, 55, 117, 232, 57, 203, - 146, 64, 55, 96, 232, 57, 203, 146, 64, 55, 64, 63, 203, 145, 193, 73, - 108, 64, 63, 203, 145, 193, 73, 103, 198, 248, 63, 209, 51, 196, 62, 199, - 20, 185, 193, 102, 63, 209, 51, 96, 199, 20, 238, 114, 201, 253, 193, - 102, 47, 238, 171, 232, 104, 4, 232, 90, 236, 94, 47, 238, 171, 232, 104, - 4, 103, 236, 94, 47, 238, 171, 232, 103, 45, 134, 242, 219, 4, 232, 90, - 236, 94, 45, 134, 242, 219, 4, 115, 236, 94, 45, 134, 242, 219, 4, 103, - 236, 94, 45, 134, 242, 219, 4, 236, 96, 45, 134, 242, 218, 235, 76, 233, - 55, 106, 235, 76, 233, 55, 212, 251, 106, 235, 76, 233, 55, 228, 219, 4, - 236, 96, 235, 76, 233, 55, 212, 251, 228, 219, 4, 236, 96, 209, 127, 232, - 206, 64, 229, 191, 247, 227, 229, 191, 209, 126, 230, 20, 191, 17, 233, - 62, 215, 212, 233, 62, 233, 63, 4, 199, 16, 214, 78, 233, 62, 198, 253, - 233, 62, 233, 63, 4, 229, 202, 206, 145, 233, 62, 228, 119, 233, 62, 3, - 80, 199, 29, 228, 155, 247, 91, 216, 214, 230, 20, 207, 142, 249, 97, 80, - 230, 20, 219, 199, 232, 190, 206, 202, 232, 190, 229, 250, 230, 21, 4, - 140, 24, 82, 232, 207, 238, 166, 228, 44, 218, 220, 191, 239, 230, 21, - 57, 233, 63, 4, 238, 191, 229, 232, 242, 160, 233, 62, 214, 188, 233, 62, - 206, 133, 211, 94, 199, 29, 232, 154, 219, 231, 235, 56, 233, 62, 218, - 157, 233, 62, 233, 63, 210, 172, 202, 51, 233, 62, 233, 63, 4, 91, 233, - 151, 207, 141, 230, 163, 233, 63, 4, 201, 98, 233, 144, 230, 163, 233, - 63, 4, 91, 219, 245, 24, 91, 2, 233, 152, 233, 63, 4, 232, 212, 238, 194, - 242, 171, 219, 72, 203, 253, 233, 63, 4, 200, 73, 238, 194, 215, 163, - 202, 59, 233, 63, 4, 202, 59, 233, 145, 24, 230, 21, 238, 194, 215, 163, - 233, 63, 4, 211, 66, 215, 164, 195, 6, 203, 49, 233, 63, 4, 233, 167, - 229, 203, 208, 219, 193, 35, 247, 248, 210, 171, 132, 198, 82, 204, 26, - 208, 207, 217, 71, 223, 135, 197, 42, 215, 178, 243, 7, 203, 4, 209, 242, - 236, 114, 247, 35, 222, 150, 232, 253, 215, 238, 210, 12, 193, 8, 193, - 142, 209, 37, 229, 255, 236, 156, 217, 16, 193, 67, 232, 146, 235, 51, 4, - 235, 49, 242, 178, 230, 235, 197, 70, 230, 236, 201, 198, 230, 221, 214, - 71, 206, 203, 232, 197, 209, 100, 216, 200, 205, 52, 209, 100, 216, 200, - 198, 252, 209, 100, 216, 200, 248, 13, 230, 230, 217, 27, 250, 173, 196, - 90, 238, 125, 201, 60, 220, 86, 201, 70, 24, 249, 61, 202, 26, 232, 138, - 236, 181, 238, 174, 250, 91, 238, 141, 249, 88, 209, 5, 247, 39, 249, 74, - 247, 251, 230, 167, 205, 160, 203, 137, 210, 157, 80, 232, 122, 201, 4, - 232, 165, 234, 136, 230, 237, 80, 216, 35, 210, 47, 221, 92, 210, 153, - 235, 32, 232, 99, 238, 225, 199, 202, 248, 14, 243, 14, 248, 19, 4, 201, - 198, 238, 135, 4, 201, 38, 242, 45, 247, 231, 209, 167, 208, 211, 238, - 108, 80, 216, 205, 205, 132, 247, 67, 232, 122, 219, 208, 230, 166, 217, - 62, 215, 189, 247, 98, 249, 77, 202, 59, 233, 63, 4, 202, 59, 233, 145, - 24, 115, 229, 189, 192, 87, 233, 62, 202, 59, 233, 63, 4, 199, 126, 233, - 63, 4, 210, 92, 228, 157, 24, 210, 92, 229, 232, 233, 63, 4, 196, 94, - 233, 145, 24, 193, 133, 215, 163, 210, 251, 233, 62, 232, 69, 233, 62, - 213, 155, 236, 179, 233, 62, 233, 63, 228, 230, 249, 97, 199, 120, 233, - 63, 4, 209, 85, 233, 144, 205, 120, 220, 95, 242, 48, 230, 217, 229, 97, - 248, 43, 232, 167, 203, 47, 238, 188, 219, 76, 233, 62, 205, 76, 197, 58, - 196, 92, 233, 62, 234, 170, 235, 41, 249, 14, 203, 123, 210, 239, 232, - 82, 233, 62, 247, 167, 237, 83, 230, 201, 219, 54, 207, 0, 203, 8, 201, - 179, 230, 249, 233, 62, 191, 85, 233, 62, 229, 184, 205, 105, 200, 38, - 238, 177, 222, 56, 219, 46, 210, 49, 229, 89, 210, 98, 207, 168, 219, 17, - 215, 180, 216, 71, 249, 83, 200, 144, 217, 72, 236, 120, 202, 73, 211, - 12, 211, 43, 202, 97, 232, 169, 210, 229, 248, 210, 248, 101, 205, 56, - 230, 130, 236, 117, 208, 195, 247, 69, 234, 67, 242, 16, 207, 82, 230, - 45, 234, 67, 242, 16, 238, 124, 230, 45, 234, 67, 242, 16, 249, 63, 234, - 67, 242, 16, 64, 230, 45, 248, 50, 219, 188, 232, 120, 198, 51, 200, 179, - 200, 174, 205, 183, 195, 78, 234, 168, 4, 229, 193, 251, 183, 215, 174, - 193, 89, 217, 54, 193, 89, 216, 204, 250, 200, 216, 204, 219, 188, 243, - 70, 193, 114, 238, 133, 205, 154, 203, 141, 248, 158, 248, 14, 231, 160, - 211, 82, 233, 44, 193, 171, 247, 168, 217, 10, 235, 60, 227, 253, 238, - 143, 247, 217, 199, 129, 197, 210, 201, 100, 209, 241, 221, 56, 209, 241, - 237, 99, 209, 241, 233, 63, 4, 215, 207, 251, 233, 243, 38, 211, 107, - 251, 233, 248, 214, 209, 241, 209, 242, 4, 229, 198, 209, 242, 223, 135, - 201, 77, 206, 125, 209, 242, 242, 180, 209, 242, 223, 135, 218, 225, 209, - 17, 217, 103, 233, 46, 195, 174, 216, 155, 234, 82, 231, 111, 191, 5, - 248, 2, 211, 44, 229, 191, 248, 123, 247, 63, 205, 89, 230, 229, 242, 48, - 202, 29, 207, 82, 231, 6, 234, 25, 232, 201, 222, 211, 208, 118, 209, - 166, 199, 70, 197, 80, 209, 226, 236, 177, 236, 131, 54, 229, 172, 242, - 21, 252, 19, 232, 203, 233, 161, 198, 53, 247, 239, 217, 101, 218, 193, - 218, 226, 248, 30, 201, 199, 80, 198, 222, 249, 62, 80, 192, 100, 205, - 183, 209, 130, 199, 119, 248, 215, 247, 228, 249, 19, 206, 136, 80, 210, - 125, 249, 38, 80, 202, 32, 201, 200, 207, 98, 214, 182, 251, 83, 214, 68, - 243, 57, 221, 114, 214, 68, 243, 57, 208, 9, 214, 68, 243, 57, 206, 126, - 214, 68, 243, 57, 248, 104, 214, 68, 243, 57, 221, 52, 214, 68, 243, 57, - 210, 64, 64, 243, 57, 221, 53, 206, 117, 232, 96, 237, 79, 62, 243, 57, - 221, 53, 206, 117, 232, 96, 237, 79, 214, 68, 243, 57, 221, 53, 206, 117, - 232, 96, 237, 79, 64, 243, 57, 221, 115, 206, 117, 213, 157, 237, 79, 64, - 243, 57, 208, 10, 206, 117, 213, 157, 237, 79, 64, 243, 57, 206, 127, - 206, 117, 213, 157, 237, 79, 64, 243, 57, 248, 105, 206, 117, 213, 157, - 237, 79, 64, 243, 57, 221, 53, 206, 117, 213, 157, 237, 79, 64, 243, 57, - 210, 65, 206, 117, 213, 157, 237, 79, 62, 243, 57, 221, 115, 206, 117, - 213, 157, 237, 79, 62, 243, 57, 208, 10, 206, 117, 213, 157, 237, 79, 62, - 243, 57, 206, 127, 206, 117, 213, 157, 237, 79, 62, 243, 57, 248, 105, - 206, 117, 213, 157, 237, 79, 62, 243, 57, 221, 53, 206, 117, 213, 157, - 237, 79, 62, 243, 57, 210, 65, 206, 117, 213, 157, 237, 79, 214, 68, 243, - 57, 221, 115, 206, 117, 213, 157, 237, 79, 214, 68, 243, 57, 208, 10, - 206, 117, 213, 157, 237, 79, 214, 68, 243, 57, 206, 127, 206, 117, 213, - 157, 237, 79, 214, 68, 243, 57, 248, 105, 206, 117, 213, 157, 237, 79, - 214, 68, 243, 57, 221, 53, 206, 117, 213, 157, 237, 79, 214, 68, 243, 57, - 210, 65, 206, 117, 213, 157, 237, 79, 64, 243, 57, 221, 53, 206, 117, 91, - 228, 110, 198, 243, 237, 79, 62, 243, 57, 221, 53, 206, 117, 91, 228, - 110, 198, 243, 237, 79, 214, 68, 243, 57, 221, 53, 206, 117, 91, 228, - 110, 198, 243, 237, 79, 64, 243, 57, 152, 221, 114, 64, 243, 57, 152, - 208, 9, 64, 243, 57, 152, 206, 126, 64, 243, 57, 152, 248, 104, 64, 243, - 57, 152, 221, 52, 64, 243, 57, 152, 210, 64, 62, 243, 57, 152, 221, 114, - 62, 243, 57, 152, 208, 9, 62, 243, 57, 152, 206, 126, 62, 243, 57, 152, - 248, 104, 62, 243, 57, 152, 221, 52, 62, 243, 57, 152, 210, 64, 214, 68, - 243, 57, 152, 221, 114, 214, 68, 243, 57, 152, 208, 9, 214, 68, 243, 57, - 152, 206, 126, 214, 68, 243, 57, 152, 248, 104, 214, 68, 243, 57, 152, - 221, 52, 214, 68, 243, 57, 152, 210, 64, 64, 243, 57, 221, 53, 206, 117, - 103, 228, 110, 197, 25, 237, 79, 62, 243, 57, 221, 53, 206, 117, 103, - 228, 110, 197, 25, 237, 79, 214, 68, 243, 57, 221, 53, 206, 117, 103, - 228, 110, 197, 25, 237, 79, 64, 243, 57, 221, 115, 206, 117, 103, 228, - 110, 203, 237, 237, 79, 64, 243, 57, 208, 10, 206, 117, 103, 228, 110, - 203, 237, 237, 79, 64, 243, 57, 206, 127, 206, 117, 103, 228, 110, 203, - 237, 237, 79, 64, 243, 57, 248, 105, 206, 117, 103, 228, 110, 203, 237, - 237, 79, 64, 243, 57, 221, 53, 206, 117, 103, 228, 110, 203, 237, 237, - 79, 64, 243, 57, 210, 65, 206, 117, 103, 228, 110, 203, 237, 237, 79, 62, - 243, 57, 221, 115, 206, 117, 103, 228, 110, 203, 237, 237, 79, 62, 243, - 57, 208, 10, 206, 117, 103, 228, 110, 203, 237, 237, 79, 62, 243, 57, - 206, 127, 206, 117, 103, 228, 110, 203, 237, 237, 79, 62, 243, 57, 248, - 105, 206, 117, 103, 228, 110, 203, 237, 237, 79, 62, 243, 57, 221, 53, - 206, 117, 103, 228, 110, 203, 237, 237, 79, 62, 243, 57, 210, 65, 206, - 117, 103, 228, 110, 203, 237, 237, 79, 214, 68, 243, 57, 221, 115, 206, - 117, 103, 228, 110, 203, 237, 237, 79, 214, 68, 243, 57, 208, 10, 206, - 117, 103, 228, 110, 203, 237, 237, 79, 214, 68, 243, 57, 206, 127, 206, - 117, 103, 228, 110, 203, 237, 237, 79, 214, 68, 243, 57, 248, 105, 206, - 117, 103, 228, 110, 203, 237, 237, 79, 214, 68, 243, 57, 221, 53, 206, - 117, 103, 228, 110, 203, 237, 237, 79, 214, 68, 243, 57, 210, 65, 206, - 117, 103, 228, 110, 203, 237, 237, 79, 64, 243, 57, 221, 53, 206, 117, - 115, 228, 110, 232, 235, 237, 79, 62, 243, 57, 221, 53, 206, 117, 115, - 228, 110, 232, 235, 237, 79, 214, 68, 243, 57, 221, 53, 206, 117, 115, - 228, 110, 232, 235, 237, 79, 64, 243, 57, 233, 252, 62, 243, 57, 233, - 252, 214, 68, 243, 57, 233, 252, 64, 243, 57, 233, 253, 206, 117, 213, - 157, 237, 79, 62, 243, 57, 233, 253, 206, 117, 213, 157, 237, 79, 214, - 68, 243, 57, 233, 253, 206, 117, 213, 157, 237, 79, 64, 243, 57, 221, 50, - 64, 243, 57, 221, 49, 64, 243, 57, 221, 51, 62, 243, 57, 221, 50, 62, - 243, 57, 221, 49, 62, 243, 57, 221, 51, 192, 205, 207, 82, 231, 113, 192, - 205, 207, 82, 217, 64, 192, 205, 207, 82, 234, 88, 192, 205, 207, 82, - 228, 152, 192, 205, 207, 82, 243, 90, 192, 205, 207, 82, 247, 66, 192, - 205, 207, 82, 202, 21, 192, 205, 62, 231, 113, 192, 205, 62, 217, 64, - 192, 205, 62, 234, 88, 192, 205, 62, 228, 152, 192, 205, 62, 243, 90, - 192, 205, 62, 247, 66, 192, 205, 62, 202, 21, 249, 60, 203, 46, 211, 87, - 200, 131, 247, 235, 203, 20, 198, 232, 205, 134, 235, 55, 80, 248, 72, - 251, 239, 249, 46, 201, 71, 192, 234, 238, 154, 191, 253, 221, 95, 210, - 119, 248, 44, 217, 102, 193, 160, 209, 128, 214, 73, 236, 109, 206, 182, - 209, 92, 246, 204, 207, 113, 250, 82, 236, 151, 220, 1, 249, 44, 216, 36, - 229, 168, 252, 4, 177, 235, 50, 242, 40, 247, 41, 205, 103, 205, 70, 220, - 85, 106, 216, 9, 193, 63, 209, 75, 203, 234, 214, 95, 221, 47, 247, 214, - 215, 166, 198, 2, 198, 50, 229, 196, 209, 101, 206, 142, 216, 10, 249, - 61, 227, 243, 247, 52, 131, 249, 8, 230, 27, 232, 139, 193, 17, 248, 201, - 242, 47, 209, 4, 209, 91, 193, 28, 233, 13, 218, 224, 238, 213, 234, 63, - 214, 75, 214, 76, 4, 234, 135, 251, 78, 229, 191, 218, 184, 210, 11, 228, - 118, 208, 219, 217, 70, 208, 219, 209, 241, 209, 242, 4, 238, 161, 248, - 65, 248, 186, 210, 6, 211, 104, 232, 165, 199, 191, 232, 126, 199, 127, - 209, 0, 219, 68, 248, 217, 222, 246, 216, 176, 233, 62, 205, 148, 233, - 62, 233, 63, 4, 211, 66, 233, 145, 24, 230, 21, 138, 215, 163, 233, 63, - 4, 210, 38, 233, 152, 233, 63, 4, 236, 250, 215, 163, 235, 94, 219, 89, - 233, 62, 248, 97, 219, 74, 247, 215, 230, 21, 4, 140, 232, 212, 24, 174, - 238, 166, 96, 230, 20, 117, 230, 20, 210, 173, 143, 230, 20, 210, 173, - 132, 230, 20, 140, 209, 51, 250, 133, 199, 29, 195, 52, 229, 192, 229, - 251, 182, 203, 231, 182, 203, 201, 182, 203, 230, 182, 203, 186, 182, - 203, 215, 182, 203, 200, 182, 203, 229, 182, 203, 178, 182, 203, 208, - 182, 203, 192, 182, 203, 222, 182, 203, 185, 182, 203, 214, 182, 203, - 199, 182, 203, 228, 182, 203, 174, 182, 203, 204, 182, 203, 189, 182, - 203, 218, 182, 203, 181, 182, 203, 195, 182, 203, 225, 182, 203, 177, - 182, 203, 207, 182, 203, 191, 182, 203, 221, 182, 203, 184, 182, 203, - 213, 182, 203, 198, 182, 203, 227, 182, 203, 172, 182, 203, 202, 182, - 203, 187, 182, 203, 216, 182, 203, 179, 182, 203, 209, 182, 203, 193, - 182, 203, 223, 182, 203, 175, 182, 203, 205, 182, 203, 219, 182, 203, - 182, 182, 203, 211, 182, 203, 196, 182, 203, 226, 182, 203, 173, 182, - 203, 203, 182, 203, 188, 182, 203, 217, 182, 203, 180, 182, 203, 210, - 182, 203, 194, 182, 203, 224, 182, 203, 176, 182, 203, 206, 182, 203, - 190, 182, 203, 220, 182, 203, 183, 182, 203, 212, 182, 203, 197, 110, 45, - 182, 236, 250, 110, 82, 45, 118, 110, 246, 229, 110, 45, 182, 236, 250, - 110, 82, 45, 118, 110, 187, 110, 45, 182, 236, 250, 116, 82, 45, 118, - 110, 246, 229, 110, 45, 182, 236, 250, 116, 82, 45, 118, 110, 187, 110, - 45, 182, 236, 250, 116, 45, 118, 110, 246, 229, 110, 50, 182, 236, 250, - 116, 82, 45, 118, 116, 246, 229, 110, 50, 182, 236, 250, 116, 82, 45, - 118, 116, 187, 110, 50, 182, 236, 250, 110, 82, 45, 118, 116, 246, 229, - 110, 50, 182, 236, 250, 110, 82, 45, 118, 116, 187, 110, 50, 182, 236, - 250, 110, 45, 118, 116, 246, 229, 110, 50, 182, 236, 250, 110, 82, 45, - 118, 116, 82, 187, 110, 50, 182, 236, 250, 110, 246, 230, 118, 110, 82, - 187, 110, 50, 182, 236, 250, 110, 45, 118, 110, 82, 187, 110, 50, 182, - 236, 250, 110, 246, 230, 118, 116, 82, 187, 110, 50, 182, 236, 250, 110, - 45, 118, 116, 82, 187, 110, 50, 182, 236, 250, 110, 246, 230, 118, 116, - 187, 110, 45, 182, 236, 250, 116, 246, 230, 118, 116, 82, 187, 110, 45, - 182, 236, 250, 116, 45, 118, 116, 82, 187, 110, 45, 182, 236, 250, 116, - 246, 230, 118, 110, 82, 187, 110, 45, 182, 236, 250, 116, 45, 118, 110, - 82, 187, 110, 45, 182, 236, 250, 116, 246, 230, 118, 110, 187, 110, 45, - 182, 236, 250, 116, 82, 45, 118, 110, 82, 187, 116, 50, 182, 236, 250, - 110, 82, 45, 118, 110, 246, 229, 116, 50, 182, 236, 250, 110, 82, 45, - 118, 110, 187, 116, 50, 182, 236, 250, 116, 82, 45, 118, 110, 246, 229, - 116, 50, 182, 236, 250, 116, 82, 45, 118, 110, 187, 116, 50, 182, 236, - 250, 116, 45, 118, 110, 246, 229, 116, 45, 182, 236, 250, 116, 82, 45, - 118, 116, 246, 229, 116, 45, 182, 236, 250, 116, 82, 45, 118, 116, 187, - 116, 45, 182, 236, 250, 110, 82, 45, 118, 116, 246, 229, 116, 45, 182, - 236, 250, 110, 82, 45, 118, 116, 187, 116, 45, 182, 236, 250, 110, 45, - 118, 116, 246, 229, 116, 45, 182, 236, 250, 110, 82, 45, 118, 116, 82, - 187, 116, 45, 182, 236, 250, 110, 246, 230, 118, 110, 82, 187, 116, 45, - 182, 236, 250, 110, 45, 118, 110, 82, 187, 116, 45, 182, 236, 250, 110, - 246, 230, 118, 116, 82, 187, 116, 45, 182, 236, 250, 110, 45, 118, 116, - 82, 187, 116, 45, 182, 236, 250, 110, 246, 230, 118, 116, 187, 116, 50, - 182, 236, 250, 116, 246, 230, 118, 116, 82, 187, 116, 50, 182, 236, 250, - 116, 45, 118, 116, 82, 187, 116, 50, 182, 236, 250, 116, 246, 230, 118, - 110, 82, 187, 116, 50, 182, 236, 250, 116, 45, 118, 110, 82, 187, 116, - 50, 182, 236, 250, 116, 246, 230, 118, 110, 187, 116, 50, 182, 236, 250, - 116, 82, 45, 118, 110, 82, 187, 116, 24, 50, 24, 110, 197, 234, 115, 208, - 16, 248, 81, 45, 24, 110, 24, 50, 197, 234, 115, 208, 16, 248, 81, 116, - 24, 45, 24, 110, 197, 234, 115, 208, 16, 248, 81, 45, 24, 116, 24, 50, - 197, 234, 115, 208, 16, 248, 81, 45, 197, 234, 91, 208, 18, 248, 81, 116, - 197, 234, 91, 208, 18, 248, 81, 50, 197, 234, 91, 208, 18, 248, 81, 110, - 197, 234, 91, 208, 18, 248, 81, 81, 91, 234, 117, 248, 79, 81, 91, 234, - 117, 248, 78, 81, 91, 234, 117, 248, 77, 81, 91, 234, 117, 248, 76, 81, - 91, 234, 117, 248, 75, 81, 91, 234, 117, 248, 74, 228, 209, 91, 234, 117, - 248, 79, 228, 209, 91, 234, 117, 248, 78, 228, 209, 91, 234, 117, 248, - 77, 228, 209, 91, 234, 117, 248, 76, 228, 209, 91, 234, 117, 248, 75, - 228, 209, 91, 234, 117, 248, 74, 45, 24, 110, 91, 234, 117, 248, 81, 45, - 24, 116, 91, 234, 117, 248, 81, 50, 24, 116, 91, 234, 117, 248, 81, 50, - 24, 110, 91, 234, 117, 248, 81, 116, 24, 110, 91, 234, 117, 248, 81, 228, - 209, 91, 234, 117, 248, 80, 116, 91, 208, 18, 248, 81, 116, 115, 234, - 115, 248, 81, 116, 232, 185, 234, 115, 248, 81, 116, 115, 208, 16, 248, - 81, 116, 203, 242, 234, 115, 248, 81, 50, 91, 208, 18, 248, 81, 50, 115, - 234, 115, 248, 81, 50, 232, 185, 234, 115, 248, 81, 50, 115, 208, 16, - 248, 81, 50, 203, 242, 234, 115, 248, 81, 45, 134, 216, 194, 203, 148, - 50, 134, 216, 194, 203, 148, 116, 134, 216, 194, 203, 148, 110, 134, 216, - 194, 203, 148, 223, 67, 216, 194, 203, 148, 116, 134, 182, 24, 110, 134, - 223, 67, 216, 194, 203, 148, 116, 134, 223, 67, 216, 194, 203, 149, 24, - 110, 134, 248, 81, 45, 134, 223, 67, 216, 194, 203, 149, 24, 50, 134, - 248, 81, 243, 76, 248, 60, 232, 220, 223, 67, 243, 76, 248, 60, 232, 220, - 88, 228, 209, 232, 220, 116, 45, 118, 110, 50, 232, 220, 116, 50, 118, - 110, 45, 232, 220, 116, 24, 110, 197, 234, 134, 248, 81, 45, 24, 50, 197, - 234, 134, 248, 81, 116, 45, 197, 234, 216, 194, 203, 148, 116, 50, 197, - 234, 216, 194, 203, 148, 110, 50, 197, 234, 216, 194, 203, 148, 110, 45, - 197, 234, 216, 194, 203, 148, 111, 122, 155, 236, 250, 116, 246, 230, - 118, 82, 219, 200, 111, 122, 155, 236, 250, 116, 246, 230, 118, 82, 187, - 111, 122, 155, 236, 250, 82, 45, 118, 110, 246, 229, 111, 122, 155, 236, - 250, 82, 50, 118, 110, 246, 229, 111, 122, 155, 236, 250, 116, 246, 230, - 118, 82, 45, 118, 110, 246, 229, 111, 122, 155, 236, 250, 116, 246, 230, - 118, 82, 50, 118, 110, 246, 229, 111, 122, 155, 236, 250, 82, 45, 118, - 110, 246, 230, 118, 82, 187, 111, 122, 155, 236, 250, 82, 45, 118, 116, - 246, 230, 118, 82, 187, 111, 122, 155, 236, 250, 116, 246, 230, 118, 82, - 45, 24, 82, 50, 118, 110, 246, 229, 111, 122, 155, 236, 250, 116, 246, - 230, 118, 82, 50, 24, 82, 45, 118, 110, 246, 229, 111, 122, 155, 236, - 250, 116, 246, 230, 118, 82, 50, 118, 110, 246, 230, 118, 82, 219, 200, - 111, 122, 155, 236, 250, 116, 246, 230, 118, 82, 45, 118, 110, 246, 230, - 118, 82, 187, 111, 122, 155, 236, 250, 82, 45, 118, 116, 246, 230, 118, - 82, 50, 118, 110, 246, 229, 111, 122, 155, 236, 250, 82, 50, 118, 116, - 246, 230, 118, 82, 45, 118, 110, 246, 229, 111, 122, 155, 236, 250, 236, - 243, 111, 122, 155, 228, 209, 4, 81, 105, 250, 184, 209, 52, 223, 67, - 243, 78, 77, 45, 134, 206, 37, 217, 70, 50, 134, 206, 37, 217, 70, 223, - 67, 235, 75, 63, 4, 198, 131, 219, 190, 117, 63, 24, 116, 24, 110, 91, - 234, 117, 248, 81, 96, 63, 24, 116, 24, 110, 91, 234, 117, 248, 81, 235, - 75, 63, 24, 50, 91, 234, 117, 248, 81, 196, 62, 63, 24, 50, 91, 234, 117, - 248, 81, 45, 134, 232, 131, 50, 134, 232, 131, 195, 13, 35, 238, 170, 50, - 211, 66, 112, 236, 96, 214, 92, 236, 250, 238, 170, 214, 92, 236, 250, - 82, 50, 118, 110, 246, 229, 214, 92, 236, 250, 236, 243, 64, 88, 205, - 150, 4, 206, 108, 238, 209, 45, 198, 252, 64, 50, 209, 51, 223, 120, 82, - 198, 252, 64, 50, 209, 51, 223, 120, 50, 198, 252, 64, 50, 209, 51, 223, - 120, 214, 92, 112, 208, 8, 77, 201, 70, 232, 227, 201, 70, 232, 228, 4, - 250, 197, 207, 141, 201, 70, 232, 228, 219, 207, 219, 200, 201, 70, 232, - 228, 219, 207, 187, 201, 70, 232, 228, 4, 235, 62, 64, 196, 72, 243, 52, - 205, 37, 17, 191, 77, 205, 37, 17, 108, 205, 37, 17, 109, 205, 37, 17, - 139, 205, 37, 17, 137, 205, 37, 17, 153, 205, 37, 17, 173, 205, 37, 17, - 181, 205, 37, 17, 176, 205, 37, 17, 184, 12, 15, 227, 240, 12, 15, 227, - 239, 12, 15, 227, 238, 12, 15, 227, 237, 12, 15, 227, 236, 12, 15, 227, - 235, 12, 15, 227, 234, 12, 15, 227, 233, 12, 15, 227, 232, 12, 15, 227, - 231, 12, 15, 227, 230, 12, 15, 227, 229, 12, 15, 227, 228, 12, 15, 227, - 227, 12, 15, 227, 226, 12, 15, 227, 225, 12, 15, 227, 224, 12, 15, 227, - 223, 12, 15, 227, 222, 12, 15, 227, 221, 12, 15, 227, 220, 12, 15, 227, - 219, 12, 15, 227, 218, 12, 15, 227, 217, 12, 15, 227, 216, 12, 15, 227, - 215, 12, 15, 227, 214, 12, 15, 227, 213, 12, 15, 227, 212, 12, 15, 227, - 211, 12, 15, 227, 210, 12, 15, 227, 209, 12, 15, 227, 208, 12, 15, 227, - 207, 12, 15, 227, 206, 12, 15, 227, 205, 12, 15, 227, 204, 12, 15, 227, - 203, 12, 15, 227, 202, 12, 15, 227, 201, 12, 15, 227, 200, 12, 15, 227, - 199, 12, 15, 227, 198, 12, 15, 227, 197, 12, 15, 227, 196, 12, 15, 227, - 195, 12, 15, 227, 194, 12, 15, 227, 193, 12, 15, 227, 192, 12, 15, 227, - 191, 12, 15, 227, 190, 12, 15, 227, 189, 12, 15, 227, 188, 12, 15, 227, - 187, 12, 15, 227, 186, 12, 15, 227, 185, 12, 15, 227, 184, 12, 15, 227, - 183, 12, 15, 227, 182, 12, 15, 227, 181, 12, 15, 227, 180, 12, 15, 227, - 179, 12, 15, 227, 178, 12, 15, 227, 177, 12, 15, 227, 176, 12, 15, 227, - 175, 12, 15, 227, 174, 12, 15, 227, 173, 12, 15, 227, 172, 12, 15, 227, - 171, 12, 15, 227, 170, 12, 15, 227, 169, 12, 15, 227, 168, 12, 15, 227, - 167, 12, 15, 227, 166, 12, 15, 227, 165, 12, 15, 227, 164, 12, 15, 227, - 163, 12, 15, 227, 162, 12, 15, 227, 161, 12, 15, 227, 160, 12, 15, 227, - 159, 12, 15, 227, 158, 12, 15, 227, 157, 12, 15, 227, 156, 12, 15, 227, - 155, 12, 15, 227, 154, 12, 15, 227, 153, 12, 15, 227, 152, 12, 15, 227, - 151, 12, 15, 227, 150, 12, 15, 227, 149, 12, 15, 227, 148, 12, 15, 227, - 147, 12, 15, 227, 146, 12, 15, 227, 145, 12, 15, 227, 144, 12, 15, 227, - 143, 12, 15, 227, 142, 12, 15, 227, 141, 12, 15, 227, 140, 12, 15, 227, - 139, 12, 15, 227, 138, 12, 15, 227, 137, 12, 15, 227, 136, 12, 15, 227, - 135, 12, 15, 227, 134, 12, 15, 227, 133, 12, 15, 227, 132, 12, 15, 227, - 131, 12, 15, 227, 130, 12, 15, 227, 129, 12, 15, 227, 128, 12, 15, 227, - 127, 12, 15, 227, 126, 12, 15, 227, 125, 12, 15, 227, 124, 12, 15, 227, - 123, 12, 15, 227, 122, 12, 15, 227, 121, 12, 15, 227, 120, 12, 15, 227, - 119, 12, 15, 227, 118, 12, 15, 227, 117, 12, 15, 227, 116, 12, 15, 227, - 115, 12, 15, 227, 114, 12, 15, 227, 113, 12, 15, 227, 112, 12, 15, 227, - 111, 12, 15, 227, 110, 12, 15, 227, 109, 12, 15, 227, 108, 12, 15, 227, - 107, 12, 15, 227, 106, 12, 15, 227, 105, 12, 15, 227, 104, 12, 15, 227, - 103, 12, 15, 227, 102, 12, 15, 227, 101, 12, 15, 227, 100, 12, 15, 227, - 99, 12, 15, 227, 98, 12, 15, 227, 97, 12, 15, 227, 96, 12, 15, 227, 95, - 12, 15, 227, 94, 12, 15, 227, 93, 12, 15, 227, 92, 12, 15, 227, 91, 12, - 15, 227, 90, 12, 15, 227, 89, 12, 15, 227, 88, 12, 15, 227, 87, 12, 15, - 227, 86, 12, 15, 227, 85, 12, 15, 227, 84, 12, 15, 227, 83, 12, 15, 227, - 82, 12, 15, 227, 81, 12, 15, 227, 80, 12, 15, 227, 79, 12, 15, 227, 78, - 12, 15, 227, 77, 12, 15, 227, 76, 12, 15, 227, 75, 12, 15, 227, 74, 12, - 15, 227, 73, 12, 15, 227, 72, 12, 15, 227, 71, 12, 15, 227, 70, 12, 15, - 227, 69, 12, 15, 227, 68, 12, 15, 227, 67, 12, 15, 227, 66, 12, 15, 227, - 65, 12, 15, 227, 64, 12, 15, 227, 63, 12, 15, 227, 62, 12, 15, 227, 61, - 12, 15, 227, 60, 12, 15, 227, 59, 12, 15, 227, 58, 12, 15, 227, 57, 12, - 15, 227, 56, 12, 15, 227, 55, 12, 15, 227, 54, 12, 15, 227, 53, 12, 15, - 227, 52, 12, 15, 227, 51, 12, 15, 227, 50, 12, 15, 227, 49, 12, 15, 227, - 48, 12, 15, 227, 47, 12, 15, 227, 46, 12, 15, 227, 45, 12, 15, 227, 44, - 12, 15, 227, 43, 12, 15, 227, 42, 12, 15, 227, 41, 12, 15, 227, 40, 12, - 15, 227, 39, 12, 15, 227, 38, 12, 15, 227, 37, 12, 15, 227, 36, 12, 15, - 227, 35, 12, 15, 227, 34, 12, 15, 227, 33, 12, 15, 227, 32, 12, 15, 227, - 31, 12, 15, 227, 30, 12, 15, 227, 29, 12, 15, 227, 28, 12, 15, 227, 27, - 12, 15, 227, 26, 12, 15, 227, 25, 12, 15, 227, 24, 12, 15, 227, 23, 12, - 15, 227, 22, 12, 15, 227, 21, 12, 15, 227, 20, 12, 15, 227, 19, 12, 15, - 227, 18, 12, 15, 227, 17, 12, 15, 227, 16, 12, 15, 227, 15, 12, 15, 227, - 14, 12, 15, 227, 13, 12, 15, 227, 12, 12, 15, 227, 11, 12, 15, 227, 10, - 12, 15, 227, 9, 12, 15, 227, 8, 12, 15, 227, 7, 12, 15, 227, 6, 12, 15, - 227, 5, 12, 15, 227, 4, 12, 15, 227, 3, 12, 15, 227, 2, 12, 15, 227, 1, - 12, 15, 227, 0, 12, 15, 226, 255, 12, 15, 226, 254, 12, 15, 226, 253, 12, - 15, 226, 252, 12, 15, 226, 251, 12, 15, 226, 250, 12, 15, 226, 249, 12, - 15, 226, 248, 12, 15, 226, 247, 12, 15, 226, 246, 12, 15, 226, 245, 12, - 15, 226, 244, 12, 15, 226, 243, 12, 15, 226, 242, 12, 15, 226, 241, 12, - 15, 226, 240, 12, 15, 226, 239, 12, 15, 226, 238, 12, 15, 226, 237, 12, - 15, 226, 236, 12, 15, 226, 235, 12, 15, 226, 234, 12, 15, 226, 233, 12, - 15, 226, 232, 12, 15, 226, 231, 12, 15, 226, 230, 12, 15, 226, 229, 12, - 15, 226, 228, 12, 15, 226, 227, 12, 15, 226, 226, 12, 15, 226, 225, 12, - 15, 226, 224, 12, 15, 226, 223, 12, 15, 226, 222, 12, 15, 226, 221, 12, - 15, 226, 220, 12, 15, 226, 219, 12, 15, 226, 218, 12, 15, 226, 217, 12, - 15, 226, 216, 12, 15, 226, 215, 12, 15, 226, 214, 12, 15, 226, 213, 12, - 15, 226, 212, 12, 15, 226, 211, 12, 15, 226, 210, 12, 15, 226, 209, 12, - 15, 226, 208, 12, 15, 226, 207, 12, 15, 226, 206, 12, 15, 226, 205, 12, - 15, 226, 204, 12, 15, 226, 203, 12, 15, 226, 202, 12, 15, 226, 201, 12, - 15, 226, 200, 12, 15, 226, 199, 12, 15, 226, 198, 12, 15, 226, 197, 12, - 15, 226, 196, 12, 15, 226, 195, 12, 15, 226, 194, 12, 15, 226, 193, 12, - 15, 226, 192, 12, 15, 226, 191, 12, 15, 226, 190, 12, 15, 226, 189, 12, - 15, 226, 188, 12, 15, 226, 187, 12, 15, 226, 186, 12, 15, 226, 185, 12, - 15, 226, 184, 12, 15, 226, 183, 12, 15, 226, 182, 12, 15, 226, 181, 12, - 15, 226, 180, 12, 15, 226, 179, 12, 15, 226, 178, 12, 15, 226, 177, 12, - 15, 226, 176, 12, 15, 226, 175, 12, 15, 226, 174, 12, 15, 226, 173, 12, - 15, 226, 172, 12, 15, 226, 171, 12, 15, 226, 170, 12, 15, 226, 169, 12, - 15, 226, 168, 12, 15, 226, 167, 12, 15, 226, 166, 12, 15, 226, 165, 12, - 15, 226, 164, 12, 15, 226, 163, 12, 15, 226, 162, 12, 15, 226, 161, 12, - 15, 226, 160, 12, 15, 226, 159, 12, 15, 226, 158, 12, 15, 226, 157, 12, - 15, 226, 156, 12, 15, 226, 155, 12, 15, 226, 154, 12, 15, 226, 153, 12, - 15, 226, 152, 12, 15, 226, 151, 12, 15, 226, 150, 12, 15, 226, 149, 12, - 15, 226, 148, 12, 15, 226, 147, 12, 15, 226, 146, 12, 15, 226, 145, 12, - 15, 226, 144, 12, 15, 226, 143, 12, 15, 226, 142, 12, 15, 226, 141, 12, - 15, 226, 140, 12, 15, 226, 139, 12, 15, 226, 138, 12, 15, 226, 137, 12, - 15, 226, 136, 12, 15, 226, 135, 12, 15, 226, 134, 12, 15, 226, 133, 12, - 15, 226, 132, 12, 15, 226, 131, 12, 15, 226, 130, 12, 15, 226, 129, 12, - 15, 226, 128, 12, 15, 226, 127, 12, 15, 226, 126, 12, 15, 226, 125, 12, - 15, 226, 124, 12, 15, 226, 123, 12, 15, 226, 122, 12, 15, 226, 121, 12, - 15, 226, 120, 12, 15, 226, 119, 12, 15, 226, 118, 12, 15, 226, 117, 12, - 15, 226, 116, 12, 15, 226, 115, 12, 15, 226, 114, 12, 15, 226, 113, 12, - 15, 226, 112, 12, 15, 226, 111, 12, 15, 226, 110, 12, 15, 226, 109, 12, - 15, 226, 108, 12, 15, 226, 107, 12, 15, 226, 106, 12, 15, 226, 105, 12, - 15, 226, 104, 12, 15, 226, 103, 12, 15, 226, 102, 12, 15, 226, 101, 12, - 15, 226, 100, 12, 15, 226, 99, 12, 15, 226, 98, 12, 15, 226, 97, 12, 15, - 226, 96, 12, 15, 226, 95, 12, 15, 226, 94, 12, 15, 226, 93, 12, 15, 226, - 92, 12, 15, 226, 91, 12, 15, 226, 90, 12, 15, 226, 89, 12, 15, 226, 88, - 12, 15, 226, 87, 12, 15, 226, 86, 12, 15, 226, 85, 12, 15, 226, 84, 12, - 15, 226, 83, 12, 15, 226, 82, 12, 15, 226, 81, 12, 15, 226, 80, 12, 15, - 226, 79, 12, 15, 226, 78, 12, 15, 226, 77, 12, 15, 226, 76, 12, 15, 226, - 75, 12, 15, 226, 74, 12, 15, 226, 73, 12, 15, 226, 72, 12, 15, 226, 71, - 12, 15, 226, 70, 12, 15, 226, 69, 12, 15, 226, 68, 12, 15, 226, 67, 12, - 15, 226, 66, 12, 15, 226, 65, 12, 15, 226, 64, 12, 15, 226, 63, 12, 15, - 226, 62, 12, 15, 226, 61, 12, 15, 226, 60, 12, 15, 226, 59, 12, 15, 226, - 58, 12, 15, 226, 57, 12, 15, 226, 56, 12, 15, 226, 55, 12, 15, 226, 54, - 12, 15, 226, 53, 12, 15, 226, 52, 12, 15, 226, 51, 12, 15, 226, 50, 12, - 15, 226, 49, 12, 15, 226, 48, 12, 15, 226, 47, 12, 15, 226, 46, 12, 15, - 226, 45, 12, 15, 226, 44, 12, 15, 226, 43, 12, 15, 226, 42, 12, 15, 226, - 41, 12, 15, 226, 40, 12, 15, 226, 39, 12, 15, 226, 38, 12, 15, 226, 37, - 12, 15, 226, 36, 12, 15, 226, 35, 12, 15, 226, 34, 12, 15, 226, 33, 12, - 15, 226, 32, 12, 15, 226, 31, 12, 15, 226, 30, 12, 15, 226, 29, 12, 15, - 226, 28, 12, 15, 226, 27, 12, 15, 226, 26, 12, 15, 226, 25, 12, 15, 226, - 24, 12, 15, 226, 23, 12, 15, 226, 22, 12, 15, 226, 21, 12, 15, 226, 20, - 12, 15, 226, 19, 12, 15, 226, 18, 12, 15, 226, 17, 12, 15, 226, 16, 12, - 15, 226, 15, 12, 15, 226, 14, 12, 15, 226, 13, 12, 15, 226, 12, 12, 15, - 226, 11, 12, 15, 226, 10, 12, 15, 226, 9, 12, 15, 226, 8, 12, 15, 226, 7, - 12, 15, 226, 6, 12, 15, 226, 5, 12, 15, 226, 4, 12, 15, 226, 3, 12, 15, - 226, 2, 12, 15, 226, 1, 12, 15, 226, 0, 12, 15, 225, 255, 12, 15, 225, - 254, 12, 15, 225, 253, 12, 15, 225, 252, 12, 15, 225, 251, 12, 15, 225, - 250, 12, 15, 225, 249, 12, 15, 225, 248, 12, 15, 225, 247, 12, 15, 225, - 246, 12, 15, 225, 245, 12, 15, 225, 244, 12, 15, 225, 243, 12, 15, 225, - 242, 12, 15, 225, 241, 12, 15, 225, 240, 12, 15, 225, 239, 12, 15, 225, - 238, 12, 15, 225, 237, 12, 15, 225, 236, 12, 15, 225, 235, 12, 15, 225, - 234, 12, 15, 225, 233, 12, 15, 225, 232, 12, 15, 225, 231, 12, 15, 225, - 230, 12, 15, 225, 229, 12, 15, 225, 228, 12, 15, 225, 227, 12, 15, 225, - 226, 12, 15, 225, 225, 12, 15, 225, 224, 12, 15, 225, 223, 12, 15, 225, - 222, 12, 15, 225, 221, 12, 15, 225, 220, 12, 15, 225, 219, 12, 15, 225, - 218, 12, 15, 225, 217, 12, 15, 225, 216, 12, 15, 225, 215, 12, 15, 225, - 214, 12, 15, 225, 213, 12, 15, 225, 212, 12, 15, 225, 211, 219, 252, 199, - 218, 199, 219, 201, 242, 199, 219, 233, 175, 77, 199, 219, 207, 247, 77, - 199, 219, 31, 57, 199, 219, 236, 110, 57, 199, 219, 210, 4, 57, 199, 219, - 251, 86, 199, 219, 250, 255, 199, 219, 45, 210, 103, 199, 219, 50, 210, - 103, 199, 219, 250, 143, 199, 219, 107, 57, 199, 219, 242, 26, 199, 219, - 228, 57, 199, 219, 232, 42, 201, 58, 199, 219, 202, 18, 199, 219, 17, - 191, 77, 199, 219, 17, 108, 199, 219, 17, 109, 199, 219, 17, 139, 199, - 219, 17, 137, 199, 219, 17, 153, 199, 219, 17, 173, 199, 219, 17, 181, - 199, 219, 17, 176, 199, 219, 17, 184, 199, 219, 242, 35, 199, 219, 204, - 20, 199, 219, 219, 156, 57, 199, 219, 234, 1, 57, 199, 219, 230, 170, 57, - 199, 219, 208, 8, 77, 199, 219, 242, 24, 250, 132, 199, 219, 8, 6, 1, 65, - 199, 219, 8, 6, 1, 250, 70, 199, 219, 8, 6, 1, 247, 145, 199, 219, 8, 6, - 1, 238, 80, 199, 219, 8, 6, 1, 73, 199, 219, 8, 6, 1, 233, 134, 199, 219, - 8, 6, 1, 232, 14, 199, 219, 8, 6, 1, 230, 83, 199, 219, 8, 6, 1, 70, 199, - 219, 8, 6, 1, 223, 7, 199, 219, 8, 6, 1, 222, 125, 199, 219, 8, 6, 1, - 170, 199, 219, 8, 6, 1, 218, 147, 199, 219, 8, 6, 1, 215, 47, 199, 219, - 8, 6, 1, 74, 199, 219, 8, 6, 1, 210, 226, 199, 219, 8, 6, 1, 208, 97, - 199, 219, 8, 6, 1, 148, 199, 219, 8, 6, 1, 206, 3, 199, 219, 8, 6, 1, - 200, 39, 199, 219, 8, 6, 1, 69, 199, 219, 8, 6, 1, 196, 8, 199, 219, 8, - 6, 1, 193, 221, 199, 219, 8, 6, 1, 192, 235, 199, 219, 8, 6, 1, 192, 159, - 199, 219, 8, 6, 1, 191, 166, 199, 219, 45, 51, 248, 5, 199, 219, 207, 14, - 202, 18, 199, 219, 50, 51, 248, 5, 199, 219, 242, 210, 252, 8, 199, 219, - 131, 219, 88, 199, 219, 230, 177, 252, 8, 199, 219, 8, 2, 1, 65, 199, - 219, 8, 2, 1, 250, 70, 199, 219, 8, 2, 1, 247, 145, 199, 219, 8, 2, 1, - 238, 80, 199, 219, 8, 2, 1, 73, 199, 219, 8, 2, 1, 233, 134, 199, 219, 8, - 2, 1, 232, 14, 199, 219, 8, 2, 1, 230, 83, 199, 219, 8, 2, 1, 70, 199, - 219, 8, 2, 1, 223, 7, 199, 219, 8, 2, 1, 222, 125, 199, 219, 8, 2, 1, - 170, 199, 219, 8, 2, 1, 218, 147, 199, 219, 8, 2, 1, 215, 47, 199, 219, - 8, 2, 1, 74, 199, 219, 8, 2, 1, 210, 226, 199, 219, 8, 2, 1, 208, 97, - 199, 219, 8, 2, 1, 148, 199, 219, 8, 2, 1, 206, 3, 199, 219, 8, 2, 1, - 200, 39, 199, 219, 8, 2, 1, 69, 199, 219, 8, 2, 1, 196, 8, 199, 219, 8, - 2, 1, 193, 221, 199, 219, 8, 2, 1, 192, 235, 199, 219, 8, 2, 1, 192, 159, - 199, 219, 8, 2, 1, 191, 166, 199, 219, 45, 238, 124, 248, 5, 199, 219, - 81, 219, 88, 199, 219, 50, 238, 124, 248, 5, 199, 219, 198, 147, 247, 79, - 199, 218, 66, 204, 206, 66, 204, 195, 66, 204, 184, 66, 204, 172, 66, - 204, 161, 66, 204, 150, 66, 204, 139, 66, 204, 128, 66, 204, 117, 66, - 204, 109, 66, 204, 108, 66, 204, 107, 66, 204, 106, 66, 204, 104, 66, - 204, 103, 66, 204, 102, 66, 204, 101, 66, 204, 100, 66, 204, 99, 66, 204, - 98, 66, 204, 97, 66, 204, 96, 66, 204, 95, 66, 204, 93, 66, 204, 92, 66, - 204, 91, 66, 204, 90, 66, 204, 89, 66, 204, 88, 66, 204, 87, 66, 204, 86, - 66, 204, 85, 66, 204, 84, 66, 204, 82, 66, 204, 81, 66, 204, 80, 66, 204, - 79, 66, 204, 78, 66, 204, 77, 66, 204, 76, 66, 204, 75, 66, 204, 74, 66, - 204, 73, 66, 204, 71, 66, 204, 70, 66, 204, 69, 66, 204, 68, 66, 204, 67, - 66, 204, 66, 66, 204, 65, 66, 204, 64, 66, 204, 63, 66, 204, 62, 66, 204, - 60, 66, 204, 59, 66, 204, 58, 66, 204, 57, 66, 204, 56, 66, 204, 55, 66, - 204, 54, 66, 204, 53, 66, 204, 52, 66, 204, 51, 66, 204, 49, 66, 204, 48, - 66, 204, 47, 66, 204, 46, 66, 204, 45, 66, 204, 44, 66, 204, 43, 66, 204, - 42, 66, 204, 41, 66, 204, 40, 66, 204, 38, 66, 204, 37, 66, 204, 36, 66, - 204, 35, 66, 204, 34, 66, 204, 33, 66, 204, 32, 66, 204, 31, 66, 204, 30, - 66, 204, 29, 66, 205, 26, 66, 205, 25, 66, 205, 24, 66, 205, 23, 66, 205, - 22, 66, 205, 21, 66, 205, 20, 66, 205, 19, 66, 205, 18, 66, 205, 17, 66, - 205, 15, 66, 205, 14, 66, 205, 13, 66, 205, 12, 66, 205, 11, 66, 205, 10, - 66, 205, 9, 66, 205, 8, 66, 205, 7, 66, 205, 6, 66, 205, 4, 66, 205, 3, - 66, 205, 2, 66, 205, 1, 66, 205, 0, 66, 204, 255, 66, 204, 254, 66, 204, - 253, 66, 204, 252, 66, 204, 251, 66, 204, 249, 66, 204, 248, 66, 204, - 247, 66, 204, 246, 66, 204, 245, 66, 204, 244, 66, 204, 243, 66, 204, - 242, 66, 204, 241, 66, 204, 240, 66, 204, 238, 66, 204, 237, 66, 204, - 236, 66, 204, 235, 66, 204, 234, 66, 204, 233, 66, 204, 232, 66, 204, - 231, 66, 204, 230, 66, 204, 229, 66, 204, 227, 66, 204, 226, 66, 204, - 225, 66, 204, 224, 66, 204, 223, 66, 204, 222, 66, 204, 221, 66, 204, - 220, 66, 204, 219, 66, 204, 218, 66, 204, 216, 66, 204, 215, 66, 204, - 214, 66, 204, 213, 66, 204, 212, 66, 204, 211, 66, 204, 210, 66, 204, - 209, 66, 204, 208, 66, 204, 207, 66, 204, 205, 66, 204, 204, 66, 204, - 203, 66, 204, 202, 66, 204, 201, 66, 204, 200, 66, 204, 199, 66, 204, - 198, 66, 204, 197, 66, 204, 196, 66, 204, 194, 66, 204, 193, 66, 204, - 192, 66, 204, 191, 66, 204, 190, 66, 204, 189, 66, 204, 188, 66, 204, - 187, 66, 204, 186, 66, 204, 185, 66, 204, 183, 66, 204, 182, 66, 204, - 181, 66, 204, 180, 66, 204, 179, 66, 204, 178, 66, 204, 177, 66, 204, - 176, 66, 204, 175, 66, 204, 174, 66, 204, 171, 66, 204, 170, 66, 204, - 169, 66, 204, 168, 66, 204, 167, 66, 204, 166, 66, 204, 165, 66, 204, - 164, 66, 204, 163, 66, 204, 162, 66, 204, 160, 66, 204, 159, 66, 204, - 158, 66, 204, 157, 66, 204, 156, 66, 204, 155, 66, 204, 154, 66, 204, - 153, 66, 204, 152, 66, 204, 151, 66, 204, 149, 66, 204, 148, 66, 204, - 147, 66, 204, 146, 66, 204, 145, 66, 204, 144, 66, 204, 143, 66, 204, - 142, 66, 204, 141, 66, 204, 140, 66, 204, 138, 66, 204, 137, 66, 204, - 136, 66, 204, 135, 66, 204, 134, 66, 204, 133, 66, 204, 132, 66, 204, - 131, 66, 204, 130, 66, 204, 129, 66, 204, 127, 66, 204, 126, 66, 204, - 125, 66, 204, 124, 66, 204, 123, 66, 204, 122, 66, 204, 121, 66, 204, - 120, 66, 204, 119, 66, 204, 118, 66, 204, 116, 66, 204, 115, 66, 204, - 114, 66, 204, 113, 66, 204, 112, 66, 204, 111, 66, 204, 110, 212, 125, - 212, 127, 201, 93, 80, 229, 200, 202, 22, 201, 93, 80, 199, 48, 201, 1, - 234, 53, 80, 199, 48, 233, 203, 234, 53, 80, 198, 7, 234, 15, 234, 39, - 234, 40, 251, 255, 252, 0, 251, 138, 248, 188, 249, 90, 247, 224, 246, - 192, 199, 225, 228, 209, 199, 225, 228, 134, 199, 231, 219, 89, 233, 9, - 214, 66, 219, 88, 234, 53, 80, 219, 88, 219, 137, 213, 92, 234, 18, 219, - 89, 199, 225, 81, 199, 225, 193, 248, 232, 107, 233, 9, 232, 242, 247, - 40, 207, 17, 238, 189, 203, 72, 211, 4, 219, 9, 108, 202, 41, 203, 72, - 223, 134, 219, 9, 191, 77, 202, 217, 237, 165, 219, 79, 233, 228, 236, - 140, 237, 30, 238, 231, 108, 237, 154, 237, 30, 238, 231, 109, 237, 153, - 237, 30, 238, 231, 139, 237, 152, 237, 30, 238, 231, 137, 237, 151, 214, - 92, 251, 255, 214, 219, 200, 65, 223, 199, 200, 69, 234, 53, 80, 198, 8, - 248, 81, 233, 210, 247, 78, 247, 80, 234, 53, 80, 216, 193, 234, 16, 200, - 221, 200, 240, 233, 228, 233, 229, 223, 109, 204, 6, 137, 232, 222, 204, - 5, 232, 52, 223, 109, 204, 6, 139, 230, 154, 204, 5, 230, 151, 223, 109, - 204, 6, 109, 207, 93, 204, 5, 206, 69, 223, 109, 204, 6, 108, 196, 87, - 204, 5, 196, 41, 201, 245, 237, 71, 237, 73, 210, 198, 246, 191, 210, - 200, 136, 211, 146, 208, 213, 228, 212, 247, 250, 209, 248, 229, 160, - 248, 10, 213, 31, 247, 250, 229, 160, 214, 177, 223, 120, 223, 122, 214, - 59, 219, 88, 214, 90, 201, 93, 80, 205, 31, 250, 214, 201, 170, 234, 53, - 80, 205, 31, 250, 214, 233, 231, 246, 192, 199, 226, 203, 247, 228, 209, - 199, 226, 203, 247, 228, 131, 246, 192, 199, 226, 4, 222, 137, 228, 209, - 199, 226, 4, 222, 137, 228, 132, 219, 89, 199, 226, 203, 247, 81, 199, - 226, 203, 247, 193, 247, 210, 95, 219, 89, 232, 94, 210, 95, 219, 89, - 235, 79, 209, 86, 210, 95, 219, 89, 249, 89, 210, 95, 219, 89, 196, 73, - 209, 80, 207, 14, 219, 89, 233, 9, 207, 14, 223, 120, 206, 252, 202, 165, - 203, 72, 109, 202, 162, 201, 172, 202, 165, 203, 72, 139, 202, 161, 201, - 171, 237, 30, 238, 231, 201, 25, 237, 149, 208, 198, 196, 40, 108, 208, - 198, 196, 38, 208, 157, 208, 198, 196, 40, 109, 208, 198, 196, 37, 208, - 156, 203, 248, 198, 6, 201, 90, 201, 8, 247, 79, 246, 191, 247, 13, 216, - 150, 193, 168, 215, 67, 201, 93, 80, 230, 139, 250, 214, 201, 93, 80, - 208, 175, 250, 214, 201, 244, 234, 53, 80, 230, 139, 250, 214, 234, 53, - 80, 208, 175, 250, 214, 234, 13, 201, 93, 80, 201, 25, 202, 4, 202, 165, - 230, 182, 246, 192, 223, 68, 203, 165, 202, 165, 246, 192, 223, 68, 205, - 80, 238, 231, 204, 2, 223, 68, 238, 149, 201, 26, 199, 75, 201, 113, 211, - 57, 200, 54, 242, 25, 211, 24, 208, 199, 216, 149, 209, 68, 250, 251, - 208, 191, 242, 25, 251, 12, 214, 165, 202, 226, 8, 6, 1, 231, 54, 8, 2, - 1, 231, 54, 246, 212, 251, 115, 200, 59, 200, 227, 242, 36, 202, 105, - 219, 200, 222, 55, 1, 219, 38, 219, 249, 1, 232, 136, 232, 127, 219, 249, - 1, 232, 136, 233, 21, 219, 249, 1, 206, 157, 219, 249, 1, 219, 19, 86, - 87, 248, 93, 203, 45, 231, 17, 216, 99, 207, 4, 30, 125, 192, 54, 30, - 125, 192, 50, 30, 125, 201, 148, 30, 125, 192, 55, 232, 29, 232, 28, 232, - 27, 215, 69, 232, 26, 190, 232, 190, 233, 190, 235, 218, 207, 206, 165, - 218, 209, 206, 167, 210, 56, 218, 206, 206, 164, 213, 62, 215, 255, 193, - 50, 218, 208, 206, 166, 232, 51, 210, 55, 193, 109, 234, 77, 232, 39, - 216, 73, 211, 94, 196, 42, 113, 216, 73, 237, 171, 113, 117, 197, 236, - 63, 4, 54, 81, 105, 96, 197, 236, 63, 4, 54, 81, 105, 11, 5, 223, 23, 77, - 79, 1, 221, 181, 219, 49, 194, 248, 194, 137, 194, 69, 194, 58, 194, 47, - 194, 36, 194, 25, 194, 14, 194, 3, 194, 247, 194, 236, 194, 225, 194, - 214, 194, 203, 194, 192, 194, 181, 208, 214, 232, 107, 39, 81, 50, 64, - 219, 163, 248, 5, 247, 150, 211, 41, 77, 248, 52, 190, 234, 10, 3, 212, - 135, 199, 79, 10, 3, 212, 135, 138, 212, 135, 247, 183, 138, 247, 182, - 216, 199, 6, 1, 230, 83, 216, 199, 6, 1, 214, 56, 216, 199, 2, 1, 230, - 83, 216, 199, 2, 1, 214, 56, 61, 1, 234, 226, 72, 37, 16, 232, 50, 202, - 101, 243, 4, 195, 161, 194, 170, 194, 159, 194, 148, 194, 136, 194, 125, - 194, 114, 194, 103, 194, 92, 194, 81, 194, 73, 194, 72, 194, 71, 194, 70, - 194, 68, 194, 67, 194, 66, 194, 65, 194, 64, 194, 63, 194, 62, 194, 61, - 194, 60, 194, 59, 194, 57, 194, 56, 194, 55, 194, 54, 194, 53, 194, 52, - 194, 51, 194, 50, 194, 49, 194, 48, 194, 46, 194, 45, 194, 44, 194, 43, - 194, 42, 194, 41, 194, 40, 194, 39, 194, 38, 194, 37, 194, 35, 194, 34, - 194, 33, 194, 32, 194, 31, 194, 30, 194, 29, 194, 28, 194, 27, 194, 26, - 194, 24, 194, 23, 194, 22, 194, 21, 194, 20, 194, 19, 194, 18, 194, 17, - 194, 16, 194, 15, 194, 13, 194, 12, 194, 11, 194, 10, 194, 9, 194, 8, - 194, 7, 194, 6, 194, 5, 194, 4, 194, 2, 194, 1, 194, 0, 193, 255, 193, - 254, 193, 253, 193, 252, 193, 251, 193, 250, 193, 249, 194, 246, 194, - 245, 194, 244, 194, 243, 194, 242, 194, 241, 194, 240, 194, 239, 194, - 238, 194, 237, 194, 235, 194, 234, 194, 233, 194, 232, 194, 231, 194, - 230, 194, 229, 194, 228, 194, 227, 194, 226, 194, 224, 194, 223, 194, - 222, 194, 221, 194, 220, 194, 219, 194, 218, 194, 217, 194, 216, 194, - 215, 194, 213, 194, 212, 194, 211, 194, 210, 194, 209, 194, 208, 194, - 207, 194, 206, 194, 205, 194, 204, 194, 202, 194, 201, 194, 200, 194, - 199, 194, 198, 194, 197, 194, 196, 194, 195, 194, 194, 194, 193, 194, - 191, 194, 190, 194, 189, 194, 188, 194, 187, 194, 186, 194, 185, 194, - 184, 194, 183, 194, 182, 194, 180, 194, 179, 194, 178, 194, 177, 194, - 176, 194, 175, 194, 174, 194, 173, 194, 172, 194, 171, 194, 169, 194, - 168, 194, 167, 194, 166, 194, 165, 194, 164, 194, 163, 194, 162, 194, - 161, 194, 160, 194, 158, 194, 157, 194, 156, 194, 155, 194, 154, 194, - 153, 194, 152, 194, 151, 194, 150, 194, 149, 194, 147, 194, 146, 194, - 145, 194, 144, 194, 143, 194, 142, 194, 141, 194, 140, 194, 139, 194, - 138, 194, 135, 194, 134, 194, 133, 194, 132, 194, 131, 194, 130, 194, - 129, 194, 128, 194, 127, 194, 126, 194, 124, 194, 123, 194, 122, 194, - 121, 194, 120, 194, 119, 194, 118, 194, 117, 194, 116, 194, 115, 194, - 113, 194, 112, 194, 111, 194, 110, 194, 109, 194, 108, 194, 107, 194, - 106, 194, 105, 194, 104, 194, 102, 194, 101, 194, 100, 194, 99, 194, 98, - 194, 97, 194, 96, 194, 95, 194, 94, 194, 93, 194, 91, 194, 90, 194, 89, - 194, 88, 194, 87, 194, 86, 194, 85, 194, 84, 194, 83, 194, 82, 194, 80, - 194, 79, 194, 78, 194, 77, 194, 76, 194, 75, 194, 74, 221, 194, 31, 57, - 221, 194, 250, 143, 221, 194, 17, 191, 77, 221, 194, 17, 108, 221, 194, - 17, 109, 221, 194, 17, 139, 221, 194, 17, 137, 221, 194, 17, 153, 221, - 194, 17, 173, 221, 194, 17, 181, 221, 194, 17, 176, 221, 194, 17, 184, 8, - 6, 1, 41, 4, 217, 126, 24, 230, 176, 8, 2, 1, 41, 4, 217, 126, 24, 230, - 176, 8, 6, 1, 228, 44, 4, 217, 126, 24, 230, 176, 8, 2, 1, 228, 44, 4, - 217, 126, 24, 230, 176, 8, 6, 1, 126, 4, 217, 126, 24, 230, 176, 8, 2, 1, - 126, 4, 217, 126, 24, 230, 176, 8, 6, 1, 234, 227, 4, 81, 219, 89, 60, 8, - 2, 1, 234, 227, 4, 81, 219, 89, 60, 8, 6, 1, 234, 227, 4, 81, 219, 89, - 248, 183, 24, 230, 176, 8, 2, 1, 234, 227, 4, 81, 219, 89, 248, 183, 24, - 230, 176, 8, 6, 1, 234, 227, 4, 81, 219, 89, 248, 183, 24, 251, 250, 8, - 2, 1, 234, 227, 4, 81, 219, 89, 248, 183, 24, 251, 250, 8, 6, 1, 186, 4, - 81, 219, 89, 60, 8, 2, 1, 186, 4, 81, 219, 89, 60, 8, 6, 1, 186, 4, 81, - 219, 89, 248, 183, 24, 230, 176, 8, 2, 1, 186, 4, 81, 219, 89, 248, 183, - 24, 230, 176, 8, 6, 1, 186, 4, 81, 219, 89, 248, 183, 24, 251, 250, 8, 2, - 1, 186, 4, 81, 219, 89, 248, 183, 24, 251, 250, 8, 6, 1, 206, 4, 4, 81, - 219, 89, 60, 8, 2, 1, 206, 4, 4, 81, 219, 89, 60, 8, 6, 1, 234, 227, 4, - 242, 210, 24, 217, 125, 8, 2, 1, 234, 227, 4, 242, 210, 24, 217, 125, 8, - 6, 1, 234, 227, 4, 242, 210, 24, 247, 44, 8, 2, 1, 234, 227, 4, 242, 210, - 24, 247, 44, 8, 2, 1, 228, 44, 4, 75, 95, 24, 251, 250, 8, 2, 1, 214, 57, - 4, 198, 148, 56, 8, 6, 1, 41, 4, 211, 127, 24, 251, 250, 8, 2, 1, 41, 4, - 211, 127, 24, 251, 250, 8, 6, 1, 41, 4, 211, 127, 24, 198, 147, 8, 2, 1, - 41, 4, 211, 127, 24, 198, 147, 8, 6, 1, 234, 227, 4, 211, 127, 24, 251, - 250, 8, 2, 1, 234, 227, 4, 211, 127, 24, 251, 250, 8, 6, 1, 234, 227, 4, - 211, 127, 24, 198, 147, 8, 2, 1, 234, 227, 4, 211, 127, 24, 198, 147, 8, - 6, 1, 234, 227, 4, 75, 95, 24, 251, 250, 8, 2, 1, 234, 227, 4, 75, 95, - 24, 251, 250, 8, 6, 1, 234, 227, 4, 75, 95, 24, 198, 147, 8, 2, 1, 234, - 227, 4, 75, 95, 24, 198, 147, 8, 2, 1, 228, 44, 4, 75, 95, 24, 230, 176, - 8, 2, 1, 228, 44, 4, 75, 95, 24, 198, 147, 8, 6, 1, 228, 44, 4, 211, 127, - 24, 251, 250, 8, 2, 1, 228, 44, 4, 211, 127, 24, 75, 95, 24, 251, 250, 8, - 6, 1, 228, 44, 4, 211, 127, 24, 198, 147, 8, 2, 1, 228, 44, 4, 211, 127, - 24, 75, 95, 24, 198, 147, 8, 6, 1, 223, 8, 4, 198, 147, 8, 2, 1, 223, 8, - 4, 75, 95, 24, 198, 147, 8, 6, 1, 220, 119, 4, 198, 147, 8, 2, 1, 220, - 119, 4, 198, 147, 8, 6, 1, 218, 148, 4, 198, 147, 8, 2, 1, 218, 148, 4, - 198, 147, 8, 6, 1, 207, 217, 4, 198, 147, 8, 2, 1, 207, 217, 4, 198, 147, - 8, 6, 1, 126, 4, 211, 127, 24, 251, 250, 8, 2, 1, 126, 4, 211, 127, 24, - 251, 250, 8, 6, 1, 126, 4, 211, 127, 24, 198, 147, 8, 2, 1, 126, 4, 211, - 127, 24, 198, 147, 8, 6, 1, 126, 4, 217, 126, 24, 251, 250, 8, 2, 1, 126, - 4, 217, 126, 24, 251, 250, 8, 6, 1, 126, 4, 217, 126, 24, 198, 147, 8, 2, - 1, 126, 4, 217, 126, 24, 198, 147, 8, 2, 1, 251, 230, 4, 230, 176, 8, 2, - 1, 211, 66, 186, 4, 230, 176, 8, 2, 1, 211, 66, 186, 4, 251, 250, 8, 2, - 1, 152, 196, 9, 4, 230, 176, 8, 2, 1, 152, 196, 9, 4, 251, 250, 8, 2, 1, - 205, 82, 4, 230, 176, 8, 2, 1, 205, 82, 4, 251, 250, 8, 2, 1, 228, 218, - 205, 82, 4, 230, 176, 8, 2, 1, 228, 218, 205, 82, 4, 251, 250, 9, 204, 2, - 99, 4, 230, 25, 95, 4, 251, 141, 9, 204, 2, 99, 4, 230, 25, 95, 4, 193, - 131, 9, 204, 2, 99, 4, 230, 25, 95, 4, 130, 217, 79, 9, 204, 2, 99, 4, - 230, 25, 95, 4, 211, 139, 9, 204, 2, 99, 4, 230, 25, 95, 4, 69, 9, 204, - 2, 99, 4, 230, 25, 95, 4, 191, 225, 9, 204, 2, 99, 4, 230, 25, 95, 4, 73, - 9, 204, 2, 99, 4, 230, 25, 95, 4, 251, 229, 9, 204, 2, 213, 12, 4, 221, - 235, 104, 204, 2, 39, 1, 208, 89, 104, 204, 2, 39, 1, 221, 169, 104, 204, - 2, 39, 1, 231, 29, 104, 204, 2, 39, 1, 191, 123, 104, 204, 2, 39, 1, 237, - 135, 104, 204, 2, 39, 1, 207, 1, 104, 204, 2, 39, 1, 233, 68, 104, 204, - 2, 39, 1, 191, 175, 248, 175, 204, 2, 39, 1, 206, 104, 248, 175, 204, 2, - 39, 1, 207, 1, 248, 175, 204, 2, 39, 1, 191, 175, 230, 111, 204, 2, 39, - 1, 219, 49, 230, 111, 204, 2, 39, 1, 203, 160, 230, 111, 204, 2, 39, 1, - 221, 169, 230, 111, 204, 2, 39, 1, 231, 29, 230, 111, 204, 2, 39, 1, 191, - 123, 230, 111, 204, 2, 39, 1, 233, 68, 211, 35, 204, 2, 39, 1, 206, 104, - 211, 35, 204, 2, 39, 1, 207, 1, 248, 175, 1, 221, 163, 44, 119, 222, 125, - 44, 119, 214, 56, 44, 119, 247, 145, 44, 119, 212, 90, 44, 119, 197, 131, - 44, 119, 213, 67, 44, 119, 200, 39, 44, 119, 215, 47, 44, 119, 210, 226, - 44, 119, 218, 147, 44, 119, 192, 159, 44, 119, 148, 44, 119, 170, 44, - 119, 196, 8, 44, 119, 219, 39, 44, 119, 219, 50, 44, 119, 206, 105, 44, - 119, 213, 49, 44, 119, 223, 7, 44, 119, 203, 162, 44, 119, 201, 173, 44, - 119, 206, 3, 44, 119, 230, 83, 44, 119, 220, 223, 44, 5, 222, 100, 44, 5, - 221, 142, 44, 5, 221, 121, 44, 5, 220, 208, 44, 5, 220, 163, 44, 5, 221, - 253, 44, 5, 221, 244, 44, 5, 222, 75, 44, 5, 221, 43, 44, 5, 221, 17, 44, - 5, 222, 16, 44, 5, 214, 53, 44, 5, 214, 2, 44, 5, 213, 254, 44, 5, 213, - 223, 44, 5, 213, 214, 44, 5, 214, 41, 44, 5, 214, 39, 44, 5, 214, 50, 44, - 5, 213, 235, 44, 5, 213, 230, 44, 5, 214, 43, 44, 5, 247, 111, 44, 5, - 242, 237, 44, 5, 242, 227, 44, 5, 238, 148, 44, 5, 238, 106, 44, 5, 246, - 250, 44, 5, 246, 242, 44, 5, 247, 100, 44, 5, 242, 51, 44, 5, 238, 227, - 44, 5, 247, 28, 44, 5, 212, 87, 44, 5, 212, 68, 44, 5, 212, 62, 44, 5, - 212, 45, 44, 5, 212, 37, 44, 5, 212, 77, 44, 5, 212, 76, 44, 5, 212, 84, - 44, 5, 212, 52, 44, 5, 212, 49, 44, 5, 212, 80, 44, 5, 197, 127, 44, 5, - 197, 107, 44, 5, 197, 106, 44, 5, 197, 95, 44, 5, 197, 92, 44, 5, 197, - 123, 44, 5, 197, 122, 44, 5, 197, 126, 44, 5, 197, 105, 44, 5, 197, 104, - 44, 5, 197, 125, 44, 5, 213, 65, 44, 5, 213, 51, 44, 5, 213, 50, 44, 5, - 213, 34, 44, 5, 213, 33, 44, 5, 213, 61, 44, 5, 213, 60, 44, 5, 213, 64, - 44, 5, 213, 36, 44, 5, 213, 35, 44, 5, 213, 63, 44, 5, 199, 240, 44, 5, - 198, 188, 44, 5, 198, 165, 44, 5, 197, 90, 44, 5, 197, 45, 44, 5, 199, - 140, 44, 5, 199, 116, 44, 5, 199, 212, 44, 5, 159, 44, 5, 198, 54, 44, 5, - 199, 161, 44, 5, 214, 236, 44, 5, 213, 205, 44, 5, 213, 172, 44, 5, 212, - 165, 44, 5, 212, 102, 44, 5, 214, 107, 44, 5, 214, 96, 44, 5, 214, 222, - 44, 5, 213, 30, 44, 5, 213, 13, 44, 5, 214, 191, 44, 5, 210, 210, 44, 5, - 209, 176, 44, 5, 209, 136, 44, 5, 208, 158, 44, 5, 208, 121, 44, 5, 210, - 53, 44, 5, 210, 40, 44, 5, 210, 188, 44, 5, 209, 65, 44, 5, 209, 30, 44, - 5, 210, 70, 44, 5, 217, 130, 44, 5, 216, 81, 44, 5, 216, 43, 44, 5, 215, - 139, 44, 5, 215, 79, 44, 5, 216, 213, 44, 5, 216, 192, 44, 5, 217, 91, - 44, 5, 215, 251, 44, 5, 215, 194, 44, 5, 217, 6, 44, 5, 192, 140, 44, 5, - 192, 33, 44, 5, 192, 23, 44, 5, 191, 225, 44, 5, 191, 188, 44, 5, 192, - 80, 44, 5, 192, 77, 44, 5, 192, 119, 44, 5, 192, 12, 44, 5, 191, 246, 44, - 5, 192, 91, 44, 5, 207, 173, 44, 5, 206, 252, 44, 5, 206, 190, 44, 5, - 206, 63, 44, 5, 206, 24, 44, 5, 207, 108, 44, 5, 207, 79, 44, 5, 207, - 151, 44, 5, 206, 157, 44, 5, 206, 129, 44, 5, 207, 120, 44, 5, 220, 101, - 44, 5, 219, 122, 44, 5, 219, 104, 44, 5, 218, 203, 44, 5, 218, 173, 44, - 5, 219, 214, 44, 5, 219, 204, 44, 5, 220, 72, 44, 5, 219, 19, 44, 5, 218, - 240, 44, 5, 219, 232, 44, 5, 195, 184, 44, 5, 195, 66, 44, 5, 195, 48, - 44, 5, 193, 246, 44, 5, 193, 238, 44, 5, 195, 150, 44, 5, 195, 145, 44, - 5, 195, 180, 44, 5, 195, 21, 44, 5, 195, 5, 44, 5, 195, 157, 44, 5, 219, - 37, 44, 5, 219, 32, 44, 5, 219, 31, 44, 5, 219, 28, 44, 5, 219, 27, 44, - 5, 219, 34, 44, 5, 219, 33, 44, 5, 219, 36, 44, 5, 219, 30, 44, 5, 219, - 29, 44, 5, 219, 35, 44, 5, 219, 48, 44, 5, 219, 41, 44, 5, 219, 40, 44, - 5, 219, 24, 44, 5, 219, 23, 44, 5, 219, 44, 44, 5, 219, 43, 44, 5, 219, - 47, 44, 5, 219, 26, 44, 5, 219, 25, 44, 5, 219, 45, 44, 5, 206, 103, 44, - 5, 206, 92, 44, 5, 206, 91, 44, 5, 206, 84, 44, 5, 206, 77, 44, 5, 206, - 99, 44, 5, 206, 98, 44, 5, 206, 102, 44, 5, 206, 90, 44, 5, 206, 89, 44, - 5, 206, 101, 44, 5, 213, 47, 44, 5, 213, 42, 44, 5, 213, 41, 44, 5, 213, - 38, 44, 5, 213, 37, 44, 5, 213, 44, 44, 5, 213, 43, 44, 5, 213, 46, 44, - 5, 213, 40, 44, 5, 213, 39, 44, 5, 213, 45, 44, 5, 223, 3, 44, 5, 222, - 217, 44, 5, 222, 209, 44, 5, 222, 155, 44, 5, 222, 135, 44, 5, 222, 238, - 44, 5, 222, 236, 44, 5, 222, 253, 44, 5, 222, 174, 44, 5, 222, 164, 44, - 5, 222, 245, 44, 5, 203, 155, 44, 5, 203, 76, 44, 5, 203, 71, 44, 5, 203, - 0, 44, 5, 202, 238, 44, 5, 203, 108, 44, 5, 203, 106, 44, 5, 203, 143, - 44, 5, 203, 51, 44, 5, 203, 43, 44, 5, 203, 117, 44, 5, 201, 169, 44, 5, - 201, 137, 44, 5, 201, 133, 44, 5, 201, 124, 44, 5, 201, 121, 44, 5, 201, - 143, 44, 5, 201, 142, 44, 5, 201, 168, 44, 5, 201, 129, 44, 5, 201, 128, - 44, 5, 201, 145, 44, 5, 205, 192, 44, 5, 202, 217, 44, 5, 202, 188, 44, - 5, 200, 255, 44, 5, 200, 156, 44, 5, 205, 63, 44, 5, 205, 45, 44, 5, 205, - 176, 44, 5, 202, 41, 44, 5, 202, 11, 44, 5, 205, 109, 44, 5, 230, 58, 44, - 5, 229, 126, 44, 5, 229, 98, 44, 5, 228, 128, 44, 5, 228, 97, 44, 5, 229, - 213, 44, 5, 229, 183, 44, 5, 230, 47, 44, 5, 228, 247, 44, 5, 228, 220, - 44, 5, 229, 225, 44, 5, 220, 222, 44, 5, 220, 221, 44, 5, 220, 216, 44, - 5, 220, 215, 44, 5, 220, 212, 44, 5, 220, 211, 44, 5, 220, 218, 44, 5, - 220, 217, 44, 5, 220, 220, 44, 5, 220, 214, 44, 5, 220, 213, 44, 5, 220, - 219, 44, 5, 203, 9, 165, 119, 3, 192, 105, 165, 119, 3, 207, 139, 165, - 119, 3, 207, 45, 100, 1, 196, 220, 94, 119, 3, 242, 43, 157, 94, 119, 3, - 242, 43, 221, 190, 94, 119, 3, 242, 43, 221, 43, 94, 119, 3, 242, 43, - 221, 159, 94, 119, 3, 242, 43, 213, 235, 94, 119, 3, 242, 43, 247, 112, - 94, 119, 3, 242, 43, 246, 209, 94, 119, 3, 242, 43, 242, 51, 94, 119, 3, - 242, 43, 243, 20, 94, 119, 3, 242, 43, 212, 52, 94, 119, 3, 242, 43, 237, - 241, 94, 119, 3, 242, 43, 197, 116, 94, 119, 3, 242, 43, 236, 129, 94, - 119, 3, 242, 43, 197, 111, 94, 119, 3, 242, 43, 180, 94, 119, 3, 242, 43, - 199, 247, 94, 119, 3, 242, 43, 199, 44, 94, 119, 3, 242, 43, 159, 94, - 119, 3, 242, 43, 198, 236, 94, 119, 3, 242, 43, 213, 30, 94, 119, 3, 242, - 43, 249, 103, 94, 119, 3, 242, 43, 209, 219, 94, 119, 3, 242, 43, 209, - 65, 94, 119, 3, 242, 43, 209, 190, 94, 119, 3, 242, 43, 215, 251, 94, - 119, 3, 242, 43, 192, 12, 94, 119, 3, 242, 43, 206, 157, 94, 119, 3, 242, - 43, 219, 19, 94, 119, 3, 242, 43, 195, 21, 94, 119, 3, 242, 43, 203, 160, - 94, 119, 3, 242, 43, 201, 170, 94, 119, 3, 242, 43, 189, 94, 119, 3, 242, - 43, 144, 94, 119, 3, 242, 43, 171, 94, 18, 3, 242, 43, 208, 89, 94, 223, - 121, 18, 3, 242, 43, 208, 27, 94, 223, 121, 18, 3, 242, 43, 206, 12, 94, - 223, 121, 18, 3, 242, 43, 206, 5, 94, 223, 121, 18, 3, 242, 43, 208, 69, - 94, 18, 3, 211, 102, 94, 18, 3, 252, 115, 229, 88, 1, 248, 133, 214, 54, - 229, 88, 1, 248, 133, 214, 2, 229, 88, 1, 248, 133, 213, 223, 229, 88, 1, - 248, 133, 214, 41, 229, 88, 1, 248, 133, 213, 235, 71, 1, 248, 133, 214, - 54, 71, 1, 248, 133, 214, 2, 71, 1, 248, 133, 213, 223, 71, 1, 248, 133, - 214, 41, 71, 1, 248, 133, 213, 235, 71, 1, 251, 176, 246, 250, 71, 1, - 251, 176, 197, 90, 71, 1, 251, 176, 159, 71, 1, 251, 176, 210, 226, 59, - 1, 233, 159, 233, 158, 238, 235, 163, 164, 59, 1, 233, 158, 233, 159, - 238, 235, 163, 164, + 13, 28, 43, 2, 65, 13, 28, 43, 2, 250, 120, 13, 28, 43, 2, 247, 193, 13, + 28, 43, 2, 238, 127, 13, 28, 43, 2, 71, 13, 28, 43, 2, 233, 175, 13, 28, + 43, 2, 232, 51, 13, 28, 43, 2, 230, 116, 13, 28, 43, 2, 68, 13, 28, 43, + 2, 223, 35, 13, 28, 43, 2, 222, 152, 13, 28, 43, 2, 172, 13, 28, 43, 2, + 218, 168, 13, 28, 43, 2, 215, 61, 13, 28, 43, 2, 74, 13, 28, 43, 2, 210, + 236, 13, 28, 43, 2, 208, 104, 13, 28, 43, 2, 146, 13, 28, 43, 2, 206, 8, + 13, 28, 43, 2, 200, 43, 13, 28, 43, 2, 66, 13, 28, 43, 2, 196, 12, 13, + 28, 43, 2, 193, 224, 13, 28, 43, 2, 192, 235, 13, 28, 43, 2, 192, 159, + 13, 28, 43, 2, 191, 166, 13, 27, 6, 65, 13, 27, 6, 247, 193, 13, 27, 6, + 238, 127, 13, 27, 6, 232, 51, 13, 27, 6, 223, 35, 13, 27, 6, 222, 152, + 13, 27, 6, 215, 61, 13, 27, 6, 74, 13, 27, 6, 210, 236, 13, 27, 6, 208, + 104, 13, 27, 6, 206, 8, 13, 27, 6, 200, 43, 13, 27, 6, 66, 13, 27, 6, + 196, 12, 13, 27, 6, 193, 224, 13, 27, 6, 192, 235, 13, 27, 6, 192, 159, + 13, 27, 6, 191, 166, 13, 27, 2, 65, 13, 27, 2, 250, 120, 13, 27, 2, 247, + 193, 13, 27, 2, 238, 127, 13, 27, 2, 233, 175, 13, 27, 2, 230, 116, 13, + 27, 2, 68, 13, 27, 2, 223, 35, 13, 27, 2, 222, 152, 13, 27, 2, 172, 13, + 27, 2, 218, 168, 13, 27, 2, 215, 61, 13, 27, 2, 210, 236, 13, 27, 2, 208, + 104, 13, 27, 2, 146, 13, 27, 2, 206, 8, 13, 27, 2, 200, 43, 13, 27, 2, + 66, 13, 27, 2, 196, 12, 13, 27, 2, 193, 224, 13, 27, 2, 192, 235, 13, 27, + 2, 192, 159, 13, 27, 2, 191, 166, 13, 28, 27, 6, 65, 13, 28, 27, 6, 250, + 120, 13, 28, 27, 6, 247, 193, 13, 28, 27, 6, 238, 127, 13, 28, 27, 6, 71, + 13, 28, 27, 6, 233, 175, 13, 28, 27, 6, 232, 51, 13, 28, 27, 6, 230, 116, + 13, 28, 27, 6, 68, 13, 28, 27, 6, 223, 35, 13, 28, 27, 6, 222, 152, 13, + 28, 27, 6, 172, 13, 28, 27, 6, 218, 168, 13, 28, 27, 6, 215, 61, 13, 28, + 27, 6, 74, 13, 28, 27, 6, 210, 236, 13, 28, 27, 6, 208, 104, 13, 28, 27, + 6, 146, 13, 28, 27, 6, 206, 8, 13, 28, 27, 6, 200, 43, 13, 28, 27, 6, 66, + 13, 28, 27, 6, 196, 12, 13, 28, 27, 6, 193, 224, 13, 28, 27, 6, 192, 235, + 13, 28, 27, 6, 192, 159, 13, 28, 27, 6, 191, 166, 13, 28, 27, 2, 65, 13, + 28, 27, 2, 250, 120, 13, 28, 27, 2, 247, 193, 13, 28, 27, 2, 238, 127, + 13, 28, 27, 2, 71, 13, 28, 27, 2, 233, 175, 13, 28, 27, 2, 232, 51, 13, + 28, 27, 2, 230, 116, 13, 28, 27, 2, 68, 13, 28, 27, 2, 223, 35, 13, 28, + 27, 2, 222, 152, 13, 28, 27, 2, 172, 13, 28, 27, 2, 218, 168, 13, 28, 27, + 2, 215, 61, 13, 28, 27, 2, 74, 13, 28, 27, 2, 210, 236, 13, 28, 27, 2, + 208, 104, 13, 28, 27, 2, 146, 13, 28, 27, 2, 206, 8, 13, 28, 27, 2, 200, + 43, 13, 28, 27, 2, 66, 13, 28, 27, 2, 196, 12, 13, 28, 27, 2, 193, 224, + 13, 28, 27, 2, 192, 235, 13, 28, 27, 2, 192, 159, 13, 28, 27, 2, 191, + 166, 13, 232, 115, 6, 65, 13, 232, 115, 6, 250, 120, 13, 232, 115, 6, + 238, 127, 13, 232, 115, 6, 71, 13, 232, 115, 6, 233, 175, 13, 232, 115, + 6, 232, 51, 13, 232, 115, 6, 223, 35, 13, 232, 115, 6, 222, 152, 13, 232, + 115, 6, 172, 13, 232, 115, 6, 218, 168, 13, 232, 115, 6, 215, 61, 13, + 232, 115, 6, 74, 13, 232, 115, 6, 210, 236, 13, 232, 115, 6, 208, 104, + 13, 232, 115, 6, 206, 8, 13, 232, 115, 6, 200, 43, 13, 232, 115, 6, 66, + 13, 232, 115, 6, 196, 12, 13, 232, 115, 6, 193, 224, 13, 232, 115, 6, + 192, 235, 13, 232, 115, 6, 192, 159, 13, 232, 115, 2, 65, 13, 232, 115, + 2, 250, 120, 13, 232, 115, 2, 247, 193, 13, 232, 115, 2, 238, 127, 13, + 232, 115, 2, 71, 13, 232, 115, 2, 233, 175, 13, 232, 115, 2, 232, 51, 13, + 232, 115, 2, 230, 116, 13, 232, 115, 2, 68, 13, 232, 115, 2, 223, 35, 13, + 232, 115, 2, 222, 152, 13, 232, 115, 2, 172, 13, 232, 115, 2, 218, 168, + 13, 232, 115, 2, 215, 61, 13, 232, 115, 2, 74, 13, 232, 115, 2, 210, 236, + 13, 232, 115, 2, 208, 104, 13, 232, 115, 2, 146, 13, 232, 115, 2, 206, 8, + 13, 232, 115, 2, 200, 43, 13, 232, 115, 2, 66, 13, 232, 115, 2, 196, 12, + 13, 232, 115, 2, 193, 224, 13, 232, 115, 2, 192, 235, 13, 232, 115, 2, + 192, 159, 13, 232, 115, 2, 191, 166, 13, 235, 129, 6, 65, 13, 235, 129, + 6, 250, 120, 13, 235, 129, 6, 238, 127, 13, 235, 129, 6, 71, 13, 235, + 129, 6, 233, 175, 13, 235, 129, 6, 232, 51, 13, 235, 129, 6, 68, 13, 235, + 129, 6, 223, 35, 13, 235, 129, 6, 222, 152, 13, 235, 129, 6, 172, 13, + 235, 129, 6, 218, 168, 13, 235, 129, 6, 74, 13, 235, 129, 6, 206, 8, 13, + 235, 129, 6, 200, 43, 13, 235, 129, 6, 66, 13, 235, 129, 6, 196, 12, 13, + 235, 129, 6, 193, 224, 13, 235, 129, 6, 192, 235, 13, 235, 129, 6, 192, + 159, 13, 235, 129, 2, 65, 13, 235, 129, 2, 250, 120, 13, 235, 129, 2, + 247, 193, 13, 235, 129, 2, 238, 127, 13, 235, 129, 2, 71, 13, 235, 129, + 2, 233, 175, 13, 235, 129, 2, 232, 51, 13, 235, 129, 2, 230, 116, 13, + 235, 129, 2, 68, 13, 235, 129, 2, 223, 35, 13, 235, 129, 2, 222, 152, 13, + 235, 129, 2, 172, 13, 235, 129, 2, 218, 168, 13, 235, 129, 2, 215, 61, + 13, 235, 129, 2, 74, 13, 235, 129, 2, 210, 236, 13, 235, 129, 2, 208, + 104, 13, 235, 129, 2, 146, 13, 235, 129, 2, 206, 8, 13, 235, 129, 2, 200, + 43, 13, 235, 129, 2, 66, 13, 235, 129, 2, 196, 12, 13, 235, 129, 2, 193, + 224, 13, 235, 129, 2, 192, 235, 13, 235, 129, 2, 192, 159, 13, 235, 129, + 2, 191, 166, 13, 28, 232, 115, 6, 65, 13, 28, 232, 115, 6, 250, 120, 13, + 28, 232, 115, 6, 247, 193, 13, 28, 232, 115, 6, 238, 127, 13, 28, 232, + 115, 6, 71, 13, 28, 232, 115, 6, 233, 175, 13, 28, 232, 115, 6, 232, 51, + 13, 28, 232, 115, 6, 230, 116, 13, 28, 232, 115, 6, 68, 13, 28, 232, 115, + 6, 223, 35, 13, 28, 232, 115, 6, 222, 152, 13, 28, 232, 115, 6, 172, 13, + 28, 232, 115, 6, 218, 168, 13, 28, 232, 115, 6, 215, 61, 13, 28, 232, + 115, 6, 74, 13, 28, 232, 115, 6, 210, 236, 13, 28, 232, 115, 6, 208, 104, + 13, 28, 232, 115, 6, 146, 13, 28, 232, 115, 6, 206, 8, 13, 28, 232, 115, + 6, 200, 43, 13, 28, 232, 115, 6, 66, 13, 28, 232, 115, 6, 196, 12, 13, + 28, 232, 115, 6, 193, 224, 13, 28, 232, 115, 6, 192, 235, 13, 28, 232, + 115, 6, 192, 159, 13, 28, 232, 115, 6, 191, 166, 13, 28, 232, 115, 2, 65, + 13, 28, 232, 115, 2, 250, 120, 13, 28, 232, 115, 2, 247, 193, 13, 28, + 232, 115, 2, 238, 127, 13, 28, 232, 115, 2, 71, 13, 28, 232, 115, 2, 233, + 175, 13, 28, 232, 115, 2, 232, 51, 13, 28, 232, 115, 2, 230, 116, 13, 28, + 232, 115, 2, 68, 13, 28, 232, 115, 2, 223, 35, 13, 28, 232, 115, 2, 222, + 152, 13, 28, 232, 115, 2, 172, 13, 28, 232, 115, 2, 218, 168, 13, 28, + 232, 115, 2, 215, 61, 13, 28, 232, 115, 2, 74, 13, 28, 232, 115, 2, 210, + 236, 13, 28, 232, 115, 2, 208, 104, 13, 28, 232, 115, 2, 146, 13, 28, + 232, 115, 2, 206, 8, 13, 28, 232, 115, 2, 200, 43, 13, 28, 232, 115, 2, + 66, 13, 28, 232, 115, 2, 196, 12, 13, 28, 232, 115, 2, 193, 224, 13, 28, + 232, 115, 2, 192, 235, 13, 28, 232, 115, 2, 192, 159, 13, 28, 232, 115, + 2, 191, 166, 13, 49, 6, 65, 13, 49, 6, 250, 120, 13, 49, 6, 247, 193, 13, + 49, 6, 238, 127, 13, 49, 6, 71, 13, 49, 6, 233, 175, 13, 49, 6, 232, 51, + 13, 49, 6, 230, 116, 13, 49, 6, 68, 13, 49, 6, 223, 35, 13, 49, 6, 222, + 152, 13, 49, 6, 172, 13, 49, 6, 218, 168, 13, 49, 6, 215, 61, 13, 49, 6, + 74, 13, 49, 6, 210, 236, 13, 49, 6, 208, 104, 13, 49, 6, 146, 13, 49, 6, + 206, 8, 13, 49, 6, 200, 43, 13, 49, 6, 66, 13, 49, 6, 196, 12, 13, 49, 6, + 193, 224, 13, 49, 6, 192, 235, 13, 49, 6, 192, 159, 13, 49, 6, 191, 166, + 13, 49, 2, 65, 13, 49, 2, 250, 120, 13, 49, 2, 247, 193, 13, 49, 2, 238, + 127, 13, 49, 2, 71, 13, 49, 2, 233, 175, 13, 49, 2, 232, 51, 13, 49, 2, + 230, 116, 13, 49, 2, 68, 13, 49, 2, 223, 35, 13, 49, 2, 222, 152, 13, 49, + 2, 172, 13, 49, 2, 218, 168, 13, 49, 2, 215, 61, 13, 49, 2, 74, 13, 49, + 2, 210, 236, 13, 49, 2, 208, 104, 13, 49, 2, 146, 13, 49, 2, 206, 8, 13, + 49, 2, 200, 43, 13, 49, 2, 66, 13, 49, 2, 196, 12, 13, 49, 2, 193, 224, + 13, 49, 2, 192, 235, 13, 49, 2, 192, 159, 13, 49, 2, 191, 166, 13, 49, + 28, 6, 65, 13, 49, 28, 6, 250, 120, 13, 49, 28, 6, 247, 193, 13, 49, 28, + 6, 238, 127, 13, 49, 28, 6, 71, 13, 49, 28, 6, 233, 175, 13, 49, 28, 6, + 232, 51, 13, 49, 28, 6, 230, 116, 13, 49, 28, 6, 68, 13, 49, 28, 6, 223, + 35, 13, 49, 28, 6, 222, 152, 13, 49, 28, 6, 172, 13, 49, 28, 6, 218, 168, + 13, 49, 28, 6, 215, 61, 13, 49, 28, 6, 74, 13, 49, 28, 6, 210, 236, 13, + 49, 28, 6, 208, 104, 13, 49, 28, 6, 146, 13, 49, 28, 6, 206, 8, 13, 49, + 28, 6, 200, 43, 13, 49, 28, 6, 66, 13, 49, 28, 6, 196, 12, 13, 49, 28, 6, + 193, 224, 13, 49, 28, 6, 192, 235, 13, 49, 28, 6, 192, 159, 13, 49, 28, + 6, 191, 166, 13, 49, 28, 2, 65, 13, 49, 28, 2, 250, 120, 13, 49, 28, 2, + 247, 193, 13, 49, 28, 2, 238, 127, 13, 49, 28, 2, 71, 13, 49, 28, 2, 233, + 175, 13, 49, 28, 2, 232, 51, 13, 49, 28, 2, 230, 116, 13, 49, 28, 2, 68, + 13, 49, 28, 2, 223, 35, 13, 49, 28, 2, 222, 152, 13, 49, 28, 2, 172, 13, + 49, 28, 2, 218, 168, 13, 49, 28, 2, 215, 61, 13, 49, 28, 2, 74, 13, 49, + 28, 2, 210, 236, 13, 49, 28, 2, 208, 104, 13, 49, 28, 2, 146, 13, 49, 28, + 2, 206, 8, 13, 49, 28, 2, 200, 43, 13, 49, 28, 2, 66, 13, 49, 28, 2, 196, + 12, 13, 49, 28, 2, 193, 224, 13, 49, 28, 2, 192, 235, 13, 49, 28, 2, 192, + 159, 13, 49, 28, 2, 191, 166, 13, 49, 43, 6, 65, 13, 49, 43, 6, 250, 120, + 13, 49, 43, 6, 247, 193, 13, 49, 43, 6, 238, 127, 13, 49, 43, 6, 71, 13, + 49, 43, 6, 233, 175, 13, 49, 43, 6, 232, 51, 13, 49, 43, 6, 230, 116, 13, + 49, 43, 6, 68, 13, 49, 43, 6, 223, 35, 13, 49, 43, 6, 222, 152, 13, 49, + 43, 6, 172, 13, 49, 43, 6, 218, 168, 13, 49, 43, 6, 215, 61, 13, 49, 43, + 6, 74, 13, 49, 43, 6, 210, 236, 13, 49, 43, 6, 208, 104, 13, 49, 43, 6, + 146, 13, 49, 43, 6, 206, 8, 13, 49, 43, 6, 200, 43, 13, 49, 43, 6, 66, + 13, 49, 43, 6, 196, 12, 13, 49, 43, 6, 193, 224, 13, 49, 43, 6, 192, 235, + 13, 49, 43, 6, 192, 159, 13, 49, 43, 6, 191, 166, 13, 49, 43, 2, 65, 13, + 49, 43, 2, 250, 120, 13, 49, 43, 2, 247, 193, 13, 49, 43, 2, 238, 127, + 13, 49, 43, 2, 71, 13, 49, 43, 2, 233, 175, 13, 49, 43, 2, 232, 51, 13, + 49, 43, 2, 230, 116, 13, 49, 43, 2, 68, 13, 49, 43, 2, 223, 35, 13, 49, + 43, 2, 222, 152, 13, 49, 43, 2, 172, 13, 49, 43, 2, 218, 168, 13, 49, 43, + 2, 215, 61, 13, 49, 43, 2, 74, 13, 49, 43, 2, 210, 236, 13, 49, 43, 2, + 208, 104, 13, 49, 43, 2, 146, 13, 49, 43, 2, 206, 8, 13, 49, 43, 2, 200, + 43, 13, 49, 43, 2, 66, 13, 49, 43, 2, 196, 12, 13, 49, 43, 2, 193, 224, + 13, 49, 43, 2, 192, 235, 13, 49, 43, 2, 192, 159, 13, 49, 43, 2, 191, + 166, 13, 49, 28, 43, 6, 65, 13, 49, 28, 43, 6, 250, 120, 13, 49, 28, 43, + 6, 247, 193, 13, 49, 28, 43, 6, 238, 127, 13, 49, 28, 43, 6, 71, 13, 49, + 28, 43, 6, 233, 175, 13, 49, 28, 43, 6, 232, 51, 13, 49, 28, 43, 6, 230, + 116, 13, 49, 28, 43, 6, 68, 13, 49, 28, 43, 6, 223, 35, 13, 49, 28, 43, + 6, 222, 152, 13, 49, 28, 43, 6, 172, 13, 49, 28, 43, 6, 218, 168, 13, 49, + 28, 43, 6, 215, 61, 13, 49, 28, 43, 6, 74, 13, 49, 28, 43, 6, 210, 236, + 13, 49, 28, 43, 6, 208, 104, 13, 49, 28, 43, 6, 146, 13, 49, 28, 43, 6, + 206, 8, 13, 49, 28, 43, 6, 200, 43, 13, 49, 28, 43, 6, 66, 13, 49, 28, + 43, 6, 196, 12, 13, 49, 28, 43, 6, 193, 224, 13, 49, 28, 43, 6, 192, 235, + 13, 49, 28, 43, 6, 192, 159, 13, 49, 28, 43, 6, 191, 166, 13, 49, 28, 43, + 2, 65, 13, 49, 28, 43, 2, 250, 120, 13, 49, 28, 43, 2, 247, 193, 13, 49, + 28, 43, 2, 238, 127, 13, 49, 28, 43, 2, 71, 13, 49, 28, 43, 2, 233, 175, + 13, 49, 28, 43, 2, 232, 51, 13, 49, 28, 43, 2, 230, 116, 13, 49, 28, 43, + 2, 68, 13, 49, 28, 43, 2, 223, 35, 13, 49, 28, 43, 2, 222, 152, 13, 49, + 28, 43, 2, 172, 13, 49, 28, 43, 2, 218, 168, 13, 49, 28, 43, 2, 215, 61, + 13, 49, 28, 43, 2, 74, 13, 49, 28, 43, 2, 210, 236, 13, 49, 28, 43, 2, + 208, 104, 13, 49, 28, 43, 2, 146, 13, 49, 28, 43, 2, 206, 8, 13, 49, 28, + 43, 2, 200, 43, 13, 49, 28, 43, 2, 66, 13, 49, 28, 43, 2, 196, 12, 13, + 49, 28, 43, 2, 193, 224, 13, 49, 28, 43, 2, 192, 235, 13, 49, 28, 43, 2, + 192, 159, 13, 49, 28, 43, 2, 191, 166, 13, 215, 217, 6, 65, 13, 215, 217, + 6, 250, 120, 13, 215, 217, 6, 247, 193, 13, 215, 217, 6, 238, 127, 13, + 215, 217, 6, 71, 13, 215, 217, 6, 233, 175, 13, 215, 217, 6, 232, 51, 13, + 215, 217, 6, 230, 116, 13, 215, 217, 6, 68, 13, 215, 217, 6, 223, 35, 13, + 215, 217, 6, 222, 152, 13, 215, 217, 6, 172, 13, 215, 217, 6, 218, 168, + 13, 215, 217, 6, 215, 61, 13, 215, 217, 6, 74, 13, 215, 217, 6, 210, 236, + 13, 215, 217, 6, 208, 104, 13, 215, 217, 6, 146, 13, 215, 217, 6, 206, 8, + 13, 215, 217, 6, 200, 43, 13, 215, 217, 6, 66, 13, 215, 217, 6, 196, 12, + 13, 215, 217, 6, 193, 224, 13, 215, 217, 6, 192, 235, 13, 215, 217, 6, + 192, 159, 13, 215, 217, 6, 191, 166, 13, 215, 217, 2, 65, 13, 215, 217, + 2, 250, 120, 13, 215, 217, 2, 247, 193, 13, 215, 217, 2, 238, 127, 13, + 215, 217, 2, 71, 13, 215, 217, 2, 233, 175, 13, 215, 217, 2, 232, 51, 13, + 215, 217, 2, 230, 116, 13, 215, 217, 2, 68, 13, 215, 217, 2, 223, 35, 13, + 215, 217, 2, 222, 152, 13, 215, 217, 2, 172, 13, 215, 217, 2, 218, 168, + 13, 215, 217, 2, 215, 61, 13, 215, 217, 2, 74, 13, 215, 217, 2, 210, 236, + 13, 215, 217, 2, 208, 104, 13, 215, 217, 2, 146, 13, 215, 217, 2, 206, 8, + 13, 215, 217, 2, 200, 43, 13, 215, 217, 2, 66, 13, 215, 217, 2, 196, 12, + 13, 215, 217, 2, 193, 224, 13, 215, 217, 2, 192, 235, 13, 215, 217, 2, + 192, 159, 13, 215, 217, 2, 191, 166, 13, 43, 2, 236, 139, 68, 13, 43, 2, + 236, 139, 223, 35, 13, 28, 6, 251, 160, 13, 28, 6, 248, 212, 13, 28, 6, + 231, 211, 13, 28, 6, 237, 106, 13, 28, 6, 234, 47, 13, 28, 6, 191, 76, + 13, 28, 6, 233, 253, 13, 28, 6, 199, 15, 13, 28, 6, 223, 83, 13, 28, 6, + 222, 72, 13, 28, 6, 220, 31, 13, 28, 6, 215, 155, 13, 28, 6, 212, 178, + 13, 28, 6, 192, 207, 13, 28, 6, 211, 107, 13, 28, 6, 209, 185, 13, 28, 6, + 207, 3, 13, 28, 6, 199, 16, 113, 13, 28, 6, 202, 196, 13, 28, 6, 199, + 166, 13, 28, 6, 196, 70, 13, 28, 6, 209, 211, 13, 28, 6, 243, 95, 13, 28, + 6, 208, 176, 13, 28, 6, 211, 110, 13, 28, 214, 245, 13, 28, 2, 251, 160, + 13, 28, 2, 248, 212, 13, 28, 2, 231, 211, 13, 28, 2, 237, 106, 13, 28, 2, + 234, 47, 13, 28, 2, 191, 76, 13, 28, 2, 233, 253, 13, 28, 2, 199, 15, 13, + 28, 2, 223, 83, 13, 28, 2, 222, 72, 13, 28, 2, 220, 31, 13, 28, 2, 215, + 155, 13, 28, 2, 212, 178, 13, 28, 2, 192, 207, 13, 28, 2, 211, 107, 13, + 28, 2, 209, 185, 13, 28, 2, 207, 3, 13, 28, 2, 53, 202, 196, 13, 28, 2, + 202, 196, 13, 28, 2, 199, 166, 13, 28, 2, 196, 70, 13, 28, 2, 209, 211, + 13, 28, 2, 243, 95, 13, 28, 2, 208, 176, 13, 28, 2, 211, 110, 13, 28, + 210, 105, 237, 16, 13, 28, 234, 48, 113, 13, 28, 199, 16, 113, 13, 28, + 222, 73, 113, 13, 28, 209, 212, 113, 13, 28, 207, 4, 113, 13, 28, 209, + 186, 113, 13, 43, 6, 251, 160, 13, 43, 6, 248, 212, 13, 43, 6, 231, 211, + 13, 43, 6, 237, 106, 13, 43, 6, 234, 47, 13, 43, 6, 191, 76, 13, 43, 6, + 233, 253, 13, 43, 6, 199, 15, 13, 43, 6, 223, 83, 13, 43, 6, 222, 72, 13, + 43, 6, 220, 31, 13, 43, 6, 215, 155, 13, 43, 6, 212, 178, 13, 43, 6, 192, + 207, 13, 43, 6, 211, 107, 13, 43, 6, 209, 185, 13, 43, 6, 207, 3, 13, 43, + 6, 199, 16, 113, 13, 43, 6, 202, 196, 13, 43, 6, 199, 166, 13, 43, 6, + 196, 70, 13, 43, 6, 209, 211, 13, 43, 6, 243, 95, 13, 43, 6, 208, 176, + 13, 43, 6, 211, 110, 13, 43, 214, 245, 13, 43, 2, 251, 160, 13, 43, 2, + 248, 212, 13, 43, 2, 231, 211, 13, 43, 2, 237, 106, 13, 43, 2, 234, 47, + 13, 43, 2, 191, 76, 13, 43, 2, 233, 253, 13, 43, 2, 199, 15, 13, 43, 2, + 223, 83, 13, 43, 2, 222, 72, 13, 43, 2, 220, 31, 13, 43, 2, 215, 155, 13, + 43, 2, 212, 178, 13, 43, 2, 192, 207, 13, 43, 2, 211, 107, 13, 43, 2, + 209, 185, 13, 43, 2, 207, 3, 13, 43, 2, 53, 202, 196, 13, 43, 2, 202, + 196, 13, 43, 2, 199, 166, 13, 43, 2, 196, 70, 13, 43, 2, 209, 211, 13, + 43, 2, 243, 95, 13, 43, 2, 208, 176, 13, 43, 2, 211, 110, 13, 43, 210, + 105, 237, 16, 13, 43, 234, 48, 113, 13, 43, 199, 16, 113, 13, 43, 222, + 73, 113, 13, 43, 209, 212, 113, 13, 43, 207, 4, 113, 13, 43, 209, 186, + 113, 13, 28, 43, 6, 251, 160, 13, 28, 43, 6, 248, 212, 13, 28, 43, 6, + 231, 211, 13, 28, 43, 6, 237, 106, 13, 28, 43, 6, 234, 47, 13, 28, 43, 6, + 191, 76, 13, 28, 43, 6, 233, 253, 13, 28, 43, 6, 199, 15, 13, 28, 43, 6, + 223, 83, 13, 28, 43, 6, 222, 72, 13, 28, 43, 6, 220, 31, 13, 28, 43, 6, + 215, 155, 13, 28, 43, 6, 212, 178, 13, 28, 43, 6, 192, 207, 13, 28, 43, + 6, 211, 107, 13, 28, 43, 6, 209, 185, 13, 28, 43, 6, 207, 3, 13, 28, 43, + 6, 199, 16, 113, 13, 28, 43, 6, 202, 196, 13, 28, 43, 6, 199, 166, 13, + 28, 43, 6, 196, 70, 13, 28, 43, 6, 209, 211, 13, 28, 43, 6, 243, 95, 13, + 28, 43, 6, 208, 176, 13, 28, 43, 6, 211, 110, 13, 28, 43, 214, 245, 13, + 28, 43, 2, 251, 160, 13, 28, 43, 2, 248, 212, 13, 28, 43, 2, 231, 211, + 13, 28, 43, 2, 237, 106, 13, 28, 43, 2, 234, 47, 13, 28, 43, 2, 191, 76, + 13, 28, 43, 2, 233, 253, 13, 28, 43, 2, 199, 15, 13, 28, 43, 2, 223, 83, + 13, 28, 43, 2, 222, 72, 13, 28, 43, 2, 220, 31, 13, 28, 43, 2, 215, 155, + 13, 28, 43, 2, 212, 178, 13, 28, 43, 2, 192, 207, 13, 28, 43, 2, 211, + 107, 13, 28, 43, 2, 209, 185, 13, 28, 43, 2, 207, 3, 13, 28, 43, 2, 53, + 202, 196, 13, 28, 43, 2, 202, 196, 13, 28, 43, 2, 199, 166, 13, 28, 43, + 2, 196, 70, 13, 28, 43, 2, 209, 211, 13, 28, 43, 2, 243, 95, 13, 28, 43, + 2, 208, 176, 13, 28, 43, 2, 211, 110, 13, 28, 43, 210, 105, 237, 16, 13, + 28, 43, 234, 48, 113, 13, 28, 43, 199, 16, 113, 13, 28, 43, 222, 73, 113, + 13, 28, 43, 209, 212, 113, 13, 28, 43, 207, 4, 113, 13, 28, 43, 209, 186, + 113, 13, 49, 28, 6, 251, 160, 13, 49, 28, 6, 248, 212, 13, 49, 28, 6, + 231, 211, 13, 49, 28, 6, 237, 106, 13, 49, 28, 6, 234, 47, 13, 49, 28, 6, + 191, 76, 13, 49, 28, 6, 233, 253, 13, 49, 28, 6, 199, 15, 13, 49, 28, 6, + 223, 83, 13, 49, 28, 6, 222, 72, 13, 49, 28, 6, 220, 31, 13, 49, 28, 6, + 215, 155, 13, 49, 28, 6, 212, 178, 13, 49, 28, 6, 192, 207, 13, 49, 28, + 6, 211, 107, 13, 49, 28, 6, 209, 185, 13, 49, 28, 6, 207, 3, 13, 49, 28, + 6, 199, 16, 113, 13, 49, 28, 6, 202, 196, 13, 49, 28, 6, 199, 166, 13, + 49, 28, 6, 196, 70, 13, 49, 28, 6, 209, 211, 13, 49, 28, 6, 243, 95, 13, + 49, 28, 6, 208, 176, 13, 49, 28, 6, 211, 110, 13, 49, 28, 214, 245, 13, + 49, 28, 2, 251, 160, 13, 49, 28, 2, 248, 212, 13, 49, 28, 2, 231, 211, + 13, 49, 28, 2, 237, 106, 13, 49, 28, 2, 234, 47, 13, 49, 28, 2, 191, 76, + 13, 49, 28, 2, 233, 253, 13, 49, 28, 2, 199, 15, 13, 49, 28, 2, 223, 83, + 13, 49, 28, 2, 222, 72, 13, 49, 28, 2, 220, 31, 13, 49, 28, 2, 215, 155, + 13, 49, 28, 2, 212, 178, 13, 49, 28, 2, 192, 207, 13, 49, 28, 2, 211, + 107, 13, 49, 28, 2, 209, 185, 13, 49, 28, 2, 207, 3, 13, 49, 28, 2, 53, + 202, 196, 13, 49, 28, 2, 202, 196, 13, 49, 28, 2, 199, 166, 13, 49, 28, + 2, 196, 70, 13, 49, 28, 2, 209, 211, 13, 49, 28, 2, 243, 95, 13, 49, 28, + 2, 208, 176, 13, 49, 28, 2, 211, 110, 13, 49, 28, 210, 105, 237, 16, 13, + 49, 28, 234, 48, 113, 13, 49, 28, 199, 16, 113, 13, 49, 28, 222, 73, 113, + 13, 49, 28, 209, 212, 113, 13, 49, 28, 207, 4, 113, 13, 49, 28, 209, 186, + 113, 13, 49, 28, 43, 6, 251, 160, 13, 49, 28, 43, 6, 248, 212, 13, 49, + 28, 43, 6, 231, 211, 13, 49, 28, 43, 6, 237, 106, 13, 49, 28, 43, 6, 234, + 47, 13, 49, 28, 43, 6, 191, 76, 13, 49, 28, 43, 6, 233, 253, 13, 49, 28, + 43, 6, 199, 15, 13, 49, 28, 43, 6, 223, 83, 13, 49, 28, 43, 6, 222, 72, + 13, 49, 28, 43, 6, 220, 31, 13, 49, 28, 43, 6, 215, 155, 13, 49, 28, 43, + 6, 212, 178, 13, 49, 28, 43, 6, 192, 207, 13, 49, 28, 43, 6, 211, 107, + 13, 49, 28, 43, 6, 209, 185, 13, 49, 28, 43, 6, 207, 3, 13, 49, 28, 43, + 6, 199, 16, 113, 13, 49, 28, 43, 6, 202, 196, 13, 49, 28, 43, 6, 199, + 166, 13, 49, 28, 43, 6, 196, 70, 13, 49, 28, 43, 6, 209, 211, 13, 49, 28, + 43, 6, 243, 95, 13, 49, 28, 43, 6, 208, 176, 13, 49, 28, 43, 6, 211, 110, + 13, 49, 28, 43, 214, 245, 13, 49, 28, 43, 2, 251, 160, 13, 49, 28, 43, 2, + 248, 212, 13, 49, 28, 43, 2, 231, 211, 13, 49, 28, 43, 2, 237, 106, 13, + 49, 28, 43, 2, 234, 47, 13, 49, 28, 43, 2, 191, 76, 13, 49, 28, 43, 2, + 233, 253, 13, 49, 28, 43, 2, 199, 15, 13, 49, 28, 43, 2, 223, 83, 13, 49, + 28, 43, 2, 222, 72, 13, 49, 28, 43, 2, 220, 31, 13, 49, 28, 43, 2, 215, + 155, 13, 49, 28, 43, 2, 212, 178, 13, 49, 28, 43, 2, 192, 207, 13, 49, + 28, 43, 2, 211, 107, 13, 49, 28, 43, 2, 209, 185, 13, 49, 28, 43, 2, 207, + 3, 13, 49, 28, 43, 2, 53, 202, 196, 13, 49, 28, 43, 2, 202, 196, 13, 49, + 28, 43, 2, 199, 166, 13, 49, 28, 43, 2, 196, 70, 13, 49, 28, 43, 2, 209, + 211, 13, 49, 28, 43, 2, 243, 95, 13, 49, 28, 43, 2, 208, 176, 13, 49, 28, + 43, 2, 211, 110, 13, 49, 28, 43, 210, 105, 237, 16, 13, 49, 28, 43, 234, + 48, 113, 13, 49, 28, 43, 199, 16, 113, 13, 49, 28, 43, 222, 73, 113, 13, + 49, 28, 43, 209, 212, 113, 13, 49, 28, 43, 207, 4, 113, 13, 49, 28, 43, + 209, 186, 113, 13, 28, 6, 237, 10, 13, 28, 2, 237, 10, 13, 28, 17, 191, + 77, 13, 28, 17, 107, 13, 28, 17, 109, 13, 28, 17, 138, 13, 28, 17, 134, + 13, 28, 17, 149, 13, 28, 17, 169, 13, 28, 17, 175, 13, 28, 17, 171, 13, + 28, 17, 178, 13, 235, 129, 17, 191, 77, 13, 235, 129, 17, 107, 13, 235, + 129, 17, 109, 13, 235, 129, 17, 138, 13, 235, 129, 17, 134, 13, 235, 129, + 17, 149, 13, 235, 129, 17, 169, 13, 235, 129, 17, 175, 13, 235, 129, 17, + 171, 13, 235, 129, 17, 178, 13, 49, 17, 191, 77, 13, 49, 17, 107, 13, 49, + 17, 109, 13, 49, 17, 138, 13, 49, 17, 134, 13, 49, 17, 149, 13, 49, 17, + 169, 13, 49, 17, 175, 13, 49, 17, 171, 13, 49, 17, 178, 13, 49, 28, 17, + 191, 77, 13, 49, 28, 17, 107, 13, 49, 28, 17, 109, 13, 49, 28, 17, 138, + 13, 49, 28, 17, 134, 13, 49, 28, 17, 149, 13, 49, 28, 17, 169, 13, 49, + 28, 17, 175, 13, 49, 28, 17, 171, 13, 49, 28, 17, 178, 13, 215, 217, 17, + 191, 77, 13, 215, 217, 17, 107, 13, 215, 217, 17, 109, 13, 215, 217, 17, + 138, 13, 215, 217, 17, 134, 13, 215, 217, 17, 149, 13, 215, 217, 17, 169, + 13, 215, 217, 17, 175, 13, 215, 217, 17, 171, 13, 215, 217, 17, 178, 24, + 151, 223, 148, 24, 230, 50, 223, 148, 24, 230, 46, 223, 148, 24, 230, 35, + 223, 148, 24, 230, 39, 223, 148, 24, 230, 52, 223, 148, 24, 151, 141, + 248, 223, 24, 230, 50, 141, 248, 223, 24, 151, 176, 196, 105, 141, 248, + 223, 24, 151, 141, 207, 147, 221, 70, 24, 151, 141, 238, 177, 24, 151, + 141, 229, 124, 24, 151, 141, 229, 125, 218, 241, 24, 230, 50, 141, 229, + 126, 24, 151, 141, 216, 84, 24, 230, 50, 141, 216, 84, 24, 151, 141, 82, + 248, 223, 24, 151, 141, 82, 207, 147, 221, 69, 24, 151, 141, 82, 229, + 124, 24, 151, 141, 133, 82, 229, 124, 24, 151, 141, 229, 125, 82, 196, + 77, 24, 151, 141, 82, 239, 46, 24, 151, 141, 82, 239, 47, 141, 248, 223, + 24, 151, 141, 82, 239, 47, 82, 248, 223, 24, 151, 141, 82, 239, 47, 238, + 177, 24, 151, 141, 82, 239, 47, 229, 124, 24, 151, 141, 82, 238, 213, 24, + 230, 50, 141, 82, 238, 213, 24, 151, 82, 248, 224, 139, 223, 148, 24, + 151, 141, 248, 224, 139, 216, 84, 24, 151, 141, 82, 198, 212, 24, 230, + 50, 141, 82, 198, 212, 24, 151, 141, 82, 201, 53, 176, 248, 223, 24, 151, + 141, 82, 248, 224, 176, 201, 52, 24, 151, 141, 82, 176, 248, 223, 24, + 151, 141, 82, 229, 125, 201, 199, 176, 202, 207, 24, 151, 141, 133, 82, + 229, 125, 176, 202, 207, 24, 151, 141, 133, 82, 229, 125, 176, 239, 46, + 24, 151, 141, 229, 125, 82, 133, 176, 202, 207, 24, 151, 141, 82, 133, + 201, 199, 176, 232, 132, 24, 151, 141, 82, 176, 238, 177, 24, 151, 141, + 82, 176, 243, 9, 24, 151, 141, 82, 176, 228, 249, 24, 151, 141, 82, 176, + 229, 124, 24, 151, 176, 248, 210, 141, 82, 201, 52, 24, 151, 141, 82, + 239, 47, 176, 202, 207, 24, 151, 141, 82, 239, 47, 176, 202, 208, 239, + 46, 24, 151, 141, 82, 239, 47, 176, 202, 208, 248, 223, 24, 151, 82, 176, + 228, 250, 141, 196, 77, 24, 151, 141, 176, 228, 250, 82, 196, 77, 24, + 151, 141, 82, 239, 47, 229, 125, 176, 202, 207, 24, 151, 141, 82, 238, + 214, 176, 202, 207, 24, 151, 141, 82, 239, 47, 176, 232, 132, 24, 151, + 141, 82, 239, 47, 238, 178, 176, 232, 132, 24, 151, 82, 176, 238, 178, + 141, 196, 77, 24, 151, 141, 176, 238, 178, 82, 196, 77, 24, 151, 82, 176, + 47, 141, 196, 77, 24, 151, 82, 176, 47, 141, 229, 124, 24, 151, 141, 176, + 251, 114, 211, 15, 82, 196, 77, 24, 151, 141, 176, 251, 114, 223, 163, + 82, 196, 77, 24, 151, 141, 176, 47, 82, 196, 77, 24, 151, 141, 82, 176, + 239, 47, 229, 124, 24, 151, 141, 82, 176, 251, 114, 211, 14, 24, 151, + 141, 82, 176, 251, 113, 24, 151, 82, 176, 251, 114, 211, 15, 141, 196, + 77, 24, 151, 82, 176, 251, 114, 211, 15, 141, 238, 213, 24, 151, 82, 176, + 251, 114, 141, 196, 77, 24, 151, 141, 176, 228, 250, 82, 229, 124, 24, + 230, 41, 232, 128, 232, 247, 24, 230, 41, 232, 128, 232, 248, 248, 223, + 24, 230, 41, 232, 128, 232, 248, 229, 124, 24, 230, 41, 232, 128, 232, + 248, 239, 46, 24, 230, 41, 232, 128, 232, 248, 239, 47, 201, 209, 24, + 230, 48, 232, 128, 232, 248, 239, 46, 24, 151, 232, 128, 232, 248, 239, + 47, 248, 223, 24, 230, 39, 232, 128, 232, 248, 239, 46, 24, 230, 41, 232, + 226, 232, 248, 201, 198, 24, 230, 41, 229, 213, 232, 226, 232, 248, 201, + 198, 24, 230, 41, 232, 226, 232, 248, 201, 199, 232, 128, 248, 223, 24, + 230, 41, 229, 213, 232, 226, 232, 248, 201, 199, 232, 128, 248, 223, 24, + 230, 41, 232, 226, 232, 248, 201, 199, 248, 223, 24, 230, 41, 229, 213, + 232, 226, 232, 248, 201, 199, 248, 223, 24, 230, 41, 232, 226, 232, 248, + 201, 199, 176, 232, 132, 24, 230, 46, 232, 226, 232, 248, 201, 198, 24, + 230, 46, 232, 226, 232, 248, 201, 199, 211, 76, 24, 230, 39, 232, 226, + 232, 248, 201, 199, 211, 76, 24, 230, 35, 232, 226, 232, 248, 201, 198, + 24, 230, 41, 232, 226, 232, 248, 201, 199, 229, 124, 24, 230, 41, 232, + 226, 232, 248, 201, 199, 229, 125, 176, 202, 207, 24, 230, 41, 232, 226, + 232, 248, 201, 199, 229, 125, 213, 44, 198, 212, 24, 230, 40, 24, 230, + 41, 248, 210, 210, 183, 233, 95, 24, 230, 41, 229, 212, 24, 230, 41, 176, + 202, 207, 24, 230, 41, 229, 213, 176, 202, 207, 24, 230, 41, 176, 248, + 223, 24, 230, 41, 176, 232, 132, 24, 230, 41, 201, 210, 141, 176, 202, + 207, 24, 230, 41, 201, 210, 247, 21, 24, 230, 41, 201, 210, 247, 22, 176, + 202, 207, 24, 230, 41, 201, 210, 247, 22, 176, 202, 208, 248, 223, 24, + 230, 41, 201, 210, 219, 82, 24, 230, 47, 24, 230, 48, 176, 202, 207, 24, + 230, 48, 213, 44, 198, 212, 24, 230, 48, 176, 232, 132, 24, 230, 37, 238, + 173, 24, 230, 36, 24, 230, 46, 211, 76, 24, 230, 45, 24, 230, 46, 211, + 77, 176, 202, 207, 24, 230, 46, 176, 202, 207, 24, 230, 46, 211, 77, 213, + 44, 198, 212, 24, 230, 46, 213, 44, 198, 212, 24, 230, 46, 211, 77, 176, + 232, 132, 24, 230, 46, 176, 232, 132, 24, 230, 44, 211, 76, 24, 230, 43, + 24, 230, 49, 24, 230, 34, 24, 230, 35, 176, 202, 207, 24, 230, 35, 213, + 44, 198, 212, 24, 230, 35, 176, 232, 132, 24, 230, 39, 211, 76, 24, 230, + 39, 211, 77, 176, 232, 132, 24, 230, 38, 24, 230, 39, 202, 70, 24, 230, + 39, 211, 77, 176, 202, 207, 24, 230, 39, 176, 202, 207, 24, 230, 39, 211, + 77, 213, 44, 198, 212, 24, 230, 39, 213, 44, 198, 212, 24, 230, 39, 176, + 202, 208, 198, 35, 223, 148, 24, 230, 39, 176, 248, 210, 82, 206, 188, + 24, 230, 51, 24, 151, 141, 82, 206, 188, 24, 230, 50, 141, 82, 206, 188, + 24, 230, 39, 141, 82, 206, 188, 24, 230, 52, 141, 82, 206, 188, 24, 230, + 39, 219, 82, 24, 151, 141, 82, 206, 189, 248, 223, 24, 151, 141, 82, 206, + 189, 239, 46, 24, 230, 39, 141, 82, 206, 189, 239, 46, 24, 151, 219, 83, + 235, 123, 24, 151, 219, 83, 144, 206, 183, 201, 52, 24, 151, 219, 83, + 144, 206, 183, 238, 162, 24, 151, 219, 83, 144, 211, 26, 243, 9, 24, 151, + 219, 83, 196, 77, 24, 151, 176, 196, 105, 219, 83, 196, 77, 24, 230, 50, + 219, 83, 196, 77, 24, 230, 35, 219, 83, 196, 77, 24, 230, 52, 219, 83, + 196, 77, 24, 151, 219, 83, 207, 147, 221, 70, 24, 151, 219, 83, 248, 223, + 24, 151, 219, 83, 198, 36, 198, 212, 24, 151, 219, 83, 198, 212, 24, 230, + 39, 219, 83, 198, 212, 24, 151, 219, 83, 141, 198, 212, 24, 230, 39, 219, + 83, 141, 198, 212, 24, 230, 52, 219, 83, 141, 176, 141, 176, 211, 14, 24, + 230, 52, 219, 83, 141, 176, 141, 198, 212, 24, 151, 219, 83, 223, 148, + 24, 230, 50, 219, 83, 223, 148, 24, 230, 39, 219, 83, 223, 148, 24, 230, + 52, 219, 83, 223, 148, 24, 151, 141, 82, 219, 82, 24, 230, 50, 141, 82, + 219, 82, 24, 230, 39, 141, 82, 219, 82, 24, 230, 39, 206, 188, 24, 230, + 52, 141, 82, 219, 82, 24, 151, 141, 82, 238, 218, 219, 82, 24, 230, 50, + 141, 82, 238, 218, 219, 82, 24, 151, 206, 189, 235, 123, 24, 230, 39, + 206, 189, 144, 141, 176, 228, 251, 216, 84, 24, 230, 52, 206, 189, 144, + 82, 176, 141, 238, 217, 24, 151, 206, 189, 196, 77, 24, 151, 206, 189, + 207, 147, 221, 70, 24, 151, 206, 189, 219, 82, 24, 230, 50, 206, 189, + 219, 82, 24, 230, 35, 206, 189, 219, 82, 24, 230, 52, 206, 189, 219, 82, + 24, 151, 206, 189, 216, 84, 24, 151, 206, 189, 82, 239, 46, 24, 151, 206, + 189, 82, 207, 147, 221, 69, 24, 151, 206, 189, 223, 148, 24, 151, 206, + 189, 198, 212, 24, 230, 37, 206, 189, 198, 212, 24, 151, 141, 206, 189, + 219, 82, 24, 230, 50, 141, 206, 189, 219, 82, 24, 230, 44, 141, 206, 189, + 219, 83, 211, 104, 24, 230, 37, 141, 206, 189, 219, 83, 211, 14, 24, 230, + 37, 141, 206, 189, 219, 83, 223, 162, 24, 230, 37, 141, 206, 189, 219, + 83, 196, 104, 24, 230, 46, 141, 206, 189, 219, 82, 24, 230, 39, 141, 206, + 189, 219, 82, 24, 230, 52, 141, 206, 189, 219, 83, 211, 14, 24, 230, 52, + 141, 206, 189, 219, 82, 24, 151, 82, 235, 123, 24, 230, 39, 216, 84, 24, + 151, 82, 196, 77, 24, 230, 50, 82, 196, 77, 24, 151, 82, 207, 147, 221, + 70, 24, 151, 82, 133, 176, 202, 207, 24, 230, 37, 82, 198, 212, 24, 151, + 82, 176, 219, 82, 24, 151, 82, 219, 82, 24, 151, 82, 206, 189, 219, 82, + 24, 230, 50, 82, 206, 189, 219, 82, 24, 230, 44, 82, 206, 189, 219, 83, + 211, 104, 24, 230, 46, 82, 206, 189, 219, 82, 24, 230, 39, 82, 206, 189, + 219, 82, 24, 230, 52, 82, 206, 189, 219, 83, 211, 14, 24, 230, 52, 82, + 206, 189, 219, 83, 223, 162, 24, 230, 52, 82, 206, 189, 219, 82, 24, 230, + 50, 82, 206, 189, 219, 83, 248, 223, 24, 230, 48, 82, 206, 189, 219, 83, + 239, 46, 24, 230, 48, 82, 206, 189, 219, 83, 239, 47, 202, 207, 24, 230, + 37, 82, 206, 189, 219, 83, 239, 47, 211, 14, 24, 230, 37, 82, 206, 189, + 219, 83, 239, 47, 223, 162, 24, 230, 37, 82, 206, 189, 219, 83, 239, 46, + 24, 230, 39, 141, 229, 124, 24, 151, 141, 176, 202, 207, 24, 230, 39, + 141, 176, 202, 207, 24, 151, 141, 176, 202, 208, 176, 237, 38, 24, 151, + 141, 176, 202, 208, 176, 239, 46, 24, 151, 141, 176, 202, 208, 176, 248, + 223, 24, 151, 141, 176, 202, 208, 141, 248, 223, 24, 151, 141, 176, 202, + 208, 248, 80, 248, 223, 24, 151, 141, 176, 202, 208, 141, 229, 126, 24, + 151, 141, 176, 232, 133, 141, 201, 52, 24, 151, 141, 176, 232, 133, 141, + 248, 223, 24, 151, 141, 176, 102, 24, 151, 141, 176, 238, 173, 24, 151, + 141, 176, 238, 165, 176, 223, 117, 24, 230, 48, 141, 176, 238, 165, 176, + 223, 117, 24, 151, 141, 176, 238, 165, 176, 196, 104, 24, 151, 141, 176, + 243, 10, 24, 230, 46, 141, 198, 212, 24, 230, 46, 141, 176, 211, 76, 24, + 230, 39, 141, 176, 211, 76, 24, 230, 39, 141, 176, 220, 12, 24, 230, 39, + 141, 198, 212, 24, 230, 39, 141, 176, 202, 70, 24, 230, 52, 141, 176, + 211, 14, 24, 230, 52, 141, 176, 223, 162, 24, 230, 52, 141, 198, 212, 24, + 151, 198, 212, 24, 151, 176, 229, 212, 24, 151, 176, 202, 208, 237, 38, + 24, 151, 176, 202, 208, 239, 46, 24, 151, 176, 202, 208, 248, 223, 24, + 151, 176, 232, 132, 24, 151, 176, 248, 210, 141, 216, 84, 24, 151, 176, + 248, 210, 82, 206, 188, 24, 151, 176, 248, 210, 206, 189, 219, 82, 24, + 151, 176, 196, 105, 105, 232, 247, 24, 151, 176, 139, 105, 232, 247, 24, + 151, 176, 196, 105, 115, 232, 247, 24, 151, 176, 196, 105, 232, 128, 232, + 247, 24, 151, 176, 139, 232, 128, 207, 147, 221, 69, 24, 230, 42, 24, + 151, 229, 212, 24, 198, 37, 202, 169, 24, 198, 37, 215, 128, 24, 198, 37, + 248, 209, 24, 230, 215, 202, 169, 24, 230, 215, 215, 128, 24, 230, 215, + 248, 209, 24, 201, 33, 202, 169, 24, 201, 33, 215, 128, 24, 201, 33, 248, + 209, 24, 248, 18, 202, 169, 24, 248, 18, 215, 128, 24, 248, 18, 248, 209, + 24, 206, 60, 202, 169, 24, 206, 60, 215, 128, 24, 206, 60, 248, 209, 24, + 200, 171, 200, 76, 24, 200, 171, 248, 209, 24, 201, 186, 220, 13, 202, + 169, 24, 201, 186, 2, 202, 169, 24, 201, 186, 220, 13, 215, 128, 24, 201, + 186, 2, 215, 128, 24, 201, 186, 204, 6, 24, 232, 197, 220, 13, 202, 169, + 24, 232, 197, 2, 202, 169, 24, 232, 197, 220, 13, 215, 128, 24, 232, 197, + 2, 215, 128, 24, 232, 197, 204, 6, 24, 201, 186, 232, 197, 251, 154, 24, + 215, 172, 133, 144, 220, 12, 24, 215, 172, 133, 144, 202, 70, 24, 215, + 172, 133, 204, 6, 24, 215, 172, 144, 204, 6, 24, 215, 172, 133, 144, 251, + 155, 220, 12, 24, 215, 172, 133, 144, 251, 155, 202, 70, 24, 215, 172, + 202, 208, 119, 202, 208, 205, 84, 24, 215, 171, 232, 253, 239, 35, 24, + 215, 173, 232, 253, 239, 35, 24, 215, 171, 202, 170, 201, 53, 202, 70, + 24, 215, 171, 202, 170, 201, 53, 216, 212, 24, 215, 171, 202, 170, 201, + 53, 220, 12, 24, 215, 171, 202, 170, 201, 53, 220, 10, 24, 215, 171, 202, + 170, 193, 4, 232, 200, 24, 215, 171, 55, 201, 52, 24, 215, 171, 55, 193, + 4, 232, 200, 24, 215, 171, 55, 251, 154, 24, 215, 171, 55, 251, 155, 193, + 4, 232, 200, 24, 215, 171, 238, 217, 24, 215, 171, 197, 225, 201, 53, + 215, 175, 24, 215, 171, 197, 225, 193, 4, 232, 200, 24, 215, 171, 197, + 225, 251, 154, 24, 215, 171, 197, 225, 251, 155, 193, 4, 232, 200, 24, + 215, 171, 248, 228, 202, 70, 24, 215, 171, 248, 228, 216, 212, 24, 215, + 171, 248, 228, 220, 12, 24, 215, 171, 239, 2, 202, 70, 24, 215, 171, 239, + 2, 216, 212, 24, 215, 171, 239, 2, 220, 12, 24, 215, 171, 239, 2, 206, + 120, 24, 215, 171, 243, 126, 202, 70, 24, 215, 171, 243, 126, 216, 212, + 24, 215, 171, 243, 126, 220, 12, 24, 215, 171, 111, 202, 70, 24, 215, + 171, 111, 216, 212, 24, 215, 171, 111, 220, 12, 24, 215, 171, 191, 21, + 202, 70, 24, 215, 171, 191, 21, 216, 212, 24, 215, 171, 191, 21, 220, 12, + 24, 215, 171, 210, 57, 202, 70, 24, 215, 171, 210, 57, 216, 212, 24, 215, + 171, 210, 57, 220, 12, 24, 198, 3, 206, 118, 202, 169, 24, 198, 3, 206, + 118, 235, 133, 24, 198, 3, 206, 118, 251, 154, 24, 198, 3, 206, 119, 202, + 169, 24, 198, 3, 206, 119, 235, 133, 24, 198, 3, 206, 119, 251, 154, 24, + 198, 3, 203, 144, 24, 198, 3, 250, 251, 201, 218, 202, 169, 24, 198, 3, + 250, 251, 201, 218, 235, 133, 24, 198, 3, 250, 251, 201, 218, 197, 224, + 24, 215, 174, 250, 139, 202, 70, 24, 215, 174, 250, 139, 216, 212, 24, + 215, 174, 250, 139, 220, 12, 24, 215, 174, 250, 139, 220, 10, 24, 215, + 174, 198, 31, 202, 70, 24, 215, 174, 198, 31, 216, 212, 24, 215, 174, + 198, 31, 220, 12, 24, 215, 174, 198, 31, 220, 10, 24, 215, 174, 248, 210, + 250, 139, 202, 70, 24, 215, 174, 248, 210, 250, 139, 216, 212, 24, 215, + 174, 248, 210, 250, 139, 220, 12, 24, 215, 174, 248, 210, 250, 139, 220, + 10, 24, 215, 174, 248, 210, 198, 31, 202, 70, 24, 215, 174, 248, 210, + 198, 31, 216, 212, 24, 215, 174, 248, 210, 198, 31, 220, 12, 24, 215, + 174, 248, 210, 198, 31, 220, 10, 24, 215, 173, 202, 170, 201, 53, 202, + 70, 24, 215, 173, 202, 170, 201, 53, 216, 212, 24, 215, 173, 202, 170, + 201, 53, 220, 12, 24, 215, 173, 202, 170, 201, 53, 220, 10, 24, 215, 173, + 202, 170, 193, 4, 232, 200, 24, 215, 173, 55, 201, 52, 24, 215, 173, 55, + 193, 4, 232, 200, 24, 215, 173, 55, 251, 154, 24, 215, 173, 55, 251, 155, + 193, 4, 232, 200, 24, 215, 173, 238, 217, 24, 215, 173, 197, 225, 201, + 53, 215, 175, 24, 215, 173, 197, 225, 193, 4, 232, 200, 24, 215, 173, + 197, 225, 251, 155, 215, 175, 24, 215, 173, 197, 225, 251, 155, 193, 4, + 232, 200, 24, 215, 173, 248, 227, 24, 215, 173, 239, 2, 202, 70, 24, 215, + 173, 239, 2, 216, 212, 24, 215, 173, 239, 2, 220, 12, 24, 215, 173, 243, + 125, 24, 215, 173, 111, 202, 70, 24, 215, 173, 111, 216, 212, 24, 215, + 173, 111, 220, 12, 24, 215, 173, 191, 21, 202, 70, 24, 215, 173, 191, 21, + 216, 212, 24, 215, 173, 191, 21, 220, 12, 24, 215, 173, 210, 57, 202, 70, + 24, 215, 173, 210, 57, 216, 212, 24, 215, 173, 210, 57, 220, 12, 24, 198, + 4, 206, 119, 202, 169, 24, 198, 4, 206, 119, 235, 133, 24, 198, 4, 206, + 119, 251, 154, 24, 198, 4, 206, 118, 202, 169, 24, 198, 4, 206, 118, 235, + 133, 24, 198, 4, 206, 118, 251, 154, 24, 198, 4, 203, 144, 24, 215, 171, + 238, 165, 208, 23, 202, 70, 24, 215, 171, 238, 165, 208, 23, 216, 212, + 24, 215, 171, 238, 165, 208, 23, 220, 12, 24, 215, 171, 238, 165, 208, + 23, 220, 10, 24, 215, 171, 238, 165, 230, 67, 202, 70, 24, 215, 171, 238, + 165, 230, 67, 216, 212, 24, 215, 171, 238, 165, 230, 67, 220, 12, 24, + 215, 171, 238, 165, 230, 67, 220, 10, 24, 215, 171, 238, 165, 198, 218, + 243, 11, 202, 70, 24, 215, 171, 238, 165, 198, 218, 243, 11, 216, 212, + 24, 215, 171, 228, 143, 202, 70, 24, 215, 171, 228, 143, 216, 212, 24, + 215, 171, 228, 143, 220, 12, 24, 215, 171, 219, 5, 202, 70, 24, 215, 171, + 219, 5, 216, 212, 24, 215, 171, 219, 5, 220, 12, 24, 215, 171, 219, 5, 2, + 235, 133, 24, 215, 171, 193, 139, 238, 165, 55, 202, 70, 24, 215, 171, + 193, 139, 238, 165, 55, 216, 212, 24, 215, 171, 193, 139, 238, 165, 55, + 220, 12, 24, 215, 171, 193, 139, 238, 165, 197, 225, 202, 70, 24, 215, + 171, 193, 139, 238, 165, 197, 225, 216, 212, 24, 215, 171, 193, 139, 238, + 165, 197, 225, 220, 12, 24, 215, 171, 238, 165, 199, 25, 201, 52, 24, + 215, 171, 238, 163, 238, 218, 202, 70, 24, 215, 171, 238, 163, 238, 218, + 216, 212, 24, 206, 118, 202, 169, 24, 206, 118, 235, 133, 24, 206, 118, + 251, 156, 24, 215, 171, 203, 144, 24, 215, 171, 238, 165, 229, 116, 232, + 97, 193, 167, 24, 215, 171, 228, 143, 229, 116, 232, 97, 193, 167, 24, + 215, 171, 219, 5, 229, 116, 232, 97, 193, 167, 24, 215, 171, 193, 139, + 229, 116, 232, 97, 193, 167, 24, 206, 118, 202, 170, 229, 116, 232, 97, + 193, 167, 24, 206, 118, 55, 229, 116, 232, 97, 193, 167, 24, 206, 118, + 251, 155, 229, 116, 232, 97, 193, 167, 24, 215, 171, 238, 165, 229, 116, + 243, 104, 24, 215, 171, 228, 143, 229, 116, 243, 104, 24, 215, 171, 219, + 5, 229, 116, 243, 104, 24, 215, 171, 193, 139, 229, 116, 243, 104, 24, + 206, 118, 202, 170, 229, 116, 243, 104, 24, 206, 118, 55, 229, 116, 243, + 104, 24, 206, 118, 251, 155, 229, 116, 243, 104, 24, 215, 171, 193, 139, + 237, 39, 210, 86, 202, 70, 24, 215, 171, 193, 139, 237, 39, 210, 86, 216, + 212, 24, 215, 171, 193, 139, 237, 39, 210, 86, 220, 12, 24, 215, 173, + 238, 165, 229, 116, 247, 31, 202, 70, 24, 215, 173, 238, 165, 229, 116, + 247, 31, 220, 12, 24, 215, 173, 228, 143, 229, 116, 247, 31, 2, 235, 133, + 24, 215, 173, 228, 143, 229, 116, 247, 31, 220, 13, 235, 133, 24, 215, + 173, 228, 143, 229, 116, 247, 31, 2, 197, 224, 24, 215, 173, 228, 143, + 229, 116, 247, 31, 220, 13, 197, 224, 24, 215, 173, 219, 5, 229, 116, + 247, 31, 2, 202, 169, 24, 215, 173, 219, 5, 229, 116, 247, 31, 220, 13, + 202, 169, 24, 215, 173, 219, 5, 229, 116, 247, 31, 2, 235, 133, 24, 215, + 173, 219, 5, 229, 116, 247, 31, 220, 13, 235, 133, 24, 215, 173, 193, + 139, 229, 116, 247, 31, 202, 70, 24, 215, 173, 193, 139, 229, 116, 247, + 31, 220, 12, 24, 206, 119, 202, 170, 229, 116, 247, 30, 24, 206, 119, 55, + 229, 116, 247, 30, 24, 206, 119, 251, 155, 229, 116, 247, 30, 24, 215, + 173, 238, 165, 229, 116, 232, 194, 202, 70, 24, 215, 173, 238, 165, 229, + 116, 232, 194, 220, 12, 24, 215, 173, 228, 143, 229, 116, 232, 194, 2, + 235, 133, 24, 215, 173, 228, 143, 229, 116, 232, 194, 220, 13, 235, 133, + 24, 215, 173, 228, 143, 229, 116, 232, 194, 197, 225, 2, 197, 224, 24, + 215, 173, 228, 143, 229, 116, 232, 194, 197, 225, 220, 13, 197, 224, 24, + 215, 173, 219, 5, 229, 116, 232, 194, 2, 202, 169, 24, 215, 173, 219, 5, + 229, 116, 232, 194, 220, 13, 202, 169, 24, 215, 173, 219, 5, 229, 116, + 232, 194, 2, 235, 133, 24, 215, 173, 219, 5, 229, 116, 232, 194, 220, 13, + 235, 133, 24, 215, 173, 193, 139, 229, 116, 232, 194, 202, 70, 24, 215, + 173, 193, 139, 229, 116, 232, 194, 220, 12, 24, 206, 119, 202, 170, 229, + 116, 232, 193, 24, 206, 119, 55, 229, 116, 232, 193, 24, 206, 119, 251, + 155, 229, 116, 232, 193, 24, 215, 173, 238, 165, 202, 70, 24, 215, 173, + 238, 165, 216, 212, 24, 215, 173, 238, 165, 220, 12, 24, 215, 173, 238, + 165, 220, 10, 24, 215, 173, 238, 165, 242, 78, 24, 215, 173, 228, 143, + 202, 70, 24, 215, 173, 219, 5, 202, 70, 24, 215, 173, 193, 139, 202, 58, + 24, 215, 173, 193, 139, 202, 70, 24, 215, 173, 193, 139, 220, 12, 24, + 206, 119, 202, 169, 24, 206, 119, 235, 133, 24, 206, 119, 251, 154, 24, + 215, 173, 203, 145, 210, 118, 24, 215, 171, 250, 251, 243, 11, 2, 202, + 169, 24, 215, 171, 250, 251, 243, 11, 216, 213, 202, 169, 24, 215, 171, + 250, 251, 243, 11, 2, 235, 133, 24, 215, 171, 250, 251, 243, 11, 216, + 213, 235, 133, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 2, + 202, 169, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 216, 213, + 202, 169, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 220, 13, + 202, 169, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 2, 235, + 133, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 216, 213, 235, + 133, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 220, 13, 235, + 133, 24, 215, 171, 193, 4, 243, 11, 232, 97, 202, 169, 24, 215, 171, 193, + 4, 243, 11, 232, 97, 235, 133, 24, 215, 173, 193, 4, 243, 11, 229, 116, + 193, 168, 202, 169, 24, 215, 173, 193, 4, 243, 11, 229, 116, 193, 168, + 235, 133, 24, 215, 171, 232, 253, 243, 8, 202, 169, 24, 215, 171, 232, + 253, 243, 8, 235, 133, 24, 215, 173, 232, 253, 243, 8, 229, 116, 193, + 168, 202, 169, 24, 215, 173, 232, 253, 243, 8, 229, 116, 193, 168, 235, + 133, 24, 235, 40, 250, 236, 202, 70, 24, 235, 40, 250, 236, 220, 12, 24, + 235, 40, 233, 73, 24, 235, 40, 202, 75, 24, 235, 40, 199, 88, 24, 235, + 40, 207, 63, 24, 235, 40, 202, 176, 24, 235, 40, 202, 177, 251, 154, 24, + 235, 40, 233, 225, 211, 27, 198, 146, 24, 235, 40, 230, 226, 24, 229, + 235, 24, 229, 236, 206, 193, 24, 229, 236, 215, 171, 201, 52, 24, 229, + 236, 215, 171, 198, 149, 24, 229, 236, 215, 173, 201, 52, 24, 229, 236, + 215, 171, 238, 164, 24, 229, 236, 215, 173, 238, 164, 24, 229, 236, 215, + 176, 243, 10, 24, 233, 104, 236, 233, 209, 25, 213, 14, 232, 133, 198, + 147, 24, 233, 104, 236, 233, 209, 25, 213, 14, 133, 211, 57, 235, 123, + 24, 233, 104, 236, 233, 209, 25, 213, 14, 133, 211, 57, 144, 198, 147, + 24, 233, 191, 201, 53, 196, 77, 24, 233, 191, 201, 53, 214, 81, 24, 233, + 191, 201, 53, 235, 123, 24, 235, 107, 233, 191, 214, 82, 235, 123, 24, + 235, 107, 233, 191, 144, 214, 81, 24, 235, 107, 233, 191, 133, 214, 81, + 24, 235, 107, 233, 191, 214, 82, 196, 77, 24, 232, 151, 214, 81, 24, 232, + 151, 239, 35, 24, 232, 151, 193, 7, 24, 233, 186, 211, 76, 24, 233, 186, + 201, 185, 24, 233, 186, 242, 218, 24, 233, 194, 248, 130, 202, 169, 24, + 233, 194, 248, 130, 215, 128, 24, 233, 186, 132, 211, 76, 24, 233, 186, + 193, 78, 211, 76, 24, 233, 186, 132, 242, 218, 24, 233, 186, 193, 76, + 215, 175, 24, 233, 194, 193, 58, 24, 233, 187, 196, 77, 24, 233, 187, + 235, 123, 24, 233, 187, 232, 180, 24, 233, 189, 201, 52, 24, 233, 189, + 201, 53, 235, 133, 24, 233, 189, 201, 53, 251, 154, 24, 233, 190, 201, + 52, 24, 233, 190, 201, 53, 235, 133, 24, 233, 190, 201, 53, 251, 154, 24, + 233, 189, 238, 162, 24, 233, 190, 238, 162, 24, 233, 189, 243, 5, 24, + 243, 121, 208, 155, 24, 243, 121, 214, 81, 24, 243, 121, 200, 218, 24, + 199, 89, 243, 121, 229, 135, 24, 199, 89, 243, 121, 216, 84, 24, 199, 89, + 243, 121, 218, 241, 24, 234, 209, 24, 213, 14, 214, 81, 24, 213, 14, 239, + 35, 24, 213, 14, 193, 5, 24, 213, 14, 193, 73, 24, 251, 226, 248, 116, + 211, 14, 24, 251, 226, 200, 217, 223, 162, 24, 251, 226, 248, 118, 2, + 206, 117, 24, 251, 226, 200, 219, 2, 206, 117, 24, 248, 39, 223, 134, 24, + 248, 39, 233, 214, 24, 215, 180, 242, 219, 214, 81, 24, 215, 180, 242, + 219, 232, 132, 24, 215, 180, 242, 219, 239, 35, 24, 215, 180, 202, 65, + 24, 215, 180, 202, 66, 193, 7, 24, 215, 180, 202, 66, 211, 76, 24, 215, + 180, 232, 93, 24, 215, 180, 232, 94, 193, 7, 24, 215, 180, 232, 94, 211, + 76, 24, 215, 180, 211, 77, 243, 10, 24, 215, 180, 211, 77, 232, 132, 24, + 215, 180, 211, 77, 193, 7, 24, 215, 180, 211, 77, 211, 7, 24, 215, 180, + 211, 77, 211, 8, 193, 7, 24, 215, 180, 211, 77, 211, 8, 192, 88, 24, 215, + 180, 211, 77, 207, 92, 24, 215, 180, 211, 77, 207, 93, 193, 7, 24, 215, + 180, 211, 77, 207, 93, 192, 88, 24, 215, 180, 221, 122, 24, 215, 180, + 221, 123, 232, 132, 24, 215, 180, 221, 123, 193, 7, 24, 215, 180, 199, + 88, 24, 215, 180, 199, 89, 232, 132, 24, 215, 180, 199, 89, 200, 218, 24, + 219, 97, 208, 219, 198, 87, 24, 219, 99, 110, 139, 196, 74, 24, 219, 99, + 116, 139, 218, 236, 24, 215, 180, 239, 0, 24, 215, 180, 193, 6, 202, 169, + 24, 215, 180, 193, 6, 235, 133, 24, 198, 62, 201, 74, 211, 15, 233, 75, + 24, 198, 62, 219, 142, 219, 96, 24, 198, 62, 198, 136, 248, 210, 219, 96, + 24, 198, 62, 198, 136, 198, 35, 223, 118, 215, 179, 24, 198, 62, 223, + 118, 215, 180, 207, 63, 24, 198, 62, 215, 170, 251, 251, 243, 122, 24, + 198, 62, 247, 22, 201, 74, 211, 14, 24, 198, 62, 247, 22, 223, 118, 215, + 179, 24, 199, 117, 24, 199, 118, 215, 175, 24, 199, 118, 211, 105, 198, + 61, 24, 199, 118, 211, 105, 198, 62, 215, 175, 24, 199, 118, 211, 105, + 219, 96, 24, 199, 118, 211, 105, 219, 97, 215, 175, 24, 199, 118, 248, + 146, 219, 96, 24, 215, 171, 223, 14, 24, 215, 173, 223, 14, 24, 214, 112, + 24, 230, 78, 24, 233, 217, 24, 203, 22, 229, 123, 201, 219, 24, 203, 22, + 229, 123, 209, 23, 24, 193, 165, 203, 22, 229, 123, 215, 178, 24, 232, + 192, 203, 22, 229, 123, 215, 178, 24, 203, 22, 198, 148, 232, 98, 193, + 172, 24, 198, 43, 201, 53, 201, 37, 24, 198, 43, 238, 163, 248, 227, 24, + 198, 44, 197, 16, 24, 116, 248, 105, 198, 148, 232, 98, 229, 123, 222, + 195, 24, 219, 124, 242, 79, 24, 219, 124, 219, 197, 24, 219, 124, 219, + 196, 24, 219, 124, 219, 195, 24, 219, 124, 219, 194, 24, 219, 124, 219, + 193, 24, 219, 124, 219, 192, 24, 219, 124, 219, 191, 24, 232, 252, 24, + 219, 37, 201, 247, 24, 219, 38, 201, 247, 24, 219, 40, 229, 208, 24, 219, + 40, 193, 74, 24, 219, 40, 237, 92, 24, 219, 40, 229, 236, 214, 112, 24, + 219, 40, 198, 45, 24, 219, 40, 219, 123, 237, 9, 24, 242, 74, 24, 232, + 80, 201, 63, 24, 204, 25, 24, 242, 83, 24, 210, 113, 24, 233, 6, 215, + 244, 24, 233, 6, 215, 243, 24, 233, 6, 215, 242, 24, 233, 6, 215, 241, + 24, 233, 6, 215, 240, 24, 206, 121, 215, 244, 24, 206, 121, 215, 243, 24, + 206, 121, 215, 242, 24, 206, 121, 215, 241, 24, 206, 121, 215, 240, 24, + 206, 121, 215, 239, 24, 206, 121, 215, 238, 24, 206, 121, 215, 237, 24, + 206, 121, 215, 251, 24, 206, 121, 215, 250, 24, 206, 121, 215, 249, 24, + 206, 121, 215, 248, 24, 206, 121, 215, 247, 24, 206, 121, 215, 246, 24, + 206, 121, 215, 245, 8, 2, 1, 233, 37, 237, 3, 4, 197, 228, 8, 2, 1, 207, + 18, 27, 232, 51, 8, 1, 2, 6, 153, 232, 51, 8, 2, 1, 207, 18, 222, 152, 8, + 1, 2, 6, 220, 143, 4, 248, 231, 8, 2, 1, 219, 163, 4, 207, 24, 102, 8, 2, + 1, 153, 192, 160, 4, 248, 231, 8, 2, 1, 207, 18, 234, 88, 8, 2, 1, 153, + 207, 222, 4, 179, 219, 213, 23, 207, 24, 102, 8, 2, 1, 200, 44, 4, 228, + 251, 23, 207, 24, 102, 8, 1, 207, 24, 242, 232, 4, 207, 24, 102, 8, 2, 1, + 234, 13, 4, 55, 164, 8, 2, 1, 234, 13, 4, 55, 249, 88, 23, 238, 175, 8, + 2, 1, 153, 200, 44, 4, 238, 175, 8, 1, 223, 93, 231, 11, 201, 64, 4, 238, + 175, 8, 1, 201, 36, 247, 194, 4, 238, 175, 8, 1, 2, 6, 153, 222, 152, 8, + 2, 1, 220, 143, 4, 232, 233, 8, 2, 1, 237, 70, 237, 3, 4, 210, 192, 102, + 8, 2, 1, 220, 143, 4, 248, 232, 23, 210, 192, 102, 8, 2, 1, 234, 89, 4, + 210, 192, 102, 8, 2, 1, 153, 207, 222, 4, 210, 192, 102, 8, 2, 1, 207, + 222, 4, 232, 234, 23, 210, 192, 102, 8, 2, 1, 199, 79, 237, 3, 4, 210, + 192, 102, 8, 2, 1, 233, 179, 4, 210, 192, 102, 8, 2, 1, 237, 70, 237, 3, + 4, 207, 24, 102, 8, 2, 1, 228, 74, 4, 201, 28, 23, 207, 24, 102, 8, 2, 1, + 187, 4, 207, 24, 102, 8, 2, 1, 199, 79, 237, 3, 4, 207, 24, 102, 8, 2, 1, + 247, 194, 4, 207, 24, 102, 8, 2, 1, 206, 9, 4, 238, 175, 8, 2, 1, 238, + 128, 4, 216, 86, 45, 102, 8, 2, 1, 220, 143, 4, 216, 86, 45, 102, 8, 2, + 1, 215, 62, 4, 216, 86, 45, 102, 8, 2, 1, 207, 222, 4, 216, 86, 45, 102, + 8, 2, 1, 206, 9, 4, 216, 86, 45, 102, 8, 2, 1, 200, 44, 4, 216, 86, 45, + 102, 33, 135, 1, 250, 122, 33, 135, 1, 247, 252, 33, 135, 1, 195, 151, + 33, 135, 1, 231, 18, 33, 135, 1, 236, 169, 33, 135, 1, 192, 49, 33, 135, + 1, 191, 55, 33, 135, 1, 191, 82, 33, 135, 1, 223, 39, 33, 135, 1, 89, + 223, 39, 33, 135, 1, 68, 33, 135, 1, 236, 190, 33, 135, 1, 222, 94, 33, + 135, 1, 219, 75, 33, 135, 1, 215, 66, 33, 135, 1, 214, 210, 33, 135, 1, + 211, 89, 33, 135, 1, 209, 55, 33, 135, 1, 206, 179, 33, 135, 1, 202, 77, + 33, 135, 1, 197, 44, 33, 135, 1, 196, 124, 33, 135, 1, 232, 101, 33, 135, + 1, 229, 188, 33, 135, 1, 203, 8, 33, 135, 1, 197, 146, 33, 135, 1, 243, + 54, 33, 135, 1, 203, 165, 33, 135, 1, 192, 58, 33, 135, 1, 192, 60, 33, + 135, 1, 192, 93, 33, 135, 1, 191, 225, 33, 135, 1, 2, 191, 190, 33, 135, + 1, 192, 12, 33, 135, 1, 223, 82, 2, 191, 190, 33, 135, 1, 248, 175, 191, + 190, 33, 135, 1, 223, 82, 248, 175, 191, 190, 33, 135, 1, 232, 228, 52, + 1, 38, 2, 65, 52, 1, 38, 2, 249, 17, 52, 1, 38, 2, 195, 153, 52, 1, 38, + 2, 231, 77, 52, 1, 38, 2, 237, 146, 52, 1, 38, 2, 223, 226, 52, 1, 38, 2, + 191, 62, 52, 1, 38, 2, 191, 87, 52, 1, 38, 2, 68, 52, 1, 38, 2, 155, 52, + 1, 38, 2, 234, 140, 52, 1, 38, 2, 234, 114, 52, 1, 38, 2, 74, 52, 1, 38, + 2, 210, 63, 52, 1, 38, 2, 234, 34, 52, 1, 38, 2, 234, 22, 52, 1, 38, 2, + 199, 145, 52, 1, 38, 2, 66, 52, 1, 38, 2, 234, 181, 52, 1, 38, 2, 140, + 52, 1, 38, 2, 197, 161, 52, 1, 38, 2, 243, 127, 52, 1, 38, 2, 203, 165, + 52, 1, 38, 2, 192, 58, 52, 1, 38, 2, 71, 52, 1, 38, 2, 191, 225, 52, 1, + 38, 2, 235, 17, 52, 1, 38, 2, 205, 86, 52, 1, 38, 2, 247, 203, 68, 52, 1, + 38, 2, 223, 10, 52, 1, 38, 2, 249, 82, 74, 52, 1, 38, 2, 201, 53, 66, 52, + 1, 38, 2, 210, 179, 38, 200, 230, 2, 1, 65, 38, 200, 230, 2, 1, 249, 17, + 38, 200, 230, 2, 1, 195, 153, 38, 200, 230, 2, 1, 231, 77, 38, 200, 230, + 2, 1, 237, 146, 38, 200, 230, 2, 1, 223, 226, 38, 200, 230, 2, 1, 191, + 62, 38, 200, 230, 2, 1, 191, 87, 38, 200, 230, 2, 1, 68, 38, 200, 230, 2, + 1, 155, 38, 200, 230, 2, 1, 234, 140, 38, 200, 230, 2, 1, 74, 38, 200, + 230, 2, 1, 210, 63, 38, 200, 230, 2, 1, 234, 22, 38, 200, 230, 2, 1, 66, + 38, 200, 230, 2, 1, 234, 181, 38, 200, 230, 2, 1, 140, 38, 200, 230, 2, + 1, 197, 161, 38, 200, 230, 2, 1, 243, 127, 38, 200, 230, 2, 1, 203, 165, + 38, 200, 230, 2, 1, 230, 17, 56, 38, 200, 230, 2, 1, 192, 58, 38, 200, + 230, 2, 1, 231, 78, 4, 196, 69, 38, 200, 230, 2, 1, 247, 203, 68, 38, + 200, 230, 2, 1, 235, 32, 38, 200, 230, 2, 1, 235, 28, 52, 1, 38, 2, 234, + 23, 4, 237, 87, 52, 1, 38, 2, 192, 59, 4, 249, 147, 192, 62, 52, 1, 38, + 2, 201, 53, 126, 4, 106, 33, 38, 2, 1, 247, 203, 68, 212, 80, 208, 162, + 90, 1, 174, 212, 80, 208, 162, 90, 1, 197, 168, 212, 80, 208, 162, 90, 1, + 212, 199, 212, 80, 208, 162, 90, 1, 190, 190, 212, 80, 208, 162, 90, 1, + 140, 212, 80, 208, 162, 90, 1, 180, 212, 80, 208, 162, 90, 1, 192, 220, + 212, 80, 208, 162, 90, 1, 213, 111, 212, 80, 208, 162, 90, 1, 247, 160, + 212, 80, 208, 162, 90, 1, 173, 212, 80, 208, 162, 90, 1, 188, 212, 80, + 208, 162, 90, 1, 191, 123, 212, 80, 208, 162, 90, 1, 214, 166, 212, 80, + 208, 162, 90, 1, 212, 186, 212, 80, 208, 162, 90, 1, 155, 212, 80, 208, + 162, 90, 1, 238, 32, 212, 80, 208, 162, 90, 1, 212, 101, 212, 80, 208, + 162, 90, 1, 212, 244, 212, 80, 208, 162, 90, 1, 195, 188, 212, 80, 208, + 162, 90, 1, 212, 180, 212, 80, 208, 162, 90, 1, 197, 8, 212, 80, 208, + 162, 90, 1, 233, 109, 212, 80, 208, 162, 90, 1, 165, 212, 80, 208, 162, + 90, 1, 208, 96, 212, 80, 208, 162, 90, 1, 170, 212, 80, 208, 162, 90, 1, + 212, 246, 212, 80, 208, 162, 90, 1, 168, 212, 80, 208, 162, 90, 1, 192, + 175, 212, 80, 208, 162, 90, 1, 212, 248, 212, 80, 208, 162, 90, 1, 236, + 186, 212, 80, 208, 162, 90, 1, 212, 247, 212, 80, 208, 162, 90, 1, 230, + 81, 212, 80, 208, 162, 90, 1, 216, 19, 212, 80, 208, 162, 90, 1, 209, + 110, 212, 80, 208, 162, 90, 1, 231, 240, 212, 80, 208, 162, 90, 1, 206, + 109, 212, 80, 208, 162, 90, 1, 65, 212, 80, 208, 162, 90, 1, 252, 206, + 212, 80, 208, 162, 90, 1, 68, 212, 80, 208, 162, 90, 1, 66, 212, 80, 208, + 162, 90, 1, 74, 212, 80, 208, 162, 90, 1, 211, 87, 212, 80, 208, 162, 90, + 1, 71, 212, 80, 208, 162, 90, 1, 234, 188, 212, 80, 208, 162, 90, 1, 193, + 224, 212, 80, 208, 162, 90, 198, 70, 212, 80, 208, 162, 90, 198, 66, 212, + 80, 208, 162, 90, 198, 67, 212, 80, 208, 162, 90, 198, 64, 212, 80, 208, + 162, 90, 198, 65, 212, 80, 208, 162, 90, 198, 68, 212, 80, 208, 162, 90, + 198, 69, 212, 80, 208, 162, 90, 3, 40, 209, 250, 212, 80, 208, 162, 90, + 3, 40, 199, 3, 212, 80, 208, 162, 90, 3, 40, 219, 39, 212, 80, 208, 162, + 90, 3, 40, 251, 101, 212, 80, 208, 162, 90, 3, 40, 223, 94, 212, 80, 208, + 162, 90, 3, 192, 183, 192, 182, 212, 80, 208, 162, 90, 5, 219, 190, 212, + 80, 208, 162, 90, 17, 191, 77, 212, 80, 208, 162, 90, 17, 107, 212, 80, + 208, 162, 90, 17, 109, 212, 80, 208, 162, 90, 17, 138, 212, 80, 208, 162, + 90, 17, 134, 212, 80, 208, 162, 90, 17, 149, 212, 80, 208, 162, 90, 17, + 169, 212, 80, 208, 162, 90, 17, 175, 212, 80, 208, 162, 90, 17, 171, 212, + 80, 208, 162, 90, 17, 178, 212, 80, 208, 162, 90, 219, 28, 212, 96, 212, + 80, 208, 162, 90, 47, 247, 160, 198, 38, 1, 168, 198, 38, 1, 249, 153, + 198, 38, 1, 190, 190, 198, 38, 1, 238, 32, 198, 38, 1, 155, 198, 38, 1, + 231, 240, 198, 38, 1, 174, 198, 38, 1, 180, 198, 38, 1, 214, 68, 198, 38, + 1, 188, 198, 38, 1, 247, 1, 198, 38, 1, 170, 198, 38, 1, 193, 190, 198, + 38, 1, 223, 32, 198, 38, 1, 140, 198, 38, 1, 165, 198, 38, 1, 173, 198, + 38, 1, 68, 198, 38, 1, 248, 38, 68, 198, 38, 1, 223, 49, 198, 38, 1, 248, + 38, 223, 49, 198, 38, 1, 66, 198, 38, 1, 71, 198, 38, 1, 248, 38, 71, + 198, 38, 1, 234, 65, 198, 38, 1, 248, 38, 234, 65, 198, 38, 1, 74, 198, + 38, 1, 252, 25, 198, 38, 1, 248, 38, 252, 25, 198, 38, 1, 65, 198, 38, 3, + 206, 180, 198, 79, 193, 163, 1, 252, 206, 193, 163, 1, 65, 193, 163, 1, + 249, 153, 193, 163, 1, 247, 160, 193, 163, 1, 238, 32, 193, 163, 1, 231, + 240, 193, 163, 1, 170, 193, 163, 1, 209, 228, 193, 163, 1, 173, 193, 163, + 1, 180, 193, 163, 1, 168, 193, 163, 1, 190, 190, 193, 163, 1, 199, 49, + 193, 163, 1, 233, 109, 193, 163, 1, 188, 193, 163, 1, 203, 165, 193, 163, + 1, 223, 32, 193, 163, 1, 191, 123, 193, 163, 1, 193, 190, 193, 163, 1, + 195, 188, 193, 163, 1, 155, 193, 163, 1, 74, 193, 163, 1, 250, 163, 193, + 163, 1, 165, 193, 163, 1, 174, 193, 163, 1, 221, 215, 193, 163, 1, 140, + 193, 163, 1, 71, 193, 163, 1, 68, 193, 163, 1, 214, 68, 193, 163, 1, 66, + 193, 163, 1, 219, 66, 193, 163, 1, 197, 168, 193, 163, 1, 198, 26, 193, + 163, 1, 211, 94, 193, 163, 1, 252, 165, 193, 163, 1, 251, 122, 193, 163, + 1, 223, 136, 193, 163, 1, 211, 104, 193, 163, 1, 234, 103, 193, 163, 1, + 252, 166, 193, 163, 1, 212, 101, 193, 163, 1, 196, 147, 193, 163, 1, 192, + 24, 193, 163, 163, 197, 67, 193, 163, 163, 197, 66, 193, 163, 163, 221, + 54, 193, 163, 163, 221, 53, 193, 163, 17, 191, 77, 193, 163, 17, 107, + 193, 163, 17, 109, 193, 163, 17, 138, 193, 163, 17, 134, 193, 163, 17, + 149, 193, 163, 17, 169, 193, 163, 17, 175, 193, 163, 17, 171, 193, 163, + 17, 178, 193, 163, 213, 232, 56, 214, 243, 215, 120, 1, 74, 214, 243, + 215, 120, 1, 211, 78, 214, 243, 215, 120, 1, 211, 120, 214, 243, 215, + 120, 1, 210, 242, 214, 243, 215, 120, 1, 211, 94, 214, 243, 215, 120, 1, + 65, 214, 243, 215, 120, 1, 251, 218, 214, 243, 215, 120, 1, 252, 155, + 214, 243, 215, 120, 1, 251, 69, 214, 243, 215, 120, 1, 251, 245, 214, + 243, 215, 120, 1, 68, 214, 243, 215, 120, 1, 223, 68, 214, 243, 215, 120, + 1, 228, 18, 214, 243, 215, 120, 1, 223, 53, 214, 243, 215, 120, 1, 223, + 200, 214, 243, 215, 120, 1, 66, 214, 243, 215, 120, 1, 196, 160, 214, + 243, 215, 120, 1, 196, 158, 214, 243, 215, 120, 1, 196, 128, 214, 243, + 215, 120, 1, 196, 62, 214, 243, 215, 120, 1, 71, 214, 243, 215, 120, 1, + 234, 85, 214, 243, 215, 120, 1, 234, 180, 214, 243, 215, 120, 1, 234, + 114, 214, 243, 215, 120, 1, 234, 103, 214, 243, 215, 120, 1, 233, 245, + 214, 243, 215, 120, 1, 234, 122, 214, 243, 215, 120, 3, 211, 127, 214, + 243, 215, 120, 3, 215, 138, 214, 243, 215, 120, 3, 198, 28, 214, 243, + 215, 120, 3, 223, 193, 214, 243, 215, 120, 3, 200, 161, 214, 243, 215, + 120, 17, 191, 77, 214, 243, 215, 120, 17, 107, 214, 243, 215, 120, 17, + 109, 214, 243, 215, 120, 17, 138, 214, 243, 215, 120, 17, 134, 214, 243, + 215, 120, 17, 149, 214, 243, 215, 120, 17, 169, 214, 243, 215, 120, 17, + 175, 214, 243, 215, 120, 17, 171, 214, 243, 215, 120, 17, 178, 36, 5, + 229, 166, 36, 5, 229, 160, 36, 5, 229, 162, 36, 5, 229, 165, 36, 5, 229, + 163, 36, 5, 229, 164, 36, 5, 229, 161, 36, 5, 230, 147, 229, 170, 36, 5, + 229, 167, 36, 5, 229, 168, 36, 5, 229, 169, 36, 5, 230, 147, 215, 76, 36, + 5, 230, 147, 215, 77, 36, 5, 230, 147, 207, 236, 36, 5, 230, 147, 207, + 237, 36, 5, 230, 147, 207, 238, 36, 5, 230, 147, 247, 207, 36, 5, 230, + 147, 247, 208, 36, 5, 230, 147, 220, 172, 36, 5, 230, 147, 220, 173, 36, + 5, 230, 147, 220, 174, 36, 5, 230, 147, 230, 131, 36, 5, 230, 147, 230, + 132, 36, 5, 230, 147, 230, 133, 36, 5, 230, 147, 232, 58, 36, 5, 230, + 147, 232, 59, 36, 5, 230, 147, 208, 118, 36, 5, 230, 147, 208, 119, 85, + 84, 5, 218, 167, 221, 166, 85, 84, 5, 218, 163, 155, 85, 84, 5, 218, 161, + 220, 232, 85, 84, 5, 218, 37, 222, 13, 85, 84, 5, 218, 7, 222, 22, 85, + 84, 5, 218, 26, 221, 41, 85, 84, 5, 218, 54, 221, 67, 85, 84, 5, 217, + 179, 220, 219, 85, 84, 5, 218, 158, 193, 86, 85, 84, 5, 218, 156, 193, + 190, 85, 84, 5, 218, 154, 193, 0, 85, 84, 5, 217, 232, 193, 114, 85, 84, + 5, 217, 240, 193, 125, 85, 84, 5, 217, 244, 193, 29, 85, 84, 5, 218, 57, + 193, 48, 85, 84, 5, 217, 164, 192, 252, 85, 84, 5, 217, 215, 193, 112, + 85, 84, 5, 218, 41, 192, 240, 85, 84, 5, 218, 53, 192, 242, 85, 84, 5, + 217, 219, 192, 241, 85, 84, 5, 218, 152, 216, 44, 85, 84, 5, 218, 150, + 217, 90, 85, 84, 5, 218, 148, 215, 122, 85, 84, 5, 218, 43, 216, 186, 85, + 84, 5, 218, 8, 215, 231, 85, 84, 5, 217, 204, 215, 148, 85, 84, 5, 217, + 169, 215, 142, 85, 84, 5, 218, 146, 248, 188, 85, 84, 5, 218, 143, 249, + 153, 85, 84, 5, 218, 141, 248, 10, 85, 84, 5, 217, 208, 249, 1, 85, 84, + 5, 218, 5, 249, 17, 85, 84, 5, 217, 255, 248, 97, 85, 84, 5, 217, 220, + 248, 111, 85, 84, 5, 218, 131, 68, 85, 84, 5, 218, 129, 65, 85, 84, 5, + 218, 127, 66, 85, 84, 5, 217, 195, 234, 188, 85, 84, 5, 218, 2, 71, 85, + 84, 5, 217, 193, 211, 87, 85, 84, 5, 217, 211, 74, 85, 84, 5, 217, 221, + 234, 166, 85, 84, 5, 217, 227, 223, 162, 85, 84, 5, 217, 223, 223, 162, + 85, 84, 5, 217, 163, 251, 132, 85, 84, 5, 217, 180, 234, 103, 85, 84, 5, + 218, 116, 202, 222, 85, 84, 5, 218, 114, 188, 85, 84, 5, 218, 112, 201, + 4, 85, 84, 5, 217, 196, 205, 50, 85, 84, 5, 217, 242, 205, 68, 85, 84, 5, + 217, 222, 202, 16, 85, 84, 5, 218, 23, 202, 46, 85, 84, 5, 217, 162, 202, + 215, 85, 84, 5, 218, 102, 219, 146, 85, 84, 5, 218, 100, 173, 85, 84, 5, + 218, 98, 218, 225, 85, 84, 5, 218, 18, 219, 228, 85, 84, 5, 218, 29, 219, + 238, 85, 84, 5, 218, 48, 219, 8, 85, 84, 5, 217, 205, 219, 43, 85, 84, 5, + 217, 248, 179, 219, 238, 85, 84, 5, 218, 124, 237, 44, 85, 84, 5, 218, + 121, 238, 32, 85, 84, 5, 218, 118, 235, 89, 85, 84, 5, 218, 13, 237, 131, + 85, 84, 5, 217, 178, 236, 146, 85, 84, 5, 217, 177, 236, 174, 85, 84, 5, + 218, 110, 198, 193, 85, 84, 5, 218, 107, 190, 190, 85, 84, 5, 218, 105, + 197, 94, 85, 84, 5, 218, 11, 199, 121, 85, 84, 5, 218, 47, 199, 145, 85, + 84, 5, 217, 254, 198, 59, 85, 84, 5, 218, 33, 159, 85, 84, 5, 218, 96, + 222, 244, 85, 84, 5, 218, 93, 223, 32, 85, 84, 5, 218, 91, 222, 182, 85, + 84, 5, 217, 201, 223, 8, 85, 84, 5, 217, 245, 223, 10, 85, 84, 5, 217, + 198, 222, 191, 85, 84, 5, 218, 39, 222, 201, 85, 84, 5, 217, 183, 179, + 222, 201, 85, 84, 5, 218, 89, 192, 33, 85, 84, 5, 218, 86, 170, 85, 84, + 5, 218, 84, 191, 225, 85, 84, 5, 217, 249, 192, 77, 85, 84, 5, 218, 22, + 192, 80, 85, 84, 5, 217, 217, 191, 246, 85, 84, 5, 217, 237, 192, 12, 85, + 84, 5, 218, 80, 233, 23, 85, 84, 5, 218, 78, 233, 109, 85, 84, 5, 218, + 76, 232, 86, 85, 84, 5, 218, 24, 233, 52, 85, 84, 5, 218, 27, 233, 59, + 85, 84, 5, 217, 225, 232, 162, 85, 84, 5, 218, 14, 232, 175, 85, 84, 5, + 217, 161, 232, 85, 85, 84, 5, 218, 1, 233, 80, 85, 84, 5, 218, 74, 213, + 179, 85, 84, 5, 218, 72, 214, 226, 85, 84, 5, 218, 70, 212, 130, 85, 84, + 5, 217, 241, 214, 102, 85, 84, 5, 217, 189, 213, 31, 85, 84, 5, 217, 182, + 229, 158, 85, 84, 5, 218, 65, 140, 85, 84, 5, 217, 172, 228, 159, 85, 84, + 5, 218, 68, 229, 215, 85, 84, 5, 218, 6, 229, 245, 85, 84, 5, 218, 63, + 228, 252, 85, 84, 5, 217, 218, 229, 23, 85, 84, 5, 218, 19, 229, 214, 85, + 84, 5, 217, 230, 228, 245, 85, 84, 5, 218, 49, 229, 128, 85, 84, 5, 217, + 228, 230, 56, 85, 84, 5, 218, 15, 228, 142, 85, 84, 5, 218, 50, 229, 198, + 85, 84, 5, 217, 165, 228, 255, 85, 84, 5, 218, 56, 228, 155, 85, 84, 5, + 218, 12, 214, 33, 85, 84, 5, 218, 61, 214, 47, 85, 84, 5, 218, 20, 214, + 30, 85, 84, 5, 217, 243, 214, 41, 85, 84, 5, 217, 212, 214, 42, 85, 84, + 5, 217, 202, 214, 31, 85, 84, 5, 217, 238, 214, 32, 85, 84, 5, 217, 199, + 214, 46, 85, 84, 5, 217, 231, 214, 29, 85, 84, 5, 218, 16, 179, 214, 42, + 85, 84, 5, 217, 252, 179, 214, 31, 85, 84, 5, 217, 175, 179, 214, 32, 85, + 84, 5, 217, 203, 231, 53, 85, 84, 5, 217, 247, 231, 240, 85, 84, 5, 217, + 190, 230, 179, 85, 84, 5, 217, 168, 231, 157, 85, 84, 5, 217, 192, 230, + 165, 85, 84, 5, 217, 191, 230, 175, 85, 84, 5, 217, 174, 214, 52, 85, 84, + 5, 218, 45, 213, 245, 85, 84, 5, 217, 181, 213, 234, 85, 84, 5, 218, 34, + 209, 185, 85, 84, 5, 218, 3, 168, 85, 84, 5, 218, 52, 208, 165, 85, 84, + 5, 218, 21, 210, 49, 85, 84, 5, 218, 51, 210, 63, 85, 84, 5, 218, 0, 209, + 37, 85, 84, 5, 218, 36, 209, 73, 85, 84, 5, 217, 213, 216, 252, 85, 84, + 5, 218, 40, 217, 11, 85, 84, 5, 217, 236, 216, 246, 85, 84, 5, 218, 55, + 217, 3, 85, 84, 5, 217, 170, 217, 3, 85, 84, 5, 218, 30, 217, 4, 85, 84, + 5, 217, 186, 216, 247, 85, 84, 5, 217, 184, 216, 248, 85, 84, 5, 217, + 171, 216, 240, 85, 84, 5, 217, 197, 179, 217, 4, 85, 84, 5, 217, 253, + 179, 216, 247, 85, 84, 5, 217, 216, 179, 216, 248, 85, 84, 5, 217, 226, + 221, 13, 85, 84, 5, 218, 10, 221, 21, 85, 84, 5, 218, 28, 221, 9, 85, 84, + 5, 218, 59, 221, 16, 85, 84, 5, 217, 250, 221, 17, 85, 84, 5, 217, 246, + 221, 11, 85, 84, 5, 217, 200, 221, 12, 85, 84, 5, 217, 234, 231, 174, 85, + 84, 5, 218, 46, 231, 182, 85, 84, 5, 217, 210, 231, 169, 85, 84, 5, 218, + 9, 231, 178, 85, 84, 5, 217, 251, 231, 179, 85, 84, 5, 218, 31, 231, 170, + 85, 84, 5, 218, 32, 231, 172, 85, 84, 5, 217, 187, 165, 85, 84, 5, 217, + 235, 214, 147, 85, 84, 5, 217, 229, 214, 162, 85, 84, 5, 217, 233, 214, + 129, 85, 84, 5, 217, 167, 214, 153, 85, 84, 5, 217, 239, 214, 154, 85, + 84, 5, 218, 35, 214, 134, 85, 84, 5, 218, 38, 214, 138, 85, 84, 5, 217, + 206, 213, 157, 85, 84, 5, 217, 166, 213, 127, 85, 84, 5, 217, 209, 213, + 148, 85, 84, 5, 217, 224, 213, 131, 85, 84, 5, 217, 176, 195, 69, 85, 84, + 5, 217, 173, 195, 188, 85, 84, 5, 217, 207, 193, 249, 85, 84, 5, 217, + 185, 195, 148, 85, 84, 5, 218, 17, 195, 153, 85, 84, 5, 217, 214, 195, 8, + 85, 84, 5, 218, 25, 195, 24, 85, 84, 5, 217, 194, 212, 74, 85, 84, 5, + 218, 44, 212, 94, 85, 84, 5, 217, 188, 212, 56, 85, 84, 5, 218, 4, 212, + 86, 85, 84, 5, 218, 42, 212, 63, 85, 84, 17, 107, 85, 84, 17, 109, 85, + 84, 17, 138, 85, 84, 17, 134, 85, 84, 17, 149, 85, 84, 17, 169, 85, 84, + 17, 175, 85, 84, 17, 171, 85, 84, 17, 178, 85, 84, 33, 31, 199, 119, 85, + 84, 33, 31, 199, 90, 85, 84, 33, 31, 228, 138, 85, 84, 33, 31, 198, 228, + 85, 84, 33, 31, 199, 96, 198, 228, 85, 84, 33, 31, 228, 141, 198, 228, + 85, 84, 33, 31, 216, 47, 252, 33, 6, 1, 251, 180, 252, 33, 6, 1, 238, 29, + 252, 33, 6, 1, 220, 123, 252, 33, 6, 1, 216, 60, 252, 33, 6, 1, 249, 153, + 252, 33, 6, 1, 202, 164, 252, 33, 6, 1, 210, 63, 252, 33, 6, 1, 248, 196, + 252, 33, 6, 1, 165, 252, 33, 6, 1, 71, 252, 33, 6, 1, 233, 109, 252, 33, + 6, 1, 68, 252, 33, 6, 1, 74, 252, 33, 6, 1, 237, 68, 252, 33, 6, 1, 192, + 34, 252, 33, 6, 1, 193, 133, 252, 33, 6, 1, 212, 130, 252, 33, 6, 1, 222, + 106, 252, 33, 6, 1, 170, 252, 33, 6, 1, 66, 252, 33, 6, 1, 222, 235, 252, + 33, 6, 1, 243, 95, 252, 33, 6, 1, 140, 252, 33, 6, 1, 208, 94, 252, 33, + 6, 1, 231, 240, 252, 33, 6, 1, 212, 101, 252, 33, 6, 1, 197, 94, 252, 33, + 6, 1, 213, 224, 252, 33, 6, 1, 195, 188, 252, 33, 6, 1, 221, 215, 252, + 33, 6, 1, 231, 179, 252, 33, 6, 1, 191, 108, 252, 33, 6, 1, 221, 12, 252, + 33, 6, 1, 203, 165, 252, 33, 2, 1, 251, 180, 252, 33, 2, 1, 238, 29, 252, + 33, 2, 1, 220, 123, 252, 33, 2, 1, 216, 60, 252, 33, 2, 1, 249, 153, 252, + 33, 2, 1, 202, 164, 252, 33, 2, 1, 210, 63, 252, 33, 2, 1, 248, 196, 252, + 33, 2, 1, 165, 252, 33, 2, 1, 71, 252, 33, 2, 1, 233, 109, 252, 33, 2, 1, + 68, 252, 33, 2, 1, 74, 252, 33, 2, 1, 237, 68, 252, 33, 2, 1, 192, 34, + 252, 33, 2, 1, 193, 133, 252, 33, 2, 1, 212, 130, 252, 33, 2, 1, 222, + 106, 252, 33, 2, 1, 170, 252, 33, 2, 1, 66, 252, 33, 2, 1, 222, 235, 252, + 33, 2, 1, 243, 95, 252, 33, 2, 1, 140, 252, 33, 2, 1, 208, 94, 252, 33, + 2, 1, 231, 240, 252, 33, 2, 1, 212, 101, 252, 33, 2, 1, 197, 94, 252, 33, + 2, 1, 213, 224, 252, 33, 2, 1, 195, 188, 252, 33, 2, 1, 221, 215, 252, + 33, 2, 1, 231, 179, 252, 33, 2, 1, 191, 108, 252, 33, 2, 1, 221, 12, 252, + 33, 2, 1, 203, 165, 252, 33, 251, 181, 219, 190, 252, 33, 18, 219, 190, + 252, 33, 231, 153, 77, 252, 33, 230, 57, 252, 33, 120, 215, 252, 252, 33, + 231, 154, 120, 215, 252, 252, 33, 212, 141, 252, 33, 214, 213, 77, 252, + 33, 17, 191, 77, 252, 33, 17, 107, 252, 33, 17, 109, 252, 33, 17, 138, + 252, 33, 17, 134, 252, 33, 17, 149, 252, 33, 17, 169, 252, 33, 17, 175, + 252, 33, 17, 171, 252, 33, 17, 178, 252, 33, 89, 233, 216, 77, 252, 33, + 89, 208, 13, 77, 223, 146, 143, 31, 107, 223, 146, 143, 31, 109, 223, + 146, 143, 31, 138, 223, 146, 143, 31, 134, 223, 146, 143, 31, 149, 223, + 146, 143, 31, 169, 223, 146, 143, 31, 175, 223, 146, 143, 31, 171, 223, + 146, 143, 31, 178, 223, 146, 143, 31, 199, 95, 223, 146, 143, 31, 197, + 32, 223, 146, 143, 31, 198, 249, 223, 146, 143, 31, 232, 135, 223, 146, + 143, 31, 233, 15, 223, 146, 143, 31, 202, 120, 223, 146, 143, 31, 203, + 241, 223, 146, 143, 31, 234, 153, 223, 146, 143, 31, 213, 169, 223, 146, + 143, 31, 91, 228, 140, 223, 146, 143, 31, 105, 228, 140, 223, 146, 143, + 31, 115, 228, 140, 223, 146, 143, 31, 232, 128, 228, 140, 223, 146, 143, + 31, 232, 226, 228, 140, 223, 146, 143, 31, 202, 136, 228, 140, 223, 146, + 143, 31, 203, 247, 228, 140, 223, 146, 143, 31, 234, 164, 228, 140, 223, + 146, 143, 31, 213, 175, 228, 140, 223, 146, 143, 31, 91, 189, 223, 146, + 143, 31, 105, 189, 223, 146, 143, 31, 115, 189, 223, 146, 143, 31, 232, + 128, 189, 223, 146, 143, 31, 232, 226, 189, 223, 146, 143, 31, 202, 136, + 189, 223, 146, 143, 31, 203, 247, 189, 223, 146, 143, 31, 234, 164, 189, + 223, 146, 143, 31, 213, 175, 189, 223, 146, 143, 31, 199, 96, 189, 223, + 146, 143, 31, 197, 33, 189, 223, 146, 143, 31, 198, 250, 189, 223, 146, + 143, 31, 232, 136, 189, 223, 146, 143, 31, 233, 16, 189, 223, 146, 143, + 31, 202, 121, 189, 223, 146, 143, 31, 203, 242, 189, 223, 146, 143, 31, + 234, 154, 189, 223, 146, 143, 31, 213, 170, 189, 223, 146, 143, 31, 220, + 41, 223, 146, 143, 31, 220, 40, 223, 146, 143, 220, 42, 77, 223, 146, + 143, 31, 222, 60, 223, 146, 143, 31, 222, 59, 223, 146, 143, 31, 208, + 227, 107, 223, 146, 143, 31, 208, 227, 109, 223, 146, 143, 31, 208, 227, + 138, 223, 146, 143, 31, 208, 227, 134, 223, 146, 143, 31, 208, 227, 149, + 223, 146, 143, 31, 208, 227, 169, 223, 146, 143, 31, 208, 227, 175, 223, + 146, 143, 31, 208, 227, 171, 223, 146, 143, 31, 208, 227, 178, 223, 146, + 143, 209, 106, 223, 146, 143, 232, 118, 91, 208, 22, 223, 146, 143, 232, + 118, 91, 230, 70, 223, 146, 143, 232, 118, 115, 208, 20, 223, 146, 143, + 206, 36, 77, 223, 146, 143, 31, 251, 157, 107, 223, 146, 143, 31, 251, + 157, 109, 223, 146, 143, 31, 251, 157, 199, 96, 189, 223, 146, 143, 251, + 157, 220, 42, 77, 211, 21, 143, 31, 107, 211, 21, 143, 31, 109, 211, 21, + 143, 31, 138, 211, 21, 143, 31, 134, 211, 21, 143, 31, 149, 211, 21, 143, + 31, 169, 211, 21, 143, 31, 175, 211, 21, 143, 31, 171, 211, 21, 143, 31, + 178, 211, 21, 143, 31, 199, 95, 211, 21, 143, 31, 197, 32, 211, 21, 143, + 31, 198, 249, 211, 21, 143, 31, 232, 135, 211, 21, 143, 31, 233, 15, 211, + 21, 143, 31, 202, 120, 211, 21, 143, 31, 203, 241, 211, 21, 143, 31, 234, + 153, 211, 21, 143, 31, 213, 169, 211, 21, 143, 31, 91, 228, 140, 211, 21, + 143, 31, 105, 228, 140, 211, 21, 143, 31, 115, 228, 140, 211, 21, 143, + 31, 232, 128, 228, 140, 211, 21, 143, 31, 232, 226, 228, 140, 211, 21, + 143, 31, 202, 136, 228, 140, 211, 21, 143, 31, 203, 247, 228, 140, 211, + 21, 143, 31, 234, 164, 228, 140, 211, 21, 143, 31, 213, 175, 228, 140, + 211, 21, 143, 31, 91, 189, 211, 21, 143, 31, 105, 189, 211, 21, 143, 31, + 115, 189, 211, 21, 143, 31, 232, 128, 189, 211, 21, 143, 31, 232, 226, + 189, 211, 21, 143, 31, 202, 136, 189, 211, 21, 143, 31, 203, 247, 189, + 211, 21, 143, 31, 234, 164, 189, 211, 21, 143, 31, 213, 175, 189, 211, + 21, 143, 31, 199, 96, 189, 211, 21, 143, 31, 197, 33, 189, 211, 21, 143, + 31, 198, 250, 189, 211, 21, 143, 31, 232, 136, 189, 211, 21, 143, 31, + 233, 16, 189, 211, 21, 143, 31, 202, 121, 189, 211, 21, 143, 31, 203, + 242, 189, 211, 21, 143, 31, 234, 154, 189, 211, 21, 143, 31, 213, 170, + 189, 211, 21, 143, 217, 49, 211, 21, 143, 251, 157, 31, 109, 211, 21, + 143, 251, 157, 31, 138, 211, 21, 143, 251, 157, 31, 134, 211, 21, 143, + 251, 157, 31, 149, 211, 21, 143, 251, 157, 31, 169, 211, 21, 143, 251, + 157, 31, 175, 211, 21, 143, 251, 157, 31, 171, 211, 21, 143, 251, 157, + 31, 178, 211, 21, 143, 251, 157, 31, 199, 95, 211, 21, 143, 251, 157, 31, + 232, 128, 228, 140, 211, 21, 143, 251, 157, 31, 202, 136, 228, 140, 211, + 21, 143, 251, 157, 31, 105, 189, 211, 21, 143, 251, 157, 31, 199, 96, + 189, 211, 21, 143, 232, 118, 91, 230, 70, 211, 21, 143, 232, 118, 91, + 202, 124, 9, 13, 251, 192, 9, 13, 248, 245, 9, 13, 223, 6, 9, 13, 238, 3, + 9, 13, 193, 133, 9, 13, 191, 113, 9, 13, 230, 81, 9, 13, 199, 219, 9, 13, + 192, 75, 9, 13, 222, 106, 9, 13, 220, 35, 9, 13, 216, 208, 9, 13, 213, + 24, 9, 13, 205, 46, 9, 13, 251, 230, 9, 13, 233, 46, 9, 13, 205, 192, 9, + 13, 208, 89, 9, 13, 207, 71, 9, 13, 203, 109, 9, 13, 199, 114, 9, 13, + 199, 29, 9, 13, 221, 210, 9, 13, 199, 41, 9, 13, 238, 26, 9, 13, 191, + 116, 9, 13, 231, 86, 9, 13, 236, 139, 248, 245, 9, 13, 236, 139, 213, 24, + 9, 13, 236, 139, 233, 46, 9, 13, 236, 139, 208, 89, 9, 13, 89, 248, 245, + 9, 13, 89, 223, 6, 9, 13, 89, 229, 210, 9, 13, 89, 230, 81, 9, 13, 89, + 192, 75, 9, 13, 89, 222, 106, 9, 13, 89, 220, 35, 9, 13, 89, 216, 208, 9, + 13, 89, 213, 24, 9, 13, 89, 205, 46, 9, 13, 89, 251, 230, 9, 13, 89, 233, + 46, 9, 13, 89, 205, 192, 9, 13, 89, 208, 89, 9, 13, 89, 203, 109, 9, 13, + 89, 199, 114, 9, 13, 89, 199, 29, 9, 13, 89, 221, 210, 9, 13, 89, 238, + 26, 9, 13, 89, 231, 86, 9, 13, 199, 214, 223, 6, 9, 13, 199, 214, 230, + 81, 9, 13, 199, 214, 192, 75, 9, 13, 199, 214, 220, 35, 9, 13, 199, 214, + 213, 24, 9, 13, 199, 214, 205, 46, 9, 13, 199, 214, 251, 230, 9, 13, 199, + 214, 205, 192, 9, 13, 199, 214, 208, 89, 9, 13, 199, 214, 203, 109, 9, + 13, 199, 214, 221, 210, 9, 13, 199, 214, 238, 26, 9, 13, 199, 214, 231, + 86, 9, 13, 199, 214, 236, 139, 213, 24, 9, 13, 199, 214, 236, 139, 208, + 89, 9, 13, 201, 36, 248, 245, 9, 13, 201, 36, 223, 6, 9, 13, 201, 36, + 229, 210, 9, 13, 201, 36, 230, 81, 9, 13, 201, 36, 199, 219, 9, 13, 201, + 36, 192, 75, 9, 13, 201, 36, 222, 106, 9, 13, 201, 36, 216, 208, 9, 13, + 201, 36, 213, 24, 9, 13, 201, 36, 205, 46, 9, 13, 201, 36, 251, 230, 9, + 13, 201, 36, 233, 46, 9, 13, 201, 36, 205, 192, 9, 13, 201, 36, 208, 89, + 9, 13, 201, 36, 203, 109, 9, 13, 201, 36, 199, 114, 9, 13, 201, 36, 199, + 29, 9, 13, 201, 36, 221, 210, 9, 13, 201, 36, 238, 26, 9, 13, 201, 36, + 191, 116, 9, 13, 201, 36, 231, 86, 9, 13, 201, 36, 236, 139, 248, 245, 9, + 13, 201, 36, 236, 139, 233, 46, 9, 13, 219, 3, 251, 192, 9, 13, 219, 3, + 248, 245, 9, 13, 219, 3, 223, 6, 9, 13, 219, 3, 238, 3, 9, 13, 219, 3, + 229, 210, 9, 13, 219, 3, 193, 133, 9, 13, 219, 3, 191, 113, 9, 13, 219, + 3, 230, 81, 9, 13, 219, 3, 199, 219, 9, 13, 219, 3, 192, 75, 9, 13, 219, + 3, 220, 35, 9, 13, 219, 3, 216, 208, 9, 13, 219, 3, 213, 24, 9, 13, 219, + 3, 205, 46, 9, 13, 219, 3, 251, 230, 9, 13, 219, 3, 233, 46, 9, 13, 219, + 3, 205, 192, 9, 13, 219, 3, 208, 89, 9, 13, 219, 3, 207, 71, 9, 13, 219, + 3, 203, 109, 9, 13, 219, 3, 199, 114, 9, 13, 219, 3, 199, 29, 9, 13, 219, + 3, 221, 210, 9, 13, 219, 3, 199, 41, 9, 13, 219, 3, 238, 26, 9, 13, 219, + 3, 191, 116, 9, 13, 219, 3, 231, 86, 9, 13, 235, 129, 248, 245, 9, 13, + 235, 129, 223, 6, 9, 13, 235, 129, 238, 3, 9, 13, 235, 129, 193, 133, 9, + 13, 235, 129, 191, 113, 9, 13, 235, 129, 230, 81, 9, 13, 235, 129, 199, + 219, 9, 13, 235, 129, 192, 75, 9, 13, 235, 129, 220, 35, 9, 13, 235, 129, + 216, 208, 9, 13, 235, 129, 213, 24, 9, 13, 235, 129, 205, 46, 9, 13, 235, + 129, 251, 230, 9, 13, 235, 129, 233, 46, 9, 13, 235, 129, 205, 192, 9, + 13, 235, 129, 208, 89, 9, 13, 235, 129, 207, 71, 9, 13, 235, 129, 203, + 109, 9, 13, 235, 129, 199, 114, 9, 13, 235, 129, 199, 29, 9, 13, 235, + 129, 221, 210, 9, 13, 235, 129, 199, 41, 9, 13, 235, 129, 238, 26, 9, 13, + 235, 129, 191, 116, 9, 13, 235, 129, 231, 86, 9, 13, 211, 67, 92, 4, 182, + 4, 199, 168, 9, 13, 211, 67, 182, 4, 238, 3, 217, 114, 123, 234, 204, + 193, 66, 217, 114, 123, 202, 2, 193, 66, 217, 114, 123, 193, 105, 193, + 66, 217, 114, 123, 186, 193, 66, 217, 114, 123, 207, 87, 235, 111, 217, + 114, 123, 230, 201, 235, 111, 217, 114, 123, 63, 235, 111, 217, 114, 123, + 91, 79, 243, 140, 217, 114, 123, 105, 79, 243, 140, 217, 114, 123, 115, + 79, 243, 140, 217, 114, 123, 232, 128, 79, 243, 140, 217, 114, 123, 232, + 226, 79, 243, 140, 217, 114, 123, 202, 136, 79, 243, 140, 217, 114, 123, + 203, 247, 79, 243, 140, 217, 114, 123, 234, 164, 79, 243, 140, 217, 114, + 123, 213, 175, 79, 243, 140, 217, 114, 123, 91, 79, 249, 102, 217, 114, + 123, 105, 79, 249, 102, 217, 114, 123, 115, 79, 249, 102, 217, 114, 123, + 232, 128, 79, 249, 102, 217, 114, 123, 232, 226, 79, 249, 102, 217, 114, + 123, 202, 136, 79, 249, 102, 217, 114, 123, 203, 247, 79, 249, 102, 217, + 114, 123, 234, 164, 79, 249, 102, 217, 114, 123, 213, 175, 79, 249, 102, + 217, 114, 123, 91, 79, 243, 7, 217, 114, 123, 105, 79, 243, 7, 217, 114, + 123, 115, 79, 243, 7, 217, 114, 123, 232, 128, 79, 243, 7, 217, 114, 123, + 232, 226, 79, 243, 7, 217, 114, 123, 202, 136, 79, 243, 7, 217, 114, 123, + 203, 247, 79, 243, 7, 217, 114, 123, 234, 164, 79, 243, 7, 217, 114, 123, + 213, 175, 79, 243, 7, 217, 114, 123, 209, 85, 217, 114, 123, 211, 53, + 217, 114, 123, 249, 103, 217, 114, 123, 243, 49, 217, 114, 123, 201, 196, + 217, 114, 123, 200, 200, 217, 114, 123, 250, 149, 217, 114, 123, 193, 56, + 217, 114, 123, 222, 194, 217, 114, 123, 249, 146, 236, 151, 123, 228, + 241, 249, 146, 236, 151, 123, 228, 239, 236, 151, 123, 228, 238, 236, + 151, 123, 228, 237, 236, 151, 123, 228, 236, 236, 151, 123, 228, 235, + 236, 151, 123, 228, 234, 236, 151, 123, 228, 233, 236, 151, 123, 228, + 232, 236, 151, 123, 228, 231, 236, 151, 123, 228, 230, 236, 151, 123, + 228, 229, 236, 151, 123, 228, 228, 236, 151, 123, 228, 227, 236, 151, + 123, 228, 226, 236, 151, 123, 228, 225, 236, 151, 123, 228, 224, 236, + 151, 123, 228, 223, 236, 151, 123, 228, 222, 236, 151, 123, 228, 221, + 236, 151, 123, 228, 220, 236, 151, 123, 228, 219, 236, 151, 123, 228, + 218, 236, 151, 123, 228, 217, 236, 151, 123, 228, 216, 236, 151, 123, + 228, 215, 236, 151, 123, 228, 214, 236, 151, 123, 228, 213, 236, 151, + 123, 228, 212, 236, 151, 123, 228, 211, 236, 151, 123, 228, 210, 236, + 151, 123, 228, 209, 236, 151, 123, 228, 208, 236, 151, 123, 228, 207, + 236, 151, 123, 228, 206, 236, 151, 123, 228, 205, 236, 151, 123, 228, + 204, 236, 151, 123, 228, 203, 236, 151, 123, 228, 202, 236, 151, 123, + 228, 201, 236, 151, 123, 228, 200, 236, 151, 123, 228, 199, 236, 151, + 123, 228, 198, 236, 151, 123, 228, 197, 236, 151, 123, 228, 196, 236, + 151, 123, 228, 195, 236, 151, 123, 228, 194, 236, 151, 123, 228, 193, + 236, 151, 123, 228, 192, 236, 151, 123, 228, 191, 236, 151, 123, 81, 249, + 146, 236, 151, 123, 195, 134, 236, 151, 123, 195, 133, 236, 151, 123, + 195, 132, 236, 151, 123, 195, 131, 236, 151, 123, 195, 130, 236, 151, + 123, 195, 129, 236, 151, 123, 195, 128, 236, 151, 123, 195, 127, 236, + 151, 123, 195, 126, 236, 151, 123, 195, 125, 236, 151, 123, 195, 124, + 236, 151, 123, 195, 123, 236, 151, 123, 195, 122, 236, 151, 123, 195, + 121, 236, 151, 123, 195, 120, 236, 151, 123, 195, 119, 236, 151, 123, + 195, 118, 236, 151, 123, 195, 117, 236, 151, 123, 195, 116, 236, 151, + 123, 195, 115, 236, 151, 123, 195, 114, 236, 151, 123, 195, 113, 236, + 151, 123, 195, 112, 236, 151, 123, 195, 111, 236, 151, 123, 195, 110, + 236, 151, 123, 195, 109, 236, 151, 123, 195, 108, 236, 151, 123, 195, + 107, 236, 151, 123, 195, 106, 236, 151, 123, 195, 105, 236, 151, 123, + 195, 104, 236, 151, 123, 195, 103, 236, 151, 123, 195, 102, 236, 151, + 123, 195, 101, 236, 151, 123, 195, 100, 236, 151, 123, 195, 99, 236, 151, + 123, 195, 98, 236, 151, 123, 195, 97, 236, 151, 123, 195, 96, 236, 151, + 123, 195, 95, 236, 151, 123, 195, 94, 236, 151, 123, 195, 93, 236, 151, + 123, 195, 92, 236, 151, 123, 195, 91, 236, 151, 123, 195, 90, 236, 151, + 123, 195, 89, 236, 151, 123, 195, 88, 236, 151, 123, 195, 87, 236, 151, + 123, 195, 86, 209, 95, 247, 101, 249, 146, 209, 95, 247, 101, 252, 53, + 79, 201, 244, 209, 95, 247, 101, 105, 79, 201, 244, 209, 95, 247, 101, + 115, 79, 201, 244, 209, 95, 247, 101, 232, 128, 79, 201, 244, 209, 95, + 247, 101, 232, 226, 79, 201, 244, 209, 95, 247, 101, 202, 136, 79, 201, + 244, 209, 95, 247, 101, 203, 247, 79, 201, 244, 209, 95, 247, 101, 234, + 164, 79, 201, 244, 209, 95, 247, 101, 213, 175, 79, 201, 244, 209, 95, + 247, 101, 199, 96, 79, 201, 244, 209, 95, 247, 101, 223, 30, 79, 201, + 244, 209, 95, 247, 101, 221, 77, 79, 201, 244, 209, 95, 247, 101, 208, + 15, 79, 201, 244, 209, 95, 247, 101, 221, 139, 79, 201, 244, 209, 95, + 247, 101, 252, 53, 79, 229, 221, 209, 95, 247, 101, 105, 79, 229, 221, + 209, 95, 247, 101, 115, 79, 229, 221, 209, 95, 247, 101, 232, 128, 79, + 229, 221, 209, 95, 247, 101, 232, 226, 79, 229, 221, 209, 95, 247, 101, + 202, 136, 79, 229, 221, 209, 95, 247, 101, 203, 247, 79, 229, 221, 209, + 95, 247, 101, 234, 164, 79, 229, 221, 209, 95, 247, 101, 213, 175, 79, + 229, 221, 209, 95, 247, 101, 199, 96, 79, 229, 221, 209, 95, 247, 101, + 223, 30, 79, 229, 221, 209, 95, 247, 101, 221, 77, 79, 229, 221, 209, 95, + 247, 101, 208, 15, 79, 229, 221, 209, 95, 247, 101, 221, 139, 79, 229, + 221, 209, 95, 247, 101, 207, 87, 222, 194, 209, 95, 247, 101, 252, 53, + 79, 237, 31, 209, 95, 247, 101, 105, 79, 237, 31, 209, 95, 247, 101, 115, + 79, 237, 31, 209, 95, 247, 101, 232, 128, 79, 237, 31, 209, 95, 247, 101, + 232, 226, 79, 237, 31, 209, 95, 247, 101, 202, 136, 79, 237, 31, 209, 95, + 247, 101, 203, 247, 79, 237, 31, 209, 95, 247, 101, 234, 164, 79, 237, + 31, 209, 95, 247, 101, 213, 175, 79, 237, 31, 209, 95, 247, 101, 199, 96, + 79, 237, 31, 209, 95, 247, 101, 223, 30, 79, 237, 31, 209, 95, 247, 101, + 221, 77, 79, 237, 31, 209, 95, 247, 101, 208, 15, 79, 237, 31, 209, 95, + 247, 101, 221, 139, 79, 237, 31, 209, 95, 247, 101, 62, 222, 194, 209, + 95, 247, 101, 252, 53, 79, 242, 204, 209, 95, 247, 101, 105, 79, 242, + 204, 209, 95, 247, 101, 115, 79, 242, 204, 209, 95, 247, 101, 232, 128, + 79, 242, 204, 209, 95, 247, 101, 232, 226, 79, 242, 204, 209, 95, 247, + 101, 202, 136, 79, 242, 204, 209, 95, 247, 101, 203, 247, 79, 242, 204, + 209, 95, 247, 101, 234, 164, 79, 242, 204, 209, 95, 247, 101, 213, 175, + 79, 242, 204, 209, 95, 247, 101, 199, 96, 79, 242, 204, 209, 95, 247, + 101, 223, 30, 79, 242, 204, 209, 95, 247, 101, 221, 77, 79, 242, 204, + 209, 95, 247, 101, 208, 15, 79, 242, 204, 209, 95, 247, 101, 221, 139, + 79, 242, 204, 209, 95, 247, 101, 63, 222, 194, 209, 95, 247, 101, 232, + 160, 209, 95, 247, 101, 197, 200, 209, 95, 247, 101, 197, 189, 209, 95, + 247, 101, 197, 186, 209, 95, 247, 101, 197, 185, 209, 95, 247, 101, 197, + 184, 209, 95, 247, 101, 197, 183, 209, 95, 247, 101, 197, 182, 209, 95, + 247, 101, 197, 181, 209, 95, 247, 101, 197, 180, 209, 95, 247, 101, 197, + 199, 209, 95, 247, 101, 197, 198, 209, 95, 247, 101, 197, 197, 209, 95, + 247, 101, 197, 196, 209, 95, 247, 101, 197, 195, 209, 95, 247, 101, 197, + 194, 209, 95, 247, 101, 197, 193, 209, 95, 247, 101, 197, 192, 209, 95, + 247, 101, 197, 191, 209, 95, 247, 101, 197, 190, 209, 95, 247, 101, 197, + 188, 209, 95, 247, 101, 197, 187, 17, 191, 78, 232, 80, 201, 63, 17, 191, + 78, 242, 74, 17, 91, 242, 74, 17, 105, 242, 74, 17, 115, 242, 74, 17, + 232, 128, 242, 74, 17, 232, 226, 242, 74, 17, 202, 136, 242, 74, 17, 203, + 247, 242, 74, 17, 234, 164, 242, 74, 17, 213, 175, 242, 74, 236, 241, 47, + 49, 17, 191, 77, 236, 241, 214, 106, 47, 49, 17, 191, 77, 47, 191, 78, 4, + 202, 97, 47, 251, 85, 57, 47, 236, 155, 3, 4, 211, 4, 249, 141, 127, 8, + 6, 1, 65, 127, 8, 6, 1, 250, 120, 127, 8, 6, 1, 247, 193, 127, 8, 6, 1, + 238, 127, 127, 8, 6, 1, 71, 127, 8, 6, 1, 233, 175, 127, 8, 6, 1, 232, + 51, 127, 8, 6, 1, 230, 116, 127, 8, 6, 1, 68, 127, 8, 6, 1, 223, 35, 127, + 8, 6, 1, 222, 152, 127, 8, 6, 1, 172, 127, 8, 6, 1, 218, 168, 127, 8, 6, + 1, 215, 61, 127, 8, 6, 1, 74, 127, 8, 6, 1, 210, 236, 127, 8, 6, 1, 208, + 104, 127, 8, 6, 1, 146, 127, 8, 6, 1, 206, 8, 127, 8, 6, 1, 200, 43, 127, + 8, 6, 1, 66, 127, 8, 6, 1, 196, 12, 127, 8, 6, 1, 193, 224, 127, 8, 6, 1, + 192, 235, 127, 8, 6, 1, 192, 159, 127, 8, 6, 1, 191, 166, 198, 42, 203, + 103, 248, 52, 8, 6, 1, 206, 8, 47, 43, 8, 6, 1, 247, 193, 47, 43, 8, 6, + 1, 146, 47, 247, 43, 47, 192, 237, 239, 7, 113, 112, 8, 6, 1, 65, 112, 8, + 6, 1, 250, 120, 112, 8, 6, 1, 247, 193, 112, 8, 6, 1, 238, 127, 112, 8, + 6, 1, 71, 112, 8, 6, 1, 233, 175, 112, 8, 6, 1, 232, 51, 112, 8, 6, 1, + 230, 116, 112, 8, 6, 1, 68, 112, 8, 6, 1, 223, 35, 112, 8, 6, 1, 222, + 152, 112, 8, 6, 1, 172, 112, 8, 6, 1, 218, 168, 112, 8, 6, 1, 215, 61, + 112, 8, 6, 1, 74, 112, 8, 6, 1, 210, 236, 112, 8, 6, 1, 208, 104, 112, 8, + 6, 1, 146, 112, 8, 6, 1, 206, 8, 112, 8, 6, 1, 200, 43, 112, 8, 6, 1, 66, + 112, 8, 6, 1, 196, 12, 112, 8, 6, 1, 193, 224, 112, 8, 6, 1, 192, 235, + 112, 8, 6, 1, 192, 159, 112, 8, 6, 1, 191, 166, 112, 228, 126, 112, 215, + 87, 112, 205, 70, 112, 201, 178, 112, 208, 248, 112, 193, 126, 214, 106, + 47, 8, 6, 1, 65, 214, 106, 47, 8, 6, 1, 250, 120, 214, 106, 47, 8, 6, 1, + 247, 193, 214, 106, 47, 8, 6, 1, 238, 127, 214, 106, 47, 8, 6, 1, 71, + 214, 106, 47, 8, 6, 1, 233, 175, 214, 106, 47, 8, 6, 1, 232, 51, 214, + 106, 47, 8, 6, 1, 230, 116, 214, 106, 47, 8, 6, 1, 68, 214, 106, 47, 8, + 6, 1, 223, 35, 214, 106, 47, 8, 6, 1, 222, 152, 214, 106, 47, 8, 6, 1, + 172, 214, 106, 47, 8, 6, 1, 218, 168, 214, 106, 47, 8, 6, 1, 215, 61, + 214, 106, 47, 8, 6, 1, 74, 214, 106, 47, 8, 6, 1, 210, 236, 214, 106, 47, + 8, 6, 1, 208, 104, 214, 106, 47, 8, 6, 1, 146, 214, 106, 47, 8, 6, 1, + 206, 8, 214, 106, 47, 8, 6, 1, 200, 43, 214, 106, 47, 8, 6, 1, 66, 214, + 106, 47, 8, 6, 1, 196, 12, 214, 106, 47, 8, 6, 1, 193, 224, 214, 106, 47, + 8, 6, 1, 192, 235, 214, 106, 47, 8, 6, 1, 192, 159, 214, 106, 47, 8, 6, + 1, 191, 166, 207, 147, 216, 239, 56, 207, 147, 216, 235, 56, 207, 147, + 215, 164, 56, 47, 247, 66, 47, 247, 194, 4, 211, 4, 249, 141, 47, 228, + 145, 233, 12, 214, 106, 112, 8, 6, 1, 65, 214, 106, 112, 8, 6, 1, 250, + 120, 214, 106, 112, 8, 6, 1, 247, 193, 214, 106, 112, 8, 6, 1, 238, 127, + 214, 106, 112, 8, 6, 1, 71, 214, 106, 112, 8, 6, 1, 233, 175, 214, 106, + 112, 8, 6, 1, 232, 51, 214, 106, 112, 8, 6, 1, 230, 116, 214, 106, 112, + 8, 6, 1, 68, 214, 106, 112, 8, 6, 1, 223, 35, 214, 106, 112, 8, 6, 1, + 222, 152, 214, 106, 112, 8, 6, 1, 172, 214, 106, 112, 8, 6, 1, 218, 168, + 214, 106, 112, 8, 6, 1, 215, 61, 214, 106, 112, 8, 6, 1, 74, 214, 106, + 112, 8, 6, 1, 210, 236, 214, 106, 112, 8, 6, 1, 208, 104, 214, 106, 112, + 8, 6, 1, 146, 214, 106, 112, 8, 6, 1, 206, 8, 214, 106, 112, 8, 6, 1, + 200, 43, 214, 106, 112, 8, 6, 1, 66, 214, 106, 112, 8, 6, 1, 196, 12, + 214, 106, 112, 8, 6, 1, 193, 224, 214, 106, 112, 8, 6, 1, 192, 235, 214, + 106, 112, 8, 6, 1, 192, 159, 214, 106, 112, 8, 6, 1, 191, 166, 238, 214, + 214, 106, 112, 8, 6, 1, 210, 236, 214, 106, 112, 228, 28, 214, 106, 112, + 168, 214, 106, 112, 188, 214, 106, 112, 252, 155, 214, 106, 112, 193, + 126, 51, 236, 194, 112, 242, 247, 112, 239, 14, 112, 232, 108, 112, 228, + 19, 112, 214, 79, 112, 214, 70, 112, 211, 125, 112, 202, 9, 112, 133, 4, + 233, 216, 77, 112, 194, 252, 112, 115, 238, 127, 112, 205, 57, 205, 76, + 112, 105, 222, 152, 112, 232, 128, 222, 152, 112, 234, 164, 222, 152, + 112, 232, 226, 209, 62, 107, 112, 203, 247, 209, 62, 107, 112, 197, 21, + 209, 62, 109, 112, 202, 121, 210, 236, 112, 91, 228, 141, 197, 33, 210, + 236, 112, 8, 2, 1, 238, 127, 112, 229, 248, 112, 229, 247, 112, 229, 150, + 112, 218, 252, 112, 202, 241, 112, 196, 140, 112, 195, 21, 217, 36, 193, + 21, 113, 207, 79, 223, 145, 16, 1, 65, 207, 79, 223, 145, 16, 1, 250, + 120, 207, 79, 223, 145, 16, 1, 247, 193, 207, 79, 223, 145, 16, 1, 238, + 127, 207, 79, 223, 145, 16, 1, 71, 207, 79, 223, 145, 16, 1, 233, 175, + 207, 79, 223, 145, 16, 1, 232, 51, 207, 79, 223, 145, 16, 1, 230, 116, + 207, 79, 223, 145, 16, 1, 68, 207, 79, 223, 145, 16, 1, 223, 35, 207, 79, + 223, 145, 16, 1, 222, 152, 207, 79, 223, 145, 16, 1, 172, 207, 79, 223, + 145, 16, 1, 218, 168, 207, 79, 223, 145, 16, 1, 215, 61, 207, 79, 223, + 145, 16, 1, 74, 207, 79, 223, 145, 16, 1, 210, 236, 207, 79, 223, 145, + 16, 1, 208, 104, 207, 79, 223, 145, 16, 1, 146, 207, 79, 223, 145, 16, 1, + 206, 8, 207, 79, 223, 145, 16, 1, 200, 43, 207, 79, 223, 145, 16, 1, 66, + 207, 79, 223, 145, 16, 1, 196, 12, 207, 79, 223, 145, 16, 1, 193, 224, + 207, 79, 223, 145, 16, 1, 192, 235, 207, 79, 223, 145, 16, 1, 192, 159, + 207, 79, 223, 145, 16, 1, 191, 166, 51, 229, 120, 229, 9, 112, 72, 221, + 49, 112, 72, 188, 112, 12, 196, 95, 225, 217, 112, 12, 196, 95, 225, 221, + 112, 12, 196, 95, 225, 229, 112, 72, 237, 146, 112, 12, 196, 95, 225, + 236, 112, 12, 196, 95, 225, 223, 112, 12, 196, 95, 225, 195, 112, 12, + 196, 95, 225, 222, 112, 12, 196, 95, 225, 235, 112, 12, 196, 95, 225, + 209, 112, 12, 196, 95, 225, 202, 112, 12, 196, 95, 225, 211, 112, 12, + 196, 95, 225, 232, 112, 12, 196, 95, 225, 218, 112, 12, 196, 95, 225, + 234, 112, 12, 196, 95, 225, 210, 112, 12, 196, 95, 225, 233, 112, 12, + 196, 95, 225, 196, 112, 12, 196, 95, 225, 201, 112, 12, 196, 95, 225, + 194, 112, 12, 196, 95, 225, 224, 112, 12, 196, 95, 225, 226, 112, 12, + 196, 95, 225, 204, 112, 12, 196, 95, 225, 215, 112, 12, 196, 95, 225, + 213, 112, 12, 196, 95, 225, 239, 112, 12, 196, 95, 225, 238, 112, 12, + 196, 95, 225, 192, 112, 12, 196, 95, 225, 219, 112, 12, 196, 95, 225, + 237, 112, 12, 196, 95, 225, 228, 112, 12, 196, 95, 225, 214, 112, 12, + 196, 95, 225, 193, 112, 12, 196, 95, 225, 216, 112, 12, 196, 95, 225, + 198, 112, 12, 196, 95, 225, 197, 112, 12, 196, 95, 225, 227, 112, 12, + 196, 95, 225, 205, 112, 12, 196, 95, 225, 207, 112, 12, 196, 95, 225, + 208, 112, 12, 196, 95, 225, 200, 112, 12, 196, 95, 225, 231, 112, 12, + 196, 95, 225, 225, 112, 12, 196, 95, 225, 191, 198, 42, 203, 103, 248, + 52, 12, 196, 95, 225, 206, 198, 42, 203, 103, 248, 52, 12, 196, 95, 225, + 238, 198, 42, 203, 103, 248, 52, 12, 196, 95, 225, 236, 198, 42, 203, + 103, 248, 52, 12, 196, 95, 225, 220, 198, 42, 203, 103, 248, 52, 12, 196, + 95, 225, 203, 198, 42, 203, 103, 248, 52, 12, 196, 95, 225, 216, 198, 42, + 203, 103, 248, 52, 12, 196, 95, 225, 199, 198, 42, 203, 103, 248, 52, 12, + 196, 95, 225, 230, 198, 42, 203, 103, 248, 52, 12, 196, 95, 225, 212, 47, + 228, 14, 252, 27, 47, 228, 14, 252, 58, 206, 113, 16, 40, 232, 86, 206, + 113, 16, 40, 218, 225, 206, 113, 16, 40, 203, 23, 206, 113, 16, 40, 192, + 207, 206, 113, 16, 40, 203, 2, 206, 113, 16, 40, 247, 148, 238, 139, 232, + 173, 242, 219, 196, 117, 213, 191, 4, 201, 99, 200, 193, 139, 215, 183, + 200, 192, 242, 251, 250, 183, 235, 61, 200, 191, 139, 247, 253, 207, 148, + 248, 29, 250, 183, 213, 190, 193, 144, 193, 138, 195, 14, 216, 52, 193, + 128, 234, 208, 231, 12, 233, 232, 234, 208, 231, 12, 251, 140, 234, 208, + 231, 12, 250, 202, 231, 12, 4, 216, 177, 214, 80, 215, 206, 113, 193, + 130, 238, 228, 215, 206, 113, 232, 238, 208, 23, 215, 206, 113, 193, 130, + 231, 49, 215, 206, 113, 232, 80, 215, 206, 113, 193, 159, 231, 49, 215, + 206, 113, 220, 6, 208, 23, 215, 206, 113, 193, 159, 238, 228, 215, 206, + 113, 238, 228, 215, 205, 214, 80, 215, 206, 4, 233, 103, 232, 238, 208, + 23, 215, 206, 4, 233, 103, 220, 6, 208, 23, 215, 206, 4, 233, 103, 232, + 80, 215, 206, 4, 233, 103, 200, 199, 4, 233, 103, 231, 8, 201, 102, 203, + 45, 201, 102, 199, 21, 62, 235, 97, 63, 200, 198, 63, 200, 199, 4, 2, + 242, 210, 63, 200, 199, 248, 242, 242, 210, 63, 200, 199, 248, 242, 242, + 211, 4, 207, 149, 242, 211, 4, 207, 149, 242, 211, 4, 202, 52, 242, 211, + 4, 219, 129, 242, 211, 4, 198, 46, 232, 174, 193, 67, 248, 116, 233, 103, + 228, 181, 236, 162, 199, 227, 247, 228, 243, 103, 205, 48, 233, 226, 197, + 254, 237, 139, 197, 254, 210, 183, 197, 254, 247, 153, 228, 181, 210, 15, + 197, 78, 243, 107, 248, 119, 206, 126, 229, 149, 200, 196, 248, 119, 234, + 212, 79, 217, 103, 234, 212, 79, 206, 245, 229, 193, 232, 128, 219, 234, + 242, 209, 217, 69, 219, 233, 233, 84, 219, 233, 219, 234, 232, 181, 223, + 163, 193, 66, 215, 98, 198, 83, 250, 162, 230, 218, 216, 196, 193, 142, + 199, 187, 219, 201, 249, 98, 209, 133, 207, 87, 251, 46, 230, 201, 251, + 46, 210, 55, 210, 59, 243, 108, 201, 42, 230, 63, 202, 89, 79, 209, 112, + 216, 225, 211, 105, 248, 98, 209, 9, 219, 212, 206, 246, 238, 234, 206, + 246, 249, 111, 239, 17, 206, 245, 238, 167, 23, 206, 245, 201, 83, 248, + 66, 201, 243, 248, 43, 232, 106, 232, 102, 206, 152, 200, 142, 209, 12, + 237, 235, 211, 153, 200, 165, 232, 103, 203, 13, 232, 237, 247, 147, 4, + 200, 134, 237, 80, 202, 32, 228, 27, 238, 232, 203, 121, 228, 26, 228, + 27, 238, 232, 235, 126, 239, 16, 243, 66, 164, 247, 118, 219, 24, 238, + 158, 228, 254, 209, 14, 203, 29, 248, 222, 248, 62, 209, 15, 79, 232, + 161, 239, 15, 232, 150, 23, 221, 78, 199, 133, 193, 51, 230, 31, 205, + 176, 248, 79, 23, 238, 181, 193, 63, 231, 16, 242, 94, 231, 16, 197, 204, + 235, 104, 248, 253, 215, 140, 242, 226, 248, 253, 215, 139, 249, 149, + 248, 78, 232, 150, 23, 221, 79, 4, 209, 97, 248, 79, 4, 209, 30, 239, 3, + 209, 32, 206, 247, 193, 11, 208, 222, 248, 157, 247, 146, 223, 29, 243, + 56, 197, 254, 233, 67, 243, 55, 232, 240, 232, 241, 201, 241, 249, 109, + 210, 102, 209, 31, 239, 54, 249, 111, 199, 191, 197, 254, 238, 214, 232, + 211, 209, 134, 237, 136, 223, 19, 236, 154, 247, 90, 201, 41, 193, 67, + 243, 82, 215, 206, 195, 54, 247, 8, 205, 90, 205, 120, 230, 225, 247, + 111, 229, 224, 4, 198, 136, 211, 105, 199, 34, 219, 224, 248, 72, 79, + 232, 185, 216, 54, 216, 219, 207, 58, 206, 247, 37, 221, 221, 4, 223, 28, + 201, 11, 216, 89, 219, 168, 202, 86, 239, 22, 221, 72, 249, 13, 250, 213, + 37, 213, 1, 249, 13, 237, 86, 37, 213, 1, 233, 0, 232, 112, 252, 31, 198, + 180, 247, 91, 228, 183, 233, 33, 193, 93, 206, 139, 242, 97, 232, 232, + 209, 53, 23, 232, 236, 216, 89, 215, 169, 247, 132, 243, 14, 229, 231, + 250, 224, 210, 188, 198, 54, 230, 9, 243, 0, 199, 87, 198, 181, 242, 242, + 248, 107, 210, 6, 250, 222, 195, 65, 231, 214, 236, 234, 229, 117, 202, + 79, 217, 148, 248, 170, 231, 215, 237, 24, 248, 65, 232, 187, 209, 95, + 247, 99, 37, 213, 6, 215, 129, 37, 213, 1, 205, 104, 230, 162, 37, 221, + 220, 197, 179, 195, 42, 37, 205, 82, 206, 42, 203, 60, 4, 205, 123, 199, + 92, 207, 170, 23, 249, 111, 202, 109, 23, 202, 109, 248, 91, 249, 68, 23, + 228, 247, 243, 109, 232, 217, 202, 51, 206, 43, 200, 170, 201, 202, 216, + 219, 197, 205, 228, 184, 207, 171, 251, 141, 232, 158, 206, 56, 232, 158, + 200, 137, 193, 110, 219, 134, 230, 249, 207, 172, 215, 191, 207, 172, + 247, 102, 238, 225, 249, 65, 23, 249, 111, 195, 13, 233, 22, 229, 12, + 201, 75, 23, 249, 111, 228, 27, 229, 12, 201, 75, 23, 208, 157, 199, 234, + 199, 92, 210, 207, 23, 249, 111, 202, 53, 247, 107, 215, 184, 247, 130, + 249, 16, 4, 196, 117, 247, 255, 239, 36, 228, 173, 247, 253, 242, 250, + 237, 90, 228, 173, 247, 254, 242, 240, 247, 254, 237, 82, 237, 83, 223, + 60, 214, 208, 210, 109, 201, 113, 228, 173, 247, 254, 228, 173, 4, 231, + 198, 211, 144, 247, 254, 223, 19, 209, 20, 211, 143, 233, 231, 209, 20, + 211, 143, 228, 182, 249, 92, 250, 151, 199, 102, 217, 148, 228, 178, 218, + 242, 228, 178, 239, 20, 201, 57, 205, 89, 237, 94, 201, 57, 233, 92, 223, + 40, 220, 18, 223, 19, 247, 80, 233, 231, 247, 80, 63, 210, 28, 62, 210, + 28, 193, 136, 63, 232, 217, 193, 136, 62, 232, 217, 206, 125, 62, 206, + 125, 220, 117, 249, 132, 207, 170, 23, 202, 244, 248, 70, 23, 57, 251, + 136, 234, 109, 52, 232, 227, 196, 253, 234, 109, 52, 232, 227, 196, 250, + 234, 109, 52, 232, 227, 196, 248, 234, 109, 52, 232, 227, 196, 246, 234, + 109, 52, 232, 227, 196, 244, 207, 130, 215, 181, 210, 247, 193, 144, 248, + 3, 238, 239, 198, 173, 219, 185, 207, 174, 247, 78, 235, 111, 238, 223, + 193, 96, 202, 60, 202, 58, 228, 183, 207, 142, 230, 255, 203, 107, 215, + 225, 206, 129, 243, 93, 236, 162, 209, 147, 248, 109, 234, 131, 211, 156, + 201, 218, 203, 102, 248, 2, 251, 89, 228, 253, 220, 108, 248, 251, 232, + 236, 197, 204, 232, 236, 248, 117, 197, 55, 230, 7, 243, 94, 249, 149, + 243, 94, 232, 96, 249, 149, 243, 94, 248, 160, 210, 30, 221, 61, 209, 36, + 235, 101, 247, 134, 249, 137, 247, 134, 236, 153, 215, 182, 233, 103, + 238, 240, 233, 103, 198, 174, 233, 103, 207, 175, 233, 103, 247, 79, 233, + 103, 235, 112, 233, 103, 201, 200, 193, 96, 228, 184, 233, 103, 215, 226, + 233, 103, 236, 163, 233, 103, 209, 148, 233, 103, 232, 100, 233, 103, + 230, 59, 233, 103, 193, 38, 233, 103, 249, 10, 233, 103, 210, 162, 233, + 103, 209, 148, 213, 13, 210, 76, 208, 208, 243, 77, 233, 185, 233, 193, + 234, 211, 213, 13, 215, 179, 198, 61, 63, 133, 209, 58, 249, 144, 223, + 148, 63, 144, 209, 58, 249, 144, 223, 148, 63, 45, 209, 58, 249, 144, + 223, 148, 63, 50, 209, 58, 249, 144, 223, 148, 232, 230, 230, 54, 56, + 193, 136, 230, 54, 56, 211, 126, 230, 54, 56, 198, 211, 133, 56, 198, + 211, 144, 56, 242, 241, 230, 29, 56, 211, 77, 230, 29, 56, 238, 208, 193, + 34, 230, 9, 233, 188, 214, 111, 200, 41, 223, 9, 235, 106, 221, 142, 248, + 173, 193, 34, 242, 212, 208, 137, 230, 33, 209, 10, 217, 78, 203, 52, + 250, 178, 203, 52, 229, 134, 203, 52, 193, 34, 205, 139, 193, 34, 248, + 90, 232, 156, 247, 220, 223, 163, 202, 187, 247, 219, 223, 163, 202, 187, + 248, 60, 231, 28, 217, 90, 193, 35, 233, 81, 217, 91, 23, 193, 36, 229, + 6, 230, 28, 105, 216, 187, 229, 6, 230, 28, 105, 193, 33, 229, 6, 230, + 28, 209, 50, 211, 142, 193, 36, 4, 247, 239, 234, 209, 248, 30, 4, 195, + 144, 209, 251, 4, 248, 121, 230, 78, 217, 91, 4, 230, 176, 209, 186, 217, + 73, 217, 91, 4, 197, 63, 211, 118, 217, 90, 211, 118, 193, 35, 249, 148, + 239, 37, 193, 19, 208, 213, 223, 19, 211, 137, 223, 19, 230, 254, 231, + 61, 249, 149, 251, 120, 233, 198, 251, 182, 251, 183, 215, 215, 223, 168, + 202, 103, 223, 137, 237, 79, 209, 250, 230, 170, 237, 240, 219, 95, 214, + 235, 209, 48, 233, 104, 217, 33, 230, 77, 249, 86, 209, 52, 200, 62, 209, + 140, 221, 123, 77, 218, 242, 219, 175, 206, 188, 231, 155, 201, 65, 221, + 122, 248, 71, 238, 243, 4, 229, 223, 193, 117, 249, 6, 229, 223, 248, 22, + 229, 223, 105, 229, 221, 201, 239, 229, 223, 230, 186, 229, 223, 229, + 224, 4, 57, 248, 115, 229, 223, 230, 201, 229, 223, 192, 73, 229, 223, + 208, 138, 229, 223, 229, 224, 4, 206, 247, 207, 12, 229, 221, 229, 224, + 237, 136, 237, 33, 203, 135, 4, 42, 75, 223, 117, 234, 135, 156, 247, + 251, 251, 119, 113, 248, 99, 202, 92, 113, 242, 85, 113, 201, 212, 200, + 144, 113, 235, 97, 237, 216, 113, 209, 141, 79, 209, 37, 232, 199, 248, + 185, 236, 195, 113, 201, 230, 249, 109, 198, 231, 249, 109, 63, 232, 186, + 228, 141, 209, 56, 113, 215, 230, 249, 130, 238, 170, 233, 218, 88, 236, + 155, 56, 238, 230, 247, 100, 249, 91, 4, 192, 71, 56, 249, 91, 4, 236, + 155, 56, 249, 91, 4, 233, 234, 56, 249, 91, 4, 209, 8, 56, 215, 230, 4, + 193, 60, 243, 137, 4, 196, 66, 197, 250, 23, 192, 71, 56, 205, 60, 209, + 249, 239, 59, 248, 28, 216, 41, 232, 191, 236, 220, 211, 60, 236, 226, + 235, 55, 233, 7, 232, 171, 211, 77, 233, 7, 232, 171, 210, 205, 4, 238, + 175, 210, 205, 233, 96, 196, 77, 247, 140, 199, 130, 247, 140, 247, 101, + 223, 148, 243, 137, 4, 196, 66, 197, 249, 243, 137, 4, 235, 119, 197, + 249, 249, 88, 243, 136, 242, 225, 208, 133, 206, 115, 208, 133, 210, 134, + 201, 53, 206, 50, 197, 238, 206, 50, 248, 95, 199, 232, 219, 229, 213, 4, + 213, 5, 4, 237, 135, 238, 242, 242, 219, 248, 96, 211, 77, 248, 96, 230, + 201, 248, 96, 248, 115, 248, 96, 211, 55, 248, 96, 248, 93, 214, 228, + 249, 134, 205, 73, 216, 188, 199, 107, 207, 101, 210, 203, 233, 64, 217, + 148, 205, 119, 251, 86, 208, 158, 252, 39, 218, 244, 243, 119, 216, 201, + 211, 13, 198, 2, 223, 159, 198, 2, 210, 212, 235, 8, 113, 223, 156, 234, + 67, 234, 68, 4, 235, 119, 64, 58, 242, 219, 217, 109, 4, 218, 235, 232, + 217, 242, 219, 217, 109, 4, 207, 147, 232, 217, 211, 77, 217, 109, 4, + 207, 147, 232, 217, 211, 77, 217, 109, 4, 218, 235, 232, 217, 209, 17, + 209, 18, 228, 187, 214, 75, 216, 4, 209, 194, 216, 4, 209, 195, 4, 96, + 64, 250, 183, 219, 224, 195, 68, 216, 3, 216, 4, 209, 195, 211, 145, 213, + 44, 216, 4, 209, 193, 251, 87, 4, 249, 76, 247, 132, 247, 133, 4, 232, + 208, 195, 65, 247, 132, 199, 104, 207, 165, 195, 64, 233, 0, 208, 193, + 209, 27, 201, 77, 208, 236, 249, 15, 197, 17, 96, 250, 231, 242, 221, 96, + 23, 118, 211, 77, 243, 11, 250, 231, 242, 221, 96, 23, 118, 211, 77, 243, + 11, 250, 232, 4, 47, 91, 210, 255, 242, 221, 235, 119, 23, 196, 66, 211, + 77, 243, 11, 250, 231, 251, 85, 235, 119, 23, 196, 66, 211, 77, 243, 11, + 250, 231, 130, 248, 26, 113, 137, 248, 26, 113, 201, 235, 4, 247, 125, + 106, 201, 234, 201, 235, 4, 91, 202, 5, 193, 138, 201, 235, 4, 115, 202, + 5, 193, 137, 249, 58, 234, 135, 209, 87, 219, 219, 217, 121, 231, 16, + 206, 203, 217, 121, 231, 16, 219, 35, 4, 223, 129, 210, 34, 242, 219, + 219, 35, 4, 221, 222, 221, 222, 219, 34, 211, 77, 219, 34, 248, 235, 248, + 236, 4, 247, 125, 106, 248, 94, 219, 103, 113, 207, 166, 247, 213, 249, + 147, 4, 118, 64, 58, 234, 95, 4, 118, 64, 58, 211, 105, 4, 233, 216, 87, + 4, 45, 50, 64, 58, 202, 15, 4, 96, 64, 58, 198, 54, 4, 196, 66, 64, 58, + 213, 44, 91, 196, 105, 234, 162, 113, 221, 219, 199, 95, 223, 123, 16, + 40, 8, 6, 219, 174, 223, 123, 16, 40, 8, 2, 219, 174, 223, 123, 16, 40, + 212, 135, 223, 123, 16, 40, 200, 76, 223, 123, 16, 40, 8, 219, 174, 232, + 243, 234, 135, 198, 49, 193, 9, 230, 61, 212, 118, 23, 248, 101, 229, 13, + 209, 118, 216, 88, 199, 105, 238, 197, 249, 111, 202, 136, 209, 60, 201, + 103, 4, 82, 236, 140, 223, 19, 16, 40, 248, 248, 197, 236, 234, 111, 62, + 51, 247, 213, 63, 51, 247, 213, 220, 13, 207, 87, 243, 10, 220, 13, 248, + 115, 243, 10, 220, 13, 211, 55, 237, 32, 220, 13, 248, 115, 237, 32, 2, + 211, 55, 237, 32, 2, 248, 115, 237, 32, 196, 76, 207, 87, 197, 241, 235, + 122, 207, 87, 197, 241, 196, 76, 2, 207, 87, 197, 241, 235, 122, 2, 207, + 87, 197, 241, 110, 50, 203, 151, 63, 243, 10, 116, 50, 203, 151, 63, 243, + 10, 47, 238, 218, 209, 41, 238, 218, 209, 42, 4, 230, 67, 60, 238, 218, + 209, 41, 213, 8, 45, 204, 28, 4, 115, 236, 138, 213, 8, 50, 204, 28, 4, + 115, 236, 138, 16, 40, 217, 50, 246, 242, 63, 8, 238, 217, 88, 8, 238, + 217, 247, 26, 238, 217, 211, 114, 113, 235, 125, 79, 210, 60, 222, 125, + 215, 197, 200, 70, 216, 183, 4, 213, 175, 248, 46, 248, 67, 79, 228, 90, + 242, 223, 233, 104, 91, 211, 162, 242, 223, 233, 104, 105, 211, 162, 242, + 223, 233, 104, 115, 211, 162, 242, 223, 233, 104, 232, 128, 211, 162, + 242, 223, 233, 104, 232, 226, 211, 162, 242, 223, 233, 104, 202, 136, + 211, 162, 242, 223, 233, 104, 203, 247, 211, 162, 242, 223, 233, 104, + 234, 164, 211, 162, 242, 223, 233, 104, 213, 175, 211, 162, 242, 223, + 233, 104, 199, 96, 211, 162, 242, 223, 233, 104, 234, 128, 211, 162, 242, + 223, 233, 104, 197, 38, 211, 162, 242, 223, 233, 104, 211, 97, 242, 223, + 233, 104, 197, 11, 242, 223, 233, 104, 198, 217, 242, 223, 233, 104, 232, + 124, 242, 223, 233, 104, 232, 223, 242, 223, 233, 104, 202, 132, 242, + 223, 233, 104, 203, 246, 242, 223, 233, 104, 234, 163, 242, 223, 233, + 104, 213, 173, 242, 223, 233, 104, 199, 94, 242, 223, 233, 104, 234, 126, + 242, 223, 233, 104, 197, 36, 50, 201, 234, 50, 201, 235, 4, 91, 202, 5, + 193, 138, 50, 201, 235, 4, 115, 202, 5, 193, 137, 247, 246, 247, 247, 4, + 202, 5, 193, 137, 206, 186, 248, 235, 248, 96, 247, 123, 217, 75, 242, + 222, 62, 202, 104, 23, 238, 215, 213, 44, 209, 124, 229, 5, 217, 91, 223, + 163, 247, 222, 200, 212, 219, 165, 202, 90, 211, 57, 201, 191, 237, 221, + 200, 194, 201, 221, 201, 222, 193, 118, 222, 183, 217, 91, 237, 239, 45, + 230, 54, 199, 107, 207, 101, 199, 107, 207, 102, 4, 210, 204, 50, 230, + 54, 199, 107, 207, 101, 63, 198, 34, 199, 106, 62, 198, 34, 199, 106, + 199, 107, 211, 105, 198, 54, 79, 216, 0, 242, 245, 216, 4, 209, 194, 249, + 147, 79, 234, 67, 201, 109, 234, 67, 234, 68, 4, 219, 129, 232, 178, 234, + 67, 210, 35, 139, 201, 109, 234, 67, 219, 102, 210, 133, 62, 208, 133, + 110, 45, 210, 33, 110, 45, 249, 105, 210, 34, 110, 45, 232, 130, 210, 34, + 110, 45, 210, 197, 110, 45, 238, 233, 45, 193, 3, 230, 53, 153, 211, 126, + 230, 54, 56, 207, 147, 230, 54, 4, 232, 248, 201, 211, 207, 18, 207, 147, + 230, 54, 4, 232, 248, 201, 211, 207, 18, 198, 211, 133, 56, 207, 18, 198, + 211, 144, 56, 207, 18, 195, 67, 230, 53, 207, 18, 230, 54, 4, 82, 232, + 253, 233, 204, 207, 147, 230, 54, 4, 210, 107, 248, 210, 82, 23, 206, + 189, 232, 247, 63, 144, 209, 58, 45, 230, 54, 223, 148, 202, 206, 63, 45, + 209, 58, 223, 148, 202, 206, 63, 50, 209, 58, 223, 148, 202, 206, 62, 45, + 209, 58, 223, 148, 202, 206, 62, 50, 209, 58, 223, 148, 62, 45, 209, 58, + 249, 144, 223, 148, 62, 50, 209, 58, 249, 144, 223, 148, 202, 206, 63, + 133, 209, 58, 223, 148, 202, 206, 63, 144, 209, 58, 223, 148, 202, 206, + 62, 133, 209, 58, 223, 148, 202, 206, 62, 144, 209, 58, 223, 148, 62, + 133, 209, 58, 249, 144, 223, 148, 62, 144, 209, 58, 249, 144, 223, 148, + 62, 229, 223, 237, 78, 239, 59, 221, 221, 23, 215, 181, 115, 214, 84, + 239, 58, 208, 209, 209, 71, 247, 142, 62, 230, 17, 203, 103, 232, 191, + 236, 220, 63, 230, 17, 203, 103, 232, 191, 236, 220, 202, 32, 203, 103, + 232, 191, 236, 220, 199, 182, 247, 84, 193, 55, 221, 220, 91, 247, 214, + 215, 181, 105, 247, 214, 215, 181, 115, 247, 214, 215, 181, 198, 24, 39, + 209, 249, 239, 59, 230, 17, 236, 220, 205, 76, 208, 210, 228, 20, 233, + 64, 228, 20, 211, 60, 236, 227, 228, 20, 236, 168, 4, 199, 53, 236, 168, + 4, 199, 54, 23, 209, 177, 236, 168, 4, 209, 177, 232, 114, 4, 209, 177, + 232, 114, 4, 198, 150, 232, 114, 4, 251, 133, 192, 235, 62, 232, 171, + 232, 171, 211, 77, 232, 171, 247, 101, 141, 236, 204, 247, 101, 233, 7, + 248, 62, 233, 7, 247, 155, 234, 105, 213, 6, 234, 105, 213, 7, 210, 204, + 234, 105, 213, 7, 210, 210, 213, 6, 213, 7, 210, 204, 213, 7, 210, 210, + 234, 105, 236, 167, 234, 105, 210, 204, 234, 105, 210, 202, 236, 167, + 210, 204, 210, 202, 193, 148, 201, 218, 213, 7, 210, 210, 201, 218, 247, + 141, 210, 210, 237, 78, 193, 65, 216, 38, 217, 22, 211, 2, 242, 221, 50, + 23, 45, 204, 28, 250, 231, 247, 125, 192, 235, 223, 154, 232, 163, 202, + 116, 113, 237, 134, 232, 163, 202, 116, 113, 239, 60, 39, 221, 222, 206, + 140, 214, 75, 210, 205, 4, 47, 199, 53, 201, 67, 243, 136, 238, 15, 221, + 78, 219, 96, 201, 233, 229, 236, 223, 163, 202, 187, 115, 207, 120, 58, + 115, 207, 120, 60, 115, 207, 120, 219, 224, 115, 207, 120, 183, 45, 201, + 230, 248, 8, 50, 201, 230, 248, 8, 105, 201, 230, 248, 7, 115, 201, 230, + 248, 7, 45, 198, 231, 248, 8, 50, 198, 231, 248, 8, 45, 251, 119, 248, 8, + 50, 251, 119, 248, 8, 215, 210, 248, 8, 219, 130, 215, 210, 248, 8, 219, + 130, 215, 209, 249, 107, 111, 4, 249, 106, 249, 107, 27, 192, 235, 249, + 107, 111, 4, 27, 192, 235, 249, 107, 28, 27, 192, 235, 249, 107, 111, 4, + 28, 27, 192, 235, 156, 243, 126, 77, 249, 107, 111, 4, 28, 243, 125, 193, + 18, 217, 71, 215, 186, 232, 81, 198, 85, 198, 30, 201, 92, 79, 219, 144, + 202, 188, 79, 223, 20, 215, 167, 230, 196, 233, 103, 230, 196, 233, 104, + 4, 202, 64, 233, 185, 233, 104, 4, 199, 126, 79, 222, 185, 202, 64, 233, + 104, 4, 211, 77, 215, 179, 202, 64, 233, 104, 4, 211, 77, 215, 180, 23, + 202, 64, 233, 185, 202, 64, 233, 104, 4, 211, 77, 215, 180, 23, 242, 87, + 200, 143, 202, 64, 233, 104, 4, 211, 77, 215, 180, 23, 198, 171, 233, + 185, 202, 64, 233, 104, 4, 230, 66, 202, 64, 233, 104, 4, 228, 186, 193, + 57, 233, 103, 202, 64, 233, 104, 4, 202, 64, 233, 185, 233, 104, 205, + 109, 237, 114, 232, 161, 207, 61, 233, 103, 202, 64, 233, 104, 4, 229, + 222, 233, 185, 202, 64, 233, 104, 4, 200, 194, 202, 63, 233, 103, 214, + 82, 233, 103, 233, 206, 233, 103, 196, 111, 233, 103, 233, 104, 4, 242, + 87, 200, 143, 210, 26, 233, 103, 239, 51, 233, 103, 239, 52, 233, 103, + 221, 121, 233, 103, 233, 104, 198, 214, 42, 221, 122, 221, 121, 233, 104, + 4, 202, 64, 233, 185, 221, 121, 233, 104, 4, 242, 219, 233, 185, 233, + 104, 4, 201, 12, 198, 61, 233, 104, 4, 201, 12, 198, 62, 23, 193, 57, + 233, 193, 233, 104, 4, 201, 12, 198, 62, 23, 198, 171, 233, 185, 236, + 228, 233, 103, 193, 16, 233, 103, 251, 111, 233, 103, 209, 6, 233, 103, + 238, 199, 233, 103, 209, 253, 233, 103, 233, 104, 4, 219, 7, 79, 197, + 217, 236, 228, 247, 218, 207, 61, 233, 103, 232, 92, 233, 104, 4, 211, + 77, 215, 179, 251, 109, 233, 103, 233, 57, 233, 103, 193, 119, 233, 103, + 202, 91, 233, 103, 198, 130, 233, 103, 230, 197, 233, 103, 218, 245, 238, + 199, 233, 103, 233, 104, 4, 211, 77, 215, 179, 228, 130, 233, 103, 233, + 104, 4, 211, 77, 215, 180, 23, 242, 87, 200, 143, 233, 104, 205, 78, 223, + 163, 233, 58, 250, 190, 233, 103, 232, 183, 233, 103, 202, 92, 233, 103, + 236, 195, 233, 103, 233, 104, 193, 51, 215, 179, 233, 104, 4, 216, 216, + 217, 35, 230, 196, 247, 79, 233, 104, 4, 202, 64, 233, 185, 247, 79, 233, + 104, 4, 199, 126, 79, 222, 185, 202, 64, 247, 79, 233, 104, 4, 211, 77, + 215, 179, 202, 64, 247, 79, 233, 104, 4, 229, 222, 233, 185, 247, 79, + 233, 104, 4, 193, 1, 202, 65, 221, 121, 247, 79, 233, 104, 4, 242, 219, + 233, 185, 209, 6, 247, 79, 233, 103, 238, 199, 247, 79, 233, 103, 193, + 119, 247, 79, 233, 103, 202, 84, 232, 92, 233, 103, 202, 84, 202, 64, + 233, 103, 196, 72, 233, 103, 233, 104, 4, 206, 138, 233, 185, 233, 104, + 4, 213, 44, 230, 244, 231, 132, 233, 104, 4, 211, 126, 231, 132, 209, + 251, 248, 68, 237, 129, 205, 49, 215, 225, 229, 226, 215, 225, 201, 236, + 215, 225, 230, 20, 209, 251, 207, 145, 91, 230, 53, 209, 251, 207, 145, + 248, 80, 230, 29, 223, 163, 247, 28, 209, 251, 232, 91, 209, 251, 4, 209, + 6, 233, 103, 209, 251, 4, 232, 172, 230, 28, 186, 193, 105, 209, 58, 219, + 233, 202, 2, 193, 105, 209, 58, 219, 233, 186, 234, 204, 209, 58, 219, + 233, 202, 2, 234, 204, 209, 58, 219, 233, 153, 186, 193, 105, 209, 58, + 219, 233, 153, 202, 2, 193, 105, 209, 58, 219, 233, 153, 186, 234, 204, + 209, 58, 219, 233, 153, 202, 2, 234, 204, 209, 58, 219, 233, 186, 193, + 105, 209, 58, 195, 48, 219, 233, 202, 2, 193, 105, 209, 58, 195, 48, 219, + 233, 186, 234, 204, 209, 58, 195, 48, 219, 233, 202, 2, 234, 204, 209, + 58, 195, 48, 219, 233, 88, 186, 193, 105, 209, 58, 195, 48, 219, 233, 88, + 202, 2, 193, 105, 209, 58, 195, 48, 219, 233, 88, 186, 234, 204, 209, 58, + 195, 48, 219, 233, 88, 202, 2, 234, 204, 209, 58, 195, 48, 219, 233, 186, + 193, 105, 209, 58, 248, 4, 202, 2, 193, 105, 209, 58, 248, 4, 186, 234, + 204, 209, 58, 248, 4, 202, 2, 234, 204, 209, 58, 248, 4, 88, 186, 193, + 105, 209, 58, 248, 4, 88, 202, 2, 193, 105, 209, 58, 248, 4, 88, 186, + 234, 204, 209, 58, 248, 4, 88, 202, 2, 234, 204, 209, 58, 248, 4, 229, 4, + 208, 6, 51, 211, 42, 229, 4, 208, 6, 51, 211, 43, 223, 163, 62, 201, 190, + 202, 25, 208, 6, 51, 211, 42, 202, 25, 208, 6, 51, 211, 43, 223, 163, 62, + 201, 190, 118, 206, 146, 196, 66, 206, 146, 96, 206, 146, 235, 119, 206, + 146, 27, 34, 234, 0, 211, 42, 88, 27, 34, 234, 0, 211, 42, 34, 211, 77, + 234, 0, 211, 42, 88, 34, 211, 77, 234, 0, 211, 42, 88, 251, 138, 211, 42, + 200, 146, 251, 138, 211, 42, 49, 88, 55, 153, 242, 75, 207, 252, 87, 211, + 42, 49, 88, 55, 242, 75, 207, 252, 87, 211, 42, 49, 88, 130, 55, 242, 75, + 207, 252, 87, 211, 42, 88, 223, 103, 211, 42, 49, 223, 103, 211, 42, 88, + 49, 223, 103, 211, 42, 195, 83, 88, 202, 23, 195, 83, 88, 207, 19, 202, + 23, 243, 124, 248, 107, 207, 19, 243, 124, 248, 107, 206, 146, 229, 205, + 201, 85, 219, 32, 207, 152, 247, 102, 229, 131, 198, 16, 229, 131, 198, + 17, 4, 247, 249, 213, 13, 198, 16, 216, 158, 156, 207, 153, 201, 93, 198, + 14, 198, 15, 247, 102, 247, 223, 211, 101, 247, 223, 197, 212, 247, 224, + 201, 63, 216, 42, 251, 142, 232, 244, 234, 87, 209, 50, 247, 102, 211, + 101, 209, 50, 247, 102, 199, 155, 211, 101, 199, 155, 250, 150, 211, 101, + 250, 150, 207, 94, 195, 145, 237, 110, 197, 203, 250, 225, 218, 254, 198, + 23, 215, 218, 215, 185, 207, 151, 200, 164, 207, 151, 215, 185, 247, 154, + 252, 11, 198, 13, 203, 65, 206, 112, 201, 228, 228, 241, 198, 20, 219, + 132, 81, 198, 20, 219, 132, 239, 37, 56, 209, 50, 247, 86, 207, 12, 219, + 132, 197, 238, 232, 218, 211, 105, 209, 19, 236, 144, 213, 44, 234, 73, + 56, 202, 62, 113, 213, 44, 202, 62, 113, 208, 132, 219, 84, 223, 163, + 223, 50, 209, 108, 113, 236, 175, 213, 12, 219, 84, 113, 209, 13, 193, + 144, 113, 213, 28, 193, 144, 113, 248, 184, 213, 44, 248, 183, 248, 182, + 215, 185, 248, 182, 210, 51, 213, 44, 210, 50, 243, 85, 238, 209, 216, + 182, 113, 193, 32, 113, 207, 28, 249, 149, 113, 198, 86, 193, 144, 242, + 216, 203, 20, 249, 61, 249, 59, 210, 91, 239, 21, 238, 156, 249, 126, + 242, 246, 45, 218, 215, 197, 242, 4, 206, 113, 239, 0, 208, 196, 56, 47, + 223, 137, 202, 3, 248, 59, 113, 231, 27, 113, 238, 248, 23, 220, 25, 202, + 92, 252, 57, 203, 43, 249, 125, 248, 234, 248, 235, 249, 2, 209, 108, 79, + 193, 15, 211, 159, 56, 203, 43, 197, 213, 201, 8, 210, 201, 229, 127, + 199, 98, 228, 129, 234, 130, 193, 54, 209, 96, 202, 87, 193, 93, 206, + 189, 247, 233, 230, 62, 23, 193, 9, 203, 78, 211, 132, 235, 94, 215, 189, + 207, 152, 198, 25, 215, 192, 248, 106, 196, 76, 216, 54, 251, 223, 196, + 76, 251, 223, 196, 76, 2, 251, 223, 2, 251, 223, 213, 17, 251, 223, 251, + 224, 237, 93, 251, 224, 250, 238, 205, 118, 211, 101, 232, 244, 234, 87, + 237, 22, 219, 32, 210, 95, 203, 65, 205, 83, 215, 192, 205, 83, 247, 113, + 202, 94, 232, 178, 205, 113, 202, 111, 250, 152, 206, 243, 209, 178, 197, + 203, 206, 139, 202, 112, 160, 16, 40, 208, 2, 160, 16, 40, 251, 225, 160, + 16, 40, 232, 243, 160, 16, 40, 234, 207, 160, 16, 40, 193, 143, 160, 16, + 40, 251, 35, 160, 16, 40, 251, 36, 207, 81, 160, 16, 40, 251, 36, 207, + 80, 160, 16, 40, 251, 36, 195, 31, 160, 16, 40, 251, 36, 195, 30, 160, + 16, 40, 195, 45, 160, 16, 40, 195, 44, 160, 16, 40, 195, 43, 160, 16, 40, + 200, 205, 160, 16, 40, 209, 203, 200, 205, 160, 16, 40, 62, 200, 205, + 160, 16, 40, 216, 181, 200, 236, 160, 16, 40, 216, 181, 200, 235, 160, + 16, 40, 216, 181, 200, 234, 160, 16, 40, 243, 13, 160, 16, 40, 205, 158, + 160, 16, 40, 213, 161, 160, 16, 40, 195, 28, 160, 16, 40, 195, 27, 160, + 16, 40, 206, 148, 205, 158, 160, 16, 40, 206, 148, 205, 157, 160, 16, 40, + 230, 250, 160, 16, 40, 202, 184, 160, 16, 40, 223, 74, 211, 49, 160, 16, + 40, 223, 74, 211, 48, 160, 16, 40, 238, 222, 79, 223, 73, 160, 16, 40, + 207, 77, 79, 223, 73, 160, 16, 40, 239, 12, 211, 49, 160, 16, 40, 223, + 72, 211, 49, 160, 16, 40, 200, 237, 79, 239, 11, 160, 16, 40, 238, 222, + 79, 239, 11, 160, 16, 40, 238, 222, 79, 239, 10, 160, 16, 40, 239, 12, + 251, 79, 160, 16, 40, 205, 159, 79, 239, 12, 251, 79, 160, 16, 40, 200, + 237, 79, 205, 159, 79, 239, 11, 160, 16, 40, 195, 139, 160, 16, 40, 198, + 143, 211, 49, 160, 16, 40, 219, 237, 211, 49, 160, 16, 40, 251, 78, 211, + 49, 160, 16, 40, 200, 237, 79, 251, 77, 160, 16, 40, 205, 159, 79, 251, + 77, 160, 16, 40, 200, 237, 79, 205, 159, 79, 251, 77, 160, 16, 40, 195, + 46, 79, 251, 77, 160, 16, 40, 207, 77, 79, 251, 77, 160, 16, 40, 207, 77, + 79, 251, 76, 160, 16, 40, 207, 76, 160, 16, 40, 207, 75, 160, 16, 40, + 207, 74, 160, 16, 40, 207, 73, 160, 16, 40, 251, 177, 160, 16, 40, 251, + 176, 160, 16, 40, 217, 61, 160, 16, 40, 205, 168, 160, 16, 40, 250, 230, + 160, 16, 40, 207, 105, 160, 16, 40, 207, 104, 160, 16, 40, 250, 154, 160, + 16, 40, 248, 150, 211, 49, 160, 16, 40, 199, 177, 160, 16, 40, 199, 176, + 160, 16, 40, 208, 8, 219, 121, 160, 16, 40, 248, 87, 160, 16, 40, 248, + 86, 160, 16, 40, 248, 85, 160, 16, 40, 251, 151, 160, 16, 40, 211, 131, + 160, 16, 40, 201, 214, 160, 16, 40, 198, 141, 160, 16, 40, 230, 158, 160, + 16, 40, 193, 131, 160, 16, 40, 209, 1, 160, 16, 40, 247, 137, 160, 16, + 40, 197, 50, 160, 16, 40, 247, 104, 215, 198, 160, 16, 40, 205, 93, 79, + 222, 187, 160, 16, 40, 247, 151, 160, 16, 40, 197, 235, 160, 16, 40, 201, + 100, 197, 235, 160, 16, 40, 219, 31, 160, 16, 40, 202, 37, 160, 16, 40, + 196, 54, 160, 16, 40, 228, 184, 235, 71, 160, 16, 40, 250, 204, 160, 16, + 40, 209, 15, 250, 204, 160, 16, 40, 248, 31, 160, 16, 40, 209, 0, 248, + 31, 160, 16, 40, 251, 148, 160, 16, 40, 201, 46, 200, 186, 201, 45, 160, + 16, 40, 201, 46, 200, 186, 201, 44, 160, 16, 40, 200, 233, 160, 16, 40, + 208, 229, 160, 16, 40, 236, 215, 160, 16, 40, 236, 217, 160, 16, 40, 236, + 216, 160, 16, 40, 208, 141, 160, 16, 40, 208, 129, 160, 16, 40, 238, 207, + 160, 16, 40, 238, 206, 160, 16, 40, 238, 205, 160, 16, 40, 238, 204, 160, + 16, 40, 238, 203, 160, 16, 40, 251, 191, 160, 16, 40, 249, 62, 79, 217, + 42, 160, 16, 40, 249, 62, 79, 195, 174, 160, 16, 40, 207, 26, 160, 16, + 40, 228, 176, 160, 16, 40, 213, 190, 160, 16, 40, 237, 203, 160, 16, 40, + 215, 213, 160, 16, 40, 132, 235, 109, 160, 16, 40, 132, 211, 17, 218, + 250, 79, 232, 137, 211, 164, 218, 207, 234, 194, 230, 1, 217, 101, 230, + 246, 208, 24, 211, 52, 62, 219, 219, 223, 56, 50, 197, 241, 62, 196, 76, + 223, 56, 50, 197, 241, 62, 206, 203, 223, 56, 50, 197, 241, 62, 235, 122, + 223, 56, 50, 197, 241, 62, 202, 84, 2, 243, 10, 216, 213, 28, 63, 243, + 10, 28, 63, 243, 10, 88, 63, 243, 10, 195, 83, 88, 63, 243, 10, 233, 197, + 88, 63, 243, 10, 63, 243, 11, 239, 33, 62, 2, 243, 10, 206, 115, 199, + 178, 62, 198, 138, 201, 190, 62, 202, 84, 2, 201, 190, 156, 63, 201, 190, + 216, 213, 63, 201, 190, 28, 63, 201, 190, 88, 63, 201, 190, 195, 83, 88, + 63, 201, 190, 233, 197, 88, 63, 201, 190, 63, 51, 239, 33, 62, 195, 83, + 2, 201, 190, 63, 51, 239, 33, 62, 216, 213, 201, 190, 51, 199, 178, 62, + 198, 138, 237, 32, 62, 195, 83, 2, 237, 32, 62, 216, 213, 2, 237, 32, 63, + 237, 33, 239, 33, 62, 195, 83, 2, 237, 32, 63, 237, 33, 239, 33, 62, 216, + 213, 237, 32, 237, 33, 199, 178, 62, 198, 138, 218, 232, 62, 195, 83, 2, + 218, 232, 62, 216, 213, 2, 218, 232, 63, 218, 233, 239, 33, 62, 2, 218, + 232, 199, 4, 35, 238, 217, 156, 35, 238, 217, 216, 213, 35, 238, 217, 28, + 35, 238, 217, 195, 83, 28, 35, 238, 217, 195, 83, 88, 35, 238, 217, 233, + 197, 88, 35, 238, 217, 199, 4, 205, 154, 156, 205, 154, 216, 213, 205, + 154, 28, 205, 154, 88, 205, 154, 195, 83, 88, 205, 154, 233, 197, 88, + 205, 154, 156, 232, 226, 201, 206, 250, 193, 216, 213, 232, 226, 201, + 206, 250, 193, 28, 232, 226, 201, 206, 250, 193, 88, 232, 226, 201, 206, + 250, 193, 195, 83, 88, 232, 226, 201, 206, 250, 193, 233, 197, 88, 232, + 226, 201, 206, 250, 193, 156, 202, 136, 201, 206, 250, 193, 216, 213, + 202, 136, 201, 206, 250, 193, 28, 202, 136, 201, 206, 250, 193, 88, 202, + 136, 201, 206, 250, 193, 195, 83, 88, 202, 136, 201, 206, 250, 193, 233, + 197, 88, 202, 136, 201, 206, 250, 193, 156, 234, 164, 201, 206, 250, 193, + 216, 213, 234, 164, 201, 206, 250, 193, 28, 234, 164, 201, 206, 250, 193, + 88, 234, 164, 201, 206, 250, 193, 195, 83, 88, 234, 164, 201, 206, 250, + 193, 156, 115, 209, 60, 62, 201, 102, 216, 213, 115, 209, 60, 62, 201, + 102, 115, 209, 60, 62, 201, 102, 216, 213, 115, 209, 60, 209, 130, 201, + 102, 156, 232, 128, 209, 60, 62, 201, 102, 216, 213, 232, 128, 209, 60, + 62, 201, 102, 232, 128, 209, 60, 62, 201, 102, 216, 213, 232, 128, 209, + 60, 209, 130, 201, 102, 207, 19, 156, 232, 128, 209, 60, 209, 130, 201, + 102, 156, 232, 226, 209, 60, 62, 201, 102, 88, 232, 226, 209, 60, 62, + 201, 102, 216, 213, 202, 136, 209, 60, 62, 201, 102, 88, 202, 136, 209, + 60, 62, 201, 102, 202, 136, 209, 60, 209, 130, 201, 102, 216, 213, 234, + 164, 209, 60, 62, 201, 102, 88, 234, 164, 209, 60, 62, 201, 102, 195, 83, + 88, 234, 164, 209, 60, 62, 201, 102, 88, 234, 164, 209, 60, 209, 130, + 201, 102, 156, 197, 38, 209, 60, 62, 201, 102, 88, 197, 38, 209, 60, 62, + 201, 102, 88, 197, 38, 209, 60, 209, 130, 201, 102, 47, 197, 241, 214, + 106, 47, 197, 241, 47, 201, 190, 214, 106, 47, 201, 190, 213, 175, 209, + 60, 63, 201, 102, 220, 13, 211, 55, 243, 10, 220, 13, 192, 73, 243, 10, + 220, 13, 230, 201, 243, 10, 220, 13, 208, 138, 243, 10, 220, 13, 248, 19, + 243, 10, 220, 13, 207, 87, 201, 190, 220, 13, 248, 115, 201, 190, 220, + 13, 211, 55, 201, 190, 220, 13, 192, 73, 201, 190, 220, 13, 230, 201, + 201, 190, 220, 13, 208, 138, 201, 190, 220, 13, 248, 19, 201, 190, 88, + 234, 43, 56, 118, 64, 4, 2, 197, 242, 250, 235, 196, 66, 64, 4, 2, 197, + 242, 250, 235, 96, 64, 4, 2, 197, 242, 250, 235, 235, 119, 64, 4, 2, 197, + 242, 250, 235, 118, 64, 4, 216, 213, 197, 242, 250, 235, 196, 66, 64, 4, + 216, 213, 197, 242, 250, 235, 96, 64, 4, 216, 213, 197, 242, 250, 235, + 235, 119, 64, 4, 216, 213, 197, 242, 250, 235, 118, 64, 4, 220, 13, 197, + 242, 250, 235, 196, 66, 64, 4, 220, 13, 197, 242, 250, 235, 96, 64, 4, + 220, 13, 197, 242, 250, 235, 235, 119, 64, 4, 220, 13, 197, 242, 250, + 235, 118, 64, 4, 2, 234, 37, 250, 235, 196, 66, 64, 4, 2, 234, 37, 250, + 235, 96, 64, 4, 2, 234, 37, 250, 235, 235, 119, 64, 4, 2, 234, 37, 250, + 235, 118, 64, 4, 234, 37, 250, 235, 196, 66, 64, 4, 234, 37, 250, 235, + 96, 64, 4, 234, 37, 250, 235, 235, 119, 64, 4, 234, 37, 250, 235, 88, + 118, 64, 4, 234, 37, 250, 235, 88, 196, 66, 64, 4, 234, 37, 250, 235, 88, + 96, 64, 4, 234, 37, 250, 235, 88, 235, 119, 64, 4, 234, 37, 250, 235, 88, + 118, 64, 4, 220, 13, 234, 37, 250, 235, 88, 196, 66, 64, 4, 220, 13, 234, + 37, 250, 235, 88, 96, 64, 4, 220, 13, 234, 37, 250, 235, 88, 235, 119, + 64, 4, 220, 13, 234, 37, 250, 235, 118, 197, 240, 64, 4, 214, 215, 203, + 149, 196, 66, 197, 240, 64, 4, 214, 215, 203, 149, 96, 197, 240, 64, 4, + 214, 215, 203, 149, 235, 119, 197, 240, 64, 4, 214, 215, 203, 149, 118, + 197, 240, 64, 4, 216, 213, 203, 149, 196, 66, 197, 240, 64, 4, 216, 213, + 203, 149, 96, 197, 240, 64, 4, 216, 213, 203, 149, 235, 119, 197, 240, + 64, 4, 216, 213, 203, 149, 118, 197, 240, 64, 4, 28, 203, 149, 196, 66, + 197, 240, 64, 4, 28, 203, 149, 96, 197, 240, 64, 4, 28, 203, 149, 235, + 119, 197, 240, 64, 4, 28, 203, 149, 118, 197, 240, 64, 4, 88, 203, 149, + 196, 66, 197, 240, 64, 4, 88, 203, 149, 96, 197, 240, 64, 4, 88, 203, + 149, 235, 119, 197, 240, 64, 4, 88, 203, 149, 118, 197, 240, 64, 4, 195, + 83, 88, 203, 149, 196, 66, 197, 240, 64, 4, 195, 83, 88, 203, 149, 96, + 197, 240, 64, 4, 195, 83, 88, 203, 149, 235, 119, 197, 240, 64, 4, 195, + 83, 88, 203, 149, 118, 232, 251, 57, 196, 66, 232, 251, 57, 96, 232, 251, + 57, 235, 119, 232, 251, 57, 118, 112, 57, 196, 66, 112, 57, 96, 112, 57, + 235, 119, 112, 57, 118, 239, 61, 57, 196, 66, 239, 61, 57, 96, 239, 61, + 57, 235, 119, 239, 61, 57, 118, 88, 239, 61, 57, 196, 66, 88, 239, 61, + 57, 96, 88, 239, 61, 57, 235, 119, 88, 239, 61, 57, 118, 88, 57, 196, 66, + 88, 57, 96, 88, 57, 235, 119, 88, 57, 118, 49, 57, 196, 66, 49, 57, 96, + 49, 57, 235, 119, 49, 57, 186, 193, 105, 49, 57, 186, 234, 204, 49, 57, + 202, 2, 234, 204, 49, 57, 202, 2, 193, 105, 49, 57, 45, 50, 49, 57, 133, + 144, 49, 57, 193, 77, 118, 156, 181, 57, 193, 77, 196, 66, 156, 181, 57, + 193, 77, 96, 156, 181, 57, 193, 77, 235, 119, 156, 181, 57, 193, 77, 186, + 193, 105, 156, 181, 57, 193, 77, 186, 234, 204, 156, 181, 57, 193, 77, + 202, 2, 234, 204, 156, 181, 57, 193, 77, 202, 2, 193, 105, 156, 181, 57, + 193, 77, 118, 181, 57, 193, 77, 196, 66, 181, 57, 193, 77, 96, 181, 57, + 193, 77, 235, 119, 181, 57, 193, 77, 186, 193, 105, 181, 57, 193, 77, + 186, 234, 204, 181, 57, 193, 77, 202, 2, 234, 204, 181, 57, 193, 77, 202, + 2, 193, 105, 181, 57, 193, 77, 118, 216, 213, 181, 57, 193, 77, 196, 66, + 216, 213, 181, 57, 193, 77, 96, 216, 213, 181, 57, 193, 77, 235, 119, + 216, 213, 181, 57, 193, 77, 186, 193, 105, 216, 213, 181, 57, 193, 77, + 186, 234, 204, 216, 213, 181, 57, 193, 77, 202, 2, 234, 204, 216, 213, + 181, 57, 193, 77, 202, 2, 193, 105, 216, 213, 181, 57, 193, 77, 118, 88, + 181, 57, 193, 77, 196, 66, 88, 181, 57, 193, 77, 96, 88, 181, 57, 193, + 77, 235, 119, 88, 181, 57, 193, 77, 186, 193, 105, 88, 181, 57, 193, 77, + 186, 234, 204, 88, 181, 57, 193, 77, 202, 2, 234, 204, 88, 181, 57, 193, + 77, 202, 2, 193, 105, 88, 181, 57, 193, 77, 118, 195, 83, 88, 181, 57, + 193, 77, 196, 66, 195, 83, 88, 181, 57, 193, 77, 96, 195, 83, 88, 181, + 57, 193, 77, 235, 119, 195, 83, 88, 181, 57, 193, 77, 186, 193, 105, 195, + 83, 88, 181, 57, 193, 77, 186, 234, 204, 195, 83, 88, 181, 57, 193, 77, + 202, 2, 234, 204, 195, 83, 88, 181, 57, 193, 77, 202, 2, 193, 105, 195, + 83, 88, 181, 57, 118, 197, 242, 250, 235, 196, 66, 197, 242, 250, 235, + 96, 197, 242, 250, 235, 235, 119, 197, 242, 250, 235, 118, 63, 64, 193, + 53, 197, 242, 250, 235, 196, 66, 63, 64, 193, 53, 197, 242, 250, 235, 96, + 63, 64, 193, 53, 197, 242, 250, 235, 235, 119, 63, 64, 193, 53, 197, 242, + 250, 235, 118, 64, 4, 213, 8, 199, 215, 196, 66, 64, 4, 213, 8, 199, 215, + 96, 64, 4, 213, 8, 199, 215, 235, 119, 64, 4, 213, 8, 199, 215, 88, 64, + 203, 150, 193, 75, 107, 88, 64, 203, 150, 193, 75, 105, 198, 253, 88, 64, + 203, 150, 193, 75, 91, 230, 70, 88, 64, 203, 150, 193, 75, 91, 199, 0, + 118, 248, 74, 63, 57, 96, 248, 77, 203, 152, 63, 57, 118, 198, 54, 203, + 152, 63, 57, 96, 198, 54, 203, 152, 63, 57, 118, 219, 218, 63, 57, 96, + 206, 202, 63, 57, 118, 206, 202, 63, 57, 96, 219, 218, 63, 57, 118, 249, + 145, 203, 151, 63, 57, 96, 249, 145, 203, 151, 63, 57, 118, 232, 95, 203, + 151, 63, 57, 96, 232, 95, 203, 151, 63, 57, 63, 64, 203, 150, 193, 75, + 107, 63, 64, 203, 150, 193, 75, 105, 198, 253, 64, 209, 58, 196, 66, 199, + 25, 186, 193, 104, 64, 209, 58, 96, 199, 25, 238, 161, 202, 2, 193, 104, + 47, 238, 218, 232, 143, 4, 232, 128, 236, 138, 47, 238, 218, 232, 143, 4, + 105, 236, 138, 47, 238, 218, 232, 142, 45, 132, 243, 11, 4, 232, 128, + 236, 138, 45, 132, 243, 11, 4, 115, 236, 138, 45, 132, 243, 11, 4, 105, + 236, 138, 45, 132, 243, 11, 4, 236, 140, 45, 132, 243, 10, 235, 120, 233, + 96, 102, 235, 120, 233, 96, 213, 8, 102, 235, 120, 233, 96, 228, 251, 4, + 236, 140, 235, 120, 233, 96, 213, 8, 228, 251, 4, 236, 140, 209, 136, + 232, 247, 63, 229, 223, 248, 19, 229, 223, 209, 135, 230, 53, 191, 17, + 233, 103, 215, 229, 233, 103, 233, 104, 4, 199, 21, 214, 92, 233, 103, + 199, 2, 233, 103, 233, 104, 4, 229, 234, 206, 150, 233, 103, 228, 150, + 233, 103, 3, 79, 199, 34, 228, 186, 247, 139, 216, 233, 230, 53, 207, + 147, 249, 147, 79, 230, 53, 219, 223, 232, 231, 206, 207, 232, 231, 230, + 27, 230, 54, 4, 141, 23, 82, 232, 248, 238, 213, 228, 74, 218, 242, 191, + 239, 230, 54, 56, 233, 104, 4, 238, 238, 230, 9, 242, 208, 233, 103, 214, + 202, 233, 103, 206, 138, 211, 105, 199, 34, 232, 194, 219, 255, 235, 100, + 233, 103, 218, 178, 233, 103, 233, 104, 210, 182, 202, 56, 233, 103, 233, + 104, 4, 91, 233, 192, 207, 146, 230, 196, 233, 104, 4, 201, 103, 233, + 185, 230, 196, 233, 104, 4, 91, 220, 13, 23, 91, 2, 233, 193, 233, 104, + 4, 232, 253, 238, 241, 242, 219, 219, 96, 204, 2, 233, 104, 4, 200, 77, + 238, 241, 215, 179, 202, 64, 233, 104, 4, 202, 64, 233, 186, 23, 230, 54, + 238, 241, 215, 179, 233, 104, 4, 211, 77, 215, 180, 195, 9, 203, 54, 233, + 104, 4, 233, 208, 229, 235, 208, 226, 193, 35, 248, 40, 210, 181, 133, + 198, 87, 204, 31, 208, 214, 217, 91, 223, 163, 197, 46, 215, 194, 243, + 55, 203, 9, 209, 251, 236, 159, 247, 83, 222, 177, 233, 38, 215, 255, + 210, 21, 193, 8, 193, 144, 209, 44, 230, 32, 236, 201, 217, 35, 193, 69, + 232, 186, 235, 95, 4, 235, 93, 242, 226, 231, 15, 197, 74, 231, 16, 201, + 203, 231, 1, 214, 85, 206, 208, 232, 238, 209, 108, 216, 219, 205, 57, + 209, 108, 216, 219, 199, 1, 209, 108, 216, 219, 248, 61, 231, 10, 217, + 46, 250, 223, 196, 94, 238, 172, 201, 65, 220, 110, 201, 75, 23, 249, + 111, 202, 31, 232, 178, 236, 226, 238, 221, 250, 141, 238, 188, 249, 138, + 209, 12, 247, 87, 249, 124, 248, 43, 230, 201, 205, 165, 203, 142, 210, + 167, 79, 232, 161, 201, 9, 232, 205, 234, 179, 231, 17, 79, 216, 53, 210, + 56, 221, 116, 210, 163, 235, 76, 232, 138, 239, 16, 199, 207, 248, 62, + 243, 62, 248, 67, 4, 201, 203, 238, 182, 4, 201, 43, 242, 93, 248, 23, + 209, 176, 208, 218, 238, 155, 79, 216, 224, 205, 137, 247, 115, 232, 161, + 219, 232, 230, 200, 217, 82, 215, 206, 247, 146, 249, 127, 202, 64, 233, + 104, 4, 202, 64, 233, 186, 23, 115, 229, 221, 192, 87, 233, 103, 202, 64, + 233, 104, 4, 199, 131, 233, 104, 4, 210, 102, 228, 188, 23, 210, 102, + 230, 9, 233, 104, 4, 196, 98, 233, 186, 23, 193, 135, 215, 179, 211, 5, + 233, 103, 232, 107, 233, 103, 213, 168, 236, 224, 233, 103, 233, 104, + 229, 6, 249, 147, 199, 125, 233, 104, 4, 209, 93, 233, 185, 205, 125, + 220, 119, 242, 96, 230, 253, 229, 129, 248, 91, 232, 207, 203, 52, 238, + 235, 219, 100, 233, 103, 205, 81, 197, 62, 196, 96, 233, 103, 234, 214, + 235, 85, 249, 64, 203, 128, 210, 249, 232, 120, 233, 103, 247, 215, 237, + 128, 230, 235, 219, 78, 207, 5, 203, 13, 201, 184, 231, 29, 233, 103, + 191, 85, 233, 103, 229, 216, 205, 110, 200, 42, 238, 224, 222, 82, 219, + 70, 210, 58, 229, 121, 210, 108, 207, 173, 219, 41, 215, 196, 216, 90, + 249, 133, 200, 148, 217, 92, 236, 165, 202, 78, 211, 22, 211, 54, 202, + 102, 232, 209, 210, 239, 249, 4, 248, 149, 205, 61, 230, 163, 236, 162, + 208, 202, 247, 117, 234, 109, 242, 64, 207, 87, 230, 78, 234, 109, 242, + 64, 238, 171, 230, 78, 234, 109, 242, 64, 249, 113, 234, 109, 242, 64, + 63, 230, 78, 248, 98, 219, 212, 232, 159, 198, 56, 200, 184, 200, 179, + 205, 188, 195, 81, 234, 212, 4, 229, 225, 251, 235, 215, 190, 193, 91, + 217, 74, 193, 91, 216, 223, 250, 250, 216, 223, 219, 212, 243, 118, 193, + 116, 238, 180, 205, 159, 203, 146, 248, 208, 248, 62, 231, 197, 211, 93, + 233, 85, 193, 174, 247, 216, 217, 29, 235, 104, 228, 27, 238, 190, 248, + 9, 199, 134, 197, 214, 201, 105, 209, 250, 221, 80, 209, 250, 237, 144, + 209, 250, 233, 104, 4, 215, 224, 252, 29, 243, 86, 211, 118, 252, 29, + 249, 8, 209, 250, 209, 251, 4, 229, 230, 209, 251, 223, 163, 201, 82, + 206, 130, 209, 251, 242, 228, 209, 251, 223, 163, 218, 247, 209, 24, 217, + 124, 233, 87, 195, 177, 216, 174, 234, 125, 231, 148, 191, 5, 248, 50, + 211, 55, 229, 223, 248, 171, 247, 111, 205, 94, 231, 9, 242, 96, 202, 34, + 207, 87, 231, 43, 234, 67, 232, 242, 222, 238, 208, 125, 209, 175, 199, + 75, 197, 84, 209, 235, 236, 222, 236, 176, 55, 229, 204, 242, 69, 252, + 71, 232, 244, 233, 202, 198, 58, 248, 31, 217, 122, 218, 215, 218, 248, + 248, 78, 201, 204, 79, 198, 227, 249, 112, 79, 192, 100, 205, 188, 209, + 139, 199, 124, 249, 9, 248, 20, 249, 69, 206, 141, 79, 210, 135, 249, 88, + 79, 202, 37, 201, 205, 207, 103, 214, 196, 251, 134, 214, 82, 243, 105, + 221, 138, 214, 82, 243, 105, 208, 14, 214, 82, 243, 105, 206, 131, 214, + 82, 243, 105, 248, 152, 214, 82, 243, 105, 221, 76, 214, 82, 243, 105, + 210, 74, 63, 243, 105, 221, 77, 206, 122, 232, 134, 237, 124, 62, 243, + 105, 221, 77, 206, 122, 232, 134, 237, 124, 214, 82, 243, 105, 221, 77, + 206, 122, 232, 134, 237, 124, 63, 243, 105, 221, 139, 206, 122, 213, 170, + 237, 124, 63, 243, 105, 208, 15, 206, 122, 213, 170, 237, 124, 63, 243, + 105, 206, 132, 206, 122, 213, 170, 237, 124, 63, 243, 105, 248, 153, 206, + 122, 213, 170, 237, 124, 63, 243, 105, 221, 77, 206, 122, 213, 170, 237, + 124, 63, 243, 105, 210, 75, 206, 122, 213, 170, 237, 124, 62, 243, 105, + 221, 139, 206, 122, 213, 170, 237, 124, 62, 243, 105, 208, 15, 206, 122, + 213, 170, 237, 124, 62, 243, 105, 206, 132, 206, 122, 213, 170, 237, 124, + 62, 243, 105, 248, 153, 206, 122, 213, 170, 237, 124, 62, 243, 105, 221, + 77, 206, 122, 213, 170, 237, 124, 62, 243, 105, 210, 75, 206, 122, 213, + 170, 237, 124, 214, 82, 243, 105, 221, 139, 206, 122, 213, 170, 237, 124, + 214, 82, 243, 105, 208, 15, 206, 122, 213, 170, 237, 124, 214, 82, 243, + 105, 206, 132, 206, 122, 213, 170, 237, 124, 214, 82, 243, 105, 248, 153, + 206, 122, 213, 170, 237, 124, 214, 82, 243, 105, 221, 77, 206, 122, 213, + 170, 237, 124, 214, 82, 243, 105, 210, 75, 206, 122, 213, 170, 237, 124, + 63, 243, 105, 221, 77, 206, 122, 91, 228, 141, 198, 248, 237, 124, 62, + 243, 105, 221, 77, 206, 122, 91, 228, 141, 198, 248, 237, 124, 214, 82, + 243, 105, 221, 77, 206, 122, 91, 228, 141, 198, 248, 237, 124, 63, 243, + 105, 153, 221, 138, 63, 243, 105, 153, 208, 14, 63, 243, 105, 153, 206, + 131, 63, 243, 105, 153, 248, 152, 63, 243, 105, 153, 221, 76, 63, 243, + 105, 153, 210, 74, 62, 243, 105, 153, 221, 138, 62, 243, 105, 153, 208, + 14, 62, 243, 105, 153, 206, 131, 62, 243, 105, 153, 248, 152, 62, 243, + 105, 153, 221, 76, 62, 243, 105, 153, 210, 74, 214, 82, 243, 105, 153, + 221, 138, 214, 82, 243, 105, 153, 208, 14, 214, 82, 243, 105, 153, 206, + 131, 214, 82, 243, 105, 153, 248, 152, 214, 82, 243, 105, 153, 221, 76, + 214, 82, 243, 105, 153, 210, 74, 63, 243, 105, 221, 77, 206, 122, 105, + 228, 141, 197, 29, 237, 124, 62, 243, 105, 221, 77, 206, 122, 105, 228, + 141, 197, 29, 237, 124, 214, 82, 243, 105, 221, 77, 206, 122, 105, 228, + 141, 197, 29, 237, 124, 63, 243, 105, 221, 139, 206, 122, 105, 228, 141, + 203, 242, 237, 124, 63, 243, 105, 208, 15, 206, 122, 105, 228, 141, 203, + 242, 237, 124, 63, 243, 105, 206, 132, 206, 122, 105, 228, 141, 203, 242, + 237, 124, 63, 243, 105, 248, 153, 206, 122, 105, 228, 141, 203, 242, 237, + 124, 63, 243, 105, 221, 77, 206, 122, 105, 228, 141, 203, 242, 237, 124, + 63, 243, 105, 210, 75, 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, + 243, 105, 221, 139, 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, 243, + 105, 208, 15, 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, 243, 105, + 206, 132, 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, 243, 105, 248, + 153, 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, 243, 105, 221, 77, + 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, 243, 105, 210, 75, 206, + 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 221, 139, 206, + 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 208, 15, 206, + 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 206, 132, 206, + 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 248, 153, 206, + 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 221, 77, 206, + 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 210, 75, 206, + 122, 105, 228, 141, 203, 242, 237, 124, 63, 243, 105, 221, 77, 206, 122, + 115, 228, 141, 233, 20, 237, 124, 62, 243, 105, 221, 77, 206, 122, 115, + 228, 141, 233, 20, 237, 124, 214, 82, 243, 105, 221, 77, 206, 122, 115, + 228, 141, 233, 20, 237, 124, 63, 243, 105, 234, 38, 62, 243, 105, 234, + 38, 214, 82, 243, 105, 234, 38, 63, 243, 105, 234, 39, 206, 122, 213, + 170, 237, 124, 62, 243, 105, 234, 39, 206, 122, 213, 170, 237, 124, 214, + 82, 243, 105, 234, 39, 206, 122, 213, 170, 237, 124, 63, 243, 105, 221, + 74, 63, 243, 105, 221, 73, 63, 243, 105, 221, 75, 62, 243, 105, 221, 74, + 62, 243, 105, 221, 73, 62, 243, 105, 221, 75, 192, 205, 207, 87, 231, + 150, 192, 205, 207, 87, 217, 84, 192, 205, 207, 87, 234, 131, 192, 205, + 207, 87, 228, 183, 192, 205, 207, 87, 243, 138, 192, 205, 207, 87, 247, + 114, 192, 205, 207, 87, 202, 26, 192, 205, 62, 231, 150, 192, 205, 62, + 217, 84, 192, 205, 62, 234, 131, 192, 205, 62, 228, 183, 192, 205, 62, + 243, 138, 192, 205, 62, 247, 114, 192, 205, 62, 202, 26, 249, 110, 203, + 51, 211, 98, 200, 135, 248, 27, 203, 25, 198, 237, 205, 139, 156, 248, + 115, 229, 223, 230, 198, 229, 223, 209, 131, 229, 223, 235, 99, 79, 248, + 120, 252, 35, 249, 96, 201, 76, 192, 234, 238, 201, 191, 253, 221, 119, + 210, 129, 248, 92, 217, 123, 193, 162, 209, 137, 214, 87, 236, 154, 217, + 64, 232, 182, 206, 187, 209, 100, 246, 252, 207, 118, 250, 132, 236, 196, + 220, 25, 249, 94, 216, 54, 229, 200, 252, 56, 179, 235, 94, 242, 88, 247, + 89, 205, 108, 205, 75, 220, 109, 102, 216, 26, 193, 65, 209, 83, 203, + 239, 214, 109, 221, 71, 248, 6, 215, 182, 198, 6, 198, 55, 229, 228, 209, + 109, 206, 147, 216, 27, 249, 111, 228, 16, 247, 100, 130, 249, 58, 230, + 60, 232, 170, 230, 54, 233, 80, 230, 79, 209, 180, 221, 203, 232, 179, + 193, 17, 248, 251, 242, 95, 209, 11, 209, 99, 193, 28, 233, 54, 218, 246, + 239, 4, 234, 105, 214, 89, 214, 90, 4, 234, 178, 228, 92, 223, 2, 193, + 61, 230, 243, 251, 129, 229, 223, 218, 205, 210, 20, 228, 149, 208, 226, + 217, 90, 208, 226, 209, 250, 209, 251, 4, 238, 208, 215, 204, 236, 147, + 248, 113, 248, 236, 210, 15, 211, 115, 232, 205, 199, 196, 232, 165, 199, + 132, 209, 7, 219, 92, 249, 11, 223, 18, 231, 36, 206, 128, 210, 62, 209, + 70, 216, 195, 233, 103, 205, 153, 233, 103, 233, 104, 4, 211, 77, 233, + 186, 23, 230, 54, 139, 215, 179, 233, 104, 4, 210, 47, 233, 193, 233, + 104, 4, 237, 39, 215, 179, 235, 138, 219, 113, 233, 103, 248, 145, 219, + 98, 248, 7, 203, 145, 233, 103, 230, 54, 4, 141, 232, 253, 23, 176, 238, + 213, 96, 230, 53, 118, 230, 53, 210, 183, 144, 230, 53, 210, 183, 133, + 230, 53, 141, 209, 58, 250, 183, 199, 34, 195, 55, 229, 224, 230, 28, + 118, 208, 135, 230, 53, 96, 208, 135, 230, 53, 184, 203, 236, 184, 203, + 206, 184, 203, 235, 184, 203, 191, 184, 203, 220, 184, 203, 205, 184, + 203, 234, 184, 203, 183, 184, 203, 213, 184, 203, 197, 184, 203, 227, + 184, 203, 190, 184, 203, 219, 184, 203, 204, 184, 203, 233, 184, 203, + 179, 184, 203, 209, 184, 203, 194, 184, 203, 223, 184, 203, 186, 184, + 203, 200, 184, 203, 230, 184, 203, 182, 184, 203, 212, 184, 203, 196, + 184, 203, 226, 184, 203, 189, 184, 203, 218, 184, 203, 203, 184, 203, + 232, 184, 203, 177, 184, 203, 207, 184, 203, 192, 184, 203, 221, 184, + 203, 184, 184, 203, 214, 184, 203, 198, 184, 203, 228, 184, 203, 180, + 184, 203, 210, 184, 203, 224, 184, 203, 187, 184, 203, 216, 184, 203, + 201, 184, 203, 231, 184, 203, 178, 184, 203, 208, 184, 203, 193, 184, + 203, 222, 184, 203, 185, 184, 203, 215, 184, 203, 199, 184, 203, 229, + 184, 203, 181, 184, 203, 211, 184, 203, 195, 184, 203, 225, 184, 203, + 188, 184, 203, 217, 184, 203, 202, 110, 45, 184, 237, 39, 110, 82, 45, + 119, 110, 247, 21, 110, 45, 184, 237, 39, 110, 82, 45, 119, 110, 183, + 110, 45, 184, 237, 39, 116, 82, 45, 119, 110, 247, 21, 110, 45, 184, 237, + 39, 116, 82, 45, 119, 110, 183, 110, 45, 184, 237, 39, 116, 45, 119, 110, + 247, 21, 110, 50, 184, 237, 39, 116, 82, 45, 119, 116, 247, 21, 110, 50, + 184, 237, 39, 116, 82, 45, 119, 116, 183, 110, 50, 184, 237, 39, 110, 82, + 45, 119, 116, 247, 21, 110, 50, 184, 237, 39, 110, 82, 45, 119, 116, 183, + 110, 50, 184, 237, 39, 110, 45, 119, 116, 247, 21, 110, 50, 184, 237, 39, + 110, 82, 45, 119, 116, 82, 183, 110, 50, 184, 237, 39, 110, 247, 22, 119, + 110, 82, 183, 110, 50, 184, 237, 39, 110, 45, 119, 110, 82, 183, 110, 50, + 184, 237, 39, 110, 247, 22, 119, 116, 82, 183, 110, 50, 184, 237, 39, + 110, 45, 119, 116, 82, 183, 110, 50, 184, 237, 39, 110, 247, 22, 119, + 116, 183, 110, 45, 184, 237, 39, 116, 247, 22, 119, 116, 82, 183, 110, + 45, 184, 237, 39, 116, 45, 119, 116, 82, 183, 110, 45, 184, 237, 39, 116, + 247, 22, 119, 110, 82, 183, 110, 45, 184, 237, 39, 116, 45, 119, 110, 82, + 183, 110, 45, 184, 237, 39, 116, 247, 22, 119, 110, 183, 110, 45, 184, + 237, 39, 116, 82, 45, 119, 110, 82, 183, 116, 50, 184, 237, 39, 110, 82, + 45, 119, 110, 247, 21, 116, 50, 184, 237, 39, 110, 82, 45, 119, 110, 183, + 116, 50, 184, 237, 39, 116, 82, 45, 119, 110, 247, 21, 116, 50, 184, 237, + 39, 116, 82, 45, 119, 110, 183, 116, 50, 184, 237, 39, 116, 45, 119, 110, + 247, 21, 116, 45, 184, 237, 39, 116, 82, 45, 119, 116, 247, 21, 116, 45, + 184, 237, 39, 116, 82, 45, 119, 116, 183, 116, 45, 184, 237, 39, 110, 82, + 45, 119, 116, 247, 21, 116, 45, 184, 237, 39, 110, 82, 45, 119, 116, 183, + 116, 45, 184, 237, 39, 110, 45, 119, 116, 247, 21, 116, 45, 184, 237, 39, + 110, 82, 45, 119, 116, 82, 183, 116, 45, 184, 237, 39, 110, 247, 22, 119, + 110, 82, 183, 116, 45, 184, 237, 39, 110, 45, 119, 110, 82, 183, 116, 45, + 184, 237, 39, 110, 247, 22, 119, 116, 82, 183, 116, 45, 184, 237, 39, + 110, 45, 119, 116, 82, 183, 116, 45, 184, 237, 39, 110, 247, 22, 119, + 116, 183, 116, 50, 184, 237, 39, 116, 247, 22, 119, 116, 82, 183, 116, + 50, 184, 237, 39, 116, 45, 119, 116, 82, 183, 116, 50, 184, 237, 39, 116, + 247, 22, 119, 110, 82, 183, 116, 50, 184, 237, 39, 116, 45, 119, 110, 82, + 183, 116, 50, 184, 237, 39, 116, 247, 22, 119, 110, 183, 116, 50, 184, + 237, 39, 116, 82, 45, 119, 110, 82, 183, 116, 23, 50, 23, 110, 197, 238, + 115, 208, 21, 248, 129, 45, 23, 110, 23, 50, 197, 238, 115, 208, 21, 248, + 129, 116, 23, 45, 23, 110, 197, 238, 115, 208, 21, 248, 129, 45, 23, 116, + 23, 50, 197, 238, 115, 208, 21, 248, 129, 45, 197, 238, 91, 208, 23, 248, + 129, 116, 197, 238, 91, 208, 23, 248, 129, 50, 197, 238, 91, 208, 23, + 248, 129, 110, 197, 238, 91, 208, 23, 248, 129, 81, 91, 234, 160, 248, + 127, 81, 91, 234, 160, 248, 126, 81, 91, 234, 160, 248, 125, 81, 91, 234, + 160, 248, 124, 81, 91, 234, 160, 248, 123, 81, 91, 234, 160, 248, 122, + 228, 241, 91, 234, 160, 248, 127, 228, 241, 91, 234, 160, 248, 126, 228, + 241, 91, 234, 160, 248, 125, 228, 241, 91, 234, 160, 248, 124, 228, 241, + 91, 234, 160, 248, 123, 228, 241, 91, 234, 160, 248, 122, 45, 23, 110, + 91, 234, 160, 248, 129, 45, 23, 116, 91, 234, 160, 248, 129, 50, 23, 116, + 91, 234, 160, 248, 129, 50, 23, 110, 91, 234, 160, 248, 129, 116, 23, + 110, 91, 234, 160, 248, 129, 228, 241, 91, 234, 160, 248, 128, 116, 91, + 208, 23, 248, 129, 116, 115, 234, 158, 248, 129, 116, 232, 226, 234, 158, + 248, 129, 116, 115, 208, 21, 248, 129, 116, 203, 247, 234, 158, 248, 129, + 50, 91, 208, 23, 248, 129, 50, 115, 234, 158, 248, 129, 50, 232, 226, + 234, 158, 248, 129, 50, 115, 208, 21, 248, 129, 50, 203, 247, 234, 158, + 248, 129, 45, 132, 216, 213, 203, 153, 50, 132, 216, 213, 203, 153, 116, + 132, 216, 213, 203, 153, 110, 132, 216, 213, 203, 153, 223, 95, 216, 213, + 203, 153, 116, 132, 184, 23, 110, 132, 223, 95, 216, 213, 203, 153, 116, + 132, 223, 95, 216, 213, 203, 154, 23, 110, 132, 248, 129, 45, 132, 223, + 95, 216, 213, 203, 154, 23, 50, 132, 248, 129, 243, 124, 248, 108, 233, + 5, 223, 95, 243, 124, 248, 108, 233, 5, 88, 228, 241, 233, 5, 116, 45, + 119, 110, 50, 233, 5, 116, 50, 119, 110, 45, 233, 5, 116, 23, 110, 197, + 238, 132, 248, 129, 45, 23, 50, 197, 238, 132, 248, 129, 116, 45, 197, + 238, 216, 213, 203, 153, 116, 50, 197, 238, 216, 213, 203, 153, 110, 50, + 197, 238, 216, 213, 203, 153, 110, 45, 197, 238, 216, 213, 203, 153, 111, + 122, 156, 237, 39, 116, 247, 22, 119, 82, 219, 224, 111, 122, 156, 237, + 39, 116, 247, 22, 119, 82, 183, 111, 122, 156, 237, 39, 82, 45, 119, 110, + 247, 21, 111, 122, 156, 237, 39, 82, 50, 119, 110, 247, 21, 111, 122, + 156, 237, 39, 116, 247, 22, 119, 82, 45, 119, 110, 247, 21, 111, 122, + 156, 237, 39, 116, 247, 22, 119, 82, 50, 119, 110, 247, 21, 111, 122, + 156, 237, 39, 82, 45, 119, 110, 247, 22, 119, 82, 183, 111, 122, 156, + 237, 39, 82, 45, 119, 116, 247, 22, 119, 82, 183, 111, 122, 156, 237, 39, + 116, 247, 22, 119, 82, 45, 23, 82, 50, 119, 110, 247, 21, 111, 122, 156, + 237, 39, 116, 247, 22, 119, 82, 50, 23, 82, 45, 119, 110, 247, 21, 111, + 122, 156, 237, 39, 116, 247, 22, 119, 82, 50, 119, 110, 247, 22, 119, 82, + 219, 224, 111, 122, 156, 237, 39, 116, 247, 22, 119, 82, 45, 119, 110, + 247, 22, 119, 82, 183, 111, 122, 156, 237, 39, 82, 45, 119, 116, 247, 22, + 119, 82, 50, 119, 110, 247, 21, 111, 122, 156, 237, 39, 82, 50, 119, 116, + 247, 22, 119, 82, 45, 119, 110, 247, 21, 111, 122, 156, 237, 39, 237, 32, + 111, 122, 156, 228, 241, 4, 81, 106, 250, 234, 209, 59, 223, 95, 243, + 126, 77, 45, 132, 206, 42, 217, 90, 50, 132, 206, 42, 217, 90, 223, 95, + 235, 119, 64, 4, 198, 136, 219, 214, 118, 64, 23, 116, 23, 110, 91, 234, + 160, 248, 129, 96, 64, 23, 116, 23, 110, 91, 234, 160, 248, 129, 235, + 119, 64, 23, 50, 91, 234, 160, 248, 129, 196, 66, 64, 23, 50, 91, 234, + 160, 248, 129, 45, 132, 232, 171, 50, 132, 232, 171, 195, 16, 35, 238, + 217, 50, 211, 77, 112, 236, 140, 214, 106, 237, 39, 238, 217, 214, 106, + 237, 39, 82, 50, 119, 110, 247, 21, 214, 106, 237, 39, 237, 32, 63, 88, + 205, 155, 4, 206, 113, 239, 0, 45, 199, 1, 63, 50, 209, 58, 223, 148, 82, + 199, 1, 63, 50, 209, 58, 223, 148, 50, 199, 1, 63, 50, 209, 58, 223, 148, + 214, 106, 112, 208, 13, 77, 201, 75, 233, 12, 201, 75, 233, 13, 4, 250, + 247, 207, 146, 201, 75, 233, 13, 219, 231, 219, 224, 201, 75, 233, 13, + 219, 231, 183, 201, 75, 233, 13, 4, 235, 106, 63, 196, 76, 243, 100, 205, + 42, 17, 191, 77, 205, 42, 17, 107, 205, 42, 17, 109, 205, 42, 17, 138, + 205, 42, 17, 134, 205, 42, 17, 149, 205, 42, 17, 169, 205, 42, 17, 175, + 205, 42, 17, 171, 205, 42, 17, 178, 12, 15, 228, 13, 12, 15, 228, 12, 12, + 15, 228, 11, 12, 15, 228, 10, 12, 15, 228, 9, 12, 15, 228, 8, 12, 15, + 228, 7, 12, 15, 228, 6, 12, 15, 228, 5, 12, 15, 228, 4, 12, 15, 228, 3, + 12, 15, 228, 2, 12, 15, 228, 1, 12, 15, 228, 0, 12, 15, 227, 255, 12, 15, + 227, 254, 12, 15, 227, 253, 12, 15, 227, 252, 12, 15, 227, 251, 12, 15, + 227, 250, 12, 15, 227, 249, 12, 15, 227, 248, 12, 15, 227, 247, 12, 15, + 227, 246, 12, 15, 227, 245, 12, 15, 227, 244, 12, 15, 227, 243, 12, 15, + 227, 242, 12, 15, 227, 241, 12, 15, 227, 240, 12, 15, 227, 239, 12, 15, + 227, 238, 12, 15, 227, 237, 12, 15, 227, 236, 12, 15, 227, 235, 12, 15, + 227, 234, 12, 15, 227, 233, 12, 15, 227, 232, 12, 15, 227, 231, 12, 15, + 227, 230, 12, 15, 227, 229, 12, 15, 227, 228, 12, 15, 227, 227, 12, 15, + 227, 226, 12, 15, 227, 225, 12, 15, 227, 224, 12, 15, 227, 223, 12, 15, + 227, 222, 12, 15, 227, 221, 12, 15, 227, 220, 12, 15, 227, 219, 12, 15, + 227, 218, 12, 15, 227, 217, 12, 15, 227, 216, 12, 15, 227, 215, 12, 15, + 227, 214, 12, 15, 227, 213, 12, 15, 227, 212, 12, 15, 227, 211, 12, 15, + 227, 210, 12, 15, 227, 209, 12, 15, 227, 208, 12, 15, 227, 207, 12, 15, + 227, 206, 12, 15, 227, 205, 12, 15, 227, 204, 12, 15, 227, 203, 12, 15, + 227, 202, 12, 15, 227, 201, 12, 15, 227, 200, 12, 15, 227, 199, 12, 15, + 227, 198, 12, 15, 227, 197, 12, 15, 227, 196, 12, 15, 227, 195, 12, 15, + 227, 194, 12, 15, 227, 193, 12, 15, 227, 192, 12, 15, 227, 191, 12, 15, + 227, 190, 12, 15, 227, 189, 12, 15, 227, 188, 12, 15, 227, 187, 12, 15, + 227, 186, 12, 15, 227, 185, 12, 15, 227, 184, 12, 15, 227, 183, 12, 15, + 227, 182, 12, 15, 227, 181, 12, 15, 227, 180, 12, 15, 227, 179, 12, 15, + 227, 178, 12, 15, 227, 177, 12, 15, 227, 176, 12, 15, 227, 175, 12, 15, + 227, 174, 12, 15, 227, 173, 12, 15, 227, 172, 12, 15, 227, 171, 12, 15, + 227, 170, 12, 15, 227, 169, 12, 15, 227, 168, 12, 15, 227, 167, 12, 15, + 227, 166, 12, 15, 227, 165, 12, 15, 227, 164, 12, 15, 227, 163, 12, 15, + 227, 162, 12, 15, 227, 161, 12, 15, 227, 160, 12, 15, 227, 159, 12, 15, + 227, 158, 12, 15, 227, 157, 12, 15, 227, 156, 12, 15, 227, 155, 12, 15, + 227, 154, 12, 15, 227, 153, 12, 15, 227, 152, 12, 15, 227, 151, 12, 15, + 227, 150, 12, 15, 227, 149, 12, 15, 227, 148, 12, 15, 227, 147, 12, 15, + 227, 146, 12, 15, 227, 145, 12, 15, 227, 144, 12, 15, 227, 143, 12, 15, + 227, 142, 12, 15, 227, 141, 12, 15, 227, 140, 12, 15, 227, 139, 12, 15, + 227, 138, 12, 15, 227, 137, 12, 15, 227, 136, 12, 15, 227, 135, 12, 15, + 227, 134, 12, 15, 227, 133, 12, 15, 227, 132, 12, 15, 227, 131, 12, 15, + 227, 130, 12, 15, 227, 129, 12, 15, 227, 128, 12, 15, 227, 127, 12, 15, + 227, 126, 12, 15, 227, 125, 12, 15, 227, 124, 12, 15, 227, 123, 12, 15, + 227, 122, 12, 15, 227, 121, 12, 15, 227, 120, 12, 15, 227, 119, 12, 15, + 227, 118, 12, 15, 227, 117, 12, 15, 227, 116, 12, 15, 227, 115, 12, 15, + 227, 114, 12, 15, 227, 113, 12, 15, 227, 112, 12, 15, 227, 111, 12, 15, + 227, 110, 12, 15, 227, 109, 12, 15, 227, 108, 12, 15, 227, 107, 12, 15, + 227, 106, 12, 15, 227, 105, 12, 15, 227, 104, 12, 15, 227, 103, 12, 15, + 227, 102, 12, 15, 227, 101, 12, 15, 227, 100, 12, 15, 227, 99, 12, 15, + 227, 98, 12, 15, 227, 97, 12, 15, 227, 96, 12, 15, 227, 95, 12, 15, 227, + 94, 12, 15, 227, 93, 12, 15, 227, 92, 12, 15, 227, 91, 12, 15, 227, 90, + 12, 15, 227, 89, 12, 15, 227, 88, 12, 15, 227, 87, 12, 15, 227, 86, 12, + 15, 227, 85, 12, 15, 227, 84, 12, 15, 227, 83, 12, 15, 227, 82, 12, 15, + 227, 81, 12, 15, 227, 80, 12, 15, 227, 79, 12, 15, 227, 78, 12, 15, 227, + 77, 12, 15, 227, 76, 12, 15, 227, 75, 12, 15, 227, 74, 12, 15, 227, 73, + 12, 15, 227, 72, 12, 15, 227, 71, 12, 15, 227, 70, 12, 15, 227, 69, 12, + 15, 227, 68, 12, 15, 227, 67, 12, 15, 227, 66, 12, 15, 227, 65, 12, 15, + 227, 64, 12, 15, 227, 63, 12, 15, 227, 62, 12, 15, 227, 61, 12, 15, 227, + 60, 12, 15, 227, 59, 12, 15, 227, 58, 12, 15, 227, 57, 12, 15, 227, 56, + 12, 15, 227, 55, 12, 15, 227, 54, 12, 15, 227, 53, 12, 15, 227, 52, 12, + 15, 227, 51, 12, 15, 227, 50, 12, 15, 227, 49, 12, 15, 227, 48, 12, 15, + 227, 47, 12, 15, 227, 46, 12, 15, 227, 45, 12, 15, 227, 44, 12, 15, 227, + 43, 12, 15, 227, 42, 12, 15, 227, 41, 12, 15, 227, 40, 12, 15, 227, 39, + 12, 15, 227, 38, 12, 15, 227, 37, 12, 15, 227, 36, 12, 15, 227, 35, 12, + 15, 227, 34, 12, 15, 227, 33, 12, 15, 227, 32, 12, 15, 227, 31, 12, 15, + 227, 30, 12, 15, 227, 29, 12, 15, 227, 28, 12, 15, 227, 27, 12, 15, 227, + 26, 12, 15, 227, 25, 12, 15, 227, 24, 12, 15, 227, 23, 12, 15, 227, 22, + 12, 15, 227, 21, 12, 15, 227, 20, 12, 15, 227, 19, 12, 15, 227, 18, 12, + 15, 227, 17, 12, 15, 227, 16, 12, 15, 227, 15, 12, 15, 227, 14, 12, 15, + 227, 13, 12, 15, 227, 12, 12, 15, 227, 11, 12, 15, 227, 10, 12, 15, 227, + 9, 12, 15, 227, 8, 12, 15, 227, 7, 12, 15, 227, 6, 12, 15, 227, 5, 12, + 15, 227, 4, 12, 15, 227, 3, 12, 15, 227, 2, 12, 15, 227, 1, 12, 15, 227, + 0, 12, 15, 226, 255, 12, 15, 226, 254, 12, 15, 226, 253, 12, 15, 226, + 252, 12, 15, 226, 251, 12, 15, 226, 250, 12, 15, 226, 249, 12, 15, 226, + 248, 12, 15, 226, 247, 12, 15, 226, 246, 12, 15, 226, 245, 12, 15, 226, + 244, 12, 15, 226, 243, 12, 15, 226, 242, 12, 15, 226, 241, 12, 15, 226, + 240, 12, 15, 226, 239, 12, 15, 226, 238, 12, 15, 226, 237, 12, 15, 226, + 236, 12, 15, 226, 235, 12, 15, 226, 234, 12, 15, 226, 233, 12, 15, 226, + 232, 12, 15, 226, 231, 12, 15, 226, 230, 12, 15, 226, 229, 12, 15, 226, + 228, 12, 15, 226, 227, 12, 15, 226, 226, 12, 15, 226, 225, 12, 15, 226, + 224, 12, 15, 226, 223, 12, 15, 226, 222, 12, 15, 226, 221, 12, 15, 226, + 220, 12, 15, 226, 219, 12, 15, 226, 218, 12, 15, 226, 217, 12, 15, 226, + 216, 12, 15, 226, 215, 12, 15, 226, 214, 12, 15, 226, 213, 12, 15, 226, + 212, 12, 15, 226, 211, 12, 15, 226, 210, 12, 15, 226, 209, 12, 15, 226, + 208, 12, 15, 226, 207, 12, 15, 226, 206, 12, 15, 226, 205, 12, 15, 226, + 204, 12, 15, 226, 203, 12, 15, 226, 202, 12, 15, 226, 201, 12, 15, 226, + 200, 12, 15, 226, 199, 12, 15, 226, 198, 12, 15, 226, 197, 12, 15, 226, + 196, 12, 15, 226, 195, 12, 15, 226, 194, 12, 15, 226, 193, 12, 15, 226, + 192, 12, 15, 226, 191, 12, 15, 226, 190, 12, 15, 226, 189, 12, 15, 226, + 188, 12, 15, 226, 187, 12, 15, 226, 186, 12, 15, 226, 185, 12, 15, 226, + 184, 12, 15, 226, 183, 12, 15, 226, 182, 12, 15, 226, 181, 12, 15, 226, + 180, 12, 15, 226, 179, 12, 15, 226, 178, 12, 15, 226, 177, 12, 15, 226, + 176, 12, 15, 226, 175, 12, 15, 226, 174, 12, 15, 226, 173, 12, 15, 226, + 172, 12, 15, 226, 171, 12, 15, 226, 170, 12, 15, 226, 169, 12, 15, 226, + 168, 12, 15, 226, 167, 12, 15, 226, 166, 12, 15, 226, 165, 12, 15, 226, + 164, 12, 15, 226, 163, 12, 15, 226, 162, 12, 15, 226, 161, 12, 15, 226, + 160, 12, 15, 226, 159, 12, 15, 226, 158, 12, 15, 226, 157, 12, 15, 226, + 156, 12, 15, 226, 155, 12, 15, 226, 154, 12, 15, 226, 153, 12, 15, 226, + 152, 12, 15, 226, 151, 12, 15, 226, 150, 12, 15, 226, 149, 12, 15, 226, + 148, 12, 15, 226, 147, 12, 15, 226, 146, 12, 15, 226, 145, 12, 15, 226, + 144, 12, 15, 226, 143, 12, 15, 226, 142, 12, 15, 226, 141, 12, 15, 226, + 140, 12, 15, 226, 139, 12, 15, 226, 138, 12, 15, 226, 137, 12, 15, 226, + 136, 12, 15, 226, 135, 12, 15, 226, 134, 12, 15, 226, 133, 12, 15, 226, + 132, 12, 15, 226, 131, 12, 15, 226, 130, 12, 15, 226, 129, 12, 15, 226, + 128, 12, 15, 226, 127, 12, 15, 226, 126, 12, 15, 226, 125, 12, 15, 226, + 124, 12, 15, 226, 123, 12, 15, 226, 122, 12, 15, 226, 121, 12, 15, 226, + 120, 12, 15, 226, 119, 12, 15, 226, 118, 12, 15, 226, 117, 12, 15, 226, + 116, 12, 15, 226, 115, 12, 15, 226, 114, 12, 15, 226, 113, 12, 15, 226, + 112, 12, 15, 226, 111, 12, 15, 226, 110, 12, 15, 226, 109, 12, 15, 226, + 108, 12, 15, 226, 107, 12, 15, 226, 106, 12, 15, 226, 105, 12, 15, 226, + 104, 12, 15, 226, 103, 12, 15, 226, 102, 12, 15, 226, 101, 12, 15, 226, + 100, 12, 15, 226, 99, 12, 15, 226, 98, 12, 15, 226, 97, 12, 15, 226, 96, + 12, 15, 226, 95, 12, 15, 226, 94, 12, 15, 226, 93, 12, 15, 226, 92, 12, + 15, 226, 91, 12, 15, 226, 90, 12, 15, 226, 89, 12, 15, 226, 88, 12, 15, + 226, 87, 12, 15, 226, 86, 12, 15, 226, 85, 12, 15, 226, 84, 12, 15, 226, + 83, 12, 15, 226, 82, 12, 15, 226, 81, 12, 15, 226, 80, 12, 15, 226, 79, + 12, 15, 226, 78, 12, 15, 226, 77, 12, 15, 226, 76, 12, 15, 226, 75, 12, + 15, 226, 74, 12, 15, 226, 73, 12, 15, 226, 72, 12, 15, 226, 71, 12, 15, + 226, 70, 12, 15, 226, 69, 12, 15, 226, 68, 12, 15, 226, 67, 12, 15, 226, + 66, 12, 15, 226, 65, 12, 15, 226, 64, 12, 15, 226, 63, 12, 15, 226, 62, + 12, 15, 226, 61, 12, 15, 226, 60, 12, 15, 226, 59, 12, 15, 226, 58, 12, + 15, 226, 57, 12, 15, 226, 56, 12, 15, 226, 55, 12, 15, 226, 54, 12, 15, + 226, 53, 12, 15, 226, 52, 12, 15, 226, 51, 12, 15, 226, 50, 12, 15, 226, + 49, 12, 15, 226, 48, 12, 15, 226, 47, 12, 15, 226, 46, 12, 15, 226, 45, + 12, 15, 226, 44, 12, 15, 226, 43, 12, 15, 226, 42, 12, 15, 226, 41, 12, + 15, 226, 40, 12, 15, 226, 39, 12, 15, 226, 38, 12, 15, 226, 37, 12, 15, + 226, 36, 12, 15, 226, 35, 12, 15, 226, 34, 12, 15, 226, 33, 12, 15, 226, + 32, 12, 15, 226, 31, 12, 15, 226, 30, 12, 15, 226, 29, 12, 15, 226, 28, + 12, 15, 226, 27, 12, 15, 226, 26, 12, 15, 226, 25, 12, 15, 226, 24, 12, + 15, 226, 23, 12, 15, 226, 22, 12, 15, 226, 21, 12, 15, 226, 20, 12, 15, + 226, 19, 12, 15, 226, 18, 12, 15, 226, 17, 12, 15, 226, 16, 12, 15, 226, + 15, 12, 15, 226, 14, 12, 15, 226, 13, 12, 15, 226, 12, 12, 15, 226, 11, + 12, 15, 226, 10, 12, 15, 226, 9, 12, 15, 226, 8, 12, 15, 226, 7, 12, 15, + 226, 6, 12, 15, 226, 5, 12, 15, 226, 4, 12, 15, 226, 3, 12, 15, 226, 2, + 12, 15, 226, 1, 12, 15, 226, 0, 12, 15, 225, 255, 12, 15, 225, 254, 12, + 15, 225, 253, 12, 15, 225, 252, 12, 15, 225, 251, 12, 15, 225, 250, 12, + 15, 225, 249, 12, 15, 225, 248, 12, 15, 225, 247, 12, 15, 225, 246, 12, + 15, 225, 245, 12, 15, 225, 244, 12, 15, 225, 243, 12, 15, 225, 242, 12, + 15, 225, 241, 12, 15, 225, 240, 220, 20, 199, 223, 199, 224, 201, 247, + 199, 224, 233, 216, 77, 199, 224, 207, 252, 77, 199, 224, 31, 56, 199, + 224, 236, 155, 56, 199, 224, 210, 13, 56, 199, 224, 251, 137, 199, 224, + 251, 49, 199, 224, 45, 210, 113, 199, 224, 50, 210, 113, 199, 224, 250, + 193, 199, 224, 108, 56, 199, 224, 242, 74, 199, 224, 228, 87, 199, 224, + 232, 80, 201, 63, 199, 224, 202, 23, 199, 224, 17, 191, 77, 199, 224, 17, + 107, 199, 224, 17, 109, 199, 224, 17, 138, 199, 224, 17, 134, 199, 224, + 17, 149, 199, 224, 17, 169, 199, 224, 17, 175, 199, 224, 17, 171, 199, + 224, 17, 178, 199, 224, 242, 83, 199, 224, 204, 25, 199, 224, 219, 180, + 56, 199, 224, 234, 43, 56, 199, 224, 230, 204, 56, 199, 224, 208, 13, 77, + 199, 224, 242, 72, 250, 182, 199, 224, 8, 6, 1, 65, 199, 224, 8, 6, 1, + 250, 120, 199, 224, 8, 6, 1, 247, 193, 199, 224, 8, 6, 1, 238, 127, 199, + 224, 8, 6, 1, 71, 199, 224, 8, 6, 1, 233, 175, 199, 224, 8, 6, 1, 232, + 51, 199, 224, 8, 6, 1, 230, 116, 199, 224, 8, 6, 1, 68, 199, 224, 8, 6, + 1, 223, 35, 199, 224, 8, 6, 1, 222, 152, 199, 224, 8, 6, 1, 172, 199, + 224, 8, 6, 1, 218, 168, 199, 224, 8, 6, 1, 215, 61, 199, 224, 8, 6, 1, + 74, 199, 224, 8, 6, 1, 210, 236, 199, 224, 8, 6, 1, 208, 104, 199, 224, + 8, 6, 1, 146, 199, 224, 8, 6, 1, 206, 8, 199, 224, 8, 6, 1, 200, 43, 199, + 224, 8, 6, 1, 66, 199, 224, 8, 6, 1, 196, 12, 199, 224, 8, 6, 1, 193, + 224, 199, 224, 8, 6, 1, 192, 235, 199, 224, 8, 6, 1, 192, 159, 199, 224, + 8, 6, 1, 191, 166, 199, 224, 45, 51, 248, 53, 199, 224, 207, 19, 202, 23, + 199, 224, 50, 51, 248, 53, 199, 224, 243, 2, 252, 60, 199, 224, 130, 219, + 112, 199, 224, 230, 211, 252, 60, 199, 224, 8, 2, 1, 65, 199, 224, 8, 2, + 1, 250, 120, 199, 224, 8, 2, 1, 247, 193, 199, 224, 8, 2, 1, 238, 127, + 199, 224, 8, 2, 1, 71, 199, 224, 8, 2, 1, 233, 175, 199, 224, 8, 2, 1, + 232, 51, 199, 224, 8, 2, 1, 230, 116, 199, 224, 8, 2, 1, 68, 199, 224, 8, + 2, 1, 223, 35, 199, 224, 8, 2, 1, 222, 152, 199, 224, 8, 2, 1, 172, 199, + 224, 8, 2, 1, 218, 168, 199, 224, 8, 2, 1, 215, 61, 199, 224, 8, 2, 1, + 74, 199, 224, 8, 2, 1, 210, 236, 199, 224, 8, 2, 1, 208, 104, 199, 224, + 8, 2, 1, 146, 199, 224, 8, 2, 1, 206, 8, 199, 224, 8, 2, 1, 200, 43, 199, + 224, 8, 2, 1, 66, 199, 224, 8, 2, 1, 196, 12, 199, 224, 8, 2, 1, 193, + 224, 199, 224, 8, 2, 1, 192, 235, 199, 224, 8, 2, 1, 192, 159, 199, 224, + 8, 2, 1, 191, 166, 199, 224, 45, 238, 171, 248, 53, 199, 224, 81, 219, + 112, 199, 224, 50, 238, 171, 248, 53, 199, 224, 198, 152, 247, 127, 199, + 223, 67, 204, 211, 67, 204, 200, 67, 204, 189, 67, 204, 177, 67, 204, + 166, 67, 204, 155, 67, 204, 144, 67, 204, 133, 67, 204, 122, 67, 204, + 114, 67, 204, 113, 67, 204, 112, 67, 204, 111, 67, 204, 109, 67, 204, + 108, 67, 204, 107, 67, 204, 106, 67, 204, 105, 67, 204, 104, 67, 204, + 103, 67, 204, 102, 67, 204, 101, 67, 204, 100, 67, 204, 98, 67, 204, 97, + 67, 204, 96, 67, 204, 95, 67, 204, 94, 67, 204, 93, 67, 204, 92, 67, 204, + 91, 67, 204, 90, 67, 204, 89, 67, 204, 87, 67, 204, 86, 67, 204, 85, 67, + 204, 84, 67, 204, 83, 67, 204, 82, 67, 204, 81, 67, 204, 80, 67, 204, 79, + 67, 204, 78, 67, 204, 76, 67, 204, 75, 67, 204, 74, 67, 204, 73, 67, 204, + 72, 67, 204, 71, 67, 204, 70, 67, 204, 69, 67, 204, 68, 67, 204, 67, 67, + 204, 65, 67, 204, 64, 67, 204, 63, 67, 204, 62, 67, 204, 61, 67, 204, 60, + 67, 204, 59, 67, 204, 58, 67, 204, 57, 67, 204, 56, 67, 204, 54, 67, 204, + 53, 67, 204, 52, 67, 204, 51, 67, 204, 50, 67, 204, 49, 67, 204, 48, 67, + 204, 47, 67, 204, 46, 67, 204, 45, 67, 204, 43, 67, 204, 42, 67, 204, 41, + 67, 204, 40, 67, 204, 39, 67, 204, 38, 67, 204, 37, 67, 204, 36, 67, 204, + 35, 67, 204, 34, 67, 205, 31, 67, 205, 30, 67, 205, 29, 67, 205, 28, 67, + 205, 27, 67, 205, 26, 67, 205, 25, 67, 205, 24, 67, 205, 23, 67, 205, 22, + 67, 205, 20, 67, 205, 19, 67, 205, 18, 67, 205, 17, 67, 205, 16, 67, 205, + 15, 67, 205, 14, 67, 205, 13, 67, 205, 12, 67, 205, 11, 67, 205, 9, 67, + 205, 8, 67, 205, 7, 67, 205, 6, 67, 205, 5, 67, 205, 4, 67, 205, 3, 67, + 205, 2, 67, 205, 1, 67, 205, 0, 67, 204, 254, 67, 204, 253, 67, 204, 252, + 67, 204, 251, 67, 204, 250, 67, 204, 249, 67, 204, 248, 67, 204, 247, 67, + 204, 246, 67, 204, 245, 67, 204, 243, 67, 204, 242, 67, 204, 241, 67, + 204, 240, 67, 204, 239, 67, 204, 238, 67, 204, 237, 67, 204, 236, 67, + 204, 235, 67, 204, 234, 67, 204, 232, 67, 204, 231, 67, 204, 230, 67, + 204, 229, 67, 204, 228, 67, 204, 227, 67, 204, 226, 67, 204, 225, 67, + 204, 224, 67, 204, 223, 67, 204, 221, 67, 204, 220, 67, 204, 219, 67, + 204, 218, 67, 204, 217, 67, 204, 216, 67, 204, 215, 67, 204, 214, 67, + 204, 213, 67, 204, 212, 67, 204, 210, 67, 204, 209, 67, 204, 208, 67, + 204, 207, 67, 204, 206, 67, 204, 205, 67, 204, 204, 67, 204, 203, 67, + 204, 202, 67, 204, 201, 67, 204, 199, 67, 204, 198, 67, 204, 197, 67, + 204, 196, 67, 204, 195, 67, 204, 194, 67, 204, 193, 67, 204, 192, 67, + 204, 191, 67, 204, 190, 67, 204, 188, 67, 204, 187, 67, 204, 186, 67, + 204, 185, 67, 204, 184, 67, 204, 183, 67, 204, 182, 67, 204, 181, 67, + 204, 180, 67, 204, 179, 67, 204, 176, 67, 204, 175, 67, 204, 174, 67, + 204, 173, 67, 204, 172, 67, 204, 171, 67, 204, 170, 67, 204, 169, 67, + 204, 168, 67, 204, 167, 67, 204, 165, 67, 204, 164, 67, 204, 163, 67, + 204, 162, 67, 204, 161, 67, 204, 160, 67, 204, 159, 67, 204, 158, 67, + 204, 157, 67, 204, 156, 67, 204, 154, 67, 204, 153, 67, 204, 152, 67, + 204, 151, 67, 204, 150, 67, 204, 149, 67, 204, 148, 67, 204, 147, 67, + 204, 146, 67, 204, 145, 67, 204, 143, 67, 204, 142, 67, 204, 141, 67, + 204, 140, 67, 204, 139, 67, 204, 138, 67, 204, 137, 67, 204, 136, 67, + 204, 135, 67, 204, 134, 67, 204, 132, 67, 204, 131, 67, 204, 130, 67, + 204, 129, 67, 204, 128, 67, 204, 127, 67, 204, 126, 67, 204, 125, 67, + 204, 124, 67, 204, 123, 67, 204, 121, 67, 204, 120, 67, 204, 119, 67, + 204, 118, 67, 204, 117, 67, 204, 116, 67, 204, 115, 212, 138, 212, 140, + 201, 98, 79, 229, 232, 202, 27, 201, 98, 79, 199, 53, 201, 6, 234, 95, + 79, 199, 53, 233, 244, 234, 95, 79, 198, 11, 234, 57, 234, 81, 234, 82, + 252, 51, 252, 52, 251, 189, 248, 238, 249, 140, 248, 16, 246, 240, 199, + 230, 228, 241, 199, 230, 228, 165, 199, 236, 219, 113, 233, 50, 214, 80, + 219, 112, 234, 95, 79, 219, 112, 219, 161, 213, 105, 234, 60, 219, 113, + 199, 230, 81, 199, 230, 193, 251, 232, 146, 233, 50, 233, 27, 247, 88, + 207, 22, 238, 236, 203, 77, 211, 14, 219, 33, 107, 202, 46, 203, 77, 223, + 162, 219, 33, 191, 77, 202, 222, 237, 210, 219, 103, 234, 14, 236, 185, + 237, 75, 239, 22, 107, 237, 199, 237, 75, 239, 22, 109, 237, 198, 237, + 75, 239, 22, 138, 237, 197, 237, 75, 239, 22, 134, 237, 196, 214, 106, + 252, 51, 214, 233, 200, 69, 223, 228, 200, 73, 234, 95, 79, 198, 12, 248, + 129, 233, 252, 247, 126, 247, 128, 234, 95, 79, 216, 212, 234, 58, 234, + 114, 200, 226, 200, 245, 234, 14, 234, 15, 223, 137, 204, 11, 134, 233, + 7, 204, 10, 232, 90, 223, 137, 204, 11, 138, 230, 187, 204, 10, 230, 184, + 223, 137, 204, 11, 109, 207, 98, 204, 10, 206, 74, 223, 137, 204, 11, + 107, 196, 91, 204, 10, 196, 45, 201, 250, 237, 116, 237, 118, 210, 208, + 246, 239, 210, 210, 137, 211, 158, 208, 220, 228, 244, 248, 42, 210, 1, + 229, 192, 248, 58, 213, 44, 248, 42, 229, 192, 214, 191, 223, 148, 223, + 150, 214, 73, 219, 112, 214, 104, 201, 98, 79, 205, 36, 251, 8, 201, 175, + 234, 95, 79, 205, 36, 251, 8, 234, 17, 246, 240, 199, 231, 203, 252, 228, + 241, 199, 231, 203, 252, 228, 162, 246, 240, 199, 231, 4, 222, 164, 228, + 241, 199, 231, 4, 222, 164, 228, 163, 219, 113, 199, 231, 203, 252, 81, + 199, 231, 203, 252, 193, 250, 210, 105, 219, 113, 232, 132, 210, 105, + 219, 113, 235, 123, 209, 94, 210, 105, 219, 113, 249, 139, 210, 105, 219, + 113, 196, 77, 209, 88, 207, 19, 219, 113, 233, 50, 207, 19, 223, 148, + 207, 1, 202, 170, 203, 77, 109, 202, 167, 201, 177, 202, 170, 203, 77, + 138, 202, 166, 201, 176, 237, 75, 239, 22, 201, 30, 237, 194, 208, 205, + 196, 44, 107, 208, 205, 196, 42, 208, 164, 208, 205, 196, 44, 109, 208, + 205, 196, 41, 208, 163, 203, 253, 198, 10, 201, 95, 201, 13, 247, 127, + 246, 239, 247, 61, 216, 169, 193, 171, 215, 81, 201, 98, 79, 230, 172, + 251, 8, 201, 98, 79, 208, 182, 251, 8, 201, 249, 234, 95, 79, 230, 172, + 251, 8, 234, 95, 79, 208, 182, 251, 8, 234, 55, 201, 98, 79, 201, 30, + 202, 9, 202, 170, 230, 216, 246, 240, 223, 96, 203, 170, 202, 170, 246, + 240, 223, 96, 205, 85, 239, 22, 204, 7, 223, 96, 238, 196, 201, 31, 199, + 80, 201, 118, 211, 68, 200, 58, 242, 73, 211, 34, 208, 206, 216, 168, + 209, 76, 251, 45, 208, 198, 242, 73, 251, 62, 214, 179, 202, 231, 8, 6, + 1, 231, 91, 8, 2, 1, 231, 91, 247, 4, 9, 2, 137, 34, 131, 4, 99, 249, 80, + 251, 166, 200, 63, 200, 232, 242, 84, 202, 110, 219, 224, 222, 81, 1, + 219, 62, 220, 17, 1, 232, 176, 232, 166, 220, 17, 1, 232, 176, 233, 62, + 220, 17, 1, 206, 162, 220, 17, 1, 219, 43, 86, 87, 248, 141, 203, 50, + 231, 54, 216, 118, 207, 9, 30, 125, 192, 54, 30, 125, 192, 50, 30, 125, + 201, 153, 30, 125, 192, 55, 232, 66, 232, 65, 232, 64, 215, 83, 232, 63, + 200, 197, 1, 251, 14, 68, 190, 232, 190, 233, 190, 235, 218, 229, 206, + 170, 218, 231, 206, 172, 210, 66, 218, 228, 206, 169, 213, 75, 216, 16, + 193, 50, 218, 230, 206, 171, 232, 89, 210, 65, 193, 111, 234, 119, 232, + 76, 216, 92, 211, 105, 196, 46, 113, 216, 92, 237, 216, 113, 118, 197, + 240, 64, 4, 55, 81, 106, 96, 197, 240, 64, 4, 55, 81, 106, 11, 5, 223, + 51, 77, 80, 1, 221, 206, 219, 73, 194, 251, 194, 140, 194, 72, 194, 61, + 194, 50, 194, 39, 194, 28, 194, 17, 194, 6, 194, 250, 194, 239, 194, 228, + 194, 217, 194, 206, 194, 195, 194, 184, 208, 221, 232, 146, 40, 81, 50, + 63, 219, 187, 248, 53, 247, 198, 211, 51, 77, 248, 100, 190, 234, 10, 3, + 212, 148, 199, 84, 10, 3, 212, 148, 139, 212, 148, 247, 231, 139, 247, + 230, 216, 218, 6, 1, 230, 116, 216, 218, 6, 1, 214, 70, 216, 218, 2, 1, + 230, 116, 216, 218, 2, 1, 214, 70, 61, 1, 235, 14, 73, 37, 16, 232, 88, + 202, 106, 243, 52, 195, 164, 194, 173, 194, 162, 194, 151, 194, 139, 194, + 128, 194, 117, 194, 106, 194, 95, 194, 84, 194, 76, 194, 75, 194, 74, + 194, 73, 194, 71, 194, 70, 194, 69, 194, 68, 194, 67, 194, 66, 194, 65, + 194, 64, 194, 63, 194, 62, 194, 60, 194, 59, 194, 58, 194, 57, 194, 56, + 194, 55, 194, 54, 194, 53, 194, 52, 194, 51, 194, 49, 194, 48, 194, 47, + 194, 46, 194, 45, 194, 44, 194, 43, 194, 42, 194, 41, 194, 40, 194, 38, + 194, 37, 194, 36, 194, 35, 194, 34, 194, 33, 194, 32, 194, 31, 194, 30, + 194, 29, 194, 27, 194, 26, 194, 25, 194, 24, 194, 23, 194, 22, 194, 21, + 194, 20, 194, 19, 194, 18, 194, 16, 194, 15, 194, 14, 194, 13, 194, 12, + 194, 11, 194, 10, 194, 9, 194, 8, 194, 7, 194, 5, 194, 4, 194, 3, 194, 2, + 194, 1, 194, 0, 193, 255, 193, 254, 193, 253, 193, 252, 194, 249, 194, + 248, 194, 247, 194, 246, 194, 245, 194, 244, 194, 243, 194, 242, 194, + 241, 194, 240, 194, 238, 194, 237, 194, 236, 194, 235, 194, 234, 194, + 233, 194, 232, 194, 231, 194, 230, 194, 229, 194, 227, 194, 226, 194, + 225, 194, 224, 194, 223, 194, 222, 194, 221, 194, 220, 194, 219, 194, + 218, 194, 216, 194, 215, 194, 214, 194, 213, 194, 212, 194, 211, 194, + 210, 194, 209, 194, 208, 194, 207, 194, 205, 194, 204, 194, 203, 194, + 202, 194, 201, 194, 200, 194, 199, 194, 198, 194, 197, 194, 196, 194, + 194, 194, 193, 194, 192, 194, 191, 194, 190, 194, 189, 194, 188, 194, + 187, 194, 186, 194, 185, 194, 183, 194, 182, 194, 181, 194, 180, 194, + 179, 194, 178, 194, 177, 194, 176, 194, 175, 194, 174, 194, 172, 194, + 171, 194, 170, 194, 169, 194, 168, 194, 167, 194, 166, 194, 165, 194, + 164, 194, 163, 194, 161, 194, 160, 194, 159, 194, 158, 194, 157, 194, + 156, 194, 155, 194, 154, 194, 153, 194, 152, 194, 150, 194, 149, 194, + 148, 194, 147, 194, 146, 194, 145, 194, 144, 194, 143, 194, 142, 194, + 141, 194, 138, 194, 137, 194, 136, 194, 135, 194, 134, 194, 133, 194, + 132, 194, 131, 194, 130, 194, 129, 194, 127, 194, 126, 194, 125, 194, + 124, 194, 123, 194, 122, 194, 121, 194, 120, 194, 119, 194, 118, 194, + 116, 194, 115, 194, 114, 194, 113, 194, 112, 194, 111, 194, 110, 194, + 109, 194, 108, 194, 107, 194, 105, 194, 104, 194, 103, 194, 102, 194, + 101, 194, 100, 194, 99, 194, 98, 194, 97, 194, 96, 194, 94, 194, 93, 194, + 92, 194, 91, 194, 90, 194, 89, 194, 88, 194, 87, 194, 86, 194, 85, 194, + 83, 194, 82, 194, 81, 194, 80, 194, 79, 194, 78, 194, 77, 221, 219, 31, + 56, 221, 219, 250, 193, 221, 219, 17, 191, 77, 221, 219, 17, 107, 221, + 219, 17, 109, 221, 219, 17, 138, 221, 219, 17, 134, 221, 219, 17, 149, + 221, 219, 17, 169, 221, 219, 17, 175, 221, 219, 17, 171, 221, 219, 17, + 178, 8, 6, 1, 42, 4, 217, 147, 23, 230, 210, 8, 2, 1, 42, 4, 217, 147, + 23, 230, 210, 8, 6, 1, 228, 74, 4, 217, 147, 23, 230, 210, 8, 2, 1, 228, + 74, 4, 217, 147, 23, 230, 210, 8, 6, 1, 126, 4, 217, 147, 23, 230, 210, + 8, 2, 1, 126, 4, 217, 147, 23, 230, 210, 8, 6, 1, 235, 15, 4, 81, 219, + 113, 60, 8, 2, 1, 235, 15, 4, 81, 219, 113, 60, 8, 6, 1, 235, 15, 4, 81, + 219, 113, 248, 233, 23, 230, 210, 8, 2, 1, 235, 15, 4, 81, 219, 113, 248, + 233, 23, 230, 210, 8, 6, 1, 235, 15, 4, 81, 219, 113, 248, 233, 23, 252, + 46, 8, 2, 1, 235, 15, 4, 81, 219, 113, 248, 233, 23, 252, 46, 8, 6, 1, + 187, 4, 81, 219, 113, 60, 8, 2, 1, 187, 4, 81, 219, 113, 60, 8, 6, 1, + 187, 4, 81, 219, 113, 248, 233, 23, 230, 210, 8, 2, 1, 187, 4, 81, 219, + 113, 248, 233, 23, 230, 210, 8, 6, 1, 187, 4, 81, 219, 113, 248, 233, 23, + 252, 46, 8, 2, 1, 187, 4, 81, 219, 113, 248, 233, 23, 252, 46, 8, 6, 1, + 206, 9, 4, 81, 219, 113, 60, 8, 2, 1, 206, 9, 4, 81, 219, 113, 60, 8, 6, + 1, 235, 15, 4, 243, 2, 23, 217, 146, 8, 2, 1, 235, 15, 4, 243, 2, 23, + 217, 146, 8, 6, 1, 235, 15, 4, 243, 2, 23, 247, 92, 8, 2, 1, 235, 15, 4, + 243, 2, 23, 247, 92, 8, 2, 1, 228, 74, 4, 75, 93, 23, 252, 46, 8, 2, 1, + 214, 71, 4, 198, 153, 58, 8, 6, 1, 42, 4, 211, 139, 23, 252, 46, 8, 2, 1, + 42, 4, 211, 139, 23, 252, 46, 8, 6, 1, 42, 4, 211, 139, 23, 198, 152, 8, + 2, 1, 42, 4, 211, 139, 23, 198, 152, 8, 6, 1, 235, 15, 4, 211, 139, 23, + 252, 46, 8, 2, 1, 235, 15, 4, 211, 139, 23, 252, 46, 8, 6, 1, 235, 15, 4, + 211, 139, 23, 198, 152, 8, 2, 1, 235, 15, 4, 211, 139, 23, 198, 152, 8, + 6, 1, 235, 15, 4, 75, 93, 23, 252, 46, 8, 2, 1, 235, 15, 4, 75, 93, 23, + 252, 46, 8, 6, 1, 235, 15, 4, 75, 93, 23, 198, 152, 8, 2, 1, 235, 15, 4, + 75, 93, 23, 198, 152, 8, 2, 1, 228, 74, 4, 75, 93, 23, 230, 210, 8, 2, 1, + 228, 74, 4, 75, 93, 23, 198, 152, 8, 6, 1, 228, 74, 4, 211, 139, 23, 252, + 46, 8, 2, 1, 228, 74, 4, 211, 139, 23, 75, 93, 23, 252, 46, 8, 6, 1, 228, + 74, 4, 211, 139, 23, 198, 152, 8, 2, 1, 228, 74, 4, 211, 139, 23, 75, 93, + 23, 198, 152, 8, 6, 1, 223, 36, 4, 198, 152, 8, 2, 1, 223, 36, 4, 75, 93, + 23, 198, 152, 8, 6, 1, 220, 143, 4, 198, 152, 8, 2, 1, 220, 143, 4, 198, + 152, 8, 6, 1, 218, 169, 4, 198, 152, 8, 2, 1, 218, 169, 4, 198, 152, 8, + 6, 1, 207, 222, 4, 198, 152, 8, 2, 1, 207, 222, 4, 198, 152, 8, 6, 1, + 126, 4, 211, 139, 23, 252, 46, 8, 2, 1, 126, 4, 211, 139, 23, 252, 46, 8, + 6, 1, 126, 4, 211, 139, 23, 198, 152, 8, 2, 1, 126, 4, 211, 139, 23, 198, + 152, 8, 6, 1, 126, 4, 217, 147, 23, 252, 46, 8, 2, 1, 126, 4, 217, 147, + 23, 252, 46, 8, 6, 1, 126, 4, 217, 147, 23, 198, 152, 8, 2, 1, 126, 4, + 217, 147, 23, 198, 152, 8, 2, 1, 252, 26, 4, 230, 210, 8, 2, 1, 211, 77, + 187, 4, 230, 210, 8, 2, 1, 211, 77, 187, 4, 252, 46, 8, 2, 1, 153, 196, + 13, 4, 230, 210, 8, 2, 1, 153, 196, 13, 4, 252, 46, 8, 2, 1, 205, 87, 4, + 230, 210, 8, 2, 1, 205, 87, 4, 252, 46, 8, 2, 1, 228, 250, 205, 87, 4, + 230, 210, 8, 2, 1, 228, 250, 205, 87, 4, 252, 46, 9, 204, 7, 99, 4, 230, + 58, 93, 4, 251, 192, 9, 204, 7, 99, 4, 230, 58, 93, 4, 193, 133, 9, 204, + 7, 99, 4, 230, 58, 93, 4, 131, 217, 99, 9, 204, 7, 99, 4, 230, 58, 93, 4, + 211, 151, 9, 204, 7, 99, 4, 230, 58, 93, 4, 66, 9, 204, 7, 99, 4, 230, + 58, 93, 4, 191, 225, 9, 204, 7, 99, 4, 230, 58, 93, 4, 71, 9, 204, 7, 99, + 4, 230, 58, 93, 4, 252, 25, 9, 204, 7, 213, 25, 4, 222, 4, 100, 204, 7, + 40, 1, 208, 96, 100, 204, 7, 40, 1, 221, 193, 100, 204, 7, 40, 1, 231, + 66, 100, 204, 7, 40, 1, 191, 123, 100, 204, 7, 40, 1, 237, 180, 100, 204, + 7, 40, 1, 207, 6, 100, 204, 7, 40, 1, 233, 109, 100, 204, 7, 40, 1, 191, + 175, 248, 225, 204, 7, 40, 1, 206, 109, 248, 225, 204, 7, 40, 1, 207, 6, + 248, 225, 204, 7, 40, 1, 191, 175, 230, 144, 204, 7, 40, 1, 219, 73, 230, + 144, 204, 7, 40, 1, 203, 165, 230, 144, 204, 7, 40, 1, 221, 193, 230, + 144, 204, 7, 40, 1, 231, 66, 230, 144, 204, 7, 40, 1, 191, 123, 230, 144, + 204, 7, 40, 1, 233, 109, 211, 45, 204, 7, 40, 1, 206, 109, 211, 45, 204, + 7, 40, 1, 207, 6, 248, 225, 1, 221, 187, 44, 120, 222, 152, 44, 120, 214, + 70, 44, 120, 247, 193, 44, 120, 212, 103, 44, 120, 197, 135, 44, 120, + 213, 80, 44, 120, 200, 43, 44, 120, 215, 61, 44, 120, 210, 236, 44, 120, + 218, 168, 44, 120, 192, 159, 44, 120, 146, 44, 120, 172, 44, 120, 196, + 12, 44, 120, 219, 63, 44, 120, 219, 74, 44, 120, 206, 110, 44, 120, 213, + 62, 44, 120, 223, 35, 44, 120, 203, 167, 44, 120, 201, 178, 44, 120, 206, + 8, 44, 120, 230, 116, 44, 120, 220, 247, 44, 5, 222, 127, 44, 5, 221, + 166, 44, 5, 221, 145, 44, 5, 220, 232, 44, 5, 220, 187, 44, 5, 222, 22, + 44, 5, 222, 13, 44, 5, 222, 102, 44, 5, 221, 67, 44, 5, 221, 41, 44, 5, + 222, 42, 44, 5, 214, 67, 44, 5, 214, 16, 44, 5, 214, 12, 44, 5, 213, 237, + 44, 5, 213, 228, 44, 5, 214, 55, 44, 5, 214, 53, 44, 5, 214, 64, 44, 5, + 213, 249, 44, 5, 213, 244, 44, 5, 214, 57, 44, 5, 247, 159, 44, 5, 243, + 29, 44, 5, 243, 19, 44, 5, 238, 195, 44, 5, 238, 153, 44, 5, 247, 42, 44, + 5, 247, 34, 44, 5, 247, 148, 44, 5, 242, 99, 44, 5, 239, 18, 44, 5, 247, + 76, 44, 5, 212, 100, 44, 5, 212, 81, 44, 5, 212, 75, 44, 5, 212, 58, 44, + 5, 212, 50, 44, 5, 212, 90, 44, 5, 212, 89, 44, 5, 212, 97, 44, 5, 212, + 65, 44, 5, 212, 62, 44, 5, 212, 93, 44, 5, 197, 131, 44, 5, 197, 111, 44, + 5, 197, 110, 44, 5, 197, 99, 44, 5, 197, 96, 44, 5, 197, 127, 44, 5, 197, + 126, 44, 5, 197, 130, 44, 5, 197, 109, 44, 5, 197, 108, 44, 5, 197, 129, + 44, 5, 213, 78, 44, 5, 213, 64, 44, 5, 213, 63, 44, 5, 213, 47, 44, 5, + 213, 46, 44, 5, 213, 74, 44, 5, 213, 73, 44, 5, 213, 77, 44, 5, 213, 49, + 44, 5, 213, 48, 44, 5, 213, 76, 44, 5, 199, 245, 44, 5, 198, 193, 44, 5, + 198, 170, 44, 5, 197, 94, 44, 5, 197, 49, 44, 5, 199, 145, 44, 5, 199, + 121, 44, 5, 199, 217, 44, 5, 159, 44, 5, 198, 59, 44, 5, 199, 166, 44, 5, + 214, 250, 44, 5, 213, 219, 44, 5, 213, 186, 44, 5, 212, 178, 44, 5, 212, + 115, 44, 5, 214, 121, 44, 5, 214, 110, 44, 5, 214, 236, 44, 5, 213, 43, + 44, 5, 213, 26, 44, 5, 214, 205, 44, 5, 210, 220, 44, 5, 209, 185, 44, 5, + 209, 145, 44, 5, 208, 165, 44, 5, 208, 128, 44, 5, 210, 63, 44, 5, 210, + 49, 44, 5, 210, 198, 44, 5, 209, 73, 44, 5, 209, 37, 44, 5, 210, 80, 44, + 5, 217, 151, 44, 5, 216, 100, 44, 5, 216, 61, 44, 5, 215, 155, 44, 5, + 215, 93, 44, 5, 216, 232, 44, 5, 216, 211, 44, 5, 217, 112, 44, 5, 216, + 12, 44, 5, 215, 211, 44, 5, 217, 25, 44, 5, 192, 140, 44, 5, 192, 33, 44, + 5, 192, 23, 44, 5, 191, 225, 44, 5, 191, 188, 44, 5, 192, 80, 44, 5, 192, + 77, 44, 5, 192, 119, 44, 5, 192, 12, 44, 5, 191, 246, 44, 5, 192, 91, 44, + 5, 207, 178, 44, 5, 207, 1, 44, 5, 206, 195, 44, 5, 206, 68, 44, 5, 206, + 29, 44, 5, 207, 113, 44, 5, 207, 84, 44, 5, 207, 156, 44, 5, 206, 162, + 44, 5, 206, 134, 44, 5, 207, 125, 44, 5, 220, 125, 44, 5, 219, 146, 44, + 5, 219, 128, 44, 5, 218, 225, 44, 5, 218, 194, 44, 5, 219, 238, 44, 5, + 219, 228, 44, 5, 220, 96, 44, 5, 219, 43, 44, 5, 219, 8, 44, 5, 220, 0, + 44, 5, 195, 187, 44, 5, 195, 69, 44, 5, 195, 51, 44, 5, 193, 249, 44, 5, + 193, 241, 44, 5, 195, 153, 44, 5, 195, 148, 44, 5, 195, 183, 44, 5, 195, + 24, 44, 5, 195, 8, 44, 5, 195, 160, 44, 5, 219, 61, 44, 5, 219, 56, 44, + 5, 219, 55, 44, 5, 219, 52, 44, 5, 219, 51, 44, 5, 219, 58, 44, 5, 219, + 57, 44, 5, 219, 60, 44, 5, 219, 54, 44, 5, 219, 53, 44, 5, 219, 59, 44, + 5, 219, 72, 44, 5, 219, 65, 44, 5, 219, 64, 44, 5, 219, 48, 44, 5, 219, + 47, 44, 5, 219, 68, 44, 5, 219, 67, 44, 5, 219, 71, 44, 5, 219, 50, 44, + 5, 219, 49, 44, 5, 219, 69, 44, 5, 206, 108, 44, 5, 206, 97, 44, 5, 206, + 96, 44, 5, 206, 89, 44, 5, 206, 82, 44, 5, 206, 104, 44, 5, 206, 103, 44, + 5, 206, 107, 44, 5, 206, 95, 44, 5, 206, 94, 44, 5, 206, 106, 44, 5, 213, + 60, 44, 5, 213, 55, 44, 5, 213, 54, 44, 5, 213, 51, 44, 5, 213, 50, 44, + 5, 213, 57, 44, 5, 213, 56, 44, 5, 213, 59, 44, 5, 213, 53, 44, 5, 213, + 52, 44, 5, 213, 58, 44, 5, 223, 31, 44, 5, 222, 244, 44, 5, 222, 236, 44, + 5, 222, 182, 44, 5, 222, 162, 44, 5, 223, 10, 44, 5, 223, 8, 44, 5, 223, + 25, 44, 5, 222, 201, 44, 5, 222, 191, 44, 5, 223, 17, 44, 5, 203, 160, + 44, 5, 203, 81, 44, 5, 203, 76, 44, 5, 203, 5, 44, 5, 202, 243, 44, 5, + 203, 113, 44, 5, 203, 111, 44, 5, 203, 148, 44, 5, 203, 56, 44, 5, 203, + 48, 44, 5, 203, 122, 44, 5, 201, 174, 44, 5, 201, 142, 44, 5, 201, 138, + 44, 5, 201, 129, 44, 5, 201, 126, 44, 5, 201, 148, 44, 5, 201, 147, 44, + 5, 201, 173, 44, 5, 201, 134, 44, 5, 201, 133, 44, 5, 201, 150, 44, 5, + 205, 197, 44, 5, 202, 222, 44, 5, 202, 193, 44, 5, 201, 4, 44, 5, 200, + 160, 44, 5, 205, 68, 44, 5, 205, 50, 44, 5, 205, 181, 44, 5, 202, 46, 44, + 5, 202, 16, 44, 5, 205, 114, 44, 5, 230, 91, 44, 5, 229, 158, 44, 5, 229, + 130, 44, 5, 228, 159, 44, 5, 228, 128, 44, 5, 229, 245, 44, 5, 229, 215, + 44, 5, 230, 80, 44, 5, 229, 23, 44, 5, 228, 252, 44, 5, 230, 2, 44, 5, + 220, 246, 44, 5, 220, 245, 44, 5, 220, 240, 44, 5, 220, 239, 44, 5, 220, + 236, 44, 5, 220, 235, 44, 5, 220, 242, 44, 5, 220, 241, 44, 5, 220, 244, + 44, 5, 220, 238, 44, 5, 220, 237, 44, 5, 220, 243, 44, 5, 203, 14, 166, + 120, 3, 192, 105, 166, 120, 3, 207, 144, 166, 120, 3, 207, 50, 101, 1, + 196, 224, 95, 120, 3, 242, 91, 155, 95, 120, 3, 242, 91, 221, 215, 95, + 120, 3, 242, 91, 221, 67, 95, 120, 3, 242, 91, 221, 183, 95, 120, 3, 242, + 91, 213, 249, 95, 120, 3, 242, 91, 247, 160, 95, 120, 3, 242, 91, 247, 1, + 95, 120, 3, 242, 91, 242, 99, 95, 120, 3, 242, 91, 243, 68, 95, 120, 3, + 242, 91, 212, 65, 95, 120, 3, 242, 91, 238, 32, 95, 120, 3, 242, 91, 197, + 120, 95, 120, 3, 242, 91, 236, 174, 95, 120, 3, 242, 91, 197, 115, 95, + 120, 3, 242, 91, 180, 95, 120, 3, 242, 91, 190, 190, 95, 120, 3, 242, 91, + 199, 49, 95, 120, 3, 242, 91, 159, 95, 120, 3, 242, 91, 198, 241, 95, + 120, 3, 242, 91, 213, 43, 95, 120, 3, 242, 91, 249, 153, 95, 120, 3, 242, + 91, 209, 228, 95, 120, 3, 242, 91, 209, 73, 95, 120, 3, 242, 91, 209, + 199, 95, 120, 3, 242, 91, 216, 12, 95, 120, 3, 242, 91, 192, 12, 95, 120, + 3, 242, 91, 206, 162, 95, 120, 3, 242, 91, 219, 43, 95, 120, 3, 242, 91, + 195, 24, 95, 120, 3, 242, 91, 203, 165, 95, 120, 3, 242, 91, 201, 175, + 95, 120, 3, 242, 91, 188, 95, 120, 3, 242, 91, 140, 95, 120, 3, 242, 91, + 173, 95, 18, 3, 242, 91, 208, 96, 95, 223, 149, 18, 3, 242, 91, 208, 33, + 95, 223, 149, 18, 3, 242, 91, 206, 17, 95, 223, 149, 18, 3, 242, 91, 206, + 10, 95, 223, 149, 18, 3, 242, 91, 208, 75, 95, 18, 3, 211, 113, 95, 18, + 3, 252, 167, 229, 120, 1, 248, 181, 214, 68, 229, 120, 1, 248, 181, 214, + 16, 229, 120, 1, 248, 181, 213, 237, 229, 120, 1, 248, 181, 214, 55, 229, + 120, 1, 248, 181, 213, 249, 72, 1, 248, 181, 214, 68, 72, 1, 248, 181, + 214, 16, 72, 1, 248, 181, 213, 237, 72, 1, 248, 181, 214, 55, 72, 1, 248, + 181, 213, 249, 72, 1, 251, 228, 247, 42, 72, 1, 251, 228, 197, 94, 72, 1, + 251, 228, 159, 72, 1, 251, 228, 210, 236, 52, 1, 233, 200, 233, 199, 239, + 26, 163, 164, 52, 1, 233, 199, 233, 200, 239, 26, 163, 164, }; static const unsigned short phrasebook_offset1[] = { @@ -20584,39 +20721,39 @@ static const unsigned short phrasebook_offset1[] = { 148, 104, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 104, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 104, 182, 183, 104, 184, 185, - 186, 187, 104, 188, 189, 190, 191, 192, 193, 104, 104, 194, 195, 196, - 197, 104, 198, 104, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 186, 187, 104, 188, 189, 190, 191, 192, 193, 194, 104, 195, 196, 197, + 198, 104, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 221, 222, 223, 224, 225, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 223, 224, 225, 226, 227, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 226, 227, 228, 229, 230, - 231, 232, 233, 104, 104, 104, 104, 234, 235, 236, 237, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 228, 229, 230, 231, 232, + 233, 234, 235, 104, 104, 104, 104, 236, 237, 238, 239, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 104, + 104, 104, 104, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 248, 249, - 250, 251, 252, 253, 254, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 255, 256, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 250, 251, + 252, 253, 254, 255, 256, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 257, 258, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 104, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 104, 104, 104, 104, 104, 104, 104, 104, 280, 104, 281, 104, 282, - 104, 104, 283, 104, 104, 104, 104, 104, 104, 104, 104, 104, 284, 285, - 286, 287, 104, 104, 104, 104, 104, 288, 289, 290, 104, 291, 292, 104, - 104, 293, 294, 295, 296, 297, 104, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 104, 104, 104, + 104, 104, 104, 104, 104, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 104, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 104, 104, 104, 104, 104, 104, 104, 104, 282, 104, 283, 284, 285, + 104, 104, 286, 104, 104, 104, 287, 104, 104, 104, 104, 104, 288, 289, + 290, 291, 104, 104, 104, 104, 104, 292, 293, 294, 104, 295, 296, 104, + 104, 297, 298, 299, 300, 301, 104, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, @@ -20652,8 +20789,8 @@ static const unsigned short phrasebook_offset1[] = { 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 316, 317, 318, - 319, 320, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 320, 321, 322, + 323, 324, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, @@ -21056,7 +21193,7 @@ static const unsigned short phrasebook_offset1[] = { 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 321, 104, 322, 323, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 325, 104, 326, 327, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, @@ -21092,8 +21229,8 @@ static const unsigned short phrasebook_offset1[] = { 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 324, 325, 326, - 327, 328, 329, 330, 331, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 328, 329, 330, + 331, 332, 333, 334, 335, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, @@ -21446,3738 +21583,3780 @@ static const unsigned int phrasebook_offset2[] = { 17007, 17013, 0, 17019, 17024, 17030, 17036, 0, 0, 0, 0, 0, 0, 0, 17041, 17046, 0, 0, 0, 0, 0, 0, 17053, 17060, 0, 17065, 17071, 17077, 17083, 0, 0, 17090, 17095, 17099, 17103, 17107, 17111, 17115, 17119, 17123, 17127, - 0, 17131, 17136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17141, 17147, - 17151, 17155, 17159, 17165, 17168, 17172, 17175, 17179, 17182, 17186, - 17190, 0, 17194, 17197, 17201, 0, 17205, 17208, 17212, 17216, 17219, - 17223, 17227, 17231, 17235, 17239, 17243, 17247, 17251, 17255, 17259, - 17263, 17267, 17271, 17275, 17279, 17283, 17287, 17291, 17294, 17298, - 17301, 17305, 17309, 17313, 17316, 17319, 17322, 17326, 17329, 17333, - 17337, 17341, 17345, 17349, 17352, 17355, 17359, 17366, 17372, 17376, - 17381, 17385, 17390, 17394, 17399, 17404, 0, 17410, 17414, 17419, 0, - 17424, 17428, 17433, 17438, 17442, 17447, 0, 0, 0, 0, 17451, 17457, - 17463, 17469, 17475, 17481, 17487, 17493, 17499, 17505, 17511, 17517, - 17523, 17528, 17533, 17538, 0, 0, 17544, 17548, 17551, 17554, 17557, - 17560, 17563, 17566, 17569, 17572, 17575, 17579, 17584, 17588, 17594, - 17600, 17606, 17612, 17618, 17624, 17628, 17634, 17640, 17646, 17651, - 17657, 0, 17663, 17667, 17671, 0, 17675, 17679, 17683, 17687, 17691, - 17695, 17699, 17703, 17707, 17711, 17715, 17719, 17723, 17727, 17731, - 17735, 17739, 17743, 0, 0, 0, 17747, 17753, 17759, 17765, 17771, 17777, - 17783, 17789, 17795, 17801, 17807, 17813, 17821, 17827, 17833, 17839, - 17845, 17851, 17857, 17863, 17869, 17875, 17881, 17887, 0, 17893, 17899, - 17905, 17911, 17917, 17923, 17927, 17933, 17937, 0, 17941, 0, 0, 17947, - 17951, 17957, 17963, 17969, 17973, 17979, 0, 0, 0, 17983, 0, 0, 0, 0, - 17987, 17992, 17999, 18006, 18013, 18020, 0, 18027, 0, 18034, 18039, - 18044, 18051, 18058, 18067, 18078, 18087, 0, 0, 0, 0, 0, 0, 18092, 18098, - 18103, 18108, 18113, 18118, 18123, 18128, 18133, 18138, 0, 0, 18143, - 18150, 18157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18162, 18170, 18178, - 18186, 18194, 18202, 18210, 18218, 18226, 18234, 18242, 18250, 18258, - 18266, 18274, 18281, 18289, 18297, 18305, 18313, 18321, 18328, 18336, - 18344, 18352, 18360, 18368, 18376, 18384, 18392, 18400, 18408, 18416, - 18423, 18431, 18439, 18445, 18453, 18459, 18467, 18475, 18483, 18491, - 18499, 18507, 18514, 18522, 18528, 18535, 18543, 18551, 18559, 18566, - 18574, 18582, 18590, 18597, 18605, 0, 0, 0, 0, 18611, 18618, 18625, - 18633, 18640, 18650, 18660, 18666, 18672, 18678, 18686, 18694, 18702, - 18710, 18716, 18722, 18728, 18734, 18739, 18743, 18747, 18751, 18755, - 18759, 18763, 18767, 18771, 18775, 18781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 18787, 18792, 0, 18799, 0, 18806, 18813, 18818, 18823, 18830, 0, - 18837, 18844, 18849, 18856, 18863, 18870, 18877, 18884, 18891, 18896, - 18900, 18907, 18914, 18921, 18926, 18931, 18936, 18943, 18950, 18957, - 18964, 18971, 18976, 18981, 0, 18988, 0, 18995, 19000, 19007, 19014, - 19021, 19028, 19035, 19039, 19046, 19050, 19055, 19063, 19069, 19075, - 19080, 19086, 19092, 19098, 19103, 19109, 19116, 19124, 19131, 0, 0, - 19138, 19143, 19149, 19154, 19160, 0, 19166, 0, 19171, 19178, 19185, - 19192, 19199, 19204, 0, 0, 19208, 19213, 19217, 19221, 19225, 19229, - 19233, 19237, 19241, 19245, 0, 0, 19249, 19255, 19261, 19268, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 19275, 19279, 19290, 19305, 19320, 19330, 19341, 19354, - 19365, 19371, 19379, 19389, 19395, 19403, 19407, 19413, 19419, 19427, - 19437, 19445, 19458, 19464, 19472, 19480, 19492, 19499, 19507, 19515, - 19523, 19531, 19539, 19547, 19557, 19561, 19564, 19567, 19570, 19573, - 19576, 19579, 19582, 19585, 19588, 19592, 19596, 19600, 19604, 19608, - 19612, 19616, 19620, 19624, 19629, 19635, 19645, 19659, 19669, 19675, - 19681, 19689, 19697, 19705, 19713, 19719, 19725, 19728, 19732, 19736, - 19740, 19744, 19748, 19752, 0, 19756, 19760, 19764, 19768, 19772, 19776, - 19780, 19784, 19788, 19792, 19796, 19799, 19802, 19806, 19810, 19814, - 19817, 19821, 19825, 19829, 19833, 19837, 19841, 19845, 19849, 19852, - 19855, 19858, 19862, 19866, 19869, 19872, 19875, 19879, 19884, 19888, 0, - 0, 0, 0, 19892, 19897, 19901, 19906, 19910, 19915, 19920, 19926, 19931, - 19937, 19941, 19946, 19950, 19955, 19965, 19971, 19977, 19984, 19994, - 20000, 20004, 20008, 20014, 20020, 20028, 20034, 20042, 20050, 20058, - 20068, 20076, 20086, 20091, 20097, 20103, 20109, 20115, 20121, 20127, 0, - 20133, 20139, 20145, 20151, 20157, 20163, 20169, 20175, 20181, 20187, - 20193, 20198, 20203, 20209, 20215, 20221, 20226, 20232, 20238, 20244, - 20250, 20256, 20262, 20268, 20274, 20279, 20284, 20289, 20295, 20301, - 20306, 20311, 20316, 20322, 20330, 20337, 0, 20344, 20351, 20364, 20371, - 20378, 20386, 20394, 20400, 20406, 20412, 20422, 20427, 20433, 20443, - 20453, 0, 20463, 20473, 20481, 20493, 20505, 20511, 20525, 20540, 20545, - 20550, 20558, 20566, 20574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20582, - 20585, 20589, 20593, 20597, 20601, 20605, 20609, 20613, 20617, 20621, - 20625, 20629, 20633, 20637, 20641, 20645, 20649, 20653, 20657, 20661, - 20664, 20667, 20671, 20675, 20679, 20682, 20685, 20688, 20691, 20695, - 20698, 20701, 20705, 20708, 20713, 20716, 20720, 20723, 20727, 20730, - 20735, 20738, 20742, 20749, 20754, 20758, 20763, 20767, 20772, 20776, - 20781, 20788, 20794, 20800, 20804, 20808, 20812, 20816, 20820, 20826, - 20832, 20839, 20845, 20850, 20854, 20857, 20860, 20863, 20866, 20869, - 20872, 20875, 20878, 20881, 20887, 20891, 20895, 20899, 20903, 20907, - 20911, 20915, 20919, 20924, 20928, 20933, 20938, 20944, 20949, 20955, - 20961, 20967, 20973, 20979, 20987, 20995, 21003, 21011, 21020, 21029, - 21040, 21050, 21060, 21071, 21082, 21092, 21102, 21112, 21122, 21132, - 21142, 21152, 21162, 21170, 21177, 21183, 21190, 21195, 21201, 21207, - 21213, 21219, 21225, 21231, 21236, 21242, 21248, 21254, 21260, 21265, - 21274, 21281, 21287, 21295, 21303, 21309, 21315, 21321, 21327, 21335, - 21343, 21353, 21361, 21369, 21375, 21380, 21385, 21390, 21395, 21400, - 21405, 21410, 21415, 21420, 21426, 21432, 21438, 21445, 21450, 21456, - 21461, 21466, 21471, 21476, 21481, 21486, 21491, 21496, 21501, 21506, - 21511, 21516, 21521, 21526, 21531, 21536, 21541, 21546, 21551, 21556, - 21561, 21566, 21571, 21576, 21581, 21586, 21591, 21596, 21601, 21606, - 21611, 21616, 21621, 21626, 21631, 21636, 21641, 0, 21646, 0, 0, 0, 0, 0, - 21651, 0, 0, 21656, 21660, 21664, 21668, 21672, 21676, 21680, 21684, - 21688, 21692, 21696, 21700, 21704, 21708, 21712, 21716, 21720, 21724, - 21728, 21732, 21736, 21740, 21744, 21748, 21752, 21756, 21760, 21764, - 21768, 21772, 21776, 21780, 21784, 21788, 21792, 21796, 21800, 21804, - 21808, 21812, 21816, 21820, 21825, 21829, 21834, 21839, 21843, 21848, - 21853, 21857, 21861, 21865, 21869, 21873, 21877, 21881, 21885, 21889, - 21893, 21897, 21901, 21905, 21909, 21913, 21917, 21921, 21925, 21929, - 21933, 21937, 21941, 21945, 21949, 21953, 21957, 21961, 21965, 21969, - 21973, 21977, 21981, 21985, 21989, 21993, 21997, 22001, 22005, 22009, - 22013, 22017, 22021, 22025, 22029, 22033, 22037, 22041, 22045, 22049, - 22053, 22057, 22061, 22065, 22069, 22073, 22077, 22081, 22085, 22089, - 22093, 22097, 22101, 22105, 22109, 22113, 22117, 22121, 22125, 22129, - 22133, 22137, 22141, 22145, 22149, 22153, 22157, 22161, 22165, 22169, - 22173, 22177, 22181, 22185, 22189, 22193, 22197, 22201, 22205, 22209, - 22213, 22217, 22221, 22225, 22229, 22233, 22237, 22242, 22246, 22251, - 22255, 22260, 22265, 22269, 22274, 22279, 22283, 22288, 22293, 22298, - 22303, 22307, 22312, 22317, 22322, 22327, 22332, 22337, 22341, 22346, - 22351, 22356, 22361, 22366, 22371, 22376, 22381, 22386, 22391, 22396, - 22401, 22406, 22411, 22416, 22421, 22426, 22431, 22436, 22441, 22446, - 22451, 22456, 22461, 22466, 22471, 22476, 22481, 22486, 22491, 22496, - 22501, 22506, 22511, 22516, 22521, 22526, 22531, 22536, 22541, 22546, - 22551, 22556, 22561, 22566, 22571, 22576, 22581, 22586, 22591, 22595, - 22599, 22603, 22607, 22611, 22615, 22619, 22623, 22627, 22631, 22635, - 22639, 22643, 22647, 22651, 22655, 22659, 22663, 22667, 22671, 22675, - 22679, 22683, 22687, 22691, 22695, 22699, 22703, 22707, 22711, 22715, - 22719, 22723, 22727, 22731, 22735, 22739, 22743, 22747, 22751, 22755, - 22759, 22763, 22767, 22771, 22775, 22779, 22783, 22787, 22791, 22795, - 22799, 22803, 22807, 22811, 22815, 22819, 22823, 22827, 22831, 22835, - 22839, 22843, 22847, 22851, 22855, 22859, 22863, 22867, 22871, 22875, - 22879, 22883, 22887, 22891, 22895, 22899, 22903, 22907, 22911, 22915, - 22919, 22923, 22927, 22931, 22935, 22939, 22943, 22946, 22950, 22954, - 22958, 22962, 22966, 22970, 22974, 22977, 22981, 22985, 22989, 22993, - 22997, 23001, 23005, 23009, 23013, 23017, 23021, 23025, 23029, 23033, - 23037, 23040, 23044, 23048, 23052, 23056, 23060, 23064, 23068, 23072, - 23076, 23080, 23084, 23088, 23092, 23096, 23100, 23103, 23107, 23111, - 23115, 23119, 23123, 23127, 23131, 23134, 23138, 23142, 23146, 23150, - 23154, 23158, 23162, 23166, 23170, 23174, 23178, 23182, 23186, 23190, - 23194, 23198, 23202, 23206, 23210, 23214, 23218, 23222, 23226, 0, 23230, - 23234, 23238, 23242, 0, 0, 23246, 23250, 23254, 23258, 23262, 23266, - 23270, 0, 23274, 0, 23278, 23282, 23286, 23290, 0, 0, 23294, 23298, - 23302, 23306, 23310, 23314, 23318, 23322, 23326, 23330, 23334, 23338, - 23342, 23346, 23350, 23354, 23358, 23362, 23366, 23370, 23374, 23378, - 23382, 23385, 23389, 23393, 23397, 23401, 23405, 23409, 23413, 23417, - 23421, 23425, 23429, 23433, 23437, 23441, 23445, 23449, 23453, 0, 23457, - 23461, 23465, 23469, 0, 0, 23473, 23476, 23480, 23484, 23488, 23492, - 23496, 23500, 23504, 23508, 23512, 23516, 23520, 23524, 23528, 23532, - 23536, 23541, 23546, 23551, 23557, 23563, 23568, 23573, 23579, 23582, - 23586, 23590, 23594, 23598, 23602, 23606, 23610, 0, 23614, 23618, 23622, - 23626, 0, 0, 23630, 23634, 23638, 23642, 23646, 23650, 23654, 0, 23658, - 0, 23662, 23666, 23670, 23674, 0, 0, 23678, 23682, 23686, 23690, 23694, - 23698, 23702, 23706, 23710, 23715, 23720, 23725, 23731, 23737, 23742, 0, - 23747, 23751, 23755, 23759, 23763, 23767, 23771, 23775, 23779, 23783, - 23787, 23791, 23795, 23799, 23803, 23807, 23811, 23814, 23818, 23822, - 23826, 23830, 23834, 23838, 23842, 23846, 23850, 23854, 23858, 23862, - 23866, 23870, 23874, 23878, 23882, 23886, 23890, 23894, 23898, 23902, - 23906, 23910, 23914, 23918, 23922, 23926, 23930, 23934, 23938, 23942, - 23946, 23950, 23954, 23958, 23962, 23966, 23970, 0, 23974, 23978, 23982, - 23986, 0, 0, 23990, 23994, 23998, 24002, 24006, 24010, 24014, 24018, - 24022, 24026, 24030, 24034, 24038, 24042, 24046, 24050, 24054, 24058, - 24062, 24066, 24070, 24074, 24078, 24082, 24086, 24090, 24094, 24098, - 24102, 24106, 24110, 24114, 24118, 24122, 24126, 24130, 24134, 24138, - 24142, 24146, 24150, 24154, 24158, 24162, 24166, 24170, 24174, 24178, - 24182, 24186, 24190, 24194, 24198, 24202, 24206, 24210, 24214, 24217, - 24221, 24225, 24229, 24233, 24237, 24241, 24245, 24249, 24253, 0, 0, - 24257, 24266, 24272, 24277, 24281, 24284, 24289, 24292, 24295, 24298, - 24303, 24307, 24312, 24315, 24318, 24321, 24324, 24327, 24330, 24333, - 24336, 24339, 24343, 24347, 24351, 24355, 24359, 24363, 24367, 24371, - 24375, 24379, 0, 0, 0, 24384, 24390, 24394, 24398, 24402, 24408, 24412, - 24416, 24420, 24426, 24430, 24434, 24438, 24444, 24448, 24452, 24456, - 24462, 24468, 24474, 24482, 24488, 24494, 24500, 24506, 24512, 0, 0, 0, - 0, 0, 0, 24518, 24521, 24524, 24527, 24530, 24533, 24537, 24541, 24544, - 24548, 24552, 24556, 24560, 24564, 24567, 24571, 24575, 24579, 24583, - 24587, 24590, 24594, 24598, 24602, 24606, 24610, 24613, 24617, 24621, - 24625, 24629, 24632, 24636, 24640, 24644, 24648, 24652, 24656, 24660, - 24664, 24668, 24672, 24676, 24680, 24684, 24687, 24691, 24695, 24699, - 24703, 24707, 24711, 24715, 24719, 24723, 24727, 24731, 24735, 24739, - 24743, 24747, 24751, 24755, 24759, 24763, 24767, 24771, 24775, 24779, - 24783, 24787, 24791, 24795, 24799, 24803, 24807, 24811, 24815, 24819, - 24823, 24826, 24830, 24834, 24838, 24842, 24846, 0, 0, 24850, 24855, - 24860, 24865, 24870, 24875, 0, 0, 24880, 24884, 24887, 24891, 24894, - 24898, 24901, 24905, 24911, 24916, 24920, 24923, 24927, 24931, 24937, - 24941, 24947, 24951, 24957, 24961, 24967, 24971, 24977, 24983, 24987, - 24993, 24997, 25003, 25009, 25013, 25019, 25025, 25030, 25035, 25043, - 25051, 25058, 25063, 25069, 25078, 25084, 25092, 25097, 25103, 25107, - 25111, 25115, 25119, 25123, 25127, 25131, 25135, 25139, 25143, 25149, - 25154, 25159, 25162, 25166, 25170, 25176, 25180, 25186, 25190, 25196, - 25200, 25206, 25210, 25216, 25220, 25226, 25230, 25236, 25242, 25246, - 25252, 25257, 25261, 25265, 25269, 25273, 25276, 25280, 25286, 25291, - 25296, 25300, 25304, 25308, 25314, 25318, 25324, 25328, 25334, 25337, - 25342, 25346, 25352, 25356, 25362, 25366, 25372, 25378, 25382, 25386, - 25390, 25394, 25398, 25402, 25406, 25410, 25414, 25418, 25422, 25428, - 25431, 25435, 25439, 25445, 25449, 25455, 25459, 25465, 25469, 25475, - 25479, 25485, 25489, 25495, 25499, 25505, 25511, 25515, 25519, 25525, - 25531, 25537, 25543, 25547, 25551, 25555, 25559, 25563, 25567, 25573, - 25577, 25581, 25585, 25591, 25595, 25601, 25605, 25611, 25615, 25621, - 25625, 25631, 25635, 25641, 25645, 25651, 25657, 25661, 25667, 25671, - 25675, 25679, 25683, 25687, 25691, 25697, 25700, 25704, 25708, 25714, - 25718, 25724, 25728, 25734, 25738, 25744, 25748, 25754, 25758, 25764, - 25768, 25774, 25780, 25784, 25790, 25794, 25800, 25806, 25810, 25814, - 25818, 25822, 25826, 25830, 25836, 25839, 25843, 25847, 25853, 25857, - 25863, 25867, 25873, 25879, 25883, 25888, 25892, 25896, 25900, 25904, - 25908, 25912, 25916, 25922, 25925, 25929, 25933, 25939, 25943, 25949, - 25953, 25959, 25963, 25969, 25973, 25979, 25983, 25989, 25993, 25999, - 26002, 26007, 26012, 26016, 26020, 26024, 26028, 26032, 26036, 26042, - 26045, 26049, 26053, 26059, 26063, 26069, 26073, 26079, 26083, 26089, - 26093, 26099, 26103, 26109, 26113, 26119, 26125, 26129, 26135, 26139, - 26145, 26151, 26157, 26163, 26169, 26175, 26181, 26187, 26191, 26195, - 26199, 26203, 26207, 26211, 26215, 26219, 26225, 26229, 26235, 26239, - 26245, 26249, 26255, 26259, 26265, 26269, 26275, 26279, 26285, 26289, - 26293, 26297, 26301, 26305, 26309, 26313, 26319, 26322, 26326, 26330, - 26336, 26340, 26346, 26350, 26356, 26360, 26366, 26370, 26376, 26380, - 26386, 26390, 26396, 26402, 26406, 26412, 26418, 26424, 26428, 26434, - 26440, 26444, 26448, 26452, 26456, 26460, 26466, 26469, 26473, 26478, - 26482, 26488, 26491, 26496, 26501, 26505, 26509, 26513, 26517, 26521, - 26525, 26529, 26533, 26537, 26543, 26547, 26551, 26557, 26561, 26567, - 26571, 26577, 26581, 26585, 26589, 26593, 26597, 26603, 26607, 26611, - 26615, 26619, 26623, 26627, 26631, 26635, 26639, 26643, 26649, 26655, - 26661, 26667, 26673, 26678, 26684, 26690, 26696, 26700, 26704, 26708, - 26712, 26716, 26720, 26724, 26728, 26732, 26736, 26740, 26744, 26748, - 26754, 26760, 26766, 26771, 26775, 26779, 26783, 26787, 26791, 26795, - 26799, 26803, 26807, 26813, 26819, 26825, 26831, 26837, 26843, 26849, - 26855, 26861, 26865, 26869, 26873, 26877, 26881, 26885, 26889, 26895, - 26901, 26907, 26913, 26919, 26925, 26931, 26937, 26943, 26948, 26953, - 26958, 26963, 26969, 26975, 26981, 26987, 26993, 26999, 27005, 27010, - 27016, 27022, 27028, 27033, 27039, 27045, 27051, 27056, 27061, 27066, - 27071, 27076, 27081, 27086, 27091, 27096, 27101, 27106, 27111, 27115, - 27120, 27125, 27130, 27135, 27140, 27145, 27150, 27155, 27160, 27165, - 27170, 27175, 27180, 27185, 27190, 27195, 27200, 27205, 27210, 27215, - 27220, 27225, 27230, 27235, 27240, 27245, 27250, 27255, 27260, 27264, - 27269, 27274, 27279, 27284, 27289, 27294, 27299, 27304, 27309, 27314, - 27319, 27324, 27329, 27334, 27339, 27344, 27349, 27354, 27359, 27364, - 27369, 27374, 27379, 27384, 27389, 27393, 27398, 27403, 27408, 27413, - 27418, 27422, 27427, 27432, 27437, 27442, 27447, 27451, 27456, 27462, - 27467, 27472, 27477, 27482, 27488, 27493, 27498, 27503, 27508, 27513, - 27518, 27523, 27528, 27533, 27538, 27543, 27548, 27552, 27557, 27562, - 27567, 27572, 27577, 27582, 27587, 27592, 27597, 27602, 27607, 27612, - 27617, 27622, 27627, 27632, 27637, 27642, 27647, 27652, 27657, 27662, - 27667, 27672, 27677, 27682, 27687, 27692, 27697, 27702, 27707, 27713, - 27718, 27723, 27728, 27733, 27738, 27743, 27748, 27753, 27758, 27763, - 27768, 27772, 27777, 27782, 27787, 27792, 27797, 27802, 27807, 27812, - 27817, 27822, 27827, 27832, 27837, 27842, 27847, 27852, 27857, 27862, - 27867, 27872, 27877, 27882, 27887, 27892, 27897, 27902, 27908, 27912, - 27916, 27920, 27924, 27928, 27932, 27936, 27940, 27946, 27952, 27958, - 27964, 27970, 27976, 27982, 27989, 27995, 28000, 28005, 28010, 28015, - 28020, 28025, 28030, 28035, 28040, 28045, 28050, 28055, 28060, 28065, - 28070, 28075, 28080, 28085, 28090, 28095, 28100, 28105, 28110, 28115, - 28120, 28125, 28130, 28135, 0, 0, 0, 28142, 28153, 28158, 28166, 28171, - 28176, 28181, 28190, 28195, 28201, 28207, 28213, 28218, 28224, 28230, - 28234, 28239, 28244, 28254, 28259, 28264, 28271, 28276, 28281, 28290, - 28295, 28304, 28311, 28318, 28325, 28332, 28343, 28350, 28355, 28365, - 28369, 28376, 28381, 28388, 28394, 28401, 28410, 28417, 28424, 28433, - 28440, 28445, 28450, 28461, 28468, 28473, 28484, 28491, 28496, 28501, - 28509, 28518, 28525, 28532, 28542, 28547, 28552, 28557, 28566, 28574, - 28579, 28584, 28589, 28594, 28599, 28604, 28609, 28614, 28619, 28624, - 28629, 28635, 28641, 28647, 28652, 28657, 28662, 28667, 28672, 28677, - 28686, 28695, 28704, 28713, 0, 0, 0, 0, 0, 0, 0, 28722, 28726, 28730, - 28734, 28738, 28743, 28748, 28753, 28758, 28762, 28766, 28771, 28775, - 28779, 28783, 28787, 28792, 28796, 28800, 28805, 28810, 28815, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 28820, 28826, 28830, 28834, 28838, 28842, 28847, 28852, - 28857, 28862, 28866, 28870, 28875, 28879, 28883, 28887, 28891, 28896, - 28900, 28904, 28909, 28914, 28919, 28925, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 28930, 28934, 28938, 28942, 28946, 28951, 28956, 28961, 28966, 28970, - 28974, 28979, 28983, 28987, 28991, 28995, 29000, 29004, 29008, 29013, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29018, 29022, 29026, 29030, 29034, - 29039, 29044, 29049, 29054, 29058, 29062, 29067, 29071, 0, 29075, 29079, - 29084, 0, 29088, 29093, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29098, 29101, - 29105, 29109, 29113, 29117, 29121, 29125, 29129, 29133, 29137, 29141, - 29145, 29149, 29153, 29157, 29161, 29165, 29168, 29172, 29176, 29180, - 29184, 29188, 29192, 29196, 29200, 29204, 29208, 29212, 29216, 29220, - 29223, 29226, 29229, 29233, 29239, 29245, 29251, 29257, 29263, 29269, - 29275, 29281, 29287, 29293, 29299, 29305, 29311, 29317, 29326, 29335, - 29341, 29347, 29353, 29358, 29362, 29367, 29372, 29377, 29381, 29386, - 29391, 29396, 29400, 29405, 29409, 29414, 29419, 29424, 29429, 29433, - 29437, 29441, 29445, 29449, 29453, 29457, 29461, 29465, 29469, 29475, - 29479, 29483, 29487, 29491, 29495, 29503, 29509, 29513, 29519, 29523, - 29529, 29533, 0, 0, 29537, 29541, 29544, 29547, 29550, 29553, 29556, - 29559, 29562, 29565, 0, 0, 0, 0, 0, 0, 29568, 29576, 29584, 29592, 29600, - 29608, 29616, 29624, 29632, 29640, 0, 0, 0, 0, 0, 0, 29648, 29651, 29654, - 29657, 29662, 29665, 29670, 29677, 29685, 29690, 29697, 29700, 29707, - 29714, 29721, 29725, 29732, 29736, 29739, 29742, 29745, 29748, 29751, - 29754, 29757, 29760, 0, 0, 0, 0, 0, 0, 29763, 29766, 29769, 29772, 29775, - 29778, 29782, 29786, 29790, 29793, 29797, 29801, 29804, 29808, 29812, - 29815, 29818, 29821, 29825, 29829, 29833, 29837, 29841, 29844, 29847, - 29851, 29855, 29858, 29862, 29866, 29870, 29874, 29878, 29882, 29886, - 29890, 29897, 29902, 29907, 29912, 29917, 29923, 29929, 29935, 29941, - 29946, 29952, 29958, 29963, 29969, 29975, 29981, 29987, 29993, 29998, - 30004, 30009, 30015, 30021, 30027, 30033, 30039, 30044, 30049, 30055, - 30061, 30066, 30072, 30077, 30083, 30088, 30093, 30099, 30105, 30111, - 30117, 30123, 30129, 30135, 30141, 30147, 30153, 30159, 30165, 30170, - 30175, 30180, 30186, 30192, 0, 0, 0, 0, 0, 0, 0, 30200, 30209, 30218, - 30226, 30234, 30244, 30252, 30261, 30268, 30275, 30282, 30290, 30298, - 30306, 30314, 30322, 30330, 30338, 30346, 30353, 30361, 30369, 30377, - 30385, 30393, 30403, 30413, 30423, 30433, 30443, 30453, 30463, 30473, - 30483, 30493, 30503, 30513, 30523, 30533, 30541, 30549, 30559, 30567, 0, - 0, 0, 0, 0, 30577, 30581, 30585, 30589, 30593, 30597, 30601, 30605, - 30609, 30613, 30617, 30621, 30625, 30629, 30633, 30637, 30641, 30645, - 30649, 30653, 30657, 30661, 30665, 30669, 30675, 30679, 30685, 30689, - 30695, 30699, 30705, 30709, 30713, 30717, 30721, 30725, 30729, 30735, - 30741, 30747, 30753, 30759, 30765, 30771, 30777, 30783, 30789, 30795, - 30802, 30808, 30814, 30820, 30824, 30828, 30832, 30836, 30840, 30844, - 30848, 30854, 30860, 30866, 30871, 30878, 30883, 30888, 30894, 30899, - 30906, 30913, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30920, 30926, 30930, 30935, - 30940, 30945, 30950, 30955, 30960, 30965, 30970, 30975, 30980, 30985, - 30990, 30995, 30999, 31003, 31008, 31013, 31018, 31022, 31026, 31030, - 31034, 31039, 31044, 31049, 31053, 31057, 31062, 0, 31067, 31072, 31077, - 31082, 31088, 31094, 31100, 31106, 31111, 31116, 31122, 31128, 0, 0, 0, - 0, 31135, 31140, 31146, 31152, 31158, 31163, 31168, 31173, 31178, 31183, - 31188, 31193, 0, 0, 0, 0, 31198, 0, 0, 0, 31203, 31208, 31213, 31218, - 31222, 31226, 31230, 31234, 31238, 31242, 31246, 31250, 31254, 31259, - 31265, 31271, 31277, 31282, 31287, 31293, 31299, 31304, 31309, 31315, - 31320, 31326, 31332, 31337, 31343, 31349, 31355, 31360, 31365, 31370, - 31376, 31382, 31387, 31393, 31398, 31404, 31409, 31415, 0, 0, 31421, - 31427, 31433, 31439, 31445, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31451, - 31460, 31469, 31477, 31486, 31495, 31503, 31512, 31521, 31530, 31538, - 31546, 31555, 31563, 31571, 31580, 31589, 31597, 31606, 31615, 31623, - 31631, 31640, 31648, 31656, 31665, 31673, 31682, 31691, 31699, 31708, - 31717, 31725, 31733, 31742, 31751, 31759, 31768, 31777, 31786, 31795, - 31804, 31813, 31822, 0, 0, 0, 0, 31831, 31841, 31850, 31859, 31867, - 31876, 31884, 31893, 31901, 31910, 31919, 31928, 31937, 31946, 31955, - 31964, 31973, 31982, 31991, 32000, 32009, 32018, 32027, 32036, 32045, - 32053, 0, 0, 0, 0, 0, 0, 32061, 32069, 32076, 32083, 32090, 32097, 32104, - 32111, 32118, 32125, 32132, 0, 0, 0, 32140, 32148, 32156, 32160, 32166, - 32172, 32178, 32184, 32190, 32196, 32202, 32208, 32214, 32220, 32226, - 32232, 32238, 32244, 32250, 32254, 32260, 32266, 32272, 32278, 32284, - 32290, 32296, 32302, 32308, 32314, 32320, 32326, 32332, 32338, 32344, - 32348, 32353, 32358, 32363, 32367, 32372, 32376, 32381, 32386, 32391, - 32395, 32400, 32405, 32410, 32415, 32420, 32424, 32428, 32432, 32437, - 32441, 32445, 32449, 32454, 32459, 32464, 32469, 0, 0, 32475, 32479, - 32486, 32491, 32497, 32503, 32508, 32514, 32520, 32525, 32531, 32537, - 32543, 32548, 32554, 32559, 32564, 32570, 32575, 32581, 32586, 32592, - 32598, 32604, 32610, 32614, 32619, 32624, 32630, 32636, 32641, 32647, - 32653, 32657, 32662, 32667, 32671, 32676, 32680, 32685, 32690, 32696, - 32702, 32707, 32712, 32717, 32721, 32726, 32730, 32735, 32739, 32744, - 32749, 32754, 32759, 32765, 32772, 32779, 32789, 32798, 32805, 32811, - 32822, 32827, 32833, 0, 32838, 32843, 32848, 32856, 32862, 32870, 32875, - 32881, 32887, 32893, 32898, 32904, 32909, 32916, 32922, 32927, 32933, - 32939, 32945, 32952, 32959, 32966, 32971, 32976, 32983, 32990, 32997, - 33004, 33011, 0, 0, 33018, 33025, 33032, 33038, 33044, 33050, 33056, - 33062, 33068, 33074, 33080, 0, 0, 0, 0, 0, 0, 33086, 33092, 33097, 33102, - 33107, 33112, 33117, 33122, 33127, 33132, 0, 0, 0, 0, 0, 0, 33137, 33142, - 33147, 33152, 33157, 33162, 33167, 33176, 33183, 33188, 33193, 33198, - 33203, 33208, 0, 0, 33213, 33220, 33223, 33226, 33230, 33235, 33239, - 33245, 33250, 33256, 33263, 33271, 33275, 33280, 33284, 33289, 33296, - 33304, 33311, 33317, 33325, 33332, 33337, 33341, 33348, 33352, 33357, - 33362, 33369, 33377, 33384, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33392, 33398, 33404, 33408, 33412, 33416, - 33420, 33426, 33430, 33436, 33440, 33446, 33452, 33460, 33466, 33474, - 33478, 33482, 33486, 33492, 33495, 33501, 33505, 33511, 33515, 33519, - 33525, 33529, 33535, 33539, 33545, 33553, 33561, 33569, 33575, 33579, - 33585, 33589, 33595, 33598, 33601, 33607, 33611, 33617, 33620, 33623, - 33626, 33629, 33633, 33639, 33645, 33648, 33651, 33655, 33660, 33665, - 33672, 33677, 33684, 33691, 33700, 33707, 33716, 33721, 33728, 33735, - 33744, 33749, 33756, 33761, 33767, 33773, 33779, 33785, 33791, 33797, - 33803, 0, 0, 0, 33809, 33813, 33816, 33819, 33822, 33825, 33828, 33831, - 33834, 33837, 33840, 33843, 33846, 33849, 33854, 33859, 33864, 33867, - 33872, 33877, 33882, 33887, 33894, 33899, 33904, 33909, 33914, 33921, - 33927, 33933, 33939, 33945, 33951, 33960, 33969, 33975, 33981, 33990, - 33999, 34008, 34017, 34026, 34035, 34044, 34053, 34062, 34067, 0, 34072, - 34077, 34082, 34087, 34091, 34095, 34099, 34104, 34108, 34112, 34117, - 34121, 34126, 34131, 34136, 34141, 34146, 34151, 34156, 34161, 34166, - 34170, 34174, 34179, 34184, 34189, 34193, 34197, 34201, 34205, 34210, - 34214, 34219, 34223, 34229, 34235, 34241, 34247, 34253, 34259, 34265, - 34271, 34277, 34282, 34287, 34294, 34302, 34307, 34312, 34317, 34321, - 34325, 34329, 34333, 34337, 34341, 34345, 34349, 34353, 34357, 34362, - 34367, 34372, 34378, 34384, 34388, 34394, 34398, 34404, 34410, 34415, - 34422, 34426, 34432, 34436, 34442, 34447, 34454, 34461, 34466, 34473, - 34478, 34483, 34487, 34493, 34497, 34503, 34510, 34517, 34521, 34527, - 34533, 34537, 34543, 34548, 34552, 34558, 34563, 34568, 34573, 34578, - 34582, 34586, 34591, 34596, 34603, 34609, 34614, 34621, 34626, 34633, - 34638, 34647, 34653, 34659, 34663, 0, 0, 0, 0, 0, 0, 0, 0, 34667, 34676, - 34683, 34690, 34697, 34701, 34706, 34711, 34716, 34721, 34726, 34731, - 34736, 34741, 34746, 34751, 34756, 34761, 34765, 34769, 34774, 34779, - 34784, 34789, 34794, 34799, 34803, 34808, 34813, 34818, 34823, 34827, - 34831, 34835, 34839, 34844, 34849, 34853, 34858, 34863, 34867, 34873, - 34879, 34885, 34890, 34895, 34901, 34906, 34912, 34917, 34923, 34929, - 34934, 34940, 34946, 34951, 34957, 34963, 34969, 34974, 0, 0, 0, 34979, - 34985, 34995, 35001, 35009, 35015, 35020, 35024, 35028, 35032, 35036, - 35040, 35044, 35048, 35052, 0, 0, 0, 35056, 35061, 35066, 35071, 35078, - 35084, 35090, 35096, 35102, 35108, 35114, 35120, 35126, 35132, 35138, - 35145, 35152, 35159, 35166, 35173, 35180, 35187, 35194, 35201, 35208, - 35215, 35222, 35229, 35236, 35243, 35250, 35257, 35264, 35271, 35278, - 35285, 35292, 35299, 35306, 35313, 35320, 35327, 35334, 35341, 35349, - 35357, 35365, 35371, 35377, 35383, 35391, 35400, 35407, 35414, 35420, - 35427, 35434, 35441, 35449, 35456, 0, 0, 0, 0, 0, 0, 0, 35463, 35470, - 35477, 35484, 35491, 35498, 35505, 35512, 35519, 35526, 35533, 35540, - 35547, 35554, 35561, 35568, 35575, 35582, 35589, 35596, 35603, 35610, - 35617, 35624, 35631, 35638, 35645, 35652, 35659, 35666, 35673, 35680, - 35687, 35694, 35701, 35708, 35715, 35722, 35729, 35736, 35743, 35750, - 35758, 0, 0, 35765, 35772, 35780, 35788, 35796, 35804, 35812, 35820, - 35830, 35840, 35850, 0, 0, 0, 0, 0, 0, 0, 0, 35860, 35865, 35870, 35875, - 35880, 35889, 35900, 35909, 35920, 35926, 35939, 35945, 35952, 35959, - 35964, 35970, 35976, 35987, 35996, 36003, 36010, 36019, 36026, 36035, - 36045, 36055, 36062, 36069, 36076, 36086, 36091, 36099, 36105, 36113, - 36122, 36127, 36134, 36140, 36145, 36150, 36155, 36161, 36168, 0, 0, 0, - 0, 0, 36176, 36181, 36187, 36193, 36201, 36207, 36213, 36219, 36224, - 36231, 36236, 36242, 36248, 36256, 36262, 36270, 36275, 36282, 36288, - 36296, 36304, 36310, 36316, 36323, 36330, 36336, 36343, 36349, 36355, - 36360, 36366, 36374, 36382, 36388, 36394, 36400, 36406, 36414, 36418, - 36424, 36430, 36436, 36442, 36448, 36454, 36458, 36463, 36468, 36475, - 36480, 36484, 36490, 36495, 36500, 36504, 36509, 36514, 36518, 36523, - 36528, 36535, 36539, 36544, 36549, 36553, 36558, 36562, 36567, 36571, - 36576, 36581, 36587, 36592, 36597, 36601, 36606, 36612, 36619, 36624, - 36629, 36634, 36639, 36644, 36648, 36654, 36661, 36668, 36673, 36678, - 36682, 36688, 36694, 36699, 36704, 36709, 36715, 36720, 36726, 36731, - 36737, 36743, 36749, 36756, 36763, 36770, 36777, 36784, 36791, 36796, - 36804, 36813, 36822, 36831, 36840, 36849, 36858, 36870, 36879, 36888, - 36897, 36903, 36908, 36915, 36923, 36931, 36938, 36945, 36952, 36959, - 36967, 36976, 36985, 36994, 37003, 37012, 37021, 37030, 37039, 37048, - 37057, 37066, 37075, 37084, 37093, 37101, 37110, 37121, 37130, 37141, - 37154, 37163, 37172, 37182, 37191, 37199, 37208, 37214, 37219, 37227, - 37232, 37240, 37245, 37254, 37260, 37266, 37273, 37278, 37283, 37291, - 37299, 37308, 37317, 37322, 37329, 37339, 37347, 37356, 37362, 37368, - 37373, 37380, 37385, 37394, 37399, 37404, 37409, 37416, 37422, 37427, - 37436, 37444, 37449, 37454, 37461, 37468, 37472, 37476, 37479, 37482, - 37485, 37488, 37491, 37494, 37501, 37504, 37507, 37512, 37516, 37520, - 37524, 37528, 37532, 37542, 37548, 37554, 37560, 37568, 37576, 37582, - 37588, 37595, 37601, 37606, 37612, 37619, 37625, 37632, 37638, 37646, - 37652, 37659, 37665, 37671, 37677, 37683, 37689, 37695, 37706, 37716, - 37722, 37728, 37738, 37744, 37752, 37760, 37768, 37773, 37778, 37784, - 37789, 37797, 37803, 37807, 37814, 37821, 37826, 37835, 37843, 37851, - 37858, 37865, 37872, 37879, 37887, 37895, 37906, 37917, 37925, 37933, - 37941, 37949, 37958, 37967, 37975, 37983, 37992, 38001, 38012, 38023, - 38034, 38045, 38054, 38063, 38072, 38081, 38092, 38103, 38111, 38119, - 38127, 38135, 38143, 38151, 38159, 38167, 38175, 38183, 38191, 38199, - 38208, 38217, 38226, 38235, 38246, 38257, 38265, 38273, 38281, 38289, - 38298, 38307, 38315, 38323, 38335, 38347, 38356, 38365, 38374, 38383, - 38391, 38399, 38407, 38415, 38423, 38431, 38439, 38447, 38455, 38463, - 38472, 38481, 38490, 38499, 38509, 38519, 38529, 38539, 38549, 38559, - 38569, 38579, 38587, 38595, 38603, 38611, 38619, 38627, 38635, 38643, - 38655, 38667, 38676, 38685, 38693, 38701, 38709, 38717, 38728, 38739, - 38750, 38761, 38773, 38785, 38793, 38801, 38809, 38817, 38826, 38835, - 38844, 38853, 38861, 38869, 38877, 38885, 38893, 38901, 38911, 38921, - 38931, 38941, 38949, 38957, 38965, 38973, 38981, 38989, 38997, 39005, - 39013, 39021, 39029, 39037, 39045, 39053, 39061, 39069, 39077, 39085, - 39093, 39101, 39109, 39117, 39125, 39133, 39142, 39151, 39160, 39168, - 39177, 39186, 39195, 39204, 39214, 39223, 39230, 39235, 39242, 39249, - 39257, 39265, 39275, 39285, 39295, 39305, 39316, 39327, 39337, 39347, - 39357, 39367, 39377, 39387, 39397, 39407, 39418, 39429, 39439, 39449, - 39459, 39469, 39477, 39485, 39494, 39503, 39511, 39519, 39530, 39541, - 39552, 39563, 39575, 39587, 39598, 39609, 39620, 39631, 39640, 39649, - 39657, 39665, 39672, 39679, 39687, 39695, 39705, 39715, 39725, 39735, - 39746, 39757, 39767, 39777, 39787, 39797, 39807, 39817, 39827, 39837, - 39848, 39859, 39869, 39879, 39889, 39899, 39906, 39913, 39921, 39929, - 39939, 39949, 39959, 39969, 39980, 39991, 40001, 40011, 40021, 40031, - 40039, 40047, 40055, 40063, 40072, 40081, 40089, 40097, 40104, 40111, - 40118, 40125, 40133, 40141, 40149, 40157, 40168, 40179, 40190, 40201, - 40212, 40223, 40231, 40239, 40250, 40261, 40272, 40283, 40294, 40305, - 40313, 40321, 40332, 40343, 40354, 0, 0, 40365, 40373, 40381, 40392, - 40403, 40414, 0, 0, 40425, 40433, 40441, 40452, 40463, 40474, 40485, - 40496, 40507, 40515, 40523, 40534, 40545, 40556, 40567, 40578, 40589, - 40597, 40605, 40616, 40627, 40638, 40649, 40660, 40671, 40679, 40687, - 40698, 40709, 40720, 40731, 40742, 40753, 40761, 40769, 40780, 40791, - 40802, 0, 0, 40813, 40821, 40829, 40840, 40851, 40862, 0, 0, 40873, - 40881, 40889, 40900, 40911, 40922, 40933, 40944, 0, 40955, 0, 40963, 0, - 40974, 0, 40985, 40996, 41004, 41012, 41023, 41034, 41045, 41056, 41067, - 41078, 41086, 41094, 41105, 41116, 41127, 41138, 41149, 41160, 41168, - 41176, 41184, 41192, 41200, 41208, 41216, 41224, 41232, 41240, 41248, - 41256, 41264, 0, 0, 41272, 41283, 41294, 41308, 41322, 41336, 41350, - 41364, 41378, 41389, 41400, 41414, 41428, 41442, 41456, 41470, 41484, - 41495, 41506, 41520, 41534, 41548, 41562, 41576, 41590, 41601, 41612, - 41626, 41640, 41654, 41668, 41682, 41696, 41707, 41718, 41732, 41746, - 41760, 41774, 41788, 41802, 41813, 41824, 41838, 41852, 41866, 41880, - 41894, 41908, 41916, 41924, 41935, 41943, 0, 41954, 41962, 41973, 41981, - 41989, 41997, 42005, 42013, 42016, 42019, 42022, 42025, 42031, 42042, - 42050, 0, 42061, 42069, 42080, 42088, 42096, 42104, 42112, 42120, 42126, - 42132, 42138, 42146, 42154, 42165, 0, 0, 42176, 42184, 42195, 42203, - 42211, 42219, 0, 42227, 42233, 42239, 42245, 42253, 42261, 42272, 42283, - 42291, 42299, 42307, 42318, 42326, 42334, 42342, 42350, 42358, 42364, - 42370, 0, 0, 42373, 42384, 42392, 0, 42403, 42411, 42422, 42430, 42438, - 42446, 42454, 42462, 42465, 0, 42468, 42472, 42476, 42480, 42484, 42488, - 42492, 42496, 42500, 42504, 42508, 42512, 42518, 42524, 42530, 42533, - 42536, 42538, 42542, 42546, 42550, 42554, 42557, 42561, 42565, 42571, - 42577, 42584, 42591, 42596, 42601, 42607, 42613, 42615, 42618, 42620, - 42624, 42628, 42632, 42636, 42640, 42644, 42648, 42652, 42656, 42662, - 42666, 42670, 42676, 42681, 42688, 42690, 42693, 42697, 42701, 42706, - 42712, 42714, 42723, 42732, 42735, 42739, 42741, 42743, 42745, 42749, - 42755, 42757, 42761, 42765, 42772, 42779, 42783, 42788, 42793, 42798, - 42803, 42807, 42811, 42814, 42818, 42822, 42829, 42834, 42838, 42842, - 42847, 42851, 42855, 42860, 42865, 42869, 42873, 42877, 42879, 42884, - 42889, 42893, 42897, 42901, 42905, 0, 42909, 42913, 42917, 42923, 42929, - 42935, 42941, 42948, 42955, 42960, 42965, 42969, 0, 0, 42975, 42978, - 42981, 42984, 42987, 42990, 42993, 42997, 43001, 43006, 43011, 43016, - 43023, 43027, 43030, 43033, 43036, 43039, 43042, 43045, 43048, 43051, - 43054, 43058, 43062, 43067, 43072, 0, 43077, 43083, 43089, 43095, 43102, - 43109, 43116, 43123, 43129, 43136, 43143, 43150, 43157, 0, 0, 0, 43164, - 43167, 43170, 43173, 43178, 43181, 43184, 43187, 43190, 43193, 43196, - 43201, 43204, 43207, 43210, 43213, 43216, 43221, 43224, 43227, 43230, - 43233, 43236, 43241, 43244, 43247, 43252, 43257, 43261, 43264, 43267, - 43270, 43273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43276, 43281, - 43286, 43293, 43301, 43306, 43311, 43315, 43319, 43324, 43331, 43338, - 43342, 43347, 43352, 43357, 43362, 43369, 43374, 43379, 43384, 43393, - 43400, 43407, 43411, 43416, 43422, 43427, 43434, 43442, 43450, 43454, - 43458, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43462, 43466, 43473, - 43478, 43482, 43487, 43491, 43495, 43499, 43501, 43505, 43509, 43513, - 43518, 43523, 43527, 43535, 43538, 43542, 43545, 43548, 43554, 43559, - 43562, 43568, 43572, 43577, 43582, 43585, 43589, 43593, 43597, 43599, - 43602, 43605, 43609, 43611, 43616, 43619, 43622, 43627, 43632, 43638, - 43641, 43644, 43648, 43653, 43656, 43659, 43662, 43666, 43670, 43674, - 43677, 43679, 43682, 43685, 43688, 43692, 43697, 43700, 43705, 43710, - 43715, 43720, 43726, 43731, 43735, 43740, 43745, 43751, 43757, 43762, - 43767, 43773, 43777, 43780, 43783, 43785, 43789, 43795, 43802, 43809, - 43816, 43823, 43830, 43837, 43844, 43851, 43859, 43866, 43874, 43881, - 43888, 43896, 43904, 43909, 43914, 43919, 43924, 43929, 43934, 43939, - 43944, 43949, 43954, 43960, 43966, 43972, 43978, 43985, 43993, 43999, - 44005, 44011, 44017, 44023, 44029, 44035, 44041, 44047, 44053, 44060, - 44067, 44074, 44081, 44089, 44098, 44105, 44116, 44123, 44130, 44139, - 44146, 44155, 44164, 44171, 44179, 44187, 44190, 0, 0, 0, 0, 44193, - 44195, 44198, 44200, 44203, 44206, 44209, 44213, 44217, 44222, 44227, - 44231, 44235, 44239, 44243, 44248, 44254, 44259, 44265, 44270, 44275, - 44280, 44286, 44291, 44297, 44303, 44307, 44311, 44316, 44321, 44326, - 44331, 44336, 44344, 44352, 44360, 44368, 44375, 44383, 44390, 44397, - 44404, 44414, 44421, 44428, 44435, 44442, 44450, 44458, 44465, 44472, - 44480, 44488, 44493, 44501, 44506, 44511, 44517, 44522, 44528, 44535, - 44542, 44547, 44553, 44558, 44561, 44565, 44568, 44572, 44576, 44580, - 44585, 44590, 44596, 44602, 44606, 44610, 44614, 44618, 44624, 44630, - 44634, 44639, 44643, 44648, 44652, 44656, 44659, 44663, 44666, 44670, - 44677, 44685, 44697, 44708, 44713, 44722, 44729, 44736, 44744, 44748, - 44754, 44762, 44766, 44771, 44776, 44782, 44788, 44794, 44801, 44805, - 44809, 44814, 44817, 44819, 44823, 44827, 44835, 44839, 44841, 44843, - 44847, 44855, 44860, 44866, 44876, 44883, 44888, 44892, 44896, 44900, - 44903, 44906, 44909, 44913, 44917, 44921, 44925, 44929, 44932, 44936, - 44940, 44943, 44945, 44948, 44950, 44954, 44958, 44960, 44966, 44969, - 44974, 44978, 44982, 44984, 44986, 44988, 44991, 44995, 44999, 45003, - 45007, 45011, 45017, 45023, 45025, 45027, 45029, 45031, 45034, 45036, - 45040, 45042, 45046, 45050, 45056, 45060, 45064, 45068, 45072, 45077, - 45084, 45089, 45100, 45111, 45116, 45123, 45132, 45136, 45141, 45144, - 45149, 45153, 45159, 45164, 45177, 45187, 45191, 45195, 45202, 45207, - 45210, 45212, 45215, 45219, 45224, 45231, 45235, 45240, 45245, 45248, - 45253, 45258, 45265, 45272, 45278, 45284, 45293, 45302, 45306, 45310, - 45312, 45317, 45321, 45325, 45334, 45343, 45350, 45357, 45366, 45375, - 45381, 45387, 45395, 45403, 45405, 45407, 45414, 45421, 45428, 45435, - 45441, 45447, 45451, 45455, 45462, 45469, 45477, 45485, 45496, 45507, - 45516, 45525, 45527, 45531, 45535, 45540, 45545, 45554, 45563, 45566, - 45569, 45572, 45575, 45578, 45583, 45587, 45592, 45597, 45600, 45603, - 45606, 45609, 45612, 45616, 45619, 45622, 45625, 45628, 45630, 45632, - 45634, 45636, 45644, 45652, 45658, 45662, 45668, 45678, 45684, 45690, - 45696, 45704, 45714, 45727, 45731, 45735, 45737, 45743, 45745, 45747, - 45749, 45751, 45757, 45760, 45766, 45772, 45776, 45780, 45784, 45787, - 45791, 45795, 45797, 45806, 45815, 45820, 45825, 45831, 45837, 45843, - 45846, 45849, 45852, 45855, 45857, 45863, 45868, 45873, 45879, 45885, - 45894, 45903, 45910, 45917, 45924, 45931, 45941, 45951, 45962, 45973, - 45984, 45995, 46004, 46013, 46022, 46031, 46039, 46051, 46063, 46079, - 46082, 46088, 46094, 46100, 46108, 46123, 46139, 46145, 46151, 46158, - 46164, 46173, 46180, 46194, 46209, 46214, 46220, 46228, 46231, 46234, - 46236, 46239, 46242, 46244, 46246, 46250, 46253, 46256, 46259, 46262, - 46267, 46272, 46277, 46282, 46287, 46290, 46292, 46294, 46296, 46300, - 46304, 46308, 46314, 46318, 46320, 46322, 46327, 46332, 46337, 46342, - 46347, 46352, 46354, 46356, 46366, 46370, 46376, 46385, 46387, 46393, - 46399, 46406, 46410, 46412, 46416, 46418, 46422, 46426, 46430, 46432, - 46434, 46436, 46443, 46452, 46461, 46470, 46479, 46488, 46497, 46506, - 46515, 46523, 46531, 46540, 46549, 46558, 46567, 46575, 46583, 46592, - 46601, 46610, 46620, 46629, 46639, 46648, 46658, 46667, 46677, 46687, - 46696, 46706, 46715, 46725, 46734, 46744, 46753, 46762, 46771, 46780, - 46789, 46799, 46808, 46817, 46826, 46836, 46845, 46854, 46863, 46872, - 46882, 46892, 46901, 46910, 46918, 46927, 46934, 46943, 46952, 46963, - 46972, 46982, 46992, 46999, 47006, 47013, 47022, 47031, 47040, 47049, - 47056, 47061, 47070, 47076, 47079, 47086, 47089, 47094, 47099, 47102, - 47105, 47113, 47116, 47121, 47124, 47132, 47137, 47145, 47148, 47151, - 47154, 47159, 47164, 47167, 47170, 47178, 47181, 47188, 47195, 47199, - 47203, 47208, 47213, 47218, 47223, 47228, 47233, 47238, 47243, 47250, - 47256, 47263, 47270, 47276, 47283, 47290, 47298, 47305, 47311, 47318, - 47326, 47333, 47337, 47343, 47355, 47367, 47371, 47375, 47380, 47385, - 47396, 47400, 47405, 47410, 47416, 47422, 47428, 47434, 47443, 47452, - 47460, 47471, 47482, 47490, 47501, 47512, 47520, 47531, 47542, 47550, - 47558, 47568, 47578, 47581, 47584, 47587, 47592, 47596, 47602, 47609, - 47616, 47624, 47631, 47635, 47639, 47643, 47647, 47649, 47653, 47657, - 47663, 47669, 47677, 47685, 47688, 47695, 47697, 47699, 47703, 47707, - 47712, 47718, 47724, 47730, 47736, 47745, 47754, 47763, 47767, 47769, - 47773, 47780, 47787, 47794, 47801, 47808, 47811, 47816, 47822, 47825, - 47830, 47835, 47840, 47845, 47849, 47856, 47863, 47870, 47877, 47881, - 47885, 47889, 47893, 47899, 47905, 47910, 47916, 47922, 47928, 47934, - 47942, 47949, 47956, 47963, 47970, 47976, 47982, 47991, 47995, 48002, - 48006, 48010, 48016, 48022, 48028, 48034, 48038, 48042, 48045, 48049, - 48053, 48060, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 48067, 48070, 48074, 48078, 48084, 48090, 48096, 48104, - 48111, 48115, 48123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 48128, 48131, 48134, 48137, 48140, 48143, 48146, 48149, - 48152, 48155, 48159, 48163, 48167, 48171, 48175, 48179, 48183, 48187, - 48191, 48195, 48199, 48202, 48205, 48208, 48211, 48214, 48217, 48220, - 48223, 48226, 48230, 48234, 48238, 48242, 48246, 48250, 48254, 48258, - 48262, 48266, 48270, 48276, 48282, 48288, 48295, 48302, 48309, 48316, - 48323, 48330, 48337, 48344, 48351, 48358, 48365, 48372, 48379, 48386, - 48393, 48400, 48407, 48412, 48418, 48424, 48430, 48435, 48441, 48447, - 48453, 48458, 48464, 48470, 48475, 48481, 48487, 48492, 48498, 48504, - 48509, 48515, 48521, 48526, 48532, 48538, 48544, 48550, 48556, 48561, - 48567, 48573, 48579, 48584, 48590, 48596, 48602, 48607, 48613, 48619, - 48624, 48630, 48636, 48641, 48647, 48653, 48658, 48664, 48670, 48675, - 48681, 48687, 48693, 48699, 48705, 48710, 48716, 48722, 48728, 48733, - 48739, 48745, 48751, 48756, 48762, 48768, 48773, 48779, 48785, 48790, - 48796, 48802, 48807, 48813, 48819, 48824, 48830, 48836, 48842, 48848, - 48854, 48858, 48864, 48870, 48876, 48882, 48888, 48894, 48900, 48906, - 48912, 48918, 48922, 48926, 48930, 48934, 48938, 48942, 48946, 48950, - 48954, 48959, 48965, 48970, 48975, 48980, 48985, 48994, 49003, 49012, - 49021, 49030, 49039, 49048, 49057, 49063, 49071, 49079, 49085, 49092, - 49100, 49108, 49115, 49121, 49129, 49137, 49143, 49150, 49158, 49166, - 49173, 49179, 49187, 49196, 49205, 49213, 49222, 49231, 49237, 49244, - 49252, 49261, 49270, 49278, 49287, 49296, 49303, 49310, 49319, 49328, - 49337, 49346, 49355, 49364, 49371, 49378, 49387, 49396, 49405, 49414, - 49423, 49432, 49439, 49446, 49455, 49464, 49473, 49483, 49493, 49502, - 49512, 49522, 49532, 49542, 49552, 49562, 49571, 49580, 49587, 49595, - 49603, 49611, 49619, 49624, 49629, 49638, 49646, 49652, 49661, 49669, - 49676, 49685, 49693, 49699, 49708, 49716, 49723, 49732, 49740, 49746, - 49755, 49763, 49770, 49780, 49789, 49796, 49806, 49815, 49822, 49832, - 49841, 49848, 49856, 49865, 49874, 49882, 49893, 49903, 49910, 49915, - 49920, 49924, 49929, 49934, 49939, 49943, 49948, 49955, 49963, 49970, - 49978, 49982, 49988, 49994, 50000, 50004, 50011, 50017, 50024, 50028, - 50035, 50041, 50048, 50052, 50058, 50064, 50070, 50074, 50077, 50081, - 50085, 50091, 50097, 50102, 50106, 50111, 50121, 50128, 50139, 50149, - 50153, 50161, 50171, 50174, 50177, 50184, 50192, 50198, 50203, 50211, - 50220, 50229, 50237, 50241, 50245, 50248, 50251, 50255, 50259, 50262, - 50265, 50270, 50275, 50281, 50287, 50292, 50297, 50303, 50309, 50314, - 50319, 50324, 50329, 50335, 50341, 50346, 50351, 50357, 50363, 50368, - 50373, 50376, 50379, 50388, 50390, 50392, 50395, 50399, 50405, 50407, - 50410, 50417, 50424, 50431, 50438, 50447, 50460, 50465, 50470, 50474, - 50479, 50486, 50493, 50501, 50509, 50517, 50525, 50529, 50533, 50538, - 50543, 50548, 50553, 50556, 50562, 50568, 50577, 50586, 50594, 50602, - 50611, 50620, 50624, 50631, 50638, 50645, 50652, 50660, 50668, 50676, - 50684, 50688, 50692, 50696, 50701, 50706, 50712, 50718, 50722, 50728, - 50730, 50732, 50734, 50736, 50739, 50742, 50744, 50746, 50748, 50752, - 50756, 50758, 50760, 50763, 50766, 50770, 50776, 50782, 50784, 50791, - 50795, 50800, 50805, 50807, 50817, 50823, 50829, 50835, 50841, 50847, - 50853, 50858, 50861, 50864, 50867, 50869, 50871, 50875, 50879, 50884, - 50889, 50894, 50897, 50901, 50906, 50909, 50913, 50918, 50923, 50928, - 50933, 50938, 50943, 50948, 50953, 50958, 50963, 50968, 50973, 50979, - 50985, 50991, 50993, 50996, 50998, 51001, 51003, 51005, 51007, 51009, - 51011, 51013, 51015, 51017, 51019, 51021, 51023, 51025, 51027, 51029, - 51031, 51033, 51035, 51040, 51045, 51050, 51055, 51060, 51065, 51070, - 51075, 51080, 51085, 51090, 51095, 51100, 51105, 51110, 51115, 51120, - 51125, 51130, 51135, 51139, 51143, 51147, 51153, 51159, 51164, 51169, - 51174, 51180, 51186, 51191, 51199, 51207, 51215, 51223, 51231, 51239, - 51247, 51255, 51261, 51266, 51271, 51276, 51279, 51283, 51287, 51291, - 51295, 51299, 51303, 51309, 51316, 51323, 51331, 51336, 51341, 51348, - 51355, 51362, 51369, 51372, 51375, 51380, 51382, 51386, 51391, 51393, - 51395, 51397, 51399, 51404, 51407, 51409, 51414, 51420, 51427, 51430, - 51434, 51439, 51444, 51452, 51458, 51464, 51476, 51483, 51491, 51496, - 51501, 51507, 51510, 51513, 51518, 51520, 51524, 51526, 51528, 51530, - 51532, 51534, 51536, 51541, 51543, 51545, 51547, 51549, 51553, 51555, - 51558, 51563, 51568, 51573, 51578, 51584, 51590, 51592, 51595, 51602, - 51608, 51614, 51621, 51625, 51629, 51631, 51633, 51637, 51643, 51648, - 51650, 51654, 51663, 51671, 51679, 51685, 51691, 51696, 51702, 51707, - 51710, 51724, 51727, 51732, 51737, 51743, 51753, 51755, 51761, 51767, - 51771, 51778, 51782, 51784, 51786, 51790, 51796, 51801, 51807, 51809, - 51815, 51817, 51823, 51825, 51827, 51832, 51834, 51838, 51843, 51845, - 51850, 51855, 51859, 51866, 51876, 51881, 51886, 51889, 51894, 51897, - 51902, 51907, 51911, 51913, 51915, 51919, 51923, 51927, 51931, 51935, - 51937, 51941, 51944, 51947, 51950, 51954, 51958, 51963, 51967, 51972, - 51977, 51981, 51987, 51994, 51997, 52003, 52008, 52012, 52017, 52023, - 52029, 52036, 52042, 52049, 52056, 52058, 52065, 52069, 52076, 52082, - 52087, 52093, 52097, 52102, 52105, 52111, 52117, 52124, 52132, 52139, - 52148, 52158, 52165, 52171, 52175, 52183, 52188, 52197, 52200, 52203, - 52212, 52223, 52230, 52232, 52238, 52243, 52245, 52248, 52252, 52260, - 52269, 52272, 52277, 52283, 52290, 52297, 52304, 52311, 52317, 52323, - 52329, 52337, 52342, 52345, 52349, 52352, 52363, 52373, 52383, 52392, - 52403, 52413, 52422, 52428, 52436, 52440, 52448, 52452, 52460, 52467, - 52474, 52483, 52492, 52502, 52512, 52522, 52532, 52541, 52550, 52560, - 52570, 52579, 52588, 52595, 52602, 52609, 52616, 52623, 52630, 52637, - 52644, 52651, 52659, 52665, 52671, 52677, 52683, 52689, 52695, 52701, - 52707, 52713, 52720, 52728, 52736, 52744, 52752, 52760, 52768, 52776, - 52784, 52792, 52801, 52806, 52809, 52813, 52817, 52823, 52826, 52831, - 52837, 52842, 52846, 52851, 52857, 52864, 52867, 52874, 52881, 52885, - 52894, 52903, 52908, 52914, 52919, 52924, 52931, 52938, 52945, 52952, - 52960, 52964, 52972, 52977, 52981, 52988, 52992, 52998, 53006, 53011, - 53018, 53022, 53027, 53031, 53036, 53040, 53045, 53050, 53059, 53061, - 53065, 53069, 53076, 53083, 53089, 53097, 53103, 53110, 53115, 53118, - 53123, 53128, 53133, 53141, 53145, 53152, 53159, 53166, 53171, 53176, - 53182, 53187, 53192, 53198, 53203, 53206, 53210, 53214, 53221, 53231, - 53236, 53245, 53254, 53260, 53266, 53272, 53278, 53284, 53290, 53297, - 53304, 53313, 53322, 53328, 53334, 53339, 53344, 53351, 53358, 53364, - 53367, 53370, 53374, 53378, 53382, 53387, 53393, 53399, 53406, 53413, - 53418, 53422, 53426, 53430, 53434, 53438, 53442, 53446, 53450, 53454, - 53458, 53462, 53466, 53470, 53474, 53478, 53482, 53486, 53490, 53494, - 53498, 53502, 53506, 53510, 53514, 53518, 53522, 53526, 53530, 53534, - 53538, 53542, 53546, 53550, 53554, 53558, 53562, 53566, 53570, 53574, - 53578, 53582, 53586, 53590, 53594, 53598, 53602, 53606, 53610, 53614, - 53618, 53622, 53626, 53630, 53634, 53638, 53642, 53646, 53650, 53654, - 53658, 53662, 53666, 53670, 53674, 53678, 53682, 53686, 53690, 53694, - 53698, 53702, 53706, 53710, 53714, 53718, 53722, 53726, 53730, 53734, - 53738, 53742, 53746, 53750, 53754, 53758, 53762, 53766, 53770, 53774, - 53778, 53782, 53786, 53790, 53794, 53798, 53802, 53806, 53810, 53814, - 53818, 53822, 53826, 53830, 53834, 53838, 53842, 53846, 53850, 53854, - 53858, 53862, 53866, 53870, 53874, 53878, 53882, 53886, 53890, 53894, - 53898, 53902, 53906, 53910, 53914, 53918, 53922, 53926, 53930, 53934, - 53938, 53942, 53946, 53950, 53954, 53958, 53962, 53966, 53970, 53974, - 53978, 53982, 53986, 53990, 53994, 53998, 54002, 54006, 54010, 54014, - 54018, 54022, 54026, 54030, 54034, 54038, 54042, 54046, 54050, 54054, - 54058, 54062, 54066, 54070, 54074, 54078, 54082, 54086, 54090, 54094, - 54098, 54102, 54106, 54110, 54114, 54118, 54122, 54126, 54130, 54134, - 54138, 54142, 54146, 54150, 54154, 54158, 54162, 54166, 54170, 54174, - 54178, 54182, 54186, 54190, 54194, 54198, 54202, 54206, 54210, 54214, - 54218, 54222, 54226, 54230, 54234, 54238, 54242, 54246, 54250, 54254, - 54258, 54262, 54266, 54270, 54274, 54278, 54282, 54286, 54290, 54294, - 54298, 54302, 54306, 54310, 54314, 54318, 54322, 54326, 54330, 54334, - 54338, 54342, 54346, 54350, 54354, 54358, 54362, 54366, 54370, 54374, - 54378, 54382, 54386, 54390, 54394, 54398, 54402, 54406, 54410, 54414, - 54418, 54422, 54426, 54430, 54434, 54438, 54442, 54449, 54457, 54463, - 54469, 54476, 54483, 54489, 54495, 54502, 54509, 54514, 54519, 54524, - 54529, 54535, 54541, 54549, 54556, 54561, 54566, 54574, 54583, 54590, - 54600, 54611, 54614, 54617, 54621, 54625, 54631, 54637, 54647, 54657, - 54666, 54675, 54681, 54687, 54694, 54701, 54710, 54720, 54731, 54741, - 54751, 54761, 54772, 54783, 54793, 54804, 54814, 54824, 54832, 54842, - 54852, 54863, 54874, 54881, 54888, 54895, 54902, 54912, 54922, 54929, - 54936, 54943, 54950, 54957, 54964, 54971, 54976, 54981, 54987, 54995, - 55005, 55013, 55021, 55029, 55037, 55045, 55053, 55061, 55069, 55077, - 55085, 55094, 55103, 55111, 55119, 55128, 55137, 55146, 55155, 55165, - 55175, 55184, 55193, 55203, 55213, 55227, 55243, 55257, 55273, 55287, - 55301, 55315, 55329, 55339, 55350, 55360, 55371, 55387, 55403, 55411, - 55417, 55424, 55431, 55438, 55446, 55451, 55457, 55462, 55467, 55473, - 55478, 55483, 55488, 55493, 55498, 55505, 55511, 55519, 55525, 55531, - 55535, 55539, 55548, 55557, 55566, 55575, 55582, 55589, 55602, 55615, - 55628, 55641, 55649, 55657, 55664, 55671, 55679, 55687, 55695, 55703, - 55707, 55712, 55720, 55728, 55736, 55743, 55747, 55755, 55763, 55766, - 55770, 55775, 55782, 55790, 55798, 55817, 55837, 55856, 55876, 55896, - 55916, 55936, 55956, 55962, 55969, 55978, 55986, 55994, 56000, 56003, - 56006, 56011, 56014, 56034, 56041, 56047, 56053, 56057, 56060, 56063, - 56066, 56076, 56088, 56095, 56102, 56105, 56109, 56112, 56117, 56122, - 56127, 56133, 56142, 56149, 56156, 56164, 56171, 56178, 56181, 56187, - 56193, 56196, 56199, 56204, 56209, 56215, 56221, 56225, 56230, 56237, - 56241, 56247, 56251, 56255, 56263, 56275, 56283, 56287, 56289, 56298, - 56307, 56313, 56316, 56322, 56328, 56333, 56338, 56343, 56348, 56353, - 56358, 56360, 56366, 56371, 56379, 56383, 56389, 56392, 56396, 56404, - 56412, 56414, 56416, 56422, 56428, 56434, 56443, 56452, 56459, 56466, - 56472, 56479, 56484, 56489, 56494, 56500, 56506, 56511, 56518, 56522, - 56526, 56539, 56552, 56564, 56573, 56579, 56586, 56591, 56596, 56601, - 56606, 56611, 56613, 56620, 56628, 56636, 56644, 56651, 56659, 56665, - 56670, 56676, 56682, 56688, 56695, 56701, 56709, 56717, 56725, 56733, - 56741, 56747, 56753, 56762, 56766, 56775, 56784, 56793, 56801, 56805, - 56811, 56818, 56825, 56829, 56835, 56843, 56849, 56854, 56860, 56865, - 56870, 56877, 56884, 56889, 56894, 56902, 56910, 56920, 56930, 56937, - 56944, 56948, 56952, 56964, 56970, 56977, 56982, 56987, 56994, 57001, - 57007, 57013, 57023, 57030, 57038, 57046, 57055, 57062, 57068, 57075, - 57081, 57089, 57097, 57105, 57113, 57119, 57124, 57134, 57145, 57152, - 57161, 57167, 57172, 57177, 57187, 57196, 57202, 57208, 57216, 57221, - 57228, 57235, 57246, 57253, 57260, 57267, 57274, 57281, 57290, 57299, - 57312, 57325, 57337, 57349, 57362, 57376, 57382, 57388, 57398, 57408, - 57415, 57422, 57432, 57442, 57451, 57460, 57468, 57476, 57486, 57496, - 57511, 57526, 57535, 57544, 57557, 57570, 57579, 57588, 57599, 57610, - 57616, 57622, 57631, 57640, 57645, 57650, 57658, 57664, 57670, 57678, - 57686, 57699, 57712, 57716, 57720, 57729, 57738, 57745, 57753, 57761, - 57771, 57781, 57787, 57793, 57801, 57809, 57817, 57825, 57835, 57845, - 57848, 57851, 57856, 57861, 57867, 57873, 57880, 57887, 57898, 57909, - 57916, 57923, 57931, 57939, 57948, 57957, 57966, 57975, 57982, 57989, - 57993, 57997, 58006, 58015, 58020, 58025, 58030, 58035, 58041, 58055, - 58062, 58069, 58073, 58075, 58077, 58082, 58087, 58092, 58097, 58105, - 58112, 58119, 58127, 58139, 58147, 58155, 58166, 58170, 58174, 58180, - 58188, 58201, 58208, 58215, 58222, 58228, 58235, 58244, 58253, 58259, - 58265, 58271, 58282, 58293, 58301, 58310, 58315, 58318, 58323, 58328, - 58333, 58339, 58345, 58349, 58352, 58356, 58360, 58365, 58370, 58376, - 58382, 58386, 58390, 58397, 58404, 58411, 58418, 58425, 58432, 58441, - 58450, 58457, 58464, 58472, 58480, 58484, 58489, 58494, 58500, 58506, - 58509, 58512, 58515, 58518, 58523, 58528, 58533, 58538, 58543, 58548, - 58552, 58556, 58560, 58565, 58570, 58574, 58578, 58584, 58588, 58594, - 58599, 58606, 58614, 58621, 58629, 58636, 58644, 58653, 58660, 58670, - 58681, 58687, 58696, 58702, 58711, 58721, 58727, 58733, 58737, 58741, - 58750, 58760, 58767, 58775, 58784, 58793, 58800, 58806, 58813, 58818, - 58822, 58826, 58831, 58836, 58841, 58849, 58857, 58860, 58864, 58873, - 58883, 58892, 58902, 58914, 58928, 58932, 58937, 58941, 58946, 58951, - 58956, 58962, 58968, 58975, 58982, 58988, 58995, 59001, 59008, 59017, - 59026, 59032, 59039, 59045, 0, 0, 59052, 59060, 59068, 59077, 59086, - 59095, 59105, 59114, 59124, 59130, 59135, 59144, 59156, 59165, 59177, - 59184, 59192, 59199, 59207, 59212, 59218, 59223, 59229, 59237, 59246, - 59254, 59263, 59267, 59270, 59274, 59277, 59287, 0, 59290, 59297, 59306, - 59316, 59325, 59335, 59341, 59348, 59354, 59361, 59372, 59383, 59394, - 59405, 59415, 59425, 59435, 59445, 59453, 59461, 59469, 59477, 59485, - 59493, 59501, 59509, 59515, 59520, 59526, 59531, 59537, 59543, 59549, - 59555, 59567, 59577, 59582, 59589, 59594, 59601, 59604, 59608, 59612, - 59617, 59621, 59626, 59629, 59638, 59647, 59656, 59665, 59670, 59676, - 59682, 59690, 59700, 59707, 59716, 59721, 59724, 59727, 59732, 59737, - 59742, 59747, 59749, 59751, 59753, 59755, 59757, 59759, 59764, 59771, - 59778, 59780, 59782, 59784, 59786, 59788, 59790, 59792, 59794, 59799, - 59804, 59811, 59818, 59827, 59837, 59846, 59856, 59861, 59866, 59868, - 59875, 59882, 59889, 59896, 59903, 59910, 59917, 59920, 59923, 59926, - 59929, 59934, 59939, 59944, 59949, 59954, 59959, 59964, 59969, 59974, - 59979, 59984, 59989, 59995, 59999, 60004, 60009, 60014, 60019, 60024, - 60029, 60034, 60039, 60044, 60049, 60054, 60059, 60064, 60069, 60074, - 60079, 60084, 60089, 60094, 60099, 60104, 60109, 60115, 60120, 60126, - 60135, 60140, 60148, 60155, 60164, 60169, 60174, 60179, 60185, 60192, - 60199, 60204, 60209, 60214, 60219, 60224, 60229, 60234, 60239, 60244, - 60249, 60255, 60259, 60264, 60269, 60274, 60279, 60284, 60289, 60294, - 60299, 60304, 60309, 60314, 60319, 60324, 60329, 60334, 60339, 60344, - 60349, 60354, 60359, 60364, 60369, 60375, 60380, 60386, 60395, 60400, - 60408, 60415, 60424, 60429, 60434, 60439, 60445, 60452, 60459, 60467, - 60475, 60484, 60491, 60499, 60505, 60514, 60522, 60530, 60538, 60546, - 60554, 60562, 60567, 60574, 60579, 60585, 60593, 60600, 60607, 60615, - 60621, 60627, 60634, 60642, 60651, 60661, 60667, 60674, 60679, 60689, - 60699, 60704, 60709, 60714, 60719, 60724, 60729, 60734, 60739, 60744, - 60749, 60754, 60759, 60764, 60769, 60774, 60779, 60784, 60789, 60794, - 60799, 60804, 60809, 60814, 60819, 60824, 60829, 60834, 60839, 60844, - 60849, 60853, 60857, 60862, 60867, 60872, 60877, 60882, 60887, 60892, - 60897, 60902, 60907, 60912, 60917, 60922, 60927, 60932, 60937, 60942, - 60947, 60954, 60961, 60968, 60975, 60982, 60989, 60996, 61003, 61010, - 61017, 61024, 61031, 61038, 61045, 61050, 61055, 61062, 61069, 61076, - 61083, 61090, 61097, 61104, 61111, 61118, 61125, 61132, 61139, 61145, - 61151, 61157, 61163, 61170, 61177, 61184, 61191, 61198, 61205, 61212, - 61219, 61226, 61233, 61241, 61249, 61257, 61265, 61273, 61281, 61289, - 61297, 61301, 61307, 61313, 61317, 61323, 61329, 61335, 61342, 61349, - 61356, 61363, 61368, 61374, 61380, 61387, 0, 0, 0, 0, 0, 61394, 61402, - 61411, 61420, 61428, 61434, 61439, 61444, 61449, 61454, 61459, 61464, - 61469, 61474, 61479, 61484, 61489, 61494, 61499, 61504, 61509, 61514, - 61519, 61524, 61529, 61534, 61539, 61544, 61549, 61554, 61559, 61564, - 61569, 61574, 61579, 61584, 61589, 61594, 61599, 61604, 61609, 61614, - 61619, 61624, 61629, 0, 61634, 0, 0, 0, 0, 0, 61639, 0, 0, 61644, 61648, - 61653, 61658, 61663, 61668, 61677, 61682, 61687, 61692, 61697, 61702, - 61707, 61712, 61717, 61724, 61729, 61734, 61743, 61750, 61755, 61760, - 61765, 61772, 61777, 61784, 61789, 61794, 61801, 61808, 61813, 61818, - 61823, 61830, 61837, 61842, 61847, 61852, 61857, 61862, 61869, 61876, - 61881, 61886, 61891, 61896, 61901, 61906, 61911, 61916, 61921, 61926, - 61931, 61938, 61943, 61948, 0, 0, 0, 0, 0, 0, 0, 61953, 61960, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61965, 61970, 61974, 61978, 61982, - 61986, 61990, 61994, 61998, 62002, 62006, 62010, 62016, 62020, 62024, - 62028, 62032, 62036, 62040, 62044, 62048, 62052, 62056, 62060, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 62064, 62068, 62072, 62076, 62080, 62084, 62088, 0, - 62092, 62096, 62100, 62104, 62108, 62112, 62116, 0, 62120, 62124, 62128, - 62132, 62136, 62140, 62144, 0, 62148, 62152, 62156, 62160, 62164, 62168, - 62172, 0, 62176, 62180, 62184, 62188, 62192, 62196, 62200, 0, 62204, - 62208, 62212, 62216, 62220, 62224, 62228, 0, 62232, 62236, 62240, 62244, - 62248, 62252, 62256, 0, 62260, 62264, 62268, 62272, 62276, 62280, 62284, - 0, 62288, 62293, 62298, 62303, 62308, 62313, 62318, 62322, 62327, 62332, - 62337, 62341, 62346, 62351, 62356, 62361, 62365, 62370, 62375, 62380, - 62385, 62390, 62395, 62399, 62404, 62409, 62416, 62421, 62426, 62432, - 62439, 62446, 62455, 62462, 62471, 62476, 62481, 62488, 62495, 62501, - 62509, 62515, 62520, 62525, 62529, 62536, 62543, 62547, 62549, 62553, - 62559, 62561, 62565, 62569, 62573, 62579, 62584, 62588, 62592, 62597, - 62603, 62609, 62615, 62620, 62625, 62632, 62639, 62645, 62651, 62657, - 62663, 62669, 62675, 62679, 62683, 62690, 62697, 62703, 62707, 62712, - 62715, 62719, 62726, 62729, 62733, 62737, 62740, 62746, 62752, 62755, - 62761, 62765, 62769, 62775, 62780, 62785, 62787, 62790, 62794, 62800, - 62806, 62810, 62815, 62824, 62827, 62833, 62838, 62842, 62846, 62850, - 62853, 62858, 62864, 62872, 62880, 62886, 62891, 62896, 62902, 62908, - 62915, 62922, 62928, 62934, 62940, 62946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 62950, 62954, 62958, 62963, 62968, 62973, 62977, 62981, 62985, 62990, - 62995, 62999, 63003, 63007, 63011, 63016, 63021, 63026, 63031, 63035, - 63039, 63044, 63049, 63054, 63059, 63063, 0, 63067, 63071, 63075, 63079, - 63083, 63087, 63091, 63096, 63101, 63105, 63110, 63115, 63124, 63128, - 63132, 63136, 63143, 63147, 63152, 63157, 63161, 63165, 63171, 63176, - 63181, 63186, 63191, 63195, 63199, 63203, 63207, 63211, 63216, 63221, - 63225, 63229, 63234, 63239, 63244, 63248, 63252, 63257, 63262, 63268, - 63274, 63278, 63284, 63290, 63294, 63300, 63306, 63311, 63316, 63320, - 63326, 63330, 63334, 63340, 63346, 63351, 63356, 63360, 63364, 63372, - 63378, 63384, 63390, 63395, 63400, 63405, 63411, 63415, 63421, 63425, - 63429, 63435, 63441, 63447, 63453, 63459, 63465, 63471, 63477, 63483, - 63489, 63495, 63501, 63505, 63511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 63517, 63520, 63524, 63528, 63532, 63536, 63539, 63542, 63546, 63550, - 63554, 63558, 63561, 63566, 63570, 63574, 63578, 63584, 63588, 63592, - 63596, 63600, 63607, 63613, 63617, 63621, 63625, 63629, 63633, 63637, - 63641, 63645, 63649, 63653, 63657, 63663, 63667, 63671, 63675, 63679, - 63683, 63687, 63691, 63695, 63699, 63703, 63707, 63711, 63715, 63719, - 63723, 63727, 63733, 63739, 63744, 63749, 63753, 63757, 63761, 63765, - 63769, 63773, 63777, 63781, 63785, 63789, 63793, 63797, 63801, 63805, - 63809, 63813, 63817, 63821, 63825, 63829, 63833, 63837, 63841, 63845, - 63851, 63855, 63859, 63863, 63867, 63871, 63875, 63879, 63883, 63888, - 63895, 63899, 63903, 63907, 63911, 63915, 63919, 63923, 63927, 63931, - 63935, 63939, 63943, 63950, 63954, 63960, 63964, 63968, 63972, 63976, - 63980, 63983, 63987, 63991, 63995, 63999, 64003, 64007, 64011, 64015, - 64019, 64023, 64027, 64031, 64035, 64039, 64043, 64047, 64051, 64055, - 64059, 64063, 64067, 64071, 64075, 64079, 64083, 64087, 64091, 64095, - 64099, 64103, 64107, 64111, 64117, 64121, 64125, 64129, 64133, 64137, - 64141, 64145, 64149, 64153, 64157, 64161, 64165, 64169, 64173, 64177, - 64181, 64185, 64189, 64193, 64197, 64201, 64205, 64209, 64213, 64217, - 64221, 64225, 64233, 64237, 64241, 64245, 64249, 64253, 64259, 64263, - 64267, 64271, 64275, 64279, 64283, 64287, 64291, 64295, 64299, 64303, - 64307, 64311, 64317, 64321, 64325, 64329, 64333, 64337, 64341, 64345, - 64349, 64353, 64357, 64361, 64365, 64369, 64373, 64377, 64381, 64385, - 64389, 64393, 64397, 64401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64405, 64413, 64421, 64431, 64441, - 64450, 64460, 64470, 64481, 64493, 64504, 64516, 0, 0, 0, 0, 64523, - 64526, 64529, 64534, 64537, 64544, 64548, 64552, 64556, 64561, 64566, - 64572, 64578, 64583, 64588, 64594, 64600, 64606, 64612, 64615, 64618, - 64625, 64632, 64638, 64644, 64652, 64660, 64665, 64670, 64674, 64682, - 64688, 64695, 64700, 64705, 64710, 64715, 64720, 64725, 64730, 64735, - 64740, 64745, 64750, 64755, 64760, 64765, 64771, 64776, 64780, 64786, - 64797, 64806, 64820, 64829, 64833, 64843, 64849, 64855, 64861, 64866, - 64869, 64874, 64878, 0, 64884, 64889, 64893, 64898, 64902, 64907, 64911, - 64916, 64920, 64925, 64929, 64933, 64938, 64943, 64948, 64953, 64958, - 64963, 64968, 64973, 64978, 64982, 64987, 64992, 64997, 65002, 65007, - 65012, 65017, 65022, 65027, 65032, 65037, 65042, 65047, 65053, 65058, - 65063, 65068, 65073, 65077, 65082, 65086, 65091, 65096, 65101, 65106, - 65110, 65115, 65119, 65124, 65129, 65134, 65139, 65144, 65149, 65154, - 65159, 65164, 65169, 65174, 65179, 65183, 65188, 65193, 65198, 65203, - 65208, 65212, 65218, 65223, 65229, 65234, 65238, 65243, 65248, 65253, - 65258, 65264, 65269, 65274, 65279, 65284, 65289, 65294, 65299, 0, 0, - 65305, 65313, 65321, 65328, 65335, 65340, 65347, 65353, 65358, 65362, - 65365, 65369, 65372, 65376, 65379, 65383, 65386, 65390, 65393, 65396, - 65400, 65404, 65408, 65412, 65416, 65420, 65424, 65428, 65432, 65435, - 65439, 65443, 65447, 65451, 65455, 65459, 65463, 65467, 65471, 65475, - 65479, 65483, 65487, 65492, 65496, 65500, 65504, 65508, 65511, 65515, - 65518, 65522, 65526, 65530, 65534, 65537, 65541, 65544, 65548, 65552, - 65556, 65560, 65564, 65568, 65572, 65576, 65580, 65584, 65588, 65592, - 65595, 65599, 65603, 65607, 65611, 65615, 65618, 65623, 65627, 65632, - 65636, 65639, 65643, 65647, 65651, 65655, 65660, 65664, 65668, 65672, - 65676, 65680, 65684, 65688, 65693, 65697, 65701, 65705, 65709, 65713, - 65720, 65724, 65730, 0, 0, 0, 0, 0, 65735, 65740, 65745, 65750, 65755, - 65760, 65765, 65770, 65774, 65779, 65784, 65789, 65794, 65799, 65804, - 65809, 65814, 65819, 65823, 65828, 65833, 65838, 65842, 65846, 65850, - 65855, 65860, 65865, 65870, 65875, 65880, 65885, 65890, 65895, 65900, - 65904, 65908, 65913, 65918, 65923, 65928, 65933, 65940, 0, 65945, 65949, - 65953, 65957, 65961, 65965, 65969, 65973, 65977, 65981, 65985, 65989, - 65993, 65997, 66001, 66005, 66009, 66013, 66017, 66021, 66025, 66029, - 66033, 66037, 66041, 66045, 66049, 66053, 66057, 66061, 66065, 66068, - 66072, 66075, 66079, 66083, 66086, 66090, 66094, 66097, 66101, 66105, - 66109, 66113, 66116, 66120, 66124, 66128, 66132, 66136, 66140, 66143, - 66146, 66150, 66154, 66158, 66162, 66166, 66170, 66174, 66178, 66182, - 66186, 66190, 66194, 66198, 66202, 66206, 66210, 66214, 66218, 66222, - 66226, 66230, 66234, 66238, 66242, 66246, 66250, 66254, 66258, 66262, - 66266, 66270, 66274, 66278, 66282, 66286, 66290, 66294, 66298, 66302, - 66306, 66310, 0, 66314, 66320, 66326, 66331, 66336, 66341, 66347, 66353, - 66358, 66364, 66370, 66376, 66382, 66388, 66394, 66400, 66406, 66411, - 66416, 66421, 66426, 66431, 66436, 66441, 66446, 66451, 66456, 66461, - 66466, 66471, 66476, 66481, 66486, 66491, 66496, 66501, 66506, 66512, - 66518, 66524, 66530, 66535, 66540, 66545, 66551, 66556, 66561, 66566, - 66571, 66576, 66581, 66586, 66591, 66596, 66601, 66606, 66611, 66616, - 66621, 66626, 66631, 66636, 66641, 66646, 66651, 66656, 66661, 66666, - 66671, 66676, 66681, 66686, 66691, 66696, 66701, 66706, 66711, 66716, - 66721, 66726, 66731, 66736, 66741, 66746, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 66751, 66756, 66761, 66766, 66770, 66775, 66779, 66784, 66789, - 66794, 66799, 66804, 66808, 66813, 66818, 66823, 66828, 66832, 66836, - 66840, 66844, 66848, 66852, 66856, 66860, 66864, 66868, 66872, 66876, - 66880, 66884, 66889, 66894, 66899, 66904, 66909, 66914, 66919, 66924, - 66929, 66934, 66939, 66944, 66949, 66954, 66959, 66966, 0, 66974, 66978, - 66982, 66986, 66990, 66994, 66998, 67002, 67006, 67010, 67015, 67020, - 67025, 67030, 67035, 67040, 67045, 67050, 67055, 67060, 67065, 67070, - 67075, 67080, 67085, 67090, 67095, 67100, 67105, 67110, 67115, 67120, - 67125, 67130, 67135, 67140, 67145, 67150, 67155, 67160, 67165, 67174, - 67183, 67192, 67201, 67210, 67219, 67228, 67237, 67240, 67245, 67250, - 67255, 67260, 67265, 67270, 67275, 67280, 67285, 67289, 67294, 67299, - 67304, 67309, 67314, 67318, 67322, 67326, 67330, 67334, 67338, 67342, - 67346, 67350, 67354, 67358, 67362, 67366, 67370, 67375, 67380, 67385, - 67390, 67395, 67400, 67405, 67410, 67415, 67420, 67425, 67430, 67435, - 67440, 67447, 67454, 67459, 67464, 67468, 67472, 67476, 67480, 67484, - 67488, 67492, 67496, 67500, 67505, 67510, 67515, 67520, 67525, 67530, - 67535, 67540, 67545, 67550, 67555, 67560, 67565, 67570, 67575, 67580, - 67585, 67590, 67595, 67600, 67605, 67610, 67615, 67620, 67625, 67630, - 67635, 67640, 67645, 67650, 67655, 67659, 67664, 67669, 67674, 67679, - 67684, 67689, 67694, 67699, 67704, 67709, 67714, 67719, 67723, 67728, - 67733, 67738, 67743, 67748, 67753, 67758, 67763, 67768, 67772, 67779, - 67786, 67793, 67800, 67807, 67814, 67821, 67828, 67835, 67842, 67849, - 67856, 67859, 67862, 67865, 67870, 67873, 67876, 67879, 67882, 67885, - 67888, 67892, 67896, 67900, 67904, 67907, 67911, 67915, 67919, 67923, - 67927, 67931, 67935, 67939, 67942, 67945, 67949, 67953, 67957, 67961, - 67964, 67968, 67972, 67976, 67980, 67983, 67987, 67991, 67995, 67999, - 68002, 68006, 68010, 68013, 68017, 68021, 68025, 68029, 68033, 68037, - 68041, 68045, 68052, 68055, 68058, 68061, 68064, 68067, 68070, 68073, - 68076, 68079, 68082, 68085, 68088, 68091, 68094, 68097, 68100, 68103, - 68106, 68109, 68112, 68115, 68118, 68121, 68124, 68127, 68130, 68133, - 68136, 68139, 68142, 68145, 68148, 68151, 68154, 68157, 68160, 68163, - 68166, 68169, 68172, 68175, 68178, 68181, 68184, 68187, 68190, 68193, - 68196, 68199, 68202, 68205, 68208, 68211, 68214, 68217, 68220, 68223, - 68226, 68229, 68232, 68235, 68238, 68241, 68244, 68247, 68250, 68253, - 68256, 68259, 68262, 68265, 68268, 68271, 68274, 68277, 68280, 68283, - 68286, 68289, 68292, 68295, 68298, 68301, 68304, 68307, 68310, 68313, - 68316, 68325, 68333, 68341, 68349, 68357, 68365, 68373, 68381, 68389, - 68397, 68406, 68415, 68424, 68433, 68442, 68451, 68460, 68469, 68478, - 68487, 68496, 68505, 68514, 68523, 68532, 68535, 68538, 68541, 68543, - 68546, 68549, 68552, 68557, 68562, 68565, 68572, 68579, 68586, 68593, - 68596, 68601, 68603, 68607, 68609, 68611, 68614, 68617, 68620, 68623, - 68626, 68629, 68632, 68637, 68642, 68645, 68648, 68651, 68654, 68657, - 68660, 68663, 68667, 68670, 68673, 68676, 68679, 68682, 68687, 68690, - 68693, 68696, 68701, 68706, 68711, 68716, 68721, 68726, 68731, 68736, - 68742, 68750, 68752, 68755, 68758, 68761, 68764, 68770, 68778, 68781, - 68784, 68789, 68792, 68795, 68798, 68803, 68806, 68809, 68814, 68817, - 68820, 68825, 68828, 68831, 68836, 68841, 68846, 68849, 68852, 68855, - 68858, 68864, 68867, 68870, 68873, 68875, 68878, 68881, 68884, 68889, - 68892, 68895, 68898, 68901, 68904, 68909, 68912, 68915, 68918, 68921, - 68924, 68927, 68930, 68933, 68936, 68942, 68947, 68955, 68963, 68971, - 68979, 68987, 68995, 69003, 69011, 69019, 69028, 69037, 69046, 69055, - 69064, 69073, 69082, 69091, 69100, 69109, 69118, 69127, 69136, 69145, - 69154, 69163, 69172, 69181, 69190, 69199, 69208, 69217, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69220, 69229, - 69238, 69249, 69256, 69261, 69266, 69273, 69280, 69286, 69291, 69296, - 69301, 69306, 69313, 69318, 69323, 69328, 69339, 69344, 69349, 69356, - 69361, 69368, 69373, 69378, 69385, 69392, 69399, 69408, 69417, 69422, - 69427, 69432, 69439, 69444, 69454, 69461, 69466, 69471, 69476, 69481, - 69486, 69491, 69499, 69506, 69513, 69518, 69525, 69530, 69537, 69546, - 69557, 69562, 69571, 69576, 69583, 69592, 69601, 69606, 69611, 69618, - 69624, 69631, 69638, 69642, 69646, 69649, 69653, 69657, 69661, 69665, - 69669, 69673, 69677, 69680, 69684, 69688, 69692, 69696, 69700, 69704, - 69707, 69711, 69715, 69718, 69722, 69726, 69730, 69734, 69738, 69742, - 69746, 69750, 69754, 69758, 69762, 69766, 69770, 69774, 69778, 69782, - 69786, 69790, 69794, 69798, 69802, 69806, 69810, 69814, 69818, 69822, - 69826, 69830, 69834, 69838, 69842, 69846, 69850, 69854, 69858, 69862, - 69866, 69870, 69874, 69878, 69882, 69886, 69890, 69894, 69897, 69901, - 69905, 69909, 69913, 69917, 69921, 69925, 69929, 69933, 69937, 69941, - 69945, 69949, 69953, 69957, 69961, 69965, 69969, 69973, 69977, 69981, - 69985, 69989, 69993, 69997, 70001, 70005, 70009, 70013, 70017, 70021, - 70025, 70029, 70033, 70037, 70041, 70045, 70049, 70053, 70057, 70061, - 70065, 70069, 70073, 70077, 70081, 70085, 70089, 70093, 70097, 70101, - 70105, 70109, 70113, 70117, 70121, 70125, 70129, 70133, 70137, 70141, - 70145, 70149, 70153, 70157, 70161, 70165, 70169, 70173, 70177, 70181, - 70185, 70189, 70193, 70197, 70201, 70205, 70209, 70213, 70217, 70221, - 70225, 70229, 70233, 70237, 70241, 70245, 70249, 70253, 70257, 70261, - 70265, 70269, 70273, 70277, 70281, 70285, 70289, 70293, 70297, 70301, - 70305, 70309, 70313, 70317, 70321, 70325, 70329, 70333, 70337, 70341, - 70345, 70349, 70353, 70357, 70361, 70365, 70368, 70372, 70376, 70380, - 70384, 70388, 70392, 70396, 70400, 70404, 70408, 70412, 70416, 70420, - 70424, 70428, 70432, 70436, 70440, 70444, 70448, 70452, 70456, 70460, - 70464, 70468, 70472, 70476, 70480, 70484, 70488, 70492, 70496, 70500, - 70504, 70508, 70512, 70516, 70520, 70524, 70528, 70532, 70536, 70540, - 70544, 70548, 70552, 70556, 70560, 70564, 70568, 70572, 70576, 70580, - 70584, 70588, 70592, 70596, 70600, 70604, 70608, 70612, 70616, 70620, - 70624, 70628, 70632, 70636, 70640, 70644, 70648, 70652, 70656, 70660, - 70664, 70668, 70672, 70676, 70680, 70684, 70688, 70692, 70696, 70700, - 70704, 70708, 70712, 70716, 70720, 70724, 70728, 70732, 70736, 70740, - 70744, 70748, 70752, 70756, 70760, 70764, 70768, 70772, 70776, 70780, - 70784, 70788, 70792, 70796, 70800, 70804, 70808, 70812, 70816, 70820, - 70824, 70828, 70831, 70835, 70839, 70843, 70847, 70851, 70855, 70859, - 70863, 70867, 70871, 70875, 70879, 70883, 70887, 70891, 70895, 70899, - 70903, 70907, 70911, 70915, 70919, 70923, 70927, 70931, 70935, 70939, - 70943, 70947, 70951, 70955, 70959, 70963, 70967, 70971, 70975, 70979, - 70983, 70987, 70991, 70995, 70999, 71003, 71007, 71011, 71015, 71019, - 71023, 71027, 71031, 71035, 71039, 71043, 71047, 71051, 71055, 71059, - 71063, 71067, 71071, 71075, 71079, 71083, 71087, 71091, 71095, 71099, - 71103, 71107, 71111, 71115, 71119, 71123, 71127, 71131, 71135, 71139, - 71143, 71147, 71151, 71155, 71159, 71163, 71167, 71171, 71175, 71179, - 71183, 71187, 71190, 71194, 71198, 71202, 71206, 71210, 71214, 71218, - 71222, 71226, 71230, 71234, 71238, 71242, 71246, 71250, 71254, 71258, - 71262, 71266, 71270, 71274, 71278, 71282, 71286, 71290, 71294, 71298, - 71302, 71306, 71310, 71314, 71318, 71322, 71326, 71330, 71334, 71338, - 71342, 71346, 71350, 71354, 71358, 71362, 71366, 71370, 71374, 71378, - 71382, 71386, 71390, 71394, 71398, 71402, 71406, 71410, 71414, 71418, - 71422, 71426, 71429, 71433, 71437, 71441, 71445, 71449, 71453, 71457, - 71461, 71465, 71469, 71473, 71477, 71481, 71485, 71489, 71493, 71497, - 71501, 71505, 71509, 71513, 71517, 71521, 71525, 71529, 71533, 71537, - 71541, 71545, 71549, 71553, 71557, 71561, 71565, 71569, 71573, 71577, - 71581, 71585, 71589, 71593, 71597, 71601, 71605, 71609, 71613, 71617, - 71621, 71625, 71629, 71633, 71637, 71641, 71645, 71649, 71653, 71657, - 71661, 71665, 71669, 71673, 71677, 71681, 71684, 71688, 71692, 71696, - 71700, 71704, 71708, 71712, 71716, 71720, 71724, 71728, 71732, 71736, - 71740, 71744, 71748, 71752, 71756, 71760, 71764, 71768, 71772, 71776, - 71780, 71784, 71788, 71792, 71796, 71800, 71804, 71808, 71812, 71816, - 71820, 71824, 71828, 71832, 71836, 71840, 71844, 71848, 71852, 71856, - 71860, 71864, 71868, 71872, 71876, 71880, 71884, 71888, 71892, 71896, - 71900, 71904, 71908, 71912, 71916, 71920, 71924, 71928, 71932, 71936, - 71940, 71944, 71948, 71952, 71956, 71960, 71964, 71968, 71972, 71976, - 71980, 71984, 71988, 71992, 71996, 72000, 72004, 72008, 72012, 72016, - 72020, 72024, 72028, 72032, 72036, 72040, 72044, 72048, 72052, 72056, - 72060, 72064, 72068, 72072, 72076, 72080, 72084, 72088, 72092, 72096, - 72100, 72104, 72108, 72112, 72116, 72120, 72124, 72128, 72132, 72136, - 72139, 72143, 72147, 72151, 72155, 72159, 72163, 72167, 72171, 72175, - 72179, 72183, 72187, 72191, 72195, 72199, 72203, 72207, 72211, 72215, - 72219, 72223, 72227, 72231, 72235, 72239, 72243, 72247, 72251, 72255, - 72259, 72263, 72267, 72271, 72275, 72279, 72283, 72287, 72291, 72295, - 72299, 72303, 72307, 72311, 72315, 72319, 72323, 72327, 72331, 72335, - 72339, 72343, 72347, 72351, 72355, 72359, 72363, 72367, 72371, 72375, - 72379, 72383, 72387, 72391, 72395, 72399, 72403, 72407, 72411, 72415, - 72419, 72423, 72427, 72431, 72435, 72439, 72443, 72447, 72451, 72455, - 72459, 72463, 72467, 72471, 72475, 72479, 72483, 72487, 72491, 72495, - 72499, 72503, 72507, 72511, 72515, 72519, 72523, 72527, 72531, 72535, - 72539, 72543, 72547, 72551, 72555, 72559, 72563, 72567, 72571, 72575, - 72579, 72583, 72587, 72591, 72595, 72599, 72603, 72607, 72611, 72615, - 72619, 72623, 72627, 72631, 72635, 72639, 72643, 72647, 72651, 72655, - 72659, 72663, 72667, 72671, 72675, 72679, 72683, 72687, 72691, 72695, - 72699, 72703, 72707, 72711, 72715, 72719, 72723, 72727, 72731, 72735, - 72739, 72742, 72746, 72750, 72754, 72758, 72762, 72766, 72770, 72773, - 72777, 72781, 72785, 72789, 72793, 72797, 72801, 72805, 72809, 72813, - 72817, 72821, 72825, 72829, 72833, 72837, 72841, 72845, 72849, 72853, - 72857, 72861, 72865, 72869, 72873, 72877, 72881, 72885, 72889, 72893, - 72897, 72901, 72905, 72909, 72913, 72917, 72921, 72925, 72929, 72933, - 72937, 72941, 72945, 72949, 72953, 72957, 72961, 72965, 72969, 72973, - 72977, 72981, 72985, 72989, 72993, 72997, 73001, 73005, 73009, 73013, - 73017, 73021, 73025, 73029, 73033, 73037, 73041, 73045, 73049, 73053, - 73057, 73061, 73065, 73069, 73073, 73077, 73081, 73085, 73089, 73093, - 73097, 73101, 73105, 73109, 73113, 73117, 73121, 73125, 73129, 73133, - 73137, 73141, 73145, 73149, 73153, 73157, 73161, 73165, 73169, 73173, - 73177, 73181, 73185, 73189, 73193, 73197, 73201, 73205, 73209, 73213, - 73217, 73221, 73225, 73229, 73233, 73237, 73241, 73245, 73249, 73253, - 73257, 73261, 73265, 73269, 73273, 73277, 73281, 73285, 73289, 73293, - 73297, 73301, 73305, 73309, 73313, 73317, 73321, 73325, 73329, 73333, - 73337, 73341, 73345, 73349, 73353, 73357, 73361, 73365, 73369, 73373, - 73377, 73381, 73385, 73389, 73393, 73397, 73401, 73405, 73409, 73413, - 73417, 73421, 73425, 73429, 73433, 73437, 73441, 73445, 73449, 73453, - 73457, 73461, 73465, 73469, 73473, 73477, 73481, 73485, 73489, 73493, - 73497, 73500, 73504, 73508, 73512, 73516, 73520, 73524, 73528, 73532, - 73536, 73540, 73544, 73548, 73552, 73556, 73560, 73564, 73568, 73572, - 73576, 73580, 73584, 73588, 73592, 73596, 73600, 73604, 73608, 73612, - 73616, 73620, 73624, 73628, 73632, 73636, 73640, 73644, 73648, 73652, - 73656, 73660, 73664, 73668, 73672, 73676, 73680, 73684, 73688, 73692, - 73696, 73700, 73704, 73708, 73712, 73716, 73720, 73724, 73728, 73732, - 73736, 73740, 73744, 73748, 73752, 73756, 73760, 73764, 73768, 73772, - 73776, 73780, 73784, 73788, 73792, 73796, 73800, 73804, 73808, 73812, - 73816, 73820, 73824, 73828, 73832, 73836, 73840, 73844, 73848, 73852, - 73856, 73860, 73864, 73868, 73872, 73876, 73880, 73884, 73888, 73892, - 73896, 73900, 73904, 73908, 73912, 73916, 73920, 73924, 73928, 73932, - 73936, 73940, 73944, 73948, 73952, 73956, 73960, 73964, 73968, 73972, - 73976, 73980, 73984, 73988, 73992, 73996, 74000, 74004, 74008, 74012, - 74016, 74020, 74024, 74028, 74032, 74036, 74040, 74044, 74048, 74052, - 74056, 74060, 74064, 74068, 74072, 74076, 74080, 74084, 74088, 74092, - 74096, 74100, 74104, 74108, 74112, 74116, 74120, 74124, 74128, 74132, - 74136, 74140, 74144, 74148, 74152, 74156, 74160, 74164, 74168, 74172, - 74176, 74180, 74184, 74188, 74192, 74196, 74200, 74204, 74208, 74212, - 74216, 74220, 74224, 74228, 74232, 74236, 74240, 74244, 74248, 74252, - 74256, 74260, 74264, 74268, 74272, 74276, 74280, 0, 0, 0, 74284, 74288, - 74292, 74296, 74300, 74304, 74308, 74312, 74316, 74320, 74324, 74328, - 74332, 74336, 74340, 74344, 74348, 74352, 74356, 74360, 74364, 74368, - 74372, 74376, 74380, 74384, 74388, 74392, 74396, 74400, 74404, 74408, - 74412, 74416, 74420, 74424, 74428, 74432, 74436, 74440, 74444, 74448, - 74452, 74456, 74460, 74464, 74468, 74472, 74476, 74480, 74484, 74488, - 74492, 74496, 74500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74504, 74509, 74513, - 74518, 74523, 74528, 74533, 74538, 74542, 74547, 74552, 74557, 74562, - 74567, 74572, 74577, 74581, 74585, 74589, 74593, 74598, 74603, 74608, - 74612, 74617, 74622, 74627, 74632, 74637, 74641, 74646, 74650, 74655, - 74659, 74664, 74668, 74672, 74676, 74681, 74686, 74691, 74699, 74707, - 74715, 74723, 74730, 74738, 74744, 74752, 74756, 74760, 74764, 74768, - 74772, 74776, 74780, 74784, 74788, 74792, 74796, 74800, 74804, 74808, - 74812, 74816, 74820, 74824, 74828, 74832, 74836, 74840, 74844, 74848, - 74852, 74856, 74860, 74864, 74868, 74872, 74876, 74880, 74884, 74888, - 74892, 74896, 74899, 74903, 74907, 74911, 74915, 74919, 74923, 74927, - 74931, 74935, 74939, 74943, 74947, 74951, 74955, 74959, 74963, 74967, - 74971, 74975, 74979, 74983, 74987, 74991, 74995, 74999, 75003, 75007, - 75011, 75015, 75019, 75023, 75027, 75031, 75035, 75039, 75043, 75046, - 75050, 75054, 75057, 75061, 75065, 75069, 75072, 75076, 75080, 75084, - 75088, 75092, 75096, 75100, 75104, 75108, 75112, 75116, 75120, 75124, - 75127, 75130, 75134, 75138, 75141, 75145, 75149, 75153, 75157, 75161, - 75165, 75168, 75171, 75175, 75179, 75183, 75186, 75189, 75193, 75197, - 75201, 75205, 75209, 75213, 75217, 75221, 75225, 75229, 75233, 75237, - 75241, 75245, 75249, 75253, 75257, 75261, 75265, 75269, 75273, 75277, - 75281, 75285, 75289, 75293, 75297, 75301, 75305, 75309, 75313, 75317, - 75321, 75325, 75329, 75333, 75337, 75340, 75344, 75348, 75352, 75356, - 75360, 75364, 75368, 75372, 75376, 75380, 75384, 75388, 75392, 75396, - 75400, 75404, 75408, 75412, 75416, 75420, 75424, 75428, 75432, 75436, - 75440, 75444, 75448, 75452, 75456, 75460, 75464, 75468, 75472, 75476, - 75480, 75484, 75487, 75491, 75495, 75499, 75503, 75507, 75511, 75515, - 75519, 75523, 75527, 75531, 75535, 75539, 75543, 75547, 75551, 75554, - 75558, 75562, 75566, 75570, 75574, 75578, 75582, 75586, 75590, 75594, - 75598, 75602, 75606, 75610, 75614, 75618, 75622, 75626, 75630, 75634, - 75638, 75641, 75645, 75649, 75653, 75657, 75661, 75665, 75669, 75673, - 75677, 75681, 75685, 75689, 75693, 75697, 75701, 75705, 75709, 75713, - 75717, 75721, 75725, 75729, 75733, 75737, 75741, 75745, 75749, 75753, - 75757, 75761, 75765, 75769, 75773, 75777, 75781, 75785, 75789, 75793, - 75797, 75801, 75805, 75809, 75813, 75816, 75821, 75825, 75831, 75836, - 75842, 75846, 75850, 75854, 75858, 75862, 75866, 75870, 75874, 75878, - 75882, 75886, 75890, 75894, 75898, 75901, 75904, 75907, 75910, 75913, - 75916, 75919, 75922, 75925, 75930, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 75936, 75941, 75946, 75951, 75956, 75963, 75970, - 75975, 75980, 75985, 75990, 75997, 76004, 76011, 76018, 76025, 76032, - 76042, 76052, 76059, 76066, 76073, 76080, 76086, 76092, 76101, 76110, - 76117, 76124, 76135, 76146, 76151, 76156, 76163, 76170, 76177, 76184, - 76191, 76198, 76205, 76212, 76218, 76224, 76230, 76236, 76243, 76250, - 76255, 76259, 76266, 76273, 76280, 76284, 76291, 76295, 76300, 76304, - 76310, 76315, 76321, 76326, 76330, 76334, 76337, 76340, 76345, 76350, - 76355, 76360, 76365, 76370, 76375, 76380, 76385, 76390, 76398, 76406, - 76411, 76416, 76421, 76426, 76431, 76436, 76441, 76446, 76451, 76456, - 76461, 76466, 76471, 76476, 76482, 76488, 76494, 76500, 76505, 76511, - 76514, 76517, 76520, 76524, 76528, 76532, 76536, 76539, 76543, 76546, - 76549, 76552, 76556, 76560, 76564, 76568, 76572, 76576, 76580, 76584, - 76588, 76592, 76596, 76600, 76604, 76608, 76612, 76616, 76620, 76624, - 76628, 76632, 76636, 76640, 76643, 76647, 76651, 76655, 76659, 76663, - 76667, 76671, 76675, 76679, 76683, 76687, 76691, 76695, 76699, 76703, - 76707, 76711, 76715, 76719, 76723, 76727, 76731, 76735, 76739, 76742, - 76746, 76750, 76754, 76758, 76762, 76766, 76770, 76773, 76777, 76781, - 76785, 76789, 76793, 76797, 76801, 76805, 76809, 76813, 76817, 76821, - 76826, 76831, 76834, 76839, 76842, 76845, 76848, 0, 0, 0, 0, 0, 0, 0, 0, - 76852, 76861, 76870, 76879, 76888, 76897, 76906, 76915, 76924, 76932, - 76939, 76947, 76954, 76962, 76972, 76981, 76991, 77000, 77010, 77018, - 77025, 77033, 77040, 77048, 77053, 77058, 77064, 77072, 77078, 77084, - 77091, 77100, 77108, 77116, 77124, 77131, 77138, 77145, 77152, 77157, - 77162, 77167, 77172, 77177, 77182, 77187, 77192, 77200, 77208, 77214, - 77220, 77225, 77230, 77235, 77240, 77245, 77250, 77255, 77260, 77269, - 77278, 77283, 77288, 77298, 77308, 77315, 77322, 77331, 77340, 77352, - 77364, 77370, 77376, 77384, 77392, 77402, 77412, 77419, 77426, 77431, - 77436, 77448, 77460, 77468, 77476, 77486, 77496, 77508, 77520, 77529, - 77538, 77545, 77552, 77559, 77566, 77575, 77584, 77589, 77594, 77601, - 77608, 77615, 77622, 77634, 77646, 77651, 77656, 77661, 77666, 77671, - 77676, 77681, 77686, 77690, 77695, 77700, 77705, 77710, 77715, 77721, - 77726, 77731, 77738, 77745, 77752, 77759, 77766, 77774, 77782, 77787, - 77792, 77798, 77804, 77811, 77818, 77825, 77832, 77839, 77843, 77850, - 77855, 77860, 77866, 77879, 77885, 77893, 77901, 77908, 77915, 77924, - 77933, 77940, 77947, 77954, 77961, 77968, 77975, 77982, 77989, 77996, - 78003, 78012, 78021, 78030, 78039, 78048, 78057, 78066, 78075, 78084, - 78093, 78100, 78108, 78114, 78122, 78128, 78134, 78140, 78146, 78154, - 78159, 78164, 78169, 78174, 78179, 78185, 78191, 78197, 78203, 78209, - 78215, 78221, 78227, 78234, 78241, 78248, 78255, 78264, 78271, 78280, - 78292, 78304, 78316, 0, 0, 0, 0, 0, 78328, 78337, 0, 78346, 0, 78352, - 78358, 78366, 78374, 78381, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 78388, 78393, 78398, 78403, 78411, 78419, - 78426, 78433, 78439, 78446, 78454, 78462, 78470, 78478, 78486, 78492, - 78498, 78505, 78511, 78517, 78523, 78530, 78537, 78544, 78551, 78558, - 78565, 78572, 78579, 78586, 78593, 78600, 78607, 78614, 78621, 78627, - 78634, 78641, 78648, 78655, 78662, 78669, 78676, 78683, 78690, 78697, - 78704, 78711, 78718, 78725, 78732, 78739, 78746, 78753, 78761, 78769, - 78777, 78785, 78793, 0, 0, 0, 78802, 78810, 78818, 78826, 78834, 78842, - 78850, 78856, 78862, 78868, 0, 0, 0, 0, 0, 0, 78874, 78878, 78883, 78888, - 78893, 78898, 78903, 78908, 78913, 78918, 78923, 78928, 78932, 78936, - 78941, 78946, 78950, 78955, 78960, 78965, 78970, 78975, 78980, 78985, - 78989, 78993, 78997, 79002, 79006, 79010, 79014, 79018, 79022, 79026, - 79030, 79035, 79040, 79045, 79050, 79055, 79062, 79068, 79073, 79078, - 79083, 79088, 79094, 79101, 79107, 79114, 79120, 79126, 79131, 79138, - 79144, 79149, 0, 0, 0, 0, 0, 0, 0, 0, 79155, 79160, 79165, 79169, 79174, - 79178, 79183, 79187, 79192, 79197, 79203, 79208, 79214, 79218, 79223, - 79228, 79232, 79237, 79242, 79246, 79251, 79256, 79261, 79266, 79271, - 79276, 79281, 79286, 79291, 79296, 79301, 79306, 79311, 79316, 79321, - 79326, 79331, 79336, 79340, 79344, 79349, 79354, 79359, 79363, 79367, - 79371, 79375, 79380, 79385, 79390, 79394, 79398, 79403, 79409, 79415, - 79420, 79426, 79431, 79437, 79443, 79450, 79456, 79463, 79468, 79474, - 79480, 79485, 79491, 79497, 79502, 0, 0, 0, 0, 0, 0, 0, 0, 79507, 79511, - 79516, 79521, 79525, 79529, 79533, 79537, 79541, 79545, 79549, 79553, 0, - 0, 0, 0, 0, 0, 79557, 79562, 79566, 79570, 79574, 79578, 79582, 79586, - 79590, 79594, 79598, 79602, 79606, 79610, 79614, 79618, 79622, 79627, - 79632, 79638, 79644, 79651, 79656, 79661, 79667, 79671, 79676, 79679, - 79682, 79686, 79691, 79695, 79700, 79707, 79713, 79719, 79725, 79731, - 79737, 79743, 79749, 79755, 79761, 79767, 79774, 79781, 79788, 79794, - 79801, 79808, 79815, 79822, 79829, 79835, 79841, 79848, 79854, 79861, - 79868, 79874, 79880, 79886, 79893, 79900, 79906, 79913, 79920, 79926, - 79933, 79939, 79946, 79953, 79959, 79965, 79972, 79978, 79985, 79992, - 80001, 80008, 80015, 80019, 80024, 80029, 80034, 80039, 80043, 80047, - 80052, 80056, 80061, 80066, 80071, 80075, 80079, 80083, 80087, 80092, - 80096, 80101, 80106, 80111, 80116, 80120, 80125, 80130, 80135, 80141, - 80146, 80152, 80158, 80164, 80170, 80176, 80181, 80187, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 80191, 80196, 80200, 80204, 80208, 80212, 80216, 80220, - 80224, 80228, 80232, 80236, 80240, 80244, 80248, 80252, 80256, 80260, - 80264, 80268, 80272, 80276, 80280, 80284, 80288, 80292, 80296, 80300, - 80304, 80308, 0, 0, 0, 80312, 80317, 80322, 80327, 80332, 80336, 80343, - 80347, 80352, 80356, 80363, 80370, 80379, 80383, 80388, 80392, 80396, - 80403, 80410, 80415, 80422, 80427, 80432, 80439, 80444, 80451, 80458, - 80463, 80468, 80475, 80480, 80487, 80494, 80499, 80506, 80511, 80518, - 80522, 80526, 80533, 80538, 80545, 80549, 80553, 80557, 80564, 80568, - 80573, 80580, 80587, 80591, 80595, 80602, 80608, 80614, 80620, 80628, - 80634, 80642, 80648, 80656, 80662, 80668, 80674, 80680, 80684, 80689, - 80694, 80700, 80706, 80712, 80718, 80724, 80730, 80736, 80742, 80750, - 80756, 0, 80763, 80767, 80772, 80776, 80780, 80784, 80788, 80792, 80796, - 80800, 80804, 0, 0, 0, 0, 80808, 80816, 80822, 80828, 80834, 80840, - 80846, 80852, 80858, 80865, 80872, 80879, 80886, 80893, 80900, 80907, - 80914, 80921, 80928, 80935, 80941, 80947, 80953, 80959, 80965, 80971, - 80977, 80983, 80989, 80996, 81003, 81010, 81017, 0, 81024, 81028, 81032, - 81036, 81040, 81045, 81049, 81053, 81058, 81063, 81068, 81073, 81078, - 81083, 81088, 81093, 81098, 81103, 81108, 81113, 81118, 81123, 81128, - 81133, 81138, 81142, 81147, 81151, 81156, 81161, 81166, 81171, 81176, - 81180, 81185, 81189, 81193, 81197, 81202, 81207, 81211, 81215, 81221, - 81226, 81232, 81238, 81243, 81249, 81254, 81260, 81266, 81272, 81277, - 81282, 81287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81293, 81299, 81305, 81311, - 81318, 81324, 81330, 81336, 81342, 81348, 81353, 81358, 81364, 81371, 0, - 0, 81378, 81383, 81387, 81391, 81395, 81399, 81403, 81407, 81411, 81415, - 0, 0, 81419, 81425, 81431, 81438, 81446, 81452, 81458, 81464, 81470, - 81476, 81482, 81488, 81494, 81500, 81506, 81512, 81517, 81522, 81527, - 81533, 81539, 81546, 81552, 81558, 81563, 81570, 81577, 81584, 81590, - 81595, 81600, 81605, 81613, 81620, 81627, 81635, 81643, 81650, 81657, - 81664, 81671, 81678, 81685, 81692, 81699, 81706, 81713, 81720, 81727, - 81734, 81741, 81748, 81755, 81762, 81769, 81776, 81783, 81789, 81795, - 81802, 81809, 81816, 81823, 81830, 81837, 81844, 81851, 81858, 81865, - 81872, 81879, 81886, 81893, 81900, 81907, 81914, 81921, 81928, 81935, - 81942, 81949, 81956, 81963, 81969, 81975, 81982, 81988, 81993, 81999, - 82004, 82009, 82014, 82021, 82027, 82033, 82039, 82045, 82051, 82057, - 82063, 82071, 82079, 82087, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 82095, 82101, 82107, 82113, 82121, 82129, - 82135, 82141, 82148, 82155, 82162, 82169, 82176, 82183, 82190, 82197, - 82204, 82212, 82220, 82228, 82236, 82244, 82250, 82258, 82264, 82272, - 82281, 82289, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82295, 82299, 82303, 82307, - 82311, 82315, 0, 0, 82319, 82323, 82327, 82331, 82335, 82339, 0, 0, - 82343, 82347, 82351, 82355, 82359, 82363, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82367, 82371, 82375, 82379, 82383, 82387, 82391, 0, 82395, 82399, 82403, - 82407, 82411, 82415, 82419, 0, 82423, 82430, 82436, 82442, 82448, 82456, - 82463, 82472, 82484, 82494, 82503, 82511, 82519, 82527, 82533, 82541, - 82549, 82556, 82564, 82574, 82581, 82590, 82596, 82606, 82615, 82620, - 82628, 82637, 82642, 82651, 82658, 82668, 82680, 82685, 82691, 82698, - 82703, 82713, 82723, 82733, 82743, 82758, 82771, 82782, 82790, 82795, - 82807, 82816, 82823, 82830, 82836, 82843, 82848, 82855, 82861, 82872, - 82883, 82893, 82899, 82904, 0, 0, 0, 0, 82909, 82913, 82917, 82921, - 82925, 82929, 82934, 82939, 82943, 82948, 82953, 82958, 82963, 82968, - 82972, 82977, 82982, 82987, 82992, 82997, 83001, 83006, 83011, 83016, - 83021, 83026, 83030, 83035, 83040, 83045, 83050, 83054, 83059, 83064, - 83069, 83074, 83079, 83084, 83089, 83094, 83099, 83104, 83109, 83114, - 83119, 83123, 83128, 83133, 83138, 83143, 83148, 83153, 83158, 83163, - 83168, 83173, 83178, 83183, 83188, 83193, 83198, 83203, 83208, 83213, - 83218, 83223, 83228, 83233, 83238, 83243, 83248, 83253, 83258, 83263, - 83268, 83273, 83278, 83283, 83288, 83293, 83297, 83304, 83311, 83318, - 83325, 83331, 83337, 83344, 83351, 83358, 83365, 83372, 83379, 83386, - 83393, 83400, 83406, 83413, 83420, 83427, 83434, 83441, 83448, 83455, - 83462, 83469, 83476, 83483, 83492, 83501, 83510, 83519, 83528, 83537, - 83546, 83555, 83563, 83571, 83579, 83587, 83595, 83603, 83611, 83619, - 83625, 83633, 0, 0, 83641, 83648, 83654, 83660, 83666, 83672, 83678, - 83684, 83690, 83696, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83702, 83707, 83712, 83717, 83722, - 83727, 83732, 83737, 83742, 83747, 83752, 83757, 83762, 83767, 83772, - 83777, 83782, 83787, 83792, 83797, 83802, 83807, 83812, 0, 0, 0, 0, - 83817, 83821, 83825, 83829, 83833, 83837, 83841, 83845, 83849, 83853, - 83857, 83861, 83865, 83869, 83873, 83877, 83881, 83885, 83889, 83893, - 83897, 83901, 83905, 83909, 83913, 83917, 83921, 83925, 83929, 83933, - 83937, 83941, 83945, 83949, 83953, 83957, 83961, 83965, 83969, 83973, - 83977, 83981, 83985, 83989, 83993, 83997, 84001, 84005, 84009, 0, 0, 0, - 0, 84013, 84017, 84021, 84025, 84029, 84033, 84037, 84041, 84045, 84049, - 84053, 84057, 84061, 84065, 84069, 84073, 84077, 84081, 84085, 84089, - 84093, 84097, 84101, 84105, 84109, 84113, 84117, 84121, 84125, 84129, - 84133, 84137, 84141, 84145, 84149, 84153, 84157, 84161, 84165, 84169, - 84173, 84177, 84181, 84185, 84189, 84193, 84197, 84201, 84205, 84209, - 84213, 84217, 84221, 84225, 84229, 84233, 84237, 84241, 84245, 84249, - 84253, 84257, 84261, 84265, 84269, 84273, 84277, 84281, 84285, 84289, - 84293, 84297, 84301, 84305, 84309, 84313, 84317, 84321, 84325, 84329, - 84333, 84337, 84341, 84345, 84349, 84353, 84357, 84361, 84365, 84369, - 84373, 84377, 84381, 84385, 84389, 84393, 84397, 84401, 84405, 84409, - 84413, 84417, 84421, 84425, 84429, 84433, 84437, 84441, 84445, 84449, - 84453, 84457, 84461, 84465, 84469, 84473, 84477, 84481, 84485, 84489, - 84493, 84497, 84501, 84505, 84509, 84513, 84517, 84521, 84525, 84529, - 84533, 84537, 84541, 84545, 84549, 84553, 84557, 84561, 84565, 84569, - 84573, 84577, 84581, 84585, 84589, 84593, 84597, 84601, 84605, 84609, - 84613, 84617, 84621, 84625, 84629, 84633, 84637, 84641, 84645, 84649, - 84653, 84657, 84661, 84665, 84669, 84673, 84677, 84681, 84685, 84689, - 84693, 84697, 84701, 84705, 84709, 84713, 84717, 84721, 84725, 84729, - 84733, 84737, 84741, 84745, 84749, 84753, 84757, 84761, 84765, 84769, - 84773, 84777, 84781, 84785, 84789, 84793, 84797, 84801, 84805, 84809, - 84813, 84817, 84821, 84825, 84829, 84833, 84837, 84841, 84845, 84849, - 84853, 84857, 84861, 84865, 84869, 84873, 84877, 84881, 84885, 84889, - 84893, 84897, 84901, 84905, 84909, 84913, 84917, 84921, 84925, 84929, - 84933, 84937, 84941, 84945, 84949, 84953, 84957, 84961, 84965, 84969, - 84973, 84977, 84981, 84985, 84989, 84993, 84997, 85001, 85005, 85009, - 85013, 85017, 85021, 85025, 85029, 85033, 85037, 85041, 85045, 85049, - 85053, 85057, 85061, 85065, 85069, 85073, 85077, 85081, 85085, 85089, - 85093, 85097, 85101, 85105, 85109, 85113, 85117, 85121, 85125, 85129, - 85133, 85137, 85141, 85145, 85149, 85153, 85157, 85161, 85165, 85169, - 85173, 85177, 85181, 85185, 85189, 85193, 85197, 85201, 85205, 85209, - 85213, 85217, 85221, 85225, 85229, 85233, 85237, 85241, 85245, 85249, - 85253, 85257, 85261, 85265, 85269, 85273, 85277, 85281, 85285, 85289, - 85293, 85297, 85301, 85305, 85309, 85313, 85317, 85321, 85325, 85329, - 85333, 85337, 85341, 85345, 85349, 85353, 85357, 85361, 85365, 85369, - 85373, 85377, 85381, 85385, 85389, 85393, 85397, 85401, 85405, 85409, - 85413, 85417, 85421, 85425, 85429, 85433, 85437, 85441, 85445, 85449, - 85453, 85457, 85461, 85465, 85469, 85473, 0, 0, 85477, 85481, 85485, - 85489, 85493, 85497, 85501, 85505, 85509, 85513, 85517, 85521, 85525, - 85529, 85533, 85537, 85541, 85545, 85549, 85553, 85557, 85561, 85565, - 85569, 85573, 85577, 85581, 85585, 85589, 85593, 85597, 85601, 85605, - 85609, 85613, 85617, 85621, 85625, 85629, 85633, 85637, 85641, 85645, - 85649, 85653, 85657, 85661, 85665, 85669, 85673, 85677, 85681, 85685, - 85689, 85693, 85697, 85701, 85705, 85709, 85713, 85717, 85721, 85725, - 85729, 85733, 85737, 85741, 85745, 85749, 85753, 85757, 85761, 85765, - 85769, 85773, 85777, 85781, 85785, 85789, 85793, 85797, 85801, 85805, - 85809, 85813, 85817, 85821, 85825, 85829, 85833, 85837, 85841, 85845, - 85849, 85853, 85857, 85861, 85865, 85869, 85873, 85877, 85881, 85885, - 85889, 85893, 85897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85901, - 85906, 85911, 85916, 85921, 85926, 85934, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 85939, 85947, 85955, 85963, 85971, 0, 0, 0, 0, 0, 85979, 85986, - 85993, 86003, 86009, 86015, 86021, 86027, 86033, 86039, 86046, 86052, - 86058, 86064, 86073, 86082, 86094, 86106, 86112, 86118, 86124, 86131, - 86138, 86145, 86152, 86159, 0, 86166, 86173, 86180, 86188, 86195, 0, - 86202, 0, 86209, 86216, 0, 86223, 86231, 0, 86238, 86245, 86252, 86259, - 86266, 86273, 86280, 86287, 86294, 86301, 86306, 86313, 86320, 86326, - 86332, 86338, 86345, 86351, 86357, 86363, 86370, 86376, 86382, 86388, - 86395, 86401, 86407, 86413, 86420, 86426, 86432, 86438, 86445, 86451, - 86457, 86463, 86470, 86476, 86482, 86488, 86495, 86501, 86507, 86513, - 86520, 86526, 86532, 86538, 86545, 86551, 86557, 86563, 86570, 86576, - 86582, 86588, 86595, 86601, 86607, 86613, 86620, 86626, 86632, 86638, - 86644, 86650, 86656, 86662, 86668, 86674, 86680, 86686, 86692, 86698, - 86704, 86710, 86717, 86723, 86729, 86735, 86742, 86748, 86754, 86760, - 86767, 86773, 86779, 86785, 86792, 86800, 86808, 86814, 86820, 86826, - 86833, 86842, 86851, 86859, 86867, 86875, 86884, 86892, 86900, 86908, - 86917, 86924, 86931, 86942, 86953, 86957, 86961, 86966, 86971, 86976, - 86981, 86990, 86999, 87005, 87011, 87018, 87025, 87032, 87036, 87042, - 87048, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87053, 87059, - 87065, 87071, 87078, 87083, 87088, 87094, 87100, 87106, 87112, 87121, - 87127, 87133, 87141, 87149, 87157, 87165, 87171, 87177, 87183, 87190, - 87203, 87217, 87228, 87239, 87251, 87263, 87275, 87287, 87298, 87309, - 87321, 87333, 87345, 87357, 87369, 87381, 87393, 87410, 87427, 87444, - 87451, 87458, 87465, 87473, 87485, 87496, 87507, 87520, 87531, 87540, - 87548, 87557, 87565, 87575, 87583, 87592, 87600, 87609, 87617, 87627, - 87635, 87644, 87652, 87662, 87670, 87678, 87686, 87694, 87701, 87710, - 87718, 87726, 87735, 87743, 87752, 87760, 87768, 87776, 87785, 87793, - 87802, 87810, 87818, 87826, 87834, 87843, 87851, 87860, 87868, 87877, - 87885, 87894, 87902, 87912, 87920, 87928, 87936, 87946, 87954, 87962, - 87971, 87979, 87988, 87997, 88005, 88015, 88023, 88032, 88040, 88049, - 88057, 88067, 88075, 88083, 88090, 88098, 88105, 88114, 88121, 88130, - 88138, 88147, 88155, 88165, 88173, 88182, 88190, 88200, 88208, 88216, - 88223, 88231, 88238, 88247, 88254, 88264, 88274, 88285, 88294, 88303, - 88312, 88321, 88330, 88340, 88352, 88364, 88375, 88387, 88400, 88411, - 88420, 88429, 88437, 88446, 88456, 88464, 88473, 88482, 88490, 88499, - 88509, 88517, 88526, 88535, 88543, 88552, 88562, 88570, 88580, 88588, - 88598, 88606, 88614, 88623, 88631, 88641, 88649, 88657, 88667, 88675, - 88682, 88689, 88698, 88707, 88715, 88724, 88734, 88742, 88753, 88761, - 88769, 88776, 88784, 88793, 88800, 88812, 88823, 88835, 88846, 88858, - 88867, 88875, 88884, 88892, 88901, 88910, 88918, 88927, 88935, 88944, - 88952, 88960, 88968, 88976, 88983, 88992, 89000, 89009, 89017, 89026, - 89034, 89042, 89051, 89059, 89068, 89076, 89085, 89093, 89101, 89109, - 89118, 89126, 89135, 89143, 89152, 89160, 89169, 89177, 89185, 89193, - 89202, 89210, 89219, 89228, 89236, 89245, 89253, 89262, 89270, 89279, - 89287, 89294, 89302, 89309, 89318, 89326, 89335, 89343, 89352, 89361, - 89369, 89379, 89387, 89394, 89402, 89409, 89417, 89429, 89442, 89451, - 89461, 89470, 89480, 89489, 89499, 89508, 89518, 89527, 89537, 89547, - 89556, 89565, 89574, 89584, 89592, 89601, 89611, 89621, 89631, 89641, - 89649, 89659, 89667, 89677, 89685, 89695, 89703, 89713, 89721, 89730, - 89737, 89747, 89755, 89765, 89773, 89783, 89791, 89801, 89809, 89818, - 89826, 89835, 89843, 89852, 89861, 89870, 89879, 89889, 89897, 89907, - 89915, 89925, 89933, 89943, 89951, 89961, 89969, 89978, 89985, 89995, - 90003, 90013, 90021, 90031, 90039, 90049, 90057, 90066, 90074, 90083, - 90091, 90100, 90109, 90118, 90127, 90136, 90144, 90153, 90161, 90170, - 90179, 90187, 90197, 90206, 90216, 90226, 90235, 90245, 90254, 90263, - 90271, 90279, 90284, 90289, 90295, 90303, 90311, 90319, 90327, 90335, - 90343, 90349, 90355, 90361, 90369, 90375, 90385, 90391, 90397, 90403, - 90414, 90425, 90436, 90446, 90457, 90468, 90478, 90489, 90499, 90509, - 90518, 90529, 90540, 90551, 90564, 90574, 90584, 90595, 90605, 90615, - 90625, 90635, 90645, 90655, 90665, 90676, 90687, 90698, 90708, 90718, - 90730, 90741, 90752, 90762, 90772, 90782, 90792, 90803, 90813, 90823, - 90835, 90845, 90855, 90867, 90878, 90889, 90899, 90909, 90919, 90929, - 90941, 90953, 90965, 90976, 90987, 90997, 91007, 91017, 91026, 91035, - 91045, 91055, 91066, 0, 0, 91076, 91087, 91098, 91108, 91118, 91130, - 91141, 91152, 91165, 91175, 91187, 91196, 91205, 91216, 91227, 91240, - 91251, 91264, 91274, 91286, 91296, 91308, 91320, 91333, 91343, 91353, - 91363, 91374, 91384, 91393, 91403, 91412, 91421, 91431, 91441, 91451, - 91461, 91471, 91481, 91492, 91502, 91513, 91523, 91534, 91545, 91555, - 91565, 91575, 91585, 91595, 91605, 91616, 91626, 91637, 0, 0, 0, 0, 0, 0, - 0, 91648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91654, 91669, 91684, 91690, 91696, - 91702, 91708, 91714, 91720, 91726, 91732, 91740, 91744, 91747, 91755, - 91763, 91771, 91774, 91777, 91780, 91783, 91786, 91789, 91792, 91795, - 91798, 91801, 91804, 91807, 91810, 91813, 91816, 91819, 91827, 91836, - 91847, 91855, 91863, 91872, 91881, 91893, 91905, 0, 0, 0, 0, 0, 0, 91915, - 91920, 91925, 91932, 91939, 91945, 91951, 91956, 91961, 91966, 91972, - 91978, 91984, 91990, 91996, 92003, 92010, 92020, 92030, 92040, 92049, - 92060, 92069, 92078, 92089, 92100, 92113, 92126, 92138, 92150, 92162, - 92174, 92185, 92196, 92207, 92218, 92230, 92242, 92246, 92251, 92261, - 92271, 92275, 92279, 92283, 92288, 92293, 92298, 92303, 92306, 92310, 0, - 92315, 92318, 92321, 92325, 92329, 92334, 92338, 92342, 92348, 92354, - 92362, 92370, 92373, 92376, 92379, 92382, 92385, 92389, 92393, 0, 92397, - 92402, 92406, 92410, 0, 0, 0, 0, 92415, 92420, 92427, 92432, 92437, 0, - 92442, 92447, 92453, 92458, 92464, 92469, 92475, 92480, 92486, 92491, - 92497, 92503, 92512, 92521, 92530, 92539, 92549, 92559, 92569, 92579, - 92588, 92597, 92606, 92616, 92621, 92626, 92632, 92638, 92644, 92651, - 92659, 92667, 92673, 92679, 92685, 92692, 92698, 92704, 92710, 92717, - 92723, 92729, 92735, 92742, 92747, 92752, 92757, 92763, 92769, 92775, - 92781, 92788, 92794, 92800, 92806, 92812, 92818, 92824, 92830, 92836, - 92842, 92848, 92854, 92861, 92867, 92873, 92879, 92886, 92892, 92898, - 92904, 92911, 92917, 92923, 92929, 92936, 92942, 92948, 92954, 92961, - 92967, 92973, 92979, 92986, 92992, 92998, 93004, 93011, 93017, 93023, - 93029, 93036, 93042, 93048, 93054, 93061, 93067, 93073, 93079, 93086, - 93092, 93098, 93104, 93111, 93117, 93123, 93129, 93136, 93141, 93146, - 93151, 93157, 93163, 93169, 93175, 93182, 93188, 93194, 93200, 93207, - 93213, 93219, 93226, 93233, 93238, 93243, 93248, 93254, 93266, 93278, - 93290, 93302, 93315, 93328, 93336, 0, 0, 93344, 0, 93352, 93357, 93362, - 93366, 93371, 93376, 93380, 93384, 93389, 93394, 93398, 93402, 93406, - 93410, 93416, 93420, 93425, 93429, 93433, 93437, 93441, 93445, 93449, - 93453, 93457, 93461, 93465, 93469, 93474, 93479, 93484, 93489, 93495, - 93501, 93508, 93515, 93522, 93528, 93535, 93542, 93549, 93555, 93562, - 93569, 93575, 93582, 93589, 93595, 93602, 93609, 93615, 93622, 93629, - 93635, 93642, 93649, 93656, 93663, 93670, 93676, 93682, 93688, 93694, - 93699, 93705, 93711, 93718, 93725, 93732, 93738, 93745, 93752, 93759, - 93765, 93772, 93779, 93785, 93792, 93799, 93805, 93812, 93819, 93825, - 93832, 93839, 93845, 93852, 93859, 93866, 93873, 93880, 93887, 93892, - 93899, 93903, 93909, 93915, 93921, 93927, 93933, 93937, 93942, 93947, - 93952, 93957, 93962, 93967, 93972, 93977, 93983, 93989, 93995, 94003, - 94007, 94011, 94015, 94019, 94023, 94027, 94032, 94037, 94042, 94047, - 94051, 94056, 94061, 94066, 94071, 94076, 94081, 94086, 94091, 94095, - 94099, 94104, 94109, 94114, 94119, 94123, 94128, 94133, 94138, 94143, - 94147, 94152, 94157, 94162, 94167, 94171, 94176, 94181, 94185, 94190, - 94195, 94200, 94205, 94210, 94215, 94222, 94229, 94233, 94238, 94243, - 94248, 94253, 94258, 94263, 94268, 94273, 94278, 94283, 94288, 94293, - 94298, 94303, 94308, 94313, 94318, 94323, 94328, 94333, 94338, 94343, - 94348, 94353, 94358, 94363, 94368, 94373, 94378, 0, 0, 0, 94383, 94387, - 94392, 94396, 94401, 94406, 0, 0, 94410, 94415, 94420, 94424, 94429, - 94434, 0, 0, 94439, 94444, 94448, 94453, 94458, 94463, 0, 0, 94468, - 94473, 94478, 0, 0, 0, 94482, 94487, 94492, 94497, 94501, 94506, 94511, - 0, 94516, 94522, 94525, 94529, 94532, 94536, 94540, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 94544, 94550, 94556, 94562, 94568, 0, 0, 94572, 94578, 94584, - 94590, 94596, 94602, 94609, 94616, 94623, 94630, 94637, 94644, 0, 94651, - 94658, 94665, 94671, 94678, 94685, 94692, 94699, 94705, 94712, 94719, - 94726, 94733, 94739, 94746, 94753, 94760, 94767, 94773, 94780, 94787, - 94794, 94801, 94808, 94815, 94822, 0, 94829, 94835, 94842, 94849, 94856, - 94863, 94869, 94876, 94883, 94890, 94897, 94904, 94911, 94918, 94924, - 94931, 94938, 94945, 94952, 0, 94959, 94966, 0, 94973, 94980, 94987, - 94994, 95001, 95008, 95015, 95022, 95029, 95036, 95043, 95050, 95057, - 95064, 95071, 0, 0, 95077, 95082, 95087, 95092, 95097, 95102, 95107, - 95112, 95117, 95122, 95127, 95132, 95137, 95142, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 95147, 95154, 95161, 95168, 95175, 95182, 95189, 95196, 95203, - 95210, 95217, 95224, 95231, 95238, 95245, 95252, 95259, 95266, 95273, - 95280, 95288, 95296, 95303, 95310, 95315, 95323, 95331, 95338, 95345, - 95350, 95357, 95362, 95367, 95374, 95379, 95384, 95389, 95397, 95402, - 95407, 95414, 95419, 95424, 95431, 95438, 95443, 95448, 95453, 95458, - 95463, 95468, 95473, 95478, 95483, 95490, 95495, 95502, 95507, 95512, - 95517, 95522, 95527, 95532, 95537, 95542, 95547, 95552, 95557, 95564, - 95571, 95578, 95585, 95591, 95596, 95603, 95608, 95613, 95622, 95629, - 95638, 95645, 95650, 95655, 95663, 95668, 95673, 95678, 95683, 95688, - 95695, 95700, 95705, 95710, 95715, 95720, 95727, 95734, 95741, 95748, - 95755, 95762, 95769, 95776, 95783, 95790, 95797, 95804, 95811, 95818, - 95825, 95832, 95839, 95846, 95853, 95860, 95867, 95874, 95881, 95888, - 95895, 95902, 95909, 95916, 0, 0, 0, 0, 0, 95923, 95931, 95939, 0, 0, 0, - 0, 95944, 95948, 95952, 95956, 95960, 95964, 95968, 95972, 95976, 95980, - 95985, 95990, 95995, 96000, 96005, 96010, 96015, 96020, 96025, 96031, - 96037, 96043, 96050, 96057, 96064, 96071, 96078, 96085, 96090, 96095, - 96100, 96106, 96112, 96118, 96124, 96130, 96136, 96142, 96148, 96154, - 96160, 96166, 96172, 96178, 96184, 0, 0, 0, 96190, 96198, 96206, 96214, - 96222, 96230, 96240, 96250, 96258, 96266, 96274, 96282, 96290, 96296, - 96303, 96312, 96320, 96328, 96337, 96346, 96355, 96365, 96376, 96386, - 96397, 96406, 96415, 96424, 96434, 96445, 96455, 96466, 96477, 96486, - 96494, 96500, 96506, 96512, 96518, 96526, 96534, 96540, 96547, 96557, - 96564, 96571, 96578, 96585, 96592, 96602, 96609, 96616, 96624, 96632, - 96641, 96650, 96659, 96668, 96677, 96684, 96692, 96701, 96710, 96714, - 96721, 96726, 96731, 96735, 96739, 96743, 96747, 96752, 96757, 96763, - 96769, 96773, 96779, 96783, 96787, 96791, 96795, 96799, 96803, 96809, - 96813, 96818, 96822, 96826, 0, 96829, 96834, 96839, 96844, 96849, 96856, - 96861, 96866, 96871, 96876, 96881, 96886, 96891, 0, 0, 0, 96894, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96900, 96907, - 96916, 96925, 96932, 96939, 96946, 96953, 96960, 96967, 96973, 96980, - 96987, 96994, 97001, 97008, 97015, 97022, 97029, 97038, 97045, 97052, - 97059, 97066, 97073, 97080, 97087, 97094, 97103, 97110, 97117, 97124, - 97131, 97138, 97145, 97154, 97161, 97168, 97175, 97182, 97191, 97198, - 97205, 97212, 97220, 97229, 0, 0, 97238, 97242, 97246, 97251, 97256, - 97261, 97266, 97270, 97275, 97280, 97285, 97290, 97295, 97300, 97304, - 97309, 97314, 97319, 97324, 97328, 97333, 97338, 97342, 97347, 97352, - 97357, 97362, 97367, 97372, 0, 0, 0, 97377, 97381, 97386, 97391, 97395, - 97400, 97404, 97409, 97414, 97419, 97424, 97429, 97433, 97438, 97443, - 97448, 97453, 97458, 97463, 97467, 97472, 97477, 97482, 97487, 97492, - 97497, 97501, 97505, 97510, 97515, 97520, 97525, 97530, 97535, 97540, - 97545, 97550, 97555, 97560, 97565, 97570, 97575, 97580, 97585, 97590, - 97595, 97600, 97605, 97610, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 97615, 97621, 97626, 97631, 97636, 97641, 97646, 97651, 97656, 97661, - 97666, 97672, 97678, 97684, 97690, 97696, 97702, 97708, 97714, 97720, - 97727, 97734, 97741, 97749, 97757, 97765, 97773, 97781, 0, 0, 0, 0, - 97789, 97793, 97798, 97803, 97808, 97812, 97817, 97822, 97827, 97832, - 97836, 97840, 97845, 97850, 97855, 97860, 97864, 97869, 97874, 97879, - 97884, 97889, 97894, 97898, 97903, 97908, 97913, 97918, 97923, 97928, - 97933, 97938, 97943, 97948, 97953, 97959, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 97965, 97970, 97977, 97984, 97989, 97994, 97999, 98004, 98009, 98014, - 98019, 98024, 98029, 98034, 98039, 98044, 98049, 98054, 98059, 98064, - 98069, 98074, 98079, 98084, 98089, 98094, 98099, 98104, 98109, 98114, 0, - 0, 0, 0, 0, 98121, 98127, 98133, 98139, 98145, 98150, 98156, 98162, - 98168, 98174, 98179, 98185, 98191, 98197, 98203, 98209, 98215, 98221, - 98227, 98233, 98238, 98244, 98250, 98256, 98262, 98268, 98273, 98279, - 98285, 98290, 98296, 98302, 98308, 98314, 98320, 98326, 98332, 98337, - 98343, 98350, 98357, 98364, 98371, 0, 0, 0, 0, 0, 98378, 98383, 98388, - 98393, 98398, 98403, 98408, 98413, 98418, 98423, 98428, 98433, 98438, - 98443, 98448, 98453, 98458, 98463, 98468, 98473, 98478, 98483, 98488, - 98493, 98498, 98503, 98508, 98512, 98516, 98520, 0, 98525, 98531, 98536, - 98541, 98546, 98551, 98557, 98563, 98569, 98575, 98581, 98587, 98593, - 98599, 98605, 98611, 98617, 98623, 98629, 98634, 98640, 98646, 98651, - 98657, 98662, 98668, 98674, 98679, 98685, 98691, 98696, 98702, 98707, - 98712, 98718, 98724, 98730, 0, 0, 0, 0, 98735, 98741, 98747, 98753, - 98759, 98765, 98771, 98777, 98783, 98790, 98795, 98800, 98806, 98812, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98818, 98824, 98830, - 98836, 98843, 98849, 98856, 98863, 98870, 98877, 98885, 98892, 98900, - 98906, 98912, 98918, 98924, 98930, 98936, 98942, 98948, 98954, 98960, - 98966, 98972, 98978, 98984, 98990, 98996, 99002, 99008, 99014, 99020, - 99026, 99032, 99038, 99044, 99050, 99056, 99062, 99068, 99074, 99080, - 99086, 99093, 99099, 99106, 99113, 99120, 99127, 99135, 99142, 99150, - 99156, 99162, 99168, 99174, 99180, 99186, 99192, 99198, 99204, 99210, - 99216, 99222, 99228, 99234, 99240, 99246, 99252, 99258, 99264, 99270, - 99276, 99282, 99288, 99294, 99300, 99306, 99312, 99318, 99323, 99328, - 99333, 99338, 99343, 99348, 99353, 99358, 99363, 99368, 99373, 99378, - 99383, 99388, 99393, 99398, 99403, 99408, 99413, 99418, 99423, 99428, - 99433, 99438, 99443, 99448, 99453, 99458, 99463, 99468, 99473, 99478, - 99483, 99488, 99493, 99498, 99503, 99508, 99513, 99518, 99523, 99528, - 99533, 99538, 99543, 99548, 99553, 99558, 99563, 99568, 99573, 99578, - 99583, 99588, 99593, 99597, 99601, 99606, 99611, 99616, 99621, 99626, - 99631, 99636, 99641, 99646, 99651, 99656, 99660, 99664, 99668, 99672, - 99676, 99680, 99684, 99689, 99694, 0, 0, 99699, 99704, 99708, 99712, - 99716, 99720, 99724, 99728, 99732, 99736, 0, 0, 0, 0, 0, 0, 99740, 99745, - 99751, 99757, 99763, 99769, 99775, 99781, 99786, 99792, 99797, 99803, - 99808, 99813, 99819, 99825, 99830, 99835, 99840, 99845, 99851, 99856, - 99862, 99867, 99873, 99879, 99885, 99891, 99897, 99903, 99909, 99914, - 99920, 99926, 99932, 99938, 0, 0, 0, 0, 99944, 99949, 99955, 99961, - 99967, 99973, 99979, 99985, 99990, 99996, 100001, 100007, 100012, 100017, - 100023, 100029, 100034, 100039, 100044, 100049, 100055, 100060, 100066, - 100071, 100077, 100083, 100089, 100095, 100101, 100107, 100113, 100118, - 100124, 100130, 100136, 100142, 0, 0, 0, 0, 100148, 100152, 100157, - 100162, 100167, 100172, 100177, 100182, 100187, 100191, 100196, 100201, - 100206, 100211, 100215, 100220, 100225, 100230, 100235, 100240, 100245, - 100249, 100254, 100258, 100263, 100268, 100273, 100278, 100283, 100288, - 100293, 100298, 100302, 100307, 100312, 100317, 100322, 100327, 100332, - 100337, 0, 0, 0, 0, 0, 0, 0, 0, 100342, 100349, 100356, 100363, 100370, - 100377, 100384, 100391, 100398, 100405, 100412, 100419, 100426, 100433, - 100440, 100447, 100454, 100461, 100468, 100475, 100482, 100489, 100496, - 100503, 100510, 100517, 100524, 100531, 100538, 100545, 100552, 100559, - 100566, 100573, 100580, 100587, 100594, 100601, 100608, 100615, 100622, - 100629, 100636, 100643, 100650, 100657, 100664, 100671, 100678, 100685, - 100692, 100699, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100706, 100713, 100718, - 100724, 100730, 100736, 100742, 100748, 100754, 100760, 100765, 100771, - 0, 100777, 100782, 100788, 100793, 100799, 100805, 100810, 100815, - 100821, 100827, 100833, 100839, 100844, 100850, 100856, 0, 100862, - 100868, 100874, 100880, 100886, 100891, 100897, 0, 100903, 100909, 0, - 100915, 100920, 100926, 100932, 100938, 100944, 100950, 100956, 100962, - 100967, 100973, 0, 100979, 100984, 100990, 100995, 101001, 101007, - 101012, 101017, 101023, 101029, 101035, 101041, 101046, 101052, 101058, - 0, 101064, 101070, 101076, 101082, 101088, 101093, 101099, 0, 101105, - 101111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101117, - 101122, 101127, 101132, 101137, 101142, 101147, 101152, 101157, 101162, - 101167, 101172, 101177, 101182, 101187, 101192, 101197, 101202, 101207, - 101212, 101217, 101222, 101227, 101232, 101237, 101242, 101247, 101252, - 101257, 101262, 101267, 101272, 101277, 101282, 101287, 101292, 101297, - 101302, 101307, 101312, 101317, 101322, 101327, 101332, 101337, 101342, - 101347, 101352, 101357, 101362, 101367, 101372, 101377, 101382, 101387, - 101392, 101397, 101402, 101407, 101412, 101417, 101422, 101427, 101432, - 101437, 101442, 101447, 101452, 101457, 101462, 101467, 101472, 101477, - 101482, 101487, 101492, 101497, 101502, 101507, 101512, 101517, 101522, - 101527, 101532, 101537, 101542, 101547, 101552, 101557, 101562, 101567, - 101572, 101577, 101582, 101587, 101592, 101597, 101602, 101607, 101612, - 101617, 101622, 101627, 101632, 101637, 101642, 101647, 101652, 101657, - 101662, 101667, 101672, 101677, 101682, 101687, 101692, 101697, 101702, - 101707, 101712, 101717, 101722, 101727, 101732, 101737, 101742, 101747, - 101752, 101757, 101762, 101767, 101772, 101777, 101782, 101787, 101792, - 101797, 101802, 101807, 101812, 101817, 101822, 101827, 101832, 101837, - 101842, 101847, 101852, 101857, 101862, 101867, 101872, 101877, 101882, - 101887, 101892, 101897, 101902, 101907, 101912, 101917, 101922, 101927, - 101932, 101937, 101942, 101947, 101952, 101957, 101962, 101967, 101972, - 101977, 101982, 101987, 101992, 101997, 102002, 102007, 102012, 102017, - 102022, 102027, 102032, 102037, 102042, 102047, 102052, 102057, 102062, - 102067, 102072, 102077, 102082, 102087, 102092, 102097, 102102, 102107, - 102112, 102117, 102122, 102127, 102132, 102137, 102142, 102147, 102152, - 102157, 102162, 102167, 102172, 102177, 102182, 102187, 102192, 102197, - 102202, 102207, 102212, 102217, 102222, 102227, 102232, 102237, 102242, - 102247, 102252, 102257, 102262, 102267, 102272, 102277, 102282, 102287, - 102292, 102297, 102302, 102307, 102312, 102317, 102322, 102327, 102332, - 102337, 102342, 102347, 102352, 102357, 102362, 102367, 102372, 102377, - 102382, 102387, 102392, 102397, 102402, 102407, 102412, 102417, 102422, - 102427, 102432, 102437, 102442, 102447, 102452, 102457, 102462, 102467, - 102472, 102477, 102482, 102487, 102492, 102497, 102502, 102507, 102512, - 102517, 102522, 102527, 102532, 102537, 102542, 102547, 102552, 102557, - 102562, 102567, 102572, 102577, 102582, 102587, 102592, 102597, 102602, - 102607, 102612, 102617, 102622, 102627, 102632, 102637, 102642, 102647, - 102652, 102657, 102662, 102667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102672, - 102678, 102685, 102692, 102698, 102705, 102712, 102719, 102726, 102732, - 102739, 102746, 102753, 102760, 102767, 102774, 102781, 102788, 102795, - 102802, 102809, 102816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102823, 102828, - 102833, 102838, 102843, 102848, 102853, 102858, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102863, 102869, 102877, - 102886, 102891, 102897, 0, 102903, 102910, 102921, 102931, 102938, - 102946, 102953, 102964, 102970, 102980, 102987, 102994, 103000, 103007, - 103015, 103022, 103028, 103035, 103047, 103054, 103061, 103069, 103078, - 103091, 103096, 103105, 103111, 103120, 103126, 103132, 103139, 103144, - 103154, 103168, 103176, 103184, 103189, 103199, 103206, 103217, 103224, - 103233, 0, 103241, 103247, 103255, 103265, 103271, 103277, 103283, - 103289, 103299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 103307, 103311, 103315, 103319, 103323, 103327, 0, 0, 103332, 0, - 103337, 103341, 103346, 103351, 103356, 103361, 103365, 103370, 103375, - 103380, 103385, 103389, 103394, 103399, 103404, 103409, 103413, 103418, - 103423, 103428, 103433, 103437, 103442, 103447, 103452, 103457, 103461, - 103466, 103471, 103476, 103481, 103485, 103490, 103495, 103500, 103505, - 103510, 103515, 103520, 103524, 103529, 103534, 103539, 103544, 0, - 103549, 103554, 0, 0, 0, 103559, 0, 0, 103564, 103569, 103576, 103583, - 103590, 103597, 103604, 103611, 103618, 103625, 103632, 103639, 103646, - 103653, 103660, 103667, 103674, 103681, 103688, 103695, 103702, 103709, - 103716, 0, 103723, 103730, 103736, 103742, 103748, 103755, 103762, - 103770, 103777, 103785, 103790, 103795, 103800, 103805, 103810, 103815, - 103820, 103825, 103830, 103835, 103840, 103845, 103850, 103856, 103861, - 103866, 103871, 103876, 103881, 103886, 103891, 103896, 103901, 103907, - 103913, 103917, 103921, 103925, 103929, 103933, 103938, 103943, 103949, - 103954, 103960, 103965, 103970, 103975, 103981, 103986, 103991, 103996, - 104001, 104006, 104012, 104017, 104023, 104028, 104034, 104039, 104045, - 104050, 104056, 104061, 104066, 104071, 104076, 104081, 104086, 104091, - 104097, 104102, 0, 0, 0, 0, 0, 0, 0, 0, 104107, 104111, 104115, 104119, - 104123, 104129, 104133, 104138, 104143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104149, 104154, 104159, 104164, - 104169, 104174, 104179, 104184, 104189, 104194, 104199, 104204, 104209, - 104214, 104219, 104224, 104229, 104234, 104239, 0, 104244, 104249, 0, 0, - 0, 0, 0, 104254, 104258, 104262, 104267, 104272, 104278, 104283, 104288, - 104293, 104298, 104303, 104308, 104313, 104318, 104323, 104328, 104333, - 104338, 104343, 104348, 104353, 104358, 104363, 104368, 104373, 104378, - 104383, 104388, 104392, 104397, 104402, 104408, 104412, 0, 0, 0, 104416, - 104422, 104426, 104431, 104436, 104441, 104445, 104450, 104454, 104459, - 104464, 104468, 104473, 104478, 104482, 104486, 104491, 104496, 104500, - 104505, 104510, 104515, 104520, 104525, 104530, 104535, 104540, 0, 0, 0, - 0, 0, 104545, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104550, - 104555, 104560, 104565, 104570, 104575, 104581, 104587, 104593, 104598, - 104603, 104608, 104614, 104620, 104626, 104631, 104637, 104642, 104648, - 104654, 104659, 104665, 104671, 104676, 104682, 104688, 104694, 104700, - 104706, 104711, 104717, 104723, 104729, 104734, 104739, 104744, 104749, - 104754, 104760, 104766, 104771, 104776, 104781, 104787, 104792, 104797, - 104803, 104809, 104814, 104821, 104827, 104832, 104838, 104844, 104850, - 104855, 0, 0, 0, 0, 104861, 104870, 104878, 104885, 104892, 104897, - 104902, 104907, 104912, 104917, 104922, 104927, 104932, 104937, 104943, - 104949, 104955, 104961, 104967, 104973, 0, 0, 104979, 104986, 104993, - 105000, 105008, 105016, 105024, 105032, 105040, 105048, 105054, 105060, - 105066, 105073, 105080, 105087, 105094, 105101, 105108, 105115, 105122, - 105129, 105136, 105143, 105150, 105157, 105164, 105171, 105179, 105187, - 105195, 105204, 105213, 105222, 105231, 105240, 105249, 105257, 105265, - 105273, 105282, 105291, 105300, 105309, 105318, 105327, 105336, 105340, - 105345, 105350, 0, 105356, 105361, 0, 0, 0, 0, 0, 105366, 105372, 105379, - 105384, 105389, 105393, 105398, 105403, 0, 105408, 105413, 105418, 0, - 105423, 105428, 105433, 105438, 105443, 105448, 105453, 105458, 105463, - 105468, 105473, 105477, 105481, 105486, 105491, 105496, 105500, 105504, - 105508, 105512, 105517, 105522, 105527, 105531, 105536, 105540, 105545, - 105550, 105555, 0, 0, 105560, 105566, 105571, 0, 0, 0, 0, 105576, 105580, - 105584, 105588, 105592, 105596, 105601, 105606, 105612, 105617, 0, 0, 0, - 0, 0, 0, 0, 105624, 105630, 105637, 105643, 105650, 105656, 105662, - 105668, 105675, 0, 0, 0, 0, 0, 0, 0, 105681, 105689, 105697, 105705, - 105713, 105721, 105729, 105737, 105745, 105753, 105761, 105769, 105777, - 105785, 105793, 105801, 105809, 105817, 105825, 105833, 105841, 105849, - 105857, 105865, 105873, 105881, 105889, 105897, 105905, 105913, 105920, - 105928, 105936, 105943, 105950, 105957, 105964, 105971, 105978, 105985, - 105992, 105999, 106006, 106013, 106020, 106027, 106034, 106041, 106048, - 106055, 106062, 106069, 106076, 106083, 106090, 106097, 106104, 106111, - 106118, 106125, 106132, 106139, 106145, 106152, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 106159, 106164, 106169, 106174, 106179, 106184, 106189, 106194, 106199, - 106204, 106209, 106214, 106219, 106224, 106229, 106234, 106239, 106244, - 106249, 106254, 106259, 106264, 106269, 106274, 106279, 106284, 106289, - 106294, 106299, 106304, 106309, 106314, 106319, 106324, 106329, 106334, - 106339, 106344, 106350, 0, 0, 0, 0, 106356, 106360, 106364, 106369, - 106374, 106380, 106386, 106392, 106402, 106411, 106417, 106424, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 106432, 106436, 106441, 106446, 106451, 106456, 106461, - 106466, 106471, 106475, 106480, 106484, 106489, 106493, 106498, 106502, - 106507, 106512, 106517, 106522, 106527, 106532, 106537, 106542, 106547, - 106552, 106557, 106562, 106567, 106572, 106577, 106582, 106587, 106592, - 106597, 106602, 106607, 106612, 106617, 106622, 106627, 106632, 106637, - 106642, 106647, 106652, 106657, 106662, 106667, 106672, 106677, 106682, - 106687, 106692, 0, 0, 0, 106697, 106702, 106711, 106719, 106728, 106737, - 106748, 106759, 106766, 106773, 106780, 106787, 106794, 106801, 106808, - 106815, 106822, 106829, 106836, 106843, 106850, 106857, 106864, 106871, - 106878, 106885, 106892, 106899, 106906, 0, 0, 106913, 106919, 106925, - 106931, 106937, 106944, 106951, 106959, 106966, 106973, 106980, 106987, - 106994, 107001, 107008, 107015, 107022, 107029, 107036, 107043, 107050, - 107057, 107064, 107071, 107078, 107085, 107092, 0, 0, 0, 0, 0, 107099, - 107105, 107111, 107117, 107123, 107130, 107137, 107145, 107152, 107159, - 107166, 107173, 107180, 107187, 107194, 107201, 107208, 107215, 107222, - 107229, 107236, 107243, 107250, 107257, 107264, 107271, 0, 0, 0, 0, 0, 0, - 0, 107278, 107285, 107293, 107303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 107313, 107319, 107325, 107331, 107337, 107344, 107351, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 107359, 107366, 107373, 107381, 107388, 107395, 107402, 107409, - 107417, 107425, 107433, 107441, 107449, 107457, 107465, 107473, 107481, - 107489, 107497, 107505, 107513, 107521, 107529, 107537, 107545, 107553, - 107561, 107569, 107577, 107585, 107593, 107601, 107609, 107617, 107625, - 107633, 107641, 107649, 107657, 107665, 107673, 107681, 107689, 107697, - 107705, 107713, 107721, 107729, 107737, 107745, 107753, 107761, 107769, - 107777, 107785, 107793, 107801, 107809, 107817, 107825, 107833, 107841, - 107849, 107857, 107865, 107873, 107881, 107889, 107897, 107905, 107913, - 107921, 107929, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107937, 107942, 107948, 107954, - 107960, 107966, 107972, 107978, 107984, 107990, 107995, 108002, 108008, - 108014, 108020, 108026, 108032, 108037, 108043, 108049, 108055, 108061, - 108067, 108073, 108079, 108085, 108091, 108097, 108102, 108108, 108116, - 108124, 108130, 108136, 108142, 108148, 108156, 108162, 108168, 108174, - 108180, 108186, 108192, 108197, 108203, 108211, 108219, 108225, 108231, - 108237, 108244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108250, 108255, - 108261, 108267, 108273, 108279, 108285, 108291, 108297, 108303, 108308, - 108315, 108321, 108327, 108333, 108339, 108345, 108350, 108356, 108362, - 108368, 108374, 108380, 108386, 108392, 108398, 108404, 108410, 108415, - 108421, 108429, 108437, 108443, 108449, 108455, 108461, 108469, 108475, - 108481, 108487, 108493, 108499, 108505, 108510, 108516, 108524, 108532, - 108538, 108544, 108550, 108557, 0, 0, 0, 0, 0, 0, 0, 108563, 108567, - 108571, 108576, 108581, 108587, 108592, 108598, 108605, 108611, 108618, - 108625, 108632, 108639, 108645, 108652, 108659, 108666, 108673, 108679, - 108686, 108693, 108699, 108706, 108712, 108719, 108725, 108731, 108737, - 108744, 108753, 108759, 108767, 108774, 108781, 108788, 108794, 108800, - 108806, 108812, 108818, 108825, 108834, 108841, 108848, 108855, 0, 0, 0, - 0, 0, 0, 0, 0, 108862, 108869, 108875, 108881, 108887, 108893, 108899, - 108905, 108911, 108917, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 108923, 108927, 108931, 108935, 108939, 108943, 108947, - 108951, 108955, 108959, 108964, 108969, 108974, 108979, 108984, 108989, - 108994, 108999, 109004, 109010, 109016, 109022, 109029, 109036, 109043, - 109050, 109057, 109064, 109071, 109078, 109085, 0, 109092, 109097, - 109102, 109107, 109112, 109117, 109122, 109127, 109132, 109137, 109142, - 109147, 109152, 109157, 109161, 109166, 109171, 109176, 109181, 109186, - 109191, 109196, 109201, 109206, 109211, 109216, 109221, 109226, 109234, - 109239, 109244, 109249, 109254, 109259, 109264, 109269, 109274, 109279, - 109284, 109289, 109294, 109299, 0, 109304, 109310, 109316, 0, 0, 109321, - 109329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 109338, 109344, 109351, 109357, 109364, 109370, - 109376, 109383, 109389, 109395, 109401, 109407, 109413, 109419, 109425, - 109431, 109438, 109449, 109455, 109461, 109469, 109475, 109481, 109488, - 109499, 109505, 109511, 109517, 109524, 109535, 109540, 109545, 109550, - 109555, 109560, 109566, 109572, 109578, 109585, 109593, 0, 0, 0, 0, 0, 0, - 0, 0, 109599, 109604, 109609, 109614, 109619, 109624, 109629, 109634, - 109639, 109644, 109649, 109654, 109659, 109664, 109669, 109674, 109679, - 109684, 109689, 109694, 109699, 109704, 109710, 109715, 109721, 109726, - 109732, 109738, 109744, 109750, 109756, 109763, 109769, 109775, 109779, - 109784, 109789, 109795, 109803, 109814, 109823, 109833, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109843, 109849, 109855, - 109861, 109867, 109873, 109880, 109886, 109892, 109898, 109904, 109910, - 109916, 109922, 109928, 109934, 109940, 109946, 109952, 109958, 109964, - 109971, 109978, 109984, 109992, 110000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 110009, 110014, 110020, 110025, 110030, 110035, 110040, 110045, - 110052, 110057, 110062, 110067, 110072, 110077, 110082, 110087, 110092, - 110097, 110102, 110107, 110112, 110117, 110121, 110125, 110129, 110133, - 110138, 110143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 110149, 110154, 110159, 110164, 110169, 110174, 110179, 110184, - 110189, 110194, 110199, 110204, 110209, 110214, 110219, 110224, 110229, - 110234, 110239, 110244, 110249, 110254, 110259, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 110264, 110268, 110272, 110276, 110280, 110284, 110287, 110291, - 110294, 110298, 110301, 110305, 110309, 110314, 110318, 110323, 110326, - 110330, 110333, 110337, 110340, 110344, 110348, 110352, 110356, 110360, - 110364, 110368, 110372, 110376, 110380, 110384, 110388, 110392, 110396, - 110400, 110404, 110408, 110412, 110415, 110418, 110422, 110426, 110430, - 110433, 110436, 110439, 110442, 110446, 110450, 110454, 110457, 110460, - 110464, 110470, 110476, 110482, 110487, 110494, 110498, 110503, 110507, - 110512, 110517, 110523, 110528, 110534, 110538, 110543, 110547, 110552, - 110555, 110558, 110562, 110567, 110573, 110578, 110584, 0, 0, 0, 0, - 110589, 110592, 110595, 110598, 110601, 110604, 110607, 110610, 110613, - 110616, 110620, 110624, 110628, 110632, 110636, 110640, 110644, 110648, - 110652, 110657, 110661, 110665, 110668, 110671, 110674, 110677, 110680, - 110683, 110686, 110689, 110692, 110698, 110705, 110712, 110720, 110728, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 110734, 110738, 110743, 110748, 110753, - 110757, 110762, 110766, 110771, 110775, 110780, 110784, 110789, 110793, - 110798, 110802, 110807, 110812, 110817, 110822, 110827, 110832, 110837, - 110842, 110847, 110852, 110857, 110862, 110867, 110872, 110877, 110882, - 110887, 110892, 110897, 110902, 110906, 110910, 110915, 110920, 110925, - 110929, 110933, 110937, 110941, 110946, 110951, 110956, 110960, 110964, - 110970, 110975, 110981, 110986, 110992, 110997, 111003, 111008, 111014, - 111019, 111024, 111029, 111034, 111038, 111043, 111049, 111053, 111058, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111064, 0, 0, 111069, 111076, 111083, - 111090, 111097, 111104, 111111, 111118, 111125, 111132, 111139, 111146, - 111153, 111160, 111167, 111174, 111181, 111188, 111195, 111202, 111209, - 111216, 111223, 111230, 111237, 0, 0, 0, 0, 0, 0, 0, 111244, 111251, - 111257, 111263, 111269, 111275, 111281, 111287, 111293, 111299, 0, 0, 0, - 0, 0, 0, 111305, 111310, 111315, 111320, 111325, 111329, 111333, 111337, - 111342, 111347, 111352, 111357, 111362, 111367, 111372, 111377, 111382, - 111387, 111392, 111397, 111402, 111407, 111412, 111417, 111422, 111427, - 111432, 111437, 111442, 111447, 111452, 111457, 111462, 111467, 111472, - 111477, 111482, 111487, 111492, 111497, 111502, 111507, 111513, 111518, - 111524, 111529, 111535, 111540, 111546, 111552, 111556, 111561, 111565, - 0, 111569, 111574, 111578, 111582, 111586, 111590, 111594, 111598, - 111602, 111606, 111610, 111615, 111619, 111624, 111629, 111634, 111640, - 111646, 0, 0, 0, 0, 0, 0, 0, 0, 111651, 111655, 111659, 111663, 111667, - 111671, 111675, 111680, 111685, 111690, 111695, 111700, 111705, 111710, - 111715, 111720, 111725, 111730, 111735, 111740, 111745, 111750, 111755, - 111760, 111764, 111768, 111773, 111778, 111783, 111787, 111791, 111795, - 111800, 111804, 111808, 111813, 111818, 111823, 111828, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 111833, 111838, 111843, 111848, 111852, 111857, 111861, 111866, - 111870, 111875, 111880, 111886, 111891, 111897, 111901, 111906, 111910, - 111915, 111919, 111924, 111929, 111934, 111939, 111944, 111949, 111954, - 111959, 111964, 111969, 111974, 111979, 111984, 111989, 111994, 111999, - 112004, 112009, 112013, 112017, 112022, 112027, 112032, 112036, 112040, - 112044, 112048, 112053, 112058, 112063, 112068, 112072, 112076, 112082, - 112087, 112093, 112098, 112104, 112110, 112117, 112123, 112130, 112135, - 112141, 112146, 112152, 112157, 112162, 112167, 112172, 112176, 112180, - 112185, 112190, 112194, 112199, 112204, 112209, 112217, 112222, 112229, - 112236, 112241, 112245, 112249, 112253, 112257, 112261, 112265, 112269, - 112273, 112277, 112281, 112286, 112290, 112295, 112301, 0, 112307, - 112312, 112317, 112322, 112327, 112332, 112337, 112342, 112347, 112352, - 112358, 112364, 112370, 112376, 112382, 112388, 112394, 112400, 112406, - 112413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112419, 112423, 112428, 112432, - 112436, 112440, 112445, 112449, 112454, 112458, 112463, 112468, 112473, - 112478, 112483, 112488, 112493, 112498, 0, 112503, 112508, 112513, - 112518, 112523, 112528, 112533, 112538, 112543, 112548, 112553, 112558, - 112562, 112566, 112571, 112576, 112581, 112586, 112590, 112594, 112598, - 112602, 112607, 112611, 112615, 112620, 112626, 112631, 112637, 112642, - 112647, 112653, 112658, 112664, 112669, 112674, 112679, 112684, 112688, - 112693, 112699, 112704, 112710, 112715, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 112720, 112724, 112728, 112732, 112736, 112740, 112745, - 0, 112750, 0, 112755, 112760, 112765, 112770, 0, 112775, 112780, 112785, - 112790, 112795, 112800, 112805, 112810, 112815, 112820, 112825, 112830, - 112834, 112838, 112843, 0, 112848, 112853, 112857, 112861, 112865, - 112869, 112874, 112878, 112882, 112887, 112892, 0, 0, 0, 0, 0, 0, 112897, - 112901, 112906, 112910, 112915, 112919, 112924, 112928, 112933, 112937, - 112942, 112946, 112951, 112956, 112961, 112966, 112971, 112976, 112981, - 112986, 112991, 112996, 113001, 113006, 113011, 113016, 113021, 113026, - 113031, 113036, 113041, 113046, 113051, 113056, 113060, 113064, 113069, - 113074, 113079, 113084, 113088, 113092, 113096, 113100, 113105, 113110, - 113114, 113118, 113123, 113129, 113134, 113140, 113145, 113151, 113156, - 113162, 113167, 113173, 113178, 0, 0, 0, 0, 0, 113183, 113188, 113192, - 113196, 113200, 113204, 113208, 113212, 113216, 113220, 0, 0, 0, 0, 0, 0, - 113224, 113231, 113236, 113241, 0, 113246, 113250, 113255, 113259, - 113264, 113268, 113273, 113278, 0, 0, 113283, 113288, 0, 0, 113293, - 113298, 113303, 113307, 113312, 113317, 113322, 113327, 113332, 113337, - 113342, 113347, 113352, 113357, 113362, 113367, 113372, 113377, 113382, - 113387, 113392, 113397, 0, 113401, 113405, 113410, 113415, 113420, - 113424, 113428, 0, 113432, 113436, 0, 113441, 113446, 113451, 113456, - 113460, 0, 113464, 113468, 113473, 113478, 113484, 113489, 113495, - 113500, 113506, 113512, 0, 0, 113519, 113525, 0, 0, 113531, 113537, - 113543, 0, 0, 113548, 0, 0, 0, 0, 0, 0, 113552, 0, 0, 0, 0, 0, 113559, - 113564, 113571, 113579, 113585, 113591, 113597, 0, 0, 113604, 113610, - 113615, 113620, 113625, 113630, 113635, 0, 0, 0, 113640, 113645, 113650, - 113655, 113661, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113666, 113670, 113675, - 113679, 113684, 113688, 113693, 113698, 113704, 113709, 113715, 113719, - 113724, 113728, 113733, 113737, 113742, 113747, 113752, 113757, 113762, - 113767, 113772, 113777, 113782, 113787, 113792, 113797, 113802, 113807, - 113812, 113817, 113822, 113827, 113832, 113837, 113841, 113846, 113850, - 113855, 113860, 113865, 113869, 113874, 113878, 113882, 113887, 113891, - 113896, 113901, 113906, 113911, 113915, 113919, 113925, 113930, 113936, - 113941, 113947, 113953, 113960, 113966, 113973, 113978, 113984, 113989, - 113995, 114000, 114005, 114010, 114015, 114020, 114025, 114031, 114035, - 114039, 114043, 114048, 114052, 114058, 114063, 114068, 114072, 114076, - 114080, 114084, 114088, 114092, 114096, 114100, 114104, 114109, 0, - 114114, 114119, 114124, 114131, 114136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114141, 114145, - 114149, 114154, 114158, 114163, 114167, 114172, 114177, 114183, 114188, - 114194, 114198, 114203, 114207, 114212, 114216, 114221, 114226, 114231, - 114236, 114241, 114246, 114251, 114256, 114261, 114266, 114271, 114276, - 114281, 114286, 114291, 114296, 114301, 114306, 114310, 114314, 114319, - 114324, 114329, 114333, 114337, 114341, 114345, 114350, 114355, 114360, - 114364, 114368, 114374, 114379, 114385, 114390, 114396, 114402, 114409, - 114415, 114422, 114427, 114434, 114440, 114445, 114452, 114458, 114463, - 114468, 114473, 114478, 114483, 114488, 114492, 114497, 0, 0, 0, 0, 0, 0, - 0, 0, 114501, 114506, 114510, 114514, 114518, 114522, 114526, 114530, - 114534, 114538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114542, 114546, - 114551, 114555, 114560, 114564, 114569, 114574, 114580, 114585, 114591, - 114595, 114600, 114604, 114609, 114613, 114618, 114623, 114628, 114633, - 114638, 114643, 114648, 114653, 114658, 114663, 114668, 114673, 114678, - 114683, 114688, 114693, 114698, 114703, 114707, 114711, 114716, 114721, - 114726, 114730, 114734, 114738, 114742, 114747, 114752, 114757, 114761, - 114765, 114771, 114776, 114782, 114787, 114793, 114799, 0, 0, 114806, - 114811, 114817, 114822, 114828, 114833, 114838, 114843, 114848, 114853, - 114858, 114862, 114867, 114873, 114878, 114884, 114890, 114896, 114904, - 114917, 114930, 114943, 114957, 114972, 114980, 114991, 115000, 115010, - 115020, 115030, 115041, 115053, 115066, 115074, 115082, 115091, 115097, - 115104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115112, 115116, 115121, 115125, - 115130, 115134, 115139, 115144, 115150, 115155, 115161, 115165, 115170, - 115174, 115179, 115183, 115188, 115193, 115198, 115203, 115208, 115213, - 115218, 115223, 115228, 115233, 115238, 115243, 115248, 115253, 115258, - 115263, 115268, 115273, 115277, 115281, 115286, 115291, 115296, 115300, - 115304, 115308, 115312, 115317, 115322, 115327, 115331, 115335, 115340, - 115346, 115351, 115357, 115362, 115368, 115374, 115381, 115387, 115394, - 115399, 115405, 115410, 115416, 115421, 115426, 115431, 115436, 115440, - 115445, 115450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115455, 115460, 115464, - 115468, 115472, 115476, 115480, 115484, 115488, 115492, 0, 0, 0, 0, 0, 0, - 115496, 115502, 115507, 115514, 115522, 115529, 115537, 115546, 115551, - 115560, 115565, 115573, 115582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 115592, 115596, 115601, 115605, 115610, 115614, 115619, - 115623, 115628, 115632, 115637, 115641, 115646, 115651, 115656, 115661, - 115666, 115671, 115676, 115681, 115686, 115691, 115696, 115701, 115706, - 115711, 115716, 115721, 115726, 115731, 115735, 115739, 115744, 115749, - 115754, 115758, 115762, 115766, 115770, 115775, 115780, 115784, 115788, - 115793, 115798, 115803, 115809, 115814, 115820, 115825, 115831, 115836, - 115842, 115847, 115853, 115858, 115863, 115870, 0, 0, 0, 0, 0, 0, 115875, - 115880, 115884, 115888, 115892, 115896, 115900, 115904, 115908, 115912, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 115916, 115920, 115925, 115930, 115934, 115939, 115946, - 115950, 115955, 115960, 115964, 115969, 115974, 115979, 115983, 115987, - 115991, 115996, 116000, 116004, 116009, 116014, 116019, 116026, 116031, - 116036, 116041, 0, 0, 116048, 116055, 116062, 116071, 116076, 116082, - 116087, 116093, 116098, 116104, 116109, 116115, 116120, 116126, 116132, - 0, 0, 0, 0, 116137, 116142, 116146, 116150, 116154, 116158, 116162, - 116166, 116170, 116174, 116178, 116183, 116188, 116194, 116199, 116204, - 116209, 116214, 116219, 116224, 116229, 116234, 116239, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 116244, 116248, 116253, 116257, 116262, 116266, 116271, 116275, - 116280, 116284, 116289, 116293, 116298, 116303, 116308, 116313, 116318, - 116323, 116328, 116333, 116338, 116343, 116348, 116353, 116358, 116363, - 116368, 116373, 116378, 116383, 116387, 116391, 116396, 116401, 116406, - 116410, 116414, 116418, 116422, 116427, 116432, 116437, 116441, 116445, - 116450, 116456, 116461, 116467, 116472, 116478, 116484, 116491, 116496, - 116502, 116507, 116513, 116518, 116523, 116528, 116533, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116538, - 116546, 116553, 116561, 116569, 116576, 116584, 116592, 116600, 116607, - 116614, 116622, 116630, 116638, 116646, 116654, 116662, 116670, 116678, - 116686, 116694, 116702, 116710, 116718, 116726, 116734, 116742, 116750, - 116758, 116766, 116774, 116782, 116790, 116798, 116805, 116813, 116821, - 116828, 116836, 116844, 116852, 116859, 116866, 116874, 116882, 116890, - 116898, 116906, 116914, 116922, 116930, 116938, 116946, 116954, 116962, - 116970, 116978, 116986, 116994, 117002, 117010, 117018, 117026, 117034, - 117042, 117049, 117055, 117061, 117067, 117073, 117079, 117085, 117091, - 117097, 117103, 117110, 117117, 117124, 117131, 117138, 117145, 117152, - 117159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117166, 117172, 117178, - 117185, 117191, 117198, 117204, 117211, 0, 0, 117217, 0, 0, 117223, - 117229, 117236, 117243, 117250, 117257, 117264, 117271, 0, 117278, - 117285, 0, 117292, 117299, 117306, 117313, 117320, 117327, 117334, - 117341, 117347, 117353, 117360, 117367, 117374, 117380, 117386, 117393, - 117399, 117405, 117412, 117419, 117426, 117432, 117438, 117445, 117452, - 117460, 117467, 117475, 117482, 117490, 0, 117497, 117505, 0, 0, 117512, - 117519, 117526, 117533, 117539, 117548, 117555, 117561, 117568, 117575, - 117582, 117590, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117600, 117607, 117613, - 117619, 117625, 117631, 117637, 117643, 117649, 117655, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117661, 117665, 117670, - 117674, 117679, 117683, 117688, 117693, 0, 0, 117699, 117703, 117708, - 117712, 117717, 117721, 117726, 117731, 117736, 117741, 117746, 117751, - 117756, 117761, 117766, 117771, 117776, 117781, 117786, 117791, 117796, - 117801, 117806, 117811, 117815, 117819, 117824, 117829, 117834, 117838, - 117842, 117846, 117850, 117855, 117860, 117865, 117869, 117873, 117878, - 117883, 117889, 117894, 117900, 117905, 117911, 117917, 0, 0, 117924, - 117929, 117935, 117940, 117946, 117951, 117956, 117961, 117966, 117971, - 117975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 117982, 117987, 117993, 118000, 118006, 118012, 118019, - 118025, 118032, 118039, 118047, 118054, 118059, 118065, 118071, 118077, - 118083, 118089, 118095, 118101, 118107, 118113, 118119, 118125, 118131, - 118137, 118143, 118149, 118155, 118161, 118166, 118171, 118177, 118183, - 118189, 118194, 118200, 118206, 118212, 118218, 118224, 118230, 118236, - 118241, 118246, 118251, 118257, 118263, 118269, 118274, 118279, 118285, - 118291, 118297, 118303, 118312, 118321, 118327, 118333, 118340, 118347, - 118354, 118361, 118369, 118376, 118384, 118390, 118396, 118403, 118410, - 118419, 118429, 0, 0, 0, 0, 0, 0, 0, 0, 118434, 118438, 118443, 118449, - 118454, 118459, 118464, 118470, 118476, 118482, 118488, 118494, 118500, - 118504, 118509, 118514, 118519, 118524, 118529, 118534, 118539, 118544, - 118549, 118554, 118559, 118564, 118569, 118574, 118579, 118584, 118589, - 118594, 118598, 118602, 118607, 118612, 118617, 118621, 118626, 118631, - 118636, 118641, 118646, 118651, 118655, 118659, 118663, 118668, 118673, - 118678, 118682, 118686, 118691, 118696, 118701, 118707, 118713, 118720, - 118726, 118733, 118740, 118747, 118754, 118761, 118768, 118775, 118781, - 118787, 118794, 118801, 118808, 118813, 118818, 118823, 118827, 118832, - 118837, 118843, 118848, 118864, 118878, 118889, 118895, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 118901, 118907, 118913, 118919, 118925, 118930, - 118936, 118942, 118948, 118954, 118960, 118966, 118972, 118976, 118980, - 118984, 118988, 118996, 119004, 119012, 119020, 119029, 119038, 119047, - 119056, 119064, 119073, 119082, 119090, 119099, 119108, 119117, 119126, - 119134, 119143, 119151, 119160, 119169, 119177, 119185, 119193, 119201, - 119209, 119218, 119227, 119237, 119247, 119257, 119267, 119277, 119286, - 119296, 119306, 119316, 119327, 119337, 119349, 119361, 119372, 119386, - 119397, 119407, 119419, 119430, 119440, 119452, 119464, 119475, 119486, - 119496, 119506, 119518, 119529, 0, 0, 0, 0, 0, 0, 0, 119541, 119545, - 119550, 119554, 119559, 119563, 119568, 119573, 119579, 0, 119584, - 119588, 119593, 119597, 119602, 119606, 119611, 119616, 119621, 119626, - 119631, 119636, 119641, 119646, 119651, 119656, 119661, 119666, 119671, - 119676, 119681, 119686, 119691, 119696, 119700, 119704, 119709, 119714, - 119719, 119723, 119727, 119731, 119735, 119740, 119745, 119750, 119754, - 119758, 119764, 119769, 119775, 119780, 119786, 119792, 119799, 0, - 119805, 119810, 119816, 119821, 119827, 119832, 119837, 119842, 119847, - 119852, 119856, 119861, 119867, 119873, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 119879, 119884, 119888, 119892, 119896, 119900, 119904, 119908, 119912, - 119916, 119920, 119924, 119928, 119932, 119936, 119940, 119944, 119948, - 119952, 119956, 119961, 119966, 119971, 119976, 119981, 119986, 119991, - 119996, 120001, 0, 0, 0, 120008, 120013, 120018, 120022, 120027, 120032, - 120037, 120042, 120047, 120052, 120057, 120062, 120067, 120072, 120076, - 120080, 120085, 120090, 120094, 120099, 120104, 120109, 120114, 120119, - 120124, 120129, 120133, 120137, 120141, 120146, 120150, 120154, 0, 0, - 120158, 120164, 120171, 120178, 120185, 120192, 120199, 120206, 120213, - 120220, 120227, 120234, 120240, 120246, 120253, 120260, 120266, 120273, - 120280, 120287, 120294, 120301, 0, 120308, 120314, 120320, 120326, - 120333, 120339, 120345, 120351, 120357, 120362, 120367, 120372, 120377, - 120382, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 120387, 120392, 120398, 120403, 120409, 120414, 120420, 0, - 120425, 120431, 0, 120436, 120442, 120447, 120453, 120459, 120465, - 120471, 120477, 120483, 120489, 120495, 120501, 120507, 120513, 120519, - 120525, 120531, 120537, 120543, 120549, 120555, 120560, 120565, 120571, - 120577, 120583, 120588, 120593, 120598, 120603, 120609, 120615, 120621, - 120626, 120631, 120637, 120643, 120649, 120655, 120662, 120668, 120675, - 120681, 120688, 0, 0, 0, 120695, 0, 120701, 120708, 0, 120714, 120721, - 120727, 120733, 120739, 120745, 120751, 120756, 120761, 0, 0, 0, 0, 0, 0, - 0, 0, 120766, 120772, 120777, 120782, 120787, 120792, 120797, 120802, - 120807, 120812, 0, 0, 0, 0, 0, 0, 120817, 120822, 120828, 120833, 120839, - 120844, 0, 120850, 120856, 0, 120862, 120868, 120874, 120879, 120885, - 120891, 120897, 120902, 120907, 120913, 120919, 120925, 120930, 120936, - 120942, 120948, 120954, 120959, 120965, 120971, 120977, 120983, 120989, - 120995, 121001, 121007, 121013, 121019, 121024, 121030, 121035, 121040, - 121045, 121052, 121058, 121065, 121071, 0, 121078, 121085, 0, 121092, - 121099, 121106, 121112, 121118, 121123, 0, 0, 0, 0, 0, 0, 0, 121128, - 121134, 121139, 121144, 121149, 121154, 121159, 121164, 121169, 121174, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121179, 121183, 121188, 121193, - 121197, 121202, 121206, 121211, 121216, 121220, 121225, 121230, 121235, - 121239, 121243, 121247, 121252, 121256, 121260, 121264, 121269, 121274, - 121279, 121284, 121288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121295, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 121300, 121306, 121312, 121318, 121324, 121330, - 121336, 121342, 121348, 121354, 121360, 121366, 121372, 121378, 121384, - 121390, 121396, 121402, 121408, 121414, 121420, 121429, 121433, 121437, - 121441, 121445, 121449, 121453, 121457, 121461, 121465, 121469, 121473, - 121477, 121481, 121485, 121489, 121495, 121501, 121505, 121511, 121517, - 121522, 121526, 121531, 121535, 121539, 121545, 121551, 121555, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121559, 121567, 121570, 121575, 121581, - 121589, 121594, 121600, 121608, 121614, 121620, 121624, 121628, 121635, - 121644, 121651, 121660, 121666, 121675, 121682, 121689, 121696, 121706, - 121712, 121716, 121723, 121732, 121742, 121749, 121756, 121760, 121764, - 121771, 121781, 121785, 121792, 121799, 121806, 121812, 121819, 121826, - 121833, 121840, 121844, 121848, 121852, 121859, 121863, 121870, 121877, - 121891, 121900, 121904, 121908, 121912, 121919, 121923, 121927, 121931, - 121939, 121947, 121966, 121976, 121996, 122000, 122004, 122008, 122012, - 122016, 122020, 122024, 122031, 122035, 122038, 122042, 122046, 122052, - 122059, 122068, 122072, 122081, 122090, 122098, 122102, 122109, 122113, - 122117, 122121, 122125, 122136, 122145, 122154, 122163, 122172, 122184, - 122193, 122202, 122211, 122219, 122228, 122240, 122249, 122257, 122266, - 122278, 122287, 122296, 122308, 122317, 122326, 122338, 122347, 122351, - 122355, 122359, 122363, 122367, 122371, 122375, 122382, 122386, 122390, - 122401, 122405, 122409, 122416, 122422, 122428, 122432, 122439, 122443, - 122447, 122451, 122455, 122459, 122463, 122469, 122477, 122481, 122485, - 122488, 122495, 122507, 122511, 122523, 122530, 122537, 122544, 122551, - 122557, 122561, 122565, 122569, 122573, 122580, 122589, 122596, 122604, - 122612, 122618, 122622, 122626, 122630, 122634, 122640, 122649, 122661, - 122668, 122675, 122684, 122695, 122701, 122710, 122719, 122726, 122735, - 122742, 122748, 122758, 122765, 122772, 122779, 122786, 122790, 122796, - 122800, 122811, 122819, 122828, 122840, 122847, 122854, 122864, 122871, - 122880, 122887, 122896, 122903, 122910, 122920, 122927, 122934, 122943, - 122950, 122962, 122971, 122978, 122985, 122992, 123001, 123011, 123024, - 123031, 123040, 123050, 123057, 123066, 123079, 123086, 123093, 123100, - 123110, 123120, 123126, 123136, 123143, 123150, 123160, 123166, 123173, - 123180, 123187, 123197, 123204, 123211, 123218, 123224, 123231, 123241, - 123248, 123252, 123260, 123264, 123276, 123280, 123294, 123298, 123302, - 123306, 123310, 123316, 123323, 123331, 123335, 123339, 123343, 123347, - 123354, 123358, 123364, 123370, 123378, 123382, 123389, 123397, 123401, - 123405, 123411, 123415, 123424, 123433, 123440, 123450, 123456, 123460, - 123464, 123472, 123479, 123486, 123492, 123496, 123504, 123508, 123515, - 123527, 123534, 123544, 123550, 123554, 123563, 123570, 123579, 123583, - 123587, 123594, 123598, 123602, 123606, 123610, 123613, 123619, 123625, - 123629, 123633, 123640, 123647, 123654, 123661, 123668, 123675, 123682, - 123689, 123695, 123699, 123703, 123710, 123717, 123724, 123731, 123738, - 123742, 123745, 123750, 123754, 123758, 123767, 123776, 123780, 123784, - 123790, 123796, 123813, 123819, 123823, 123832, 123836, 123840, 123847, - 123855, 123863, 123869, 123873, 123877, 123881, 123885, 123888, 123894, - 123901, 123911, 123918, 123925, 123932, 123938, 123945, 123952, 123959, - 123966, 123973, 123982, 123989, 124001, 124008, 124015, 124025, 124036, - 124043, 124050, 124057, 124064, 124071, 124078, 124085, 124092, 124099, - 124106, 124116, 124126, 124136, 124143, 124153, 124160, 124167, 124174, - 124181, 124187, 124194, 124201, 124208, 124215, 124222, 124229, 124236, - 124243, 124249, 124256, 124263, 124272, 124279, 124286, 124290, 124298, - 124302, 124306, 124310, 124314, 124318, 124325, 124329, 124338, 124342, - 124349, 124357, 124361, 124365, 124369, 124382, 124398, 124402, 124406, - 124413, 124419, 124426, 124430, 124434, 124438, 124442, 124446, 124453, - 124457, 124475, 124479, 124483, 124490, 124494, 124498, 124504, 124508, - 124512, 124520, 124524, 124528, 124531, 124535, 124541, 124552, 124561, - 124570, 124577, 124584, 124595, 124602, 124609, 124616, 124623, 124630, - 124637, 124644, 124654, 124660, 124667, 124677, 124686, 124693, 124702, - 124712, 124719, 124726, 124733, 124740, 124752, 124759, 124766, 124773, - 124780, 124787, 124797, 124804, 124811, 124821, 124834, 124846, 124853, - 124863, 124870, 124877, 124884, 124898, 124904, 124912, 124922, 124932, - 124939, 124946, 124952, 124956, 124963, 124973, 124979, 124992, 124996, - 125000, 125007, 125011, 125018, 125028, 125032, 125036, 125040, 125044, - 125048, 125055, 125059, 125066, 125073, 125080, 125089, 125098, 125108, - 125115, 125122, 125129, 125139, 125146, 125156, 125163, 125173, 125180, - 125187, 125197, 125207, 125214, 125220, 125228, 125236, 125242, 125248, - 125252, 125256, 125263, 125271, 125277, 125281, 125285, 125289, 125296, - 125308, 125311, 125318, 125324, 125328, 125332, 125336, 125340, 125344, - 125348, 125352, 125356, 125360, 125364, 125371, 125375, 125381, 125385, - 125389, 125393, 125399, 125406, 125413, 125420, 125431, 125439, 125443, - 125449, 125458, 125465, 125471, 125474, 125478, 125482, 125488, 125497, - 125505, 125509, 125515, 125519, 125523, 125527, 125533, 125540, 125546, - 125550, 125556, 125560, 125564, 125573, 125585, 125589, 125596, 125603, - 125613, 125620, 125632, 125639, 125646, 125653, 125664, 125674, 125687, - 125697, 125704, 125708, 125712, 125716, 125720, 125729, 125738, 125747, - 125764, 125773, 125779, 125786, 125794, 125807, 125811, 125820, 125829, - 125838, 125847, 125858, 125867, 125875, 125884, 125893, 125902, 125911, - 125921, 125924, 125928, 125932, 125936, 125940, 125944, 125950, 125957, - 125964, 125971, 125977, 125983, 125990, 125996, 126003, 126011, 126015, - 126022, 126029, 126036, 126044, 126047, 126051, 126055, 126059, 126062, - 126068, 126072, 126078, 126085, 126092, 126098, 126105, 126112, 126119, - 126126, 126133, 126140, 126147, 126154, 126161, 126168, 126175, 126182, - 126189, 126196, 126202, 126206, 126215, 126219, 126223, 126227, 126231, - 126237, 126244, 126251, 126258, 126265, 126272, 126278, 126286, 126290, - 126294, 126298, 126302, 126308, 126325, 126342, 126346, 126350, 126354, - 126358, 126362, 126366, 126372, 126379, 126383, 126389, 126396, 126403, - 126410, 126417, 126424, 126433, 126440, 126447, 126454, 126461, 126465, - 126469, 126475, 126487, 126491, 126495, 126504, 126508, 126512, 126516, - 126522, 126526, 126530, 126539, 126543, 126547, 126551, 126558, 126562, - 126566, 126570, 126574, 126578, 126582, 126586, 126590, 126596, 126603, - 126610, 126616, 126620, 126637, 126643, 126647, 126654, 126661, 126668, - 126675, 126682, 126689, 126693, 126697, 126701, 126707, 126711, 126717, - 126721, 126725, 126732, 126739, 126756, 126760, 126764, 126768, 126772, - 126776, 126788, 126791, 126796, 126801, 126816, 126826, 126838, 126842, - 126846, 126850, 126856, 126863, 126870, 126880, 126892, 126898, 126904, - 126913, 126917, 126921, 126928, 126938, 126945, 126951, 126955, 126959, - 126966, 126972, 126976, 126982, 126986, 126994, 127000, 127004, 127012, - 127020, 127027, 127033, 127040, 127047, 127057, 127067, 127071, 127075, - 127079, 127083, 127089, 127096, 127102, 127109, 127116, 127123, 127132, - 127139, 127146, 127152, 127159, 127166, 127173, 127180, 127187, 127194, - 127200, 127207, 127214, 127221, 127230, 127237, 127244, 127248, 127254, - 127258, 127264, 127271, 127278, 127285, 127289, 127293, 127297, 127301, - 127305, 127312, 127316, 127320, 127326, 127334, 127338, 127342, 127346, - 127350, 127357, 127361, 127365, 127373, 127377, 127381, 127385, 127389, - 127395, 127399, 127403, 127409, 127416, 127422, 127429, 127441, 127445, - 127452, 127459, 127466, 127473, 127485, 127492, 127496, 127500, 127504, - 127511, 127518, 127525, 127532, 127542, 127549, 127555, 127562, 127569, - 127576, 127583, 127592, 127602, 127609, 127613, 127620, 127624, 127628, - 127632, 127639, 127646, 127656, 127662, 127666, 127675, 127679, 127686, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 127690, 127696, 127702, 127709, 127716, 127723, 127730, - 127737, 127744, 127750, 127757, 127764, 127771, 127778, 127785, 127792, - 127798, 127804, 127810, 127816, 127822, 127828, 127834, 127840, 127846, - 127853, 127860, 127867, 127874, 127881, 127888, 127894, 127900, 127906, - 127913, 127920, 127926, 127932, 127941, 127948, 127955, 127962, 127969, - 127976, 127983, 127989, 127995, 128001, 128010, 128017, 128024, 128035, - 128046, 128052, 128058, 128064, 128073, 128080, 128087, 128097, 128107, - 128118, 128129, 128141, 128154, 128165, 128176, 128188, 128201, 128212, - 128223, 128234, 128245, 128256, 128268, 128276, 128284, 128293, 128302, - 128311, 128317, 128323, 128329, 128336, 128346, 128353, 128363, 128368, - 128373, 128379, 128385, 128393, 128401, 128410, 128421, 128432, 128440, - 128448, 128457, 128466, 128474, 128481, 128489, 128497, 128504, 128511, - 128520, 128529, 128538, 128547, 128556, 0, 128565, 128576, 128583, - 128591, 128599, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128607, 128616, 128623, - 128630, 128639, 128646, 128653, 128660, 128670, 128677, 128684, 128691, - 128699, 128706, 128713, 128720, 128731, 128738, 128745, 128752, 128759, - 128766, 128775, 128782, 128788, 128795, 128804, 128811, 128818, 128825, - 128835, 128842, 128849, 128859, 128869, 128876, 128883, 128890, 128897, - 128904, 128911, 128920, 128927, 128934, 128940, 128948, 128957, 128966, - 128977, 128985, 128994, 129003, 129012, 129021, 129028, 129035, 129044, - 129056, 129066, 129073, 129080, 129090, 129100, 129109, 129119, 129126, - 129136, 129143, 129150, 129157, 129167, 129177, 129184, 129191, 129201, - 129207, 129218, 129227, 129237, 129245, 129258, 129265, 129271, 129279, - 129286, 129296, 129300, 129304, 129308, 129312, 129316, 129320, 129324, - 129333, 129337, 129344, 129348, 129352, 129356, 129360, 129364, 129368, - 129372, 129376, 129380, 129384, 129388, 129392, 129396, 129400, 129404, - 129408, 129412, 129416, 129420, 129427, 129434, 129444, 129457, 129467, - 129471, 129475, 129479, 129483, 129487, 129491, 129495, 129499, 129503, - 129507, 129511, 129518, 129525, 129536, 129543, 129549, 129556, 129563, - 129570, 129577, 129584, 129588, 129592, 129599, 129606, 129613, 129622, - 129629, 129642, 129652, 129659, 129666, 129670, 129674, 129683, 129690, - 129697, 129704, 129717, 129724, 129731, 129741, 129751, 129760, 129767, - 129774, 129781, 129788, 129795, 129802, 129812, 129818, 129826, 129833, - 129841, 129848, 129859, 129866, 129872, 129879, 129886, 129893, 129900, - 129910, 129920, 129927, 129934, 129943, 129951, 129957, 129964, 129971, - 129978, 129985, 129989, 129999, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130009, 130014, 130019, 130024, - 130029, 130034, 130039, 130044, 130049, 130054, 130059, 130064, 130069, - 130074, 130079, 130084, 130089, 130094, 130099, 130104, 130109, 130114, - 130119, 130124, 130129, 130134, 130139, 130144, 130149, 130154, 130159, - 130164, 130169, 130174, 130179, 130184, 130189, 130194, 130199, 130204, - 130209, 130214, 130219, 130224, 130229, 130234, 130239, 130244, 130249, - 130254, 130259, 130264, 130269, 130274, 130279, 130284, 130289, 130294, - 130299, 130304, 130309, 130314, 130319, 130324, 130329, 130334, 130339, - 130344, 130349, 130354, 130359, 130364, 130369, 130374, 130379, 130384, - 130389, 130394, 130399, 130404, 130409, 130414, 130419, 130424, 130429, - 130434, 130439, 130444, 130449, 130454, 130459, 130464, 130469, 130474, - 130479, 130484, 130489, 130494, 130499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 130504, 130508, 130512, 130516, 130520, 130524, 130528, 130532, - 130536, 130540, 130544, 130548, 130552, 130556, 130560, 130564, 130568, - 130572, 130576, 130580, 130584, 130588, 130592, 130596, 130600, 130604, - 130608, 130612, 130616, 130620, 130624, 130628, 130632, 130636, 130640, - 130644, 130648, 130652, 130656, 130660, 130664, 130668, 130672, 130676, - 130680, 130684, 130688, 130692, 130696, 130700, 130704, 130708, 130712, - 130716, 130720, 130724, 130728, 130732, 130736, 130740, 130744, 130748, - 130752, 130756, 130760, 130764, 130768, 130772, 130776, 130780, 130784, - 130788, 130792, 130796, 130800, 130804, 130808, 130812, 130816, 130820, - 130824, 130828, 130832, 130836, 130840, 130844, 130848, 130852, 130856, - 130860, 130864, 130868, 130872, 130876, 130880, 130884, 130888, 130892, - 130896, 130900, 130904, 130908, 130912, 130916, 130920, 130924, 130928, - 130932, 130936, 130940, 130944, 130948, 130952, 130956, 130960, 130964, - 130968, 130972, 130976, 130980, 130984, 130988, 130992, 130996, 131000, - 131004, 131008, 131012, 131016, 131020, 131024, 131028, 131032, 131036, - 131040, 131044, 131048, 131052, 131056, 131060, 131064, 131068, 131072, - 131076, 131080, 131084, 131088, 131092, 131096, 131100, 131104, 131108, - 131112, 131116, 131120, 131124, 131128, 131132, 131136, 131140, 131144, - 131148, 131152, 131156, 131160, 131164, 131168, 131172, 131176, 131180, - 131184, 131188, 131192, 131196, 131200, 131204, 131208, 131212, 131216, - 131220, 131224, 131228, 131232, 131236, 131240, 131244, 131248, 131252, - 131256, 131260, 131264, 131268, 131272, 131276, 131280, 131284, 131288, - 131292, 131296, 131300, 131304, 131308, 131312, 131316, 131320, 131324, - 131328, 131332, 131336, 131340, 131344, 131348, 131352, 131356, 131360, - 131364, 131368, 131372, 131376, 131380, 131384, 131388, 131392, 131396, - 131400, 131404, 131408, 131412, 131416, 131420, 131424, 131428, 131432, - 131436, 131440, 131444, 131448, 131452, 131456, 131460, 131464, 131468, - 131472, 131476, 131480, 131484, 131488, 131492, 131496, 131500, 131504, - 131508, 131512, 131516, 131520, 131524, 131528, 131532, 131536, 131540, - 131544, 131548, 131552, 131556, 131560, 131564, 131568, 131572, 131576, - 131580, 131584, 131588, 131592, 131596, 131600, 131604, 131608, 131612, - 131616, 131620, 131624, 131628, 131632, 131636, 131640, 131644, 131648, - 131652, 131656, 131660, 131664, 131668, 131672, 131676, 131680, 131684, - 131688, 131692, 131696, 131700, 131704, 131708, 131712, 131716, 131720, - 131724, 131728, 131732, 131736, 131740, 131744, 131748, 131752, 131756, - 131760, 131764, 131768, 131772, 131776, 131780, 131784, 131788, 131792, - 131796, 131800, 131804, 131808, 131812, 131816, 131820, 131824, 131828, - 131832, 131836, 131840, 131844, 131848, 131852, 131856, 131860, 131864, - 131868, 131872, 131876, 131880, 131884, 131888, 131892, 131896, 131900, - 131904, 131908, 131912, 131916, 131920, 131924, 131928, 131932, 131936, - 131940, 131944, 131948, 131952, 131956, 131960, 131964, 131968, 131972, - 131976, 131980, 131984, 131988, 131992, 131996, 132000, 132004, 132008, - 132012, 132016, 132020, 132024, 132028, 132032, 132036, 132040, 132044, - 132048, 132052, 132056, 132060, 132064, 132068, 132072, 132076, 132080, - 132084, 132088, 132092, 132096, 132100, 132104, 132108, 132112, 132116, - 132120, 132124, 132128, 132132, 132136, 132140, 132144, 132148, 132152, - 132156, 132160, 132164, 132168, 132172, 132176, 132180, 132184, 132188, - 132192, 132196, 132200, 132204, 132208, 132212, 132216, 132220, 132224, - 132228, 132232, 132236, 132240, 132244, 132248, 132252, 132256, 132260, - 132264, 132268, 132272, 132276, 132280, 132284, 132288, 132292, 132296, - 132300, 132304, 132308, 132312, 132316, 132320, 132324, 132328, 132332, - 132336, 132340, 132344, 132348, 132352, 132356, 132360, 132364, 132368, - 132372, 132376, 132380, 132384, 132388, 132392, 132396, 132400, 132404, - 132408, 132412, 132416, 132420, 132424, 132428, 132432, 132436, 132440, - 132444, 132448, 132452, 132456, 132460, 132464, 132468, 132472, 132476, - 132480, 132484, 132488, 132492, 132496, 132500, 132504, 132508, 132512, - 132516, 132520, 132524, 132528, 132532, 132536, 132540, 132544, 132548, - 132552, 132556, 132560, 132564, 132568, 132572, 132576, 132580, 132584, - 132588, 132592, 132596, 132600, 132604, 132608, 132612, 132616, 132620, - 132624, 132628, 132632, 132636, 132640, 132644, 132648, 132652, 132656, - 132660, 132664, 132668, 132672, 132676, 132680, 132684, 132688, 132692, - 132696, 132700, 132704, 132708, 132712, 132716, 132720, 132724, 132728, - 132732, 132736, 132740, 132744, 132748, 132752, 132756, 132760, 132764, - 132768, 132772, 132776, 132780, 132784, 132788, 132792, 132796, 132800, - 132804, 132808, 132812, 132816, 132820, 132824, 132828, 132832, 132836, - 132840, 132844, 132848, 132852, 132856, 132860, 132864, 132868, 132872, - 132876, 132880, 132884, 132888, 132892, 132896, 132900, 132904, 132908, - 132912, 132916, 132920, 132924, 132928, 132932, 132936, 132940, 132944, - 132948, 132952, 132956, 132960, 132964, 132968, 132972, 132976, 132980, - 132984, 132988, 132992, 132996, 133000, 133004, 133008, 133012, 133016, - 133020, 133024, 133028, 133032, 133036, 133040, 133044, 133048, 133052, - 133056, 133060, 133064, 133068, 133072, 133076, 133080, 133084, 133088, - 133092, 133096, 133100, 133104, 133108, 133112, 133116, 133120, 133124, - 133128, 133132, 133136, 133140, 133144, 133148, 133152, 133156, 133160, - 133164, 133168, 133172, 133176, 133180, 133184, 133188, 133192, 133196, - 133200, 133204, 133208, 133212, 133216, 133220, 133224, 133228, 133232, - 133236, 133240, 133244, 133248, 133252, 133256, 133260, 133264, 133268, - 133272, 133276, 133280, 133284, 133288, 133292, 133296, 133300, 133304, - 133308, 133312, 133316, 133320, 133324, 133328, 133332, 133336, 133340, - 133344, 133348, 133352, 133356, 133360, 133364, 133368, 133372, 133376, - 133380, 133384, 133388, 133392, 133396, 133400, 133404, 133408, 133412, - 133416, 133420, 133424, 133428, 133432, 133436, 133440, 133444, 133448, - 133452, 133456, 133460, 133464, 133468, 133472, 133476, 133480, 133484, - 133488, 133492, 133496, 133500, 133504, 133508, 133512, 133516, 133520, - 133524, 133528, 133532, 133536, 133540, 133544, 133548, 133552, 133556, - 133560, 133564, 133568, 133572, 133576, 133580, 133584, 133588, 133592, - 133596, 133600, 133604, 133608, 133612, 133616, 133620, 133624, 133628, - 133632, 133636, 133640, 133644, 133648, 133652, 133656, 133660, 133664, - 133668, 133672, 133676, 133680, 133684, 133688, 133692, 133696, 133700, - 133704, 133708, 133712, 133716, 133720, 133724, 133728, 133732, 133736, - 133740, 133744, 133748, 133752, 133756, 133760, 133764, 133768, 133772, - 133776, 133780, 133784, 133788, 133792, 133796, 133800, 133804, 133808, - 133812, 133816, 133820, 133824, 133828, 133832, 133836, 133840, 133844, - 133848, 133852, 133856, 133860, 133864, 133868, 133872, 133876, 133880, - 133884, 133888, 133892, 133896, 133900, 133904, 133908, 133912, 133916, - 133920, 133924, 133928, 133932, 133936, 133940, 133944, 133948, 133952, - 133956, 133960, 133964, 133968, 133972, 133976, 133980, 133984, 133988, - 133992, 133996, 134000, 134004, 134008, 134012, 134016, 134020, 134024, - 134028, 134032, 134036, 134040, 134044, 134048, 134052, 134056, 134060, - 134064, 134068, 134072, 134076, 134080, 134084, 134088, 134092, 134096, - 134100, 134104, 134108, 134112, 134116, 134120, 134124, 134128, 134132, - 134136, 134140, 134144, 134148, 134152, 134156, 134160, 134164, 134168, - 134172, 134176, 134180, 134184, 134188, 134192, 134196, 134200, 134204, - 134208, 134212, 134216, 134220, 134224, 134228, 134232, 134236, 134240, - 134244, 134248, 134252, 134256, 134260, 134264, 134268, 134272, 134276, - 134280, 134284, 134288, 134292, 134296, 134300, 134304, 134308, 134312, - 134316, 134320, 134324, 134328, 134332, 134336, 134340, 134344, 134348, - 134352, 134356, 134360, 134364, 134368, 134372, 134376, 134380, 134384, - 134388, 134392, 134396, 134400, 134404, 134408, 134412, 134416, 134420, - 134424, 134428, 134432, 134436, 134440, 134444, 134448, 134452, 134456, - 134460, 134464, 134468, 134472, 134476, 134480, 134484, 134488, 134492, - 134496, 134500, 134504, 134508, 134512, 134516, 134520, 134524, 134528, - 134532, 134536, 134540, 134544, 134548, 134552, 134556, 134560, 134564, - 134568, 134572, 134576, 134580, 134584, 134588, 134592, 134596, 134600, - 134604, 134608, 134612, 134616, 134620, 134624, 134628, 134632, 134636, - 134640, 134644, 134648, 134652, 134656, 134660, 134664, 134668, 134672, - 134676, 134680, 134684, 134688, 134692, 134696, 134700, 134704, 134708, - 134712, 134716, 134720, 134724, 134728, 134732, 134736, 134740, 134744, - 134748, 134752, 134756, 134760, 134764, 134768, 134772, 134776, 134780, - 134784, 0, 134788, 134793, 134799, 134809, 134819, 134829, 134839, - 134845, 134851, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 134857, 134861, 134865, 134869, 134873, 134877, 134881, - 134885, 134889, 134893, 134897, 134901, 134905, 134909, 134913, 134917, - 134921, 134925, 134929, 134933, 134937, 134941, 134945, 134949, 134953, - 134957, 134961, 134965, 134969, 134973, 134977, 134981, 134985, 134989, - 134993, 134997, 135001, 135005, 135009, 135013, 135017, 135021, 135025, - 135029, 135033, 135037, 135041, 135045, 135049, 135053, 135057, 135061, - 135065, 135069, 135073, 135077, 135081, 135085, 135089, 135093, 135097, - 135101, 135105, 135109, 135113, 135117, 135121, 135125, 135129, 135133, - 135137, 135141, 135145, 135149, 135153, 135157, 135161, 135165, 135169, - 135173, 135177, 135181, 135185, 135189, 135193, 135197, 135201, 135205, - 135209, 135213, 135217, 135221, 135225, 135229, 135233, 135237, 135241, - 135245, 135249, 135253, 135257, 135261, 135265, 135269, 135273, 135277, - 135281, 135285, 135289, 135293, 135297, 135301, 135305, 135309, 135313, - 135317, 135321, 135325, 135329, 135333, 135337, 135341, 135345, 135349, - 135353, 135357, 135361, 135365, 135369, 135373, 135377, 135381, 135385, - 135389, 135393, 135397, 135401, 135405, 135409, 135413, 135417, 135421, - 135425, 135429, 135433, 135437, 135441, 135445, 135449, 135453, 135457, - 135461, 135465, 135469, 135473, 135477, 135481, 135485, 135489, 135493, - 135497, 135501, 135505, 135509, 135513, 135517, 135521, 135525, 135529, - 135533, 135537, 135541, 135545, 135549, 135553, 135557, 135561, 135565, - 135569, 135573, 135577, 135581, 135585, 135589, 135593, 135597, 135601, - 135605, 135609, 135613, 135617, 135621, 135625, 135629, 135633, 135637, - 135641, 135645, 135649, 135653, 135657, 135661, 135665, 135669, 135673, - 135677, 135681, 135685, 135689, 135693, 135697, 135701, 135705, 135709, - 135713, 135717, 135721, 135725, 135729, 135733, 135737, 135741, 135745, - 135749, 135753, 135757, 135761, 135765, 135769, 135773, 135777, 135781, - 135785, 135789, 135793, 135797, 135801, 135805, 135809, 135813, 135817, - 135821, 135825, 135829, 135833, 135837, 135841, 135845, 135849, 135853, - 135857, 135861, 135865, 135869, 135873, 135877, 135881, 135885, 135889, - 135893, 135897, 135901, 135905, 135909, 135913, 135917, 135921, 135925, - 135929, 135933, 135937, 135941, 135945, 135949, 135953, 135957, 135961, - 135965, 135969, 135973, 135977, 135981, 135985, 135989, 135993, 135997, - 136001, 136005, 136009, 136013, 136017, 136021, 136025, 136029, 136033, - 136037, 136041, 136045, 136049, 136053, 136057, 136061, 136065, 136069, - 136073, 136077, 136081, 136085, 136089, 136093, 136097, 136101, 136105, - 136109, 136113, 136117, 136121, 136125, 136129, 136133, 136137, 136141, - 136145, 136149, 136153, 136157, 136161, 136165, 136169, 136173, 136177, - 136181, 136185, 136189, 136193, 136197, 136201, 136205, 136209, 136213, - 136217, 136221, 136225, 136229, 136233, 136237, 136241, 136245, 136249, - 136253, 136257, 136261, 136265, 136269, 136273, 136277, 136281, 136285, - 136289, 136293, 136297, 136301, 136305, 136309, 136313, 136317, 136321, - 136325, 136329, 136333, 136337, 136341, 136345, 136349, 136353, 136357, - 136361, 136365, 136369, 136373, 136377, 136381, 136385, 136389, 136393, - 136397, 136401, 136405, 136409, 136413, 136417, 136421, 136425, 136429, - 136433, 136437, 136441, 136445, 136449, 136453, 136457, 136461, 136465, - 136469, 136473, 136477, 136481, 136485, 136489, 136493, 136497, 136501, - 136505, 136509, 136513, 136517, 136521, 136525, 136529, 136533, 136537, - 136541, 136545, 136549, 136553, 136557, 136561, 136565, 136569, 136573, - 136577, 136581, 136585, 136589, 136599, 136603, 136607, 136611, 136615, - 136619, 136623, 136627, 136631, 136635, 136639, 136643, 136648, 136652, - 136656, 136660, 136664, 136668, 136672, 136676, 136680, 136684, 136688, - 136692, 136696, 136700, 136704, 136708, 136712, 136721, 136730, 136734, - 136738, 136742, 136746, 136750, 136754, 136758, 136762, 136766, 136770, - 136774, 136778, 136782, 136786, 136790, 136794, 136798, 136802, 136806, - 136810, 136814, 136818, 136822, 136826, 136830, 136834, 136838, 136842, - 136846, 136850, 136854, 136858, 136862, 136866, 136870, 136874, 136878, - 136882, 136886, 136890, 136894, 136898, 136902, 136906, 136910, 136914, - 136918, 136922, 136926, 136930, 136934, 136938, 136942, 136946, 136950, - 136954, 136958, 136962, 136966, 136970, 136974, 136978, 136982, 136986, - 136990, 136994, 136998, 137002, 137006, 137010, 137014, 137018, 137022, - 137026, 137030, 137034, 137038, 137042, 137046, 137050, 137054, 137058, - 137062, 137066, 137070, 137074, 137078, 137082, 137086, 137090, 137094, - 137098, 137102, 137106, 137110, 137114, 137118, 137122, 137126, 137130, - 137134, 137138, 137142, 137146, 137150, 137154, 137158, 137162, 137166, - 137170, 137174, 137178, 137182, 137186, 137190, 137194, 137198, 137202, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 137206, 137214, 137222, 137232, 137242, - 137250, 137256, 137264, 137272, 137282, 137294, 137306, 137312, 137320, - 137326, 137332, 137338, 137344, 137350, 137356, 137362, 137368, 137374, - 137380, 137386, 137394, 137402, 137408, 137414, 137420, 137426, 137434, - 137442, 137451, 137457, 137465, 137471, 137477, 137483, 137489, 137495, - 137503, 137511, 137517, 137523, 137529, 137535, 137541, 137547, 137553, - 137559, 137565, 137571, 137577, 137583, 137589, 137595, 137601, 137607, - 137613, 137619, 137625, 137633, 137639, 137645, 137655, 137663, 137669, - 137675, 137681, 137687, 137693, 137699, 137705, 137711, 137717, 137723, - 137729, 137735, 137741, 137747, 137753, 137759, 137765, 137771, 137777, - 137783, 137789, 137795, 137803, 137809, 137817, 137825, 137833, 137839, - 137845, 137851, 137857, 137863, 137871, 137881, 137889, 137897, 137903, - 137909, 137917, 137925, 137931, 137939, 137947, 137955, 137961, 137967, - 137973, 137979, 137985, 137991, 137999, 138007, 138013, 138019, 138025, - 138031, 138037, 138045, 138051, 138057, 138063, 138069, 138075, 138081, - 138089, 138095, 138101, 138107, 138113, 138121, 138129, 138135, 138141, - 138147, 138152, 138158, 138164, 138172, 138178, 138184, 138190, 138196, - 138202, 138208, 138214, 138220, 138226, 138236, 138244, 138250, 138256, - 138262, 138270, 138276, 138282, 138288, 138296, 138302, 138308, 138314, - 138320, 138326, 138332, 138338, 138344, 138350, 138356, 138362, 138370, - 138376, 138384, 138390, 138396, 138404, 138410, 138416, 138422, 138428, - 138434, 138440, 138446, 138452, 138458, 138464, 138470, 138476, 138482, - 138488, 138494, 138500, 138506, 138512, 138518, 138526, 138532, 138538, - 138544, 138550, 138556, 138562, 138568, 138574, 138580, 138586, 138592, - 138598, 138604, 138612, 138618, 138624, 138632, 138638, 138644, 138650, - 138656, 138662, 138668, 138674, 138680, 138686, 138692, 138700, 138706, - 138712, 138718, 138724, 138730, 138738, 138746, 138752, 138758, 138764, - 138770, 138776, 138782, 138787, 138792, 138797, 138802, 138807, 138812, - 138817, 138822, 138827, 138832, 138837, 138842, 138847, 138852, 138857, - 138862, 138867, 138872, 138877, 138882, 138887, 138892, 138897, 138902, - 138907, 138912, 138917, 138922, 138927, 138932, 138939, 138944, 138949, - 138954, 138959, 138964, 138969, 138974, 138979, 138984, 138989, 138994, - 138999, 139004, 139009, 139014, 139019, 139024, 139029, 139034, 139039, - 139044, 139049, 139054, 139059, 139064, 139069, 139074, 139079, 139084, - 139089, 139094, 139099, 139104, 139109, 139114, 139119, 139124, 139129, - 139134, 139139, 139144, 139149, 139154, 139159, 139164, 139169, 139174, - 139179, 139184, 139189, 139194, 139199, 139204, 139209, 139214, 139219, - 139224, 139229, 139236, 139241, 139246, 139251, 139256, 139261, 139266, - 139271, 139276, 139281, 139286, 139291, 139296, 139301, 139306, 139311, - 139316, 139321, 139326, 139331, 139336, 139341, 139348, 139353, 139358, - 139364, 139369, 139374, 139379, 139384, 139389, 139394, 139399, 139404, - 139409, 139414, 139419, 139424, 139429, 139434, 139439, 139444, 139449, - 139454, 139459, 139464, 139469, 139474, 139479, 139484, 139489, 139494, - 139499, 139504, 139509, 139514, 139519, 139524, 139529, 139534, 139539, - 139544, 139549, 139554, 139559, 139564, 139569, 139574, 139579, 139586, - 139591, 139596, 139603, 139610, 139615, 139620, 139625, 139630, 139635, - 139640, 139645, 139650, 139655, 139660, 139665, 139670, 139675, 139680, - 139685, 139690, 139695, 139700, 139705, 139710, 139715, 139720, 139725, - 139730, 139735, 139742, 139747, 139752, 139757, 139762, 139767, 139772, - 139777, 139782, 139787, 139792, 139797, 139802, 139807, 139812, 139817, - 139822, 139827, 139832, 139839, 139844, 139849, 139854, 139859, 139864, - 139869, 139874, 139880, 139885, 139890, 139895, 139900, 139905, 139910, - 139915, 139920, 139927, 139934, 139939, 139944, 139948, 139953, 139957, - 139961, 139966, 139973, 139978, 139983, 139992, 139997, 140002, 140007, - 140012, 140019, 140026, 140031, 140036, 140041, 140046, 140053, 140058, - 140063, 140068, 140073, 140078, 140083, 140088, 140093, 140098, 140103, - 140108, 140113, 140120, 140124, 140129, 140134, 140139, 140144, 140148, - 140153, 140158, 140163, 140168, 140173, 140178, 140183, 140188, 140193, - 140199, 140205, 140211, 140217, 140223, 140228, 140234, 140240, 140246, - 140252, 140258, 140264, 140270, 140276, 140282, 140288, 140294, 140300, - 140306, 140312, 140318, 140324, 140330, 140336, 140341, 140347, 140353, - 140359, 140365, 140371, 140377, 140383, 140389, 140395, 140401, 140407, - 140413, 140419, 140425, 140431, 140437, 140443, 140449, 140455, 140461, - 140466, 140472, 140478, 140484, 140490, 140496, 0, 0, 0, 0, 0, 0, 0, - 140502, 140507, 140512, 140517, 140522, 140527, 140532, 140536, 140541, - 140546, 140551, 140556, 140561, 140566, 140571, 140576, 140581, 140585, - 140590, 140594, 140599, 140604, 140609, 140614, 140619, 140623, 140628, - 140633, 140637, 140642, 140647, 0, 140652, 140657, 140661, 140665, - 140669, 140673, 140677, 140681, 140685, 140689, 0, 0, 0, 0, 140693, - 140697, 140702, 140707, 140712, 140717, 140722, 140727, 140732, 140737, - 140742, 140747, 140752, 140757, 140762, 140767, 140772, 140777, 140782, - 140787, 140792, 140797, 140802, 140807, 140812, 140817, 140822, 140827, - 140832, 140837, 140842, 140847, 140852, 140857, 140862, 140868, 140874, - 140881, 140888, 140893, 140898, 140903, 140908, 140913, 140918, 140923, - 140928, 140933, 140938, 140943, 140948, 140952, 140957, 140962, 140967, - 140971, 140975, 140980, 140984, 140989, 140994, 140999, 141003, 141007, - 141011, 141015, 141020, 141025, 141030, 141034, 141039, 141044, 141049, - 141054, 141059, 141064, 141069, 141074, 141079, 141084, 141089, 0, - 141094, 141099, 141103, 141107, 141111, 141115, 141119, 141123, 141127, - 141131, 0, 0, 0, 0, 0, 0, 141135, 141142, 141148, 141155, 141162, 141169, - 141176, 141183, 141190, 141197, 141204, 141211, 141218, 141225, 141232, - 141239, 141246, 141253, 141259, 141266, 141273, 141280, 141286, 141293, - 141299, 141305, 141312, 141318, 141325, 141331, 0, 0, 141337, 141345, - 141353, 141362, 141371, 141380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141388, - 141393, 141398, 141403, 141408, 141413, 141418, 141423, 141428, 141433, - 141438, 141443, 141448, 141453, 141458, 141463, 141468, 141473, 141478, - 141483, 141488, 141493, 141498, 141503, 141508, 141513, 141518, 141523, - 141528, 141533, 141538, 141543, 141548, 141553, 141558, 141563, 141568, - 141573, 141578, 141583, 141588, 141593, 141598, 141603, 141608, 141613, - 141618, 141623, 141628, 141635, 141642, 141649, 141656, 141663, 141670, - 141677, 141684, 141693, 141700, 141707, 141714, 141721, 141728, 141735, - 141742, 141749, 141756, 141763, 141770, 141775, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 141784, 141789, 141793, 141797, 141801, 141805, 141809, 141813, - 141817, 141821, 0, 141825, 141830, 141835, 141842, 141847, 141854, - 141861, 0, 141866, 141873, 141878, 141883, 141890, 141897, 141902, - 141907, 141912, 141917, 141922, 141929, 141936, 141941, 141946, 141951, - 141964, 141973, 141980, 141989, 141998, 0, 0, 0, 0, 0, 142007, 142014, - 142021, 142028, 142035, 142042, 142049, 142056, 142063, 142070, 142077, - 142084, 142091, 142098, 142105, 142112, 142119, 142126, 142133, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 142140, 142146, 142152, 142158, 142164, 142170, 142176, - 142182, 142188, 142194, 142200, 142206, 142211, 142217, 142222, 142228, - 142233, 142239, 142245, 142250, 142256, 142261, 142267, 142273, 142279, - 142285, 142291, 142297, 142303, 142308, 142313, 142319, 142325, 142331, - 142337, 142343, 142349, 142355, 142361, 142367, 142373, 142379, 142385, - 142391, 142396, 142402, 142407, 142413, 142418, 142424, 142430, 142435, - 142441, 142446, 142452, 142458, 142464, 142470, 142476, 142482, 142488, - 142493, 142498, 142504, 142510, 142515, 142519, 142523, 142527, 142531, - 142535, 142539, 142543, 142547, 142551, 142556, 142561, 142566, 142571, - 142576, 142581, 142586, 142591, 142596, 142601, 142608, 142615, 142622, - 142626, 142632, 142637, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142643, 142646, 142650, 142654, - 142658, 142661, 142665, 142670, 142674, 142678, 142682, 142686, 142690, - 142695, 142700, 142704, 142708, 142711, 142715, 142720, 142725, 142729, - 142733, 142736, 142740, 142744, 142748, 142752, 142756, 142760, 142764, - 142767, 142771, 142775, 142779, 142783, 142787, 142791, 142797, 142800, - 142804, 142808, 142812, 142816, 142820, 142824, 142828, 142832, 142836, - 142841, 142846, 142852, 142856, 142860, 142864, 142868, 142872, 142876, - 142881, 142884, 142888, 142892, 142896, 142900, 142906, 142910, 142914, - 142918, 142922, 142926, 142930, 142934, 142938, 142942, 142946, 0, 0, 0, - 0, 142950, 142955, 142959, 142963, 142969, 142975, 142979, 142984, - 142989, 142994, 142999, 143003, 143008, 143013, 143018, 143022, 143027, - 143032, 143037, 143041, 143046, 143051, 143056, 143061, 143066, 143071, - 143076, 143081, 143085, 143090, 143095, 143100, 143105, 143110, 143115, - 143120, 143125, 143130, 143135, 143140, 143147, 143152, 143159, 143164, - 143169, 143174, 143179, 143184, 143189, 143194, 143199, 143204, 143209, - 143214, 143219, 143224, 143229, 0, 0, 0, 0, 0, 0, 0, 143234, 143237, - 143242, 143245, 143248, 143252, 143256, 143260, 143264, 143268, 143272, - 143276, 143282, 143288, 143294, 143300, 143306, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 143312, 143316, 143320, 143326, 143332, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 143337, 143346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 143355, 143358, 143361, 143364, 143367, 143370, 143373, 143376, - 143379, 143382, 143385, 143388, 143391, 143394, 143397, 143400, 143403, - 143406, 143409, 143412, 143415, 143418, 143421, 143424, 143427, 143430, - 143433, 143436, 143439, 143442, 143445, 143448, 143451, 143454, 143457, - 143460, 143463, 143466, 143469, 143472, 143475, 143478, 143481, 143484, - 143487, 143490, 143493, 143496, 143499, 143502, 143505, 143508, 143511, - 143514, 143517, 143520, 143523, 143526, 143529, 143532, 143535, 143538, - 143541, 143544, 143547, 143550, 143553, 143556, 143559, 143562, 143565, - 143568, 143571, 143574, 143577, 143580, 143583, 143586, 143589, 143592, - 143595, 143598, 143601, 143604, 143607, 143610, 143613, 143616, 143619, - 143622, 143625, 143628, 143631, 143634, 143637, 143640, 143643, 143646, - 143649, 143652, 143655, 143658, 143661, 143664, 143667, 143670, 143673, - 143676, 143679, 143682, 143685, 143688, 143691, 143694, 143697, 143700, - 143703, 143706, 143709, 143712, 143715, 143718, 143721, 143724, 143727, - 143730, 143733, 143736, 143739, 143742, 143745, 143748, 143751, 143754, - 143757, 143760, 143763, 143766, 143769, 143772, 143775, 143778, 143781, - 143784, 143787, 143790, 143793, 143796, 143799, 143802, 143805, 143808, - 143811, 143814, 143817, 143820, 143823, 143826, 143829, 143832, 143835, - 143838, 143841, 143844, 143847, 143850, 143853, 143856, 143859, 143862, - 143865, 143868, 143871, 143874, 143877, 143880, 143883, 143886, 143889, - 143892, 143895, 143898, 143901, 143904, 143907, 143910, 143913, 143916, - 143919, 143922, 143925, 143928, 143931, 143934, 143937, 143940, 143943, - 143946, 143949, 143952, 143955, 143958, 143961, 143964, 143967, 143970, - 143973, 143976, 143979, 143982, 143985, 143988, 143991, 143994, 143997, - 144000, 144003, 144006, 144009, 144012, 144015, 144018, 144021, 144024, - 144027, 144030, 144033, 144036, 144039, 144042, 144045, 144048, 144051, - 144054, 144057, 144060, 144063, 144066, 144069, 144072, 144075, 144078, - 144081, 144084, 144087, 144090, 144093, 144096, 144099, 144102, 144105, - 144108, 144111, 144114, 144117, 144120, 144123, 144126, 144129, 144132, - 144135, 144138, 144141, 144144, 144147, 144150, 144153, 144156, 144159, - 144162, 144165, 144168, 144171, 144174, 144177, 144180, 144183, 144186, - 144189, 144192, 144195, 144198, 144201, 144204, 144207, 144210, 144213, - 144216, 144219, 144222, 144225, 144228, 144231, 144234, 144237, 144240, - 144243, 144246, 144249, 144252, 144255, 144258, 144261, 144264, 144267, - 144270, 144273, 144276, 144279, 144282, 144285, 144288, 144291, 144294, - 144297, 144300, 144303, 144306, 144309, 144312, 144315, 144318, 144321, - 144324, 144327, 144330, 144333, 144336, 144339, 144342, 144345, 144348, - 144351, 144354, 144357, 144360, 144363, 144366, 144369, 144372, 144375, - 144378, 144381, 144384, 144387, 144390, 144393, 144396, 144399, 144402, - 144405, 144408, 144411, 144414, 144417, 144420, 144423, 144426, 144429, - 144432, 144435, 144438, 144441, 144444, 144447, 144450, 144453, 144456, - 144459, 144462, 144465, 144468, 144471, 144474, 144477, 144480, 144483, - 144486, 144489, 144492, 144495, 144498, 144501, 144504, 144507, 144510, - 144513, 144516, 144519, 144522, 144525, 144528, 144531, 144534, 144537, - 144540, 144543, 144546, 144549, 144552, 144555, 144558, 144561, 144564, - 144567, 144570, 144573, 144576, 144579, 144582, 144585, 144588, 144591, - 144594, 144597, 144600, 144603, 144606, 144609, 144612, 144615, 144618, - 144621, 144624, 144627, 144630, 144633, 144636, 144639, 144642, 144645, - 144648, 144651, 144654, 144657, 144660, 144663, 144666, 144669, 144672, - 144675, 144678, 144681, 144684, 144687, 144690, 144693, 144696, 144699, - 144702, 144705, 144708, 144711, 144714, 144717, 144720, 144723, 144726, - 144729, 144732, 144735, 144738, 144741, 144744, 144747, 144750, 144753, - 144756, 144759, 144762, 144765, 144768, 144771, 144774, 144777, 144780, - 144783, 144786, 144789, 144792, 144795, 144798, 144801, 144804, 144807, - 144810, 144813, 144816, 144819, 144822, 144825, 144828, 144831, 144834, - 144837, 144840, 144843, 144846, 144849, 144852, 144855, 144858, 144861, - 144864, 144867, 144870, 144873, 144876, 144879, 144882, 144885, 144888, - 144891, 144894, 144897, 144900, 144903, 144906, 144909, 144912, 144915, - 144918, 144921, 144924, 144927, 144930, 144933, 144936, 144939, 144942, - 144945, 144948, 144951, 144954, 144957, 144960, 144963, 144966, 144969, - 144972, 144975, 144978, 144981, 144984, 144987, 144990, 144993, 144996, - 144999, 145002, 145005, 145008, 145011, 145014, 145017, 145020, 145023, - 145026, 145029, 145032, 145035, 145038, 145041, 145044, 145047, 145050, - 145053, 145056, 145059, 145062, 145065, 145068, 145071, 145074, 145077, - 145080, 145083, 145086, 145089, 145092, 145095, 145098, 145101, 145104, - 145107, 145110, 145113, 145116, 145119, 145122, 145125, 145128, 145131, - 145134, 145137, 145140, 145143, 145146, 145149, 145152, 145155, 145158, - 145161, 145164, 145167, 145170, 145173, 145176, 145179, 145182, 145185, - 145188, 145191, 145194, 145197, 145200, 145203, 145206, 145209, 145212, - 145215, 145218, 145221, 145224, 145227, 145230, 145233, 145236, 145239, - 145242, 145245, 145248, 145251, 145254, 145257, 145260, 145263, 145266, - 145269, 145272, 145275, 145278, 145281, 145284, 145287, 145290, 145293, - 145296, 145299, 145302, 145305, 145308, 145311, 145314, 145317, 145320, - 145323, 145326, 145329, 145332, 145335, 145338, 145341, 145344, 145347, - 145350, 145353, 145356, 145359, 145362, 145365, 145368, 145371, 145374, - 145377, 145380, 145383, 145386, 145389, 145392, 145395, 145398, 145401, - 145404, 145407, 145410, 145413, 145416, 145419, 145422, 145425, 145428, - 145431, 145434, 145437, 145440, 145443, 145446, 145449, 145452, 145455, - 145458, 145461, 145464, 145467, 145470, 145473, 145476, 145479, 145482, - 145485, 145488, 145491, 145494, 145497, 145500, 145503, 145506, 145509, - 145512, 145515, 145518, 145521, 145524, 145527, 145530, 145533, 145536, - 145539, 145542, 145545, 145548, 145551, 145554, 145557, 145560, 145563, - 145566, 145569, 145572, 145575, 145578, 145581, 145584, 145587, 145590, - 145593, 145596, 145599, 145602, 145605, 145608, 145611, 145614, 145617, - 145620, 145623, 145626, 145629, 145632, 145635, 145638, 145641, 145644, - 145647, 145650, 145653, 145656, 145659, 145664, 145669, 145674, 145679, - 145684, 145689, 145694, 145699, 145704, 145709, 145714, 145719, 145724, - 145729, 145734, 145739, 145744, 145749, 145754, 145759, 145764, 145769, - 145774, 145779, 145784, 145789, 145794, 145799, 145804, 145809, 145814, - 145819, 145824, 145829, 145834, 145839, 145844, 145849, 145854, 145859, - 145864, 145869, 145874, 145879, 145884, 145889, 145894, 145899, 145904, - 145909, 145914, 145919, 145924, 145929, 145934, 145939, 145944, 145949, - 145954, 145959, 145964, 145969, 145974, 145979, 145984, 145989, 145994, - 145999, 146004, 146009, 146014, 146019, 146024, 146029, 146034, 146039, - 146044, 146049, 146054, 146059, 146064, 146069, 146074, 146079, 146084, - 146089, 146094, 146099, 146104, 146109, 146114, 146119, 146124, 146129, - 146134, 146139, 146144, 146149, 146154, 146159, 146164, 146169, 146174, - 146179, 146184, 146189, 146194, 146199, 146204, 146209, 146214, 146219, - 146224, 146229, 146234, 146239, 146244, 146249, 146254, 146259, 146264, - 146269, 146274, 146279, 146284, 146289, 146294, 146299, 146304, 146309, - 146314, 146319, 146324, 146329, 146334, 146339, 146344, 146349, 146354, - 146359, 146364, 146369, 146374, 146379, 146384, 146389, 146394, 146399, - 146404, 146409, 146414, 146419, 146424, 146429, 146434, 146439, 146444, - 146449, 146454, 146459, 146464, 146469, 146474, 146479, 146484, 146489, - 146494, 146499, 146504, 146509, 146514, 146519, 146524, 146529, 146534, - 146539, 146544, 146549, 146554, 146559, 146564, 146569, 146574, 146579, - 146584, 146589, 146594, 146599, 146604, 146609, 146614, 146619, 146624, - 146629, 146634, 146639, 146644, 146649, 146654, 146659, 146664, 146669, - 146674, 146679, 146684, 146689, 146694, 146699, 146704, 146709, 146714, - 146719, 146724, 146729, 146734, 146739, 146744, 146749, 146754, 146759, - 146764, 146769, 146774, 146779, 146784, 146789, 146794, 146799, 146804, - 146809, 146814, 146819, 146824, 146829, 146834, 146839, 146844, 146849, - 146854, 146859, 146864, 146869, 146874, 146879, 146884, 146889, 146894, - 146899, 146904, 146909, 146914, 146919, 146924, 146929, 146934, 146939, - 146944, 146949, 146954, 146959, 146964, 146969, 146974, 146979, 146984, - 146989, 146994, 146999, 147004, 147009, 147014, 147019, 147024, 147029, - 147034, 147039, 147044, 147049, 147054, 147059, 147064, 147069, 147074, - 147079, 147084, 147089, 147094, 147099, 147104, 147109, 147114, 147119, - 147124, 147129, 147134, 147139, 147144, 147149, 147154, 147159, 147164, - 147169, 147174, 147179, 147184, 147189, 147194, 147199, 147204, 147209, - 147214, 147219, 147224, 147229, 147234, 147239, 147244, 147249, 147254, - 147259, 147264, 147269, 147274, 147279, 147284, 147289, 147294, 147299, - 147304, 147309, 147314, 147319, 147324, 147329, 147334, 147339, 147344, - 147349, 147354, 147359, 147364, 147369, 147374, 147379, 147384, 147389, - 147394, 147399, 147404, 147409, 147414, 147419, 147424, 147429, 147434, - 147439, 147444, 147449, 147454, 147459, 147464, 147469, 147474, 147479, - 147484, 147489, 147494, 147499, 147504, 147509, 147514, 147519, 147524, - 147529, 147534, 147539, 147544, 147549, 147554, 147559, 147564, 147569, - 147574, 147579, 147584, 147589, 147594, 147599, 147604, 147609, 147614, - 147619, 147624, 147629, 147634, 147639, 147644, 147649, 147654, 147659, - 147664, 147669, 147674, 147679, 147684, 147689, 147694, 147699, 147704, - 147709, 147714, 147719, 147724, 147729, 147734, 147739, 147744, 147749, - 147754, 147759, 147764, 147769, 147774, 147779, 147784, 147789, 147794, - 147799, 147804, 147809, 147814, 147819, 147824, 147829, 147834, 147839, - 147844, 147849, 147854, 147859, 147864, 147869, 147874, 147879, 147884, - 147889, 147894, 147899, 147904, 147909, 147914, 147919, 147924, 147929, - 147934, 147939, 147944, 147949, 147954, 147959, 147964, 147969, 147974, - 147979, 147984, 147989, 147994, 147999, 148004, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 148009, 148015, 148021, 148027, 0, 148033, 148039, 148045, 148053, - 148061, 148069, 148077, 0, 148085, 148093, 0, 148101, 148106, 148113, - 148117, 148121, 148125, 148129, 148133, 148137, 148141, 148145, 148149, - 148153, 148157, 148161, 148165, 148169, 148173, 148177, 148181, 148185, - 148189, 148193, 148197, 148201, 148205, 148209, 148213, 148217, 148221, - 148225, 148229, 148233, 148237, 148241, 148245, 148249, 148253, 148257, - 148261, 148265, 148269, 148273, 148277, 148281, 148285, 148289, 148293, - 148297, 148301, 148305, 148309, 148313, 148317, 148321, 148325, 148329, - 148333, 148337, 148341, 148345, 148349, 148353, 148357, 148361, 148365, - 148369, 148373, 148377, 148381, 148385, 148389, 148393, 148397, 148401, - 148405, 148409, 148413, 148417, 148421, 148425, 148429, 148433, 148437, - 148441, 148445, 148449, 148453, 148457, 148461, 148465, 148469, 148473, - 148477, 148481, 148485, 148489, 148493, 148497, 148501, 148505, 148509, - 148513, 148517, 148521, 148525, 148529, 148533, 148537, 148541, 148545, - 148549, 148553, 148557, 148561, 148565, 148569, 148573, 148577, 148581, - 148585, 148589, 148593, 148597, 148601, 148605, 148609, 148613, 148617, - 148621, 148625, 148629, 148633, 148637, 148641, 148645, 148649, 148653, - 148657, 148661, 148665, 148669, 148673, 148677, 148681, 148685, 148689, - 148693, 148697, 148701, 148705, 148709, 148713, 148717, 148721, 148725, - 148729, 148733, 148737, 148741, 148745, 148749, 148753, 148757, 148761, - 148765, 148769, 148773, 148777, 148781, 148785, 148789, 148793, 148797, - 148801, 148805, 148809, 148813, 148817, 148821, 148825, 148829, 148833, - 148837, 148841, 148845, 148849, 148853, 148857, 148861, 148865, 148869, - 148873, 148877, 148881, 148885, 148889, 148893, 148897, 148901, 148905, - 148909, 148913, 148917, 148921, 148925, 148929, 148933, 148937, 148941, - 148945, 148949, 148953, 148957, 148961, 148965, 148969, 148973, 148977, - 148981, 148985, 148989, 148993, 148997, 149001, 149005, 149009, 149013, - 149017, 149021, 149025, 149029, 149033, 149037, 149041, 149045, 149049, - 149053, 149057, 149061, 149065, 149069, 149073, 149077, 149081, 149085, - 149089, 149093, 149097, 149101, 149105, 149109, 149113, 149117, 149121, - 149125, 149129, 149133, 149137, 149141, 149145, 149149, 149153, 149157, - 149161, 149165, 149169, 149173, 149177, 149181, 149185, 149189, 149193, - 149197, 149201, 149205, 149209, 149213, 149217, 149221, 149225, 149229, - 149233, 149237, 149241, 149245, 149249, 149253, 149260, 149266, 149272, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149278, - 149284, 149290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 149296, 149301, 149306, 149311, 0, 0, 0, 0, 0, 0, 0, 0, 149316, 149319, - 149322, 149325, 149328, 149331, 149334, 149337, 149340, 149343, 149346, - 149349, 149352, 149355, 149358, 149361, 149364, 149367, 149370, 149373, - 149376, 149379, 149382, 149385, 149388, 149391, 149394, 149397, 149400, - 149403, 149406, 149409, 149412, 149415, 149418, 149421, 149424, 149427, - 149430, 149433, 149436, 149439, 149442, 149445, 149448, 149451, 149454, - 149457, 149460, 149463, 149466, 149469, 149472, 149475, 149478, 149481, - 149484, 149487, 149490, 149493, 149496, 149499, 149502, 149505, 149508, - 149511, 149514, 149517, 149520, 149523, 149526, 149529, 149532, 149535, - 149538, 149541, 149544, 149547, 149550, 149553, 149556, 149559, 149562, - 149565, 149568, 149571, 149574, 149577, 149580, 149583, 149586, 149589, - 149592, 149595, 149598, 149601, 149604, 149607, 149610, 149613, 149616, - 149619, 149622, 149625, 149628, 149631, 149634, 149637, 149640, 149643, - 149646, 149649, 149652, 149655, 149658, 149661, 149664, 149667, 149670, - 149673, 149676, 149679, 149682, 149685, 149688, 149691, 149694, 149697, - 149700, 149703, 149706, 149709, 149712, 149715, 149718, 149721, 149724, - 149727, 149730, 149733, 149736, 149739, 149742, 149745, 149748, 149751, - 149754, 149757, 149760, 149763, 149766, 149769, 149772, 149775, 149778, - 149781, 149784, 149787, 149790, 149793, 149796, 149799, 149802, 149805, - 149808, 149811, 149814, 149817, 149820, 149823, 149826, 149829, 149832, - 149835, 149838, 149841, 149844, 149847, 149850, 149853, 149856, 149859, - 149862, 149865, 149868, 149871, 149874, 149877, 149880, 149883, 149886, - 149889, 149892, 149895, 149898, 149901, 149904, 149907, 149910, 149913, - 149916, 149919, 149922, 149925, 149928, 149931, 149934, 149937, 149940, - 149943, 149946, 149949, 149952, 149955, 149958, 149961, 149964, 149967, - 149970, 149973, 149976, 149979, 149982, 149985, 149988, 149991, 149994, - 149997, 150000, 150003, 150006, 150009, 150012, 150015, 150018, 150021, - 150024, 150027, 150030, 150033, 150036, 150039, 150042, 150045, 150048, - 150051, 150054, 150057, 150060, 150063, 150066, 150069, 150072, 150075, - 150078, 150081, 150084, 150087, 150090, 150093, 150096, 150099, 150102, - 150105, 150108, 150111, 150114, 150117, 150120, 150123, 150126, 150129, - 150132, 150135, 150138, 150141, 150144, 150147, 150150, 150153, 150156, - 150159, 150162, 150165, 150168, 150171, 150174, 150177, 150180, 150183, - 150186, 150189, 150192, 150195, 150198, 150201, 150204, 150207, 150210, - 150213, 150216, 150219, 150222, 150225, 150228, 150231, 150234, 150237, - 150240, 150243, 150246, 150249, 150252, 150255, 150258, 150261, 150264, - 150267, 150270, 150273, 150276, 150279, 150282, 150285, 150288, 150291, - 150294, 150297, 150300, 150303, 150306, 150309, 150312, 150315, 150318, - 150321, 150324, 150327, 150330, 150333, 150336, 150339, 150342, 150345, - 150348, 150351, 150354, 150357, 150360, 150363, 150366, 150369, 150372, - 150375, 150378, 150381, 150384, 150387, 150390, 150393, 150396, 150399, - 150402, 150405, 150408, 150411, 150414, 150417, 150420, 150423, 150426, - 150429, 150432, 150435, 150438, 150441, 150444, 150447, 150450, 150453, - 150456, 150459, 150462, 150465, 150468, 150471, 150474, 150477, 150480, - 150483, 150486, 150489, 150492, 150495, 150498, 150501, 0, 0, 0, 0, - 150504, 150508, 150512, 150516, 150520, 150524, 150528, 150531, 150535, - 150539, 150543, 150547, 150550, 150556, 150562, 150568, 150574, 150580, - 150584, 150590, 150594, 150598, 150604, 150608, 150612, 150616, 150620, - 150624, 150628, 150632, 150638, 150644, 150650, 150656, 150663, 150670, - 150677, 150687, 150694, 150701, 150707, 150713, 150719, 150725, 150733, - 150741, 150749, 150757, 150766, 150772, 150780, 150786, 150793, 150799, - 150806, 150812, 150820, 150824, 150828, 150833, 150839, 150845, 150853, - 150861, 150867, 150874, 150877, 150883, 150887, 150890, 150894, 150897, - 150900, 150904, 150909, 150913, 150917, 150923, 150928, 150934, 150938, - 150942, 150945, 150949, 150953, 150958, 150962, 150967, 150971, 150976, - 150980, 150984, 150988, 150992, 150996, 151000, 151004, 151008, 151013, - 151018, 151023, 151028, 151034, 151040, 151046, 151052, 151058, 0, 0, 0, - 0, 0, 151063, 151071, 151080, 151088, 151095, 151103, 151110, 151117, - 151126, 151133, 151140, 151148, 151156, 0, 0, 0, 151164, 151170, 151178, - 151184, 151191, 151197, 151203, 151209, 151215, 0, 0, 0, 0, 0, 0, 0, - 151221, 151227, 151235, 151241, 151248, 151254, 151260, 151266, 151272, - 151278, 0, 0, 151283, 151289, 151295, 151298, 151307, 151314, 151322, - 151329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151336, - 151351, 151364, 151373, 151384, 151393, 151402, 151413, 151422, 151431, - 151446, 151459, 151472, 151486, 151498, 151506, 151516, 151524, 151532, - 151542, 151550, 151558, 151572, 151584, 151596, 151605, 151616, 151625, - 151634, 151641, 151650, 151659, 151666, 151671, 151676, 151681, 151686, - 151691, 151696, 151701, 151706, 151711, 151716, 151721, 151726, 151731, - 0, 0, 151740, 151749, 151758, 151767, 151772, 151779, 151784, 151789, - 151797, 151802, 151809, 151814, 151821, 151826, 151831, 151838, 151845, - 151850, 151859, 151865, 151871, 151879, 151885, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 151891, 151895, 151901, 151905, 151913, 151917, 151921, 151925, - 151933, 151937, 151943, 151952, 151956, 151960, 151964, 151970, 151976, - 151982, 151988, 151994, 152000, 152006, 152012, 152018, 152026, 152034, - 152042, 152050, 152055, 152061, 152065, 152069, 152073, 152077, 152083, - 152089, 152095, 152101, 152107, 152115, 152121, 152129, 152137, 152145, - 152153, 152161, 152165, 152173, 152179, 152187, 152191, 152195, 152199, - 152203, 152207, 152211, 152219, 152227, 152239, 152251, 152257, 152267, - 152275, 152285, 152297, 152301, 152307, 152313, 152319, 152325, 152331, - 152337, 152343, 152349, 152355, 152363, 152369, 152375, 152381, 152389, - 152397, 152408, 152419, 152425, 152431, 152441, 152447, 152455, 152459, - 152465, 152471, 152477, 152483, 152489, 152495, 152501, 152505, 152511, - 152517, 152525, 152533, 152541, 152547, 152555, 152568, 152581, 152589, - 152597, 152609, 152617, 152627, 152635, 152639, 152643, 152647, 152651, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152655, 152660, 152665, 152670, - 152677, 152684, 152691, 152698, 152703, 152708, 152713, 152718, 152725, - 152730, 152737, 152744, 152749, 152754, 152759, 152766, 152771, 152776, - 152783, 152790, 152795, 152800, 152805, 152812, 152819, 152826, 152831, - 152836, 152843, 152850, 152857, 152864, 152869, 152874, 152879, 152886, - 152891, 152896, 152901, 152908, 152917, 152924, 152929, 152934, 152939, - 152944, 152949, 152954, 152963, 152970, 152975, 152982, 152989, 152994, - 152999, 153004, 153011, 153016, 153023, 153030, 153035, 153040, 153045, - 153052, 153059, 153064, 153069, 153076, 153083, 153090, 153095, 153100, - 153105, 153110, 153117, 153126, 153135, 153140, 153147, 153156, 153161, - 153166, 153171, 153176, 153183, 153190, 153197, 153204, 153209, 153214, - 153219, 153226, 153233, 153240, 153245, 153250, 153257, 153262, 153269, - 153274, 153281, 153286, 153293, 153300, 153305, 153310, 153315, 153320, - 153325, 153330, 153335, 153340, 153345, 153352, 153359, 153366, 153373, - 153380, 153389, 153394, 153399, 153406, 153413, 153418, 153425, 153432, - 153439, 153446, 153453, 153460, 153465, 153470, 153475, 153480, 153485, - 153494, 153503, 153512, 153521, 153530, 153539, 153548, 153557, 153562, - 153573, 153584, 153593, 153598, 153603, 153608, 153613, 153622, 153629, - 153636, 153643, 153650, 153657, 153664, 153673, 153682, 153693, 153702, - 153713, 153722, 153729, 153738, 153749, 153758, 153767, 153776, 153785, - 153792, 153799, 153806, 153815, 153824, 153835, 153844, 153853, 153864, - 153869, 153874, 153885, 153893, 153902, 153911, 153920, 153931, 153940, - 153949, 153960, 153971, 153982, 153993, 154004, 154015, 154022, 154029, - 154036, 154043, 154054, 154063, 154070, 154077, 154084, 154095, 154106, - 154117, 154128, 154139, 154150, 154161, 154172, 154179, 154186, 154195, - 154204, 154211, 154218, 154225, 154234, 154243, 154252, 154259, 154268, - 154277, 154286, 154293, 154300, 154305, 154311, 154318, 154325, 154332, - 154339, 154346, 154353, 154362, 154371, 154380, 154389, 154396, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 154405, 154411, 154416, 154421, 154428, 154434, - 154440, 154446, 154452, 154458, 154464, 154470, 154474, 154478, 154484, - 154490, 154496, 154500, 154505, 154510, 154514, 154518, 154522, 154528, - 154534, 154540, 154546, 154552, 154558, 154564, 154570, 154576, 154586, - 154596, 154602, 154608, 154618, 154628, 154634, 0, 0, 154640, 154648, - 154653, 154658, 154664, 154670, 154676, 154682, 154688, 154694, 154701, - 154708, 154714, 154720, 154726, 154732, 154738, 154744, 154750, 154756, - 154761, 154767, 154773, 154779, 154785, 154791, 154800, 154806, 154811, - 154819, 154826, 154833, 154842, 154851, 154860, 154869, 154878, 154887, - 154896, 154905, 154915, 154925, 154933, 154941, 154950, 154959, 154965, - 154971, 154977, 154983, 154991, 154999, 155003, 155009, 155014, 155020, - 155026, 155032, 155038, 155044, 155053, 155058, 155065, 155070, 155075, - 155080, 155086, 155092, 155098, 155105, 155110, 155115, 155120, 155125, - 155130, 155136, 155142, 155148, 155154, 155160, 155166, 155172, 155178, - 155183, 155188, 155193, 155198, 155203, 155208, 155213, 155218, 155224, - 155230, 155235, 155240, 155245, 155250, 155255, 155261, 155268, 155272, - 155276, 155280, 155284, 155288, 155292, 155296, 155300, 155308, 155318, - 155322, 155326, 155332, 155338, 155344, 155350, 155356, 155362, 155368, - 155374, 155380, 155386, 155392, 155398, 155404, 155410, 155414, 155418, - 155425, 155431, 155437, 155443, 155448, 155455, 155460, 155466, 155472, - 155478, 155484, 155489, 155493, 155499, 155503, 155507, 155511, 155517, - 155523, 155527, 155533, 155539, 155545, 155551, 155557, 155565, 155573, - 155579, 155585, 155591, 155597, 155609, 155621, 155635, 155647, 155659, - 155673, 155687, 155701, 155705, 155713, 155721, 155726, 155730, 155734, - 155738, 155742, 155746, 155750, 155754, 155760, 155766, 155772, 155778, - 155786, 155795, 155802, 155809, 155817, 155824, 155836, 155848, 155860, - 155872, 155879, 155883, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 155887, 155894, 155901, 155908, 155915, 155922, 155929, - 155936, 155943, 155950, 155957, 155964, 155971, 155978, 155985, 155992, - 155999, 156006, 156013, 156020, 156027, 156034, 156041, 156048, 156055, - 156062, 156069, 156076, 156083, 156090, 156097, 156104, 156111, 156118, - 156125, 156132, 156139, 156146, 156153, 156160, 156167, 156174, 156181, - 156188, 156195, 156202, 156209, 156216, 156223, 156230, 156237, 156244, - 156251, 156258, 156265, 156272, 156279, 156286, 156293, 156300, 156307, - 156314, 156321, 156328, 156335, 156342, 156349, 156354, 156359, 156364, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156368, 156374, 156379, 156384, 156389, - 156394, 156399, 156404, 156409, 156414, 156419, 156425, 156431, 156437, - 156443, 156449, 156455, 156461, 156467, 156473, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 156479, 156484, 156491, 156498, 156505, 156512, 156517, - 156522, 156529, 156534, 156539, 156546, 156551, 156556, 156561, 156568, - 156577, 156582, 156587, 156592, 156597, 156602, 156607, 156614, 156619, - 156624, 156629, 156634, 156639, 156644, 156649, 156654, 156659, 156664, - 156669, 156674, 156680, 156685, 156690, 156695, 156700, 156705, 156710, - 156715, 156720, 156725, 156734, 156739, 156747, 156752, 156757, 156762, - 156767, 156772, 156777, 156782, 156791, 156796, 156801, 156806, 156811, - 156816, 156823, 156828, 156835, 156840, 156845, 156850, 156855, 156860, - 156865, 156870, 156875, 156880, 156885, 156890, 156895, 156900, 156905, - 156910, 156915, 156920, 156925, 156930, 156939, 156944, 156949, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 156954, 156962, 156970, 156978, 156986, 156994, 157002, - 157010, 157018, 157026, 157034, 157042, 157050, 157058, 157066, 157074, - 157082, 157090, 157098, 157103, 157108, 157113, 157118, 157123, 157127, - 0, 0, 0, 0, 0, 0, 0, 157131, 157135, 157140, 157145, 157150, 157154, - 157159, 157164, 157169, 157173, 157178, 157183, 157187, 157192, 157197, - 157201, 157206, 157211, 157215, 157220, 157225, 157229, 157234, 157239, - 157244, 157249, 157254, 157258, 157263, 157268, 157273, 157277, 157282, - 157287, 157292, 157296, 157301, 157306, 157310, 157315, 157320, 157324, - 157329, 157334, 157338, 157343, 157348, 157352, 157357, 157362, 157367, - 157372, 157377, 157381, 157386, 157391, 157396, 157400, 157405, 157410, - 157415, 157419, 157424, 157429, 157433, 157438, 157443, 157447, 157452, - 157457, 157461, 157466, 157471, 157475, 157480, 157485, 157490, 157495, - 157500, 157504, 157509, 157514, 157519, 157523, 157528, 0, 157533, - 157537, 157542, 157547, 157551, 157556, 157561, 157565, 157570, 157575, - 157579, 157584, 157589, 157593, 157598, 157603, 157608, 157613, 157618, - 157623, 157629, 157635, 157641, 157646, 157652, 157658, 157664, 157669, - 157675, 157681, 157686, 157692, 157698, 157703, 157709, 157715, 157720, - 157726, 157732, 157737, 157743, 157749, 157755, 157761, 157767, 157772, - 157778, 157784, 157790, 157795, 157801, 157807, 157813, 157818, 157824, - 157830, 157835, 157841, 157847, 157852, 157858, 157864, 157869, 157875, - 157881, 157886, 157892, 157898, 157904, 157910, 157916, 0, 157920, - 157925, 0, 0, 157930, 0, 0, 157935, 157940, 0, 0, 157945, 157950, 157954, - 157959, 0, 157964, 157969, 157974, 157978, 157983, 157988, 157993, - 157998, 158003, 158007, 158012, 158017, 0, 158022, 0, 158027, 158032, - 158036, 158041, 158046, 158050, 158055, 0, 158060, 158065, 158070, - 158074, 158079, 158084, 158088, 158093, 158098, 158103, 158108, 158113, - 158118, 158124, 158130, 158136, 158141, 158147, 158153, 158159, 158164, - 158170, 158176, 158181, 158187, 158193, 158198, 158204, 158210, 158215, - 158221, 158227, 158232, 158238, 158244, 158250, 158256, 158262, 158267, - 158273, 158279, 158285, 158290, 158296, 158302, 158308, 158313, 158319, - 158325, 158330, 158336, 158342, 158347, 158353, 158359, 158364, 158370, - 158376, 158381, 158387, 158393, 158399, 158405, 158411, 158416, 0, - 158422, 158428, 158433, 158439, 0, 0, 158445, 158451, 158457, 158462, - 158468, 158474, 158479, 158485, 0, 158491, 158497, 158503, 158508, - 158514, 158520, 158526, 0, 158532, 158537, 158543, 158549, 158555, - 158560, 158566, 158572, 158578, 158583, 158589, 158595, 158600, 158606, - 158612, 158617, 158623, 158629, 158634, 158640, 158646, 158651, 158657, - 158663, 158669, 158675, 158681, 158686, 0, 158692, 158698, 158703, - 158709, 0, 158715, 158720, 158726, 158732, 158737, 0, 158743, 0, 0, 0, - 158748, 158754, 158760, 158765, 158771, 158777, 158783, 0, 158789, - 158794, 158800, 158806, 158812, 158817, 158823, 158829, 158835, 158840, - 158846, 158852, 158857, 158863, 158869, 158874, 158880, 158886, 158891, - 158897, 158903, 158908, 158914, 158920, 158926, 158932, 158938, 158944, - 158951, 158958, 158965, 158971, 158978, 158985, 158992, 158998, 159005, - 159012, 159018, 159025, 159032, 159038, 159045, 159052, 159058, 159065, - 159072, 159078, 159085, 159092, 159099, 159106, 159113, 159119, 159126, - 159133, 159140, 159146, 159153, 159160, 159167, 159173, 159180, 159187, - 159193, 159200, 159207, 159213, 159220, 159227, 159233, 159240, 159247, - 159253, 159260, 159267, 159274, 159281, 159288, 159292, 159297, 159302, - 159307, 159311, 159316, 159321, 159326, 159330, 159335, 159340, 159344, - 159349, 159354, 159358, 159363, 159368, 159372, 159377, 159382, 159386, - 159391, 159396, 159401, 159406, 159411, 159415, 159420, 159425, 159430, - 159434, 159439, 159444, 159449, 159453, 159458, 159463, 159467, 159472, - 159477, 159481, 159486, 159491, 159495, 159500, 159505, 159509, 159514, - 159519, 159524, 159529, 159534, 159539, 159545, 159551, 159557, 159562, - 159568, 159574, 159580, 159585, 159591, 159597, 159602, 159608, 159614, - 159619, 159625, 159631, 159636, 159642, 159648, 159653, 159659, 159665, - 159671, 159677, 159683, 159688, 159694, 159700, 159706, 159711, 159717, - 159723, 159729, 159734, 159740, 159746, 159751, 159757, 159763, 159768, - 159774, 159780, 159785, 159791, 159797, 159802, 159808, 159814, 159820, - 159826, 159832, 159837, 159843, 159849, 159855, 159860, 159866, 159872, - 159878, 159883, 159889, 159895, 159900, 159906, 159912, 159917, 159923, - 159929, 159934, 159940, 159946, 159951, 159957, 159963, 159969, 159975, - 159981, 159986, 159992, 159998, 160004, 160009, 160015, 160021, 160027, - 160032, 160038, 160044, 160049, 160055, 160061, 160066, 160072, 160078, - 160083, 160089, 160095, 160100, 160106, 160112, 160118, 160124, 160130, - 160136, 160143, 160150, 160157, 160163, 160170, 160177, 160184, 160190, - 160197, 160204, 160210, 160217, 160224, 160230, 160237, 160244, 160250, - 160257, 160264, 160270, 160277, 160284, 160291, 160298, 160305, 160311, - 160318, 160325, 160332, 160338, 160345, 160352, 160359, 160365, 160372, - 160379, 160385, 160392, 160399, 160405, 160412, 160419, 160425, 160432, - 160439, 160445, 160452, 160459, 160466, 160473, 160480, 160485, 160491, - 160497, 160503, 160508, 160514, 160520, 160526, 160531, 160537, 160543, - 160548, 160554, 160560, 160565, 160571, 160577, 160582, 160588, 160594, - 160599, 160605, 160611, 160617, 160623, 160629, 160634, 160640, 160646, - 160652, 160657, 160663, 160669, 160675, 160680, 160686, 160692, 160697, - 160703, 160709, 160714, 160720, 160726, 160731, 160737, 160743, 160748, - 160754, 160760, 160766, 160772, 160778, 160784, 0, 0, 160791, 160796, - 160801, 160806, 160811, 160816, 160821, 160826, 160831, 160836, 160841, - 160846, 160851, 160856, 160861, 160866, 160871, 160876, 160882, 160887, - 160892, 160897, 160902, 160907, 160912, 160917, 160921, 160926, 160931, - 160936, 160941, 160946, 160951, 160956, 160961, 160966, 160971, 160976, - 160981, 160986, 160991, 160996, 161001, 161006, 161012, 161017, 161022, - 161027, 161032, 161037, 161042, 161047, 161053, 161058, 161063, 161068, - 161073, 161078, 161083, 161088, 161093, 161098, 161103, 161108, 161113, - 161118, 161123, 161128, 161133, 161138, 161143, 161148, 161153, 161158, - 161163, 161168, 161174, 161179, 161184, 161189, 161194, 161199, 161204, - 161209, 161213, 161218, 161223, 161228, 161233, 161238, 161243, 161248, - 161253, 161258, 161263, 161268, 161273, 161278, 161283, 161288, 161293, - 161298, 161304, 161309, 161314, 161319, 161324, 161329, 161334, 161339, - 161345, 161350, 161355, 161360, 161365, 161370, 161375, 161381, 161387, - 161393, 161399, 161405, 161411, 161417, 161423, 161429, 161435, 161441, - 161447, 161453, 161459, 161465, 161471, 161477, 161484, 161490, 161496, - 161502, 161508, 161514, 161520, 161526, 161531, 161537, 161543, 161549, - 161555, 161561, 161567, 161573, 161579, 161585, 161591, 161597, 161603, - 161609, 161615, 161621, 161627, 161633, 161640, 161646, 161652, 161658, - 161664, 161670, 161676, 161682, 161689, 161695, 161701, 161707, 161713, - 161719, 161725, 161731, 161737, 161743, 161749, 161755, 161761, 161767, - 161773, 161779, 161785, 161791, 161797, 161803, 161809, 161815, 161821, - 161827, 161834, 161840, 161846, 161852, 161858, 161864, 161870, 161876, - 161881, 161887, 161893, 161899, 161905, 161911, 161917, 161923, 161929, - 161935, 161941, 161947, 161953, 161959, 161965, 161971, 161977, 161983, - 161990, 161996, 162002, 162008, 162014, 162020, 162026, 162032, 162039, - 162045, 162051, 162057, 162063, 162069, 162075, 162082, 162089, 162096, - 162103, 162110, 162117, 162124, 162131, 162138, 162145, 162152, 162159, - 162166, 162173, 162180, 162187, 162194, 162202, 162209, 162216, 162223, - 162230, 162237, 162244, 162251, 162257, 162264, 162271, 162278, 162285, - 162292, 162299, 162306, 162313, 162320, 162327, 162334, 162341, 162348, - 162355, 162362, 162369, 162376, 162384, 162391, 162398, 162405, 162412, - 162419, 162426, 162433, 162441, 162448, 162455, 162462, 162469, 162476, - 162483, 162488, 0, 0, 162493, 162498, 162502, 162506, 162510, 162514, - 162518, 162522, 162526, 162530, 162534, 162540, 162545, 162550, 162555, - 162560, 162565, 162570, 162575, 162580, 162585, 162590, 162594, 162598, - 162602, 162606, 162610, 162614, 162618, 162622, 162626, 162632, 162637, - 162642, 162647, 162652, 162657, 162662, 162667, 162672, 162677, 162683, - 162688, 162693, 162698, 162703, 162708, 162713, 162718, 162723, 162728, - 162732, 162737, 162742, 162747, 162752, 162757, 162762, 162768, 162776, - 162783, 162788, 162793, 162800, 162806, 162811, 162817, 162823, 162831, - 162837, 162844, 162852, 162858, 162867, 162876, 162884, 162892, 162898, - 162905, 162913, 162921, 162927, 162934, 162943, 162952, 162959, 162970, - 162980, 162990, 163000, 163010, 163017, 163024, 163031, 163038, 163047, - 163056, 163067, 163078, 163087, 163096, 163107, 163116, 163125, 163136, - 163145, 163154, 163162, 163170, 163181, 163192, 163200, 163209, 163218, - 163225, 163236, 163247, 163256, 163265, 163272, 163281, 163290, 163299, - 163310, 163319, 163329, 163338, 163347, 163358, 163371, 163386, 163397, - 163410, 163422, 163431, 163442, 163453, 163462, 163473, 163487, 163502, - 163505, 163514, 163519, 163525, 163533, 163539, 163545, 163554, 163561, - 163571, 163583, 163590, 163593, 163599, 163606, 163612, 163617, 163620, - 163625, 163628, 163636, 163642, 163651, 163658, 163666, 163672, 163677, - 163680, 163683, 163686, 163692, 163699, 163705, 163710, 163718, 163721, - 163726, 163734, 163740, 163749, 163756, 163766, 163775, 163778, 163784, - 163791, 163798, 163805, 163810, 163818, 163826, 163835, 163841, 163850, - 163859, 163868, 163874, 163883, 163890, 163897, 163904, 163912, 163918, - 163926, 163932, 163939, 163946, 163954, 163965, 163975, 163981, 163988, - 163995, 164002, 164008, 164015, 164022, 164027, 164034, 164042, 164051, - 164057, 164069, 164080, 164086, 164094, 164100, 164107, 164114, 164121, - 164127, 164134, 164143, 164149, 164155, 164162, 164169, 164177, 164187, - 164197, 164207, 164217, 164225, 164233, 164243, 164251, 164256, 164261, - 164266, 164272, 164279, 164286, 164292, 164298, 164303, 164310, 164318, - 164328, 164336, 164344, 164354, 164364, 164372, 164382, 164392, 164404, - 164416, 164428, 164438, 164444, 164450, 164457, 164466, 164475, 164484, - 164493, 164503, 164512, 164521, 164530, 164535, 164541, 164550, 164560, - 164569, 164575, 164581, 164588, 164595, 164602, 164608, 164615, 164622, - 164629, 164635, 164639, 164644, 164651, 164658, 164665, 164670, 164678, - 164686, 164695, 164703, 164710, 164718, 164727, 164737, 164740, 164744, - 164749, 164754, 164759, 164764, 164769, 164774, 164779, 164784, 164789, - 164794, 164799, 164804, 164809, 164814, 164819, 164824, 164829, 164836, - 164842, 164849, 164855, 164860, 164867, 164873, 164880, 164886, 164891, - 164898, 164905, 164912, 164918, 164924, 164933, 164942, 164952, 164959, - 164966, 164975, 164984, 164993, 165002, 165011, 165017, 165025, 165031, - 165041, 165046, 165055, 165064, 165071, 165082, 165089, 165096, 165103, - 165110, 165117, 165124, 165131, 165138, 165145, 165152, 165158, 165164, - 165170, 165177, 165184, 165191, 165198, 165205, 165212, 165219, 165226, - 165233, 165240, 165247, 165254, 165259, 165268, 165277, 165286, 165293, - 165300, 165307, 165314, 165321, 165328, 165335, 165342, 165351, 165360, - 165369, 165378, 165387, 165396, 165405, 165414, 165423, 165432, 165441, - 165450, 165459, 165465, 165473, 165479, 165489, 165494, 165503, 165512, - 165521, 165532, 165537, 165544, 165551, 165558, 165563, 165569, 165575, - 165581, 165588, 165595, 165602, 165609, 165616, 165623, 165630, 165637, - 165644, 165651, 165658, 165665, 165670, 165679, 165688, 165697, 165706, - 165715, 165724, 165733, 165742, 165753, 165764, 165771, 165778, 165785, - 165792, 165799, 165806, 165814, 165824, 165834, 165844, 165855, 165866, - 165877, 165886, 165895, 165904, 165909, 165914, 165919, 165924, 165935, - 165946, 165957, 165968, 165979, 165989, 166000, 166009, 166018, 166027, - 166036, 166045, 166053, 166062, 166073, 166084, 166095, 166106, 166117, - 166129, 166142, 166154, 166167, 166179, 166192, 166204, 166217, 166228, - 166239, 166248, 166256, 166265, 166276, 166287, 166299, 166312, 166326, - 166341, 166353, 166366, 166378, 166391, 166402, 166413, 166422, 166430, - 166439, 166446, 166453, 166460, 166467, 166474, 166481, 166488, 166495, - 166502, 166509, 166514, 166519, 166524, 166531, 166541, 166552, 166562, - 166573, 166587, 166602, 166617, 166631, 166646, 166661, 166672, 166683, - 166696, 166709, 166718, 166727, 166740, 166753, 166760, 166767, 166772, - 166777, 166782, 166787, 166792, 166799, 166808, 166813, 166816, 166821, - 166828, 166835, 166842, 166849, 166856, 166863, 166876, 166890, 166905, - 166912, 166919, 166926, 166935, 166943, 166951, 166960, 166965, 166970, - 166975, 166980, 166985, 166990, 166997, 167004, 167010, 167017, 167023, - 167030, 167035, 167040, 167045, 167050, 167055, 167062, 167069, 167074, - 167081, 167088, 167093, 167098, 167103, 167108, 167113, 167118, 167125, - 167132, 167139, 167142, 167147, 167152, 167157, 167162, 167169, 167176, - 167184, 167192, 167197, 167202, 167209, 167216, 167223, 167228, 167235, - 167242, 167247, 167254, 167261, 167268, 167275, 167282, 167289, 167298, - 167307, 167314, 167323, 167332, 167337, 167344, 167351, 167356, 167363, - 167370, 167377, 167384, 167391, 167396, 167403, 167410, 167419, 167426, - 167435, 167446, 167455, 167464, 167473, 167482, 167485, 167490, 167497, - 167506, 167513, 167522, 167529, 167534, 167539, 167542, 167545, 167548, - 167555, 167562, 167571, 167580, 167589, 167596, 167603, 167608, 167620, - 167625, 167630, 167635, 167640, 167645, 167650, 167655, 167660, 167663, - 167668, 167673, 167678, 167683, 167688, 167695, 167700, 167707, 167710, - 167715, 167718, 167721, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 167724, 167729, 167734, 167739, 167744, 0, 167749, 167754, 167759, - 167764, 167769, 167774, 167779, 167784, 167789, 167794, 167799, 167804, - 167809, 167814, 167819, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167824, 167834, 167842, - 167849, 167856, 167865, 167874, 167883, 167890, 167904, 167916, 167926, - 167934, 167946, 167955, 167966, 167975, 167982, 167990, 168001, 168013, - 168022, 168032, 168044, 168055, 168064, 168075, 168087, 168095, 168106, - 168115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 168123, 168128, 168133, 168138, 168143, 168148, 168153, 0, - 168158, 168163, 168168, 168174, 168178, 168183, 168188, 168193, 168198, - 168203, 168208, 168213, 168218, 168223, 168228, 168233, 168238, 0, 0, - 168243, 168248, 168253, 168258, 168263, 168268, 168273, 0, 168278, - 168283, 0, 168289, 168294, 168302, 168309, 168318, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 168323, 168330, 168338, 168346, 168354, 168361, 168368, - 168376, 168384, 168392, 168399, 168406, 168414, 168422, 168430, 168437, - 168445, 168453, 168461, 168469, 168477, 168485, 168493, 168500, 168508, - 168515, 168523, 168530, 168538, 168546, 168554, 168562, 168570, 168578, - 168586, 168594, 168602, 168609, 168617, 168624, 168631, 168638, 168646, - 168653, 168661, 0, 0, 0, 168669, 168676, 168683, 168690, 168697, 168704, - 168711, 168718, 168727, 168736, 168745, 168754, 168763, 168773, 0, 0, - 168781, 168789, 168796, 168803, 168810, 168817, 168824, 168831, 168838, - 168845, 0, 0, 0, 0, 168852, 168861, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 168869, 168873, 168878, 168883, 168888, 168892, 168897, - 168901, 168905, 168910, 168914, 168919, 168923, 168928, 168933, 168937, - 168941, 168945, 168949, 168955, 168960, 168967, 168971, 168975, 168981, - 168986, 168993, 168997, 169002, 169009, 169013, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 169020, 169025, 169029, 169034, 169039, - 169044, 169049, 169053, 169058, 169062, 169066, 169070, 169075, 169080, - 169085, 169089, 169094, 169099, 169104, 169109, 169114, 169118, 169122, - 169127, 169131, 169135, 169140, 169144, 169148, 169152, 169157, 169161, - 169166, 169171, 169176, 169181, 169186, 169191, 169196, 169201, 169206, - 169211, 169216, 169221, 169226, 169231, 169236, 169241, 169246, 169251, - 169255, 169259, 169263, 169267, 169271, 169275, 169279, 169283, 0, 0, 0, - 0, 0, 169287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 169292, 169296, 169300, 169304, 169308, 169312, 169316, 0, - 169320, 169326, 169330, 169334, 0, 169338, 169344, 0, 169350, 169356, - 169362, 169368, 169374, 169380, 169386, 169392, 169398, 169404, 169410, - 169416, 169422, 169428, 169434, 0, 169440, 169447, 169453, 169460, - 169467, 169474, 169481, 169488, 169495, 169502, 169509, 169516, 169523, - 169530, 169537, 169544, 169551, 169558, 169565, 169572, 169579, 169586, - 169593, 169600, 169607, 169614, 169621, 169628, 169635, 169642, 169649, - 169656, 169663, 169670, 169677, 169683, 169689, 169695, 169702, 169708, - 169715, 169721, 169728, 169735, 169742, 169749, 169756, 169763, 169769, - 169776, 169783, 169790, 169797, 169804, 169811, 169818, 169824, 169831, - 169838, 169845, 169852, 169859, 169867, 169874, 169881, 169888, 169895, - 169902, 169909, 169916, 169923, 169930, 169937, 169944, 169951, 169957, - 169964, 169971, 169978, 169985, 169992, 169999, 170006, 170014, 170021, - 170027, 170034, 170041, 170048, 170055, 170062, 170069, 170076, 170083, - 170090, 170097, 170104, 170111, 170118, 170125, 170132, 170139, 170146, - 170153, 170160, 170167, 170173, 170180, 170187, 170194, 170201, 170208, - 170215, 170222, 170229, 170236, 170243, 170250, 170257, 170264, 170271, - 170278, 170285, 170292, 170299, 170306, 170313, 170320, 170327, 170335, - 170343, 170351, 170358, 170365, 170372, 170379, 170386, 170393, 170400, - 170407, 170414, 170421, 170427, 170434, 170441, 170448, 170455, 170462, - 170469, 170476, 170483, 170490, 170497, 170504, 170511, 170518, 170525, - 170533, 170541, 170549, 170556, 170563, 170570, 170577, 170584, 170591, - 170598, 170605, 170612, 170619, 170626, 170633, 170640, 170647, 170653, - 170660, 170667, 170674, 170681, 170688, 170695, 170702, 170709, 170716, - 170723, 170730, 170737, 170744, 170751, 170758, 170765, 170772, 170779, - 170786, 170793, 170800, 170807, 0, 0, 170814, 170818, 170822, 170826, - 170830, 170834, 170838, 170842, 170846, 170850, 170856, 170862, 170868, - 170874, 170882, 170890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 170896, 170902, 170908, 170914, 170920, 170926, 170932, 170938, - 170944, 170949, 170954, 170960, 170965, 170970, 170976, 170982, 170988, - 170994, 171000, 171005, 171010, 171016, 171022, 171027, 171033, 171039, - 171045, 171051, 171057, 171063, 171069, 171075, 171081, 171087, 171093, - 171099, 171105, 171111, 171117, 171123, 171129, 171135, 171141, 171146, - 171151, 171157, 171162, 171167, 171173, 171179, 171185, 171191, 171197, - 171202, 171207, 171213, 171219, 171224, 171230, 171236, 171242, 171248, - 171254, 171260, 171266, 171272, 171278, 171284, 171290, 171296, 171301, - 171306, 171310, 171315, 171322, 171326, 0, 0, 0, 0, 171331, 171336, - 171340, 171344, 171348, 171352, 171356, 171360, 171364, 171368, 0, 0, 0, - 0, 171372, 171378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 171384, 171389, 171394, 171399, 171404, 171409, - 171414, 171419, 171424, 171429, 171435, 171441, 171447, 171453, 171459, - 171465, 171471, 171477, 171483, 171490, 171497, 171504, 171512, 171520, - 171528, 171536, 171544, 171552, 171558, 171564, 171570, 171577, 171584, - 171591, 171598, 171605, 171612, 171619, 171626, 171633, 171640, 171647, - 171654, 171661, 171668, 171675, 171681, 171687, 171693, 171699, 171705, - 171712, 171719, 171726, 171733, 171740, 171747, 171754, 171761, 171768, - 171773, 171781, 171789, 171797, 171803, 171810, 171817, 171826, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 171834, 171839, 171844, 171849, 171854, 171859, 171864, 171869, - 171874, 171879, 171885, 171891, 171897, 171903, 171909, 171915, 171921, - 171927, 171933, 171940, 171947, 171954, 171962, 171970, 171978, 171986, - 171994, 172002, 172008, 172014, 172020, 172027, 172034, 172041, 172048, - 172055, 172062, 172069, 172076, 172083, 172090, 172097, 172104, 172111, - 172118, 172125, 172130, 172137, 172144, 172151, 172158, 172165, 172172, - 172179, 172186, 172194, 172204, 172214, 172222, 172231, 172239, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172247, 172251, 172255, - 172259, 0, 172263, 172267, 172271, 172275, 172279, 172283, 172287, - 172291, 172295, 172299, 172303, 172307, 172311, 172315, 172319, 172323, - 172327, 172331, 172335, 172339, 172343, 172347, 172351, 172355, 172361, - 172367, 172373, 0, 172379, 172384, 0, 172389, 0, 0, 172394, 0, 172399, - 172404, 172409, 172414, 172419, 172424, 172429, 172434, 172439, 172444, - 0, 172449, 172454, 172459, 172464, 0, 172469, 0, 172474, 0, 0, 0, 0, 0, - 0, 172479, 0, 0, 0, 0, 172485, 0, 172491, 0, 172497, 0, 172503, 172509, - 172515, 0, 172521, 172527, 0, 172533, 0, 0, 172539, 0, 172545, 0, 172551, - 0, 172557, 0, 172565, 0, 172573, 172579, 0, 172585, 0, 0, 172591, 172597, - 172603, 172609, 0, 172615, 172621, 172627, 172633, 172639, 172645, - 172651, 0, 172657, 172663, 172669, 172675, 0, 172681, 172687, 172693, - 172699, 0, 172707, 0, 172715, 172721, 172727, 172733, 172739, 172745, - 172751, 172757, 172763, 172769, 0, 172775, 172781, 172787, 172793, - 172799, 172805, 172811, 172817, 172823, 172829, 172835, 172841, 172847, - 172853, 172859, 172865, 172871, 0, 0, 0, 0, 0, 172877, 172883, 172889, 0, - 172895, 172901, 172907, 172913, 172919, 0, 172925, 172931, 172937, - 172943, 172949, 172955, 172961, 172967, 172973, 172979, 172985, 172991, - 172997, 173003, 173009, 173015, 173021, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173027, 173037, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173045, 173052, 173059, 173066, - 173072, 173079, 173086, 173092, 173099, 173106, 173113, 173121, 173129, - 173137, 173145, 173153, 173161, 173168, 173175, 173182, 173190, 173198, - 173206, 173214, 173222, 173230, 173237, 173244, 173251, 173259, 173267, - 173275, 173283, 173291, 173299, 173304, 173309, 173314, 173319, 173324, - 173329, 173334, 173339, 173344, 0, 0, 0, 0, 173349, 173356, 173361, - 173366, 173371, 173376, 173381, 173386, 173391, 173396, 173401, 173406, - 173411, 173416, 173421, 173426, 173431, 173436, 173441, 173446, 173451, - 173456, 173461, 173466, 173471, 173476, 173481, 173486, 173491, 173496, - 173501, 173506, 173511, 173516, 173521, 173526, 173531, 173536, 173541, - 173546, 173551, 173556, 173561, 173566, 173571, 173576, 173581, 173586, - 173591, 173596, 173601, 173607, 173612, 173617, 173622, 173627, 173632, - 173637, 173642, 173647, 173652, 173657, 173662, 173667, 173672, 173677, - 173682, 173687, 173692, 173697, 173702, 173707, 173712, 173717, 173722, - 173727, 173732, 173737, 173742, 173747, 173752, 173757, 173762, 173767, - 173772, 173777, 173782, 173787, 173792, 173797, 173802, 173807, 173812, - 173817, 173822, 173827, 173832, 173837, 173842, 173847, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 173852, 173858, 173867, 173875, 173883, 173892, 173901, - 173910, 173919, 173928, 173937, 173946, 173955, 173964, 173973, 0, 0, - 173982, 173991, 173999, 174007, 174016, 174025, 174034, 174043, 174052, - 174061, 174070, 174079, 174088, 174097, 174106, 0, 174114, 174123, - 174131, 174139, 174148, 174157, 174166, 174175, 174184, 174193, 174202, - 174211, 174220, 174229, 174238, 0, 174245, 174254, 174262, 174270, - 174279, 174288, 174297, 174306, 174315, 174324, 174333, 174342, 174351, - 174360, 174369, 174376, 174382, 174388, 174394, 174400, 174406, 174412, - 174418, 174424, 174430, 174436, 174442, 174448, 174454, 174460, 174466, - 174472, 174478, 174484, 174490, 174496, 174502, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 174508, 174515, 174520, 174524, 174528, 174532, 174537, 174542, - 174547, 174552, 174557, 174562, 174569, 174578, 174584, 174588, 174597, - 174602, 174608, 174614, 174620, 174625, 174631, 174637, 174643, 174648, - 174654, 174660, 174665, 174671, 174677, 174682, 174688, 174694, 174699, - 174705, 174711, 174716, 174722, 174728, 174734, 174740, 174746, 174757, - 174764, 174770, 174773, 174776, 174779, 174784, 174790, 174796, 174802, - 174807, 174813, 174819, 174825, 174830, 174836, 174842, 174847, 174853, - 174859, 174864, 174870, 174876, 174881, 174887, 174893, 174898, 174904, - 174910, 174916, 174922, 174928, 174931, 174934, 174937, 174940, 174943, - 174946, 174953, 174961, 174969, 174977, 174984, 174992, 175000, 175008, - 175015, 175023, 175031, 175038, 175046, 175054, 175061, 175069, 175077, - 175084, 175092, 175100, 175107, 175115, 175123, 175131, 175139, 175147, - 175152, 175157, 175162, 175165, 175173, 175178, 175185, 175193, 175201, - 175209, 175216, 175224, 175232, 175240, 175247, 175255, 175263, 175270, - 175278, 175286, 175293, 175301, 175309, 175316, 175324, 175332, 175339, - 175347, 175355, 175363, 175371, 175379, 175389, 175394, 175398, 175402, - 175407, 175412, 175415, 175418, 175421, 175424, 175427, 175430, 175433, - 175436, 175439, 175445, 175448, 175452, 175457, 175461, 175466, 175471, - 175477, 175483, 175489, 175494, 175502, 175508, 175511, 175514, 175517, - 175520, 175523, 175526, 175529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175534, 175541, - 175549, 175557, 175565, 175572, 175580, 175588, 175596, 175603, 175611, - 175619, 175626, 175634, 175642, 175649, 175657, 175665, 175672, 175680, - 175688, 175695, 175703, 175711, 175719, 175727, 175735, 175740, 175744, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175747, 175753, 175759, 175765, - 175769, 175775, 175781, 175787, 175793, 175799, 175805, 175811, 175817, - 175823, 175829, 175835, 175841, 175847, 175853, 175859, 175865, 175871, - 175877, 175883, 175889, 175895, 175901, 175907, 175913, 175919, 175925, - 175931, 175937, 175943, 175949, 175955, 175961, 175967, 175973, 175979, - 175985, 175991, 175997, 176003, 0, 0, 0, 0, 176009, 176020, 176031, - 176042, 176053, 176064, 176075, 176086, 176097, 0, 0, 0, 0, 0, 0, 0, - 176108, 176113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176118, 176124, - 176130, 176136, 176142, 176148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176154, 176156, 176158, 176162, - 176167, 176172, 176174, 176180, 176185, 176187, 176193, 176197, 176199, - 176203, 176209, 176215, 176221, 176226, 176231, 176238, 176245, 176252, - 176257, 176264, 176271, 176278, 176282, 176289, 176298, 176307, 176314, - 176319, 176323, 176327, 176329, 176332, 176335, 176342, 176349, 176359, - 176364, 176369, 176374, 176379, 176381, 176387, 176391, 176393, 176395, - 176397, 176399, 176403, 176407, 176411, 176413, 176417, 176419, 176423, - 176425, 176427, 176429, 176431, 176436, 176441, 176443, 176449, 176453, - 176457, 176465, 176467, 176469, 176471, 176473, 176475, 176477, 176479, - 176481, 176483, 176485, 176489, 176493, 176495, 176497, 176499, 176501, - 176503, 176508, 176514, 176518, 176522, 176526, 176530, 176535, 176539, - 176541, 176543, 176547, 176553, 176555, 176557, 176559, 176563, 176572, - 176578, 176582, 176586, 176588, 176590, 176593, 176595, 176597, 176599, - 176603, 176605, 176609, 176614, 176616, 176621, 176627, 176634, 176638, - 176642, 176646, 176650, 176656, 176660, 176668, 176675, 176677, 176679, - 176683, 176687, 176689, 176693, 176697, 176699, 176703, 176705, 176709, - 176713, 176717, 176721, 176725, 176729, 176733, 176737, 176743, 176747, - 176751, 176762, 176767, 176771, 176775, 176781, 176785, 176789, 176793, - 176800, 176807, 176811, 176815, 176819, 176823, 176827, 176834, 176836, - 176840, 176842, 176844, 176848, 176852, 176856, 176858, 176862, 176866, - 176870, 176874, 176878, 176880, 176884, 176886, 176892, 176895, 176900, - 176902, 176904, 176907, 176909, 176911, 176914, 176921, 176928, 176935, - 176940, 176944, 176946, 176948, 176950, 176954, 176956, 176960, 176964, - 176968, 176970, 176974, 176976, 176980, 176984, 176991, 176993, 177002, - 177011, 177020, 177026, 177028, 177033, 177037, 177041, 177043, 177049, - 177053, 177055, 177059, 177063, 177065, 177069, 177074, 177078, 177084, - 177090, 177092, 177094, 177100, 177102, 177106, 177110, 177112, 177116, - 177118, 177122, 177126, 177130, 177133, 177136, 177141, 177146, 177148, - 177151, 177153, 177160, 177164, 177166, 177173, 177180, 177187, 177194, - 177201, 177203, 177205, 177207, 177211, 177213, 177215, 177217, 177219, - 177221, 177223, 177225, 177227, 177229, 177231, 177233, 177235, 177237, - 177239, 177241, 177243, 177245, 177247, 177249, 177251, 177253, 177255, - 177259, 177261, 177263, 177265, 177269, 177271, 177275, 177277, 177279, - 177283, 177287, 177293, 177295, 177297, 177299, 177301, 177305, 177309, - 177311, 177315, 177319, 177323, 177327, 177331, 177335, 177339, 177343, - 177347, 177351, 177355, 177359, 177363, 177367, 177371, 177375, 177379, - 177383, 177385, 177387, 177389, 177391, 177393, 177395, 177397, 177405, - 177413, 177421, 177429, 177434, 177439, 177444, 177448, 177452, 177457, - 177462, 177464, 177468, 177470, 177472, 177474, 177476, 177478, 177480, - 177482, 177486, 177488, 177490, 177492, 177496, 177500, 177504, 177508, - 177512, 177514, 177520, 177526, 177528, 177530, 177532, 177534, 177536, - 177545, 177552, 177559, 177563, 177570, 177575, 177582, 177591, 177596, - 177600, 177604, 177606, 177610, 177612, 177616, 177620, 177622, 177626, - 177630, 177634, 177636, 177638, 177644, 177646, 177648, 177650, 177654, - 177658, 177660, 177664, 177666, 177668, 177671, 177675, 177677, 177681, - 177683, 177685, 177690, 177692, 177696, 177700, 177703, 177707, 177711, - 177715, 177719, 177723, 177727, 177731, 177736, 177740, 177744, 177753, - 177758, 177761, 177763, 177766, 177769, 177774, 177776, 177779, 177784, - 177788, 177791, 177795, 177799, 177802, 177807, 177811, 177815, 177819, - 177823, 177829, 177835, 177841, 177847, 177852, 177863, 177865, 177869, - 177871, 177873, 177877, 177881, 177883, 177887, 177893, 177898, 177904, - 177906, 177910, 177914, 177921, 177928, 177932, 177934, 177936, 177940, - 177942, 177946, 177950, 177954, 177956, 177958, 177965, 177969, 177973, - 177977, 177981, 177985, 177987, 177991, 177993, 177995, 177999, 178001, - 178005, 178009, 178015, 178019, 178023, 178027, 178029, 178032, 178036, - 178043, 178052, 178061, 178070, 178079, 178081, 178085, 178087, 178091, - 178102, 178106, 178112, 178118, 178123, 178125, 178130, 178134, 178136, - 178138, 178140, 178144, 178148, 178152, 178157, 178168, 178184, 178197, - 178210, 178214, 178218, 178224, 178226, 178234, 178242, 178244, 178248, - 178254, 178260, 178267, 178274, 178276, 178278, 178282, 178284, 178290, - 178292, 178295, 178299, 178305, 178311, 178322, 178328, 178335, 178343, - 178347, 178355, 178363, 178369, 178375, 178382, 178384, 178388, 178390, - 178392, 178397, 178399, 178401, 178403, 178405, 178409, 178419, 178425, - 178429, 178433, 178437, 178443, 178449, 178455, 178461, 178466, 178471, - 178477, 178483, 178490, 178497, 178504, 178511, 178516, 178524, 178528, - 178537, 178546, 178552, 178556, 178560, 178564, 178567, 178572, 178574, - 178576, 178578, 178585, 178590, 178597, 178604, 178611, 178619, 178627, - 178635, 178643, 178651, 178659, 178667, 178675, 178683, 178689, 178695, - 178701, 178707, 178713, 178719, 178725, 178731, 178737, 178743, 178749, - 178755, 178758, 178767, 178776, 178778, 178785, 178789, 178791, 178793, - 178797, 178803, 178807, 178809, 178819, 178825, 178829, 178831, 178835, - 178837, 178841, 178848, 178855, 178862, 178867, 178872, 178881, 178887, - 178892, 178896, 178901, 178905, 178912, 178916, 178919, 178923, 178929, - 178935, 178939, 178943, 178948, 178954, 178963, 178974, 178980, 178986, - 178992, 179002, 179017, 179026, 179034, 179042, 179050, 179058, 179066, - 179074, 179082, 179090, 179098, 179106, 179114, 179122, 179125, 179129, - 179134, 179139, 179141, 179145, 179154, 179163, 179171, 179175, 179179, - 179184, 179189, 179194, 179196, 179201, 179205, 179207, 179211, 179215, - 179221, 179226, 179234, 179239, 179244, 179249, 179256, 179259, 179261, - 179265, 179270, 179276, 179280, 179284, 179290, 179296, 179298, 179302, - 179306, 179310, 179314, 179318, 179320, 179322, 179324, 179326, 179332, - 179338, 179342, 179344, 179346, 179348, 179357, 179361, 179368, 179375, - 179377, 179380, 179384, 179390, 179394, 179398, 179400, 179408, 179412, - 179416, 179421, 179425, 179430, 179435, 179440, 179445, 179450, 179455, - 179460, 179465, 179469, 179475, 179479, 179485, 179490, 179497, 179503, - 179511, 179515, 179522, 179526, 179530, 179534, 179539, 179544, 179546, - 179550, 179559, 179567, 179576, 179590, 179604, 179618, 179625, 179632, - 179636, 179645, 179653, 179657, 179666, 179673, 179677, 179681, 179685, - 179689, 179696, 179700, 179704, 179708, 179712, 179719, 179728, 179737, - 179744, 179756, 179768, 179772, 179776, 179780, 179784, 179788, 179792, - 179800, 179808, 179817, 179821, 179825, 179829, 179833, 179837, 179841, - 179847, 179854, 179858, 179870, 179878, 179882, 179886, 179890, 179894, - 179900, 179907, 179918, 179928, 179939, 179950, 179959, 179970, 179976, - 179982, 179988, 179994, 180000, 180004, 180011, 180020, 180027, 180033, - 180037, 180041, 180045, 180054, 180066, 180070, 180077, 180084, 180091, - 180099, 180106, 180114, 180122, 180131, 180139, 180148, 180157, 180167, - 180176, 180186, 180196, 180207, 180217, 180228, 180235, 180243, 180250, - 180258, 180266, 180275, 180283, 180292, 180299, 180311, 180318, 180330, - 180333, 180337, 180340, 180344, 180350, 180357, 180364, 180372, 180377, - 180383, 180394, 180404, 180415, 180420, 180425, 180431, 180436, 180443, - 180447, 180453, 180455, 180457, 180461, 180465, 180469, 180478, 180480, - 180482, 180485, 180487, 180489, 180493, 180495, 180499, 180501, 180505, - 180507, 180509, 180513, 180517, 180523, 180525, 180529, 180531, 180535, - 180539, 180543, 180547, 180549, 180551, 180555, 180559, 180563, 180567, - 180569, 180571, 180573, 180579, 180584, 180587, 180595, 180603, 180605, - 180610, 180613, 180618, 180629, 180636, 180641, 180646, 180648, 180652, - 180654, 180658, 180660, 180664, 180668, 180671, 180674, 180676, 180679, - 180681, 180685, 180687, 180689, 180691, 180695, 180697, 180701, 180704, - 180711, 180714, 180719, 180722, 180725, 180730, 180734, 180738, 180742, - 180744, 180749, 180752, 180756, 180758, 180760, 180764, 180766, 0, 0, 0, - 0, 0, 180768, 180772, 180774, 180778, 180783, 180785, 180789, 180791, - 180795, 180799, 180805, 180809, 180814, 180817, 180821, 180825, 0, 0, 0, - 180829, 180831, 180837, 180841, 180845, 180847, 180851, 180853, 180855, - 180859, 180861, 180865, 180869, 0, 0, 0, 180873, 180878, 180883, 180888, - 180893, 180898, 180903, 180910, 180917, 180924, 180931, 180936, 180941, - 180946, 180951, 180958, 180964, 180971, 180978, 180985, 180990, 180995, - 181000, 181005, 181010, 181017, 181024, 181029, 181034, 181041, 181048, - 181056, 181064, 181071, 181078, 181086, 181094, 181102, 181109, 181119, - 181130, 181135, 181142, 181149, 181156, 181164, 181172, 181183, 181191, - 181199, 181207, 181212, 181217, 181222, 181227, 181232, 181237, 181242, - 181247, 181252, 181257, 181262, 181267, 181274, 181279, 181284, 181291, - 181296, 181301, 181306, 181311, 181316, 181321, 181326, 181331, 181336, - 181341, 181346, 181351, 181358, 181366, 181371, 181376, 181383, 181388, - 181393, 181398, 181405, 181410, 181417, 181422, 181429, 181434, 181443, - 181452, 181457, 181462, 181467, 181472, 181477, 181482, 181487, 181492, - 181497, 181502, 181507, 181512, 181517, 181525, 181533, 181538, 181543, - 181548, 181553, 181558, 181564, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 181570, 181578, 181586, 181594, 181602, 181608, 181614, 181618, 181622, - 181628, 181634, 181643, 181647, 181652, 181658, 181662, 181667, 181671, - 181675, 181681, 181687, 181697, 181706, 181709, 181714, 181720, 181726, - 181737, 181747, 181751, 181756, 181762, 181768, 181777, 181782, 181786, - 181791, 181795, 181801, 181807, 181813, 181817, 181820, 181824, 181827, - 181830, 181835, 181840, 181847, 181855, 181862, 181869, 181878, 181887, - 181894, 181902, 181909, 181916, 181925, 181934, 181941, 181949, 181956, - 181963, 181972, 181979, 181987, 181993, 182002, 182010, 182019, 182026, - 182036, 182047, 182055, 182063, 182072, 182080, 182088, 182097, 182105, - 182115, 182124, 182132, 182140, 182149, 182152, 182157, 182160, 0, 0, 0, - 0, 0, 0, 0, 182165, 182171, 182177, 182183, 182189, 182195, 182201, - 182207, 182213, 182219, 182225, 182231, 0, 0, 0, 0, 182237, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182241, 182249, 182258, 182266, 182275, - 182284, 182294, 182303, 182313, 182322, 182332, 182341, 0, 0, 0, 0, - 182351, 182359, 182368, 182376, 182385, 182392, 182400, 182407, 182415, - 182423, 182432, 182440, 182449, 182459, 182470, 182480, 182491, 182500, - 182510, 182519, 182529, 182538, 182548, 182557, 182567, 182575, 182584, - 182592, 182601, 182609, 182618, 182626, 182635, 182645, 182656, 182666, - 182677, 182681, 182686, 182690, 182695, 182698, 182702, 182705, 182709, - 182713, 182718, 182722, 182727, 182732, 182738, 182743, 182749, 182752, - 182756, 182759, 0, 0, 0, 0, 0, 0, 0, 0, 182763, 182766, 182770, 182773, - 182777, 182782, 182787, 182793, 182799, 182803, 0, 0, 0, 0, 0, 0, 182807, - 182813, 182820, 182826, 182833, 182841, 182849, 182858, 182867, 182872, - 182878, 182883, 182889, 182896, 182903, 182911, 182919, 182926, 182934, - 182941, 182949, 182958, 182967, 182977, 182987, 182993, 183000, 183006, - 183013, 183021, 183029, 183038, 183047, 183055, 183064, 183072, 183081, - 183091, 183101, 183112, 0, 0, 0, 0, 0, 0, 0, 0, 183123, 183128, 183134, - 183139, 183145, 183154, 183164, 183173, 183183, 183190, 183198, 183205, - 183213, 183220, 183229, 183238, 183247, 183252, 183259, 183266, 183273, - 183278, 183283, 183288, 183293, 183300, 183307, 183314, 183321, 183328, - 0, 0, 183337, 183347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183359, 183369, 183378, 183383, - 183392, 183400, 183408, 183415, 183419, 183424, 183431, 183440, 183451, - 183455, 183458, 183462, 183466, 183470, 183474, 183479, 183483, 183487, - 183492, 183496, 183500, 183506, 183512, 183519, 183523, 183527, 183529, - 183539, 183548, 183555, 183559, 183563, 183573, 183577, 183581, 183585, - 183589, 183597, 183606, 183619, 183630, 183641, 183657, 183666, 183675, - 183679, 183681, 183686, 183688, 183690, 183696, 183700, 183702, 183708, - 183710, 183712, 183716, 183718, 183722, 183724, 183728, 183732, 183737, - 183741, 183745, 183747, 183751, 183753, 183759, 183765, 183771, 183775, - 183781, 183785, 183792, 183794, 183798, 183800, 183802, 183804, 183806, - 183808, 183810, 183814, 183818, 183825, 183829, 183831, 183836, 183838, - 183840, 183842, 183844, 183848, 183852, 183854, 183859, 183864, 183866, - 183868, 183870, 183872, 183877, 183879, 183883, 183887, 183889, 183893, - 183895, 183908, 183912, 183919, 183931, 183943, 183947, 183951, 183953, - 183957, 183965, 183972, 183974, 183978, 183980, 183984, 183988, 183990, - 183994, 183996, 183998, 184002, 184004, 184006, 184008, 184010, 184012, - 184016, 184018, 184020, 184022, 184024, 184026, 184028, 184030, 184034, - 184038, 184040, 184042, 184044, 184046, 184048, 184050, 184052, 184054, - 184056, 184058, 184060, 184062, 184064, 184066, 184068, 184070, 184072, - 184074, 184076, 184078, 184080, 184082, 184084, 184086, 184088, 184090, - 184094, 184098, 184106, 184114, 184120, 184127, 184129, 184131, 184133, - 184135, 184137, 184139, 184143, 184150, 184154, 184158, 184162, 184166, - 184170, 184172, 184176, 184180, 184182, 184184, 184186, 184188, 184190, - 184194, 184198, 184202, 184204, 184208, 184212, 184216, 184221, 184223, - 184225, 184229, 184233, 184238, 184246, 184250, 184258, 184260, 184262, - 184264, 184266, 184268, 184270, 184272, 184274, 184278, 184282, 184284, - 184286, 184288, 184290, 184296, 184298, 184304, 184308, 184312, 184317, - 184319, 184321, 184325, 184327, 184329, 184331, 184333, 184337, 184342, - 184347, 184351, 184355, 184357, 184359, 184364, 184369, 184371, 184373, - 184377, 184383, 184389, 184395, 184401, 184407, 184413, 184424, 184435, - 184447, 184458, 184469, 184480, 184491, 184502, 184513, 184524, 184535, - 184546, 184557, 184568, 184579, 184591, 184603, 184615, 184627, 184639, - 184651, 184665, 184679, 184694, 184700, 184706, 184712, 184718, 184724, - 184730, 184736, 184742, 184748, 184754, 184760, 184766, 184773, 184780, - 184787, 184794, 184801, 184808, 184822, 184836, 184851, 184865, 184879, - 184893, 184907, 184921, 184935, 184949, 184963, 184977, 184991, 185005, - 185019, 185034, 185049, 185064, 185079, 185094, 185109, 185123, 185137, - 185152, 185157, 185162, 185168, 185179, 185190, 185202, 185207, 185212, - 185217, 185222, 185227, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185232, - 185238, 185244, 185250, 185256, 185262, 185268, 185274, 185279, 185284, - 185289, 185294, 185299, 185304, 0, 0, 185309, 185313, 185317, 185319, - 185321, 0, 0, 0, 185325, 185330, 185334, 185336, 185338, 0, 0, 0, 185340, - 185342, 185344, 185346, 185348, 185352, 185354, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 185358, 185362, 185364, 185366, 185368, 185372, 185374, 185378, - 185380, 185383, 185385, 185389, 185391, 185393, 185394, 185396, 185398, - 185400, 185404, 185406, 185408, 185412, 185414, 185416, 185418, 185420, - 185424, 185428, 185431, 0, 0, 0, 185433, 185435, 185437, 185439, 185441, - 185445, 185447, 185449, 185451, 185453, 185457, 0, 0, 0, 0, 0, 185462, - 185466, 185468, 185472, 185476, 185480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 185485, 185487, 185491, 185493, 185495, 185497, 185499, 185501, 185505, - 185507, 0, 0, 0, 0, 0, 0, 185509, 185513, 185517, 185530, 185537, 185544, - 185550, 185554, 0, 0, 0, 0, 0, 0, 0, 0, 185556, 185566, 185569, 185572, - 185577, 185582, 185591, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185595, 185598, - 185601, 185604, 185607, 185610, 185613, 185616, 185619, 185622, 185625, - 185628, 185631, 185634, 185637, 185640, 185643, 185646, 185649, 185652, - 185655, 185658, 185661, 185664, 185667, 185670, 185673, 185676, 185679, - 185682, 185685, 185688, 185691, 185694, 185697, 185700, 185703, 185706, - 185709, 185712, 185715, 185718, 185721, 185724, 185727, 185730, 185733, - 185736, 185739, 185742, 185745, 185748, 185751, 185754, 185757, 185760, - 185763, 185766, 185769, 185772, 185775, 185787, 185798, 185810, 185821, - 185832, 185844, 185855, 185867, 185878, 185889, 185901, 185913, 185924, - 185936, 185947, 185958, 185970, 185981, 185993, 186004, 186015, 186027, - 186039, 186050, 186062, 186073, 186084, 186096, 186107, 186119, 186130, - 186141, 186153, 186165, 186176, 186188, 186199, 186210, 186222, 186233, - 186245, 186256, 186267, 186279, 186291, 186303, 186315, 186327, 186335, - 186343, 186351, 186359, 186365, 186371, 186377, 186383, 186389, 186395, - 186402, 186409, 186416, 186423, 186430, 186437, 186445, 186453, 186461, - 186469, 186477, 186484, 186490, 186496, 186503, 186509, 186516, 186522, - 186528, 186535, 186541, 186548, 186554, 186560, 186566, 186572, 186578, - 186590, 0, 186603, 186616, 186622, 186630, 186635, 186642, 186649, - 186657, 186665, 186673, 186681, 186689, 186697, 186709, 186720, 186731, - 186742, 186757, 186772, 186786, 186800, 186818, 186836, 186855, 186873, - 186891, 186909, 186916, 186924, 186928, 186933, 186939, 186945, 186955, - 186966, 186977, 186987, 186997, 187001, 187005, 187010, 187016, 187022, - 187032, 187038, 187047, 187056, 187065, 187074, 187080, 187084, 187093, - 187101, 187108, 187115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 187120, - 187125, 187129, 187133, 187137, 187141, 187145, 187149, 187153, 187157, - 0, 0, 0, 0, 0, 0, 187161, 187165, 187169, 187173, 187177, 187181, 187185, - 187189, 187193, 187197, 187201, 187205, 187209, 187213, 187217, 187221, - 187225, 187229, 187233, 187237, 187241, 187245, 187249, 187253, 187257, - 187261, 187265, 187269, 187273, 187277, 187281, 187285, 187289, 187293, - 187297, 187301, 187305, 187309, 187313, 187317, 187321, 187325, 187329, - 187333, 187337, 187341, 187345, 187349, 187353, 187357, 187361, 187365, - 187369, 187373, 187377, 187381, 187385, 187389, 187393, 187397, 187401, - 187405, 187409, 187413, 187417, 187421, 187425, 187429, 187433, 187437, - 187441, 187445, 187449, 187453, 187457, 187461, 187465, 187469, 187473, - 187477, 187481, 187485, 187489, 187493, 187497, 187501, 187505, 187509, - 187513, 187517, 187521, 187525, 187529, 187533, 187537, 187541, 187545, - 187549, 187553, 187557, 187561, 187565, 187569, 187573, 187577, 187581, - 187585, 187589, 187593, 187597, 187601, 187605, 187609, 187613, 187617, - 187621, 187625, 187629, 187633, 187637, 187641, 187645, 187649, 187653, - 187657, 187661, 187665, 187669, 187673, 187677, 187681, 187685, 187689, - 187693, 187697, 187701, 187705, 187709, 187713, 187717, 187721, 187725, - 187729, 187733, 187737, 187741, 187745, 187749, 187753, 187757, 187761, - 187765, 187769, 187773, 187777, 187781, 187785, 187789, 187793, 187797, - 187801, 187805, 187809, 187813, 187817, 187821, 187825, 187829, 187833, - 187837, 187841, 187845, 187849, 187853, 187857, 187861, 187865, 187869, - 187873, 187877, 187881, 187885, 187889, 187893, 187897, 187901, 187905, - 187909, 187913, 187917, 187921, 187925, 187929, 187933, 187937, 187941, - 187945, 187949, 187953, 187957, 187961, 187965, 187969, 187973, 187977, - 187981, 187985, 187989, 187993, 187997, 188001, 188005, 188009, 188013, - 188017, 188021, 188025, 188029, 188033, 188037, 188041, 188045, 188049, - 188053, 188057, 188061, 188065, 188069, 188073, 188077, 188081, 188085, - 188089, 188093, 188097, 188101, 188105, 188109, 188113, 188117, 188121, - 188125, 188129, 188133, 188137, 188141, 188145, 188149, 188153, 188157, - 188161, 188165, 188169, 188173, 188177, 188181, 188185, 188189, 188193, - 188197, 188201, 188205, 188209, 188213, 188217, 188221, 188225, 188229, - 188233, 188237, 188241, 188245, 188249, 188253, 188257, 188261, 188265, - 188269, 188273, 188277, 188281, 188285, 188289, 188293, 188297, 188301, - 188305, 188309, 188313, 188317, 188321, 188325, 188329, 188333, 188337, - 188341, 188345, 188349, 188353, 188357, 188361, 188365, 188369, 188373, - 188377, 188381, 188385, 188389, 188393, 188397, 188401, 188405, 188409, - 188413, 188417, 188421, 188425, 188429, 188433, 188437, 188441, 188445, - 188449, 188453, 188457, 188461, 188465, 188469, 188473, 188477, 188481, - 188485, 188489, 188493, 188497, 188501, 188505, 188509, 188513, 188517, - 188521, 188525, 188529, 188533, 188537, 188541, 188545, 188549, 188553, - 188557, 188561, 188565, 188569, 188573, 188577, 188581, 188585, 188589, - 188593, 188597, 188601, 188605, 188609, 188613, 188617, 188621, 188625, - 188629, 188633, 188637, 188641, 188645, 188649, 188653, 188657, 188661, - 188665, 188669, 188673, 188677, 188681, 188685, 188689, 188693, 188697, - 188701, 188705, 188709, 188713, 188717, 188721, 188725, 188729, 188733, - 188737, 188741, 188745, 188749, 188753, 188757, 188761, 188765, 188769, - 188773, 188777, 188781, 188785, 188789, 188793, 188797, 188801, 188805, - 188809, 188813, 188817, 188821, 188825, 188829, 188833, 188837, 188841, - 188845, 188849, 188853, 188857, 188861, 188865, 188869, 188873, 188877, - 188881, 188885, 188889, 188893, 188897, 188901, 188905, 188909, 188913, - 188917, 188921, 188925, 188929, 188933, 188937, 188941, 188945, 188949, - 188953, 188957, 188961, 188965, 188969, 188973, 188977, 188981, 188985, - 188989, 188993, 188997, 189001, 189005, 189009, 189013, 189017, 189021, - 189025, 189029, 189033, 189037, 189041, 189045, 189049, 189053, 189057, - 189061, 189065, 189069, 189073, 189077, 189081, 189085, 189089, 189093, - 189097, 189101, 189105, 189109, 189113, 189117, 189121, 189125, 189129, - 189133, 189137, 189141, 189145, 189149, 189153, 189157, 189161, 189165, - 189169, 189173, 189177, 189181, 189185, 189189, 189193, 189197, 189201, - 189205, 189209, 189213, 189217, 189221, 189225, 189229, 189233, 189237, - 189241, 189245, 189249, 189253, 189257, 189261, 189265, 189269, 189273, - 189277, 189281, 189285, 189289, 189293, 189297, 189301, 189305, 189309, - 189313, 189317, 189321, 189325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189329, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189333, - 189337, 189342, 189347, 189351, 189356, 189361, 189365, 189369, 189374, - 189379, 189383, 189387, 189391, 189395, 189401, 189405, 189410, 189414, - 189418, 189422, 189426, 189430, 189434, 189438, 189442, 189446, 189450, - 189454, 189459, 189464, 189469, 189474, 189480, 189486, 189493, 189500, - 189507, 189513, 189520, 189527, 189534, 189540, 189547, 189554, 189560, - 189567, 189574, 189580, 189587, 189594, 189600, 189607, 189614, 189620, - 189627, 189634, 189641, 189648, 189655, 189661, 189667, 189673, 189679, - 189684, 189690, 189696, 189703, 189710, 189717, 189723, 189730, 189737, - 189744, 189750, 189757, 189764, 189770, 189777, 189784, 189790, 189797, - 189804, 189810, 189817, 189824, 189830, 189837, 189844, 189851, 189858, - 189865, 189872, 189877, 189884, 189888, 189892, 189895, 189898, 189901, - 189904, 189907, 189910, 189913, 189916, 189919, 189922, 189925, 189928, - 189931, 189934, 189937, 189940, 189943, 189946, 189949, 189952, 189955, - 189958, 189961, 189964, 189967, 189970, 189973, 189976, 189979, 189982, - 189985, 189988, 189991, 189994, 189997, 190000, 190003, 190006, 190009, - 190012, 190015, 190018, 190021, 190024, 190027, 190030, 190033, 190036, - 190039, 190042, 190045, 190048, 190051, 190054, 190057, 190060, 190063, - 190066, 190069, 190072, 190075, 190078, 190081, 190084, 190087, 190090, - 190093, 190096, 190099, 190102, 190105, 190108, 190111, 190114, 190117, - 190120, 190123, 190126, 190129, 190132, 190135, 190138, 190141, 190144, - 190147, 190150, 190153, 190156, 190159, 190162, 190165, 190168, 190171, - 190174, 190177, 190180, 190183, 190186, 190189, 190192, 190195, 190198, - 190201, 190204, 190207, 190210, 190213, 190216, 190219, 190222, 190225, - 190228, 190231, 190234, 190237, 190240, 190243, 190246, 190249, 190252, - 190255, 190258, 190261, 190264, 190267, 190270, 190273, 190276, 190279, - 190282, 190285, 190288, 190291, 190294, 190297, 190300, 190303, 190306, - 190309, 190312, 190315, 190318, 190321, 190324, 190327, 190330, 190333, - 190336, 190339, 190342, 190345, 190348, 190351, 190354, 190357, 190360, - 190363, 190366, 190369, 190372, 190375, 190378, 190381, 190384, 190387, - 190390, 190393, 190396, 190399, 190402, 190405, 190408, 190411, 190414, - 190417, 190420, 190423, 190426, 190429, 190432, 190435, 190438, 190441, - 190444, 190447, 190450, 190453, 190456, 190459, 190462, 190465, 190468, - 190471, 190474, 190477, 190480, 190483, 190486, 190489, 190492, 190495, - 190498, 190501, 190504, 190507, 190510, 190513, 190516, 190519, 190522, - 190525, 190528, 190531, 190534, 190537, 190540, 190543, 190546, 190549, - 190552, 190555, 190558, 190561, 190564, 190567, 190570, 190573, 190576, - 190579, 190582, 190585, 190588, 190591, 190594, 190597, 190600, 190603, - 190606, 190609, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190612, - 190614, 190616, 190621, 190623, 190628, 190630, 190635, 190637, 190642, - 190644, 190646, 190648, 190650, 190652, 190654, 190656, 190658, 190660, - 190664, 190668, 190670, 190672, 190676, 190680, 190685, 190687, 190689, - 190691, 190695, 190698, 190700, 190704, 190706, 190710, 190712, 190716, - 190719, 190721, 190725, 190729, 190731, 190737, 190739, 190744, 190746, - 190751, 190753, 190758, 190760, 190765, 190767, 190771, 190773, 190777, - 190779, 190786, 190788, 190790, 190792, 190797, 190799, 190801, 190803, - 190805, 190807, 190812, 190816, 190818, 190823, 190827, 190829, 190834, - 190838, 190840, 190845, 190849, 190851, 190853, 190855, 190857, 190861, - 190863, 190868, 190870, 190876, 190878, 190884, 190886, 190888, 190890, - 190894, 190896, 190903, 190905, 190912, 190914, 190920, 190926, 190928, - 190935, 190942, 190944, 190950, 190955, 190957, 190963, 190969, 190971, - 190977, 190983, 190985, 190991, 190995, 190997, 191002, 191004, 191006, - 191011, 191013, 191015, 191021, 191023, 191028, 191032, 191034, 191039, - 191043, 191045, 191051, 191053, 191057, 191059, 191063, 191065, 191072, - 191079, 191081, 191088, 191095, 191097, 191102, 191104, 191112, 191114, - 191120, 191122, 191128, 191130, 191134, 191136, 191142, 191144, 191148, - 191150, 191156, 191158, 191160, 191162, 191167, 191172, 191174, 191176, - 191186, 191191, 191198, 191205, 191210, 191215, 191227, 191231, 191235, - 191239, 191243, 191245, 191247, 191249, 191251, 191253, 191255, 191257, - 191259, 191261, 191263, 191265, 191267, 191269, 191271, 191273, 191275, - 191277, 191279, 191281, 191283, 191285, 191287, 191293, 191300, 191305, - 191313, 191321, 191326, 191332, 191334, 191336, 191338, 191340, 191342, - 191344, 191346, 191348, 191350, 191352, 191354, 191356, 191358, 191360, - 191362, 191364, 191376, 191381, 191383, 191385, 191391, 191403, 191409, - 191415, 191421, 191427, 191431, 191442, 191444, 191446, 191448, 191450, - 191452, 191454, 191456, 191458, 191460, 191462, 191464, 191466, 191468, - 191470, 191472, 191474, 191476, 191478, 191480, 191482, 191484, 191486, - 191488, 191490, 191492, 191494, 191496, 191498, 191500, 191502, 191504, - 191506, 191508, 191510, 191512, 191514, 191516, 191518, 191520, 191522, - 191524, 191526, 191528, 191530, 191532, 191534, 191536, 191538, 191540, - 191542, 191544, 191546, 191548, 191550, 191552, 191554, 191556, 191558, - 191560, 191562, 191564, 191566, 191568, 191570, 191572, 191574, 191576, - 191578, 191580, 191582, 191584, 191586, 191588, 191590, 191592, 191594, - 191596, 191598, 191600, 191602, 191604, 191606, 191608, 191610, 191612, - 191614, 191616, 191618, 191620, 191622, 191624, 191626, 191628, 191630, - 191632, 191634, 191636, 191638, 191640, 191642, 191644, 191646, 191648, - 191650, 191652, 191654, 191656, 191658, 191660, 191662, 191664, 191666, - 191668, 191670, 191672, 191674, 191676, 191678, 191680, 191682, 191684, - 191686, 191688, 191690, 191692, 191694, 191696, 191698, 191700, 191702, - 191704, 191706, 191708, 191710, 191712, 191714, 191716, 191718, 191720, - 191722, 191724, 191726, 191728, 191730, 191732, 191734, 191736, 191738, - 191740, 191742, 191744, 191746, 191748, 191750, 191752, 191754, 191756, - 191758, 191760, 191762, 191764, 191766, 191768, 191770, 191772, 191774, - 191776, 191778, 191780, 191782, 191784, 191786, 191788, 191790, 191792, - 191794, 191796, 191798, 191800, 191802, 191804, 191806, 191808, 191810, - 191812, 191814, 191816, 191818, 191820, 191822, 191824, 191826, 191828, - 191830, 191832, 191834, 191836, 191838, 191840, 191842, 191844, 191846, - 191848, 191850, 191852, 191854, 191856, 191858, 191860, 191862, 191864, - 191866, 191868, 191870, 191872, 191874, 191876, 191878, 191880, 191882, - 191884, 191886, 191888, 191890, 191892, 191894, 191896, 191898, 191900, - 191902, 191904, 191906, 191908, 191910, 191912, 191914, 191916, 191918, - 191920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191922, - 191926, 191930, 191935, 191939, 191943, 191947, 191951, 191955, 191959, - 191963, 191967, 191971, 191981, 191991, 192002, 192013, 192023, 192033, - 192043, 192053, 192067, 192081, 192095, 192109, 192118, 192127, 192140, - 192153, 192166, 192179, 192189, 192199, 192210, 192221, 192232, 192243, - 192254, 192263, 192273, 192283, 192293, 192303, 192314, 192325, 192336, - 192347, 192358, 192369, 192380, 192391, 192402, 192413, 192424, 192438, - 192449, 192463, 192471, 192482, 192490, 192498, 192506, 192514, 192522, - 192530, 192540, 192550, 192560, 192570, 192580, 192590, 192600, 192610, - 192618, 192627, 192636, 192645, 192654, 192662, 192670, 192680, 192690, - 192701, 192712, 192724, 192735, 192745, 192756, 192766, 192777, 192785, - 192792, 192799, 192806, 192813, 192820, 192827, 192834, 192841, 192849, - 192857, 192865, 192873, 192881, 192889, 192897, 192905, 192913, 192921, - 192929, 192934, 192938, 192942, 192946, 192950, 192954, 192958, 192962, - 192966, 192970, 192974, 192978, 192981, 192984, 192988, 192992, 192996, - 193000, 193004, 193008, 193012, 193016, 193020, 193024, 193028, 193032, - 193036, 193040, 193044, 193048, 193052, 193056, 193060, 193064, 193068, - 193072, 193076, 193080, 193084, 193088, 193092, 193096, 193100, 193104, - 193108, 193112, 193116, 193120, 193124, 193128, 193132, 193136, 193140, - 193144, 193148, 193152, 193156, 193160, 193164, 193168, 193172, 193176, - 193180, 193184, 193188, 193192, 193196, 193200, 193204, 193208, 193212, - 193216, 193220, 193224, 193228, 193232, 193236, 193240, 193244, 193248, - 193252, 193256, 193260, 193264, 193268, 193272, 193276, 193280, 193284, - 193288, 193292, 193296, 193300, 193304, 193308, 193312, 193316, 193320, - 193324, 193327, 193331, 193335, 193339, 193343, 193347, 193351, 193355, - 193359, 193363, 193367, 193371, 193375, 193379, 193383, 193387, 193391, - 193395, 193399, 193403, 193407, 193411, 193415, 193419, 193423, 193427, - 193431, 193435, 193439, 193443, 193447, 193451, 193455, 193459, 193463, - 193467, 193471, 193475, 193479, 193483, 193487, 193491, 193495, 193499, - 193503, 193507, 193511, 193515, 193519, 193523, 193527, 193531, 193535, - 193539, 193543, 193547, 193551, 193555, 193559, 193563, 193567, 193571, - 193575, 193579, 193583, 193587, 193591, 193595, 193599, 193603, 193607, - 193611, 193615, 193619, 193623, 193627, 193631, 193635, 193639, 193643, - 193647, 193651, 193655, 193659, 193663, 193667, 193671, 193675, 193679, - 193683, 193687, 193691, 193695, 193699, 193703, 193707, 193711, 193715, - 193719, 193723, 193727, 193731, 193735, 193739, 193743, 193747, 193751, - 193755, 193759, 193763, 193767, 193771, 193775, 193779, 193783, 193787, - 193791, 193795, 193799, 193803, 193807, 193811, 193815, 193819, 193823, - 193827, 193831, 193835, 193839, 193843, 193847, 193851, 193855, 193859, - 193863, 193867, 193871, 193875, 193879, 193883, 193887, 193891, 193895, - 193899, 193903, 193907, 193911, 193915, 193919, 193923, 193927, 193931, - 193935, 193939, 193943, 193947, 193951, 193955, 193959, 193963, 193967, - 193971, 193975, 193979, 193983, 193987, 193991, 193995, 193999, 194003, - 194007, 194011, 194015, 194019, 194023, 194027, 194031, 194035, 194039, - 194043, 194047, 194051, 194055, 194059, 194063, 194067, 194071, 194075, - 194079, 194083, 194087, 194091, 194096, 194101, 194106, 194110, 194116, - 194123, 194130, 194137, 194144, 194151, 194158, 194165, 194172, 194179, - 194186, 194193, 194200, 194207, 194213, 194220, 194227, 194233, 194240, - 194247, 194254, 194261, 194268, 194275, 194282, 194289, 194296, 194303, - 194310, 194317, 194324, 194330, 194336, 194342, 194349, 194358, 194367, - 194376, 194385, 194390, 194395, 194402, 194409, 194416, 194423, 194430, - 194436, 194442, 194448, 194454, 194460, 194466, 194472, 194477, 194483, - 194493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, + 0, 17131, 17136, 17141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17149, 17155, + 17159, 17163, 17167, 17173, 17176, 17180, 17183, 17187, 17190, 17194, + 17198, 0, 17202, 17205, 17209, 0, 17213, 17216, 17220, 17224, 17227, + 17231, 17235, 17239, 17243, 17247, 17251, 17255, 17259, 17263, 17267, + 17271, 17275, 17279, 17283, 17287, 17291, 17295, 17299, 17302, 17306, + 17309, 17313, 17317, 17321, 17324, 17327, 17330, 17334, 17337, 17341, + 17345, 17349, 17353, 17357, 17360, 17363, 17367, 17374, 17380, 17384, + 17389, 17393, 17398, 17402, 17407, 17412, 0, 17418, 17422, 17427, 0, + 17432, 17436, 17441, 17446, 17450, 17455, 0, 0, 0, 0, 17459, 17465, + 17471, 17477, 17483, 17489, 17495, 17501, 17507, 17513, 17519, 17525, + 17531, 17536, 17541, 17546, 0, 0, 17552, 17556, 17559, 17562, 17565, + 17568, 17571, 17574, 17577, 17580, 17583, 17587, 17592, 17596, 17602, + 17608, 17614, 17620, 17626, 17632, 17636, 17642, 17648, 17654, 17659, + 17665, 0, 17671, 17675, 17679, 0, 17683, 17687, 17691, 17695, 17699, + 17703, 17707, 17711, 17715, 17719, 17723, 17727, 17731, 17735, 17739, + 17743, 17747, 17751, 0, 0, 0, 17755, 17761, 17767, 17773, 17779, 17785, + 17791, 17797, 17803, 17809, 17815, 17821, 17829, 17835, 17841, 17847, + 17853, 17859, 17865, 17871, 17877, 17883, 17889, 17895, 0, 17901, 17907, + 17913, 17919, 17925, 17931, 17935, 17941, 17945, 0, 17949, 0, 0, 17955, + 17959, 17965, 17971, 17977, 17981, 17987, 0, 0, 0, 17991, 0, 0, 0, 0, + 17995, 18000, 18007, 18014, 18021, 18028, 0, 18035, 0, 18042, 18047, + 18052, 18059, 18066, 18075, 18086, 18095, 0, 0, 0, 0, 0, 0, 18100, 18106, + 18111, 18116, 18121, 18126, 18131, 18136, 18141, 18146, 0, 0, 18151, + 18158, 18165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18170, 18178, 18186, + 18194, 18202, 18210, 18218, 18226, 18234, 18242, 18250, 18258, 18266, + 18274, 18282, 18289, 18297, 18305, 18313, 18321, 18329, 18336, 18344, + 18352, 18360, 18368, 18376, 18384, 18392, 18400, 18408, 18416, 18424, + 18431, 18439, 18447, 18453, 18461, 18467, 18475, 18483, 18491, 18499, + 18507, 18515, 18522, 18530, 18536, 18543, 18551, 18559, 18567, 18574, + 18582, 18590, 18598, 18605, 18613, 0, 0, 0, 0, 18619, 18626, 18633, + 18641, 18648, 18658, 18668, 18674, 18680, 18686, 18694, 18702, 18710, + 18718, 18724, 18730, 18736, 18742, 18747, 18751, 18755, 18759, 18763, + 18767, 18771, 18775, 18779, 18783, 18789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 18795, 18800, 0, 18807, 0, 18814, 18821, 18826, 18831, 18838, 0, + 18845, 18852, 18857, 18864, 18871, 18878, 18885, 18892, 18899, 18904, + 18908, 18915, 18922, 18929, 18934, 18939, 18944, 18951, 18958, 18965, + 18972, 18979, 18984, 18989, 0, 18996, 0, 19003, 19008, 19015, 19022, + 19029, 19036, 19043, 19047, 19054, 19058, 19063, 19071, 19077, 19083, + 19088, 19094, 19100, 19106, 19111, 19117, 19124, 19132, 19139, 0, 0, + 19146, 19151, 19157, 19162, 19168, 0, 19174, 0, 19179, 19186, 19193, + 19200, 19207, 19212, 19216, 0, 19220, 19225, 19229, 19233, 19237, 19241, + 19245, 19249, 19253, 19257, 0, 0, 19261, 19267, 19273, 19280, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 19287, 19291, 19302, 19317, 19332, 19342, 19353, 19366, + 19377, 19383, 19391, 19401, 19407, 19415, 19419, 19425, 19431, 19439, + 19449, 19457, 19470, 19476, 19484, 19492, 19504, 19511, 19519, 19527, + 19535, 19543, 19551, 19559, 19569, 19573, 19576, 19579, 19582, 19585, + 19588, 19591, 19594, 19597, 19600, 19604, 19608, 19612, 19616, 19620, + 19624, 19628, 19632, 19636, 19641, 19647, 19657, 19671, 19681, 19687, + 19693, 19701, 19709, 19717, 19725, 19731, 19737, 19740, 19744, 19748, + 19752, 19756, 19760, 19764, 0, 19768, 19772, 19776, 19780, 19784, 19788, + 19792, 19796, 19800, 19804, 19808, 19811, 19814, 19818, 19822, 19826, + 19829, 19833, 19837, 19841, 19845, 19849, 19853, 19857, 19861, 19864, + 19867, 19870, 19874, 19878, 19881, 19884, 19887, 19891, 19896, 19900, 0, + 0, 0, 0, 19904, 19909, 19913, 19918, 19922, 19927, 19932, 19938, 19943, + 19949, 19953, 19958, 19962, 19967, 19977, 19983, 19989, 19996, 20006, + 20012, 20016, 20020, 20026, 20032, 20040, 20046, 20054, 20062, 20070, + 20080, 20088, 20098, 20103, 20109, 20115, 20121, 20127, 20133, 20139, 0, + 20145, 20151, 20157, 20163, 20169, 20175, 20181, 20187, 20193, 20199, + 20205, 20210, 20215, 20221, 20227, 20233, 20238, 20244, 20250, 20256, + 20262, 20268, 20274, 20280, 20286, 20291, 20296, 20301, 20307, 20313, + 20318, 20323, 20328, 20334, 20342, 20349, 0, 20356, 20363, 20376, 20383, + 20390, 20398, 20406, 20412, 20418, 20424, 20434, 20439, 20445, 20455, + 20465, 0, 20475, 20485, 20493, 20505, 20517, 20523, 20537, 20552, 20557, + 20562, 20570, 20578, 20586, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20594, + 20597, 20601, 20605, 20609, 20613, 20617, 20621, 20625, 20629, 20633, + 20637, 20641, 20645, 20649, 20653, 20657, 20661, 20665, 20669, 20673, + 20676, 20679, 20683, 20687, 20691, 20694, 20697, 20700, 20703, 20707, + 20710, 20713, 20717, 20720, 20725, 20728, 20732, 20735, 20739, 20742, + 20747, 20750, 20754, 20761, 20766, 20770, 20775, 20779, 20784, 20788, + 20793, 20800, 20806, 20812, 20816, 20820, 20824, 20828, 20832, 20838, + 20844, 20851, 20857, 20862, 20866, 20869, 20872, 20875, 20878, 20881, + 20884, 20887, 20890, 20893, 20899, 20903, 20907, 20911, 20915, 20919, + 20923, 20927, 20931, 20936, 20940, 20945, 20950, 20956, 20961, 20967, + 20973, 20979, 20985, 20991, 20999, 21007, 21015, 21023, 21032, 21041, + 21052, 21062, 21072, 21083, 21094, 21104, 21114, 21124, 21134, 21144, + 21154, 21164, 21174, 21182, 21189, 21195, 21202, 21207, 21213, 21219, + 21225, 21231, 21237, 21243, 21248, 21254, 21260, 21266, 21272, 21277, + 21286, 21293, 21299, 21307, 21315, 21321, 21327, 21333, 21339, 21347, + 21355, 21365, 21373, 21381, 21387, 21392, 21397, 21402, 21407, 21412, + 21417, 21422, 21427, 21432, 21438, 21444, 21450, 21457, 21462, 21468, + 21473, 21478, 21483, 21488, 21493, 21498, 21503, 21508, 21513, 21518, + 21523, 21528, 21533, 21538, 21543, 21548, 21553, 21558, 21563, 21568, + 21573, 21578, 21583, 21588, 21593, 21598, 21603, 21608, 21613, 21618, + 21623, 21628, 21633, 21638, 21643, 21648, 21653, 0, 21658, 0, 0, 0, 0, 0, + 21663, 0, 0, 21668, 21672, 21676, 21680, 21684, 21688, 21692, 21696, + 21700, 21704, 21708, 21712, 21716, 21720, 21724, 21728, 21732, 21736, + 21740, 21744, 21748, 21752, 21756, 21760, 21764, 21768, 21772, 21776, + 21780, 21784, 21788, 21792, 21796, 21800, 21804, 21808, 21812, 21816, + 21820, 21824, 21828, 21832, 21837, 21841, 21846, 21851, 21855, 21860, + 21865, 21869, 21873, 21877, 21881, 21885, 21889, 21893, 21897, 21901, + 21905, 21909, 21913, 21917, 21921, 21925, 21929, 21933, 21937, 21941, + 21945, 21949, 21953, 21957, 21961, 21965, 21969, 21973, 21977, 21981, + 21985, 21989, 21993, 21997, 22001, 22005, 22009, 22013, 22017, 22021, + 22025, 22029, 22033, 22037, 22041, 22045, 22049, 22053, 22057, 22061, + 22065, 22069, 22073, 22077, 22081, 22085, 22089, 22093, 22097, 22101, + 22105, 22109, 22113, 22117, 22121, 22125, 22129, 22133, 22137, 22141, + 22145, 22149, 22153, 22157, 22161, 22165, 22169, 22173, 22177, 22181, + 22185, 22189, 22193, 22197, 22201, 22205, 22209, 22213, 22217, 22221, + 22225, 22229, 22233, 22237, 22241, 22245, 22249, 22254, 22258, 22263, + 22267, 22272, 22277, 22281, 22286, 22291, 22295, 22300, 22305, 22310, + 22315, 22319, 22324, 22329, 22334, 22339, 22344, 22349, 22353, 22358, + 22363, 22368, 22373, 22378, 22383, 22388, 22393, 22398, 22403, 22408, + 22413, 22418, 22423, 22428, 22433, 22438, 22443, 22448, 22453, 22458, + 22463, 22468, 22473, 22478, 22483, 22488, 22493, 22498, 22503, 22508, + 22513, 22518, 22523, 22528, 22533, 22538, 22543, 22548, 22553, 22558, + 22563, 22568, 22573, 22578, 22583, 22588, 22593, 22598, 22603, 22607, + 22611, 22615, 22619, 22623, 22627, 22631, 22635, 22639, 22643, 22647, + 22651, 22655, 22659, 22663, 22667, 22671, 22675, 22679, 22683, 22687, + 22691, 22695, 22699, 22703, 22707, 22711, 22715, 22719, 22723, 22727, + 22731, 22735, 22739, 22743, 22747, 22751, 22755, 22759, 22763, 22767, + 22771, 22775, 22779, 22783, 22787, 22791, 22795, 22799, 22803, 22807, + 22811, 22815, 22819, 22823, 22827, 22831, 22835, 22839, 22843, 22847, + 22851, 22855, 22859, 22863, 22867, 22871, 22875, 22879, 22883, 22887, + 22891, 22895, 22899, 22903, 22907, 22911, 22915, 22919, 22923, 22927, + 22931, 22935, 22939, 22943, 22947, 22951, 22955, 22958, 22962, 22966, + 22970, 22974, 22978, 22982, 22986, 22989, 22993, 22997, 23001, 23005, + 23009, 23013, 23017, 23021, 23025, 23029, 23033, 23037, 23041, 23045, + 23049, 23052, 23056, 23060, 23064, 23068, 23072, 23076, 23080, 23084, + 23088, 23092, 23096, 23100, 23104, 23108, 23112, 23115, 23119, 23123, + 23127, 23131, 23135, 23139, 23143, 23146, 23150, 23154, 23158, 23162, + 23166, 23170, 23174, 23178, 23182, 23186, 23190, 23194, 23198, 23202, + 23206, 23210, 23214, 23218, 23222, 23226, 23230, 23234, 23238, 0, 23242, + 23246, 23250, 23254, 0, 0, 23258, 23262, 23266, 23270, 23274, 23278, + 23282, 0, 23286, 0, 23290, 23294, 23298, 23302, 0, 0, 23306, 23310, + 23314, 23318, 23322, 23326, 23330, 23334, 23338, 23342, 23346, 23350, + 23354, 23358, 23362, 23366, 23370, 23374, 23378, 23382, 23386, 23390, + 23394, 23397, 23401, 23405, 23409, 23413, 23417, 23421, 23425, 23429, + 23433, 23437, 23441, 23445, 23449, 23453, 23457, 23461, 23465, 0, 23469, + 23473, 23477, 23481, 0, 0, 23485, 23488, 23492, 23496, 23500, 23504, + 23508, 23512, 23516, 23520, 23524, 23528, 23532, 23536, 23540, 23544, + 23548, 23553, 23558, 23563, 23569, 23575, 23580, 23585, 23591, 23594, + 23598, 23602, 23606, 23610, 23614, 23618, 23622, 0, 23626, 23630, 23634, + 23638, 0, 0, 23642, 23646, 23650, 23654, 23658, 23662, 23666, 0, 23670, + 0, 23674, 23678, 23682, 23686, 0, 0, 23690, 23694, 23698, 23702, 23706, + 23710, 23714, 23718, 23722, 23727, 23732, 23737, 23743, 23749, 23754, 0, + 23759, 23763, 23767, 23771, 23775, 23779, 23783, 23787, 23791, 23795, + 23799, 23803, 23807, 23811, 23815, 23819, 23823, 23826, 23830, 23834, + 23838, 23842, 23846, 23850, 23854, 23858, 23862, 23866, 23870, 23874, + 23878, 23882, 23886, 23890, 23894, 23898, 23902, 23906, 23910, 23914, + 23918, 23922, 23926, 23930, 23934, 23938, 23942, 23946, 23950, 23954, + 23958, 23962, 23966, 23970, 23974, 23978, 23982, 0, 23986, 23990, 23994, + 23998, 0, 0, 24002, 24006, 24010, 24014, 24018, 24022, 24026, 24030, + 24034, 24038, 24042, 24046, 24050, 24054, 24058, 24062, 24066, 24070, + 24074, 24078, 24082, 24086, 24090, 24094, 24098, 24102, 24106, 24110, + 24114, 24118, 24122, 24126, 24130, 24134, 24138, 24142, 24146, 24150, + 24154, 24158, 24162, 24166, 24170, 24174, 24178, 24182, 24186, 24190, + 24194, 24198, 24202, 24206, 24210, 24214, 24218, 24222, 24226, 24229, + 24233, 24237, 24241, 24245, 24249, 24253, 24257, 24261, 24265, 0, 0, + 24269, 24278, 24284, 24289, 24293, 24296, 24301, 24304, 24307, 24310, + 24315, 24319, 24324, 24327, 24330, 24333, 24336, 24339, 24342, 24345, + 24348, 24351, 24355, 24359, 24363, 24367, 24371, 24375, 24379, 24383, + 24387, 24391, 0, 0, 0, 24396, 24402, 24406, 24410, 24414, 24420, 24424, + 24428, 24432, 24438, 24442, 24446, 24450, 24456, 24460, 24464, 24468, + 24474, 24480, 24486, 24494, 24500, 24506, 24512, 24518, 24524, 0, 0, 0, + 0, 0, 0, 24530, 24533, 24536, 24539, 24542, 24545, 24549, 24553, 24556, + 24560, 24564, 24568, 24572, 24576, 24579, 24583, 24587, 24591, 24595, + 24599, 24602, 24606, 24610, 24614, 24618, 24622, 24625, 24629, 24633, + 24637, 24641, 24644, 24648, 24652, 24656, 24660, 24664, 24668, 24672, + 24676, 24680, 24684, 24688, 24692, 24696, 24699, 24703, 24707, 24711, + 24715, 24719, 24723, 24727, 24731, 24735, 24739, 24743, 24747, 24751, + 24755, 24759, 24763, 24767, 24771, 24775, 24779, 24783, 24787, 24791, + 24795, 24799, 24803, 24807, 24811, 24815, 24819, 24823, 24827, 24831, + 24835, 24838, 24842, 24846, 24850, 24854, 24858, 0, 0, 24862, 24867, + 24872, 24877, 24882, 24887, 0, 0, 24892, 24896, 24899, 24903, 24906, + 24910, 24913, 24917, 24923, 24928, 24932, 24935, 24939, 24943, 24949, + 24953, 24959, 24963, 24969, 24973, 24979, 24983, 24989, 24995, 24999, + 25005, 25009, 25015, 25021, 25025, 25031, 25037, 25042, 25047, 25055, + 25063, 25070, 25075, 25081, 25090, 25096, 25104, 25109, 25115, 25119, + 25123, 25127, 25131, 25135, 25139, 25143, 25147, 25151, 25155, 25161, + 25166, 25171, 25174, 25178, 25182, 25188, 25192, 25198, 25202, 25208, + 25212, 25218, 25222, 25228, 25232, 25238, 25242, 25248, 25254, 25258, + 25264, 25269, 25273, 25277, 25281, 25285, 25288, 25292, 25298, 25303, + 25308, 25312, 25316, 25320, 25326, 25330, 25336, 25340, 25346, 25349, + 25354, 25358, 25364, 25368, 25374, 25378, 25384, 25390, 25394, 25398, + 25402, 25406, 25410, 25414, 25418, 25422, 25426, 25430, 25434, 25440, + 25443, 25447, 25451, 25457, 25461, 25467, 25471, 25477, 25481, 25487, + 25491, 25497, 25501, 25507, 25511, 25517, 25523, 25527, 25531, 25537, + 25543, 25549, 25555, 25559, 25563, 25567, 25571, 25575, 25579, 25585, + 25589, 25593, 25597, 25603, 25607, 25613, 25617, 25623, 25627, 25633, + 25637, 25643, 25647, 25653, 25657, 25663, 25669, 25673, 25679, 25683, + 25687, 25691, 25695, 25699, 25703, 25709, 25712, 25716, 25720, 25726, + 25730, 25736, 25740, 25746, 25750, 25756, 25760, 25766, 25770, 25776, + 25780, 25786, 25792, 25796, 25802, 25806, 25812, 25818, 25822, 25826, + 25830, 25834, 25838, 25842, 25848, 25851, 25855, 25859, 25865, 25869, + 25875, 25879, 25885, 25891, 25895, 25900, 25904, 25908, 25912, 25916, + 25920, 25924, 25928, 25934, 25937, 25941, 25945, 25951, 25955, 25961, + 25965, 25971, 25975, 25981, 25985, 25991, 25995, 26001, 26005, 26011, + 26014, 26019, 26024, 26028, 26032, 26036, 26040, 26044, 26048, 26054, + 26057, 26061, 26065, 26071, 26075, 26081, 26085, 26091, 26095, 26101, + 26105, 26111, 26115, 26121, 26125, 26131, 26137, 26141, 26147, 26151, + 26157, 26163, 26169, 26175, 26181, 26187, 26193, 26199, 26203, 26207, + 26211, 26215, 26219, 26223, 26227, 26231, 26237, 26241, 26247, 26251, + 26257, 26261, 26267, 26271, 26277, 26281, 26287, 26291, 26297, 26301, + 26305, 26309, 26313, 26317, 26321, 26325, 26331, 26334, 26338, 26342, + 26348, 26352, 26358, 26362, 26368, 26372, 26378, 26382, 26388, 26392, + 26398, 26402, 26408, 26414, 26418, 26424, 26430, 26436, 26440, 26446, + 26452, 26456, 26460, 26464, 26468, 26472, 26478, 26481, 26485, 26490, + 26494, 26500, 26503, 26508, 26513, 26517, 26521, 26525, 26529, 26533, + 26537, 26541, 26545, 26549, 26555, 26559, 26563, 26569, 26573, 26579, + 26583, 26589, 26593, 26597, 26601, 26605, 26609, 26615, 26619, 26623, + 26627, 26631, 26635, 26639, 26643, 26647, 26651, 26655, 26661, 26667, + 26673, 26679, 26685, 26690, 26696, 26702, 26708, 26712, 26716, 26720, + 26724, 26728, 26732, 26736, 26740, 26744, 26748, 26752, 26756, 26760, + 26766, 26772, 26778, 26783, 26787, 26791, 26795, 26799, 26803, 26807, + 26811, 26815, 26819, 26825, 26831, 26837, 26843, 26849, 26855, 26861, + 26867, 26873, 26877, 26881, 26885, 26889, 26893, 26897, 26901, 26907, + 26913, 26919, 26925, 26931, 26937, 26943, 26949, 26955, 26960, 26965, + 26970, 26975, 26981, 26987, 26993, 26999, 27005, 27011, 27017, 27022, + 27028, 27034, 27040, 27045, 27051, 27057, 27063, 27068, 27073, 27078, + 27083, 27088, 27093, 27098, 27103, 27108, 27113, 27118, 27123, 27127, + 27132, 27137, 27142, 27147, 27152, 27157, 27162, 27167, 27172, 27177, + 27182, 27187, 27192, 27197, 27202, 27207, 27212, 27217, 27222, 27227, + 27232, 27237, 27242, 27247, 27252, 27257, 27262, 27267, 27272, 27276, + 27281, 27286, 27291, 27296, 27301, 27306, 27311, 27316, 27321, 27326, + 27331, 27336, 27341, 27346, 27351, 27356, 27361, 27366, 27371, 27376, + 27381, 27386, 27391, 27396, 27401, 27405, 27410, 27415, 27420, 27425, + 27430, 27434, 27439, 27444, 27449, 27454, 27459, 27463, 27468, 27474, + 27479, 27484, 27489, 27494, 27500, 27505, 27510, 27515, 27520, 27525, + 27530, 27535, 27540, 27545, 27550, 27555, 27560, 27564, 27569, 27574, + 27579, 27584, 27589, 27594, 27599, 27604, 27609, 27614, 27619, 27624, + 27629, 27634, 27639, 27644, 27649, 27654, 27659, 27664, 27669, 27674, + 27679, 27684, 27689, 27694, 27699, 27704, 27709, 27714, 27719, 27725, + 27730, 27735, 27740, 27745, 27750, 27755, 27760, 27765, 27770, 27775, + 27780, 27784, 27789, 27794, 27799, 27804, 27809, 27814, 27819, 27824, + 27829, 27834, 27839, 27844, 27849, 27854, 27859, 27864, 27869, 27874, + 27879, 27884, 27889, 27894, 27899, 27904, 27909, 27914, 27920, 27924, + 27928, 27932, 27936, 27940, 27944, 27948, 27952, 27958, 27964, 27970, + 27976, 27982, 27988, 27994, 28001, 28007, 28012, 28017, 28022, 28027, + 28032, 28037, 28042, 28047, 28052, 28057, 28062, 28067, 28072, 28077, + 28082, 28087, 28092, 28097, 28102, 28107, 28112, 28117, 28122, 28127, + 28132, 28137, 28142, 28147, 0, 0, 0, 28154, 28165, 28170, 28178, 28183, + 28188, 28193, 28202, 28207, 28213, 28219, 28225, 28230, 28236, 28242, + 28246, 28251, 28256, 28266, 28271, 28276, 28283, 28288, 28293, 28302, + 28307, 28316, 28323, 28330, 28337, 28344, 28355, 28362, 28367, 28377, + 28381, 28388, 28393, 28400, 28406, 28413, 28422, 28429, 28436, 28445, + 28452, 28457, 28462, 28473, 28480, 28485, 28496, 28503, 28508, 28513, + 28521, 28530, 28537, 28544, 28554, 28559, 28564, 28569, 28578, 28586, + 28591, 28596, 28601, 28606, 28611, 28616, 28621, 28626, 28631, 28636, + 28641, 28647, 28653, 28659, 28664, 28669, 28674, 28679, 28684, 28689, + 28698, 28707, 28716, 28725, 0, 0, 0, 0, 0, 0, 0, 28734, 28738, 28742, + 28746, 28750, 28755, 28760, 28765, 28770, 28774, 28778, 28783, 28787, + 28791, 28795, 28799, 28804, 28808, 28812, 28817, 28822, 28827, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 28832, 28838, 28842, 28846, 28850, 28854, 28859, 28864, + 28869, 28874, 28878, 28882, 28887, 28891, 28895, 28899, 28903, 28908, + 28912, 28916, 28921, 28926, 28931, 28937, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 28942, 28946, 28950, 28954, 28958, 28963, 28968, 28973, 28978, 28982, + 28986, 28991, 28995, 28999, 29003, 29007, 29012, 29016, 29020, 29025, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29030, 29034, 29038, 29042, 29046, + 29051, 29056, 29061, 29066, 29070, 29074, 29079, 29083, 0, 29087, 29091, + 29096, 0, 29100, 29105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29110, 29113, + 29117, 29121, 29125, 29129, 29133, 29137, 29141, 29145, 29149, 29153, + 29157, 29161, 29165, 29169, 29173, 29177, 29180, 29184, 29188, 29192, + 29196, 29200, 29204, 29208, 29212, 29216, 29220, 29224, 29228, 29232, + 29235, 29238, 29241, 29245, 29251, 29257, 29263, 29269, 29275, 29281, + 29287, 29293, 29299, 29305, 29311, 29317, 29323, 29329, 29338, 29347, + 29353, 29359, 29365, 29370, 29374, 29379, 29384, 29389, 29393, 29398, + 29403, 29408, 29412, 29417, 29421, 29426, 29431, 29436, 29441, 29445, + 29449, 29453, 29457, 29461, 29465, 29469, 29473, 29477, 29481, 29487, + 29491, 29495, 29499, 29503, 29507, 29515, 29521, 29525, 29531, 29535, + 29541, 29545, 0, 0, 29549, 29553, 29556, 29559, 29562, 29565, 29568, + 29571, 29574, 29577, 0, 0, 0, 0, 0, 0, 29580, 29588, 29596, 29604, 29612, + 29620, 29628, 29636, 29644, 29652, 0, 0, 0, 0, 0, 0, 29660, 29663, 29666, + 29669, 29674, 29677, 29682, 29689, 29697, 29702, 29709, 29712, 29719, + 29726, 29733, 29737, 29744, 29748, 29751, 29754, 29757, 29760, 29763, + 29766, 29769, 29772, 0, 0, 0, 0, 0, 0, 29775, 29778, 29781, 29784, 29787, + 29790, 29794, 29798, 29802, 29805, 29809, 29813, 29816, 29820, 29824, + 29827, 29830, 29833, 29837, 29841, 29845, 29849, 29853, 29856, 29859, + 29863, 29867, 29870, 29874, 29878, 29882, 29886, 29890, 29894, 29898, + 29902, 29909, 29914, 29919, 29924, 29929, 29935, 29941, 29947, 29953, + 29958, 29964, 29970, 29975, 29981, 29987, 29993, 29999, 30005, 30010, + 30016, 30021, 30027, 30033, 30039, 30045, 30051, 30056, 30061, 30067, + 30073, 30078, 30084, 30089, 30095, 30100, 30105, 30111, 30117, 30123, + 30129, 30135, 30141, 30147, 30153, 30159, 30165, 30171, 30177, 30182, + 30187, 30192, 30198, 30204, 0, 0, 0, 0, 0, 0, 0, 30212, 30221, 30230, + 30238, 30246, 30256, 30264, 30273, 30280, 30287, 30294, 30302, 30310, + 30318, 30326, 30334, 30342, 30350, 30358, 30365, 30373, 30381, 30389, + 30397, 30405, 30415, 30425, 30435, 30445, 30455, 30465, 30475, 30485, + 30495, 30505, 30515, 30525, 30535, 30545, 30553, 30561, 30571, 30579, 0, + 0, 0, 0, 0, 30589, 30593, 30597, 30601, 30605, 30609, 30613, 30617, + 30621, 30625, 30629, 30633, 30637, 30641, 30645, 30649, 30653, 30657, + 30661, 30665, 30669, 30673, 30677, 30681, 30687, 30691, 30697, 30701, + 30707, 30711, 30717, 30721, 30725, 30729, 30733, 30737, 30741, 30747, + 30753, 30759, 30765, 30771, 30777, 30783, 30789, 30795, 30801, 30807, + 30814, 30820, 30826, 30832, 30836, 30840, 30844, 30848, 30852, 30856, + 30860, 30866, 30872, 30878, 30883, 30890, 30895, 30900, 30906, 30911, + 30918, 30925, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30932, 30938, 30942, 30947, + 30952, 30957, 30962, 30967, 30972, 30977, 30982, 30987, 30992, 30997, + 31002, 31007, 31011, 31015, 31020, 31025, 31030, 31034, 31038, 31042, + 31046, 31051, 31056, 31061, 31065, 31069, 31074, 0, 31079, 31084, 31089, + 31094, 31100, 31106, 31112, 31118, 31123, 31128, 31134, 31140, 0, 0, 0, + 0, 31147, 31152, 31158, 31164, 31170, 31175, 31180, 31185, 31190, 31195, + 31200, 31205, 0, 0, 0, 0, 31210, 0, 0, 0, 31215, 31220, 31225, 31230, + 31234, 31238, 31242, 31246, 31250, 31254, 31258, 31262, 31266, 31271, + 31277, 31283, 31289, 31294, 31299, 31305, 31311, 31316, 31321, 31327, + 31332, 31338, 31344, 31349, 31355, 31361, 31367, 31372, 31377, 31382, + 31388, 31394, 31399, 31405, 31410, 31416, 31421, 31427, 0, 0, 31433, + 31439, 31445, 31451, 31457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31463, + 31472, 31481, 31489, 31498, 31507, 31515, 31524, 31533, 31542, 31550, + 31558, 31567, 31575, 31583, 31592, 31601, 31609, 31618, 31627, 31635, + 31643, 31652, 31660, 31668, 31677, 31685, 31694, 31703, 31711, 31720, + 31729, 31737, 31745, 31754, 31763, 31771, 31780, 31789, 31798, 31807, + 31816, 31825, 31834, 0, 0, 0, 0, 31843, 31853, 31862, 31871, 31879, + 31888, 31896, 31905, 31913, 31922, 31931, 31940, 31949, 31958, 31967, + 31976, 31985, 31994, 32003, 32012, 32021, 32030, 32039, 32048, 32057, + 32065, 0, 0, 0, 0, 0, 0, 32073, 32081, 32088, 32095, 32102, 32109, 32116, + 32123, 32130, 32137, 32144, 0, 0, 0, 32152, 32160, 32168, 32172, 32178, + 32184, 32190, 32196, 32202, 32208, 32214, 32220, 32226, 32232, 32238, + 32244, 32250, 32256, 32262, 32266, 32272, 32278, 32284, 32290, 32296, + 32302, 32308, 32314, 32320, 32326, 32332, 32338, 32344, 32350, 32356, + 32360, 32365, 32370, 32375, 32379, 32384, 32388, 32393, 32398, 32403, + 32407, 32412, 32417, 32422, 32427, 32432, 32436, 32440, 32444, 32449, + 32453, 32457, 32461, 32466, 32471, 32476, 32481, 0, 0, 32487, 32491, + 32498, 32503, 32509, 32515, 32520, 32526, 32532, 32537, 32543, 32549, + 32555, 32560, 32566, 32571, 32576, 32582, 32587, 32593, 32598, 32604, + 32610, 32616, 32622, 32626, 32631, 32636, 32642, 32648, 32653, 32659, + 32665, 32669, 32674, 32679, 32683, 32688, 32692, 32697, 32702, 32708, + 32714, 32719, 32724, 32729, 32733, 32738, 32742, 32747, 32751, 32756, + 32761, 32766, 32771, 32777, 32784, 32791, 32801, 32810, 32817, 32823, + 32834, 32839, 32845, 0, 32850, 32855, 32860, 32868, 32874, 32882, 32887, + 32893, 32899, 32905, 32910, 32916, 32921, 32928, 32934, 32939, 32945, + 32951, 32957, 32964, 32971, 32978, 32983, 32988, 32995, 33002, 33009, + 33016, 33023, 0, 0, 33030, 33037, 33044, 33050, 33056, 33062, 33068, + 33074, 33080, 33086, 33092, 0, 0, 0, 0, 0, 0, 33098, 33104, 33109, 33114, + 33119, 33124, 33129, 33134, 33139, 33144, 0, 0, 0, 0, 0, 0, 33149, 33154, + 33159, 33164, 33169, 33174, 33179, 33188, 33195, 33200, 33205, 33210, + 33215, 33220, 0, 0, 33225, 33232, 33235, 33238, 33242, 33247, 33251, + 33257, 33262, 33268, 33275, 33283, 33287, 33292, 33296, 33301, 33308, + 33316, 33323, 33329, 33337, 33344, 33349, 33353, 33360, 33364, 33369, + 33374, 33381, 33389, 33396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33404, 33410, 33416, 33420, 33424, 33428, + 33432, 33438, 33442, 33448, 33452, 33458, 33464, 33472, 33478, 33486, + 33490, 33494, 33498, 33504, 33507, 33513, 33517, 33523, 33527, 33531, + 33537, 33541, 33547, 33551, 33557, 33565, 33573, 33581, 33587, 33591, + 33597, 33601, 33607, 33610, 33613, 33619, 33623, 33629, 33632, 33635, + 33638, 33641, 33645, 33651, 33657, 33660, 33663, 33667, 33672, 33677, + 33684, 33689, 33696, 33703, 33712, 33719, 33728, 33733, 33740, 33747, + 33756, 33761, 33768, 33773, 33779, 33785, 33791, 33797, 33803, 33809, + 33815, 0, 0, 0, 33821, 33825, 33828, 33831, 33834, 33837, 33840, 33843, + 33846, 33849, 33852, 33855, 33858, 33861, 33866, 33871, 33876, 33879, + 33884, 33889, 33894, 33899, 33906, 33911, 33916, 33921, 33926, 33933, + 33939, 33945, 33951, 33957, 33963, 33972, 33981, 33987, 33993, 34002, + 34011, 34020, 34029, 34038, 34047, 34056, 34065, 34074, 34079, 0, 34084, + 34089, 34094, 34099, 34103, 34107, 34111, 34116, 34120, 34124, 34129, + 34133, 34138, 34143, 34148, 34153, 34158, 34163, 34168, 34173, 34178, + 34182, 34186, 34191, 34196, 34201, 34205, 34209, 34213, 34217, 34222, + 34226, 34231, 34235, 34241, 34247, 34253, 34259, 34265, 34271, 34277, + 34283, 34289, 34294, 34299, 34306, 34314, 34319, 34324, 34329, 34333, + 34337, 34341, 34345, 34349, 34353, 34357, 34361, 34365, 34369, 34374, + 34379, 34384, 34390, 34396, 34400, 34406, 34410, 34416, 34422, 34427, + 34434, 34438, 34444, 34448, 34454, 34459, 34466, 34473, 34478, 34485, + 34490, 34495, 34499, 34505, 34509, 34515, 34522, 34529, 34533, 34539, + 34545, 34549, 34555, 34560, 34564, 34570, 34575, 34580, 34585, 34590, + 34594, 34598, 34603, 34608, 34615, 34621, 34626, 34633, 34638, 34645, + 34650, 34659, 34665, 34671, 34675, 0, 0, 0, 0, 0, 0, 0, 0, 34679, 34688, + 34695, 34702, 34709, 34713, 34718, 34723, 34728, 34733, 34738, 34743, + 34748, 34753, 34758, 34763, 34768, 34773, 34777, 34781, 34786, 34791, + 34796, 34801, 34806, 34811, 34815, 34820, 34825, 34830, 34835, 34839, + 34843, 34847, 34851, 34856, 34861, 34865, 34870, 34875, 34879, 34885, + 34891, 34897, 34902, 34907, 34913, 34918, 34924, 34929, 34935, 34941, + 34946, 34952, 34958, 34963, 34969, 34975, 34981, 34986, 0, 0, 0, 34991, + 34997, 35007, 35013, 35021, 35027, 35032, 35036, 35040, 35044, 35048, + 35052, 35056, 35060, 35064, 0, 0, 0, 35068, 35073, 35078, 35083, 35090, + 35096, 35102, 35108, 35114, 35120, 35126, 35132, 35138, 35144, 35150, + 35157, 35164, 35171, 35178, 35185, 35192, 35199, 35206, 35213, 35220, + 35227, 35234, 35241, 35248, 35255, 35262, 35269, 35276, 35283, 35290, + 35297, 35304, 35311, 35318, 35325, 35332, 35339, 35346, 35353, 35361, + 35369, 35377, 35383, 35389, 35395, 35403, 35412, 35419, 35426, 35432, + 35439, 35446, 35453, 35461, 35468, 0, 0, 0, 0, 0, 0, 0, 35475, 35482, + 35489, 35496, 35503, 35510, 35517, 35524, 35531, 35538, 35545, 35552, + 35559, 35566, 35573, 35580, 35587, 35594, 35601, 35608, 35615, 35622, + 35629, 35636, 35643, 35650, 35657, 35664, 35671, 35678, 35685, 35692, + 35699, 35706, 35713, 35720, 35727, 35734, 35741, 35748, 35755, 35762, + 35770, 0, 0, 35777, 35784, 35792, 35800, 35808, 35816, 35824, 35832, + 35842, 35852, 35862, 0, 0, 0, 0, 0, 0, 0, 0, 35872, 35877, 35882, 35887, + 35892, 35901, 35912, 35921, 35932, 35938, 35951, 35957, 35964, 35971, + 35976, 35982, 35988, 35999, 36008, 36015, 36022, 36031, 36038, 36047, + 36057, 36067, 36074, 36081, 36088, 36098, 36103, 36111, 36117, 36125, + 36134, 36139, 36146, 36152, 36157, 36162, 36167, 36173, 36180, 0, 0, 0, + 0, 0, 36188, 36193, 36199, 36205, 36213, 36219, 36225, 36231, 36236, + 36243, 36248, 36254, 36260, 36268, 36274, 36282, 36287, 36294, 36300, + 36308, 36316, 36322, 36328, 36335, 36342, 36348, 36355, 36361, 36367, + 36372, 36378, 36386, 36394, 36400, 36406, 36412, 36418, 36426, 36430, + 36436, 36442, 36448, 36454, 36460, 36466, 36470, 36475, 36480, 36487, + 36492, 36496, 36502, 36507, 36512, 36516, 36521, 36526, 36530, 36535, + 36540, 36547, 36551, 36556, 36561, 36565, 36570, 36574, 36579, 36583, + 36588, 36593, 36599, 36604, 36609, 36613, 36618, 36624, 36631, 36636, + 36641, 36646, 36651, 36656, 36660, 36666, 36673, 36680, 36685, 36690, + 36694, 36700, 36706, 36711, 36716, 36721, 36727, 36732, 36738, 36743, + 36749, 36755, 36761, 36768, 36775, 36782, 36789, 36796, 36803, 36808, + 36816, 36825, 36834, 36843, 36852, 36861, 36870, 36882, 36891, 36900, + 36909, 36915, 36920, 36927, 36935, 36943, 36950, 36957, 36964, 36971, + 36979, 36988, 36997, 37006, 37015, 37024, 37033, 37042, 37051, 37060, + 37069, 37078, 37087, 37096, 37105, 37113, 37122, 37133, 37142, 37153, + 37166, 37175, 37184, 37194, 37203, 37211, 37220, 37226, 37231, 37239, + 37244, 37252, 37257, 37266, 37272, 37278, 37285, 37290, 37295, 37303, + 37311, 37320, 37329, 37334, 37341, 37351, 37359, 37368, 37374, 37380, + 37385, 37392, 37397, 37406, 37411, 37416, 37421, 37428, 37434, 37439, + 37448, 37456, 37461, 37466, 37473, 37480, 37484, 37488, 37491, 37494, + 37497, 37500, 37503, 37506, 37513, 37516, 37519, 37524, 37528, 37532, + 37536, 37540, 37544, 37554, 37560, 37566, 37572, 37580, 37588, 37594, + 37600, 37607, 37613, 37618, 37624, 37631, 37637, 37644, 37650, 37658, + 37664, 37671, 37677, 37683, 37689, 37695, 37701, 37707, 37718, 37728, + 37734, 37740, 37750, 37756, 37764, 37772, 37780, 37785, 37790, 37796, + 37801, 37809, 37815, 37819, 37826, 37833, 37838, 37847, 37855, 37863, + 37870, 37877, 37884, 37891, 37899, 37907, 37918, 37929, 37937, 37945, + 37953, 37961, 37970, 37979, 37987, 37995, 38004, 38013, 38024, 38035, + 38046, 38057, 38066, 38075, 38084, 38093, 38104, 38115, 38123, 38131, + 38139, 38147, 38155, 38163, 38171, 38179, 38187, 38195, 38203, 38211, + 38220, 38229, 38238, 38247, 38258, 38269, 38277, 38285, 38293, 38301, + 38310, 38319, 38327, 38335, 38347, 38359, 38368, 38377, 38386, 38395, + 38403, 38411, 38419, 38427, 38435, 38443, 38451, 38459, 38467, 38475, + 38484, 38493, 38502, 38511, 38521, 38531, 38541, 38551, 38561, 38571, + 38581, 38591, 38599, 38607, 38615, 38623, 38631, 38639, 38647, 38655, + 38667, 38679, 38688, 38697, 38705, 38713, 38721, 38729, 38740, 38751, + 38762, 38773, 38785, 38797, 38805, 38813, 38821, 38829, 38838, 38847, + 38856, 38865, 38873, 38881, 38889, 38897, 38905, 38913, 38923, 38933, + 38943, 38953, 38961, 38969, 38977, 38985, 38993, 39001, 39009, 39017, + 39025, 39033, 39041, 39049, 39057, 39065, 39073, 39081, 39089, 39097, + 39105, 39113, 39121, 39129, 39137, 39145, 39154, 39163, 39172, 39180, + 39189, 39198, 39207, 39216, 39226, 39235, 39242, 39247, 39254, 39261, + 39269, 39277, 39287, 39297, 39307, 39317, 39328, 39339, 39349, 39359, + 39369, 39379, 39389, 39399, 39409, 39419, 39430, 39441, 39451, 39461, + 39471, 39481, 39489, 39497, 39506, 39515, 39523, 39531, 39542, 39553, + 39564, 39575, 39587, 39599, 39610, 39621, 39632, 39643, 39652, 39661, + 39669, 39677, 39684, 39691, 39699, 39707, 39717, 39727, 39737, 39747, + 39758, 39769, 39779, 39789, 39799, 39809, 39819, 39829, 39839, 39849, + 39860, 39871, 39881, 39891, 39901, 39911, 39918, 39925, 39933, 39941, + 39951, 39961, 39971, 39981, 39992, 40003, 40013, 40023, 40033, 40043, + 40051, 40059, 40067, 40075, 40084, 40093, 40101, 40109, 40116, 40123, + 40130, 40137, 40145, 40153, 40161, 40169, 40180, 40191, 40202, 40213, + 40224, 40235, 40243, 40251, 40262, 40273, 40284, 40295, 40306, 40317, + 40325, 40333, 40344, 40355, 40366, 0, 0, 40377, 40385, 40393, 40404, + 40415, 40426, 0, 0, 40437, 40445, 40453, 40464, 40475, 40486, 40497, + 40508, 40519, 40527, 40535, 40546, 40557, 40568, 40579, 40590, 40601, + 40609, 40617, 40628, 40639, 40650, 40661, 40672, 40683, 40691, 40699, + 40710, 40721, 40732, 40743, 40754, 40765, 40773, 40781, 40792, 40803, + 40814, 0, 0, 40825, 40833, 40841, 40852, 40863, 40874, 0, 0, 40885, + 40893, 40901, 40912, 40923, 40934, 40945, 40956, 0, 40967, 0, 40975, 0, + 40986, 0, 40997, 41008, 41016, 41024, 41035, 41046, 41057, 41068, 41079, + 41090, 41098, 41106, 41117, 41128, 41139, 41150, 41161, 41172, 41180, + 41188, 41196, 41204, 41212, 41220, 41228, 41236, 41244, 41252, 41260, + 41268, 41276, 0, 0, 41284, 41295, 41306, 41320, 41334, 41348, 41362, + 41376, 41390, 41401, 41412, 41426, 41440, 41454, 41468, 41482, 41496, + 41507, 41518, 41532, 41546, 41560, 41574, 41588, 41602, 41613, 41624, + 41638, 41652, 41666, 41680, 41694, 41708, 41719, 41730, 41744, 41758, + 41772, 41786, 41800, 41814, 41825, 41836, 41850, 41864, 41878, 41892, + 41906, 41920, 41928, 41936, 41947, 41955, 0, 41966, 41974, 41985, 41993, + 42001, 42009, 42017, 42025, 42028, 42031, 42034, 42037, 42043, 42054, + 42062, 0, 42073, 42081, 42092, 42100, 42108, 42116, 42124, 42132, 42138, + 42144, 42150, 42158, 42166, 42177, 0, 0, 42188, 42196, 42207, 42215, + 42223, 42231, 0, 42239, 42245, 42251, 42257, 42265, 42273, 42284, 42295, + 42303, 42311, 42319, 42330, 42338, 42346, 42354, 42362, 42370, 42376, + 42382, 0, 0, 42385, 42396, 42404, 0, 42415, 42423, 42434, 42442, 42450, + 42458, 42466, 42474, 42477, 0, 42480, 42484, 42488, 42492, 42496, 42500, + 42504, 42508, 42512, 42516, 42520, 42524, 42530, 42536, 42542, 42545, + 42548, 42550, 42554, 42558, 42562, 42566, 42569, 42573, 42577, 42583, + 42589, 42596, 42603, 42608, 42613, 42619, 42625, 42627, 42630, 42632, + 42636, 42640, 42644, 42648, 42652, 42656, 42660, 42664, 42668, 42674, + 42678, 42682, 42688, 42693, 42700, 42702, 42705, 42709, 42713, 42718, + 42724, 42726, 42735, 42744, 42747, 42751, 42753, 42755, 42757, 42761, + 42767, 42769, 42773, 42777, 42784, 42791, 42795, 42800, 42805, 42810, + 42815, 42819, 42823, 42826, 42830, 42834, 42841, 42846, 42850, 42854, + 42859, 42863, 42867, 42872, 42877, 42881, 42885, 42889, 42891, 42896, + 42901, 42905, 42909, 42913, 42917, 0, 42921, 42925, 42929, 42935, 42941, + 42947, 42953, 42960, 42967, 42972, 42977, 42981, 0, 0, 42987, 42990, + 42993, 42996, 42999, 43002, 43005, 43009, 43013, 43018, 43023, 43028, + 43035, 43039, 43042, 43045, 43048, 43051, 43054, 43057, 43060, 43063, + 43066, 43070, 43074, 43079, 43084, 0, 43089, 43095, 43101, 43107, 43114, + 43121, 43128, 43135, 43141, 43148, 43155, 43162, 43169, 0, 0, 0, 43176, + 43179, 43182, 43185, 43190, 43193, 43196, 43199, 43202, 43205, 43208, + 43213, 43216, 43219, 43222, 43225, 43228, 43233, 43236, 43239, 43242, + 43245, 43248, 43253, 43256, 43259, 43264, 43269, 43273, 43276, 43279, + 43282, 43285, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43288, 43293, + 43298, 43305, 43313, 43318, 43323, 43327, 43331, 43336, 43343, 43350, + 43354, 43359, 43364, 43369, 43374, 43381, 43386, 43391, 43396, 43405, + 43412, 43419, 43423, 43428, 43434, 43439, 43446, 43454, 43462, 43466, + 43470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43474, 43478, 43485, + 43490, 43494, 43499, 43503, 43507, 43511, 43513, 43517, 43521, 43525, + 43530, 43535, 43539, 43547, 43550, 43554, 43557, 43560, 43566, 43571, + 43574, 43580, 43584, 43589, 43594, 43597, 43601, 43605, 43609, 43611, + 43614, 43617, 43621, 43623, 43628, 43631, 43634, 43639, 43644, 43650, + 43653, 43656, 43660, 43665, 43668, 43671, 43674, 43678, 43682, 43686, + 43689, 43691, 43694, 43697, 43700, 43704, 43709, 43712, 43717, 43722, + 43727, 43732, 43738, 43743, 43747, 43752, 43757, 43763, 43769, 43774, + 43779, 43785, 43789, 43792, 43795, 43797, 43801, 43807, 43814, 43821, + 43828, 43835, 43842, 43849, 43856, 43863, 43871, 43878, 43886, 43893, + 43900, 43908, 43916, 43921, 43926, 43931, 43936, 43941, 43946, 43951, + 43956, 43961, 43966, 43972, 43978, 43984, 43990, 43997, 44005, 44011, + 44017, 44023, 44029, 44035, 44041, 44047, 44053, 44059, 44065, 44072, + 44079, 44086, 44093, 44101, 44110, 44117, 44128, 44135, 44142, 44151, + 44158, 44167, 44176, 44183, 44191, 44199, 44202, 0, 0, 0, 0, 44205, + 44207, 44210, 44212, 44215, 44218, 44221, 44225, 44229, 44234, 44239, + 44243, 44247, 44251, 44255, 44260, 44266, 44271, 44277, 44282, 44287, + 44292, 44298, 44303, 44309, 44315, 44319, 44323, 44328, 44333, 44338, + 44343, 44348, 44356, 44364, 44372, 44380, 44387, 44395, 44402, 44409, + 44416, 44426, 44433, 44440, 44447, 44454, 44462, 44470, 44477, 44484, + 44492, 44500, 44505, 44513, 44518, 44523, 44529, 44534, 44540, 44547, + 44554, 44559, 44565, 44570, 44573, 44577, 44580, 44584, 44588, 44592, + 44597, 44602, 44608, 44614, 44618, 44622, 44626, 44630, 44636, 44642, + 44646, 44651, 44655, 44660, 44664, 44668, 44671, 44675, 44678, 44682, + 44689, 44697, 44709, 44720, 44725, 44734, 44741, 44748, 44756, 44760, + 44766, 44774, 44778, 44783, 44788, 44794, 44800, 44806, 44813, 44817, + 44821, 44826, 44829, 44831, 44835, 44839, 44847, 44851, 44853, 44855, + 44859, 44867, 44872, 44878, 44888, 44895, 44900, 44904, 44908, 44912, + 44915, 44918, 44921, 44925, 44929, 44933, 44937, 44941, 44944, 44948, + 44952, 44955, 44957, 44960, 44962, 44966, 44970, 44972, 44978, 44981, + 44986, 44990, 44994, 44996, 44998, 45000, 45003, 45007, 45011, 45015, + 45019, 45023, 45029, 45035, 45037, 45039, 45041, 45043, 45046, 45048, + 45052, 45054, 45058, 45062, 45068, 45072, 45076, 45080, 45084, 45089, + 45096, 45101, 45112, 45123, 45128, 45135, 45144, 45148, 45153, 45156, + 45161, 45165, 45171, 45176, 45189, 45199, 45203, 45207, 45214, 45219, + 45222, 45224, 45227, 45231, 45236, 45243, 45247, 45252, 45257, 45260, + 45265, 45270, 45277, 45284, 45290, 45296, 45305, 45314, 45318, 45322, + 45324, 45329, 45333, 45337, 45346, 45355, 45362, 45369, 45378, 45387, + 45393, 45399, 45407, 45415, 45417, 45419, 45426, 45433, 45440, 45447, + 45453, 45459, 45463, 45467, 45474, 45481, 45489, 45497, 45508, 45519, + 45528, 45537, 45539, 45543, 45547, 45552, 45557, 45566, 45575, 45578, + 45581, 45584, 45587, 45590, 45595, 45599, 45604, 45609, 45612, 45615, + 45618, 45621, 45624, 45628, 45631, 45634, 45637, 45640, 45642, 45644, + 45646, 45648, 45656, 45664, 45670, 45674, 45680, 45690, 45696, 45702, + 45708, 45716, 45726, 45739, 45743, 45747, 45749, 45755, 45757, 45759, + 45761, 45763, 45769, 45772, 45778, 45784, 45788, 45792, 45796, 45799, + 45803, 45807, 45809, 45818, 45827, 45832, 45837, 45843, 45849, 45855, + 45858, 45861, 45864, 45867, 45869, 45875, 45880, 45885, 45891, 45897, + 45906, 45915, 45922, 45929, 45936, 45943, 45953, 45963, 45974, 45985, + 45996, 46007, 46016, 46025, 46034, 46043, 46051, 46063, 46075, 46091, + 46094, 46100, 46106, 46112, 46120, 46135, 46151, 46157, 46163, 46170, + 46176, 46185, 46192, 46206, 46221, 46226, 46232, 46240, 46243, 46246, + 46248, 46251, 46254, 46256, 46258, 46262, 46265, 46268, 46271, 46274, + 46279, 46284, 46289, 46294, 46299, 46302, 46304, 46306, 46308, 46312, + 46316, 46320, 46326, 46330, 46332, 46334, 46339, 46344, 46349, 46354, + 46359, 46364, 46366, 46368, 46378, 46382, 46388, 46397, 46399, 46405, + 46411, 46418, 46422, 46424, 46428, 46430, 46434, 46438, 46442, 46444, + 46446, 46448, 46455, 46464, 46473, 46482, 46491, 46500, 46509, 46518, + 46527, 46535, 46543, 46552, 46561, 46570, 46579, 46587, 46595, 46604, + 46613, 46622, 46632, 46641, 46651, 46660, 46670, 46679, 46689, 46699, + 46708, 46718, 46727, 46737, 46746, 46756, 46765, 46774, 46783, 46792, + 46801, 46811, 46820, 46829, 46838, 46848, 46857, 46866, 46875, 46884, + 46894, 46904, 46913, 46922, 46930, 46939, 46946, 46955, 46964, 46975, + 46984, 46994, 47004, 47011, 47018, 47025, 47034, 47043, 47052, 47061, + 47068, 47073, 47082, 47088, 47091, 47098, 47101, 47106, 47111, 47114, + 47117, 47125, 47128, 47133, 47136, 47144, 47149, 47157, 47160, 47163, + 47166, 47171, 47176, 47179, 47182, 47190, 47193, 47200, 47207, 47211, + 47215, 47220, 47225, 47230, 47235, 47240, 47245, 47250, 47255, 47262, + 47268, 47275, 47282, 47288, 47295, 47302, 47310, 47317, 47323, 47330, + 47338, 47345, 47349, 47355, 47367, 47379, 47383, 47387, 47392, 47397, + 47408, 47412, 47417, 47422, 47428, 47434, 47440, 47446, 47455, 47464, + 47472, 47483, 47494, 47502, 47513, 47524, 47532, 47543, 47554, 47562, + 47570, 47580, 47590, 47593, 47596, 47599, 47604, 47608, 47614, 47621, + 47628, 47636, 47643, 47647, 47651, 47655, 47659, 47661, 47665, 47669, + 47675, 47681, 47689, 47697, 47700, 47707, 47709, 47711, 47715, 47719, + 47724, 47730, 47736, 47742, 47748, 47757, 47766, 47775, 47779, 47781, + 47785, 47792, 47799, 47806, 47813, 47820, 47823, 47828, 47834, 47837, + 47842, 47847, 47852, 47857, 47861, 47868, 47875, 47882, 47889, 47893, + 47897, 47901, 47905, 47911, 47917, 47922, 47928, 47934, 47940, 47946, + 47954, 47961, 47968, 47975, 47982, 47988, 47994, 48003, 48007, 48014, + 48018, 48022, 48028, 48034, 48040, 48046, 48050, 48054, 48057, 48061, + 48065, 48072, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 48079, 48082, 48086, 48090, 48096, 48102, 48108, 48116, + 48123, 48127, 48135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 48140, 48143, 48146, 48149, 48152, 48155, 48158, 48161, + 48164, 48167, 48171, 48175, 48179, 48183, 48187, 48191, 48195, 48199, + 48203, 48207, 48211, 48214, 48217, 48220, 48223, 48226, 48229, 48232, + 48235, 48238, 48242, 48246, 48250, 48254, 48258, 48262, 48266, 48270, + 48274, 48278, 48282, 48288, 48294, 48300, 48307, 48314, 48321, 48328, + 48335, 48342, 48349, 48356, 48363, 48370, 48377, 48384, 48391, 48398, + 48405, 48412, 48419, 48424, 48430, 48436, 48442, 48447, 48453, 48459, + 48465, 48470, 48476, 48482, 48487, 48493, 48499, 48504, 48510, 48516, + 48521, 48527, 48533, 48538, 48544, 48550, 48556, 48562, 48568, 48573, + 48579, 48585, 48591, 48596, 48602, 48608, 48614, 48619, 48625, 48631, + 48636, 48642, 48648, 48653, 48659, 48665, 48670, 48676, 48682, 48687, + 48693, 48699, 48705, 48711, 48717, 48722, 48728, 48734, 48740, 48745, + 48751, 48757, 48763, 48768, 48774, 48780, 48785, 48791, 48797, 48802, + 48808, 48814, 48819, 48825, 48831, 48836, 48842, 48848, 48854, 48860, + 48866, 48870, 48876, 48882, 48888, 48894, 48900, 48906, 48912, 48918, + 48924, 48930, 48934, 48938, 48942, 48946, 48950, 48954, 48958, 48962, + 48966, 48971, 48977, 48982, 48987, 48992, 48997, 49006, 49015, 49024, + 49033, 49042, 49051, 49060, 49069, 49075, 49083, 49091, 49097, 49104, + 49112, 49120, 49127, 49133, 49141, 49149, 49155, 49162, 49170, 49178, + 49185, 49191, 49199, 49208, 49217, 49225, 49234, 49243, 49249, 49256, + 49264, 49273, 49282, 49290, 49299, 49308, 49315, 49322, 49331, 49340, + 49349, 49358, 49367, 49376, 49383, 49390, 49399, 49408, 49417, 49426, + 49435, 49444, 49451, 49458, 49467, 49476, 49485, 49495, 49505, 49514, + 49524, 49534, 49544, 49554, 49564, 49574, 49583, 49592, 49599, 49607, + 49615, 49623, 49631, 49636, 49641, 49650, 49658, 49664, 49673, 49681, + 49688, 49697, 49705, 49711, 49720, 49728, 49735, 49744, 49752, 49758, + 49767, 49775, 49782, 49792, 49801, 49808, 49818, 49827, 49834, 49844, + 49853, 49860, 49868, 49877, 49886, 49894, 49905, 49915, 49922, 49927, + 49932, 49936, 49941, 49946, 49951, 49955, 49960, 49967, 49975, 49982, + 49990, 49994, 50000, 50006, 50012, 50016, 50023, 50029, 50036, 50040, + 50047, 50053, 50060, 50064, 50070, 50076, 50082, 50086, 50089, 50093, + 50097, 50103, 50109, 50114, 50118, 50123, 50133, 50140, 50151, 50161, + 50165, 50173, 50183, 50186, 50189, 50196, 50204, 50210, 50215, 50223, + 50232, 50241, 50249, 50253, 50257, 50260, 50263, 50267, 50271, 50274, + 50277, 50282, 50287, 50293, 50299, 50304, 50309, 50315, 50321, 50326, + 50331, 50336, 50341, 50347, 50353, 50358, 50363, 50369, 50375, 50380, + 50385, 50388, 50391, 50400, 50402, 50404, 50407, 50411, 50417, 50419, + 50422, 50429, 50436, 50443, 50450, 50459, 50472, 50477, 50482, 50486, + 50491, 50498, 50505, 50513, 50521, 50529, 50537, 50541, 50545, 50550, + 50555, 50560, 50565, 50568, 50574, 50580, 50589, 50598, 50606, 50614, + 50623, 50632, 50636, 50643, 50650, 50657, 50664, 50672, 50680, 50688, + 50696, 50700, 50704, 50708, 50713, 50718, 50724, 50730, 50734, 50740, + 50742, 50744, 50746, 50748, 50751, 50754, 50756, 50758, 50760, 50764, + 50768, 50770, 50772, 50775, 50778, 50782, 50788, 50794, 50796, 50803, + 50807, 50812, 50817, 50819, 50829, 50835, 50841, 50847, 50853, 50859, + 50865, 50870, 50873, 50876, 50879, 50881, 50883, 50887, 50891, 50896, + 50901, 50906, 50909, 50913, 50918, 50921, 50925, 50930, 50935, 50940, + 50945, 50950, 50955, 50960, 50965, 50970, 50975, 50980, 50985, 50991, + 50997, 51003, 51005, 51008, 51010, 51013, 51015, 51017, 51019, 51021, + 51023, 51025, 51027, 51029, 51031, 51033, 51035, 51037, 51039, 51041, + 51043, 51045, 51047, 51052, 51057, 51062, 51067, 51072, 51077, 51082, + 51087, 51092, 51097, 51102, 51107, 51112, 51117, 51122, 51127, 51132, + 51137, 51142, 51147, 51151, 51155, 51159, 51165, 51171, 51176, 51181, + 51186, 51192, 51198, 51203, 51211, 51219, 51227, 51235, 51243, 51251, + 51259, 51267, 51273, 51278, 51283, 51288, 51291, 51295, 51299, 51303, + 51307, 51311, 51315, 51321, 51328, 51335, 51343, 51348, 51353, 51360, + 51367, 51374, 51381, 51384, 51387, 51392, 51394, 51398, 51403, 51405, + 51407, 51409, 51411, 51416, 51419, 51421, 51426, 51432, 51439, 51442, + 51446, 51451, 51456, 51464, 51470, 51476, 51488, 51495, 51503, 51508, + 51513, 51519, 51522, 51525, 51530, 51532, 51536, 51538, 51540, 51542, + 51544, 51546, 51548, 51553, 51555, 51557, 51559, 51561, 51565, 51567, + 51570, 51575, 51580, 51585, 51590, 51596, 51602, 51604, 51607, 51614, + 51620, 51626, 51633, 51637, 51641, 51643, 51645, 51649, 51655, 51660, + 51662, 51666, 51675, 51683, 51691, 51697, 51703, 51708, 51714, 51719, + 51722, 51736, 51739, 51744, 51749, 51755, 51765, 51767, 51773, 51779, + 51783, 51790, 51794, 51796, 51798, 51802, 51808, 51813, 51819, 51821, + 51827, 51829, 51835, 51837, 51839, 51844, 51846, 51850, 51855, 51857, + 51862, 51867, 51871, 51878, 51888, 51893, 51898, 51901, 51906, 51909, + 51914, 51919, 51923, 51925, 51927, 51931, 51935, 51939, 51943, 51947, + 51949, 51953, 51956, 51959, 51962, 51966, 51970, 51975, 51979, 51984, + 51989, 51993, 51999, 52006, 52009, 52015, 52020, 52024, 52029, 52035, + 52041, 52048, 52054, 52061, 52068, 52070, 52077, 52081, 52088, 52094, + 52099, 52105, 52109, 52114, 52117, 52123, 52129, 52136, 52144, 52151, + 52160, 52170, 52177, 52183, 52187, 52195, 52200, 52209, 52212, 52215, + 52224, 52235, 52242, 52244, 52250, 52255, 52257, 52260, 52264, 52272, + 52281, 52284, 52289, 52295, 52302, 52309, 52316, 52323, 52329, 52335, + 52341, 52349, 52354, 52357, 52361, 52364, 52375, 52385, 52395, 52404, + 52415, 52425, 52434, 52440, 52448, 52452, 52460, 52464, 52472, 52479, + 52486, 52495, 52504, 52514, 52524, 52534, 52544, 52553, 52562, 52572, + 52582, 52591, 52600, 52607, 52614, 52621, 52628, 52635, 52642, 52649, + 52656, 52663, 52671, 52677, 52683, 52689, 52695, 52701, 52707, 52713, + 52719, 52725, 52732, 52740, 52748, 52756, 52764, 52772, 52780, 52788, + 52796, 52804, 52813, 52818, 52821, 52825, 52829, 52835, 52838, 52843, + 52849, 52854, 52858, 52863, 52869, 52876, 52879, 52886, 52893, 52897, + 52906, 52915, 52920, 52926, 52931, 52936, 52943, 52950, 52957, 52964, + 52972, 52976, 52984, 52989, 52993, 53000, 53004, 53010, 53018, 53023, + 53030, 53034, 53039, 53043, 53048, 53052, 53057, 53062, 53071, 53073, + 53077, 53081, 53088, 53095, 53101, 53109, 53115, 53122, 53127, 53130, + 53135, 53140, 53145, 53153, 53157, 53164, 53171, 53178, 53183, 53188, + 53194, 53199, 53204, 53210, 53215, 53218, 53222, 53226, 53233, 53243, + 53248, 53257, 53266, 53272, 53278, 53284, 53290, 53296, 53302, 53309, + 53316, 53325, 53334, 53340, 53346, 53351, 53356, 53363, 53370, 53376, + 53379, 53382, 53386, 53390, 53394, 53399, 53405, 53411, 53418, 53425, + 53430, 53434, 53438, 53442, 53446, 53450, 53454, 53458, 53462, 53466, + 53470, 53474, 53478, 53482, 53486, 53490, 53494, 53498, 53502, 53506, + 53510, 53514, 53518, 53522, 53526, 53530, 53534, 53538, 53542, 53546, + 53550, 53554, 53558, 53562, 53566, 53570, 53574, 53578, 53582, 53586, + 53590, 53594, 53598, 53602, 53606, 53610, 53614, 53618, 53622, 53626, + 53630, 53634, 53638, 53642, 53646, 53650, 53654, 53658, 53662, 53666, + 53670, 53674, 53678, 53682, 53686, 53690, 53694, 53698, 53702, 53706, + 53710, 53714, 53718, 53722, 53726, 53730, 53734, 53738, 53742, 53746, + 53750, 53754, 53758, 53762, 53766, 53770, 53774, 53778, 53782, 53786, + 53790, 53794, 53798, 53802, 53806, 53810, 53814, 53818, 53822, 53826, + 53830, 53834, 53838, 53842, 53846, 53850, 53854, 53858, 53862, 53866, + 53870, 53874, 53878, 53882, 53886, 53890, 53894, 53898, 53902, 53906, + 53910, 53914, 53918, 53922, 53926, 53930, 53934, 53938, 53942, 53946, + 53950, 53954, 53958, 53962, 53966, 53970, 53974, 53978, 53982, 53986, + 53990, 53994, 53998, 54002, 54006, 54010, 54014, 54018, 54022, 54026, + 54030, 54034, 54038, 54042, 54046, 54050, 54054, 54058, 54062, 54066, + 54070, 54074, 54078, 54082, 54086, 54090, 54094, 54098, 54102, 54106, + 54110, 54114, 54118, 54122, 54126, 54130, 54134, 54138, 54142, 54146, + 54150, 54154, 54158, 54162, 54166, 54170, 54174, 54178, 54182, 54186, + 54190, 54194, 54198, 54202, 54206, 54210, 54214, 54218, 54222, 54226, + 54230, 54234, 54238, 54242, 54246, 54250, 54254, 54258, 54262, 54266, + 54270, 54274, 54278, 54282, 54286, 54290, 54294, 54298, 54302, 54306, + 54310, 54314, 54318, 54322, 54326, 54330, 54334, 54338, 54342, 54346, + 54350, 54354, 54358, 54362, 54366, 54370, 54374, 54378, 54382, 54386, + 54390, 54394, 54398, 54402, 54406, 54410, 54414, 54418, 54422, 54426, + 54430, 54434, 54438, 54442, 54446, 54450, 54454, 54461, 54469, 54475, + 54481, 54488, 54495, 54501, 54507, 54514, 54521, 54526, 54531, 54536, + 54541, 54547, 54553, 54561, 54568, 54573, 54578, 54586, 54595, 54602, + 54612, 54623, 54626, 54629, 54633, 54637, 54643, 54649, 54659, 54669, + 54678, 54687, 54693, 54699, 54706, 54713, 54722, 54732, 54743, 54753, + 54763, 54773, 54784, 54795, 54805, 54816, 54826, 54836, 54844, 54854, + 54864, 54875, 54886, 54893, 54900, 54907, 54914, 54924, 54934, 54941, + 54948, 54955, 54962, 54969, 54976, 54983, 54988, 54993, 54999, 55007, + 55017, 55025, 55033, 55041, 55049, 55057, 55065, 55073, 55081, 55089, + 55097, 55106, 55115, 55123, 55131, 55140, 55149, 55158, 55167, 55177, + 55187, 55196, 55205, 55215, 55225, 55239, 55255, 55269, 55285, 55299, + 55313, 55327, 55341, 55351, 55362, 55372, 55383, 55399, 55415, 55423, + 55429, 55436, 55443, 55450, 55458, 55463, 55469, 55474, 55479, 55485, + 55490, 55495, 55500, 55505, 55510, 55517, 55523, 55531, 55537, 55543, + 55547, 55551, 55560, 55569, 55578, 55587, 55594, 55601, 55614, 55627, + 55640, 55653, 55661, 55669, 55676, 55683, 55691, 55699, 55707, 55715, + 55719, 55724, 55732, 55740, 55748, 55755, 55759, 55767, 55775, 55778, + 55782, 55787, 55794, 55802, 55810, 55829, 55849, 55868, 55888, 55908, + 55928, 55948, 55968, 55974, 55981, 55990, 55998, 56006, 56012, 56015, + 56018, 56023, 56026, 56046, 56053, 56059, 56065, 56069, 56072, 56075, + 56078, 56088, 56100, 56107, 56114, 56117, 56121, 56124, 56129, 56134, + 56139, 56145, 56154, 56161, 56168, 56176, 56183, 56190, 56193, 56199, + 56205, 56208, 56211, 56216, 56221, 56227, 56233, 56237, 56242, 56249, + 56253, 56259, 56263, 56267, 56275, 56287, 56295, 56299, 56301, 56310, + 56319, 56325, 56328, 56334, 56340, 56345, 56350, 56355, 56360, 56365, + 56370, 56372, 56378, 56383, 56391, 56395, 56401, 56404, 56408, 56416, + 56424, 56426, 56428, 56434, 56440, 56446, 56455, 56464, 56471, 56478, + 56484, 56491, 56496, 56501, 56506, 56512, 56518, 56523, 56530, 56534, + 56538, 56551, 56564, 56576, 56585, 56591, 56598, 56603, 56608, 56613, + 56618, 56623, 56625, 56632, 56640, 56648, 56656, 56663, 56671, 56677, + 56682, 56688, 56694, 56700, 56707, 56713, 56721, 56729, 56737, 56745, + 56753, 56759, 56765, 56774, 56778, 56787, 56796, 56805, 56813, 56817, + 56823, 56830, 56837, 56841, 56847, 56855, 56861, 56866, 56872, 56877, + 56882, 56889, 56896, 56901, 56906, 56914, 56922, 56932, 56942, 56949, + 56956, 56960, 56964, 56976, 56982, 56989, 56994, 56999, 57006, 57013, + 57019, 57025, 57035, 57042, 57050, 57058, 57067, 57074, 57080, 57087, + 57093, 57101, 57109, 57117, 57125, 57131, 57136, 57146, 57157, 57164, + 57173, 57179, 57184, 57189, 57199, 57208, 57214, 57220, 57228, 57233, + 57240, 57247, 57258, 57265, 57272, 57279, 57286, 57293, 57302, 57311, + 57324, 57337, 57349, 57361, 57374, 57388, 57394, 57400, 57410, 57420, + 57427, 57434, 57444, 57454, 57463, 57472, 57480, 57488, 57498, 57508, + 57523, 57538, 57547, 57556, 57569, 57582, 57591, 57600, 57611, 57622, + 57628, 57634, 57643, 57652, 57657, 57662, 57670, 57676, 57682, 57690, + 57698, 57711, 57724, 57728, 57732, 57741, 57750, 57757, 57765, 57773, + 57783, 57793, 57799, 57805, 57813, 57821, 57829, 57837, 57847, 57857, + 57860, 57863, 57868, 57873, 57879, 57885, 57892, 57899, 57910, 57921, + 57928, 57935, 57943, 57951, 57960, 57969, 57978, 57987, 57994, 58001, + 58005, 58009, 58018, 58027, 58032, 58037, 58042, 58047, 58053, 58067, + 58074, 58081, 58085, 58087, 58089, 58094, 58099, 58104, 58109, 58117, + 58124, 58131, 58139, 58151, 58159, 58167, 58178, 58182, 58186, 58192, + 58200, 58213, 58220, 58227, 58234, 58240, 58247, 58256, 58265, 58271, + 58277, 58283, 58294, 58305, 58313, 58322, 58327, 58330, 58335, 58340, + 58345, 58351, 58357, 58361, 58364, 58368, 58372, 58377, 58382, 58388, + 58394, 58398, 58402, 58409, 58416, 58423, 58430, 58437, 58444, 58453, + 58462, 58469, 58476, 58484, 58492, 58496, 58501, 58506, 58512, 58518, + 58521, 58524, 58527, 58530, 58535, 58540, 58545, 58550, 58555, 58560, + 58564, 58568, 58572, 58577, 58582, 58586, 58590, 58596, 58600, 58606, + 58611, 58618, 58626, 58633, 58641, 58648, 58656, 58665, 58672, 58682, + 58693, 58699, 58708, 58714, 58723, 58733, 58739, 58745, 58749, 58753, + 58762, 58772, 58779, 58787, 58796, 58805, 58812, 58818, 58825, 58830, + 58834, 58838, 58843, 58848, 58853, 58861, 58869, 58872, 58876, 58885, + 58895, 58904, 58914, 58926, 58940, 58944, 58949, 58953, 58958, 58963, + 58968, 58974, 58980, 58987, 58994, 59000, 59007, 59013, 59020, 59029, + 59038, 59044, 59051, 59057, 0, 0, 59064, 59072, 59080, 59089, 59098, + 59107, 59117, 59126, 59136, 59142, 59147, 59156, 59168, 59177, 59189, + 59196, 59204, 59211, 59219, 59224, 59230, 59235, 59241, 59249, 59258, + 59266, 59275, 59279, 59282, 59286, 59289, 59299, 0, 59302, 59309, 59318, + 59328, 59337, 59347, 59353, 59360, 59366, 59373, 59384, 59395, 59406, + 59417, 59427, 59437, 59447, 59457, 59465, 59473, 59481, 59489, 59497, + 59505, 59513, 59521, 59527, 59532, 59538, 59543, 59549, 59555, 59561, + 59567, 59579, 59589, 59594, 59601, 59606, 59613, 59616, 59620, 59624, + 59629, 59633, 59638, 59641, 59650, 59659, 59668, 59677, 59682, 59688, + 59694, 59702, 59712, 59719, 59728, 59733, 59736, 59739, 59744, 59749, + 59754, 59759, 59761, 59763, 59765, 59767, 59769, 59771, 59776, 59783, + 59790, 59792, 59794, 59796, 59798, 59800, 59802, 59804, 59806, 59811, + 59816, 59823, 59830, 59839, 59849, 59858, 59868, 59873, 59878, 59880, + 59887, 59894, 59901, 59908, 59915, 59922, 59929, 59932, 59935, 59938, + 59941, 59946, 59951, 59956, 59961, 59966, 59971, 59976, 59981, 59986, + 59991, 59996, 60001, 60007, 60011, 60016, 60021, 60026, 60031, 60036, + 60041, 60046, 60051, 60056, 60061, 60066, 60071, 60076, 60081, 60086, + 60091, 60096, 60101, 60106, 60111, 60116, 60121, 60127, 60132, 60138, + 60147, 60152, 60160, 60167, 60176, 60181, 60186, 60191, 60197, 60204, + 60211, 60216, 60221, 60226, 60231, 60236, 60241, 60246, 60251, 60256, + 60261, 60267, 60271, 60276, 60281, 60286, 60291, 60296, 60301, 60306, + 60311, 60316, 60321, 60326, 60331, 60336, 60341, 60346, 60351, 60356, + 60361, 60366, 60371, 60376, 60381, 60387, 60392, 60398, 60407, 60412, + 60420, 60427, 60436, 60441, 60446, 60451, 60457, 60464, 60471, 60479, + 60487, 60496, 60503, 60511, 60517, 60526, 60534, 60542, 60550, 60558, + 60566, 60574, 60579, 60586, 60591, 60597, 60605, 60612, 60619, 60627, + 60633, 60639, 60646, 60654, 60663, 60673, 60679, 60686, 60691, 60701, + 60711, 60716, 60721, 60726, 60731, 60736, 60741, 60746, 60751, 60756, + 60761, 60766, 60771, 60776, 60781, 60786, 60791, 60796, 60801, 60806, + 60811, 60816, 60821, 60826, 60831, 60836, 60841, 60846, 60851, 60856, + 60861, 60865, 60869, 60874, 60879, 60884, 60889, 60894, 60899, 60904, + 60909, 60914, 60919, 60924, 60929, 60934, 60939, 60944, 60949, 60954, + 60959, 60966, 60973, 60980, 60987, 60994, 61001, 61008, 61015, 61022, + 61029, 61036, 61043, 61050, 61057, 61062, 61067, 61074, 61081, 61088, + 61095, 61102, 61109, 61116, 61123, 61130, 61137, 61144, 61151, 61157, + 61163, 61169, 61175, 61182, 61189, 61196, 61203, 61210, 61217, 61224, + 61231, 61238, 61245, 61253, 61261, 61269, 61277, 61285, 61293, 61301, + 61309, 61313, 61319, 61325, 61329, 61335, 61341, 61347, 61354, 61361, + 61368, 61375, 61380, 61386, 61392, 61399, 0, 0, 0, 0, 0, 61406, 61414, + 61423, 61432, 61440, 61446, 61451, 61456, 61461, 61466, 61471, 61476, + 61481, 61486, 61491, 61496, 61501, 61506, 61511, 61516, 61521, 61526, + 61531, 61536, 61541, 61546, 61551, 61556, 61561, 61566, 61571, 61576, + 61581, 61586, 61591, 61596, 61601, 61606, 61611, 61616, 61621, 61626, + 61631, 61636, 61641, 0, 61646, 0, 0, 0, 0, 0, 61651, 0, 0, 61656, 61660, + 61665, 61670, 61675, 61680, 61689, 61694, 61699, 61704, 61709, 61714, + 61719, 61724, 61729, 61736, 61741, 61746, 61755, 61762, 61767, 61772, + 61777, 61784, 61789, 61796, 61801, 61806, 61813, 61820, 61825, 61830, + 61835, 61842, 61849, 61854, 61859, 61864, 61869, 61874, 61881, 61888, + 61893, 61898, 61903, 61908, 61913, 61918, 61923, 61928, 61933, 61938, + 61943, 61950, 61955, 61960, 0, 0, 0, 0, 0, 0, 0, 61965, 61972, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61977, 61982, 61986, 61990, 61994, + 61998, 62002, 62006, 62010, 62014, 62018, 62022, 62028, 62032, 62036, + 62040, 62044, 62048, 62052, 62056, 62060, 62064, 62068, 62072, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 62076, 62080, 62084, 62088, 62092, 62096, 62100, 0, + 62104, 62108, 62112, 62116, 62120, 62124, 62128, 0, 62132, 62136, 62140, + 62144, 62148, 62152, 62156, 0, 62160, 62164, 62168, 62172, 62176, 62180, + 62184, 0, 62188, 62192, 62196, 62200, 62204, 62208, 62212, 0, 62216, + 62220, 62224, 62228, 62232, 62236, 62240, 0, 62244, 62248, 62252, 62256, + 62260, 62264, 62268, 0, 62272, 62276, 62280, 62284, 62288, 62292, 62296, + 0, 62300, 62305, 62310, 62315, 62320, 62325, 62330, 62334, 62339, 62344, + 62349, 62353, 62358, 62363, 62368, 62373, 62377, 62382, 62387, 62392, + 62397, 62402, 62407, 62411, 62416, 62421, 62428, 62433, 62438, 62444, + 62451, 62458, 62467, 62474, 62483, 62488, 62493, 62500, 62507, 62513, + 62521, 62527, 62532, 62537, 62541, 62548, 62555, 62559, 62561, 62565, + 62571, 62573, 62577, 62581, 62585, 62591, 62596, 62600, 62604, 62609, + 62615, 62621, 62627, 62632, 62637, 62644, 62651, 62657, 62663, 62669, + 62675, 62681, 62687, 62691, 62695, 62702, 62709, 62715, 62719, 62724, + 62727, 62731, 62738, 62741, 62745, 62749, 62752, 62758, 62764, 62767, + 62773, 62777, 62781, 62787, 62792, 62797, 62799, 62802, 62806, 62812, + 62818, 62822, 62827, 62836, 62839, 62845, 62850, 62854, 62858, 62862, + 62865, 62870, 62876, 62884, 62892, 62898, 62903, 62908, 62914, 62920, + 62927, 62934, 62940, 62946, 62952, 62958, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 62962, 62966, 62970, 62975, 62980, 62985, 62989, 62993, 62997, 63002, + 63007, 63011, 63015, 63019, 63023, 63028, 63033, 63038, 63043, 63047, + 63051, 63056, 63061, 63066, 63071, 63075, 0, 63079, 63083, 63087, 63091, + 63095, 63099, 63103, 63108, 63113, 63117, 63122, 63127, 63136, 63140, + 63144, 63148, 63155, 63159, 63164, 63169, 63173, 63177, 63183, 63188, + 63193, 63198, 63203, 63207, 63211, 63215, 63219, 63223, 63228, 63233, + 63237, 63241, 63246, 63251, 63256, 63260, 63264, 63269, 63274, 63280, + 63286, 63290, 63296, 63302, 63306, 63312, 63318, 63323, 63328, 63332, + 63338, 63342, 63346, 63352, 63358, 63363, 63368, 63372, 63376, 63384, + 63390, 63396, 63402, 63407, 63412, 63417, 63423, 63427, 63433, 63437, + 63441, 63447, 63453, 63459, 63465, 63471, 63477, 63483, 63489, 63495, + 63501, 63507, 63513, 63517, 63523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 63529, 63532, 63536, 63540, 63544, 63548, 63551, 63554, 63558, 63562, + 63566, 63570, 63573, 63578, 63582, 63586, 63590, 63596, 63600, 63604, + 63608, 63612, 63619, 63625, 63629, 63633, 63637, 63641, 63645, 63649, + 63653, 63657, 63661, 63665, 63669, 63675, 63679, 63683, 63687, 63691, + 63695, 63699, 63703, 63707, 63711, 63715, 63719, 63723, 63727, 63731, + 63735, 63739, 63745, 63751, 63756, 63761, 63765, 63769, 63773, 63777, + 63781, 63785, 63789, 63793, 63797, 63801, 63805, 63809, 63813, 63817, + 63821, 63825, 63829, 63833, 63837, 63841, 63845, 63849, 63853, 63857, + 63863, 63867, 63871, 63875, 63879, 63883, 63887, 63891, 63895, 63900, + 63907, 63911, 63915, 63919, 63923, 63927, 63931, 63935, 63939, 63943, + 63947, 63951, 63955, 63962, 63966, 63972, 63976, 63980, 63984, 63988, + 63992, 63995, 63999, 64003, 64007, 64011, 64015, 64019, 64023, 64027, + 64031, 64035, 64039, 64043, 64047, 64051, 64055, 64059, 64063, 64067, + 64071, 64075, 64079, 64083, 64087, 64091, 64095, 64099, 64103, 64107, + 64111, 64115, 64119, 64123, 64129, 64133, 64137, 64141, 64145, 64149, + 64153, 64157, 64161, 64165, 64169, 64173, 64177, 64181, 64185, 64189, + 64193, 64197, 64201, 64205, 64209, 64213, 64217, 64221, 64225, 64229, + 64233, 64237, 64245, 64249, 64253, 64257, 64261, 64265, 64271, 64275, + 64279, 64283, 64287, 64291, 64295, 64299, 64303, 64307, 64311, 64315, + 64319, 64323, 64329, 64333, 64337, 64341, 64345, 64349, 64353, 64357, + 64361, 64365, 64369, 64373, 64377, 64381, 64385, 64389, 64393, 64397, + 64401, 64405, 64409, 64413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64417, 64425, 64433, 64443, 64453, + 64462, 64472, 64482, 64493, 64505, 64516, 64528, 0, 0, 0, 0, 64535, + 64538, 64541, 64546, 64549, 64556, 64560, 64564, 64568, 64573, 64578, + 64584, 64590, 64595, 64600, 64606, 64612, 64618, 64624, 64627, 64630, + 64637, 64644, 64650, 64656, 64664, 64672, 64677, 64682, 64686, 64694, + 64700, 64707, 64712, 64717, 64722, 64727, 64732, 64737, 64742, 64747, + 64752, 64757, 64762, 64767, 64772, 64777, 64783, 64788, 64792, 64798, + 64809, 64818, 64832, 64841, 64845, 64855, 64861, 64867, 64873, 64878, + 64881, 64886, 64890, 0, 64896, 64901, 64905, 64910, 64914, 64919, 64923, + 64928, 64932, 64937, 64941, 64945, 64950, 64955, 64960, 64965, 64970, + 64975, 64980, 64985, 64990, 64994, 64999, 65004, 65009, 65014, 65019, + 65024, 65029, 65034, 65039, 65044, 65049, 65054, 65059, 65065, 65070, + 65075, 65080, 65085, 65089, 65094, 65098, 65103, 65108, 65113, 65118, + 65122, 65127, 65131, 65136, 65141, 65146, 65151, 65156, 65161, 65166, + 65171, 65176, 65181, 65186, 65191, 65195, 65200, 65205, 65210, 65215, + 65220, 65224, 65230, 65235, 65241, 65246, 65250, 65255, 65260, 65265, + 65270, 65276, 65281, 65286, 65291, 65296, 65301, 65306, 65311, 0, 0, + 65317, 65325, 65333, 65340, 65347, 65352, 65359, 65365, 65370, 65374, + 65377, 65381, 65384, 65388, 65391, 65395, 65398, 65402, 65405, 65408, + 65412, 65416, 65420, 65424, 65428, 65432, 65436, 65440, 65444, 65447, + 65451, 65455, 65459, 65463, 65467, 65471, 65475, 65479, 65483, 65487, + 65491, 65495, 65499, 65504, 65508, 65512, 65516, 65520, 65523, 65527, + 65530, 65534, 65538, 65542, 65546, 65549, 65553, 65556, 65560, 65564, + 65568, 65572, 65576, 65580, 65584, 65588, 65592, 65596, 65600, 65604, + 65607, 65611, 65615, 65619, 65623, 65627, 65630, 65635, 65639, 65644, + 65648, 65651, 65655, 65659, 65663, 65667, 65672, 65676, 65680, 65684, + 65688, 65692, 65696, 65700, 65705, 65709, 65713, 65717, 65721, 65725, + 65732, 65736, 65742, 0, 0, 0, 0, 0, 65747, 65752, 65757, 65762, 65767, + 65772, 65777, 65782, 65786, 65791, 65796, 65801, 65806, 65811, 65816, + 65821, 65826, 65831, 65835, 65840, 65845, 65850, 65854, 65858, 65862, + 65867, 65872, 65877, 65882, 65887, 65892, 65897, 65902, 65907, 65912, + 65916, 65920, 65925, 65930, 65935, 65940, 65945, 65952, 0, 65957, 65961, + 65965, 65969, 65973, 65977, 65981, 65985, 65989, 65993, 65997, 66001, + 66005, 66009, 66013, 66017, 66021, 66025, 66029, 66033, 66037, 66041, + 66045, 66049, 66053, 66057, 66061, 66065, 66069, 66073, 66077, 66080, + 66084, 66087, 66091, 66095, 66098, 66102, 66106, 66109, 66113, 66117, + 66121, 66125, 66128, 66132, 66136, 66140, 66144, 66148, 66152, 66155, + 66158, 66162, 66166, 66170, 66174, 66178, 66182, 66186, 66190, 66194, + 66198, 66202, 66206, 66210, 66214, 66218, 66222, 66226, 66230, 66234, + 66238, 66242, 66246, 66250, 66254, 66258, 66262, 66266, 66270, 66274, + 66278, 66282, 66286, 66290, 66294, 66298, 66302, 66306, 66310, 66314, + 66318, 66322, 0, 66326, 66332, 66338, 66343, 66348, 66353, 66359, 66365, + 66370, 66376, 66382, 66388, 66394, 66400, 66406, 66412, 66418, 66423, + 66428, 66433, 66438, 66443, 66448, 66453, 66458, 66463, 66468, 66473, + 66478, 66483, 66488, 66493, 66498, 66503, 66508, 66513, 66518, 66524, + 66530, 66536, 66542, 66547, 66552, 66557, 66563, 66568, 66573, 66578, + 66583, 66588, 66593, 66598, 66603, 66608, 66613, 66618, 66623, 66628, + 66633, 66638, 66643, 66648, 66653, 66658, 66663, 66668, 66673, 66678, + 66683, 66688, 66693, 66698, 66703, 66708, 66713, 66718, 66723, 66728, + 66733, 66738, 66743, 66748, 66753, 66758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 66763, 66768, 66773, 66778, 66782, 66787, 66791, 66796, 66801, + 66806, 66811, 66816, 66820, 66825, 66830, 66835, 66840, 66844, 66848, + 66852, 66856, 66860, 66864, 66868, 66872, 66876, 66880, 66884, 66888, + 66892, 66896, 66901, 66906, 66911, 66916, 66921, 66926, 66931, 66936, + 66941, 66946, 66951, 66956, 66961, 66966, 66971, 66978, 0, 66986, 66990, + 66994, 66998, 67002, 67006, 67010, 67014, 67018, 67022, 67027, 67032, + 67037, 67042, 67047, 67052, 67057, 67062, 67067, 67072, 67077, 67082, + 67087, 67092, 67097, 67102, 67107, 67112, 67117, 67122, 67127, 67132, + 67137, 67142, 67147, 67152, 67157, 67162, 67167, 67172, 67177, 67186, + 67195, 67204, 67213, 67222, 67231, 67240, 67249, 67252, 67257, 67262, + 67267, 67272, 67277, 67282, 67287, 67292, 67297, 67301, 67306, 67311, + 67316, 67321, 67326, 67330, 67334, 67338, 67342, 67346, 67350, 67354, + 67358, 67362, 67366, 67370, 67374, 67378, 67382, 67387, 67392, 67397, + 67402, 67407, 67412, 67417, 67422, 67427, 67432, 67437, 67442, 67447, + 67452, 67459, 67466, 67471, 67476, 67480, 67484, 67488, 67492, 67496, + 67500, 67504, 67508, 67512, 67517, 67522, 67527, 67532, 67537, 67542, + 67547, 67552, 67557, 67562, 67567, 67572, 67577, 67582, 67587, 67592, + 67597, 67602, 67607, 67612, 67617, 67622, 67627, 67632, 67637, 67642, + 67647, 67652, 67657, 67662, 67667, 67671, 67676, 67681, 67686, 67691, + 67696, 67701, 67706, 67711, 67716, 67721, 67726, 67731, 67735, 67740, + 67745, 67750, 67755, 67760, 67765, 67770, 67775, 67780, 67784, 67791, + 67798, 67805, 67812, 67819, 67826, 67833, 67840, 67847, 67854, 67861, + 67868, 67871, 67874, 67877, 67882, 67885, 67888, 67891, 67894, 67897, + 67900, 67904, 67908, 67912, 67916, 67919, 67923, 67927, 67931, 67935, + 67939, 67943, 67947, 67951, 67954, 67957, 67961, 67965, 67969, 67973, + 67976, 67980, 67984, 67988, 67992, 67995, 67999, 68003, 68007, 68011, + 68014, 68018, 68022, 68025, 68029, 68033, 68037, 68041, 68045, 68049, + 68053, 68057, 68064, 68067, 68070, 68073, 68076, 68079, 68082, 68085, + 68088, 68091, 68094, 68097, 68100, 68103, 68106, 68109, 68112, 68115, + 68118, 68121, 68124, 68127, 68130, 68133, 68136, 68139, 68142, 68145, + 68148, 68151, 68154, 68157, 68160, 68163, 68166, 68169, 68172, 68175, + 68178, 68181, 68184, 68187, 68190, 68193, 68196, 68199, 68202, 68205, + 68208, 68211, 68214, 68217, 68220, 68223, 68226, 68229, 68232, 68235, + 68238, 68241, 68244, 68247, 68250, 68253, 68256, 68259, 68262, 68265, + 68268, 68271, 68274, 68277, 68280, 68283, 68286, 68289, 68292, 68295, + 68298, 68301, 68304, 68307, 68310, 68313, 68316, 68319, 68322, 68325, + 68328, 68337, 68345, 68353, 68361, 68369, 68377, 68385, 68393, 68401, + 68409, 68418, 68427, 68436, 68445, 68454, 68463, 68472, 68481, 68490, + 68499, 68508, 68517, 68526, 68535, 68544, 68547, 68550, 68553, 68555, + 68558, 68561, 68564, 68569, 68574, 68577, 68584, 68591, 68598, 68605, + 68608, 68613, 68615, 68619, 68621, 68623, 68626, 68629, 68632, 68635, + 68638, 68641, 68644, 68649, 68654, 68657, 68660, 68663, 68666, 68669, + 68672, 68675, 68679, 68682, 68685, 68688, 68691, 68694, 68699, 68702, + 68705, 68708, 68713, 68718, 68723, 68728, 68733, 68738, 68743, 68748, + 68754, 68762, 68764, 68767, 68770, 68773, 68776, 68782, 68790, 68793, + 68796, 68801, 68804, 68807, 68810, 68815, 68818, 68821, 68826, 68829, + 68832, 68837, 68840, 68843, 68848, 68853, 68858, 68861, 68864, 68867, + 68870, 68876, 68879, 68882, 68885, 68887, 68890, 68893, 68896, 68901, + 68904, 68907, 68910, 68913, 68916, 68921, 68924, 68927, 68930, 68933, + 68936, 68939, 68942, 68945, 68948, 68954, 68959, 68967, 68975, 68983, + 68991, 68999, 69007, 69015, 69023, 69031, 69040, 69049, 69058, 69067, + 69076, 69085, 69094, 69103, 69112, 69121, 69130, 69139, 69148, 69157, + 69166, 69175, 69184, 69193, 69202, 69211, 69220, 69229, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69232, 69241, + 69250, 69261, 69268, 69273, 69278, 69285, 69292, 69298, 69303, 69308, + 69313, 69318, 69325, 69330, 69335, 69340, 69351, 69356, 69361, 69368, + 69373, 69380, 69385, 69390, 69397, 69404, 69411, 69420, 69429, 69434, + 69439, 69444, 69451, 69456, 69466, 69473, 69478, 69483, 69488, 69493, + 69498, 69503, 69511, 69518, 69525, 69530, 69537, 69542, 69549, 69558, + 69569, 69574, 69583, 69588, 69595, 69604, 69613, 69618, 69623, 69630, + 69636, 69643, 69650, 69654, 69658, 69661, 69665, 69669, 69673, 69677, + 69681, 69685, 69689, 69692, 69696, 69700, 69704, 69708, 69712, 69716, + 69719, 69723, 69727, 69730, 69734, 69738, 69742, 69746, 69750, 69754, + 69758, 69762, 69766, 69770, 69774, 69778, 69782, 69786, 69790, 69794, + 69798, 69802, 69806, 69810, 69814, 69818, 69822, 69826, 69830, 69834, + 69838, 69842, 69846, 69850, 69854, 69858, 69862, 69866, 69870, 69874, + 69878, 69882, 69886, 69890, 69894, 69898, 69902, 69906, 69909, 69913, + 69917, 69921, 69925, 69929, 69933, 69937, 69941, 69945, 69949, 69953, + 69957, 69961, 69965, 69969, 69973, 69977, 69981, 69985, 69989, 69993, + 69997, 70001, 70005, 70009, 70013, 70017, 70021, 70025, 70029, 70033, + 70037, 70041, 70045, 70049, 70053, 70057, 70061, 70065, 70069, 70073, + 70077, 70081, 70085, 70089, 70093, 70097, 70101, 70105, 70109, 70113, + 70117, 70121, 70125, 70129, 70133, 70137, 70141, 70145, 70149, 70153, + 70157, 70161, 70165, 70169, 70173, 70177, 70181, 70185, 70189, 70193, + 70197, 70201, 70205, 70209, 70213, 70217, 70221, 70225, 70229, 70233, + 70237, 70241, 70245, 70249, 70253, 70257, 70261, 70265, 70269, 70273, + 70277, 70281, 70285, 70289, 70293, 70297, 70301, 70305, 70309, 70313, + 70317, 70321, 70325, 70329, 70333, 70337, 70341, 70345, 70349, 70353, + 70357, 70361, 70365, 70369, 70373, 70377, 70380, 70384, 70388, 70392, + 70396, 70400, 70404, 70408, 70412, 70416, 70420, 70424, 70428, 70432, + 70436, 70440, 70444, 70448, 70452, 70456, 70460, 70464, 70468, 70472, + 70476, 70480, 70484, 70488, 70492, 70496, 70500, 70504, 70508, 70512, + 70516, 70520, 70524, 70528, 70532, 70536, 70540, 70544, 70548, 70552, + 70556, 70560, 70564, 70568, 70572, 70576, 70580, 70584, 70588, 70592, + 70596, 70600, 70604, 70608, 70612, 70616, 70620, 70624, 70628, 70632, + 70636, 70640, 70644, 70648, 70652, 70656, 70660, 70664, 70668, 70672, + 70676, 70680, 70684, 70688, 70692, 70696, 70700, 70704, 70708, 70712, + 70716, 70720, 70724, 70728, 70732, 70736, 70740, 70744, 70748, 70752, + 70756, 70760, 70764, 70768, 70772, 70776, 70780, 70784, 70788, 70792, + 70796, 70800, 70804, 70808, 70812, 70816, 70820, 70824, 70828, 70832, + 70836, 70840, 70843, 70847, 70851, 70855, 70859, 70863, 70867, 70871, + 70875, 70879, 70883, 70887, 70891, 70895, 70899, 70903, 70907, 70911, + 70915, 70919, 70923, 70927, 70931, 70935, 70939, 70943, 70947, 70951, + 70955, 70959, 70963, 70967, 70971, 70975, 70979, 70983, 70987, 70991, + 70995, 70999, 71003, 71007, 71011, 71015, 71019, 71023, 71027, 71031, + 71035, 71039, 71043, 71047, 71051, 71055, 71059, 71063, 71067, 71071, + 71075, 71079, 71083, 71087, 71091, 71095, 71099, 71103, 71107, 71111, + 71115, 71119, 71123, 71127, 71131, 71135, 71139, 71143, 71147, 71151, + 71155, 71159, 71163, 71167, 71171, 71175, 71179, 71183, 71187, 71191, + 71195, 71199, 71202, 71206, 71210, 71214, 71218, 71222, 71226, 71230, + 71234, 71238, 71242, 71246, 71250, 71254, 71258, 71262, 71266, 71270, + 71274, 71278, 71282, 71286, 71290, 71294, 71298, 71302, 71306, 71310, + 71314, 71318, 71322, 71326, 71330, 71334, 71338, 71342, 71346, 71350, + 71354, 71358, 71362, 71366, 71370, 71374, 71378, 71382, 71386, 71390, + 71394, 71398, 71402, 71406, 71410, 71414, 71418, 71422, 71426, 71430, + 71434, 71438, 71441, 71445, 71449, 71453, 71457, 71461, 71465, 71469, + 71473, 71477, 71481, 71485, 71489, 71493, 71497, 71501, 71505, 71509, + 71513, 71517, 71521, 71525, 71529, 71533, 71537, 71541, 71545, 71549, + 71553, 71557, 71561, 71565, 71569, 71573, 71577, 71581, 71585, 71589, + 71593, 71597, 71601, 71605, 71609, 71613, 71617, 71621, 71625, 71629, + 71633, 71637, 71641, 71645, 71649, 71653, 71657, 71661, 71665, 71669, + 71673, 71677, 71681, 71685, 71689, 71693, 71696, 71700, 71704, 71708, + 71712, 71716, 71720, 71724, 71728, 71732, 71736, 71740, 71744, 71748, + 71752, 71756, 71760, 71764, 71768, 71772, 71776, 71780, 71784, 71788, + 71792, 71796, 71800, 71804, 71808, 71812, 71816, 71820, 71824, 71828, + 71832, 71836, 71840, 71844, 71848, 71852, 71856, 71860, 71864, 71868, + 71872, 71876, 71880, 71884, 71888, 71892, 71896, 71900, 71904, 71908, + 71912, 71916, 71920, 71924, 71928, 71932, 71936, 71940, 71944, 71948, + 71952, 71956, 71960, 71964, 71968, 71972, 71976, 71980, 71984, 71988, + 71992, 71996, 72000, 72004, 72008, 72012, 72016, 72020, 72024, 72028, + 72032, 72036, 72040, 72044, 72048, 72052, 72056, 72060, 72064, 72068, + 72072, 72076, 72080, 72084, 72088, 72092, 72096, 72100, 72104, 72108, + 72112, 72116, 72120, 72124, 72128, 72132, 72136, 72140, 72144, 72148, + 72151, 72155, 72159, 72163, 72167, 72171, 72175, 72179, 72183, 72187, + 72191, 72195, 72199, 72203, 72207, 72211, 72215, 72219, 72223, 72227, + 72231, 72235, 72239, 72243, 72247, 72251, 72255, 72259, 72263, 72267, + 72271, 72275, 72279, 72283, 72287, 72291, 72295, 72299, 72303, 72307, + 72311, 72315, 72319, 72323, 72327, 72331, 72335, 72339, 72343, 72347, + 72351, 72355, 72359, 72363, 72367, 72371, 72375, 72379, 72383, 72387, + 72391, 72395, 72399, 72403, 72407, 72411, 72415, 72419, 72423, 72427, + 72431, 72435, 72439, 72443, 72447, 72451, 72455, 72459, 72463, 72467, + 72471, 72475, 72479, 72483, 72487, 72491, 72495, 72499, 72503, 72507, + 72511, 72515, 72519, 72523, 72527, 72531, 72535, 72539, 72543, 72547, + 72551, 72555, 72559, 72563, 72567, 72571, 72575, 72579, 72583, 72587, + 72591, 72595, 72599, 72603, 72607, 72611, 72615, 72619, 72623, 72627, + 72631, 72635, 72639, 72643, 72647, 72651, 72655, 72659, 72663, 72667, + 72671, 72675, 72679, 72683, 72687, 72691, 72695, 72699, 72703, 72707, + 72711, 72715, 72719, 72723, 72727, 72731, 72735, 72739, 72743, 72747, + 72751, 72754, 72758, 72762, 72766, 72770, 72774, 72778, 72782, 72785, + 72789, 72793, 72797, 72801, 72805, 72809, 72813, 72817, 72821, 72825, + 72829, 72833, 72837, 72841, 72845, 72849, 72853, 72857, 72861, 72865, + 72869, 72873, 72877, 72881, 72885, 72889, 72893, 72897, 72901, 72905, + 72909, 72913, 72917, 72921, 72925, 72929, 72933, 72937, 72941, 72945, + 72949, 72953, 72957, 72961, 72965, 72969, 72973, 72977, 72981, 72985, + 72989, 72993, 72997, 73001, 73005, 73009, 73013, 73017, 73021, 73025, + 73029, 73033, 73037, 73041, 73045, 73049, 73053, 73057, 73061, 73065, + 73069, 73073, 73077, 73081, 73085, 73089, 73093, 73097, 73101, 73105, + 73109, 73113, 73117, 73121, 73125, 73129, 73133, 73137, 73141, 73145, + 73149, 73153, 73157, 73161, 73165, 73169, 73173, 73177, 73181, 73185, + 73189, 73193, 73197, 73201, 73205, 73209, 73213, 73217, 73221, 73225, + 73229, 73233, 73237, 73241, 73245, 73249, 73253, 73257, 73261, 73265, + 73269, 73273, 73277, 73281, 73285, 73289, 73293, 73297, 73301, 73305, + 73309, 73313, 73317, 73321, 73325, 73329, 73333, 73337, 73341, 73345, + 73349, 73353, 73357, 73361, 73365, 73369, 73373, 73377, 73381, 73385, + 73389, 73393, 73397, 73401, 73405, 73409, 73413, 73417, 73421, 73425, + 73429, 73433, 73437, 73441, 73445, 73449, 73453, 73457, 73461, 73465, + 73469, 73473, 73477, 73481, 73485, 73489, 73493, 73497, 73501, 73505, + 73509, 73512, 73516, 73520, 73524, 73528, 73532, 73536, 73540, 73544, + 73548, 73552, 73556, 73560, 73564, 73568, 73572, 73576, 73580, 73584, + 73588, 73592, 73596, 73600, 73604, 73608, 73612, 73616, 73620, 73624, + 73628, 73632, 73636, 73640, 73644, 73648, 73652, 73656, 73660, 73664, + 73668, 73672, 73676, 73680, 73684, 73688, 73692, 73696, 73700, 73704, + 73708, 73712, 73716, 73720, 73724, 73728, 73732, 73736, 73740, 73744, + 73748, 73752, 73756, 73760, 73764, 73768, 73772, 73776, 73780, 73784, + 73788, 73792, 73796, 73800, 73804, 73808, 73812, 73816, 73820, 73824, + 73828, 73832, 73836, 73840, 73844, 73848, 73852, 73856, 73860, 73864, + 73868, 73872, 73876, 73880, 73884, 73888, 73892, 73896, 73900, 73904, + 73908, 73912, 73916, 73920, 73924, 73928, 73932, 73936, 73940, 73944, + 73948, 73952, 73956, 73960, 73964, 73968, 73972, 73976, 73980, 73984, + 73988, 73992, 73996, 74000, 74004, 74008, 74012, 74016, 74020, 74024, + 74028, 74032, 74036, 74040, 74044, 74048, 74052, 74056, 74060, 74064, + 74068, 74072, 74076, 74080, 74084, 74088, 74092, 74096, 74100, 74104, + 74108, 74112, 74116, 74120, 74124, 74128, 74132, 74136, 74140, 74144, + 74148, 74152, 74156, 74160, 74164, 74168, 74172, 74176, 74180, 74184, + 74188, 74192, 74196, 74200, 74204, 74208, 74212, 74216, 74220, 74224, + 74228, 74232, 74236, 74240, 74244, 74248, 74252, 74256, 74260, 74264, + 74268, 74272, 74276, 74280, 74284, 74288, 74292, 0, 0, 0, 74296, 74300, + 74304, 74308, 74312, 74316, 74320, 74324, 74328, 74332, 74336, 74340, + 74344, 74348, 74352, 74356, 74360, 74364, 74368, 74372, 74376, 74380, + 74384, 74388, 74392, 74396, 74400, 74404, 74408, 74412, 74416, 74420, + 74424, 74428, 74432, 74436, 74440, 74444, 74448, 74452, 74456, 74460, + 74464, 74468, 74472, 74476, 74480, 74484, 74488, 74492, 74496, 74500, + 74504, 74508, 74512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74516, 74521, 74525, + 74530, 74535, 74540, 74545, 74550, 74554, 74559, 74564, 74569, 74574, + 74579, 74584, 74589, 74593, 74597, 74601, 74605, 74610, 74615, 74620, + 74624, 74629, 74634, 74639, 74644, 74649, 74653, 74658, 74662, 74667, + 74671, 74676, 74680, 74684, 74688, 74693, 74698, 74703, 74711, 74719, + 74727, 74735, 74742, 74750, 74756, 74764, 74768, 74772, 74776, 74780, + 74784, 74788, 74792, 74796, 74800, 74804, 74808, 74812, 74816, 74820, + 74824, 74828, 74832, 74836, 74840, 74844, 74848, 74852, 74856, 74860, + 74864, 74868, 74872, 74876, 74880, 74884, 74888, 74892, 74896, 74900, + 74904, 74908, 74911, 74915, 74919, 74923, 74927, 74931, 74935, 74939, + 74943, 74947, 74951, 74955, 74959, 74963, 74967, 74971, 74975, 74979, + 74983, 74987, 74991, 74995, 74999, 75003, 75007, 75011, 75015, 75019, + 75023, 75027, 75031, 75035, 75039, 75043, 75047, 75051, 75055, 75058, + 75062, 75066, 75069, 75073, 75077, 75081, 75084, 75088, 75092, 75096, + 75100, 75104, 75108, 75112, 75116, 75120, 75124, 75128, 75132, 75136, + 75139, 75142, 75146, 75150, 75153, 75157, 75161, 75165, 75169, 75173, + 75177, 75180, 75183, 75187, 75191, 75195, 75198, 75201, 75205, 75209, + 75213, 75217, 75221, 75225, 75229, 75233, 75237, 75241, 75245, 75249, + 75253, 75257, 75261, 75265, 75269, 75273, 75277, 75281, 75285, 75289, + 75293, 75297, 75301, 75305, 75309, 75313, 75317, 75321, 75325, 75329, + 75333, 75337, 75341, 75345, 75349, 75352, 75356, 75360, 75364, 75368, + 75372, 75376, 75380, 75384, 75388, 75392, 75396, 75400, 75404, 75408, + 75412, 75416, 75420, 75424, 75428, 75432, 75436, 75440, 75444, 75448, + 75452, 75456, 75460, 75464, 75468, 75472, 75476, 75480, 75484, 75488, + 75492, 75496, 75499, 75503, 75507, 75511, 75515, 75519, 75523, 75527, + 75531, 75535, 75539, 75543, 75547, 75551, 75555, 75559, 75563, 75566, + 75570, 75574, 75578, 75582, 75586, 75590, 75594, 75598, 75602, 75606, + 75610, 75614, 75618, 75622, 75626, 75630, 75634, 75638, 75642, 75646, + 75650, 75653, 75657, 75661, 75665, 75669, 75673, 75677, 75681, 75685, + 75689, 75693, 75697, 75701, 75705, 75709, 75713, 75717, 75721, 75725, + 75729, 75733, 75737, 75741, 75745, 75749, 75753, 75757, 75761, 75765, + 75769, 75773, 75777, 75781, 75785, 75789, 75793, 75797, 75801, 75805, + 75809, 75813, 75817, 75821, 75825, 75828, 75833, 75837, 75843, 75848, + 75854, 75858, 75862, 75866, 75870, 75874, 75878, 75882, 75886, 75890, + 75894, 75898, 75902, 75906, 75910, 75913, 75916, 75919, 75922, 75925, + 75928, 75931, 75934, 75937, 75942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 75948, 75953, 75958, 75963, 75968, 75975, 75982, + 75987, 75992, 75997, 76002, 76009, 76016, 76023, 76030, 76037, 76044, + 76054, 76064, 76071, 76078, 76085, 76092, 76098, 76104, 76113, 76122, + 76129, 76136, 76147, 76158, 76163, 76168, 76175, 76182, 76189, 76196, + 76203, 76210, 76217, 76224, 76230, 76236, 76242, 76248, 76255, 76262, + 76267, 76271, 76278, 76285, 76292, 76296, 76303, 76307, 76312, 76316, + 76322, 76327, 76333, 76338, 76342, 76346, 76349, 76352, 76357, 76362, + 76367, 76372, 76377, 76382, 76387, 76392, 76397, 76402, 76410, 76418, + 76423, 76428, 76433, 76438, 76443, 76448, 76453, 76458, 76463, 76468, + 76473, 76478, 76483, 76488, 76494, 76500, 76506, 76512, 76517, 76523, + 76526, 76529, 76532, 76536, 76540, 76544, 76548, 76551, 76555, 76558, + 76561, 76564, 76568, 76572, 76576, 76580, 76584, 76588, 76592, 76596, + 76600, 76604, 76608, 76612, 76616, 76620, 76624, 76628, 76632, 76636, + 76640, 76644, 76648, 76652, 76655, 76659, 76663, 76667, 76671, 76675, + 76679, 76683, 76687, 76691, 76695, 76699, 76703, 76707, 76711, 76715, + 76719, 76723, 76727, 76731, 76735, 76739, 76743, 76747, 76751, 76754, + 76758, 76762, 76766, 76770, 76774, 76778, 76782, 76785, 76789, 76793, + 76797, 76801, 76805, 76809, 76813, 76817, 76821, 76825, 76829, 76833, + 76838, 76843, 76846, 76851, 76854, 76857, 76860, 0, 0, 0, 0, 0, 0, 0, 0, + 76864, 76873, 76882, 76891, 76900, 76909, 76918, 76927, 76936, 76944, + 76951, 76959, 76966, 76974, 76984, 76993, 77003, 77012, 77022, 77030, + 77037, 77045, 77052, 77060, 77065, 77070, 77076, 77084, 77090, 77096, + 77103, 77112, 77120, 77128, 77136, 77143, 77150, 77157, 77164, 77169, + 77174, 77179, 77184, 77189, 77194, 77199, 77204, 77212, 77220, 77226, + 77232, 77237, 77242, 77247, 77252, 77257, 77262, 77267, 77272, 77281, + 77290, 77295, 77300, 77310, 77320, 77327, 77334, 77343, 77352, 77364, + 77376, 77382, 77388, 77396, 77404, 77414, 77424, 77431, 77438, 77443, + 77448, 77460, 77472, 77480, 77488, 77498, 77508, 77520, 77532, 77541, + 77550, 77557, 77564, 77571, 77578, 77587, 77596, 77601, 77606, 77613, + 77620, 77627, 77634, 77646, 77658, 77663, 77668, 77673, 77678, 77683, + 77688, 77693, 77698, 77702, 77707, 77712, 77717, 77722, 77727, 77733, + 77738, 77743, 77750, 77757, 77764, 77771, 77778, 77786, 77794, 77799, + 77804, 77810, 77816, 77823, 77830, 77837, 77844, 77851, 77855, 77862, + 77867, 77872, 77878, 77891, 77897, 77905, 77913, 77920, 77927, 77936, + 77945, 77952, 77959, 77966, 77973, 77980, 77987, 77994, 78001, 78008, + 78015, 78024, 78033, 78042, 78051, 78060, 78069, 78078, 78087, 78096, + 78105, 78112, 78120, 78126, 78134, 78140, 78146, 78152, 78158, 78166, + 78171, 78176, 78181, 78186, 78191, 78197, 78203, 78209, 78215, 78221, + 78227, 78233, 78239, 78246, 78253, 78260, 78267, 78276, 78283, 78292, + 78304, 78316, 78328, 0, 0, 0, 0, 0, 78340, 78349, 0, 78358, 0, 78364, + 78370, 78378, 78386, 78393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 78400, 78405, 78410, 78415, 78423, 78431, + 78438, 78445, 78451, 78458, 78466, 78474, 78482, 78490, 78498, 78504, + 78510, 78517, 78523, 78529, 78535, 78542, 78549, 78556, 78563, 78570, + 78577, 78584, 78591, 78598, 78605, 78612, 78619, 78626, 78633, 78639, + 78646, 78653, 78660, 78667, 78674, 78681, 78688, 78695, 78702, 78709, + 78716, 78723, 78730, 78737, 78744, 78751, 78758, 78765, 78773, 78781, + 78789, 78797, 78805, 0, 0, 0, 78814, 78822, 78830, 78838, 78846, 78854, + 78862, 78868, 78874, 78880, 0, 0, 0, 0, 0, 0, 78886, 78890, 78895, 78900, + 78905, 78910, 78915, 78920, 78925, 78930, 78935, 78940, 78944, 78948, + 78953, 78958, 78962, 78967, 78972, 78977, 78982, 78987, 78992, 78997, + 79001, 79005, 79009, 79014, 79018, 79022, 79026, 79030, 79034, 79038, + 79042, 79047, 79052, 79057, 79062, 79067, 79074, 79080, 79085, 79090, + 79095, 79100, 79106, 79113, 79119, 79126, 79132, 79138, 79143, 79150, + 79156, 79161, 0, 0, 0, 0, 0, 0, 0, 0, 79167, 79172, 79177, 79181, 79186, + 79190, 79195, 79199, 79204, 79209, 79215, 79220, 79226, 79230, 79235, + 79240, 79244, 79249, 79254, 79258, 79263, 79268, 79273, 79278, 79283, + 79288, 79293, 79298, 79303, 79308, 79313, 79318, 79323, 79328, 79333, + 79338, 79343, 79348, 79352, 79356, 79361, 79366, 79371, 79375, 79379, + 79383, 79387, 79392, 79397, 79402, 79406, 79410, 79415, 79421, 79427, + 79432, 79438, 79443, 79449, 79455, 79462, 79468, 79475, 79480, 79486, + 79492, 79497, 79503, 79509, 79514, 0, 0, 0, 0, 0, 0, 0, 0, 79519, 79523, + 79528, 79533, 79537, 79541, 79545, 79549, 79553, 79557, 79561, 79565, 0, + 0, 0, 0, 0, 0, 79569, 79574, 79578, 79582, 79586, 79590, 79594, 79598, + 79602, 79606, 79610, 79614, 79618, 79622, 79626, 79630, 79634, 79639, + 79644, 79650, 79656, 79663, 79668, 79673, 79679, 79683, 79688, 79691, + 79694, 79698, 79703, 79707, 79712, 79719, 79725, 79731, 79737, 79743, + 79749, 79755, 79761, 79767, 79773, 79779, 79786, 79793, 79800, 79806, + 79813, 79820, 79827, 79834, 79841, 79847, 79853, 79860, 79866, 79873, + 79880, 79886, 79892, 79898, 79905, 79912, 79918, 79925, 79932, 79938, + 79945, 79951, 79958, 79965, 79971, 79977, 79984, 79990, 79997, 80004, + 80013, 80020, 80027, 80031, 80036, 80041, 80046, 80051, 80055, 80059, + 80064, 80068, 80073, 80078, 80083, 80087, 80091, 80095, 80099, 80104, + 80108, 80113, 80118, 80123, 80128, 80132, 80137, 80142, 80147, 80153, + 80158, 80164, 80170, 80176, 80182, 80188, 80193, 80199, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 80203, 80208, 80212, 80216, 80220, 80224, 80228, 80232, + 80236, 80240, 80244, 80248, 80252, 80256, 80260, 80264, 80268, 80272, + 80276, 80280, 80284, 80288, 80292, 80296, 80300, 80304, 80308, 80312, + 80316, 80320, 0, 0, 0, 80324, 80329, 80334, 80339, 80344, 80348, 80355, + 80359, 80364, 80368, 80375, 80382, 80391, 80395, 80400, 80404, 80408, + 80415, 80422, 80427, 80434, 80439, 80444, 80451, 80456, 80463, 80470, + 80475, 80480, 80487, 80492, 80499, 80506, 80511, 80518, 80523, 80530, + 80534, 80538, 80545, 80550, 80557, 80561, 80565, 80569, 80576, 80580, + 80585, 80592, 80599, 80603, 80607, 80614, 80620, 80626, 80632, 80640, + 80646, 80654, 80660, 80668, 80674, 80680, 80686, 80692, 80696, 80701, + 80706, 80712, 80718, 80724, 80730, 80736, 80742, 80748, 80754, 80762, + 80768, 0, 80775, 80779, 80784, 80788, 80792, 80796, 80800, 80804, 80808, + 80812, 80816, 0, 0, 0, 0, 80820, 80828, 80834, 80840, 80846, 80852, + 80858, 80864, 80870, 80877, 80884, 80891, 80898, 80905, 80912, 80919, + 80926, 80933, 80940, 80947, 80953, 80959, 80965, 80971, 80977, 80983, + 80989, 80995, 81001, 81008, 81015, 81022, 81029, 0, 81036, 81040, 81044, + 81048, 81052, 81057, 81061, 81065, 81070, 81075, 81080, 81085, 81090, + 81095, 81100, 81105, 81110, 81115, 81120, 81125, 81130, 81135, 81140, + 81145, 81150, 81154, 81159, 81163, 81168, 81173, 81178, 81183, 81188, + 81192, 81197, 81201, 81205, 81209, 81214, 81219, 81223, 81227, 81233, + 81238, 81244, 81250, 81255, 81261, 81266, 81272, 81278, 81284, 81289, + 81294, 81299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81305, 81311, 81317, 81323, + 81330, 81336, 81342, 81348, 81354, 81360, 81365, 81370, 81376, 81383, 0, + 0, 81390, 81395, 81399, 81403, 81407, 81411, 81415, 81419, 81423, 81427, + 0, 0, 81431, 81437, 81443, 81450, 81458, 81464, 81470, 81476, 81482, + 81488, 81494, 81500, 81506, 81512, 81518, 81524, 81529, 81534, 81539, + 81545, 81551, 81558, 81564, 81570, 81575, 81582, 81589, 81596, 81602, + 81607, 81612, 81617, 81625, 81632, 81639, 81647, 81655, 81662, 81669, + 81676, 81683, 81690, 81697, 81704, 81711, 81718, 81725, 81732, 81739, + 81746, 81753, 81760, 81767, 81774, 81781, 81788, 81795, 81801, 81807, + 81814, 81821, 81828, 81835, 81842, 81849, 81856, 81863, 81870, 81877, + 81884, 81891, 81898, 81905, 81912, 81919, 81926, 81933, 81940, 81947, + 81954, 81961, 81968, 81975, 81981, 81987, 81994, 82000, 82005, 82011, + 82016, 82021, 82026, 82033, 82039, 82045, 82051, 82057, 82063, 82069, + 82075, 82083, 82091, 82099, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 82107, 82113, 82119, 82125, 82133, 82141, + 82147, 82153, 82160, 82167, 82174, 82181, 82188, 82195, 82202, 82209, + 82216, 82224, 82232, 82240, 82248, 82256, 82262, 82270, 82276, 82284, + 82293, 82301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82307, 82311, 82315, 82319, + 82323, 82327, 0, 0, 82331, 82335, 82339, 82343, 82347, 82351, 0, 0, + 82355, 82359, 82363, 82367, 82371, 82375, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 82379, 82383, 82387, 82391, 82395, 82399, 82403, 0, 82407, 82411, 82415, + 82419, 82423, 82427, 82431, 0, 82435, 82442, 82448, 82454, 82460, 82468, + 82475, 82484, 82496, 82506, 82515, 82523, 82531, 82539, 82545, 82553, + 82561, 82568, 82576, 82586, 82593, 82602, 82608, 82618, 82627, 82632, + 82640, 82649, 82654, 82663, 82670, 82680, 82692, 82697, 82703, 82710, + 82715, 82725, 82735, 82745, 82755, 82770, 82783, 82794, 82802, 82807, + 82819, 82828, 82835, 82842, 82848, 82855, 82860, 82867, 82873, 82884, + 82895, 82905, 82911, 82916, 0, 0, 0, 0, 82921, 82925, 82929, 82933, + 82937, 82941, 82946, 82951, 82955, 82960, 82965, 82970, 82975, 82980, + 82984, 82989, 82994, 82999, 83004, 83009, 83013, 83018, 83023, 83028, + 83033, 83038, 83042, 83047, 83052, 83057, 83062, 83066, 83071, 83076, + 83081, 83086, 83091, 83096, 83101, 83106, 83111, 83116, 83121, 83126, + 83131, 83135, 83140, 83145, 83150, 83155, 83160, 83165, 83170, 83175, + 83180, 83185, 83190, 83195, 83200, 83205, 83210, 83215, 83220, 83225, + 83230, 83235, 83240, 83245, 83250, 83255, 83260, 83265, 83270, 83275, + 83280, 83285, 83290, 83295, 83300, 83305, 83309, 83316, 83323, 83330, + 83337, 83343, 83349, 83356, 83363, 83370, 83377, 83384, 83391, 83398, + 83405, 83412, 83418, 83425, 83432, 83439, 83446, 83453, 83460, 83467, + 83474, 83481, 83488, 83495, 83504, 83513, 83522, 83531, 83540, 83549, + 83558, 83567, 83575, 83583, 83591, 83599, 83607, 83615, 83623, 83631, + 83637, 83645, 0, 0, 83653, 83660, 83666, 83672, 83678, 83684, 83690, + 83696, 83702, 83708, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83714, 83719, 83724, 83729, 83734, + 83739, 83744, 83749, 83754, 83759, 83764, 83769, 83774, 83779, 83784, + 83789, 83794, 83799, 83804, 83809, 83814, 83819, 83824, 0, 0, 0, 0, + 83829, 83833, 83837, 83841, 83845, 83849, 83853, 83857, 83861, 83865, + 83869, 83873, 83877, 83881, 83885, 83889, 83893, 83897, 83901, 83905, + 83909, 83913, 83917, 83921, 83925, 83929, 83933, 83937, 83941, 83945, + 83949, 83953, 83957, 83961, 83965, 83969, 83973, 83977, 83981, 83985, + 83989, 83993, 83997, 84001, 84005, 84009, 84013, 84017, 84021, 0, 0, 0, + 0, 84025, 84029, 84033, 84037, 84041, 84045, 84049, 84053, 84057, 84061, + 84065, 84069, 84073, 84077, 84081, 84085, 84089, 84093, 84097, 84101, + 84105, 84109, 84113, 84117, 84121, 84125, 84129, 84133, 84137, 84141, + 84145, 84149, 84153, 84157, 84161, 84165, 84169, 84173, 84177, 84181, + 84185, 84189, 84193, 84197, 84201, 84205, 84209, 84213, 84217, 84221, + 84225, 84229, 84233, 84237, 84241, 84245, 84249, 84253, 84257, 84261, + 84265, 84269, 84273, 84277, 84281, 84285, 84289, 84293, 84297, 84301, + 84305, 84309, 84313, 84317, 84321, 84325, 84329, 84333, 84337, 84341, + 84345, 84349, 84353, 84357, 84361, 84365, 84369, 84373, 84377, 84381, + 84385, 84389, 84393, 84397, 84401, 84405, 84409, 84413, 84417, 84421, + 84425, 84429, 84433, 84437, 84441, 84445, 84449, 84453, 84457, 84461, + 84465, 84469, 84473, 84477, 84481, 84485, 84489, 84493, 84497, 84501, + 84505, 84509, 84513, 84517, 84521, 84525, 84529, 84533, 84537, 84541, + 84545, 84549, 84553, 84557, 84561, 84565, 84569, 84573, 84577, 84581, + 84585, 84589, 84593, 84597, 84601, 84605, 84609, 84613, 84617, 84621, + 84625, 84629, 84633, 84637, 84641, 84645, 84649, 84653, 84657, 84661, + 84665, 84669, 84673, 84677, 84681, 84685, 84689, 84693, 84697, 84701, + 84705, 84709, 84713, 84717, 84721, 84725, 84729, 84733, 84737, 84741, + 84745, 84749, 84753, 84757, 84761, 84765, 84769, 84773, 84777, 84781, + 84785, 84789, 84793, 84797, 84801, 84805, 84809, 84813, 84817, 84821, + 84825, 84829, 84833, 84837, 84841, 84845, 84849, 84853, 84857, 84861, + 84865, 84869, 84873, 84877, 84881, 84885, 84889, 84893, 84897, 84901, + 84905, 84909, 84913, 84917, 84921, 84925, 84929, 84933, 84937, 84941, + 84945, 84949, 84953, 84957, 84961, 84965, 84969, 84973, 84977, 84981, + 84985, 84989, 84993, 84997, 85001, 85005, 85009, 85013, 85017, 85021, + 85025, 85029, 85033, 85037, 85041, 85045, 85049, 85053, 85057, 85061, + 85065, 85069, 85073, 85077, 85081, 85085, 85089, 85093, 85097, 85101, + 85105, 85109, 85113, 85117, 85121, 85125, 85129, 85133, 85137, 85141, + 85145, 85149, 85153, 85157, 85161, 85165, 85169, 85173, 85177, 85181, + 85185, 85189, 85193, 85197, 85201, 85205, 85209, 85213, 85217, 85221, + 85225, 85229, 85233, 85237, 85241, 85245, 85249, 85253, 85257, 85261, + 85265, 85269, 85273, 85277, 85281, 85285, 85289, 85293, 85297, 85301, + 85305, 85309, 85313, 85317, 85321, 85325, 85329, 85333, 85337, 85341, + 85345, 85349, 85353, 85357, 85361, 85365, 85369, 85373, 85377, 85381, + 85385, 85389, 85393, 85397, 85401, 85405, 85409, 85413, 85417, 85421, + 85425, 85429, 85433, 85437, 85441, 85445, 85449, 85453, 85457, 85461, + 85465, 85469, 85473, 85477, 85481, 85485, 0, 0, 85489, 85493, 85497, + 85501, 85505, 85509, 85513, 85517, 85521, 85525, 85529, 85533, 85537, + 85541, 85545, 85549, 85553, 85557, 85561, 85565, 85569, 85573, 85577, + 85581, 85585, 85589, 85593, 85597, 85601, 85605, 85609, 85613, 85617, + 85621, 85625, 85629, 85633, 85637, 85641, 85645, 85649, 85653, 85657, + 85661, 85665, 85669, 85673, 85677, 85681, 85685, 85689, 85693, 85697, + 85701, 85705, 85709, 85713, 85717, 85721, 85725, 85729, 85733, 85737, + 85741, 85745, 85749, 85753, 85757, 85761, 85765, 85769, 85773, 85777, + 85781, 85785, 85789, 85793, 85797, 85801, 85805, 85809, 85813, 85817, + 85821, 85825, 85829, 85833, 85837, 85841, 85845, 85849, 85853, 85857, + 85861, 85865, 85869, 85873, 85877, 85881, 85885, 85889, 85893, 85897, + 85901, 85905, 85909, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85913, + 85918, 85923, 85928, 85933, 85938, 85946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 85951, 85959, 85967, 85975, 85983, 0, 0, 0, 0, 0, 85991, 85998, + 86005, 86015, 86021, 86027, 86033, 86039, 86045, 86051, 86058, 86064, + 86070, 86076, 86085, 86094, 86106, 86118, 86124, 86130, 86136, 86143, + 86150, 86157, 86164, 86171, 0, 86178, 86185, 86192, 86200, 86207, 0, + 86214, 0, 86221, 86228, 0, 86235, 86243, 0, 86250, 86257, 86264, 86271, + 86278, 86285, 86292, 86299, 86306, 86313, 86318, 86325, 86332, 86338, + 86344, 86350, 86357, 86363, 86369, 86375, 86382, 86388, 86394, 86400, + 86407, 86413, 86419, 86425, 86432, 86438, 86444, 86450, 86457, 86463, + 86469, 86475, 86482, 86488, 86494, 86500, 86507, 86513, 86519, 86525, + 86532, 86538, 86544, 86550, 86557, 86563, 86569, 86575, 86582, 86588, + 86594, 86600, 86607, 86613, 86619, 86625, 86632, 86638, 86644, 86650, + 86656, 86662, 86668, 86674, 86680, 86686, 86692, 86698, 86704, 86710, + 86716, 86722, 86729, 86735, 86741, 86747, 86754, 86760, 86766, 86772, + 86779, 86785, 86791, 86797, 86804, 86812, 86820, 86826, 86832, 86838, + 86845, 86854, 86863, 86871, 86879, 86887, 86896, 86904, 86912, 86920, + 86929, 86936, 86943, 86954, 86965, 86969, 86973, 86978, 86983, 86988, + 86993, 87002, 87011, 87017, 87023, 87030, 87037, 87044, 87048, 87054, + 87060, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87065, 87071, + 87077, 87083, 87090, 87095, 87100, 87106, 87112, 87118, 87124, 87133, + 87139, 87145, 87153, 87161, 87169, 87177, 87183, 87189, 87195, 87202, + 87215, 87229, 87240, 87251, 87263, 87275, 87287, 87299, 87310, 87321, + 87333, 87345, 87357, 87369, 87381, 87393, 87405, 87422, 87439, 87456, + 87463, 87470, 87477, 87485, 87497, 87508, 87519, 87532, 87543, 87552, + 87560, 87569, 87577, 87587, 87595, 87604, 87612, 87621, 87629, 87639, + 87647, 87656, 87664, 87674, 87682, 87690, 87698, 87706, 87713, 87722, + 87730, 87738, 87747, 87755, 87764, 87772, 87780, 87788, 87797, 87805, + 87814, 87822, 87830, 87838, 87846, 87855, 87863, 87872, 87880, 87889, + 87897, 87906, 87914, 87924, 87932, 87940, 87948, 87958, 87966, 87974, + 87983, 87991, 88000, 88009, 88017, 88027, 88035, 88044, 88052, 88061, + 88069, 88079, 88087, 88095, 88102, 88110, 88117, 88126, 88133, 88142, + 88150, 88159, 88167, 88177, 88185, 88194, 88202, 88212, 88220, 88228, + 88235, 88243, 88250, 88259, 88266, 88276, 88286, 88297, 88306, 88315, + 88324, 88333, 88342, 88352, 88364, 88376, 88387, 88399, 88412, 88423, + 88432, 88441, 88449, 88458, 88468, 88476, 88485, 88494, 88502, 88511, + 88521, 88529, 88538, 88547, 88555, 88564, 88574, 88582, 88592, 88600, + 88610, 88618, 88626, 88635, 88643, 88653, 88661, 88669, 88679, 88687, + 88694, 88701, 88710, 88719, 88727, 88736, 88746, 88754, 88765, 88773, + 88781, 88788, 88796, 88805, 88812, 88824, 88835, 88847, 88858, 88870, + 88879, 88887, 88896, 88904, 88913, 88922, 88930, 88939, 88947, 88956, + 88964, 88972, 88980, 88988, 88995, 89004, 89012, 89021, 89029, 89038, + 89046, 89054, 89063, 89071, 89080, 89088, 89097, 89105, 89113, 89121, + 89130, 89138, 89147, 89155, 89164, 89172, 89181, 89189, 89197, 89205, + 89214, 89222, 89231, 89240, 89248, 89257, 89265, 89274, 89282, 89291, + 89299, 89306, 89314, 89321, 89330, 89338, 89347, 89355, 89364, 89373, + 89381, 89391, 89399, 89406, 89414, 89421, 89429, 89441, 89454, 89463, + 89473, 89482, 89492, 89501, 89511, 89520, 89530, 89539, 89549, 89559, + 89568, 89577, 89586, 89596, 89604, 89613, 89623, 89633, 89643, 89653, + 89661, 89671, 89679, 89689, 89697, 89707, 89715, 89725, 89733, 89742, + 89749, 89759, 89767, 89777, 89785, 89795, 89803, 89813, 89821, 89830, + 89838, 89847, 89855, 89864, 89873, 89882, 89891, 89901, 89909, 89919, + 89927, 89937, 89945, 89955, 89963, 89973, 89981, 89990, 89997, 90007, + 90015, 90025, 90033, 90043, 90051, 90061, 90069, 90078, 90086, 90095, + 90103, 90112, 90121, 90130, 90139, 90148, 90156, 90165, 90173, 90182, + 90191, 90199, 90209, 90218, 90228, 90238, 90247, 90257, 90266, 90275, + 90283, 90291, 90296, 90301, 90307, 90315, 90323, 90331, 90339, 90347, + 90355, 90361, 90367, 90373, 90381, 90387, 90397, 90403, 90409, 90415, + 90426, 90437, 90448, 90458, 90469, 90480, 90490, 90501, 90511, 90521, + 90530, 90541, 90552, 90563, 90576, 90586, 90596, 90607, 90617, 90627, + 90637, 90647, 90657, 90667, 90677, 90688, 90699, 90710, 90720, 90730, + 90742, 90753, 90764, 90774, 90784, 90794, 90804, 90815, 90825, 90835, + 90847, 90857, 90867, 90879, 90890, 90901, 90911, 90921, 90931, 90941, + 90953, 90965, 90977, 90988, 90999, 91009, 91019, 91029, 91038, 91047, + 91057, 91067, 91078, 0, 0, 91088, 91099, 91110, 91120, 91130, 91142, + 91153, 91164, 91177, 91187, 91199, 91208, 91217, 91228, 91239, 91252, + 91263, 91276, 91286, 91298, 91308, 91320, 91332, 91345, 91355, 91365, + 91375, 91386, 91396, 91405, 91415, 91424, 91433, 91443, 91453, 91463, + 91473, 91483, 91493, 91504, 91514, 91525, 91535, 91546, 91557, 91567, + 91577, 91587, 91597, 91607, 91617, 91628, 91638, 91649, 0, 0, 0, 0, 0, 0, + 0, 91660, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91666, 91681, 91696, 91702, 91708, + 91714, 91720, 91726, 91732, 91738, 91744, 91752, 91756, 91759, 91767, + 91775, 91783, 91786, 91789, 91792, 91795, 91798, 91801, 91804, 91807, + 91810, 91813, 91816, 91819, 91822, 91825, 91828, 91831, 91839, 91848, + 91859, 91867, 91875, 91884, 91893, 91905, 91917, 0, 0, 0, 0, 0, 0, 91927, + 91932, 91937, 91944, 91951, 91957, 91963, 91968, 91973, 91978, 91984, + 91990, 91996, 92002, 92008, 92015, 92022, 92032, 92042, 92052, 92061, + 92072, 92081, 92090, 92101, 92112, 92125, 92138, 92150, 92162, 92174, + 92186, 92197, 92208, 92219, 92230, 92242, 92254, 92258, 92263, 92273, + 92283, 92287, 92291, 92295, 92300, 92305, 92310, 92315, 92318, 92322, 0, + 92327, 92330, 92333, 92337, 92341, 92346, 92350, 92354, 92360, 92366, + 92374, 92382, 92385, 92388, 92391, 92394, 92397, 92401, 92405, 0, 92409, + 92414, 92418, 92422, 0, 0, 0, 0, 92427, 92432, 92439, 92444, 92449, 0, + 92454, 92459, 92465, 92470, 92476, 92481, 92487, 92492, 92498, 92503, + 92509, 92515, 92524, 92533, 92542, 92551, 92561, 92571, 92581, 92591, + 92600, 92609, 92618, 92628, 92633, 92638, 92644, 92650, 92656, 92663, + 92671, 92679, 92685, 92691, 92697, 92704, 92710, 92716, 92722, 92729, + 92735, 92741, 92747, 92754, 92759, 92764, 92769, 92775, 92781, 92787, + 92793, 92800, 92806, 92812, 92818, 92824, 92830, 92836, 92842, 92848, + 92854, 92860, 92866, 92873, 92879, 92885, 92891, 92898, 92904, 92910, + 92916, 92923, 92929, 92935, 92941, 92948, 92954, 92960, 92966, 92973, + 92979, 92985, 92991, 92998, 93004, 93010, 93016, 93023, 93029, 93035, + 93041, 93048, 93054, 93060, 93066, 93073, 93079, 93085, 93091, 93098, + 93104, 93110, 93116, 93123, 93129, 93135, 93141, 93148, 93153, 93158, + 93163, 93169, 93175, 93181, 93187, 93194, 93200, 93206, 93212, 93219, + 93225, 93231, 93238, 93245, 93250, 93255, 93260, 93266, 93278, 93290, + 93302, 93314, 93327, 93340, 93348, 0, 0, 93356, 0, 93364, 93369, 93374, + 93378, 93383, 93388, 93392, 93396, 93401, 93406, 93410, 93414, 93418, + 93422, 93428, 93432, 93437, 93441, 93445, 93449, 93453, 93457, 93461, + 93465, 93469, 93473, 93477, 93481, 93486, 93491, 93496, 93501, 93507, + 93513, 93520, 93527, 93534, 93540, 93547, 93554, 93561, 93567, 93574, + 93581, 93587, 93594, 93601, 93607, 93614, 93621, 93627, 93634, 93641, + 93647, 93654, 93661, 93668, 93675, 93682, 93688, 93694, 93700, 93706, + 93711, 93717, 93723, 93730, 93737, 93744, 93750, 93757, 93764, 93771, + 93777, 93784, 93791, 93797, 93804, 93811, 93817, 93824, 93831, 93837, + 93844, 93851, 93857, 93864, 93871, 93878, 93885, 93892, 93899, 93904, + 93911, 93915, 93921, 93927, 93933, 93939, 93945, 93949, 93954, 93959, + 93964, 93969, 93974, 93979, 93984, 93989, 93995, 94001, 94007, 94015, + 94019, 94023, 94027, 94031, 94035, 94039, 94044, 94049, 94054, 94059, + 94063, 94068, 94073, 94078, 94083, 94088, 94093, 94098, 94103, 94107, + 94111, 94116, 94121, 94126, 94131, 94135, 94140, 94145, 94150, 94155, + 94159, 94164, 94169, 94174, 94179, 94183, 94188, 94193, 94197, 94202, + 94207, 94212, 94217, 94222, 94227, 94234, 94241, 94245, 94250, 94255, + 94260, 94265, 94270, 94275, 94280, 94285, 94290, 94295, 94300, 94305, + 94310, 94315, 94320, 94325, 94330, 94335, 94340, 94345, 94350, 94355, + 94360, 94365, 94370, 94375, 94380, 94385, 94390, 0, 0, 0, 94395, 94399, + 94404, 94408, 94413, 94418, 0, 0, 94422, 94427, 94432, 94436, 94441, + 94446, 0, 0, 94451, 94456, 94460, 94465, 94470, 94475, 0, 0, 94480, + 94485, 94490, 0, 0, 0, 94494, 94499, 94504, 94509, 94513, 94518, 94523, + 0, 94528, 94534, 94537, 94541, 94544, 94548, 94552, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 94556, 94562, 94568, 94574, 94580, 0, 0, 94584, 94590, 94596, + 94602, 94608, 94614, 94621, 94628, 94635, 94642, 94649, 94656, 0, 94663, + 94670, 94677, 94683, 94690, 94697, 94704, 94711, 94717, 94724, 94731, + 94738, 94745, 94751, 94758, 94765, 94772, 94779, 94785, 94792, 94799, + 94806, 94813, 94820, 94827, 94834, 0, 94841, 94847, 94854, 94861, 94868, + 94875, 94881, 94888, 94895, 94902, 94909, 94916, 94923, 94930, 94936, + 94943, 94950, 94957, 94964, 0, 94971, 94978, 0, 94985, 94992, 94999, + 95006, 95013, 95020, 95027, 95034, 95041, 95048, 95055, 95062, 95069, + 95076, 95083, 0, 0, 95089, 95094, 95099, 95104, 95109, 95114, 95119, + 95124, 95129, 95134, 95139, 95144, 95149, 95154, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 95159, 95166, 95173, 95180, 95187, 95194, 95201, 95208, 95215, + 95222, 95229, 95236, 95243, 95250, 95257, 95264, 95271, 95278, 95285, + 95292, 95300, 95308, 95315, 95322, 95327, 95335, 95343, 95350, 95357, + 95362, 95369, 95374, 95379, 95386, 95391, 95396, 95401, 95409, 95414, + 95419, 95426, 95431, 95436, 95443, 95450, 95455, 95460, 95465, 95470, + 95475, 95480, 95485, 95490, 95495, 95502, 95507, 95514, 95519, 95524, + 95529, 95534, 95539, 95544, 95549, 95554, 95559, 95564, 95569, 95576, + 95583, 95590, 95597, 95603, 95608, 95615, 95620, 95625, 95634, 95641, + 95650, 95657, 95662, 95667, 95675, 95680, 95685, 95690, 95695, 95700, + 95707, 95712, 95717, 95722, 95727, 95732, 95739, 95746, 95753, 95760, + 95767, 95774, 95781, 95788, 95795, 95802, 95809, 95816, 95823, 95830, + 95837, 95844, 95851, 95858, 95865, 95872, 95879, 95886, 95893, 95900, + 95907, 95914, 95921, 95928, 0, 0, 0, 0, 0, 95935, 95943, 95951, 0, 0, 0, + 0, 95956, 95960, 95964, 95968, 95972, 95976, 95980, 95984, 95988, 95992, + 95997, 96002, 96007, 96012, 96017, 96022, 96027, 96032, 96037, 96043, + 96049, 96055, 96062, 96069, 96076, 96083, 96090, 96097, 96102, 96107, + 96112, 96118, 96124, 96130, 96136, 96142, 96148, 96154, 96160, 96166, + 96172, 96178, 96184, 96190, 96196, 0, 0, 0, 96202, 96210, 96218, 96226, + 96234, 96242, 96252, 96262, 96270, 96278, 96286, 96294, 96302, 96308, + 96315, 96324, 96332, 96340, 96349, 96358, 96367, 96377, 96388, 96398, + 96409, 96418, 96427, 96436, 96446, 96457, 96467, 96478, 96489, 96498, + 96506, 96512, 96518, 96524, 96530, 96538, 96546, 96552, 96559, 96569, + 96576, 96583, 96590, 96597, 96604, 96614, 96621, 96628, 96636, 96644, + 96653, 96662, 96671, 96680, 96689, 96696, 96704, 96713, 96722, 96726, + 96733, 96738, 96743, 96747, 96751, 96755, 96759, 96764, 96769, 96775, + 96781, 96785, 96791, 96795, 96799, 96803, 96807, 96811, 96815, 96821, + 96825, 96830, 96834, 96838, 0, 96841, 96846, 96851, 96856, 96861, 96868, + 96873, 96878, 96883, 96888, 96893, 96898, 96903, 0, 0, 0, 96906, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96912, 96919, + 96928, 96937, 96944, 96951, 96958, 96965, 96972, 96979, 96985, 96992, + 96999, 97006, 97013, 97020, 97027, 97034, 97041, 97050, 97057, 97064, + 97071, 97078, 97085, 97092, 97099, 97106, 97115, 97122, 97129, 97136, + 97143, 97150, 97157, 97166, 97173, 97180, 97187, 97194, 97203, 97210, + 97217, 97224, 97232, 97241, 0, 0, 97250, 97254, 97258, 97263, 97268, + 97273, 97278, 97282, 97287, 97292, 97297, 97302, 97307, 97312, 97316, + 97321, 97326, 97331, 97336, 97340, 97345, 97350, 97354, 97359, 97364, + 97369, 97374, 97379, 97384, 0, 0, 0, 97389, 97393, 97398, 97403, 97407, + 97412, 97416, 97421, 97426, 97431, 97436, 97441, 97445, 97450, 97455, + 97460, 97465, 97470, 97475, 97479, 97484, 97489, 97494, 97499, 97504, + 97509, 97513, 97517, 97522, 97527, 97532, 97537, 97542, 97547, 97552, + 97557, 97562, 97567, 97572, 97577, 97582, 97587, 97592, 97597, 97602, + 97607, 97612, 97617, 97622, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 97627, 97633, 97638, 97643, 97648, 97653, 97658, 97663, 97668, 97673, + 97678, 97684, 97690, 97696, 97702, 97708, 97714, 97720, 97726, 97732, + 97739, 97746, 97753, 97761, 97769, 97777, 97785, 97793, 0, 0, 0, 0, + 97801, 97805, 97810, 97815, 97820, 97824, 97829, 97834, 97839, 97844, + 97848, 97852, 97857, 97862, 97867, 97872, 97876, 97881, 97886, 97891, + 97896, 97901, 97906, 97910, 97915, 97920, 97925, 97930, 97935, 97940, + 97945, 97950, 97955, 97960, 97965, 97971, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 97977, 97982, 97989, 97996, 98001, 98006, 98011, 98016, 98021, 98026, + 98031, 98036, 98041, 98046, 98051, 98056, 98061, 98066, 98071, 98076, + 98081, 98086, 98091, 98096, 98101, 98106, 98111, 98116, 98121, 98126, 0, + 0, 0, 0, 0, 98133, 98139, 98145, 98151, 98157, 98162, 98168, 98174, + 98180, 98186, 98191, 98197, 98203, 98209, 98215, 98221, 98227, 98233, + 98239, 98245, 98250, 98256, 98262, 98268, 98274, 98280, 98285, 98291, + 98297, 98302, 98308, 98314, 98320, 98326, 98332, 98338, 98344, 98349, + 98355, 98362, 98369, 98376, 98383, 0, 0, 0, 0, 0, 98390, 98395, 98400, + 98405, 98410, 98415, 98420, 98425, 98430, 98435, 98440, 98445, 98450, + 98455, 98460, 98465, 98470, 98475, 98480, 98485, 98490, 98495, 98500, + 98505, 98510, 98515, 98520, 98524, 98528, 98532, 0, 98537, 98543, 98548, + 98553, 98558, 98563, 98569, 98575, 98581, 98587, 98593, 98599, 98605, + 98611, 98617, 98623, 98629, 98635, 98641, 98646, 98652, 98658, 98663, + 98669, 98674, 98680, 98686, 98691, 98697, 98703, 98708, 98714, 98719, + 98724, 98730, 98736, 98742, 0, 0, 0, 0, 98747, 98753, 98759, 98765, + 98771, 98777, 98783, 98789, 98795, 98802, 98807, 98812, 98818, 98824, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98830, 98836, 98842, + 98848, 98855, 98861, 98868, 98875, 98882, 98889, 98897, 98904, 98912, + 98918, 98924, 98930, 98936, 98942, 98948, 98954, 98960, 98966, 98972, + 98978, 98984, 98990, 98996, 99002, 99008, 99014, 99020, 99026, 99032, + 99038, 99044, 99050, 99056, 99062, 99068, 99074, 99080, 99086, 99092, + 99098, 99105, 99111, 99118, 99125, 99132, 99139, 99147, 99154, 99162, + 99168, 99174, 99180, 99186, 99192, 99198, 99204, 99210, 99216, 99222, + 99228, 99234, 99240, 99246, 99252, 99258, 99264, 99270, 99276, 99282, + 99288, 99294, 99300, 99306, 99312, 99318, 99324, 99330, 99335, 99340, + 99345, 99350, 99355, 99360, 99365, 99370, 99375, 99380, 99385, 99390, + 99395, 99400, 99405, 99410, 99415, 99420, 99425, 99430, 99435, 99440, + 99445, 99450, 99455, 99460, 99465, 99470, 99475, 99480, 99485, 99490, + 99495, 99500, 99505, 99510, 99515, 99520, 99525, 99530, 99535, 99540, + 99545, 99550, 99555, 99560, 99565, 99570, 99575, 99580, 99585, 99590, + 99595, 99600, 99605, 99609, 99613, 99618, 99623, 99628, 99633, 99638, + 99643, 99648, 99653, 99658, 99663, 99668, 99672, 99676, 99680, 99684, + 99688, 99692, 99696, 99701, 99706, 0, 0, 99711, 99716, 99720, 99724, + 99728, 99732, 99736, 99740, 99744, 99748, 0, 0, 0, 0, 0, 0, 99752, 99757, + 99763, 99769, 99775, 99781, 99787, 99793, 99798, 99804, 99809, 99815, + 99820, 99825, 99831, 99837, 99842, 99847, 99852, 99857, 99863, 99868, + 99874, 99879, 99885, 99891, 99897, 99903, 99909, 99915, 99921, 99926, + 99932, 99938, 99944, 99950, 0, 0, 0, 0, 99956, 99961, 99967, 99973, + 99979, 99985, 99991, 99997, 100002, 100008, 100013, 100019, 100024, + 100029, 100035, 100041, 100046, 100051, 100056, 100061, 100067, 100072, + 100078, 100083, 100089, 100095, 100101, 100107, 100113, 100119, 100125, + 100130, 100136, 100142, 100148, 100154, 0, 0, 0, 0, 100160, 100164, + 100169, 100174, 100179, 100184, 100189, 100194, 100199, 100203, 100208, + 100213, 100218, 100223, 100227, 100232, 100237, 100242, 100247, 100252, + 100257, 100261, 100266, 100270, 100275, 100280, 100285, 100290, 100295, + 100300, 100305, 100310, 100314, 100319, 100324, 100329, 100334, 100339, + 100344, 100349, 0, 0, 0, 0, 0, 0, 0, 0, 100354, 100361, 100368, 100375, + 100382, 100389, 100396, 100403, 100410, 100417, 100424, 100431, 100438, + 100445, 100452, 100459, 100466, 100473, 100480, 100487, 100494, 100501, + 100508, 100515, 100522, 100529, 100536, 100543, 100550, 100557, 100564, + 100571, 100578, 100585, 100592, 100599, 100606, 100613, 100620, 100627, + 100634, 100641, 100648, 100655, 100662, 100669, 100676, 100683, 100690, + 100697, 100704, 100711, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100718, 100725, + 100730, 100736, 100742, 100748, 100754, 100760, 100766, 100772, 100777, + 100783, 0, 100789, 100794, 100800, 100805, 100811, 100817, 100822, + 100827, 100833, 100839, 100845, 100851, 100856, 100862, 100868, 0, + 100874, 100880, 100886, 100892, 100898, 100903, 100909, 0, 100915, + 100921, 0, 100927, 100932, 100938, 100944, 100950, 100956, 100962, + 100968, 100974, 100979, 100985, 0, 100991, 100996, 101002, 101007, + 101013, 101019, 101024, 101029, 101035, 101041, 101047, 101053, 101058, + 101064, 101070, 0, 101076, 101082, 101088, 101094, 101100, 101105, + 101111, 0, 101117, 101123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 101129, 101134, 101139, 101144, 101149, 101154, 101159, + 101164, 101169, 101174, 101179, 101184, 101189, 101194, 101199, 101204, + 101209, 101214, 101219, 101224, 101229, 101234, 101239, 101244, 101249, + 101254, 101259, 101264, 101269, 101274, 101279, 101284, 101289, 101294, + 101299, 101304, 101309, 101314, 101319, 101324, 101329, 101334, 101339, + 101344, 101349, 101354, 101359, 101364, 101369, 101374, 101379, 101384, + 101389, 101394, 101399, 101404, 101409, 101414, 101419, 101424, 101429, + 101434, 101439, 101444, 101449, 101454, 101459, 101464, 101469, 101474, + 101479, 101484, 101489, 101494, 101499, 101504, 101509, 101514, 101519, + 101524, 101529, 101534, 101539, 101544, 101549, 101554, 101559, 101564, + 101569, 101574, 101579, 101584, 101589, 101594, 101599, 101604, 101609, + 101614, 101619, 101624, 101629, 101634, 101639, 101644, 101649, 101654, + 101659, 101664, 101669, 101674, 101679, 101684, 101689, 101694, 101699, + 101704, 101709, 101714, 101719, 101724, 101729, 101734, 101739, 101744, + 101749, 101754, 101759, 101764, 101769, 101774, 101779, 101784, 101789, + 101794, 101799, 101804, 101809, 101814, 101819, 101824, 101829, 101834, + 101839, 101844, 101849, 101854, 101859, 101864, 101869, 101874, 101879, + 101884, 101889, 101894, 101899, 101904, 101909, 101914, 101919, 101924, + 101929, 101934, 101939, 101944, 101949, 101954, 101959, 101964, 101969, + 101974, 101979, 101984, 101989, 101994, 101999, 102004, 102009, 102014, + 102019, 102024, 102029, 102034, 102039, 102044, 102049, 102054, 102059, + 102064, 102069, 102074, 102079, 102084, 102089, 102094, 102099, 102104, + 102109, 102114, 102119, 102124, 102129, 102134, 102139, 102144, 102149, + 102154, 102159, 102164, 102169, 102174, 102179, 102184, 102189, 102194, + 102199, 102204, 102209, 102214, 102219, 102224, 102229, 102234, 102239, + 102244, 102249, 102254, 102259, 102264, 102269, 102274, 102279, 102284, + 102289, 102294, 102299, 102304, 102309, 102314, 102319, 102324, 102329, + 102334, 102339, 102344, 102349, 102354, 102359, 102364, 102369, 102374, + 102379, 102384, 102389, 102394, 102399, 102404, 102409, 102414, 102419, + 102424, 102429, 102434, 102439, 102444, 102449, 102454, 102459, 102464, + 102469, 102474, 102479, 102484, 102489, 102494, 102499, 102504, 102509, + 102514, 102519, 102524, 102529, 102534, 102539, 102544, 102549, 102554, + 102559, 102564, 102569, 102574, 102579, 102584, 102589, 102594, 102599, + 102604, 102609, 102614, 102619, 102624, 102629, 102634, 102639, 102644, + 102649, 102654, 102659, 102664, 102669, 102674, 102679, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 102684, 102690, 102697, 102704, 102710, 102717, 102724, 102731, + 102738, 102744, 102751, 102758, 102765, 102772, 102779, 102786, 102793, + 102800, 102807, 102814, 102821, 102828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 102835, 102840, 102845, 102850, 102855, 102860, 102865, 102870, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102875, + 102881, 102889, 102898, 102903, 102909, 0, 102915, 102922, 102933, + 102943, 102950, 102958, 102965, 102976, 102982, 102992, 102999, 103006, + 103012, 103019, 103027, 103034, 103040, 103047, 103059, 103066, 103073, + 103081, 103090, 103103, 103108, 103117, 103123, 103132, 103138, 103144, + 103151, 103156, 103166, 103180, 103188, 103196, 103201, 103211, 103218, + 103229, 103236, 103245, 0, 103253, 103259, 103267, 103277, 103283, + 103289, 103295, 103301, 103311, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 103319, 103323, 103327, 103331, 103335, 103339, 0, + 0, 103344, 0, 103349, 103353, 103358, 103363, 103368, 103373, 103377, + 103382, 103387, 103392, 103397, 103401, 103406, 103411, 103416, 103421, + 103425, 103430, 103435, 103440, 103445, 103449, 103454, 103459, 103464, + 103469, 103473, 103478, 103483, 103488, 103493, 103497, 103502, 103507, + 103512, 103517, 103522, 103527, 103532, 103536, 103541, 103546, 103551, + 103556, 0, 103561, 103566, 0, 0, 0, 103571, 0, 0, 103576, 103581, 103588, + 103595, 103602, 103609, 103616, 103623, 103630, 103637, 103644, 103651, + 103658, 103665, 103672, 103679, 103686, 103693, 103700, 103707, 103714, + 103721, 103728, 0, 103735, 103742, 103748, 103754, 103760, 103767, + 103774, 103782, 103789, 103797, 103802, 103807, 103812, 103817, 103822, + 103827, 103832, 103837, 103842, 103847, 103852, 103857, 103862, 103868, + 103873, 103878, 103883, 103888, 103893, 103898, 103903, 103908, 103913, + 103919, 103925, 103929, 103933, 103937, 103941, 103945, 103950, 103955, + 103961, 103966, 103972, 103977, 103982, 103987, 103993, 103998, 104003, + 104008, 104013, 104018, 104024, 104029, 104035, 104040, 104046, 104051, + 104057, 104062, 104068, 104073, 104078, 104083, 104088, 104093, 104098, + 104103, 104109, 104114, 0, 0, 0, 0, 0, 0, 0, 0, 104119, 104123, 104127, + 104131, 104135, 104141, 104145, 104150, 104155, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104161, 104166, 104171, + 104176, 104181, 104186, 104191, 104196, 104201, 104206, 104211, 104216, + 104221, 104226, 104231, 104236, 104241, 104246, 104251, 0, 104256, + 104261, 0, 0, 0, 0, 0, 104266, 104270, 104274, 104279, 104284, 104290, + 104295, 104300, 104305, 104310, 104315, 104320, 104325, 104330, 104335, + 104340, 104345, 104350, 104355, 104360, 104365, 104370, 104375, 104380, + 104385, 104390, 104395, 104400, 104404, 104409, 104414, 104420, 104424, + 0, 0, 0, 104428, 104434, 104438, 104443, 104448, 104453, 104457, 104462, + 104466, 104471, 104476, 104480, 104485, 104490, 104494, 104498, 104503, + 104508, 104512, 104517, 104522, 104527, 104532, 104537, 104542, 104547, + 104552, 0, 0, 0, 0, 0, 104557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 104562, 104567, 104572, 104577, 104582, 104587, 104593, 104599, + 104605, 104610, 104615, 104620, 104626, 104632, 104638, 104643, 104649, + 104654, 104660, 104666, 104671, 104677, 104683, 104688, 104694, 104700, + 104706, 104712, 104718, 104723, 104729, 104735, 104741, 104746, 104751, + 104756, 104761, 104766, 104772, 104778, 104783, 104788, 104793, 104799, + 104804, 104809, 104815, 104821, 104826, 104833, 104839, 104844, 104850, + 104856, 104862, 104867, 0, 0, 0, 0, 104873, 104882, 104890, 104897, + 104904, 104909, 104914, 104919, 104924, 104929, 104934, 104939, 104944, + 104949, 104955, 104961, 104967, 104973, 104979, 104985, 0, 0, 104991, + 104998, 105005, 105012, 105020, 105028, 105036, 105044, 105052, 105060, + 105066, 105072, 105078, 105085, 105092, 105099, 105106, 105113, 105120, + 105127, 105134, 105141, 105148, 105155, 105162, 105169, 105176, 105183, + 105191, 105199, 105207, 105216, 105225, 105234, 105243, 105252, 105261, + 105269, 105277, 105285, 105294, 105303, 105312, 105321, 105330, 105339, + 105348, 105352, 105357, 105362, 0, 105368, 105373, 0, 0, 0, 0, 0, 105378, + 105384, 105391, 105396, 105401, 105405, 105410, 105415, 0, 105420, + 105425, 105430, 0, 105435, 105440, 105445, 105450, 105455, 105460, + 105465, 105470, 105475, 105480, 105485, 105489, 105493, 105498, 105503, + 105508, 105512, 105516, 105520, 105524, 105529, 105534, 105539, 105543, + 105548, 105552, 105557, 105562, 105567, 0, 0, 105572, 105578, 105583, 0, + 0, 0, 0, 105588, 105592, 105596, 105600, 105604, 105608, 105613, 105618, + 105624, 105629, 0, 0, 0, 0, 0, 0, 0, 105636, 105642, 105649, 105655, + 105662, 105668, 105674, 105680, 105687, 0, 0, 0, 0, 0, 0, 0, 105693, + 105701, 105709, 105717, 105725, 105733, 105741, 105749, 105757, 105765, + 105773, 105781, 105789, 105797, 105805, 105813, 105821, 105829, 105837, + 105845, 105853, 105861, 105869, 105877, 105885, 105893, 105901, 105909, + 105917, 105925, 105932, 105940, 105948, 105955, 105962, 105969, 105976, + 105983, 105990, 105997, 106004, 106011, 106018, 106025, 106032, 106039, + 106046, 106053, 106060, 106067, 106074, 106081, 106088, 106095, 106102, + 106109, 106116, 106123, 106130, 106137, 106144, 106151, 106157, 106164, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 106171, 106176, 106181, 106186, 106191, 106196, + 106201, 106206, 106211, 106216, 106221, 106226, 106231, 106236, 106241, + 106246, 106251, 106256, 106261, 106266, 106271, 106276, 106281, 106286, + 106291, 106296, 106301, 106306, 106311, 106316, 106321, 106326, 106331, + 106336, 106341, 106346, 106351, 106356, 106362, 0, 0, 0, 0, 106368, + 106372, 106376, 106381, 106386, 106392, 106398, 106404, 106414, 106423, + 106429, 106436, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106444, 106448, 106453, + 106458, 106463, 106468, 106473, 106478, 106483, 106487, 106492, 106496, + 106501, 106505, 106510, 106514, 106519, 106524, 106529, 106534, 106539, + 106544, 106549, 106554, 106559, 106564, 106569, 106574, 106579, 106584, + 106589, 106594, 106599, 106604, 106609, 106614, 106619, 106624, 106629, + 106634, 106639, 106644, 106649, 106654, 106659, 106664, 106669, 106674, + 106679, 106684, 106689, 106694, 106699, 106704, 0, 0, 0, 106709, 106714, + 106723, 106731, 106740, 106749, 106760, 106771, 106778, 106785, 106792, + 106799, 106806, 106813, 106820, 106827, 106834, 106841, 106848, 106855, + 106862, 106869, 106876, 106883, 106890, 106897, 106904, 106911, 106918, + 0, 0, 106925, 106931, 106937, 106943, 106949, 106956, 106963, 106971, + 106978, 106985, 106992, 106999, 107006, 107013, 107020, 107027, 107034, + 107041, 107048, 107055, 107062, 107069, 107076, 107083, 107090, 107097, + 107104, 0, 0, 0, 0, 0, 107111, 107117, 107123, 107129, 107135, 107142, + 107149, 107157, 107164, 107171, 107178, 107185, 107192, 107199, 107206, + 107213, 107220, 107227, 107234, 107241, 107248, 107255, 107262, 107269, + 107276, 107283, 0, 0, 0, 0, 0, 0, 0, 107290, 107297, 107305, 107315, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107325, 107331, 107337, 107343, 107349, + 107356, 107363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107371, 107378, 107385, 107393, + 107400, 107407, 107414, 107421, 107429, 107437, 107445, 107453, 107461, + 107469, 107477, 107485, 107493, 107501, 107509, 107517, 107525, 107533, + 107541, 107549, 107557, 107565, 107573, 107581, 107589, 107597, 107605, + 107613, 107621, 107629, 107637, 107645, 107653, 107661, 107669, 107677, + 107685, 107693, 107701, 107709, 107717, 107725, 107733, 107741, 107749, + 107757, 107765, 107773, 107781, 107789, 107797, 107805, 107813, 107821, + 107829, 107837, 107845, 107853, 107861, 107869, 107877, 107885, 107893, + 107901, 107909, 107917, 107925, 107933, 107941, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107949, 107954, 107960, 107966, 107972, 107978, 107984, 107990, 107996, + 108002, 108007, 108014, 108020, 108026, 108032, 108038, 108044, 108049, + 108055, 108061, 108067, 108073, 108079, 108085, 108091, 108097, 108103, + 108109, 108114, 108120, 108128, 108136, 108142, 108148, 108154, 108160, + 108168, 108174, 108180, 108186, 108192, 108198, 108204, 108209, 108215, + 108223, 108231, 108237, 108243, 108249, 108256, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 108262, 108267, 108273, 108279, 108285, 108291, 108297, + 108303, 108309, 108315, 108320, 108327, 108333, 108339, 108345, 108351, + 108357, 108362, 108368, 108374, 108380, 108386, 108392, 108398, 108404, + 108410, 108416, 108422, 108427, 108433, 108441, 108449, 108455, 108461, + 108467, 108473, 108481, 108487, 108493, 108499, 108505, 108511, 108517, + 108522, 108528, 108536, 108544, 108550, 108556, 108562, 108569, 0, 0, 0, + 0, 0, 0, 0, 108575, 108579, 108583, 108588, 108593, 108599, 108604, + 108610, 108617, 108623, 108630, 108637, 108644, 108651, 108657, 108664, + 108671, 108678, 108685, 108691, 108698, 108705, 108711, 108718, 108724, + 108731, 108737, 108743, 108749, 108756, 108765, 108771, 108779, 108786, + 108793, 108800, 108806, 108812, 108818, 108824, 108830, 108837, 108846, + 108853, 108860, 108867, 0, 0, 0, 0, 0, 0, 0, 0, 108874, 108881, 108887, + 108893, 108899, 108905, 108911, 108917, 108923, 108929, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108935, 108939, 108943, + 108947, 108951, 108955, 108959, 108963, 108967, 108971, 108976, 108981, + 108986, 108991, 108996, 109001, 109006, 109011, 109016, 109022, 109028, + 109034, 109041, 109048, 109055, 109062, 109069, 109076, 109083, 109090, + 109097, 0, 109104, 109109, 109114, 109119, 109124, 109129, 109134, + 109139, 109144, 109149, 109154, 109159, 109164, 109169, 109173, 109178, + 109183, 109188, 109193, 109198, 109203, 109208, 109213, 109218, 109223, + 109228, 109233, 109238, 109246, 109251, 109256, 109261, 109266, 109271, + 109276, 109281, 109286, 109291, 109296, 109301, 109306, 109311, 0, + 109316, 109322, 109328, 0, 0, 109333, 109341, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109350, 109357, + 109364, 109371, 109377, 109384, 109390, 109397, 109403, 109409, 109416, + 109422, 109428, 109434, 109440, 109446, 109452, 109458, 109464, 109471, + 109482, 109488, 109494, 109502, 109508, 109514, 109521, 109532, 109538, + 109544, 109550, 109557, 109568, 109573, 109578, 109583, 109588, 109593, + 109599, 109605, 109611, 109618, 109626, 0, 0, 0, 0, 0, 0, 0, 0, 109632, + 109637, 109642, 109647, 109652, 109657, 109662, 109667, 109672, 109677, + 109682, 109687, 109692, 109697, 109702, 109707, 109712, 109717, 109722, + 109727, 109732, 109737, 109743, 109748, 109754, 109759, 109765, 109771, + 109777, 109783, 109789, 109796, 109802, 109808, 109812, 109817, 109822, + 109828, 109836, 109847, 109856, 109866, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109876, 109882, 109888, 109894, 109900, + 109906, 109913, 109919, 109925, 109931, 109937, 109943, 109949, 109955, + 109961, 109967, 109973, 109979, 109985, 109991, 109997, 110004, 110011, + 110017, 110025, 110033, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110042, + 110047, 110053, 110058, 110063, 110068, 110073, 110078, 110085, 110090, + 110095, 110100, 110105, 110110, 110115, 110120, 110125, 110130, 110135, + 110140, 110145, 110150, 110154, 110158, 110162, 110166, 110171, 110176, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110182, + 110187, 110192, 110197, 110202, 110207, 110212, 110217, 110222, 110227, + 110232, 110237, 110242, 110247, 110252, 110257, 110262, 110267, 110272, + 110277, 110282, 110287, 110292, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110297, + 110301, 110305, 110309, 110313, 110317, 110320, 110324, 110327, 110331, + 110334, 110338, 110342, 110347, 110351, 110356, 110359, 110363, 110366, + 110370, 110373, 110377, 110381, 110385, 110389, 110393, 110397, 110401, + 110405, 110409, 110413, 110417, 110421, 110425, 110429, 110433, 110437, + 110441, 110445, 110448, 110451, 110455, 110459, 110463, 110466, 110469, + 110472, 110475, 110479, 110483, 110487, 110490, 110493, 110497, 110503, + 110509, 110515, 110520, 110527, 110531, 110536, 110540, 110545, 110550, + 110556, 110561, 110567, 110571, 110576, 110580, 110585, 110588, 110591, + 110595, 110600, 110606, 110611, 110617, 0, 0, 0, 0, 110622, 110625, + 110628, 110631, 110634, 110637, 110640, 110643, 110646, 110649, 110653, + 110657, 110661, 110665, 110669, 110673, 110677, 110681, 110685, 110690, + 110694, 110698, 110701, 110704, 110707, 110710, 110713, 110716, 110719, + 110722, 110725, 110731, 110738, 110745, 110753, 110761, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 110767, 110771, 110776, 110781, 110786, 110790, 110795, 110799, + 110804, 110808, 110813, 110817, 110822, 110826, 110831, 110835, 110840, + 110845, 110850, 110855, 110860, 110865, 110870, 110875, 110880, 110885, + 110890, 110895, 110900, 110905, 110910, 110915, 110920, 110925, 110930, + 110935, 110939, 110943, 110948, 110953, 110958, 110962, 110966, 110970, + 110974, 110979, 110984, 110989, 110993, 110997, 111003, 111008, 111014, + 111019, 111025, 111030, 111036, 111041, 111047, 111052, 111057, 111062, + 111067, 111071, 111076, 111082, 111086, 111091, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 111097, 0, 0, 111102, 111109, 111116, 111123, 111130, 111137, + 111144, 111151, 111158, 111165, 111172, 111179, 111186, 111193, 111200, + 111207, 111214, 111221, 111228, 111235, 111242, 111249, 111256, 111263, + 111270, 0, 0, 0, 0, 0, 0, 0, 111277, 111284, 111290, 111296, 111302, + 111308, 111314, 111320, 111326, 111332, 0, 0, 0, 0, 0, 0, 111338, 111343, + 111348, 111353, 111358, 111362, 111366, 111370, 111375, 111380, 111385, + 111390, 111395, 111400, 111405, 111410, 111415, 111420, 111425, 111430, + 111435, 111440, 111445, 111450, 111455, 111460, 111465, 111470, 111475, + 111480, 111485, 111490, 111495, 111500, 111505, 111510, 111515, 111520, + 111525, 111530, 111535, 111540, 111546, 111551, 111557, 111562, 111568, + 111573, 111579, 111585, 111589, 111594, 111598, 0, 111602, 111607, + 111611, 111615, 111619, 111623, 111627, 111631, 111635, 111639, 111643, + 111648, 111652, 111657, 111662, 111667, 111673, 111679, 0, 0, 0, 0, 0, 0, + 0, 0, 111684, 111688, 111692, 111696, 111700, 111704, 111708, 111713, + 111718, 111723, 111728, 111733, 111738, 111743, 111748, 111753, 111758, + 111763, 111768, 111773, 111778, 111783, 111788, 111793, 111797, 111801, + 111806, 111811, 111816, 111820, 111824, 111828, 111833, 111837, 111841, + 111846, 111851, 111856, 111861, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111866, + 111871, 111876, 111881, 111885, 111890, 111894, 111899, 111903, 111908, + 111913, 111919, 111924, 111930, 111934, 111939, 111943, 111948, 111952, + 111957, 111962, 111967, 111972, 111977, 111982, 111987, 111992, 111997, + 112002, 112007, 112012, 112017, 112022, 112027, 112032, 112037, 112042, + 112046, 112050, 112055, 112060, 112065, 112069, 112073, 112077, 112081, + 112086, 112091, 112096, 112101, 112105, 112109, 112115, 112120, 112126, + 112131, 112137, 112143, 112150, 112156, 112163, 112168, 112174, 112179, + 112185, 112190, 112195, 112200, 112205, 112209, 112213, 112218, 112223, + 112227, 112232, 112237, 112242, 112250, 112255, 112262, 112269, 112274, + 112278, 112282, 112286, 112290, 112294, 112298, 112302, 112306, 112310, + 112314, 112319, 112323, 112328, 112334, 0, 112340, 112345, 112350, + 112355, 112360, 112365, 112370, 112375, 112380, 112385, 112391, 112397, + 112403, 112409, 112415, 112421, 112427, 112433, 112439, 112446, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 112452, 112456, 112461, 112465, 112469, 112473, + 112478, 112482, 112487, 112491, 112496, 112501, 112506, 112511, 112516, + 112521, 112526, 112531, 0, 112536, 112541, 112546, 112551, 112556, + 112561, 112566, 112571, 112576, 112581, 112586, 112591, 112595, 112599, + 112604, 112609, 112614, 112619, 112623, 112627, 112631, 112635, 112640, + 112644, 112648, 112653, 112659, 112664, 112670, 112675, 112680, 112686, + 112691, 112697, 112702, 112707, 112712, 112717, 112721, 112726, 112732, + 112737, 112743, 112748, 112753, 112758, 112764, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 112770, 112774, 112778, 112782, 112786, 112790, 112795, + 0, 112800, 0, 112805, 112810, 112815, 112820, 0, 112825, 112830, 112835, + 112840, 112845, 112850, 112855, 112860, 112865, 112870, 112875, 112880, + 112884, 112888, 112893, 0, 112898, 112903, 112907, 112911, 112915, + 112919, 112924, 112928, 112932, 112937, 112942, 0, 0, 0, 0, 0, 0, 112947, + 112951, 112956, 112960, 112965, 112969, 112974, 112978, 112983, 112987, + 112992, 112996, 113001, 113006, 113011, 113016, 113021, 113026, 113031, + 113036, 113041, 113046, 113051, 113056, 113061, 113066, 113071, 113076, + 113081, 113086, 113091, 113096, 113101, 113106, 113110, 113114, 113119, + 113124, 113129, 113134, 113138, 113142, 113146, 113150, 113155, 113160, + 113164, 113168, 113173, 113179, 113184, 113190, 113195, 113201, 113206, + 113212, 113217, 113223, 113228, 0, 0, 0, 0, 0, 113233, 113238, 113242, + 113246, 113250, 113254, 113258, 113262, 113266, 113270, 0, 0, 0, 0, 0, 0, + 113274, 113281, 113286, 113291, 0, 113296, 113300, 113305, 113309, + 113314, 113318, 113323, 113328, 0, 0, 113333, 113338, 0, 0, 113343, + 113348, 113353, 113357, 113362, 113367, 113372, 113377, 113382, 113387, + 113392, 113397, 113402, 113407, 113412, 113417, 113422, 113427, 113432, + 113437, 113442, 113447, 0, 113451, 113455, 113460, 113465, 113470, + 113474, 113478, 0, 113482, 113486, 0, 113491, 113496, 113501, 113506, + 113510, 0, 113514, 113518, 113523, 113528, 113534, 113539, 113545, + 113550, 113556, 113562, 0, 0, 113569, 113575, 0, 0, 113581, 113587, + 113593, 0, 0, 113598, 0, 0, 0, 0, 0, 0, 113602, 0, 0, 0, 0, 0, 113609, + 113614, 113621, 113629, 113635, 113641, 113647, 0, 0, 113654, 113660, + 113665, 113670, 113675, 113680, 113685, 0, 0, 0, 113690, 113695, 113700, + 113705, 113711, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113716, 113720, 113725, + 113729, 113734, 113738, 113743, 113748, 113754, 113759, 113765, 113769, + 113774, 113778, 113783, 113787, 113792, 113797, 113802, 113807, 113812, + 113817, 113822, 113827, 113832, 113837, 113842, 113847, 113852, 113857, + 113862, 113867, 113872, 113877, 113882, 113887, 113891, 113896, 113900, + 113905, 113910, 113915, 113919, 113924, 113928, 113932, 113937, 113941, + 113946, 113951, 113956, 113961, 113965, 113969, 113975, 113980, 113986, + 113991, 113997, 114003, 114010, 114016, 114023, 114028, 114034, 114039, + 114045, 114050, 114055, 114060, 114065, 114070, 114075, 114081, 114085, + 114089, 114093, 114098, 114102, 114108, 114113, 114118, 114122, 114126, + 114130, 114134, 114138, 114142, 114146, 114150, 114154, 114159, 0, + 114164, 114169, 114174, 114181, 114186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114191, 114195, + 114199, 114204, 114208, 114213, 114217, 114222, 114227, 114233, 114238, + 114244, 114248, 114253, 114257, 114262, 114266, 114271, 114276, 114281, + 114286, 114291, 114296, 114301, 114306, 114311, 114316, 114321, 114326, + 114331, 114336, 114341, 114346, 114351, 114356, 114360, 114364, 114369, + 114374, 114379, 114383, 114387, 114391, 114395, 114400, 114405, 114410, + 114414, 114418, 114424, 114429, 114435, 114440, 114446, 114452, 114459, + 114465, 114472, 114477, 114484, 114490, 114495, 114502, 114508, 114513, + 114518, 114523, 114528, 114533, 114538, 114542, 114547, 0, 0, 0, 0, 0, 0, + 0, 0, 114551, 114556, 114560, 114564, 114568, 114572, 114576, 114580, + 114584, 114588, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114592, 114596, + 114601, 114605, 114610, 114614, 114619, 114624, 114630, 114635, 114641, + 114645, 114650, 114654, 114659, 114663, 114668, 114673, 114678, 114683, + 114688, 114693, 114698, 114703, 114708, 114713, 114718, 114723, 114728, + 114733, 114738, 114743, 114748, 114753, 114757, 114761, 114766, 114771, + 114776, 114780, 114784, 114788, 114792, 114797, 114802, 114807, 114811, + 114815, 114821, 114826, 114832, 114837, 114843, 114849, 0, 0, 114856, + 114861, 114867, 114872, 114878, 114883, 114888, 114893, 114898, 114903, + 114908, 114912, 114917, 114923, 114928, 114934, 114940, 114946, 114954, + 114967, 114980, 114993, 115007, 115022, 115030, 115041, 115050, 115060, + 115070, 115080, 115091, 115103, 115116, 115124, 115132, 115141, 115147, + 115154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115162, 115166, 115171, 115175, + 115180, 115184, 115189, 115194, 115200, 115205, 115211, 115215, 115220, + 115224, 115229, 115233, 115238, 115243, 115248, 115253, 115258, 115263, + 115268, 115273, 115278, 115283, 115288, 115293, 115298, 115303, 115308, + 115313, 115318, 115323, 115327, 115331, 115336, 115341, 115346, 115350, + 115354, 115358, 115362, 115367, 115372, 115377, 115381, 115385, 115390, + 115396, 115401, 115407, 115412, 115418, 115424, 115431, 115437, 115444, + 115449, 115455, 115460, 115466, 115471, 115476, 115481, 115486, 115490, + 115495, 115500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115505, 115510, 115514, + 115518, 115522, 115526, 115530, 115534, 115538, 115542, 0, 0, 0, 0, 0, 0, + 115546, 115552, 115557, 115564, 115572, 115579, 115587, 115596, 115601, + 115610, 115615, 115623, 115632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 115642, 115646, 115651, 115655, 115660, 115664, 115669, + 115673, 115678, 115682, 115687, 115691, 115696, 115701, 115706, 115711, + 115716, 115721, 115726, 115731, 115736, 115741, 115746, 115751, 115756, + 115761, 115766, 115771, 115776, 115781, 115785, 115789, 115794, 115799, + 115804, 115808, 115812, 115816, 115820, 115825, 115830, 115834, 115838, + 115843, 115848, 115853, 115859, 115864, 115870, 115875, 115881, 115886, + 115892, 115897, 115903, 115908, 115913, 115920, 0, 0, 0, 0, 0, 0, 115925, + 115930, 115934, 115938, 115942, 115946, 115950, 115954, 115958, 115962, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 115966, 115970, 115975, 115980, 115984, 115989, 115996, + 116000, 116005, 116010, 116014, 116019, 116024, 116029, 116033, 116037, + 116041, 116046, 116050, 116054, 116059, 116064, 116069, 116076, 116081, + 116086, 116091, 0, 0, 116098, 116105, 116112, 116121, 116126, 116132, + 116137, 116143, 116148, 116154, 116159, 116165, 116170, 116176, 116182, + 0, 0, 0, 0, 116187, 116192, 116196, 116200, 116204, 116208, 116212, + 116216, 116220, 116224, 116228, 116233, 116238, 116244, 116249, 116254, + 116259, 116264, 116269, 116274, 116279, 116284, 116289, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 116294, 116298, 116303, 116307, 116312, 116316, 116321, 116325, + 116330, 116334, 116339, 116343, 116348, 116353, 116358, 116363, 116368, + 116373, 116378, 116383, 116388, 116393, 116398, 116403, 116408, 116413, + 116418, 116423, 116428, 116433, 116437, 116441, 116446, 116451, 116456, + 116460, 116464, 116468, 116472, 116477, 116482, 116487, 116491, 116495, + 116500, 116506, 116511, 116517, 116522, 116528, 116534, 116541, 116546, + 116552, 116557, 116563, 116568, 116573, 116578, 116583, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116588, + 116596, 116603, 116611, 116619, 116626, 116634, 116642, 116650, 116657, + 116664, 116672, 116680, 116688, 116696, 116704, 116712, 116720, 116728, + 116736, 116744, 116752, 116760, 116768, 116776, 116784, 116792, 116800, + 116808, 116816, 116824, 116832, 116840, 116848, 116855, 116863, 116871, + 116878, 116886, 116894, 116902, 116909, 116916, 116924, 116932, 116940, + 116948, 116956, 116964, 116972, 116980, 116988, 116996, 117004, 117012, + 117020, 117028, 117036, 117044, 117052, 117060, 117068, 117076, 117084, + 117092, 117099, 117105, 117111, 117117, 117123, 117129, 117135, 117141, + 117147, 117153, 117160, 117167, 117174, 117181, 117188, 117195, 117202, + 117209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117216, 117222, 117228, + 117235, 117241, 117248, 117254, 117261, 0, 0, 117267, 0, 0, 117273, + 117279, 117286, 117293, 117300, 117307, 117314, 117321, 0, 117328, + 117335, 0, 117342, 117349, 117356, 117363, 117370, 117377, 117384, + 117391, 117397, 117403, 117410, 117417, 117424, 117430, 117436, 117443, + 117449, 117455, 117462, 117469, 117476, 117482, 117488, 117495, 117502, + 117510, 117517, 117525, 117532, 117540, 0, 117547, 117555, 0, 0, 117562, + 117569, 117576, 117583, 117589, 117598, 117605, 117611, 117618, 117625, + 117632, 117640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117650, 117657, 117663, + 117669, 117675, 117681, 117687, 117693, 117699, 117705, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117711, 117715, 117720, + 117724, 117729, 117733, 117738, 117743, 0, 0, 117749, 117753, 117758, + 117762, 117767, 117771, 117776, 117781, 117786, 117791, 117796, 117801, + 117806, 117811, 117816, 117821, 117826, 117831, 117836, 117841, 117846, + 117851, 117856, 117861, 117865, 117869, 117874, 117879, 117884, 117888, + 117892, 117896, 117900, 117905, 117910, 117915, 117919, 117923, 117928, + 117933, 117939, 117944, 117950, 117955, 117961, 117967, 0, 0, 117974, + 117979, 117985, 117990, 117996, 118001, 118006, 118011, 118016, 118021, + 118025, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 118032, 118037, 118043, 118050, 118056, 118062, 118069, + 118075, 118082, 118089, 118097, 118104, 118109, 118115, 118121, 118127, + 118133, 118139, 118145, 118151, 118157, 118163, 118169, 118175, 118181, + 118187, 118193, 118199, 118205, 118211, 118216, 118221, 118227, 118233, + 118239, 118244, 118250, 118256, 118262, 118268, 118274, 118280, 118286, + 118291, 118296, 118301, 118307, 118313, 118319, 118324, 118329, 118335, + 118341, 118347, 118353, 118362, 118371, 118377, 118383, 118390, 118397, + 118404, 118411, 118419, 118426, 118434, 118440, 118446, 118453, 118460, + 118469, 118479, 0, 0, 0, 0, 0, 0, 0, 0, 118484, 118488, 118493, 118499, + 118504, 118509, 118514, 118520, 118526, 118532, 118538, 118544, 118550, + 118554, 118559, 118564, 118569, 118574, 118579, 118584, 118589, 118594, + 118599, 118604, 118609, 118614, 118619, 118624, 118629, 118634, 118639, + 118644, 118648, 118652, 118657, 118662, 118667, 118671, 118676, 118681, + 118686, 118691, 118696, 118701, 118705, 118709, 118713, 118718, 118723, + 118728, 118732, 118736, 118741, 118746, 118751, 118757, 118763, 118770, + 118776, 118783, 118790, 118797, 118804, 118811, 118818, 118825, 118831, + 118837, 118844, 118851, 118858, 118863, 118868, 118873, 118877, 118882, + 118887, 118893, 118898, 118914, 118928, 118939, 118945, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 118951, 118957, 118963, 118969, 118975, 118980, + 118986, 118992, 118998, 119004, 119010, 119016, 119022, 119026, 119030, + 119034, 119038, 119046, 119054, 119062, 119070, 119079, 119088, 119097, + 119106, 119114, 119123, 119132, 119140, 119149, 119158, 119167, 119176, + 119184, 119193, 119201, 119210, 119219, 119227, 119235, 119243, 119251, + 119259, 119268, 119277, 119287, 119297, 119307, 119317, 119327, 119336, + 119346, 119356, 119366, 119377, 119387, 119399, 119411, 119422, 119436, + 119447, 119457, 119469, 119480, 119490, 119502, 119514, 119525, 119536, + 119546, 119556, 119568, 119579, 0, 0, 0, 0, 0, 0, 0, 119591, 119595, + 119602, 119606, 119612, 119618, 119626, 119634, 119642, 119650, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119654, 119658, + 119663, 119667, 119672, 119676, 119681, 119686, 119692, 0, 119697, + 119701, 119706, 119710, 119715, 119719, 119724, 119729, 119734, 119739, + 119744, 119749, 119754, 119759, 119764, 119769, 119774, 119779, 119784, + 119789, 119794, 119799, 119804, 119809, 119813, 119817, 119822, 119827, + 119832, 119836, 119840, 119844, 119848, 119853, 119858, 119863, 119867, + 119871, 119877, 119882, 119888, 119893, 119899, 119905, 119912, 0, + 119918, 119923, 119929, 119934, 119940, 119945, 119950, 119955, 119960, + 119965, 119969, 119974, 119980, 119986, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 119992, 119997, 120001, 120005, 120009, 120013, 120017, 120021, 120025, + 120029, 120033, 120037, 120041, 120045, 120049, 120053, 120057, 120061, + 120065, 120069, 120074, 120079, 120084, 120089, 120094, 120099, 120104, + 120109, 120114, 0, 0, 0, 120121, 120126, 120131, 120135, 120140, 120145, + 120150, 120155, 120160, 120165, 120170, 120175, 120180, 120185, 120189, + 120193, 120198, 120203, 120207, 120212, 120217, 120222, 120227, 120232, + 120237, 120242, 120246, 120250, 120254, 120259, 120263, 120267, 0, 0, + 120271, 120277, 120284, 120291, 120298, 120305, 120312, 120319, 120326, + 120333, 120340, 120347, 120353, 120359, 120366, 120373, 120379, 120386, + 120393, 120400, 120407, 120414, 0, 120421, 120427, 120433, 120439, + 120446, 120452, 120458, 120464, 120470, 120475, 120480, 120485, 120490, + 120495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 120500, 120505, 120511, 120516, 120522, 120527, 120533, 0, + 120538, 120544, 0, 120549, 120555, 120560, 120566, 120572, 120578, + 120584, 120590, 120596, 120602, 120608, 120614, 120620, 120626, 120632, + 120638, 120644, 120650, 120656, 120662, 120668, 120673, 120678, 120684, + 120690, 120696, 120701, 120706, 120711, 120716, 120722, 120728, 120734, + 120739, 120744, 120750, 120756, 120762, 120768, 120775, 120781, 120788, + 120794, 120801, 0, 0, 0, 120808, 0, 120814, 120821, 0, 120827, 120834, + 120840, 120846, 120852, 120858, 120864, 120869, 120874, 0, 0, 0, 0, 0, 0, + 0, 0, 120879, 120885, 120890, 120895, 120900, 120905, 120910, 120915, + 120920, 120925, 0, 0, 0, 0, 0, 0, 120930, 120935, 120941, 120946, 120952, + 120957, 0, 120963, 120969, 0, 120975, 120981, 120987, 120992, 120998, + 121004, 121010, 121015, 121020, 121026, 121032, 121038, 121043, 121049, + 121055, 121061, 121067, 121072, 121078, 121084, 121090, 121096, 121102, + 121108, 121114, 121120, 121126, 121132, 121137, 121143, 121148, 121153, + 121158, 121165, 121171, 121178, 121184, 0, 121191, 121198, 0, 121205, + 121212, 121219, 121225, 121231, 121236, 0, 0, 0, 0, 0, 0, 0, 121241, + 121247, 121252, 121257, 121262, 121267, 121272, 121277, 121282, 121287, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121292, 121296, 121301, 121306, + 121310, 121315, 121319, 121324, 121329, 121333, 121338, 121343, 121348, + 121352, 121356, 121360, 121365, 121369, 121373, 121377, 121382, 121387, + 121392, 121397, 121401, 0, 0, 0, 0, 0, 0, 0, 121408, 121413, 121418, + 121423, 121428, 121432, 121437, 121441, 121446, 121450, 121455, 121460, + 121466, 121471, 121477, 121481, 121486, 0, 121490, 121494, 121499, + 121504, 121509, 121514, 121519, 121524, 121529, 121534, 121539, 121544, + 121549, 121554, 121559, 121564, 121569, 121574, 121579, 121584, 121588, + 121592, 121597, 121602, 121607, 121611, 121615, 121619, 121623, 121628, + 121633, 121638, 121642, 121646, 121651, 121657, 121665, 121670, 121676, + 121681, 121687, 0, 0, 0, 121693, 121698, 121704, 121710, 121715, 121719, + 121723, 121728, 121736, 121746, 121752, 121760, 121766, 121773, 121781, + 121787, 121795, 121801, 121809, 121814, 121818, 121822, 121826, 121830, + 121834, 121838, 121842, 121846, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 121850, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121855, 121861, + 121867, 121873, 121879, 121885, 121891, 121897, 121903, 121909, 121915, + 121921, 121927, 121933, 121939, 121945, 121951, 121957, 121963, 121969, + 121975, 121984, 121988, 121992, 121996, 122000, 122004, 122008, 122012, + 122016, 122020, 122024, 122028, 122032, 122036, 122040, 122044, 122050, + 122056, 122060, 122066, 122072, 122077, 122081, 122086, 122090, 122094, + 122100, 122106, 122110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122114, + 122122, 122125, 122130, 122136, 122144, 122149, 122155, 122163, 122169, + 122175, 122179, 122183, 122190, 122199, 122206, 122215, 122221, 122230, + 122237, 122244, 122251, 122261, 122267, 122271, 122278, 122287, 122297, + 122304, 122311, 122315, 122319, 122326, 122336, 122340, 122347, 122354, + 122361, 122367, 122374, 122381, 122388, 122395, 122399, 122403, 122407, + 122414, 122418, 122425, 122432, 122446, 122455, 122459, 122463, 122467, + 122474, 122478, 122482, 122486, 122494, 122502, 122521, 122531, 122551, + 122555, 122559, 122563, 122567, 122571, 122575, 122579, 122586, 122590, + 122593, 122597, 122601, 122607, 122614, 122623, 122627, 122636, 122645, + 122653, 122657, 122664, 122668, 122672, 122676, 122680, 122691, 122700, + 122709, 122718, 122727, 122739, 122748, 122757, 122766, 122774, 122783, + 122795, 122804, 122812, 122821, 122833, 122842, 122851, 122863, 122872, + 122881, 122893, 122902, 122906, 122910, 122914, 122918, 122922, 122926, + 122930, 122937, 122941, 122945, 122956, 122960, 122964, 122971, 122977, + 122983, 122987, 122994, 122998, 123002, 123006, 123010, 123014, 123018, + 123024, 123032, 123036, 123040, 123043, 123050, 123062, 123066, 123078, + 123085, 123092, 123099, 123106, 123112, 123116, 123120, 123124, 123128, + 123135, 123144, 123151, 123159, 123167, 123173, 123177, 123181, 123185, + 123189, 123195, 123204, 123216, 123223, 123230, 123239, 123250, 123256, + 123265, 123274, 123281, 123290, 123297, 123303, 123313, 123320, 123327, + 123334, 123341, 123345, 123351, 123355, 123366, 123374, 123383, 123395, + 123402, 123409, 123419, 123426, 123435, 123442, 123451, 123458, 123465, + 123475, 123482, 123489, 123498, 123505, 123517, 123526, 123533, 123540, + 123547, 123556, 123566, 123579, 123586, 123595, 123605, 123612, 123621, + 123634, 123641, 123648, 123655, 123665, 123675, 123681, 123691, 123698, + 123705, 123715, 123721, 123728, 123735, 123742, 123752, 123759, 123766, + 123773, 123779, 123786, 123796, 123803, 123807, 123815, 123819, 123831, + 123835, 123849, 123853, 123857, 123861, 123865, 123871, 123878, 123886, + 123890, 123894, 123898, 123902, 123909, 123913, 123919, 123925, 123933, + 123937, 123944, 123952, 123956, 123960, 123966, 123970, 123979, 123988, + 123995, 124005, 124011, 124015, 124019, 124027, 124034, 124041, 124047, + 124051, 124059, 124063, 124070, 124082, 124089, 124099, 124105, 124109, + 124118, 124125, 124134, 124138, 124142, 124149, 124153, 124157, 124161, + 124165, 124168, 124174, 124180, 124184, 124188, 124195, 124202, 124209, + 124216, 124223, 124230, 124237, 124244, 124250, 124254, 124258, 124265, + 124272, 124279, 124286, 124293, 124297, 124300, 124305, 124309, 124313, + 124322, 124331, 124335, 124339, 124345, 124351, 124368, 124374, 124378, + 124387, 124391, 124395, 124402, 124410, 124418, 124424, 124428, 124432, + 124436, 124440, 124443, 124449, 124456, 124466, 124473, 124480, 124487, + 124493, 124500, 124507, 124514, 124521, 124528, 124537, 124544, 124556, + 124563, 124570, 124580, 124591, 124598, 124605, 124612, 124619, 124626, + 124633, 124640, 124647, 124654, 124661, 124671, 124681, 124691, 124698, + 124708, 124715, 124722, 124729, 124736, 124742, 124749, 124756, 124763, + 124770, 124777, 124784, 124791, 124798, 124804, 124811, 124818, 124827, + 124834, 124841, 124845, 124853, 124857, 124861, 124865, 124869, 124873, + 124880, 124884, 124893, 124897, 124904, 124912, 124916, 124920, 124924, + 124937, 124953, 124957, 124961, 124968, 124974, 124981, 124985, 124989, + 124993, 124997, 125001, 125008, 125012, 125030, 125034, 125038, 125045, + 125049, 125053, 125059, 125063, 125067, 125075, 125079, 125083, 125086, + 125090, 125096, 125107, 125116, 125125, 125132, 125139, 125150, 125157, + 125164, 125171, 125178, 125185, 125192, 125199, 125209, 125215, 125222, + 125232, 125241, 125248, 125257, 125267, 125274, 125281, 125288, 125295, + 125307, 125314, 125321, 125328, 125335, 125342, 125352, 125359, 125366, + 125376, 125389, 125401, 125408, 125418, 125425, 125432, 125439, 125453, + 125459, 125467, 125477, 125487, 125494, 125501, 125507, 125511, 125518, + 125528, 125534, 125547, 125551, 125555, 125562, 125566, 125573, 125583, + 125587, 125591, 125595, 125599, 125603, 125610, 125614, 125621, 125628, + 125635, 125644, 125653, 125663, 125670, 125677, 125684, 125694, 125701, + 125711, 125718, 125728, 125735, 125742, 125752, 125762, 125769, 125775, + 125783, 125791, 125797, 125803, 125807, 125811, 125818, 125826, 125832, + 125836, 125840, 125844, 125851, 125863, 125866, 125873, 125879, 125883, + 125887, 125891, 125895, 125899, 125903, 125907, 125911, 125915, 125919, + 125926, 125930, 125936, 125940, 125944, 125948, 125954, 125961, 125968, + 125975, 125986, 125994, 125998, 126004, 126013, 126020, 126026, 126029, + 126033, 126037, 126043, 126052, 126060, 126064, 126070, 126074, 126078, + 126082, 126088, 126095, 126101, 126105, 126111, 126115, 126119, 126128, + 126140, 126144, 126151, 126158, 126168, 126175, 126187, 126194, 126201, + 126208, 126219, 126229, 126242, 126252, 126259, 126263, 126267, 126271, + 126275, 126284, 126293, 126302, 126319, 126328, 126334, 126341, 126349, + 126362, 126366, 126375, 126384, 126393, 126402, 126413, 126422, 126430, + 126439, 126448, 126457, 126466, 126476, 126479, 126483, 126487, 126491, + 126495, 126499, 126505, 126512, 126519, 126526, 126532, 126538, 126545, + 126551, 126558, 126566, 126570, 126577, 126584, 126591, 126599, 126602, + 126606, 126610, 126614, 126617, 126623, 126627, 126633, 126640, 126647, + 126653, 126660, 126667, 126674, 126681, 126688, 126695, 126702, 126709, + 126716, 126723, 126730, 126737, 126744, 126751, 126757, 126761, 126770, + 126774, 126778, 126782, 126786, 126792, 126799, 126806, 126813, 126820, + 126827, 126833, 126841, 126845, 126849, 126853, 126857, 126863, 126880, + 126897, 126901, 126905, 126909, 126913, 126917, 126921, 126927, 126934, + 126938, 126944, 126951, 126958, 126965, 126972, 126979, 126988, 126995, + 127002, 127009, 127016, 127020, 127024, 127030, 127042, 127046, 127050, + 127059, 127063, 127067, 127071, 127077, 127081, 127085, 127094, 127098, + 127102, 127106, 127113, 127117, 127121, 127125, 127129, 127133, 127137, + 127141, 127145, 127151, 127158, 127165, 127171, 127175, 127192, 127198, + 127202, 127209, 127216, 127223, 127230, 127237, 127244, 127248, 127252, + 127256, 127262, 127266, 127272, 127276, 127280, 127287, 127294, 127311, + 127315, 127319, 127323, 127327, 127331, 127343, 127346, 127351, 127356, + 127371, 127381, 127393, 127397, 127401, 127405, 127411, 127418, 127425, + 127435, 127447, 127453, 127459, 127468, 127472, 127476, 127483, 127493, + 127500, 127506, 127510, 127514, 127521, 127527, 127531, 127537, 127541, + 127549, 127555, 127559, 127567, 127575, 127582, 127588, 127595, 127602, + 127612, 127622, 127626, 127630, 127634, 127638, 127644, 127651, 127657, + 127664, 127671, 127678, 127687, 127694, 127701, 127707, 127714, 127721, + 127728, 127735, 127742, 127749, 127755, 127762, 127769, 127776, 127785, + 127792, 127799, 127803, 127809, 127813, 127819, 127826, 127833, 127840, + 127844, 127848, 127852, 127856, 127860, 127867, 127871, 127875, 127881, + 127889, 127893, 127897, 127901, 127905, 127912, 127916, 127920, 127928, + 127932, 127936, 127940, 127944, 127950, 127954, 127958, 127964, 127971, + 127977, 127984, 127996, 128000, 128007, 128014, 128021, 128028, 128040, + 128047, 128051, 128055, 128059, 128066, 128073, 128080, 128087, 128097, + 128104, 128110, 128117, 128124, 128131, 128138, 128147, 128157, 128164, + 128168, 128175, 128179, 128183, 128187, 128194, 128201, 128211, 128217, + 128221, 128230, 128234, 128241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128245, 128251, 128257, + 128264, 128271, 128278, 128285, 128292, 128299, 128305, 128312, 128319, + 128326, 128333, 128340, 128347, 128353, 128359, 128365, 128371, 128377, + 128383, 128389, 128395, 128401, 128408, 128415, 128422, 128429, 128436, + 128443, 128449, 128455, 128461, 128468, 128475, 128481, 128487, 128496, + 128503, 128510, 128517, 128524, 128531, 128538, 128544, 128550, 128556, + 128565, 128572, 128579, 128590, 128601, 128607, 128613, 128619, 128628, + 128635, 128642, 128652, 128662, 128673, 128684, 128696, 128709, 128720, + 128731, 128743, 128756, 128767, 128778, 128789, 128800, 128811, 128823, + 128831, 128839, 128848, 128857, 128866, 128872, 128878, 128884, 128891, + 128901, 128908, 128918, 128923, 128928, 128934, 128940, 128948, 128956, + 128965, 128976, 128987, 128995, 129003, 129012, 129021, 129029, 129036, + 129044, 129052, 129059, 129066, 129075, 129084, 129093, 129102, 129111, + 0, 129120, 129131, 129138, 129146, 129154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 129162, 129171, 129178, 129185, 129194, 129201, 129208, 129215, + 129225, 129232, 129239, 129246, 129254, 129261, 129268, 129275, 129286, + 129293, 129300, 129307, 129314, 129321, 129330, 129337, 129343, 129350, + 129359, 129366, 129373, 129380, 129390, 129397, 129404, 129414, 129424, + 129431, 129438, 129445, 129452, 129459, 129466, 129475, 129482, 129489, + 129495, 129503, 129512, 129521, 129532, 129540, 129549, 129558, 129567, + 129576, 129583, 129590, 129599, 129611, 129621, 129628, 129635, 129645, + 129655, 129664, 129674, 129681, 129691, 129698, 129705, 129712, 129722, + 129732, 129739, 129746, 129756, 129762, 129773, 129782, 129792, 129800, + 129813, 129820, 129826, 129834, 129841, 129851, 129855, 129859, 129863, + 129867, 129871, 129875, 129879, 129888, 129892, 129899, 129903, 129907, + 129911, 129915, 129919, 129923, 129927, 129931, 129935, 129939, 129943, + 129947, 129951, 129955, 129959, 129963, 129967, 129971, 129975, 129982, + 129989, 129999, 130012, 130022, 130026, 130030, 130034, 130038, 130042, + 130046, 130050, 130054, 130058, 130062, 130066, 130073, 130080, 130091, + 130098, 130104, 130111, 130118, 130125, 130132, 130139, 130143, 130147, + 130154, 130161, 130168, 130177, 130184, 130197, 130207, 130214, 130221, + 130225, 130229, 130238, 130245, 130252, 130259, 130272, 130279, 130286, + 130296, 130306, 130315, 130322, 130329, 130336, 130343, 130350, 130357, + 130367, 130373, 130381, 130388, 130396, 130403, 130414, 130421, 130427, + 130434, 130441, 130448, 130455, 130465, 130475, 130482, 130489, 130498, + 130506, 130512, 130519, 130526, 130533, 130540, 130544, 130554, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 130564, 130569, 130574, 130579, 130584, 130589, 130594, 130599, + 130604, 130609, 130614, 130619, 130624, 130629, 130634, 130639, 130644, + 130649, 130654, 130659, 130664, 130669, 130674, 130679, 130684, 130689, + 130694, 130699, 130704, 130709, 130714, 130719, 130724, 130729, 130734, + 130739, 130744, 130749, 130754, 130759, 130764, 130769, 130774, 130779, + 130784, 130789, 130794, 130799, 130804, 130809, 130814, 130819, 130824, + 130829, 130834, 130839, 130844, 130849, 130854, 130859, 130864, 130869, + 130874, 130879, 130884, 130889, 130894, 130899, 130904, 130909, 130914, + 130919, 130924, 130929, 130934, 130939, 130944, 130949, 130954, 130959, + 130964, 130969, 130974, 130979, 130984, 130989, 130994, 130999, 131004, + 131009, 131014, 131019, 131024, 131029, 131034, 131039, 131044, 131049, + 131054, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131059, 131063, 131067, + 131071, 131075, 131079, 131083, 131087, 131091, 131095, 131099, 131103, + 131107, 131111, 131115, 131119, 131123, 131127, 131131, 131135, 131139, + 131143, 131147, 131151, 131155, 131159, 131163, 131167, 131171, 131175, + 131179, 131183, 131187, 131191, 131195, 131199, 131203, 131207, 131211, + 131215, 131219, 131223, 131227, 131231, 131235, 131239, 131243, 131247, + 131251, 131255, 131259, 131263, 131267, 131271, 131275, 131279, 131283, + 131287, 131291, 131295, 131299, 131303, 131307, 131311, 131315, 131319, + 131323, 131327, 131331, 131335, 131339, 131343, 131347, 131351, 131355, + 131359, 131363, 131367, 131371, 131375, 131379, 131383, 131387, 131391, + 131395, 131399, 131403, 131407, 131411, 131415, 131419, 131423, 131427, + 131431, 131435, 131439, 131443, 131447, 131451, 131455, 131459, 131463, + 131467, 131471, 131475, 131479, 131483, 131487, 131491, 131495, 131499, + 131503, 131507, 131511, 131515, 131519, 131523, 131527, 131531, 131535, + 131539, 131543, 131547, 131551, 131555, 131559, 131563, 131567, 131571, + 131575, 131579, 131583, 131587, 131591, 131595, 131599, 131603, 131607, + 131611, 131615, 131619, 131623, 131627, 131631, 131635, 131639, 131643, + 131647, 131651, 131655, 131659, 131663, 131667, 131671, 131675, 131679, + 131683, 131687, 131691, 131695, 131699, 131703, 131707, 131711, 131715, + 131719, 131723, 131727, 131731, 131735, 131739, 131743, 131747, 131751, + 131755, 131759, 131763, 131767, 131771, 131775, 131779, 131783, 131787, + 131791, 131795, 131799, 131803, 131807, 131811, 131815, 131819, 131823, + 131827, 131831, 131835, 131839, 131843, 131847, 131851, 131855, 131859, + 131863, 131867, 131871, 131875, 131879, 131883, 131887, 131891, 131895, + 131899, 131903, 131907, 131911, 131915, 131919, 131923, 131927, 131931, + 131935, 131939, 131943, 131947, 131951, 131955, 131959, 131963, 131967, + 131971, 131975, 131979, 131983, 131987, 131991, 131995, 131999, 132003, + 132007, 132011, 132015, 132019, 132023, 132027, 132031, 132035, 132039, + 132043, 132047, 132051, 132055, 132059, 132063, 132067, 132071, 132075, + 132079, 132083, 132087, 132091, 132095, 132099, 132103, 132107, 132111, + 132115, 132119, 132123, 132127, 132131, 132135, 132139, 132143, 132147, + 132151, 132155, 132159, 132163, 132167, 132171, 132175, 132179, 132183, + 132187, 132191, 132195, 132199, 132203, 132207, 132211, 132215, 132219, + 132223, 132227, 132231, 132235, 132239, 132243, 132247, 132251, 132255, + 132259, 132263, 132267, 132271, 132275, 132279, 132283, 132287, 132291, + 132295, 132299, 132303, 132307, 132311, 132315, 132319, 132323, 132327, + 132331, 132335, 132339, 132343, 132347, 132351, 132355, 132359, 132363, + 132367, 132371, 132375, 132379, 132383, 132387, 132391, 132395, 132399, + 132403, 132407, 132411, 132415, 132419, 132423, 132427, 132431, 132435, + 132439, 132443, 132447, 132451, 132455, 132459, 132463, 132467, 132471, + 132475, 132479, 132483, 132487, 132491, 132495, 132499, 132503, 132507, + 132511, 132515, 132519, 132523, 132527, 132531, 132535, 132539, 132543, + 132547, 132551, 132555, 132559, 132563, 132567, 132571, 132575, 132579, + 132583, 132587, 132591, 132595, 132599, 132603, 132607, 132611, 132615, + 132619, 132623, 132627, 132631, 132635, 132639, 132643, 132647, 132651, + 132655, 132659, 132663, 132667, 132671, 132675, 132679, 132683, 132687, + 132691, 132695, 132699, 132703, 132707, 132711, 132715, 132719, 132723, + 132727, 132731, 132735, 132739, 132743, 132747, 132751, 132755, 132759, + 132763, 132767, 132771, 132775, 132779, 132783, 132787, 132791, 132795, + 132799, 132803, 132807, 132811, 132815, 132819, 132823, 132827, 132831, + 132835, 132839, 132843, 132847, 132851, 132855, 132859, 132863, 132867, + 132871, 132875, 132879, 132883, 132887, 132891, 132895, 132899, 132903, + 132907, 132911, 132915, 132919, 132923, 132927, 132931, 132935, 132939, + 132943, 132947, 132951, 132955, 132959, 132963, 132967, 132971, 132975, + 132979, 132983, 132987, 132991, 132995, 132999, 133003, 133007, 133011, + 133015, 133019, 133023, 133027, 133031, 133035, 133039, 133043, 133047, + 133051, 133055, 133059, 133063, 133067, 133071, 133075, 133079, 133083, + 133087, 133091, 133095, 133099, 133103, 133107, 133111, 133115, 133119, + 133123, 133127, 133131, 133135, 133139, 133143, 133147, 133151, 133155, + 133159, 133163, 133167, 133171, 133175, 133179, 133183, 133187, 133191, + 133195, 133199, 133203, 133207, 133211, 133215, 133219, 133223, 133227, + 133231, 133235, 133239, 133243, 133247, 133251, 133255, 133259, 133263, + 133267, 133271, 133275, 133279, 133283, 133287, 133291, 133295, 133299, + 133303, 133307, 133311, 133315, 133319, 133323, 133327, 133331, 133335, + 133339, 133343, 133347, 133351, 133355, 133359, 133363, 133367, 133371, + 133375, 133379, 133383, 133387, 133391, 133395, 133399, 133403, 133407, + 133411, 133415, 133419, 133423, 133427, 133431, 133435, 133439, 133443, + 133447, 133451, 133455, 133459, 133463, 133467, 133471, 133475, 133479, + 133483, 133487, 133491, 133495, 133499, 133503, 133507, 133511, 133515, + 133519, 133523, 133527, 133531, 133535, 133539, 133543, 133547, 133551, + 133555, 133559, 133563, 133567, 133571, 133575, 133579, 133583, 133587, + 133591, 133595, 133599, 133603, 133607, 133611, 133615, 133619, 133623, + 133627, 133631, 133635, 133639, 133643, 133647, 133651, 133655, 133659, + 133663, 133667, 133671, 133675, 133679, 133683, 133687, 133691, 133695, + 133699, 133703, 133707, 133711, 133715, 133719, 133723, 133727, 133731, + 133735, 133739, 133743, 133747, 133751, 133755, 133759, 133763, 133767, + 133771, 133775, 133779, 133783, 133787, 133791, 133795, 133799, 133803, + 133807, 133811, 133815, 133819, 133823, 133827, 133831, 133835, 133839, + 133843, 133847, 133851, 133855, 133859, 133863, 133867, 133871, 133875, + 133879, 133883, 133887, 133891, 133895, 133899, 133903, 133907, 133911, + 133915, 133919, 133923, 133927, 133931, 133935, 133939, 133943, 133947, + 133951, 133955, 133959, 133963, 133967, 133971, 133975, 133979, 133983, + 133987, 133991, 133995, 133999, 134003, 134007, 134011, 134015, 134019, + 134023, 134027, 134031, 134035, 134039, 134043, 134047, 134051, 134055, + 134059, 134063, 134067, 134071, 134075, 134079, 134083, 134087, 134091, + 134095, 134099, 134103, 134107, 134111, 134115, 134119, 134123, 134127, + 134131, 134135, 134139, 134143, 134147, 134151, 134155, 134159, 134163, + 134167, 134171, 134175, 134179, 134183, 134187, 134191, 134195, 134199, + 134203, 134207, 134211, 134215, 134219, 134223, 134227, 134231, 134235, + 134239, 134243, 134247, 134251, 134255, 134259, 134263, 134267, 134271, + 134275, 134279, 134283, 134287, 134291, 134295, 134299, 134303, 134307, + 134311, 134315, 134319, 134323, 134327, 134331, 134335, 134339, 134343, + 134347, 134351, 134355, 134359, 134363, 134367, 134371, 134375, 134379, + 134383, 134387, 134391, 134395, 134399, 134403, 134407, 134411, 134415, + 134419, 134423, 134427, 134431, 134435, 134439, 134443, 134447, 134451, + 134455, 134459, 134463, 134467, 134471, 134475, 134479, 134483, 134487, + 134491, 134495, 134499, 134503, 134507, 134511, 134515, 134519, 134523, + 134527, 134531, 134535, 134539, 134543, 134547, 134551, 134555, 134559, + 134563, 134567, 134571, 134575, 134579, 134583, 134587, 134591, 134595, + 134599, 134603, 134607, 134611, 134615, 134619, 134623, 134627, 134631, + 134635, 134639, 134643, 134647, 134651, 134655, 134659, 134663, 134667, + 134671, 134675, 134679, 134683, 134687, 134691, 134695, 134699, 134703, + 134707, 134711, 134715, 134719, 134723, 134727, 134731, 134735, 134739, + 134743, 134747, 134751, 134755, 134759, 134763, 134767, 134771, 134775, + 134779, 134783, 134787, 134791, 134795, 134799, 134803, 134807, 134811, + 134815, 134819, 134823, 134827, 134831, 134835, 134839, 134843, 134847, + 134851, 134855, 134859, 134863, 134867, 134871, 134875, 134879, 134883, + 134887, 134891, 134895, 134899, 134903, 134907, 134911, 134915, 134919, + 134923, 134927, 134931, 134935, 134939, 134943, 134947, 134951, 134955, + 134959, 134963, 134967, 134971, 134975, 134979, 134983, 134987, 134991, + 134995, 134999, 135003, 135007, 135011, 135015, 135019, 135023, 135027, + 135031, 135035, 135039, 135043, 135047, 135051, 135055, 135059, 135063, + 135067, 135071, 135075, 135079, 135083, 135087, 135091, 135095, 135099, + 135103, 135107, 135111, 135115, 135119, 135123, 135127, 135131, 135135, + 135139, 135143, 135147, 135151, 135155, 135159, 135163, 135167, 135171, + 135175, 135179, 135183, 135187, 135191, 135195, 135199, 135203, 135207, + 135211, 135215, 135219, 135223, 135227, 135231, 135235, 135239, 135243, + 135247, 135251, 135255, 135259, 135263, 135267, 135271, 135275, 135279, + 135283, 135287, 135291, 135295, 135299, 135303, 135307, 135311, 135315, + 135319, 135323, 135327, 135331, 135335, 135339, 135343, 135347, 135352, + 135358, 135368, 135378, 135388, 135398, 135404, 135410, 135416, 135424, + 135432, 135440, 135446, 135452, 135460, 135468, 135474, 135480, 135485, + 135490, 135496, 135503, 135510, 135521, 135532, 135541, 135552, 135561, + 135577, 135589, 135600, 135616, 135625, 135637, 135646, 135658, 135670, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135675, 135679, + 135683, 135687, 135691, 135695, 135699, 135703, 135707, 135711, 135715, + 135719, 135723, 135727, 135731, 135735, 135739, 135743, 135747, 135751, + 135755, 135759, 135763, 135767, 135771, 135775, 135779, 135783, 135787, + 135791, 135795, 135799, 135803, 135807, 135811, 135815, 135819, 135823, + 135827, 135831, 135835, 135839, 135843, 135847, 135851, 135855, 135859, + 135863, 135867, 135871, 135875, 135879, 135883, 135887, 135891, 135895, + 135899, 135903, 135907, 135911, 135915, 135919, 135923, 135927, 135931, + 135935, 135939, 135943, 135947, 135951, 135955, 135959, 135963, 135967, + 135971, 135975, 135979, 135983, 135987, 135991, 135995, 135999, 136003, + 136007, 136011, 136015, 136019, 136023, 136027, 136031, 136035, 136039, + 136043, 136047, 136051, 136055, 136059, 136063, 136067, 136071, 136075, + 136079, 136083, 136087, 136091, 136095, 136099, 136103, 136107, 136111, + 136115, 136119, 136123, 136127, 136131, 136135, 136139, 136143, 136147, + 136151, 136155, 136159, 136163, 136167, 136171, 136175, 136179, 136183, + 136187, 136191, 136195, 136199, 136203, 136207, 136211, 136215, 136219, + 136223, 136227, 136231, 136235, 136239, 136243, 136247, 136251, 136255, + 136259, 136263, 136267, 136271, 136275, 136279, 136283, 136287, 136291, + 136295, 136299, 136303, 136307, 136311, 136315, 136319, 136323, 136327, + 136331, 136335, 136339, 136343, 136347, 136351, 136355, 136359, 136363, + 136367, 136371, 136375, 136379, 136383, 136387, 136391, 136395, 136399, + 136403, 136407, 136411, 136415, 136419, 136423, 136427, 136431, 136435, + 136439, 136443, 136447, 136451, 136455, 136459, 136463, 136467, 136471, + 136475, 136479, 136483, 136487, 136491, 136495, 136499, 136503, 136507, + 136511, 136515, 136519, 136523, 136527, 136531, 136535, 136539, 136543, + 136547, 136551, 136555, 136559, 136563, 136567, 136571, 136575, 136579, + 136583, 136587, 136591, 136595, 136599, 136603, 136607, 136611, 136615, + 136619, 136623, 136627, 136631, 136635, 136639, 136643, 136647, 136651, + 136655, 136659, 136663, 136667, 136671, 136675, 136679, 136683, 136687, + 136691, 136695, 136699, 136703, 136707, 136711, 136715, 136719, 136723, + 136727, 136731, 136735, 136739, 136743, 136747, 136751, 136755, 136759, + 136763, 136767, 136771, 136775, 136779, 136783, 136787, 136791, 136795, + 136799, 136803, 136807, 136811, 136815, 136819, 136823, 136827, 136831, + 136835, 136839, 136843, 136847, 136851, 136855, 136859, 136863, 136867, + 136871, 136875, 136879, 136883, 136887, 136891, 136895, 136899, 136903, + 136907, 136911, 136915, 136919, 136923, 136927, 136931, 136935, 136939, + 136943, 136947, 136951, 136955, 136959, 136963, 136967, 136971, 136975, + 136979, 136983, 136987, 136991, 136995, 136999, 137003, 137007, 137011, + 137015, 137019, 137023, 137027, 137031, 137035, 137039, 137043, 137047, + 137051, 137055, 137059, 137063, 137067, 137071, 137075, 137079, 137083, + 137087, 137091, 137095, 137099, 137103, 137107, 137111, 137115, 137119, + 137123, 137127, 137131, 137135, 137139, 137143, 137147, 137151, 137155, + 137159, 137163, 137167, 137171, 137175, 137179, 137183, 137187, 137191, + 137195, 137199, 137203, 137207, 137211, 137215, 137219, 137223, 137227, + 137231, 137235, 137239, 137243, 137247, 137251, 137255, 137259, 137263, + 137267, 137271, 137275, 137279, 137283, 137287, 137291, 137295, 137299, + 137303, 137307, 137311, 137315, 137319, 137323, 137327, 137331, 137335, + 137339, 137343, 137347, 137351, 137355, 137359, 137363, 137367, 137371, + 137375, 137379, 137383, 137387, 137391, 137395, 137399, 137403, 137407, + 137417, 137421, 137425, 137429, 137433, 137437, 137441, 137445, 137449, + 137453, 137457, 137461, 137466, 137470, 137474, 137478, 137482, 137486, + 137490, 137494, 137498, 137502, 137506, 137510, 137514, 137518, 137522, + 137526, 137530, 137539, 137548, 137552, 137556, 137560, 137564, 137568, + 137572, 137576, 137580, 137584, 137588, 137592, 137596, 137600, 137604, + 137608, 137612, 137616, 137620, 137624, 137628, 137632, 137636, 137640, + 137644, 137648, 137652, 137656, 137660, 137664, 137668, 137672, 137676, + 137680, 137684, 137688, 137692, 137696, 137700, 137704, 137708, 137712, + 137716, 137720, 137724, 137728, 137732, 137736, 137740, 137744, 137748, + 137752, 137756, 137760, 137764, 137768, 137772, 137776, 137780, 137784, + 137788, 137792, 137796, 137800, 137804, 137808, 137812, 137816, 137820, + 137824, 137828, 137832, 137836, 137840, 137844, 137848, 137852, 137856, + 137860, 137864, 137868, 137872, 137876, 137880, 137884, 137888, 137892, + 137896, 137900, 137904, 137908, 137912, 137916, 137920, 137924, 137928, + 137932, 137936, 137940, 137944, 137948, 137952, 137956, 137960, 137964, + 137968, 137972, 137976, 137980, 137984, 137988, 137992, 137996, 138000, + 138004, 138008, 138012, 138016, 138020, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138024, + 138032, 138040, 138050, 138060, 138068, 138074, 138082, 138090, 138100, + 138112, 138124, 138130, 138138, 138144, 138150, 138156, 138162, 138168, + 138174, 138180, 138186, 138192, 138198, 138204, 138212, 138220, 138226, + 138232, 138238, 138244, 138252, 138260, 138269, 138275, 138283, 138289, + 138295, 138301, 138307, 138313, 138321, 138329, 138335, 138341, 138347, + 138353, 138359, 138365, 138371, 138377, 138383, 138389, 138395, 138401, + 138407, 138413, 138419, 138425, 138431, 138437, 138443, 138451, 138457, + 138463, 138473, 138481, 138487, 138493, 138499, 138505, 138511, 138517, + 138523, 138529, 138535, 138541, 138547, 138553, 138559, 138565, 138571, + 138577, 138583, 138589, 138595, 138601, 138607, 138613, 138621, 138627, + 138635, 138643, 138651, 138657, 138663, 138669, 138675, 138681, 138689, + 138699, 138707, 138715, 138721, 138727, 138735, 138743, 138749, 138757, + 138765, 138773, 138779, 138785, 138791, 138797, 138803, 138809, 138817, + 138825, 138831, 138837, 138843, 138849, 138855, 138863, 138869, 138875, + 138881, 138887, 138893, 138899, 138907, 138913, 138919, 138925, 138931, + 138939, 138947, 138953, 138959, 138965, 138970, 138976, 138982, 138990, + 138996, 139002, 139008, 139014, 139020, 139026, 139032, 139038, 139044, + 139054, 139062, 139068, 139074, 139080, 139088, 139094, 139100, 139106, + 139114, 139120, 139126, 139132, 139138, 139144, 139150, 139156, 139162, + 139168, 139174, 139180, 139188, 139194, 139202, 139208, 139214, 139222, + 139228, 139234, 139240, 139246, 139252, 139258, 139264, 139270, 139276, + 139282, 139288, 139294, 139300, 139306, 139312, 139318, 139324, 139330, + 139336, 139344, 139350, 139356, 139362, 139368, 139374, 139380, 139386, + 139392, 139398, 139404, 139410, 139416, 139422, 139430, 139436, 139442, + 139450, 139456, 139462, 139468, 139474, 139480, 139486, 139492, 139498, + 139504, 139510, 139518, 139524, 139530, 139536, 139542, 139548, 139556, + 139564, 139570, 139576, 139582, 139588, 139594, 139600, 139605, 139610, + 139615, 139620, 139625, 139630, 139635, 139640, 139645, 139650, 139655, + 139660, 139665, 139670, 139675, 139680, 139685, 139690, 139695, 139700, + 139705, 139710, 139715, 139720, 139725, 139730, 139735, 139740, 139745, + 139750, 139757, 139762, 139767, 139772, 139777, 139782, 139787, 139792, + 139797, 139802, 139807, 139812, 139817, 139822, 139827, 139832, 139837, + 139842, 139847, 139852, 139857, 139862, 139867, 139872, 139877, 139882, + 139887, 139892, 139897, 139902, 139907, 139912, 139917, 139922, 139927, + 139932, 139937, 139942, 139947, 139952, 139957, 139962, 139967, 139972, + 139977, 139982, 139987, 139992, 139997, 140002, 140007, 140012, 140017, + 140022, 140027, 140032, 140037, 140042, 140047, 140054, 140059, 140064, + 140069, 140074, 140079, 140084, 140089, 140094, 140099, 140104, 140109, + 140114, 140119, 140124, 140129, 140134, 140139, 140144, 140149, 140154, + 140159, 140166, 140171, 140176, 140182, 140187, 140192, 140197, 140202, + 140207, 140212, 140217, 140222, 140227, 140232, 140237, 140242, 140247, + 140252, 140257, 140262, 140267, 140272, 140277, 140282, 140287, 140292, + 140297, 140302, 140307, 140312, 140317, 140322, 140327, 140332, 140337, + 140342, 140347, 140352, 140357, 140362, 140367, 140372, 140377, 140382, + 140387, 140392, 140397, 140404, 140409, 140414, 140421, 140428, 140433, + 140438, 140443, 140448, 140453, 140458, 140463, 140468, 140473, 140478, + 140483, 140488, 140493, 140498, 140503, 140508, 140513, 140518, 140523, + 140528, 140533, 140538, 140543, 140548, 140553, 140560, 140565, 140570, + 140575, 140580, 140585, 140590, 140595, 140600, 140605, 140610, 140615, + 140620, 140625, 140630, 140635, 140640, 140645, 140650, 140657, 140662, + 140667, 140672, 140677, 140682, 140687, 140692, 140698, 140703, 140708, + 140713, 140718, 140723, 140728, 140733, 140738, 140745, 140752, 140757, + 140762, 140766, 140771, 140775, 140779, 140784, 140791, 140796, 140801, + 140810, 140815, 140820, 140825, 140830, 140837, 140844, 140849, 140854, + 140859, 140864, 140871, 140876, 140881, 140886, 140891, 140896, 140901, + 140906, 140911, 140916, 140921, 140926, 140931, 140938, 140942, 140947, + 140952, 140957, 140962, 140966, 140971, 140976, 140981, 140986, 140991, + 140996, 141001, 141006, 141011, 141017, 141023, 141029, 141035, 141041, + 141046, 141052, 141058, 141064, 141070, 141076, 141082, 141088, 141094, + 141100, 141106, 141112, 141118, 141124, 141130, 141136, 141142, 141148, + 141154, 141159, 141165, 141171, 141177, 141183, 141189, 141195, 141201, + 141207, 141213, 141219, 141225, 141231, 141237, 141243, 141249, 141255, + 141261, 141267, 141273, 141279, 141284, 141290, 141296, 141302, 141308, + 141314, 0, 0, 0, 0, 0, 0, 0, 141320, 141325, 141330, 141335, 141340, + 141345, 141350, 141354, 141359, 141364, 141369, 141374, 141379, 141384, + 141389, 141394, 141399, 141403, 141408, 141412, 141417, 141422, 141427, + 141432, 141437, 141441, 141446, 141451, 141455, 141460, 141465, 0, + 141470, 141475, 141479, 141483, 141487, 141491, 141495, 141499, 141503, + 141507, 0, 0, 0, 0, 141511, 141515, 141520, 141525, 141530, 141535, + 141540, 141545, 141550, 141555, 141560, 141565, 141570, 141575, 141580, + 141585, 141590, 141595, 141600, 141605, 141610, 141615, 141620, 141625, + 141630, 141635, 141640, 141645, 141650, 141655, 141660, 141665, 141670, + 141675, 141680, 141686, 141692, 141699, 141706, 141711, 141716, 141721, + 141726, 141731, 141736, 141741, 141746, 141751, 141756, 141761, 141766, + 141770, 141775, 141780, 141785, 141789, 141793, 141798, 141802, 141807, + 141812, 141817, 141821, 141825, 141829, 141833, 141838, 141843, 141848, + 141852, 141857, 141862, 141867, 141872, 141877, 141882, 141887, 141892, + 141897, 141902, 141907, 0, 141912, 141917, 141921, 141925, 141929, + 141933, 141937, 141941, 141945, 141949, 0, 0, 0, 0, 0, 0, 141953, 141960, + 141966, 141973, 141980, 141987, 141994, 142001, 142008, 142015, 142022, + 142029, 142036, 142043, 142050, 142057, 142064, 142071, 142077, 142084, + 142091, 142098, 142104, 142111, 142117, 142123, 142130, 142136, 142143, + 142149, 0, 0, 142155, 142163, 142171, 142180, 142189, 142198, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 142206, 142211, 142216, 142221, 142226, 142231, 142236, + 142241, 142246, 142251, 142256, 142261, 142266, 142271, 142276, 142281, + 142286, 142291, 142296, 142301, 142306, 142311, 142316, 142321, 142326, + 142331, 142336, 142341, 142346, 142351, 142356, 142361, 142366, 142371, + 142376, 142381, 142386, 142391, 142396, 142401, 142406, 142411, 142416, + 142421, 142426, 142431, 142436, 142441, 142446, 142453, 142460, 142467, + 142474, 142481, 142488, 142495, 142502, 142511, 142518, 142525, 142532, + 142539, 142546, 142553, 142560, 142567, 142574, 142581, 142588, 142593, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142602, 142607, 142611, 142615, 142619, + 142623, 142627, 142631, 142635, 142639, 0, 142643, 142648, 142653, + 142660, 142665, 142672, 142679, 0, 142684, 142691, 142696, 142701, + 142708, 142715, 142720, 142725, 142730, 142735, 142740, 142747, 142754, + 142759, 142764, 142769, 142782, 142791, 142798, 142807, 142816, 0, 0, 0, + 0, 0, 142825, 142832, 142839, 142846, 142853, 142860, 142867, 142874, + 142881, 142888, 142895, 142902, 142909, 142916, 142923, 142930, 142937, + 142944, 142951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142958, 142964, 142970, 142976, + 142982, 142988, 142994, 143000, 143006, 143012, 143018, 143024, 143029, + 143035, 143040, 143046, 143051, 143057, 143063, 143068, 143074, 143079, + 143085, 143091, 143097, 143103, 143109, 143115, 143121, 143126, 143131, + 143137, 143143, 143149, 143155, 143161, 143167, 143173, 143179, 143185, + 143191, 143197, 143203, 143209, 143214, 143220, 143225, 143231, 143236, + 143242, 143248, 143253, 143259, 143264, 143270, 143276, 143282, 143288, + 143294, 143300, 143306, 143311, 143316, 143322, 143328, 143333, 143337, + 143341, 143345, 143349, 143353, 143357, 143361, 143365, 143369, 143374, + 143379, 143384, 143389, 143394, 143399, 143404, 143409, 143414, 143419, + 143426, 143433, 143440, 143444, 143450, 143455, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143461, + 143464, 143468, 143472, 143476, 143479, 143483, 143488, 143492, 143496, + 143500, 143504, 143508, 143513, 143518, 143522, 143526, 143529, 143533, + 143538, 143543, 143547, 143551, 143554, 143558, 143562, 143566, 143570, + 143574, 143578, 143582, 143585, 143589, 143593, 143597, 143601, 143605, + 143609, 143615, 143618, 143622, 143626, 143630, 143634, 143638, 143642, + 143646, 143650, 143654, 143659, 143664, 143670, 143674, 143678, 143682, + 143686, 143690, 143694, 143699, 143702, 143706, 143710, 143714, 143718, + 143724, 143728, 143732, 143736, 143740, 143744, 143748, 143752, 143756, + 143760, 143764, 0, 0, 0, 0, 143768, 143773, 143777, 143781, 143787, + 143793, 143797, 143802, 143807, 143812, 143817, 143821, 143826, 143831, + 143836, 143840, 143845, 143850, 143855, 143859, 143864, 143869, 143874, + 143879, 143884, 143889, 143894, 143899, 143903, 143908, 143913, 143918, + 143923, 143928, 143933, 143938, 143943, 143948, 143953, 143958, 143965, + 143970, 143977, 143982, 143987, 143992, 143997, 144002, 144007, 144012, + 144017, 144022, 144027, 144032, 144037, 144042, 144047, 0, 0, 0, 0, 0, 0, + 0, 144052, 144055, 144060, 144063, 144066, 144070, 144074, 144078, + 144082, 144086, 144090, 144094, 144100, 144106, 144112, 144118, 144124, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144130, 144134, 144138, + 144144, 144150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144155, 144164, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144173, 144176, 144179, 144182, 144185, + 144188, 144191, 144194, 144197, 144200, 144203, 144206, 144209, 144212, + 144215, 144218, 144221, 144224, 144227, 144230, 144233, 144236, 144239, + 144242, 144245, 144248, 144251, 144254, 144257, 144260, 144263, 144266, + 144269, 144272, 144275, 144278, 144281, 144284, 144287, 144290, 144293, + 144296, 144299, 144302, 144305, 144308, 144311, 144314, 144317, 144320, + 144323, 144326, 144329, 144332, 144335, 144338, 144341, 144344, 144347, + 144350, 144353, 144356, 144359, 144362, 144365, 144368, 144371, 144374, + 144377, 144380, 144383, 144386, 144389, 144392, 144395, 144398, 144401, + 144404, 144407, 144410, 144413, 144416, 144419, 144422, 144425, 144428, + 144431, 144434, 144437, 144440, 144443, 144446, 144449, 144452, 144455, + 144458, 144461, 144464, 144467, 144470, 144473, 144476, 144479, 144482, + 144485, 144488, 144491, 144494, 144497, 144500, 144503, 144506, 144509, + 144512, 144515, 144518, 144521, 144524, 144527, 144530, 144533, 144536, + 144539, 144542, 144545, 144548, 144551, 144554, 144557, 144560, 144563, + 144566, 144569, 144572, 144575, 144578, 144581, 144584, 144587, 144590, + 144593, 144596, 144599, 144602, 144605, 144608, 144611, 144614, 144617, + 144620, 144623, 144626, 144629, 144632, 144635, 144638, 144641, 144644, + 144647, 144650, 144653, 144656, 144659, 144662, 144665, 144668, 144671, + 144674, 144677, 144680, 144683, 144686, 144689, 144692, 144695, 144698, + 144701, 144704, 144707, 144710, 144713, 144716, 144719, 144722, 144725, + 144728, 144731, 144734, 144737, 144740, 144743, 144746, 144749, 144752, + 144755, 144758, 144761, 144764, 144767, 144770, 144773, 144776, 144779, + 144782, 144785, 144788, 144791, 144794, 144797, 144800, 144803, 144806, + 144809, 144812, 144815, 144818, 144821, 144824, 144827, 144830, 144833, + 144836, 144839, 144842, 144845, 144848, 144851, 144854, 144857, 144860, + 144863, 144866, 144869, 144872, 144875, 144878, 144881, 144884, 144887, + 144890, 144893, 144896, 144899, 144902, 144905, 144908, 144911, 144914, + 144917, 144920, 144923, 144926, 144929, 144932, 144935, 144938, 144941, + 144944, 144947, 144950, 144953, 144956, 144959, 144962, 144965, 144968, + 144971, 144974, 144977, 144980, 144983, 144986, 144989, 144992, 144995, + 144998, 145001, 145004, 145007, 145010, 145013, 145016, 145019, 145022, + 145025, 145028, 145031, 145034, 145037, 145040, 145043, 145046, 145049, + 145052, 145055, 145058, 145061, 145064, 145067, 145070, 145073, 145076, + 145079, 145082, 145085, 145088, 145091, 145094, 145097, 145100, 145103, + 145106, 145109, 145112, 145115, 145118, 145121, 145124, 145127, 145130, + 145133, 145136, 145139, 145142, 145145, 145148, 145151, 145154, 145157, + 145160, 145163, 145166, 145169, 145172, 145175, 145178, 145181, 145184, + 145187, 145190, 145193, 145196, 145199, 145202, 145205, 145208, 145211, + 145214, 145217, 145220, 145223, 145226, 145229, 145232, 145235, 145238, + 145241, 145244, 145247, 145250, 145253, 145256, 145259, 145262, 145265, + 145268, 145271, 145274, 145277, 145280, 145283, 145286, 145289, 145292, + 145295, 145298, 145301, 145304, 145307, 145310, 145313, 145316, 145319, + 145322, 145325, 145328, 145331, 145334, 145337, 145340, 145343, 145346, + 145349, 145352, 145355, 145358, 145361, 145364, 145367, 145370, 145373, + 145376, 145379, 145382, 145385, 145388, 145391, 145394, 145397, 145400, + 145403, 145406, 145409, 145412, 145415, 145418, 145421, 145424, 145427, + 145430, 145433, 145436, 145439, 145442, 145445, 145448, 145451, 145454, + 145457, 145460, 145463, 145466, 145469, 145472, 145475, 145478, 145481, + 145484, 145487, 145490, 145493, 145496, 145499, 145502, 145505, 145508, + 145511, 145514, 145517, 145520, 145523, 145526, 145529, 145532, 145535, + 145538, 145541, 145544, 145547, 145550, 145553, 145556, 145559, 145562, + 145565, 145568, 145571, 145574, 145577, 145580, 145583, 145586, 145589, + 145592, 145595, 145598, 145601, 145604, 145607, 145610, 145613, 145616, + 145619, 145622, 145625, 145628, 145631, 145634, 145637, 145640, 145643, + 145646, 145649, 145652, 145655, 145658, 145661, 145664, 145667, 145670, + 145673, 145676, 145679, 145682, 145685, 145688, 145691, 145694, 145697, + 145700, 145703, 145706, 145709, 145712, 145715, 145718, 145721, 145724, + 145727, 145730, 145733, 145736, 145739, 145742, 145745, 145748, 145751, + 145754, 145757, 145760, 145763, 145766, 145769, 145772, 145775, 145778, + 145781, 145784, 145787, 145790, 145793, 145796, 145799, 145802, 145805, + 145808, 145811, 145814, 145817, 145820, 145823, 145826, 145829, 145832, + 145835, 145838, 145841, 145844, 145847, 145850, 145853, 145856, 145859, + 145862, 145865, 145868, 145871, 145874, 145877, 145880, 145883, 145886, + 145889, 145892, 145895, 145898, 145901, 145904, 145907, 145910, 145913, + 145916, 145919, 145922, 145925, 145928, 145931, 145934, 145937, 145940, + 145943, 145946, 145949, 145952, 145955, 145958, 145961, 145964, 145967, + 145970, 145973, 145976, 145979, 145982, 145985, 145988, 145991, 145994, + 145997, 146000, 146003, 146006, 146009, 146012, 146015, 146018, 146021, + 146024, 146027, 146030, 146033, 146036, 146039, 146042, 146045, 146048, + 146051, 146054, 146057, 146060, 146063, 146066, 146069, 146072, 146075, + 146078, 146081, 146084, 146087, 146090, 146093, 146096, 146099, 146102, + 146105, 146108, 146111, 146114, 146117, 146120, 146123, 146126, 146129, + 146132, 146135, 146138, 146141, 146144, 146147, 146150, 146153, 146156, + 146159, 146162, 146165, 146168, 146171, 146174, 146177, 146180, 146183, + 146186, 146189, 146192, 146195, 146198, 146201, 146204, 146207, 146210, + 146213, 146216, 146219, 146222, 146225, 146228, 146231, 146234, 146237, + 146240, 146243, 146246, 146249, 146252, 146255, 146258, 146261, 146264, + 146267, 146270, 146273, 146276, 146279, 146282, 146285, 146288, 146291, + 146294, 146297, 146300, 146303, 146306, 146309, 146312, 146315, 146318, + 146321, 146324, 146327, 146330, 146333, 146336, 146339, 146342, 146345, + 146348, 146351, 146354, 146357, 146360, 146363, 146366, 146369, 146372, + 146375, 146378, 146381, 146384, 146387, 146390, 146393, 146396, 146399, + 146402, 146405, 146408, 146411, 146414, 146417, 146420, 146423, 146426, + 146429, 146432, 146435, 146438, 146441, 146444, 146447, 146450, 146453, + 146456, 146459, 146462, 146465, 146468, 146471, 146474, 146477, 146482, + 146487, 146492, 146497, 146502, 146507, 146512, 146517, 146522, 146527, + 146532, 146537, 146542, 146547, 146552, 146557, 146562, 146567, 146572, + 146577, 146582, 146587, 146592, 146597, 146602, 146607, 146612, 146617, + 146622, 146627, 146632, 146637, 146642, 146647, 146652, 146657, 146662, + 146667, 146672, 146677, 146682, 146687, 146692, 146697, 146702, 146707, + 146712, 146717, 146722, 146727, 146732, 146737, 146742, 146747, 146752, + 146757, 146762, 146767, 146772, 146777, 146782, 146787, 146792, 146797, + 146802, 146807, 146812, 146817, 146822, 146827, 146832, 146837, 146842, + 146847, 146852, 146857, 146862, 146867, 146872, 146877, 146882, 146887, + 146892, 146897, 146902, 146907, 146912, 146917, 146922, 146927, 146932, + 146937, 146942, 146947, 146952, 146957, 146962, 146967, 146972, 146977, + 146982, 146987, 146992, 146997, 147002, 147007, 147012, 147017, 147022, + 147027, 147032, 147037, 147042, 147047, 147052, 147057, 147062, 147067, + 147072, 147077, 147082, 147087, 147092, 147097, 147102, 147107, 147112, + 147117, 147122, 147127, 147132, 147137, 147142, 147147, 147152, 147157, + 147162, 147167, 147172, 147177, 147182, 147187, 147192, 147197, 147202, + 147207, 147212, 147217, 147222, 147227, 147232, 147237, 147242, 147247, + 147252, 147257, 147262, 147267, 147272, 147277, 147282, 147287, 147292, + 147297, 147302, 147307, 147312, 147317, 147322, 147327, 147332, 147337, + 147342, 147347, 147352, 147357, 147362, 147367, 147372, 147377, 147382, + 147387, 147392, 147397, 147402, 147407, 147412, 147417, 147422, 147427, + 147432, 147437, 147442, 147447, 147452, 147457, 147462, 147467, 147472, + 147477, 147482, 147487, 147492, 147497, 147502, 147507, 147512, 147517, + 147522, 147527, 147532, 147537, 147542, 147547, 147552, 147557, 147562, + 147567, 147572, 147577, 147582, 147587, 147592, 147597, 147602, 147607, + 147612, 147617, 147622, 147627, 147632, 147637, 147642, 147647, 147652, + 147657, 147662, 147667, 147672, 147677, 147682, 147687, 147692, 147697, + 147702, 147707, 147712, 147717, 147722, 147727, 147732, 147737, 147742, + 147747, 147752, 147757, 147762, 147767, 147772, 147777, 147782, 147787, + 147792, 147797, 147802, 147807, 147812, 147817, 147822, 147827, 147832, + 147837, 147842, 147847, 147852, 147857, 147862, 147867, 147872, 147877, + 147882, 147887, 147892, 147897, 147902, 147907, 147912, 147917, 147922, + 147927, 147932, 147937, 147942, 147947, 147952, 147957, 147962, 147967, + 147972, 147977, 147982, 147987, 147992, 147997, 148002, 148007, 148012, + 148017, 148022, 148027, 148032, 148037, 148042, 148047, 148052, 148057, + 148062, 148067, 148072, 148077, 148082, 148087, 148092, 148097, 148102, + 148107, 148112, 148117, 148122, 148127, 148132, 148137, 148142, 148147, + 148152, 148157, 148162, 148167, 148172, 148177, 148182, 148187, 148192, + 148197, 148202, 148207, 148212, 148217, 148222, 148227, 148232, 148237, + 148242, 148247, 148252, 148257, 148262, 148267, 148272, 148277, 148282, + 148287, 148292, 148297, 148302, 148307, 148312, 148317, 148322, 148327, + 148332, 148337, 148342, 148347, 148352, 148357, 148362, 148367, 148372, + 148377, 148382, 148387, 148392, 148397, 148402, 148407, 148412, 148417, + 148422, 148427, 148432, 148437, 148442, 148447, 148452, 148457, 148462, + 148467, 148472, 148477, 148482, 148487, 148492, 148497, 148502, 148507, + 148512, 148517, 148522, 148527, 148532, 148537, 148542, 148547, 148552, + 148557, 148562, 148567, 148572, 148577, 148582, 148587, 148592, 148597, + 148602, 148607, 148612, 148617, 148622, 148627, 148632, 148637, 148642, + 148647, 148652, 148657, 148662, 148667, 148672, 148677, 148682, 148687, + 148692, 148697, 148702, 148707, 148712, 148717, 148722, 148727, 148732, + 148737, 148742, 148747, 148752, 148757, 148762, 148767, 148772, 148777, + 148782, 148787, 148792, 148797, 148802, 148807, 148812, 148817, 148822, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148827, 148833, 148839, 148845, 0, 148851, + 148857, 148863, 148871, 148879, 148887, 148895, 0, 148903, 148911, 0, + 148919, 148924, 148931, 148935, 148939, 148943, 148947, 148951, 148955, + 148959, 148963, 148967, 148971, 148975, 148979, 148983, 148987, 148991, + 148995, 148999, 149003, 149007, 149011, 149015, 149019, 149023, 149027, + 149031, 149035, 149039, 149043, 149047, 149051, 149055, 149059, 149063, + 149067, 149071, 149075, 149079, 149083, 149087, 149091, 149095, 149099, + 149103, 149107, 149111, 149115, 149119, 149123, 149127, 149131, 149135, + 149139, 149143, 149147, 149151, 149155, 149159, 149163, 149167, 149171, + 149175, 149179, 149183, 149187, 149191, 149195, 149199, 149203, 149207, + 149211, 149215, 149219, 149223, 149227, 149231, 149235, 149239, 149243, + 149247, 149251, 149255, 149259, 149263, 149267, 149271, 149275, 149279, + 149283, 149287, 149291, 149295, 149299, 149303, 149307, 149311, 149315, + 149319, 149323, 149327, 149331, 149335, 149339, 149343, 149347, 149351, + 149355, 149359, 149363, 149367, 149371, 149375, 149379, 149383, 149387, + 149391, 149395, 149399, 149403, 149407, 149411, 149415, 149419, 149423, + 149427, 149431, 149435, 149439, 149443, 149447, 149451, 149455, 149459, + 149463, 149467, 149471, 149475, 149479, 149483, 149487, 149491, 149495, + 149499, 149503, 149507, 149511, 149515, 149519, 149523, 149527, 149531, + 149535, 149539, 149543, 149547, 149551, 149555, 149559, 149563, 149567, + 149571, 149575, 149579, 149583, 149587, 149591, 149595, 149599, 149603, + 149607, 149611, 149615, 149619, 149623, 149627, 149631, 149635, 149639, + 149643, 149647, 149651, 149655, 149659, 149663, 149667, 149671, 149675, + 149679, 149683, 149687, 149691, 149695, 149699, 149703, 149707, 149711, + 149715, 149719, 149723, 149727, 149731, 149735, 149739, 149743, 149747, + 149751, 149755, 149759, 149763, 149767, 149771, 149775, 149779, 149783, + 149787, 149791, 149795, 149799, 149803, 149807, 149811, 149815, 149819, + 149823, 149827, 149831, 149835, 149839, 149843, 149847, 149851, 149855, + 149859, 149863, 149867, 149871, 149875, 149879, 149883, 149887, 149891, + 149895, 149899, 149903, 149907, 149911, 149915, 149919, 149923, 149927, + 149931, 149935, 149939, 149943, 149947, 149951, 149955, 149959, 149963, + 149967, 149971, 149975, 149979, 149983, 149987, 149991, 149995, 149999, + 150003, 150007, 150011, 150015, 150019, 150023, 150027, 150031, 150035, + 150039, 150043, 150047, 150051, 150055, 150059, 150063, 150067, 150071, + 150078, 150084, 150090, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 150096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 150102, 150108, 150114, 0, 0, 150120, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 150125, 150130, 150135, 150140, 0, 0, 0, 0, 0, + 0, 0, 0, 150145, 150148, 150151, 150154, 150157, 150160, 150163, 150166, + 150169, 150172, 150175, 150178, 150181, 150184, 150187, 150190, 150193, + 150196, 150199, 150202, 150205, 150208, 150211, 150214, 150217, 150220, + 150223, 150226, 150229, 150232, 150235, 150238, 150241, 150244, 150247, + 150250, 150253, 150256, 150259, 150262, 150265, 150268, 150271, 150274, + 150277, 150280, 150283, 150286, 150289, 150292, 150295, 150298, 150301, + 150304, 150307, 150310, 150313, 150316, 150319, 150322, 150325, 150328, + 150331, 150334, 150337, 150340, 150343, 150346, 150349, 150352, 150355, + 150358, 150361, 150364, 150367, 150370, 150373, 150376, 150379, 150382, + 150385, 150388, 150391, 150394, 150397, 150400, 150403, 150406, 150409, + 150412, 150415, 150418, 150421, 150424, 150427, 150430, 150433, 150436, + 150439, 150442, 150445, 150448, 150451, 150454, 150457, 150460, 150463, + 150466, 150469, 150472, 150475, 150478, 150481, 150484, 150487, 150490, + 150493, 150496, 150499, 150502, 150505, 150508, 150511, 150514, 150517, + 150520, 150523, 150526, 150529, 150532, 150535, 150538, 150541, 150544, + 150547, 150550, 150553, 150556, 150559, 150562, 150565, 150568, 150571, + 150574, 150577, 150580, 150583, 150586, 150589, 150592, 150595, 150598, + 150601, 150604, 150607, 150610, 150613, 150616, 150619, 150622, 150625, + 150628, 150631, 150634, 150637, 150640, 150643, 150646, 150649, 150652, + 150655, 150658, 150661, 150664, 150667, 150670, 150673, 150676, 150679, + 150682, 150685, 150688, 150691, 150694, 150697, 150700, 150703, 150706, + 150709, 150712, 150715, 150718, 150721, 150724, 150727, 150730, 150733, + 150736, 150739, 150742, 150745, 150748, 150751, 150754, 150757, 150760, + 150763, 150766, 150769, 150772, 150775, 150778, 150781, 150784, 150787, + 150790, 150793, 150796, 150799, 150802, 150805, 150808, 150811, 150814, + 150817, 150820, 150823, 150826, 150829, 150832, 150835, 150838, 150841, + 150844, 150847, 150850, 150853, 150856, 150859, 150862, 150865, 150868, + 150871, 150874, 150877, 150880, 150883, 150886, 150889, 150892, 150895, + 150898, 150901, 150904, 150907, 150910, 150913, 150916, 150919, 150922, + 150925, 150928, 150931, 150934, 150937, 150940, 150943, 150946, 150949, + 150952, 150955, 150958, 150961, 150964, 150967, 150970, 150973, 150976, + 150979, 150982, 150985, 150988, 150991, 150994, 150997, 151000, 151003, + 151006, 151009, 151012, 151015, 151018, 151021, 151024, 151027, 151030, + 151033, 151036, 151039, 151042, 151045, 151048, 151051, 151054, 151057, + 151060, 151063, 151066, 151069, 151072, 151075, 151078, 151081, 151084, + 151087, 151090, 151093, 151096, 151099, 151102, 151105, 151108, 151111, + 151114, 151117, 151120, 151123, 151126, 151129, 151132, 151135, 151138, + 151141, 151144, 151147, 151150, 151153, 151156, 151159, 151162, 151165, + 151168, 151171, 151174, 151177, 151180, 151183, 151186, 151189, 151192, + 151195, 151198, 151201, 151204, 151207, 151210, 151213, 151216, 151219, + 151222, 151225, 151228, 151231, 151234, 151237, 151240, 151243, 151246, + 151249, 151252, 151255, 151258, 151261, 151264, 151267, 151270, 151273, + 151276, 151279, 151282, 151285, 151288, 151291, 151294, 151297, 151300, + 151303, 151306, 151309, 151312, 151315, 151318, 151321, 151324, 151327, + 151330, 0, 0, 0, 0, 151333, 151337, 151341, 151345, 151349, 151353, + 151357, 151360, 151364, 151368, 151372, 151376, 151379, 151385, 151391, + 151397, 151403, 151409, 151413, 151419, 151423, 151427, 151433, 151437, + 151441, 151445, 151449, 151453, 151457, 151461, 151467, 151473, 151479, + 151485, 151492, 151499, 151506, 151516, 151523, 151530, 151536, 151542, + 151548, 151554, 151562, 151570, 151578, 151586, 151595, 151601, 151609, + 151615, 151622, 151628, 151635, 151641, 151649, 151653, 151657, 151662, + 151668, 151674, 151682, 151690, 151696, 151703, 151706, 151712, 151716, + 151719, 151723, 151726, 151729, 151733, 151738, 151742, 151746, 151752, + 151757, 151763, 151767, 151771, 151774, 151778, 151782, 151787, 151791, + 151796, 151800, 151805, 151809, 151813, 151817, 151821, 151825, 151829, + 151833, 151837, 151842, 151847, 151852, 151857, 151863, 151869, 151875, + 151881, 151887, 0, 0, 0, 0, 0, 151892, 151900, 151909, 151917, 151924, + 151932, 151939, 151946, 151955, 151962, 151969, 151977, 151985, 0, 0, 0, + 151993, 151999, 152007, 152013, 152020, 152026, 152032, 152038, 152044, + 0, 0, 0, 0, 0, 0, 0, 152050, 152056, 152064, 152070, 152077, 152083, + 152089, 152095, 152101, 152107, 0, 0, 152112, 152118, 152124, 152127, + 152136, 152143, 152151, 152158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 152165, 152180, 152193, 152202, 152213, 152222, 152231, + 152242, 152251, 152260, 152275, 152288, 152301, 152315, 152327, 152335, + 152345, 152353, 152361, 152371, 152379, 152387, 152401, 152413, 152425, + 152434, 152445, 152454, 152463, 152470, 152479, 152488, 152495, 152500, + 152505, 152510, 152515, 152520, 152525, 152530, 152535, 152540, 152545, + 152550, 152555, 152560, 0, 0, 152569, 152578, 152587, 152596, 152601, + 152608, 152613, 152618, 152626, 152631, 152638, 152643, 152650, 152655, + 152660, 152667, 152674, 152679, 152688, 152694, 152700, 152708, 152714, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 152720, 152724, 152730, 152734, 152742, + 152746, 152750, 152754, 152762, 152766, 152772, 152781, 152785, 152789, + 152793, 152799, 152805, 152811, 152817, 152823, 152829, 152835, 152841, + 152847, 152855, 152863, 152871, 152879, 152884, 152890, 152894, 152898, + 152902, 152906, 152912, 152918, 152924, 152930, 152936, 152944, 152950, + 152958, 152966, 152974, 152982, 152990, 152994, 153002, 153008, 153016, + 153020, 153024, 153028, 153032, 153036, 153040, 153048, 153056, 153068, + 153080, 153086, 153096, 153104, 153114, 153126, 153130, 153136, 153142, + 153148, 153154, 153160, 153166, 153172, 153178, 153184, 153192, 153198, + 153204, 153210, 153218, 153226, 153237, 153248, 153254, 153260, 153270, + 153276, 153284, 153288, 153294, 153300, 153306, 153312, 153318, 153324, + 153330, 153334, 153340, 153346, 153354, 153362, 153370, 153376, 153384, + 153397, 153410, 153418, 153426, 153438, 153446, 153456, 153464, 153468, + 153472, 153476, 153480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153484, + 153489, 153494, 153499, 153506, 153513, 153520, 153527, 153532, 153537, + 153542, 153547, 153554, 153559, 153566, 153573, 153578, 153583, 153588, + 153595, 153600, 153605, 153612, 153619, 153624, 153629, 153634, 153641, + 153648, 153655, 153660, 153665, 153672, 153679, 153686, 153693, 153698, + 153703, 153708, 153715, 153720, 153725, 153730, 153737, 153746, 153753, + 153758, 153763, 153768, 153773, 153778, 153783, 153792, 153799, 153804, + 153811, 153818, 153823, 153828, 153833, 153840, 153845, 153852, 153859, + 153864, 153869, 153874, 153881, 153888, 153893, 153898, 153905, 153912, + 153919, 153924, 153929, 153934, 153939, 153946, 153955, 153964, 153969, + 153976, 153985, 153990, 153995, 154000, 154005, 154012, 154019, 154026, + 154033, 154038, 154043, 154048, 154055, 154062, 154069, 154074, 154079, + 154086, 154091, 154098, 154103, 154110, 154115, 154122, 154129, 154134, + 154139, 154144, 154149, 154154, 154159, 154164, 154169, 154174, 154181, + 154188, 154195, 154202, 154209, 154218, 154223, 154228, 154235, 154242, + 154247, 154254, 154261, 154268, 154275, 154282, 154289, 154294, 154299, + 154304, 154309, 154314, 154323, 154332, 154341, 154350, 154359, 154368, + 154377, 154386, 154391, 154402, 154413, 154422, 154427, 154432, 154437, + 154442, 154451, 154458, 154465, 154472, 154479, 154486, 154493, 154502, + 154511, 154522, 154531, 154542, 154551, 154558, 154567, 154578, 154587, + 154596, 154605, 154614, 154621, 154628, 154635, 154644, 154653, 154664, + 154673, 154682, 154693, 154698, 154703, 154714, 154722, 154731, 154740, + 154749, 154760, 154769, 154778, 154789, 154800, 154811, 154822, 154833, + 154844, 154851, 154858, 154865, 154872, 154883, 154892, 154899, 154906, + 154913, 154924, 154935, 154946, 154957, 154968, 154979, 154990, 155001, + 155008, 155015, 155024, 155033, 155040, 155047, 155054, 155063, 155072, + 155081, 155088, 155097, 155106, 155115, 155122, 155129, 155134, 155140, + 155147, 155154, 155161, 155168, 155175, 155182, 155191, 155200, 155209, + 155218, 155225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155234, 155240, 155245, + 155250, 155257, 155263, 155269, 155275, 155281, 155287, 155293, 155299, + 155303, 155307, 155313, 155319, 155325, 155329, 155334, 155339, 155343, + 155347, 155351, 155357, 155363, 155369, 155375, 155381, 155387, 155393, + 155399, 155405, 155415, 155425, 155431, 155437, 155447, 155457, 155463, + 0, 0, 155469, 155477, 155482, 155487, 155493, 155499, 155505, 155511, + 155517, 155523, 155530, 155537, 155543, 155549, 155555, 155561, 155567, + 155573, 155579, 155585, 155590, 155596, 155602, 155608, 155614, 155620, + 155629, 155635, 155640, 155648, 155655, 155662, 155671, 155680, 155689, + 155698, 155707, 155716, 155725, 155734, 155744, 155754, 155762, 155770, + 155779, 155788, 155794, 155800, 155806, 155812, 155820, 155828, 155832, + 155838, 155843, 155849, 155855, 155861, 155867, 155873, 155882, 155887, + 155894, 155899, 155904, 155909, 155915, 155921, 155927, 155934, 155939, + 155944, 155949, 155954, 155959, 155965, 155971, 155977, 155983, 155989, + 155995, 156001, 156007, 156012, 156017, 156022, 156027, 156032, 156037, + 156042, 156047, 156053, 156059, 156064, 156069, 156074, 156079, 156084, + 156090, 156097, 156101, 156105, 156109, 156113, 156117, 156121, 156125, + 156129, 156137, 156147, 156151, 156155, 156161, 156167, 156173, 156179, + 156185, 156191, 156197, 156203, 156209, 156215, 156221, 156227, 156233, + 156239, 156243, 156247, 156254, 156260, 156266, 156272, 156277, 156284, + 156289, 156295, 156301, 156307, 156313, 156318, 156322, 156328, 156332, + 156336, 156340, 156346, 156352, 156356, 156362, 156368, 156374, 156380, + 156386, 156394, 156402, 156408, 156414, 156420, 156426, 156438, 156450, + 156464, 156476, 156488, 156502, 156516, 156530, 156534, 156542, 156550, + 156555, 156559, 156563, 156567, 156571, 156575, 156579, 156583, 156589, + 156595, 156601, 156607, 156615, 156624, 156631, 156638, 156646, 156653, + 156665, 156677, 156689, 156701, 156708, 156712, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156716, 156723, 156730, 156737, + 156744, 156751, 156758, 156765, 156772, 156779, 156786, 156793, 156800, + 156807, 156814, 156821, 156828, 156835, 156842, 156849, 156856, 156863, + 156870, 156877, 156884, 156891, 156898, 156905, 156912, 156919, 156926, + 156933, 156940, 156947, 156954, 156961, 156968, 156975, 156982, 156989, + 156996, 157003, 157010, 157017, 157024, 157031, 157038, 157045, 157052, + 157059, 157066, 157073, 157080, 157087, 157094, 157101, 157108, 157115, + 157122, 157129, 157136, 157143, 157150, 157157, 157164, 157171, 157178, + 157183, 157188, 157193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157197, 157203, 157208, 157213, 157218, + 157223, 157228, 157233, 157238, 157243, 157248, 157254, 157260, 157266, + 157272, 157278, 157284, 157290, 157296, 157302, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 157308, 157314, 157319, 157324, 157329, 157334, 157339, + 157344, 157349, 157354, 157359, 157365, 157371, 157377, 157383, 157389, + 157395, 157401, 157407, 157413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 157419, 157424, 157431, 157438, 157445, 157452, 157457, 157462, 157469, + 157474, 157479, 157486, 157491, 157496, 157501, 157508, 157517, 157522, + 157527, 157532, 157537, 157542, 157547, 157554, 157559, 157564, 157569, + 157574, 157579, 157584, 157589, 157594, 157599, 157604, 157609, 157614, + 157620, 157625, 157630, 157635, 157640, 157645, 157650, 157655, 157660, + 157665, 157674, 157679, 157687, 157692, 157697, 157702, 157707, 157712, + 157717, 157722, 157731, 157736, 157741, 157746, 157751, 157756, 157763, + 157768, 157775, 157780, 157785, 157790, 157795, 157800, 157805, 157810, + 157815, 157820, 157825, 157830, 157835, 157840, 157845, 157850, 157855, + 157860, 157865, 157870, 157879, 157884, 157889, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 157894, 157902, 157910, 157918, 157926, 157934, 157942, 157950, + 157958, 157966, 157974, 157982, 157990, 157998, 158006, 158014, 158022, + 158030, 158038, 158043, 158048, 158053, 158058, 158063, 158067, 0, 0, 0, + 0, 0, 0, 0, 158071, 158075, 158080, 158085, 158090, 158094, 158099, + 158104, 158109, 158113, 158118, 158123, 158127, 158132, 158137, 158141, + 158146, 158151, 158155, 158160, 158165, 158169, 158174, 158179, 158184, + 158189, 158194, 158198, 158203, 158208, 158213, 158217, 158222, 158227, + 158232, 158236, 158241, 158246, 158250, 158255, 158260, 158264, 158269, + 158274, 158278, 158283, 158288, 158292, 158297, 158302, 158307, 158312, + 158317, 158321, 158326, 158331, 158336, 158340, 158345, 158350, 158355, + 158359, 158364, 158369, 158373, 158378, 158383, 158387, 158392, 158397, + 158401, 158406, 158411, 158415, 158420, 158425, 158430, 158435, 158440, + 158444, 158449, 158454, 158459, 158463, 158468, 0, 158473, 158477, + 158482, 158487, 158491, 158496, 158501, 158505, 158510, 158515, 158519, + 158524, 158529, 158533, 158538, 158543, 158548, 158553, 158558, 158563, + 158569, 158575, 158581, 158586, 158592, 158598, 158604, 158609, 158615, + 158621, 158626, 158632, 158638, 158643, 158649, 158655, 158660, 158666, + 158672, 158677, 158683, 158689, 158695, 158701, 158707, 158712, 158718, + 158724, 158730, 158735, 158741, 158747, 158753, 158758, 158764, 158770, + 158775, 158781, 158787, 158792, 158798, 158804, 158809, 158815, 158821, + 158826, 158832, 158838, 158844, 158850, 158856, 0, 158860, 158865, 0, 0, + 158870, 0, 0, 158875, 158880, 0, 0, 158885, 158890, 158894, 158899, 0, + 158904, 158909, 158914, 158918, 158923, 158928, 158933, 158938, 158943, + 158947, 158952, 158957, 0, 158962, 0, 158967, 158972, 158976, 158981, + 158986, 158990, 158995, 0, 159000, 159005, 159010, 159014, 159019, + 159024, 159028, 159033, 159038, 159043, 159048, 159053, 159058, 159064, + 159070, 159076, 159081, 159087, 159093, 159099, 159104, 159110, 159116, + 159121, 159127, 159133, 159138, 159144, 159150, 159155, 159161, 159167, + 159172, 159178, 159184, 159190, 159196, 159202, 159207, 159213, 159219, + 159225, 159230, 159236, 159242, 159248, 159253, 159259, 159265, 159270, + 159276, 159282, 159287, 159293, 159299, 159304, 159310, 159316, 159321, + 159327, 159333, 159339, 159345, 159351, 159356, 0, 159362, 159368, + 159373, 159379, 0, 0, 159385, 159391, 159397, 159402, 159408, 159414, + 159419, 159425, 0, 159431, 159437, 159443, 159448, 159454, 159460, + 159466, 0, 159472, 159477, 159483, 159489, 159495, 159500, 159506, + 159512, 159518, 159523, 159529, 159535, 159540, 159546, 159552, 159557, + 159563, 159569, 159574, 159580, 159586, 159591, 159597, 159603, 159609, + 159615, 159621, 159626, 0, 159632, 159638, 159643, 159649, 0, 159655, + 159660, 159666, 159672, 159677, 0, 159683, 0, 0, 0, 159688, 159694, + 159700, 159705, 159711, 159717, 159723, 0, 159729, 159734, 159740, + 159746, 159752, 159757, 159763, 159769, 159775, 159780, 159786, 159792, + 159797, 159803, 159809, 159814, 159820, 159826, 159831, 159837, 159843, + 159848, 159854, 159860, 159866, 159872, 159878, 159884, 159891, 159898, + 159905, 159911, 159918, 159925, 159932, 159938, 159945, 159952, 159958, + 159965, 159972, 159978, 159985, 159992, 159998, 160005, 160012, 160018, + 160025, 160032, 160039, 160046, 160053, 160059, 160066, 160073, 160080, + 160086, 160093, 160100, 160107, 160113, 160120, 160127, 160133, 160140, + 160147, 160153, 160160, 160167, 160173, 160180, 160187, 160193, 160200, + 160207, 160214, 160221, 160228, 160232, 160237, 160242, 160247, 160251, + 160256, 160261, 160266, 160270, 160275, 160280, 160284, 160289, 160294, + 160298, 160303, 160308, 160312, 160317, 160322, 160326, 160331, 160336, + 160341, 160346, 160351, 160355, 160360, 160365, 160370, 160374, 160379, + 160384, 160389, 160393, 160398, 160403, 160407, 160412, 160417, 160421, + 160426, 160431, 160435, 160440, 160445, 160449, 160454, 160459, 160464, + 160469, 160474, 160479, 160485, 160491, 160497, 160502, 160508, 160514, + 160520, 160525, 160531, 160537, 160542, 160548, 160554, 160559, 160565, + 160571, 160576, 160582, 160588, 160593, 160599, 160605, 160611, 160617, + 160623, 160628, 160634, 160640, 160646, 160651, 160657, 160663, 160669, + 160674, 160680, 160686, 160691, 160697, 160703, 160708, 160714, 160720, + 160725, 160731, 160737, 160742, 160748, 160754, 160760, 160766, 160772, + 160777, 160783, 160789, 160795, 160800, 160806, 160812, 160818, 160823, + 160829, 160835, 160840, 160846, 160852, 160857, 160863, 160869, 160874, + 160880, 160886, 160891, 160897, 160903, 160909, 160915, 160921, 160926, + 160932, 160938, 160944, 160949, 160955, 160961, 160967, 160972, 160978, + 160984, 160989, 160995, 161001, 161006, 161012, 161018, 161023, 161029, + 161035, 161040, 161046, 161052, 161058, 161064, 161070, 161076, 161083, + 161090, 161097, 161103, 161110, 161117, 161124, 161130, 161137, 161144, + 161150, 161157, 161164, 161170, 161177, 161184, 161190, 161197, 161204, + 161210, 161217, 161224, 161231, 161238, 161245, 161251, 161258, 161265, + 161272, 161278, 161285, 161292, 161299, 161305, 161312, 161319, 161325, + 161332, 161339, 161345, 161352, 161359, 161365, 161372, 161379, 161385, + 161392, 161399, 161406, 161413, 161420, 161425, 161431, 161437, 161443, + 161448, 161454, 161460, 161466, 161471, 161477, 161483, 161488, 161494, + 161500, 161505, 161511, 161517, 161522, 161528, 161534, 161539, 161545, + 161551, 161557, 161563, 161569, 161574, 161580, 161586, 161592, 161597, + 161603, 161609, 161615, 161620, 161626, 161632, 161637, 161643, 161649, + 161654, 161660, 161666, 161671, 161677, 161683, 161688, 161694, 161700, + 161706, 161712, 161718, 161724, 0, 0, 161731, 161736, 161741, 161746, + 161751, 161756, 161761, 161766, 161771, 161776, 161781, 161786, 161791, + 161796, 161801, 161806, 161811, 161816, 161822, 161827, 161832, 161837, + 161842, 161847, 161852, 161857, 161861, 161866, 161871, 161876, 161881, + 161886, 161891, 161896, 161901, 161906, 161911, 161916, 161921, 161926, + 161931, 161936, 161941, 161946, 161952, 161957, 161962, 161967, 161972, + 161977, 161982, 161987, 161993, 161998, 162003, 162008, 162013, 162018, + 162023, 162028, 162033, 162038, 162043, 162048, 162053, 162058, 162063, + 162068, 162073, 162078, 162083, 162088, 162093, 162098, 162103, 162108, + 162114, 162119, 162124, 162129, 162134, 162139, 162144, 162149, 162153, + 162158, 162163, 162168, 162173, 162178, 162183, 162188, 162193, 162198, + 162203, 162208, 162213, 162218, 162223, 162228, 162233, 162238, 162244, + 162249, 162254, 162259, 162264, 162269, 162274, 162279, 162285, 162290, + 162295, 162300, 162305, 162310, 162315, 162321, 162327, 162333, 162339, + 162345, 162351, 162357, 162363, 162369, 162375, 162381, 162387, 162393, + 162399, 162405, 162411, 162417, 162424, 162430, 162436, 162442, 162448, + 162454, 162460, 162466, 162471, 162477, 162483, 162489, 162495, 162501, + 162507, 162513, 162519, 162525, 162531, 162537, 162543, 162549, 162555, + 162561, 162567, 162573, 162580, 162586, 162592, 162598, 162604, 162610, + 162616, 162622, 162629, 162635, 162641, 162647, 162653, 162659, 162665, + 162671, 162677, 162683, 162689, 162695, 162701, 162707, 162713, 162719, + 162725, 162731, 162737, 162743, 162749, 162755, 162761, 162767, 162774, + 162780, 162786, 162792, 162798, 162804, 162810, 162816, 162821, 162827, + 162833, 162839, 162845, 162851, 162857, 162863, 162869, 162875, 162881, + 162887, 162893, 162899, 162905, 162911, 162917, 162923, 162930, 162936, + 162942, 162948, 162954, 162960, 162966, 162972, 162979, 162985, 162991, + 162997, 163003, 163009, 163015, 163022, 163029, 163036, 163043, 163050, + 163057, 163064, 163071, 163078, 163085, 163092, 163099, 163106, 163113, + 163120, 163127, 163134, 163142, 163149, 163156, 163163, 163170, 163177, + 163184, 163191, 163197, 163204, 163211, 163218, 163225, 163232, 163239, + 163246, 163253, 163260, 163267, 163274, 163281, 163288, 163295, 163302, + 163309, 163316, 163324, 163331, 163338, 163345, 163352, 163359, 163366, + 163373, 163381, 163388, 163395, 163402, 163409, 163416, 163423, 163428, + 0, 0, 163433, 163438, 163442, 163446, 163450, 163454, 163458, 163462, + 163466, 163470, 163474, 163480, 163485, 163490, 163495, 163500, 163505, + 163510, 163515, 163520, 163525, 163530, 163534, 163538, 163542, 163546, + 163550, 163554, 163558, 163562, 163566, 163572, 163577, 163582, 163587, + 163592, 163597, 163602, 163607, 163612, 163617, 163623, 163628, 163633, + 163638, 163643, 163648, 163653, 163658, 163663, 163668, 163672, 163677, + 163682, 163687, 163692, 163697, 163702, 163708, 163716, 163723, 163728, + 163733, 163740, 163746, 163751, 163757, 163763, 163771, 163777, 163784, + 163792, 163798, 163807, 163816, 163824, 163832, 163838, 163845, 163853, + 163861, 163867, 163874, 163883, 163892, 163899, 163910, 163920, 163930, + 163940, 163950, 163957, 163964, 163971, 163978, 163987, 163996, 164007, + 164018, 164027, 164036, 164047, 164056, 164065, 164076, 164085, 164094, + 164102, 164110, 164121, 164132, 164140, 164149, 164158, 164165, 164176, + 164187, 164196, 164205, 164212, 164221, 164230, 164239, 164250, 164259, + 164269, 164278, 164287, 164298, 164311, 164326, 164337, 164350, 164362, + 164371, 164382, 164393, 164402, 164413, 164427, 164442, 164445, 164454, + 164459, 164465, 164473, 164479, 164485, 164494, 164501, 164511, 164523, + 164530, 164533, 164539, 164546, 164552, 164557, 164560, 164565, 164568, + 164576, 164582, 164591, 164598, 164606, 164612, 164617, 164620, 164623, + 164626, 164632, 164639, 164645, 164650, 164658, 164661, 164666, 164674, + 164680, 164689, 164696, 164706, 164715, 164718, 164724, 164731, 164738, + 164745, 164750, 164758, 164766, 164775, 164781, 164790, 164799, 164808, + 164814, 164823, 164830, 164837, 164844, 164852, 164858, 164866, 164872, + 164879, 164886, 164894, 164905, 164915, 164921, 164928, 164935, 164942, + 164948, 164955, 164962, 164967, 164974, 164982, 164991, 164997, 165009, + 165020, 165026, 165034, 165040, 165047, 165054, 165061, 165067, 165074, + 165083, 165089, 165095, 165102, 165109, 165117, 165127, 165137, 165147, + 165157, 165165, 165173, 165183, 165191, 165196, 165201, 165206, 165212, + 165219, 165226, 165232, 165238, 165243, 165250, 165258, 165268, 165276, + 165284, 165294, 165304, 165312, 165322, 165332, 165344, 165356, 165368, + 165378, 165384, 165390, 165397, 165406, 165415, 165424, 165433, 165443, + 165452, 165461, 165470, 165475, 165481, 165490, 165500, 165509, 165515, + 165521, 165528, 165535, 165542, 165548, 165555, 165562, 165569, 165575, + 165579, 165584, 165591, 165598, 165605, 165610, 165618, 165626, 165635, + 165643, 165650, 165658, 165667, 165677, 165680, 165684, 165689, 165694, + 165699, 165704, 165709, 165714, 165719, 165724, 165729, 165734, 165739, + 165744, 165749, 165754, 165759, 165764, 165769, 165776, 165782, 165789, + 165795, 165800, 165807, 165813, 165820, 165826, 165831, 165838, 165845, + 165852, 165858, 165864, 165873, 165882, 165892, 165899, 165906, 165915, + 165924, 165933, 165942, 165951, 165957, 165965, 165971, 165981, 165986, + 165995, 166004, 166011, 166022, 166029, 166036, 166043, 166050, 166057, + 166064, 166071, 166078, 166085, 166092, 166098, 166104, 166110, 166117, + 166124, 166131, 166138, 166145, 166152, 166159, 166166, 166173, 166180, + 166187, 166194, 166199, 166208, 166217, 166226, 166233, 166240, 166247, + 166254, 166261, 166268, 166275, 166282, 166291, 166300, 166309, 166318, + 166327, 166336, 166345, 166354, 166363, 166372, 166381, 166390, 166399, + 166405, 166413, 166419, 166429, 166434, 166443, 166452, 166461, 166472, + 166477, 166484, 166491, 166498, 166503, 166509, 166515, 166521, 166528, + 166535, 166542, 166549, 166556, 166563, 166570, 166577, 166584, 166591, + 166598, 166605, 166610, 166619, 166628, 166637, 166646, 166655, 166664, + 166673, 166682, 166693, 166704, 166711, 166718, 166725, 166732, 166739, + 166746, 166754, 166764, 166774, 166784, 166795, 166806, 166817, 166826, + 166835, 166844, 166849, 166854, 166859, 166864, 166875, 166886, 166897, + 166908, 166919, 166929, 166940, 166949, 166958, 166967, 166976, 166985, + 166993, 167002, 167013, 167024, 167035, 167046, 167057, 167069, 167082, + 167094, 167107, 167119, 167132, 167144, 167157, 167168, 167179, 167188, + 167196, 167205, 167216, 167227, 167239, 167252, 167266, 167281, 167293, + 167306, 167318, 167331, 167342, 167353, 167362, 167370, 167379, 167386, + 167393, 167400, 167407, 167414, 167421, 167428, 167435, 167442, 167449, + 167454, 167459, 167464, 167471, 167481, 167492, 167502, 167513, 167527, + 167542, 167557, 167571, 167586, 167601, 167612, 167623, 167636, 167649, + 167658, 167667, 167680, 167693, 167700, 167707, 167712, 167717, 167722, + 167727, 167732, 167739, 167748, 167753, 167756, 167761, 167768, 167775, + 167782, 167789, 167796, 167803, 167816, 167830, 167845, 167852, 167859, + 167866, 167875, 167883, 167891, 167900, 167905, 167910, 167915, 167920, + 167925, 167930, 167937, 167944, 167950, 167957, 167963, 167970, 167975, + 167980, 167985, 167990, 167995, 168002, 168009, 168014, 168021, 168028, + 168033, 168038, 168043, 168048, 168053, 168058, 168065, 168072, 168079, + 168082, 168087, 168092, 168097, 168102, 168109, 168116, 168124, 168132, + 168137, 168142, 168149, 168156, 168163, 168168, 168175, 168182, 168187, + 168194, 168201, 168208, 168215, 168222, 168229, 168238, 168247, 168254, + 168263, 168272, 168277, 168284, 168291, 168296, 168303, 168310, 168317, + 168324, 168331, 168336, 168343, 168350, 168359, 168366, 168375, 168386, + 168395, 168404, 168413, 168422, 168425, 168430, 168437, 168446, 168453, + 168462, 168469, 168474, 168479, 168482, 168485, 168488, 168495, 168502, + 168511, 168520, 168529, 168536, 168543, 168548, 168560, 168565, 168570, + 168575, 168580, 168585, 168590, 168595, 168600, 168603, 168608, 168613, + 168618, 168623, 168628, 168635, 168640, 168647, 168650, 168655, 168658, + 168661, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168664, 168669, + 168674, 168679, 168684, 0, 168689, 168694, 168699, 168704, 168709, + 168714, 168719, 168724, 168729, 168734, 168739, 168744, 168749, 168754, + 168759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168764, 168774, 168782, 168789, 168796, + 168805, 168814, 168823, 168830, 168844, 168856, 168866, 168874, 168886, + 168895, 168906, 168915, 168922, 168930, 168941, 168953, 168962, 168972, + 168984, 168995, 169004, 169015, 169027, 169035, 169046, 169055, 0, 0, 0, + 0, 0, 0, 169063, 169073, 169083, 169093, 169103, 169113, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 169123, 169128, 169133, 169138, 169143, 169148, + 169153, 0, 169158, 169163, 169168, 169174, 169178, 169183, 169188, + 169193, 169198, 169203, 169208, 169213, 169218, 169223, 169228, 169233, + 169238, 0, 0, 169243, 169248, 169253, 169258, 169263, 169268, 169273, 0, + 169278, 169283, 0, 169289, 169294, 169302, 169309, 169318, 0, 0, 0, 0, 0, + 169323, 169328, 169334, 169340, 169346, 169352, 169358, 169364, 169370, + 169375, 169380, 169386, 169392, 169397, 169403, 169409, 169415, 169421, + 169426, 169432, 169437, 169443, 169449, 169455, 169461, 169466, 169472, + 169478, 169484, 169491, 169497, 169504, 169511, 169517, 169523, 169530, + 169537, 169544, 169551, 169558, 169565, 169572, 169578, 169584, 169591, + 169597, 169604, 169611, 169617, 169624, 169630, 169637, 169644, 169651, + 169659, 169666, 169676, 169684, 169691, 169698, 169707, 169718, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 169727, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 169734, 169741, 169749, 169757, 169765, 169772, 169779, 169787, 169795, + 169803, 169810, 169817, 169825, 169833, 169841, 169848, 169856, 169864, + 169872, 169880, 169888, 169896, 169904, 169911, 169919, 169926, 169934, + 169941, 169949, 169957, 169965, 169973, 169981, 169989, 169997, 170005, + 170013, 170020, 170028, 170035, 170042, 170049, 170057, 170064, 170072, + 0, 0, 0, 170080, 170087, 170094, 170101, 170108, 170115, 170122, 170129, + 170138, 170147, 170156, 170165, 170174, 170184, 0, 0, 170192, 170200, + 170207, 170214, 170221, 170228, 170235, 170242, 170249, 170256, 0, 0, 0, + 0, 170263, 170272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170280, + 170284, 170289, 170294, 170299, 170303, 170308, 170312, 170316, 170321, + 170325, 170330, 170334, 170339, 170344, 170348, 170352, 170356, 170360, + 170366, 170371, 170378, 170382, 170386, 170392, 170397, 170404, 170408, + 170413, 170420, 170424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 170431, 170436, 170440, 170445, 170450, 170455, 170460, 170464, + 170469, 170473, 170477, 170481, 170486, 170491, 170496, 170500, 170505, + 170510, 170515, 170520, 170525, 170529, 170533, 170538, 170542, 170546, + 170551, 170555, 170559, 170563, 170568, 170572, 170577, 170582, 170587, + 170592, 170597, 170602, 170607, 170612, 170617, 170622, 170627, 170632, + 170637, 170642, 170647, 170652, 170657, 170662, 170666, 170670, 170674, + 170678, 170682, 170686, 170690, 170694, 0, 0, 0, 0, 0, 170698, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 170703, 170709, 170716, 170723, 170730, 170737, 170743, + 170750, 170757, 170764, 170771, 170777, 170784, 170791, 170798, 170805, + 170811, 170818, 170825, 170832, 170839, 170845, 170852, 170859, 170866, + 170873, 170880, 170887, 170894, 170901, 170908, 170915, 170922, 170929, + 170935, 170941, 170947, 170953, 170959, 170965, 170971, 170977, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 170983, 170987, 170991, 170995, 170999, 171003, 171007, 0, + 171011, 171017, 171021, 171025, 0, 171029, 171035, 0, 171041, 171047, + 171053, 171059, 171065, 171071, 171077, 171083, 171089, 171095, 171101, + 171107, 171113, 171119, 171125, 0, 171131, 171138, 171144, 171151, + 171158, 171165, 171172, 171179, 171186, 171193, 171200, 171207, 171214, + 171221, 171228, 171235, 171242, 171249, 171256, 171263, 171270, 171277, + 171284, 171291, 171298, 171305, 171312, 171319, 171326, 171333, 171340, + 171347, 171354, 171361, 171368, 171374, 171380, 171386, 171393, 171399, + 171406, 171412, 171419, 171426, 171433, 171440, 171447, 171454, 171460, + 171467, 171474, 171481, 171488, 171495, 171502, 171509, 171515, 171522, + 171529, 171536, 171543, 171550, 171558, 171565, 171572, 171579, 171586, + 171593, 171600, 171607, 171614, 171621, 171628, 171635, 171642, 171648, + 171655, 171662, 171669, 171676, 171683, 171690, 171697, 171705, 171712, + 171718, 171725, 171732, 171739, 171746, 171753, 171760, 171767, 171774, + 171781, 171788, 171795, 171802, 171809, 171816, 171823, 171830, 171837, + 171844, 171851, 171858, 171864, 171871, 171878, 171885, 171892, 171899, + 171906, 171913, 171920, 171927, 171934, 171941, 171948, 171955, 171962, + 171969, 171976, 171983, 171990, 171997, 172004, 172011, 172018, 172026, + 172034, 172042, 172049, 172056, 172063, 172070, 172077, 172084, 172091, + 172098, 172105, 172112, 172118, 172125, 172132, 172139, 172146, 172153, + 172160, 172167, 172174, 172181, 172188, 172195, 172202, 172209, 172216, + 172224, 172232, 172240, 172247, 172254, 172261, 172268, 172275, 172282, + 172289, 172296, 172303, 172310, 172317, 172324, 172331, 172338, 172344, + 172351, 172358, 172365, 172372, 172379, 172386, 172393, 172400, 172407, + 172414, 172421, 172428, 172435, 172442, 172449, 172456, 172463, 172470, + 172477, 172484, 172491, 172498, 0, 0, 172505, 172509, 172513, 172517, + 172521, 172525, 172529, 172533, 172537, 172541, 172547, 172553, 172559, + 172565, 172573, 172581, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 172587, 172593, 172599, 172605, 172611, 172617, 172623, 172629, + 172635, 172640, 172645, 172651, 172656, 172661, 172667, 172673, 172679, + 172685, 172691, 172696, 172701, 172707, 172713, 172718, 172724, 172730, + 172736, 172742, 172748, 172754, 172760, 172766, 172772, 172778, 172784, + 172790, 172796, 172802, 172808, 172814, 172820, 172826, 172832, 172837, + 172842, 172848, 172853, 172858, 172864, 172870, 172876, 172882, 172888, + 172893, 172898, 172904, 172910, 172915, 172921, 172927, 172933, 172939, + 172945, 172951, 172957, 172963, 172969, 172975, 172981, 172987, 172992, + 172997, 173001, 173006, 173013, 173017, 0, 0, 0, 0, 173022, 173027, + 173031, 173035, 173039, 173043, 173047, 173051, 173055, 173059, 0, 0, 0, + 0, 173063, 173069, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 173075, 173080, 173085, 173090, 173095, 173100, + 173105, 173110, 173115, 173120, 173126, 173132, 173138, 173144, 173150, + 173156, 173162, 173168, 173174, 173181, 173188, 173195, 173203, 173211, + 173219, 173227, 173235, 173243, 173249, 173255, 173261, 173268, 173275, + 173282, 173289, 173296, 173303, 173310, 173317, 173324, 173331, 173338, + 173345, 173352, 173359, 173366, 173372, 173378, 173384, 173390, 173396, + 173403, 173410, 173417, 173424, 173431, 173438, 173445, 173452, 173459, + 173464, 173472, 173480, 173488, 173494, 173501, 173508, 173517, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 173525, 173530, 173535, 173540, 173545, 173550, 173555, 173560, + 173565, 173570, 173576, 173582, 173588, 173594, 173600, 173606, 173612, + 173618, 173624, 173631, 173638, 173645, 173653, 173661, 173669, 173677, + 173685, 173693, 173699, 173705, 173711, 173718, 173725, 173732, 173739, + 173746, 173753, 173760, 173767, 173774, 173781, 173788, 173795, 173802, + 173809, 173816, 173821, 173828, 173835, 173842, 173849, 173856, 173863, + 173870, 173877, 173885, 173895, 173905, 173913, 173922, 173930, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173938, 173942, 173946, + 173950, 0, 173954, 173958, 173962, 173966, 173970, 173974, 173978, + 173982, 173986, 173990, 173994, 173998, 174002, 174006, 174010, 174014, + 174018, 174022, 174026, 174030, 174034, 174038, 174042, 174046, 174052, + 174058, 174064, 0, 174070, 174075, 0, 174080, 0, 0, 174085, 0, 174090, + 174095, 174100, 174105, 174110, 174115, 174120, 174125, 174130, 174135, + 0, 174140, 174145, 174150, 174155, 0, 174160, 0, 174165, 0, 0, 0, 0, 0, + 0, 174170, 0, 0, 0, 0, 174176, 0, 174182, 0, 174188, 0, 174194, 174200, + 174206, 0, 174212, 174218, 0, 174224, 0, 0, 174230, 0, 174236, 0, 174242, + 0, 174248, 0, 174256, 0, 174264, 174270, 0, 174276, 0, 0, 174282, 174288, + 174294, 174300, 0, 174306, 174312, 174318, 174324, 174330, 174336, + 174342, 0, 174348, 174354, 174360, 174366, 0, 174372, 174378, 174384, + 174390, 0, 174398, 0, 174406, 174412, 174418, 174424, 174430, 174436, + 174442, 174448, 174454, 174460, 0, 174466, 174472, 174478, 174484, + 174490, 174496, 174502, 174508, 174514, 174520, 174526, 174532, 174538, + 174544, 174550, 174556, 174562, 0, 0, 0, 0, 0, 174568, 174574, 174580, 0, + 174586, 174592, 174598, 174604, 174610, 0, 174616, 174622, 174628, + 174634, 174640, 174646, 174652, 174658, 174664, 174670, 174676, 174682, + 174688, 174694, 174700, 174706, 174712, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174718, 174728, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174736, 174743, 174750, 174757, + 174763, 174770, 174777, 174783, 174790, 174797, 174804, 174812, 174820, + 174828, 174836, 174844, 174852, 174859, 174866, 174873, 174881, 174889, + 174897, 174905, 174913, 174921, 174928, 174935, 174942, 174950, 174958, + 174966, 174974, 174982, 174990, 174995, 175000, 175005, 175010, 175015, + 175020, 175025, 175030, 175035, 0, 0, 0, 0, 175040, 175047, 175052, + 175057, 175062, 175067, 175072, 175077, 175082, 175087, 175092, 175097, + 175102, 175107, 175112, 175117, 175122, 175127, 175132, 175137, 175142, + 175147, 175152, 175157, 175162, 175167, 175172, 175177, 175182, 175187, + 175192, 175197, 175202, 175207, 175212, 175217, 175222, 175227, 175232, + 175237, 175242, 175247, 175252, 175257, 175262, 175267, 175272, 175277, + 175282, 175287, 175292, 175298, 175303, 175308, 175313, 175318, 175323, + 175328, 175333, 175338, 175343, 175348, 175353, 175358, 175363, 175368, + 175373, 175378, 175383, 175388, 175393, 175398, 175403, 175408, 175413, + 175418, 175423, 175428, 175433, 175438, 175443, 175448, 175453, 175458, + 175463, 175468, 175473, 175478, 175483, 175488, 175493, 175498, 175503, + 175508, 175513, 175518, 175523, 175528, 175533, 175538, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 175543, 175549, 175558, 175566, 175574, 175583, 175592, + 175601, 175610, 175619, 175628, 175637, 175646, 175655, 175664, 0, 0, + 175673, 175682, 175690, 175698, 175707, 175716, 175725, 175734, 175743, + 175752, 175761, 175770, 175779, 175788, 175797, 0, 175805, 175814, + 175822, 175830, 175839, 175848, 175857, 175866, 175875, 175884, 175893, + 175902, 175911, 175920, 175929, 0, 175936, 175945, 175953, 175961, + 175970, 175979, 175988, 175997, 176006, 176015, 176024, 176033, 176042, + 176051, 176060, 176067, 176073, 176079, 176085, 176091, 176097, 176103, + 176109, 176115, 176121, 176127, 176133, 176139, 176145, 176151, 176157, + 176163, 176169, 176175, 176181, 176187, 176193, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 176199, 176206, 176211, 176215, 176219, 176223, 176228, 176233, + 176238, 176243, 176248, 176253, 176260, 176269, 176275, 176279, 176288, + 176293, 176299, 176305, 176311, 176316, 176322, 176328, 176334, 176339, + 176345, 176351, 176356, 176362, 176368, 176373, 176379, 176385, 176390, + 176396, 176402, 176407, 176413, 176419, 176425, 176431, 176437, 176448, + 176455, 176461, 176464, 176467, 176470, 176475, 176481, 176487, 176493, + 176498, 176504, 176510, 176516, 176521, 176527, 176533, 176538, 176544, + 176550, 176555, 176561, 176567, 176572, 176578, 176584, 176589, 176595, + 176601, 176607, 176613, 176619, 176622, 176625, 176628, 176631, 176634, + 176637, 176644, 176652, 176660, 176668, 176675, 176683, 176691, 176699, + 176706, 176714, 176722, 176729, 176737, 176745, 176752, 176760, 176768, + 176775, 176783, 176791, 176798, 176806, 176814, 176822, 176830, 176838, + 176843, 176848, 176853, 176856, 176864, 176869, 176876, 176884, 176892, + 176900, 176907, 176915, 176923, 176931, 176938, 176946, 176954, 176961, + 176969, 176977, 176984, 176992, 177000, 177007, 177015, 177023, 177030, + 177038, 177046, 177054, 177062, 177070, 177080, 177085, 177089, 177093, + 177098, 177103, 177106, 177109, 177112, 177115, 177118, 177121, 177124, + 177127, 177130, 177136, 177139, 177143, 177148, 177152, 177157, 177162, + 177168, 177174, 177180, 177185, 177193, 177199, 177202, 177205, 177208, + 177211, 177214, 177217, 177220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177225, 177232, + 177240, 177248, 177256, 177263, 177271, 177279, 177287, 177294, 177302, + 177310, 177317, 177325, 177333, 177340, 177348, 177356, 177363, 177371, + 177379, 177386, 177394, 177402, 177410, 177418, 177426, 177431, 177435, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177438, 177444, 177450, 177456, + 177460, 177466, 177472, 177478, 177484, 177490, 177496, 177502, 177508, + 177514, 177520, 177526, 177532, 177538, 177544, 177550, 177556, 177562, + 177568, 177574, 177580, 177586, 177592, 177598, 177604, 177610, 177616, + 177622, 177628, 177634, 177640, 177646, 177652, 177658, 177664, 177670, + 177676, 177682, 177688, 177694, 0, 0, 0, 0, 177700, 177711, 177722, + 177733, 177744, 177755, 177766, 177777, 177788, 0, 0, 0, 0, 0, 0, 0, + 177799, 177804, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177809, 177815, + 177821, 177827, 177833, 177839, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177845, 177847, 177849, 177853, + 177858, 177863, 177865, 177871, 177876, 177878, 177884, 177888, 177890, + 177894, 177900, 177906, 177912, 177917, 177922, 177929, 177936, 177943, + 177948, 177955, 177962, 177969, 177973, 177980, 177989, 177998, 178005, + 178010, 178014, 178018, 178020, 178023, 178026, 178033, 178040, 178050, + 178055, 178060, 178065, 178070, 178072, 178078, 178082, 178084, 178086, + 178088, 178090, 178094, 178098, 178102, 178104, 178108, 178110, 178114, + 178116, 178118, 178120, 178122, 178127, 178132, 178134, 178140, 178144, + 178148, 178156, 178158, 178160, 178162, 178164, 178166, 178168, 178170, + 178172, 178174, 178176, 178180, 178184, 178186, 178188, 178190, 178192, + 178194, 178199, 178205, 178209, 178213, 178217, 178221, 178226, 178230, + 178232, 178234, 178238, 178244, 178246, 178248, 178250, 178254, 178263, + 178269, 178273, 178277, 178279, 178281, 178284, 178286, 178288, 178290, + 178294, 178296, 178300, 178305, 178307, 178312, 178318, 178325, 178329, + 178333, 178337, 178341, 178347, 178351, 178359, 178366, 178368, 178370, + 178374, 178378, 178380, 178384, 178388, 178390, 178394, 178396, 178400, + 178404, 178408, 178412, 178416, 178420, 178424, 178428, 178434, 178438, + 178442, 178453, 178458, 178462, 178466, 178472, 178476, 178480, 178484, + 178491, 178498, 178502, 178506, 178510, 178514, 178518, 178525, 178527, + 178531, 178533, 178535, 178539, 178543, 178547, 178549, 178553, 178557, + 178561, 178565, 178569, 178571, 178575, 178577, 178583, 178586, 178591, + 178593, 178595, 178598, 178600, 178602, 178605, 178612, 178619, 178626, + 178631, 178635, 178637, 178639, 178641, 178645, 178647, 178651, 178655, + 178659, 178661, 178665, 178667, 178671, 178675, 178682, 178684, 178693, + 178702, 178711, 178717, 178719, 178724, 178728, 178732, 178734, 178740, + 178744, 178746, 178750, 178754, 178756, 178760, 178765, 178769, 178775, + 178781, 178783, 178785, 178791, 178793, 178797, 178801, 178803, 178807, + 178809, 178813, 178817, 178821, 178824, 178827, 178832, 178837, 178839, + 178842, 178844, 178851, 178855, 178857, 178864, 178871, 178878, 178885, + 178892, 178894, 178896, 178898, 178902, 178904, 178906, 178908, 178910, + 178912, 178914, 178916, 178918, 178920, 178922, 178924, 178926, 178928, + 178930, 178932, 178934, 178936, 178938, 178940, 178942, 178944, 178946, + 178950, 178952, 178954, 178956, 178960, 178962, 178966, 178968, 178970, + 178974, 178978, 178984, 178986, 178988, 178990, 178992, 178996, 179000, + 179002, 179006, 179010, 179014, 179018, 179022, 179026, 179030, 179034, + 179038, 179042, 179046, 179050, 179054, 179058, 179062, 179066, 179070, + 179074, 179076, 179078, 179080, 179082, 179084, 179086, 179088, 179096, + 179104, 179112, 179120, 179125, 179130, 179135, 179139, 179143, 179148, + 179153, 179155, 179159, 179161, 179163, 179165, 179167, 179169, 179171, + 179173, 179177, 179179, 179181, 179183, 179187, 179191, 179195, 179199, + 179203, 179205, 179211, 179217, 179219, 179221, 179223, 179225, 179227, + 179236, 179243, 179250, 179254, 179261, 179266, 179273, 179282, 179287, + 179291, 179295, 179297, 179301, 179303, 179307, 179311, 179313, 179317, + 179321, 179325, 179327, 179329, 179335, 179337, 179339, 179341, 179345, + 179349, 179351, 179355, 179357, 179359, 179362, 179366, 179368, 179372, + 179374, 179376, 179381, 179383, 179387, 179391, 179394, 179398, 179402, + 179406, 179410, 179414, 179418, 179422, 179427, 179431, 179435, 179444, + 179449, 179452, 179454, 179457, 179460, 179465, 179467, 179470, 179475, + 179479, 179482, 179486, 179490, 179493, 179498, 179502, 179506, 179510, + 179514, 179520, 179526, 179532, 179538, 179543, 179554, 179556, 179560, + 179562, 179564, 179568, 179572, 179574, 179578, 179584, 179589, 179595, + 179597, 179601, 179605, 179612, 179619, 179623, 179625, 179627, 179631, + 179633, 179637, 179641, 179645, 179647, 179649, 179656, 179660, 179664, + 179668, 179672, 179676, 179678, 179682, 179684, 179686, 179690, 179692, + 179696, 179700, 179706, 179710, 179714, 179718, 179720, 179723, 179727, + 179734, 179743, 179752, 179761, 179770, 179772, 179776, 179778, 179782, + 179793, 179797, 179803, 179809, 179814, 179816, 179821, 179825, 179827, + 179829, 179831, 179835, 179839, 179843, 179848, 179859, 179875, 179888, + 179901, 179905, 179909, 179915, 179917, 179925, 179933, 179935, 179939, + 179945, 179951, 179958, 179965, 179967, 179969, 179973, 179975, 179981, + 179983, 179986, 179990, 179996, 180002, 180013, 180019, 180026, 180034, + 180038, 180046, 180054, 180060, 180066, 180073, 180075, 180079, 180081, + 180083, 180088, 180090, 180092, 180094, 180096, 180100, 180110, 180116, + 180120, 180124, 180128, 180134, 180140, 180146, 180152, 180157, 180162, + 180168, 180174, 180181, 180188, 180195, 180202, 180207, 180215, 180219, + 180228, 180237, 180243, 180247, 180251, 180255, 180258, 180263, 180265, + 180267, 180269, 180276, 180281, 180288, 180295, 180302, 180310, 180318, + 180326, 180334, 180342, 180350, 180358, 180366, 180374, 180380, 180386, + 180392, 180398, 180404, 180410, 180416, 180422, 180428, 180434, 180440, + 180446, 180449, 180458, 180467, 180469, 180476, 180480, 180482, 180484, + 180488, 180494, 180498, 180500, 180510, 180516, 180520, 180522, 180526, + 180528, 180532, 180539, 180546, 180553, 180558, 180563, 180572, 180578, + 180583, 180587, 180592, 180596, 180603, 180607, 180610, 180614, 180620, + 180626, 180630, 180634, 180639, 180645, 180654, 180665, 180671, 180677, + 180683, 180693, 180708, 180717, 180725, 180733, 180741, 180749, 180757, + 180765, 180773, 180781, 180789, 180797, 180805, 180813, 180816, 180820, + 180825, 180830, 180832, 180836, 180845, 180854, 180862, 180866, 180870, + 180875, 180880, 180885, 180887, 180892, 180896, 180898, 180902, 180906, + 180912, 180917, 180925, 180930, 180935, 180940, 180947, 180950, 180952, + 180956, 180961, 180967, 180971, 180975, 180981, 180987, 180989, 180993, + 180997, 181001, 181005, 181009, 181011, 181013, 181015, 181017, 181023, + 181029, 181033, 181035, 181037, 181039, 181048, 181052, 181059, 181066, + 181068, 181071, 181075, 181081, 181085, 181089, 181091, 181099, 181103, + 181107, 181112, 181116, 181121, 181126, 181131, 181136, 181141, 181146, + 181151, 181156, 181160, 181166, 181170, 181176, 181181, 181188, 181194, + 181202, 181206, 181213, 181217, 181221, 181225, 181230, 181235, 181237, + 181241, 181250, 181258, 181267, 181281, 181295, 181309, 181316, 181323, + 181327, 181336, 181344, 181348, 181357, 181364, 181368, 181372, 181376, + 181380, 181387, 181391, 181395, 181399, 181403, 181410, 181419, 181428, + 181435, 181447, 181459, 181463, 181467, 181471, 181475, 181479, 181483, + 181491, 181499, 181508, 181512, 181516, 181520, 181524, 181528, 181532, + 181538, 181545, 181549, 181561, 181569, 181573, 181577, 181581, 181585, + 181591, 181598, 181609, 181619, 181630, 181641, 181650, 181661, 181667, + 181673, 181679, 181685, 181691, 181695, 181702, 181711, 181718, 181724, + 181728, 181732, 181736, 181745, 181757, 181761, 181768, 181775, 181782, + 181790, 181797, 181805, 181813, 181822, 181830, 181839, 181848, 181858, + 181867, 181877, 181887, 181898, 181908, 181919, 181926, 181934, 181941, + 181949, 181957, 181966, 181974, 181983, 181990, 182002, 182009, 182021, + 182024, 182028, 182031, 182035, 182041, 182048, 182055, 182063, 182068, + 182074, 182085, 182095, 182106, 182111, 182116, 182122, 182127, 182134, + 182138, 182144, 182146, 182148, 182152, 182156, 182160, 182169, 182171, + 182173, 182176, 182178, 182180, 182184, 182186, 182190, 182192, 182196, + 182198, 182200, 182204, 182208, 182214, 182216, 182220, 182222, 182226, + 182230, 182234, 182238, 182240, 182242, 182246, 182250, 182254, 182258, + 182260, 182262, 182264, 182270, 182275, 182278, 182286, 182294, 182296, + 182301, 182304, 182309, 182320, 182327, 182332, 182337, 182339, 182343, + 182345, 182349, 182351, 182355, 182359, 182362, 182365, 182367, 182370, + 182372, 182376, 182378, 182380, 182382, 182386, 182388, 182392, 182395, + 182402, 182405, 182410, 182413, 182416, 182421, 182425, 182429, 182433, + 182435, 182440, 182443, 182447, 182449, 182451, 182455, 182457, 0, 0, 0, + 0, 182459, 182461, 182465, 182467, 182471, 182476, 182478, 182482, + 182484, 182488, 182492, 182498, 182502, 182507, 182510, 182514, 182518, + 0, 0, 0, 182522, 182524, 182530, 182534, 182538, 182540, 182544, 182546, + 182548, 182552, 182554, 182558, 182562, 0, 0, 0, 182566, 182571, 182576, + 182581, 182586, 182591, 182596, 182603, 182610, 182617, 182624, 182629, + 182634, 182639, 182644, 182651, 182657, 182664, 182671, 182678, 182683, + 182688, 182693, 182698, 182703, 182710, 182717, 182722, 182727, 182734, + 182741, 182749, 182757, 182764, 182771, 182779, 182787, 182795, 182802, + 182812, 182823, 182828, 182835, 182842, 182849, 182857, 182865, 182876, + 182884, 182892, 182900, 182905, 182910, 182915, 182920, 182925, 182930, + 182935, 182940, 182945, 182950, 182955, 182960, 182967, 182972, 182977, + 182984, 182989, 182994, 182999, 183004, 183009, 183014, 183019, 183024, + 183029, 183034, 183039, 183044, 183051, 183059, 183064, 183069, 183076, + 183081, 183086, 183091, 183098, 183103, 183110, 183115, 183122, 183127, + 183136, 183145, 183150, 183155, 183160, 183165, 183170, 183175, 183180, + 183185, 183190, 183195, 183200, 183205, 183210, 183218, 183226, 183231, + 183236, 183241, 183246, 183251, 183257, 183263, 183268, 183270, 0, 0, 0, + 0, 183274, 183276, 183278, 183280, 183282, 183284, 183292, 183300, + 183308, 183316, 183322, 183328, 183332, 183336, 183342, 183348, 183357, + 183361, 183366, 183372, 183376, 183381, 183385, 183389, 183395, 183401, + 183411, 183420, 183423, 183428, 183434, 183440, 183451, 183461, 183465, + 183470, 183476, 183482, 183491, 183496, 183500, 183505, 183509, 183515, + 183521, 183527, 183531, 183534, 183538, 183541, 183544, 183549, 183554, + 183561, 183569, 183576, 183583, 183592, 183601, 183608, 183616, 183623, + 183630, 183639, 183648, 183655, 183663, 183670, 183677, 183686, 183693, + 183701, 183707, 183716, 183724, 183733, 183740, 183750, 183761, 183769, + 183777, 183786, 183794, 183802, 183811, 183819, 183829, 183838, 183846, + 183854, 183863, 183866, 183871, 183874, 183879, 0, 0, 0, 0, 0, 0, 183886, + 183892, 183898, 183904, 183910, 183916, 183922, 183928, 183934, 183940, + 183946, 183952, 0, 0, 0, 0, 183958, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 183962, 183970, 183979, 183987, 183996, 184005, 184015, 184024, + 184034, 184043, 184053, 184062, 0, 0, 0, 0, 184072, 184080, 184089, + 184097, 184106, 184113, 184121, 184128, 184136, 184144, 184153, 184161, + 184170, 184180, 184191, 184201, 184212, 184221, 184231, 184240, 184250, + 184259, 184269, 184278, 184288, 184296, 184305, 184313, 184322, 184330, + 184339, 184347, 184356, 184366, 184377, 184387, 184398, 184402, 184407, + 184411, 184416, 184419, 184423, 184426, 184430, 184434, 184439, 184443, + 184448, 184453, 184459, 184464, 184470, 184473, 184477, 184480, 0, 0, 0, + 0, 0, 0, 0, 0, 184484, 184487, 184491, 184494, 184498, 184503, 184508, + 184514, 184520, 184524, 0, 0, 0, 0, 0, 0, 184528, 184534, 184541, 184547, + 184554, 184562, 184570, 184579, 184588, 184593, 184599, 184604, 184610, + 184617, 184624, 184632, 184640, 184647, 184655, 184662, 184670, 184679, + 184688, 184698, 184708, 184714, 184721, 184727, 184734, 184742, 184750, + 184759, 184768, 184776, 184785, 184793, 184802, 184812, 184822, 184833, + 0, 0, 0, 0, 0, 0, 0, 0, 184844, 184849, 184855, 184860, 184866, 184875, + 184885, 184894, 184904, 184911, 184919, 184926, 184934, 184941, 184950, + 184959, 184968, 184973, 184980, 184987, 184994, 184999, 185004, 185009, + 185014, 185021, 185028, 185035, 185042, 185049, 0, 0, 185058, 185068, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 185080, 185090, 185099, 185104, 185113, 185121, 185129, + 185136, 185140, 185145, 185152, 185161, 185172, 185176, 185179, 185183, + 185187, 185191, 185195, 185200, 185204, 185208, 185213, 185217, 185221, + 185227, 185233, 185240, 185244, 185248, 185250, 185260, 185269, 185276, + 185280, 185284, 185294, 185298, 185302, 185306, 185310, 185318, 185327, + 185340, 185351, 185362, 185378, 185387, 185396, 185400, 185402, 185407, + 185409, 185411, 185417, 185421, 185423, 185429, 185431, 185433, 185437, + 185439, 185443, 185445, 185449, 185453, 185458, 185462, 185466, 185468, + 185472, 185474, 185480, 185486, 185492, 185496, 185502, 185506, 185513, + 185515, 185519, 185521, 185523, 185525, 185527, 185529, 185531, 185535, + 185539, 185546, 185550, 185552, 185557, 185559, 185561, 185563, 185565, + 185569, 185573, 185575, 185580, 185585, 185587, 185589, 185591, 185593, + 185598, 185600, 185604, 185608, 185610, 185614, 185616, 185629, 185633, + 185640, 185652, 185664, 185668, 185672, 185674, 185678, 185686, 185693, + 185695, 185699, 185701, 185705, 185709, 185711, 185715, 185717, 185719, + 185723, 185725, 185727, 185729, 185731, 185733, 185737, 185739, 185741, + 185743, 185745, 185747, 185749, 185751, 185755, 185759, 185761, 185763, + 185765, 185767, 185769, 185771, 185773, 185775, 185777, 185779, 185781, + 185783, 185785, 185787, 185789, 185791, 185793, 185795, 185797, 185799, + 185801, 185803, 185805, 185807, 185809, 185811, 185815, 185819, 185827, + 185835, 185841, 185848, 185850, 185852, 185854, 185856, 185858, 185860, + 185864, 185871, 185875, 185879, 185883, 185887, 185891, 185893, 185897, + 185901, 185903, 185905, 185907, 185909, 185911, 185915, 185919, 185923, + 185925, 185929, 185933, 185937, 185942, 185944, 185946, 185950, 185954, + 185959, 185967, 185971, 185979, 185981, 185983, 185985, 185987, 185989, + 185991, 185993, 185995, 185999, 186003, 186005, 186007, 186009, 186011, + 186017, 186019, 186025, 186029, 186033, 186038, 186040, 186042, 186046, + 186048, 186050, 186052, 186054, 186058, 186063, 186068, 186072, 186076, + 186078, 186080, 186085, 186090, 186092, 186094, 186098, 186104, 186110, + 186116, 186122, 186128, 186134, 186145, 186156, 186168, 186179, 186190, + 186201, 186212, 186223, 186234, 186245, 186256, 186267, 186278, 186289, + 186300, 186312, 186324, 186336, 186348, 186360, 186372, 186386, 186400, + 186415, 186421, 186427, 186433, 186439, 186445, 186451, 186457, 186463, + 186469, 186475, 186481, 186487, 186494, 186501, 186508, 186515, 186522, + 186529, 186543, 186557, 186572, 186586, 186600, 186614, 186628, 186642, + 186656, 186670, 186684, 186698, 186712, 186726, 186740, 186755, 186770, + 186785, 186800, 186815, 186830, 186844, 186858, 186873, 186878, 186883, + 186889, 186900, 186911, 186923, 186928, 186933, 186938, 186943, 186948, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186953, 186959, 186965, 186971, + 186977, 186983, 186989, 186995, 187000, 187005, 187010, 187015, 187020, + 187025, 0, 0, 187030, 187034, 187038, 187040, 187042, 187046, 187051, + 187055, 187059, 187064, 187068, 187070, 187072, 0, 0, 0, 187074, 187076, + 187078, 187080, 187082, 187086, 187088, 187092, 187094, 0, 0, 0, 0, 0, 0, + 0, 187096, 187100, 187102, 187104, 187106, 187110, 187112, 187116, + 187118, 187121, 187123, 187127, 187129, 187131, 187132, 187134, 187136, + 187138, 187142, 187144, 187146, 187150, 187152, 187154, 187156, 187158, + 187162, 187166, 187169, 187171, 187177, 187181, 187183, 187185, 187187, + 187189, 187191, 187195, 187197, 187199, 187201, 187203, 187207, 187212, + 187214, 187216, 0, 187218, 187220, 187224, 187226, 187230, 187234, + 187238, 0, 0, 0, 0, 0, 0, 0, 0, 187243, 187245, 187247, 187249, 187253, + 187255, 187257, 187259, 187261, 187263, 187267, 187269, 187271, 187275, + 0, 0, 0, 0, 187279, 187283, 187287, 187300, 187307, 187314, 187320, + 187324, 187326, 0, 0, 0, 0, 0, 0, 0, 187330, 187340, 187343, 187346, + 187351, 187356, 187365, 187369, 187374, 0, 0, 0, 0, 0, 0, 0, 187379, + 187382, 187385, 187388, 187391, 187394, 187397, 187400, 187403, 187406, + 187409, 187412, 187415, 187418, 187421, 187424, 187427, 187430, 187433, + 187436, 187439, 187442, 187445, 187448, 187451, 187454, 187457, 187460, + 187463, 187466, 187469, 187472, 187475, 187478, 187481, 187484, 187487, + 187490, 187493, 187496, 187499, 187502, 187505, 187508, 187511, 187514, + 187517, 187520, 187523, 187526, 187529, 187532, 187535, 187538, 187541, + 187544, 187547, 187550, 187553, 187556, 187559, 187571, 187582, 187594, + 187605, 187616, 187628, 187639, 187651, 187662, 187673, 187685, 187697, + 187708, 187720, 187731, 187742, 187754, 187765, 187777, 187788, 187799, + 187811, 187823, 187834, 187846, 187857, 187868, 187880, 187891, 187903, + 187914, 187925, 187937, 187949, 187960, 187972, 187983, 187994, 188006, + 188017, 188029, 188040, 188051, 188063, 188075, 188087, 188099, 188111, + 188119, 188127, 188135, 188143, 188149, 188155, 188161, 188167, 188173, + 188179, 188186, 188193, 188200, 188207, 188214, 188221, 188229, 188237, + 188245, 188253, 188261, 188268, 188274, 188280, 188287, 188293, 188300, + 188306, 188312, 188319, 188325, 188332, 188338, 188344, 188350, 188356, + 188362, 188374, 0, 188387, 188400, 188406, 188414, 188419, 188426, + 188433, 188441, 188449, 188457, 188465, 188473, 188481, 188493, 188504, + 188515, 188526, 188541, 188556, 188570, 188584, 188602, 188620, 188639, + 188657, 188675, 188693, 188700, 188708, 188712, 188717, 188723, 188729, + 188739, 188750, 188761, 188771, 188781, 188785, 188789, 188794, 188800, + 188806, 188816, 188822, 188831, 188840, 188849, 188858, 188864, 188868, + 188877, 188885, 188892, 188899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 188904, 188909, 188913, 188917, 188921, 188925, 188929, 188933, 188937, + 188941, 0, 0, 0, 0, 0, 0, 188945, 188949, 188953, 188957, 188961, 188965, + 188969, 188973, 188977, 188981, 188985, 188989, 188993, 188997, 189001, + 189005, 189009, 189013, 189017, 189021, 189025, 189029, 189033, 189037, + 189041, 189045, 189049, 189053, 189057, 189061, 189065, 189069, 189073, + 189077, 189081, 189085, 189089, 189093, 189097, 189101, 189105, 189109, + 189113, 189117, 189121, 189125, 189129, 189133, 189137, 189141, 189145, + 189149, 189153, 189157, 189161, 189165, 189169, 189173, 189177, 189181, + 189185, 189189, 189193, 189197, 189201, 189205, 189209, 189213, 189217, + 189221, 189225, 189229, 189233, 189237, 189241, 189245, 189249, 189253, + 189257, 189261, 189265, 189269, 189273, 189277, 189281, 189285, 189289, + 189293, 189297, 189301, 189305, 189309, 189313, 189317, 189321, 189325, + 189329, 189333, 189337, 189341, 189345, 189349, 189353, 189357, 189361, + 189365, 189369, 189373, 189377, 189381, 189385, 189389, 189393, 189397, + 189401, 189405, 189409, 189413, 189417, 189421, 189425, 189429, 189433, + 189437, 189441, 189445, 189449, 189453, 189457, 189461, 189465, 189469, + 189473, 189477, 189481, 189485, 189489, 189493, 189497, 189501, 189505, + 189509, 189513, 189517, 189521, 189525, 189529, 189533, 189537, 189541, + 189545, 189549, 189553, 189557, 189561, 189565, 189569, 189573, 189577, + 189581, 189585, 189589, 189593, 189597, 189601, 189605, 189609, 189613, + 189617, 189621, 189625, 189629, 189633, 189637, 189641, 189645, 189649, + 189653, 189657, 189661, 189665, 189669, 189673, 189677, 189681, 189685, + 189689, 189693, 189697, 189701, 189705, 189709, 189713, 189717, 189721, + 189725, 189729, 189733, 189737, 189741, 189745, 189749, 189753, 189757, + 189761, 189765, 189769, 189773, 189777, 189781, 189785, 189789, 189793, + 189797, 189801, 189805, 189809, 189813, 189817, 189821, 189825, 189829, + 189833, 189837, 189841, 189845, 189849, 189853, 189857, 189861, 189865, + 189869, 189873, 189877, 189881, 189885, 189889, 189893, 189897, 189901, + 189905, 189909, 189913, 189917, 189921, 189925, 189929, 189933, 189937, + 189941, 189945, 189949, 189953, 189957, 189961, 189965, 189969, 189973, + 189977, 189981, 189985, 189989, 189993, 189997, 190001, 190005, 190009, + 190013, 190017, 190021, 190025, 190029, 190033, 190037, 190041, 190045, + 190049, 190053, 190057, 190061, 190065, 190069, 190073, 190077, 190081, + 190085, 190089, 190093, 190097, 190101, 190105, 190109, 190113, 190117, + 190121, 190125, 190129, 190133, 190137, 190141, 190145, 190149, 190153, + 190157, 190161, 190165, 190169, 190173, 190177, 190181, 190185, 190189, + 190193, 190197, 190201, 190205, 190209, 190213, 190217, 190221, 190225, + 190229, 190233, 190237, 190241, 190245, 190249, 190253, 190257, 190261, + 190265, 190269, 190273, 190277, 190281, 190285, 190289, 190293, 190297, + 190301, 190305, 190309, 190313, 190317, 190321, 190325, 190329, 190333, + 190337, 190341, 190345, 190349, 190353, 190357, 190361, 190365, 190369, + 190373, 190377, 190381, 190385, 190389, 190393, 190397, 190401, 190405, + 190409, 190413, 190417, 190421, 190425, 190429, 190433, 190437, 190441, + 190445, 190449, 190453, 190457, 190461, 190465, 190469, 190473, 190477, + 190481, 190485, 190489, 190493, 190497, 190501, 190505, 190509, 190513, + 190517, 190521, 190525, 190529, 190533, 190537, 190541, 190545, 190549, + 190553, 190557, 190561, 190565, 190569, 190573, 190577, 190581, 190585, + 190589, 190593, 190597, 190601, 190605, 190609, 190613, 190617, 190621, + 190625, 190629, 190633, 190637, 190641, 190645, 190649, 190653, 190657, + 190661, 190665, 190669, 190673, 190677, 190681, 190685, 190689, 190693, + 190697, 190701, 190705, 190709, 190713, 190717, 190721, 190725, 190729, + 190733, 190737, 190741, 190745, 190749, 190753, 190757, 190761, 190765, + 190769, 190773, 190777, 190781, 190785, 190789, 190793, 190797, 190801, + 190805, 190809, 190813, 190817, 190821, 190825, 190829, 190833, 190837, + 190841, 190845, 190849, 190853, 190857, 190861, 190865, 190869, 190873, + 190877, 190881, 190885, 190889, 190893, 190897, 190901, 190905, 190909, + 190913, 190917, 190921, 190925, 190929, 190933, 190937, 190941, 190945, + 190949, 190953, 190957, 190961, 190965, 190969, 190973, 190977, 190981, + 190985, 190989, 190993, 190997, 191001, 191005, 191009, 191013, 191017, + 191021, 191025, 191029, 191033, 191037, 191041, 191045, 191049, 191053, + 191057, 191061, 191065, 191069, 191073, 191077, 191081, 191085, 191089, + 191093, 191097, 191101, 191105, 191109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191113, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 191117, 191121, 191126, 191131, 191135, 191140, 191145, 191149, 191153, + 191158, 191163, 191167, 191171, 191175, 191179, 191185, 191189, 191194, + 191198, 191202, 191206, 191210, 191214, 191218, 191222, 191226, 191230, + 191234, 191238, 191243, 191248, 191253, 191258, 191264, 191270, 191277, + 191284, 191291, 191297, 191304, 191311, 191318, 191324, 191331, 191338, + 191344, 191351, 191358, 191364, 191371, 191378, 191384, 191391, 191398, + 191404, 191411, 191418, 191425, 191432, 191439, 191445, 191451, 191457, + 191463, 191468, 191474, 191480, 191487, 191494, 191501, 191507, 191514, + 191521, 191528, 191534, 191541, 191548, 191554, 191561, 191568, 191574, + 191581, 191588, 191594, 191601, 191608, 191614, 191621, 191628, 191635, + 191642, 191649, 191656, 191661, 191668, 191672, 191676, 191679, 191682, + 191685, 191688, 191691, 191694, 191697, 191700, 191703, 191706, 191709, + 191712, 191715, 191718, 191721, 191724, 191727, 191730, 191733, 191736, + 191739, 191742, 191745, 191748, 191751, 191754, 191757, 191760, 191763, + 191766, 191769, 191772, 191775, 191778, 191781, 191784, 191787, 191790, + 191793, 191796, 191799, 191802, 191805, 191808, 191811, 191814, 191817, + 191820, 191823, 191826, 191829, 191832, 191835, 191838, 191841, 191844, + 191847, 191850, 191853, 191856, 191859, 191862, 191865, 191868, 191871, + 191874, 191877, 191880, 191883, 191886, 191889, 191892, 191895, 191898, + 191901, 191904, 191907, 191910, 191913, 191916, 191919, 191922, 191925, + 191928, 191931, 191934, 191937, 191940, 191943, 191946, 191949, 191952, + 191955, 191958, 191961, 191964, 191967, 191970, 191973, 191976, 191979, + 191982, 191985, 191988, 191991, 191994, 191997, 192000, 192003, 192006, + 192009, 192012, 192015, 192018, 192021, 192024, 192027, 192030, 192033, + 192036, 192039, 192042, 192045, 192048, 192051, 192054, 192057, 192060, + 192063, 192066, 192069, 192072, 192075, 192078, 192081, 192084, 192087, + 192090, 192093, 192096, 192099, 192102, 192105, 192108, 192111, 192114, + 192117, 192120, 192123, 192126, 192129, 192132, 192135, 192138, 192141, + 192144, 192147, 192150, 192153, 192156, 192159, 192162, 192165, 192168, + 192171, 192174, 192177, 192180, 192183, 192186, 192189, 192192, 192195, + 192198, 192201, 192204, 192207, 192210, 192213, 192216, 192219, 192222, + 192225, 192228, 192231, 192234, 192237, 192240, 192243, 192246, 192249, + 192252, 192255, 192258, 192261, 192264, 192267, 192270, 192273, 192276, + 192279, 192282, 192285, 192288, 192291, 192294, 192297, 192300, 192303, + 192306, 192309, 192312, 192315, 192318, 192321, 192324, 192327, 192330, + 192333, 192336, 192339, 192342, 192345, 192348, 192351, 192354, 192357, + 192360, 192363, 192366, 192369, 192372, 192375, 192378, 192381, 192384, + 192387, 192390, 192393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 192396, 192398, 192400, 192405, 192407, 192412, 192414, 192419, 192421, + 192426, 192428, 192430, 192432, 192434, 192436, 192438, 192440, 192442, + 192444, 192448, 192452, 192454, 192456, 192460, 192464, 192469, 192471, + 192473, 192475, 192479, 192482, 192484, 192488, 192490, 192494, 192496, + 192500, 192503, 192505, 192509, 192513, 192515, 192521, 192523, 192528, + 192530, 192535, 192537, 192542, 192544, 192549, 192551, 192555, 192557, + 192561, 192563, 192570, 192572, 192574, 192576, 192581, 192583, 192585, + 192587, 192589, 192591, 192593, 192598, 192602, 192604, 192609, 192613, + 192615, 192620, 192624, 192626, 192631, 192635, 192637, 192639, 192641, + 192643, 192647, 192649, 192654, 192656, 192662, 192664, 192670, 192672, + 192674, 192676, 192680, 192682, 192689, 192691, 192698, 192700, 192706, + 192712, 192714, 192721, 192728, 192730, 192736, 192741, 192743, 192749, + 192755, 192757, 192763, 192769, 192771, 192777, 192781, 192783, 192788, + 192790, 192792, 192797, 192799, 192801, 192807, 192809, 192814, 192818, + 192820, 192825, 192829, 192831, 192837, 192839, 192843, 192845, 192849, + 192851, 192858, 192865, 192867, 192874, 192881, 192883, 192888, 192890, + 192898, 192900, 192906, 192908, 192914, 192916, 192920, 192922, 192928, + 192930, 192934, 192936, 192942, 192944, 192946, 192948, 192953, 192958, + 192960, 192969, 192971, 192981, 192986, 192993, 193000, 193005, 193010, + 193022, 193026, 193030, 193034, 193038, 193040, 193042, 193044, 193046, + 193048, 193054, 193056, 193058, 193060, 193062, 193064, 193066, 193068, + 193070, 193072, 193074, 193076, 193078, 193080, 193082, 193084, 193086, + 193088, 193094, 193101, 193106, 193114, 193122, 193127, 193133, 193135, + 193137, 193139, 193141, 193143, 193145, 193147, 193149, 193151, 193153, + 193155, 193157, 193159, 193161, 193163, 193165, 193177, 193182, 193184, + 193186, 193192, 193204, 193210, 193216, 193222, 193228, 193232, 193243, + 193245, 193247, 193249, 193251, 193253, 193255, 193257, 193259, 193261, + 193263, 193265, 193267, 193269, 193271, 193273, 193275, 193277, 193279, + 193281, 193283, 193285, 193287, 193289, 193291, 193293, 193295, 193297, + 193299, 193301, 193303, 193305, 193307, 193309, 193311, 193313, 193315, + 193317, 193319, 193321, 193323, 193325, 193327, 193329, 193331, 193333, + 193335, 193337, 193339, 193341, 193343, 193345, 193347, 193349, 193351, + 193353, 193355, 193357, 193359, 193361, 193363, 193365, 193367, 193369, + 193371, 193373, 193375, 193377, 193379, 193381, 193383, 193385, 193387, + 193389, 193391, 193393, 193395, 193397, 193399, 193401, 193403, 193405, + 193407, 193409, 193411, 193413, 193415, 193417, 193419, 193421, 193423, + 193425, 193427, 193429, 193431, 193433, 193435, 193437, 193439, 193441, + 193443, 193445, 193447, 193449, 193451, 193453, 193455, 193457, 193459, + 193461, 193463, 193465, 193467, 193469, 193471, 193473, 193475, 193477, + 193479, 193481, 193483, 193485, 193487, 193489, 193491, 193493, 193495, + 193497, 193499, 193501, 193503, 193505, 193507, 193509, 193511, 193513, + 193515, 193517, 193519, 193521, 193523, 193525, 193527, 193529, 193531, + 193533, 193535, 193537, 193539, 193541, 193543, 193545, 193547, 193549, + 193551, 193553, 193555, 193557, 193559, 193561, 193563, 193565, 193567, + 193569, 193571, 193573, 193575, 193577, 193579, 193581, 193583, 193585, + 193587, 193589, 193591, 193593, 193595, 193597, 193599, 193601, 193603, + 193605, 193607, 193609, 193611, 193613, 193615, 193617, 193619, 193621, + 193623, 193625, 193627, 193629, 193631, 193633, 193635, 193637, 193639, + 193641, 193643, 193645, 193647, 193649, 193651, 193653, 193655, 193657, + 193659, 193661, 193663, 193665, 193667, 193669, 193671, 193673, 193675, + 193677, 193679, 193681, 193683, 193685, 193687, 193689, 193691, 193693, + 193695, 193697, 193699, 193701, 193703, 193705, 193707, 193709, 193711, + 193713, 193715, 193717, 193719, 193721, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 193723, 193727, 193731, 193736, 193740, 193744, 193748, + 193752, 193756, 193760, 193764, 193768, 193772, 193782, 193792, 193803, + 193814, 193824, 193834, 193844, 193854, 193868, 193882, 193896, 193910, + 193919, 193928, 193941, 193954, 193967, 193980, 193990, 194000, 194011, + 194022, 194033, 194044, 194055, 194064, 194074, 194084, 194094, 194104, + 194115, 194126, 194137, 194148, 194159, 194170, 194181, 194192, 194203, + 194214, 194225, 194239, 194250, 194264, 194272, 194283, 194291, 194299, + 194307, 194315, 194323, 194331, 194341, 194351, 194361, 194371, 194381, + 194391, 194401, 194411, 194419, 194428, 194437, 194446, 194455, 194463, + 194471, 194481, 194491, 194502, 194513, 194525, 194536, 194546, 194557, + 194567, 194578, 194586, 194593, 194600, 194607, 194614, 194621, 194628, + 194635, 194642, 194650, 194658, 194666, 194674, 194682, 194690, 194698, + 194706, 194714, 194722, 194730, 194735, 194739, 194743, 194747, 194751, + 194755, 194759, 194763, 194767, 194771, 194775, 194779, 194782, 194785, + 194789, 194793, 194797, 194801, 194805, 194809, 194813, 194817, 194821, + 194825, 194829, 194833, 194837, 194841, 194845, 194849, 194853, 194857, + 194861, 194865, 194869, 194873, 194877, 194881, 194885, 194889, 194893, + 194897, 194901, 194905, 194909, 194913, 194917, 194921, 194925, 194929, + 194933, 194937, 194941, 194945, 194949, 194953, 194957, 194961, 194965, + 194969, 194973, 194977, 194981, 194985, 194989, 194993, 194997, 195001, + 195005, 195009, 195013, 195017, 195021, 195025, 195029, 195033, 195037, + 195041, 195045, 195049, 195053, 195057, 195061, 195065, 195069, 195073, + 195077, 195081, 195085, 195089, 195093, 195097, 195101, 195105, 195109, + 195113, 195117, 195121, 195125, 195128, 195132, 195136, 195140, 195144, + 195148, 195152, 195156, 195160, 195164, 195168, 195172, 195176, 195180, + 195184, 195188, 195192, 195196, 195200, 195204, 195208, 195212, 195216, + 195220, 195224, 195228, 195232, 195236, 195240, 195244, 195248, 195252, + 195256, 195260, 195264, 195268, 195272, 195276, 195280, 195284, 195288, + 195292, 195296, 195300, 195304, 195308, 195312, 195316, 195320, 195324, + 195328, 195332, 195336, 195340, 195344, 195348, 195352, 195356, 195360, + 195364, 195368, 195372, 195376, 195380, 195384, 195388, 195392, 195396, + 195400, 195404, 195408, 195412, 195416, 195420, 195424, 195428, 195432, + 195436, 195440, 195444, 195448, 195452, 195456, 195460, 195464, 195468, + 195472, 195476, 195480, 195484, 195488, 195492, 195496, 195500, 195504, + 195508, 195512, 195516, 195520, 195524, 195528, 195532, 195536, 195540, + 195544, 195548, 195552, 195556, 195560, 195564, 195568, 195572, 195576, + 195580, 195584, 195588, 195592, 195596, 195600, 195604, 195608, 195612, + 195616, 195620, 195624, 195628, 195632, 195636, 195640, 195644, 195648, + 195652, 195656, 195660, 195664, 195668, 195672, 195676, 195680, 195684, + 195688, 195692, 195696, 195700, 195704, 195708, 195712, 195716, 195720, + 195724, 195728, 195732, 195736, 195740, 195744, 195748, 195752, 195756, + 195760, 195764, 195768, 195772, 195776, 195780, 195784, 195788, 195792, + 195796, 195800, 195804, 195808, 195812, 195816, 195820, 195824, 195828, + 195832, 195836, 195840, 195844, 195848, 195852, 195856, 195860, 195864, + 195868, 195872, 195876, 195880, 195884, 195888, 195892, 195897, 195902, + 195907, 195911, 195917, 195924, 195931, 195938, 195945, 195952, 195959, + 195966, 195973, 195980, 195987, 195994, 196001, 196008, 196014, 196021, + 196028, 196034, 196041, 196048, 196055, 196062, 196069, 196076, 196083, + 196090, 196097, 196104, 196111, 196118, 196125, 196131, 196137, 196143, + 196150, 196159, 196168, 196177, 196186, 196191, 196196, 196203, 196210, + 196217, 196224, 196231, 196237, 196243, 196249, 196255, 196261, 196267, + 196273, 196278, 196284, 196294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; /* name->code dictionary */ @@ -25185,7 +25364,7 @@ static const unsigned int code_hash[] = { 74224, 4851, 0, 0, 0, 0, 7929, 0, 0, 0, 0, 127931, 0, 42833, 983091, 12064, 110752, 129548, 194597, 69850, 65842, 0, 0, 0, 78159, 68476, 72392, 1373, 0, 0, 5816, 0, 0, 4231, 0, 0, 4233, 4234, 4232, 68885, - 70351, 0, 7404, 72393, 0, 0, 0, 0, 0, 41601, 8874, 0, 0, 0, 0, 0, 0, + 70351, 0, 7404, 72393, 0, 0, 0, 0, 0, 41601, 8874, 0, 0, 0, 128498, 0, 0, 41603, 9784, 0, 9188, 41600, 0, 0, 0, 0, 3535, 0, 0, 0, 66797, 0, 74491, 0, 3404, 100419, 0, 72411, 1759, 100417, 0, 100418, 69972, 11240, 121038, 100416, 127764, 0, 0, 0, 0, 0, 69970, 0, 0, 9834, 43249, 2234, 983891, 0, @@ -25197,102 +25376,103 @@ static const unsigned int code_hash[] = { 5194, 11657, 128353, 0, 0, 0, 0, 0, 120766, 100525, 0, 0, 74350, 0, 10682, 110820, 10602, 800, 70044, 118883, 0, 0, 64930, 118940, 67853, 72001, 0, 762, 120485, 0, 0, 0, 10906, 1353, 6960, 0, 0, 5828, 8724, 0, - 0, 118548, 0, 0, 7080, 0, 128806, 0, 0, 72388, 0, 11859, 0, 0, 68878, 0, - 0, 0, 7240, 0, 556, 0, 118544, 0, 0, 0, 72397, 0, 0, 0, 0, 0, 0, 0, 0, - 72986, 0, 0, 43931, 0, 11093, 0, 0, 125016, 7341, 66801, 68527, 0, 1874, - 0, 0, 129314, 0, 0, 0, 0, 0, 0, 7688, 0, 0, 9036, 0, 0, 66389, 0, 121347, - 0, 0, 10100, 0, 2725, 0, 0, 43981, 42128, 0, 0, 68146, 0, 0, 0, 0, 71349, - 7859, 1945, 0, 0, 0, 65918, 7188, 9992, 0, 7389, 127008, 71341, 0, 0, 0, - 528, 129681, 44017, 11429, 71347, 0, 0, 120864, 0, 0, 0, 11530, 73102, - 6188, 0, 0, 68208, 1823, 0, 0, 92928, 0, 64843, 7233, 92929, 0, 0, 6639, - 0, 0, 123149, 0, 1176, 0, 0, 8276, 128667, 0, 0, 68892, 42931, 0, 0, 0, - 0, 0, 0, 0, 5388, 0, 0, 0, 11310, 0, 123607, 0, 68888, 4199, 119264, 0, - 119020, 0, 0, 9560, 0, 0, 43869, 0, 0, 0, 83172, 0, 0, 0, 83173, 101559, - 128875, 0, 0, 74327, 0, 0, 0, 0, 0, 123623, 68886, 0, 0, 0, 8408, 64704, - 0, 0, 0, 0, 118711, 67999, 0, 0, 0, 0, 43049, 0, 43050, 73028, 0, 0, 0, - 0, 0, 127396, 0, 69847, 9322, 0, 0, 129321, 68192, 120507, 983634, 0, 0, - 0, 6199, 67249, 0, 0, 0, 0, 11329, 66285, 0, 983086, 0, 0, 0, 0, 41335, - 118866, 43401, 0, 41334, 0, 0, 0, 983481, 71997, 983480, 128114, 0, - 42627, 0, 32, 6187, 0, 123619, 983477, 3665, 121083, 42871, 983118, - 41336, 0, 0, 983473, 0, 0, 0, 4412, 0, 0, 0, 0, 119533, 0, 4181, 0, 0, - 127589, 0, 0, 71453, 6181, 74755, 917895, 0, 0, 0, 0, 121107, 0, 0, - 10073, 0, 100738, 127186, 0, 42844, 7498, 1098, 92565, 119530, 0, 0, - 10207, 0, 983230, 0, 983555, 0, 9234, 0, 6182, 0, 92552, 0, 0, 0, 0, - 5471, 9461, 6697, 0, 5473, 0, 0, 0, 0, 0, 0, 70073, 0, 0, 7767, 8304, - 41339, 0, 983491, 69450, 0, 0, 983489, 43855, 41337, 0, 0, 0, 129706, 0, - 0, 0, 72396, 0, 0, 0, 42633, 0, 0, 0, 0, 0, 0, 0, 70005, 129506, 0, 0, 0, - 129580, 69817, 128299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1437, 41617, 0, 0, 0, - 128853, 0, 0, 0, 0, 0, 128529, 12113, 0, 42772, 0, 0, 7693, 10749, 67485, - 65210, 5773, 978, 128134, 0, 41619, 10239, 0, 0, 0, 74328, 0, 9748, 0, 0, - 0, 0, 0, 0, 0, 70681, 0, 72811, 0, 67464, 0, 92776, 0, 0, 2379, 11325, 0, - 0, 67854, 0, 78547, 42209, 0, 120392, 2369, 0, 984003, 984004, 0, 0, - 73936, 7008, 69415, 122919, 0, 43841, 2367, 127827, 983888, 0, 2375, - 8060, 6194, 0, 0, 119084, 0, 0, 0, 0, 6961, 0, 0, 0, 68426, 0, 42862, 0, - 0, 6192, 127900, 42771, 0, 0, 11435, 128445, 118797, 120800, 0, 12892, 0, - 128621, 67149, 0, 0, 0, 0, 120707, 0, 0, 19954, 0, 121164, 8983, 0, 0, 0, - 0, 0, 6198, 121344, 0, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 983509, 41323, 0, 0, 92289, 0, 0, 0, 983505, 41321, 12907, 3048, 7752, - 41320, 0, 0, 12819, 111247, 72127, 0, 0, 0, 0, 0, 72971, 0, 0, 0, 0, - 78650, 78649, 0, 41326, 0, 11806, 43167, 0, 1245, 0, 66463, 0, 0, 0, 0, - 0, 194619, 0, 194618, 0, 0, 194620, 0, 70403, 325, 12874, 128454, 74178, - 0, 0, 119110, 0, 0, 0, 0, 0, 0, 983563, 92175, 0, 0, 0, 121049, 0, 0, 0, - 0, 0, 0, 110844, 11776, 0, 19908, 0, 0, 0, 8753, 69278, 0, 0, 9511, - 43493, 0, 93032, 6205, 0, 0, 0, 0, 0, 0, 0, 0, 120269, 0, 41607, 0, 0, - 120617, 0, 0, 0, 7005, 41609, 9580, 0, 401, 0, 43779, 0, 127962, 0, - 65486, 0, 12857, 0, 11983, 0, 0, 0, 121371, 0, 194971, 74258, 983647, 0, - 0, 0, 0, 0, 8295, 6200, 0, 127864, 0, 0, 71435, 0, 92523, 0, 128631, 0, - 0, 125197, 0, 0, 0, 127556, 0, 0, 0, 64775, 0, 68862, 120590, 0, 0, - 129959, 8074, 8199, 126641, 1907, 127269, 4432, 127271, 10808, 120668, - 127272, 127259, 3888, 127261, 72724, 127263, 127262, 127265, 123169, - 121195, 127250, 66879, 127252, 100422, 66023, 67363, 7663, 0, 0, 0, 0, - 66321, 0, 12814, 127248, 127169, 0, 0, 194603, 7641, 92694, 0, 0, 0, 0, - 74320, 120818, 120268, 0, 128475, 0, 110627, 0, 9622, 128972, 120264, 0, - 0, 0, 0, 68319, 0, 0, 71484, 118613, 0, 0, 69906, 0, 0, 947, 0, 194586, - 129059, 10969, 119935, 7613, 119937, 119936, 4795, 119930, 119933, 7376, - 0, 0, 0, 72343, 0, 0, 0, 0, 119919, 7216, 119921, 7217, 119915, 7218, - 119917, 7219, 119927, 119926, 119929, 119928, 7213, 119922, 7214, 7215, - 128622, 0, 8880, 7685, 128849, 0, 0, 119618, 119853, 8187, 119913, 12815, - 7236, 7915, 71906, 0, 121284, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10468, 0, 0, 0, 0, 0, 0, 0, 0, 917909, 0, 110633, 1616, 3795, 67732, - 11529, 0, 126225, 0, 0, 1138, 194577, 12677, 0, 0, 3239, 0, 0, 194809, - 194583, 0, 42164, 0, 11778, 67473, 43259, 118543, 119073, 0, 0, 0, 67094, - 129638, 0, 78421, 128123, 78418, 0, 0, 0, 0, 43959, 43960, 0, 72257, 0, - 9359, 78416, 0, 0, 0, 6662, 0, 0, 3863, 0, 41329, 55266, 0, 127822, - 41328, 75026, 194569, 129516, 0, 0, 2178, 119595, 569, 0, 0, 0, 119085, - 110669, 0, 0, 11610, 11368, 0, 194570, 41331, 1006, 127747, 120883, 1550, - 8201, 0, 194811, 5499, 43956, 77908, 77910, 77906, 43957, 77904, 77905, - 128410, 0, 0, 129581, 100447, 43955, 77913, 0, 0, 5511, 0, 983721, 0, - 69241, 8255, 5512, 128560, 119560, 127858, 64313, 127928, 5906, 1119, - 128180, 67088, 983364, 0, 113798, 0, 66423, 0, 0, 0, 67089, 0, 0, 0, 0, - 128177, 983728, 0, 0, 0, 5821, 6186, 129960, 128034, 19961, 0, 983719, 0, - 65138, 302, 41113, 41115, 0, 6637, 5907, 128789, 0, 43642, 0, 128625, 0, - 70345, 5513, 6666, 100567, 78442, 5510, 0, 0, 0, 983725, 78437, 0, 0, 0, - 110838, 0, 0, 0, 92710, 0, 0, 0, 0, 0, 74497, 92395, 120511, 6929, 69412, - 0, 110835, 64442, 0, 0, 74496, 0, 6674, 43397, 0, 1476, 0, 0, 72276, - 3233, 0, 0, 10164, 118555, 0, 3530, 67243, 0, 111219, 6656, 0, 0, 74647, - 8512, 72275, 74261, 8967, 0, 0, 0, 72277, 7986, 73782, 120556, 9006, - 983562, 72273, 0, 7853, 0, 983357, 0, 0, 0, 0, 983971, 0, 0, 0, 0, 0, 0, - 0, 0, 127971, 67983, 13296, 517, 0, 0, 0, 41528, 19923, 65454, 0, 0, 0, - 10531, 7784, 41526, 71727, 0, 8057, 1126, 73895, 0, 0, 130040, 119186, - 4251, 8235, 43142, 0, 489, 71733, 4250, 71731, 110721, 43151, 94177, - 71725, 0, 121238, 0, 0, 0, 110726, 0, 8711, 6183, 110722, 110723, 0, 0, - 7623, 0, 0, 9235, 12760, 74176, 0, 0, 0, 0, 3743, 11514, 11078, 74582, 0, - 0, 126597, 0, 0, 0, 0, 983907, 267, 3393, 127504, 2364, 0, 69233, 6958, - 0, 6201, 0, 42360, 0, 10652, 41612, 917802, 3402, 917801, 3398, 0, 0, 0, - 3391, 70683, 0, 92541, 128017, 126087, 126590, 0, 12767, 0, 983377, - 64261, 0, 127537, 70852, 70347, 0, 6673, 0, 0, 129346, 12438, 0, 0, 0, - 71128, 0, 9053, 43954, 74523, 0, 0, 0, 6195, 0, 6660, 0, 917760, 917793, - 0, 12629, 0, 0, 0, 0, 0, 127940, 0, 0, 0, 65448, 0, 0, 121084, 129688, - 43949, 0, 78099, 0, 983382, 0, 0, 0, 5741, 1131, 0, 0, 74862, 0, 43952, - 42533, 119598, 78107, 0, 0, 43950, 121297, 118990, 7691, 43951, 578, 0, - 0, 0, 42514, 74547, 74196, 120608, 74561, 0, 983976, 0, 0, 0, 0, 0, 0, 0, - 0, 7241, 0, 93846, 119167, 0, 12811, 78082, 3946, 0, 10998, 66807, 673, - 0, 0, 0, 0, 119301, 0, 68890, 0, 0, 78085, 10267, 0, 74560, 78083, 0, - 8729, 0, 0, 0, 0, 0, 0, 0, 119296, 0, 0, 0, 2181, 983460, 731, 0, 71904, - 128316, 0, 0, 0, 1175, 0, 68167, 0, 0, 10793, 0, 67644, 7723, 983455, 0, - 0, 0, 0, 5273, 0, 5269, 0, 69607, 2404, 5267, 124967, 124913, 0, 5277, 0, - 0, 6189, 65469, 1314, 0, 0, 118873, 8785, 0, 0, 127527, 68414, 43535, - 9204, 0, 3879, 0, 71696, 6197, 9497, 0, 7567, 64484, 78128, 41390, 41379, + 0, 118548, 0, 0, 7080, 0, 128806, 122979, 0, 72388, 0, 11859, 0, 0, + 68878, 0, 0, 0, 7240, 0, 556, 0, 118544, 0, 0, 0, 72397, 0, 0, 0, 0, 0, + 0, 0, 0, 72986, 0, 0, 43931, 0, 11093, 0, 0, 122960, 7341, 66801, 68527, + 0, 1874, 0, 0, 129314, 0, 0, 0, 0, 0, 0, 7688, 0, 0, 9036, 0, 0, 66389, + 0, 121347, 0, 0, 10100, 0, 2725, 0, 0, 43981, 42128, 0, 0, 68146, 0, 0, + 0, 0, 71349, 7859, 1945, 0, 0, 0, 65918, 7188, 9992, 0, 7389, 127008, + 71341, 0, 0, 0, 528, 129681, 44017, 11429, 71347, 0, 0, 120864, 0, 0, 0, + 11530, 73102, 6188, 0, 0, 68208, 1823, 0, 0, 92928, 0, 64843, 7233, + 92929, 0, 0, 6639, 0, 0, 123149, 0, 1176, 0, 0, 8276, 128667, 0, 0, + 68892, 42931, 0, 0, 0, 0, 0, 0, 0, 5388, 0, 0, 0, 11310, 0, 123607, 0, + 68888, 4199, 119264, 0, 119020, 0, 0, 9560, 0, 0, 43869, 0, 0, 0, 83172, + 0, 0, 0, 83173, 101559, 128875, 0, 0, 74327, 0, 0, 0, 0, 0, 123623, + 68886, 0, 0, 0, 8408, 64704, 0, 0, 0, 0, 118711, 67999, 0, 0, 0, 0, + 43049, 0, 43050, 73028, 0, 0, 0, 0, 0, 127396, 0, 69847, 9322, 0, 0, + 129321, 68192, 120507, 983634, 0, 0, 0, 6199, 67249, 0, 0, 0, 0, 11329, + 66285, 0, 983086, 0, 0, 0, 0, 41335, 118866, 43401, 0, 41334, 0, 0, 0, + 983484, 71997, 983483, 128114, 0, 42627, 0, 32, 6187, 0, 123619, 983480, + 3665, 121083, 42871, 983119, 41336, 0, 0, 983476, 0, 0, 0, 4412, 0, 0, 0, + 0, 119533, 0, 4181, 0, 0, 127589, 0, 0, 71453, 6181, 74755, 917895, 0, 0, + 0, 73557, 121107, 0, 0, 10073, 0, 100738, 127186, 0, 42844, 7498, 1098, + 92565, 119530, 0, 0, 10207, 0, 983233, 0, 983555, 0, 9234, 0, 6182, 0, + 92552, 0, 0, 0, 0, 5471, 9461, 6697, 0, 5473, 0, 0, 0, 0, 0, 0, 70073, 0, + 0, 7767, 8304, 41339, 0, 983494, 69450, 0, 0, 983492, 43855, 41337, 0, 0, + 0, 129706, 0, 0, 0, 72396, 0, 0, 0, 42633, 0, 0, 0, 0, 0, 0, 0, 70005, + 129506, 0, 0, 0, 129580, 69817, 128299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1437, + 41617, 0, 0, 0, 128853, 0, 0, 0, 0, 0, 128529, 12113, 0, 42772, 0, 0, + 7693, 10749, 67485, 65210, 5773, 978, 128134, 0, 41619, 10239, 0, 0, 0, + 74328, 0, 9748, 0, 0, 0, 0, 0, 0, 0, 70681, 0, 72811, 0, 67464, 0, 92776, + 0, 0, 2379, 11325, 0, 0, 67854, 0, 78547, 42209, 0, 120392, 2369, 0, + 984003, 984004, 0, 0, 73936, 7008, 69415, 122919, 0, 43841, 2367, 127827, + 983888, 0, 2375, 8060, 6194, 0, 0, 119084, 0, 0, 0, 0, 6961, 0, 0, 0, + 68426, 0, 42862, 0, 0, 6192, 127900, 42771, 0, 0, 11435, 128445, 118797, + 120800, 0, 12892, 0, 128621, 67149, 0, 0, 0, 0, 120707, 0, 0, 19954, 0, + 121164, 8983, 0, 0, 0, 0, 0, 6198, 121344, 0, 196, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 983512, 41323, 0, 0, 92289, 0, 0, 0, 983508, 41321, + 12907, 3048, 7752, 41320, 0, 0, 12819, 111247, 72127, 0, 0, 0, 0, 0, + 72971, 0, 0, 0, 0, 78650, 78649, 0, 41326, 0, 11806, 43167, 0, 1245, 0, + 66463, 0, 0, 0, 0, 0, 194619, 0, 194618, 0, 0, 194620, 0, 70403, 325, + 12874, 128454, 74178, 0, 0, 119110, 0, 0, 0, 0, 0, 0, 983563, 92175, 0, + 125016, 0, 121049, 0, 0, 0, 0, 0, 0, 110844, 11776, 0, 19908, 0, 0, 0, + 8753, 69278, 0, 0, 9511, 43493, 0, 93032, 6205, 0, 0, 0, 0, 0, 78928, 0, + 0, 120269, 0, 41607, 0, 0, 120617, 0, 0, 0, 7005, 41609, 9580, 0, 401, 0, + 43779, 0, 127962, 0, 65486, 0, 12857, 0, 11983, 0, 0, 0, 121371, 0, + 194971, 74258, 983647, 0, 0, 0, 0, 0, 8295, 6200, 0, 127864, 0, 0, 71435, + 0, 92523, 0, 128631, 0, 0, 125197, 0, 100426, 0, 127556, 0, 0, 0, 64775, + 0, 68862, 120590, 0, 0, 129959, 8074, 8199, 126641, 1907, 127269, 4432, + 127271, 10808, 120668, 127272, 127259, 3888, 127261, 72724, 127263, + 127262, 127265, 123169, 121195, 127250, 66879, 127252, 100422, 66023, + 67363, 7663, 0, 0, 0, 0, 66321, 0, 12814, 127248, 127169, 0, 0, 194603, + 7641, 92694, 0, 0, 0, 0, 74320, 120818, 120268, 0, 128475, 0, 110627, 0, + 9622, 128972, 120264, 0, 0, 0, 0, 68319, 0, 0, 71484, 118613, 0, 0, + 69906, 0, 0, 947, 0, 194586, 129059, 10969, 119935, 7613, 119937, 119936, + 4795, 119930, 119933, 7376, 0, 0, 0, 72343, 69373, 0, 0, 0, 119919, 7216, + 119921, 7217, 119915, 7218, 119917, 7219, 119927, 119926, 119929, 119928, + 7213, 119922, 7214, 7215, 128622, 0, 8880, 7685, 128849, 0, 0, 119618, + 119853, 8187, 119913, 12815, 7236, 7915, 71906, 0, 121284, 0, 0, 0, 0, 0, + 0, 0, 122969, 0, 0, 0, 0, 0, 10468, 0, 0, 0, 0, 0, 0, 0, 0, 917909, 0, + 110633, 1616, 3795, 67732, 11529, 0, 126225, 0, 0, 1138, 194577, 12677, + 0, 0, 3239, 0, 0, 194809, 194583, 0, 42164, 0, 11778, 67473, 43259, + 118543, 119073, 122975, 0, 0, 67094, 129638, 0, 78421, 128123, 78418, 0, + 0, 0, 0, 43959, 43960, 0, 72257, 0, 9359, 78416, 0, 0, 0, 6662, 0, 0, + 3863, 0, 41329, 55266, 0, 127822, 41328, 75026, 194569, 129516, 0, 0, + 2178, 119595, 569, 0, 0, 0, 119085, 110669, 0, 0, 11610, 11368, 0, + 194570, 41331, 1006, 127747, 120883, 1550, 8201, 0, 194811, 5499, 43956, + 77908, 77910, 77906, 43957, 77904, 77905, 128410, 0, 0, 129581, 100447, + 43955, 77913, 122989, 0, 5511, 0, 983721, 0, 69241, 8255, 5512, 128560, + 119560, 127858, 64313, 127928, 5906, 1119, 128180, 67088, 983367, 0, + 113798, 0, 66423, 0, 0, 0, 67089, 0, 0, 0, 0, 128177, 983728, 0, 0, 0, + 5821, 6186, 129960, 128034, 19961, 0, 983719, 0, 65138, 302, 41113, + 41115, 0, 6637, 5907, 128789, 0, 43642, 0, 128625, 0, 70345, 5513, 6666, + 100567, 78442, 5510, 0, 0, 0, 983725, 78437, 0, 0, 0, 110838, 0, 0, 0, + 92710, 0, 0, 0, 0, 0, 74497, 92395, 120511, 6929, 69412, 0, 110835, + 64442, 0, 0, 74496, 0, 6674, 43397, 0, 1476, 0, 0, 72276, 3233, 0, 0, + 10164, 118555, 0, 3530, 67243, 0, 111219, 6656, 0, 0, 74647, 8512, 72275, + 74261, 8967, 0, 0, 0, 72277, 7986, 73782, 120556, 9006, 983562, 72273, 0, + 7853, 0, 983360, 0, 0, 0, 0, 983971, 0, 0, 0, 0, 0, 0, 0, 0, 127971, + 67983, 13296, 517, 0, 0, 0, 41528, 19923, 65454, 73518, 0, 0, 10531, + 7784, 41526, 71727, 0, 8057, 1126, 73895, 0, 0, 130040, 119186, 4251, + 8235, 43142, 0, 489, 71733, 4250, 71731, 110721, 43151, 94177, 71725, 0, + 121238, 0, 0, 0, 110726, 0, 8711, 6183, 110722, 110723, 0, 0, 7623, 0, 0, + 9235, 12760, 74176, 0, 0, 0, 0, 3743, 11514, 11078, 74582, 0, 0, 126597, + 0, 0, 0, 0, 983907, 267, 3393, 127504, 2364, 0, 69233, 6958, 0, 6201, 0, + 42360, 0, 10652, 41612, 917802, 3402, 917801, 3398, 0, 0, 0, 3391, 70683, + 0, 92541, 128017, 126087, 126590, 0, 12767, 0, 983380, 64261, 0, 127537, + 70852, 70347, 0, 6673, 0, 0, 129346, 12438, 0, 0, 0, 71128, 0, 9053, + 43954, 74523, 0, 0, 0, 6195, 0, 6660, 0, 917760, 917793, 0, 12629, 0, 0, + 0, 0, 0, 127940, 0, 0, 0, 65448, 0, 0, 121084, 129688, 43949, 0, 78099, + 0, 983385, 0, 0, 0, 5741, 1131, 0, 0, 74862, 0, 43952, 42533, 119598, + 78107, 0, 0, 43950, 121297, 118990, 7691, 43951, 578, 0, 0, 0, 42514, + 74547, 74196, 120608, 74561, 0, 983976, 0, 0, 0, 0, 0, 0, 0, 0, 7241, 0, + 93846, 119167, 0, 12811, 78082, 3946, 0, 10998, 66807, 673, 0, 0, 0, 0, + 119301, 0, 68890, 0, 0, 78085, 10267, 0, 74560, 78083, 0, 8729, 0, 0, 0, + 0, 0, 0, 0, 119296, 0, 0, 0, 2181, 983463, 731, 0, 71904, 128316, 0, + 73539, 0, 1175, 0, 68167, 0, 0, 10793, 0, 67644, 7723, 983458, 0, 0, 0, + 0, 5273, 0, 5269, 0, 69607, 2404, 5267, 124967, 124913, 0, 5277, 0, 0, + 6189, 65469, 1314, 0, 0, 118873, 8785, 0, 0, 127527, 68414, 43535, 9204, + 0, 3879, 0, 71696, 6197, 9497, 0, 7567, 64484, 78128, 41390, 41379, 41882, 67647, 67279, 70085, 0, 121413, 41388, 64446, 41392, 64288, 41387, 0, 8706, 10675, 0, 700, 0, 5775, 0, 7088, 74756, 7499, 0, 78120, 78111, 67251, 126557, 0, 0, 128945, 10311, 78115, 6665, 11115, 0, 7618, 10821, @@ -25304,17 +25484,17 @@ static const unsigned int code_hash[] = { 42087, 3063, 0, 0, 7838, 0, 129282, 0, 0, 67968, 0, 128582, 9078, 92446, 0, 0, 0, 0, 0, 0, 119586, 0, 7750, 128422, 68237, 6190, 0, 0, 0, 72340, 9857, 7014, 9856, 0, 92620, 120547, 0, 8481, 0, 6202, 0, 10920, 67970, 0, - 0, 983294, 0, 7843, 65818, 66824, 0, 0, 0, 0, 0, 0, 0, 6657, 207, 0, + 0, 983297, 0, 7843, 65818, 66824, 0, 73481, 0, 0, 0, 0, 0, 6657, 207, 0, 69728, 74819, 0, 0, 0, 0, 0, 0, 0, 0, 41368, 43974, 488, 0, 0, 71339, 10157, 118700, 43034, 11982, 0, 0, 0, 0, 0, 41372, 6669, 8504, 72103, 0, 41367, 129328, 119272, 0, 11726, 8261, 129793, 304, 129799, 129795, - 129822, 129807, 113683, 983236, 238, 74522, 0, 0, 19905, 120577, 983471, - 129200, 41044, 67640, 67302, 64814, 9912, 65939, 983467, 0, 0, 0, 917925, + 129822, 129807, 113683, 983239, 238, 74522, 0, 0, 19905, 120577, 122968, + 129200, 41044, 67640, 67302, 64814, 9912, 65939, 983470, 0, 0, 0, 917925, 0, 0, 309, 6622, 0, 10858, 0, 67636, 0, 72749, 0, 0, 0, 67637, 123138, 9712, 68680, 43970, 0, 65165, 93047, 983831, 0, 0, 0, 0, 0, 6191, 12944, 0, 0, 67634, 43763, 0, 0, 67635, 9370, 41381, 0, 0, 123148, 118817, 0, - 3222, 121439, 0, 0, 66663, 0, 0, 0, 0, 0, 65732, 121144, 0, 983217, 0, 0, - 67309, 72192, 41383, 64568, 0, 0, 0, 0, 984009, 66725, 0, 0, 0, 0, 0, + 3222, 121439, 0, 0, 66663, 0, 0, 0, 0, 0, 65732, 121144, 0, 983219, 0, 0, + 67309, 72192, 41383, 64568, 0, 0, 0, 0, 984009, 66725, 0, 0, 0, 0, 73766, 67306, 3632, 128246, 0, 8376, 3648, 0, 74844, 67639, 3636, 0, 3650, 8837, 0, 0, 0, 43250, 41562, 0, 0, 68839, 3640, 127190, 0, 11781, 0, 0, 0, 0, 129659, 0, 126649, 0, 42080, 2529, 0, 78004, 0, 42083, 0, 0, 120531, @@ -25327,97 +25507,97 @@ static const unsigned int code_hash[] = { 12753, 0, 983753, 67626, 67722, 0, 0, 0, 0, 12751, 74906, 8542, 0, 0, 3626, 66706, 0, 0, 3883, 64388, 0, 0, 0, 0, 0, 0, 126268, 67624, 0, 10932, 0, 65585, 64338, 806, 0, 41884, 110845, 1318, 128828, 0, 0, 0, - 983808, 3465, 2405, 983392, 0, 12756, 65259, 69381, 983812, 12752, 5833, + 983808, 3465, 2405, 983395, 0, 12756, 65259, 69381, 983812, 12752, 5833, 1432, 110843, 41883, 110841, 9799, 0, 41886, 0, 0, 2062, 0, 0, 0, 0, - 129376, 0, 124969, 983389, 0, 120971, 0, 118832, 0, 983283, 0, 68005, + 129376, 0, 124969, 983392, 0, 120971, 0, 118832, 0, 983286, 0, 68005, 10622, 0, 0, 0, 6566, 71195, 0, 73780, 0, 68865, 0, 0, 0, 8284, 0, 0, 0, - 0, 0, 43023, 0, 983287, 6642, 3977, 72743, 64729, 836, 983383, 92947, 0, + 0, 0, 43023, 0, 983290, 6642, 3977, 72743, 64729, 836, 983386, 92947, 0, 0, 0, 0, 0, 0, 125239, 917923, 0, 0, 0, 0, 0, 0, 1374, 65149, 119014, 67720, 0, 2273, 0, 0, 0, 11234, 0, 0, 9630, 12597, 0, 0, 0, 6661, 0, 113751, 120551, 125015, 0, 0, 72151, 0, 73674, 7718, 113755, 0, 69570, 0, - 0, 983777, 0, 0, 0, 127841, 6365, 1887, 983411, 0, 8080, 113681, 0, 0, 0, - 129855, 1544, 0, 0, 64677, 0, 0, 0, 0, 119019, 0, 0, 12812, 7342, 0, + 0, 983777, 0, 0, 0, 127841, 6365, 1887, 983414, 0, 8080, 113681, 0, 0, 0, + 129855, 1544, 0, 0, 64677, 0, 0, 0, 0, 73561, 0, 0, 12812, 7342, 0, 73784, 66947, 7904, 0, 0, 120910, 0, 0, 0, 0, 9724, 0, 983804, 9524, 0, - 0, 0, 0, 0, 129344, 0, 471, 0, 0, 128302, 0, 0, 0, 983769, 0, 0, 6918, - 118685, 0, 5156, 0, 128683, 10232, 10615, 10213, 0, 0, 42528, 0, 0, 0, 0, - 65311, 74935, 0, 13306, 10533, 7870, 0, 7625, 0, 120544, 0, 0, 128816, - 126098, 118870, 0, 92819, 0, 0, 92341, 0, 12978, 128533, 0, 0, 43836, - 42675, 0, 12845, 0, 19942, 0, 0, 0, 0, 0, 120000, 120008, 120001, 0, - 194894, 0, 0, 0, 0, 7186, 73107, 0, 70093, 445, 119028, 0, 0, 0, 73047, - 0, 0, 128442, 0, 0, 0, 3902, 68913, 129916, 0, 0, 1560, 43958, 0, 4584, - 0, 67862, 0, 10866, 92905, 1118, 92209, 74888, 0, 1081, 7436, 11147, - 7252, 0, 121188, 0, 0, 0, 41386, 5162, 129823, 1330, 0, 121270, 0, 12047, - 7675, 0, 0, 1848, 74528, 983147, 64708, 0, 0, 194880, 0, 0, 0, 983772, - 12715, 128349, 0, 0, 0, 66672, 73710, 66685, 0, 0, 92464, 0, 68884, 0, - 72835, 123546, 70800, 70101, 120725, 0, 194893, 9214, 43494, 0, 0, - 120841, 0, 0, 6313, 65513, 119355, 0, 0, 0, 2345, 72975, 0, 0, 129937, 0, - 3117, 0, 71882, 0, 73100, 0, 0, 0, 0, 78415, 983233, 100907, 0, 13248, 0, - 120241, 129416, 128415, 0, 94193, 12382, 71120, 0, 0, 0, 0, 1471, 0, + 0, 0, 0, 0, 129344, 0, 471, 0, 0, 128302, 72450, 0, 0, 983769, 0, 0, + 6918, 118685, 0, 5156, 0, 128683, 10232, 10615, 10213, 0, 0, 42528, 0, 0, + 0, 0, 65311, 74935, 0, 13306, 10533, 7870, 0, 7625, 0, 120544, 0, 0, + 128816, 126098, 118870, 0, 92819, 0, 0, 92341, 0, 12978, 128533, 0, 0, + 43836, 42675, 0, 12845, 0, 19942, 0, 0, 0, 0, 0, 120000, 120008, 120001, + 0, 194894, 983746, 0, 0, 0, 7186, 73107, 0, 70093, 445, 119028, 0, 0, 0, + 73047, 0, 0, 128442, 0, 0, 0, 3902, 68913, 129916, 0, 0, 1560, 43958, 0, + 4584, 0, 67862, 0, 10866, 92905, 1118, 92209, 74888, 0, 1081, 7436, + 11147, 7252, 0, 121188, 0, 0, 0, 41386, 5162, 129823, 1330, 0, 121270, 0, + 12047, 7675, 0, 0, 1848, 74528, 983148, 64708, 0, 0, 194880, 0, 0, 0, + 983772, 12715, 128349, 0, 101402, 0, 66672, 73710, 66685, 0, 0, 92464, 0, + 68884, 0, 72835, 123546, 70800, 70101, 120725, 0, 194893, 9214, 43494, 0, + 0, 120841, 0, 0, 6313, 65513, 119355, 0, 0, 0, 2345, 72975, 0, 0, 129937, + 0, 3117, 0, 71882, 0, 73100, 0, 0, 0, 0, 78415, 983236, 100907, 0, 13248, + 0, 120241, 129416, 128415, 0, 94193, 12382, 71120, 0, 0, 0, 0, 1471, 0, 113747, 0, 12378, 0, 69664, 0, 12374, 121357, 0, 0, 0, 0, 0, 0, 12376, 0, 0, 0, 12380, 10557, 0, 12520, 11122, 2024, 127180, 0, 0, 74588, 0, 0, 70120, 3853, 0, 0, 0, 983763, 0, 0, 12090, 0, 12474, 92579, 9503, 0, 0, - 983273, 68318, 0, 110834, 0, 0, 0, 12470, 0, 74189, 2742, 12476, 66370, - 10946, 0, 12472, 0, 0, 0, 0, 8213, 43824, 7771, 6161, 983277, 68010, 0, + 73505, 68318, 0, 110834, 0, 0, 0, 12470, 0, 74189, 2742, 12476, 66370, + 10946, 0, 12472, 0, 0, 0, 0, 8213, 43824, 7771, 6161, 983280, 68010, 0, 0, 0, 68235, 0, 0, 0, 120985, 0, 0, 0, 129814, 73791, 129830, 68871, 0, 0, 0, 0, 0, 73704, 12015, 128561, 8275, 0, 43459, 120927, 127555, 0, 0, 0, 68881, 71215, 983642, 118841, 0, 12516, 4444, 0, 119017, 120506, 10892, 118828, 0, 6473, 0, 0, 71735, 3591, 0, 0, 0, 0, 72345, 0, 0, 0, - 127547, 0, 0, 0, 0, 128253, 0, 0, 0, 0, 94060, 687, 0, 0, 983401, 0, 0, + 127547, 0, 0, 0, 0, 128253, 0, 0, 0, 0, 94060, 687, 0, 0, 983404, 0, 0, 43882, 0, 128526, 285, 0, 0, 0, 4459, 0, 0, 74917, 0, 0, 126255, 0, 119248, 0, 9743, 0, 0, 126535, 0, 0, 73104, 0, 69659, 0, 0, 3081, 74577, 42921, 0, 0, 0, 0, 0, 0, 0, 9125, 119023, 0, 120820, 0, 65221, 0, 0, 64852, 0, 0, 0, 0, 66578, 5001, 41879, 0, 0, 5003, 884, 0, 0, 4943, 5150, - 73889, 74182, 0, 41876, 0, 0, 42448, 42299, 72804, 0, 0, 0, 0, 8491, 0, - 0, 983635, 4530, 42409, 7126, 119526, 66200, 0, 118559, 19929, 0, 0, 0, - 4242, 0, 0, 0, 0, 66034, 65941, 124929, 64522, 10740, 8958, 128257, 9754, - 119102, 983248, 74222, 983246, 983245, 119064, 983243, 983242, 0, 0, 0, - 74518, 66026, 4306, 41468, 68432, 0, 0, 66667, 0, 0, 983496, 42200, 0, 0, - 0, 120236, 6948, 0, 8524, 0, 0, 12385, 0, 74926, 0, 1386, 73996, 0, 0, 0, - 121184, 12392, 0, 8064, 0, 0, 78216, 119004, 2080, 710, 128491, 12390, - 1666, 42091, 0, 12383, 92968, 42092, 68418, 0, 128106, 0, 0, 42096, 0, - 3362, 12377, 127878, 0, 0, 0, 0, 1244, 4401, 73786, 12683, 10662, 0, - 8112, 129837, 119021, 121017, 12379, 73108, 120534, 0, 42208, 0, 12381, - 0, 0, 0, 4327, 0, 0, 128350, 0, 78232, 0, 584, 12933, 0, 12373, 73105, - 13000, 0, 2935, 129113, 12665, 0, 43081, 73098, 120505, 12427, 0, 983625, - 78227, 0, 0, 0, 0, 128760, 74551, 0, 0, 12426, 0, 0, 0, 12428, 0, 0, 0, - 0, 0, 12429, 6727, 0, 0, 0, 3387, 0, 0, 0, 0, 0, 0, 74427, 0, 3536, - 120589, 9752, 92397, 6162, 0, 0, 10113, 0, 0, 0, 12422, 0, 439, 3072, 0, - 42207, 74549, 120830, 0, 0, 0, 0, 8308, 0, 70807, 0, 0, 0, 13218, 0, 0, - 8082, 12424, 0, 6819, 3539, 93838, 0, 0, 74539, 0, 68181, 0, 72964, 0, - 72969, 12420, 11371, 0, 4600, 0, 127810, 0, 0, 0, 72962, 128552, 6704, - 4591, 72966, 0, 0, 0, 72960, 120623, 561, 12159, 78223, 0, 78224, 0, - 71068, 11932, 7172, 42687, 8368, 0, 0, 93068, 0, 0, 75010, 0, 0, 0, 0, - 42463, 0, 2924, 67183, 0, 129947, 0, 128958, 0, 0, 42330, 73079, 3969, 0, - 129973, 7169, 1992, 9652, 0, 0, 42086, 0, 100865, 0, 0, 0, 0, 0, 327, 0, - 0, 0, 0, 0, 12433, 0, 0, 118570, 12431, 0, 12434, 983436, 0, 0, 0, 7712, - 12432, 0, 69377, 129147, 100867, 0, 8212, 0, 128014, 0, 119066, 7333, 0, - 0, 0, 67407, 70006, 128461, 0, 12436, 0, 43160, 0, 74896, 92757, 71360, - 42350, 0, 0, 0, 100566, 0, 11348, 0, 0, 9194, 983184, 0, 55250, 0, - 100569, 0, 0, 0, 0, 0, 64746, 66012, 100565, 3444, 75029, 64651, 0, - 41503, 0, 0, 0, 0, 0, 0, 0, 120876, 0, 0, 129408, 65309, 12416, 0, 0, 0, - 0, 93024, 12418, 74111, 121046, 0, 0, 0, 119361, 0, 4596, 66339, 12417, - 66001, 0, 126491, 12414, 8287, 0, 69499, 0, 1143, 0, 0, 12415, 0, 0, - 983244, 0, 9021, 120783, 0, 11724, 0, 0, 0, 194794, 0, 0, 8027, 194796, - 74257, 127375, 11400, 74197, 194799, 66833, 194798, 0, 0, 983249, 0, 0, - 1324, 0, 0, 0, 194878, 7715, 0, 0, 194777, 194780, 0, 0, 0, 194787, 0, 0, - 0, 0, 0, 66289, 127109, 3889, 129561, 194800, 0, 0, 0, 0, 121226, 12999, - 0, 120902, 0, 0, 0, 0, 0, 64802, 42210, 4597, 983133, 0, 0, 12371, 67164, - 0, 67163, 10805, 0, 0, 0, 0, 118662, 12367, 0, 0, 92557, 12363, 0, 0, - 128611, 983645, 0, 0, 8005, 12365, 0, 0, 3756, 12369, 10649, 0, 70095, 0, - 0, 0, 42923, 0, 0, 0, 0, 0, 0, 66659, 0, 0, 0, 0, 5268, 4954, 0, 0, 5266, - 126980, 5272, 92294, 0, 42230, 983980, 0, 9128, 0, 0, 0, 0, 6928, 9803, - 42282, 9110, 1505, 0, 0, 5276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8722, 120805, - 0, 0, 66695, 0, 0, 4383, 8900, 0, 0, 74930, 64297, 0, 0, 0, 0, 3419, - 42229, 0, 0, 8911, 0, 42353, 0, 0, 0, 0, 0, 0, 0, 100629, 41576, 42215, - 122888, 0, 0, 8578, 68178, 7573, 41575, 74789, 92310, 0, 73863, 0, 2670, - 0, 0, 11723, 0, 0, 0, 0, 0, 43414, 0, 0, 65675, 0, 67179, 67168, 12413, - 129746, 67177, 0, 0, 0, 0, 12302, 0, 5250, 12407, 12245, 4404, 9189, - 12401, 42007, 0, 42005, 65806, 43997, 122922, 42002, 12404, 0, 74928, - 4940, 12410, 0, 128761, 0, 64567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11956, 0, - 0, 122882, 0, 6631, 128923, 120704, 74583, 42218, 0, 0, 70094, 0, 0, 0, - 71058, 0, 0, 0, 127341, 0, 0, 0, 0, 0, 43370, 0, 5016, 121052, 0, 0, - 9491, 0, 0, 0, 0, 64922, 0, 0, 0, 0, 92198, 0, 118622, 0, 74619, 0, 0, - 70422, 983688, 10565, 0, 12177, 0, 0, 0, 0, 0, 12395, 127874, 12878, + 73889, 74182, 0, 41876, 0, 78915, 42448, 42299, 72804, 0, 0, 0, 0, 8491, + 0, 0, 983635, 4530, 42409, 7126, 119526, 66200, 0, 118559, 19929, 0, 0, + 0, 4242, 0, 0, 0, 0, 66034, 65941, 124929, 64522, 10740, 8958, 128257, + 9754, 119102, 983251, 74222, 983249, 983248, 119064, 983246, 983245, 0, + 0, 0, 74518, 66026, 4306, 41468, 68432, 0, 0, 66667, 0, 0, 983499, 42200, + 0, 0, 0, 120236, 6948, 0, 8524, 0, 0, 12385, 0, 74926, 0, 1386, 73996, 0, + 0, 0, 121184, 12392, 0, 8064, 0, 0, 78216, 119004, 2080, 710, 128491, + 12390, 1666, 42091, 0, 12383, 92968, 42092, 68418, 0, 128106, 0, 0, + 42096, 0, 3362, 12377, 127878, 0, 0, 0, 0, 1244, 4401, 73786, 12683, + 10662, 0, 8112, 129837, 119021, 121017, 12379, 73108, 120534, 0, 42208, + 0, 12381, 0, 0, 0, 4327, 0, 0, 128350, 0, 78232, 0, 584, 12933, 0, 12373, + 73105, 13000, 0, 2935, 129113, 12665, 0, 43081, 73098, 120505, 12427, 0, + 983625, 78227, 0, 0, 0, 0, 128760, 74551, 0, 0, 12426, 0, 73497, 0, + 12428, 0, 0, 0, 0, 0, 12429, 6727, 0, 0, 0, 3387, 0, 0, 0, 0, 0, 0, + 73517, 0, 3536, 120589, 9752, 92397, 6162, 0, 0, 10113, 0, 0, 0, 12422, + 0, 439, 3072, 0, 42207, 74549, 120830, 0, 0, 0, 0, 8308, 0, 70807, 0, 0, + 0, 13218, 0, 0, 8082, 12424, 0, 6819, 3539, 93838, 0, 0, 74539, 0, 68181, + 0, 72964, 0, 72969, 12420, 11371, 0, 4600, 0, 127810, 0, 0, 0, 72962, + 128552, 6704, 4591, 72966, 0, 0, 0, 72960, 120623, 561, 12159, 78223, 0, + 78224, 0, 71068, 11932, 7172, 42687, 8368, 0, 0, 93068, 0, 0, 75010, 0, + 0, 0, 0, 42463, 0, 2924, 67183, 0, 129947, 0, 128958, 0, 0, 42330, 73079, + 3969, 0, 129973, 7169, 1992, 9652, 0, 0, 42086, 0, 100865, 0, 0, 0, 0, 0, + 327, 0, 0, 0, 0, 73509, 12433, 0, 0, 118570, 12431, 0, 12434, 983439, 0, + 73544, 0, 7712, 12432, 0, 69377, 129147, 100867, 0, 8212, 0, 128014, 0, + 119066, 7333, 0, 0, 0, 67407, 70006, 128461, 0, 12436, 0, 43160, 0, + 74896, 92757, 71360, 42350, 0, 0, 0, 100566, 0, 11348, 0, 0, 9194, + 983185, 0, 55250, 0, 100569, 0, 0, 0, 0, 0, 64746, 66012, 100565, 3444, + 75029, 64651, 0, 41503, 0, 0, 0, 0, 0, 0, 0, 120876, 0, 0, 129408, 65309, + 12416, 0, 0, 0, 0, 93024, 12418, 74111, 121046, 0, 0, 0, 119361, 0, 4596, + 66339, 12417, 66001, 0, 126491, 12414, 8287, 0, 69499, 0, 1143, 0, 0, + 12415, 0, 0, 983247, 0, 9021, 120783, 0, 11724, 0, 0, 0, 194794, 0, 0, + 8027, 194796, 74257, 127375, 11400, 74197, 194799, 66833, 194798, 0, 0, + 983252, 0, 0, 1324, 0, 0, 0, 194878, 7715, 0, 0, 194777, 194780, 0, 0, 0, + 194787, 0, 0, 0, 0, 0, 66289, 127109, 3889, 129561, 194800, 0, 0, 0, 0, + 121226, 12999, 0, 120902, 0, 0, 0, 0, 0, 64802, 42210, 4597, 983134, 0, + 0, 12371, 67164, 0, 67163, 10805, 0, 0, 0, 0, 118662, 12367, 0, 0, 92557, + 12363, 0, 0, 128611, 983645, 0, 0, 8005, 12365, 0, 0, 3756, 12369, 10649, + 0, 70095, 0, 0, 0, 42923, 0, 0, 0, 0, 0, 0, 66659, 0, 0, 0, 0, 5268, + 4954, 0, 0, 5266, 126980, 5272, 92294, 0, 42230, 983980, 0, 9128, 0, 0, + 0, 0, 6928, 9803, 42282, 9110, 1505, 0, 0, 5276, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8722, 120805, 0, 0, 66695, 0, 0, 4383, 8900, 0, 0, 74930, 64297, 0, 0, + 0, 0, 3419, 42229, 0, 0, 8911, 0, 42353, 0, 0, 0, 0, 0, 0, 0, 100629, + 41576, 42215, 122888, 0, 0, 8578, 68178, 7573, 41575, 74789, 92310, 0, + 73863, 0, 2670, 0, 0, 11723, 0, 0, 0, 0, 0, 43414, 0, 0, 65675, 0, 67179, + 67168, 12413, 129746, 67177, 0, 0, 0, 0, 12302, 0, 5250, 12407, 12245, + 4404, 9189, 12401, 42007, 0, 42005, 65806, 43997, 122922, 42002, 12404, + 0, 74928, 4940, 12410, 0, 128761, 0, 64567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 11956, 0, 0, 122882, 0, 6631, 128923, 120704, 74583, 42218, 0, 0, 70094, + 0, 0, 0, 71058, 0, 0, 0, 127341, 0, 0, 0, 0, 0, 43370, 0, 5016, 121052, + 0, 0, 9491, 0, 0, 0, 0, 64922, 0, 0, 0, 0, 92198, 0, 118622, 0, 74619, 0, + 0, 70422, 983688, 10565, 0, 12177, 0, 0, 0, 0, 0, 12395, 127874, 12878, 92630, 12396, 0, 0, 92537, 0, 43113, 0, 0, 0, 9781, 0, 4927, 0, 0, 0, 0, 12397, 129089, 128910, 0, 12394, 0, 0, 0, 0, 0, 72789, 10781, 1546, 0, 5010, 0, 10507, 127891, 128291, 0, 0, 0, 0, 7267, 0, 0, 0, 0, 2819, 0, 0, @@ -25464,10 +25644,10 @@ static const unsigned int code_hash[] = { 67600, 67477, 0, 127293, 8575, 127295, 127296, 127289, 127290, 127291, 127292, 127285, 127286, 127287, 118877, 127281, 127282, 9460, 823, 11587, 0, 0, 0, 127305, 12387, 0, 0, 127301, 126979, 42783, 69998, 64208, - 127298, 127299, 66031, 0, 11606, 64784, 0, 69973, 0, 0, 0, 5152, 11048, - 0, 120121, 67605, 0, 69604, 0, 70276, 194847, 0, 127052, 42587, 42214, - 41394, 0, 4763, 0, 118935, 0, 5260, 0, 94038, 326, 120131, 74119, 0, - 10771, 42198, 194920, 194835, 194925, 41398, 127079, 41393, 127077, + 127298, 127299, 66031, 0, 11606, 64784, 0, 69973, 0, 124149, 0, 5152, + 11048, 0, 120121, 67605, 0, 69604, 0, 70276, 194847, 0, 127052, 42587, + 42214, 41394, 0, 4763, 0, 118935, 0, 5260, 0, 94038, 326, 120131, 74119, + 0, 10771, 42198, 194920, 194835, 194925, 41398, 127079, 41393, 127077, 127076, 453, 41396, 0, 13159, 11227, 9572, 0, 0, 194576, 128835, 127081, 0, 126617, 43144, 0, 72972, 194887, 0, 0, 0, 0, 0, 64061, 0, 0, 64056, 70310, 0, 0, 0, 66971, 0, 111084, 64301, 72998, 10464, 0, 128393, 72847, @@ -25481,7 +25661,7 @@ static const unsigned int code_hash[] = { 194829, 1833, 11576, 74334, 0, 0, 42854, 69438, 0, 70307, 0, 194856, 8085, 0, 194850, 0, 72996, 128778, 1949, 11614, 7847, 120489, 120997, 64483, 0, 0, 0, 122639, 0, 0, 0, 126651, 42864, 0, 64667, 74624, 0, 0, - 43261, 11484, 127535, 67840, 0, 0, 128965, 0, 72974, 0, 110928, 8995, + 43261, 11484, 127535, 67840, 0, 0, 128965, 0, 72974, 0, 72456, 8995, 3455, 0, 0, 9879, 0, 0, 4158, 128050, 0, 0, 110929, 0, 0, 0, 332, 118808, 0, 0, 2407, 0, 42199, 92386, 110865, 0, 77921, 55217, 123161, 125199, 70043, 0, 0, 0, 121093, 1834, 0, 0, 71315, 0, 65249, 0, 8662, 0, 0, @@ -25490,12 +25670,12 @@ static const unsigned int code_hash[] = { 1620, 0, 3601, 0, 0, 67246, 609, 11555, 0, 12496, 0, 74181, 120492, 12505, 0, 194902, 0, 43567, 239, 0, 127085, 0, 0, 42671, 0, 0, 83095, 43565, 127082, 983955, 12696, 127753, 0, 94062, 12929, 0, 712, 0, 4197, - 0, 42818, 0, 70306, 0, 0, 983824, 0, 43562, 0, 129034, 68076, 0, 111074, + 0, 42818, 0, 70306, 0, 0, 983824, 0, 43562, 0, 119506, 68076, 0, 111074, 64628, 0, 0, 0, 0, 7494, 0, 4924, 0, 0, 0, 0, 72368, 0, 127087, 69987, - 64796, 0, 0, 12033, 0, 0, 72370, 0, 0, 0, 0, 70299, 0, 0, 68324, 72420, - 0, 0, 0, 0, 70309, 127000, 0, 0, 0, 72418, 72963, 0, 5699, 0, 983898, - 9488, 74410, 119112, 70477, 11170, 0, 0, 72312, 0, 5265, 0, 0, 0, 0, - 12464, 0, 43264, 72977, 0, 43345, 120853, 0, 120592, 6807, 0, 9829, + 64796, 0, 0, 12033, 119492, 0, 72370, 0, 0, 0, 0, 70299, 0, 0, 68324, + 72420, 0, 0, 0, 0, 70309, 127000, 0, 0, 0, 72418, 72963, 0, 5699, 0, + 983898, 9488, 74410, 119112, 70477, 11170, 0, 0, 72312, 0, 5265, 0, 0, 0, + 0, 12464, 0, 43264, 72977, 0, 43345, 120853, 0, 120592, 6807, 0, 9829, 69997, 0, 0, 43346, 11393, 795, 0, 72412, 12462, 72416, 72415, 0, 0, 64362, 0, 0, 120811, 0, 12468, 8607, 1008, 0, 120670, 0, 0, 67855, 125018, 72372, 6758, 0, 0, 1820, 41112, 0, 11202, 129451, 0, 13223, 0, @@ -25519,13 +25699,13 @@ static const unsigned int code_hash[] = { 0, 9282, 0, 224, 0, 68670, 9332, 65581, 68677, 0, 68644, 0, 11764, 68634, 0, 10732, 68640, 850, 0, 0, 71123, 0, 68619, 44008, 68627, 0, 0, 0, 0, 66969, 0, 0, 0, 12507, 0, 0, 128311, 0, 120529, 4375, 0, 0, 0, 12198, 0, - 67339, 0, 0, 72994, 74293, 128434, 0, 0, 64546, 0, 71208, 0, 0, 125241, + 67339, 0, 0, 72994, 74293, 128434, 0, 0, 64546, 0, 71208, 0, 0, 78916, 42334, 42502, 0, 120887, 72961, 0, 917838, 5767, 0, 0, 71710, 8353, 0, 0, 0, 121233, 0, 0, 0, 0, 119920, 0, 0, 121186, 0, 0, 0, 72719, 64604, 0, 6096, 122632, 10063, 0, 0, 119630, 3485, 12987, 0, 127522, 0, 0, 0, 0, 0, 0, 0, 0, 127173, 0, 0, 68249, 0, 0, 118923, 0, 64574, 128794, 0, 1640, 12495, 66691, 0, 3138, 12504, 11171, 1922, 0, 12498, 128733, 0, 69939, 0, - 65543, 0, 0, 0, 66643, 0, 120734, 0, 4228, 0, 10303, 0, 0, 0, 10335, + 65543, 0, 0, 0, 66643, 0, 120734, 0, 4228, 0, 10303, 128884, 0, 0, 10335, 3520, 0, 12490, 0, 0, 0, 12493, 121452, 64636, 1002, 12491, 0, 0, 92615, 2096, 0, 0, 0, 0, 11611, 66228, 0, 11241, 66224, 66221, 66226, 66229, 66219, 66231, 66216, 0, 66236, 66211, 66218, 0, 66240, 78041, 66233, @@ -25551,7 +25731,7 @@ static const unsigned int code_hash[] = { 77995, 0, 3608, 0, 0, 1107, 0, 129658, 0, 0, 0, 0, 983956, 43217, 66571, 13222, 118963, 0, 126514, 10463, 11553, 0, 63995, 9043, 128634, 71722, 0, 0, 127751, 92974, 12529, 8042, 0, 2344, 12528, 0, 0, 0, 69719, 120956, 0, - 0, 66512, 0, 12530, 0, 0, 68917, 12658, 0, 71683, 0, 983238, 0, 127526, + 0, 66512, 0, 12530, 0, 0, 68917, 12658, 0, 71683, 0, 983241, 0, 127526, 469, 0, 4363, 3313, 0, 0, 2023, 0, 72251, 78225, 65706, 10051, 78219, 78220, 0, 9920, 12215, 0, 4931, 1951, 12497, 119363, 0, 0, 119336, 0, 0, 0, 0, 0, 1491, 128578, 129169, 0, 0, 0, 0, 78898, 94086, 41993, 0, 67379, @@ -25574,7 +25754,7 @@ static const unsigned int code_hash[] = { 4156, 0, 0, 0, 78591, 1611, 73058, 13018, 78586, 78588, 78584, 3337, 4537, 78593, 11736, 0, 0, 0, 4214, 73790, 0, 0, 13046, 194844, 425, 74763, 42066, 78595, 0, 2392, 13047, 0, 0, 12425, 13049, 0, 92243, 0, - 72715, 73944, 13050, 0, 0, 0, 0, 983503, 0, 0, 8929, 6849, 0, 0, 0, + 72715, 73944, 13050, 0, 0, 0, 0, 983506, 0, 0, 8929, 6849, 0, 0, 0, 983990, 0, 13045, 0, 0, 7751, 0, 9726, 0, 3997, 0, 8768, 13044, 0, 0, 4024, 0, 0, 2419, 9757, 69736, 0, 0, 0, 129500, 0, 0, 0, 72735, 0, 0, 0, 0, 0, 11911, 124990, 0, 2346, 194691, 69931, 0, 9646, 3773, 43557, 68154, @@ -25609,7 +25789,7 @@ static const unsigned int code_hash[] = { 0, 111011, 92960, 74356, 0, 74562, 0, 72745, 0, 0, 120568, 0, 0, 0, 0, 0, 8703, 5462, 83195, 0, 10101, 0, 70049, 0, 0, 128793, 0, 0, 66254, 120821, 0, 1565, 123621, 0, 119194, 0, 42651, 0, 0, 917847, 83227, 83218, 0, - 75011, 0, 917846, 0, 64399, 0, 12899, 74564, 0, 42206, 0, 72718, 71715, + 75011, 0, 129724, 0, 64399, 0, 12899, 74564, 0, 42206, 0, 72718, 71715, 83149, 983794, 83146, 12192, 917826, 0, 0, 0, 0, 68056, 0, 67426, 128687, 0, 0, 0, 0, 0, 0, 67431, 71718, 74357, 0, 121176, 43596, 6090, 0, 7812, 10534, 0, 0, 0, 0, 129763, 0, 0, 0, 0, 0, 0, 43306, 0, 0, 0, 7930, 0, @@ -25620,76 +25800,76 @@ static const unsigned int code_hash[] = { 310, 0, 0, 68403, 100480, 72738, 125279, 0, 0, 6497, 127320, 0, 0, 19958, 0, 128691, 74953, 0, 118998, 67332, 374, 0, 41933, 120975, 0, 0, 41934, 7465, 0, 128168, 70666, 11151, 6101, 0, 41936, 100476, 4879, 0, 65446, 0, - 0, 0, 0, 5374, 0, 128059, 127390, 0, 126618, 983575, 129146, 0, 0, 1929, - 0, 12142, 0, 0, 0, 121472, 0, 12982, 0, 5378, 0, 128679, 0, 0, 127869, 0, - 127343, 0, 0, 0, 78832, 74481, 0, 43262, 100511, 2421, 0, 2324, 828, - 3611, 121055, 0, 64314, 0, 0, 0, 0, 0, 0, 7999, 0, 11217, 983263, 10634, - 10942, 0, 2348, 0, 0, 0, 0, 118587, 9982, 64324, 41240, 0, 100470, 78462, - 1810, 0, 92566, 71299, 0, 0, 917848, 0, 0, 100515, 0, 0, 0, 43912, - 128385, 0, 0, 0, 917850, 0, 7485, 0, 129382, 74576, 44019, 128171, - 917851, 3967, 129335, 0, 0, 0, 0, 119096, 0, 0, 8699, 723, 83084, 966, 0, - 0, 0, 128428, 78778, 2320, 0, 65740, 4968, 0, 0, 8075, 55276, 123589, - 8047, 983787, 78827, 12634, 0, 78781, 71322, 0, 12174, 42610, 0, 0, 0, - 1584, 0, 6045, 0, 0, 65218, 11559, 0, 0, 0, 124991, 0, 2257, 64418, 0, 0, - 0, 0, 0, 0, 67821, 0, 13092, 0, 128365, 0, 0, 0, 0, 0, 11414, 0, 2531, - 13034, 0, 0, 0, 13036, 0, 70866, 70198, 10394, 129979, 13037, 0, 129956, - 0, 0, 100496, 120640, 41129, 0, 42850, 13035, 0, 0, 5466, 0, 0, 0, - 129439, 4535, 0, 4271, 0, 0, 6769, 0, 0, 67350, 6767, 0, 66273, 0, 6755, - 73827, 9046, 67355, 0, 0, 0, 0, 0, 0, 0, 0, 92221, 83235, 2563, 13033, - 247, 83229, 0, 12338, 0, 83231, 11270, 0, 0, 0, 0, 70107, 0, 0, 0, 0, - 3752, 83243, 68895, 66973, 68897, 0, 0, 0, 0, 5009, 0, 0, 0, 0, 119521, - 78823, 78824, 70353, 68399, 3877, 0, 78825, 10145, 43566, 0, 0, 10236, 0, - 43782, 0, 127329, 0, 69652, 2247, 120612, 128058, 0, 43200, 43777, 71253, - 983644, 69558, 0, 71866, 43203, 0, 68894, 0, 127326, 0, 43778, 119538, 0, - 0, 43781, 11303, 65547, 0, 7031, 0, 0, 67343, 83237, 83267, 0, 67341, - 120522, 8535, 0, 0, 0, 66032, 0, 0, 120786, 42233, 0, 9946, 7667, 0, - 11822, 0, 43189, 120673, 100507, 2979, 1579, 0, 0, 0, 0, 0, 12635, 71337, - 0, 94055, 0, 1285, 64882, 0, 0, 83113, 12640, 83112, 7401, 92869, 12625, - 0, 71296, 72744, 0, 74286, 55260, 3396, 12642, 0, 110719, 0, 12630, 0, 0, - 10153, 0, 6166, 120516, 0, 110680, 0, 0, 0, 9285, 913, 42259, 83017, 0, - 2142, 127889, 0, 94012, 7878, 0, 72733, 0, 0, 0, 0, 92868, 0, 0, 0, 0, - 128918, 5263, 74782, 0, 41939, 43702, 0, 917856, 0, 10139, 980, 43698, 0, - 2208, 0, 43701, 0, 125132, 0, 100528, 0, 10085, 0, 0, 119989, 100529, 0, - 71699, 0, 8072, 0, 43700, 0, 7304, 7783, 66894, 12398, 0, 0, 0, 0, 0, 0, - 120565, 0, 2217, 0, 94015, 6367, 0, 66688, 0, 0, 0, 0, 0, 92199, 7808, - 1829, 0, 41937, 0, 43272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92467, 6627, 0, - 6258, 10683, 0, 0, 0, 5649, 0, 0, 0, 1643, 127898, 0, 127846, 67244, 0, - 42452, 0, 0, 0, 0, 64291, 0, 0, 0, 6576, 74773, 0, 0, 66309, 0, 9886, - 55225, 11292, 0, 72867, 55227, 0, 12632, 0, 194817, 0, 7680, 0, 92745, - 120714, 12639, 3380, 8123, 0, 12638, 42262, 4501, 0, 0, 0, 0, 125131, - 1494, 983146, 0, 0, 0, 0, 10494, 0, 65872, 0, 0, 0, 0, 0, 0, 983587, 0, - 0, 0, 0, 0, 0, 0, 71077, 0, 127335, 121128, 0, 5570, 1881, 7210, 0, 1012, - 66630, 0, 128982, 7208, 66442, 5569, 113723, 42339, 92655, 0, 0, 0, 0, - 92378, 65602, 0, 92375, 64727, 9160, 0, 0, 0, 124928, 10503, 0, 3423, - 3870, 8483, 10162, 0, 4319, 0, 0, 0, 0, 0, 983116, 0, 69562, 0, 0, 0, 0, - 0, 0, 5571, 7630, 9740, 9121, 5568, 0, 0, 42085, 0, 0, 65056, 0, 589, 0, - 0, 0, 10233, 66252, 66251, 78734, 66253, 0, 0, 42645, 0, 128424, 8583, 0, - 0, 0, 129932, 0, 0, 0, 0, 0, 12204, 92436, 120453, 0, 0, 0, 983259, 0, 0, - 70311, 0, 0, 128012, 41063, 0, 10664, 0, 983660, 0, 4551, 129090, 74759, - 0, 983267, 0, 0, 72806, 0, 0, 12517, 7806, 0, 12034, 0, 6355, 12519, - 41004, 0, 0, 93849, 0, 71707, 0, 121231, 7332, 129075, 12111, 3927, 0, - 12515, 1474, 68768, 0, 6923, 69509, 0, 127802, 0, 43990, 74639, 126229, - 121007, 0, 92706, 0, 0, 0, 0, 0, 9645, 0, 121026, 5853, 0, 10363, 120729, - 12956, 0, 0, 0, 0, 127888, 0, 0, 0, 0, 0, 10514, 65517, 0, 0, 71101, 0, - 0, 0, 43570, 2969, 43420, 129944, 0, 0, 92366, 70809, 0, 0, 0, 0, 0, - 118714, 12125, 41124, 0, 1164, 128817, 0, 120466, 0, 0, 65014, 66009, - 74451, 125075, 983128, 7469, 0, 0, 0, 69988, 120671, 83171, 41123, 11176, - 0, 0, 41126, 9991, 41128, 0, 0, 110949, 0, 0, 42877, 7994, 0, 6104, - 983612, 0, 129869, 0, 0, 0, 0, 74438, 128272, 121409, 41981, 0, 69296, - 42904, 0, 0, 74435, 126640, 0, 0, 0, 127968, 92442, 12703, 9661, 67360, - 67359, 7455, 70732, 11473, 119217, 128512, 0, 92323, 0, 0, 129632, 67358, - 0, 0, 0, 0, 174, 121131, 883, 4161, 128033, 42603, 0, 0, 72256, 0, 0, - 128356, 0, 0, 0, 0, 3846, 8070, 6150, 128109, 4370, 118617, 0, 0, 74587, - 0, 0, 0, 0, 4986, 12189, 917553, 67648, 120499, 0, 4257, 71695, 123620, - 6220, 0, 65561, 0, 0, 0, 0, 122652, 0, 0, 0, 69684, 0, 0, 128452, 120873, - 0, 0, 74922, 0, 71897, 0, 0, 67368, 67367, 8871, 67366, 0, 0, 0, 0, 0, - 67361, 0, 0, 67365, 67364, 3427, 4240, 67376, 67375, 67374, 67373, 0, 0, - 0, 67377, 0, 71689, 0, 0, 67372, 67371, 67370, 67369, 0, 0, 0, 124962, 0, - 0, 0, 0, 65898, 0, 65312, 0, 0, 0, 0, 4010, 121208, 41106, 0, 0, 0, - 41105, 0, 64803, 83456, 0, 0, 0, 0, 0, 0, 0, 11008, 0, 0, 71351, 41110, - 71681, 64892, 9113, 1954, 41108, 0, 42878, 0, 67405, 0, 0, 0, 0, 0, - 119539, 69435, 73463, 0, 4586, 129342, 0, 0, 0, 0, 0, 125233, 92307, 0, - 0, 0, 67382, 0, 9500, 0, 4957, 0, 2422, 2212, 0, 67381, 67380, 11045, + 0, 983695, 0, 5374, 0, 128059, 127390, 0, 126618, 983575, 129146, 0, 0, + 1929, 0, 12142, 0, 0, 0, 121472, 0, 12982, 0, 5378, 0, 128679, 0, 0, + 127869, 0, 127343, 0, 0, 0, 78832, 74481, 0, 43262, 100511, 2421, 0, + 2324, 828, 3611, 121055, 0, 64314, 0, 0, 0, 0, 0, 0, 7999, 0, 11217, + 983266, 10634, 10942, 0, 2348, 0, 0, 0, 0, 118587, 9982, 64324, 41240, 0, + 100470, 78462, 1810, 0, 92566, 71299, 0, 0, 917848, 0, 0, 100515, 0, 0, + 0, 43912, 128385, 0, 0, 0, 917850, 0, 7485, 0, 129382, 74576, 44019, + 128171, 917851, 3967, 129335, 0, 0, 0, 0, 119096, 0, 0, 8699, 723, 83084, + 966, 0, 0, 0, 128428, 78778, 2320, 0, 65740, 4968, 0, 0, 8075, 55276, + 123589, 8047, 983787, 78827, 12634, 0, 78781, 71322, 0, 12174, 42610, 0, + 0, 0, 1584, 0, 6045, 0, 0, 65218, 11559, 0, 0, 0, 124991, 0, 2257, 64418, + 0, 0, 0, 0, 0, 0, 67821, 0, 13092, 0, 128365, 0, 0, 0, 0, 0, 11414, 0, + 2531, 13034, 0, 0, 0, 13036, 0, 70866, 70198, 10394, 129979, 13037, 0, + 129956, 0, 0, 100496, 120640, 41129, 0, 42850, 13035, 0, 0, 5466, 0, 0, + 0, 129439, 4535, 0, 4271, 0, 0, 6769, 0, 0, 67350, 6767, 0, 66273, 0, + 6755, 73827, 9046, 67355, 0, 0, 0, 0, 0, 0, 0, 0, 92221, 83235, 2563, + 13033, 247, 83229, 0, 12338, 0, 83231, 11270, 0, 0, 0, 0, 70107, 0, 0, 0, + 0, 3752, 83243, 68895, 66973, 68897, 0, 0, 0, 0, 5009, 0, 0, 0, 0, + 119521, 78823, 78824, 70353, 68399, 3877, 0, 78825, 10145, 43566, 0, 0, + 10236, 0, 43782, 0, 127329, 0, 69652, 2247, 120612, 128058, 0, 43200, + 43777, 71253, 983644, 69558, 0, 71866, 43203, 0, 68894, 0, 127326, 0, + 43778, 119538, 0, 0, 43781, 11303, 65547, 0, 7031, 0, 0, 67343, 83237, + 83267, 0, 67341, 120522, 8535, 0, 0, 0, 66032, 0, 0, 120786, 42233, 0, + 9946, 7667, 0, 11822, 0, 43189, 120673, 100507, 2979, 1579, 0, 0, 0, 0, + 0, 12635, 71337, 0, 94055, 0, 1285, 64882, 0, 0, 83113, 12640, 83112, + 7401, 92869, 12625, 0, 71296, 72744, 0, 74286, 55260, 3396, 12642, 0, + 110719, 0, 12630, 0, 0, 10153, 0, 6166, 120516, 0, 110680, 0, 0, 119499, + 9285, 913, 42259, 83017, 0, 2142, 127889, 0, 94012, 7878, 0, 72733, 0, 0, + 0, 0, 92868, 0, 0, 0, 0, 128918, 5263, 74782, 0, 41939, 43702, 0, 917856, + 0, 10139, 980, 43698, 0, 2208, 0, 43701, 0, 125132, 0, 100528, 0, 10085, + 0, 0, 119989, 100529, 0, 71699, 0, 8072, 0, 43700, 0, 7304, 7783, 66894, + 12398, 0, 0, 0, 0, 0, 0, 120565, 0, 2217, 0, 94015, 6367, 0, 66688, 0, 0, + 0, 0, 0, 92199, 7808, 1829, 0, 41937, 0, 43272, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 92467, 6627, 0, 6258, 10683, 0, 0, 0, 5649, 0, 0, 0, 1643, 127898, + 0, 127846, 67244, 0, 42452, 0, 0, 0, 0, 64291, 0, 0, 0, 6576, 74773, 0, + 0, 66309, 0, 9886, 55225, 11292, 0, 72867, 55227, 0, 12632, 0, 194817, 0, + 7680, 0, 92745, 120714, 12639, 3380, 8123, 0, 12638, 42262, 4501, 0, 0, + 0, 0, 125131, 1494, 983147, 0, 0, 0, 0, 10494, 0, 65872, 0, 0, 0, 0, 0, + 0, 983587, 0, 0, 0, 0, 0, 0, 0, 71077, 0, 127335, 121128, 0, 5570, 1881, + 7210, 0, 1012, 66630, 0, 128982, 7208, 66442, 5569, 113723, 42339, 92655, + 0, 0, 0, 0, 92378, 65602, 0, 92375, 64727, 9160, 0, 0, 0, 124928, 10503, + 0, 3423, 3870, 8483, 10162, 0, 4319, 0, 0, 0, 0, 0, 983117, 0, 69562, 0, + 0, 0, 0, 0, 0, 5571, 7630, 9740, 9121, 5568, 0, 0, 42085, 0, 0, 65056, 0, + 589, 0, 0, 0, 10233, 66252, 66251, 78734, 66253, 0, 0, 42645, 0, 128424, + 8583, 0, 0, 0, 129932, 0, 0, 0, 0, 0, 12204, 92436, 120453, 0, 0, 0, + 983262, 0, 0, 70311, 0, 0, 128012, 41063, 0, 10664, 0, 983660, 0, 4551, + 129090, 74759, 0, 983270, 0, 0, 72806, 0, 0, 12517, 7806, 0, 12034, 0, + 6355, 12519, 41004, 0, 0, 93849, 0, 71707, 0, 121231, 7332, 129075, + 12111, 3927, 0, 12515, 1474, 68768, 0, 6923, 69509, 0, 127802, 0, 43990, + 74639, 126229, 121007, 0, 92706, 0, 0, 0, 0, 0, 9645, 0, 121026, 5853, 0, + 10363, 120729, 12956, 0, 0, 0, 0, 127888, 0, 0, 0, 0, 0, 10514, 65517, 0, + 0, 71101, 0, 0, 0, 43570, 2969, 43420, 129944, 0, 0, 92366, 70809, 0, 0, + 0, 0, 0, 118714, 12125, 41124, 0, 1164, 128817, 0, 120466, 0, 0, 65014, + 66009, 74451, 125075, 983129, 7469, 0, 0, 0, 69988, 120671, 83171, 41123, + 11176, 0, 0, 41126, 9991, 41128, 0, 0, 110949, 0, 0, 42877, 7994, 0, + 6104, 983612, 0, 129869, 0, 0, 0, 0, 74438, 128272, 121409, 41981, 0, + 69296, 42904, 0, 0, 74435, 126640, 0, 0, 0, 127968, 92442, 12703, 9661, + 67360, 67359, 7455, 70732, 11473, 119217, 128512, 0, 92323, 0, 0, 129632, + 67358, 0, 0, 0, 0, 174, 121131, 883, 4161, 128033, 42603, 0, 0, 72256, 0, + 0, 128356, 0, 0, 0, 0, 3846, 8070, 6150, 128109, 4370, 118617, 0, 0, + 74587, 0, 0, 0, 0, 4986, 12189, 917553, 67648, 120499, 0, 4257, 71695, + 123620, 6220, 0, 65561, 0, 0, 0, 0, 122652, 0, 0, 0, 69684, 0, 0, 128452, + 120873, 0, 0, 74922, 0, 71897, 0, 0, 67368, 67367, 8871, 67366, 0, 0, 0, + 0, 0, 67361, 0, 0, 67365, 67364, 3427, 4240, 67376, 67375, 67374, 67373, + 0, 0, 0, 67377, 0, 71689, 0, 0, 67372, 67371, 67370, 67369, 0, 0, 0, + 124962, 0, 0, 0, 0, 65898, 0, 65312, 0, 0, 0, 0, 4010, 121208, 41106, 0, + 0, 0, 41105, 0, 64803, 83456, 0, 0, 0, 0, 0, 0, 0, 11008, 0, 0, 71351, + 41110, 71681, 64892, 9113, 1954, 41108, 0, 42878, 0, 67405, 0, 0, 0, 0, + 0, 119539, 69435, 73463, 0, 4586, 129342, 0, 0, 0, 0, 0, 125233, 92307, + 0, 0, 0, 67382, 0, 9500, 0, 4957, 0, 2422, 2212, 0, 67381, 67380, 11045, 67378, 0, 0, 3890, 12168, 121328, 0, 0, 0, 41947, 0, 120828, 74946, 917901, 0, 1571, 66461, 41949, 42805, 8270, 943, 41946, 0, 2073, 0, 41980, 0, 0, 0, 0, 4429, 6272, 0, 1460, 6954, 128572, 41120, 0, 65733, 0, @@ -25697,286 +25877,287 @@ static const unsigned int code_hash[] = { 0, 0, 0, 0, 0, 41122, 0, 2457, 0, 0, 0, 0, 0, 0, 8840, 8035, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8681, 0, 121505, 128747, 0, 0, 70102, 0, 124976, 9605, 0, 13220, 0, 67354, 11312, 0, 9246, 67349, 0, 0, 0, 0, 10012, 12123, 0, - 0, 0, 0, 983846, 0, 0, 0, 67817, 0, 1272, 0, 0, 0, 983578, 0, 1467, 0, - 917806, 0, 0, 0, 70312, 0, 124955, 0, 70400, 0, 0, 72817, 0, 19935, 0, - 92162, 0, 0, 0, 128406, 5275, 0, 0, 44006, 129082, 0, 3789, 128205, 0, 0, - 0, 11474, 0, 0, 0, 129050, 0, 92194, 129503, 9537, 4496, 0, 120443, 2605, - 4500, 0, 55224, 8600, 0, 0, 41646, 11667, 69569, 0, 0, 917905, 4499, - 41649, 0, 0, 0, 69254, 0, 0, 0, 65804, 0, 70034, 41866, 0, 0, 0, 11174, - 0, 0, 0, 9559, 128773, 41940, 8299, 41945, 0, 41941, 5455, 7190, 0, 0, - 917810, 65266, 0, 41943, 10762, 0, 41931, 0, 0, 8106, 4128, 0, 0, 4494, - 0, 0, 72405, 0, 119567, 42068, 917808, 0, 11004, 12794, 65072, 5271, - 7317, 0, 0, 0, 0, 0, 0, 92281, 0, 0, 0, 0, 71880, 3868, 71881, 983573, - 128431, 7703, 0, 64390, 0, 7406, 120358, 93850, 0, 3985, 66425, 0, 66615, - 10177, 0, 41853, 71873, 12809, 0, 12193, 0, 10879, 0, 0, 9055, 0, 3851, - 8132, 0, 0, 119263, 917908, 0, 0, 0, 0, 0, 42657, 0, 7643, 0, 0, 0, - 43568, 0, 11949, 7650, 43569, 64951, 7647, 7649, 0, 7646, 0, 0, 9651, - 125005, 3891, 0, 0, 2337, 77831, 77832, 67860, 129288, 0, 0, 43561, - 67706, 119669, 0, 1860, 0, 68835, 5812, 12784, 0, 0, 0, 0, 69260, 7727, - 0, 69292, 69818, 66444, 128665, 42719, 0, 1569, 0, 12534, 12124, 7690, - 194871, 12533, 0, 68383, 67997, 0, 6969, 0, 0, 0, 67974, 63895, 128650, - 0, 0, 0, 42144, 0, 0, 0, 0, 92211, 119043, 0, 0, 917545, 0, 0, 12791, 0, - 0, 0, 4447, 71065, 12793, 0, 0, 43385, 0, 0, 12790, 120256, 0, 983840, - 12792, 120254, 0, 0, 12789, 128489, 12317, 74934, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 127840, 41652, 2974, 78689, 11476, 0, 0, 0, 0, 43871, 0, 10894, - 119176, 74557, 65686, 0, 0, 3724, 67335, 67334, 67333, 67338, 67337, 0, - 67336, 0, 65306, 0, 128421, 0, 8646, 129593, 77829, 0, 0, 74852, 0, 0, 0, - 0, 0, 220, 120252, 43551, 0, 10044, 0, 0, 983847, 68659, 110825, 5707, - 71362, 0, 0, 0, 0, 0, 0, 10297, 0, 41308, 67331, 0, 0, 0, 0, 2467, 0, - 6003, 0, 0, 8040, 0, 0, 4182, 0, 11135, 120501, 0, 0, 2510, 0, 10208, 0, - 78302, 70829, 0, 0, 6837, 0, 0, 67348, 0, 0, 0, 0, 1559, 67342, 11104, - 67340, 67347, 67346, 67345, 67344, 0, 0, 67357, 67356, 0, 0, 0, 0, 67352, - 67351, 5516, 2845, 7717, 8036, 65161, 67353, 5514, 12045, 6278, 0, 5515, - 0, 0, 0, 0, 0, 65194, 100387, 5517, 70116, 92774, 0, 67884, 0, 67890, - 42094, 67880, 67881, 67882, 67883, 0, 0, 67879, 120411, 1902, 67887, - 67888, 12976, 126546, 12483, 12368, 41769, 42726, 41765, 69557, 12787, - 67874, 7556, 67878, 74351, 67897, 989, 42677, 67889, 0, 6060, 0, 4326, - 11000, 64601, 68478, 0, 0, 6917, 0, 120837, 0, 0, 0, 6148, 8605, 74205, - 0, 0, 0, 42715, 0, 101047, 0, 68663, 0, 41796, 1269, 42703, 64754, - 101049, 101042, 5144, 12221, 42716, 71048, 5133, 4331, 0, 128675, 0, - 5279, 121362, 71046, 0, 0, 42701, 0, 0, 0, 121470, 0, 0, 0, 983308, 0, - 983608, 121259, 42666, 12207, 1067, 255, 12131, 0, 0, 0, 0, 0, 0, 0, - 70728, 43460, 0, 42723, 125216, 0, 70427, 0, 12797, 0, 0, 983722, 0, - 67977, 12799, 0, 92504, 9746, 5135, 0, 12796, 0, 0, 0, 5139, 346, 74303, - 121134, 12795, 125109, 5168, 0, 43845, 983727, 0, 8253, 8817, 1136, - 983735, 43563, 127774, 129542, 0, 0, 0, 0, 0, 0, 983619, 0, 0, 4041, 0, - 2357, 43240, 12786, 0, 0, 0, 44004, 7142, 0, 67984, 0, 0, 0, 0, 12785, 0, - 0, 7770, 10712, 64853, 42679, 118916, 42375, 0, 983123, 94074, 12119, 0, - 11059, 10791, 111092, 450, 0, 0, 0, 0, 5450, 64691, 0, 0, 44009, 0, 0, - 111097, 94085, 1839, 94004, 0, 10927, 1701, 0, 129610, 41749, 41761, - 5453, 8361, 66045, 41758, 5444, 41763, 0, 0, 0, 66349, 983137, 121274, 0, - 0, 8801, 0, 4340, 0, 0, 0, 0, 70001, 41824, 0, 0, 0, 0, 42700, 0, 127980, - 0, 0, 0, 0, 0, 0, 4493, 4336, 129171, 2314, 983061, 41808, 0, 0, 0, - 64638, 0, 65937, 4489, 71331, 0, 0, 5358, 42717, 0, 71236, 0, 0, 0, - 127042, 41813, 2712, 0, 127044, 1410, 0, 0, 0, 0, 0, 0, 0, 0, 128587, 0, - 0, 0, 4892, 0, 0, 0, 0, 0, 5777, 0, 759, 0, 2079, 65248, 12788, 0, 64552, - 0, 41803, 68043, 0, 0, 0, 0, 128785, 0, 68492, 67991, 75071, 2340, 0, - 120638, 0, 983902, 0, 0, 917865, 64749, 0, 2321, 3587, 0, 67236, 9953, - 9952, 0, 0, 42714, 9951, 0, 0, 127902, 74150, 0, 0, 74757, 127554, 0, - 983826, 2395, 0, 9976, 0, 125128, 0, 0, 0, 42809, 42807, 0, 66290, 70854, - 4150, 64424, 8318, 41790, 67976, 65559, 2360, 41794, 0, 0, 120987, 0, 0, - 2418, 0, 2411, 0, 41783, 0, 41786, 65108, 0, 0, 41772, 42813, 2317, 0, - 118980, 0, 0, 0, 0, 0, 0, 78682, 7753, 2351, 6655, 64489, 0, 0, 0, 4443, - 41697, 230, 65793, 0, 65943, 42803, 0, 0, 5441, 0, 0, 127053, 0, 855, 0, - 6109, 101021, 0, 119116, 69989, 0, 0, 72146, 0, 101023, 0, 72148, 124918, - 19915, 41892, 0, 0, 128901, 41887, 0, 67980, 9735, 0, 0, 120591, 13082, - 101026, 0, 0, 0, 0, 0, 0, 0, 289, 0, 0, 64504, 0, 69489, 120514, 0, - 92962, 0, 42724, 69977, 0, 0, 0, 0, 67994, 0, 0, 0, 3565, 0, 0, 127553, - 43035, 69898, 0, 0, 0, 0, 4891, 0, 0, 4602, 0, 121065, 0, 0, 121157, 0, - 43978, 8988, 0, 0, 0, 0, 0, 119184, 121436, 73902, 69740, 0, 0, 72976, 0, - 0, 8771, 0, 0, 0, 119209, 74974, 71737, 0, 0, 67987, 0, 0, 0, 67989, 0, - 10065, 8207, 0, 983588, 0, 0, 662, 0, 41927, 0, 0, 0, 0, 0, 0, 0, 41929, - 0, 0, 0, 41926, 69994, 0, 0, 0, 126230, 68013, 1433, 64648, 6475, 0, - 120983, 0, 73876, 0, 0, 0, 67992, 78052, 0, 3978, 0, 0, 0, 0, 120761, - 12281, 0, 0, 13241, 0, 0, 0, 0, 11765, 42577, 0, 0, 2641, 7192, 0, 0, - 118809, 101015, 0, 101016, 128948, 101013, 6479, 64294, 118683, 0, 0, 0, - 64334, 0, 0, 0, 92266, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9478, 127339, - 124964, 0, 202, 0, 0, 1242, 0, 121170, 0, 63940, 0, 0, 0, 63939, 11990, - 92430, 67982, 0, 65440, 70068, 0, 0, 64829, 0, 0, 0, 0, 0, 2858, 0, - 63989, 0, 69239, 0, 121152, 0, 77841, 0, 70078, 92574, 129519, 0, 0, 0, - 128974, 0, 12922, 92498, 0, 66424, 71124, 0, 0, 0, 2856, 0, 47, 0, - 126986, 65858, 0, 0, 0, 0, 119161, 8417, 65903, 0, 0, 0, 4033, 128164, 0, - 0, 0, 129961, 64600, 1903, 12320, 0, 120894, 0, 0, 8915, 0, 945, 0, 0, 0, - 0, 111068, 0, 74828, 0, 69560, 9531, 0, 8505, 0, 119238, 0, 0, 65538, 0, - 0, 0, 0, 0, 0, 63935, 0, 0, 0, 0, 0, 64787, 111060, 0, 0, 110828, 0, - 2230, 0, 0, 71886, 9843, 0, 92419, 111062, 67488, 92715, 0, 1320, 0, - 1673, 0, 92383, 129902, 9338, 128355, 0, 0, 0, 0, 11997, 0, 0, 0, 0, 0, - 0, 43308, 0, 0, 0, 0, 0, 0, 0, 63920, 0, 0, 0, 0, 0, 0, 3514, 78723, 0, - 7492, 0, 0, 0, 7514, 0, 63924, 0, 7502, 7587, 0, 0, 0, 118689, 43881, - 7610, 0, 0, 118710, 692, 43588, 0, 0, 75056, 9688, 0, 9535, 0, 0, 0, - 64530, 0, 125251, 194861, 0, 72209, 7453, 0, 8013, 66396, 0, 0, 8895, - 5356, 0, 5458, 0, 2866, 0, 127860, 71732, 71724, 6700, 0, 111081, 120583, - 0, 110614, 0, 9641, 63830, 65294, 0, 0, 67969, 0, 7441, 0, 63826, 0, 0, - 0, 0, 2844, 983972, 0, 63824, 12139, 67971, 0, 0, 3358, 65295, 0, 3104, - 0, 0, 0, 0, 65772, 0, 0, 0, 0, 2862, 11326, 0, 0, 94001, 3268, 66591, 0, - 6552, 42367, 7035, 120558, 0, 0, 1814, 195092, 10240, 195093, 0, 0, 0, 0, - 0, 66960, 0, 0, 2837, 4341, 0, 0, 129982, 125064, 195094, 0, 0, 66964, 0, - 72721, 863, 66936, 0, 0, 43323, 66928, 0, 0, 68054, 0, 3654, 66951, 0, - 66942, 0, 0, 7653, 0, 0, 66587, 0, 0, 92401, 0, 0, 12927, 0, 0, 129697, - 13056, 0, 0, 3056, 0, 0, 195101, 0, 0, 74506, 73770, 0, 0, 0, 0, 0, 0, 0, - 0, 72233, 0, 5811, 0, 0, 0, 66817, 983855, 0, 0, 128636, 129311, 0, - 128041, 0, 67739, 120965, 0, 0, 67507, 0, 68375, 0, 0, 70300, 0, 0, 0, - 983698, 111078, 0, 11991, 128079, 0, 92943, 1502, 74117, 127988, 0, - 129478, 121253, 0, 67661, 0, 0, 125084, 68667, 0, 74057, 68639, 0, 42898, - 120742, 0, 74388, 74838, 120822, 0, 0, 0, 0, 69452, 43214, 5893, 0, 0, - 92496, 0, 0, 119907, 119900, 0, 0, 0, 0, 41950, 0, 0, 68610, 0, 68626, - 894, 0, 0, 12306, 73846, 0, 0, 0, 8636, 0, 121028, 42503, 0, 92942, 0, - 121468, 119241, 0, 126569, 5096, 5095, 2863, 127505, 0, 10454, 42530, - 5094, 0, 0, 13156, 0, 111035, 5093, 127178, 983416, 0, 5092, 10708, - 11327, 0, 5091, 0, 0, 9153, 4104, 78599, 78601, 2929, 42712, 75067, - 12272, 9832, 0, 0, 111105, 0, 0, 0, 0, 0, 0, 13106, 0, 0, 129111, 0, 0, - 0, 0, 9074, 111111, 0, 111110, 0, 8113, 11168, 92563, 1786, 111109, 0, - 111108, 0, 74423, 0, 586, 74414, 64359, 1267, 0, 127531, 0, 65731, 0, 0, - 0, 92932, 0, 0, 0, 0, 0, 0, 1228, 0, 42846, 0, 0, 70343, 1714, 74406, 0, - 0, 0, 127389, 66225, 0, 0, 42660, 0, 0, 3804, 0, 0, 129859, 0, 2826, 0, - 0, 0, 128396, 0, 0, 0, 0, 0, 0, 12206, 5839, 0, 68524, 74065, 0, 0, 0, - 126240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67241, 917821, 7030, 0, 10479, - 64959, 2852, 0, 121225, 0, 0, 128586, 0, 6963, 0, 0, 0, 74786, 0, 0, 0, - 0, 121281, 0, 0, 0, 0, 113815, 121360, 0, 9994, 118680, 2864, 64719, - 1148, 0, 41677, 0, 0, 2765, 0, 128181, 0, 0, 0, 92516, 74777, 0, 0, - 65206, 0, 0, 0, 0, 69391, 0, 0, 983770, 0, 41839, 129616, 983773, 0, 0, - 6931, 0, 0, 7177, 125137, 0, 0, 0, 93020, 0, 10722, 0, 0, 128186, 121050, - 0, 0, 127207, 0, 750, 0, 129453, 63912, 0, 0, 7032, 0, 0, 4314, 128600, - 0, 128409, 730, 0, 127866, 0, 0, 41380, 0, 0, 0, 69697, 8240, 92939, 0, - 41378, 0, 6938, 70026, 0, 0, 66246, 0, 0, 0, 0, 0, 0, 983094, 0, 92754, - 41470, 64805, 0, 0, 0, 0, 0, 0, 0, 0, 92938, 68370, 0, 0, 73831, 0, 0, 0, - 2872, 0, 0, 0, 0, 604, 41097, 0, 0, 0, 0, 0, 127488, 0, 2836, 0, 0, 9707, - 0, 43202, 0, 0, 0, 0, 0, 120916, 2832, 92702, 9670, 12937, 0, 0, 0, 0, - 2822, 0, 0, 92519, 0, 73752, 0, 0, 0, 1331, 92603, 0, 11856, 0, 129432, - 5090, 5089, 0, 3200, 0, 0, 0, 5088, 0, 0, 9477, 0, 0, 5087, 92325, 0, 96, - 5086, 0, 0, 0, 5085, 64286, 0, 0, 43820, 0, 983741, 0, 0, 119042, 0, - 129660, 0, 0, 0, 0, 0, 127241, 120891, 7601, 0, 591, 0, 118953, 0, 0, 0, - 0, 0, 10939, 7246, 6933, 67142, 67141, 0, 74600, 120695, 0, 67138, 65574, - 0, 78058, 67140, 73851, 74598, 67139, 128094, 0, 6372, 0, 0, 7963, 6371, - 0, 0, 125040, 0, 0, 0, 0, 0, 0, 0, 8258, 123591, 0, 0, 65148, 118919, 42, - 0, 0, 0, 0, 0, 0, 0, 0, 67135, 67134, 67133, 0, 0, 0, 0, 67136, 67130, - 74597, 11550, 0, 67132, 65868, 0, 12826, 127872, 0, 126235, 9737, 92448, - 0, 0, 0, 8878, 0, 0, 0, 0, 0, 72220, 9086, 0, 0, 0, 7437, 7454, 0, 0, 0, - 0, 9042, 0, 0, 0, 0, 3805, 0, 67128, 44001, 67126, 0, 44022, 19949, - 12200, 43522, 983045, 43525, 0, 0, 0, 64422, 67125, 67124, 7602, 0, 0, - 43521, 0, 0, 43711, 43523, 41447, 8424, 68483, 8704, 2397, 0, 0, 0, 0, 0, - 10916, 0, 129290, 93998, 0, 0, 0, 127800, 67686, 9961, 123203, 0, 68842, - 10792, 8889, 121402, 6951, 0, 68827, 917835, 74342, 0, 0, 0, 68816, - 129152, 0, 42909, 66597, 70092, 0, 0, 10481, 4559, 0, 1956, 43138, 0, 0, - 43490, 43148, 0, 0, 0, 43140, 0, 0, 0, 0, 69268, 8533, 0, 0, 0, 0, 0, - 4357, 0, 70289, 983156, 0, 42911, 0, 0, 0, 10941, 0, 6962, 0, 0, 113808, - 0, 11014, 0, 8942, 12000, 0, 0, 0, 0, 0, 0, 42650, 0, 75016, 63975, 0, - 66210, 0, 0, 129150, 0, 11193, 0, 0, 0, 0, 0, 0, 0, 43476, 0, 11024, - 74811, 72787, 10563, 92954, 0, 0, 2462, 92955, 0, 0, 66213, 6957, 0, - 120559, 0, 0, 0, 74594, 983421, 92347, 0, 110702, 110708, 110707, 127119, - 3109, 127117, 119909, 0, 121434, 0, 0, 4042, 0, 0, 0, 127123, 127122, - 127121, 0, 127999, 0, 3503, 74444, 68300, 6694, 127997, 0, 0, 74306, 0, - 983757, 7736, 0, 0, 0, 10521, 0, 42173, 9705, 0, 129719, 6955, 71467, 0, - 6149, 3887, 19956, 1411, 2824, 0, 0, 0, 1403, 0, 1347, 66282, 127996, 0, - 0, 0, 0, 8640, 0, 1178, 1654, 0, 0, 129529, 43314, 0, 0, 0, 0, 2873, - 67461, 0, 0, 67085, 10861, 0, 0, 70377, 0, 67082, 11159, 41391, 67084, 0, - 376, 6987, 983181, 119904, 0, 8823, 0, 12943, 65185, 100988, 42099, 0, 0, - 100990, 0, 8301, 0, 0, 1684, 0, 0, 0, 120620, 0, 0, 0, 42121, 0, 66781, - 78067, 42115, 0, 127998, 0, 67080, 1493, 42111, 67077, 4097, 0, 983767, - 0, 65808, 41642, 0, 118568, 67076, 41636, 67074, 65095, 110660, 72254, - 121240, 41629, 12154, 75073, 0, 128179, 74084, 64380, 0, 0, 0, 0, 0, - 71193, 65371, 7078, 121218, 0, 0, 74592, 0, 0, 43275, 0, 41434, 6062, 0, - 0, 19916, 0, 6950, 9606, 9842, 0, 65744, 0, 0, 128659, 0, 41615, 10105, - 0, 0, 41632, 7493, 0, 0, 41622, 0, 0, 0, 0, 7632, 983215, 983214, 9805, - 5990, 900, 0, 983388, 0, 120869, 3612, 0, 64376, 0, 5389, 129469, 0, 0, - 2839, 9621, 582, 0, 0, 3749, 0, 7569, 0, 0, 92865, 6956, 4403, 0, 0, - 3299, 0, 0, 119127, 65676, 0, 74372, 0, 983494, 7598, 69819, 42469, - 42242, 1918, 9542, 480, 7716, 0, 0, 0, 0, 0, 69918, 0, 8328, 0, 118894, - 0, 0, 0, 0, 11132, 0, 66743, 74185, 100531, 2854, 66747, 0, 65755, 0, - 67120, 67119, 65835, 67117, 66736, 67123, 67122, 67121, 9881, 100481, - 65757, 100538, 100459, 67116, 8648, 128377, 6741, 43047, 0, 13180, 0, - 100487, 66754, 0, 128946, 0, 0, 41752, 0, 8641, 100490, 125185, 100489, - 100462, 100541, 6942, 69501, 1024, 42849, 41751, 0, 8941, 101034, 11121, - 0, 9023, 40973, 121476, 9928, 67109, 66865, 0, 67114, 67113, 67112, - 67111, 0, 41206, 120724, 9049, 67108, 43166, 0, 41200, 128201, 125142, - 126537, 0, 0, 41188, 119553, 0, 101007, 917548, 74585, 78626, 0, 0, - 11466, 0, 120797, 0, 125067, 2261, 0, 2860, 0, 0, 70828, 127925, 92357, - 67106, 12065, 42872, 0, 43875, 67103, 43856, 0, 67102, 67105, 7531, - 40981, 2413, 100522, 67404, 100521, 0, 67101, 41196, 100523, 0, 0, - 983746, 43117, 100495, 0, 0, 0, 0, 69876, 0, 7173, 496, 0, 4313, 64607, - 0, 0, 0, 2065, 42793, 2842, 0, 83152, 13132, 798, 0, 12801, 67098, 10686, - 118528, 128143, 0, 8054, 9174, 67087, 67086, 67097, 67096, 41611, 67095, - 74504, 78854, 42512, 0, 78857, 42089, 74613, 78856, 0, 101029, 100468, - 42079, 100467, 0, 66961, 100474, 0, 0, 0, 68338, 69958, 0, 0, 0, 0, 0, - 78859, 42093, 128951, 100504, 0, 0, 0, 4580, 0, 0, 0, 92167, 0, 3021, - 42004, 0, 0, 42317, 41998, 0, 6946, 77920, 0, 123610, 0, 0, 0, 121442, - 42690, 9880, 0, 0, 64589, 0, 0, 127880, 68035, 0, 11360, 0, 0, 72242, 0, - 0, 0, 0, 0, 64941, 0, 0, 0, 6856, 65671, 11244, 73706, 6959, 41994, - 42907, 0, 0, 122902, 8617, 41982, 8860, 0, 0, 121256, 0, 0, 9597, 0, - 43172, 0, 10117, 0, 92297, 65865, 0, 0, 128077, 0, 126065, 0, 187, 0, - 65669, 0, 4963, 0, 0, 0, 8964, 0, 7775, 0, 41948, 0, 0, 101010, 41942, - 65449, 3160, 65922, 13226, 42665, 0, 42663, 128210, 41766, 983500, 78848, - 78849, 41760, 1189, 905, 110620, 42658, 78851, 67859, 9629, 6742, 0, - 43625, 12952, 7888, 0, 3980, 0, 42656, 0, 42055, 0, 0, 0, 64540, 0, 7867, - 69218, 6236, 0, 0, 10505, 0, 12851, 118948, 0, 5474, 128843, 3103, 0, - 41753, 41733, 78051, 983474, 78844, 78845, 41739, 78843, 70744, 10931, - 41756, 43347, 68098, 122909, 41746, 119147, 92591, 41259, 66954, 69930, - 2691, 121338, 11231, 41244, 0, 69800, 66364, 41262, 67503, 0, 0, 41251, - 0, 0, 11805, 0, 0, 68331, 94045, 0, 0, 0, 74633, 41266, 126642, 0, 0, 0, - 65741, 41737, 2275, 2666, 121232, 41738, 4967, 419, 13126, 0, 0, 42822, - 0, 6434, 74913, 0, 0, 6432, 0, 69932, 128862, 769, 41742, 69927, 74805, - 6433, 0, 547, 1943, 6439, 0, 4994, 487, 0, 0, 3754, 0, 0, 0, 0, 74780, 0, - 0, 1595, 92777, 74431, 0, 0, 74860, 43267, 0, 0, 129083, 12185, 69406, 0, - 0, 100984, 0, 42856, 0, 0, 983765, 128319, 75057, 0, 0, 0, 65612, 0, 669, - 0, 0, 0, 0, 0, 70445, 100404, 69929, 0, 0, 460, 121513, 0, 0, 0, 120747, - 0, 121519, 121518, 0, 0, 121515, 71491, 65187, 9044, 78497, 11760, 78494, - 7577, 78491, 41912, 100412, 0, 100411, 0, 0, 100394, 78501, 0, 2933, - 78500, 0, 66441, 100392, 100397, 100391, 1549, 0, 100415, 0, 41755, 6206, - 8670, 120587, 0, 69935, 0, 0, 69768, 100952, 0, 66958, 0, 0, 10552, - 64342, 41922, 0, 917858, 0, 917857, 2717, 0, 0, 0, 73664, 41908, 100722, - 41916, 0, 0, 0, 92506, 100723, 66664, 69803, 0, 100725, 0, 0, 43373, 0, - 0, 8468, 100729, 121173, 128297, 119210, 118952, 0, 0, 0, 100686, 0, 0, - 0, 128703, 100670, 457, 78502, 78503, 123180, 43006, 0, 8802, 113777, 0, - 0, 0, 0, 126632, 0, 41757, 0, 100657, 44000, 0, 0, 43534, 0, 0, 11961, - 121316, 0, 0, 0, 128736, 0, 0, 9499, 92977, 128330, 0, 0, 92260, 68184, - 0, 0, 7256, 66993, 983179, 0, 42161, 0, 119126, 128022, 65880, 0, 10802, - 64861, 0, 0, 0, 0, 0, 0, 73109, 0, 955, 0, 0, 5350, 64339, 0, 100705, - 10875, 0, 5477, 73121, 0, 0, 0, 67693, 69790, 0, 0, 3874, 0, 0, 0, 0, - 83272, 100674, 127397, 0, 100989, 0, 41038, 67502, 9207, 42239, 0, 0, 0, - 0, 74432, 0, 0, 1455, 129680, 0, 11753, 119233, 0, 118594, 127854, - 100716, 69801, 0, 0, 43520, 0, 119556, 0, 0, 0, 0, 100733, 10788, 6088, - 0, 129587, 190, 983343, 12593, 100737, 129308, 64408, 0, 4417, 128615, - 74359, 41744, 0, 0, 100435, 6965, 0, 0, 13201, 100430, 69896, 78868, - 74382, 11841, 7918, 92721, 0, 0, 0, 1728, 0, 0, 0, 983347, 92679, 0, 0, - 92711, 0, 0, 119536, 0, 66679, 8382, 0, 0, 100381, 0, 917889, 42254, - 68371, 100383, 0, 0, 0, 9923, 0, 0, 11763, 100386, 120688, 0, 78187, 0, - 0, 0, 0, 8333, 0, 0, 0, 917805, 74464, 0, 92320, 74080, 0, 69911, 11910, - 0, 74141, 8963, 0, 0, 0, 121396, 0, 41747, 0, 0, 8968, 0, 0, 129110, - 110590, 0, 8836, 12315, 0, 8300, 0, 0, 0, 8856, 0, 0, 69891, 0, 66965, - 120405, 120402, 120403, 120400, 120401, 12853, 43269, 7263, 120244, 6536, - 120238, 120239, 65516, 12321, 120391, 120388, 55287, 2237, 120246, 9588, - 120248, 120382, 120383, 120380, 120381, 0, 0, 3561, 0, 0, 10613, 0, - 110583, 0, 0, 0, 128689, 5006, 64328, 68219, 917894, 0, 8825, 129880, 0, - 0, 0, 128616, 0, 119177, 0, 0, 128641, 120225, 71366, 120227, 120228, - 438, 4510, 41707, 8721, 120233, 120234, 120235, 12840, 120229, 10845, - 120231, 8096, 0, 120935, 0, 0, 65589, 8733, 0, 0, 0, 0, 0, 0, 93984, - 11262, 73747, 128522, 917902, 64591, 42405, 0, 0, 1632, 127982, 128326, - 0, 0, 121327, 121477, 42444, 0, 0, 215, 41258, 128494, 64494, 1953, - 10185, 0, 1256, 3910, 41260, 917903, 0, 0, 41257, 0, 8675, 10700, 0, - 124951, 0, 9333, 0, 121471, 0, 0, 0, 0, 0, 499, 0, 70729, 42915, 0, - 101000, 0, 100999, 0, 0, 73111, 0, 122897, 0, 125006, 0, 11118, 0, - 128009, 0, 0, 118633, 9180, 0, 0, 0, 100986, 43438, 118588, 0, 0, 0, 0, - 120669, 64782, 0, 0, 73969, 565, 42484, 118913, 201, 0, 42292, 69610, 0, - 0, 119625, 43518, 0, 0, 1022, 113788, 3880, 74247, 0, 0, 0, 0, 0, 0, 0, - 0, 72272, 100997, 0, 0, 66937, 74255, 0, 0, 92598, 0, 9903, 118993, 0, - 68226, 0, 0, 0, 127788, 100955, 83280, 7892, 0, 10777, 0, 0, 65562, 0, - 101002, 0, 8039, 3363, 101009, 0, 0, 66940, 12596, 70812, 0, 0, 0, 0, - 42944, 92425, 74992, 64541, 0, 0, 10520, 12802, 0, 12998, 0, 83270, - 42861, 83273, 11415, 0, 7541, 125068, 65878, 822, 0, 0, 5774, 194746, - 43252, 0, 92619, 7672, 129281, 0, 0, 7463, 0, 0, 0, 0, 0, 0, 121411, 0, - 0, 0, 66938, 0, 475, 0, 120586, 7329, 0, 0, 195088, 66291, 10645, 0, - 6543, 100966, 0, 0, 119065, 0, 0, 0, 983234, 195095, 0, 8923, 1645, 0, 0, - 0, 3196, 72404, 0, 0, 43595, 0, 0, 0, 0, 0, 195076, 0, 0, 5258, 4328, 0, - 0, 0, 405, 11454, 0, 0, 0, 0, 75052, 41245, 0, 195078, 4523, 11369, 0, 0, - 0, 195079, 0, 0, 983507, 0, 100961, 10480, 74610, 0, 0, 0, 12610, 0, - 41247, 0, 7609, 118837, 0, 0, 92253, 0, 984, 0, 92621, 0, 0, 129885, - 73982, 0, 0, 0, 43369, 0, 0, 0, 983504, 6634, 0, 71952, 0, 66930, 74214, - 0, 67709, 0, 0, 0, 71114, 9552, 0, 0, 0, 12997, 0, 0, 0, 0, 129109, - 12883, 10994, 10529, 55283, 0, 74618, 0, 67736, 10661, 19951, 9614, 2428, - 0, 121023, 92837, 126224, 66933, 71127, 0, 124996, 119162, 1952, 92181, - 8455, 100958, 0, 93033, 119566, 100960, 0, 12183, 100951, 0, 64929, 0, 0, - 0, 128290, 42509, 73087, 3922, 9187, 983626, 0, 0, 119057, 0, 3353, 9358, - 0, 0, 66680, 0, 73975, 12879, 0, 9795, 68380, 0, 0, 0, 0, 0, 41027, 0, - 66931, 0, 983631, 0, 70378, 0, 11751, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 129356, 0, 0, 0, 0, 41029, 0, 126513, 0, 0, 0, 11294, 0, 66665, 0, 0, - 127750, 0, 0, 70105, 0, 983643, 0, 67843, 0, 0, 121167, 983895, 0, 8088, - 129412, 0, 0, 0, 983992, 6926, 72423, 0, 129569, 42369, 4350, 0, 65145, - 9041, 43559, 0, 0, 0, 41263, 0, 0, 0, 65825, 9577, 68199, 0, 0, 983121, - 0, 6793, 0, 70409, 0, 0, 0, 0, 64669, 0, 0, 0, 11200, 72725, 2995, 0, 0, - 0, 7868, 72720, 72020, 11386, 1009, 70405, 66871, 2333, 0, 0, 0, 0, 0, - 70407, 128121, 0, 0, 0, 0, 983657, 66949, 0, 74968, 0, 0, 110601, 0, 0, - 41261, 0, 0, 0, 0, 118989, 6736, 917883, 0, 43010, 66952, 0, 69635, - 73011, 983716, 0, 0, 7293, 0, 0, 0, 0, 111332, 0, 128245, 69928, 0, 0, + 0, 0, 0, 983846, 0, 0, 0, 67817, 0, 1272, 0, 0, 0, 983578, 0, 1467, + 119501, 917806, 0, 0, 0, 70312, 73537, 124955, 0, 70400, 0, 0, 72817, 0, + 19935, 0, 92162, 0, 0, 0, 128406, 5275, 0, 0, 44006, 129082, 0, 3789, + 128205, 0, 0, 0, 11474, 0, 0, 0, 129050, 0, 92194, 129503, 9537, 4496, 0, + 120443, 2605, 4500, 0, 55224, 8600, 0, 0, 41646, 11667, 69569, 0, 0, + 917905, 4499, 41649, 0, 0, 0, 69254, 0, 0, 0, 65804, 0, 70034, 41866, 0, + 0, 0, 11174, 0, 0, 0, 9559, 128773, 41940, 8299, 41945, 0, 41941, 5455, + 7190, 0, 0, 917810, 65266, 0, 41943, 10762, 0, 41931, 0, 0, 8106, 4128, + 0, 0, 4494, 0, 0, 72405, 0, 119567, 42068, 917808, 0, 11004, 12794, + 65072, 5271, 7317, 0, 0, 0, 0, 0, 0, 92281, 0, 0, 0, 0, 71880, 3868, + 71881, 983573, 128431, 7703, 0, 64390, 0, 7406, 120358, 93850, 0, 3985, + 66425, 0, 66615, 10177, 0, 41853, 71873, 12809, 0, 12193, 0, 10879, + 122945, 0, 9055, 0, 3851, 8132, 0, 0, 119263, 917908, 0, 0, 0, 0, 122940, + 42657, 122952, 7643, 0, 0, 122936, 43568, 0, 11949, 7650, 43569, 64951, + 7647, 7649, 0, 7646, 0, 0, 9651, 125005, 3891, 0, 0, 2337, 77831, 77832, + 67860, 129288, 0, 0, 43561, 67706, 119669, 0, 1860, 0, 68835, 5812, + 12784, 0, 0, 0, 0, 69260, 7727, 0, 69292, 69818, 66444, 128665, 42719, 0, + 1569, 0, 12534, 12124, 7690, 194871, 12533, 0, 68383, 67997, 0, 6969, 0, + 0, 0, 67974, 63895, 128650, 0, 0, 0, 42144, 0, 0, 0, 0, 92211, 119043, 0, + 0, 917545, 0, 0, 12791, 0, 0, 0, 4447, 71065, 12793, 0, 0, 43385, 0, 0, + 12790, 120256, 0, 983840, 12792, 120254, 0, 0, 12789, 128489, 12317, + 74934, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127840, 41652, 2974, 78689, 11476, + 0, 0, 0, 0, 43871, 0, 10894, 119176, 74557, 65686, 0, 0, 3724, 67335, + 67334, 67333, 67338, 67337, 0, 67336, 0, 65306, 0, 128421, 0, 8646, + 129593, 77829, 0, 0, 74852, 0, 0, 0, 0, 0, 220, 120252, 43551, 0, 10044, + 0, 0, 983847, 68659, 110825, 5707, 71362, 0, 0, 0, 0, 0, 0, 10297, 0, + 41308, 67331, 0, 0, 0, 0, 2467, 0, 6003, 0, 0, 8040, 0, 0, 4182, 0, + 11135, 120501, 0, 0, 2510, 0, 10208, 0, 78302, 70829, 0, 0, 6837, 0, 0, + 67348, 0, 0, 0, 0, 1559, 67342, 11104, 67340, 67347, 67346, 67345, 67344, + 0, 0, 67357, 67356, 0, 0, 0, 0, 67352, 67351, 5516, 2845, 7717, 8036, + 65161, 67353, 5514, 12045, 6278, 0, 5515, 0, 0, 0, 0, 0, 65194, 100387, + 5517, 70116, 92774, 0, 67884, 0, 67890, 42094, 67880, 67881, 67882, + 67883, 0, 0, 67879, 120411, 1902, 67887, 67888, 12976, 126546, 12483, + 12368, 41769, 42726, 41765, 69557, 12787, 67874, 7556, 67878, 74351, + 67897, 989, 42677, 67889, 0, 6060, 0, 4326, 11000, 64601, 68478, 0, 0, + 6917, 0, 120837, 0, 0, 0, 6148, 8605, 74205, 0, 0, 0, 42715, 0, 101047, + 0, 68663, 0, 41796, 1269, 42703, 64754, 101049, 101042, 5144, 12221, + 42716, 71048, 5133, 4331, 0, 128675, 0, 5279, 121362, 71046, 0, 0, 42701, + 0, 0, 0, 121470, 0, 0, 0, 983311, 0, 72455, 121259, 42666, 12207, 1067, + 255, 12131, 0, 0, 0, 0, 0, 0, 0, 70728, 43460, 0, 42723, 125216, 0, + 70427, 0, 12797, 0, 0, 983722, 0, 67977, 12799, 0, 92504, 9746, 5135, 0, + 12796, 0, 0, 0, 5139, 346, 74303, 121134, 12795, 125109, 5168, 0, 43845, + 983727, 0, 8253, 8817, 1136, 983735, 43563, 127774, 129542, 0, 0, 0, 0, + 0, 0, 983619, 0, 0, 4041, 0, 2357, 43240, 12786, 0, 0, 0, 44004, 7142, 0, + 67984, 0, 0, 0, 0, 12785, 0, 0, 7770, 10712, 64853, 42679, 118916, 42375, + 0, 983124, 94074, 12119, 0, 11059, 10791, 111092, 450, 0, 0, 0, 0, 5450, + 64691, 0, 0, 44009, 0, 0, 111097, 94085, 1839, 94004, 0, 10927, 1701, 0, + 129610, 41749, 41761, 5453, 8361, 66045, 41758, 5444, 41763, 0, 0, 0, + 66349, 983138, 121274, 0, 0, 8801, 0, 4340, 0, 0, 0, 0, 70001, 41824, 0, + 0, 0, 0, 42700, 0, 127980, 0, 0, 0, 0, 0, 0, 4493, 4336, 129171, 2314, + 983061, 41808, 0, 0, 0, 64638, 0, 65937, 4489, 71331, 0, 0, 5358, 42717, + 0, 71236, 0, 0, 0, 127042, 41813, 2712, 0, 127044, 1410, 0, 0, 0, 0, 0, + 0, 0, 0, 128587, 0, 0, 0, 4892, 0, 0, 0, 0, 122966, 5777, 0, 759, 0, + 2079, 65248, 12788, 0, 64552, 0, 41803, 68043, 0, 0, 0, 0, 128785, 0, + 68492, 67991, 75071, 2340, 0, 120638, 0, 983902, 0, 0, 917865, 64749, 0, + 2321, 3587, 0, 67236, 9953, 9952, 0, 0, 42714, 9951, 0, 0, 127902, 74150, + 0, 0, 74757, 127554, 0, 983826, 2395, 0, 9976, 0, 125128, 0, 0, 0, 42809, + 42807, 0, 66290, 70854, 4150, 64424, 8318, 41790, 67976, 65559, 2360, + 41794, 0, 0, 120987, 0, 0, 2418, 0, 2411, 0, 41783, 0, 41786, 65108, 0, + 0, 41772, 42813, 2317, 0, 118980, 0, 0, 0, 0, 0, 0, 78682, 7753, 2351, + 6655, 64489, 0, 0, 0, 4443, 41697, 230, 65793, 0, 65943, 42803, 0, 0, + 5441, 0, 0, 127053, 0, 855, 0, 6109, 101021, 0, 119116, 69989, 0, 0, + 72146, 0, 101023, 0, 72148, 124918, 19915, 41892, 0, 0, 128901, 41887, 0, + 67980, 9735, 0, 0, 120591, 13082, 101026, 0, 0, 0, 0, 0, 0, 0, 289, 0, 0, + 64504, 0, 69489, 120514, 0, 92962, 0, 42724, 69977, 0, 0, 0, 0, 67994, 0, + 0, 983823, 3565, 0, 0, 127553, 43035, 69898, 0, 0, 0, 0, 4891, 0, 0, + 4602, 0, 121065, 0, 0, 121157, 0, 43978, 8988, 0, 0, 0, 0, 0, 119184, + 121436, 73902, 69740, 0, 0, 72976, 0, 0, 8771, 0, 0, 0, 119209, 74974, + 71737, 0, 0, 67987, 0, 0, 0, 67989, 0, 10065, 8207, 0, 983588, 0, 0, 662, + 0, 41927, 0, 0, 0, 0, 0, 0, 0, 41929, 0, 0, 0, 41926, 69994, 0, 0, 0, + 126230, 68013, 1433, 64648, 6475, 0, 120983, 0, 73876, 0, 0, 0, 67992, + 78052, 0, 3978, 0, 0, 0, 0, 120761, 12281, 0, 0, 13241, 0, 0, 0, 0, + 11765, 42577, 0, 0, 2641, 7192, 0, 0, 118809, 101015, 0, 101016, 128948, + 101013, 6479, 64294, 118683, 0, 0, 0, 64334, 0, 0, 0, 92266, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9478, 127339, 124964, 0, 202, 0, 0, 1242, 0, 121170, 0, + 63940, 0, 0, 0, 63939, 11990, 92430, 67982, 0, 65440, 70068, 0, 0, 64829, + 0, 0, 0, 0, 0, 2858, 0, 63989, 0, 69239, 0, 121152, 0, 77841, 0, 70078, + 92574, 129519, 0, 0, 0, 128974, 0, 12922, 92498, 0, 66424, 71124, 0, 0, + 0, 2856, 0, 47, 0, 126986, 65858, 0, 0, 0, 0, 119161, 8417, 65903, 0, 0, + 0, 4033, 128164, 0, 0, 0, 129961, 64600, 1903, 12320, 0, 120894, 0, 0, + 8915, 0, 945, 0, 0, 0, 0, 111068, 0, 74828, 0, 69560, 9531, 0, 8505, 0, + 119238, 0, 0, 65538, 0, 0, 0, 0, 0, 0, 63935, 0, 0, 0, 0, 0, 64787, + 111060, 0, 0, 110828, 0, 2230, 0, 0, 71886, 9843, 0, 92419, 111062, + 67488, 92715, 0, 1320, 0, 1673, 0, 92383, 129902, 9338, 128355, 0, 0, 0, + 0, 11997, 0, 0, 0, 0, 0, 0, 43308, 0, 0, 0, 0, 0, 0, 0, 63920, 0, 0, 0, + 0, 0, 0, 3514, 78723, 0, 7492, 0, 0, 0, 7514, 0, 63924, 0, 7502, 7587, 0, + 0, 0, 118689, 43881, 7610, 0, 0, 118710, 692, 43588, 0, 0, 75056, 9688, + 0, 9535, 0, 0, 0, 64530, 0, 125251, 194861, 0, 72209, 7453, 0, 8013, + 66396, 0, 0, 8895, 5356, 0, 5458, 0, 2866, 0, 127860, 71732, 71724, 6700, + 0, 111081, 120583, 0, 110614, 0, 9641, 63830, 65294, 0, 0, 67969, 0, + 7441, 0, 63826, 0, 0, 0, 0, 2844, 983972, 0, 63824, 12139, 67971, 0, 0, + 3358, 65295, 0, 3104, 0, 0, 0, 0, 65772, 0, 0, 0, 0, 2862, 11326, 0, 0, + 94001, 3268, 66591, 0, 6552, 42367, 7035, 120558, 0, 0, 1814, 195092, + 10240, 195093, 0, 0, 0, 0, 0, 66960, 0, 0, 2837, 4341, 0, 0, 129982, + 125064, 195094, 0, 0, 66964, 0, 72721, 863, 66936, 0, 0, 43323, 66928, 0, + 0, 68054, 0, 3654, 66951, 0, 66942, 0, 0, 7653, 0, 0, 66587, 0, 0, 92401, + 0, 0, 12927, 0, 0, 129697, 13056, 0, 0, 3056, 0, 0, 195101, 0, 0, 74506, + 73770, 0, 0, 0, 0, 0, 0, 0, 0, 72233, 0, 5811, 0, 0, 0, 66817, 983855, 0, + 0, 128636, 129311, 0, 128041, 0, 67739, 120965, 0, 0, 67507, 0, 68375, 0, + 0, 70300, 0, 0, 0, 983698, 111078, 0, 11991, 128079, 0, 92943, 1502, + 74117, 127988, 0, 129478, 121253, 0, 67661, 0, 0, 125084, 68667, 0, + 74057, 68639, 0, 42898, 120742, 0, 74388, 74838, 120822, 0, 0, 0, 0, + 69452, 43214, 5893, 0, 0, 92496, 0, 0, 119907, 119900, 0, 0, 0, 0, 41950, + 0, 0, 68610, 0, 68626, 894, 0, 0, 12306, 73846, 0, 0, 0, 8636, 0, 121028, + 42503, 0, 92942, 0, 121468, 119241, 0, 126569, 5096, 5095, 2863, 127505, + 0, 10454, 42530, 5094, 0, 0, 13156, 0, 111035, 5093, 111024, 983419, 0, + 5092, 10708, 11327, 0, 5091, 0, 0, 9153, 4104, 78599, 78601, 2929, 42712, + 75067, 12272, 9832, 0, 0, 111105, 0, 0, 0, 0, 0, 0, 13106, 0, 0, 129111, + 0, 0, 0, 0, 9074, 111111, 0, 111110, 0, 8113, 11168, 92563, 1786, 111109, + 0, 111108, 0, 74423, 0, 586, 74414, 64359, 1267, 0, 127531, 0, 65731, 0, + 0, 0, 92932, 0, 0, 0, 0, 0, 0, 1228, 0, 42846, 0, 0, 70343, 1714, 74406, + 0, 0, 0, 127389, 66225, 0, 0, 42660, 0, 0, 3804, 0, 0, 129859, 0, 2826, + 0, 0, 0, 128396, 0, 0, 0, 0, 0, 0, 12206, 5839, 0, 68524, 74065, 73521, + 0, 0, 126240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67241, 917821, 7030, 0, + 10479, 64959, 2852, 0, 121225, 0, 0, 128586, 0, 6963, 0, 0, 0, 74786, 0, + 0, 0, 0, 121281, 0, 0, 0, 0, 113815, 121360, 0, 9994, 118680, 2864, + 64719, 1148, 0, 41677, 0, 0, 2765, 0, 128181, 0, 0, 0, 92516, 74777, 0, + 0, 65206, 0, 0, 0, 0, 69391, 0, 0, 983770, 0, 41839, 129616, 983773, 0, + 0, 6931, 0, 0, 7177, 125137, 0, 0, 0, 93020, 0, 10722, 0, 0, 128186, + 121050, 0, 0, 127207, 0, 750, 0, 129453, 63912, 0, 0, 7032, 0, 0, 4314, + 128600, 0, 128409, 730, 0, 127866, 0, 0, 41380, 0, 0, 0, 69697, 8240, + 92939, 0, 41378, 0, 6938, 70026, 0, 0, 66246, 0, 0, 0, 0, 0, 0, 983094, + 0, 92754, 41470, 64805, 0, 0, 0, 0, 0, 0, 0, 0, 92938, 68370, 0, 0, + 73831, 0, 0, 0, 2872, 0, 0, 0, 0, 604, 41097, 0, 0, 0, 0, 0, 127488, 0, + 2836, 0, 0, 9707, 0, 43202, 0, 0, 69374, 0, 0, 120916, 2832, 92702, 9670, + 12937, 0, 0, 0, 0, 2822, 0, 0, 92519, 0, 73752, 0, 0, 0, 1331, 92603, 0, + 11856, 73510, 129432, 5090, 5089, 0, 3200, 0, 0, 0, 5088, 0, 0, 9477, 0, + 0, 5087, 92325, 0, 96, 5086, 0, 0, 0, 5085, 64286, 0, 0, 43820, 0, + 129710, 0, 0, 119042, 0, 129660, 0, 0, 0, 0, 0, 127241, 120891, 7601, 0, + 591, 0, 118953, 0, 0, 0, 0, 0, 10939, 7246, 6933, 67142, 67141, 0, 74600, + 120695, 0, 67138, 65574, 0, 78058, 67140, 73851, 74598, 67139, 128094, 0, + 6372, 0, 73514, 7963, 6371, 0, 0, 125040, 0, 0, 0, 0, 0, 0, 0, 8258, + 123591, 0, 0, 65148, 118919, 42, 0, 0, 0, 0, 0, 0, 0, 0, 67135, 67134, + 67133, 0, 0, 0, 0, 67136, 67130, 74597, 11550, 0, 67132, 65868, 0, 12826, + 127872, 124116, 126235, 9737, 92448, 0, 0, 0, 8878, 0, 0, 0, 0, 0, 72220, + 9086, 0, 100952, 0, 7437, 7454, 0, 0, 0, 0, 9042, 0, 0, 0, 0, 3805, 0, + 67128, 44001, 67126, 0, 44022, 19949, 12200, 43522, 983045, 43525, 0, 0, + 0, 64422, 67125, 67124, 7602, 0, 0, 43521, 0, 0, 43711, 43523, 41447, + 8424, 68483, 8704, 2397, 0, 0, 0, 0, 0, 10916, 0, 129290, 93998, 0, 0, 0, + 127800, 67686, 9961, 123203, 0, 68842, 10792, 8889, 121402, 6951, 0, + 68827, 917835, 74342, 0, 0, 0, 68816, 129152, 0, 42909, 66597, 70092, 0, + 0, 10481, 4559, 0, 1956, 43138, 0, 0, 43490, 43148, 0, 0, 0, 43140, 0, 0, + 0, 0, 69268, 8533, 0, 0, 0, 0, 0, 4357, 0, 70289, 983157, 0, 42911, 0, 0, + 0, 10941, 0, 6962, 0, 0, 113808, 0, 11014, 0, 8942, 12000, 0, 0, 73515, + 0, 0, 0, 42650, 0, 75016, 63975, 0, 66210, 0, 0, 129150, 0, 11193, 0, 0, + 0, 0, 0, 0, 0, 43476, 0, 11024, 74811, 72787, 10563, 92954, 0, 0, 2462, + 92955, 0, 0, 66213, 6957, 0, 120559, 0, 0, 0, 74594, 983424, 92347, 0, + 110702, 110708, 110707, 127119, 3109, 127117, 119909, 0, 121434, 0, 0, + 4042, 0, 0, 0, 127123, 127122, 127121, 0, 127999, 0, 3503, 74444, 68300, + 6694, 127997, 0, 0, 74306, 0, 983757, 7736, 0, 0, 0, 10521, 0, 42173, + 9705, 0, 129719, 6955, 71467, 0, 6149, 3887, 19956, 1411, 2824, 0, 0, 0, + 1403, 0, 1347, 66282, 127996, 0, 0, 0, 0, 8640, 0, 1178, 1654, 0, 0, + 129529, 43314, 0, 0, 0, 0, 2873, 67461, 0, 0, 67085, 10861, 0, 0, 70377, + 0, 67082, 11159, 41391, 67084, 0, 376, 6987, 983182, 119904, 0, 8823, 0, + 12943, 65185, 100988, 42099, 0, 0, 100990, 0, 8301, 0, 0, 1684, 0, 0, 0, + 120620, 0, 0, 0, 42121, 0, 66781, 78067, 42115, 0, 127998, 0, 67080, + 1493, 42111, 67077, 4097, 0, 983767, 0, 65808, 41642, 0, 118568, 67076, + 41636, 67074, 65095, 110660, 72254, 121240, 41629, 12154, 75073, 0, + 128179, 74084, 64380, 0, 0, 0, 0, 0, 71193, 65371, 7078, 121218, 0, 0, + 74592, 0, 0, 43275, 0, 41434, 6062, 0, 0, 19916, 0, 6950, 9606, 9842, 0, + 65744, 0, 0, 128659, 0, 41615, 10105, 0, 0, 41632, 7493, 0, 0, 41622, 0, + 0, 0, 0, 7632, 983217, 983216, 9805, 5990, 900, 0, 122955, 0, 120869, + 3612, 0, 64376, 0, 5389, 129469, 73495, 0, 2839, 9621, 582, 0, 0, 3749, + 0, 7569, 0, 0, 92865, 6956, 4403, 0, 0, 3299, 0, 0, 119127, 65676, 0, + 74372, 0, 983497, 7598, 69819, 42469, 42242, 1918, 9542, 480, 7716, 0, 0, + 0, 0, 0, 69918, 0, 8328, 0, 118894, 0, 0, 0, 0, 11132, 983502, 66743, + 74185, 100531, 2854, 66747, 0, 65755, 0, 67120, 67119, 65835, 67117, + 66736, 67123, 67122, 67121, 9881, 100481, 65757, 100538, 100459, 67116, + 8648, 128377, 6741, 43047, 0, 13180, 0, 100487, 66754, 73507, 73487, 0, + 0, 41752, 0, 8641, 100490, 125185, 73477, 100462, 100541, 6942, 69501, + 1024, 42849, 41751, 0, 8941, 101034, 11121, 0, 9023, 40973, 121476, 9928, + 67109, 66865, 0, 67114, 67113, 67112, 67111, 0, 41206, 120724, 9049, + 67108, 43166, 0, 41200, 128201, 125142, 126537, 0, 0, 41188, 119553, 0, + 101007, 917548, 74585, 78626, 0, 0, 11466, 0, 120797, 0, 125067, 2261, 0, + 2860, 0, 0, 70828, 127925, 92357, 67106, 12065, 42872, 0, 43875, 67103, + 43856, 0, 67102, 67105, 7531, 40981, 2413, 100522, 67404, 100521, 0, + 67101, 41196, 100523, 0, 129723, 73512, 43117, 100495, 0, 0, 0, 0, 69876, + 0, 7173, 496, 0, 4313, 64607, 0, 0, 983202, 2065, 42793, 2842, 0, 83152, + 13132, 798, 0, 12801, 67098, 10686, 118528, 128143, 0, 8054, 9174, 67087, + 67086, 67097, 67096, 41611, 67095, 74504, 78854, 42512, 0, 78857, 42089, + 74613, 78856, 0, 101029, 100468, 42079, 100467, 0, 66961, 100474, 0, 0, + 0, 68338, 69958, 0, 0, 0, 0, 0, 78859, 42093, 128951, 100504, 0, 0, 0, + 4580, 0, 0, 0, 92167, 0, 3021, 42004, 0, 0, 42317, 41998, 0, 6946, 77920, + 0, 123610, 0, 0, 0, 121442, 42690, 9880, 0, 0, 64589, 0, 0, 127880, + 68035, 0, 11360, 0, 0, 72242, 0, 0, 0, 0, 0, 64941, 0, 0, 0, 6856, 65671, + 11244, 73706, 6959, 41994, 42907, 0, 0, 122902, 8617, 41982, 8860, 0, 0, + 121256, 0, 0, 9597, 0, 43172, 0, 10117, 0, 92297, 65865, 73549, 0, + 128077, 0, 126065, 0, 187, 0, 65669, 0, 4963, 0, 0, 0, 8964, 0, 7775, 0, + 41948, 0, 0, 101010, 41942, 65449, 3160, 65922, 13226, 42665, 0, 42663, + 128210, 41766, 983503, 78848, 78849, 41760, 1189, 905, 110620, 42658, + 78851, 67859, 9629, 6742, 0, 43625, 12952, 7888, 0, 3980, 0, 42656, 0, + 42055, 0, 0, 0, 64540, 0, 7867, 69218, 6236, 0, 73490, 10505, 0, 12851, + 118948, 0, 5474, 128843, 3103, 0, 41753, 41733, 78051, 983477, 78844, + 78845, 41739, 78843, 70744, 10931, 41756, 43347, 68098, 122909, 41746, + 119147, 92591, 41259, 66954, 69930, 2691, 121338, 11231, 41244, 0, 69800, + 66364, 41262, 67503, 0, 0, 41251, 0, 0, 11805, 0, 0, 68331, 94045, 0, 0, + 0, 74633, 41266, 126642, 0, 0, 0, 65741, 41737, 2275, 2666, 121232, + 41738, 4967, 419, 13126, 0, 0, 42822, 0, 6434, 74913, 0, 0, 6432, 0, + 69932, 128862, 769, 41742, 69927, 74805, 6433, 0, 547, 1943, 6439, 0, + 4994, 487, 0, 0, 3754, 0, 0, 0, 0, 74780, 0, 0, 1595, 92777, 74431, 0, 0, + 74860, 43267, 0, 0, 129083, 12185, 69406, 0, 73479, 100984, 0, 42856, 0, + 0, 983765, 128319, 75057, 0, 0, 0, 65612, 0, 669, 0, 0, 0, 0, 0, 70445, + 100404, 69929, 0, 0, 460, 121513, 0, 0, 0, 120747, 0, 121519, 121518, 0, + 0, 121515, 71491, 65187, 9044, 78497, 11760, 78494, 7577, 78491, 41912, + 100412, 0, 100411, 0, 0, 100394, 78501, 0, 2933, 78500, 0, 66441, 100392, + 100397, 100391, 1549, 0, 100415, 0, 41755, 6206, 8670, 120587, 0, 69935, + 0, 0, 69768, 73492, 0, 66958, 0, 0, 10552, 64342, 41922, 0, 917858, 0, + 917857, 2717, 0, 0, 0, 73664, 41908, 100722, 41916, 0, 0, 0, 92506, + 100723, 66664, 69803, 0, 100725, 0, 0, 43373, 0, 0, 8468, 100729, 121173, + 128297, 119210, 118952, 0, 0, 0, 100686, 0, 0, 0, 128703, 100670, 457, + 78502, 78503, 123180, 43006, 0, 8802, 113777, 0, 0, 0, 0, 126632, 0, + 41757, 0, 100657, 44000, 0, 0, 43534, 0, 0, 11961, 121316, 0, 0, 0, + 128736, 0, 0, 9499, 73522, 128330, 0, 0, 92260, 68184, 0, 0, 7256, 66993, + 983180, 0, 42161, 0, 119126, 128022, 65880, 0, 10802, 64861, 0, 0, 0, 0, + 0, 0, 73109, 0, 955, 0, 0, 5350, 64339, 0, 100705, 10875, 0, 5477, 73121, + 0, 0, 0, 67693, 69790, 0, 0, 3874, 0, 983741, 0, 0, 83272, 100674, + 127397, 0, 100989, 0, 41038, 67502, 9207, 42239, 0, 0, 0, 0, 74432, 0, 0, + 1455, 129680, 0, 11753, 119233, 0, 118594, 127854, 100716, 69801, 0, 0, + 43520, 0, 119556, 0, 0, 0, 0, 100733, 10788, 6088, 0, 129587, 190, + 983346, 12593, 100737, 129308, 64408, 0, 4417, 128615, 74359, 41744, 0, + 0, 100435, 6965, 0, 0, 13201, 100430, 69896, 78868, 74382, 11841, 7918, + 92721, 0, 0, 0, 1728, 0, 0, 0, 983350, 92679, 0, 0, 92711, 0, 0, 119536, + 73491, 66679, 8382, 0, 0, 100381, 0, 917889, 42254, 68371, 100383, 0, 0, + 0, 9923, 0, 0, 11763, 100386, 120688, 0, 78187, 0, 0, 0, 0, 8333, 0, 0, + 0, 917805, 74464, 0, 92320, 74080, 0, 69911, 11910, 0, 74141, 8963, 0, 0, + 0, 121396, 0, 41747, 0, 0, 8968, 0, 0, 129110, 110590, 0, 8836, 12315, 0, + 8300, 0, 0, 0, 8856, 0, 0, 69891, 0, 66965, 120405, 120402, 120403, + 120400, 120401, 12853, 43269, 7263, 120244, 6536, 120238, 120239, 65516, + 12321, 120391, 120388, 55287, 2237, 120246, 9588, 120248, 120382, 120383, + 120380, 120381, 0, 0, 3561, 0, 0, 10613, 0, 110583, 0, 0, 0, 128689, + 5006, 64328, 68219, 917894, 0, 8825, 122972, 0, 0, 0, 128616, 0, 119177, + 0, 0, 128641, 120225, 71366, 120227, 120228, 438, 4510, 41707, 8721, + 120233, 120234, 120235, 12840, 120229, 10845, 120231, 8096, 0, 120935, 0, + 0, 65589, 8733, 0, 0, 0, 0, 0, 0, 93984, 11262, 73747, 128522, 917902, + 64591, 42405, 0, 0, 1632, 127982, 128326, 0, 0, 121327, 121477, 42444, 0, + 0, 215, 41258, 128494, 64494, 1953, 10185, 0, 1256, 3910, 41260, 917903, + 0, 0, 41257, 0, 8675, 10700, 0, 124951, 0, 9333, 0, 121471, 0, 0, 0, 0, + 0, 499, 0, 70729, 42915, 0, 101000, 0, 100999, 0, 0, 73111, 128893, + 122897, 0, 125006, 0, 11118, 0, 128009, 0, 0, 118633, 9180, 0, 0, 0, + 100986, 43438, 118588, 0, 0, 0, 0, 120669, 64782, 0, 0, 73969, 565, + 42484, 118913, 201, 0, 42292, 69610, 0, 0, 119625, 43518, 0, 0, 1022, + 113788, 3880, 74247, 0, 0, 0, 0, 0, 0, 0, 0, 72272, 100997, 0, 0, 66937, + 74255, 0, 0, 92598, 0, 9903, 118993, 0, 68226, 0, 0, 0, 127788, 100955, + 83280, 7892, 0, 10777, 0, 0, 65562, 0, 101002, 0, 8039, 3363, 101009, 0, + 0, 66940, 12596, 70812, 0, 0, 0, 0, 42944, 92425, 74992, 64541, 0, 0, + 10520, 12802, 0, 12998, 0, 83270, 42861, 83273, 11415, 0, 7541, 125068, + 65878, 822, 0, 0, 5774, 194746, 43252, 0, 92619, 7672, 129281, 0, 0, + 7463, 0, 0, 0, 0, 0, 0, 121411, 0, 0, 0, 66938, 0, 475, 0, 120586, 7329, + 0, 0, 195088, 66291, 10645, 0, 6543, 100966, 0, 0, 119065, 0, 0, 0, + 983237, 195095, 0, 8923, 1645, 0, 0, 0, 3196, 72404, 0, 0, 43595, 0, 0, + 0, 0, 0, 195076, 0, 0, 5258, 4328, 0, 0, 0, 405, 11454, 0, 0, 0, 0, + 75052, 41245, 0, 195078, 4523, 11369, 0, 0, 0, 195079, 0, 0, 983510, 0, + 100961, 10480, 74610, 0, 0, 0, 12610, 0, 41247, 0, 7609, 118837, 0, 0, + 92253, 0, 984, 0, 92621, 0, 0, 129885, 73982, 0, 0, 0, 43369, 0, 0, 0, + 983507, 6634, 0, 71952, 0, 66930, 74214, 0, 67709, 0, 0, 0, 71114, 9552, + 0, 0, 0, 12997, 0, 0, 0, 0, 129109, 12883, 10994, 10529, 55283, 0, 74618, + 0, 67736, 10661, 19951, 9614, 2428, 0, 121023, 92837, 126224, 66933, + 71127, 0, 124996, 119162, 1952, 92181, 8455, 100958, 118654, 93033, + 119566, 100960, 0, 12183, 100951, 0, 64929, 0, 0, 0, 128290, 42509, + 73087, 3922, 9187, 983626, 0, 0, 119057, 0, 3353, 9358, 0, 0, 66680, 0, + 73975, 12879, 0, 9795, 68380, 0, 0, 119488, 0, 0, 41027, 0, 66931, 0, + 983631, 0, 70378, 0, 11751, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129356, 0, 0, + 0, 0, 41029, 0, 126513, 0, 0, 0, 11294, 0, 66665, 0, 0, 127750, 0, 0, + 70105, 0, 983643, 0, 67843, 0, 0, 121167, 983895, 0, 8088, 129412, 0, 0, + 0, 983992, 6926, 72423, 0, 129569, 42369, 4350, 0, 65145, 9041, 43559, 0, + 0, 0, 41263, 0, 0, 0, 65825, 9577, 68199, 0, 0, 983122, 0, 6793, 0, + 70409, 0, 0, 0, 0, 64669, 0, 0, 0, 11200, 72725, 2995, 0, 0, 0, 7868, + 72720, 72020, 11386, 1009, 70405, 66871, 2333, 0, 0, 0, 0, 0, 70407, + 128121, 0, 0, 0, 0, 983657, 66949, 0, 74968, 0, 0, 110601, 0, 0, 41261, + 0, 0, 0, 0, 118989, 6736, 917883, 124132, 43010, 66952, 0, 69635, 73011, + 983716, 0, 0, 7293, 0, 0, 0, 0, 111332, 0, 128245, 69928, 127071, 0, 127072, 64445, 111336, 6635, 0, 0, 72707, 74936, 0, 0, 917876, 0, 93025, 66948, 0, 111329, 0, 129887, 128045, 65219, 11925, 0, 92434, 0, 0, 9845, 101317, 7546, 0, 0, 11230, 4985, 13288, 672, 8098, 0, 0, 0, 128126, 42655, 0, 0, 1577, 11772, 78327, 0, 66673, 0, 65911, 118705, 0, 0, 101303, 92180, 0, 0, 120566, 125140, 127177, 0, 0, 119593, 1539, 0, 74969, 42731, 0, 74970, 71066, 0, 3051, 0, 73783, 0, 0, 0, 0, 78777, 0, - 983160, 0, 0, 101310, 0, 0, 0, 0, 0, 0, 3505, 8707, 0, 6725, 128013, 0, - 92314, 0, 66391, 5479, 0, 6686, 0, 0, 983315, 42754, 0, 0, 0, 0, 0, 0, + 983161, 0, 0, 101310, 0, 0, 0, 0, 0, 0, 3505, 8707, 0, 6725, 128013, 0, + 92314, 0, 66391, 5479, 0, 6686, 0, 0, 983318, 42754, 0, 0, 0, 0, 0, 0, 128523, 0, 0, 4433, 41156, 0, 74971, 1443, 9339, 0, 92871, 10926, 0, - 43511, 0, 0, 983321, 0, 126086, 72236, 10021, 0, 101329, 0, 65914, 0, + 43511, 0, 0, 983324, 0, 126086, 72236, 10021, 0, 101329, 0, 65914, 0, 66749, 0, 6721, 217, 12466, 0, 0, 10443, 0, 68654, 0, 0, 0, 78334, 0, 41250, 0, 129532, 128375, 0, 0, 69232, 0, 41252, 66682, 0, 119637, 41249, 1366, 0, 0, 101326, 0, 0, 4397, 101324, 0, 66946, 9545, 101323, 0, 0, 0, @@ -25989,17 +26170,17 @@ static const unsigned int code_hash[] = { 128436, 68845, 0, 69724, 67412, 92952, 0, 43811, 0, 128924, 0, 11062, 128748, 0, 0, 0, 69276, 2901, 7865, 66945, 78354, 0, 78347, 0, 126123, 0, 66363, 0, 0, 0, 74967, 7414, 0, 0, 92691, 0, 128507, 885, 64772, 65180, - 0, 71267, 852, 0, 0, 0, 78614, 121174, 129092, 67809, 9609, 12156, 0, 0, - 43586, 11035, 10411, 0, 13268, 6710, 0, 0, 0, 43853, 77949, 4315, 0, - 111104, 0, 43639, 43343, 0, 0, 0, 73074, 0, 65812, 43431, 0, 0, 0, 0, 0, - 129890, 0, 0, 0, 0, 994, 125222, 127104, 127103, 73966, 66890, 0, 65291, - 70753, 0, 0, 0, 0, 66873, 4186, 92531, 127106, 127105, 6718, 7330, 4406, - 0, 8480, 7319, 64373, 128699, 4413, 0, 0, 3198, 0, 0, 92469, 111126, 0, - 128591, 128681, 0, 0, 0, 101321, 73023, 742, 0, 2893, 78738, 0, 0, 0, - 2553, 42294, 6756, 0, 73020, 8363, 0, 2993, 128381, 3916, 4301, 0, 1141, - 42407, 0, 0, 7572, 973, 0, 125077, 0, 2415, 0, 0, 9640, 42333, 0, 0, - 129546, 42486, 43381, 65390, 0, 69434, 1202, 0, 0, 0, 0, 68484, 0, 0, - 64542, 3260, 0, 65388, 43502, 69904, 0, 6738, 0, 0, 74193, 0, 0, 0, + 0, 71267, 852, 0, 0, 0, 78614, 121174, 129092, 67809, 9609, 12156, 0, + 122930, 43586, 11035, 10411, 0, 13268, 6710, 0, 0, 0, 43853, 77949, 4315, + 0, 111104, 0, 43639, 43343, 0, 0, 0, 73074, 0, 65812, 43431, 0, 0, 0, 0, + 0, 129890, 0, 0, 0, 0, 994, 125222, 127104, 127103, 73966, 66890, 0, + 65291, 70753, 0, 0, 0, 0, 66873, 4186, 92531, 127106, 127105, 6718, 7330, + 4406, 122946, 8480, 7319, 64373, 128699, 4413, 0, 0, 3198, 0, 0, 92469, + 111126, 0, 128591, 128681, 0, 0, 0, 101321, 73023, 742, 0, 2893, 78738, + 0, 0, 0, 2553, 42294, 6756, 0, 73020, 8363, 0, 2993, 128381, 3916, 4301, + 0, 1141, 42407, 0, 0, 7572, 973, 0, 125077, 0, 2415, 0, 0, 9640, 42333, + 0, 0, 129546, 42486, 43381, 65390, 0, 69434, 1202, 0, 0, 0, 0, 68484, 0, + 0, 64542, 3260, 0, 65388, 43502, 69904, 0, 6738, 0, 0, 74193, 0, 0, 0, 74641, 6312, 0, 74556, 12446, 0, 0, 128076, 8229, 1235, 0, 11472, 83064, 0, 0, 101366, 0, 0, 1740, 12872, 0, 985, 0, 0, 0, 12068, 983658, 0, 101363, 0, 0, 0, 13133, 65071, 110780, 12655, 12134, 0, 92934, 0, 66915, @@ -26010,21 +26191,21 @@ static const unsigned int code_hash[] = { 7525, 3346, 8339, 125004, 72705, 69462, 268, 0, 0, 5754, 94019, 0, 110684, 8336, 0, 0, 0, 8337, 8341, 0, 11388, 7522, 0, 0, 0, 11090, 6953, 125240, 0, 74973, 120708, 0, 0, 0, 0, 0, 110782, 0, 9038, 7887, 0, 0, - 42534, 64347, 0, 0, 67660, 120341, 0, 0, 0, 120878, 0, 0, 73999, 0, + 42534, 64347, 0, 0, 67660, 120341, 0, 122933, 0, 120878, 0, 0, 73999, 0, 64580, 0, 0, 64643, 0, 0, 74975, 0, 92227, 129052, 0, 83071, 83072, 83073, 119154, 0, 119153, 0, 0, 5349, 72440, 2160, 917554, 7411, 0, - 983221, 0, 0, 0, 42736, 70747, 5756, 983226, 92946, 0, 42764, 0, 0, + 983224, 0, 0, 0, 42736, 70747, 5756, 983229, 92946, 0, 42764, 0, 0, 119529, 5752, 120600, 0, 0, 0, 0, 0, 78893, 0, 0, 0, 125242, 0, 0, - 120331, 0, 0, 0, 67501, 0, 10080, 83056, 12647, 0, 0, 69252, 66882, 0, 0, - 0, 0, 0, 72005, 72845, 0, 0, 0, 0, 0, 74213, 0, 0, 0, 0, 0, 6302, 0, 0, - 0, 0, 1417, 983223, 0, 9452, 0, 74393, 0, 0, 110850, 0, 65391, 63789, - 69251, 78659, 78660, 41264, 78658, 6426, 42398, 9179, 78654, 64906, - 41255, 42036, 0, 41269, 0, 41267, 42436, 67759, 42323, 42034, 0, 0, - 42475, 42033, 0, 0, 68916, 43948, 0, 78673, 78674, 1659, 919, 42784, + 120331, 122957, 0, 0, 67501, 0, 10080, 83056, 12647, 0, 0, 69252, 66882, + 0, 0, 0, 0, 0, 72005, 72845, 0, 0, 0, 0, 0, 74213, 0, 0, 0, 0, 0, 6302, + 0, 0, 0, 0, 1417, 983226, 0, 9452, 0, 74393, 0, 0, 110850, 0, 65391, + 63789, 69251, 78659, 78660, 41264, 78658, 6426, 42398, 9179, 78654, + 64906, 41255, 42036, 0, 41269, 0, 41267, 42436, 67759, 42323, 42034, 0, + 0, 42475, 42033, 0, 0, 68916, 43948, 0, 78673, 78674, 1659, 919, 42784, 1671, 0, 6069, 9219, 0, 1661, 71489, 0, 92690, 10140, 9713, 78400, 119143, 125236, 0, 2306, 0, 0, 6068, 10612, 0, 0, 121314, 92561, 41462, - 0, 0, 0, 0, 0, 0, 0, 128204, 10635, 0, 983222, 0, 0, 0, 983232, 92251, 0, - 121029, 983224, 0, 8100, 0, 78669, 78670, 13301, 78667, 9667, 78665, 0, + 0, 0, 0, 0, 0, 0, 0, 128204, 10635, 0, 983225, 0, 0, 0, 983235, 92251, 0, + 121029, 983227, 0, 8100, 0, 78669, 78670, 13301, 78667, 9667, 78665, 0, 0, 11003, 9904, 0, 0, 0, 0, 0, 0, 78680, 78681, 78677, 78678, 0, 10313, 0, 0, 64320, 10265, 78686, 129404, 78684, 78685, 8945, 78683, 70750, 41, 0, 0, 0, 0, 8655, 0, 0, 71333, 0, 0, 0, 0, 2585, 0, 65254, 3126, 0, @@ -26034,7 +26215,7 @@ static const unsigned int code_hash[] = { 78688, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119925, 0, 983637, 0, 0, 0, 71494, 83399, 127541, 83398, 8022, 78808, 0, 73794, 0, 0, 83414, 119916, 0, 0, 0, 0, 0, 0, 63799, 78427, 12063, 78425, 78424, 0, 0, 0, 75025, 0, - 297, 0, 0, 68326, 0, 78429, 78428, 7077, 2497, 128651, 0, 983111, 0, 0, + 297, 0, 0, 68326, 0, 78429, 78428, 7077, 2497, 128651, 0, 983112, 0, 0, 0, 4292, 0, 74815, 10512, 0, 74814, 119931, 0, 72841, 2503, 65070, 1762, 69794, 2495, 0, 71230, 94069, 77984, 0, 12654, 0, 1899, 0, 2507, 0, 8726, 0, 65594, 0, 71272, 8892, 0, 0, 0, 0, 0, 420, 0, 0, 125130, 10797, 74637, @@ -26069,12 +26250,12 @@ static const unsigned int code_hash[] = { 66604, 72025, 0, 0, 0, 66600, 523, 92642, 71100, 74436, 0, 0, 0, 8608, 83435, 72828, 128704, 0, 127402, 11307, 66707, 67301, 67300, 67299, 0, 67304, 67303, 0, 0, 0, 0, 122654, 5908, 0, 0, 6744, 67310, 1699, 67308, - 67307, 67314, 67313, 6306, 67311, 983207, 72150, 69862, 3766, 2389, + 67307, 67314, 67313, 6306, 67311, 983209, 72150, 69862, 3766, 2389, 67305, 74569, 6611, 65700, 0, 0, 0, 42386, 0, 0, 2599, 917972, 119131, - 119049, 65717, 0, 0, 119654, 0, 0, 0, 74203, 3760, 1718, 68160, 0, 3776, - 7335, 0, 0, 67324, 69861, 0, 69792, 0, 0, 3778, 0, 9462, 7824, 0, 78896, - 3768, 68142, 765, 72822, 3764, 0, 0, 113822, 129667, 12947, 0, 0, 0, - 118806, 73753, 0, 0, 0, 6829, 5225, 66901, 0, 0, 0, 0, 67319, 67318, + 119049, 65717, 0, 0, 119654, 0, 0, 73538, 74203, 3760, 1718, 68160, 0, + 3776, 7335, 0, 0, 67324, 69861, 0, 69792, 0, 0, 3778, 0, 9462, 7824, 0, + 78896, 3768, 68142, 765, 72822, 3764, 0, 0, 113822, 129667, 12947, 0, 0, + 0, 118806, 73753, 0, 0, 0, 6829, 5225, 66901, 0, 0, 0, 0, 67319, 67318, 3162, 67316, 67323, 67322, 67321, 67320, 0, 5353, 128190, 74179, 67315, 0, 1010, 6851, 0, 67326, 67325, 127870, 6952, 67329, 67328, 67327, 2590, 120036, 65552, 120034, 120039, 7183, 120037, 120038, 120027, 120028, @@ -26103,13 +26284,13 @@ static const unsigned int code_hash[] = { 3140, 0, 0, 68007, 0, 67258, 10909, 0, 1428, 0, 67254, 67253, 7699, 12393, 67257, 0, 67256, 67255, 0, 0, 69389, 0, 0, 0, 0, 0, 67153, 0, 0, 127383, 69376, 64554, 0, 3878, 0, 42352, 1752, 0, 129702, 42506, 0, - 10199, 0, 983465, 125231, 0, 0, 0, 720, 0, 0, 0, 68831, 0, 1464, 128339, + 10199, 0, 983468, 125231, 0, 0, 0, 720, 0, 0, 0, 68831, 0, 1464, 128339, 0, 7974, 0, 125017, 68082, 0, 0, 0, 0, 74787, 0, 78864, 92258, 0, 0, 78863, 0, 1302, 66288, 0, 0, 0, 67152, 0, 983611, 983618, 0, 0, 3995, 0, 65608, 3714, 0, 0, 67262, 67261, 67260, 67259, 43251, 67264, 67263, 0, 120557, 92346, 8672, 68006, 11964, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 92610, 0, 468, 0, 0, 0, 983472, 0, 0, 128544, 129397, 65907, 983163, 0, - 0, 0, 0, 0, 983470, 41743, 0, 0, 0, 74880, 0, 121001, 820, 41741, 0, + 92610, 0, 468, 0, 0, 0, 983475, 0, 0, 128544, 129397, 65907, 983164, 0, + 0, 0, 0, 0, 983473, 41743, 0, 0, 0, 74880, 0, 121001, 820, 41741, 0, 120667, 0, 64684, 126992, 128604, 126082, 69934, 65177, 6226, 353, 43645, 0, 119612, 120738, 67700, 0, 0, 0, 0, 42457, 120276, 0, 120277, 1884, 129637, 42418, 113678, 41157, 0, 42305, 120279, 0, 0, 41151, 0, 71430, 0, @@ -26124,7 +26305,7 @@ static const unsigned int code_hash[] = { 119083, 0, 71437, 119854, 69936, 0, 0, 3525, 6824, 0, 0, 119858, 128451, 0, 72239, 113738, 0, 71424, 0, 0, 0, 0, 0, 10727, 7212, 129071, 71957, 0, 0, 0, 67156, 808, 7207, 42387, 0, 0, 0, 0, 0, 0, 0, 0, 9225, 121149, 0, - 9145, 128060, 41018, 67841, 983158, 42300, 0, 3084, 983155, 125014, + 9145, 128060, 41018, 67841, 983159, 42300, 0, 3084, 983156, 125014, 41025, 6037, 0, 194885, 0, 10290, 0, 3083, 10322, 111017, 129030, 0, 41036, 0, 0, 43321, 65606, 0, 41032, 42388, 0, 64700, 0, 1445, 40961, 0, 0, 0, 40960, 0, 67727, 0, 2223, 64952, 10402, 0, 0, 0, 10603, 0, 118577, @@ -26141,15 +26322,15 @@ static const unsigned int code_hash[] = { 0, 13099, 71445, 70371, 0, 6435, 72154, 11362, 0, 0, 0, 0, 41420, 0, 3625, 74915, 41409, 71441, 0, 0, 0, 9672, 0, 0, 43317, 0, 0, 0, 41424, 917598, 0, 0, 0, 0, 41417, 1261, 0, 0, 12102, 119662, 41401, 0, 127538, - 129518, 0, 124943, 72765, 3275, 92472, 0, 0, 0, 118686, 0, 0, 0, 0, - 125129, 983140, 10598, 0, 128633, 6711, 0, 2920, 0, 0, 0, 0, 19928, 0, 0, + 129518, 0, 124943, 72765, 3275, 92472, 0, 0, 0, 118686, 0, 128946, 0, 0, + 125129, 983141, 10598, 0, 128633, 6711, 0, 2920, 0, 0, 0, 0, 19928, 0, 0, 3917, 0, 113756, 0, 0, 66588, 128078, 0, 0, 113721, 113758, 983081, 0, 0, 41184, 0, 232, 0, 0, 74170, 0, 0, 0, 0, 9094, 0, 0, 92585, 0, 1064, 0, 0, 10115, 0, 0, 0, 7862, 0, 13224, 0, 0, 66650, 0, 0, 72877, 1878, 0, 71434, 2911, 0, 41178, 5427, 0, 0, 0, 12617, 41174, 0, 67148, 67147, 0, 42413, 41167, 2406, 0, 0, 0, 0, 0, 9618, 128668, 0, 0, 0, 0, 41436, 9337, 126067, 0, 41456, 0, 119086, 11333, 0, 6703, 0, 125071, 1613, 0, 0, 0, - 983191, 0, 0, 74500, 41460, 78197, 0, 0, 194899, 67144, 65841, 0, 121109, + 983192, 0, 0, 74500, 41460, 78197, 0, 0, 194899, 67144, 65841, 0, 121109, 74064, 111146, 111144, 120375, 0, 111122, 0, 111121, 64687, 111120, 42592, 3871, 0, 128305, 9111, 111163, 0, 111156, 120366, 121462, 11150, 111154, 71488, 111179, 0, 111168, 0, 120362, 41587, 70391, 0, 74322, @@ -26157,8 +26338,8 @@ static const unsigned int code_hash[] = { 111127, 111140, 41595, 0, 0, 65801, 110587, 110586, 110585, 110584, 73712, 0, 41598, 3993, 121269, 1545, 40971, 121286, 72874, 0, 0, 0, 120767, 65286, 0, 0, 0, 0, 2201, 0, 0, 5402, 0, 0, 74462, 73457, 0, 0, - 78194, 64326, 40969, 0, 128110, 983703, 40968, 0, 121139, 0, 0, 0, 0, - 128513, 8020, 0, 41012, 0, 0, 65805, 41006, 0, 0, 74605, 0, 118942, + 78194, 64326, 40969, 0, 128110, 983703, 40968, 0, 121139, 0, 128891, 0, + 0, 128513, 8020, 0, 41012, 0, 0, 65805, 41006, 0, 0, 74605, 0, 118942, 43432, 0, 0, 92900, 0, 0, 68671, 120687, 0, 92958, 0, 0, 68332, 0, 40992, 0, 0, 0, 0, 0, 42235, 0, 1741, 42370, 0, 0, 0, 11413, 126583, 0, 0, 128769, 6470, 0, 74517, 0, 0, 120651, 40984, 0, 42742, 0, 12916, 6284, 0, @@ -26167,7 +26348,7 @@ static const unsigned int code_hash[] = { 2796, 0, 0, 9902, 0, 67988, 64785, 82995, 128822, 42631, 983040, 71890, 0, 74164, 41238, 10049, 11405, 0, 64368, 0, 120925, 0, 397, 12299, 42139, 0, 9590, 0, 0, 43661, 43819, 0, 6651, 3544, 0, 0, 9620, 0, 0, 0, 92229, - 1333, 7104, 0, 6425, 0, 0, 123561, 0, 0, 0, 11976, 8554, 13055, 0, + 1333, 7104, 0, 6425, 0, 0, 123561, 0, 0, 129725, 11976, 8554, 13055, 0, 110733, 0, 110731, 41218, 0, 0, 128673, 1883, 0, 0, 70443, 41225, 70788, 42419, 983707, 129450, 0, 127896, 0, 65809, 11837, 0, 129104, 7141, 0, 0, 0, 0, 0, 42363, 0, 0, 0, 0, 69949, 119157, 64732, 0, 0, 126983, 0, 0, @@ -26178,9 +26359,9 @@ static const unsigned int code_hash[] = { 11273, 120986, 43004, 0, 82988, 0, 961, 64307, 0, 0, 129752, 67711, 110615, 0, 1696, 0, 9762, 12105, 0, 110622, 110623, 3264, 110621, 110618, 43003, 110616, 110617, 0, 120359, 0, 128660, 0, 2322, 0, 70831, 11449, - 128187, 42868, 0, 0, 0, 0, 113746, 983235, 0, 129583, 66398, 0, 0, 0, 0, + 128187, 42868, 0, 0, 0, 0, 113746, 983238, 0, 129583, 66398, 0, 0, 0, 0, 0, 69494, 119224, 0, 0, 64421, 0, 113739, 0, 65823, 0, 11182, 0, 0, 0, - 7766, 55268, 0, 4598, 0, 65839, 0, 0, 0, 10851, 0, 6179, 92602, 6180, + 7766, 55268, 0, 4598, 0, 65839, 0, 0, 3315, 10851, 0, 6179, 92602, 6180, 129524, 11952, 0, 78648, 78651, 78646, 78647, 78644, 78645, 3801, 78643, 6176, 120580, 0, 0, 6177, 0, 78652, 78653, 6178, 0, 0, 0, 0, 2214, 8754, 0, 0, 2137, 0, 0, 0, 0, 66889, 0, 0, 0, 8974, 2308, 0, 74579, 0, 2318, @@ -26224,151 +26405,152 @@ static const unsigned int code_hash[] = { 0, 127321, 0, 127322, 0, 0, 0, 1050, 7549, 127319, 0, 9314, 0, 0, 0, 0, 0, 70434, 127314, 12527, 66504, 0, 0, 0, 0, 64333, 127312, 128547, 92594, 0, 0, 0, 129316, 0, 124960, 10360, 6746, 0, 0, 0, 0, 13085, 9233, 0, 0, - 0, 0, 0, 0, 92766, 0, 121114, 983944, 74212, 42819, 10910, 118627, 68044, - 9896, 0, 0, 120915, 0, 0, 7970, 0, 0, 0, 0, 113699, 9849, 0, 122910, 0, - 0, 10487, 69714, 0, 10103, 0, 4769, 0, 129967, 0, 2283, 0, 0, 74785, 0, - 0, 0, 110595, 110596, 0, 110594, 64565, 4773, 0, 0, 0, 4770, 0, 0, 0, - 65457, 69441, 0, 0, 127338, 983593, 4774, 0, 68497, 2259, 0, 0, 10215, 0, - 0, 0, 0, 0, 74776, 92160, 4768, 0, 0, 4099, 0, 110699, 110700, 110697, - 2225, 0, 0, 0, 0, 125217, 11255, 42814, 880, 0, 0, 0, 0, 0, 67756, 65246, - 0, 0, 129463, 7095, 0, 0, 0, 0, 0, 0, 2427, 0, 7093, 0, 11585, 0, 9962, - 0, 12223, 0, 78211, 1434, 42939, 0, 11573, 0, 0, 0, 121257, 0, 0, 0, 0, - 74437, 0, 113711, 917596, 0, 8740, 0, 3782, 64331, 0, 65167, 1014, 0, 0, - 0, 10835, 129987, 0, 0, 0, 0, 0, 118824, 7302, 0, 67707, 0, 1150, 10547, - 0, 0, 68427, 0, 0, 0, 0, 118788, 0, 0, 0, 42257, 8010, 0, 0, 0, 9643, 0, - 0, 12864, 0, 0, 0, 0, 0, 0, 0, 0, 1426, 68217, 0, 68447, 129971, 0, 0, 0, - 73701, 0, 0, 0, 65383, 0, 0, 0, 0, 0, 0, 43196, 43194, 92549, 10744, 0, - 990, 93772, 0, 0, 0, 0, 0, 66470, 0, 0, 0, 3945, 0, 0, 0, 130039, 0, - 127546, 127746, 1020, 73763, 92257, 118669, 0, 64748, 0, 0, 10205, 0, 0, - 10016, 0, 74051, 0, 43242, 125096, 2667, 0, 125037, 0, 9911, 0, 0, 10097, - 0, 0, 0, 118836, 0, 0, 0, 0, 68889, 10159, 113759, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 983340, 92291, 0, 127973, 72882, 0, 1041, 127182, 6354, 0, 65364, - 0, 0, 0, 72884, 0, 128477, 0, 65906, 127819, 72883, 0, 128470, 5375, - 72881, 0, 8215, 0, 10074, 0, 0, 0, 69899, 0, 0, 121426, 41382, 0, 0, - 5173, 65348, 527, 0, 0, 0, 128250, 0, 0, 0, 0, 0, 0, 42695, 0, 42250, 0, - 11187, 113695, 0, 1568, 66806, 0, 0, 113705, 0, 0, 129487, 0, 0, 128839, - 9069, 6144, 0, 0, 0, 0, 66783, 0, 74027, 118934, 66787, 74580, 0, 110790, - 6364, 0, 66794, 43508, 0, 92612, 0, 0, 0, 0, 128405, 66449, 0, 0, 0, 0, - 70714, 0, 70716, 0, 1044, 42411, 0, 0, 0, 0, 43239, 0, 0, 0, 118572, - 42450, 0, 0, 68479, 119237, 0, 0, 0, 0, 0, 69956, 11537, 0, 121206, 0, 0, - 0, 0, 1057, 566, 0, 0, 10907, 42274, 43464, 0, 118698, 0, 78472, 71207, - 42636, 0, 123603, 0, 0, 121171, 64659, 0, 127749, 0, 6357, 6362, 0, 0, - 2216, 9090, 0, 0, 0, 0, 68227, 0, 0, 0, 0, 1053, 12830, 0, 0, 0, 1052, - 1051, 459, 1060, 0, 66479, 0, 0, 0, 128061, 42490, 689, 6508, 4163, - 42298, 8639, 983335, 4246, 0, 43514, 42362, 0, 42337, 64596, 0, 0, 0, 0, - 0, 6359, 0, 43471, 0, 0, 0, 127274, 0, 6358, 6361, 1926, 6356, 0, 7898, - 0, 10935, 0, 127972, 121285, 0, 43685, 0, 0, 42910, 0, 8693, 0, 0, 44010, - 0, 120991, 121454, 0, 0, 0, 0, 129514, 0, 0, 0, 0, 73947, 0, 129361, - 92412, 0, 66477, 0, 0, 0, 43854, 71913, 0, 0, 0, 0, 72227, 65899, 92275, - 0, 0, 0, 68887, 0, 71057, 0, 0, 0, 0, 119183, 2923, 10853, 0, 0, 0, 0, - 72864, 0, 72773, 72772, 0, 120801, 65251, 122624, 68228, 0, 128548, 0, 0, - 5370, 70465, 2931, 73848, 0, 10188, 0, 118848, 0, 983942, 0, 0, 120584, - 72212, 0, 10844, 121016, 128195, 92424, 0, 0, 0, 286, 0, 1062, 0, 0, 0, - 7395, 0, 1070, 128993, 0, 6095, 0, 0, 0, 127796, 126465, 64497, 0, 0, 0, - 0, 70054, 8189, 78272, 0, 0, 0, 0, 0, 113783, 42102, 78276, 0, 0, 42101, - 0, 78402, 67427, 33, 67425, 67424, 10824, 67430, 67429, 67428, 427, - 64723, 0, 0, 0, 0, 1031, 0, 0, 42104, 0, 0, 2328, 0, 1071, 42899, 128486, - 0, 7673, 0, 0, 1047, 194837, 0, 42908, 0, 0, 10651, 0, 0, 0, 72433, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13216, 0, 69716, 0, 0, 0, 0, 0, 92411, - 69654, 0, 0, 129904, 2761, 129909, 0, 0, 0, 0, 8643, 0, 0, 94021, 2757, - 11067, 0, 74498, 8910, 10689, 0, 0, 0, 71173, 0, 9196, 71214, 0, 0, 0, 0, - 118911, 0, 0, 0, 0, 0, 0, 0, 0, 68130, 119616, 0, 0, 42477, 67482, 0, - 4495, 0, 0, 0, 0, 70080, 10992, 0, 0, 0, 0, 9318, 0, 6002, 0, 73808, 0, - 92601, 42249, 7639, 43995, 0, 0, 5454, 0, 0, 0, 0, 0, 0, 0, 121189, 0, - 119173, 0, 9704, 120686, 0, 78436, 78435, 11204, 0, 0, 1731, 0, 92937, 0, - 67990, 0, 0, 0, 126576, 127018, 71951, 55265, 0, 0, 0, 0, 127257, 73826, - 0, 3840, 0, 41432, 0, 0, 68430, 0, 43253, 128284, 0, 3371, 92936, 0, 0, - 1479, 69282, 0, 1109, 77997, 0, 129154, 0, 92782, 0, 0, 8868, 399, 67978, - 74842, 0, 0, 194839, 0, 551, 0, 10156, 0, 92572, 0, 2544, 65074, 0, 0, 0, - 0, 0, 0, 0, 128713, 0, 0, 74268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68045, 0, - 0, 0, 3447, 0, 0, 121414, 2549, 110818, 0, 0, 43564, 8946, 0, 74411, - 66864, 0, 70480, 7980, 0, 113698, 0, 119653, 66489, 0, 64695, 128063, 0, - 0, 0, 0, 0, 0, 43452, 0, 92993, 0, 10919, 0, 67810, 0, 0, 0, 0, 6450, - 10055, 0, 0, 0, 0, 42720, 0, 9626, 0, 128055, 74447, 0, 125127, 92573, 0, - 0, 0, 119075, 0, 0, 66486, 0, 0, 0, 0, 0, 0, 75028, 983883, 74839, 0, 0, - 0, 0, 0, 55286, 0, 1055, 917628, 0, 0, 0, 70516, 12146, 118623, 73956, - 66488, 0, 0, 0, 0, 0, 0, 42518, 0, 0, 0, 7407, 74978, 0, 0, 0, 0, 0, 0, - 0, 10231, 0, 66626, 0, 0, 92951, 0, 65927, 0, 0, 69696, 0, 92389, 0, 0, - 0, 68095, 92950, 0, 10555, 0, 0, 9091, 10798, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 43222, 0, 74982, 0, 0, 120952, 0, 0, 2992, 7826, 74321, 110879, 125103, - 74981, 92628, 0, 129903, 128289, 128203, 4361, 129597, 1306, 78770, 1497, - 983628, 0, 0, 0, 8248, 0, 127253, 7973, 128706, 0, 0, 73122, 983949, 0, - 0, 2963, 120653, 0, 128554, 0, 0, 64258, 0, 0, 69677, 74983, 65103, 0, - 125008, 42625, 0, 72022, 0, 0, 64905, 0, 9512, 0, 119076, 6443, 983264, - 0, 9135, 0, 0, 123202, 0, 0, 983882, 93788, 0, 0, 0, 93767, 64256, 0, - 11669, 0, 0, 4524, 0, 129182, 128390, 0, 74266, 0, 0, 0, 70119, 78410, - 69809, 121031, 55219, 69815, 93765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2986, 0, 93763, 3437, 0, 6203, 4247, 0, 11920, 8274, 68240, 129694, 1657, - 0, 121276, 0, 0, 2954, 43506, 42837, 0, 0, 71179, 0, 0, 0, 66476, 68450, - 0, 0, 0, 43362, 983134, 129596, 11705, 0, 0, 0, 127354, 0, 11710, 0, 0, - 0, 0, 74429, 0, 0, 1058, 129555, 0, 0, 5484, 1144, 0, 0, 0, 0, 0, 118972, - 0, 65322, 0, 6441, 0, 0, 2547, 66484, 43634, 0, 5871, 0, 0, 0, 0, 0, 0, - 71204, 0, 0, 1865, 0, 0, 69950, 0, 93021, 73713, 0, 71199, 65826, 2069, - 0, 119092, 43999, 2997, 0, 126588, 0, 65319, 0, 12316, 0, 0, 123630, - 8776, 0, 0, 66294, 13130, 0, 71191, 126625, 0, 10030, 11709, 12364, - 983853, 0, 11704, 0, 118641, 68672, 0, 0, 0, 0, 11706, 9710, 0, 82985, 0, - 413, 65623, 0, 0, 0, 74446, 0, 1042, 0, 128378, 12171, 119240, 0, 69384, - 4984, 0, 708, 11391, 0, 0, 0, 983930, 1308, 0, 3673, 810, 0, 120933, - 118567, 0, 0, 1917, 3000, 0, 0, 0, 65628, 66387, 74470, 0, 0, 0, 10027, - 0, 0, 0, 0, 128831, 983167, 2980, 755, 0, 0, 65622, 0, 121012, 7277, - 121022, 0, 0, 0, 0, 8730, 0, 0, 0, 7274, 119250, 0, 7275, 0, 935, 0, 0, - 377, 42325, 121103, 0, 101133, 101132, 101135, 101134, 0, 74911, 2417, - 101130, 0, 19912, 0, 0, 101128, 101127, 0, 101129, 101124, 7248, 101126, - 101125, 1781, 5496, 3627, 62, 1649, 0, 964, 0, 0, 0, 0, 92897, 0, 0, - 127364, 0, 43689, 127911, 66287, 78812, 64389, 66575, 0, 73041, 0, - 129687, 0, 7677, 2991, 3293, 0, 0, 0, 72201, 0, 11341, 127049, 0, 65625, - 9714, 11692, 0, 0, 120850, 6478, 10195, 43673, 65237, 6241, 0, 0, 0, - 6238, 0, 129889, 0, 4409, 0, 0, 67170, 0, 0, 0, 94047, 6237, 5461, 66851, - 9176, 92882, 121341, 65231, 0, 0, 121182, 110581, 0, 44018, 0, 64765, 0, - 0, 0, 5685, 0, 2461, 0, 7091, 0, 0, 0, 68163, 0, 73030, 0, 0, 73928, 0, - 0, 0, 0, 0, 0, 110582, 0, 0, 68506, 0, 0, 0, 0, 0, 2542, 0, 0, 0, 128176, - 5776, 0, 0, 0, 0, 0, 11987, 0, 0, 75036, 68744, 0, 0, 10039, 42828, 0, 0, - 0, 0, 0, 10721, 67664, 43433, 0, 0, 41875, 0, 41870, 266, 129066, 0, - 41873, 71271, 0, 0, 0, 0, 0, 0, 41871, 66186, 3734, 7734, 43683, 8750, - 110600, 66011, 92899, 0, 127937, 0, 0, 10572, 0, 42906, 0, 64349, 7287, - 0, 0, 0, 0, 11167, 69220, 0, 43429, 0, 1697, 0, 0, 68633, 7286, 0, - 128738, 10031, 78754, 0, 68645, 8620, 0, 42162, 0, 0, 7285, 0, 119577, 0, - 66842, 43677, 41583, 0, 65799, 129332, 0, 0, 0, 0, 110806, 0, 3609, 0, - 129448, 119074, 125116, 126254, 128108, 73948, 0, 0, 0, 0, 129189, 42732, - 92699, 74984, 68620, 11691, 74985, 0, 0, 0, 0, 0, 6348, 243, 74075, 0, 0, - 92309, 123585, 0, 0, 10648, 8538, 43687, 0, 118723, 0, 70515, 0, 118954, - 92886, 13307, 129573, 92891, 0, 120770, 983850, 0, 0, 0, 0, 214, 0, 0, 0, - 65893, 0, 120488, 128386, 0, 92893, 0, 2603, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 43, 0, 0, 1016, 0, 0, 0, 3885, 92, 65456, 64608, 0, 0, 0, 70656, - 113742, 0, 0, 0, 128128, 983857, 0, 0, 6791, 983861, 127960, 0, 0, 0, - 118976, 0, 7328, 92358, 0, 7995, 8759, 43421, 0, 68029, 92860, 0, 125272, - 0, 3197, 0, 0, 0, 983150, 0, 11595, 0, 0, 43435, 0, 0, 0, 0, 0, 70660, 0, - 741, 83291, 5494, 0, 70668, 1990, 11107, 4498, 0, 0, 70658, 0, 0, 2960, - 73779, 0, 8969, 101256, 43424, 0, 101257, 2950, 101251, 101254, 101253, - 370, 0, 101250, 101249, 0, 0, 0, 0, 0, 0, 0, 122900, 0, 0, 983253, 0, - 2964, 43663, 0, 6344, 0, 0, 10144, 0, 8252, 729, 66016, 78446, 0, 0, 0, - 78740, 43669, 9032, 0, 0, 0, 0, 0, 0, 0, 0, 74612, 3761, 101261, 101260, - 101263, 101262, 0, 0, 3850, 101258, 0, 128389, 0, 0, 0, 0, 8611, 0, 0, 0, - 43691, 125032, 0, 41802, 120540, 0, 0, 0, 0, 0, 3848, 101230, 113800, - 127536, 101227, 101226, 101229, 101228, 663, 0, 0, 0, 0, 0, 0, 0, 0, - 13221, 0, 0, 101244, 101243, 101246, 101245, 0, 65579, 12980, 68046, - 12143, 101069, 128067, 0, 43441, 41804, 101241, 101240, 101235, 101234, - 101237, 101236, 66329, 0, 72324, 101232, 0, 125038, 0, 129383, 101214, - 101213, 0, 101215, 101210, 0, 101212, 101211, 0, 1097, 129033, 0, 101209, - 101208, 93828, 0, 101205, 101204, 101207, 101206, 101201, 101200, 101203, - 101202, 0, 13110, 0, 983886, 68229, 1000, 0, 0, 101222, 1209, 101224, - 101223, 92354, 1073, 6321, 77878, 92818, 0, 68213, 0, 12167, 0, 0, 0, 0, - 73673, 121500, 0, 121501, 0, 6587, 0, 0, 0, 9231, 0, 2959, 101191, 0, - 101193, 101188, 101187, 101190, 101189, 101184, 0, 101186, 42941, 0, 0, - 68434, 0, 70742, 0, 0, 12290, 0, 0, 110801, 0, 77873, 8205, 110803, 5131, - 118542, 0, 0, 0, 0, 0, 1944, 78453, 0, 0, 119990, 119991, 12701, 78492, - 11308, 119995, 0, 113702, 66836, 119999, 74263, 92382, 120002, 120003, - 7075, 101196, 101199, 101198, 41817, 73934, 42275, 101194, 120012, - 120013, 120014, 42943, 6041, 0, 41899, 0, 8002, 0, 41902, 0, 0, 64332, 0, - 7813, 119117, 0, 41900, 120633, 101167, 7281, 78455, 7279, 12041, 93027, - 101165, 12673, 0, 129123, 9660, 0, 72984, 101161, 0, 0, 0, 92901, 2970, - 0, 101180, 101179, 77870, 101181, 0, 0, 101178, 0, 0, 0, 0, 0, 3486, - 101174, 69498, 101176, 101171, 101170, 101173, 101172, 0, 69920, 101169, - 66834, 0, 984006, 0, 68312, 101150, 65673, 1019, 78495, 4148, 0, 12289, - 101147, 4316, 0, 13119, 983932, 101145, 101144, 0, 0, 101141, 101140, - 43434, 41865, 101137, 9163, 8659, 9072, 5867, 13302, 7622, 7120, 0, 0, 0, - 0, 7400, 5416, 101160, 101159, 10817, 101153, 101156, 101155, 0, 68162, - 41855, 41867, 0, 983225, 0, 11536, 71988, 0, 7115, 0, 0, 5498, 7337, + 0, 0, 983474, 0, 92766, 0, 121114, 983944, 74212, 42819, 10910, 118627, + 68044, 9896, 0, 0, 120915, 0, 0, 7970, 0, 0, 0, 0, 113699, 9849, 0, + 122910, 0, 0, 10487, 69714, 0, 10103, 0, 4769, 0, 129967, 0, 2283, 0, 0, + 74785, 0, 0, 0, 110595, 110596, 0, 110594, 64565, 4773, 0, 0, 0, 4770, 0, + 0, 0, 65457, 69441, 0, 0, 127338, 983593, 4774, 0, 68497, 2259, 0, 0, + 10215, 0, 0, 0, 0, 0, 74776, 92160, 4768, 0, 0, 4099, 0, 110699, 110700, + 110697, 2225, 0, 0, 0, 41183, 125217, 11255, 42814, 880, 0, 0, 0, 0, 0, + 67756, 65246, 0, 0, 129463, 7095, 0, 0, 0, 0, 0, 0, 2427, 0, 7093, 0, + 11585, 0, 9962, 0, 12223, 0, 78211, 1434, 42939, 0, 11573, 0, 0, 0, + 121257, 0, 0, 0, 0, 74437, 0, 113711, 917596, 0, 8740, 0, 3782, 64331, 0, + 65167, 1014, 0, 0, 0, 10835, 129987, 0, 0, 0, 0, 0, 118824, 7302, 0, + 67707, 0, 1150, 10547, 0, 0, 68427, 0, 0, 0, 0, 118788, 0, 0, 0, 42257, + 8010, 0, 0, 0, 9643, 0, 0, 12864, 0, 0, 0, 0, 0, 0, 0, 0, 1426, 68217, 0, + 68447, 129971, 0, 0, 0, 73701, 0, 0, 0, 65383, 0, 0, 0, 0, 0, 0, 43196, + 43194, 92549, 10744, 0, 990, 93772, 0, 0, 0, 0, 0, 66470, 0, 0, 0, 3945, + 0, 0, 0, 130039, 0, 127546, 127746, 1020, 73763, 92257, 118669, 0, 64748, + 0, 0, 10205, 0, 0, 10016, 0, 74051, 0, 43242, 125096, 2667, 0, 125037, 0, + 9911, 0, 0, 10097, 0, 0, 0, 118836, 0, 0, 0, 0, 68889, 10159, 113759, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 983343, 92291, 0, 127973, 72882, 0, 1041, 127182, + 6354, 0, 65364, 0, 0, 0, 72884, 0, 128477, 0, 65906, 127819, 72883, 0, + 128470, 5375, 72881, 0, 8215, 0, 10074, 0, 0, 0, 69899, 0, 0, 121426, + 41382, 0, 0, 5173, 65348, 527, 0, 0, 0, 128250, 0, 0, 0, 0, 0, 0, 42695, + 0, 42250, 0, 11187, 113695, 0, 1568, 66806, 0, 0, 113705, 0, 0, 129487, + 0, 0, 128839, 9069, 6144, 0, 0, 0, 0, 66783, 0, 74027, 118934, 66787, + 74580, 0, 110790, 6364, 0, 66794, 43508, 0, 92612, 0, 0, 0, 0, 128405, + 66449, 0, 0, 0, 0, 70714, 0, 70716, 0, 1044, 42411, 0, 0, 0, 0, 43239, 0, + 0, 0, 118572, 42450, 0, 0, 68479, 119237, 0, 0, 0, 0, 0, 69956, 11537, 0, + 121206, 0, 0, 0, 0, 1057, 566, 0, 0, 10907, 42274, 43464, 0, 118698, 0, + 78472, 71207, 42636, 0, 123603, 0, 0, 121171, 64659, 0, 127749, 0, 6357, + 6362, 0, 0, 2216, 9090, 0, 0, 0, 0, 68227, 0, 0, 0, 0, 1053, 12830, 0, 0, + 0, 1052, 1051, 459, 1060, 0, 66479, 0, 0, 0, 128061, 42490, 689, 6508, + 4163, 42298, 8639, 983338, 4246, 0, 43514, 42362, 0, 42337, 64596, 0, 0, + 0, 0, 0, 6359, 0, 43471, 0, 0, 0, 127274, 0, 6358, 6361, 1926, 6356, 0, + 7898, 0, 10935, 0, 127972, 121285, 0, 43685, 0, 0, 42910, 0, 8693, 0, 0, + 44010, 0, 120991, 121454, 0, 0, 0, 0, 129514, 0, 0, 0, 0, 73947, 0, + 129361, 92412, 0, 66477, 0, 0, 0, 43854, 71913, 0, 0, 0, 0, 72227, 65899, + 92275, 0, 0, 0, 68887, 0, 71057, 0, 0, 0, 0, 119183, 2923, 10853, 0, 0, + 0, 0, 72864, 0, 72773, 72772, 0, 120801, 65251, 122624, 68228, 0, 128548, + 0, 0, 5370, 70465, 2931, 73848, 0, 10188, 0, 118848, 0, 983942, 0, 0, + 120584, 72212, 0, 10844, 121016, 128195, 92424, 0, 0, 0, 286, 0, 1062, 0, + 0, 124127, 7395, 0, 1070, 128993, 0, 6095, 0, 0, 0, 127796, 126465, + 64497, 0, 0, 0, 0, 70054, 8189, 78272, 0, 0, 0, 0, 0, 113783, 42102, + 78276, 0, 0, 42101, 0, 78402, 67427, 33, 67425, 67424, 10824, 67430, + 67429, 67428, 427, 64723, 0, 0, 0, 0, 1031, 0, 0, 42104, 0, 0, 2328, 0, + 1071, 42899, 128486, 0, 7673, 0, 0, 1047, 194837, 0, 42908, 0, 0, 10651, + 0, 0, 0, 72433, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13216, 0, 69716, 0, + 0, 0, 0, 0, 92411, 69654, 0, 0, 129904, 2761, 129909, 0, 0, 0, 0, 8643, + 0, 0, 94021, 2757, 11067, 0, 74498, 8910, 10689, 0, 0, 0, 71173, 0, 9196, + 71214, 0, 0, 0, 0, 118911, 0, 0, 0, 0, 0, 0, 0, 0, 68130, 119616, 0, 0, + 42477, 67482, 0, 4495, 0, 0, 0, 0, 70080, 10992, 0, 0, 0, 0, 9318, 0, + 6002, 0, 73808, 0, 92601, 42249, 7639, 43995, 0, 0, 5454, 0, 0, 0, 0, 0, + 0, 0, 121189, 0, 119173, 0, 9704, 120686, 0, 78436, 78435, 11204, 0, 0, + 1731, 0, 92937, 0, 67990, 0, 0, 0, 126576, 127018, 71951, 55265, 0, 0, 0, + 0, 127257, 73826, 0, 3840, 0, 41432, 0, 0, 68430, 0, 43253, 128284, 0, + 3371, 92936, 0, 0, 1479, 69282, 0, 1109, 77997, 0, 129154, 0, 92782, 0, + 0, 8868, 399, 67978, 74842, 0, 0, 194839, 73498, 551, 0, 10156, 0, 92572, + 0, 2544, 65074, 0, 0, 0, 0, 0, 0, 0, 128713, 0, 0, 74268, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 68045, 0, 0, 0, 3447, 0, 0, 121414, 2549, 110818, 0, 0, + 43564, 8946, 0, 74411, 66864, 0, 70480, 7980, 0, 113698, 0, 119653, + 66489, 0, 64695, 128063, 0, 0, 0, 0, 0, 0, 43452, 0, 92993, 0, 10919, 0, + 67810, 0, 0, 0, 0, 6450, 10055, 0, 0, 0, 0, 42720, 0, 9626, 0, 128055, + 74447, 0, 125127, 92573, 0, 0, 0, 119075, 0, 0, 66486, 0, 0, 0, 0, 0, 0, + 75028, 983883, 74839, 0, 0, 0, 0, 0, 55286, 0, 1055, 917628, 0, 0, 0, + 70516, 12146, 118623, 73956, 66488, 0, 0, 0, 0, 0, 0, 42518, 0, 0, 0, + 7407, 74978, 0, 0, 0, 0, 0, 0, 0, 10231, 0, 66626, 0, 0, 92951, 0, 65927, + 0, 0, 69696, 0, 92389, 0, 0, 0, 68095, 92950, 0, 10555, 0, 0, 9091, + 10798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43222, 0, 74982, 0, 0, 120952, 0, 0, + 2992, 7826, 74321, 110879, 125103, 74981, 92628, 0, 129903, 128289, + 128203, 4361, 129597, 1306, 78770, 1497, 983628, 0, 0, 0, 8248, 0, + 127253, 7973, 128706, 0, 0, 73122, 983949, 0, 0, 2963, 120653, 0, 128554, + 0, 0, 64258, 0, 0, 69677, 74983, 65103, 0, 125008, 42625, 0, 72022, 0, 0, + 64905, 0, 9512, 0, 119076, 6443, 983267, 0, 9135, 0, 0, 123202, 0, 0, + 983882, 93788, 0, 0, 0, 93767, 64256, 0, 11669, 0, 0, 4524, 0, 129182, + 128390, 0, 74266, 0, 0, 0, 70119, 78410, 69809, 121031, 55219, 69815, + 93765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2986, 0, 93763, 3437, 0, 6203, + 4247, 0, 11920, 8274, 68240, 129694, 1657, 0, 121276, 122951, 0, 2954, + 43506, 42837, 0, 0, 71179, 0, 0, 0, 66476, 68450, 0, 0, 0, 43362, 983135, + 129596, 11705, 0, 0, 0, 127354, 0, 11710, 0, 0, 0, 119507, 74429, 0, 0, + 1058, 129555, 0, 0, 5484, 1144, 0, 0, 0, 0, 0, 118972, 0, 65322, 0, 6441, + 0, 0, 2547, 66484, 43634, 0, 5871, 0, 0, 0, 0, 0, 0, 71204, 0, 0, 1865, + 0, 0, 69950, 0, 93021, 73713, 0, 71199, 65826, 2069, 0, 119092, 43999, + 2997, 0, 126588, 0, 65319, 0, 12316, 0, 0, 123630, 8776, 0, 0, 66294, + 13130, 0, 71191, 126625, 0, 10030, 11709, 12364, 983853, 0, 11704, 0, + 118641, 68672, 0, 0, 0, 0, 11706, 9710, 0, 82985, 0, 413, 65623, 0, 0, + 93980, 74446, 0, 1042, 0, 128378, 12171, 119240, 0, 69384, 4984, 0, 708, + 11391, 0, 0, 0, 983930, 1308, 0, 3673, 810, 0, 120933, 118567, 0, 0, + 1917, 3000, 0, 0, 0, 65628, 66387, 74470, 0, 0, 0, 10027, 0, 0, 0, 0, + 128831, 983168, 2980, 755, 0, 0, 65622, 0, 121012, 7277, 121022, 0, 0, 0, + 0, 8730, 0, 0, 0, 7274, 119250, 0, 7275, 0, 935, 0, 0, 377, 42325, + 121103, 0, 101133, 101132, 101135, 101134, 0, 74911, 2417, 101130, 0, + 19912, 0, 0, 101128, 101127, 0, 101129, 101124, 7248, 101126, 101125, + 1781, 5496, 3627, 62, 1649, 0, 964, 0, 0, 0, 0, 92897, 0, 0, 127364, 0, + 43689, 127911, 66287, 78812, 64389, 66575, 0, 73041, 0, 129687, 0, 7677, + 2991, 3293, 0, 0, 0, 72201, 0, 11341, 127049, 0, 65625, 9714, 11692, 0, + 0, 120850, 6478, 10195, 43673, 65237, 6241, 0, 0, 0, 6238, 0, 129889, 0, + 4409, 0, 0, 67170, 0, 0, 0, 94047, 6237, 5461, 66851, 9176, 92882, + 121341, 65231, 0, 0, 121182, 110581, 0, 44018, 0, 64765, 0, 0, 0, 5685, + 0, 2461, 0, 7091, 0, 0, 0, 68163, 0, 73030, 0, 0, 73928, 0, 0, 0, 0, 0, + 0, 110582, 0, 0, 68506, 0, 0, 0, 0, 0, 2542, 0, 0, 0, 128176, 5776, 0, 0, + 0, 0, 0, 11987, 0, 0, 75036, 68744, 0, 0, 10039, 42828, 0, 0, 0, 0, 0, + 10721, 67664, 43433, 0, 0, 41875, 0, 41870, 266, 129066, 0, 41873, 71271, + 0, 0, 0, 0, 0, 0, 41871, 66186, 3734, 7734, 43683, 8750, 110600, 66011, + 92899, 0, 127937, 0, 0, 10572, 0, 42906, 0, 64349, 7287, 0, 0, 0, 0, + 11167, 69220, 0, 43429, 0, 1697, 0, 0, 68633, 7286, 0, 128738, 10031, + 78754, 0, 68645, 8620, 0, 42162, 0, 0, 7285, 0, 119577, 0, 66842, 43677, + 41583, 0, 65799, 129332, 0, 0, 0, 0, 110806, 0, 3609, 0, 129448, 119074, + 125116, 126254, 128108, 73948, 0, 0, 0, 0, 129189, 42732, 92699, 74984, + 68620, 11691, 74985, 0, 0, 0, 0, 0, 6348, 243, 74075, 0, 0, 92309, + 123585, 0, 0, 10648, 8538, 43687, 0, 118723, 0, 70515, 0, 118954, 92886, + 13307, 129573, 92891, 0, 120770, 983850, 0, 0, 0, 0, 214, 0, 0, 0, 65893, + 0, 120488, 128386, 0, 92893, 0, 2603, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 0, 0, 1016, 0, 0, 0, 3885, 92, 65456, 64608, 0, 0, 0, 70656, 113742, + 0, 0, 0, 128128, 983857, 0, 0, 6791, 983861, 127960, 0, 0, 0, 118976, 0, + 7328, 92358, 0, 7995, 8759, 43421, 0, 68029, 92860, 0, 125272, 0, 3197, + 0, 0, 0, 983151, 0, 11595, 0, 0, 43435, 0, 0, 0, 0, 0, 70660, 0, 741, + 83291, 5494, 0, 70668, 1990, 11107, 4498, 0, 0, 70658, 0, 0, 2960, 73779, + 0, 8969, 101256, 43424, 0, 101257, 2950, 101251, 101254, 101253, 370, 0, + 101250, 101249, 0, 0, 0, 122967, 0, 0, 0, 122900, 0, 0, 983256, 0, 2964, + 43663, 0, 6344, 0, 0, 10144, 0, 8252, 729, 66016, 78446, 0, 0, 0, 78740, + 43669, 9032, 0, 0, 0, 0, 0, 0, 0, 0, 74612, 3761, 101261, 101260, 101263, + 101262, 0, 0, 3850, 101258, 0, 128389, 0, 0, 0, 0, 8611, 0, 0, 0, 43691, + 125032, 0, 41802, 120540, 0, 0, 0, 0, 0, 3848, 101230, 113800, 127536, + 101227, 101226, 101229, 101228, 663, 0, 0, 0, 0, 0, 0, 0, 0, 13221, 0, 0, + 101244, 101243, 101246, 101245, 0, 65579, 12980, 68046, 12143, 101069, + 128067, 0, 43441, 41804, 101241, 101240, 101235, 101234, 101237, 101236, + 66329, 0, 72324, 101232, 0, 125038, 0, 129383, 101214, 101213, 0, 101215, + 101210, 0, 101212, 101211, 0, 1097, 129033, 0, 101209, 101208, 93828, 0, + 101205, 101204, 101207, 101206, 101201, 101200, 101203, 101202, 0, 13110, + 0, 983886, 68229, 1000, 0, 0, 101222, 1209, 101224, 101223, 92354, 1073, + 6321, 77878, 92818, 0, 68213, 0, 12167, 0, 0, 0, 0, 73673, 121500, 0, + 121501, 0, 6587, 0, 0, 0, 9231, 0, 2959, 101191, 0, 101193, 101188, + 101187, 101190, 101189, 101184, 0, 101186, 42941, 0, 0, 68434, 0, 70742, + 0, 0, 12290, 0, 0, 110801, 0, 77873, 8205, 110803, 5131, 118542, 0, 0, 0, + 0, 0, 1944, 78453, 0, 0, 119990, 119991, 12701, 78492, 11308, 119995, 0, + 113702, 66836, 119999, 74263, 92382, 120002, 120003, 7075, 101196, + 101199, 101198, 41817, 73934, 42275, 101194, 120012, 120013, 120014, + 42943, 6041, 0, 41899, 0, 8002, 0, 41902, 0, 0, 64332, 0, 7813, 119117, + 0, 41900, 120633, 101167, 7281, 78455, 7279, 12041, 93027, 101165, 12673, + 0, 129123, 9660, 0, 72984, 101161, 0, 0, 0, 92901, 2970, 0, 101180, + 101179, 77870, 101181, 0, 0, 101178, 0, 0, 0, 0, 0, 3486, 101174, 69498, + 101176, 101171, 101170, 101173, 101172, 0, 69920, 101169, 66834, 0, + 984006, 0, 68312, 101150, 65673, 1019, 78495, 4148, 0, 12289, 101147, + 4316, 0, 13119, 983932, 101145, 101144, 0, 0, 101141, 101140, 43434, + 41865, 101137, 9163, 8659, 9072, 5867, 13302, 7622, 7120, 0, 0, 0, 0, + 7400, 5416, 101160, 101159, 10817, 101153, 101156, 101155, 0, 68162, + 41855, 41867, 0, 983228, 0, 11536, 71988, 0, 7115, 0, 0, 5498, 7337, 41536, 0, 0, 92587, 7221, 8997, 0, 0, 0, 71949, 0, 0, 127814, 0, 0, 0, 0, 0, 295, 0, 0, 0, 0, 121292, 0, 43454, 63903, 63902, 63901, 122644, 3971, 0, 0, 2952, 0, 11038, 10901, 63900, 63899, 63898, 5198, 667, 43273, @@ -26393,7 +26575,7 @@ static const unsigned int code_hash[] = { 63932, 75050, 63929, 63928, 63927, 77934, 9806, 65566, 77933, 63922, 63921, 2086, 0, 63926, 2984, 5968, 63923, 0, 0, 129458, 11137, 13169, 5290, 2089, 0, 63827, 1088, 63825, 7268, 1084, 1085, 63829, 1083, 10131, - 7283, 0, 0, 0, 1092, 0, 7273, 983274, 44016, 43627, 0, 0, 0, 11809, 0, 0, + 7283, 0, 0, 0, 1092, 0, 7273, 983277, 44016, 43627, 0, 0, 0, 11809, 0, 0, 0, 2965, 7258, 8808, 0, 1089, 7278, 63937, 63936, 43405, 11106, 940, 5787, 10099, 63938, 101269, 63897, 101271, 2994, 101265, 101264, 101267, 101266, 77939, 77940, 77937, 77938, 74343, 93043, 72704, 660, 10127, 666, @@ -26419,36 +26601,36 @@ static const unsigned int code_hash[] = { 128100, 0, 42612, 43655, 0, 0, 0, 66468, 0, 0, 68623, 101423, 0, 0, 101420, 101419, 101422, 101421, 0, 1151, 101418, 73709, 127544, 0, 71106, 118722, 0, 0, 0, 0, 101437, 101436, 11527, 101438, 0, 0, 11538, 101434, - 0, 11020, 0, 66467, 101432, 8087, 71700, 101433, 9894, 101427, 101430, + 0, 11020, 0, 66467, 101432, 8087, 71700, 101433, 9894, 101427, 73485, 70824, 101424, 0, 78513, 8053, 0, 0, 0, 0, 101407, 101406, 0, 63845, - 101403, 101402, 78602, 101404, 13084, 42966, 8741, 0, 0, 101401, 0, - 64605, 83051, 101397, 473, 43415, 101394, 101393, 101396, 1087, 124966, - 71275, 101392, 0, 66439, 43218, 0, 0, 7237, 101414, 101417, 101416, - 71996, 101410, 92261, 101412, 121036, 4384, 74220, 101408, 2058, 917561, - 0, 129462, 0, 0, 0, 3857, 0, 0, 0, 64630, 0, 0, 74168, 127113, 125088, - 4421, 0, 0, 101381, 66400, 101383, 68431, 101377, 101376, 101379, 83053, - 0, 0, 69640, 127861, 0, 437, 0, 0, 0, 0, 65236, 13290, 119180, 4997, - 64306, 0, 0, 4999, 0, 0, 0, 4711, 120769, 0, 2739, 0, 92915, 74834, 0, - 127175, 0, 0, 0, 0, 0, 1779, 6600, 6601, 0, 5325, 101390, 101389, 13058, - 101391, 101386, 0, 92186, 101387, 71845, 10575, 43399, 0, 101385, 101384, - 1104, 0, 0, 10655, 0, 0, 69497, 0, 1082, 110878, 0, 67401, 0, 0, 0, 0, - 6783, 0, 0, 42867, 69655, 44021, 6458, 0, 0, 0, 0, 0, 0, 1273, 43407, 0, - 0, 0, 0, 1313, 6322, 41720, 128627, 66433, 0, 0, 0, 11216, 0, 0, 0, - 43437, 93833, 0, 0, 0, 5122, 0, 72728, 129520, 70161, 0, 0, 0, 0, 0, - 8303, 0, 128926, 0, 10003, 0, 0, 0, 1686, 0, 0, 42834, 3664, 0, 126088, - 121346, 0, 0, 4324, 126, 0, 0, 0, 0, 0, 65166, 0, 0, 0, 0, 43817, 0, - 43822, 0, 0, 65600, 13002, 0, 0, 0, 1103, 0, 119575, 129452, 0, 13078, 0, - 8116, 0, 2050, 0, 0, 1102, 0, 6555, 0, 0, 74003, 74794, 0, 0, 42591, - 127278, 0, 1111, 0, 75047, 4707, 0, 0, 0, 0, 43468, 4522, 8645, 0, 74857, - 0, 11352, 0, 92787, 0, 2293, 0, 0, 0, 128265, 71709, 0, 121194, 0, 93827, - 0, 0, 0, 128488, 0, 160, 2677, 0, 0, 120141, 0, 983646, 70790, 0, 42770, - 0, 71986, 0, 43821, 113769, 0, 0, 43816, 0, 0, 1079, 3867, 64817, 0, - 118549, 0, 0, 64768, 0, 0, 4005, 983211, 0, 10991, 0, 92957, 917578, - 92850, 917580, 917575, 128314, 917577, 917576, 917571, 78534, 917573, - 917572, 0, 0, 128359, 73458, 0, 3339, 11448, 1106, 917591, 917590, - 917593, 3340, 917587, 917586, 917589, 917588, 917583, 10605, 1309, 74996, - 120743, 92650, 0, 0, 9485, 0, 129781, 0, 0, 0, 125002, 92533, 128487, 0, - 129285, 4338, 11238, 0, 66825, 0, 0, 0, 0, 0, 0, 74128, 0, 0, 73680, 0, + 101403, 78912, 78602, 101404, 13084, 42966, 8741, 0, 0, 101401, 0, 64605, + 83051, 101397, 473, 43415, 101394, 101393, 101396, 1087, 124966, 71275, + 101392, 0, 66439, 43218, 0, 0, 7237, 101414, 101417, 101416, 71996, + 101410, 92261, 101412, 121036, 4384, 74220, 101408, 2058, 917561, 0, + 129462, 0, 0, 0, 3857, 0, 0, 0, 64630, 0, 0, 74168, 127113, 125088, 4421, + 0, 0, 101381, 66400, 101383, 68431, 101377, 101376, 101379, 83053, 0, 0, + 69640, 127861, 0, 437, 73483, 0, 0, 0, 65236, 13290, 119180, 4997, 64306, + 0, 0, 4999, 0, 0, 0, 4711, 120769, 0, 2739, 0, 92915, 74834, 0, 127175, + 0, 0, 0, 0, 0, 1779, 6600, 6601, 0, 5325, 101390, 101389, 13058, 101391, + 101386, 0, 92186, 101387, 71845, 10575, 43399, 0, 101385, 101384, 1104, + 0, 0, 10655, 0, 0, 69497, 0, 1082, 110878, 0, 67401, 0, 0, 0, 0, 6783, 0, + 0, 42867, 69655, 44021, 6458, 0, 0, 0, 0, 0, 0, 1273, 43407, 0, 0, 0, 0, + 1313, 6322, 41720, 128627, 66433, 0, 0, 0, 11216, 0, 0, 0, 43437, 93833, + 0, 0, 0, 5122, 0, 72728, 129520, 70161, 0, 0, 0, 0, 0, 8303, 0, 128926, + 0, 10003, 0, 0, 0, 1686, 0, 0, 42834, 3664, 0, 126088, 121346, 0, 0, + 4324, 126, 0, 0, 0, 0, 0, 65166, 0, 0, 0, 0, 43817, 0, 43822, 0, 0, + 65600, 13002, 0, 0, 0, 1103, 0, 119575, 129452, 0, 13078, 0, 8116, 0, + 2050, 0, 0, 1102, 0, 6555, 0, 0, 74003, 74794, 0, 0, 42591, 127278, 0, + 1111, 0, 75047, 4707, 0, 0, 0, 0, 43468, 4522, 8645, 0, 74857, 0, 11352, + 0, 92787, 0, 2293, 0, 0, 0, 128265, 71709, 0, 121194, 0, 93827, 0, 0, 0, + 128488, 0, 160, 2677, 0, 0, 120141, 0, 983646, 70790, 0, 42770, 0, 71986, + 0, 43821, 113769, 0, 0, 43816, 0, 0, 1079, 3867, 64817, 0, 118549, 0, 0, + 64768, 0, 0, 4005, 983213, 0, 10991, 0, 92957, 917578, 92850, 917580, + 917575, 128314, 917577, 917576, 917571, 78534, 917573, 917572, 0, 0, + 128359, 73458, 0, 3339, 11448, 1106, 917591, 917590, 129192, 3340, + 917587, 917586, 917589, 917588, 917583, 10605, 1309, 74996, 120743, + 92650, 0, 0, 9485, 0, 129781, 0, 0, 0, 125002, 92533, 128487, 0, 129285, + 4338, 11238, 0, 66825, 0, 0, 0, 0, 122939, 0, 74128, 0, 0, 73680, 0, 129438, 9553, 1590, 63777, 63776, 128677, 63782, 63781, 63780, 63779, 1583, 101525, 101528, 101527, 101522, 101521, 101524, 101523, 41522, 0, 92168, 983803, 66759, 0, 983580, 0, 0, 0, 0, 11394, 0, 983071, 0, 66823, @@ -26463,14 +26645,14 @@ static const unsigned int code_hash[] = { 121136, 0, 7950, 63772, 63771, 63770, 0, 63767, 63766, 2793, 63764, 0, 128501, 63769, 9530, 0, 92398, 0, 128642, 63763, 63762, 4595, 63760, 792, 92808, 0, 0, 8742, 0, 0, 0, 63744, 0, 0, 120815, 63748, 63747, 63746, - 63745, 5055, 0, 0, 1090, 0, 125268, 11665, 92830, 4558, 0, 72211, 0, 0, - 0, 11513, 983978, 6157, 63775, 63774, 63773, 0, 12170, 9067, 92843, 0, + 63745, 5055, 0, 0, 1090, 0, 125268, 11665, 92830, 4558, 78919, 72211, 0, + 0, 0, 11513, 983978, 6157, 63775, 63774, 63773, 0, 12170, 9067, 92843, 0, 10872, 129643, 43891, 43893, 43892, 129747, 43933, 0, 128231, 0, 0, 0, 0, - 0, 11063, 0, 43888, 0, 0, 128368, 43889, 0, 73807, 983104, 7386, 0, 0, + 0, 11063, 0, 43888, 0, 0, 128368, 43889, 0, 73807, 983105, 7386, 0, 0, 70295, 0, 0, 0, 71201, 128460, 0, 0, 0, 0, 69915, 2918, 66820, 65300, 0, 124898, 64726, 2790, 0, 3793, 42065, 127829, 0, 124901, 0, 0, 0, 0, 0, 92712, 0, 12923, 5270, 2166, 0, 0, 65813, 0, 128499, 0, 75012, 0, 10888, - 0, 93997, 94180, 3330, 129417, 0, 0, 0, 0, 0, 8220, 0, 0, 101581, 101580, + 0, 93997, 94180, 3330, 129417, 0, 0, 0, 0, 0, 8220, 0, 0, 101581, 72457, 1627, 101582, 0, 0, 5371, 101578, 0, 1826, 118794, 0, 0, 70023, 0, 0, 0, 71108, 0, 0, 124907, 0, 92207, 68125, 74898, 71353, 0, 72006, 71098, 70029, 0, 43116, 10190, 70019, 64346, 0, 101585, 66818, 101587, 70031, 0, @@ -26485,37 +26667,37 @@ static const unsigned int code_hash[] = { 5788, 127852, 0, 65491, 1831, 66020, 0, 984012, 92588, 0, 1343, 120784, 0, 0, 12018, 0, 0, 0, 0, 0, 4422, 4708, 3799, 101550, 119357, 0, 101547, 101546, 101549, 101548, 983095, 0, 1364, 0, 8038, 101545, 0, 12868, - 129560, 70425, 55223, 0, 64414, 110689, 0, 0, 0, 0, 0, 0, 118802, 118644, - 42855, 118856, 42866, 0, 0, 0, 0, 66438, 0, 983996, 119356, 92853, - 119354, 0, 123556, 0, 73013, 67685, 128062, 119350, 0, 11864, 10404, - 10340, 119352, 1556, 5274, 0, 127821, 10017, 9733, 0, 69488, 0, 41373, 0, - 0, 0, 0, 0, 349, 4863, 41371, 0, 0, 0, 0, 72295, 4398, 8543, 65618, - 128018, 0, 0, 0, 0, 12441, 0, 119348, 119347, 4318, 10452, 0, 8032, 0, - 119349, 119344, 0, 127844, 121156, 0, 110729, 119345, 8597, 0, 110727, - 9864, 0, 92796, 0, 92799, 0, 0, 0, 7722, 0, 0, 92797, 0, 0, 66590, 0, 0, - 129850, 0, 0, 0, 4965, 0, 917536, 0, 123196, 0, 0, 0, 10436, 119342, - 43147, 119340, 10356, 10420, 982, 2756, 0, 983997, 0, 0, 11162, 119338, - 0, 92914, 0, 65110, 0, 0, 983800, 78543, 0, 118793, 0, 128112, 119179, - 64476, 1694, 8216, 0, 0, 78539, 0, 65620, 0, 78537, 0, 0, 42158, 65621, - 69955, 120324, 120327, 120326, 120321, 120320, 120323, 120322, 12314, - 65616, 55221, 43825, 983553, 119337, 68060, 119335, 0, 71874, 123628, - 128537, 119332, 73089, 0, 41347, 0, 0, 8842, 0, 0, 4379, 127393, 12692, - 0, 0, 66353, 71875, 0, 0, 92907, 0, 0, 71877, 120303, 65619, 9872, 0, 0, - 1846, 120309, 120308, 119256, 71192, 120305, 120304, 120307, 6442, + 129560, 70425, 55223, 0, 64414, 110689, 122978, 0, 0, 0, 0, 0, 118802, + 118644, 42855, 118856, 42866, 73525, 0, 0, 0, 66438, 0, 983996, 119356, + 92853, 119354, 0, 123556, 0, 73013, 67685, 128062, 119350, 0, 11864, + 10404, 10340, 119352, 1556, 5274, 0, 127821, 10017, 9733, 0, 69488, 0, + 41373, 0, 0, 0, 0, 0, 349, 4863, 41371, 0, 0, 0, 0, 72295, 4398, 8543, + 65618, 128018, 129784, 0, 0, 0, 12441, 0, 119348, 119347, 4318, 10452, 0, + 8032, 0, 119349, 119344, 0, 127844, 121156, 0, 110729, 119345, 8597, 0, + 110727, 9864, 0, 92796, 0, 92799, 0, 0, 0, 7722, 0, 0, 92797, 0, 0, + 66590, 0, 0, 129850, 0, 0, 0, 4965, 0, 917536, 0, 123196, 0, 0, 0, 10436, + 119342, 43147, 119340, 10356, 10420, 982, 2756, 0, 983997, 0, 0, 11162, + 119338, 0, 92914, 0, 65110, 0, 0, 983800, 78543, 0, 118793, 0, 128112, + 119179, 64476, 1694, 8216, 0, 0, 78539, 0, 65620, 0, 78537, 0, 0, 42158, + 65621, 69955, 120324, 120327, 120326, 120321, 120320, 120323, 120322, + 12314, 65616, 55221, 43825, 983553, 119337, 68060, 119335, 0, 71874, + 123628, 128537, 119332, 73089, 0, 41347, 0, 0, 8842, 0, 0, 4379, 127393, + 12692, 0, 0, 66353, 71875, 0, 0, 92907, 0, 0, 71877, 120303, 65619, 9872, + 0, 0, 1846, 120309, 120308, 119256, 71192, 120305, 120304, 120307, 6442, 120317, 120316, 5379, 120318, 110717, 120312, 120315, 71876, 0, 65934, 66497, 0, 66986, 0, 0, 0, 0, 0, 0, 0, 0, 72002, 0, 6151, 12110, 0, - 129761, 0, 66959, 0, 0, 0, 0, 68335, 0, 0, 0, 0, 0, 0, 66041, 9676, - 10202, 0, 0, 0, 64575, 126637, 11965, 0, 124936, 0, 0, 0, 0, 0, 9698, + 129761, 0, 66959, 0, 0, 0, 0, 68335, 129655, 0, 0, 0, 0, 0, 66041, 9676, + 10202, 0, 0, 0, 64575, 78929, 11965, 0, 124936, 0, 0, 0, 0, 0, 9698, 66293, 0, 119651, 0, 0, 41921, 0, 0, 0, 119258, 0, 0, 0, 0, 0, 8012, 12355, 12353, 0, 0, 74107, 0, 0, 41925, 0, 41920, 65444, 0, 0, 41923, 12694, 0, 10112, 1294, 0, 120091, 0, 120092, 0, 0, 128474, 121400, 0, 0, 0, 8718, 0, 10284, 10268, 10380, 10316, 92593, 0, 71850, 0, 0, 92889, 0, 0, 0, 0, 9342, 12829, 0, 0, 101239, 127978, 0, 0, 69428, 0, 73767, 72347, 0, 7956, 598, 0, 72329, 93837, 0, 0, 128860, 0, 120041, 0, 0, 101242, 0, - 0, 847, 0, 9529, 0, 0, 0, 101247, 120035, 0, 0, 0, 67411, 0, 0, 0, + 0, 847, 0, 9529, 0, 0, 0, 101247, 120035, 0, 0, 0, 67411, 0, 0, 119497, 120040, 0, 128580, 0, 9624, 0, 0, 0, 65463, 1554, 0, 0, 0, 0, 71879, 0, 0, 0, 121161, 19963, 123566, 0, 72326, 92933, 71887, 10324, 10292, 65546, - 0, 68141, 8372, 0, 0, 83018, 120022, 10175, 10388, 42799, 0, 983180, + 0, 68141, 8372, 0, 0, 83018, 120022, 10175, 10388, 42799, 0, 983181, 10568, 0, 127400, 0, 0, 0, 983762, 0, 4366, 0, 983805, 0, 0, 42608, 0, 9884, 0, 0, 0, 0, 129180, 0, 128964, 0, 0, 1609, 0, 92773, 73448, 0, 11661, 0, 5818, 0, 0, 0, 9540, 0, 2554, 5158, 0, 2213, 0, 0, 78522, @@ -26524,7 +26706,7 @@ static const unsigned int code_hash[] = { 0, 0, 127061, 11005, 0, 66656, 127063, 0, 129936, 0, 127065, 43393, 0, 120643, 0, 0, 0, 0, 120798, 0, 0, 0, 0, 0, 0, 70435, 64356, 0, 0, 0, 383, 7154, 127815, 43495, 128809, 121448, 0, 0, 0, 11286, 0, 0, 0, 0, 0, 0, 0, - 42644, 129824, 129797, 129801, 8292, 0, 4980, 113726, 92674, 70130, 0, 0, + 42644, 73555, 129797, 129801, 8292, 0, 4980, 113726, 92674, 70130, 0, 0, 0, 0, 74912, 0, 10631, 83330, 100488, 68042, 0, 0, 7900, 101252, 0, 78779, 4198, 128555, 0, 0, 0, 123159, 0, 0, 12931, 0, 0, 0, 2088, 0, 72164, 129284, 0, 0, 69265, 0, 0, 0, 69694, 92838, 129794, 8593, 0, 0, 0, @@ -26539,70 +26721,71 @@ static const unsigned int code_hash[] = { 127558, 0, 7539, 0, 0, 0, 0, 0, 0, 0, 92898, 42567, 0, 0, 73886, 0, 129988, 12326, 0, 92848, 0, 0, 11355, 0, 0, 0, 0, 69437, 128222, 129803, 129811, 119537, 72327, 43005, 65342, 118902, 0, 0, 8644, 0, 0, 11186, - 74296, 41909, 0, 128682, 2791, 0, 1891, 0, 0, 41907, 66647, 0, 0, 41906, - 0, 0, 10773, 70206, 0, 0, 0, 6412, 2061, 8520, 13146, 0, 92836, 83275, - 65902, 2882, 0, 126232, 65852, 0, 92795, 0, 123627, 0, 0, 92794, 0, 0, - 128098, 0, 0, 0, 70871, 0, 92792, 0, 120087, 0, 0, 92793, 93971, 0, 3844, - 6842, 0, 0, 6612, 0, 0, 0, 0, 0, 783, 0, 0, 0, 983064, 68032, 119225, 0, - 0, 68378, 4556, 67839, 68480, 78663, 120069, 120074, 67657, 10510, 4382, - 74218, 42194, 0, 92806, 9177, 8902, 93958, 9839, 92804, 120700, 92807, 0, - 63999, 41904, 41917, 9788, 120973, 92805, 1862, 0, 0, 0, 41915, 0, 41919, - 63994, 41914, 7981, 0, 0, 0, 0, 0, 0, 0, 120834, 0, 0, 0, 6784, 78788, 0, - 0, 0, 0, 127534, 127484, 127476, 983874, 0, 983960, 64289, 65289, 0, - 129539, 129575, 64509, 0, 0, 126505, 11051, 0, 66635, 55259, 65885, 0, - 128310, 0, 0, 0, 0, 7500, 4506, 0, 0, 0, 0, 0, 126609, 4040, 128680, - 6167, 0, 42945, 0, 0, 0, 0, 7830, 43036, 0, 0, 63990, 19947, 63988, - 63987, 0, 63993, 10440, 9611, 2244, 71883, 0, 65260, 63986, 11446, 63984, - 92641, 3435, 119652, 0, 119108, 0, 128632, 0, 0, 12748, 0, 0, 92705, 0, - 78790, 0, 0, 63956, 42458, 63954, 63953, 63960, 63959, 63958, 11596, 0, - 11469, 69267, 42306, 2723, 0, 0, 70027, 0, 0, 0, 128093, 2880, 0, 0, 0, - 0, 128506, 3498, 4378, 0, 129825, 0, 65551, 118928, 0, 43387, 0, 64415, - 128898, 0, 0, 0, 0, 8161, 393, 12013, 0, 92216, 126479, 63965, 63964, - 63963, 42345, 0, 2174, 63967, 42498, 0, 2927, 0, 63961, 0, 0, 983946, 0, - 69699, 0, 42340, 0, 0, 0, 10730, 0, 69688, 0, 64187, 118535, 0, 12437, - 9813, 0, 42453, 1604, 9565, 0, 69701, 69235, 42414, 110724, 129196, 0, - 42301, 11372, 0, 917973, 0, 0, 63980, 63979, 63978, 0, 128207, 12017, - 63982, 63981, 73687, 0, 63977, 63976, 72794, 0, 0, 0, 63971, 4347, 4416, - 63968, 11009, 63974, 63973, 402, 69390, 13147, 0, 0, 64646, 13228, 0, 0, - 3515, 74252, 65261, 0, 0, 6259, 0, 0, 0, 0, 0, 0, 74813, 74425, 0, - 126998, 126114, 0, 0, 0, 129933, 983717, 0, 0, 74301, 0, 122633, 0, 0, - 74060, 69508, 0, 66235, 5145, 0, 0, 128394, 0, 73120, 0, 7402, 0, 0, 0, - 7952, 7832, 43382, 66616, 0, 983950, 120852, 0, 127875, 64866, 0, 0, 0, - 78784, 74248, 0, 0, 983196, 0, 0, 0, 78656, 42390, 0, 0, 983940, 0, 0, 0, - 92839, 9508, 0, 9544, 11520, 0, 0, 3377, 0, 129562, 0, 0, 0, 0, 66989, - 66280, 0, 127198, 0, 0, 0, 1955, 119565, 0, 0, 3076, 0, 42168, 73049, - 66304, 0, 0, 8917, 42403, 301, 0, 111175, 0, 0, 0, 0, 0, 0, 67819, 92987, - 0, 0, 0, 983204, 0, 69403, 3182, 0, 0, 0, 0, 0, 42169, 123162, 74244, 0, - 42329, 0, 66326, 6841, 0, 128913, 0, 1219, 3934, 71276, 11483, 74510, - 101122, 121110, 42442, 65470, 69565, 0, 64622, 7759, 42482, 485, 0, 0, - 42290, 0, 0, 42280, 0, 0, 11655, 64379, 127913, 42431, 10126, 42318, 0, - 119631, 74397, 42470, 0, 68315, 0, 110829, 74041, 0, 0, 0, 5411, 0, 0, 0, - 64205, 0, 64206, 42393, 64478, 1310, 125007, 0, 12052, 10643, 55271, - 72727, 0, 121045, 0, 0, 118852, 0, 0, 0, 0, 113826, 0, 0, 64385, 0, 0, 0, - 0, 0, 0, 93848, 92560, 2713, 0, 9650, 0, 0, 120602, 1406, 983650, 78174, - 92659, 0, 68223, 0, 0, 0, 0, 43475, 0, 65287, 1508, 127938, 8779, 10569, - 75034, 0, 0, 0, 0, 0, 0, 0, 70786, 0, 0, 128344, 9185, 0, 42932, 43403, - 0, 0, 0, 0, 0, 0, 0, 0, 12955, 0, 2888, 0, 0, 0, 0, 0, 0, 0, 2878, 0, 0, - 0, 0, 0, 0, 129028, 13203, 129722, 10429, 10365, 0, 0, 127165, 7503, 0, - 113676, 68381, 119658, 0, 8986, 0, 10632, 11934, 11452, 1332, 0, 0, 0, 0, - 73741, 1791, 8850, 9288, 0, 2892, 0, 43394, 555, 0, 0, 0, 0, 64172, - 118899, 0, 0, 0, 0, 8854, 0, 5858, 73101, 10582, 0, 0, 1361, 0, 0, 7905, - 0, 65256, 0, 41210, 0, 0, 71884, 0, 0, 0, 6828, 0, 92302, 0, 1342, 68440, - 0, 64161, 10903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64381, 0, 0, 0, 42245, - 126467, 41972, 0, 0, 0, 9127, 0, 66619, 126489, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 11620, 0, 1149, 68316, 0, 0, 0, 0, 0, 92492, 0, 118784, 0, 0, 0, - 12838, 0, 118819, 0, 0, 0, 0, 41087, 0, 0, 0, 0, 12036, 0, 0, 0, 0, 0, - 64428, 12227, 0, 0, 0, 0, 125248, 120964, 0, 0, 0, 0, 0, 69566, 0, 0, 0, - 0, 0, 1743, 0, 0, 0, 65186, 122626, 0, 0, 0, 0, 64439, 0, 68062, 0, - 111259, 111258, 43866, 0, 111263, 3395, 9362, 111260, 0, 111257, 111256, - 111255, 0, 0, 41091, 3426, 1344, 111249, 111248, 126215, 4735, 11111, - 6119, 111251, 42699, 0, 0, 74818, 1423, 0, 0, 0, 0, 12039, 10559, 0, 0, - 0, 9472, 67734, 11929, 0, 0, 0, 0, 128826, 0, 11579, 0, 0, 128364, 0, - 92185, 0, 0, 1004, 92584, 0, 0, 0, 0, 0, 2556, 0, 0, 72790, 0, 0, 9686, - 0, 0, 0, 70109, 111102, 0, 10718, 13154, 111100, 9139, 0, 0, 0, 0, 0, 0, - 0, 0, 92831, 92810, 41708, 12860, 41703, 0, 42090, 5403, 10352, 73917, + 74296, 41909, 0, 128682, 2791, 127472, 1891, 0, 0, 41907, 66647, 0, 0, + 41906, 0, 129672, 10773, 70206, 0, 0, 0, 6412, 2061, 8520, 13146, 0, + 92836, 83275, 65902, 2882, 0, 126232, 65852, 0, 92795, 0, 123627, 0, 0, + 92794, 0, 0, 128098, 0, 0, 0, 70871, 0, 92792, 0, 120087, 0, 0, 92793, + 93971, 0, 3844, 6842, 0, 0, 6612, 0, 0, 0, 0, 0, 783, 0, 0, 0, 983064, + 68032, 119225, 0, 0, 68378, 4556, 67839, 68480, 78663, 120069, 120074, + 67657, 10510, 4382, 74218, 42194, 0, 92806, 9177, 8902, 93958, 9839, + 92804, 120700, 92807, 0, 63999, 41904, 41917, 9788, 120973, 92805, 1862, + 0, 0, 0, 41915, 0, 41919, 63994, 41914, 7981, 0, 0, 0, 0, 0, 0, 0, + 120834, 0, 0, 0, 6784, 78788, 0, 0, 0, 0, 127534, 127484, 127476, 983874, + 0, 983960, 64289, 65289, 0, 129539, 129575, 64509, 0, 0, 126505, 11051, + 0, 66635, 55259, 65885, 0, 128310, 0, 0, 0, 0, 7500, 4506, 0, 0, 0, 0, 0, + 126609, 4040, 128680, 6167, 0, 42945, 0, 0, 0, 0, 7830, 43036, 0, 0, + 63990, 19947, 63988, 63987, 0, 63993, 10440, 9611, 2244, 71883, 0, 65260, + 63986, 11446, 63984, 92641, 3435, 119652, 0, 119108, 0, 128632, 0, 0, + 12748, 0, 0, 92705, 0, 78790, 0, 0, 63956, 42458, 63954, 63953, 63960, + 63959, 63958, 11596, 0, 11469, 69267, 42306, 2723, 0, 0, 70027, 0, 0, 0, + 128093, 2880, 0, 0, 0, 0, 128506, 3498, 4378, 0, 129825, 0, 65551, + 118928, 0, 43387, 0, 64415, 128898, 0, 0, 0, 0, 8161, 393, 12013, 0, + 92216, 126479, 63965, 63964, 63963, 42345, 0, 2174, 63967, 42498, 0, + 2927, 0, 63961, 0, 0, 983946, 0, 69699, 0, 42340, 0, 0, 0, 10730, 0, + 69688, 0, 64187, 118535, 0, 12437, 9813, 0, 42453, 1604, 9565, 0, 69701, + 69235, 42414, 110724, 129196, 0, 42301, 11372, 0, 917973, 0, 0, 63980, + 63979, 63978, 0, 128207, 12017, 63982, 63981, 73687, 0, 63977, 63976, + 72794, 0, 0, 0, 63971, 4347, 4416, 63968, 11009, 63974, 63973, 402, + 69390, 13147, 0, 0, 64646, 13228, 0, 0, 3515, 74252, 65261, 0, 0, 6259, + 0, 0, 0, 0, 0, 0, 74813, 74425, 0, 126998, 126114, 0, 0, 0, 129933, + 983717, 0, 0, 74301, 0, 122633, 0, 0, 74060, 69508, 0, 66235, 5145, 0, 0, + 128394, 0, 73120, 0, 7402, 0, 0, 0, 7952, 7832, 43382, 66616, 0, 983950, + 120852, 0, 127875, 64866, 0, 0, 0, 78784, 74248, 0, 0, 983197, 0, 0, 0, + 78656, 42390, 0, 0, 983940, 0, 0, 0, 92839, 9508, 0, 9544, 11520, 0, + 110898, 3377, 0, 129562, 0, 0, 0, 0, 66989, 66280, 0, 127198, 0, 0, 0, + 1955, 119565, 0, 0, 3076, 0, 42168, 73049, 66304, 0, 0, 8917, 42403, 301, + 0, 111175, 0, 0, 0, 0, 0, 0, 67819, 92987, 0, 0, 0, 983206, 0, 69403, + 3182, 0, 0, 0, 0, 0, 42169, 123162, 74244, 0, 42329, 0, 66326, 6841, 0, + 128913, 0, 1219, 3934, 71276, 11483, 74510, 101122, 121110, 42442, 65470, + 69565, 0, 64622, 7759, 42482, 485, 0, 0, 42290, 0, 0, 42280, 0, 0, 11655, + 64379, 127913, 42431, 10126, 42318, 0, 119631, 74397, 42470, 0, 68315, 0, + 110829, 74041, 0, 0, 0, 5411, 0, 0, 0, 64205, 0, 64206, 42393, 64478, + 1310, 125007, 0, 12052, 10643, 55271, 72727, 0, 121045, 0, 0, 118852, 0, + 0, 0, 0, 113826, 0, 0, 64385, 0, 0, 0, 0, 0, 0, 93848, 92560, 2713, 0, + 9650, 0, 0, 120602, 1406, 983650, 78174, 92659, 0, 68223, 0, 0, 0, 0, + 43475, 0, 65287, 1508, 127938, 8779, 10569, 75034, 0, 0, 0, 0, 0, 0, 0, + 70786, 0, 0, 128344, 9185, 0, 42932, 43403, 0, 0, 0, 0, 0, 0, 0, 0, + 12955, 0, 2888, 0, 0, 0, 0, 0, 0, 0, 2878, 0, 0, 0, 0, 0, 0, 129028, + 13203, 129722, 10429, 10365, 0, 0, 127165, 7503, 0, 113676, 68381, + 119658, 0, 8986, 0, 10632, 11934, 11452, 1332, 0, 0, 0, 0, 73741, 1791, + 8850, 9288, 0, 2892, 0, 43394, 555, 0, 0, 0, 0, 64172, 118899, 0, 0, 0, + 0, 8854, 0, 5858, 73101, 10582, 0, 0, 1361, 0, 0, 7905, 0, 65256, 0, + 41210, 0, 0, 71884, 0, 0, 0, 6828, 0, 92302, 0, 1342, 68440, 0, 64161, + 10903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64381, 0, 0, 0, 42245, 126467, + 41972, 0, 0, 0, 9127, 0, 66619, 126489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11620, + 0, 1149, 68316, 0, 0, 0, 0, 0, 92492, 0, 118784, 0, 0, 0, 12838, 0, + 118819, 0, 0, 0, 0, 41087, 0, 0, 0, 0, 12036, 0, 124143, 0, 0, 0, 64428, + 12227, 0, 0, 0, 0, 125248, 120964, 0, 0, 0, 0, 0, 69566, 0, 0, 0, 0, 0, + 1743, 0, 0, 0, 65186, 122626, 0, 0, 0, 0, 64439, 0, 68062, 0, 111259, + 111258, 43866, 0, 111263, 3395, 9362, 111260, 0, 111257, 111256, 111255, + 0, 0, 41091, 3426, 1344, 111249, 111248, 126215, 4735, 11111, 6119, + 111251, 42699, 0, 0, 74818, 1423, 0, 0, 0, 0, 12039, 10559, 0, 0, 0, + 9472, 67734, 11929, 0, 0, 0, 0, 128826, 0, 11579, 0, 0, 128364, 0, 92185, + 0, 0, 1004, 92584, 0, 0, 0, 129755, 0, 2556, 0, 0, 72790, 0, 0, 9686, 0, + 0, 0, 70109, 111102, 0, 10718, 13154, 111100, 9139, 0, 0, 0, 0, 0, 0, 0, + 0, 92831, 92810, 41708, 12860, 41703, 0, 42090, 5403, 10352, 73917, 129144, 111096, 111088, 5140, 3753, 118785, 41704, 0, 43078, 127789, - 2207, 129360, 0, 983205, 92362, 0, 0, 2410, 92525, 0, 0, 0, 0, 0, 0, 0, + 2207, 129360, 0, 983207, 92362, 0, 0, 2410, 92525, 0, 0, 0, 0, 0, 0, 0, 0, 119253, 0, 126601, 0, 2066, 74199, 0, 43463, 10659, 119623, 68863, 0, 1336, 0, 0, 69463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126639, 0, 272, 0, 0, 0, 0, 983965, 128133, 0, 0, 124940, 0, 1190, 42146, 1335, 42177, 43867, 0, 0, @@ -26612,9 +26795,9 @@ static const unsigned int code_hash[] = { 111193, 111192, 43097, 11688, 0, 78797, 194, 111186, 111185, 111184, 0, 0, 0, 11226, 4519, 70337, 10898, 43072, 70205, 0, 0, 0, 73094, 10695, 0, 7540, 0, 110984, 41859, 6067, 92790, 110982, 0, 110981, 13311, 92788, - 41857, 92791, 8359, 121224, 12689, 0, 983131, 64577, 92789, 111203, + 41857, 92791, 8359, 121224, 12689, 0, 983132, 64577, 92789, 111203, 68183, 111209, 111208, 6064, 110988, 0, 110979, 74142, 0, 111201, 111200, - 6051, 123613, 0, 0, 983371, 0, 983651, 0, 0, 0, 110864, 10537, 110862, + 6051, 123613, 0, 0, 983374, 0, 983651, 0, 0, 0, 110864, 10537, 110862, 1276, 0, 6549, 6052, 0, 0, 0, 0, 118687, 0, 0, 0, 0, 1960, 0, 71232, 66297, 0, 129313, 0, 0, 1345, 111213, 111212, 111211, 8956, 43083, 0, 111215, 64682, 0, 6430, 69563, 111210, 119814, 0, 0, 0, 119817, 0, 492, @@ -26636,7 +26819,7 @@ static const unsigned int code_hash[] = { 121097, 2847, 111028, 10330, 0, 1251, 7777, 41852, 125059, 111327, 111032, 111325, 12646, 0, 10259, 0, 65821, 75046, 6018, 0, 111324, 111323, 111322, 68372, 111319, 111318, 71893, 2558, 0, 64584, 111321, - 111320, 0, 0, 0, 0, 111309, 111308, 111307, 69500, 73987, 74599, 71895, + 111320, 0, 0, 0, 0, 78911, 111308, 111307, 69500, 73987, 74599, 71895, 93012, 0, 128715, 0, 12867, 111296, 0, 0, 11044, 111300, 111299, 8904, 11824, 65857, 0, 128674, 129027, 4387, 0, 0, 124920, 0, 0, 0, 0, 11842, 0, 0, 0, 5136, 1968, 983041, 126627, 1337, 0, 0, 0, 0, 66506, 0, 0, 0, 0, @@ -26644,7 +26827,7 @@ static const unsigned int code_hash[] = { 71894, 4276, 111314, 3619, 41638, 69691, 0, 42322, 8853, 111043, 0, 490, 0, 13231, 68384, 72310, 65350, 0, 0, 0, 68245, 42435, 6154, 0, 65354, 0, 0, 42397, 334, 72732, 42416, 65359, 65273, 74634, 128227, 4442, 10364, 0, - 778, 41626, 42455, 7989, 0, 3227, 69907, 111053, 0, 2915, 11502, 983212, + 778, 41626, 42455, 7989, 0, 3227, 69907, 111053, 0, 2915, 11502, 983214, 41702, 10309, 0, 0, 0, 0, 0, 0, 0, 127268, 127258, 127267, 65215, 64410, 127260, 71175, 0, 0, 0, 0, 0, 0, 41700, 110651, 69266, 126488, 0, 0, 42495, 0, 0, 0, 10460, 43364, 0, 1356, 3728, 42713, 0, 0, 42342, 10914, @@ -26654,75 +26837,76 @@ static const unsigned int code_hash[] = { 69888, 65508, 0, 0, 121451, 0, 0, 0, 129780, 69272, 4732, 128283, 0, 0, 0, 121113, 2236, 126551, 0, 6048, 0, 0, 73965, 0, 0, 0, 0, 10151, 9681, 4475, 0, 41142, 2100, 0, 0, 6035, 0, 123599, 10296, 0, 0, 0, 0, 0, 0, 0, - 983309, 68488, 10392, 10328, 0, 43462, 0, 0, 0, 8979, 0, 0, 983306, 0, 0, + 983312, 68488, 10392, 10328, 0, 43462, 0, 0, 0, 8979, 0, 0, 983309, 0, 0, 0, 10977, 0, 10344, 0, 65299, 10408, 0, 0, 121187, 66505, 0, 0, 0, 0, 0, - 122648, 43074, 73799, 0, 0, 0, 0, 3446, 0, 129891, 128692, 0, 0, 119582, - 4474, 0, 43093, 6282, 0, 0, 127372, 0, 0, 0, 129881, 0, 0, 0, 0, 66910, - 67811, 92277, 0, 64948, 0, 74347, 0, 0, 0, 983981, 8194, 0, 121165, - 11010, 0, 8893, 0, 983988, 0, 0, 0, 983319, 7925, 0, 0, 113825, 0, 1352, - 11069, 7707, 0, 126486, 0, 0, 0, 0, 65605, 6040, 0, 10071, 0, 128156, - 43750, 0, 8899, 69873, 0, 0, 983313, 128208, 7820, 69615, 0, 0, 7746, - 1492, 0, 0, 0, 66866, 0, 11788, 65913, 0, 0, 43095, 0, 0, 92265, 2999, 0, - 120720, 0, 371, 120759, 6023, 0, 0, 11708, 0, 0, 6323, 0, 0, 0, 8938, - 6043, 65866, 0, 0, 0, 72419, 0, 129480, 2589, 74332, 1689, 7802, 0, 0, 0, - 0, 66704, 0, 129992, 0, 0, 128127, 6049, 0, 4027, 0, 0, 111334, 111333, - 1503, 111331, 0, 111337, 11951, 111335, 2387, 0, 0, 8289, 111330, 7326, - 66514, 65514, 0, 64865, 0, 9668, 0, 0, 0, 0, 93060, 6036, 92768, 4026, - 74089, 127091, 0, 0, 75044, 110821, 0, 110819, 0, 0, 0, 0, 6021, 0, - 128288, 0, 43155, 0, 110822, 0, 111343, 42691, 111341, 111340, 2246, 166, - 0, 0, 0, 10623, 408, 0, 111339, 13298, 0, 7426, 43694, 0, 0, 8811, 0, 0, - 129753, 0, 0, 74134, 983054, 0, 127811, 0, 0, 0, 6645, 646, 128813, 0, - 42129, 0, 120880, 0, 8697, 0, 120936, 0, 0, 0, 0, 5809, 1950, 0, 92432, - 68339, 0, 42136, 0, 0, 0, 0, 0, 0, 111354, 983984, 0, 0, 111349, 111348, - 43330, 111346, 111353, 111352, 41567, 111350, 0, 0, 0, 0, 111345, 111344, - 8285, 0, 4509, 0, 128361, 0, 77774, 129851, 0, 0, 41727, 0, 0, 0, 0, 0, - 71188, 0, 74512, 7027, 3886, 0, 74023, 92888, 0, 0, 126092, 94058, - 119855, 0, 121455, 11707, 119852, 0, 7939, 10342, 92460, 72747, 121408, - 917569, 0, 71198, 94077, 119847, 0, 0, 7201, 0, 123554, 120866, 983987, - 1540, 0, 0, 124923, 0, 119856, 41718, 71177, 0, 0, 128001, 118699, 0, - 119040, 0, 9619, 120840, 0, 0, 0, 0, 3560, 0, 6070, 129000, 0, 2922, - 6082, 70147, 65009, 983973, 0, 0, 0, 0, 0, 0, 3607, 65863, 0, 92487, - 42153, 121042, 0, 983862, 2032, 0, 0, 0, 0, 129985, 0, 43085, 6057, 0, 0, - 0, 0, 0, 0, 0, 0, 638, 6083, 126976, 0, 0, 2305, 0, 0, 118658, 6056, - 10878, 0, 0, 6085, 119351, 0, 3915, 0, 0, 0, 0, 0, 0, 4028, 1787, 0, - 43096, 0, 0, 1768, 0, 0, 0, 128125, 0, 0, 583, 129137, 0, 0, 66004, 0, 0, - 0, 92859, 0, 55267, 120810, 128995, 43075, 65049, 0, 74531, 0, 93009, - 70694, 0, 0, 129375, 9869, 128815, 1771, 0, 0, 0, 0, 0, 0, 119115, - 113708, 0, 0, 74101, 0, 0, 0, 0, 83367, 0, 0, 0, 12539, 123631, 0, 0, - 129846, 73862, 69842, 9897, 0, 100561, 0, 0, 0, 0, 0, 8931, 0, 1415, - 8866, 74552, 0, 128312, 0, 983566, 43106, 127275, 71089, 1580, 92278, - 68424, 0, 0, 7658, 3440, 78215, 1562, 0, 0, 129031, 0, 0, 0, 0, 0, 0, - 6028, 68900, 42892, 0, 111016, 0, 0, 0, 0, 0, 128269, 0, 66776, 42946, - 127276, 92849, 0, 0, 120510, 11599, 0, 11602, 11591, 11574, 11581, 11597, - 11598, 6253, 11571, 11584, 70273, 11569, 0, 8906, 0, 5755, 2636, 0, - 10815, 11619, 129094, 0, 7815, 11616, 11617, 70064, 11618, 11604, 7869, - 11612, 0, 42152, 0, 0, 0, 92586, 126247, 0, 92173, 0, 0, 6616, 0, 0, - 120875, 391, 0, 0, 0, 42296, 11588, 0, 0, 0, 68397, 0, 0, 42335, 983188, - 0, 0, 7538, 94040, 0, 42491, 0, 0, 128088, 4576, 0, 0, 43809, 4277, 0, - 3563, 0, 42338, 368, 0, 0, 42412, 0, 78209, 119144, 0, 43814, 983616, - 1849, 0, 9921, 42451, 4253, 0, 0, 118688, 42404, 64657, 73919, 3618, - 78338, 0, 0, 0, 0, 0, 929, 6827, 42035, 0, 0, 0, 67847, 0, 0, 0, 0, 0, 0, - 0, 0, 4578, 64513, 0, 0, 0, 71049, 68090, 127086, 43305, 0, 73462, - 118530, 0, 42048, 10166, 0, 127095, 113810, 983127, 0, 983991, 0, 0, - 42483, 0, 0, 0, 42291, 0, 71047, 0, 6641, 525, 66404, 0, 8763, 125091, 0, - 0, 0, 0, 0, 42504, 42581, 74280, 6915, 42310, 0, 8559, 0, 983994, 125100, - 0, 0, 11666, 8679, 0, 1576, 42423, 0, 0, 73840, 983092, 11374, 0, 10889, - 129076, 0, 42462, 0, 77982, 0, 2718, 42424, 0, 0, 127166, 0, 1179, 0, 0, - 0, 363, 11015, 72229, 0, 43857, 0, 66692, 0, 0, 0, 11041, 72018, 0, 0, 0, - 0, 125184, 0, 92520, 0, 9492, 66709, 9212, 12833, 0, 0, 1297, 0, 0, 0, 0, - 0, 0, 12924, 0, 0, 10090, 125249, 0, 42505, 0, 42507, 0, 42311, 92940, - 120919, 68401, 10759, 0, 0, 120924, 42351, 42919, 9398, 66292, 0, 9422, - 0, 0, 0, 0, 0, 129440, 92575, 1603, 0, 0, 0, 0, 0, 69703, 11250, 0, 0, - 10546, 0, 0, 11600, 0, 2797, 73821, 42427, 306, 714, 3058, 120154, 0, 0, - 0, 42395, 0, 11607, 0, 11198, 127512, 0, 72232, 129067, 0, 42433, 0, - 7603, 74063, 0, 42141, 0, 0, 0, 129085, 8244, 362, 125069, 0, 8037, 0, 0, - 0, 69510, 41606, 66696, 77912, 0, 2093, 0, 120676, 0, 41604, 0, 0, 0, 0, - 10523, 1446, 42320, 0, 0, 64773, 42472, 0, 0, 1722, 5581, 0, 64496, 0, 0, - 64914, 0, 42620, 128603, 124988, 0, 0, 10549, 130035, 71190, 0, 0, 0, 0, - 0, 71712, 0, 0, 0, 0, 0, 0, 0, 7684, 66338, 0, 1174, 0, 0, 983621, 0, 0, - 0, 42277, 0, 42456, 65667, 0, 0, 0, 0, 42417, 0, 0, 120812, 42304, 0, 0, - 0, 74443, 127894, 0, 8313, 0, 0, 1316, 66690, 0, 0, 0, 0, 0, 0, 66844, - 983715, 0, 0, 0, 65200, 3383, 0, 0, 70063, 0, 0, 0, 42420, 119185, 0, 0, + 122648, 43074, 73799, 0, 0, 122944, 0, 3446, 0, 129891, 128692, 0, 0, + 119582, 4474, 0, 43093, 6282, 0, 0, 127372, 0, 0, 0, 129881, 0, 0, 0, 0, + 66910, 67811, 92277, 0, 64948, 0, 74347, 0, 0, 0, 983981, 8194, 0, + 121165, 11010, 0, 8893, 0, 983988, 0, 0, 0, 983322, 7925, 0, 0, 113825, + 0, 1352, 11069, 7707, 0, 126486, 0, 0, 0, 0, 65605, 6040, 0, 10071, 0, + 128156, 43750, 0, 8899, 69873, 0, 0, 983316, 128208, 7820, 69615, 0, 0, + 7746, 1492, 0, 0, 0, 66866, 0, 11788, 65913, 0, 0, 43095, 0, 0, 92265, + 2999, 0, 120720, 0, 371, 120759, 6023, 0, 0, 11708, 0, 0, 6323, 0, 0, 0, + 8938, 6043, 65866, 0, 78910, 0, 72419, 0, 129480, 2589, 74332, 1689, + 7802, 0, 0, 0, 0, 66704, 0, 129992, 0, 0, 128127, 6049, 0, 4027, 0, 0, + 111334, 111333, 1503, 111331, 0, 111337, 11951, 111335, 2387, 0, 0, 8289, + 111330, 7326, 66514, 65514, 0, 64865, 0, 9668, 0, 0, 0, 0, 93060, 6036, + 92768, 4026, 74089, 127091, 0, 0, 75044, 110821, 0, 110819, 0, 0, 0, 0, + 6021, 0, 128288, 0, 43155, 0, 110822, 124152, 111343, 42691, 111341, + 111340, 2246, 166, 0, 0, 0, 10623, 408, 0, 111339, 13298, 0, 7426, 43694, + 0, 0, 8811, 0, 0, 129753, 0, 0, 74134, 983054, 0, 127811, 0, 0, 0, 6645, + 646, 128813, 0, 42129, 0, 120880, 0, 8697, 0, 120936, 122953, 0, 0, 0, + 5809, 1950, 0, 92432, 68339, 0, 42136, 0, 0, 0, 0, 0, 0, 111354, 983984, + 0, 0, 111349, 111348, 43330, 111346, 111353, 111352, 41567, 111350, 0, 0, + 0, 0, 111345, 111344, 8285, 0, 4509, 0, 128361, 0, 77774, 129851, 0, 0, + 41727, 0, 0, 0, 0, 0, 71188, 0, 74512, 7027, 3886, 0, 74023, 92888, 0, 0, + 126092, 94058, 119855, 0, 121455, 11707, 119852, 0, 7939, 10342, 92460, + 72747, 121408, 917569, 0, 71198, 94077, 119847, 0, 0, 7201, 0, 123554, + 120866, 983987, 1540, 0, 0, 124923, 0, 119856, 41718, 71177, 0, 0, + 128001, 118699, 0, 119040, 0, 9619, 120840, 0, 0, 0, 0, 3560, 0, 6070, + 129000, 0, 2922, 6082, 70147, 65009, 983973, 0, 0, 0, 0, 0, 0, 3607, + 65863, 0, 92487, 42153, 121042, 0, 983862, 2032, 0, 0, 0, 0, 129985, 0, + 43085, 6057, 0, 0, 0, 0, 0, 0, 0, 0, 638, 6083, 126976, 0, 0, 2305, 0, 0, + 118658, 6056, 10878, 0, 0, 6085, 119351, 0, 3915, 0, 0, 0, 0, 0, 0, 4028, + 1787, 0, 43096, 0, 0, 1768, 0, 0, 0, 128125, 0, 0, 583, 129137, 0, 0, + 66004, 0, 0, 0, 92859, 0, 55267, 120810, 128995, 43075, 65049, 0, 74531, + 0, 93009, 70694, 0, 0, 129375, 9869, 128815, 1771, 0, 0, 0, 0, 0, 0, + 119115, 113708, 0, 0, 74101, 0, 0, 0, 0, 83367, 0, 0, 0, 12539, 123631, + 0, 0, 129846, 73862, 69842, 9897, 0, 100561, 0, 124142, 0, 0, 0, 8931, 0, + 1415, 8866, 74552, 0, 128312, 0, 983566, 43106, 127275, 71089, 1580, + 92278, 68424, 0, 0, 7658, 3440, 78215, 1562, 0, 0, 129031, 0, 0, 0, 0, 0, + 0, 6028, 68900, 42892, 0, 111016, 0, 0, 0, 0, 0, 128269, 0, 66776, 42946, + 127276, 92849, 0, 72448, 120510, 11599, 0, 11602, 11591, 11574, 11581, + 11597, 11598, 6253, 11571, 11584, 70273, 11569, 122937, 8906, 0, 5755, + 2636, 0, 10815, 11619, 129094, 0, 7815, 11616, 11617, 70064, 11618, + 11604, 7869, 11612, 0, 42152, 0, 122941, 0, 92586, 126247, 0, 92173, 0, + 0, 6616, 0, 0, 120875, 391, 0, 0, 0, 42296, 11588, 0, 0, 0, 68397, 0, 0, + 42335, 983189, 0, 0, 7538, 94040, 0, 42491, 0, 0, 128088, 4576, 0, 0, + 43809, 4277, 0, 3563, 0, 42338, 368, 0, 0, 42412, 0, 78209, 119144, 0, + 43814, 983616, 1849, 0, 9921, 42451, 4253, 0, 0, 118688, 42404, 64657, + 73919, 3618, 78338, 0, 0, 0, 0, 0, 929, 6827, 42035, 0, 0, 0, 67847, 0, + 0, 0, 0, 0, 0, 0, 0, 4578, 64513, 0, 0, 0, 71049, 68090, 127086, 43305, + 0, 73462, 118530, 0, 42048, 10166, 0, 127095, 113810, 983128, 0, 983991, + 0, 0, 42483, 0, 0, 0, 42291, 0, 71047, 0, 6641, 525, 66404, 0, 8763, + 125091, 0, 0, 0, 0, 0, 42504, 42581, 74280, 6915, 42310, 0, 8559, 0, + 983994, 125100, 0, 0, 11666, 8679, 0, 1576, 42423, 0, 0, 73840, 983092, + 11374, 0, 10889, 129076, 0, 42462, 0, 77982, 0, 2718, 42424, 0, 0, + 127166, 0, 1179, 0, 0, 0, 363, 11015, 72229, 0, 43857, 0, 66692, 0, 0, 0, + 11041, 72018, 0, 0, 0, 0, 125184, 0, 92520, 0, 9492, 66709, 9212, 12833, + 0, 0, 1297, 122932, 0, 0, 0, 0, 0, 12924, 0, 0, 10090, 125249, 0, 42505, + 0, 42507, 0, 42311, 92940, 120919, 68401, 10759, 0, 0, 120924, 42351, + 42919, 9398, 66292, 0, 9422, 122942, 122943, 0, 0, 0, 129440, 92575, + 1603, 0, 0, 0, 0, 0, 69703, 11250, 0, 0, 10546, 0, 0, 11600, 0, 2797, + 73821, 42427, 306, 714, 3058, 120154, 0, 0, 0, 42395, 0, 11607, 0, 11198, + 127512, 0, 72232, 129067, 0, 42433, 0, 7603, 74063, 0, 42141, 0, 0, 0, + 129085, 8244, 362, 125069, 0, 8037, 0, 0, 0, 69510, 41606, 66696, 77912, + 0, 2093, 0, 120676, 122929, 41604, 0, 0, 0, 0, 10523, 1446, 42320, 0, + 120247, 64773, 42472, 0, 0, 1722, 5581, 0, 64496, 0, 0, 64914, 0, 42620, + 128603, 124988, 0, 0, 10549, 130035, 71190, 0, 0, 0, 0, 0, 71712, 0, 0, + 0, 0, 0, 0, 0, 7684, 66338, 0, 1174, 0, 0, 983621, 0, 0, 0, 42277, 0, + 42456, 65667, 0, 0, 0, 0, 42417, 0, 0, 120812, 42304, 0, 0, 0, 74443, + 127894, 0, 8313, 0, 0, 1316, 66690, 0, 0, 0, 0, 0, 0, 66844, 983715, 0, + 0, 0, 65200, 3383, 0, 0, 70063, 122947, 0, 0, 42420, 119185, 0, 0, 983917, 0, 121079, 72369, 0, 42343, 124980, 42706, 1751, 42496, 65742, 13166, 0, 0, 0, 0, 0, 42683, 12697, 0, 0, 0, 125047, 0, 42346, 0, 0, 3757, 0, 0, 121075, 65869, 0, 9247, 74976, 3193, 0, 0, 42459, 7596, 7921, @@ -26747,17 +26931,17 @@ static const unsigned int code_hash[] = { 10502, 74457, 0, 11221, 41554, 0, 0, 0, 41557, 11209, 0, 11070, 119221, 0, 0, 73858, 41555, 9514, 0, 66771, 64641, 92447, 0, 7520, 73888, 77955, 0, 0, 0, 0, 0, 64527, 0, 118707, 12723, 0, 68776, 0, 0, 0, 78835, 4055, - 78826, 77960, 65212, 0, 127353, 12319, 0, 0, 983216, 7964, 65427, 0, + 78826, 77960, 65212, 0, 127353, 12319, 0, 0, 983218, 7964, 65427, 0, 65424, 72217, 120966, 0, 65425, 74890, 128251, 0, 0, 0, 3448, 10827, 0, 9866, 74527, 0, 0, 8625, 69783, 92304, 10477, 0, 0, 0, 65423, 0, 0, 0, 0, 6152, 0, 0, 6629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11046, 11490, 0, 4485, 71126, 0, 0, 0, 0, 0, 5869, 118533, 119633, 0, 7040, 3588, 0, 12825, 0, - 0, 128569, 0, 0, 0, 0, 0, 0, 0, 0, 128449, 64499, 65245, 127367, 1171, - 127368, 69717, 127365, 1805, 8772, 0, 127363, 9930, 65247, 0, 0, 2338, - 127362, 92695, 0, 0, 0, 69219, 0, 120104, 0, 120103, 72221, 120102, + 0, 128569, 0, 0, 0, 0, 0, 126637, 0, 0, 128449, 64499, 65245, 127367, + 1171, 127368, 69717, 127365, 1805, 8772, 0, 127363, 9930, 65247, 0, 0, + 2338, 127362, 92695, 0, 0, 0, 69219, 0, 120104, 0, 120103, 72221, 120102, 129924, 118814, 8734, 4212, 0, 0, 66701, 0, 65862, 0, 120095, 42903, 0, 0, 0, 126117, 426, 0, 120098, 8251, 0, 65436, 0, 2120, 43302, 1224, 0, - 65576, 0, 66876, 1764, 6074, 0, 12858, 0, 0, 65439, 6378, 74566, 0, + 65576, 0, 66876, 1764, 6074, 0, 12858, 0, 0, 65439, 6378, 74566, 128885, 41960, 0, 41644, 0, 2129, 0, 9222, 0, 0, 4259, 9092, 0, 41961, 0, 0, 66357, 42331, 64935, 0, 0, 1293, 0, 2132, 0, 983569, 0, 2454, 0, 3613, 128837, 71117, 0, 0, 69681, 10978, 10840, 0, 10668, 72826, 127197, 9118, @@ -26771,128 +26955,129 @@ static const unsigned int code_hash[] = { 2430, 41678, 71492, 0, 43785, 113716, 0, 121263, 0, 0, 1921, 0, 19927, 70390, 65406, 0, 43786, 4284, 128346, 72210, 43789, 12841, 9229, 0, 42285, 0, 0, 0, 0, 3521, 0, 118690, 8325, 0, 65403, 0, 1854, 0, 0, 0, 0, - 0, 0, 0, 0, 4344, 0, 65433, 6076, 0, 0, 74764, 12074, 0, 0, 0, 0, 12934, - 119555, 65432, 128877, 0, 6071, 65434, 0, 65435, 4053, 128623, 0, 0, 0, - 917934, 69823, 127463, 0, 121403, 127473, 8421, 127472, 0, 43705, 502, 0, - 65431, 0, 0, 0, 1303, 316, 7364, 0, 2136, 0, 120796, 64365, 43480, 92639, - 4860, 0, 127877, 0, 129728, 9583, 0, 5546, 0, 118565, 0, 0, 0, 5544, - 127475, 0, 70352, 5543, 128917, 72821, 12137, 5548, 0, 0, 10007, 0, - 127523, 6077, 0, 65452, 0, 119341, 11214, 65952, 0, 72226, 0, 0, 1319, + 0, 0, 0, 0, 4344, 0, 65433, 6076, 0, 0, 74764, 12074, 0, 0, 129148, 0, + 12934, 119555, 65432, 128877, 0, 6071, 65434, 0, 65435, 4053, 128623, 0, + 0, 0, 917934, 69823, 127463, 0, 121403, 127473, 8421, 73836, 0, 43705, + 502, 0, 65431, 0, 0, 0, 1303, 316, 7364, 0, 2136, 0, 120796, 64365, + 43480, 92639, 4860, 0, 127877, 0, 129728, 9583, 0, 5546, 0, 118565, 0, 0, + 0, 5544, 127475, 0, 70352, 5543, 128917, 72821, 12137, 5548, 0, 0, 10007, + 0, 127523, 6077, 0, 65452, 0, 119341, 11214, 65952, 0, 72226, 0, 0, 1319, 74210, 65410, 67399, 92606, 0, 0, 118660, 0, 66716, 83513, 4691, 128619, 9345, 621, 92872, 0, 122889, 65411, 0, 74575, 121246, 65408, 73899, 0, 9474, 2812, 119118, 65412, 3786, 65409, 8894, 83246, 119611, 7923, 3716, - 92798, 0, 0, 0, 7012, 0, 128439, 9566, 0, 94176, 0, 65012, 126242, 545, - 9575, 0, 10050, 12718, 0, 8859, 6820, 124915, 129941, 120740, 0, 0, 9119, - 2787, 0, 984000, 8507, 2012, 7985, 0, 0, 0, 0, 194634, 0, 410, 0, 0, - 120789, 120609, 0, 120378, 120379, 0, 0, 120374, 72742, 120376, 120377, - 120370, 120371, 120372, 120373, 3860, 120367, 72205, 74031, 111131, - 73685, 11748, 120365, 7941, 111134, 8749, 111132, 12698, 111129, 361, - 110793, 845, 67509, 0, 0, 4562, 72241, 2926, 0, 4569, 0, 110797, 43487, - 0, 0, 0, 74287, 122885, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6291, 0, 0, 0, 9734, - 0, 0, 0, 0, 127754, 7359, 83523, 43863, 0, 111150, 8769, 111148, 111147, - 111145, 4859, 111143, 111142, 0, 0, 0, 0, 12172, 111136, 0, 127899, - 111141, 64764, 4210, 111138, 0, 804, 0, 83520, 0, 70344, 0, 0, 67202, - 10091, 67200, 119257, 67206, 67205, 67204, 67203, 72302, 0, 0, 0, 128959, - 0, 1425, 92259, 119229, 11049, 0, 71480, 42649, 8482, 0, 0, 66715, 67209, - 11940, 67207, 664, 0, 0, 0, 70200, 127525, 0, 70194, 93061, 111155, - 68474, 111153, 6032, 67218, 67217, 7430, 194670, 70191, 0, 0, 0, 0, 0, - 41161, 0, 9765, 10993, 41162, 0, 70189, 1169, 111181, 0, 1905, 6034, - 41164, 64744, 43236, 0, 128800, 73110, 0, 0, 788, 0, 0, 111167, 111128, - 1663, 128976, 42901, 127237, 67211, 67210, 0, 0, 67215, 67214, 67213, - 67212, 111160, 111159, 111158, 111157, 0, 69492, 0, 111161, 43612, 0, 0, - 0, 10855, 67223, 9355, 67221, 65198, 120355, 0, 221, 0, 0, 0, 121141, - 7191, 118930, 72208, 125212, 0, 0, 0, 0, 67228, 67227, 43333, 67225, 0, - 0, 0, 67229, 0, 7245, 0, 74405, 69922, 72219, 111178, 3873, 8367, 111174, - 111173, 111172, 43649, 0, 111177, 111176, 0, 11164, 0, 74403, 111171, - 111170, 111169, 7682, 74404, 1462, 10235, 0, 0, 0, 0, 0, 111130, 0, 0, - 74402, 0, 92299, 0, 0, 74052, 0, 126127, 120549, 0, 64295, 0, 0, 0, 0, 0, - 120662, 0, 0, 67231, 67230, 10755, 55257, 11155, 128568, 983136, 9470, 0, - 127540, 0, 69680, 64384, 0, 128607, 0, 0, 0, 0, 73764, 8204, 0, 0, 0, 0, - 0, 8728, 0, 10904, 73446, 19936, 7833, 0, 0, 0, 0, 92546, 0, 0, 0, 8537, - 0, 0, 0, 121244, 0, 0, 2254, 128193, 0, 0, 0, 0, 3062, 0, 0, 0, 0, 0, - 41160, 41147, 41158, 0, 120777, 0, 41155, 111116, 111115, 111114, 0, - 121332, 111119, 111118, 111117, 129878, 0, 129091, 0, 0, 0, 64594, 2456, - 66867, 0, 0, 0, 0, 3721, 0, 0, 1230, 2678, 0, 3597, 917795, 0, 0, 92215, - 0, 67737, 8352, 0, 0, 0, 64515, 121378, 0, 129128, 67846, 0, 129767, - 92466, 0, 0, 71338, 0, 8660, 0, 0, 0, 0, 0, 4483, 0, 0, 0, 6080, 0, 0, - 1746, 1315, 0, 70201, 0, 13140, 74508, 0, 0, 4480, 0, 111113, 111112, 0, - 67979, 0, 6360, 10897, 111106, 605, 68302, 110737, 69875, 110735, 110736, - 66681, 0, 0, 0, 0, 0, 0, 0, 10877, 118868, 64885, 0, 0, 0, 0, 0, 0, 345, - 0, 0, 64606, 9917, 0, 0, 92196, 0, 1776, 8422, 43992, 0, 0, 0, 126543, - 43328, 0, 0, 1295, 0, 42869, 0, 0, 0, 0, 128772, 65123, 125210, 11293, - 11288, 0, 0, 65666, 0, 92369, 65420, 0, 0, 4252, 0, 0, 0, 706, 72800, 0, - 0, 129931, 65419, 92177, 0, 8419, 65421, 0, 66702, 0, 12670, 118608, 0, - 0, 0, 72825, 65422, 83008, 0, 0, 0, 0, 0, 0, 9736, 4184, 65418, 0, 0, - 74035, 0, 129955, 0, 0, 0, 0, 129447, 0, 7962, 12211, 9837, 83505, 0, 0, - 5719, 0, 129720, 119068, 73777, 1857, 0, 9927, 0, 983959, 0, 10037, 0, - 73695, 78322, 78319, 7818, 0, 0, 127769, 0, 0, 0, 65077, 0, 78325, 78326, - 78323, 43327, 43989, 0, 65828, 0, 0, 83499, 0, 68390, 0, 110687, 78336, - 78339, 9543, 78335, 78332, 78333, 0, 127964, 0, 129552, 983914, 0, 69448, - 0, 71429, 0, 0, 0, 11914, 69431, 0, 0, 0, 9949, 0, 0, 119215, 0, 12073, - 0, 0, 0, 0, 101218, 2260, 0, 0, 0, 0, 0, 0, 1939, 0, 0, 0, 69903, 0, 0, - 0, 0, 6643, 92477, 0, 0, 78330, 78331, 78328, 78329, 0, 92551, 0, 0, 0, - 0, 0, 72417, 0, 0, 0, 0, 78341, 78342, 120944, 78340, 129513, 127529, - 92350, 3784, 78350, 0, 78348, 78349, 78345, 43324, 78343, 78344, 2231, 0, - 0, 0, 42467, 0, 0, 42894, 78363, 13281, 78360, 78361, 78356, 78358, - 78353, 64899, 0, 41149, 0, 43162, 68096, 41150, 0, 10571, 67162, 67161, - 67160, 67159, 6947, 41152, 887, 9249, 6565, 64806, 74366, 0, 67158, - 67157, 0, 10831, 67175, 67174, 120232, 65827, 43325, 67178, 10168, 67176, - 0, 0, 9190, 128497, 9666, 41997, 0, 0, 0, 0, 0, 0, 129411, 0, 78508, 0, - 78351, 78352, 0, 75063, 72839, 983749, 0, 126604, 0, 0, 0, 983419, 0, - 2270, 0, 129957, 0, 78365, 0, 67189, 72818, 0, 0, 0, 0, 0, 0, 0, 72833, - 101119, 78366, 78367, 0, 0, 0, 0, 10137, 6121, 10995, 0, 71050, 8119, 0, - 71052, 0, 0, 0, 0, 0, 0, 0, 1394, 0, 0, 128960, 0, 67184, 2998, 67182, - 67181, 67188, 67187, 67186, 67185, 0, 101185, 0, 0, 67180, 42003, 0, 0, - 67193, 67192, 67191, 67190, 67197, 67196, 67195, 67194, 0, 72770, 43315, - 71051, 0, 1593, 0, 125120, 619, 4635, 0, 72875, 0, 128859, 118657, 0, 0, - 0, 67199, 67198, 0, 42790, 42006, 0, 0, 0, 128998, 10757, 9347, 127767, - 0, 0, 74227, 78904, 0, 74116, 128423, 121073, 120860, 0, 92427, 0, 0, 0, - 0, 64590, 0, 4371, 0, 0, 92478, 0, 0, 73977, 0, 0, 127847, 0, 120862, 0, - 64550, 73745, 70451, 0, 121013, 0, 0, 0, 129286, 0, 0, 0, 0, 9131, - 118648, 125214, 983220, 0, 0, 64260, 0, 12606, 0, 0, 0, 0, 562, 983614, - 0, 129648, 66455, 127533, 3219, 0, 0, 0, 1037, 0, 64491, 0, 983695, - 78572, 78580, 4568, 549, 0, 0, 0, 0, 0, 128095, 70851, 2205, 0, 0, 0, 0, - 129716, 0, 10825, 8079, 118962, 0, 0, 0, 128855, 0, 13071, 0, 0, 41049, - 42840, 43614, 129341, 74881, 74596, 127191, 5212, 0, 66402, 119191, 0, - 9747, 0, 0, 129778, 984008, 41047, 1668, 0, 0, 0, 1187, 0, 74416, 0, 0, - 0, 0, 3240, 128518, 9213, 0, 0, 0, 127174, 69822, 0, 0, 0, 0, 1623, 0, 0, - 0, 0, 0, 0, 11272, 0, 73914, 65048, 1909, 42172, 0, 0, 10736, 11580, - 72228, 7615, 0, 0, 4237, 66576, 0, 65815, 68083, 0, 0, 0, 3489, 0, 0, 0, - 0, 0, 0, 127146, 3796, 6800, 0, 65582, 0, 129521, 0, 0, 68036, 0, 0, - 64857, 121213, 126493, 0, 66308, 0, 0, 64634, 127817, 0, 0, 0, 0, 3246, - 0, 43972, 128643, 0, 0, 0, 0, 120751, 0, 0, 0, 0, 1496, 42827, 0, 942, - 2378, 119213, 0, 0, 0, 0, 9510, 1232, 8139, 0, 0, 0, 11409, 0, 6382, 0, - 66319, 121237, 0, 0, 0, 127887, 2374, 0, 8475, 120844, 66313, 0, 0, - 64879, 119298, 0, 0, 70869, 0, 0, 129025, 0, 7705, 11942, 0, 0, 3309, 0, - 0, 0, 83345, 983866, 0, 0, 1280, 6998, 128104, 0, 0, 0, 129945, 0, 0, 0, - 0, 0, 0, 0, 74239, 983073, 0, 0, 0, 6078, 121354, 0, 1475, 0, 9938, 6084, - 0, 983995, 0, 118571, 0, 3256, 0, 43973, 0, 0, 0, 8727, 0, 0, 0, 110831, - 110832, 10562, 110830, 0, 0, 0, 3248, 0, 0, 9015, 0, 0, 3635, 64337, 0, - 0, 43852, 7195, 0, 2007, 64431, 0, 0, 0, 0, 0, 0, 0, 65613, 77909, 0, 0, - 0, 0, 119218, 7984, 11670, 74434, 127770, 4176, 69248, 2034, 69442, - 11154, 65891, 0, 0, 318, 2038, 0, 0, 0, 3649, 13149, 42145, 42798, 3634, - 0, 0, 128483, 0, 0, 0, 11402, 120954, 94032, 74238, 0, 43313, 0, 0, 7938, - 0, 1761, 0, 65379, 68386, 128185, 1159, 71183, 0, 0, 0, 66687, 120851, 0, - 41680, 0, 0, 0, 1514, 11668, 67891, 9313, 0, 128490, 67877, 0, 41681, 0, - 0, 12848, 69982, 67873, 0, 74278, 0, 0, 12649, 0, 0, 1194, 3242, 9761, - 9555, 8598, 0, 120524, 0, 1551, 65447, 129414, 126211, 0, 0, 0, 67875, 0, - 3495, 66648, 125079, 0, 73024, 983229, 0, 126130, 10641, 0, 0, 0, 77845, - 0, 0, 0, 0, 0, 11131, 0, 0, 0, 0, 0, 42685, 72017, 193, 0, 0, 0, 42667, - 0, 0, 92318, 71958, 0, 1362, 9558, 0, 0, 0, 7351, 73789, 0, 0, 4426, 0, - 0, 0, 0, 7276, 42163, 5220, 0, 0, 67822, 0, 0, 0, 0, 41692, 0, 72283, 0, - 0, 3223, 65492, 0, 0, 4549, 983706, 0, 0, 101162, 10807, 0, 0, 0, 42182, - 8688, 12866, 0, 3294, 0, 0, 128101, 0, 64514, 0, 43329, 129989, 0, 0, 0, - 119061, 0, 43422, 0, 0, 128618, 0, 42729, 0, 3215, 120982, 68880, 917564, - 0, 0, 0, 65682, 0, 0, 65924, 0, 983823, 0, 1501, 0, 118807, 0, 0, 9607, - 0, 65794, 72243, 983046, 10989, 0, 74399, 0, 0, 7152, 0, 0, 129530, 7483, - 125083, 0, 8104, 70128, 7474, 0, 5189, 0, 0, 0, 8141, 0, 42537, 69612, 0, - 0, 0, 0, 0, 127307, 42934, 0, 0, 0, 0, 0, 0, 64517, 0, 0, 1650, 0, 0, - 128502, 7901, 3238, 0, 65556, 0, 0, 65158, 43416, 74959, 0, 7527, 0, - 43319, 0, 0, 45, 0, 0, 0, 0, 0, 7347, 0, 0, 0, 13129, 0, 9084, 0, 8737, - 0, 0, 0, 66808, 9639, 7912, 2620, 0, 3564, 0, 0, 0, 0, 75049, 0, 2853, 0, - 0, 0, 0, 0, 2850, 8084, 0, 0, 71446, 92284, 43122, 0, 0, 0, 126503, - 72214, 0, 74767, 0, 7331, 110646, 0, 8245, 0, 3158, 92396, 3983, 0, 923, - 0, 69397, 292, 0, 126548, 0, 3221, 1763, 0, 0, 0, 0, 7253, 194636, 68391, + 92798, 0, 0, 0, 7012, 124122, 128439, 9566, 0, 94176, 0, 65012, 126242, + 545, 9575, 0, 10050, 12718, 0, 8859, 6820, 124915, 129941, 120740, 0, 0, + 9119, 2787, 0, 984000, 8507, 2012, 7985, 0, 0, 0, 0, 194634, 0, 410, 0, + 0, 120789, 120609, 0, 120378, 120379, 0, 0, 120374, 72742, 120376, + 120377, 120370, 120371, 120372, 120373, 3860, 120367, 72205, 74031, + 111131, 73685, 11748, 120365, 7941, 111134, 8749, 111132, 12698, 111129, + 361, 110793, 845, 67509, 0, 0, 4562, 72241, 2926, 0, 4569, 0, 110797, + 43487, 0, 0, 0, 74287, 122885, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6291, 0, 0, 0, + 9734, 0, 0, 0, 0, 127754, 7359, 83523, 43863, 0, 111150, 8769, 111148, + 111147, 111145, 4859, 111143, 111142, 0, 0, 0, 0, 12172, 111136, 0, + 127899, 111141, 64764, 4210, 111138, 0, 804, 0, 83520, 0, 70344, 0, 0, + 67202, 10091, 67200, 119257, 67206, 67205, 67204, 67203, 72302, 0, 0, 0, + 128959, 0, 1425, 92259, 119229, 11049, 0, 71480, 42649, 8482, 0, 0, + 66715, 67209, 11940, 67207, 664, 0, 0, 0, 70200, 127525, 0, 70194, 93061, + 111155, 68474, 111153, 6032, 67218, 67217, 7430, 194670, 70191, 0, 0, 0, + 0, 0, 41161, 0, 9765, 10993, 41162, 0, 70189, 1169, 111181, 0, 1905, + 6034, 41164, 64744, 43236, 0, 128800, 73110, 0, 0, 788, 0, 0, 111167, + 111128, 1663, 128976, 42901, 127237, 67211, 67210, 0, 0, 67215, 67214, + 67213, 67212, 111160, 111159, 111158, 111157, 0, 69492, 0, 111161, 43612, + 0, 0, 0, 10855, 67223, 9355, 67221, 65198, 120355, 0, 221, 0, 0, 0, + 121141, 7191, 118930, 72208, 125212, 0, 0, 0, 0, 67228, 67227, 43333, + 67225, 0, 0, 0, 67229, 0, 7245, 0, 74405, 69922, 72219, 111178, 3873, + 8367, 111174, 111173, 111172, 43649, 0, 111177, 111176, 0, 11164, 0, + 74403, 111171, 111170, 111169, 7682, 74404, 1462, 10235, 0, 0, 0, 0, 0, + 111130, 0, 0, 74402, 0, 92299, 0, 0, 74052, 0, 126127, 120549, 0, 64295, + 0, 0, 0, 0, 0, 120662, 0, 0, 67231, 67230, 10755, 55257, 11155, 128568, + 983137, 9470, 0, 127540, 0, 69680, 64384, 0, 128607, 0, 0, 0, 122987, + 73764, 8204, 0, 0, 0, 0, 0, 8728, 0, 10904, 73446, 19936, 7833, 0, 0, 0, + 0, 92546, 0, 0, 0, 8537, 0, 0, 0, 121244, 0, 0, 2254, 128193, 0, 0, 0, 0, + 3062, 0, 0, 0, 0, 0, 41160, 41147, 41158, 0, 120777, 0, 41155, 111116, + 111115, 111114, 0, 121332, 111119, 111118, 111117, 129878, 0, 129091, 0, + 0, 0, 64594, 2456, 66867, 0, 0, 0, 0, 3721, 0, 0, 1230, 2678, 0, 3597, + 917795, 0, 0, 92215, 0, 67737, 8352, 0, 0, 0, 64515, 121378, 0, 129128, + 67846, 0, 129767, 92466, 0, 0, 71338, 0, 8660, 0, 0, 0, 0, 0, 4483, 0, 0, + 0, 6080, 0, 0, 1746, 1315, 0, 70201, 0, 13140, 74508, 0, 0, 4480, 0, + 111113, 111112, 0, 67979, 0, 6360, 10897, 111106, 605, 68302, 110737, + 69875, 110735, 110736, 66681, 0, 0, 0, 0, 0, 0, 0, 10877, 118868, 64885, + 0, 0, 0, 0, 0, 0, 345, 0, 0, 64606, 9917, 0, 0, 92196, 0, 1776, 8422, + 43992, 0, 0, 0, 126543, 43328, 0, 0, 1295, 0, 42869, 0, 0, 0, 0, 128772, + 65123, 125210, 11293, 11288, 0, 0, 65666, 0, 92369, 65420, 0, 0, 4252, 0, + 0, 0, 706, 72800, 0, 0, 129931, 65419, 92177, 0, 8419, 65421, 0, 66702, + 0, 12670, 118608, 0, 0, 0, 72825, 65422, 83008, 0, 0, 0, 0, 0, 124153, + 9736, 4184, 65418, 0, 0, 74035, 0, 129955, 0, 0, 0, 0, 129447, 0, 7962, + 12211, 9837, 83505, 0, 0, 5719, 0, 129720, 119068, 73777, 1857, 0, 9927, + 0, 983959, 0, 10037, 0, 73695, 78322, 78319, 7818, 0, 0, 127769, 0, 0, 0, + 65077, 0, 78325, 78326, 78323, 43327, 43989, 0, 65828, 0, 0, 83499, 0, + 68390, 0, 110687, 78336, 78339, 9543, 78335, 78332, 78333, 0, 127964, 0, + 129552, 983914, 0, 69448, 0, 71429, 0, 0, 0, 11914, 69431, 0, 0, 0, 9949, + 0, 0, 119215, 0, 12073, 73519, 0, 0, 0, 101218, 2260, 0, 0, 0, 0, 0, 0, + 1939, 0, 0, 0, 69903, 0, 0, 0, 0, 6643, 92477, 128485, 0, 78330, 78331, + 78328, 78329, 0, 92551, 0, 0, 0, 0, 124124, 72417, 0, 0, 0, 0, 78341, + 78342, 120944, 78340, 129513, 127529, 92350, 3784, 78350, 0, 78348, + 78349, 78345, 43324, 78343, 78344, 2231, 0, 0, 0, 42467, 0, 0, 42894, + 78363, 13281, 78360, 78361, 78356, 78358, 78353, 64899, 0, 41149, 0, + 43162, 68096, 41150, 0, 10571, 67162, 67161, 67160, 67159, 6947, 41152, + 887, 9249, 6565, 64806, 74366, 0, 67158, 67157, 0, 10831, 67175, 67174, + 120232, 65827, 43325, 67178, 10168, 67176, 0, 0, 9190, 128497, 9666, + 41997, 0, 0, 0, 0, 0, 0, 129411, 0, 78508, 0, 78351, 78352, 0, 75063, + 72839, 983749, 0, 126604, 0, 0, 0, 983422, 0, 2270, 0, 129957, 0, 78365, + 0, 67189, 72818, 0, 0, 0, 0, 0, 0, 0, 72833, 101119, 78366, 78367, 0, 0, + 0, 0, 10137, 6121, 10995, 0, 71050, 8119, 0, 71052, 0, 0, 0, 0, 0, 0, 0, + 1394, 0, 0, 128960, 0, 67184, 2998, 67182, 67181, 67188, 67187, 67186, + 67185, 0, 101185, 0, 0, 67180, 42003, 0, 0, 67193, 67192, 67191, 67190, + 67197, 67196, 67195, 67194, 0, 72770, 43315, 71051, 0, 1593, 0, 125120, + 619, 4635, 0, 72875, 0, 128859, 118657, 0, 0, 0, 67199, 67198, 0, 42790, + 42006, 0, 0, 0, 128998, 10757, 9347, 127767, 0, 0, 74227, 78904, 0, + 74116, 128423, 121073, 120860, 0, 92427, 0, 0, 0, 0, 64590, 0, 4371, 0, + 0, 92478, 0, 0, 73977, 0, 0, 127847, 0, 120862, 0, 64550, 73745, 70451, + 0, 121013, 0, 0, 0, 129286, 0, 0, 0, 0, 9131, 118648, 125214, 983223, 0, + 0, 64260, 0, 12606, 0, 0, 0, 0, 562, 983614, 0, 129648, 66455, 127533, + 3219, 0, 0, 0, 1037, 0, 64491, 0, 78579, 78572, 78580, 4568, 549, 0, 0, + 0, 0, 0, 128095, 70851, 2205, 0, 0, 0, 0, 129716, 0, 10825, 8079, 118962, + 0, 0, 0, 128855, 0, 13071, 0, 0, 41049, 42840, 43614, 129341, 74881, + 74596, 127191, 5212, 0, 66402, 119191, 0, 9747, 0, 0, 129778, 984008, + 41047, 1668, 0, 0, 0, 1187, 0, 74416, 0, 0, 0, 0, 3240, 128518, 9213, 0, + 0, 0, 127174, 69822, 0, 0, 0, 0, 1623, 0, 0, 0, 0, 0, 0, 11272, 0, 73914, + 65048, 1909, 42172, 0, 0, 10736, 11580, 72228, 7615, 0, 0, 4237, 66576, + 0, 65815, 68083, 0, 0, 0, 3489, 0, 0, 0, 0, 0, 0, 127146, 3796, 6800, 0, + 65582, 0, 129521, 0, 0, 68036, 0, 0, 64857, 121213, 126493, 0, 66308, 0, + 0, 64634, 127817, 0, 0, 0, 0, 3246, 0, 43972, 128643, 0, 0, 0, 0, 120751, + 0, 0, 0, 0, 1496, 42827, 0, 942, 2378, 119213, 0, 0, 0, 0, 9510, 1232, + 8139, 0, 0, 0, 11409, 0, 6382, 0, 66319, 121237, 0, 0, 0, 127887, 2374, + 0, 8475, 120844, 66313, 0, 0, 64879, 119298, 0, 0, 70869, 0, 0, 129025, + 0, 7705, 11942, 0, 0, 3309, 0, 119302, 0, 83345, 983866, 0, 0, 1280, + 6998, 128104, 0, 0, 0, 129945, 0, 0, 0, 0, 0, 0, 0, 74239, 983073, 0, 0, + 0, 6078, 121354, 0, 1475, 0, 9938, 6084, 0, 983995, 0, 118571, 0, 3256, + 0, 43973, 0, 0, 0, 8727, 0, 0, 0, 110831, 110832, 10562, 110830, 0, 0, 0, + 3248, 0, 0, 9015, 0, 0, 3635, 64337, 0, 0, 43852, 7195, 0, 2007, 64431, + 0, 0, 0, 0, 0, 0, 0, 65613, 77909, 0, 0, 0, 0, 119218, 7984, 11670, + 74434, 127770, 4176, 69248, 2034, 69442, 11154, 65891, 0, 0, 318, 2038, + 0, 0, 0, 3649, 13149, 42145, 42798, 3634, 0, 0, 128483, 122928, 124113, + 0, 11402, 120954, 94032, 74238, 0, 43313, 0, 0, 7938, 0, 1761, 0, 65379, + 68386, 128185, 1159, 71183, 0, 0, 0, 66687, 120851, 0, 41680, 0, 0, 0, + 1514, 11668, 67891, 9313, 0, 128490, 67877, 0, 41681, 0, 0, 12848, 69982, + 67873, 0, 74278, 0, 0, 12649, 0, 0, 1194, 3242, 9761, 9555, 8598, 0, + 120524, 0, 1551, 65447, 129414, 126211, 0, 0, 0, 67875, 0, 3495, 66648, + 125079, 0, 73024, 983232, 0, 126130, 10641, 0, 0, 0, 77845, 0, 0, 0, 0, + 0, 11131, 0, 0, 0, 0, 0, 42685, 72017, 193, 0, 0, 0, 42667, 0, 0, 92318, + 71958, 0, 1362, 9558, 0, 0, 0, 7351, 73789, 0, 0, 4426, 0, 0, 0, 0, 7276, + 42163, 5220, 0, 0, 67822, 0, 0, 0, 0, 41692, 0, 72283, 0, 0, 3223, 65492, + 0, 0, 4549, 983706, 0, 0, 101162, 10807, 0, 0, 0, 42182, 8688, 12866, 0, + 3294, 0, 0, 128101, 0, 64514, 0, 43329, 129989, 0, 0, 0, 119061, 0, + 43422, 0, 0, 128618, 0, 42729, 0, 3215, 120982, 68880, 917564, 0, 0, 0, + 65682, 0, 0, 65924, 0, 73506, 0, 1501, 0, 118807, 0, 0, 9607, 0, 65794, + 72243, 983046, 10989, 0, 74399, 0, 0, 7152, 0, 0, 129530, 7483, 125083, + 0, 8104, 70128, 7474, 0, 5189, 0, 0, 0, 8141, 0, 42537, 69612, 0, 0, 0, + 0, 0, 127307, 42934, 0, 0, 0, 0, 0, 0, 64517, 0, 0, 1650, 0, 0, 128502, + 7901, 3238, 0, 65556, 0, 0, 65158, 43416, 74959, 0, 7527, 0, 43319, 0, 0, + 45, 0, 0, 0, 0, 0, 7347, 0, 0, 0, 13129, 0, 9084, 0, 8737, 0, 0, 0, + 66808, 9639, 7912, 2620, 129653, 3564, 0, 0, 0, 0, 75049, 0, 2853, 0, 0, + 0, 0, 0, 2850, 8084, 0, 0, 71446, 92284, 43122, 0, 0, 0, 126503, 72214, + 0, 74767, 0, 7331, 110646, 0, 8245, 0, 3158, 92396, 3983, 0, 923, 0, + 69397, 292, 0, 126548, 0, 3221, 1763, 0, 0, 0, 0, 7253, 194636, 68391, 75002, 0, 3637, 12996, 0, 70461, 0, 0, 3228, 0, 0, 0, 0, 0, 0, 120833, 118939, 0, 7696, 78589, 0, 0, 0, 43316, 4177, 0, 9089, 0, 128805, 72116, 64500, 68133, 0, 0, 1856, 100572, 0, 6379, 0, 118999, 0, 3208, 0, 0, 0, @@ -26901,20 +27086,20 @@ static const unsigned int code_hash[] = { 4573, 0, 0, 0, 0, 0, 92961, 0, 118620, 41688, 0, 0, 0, 8314, 0, 0, 0, 0, 0, 66721, 0, 0, 121033, 0, 128226, 0, 0, 0, 13164, 0, 66237, 983982, 0, 0, 0, 3257, 0, 0, 1845, 0, 0, 0, 0, 128783, 0, 0, 0, 0, 3499, 8609, 0, - 7145, 0, 0, 0, 0, 74829, 984007, 983293, 0, 0, 0, 7591, 0, 0, 0, 73778, + 7145, 0, 0, 0, 0, 74829, 984007, 983296, 0, 0, 0, 7591, 0, 0, 0, 73778, 70132, 128167, 0, 0, 0, 0, 119261, 0, 0, 118561, 13083, 0, 0, 0, 0, - 66177, 983271, 5429, 0, 0, 68168, 66181, 0, 0, 983255, 0, 0, 5433, 67659, + 66177, 983274, 5429, 0, 0, 68168, 66181, 0, 0, 983258, 0, 0, 5433, 67659, 0, 42776, 1547, 66176, 92428, 0, 5425, 4977, 9999, 0, 5423, 64560, 125094, 0, 0, 0, 74122, 0, 0, 0, 128003, 4418, 66199, 0, 92300, 0, 0, 0, - 11863, 124995, 0, 11908, 0, 9360, 125101, 983202, 0, 66187, 12837, - 983290, 0, 11112, 0, 92321, 43318, 0, 0, 0, 0, 126518, 120604, 0, 983288, + 11863, 124995, 0, 11908, 0, 9360, 125101, 983204, 0, 66187, 12837, + 983293, 0, 11112, 0, 92321, 43318, 0, 0, 0, 0, 126518, 120604, 0, 983291, 0, 129595, 0, 983801, 0, 9958, 0, 125108, 0, 0, 0, 2433, 128602, 0, 3352, 0, 0, 0, 0, 0, 0, 305, 567, 67662, 0, 69979, 65242, 0, 41695, 0, 0, 0, 7837, 92873, 129002, 5337, 917622, 7325, 43312, 917619, 68742, 917617, 74086, 68777, 917614, 917613, 10973, 917611, 1372, 128768, 917608, 917607, 1254, 917605, 917604, 93967, 917602, 65228, 113753, 129367, 67723, 8068, 0, 0, 983970, 0, 3245, 64393, 119069, 118681, 0, 0, 0, 0, 0, - 0, 983281, 0, 119563, 129935, 78865, 0, 126638, 0, 0, 43322, 0, 0, 0, 0, + 0, 983284, 0, 119563, 129935, 78865, 0, 126638, 0, 0, 43322, 0, 0, 0, 0, 92698, 3226, 67695, 0, 0, 983958, 10200, 0, 128779, 101143, 0, 65610, 0, 0, 0, 3585, 250, 101142, 43320, 0, 0, 0, 0, 1152, 129849, 1688, 0, 0, 0, 0, 0, 121040, 128340, 0, 0, 0, 2107, 0, 129048, 0, 0, 0, 43868, 129832, @@ -26929,97 +27114,98 @@ static const unsigned int code_hash[] = { 0, 0, 2625, 92724, 0, 74309, 0, 0, 0, 7850, 120296, 69639, 127032, 0, 0, 43384, 12660, 110663, 0, 0, 110706, 110661, 0, 92380, 0, 0, 69649, 0, 713, 41073, 0, 3990, 0, 0, 0, 5017, 128313, 120352, 0, 0, 1030, 0, - 983120, 9513, 0, 0, 0, 4668, 0, 120350, 0, 6339, 0, 0, 0, 64650, 0, 0, + 983121, 9513, 0, 0, 0, 4668, 0, 120350, 0, 6339, 0, 0, 0, 64650, 0, 0, 74766, 983869, 8908, 0, 0, 0, 0, 10752, 13003, 68769, 0, 41307, 8732, - 120336, 0, 41310, 0, 4696, 0, 983953, 0, 120334, 3641, 5419, 0, 0, 0, 0, - 120344, 128129, 0, 7320, 65230, 11808, 0, 93970, 936, 13289, 0, 69892, - 65774, 0, 65243, 0, 19953, 0, 126469, 121375, 127256, 12913, 70722, - 68759, 0, 0, 70203, 0, 4113, 0, 2372, 1819, 0, 128053, 12152, 0, 682, - 7655, 120330, 129921, 0, 10593, 1703, 0, 0, 8033, 69953, 0, 9810, 0, 0, - 127949, 0, 119159, 10109, 0, 73898, 0, 71730, 126704, 0, 0, 917620, 1965, - 917621, 0, 0, 73887, 0, 0, 0, 6314, 0, 8501, 0, 0, 0, 41317, 0, 5417, - 983582, 0, 0, 9353, 68148, 41315, 0, 11161, 0, 41314, 194892, 0, 126562, - 119236, 634, 0, 0, 0, 69779, 4355, 12016, 0, 9654, 12856, 6924, 7660, 0, - 0, 0, 0, 0, 42692, 0, 74604, 0, 0, 0, 680, 6274, 0, 1181, 0, 3174, 67248, - 0, 0, 0, 0, 113776, 10650, 917603, 92295, 70672, 118965, 0, 64644, - 126981, 0, 0, 0, 0, 983961, 0, 65302, 40989, 68239, 68230, 68234, 0, 0, - 124989, 0, 40987, 4667, 0, 983963, 8828, 0, 0, 0, 4746, 0, 129840, 2269, - 4749, 0, 100598, 65192, 4744, 7345, 0, 242, 100595, 0, 8217, 0, 68919, 0, - 2245, 0, 0, 66790, 10850, 0, 0, 0, 0, 0, 129853, 64680, 0, 0, 120562, 0, - 127324, 0, 100551, 128721, 0, 7316, 0, 983610, 100552, 74157, 1646, 0, 0, - 73995, 120857, 129047, 0, 7350, 0, 0, 0, 9099, 4107, 3441, 0, 2975, - 194701, 0, 983966, 55220, 10084, 73943, 120845, 118649, 0, 0, 3399, 0, 0, - 11909, 0, 0, 7687, 0, 6789, 0, 0, 72739, 71367, 0, 0, 92589, 9151, 1137, - 0, 749, 7505, 125076, 5385, 0, 69387, 0, 0, 41298, 0, 69461, 0, 0, 0, 0, - 0, 0, 128455, 0, 519, 0, 64547, 5766, 0, 0, 0, 8848, 0, 41297, 0, 0, 0, - 41300, 74468, 65160, 0, 129839, 127511, 0, 0, 6558, 0, 0, 128686, 92775, - 0, 71450, 41302, 127927, 0, 0, 128646, 68762, 11729, 8719, 9060, 0, - 128796, 0, 0, 118573, 129682, 0, 11734, 93011, 11730, 73450, 9593, 5757, - 2403, 0, 55275, 0, 11728, 65894, 0, 0, 0, 68741, 0, 0, 0, 43489, 4282, - 983864, 0, 83497, 70328, 128103, 70324, 0, 69490, 127509, 0, 8456, 0, 0, - 74783, 0, 78250, 0, 70320, 120722, 9792, 0, 70326, 0, 0, 83500, 70322, - 10019, 71701, 123617, 6568, 4365, 0, 0, 3647, 0, 41134, 128341, 0, - 125043, 41135, 0, 0, 0, 129938, 0, 123616, 0, 41137, 41139, 0, 6545, 0, - 125139, 7597, 10528, 75054, 0, 3732, 73910, 0, 0, 0, 7312, 983639, 9062, - 93840, 11853, 0, 0, 128324, 41538, 0, 0, 118702, 0, 194706, 41531, 1263, - 3720, 0, 68028, 0, 41524, 64692, 119635, 0, 41534, 0, 92193, 0, 41168, 0, - 67398, 127347, 3524, 0, 8831, 127349, 127357, 0, 127360, 127352, 129816, - 0, 0, 0, 0, 0, 5845, 0, 0, 0, 71909, 8200, 0, 68460, 0, 43283, 5551, 0, - 0, 0, 6340, 983552, 100602, 0, 0, 0, 0, 0, 5422, 0, 0, 0, 2471, 0, 0, - 2749, 0, 73774, 10913, 72122, 0, 8666, 675, 74093, 0, 194986, 0, 69262, - 0, 0, 0, 10928, 0, 41153, 0, 0, 0, 3738, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 42347, 12092, 9615, 7234, 74047, 129782, 0, 0, 123639, 0, 0, 2934, - 0, 0, 0, 0, 74507, 0, 74461, 0, 0, 74290, 0, 64562, 129975, 64473, 0, 0, - 73728, 0, 11212, 0, 12128, 6534, 0, 0, 1901, 0, 0, 0, 0, 0, 127520, 0, 0, - 0, 0, 69940, 65459, 68293, 92290, 128808, 3770, 0, 0, 0, 64579, 128511, - 0, 0, 983334, 983342, 0, 0, 0, 5941, 0, 0, 65079, 0, 0, 0, 73961, 983336, - 0, 0, 0, 0, 0, 0, 10638, 0, 0, 0, 71486, 0, 0, 983351, 0, 43840, 129495, - 0, 5233, 983348, 64792, 71233, 0, 983326, 0, 0, 9847, 0, 1685, 595, 0, - 73971, 1292, 8940, 0, 11088, 0, 10004, 0, 0, 6541, 0, 0, 0, 5603, 9014, - 5606, 0, 538, 128705, 5602, 8467, 74391, 6547, 0, 0, 0, 0, 8458, 129534, - 8495, 0, 0, 917552, 10981, 78314, 125057, 2465, 0, 0, 0, 9730, 9280, 0, - 0, 74155, 72766, 113690, 0, 504, 0, 120715, 0, 983606, 0, 0, 0, 123141, - 125024, 0, 0, 732, 3737, 0, 1548, 0, 0, 1832, 5604, 0, 41141, 0, 5607, - 72854, 2176, 3745, 0, 0, 128137, 0, 0, 3869, 11937, 5725, 0, 66566, 7416, - 5728, 0, 0, 0, 11918, 66567, 5724, 118829, 5727, 0, 0, 0, 5723, 118585, - 128116, 71999, 0, 0, 0, 42532, 0, 12303, 0, 11423, 0, 983115, 68303, - 74074, 0, 128267, 6559, 64557, 71348, 0, 66763, 43019, 0, 10238, 0, 0, - 43377, 0, 71346, 124937, 9783, 42704, 0, 71719, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 41144, 129465, 0, 0, 0, 72793, 92176, 0, 70682, 0, 8820, 0, 0, - 0, 11515, 526, 0, 0, 0, 0, 0, 0, 8635, 0, 0, 8288, 11815, 0, 0, 0, 1543, - 3713, 0, 0, 0, 68041, 127816, 0, 0, 64357, 0, 42082, 0, 0, 8987, 42081, - 0, 0, 0, 0, 0, 0, 6553, 0, 0, 11253, 0, 0, 5475, 0, 0, 0, 119334, 12990, - 1160, 42084, 0, 123152, 0, 0, 360, 0, 0, 128274, 5863, 3137, 0, 983317, - 0, 0, 10959, 3146, 0, 127374, 0, 68341, 13076, 3135, 983300, 0, 0, 3142, - 0, 94068, 10819, 128479, 0, 74635, 12877, 119867, 73967, 0, 70808, 0, 0, - 0, 0, 6163, 129745, 113728, 0, 0, 0, 8603, 0, 0, 3306, 0, 43392, 0, - 917565, 5751, 0, 0, 0, 0, 0, 7403, 0, 118933, 0, 122628, 64783, 92658, 0, - 0, 129592, 0, 0, 65569, 7021, 0, 0, 0, 0, 0, 6540, 6974, 0, 0, 0, 0, 0, - 0, 0, 983655, 0, 43585, 0, 6551, 983993, 0, 0, 0, 0, 0, 72216, 8977, 602, - 120814, 0, 0, 0, 72119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 983624, 74812, 0, - 0, 0, 9475, 0, 65105, 0, 118556, 0, 43592, 7831, 66751, 0, 0, 73915, 0, - 43593, 0, 43591, 43061, 0, 0, 43589, 43584, 0, 13113, 0, 0, 43590, 8766, - 9087, 0, 0, 41574, 78337, 0, 42900, 6376, 0, 0, 0, 0, 9854, 0, 0, 0, 0, - 0, 0, 0, 2909, 0, 0, 0, 6529, 110930, 75004, 3751, 0, 0, 0, 1798, 0, 0, - 1354, 0, 13152, 6557, 12430, 0, 94098, 0, 0, 0, 68123, 128097, 0, 0, 0, - 71264, 123559, 11082, 0, 65677, 8682, 42054, 92595, 42045, 9804, 0, 0, - 3595, 0, 0, 0, 0, 42399, 0, 0, 0, 65541, 0, 7324, 0, 0, 0, 8797, 77895, - 0, 64888, 7167, 2356, 95, 110810, 0, 0, 42286, 0, 0, 69999, 0, 120877, 0, - 0, 42324, 129359, 0, 0, 43492, 0, 43406, 0, 0, 0, 0, 0, 43400, 0, 0, - 71720, 0, 66435, 0, 0, 3201, 514, 74502, 0, 43396, 0, 64493, 0, 43404, - 11218, 0, 0, 43398, 0, 0, 41341, 129485, 6564, 1463, 41342, 0, 5293, 0, - 0, 3733, 0, 0, 41344, 0, 0, 0, 0, 41346, 0, 69747, 0, 0, 0, 0, 0, 0, 0, - 983764, 0, 0, 0, 65272, 0, 0, 1270, 1132, 0, 0, 0, 66655, 0, 0, 74314, - 64761, 0, 110853, 8510, 0, 129600, 0, 0, 0, 0, 0, 0, 69692, 0, 0, 42383, - 69690, 0, 69700, 13141, 0, 92465, 0, 0, 0, 41566, 0, 0, 129334, 127171, - 0, 0, 0, 0, 0, 0, 0, 6308, 0, 0, 2611, 0, 66881, 0, 65063, 0, 0, 0, 0, - 4484, 8747, 110597, 128369, 0, 0, 0, 0, 0, 0, 12902, 0, 0, 7299, 0, 0, - 12107, 7100, 10905, 65010, 0, 125135, 66018, 9284, 0, 0, 0, 0, 0, 0, 0, - 12010, 0, 126093, 120949, 121032, 0, 0, 0, 0, 0, 0, 0, 0, 6618, 3562, - 66365, 0, 42234, 12648, 128039, 0, 0, 0, 41309, 9764, 41316, 0, 0, 13230, - 41299, 0, 0, 68365, 0, 0, 0, 0, 0, 0, 4153, 0, 0, 128047, 0, 0, 42889, 0, - 129322, 41578, 0, 41577, 0, 68092, 0, 6533, 0, 41570, 0, 72414, 0, 41580, - 74628, 0, 12901, 0, 0, 0, 0, 71461, 41360, 0, 0, 4743, 0, 0, 0, 0, 68398, + 120336, 0, 41310, 0, 4696, 0, 983953, 0, 120334, 3641, 5419, 124119, 0, + 0, 0, 120344, 128129, 0, 7320, 65230, 11808, 0, 93970, 936, 13289, 0, + 69892, 65774, 0, 65243, 0, 19953, 0, 126469, 121375, 127256, 12913, + 70722, 68759, 0, 0, 70203, 0, 4113, 0, 2372, 1819, 0, 128053, 12152, 0, + 682, 7655, 120330, 129921, 0, 10593, 1703, 0, 0, 8033, 69953, 0, 9810, 0, + 0, 127949, 0, 119159, 10109, 0, 73898, 0, 71730, 126704, 0, 0, 917620, + 1965, 917621, 0, 0, 73887, 0, 0, 0, 6314, 0, 8501, 0, 0, 0, 41317, 0, + 5417, 983582, 0, 0, 9353, 68148, 41315, 0, 11161, 0, 41314, 194892, 0, + 126562, 119236, 634, 0, 0, 0, 69779, 4355, 12016, 0, 9654, 12856, 6924, + 7660, 0, 0, 0, 0, 0, 42692, 0, 74604, 0, 0, 0, 680, 6274, 0, 1181, 0, + 3174, 67248, 0, 0, 0, 0, 113776, 10650, 917603, 92295, 70672, 118965, 0, + 64644, 126981, 0, 0, 0, 0, 983961, 0, 65302, 40989, 68239, 68230, 68234, + 0, 0, 124989, 0, 40987, 4667, 0, 983963, 8828, 0, 0, 0, 4746, 0, 129840, + 2269, 4749, 0, 100598, 65192, 4744, 7345, 0, 242, 100595, 0, 8217, 0, + 68919, 0, 2245, 0, 0, 66790, 10850, 0, 0, 0, 983391, 0, 129853, 64680, 0, + 0, 120562, 0, 127324, 0, 100551, 128721, 0, 7316, 0, 983610, 100552, + 74157, 1646, 0, 0, 73995, 120857, 73500, 0, 7350, 0, 0, 0, 9099, 4107, + 3441, 0, 2975, 194701, 0, 983966, 55220, 10084, 73943, 120845, 118649, 0, + 0, 3399, 0, 0, 11909, 0, 0, 7687, 0, 6789, 0, 0, 72739, 71367, 0, 0, + 92589, 9151, 1137, 0, 749, 7505, 125076, 5385, 0, 69387, 0, 0, 41298, 0, + 69461, 0, 0, 0, 0, 0, 0, 128455, 0, 519, 0, 64547, 5766, 0, 0, 0, 8848, + 0, 41297, 0, 0, 0, 41300, 74468, 65160, 0, 129839, 127511, 0, 0, 6558, 0, + 0, 128686, 92775, 0, 71450, 41302, 127927, 0, 0, 128646, 68762, 11729, + 8719, 9060, 0, 128796, 0, 0, 118573, 129682, 0, 11734, 93011, 11730, + 73450, 9593, 5757, 2403, 0, 55275, 0, 11728, 65894, 0, 0, 0, 68741, 0, 0, + 0, 43489, 4282, 983864, 0, 83497, 70328, 128103, 70324, 0, 69490, 127509, + 0, 8456, 0, 0, 74783, 0, 78250, 0, 70320, 120722, 9792, 0, 70326, 0, 0, + 83500, 70322, 10019, 71701, 123617, 6568, 4365, 129399, 0, 3647, 0, + 41134, 128341, 0, 125043, 41135, 0, 0, 0, 129938, 0, 123616, 0, 41137, + 41139, 0, 6545, 0, 125139, 7597, 10528, 75054, 0, 3732, 73910, 0, 0, 0, + 7312, 983639, 9062, 93840, 11853, 0, 0, 128324, 41538, 0, 0, 118702, 0, + 194706, 41531, 1263, 3720, 0, 68028, 0, 41524, 64692, 119635, 0, 41534, + 0, 92193, 0, 41168, 0, 67398, 127347, 3524, 0, 8831, 127349, 127357, 0, + 127360, 127352, 129816, 0, 0, 0, 0, 0, 5845, 0, 0, 0, 71909, 8200, 0, + 68460, 0, 43283, 5551, 0, 0, 0, 6340, 983552, 100602, 0, 0, 0, 0, 0, + 5422, 0, 0, 0, 2471, 0, 0, 2749, 0, 73774, 10913, 72122, 0, 8666, 675, + 74093, 0, 194986, 0, 69262, 0, 0, 0, 10928, 0, 41153, 0, 0, 0, 3738, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42347, 12092, 9615, 7234, 74047, + 129782, 0, 0, 123639, 0, 0, 2934, 0, 0, 0, 0, 74507, 0, 74461, 0, 0, + 74290, 0, 64562, 129975, 64473, 0, 0, 73728, 0, 11212, 0, 12128, 6534, 0, + 0, 1901, 0, 0, 0, 0, 0, 127520, 0, 0, 0, 0, 69940, 65459, 68293, 92290, + 128808, 3770, 0, 0, 0, 64579, 128511, 0, 0, 983337, 983345, 0, 0, 0, + 5941, 0, 0, 65079, 0, 0, 0, 73961, 983339, 0, 0, 0, 0, 0, 0, 10638, 0, 0, + 0, 71486, 0, 0, 983354, 0, 43840, 129495, 0, 5233, 983351, 64792, 71233, + 0, 983329, 0, 73553, 9847, 0, 1685, 595, 0, 73971, 1292, 8940, 0, 11088, + 0, 10004, 0, 0, 6541, 0, 0, 0, 5603, 9014, 5606, 0, 538, 128705, 5602, + 8467, 74391, 6547, 0, 0, 0, 0, 8458, 129534, 8495, 0, 0, 917552, 10981, + 78314, 125057, 2465, 0, 0, 0, 9730, 9280, 0, 0, 74155, 72766, 113690, 0, + 504, 0, 120715, 0, 983606, 0, 0, 0, 123141, 125024, 0, 0, 732, 3737, 0, + 1548, 0, 0, 1832, 5604, 0, 41141, 0, 5607, 72854, 2176, 3745, 0, 0, + 128137, 0, 0, 3869, 11937, 5725, 0, 66566, 7416, 5728, 0, 0, 0, 11918, + 66567, 5724, 118829, 5727, 0, 0, 0, 5723, 118585, 128116, 71999, 0, 0, 0, + 42532, 0, 12303, 0, 11423, 0, 983116, 68303, 74074, 0, 128267, 6559, + 64557, 71348, 0, 66763, 43019, 0, 10238, 0, 0, 43377, 0, 71346, 124937, + 9783, 42704, 0, 71719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41144, 129465, 0, + 0, 0, 72793, 92176, 0, 70682, 0, 8820, 0, 0, 0, 11515, 526, 0, 0, 0, 0, + 0, 0, 8635, 0, 0, 8288, 11815, 0, 0, 0, 1543, 3713, 0, 0, 0, 68041, + 127816, 0, 0, 64357, 0, 42082, 0, 0, 8987, 42081, 0, 0, 0, 0, 0, 0, 6553, + 0, 0, 11253, 0, 0, 5475, 0, 0, 0, 119334, 12990, 1160, 42084, 0, 123152, + 0, 0, 360, 0, 0, 128274, 5863, 3137, 0, 983320, 0, 0, 10959, 3146, 0, + 127374, 0, 68341, 13076, 3135, 983303, 0, 0, 3142, 0, 94068, 10819, + 128479, 0, 74635, 12877, 119867, 73967, 0, 70808, 0, 0, 0, 0, 6163, + 129745, 113728, 0, 0, 0, 8603, 0, 0, 3306, 0, 43392, 0, 917565, 5751, 0, + 0, 0, 0, 0, 7403, 0, 118933, 0, 122628, 64783, 92658, 0, 0, 129592, 0, 0, + 65569, 7021, 0, 0, 119864, 0, 0, 6540, 6974, 0, 0, 0, 0, 0, 0, 0, 983655, + 0, 43585, 0, 6551, 983993, 0, 0, 0, 0, 0, 72216, 8977, 602, 120814, 0, 0, + 0, 72119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 983624, 74812, 0, 0, 0, 9475, 0, + 65105, 0, 118556, 0, 43592, 7831, 66751, 0, 0, 73915, 0, 43593, 0, 43591, + 43061, 0, 0, 43589, 43584, 0, 13113, 0, 0, 43590, 8766, 9087, 0, 0, + 41574, 78337, 0, 42900, 6376, 0, 0, 0, 0, 9854, 0, 0, 0, 0, 0, 0, 0, + 2909, 110928, 0, 0, 6529, 110930, 75004, 3751, 0, 0, 0, 1798, 0, 0, 1354, + 0, 13152, 6557, 12430, 0, 94098, 0, 0, 0, 68123, 128097, 0, 0, 0, 71264, + 123559, 11082, 0, 65677, 8682, 42054, 92595, 42045, 9804, 0, 0, 3595, 0, + 0, 119498, 0, 42399, 0, 0, 0, 65541, 0, 7324, 0, 0, 0, 8797, 77895, 0, + 64888, 7167, 2356, 95, 110810, 0, 0, 42286, 0, 0, 69999, 0, 120877, 0, 0, + 42324, 129359, 0, 0, 43492, 0, 43406, 0, 0, 0, 0, 0, 43400, 0, 0, 71720, + 0, 66435, 0, 0, 3201, 514, 74502, 0, 43396, 0, 64493, 0, 43404, 11218, 0, + 0, 43398, 0, 0, 41341, 129485, 6564, 1463, 41342, 0, 5293, 0, 0, 3733, 0, + 0, 41344, 0, 0, 0, 0, 41346, 0, 69747, 0, 0, 0, 0, 0, 0, 0, 983764, 0, 0, + 0, 65272, 0, 0, 1270, 1132, 0, 0, 0, 66655, 0, 0, 74314, 64761, 0, + 110853, 8510, 0, 129600, 0, 0, 0, 0, 0, 0, 69692, 0, 0, 42383, 69690, 0, + 69700, 13141, 0, 92465, 0, 0, 0, 41566, 0, 0, 129334, 127171, 0, 0, 0, 0, + 0, 0, 0, 6308, 0, 0, 2611, 0, 66881, 0, 65063, 0, 0, 0, 0, 4484, 8747, + 110597, 128369, 0, 0, 0, 0, 0, 0, 12902, 0, 0, 7299, 0, 0, 12107, 7100, + 10905, 65010, 0, 125135, 66018, 9284, 0, 0, 0, 0, 0, 0, 0, 12010, 0, + 126093, 120949, 121032, 0, 0, 0, 0, 0, 0, 0, 0, 6618, 3562, 66365, 0, + 42234, 12648, 128039, 0, 0, 0, 41309, 9764, 41316, 0, 0, 13230, 41299, 0, + 0, 68365, 0, 0, 0, 0, 0, 0, 4153, 0, 0, 128047, 0, 0, 42889, 0, 129322, + 41578, 0, 41577, 0, 68092, 0, 6533, 0, 41570, 0, 72414, 0, 41580, 74628, + 0, 12901, 0, 0, 0, 0, 71461, 41360, 0, 0, 4743, 0, 0, 0, 0, 68398, 110781, 5890, 110779, 111103, 3739, 8695, 92514, 0, 3964, 8984, 111095, 68288, 0, 0, 70000, 111090, 111089, 67504, 3956, 82952, 111093, 6563, 111091, 41305, 0, 0, 12067, 41312, 0, 0, 0, 129708, 0, 8175, 0, 3600, 0, @@ -27036,30 +27222,30 @@ static const unsigned int code_hash[] = { 7396, 0, 0, 69788, 0, 43512, 7965, 111039, 111038, 111037, 111036, 41350, 0, 0, 0, 2294, 64501, 68034, 0, 68405, 111034, 0, 0, 111030, 111029, 71105, 111027, 0, 111033, 92200, 111031, 0, 6764, 0, 0, 111026, 111025, - 111024, 65203, 128010, 0, 0, 0, 3210, 0, 129978, 0, 0, 82958, 127970, + 72454, 65203, 128010, 0, 0, 0, 3210, 0, 129978, 0, 0, 82958, 127970, 82957, 0, 68875, 10043, 71979, 1186, 41571, 0, 5209, 9464, 82960, 66657, 5207, 65062, 5213, 0, 0, 41348, 41568, 128803, 3253, 111045, 111044, 74067, 111042, 111049, 5596, 111047, 111046, 0, 64887, 0, 5217, 111041, 72252, 0, 0, 0, 0, 2635, 92760, 0, 0, 0, 92742, 0, 113672, 0, 0, 0, 2258, 67081, 0, 67083, 0, 0, 0, 5784, 0, 0, 0, 0, 4011, 0, 0, 0, 0, 4254, 0, 111054, 5600, 111052, 111051, 10447, 5598, 1207, 111055, 0, 3501, 42582, - 0, 111050, 0, 1124, 5597, 983498, 983499, 9321, 129464, 75040, 983495, 0, - 1719, 68356, 68354, 9671, 1125, 2721, 0, 129876, 983501, 7631, 5488, + 0, 111050, 0, 1124, 5597, 983501, 78908, 9321, 129464, 75040, 983498, 0, + 1719, 68356, 68354, 9671, 1125, 2721, 0, 129876, 983504, 7631, 5488, 111082, 0, 0, 5491, 111086, 8937, 0, 3236, 74187, 5490, 0, 5489, 8522, 68358, 111069, 6300, 111067, 111066, 0, 0, 111071, 111070, 0, 9875, 7593, 111065, 0, 0, 43182, 0, 68379, 3311, 111058, 111057, 3746, 11016, 65752, 111061, 0, 43423, 68775, 0, 111056, 72225, 0, 0, 127120, 0, 2232, 0, 0, - 0, 0, 0, 126555, 0, 0, 8656, 0, 128358, 0, 0, 983487, 983488, 917563, - 983486, 983483, 983484, 0, 0, 0, 129669, 0, 111183, 128043, 983492, 1036, - 983490, 111075, 1723, 111073, 111072, 111079, 41579, 111077, 111076, - 10705, 0, 983482, 74486, 71693, 740, 983478, 983479, 129645, 0, 0, 74846, + 0, 0, 0, 126555, 0, 0, 8656, 0, 128358, 0, 0, 983490, 983491, 917563, + 983489, 983486, 983487, 0, 0, 0, 129669, 0, 111183, 128043, 983495, 1036, + 983493, 111075, 1723, 111073, 111072, 111079, 41579, 111077, 111076, + 10705, 0, 983485, 74486, 71693, 740, 983481, 983482, 129645, 0, 0, 74846, 92255, 0, 0, 0, 0, 0, 10438, 74487, 73798, 13285, 0, 0, 0, 5690, 0, 93992, 0, 0, 13095, 0, 127857, 121419, 7321, 121203, 13254, 70176, 75070, 0, 0, 0, 0, 127845, 3247, 317, 0, 0, 0, 0, 917543, 0, 10173, 0, 0, 0, 0, 0, 5223, 0, 0, 119564, 5226, 0, 94044, 5880, 94065, 7758, 0, 0, 5224, - 5487, 94041, 5692, 41725, 983464, 0, 5695, 41711, 0, 43171, 0, 94049, - 5691, 983469, 866, 1488, 983468, 983454, 65665, 94036, 983453, 74797, 0, - 0, 11039, 983462, 11145, 71211, 983461, 983458, 983459, 983456, 983457, + 5487, 94041, 5692, 41725, 983467, 0, 5695, 41711, 0, 43171, 0, 94049, + 5691, 983472, 866, 1488, 983471, 983457, 65665, 94036, 983456, 74797, 0, + 0, 11039, 983465, 11145, 71211, 983464, 983461, 983462, 983459, 983460, 42492, 43402, 125208, 3302, 0, 72842, 43153, 0, 0, 120885, 121300, 0, 7856, 8690, 0, 73076, 110880, 0, 0, 73091, 0, 69925, 120635, 65153, 0, 0, 0, 0, 0, 0, 4540, 0, 0, 0, 0, 11844, 121209, 8863, 0, 75061, 71978, 6389, @@ -27067,7 +27253,7 @@ static const unsigned int code_hash[] = { 9648, 111123, 71170, 10270, 10286, 10318, 10382, 43529, 0, 0, 0, 0, 0, 70110, 43835, 119520, 70111, 119360, 118815, 127084, 127083, 8767, 0, 128437, 41281, 0, 5201, 0, 6215, 67072, 6214, 13101, 0, 0, 65268, 67073, - 0, 0, 127976, 72995, 127073, 10511, 42075, 0, 127071, 129509, 0, 67115, + 0, 0, 127976, 72995, 127073, 10511, 42075, 0, 73475, 129509, 0, 67115, 127069, 111293, 127068, 0, 127067, 0, 74845, 0, 42071, 43156, 0, 0, 0, 0, 7954, 0, 0, 0, 8485, 4671, 0, 69513, 4740, 0, 0, 42618, 78294, 3064, 6212, 0, 0, 0, 9554, 0, 83044, 0, 126598, 0, 78291, 6159, 6213, 12885, 0, @@ -27085,14 +27271,14 @@ static const unsigned int code_hash[] = { 125136, 128583, 0, 7022, 0, 4739, 0, 5802, 9816, 8615, 0, 0, 491, 65837, 0, 0, 128644, 0, 8426, 11092, 9891, 0, 0, 0, 41881, 118823, 3736, 7394, 42648, 0, 68448, 9095, 7741, 12684, 41885, 0, 0, 0, 0, 5815, 0, 0, 0, - 127392, 0, 0, 41878, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120804, 0, 0, 2267, 0, - 78289, 78359, 78288, 0, 0, 78318, 65920, 0, 194819, 7057, 9408, 9409, - 9410, 9411, 9412, 9413, 9414, 9415, 9416, 9417, 9418, 9419, 9420, 9421, - 5897, 9423, 917933, 127107, 0, 127108, 917937, 127963, 8955, 9399, 9400, - 9401, 9402, 9403, 9404, 9405, 9406, 9407, 0, 128626, 42669, 73832, 78261, - 67683, 2631, 119308, 78259, 0, 78260, 3996, 0, 119307, 0, 0, 0, 0, 0, 0, - 64825, 917916, 917913, 917914, 917919, 5899, 917917, 129990, 12085, 0, - 574, 69734, 77825, 73828, 9473, 77824, 118918, 73900, 41735, 42211, 0, + 127392, 0, 0, 41878, 0, 0, 0, 0, 0, 0, 0, 0, 119503, 0, 120804, 0, 0, + 2267, 0, 78289, 78359, 78288, 0, 0, 78318, 65920, 0, 194819, 7057, 9408, + 9409, 9410, 9411, 9412, 9413, 9414, 9415, 9416, 9417, 9418, 9419, 9420, + 9421, 5897, 9423, 917933, 127107, 0, 127108, 917937, 127963, 8955, 9399, + 9400, 9401, 9402, 9403, 9404, 9405, 9406, 9407, 0, 128626, 42669, 73832, + 78261, 67683, 2631, 119308, 78259, 0, 78260, 3996, 0, 119307, 0, 0, 0, 0, + 0, 0, 64825, 917916, 917913, 917914, 917919, 5899, 917917, 129990, 12085, + 0, 574, 69734, 77825, 73828, 9473, 77824, 118918, 73900, 41735, 42211, 0, 4190, 77834, 77835, 77830, 77833, 3616, 77828, 77837, 77838, 7708, 77836, 2228, 113765, 0, 0, 4191, 42968, 77844, 73800, 77842, 77843, 77839, 77840, 0, 78311, 83375, 0, 0, 10415, 74102, 0, 5896, 0, 10351, 67151, 0, @@ -27115,45 +27301,45 @@ static const unsigned int code_hash[] = { 0, 101166, 82976, 0, 0, 67812, 0, 101163, 0, 42572, 0, 128300, 119146, 1963, 11622, 0, 43237, 82981, 7550, 67100, 5903, 82984, 78009, 129750, 9662, 0, 128391, 0, 0, 0, 0, 11013, 0, 0, 0, 128433, 67090, 0, 0, 0, 0, - 0, 11568, 983704, 43367, 0, 0, 7852, 0, 0, 0, 0, 0, 194676, 0, 194675, 0, - 0, 416, 129668, 0, 73834, 0, 68921, 10984, 0, 0, 101175, 129838, 101182, - 0, 127013, 92423, 0, 983258, 121199, 0, 0, 12540, 0, 0, 0, 0, 11445, - 101168, 2112, 0, 0, 0, 1021, 0, 9507, 10210, 78005, 8023, 93963, 78006, - 78001, 43181, 78003, 9532, 119094, 0, 0, 0, 0, 0, 1885, 43268, 129802, - 129798, 120542, 121153, 392, 7894, 4391, 129810, 8221, 119597, 77999, - 77998, 0, 0, 0, 92967, 0, 3558, 0, 3913, 70429, 121376, 0, 0, 1265, 0, - 6309, 0, 12969, 0, 101151, 0, 101146, 0, 101139, 0, 41864, 0, 0, 74294, - 0, 167, 0, 917584, 0, 93983, 72354, 68477, 0, 0, 917594, 0, 2493, 129827, - 0, 129804, 0, 917570, 0, 0, 0, 406, 917592, 0, 0, 0, 0, 0, 0, 0, 127161, - 0, 128597, 0, 0, 0, 3421, 10561, 0, 8365, 917581, 0, 127569, 120787, - 128669, 0, 0, 0, 0, 7834, 0, 0, 101154, 10298, 6624, 4908, 0, 1639, - 120842, 0, 0, 6327, 6724, 0, 0, 0, 69910, 4817, 0, 0, 0, 68059, 0, 11022, - 0, 0, 0, 118888, 0, 0, 7548, 64794, 0, 12291, 983165, 0, 0, 0, 0, 0, 0, - 1134, 1838, 0, 2057, 0, 0, 0, 0, 0, 0, 5206, 0, 0, 42523, 0, 0, 0, 0, - 65550, 8570, 4816, 0, 127926, 0, 4821, 0, 0, 0, 4818, 125257, 119974, - 119977, 0, 0, 119970, 119973, 0, 119983, 119982, 67470, 119984, 119979, - 119978, 0, 119980, 119670, 129297, 0, 11284, 119987, 70097, 65155, - 119988, 0, 9363, 0, 0, 0, 5900, 93990, 7889, 2722, 128770, 0, 0, 0, 0, - 2282, 0, 0, 0, 68093, 0, 0, 0, 0, 0, 70150, 118628, 0, 0, 0, 129651, - 70146, 983079, 119967, 71330, 70148, 0, 0, 94006, 70144, 119964, 110677, - 110678, 110675, 110676, 0, 110674, 4226, 0, 123165, 5732, 71327, 0, 0, - 65119, 0, 0, 92971, 64770, 0, 0, 6093, 0, 0, 1395, 0, 0, 0, 121179, 786, - 0, 43174, 64340, 0, 125269, 0, 983662, 125138, 10132, 0, 0, 0, 0, 0, - 93956, 0, 68444, 0, 92437, 123143, 0, 0, 92656, 0, 0, 0, 1399, 121463, 0, - 121465, 121464, 120808, 241, 121469, 4907, 0, 0, 0, 0, 0, 0, 0, 0, - 127904, 0, 0, 42780, 0, 0, 0, 4217, 0, 0, 0, 0, 72158, 0, 0, 43099, 3965, - 0, 0, 0, 13300, 0, 0, 43057, 0, 0, 0, 0, 0, 65372, 0, 6410, 126073, + 0, 11568, 983704, 43367, 0, 0, 7852, 119496, 0, 0, 0, 0, 194676, 0, + 194675, 0, 0, 416, 129668, 0, 73834, 0, 68921, 10984, 0, 0, 101175, + 129838, 101182, 0, 127013, 92423, 0, 983261, 121199, 0, 0, 12540, 0, + 983220, 0, 0, 11445, 101168, 2112, 0, 0, 0, 1021, 0, 9507, 10210, 78005, + 8023, 93963, 78006, 78001, 43181, 78003, 9532, 119094, 0, 0, 0, 0, 0, + 1885, 43268, 129802, 129798, 120542, 121153, 392, 7894, 4391, 129810, + 8221, 119597, 77999, 77998, 0, 0, 0, 92967, 0, 3558, 0, 3913, 70429, + 121376, 0, 0, 1265, 0, 6309, 0, 12969, 0, 101151, 0, 101146, 0, 101139, + 0, 41864, 0, 0, 74294, 0, 167, 0, 917584, 0, 93983, 72354, 68477, 0, 0, + 917594, 0, 2493, 129827, 0, 129804, 0, 917570, 917593, 0, 0, 406, 917592, + 0, 0, 0, 0, 0, 0, 0, 127161, 0, 128597, 0, 0, 0, 3421, 10561, 0, 8365, + 917581, 0, 127569, 120787, 128669, 0, 0, 0, 0, 7834, 0, 0, 101154, 10298, + 6624, 4908, 0, 1639, 120842, 0, 0, 6327, 6724, 0, 0, 0, 69910, 4817, 0, + 0, 0, 68059, 0, 11022, 0, 0, 0, 118888, 0, 0, 7548, 64794, 0, 12291, + 983166, 0, 0, 0, 0, 0, 0, 1134, 1838, 0, 2057, 0, 0, 0, 0, 0, 0, 5206, 0, + 0, 42523, 0, 0, 0, 0, 65550, 8570, 4816, 0, 127926, 0, 4821, 0, 0, 0, + 4818, 125257, 119974, 119977, 0, 0, 119970, 119973, 0, 119983, 119982, + 67470, 119984, 119979, 119978, 0, 119980, 119670, 129297, 0, 11284, + 119987, 70097, 65155, 119988, 0, 9363, 0, 0, 0, 5900, 93990, 7889, 2722, + 128770, 0, 0, 0, 0, 2282, 0, 0, 0, 68093, 0, 0, 0, 0, 0, 70150, 118628, + 0, 0, 0, 129651, 70146, 983079, 119967, 71330, 70148, 0, 0, 94006, 70144, + 119964, 110677, 110678, 110675, 110676, 0, 110674, 4226, 0, 123165, 5732, + 71327, 0, 0, 65119, 0, 0, 92971, 64770, 0, 0, 6093, 0, 0, 1395, 0, 0, 0, + 121179, 786, 0, 43174, 64340, 0, 125269, 0, 983662, 125138, 10132, 0, 0, + 0, 0, 0, 93956, 0, 68444, 0, 92437, 123143, 0, 0, 92656, 0, 0, 0, 1399, + 121463, 0, 121465, 121464, 120808, 241, 121469, 4907, 0, 0, 0, 0, 0, 0, + 0, 0, 127904, 0, 0, 42780, 0, 0, 0, 4217, 0, 0, 0, 0, 72158, 0, 0, 43099, + 3965, 0, 0, 0, 13300, 0, 0, 43057, 0, 0, 0, 0, 0, 65372, 0, 6410, 126073, 125252, 70468, 0, 0, 0, 119558, 0, 0, 0, 0, 0, 0, 43188, 2626, 7762, 0, 0, 0, 127183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67726, 0, 126993, 1542, 0, 0, 92550, 0, 0, 74311, 0, 0, 10181, 2150, 0, 0, 0, 0, 124921, 68053, 6029, 72852, 0, 0, 0, 0, 8993, 0, 0, 0, 93968, 606, 118664, 0, 0, 0, 4311, 0, 6027, 126615, 4322, 0, 65207, 0, 2184, 983920, 0, 0, 2735, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 70806, 0, 0, 0, 92783, 92844, 0, 65817, 55288, 127934, - 66564, 8530, 0, 7709, 0, 121202, 66560, 128528, 917595, 12876, 66561, 0, - 121430, 983957, 7789, 5855, 809, 0, 0, 72853, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 64386, 0, 74909, 64845, 120607, 66416, 83360, 6532, 0, 0, 0, 0, - 128224, 0, 0, 0, 0, 43091, 92287, 0, 0, 129312, 0, 0, 0, 11361, 0, 0, - 8153, 128105, 0, 10741, 0, 0, 0, 0, 0, 64706, 917922, 0, 69505, 78870, + 0, 0, 0, 0, 0, 0, 70806, 0, 73547, 0, 92783, 92844, 0, 65817, 55288, + 127934, 66564, 8530, 0, 7709, 0, 121202, 66560, 128528, 917595, 12876, + 66561, 0, 121430, 983957, 7789, 5855, 809, 0, 0, 72853, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 64386, 0, 74909, 64845, 120607, 66416, 83360, 6532, 0, 0, + 0, 0, 128224, 0, 0, 0, 0, 43091, 92287, 0, 0, 129312, 0, 0, 0, 11361, 0, + 0, 8153, 128105, 0, 10741, 0, 0, 0, 0, 0, 64706, 917922, 0, 69505, 78870, 9466, 78866, 9824, 0, 0, 0, 120977, 915, 0, 0, 43865, 0, 0, 0, 67131, 70096, 67137, 0, 129614, 73648, 6730, 78862, 68161, 0, 78861, 126542, 0, 0, 94010, 118655, 0, 0, 66043, 0, 0, 43107, 0, 0, 92343, 0, 73879, 0, 0, @@ -27163,7 +27349,7 @@ static const unsigned int code_hash[] = { 0, 128273, 0, 0, 7379, 64581, 5386, 0, 0, 10633, 72316, 64488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124956, 71307, 0, 0, 0, 0, 0, 92370, 0, 0, 0, 0, 0, 71314, 1801, 0, 0, 120867, 0, 0, 77888, 2085, 702, 77887, 77884, 77885, - 13074, 77883, 66299, 0, 0, 12106, 0, 0, 1755, 0, 77897, 77898, 1163, + 13074, 77883, 66299, 0, 0, 12106, 78905, 0, 1755, 0, 77897, 77898, 1163, 3102, 77893, 77894, 0, 0, 0, 0, 69227, 0, 77901, 77902, 77899, 77900, 65171, 0, 0, 0, 70157, 0, 0, 0, 64846, 2908, 0, 11177, 64902, 64950, 0, 128740, 66906, 124959, 70499, 0, 0, 0, 64352, 0, 125031, 1007, 0, 9199, @@ -27183,70 +27369,71 @@ static const unsigned int code_hash[] = { 127233, 0, 0, 0, 92345, 68254, 983661, 77991, 0, 2724, 0, 0, 12313, 110619, 515, 119947, 119944, 119945, 119942, 119943, 119940, 119941, 119938, 8606, 4046, 4589, 4521, 0, 9141, 0, 0, 2741, 0, 0, 1370, 0, 0, 0, - 0, 0, 0, 66880, 0, 66003, 0, 64440, 0, 0, 69458, 0, 11593, 68669, 68666, - 68660, 0, 0, 2744, 72285, 68638, 0, 814, 0, 119962, 119963, 119960, - 119961, 101106, 43029, 119956, 11623, 119954, 11955, 119952, 119953, - 41986, 119951, 0, 120497, 4847, 110975, 0, 0, 0, 0, 1581, 64920, 93830, - 12954, 963, 110973, 110972, 110971, 110969, 5278, 110967, 68621, 92222, - 983451, 68625, 983449, 68617, 110960, 0, 101459, 101487, 110964, 110963, - 110962, 0, 0, 101464, 101483, 101463, 983440, 983437, 92648, 127379, 0, - 65137, 6483, 65392, 0, 4213, 129649, 41303, 0, 0, 0, 41306, 129751, 2698, - 0, 0, 0, 68396, 0, 41304, 824, 0, 78011, 72315, 78894, 74827, 78892, - 64804, 9820, 119820, 110985, 110976, 0, 6739, 0, 5481, 3490, 110978, - 110977, 71706, 69947, 67702, 9124, 12688, 119833, 101496, 0, 101495, - 119821, 119824, 67480, 42575, 101474, 101478, 119827, 101481, 101476, - 71087, 68658, 119946, 8025, 68630, 101490, 68675, 92445, 71097, 69613, 0, - 0, 0, 0, 983432, 2745, 11797, 110990, 983428, 9202, 983426, 983427, 0, 0, - 0, 10525, 5436, 74584, 110987, 110986, 121506, 43080, 121508, 121507, - 983417, 6246, 119958, 10921, 9723, 6777, 6776, 6775, 0, 0, 70287, 92384, - 0, 8669, 0, 0, 65093, 0, 78881, 2716, 0, 0, 11252, 101475, 68369, 0, - 11060, 12985, 2711, 78872, 78027, 78026, 7992, 0, 0, 42938, 78033, 78032, - 78877, 70724, 78029, 78028, 78031, 78030, 64535, 110998, 10130, 110996, - 0, 0, 111001, 111000, 127914, 983414, 78014, 5713, 110995, 7570, 110993, - 110992, 0, 11190, 129700, 9026, 0, 74864, 7547, 78891, 0, 10008, 10222, - 0, 129543, 9744, 0, 68809, 983410, 119656, 983408, 94070, 983406, 983407, - 983404, 9045, 78888, 4225, 78886, 78887, 68757, 78885, 78882, 78883, - 983399, 983400, 8405, 983398, 10423, 10359, 983393, 983394, 0, 129149, - 4215, 9789, 0, 4321, 12309, 983402, 41313, 0, 5368, 66886, 0, 0, 5366, 0, - 5372, 101482, 67512, 0, 7720, 7390, 2696, 0, 0, 8268, 0, 1790, 0, 0, - 118977, 0, 0, 0, 5376, 1835, 72313, 78704, 128089, 0, 0, 68655, 1180, 0, - 0, 0, 0, 119274, 0, 0, 9122, 118584, 11928, 0, 65283, 0, 101449, 5971, - 101448, 43500, 1268, 65097, 983219, 0, 101445, 0, 1427, 128440, 0, 5970, - 3431, 72299, 101439, 101435, 983386, 983387, 983384, 2738, 125066, 10455, - 0, 74026, 0, 4222, 6240, 0, 119013, 983391, 68377, 6248, 983375, 67815, - 983373, 917907, 92582, 0, 101453, 125215, 0, 2728, 65549, 64563, 101428, - 101425, 101429, 128145, 0, 10713, 7166, 119559, 2622, 101450, 0, 0, 0, - 8954, 0, 94008, 2632, 42617, 10108, 1011, 42852, 12080, 2709, 0, 5716, 0, - 0, 0, 0, 127100, 69378, 0, 9515, 127098, 66465, 6451, 0, 127097, 8918, - 983556, 0, 0, 19950, 0, 0, 0, 44003, 0, 64735, 0, 0, 0, 0, 983497, 74022, - 0, 128795, 68643, 67410, 0, 5721, 0, 0, 0, 121074, 11267, 983366, 66464, - 5720, 983365, 0, 4219, 5718, 8696, 5717, 122651, 983372, 983897, 983370, - 541, 983368, 983369, 119948, 119089, 68389, 983354, 119949, 56, 4216, - 10577, 0, 0, 77849, 69620, 983359, 983360, 66899, 983358, 0, 0, 67628, 0, - 0, 7086, 0, 67998, 67621, 0, 2734, 69616, 0, 67627, 118937, 0, 67625, 0, - 0, 0, 42593, 0, 128217, 0, 0, 119939, 0, 68180, 0, 0, 71104, 7442, 43665, - 359, 41253, 68392, 6239, 120599, 41256, 0, 67740, 111023, 111022, 111021, - 9346, 69660, 41254, 0, 43291, 78002, 0, 67491, 124993, 93841, 0, 0, 0, - 4368, 983502, 0, 68137, 0, 0, 41024, 0, 0, 121359, 121420, 0, 0, 0, 4223, - 0, 8574, 83502, 0, 0, 0, 118576, 0, 92718, 983636, 70432, 128323, 68382, - 0, 0, 0, 0, 0, 4144, 0, 83193, 6245, 0, 2732, 92644, 0, 0, 64558, 83501, - 0, 0, 0, 128005, 0, 0, 129652, 983148, 3097, 0, 0, 77996, 0, 0, 10863, - 111020, 111019, 111018, 0, 111015, 111014, 111013, 111012, 118964, 0, - 10216, 64293, 0, 0, 69393, 128331, 12325, 111010, 8717, 111008, 101413, - 0, 101380, 0, 8700, 0, 101382, 68363, 10426, 0, 71091, 10362, 0, 1715, - 101378, 0, 64918, 101409, 43278, 42635, 0, 0, 65275, 0, 0, 101319, 0, - 69746, 1607, 466, 118949, 0, 0, 127918, 6243, 983901, 1350, 74195, 64420, - 1993, 5362, 10666, 2708, 92471, 0, 13143, 234, 3199, 0, 41268, 6334, - 2173, 0, 0, 73750, 0, 73762, 10458, 0, 8576, 127136, 0, 2704, 64953, 0, - 64832, 8322, 0, 3132, 0, 2694, 0, 0, 2439, 65104, 69804, 0, 303, 74625, - 92622, 0, 2437, 0, 9817, 4844, 0, 0, 0, 0, 0, 121120, 43292, 0, 2441, 0, - 0, 0, 0, 0, 2451, 2714, 0, 0, 43379, 127984, 74541, 753, 5849, 0, 43089, - 0, 0, 119534, 72380, 0, 0, 0, 2726, 3107, 0, 0, 64937, 0, 78841, 1408, 0, - 4607, 101299, 181, 0, 67728, 9539, 0, 0, 65201, 121121, 92973, 64185, - 4142, 64183, 0, 0, 0, 9706, 64178, 64177, 64176, 0, 64182, 64181, 64180, - 64179, 11401, 125124, 0, 1822, 0, 128581, 68055, 3865, 122918, 0, 10500, - 129602, 119024, 0, 110732, 9830, 0, 0, 0, 65131, 0, 0, 0, 0, 74608, 7038, - 0, 9599, 8748, 0, 0, 9557, 0, 0, 0, 11494, 0, 0, 10865, 0, 43279, 64186, + 0, 0, 0, 66880, 0, 66003, 0, 64440, 0, 129943, 69458, 0, 11593, 68669, + 68666, 68660, 0, 0, 2744, 72285, 68638, 0, 814, 0, 119962, 119963, + 119960, 119961, 101106, 43029, 119956, 11623, 119954, 11955, 119952, + 119953, 41986, 119951, 0, 120497, 4847, 110975, 0, 0, 0, 0, 1581, 64920, + 93830, 12954, 963, 110973, 110972, 110971, 110969, 5278, 110967, 68621, + 92222, 983454, 68625, 983452, 68617, 110960, 0, 101459, 101487, 110964, + 110963, 110962, 0, 0, 101464, 101483, 101463, 983443, 983440, 92648, + 127379, 0, 65137, 6483, 65392, 0, 4213, 129649, 41303, 0, 0, 0, 41306, + 129751, 2698, 0, 0, 0, 68396, 0, 41304, 824, 0, 78011, 72315, 78894, + 74827, 78892, 64804, 9820, 119820, 110985, 110976, 0, 6739, 0, 5481, + 3490, 110978, 110977, 71706, 69947, 67702, 9124, 12688, 119833, 101496, + 0, 101495, 119821, 119824, 67480, 42575, 101474, 101478, 119827, 101481, + 101476, 71087, 68658, 119946, 8025, 68630, 101490, 68675, 92445, 71097, + 69613, 0, 0, 0, 0, 983435, 2745, 11797, 110990, 983431, 9202, 983429, + 983430, 0, 0, 0, 10525, 5436, 74584, 110987, 110986, 121506, 43080, + 121508, 121507, 983420, 6246, 119958, 10921, 9723, 6777, 6776, 6775, 0, + 0, 70287, 92384, 0, 8669, 0, 0, 65093, 0, 78881, 2716, 0, 0, 11252, + 101475, 68369, 0, 11060, 12985, 2711, 78872, 78027, 78026, 7992, 0, 0, + 42938, 78033, 78032, 78877, 70724, 78029, 78028, 78031, 78030, 64535, + 110998, 10130, 110996, 0, 0, 111001, 111000, 127914, 983417, 78014, 5713, + 110995, 7570, 110993, 110992, 0, 11190, 129700, 9026, 0, 74864, 7547, + 78891, 0, 10008, 10222, 0, 129543, 9744, 0, 68809, 983413, 119656, + 983411, 94070, 983409, 983410, 983407, 9045, 78888, 4225, 78886, 78887, + 68757, 78885, 78882, 78883, 983402, 983403, 8405, 983401, 10423, 10359, + 983396, 983397, 0, 129149, 4215, 9789, 0, 4321, 12309, 983405, 41313, 0, + 5368, 66886, 0, 0, 5366, 0, 5372, 101482, 67512, 0, 7720, 7390, 2696, 0, + 0, 8268, 0, 1790, 0, 0, 118977, 0, 0, 0, 5376, 1835, 72313, 78704, + 128089, 0, 0, 68655, 1180, 0, 0, 0, 0, 119274, 0, 0, 9122, 118584, 11928, + 0, 65283, 0, 101449, 5971, 101448, 43500, 1268, 65097, 983222, 0, 101445, + 0, 1427, 128440, 0, 5970, 3431, 72299, 101439, 101435, 983389, 983390, + 983387, 2738, 125066, 10455, 0, 74026, 0, 4222, 6240, 0, 119013, 983394, + 68377, 6248, 983378, 67815, 983376, 917907, 92582, 0, 101453, 125215, 0, + 2728, 65549, 64563, 101428, 101425, 101429, 128145, 0, 10713, 7166, + 119559, 2622, 101450, 0, 0, 0, 8954, 0, 94008, 2632, 42617, 10108, 1011, + 42852, 12080, 2709, 0, 5716, 0, 0, 0, 0, 127100, 69378, 0, 9515, 127098, + 66465, 6451, 0, 127097, 8918, 983556, 0, 0, 19950, 0, 0, 0, 44003, 0, + 64735, 0, 0, 0, 0, 983500, 74022, 0, 128795, 68643, 67410, 0, 5721, 0, 0, + 0, 121074, 11267, 983369, 66464, 5720, 983368, 0, 4219, 5718, 8696, 5717, + 122651, 983375, 983897, 983373, 541, 983371, 983372, 119948, 119089, + 68389, 983357, 119949, 56, 4216, 10577, 0, 0, 77849, 69620, 983362, + 983363, 66899, 983361, 0, 0, 67628, 0, 0, 7086, 0, 67998, 67621, 0, 2734, + 69616, 0, 67627, 118937, 0, 67625, 0, 0, 0, 42593, 0, 128217, 0, 0, + 119939, 0, 68180, 0, 0, 71104, 7442, 43665, 359, 41253, 68392, 6239, + 120599, 41256, 0, 67740, 111023, 111022, 111021, 9346, 69660, 41254, 0, + 43291, 78002, 0, 67491, 124993, 93841, 0, 0, 0, 4368, 983505, 0, 68137, + 0, 0, 41024, 0, 0, 121359, 121420, 0, 0, 0, 4223, 0, 8574, 83502, 0, 0, + 0, 118576, 0, 92718, 983636, 70432, 128323, 68382, 0, 0, 0, 0, 0, 4144, + 0, 83193, 6245, 0, 2732, 92644, 0, 0, 64558, 83501, 0, 0, 0, 128005, 0, + 0, 129652, 983149, 3097, 0, 0, 77996, 0, 0, 10863, 111020, 111019, + 111018, 0, 111015, 111014, 111013, 111012, 118964, 0, 10216, 64293, 0, 0, + 69393, 128331, 12325, 111010, 8717, 111008, 101413, 0, 101380, 0, 8700, + 0, 101382, 68363, 10426, 0, 71091, 10362, 0, 1715, 101378, 0, 64918, + 101409, 43278, 42635, 0, 0, 65275, 0, 0, 101319, 0, 69746, 1607, 466, + 118949, 0, 0, 127918, 6243, 983901, 1350, 74195, 64420, 1993, 5362, + 10666, 2708, 92471, 0, 13143, 234, 3199, 0, 41268, 6334, 2173, 0, 0, + 73750, 0, 73762, 10458, 0, 8576, 127136, 0, 2704, 64953, 0, 64832, 8322, + 0, 3132, 0, 2694, 0, 0, 2439, 65104, 69804, 0, 303, 74625, 92622, 0, + 2437, 0, 9817, 4844, 0, 0, 0, 0, 0, 121120, 43292, 0, 2441, 0, 0, 0, 0, + 0, 2451, 2714, 0, 0, 43379, 127984, 74541, 753, 5849, 0, 43089, 0, 0, + 119534, 72380, 0, 0, 0, 2726, 3107, 0, 0, 64937, 0, 78841, 1408, 0, 4607, + 101299, 181, 0, 67728, 9539, 0, 0, 65201, 121121, 92973, 64185, 4142, + 64183, 0, 0, 0, 9706, 64178, 64177, 64176, 0, 64182, 64181, 64180, 64179, + 11401, 125124, 0, 1822, 0, 128581, 68055, 3865, 122918, 0, 10500, 129602, + 119024, 0, 110732, 9830, 0, 0, 0, 65131, 0, 0, 0, 0, 74608, 7038, 0, + 9599, 8748, 0, 0, 9557, 0, 0, 0, 11494, 0, 0, 10865, 0, 43279, 64186, 68521, 0, 64191, 64190, 8898, 64188, 129153, 41030, 78836, 0, 0, 78820, 126100, 0, 78805, 78806, 78801, 78802, 6745, 78800, 0, 0, 0, 110866, 0, 0, 73679, 67838, 41039, 78809, 128162, 0, 129893, 0, 110869, 127045, @@ -27265,78 +27452,79 @@ static const unsigned int code_hash[] = { 0, 0, 0, 83484, 83485, 83486, 83487, 83480, 8355, 7854, 83483, 954, 64927, 0, 41045, 0, 41438, 0, 0, 10711, 0, 0, 0, 0, 64774, 13309, 10947, 66727, 101426, 0, 0, 66795, 0, 0, 0, 0, 0, 0, 0, 120634, 69228, 0, 0, 0, - 0, 0, 0, 3060, 83478, 9986, 0, 83473, 83474, 11698, 77880, 83469, 9916, - 11701, 83472, 42586, 0, 8320, 0, 119095, 0, 0, 1477, 43289, 0, 74358, - 10884, 69446, 9908, 0, 0, 0, 3414, 74304, 0, 0, 0, 0, 2110, 0, 68306, 0, - 74532, 0, 129865, 0, 0, 7164, 0, 0, 0, 11950, 5392, 42248, 65129, 68656, - 5397, 129579, 0, 68136, 0, 0, 5395, 72870, 5393, 354, 68615, 0, 0, 0, 0, - 0, 126236, 0, 0, 626, 0, 5895, 0, 0, 5780, 0, 66407, 10220, 0, 71121, - 43297, 0, 0, 11468, 64436, 0, 0, 0, 73818, 3918, 0, 3797, 72786, 0, 0, - 4140, 0, 71254, 0, 9030, 813, 0, 68131, 4146, 119957, 5360, 0, 129498, 0, - 0, 6249, 0, 0, 0, 0, 0, 73092, 0, 4911, 988, 0, 73125, 0, 42948, 0, 0, 0, - 0, 74972, 0, 0, 0, 9825, 0, 0, 12803, 126977, 11032, 67654, 6244, 0, 0, - 68662, 0, 129351, 0, 72131, 4169, 0, 0, 0, 129986, 121410, 120657, 0, 0, - 68657, 128943, 78496, 0, 0, 5898, 74540, 0, 41856, 93056, 194926, 118538, - 127373, 83424, 83425, 83426, 73736, 83420, 68870, 6448, 6835, 0, 4831, - 83418, 83419, 67731, 0, 0, 0, 0, 0, 0, 0, 78499, 0, 0, 0, 43288, 0, 0, 0, - 0, 0, 43418, 0, 0, 0, 7876, 68132, 917872, 0, 917870, 43378, 0, 0, - 120890, 5892, 43605, 0, 0, 0, 129058, 0, 0, 6251, 83409, 83410, 83411, - 83412, 126512, 0, 71092, 83408, 10114, 0, 0, 5387, 0, 0, 0, 0, 65553, - 78346, 1747, 917849, 65109, 69240, 917852, 126509, 0, 0, 0, 0, 125065, 0, - 9850, 0, 367, 1472, 917859, 6687, 0, 0, 5905, 12339, 8919, 73953, 65680, - 0, 2204, 78664, 0, 9134, 118589, 78666, 43011, 0, 126626, 0, 0, 0, 43013, - 10614, 0, 0, 83413, 66646, 83415, 83416, 0, 73881, 43012, 121127, 83293, - 54, 43009, 73885, 0, 6211, 0, 0, 83295, 68119, 43008, 10758, 0, 0, 0, 0, - 0, 70018, 0, 0, 0, 0, 12765, 0, 0, 0, 0, 126580, 0, 0, 43657, 0, 0, 0, - 983737, 0, 83405, 917843, 0, 0, 83401, 83402, 83403, 83404, 83397, 11363, - 12057, 83400, 1567, 0, 0, 83396, 0, 8957, 4139, 0, 0, 129336, 0, 0, - 12740, 0, 92195, 12761, 127793, 12759, 0, 72304, 67169, 83467, 44002, 0, - 83462, 83463, 83464, 12755, 12762, 41022, 67690, 64217, 476, 0, 983734, - 0, 64212, 41020, 1382, 64209, 64216, 64215, 64214, 64213, 0, 0, 0, 67584, - 8720, 3908, 0, 0, 0, 0, 101529, 129576, 0, 0, 3849, 92324, 94026, 9778, - 917906, 5891, 917912, 55, 917910, 917911, 0, 0, 7935, 67586, 0, 1114, - 92599, 67585, 78675, 0, 83447, 83449, 0, 0, 0, 64717, 0, 0, 0, 66884, - 6292, 65303, 0, 6452, 917886, 917887, 66249, 917885, 917890, 917891, - 917888, 719, 101446, 0, 917892, 0, 0, 0, 94083, 10868, 121333, 2349, - 5902, 917896, 6335, 101350, 917899, 917900, 0, 64369, 0, 0, 0, 69245, 0, + 0, 101430, 0, 3060, 83478, 9986, 0, 83473, 83474, 11698, 77880, 83469, + 9916, 11701, 83472, 42586, 0, 8320, 0, 119095, 0, 0, 1477, 43289, 0, + 74358, 10884, 69446, 9908, 0, 0, 0, 3414, 74304, 0, 0, 0, 0, 2110, 0, + 68306, 0, 74532, 0, 129865, 0, 0, 7164, 0, 0, 0, 11950, 5392, 42248, + 65129, 68656, 5397, 129579, 0, 68136, 0, 0, 5395, 72870, 5393, 354, + 68615, 0, 0, 0, 0, 0, 126236, 0, 0, 626, 0, 5895, 0, 0, 5780, 0, 66407, + 10220, 0, 71121, 43297, 0, 0, 11468, 64436, 0, 0, 0, 73818, 3918, 0, + 3797, 72786, 122961, 0, 4140, 0, 71254, 0, 9030, 813, 0, 68131, 4146, + 119957, 5360, 0, 129498, 0, 0, 6249, 0, 0, 0, 0, 0, 73092, 0, 4911, 988, + 0, 73125, 0, 42948, 0, 0, 0, 0, 74972, 0, 0, 0, 9825, 0, 0, 12803, + 126977, 11032, 67654, 6244, 0, 0, 68662, 0, 129351, 0, 72131, 4169, 0, 0, + 0, 129986, 121410, 120657, 0, 0, 68657, 128943, 78496, 0, 0, 5898, 74540, + 0, 41856, 93056, 194926, 118538, 127373, 83424, 83425, 83426, 73736, + 83420, 68870, 6448, 6835, 0, 4831, 83418, 83419, 67731, 0, 0, 0, 0, 0, 0, + 0, 78499, 0, 0, 0, 43288, 122931, 0, 0, 0, 0, 43418, 0, 0, 0, 7876, + 68132, 917872, 0, 917870, 43378, 0, 0, 120890, 5892, 43605, 0, 0, 0, + 129058, 0, 0, 6251, 83409, 83410, 83411, 83412, 126512, 0, 71092, 83408, + 10114, 0, 0, 5387, 0, 0, 0, 0, 65553, 78346, 1747, 917849, 65109, 69240, + 917852, 126509, 0, 0, 0, 0, 125065, 0, 9850, 0, 367, 1472, 917859, 6687, + 0, 0, 5905, 12339, 8919, 73953, 65680, 0, 2204, 78664, 0, 9134, 118589, + 78666, 43011, 0, 126626, 0, 0, 0, 43013, 10614, 0, 0, 83413, 66646, + 83415, 83416, 0, 73881, 43012, 121127, 83293, 54, 43009, 73885, 0, 6211, + 0, 0, 83295, 68119, 43008, 10758, 0, 0, 0, 0, 0, 70018, 0, 0, 0, 0, + 12765, 0, 0, 0, 0, 126580, 0, 0, 43657, 0, 0, 0, 983737, 0, 83405, + 917843, 0, 0, 83401, 83402, 83403, 83404, 83397, 11363, 12057, 83400, + 1567, 0, 0, 83396, 0, 8957, 4139, 0, 0, 129336, 0, 0, 12740, 0, 92195, + 12761, 127793, 12759, 0, 72304, 67169, 83467, 44002, 0, 83462, 83463, + 83464, 12755, 12762, 41022, 67690, 64217, 476, 0, 983734, 0, 64212, + 41020, 1382, 64209, 64216, 64215, 64214, 64213, 0, 0, 0, 67584, 8720, + 3908, 0, 0, 0, 0, 101529, 129576, 0, 0, 3849, 92324, 94026, 9778, 917906, + 5891, 917912, 55, 917910, 917911, 0, 0, 7935, 67586, 0, 1114, 92599, + 67585, 78675, 0, 83447, 83449, 0, 0, 0, 64717, 0, 0, 0, 66884, 6292, + 65303, 0, 6452, 917886, 917887, 66249, 917885, 917890, 917891, 917888, + 719, 101446, 0, 917892, 0, 0, 0, 94083, 10868, 121333, 2349, 5902, + 917896, 6335, 101350, 917899, 917900, 0, 64369, 0, 0, 0, 69245, 0, 126564, 0, 0, 128565, 0, 0, 0, 0, 0, 6454, 1229, 83457, 83458, 83450, 83451, 83452, 65100, 120508, 8224, 917873, 917874, 917879, 917880, 917877, 917878, 128929, 0, 917881, 917882, 5365, 67836, 8901, 0, 0, 129951, 0, 69257, 5925, 83436, 64330, 128400, 83431, 83432, 83433, 83434, 83427, 83428, 83429, 83430, 64928, 10543, 0, 0, 83446, 414, 0, 0, 83442, 6456, 71490, 83445, 11905, 83439, 66284, 83441, 0, 68337, 0, 83437, - 43832, 983139, 9751, 0, 128085, 11770, 0, 0, 69600, 65061, 0, 0, 0, 0, 0, + 43832, 983140, 9751, 0, 128085, 11770, 0, 0, 69600, 65061, 0, 0, 0, 0, 0, 0, 121087, 0, 0, 69924, 0, 0, 0, 69913, 0, 121387, 101513, 101504, 101512, 42038, 387, 0, 12737, 0, 0, 43368, 0, 0, 0, 0, 129713, 129449, 121295, 0, 69400, 127309, 0, 375, 0, 0, 0, 983905, 0, 0, 119202, 119203, - 0, 43120, 0, 0, 119196, 119197, 0, 4529, 119200, 119201, 119198, 119199, - 0, 0, 69698, 13150, 64492, 0, 0, 0, 0, 0, 42891, 66327, 74298, 0, 0, 0, - 2587, 42193, 0, 6455, 0, 4241, 0, 0, 0, 0, 0, 0, 0, 118821, 0, 0, 0, - 125030, 0, 128684, 129390, 6988, 5373, 0, 0, 119232, 10015, 0, 0, 0, + 124117, 43120, 0, 0, 119196, 119197, 0, 4529, 119200, 119201, 119198, + 119199, 0, 0, 69698, 13150, 64492, 0, 0, 0, 0, 0, 42891, 66327, 74298, 0, + 0, 0, 2587, 42193, 0, 6455, 0, 4241, 0, 0, 0, 0, 0, 0, 0, 118821, 0, 0, + 0, 125030, 0, 128684, 129390, 6988, 5373, 0, 0, 119232, 10015, 0, 0, 0, 68642, 0, 120855, 42040, 128827, 5779, 129841, 42037, 83282, 0, 0, 93040, 83283, 101116, 0, 101117, 6983, 0, 0, 101115, 0, 0, 0, 127323, 101111, 0, 119588, 0, 92495, 74558, 0, 68138, 70163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 11144, 0, 2551, 0, 6453, 0, 6235, 0, 0, 129081, 72886, 44020, 11826, 0, - 7780, 5369, 118958, 0, 0, 5367, 66870, 0, 0, 5377, 0, 68143, 128624, - 78245, 5218, 0, 127333, 0, 0, 129717, 0, 0, 1300, 0, 127334, 64505, 0, 0, - 119624, 1465, 0, 127316, 0, 0, 0, 101109, 0, 113694, 10729, 0, 0, 8839, - 119243, 0, 7785, 126530, 0, 0, 0, 0, 118638, 0, 0, 0, 3897, 0, 92331, - 74417, 113704, 0, 68127, 71425, 70688, 0, 0, 0, 0, 69287, 3542, 0, - 120685, 7951, 68152, 118857, 0, 92972, 0, 0, 127311, 73683, 0, 65150, + 11144, 73484, 2551, 73482, 6453, 0, 6235, 0, 0, 129081, 72886, 44020, + 11826, 0, 7780, 5369, 118958, 0, 0, 5367, 66870, 0, 0, 5377, 0, 68143, + 128624, 78245, 5218, 0, 127333, 0, 0, 129717, 0, 0, 1300, 0, 127334, + 64505, 0, 0, 119624, 1465, 0, 127316, 0, 0, 0, 101109, 0, 113694, 10729, + 0, 0, 8839, 119243, 0, 7785, 126530, 0, 0, 0, 0, 118638, 0, 0, 0, 3897, + 0, 92331, 74417, 113704, 0, 68127, 71425, 70688, 0, 0, 0, 0, 69287, 3542, + 0, 120685, 7951, 68152, 118857, 0, 92972, 0, 0, 127311, 73683, 0, 65150, 68031, 0, 0, 0, 0, 9985, 0, 127328, 0, 0, 0, 0, 10830, 0, 615, 64490, 7574, 0, 0, 0, 12909, 73698, 64559, 127332, 73951, 0, 67996, 2020, 0, 0, 0, 120701, 0, 983640, 0, 0, 0, 92991, 0, 0, 9070, 0, 68411, 11281, 42829, - 0, 1033, 0, 0, 0, 118610, 0, 65226, 0, 0, 0, 0, 0, 3450, 0, 7397, 0, 0, - 42778, 10000, 41088, 449, 0, 0, 68458, 113725, 0, 0, 10738, 69634, 0, 0, - 41085, 0, 0, 0, 12764, 0, 93058, 3596, 7322, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1033, 0, 78918, 0, 118610, 0, 65226, 0, 0, 0, 0, 0, 3450, 0, 7397, 0, + 0, 42778, 10000, 41088, 449, 0, 0, 68458, 113725, 0, 0, 10738, 69634, 0, + 0, 41085, 0, 0, 0, 12764, 0, 93058, 3596, 7322, 0, 0, 0, 0, 0, 0, 0, 0, 2092, 0, 0, 0, 121350, 10820, 0, 0, 126567, 1853, 0, 0, 93014, 0, 12770, 0, 0, 124997, 0, 0, 0, 0, 0, 129053, 4828, 1258, 0, 2006, 0, 0, 74285, 127987, 0, 120683, 122880, 983900, 983903, 8846, 128255, 0, 128091, 2650, 9182, 1961, 121399, 11525, 0, 1959, 0, 55228, 11774, 41016, 0, 0, 128054, 41017, 13109, 0, 10519, 66331, 3454, 19930, 0, 41019, 92894, 0, 0, 78362, 41021, 101566, 0, 0, 0, 0, 65531, 0, 0, 0, 0, 0, 0, 8865, 6402, 113827, - 77923, 0, 101536, 0, 7733, 0, 4998, 68493, 0, 0, 0, 4268, 101368, 0, 0, - 101555, 101579, 10881, 0, 0, 0, 0, 2014, 0, 71901, 0, 0, 195057, 0, 0, + 77923, 0, 101536, 0, 7733, 0, 4998, 68493, 0, 78930, 0, 4268, 101368, 0, + 0, 101555, 101579, 10881, 0, 0, 0, 0, 2014, 0, 71901, 0, 0, 195057, 0, 0, 78357, 65281, 0, 0, 0, 0, 0, 2015, 0, 0, 71840, 66318, 74824, 101575, 0, 101574, 101569, 0, 70061, 8094, 10135, 101551, 0, 794, 0, 0, 66335, 0, 121303, 4343, 0, 4833, 0, 0, 0, 0, 189, 12611, 0, 72215, 0, 4838, 126214, @@ -27356,143 +27544,144 @@ static const unsigned int code_hash[] = { 0, 0, 121068, 92418, 0, 0, 0, 43280, 0, 70718, 1812, 0, 73046, 0, 0, 0, 0, 0, 6054, 10697, 3169, 0, 0, 70720, 11487, 70712, 0, 0, 0, 194716, 0, 0, 41863, 0, 0, 2304, 0, 92326, 0, 42951, 0, 0, 64760, 11766, 0, 0, 0, 0, - 69236, 0, 0, 8773, 10733, 36, 0, 0, 0, 0, 0, 11074, 0, 64910, 983130, - 2009, 0, 0, 128036, 68114, 128906, 0, 0, 0, 983998, 12852, 3031, 0, 0, - 129088, 0, 66414, 0, 0, 119950, 42613, 65933, 366, 0, 9892, 0, 11754, - 101107, 83329, 65301, 44013, 83058, 67245, 10102, 0, 7739, 41026, 0, 0, - 0, 0, 0, 0, 0, 0, 78386, 129475, 71868, 113811, 13081, 10923, 129330, 0, - 68145, 0, 65861, 74083, 0, 0, 128392, 83063, 83065, 0, 70706, 0, 0, 0, - 70168, 66586, 4183, 64967, 66250, 0, 92547, 0, 0, 113685, 0, 3792, 2011, - 0, 0, 77748, 83332, 77749, 120595, 0, 68489, 41023, 77747, 0, 11659, - 7922, 12614, 2005, 8523, 0, 0, 7513, 1863, 129436, 83337, 128969, 0, - 120274, 120033, 0, 8144, 0, 73031, 77767, 127524, 120270, 42241, 8783, - 77764, 77765, 77766, 77760, 77761, 77762, 77763, 0, 10680, 0, 43293, - 68771, 0, 119164, 83320, 72003, 10187, 77742, 77743, 0, 77737, 77738, - 77739, 0, 10968, 43296, 119044, 0, 0, 101400, 0, 1005, 43826, 120030, 0, - 2870, 0, 101399, 0, 0, 983798, 0, 235, 1384, 77758, 74887, 70494, 77754, - 77755, 9796, 69895, 77750, 77751, 77752, 13186, 120407, 120250, 0, 0, 0, - 42527, 12911, 43427, 1383, 983581, 0, 0, 0, 6156, 68117, 0, 7993, 4288, - 0, 0, 13238, 13244, 0, 0, 120426, 13234, 120427, 0, 118904, 0, 11364, 0, - 1380, 65617, 120253, 120261, 13196, 13197, 120311, 120419, 9495, 0, 0, - 120418, 0, 73976, 128160, 0, 6941, 0, 13205, 13211, 5801, 0, 74271, - 120319, 0, 120302, 7670, 0, 68075, 983583, 0, 19957, 72314, 2021, 93811, - 43877, 0, 0, 0, 0, 3875, 120431, 64341, 0, 9814, 43457, 13066, 3314, - 7787, 0, 0, 0, 0, 0, 0, 64531, 129860, 0, 0, 0, 0, 0, 127138, 0, 0, 9742, - 0, 0, 10800, 77718, 8404, 0, 92592, 77714, 7089, 77716, 78545, 0, 77712, - 77713, 0, 0, 4772, 5771, 101405, 0, 9841, 8843, 0, 0, 0, 129862, 120816, - 0, 123137, 0, 77735, 0, 0, 0, 77731, 8849, 77733, 77734, 65112, 1796, - 77729, 77730, 69665, 8164, 41301, 3502, 0, 122884, 128387, 0, 983835, - 5825, 0, 0, 0, 0, 121322, 10983, 10354, 10418, 0, 2022, 0, 1409, 100789, - 0, 0, 0, 0, 1390, 0, 0, 10471, 65904, 5846, 126472, 0, 0, 0, 0, 0, 0, - 66035, 77725, 0, 77726, 77720, 77721, 67458, 3168, 67733, 0, 0, 2370, 0, - 126243, 0, 195049, 0, 0, 1836, 0, 121207, 119137, 118959, 125232, 0, 0, - 0, 2390, 3944, 0, 0, 0, 0, 69908, 125011, 0, 0, 123200, 0, 0, 8975, - 64739, 0, 0, 0, 0, 64409, 0, 0, 0, 0, 128564, 0, 0, 0, 0, 6204, 0, 0, 0, - 10911, 64954, 119003, 74809, 118903, 4267, 0, 0, 0, 0, 0, 0, 72023, 0, 0, - 0, 92887, 0, 0, 0, 0, 121125, 0, 128337, 5842, 0, 41439, 0, 0, 0, 9328, - 0, 120980, 120917, 0, 0, 2285, 0, 0, 0, 0, 118634, 64555, 0, 0, 72162, - 9541, 0, 0, 0, 41441, 0, 0, 0, 41040, 2459, 0, 0, 41041, 0, 0, 0, 0, 0, - 10450, 0, 41043, 0, 0, 43125, 0, 0, 0, 0, 0, 121008, 68436, 128040, 0, - 120649, 0, 0, 4312, 43927, 0, 0, 11923, 42227, 0, 5763, 0, 4827, 74559, - 42228, 64406, 0, 0, 129703, 433, 119620, 0, 2499, 67167, 67166, 0, 11973, - 0, 4293, 42271, 42224, 0, 0, 66322, 42226, 0, 0, 0, 74180, 0, 55277, 0, - 0, 0, 119317, 0, 74632, 0, 0, 71103, 0, 0, 0, 585, 2383, 0, 43263, 0, - 4290, 64842, 0, 68920, 0, 8511, 0, 0, 0, 119048, 2380, 126119, 0, 71704, - 2376, 0, 0, 0, 5197, 127046, 127047, 127048, 2366, 127050, 127051, 73442, - 0, 0, 0, 93835, 0, 93818, 0, 0, 74188, 113813, 0, 0, 0, 983838, 0, 0, 0, - 0, 1847, 0, 72771, 0, 42384, 0, 4227, 74158, 0, 92501, 0, 0, 42365, 0, - 128902, 0, 92821, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128563, 0, 983506, 127560, - 2754, 0, 0, 128900, 0, 127867, 119638, 0, 1711, 12984, 92365, 77776, - 6255, 77770, 77771, 77772, 77773, 0, 42063, 74184, 0, 0, 0, 0, 0, 77785, - 77786, 41035, 43274, 77781, 11256, 77783, 77784, 520, 77778, 41037, - 77780, 0, 0, 41034, 0, 983829, 64815, 0, 0, 321, 41028, 0, 0, 0, 0, 0, 0, - 0, 74191, 0, 0, 72767, 1861, 118938, 129666, 0, 0, 100770, 0, 0, 128530, - 3859, 0, 41660, 0, 70793, 0, 983756, 75014, 0, 127514, 41658, 0, 0, 0, 0, - 0, 4414, 77769, 0, 42632, 0, 0, 0, 0, 0, 1405, 0, 43220, 43341, 0, 0, 0, - 0, 0, 983733, 11199, 0, 3513, 0, 70341, 43342, 0, 65529, 0, 0, 0, 6485, - 1397, 0, 0, 92678, 118566, 0, 0, 82961, 0, 82962, 0, 74270, 43287, - 983731, 0, 0, 983738, 0, 71914, 4317, 10490, 0, 0, 194867, 74463, 128952, - 464, 41624, 0, 0, 0, 1346, 128240, 69271, 64724, 128566, 423, 0, 0, - 113748, 0, 128161, 0, 0, 120563, 64960, 0, 0, 0, 0, 9584, 77795, 77796, - 125026, 0, 9718, 77792, 42642, 77794, 64750, 77789, 77790, 0, 0, 128333, - 0, 3204, 64666, 0, 43530, 2752, 0, 0, 119594, 0, 0, 0, 0, 92371, 0, - 41983, 0, 7010, 0, 0, 41495, 92379, 5877, 42252, 93070, 8009, 3305, 0, 0, - 0, 0, 92293, 0, 0, 0, 100836, 0, 65915, 1400, 75018, 10685, 75017, 2103, - 122908, 0, 43276, 0, 11169, 0, 6481, 0, 0, 0, 100837, 72249, 100838, - 74198, 0, 9116, 0, 0, 0, 0, 0, 0, 8129, 92994, 0, 124992, 0, 11658, 0, 0, - 3452, 41031, 0, 1385, 0, 0, 0, 43340, 11123, 41033, 6493, 12758, 0, 0, - 11426, 0, 1681, 100755, 1204, 11960, 69902, 0, 69457, 0, 119322, 129483, - 7415, 43338, 0, 0, 67717, 64915, 0, 100759, 72021, 41497, 65044, 0, - 19960, 65358, 983601, 0, 0, 0, 73670, 0, 1789, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 64728, 0, 0, 0, 6506, 64312, 0, 2368, 0, 0, 0, 0, 3439, 1825, 1192, 0, - 73739, 10639, 0, 7790, 5430, 0, 0, 2848, 92981, 0, 0, 7607, 0, 0, 0, - 120658, 0, 0, 8883, 0, 728, 0, 0, 0, 0, 92931, 0, 121372, 128348, 0, - 68078, 8091, 11447, 0, 0, 126261, 983729, 0, 70003, 0, 0, 74419, 12335, - 0, 0, 3443, 0, 0, 0, 127145, 0, 0, 0, 0, 11843, 0, 9205, 8624, 128543, - 92930, 43295, 0, 65445, 0, 6277, 41672, 0, 10010, 70186, 983052, 0, 835, - 71340, 0, 0, 0, 0, 0, 5426, 4258, 0, 64891, 5424, 0, 8283, 0, 5434, 0, 0, - 0, 0, 0, 11947, 0, 1404, 0, 11432, 0, 3464, 6486, 4819, 0, 0, 570, 8095, - 0, 0, 1498, 0, 0, 0, 431, 67820, 0, 120574, 128096, 0, 0, 13096, 0, 0, - 43408, 0, 128538, 8835, 77875, 0, 0, 0, 0, 0, 0, 0, 0, 3477, 227, 10488, - 0, 382, 11418, 0, 5878, 0, 0, 0, 0, 6484, 92355, 66039, 0, 0, 0, 78717, - 0, 92662, 119665, 0, 0, 43290, 0, 0, 0, 0, 8782, 0, 0, 4323, 128649, 0, - 120903, 12094, 67499, 0, 0, 0, 92953, 3856, 120970, 0, 5872, 6495, 72306, - 0, 0, 0, 67173, 67172, 67171, 3953, 0, 0, 93063, 11994, 4339, 0, 92654, - 0, 0, 0, 0, 128804, 0, 5228, 0, 9766, 0, 92741, 0, 0, 0, 0, 68860, 0, - 1162, 0, 2671, 0, 73666, 92632, 92631, 72117, 0, 73811, 0, 194895, 0, - 68085, 0, 74331, 11424, 0, 10466, 121239, 0, 194890, 0, 4820, 0, 0, 0, - 194891, 0, 119212, 4896, 0, 4897, 42821, 64611, 0, 4438, 0, 0, 1753, - 11331, 6147, 0, 43282, 8833, 0, 0, 6504, 0, 0, 0, 118670, 0, 1413, 0, 0, - 64353, 12141, 121138, 0, 0, 43163, 0, 72880, 64789, 127094, 838, 127092, - 120697, 127090, 5014, 0, 256, 0, 0, 42443, 42739, 0, 7542, 0, 70389, 0, - 6489, 10048, 74326, 0, 66573, 0, 125271, 78712, 11761, 126078, 129603, - 41094, 0, 0, 0, 0, 92689, 8453, 0, 0, 120942, 128184, 0, 11816, 0, 0, - 2930, 93845, 0, 41098, 92771, 41093, 0, 0, 6498, 41096, 0, 0, 1238, 200, - 0, 1660, 74476, 0, 0, 74362, 0, 0, 72301, 9224, 0, 0, 0, 0, 0, 0, 0, 0, + 69236, 119171, 0, 8773, 10733, 36, 0, 0, 0, 0, 0, 11074, 0, 64910, + 983131, 2009, 0, 0, 128036, 68114, 128906, 0, 0, 0, 983998, 12852, 3031, + 0, 0, 129088, 0, 66414, 0, 0, 119950, 42613, 65933, 366, 0, 9892, 0, + 11754, 101107, 83329, 65301, 44013, 83058, 67245, 10102, 0, 7739, 41026, + 0, 0, 0, 0, 0, 0, 0, 0, 78386, 129475, 71868, 113811, 13081, 10923, + 129330, 0, 68145, 0, 65861, 74083, 0, 0, 128392, 83063, 83065, 0, 70706, + 0, 0, 0, 70168, 66586, 4183, 64967, 66250, 0, 92547, 0, 0, 113685, 0, + 3792, 2011, 0, 0, 77748, 83332, 77749, 120595, 0, 68489, 41023, 77747, 0, + 11659, 7922, 12614, 2005, 8523, 129880, 0, 7513, 1863, 129436, 83337, + 128969, 0, 120274, 120033, 0, 8144, 0, 73031, 77767, 127524, 120270, + 42241, 8783, 77764, 77765, 77766, 77760, 77761, 77762, 77763, 0, 10680, + 0, 43293, 68771, 0, 119164, 83320, 72003, 10187, 77742, 77743, 0, 77737, + 77738, 77739, 0, 10968, 43296, 119044, 0, 0, 101400, 0, 1005, 43826, + 120030, 0, 2870, 0, 101399, 0, 0, 983798, 0, 235, 1384, 77758, 74887, + 70494, 77754, 77755, 9796, 69895, 77750, 77751, 77752, 13186, 120407, + 120250, 0, 0, 0, 42527, 12911, 43427, 1383, 983581, 0, 0, 0, 6156, 68117, + 0, 7993, 4288, 0, 0, 13238, 13244, 0, 0, 120426, 13234, 120427, 0, + 118904, 0, 11364, 0, 1380, 65617, 120253, 120261, 13196, 13197, 120311, + 120419, 9495, 0, 0, 120418, 0, 73976, 128160, 0, 6941, 0, 13205, 13211, + 5801, 0, 74271, 120319, 0, 120302, 7670, 0, 68075, 983583, 0, 19957, + 72314, 2021, 93811, 43877, 0, 0, 0, 0, 3875, 120431, 64341, 0, 9814, + 43457, 13066, 3314, 7787, 0, 0, 0, 0, 0, 0, 64531, 129860, 0, 0, 0, 0, 0, + 127138, 0, 0, 9742, 0, 0, 10800, 77718, 8404, 0, 92592, 77714, 7089, + 77716, 78545, 0, 77712, 77713, 0, 0, 4772, 5771, 101405, 0, 9841, 8843, + 0, 0, 0, 129862, 120816, 0, 123137, 0, 77735, 0, 0, 0, 77731, 8849, + 77733, 77734, 65112, 1796, 77729, 77730, 69665, 8164, 41301, 3502, 0, + 122884, 128387, 0, 983835, 5825, 0, 0, 0, 0, 121322, 10983, 10354, 10418, + 0, 2022, 0, 1409, 100789, 0, 0, 0, 0, 1390, 0, 0, 10471, 65904, 5846, + 126472, 0, 0, 0, 0, 0, 0, 66035, 77725, 0, 77726, 77720, 77721, 67458, + 3168, 67733, 0, 0, 2370, 0, 126243, 0, 195049, 0, 0, 1836, 0, 121207, + 119137, 118959, 125232, 0, 0, 0, 2390, 3944, 0, 0, 0, 0, 69908, 125011, + 0, 0, 123200, 0, 0, 8975, 64739, 0, 0, 0, 0, 64409, 0, 0, 0, 0, 128564, + 0, 0, 0, 0, 6204, 0, 0, 0, 10911, 64954, 119003, 74809, 118903, 4267, 0, + 0, 0, 0, 0, 0, 72023, 0, 0, 119504, 92887, 0, 0, 0, 0, 121125, 0, 128337, + 5842, 0, 41439, 0, 0, 0, 9328, 0, 120980, 120917, 0, 0, 2285, 0, 0, 0, 0, + 118634, 64555, 0, 0, 72162, 9541, 0, 0, 0, 41441, 0, 0, 0, 41040, 2459, + 0, 0, 41041, 0, 0, 0, 0, 0, 10450, 0, 41043, 0, 0, 43125, 0, 0, 0, 0, 0, + 121008, 68436, 128040, 0, 120649, 0, 0, 4312, 43927, 0, 0, 11923, 42227, + 0, 5763, 0, 4827, 74559, 42228, 64406, 0, 0, 129703, 433, 119620, 0, + 2499, 67167, 67166, 0, 11973, 0, 4293, 42271, 42224, 0, 0, 66322, 42226, + 0, 0, 0, 74180, 0, 55277, 0, 0, 0, 119317, 0, 74632, 0, 0, 71103, 0, 0, + 0, 585, 2383, 0, 43263, 0, 4290, 64842, 0, 68920, 0, 8511, 0, 0, 0, + 119048, 2380, 126119, 0, 71704, 2376, 0, 0, 0, 5197, 127046, 127047, + 127048, 2366, 127050, 127051, 73442, 0, 0, 0, 93835, 0, 93818, 0, 0, + 74188, 113813, 0, 0, 0, 983838, 0, 0, 0, 0, 1847, 0, 72771, 0, 42384, 0, + 4227, 74158, 0, 92501, 0, 0, 42365, 0, 128902, 0, 92821, 0, 0, 0, 0, 0, + 0, 0, 0, 122934, 128563, 0, 983509, 127560, 2754, 0, 0, 128900, 0, + 127867, 119638, 0, 1711, 12984, 92365, 77776, 6255, 77770, 77771, 77772, + 77773, 0, 42063, 74184, 0, 0, 0, 0, 0, 77785, 77786, 41035, 43274, 77781, + 11256, 77783, 77784, 520, 77778, 41037, 77780, 0, 0, 41034, 0, 983829, + 64815, 0, 0, 321, 41028, 0, 0, 0, 0, 0, 0, 0, 74191, 0, 0, 72767, 1861, + 118938, 129666, 0, 0, 100770, 0, 0, 128530, 3859, 0, 41660, 0, 70793, 0, + 983756, 75014, 0, 127514, 41658, 0, 0, 0, 0, 0, 4414, 77769, 0, 42632, 0, + 0, 0, 0, 0, 1405, 0, 43220, 43341, 0, 0, 0, 0, 0, 983733, 11199, 0, 3513, + 0, 70341, 43342, 0, 65529, 0, 0, 0, 6485, 1397, 0, 0, 92678, 118566, + 124137, 0, 82961, 0, 82962, 0, 74270, 43287, 983731, 0, 0, 983738, 0, + 71914, 4317, 10490, 0, 0, 194867, 74463, 128952, 464, 41624, 0, 0, 0, + 1346, 128240, 69271, 64724, 128566, 423, 0, 0, 113748, 0, 128161, 0, 0, + 120563, 64960, 0, 0, 0, 0, 9584, 77795, 77796, 78927, 0, 9718, 77792, + 42642, 77794, 64750, 77789, 77790, 0, 0, 128333, 0, 3204, 64666, 0, + 43530, 2752, 0, 0, 119594, 0, 0, 0, 0, 92371, 0, 41983, 0, 7010, 0, 0, + 41495, 92379, 5877, 42252, 93070, 8009, 3305, 0, 0, 0, 0, 92293, 0, 0, 0, + 100836, 0, 65915, 1400, 75018, 10685, 75017, 2103, 122908, 0, 43276, 0, + 11169, 0, 6481, 0, 0, 0, 100837, 72249, 100838, 74198, 0, 9116, 0, 0, 0, + 0, 0, 0, 8129, 92994, 0, 124992, 0, 11658, 0, 0, 3452, 41031, 0, 1385, 0, + 100754, 0, 43340, 11123, 41033, 6493, 12758, 0, 0, 11426, 0, 1681, + 100755, 1204, 11960, 69902, 0, 69457, 0, 119322, 129483, 7415, 43338, 0, + 0, 67717, 64915, 0, 100759, 72021, 41497, 65044, 0, 19960, 65358, 983601, + 0, 0, 0, 73670, 0, 1789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64728, 0, 0, 0, + 6506, 64312, 0, 2368, 0, 0, 0, 0, 3439, 1825, 1192, 0, 73739, 10639, 0, + 7790, 5430, 0, 0, 2848, 92981, 0, 0, 7607, 0, 0, 0, 120658, 0, 0, 8883, + 0, 728, 0, 0, 0, 0, 92931, 0, 121372, 128348, 0, 68078, 8091, 11447, 0, + 0, 126261, 983729, 0, 70003, 0, 0, 74419, 12335, 0, 0, 3443, 0, 0, 0, + 127145, 0, 0, 0, 0, 11843, 0, 9205, 8624, 128543, 92930, 43295, 0, 65445, + 0, 6277, 41672, 0, 10010, 70186, 983052, 0, 835, 71340, 0, 0, 0, 0, 0, + 5426, 4258, 0, 64891, 5424, 0, 8283, 0, 5434, 0, 0, 0, 0, 0, 11947, 0, + 1404, 0, 11432, 0, 3464, 6486, 4819, 0, 0, 570, 8095, 0, 0, 1498, 0, 0, + 0, 431, 67820, 0, 120574, 128096, 0, 0, 13096, 0, 0, 43408, 0, 128538, + 8835, 77875, 0, 0, 122973, 0, 0, 0, 0, 0, 3477, 227, 10488, 0, 382, + 11418, 0, 5878, 0, 0, 0, 0, 6484, 92355, 66039, 0, 0, 0, 78717, 0, 92662, + 119665, 0, 0, 43290, 0, 0, 0, 0, 8782, 0, 0, 4323, 128649, 0, 120903, + 12094, 67499, 0, 0, 0, 92953, 3856, 120970, 124138, 5872, 6495, 72306, 0, + 0, 0, 67173, 67172, 67171, 3953, 0, 0, 93063, 11994, 4339, 0, 92654, 0, + 0, 0, 0, 128804, 0, 5228, 0, 9766, 0, 92741, 0, 0, 0, 0, 68860, 0, 1162, + 0, 2671, 0, 73666, 92632, 92631, 72117, 0, 73811, 0, 194895, 0, 68085, 0, + 74331, 11424, 0, 10466, 121239, 0, 194890, 0, 4820, 0, 0, 0, 194891, 0, + 119212, 4896, 0, 4897, 42821, 64611, 0, 4438, 0, 0, 1753, 11331, 6147, 0, + 43282, 8833, 0, 0, 6504, 0, 0, 0, 118670, 0, 1413, 0, 0, 64353, 12141, + 121138, 0, 0, 43163, 0, 72880, 64789, 127094, 838, 127092, 120697, + 127090, 5014, 0, 256, 0, 0, 42443, 42739, 0, 7542, 0, 70389, 0, 6489, + 10048, 74326, 0, 66573, 0, 125271, 78712, 11761, 126078, 129603, 41094, + 0, 0, 0, 0, 92689, 8453, 0, 0, 120942, 128184, 0, 11816, 0, 0, 2930, + 93845, 0, 41098, 92771, 41093, 0, 0, 6498, 41096, 0, 0, 1238, 200, 0, + 1660, 74476, 0, 0, 74362, 0, 0, 72301, 9224, 0, 0, 0, 0, 0, 0, 0, 0, 72729, 43284, 0, 72110, 67459, 13183, 0, 0, 0, 1669, 10776, 0, 0, 0, 0, 0, 1732, 4030, 0, 3963, 0, 0, 0, 6491, 0, 0, 914, 121394, 0, 0, 0, 78713, 0, 92441, 74367, 42960, 0, 0, 0, 0, 0, 0, 0, 65537, 0, 0, 43430, 5301, 0, 92618, 0, 43285, 0, 0, 125186, 0, 0, 5876, 0, 69555, 0, 0, 110713, 0, 0, - 0, 0, 0, 0, 11114, 74536, 0, 0, 0, 0, 983129, 0, 0, 0, 0, 10915, 983069, + 0, 0, 0, 0, 11114, 74536, 0, 0, 0, 0, 983130, 0, 0, 0, 0, 10915, 983069, 12007, 0, 0, 0, 0, 67655, 92604, 0, 8629, 0, 43168, 41872, 0, 0, 0, 42488, 0, 0, 0, 0, 0, 64730, 70041, 0, 122895, 0, 0, 0, 92306, 11416, 4280, 128516, 8765, 73451, 0, 1393, 0, 11157, 74386, 0, 0, 0, 0, 6683, 0, - 93832, 12144, 0, 74513, 13019, 74994, 0, 0, 0, 983269, 0, 6488, 357, 0, + 93832, 12144, 0, 74513, 13019, 74994, 0, 0, 0, 983272, 0, 6488, 357, 0, 41100, 0, 41104, 0, 41099, 0, 71320, 0, 0, 0, 4434, 0, 0, 0, 74231, 83107, 0, 194914, 0, 0, 72286, 68305, 0, 41759, 12757, 0, 0, 72769, 9790, - 7674, 0, 121095, 68209, 0, 41764, 0, 0, 72322, 2268, 0, 129845, 0, 12743, - 0, 6480, 0, 41779, 0, 66601, 0, 74490, 10986, 66602, 0, 64807, 0, 0, - 41767, 119629, 0, 0, 0, 3955, 64571, 194918, 127089, 0, 70187, 69975, - 9770, 12305, 12230, 0, 78579, 0, 0, 74752, 0, 0, 123168, 128263, 74449, + 7674, 0, 121095, 68209, 0, 41764, 0, 0, 72322, 2268, 0, 129845, 983608, + 12743, 0, 6480, 0, 41779, 0, 66601, 0, 74490, 10986, 66602, 0, 64807, 0, + 0, 41767, 119629, 0, 0, 0, 3955, 64571, 194918, 127089, 0, 70187, 69975, + 9770, 12305, 12230, 0, 73551, 0, 0, 74752, 0, 0, 123168, 128263, 74449, 0, 65948, 69611, 0, 0, 71131, 129505, 78573, 0, 0, 11116, 0, 5747, 0, 110667, 9802, 41092, 120731, 0, 0, 0, 0, 0, 120733, 41090, 0, 0, 0, - 11271, 57, 0, 0, 983241, 0, 71268, 121290, 43137, 0, 0, 110672, 126221, + 11271, 57, 0, 0, 983244, 0, 71268, 121290, 43137, 0, 0, 110672, 126221, 0, 0, 0, 0, 0, 277, 74385, 0, 0, 0, 72155, 0, 13025, 8757, 0, 0, 1574, 0, 126124, 100800, 0, 5749, 129923, 0, 42824, 0, 1039, 9801, 0, 5745, 0, - 41858, 0, 0, 120655, 0, 41862, 0, 0, 0, 436, 4771, 118635, 42501, 0, - 10573, 0, 0, 118560, 917986, 9644, 0, 0, 0, 0, 69837, 0, 0, 0, 0, 67409, - 0, 0, 0, 125204, 11939, 0, 0, 0, 0, 0, 0, 0, 3504, 0, 0, 92854, 126209, - 0, 10226, 65558, 0, 3594, 0, 0, 40, 0, 0, 0, 0, 0, 74312, 72138, 74337, - 0, 69577, 0, 0, 0, 70476, 0, 121143, 72317, 0, 0, 4304, 0, 0, 78707, 0, - 0, 0, 78597, 1348, 78596, 0, 0, 0, 70406, 92392, 0, 7599, 0, 0, 13269, 0, - 129729, 0, 100804, 0, 74494, 6097, 7568, 43980, 4982, 78592, 0, 0, 0, 0, - 13270, 0, 128090, 13138, 0, 9484, 0, 0, 71364, 0, 0, 0, 9487, 0, 92913, - 0, 71911, 78668, 73963, 6193, 0, 0, 0, 194848, 7228, 10011, 194849, - 194852, 194851, 11654, 194853, 126218, 194855, 0, 194857, 3604, 0, 0, 0, - 0, 0, 94110, 43740, 94109, 194860, 194863, 66750, 121021, 0, 94111, 6995, - 74173, 5437, 74174, 0, 8702, 7339, 129981, 0, 199, 194843, 194846, - 194845, 0, 126069, 0, 67818, 0, 7560, 0, 0, 0, 0, 6472, 65814, 0, 128983, - 70845, 0, 0, 9191, 0, 0, 0, 0, 124904, 10196, 0, 0, 6585, 0, 120750, 0, - 0, 71872, 129129, 0, 0, 78590, 72308, 11382, 129499, 0, 983670, 0, - 194833, 194832, 2165, 129540, 94020, 194836, 42727, 194838, 128252, - 78585, 43874, 119610, 0, 0, 43248, 0, 194816, 0, 194818, 128845, 194820, - 127879, 5297, 194821, 13284, 6112, 93964, 93010, 73927, 42947, 0, 65746, - 0, 0, 194827, 194826, 4342, 42839, 194831, 1677, 0, 72135, 0, 0, 0, - 11011, 66399, 0, 0, 0, 10160, 0, 0, 0, 0, 2052, 4308, 92174, 43000, - 118659, 543, 64916, 0, 0, 0, 119170, 0, 118922, 2064, 0, 43158, 0, 0, - 69984, 0, 0, 129187, 0, 0, 0, 0, 41631, 92728, 0, 0, 6228, 0, 0, 0, 0, 0, - 0, 506, 0, 0, 65735, 2055, 43255, 121407, 0, 0, 0, 0, 0, 0, 194666, 2063, - 0, 0, 0, 0, 72136, 0, 74333, 194912, 11827, 74308, 194913, 194916, + 41858, 0, 0, 120655, 0, 41862, 0, 0, 78822, 436, 4771, 118635, 42501, 0, + 10573, 0, 77931, 118560, 917986, 9644, 0, 0, 0, 0, 69837, 0, 0, 0, 0, + 67409, 0, 0, 0, 125204, 11939, 0, 0, 0, 0, 0, 0, 0, 3504, 0, 0, 92854, + 126209, 0, 10226, 65558, 0, 3594, 0, 0, 40, 0, 0, 0, 0, 0, 74312, 72138, + 74337, 0, 69577, 0, 0, 0, 70476, 0, 121143, 72317, 0, 0, 4304, 0, 0, + 78707, 0, 0, 0, 78597, 1348, 78596, 0, 0, 0, 70406, 92392, 0, 7599, 0, 0, + 13269, 0, 129729, 0, 100804, 0, 74494, 6097, 7568, 43980, 4982, 78592, 0, + 0, 0, 0, 13270, 0, 128090, 13138, 0, 9484, 0, 0, 71364, 0, 0, 0, 9487, 0, + 92913, 0, 71911, 78668, 73963, 6193, 0, 0, 0, 194848, 7228, 10011, + 194849, 194852, 194851, 11654, 194853, 126218, 194855, 0, 194857, 3604, + 0, 0, 0, 0, 0, 94110, 43740, 94109, 194860, 194863, 66750, 121021, 0, + 94111, 6995, 74173, 5437, 74174, 0, 8702, 7339, 129981, 0, 199, 194843, + 194846, 194845, 0, 126069, 0, 67818, 0, 7560, 0, 0, 0, 0, 6472, 65814, 0, + 128983, 70845, 0, 0, 9191, 0, 0, 0, 0, 124904, 10196, 0, 72452, 6585, 0, + 120750, 0, 0, 71872, 129129, 0, 0, 78590, 72308, 11382, 129499, 0, + 983670, 0, 194833, 194832, 2165, 129540, 94020, 194836, 42727, 194838, + 128252, 78585, 43874, 119610, 0, 0, 43248, 0, 194816, 0, 194818, 128845, + 194820, 127879, 5297, 194821, 13284, 6112, 93964, 93010, 73927, 42947, 0, + 65746, 0, 0, 194827, 194826, 4342, 42839, 194831, 1677, 0, 72135, 0, 0, + 0, 11011, 66399, 0, 0, 0, 10160, 0, 0, 0, 0, 2052, 4308, 92174, 43000, + 118659, 543, 64916, 122964, 0, 0, 119170, 0, 118922, 2064, 0, 43158, 0, + 0, 69984, 0, 0, 129187, 0, 0, 0, 0, 41631, 92728, 0, 0, 6228, 0, 0, 0, 0, + 0, 0, 506, 0, 0, 65735, 2055, 43255, 121407, 0, 0, 0, 0, 0, 0, 194666, + 2063, 0, 0, 0, 0, 72136, 0, 74333, 194912, 11827, 74308, 194913, 194916, 194915, 64564, 194917, 67986, 194919, 0, 11037, 0, 121102, 0, 0, 10560, 0, 120756, 194922, 113737, 194924, 194927, 120495, 1931, 0, 0, 0, 128228, 0, 12643, 8751, 123629, 0, 12294, 0, 78834, 9138, 78831, 78833, 12631, @@ -27511,7 +27700,7 @@ static const unsigned int code_hash[] = { 94042, 0, 8373, 41989, 69507, 73460, 3418, 3263, 0, 0, 0, 3270, 64539, 11489, 0, 118945, 126220, 0, 127795, 0, 94031, 0, 0, 0, 0, 0, 70512, 983983, 186, 0, 119156, 5770, 13179, 0, 12612, 12949, 64856, 12800, 0, 0, - 983151, 11507, 0, 0, 118929, 0, 0, 72141, 0, 73459, 0, 0, 0, 73461, 9254, + 983152, 11507, 0, 0, 118929, 0, 0, 72141, 0, 73459, 0, 0, 0, 73461, 9254, 66877, 194907, 0, 92338, 5624, 126253, 0, 0, 0, 120472, 120464, 0, 0, 122915, 120462, 0, 1872, 66508, 120467, 41079, 0, 5502, 119330, 41078, 194906, 0, 0, 4511, 68449, 0, 0, 0, 0, 43245, 41083, 68861, 0, 0, 9003, @@ -27538,7 +27727,7 @@ static const unsigned int code_hash[] = { 120188, 0, 9137, 0, 0, 0, 0, 3466, 0, 0, 1996, 0, 3453, 3412, 0, 2002, 2000, 120176, 0, 0, 0, 0, 1998, 0, 1842, 7037, 0, 9628, 68446, 0, 9826, 64502, 1767, 3413, 0, 0, 0, 0, 0, 0, 13108, 44024, 120204, 0, 92693, 0, - 0, 0, 70291, 12650, 983208, 0, 68061, 0, 3592, 0, 0, 0, 0, 983975, 0, + 0, 0, 70291, 12650, 983210, 0, 68061, 0, 3592, 0, 0, 0, 0, 983975, 0, 66417, 128792, 10742, 0, 0, 1994, 9281, 3296, 64475, 1997, 1895, 128936, 43024, 0, 0, 123184, 72391, 0, 8999, 0, 983633, 0, 66480, 0, 0, 0, 983083, 0, 596, 0, 0, 120216, 8651, 120217, 0, 0, 12995, 0, 0, 70740, 0, @@ -27571,9 +27760,9 @@ static const unsigned int code_hash[] = { 69816, 0, 118796, 0, 8708, 0, 64077, 64076, 8996, 4992, 4471, 83343, 64079, 64078, 92179, 0, 0, 123540, 64615, 0, 0, 12075, 42041, 0, 0, 0, 0, 127557, 3123, 0, 983754, 0, 0, 0, 83328, 0, 9223, 0, 83321, 83322, 73797, - 83327, 1116, 0, 83319, 7136, 0, 0, 0, 0, 75031, 0, 0, 0, 64092, 43675, - 10104, 83338, 83331, 64095, 64094, 8111, 66247, 0, 64089, 64088, 0, - 70106, 42236, 11434, 64083, 64082, 43216, 7737, 64087, 64086, 64085, + 83327, 1116, 0, 83319, 7136, 73550, 0, 0, 0, 75031, 0, 0, 0, 64092, + 43675, 10104, 83338, 83331, 64095, 64094, 8111, 66247, 0, 64089, 64088, + 0, 70106, 42236, 11434, 64083, 64082, 43216, 7737, 64087, 64086, 64085, 64084, 0, 0, 0, 4118, 1797, 83312, 0, 0, 46, 83308, 83309, 298, 83303, 72402, 83305, 83306, 0, 0, 0, 128905, 11495, 0, 67490, 0, 127377, 194828, 127370, 0, 0, 0, 66239, 74945, 64403, 0, 0, 83314, 0, 0, 65758, 43536, 0, @@ -27586,7 +27775,7 @@ static const unsigned int code_hash[] = { 0, 0, 0, 66802, 5058, 0, 0, 0, 5057, 125256, 0, 74538, 5054, 0, 0, 0, 0, 0, 0, 658, 3497, 128509, 0, 5061, 5060, 4235, 0, 0, 0, 127757, 4236, 4727, 0, 0, 0, 128791, 0, 7488, 128693, 7476, 0, 125259, 120646, 0, 0, 0, - 66209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128903, 0, 9341, + 66209, 0, 0, 0, 78931, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128903, 0, 9341, 119596, 0, 0, 0, 64668, 0, 8125, 0, 6743, 119175, 0, 129441, 83406, 0, 127966, 119235, 74092, 0, 0, 43660, 71125, 0, 127901, 0, 0, 0, 264, 0, 74954, 0, 0, 0, 0, 0, 6019, 0, 0, 129121, 0, 0, 0, 8800, 0, 66376, 0, @@ -27595,7 +27784,7 @@ static const unsigned int code_hash[] = { 70723, 5072, 128576, 13098, 72403, 0, 11040, 0, 0, 0, 4929, 0, 0, 0, 0, 0, 0, 0, 0, 67754, 4934, 0, 0, 9758, 0, 0, 70181, 42584, 0, 4329, 0, 4979, 8663, 74521, 0, 983042, 74418, 983653, 0, 5071, 0, 3642, 0, 5070, - 10042, 0, 3987, 5068, 120209, 8909, 0, 0, 69917, 0, 73981, 983141, 70749, + 10042, 0, 3987, 5068, 120209, 8909, 0, 0, 69917, 0, 73981, 983142, 70749, 4531, 120212, 9105, 0, 4921, 121059, 4926, 65544, 113786, 69621, 0, 0, 0, 83269, 0, 120790, 4922, 0, 992, 119568, 4925, 0, 0, 9526, 4920, 128617, 948, 0, 0, 4930, 0, 0, 0, 4933, 0, 0, 0, 4928, 0, 0, 0, 0, 128379, 722, @@ -27614,12 +27803,12 @@ static const unsigned int code_hash[] = { 0, 0, 0, 129172, 118715, 67703, 0, 0, 0, 0, 0, 72290, 0, 0, 0, 0, 7018, 66241, 0, 0, 0, 0, 0, 74056, 0, 11833, 0, 67975, 65232, 40964, 251, 12686, 7895, 4395, 43538, 0, 0, 0, 78042, 0, 0, 40967, 5879, 0, 0, 0, 0, - 0, 65540, 128590, 625, 0, 120194, 1113, 0, 13103, 3630, 67224, 8179, + 0, 65540, 128590, 625, 0, 120194, 1113, 120195, 13103, 3630, 67224, 8179, 74264, 67886, 9316, 10980, 2489, 120958, 8150, 1359, 121353, 70464, 127330, 127327, 5042, 5041, 42769, 12084, 11196, 42961, 92279, 72398, - 120535, 127317, 127318, 127315, 12283, 127313, 11453, 0, 8795, 66245, 0, - 5919, 0, 5037, 118864, 0, 0, 67724, 0, 66893, 74006, 129535, 8431, 0, 0, - 0, 0, 12620, 6826, 73773, 70169, 5040, 0, 0, 0, 0, 0, 5039, 0, 0, 0, + 120535, 127317, 127318, 127315, 12283, 127313, 11453, 70207, 8795, 66245, + 0, 5919, 0, 5037, 118864, 0, 0, 67724, 0, 66893, 74006, 129535, 8431, 0, + 0, 0, 0, 12620, 6826, 73773, 70169, 5040, 0, 0, 0, 0, 0, 5039, 0, 0, 0, 5038, 0, 0, 0, 0, 0, 65908, 0, 0, 0, 0, 0, 65157, 0, 0, 70182, 0, 73909, 4835, 0, 0, 0, 4309, 7127, 0, 0, 0, 1301, 0, 0, 12222, 0, 73813, 711, 92439, 7133, 0, 0, 0, 0, 0, 0, 0, 7661, 72263, 129541, 0, 0, 70453, 7627, @@ -27632,12 +27821,12 @@ static const unsigned int code_hash[] = { 0, 120854, 0, 0, 0, 2470, 0, 0, 1925, 71251, 0, 10971, 113770, 5048, 5047, 0, 0, 194946, 92313, 129972, 0, 0, 8089, 128468, 639, 0, 68179, 0, 70180, 0, 4599, 0, 0, 0, 0, 983817, 648, 194948, 65819, 0, 0, 0, 129968, - 94017, 0, 11777, 9750, 983122, 0, 0, 92367, 70175, 5046, 66255, 0, 0, + 94017, 0, 11777, 9750, 983123, 0, 0, 92367, 70175, 5046, 66255, 0, 0, 65253, 0, 5045, 0, 1916, 74069, 5044, 92348, 0, 0, 5043, 0, 0, 0, 74004, 9669, 12341, 0, 8402, 0, 0, 70174, 0, 3586, 64508, 92456, 0, 0, 119606, 0, 42628, 10069, 0, 0, 0, 0, 123, 120703, 0, 121326, 0, 10719, 129409, 120444, 10829, 120593, 0, 12130, 0, 0, 0, 0, 3925, 0, 0, 75065, 71112, - 92372, 71110, 71111, 0, 120441, 120452, 983178, 0, 0, 0, 0, 0, 0, 0, 0, + 92372, 71110, 71111, 0, 120441, 120452, 983179, 0, 0, 0, 0, 0, 0, 0, 0, 69879, 8509, 120449, 0, 0, 0, 120448, 0, 118889, 194858, 0, 0, 0, 66445, 0, 71109, 0, 0, 72425, 0, 12136, 0, 983629, 0, 0, 0, 0, 19922, 41768, 74002, 0, 0, 0, 0, 2458, 0, 0, 0, 41074, 4266, 64834, 0, 41077, 0, 9050, @@ -27652,7 +27841,7 @@ static const unsigned int code_hash[] = { 65925, 194997, 195000, 194999, 0, 66996, 0, 64397, 0, 0, 0, 71310, 194977, 194976, 2448, 194978, 194981, 194980, 2452, 194982, 194985, 194984, 78694, 72292, 7845, 0, 78692, 4408, 4122, 6772, 194988, 8723, - 72147, 194989, 119302, 11857, 119304, 119303, 2438, 119297, 119300, + 72147, 194989, 73472, 11857, 119304, 119303, 2438, 119297, 119300, 119299, 41953, 0, 42135, 373, 119172, 2119, 11457, 129618, 41955, 0, 0, 0, 41952, 0, 0, 2127, 0, 128496, 5202, 0, 78765, 42823, 11291, 0, 0, 12963, 0, 0, 4125, 41958, 12133, 0, 125099, 1271, 129427, 0, 66024, 0, @@ -27665,7 +27854,7 @@ static const unsigned int code_hash[] = { 983669, 0, 950, 0, 983673, 983683, 983668, 0, 983675, 0, 119121, 0, 5098, 0, 0, 119099, 5097, 0, 9848, 0, 10293, 983664, 72798, 0, 0, 70303, 983684, 5102, 5101, 128370, 0, 8138, 4517, 1932, 5100, 195060, 65022, - 1247, 10034, 195064, 5099, 0, 1441, 0, 4724, 650, 0, 73954, 983268, + 1247, 10034, 195064, 5099, 0, 1441, 0, 4724, 650, 0, 73954, 983271, 129348, 195040, 195043, 9031, 195045, 195044, 195047, 8545, 66356, 195048, 0, 9154, 127243, 0, 0, 2676, 2277, 0, 73812, 195051, 8599, 195053, 917918, 195055, 65462, 0, 92524, 195033, 71903, 0, 0, 41199, 0, @@ -27677,185 +27866,186 @@ static const unsigned int code_hash[] = { 127342, 70149, 932, 0, 6567, 195009, 195008, 195011, 195010, 70145, 43850, 195015, 195014, 195017, 195016, 0, 0, 0, 69511, 10670, 0, 13273, 0, 195020, 121370, 8803, 195021, 72431, 8151, 67145, 72436, 0, 12553, 0, - 0, 0, 0, 13065, 12570, 0, 0, 0, 983198, 124985, 0, 0, 66466, 0, 0, + 0, 0, 0, 13065, 12570, 0, 0, 0, 983199, 124985, 0, 0, 66466, 0, 0, 194595, 0, 194596, 11351, 43256, 0, 0, 0, 0, 41754, 0, 0, 2720, 194975, - 68462, 8232, 120758, 0, 0, 0, 0, 0, 0, 0, 93067, 10834, 0, 0, 119266, 0, - 0, 125025, 67679, 0, 75064, 7781, 0, 0, 126076, 0, 12077, 0, 64586, - 127164, 42396, 0, 3475, 0, 2479, 0, 0, 0, 120728, 0, 42434, 194960, - 194963, 194962, 110611, 67894, 42473, 194966, 110609, 1843, 42283, 0, 0, - 0, 0, 0, 194970, 0, 42321, 7284, 194974, 194973, 194950, 194949, 194952, - 194951, 0, 194953, 123614, 128645, 0, 0, 0, 0, 74952, 194954, 194957, - 194956, 66367, 194958, 41069, 67689, 9988, 0, 41068, 0, 4295, 0, 0, - 41951, 67835, 0, 785, 8236, 128647, 9027, 0, 194943, 0, 0, 0, 0, 0, 0, - 41071, 41059, 0, 92458, 129442, 0, 0, 0, 123612, 2067, 4310, 0, 123611, - 5180, 123605, 0, 73872, 0, 69880, 5184, 42385, 194947, 983774, 128531, 0, - 0, 119149, 0, 121334, 0, 983781, 0, 0, 5178, 194929, 120548, 194931, - 5188, 194933, 194932, 72245, 194934, 1166, 64429, 42639, 0, 0, 0, 0, - 128071, 2442, 10703, 194940, 194939, 194635, 42439, 0, 0, 0, 73933, - 983239, 42401, 0, 0, 0, 42288, 0, 0, 0, 13145, 0, 2468, 0, 42327, 0, 0, - 0, 42479, 128698, 0, 0, 92580, 0, 74939, 120678, 0, 73733, 0, 0, 2715, 0, - 71257, 0, 74114, 0, 0, 0, 0, 0, 66325, 69603, 0, 9240, 0, 0, 129142, 0, - 0, 0, 9815, 0, 11246, 0, 73912, 42733, 0, 0, 2480, 0, 0, 0, 6494, 5537, - 0, 0, 0, 0, 1211, 0, 121379, 0, 0, 12318, 0, 113796, 0, 0, 0, 0, 0, - 64642, 0, 0, 0, 0, 64864, 0, 0, 0, 121212, 0, 0, 3589, 92719, 4035, 6492, - 92236, 4265, 6843, 0, 74186, 41778, 113764, 119216, 2488, 0, 4582, 0, - 71426, 41777, 12926, 72708, 7528, 10550, 113761, 0, 0, 11439, 0, 0, - 64878, 0, 0, 0, 0, 2286, 0, 0, 126646, 127909, 5909, 400, 126500, 0, 0, - 0, 0, 0, 64827, 0, 74948, 390, 0, 71301, 0, 3473, 0, 0, 66742, 0, 55285, - 0, 0, 0, 92206, 194964, 0, 8004, 0, 6763, 0, 0, 7006, 0, 0, 6757, 73707, - 126648, 0, 6766, 0, 0, 0, 6146, 0, 771, 0, 0, 41318, 0, 42272, 0, 120211, - 69559, 0, 953, 12917, 72287, 12300, 64837, 11491, 68612, 0, 0, 71321, - 7490, 11389, 7489, 3379, 0, 7487, 42996, 7486, 7484, 7482, 6753, 7480, - 7479, 7478, 7477, 6501, 7475, 42995, 7473, 7472, 2474, 7470, 7468, - 124977, 0, 0, 0, 0, 71871, 11834, 128376, 0, 6017, 0, 128763, 0, 0, 0, - 119365, 73949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2472, 69945, 120699, 121133, - 2139, 4256, 120776, 74380, 0, 73847, 73844, 0, 0, 101375, 0, 101374, 0, - 0, 101347, 7083, 0, 8066, 7678, 0, 121124, 101341, 101373, 101336, 0, - 101331, 0, 101304, 0, 101301, 0, 0, 0, 8330, 0, 101298, 101322, 101297, - 0, 0, 19934, 0, 1770, 67091, 0, 128671, 129617, 110605, 101355, 73843, - 110604, 0, 101362, 67092, 0, 71334, 0, 0, 0, 0, 0, 8162, 0, 5996, 129644, - 4903, 0, 0, 43063, 0, 5172, 0, 7139, 0, 127385, 0, 118667, 0, 0, 4334, - 6324, 41975, 12186, 10674, 12308, 0, 0, 0, 72807, 41977, 68002, 0, - 126630, 2018, 121388, 41979, 68003, 0, 68000, 0, 0, 126984, 68001, 9334, - 118609, 71440, 0, 7975, 0, 0, 0, 66621, 4884, 70367, 983759, 0, 121010, - 0, 0, 0, 0, 127799, 0, 0, 0, 463, 0, 194584, 69617, 6509, 5460, 0, 0, 0, - 0, 42279, 0, 0, 0, 0, 0, 0, 0, 125027, 0, 121119, 0, 0, 0, 5663, 0, 0, 0, - 0, 2482, 66202, 0, 0, 42247, 65174, 73925, 0, 100940, 0, 0, 126573, 0, 0, - 2460, 0, 11944, 0, 0, 64679, 120835, 127310, 0, 0, 0, 5870, 0, 0, 0, - 100931, 539, 100933, 100932, 100935, 9064, 100937, 100936, 100939, - 100938, 0, 0, 0, 0, 0, 0, 41295, 100941, 2478, 100943, 4162, 100945, - 4260, 12953, 100950, 100949, 129800, 0, 0, 0, 0, 0, 0, 0, 5000, 0, 0, 0, - 69672, 71439, 0, 74017, 0, 0, 6709, 0, 0, 983739, 0, 0, 100922, 100921, - 10301, 10333, 10397, 100925, 100928, 100927, 0, 0, 0, 127830, 0, 4014, - 12842, 0, 67413, 0, 0, 3893, 0, 0, 12210, 0, 42147, 0, 983622, 74465, 0, - 0, 0, 0, 0, 0, 0, 0, 110805, 8231, 0, 69946, 41968, 100929, 41973, 12935, - 41969, 0, 2453, 0, 0, 78807, 122893, 0, 10349, 10413, 0, 41962, 3202, - 119097, 0, 8316, 129174, 0, 7314, 0, 0, 0, 0, 1840, 0, 0, 0, 4883, - 100908, 4723, 70099, 100909, 0, 0, 0, 0, 11089, 240, 19906, 0, 0, 0, - 43600, 121004, 13134, 93065, 0, 65931, 110649, 110650, 42634, 110648, 0, - 121005, 11463, 0, 0, 129861, 10445, 0, 92969, 0, 2614, 0, 129954, 1729, - 0, 0, 100911, 0, 43334, 100912, 100915, 100914, 66201, 100916, 69662, - 100896, 100899, 100898, 4121, 100900, 70272, 82954, 63879, 0, 70872, 0, - 0, 4039, 643, 7726, 120082, 0, 120068, 58, 0, 0, 0, 63872, 0, 0, 100891, - 0, 10625, 100892, 100895, 100894, 1416, 120073, 917761, 67393, 0, 0, 0, - 6996, 4264, 0, 100902, 66179, 66768, 100903, 13114, 72311, 67510, 3094, - 0, 0, 127074, 4437, 0, 0, 0, 55280, 42174, 0, 42430, 129796, 72246, - 42355, 0, 0, 0, 0, 121251, 127401, 0, 0, 0, 0, 0, 0, 100882, 100881, - 74037, 100883, 0, 127099, 0, 0, 0, 0, 0, 69646, 65035, 65034, 11480, - 6116, 65039, 65038, 41180, 65036, 194565, 0, 12101, 5822, 0, 0, 0, 0, - 11663, 127873, 63854, 119657, 63853, 0, 63852, 65810, 4289, 100885, - 63896, 100887, 100890, 43621, 0, 0, 0, 129613, 194560, 7461, 73901, 0, - 331, 0, 0, 0, 128029, 0, 0, 0, 74629, 0, 0, 0, 41964, 0, 63843, 2084, - 41965, 0, 100864, 100863, 100866, 63841, 78549, 41220, 13032, 100869, - 8383, 0, 78548, 126102, 0, 0, 1351, 983865, 8698, 100874, 100877, 1930, - 100879, 78554, 74360, 100880, 69859, 78551, 0, 0, 129433, 3657, 0, 65202, - 6000, 119206, 41901, 0, 0, 41740, 0, 41283, 0, 119267, 0, 0, 100871, - 9695, 100873, 7562, 100853, 5170, 100855, 100854, 676, 100856, 100859, - 100858, 9978, 100860, 0, 0, 64934, 0, 0, 0, 113714, 113706, 41829, 65886, - 5159, 0, 41832, 704, 43077, 0, 120532, 0, 68496, 65065, 41830, 0, 917799, - 917798, 917797, 917796, 0, 67864, 113696, 917800, 12336, 4135, 69805, - 341, 2727, 4129, 100862, 100861, 0, 64503, 7913, 0, 0, 4131, 63868, 0, - 63871, 4133, 63864, 210, 0, 0, 0, 4137, 78505, 78506, 0, 78504, 78830, 0, - 0, 43873, 0, 0, 0, 0, 11988, 78510, 195, 68321, 41501, 0, 42031, 0, - 13135, 0, 0, 0, 41499, 0, 0, 9680, 41498, 917794, 42025, 78567, 78556, 0, - 0, 0, 0, 0, 0, 101074, 120502, 92597, 0, 0, 917784, 7864, 129001, 129704, - 917788, 121106, 917786, 917785, 5753, 67816, 72371, 2219, 0, 0, 0, 0, 0, - 0, 121277, 0, 917777, 917776, 917775, 69644, 917781, 917780, 917779, - 917778, 8668, 0, 121383, 917782, 5999, 0, 0, 129195, 128243, 43653, 1726, - 1015, 0, 127247, 0, 0, 64919, 0, 0, 0, 128478, 0, 69791, 927, 0, 0, - 42010, 0, 42021, 0, 0, 1299, 12240, 64537, 0, 0, 0, 0, 0, 0, 69454, 0, 0, - 0, 122903, 19914, 12179, 0, 2296, 0, 0, 63832, 917773, 0, 63816, 2594, - 63823, 63817, 11178, 0, 0, 0, 11265, 68295, 0, 0, 0, 10554, 3972, 0, - 121198, 0, 917766, 10816, 917764, 119608, 74374, 917769, 11210, 93069, - 8586, 3882, 8532, 120183, 1573, 128648, 0, 69916, 0, 101051, 67719, 0, 0, - 0, 0, 0, 0, 0, 128821, 119169, 0, 0, 6626, 42763, 130034, 118884, 128613, - 0, 83128, 0, 0, 0, 0, 0, 983561, 0, 0, 0, 9171, 0, 0, 71305, 983919, - 121146, 0, 101095, 128881, 119604, 126596, 0, 0, 0, 128214, 42368, 0, - 983105, 2271, 41487, 12118, 74124, 68651, 110836, 110833, 3009, 41476, - 41489, 69825, 3007, 1448, 3018, 0, 41491, 8521, 5083, 5082, 0, 0, 8519, - 0, 3014, 5081, 73926, 0, 128549, 0, 69951, 5079, 129963, 2557, 128086, - 65532, 11828, 0, 71297, 11105, 0, 0, 0, 8518, 10779, 0, 71303, 0, 0, - 42170, 110769, 0, 629, 1924, 0, 12037, 0, 5987, 8462, 127744, 0, 63933, - 69735, 110770, 128295, 63941, 67981, 5077, 0, 10880, 64849, 5075, 0, - 128152, 65075, 0, 11007, 983736, 0, 0, 0, 66684, 72331, 3434, 72338, - 1904, 0, 0, 72730, 0, 10499, 4507, 9578, 63925, 0, 7979, 0, 9831, 66689, - 0, 461, 194834, 0, 4504, 0, 0, 6325, 0, 43021, 0, 0, 55236, 0, 0, 5177, - 41324, 12055, 63831, 0, 41327, 12591, 0, 4114, 409, 0, 0, 8948, 41325, 0, - 721, 10182, 0, 71311, 0, 0, 94052, 74963, 83503, 5998, 0, 0, 74825, 0, - 12587, 0, 78571, 74889, 71328, 128955, 0, 74121, 78570, 78822, 0, 0, - 5995, 0, 42568, 0, 0, 63944, 73860, 126586, 0, 4167, 0, 43175, 0, 74120, - 0, 65076, 938, 73857, 73854, 11737, 9721, 0, 0, 0, 11742, 0, 0, 11493, - 12334, 128762, 0, 66623, 0, 9173, 0, 11978, 0, 12734, 113750, 113741, 0, - 6759, 0, 0, 0, 126222, 0, 70388, 129093, 13027, 42777, 7683, 1167, 0, - 4983, 0, 861, 0, 0, 68297, 0, 43757, 92978, 129298, 122630, 127804, 0, - 118654, 70815, 9616, 0, 0, 12816, 43759, 0, 12710, 68674, 12721, 4101, - 66185, 0, 5992, 7616, 0, 0, 12577, 0, 0, 853, 42693, 0, 121088, 0, 0, - 917915, 0, 42835, 0, 0, 0, 0, 0, 12712, 7105, 127807, 65060, 66875, 9900, - 0, 0, 0, 121482, 119265, 0, 64778, 12585, 0, 0, 0, 0, 0, 0, 77826, 0, - 4900, 125245, 0, 0, 0, 4119, 74768, 8971, 0, 0, 0, 78594, 41132, 9245, - 73060, 0, 4138, 194841, 0, 0, 0, 77827, 0, 13054, 0, 0, 128416, 110760, - 0, 0, 3948, 128878, 0, 0, 0, 1680, 0, 11861, 0, 0, 120032, 0, 0, 0, 0, - 74833, 74190, 5993, 42709, 0, 12706, 77846, 1893, 0, 63915, 0, 0, 110744, - 129826, 0, 63997, 120018, 63996, 3077, 0, 0, 1512, 0, 12589, 41479, 0, 0, - 0, 0, 11831, 120727, 0, 41481, 0, 118912, 0, 3090, 0, 3086, 1664, 1850, - 0, 3079, 0, 0, 94080, 127140, 0, 0, 74401, 0, 917555, 0, 0, 0, 0, 0, - 11526, 63985, 5864, 0, 63992, 0, 63991, 0, 5480, 7858, 0, 4116, 78149, 0, - 0, 0, 63907, 0, 0, 126131, 63905, 119601, 0, 983190, 0, 119666, 0, 0, - 7534, 507, 91, 2042, 120775, 118596, 0, 66028, 118811, 41844, 70680, 774, - 0, 0, 0, 5994, 0, 12733, 0, 0, 0, 72297, 0, 0, 0, 0, 6026, 0, 0, 0, 162, - 0, 125247, 78151, 78152, 983590, 92709, 0, 68304, 0, 0, 0, 66658, 0, 0, - 0, 0, 121511, 2226, 121512, 129349, 10492, 0, 121510, 0, 43119, 0, 0, 0, - 66192, 0, 0, 4899, 12729, 0, 0, 0, 0, 4103, 0, 129842, 77851, 69429, - 129046, 0, 12859, 70087, 0, 0, 0, 0, 0, 0, 0, 0, 65264, 5146, 0, 194694, - 71684, 0, 0, 983652, 983863, 0, 71688, 78463, 5147, 125019, 0, 74524, - 71682, 128435, 0, 194692, 5991, 3445, 0, 4976, 66193, 0, 0, 0, 0, 128309, - 128594, 129819, 69579, 0, 63855, 0, 10138, 0, 0, 8897, 0, 75027, 0, - 120931, 77862, 65836, 0, 0, 77860, 0, 0, 1123, 4124, 41553, 77903, 0, - 71680, 121386, 398, 0, 129035, 41551, 0, 0, 0, 41550, 9970, 0, 93062, - 42392, 1305, 78901, 0, 129292, 0, 7346, 41464, 0, 0, 0, 41465, 983567, - 8528, 9149, 0, 63955, 165, 3024, 11852, 119163, 0, 9093, 0, 9147, 0, 0, - 110989, 9148, 0, 4096, 53, 8296, 0, 71352, 0, 9594, 0, 0, 63952, 0, - 10997, 0, 0, 5805, 0, 0, 129777, 42176, 71455, 74601, 129604, 10591, 0, - 92852, 0, 0, 0, 0, 0, 0, 92475, 0, 0, 42379, 0, 0, 9220, 0, 121425, 0, 0, - 4132, 0, 0, 11239, 0, 0, 74837, 0, 66408, 0, 8055, 0, 0, 0, 63962, 74042, - 8924, 43123, 5988, 0, 63969, 0, 42718, 8788, 1357, 77872, 65743, 0, 8774, - 0, 0, 0, 0, 92748, 120598, 128234, 9564, 0, 0, 119124, 0, 121241, 110983, - 92975, 3121, 0, 0, 0, 70081, 0, 0, 0, 0, 0, 64851, 0, 0, 73085, 119532, - 0, 0, 0, 0, 1198, 69293, 66708, 64619, 0, 64663, 93991, 0, 0, 2101, 1398, - 0, 92554, 0, 0, 92684, 11406, 101588, 12127, 66998, 840, 0, 0, 7101, - 120938, 0, 0, 12880, 0, 43104, 0, 0, 0, 2117, 0, 0, 0, 0, 0, 0, 0, 7769, - 129867, 92413, 0, 0, 100695, 0, 40986, 83117, 0, 0, 4127, 0, 0, 0, 0, 0, - 0, 70738, 0, 129466, 0, 0, 0, 0, 119081, 0, 10581, 0, 4533, 0, 128941, - 6490, 0, 12038, 0, 0, 68225, 0, 0, 69704, 0, 1948, 119007, 129607, - 101586, 0, 0, 0, 120802, 0, 9494, 0, 0, 0, 4843, 0, 74772, 4098, 0, 0, 0, - 3436, 0, 127279, 12817, 0, 126607, 118678, 0, 0, 0, 74433, 0, 0, 71962, - 0, 121296, 65916, 0, 0, 121458, 0, 129107, 93815, 0, 73743, 0, 0, 983132, - 67676, 0, 0, 74627, 128928, 0, 127892, 0, 71326, 67222, 0, 75013, 92435, - 0, 128500, 0, 0, 9613, 43425, 4526, 121415, 0, 64520, 71336, 0, 0, 55278, - 10228, 64957, 0, 0, 3807, 2081, 66640, 0, 0, 0, 0, 119269, 0, 128688, 0, - 128142, 1451, 0, 0, 4134, 0, 74847, 0, 74793, 0, 0, 74295, 9960, 1201, 0, - 12846, 121271, 0, 11919, 64962, 0, 43739, 0, 66358, 0, 0, 0, 43679, - 72284, 72289, 0, 129523, 1253, 983870, 65766, 500, 65764, 65765, 65762, - 65763, 65760, 65761, 70334, 983867, 9821, 11702, 110630, 110631, 110628, - 110629, 128481, 0, 7533, 66717, 92500, 92305, 0, 0, 69277, 127758, 71332, - 0, 0, 0, 0, 11188, 0, 4112, 0, 0, 12890, 0, 0, 9915, 0, 68423, 0, 0, - 2876, 0, 0, 0, 0, 7382, 92415, 0, 128132, 0, 0, 0, 0, 69561, 127915, 0, - 7003, 0, 0, 7704, 0, 0, 0, 4123, 0, 0, 9977, 0, 0, 65759, 0, 0, 128266, - 9808, 0, 92611, 4126, 0, 9521, 9589, 64755, 0, 0, 0, 69948, 0, 92368, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 93814, 0, 0, 92234, 0, 10693, 0, 0, 65897, 4058, - 0, 0, 64660, 0, 0, 0, 983730, 1139, 43298, 0, 65929, 8970, 0, 9934, 0, - 11023, 128020, 42522, 0, 0, 0, 78899, 3057, 128113, 7349, 69959, 128722, - 68065, 110813, 0, 92826, 67201, 0, 0, 0, 9528, 0, 0, 0, 9102, 627, 92827, - 6273, 129496, 0, 0, 983210, 92966, 43300, 0, 983740, 11696, 92825, 1018, - 65554, 0, 74338, 0, 7645, 0, 128321, 0, 0, 0, 0, 73814, 11544, 12563, - 10728, 0, 0, 127340, 43311, 64966, 92841, 0, 0, 118946, 0, 0, 74779, 0, - 185, 65085, 74533, 0, 0, 7535, 0, 42525, 0, 9749, 41701, 6131, 0, 4117, - 129062, 126988, 0, 92429, 65693, 0, 73445, 0, 69695, 0, 0, 0, 0, 0, 0, 0, - 1184, 0, 815, 0, 0, 0, 0, 0, 71325, 0, 0, 64683, 983816, 0, 127959, 0, 0, - 0, 0, 0, 0, 0, 68166, 0, 0, 0, 0, 66799, 0, 128912, 0, 5142, 0, 69643, 0, - 0, 68367, 93975, 0, 0, 0, 123209, 0, 0, 0, 74855, 121330, 0, 0, 0, 0, - 10940, 66030, 0, 70385, 0, 0, 2652, 120527, 0, 129946, 0, 126508, 0, 0, - 0, 0, 0, 0, 1828, 0, 128357, 0, 8531, 0, 74799, 12324, 72434, 65238, + 68462, 8232, 120758, 0, 0, 0, 0, 122959, 0, 0, 93067, 10834, 0, 0, + 119266, 0, 0, 125025, 67679, 0, 75064, 7781, 0, 0, 126076, 0, 12077, 0, + 64586, 127164, 42396, 0, 3475, 0, 2479, 0, 0, 0, 120728, 0, 42434, + 129709, 194963, 194962, 110611, 67894, 42473, 194966, 110609, 1843, + 42283, 0, 0, 0, 0, 0, 194970, 0, 42321, 7284, 194974, 194973, 194950, + 194949, 194952, 194951, 0, 194953, 123614, 128645, 0, 0, 0, 0, 74952, + 194954, 194957, 194956, 66367, 194958, 41069, 67689, 9988, 0, 41068, 0, + 4295, 0, 0, 41951, 67835, 0, 785, 8236, 128647, 9027, 0, 194943, 0, + 122986, 0, 0, 0, 0, 41071, 41059, 0, 92458, 129442, 0, 0, 0, 123612, + 2067, 4310, 0, 123611, 5180, 123605, 0, 73872, 0, 69880, 5184, 42385, + 194947, 983774, 128531, 0, 0, 119149, 73503, 121334, 0, 983781, 0, 0, + 5178, 194929, 120548, 194931, 5188, 194933, 194932, 72245, 194934, 1166, + 64429, 42639, 0, 0, 0, 0, 128071, 2442, 10703, 194940, 194939, 194635, + 42439, 0, 0, 0, 73933, 983242, 42401, 0, 0, 0, 42288, 0, 0, 0, 13145, 0, + 2468, 0, 42327, 0, 0, 0, 42479, 128698, 0, 0, 92580, 0, 74939, 120678, 0, + 73733, 0, 0, 2715, 0, 71257, 0, 74114, 0, 0, 0, 0, 0, 66325, 69603, 0, + 9240, 0, 0, 129142, 0, 0, 0, 9815, 0, 11246, 0, 73912, 42733, 0, 0, 2480, + 0, 0, 0, 6494, 5537, 0, 0, 0, 0, 1211, 0, 121379, 0, 0, 12318, 0, 113796, + 0, 0, 0, 0, 0, 64642, 0, 0, 0, 0, 64864, 0, 0, 0, 121212, 0, 0, 3589, + 92719, 4035, 6492, 92236, 4265, 6843, 0, 74186, 41778, 113764, 119216, + 2488, 0, 4582, 0, 71426, 41777, 12926, 72708, 7528, 10550, 113761, 0, 0, + 11439, 0, 0, 64878, 0, 0, 0, 0, 2286, 0, 0, 126646, 127909, 5909, 400, + 126500, 0, 0, 0, 0, 0, 64827, 0, 74948, 390, 0, 71301, 0, 3473, 0, 0, + 66742, 0, 55285, 0, 0, 0, 92206, 194964, 0, 8004, 0, 6763, 0, 0, 7006, 0, + 0, 6757, 73707, 126648, 0, 6766, 0, 0, 0, 6146, 0, 771, 0, 0, 41318, 0, + 42272, 0, 120211, 69559, 0, 953, 12917, 72287, 12300, 64837, 11491, + 68612, 0, 0, 71321, 7490, 11389, 7489, 3379, 0, 7487, 42996, 7486, 7484, + 7482, 6753, 7480, 7479, 7478, 7477, 6501, 7475, 42995, 7473, 7472, 2474, + 7470, 7468, 124977, 0, 0, 0, 0, 71871, 11834, 128376, 0, 6017, 0, 128763, + 0, 0, 0, 119365, 73949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2472, 69945, + 120699, 121133, 2139, 4256, 120776, 74380, 0, 73847, 73844, 0, 0, 101375, + 0, 101374, 0, 0, 101347, 7083, 0, 8066, 7678, 0, 121124, 101341, 101373, + 101336, 0, 101331, 0, 101304, 0, 101301, 0, 0, 0, 8330, 0, 101298, + 101322, 101297, 0, 0, 19934, 0, 1770, 67091, 0, 128671, 129617, 110605, + 101355, 73843, 110604, 0, 101362, 67092, 0, 71334, 0, 0, 0, 0, 0, 8162, + 0, 5996, 129644, 4903, 0, 0, 43063, 0, 5172, 0, 7139, 0, 127385, 0, + 118667, 0, 0, 4334, 6324, 41975, 12186, 10674, 12308, 0, 0, 0, 72807, + 41977, 68002, 0, 126630, 2018, 121388, 41979, 68003, 0, 68000, 0, 0, + 126984, 68001, 9334, 118609, 71440, 0, 7975, 0, 0, 0, 66621, 4884, 70367, + 983759, 0, 121010, 0, 0, 0, 0, 127799, 0, 0, 0, 463, 0, 194584, 69617, + 6509, 5460, 0, 0, 0, 0, 42279, 0, 0, 0, 0, 0, 0, 0, 125027, 0, 121119, 0, + 0, 0, 5663, 0, 0, 0, 0, 2482, 66202, 0, 0, 42247, 65174, 73925, 0, + 100940, 0, 0, 126573, 0, 0, 2460, 0, 11944, 0, 0, 64679, 120835, 127310, + 0, 0, 0, 5870, 0, 0, 0, 100931, 539, 100933, 100932, 100935, 9064, + 100937, 100936, 100939, 100938, 0, 0, 0, 0, 0, 0, 41295, 100941, 2478, + 100943, 4162, 100945, 4260, 12953, 100950, 100949, 129800, 0, 0, 0, 0, 0, + 0, 0, 5000, 0, 0, 0, 69672, 71439, 0, 74017, 0, 0, 6709, 0, 0, 983739, 0, + 0, 100922, 100921, 10301, 10333, 10397, 100925, 100928, 100927, 0, 0, 0, + 127830, 0, 4014, 12842, 0, 67413, 0, 0, 3893, 0, 0, 12210, 0, 42147, 0, + 983622, 74465, 0, 0, 0, 0, 0, 0, 0, 0, 110805, 8231, 0, 69946, 41968, + 100929, 41973, 12935, 41969, 0, 2453, 0, 0, 78807, 122893, 0, 10349, + 10413, 122956, 41962, 3202, 119097, 0, 8316, 129174, 0, 7314, 0, 0, 0, 0, + 1840, 0, 0, 0, 4883, 100908, 4723, 70099, 100909, 0, 0, 0, 0, 11089, 240, + 19906, 0, 0, 0, 43600, 121004, 13134, 93065, 0, 65931, 110649, 110650, + 42634, 110648, 0, 121005, 11463, 0, 0, 129861, 10445, 0, 92969, 0, 2614, + 0, 129954, 1729, 0, 0, 100911, 0, 43334, 100912, 100915, 100914, 66201, + 100916, 69662, 100896, 100899, 100898, 4121, 100900, 70272, 82954, 63879, + 0, 70872, 0, 0, 4039, 643, 7726, 120082, 0, 120068, 58, 0, 0, 0, 63872, + 0, 0, 100891, 0, 10625, 100892, 100895, 100894, 1416, 120073, 917761, + 67393, 0, 0, 0, 6996, 4264, 0, 100902, 66179, 66768, 100903, 13114, + 72311, 67510, 3094, 0, 0, 127074, 4437, 0, 0, 0, 55280, 42174, 0, 42430, + 129796, 72246, 42355, 0, 0, 0, 0, 121251, 127401, 0, 0, 0, 0, 0, 0, + 100882, 100881, 74037, 100883, 0, 127099, 0, 0, 0, 0, 0, 69646, 65035, + 65034, 11480, 6116, 65039, 65038, 41180, 65036, 194565, 0, 12101, 5822, + 0, 0, 0, 0, 11663, 127873, 63854, 119657, 63853, 0, 63852, 65810, 4289, + 100885, 63896, 100887, 100890, 43621, 0, 0, 0, 129613, 194560, 7461, + 73901, 0, 331, 0, 0, 0, 128029, 0, 0, 0, 74629, 0, 0, 0, 41964, 0, 63843, + 2084, 41965, 0, 100864, 100863, 100866, 63841, 78549, 41220, 13032, + 100869, 8383, 0, 78548, 126102, 0, 0, 1351, 983865, 8698, 100874, 100877, + 1930, 100879, 78554, 74360, 100880, 69859, 78551, 0, 0, 129433, 3657, 0, + 65202, 6000, 119206, 41901, 0, 0, 41740, 0, 41283, 73543, 119267, 0, 0, + 100871, 9695, 100873, 7562, 100853, 5170, 100855, 100854, 676, 100856, + 100859, 100858, 9978, 100860, 0, 0, 64934, 0, 0, 0, 113714, 113706, + 41829, 65886, 5159, 0, 41832, 704, 43077, 0, 120532, 0, 68496, 65065, + 41830, 0, 917799, 917798, 917797, 917796, 0, 67864, 113696, 917800, + 12336, 4135, 69805, 341, 2727, 4129, 100862, 100861, 0, 64503, 7913, 0, + 0, 4131, 63868, 0, 63871, 4133, 63864, 210, 0, 0, 0, 4137, 78505, 78506, + 0, 78504, 78830, 0, 0, 43873, 0, 0, 0, 0, 11988, 78510, 195, 68321, + 41501, 0, 42031, 0, 13135, 0, 0, 0, 41499, 0, 0, 9680, 41498, 917794, + 42025, 78567, 78556, 0, 0, 0, 0, 0, 0, 101074, 120502, 92597, 0, 0, + 917784, 7864, 129001, 129704, 917788, 121106, 917786, 917785, 5753, + 67816, 72371, 2219, 0, 0, 0, 0, 0, 0, 121277, 0, 917777, 917776, 917775, + 69644, 917781, 917780, 917779, 917778, 8668, 0, 121383, 917782, 5999, 0, + 0, 129195, 128243, 43653, 1726, 1015, 0, 127247, 0, 0, 64919, 0, 0, 0, + 128478, 0, 69791, 927, 0, 0, 42010, 0, 42021, 0, 0, 1299, 12240, 64537, + 0, 0, 0, 0, 0, 0, 69454, 0, 0, 0, 122903, 19914, 12179, 0, 2296, 0, 0, + 63832, 917773, 0, 63816, 2594, 63823, 63817, 11178, 0, 0, 0, 11265, + 68295, 0, 0, 0, 10554, 3972, 0, 121198, 0, 917766, 10816, 917764, 119608, + 74374, 917769, 11210, 93069, 8586, 3882, 8532, 120183, 1573, 128648, 0, + 69916, 0, 101051, 67719, 0, 0, 0, 0, 0, 0, 0, 128821, 119169, 0, 0, 6626, + 42763, 130034, 118884, 128613, 0, 83128, 0, 0, 0, 0, 0, 983561, 0, 0, 0, + 9171, 0, 0, 71305, 983919, 121146, 0, 101095, 128881, 119604, 126596, 0, + 0, 0, 128214, 42368, 0, 983106, 2271, 41487, 12118, 74124, 68651, 110836, + 110833, 3009, 41476, 41489, 69825, 3007, 1448, 3018, 0, 41491, 8521, + 5083, 5082, 0, 0, 8519, 0, 3014, 5081, 73926, 0, 128549, 0, 69951, 5079, + 129963, 2557, 128086, 65532, 11828, 0, 71297, 11105, 0, 0, 0, 8518, + 10779, 0, 71303, 0, 0, 42170, 110769, 0, 629, 1924, 0, 12037, 0, 5987, + 8462, 127744, 0, 63933, 69735, 110770, 128295, 63941, 67981, 5077, 0, + 10880, 64849, 5075, 0, 128152, 65075, 0, 11007, 983736, 0, 0, 0, 66684, + 72331, 3434, 72338, 1904, 0, 0, 72730, 0, 10499, 4507, 9578, 63925, 0, + 7979, 0, 9831, 66689, 0, 461, 194834, 0, 4504, 0, 0, 6325, 0, 43021, 0, + 0, 55236, 0, 0, 5177, 41324, 12055, 63831, 0, 41327, 12591, 0, 4114, 409, + 0, 0, 8948, 41325, 0, 721, 10182, 0, 71311, 0, 0, 94052, 74963, 83503, + 5998, 0, 0, 74825, 0, 12587, 0, 78571, 74889, 71328, 128955, 0, 74121, + 78570, 73499, 0, 0, 5995, 0, 42568, 0, 0, 63944, 73860, 126586, 0, 4167, + 0, 43175, 0, 74120, 0, 65076, 938, 73857, 73854, 11737, 9721, 0, 0, 0, + 11742, 0, 0, 11493, 12334, 128762, 0, 66623, 0, 9173, 0, 11978, 0, 12734, + 113750, 113741, 0, 6759, 0, 0, 0, 126222, 0, 70388, 129093, 13027, 42777, + 7683, 1167, 0, 4983, 0, 861, 0, 0, 68297, 0, 43757, 92978, 129298, + 122630, 127804, 0, 73546, 70815, 9616, 0, 0, 12816, 43759, 0, 12710, + 68674, 12721, 4101, 66185, 0, 5992, 7616, 0, 0, 12577, 0, 0, 853, 42693, + 0, 121088, 0, 0, 917915, 0, 42835, 0, 0, 0, 0, 0, 12712, 7105, 127807, + 65060, 66875, 9900, 0, 0, 0, 121482, 119265, 0, 64778, 12585, 0, 0, 0, 0, + 0, 0, 77826, 0, 4900, 125245, 0, 0, 0, 4119, 74768, 8971, 0, 0, 0, 78594, + 41132, 9245, 73060, 0, 4138, 194841, 0, 0, 0, 77827, 0, 13054, 0, 0, + 128416, 110760, 0, 0, 3948, 128878, 0, 0, 0, 1680, 0, 11861, 0, 0, + 120032, 0, 0, 0, 0, 74833, 74190, 5993, 42709, 0, 12706, 77846, 1893, 0, + 63915, 0, 0, 110744, 129826, 0, 63997, 120018, 63996, 3077, 0, 0, 1512, + 0, 12589, 41479, 0, 0, 0, 0, 11831, 120727, 122949, 41481, 0, 118912, 0, + 3090, 0, 3086, 1664, 1850, 0, 3079, 0, 0, 94080, 127140, 0, 0, 74401, 0, + 917555, 0, 0, 0, 0, 0, 11526, 63985, 5864, 0, 63992, 0, 63991, 0, 5480, + 7858, 0, 4116, 78149, 0, 0, 0, 63907, 0, 0, 126131, 63905, 119601, 0, + 983191, 0, 119666, 0, 0, 7534, 507, 91, 2042, 120775, 118596, 0, 66028, + 118811, 41844, 70680, 774, 0, 0, 0, 5994, 0, 12733, 0, 0, 0, 72297, 0, 0, + 0, 0, 6026, 0, 0, 0, 162, 0, 125247, 78151, 78152, 983590, 92709, 0, + 68304, 0, 0, 0, 66658, 0, 0, 0, 0, 121511, 2226, 121512, 129349, 10492, + 0, 121510, 0, 43119, 0, 0, 0, 66192, 0, 0, 4899, 12729, 0, 0, 0, 0, 4103, + 0, 129842, 77851, 69429, 129046, 0, 12859, 70087, 0, 101580, 0, 0, 0, 0, + 0, 0, 65264, 5146, 0, 194694, 71684, 0, 0, 983652, 983863, 78924, 71688, + 78463, 5147, 125019, 0, 74524, 71682, 128435, 0, 194692, 5991, 3445, 0, + 4976, 66193, 0, 0, 0, 0, 128309, 128594, 129819, 69579, 0, 63855, 0, + 10138, 0, 0, 8897, 0, 75027, 0, 120931, 77862, 65836, 0, 0, 77860, 0, 0, + 1123, 4124, 41553, 77903, 0, 71680, 121386, 398, 0, 129035, 41551, 0, 0, + 0, 41550, 9970, 0, 93062, 42392, 1305, 78901, 0, 129292, 0, 7346, 41464, + 0, 0, 0, 41465, 983567, 8528, 9149, 0, 63955, 165, 3024, 11852, 119163, + 0, 9093, 0, 9147, 0, 0, 110989, 9148, 0, 4096, 53, 8296, 0, 71352, 0, + 9594, 0, 0, 63952, 0, 10997, 0, 0, 5805, 0, 0, 129777, 42176, 71455, + 74601, 129604, 10591, 0, 92852, 0, 0, 0, 0, 0, 0, 92475, 0, 0, 42379, 0, + 0, 9220, 0, 121425, 0, 0, 4132, 0, 0, 11239, 0, 0, 74837, 0, 66408, 0, + 8055, 0, 0, 0, 63962, 74042, 8924, 43123, 5988, 0, 63969, 0, 42718, 8788, + 1357, 77872, 65743, 0, 8774, 0, 0, 0, 0, 92748, 120598, 128234, 9564, 0, + 0, 119124, 0, 121241, 110983, 92975, 3121, 0, 0, 0, 70081, 0, 0, 0, 0, 0, + 64851, 0, 0, 73085, 119532, 0, 0, 0, 0, 1198, 69293, 66708, 64619, 0, + 64663, 93991, 0, 0, 2101, 1398, 0, 92554, 0, 0, 92684, 11406, 101588, + 12127, 66998, 840, 0, 0, 7101, 120938, 0, 0, 12880, 0, 43104, 0, 0, 0, + 2117, 0, 0, 0, 0, 123023, 0, 0, 7769, 129867, 92413, 0, 0, 100695, 0, + 40986, 83117, 0, 0, 4127, 0, 0, 129034, 0, 0, 0, 70738, 0, 129466, 0, 0, + 0, 0, 119081, 0, 10581, 0, 4533, 0, 128941, 6490, 0, 12038, 0, 0, 68225, + 0, 0, 69704, 0, 1948, 119007, 129607, 101586, 0, 0, 0, 120802, 0, 9494, + 0, 0, 0, 4843, 0, 74772, 4098, 0, 0, 0, 3436, 0, 127279, 12817, 0, + 126607, 118678, 0, 0, 0, 74433, 0, 0, 71962, 0, 121296, 65916, 0, 0, + 121458, 0, 129107, 93815, 0, 73743, 0, 0, 983133, 67676, 0, 0, 74627, + 128928, 0, 127892, 0, 71326, 67222, 0, 75013, 92435, 0, 128500, 0, 0, + 9613, 43425, 4526, 121415, 0, 64520, 71336, 0, 0, 55278, 10228, 64957, 0, + 0, 3807, 2081, 66640, 0, 0, 0, 0, 119269, 0, 128688, 0, 128142, 1451, 0, + 0, 4134, 0, 74847, 0, 74793, 0, 78913, 74295, 9960, 1201, 0, 12846, + 121271, 0, 11919, 64962, 0, 43739, 0, 66358, 0, 0, 0, 43679, 72284, + 72289, 0, 129523, 1253, 983870, 65766, 500, 65764, 65765, 65762, 65763, + 65760, 65761, 70334, 983867, 9821, 11702, 110630, 110631, 110628, 110629, + 128481, 0, 7533, 66717, 92500, 92305, 0, 0, 69277, 127758, 71332, 0, 0, + 0, 0, 11188, 0, 4112, 0, 0, 12890, 0, 0, 9915, 0, 68423, 0, 0, 2876, 0, + 0, 0, 0, 7382, 92415, 0, 128132, 0, 0, 0, 0, 69561, 127915, 0, 7003, 0, + 0, 7704, 0, 0, 0, 4123, 0, 0, 9977, 0, 0, 65759, 0, 0, 128266, 9808, 0, + 92611, 4126, 0, 9521, 9589, 64755, 0, 0, 0, 69948, 0, 92368, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 93814, 0, 0, 92234, 0, 10693, 0, 0, 65897, 4058, 0, 0, + 64660, 0, 0, 0, 983730, 1139, 43298, 0, 65929, 8970, 0, 9934, 0, 11023, + 128020, 42522, 0, 0, 0, 78899, 3057, 128113, 7349, 69959, 128722, 68065, + 110813, 0, 92826, 67201, 0, 0, 0, 9528, 0, 0, 0, 9102, 627, 92827, 6273, + 129496, 0, 0, 983212, 92966, 43300, 0, 983740, 11696, 92825, 1018, 65554, + 0, 74338, 0, 7645, 0, 128321, 0, 0, 0, 0, 73814, 11544, 12563, 10728, 0, + 0, 127340, 43311, 64966, 92841, 0, 0, 118946, 0, 0, 74779, 0, 185, 65085, + 74533, 0, 0, 7535, 0, 42525, 0, 9749, 41701, 6131, 0, 4117, 129062, + 126988, 0, 92429, 65693, 0, 73445, 0, 69695, 0, 0, 0, 0, 0, 0, 0, 1184, + 0, 815, 0, 0, 0, 0, 0, 71325, 0, 0, 64683, 983816, 0, 127959, 0, 0, 0, 0, + 0, 0, 0, 68166, 0, 0, 0, 0, 66799, 0, 128912, 0, 5142, 0, 69643, 0, 0, + 68367, 93975, 0, 0, 0, 123209, 124133, 0, 0, 74855, 121330, 0, 0, 0, 0, + 10940, 66030, 0, 70385, 73494, 0, 2652, 120527, 0, 129946, 0, 126508, 0, + 0, 0, 0, 0, 0, 1828, 0, 128357, 0, 8531, 0, 74799, 12324, 72434, 65238, 68374, 0, 65573, 0, 68308, 68679, 12904, 43445, 0, 0, 0, 11247, 0, 0, 41426, 0, 0, 0, 0, 0, 67250, 69451, 83354, 11869, 0, 0, 0, 0, 0, 0, 637, 0, 0, 0, 121178, 0, 0, 74474, 71306, 0, 7298, 128256, 0, 0, 0, 0, 8210, @@ -27866,32 +28056,32 @@ static const unsigned int code_hash[] = { 129875, 0, 71485, 0, 917837, 0, 0, 78157, 0, 0, 0, 0, 0, 71313, 0, 70710, 128212, 0, 72238, 67858, 0, 0, 0, 0, 0, 0, 0, 10770, 118994, 0, 465, 0, 983656, 74348, 0, 0, 0, 0, 0, 0, 0, 10930, 0, 0, 0, 119091, 69388, - 122637, 129918, 0, 0, 0, 0, 0, 10092, 0, 0, 0, 0, 0, 1766, 11282, 11996, - 66644, 4547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120906, 4345, 0, 0, 128947, 0, 0, - 0, 0, 0, 5382, 0, 0, 118552, 0, 0, 5406, 43127, 120007, 0, 3590, 129874, - 0, 0, 0, 42016, 0, 0, 121002, 0, 7742, 0, 66562, 71323, 0, 0, 5310, 0, - 123625, 0, 43594, 0, 128260, 66723, 0, 73816, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1326, 128723, 0, 0, 74519, 0, 0, 0, 0, 71308, 0, 5410, 5783, 0, 8403, - 5400, 120526, 0, 128863, 0, 0, 0, 64412, 0, 0, 5587, 42865, 71858, 0, 0, - 129854, 0, 113785, 0, 120755, 0, 69738, 0, 74867, 10461, 12103, 0, 0, - 70701, 0, 0, 0, 0, 0, 94009, 0, 2760, 0, 8816, 41515, 0, 11802, 0, 7585, - 910, 0, 0, 0, 3658, 83386, 120525, 0, 7617, 0, 12888, 0, 0, 64631, 0, - 41514, 11097, 5703, 0, 41517, 41504, 41519, 0, 70104, 0, 65864, 0, - 120533, 0, 121037, 0, 0, 43553, 120774, 0, 0, 0, 0, 0, 1578, 0, 43449, 0, - 0, 8225, 121191, 94024, 72799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110655, - 0, 110656, 121247, 72213, 0, 110658, 0, 74997, 0, 3195, 10999, 983570, - 7897, 0, 1203, 74396, 0, 64544, 0, 0, 0, 2877, 0, 0, 0, 121112, 0, 0, - 128977, 119607, 0, 0, 0, 0, 983623, 0, 0, 0, 0, 0, 0, 0, 0, 983078, 0, 0, - 0, 9939, 0, 0, 0, 0, 0, 0, 0, 10714, 0, 0, 0, 0, 0, 67738, 0, 74038, 0, - 42897, 0, 0, 0, 0, 0, 0, 7730, 0, 0, 0, 11163, 0, 0, 0, 113701, 4966, - 128802, 70674, 129468, 123207, 3841, 0, 0, 983228, 77886, 0, 4972, 0, - 64699, 0, 0, 0, 0, 0, 12705, 10203, 9608, 0, 0, 11962, 121397, 0, 1196, - 67684, 0, 777, 0, 0, 65271, 0, 0, 0, 0, 64824, 983194, 0, 9454, 63778, - 8658, 0, 0, 2705, 0, 64894, 0, 0, 11986, 92636, 0, 8280, 0, 2701, 0, 0, - 0, 0, 0, 9809, 0, 0, 0, 0, 0, 63761, 1748, 0, 65719, 121078, 0, 0, 0, - 55244, 3061, 0, 63765, 63787, 0, 41520, 0, 7694, 0, 8896, 63768, 55282, - 0, 127781, 0, 0, 63807, 1591, 0, 6386, 118554, 0, 0, 0, 983199, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 68289, 0, 0, 7624, 67487, 10996, 92247, 10609, 0, + 122637, 129918, 0, 0, 0, 0, 0, 10092, 0, 0, 0, 0, 119019, 1766, 11282, + 11996, 66644, 4547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120906, 4345, 0, 0, + 128947, 0, 0, 0, 0, 0, 5382, 0, 0, 118552, 0, 0, 5406, 43127, 120007, 0, + 3590, 129874, 0, 0, 0, 42016, 0, 0, 121002, 0, 7742, 0, 66562, 71323, 0, + 0, 5310, 0, 123625, 0, 43594, 0, 128260, 66723, 0, 73816, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1326, 128723, 0, 0, 74519, 0, 0, 0, 0, 71308, 0, 5410, 5783, + 0, 8403, 5400, 120526, 0, 128863, 0, 0, 0, 64412, 0, 0, 5587, 42865, + 71858, 0, 0, 129854, 0, 113785, 0, 120755, 0, 69738, 0, 74867, 10461, + 12103, 0, 0, 70701, 0, 0, 0, 0, 0, 94009, 0, 2760, 0, 8816, 41515, 0, + 11802, 0, 7585, 910, 0, 0, 0, 3658, 83386, 120525, 0, 7617, 0, 12888, 0, + 0, 64631, 0, 41514, 11097, 5703, 0, 41517, 41504, 41519, 0, 70104, 0, + 65864, 0, 120533, 0, 121037, 0, 0, 43553, 120774, 0, 0, 0, 0, 0, 1578, 0, + 43449, 0, 0, 8225, 121191, 94024, 72799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 110655, 0, 110656, 121247, 72213, 0, 110658, 0, 74997, 0, 3195, 10999, + 983570, 7897, 0, 1203, 74396, 0, 64544, 0, 0, 0, 2877, 0, 0, 0, 121112, + 0, 0, 128977, 119607, 0, 0, 0, 0, 983623, 0, 0, 0, 0, 0, 0, 0, 0, 983078, + 0, 0, 0, 9939, 0, 0, 0, 0, 0, 0, 0, 10714, 0, 0, 0, 0, 0, 67738, 0, + 74038, 0, 42897, 0, 0, 0, 0, 0, 0, 7730, 0, 0, 0, 11163, 0, 0, 0, 113701, + 4966, 128802, 70674, 129468, 123207, 3841, 0, 0, 983231, 77886, 0, 4972, + 0, 64699, 0, 0, 0, 0, 0, 12705, 10203, 9608, 0, 0, 11962, 121397, 0, + 1196, 67684, 0, 777, 0, 0, 65271, 0, 0, 0, 0, 64824, 983195, 0, 9454, + 63778, 8658, 0, 0, 2705, 0, 64894, 0, 0, 11986, 92636, 0, 8280, 0, 2701, + 0, 0, 0, 0, 0, 9809, 0, 0, 0, 0, 0, 63761, 1748, 0, 65719, 121078, 0, 0, + 0, 55244, 3061, 0, 63765, 63787, 0, 41520, 0, 7694, 0, 8896, 63768, + 55282, 0, 127781, 0, 0, 63807, 1591, 0, 6386, 118554, 0, 0, 0, 983200, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68289, 0, 0, 7624, 67487, 10996, 92247, 10609, 0, 127181, 10987, 0, 70370, 3894, 0, 0, 0, 0, 493, 0, 0, 1717, 12228, 479, 917941, 129347, 129473, 917935, 917939, 917924, 917932, 92303, 64315, 92170, 0, 83522, 6233, 42681, 83525, 83518, 83519, 64911, 83521, 0, 0, @@ -27929,9 +28119,9 @@ static const unsigned int code_hash[] = { 128832, 100930, 0, 0, 0, 0, 0, 129776, 128546, 0, 0, 120914, 0, 0, 0, 0, 917822, 128810, 983676, 65599, 0, 9966, 12607, 4948, 128070, 0, 128149, 0, 0, 6207, 0, 6117, 73916, 0, 0, 0, 0, 68244, 41511, 0, 129489, 127304, - 0, 121289, 0, 118618, 83031, 83032, 0, 41556, 0, 0, 0, 128571, 73766, 0, + 0, 121289, 0, 118618, 83031, 83032, 0, 41556, 0, 0, 0, 128571, 73504, 0, 0, 118645, 41510, 7953, 0, 0, 41513, 0, 0, 0, 83038, 83039, 83040, 83041, - 83034, 83035, 848, 9868, 983149, 6424, 118625, 83033, 0, 0, 0, 0, 118539, + 83034, 83035, 848, 9868, 983150, 6424, 118625, 83033, 0, 0, 0, 0, 118539, 0, 893, 64576, 13299, 0, 0, 71998, 71447, 0, 0, 0, 0, 8903, 0, 0, 0, 8099, 0, 0, 0, 0, 0, 0, 0, 0, 113713, 0, 0, 0, 0, 0, 83027, 41483, 83029, 83030, 83023, 83024, 69436, 64836, 194756, 41485, 194758, 194757, 194760, @@ -27943,7 +28133,7 @@ static const unsigned int code_hash[] = { 0, 2108, 0, 73929, 0, 0, 10617, 194737, 128031, 194739, 194738, 68614, 194740, 68611, 9924, 129952, 194744, 0, 0, 0, 3277, 0, 4947, 41055, 0, 194722, 129930, 194724, 194723, 64626, 194725, 42266, 194727, 8371, - 194729, 127028, 12806, 41492, 0, 0, 73930, 194731, 194730, 41054, 1078, + 194729, 127028, 12806, 41492, 0, 0, 73930, 194731, 124140, 41054, 1078, 194735, 194734, 41057, 0, 0, 0, 0, 0, 92210, 73009, 0, 41496, 0, 9165, 1572, 0, 129712, 0, 128635, 9215, 9330, 129809, 10032, 41745, 43183, 6401, 5831, 0, 0, 0, 8056, 0, 65681, 92377, 0, 0, 0, 121048, 0, 118887, @@ -27972,13 +28162,13 @@ static const unsigned int code_hash[] = { 74317, 0, 8319, 194714, 194717, 10960, 72196, 8305, 12573, 983620, 72193, 0, 13202, 0, 12582, 0, 72198, 69856, 0, 0, 78598, 0, 72195, 0, 65802, 74822, 7698, 12708, 74045, 0, 0, 70460, 4913, 127990, 0, 123539, 0, 0, - 12728, 129980, 0, 0, 101281, 0, 130038, 0, 101283, 0, 12588, 8821, 6153, - 194705, 78900, 194707, 194710, 194709, 194712, 194711, 118854, 194713, - 651, 0, 0, 0, 0, 0, 78468, 78469, 69433, 78467, 69614, 74905, 194695, - 78461, 194697, 194696, 0, 4716, 43277, 0, 2185, 78475, 128592, 120928, - 194700, 55264, 194702, 12732, 0, 12707, 0, 0, 0, 0, 121417, 8479, 4151, - 0, 0, 0, 0, 0, 0, 0, 0, 113799, 0, 74050, 0, 0, 0, 0, 0, 129467, 12278, - 0, 129507, 0, 2700, 12576, 7842, 0, 67471, 0, 2699, 0, 0, 2985, 0, + 12728, 129980, 128895, 0, 101281, 0, 130038, 0, 101283, 0, 12588, 8821, + 6153, 194705, 78900, 194707, 194710, 194709, 194712, 194711, 118854, + 194713, 651, 0, 0, 0, 0, 0, 78468, 78469, 69433, 78467, 69614, 74905, + 194695, 78461, 194697, 194696, 0, 4716, 43277, 0, 2185, 78475, 128592, + 120928, 194700, 55264, 194702, 12732, 0, 12707, 0, 0, 0, 0, 121417, 8479, + 4151, 0, 0, 0, 0, 0, 0, 0, 0, 113799, 0, 74050, 0, 0, 0, 0, 0, 129467, + 12278, 0, 129507, 0, 2700, 12576, 7842, 0, 67471, 0, 2699, 0, 0, 2985, 0, 126475, 0, 129873, 119314, 0, 119312, 9827, 101292, 119311, 101291, 119309, 119306, 11481, 118718, 119305, 0, 35, 78481, 78482, 66694, 78480, 78477, 78478, 0, 0, 64257, 0, 0, 0, 78485, 78486, 78483, 4272, 0, 0, @@ -27988,7 +28178,7 @@ static const unsigned int code_hash[] = { 128628, 101088, 0, 12346, 128596, 101089, 0, 0, 7251, 0, 0, 118850, 73025, 0, 0, 0, 0, 0, 12564, 66457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101131, 0, 41564, 10976, 0, 121223, 0, 0, 10054, 9197, 120618, 0, 9012, 65737, - 74420, 0, 13215, 12730, 0, 0, 0, 0, 816, 0, 101123, 0, 83191, 0, 0, + 74420, 0, 13215, 12730, 0, 0, 0, 0, 816, 0, 101123, 122664, 83191, 0, 0, 92752, 101120, 4715, 94107, 94106, 71075, 0, 0, 0, 67729, 0, 307, 0, 9585, 0, 0, 0, 101255, 0, 125267, 0, 70727, 65567, 101238, 75006, 101231, 983909, 0, 12236, 41419, 101259, 194621, 101248, 75003, 194622, 73675, @@ -28010,89 +28200,90 @@ static const unsigned int code_hash[] = { 100813, 100816, 100815, 100818, 100817, 100798, 100797, 41410, 100799, 64262, 0, 41407, 75000, 0, 0, 93812, 0, 0, 72803, 74999, 78897, 0, 0, 67675, 0, 0, 0, 0, 43647, 0, 0, 100792, 100791, 100794, 100793, 100796, - 100795, 0, 74630, 11933, 0, 0, 41903, 67892, 11001, 100801, 42255, + 100795, 983276, 74630, 11933, 0, 0, 41903, 67892, 11001, 100801, 42255, 100803, 100802, 100805, 41905, 100807, 100806, 10775, 9793, 0, 0, 74452, 0, 983063, 42535, 0, 64529, 41408, 42853, 0, 0, 42674, 118915, 0, 0, 983807, 0, 70838, 0, 0, 0, 64506, 0, 66738, 4747, 100783, 69844, 100785, - 5832, 0, 0, 5141, 42600, 0, 0, 0, 0, 0, 0, 93790, 0, 7657, 0, 71132, + 5832, 0, 0, 5141, 42600, 124147, 0, 0, 0, 0, 0, 93790, 0, 7657, 0, 71132, 74137, 0, 128362, 73682, 73681, 859, 0, 0, 0, 6059, 126985, 55235, 0, 0, - 0, 0, 0, 100787, 11488, 72838, 100788, 0, 100790, 10558, 0, 0, 118646, - 126090, 71069, 0, 0, 1788, 0, 0, 0, 0, 119571, 92822, 9028, 0, 69234, - 73665, 0, 9905, 128485, 41242, 70086, 0, 74109, 100765, 100764, 100767, - 100766, 70830, 83184, 70082, 3940, 0, 43754, 0, 128188, 8665, 0, 0, 0, - 1653, 100775, 42406, 100777, 100780, 70825, 120523, 0, 8815, 0, 65046, 0, - 42445, 0, 11180, 119318, 119315, 68454, 42485, 0, 0, 8211, 42293, 983602, - 0, 0, 0, 0, 65385, 100771, 42332, 100773, 78431, 78432, 78423, 78430, - 78420, 10022, 65387, 78419, 65384, 0, 0, 0, 65386, 0, 11248, 0, 43198, - 64751, 0, 0, 0, 0, 0, 0, 101102, 7363, 0, 0, 119323, 119324, 100752, - 100751, 0, 119320, 0, 983632, 0, 8237, 0, 0, 0, 0, 0, 0, 9914, 0, 100763, - 100762, 120009, 6351, 119993, 92740, 68766, 0, 120010, 41243, 0, 74108, - 11467, 120165, 119998, 4358, 0, 6353, 0, 0, 0, 93045, 1710, 0, 0, 92237, - 0, 49, 73871, 120005, 78671, 0, 78672, 9741, 78443, 78444, 78441, 43443, - 78439, 78440, 69244, 78438, 3470, 0, 0, 92814, 0, 0, 78445, 0, 1072, - 78457, 78452, 78454, 74230, 78451, 78447, 78449, 1080, 0, 74100, 0, 1101, - 68404, 78458, 78459, 71082, 0, 1086, 1869, 0, 0, 0, 65458, 0, 0, 41988, - 0, 1091, 0, 7977, 0, 66992, 0, 0, 0, 92758, 0, 0, 0, 0, 0, 71255, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 64582, 0, 0, 70794, 0, 120989, 128495, 74106, 0, - 66883, 0, 0, 0, 0, 0, 0, 0, 92553, 43752, 110592, 0, 71249, 120886, 0, 0, - 0, 0, 6063, 100857, 101221, 917995, 6053, 74096, 0, 0, 74169, 13100, 0, - 917999, 0, 71081, 0, 70387, 6055, 7800, 4279, 8490, 120114, 120111, - 64786, 8602, 120110, 83389, 92204, 0, 0, 74961, 0, 120117, 120118, - 120099, 120100, 65087, 64402, 3674, 120096, 0, 120094, 120107, 118624, - 120105, 10107, 42159, 42870, 120101, 69632, 0, 0, 43281, 127078, 0, - 74098, 0, 0, 126497, 74099, 129056, 0, 0, 0, 121123, 5847, 125258, 0, 0, - 0, 0, 0, 66592, 64469, 71698, 19966, 0, 42561, 0, 129170, 66854, 8120, - 75042, 0, 0, 0, 0, 0, 0, 126068, 8369, 0, 0, 122912, 3369, 0, 121094, 0, - 0, 69238, 10495, 121365, 0, 557, 9457, 0, 0, 121054, 73880, 127220, 0, - 74937, 74094, 0, 0, 0, 92171, 127219, 128175, 127939, 120424, 0, 127214, - 2109, 67893, 127211, 69656, 127217, 10604, 127215, 0, 0, 0, 0, 126561, 0, - 0, 0, 0, 1618, 0, 0, 83175, 10430, 0, 0, 13063, 917585, 0, 92982, 113666, - 0, 78390, 83489, 12060, 0, 113669, 0, 6329, 0, 0, 0, 74395, 2707, 8309, - 0, 127054, 78398, 0, 2697, 0, 78396, 127057, 2695, 0, 0, 68334, 0, 0, 0, - 72325, 2693, 74091, 0, 0, 2703, 113729, 70283, 41918, 983168, 127542, - 8687, 127543, 12178, 43361, 92540, 64075, 110705, 5248, 110703, 120538, - 6427, 0, 0, 0, 0, 110710, 0, 74990, 74989, 70703, 127031, 0, 9873, 0, 0, - 0, 64762, 2053, 0, 6591, 9340, 0, 1589, 0, 296, 67712, 128315, 12766, - 118931, 74370, 120417, 2414, 128068, 43829, 111202, 74836, 0, 12579, 0, - 12575, 6416, 5656, 0, 13262, 65590, 5299, 983702, 0, 5449, 1252, 0, - 78404, 69748, 74369, 65373, 5295, 0, 121066, 1223, 1642, 78408, 0, 12158, - 5303, 0, 120546, 41413, 3212, 127025, 3211, 74810, 41425, 127029, 0, - 74450, 9728, 0, 10924, 74778, 6636, 0, 129884, 0, 0, 129882, 9519, 0, 0, - 129106, 101110, 68780, 0, 0, 0, 119182, 0, 12104, 77942, 77951, 9004, 0, - 74249, 10230, 0, 0, 0, 77947, 0, 69679, 121475, 9890, 125049, 12971, 0, - 92556, 0, 67903, 70051, 983924, 0, 0, 9635, 12600, 0, 0, 0, 118900, 6469, - 0, 101113, 65304, 4679, 101114, 64300, 64867, 6531, 101118, 101099, - 101098, 92813, 101100, 42916, 0, 0, 0, 0, 0, 0, 4445, 72296, 0, 11533, 0, - 3416, 129148, 0, 0, 0, 78566, 0, 0, 101091, 92815, 101093, 5447, 72140, - 70752, 101097, 101096, 0, 0, 0, 64448, 0, 43920, 70677, 0, 6232, 101101, - 101104, 101103, 43608, 101105, 101108, 6538, 4335, 0, 3941, 74986, 11061, - 0, 74988, 74987, 0, 12155, 128278, 0, 0, 0, 0, 74578, 0, 65832, 0, - 129459, 70789, 0, 125050, 0, 0, 350, 10951, 101081, 509, 101083, 101086, - 101085, 0, 0, 0, 917540, 0, 100905, 110970, 12162, 64741, 0, 9354, 0, - 70802, 100901, 2496, 11516, 944, 128238, 0, 0, 1438, 0, 0, 120185, 70785, - 1220, 917952, 93844, 0, 0, 5008, 42630, 70787, 101087, 2229, 68206, 564, - 0, 312, 0, 0, 0, 70797, 8877, 269, 0, 128065, 9617, 0, 0, 100910, 0, 0, - 10862, 0, 0, 41416, 0, 4173, 0, 0, 0, 1906, 983854, 41418, 74073, 101068, - 101067, 41415, 69622, 9582, 0, 64287, 0, 0, 11428, 1730, 0, 0, 19918, - 10469, 101076, 101079, 68088, 0, 101080, 72342, 0, 129692, 0, 6129, 0, 0, - 0, 0, 7874, 0, 0, 11206, 13136, 118529, 129305, 0, 64374, 74925, 0, - 73892, 0, 101073, 101072, 101075, 74960, 9228, 101054, 101057, 101056, - 5240, 9811, 0, 101060, 129718, 0, 0, 74079, 65873, 0, 0, 0, 9501, 0, - 68081, 72808, 65465, 64654, 7467, 0, 0, 83460, 10040, 0, 3096, 0, 101053, - 101052, 68820, 83461, 0, 0, 0, 0, 0, 0, 83377, 0, 68801, 0, 101062, - 101061, 101064, 101063, 0, 8637, 70741, 0, 77983, 77969, 11471, 43554, 0, - 77968, 0, 0, 0, 2426, 12042, 0, 0, 0, 3961, 12115, 129633, 0, 77972, - 64561, 0, 4981, 74644, 129558, 0, 0, 42686, 77976, 128776, 64686, 0, - 77958, 7589, 0, 0, 3237, 0, 68215, 0, 8541, 127157, 71067, 120174, 0, 0, - 0, 0, 0, 43555, 0, 0, 10060, 111261, 100917, 0, 0, 0, 64877, 0, 0, 8614, - 65220, 41493, 0, 0, 0, 43780, 0, 0, 70689, 0, 0, 0, 0, 0, 0, 4012, 10395, - 0, 0, 111253, 126511, 111254, 125051, 695, 739, 696, 7611, 0, 42755, - 68421, 9227, 7506, 7510, 67493, 691, 738, 7511, 7512, 7515, 7501, 688, - 41847, 690, 2548, 737, 974, 43386, 0, 0, 0, 0, 0, 0, 65860, 0, 7051, - 69777, 4682, 0, 983096, 6406, 4685, 0, 0, 10347, 4680, 6341, 0, 0, 92607, - 74325, 0, 123555, 0, 0, 0, 0, 0, 0, 43505, 92468, 11718, 42373, 11714, 0, - 0, 129567, 11717, 0, 10594, 129732, 11712, 0, 0, 10967, 0, 0, 0, 66632, - 118647, 0, 0, 0, 1735, 0, 11134, 2363, 983135, 0, 0, 70695, 128032, 0, + 0, 0, 0, 100787, 11488, 72838, 100788, 0, 100790, 10558, 0, 124144, + 118646, 126090, 71069, 0, 0, 1788, 0, 0, 0, 0, 119571, 92822, 9028, 0, + 69234, 73665, 0, 9905, 73556, 41242, 70086, 0, 74109, 100765, 100764, + 100767, 100766, 70830, 83184, 70082, 3940, 0, 43754, 0, 128188, 8665, 0, + 0, 0, 1653, 100775, 42406, 100777, 100780, 70825, 120523, 0, 8815, 0, + 65046, 0, 42445, 0, 11180, 119318, 119315, 68454, 42485, 0, 0, 8211, + 42293, 983602, 0, 0, 0, 0, 65385, 100771, 42332, 100773, 78431, 78432, + 78423, 78430, 78420, 10022, 65387, 78419, 65384, 0, 0, 0, 65386, 0, + 11248, 0, 43198, 64751, 0, 0, 0, 0, 0, 0, 101102, 7363, 0, 0, 119323, + 119324, 100752, 100751, 0, 119320, 0, 983632, 0, 8237, 0, 0, 0, 0, 0, 0, + 9914, 0, 100763, 100762, 120009, 6351, 119993, 92740, 68766, 0, 120010, + 41243, 0, 74108, 11467, 120165, 119998, 4358, 0, 6353, 0, 0, 0, 93045, + 1710, 0, 0, 92237, 0, 49, 73871, 120005, 78671, 0, 78672, 9741, 78443, + 78444, 78441, 43443, 78439, 78440, 69244, 78438, 3470, 0, 0, 92814, 0, 0, + 78445, 0, 1072, 78457, 78452, 78454, 74230, 78451, 78447, 78449, 1080, 0, + 74100, 0, 1101, 68404, 78458, 78459, 71082, 0, 1086, 1869, 0, 0, 0, + 65458, 0, 0, 41988, 0, 1091, 0, 7977, 0, 66992, 0, 0, 0, 92758, 0, 0, 0, + 0, 0, 71255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64582, 0, 0, 70794, 0, 120989, + 128495, 74106, 0, 66883, 0, 0, 0, 0, 0, 0, 0, 92553, 43752, 110592, 0, + 71249, 120886, 0, 0, 0, 0, 6063, 100857, 101221, 917995, 6053, 74096, 0, + 0, 74169, 13100, 0, 917999, 0, 71081, 0, 70387, 6055, 7800, 4279, 8490, + 120114, 120111, 64786, 8602, 120110, 83389, 92204, 0, 0, 74961, 0, + 120117, 120118, 120099, 120100, 65087, 64402, 3674, 120096, 0, 120094, + 120107, 118624, 120105, 10107, 42159, 42870, 120101, 69632, 0, 0, 43281, + 127078, 0, 74098, 0, 0, 126497, 74099, 129056, 0, 0, 0, 121123, 5847, + 125258, 0, 0, 0, 0, 0, 66592, 64469, 71698, 19966, 0, 42561, 0, 129170, + 66854, 8120, 75042, 0, 0, 0, 0, 0, 0, 126068, 8369, 0, 0, 122912, 3369, + 0, 121094, 0, 0, 69238, 10495, 121365, 0, 557, 9457, 0, 0, 121054, 73880, + 127220, 0, 74937, 74094, 0, 0, 119001, 92171, 127219, 128175, 127939, + 120424, 0, 127214, 2109, 67893, 127211, 69656, 127217, 10604, 127215, 0, + 0, 0, 129727, 126561, 0, 0, 0, 0, 1618, 0, 0, 83175, 10430, 0, 0, 13063, + 917585, 0, 92982, 113666, 0, 78390, 83489, 12060, 0, 113669, 0, 6329, 0, + 0, 0, 74395, 2707, 8309, 0, 127054, 78398, 0, 2697, 0, 78396, 127057, + 2695, 0, 0, 68334, 0, 0, 0, 72325, 2693, 74091, 0, 0, 2703, 113729, + 70283, 41918, 983169, 127542, 8687, 127543, 12178, 43361, 92540, 64075, + 110705, 5248, 110703, 120538, 6427, 0, 0, 0, 0, 110710, 0, 74990, 74989, + 70703, 127031, 0, 9873, 0, 0, 0, 64762, 2053, 0, 6591, 9340, 0, 1589, 0, + 296, 67712, 128315, 12766, 118931, 74370, 120417, 2414, 128068, 43829, + 111202, 74836, 0, 12579, 0, 12575, 6416, 5656, 0, 13262, 65590, 5299, + 983702, 0, 5449, 1252, 0, 78404, 69748, 74369, 65373, 5295, 0, 121066, + 1223, 1642, 78408, 0, 12158, 5303, 0, 120546, 41413, 3212, 127025, 3211, + 74810, 41425, 127029, 0, 74450, 9728, 0, 10924, 74778, 6636, 73552, + 129884, 0, 0, 129882, 9519, 0, 0, 129106, 101110, 68780, 0, 0, 0, 119182, + 0, 12104, 77942, 77951, 9004, 0, 74249, 10230, 0, 0, 0, 77947, 0, 69679, + 121475, 9890, 125049, 12971, 0, 92556, 0, 67903, 70051, 983924, 0, 0, + 9635, 12600, 0, 0, 0, 118900, 6469, 0, 101113, 65304, 4679, 101114, + 64300, 64867, 6531, 101118, 101099, 101098, 92813, 101100, 42916, 0, 0, + 0, 0, 0, 0, 4445, 72296, 0, 11533, 0, 3416, 124112, 0, 0, 0, 78566, 0, 0, + 101091, 92815, 101093, 5447, 72140, 70752, 101097, 101096, 0, 0, 0, + 64448, 0, 43920, 70677, 0, 6232, 101101, 101104, 101103, 43608, 101105, + 101108, 6538, 4335, 0, 3941, 74986, 11061, 0, 74988, 74987, 0, 12155, + 128278, 0, 0, 0, 0, 74578, 0, 65832, 0, 129459, 70789, 0, 125050, 0, 0, + 350, 10951, 101081, 509, 101083, 101086, 101085, 0, 0, 0, 917540, 0, + 100905, 110970, 12162, 64741, 0, 9354, 0, 70802, 100901, 2496, 11516, + 944, 128238, 0, 0, 1438, 0, 0, 120185, 70785, 1220, 917952, 93844, 0, 0, + 5008, 42630, 70787, 101087, 2229, 68206, 564, 0, 312, 0, 0, 0, 70797, + 8877, 269, 0, 128065, 9617, 0, 0, 100910, 0, 0, 10862, 0, 0, 41416, 0, + 4173, 0, 0, 0, 1906, 983854, 41418, 74073, 101068, 101067, 41415, 69622, + 9582, 0, 64287, 0, 0, 11428, 1730, 0, 0, 19918, 10469, 101076, 101079, + 68088, 0, 101080, 72342, 0, 129692, 0, 6129, 0, 0, 0, 0, 7874, 0, 0, + 11206, 13136, 118529, 129305, 0, 64374, 74925, 0, 73892, 0, 101073, + 101072, 101075, 74960, 9228, 101054, 101057, 101056, 5240, 9811, 0, + 101060, 129718, 0, 0, 74079, 65873, 0, 0, 0, 9501, 0, 68081, 72808, + 65465, 64654, 7467, 0, 0, 83460, 10040, 0, 3096, 0, 101053, 101052, + 68820, 83461, 0, 0, 0, 0, 0, 0, 83377, 0, 68801, 0, 101062, 101061, + 101064, 101063, 0, 8637, 70741, 0, 77983, 77969, 11471, 43554, 0, 77968, + 0, 0, 0, 2426, 12042, 0, 0, 0, 3961, 12115, 129633, 0, 77972, 64561, 0, + 4981, 74644, 129558, 0, 0, 42686, 77976, 128776, 64686, 0, 77958, 7589, + 0, 0, 3237, 0, 68215, 0, 8541, 127157, 71067, 120174, 0, 0, 0, 0, 0, + 43555, 0, 0, 10060, 111261, 100917, 0, 0, 0, 64877, 0, 0, 8614, 65220, + 41493, 0, 0, 0, 43780, 0, 0, 70689, 0, 0, 0, 0, 0, 0, 4012, 10395, 0, 0, + 111253, 126511, 111254, 125051, 695, 739, 696, 7611, 0, 42755, 68421, + 9227, 7506, 7510, 67493, 691, 738, 7511, 7512, 7515, 7501, 688, 41847, + 690, 2548, 737, 974, 43386, 0, 0, 0, 0, 0, 0, 65860, 0, 7051, 69777, + 4682, 0, 983096, 6406, 4685, 0, 0, 10347, 4680, 6341, 0, 0, 92607, 74325, + 0, 123555, 0, 0, 0, 0, 0, 0, 43505, 92468, 11718, 42373, 11714, 0, 0, + 129567, 11717, 0, 10594, 129732, 11712, 122962, 0, 10967, 0, 0, 0, 66632, + 118647, 0, 0, 0, 1735, 0, 11134, 2363, 983136, 0, 0, 70695, 128032, 0, 7491, 7495, 7580, 7496, 7497, 7584, 121478, 127853, 0, 0, 70025, 0, 8498, 0, 8949, 3065, 0, 0, 0, 0, 0, 0, 11713, 0, 64939, 0, 6418, 4543, 0, 0, 0, 74800, 0, 0, 0, 0, 0, 0, 0, 12282, 3165, 0, 0, 64556, 0, 9238, 0, 68063, @@ -28100,166 +28291,167 @@ static const unsigned int code_hash[] = { 41400, 126636, 119664, 0, 42232, 0, 1744, 0, 41402, 0, 0, 0, 41399, 0, 125028, 0, 0, 12690, 0, 0, 43672, 0, 0, 0, 100870, 11315, 0, 278, 121204, 41405, 129345, 0, 10077, 129650, 70667, 0, 0, 0, 68210, 0, 0, 11189, - 70657, 0, 0, 0, 7934, 0, 93829, 120940, 0, 0, 0, 0, 0, 0, 6413, 6550, 0, - 1940, 2809, 43637, 70045, 0, 0, 10678, 0, 0, 0, 129701, 78804, 6403, - 6556, 78803, 0, 0, 123557, 0, 0, 0, 123553, 0, 3742, 74408, 3959, 0, 0, - 917969, 123565, 0, 128024, 0, 123558, 127956, 0, 0, 0, 6855, 4676, + 70657, 0, 0, 0, 7934, 0, 93829, 120940, 0, 0, 122971, 0, 0, 0, 6413, + 6550, 0, 1940, 2809, 43637, 70045, 0, 0, 10678, 0, 0, 0, 129701, 78804, + 6403, 6556, 78803, 0, 0, 123557, 0, 0, 0, 123553, 0, 3742, 74408, 3959, + 0, 0, 917969, 123565, 0, 128024, 0, 123558, 127956, 0, 0, 0, 6855, 4676, 983049, 9210, 0, 78143, 983922, 0, 78168, 983100, 11540, 43546, 6692, 0, 0, 0, 0, 9083, 0, 0, 78144, 128515, 0, 9677, 0, 70867, 74175, 0, 74070, 0, 0, 365, 0, 43027, 0, 0, 128236, 0, 119574, 70284, 13151, 0, 0, 127935, 127950, 544, 13249, 119018, 0, 120846, 0, 0, 73671, 65339, 73000, 2211, - 0, 0, 0, 0, 0, 0, 0, 0, 128037, 0, 0, 0, 0, 0, 0, 0, 127188, 0, 69708, - 9638, 0, 100878, 0, 0, 0, 74545, 128820, 128819, 75062, 128963, 0, 0, 0, - 11264, 43994, 0, 0, 0, 1311, 0, 0, 0, 0, 13068, 0, 0, 78164, 78155, 0, - 949, 0, 0, 0, 78176, 69709, 78177, 63828, 0, 0, 118629, 70282, 0, 0, 0, - 64822, 0, 6530, 983272, 0, 70493, 0, 129325, 0, 0, 4431, 118839, 127490, - 983760, 73667, 127986, 0, 10336, 10400, 0, 0, 92959, 0, 0, 0, 42270, - 128880, 6428, 0, 0, 0, 0, 43455, 0, 43526, 100888, 12835, 129501, 9493, - 0, 0, 11793, 0, 127897, 74394, 0, 10653, 0, 0, 0, 0, 6560, 7016, 74274, - 983627, 43556, 3929, 123615, 6614, 2768, 0, 65609, 0, 11811, 129696, 0, - 118615, 127513, 0, 6554, 0, 6305, 66283, 4675, 118826, 78552, 0, 0, - 74361, 0, 0, 68108, 0, 0, 92232, 0, 93022, 7392, 8230, 9365, 983742, 0, - 0, 0, 0, 42925, 0, 0, 0, 0, 229, 43834, 119884, 0, 43552, 119881, 119880, - 119883, 119882, 119877, 119876, 119879, 119878, 119873, 119872, 119875, - 119874, 0, 0, 0, 0, 0, 66352, 0, 0, 0, 128663, 0, 12239, 0, 0, 10432, - 12097, 0, 194815, 1233, 0, 0, 127200, 0, 66395, 0, 0, 129504, 0, 0, 0, 0, - 2388, 92555, 119868, 119871, 119870, 119865, 895, 92668, 119866, 64889, - 7143, 119863, 119862, 0, 0, 69983, 0, 74376, 3053, 2168, 0, 2047, 0, 0, - 0, 121279, 67985, 194801, 92600, 194803, 194802, 194805, 194804, 194807, - 194806, 129134, 194808, 0, 0, 0, 10473, 129331, 0, 194810, 129806, - 194812, 129813, 194814, 194813, 123195, 43528, 69673, 194791, 0, 194793, - 1912, 120779, 10306, 10370, 0, 0, 8867, 10250, 10258, 10274, 1635, - 120152, 0, 0, 0, 129379, 0, 0, 9919, 120148, 559, 128157, 41825, 127975, - 92989, 0, 74016, 194781, 6542, 41957, 7318, 0, 0, 41956, 65749, 65750, - 65751, 121323, 64487, 0, 0, 10223, 42062, 100640, 101195, 125044, 3668, - 65754, 43560, 12226, 0, 93973, 194784, 41959, 194786, 194785, 194788, - 43618, 65747, 10937, 2962, 0, 2953, 10062, 65745, 71457, 8921, 66013, - 129370, 0, 194769, 194768, 43409, 194770, 2949, 194772, 194775, 194774, - 2958, 194776, 74868, 2300, 2951, 120061, 0, 120043, 194778, 0, 120051, - 194779, 120056, 120065, 70798, 120048, 0, 120062, 120055, 71989, 100668, - 0, 0, 71985, 0, 71992, 70796, 127818, 0, 0, 64890, 0, 43630, 11336, 799, - 0, 10276, 10308, 10372, 917541, 0, 0, 10252, 10260, 68220, 55284, 125225, - 0, 10384, 0, 0, 0, 64523, 129744, 0, 65736, 0, 0, 0, 0, 0, 0, 0, 124912, - 43549, 65738, 42150, 65739, 0, 78195, 10288, 10320, 0, 10596, 129829, - 67673, 65045, 121283, 78198, 2049, 10098, 0, 122904, 127943, 10264, - 10280, 10312, 10376, 7013, 0, 69504, 0, 0, 66375, 0, 4862, 0, 6537, 0, - 128335, 3914, 92178, 93976, 9065, 64816, 0, 72218, 73026, 0, 0, 72139, - 4694, 11420, 4690, 0, 0, 983209, 4693, 0, 0, 0, 4688, 0, 0, 0, 0, 8238, - 3110, 0, 983939, 0, 6528, 0, 0, 0, 218, 0, 1520, 129577, 70039, 0, - 983594, 0, 120167, 78167, 10088, 6548, 100786, 0, 0, 0, 8888, 0, 124954, - 0, 0, 126593, 68876, 0, 0, 0, 0, 0, 0, 0, 4689, 43541, 77954, 120157, 0, - 120156, 78810, 120163, 0, 0, 0, 0, 78121, 0, 0, 11450, 0, 71900, 92613, - 0, 121317, 74622, 128720, 9244, 0, 0, 127763, 0, 0, 0, 0, 0, 0, 71084, 0, - 0, 0, 0, 10513, 0, 0, 0, 52, 119178, 0, 0, 93961, 0, 0, 4812, 0, 0, 0, 0, - 0, 0, 128425, 0, 6850, 0, 77959, 10170, 120450, 6544, 0, 0, 69782, - 121517, 0, 0, 65258, 10369, 0, 1585, 74014, 10249, 422, 1500, 2036, 986, - 0, 64394, 69502, 5599, 917981, 2494, 0, 0, 74021, 983896, 78203, 127808, - 0, 72871, 65102, 8961, 74305, 10243, 10245, 128170, 0, 0, 0, 0, 0, 2508, - 129591, 120440, 0, 120439, 0, 0, 0, 0, 0, 0, 64533, 983186, 0, 0, 74008, - 0, 0, 43375, 0, 2504, 0, 121313, 0, 983941, 6943, 0, 5859, 100677, 0, 0, - 72873, 983945, 0, 0, 983923, 92390, 2753, 1936, 2153, 67701, 2751, 12662, - 2763, 8953, 0, 10731, 0, 7052, 0, 0, 0, 0, 119899, 0, 66675, 0, 119897, - 0, 71053, 0, 119903, 0, 67829, 7899, 119901, 71119, 43798, 7072, 119902, - 122898, 11260, 0, 71059, 0, 0, 212, 0, 12350, 0, 0, 0, 0, 0, 128402, - 2759, 0, 0, 93064, 0, 0, 0, 1291, 0, 195065, 121318, 119911, 0, 119910, - 0, 12062, 0, 121216, 0, 129124, 121044, 120611, 8246, 128874, 0, 0, 0, 0, - 0, 73962, 0, 0, 43524, 0, 64426, 0, 0, 0, 0, 65664, 6693, 0, 0, 8674, 0, - 128812, 0, 11846, 70690, 121461, 69395, 4811, 0, 5986, 0, 3046, 74480, - 5985, 0, 0, 0, 0, 12187, 83148, 71041, 5984, 0, 93817, 4393, 126264, - 120206, 917599, 0, 0, 0, 93806, 93805, 0, 3491, 0, 67146, 0, 93819, 0, - 72428, 0, 0, 0, 124968, 41284, 126228, 0, 0, 41287, 0, 100689, 0, 0, - 92189, 0, 0, 219, 120874, 0, 0, 0, 68485, 119672, 43241, 0, 7147, 0, 0, - 0, 0, 0, 0, 64610, 11804, 0, 7149, 64808, 0, 0, 0, 92301, 73690, 0, 5253, - 0, 0, 0, 0, 129045, 983596, 11098, 68433, 0, 120484, 111009, 0, 0, 0, 0, - 0, 70801, 100779, 0, 128198, 9604, 0, 130036, 0, 0, 118941, 64392, 0, - 118684, 0, 0, 41974, 126262, 0, 0, 0, 129818, 0, 129833, 0, 0, 0, 0, 0, - 983240, 5308, 0, 290, 0, 125278, 128382, 2792, 0, 0, 120521, 0, 126237, - 0, 126099, 0, 0, 0, 0, 128503, 0, 0, 72816, 0, 0, 0, 92671, 0, 195061, - 42646, 7606, 2591, 73896, 0, 43513, 64482, 0, 0, 65270, 0, 0, 983701, - 9112, 0, 113763, 9490, 0, 0, 0, 0, 0, 9071, 0, 0, 0, 0, 74607, 0, 2535, - 65504, 43602, 0, 0, 71256, 2248, 0, 123147, 11845, 11006, 92315, 7807, - 8073, 0, 10629, 0, 74088, 0, 10823, 0, 113762, 8762, 0, 69689, 123536, - 43969, 65047, 10737, 3463, 67467, 129585, 66645, 0, 4815, 0, 0, 12345, - 983761, 0, 5195, 129808, 0, 66639, 0, 0, 66941, 0, 92759, 92385, 1262, 0, - 6561, 19939, 0, 0, 100772, 123160, 69269, 0, 100774, 0, 0, 0, 0, 0, 0, - 67511, 0, 0, 0, 0, 0, 0, 5702, 3655, 0, 8430, 0, 68807, 0, 0, 121137, 0, - 0, 5254, 0, 0, 124917, 0, 119107, 5129, 0, 70816, 0, 92280, 5614, 0, 0, - 11720, 0, 11721, 70804, 4798, 0, 120541, 66038, 4793, 67851, 7352, 0, 0, - 0, 0, 917600, 0, 300, 0, 0, 128575, 92660, 0, 0, 2562, 70156, 120856, 0, - 0, 92738, 0, 0, 127820, 71093, 0, 127969, 128221, 0, 3424, 93843, 0, 0, - 7074, 70873, 128519, 0, 0, 10832, 0, 0, 69852, 72430, 0, 0, 0, 0, 0, 176, - 0, 0, 0, 0, 0, 1215, 0, 5744, 0, 66440, 0, 0, 0, 42881, 0, 8980, 118988, - 67861, 8844, 7433, 0, 0, 4278, 124925, 0, 0, 70821, 9312, 4348, 0, - 128401, 65946, 0, 7087, 5255, 0, 661, 0, 0, 0, 0, 0, 0, 0, 121009, 73694, - 0, 123154, 0, 73688, 0, 127179, 3621, 83325, 66666, 72968, 0, 6562, - 12928, 0, 73991, 0, 0, 11383, 0, 0, 65588, 120739, 0, 0, 0, 0, 0, 0, 0, - 0, 11436, 2070, 64, 110824, 0, 10291, 10323, 10387, 0, 0, 0, 42008, 9708, - 42710, 0, 42011, 0, 92164, 0, 0, 1702, 1240, 128383, 6286, 9689, 111080, - 0, 0, 0, 1765, 0, 0, 92373, 0, 0, 0, 8401, 72991, 42014, 0, 67237, 0, 0, - 0, 0, 0, 0, 0, 70819, 0, 0, 0, 0, 12667, 0, 0, 10147, 0, 127568, 126483, - 72812, 0, 0, 0, 0, 123139, 128968, 0, 64947, 0, 0, 0, 0, 10435, 11462, 0, - 7084, 0, 0, 0, 0, 0, 126084, 0, 66662, 0, 0, 0, 0, 125134, 0, 0, 77990, - 263, 983747, 41288, 127953, 0, 78387, 74340, 70313, 129140, 0, 0, 0, - 42022, 71265, 0, 0, 0, 0, 0, 0, 42020, 123146, 0, 6992, 42019, 0, 41290, - 0, 12295, 126233, 71304, 0, 120984, 71300, 120631, 5954, 64931, 69385, - 100699, 198, 68453, 78129, 0, 121351, 0, 70818, 13165, 7107, 0, 42804, - 678, 72850, 118960, 0, 72985, 42806, 42808, 0, 0, 2097, 0, 120560, 70823, - 0, 0, 3892, 68632, 0, 6712, 917959, 0, 0, 0, 0, 123158, 69954, 0, 497, - 12100, 5953, 92667, 7796, 0, 43254, 0, 0, 11072, 5952, 1281, 43747, 0, - 69380, 10677, 0, 0, 0, 1859, 0, 72856, 3425, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 65199, 1738, 0, 122911, 0, 0, 0, 11101, 0, 0, 0, 0, 127002, 69651, - 4436, 194683, 73984, 6860, 70305, 64872, 128296, 0, 0, 0, 121377, 0, - 6862, 0, 6861, 983108, 0, 119109, 0, 70826, 319, 0, 43479, 73001, 0, 0, - 12849, 0, 7640, 71083, 9673, 0, 0, 0, 92670, 0, 92665, 113717, 41422, 0, - 100708, 74941, 3772, 0, 120660, 5011, 0, 0, 126587, 111315, 0, 0, 6677, - 111312, 0, 41427, 64419, 129445, 92262, 0, 70799, 0, 0, 0, 6106, 0, - 41271, 6760, 983758, 4534, 41270, 128876, 0, 0, 119561, 0, 0, 3671, 8976, - 123177, 0, 41275, 0, 128084, 55261, 0, 42013, 0, 568, 0, 41273, 0, 0, - 6728, 0, 9715, 0, 0, 121058, 74820, 0, 92268, 0, 194564, 11191, 43688, - 128023, 0, 0, 0, 126266, 0, 0, 0, 11958, 11165, 0, 125087, 0, 0, 66336, - 127944, 0, 0, 0, 0, 42858, 11789, 72878, 5557, 0, 69444, 7300, 0, 9467, - 5558, 64486, 43844, 0, 0, 6706, 10146, 0, 127185, 64566, 0, 0, 0, 0, 0, - 0, 0, 4546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64528, 123136, 6307, 128966, 0, - 7544, 0, 43469, 111317, 0, 10152, 0, 65091, 0, 0, 0, 0, 66652, 0, 0, 0, - 0, 64823, 5559, 0, 70711, 6702, 5556, 0, 0, 0, 0, 0, 11166, 0, 0, 5506, - 0, 1911, 73021, 0, 12598, 8845, 66698, 0, 73012, 123145, 0, 2098, 0, 0, - 0, 66622, 194678, 0, 0, 0, 9898, 0, 0, 7552, 0, 0, 0, 7223, 65723, 0, 0, - 0, 7024, 65728, 127155, 1210, 0, 65175, 10184, 65726, 43654, 0, 0, 0, 38, - 65729, 66669, 0, 917948, 0, 0, 0, 0, 0, 0, 74233, 73018, 119843, 42860, - 111301, 92576, 65721, 65722, 0, 0, 0, 0, 68843, 0, 68850, 0, 92388, - 92267, 128536, 65577, 42967, 0, 127518, 11650, 5013, 92663, 68810, 92568, - 118914, 6613, 74371, 0, 0, 0, 0, 64714, 71479, 0, 983797, 12120, 0, 0, - 43124, 0, 0, 78037, 69263, 0, 126219, 0, 0, 1837, 125086, 0, 0, 0, - 127210, 4952, 65718, 64405, 5504, 65720, 65714, 65715, 65716, 10403, - 127005, 0, 41449, 0, 74028, 72019, 0, 119234, 1127, 455, 0, 0, 72860, - 3483, 0, 1989, 0, 69678, 9104, 0, 65375, 0, 0, 0, 1864, 0, 72810, 8107, - 2540, 0, 0, 11257, 128807, 119576, 0, 120999, 0, 0, 8604, 0, 0, 0, 0, - 128270, 0, 0, 3115, 0, 10106, 120498, 118842, 101136, 0, 9631, 0, 0, 0, - 0, 0, 0, 0, 258, 129079, 0, 0, 0, 92292, 0, 70699, 0, 11478, 0, 129640, - 11522, 0, 8549, 0, 128430, 0, 0, 0, 0, 0, 0, 123140, 0, 0, 0, 9221, - 12590, 73048, 0, 0, 0, 67741, 111294, 12619, 0, 10154, 111266, 74439, - 2039, 0, 7446, 0, 111276, 10974, 458, 72831, 0, 0, 0, 11916, 0, 0, 69671, - 0, 121057, 12288, 0, 111288, 0, 111289, 983176, 0, 128199, 13080, 0, - 67828, 6610, 6030, 8059, 7508, 123170, 0, 0, 0, 0, 41278, 129393, 118691, - 128192, 41277, 64658, 984002, 101278, 6625, 983159, 19904, 0, 0, 0, 0, 0, - 0, 833, 0, 6369, 0, 0, 42664, 0, 0, 0, 0, 129765, 0, 6913, 933, 1341, - 68828, 6720, 0, 0, 983604, 0, 0, 7405, 128025, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 128037, 0, 0, 0, 0, 0, 0, 0, 127188, 92977, + 69708, 9638, 0, 100878, 0, 0, 0, 74545, 128820, 128819, 75062, 128963, 0, + 0, 0, 11264, 43994, 0, 0, 0, 1311, 0, 0, 0, 0, 13068, 0, 0, 78164, 78155, + 0, 949, 0, 0, 0, 78176, 69709, 78177, 63828, 0, 0, 118629, 70282, 0, 0, + 0, 64822, 0, 6530, 983275, 0, 70493, 0, 129325, 0, 0, 4431, 118839, + 127490, 983760, 73667, 127986, 0, 10336, 10400, 0, 0, 92959, 0, 0, 0, + 42270, 128880, 6428, 0, 0, 0, 0, 43455, 0, 43526, 100888, 12835, 129501, + 9493, 0, 0, 11793, 0, 127897, 74394, 0, 10653, 0, 0, 0, 0, 6560, 7016, + 74274, 983627, 43556, 3929, 123615, 6614, 2768, 0, 65609, 0, 11811, + 129696, 0, 118615, 127513, 0, 6554, 0, 6305, 66283, 4675, 118826, 78552, + 0, 0, 74361, 0, 0, 68108, 0, 0, 92232, 0, 93022, 7392, 8230, 9365, + 983742, 0, 0, 0, 0, 42925, 0, 0, 122965, 0, 229, 43834, 119884, 0, 43552, + 119881, 119880, 119883, 119882, 119877, 119876, 119879, 119878, 119873, + 119872, 119875, 119874, 0, 0, 0, 0, 0, 66352, 0, 0, 0, 128663, 0, 12239, + 0, 0, 10432, 12097, 0, 194815, 1233, 78179, 0, 127200, 0, 66395, 0, 0, + 129504, 0, 0, 92342, 0, 2388, 92555, 119868, 119871, 119870, 119865, 895, + 92668, 119866, 64889, 7143, 119863, 119862, 0, 0, 69983, 0, 74376, 3053, + 2168, 0, 2047, 0, 0, 0, 121279, 67985, 194801, 92600, 194803, 194802, + 194805, 194804, 194807, 194806, 129134, 194808, 0, 0, 0, 10473, 129331, + 0, 194810, 129806, 194812, 129813, 194814, 194813, 123195, 43528, 69673, + 194791, 0, 194793, 1912, 120779, 10306, 10370, 0, 0, 8867, 10250, 10258, + 10274, 1635, 120152, 0, 0, 0, 129379, 0, 0, 9919, 120148, 559, 128157, + 41825, 127975, 92989, 0, 74016, 194781, 6542, 41957, 7318, 124126, 0, + 41956, 65749, 65750, 65751, 121323, 64487, 0, 0, 10223, 42062, 100640, + 101195, 125044, 3668, 65754, 43560, 12226, 0, 93973, 194784, 41959, + 194786, 194785, 194788, 43618, 65747, 10937, 2962, 0, 2953, 10062, 65745, + 71457, 8921, 66013, 129370, 0, 194769, 194768, 43409, 194770, 2949, + 194772, 194775, 194774, 2958, 194776, 74868, 2300, 2951, 120061, 0, + 120043, 194778, 0, 120051, 194779, 120056, 120065, 70798, 120048, 0, + 120062, 120055, 71989, 100668, 0, 0, 71985, 0, 71992, 70796, 127818, 0, + 0, 64890, 0, 43630, 11336, 799, 0, 10276, 10308, 10372, 917541, 0, 0, + 10252, 10260, 68220, 55284, 125225, 0, 10384, 0, 0, 0, 64523, 129744, 0, + 65736, 0, 0, 0, 0, 0, 0, 0, 124912, 43549, 65738, 42150, 65739, 0, 78195, + 10288, 10320, 0, 10596, 129829, 67673, 65045, 121283, 78198, 2049, 10098, + 0, 122904, 127943, 10264, 10280, 10312, 10376, 7013, 0, 69504, 0, 0, + 66375, 0, 4862, 0, 6537, 0, 128335, 3914, 92178, 93976, 9065, 64816, 0, + 72218, 73026, 0, 0, 72139, 4694, 11420, 4690, 0, 0, 983211, 4693, 0, 0, + 0, 4688, 0, 0, 128892, 0, 8238, 3110, 0, 983939, 0, 6528, 0, 0, 0, 218, + 0, 1520, 129577, 70039, 0, 983594, 0, 120167, 78167, 10088, 6548, 100786, + 0, 0, 0, 8888, 0, 124954, 0, 0, 126593, 68876, 0, 0, 0, 0, 0, 0, 0, 4689, + 43541, 77954, 120157, 0, 120156, 78810, 120163, 0, 0, 0, 0, 78121, 0, 0, + 11450, 0, 71900, 92613, 0, 121317, 74622, 128720, 9244, 0, 0, 127763, 0, + 0, 0, 0, 0, 0, 71084, 0, 0, 0, 0, 10513, 0, 0, 0, 52, 119178, 0, 0, + 93961, 0, 0, 4812, 0, 0, 0, 0, 0, 0, 128425, 0, 6850, 0, 77959, 10170, + 120450, 6544, 0, 0, 69782, 121517, 0, 0, 65258, 10369, 0, 1585, 74014, + 10249, 422, 1500, 2036, 986, 0, 64394, 69502, 5599, 917981, 2494, 0, 0, + 74021, 983896, 78203, 127808, 0, 72871, 65102, 8961, 74305, 10243, 10245, + 128170, 0, 0, 0, 0, 0, 2508, 129591, 120440, 0, 120439, 0, 0, 0, 0, 0, 0, + 64533, 983187, 0, 0, 74008, 0, 0, 43375, 0, 2504, 0, 121313, 0, 983941, + 6943, 0, 5859, 100677, 0, 0, 72873, 983945, 0, 0, 983923, 92390, 2753, + 1936, 2153, 67701, 2751, 12662, 2763, 8953, 0, 10731, 0, 7052, 0, 0, 0, + 0, 119899, 0, 66675, 0, 119897, 0, 71053, 0, 119903, 0, 67829, 7899, + 119901, 71119, 43798, 7072, 119902, 122898, 11260, 0, 71059, 0, 0, 212, + 0, 12350, 0, 0, 0, 0, 0, 128402, 2759, 0, 0, 93064, 0, 0, 0, 1291, 0, + 195065, 121318, 119911, 0, 119910, 0, 12062, 0, 121216, 0, 129124, + 121044, 120611, 8246, 128874, 0, 0, 0, 0, 0, 73962, 0, 0, 43524, 0, + 64426, 0, 0, 0, 0, 65664, 6693, 0, 0, 8674, 0, 128812, 0, 11846, 70690, + 121461, 69395, 4811, 0, 5986, 0, 3046, 74480, 5985, 0, 0, 0, 0, 12187, + 83148, 71041, 5984, 0, 93817, 4393, 126264, 120206, 917599, 0, 0, 0, + 93806, 93805, 0, 3491, 0, 67146, 0, 93819, 0, 72428, 0, 0, 0, 124968, + 41284, 126228, 0, 0, 41287, 0, 100689, 0, 0, 92189, 0, 0, 219, 120874, 0, + 0, 0, 68485, 119672, 43241, 0, 7147, 73554, 0, 0, 0, 0, 0, 64610, 11804, + 0, 7149, 64808, 0, 0, 0, 92301, 73690, 0, 5253, 0, 0, 0, 0, 129045, + 983596, 11098, 68433, 0, 120484, 111009, 0, 0, 0, 0, 0, 70801, 100779, 0, + 128198, 9604, 0, 130036, 0, 0, 118941, 64392, 0, 118684, 0, 0, 41974, + 126262, 0, 0, 0, 129818, 0, 129833, 0, 0, 0, 0, 0, 983243, 5308, 0, 290, + 0, 125278, 128382, 2792, 0, 0, 120521, 0, 126237, 0, 126099, 0, 0, 0, 0, + 128503, 0, 0, 72816, 0, 0, 0, 92671, 0, 195061, 42646, 7606, 2591, 73896, + 0, 43513, 64482, 0, 0, 65270, 0, 0, 983701, 9112, 0, 113763, 9490, 0, 0, + 0, 0, 0, 9071, 0, 0, 0, 0, 74607, 0, 2535, 65504, 43602, 0, 0, 71256, + 2248, 0, 123147, 11845, 11006, 92315, 7807, 8073, 0, 10629, 0, 74088, 0, + 10823, 0, 113762, 8762, 0, 69689, 123536, 43969, 65047, 10737, 3463, + 67467, 129585, 66645, 0, 4815, 0, 0, 12345, 983761, 0, 5195, 129808, 0, + 66639, 0, 0, 66941, 0, 92759, 92385, 1262, 0, 6561, 19939, 0, 0, 100772, + 123160, 69269, 0, 100774, 0, 0, 0, 0, 0, 0, 67511, 0, 0, 0, 0, 0, 0, + 5702, 3655, 0, 8430, 0, 68807, 0, 0, 121137, 0, 0, 5254, 0, 0, 124917, 0, + 119107, 5129, 0, 70816, 0, 92280, 5614, 0, 0, 11720, 0, 11721, 70804, + 4798, 0, 120541, 66038, 4793, 67851, 7352, 0, 0, 0, 0, 917600, 0, 300, 0, + 0, 128575, 92660, 0, 0, 2562, 70156, 120856, 0, 0, 92738, 0, 0, 127820, + 71093, 0, 127969, 128221, 0, 3424, 93843, 0, 0, 7074, 70873, 128519, 0, + 0, 10832, 0, 0, 69852, 72430, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 1215, 0, + 5744, 0, 66440, 0, 0, 0, 42881, 0, 8980, 118988, 67861, 8844, 7433, 0, 0, + 4278, 124925, 0, 0, 70821, 9312, 4348, 0, 128401, 65946, 0, 7087, 5255, + 0, 661, 0, 0, 0, 0, 0, 0, 0, 121009, 73694, 0, 123154, 0, 73688, 0, + 127179, 3621, 83325, 66666, 72968, 0, 6562, 12928, 0, 73991, 0, 0, 11383, + 0, 0, 65588, 120739, 0, 0, 0, 0, 0, 0, 0, 0, 11436, 2070, 64, 110824, 0, + 10291, 10323, 10387, 0, 0, 0, 42008, 9708, 42710, 0, 42011, 0, 92164, 0, + 0, 1702, 1240, 128383, 6286, 9689, 111080, 0, 0, 0, 1765, 0, 0, 92373, 0, + 0, 0, 8401, 72991, 42014, 0, 67237, 0, 0, 0, 0, 0, 0, 0, 70819, 0, 0, 0, + 0, 12667, 0, 0, 10147, 0, 127568, 126483, 72812, 0, 0, 0, 0, 123139, + 128968, 0, 64947, 0, 0, 0, 0, 10435, 11462, 0, 7084, 0, 0, 0, 0, 0, + 126084, 0, 66662, 0, 0, 0, 0, 125134, 0, 0, 77990, 263, 983747, 41288, + 127953, 0, 78387, 74340, 70313, 129140, 0, 0, 0, 42022, 71265, 0, 0, 0, + 0, 0, 0, 42020, 123146, 0, 6992, 42019, 0, 41290, 0, 12295, 126233, + 71304, 0, 120984, 71300, 120631, 5954, 64931, 69385, 100699, 198, 68453, + 78129, 0, 121351, 0, 70818, 13165, 7107, 0, 42804, 678, 72850, 118960, 0, + 72985, 42806, 42808, 0, 0, 2097, 0, 120560, 70823, 0, 0, 3892, 68632, 0, + 6712, 917959, 0, 0, 0, 0, 123158, 69954, 0, 497, 12100, 5953, 92667, + 7796, 0, 43254, 0, 0, 11072, 5952, 1281, 43747, 0, 69380, 10677, 0, 0, 0, + 1859, 0, 72856, 3425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65199, 1738, 0, + 122911, 0, 0, 0, 11101, 0, 0, 0, 0, 127002, 69651, 4436, 194683, 73984, + 6860, 70305, 64872, 128296, 0, 0, 0, 121377, 0, 6862, 0, 6861, 983109, 0, + 119109, 0, 70826, 319, 0, 43479, 73001, 0, 0, 12849, 0, 7640, 71083, + 9673, 0, 0, 0, 92670, 0, 92665, 113717, 41422, 0, 100708, 74941, 3772, 0, + 120660, 5011, 0, 0, 126587, 111315, 0, 0, 6677, 111312, 0, 41427, 64419, + 129445, 92262, 0, 70799, 0, 0, 0, 6106, 0, 41271, 6760, 983758, 4534, + 41270, 128876, 0, 0, 119561, 0, 0, 3671, 8976, 123177, 0, 41275, 0, + 128084, 55261, 0, 42013, 0, 568, 0, 41273, 0, 0, 6728, 0, 9715, 0, 0, + 121058, 74820, 0, 92268, 0, 194564, 11191, 43688, 128023, 0, 0, 0, + 126266, 0, 0, 0, 11958, 11165, 0, 125087, 0, 0, 66336, 127944, 0, 0, 0, + 0, 42858, 11789, 72878, 5557, 0, 69444, 7300, 0, 9467, 5558, 64486, + 43844, 0, 0, 6706, 10146, 0, 127185, 64566, 0, 0, 0, 0, 0, 0, 0, 4546, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 64528, 123136, 6307, 128966, 0, 7544, 0, 43469, + 111317, 0, 10152, 0, 65091, 0, 129047, 0, 0, 66652, 0, 0, 0, 0, 64823, + 5559, 0, 70711, 6702, 5556, 0, 0, 0, 0, 0, 11166, 0, 0, 5506, 0, 1911, + 73021, 0, 12598, 8845, 66698, 0, 73012, 123145, 73496, 2098, 0, 0, 0, + 66622, 194678, 0, 0, 0, 9898, 0, 0, 7552, 0, 0, 0, 7223, 65723, 0, 0, 0, + 7024, 65728, 127155, 1210, 0, 65175, 10184, 65726, 43654, 0, 0, 0, 38, + 65729, 66669, 0, 917948, 0, 0, 0, 0, 119837, 0, 74233, 73018, 119843, + 42860, 111301, 92576, 65721, 65722, 0, 0, 0, 0, 68843, 0, 68850, 0, + 92388, 92267, 128536, 65577, 42967, 0, 127518, 11650, 5013, 92663, 68810, + 92568, 118914, 6613, 74371, 0, 0, 122985, 0, 64714, 71479, 0, 983797, + 12120, 0, 0, 43124, 0, 0, 78037, 69263, 0, 126219, 0, 0, 1837, 125086, 0, + 0, 0, 127210, 4952, 65718, 64405, 5504, 65720, 65714, 65715, 65716, + 10403, 127005, 0, 41449, 0, 74028, 72019, 0, 119234, 1127, 455, 0, 0, + 72860, 3483, 0, 1989, 0, 69678, 9104, 0, 65375, 0, 0, 0, 1864, 0, 72810, + 8107, 2540, 0, 0, 11257, 128807, 119576, 0, 120999, 0, 73501, 8604, 0, 0, + 0, 0, 128270, 0, 0, 3115, 0, 10106, 120498, 118842, 101136, 0, 9631, 0, + 0, 0, 0, 0, 0, 0, 258, 129079, 0, 0, 0, 92292, 0, 70699, 0, 11478, 0, + 129640, 11522, 0, 8549, 0, 128430, 0, 0, 0, 0, 0, 0, 123140, 0, 0, 0, + 9221, 12590, 73048, 0, 0, 0, 67741, 111294, 12619, 0, 10154, 111266, + 74439, 2039, 0, 7446, 0, 111276, 10974, 458, 72831, 0, 0, 0, 11916, 0, 0, + 69671, 0, 121057, 12288, 0, 111288, 0, 111289, 983177, 0, 128199, 13080, + 0, 67828, 6610, 6030, 8059, 7508, 123170, 0, 0, 0, 0, 41278, 129393, + 118691, 128192, 41277, 64658, 984002, 101278, 6625, 983160, 19904, 0, 0, + 0, 0, 0, 0, 833, 0, 6369, 0, 0, 42664, 0, 0, 0, 0, 129765, 0, 6913, 933, + 1341, 68828, 6720, 0, 0, 983604, 0, 0, 7405, 128025, 0, 0, 0, 0, 0, 0, 0, 70704, 0, 0, 0, 0, 9716, 0, 0, 0, 70719, 0, 0, 0, 0, 72862, 70687, 0, 93987, 0, 0, 0, 70721, 9573, 0, 0, 111245, 83225, 83226, 6949, 126482, 74061, 83222, 83223, 83224, 0, 19962, 83219, 83220, 0, 111233, 0, 42830, 0, 111234, 74236, 66276, 0, 546, 72861, 0, 70661, 0, 472, 11083, 10319, 10383, 917971, 0, 83202, 83203, 3602, 83206, 41182, 83199, 83200, 69796, - 41183, 0, 10271, 10287, 684, 0, 0, 0, 83214, 4592, 83216, 83217, 83210, + 3790, 0, 10271, 10287, 684, 0, 0, 0, 83214, 4592, 83216, 83217, 83210, 11963, 43620, 83213, 0, 0, 83208, 83209, 0, 92623, 128559, 3415, 0, 121267, 0, 0, 123151, 43447, 0, 92212, 0, 418, 0, 0, 10295, 10327, 10391, 0, 83189, 83190, 83192, 83194, 83185, 83186, 83187, 83188, 120879, 0, - 41446, 70700, 118652, 0, 120809, 10599, 66892, 0, 0, 0, 0, 0, 0, 11437, - 0, 0, 0, 0, 0, 0, 12624, 0, 41185, 72865, 69439, 8159, 0, 11686, 71478, - 65224, 0, 4655, 0, 0, 92183, 0, 10343, 10407, 0, 0, 0, 111221, 0, 0, 0, - 94057, 68201, 129574, 0, 983572, 72156, 42792, 5743, 10424, 0, 0, 0, 0, - 0, 8875, 111225, 0, 917991, 13117, 12847, 4651, 118917, 0, 962, 0, 0, - 2242, 42564, 0, 1582, 0, 5508, 0, 0, 0, 10801, 123602, 118798, 73705, 0, - 66911, 10439, 66891, 0, 0, 7860, 0, 906, 917985, 0, 6405, 64722, 0, + 41446, 70700, 118652, 0, 120809, 10599, 66892, 0, 0, 0, 0, 0, 129184, + 11437, 0, 0, 0, 0, 0, 0, 12624, 0, 41185, 72865, 69439, 8159, 0, 11686, + 71478, 65224, 0, 4655, 0, 0, 92183, 0, 10343, 10407, 0, 0, 0, 111221, 0, + 0, 0, 94057, 68201, 129574, 0, 983572, 72156, 42792, 5743, 10424, 0, 0, + 0, 0, 0, 8875, 111225, 0, 917991, 13117, 12847, 4651, 118917, 0, 962, 0, + 0, 2242, 42564, 0, 1582, 0, 5508, 0, 0, 0, 10801, 123602, 118798, 73705, + 0, 66911, 10439, 66891, 0, 0, 7860, 0, 906, 917985, 0, 6405, 64722, 0, 83266, 64694, 83268, 917990, 1153, 83263, 64788, 83265, 0, 12626, 83260, 83261, 9964, 0, 0, 4642, 66574, 127886, 0, 0, 0, 0, 0, 9008, 100847, 0, 0, 0, 83248, 917976, 917993, 123173, 42842, 83244, 83245, 83247, 83239, @@ -28267,344 +28459,345 @@ static const unsigned int code_hash[] = { 41967, 83258, 83251, 83252, 83253, 8920, 0, 0, 83249, 83250, 0, 0, 43919, 0, 0, 0, 0, 128021, 0, 68113, 65196, 0, 0, 128472, 0, 10111, 64875, 0, 83491, 43998, 83232, 83233, 83234, 70691, 83228, 42149, 83230, 68508, 0, - 0, 0, 0, 0, 0, 0, 4110, 66005, 74034, 0, 0, 0, 66703, 0, 0, 983157, 6025, - 69242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70733, 0, 983043, 0, 0, 0, 68817, 0, 0, - 0, 0, 0, 0, 43286, 0, 68765, 0, 0, 0, 0, 129871, 65144, 0, 0, 83236, - 65840, 0, 0, 10081, 0, 0, 983912, 0, 0, 0, 127394, 65882, 0, 128758, 0, - 0, 3605, 10985, 0, 0, 128872, 93972, 1745, 0, 73835, 0, 0, 0, 0, 0, 0, - 8806, 7023, 0, 0, 0, 70702, 70304, 0, 0, 0, 0, 0, 0, 0, 0, 348, 10089, 0, - 9017, 0, 0, 0, 0, 0, 0, 0, 67465, 0, 42515, 0, 0, 0, 0, 5391, 983237, - 110576, 0, 0, 5561, 0, 9429, 0, 67150, 7933, 5562, 0, 0, 0, 0, 78039, 0, - 0, 0, 0, 3979, 71248, 0, 0, 0, 68847, 0, 0, 118847, 65847, 68836, 68838, - 0, 10585, 0, 92676, 7334, 0, 0, 0, 831, 0, 0, 10716, 0, 121325, 0, 12218, - 0, 6939, 70697, 65042, 0, 0, 916, 0, 0, 11968, 0, 122641, 5563, 0, 0, - 128830, 5560, 41212, 41774, 0, 4497, 0, 0, 0, 9039, 70678, 41776, 0, - 8716, 3567, 119252, 0, 0, 74260, 0, 93954, 0, 0, 100827, 0, 128879, - 70072, 68355, 68357, 0, 0, 8634, 0, 0, 4209, 120702, 68832, 65879, 68825, - 68819, 68822, 0, 5679, 68813, 68815, 68811, 68812, 64697, 5678, 11821, - 68802, 93969, 0, 0, 0, 0, 70114, 0, 0, 0, 0, 0, 0, 0, 0, 7782, 0, 0, 0, - 0, 129977, 65711, 65712, 1216, 0, 69409, 5792, 0, 0, 0, 0, 0, 12244, 0, - 5683, 0, 120895, 121336, 43448, 70670, 0, 0, 5682, 10242, 75043, 74520, - 5680, 917568, 10001, 0, 0, 1449, 10241, 0, 70708, 0, 0, 83180, 83182, - 83183, 8584, 83176, 5567, 83178, 83179, 0, 5564, 42886, 42884, 42882, - 5565, 119022, 120881, 0, 65708, 65709, 5566, 0, 65704, 65705, 11904, - 42875, 0, 42873, 5942, 0, 0, 10361, 10425, 65697, 65698, 65699, 0, 66598, - 0, 64664, 10647, 78702, 78703, 78690, 78700, 0, 65701, 1934, 0, 0, 0, - 78710, 0, 78706, 78709, 6087, 78705, 78716, 78719, 78711, 8043, 8950, - 65694, 64485, 0, 10457, 0, 78724, 78725, 78722, 72332, 78720, 78721, 0, - 65515, 0, 10035, 13069, 0, 0, 127773, 0, 0, 0, 125207, 0, 0, 1667, 0, 0, - 42428, 110950, 0, 0, 41750, 0, 0, 93999, 0, 8101, 3610, 113670, 41748, - 110948, 0, 78394, 119208, 0, 0, 113691, 64549, 68359, 0, 0, 65692, 92701, - 0, 917960, 12896, 10456, 68298, 0, 0, 0, 0, 917962, 0, 0, 113665, 70502, - 0, 65687, 0, 0, 74009, 0, 113673, 8536, 70671, 0, 78726, 0, 724, 0, - 113675, 78749, 9975, 78746, 78747, 78744, 4175, 78741, 78743, 78751, 939, - 0, 128799, 983119, 0, 0, 0, 78763, 78764, 78760, 78761, 78758, 78759, - 78755, 8425, 0, 0, 0, 8188, 0, 0, 0, 0, 0, 6370, 0, 7827, 68441, 75008, - 0, 917943, 0, 118863, 0, 0, 0, 0, 121243, 73988, 0, 113668, 0, 11012, 0, - 43764, 178, 12972, 74620, 113671, 0, 113735, 0, 66764, 0, 0, 65690, - 72339, 0, 0, 917950, 9252, 0, 4652, 74259, 0, 917947, 0, 0, 0, 10806, 0, - 0, 70016, 0, 6723, 0, 0, 6993, 0, 0, 12855, 0, 0, 11390, 0, 0, 0, 92503, - 0, 0, 983161, 125270, 92627, 8278, 0, 4034, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 12750, 9350, 66037, 0, 0, 73700, 12747, 0, 0, 128064, 8922, 74640, 0, 0, - 43150, 0, 983090, 983088, 66779, 66777, 10813, 2592, 43139, 0, 0, 118612, - 0, 0, 71891, 0, 0, 0, 0, 0, 0, 71697, 0, 128825, 1596, 0, 0, 0, 0, 6838, - 66572, 0, 126574, 120627, 8092, 12805, 41928, 0, 78406, 78409, 0, 0, 0, - 9931, 0, 0, 0, 0, 0, 983778, 6107, 0, 0, 0, 0, 128745, 0, 335, 127003, - 64689, 0, 0, 5765, 0, 0, 119227, 6092, 118851, 0, 8876, 83465, 74947, - 83455, 129186, 83454, 70713, 0, 0, 126606, 70121, 41602, 0, 92308, 74831, - 0, 11783, 68482, 0, 0, 0, 0, 0, 0, 843, 0, 71099, 0, 0, 41935, 0, 0, 0, - 0, 1371, 0, 43818, 43159, 8069, 9579, 41938, 41608, 0, 92444, 6242, 0, 0, - 128595, 128244, 0, 92499, 8805, 1742, 113722, 0, 8202, 72399, 0, 983197, - 0, 0, 73882, 100809, 0, 43467, 123636, 55290, 0, 1712, 5932, 0, 41762, - 71982, 0, 11967, 1775, 0, 75009, 0, 11868, 120387, 9458, 0, 126614, 0, 0, - 43176, 101032, 101031, 42782, 101033, 101036, 101035, 101038, 101037, - 101040, 101039, 0, 0, 0, 0, 101041, 5794, 92274, 2662, 101045, 101044, - 8254, 101046, 10975, 101048, 120625, 101050, 917977, 4108, 8478, 917982, - 194790, 0, 92263, 917980, 7507, 0, 43149, 0, 65031, 7961, 1636, 0, 65029, - 0, 129665, 70188, 9674, 0, 99, 98, 97, 101022, 92203, 4049, 101027, - 43880, 7090, 101028, 0, 101030, 66589, 0, 65310, 66593, 66599, 129805, 0, - 0, 7447, 66594, 0, 0, 0, 73920, 66595, 66596, 42570, 5593, 0, 0, 0, 0, - 6061, 64854, 119, 118, 117, 116, 0, 122, 121, 120, 111, 110, 109, 108, - 115, 114, 113, 112, 103, 102, 101, 100, 107, 106, 105, 104, 128504, - 73974, 534, 0, 67713, 1536, 73973, 73970, 0, 0, 0, 6020, 12716, 0, 12744, - 65143, 0, 13266, 127813, 0, 0, 0, 127116, 0, 1212, 65560, 0, 8134, 42935, - 12129, 73870, 0, 1866, 0, 0, 0, 0, 65073, 12059, 66585, 121391, 0, 0, 0, - 5935, 1250, 0, 8174, 9787, 6733, 9859, 9858, 9861, 9860, 101012, 1882, - 1892, 6731, 10882, 10795, 101018, 73911, 101020, 101019, 41169, 8939, 0, - 120713, 41170, 1454, 0, 65130, 69732, 0, 0, 129611, 41172, 7855, 0, - 71472, 0, 0, 0, 71691, 65901, 0, 0, 645, 100992, 100991, 100994, 100993, - 100996, 100995, 100998, 65587, 0, 10688, 0, 0, 7729, 0, 101001, 120518, - 101003, 66722, 101005, 101004, 68415, 101006, 4538, 101008, 43141, 0, 0, - 73699, 0, 0, 0, 71918, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71454, 0, 2381, 983752, - 0, 0, 69857, 100981, 0, 100983, 100982, 100985, 10856, 100987, 55255, - 41478, 8582, 10064, 0, 0, 0, 0, 64896, 0, 74609, 0, 128048, 10082, 11575, - 0, 0, 0, 917505, 0, 6145, 75020, 0, 92433, 71916, 83279, 43186, 0, 0, - 83274, 83276, 83277, 83278, 10191, 83271, 69633, 72353, 0, 0, 0, 0, - 120090, 120089, 7931, 8558, 917946, 0, 0, 0, 119145, 120081, 120084, - 120083, 120086, 71449, 120088, 7366, 7019, 75021, 0, 917951, 120078, - 120077, 120080, 8657, 100967, 8594, 100969, 100968, 0, 100970, 120072, - 120071, 0, 0, 43154, 0, 0, 11332, 0, 7728, 100978, 100977, 100980, - 100979, 7851, 0, 8375, 128662, 0, 0, 126095, 9085, 0, 0, 9327, 6160, 0, - 0, 0, 0, 70698, 74012, 0, 0, 4439, 121151, 100972, 100971, 100974, - 100973, 100976, 100975, 100956, 42524, 71220, 100957, 10826, 100959, - 11296, 0, 0, 0, 7504, 43161, 127868, 0, 64670, 0, 78056, 0, 11295, 0, - 78053, 0, 0, 0, 10902, 0, 0, 122650, 78068, 10472, 100954, 100953, - 120215, 78062, 2371, 78069, 118893, 259, 0, 0, 2402, 12157, 6440, 0, - 100963, 100962, 100965, 100964, 65380, 9103, 2278, 0, 0, 7301, 0, 10219, - 0, 0, 0, 67718, 43178, 0, 120214, 119362, 917974, 8613, 0, 126121, - 917978, 917979, 121449, 12005, 7353, 0, 1890, 129130, 0, 0, 0, 42815, - 7991, 0, 10578, 0, 0, 0, 0, 0, 0, 0, 111190, 120601, 42668, 9348, 0, - 6164, 0, 0, 0, 7676, 0, 0, 0, 0, 0, 129422, 83443, 71096, 83444, 9175, 0, - 78047, 9088, 73689, 0, 1396, 0, 0, 11461, 71088, 127835, 92252, 0, 71090, - 121185, 69872, 0, 0, 0, 0, 74043, 119632, 0, 0, 0, 5928, 4525, 10658, 0, - 1266, 10180, 64472, 0, 12622, 0, 0, 0, 0, 127139, 13310, 773, 19933, 0, - 0, 0, 0, 92205, 0, 0, 0, 0, 5862, 7823, 0, 0, 0, 3250, 43991, 69687, - 66649, 0, 0, 0, 0, 0, 64673, 917963, 917964, 0, 0, 917967, 917968, - 917965, 917966, 127791, 75041, 3471, 917970, 64573, 882, 0, 119584, 0, - 120772, 0, 0, 0, 92696, 0, 0, 72988, 0, 3225, 0, 73729, 0, 0, 43173, - 11752, 4381, 0, 0, 917945, 11756, 11757, 917944, 917949, 42654, 127848, - 118663, 0, 0, 5160, 1387, 0, 917953, 0, 128933, 917956, 917957, 917954, - 917955, 118595, 121082, 917958, 10789, 68314, 0, 126521, 11143, 0, 0, - 70669, 128904, 42179, 0, 5931, 11744, 11215, 70676, 119245, 0, 0, 0, - 77915, 10217, 64635, 128661, 83292, 0, 0, 0, 0, 0, 41296, 11747, 41291, - 0, 0, 0, 41294, 41282, 5923, 120610, 0, 0, 0, 0, 66800, 5786, 68252, - 42539, 119869, 119860, 0, 41474, 0, 0, 0, 5934, 74572, 66583, 119231, 0, - 94072, 64481, 0, 0, 0, 0, 67240, 0, 0, 123201, 0, 5819, 0, 0, 0, 0, 0, - 129387, 0, 0, 0, 67993, 1237, 194749, 0, 0, 983557, 0, 0, 0, 0, 0, 0, 0, - 69789, 11266, 69845, 0, 10506, 194747, 0, 0, 0, 0, 43185, 194748, 100533, - 100532, 100535, 10769, 100537, 100536, 100539, 9753, 121035, 100540, 0, - 0, 121433, 0, 100542, 6072, 100544, 100543, 100546, 100545, 100548, - 100547, 100550, 100549, 0, 113744, 0, 0, 7222, 10283, 10315, 10379, 4996, - 0, 129294, 66517, 0, 10087, 127833, 74938, 0, 0, 83492, 7565, 42890, 0, - 77931, 43180, 77928, 74891, 77929, 43982, 100526, 622, 77926, 100527, - 100530, 1602, 0, 0, 0, 129559, 12160, 0, 10212, 77936, 194605, 12071, - 43143, 77935, 917983, 917984, 917989, 77932, 917987, 917988, 10255, - 10263, 10279, 4194, 10375, 93035, 0, 0, 12644, 127516, 917994, 75007, - 110791, 67408, 110789, 11501, 41177, 0, 0, 71912, 0, 0, 8715, 0, 41179, - 0, 0, 0, 41176, 0, 41181, 0, 8452, 121006, 13161, 0, 70503, 5921, 0, - 2597, 0, 5922, 72128, 0, 74242, 128374, 0, 0, 0, 0, 0, 0, 0, 127906, 0, - 64944, 0, 0, 0, 0, 5924, 5920, 129508, 6921, 78081, 74007, 78078, 8418, - 11681, 43169, 10176, 0, 0, 0, 78087, 10772, 65276, 5937, 1914, 78084, - 11682, 0, 0, 0, 11685, 0, 100513, 7772, 11680, 100514, 100517, 100516, - 100519, 7417, 718, 100520, 70083, 100500, 120718, 3235, 0, 43164, 0, - 8018, 0, 0, 128708, 6937, 67672, 128508, 0, 10067, 120849, 0, 0, 0, - 118693, 0, 100491, 0, 100493, 100492, 13116, 100494, 100497, 9945, - 100499, 100498, 0, 0, 0, 0, 2059, 0, 100502, 100501, 1431, 100503, 66565, - 100505, 100508, 12804, 100510, 100509, 78090, 3307, 78088, 78089, 0, - 4544, 71228, 0, 0, 0, 78097, 11110, 66810, 12882, 64511, 78094, 78100, - 78102, 71226, 10141, 0, 78280, 65298, 4476, 78109, 94005, 71216, 8907, - 78105, 78106, 78103, 78104, 120898, 0, 10665, 64616, 128944, 0, 127545, - 69605, 83159, 83160, 4554, 0, 83155, 83156, 83157, 83158, 0, 125123, 0, - 72258, 129831, 0, 129815, 0, 43179, 0, 0, 0, 717, 10754, 83168, 83169, - 83162, 83163, 83164, 83165, 78282, 0, 0, 83161, 68848, 10611, 72859, - 126978, 71474, 129426, 127871, 0, 0, 0, 12820, 110882, 0, 7009, 70103, 0, - 0, 67848, 41173, 4574, 0, 0, 128338, 575, 78110, 43456, 8563, 100469, 0, - 0, 65565, 0, 5936, 7290, 78117, 78118, 74919, 308, 78113, 78114, 83151, - 78123, 83153, 83154, 0, 0, 0, 0, 67496, 5926, 68250, 78130, 78126, 78127, - 78124, 78125, 42513, 0, 129026, 0, 11651, 13093, 78135, 0, 100471, 0, - 100473, 100472, 100475, 74048, 100477, 71995, 100457, 100456, 43703, - 13097, 0, 100460, 13283, 0, 0, 125073, 3488, 5933, 10033, 983947, 0, - 65570, 0, 12297, 0, 0, 0, 128517, 42538, 0, 129293, 0, 100451, 0, 100453, - 100452, 100455, 100454, 121221, 0, 0, 7638, 0, 129193, 0, 43109, 7637, 0, - 11213, 100461, 83355, 100463, 100466, 100465, 0, 0, 7636, 0, 0, 0, - 128848, 983087, 291, 0, 0, 2027, 78141, 78142, 78136, 78137, 83481, 4640, - 64713, 10224, 120429, 11183, 83482, 120430, 0, 0, 0, 127148, 83479, 0, 0, - 83488, 0, 0, 0, 0, 68837, 5778, 0, 0, 0, 12680, 119130, 0, 67242, 93041, - 0, 0, 0, 11552, 0, 127855, 0, 70091, 0, 10172, 65453, 120408, 66014, - 120410, 0, 4641, 11556, 64819, 78269, 120416, 72341, 41469, 41467, - 120412, 120415, 4646, 120425, 865, 78275, 78274, 78273, 4645, 78271, - 78270, 0, 983172, 7338, 0, 68840, 0, 12565, 0, 0, 0, 195089, 119655, - 195091, 195090, 2913, 13120, 128956, 69493, 195097, 195096, 128019, 0, - 71462, 0, 7916, 10485, 195098, 0, 195100, 195099, 0, 67705, 128351, - 195077, 195080, 129636, 129549, 195081, 0, 0, 0, 10229, 10687, 826, - 128081, 195082, 195085, 195084, 195087, 195086, 0, 1808, 7848, 0, 0, 0, - 0, 0, 0, 128897, 69255, 42942, 67704, 0, 0, 0, 0, 42940, 0, 9144, 0, 0, - 92992, 9840, 0, 0, 0, 0, 0, 0, 74448, 83475, 0, 10962, 66904, 113718, - 983187, 0, 0, 74537, 195072, 1792, 195074, 195073, 78266, 195075, 0, 0, - 12066, 0, 385, 4152, 0, 0, 0, 67397, 0, 0, 0, 0, 43258, 0, 0, 13157, 0, - 0, 3570, 0, 0, 0, 67252, 0, 71218, 126631, 7879, 68247, 128579, 0, 0, - 70196, 0, 0, 8463, 7810, 917862, 7839, 983878, 127768, 917860, 9691, 0, - 129323, 0, 120385, 0, 917844, 0, 10066, 0, 2175, 0, 0, 0, 8016, 0, - 983072, 64831, 0, 126103, 0, 119171, 1634, 68115, 94192, 11056, 0, 0, 0, - 41165, 11328, 12450, 0, 41166, 0, 12456, 0, 171, 67508, 12452, 917544, - 12458, 12531, 0, 917853, 0, 74162, 0, 0, 9969, 0, 12454, 74160, 42132, - 110755, 78878, 110753, 3230, 73711, 0, 0, 8932, 4399, 5810, 64534, 8415, - 0, 110756, 110757, 74159, 0, 0, 960, 74156, 6981, 92374, 12938, 9201, 0, - 118713, 74904, 0, 72866, 92270, 0, 0, 0, 129792, 5851, 73833, 5824, 0, - 5844, 110848, 110849, 110846, 110847, 4663, 0, 0, 0, 0, 0, 74085, 0, 0, - 0, 0, 0, 92339, 0, 0, 5782, 67495, 0, 0, 43796, 129639, 0, 195083, - 125223, 128004, 0, 43861, 0, 0, 0, 92976, 0, 0, 0, 4659, 0, 129764, 0, 0, - 129386, 0, 11129, 2238, 329, 0, 92707, 121416, 0, 0, 0, 69943, 67692, - 42167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69618, 43671, 0, 64701, 0, 0, 0, - 93055, 1172, 125089, 6786, 43601, 0, 74126, 0, 0, 0, 0, 0, 118695, 0, 0, - 118804, 0, 66741, 5347, 0, 983663, 0, 0, 10588, 0, 0, 0, 0, 5343, 0, 0, - 0, 5341, 0, 0, 74916, 5351, 0, 0, 917884, 0, 92692, 0, 121148, 128916, 0, - 0, 66785, 126256, 6638, 0, 0, 271, 0, 917904, 0, 0, 12653, 67588, 0, 0, - 0, 0, 128838, 11912, 128301, 983665, 0, 11800, 0, 0, 11103, 0, 7340, 0, - 110695, 0, 0, 70170, 0, 2423, 0, 0, 0, 128136, 42705, 0, 0, 0, 11854, 0, - 0, 0, 0, 4916, 0, 380, 10958, 66563, 127790, 78284, 67587, 0, 12918, 0, - 917897, 0, 917898, 917893, 10684, 0, 125063, 92906, 0, 0, 8182, 0, 0, - 129434, 0, 0, 0, 6859, 0, 6630, 100405, 0, 123191, 0, 0, 0, 65876, 5535, - 129892, 0, 0, 92609, 0, 983345, 6477, 43795, 92217, 129571, 72163, 69496, - 43848, 0, 0, 74256, 2665, 11304, 43751, 0, 4970, 74353, 0, 8934, 0, - 93996, 4492, 92908, 65011, 0, 0, 92909, 1188, 7254, 1100, 0, 0, 0, 2912, - 11749, 92643, 0, 0, 65057, 0, 12343, 0, 78879, 0, 78880, 0, 0, 0, 70355, - 0, 0, 11803, 0, 0, 41450, 0, 100897, 0, 41451, 0, 0, 8273, 0, 3451, 0, - 972, 41453, 68164, 78876, 0, 92408, 73945, 43504, 2288, 78873, 9538, - 78874, 128685, 0, 129095, 0, 0, 0, 0, 11019, 0, 0, 121205, 0, 73007, - 71365, 92716, 5927, 0, 0, 0, 0, 128484, 0, 6073, 0, 0, 0, 6075, 93995, - 282, 126510, 0, 74078, 121459, 2206, 0, 0, 66791, 0, 3474, 0, 0, 0, 6081, - 0, 127843, 74076, 0, 0, 0, 128908, 0, 0, 0, 12623, 120273, 9120, 120275, - 4665, 12628, 4670, 120271, 120272, 0, 0, 121480, 958, 0, 0, 0, 4666, 0, - 4915, 0, 4669, 0, 0, 0, 4664, 0, 120550, 0, 0, 0, 0, 94023, 0, 917875, - 8664, 11664, 0, 129327, 11224, 0, 0, 1063, 119088, 120251, 9772, 7255, - 8886, 0, 127932, 120257, 120258, 120259, 120260, 42661, 71345, 120255, - 119125, 120265, 120266, 120267, 42721, 92407, 120262, 120263, 66788, - 1017, 0, 118580, 505, 1447, 0, 0, 70340, 66793, 65115, 42789, 128443, 0, - 0, 123634, 0, 119195, 0, 0, 11745, 7919, 0, 1641, 0, 0, 8966, 0, 0, 8743, - 71870, 0, 67813, 0, 0, 0, 123206, 0, 0, 128505, 10169, 71324, 0, 10068, - 0, 120457, 120456, 120455, 120454, 257, 43170, 13153, 0, 0, 0, 0, 0, 0, - 6496, 19917, 5930, 128354, 11033, 0, 0, 5622, 120436, 8477, 8474, 120433, - 120432, 0, 0, 0, 41435, 4352, 0, 2435, 0, 5621, 0, 4201, 8450, 4203, - 4202, 4205, 4204, 120447, 120446, 120445, 66792, 41440, 120442, 8473, - 6373, 8469, 120438, 0, 4564, 125206, 0, 0, 0, 8374, 73669, 0, 0, 66796, - 0, 0, 0, 0, 0, 69297, 129762, 5626, 43507, 11771, 0, 0, 0, 42614, 0, - 5625, 0, 0, 0, 5623, 0, 0, 42623, 64277, 69942, 0, 0, 120752, 0, 5817, - 5629, 0, 7551, 10325, 5632, 69674, 0, 0, 124946, 125194, 5628, 129766, - 5631, 0, 0, 2400, 5627, 0, 0, 118786, 74792, 0, 0, 0, 203, 129084, 74365, - 0, 0, 0, 0, 83382, 83422, 0, 0, 554, 0, 0, 0, 12182, 0, 64569, 110840, - 73891, 0, 0, 0, 7689, 69798, 9323, 10269, 10285, 10317, 175, 0, 0, 0, 0, - 0, 1243, 42154, 0, 92387, 0, 0, 43651, 0, 125021, 0, 9075, 118597, 0, - 64777, 128570, 0, 0, 0, 0, 65255, 0, 121142, 4490, 0, 6649, 120698, - 12181, 0, 11977, 7249, 8366, 0, 7756, 12342, 0, 51, 41516, 69432, 0, - 9568, 71318, 456, 0, 10437, 1168, 9251, 9082, 0, 0, 42781, 3866, 0, - 41512, 0, 0, 68121, 41494, 0, 4660, 0, 10405, 0, 0, 0, 0, 0, 73918, - 119627, 110686, 41454, 12605, 0, 126611, 41455, 917996, 983605, 0, 8214, - 0, 100413, 129320, 41457, 0, 0, 1969, 127771, 0, 69554, 7413, 0, 69426, - 10341, 43864, 78079, 5854, 0, 0, 0, 129684, 72819, 0, 0, 0, 0, 0, 8429, - 0, 72328, 0, 6429, 0, 0, 0, 0, 110688, 83417, 0, 917864, 120813, 83423, - 1662, 125000, 0, 0, 917871, 917868, 0, 0, 66, 65, 68, 67, 70, 69, 72, 71, - 74, 73, 76, 75, 78, 77, 80, 79, 82, 81, 84, 83, 86, 85, 88, 87, 90, 89, - 0, 0, 7385, 70508, 1704, 12993, 0, 0, 0, 0, 0, 0, 0, 0, 11353, 72207, 0, - 0, 0, 0, 118831, 0, 0, 0, 0, 0, 118719, 83364, 0, 0, 1289, 0, 0, 119583, - 0, 65507, 0, 0, 0, 128042, 0, 74409, 0, 0, 0, 0, 64793, 0, 0, 100843, - 5675, 119239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6972, 70735, 0, 121108, - 126217, 0, 0, 0, 0, 0, 110640, 67687, 0, 0, 119634, 0, 43977, 111252, - 129105, 0, 7412, 64671, 0, 1412, 4594, 1391, 0, 8067, 12478, 110639, - 78375, 110637, 10281, 110635, 0, 0, 7960, 43271, 0, 12518, 69846, 0, - 3566, 0, 0, 69864, 0, 0, 68021, 0, 0, 0, 8223, 0, 4261, 121460, 68918, 0, - 0, 121294, 113712, 0, 128046, 43419, 72748, 92866, 10574, 0, 67691, 0, 0, - 73785, 0, 78875, 128541, 0, 127366, 0, 0, 0, 0, 6695, 65113, 324, 0, - 128373, 40985, 0, 0, 0, 0, 0, 72307, 43474, 0, 121190, 0, 0, 3420, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 110871, 9574, 120684, 110870, 110814, 5204, 74774, - 0, 11835, 0, 0, 983185, 0, 0, 0, 0, 0, 0, 11750, 68898, 127004, 0, 0, 0, - 0, 8130, 0, 0, 0, 121268, 0, 129443, 0, 68455, 42863, 73839, 0, 0, 0, - 92288, 0, 0, 0, 612, 110875, 110876, 72231, 10538, 0, 1674, 0, 0, 0, - 12280, 0, 540, 74550, 0, 66422, 8432, 0, 11073, 0, 64316, 129894, 0, - 7388, 0, 0, 0, 0, 126107, 0, 3359, 0, 0, 67284, 0, 0, 65482, 129589, 0, - 64742, 129304, 0, 0, 74273, 0, 19941, 0, 0, 0, 0, 9481, 65555, 0, 66628, - 129126, 1195, 64898, 0, 0, 0, 2010, 0, 0, 0, 0, 0, 0, 4360, 127009, 9739, - 0, 72885, 0, 0, 0, 126265, 72200, 0, 0, 120025, 72199, 0, 0, 65734, 0, 0, - 129690, 13075, 0, 94063, 0, 43532, 10837, 2492, 74516, 983075, 120882, 0, - 0, 11813, 9649, 0, 119617, 5128, 7377, 0, 65604, 0, 0, 6771, 1648, 7819, - 0, 0, 0, 125192, 128131, 12709, 6986, 0, 0, 0, 0, 0, 12581, 0, 5175, 0, - 73806, 0, 128420, 0, 0, 77950, 0, 0, 607, 0, 0, 128846, 119605, 67475, - 129528, 65477, 0, 121130, 0, 8265, 0, 0, 0, 5840, 42838, 0, 0, 68366, 0, - 119255, 0, 0, 0, 127929, 0, 2550, 121011, 6779, 70059, 0, 0, 0, 0, 0, 0, - 5619, 65822, 0, 0, 0, 129392, 5616, 11486, 0, 0, 0, 0, 5615, 0, 121319, - 42380, 127958, 0, 66451, 74407, 0, 11347, 0, 1026, 5620, 0, 0, 11350, - 5617, 0, 0, 64639, 0, 0, 0, 1338, 0, 0, 0, 4603, 0, 70715, 92484, 0, - 9002, 0, 3974, 78213, 0, 0, 0, 0, 0, 0, 75038, 66040, 70455, 0, 0, 0, - 72982, 0, 0, 0, 0, 0, 118661, 0, 0, 119105, 0, 0, 0, 0, 0, 128883, 0, - 66897, 0, 0, 0, 42594, 0, 0, 0, 0, 6714, 10083, 0, 121019, 0, 69976, 0, - 0, 9073, 0, 64302, 0, 128286, 9725, 0, 0, 121288, 73769, 121306, 0, 9570, - 0, 11500, 2689, 917626, 0, 983813, 66740, 0, 0, 0, 917623, 13286, 5500, - 42598, 42596, 503, 0, 0, 917618, 0, 0, 0, 0, 917615, 1652, 772, 6688, - 8310, 0, 0, 72124, 0, 10194, 43542, 0, 125054, 0, 6468, 68110, 0, 917606, - 11767, 0, 0, 5836, 12358, 0, 0, 65624, 12180, 0, 127994, 0, 43699, 0, 0, - 72114, 43706, 0, 12362, 12435, 12360, 0, 9020, 0, 12356, 8616, 0, 42924, - 2227, 0, 0, 7315, 12354, 83097, 83098, 83099, 2358, 83092, 83093, 83094, - 0, 0, 83089, 83090, 0, 11759, 71723, 0, 72834, 83109, 41423, 0, 83103, - 83104, 83105, 42237, 110653, 70717, 72260, 83102, 0, 67856, 0, 128534, - 110657, 129354, 129194, 0, 64395, 0, 73008, 120897, 74816, 0, 0, 0, - 83088, 0, 0, 94064, 83083, 83085, 83086, 83087, 83079, 83080, 2041, 9178, - 0, 64870, 0, 83076, 74924, 0, 0, 0, 0, 0, 78739, 0, 0, 0, 0, 0, 0, 3726, - 0, 0, 0, 0, 0, 121432, 129457, 0, 0, 0, 0, 0, 74901, 0, 0, 0, 0, 0, - 124944, 113781, 0, 7410, 2669, 903, 0, 0, 0, 127232, 74603, 0, 128264, 0, - 128411, 0, 0, 11732, 0, 72797, 41448, 41461, 124934, 0, 917558, 0, 8819, - 0, 0, 74606, 92847, 121412, 74835, 0, 9168, 65786, 0, 73691, 0, 67665, 0, - 11758, 68425, 0, 0, 0, 128044, 0, 19924, 67312, 0, 128755, 64551, 0, - 8516, 0, 0, 7561, 983999, 74018, 0, 0, 0, 0, 83074, 83075, 0, 11233, - 83062, 83066, 3787, 83070, 83055, 41458, 83059, 41463, 65308, 41459, - 8683, 775, 0, 65584, 69923, 0, 110798, 110799, 110796, 43440, 0, 0, 0, - 3656, 0, 0, 0, 67694, 1599, 83138, 83139, 8514, 8513, 83036, 83135, - 83136, 110794, 110795, 83131, 83132, 0, 0, 0, 11684, 10542, 9937, 83150, - 0, 75037, 83145, 65730, 83147, 0, 8427, 83142, 55246, 0, 0, 11497, 0, 0, - 0, 119222, 0, 983598, 0, 10621, 0, 0, 129295, 119111, 120745, 0, 0, 0, - 11648, 83126, 83127, 42118, 83129, 83122, 65512, 83124, 83125, 0, 0, 0, - 83121, 74530, 128456, 0, 0, 0, 65724, 0, 0, 0, 65727, 0, 0, 64963, 73830, - 66042, 0, 0, 7875, 0, 0, 0, 129476, 0, 0, 536, 0, 0, 0, 0, 65173, 129122, - 0, 70331, 0, 0, 118598, 0, 129419, 0, 0, 0, 1687, 0, 0, 0, 0, 0, 0, - 10526, 0, 8323, 0, 83301, 11731, 0, 0, 65460, 12242, 0, 0, 10843, 11554, - 0, 0, 8266, 0, 121101, 0, 0, 0, 0, 67667, 118694, 119155, 0, 0, 119636, - 67857, 0, 0, 0, 11755, 66305, 0, 0, 10917, 93979, 113688, 0, 2040, 92596, - 0, 0, 0, 0, 1227, 83119, 83120, 0, 0, 83115, 83116, 11149, 4978, 83111, - 1984, 11830, 83114, 128934, 74548, 118545, 9373, 0, 0, 0, 0, 0, 0, 0, 0, - 9237, 9390, 0, 0, 0, 0, 0, 1830, 0, 0, 0, 0, 0, 128577, 983839, 68086, 0, - 0, 0, 983059, 0, 983144, 0, 0, 0, 72197, 55291, 11683, 0, 983659, 0, - 11451, 0, 72714, 3731, 2359, 0, 67844, 0, 121503, 548, 121502, 983247, - 121405, 983250, 0, 66272, 0, 64678, 0, 9547, 0, 0, 1614, 0, 0, 66307, - 128092, 1358, 120871, 428, 0, 1466, 0, 10982, 0, 0, 0, 407, 0, 0, 0, 0, - 0, 0, 5804, 73464, 0, 0, 0, 70167, 9057, 42446, 0, 125097, 0, 0, 8250, - 10952, 8048, 0, 129155, 0, 118955, 0, 0, 118593, 4407, 74648, 0, 0, 0, - 8448, 92491, 0, 0, 12675, 12659, 0, 0, 983282, 68077, 55273, 10766, - 12012, 2386, 0, 9170, 0, 9123, 128194, 0, 0, 0, 0, 129942, 0, 0, 0, 0, 0, - 0, 8709, 0, 72383, 0, 0, 0, 0, 0, 0, 0, 128342, 0, 577, 128610, 0, 0, - 124999, 68087, 74840, 126474, 127036, 0, 0, 0, 1414, 124963, 9683, 43486, - 92231, 0, 2536, 0, 66330, 0, 0, 0, 0, 0, 0, 0, 66317, 0, 66315, 66316, 0, - 0, 0, 0, 0, 0, 0, 0, 66323, 66324, 0, 0, 3106, 65917, 0, 2182, 0, 891, 0, - 0, 42624, 0, 0, 8824, 65089, 128734, 10936, 0, 0, 0, 0, 92688, 0, 0, 0, - 0, 12745, 0, 0, 41285, 3547, 0, 0, 129877, 0, 118701, 6089, 0, 68490, - 120578, 4170, 1029, 127761, 0, 0, 42374, 917625, 744, 917624, 0, 0, 0, - 93046, 0, 3551, 0, 0, 4623, 0, 0, 12340, 0, 65136, 0, 0, 0, 0, 0, 0, 0, - 72291, 0, 0, 120778, 0, 11972, 0, 78757, 0, 122886, 177, 122894, 0, 0, 0, - 0, 55243, 0, 0, 0, 70172, 120249, 120242, 128027, 120243, 0, 0, 0, - 120237, 120245, 94079, 0, 0, 9136, 120240, 120614, 41280, 0, 0, 0, 0, - 74149, 128327, 0, 0, 66361, 12601, 72194, 64360, 65163, 0, 0, 0, 0, 0, 0, - 5404, 43332, 3667, 7936, 12925, 0, 0, 0, 0, 0, 10874, 65505, 0, 0, 0, 0, - 128920, 983681, 0, 0, 0, 0, 0, 0, 0, 0, 66677, 0, 0, 0, 70088, 74148, 0, - 0, 72868, 120230, 120224, 74172, 0, 0, 94096, 0, 128414, 120636, 0, - 127519, 917609, 917616, 0, 128652, 0, 0, 11441, 0, 3512, 0, 0, 43597, 0, - 0, 72734, 68153, 41563, 0, 0, 129352, 41544, 0, 0, 74927, 0, 129177, 0, - 0, 0, 118908, 0, 78108, 67396, 73804, 64711, 0, 0, 917610, 0, 0, 0, - 11557, 127776, 0, 12079, 0, 0, 0, 0, 128861, 0, 0, 0, 0, 0, 983200, 8103, - 72303, 128174, 92486, 110698, 0, 64587, 0, 0, 124961, 0, 0, 0, 126481, 0, - 0, 0, 0, 0, 70348, 1450, 0, 1340, 0, 0, 128970, 0, 0, 125117, 0, 0, 0, 0, - 6539, 92948, 0, 128213, 125060, 0, 0, 0, 3973, 0, 70504, 121193, 7982, 0, - 0, 127194, 0, 0, 0, 128408, 118968, 6417, 120619, 129748, 0, 0, 0, - 129455, 4919, 65121, 110872, 7755, 0, 0, 64548, 0, 1621, 0, 0, 0, 0, 0, - 12188, 0, 0, 0, 0, 5015, 0, 0, 42590, 70354, 1756, 0, 0, 0, 120694, 0, 0, - 7555, 73874, 5408, 2817, 1214, 69919, 0, 983125, 0, 0, 125055, 127195, - 7957, 0, 0, 1056, 74944, 0, 0, 0, 0, 7073, 74979, 0, 70853, 0, 110874, 0, - 0, 2341, 126644, 8484, 0, 0, 68322, 0, 8461, 67721, 42269, 0, 0, 43709, - 43708, 9451, 7571, 13073, 43847, 126647, 0, 983260, 0, 0, 0, 8781, 12894, - 78134, 0, 78132, 0, 0, 78184, 0, 11338, 120768, 0, 0, 0, 0, 0, 121367, - 65021, 64795, 74574, 0, 10047, 0, 0, 0, 0, 0, 0, 119181, 163, 576, 9895, - 0, 0, 74591, 0, 0, 66888, 0, 0, 0, 0, 0, 0, 7017, 128111, 0, 0, 129922, - 0, 41591, 11036, 65252, 120795, 129488, 0, 0, 0, 0, 0, 0, 8887, 0, 7295, - 71203, 0, 127221, 0, 0, 0, 0, 8755, 0, 0, 8147, 73127, 0, 0, 121348, 0, - 129377, 0, 74499, 0, 0, 0, 4619, 0, 6654, 123192, 0, 0, 0, 65689, 10128, - 0, 129612, 0, 0, 92651, 0, 2401, 0, 8792, 118546, 0, 74980, 0, 92246, 0, - 0, 0, 12886, 0, 66624, 0, 0, 74133, 65170, 0, 74135, 0, 0, 9984, 73867, - 3010, 0, 70349, 10698, 41475, 0, 119151, 0, 119152, 0, 0, 9100, 0, 0, 0, - 78116, 64780, 2001, 0, 55230, 0, 4052, 92856, 7626, 78080, 0, 0, 0, - 41477, 0, 0, 0, 43707, 74127, 0, 0, 0, 78086, 73758, 2335, 10663, 0, 0, - 129872, 119602, 0, 0, 70325, 0, 41443, 0, 0, 0, 9711, 1523, 0, 0, 41445, - 0, 0, 8567, 41442, 12821, 0, 0, 118978, 0, 65274, 0, 94082, 0, 127515, 0, - 0, 43446, 0, 0, 0, 0, 127985, 0, 10206, 127167, 6375, 2673, 0, 0, 0, - 43219, 129355, 0, 0, 0, 0, 129400, 11799, 101225, 68466, 0, 0, 0, 0, 0, - 120736, 0, 7203, 0, 0, 70361, 127213, 120615, 127216, 0, 0, 0, 0, 43121, - 0, 128366, 72161, 0, 129868, 0, 121260, 73781, 70365, 0, 68039, 70446, + 0, 0, 0, 0, 0, 0, 4110, 66005, 74034, 0, 0, 0, 66703, 0, 0, 983158, 6025, + 69242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70733, 0, 983043, 0, 73513, 0, 68817, + 0, 0, 0, 0, 0, 0, 43286, 0, 68765, 0, 0, 0, 0, 129871, 65144, 0, 0, + 83236, 65840, 0, 0, 10081, 0, 0, 983912, 0, 0, 0, 127394, 65882, 0, + 128758, 0, 0, 3605, 10985, 0, 0, 128872, 93972, 1745, 0, 73835, 0, 0, 0, + 0, 0, 0, 8806, 7023, 0, 0, 0, 70702, 70304, 0, 0, 0, 0, 0, 0, 0, 0, 348, + 10089, 0, 9017, 0, 0, 0, 0, 0, 0, 0, 67465, 0, 42515, 0, 0, 0, 0, 5391, + 983240, 110576, 0, 0, 5561, 0, 9429, 0, 67150, 7933, 5562, 0, 0, 0, 0, + 78039, 0, 0, 0, 0, 3979, 71248, 0, 0, 0, 68847, 0, 0, 118847, 65847, + 68836, 68838, 0, 10585, 0, 92676, 7334, 0, 0, 0, 831, 0, 0, 10716, 0, + 121325, 0, 12218, 0, 6939, 70697, 65042, 0, 0, 916, 0, 0, 11968, 0, + 122641, 5563, 0, 0, 128830, 5560, 41212, 41774, 0, 4497, 0, 0, 0, 9039, + 70678, 41776, 0, 8716, 3567, 119252, 0, 0, 74260, 0, 93954, 0, 0, 100827, + 0, 128879, 70072, 68355, 68357, 0, 0, 8634, 0, 0, 4209, 120702, 68832, + 65879, 68825, 68819, 68822, 0, 5679, 68813, 68815, 68811, 68812, 64697, + 5678, 11821, 68802, 93969, 0, 0, 0, 0, 70114, 0, 0, 0, 0, 0, 0, 0, 0, + 7782, 0, 0, 0, 0, 129977, 65711, 65712, 1216, 0, 69409, 5792, 0, 0, 0, 0, + 0, 12244, 0, 5683, 0, 120895, 121336, 43448, 70670, 0, 0, 5682, 10242, + 75043, 74520, 5680, 917568, 10001, 0, 0, 1449, 10241, 0, 70708, 0, 0, + 83180, 83182, 83183, 8584, 83176, 5567, 83178, 83179, 0, 5564, 42886, + 42884, 42882, 5565, 119022, 120881, 0, 65708, 65709, 5566, 0, 65704, + 65705, 11904, 42875, 0, 42873, 5942, 0, 0, 10361, 10425, 65697, 65698, + 65699, 0, 66598, 0, 64664, 10647, 78702, 78703, 78690, 78700, 0, 65701, + 1934, 0, 0, 0, 78710, 0, 78706, 78709, 6087, 78705, 78716, 78719, 78711, + 8043, 8950, 65694, 64485, 0, 10457, 0, 78724, 78725, 78722, 72332, 78720, + 78721, 0, 65515, 0, 10035, 13069, 0, 0, 127773, 0, 0, 0, 125207, 0, 0, + 1667, 0, 0, 42428, 110950, 0, 0, 41750, 0, 0, 93999, 0, 8101, 3610, + 113670, 41748, 110948, 0, 78394, 119208, 0, 0, 113691, 64549, 68359, 0, + 0, 65692, 92701, 0, 917960, 12896, 10456, 68298, 0, 0, 0, 0, 917962, 0, + 0, 113665, 70502, 0, 65687, 0, 0, 74009, 0, 113673, 8536, 70671, 0, + 78726, 0, 724, 0, 113675, 78749, 9975, 78746, 78747, 78744, 4175, 78741, + 78743, 78751, 939, 0, 128799, 983120, 0, 0, 0, 78763, 78764, 78760, + 78761, 78758, 78759, 78755, 8425, 0, 0, 0, 8188, 0, 0, 0, 0, 0, 6370, 0, + 7827, 68441, 75008, 0, 917943, 0, 118863, 0, 0, 0, 0, 121243, 73988, 0, + 113668, 0, 11012, 0, 43764, 178, 12972, 74620, 113671, 0, 113735, 0, + 66764, 0, 0, 65690, 72339, 0, 0, 917950, 9252, 0, 4652, 74259, 0, 917947, + 0, 0, 0, 10806, 0, 0, 70016, 0, 6723, 0, 0, 6993, 0, 0, 12855, 0, 0, + 11390, 0, 0, 0, 92503, 0, 0, 983162, 125270, 92627, 8278, 0, 4034, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 12750, 9350, 66037, 0, 0, 73700, 12747, 0, 0, + 128064, 8922, 74640, 0, 0, 43150, 0, 983090, 983088, 66779, 66777, 10813, + 2592, 43139, 0, 0, 118612, 0, 0, 71891, 0, 0, 0, 0, 0, 0, 71697, 0, + 128825, 1596, 0, 0, 0, 0, 6838, 66572, 0, 126574, 120627, 8092, 12805, + 41928, 0, 78406, 78409, 0, 0, 0, 9931, 0, 0, 0, 0, 0, 983778, 6107, 0, 0, + 0, 0, 128745, 0, 335, 127003, 64689, 0, 0, 5765, 0, 0, 119227, 6092, + 118851, 0, 8876, 83465, 74947, 83455, 129186, 83454, 70713, 0, 0, 126606, + 70121, 41602, 0, 92308, 74831, 0, 11783, 68482, 0, 0, 0, 0, 0, 0, 843, 0, + 71099, 0, 0, 41935, 0, 0, 0, 0, 1371, 0, 43818, 43159, 8069, 9579, 41938, + 41608, 0, 92444, 6242, 0, 0, 128595, 128244, 0, 92499, 8805, 1742, + 113722, 0, 8202, 72399, 0, 983198, 0, 0, 73882, 100809, 0, 43467, 123636, + 55290, 0, 1712, 5932, 0, 41762, 71982, 0, 11967, 1775, 0, 75009, 0, + 11868, 120387, 9458, 0, 126614, 0, 0, 43176, 101032, 101031, 42782, + 101033, 101036, 101035, 101038, 101037, 101040, 101039, 0, 0, 0, 0, + 101041, 5794, 92274, 2662, 101045, 101044, 8254, 101046, 10975, 101048, + 120625, 101050, 917977, 4108, 8478, 917982, 194790, 0, 92263, 917980, + 7507, 0, 43149, 0, 65031, 7961, 1636, 0, 65029, 0, 129665, 70188, 9674, + 0, 99, 98, 97, 101022, 92203, 4049, 101027, 43880, 7090, 101028, 0, + 101030, 66589, 0, 65310, 66593, 66599, 129805, 0, 0, 7447, 66594, 0, 0, + 0, 73920, 66595, 66596, 42570, 5593, 0, 0, 0, 0, 6061, 64854, 119, 118, + 117, 116, 0, 122, 121, 120, 111, 110, 109, 108, 115, 114, 113, 112, 103, + 102, 101, 100, 107, 106, 105, 104, 128504, 73974, 534, 0, 67713, 1536, + 73973, 73970, 0, 129671, 0, 6020, 12716, 0, 12744, 65143, 0, 13266, + 127813, 0, 0, 0, 127116, 0, 1212, 65560, 0, 8134, 42935, 12129, 73870, 0, + 1866, 0, 122948, 0, 0, 65073, 12059, 66585, 121391, 0, 0, 0, 5935, 1250, + 0, 8174, 9787, 6733, 9859, 9858, 9861, 9860, 101012, 1882, 1892, 6731, + 10882, 10795, 101018, 73911, 101020, 101019, 41169, 8939, 0, 120713, + 41170, 1454, 0, 65130, 69732, 0, 0, 129611, 41172, 7855, 0, 71472, 0, 0, + 0, 71691, 65901, 0, 0, 645, 100992, 100991, 100994, 100993, 100996, + 100995, 100998, 65587, 0, 10688, 0, 0, 7729, 0, 101001, 120518, 101003, + 66722, 101005, 101004, 68415, 101006, 4538, 101008, 43141, 0, 0, 73699, + 0, 0, 0, 71918, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71454, 0, 2381, 983752, 0, 0, + 69857, 100981, 0, 100983, 100982, 100985, 10856, 100987, 55255, 41478, + 8582, 10064, 0, 0, 0, 0, 64896, 0, 74609, 0, 128048, 10082, 11575, 0, 0, + 0, 917505, 0, 6145, 75020, 0, 92433, 71916, 83279, 43186, 0, 0, 83274, + 83276, 83277, 83278, 10191, 83271, 69633, 72353, 0, 0, 0, 0, 120090, + 120089, 7931, 8558, 917946, 0, 0, 0, 119145, 120081, 120084, 120083, + 120086, 71449, 120088, 7366, 7019, 75021, 0, 917951, 120078, 120077, + 120080, 8657, 100967, 8594, 100969, 100968, 0, 100970, 120072, 120071, 0, + 0, 43154, 0, 0, 11332, 0, 7728, 100978, 100977, 100980, 100979, 7851, 0, + 8375, 128662, 0, 0, 126095, 9085, 0, 0, 9327, 6160, 0, 0, 0, 0, 70698, + 74012, 0, 0, 4439, 121151, 100972, 100971, 100974, 100973, 100976, + 100975, 100956, 42524, 71220, 100957, 10826, 100959, 11296, 0, 0, 0, + 7504, 43161, 127868, 0, 64670, 0, 78056, 0, 11295, 0, 78053, 0, 0, 0, + 10902, 0, 0, 122650, 78068, 10472, 100954, 100953, 120215, 78062, 2371, + 78069, 118893, 259, 0, 0, 2402, 12157, 6440, 0, 100963, 100962, 100965, + 100964, 65380, 9103, 2278, 0, 0, 7301, 0, 10219, 0, 0, 0, 67718, 43178, + 0, 120214, 119362, 917974, 8613, 0, 126121, 917978, 917979, 121449, + 12005, 7353, 0, 1890, 129130, 0, 0, 0, 42815, 7991, 0, 10578, 0, 0, 0, 0, + 0, 0, 0, 111190, 120601, 42668, 9348, 0, 6164, 0, 0, 0, 7676, 0, 0, 0, 0, + 128732, 129422, 83443, 71096, 83444, 9175, 0, 78047, 9088, 73689, 0, + 1396, 0, 0, 11461, 71088, 127835, 92252, 0, 71090, 121185, 69872, 0, 0, + 0, 0, 74043, 119632, 0, 0, 0, 5928, 4525, 10658, 0, 1266, 10180, 64472, + 0, 12622, 0, 0, 0, 0, 127139, 13310, 773, 19933, 0, 0, 0, 0, 92205, 0, 0, + 0, 0, 5862, 7823, 0, 0, 0, 3250, 43991, 69687, 66649, 0, 0, 0, 0, 0, + 64673, 917963, 917964, 0, 0, 917967, 917968, 917965, 917966, 127791, + 75041, 3471, 917970, 64573, 882, 0, 119584, 0, 120772, 0, 0, 0, 92696, 0, + 0, 72988, 0, 3225, 0, 73729, 0, 0, 43173, 11752, 4381, 0, 0, 917945, + 11756, 11757, 917944, 917949, 42654, 127848, 118663, 0, 0, 5160, 1387, 0, + 917953, 0, 128933, 917956, 917957, 917954, 917955, 118595, 121082, + 917958, 10789, 68314, 0, 126521, 11143, 0, 0, 70669, 128904, 42179, 0, + 5931, 11744, 11215, 70676, 119245, 0, 0, 0, 77915, 10217, 64635, 128661, + 83292, 0, 0, 0, 0, 0, 41296, 11747, 41291, 0, 0, 0, 41294, 41282, 5923, + 120610, 0, 0, 0, 0, 66800, 5786, 68252, 42539, 119869, 119860, 0, 41474, + 0, 0, 0, 5934, 74572, 66583, 119231, 0, 94072, 64481, 0, 0, 0, 0, 67240, + 0, 0, 123201, 0, 5819, 0, 0, 0, 0, 0, 129387, 0, 0, 0, 67993, 1237, + 194749, 0, 0, 983557, 0, 0, 0, 0, 0, 0, 0, 69789, 11266, 69845, 0, 10506, + 194747, 0, 0, 0, 0, 43185, 194748, 100533, 100532, 100535, 10769, 100537, + 100536, 100539, 9753, 121035, 100540, 0, 0, 121433, 0, 100542, 6072, + 100544, 100543, 100546, 100545, 100548, 100547, 100550, 100549, 0, + 113744, 0, 0, 7222, 10283, 10315, 10379, 4996, 0, 129294, 66517, 0, + 10087, 127833, 74938, 0, 0, 83492, 7565, 42890, 0, 73520, 43180, 77928, + 74891, 77929, 43982, 100526, 622, 77926, 100527, 100530, 1602, 0, 0, 0, + 129559, 12160, 0, 10212, 77936, 194605, 12071, 43143, 77935, 917983, + 917984, 917989, 77932, 917987, 917988, 10255, 10263, 10279, 4194, 10375, + 93035, 0, 0, 12644, 127516, 917994, 75007, 110791, 67408, 110789, 11501, + 41177, 0, 0, 71912, 0, 0, 8715, 0, 41179, 0, 0, 0, 41176, 0, 41181, 0, + 8452, 121006, 13161, 0, 70503, 5921, 0, 2597, 0, 5922, 72128, 0, 74242, + 128374, 0, 0, 0, 0, 0, 0, 0, 127906, 0, 64944, 0, 0, 0, 0, 5924, 5920, + 129508, 6921, 78081, 74007, 78078, 8418, 11681, 43169, 10176, 0, 0, 0, + 78087, 10772, 65276, 5937, 1914, 78084, 11682, 0, 0, 0, 11685, 0, 100513, + 7772, 11680, 100514, 100517, 100516, 100519, 7417, 718, 100520, 70083, + 100500, 120718, 3235, 0, 43164, 0, 8018, 0, 0, 128708, 6937, 67672, + 128508, 0, 10067, 120849, 0, 0, 0, 118693, 0, 100491, 0, 100493, 100492, + 13116, 100494, 100497, 9945, 100499, 100498, 0, 0, 0, 0, 2059, 0, 100502, + 100501, 1431, 100503, 66565, 100505, 100508, 12804, 100510, 100509, + 78090, 3307, 78088, 78089, 0, 4544, 71228, 0, 0, 0, 78097, 11110, 66810, + 12882, 64511, 78094, 78100, 78102, 71226, 10141, 0, 78280, 65298, 4476, + 78109, 94005, 71216, 8907, 78105, 78106, 78103, 78104, 120898, 0, 10665, + 64616, 128944, 0, 127545, 69605, 83159, 83160, 4554, 0, 83155, 83156, + 83157, 83158, 0, 125123, 0, 72258, 129831, 0, 129815, 0, 43179, 0, 0, 0, + 717, 10754, 83168, 83169, 83162, 83163, 83164, 83165, 78282, 0, 0, 83161, + 68848, 10611, 72859, 126978, 71474, 129426, 127871, 0, 0, 0, 12820, + 110882, 0, 7009, 70103, 0, 0, 67848, 41173, 4574, 0, 0, 128338, 575, + 78110, 43456, 8563, 100469, 0, 0, 65565, 123598, 5936, 7290, 78117, + 78118, 74919, 308, 78113, 78114, 83151, 78123, 83153, 83154, 0, 0, 0, 0, + 67496, 5926, 68250, 78130, 78126, 78127, 78124, 78125, 42513, 0, 129026, + 0, 11651, 13093, 78135, 0, 100471, 0, 100473, 100472, 100475, 74048, + 100477, 71995, 100457, 100456, 43703, 13097, 0, 100460, 13283, 0, 0, + 125073, 3488, 5933, 10033, 983947, 0, 65570, 0, 12297, 0, 0, 0, 128517, + 42538, 0, 129293, 0, 100451, 0, 100453, 100452, 100455, 100454, 121221, + 0, 0, 7638, 0, 129193, 0, 43109, 7637, 0, 11213, 100461, 83355, 100463, + 100466, 100465, 0, 0, 7636, 0, 0, 0, 128848, 983087, 291, 0, 0, 2027, + 78141, 78142, 78136, 78137, 83481, 4640, 64713, 10224, 120429, 11183, + 83482, 120430, 0, 0, 0, 127148, 83479, 0, 0, 83488, 0, 0, 0, 0, 68837, + 5778, 0, 0, 0, 12680, 119130, 0, 67242, 93041, 0, 0, 0, 11552, 0, 127855, + 0, 70091, 0, 10172, 65453, 120408, 66014, 120410, 0, 4641, 11556, 64819, + 78269, 120416, 72341, 41469, 41467, 120412, 120415, 4646, 120425, 865, + 78275, 78274, 78273, 4645, 78271, 78270, 0, 983173, 7338, 0, 68840, 0, + 12565, 0, 0, 0, 195089, 119655, 195091, 195090, 2913, 13120, 128956, + 69493, 195097, 195096, 128019, 0, 71462, 0, 7916, 10485, 195098, 0, + 195100, 195099, 0, 67705, 128351, 195077, 195080, 129636, 129549, 195081, + 0, 0, 0, 10229, 10687, 826, 128081, 195082, 195085, 195084, 195087, + 195086, 0, 1808, 7848, 0, 0, 0, 0, 0, 0, 128897, 69255, 42942, 67704, 0, + 0, 0, 0, 42940, 0, 9144, 0, 0, 92992, 9840, 0, 0, 0, 0, 0, 0, 74448, + 83475, 0, 10962, 66904, 113718, 983188, 0, 0, 74537, 195072, 1792, + 195074, 195073, 78266, 195075, 0, 0, 12066, 0, 385, 4152, 0, 0, 0, 67397, + 0, 0, 0, 0, 43258, 0, 0, 13157, 0, 0, 3570, 0, 0, 0, 67252, 0, 71218, + 126631, 7879, 68247, 128579, 78914, 0, 70196, 0, 0, 8463, 7810, 917862, + 7839, 983878, 127768, 917860, 9691, 0, 129323, 0, 120385, 0, 917844, 0, + 10066, 0, 2175, 0, 0, 0, 8016, 0, 983072, 64831, 0, 126103, 0, 73493, + 1634, 68115, 94192, 11056, 0, 0, 0, 41165, 11328, 12450, 0, 41166, 0, + 12456, 0, 171, 67508, 12452, 917544, 12458, 12531, 0, 917853, 0, 74162, + 0, 0, 9969, 0, 12454, 74160, 42132, 110755, 78878, 110753, 3230, 73711, + 0, 0, 8932, 4399, 5810, 64534, 8415, 0, 110756, 110757, 74159, 0, 0, 960, + 74156, 6981, 92374, 12938, 9201, 0, 118713, 74904, 0, 72866, 92270, 0, 0, + 0, 129792, 5851, 73833, 5824, 0, 5844, 110848, 110849, 110846, 110847, + 4663, 0, 0, 0, 0, 0, 74085, 0, 0, 0, 0, 0, 92339, 0, 0, 5782, 67495, 0, + 0, 43796, 129639, 0, 195083, 125223, 128004, 0, 43861, 0, 0, 0, 92976, 0, + 0, 0, 4659, 0, 128894, 0, 0, 129386, 0, 11129, 2238, 329, 0, 92707, + 121416, 0, 0, 0, 69943, 67692, 42167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 69618, 43671, 0, 64701, 0, 0, 0, 93055, 1172, 125089, 6786, 43601, 0, + 74126, 0, 0, 0, 0, 0, 118695, 0, 0, 118804, 0, 66741, 5347, 125026, + 983663, 0, 0, 10588, 0, 0, 0, 0, 5343, 0, 0, 0, 5341, 0, 0, 74916, 5351, + 0, 0, 917884, 0, 92692, 0, 121148, 128916, 0, 0, 66785, 126256, 6638, 0, + 0, 271, 0, 917904, 0, 0, 12653, 67588, 0, 0, 0, 0, 128838, 11912, 128301, + 983665, 0, 11800, 0, 0, 11103, 0, 7340, 0, 110695, 0, 0, 70170, 0, 2423, + 0, 0, 0, 128136, 42705, 0, 0, 0, 11854, 0, 0, 0, 0, 4916, 0, 380, 10958, + 66563, 127790, 78284, 67587, 0, 12918, 0, 917897, 0, 917898, 917893, + 10684, 0, 125063, 92906, 0, 0, 8182, 0, 0, 129434, 0, 0, 0, 6859, 0, + 6630, 100405, 0, 123191, 0, 0, 0, 65876, 5535, 129892, 0, 0, 92609, 0, + 983348, 6477, 43795, 92217, 129571, 72163, 69496, 43848, 0, 0, 74256, + 2665, 11304, 43751, 0, 4970, 74353, 0, 8934, 0, 93996, 4492, 92908, + 65011, 0, 0, 92909, 1188, 7254, 1100, 0, 0, 0, 2912, 11749, 92643, 0, 0, + 65057, 0, 12343, 0, 78879, 0, 78880, 0, 0, 0, 70355, 0, 0, 11803, 0, 0, + 41450, 0, 100897, 0, 41451, 0, 0, 8273, 0, 3451, 0, 972, 41453, 68164, + 78876, 0, 92408, 73945, 43504, 2288, 78873, 9538, 78874, 128685, 0, + 129095, 0, 0, 0, 0, 11019, 0, 0, 121205, 0, 73007, 71365, 92716, 5927, 0, + 0, 0, 0, 128484, 0, 6073, 0, 0, 0, 6075, 93995, 282, 126510, 0, 74078, + 121459, 2206, 0, 0, 66791, 0, 3474, 0, 0, 0, 6081, 0, 127843, 74076, 0, + 0, 0, 128908, 0, 0, 0, 12623, 120273, 9120, 120275, 4665, 12628, 4670, + 120271, 120272, 0, 0, 121480, 958, 0, 0, 0, 4666, 0, 4915, 0, 4669, 0, 0, + 0, 4664, 0, 120550, 0, 0, 0, 0, 94023, 0, 917875, 8664, 11664, 0, 129327, + 11224, 0, 0, 1063, 119088, 120251, 9772, 7255, 8886, 0, 127932, 120257, + 120258, 120259, 120260, 42661, 71345, 120255, 119125, 120265, 120266, + 120267, 42721, 92407, 120262, 120263, 66788, 1017, 0, 118580, 505, 1447, + 0, 0, 70340, 66793, 65115, 42789, 128443, 0, 0, 123634, 0, 119195, 0, 0, + 11745, 7919, 0, 1641, 0, 0, 8966, 0, 0, 8743, 71870, 0, 67813, 0, 0, 0, + 123206, 0, 0, 128505, 10169, 71324, 0, 10068, 0, 120457, 120456, 120455, + 120454, 257, 43170, 13153, 0, 0, 0, 0, 0, 0, 6496, 19917, 5930, 128354, + 11033, 0, 0, 5622, 120436, 8477, 8474, 120433, 120432, 0, 0, 0, 41435, + 4352, 0, 2435, 0, 5621, 0, 4201, 8450, 4203, 4202, 4205, 4204, 120447, + 120446, 120445, 66792, 41440, 120442, 8473, 6373, 8469, 120438, 0, 4564, + 125206, 0, 0, 0, 8374, 73669, 0, 0, 66796, 0, 0, 0, 0, 0, 69297, 129762, + 5626, 43507, 11771, 0, 0, 0, 42614, 0, 5625, 0, 0, 0, 5623, 0, 0, 42623, + 64277, 69942, 0, 0, 120752, 0, 5817, 5629, 0, 7551, 10325, 5632, 69674, + 0, 0, 124946, 125194, 5628, 129766, 5631, 0, 0, 2400, 5627, 0, 0, 118786, + 74792, 0, 0, 0, 203, 129084, 74365, 0, 0, 0, 0, 83382, 83422, 0, 0, 554, + 0, 0, 0, 12182, 0, 64569, 110840, 73891, 0, 0, 0, 7689, 69798, 9323, + 10269, 10285, 10317, 175, 0, 0, 0, 0, 0, 1243, 42154, 0, 92387, 0, 0, + 43651, 0, 125021, 0, 9075, 118597, 0, 64777, 128570, 0, 0, 0, 0, 65255, + 0, 121142, 4490, 0, 6649, 120698, 12181, 0, 11977, 7249, 8366, 0, 7756, + 12342, 0, 51, 41516, 69432, 0, 9568, 71318, 456, 0, 10437, 1168, 9251, + 9082, 0, 0, 42781, 3866, 0, 41512, 0, 0, 68121, 41494, 0, 4660, 0, 10405, + 0, 0, 0, 0, 0, 73918, 119627, 110686, 41454, 12605, 0, 126611, 41455, + 917996, 983605, 0, 8214, 0, 100413, 129320, 41457, 983077, 0, 1969, + 127771, 0, 69554, 7413, 0, 69426, 10341, 43864, 78079, 5854, 0, 0, 0, + 129684, 72819, 0, 0, 73548, 0, 0, 8429, 0, 72328, 0, 6429, 0, 0, 0, 0, + 110688, 83417, 0, 917864, 120813, 83423, 1662, 125000, 0, 0, 917871, + 917868, 0, 0, 66, 65, 68, 67, 70, 69, 72, 71, 74, 73, 76, 75, 78, 77, 80, + 79, 82, 81, 84, 83, 86, 85, 88, 87, 90, 89, 0, 0, 7385, 70508, 1704, + 12993, 0, 0, 0, 0, 0, 0, 0, 0, 11353, 72207, 0, 0, 0, 0, 118831, 0, 0, 0, + 0, 0, 118719, 83364, 0, 0, 1289, 0, 0, 119583, 0, 65507, 0, 0, 0, 128042, + 0, 74409, 0, 0, 0, 0, 64793, 0, 0, 100843, 5675, 119239, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 6972, 70735, 0, 121108, 126217, 0, 0, 0, 0, 0, 110640, + 67687, 0, 0, 119634, 0, 43977, 111252, 129105, 0, 7412, 64671, 0, 1412, + 4594, 1391, 0, 8067, 12478, 110639, 78375, 110637, 10281, 110635, 0, 0, + 7960, 43271, 0, 12518, 69846, 0, 3566, 0, 0, 69864, 0, 0, 68021, 0, 0, 0, + 8223, 0, 4261, 121460, 68918, 0, 0, 121294, 113712, 0, 128046, 43419, + 72748, 92866, 10574, 0, 67691, 0, 0, 73785, 0, 78875, 128541, 0, 127366, + 0, 0, 0, 0, 6695, 65113, 324, 0, 128373, 40985, 0, 0, 0, 0, 0, 72307, + 43474, 0, 121190, 0, 0, 3420, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110871, 9574, + 120684, 110870, 110814, 5204, 74774, 0, 11835, 0, 0, 983186, 0, 0, 0, 0, + 0, 0, 11750, 68898, 127004, 0, 0, 0, 0, 8130, 0, 0, 0, 121268, 0, 129443, + 0, 68455, 42863, 73839, 0, 0, 0, 92288, 0, 0, 0, 612, 110875, 110876, + 72231, 10538, 0, 1674, 0, 0, 0, 12280, 0, 540, 74550, 0, 66422, 8432, 0, + 11073, 0, 64316, 129894, 0, 7388, 0, 0, 0, 0, 126107, 0, 3359, 0, 0, + 67284, 0, 0, 65482, 129589, 0, 64742, 129304, 0, 124141, 74273, 0, 19941, + 0, 0, 0, 0, 9481, 65555, 0, 66628, 129126, 1195, 64898, 0, 0, 0, 2010, 0, + 0, 0, 0, 0, 0, 4360, 127009, 9739, 0, 72885, 0, 0, 0, 126265, 72200, 0, + 0, 120025, 72199, 0, 0, 65734, 0, 0, 129690, 13075, 0, 94063, 0, 43532, + 10837, 2492, 74516, 983075, 120882, 0, 0, 11813, 9649, 0, 119617, 5128, + 7377, 0, 65604, 0, 0, 6771, 1648, 7819, 0, 0, 0, 125192, 128131, 12709, + 6986, 0, 0, 0, 0, 0, 12581, 0, 5175, 0, 73806, 0, 128420, 0, 0, 77950, 0, + 0, 607, 0, 0, 128846, 119605, 67475, 129528, 65477, 0, 121130, 0, 8265, + 0, 0, 0, 5840, 42838, 0, 0, 68366, 0, 119255, 0, 0, 0, 127929, 0, 2550, + 121011, 6779, 70059, 0, 0, 0, 0, 0, 0, 5619, 65822, 0, 0, 0, 129392, + 5616, 11486, 0, 0, 0, 0, 5615, 0, 121319, 42380, 127958, 0, 66451, 74407, + 0, 11347, 0, 1026, 5620, 0, 0, 11350, 5617, 0, 0, 64639, 0, 0, 0, 1338, + 0, 0, 0, 4603, 0, 70715, 92484, 0, 9002, 0, 3974, 78213, 0, 0, 0, 0, 0, + 0, 75038, 66040, 70455, 0, 0, 0, 72982, 0, 0, 0, 0, 0, 118661, 0, 0, + 119105, 0, 0, 0, 0, 0, 128883, 0, 66897, 0, 0, 0, 42594, 0, 0, 0, 0, + 6714, 10083, 0, 121019, 0, 69976, 0, 0, 9073, 0, 64302, 0, 128286, 9725, + 0, 0, 121288, 73769, 121306, 0, 9570, 0, 11500, 2689, 917626, 0, 983813, + 66740, 0, 0, 0, 917623, 13286, 5500, 42598, 42596, 503, 0, 0, 917618, 0, + 0, 0, 0, 917615, 1652, 772, 6688, 8310, 0, 0, 72124, 0, 10194, 43542, 0, + 125054, 0, 6468, 68110, 0, 917606, 11767, 0, 0, 5836, 12358, 0, 0, 65624, + 12180, 0, 127994, 0, 43699, 0, 0, 72114, 43706, 0, 12362, 12435, 12360, + 0, 9020, 0, 12356, 8616, 0, 42924, 2227, 0, 0, 7315, 12354, 83097, 83098, + 83099, 2358, 83092, 83093, 83094, 0, 0, 83089, 83090, 0, 11759, 71723, 0, + 72834, 83109, 41423, 0, 83103, 83104, 83105, 42237, 110653, 70717, 72260, + 83102, 0, 67856, 0, 128534, 110657, 129354, 129194, 0, 64395, 0, 73008, + 120897, 74816, 0, 0, 0, 83088, 0, 0, 94064, 83083, 83085, 83086, 83087, + 83079, 83080, 2041, 9178, 0, 64870, 0, 83076, 74924, 0, 0, 0, 0, 0, + 78739, 0, 0, 0, 0, 0, 0, 3726, 0, 0, 0, 0, 0, 121432, 129457, 0, 0, 0, 0, + 0, 74901, 0, 0, 0, 0, 0, 124944, 113781, 0, 7410, 2669, 903, 0, 0, 0, + 127232, 74603, 0, 128264, 0, 128411, 0, 0, 11732, 0, 72797, 41448, 41461, + 124934, 0, 917558, 0, 8819, 0, 0, 74606, 92847, 121412, 74835, 0, 9168, + 65786, 0, 73691, 0, 67665, 0, 11758, 68425, 0, 0, 0, 128044, 0, 19924, + 67312, 0, 128755, 64551, 0, 8516, 0, 0, 7561, 983999, 74018, 0, 0, 0, 0, + 83074, 83075, 0, 11233, 83062, 83066, 3787, 83070, 83055, 41458, 83059, + 41463, 65308, 41459, 8683, 775, 0, 65584, 69923, 0, 110798, 110799, + 110796, 43440, 0, 0, 0, 3656, 0, 0, 0, 67694, 1599, 83138, 83139, 8514, + 8513, 83036, 83135, 83136, 110794, 110795, 83131, 83132, 0, 0, 0, 11684, + 10542, 9937, 83150, 0, 75037, 83145, 65730, 83147, 0, 8427, 83142, 55246, + 0, 0, 11497, 0, 0, 0, 119222, 0, 983598, 0, 10621, 0, 0, 129295, 119111, + 120745, 0, 0, 0, 11648, 83126, 83127, 42118, 83129, 83122, 65512, 83124, + 83125, 0, 0, 0, 83121, 74530, 128456, 0, 0, 0, 65724, 0, 0, 0, 65727, 0, + 0, 64963, 73830, 66042, 0, 0, 7875, 0, 0, 0, 129476, 0, 0, 536, 0, 0, 0, + 0, 65173, 129122, 0, 70331, 0, 0, 118598, 0, 129419, 0, 0, 0, 1687, 0, 0, + 0, 0, 0, 0, 10526, 0, 8323, 0, 83301, 11731, 73530, 0, 65460, 12242, 0, + 0, 10843, 11554, 0, 0, 8266, 0, 121101, 0, 0, 0, 0, 67667, 118694, + 119155, 0, 0, 119636, 67857, 0, 0, 0, 11755, 66305, 0, 0, 10917, 93979, + 113688, 0, 2040, 92596, 0, 0, 0, 0, 1227, 83119, 83120, 0, 0, 83115, + 74427, 11149, 4978, 83111, 1984, 11830, 83114, 128934, 74548, 118545, + 9373, 0, 0, 0, 0, 0, 0, 0, 0, 9237, 9390, 0, 0, 0, 0, 0, 1830, 0, 0, 0, + 0, 0, 128577, 983839, 68086, 0, 0, 0, 983059, 0, 983145, 0, 0, 0, 72197, + 55291, 11683, 0, 983659, 0, 11451, 0, 72714, 3731, 2359, 0, 67844, 0, + 121503, 548, 121502, 983250, 121405, 983253, 0, 66272, 0, 64678, 0, 9547, + 0, 0, 1614, 0, 0, 66307, 128092, 1358, 120871, 428, 0, 1466, 0, 10982, 0, + 0, 0, 407, 0, 0, 0, 0, 0, 0, 5804, 73464, 0, 0, 0, 70167, 9057, 42446, 0, + 125097, 0, 0, 8250, 10952, 8048, 0, 129155, 0, 118955, 0, 0, 118593, + 4407, 74648, 0, 0, 0, 8448, 92491, 0, 0, 12675, 12659, 0, 0, 983285, + 68077, 55273, 10766, 12012, 2386, 0, 9170, 0, 9123, 128194, 0, 0, 0, 0, + 129942, 0, 0, 0, 0, 0, 0, 8709, 0, 72383, 0, 0, 0, 0, 0, 0, 0, 128342, 0, + 577, 128610, 0, 0, 124999, 68087, 74840, 126474, 127036, 0, 0, 0, 1414, + 124963, 9683, 43486, 92231, 0, 2536, 0, 66330, 0, 0, 0, 0, 0, 0, 0, + 66317, 0, 66315, 66316, 0, 0, 0, 0, 0, 0, 0, 0, 66323, 66324, 0, 0, 3106, + 65917, 0, 2182, 0, 891, 0, 0, 42624, 0, 0, 8824, 65089, 128734, 10936, 0, + 0, 0, 0, 92688, 0, 0, 0, 0, 12745, 0, 0, 41285, 3547, 0, 0, 129877, 0, + 118701, 6089, 0, 68490, 120578, 4170, 1029, 127761, 0, 0, 42374, 917625, + 744, 917624, 0, 0, 0, 93046, 0, 3551, 0, 0, 4623, 0, 0, 12340, 0, 65136, + 0, 0, 0, 0, 0, 0, 0, 72291, 0, 0, 120778, 0, 11972, 0, 78757, 0, 122886, + 177, 122894, 0, 0, 0, 0, 55243, 0, 0, 0, 70172, 120249, 120242, 128027, + 120243, 0, 0, 0, 120237, 120245, 94079, 0, 0, 9136, 120240, 120614, + 41280, 0, 0, 0, 0, 74149, 128327, 0, 0, 66361, 12601, 72194, 64360, + 65163, 125241, 0, 0, 0, 0, 0, 5404, 43332, 3667, 7936, 12925, 0, 0, 0, 0, + 0, 10874, 65505, 0, 0, 0, 0, 128920, 983681, 0, 0, 0, 0, 0, 0, 0, 0, + 66677, 0, 0, 0, 70088, 74148, 0, 0, 72868, 120230, 120224, 74172, 0, 0, + 94096, 0, 128414, 120636, 0, 127519, 917609, 917616, 0, 128652, 0, 0, + 11441, 0, 3512, 0, 0, 43597, 0, 0, 72734, 68153, 41563, 0, 0, 129352, + 41544, 0, 0, 74927, 0, 129177, 0, 0, 0, 118908, 0, 78108, 67396, 73804, + 64711, 0, 0, 917610, 0, 0, 0, 11557, 127776, 0, 12079, 0, 0, 0, 0, + 128861, 0, 0, 0, 0, 0, 983201, 8103, 72303, 128174, 92486, 110698, 0, + 64587, 0, 0, 124961, 0, 0, 0, 126481, 0, 0, 0, 0, 0, 70348, 1450, 0, + 1340, 0, 0, 128970, 0, 0, 125117, 0, 0, 0, 0, 6539, 92948, 0, 128213, + 125060, 0, 0, 0, 3973, 0, 70504, 121193, 7982, 0, 0, 127194, 0, 0, 0, + 128408, 118968, 6417, 120619, 129748, 0, 0, 0, 129455, 4919, 65121, + 110872, 7755, 0, 0, 64548, 0, 1621, 0, 0, 0, 0, 0, 12188, 0, 0, 0, 0, + 5015, 0, 0, 42590, 70354, 1756, 0, 0, 0, 120694, 0, 0, 7555, 73874, 5408, + 2817, 1214, 69919, 0, 983126, 0, 0, 125055, 127195, 7957, 0, 0, 1056, + 74944, 0, 0, 0, 0, 7073, 74979, 0, 70853, 0, 110874, 0, 0, 2341, 126644, + 8484, 0, 0, 68322, 0, 8461, 67721, 42269, 0, 0, 43709, 43708, 9451, 7571, + 13073, 43847, 126647, 0, 983263, 0, 0, 0, 8781, 12894, 78134, 0, 78132, + 0, 0, 78184, 0, 11338, 120768, 0, 0, 0, 0, 0, 121367, 65021, 64795, + 74574, 0, 10047, 0, 0, 0, 0, 0, 0, 119181, 163, 576, 9895, 0, 0, 74591, + 0, 0, 66888, 0, 0, 0, 0, 0, 0, 7017, 128111, 0, 0, 129922, 0, 41591, + 11036, 65252, 120795, 129488, 0, 0, 0, 0, 0, 0, 8887, 0, 7295, 71203, 0, + 127221, 0, 0, 0, 0, 8755, 0, 0, 8147, 73127, 0, 0, 121348, 0, 129377, 0, + 74499, 0, 0, 0, 4619, 0, 6654, 123192, 0, 0, 0, 65689, 10128, 0, 129612, + 0, 0, 92651, 0, 2401, 0, 8792, 118546, 0, 74980, 0, 92246, 0, 0, 0, + 12886, 0, 66624, 0, 0, 74133, 65170, 0, 74135, 0, 0, 9984, 73867, 3010, + 0, 70349, 10698, 41475, 0, 119151, 0, 119152, 0, 0, 9100, 0, 0, 0, 78116, + 64780, 2001, 0, 55230, 0, 4052, 92856, 7626, 78080, 0, 0, 0, 41477, 0, 0, + 0, 43707, 74127, 0, 0, 0, 78086, 73758, 2335, 10663, 0, 0, 129872, + 119602, 0, 0, 70325, 0, 41443, 0, 0, 0, 9711, 1523, 0, 0, 41445, 0, 0, + 8567, 41442, 12821, 0, 0, 118978, 0, 65274, 0, 94082, 0, 127515, 0, 0, + 43446, 0, 0, 0, 0, 127985, 0, 10206, 127167, 6375, 2673, 0, 0, 0, 43219, + 129355, 0, 0, 0, 0, 129400, 11799, 101225, 68466, 0, 0, 0, 0, 0, 120736, + 0, 7203, 0, 0, 70361, 127213, 120615, 127216, 0, 0, 0, 0, 43121, 0, + 128366, 72161, 0, 129868, 0, 121260, 73781, 70365, 0, 68039, 70446, 10057, 0, 0, 0, 101219, 120963, 101220, 2307, 0, 0, 0, 0, 73873, 0, 94035, 0, 0, 67469, 0, 129983, 7327, 0, 0, 440, 0, 0, 68613, 75059, 0, 0, 9957, 0, 0, 8046, 0, 119158, 0, 0, 68609, 0, 129405, 1521, 129460, 92256, @@ -28625,9 +28818,9 @@ static const unsigned int code_hash[] = { 120458, 5647, 120473, 7387, 0, 92675, 11477, 5646, 0, 11018, 0, 0, 0, 0, 0, 0, 69280, 128459, 126128, 5651, 0, 0, 0, 5648, 0, 120920, 0, 127517, 3545, 0, 6984, 0, 0, 0, 69414, 126613, 0, 10123, 0, 69274, 0, 0, 65020, - 74885, 119166, 0, 0, 0, 0, 0, 1140, 78426, 0, 0, 0, 0, 8128, 9889, 0, 0, - 1815, 0, 890, 0, 3267, 0, 0, 0, 983686, 4410, 125081, 10576, 8102, 0, - 580, 74232, 0, 0, 0, 0, 0, 19938, 0, 0, 0, 0, 3298, 6546, 0, 0, 0, 0, + 74885, 119166, 0, 0, 0, 0, 0, 1140, 78426, 0, 0, 0, 122665, 8128, 9889, + 0, 0, 1815, 0, 890, 0, 3267, 0, 0, 0, 983686, 4410, 125081, 10576, 8102, + 0, 580, 74232, 0, 0, 0, 0, 0, 19938, 0, 0, 0, 0, 3298, 6546, 0, 0, 0, 0, 6134, 41246, 0, 0, 0, 917770, 0, 6264, 0, 0, 0, 0, 0, 0, 69445, 0, 0, 0, 92697, 11915, 10377, 0, 10072, 0, 0, 2329, 0, 0, 0, 0, 0, 0, 0, 67498, 0, 101164, 0, 11201, 92708, 74769, 0, 13263, 0, 0, 92404, 126066, 69491, 0, @@ -28637,12 +28830,12 @@ static const unsigned int code_hash[] = { 11829, 68197, 0, 0, 11475, 70329, 3020, 42264, 0, 0, 0, 7098, 0, 0, 127967, 957, 42696, 0, 3016, 0, 0, 0, 0, 0, 121248, 92510, 3006, 4620, 0, 0, 0, 0, 129369, 129425, 0, 0, 0, 126246, 8626, 0, 128824, 0, 65377, 0, - 983102, 42920, 1698, 0, 64477, 0, 0, 43813, 100432, 100431, 100434, + 983103, 42920, 1698, 0, 64477, 0, 0, 43813, 100432, 100431, 100434, 100433, 100436, 70321, 100438, 100437, 100440, 100439, 0, 121024, 101177, 70327, 100441, 55252, 100443, 100442, 100445, 100444, 66641, 100446, 100449, 100448, 0, 100450, 113820, 74866, 64375, 0, 127850, 129477, 0, 0, 0, 0, 983799, 0, 0, 120827, 0, 0, 123637, 0, 0, 0, 101183, 8110, 100421, - 0, 100423, 5830, 100425, 100424, 100427, 100426, 100429, 100428, 42389, + 0, 100423, 5830, 100425, 100424, 100427, 73540, 100429, 100428, 42389, 78611, 121398, 0, 0, 0, 0, 0, 0, 0, 83342, 983954, 0, 127147, 119187, 2135, 11836, 0, 0, 78869, 42313, 5579, 0, 70384, 983082, 94002, 0, 5578, 11840, 73006, 42023, 69849, 5669, 92559, 0, 0, 68833, 917845, 128275, @@ -28678,75 +28871,76 @@ static const unsigned int code_hash[] = { 118626, 0, 0, 113710, 0, 73449, 68069, 0, 70332, 0, 5659, 0, 0, 66729, 5655, 0, 0, 0, 68806, 0, 128225, 66310, 73444, 0, 0, 70362, 0, 11609, 0, 126990, 92949, 10272, 10304, 10368, 74511, 594, 10244, 10248, 10256, - 983918, 0, 0, 3467, 41010, 0, 3331, 946, 0, 1495, 13184, 74330, 128242, - 9562, 0, 123175, 0, 70036, 0, 0, 0, 123176, 0, 0, 0, 5666, 65227, 123174, - 68419, 0, 11796, 123178, 0, 0, 10186, 123172, 7732, 983755, 0, 0, 0, - 5668, 83334, 0, 74645, 5670, 0, 0, 12741, 126619, 123638, 5667, 19952, - 120807, 113766, 12749, 0, 67757, 2263, 0, 0, 119260, 129131, 9286, 83335, - 128457, 83336, 70359, 0, 3571, 13247, 5874, 78279, 73447, 68435, 78278, - 78267, 78268, 0, 78265, 553, 113768, 0, 93053, 5829, 0, 4587, 78285, - 78299, 129699, 12746, 0, 70338, 0, 5633, 0, 94101, 94102, 94099, 94100, - 94105, 74856, 94103, 12742, 0, 983837, 0, 0, 0, 70330, 0, 983830, 0, 0, - 0, 12148, 0, 0, 0, 0, 0, 64938, 67234, 5634, 0, 0, 2146, 0, 118880, 2425, - 65182, 983832, 43636, 0, 83326, 328, 0, 68736, 0, 5636, 123163, 5329, 0, - 5638, 0, 7940, 0, 43223, 43760, 5635, 3373, 72424, 78292, 74223, 73441, - 68763, 78287, 9833, 0, 74208, 41635, 0, 77775, 43040, 78297, 68778, - 78295, 5639, 65603, 5660, 5640, 78303, 0, 78300, 0, 68301, 0, 0, 78312, - 0, 78310, 41625, 78308, 78309, 100731, 41780, 5642, 100732, 100735, - 100734, 4356, 100736, 100739, 12051, 70166, 100740, 5641, 8259, 0, 0, 0, - 119570, 0, 0, 121264, 983558, 0, 0, 0, 73890, 0, 0, 2800, 11220, 5645, - 64964, 8652, 83323, 0, 0, 121356, 5608, 128281, 119932, 118562, 0, 0, - 9000, 0, 83324, 92673, 129176, 0, 5613, 74267, 100721, 100724, 5610, - 100726, 92965, 100728, 5612, 100730, 10787, 0, 3615, 123647, 5609, 78316, - 78317, 78313, 78315, 5875, 5808, 0, 8186, 0, 74269, 0, 70004, 65874, - 72422, 5807, 0, 66320, 5306, 12936, 0, 92970, 127961, 0, 92583, 10211, 0, - 0, 78871, 121063, 0, 129512, 0, 0, 0, 0, 0, 74237, 0, 9133, 74262, 0, - 92840, 0, 64779, 4672, 0, 6185, 64776, 0, 121266, 6499, 0, 0, 0, 92720, - 0, 67494, 93791, 2534, 0, 93768, 93778, 93762, 71849, 71869, 93781, - 64583, 93761, 93780, 93760, 93787, 92443, 128714, 71848, 93774, 66411, - 93785, 71841, 93770, 93769, 0, 0, 0, 121168, 68443, 69774, 931, 0, - 125052, 6363, 2748, 0, 0, 0, 983603, 44011, 0, 0, 100711, 119009, 100713, - 100712, 100715, 65896, 100717, 78298, 100719, 100718, 128836, 100720, - 11649, 0, 0, 0, 0, 0, 42341, 65284, 0, 0, 12884, 0, 7907, 127255, 0, 0, - 0, 0, 68779, 0, 68786, 0, 100691, 0, 100693, 100692, 42851, 100694, - 100697, 100696, 92276, 78226, 66393, 100700, 0, 93773, 93776, 93777, - 100702, 78301, 100704, 100703, 42415, 78307, 4542, 69909, 94022, 100709, - 0, 0, 0, 0, 42454, 11565, 7949, 124939, 0, 0, 42494, 3073, 0, 0, 42302, - 0, 126553, 70810, 0, 72401, 0, 0, 0, 129319, 4877, 100681, 100684, - 100683, 10548, 100685, 100688, 100687, 100690, 64798, 70805, 5346, 0, - 126570, 0, 4874, 0, 0, 0, 0, 0, 65884, 0, 0, 0, 11378, 0, 42785, 0, 3251, - 11203, 0, 0, 0, 69568, 11052, 0, 5342, 8317, 0, 0, 5340, 0, 0, 128599, 0, - 129538, 0, 128395, 0, 128510, 0, 0, 9142, 0, 0, 0, 10938, 0, 0, 1182, - 127381, 4829, 0, 0, 72438, 529, 0, 0, 0, 10586, 10790, 10839, 121427, - 41593, 100669, 0, 0, 41594, 225, 66418, 0, 0, 983969, 11376, 0, 41596, 0, - 64975, 0, 0, 11084, 3194, 0, 78306, 78305, 0, 0, 0, 11324, 0, 0, 8420, - 127756, 128844, 0, 41338, 129683, 11485, 0, 41322, 66605, 100671, 0, - 100673, 100672, 100675, 5161, 41330, 100676, 100679, 100678, 100659, - 100658, 0, 100660, 0, 100485, 12361, 0, 12359, 983559, 41369, 66412, - 12191, 0, 0, 0, 0, 78221, 41376, 0, 9870, 0, 41385, 65824, 100651, 11938, - 100653, 100652, 100655, 100654, 42678, 100656, 0, 64649, 0, 0, 0, 0, 0, - 983967, 100662, 100661, 100664, 66334, 100666, 70280, 832, 100667, 2240, - 78473, 66007, 78471, 65703, 0, 0, 0, 12357, 0, 41395, 0, 0, 0, 0, 0, 0, - 983463, 0, 41114, 65466, 0, 983844, 6024, 0, 9979, 0, 0, 0, 0, 0, 0, 0, - 4285, 0, 0, 4230, 0, 7367, 0, 92353, 7563, 42376, 0, 128532, 0, 0, 0, 0, - 67500, 0, 78466, 0, 12208, 128138, 0, 66311, 71309, 0, 41130, 78286, 0, - 0, 70047, 0, 6022, 0, 0, 0, 0, 0, 41125, 0, 66453, 0, 41107, 0, 41121, - 5300, 129588, 0, 0, 0, 74801, 70855, 2074, 73456, 0, 0, 12453, 0, 0, 0, - 0, 68159, 12457, 0, 0, 66278, 0, 0, 0, 0, 0, 66637, 12455, 0, 128473, 0, - 12449, 0, 71224, 0, 0, 66908, 0, 10165, 0, 119249, 113715, 0, 128223, 0, - 0, 0, 0, 4993, 0, 6168, 74033, 4995, 0, 69459, 77756, 4639, 0, 72223, 0, - 0, 0, 0, 0, 0, 66991, 0, 0, 0, 0, 0, 0, 83310, 0, 0, 0, 0, 0, 0, 0, 0, - 129594, 4953, 0, 0, 0, 0, 83311, 0, 73453, 65688, 0, 10125, 3517, 0, 0, - 0, 65094, 74791, 78262, 10627, 66333, 78256, 78257, 83304, 78253, 0, - 71317, 64923, 0, 65208, 10608, 78263, 78264, 0, 0, 0, 65883, 0, 0, 74914, - 0, 0, 6853, 0, 0, 12912, 119012, 0, 128191, 0, 0, 129586, 0, 1290, 0, 0, - 0, 0, 113719, 71442, 0, 0, 8978, 0, 119135, 120979, 10527, 71079, 0, 0, - 0, 0, 0, 0, 5336, 0, 0, 6934, 0, 10780, 0, 0, 78767, 0, 0, 0, 347, 0, 0, - 78775, 64675, 41582, 78774, 78771, 68094, 74903, 78769, 69221, 69657, 0, - 0, 11153, 120981, 78526, 0, 0, 0, 0, 41584, 0, 69464, 0, 0, 0, 0, 43510, + 983918, 122974, 0, 3467, 41010, 0, 3331, 946, 0, 1495, 13184, 74330, + 128242, 9562, 0, 123175, 0, 70036, 122976, 0, 0, 123176, 0, 0, 0, 5666, + 65227, 123174, 68419, 0, 11796, 123178, 0, 0, 10186, 123172, 7732, + 983755, 0, 0, 0, 5668, 83334, 0, 74645, 5670, 0, 0, 12741, 126619, + 123638, 5667, 19952, 120807, 113766, 12749, 0, 67757, 2263, 0, 0, 119260, + 129131, 9286, 83335, 128457, 83336, 70359, 0, 3571, 13247, 5874, 78279, + 73447, 68435, 78278, 78267, 78268, 0, 78265, 553, 113768, 0, 93053, 5829, + 0, 4587, 78285, 78299, 129699, 12746, 0, 70338, 0, 5633, 0, 94101, 94102, + 94099, 94100, 94105, 74856, 94103, 12742, 0, 983837, 0, 0, 0, 70330, 0, + 983830, 0, 0, 0, 12148, 0, 0, 0, 0, 0, 64938, 67234, 5634, 0, 0, 2146, 0, + 118880, 2425, 65182, 983832, 43636, 0, 83326, 328, 0, 68736, 0, 5636, + 123163, 5329, 0, 5638, 0, 7940, 0, 43223, 43760, 5635, 3373, 72424, + 78292, 74223, 73441, 68763, 78287, 9833, 0, 74208, 41635, 0, 77775, + 43040, 78297, 68778, 78295, 5639, 65603, 5660, 5640, 78303, 0, 78300, 0, + 68301, 0, 0, 78312, 0, 78310, 41625, 78308, 78309, 100731, 41780, 5642, + 100732, 100735, 100734, 4356, 100736, 100739, 12051, 70166, 100740, 5641, + 8259, 0, 0, 0, 119570, 0, 0, 121264, 983558, 0, 0, 0, 73890, 0, 0, 2800, + 11220, 5645, 64964, 8652, 83323, 0, 0, 121356, 5608, 128281, 119932, + 118562, 0, 0, 9000, 0, 83324, 92673, 129176, 0, 5613, 74267, 100721, + 100724, 5610, 100726, 92965, 100728, 5612, 100730, 10787, 0, 3615, + 123647, 5609, 78316, 78317, 78313, 78315, 5875, 5808, 0, 8186, 0, 74269, + 122977, 70004, 65874, 72422, 5807, 0, 66320, 5306, 12936, 0, 92970, + 127961, 0, 92583, 10211, 0, 0, 78871, 121063, 0, 129512, 0, 0, 0, 0, 0, + 74237, 0, 9133, 74262, 0, 92840, 0, 64779, 4672, 73529, 6185, 64776, 0, + 121266, 6499, 0, 0, 0, 92720, 0, 67494, 93791, 2534, 0, 93768, 93778, + 93762, 71849, 71869, 93781, 64583, 93761, 93780, 78922, 93787, 92443, + 128714, 71848, 93774, 66411, 93785, 71841, 93770, 93769, 0, 0, 0, 121168, + 68443, 69774, 931, 0, 125052, 6363, 2748, 0, 0, 0, 983603, 44011, 0, 0, + 100711, 119009, 100713, 100712, 100715, 65896, 100717, 78298, 100719, + 100718, 128836, 100720, 11649, 0, 0, 0, 0, 0, 42341, 65284, 0, 0, 12884, + 0, 7907, 127255, 0, 0, 0, 0, 68779, 0, 68786, 0, 100691, 0, 100693, + 100692, 42851, 100694, 100697, 100696, 92276, 78226, 66393, 100700, 0, + 93773, 93776, 93777, 100702, 78301, 100704, 100703, 42415, 78307, 4542, + 69909, 94022, 100709, 0, 0, 0, 0, 42454, 11565, 7949, 124939, 0, 0, + 42494, 3073, 0, 0, 42302, 0, 126553, 70810, 0, 72401, 0, 0, 0, 129319, + 4877, 100681, 100684, 100683, 10548, 100685, 100688, 100687, 100690, + 64798, 70805, 5346, 0, 126570, 124135, 4874, 124136, 0, 0, 0, 0, 65884, + 0, 0, 0, 11378, 0, 42785, 0, 3251, 11203, 0, 0, 0, 69568, 11052, 0, 5342, + 8317, 0, 0, 5340, 0, 122970, 128599, 0, 129538, 0, 128395, 0, 128510, 0, + 0, 9142, 0, 0, 0, 10938, 0, 0, 1182, 127381, 4829, 0, 0, 72438, 529, 0, + 0, 0, 10586, 10790, 10839, 121427, 41593, 100669, 0, 118532, 41594, 225, + 66418, 0, 0, 983969, 11376, 0, 41596, 0, 64975, 0, 0, 11084, 3194, 0, + 78306, 78305, 0, 0, 0, 11324, 0, 0, 8420, 127756, 128844, 0, 41338, + 129683, 11485, 0, 41322, 66605, 100671, 0, 100673, 100672, 100675, 5161, + 41330, 100676, 100679, 100678, 100659, 100658, 0, 100660, 0, 100485, + 12361, 0, 12359, 983559, 41369, 66412, 12191, 0, 0, 0, 0, 78221, 41376, + 0, 9870, 0, 41385, 65824, 100651, 11938, 100653, 100652, 100655, 100654, + 42678, 100656, 0, 64649, 0, 0, 0, 0, 0, 983967, 100662, 100661, 100664, + 66334, 100666, 70280, 832, 100667, 2240, 78473, 66007, 78471, 65703, 0, + 0, 0, 12357, 0, 41395, 0, 0, 0, 0, 0, 0, 983466, 0, 41114, 65466, 0, + 983844, 6024, 0, 9979, 0, 0, 0, 0, 0, 0, 0, 4285, 0, 0, 4230, 0, 7367, 0, + 92353, 7563, 42376, 0, 128532, 0, 0, 0, 0, 67500, 0, 78466, 0, 12208, + 128138, 0, 66311, 71309, 0, 41130, 78286, 0, 0, 70047, 0, 6022, 0, 0, 0, + 0, 0, 41125, 0, 66453, 0, 41107, 0, 41121, 5300, 129588, 0, 0, 128759, + 74801, 70855, 2074, 73456, 0, 0, 12453, 0, 0, 0, 0, 68159, 12457, 0, 0, + 66278, 0, 0, 0, 0, 0, 66637, 12455, 0, 128473, 0, 12449, 0, 71224, 0, 0, + 66908, 0, 10165, 0, 119249, 113715, 0, 128223, 0, 0, 0, 0, 4993, 0, 6168, + 74033, 4995, 0, 69459, 77756, 4639, 0, 72223, 0, 73478, 0, 0, 0, 73486, + 66991, 0, 0, 0, 0, 0, 0, 83310, 0, 0, 0, 0, 0, 0, 0, 0, 129594, 4953, 0, + 0, 0, 0, 83311, 0, 73453, 65688, 0, 10125, 3517, 0, 0, 0, 65094, 74791, + 78262, 10627, 66333, 78256, 78257, 83304, 78253, 0, 71317, 64923, 0, + 65208, 10608, 78263, 78264, 0, 0, 0, 65883, 0, 0, 74914, 0, 0, 6853, 0, + 0, 12912, 119012, 0, 128191, 0, 0, 129586, 0, 1290, 0, 0, 0, 0, 113719, + 71442, 0, 0, 8978, 0, 119135, 120979, 10527, 71079, 0, 0, 0, 0, 0, 0, + 5336, 0, 0, 6934, 0, 10780, 0, 0, 78767, 0, 0, 0, 347, 0, 0, 78775, + 64675, 41582, 78774, 78771, 68094, 74903, 78769, 69221, 69657, 0, 0, + 11153, 120981, 78526, 0, 0, 0, 0, 41584, 0, 69464, 0, 0, 0, 0, 43510, 66661, 0, 66306, 78791, 66384, 0, 6609, 0, 0, 11319, 0, 66984, 0, 41730, 0, 0, 127920, 0, 65172, 41728, 41721, 0, 0, 0, 41203, 0, 0, 41726, 0, 0, - 5758, 0, 0, 41140, 2028, 78092, 0, 0, 0, 92739, 983195, 41138, 0, 0, 0, + 5758, 0, 0, 41140, 2028, 78092, 0, 0, 0, 92739, 983196, 41138, 0, 0, 0, 125082, 1115, 127060, 9794, 127062, 67671, 92238, 12237, 78787, 66314, 78785, 9290, 73668, 78783, 78780, 66985, 127144, 7926, 0, 0, 0, 64398, 100924, 71274, 12311, 101268, 78796, 78798, 78794, 78795, 78792, 78793, @@ -28760,113 +28954,114 @@ static const unsigned int code_hash[] = { 66511, 68066, 2637, 110685, 8460, 110683, 8476, 110681, 0, 110679, 0, 127919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5412, 66243, 9935, 122892, 0, 73864, 41734, 8206, 74081, 0, 3286, 120730, 0, 0, 41732, 0, 41736, - 983201, 41731, 0, 0, 70842, 0, 0, 0, 0, 129329, 0, 66853, 0, 0, 78742, + 983203, 41731, 0, 0, 70842, 0, 0, 0, 0, 129329, 0, 66853, 0, 0, 78742, 72755, 11277, 65892, 0, 10620, 92272, 68165, 0, 0, 0, 73942, 67001, 100479, 0, 119093, 3459, 0, 129398, 0, 0, 72130, 92512, 0, 66377, 69781, 128718, 0, 111304, 3161, 69981, 0, 0, 0, 0, 0, 9016, 78153, 0, 0, 43641, 0, 121018, 0, 101279, 0, 0, 0, 0, 0, 68342, 120950, 94043, 0, 12332, 121310, 6086, 41722, 0, 120709, 0, 0, 111305, 118677, 0, 128307, 74288, - 0, 74546, 0, 129178, 129399, 92224, 42460, 0, 0, 0, 0, 120941, 42421, 0, - 41723, 110606, 64358, 11460, 983508, 0, 64718, 120838, 66869, 0, 42348, - 0, 6752, 452, 42500, 0, 128258, 0, 42308, 0, 0, 0, 12932, 0, 69968, - 42950, 66827, 917582, 0, 0, 8302, 0, 66929, 0, 0, 7250, 13214, 10041, - 8105, 65568, 127780, 69969, 127759, 0, 0, 121467, 0, 121466, 41384, 0, - 69878, 0, 5538, 9987, 111298, 118932, 129307, 0, 552, 0, 7357, 10785, - 66995, 0, 4557, 0, 0, 10171, 68320, 0, 5540, 0, 0, 281, 0, 0, 42622, 0, - 5536, 0, 0, 1388, 0, 0, 10504, 0, 0, 11531, 74324, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3663, 0, 121081, 70335, 74859, 0, 5334, 0, 110738, 72319, 0, - 11305, 66997, 68456, 0, 66611, 0, 19907, 64363, 3478, 7583, 7679, 74154, - 0, 0, 1158, 0, 983890, 73748, 0, 0, 1915, 4846, 0, 120132, 118984, - 120134, 120129, 120128, 805, 120130, 64438, 120124, 8760, 120126, 72137, - 120120, 120123, 94003, 0, 0, 0, 0, 0, 12225, 0, 0, 0, 70173, 75045, 0, - 129515, 8083, 0, 0, 0, 111094, 92626, 0, 0, 0, 0, 0, 0, 110837, 0, 67699, - 560, 5643, 0, 0, 0, 0, 0, 0, 0, 120144, 0, 120661, 78304, 1597, 120143, - 120142, 206, 70126, 120139, 120138, 8168, 0, 73086, 0, 0, 0, 118650, - 125036, 0, 0, 3546, 42573, 66811, 67000, 0, 128397, 8400, 0, 0, 0, 0, 0, - 7903, 9287, 72791, 0, 0, 0, 0, 72134, 66603, 1695, 917861, 0, 0, 111101, - 0, 0, 0, 0, 0, 0, 0, 111099, 0, 111098, 4754, 0, 69222, 128229, 0, 0, - 7354, 7408, 0, 0, 121181, 0, 0, 0, 12739, 0, 1278, 4187, 0, 42119, 42120, - 0, 121158, 0, 12467, 0, 68902, 0, 12463, 0, 0, 118827, 0, 9664, 70834, - 74475, 0, 0, 0, 0, 0, 3661, 0, 0, 9022, 127955, 0, 101460, 126257, 0, - 6118, 222, 126250, 3884, 0, 74151, 0, 6502, 0, 11085, 121261, 0, 0, 0, 0, - 0, 0, 0, 0, 12461, 0, 0, 0, 94059, 11254, 10860, 64880, 0, 64685, 0, 0, - 94087, 7776, 11219, 0, 0, 121339, 69730, 801, 43165, 0, 78212, 0, 0, - 13277, 0, 12951, 0, 9906, 5486, 2334, 128672, 67680, 5483, 73732, 120884, - 119128, 2256, 0, 127876, 2539, 0, 78507, 5485, 69826, 42697, 0, 0, - 113689, 4502, 68057, 253, 73672, 0, 0, 9203, 0, 0, 0, 0, 0, 121242, - 11127, 0, 0, 0, 13257, 0, 0, 0, 69645, 0, 0, 0, 70431, 0, 5693, 64470, 0, - 66610, 67678, 0, 983678, 0, 0, 0, 0, 0, 0, 0, 94078, 0, 0, 66608, 3111, - 0, 8804, 66607, 0, 0, 0, 66606, 0, 0, 0, 1436, 0, 55226, 0, 111287, 7393, - 41592, 0, 0, 1598, 78101, 0, 0, 65193, 4423, 0, 113692, 10515, 41589, 0, - 0, 0, 101485, 1430, 101486, 0, 120606, 0, 66223, 7619, 3255, 128280, - 74032, 11549, 10735, 93038, 100741, 6801, 100743, 100746, 2148, 100748, - 100747, 100750, 100749, 0, 121229, 101479, 69243, 41724, 67716, 69669, - 41690, 111269, 983666, 8380, 100355, 983849, 0, 101480, 0, 0, 0, 0, 6333, - 111264, 42315, 0, 129502, 111265, 0, 0, 5339, 74323, 0, 13004, 0, 0, 0, - 0, 0, 0, 5684, 0, 0, 0, 5689, 0, 0, 68464, 12633, 12870, 0, 65183, 5688, - 0, 0, 6310, 5686, 0, 0, 0, 120647, 70046, 50, 94095, 9871, 0, 0, 121446, - 0, 0, 0, 66905, 0, 4448, 0, 121406, 113734, 72125, 1321, 0, 10640, 0, 0, - 101497, 0, 0, 118532, 0, 0, 0, 0, 0, 12501, 0, 0, 0, 0, 8812, 0, 69986, - 8673, 0, 129024, 0, 0, 2105, 72101, 72712, 0, 129929, 0, 0, 0, 4636, - 55262, 77745, 4515, 2382, 0, 0, 7313, 101477, 0, 0, 194626, 0, 0, 0, 0, - 0, 0, 0, 10197, 194719, 0, 0, 0, 194718, 0, 0, 0, 64189, 0, 1873, 0, 0, - 0, 0, 0, 983682, 0, 0, 101499, 72282, 126991, 71113, 0, 0, 129340, 9489, - 0, 70843, 0, 0, 0, 0, 128030, 13295, 43191, 0, 0, 1154, 0, 1205, 0, 0, 0, - 12958, 0, 0, 0, 66968, 0, 10592, 0, 495, 0, 41712, 7983, 0, 0, 0, 6347, - 69465, 7654, 41710, 4196, 0, 0, 41709, 73772, 70832, 0, 9465, 983783, 0, - 0, 917612, 0, 72374, 41714, 0, 0, 0, 6343, 72376, 0, 43996, 0, 8044, - 66979, 0, 41789, 0, 10809, 71953, 0, 0, 0, 8146, 11025, 0, 120513, 642, - 0, 0, 0, 12875, 0, 0, 13229, 71950, 41788, 0, 92835, 0, 41791, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 8428, 6569, 92851, 0, 0, 0, 10167, 0, 68248, 8049, - 0, 0, 0, 0, 128882, 4761, 0, 4766, 64623, 0, 121180, 194653, 118876, 0, - 6912, 9232, 7033, 0, 0, 41545, 0, 71970, 72160, 72107, 0, 0, 0, 3484, 0, - 0, 0, 8503, 41539, 41527, 0, 0, 983842, 0, 0, 66983, 41537, 0, 41541, - 8282, 11817, 129965, 128219, 0, 0, 126132, 0, 0, 70115, 66609, 111235, - 65921, 0, 0, 194664, 0, 129326, 77970, 42246, 75030, 120605, 0, 65926, - 7744, 68859, 94056, 74277, 126108, 0, 6966, 194633, 8136, 0, 0, 0, 0, 0, - 4762, 0, 0, 0, 4765, 69443, 983585, 66970, 4760, 0, 0, 10871, 43199, - 194645, 0, 93955, 0, 0, 11546, 0, 337, 0, 0, 0, 12279, 7768, 0, 128352, - 0, 69812, 10143, 7883, 121444, 7880, 64618, 13012, 5704, 13010, 0, 0, - 119531, 0, 0, 0, 0, 66654, 0, 0, 0, 13008, 0, 4385, 0, 13011, 0, 92569, - 66972, 13009, 74771, 70159, 0, 0, 41793, 64450, 74221, 120996, 41792, - 111242, 94054, 126094, 0, 111244, 5709, 120689, 71076, 0, 0, 0, 0, 0, - 5708, 0, 0, 0, 5706, 66362, 5705, 8791, 41797, 0, 10237, 66436, 0, 66974, - 0, 0, 128083, 13170, 0, 127075, 0, 0, 41377, 0, 0, 10058, 120735, 101431, - 0, 0, 0, 0, 0, 0, 129641, 119525, 0, 0, 72350, 0, 983584, 2144, 0, - 120765, 0, 0, 1754, 92226, 13246, 864, 0, 118926, 8972, 0, 7849, 0, 0, - 13240, 0, 5192, 0, 0, 10948, 0, 13199, 0, 1236, 13208, 13261, 13189, - 13188, 93993, 0, 7440, 66976, 0, 0, 1844, 125229, 0, 13178, 0, 0, 0, - 125230, 0, 0, 13260, 4550, 121249, 125227, 0, 71071, 0, 0, 68523, 0, 0, - 11354, 94071, 0, 42795, 129317, 0, 0, 0, 125237, 0, 13194, 13274, 0, 0, - 129533, 65586, 68311, 0, 119193, 4601, 194661, 101454, 194658, 0, 194659, - 0, 121422, 128790, 194657, 41717, 67402, 101444, 121129, 41716, 127376, - 7910, 0, 0, 754, 41944, 0, 8183, 120741, 2037, 101440, 0, 101441, 125, 0, - 0, 0, 983124, 101442, 41719, 0, 7990, 12637, 13258, 9536, 71056, 0, 4427, - 0, 71200, 0, 12217, 0, 41532, 129315, 0, 0, 0, 0, 111063, 83349, 0, 0, - 120622, 0, 0, 0, 0, 43632, 0, 0, 8140, 0, 6260, 0, 0, 66765, 129657, 0, - 3898, 0, 0, 13200, 0, 0, 66582, 0, 0, 0, 0, 1068, 71178, 13259, 12945, 0, - 42203, 0, 3124, 69411, 0, 4386, 12224, 6973, 129563, 0, 0, 119535, 0, - 121312, 0, 12232, 0, 0, 5681, 64578, 75023, 72016, 13209, 0, 0, 0, 0, 0, - 11053, 0, 74902, 128107, 128942, 7588, 0, 1693, 74942, 43204, 65831, 0, - 0, 0, 68803, 111216, 111223, 0, 0, 65685, 9523, 2243, 0, 0, 0, 0, 0, 0, - 0, 0, 13191, 0, 3500, 3139, 100643, 3170, 100645, 100644, 66934, 100646, - 13006, 64433, 0, 100650, 941, 0, 0, 120967, 3727, 0, 0, 0, 72378, 0, 0, - 118611, 94039, 129299, 92455, 0, 0, 64444, 0, 0, 43603, 94075, 65397, - 288, 0, 0, 0, 10025, 73692, 0, 0, 68182, 0, 0, 0, 92438, 65395, 0, 0, 0, - 65393, 83078, 121111, 0, 0, 0, 0, 0, 65394, 11548, 72305, 0, 65396, 0, 0, - 13256, 1282, 0, 0, 0, 111085, 0, 0, 0, 111087, 72115, 0, 0, 0, 0, 0, - 3304, 0, 0, 0, 126595, 72437, 68353, 0, 0, 42113, 0, 0, 0, 0, 0, 43094, - 0, 0, 94037, 68317, 9035, 0, 0, 0, 0, 0, 70822, 128467, 164, 68309, - 94067, 94000, 100631, 100634, 100633, 100636, 100635, 100638, 100637, - 68808, 100639, 110665, 73893, 11099, 110664, 13175, 13207, 0, 127552, 0, - 74643, 5929, 0, 0, 129192, 983654, 11306, 0, 119059, 3180, 125102, 0, 0, - 0, 13062, 0, 129551, 128707, 0, 0, 74428, 0, 128000, 0, 11251, 70204, 0, - 10045, 0, 13275, 0, 11057, 0, 13276, 125133, 41525, 983084, 128015, - 11444, 0, 129158, 0, 122642, 41523, 127765, 0, 0, 0, 0, 0, 0, 0, 3858, 0, - 119573, 0, 0, 0, 0, 0, 0, 101014, 369, 74908, 41784, 0, 120994, 0, 71180, - 0, 0, 13210, 41782, 0, 0, 101388, 41781, 10486, 74058, 43002, 0, 0, 0, 0, + 0, 74546, 124123, 129178, 124125, 92224, 42460, 0, 0, 0, 0, 120941, + 42421, 0, 41723, 110606, 64358, 11460, 983511, 0, 64718, 120838, 66869, + 0, 42348, 0, 6752, 452, 42500, 0, 128258, 0, 42308, 0, 0, 0, 12932, 0, + 69968, 42950, 66827, 917582, 0, 0, 8302, 0, 66929, 0, 0, 7250, 13214, + 10041, 8105, 65568, 127780, 69969, 127759, 0, 0, 121467, 0, 121466, + 41384, 0, 69878, 0, 5538, 9987, 111298, 118932, 129307, 0, 552, 0, 7357, + 10785, 66995, 0, 4557, 0, 0, 10171, 68320, 0, 5540, 0, 0, 281, 0, 0, + 42622, 0, 5536, 0, 0, 1388, 0, 0, 10504, 0, 0, 11531, 74324, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3663, 0, 121081, 70335, 74859, 0, 5334, 0, 110738, + 72319, 0, 11305, 66997, 68456, 0, 66611, 0, 19907, 64363, 3478, 7583, + 7679, 74154, 0, 0, 1158, 0, 983890, 73748, 0, 0, 1915, 4846, 0, 120132, + 118984, 120134, 120129, 120128, 805, 120130, 64438, 120124, 8760, 120126, + 72137, 120120, 120123, 94003, 0, 0, 0, 0, 0, 12225, 0, 0, 0, 70173, + 75045, 0, 129515, 8083, 0, 0, 0, 111094, 92626, 0, 0, 0, 0, 0, 0, 110837, + 0, 67699, 560, 5643, 0, 0, 0, 0, 0, 0, 0, 120144, 0, 120661, 78304, 1597, + 120143, 120142, 206, 70126, 120139, 120138, 8168, 0, 73086, 0, 0, 0, + 118650, 125036, 0, 0, 3546, 42573, 66811, 67000, 0, 128397, 8400, 0, 0, + 0, 0, 0, 7903, 9287, 72791, 0, 0, 0, 0, 72134, 66603, 1695, 917861, + 124150, 0, 111101, 0, 0, 0, 0, 0, 0, 0, 111099, 0, 111098, 4754, 0, + 69222, 128229, 0, 0, 7354, 7408, 0, 0, 121181, 0, 0, 0, 12739, 0, 1278, + 4187, 0, 42119, 42120, 0, 121158, 0, 12467, 0, 68902, 0, 12463, 0, 0, + 118827, 0, 9664, 70834, 74475, 0, 0, 0, 0, 0, 3661, 0, 0, 9022, 127955, + 0, 101460, 126257, 0, 6118, 222, 126250, 3884, 0, 74151, 0, 6502, 0, + 11085, 121261, 0, 0, 0, 0, 0, 0, 0, 0, 12461, 0, 0, 0, 94059, 11254, + 10860, 64880, 0, 64685, 0, 0, 94087, 7776, 11219, 0, 0, 121339, 69730, + 801, 43165, 0, 78212, 0, 0, 13277, 0, 12951, 0, 9906, 5486, 2334, 128672, + 67680, 5483, 73732, 120884, 119128, 2256, 0, 127876, 2539, 0, 78507, + 5485, 69826, 42697, 0, 0, 113689, 4502, 68057, 253, 73672, 0, 0, 9203, 0, + 0, 0, 0, 0, 121242, 11127, 0, 0, 0, 13257, 0, 0, 0, 69645, 0, 0, 0, + 70431, 0, 5693, 64470, 0, 66610, 67678, 0, 983678, 0, 0, 0, 0, 0, 0, 0, + 94078, 0, 0, 66608, 3111, 0, 8804, 66607, 0, 0, 0, 66606, 0, 0, 0, 1436, + 0, 55226, 0, 111287, 7393, 41592, 0, 0, 1598, 78101, 0, 0, 65193, 4423, + 0, 113692, 10515, 41589, 0, 0, 0, 101485, 1430, 101486, 0, 120606, 0, + 66223, 7619, 3255, 128280, 74032, 11549, 10735, 93038, 100741, 6801, + 100743, 100746, 2148, 100748, 100747, 100750, 100749, 0, 121229, 101479, + 69243, 41724, 67716, 69669, 41690, 111269, 983666, 8380, 100355, 983849, + 0, 101480, 0, 0, 0, 0, 6333, 111264, 42315, 0, 129502, 111265, 0, 0, + 5339, 74323, 0, 13004, 0, 0, 0, 0, 0, 0, 5684, 0, 0, 0, 5689, 0, 0, + 68464, 12633, 12870, 0, 65183, 5688, 0, 0, 6310, 5686, 0, 0, 0, 120647, + 70046, 50, 94095, 9871, 0, 0, 121446, 0, 0, 0, 66905, 0, 4448, 0, 121406, + 113734, 72125, 1321, 0, 10640, 0, 0, 101497, 0, 0, 73542, 0, 0, 0, 0, 0, + 12501, 0, 0, 0, 0, 8812, 0, 69986, 8673, 0, 129024, 0, 0, 2105, 72101, + 72712, 0, 129929, 0, 0, 0, 4636, 55262, 77745, 4515, 2382, 0, 0, 7313, + 101477, 0, 0, 194626, 0, 0, 0, 0, 0, 0, 0, 10197, 194719, 0, 0, 0, + 194718, 0, 0, 0, 64189, 0, 1873, 0, 0, 0, 0, 0, 983682, 0, 0, 101499, + 72282, 126991, 71113, 0, 0, 129340, 9489, 0, 70843, 0, 0, 0, 0, 128030, + 13295, 43191, 0, 0, 1154, 0, 1205, 0, 0, 0, 12958, 0, 0, 0, 66968, 0, + 10592, 0, 495, 0, 41712, 7983, 0, 0, 0, 6347, 69465, 7654, 41710, 4196, + 0, 0, 41709, 73772, 70832, 0, 9465, 983783, 0, 0, 917612, 0, 72374, + 41714, 0, 0, 0, 6343, 72376, 0, 43996, 0, 8044, 66979, 0, 41789, 0, + 10809, 71953, 0, 0, 0, 8146, 11025, 0, 120513, 642, 0, 0, 0, 12875, 0, 0, + 13229, 71950, 41788, 0, 92835, 0, 41791, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8428, 6569, 92851, 0, 0, 0, 10167, 0, 68248, 8049, 0, 0, 0, 0, 128882, + 4761, 0, 4766, 64623, 0, 121180, 194653, 118876, 0, 6912, 9232, 7033, 0, + 0, 41545, 0, 71970, 72160, 72107, 0, 0, 0, 3484, 0, 0, 0, 8503, 41539, + 41527, 0, 0, 983842, 0, 0, 66983, 41537, 0, 41541, 8282, 11817, 129965, + 128219, 0, 0, 126132, 0, 0, 70115, 66609, 111235, 65921, 0, 0, 194664, 0, + 129326, 77970, 42246, 75030, 120605, 0, 65926, 7744, 68859, 94056, 74277, + 126108, 0, 6966, 194633, 8136, 0, 0, 0, 0, 0, 4762, 0, 0, 0, 4765, 69443, + 983585, 66970, 4760, 0, 0, 10871, 43199, 194645, 0, 93955, 0, 0, 11546, + 0, 337, 0, 0, 0, 12279, 7768, 0, 128352, 0, 69812, 10143, 7883, 121444, + 7880, 64618, 13012, 5704, 13010, 0, 0, 119531, 0, 0, 0, 0, 66654, 0, 0, + 0, 13008, 0, 4385, 0, 13011, 0, 92569, 66972, 13009, 74771, 70159, 0, 0, + 41793, 64450, 74221, 120996, 41792, 111242, 94054, 126094, 0, 111244, + 5709, 120689, 71076, 0, 0, 0, 0, 0, 5708, 0, 0, 0, 5706, 66362, 5705, + 8791, 41797, 0, 10237, 66436, 0, 66974, 0, 0, 128083, 13170, 0, 127075, + 0, 0, 41377, 0, 0, 10058, 120735, 101431, 0, 0, 0, 0, 0, 0, 129641, + 119525, 0, 0, 72350, 0, 983584, 2144, 0, 120765, 0, 0, 1754, 92226, + 13246, 864, 0, 118926, 8972, 0, 7849, 0, 0, 13240, 0, 5192, 0, 0, 10948, + 0, 13199, 0, 1236, 13208, 13261, 13189, 13188, 93993, 0, 7440, 66976, 0, + 0, 1844, 125229, 0, 13178, 0, 0, 0, 125230, 0, 0, 13260, 4550, 121249, + 125227, 0, 71071, 0, 0, 68523, 0, 0, 11354, 94071, 0, 42795, 129317, 0, + 0, 0, 125237, 0, 13194, 13274, 0, 0, 129533, 65586, 68311, 0, 119193, + 4601, 194661, 101454, 194658, 0, 194659, 0, 121422, 128790, 194657, + 41717, 67402, 101444, 121129, 41716, 127376, 7910, 0, 0, 754, 41944, 0, + 8183, 120741, 2037, 101440, 0, 101441, 125, 0, 0, 0, 983125, 101442, + 41719, 0, 7990, 12637, 13258, 9536, 71056, 0, 4427, 0, 71200, 0, 12217, + 0, 41532, 129315, 0, 0, 0, 0, 111063, 83349, 0, 0, 120622, 0, 0, 0, 0, + 43632, 0, 0, 8140, 0, 6260, 0, 0, 66765, 129657, 0, 3898, 0, 0, 13200, 0, + 0, 66582, 0, 0, 0, 0, 1068, 71178, 13259, 12945, 0, 42203, 0, 3124, + 69411, 0, 4386, 12224, 6973, 129563, 0, 0, 119535, 0, 121312, 0, 12232, + 0, 0, 5681, 64578, 75023, 72016, 13209, 0, 0, 0, 0, 0, 11053, 0, 74902, + 128107, 128942, 7588, 0, 1693, 74942, 43204, 65831, 124120, 0, 0, 68803, + 111216, 111223, 0, 0, 65685, 9523, 2243, 0, 0, 0, 0, 0, 0, 0, 0, 13191, + 0, 3500, 3139, 100643, 3170, 100645, 100644, 66934, 100646, 13006, 64433, + 0, 100650, 941, 0, 0, 120967, 3727, 0, 0, 0, 72378, 0, 0, 118611, 94039, + 129299, 92455, 0, 0, 64444, 0, 0, 43603, 94075, 65397, 288, 0, 0, 0, + 10025, 73692, 0, 0, 68182, 0, 0, 0, 92438, 65395, 0, 0, 0, 65393, 83078, + 121111, 0, 122666, 0, 0, 0, 65394, 11548, 72305, 0, 65396, 0, 0, 13256, + 1282, 0, 0, 0, 111085, 0, 0, 0, 111087, 72115, 0, 0, 0, 0, 0, 3304, 0, 0, + 0, 126595, 72437, 68353, 0, 0, 42113, 0, 0, 0, 0, 0, 43094, 0, 0, 94037, + 68317, 9035, 0, 0, 0, 0, 0, 70822, 128467, 164, 68309, 94067, 94000, + 100631, 100634, 100633, 100636, 100635, 100638, 100637, 68808, 100639, + 110665, 73893, 11099, 110664, 13175, 13207, 0, 127552, 0, 74643, 5929, 0, + 0, 119502, 983654, 11306, 0, 119059, 3180, 125102, 0, 0, 0, 13062, 0, + 129551, 128707, 0, 0, 74428, 0, 128000, 0, 11251, 70204, 0, 10045, 0, + 13275, 0, 11057, 0, 13276, 125133, 41525, 983084, 128015, 11444, 0, + 129158, 0, 122642, 41523, 127765, 0, 0, 0, 0, 0, 0, 0, 3858, 0, 119573, + 0, 0, 0, 0, 0, 0, 101014, 369, 74908, 41784, 0, 120994, 0, 71180, 0, 0, + 13210, 41782, 0, 73536, 101388, 41781, 10486, 74058, 43002, 0, 0, 0, 0, 0, 3741, 0, 0, 0, 118540, 41222, 0, 128317, 3982, 0, 4388, 126105, 746, - 0, 0, 0, 13131, 0, 0, 0, 0, 0, 10434, 8794, 0, 0, 0, 0, 0, 0, 11700, + 0, 0, 0, 13131, 0, 0, 0, 0, 0, 10434, 8794, 122963, 0, 0, 0, 0, 0, 11700, 4374, 129413, 0, 0, 0, 0, 0, 917597, 0, 69814, 0, 6735, 73979, 13174, 73968, 13225, 0, 69808, 0, 0, 2365, 7841, 71476, 0, 120934, 66510, 128099, 0, 0, 0, 41785, 41171, 0, 13173, 4372, 6854, 0, 0, 0, 128939, 0, @@ -28878,78 +29073,79 @@ static const unsigned int code_hash[] = { 124949, 0, 0, 0, 41533, 66337, 0, 92184, 0, 126091, 0, 0, 73849, 0, 43638, 0, 101398, 6261, 0, 129568, 0, 1957, 0, 0, 0, 13292, 13206, 0, 0, 2925, 73809, 42576, 101395, 13212, 43238, 0, 13190, 13187, 0, 13198, 0, - 0, 5242, 0, 0, 128146, 0, 0, 6770, 43331, 127539, 0, 0, 71074, 126466, 0, - 41444, 0, 0, 64799, 5246, 119106, 13185, 9709, 0, 0, 92751, 0, 5238, 0, - 71085, 0, 5236, 40979, 0, 74201, 8286, 0, 3936, 92833, 11699, 0, 127249, - 13235, 69578, 41248, 127264, 13245, 13239, 0, 7969, 127266, 74832, - 127251, 0, 120509, 0, 983893, 734, 127270, 0, 127254, 70297, 127273, - 64921, 120969, 66631, 41771, 120490, 0, 983171, 41770, 1670, 42560, 0, - 121349, 129634, 0, 41163, 0, 11136, 0, 11506, 0, 42841, 13267, 126109, 0, - 41775, 0, 7130, 41773, 0, 0, 0, 0, 0, 0, 0, 42673, 65572, 0, 65250, - 13265, 13264, 64518, 66798, 6100, 0, 0, 6740, 71080, 67814, 12967, 70028, - 68101, 4583, 0, 0, 68097, 0, 0, 0, 0, 119211, 0, 0, 42653, 83181, 68102, - 0, 7814, 71045, 0, 73702, 0, 0, 0, 9756, 6985, 0, 0, 74219, 0, 0, 129069, - 124987, 5674, 0, 66421, 0, 5677, 5588, 0, 0, 0, 0, 5673, 0, 5676, 0, - 94048, 0, 5672, 6476, 0, 0, 110951, 42511, 1727, 0, 0, 0, 0, 0, 0, 0, - 3550, 736, 0, 4505, 5873, 74090, 5826, 55232, 5813, 0, 120712, 5841, - 5837, 55234, 0, 3105, 64370, 5838, 5796, 0, 119592, 5793, 0, 5866, 5797, - 41011, 5865, 0, 0, 71899, 0, 71235, 5806, 0, 0, 9037, 5671, 0, 0, 0, 0, - 71266, 126616, 7296, 0, 0, 0, 0, 6980, 0, 72108, 0, 0, 0, 0, 0, 64613, - 983910, 0, 129969, 0, 78277, 7114, 0, 72100, 43190, 93842, 128666, 72096, - 42611, 42563, 0, 125080, 0, 6792, 43201, 72098, 0, 128719, 0, 72106, 0, - 0, 5644, 0, 66627, 69727, 0, 0, 0, 65116, 0, 0, 0, 0, 66410, 94104, - 41013, 0, 0, 0, 2869, 0, 41015, 0, 2785, 120616, 0, 73907, 194689, 0, 0, - 0, 194688, 4759, 0, 0, 43192, 129913, 1170, 43365, 69810, 73908, 0, 902, - 0, 0, 0, 0, 8122, 66420, 129642, 0, 3861, 0, 11028, 0, 73820, 5714, 0, 0, - 0, 807, 127001, 78474, 0, 976, 113782, 0, 0, 0, 0, 0, 128657, 118801, - 71043, 0, 127017, 0, 0, 5582, 0, 0, 5798, 0, 0, 0, 128521, 0, 0, 68058, - 120553, 983183, 0, 0, 74933, 74283, 0, 0, 194698, 66044, 0, 0, 0, 0, 0, - 10094, 0, 0, 10857, 69225, 0, 0, 93, 0, 10954, 0, 0, 0, 8171, 0, 0, - 82996, 0, 0, 0, 119001, 92634, 0, 0, 5187, 120711, 71086, 118704, 0, 0, - 0, 5232, 0, 41009, 0, 41005, 0, 43205, 0, 0, 0, 194708, 0, 71054, 10028, - 66478, 7076, 13182, 100385, 0, 0, 0, 78782, 7972, 78786, 0, 0, 0, 78789, - 11309, 3806, 71252, 0, 0, 0, 78819, 0, 125218, 0, 127532, 0, 0, 0, 78817, - 0, 64366, 65156, 8814, 0, 0, 0, 0, 12836, 42725, 120079, 0, 0, 0, 0, - 69258, 13255, 0, 0, 7464, 0, 93831, 0, 0, 0, 0, 13213, 118557, 0, 64516, - 0, 0, 0, 41007, 983929, 0, 40995, 12209, 983933, 119136, 123635, 0, 0, 0, - 0, 0, 69283, 43558, 5522, 0, 71061, 0, 74105, 3633, 983931, 119364, - 41234, 41231, 0, 9771, 983936, 13251, 0, 0, 6262, 2784, 0, 71078, 8126, - 66483, 0, 0, 441, 0, 0, 0, 41002, 40999, 0, 129394, 7108, 0, 10890, 0, - 74445, 8324, 0, 0, 74817, 2813, 119056, 74853, 983690, 0, 0, 0, 1193, - 10462, 65197, 13253, 13252, 7829, 120992, 130032, 0, 0, 0, 77911, 0, - 77907, 0, 10386, 0, 41042, 0, 65944, 65683, 10338, 66469, 0, 0, 0, 0, 0, - 41966, 0, 0, 0, 68915, 0, 0, 911, 983889, 128932, 40963, 0, 65159, 0, 0, - 0, 5520, 0, 0, 0, 0, 0, 0, 0, 42965, 0, 0, 0, 0, 0, 983892, 0, 0, 66839, - 0, 0, 0, 68647, 0, 5857, 68135, 92727, 119120, 983694, 13171, 0, 0, 0, - 120338, 0, 0, 0, 13250, 69663, 0, 92201, 66397, 0, 0, 0, 8761, 12942, - 5748, 92713, 92414, 0, 83174, 8796, 0, 0, 0, 43633, 0, 72805, 71073, 0, - 0, 0, 0, 0, 12843, 4520, 0, 0, 73004, 983691, 0, 0, 194935, 110754, - 64345, 0, 983677, 3457, 0, 0, 0, 110750, 110758, 110751, 0, 0, 10427, 0, - 73859, 0, 9755, 1110, 65239, 0, 0, 0, 0, 0, 0, 0, 194936, 0, 983821, 0, - 70437, 3620, 0, 0, 72855, 0, 0, 0, 74250, 0, 0, 11980, 0, 66482, 67823, - 0, 128345, 110768, 0, 0, 0, 0, 12891, 983786, 983667, 0, 2016, 0, 65668, - 92311, 67696, 10366, 70117, 9155, 120652, 9786, 65082, 0, 8579, 0, 0, 0, - 0, 4508, 64883, 0, 92522, 129847, 0, 64592, 74276, 67688, 0, 69270, 0, + 0, 5242, 0, 0, 128146, 0, 73535, 6770, 43331, 127539, 0, 0, 71074, + 126466, 73524, 41444, 0, 0, 64799, 5246, 119106, 13185, 9709, 0, 0, + 92751, 0, 5238, 0, 71085, 0, 5236, 40979, 0, 74201, 8286, 0, 3936, 92833, + 11699, 0, 127249, 13235, 69578, 41248, 127264, 13245, 13239, 0, 7969, + 127266, 74832, 127251, 0, 120509, 0, 983893, 734, 127270, 0, 127254, + 70297, 127273, 64921, 120969, 66631, 41771, 120490, 0, 983172, 41770, + 1670, 42560, 0, 121349, 129634, 0, 41163, 0, 11136, 0, 11506, 0, 42841, + 13267, 126109, 0, 41775, 0, 7130, 41773, 0, 0, 0, 0, 0, 0, 0, 42673, + 65572, 0, 65250, 13265, 13264, 64518, 66798, 6100, 0, 0, 6740, 71080, + 67814, 12967, 70028, 68101, 4583, 0, 0, 68097, 0, 0, 0, 0, 119211, 0, 0, + 42653, 83181, 68102, 0, 7814, 71045, 0, 73702, 0, 0, 0, 9756, 6985, 0, 0, + 74219, 0, 0, 129069, 124987, 5674, 0, 66421, 0, 5677, 5588, 0, 0, 0, 0, + 5673, 73488, 5676, 0, 94048, 0, 5672, 6476, 0, 128798, 110951, 42511, + 1727, 0, 0, 0, 0, 0, 0, 0, 3550, 736, 0, 4505, 5873, 74090, 5826, 55232, + 5813, 0, 120712, 5841, 5837, 55234, 0, 3105, 64370, 5838, 5796, 0, + 119592, 5793, 0, 5866, 5797, 41011, 5865, 0, 0, 71899, 0, 71235, 5806, + 73528, 0, 9037, 5671, 0, 0, 0, 0, 71266, 126616, 7296, 0, 0, 0, 0, 6980, + 0, 72108, 0, 0, 0, 0, 0, 64613, 983910, 0, 129969, 0, 78277, 7114, 0, + 72100, 43190, 93842, 128666, 72096, 42611, 42563, 0, 125080, 0, 6792, + 43201, 72098, 0, 128719, 0, 72106, 73534, 0, 5644, 0, 66627, 69727, 0, 0, + 0, 65116, 0, 0, 73526, 0, 66410, 94104, 41013, 0, 0, 0, 2869, 0, 41015, + 0, 2785, 120616, 0, 73907, 194689, 0, 0, 0, 194688, 4759, 0, 0, 43192, + 129913, 1170, 43365, 69810, 73908, 0, 902, 0, 0, 0, 0, 8122, 66420, + 129642, 0, 3861, 0, 11028, 0, 73820, 5714, 0, 0, 0, 807, 127001, 78474, + 0, 976, 113782, 0, 0, 0, 0, 0, 128657, 118801, 71043, 0, 127017, 0, 0, + 5582, 0, 0, 5798, 0, 0, 0, 128521, 0, 0, 68058, 120553, 983184, 0, 0, + 74933, 74283, 0, 0, 194698, 66044, 0, 0, 0, 0, 0, 10094, 0, 0, 10857, + 69225, 0, 0, 93, 0, 10954, 0, 0, 0, 8171, 0, 0, 82996, 0, 0, 0, 73527, + 92634, 0, 0, 5187, 120711, 71086, 118704, 0, 0, 0, 5232, 0, 41009, 0, + 41005, 0, 43205, 0, 0, 0, 194708, 0, 71054, 10028, 66478, 7076, 13182, + 100385, 0, 0, 0, 78782, 7972, 78786, 0, 0, 0, 78789, 11309, 3806, 71252, + 0, 0, 0, 78819, 0, 125218, 0, 127532, 0, 0, 0, 78817, 0, 64366, 65156, + 8814, 0, 0, 0, 0, 12836, 42725, 120079, 0, 0, 0, 0, 69258, 13255, 0, 0, + 7464, 0, 93831, 0, 0, 0, 0, 13213, 118557, 0, 64516, 0, 0, 0, 41007, + 983929, 0, 40995, 12209, 983933, 119136, 123635, 0, 0, 0, 0, 0, 69283, + 43558, 5522, 0, 71061, 0, 74105, 3633, 983931, 119364, 41234, 41231, 0, + 9771, 983936, 13251, 0, 0, 6262, 2784, 0, 71078, 8126, 66483, 0, 0, 441, + 0, 0, 0, 41002, 40999, 0, 129394, 7108, 0, 10890, 0, 74445, 8324, 0, 0, + 74817, 2813, 119056, 74853, 983690, 0, 0, 0, 1193, 10462, 65197, 13253, + 13252, 7829, 120992, 130032, 0, 0, 0, 77911, 0, 77907, 0, 10386, 0, + 41042, 0, 65944, 65683, 10338, 66469, 0, 0, 0, 0, 0, 41966, 0, 0, 0, + 68915, 0, 0, 911, 983889, 128932, 40963, 0, 65159, 0, 122950, 0, 5520, 0, + 0, 0, 0, 0, 0, 0, 42965, 0, 0, 0, 0, 0, 983892, 0, 0, 66839, 0, 0, 0, + 68647, 0, 5857, 68135, 92727, 119120, 983694, 13171, 0, 0, 0, 120338, 0, + 0, 0, 13250, 69663, 0, 92201, 66397, 0, 0, 0, 8761, 12942, 5748, 92713, + 92414, 0, 83174, 8796, 0, 0, 0, 43633, 0, 72805, 71073, 0, 0, 0, 0, 0, + 12843, 4520, 0, 0, 73004, 983691, 0, 0, 194935, 110754, 64345, 0, 983677, + 3457, 0, 0, 0, 110750, 110758, 110751, 0, 0, 10427, 0, 73859, 0, 9755, + 1110, 65239, 0, 0, 0, 0, 0, 0, 0, 194936, 0, 983821, 0, 70437, 3620, 0, + 0, 72855, 0, 0, 0, 74250, 0, 0, 11980, 0, 66482, 67823, 0, 128345, + 110768, 0, 0, 0, 0, 12891, 983786, 983667, 0, 2016, 0, 65668, 92311, + 67696, 10366, 70117, 9155, 120652, 9786, 65082, 0, 8579, 0, 0, 0, 0, + 4508, 64883, 0, 92522, 129847, 0, 64592, 74276, 67688, 0, 69270, 0, 69456, 0, 113821, 0, 12147, 9024, 66378, 66472, 0, 0, 0, 0, 0, 71935, 0, 0, 113697, 0, 0, 69285, 0, 74275, 0, 122896, 127941, 41214, 0, 67476, 0, 0, 0, 7773, 0, 0, 9963, 68649, 0, 73734, 0, 0, 0, 0, 6594, 983771, 0, 0, 3624, 70342, 0, 64655, 121481, 0, 0, 0, 0, 0, 65932, 0, 983809, 6803, 120968, 7738, 0, 0, 120628, 129721, 66614, 122921, 0, 43810, 7029, 0, 41292, 118898, 0, 43115, 9517, 11518, 0, 0, 0, 0, 64423, 0, 0, 0, 12503, - 9591, 4516, 0, 118845, 0, 0, 129479, 43650, 983192, 69250, 0, 0, 68079, + 9591, 4516, 0, 118845, 0, 0, 129479, 43650, 983193, 69250, 0, 0, 68079, 0, 11397, 2884, 0, 0, 12678, 0, 0, 41014, 73730, 917539, 4270, 92254, - 127836, 68205, 6633, 118947, 0, 5230, 101055, 0, 0, 983231, 121392, 0, + 127836, 68205, 6633, 118947, 0, 5230, 101055, 0, 0, 983234, 121392, 0, 92985, 0, 0, 0, 0, 415, 0, 0, 0, 0, 5183, 1877, 0, 0, 0, 0, 0, 4472, 0, 0, 0, 128285, 110682, 78230, 4756, 0, 7081, 0, 0, 0, 78606, 0, 42922, 42103, 8628, 74861, 0, 0, 0, 43059, 10539, 0, 0, 0, 0, 0, 0, 0, 0, 64873, - 11992, 129444, 0, 0, 11801, 3622, 0, 0, 983213, 0, 0, 11521, 0, 1966, + 11992, 129444, 0, 0, 11801, 3622, 0, 0, 983215, 0, 0, 11521, 0, 1966, 43628, 111048, 0, 0, 0, 0, 0, 0, 42098, 66671, 10694, 128520, 0, 0, 0, 0, 42100, 0, 111040, 0, 42097, 0, 0, 0, 0, 11302, 118640, 129145, 43395, 83259, 0, 0, 92351, 0, 0, 11299, 1561, 0, 92359, 92725, 69253, 0, 194733, - 0, 0, 0, 127893, 11280, 0, 0, 983802, 0, 0, 72760, 0, 12486, 65018, + 0, 194730, 0, 127893, 11280, 0, 0, 983802, 0, 0, 72760, 0, 12486, 65018, 66516, 5409, 0, 0, 194720, 5399, 9685, 0, 983713, 5401, 0, 0, 66832, 0, 0, 5405, 0, 0, 0, 0, 0, 2235, 0, 11330, 983711, 64690, 3254, 0, 129974, - 0, 0, 43678, 0, 0, 983145, 0, 6388, 3355, 0, 9867, 0, 55258, 5611, 0, + 0, 0, 43678, 0, 0, 983146, 0, 6388, 3355, 0, 9867, 0, 55258, 5611, 0, 128527, 0, 0, 129181, 0, 78228, 0, 0, 119119, 0, 0, 194959, 0, 0, 1379, 246, 0, 0, 64736, 0, 0, 0, 121227, 0, 0, 0, 0, 0, 0, 11855, 0, 0, 0, 71961, 10656, 0, 65214, 119242, 0, 0, 13163, 0, 120831, 0, 0, 101484, 0, @@ -28965,11 +29161,11 @@ static const unsigned int code_hash[] = { 119207, 0, 0, 9550, 100621, 0, 100623, 100622, 78050, 100624, 65753, 100626, 65756, 72731, 0, 100630, 0, 0, 0, 0, 9657, 9019, 121154, 0, 0, 5390, 0, 0, 194965, 72144, 69937, 69286, 6328, 0, 0, 0, 0, 0, 983047, 0, - 5235, 803, 69289, 0, 0, 127979, 43838, 0, 119562, 43544, 0, 0, 0, 0, 0, - 70426, 9107, 5191, 119113, 0, 0, 0, 121099, 0, 0, 0, 0, 0, 128150, - 983067, 0, 7289, 74055, 0, 0, 0, 0, 0, 0, 0, 1784, 124947, 0, 0, 0, 0, - 64868, 0, 13158, 0, 7211, 0, 9371, 129378, 0, 0, 1625, 7664, 0, 0, 0, 0, - 0, 0, 69273, 0, 0, 0, 0, 4482, 118886, 0, 0, 0, 0, 0, 0, 0, 100612, + 5235, 803, 69289, 0, 0, 127979, 43838, 0, 119562, 43544, 0, 0, 0, 0, + 194960, 70426, 9107, 5191, 119113, 0, 0, 0, 121099, 0, 0, 0, 0, 0, + 128150, 983067, 0, 7289, 74055, 0, 0, 0, 0, 0, 0, 0, 1784, 124947, 0, 0, + 0, 0, 64868, 0, 13158, 0, 7211, 0, 9371, 129378, 0, 0, 1625, 7664, 0, 0, + 0, 0, 0, 0, 69273, 0, 0, 0, 0, 4482, 118886, 0, 0, 0, 0, 0, 0, 0, 100612, 66849, 100614, 100613, 100616, 444, 100618, 100617, 100620, 100619, 0, 129401, 0, 11349, 40991, 0, 0, 129324, 0, 0, 1197, 0, 40993, 0, 0, 0, 40990, 43765, 0, 3492, 0, 127942, 0, 0, 100592, 100591, 100594, 19948, @@ -28979,13 +29175,13 @@ static const unsigned int code_hash[] = { 0, 130037, 0, 118820, 0, 0, 0, 0, 0, 100581, 0, 100583, 100582, 100585, 100584, 100587, 100586, 100589, 7576, 11995, 100590, 43260, 0, 0, 64830, 0, 125046, 101526, 0, 43979, 8870, 0, 0, 42357, 0, 0, 12822, 0, 0, 0, - 118944, 0, 0, 42637, 0, 0, 70725, 0, 129934, 0, 71344, 0, 0, 0, 194745, - 7170, 9596, 8277, 194743, 43629, 110610, 0, 0, 983571, 123545, 0, 66699, - 42952, 0, 0, 0, 43234, 66008, 12627, 0, 0, 0, 43619, 43303, 11300, 0, 0, - 8745, 0, 7558, 71342, 100570, 0, 0, 127881, 3461, 121258, 129471, 69264, - 0, 0, 0, 73877, 74335, 124982, 0, 0, 0, 64620, 74762, 12069, 10838, - 92548, 43616, 0, 10061, 0, 64840, 10508, 209, 0, 43193, 120581, 0, 0, - 128049, 0, 10899, 69855, 100571, 100574, 100573, 100576, 993, 100578, + 118944, 0, 0, 42637, 0, 0, 70725, 0, 129934, 0, 71344, 0, 0, 72449, + 194745, 7170, 9596, 8277, 194743, 43629, 110610, 0, 0, 983571, 123545, 0, + 66699, 42952, 0, 0, 0, 43234, 66008, 12627, 0, 0, 0, 43619, 43303, 11300, + 0, 0, 8745, 0, 7558, 71342, 100570, 0, 0, 127881, 3461, 121258, 129471, + 69264, 0, 0, 0, 73877, 74335, 124982, 0, 0, 0, 64620, 74762, 12069, + 10838, 92548, 43616, 0, 10061, 0, 64840, 10508, 209, 0, 43193, 120581, 0, + 0, 128049, 0, 10899, 69855, 100571, 100574, 100573, 100576, 993, 100578, 100577, 100580, 100579, 100560, 100559, 7232, 0, 0, 0, 0, 0, 0, 10489, 42166, 0, 128588, 0, 0, 4224, 7671, 41518, 121311, 0, 0, 0, 0, 64820, 92538, 12966, 100554, 100553, 100556, 100555, 100558, 100557, 4263, 8793, @@ -28994,25 +29190,25 @@ static const unsigned int code_hash[] = { 0, 2147, 0, 0, 66629, 0, 0, 1255, 4149, 0, 0, 66633, 0, 129391, 92352, 0, 65101, 0, 0, 0, 0, 5835, 128797, 66625, 10842, 0, 42123, 0, 0, 66634, 1094, 66636, 0, 0, 0, 0, 0, 9972, 73865, 129289, 6114, 0, 0, 0, 0, 93960, - 0, 0, 0, 0, 12070, 0, 881, 7857, 0, 65164, 0, 0, 118703, 0, 0, 64404, - 64321, 0, 125187, 0, 0, 11245, 129395, 69506, 71859, 0, 0, 0, 1287, - 121509, 0, 0, 0, 125264, 74152, 120504, 64545, 0, 69668, 8985, 0, 0, 0, - 0, 0, 0, 3652, 0, 0, 0, 0, 0, 279, 0, 0, 0, 0, 1489, 125189, 0, 0, 3899, - 0, 42124, 43828, 42122, 0, 0, 0, 11985, 73755, 78600, 0, 0, 10988, 0, 0, - 42138, 78610, 0, 65768, 78608, 78604, 78605, 6285, 78603, 78612, 78613, - 74339, 65767, 8685, 0, 0, 0, 78622, 78623, 68475, 11470, 64538, 78618, - 78615, 78616, 0, 0, 0, 101534, 2527, 0, 128209, 2799, 0, 0, 0, 9933, 0, - 0, 767, 5524, 7028, 0, 101520, 0, 0, 0, 78633, 67481, 0, 94011, 0, 6971, - 0, 70731, 0, 0, 118979, 126075, 2434, 94018, 0, 120579, 0, 4631, 0, 0, - 6407, 0, 19931, 0, 0, 124905, 0, 3192, 0, 8414, 0, 0, 0, 124902, 0, 9164, - 66612, 93959, 8228, 124897, 0, 0, 0, 78624, 0, 0, 9993, 0, 0, 129350, - 78631, 78632, 78629, 78630, 78627, 78628, 78625, 2399, 0, 92399, 71202, - 41208, 0, 0, 8178, 2149, 3367, 0, 78640, 78641, 78636, 78638, 78634, - 6337, 0, 92342, 0, 0, 11068, 0, 9331, 0, 74798, 9181, 0, 0, 8017, 0, 0, - 0, 0, 0, 0, 0, 12126, 129184, 129306, 0, 0, 69650, 0, 0, 0, 43436, + 0, 0, 0, 0, 12070, 0, 881, 7857, 0, 65164, 0, 0, 118703, 124151, 0, + 64404, 64321, 0, 125187, 0, 0, 11245, 129395, 69506, 71859, 128886, 0, 0, + 1287, 121509, 0, 0, 0, 125264, 74152, 120504, 64545, 0, 69668, 8985, 0, + 0, 0, 0, 0, 0, 3652, 0, 0, 0, 0, 0, 279, 0, 0, 0, 0, 1489, 125189, 0, 0, + 3899, 0, 42124, 43828, 42122, 0, 0, 0, 11985, 73755, 78600, 0, 0, 10988, + 0, 0, 42138, 78610, 0, 65768, 78608, 78604, 78605, 6285, 78603, 78612, + 78613, 74339, 65767, 8685, 0, 0, 0, 78622, 78623, 68475, 11470, 64538, + 78618, 78615, 78616, 0, 0, 0, 101534, 2527, 0, 128209, 2799, 0, 0, 0, + 9933, 0, 0, 767, 5524, 7028, 0, 101520, 0, 0, 0, 78633, 67481, 0, 94011, + 0, 6971, 0, 70731, 0, 0, 118979, 126075, 2434, 94018, 0, 120579, 0, 4631, + 0, 0, 6407, 0, 19931, 0, 0, 124905, 0, 3192, 0, 8414, 0, 0, 0, 124902, 0, + 9164, 66612, 93959, 8228, 124897, 0, 0, 0, 78624, 0, 0, 9993, 0, 0, + 129350, 78631, 78632, 78629, 78630, 78627, 78628, 78625, 2399, 0, 92399, + 71202, 41208, 0, 0, 8178, 2149, 3367, 0, 78640, 78641, 78636, 78638, + 78634, 6337, 0, 78909, 0, 0, 11068, 0, 9331, 0, 74798, 9181, 0, 0, 8017, + 0, 0, 0, 0, 0, 0, 0, 12126, 119494, 129306, 0, 0, 69650, 0, 0, 0, 43436, 983744, 0, 0, 0, 0, 66845, 69249, 0, 0, 5398, 0, 127386, 93953, 0, 0, 0, 0, 0, 9476, 68899, 0, 12763, 126603, 74788, 0, 42114, 11181, 92502, 0, 0, - 0, 3469, 42107, 42116, 0, 0, 0, 0, 9853, 69648, 9040, 101518, 64665, + 0, 3469, 42107, 42116, 0, 0, 119493, 0, 9853, 69648, 9040, 101518, 64665, 119557, 0, 0, 0, 69638, 12602, 983068, 3852, 0, 67872, 12231, 11317, 0, 119812, 0, 11410, 10964, 12274, 122890, 100524, 0, 119810, 9865, 195019, 0, 0, 0, 0, 12276, 0, 124919, 0, 0, 119613, 0, 111214, 10467, 0, 2443, @@ -29022,16 +29218,16 @@ static const unsigned int code_hash[] = { 120613, 67247, 1629, 124926, 796, 0, 0, 74123, 72334, 127587, 72336, 43388, 0, 43944, 72335, 478, 65151, 0, 128147, 0, 0, 0, 0, 0, 42933, 1206, 71209, 43837, 0, 3843, 12011, 0, 3361, 0, 8121, 10715, 7578, 0, 0, - 0, 10530, 12348, 8653, 0, 0, 0, 9551, 0, 0, 784, 0, 0, 0, 0, 0, 0, 43937, - 0, 0, 43938, 43935, 73765, 66230, 0, 0, 0, 43936, 0, 43932, 11102, 0, 0, - 42753, 67165, 0, 78324, 0, 0, 6975, 917928, 5415, 12176, 0, 0, 3462, - 43940, 42629, 78691, 128016, 43942, 0, 9759, 0, 0, 78320, 8114, 78321, - 78697, 78696, 78695, 8710, 118812, 118956, 0, 4051, 92657, 0, 71206, 0, - 0, 0, 128857, 0, 1619, 9703, 77986, 0, 42112, 0, 1875, 0, 42109, 0, 0, - 71189, 121160, 64907, 5396, 13144, 0, 0, 5575, 9675, 0, 5940, 226, 0, - 6336, 0, 0, 0, 5116, 64521, 0, 0, 0, 121390, 125048, 74138, 0, 74139, - 128447, 92249, 0, 0, 0, 0, 8935, 0, 0, 0, 0, 616, 78131, 65178, 4684, - 78701, 983899, 74631, 0, 0, 0, 74460, 42110, 0, 10870, 8557, 11054, + 0, 10530, 12348, 8653, 0, 73545, 0, 9551, 0, 0, 784, 0, 0, 0, 0, 0, 0, + 43937, 0, 0, 43938, 43935, 73765, 66230, 0, 0, 0, 43936, 0, 43932, 11102, + 0, 0, 42753, 67165, 0, 78324, 0, 0, 6975, 917928, 5415, 12176, 0, 0, + 3462, 43940, 42629, 78691, 128016, 43942, 0, 9759, 0, 0, 78320, 8114, + 78321, 78697, 78696, 78695, 8710, 118812, 118956, 0, 4051, 92657, 0, + 71206, 0, 0, 0, 128857, 0, 1619, 9703, 77986, 0, 42112, 0, 1875, 0, + 42109, 0, 0, 71189, 121160, 64907, 5396, 13144, 0, 0, 5575, 9675, 0, + 5940, 226, 0, 6336, 0, 0, 0, 5116, 64521, 0, 0, 0, 121390, 125048, 74138, + 0, 74139, 128447, 92249, 0, 0, 0, 0, 8935, 0, 0, 0, 0, 616, 78131, 65178, + 4684, 78701, 983899, 74631, 0, 0, 0, 74460, 42110, 0, 10870, 8557, 11054, 68664, 0, 0, 0, 122629, 0, 0, 0, 0, 65597, 0, 7651, 6846, 0, 0, 68868, 0, 0, 118966, 129302, 40997, 127218, 0, 0, 40998, 0, 74488, 71182, 9800, 0, 0, 0, 41000, 0, 5114, 55263, 3386, 70730, 42574, 0, 5115, 5394, 0, @@ -29041,55 +29237,55 @@ static const unsigned int code_hash[] = { 4514, 72149, 0, 0, 0, 65041, 10965, 120905, 0, 0, 12542, 0, 65341, 0, 65829, 0, 0, 10475, 0, 0, 0, 0, 11795, 0, 0, 2164, 127102, 127101, 74956, 7099, 11275, 67681, 127096, 0, 9336, 0, 42626, 43966, 7798, 64474, 64259, - 0, 5730, 119809, 43018, 983174, 93796, 0, 0, 0, 69401, 0, 0, 5127, 11285, + 0, 5730, 119809, 43018, 983175, 93796, 0, 0, 0, 69401, 0, 0, 5127, 11285, 0, 5495, 4273, 0, 74765, 10849, 6346, 5493, 6342, 68636, 74319, 5492, 0, 0, 169, 5497, 125053, 0, 0, 68198, 0, 0, 128417, 0, 0, 12738, 0, 983076, 5321, 0, 0, 0, 5323, 120732, 9773, 125209, 4683, 74318, 0, 68823, 0, 0, 0, 0, 129553, 0, 123562, 0, 0, 834, 0, 1803, 0, 5733, 0, 0, 71312, 5731, - 1381, 2891, 0, 0, 127212, 64525, 0, 2881, 92996, 93847, 9601, 2879, 0, 0, - 73129, 5729, 0, 0, 0, 64881, 127905, 9361, 0, 2887, 0, 3526, 6298, 0, - 121219, 0, 0, 0, 8572, 127863, 77896, 0, 71174, 0, 0, 71197, 0, 12096, 0, - 0, 0, 110745, 71176, 110746, 65279, 0, 121236, 5734, 0, 0, 0, 0, 0, + 1381, 2891, 128639, 0, 127212, 64525, 0, 2881, 92996, 93847, 9601, 2879, + 0, 0, 73129, 5729, 0, 0, 0, 64881, 127905, 9361, 0, 2887, 0, 3526, 6298, + 0, 121219, 0, 0, 0, 8572, 127863, 77896, 0, 71174, 0, 0, 71197, 0, 12096, + 0, 0, 0, 110745, 71176, 110746, 65279, 0, 121236, 5734, 0, 0, 0, 0, 0, 41641, 12717, 0, 12552, 983615, 66713, 0, 0, 41643, 110747, 0, 8713, 41640, 78657, 41645, 66712, 125196, 0, 66726, 66711, 0, 93994, 0, 3472, 64863, 0, 121424, 0, 0, 0, 125203, 67837, 0, 0, 0, 0, 0, 0, 121440, 0, 0, 129461, 119008, 92402, 65017, 0, 0, 66668, 0, 0, 0, 0, 0, 119822, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 121043, 66471, 12216, 0, 40988, 0, 0, 0, 0, 0, - 2396, 129078, 0, 0, 0, 64940, 0, 8321, 119823, 128165, 100409, 83299, - 996, 0, 0, 4249, 0, 83294, 92535, 8222, 0, 118875, 71213, 0, 0, 0, 0, - 8534, 72844, 40983, 0, 125195, 0, 12551, 73960, 125193, 74469, 12558, + 124148, 0, 0, 0, 0, 0, 0, 0, 0, 121043, 66471, 12216, 0, 40988, 0, 0, 0, + 0, 0, 2396, 129078, 0, 0, 0, 64940, 0, 8321, 119823, 128165, 100409, + 83299, 996, 0, 0, 4249, 0, 83294, 92535, 8222, 0, 118875, 71213, 0, 0, 0, + 0, 8534, 72844, 40983, 0, 125195, 0, 12551, 73960, 125193, 74469, 12558, 121039, 0, 10052, 40982, 129371, 0, 0, 0, 127403, 0, 917559, 0, 78364, 1563, 0, 0, 19911, 0, 0, 0, 71363, 0, 7797, 78708, 10006, 0, 3308, 119134, 74940, 0, 0, 78488, 0, 0, 0, 0, 0, 128462, 9200, 10046, 9612, 0, 8218, 66496, 0, 43742, 78489, 0, 0, 0, 0, 67826, 0, 70056, 508, 128585, 0, 126539, 0, 0, 0, 0, 0, 0, 0, 124950, 0, 194601, 0, 0, 0, 0, 6659, 0, 0, 0, 0, 0, 0, 41634, 0, 41639, 71169, 11941, 0, 0, 0, 42180, 68505, - 43753, 3249, 41637, 93982, 12328, 501, 93985, 10601, 0, 6503, 0, 92192, - 0, 71181, 0, 6505, 74010, 0, 13064, 126112, 121105, 6500, 5526, 0, + 43753, 3249, 41637, 93982, 12328, 501, 93985, 10601, 129783, 6503, 0, + 92192, 0, 71181, 0, 6505, 74010, 0, 13064, 126112, 121105, 6500, 5526, 0, 128949, 0, 0, 92376, 0, 9678, 120832, 0, 41706, 0, 0, 0, 8936, 92964, - 119123, 4208, 0, 0, 0, 67742, 0, 74379, 128605, 0, 0, 92422, 983109, 0, + 119123, 4208, 0, 0, 0, 67742, 0, 74379, 128605, 0, 0, 92422, 983110, 0, 66475, 0, 5027, 0, 0, 0, 5069, 0, 5028, 0, 0, 0, 5026, 0, 0, 6331, 0, 0, 0, 0, 41076, 0, 74790, 0, 0, 0, 0, 5029, 0, 5317, 3598, 0, 41070, 92166, 11185, 6663, 0, 6507, 0, 126079, 0, 1716, 983710, 0, 917824, 620, 41001, - 0, 917823, 43758, 0, 71116, 5024, 0, 41003, 0, 5025, 7297, 0, 75039, + 0, 917823, 43758, 0, 71116, 5024, 0, 41003, 0, 5025, 7297, 122988, 75039, 69745, 119328, 65557, 0, 0, 983599, 0, 0, 0, 0, 43947, 43946, 0, 0, - 128363, 6105, 0, 119325, 983227, 0, 68203, 43945, 66491, 43939, 0, 68144, + 128363, 6105, 0, 119325, 983230, 0, 68203, 43945, 66491, 43939, 0, 68144, 78718, 2301, 0, 0, 66490, 6979, 101561, 7721, 0, 0, 1592, 0, 0, 121096, - 41048, 129358, 829, 0, 92406, 0, 120247, 0, 41056, 0, 118665, 10953, + 41048, 129358, 829, 0, 92406, 0, 73541, 0, 41056, 0, 118665, 10953, 41066, 0, 917813, 482, 101554, 0, 0, 43606, 71185, 0, 917926, 0, 72262, 110863, 72421, 12050, 0, 5315, 917817, 0, 0, 42061, 917816, 0, 0, 68417, 917815, 0, 0, 42059, 0, 0, 120723, 42058, 3960, 11043, 11337, 121358, 0, 92824, 3958, 101568, 0, 917818, 0, 917819, 0, 0, 42064, 11959, 983714, 0, - 0, 0, 0, 128498, 64336, 10478, 92629, 70350, 118692, 0, 0, 42437, 1555, - 0, 8691, 129656, 2215, 41662, 119046, 0, 0, 0, 93952, 0, 66481, 41664, 0, + 0, 0, 0, 73511, 64336, 10478, 92629, 70350, 118692, 0, 0, 42437, 1555, 0, + 8691, 129656, 2215, 41662, 119046, 0, 0, 0, 93952, 0, 66481, 41664, 0, 42578, 0, 41661, 78715, 78714, 9356, 0, 129544, 0, 1286, 110701, 0, 0, - 983206, 128925, 42476, 0, 11156, 0, 0, 0, 101583, 72123, 0, 10020, 43359, - 72827, 0, 120946, 41627, 0, 11979, 0, 41628, 533, 11931, 65225, 0, + 983208, 128925, 42476, 0, 11156, 78895, 0, 0, 101583, 72123, 0, 10020, + 43359, 72827, 0, 120946, 41627, 0, 11979, 0, 41628, 533, 11931, 65225, 0, 125122, 129994, 0, 68118, 0, 4377, 0, 0, 8587, 72097, 13193, 64350, 68233, 0, 41924, 0, 7735, 0, 127585, 120843, 0, 65820, 0, 0, 43461, 7757, 0, 0, 43787, 66493, 77943, 4168, 43904, 73952, 0, 0, 121072, 4440, 43902, 77948, 66837, 77946, 43903, 77944, 77945, 0, 120909, 120826, 120226, - 66492, 43901, 64625, 0, 0, 0, 0, 10013, 64434, 0, 983112, 0, 11782, + 66492, 43901, 64625, 0, 0, 0, 0, 10013, 64434, 0, 983113, 0, 11782, 64382, 0, 0, 0, 0, 41630, 630, 120960, 0, 0, 70165, 1043, 93017, 0, 0, 0, 124945, 313, 129590, 0, 0, 65593, 7445, 43906, 5750, 42258, 0, 55222, 68222, 11268, 11225, 0, 8526, 0, 0, 43894, 66495, 69990, 0, 92990, 0, @@ -29116,8 +29312,8 @@ static const unsigned int code_hash[] = { 19940, 43668, 41667, 0, 0, 1923, 0, 0, 0, 0, 0, 0, 0, 0, 6464, 92750, 2996, 125221, 0, 68481, 41835, 4047, 41842, 0, 0, 129601, 0, 0, 0, 0, 293, 0, 0, 64791, 41827, 0, 0, 10579, 8560, 0, 0, 118835, 4803, 73805, - 1739, 0, 3900, 128967, 73737, 0, 0, 73957, 0, 66474, 41971, 0, 0, 0, 0, - 0, 11716, 66473, 0, 92647, 0, 128080, 0, 0, 0, 0, 0, 0, 0, 6632, 73861, + 1739, 0, 3900, 128967, 73737, 0, 72451, 73957, 0, 66474, 41971, 0, 0, 0, + 0, 0, 11716, 66473, 0, 92647, 0, 78920, 0, 0, 0, 0, 0, 0, 0, 6632, 73861, 0, 74770, 0, 0, 8914, 0, 0, 3183, 1435, 0, 0, 0, 0, 0, 0, 5746, 67392, 0, 0, 0, 83506, 0, 7082, 71481, 12618, 5059, 983597, 83524, 43604, 0, 0, 0, 0, 0, 0, 8227, 0, 1218, 0, 64416, 65848, 92884, 0, 0, 0, 126987, 0, 0, 0, @@ -29125,40 +29321,40 @@ static const unsigned int code_hash[] = { 65905, 0, 42662, 0, 121159, 0, 129536, 0, 7794, 0, 42953, 6377, 0, 126080, 3669, 3968, 0, 71319, 69658, 129550, 0, 66296, 118616, 0, 0, 0, 124998, 6699, 126120, 0, 0, 66678, 0, 0, 0, 8409, 119527, 19967, 0, 0, - 9502, 0, 0, 6115, 0, 41654, 0, 0, 0, 41655, 113779, 43975, 72427, 0, 0, - 0, 0, 41657, 10778, 0, 9533, 184, 1553, 128868, 69574, 0, 0, 0, 129420, - 0, 101589, 983576, 73697, 0, 92480, 0, 128938, 74292, 0, 5157, 4020, 0, - 128154, 43788, 64818, 0, 0, 0, 92979, 0, 0, 74377, 11029, 66651, 0, 0, - 125202, 0, 0, 7877, 121070, 101411, 0, 119828, 2810, 9955, 0, 0, 42817, - 0, 65122, 11715, 0, 0, 0, 71270, 0, 0, 0, 0, 0, 70199, 0, 0, 0, 0, 0, 0, - 127862, 0, 0, 0, 78222, 127981, 0, 0, 0, 0, 0, 11290, 0, 0, 0, 0, 8315, - 0, 0, 0, 74595, 0, 0, 0, 42531, 0, 0, 0, 74589, 43993, 0, 0, 0, 0, 43690, - 0, 119139, 42730, 0, 0, 0, 64926, 0, 0, 43830, 65257, 0, 42728, 0, - 128697, 123150, 0, 43540, 0, 0, 12725, 72993, 78635, 127826, 223, 0, - 69675, 0, 0, 0, 0, 0, 0, 42605, 0, 0, 0, 0, 0, 0, 0, 0, 78621, 0, 78619, - 119062, 0, 0, 0, 42676, 129353, 64800, 78617, 83504, 68126, 1213, 0, 0, - 797, 0, 0, 83021, 83005, 64387, 4115, 0, 0, 0, 129857, 10679, 83001, - 121091, 0, 64276, 83498, 13168, 83011, 0, 10136, 0, 0, 65088, 0, 4262, - 129866, 0, 0, 10701, 0, 3101, 0, 123204, 0, 0, 11373, 0, 0, 12731, 9117, - 0, 0, 4539, 0, 0, 12727, 0, 0, 0, 43684, 74567, 68877, 983726, 12724, - 73940, 0, 0, 0, 0, 0, 7947, 12003, 0, 74593, 121140, 69653, 74807, 42018, - 0, 0, 0, 65888, 0, 0, 69683, 0, 120306, 0, 0, 12595, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 69848, 68307, 0, 4405, 0, 128336, 129032, 69216, 0, 128011, - 118656, 0, 6817, 67400, 120314, 0, 0, 998, 0, 13105, 120313, 64327, 1558, - 0, 1991, 7882, 0, 0, 0, 530, 0, 0, 0, 12002, 0, 68422, 0, 10979, 0, - 41823, 70696, 0, 0, 7896, 0, 66676, 0, 120325, 0, 0, 129407, 94033, 0, - 6311, 110725, 41698, 0, 12049, 78133, 0, 125020, 41705, 0, 0, 121298, 0, - 66822, 0, 65389, 0, 66027, 0, 0, 41699, 8340, 0, 69776, 0, 128639, 0, - 1988, 5407, 69978, 0, 65912, 93059, 0, 2336, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 126238, 0, 19913, 0, 113733, 0, 0, 74279, 0, 10956, 0, 41674, 19964, - 41679, 65084, 41675, 195031, 0, 0, 0, 0, 983089, 0, 10794, 128961, 13217, - 0, 0, 0, 5280, 0, 0, 12905, 41610, 11532, 0, 0, 768, 120545, 442, 0, 0, - 0, 64081, 41682, 0, 41693, 0, 77993, 77994, 0, 4804, 6994, 983114, 0, 0, - 41696, 467, 983934, 0, 0, 0, 0, 8678, 0, 69682, 64801, 0, 0, 0, 2193, - 64093, 12043, 0, 69666, 0, 2029, 65191, 119246, 42847, 0, 0, 0, 0, 0, 0, - 0, 70339, 126116, 0, 0, 8019, 73856, 0, 0, 0, 118709, 2355, 12150, 65725, - 77988, 77989, 68033, 77987, 0, 77985, 0, 0, 68388, 0, 74171, 0, 0, 0, - 11301, 78013, 78008, 78010, 9874, 78007, 983328, 71064, 3050, 0, 0, 0, + 9502, 0, 0, 6115, 0, 41654, 0, 0, 0, 41655, 113779, 43975, 72427, 128080, + 0, 0, 0, 41657, 10778, 0, 9533, 184, 1553, 128868, 69574, 0, 0, 0, + 129420, 0, 101589, 983576, 73697, 0, 92480, 0, 128938, 74292, 0, 5157, + 4020, 0, 128154, 43788, 64818, 0, 0, 0, 92979, 0, 0, 74377, 11029, 66651, + 0, 0, 125202, 0, 0, 7877, 121070, 101411, 0, 119828, 2810, 9955, 0, + 69375, 42817, 0, 65122, 11715, 0, 0, 0, 71270, 0, 0, 0, 0, 0, 70199, 0, + 0, 0, 0, 0, 0, 127862, 0, 0, 0, 78222, 127981, 0, 0, 0, 0, 0, 11290, 0, + 0, 0, 0, 8315, 0, 0, 0, 74595, 0, 0, 0, 42531, 0, 0, 0, 74589, 43993, 0, + 0, 0, 0, 43690, 0, 119139, 42730, 0, 0, 0, 64926, 0, 0, 43830, 65257, 0, + 42728, 0, 128697, 123150, 0, 43540, 0, 0, 12725, 72993, 78635, 127826, + 223, 0, 69675, 0, 0, 0, 0, 0, 0, 42605, 0, 0, 0, 0, 0, 0, 0, 0, 78621, 0, + 78619, 119062, 0, 0, 0, 42676, 129353, 64800, 78617, 83504, 68126, 1213, + 0, 0, 797, 0, 0, 83021, 83005, 64387, 4115, 0, 0, 0, 129857, 10679, + 83001, 121091, 0, 64276, 83498, 13168, 83011, 0, 10136, 0, 0, 65088, 0, + 4262, 129866, 0, 0, 10701, 0, 3101, 0, 123204, 0, 0, 11373, 0, 0, 12731, + 9117, 0, 0, 4539, 0, 0, 12727, 0, 0, 0, 43684, 74567, 68877, 983726, + 12724, 73940, 0, 0, 0, 0, 0, 7947, 12003, 0, 74593, 121140, 69653, 74807, + 42018, 0, 0, 0, 65888, 0, 0, 69683, 0, 120306, 0, 0, 12595, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 69848, 68307, 0, 4405, 0, 128336, 129032, 69216, 0, + 128011, 118656, 0, 6817, 67400, 120314, 0, 0, 998, 0, 13105, 120313, + 64327, 1558, 0, 1991, 7882, 0, 0, 0, 530, 0, 0, 0, 12002, 0, 68422, 0, + 10979, 0, 41823, 70696, 0, 0, 7896, 0, 66676, 0, 120325, 0, 0, 129407, + 94033, 0, 6311, 110725, 41698, 0, 12049, 78133, 0, 125020, 41705, 0, 0, + 121298, 0, 66822, 0, 65389, 0, 66027, 0, 0, 41699, 8340, 0, 69776, 0, + 78921, 0, 1988, 5407, 69978, 0, 65912, 93059, 0, 2336, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 126238, 0, 19913, 0, 113733, 0, 0, 74279, 0, 10956, 0, 41674, + 19964, 41679, 65084, 41675, 195031, 0, 0, 0, 0, 983089, 0, 10794, 128961, + 13217, 0, 0, 0, 5280, 0, 0, 12905, 41610, 11532, 0, 0, 768, 120545, 442, + 0, 0, 0, 64081, 41682, 0, 41693, 0, 77993, 77994, 0, 4804, 6994, 983115, + 0, 0, 41696, 467, 983934, 0, 0, 0, 0, 8678, 0, 69682, 64801, 0, 0, 0, + 2193, 64093, 12043, 0, 69666, 0, 2029, 65191, 119246, 42847, 0, 0, 0, 0, + 0, 0, 0, 70339, 126116, 0, 0, 8019, 73856, 0, 0, 0, 118709, 2355, 12150, + 65725, 77988, 77989, 68033, 77987, 0, 77985, 0, 0, 68388, 0, 74171, 0, 0, + 0, 11301, 78013, 78008, 78010, 9874, 78007, 983331, 71064, 3050, 0, 0, 0, 78016, 78017, 71852, 78015, 0, 0, 0, 92242, 0, 69642, 0, 0, 43883, 0, 0, 0, 78025, 0, 78023, 78024, 11847, 10545, 0, 10887, 0, 123179, 0, 0, 0, 83352, 64942, 92363, 9996, 8508, 0, 0, 8195, 0, 42171, 0, 3722, 0, 63751, @@ -29170,59 +29366,60 @@ static const unsigned int code_hash[] = { 68495, 74131, 74130, 0, 0, 0, 611, 74129, 64871, 129958, 0, 0, 0, 74854, 0, 70466, 0, 0, 0, 121147, 0, 68487, 41669, 7094, 917921, 0, 123144, 74054, 0, 0, 0, 839, 0, 7695, 0, 0, 0, 92202, 0, 121053, 123157, 67885, - 0, 7206, 0, 6647, 43986, 0, 0, 0, 122646, 0, 0, 127936, 43748, 66746, 0, - 12298, 110802, 984011, 110800, 64924, 0, 73931, 9468, 74245, 0, 0, 74246, - 0, 0, 118830, 0, 71851, 1279, 0, 6224, 0, 92405, 128601, 129886, 128997, - 0, 0, 0, 5032, 0, 0, 0, 0, 0, 5034, 0, 0, 72846, 42702, 0, 0, 13294, 0, - 64869, 0, 67808, 9129, 123632, 0, 0, 120819, 68387, 120168, 120169, - 120170, 120171, 5518, 4174, 120166, 66932, 120160, 120161, 120162, 434, - 41437, 66212, 120158, 120159, 0, 0, 118867, 0, 524, 0, 74029, 0, 126559, - 0, 0, 0, 10355, 10419, 74025, 77847, 0, 69725, 0, 120656, 0, 67876, 0, 0, - 0, 74145, 74039, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5445, 0, 93779, 71855, - 7391, 8989, 0, 74068, 0, 0, 0, 0, 4962, 120409, 8855, 0, 70820, 0, 0, 0, - 0, 71847, 0, 120406, 0, 10451, 0, 67653, 120153, 12443, 120155, 9947, - 120149, 120150, 120151, 13128, 0, 120146, 120147, 0, 0, 0, 0, 0, 129715, - 74059, 74062, 6217, 74053, 43846, 0, 74049, 0, 0, 0, 0, 0, 0, 0, 0, - 42595, 0, 68112, 118860, 0, 0, 92497, 74949, 128953, 126245, 0, 0, 0, - 42997, 0, 119251, 0, 0, 0, 0, 0, 6216, 0, 0, 9455, 127027, 8124, 128851, - 0, 6944, 0, 0, 0, 2828, 128550, 531, 42638, 0, 0, 129888, 43428, 0, 3614, - 2827, 9696, 0, 0, 0, 4354, 0, 78562, 78561, 0, 118553, 0, 42599, 42597, - 0, 68829, 125012, 0, 127277, 0, 120421, 0, 983164, 0, 0, 10121, 120422, - 74950, 123142, 69715, 0, 0, 120423, 120630, 12608, 125244, 0, 74144, - 9700, 12580, 0, 128911, 0, 71864, 0, 74071, 0, 0, 12713, 0, 70402, 0, 0, - 0, 1734, 0, 0, 0, 0, 118951, 231, 0, 74167, 542, 0, 0, 0, 0, 128074, 0, - 121343, 0, 4446, 10584, 74235, 0, 4037, 0, 0, 0, 5687, 0, 0, 0, 0, 0, 0, - 78434, 92816, 0, 113709, 74284, 0, 0, 0, 126495, 0, 0, 0, 74482, 93978, - 1709, 69721, 9909, 92286, 0, 0, 0, 55229, 8667, 0, 0, 0, 0, 0, 0, 0, 0, - 127586, 1226, 6930, 0, 71736, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41500, 0, 311, - 74282, 6221, 92988, 0, 67682, 0, 120528, 122901, 74272, 0, 0, 0, 0, - 69667, 0, 124933, 74456, 74302, 42589, 0, 0, 0, 0, 64847, 0, 66987, 0, - 41508, 0, 323, 125211, 0, 42698, 8131, 0, 4625, 0, 4630, 0, 0, 0, 74316, - 78417, 2668, 92483, 0, 42640, 0, 2519, 0, 92474, 92479, 0, 983085, 5049, - 42659, 119011, 64705, 7754, 10854, 8738, 74623, 0, 0, 0, 649, 0, 0, 0, 0, - 0, 1013, 70707, 68212, 705, 0, 0, 127803, 1183, 126519, 9320, 0, 0, 8157, - 0, 0, 0, 0, 0, 0, 0, 11913, 0, 42848, 0, 64925, 0, 0, 70693, 0, 0, 2051, - 0, 0, 0, 66988, 0, 0, 0, 8466, 0, 4626, 8464, 8472, 68844, 4629, 8499, 0, - 0, 4624, 194623, 0, 94025, 0, 7805, 0, 94007, 6935, 0, 0, 0, 0, 0, 0, 0, - 8492, 0, 8459, 0, 8497, 8496, 0, 129864, 0, 0, 129834, 69553, 0, 0, - 65849, 0, 0, 0, 12451, 3328, 8684, 0, 6102, 0, 5298, 110881, 5294, 0, - 129615, 0, 0, 0, 0, 43617, 0, 0, 0, 0, 0, 77863, 128695, 0, 0, 0, 0, 0, - 5292, 0, 0, 42688, 5302, 3970, 0, 0, 1793, 0, 0, 0, 0, 0, 65263, 0, 0, 0, - 0, 0, 0, 13219, 9569, 69567, 74383, 0, 0, 72157, 0, 42949, 0, 0, 0, 5322, - 0, 0, 43631, 5324, 0, 128694, 41614, 65269, 6230, 0, 0, 0, 3360, 0, - 11523, 72726, 92488, 9926, 7197, 0, 68429, 126575, 41821, 1249, 0, - 127951, 0, 123641, 0, 0, 0, 74459, 41807, 0, 41815, 0, 0, 0, 119918, 0, - 128248, 0, 66835, 0, 0, 72145, 41800, 0, 0, 0, 41811, 74466, 93966, 6670, - 77882, 0, 0, 43092, 0, 0, 0, 0, 0, 128655, 0, 0, 0, 0, 74501, 74005, 0, - 74387, 69860, 315, 12813, 128556, 72409, 0, 72408, 0, 0, 73061, 0, 0, - 1378, 0, 0, 0, 72407, 3066, 0, 0, 72406, 0, 0, 0, 8787, 194615, 0, 41618, - 0, 0, 0, 194614, 64652, 194611, 42088, 125226, 0, 0, 0, 0, 7176, 43756, - 0, 122649, 74492, 0, 74534, 0, 0, 0, 127199, 0, 128630, 74525, 0, 194594, - 12930, 7168, 74514, 0, 74515, 0, 128919, 43962, 9527, 120659, 70123, - 12977, 69723, 0, 93783, 194598, 41236, 92235, 65168, 118838, 41237, 5848, - 0, 194600, 3670, 129905, 129906, 129907, 129908, 7890, 0, 11298, 0, 0, - 6229, 0, 0, 0, 194593, 128907, 0, 0, 194592, 4120, 65337, 65336, 0, 0, 0, - 0, 9366, 0, 0, 0, 65327, 65326, 65325, 65324, 65323, 42216, 65321, 65320, + 0, 7206, 0, 6647, 43986, 129743, 0, 0, 122646, 0, 0, 127936, 43748, + 66746, 0, 12298, 110802, 984011, 110800, 64924, 0, 73931, 9468, 74245, 0, + 0, 74246, 0, 0, 118830, 0, 71851, 1279, 0, 6224, 0, 92405, 128601, + 129886, 128997, 0, 0, 0, 5032, 0, 0, 0, 0, 0, 5034, 0, 0, 72846, 42702, + 0, 0, 13294, 0, 64869, 0, 67808, 9129, 123632, 0, 0, 120819, 68387, + 120168, 120169, 120170, 120171, 5518, 4174, 120166, 66932, 120160, + 120161, 120162, 434, 41437, 66212, 120158, 120159, 0, 0, 118867, 0, 524, + 0, 74029, 0, 126559, 0, 0, 0, 10355, 10419, 74025, 77847, 0, 69725, 0, + 120656, 0, 67876, 0, 0, 0, 74145, 74039, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5445, 0, 93779, 71855, 7391, 8989, 0, 74068, 0, 0, 0, 0, 4962, 120409, + 8855, 0, 70820, 0, 0, 0, 0, 71847, 0, 120406, 0, 10451, 0, 67653, 120153, + 12443, 120155, 9947, 120149, 120150, 120151, 13128, 0, 120146, 120147, 0, + 0, 0, 0, 0, 129715, 74059, 74062, 6217, 74053, 43846, 0, 74049, 0, 0, 0, + 0, 0, 0, 0, 0, 42595, 0, 68112, 118860, 0, 0, 92497, 74949, 128953, + 126245, 0, 0, 0, 42997, 122984, 119251, 0, 0, 0, 0, 0, 6216, 0, 0, 9455, + 127027, 8124, 128851, 0, 6944, 0, 0, 0, 2828, 128550, 531, 42638, 0, 0, + 129888, 43428, 0, 3614, 2827, 9696, 0, 129711, 0, 4354, 0, 78562, 78561, + 0, 118553, 0, 42599, 42597, 0, 68829, 125012, 0, 127277, 0, 120421, 0, + 983165, 0, 0, 10121, 120422, 74950, 123142, 69715, 0, 0, 120423, 120630, + 12608, 125244, 0, 74144, 9700, 12580, 0, 128911, 0, 71864, 0, 74071, 0, + 0, 12713, 0, 70402, 0, 0, 0, 1734, 0, 0, 0, 119491, 118951, 231, 0, + 74167, 542, 0, 0, 0, 0, 128074, 0, 121343, 0, 4446, 10584, 74235, 0, + 4037, 0, 0, 0, 5687, 0, 0, 0, 0, 0, 0, 78434, 92816, 0, 113709, 74284, 0, + 0, 0, 126495, 0, 0, 0, 74482, 93978, 1709, 69721, 9909, 92286, 0, 0, 0, + 55229, 8667, 0, 0, 0, 0, 0, 0, 0, 0, 127586, 1226, 6930, 124146, 71736, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 41500, 0, 311, 74282, 6221, 92988, 0, 67682, + 0, 120528, 122901, 74272, 0, 0, 0, 0, 69667, 0, 124933, 74456, 74302, + 42589, 0, 0, 0, 0, 64847, 0, 66987, 0, 41508, 0, 323, 125211, 0, 42698, + 8131, 0, 4625, 0, 4630, 0, 0, 0, 74316, 78417, 2668, 92483, 0, 42640, 0, + 2519, 0, 92474, 92479, 0, 983085, 5049, 42659, 119011, 64705, 7754, + 10854, 8738, 74623, 0, 0, 0, 649, 0, 0, 73480, 0, 0, 1013, 70707, 68212, + 705, 0, 0, 127803, 1183, 126519, 9320, 0, 0, 8157, 0, 0, 0, 0, 0, 0, 0, + 11913, 0, 42848, 0, 64925, 0, 0, 70693, 0, 0, 2051, 0, 0, 0, 66988, 0, 0, + 0, 8466, 0, 4626, 8464, 8472, 68844, 4629, 8499, 0, 0, 4624, 194623, 0, + 94025, 0, 7805, 0, 94007, 6935, 0, 0, 0, 0, 0, 0, 0, 8492, 0, 8459, 0, + 8497, 8496, 0, 129864, 0, 0, 129834, 69553, 73476, 0, 65849, 0, 0, 0, + 12451, 3328, 8684, 0, 6102, 0, 5298, 110881, 5294, 0, 129615, 0, 0, 0, 0, + 43617, 0, 0, 0, 0, 0, 77863, 128695, 0, 0, 0, 0, 0, 5292, 0, 0, 42688, + 5302, 3970, 73516, 0, 1793, 0, 0, 0, 0, 0, 65263, 0, 0, 0, 0, 0, 0, + 13219, 9569, 69567, 74383, 0, 0, 72157, 0, 42949, 0, 0, 0, 5322, 0, 0, + 43631, 5324, 0, 128694, 41614, 65269, 6230, 0, 0, 0, 3360, 0, 11523, + 72726, 92488, 9926, 7197, 0, 68429, 126575, 41821, 1249, 0, 127951, 0, + 123641, 0, 0, 0, 74459, 41807, 0, 41815, 0, 0, 0, 119918, 0, 128248, 0, + 66835, 0, 0, 72145, 41800, 0, 0, 0, 41811, 74466, 93966, 6670, 77882, 0, + 0, 43092, 0, 0, 0, 0, 0, 128655, 0, 0, 0, 0, 74501, 74005, 0, 74387, + 69860, 315, 12813, 128556, 72409, 0, 72408, 0, 0, 73061, 0, 0, 1378, 0, + 0, 0, 72407, 3066, 0, 0, 72406, 0, 0, 0, 8787, 194615, 0, 41618, 0, 0, 0, + 194614, 64652, 194611, 42088, 125226, 0, 0, 0, 0, 7176, 43756, 0, 122649, + 74492, 0, 74534, 0, 0, 0, 127199, 0, 128630, 74525, 0, 194594, 12930, + 7168, 74514, 0, 74515, 0, 128919, 43962, 9527, 120659, 70123, 12977, + 69723, 0, 93783, 194598, 41236, 92235, 65168, 118838, 41237, 5848, 0, + 194600, 3670, 129905, 129906, 129907, 129908, 7890, 0, 11298, 0, 0, 6229, + 0, 0, 0, 194593, 128907, 0, 0, 194592, 4120, 65337, 65336, 0, 0, 0, 0, + 9366, 0, 0, 0, 65327, 65326, 65325, 65324, 65323, 42216, 65321, 65320, 65335, 65334, 65333, 65332, 65331, 65330, 65329, 42689, 0, 43943, 118885, 42073, 6785, 68491, 0, 42076, 7196, 65318, 2035, 65316, 4106, 65314, 65313, 42074, 0, 41228, 0, 0, 41241, 93786, 41239, 43533, 0, 7189, @@ -29233,161 +29430,161 @@ static const unsigned int code_hash[] = { 83043, 0, 68296, 0, 2823, 0, 0, 0, 2831, 0, 0, 11465, 0, 0, 0, 0, 0, 7181, 92855, 41332, 0, 12333, 0, 0, 0, 124914, 0, 9883, 127294, 73906, 70751, 0, 71863, 0, 0, 0, 0, 0, 0, 43741, 0, 8166, 70739, 0, 0, 74535, 0, - 65297, 68294, 571, 0, 8752, 0, 5288, 118822, 1541, 0, 127284, 8864, 0, 0, - 0, 0, 0, 113778, 12151, 0, 66874, 0, 1035, 0, 0, 7881, 701, 65936, - 128493, 0, 70462, 0, 11403, 0, 0, 82991, 0, 983142, 70472, 3994, 11421, + 65297, 68294, 571, 0, 8752, 0, 5288, 118822, 1541, 0, 127284, 8864, 0, + 73559, 0, 0, 0, 113778, 12151, 0, 66874, 0, 1035, 0, 0, 7881, 701, 65936, + 128493, 0, 70462, 0, 11403, 0, 0, 82991, 0, 983143, 70472, 3994, 11421, 121217, 127297, 127242, 127300, 70659, 127303, 0, 125205, 2855, 127828, 0, 41621, 68214, 0, 0, 10654, 82945, 119226, 12164, 41623, 7906, 0, 74297, 7182, 0, 83069, 0, 0, 0, 0, 121115, 0, 0, 747, 0, 92463, 12019, 43136, 0, 110861, 0, 0, 8001, 0, 0, 69394, 0, 0, 0, 68373, 0, 0, 0, - 128279, 0, 71915, 0, 0, 7282, 94066, 0, 0, 0, 0, 0, 5286, 83061, 0, 3718, - 0, 83057, 0, 124906, 71905, 0, 128480, 0, 0, 0, 0, 9206, 82980, 113824, - 6802, 0, 41653, 0, 1241, 0, 0, 0, 0, 68124, 41651, 42937, 0, 83042, - 41650, 0, 83037, 0, 12914, 2814, 0, 119552, 120691, 0, 0, 71968, 0, 0, 0, - 917546, 71862, 0, 0, 0, 3494, 10189, 69784, 0, 0, 71861, 0, 0, 65875, 0, - 0, 127762, 0, 74215, 43065, 0, 0, 7200, 0, 3261, 0, 0, 0, 65889, 71888, - 71975, 0, 0, 0, 0, 0, 77793, 0, 0, 129424, 77791, 635, 0, 0, 74753, 0, - 92420, 73997, 0, 0, 43905, 0, 118834, 126125, 0, 6667, 0, 983265, 0, 0, - 125200, 0, 0, 0, 0, 83137, 0, 0, 0, 0, 0, 121104, 127856, 125112, 71885, - 0, 120125, 7866, 194573, 92770, 194574, 0, 120140, 126074, 2849, 0, 0, - 42157, 12960, 0, 11812, 0, 74509, 0, 69881, 0, 0, 0, 123156, 7178, 0, 0, - 0, 0, 129041, 11534, 1967, 0, 0, 71361, 7015, 120298, 72757, 0, 12989, 0, - 9368, 983638, 1624, 43270, 0, 0, 10818, 0, 83091, 0, 120908, 0, 0, 0, 0, - 0, 0, 6169, 12871, 0, 2798, 65176, 4958, 42752, 119025, 0, 0, 0, 70346, - 66448, 0, 113780, 68364, 0, 0, 0, 68360, 0, 73746, 120945, 68352, 0, - 73787, 83110, 2154, 7199, 64955, 0, 0, 0, 0, 71980, 66507, 0, 69853, 0, - 0, 0, 0, 0, 0, 0, 92517, 118882, 120301, 13297, 0, 129446, 71963, 0, 0, - 0, 6658, 8045, 0, 0, 983873, 92319, 83101, 0, 72126, 0, 0, 0, 2416, 3310, - 0, 0, 379, 0, 43755, 0, 0, 0, 68362, 1284, 0, 73756, 0, 0, 83141, 70784, - 71977, 0, 0, 0, 8515, 83144, 83143, 0, 0, 0, 8529, 93782, 0, 7564, 0, 0, - 0, 0, 73757, 73760, 42359, 0, 2031, 0, 7202, 129984, 12676, 0, 0, 128418, - 0, 7710, 1610, 73801, 0, 0, 118706, 983607, 43917, 0, 9974, 228, 0, - 10398, 0, 0, 0, 92241, 70062, 118927, 42999, 1725, 65533, 8196, 9352, 0, - 0, 66868, 0, 8502, 5762, 0, 0, 43898, 0, 0, 0, 0, 43914, 0, 126507, - 64598, 13001, 9326, 83082, 43916, 1557, 0, 983879, 6330, 6805, 8631, - 2545, 70052, 0, 0, 0, 42998, 70410, 0, 42762, 71941, 42914, 126516, 262, - 1637, 0, 83025, 129491, 83026, 128757, 0, 0, 0, 128922, 0, 43658, 0, 0, - 129183, 6419, 0, 0, 0, 0, 93989, 0, 128173, 7194, 5291, 67395, 43666, 0, - 0, 0, 0, 128293, 0, 12881, 123596, 0, 73842, 0, 9011, 0, 0, 0, 70436, - 179, 43644, 0, 0, 64747, 0, 118813, 0, 0, 121389, 92649, 126629, 0, - 73850, 2801, 119837, 42069, 119839, 119838, 119841, 42072, 92736, 119842, - 0, 0, 0, 8377, 0, 42070, 119313, 119834, 119310, 4389, 43656, 1633, - 119857, 118632, 119859, 11119, 119845, 119844, 9967, 119846, 119849, - 4612, 92867, 119850, 42913, 70456, 0, 71983, 10782, 66898, 0, 119141, 0, - 0, 0, 11541, 69636, 0, 0, 119614, 2731, 0, 0, 0, 4102, 0, 73878, 0, 0, 0, - 0, 0, 11283, 0, 0, 0, 0, 0, 43674, 0, 0, 126705, 0, 0, 0, 0, 11142, - 128304, 0, 12975, 0, 123208, 0, 0, 74072, 0, 55269, 0, 0, 0, 78577, - 78576, 0, 0, 82966, 82974, 70448, 0, 0, 82968, 0, 0, 0, 0, 0, 113809, 0, - 69399, 64909, 0, 11790, 74019, 0, 128066, 0, 8561, 94076, 129481, 125045, - 69259, 65674, 7230, 0, 0, 8778, 0, 0, 67725, 2071, 0, 6459, 68325, 7628, - 65092, 73903, 0, 11342, 129388, 0, 0, 93965, 94081, 0, 11810, 70057, - 10723, 967, 0, 71973, 73905, 0, 6387, 0, 12307, 43913, 121089, 0, 127584, - 0, 1886, 0, 43895, 870, 7648, 0, 7662, 7652, 876, 871, 877, 7665, 878, - 42015, 879, 43692, 4563, 0, 0, 0, 73072, 867, 9520, 872, 7656, 868, 873, - 7642, 7659, 869, 874, 7644, 0, 875, 790, 0, 0, 0, 0, 0, 124899, 0, 0, 0, - 0, 0, 68452, 0, 0, 42067, 0, 0, 0, 12292, 0, 0, 0, 42012, 0, 0, 83388, 0, - 0, 8494, 4611, 0, 72344, 0, 9679, 0, 0, 0, 0, 93015, 0, 74364, 4628, - 4245, 0, 0, 0, 1851, 0, 127189, 0, 0, 0, 118897, 0, 64674, 124971, - 983887, 8829, 983693, 128864, 0, 0, 0, 0, 8809, 983696, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7427, 0, 4588, 43680, 72300, 74484, 0, 0, 0, 0, 113787, 74363, - 129043, 0, 793, 0, 11197, 0, 0, 0, 842, 0, 8208, 70833, 0, 1647, 0, - 70841, 0, 0, 818, 0, 0, 0, 0, 0, 0, 120594, 0, 0, 70179, 0, 13167, 66359, - 0, 127172, 0, 4969, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2840, 0, 0, 0, 66887, - 65877, 9068, 0, 68194, 0, 0, 12991, 0, 2651, 68016, 983915, 0, 983261, - 70835, 0, 70844, 43648, 0, 0, 0, 0, 0, 0, 64372, 121064, 7458, 655, 752, - 7457, 7456, 7452, 3285, 74894, 11152, 73099, 0, 2391, 93766, 92271, 671, - 7435, 7434, 618, 668, 610, 42800, 7431, 7451, 42801, 640, 42927, 7448, - 7439, 628, 3905, 100742, 0, 0, 0, 67850, 0, 0, 0, 4605, 0, 100745, 43372, - 65945, 72710, 0, 119590, 0, 0, 70495, 987, 71229, 11572, 0, 0, 10002, - 9971, 70673, 0, 0, 0, 0, 0, 0, 11334, 0, 129493, 42364, 11503, 0, 0, 0, - 4627, 70090, 127784, 0, 0, 74046, 68872, 92562, 0, 0, 129900, 0, 129812, - 0, 0, 42569, 64965, 0, 0, 10516, 129828, 12190, 0, 42140, 0, 0, 0, 0, - 9887, 0, 4000, 7429, 7428, 665, 7424, 0, 0, 7884, 0, 0, 0, 0, 0, 2509, 0, - 120573, 0, 0, 92449, 0, 10690, 0, 119114, 126226, 0, 0, 73080, 4590, 0, - 74440, 0, 0, 0, 1708, 0, 0, 983609, 0, 0, 69226, 69974, 8813, 0, 1066, 0, - 0, 71965, 127921, 70447, 0, 0, 0, 2202, 0, 7516, 0, 0, 0, 8034, 0, 0, - 3631, 110696, 0, 0, 8416, 110694, 71937, 0, 0, 110692, 74621, 0, 70185, - 0, 74850, 0, 0, 12099, 70475, 0, 6252, 0, 0, 0, 0, 0, 0, 66368, 0, 64956, - 7071, 129070, 70457, 128159, 118800, 0, 77757, 0, 9357, 0, 1773, 0, - 125092, 0, 68451, 7745, 9844, 0, 0, 94, 1880, 120929, 0, 0, 0, 0, 0, 0, - 0, 0, 11237, 0, 129173, 0, 0, 0, 1757, 6964, 42480, 72823, 0, 120806, 0, - 0, 7731, 0, 0, 127883, 0, 77777, 43988, 70423, 74758, 0, 7592, 856, - 74299, 0, 0, 0, 78138, 1459, 0, 0, 0, 0, 0, 1504, 0, 0, 0, 0, 7529, 0, 0, - 0, 0, 12594, 0, 0, 336, 0, 7509, 0, 0, 0, 0, 127882, 0, 0, 0, 65859, 0, - 983986, 43062, 124948, 0, 0, 0, 0, 12970, 0, 0, 0, 0, 0, 0, 0, 119247, 0, - 65068, 74291, 129943, 7069, 0, 0, 66977, 11130, 2087, 0, 0, 0, 0, 126249, - 0, 92747, 0, 92614, 2091, 0, 2090, 0, 0, 7117, 2077, 72281, 0, 77889, - 2083, 0, 71196, 0, 0, 71981, 0, 0, 0, 0, 4165, 8746, 0, 0, 0, 0, 129572, - 7066, 77779, 70415, 128135, 0, 0, 7786, 127766, 2233, 0, 124965, 121122, - 2302, 0, 0, 7056, 0, 0, 0, 0, 118639, 0, 126506, 6920, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 983099, 70438, 2613, 0, 0, 110734, 0, 74571, 42760, 0, 0, 0, - 0, 0, 0, 71843, 0, 0, 70506, 1246, 74243, 0, 0, 41008, 0, 0, 0, 921, - 70048, 0, 12702, 0, 0, 1566, 8407, 0, 64653, 0, 74617, 0, 0, 72711, 5313, - 951, 0, 0, 0, 0, 77807, 4009, 70277, 71844, 0, 83123, 0, 72250, 0, - 119898, 113760, 0, 0, 0, 0, 70024, 0, 0, 119892, 0, 0, 0, 119890, 2579, - 119906, 3177, 11357, 69224, 0, 0, 83130, 64734, 0, 9822, 110670, 70471, - 110668, 66990, 110666, 66967, 0, 0, 0, 9851, 983748, 110673, 9059, - 110671, 77736, 0, 41687, 129054, 0, 71842, 70178, 0, 66975, 1777, 67003, - 10158, 69767, 0, 42366, 70444, 0, 0, 0, 70127, 71955, 5989, 110716, - 74636, 126999, 0, 41685, 0, 0, 9769, 41684, 0, 6225, 111328, 11740, 0, - 118840, 0, 2600, 0, 70416, 0, 118720, 3666, 70420, 127193, 71976, 0, 0, - 74542, 69771, 0, 0, 0, 0, 0, 69765, 77804, 252, 0, 69769, 0, 194616, 0, - 69763, 0, 0, 0, 0, 0, 0, 0, 120947, 0, 129410, 0, 118792, 0, 68323, - 125219, 0, 119188, 0, 2177, 121335, 0, 0, 0, 0, 0, 7764, 983745, 11094, - 120825, 0, 0, 92505, 8298, 0, 0, 0, 0, 0, 64449, 0, 126650, 0, 0, 0, - 70442, 0, 0, 0, 0, 7774, 10607, 0, 0, 0, 0, 0, 120764, 0, 0, 77746, 0, - 3458, 0, 70053, 0, 120995, 0, 2602, 0, 0, 0, 74907, 0, 0, 0, 0, 172, 0, - 4971, 70419, 1889, 7238, 0, 0, 0, 8257, 0, 0, 0, 129570, 0, 111342, - 71948, 0, 43366, 43363, 9807, 0, 0, 0, 72247, 64479, 0, 0, 0, 113707, 0, - 10900, 121355, 0, 0, 12048, 0, 64292, 0, 0, 0, 6099, 94084, 129486, 0, 0, - 299, 0, 8525, 92356, 0, 0, 111338, 0, 92564, 3075, 0, 94053, 0, 94050, 0, - 0, 70440, 0, 123590, 0, 0, 0, 2581, 11395, 0, 0, 0, 0, 128584, 0, 0, - 129423, 101092, 118855, 0, 0, 0, 7204, 70065, 2588, 2914, 7011, 55281, 0, - 7466, 0, 2883, 42253, 83118, 0, 0, 0, 123598, 0, 41230, 68299, 0, 43571, - 0, 6219, 0, 9980, 41232, 92245, 0, 66036, 41229, 118967, 0, 120666, - 94016, 0, 12711, 0, 0, 74289, 68472, 42857, 66950, 0, 0, 0, 127306, - 119006, 0, 11380, 72348, 0, 0, 0, 0, 0, 0, 0, 983579, 12722, 0, 922, 0, - 0, 983126, 74958, 3218, 120471, 120470, 120469, 120476, 120475, 8569, - 11404, 70450, 120463, 3214, 120461, 120468, 74910, 3207, 120465, 78729, - 78728, 78727, 0, 120460, 7425, 3205, 0, 78737, 78736, 71729, 43383, - 78733, 78732, 2606, 78730, 73897, 0, 11496, 1173, 0, 0, 129135, 0, 0, 0, - 120737, 120953, 120872, 120629, 378, 2610, 0, 0, 0, 0, 0, 37, 7068, 0, - 120480, 70421, 3209, 120477, 0, 120483, 9768, 120481, 0, 0, 0, 0, 0, 0, - 65510, 0, 100625, 0, 0, 0, 100627, 0, 126633, 0, 7060, 100628, 0, 127752, - 0, 69284, 70428, 71463, 0, 7380, 0, 0, 100593, 126997, 0, 124900, 0, - 71465, 121030, 3243, 0, 0, 0, 7050, 0, 70050, 0, 0, 0, 71466, 8203, - 71102, 68241, 0, 65211, 194599, 983403, 118636, 0, 779, 125061, 64367, - 100906, 69901, 8193, 55279, 0, 0, 0, 7065, 0, 4346, 0, 0, 908, 0, 0, - 8982, 0, 0, 0, 782, 0, 10883, 0, 0, 129396, 65542, 121302, 0, 68650, - 100575, 92244, 0, 0, 111351, 0, 4376, 0, 11787, 12961, 0, 0, 42888, 0, - 100610, 6231, 0, 65713, 100608, 1783, 0, 68238, 0, 0, 0, 194945, 0, 0, 0, - 68653, 0, 983051, 0, 764, 0, 0, 43531, 0, 9033, 0, 0, 6223, 11042, 0, 0, - 0, 0, 0, 917792, 0, 0, 0, 0, 0, 0, 120648, 0, 0, 0, 0, 0, 0, 71971, 0, - 1478, 0, 11825, 2607, 0, 0, 0, 74543, 0, 0, 100588, 6132, 0, 0, 0, 70058, - 0, 0, 0, 43537, 6761, 10093, 4369, 0, 0, 73735, 100564, 3947, 110778, 0, - 0, 0, 0, 100942, 0, 0, 0, 0, 0, 0, 7686, 0, 0, 0, 100934, 0, 100944, - 66577, 41221, 0, 42281, 0, 74024, 12293, 0, 94014, 11794, 0, 120893, - 1737, 0, 0, 0, 7205, 0, 9335, 12850, 77810, 2272, 7055, 0, 0, 0, 67751, - 0, 124910, 6780, 65067, 0, 1327, 68393, 983574, 0, 41217, 0, 10018, 0, 0, - 0, 100611, 68176, 41219, 0, 4147, 983170, 41216, 983712, 2616, 70197, - 68461, 65234, 0, 0, 0, 0, 119660, 0, 0, 0, 0, 127930, 119580, 70675, - 64943, 2608, 1470, 0, 0, 6227, 0, 0, 74775, 0, 0, 72320, 101024, 0, - 73822, 67456, 0, 0, 0, 0, 10876, 92482, 0, 0, 5834, 0, 6222, 0, 0, 12086, - 0, 1600, 64309, 0, 0, 68883, 127957, 93836, 0, 8882, 0, 129415, 2570, 0, - 0, 194606, 0, 0, 1234, 0, 13115, 110743, 110740, 100923, 5002, 110739, - 41286, 100926, 127019, 0, 0, 0, 0, 0, 0, 0, 41289, 0, 0, 75051, 41272, 0, - 0, 0, 0, 0, 124978, 0, 41279, 0, 0, 0, 11081, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9637, 7112, 77975, 128984, 0, 10886, 0, 8548, 983860, 0, 0, 0, 8076, - 43048, 8290, 8291, 43051, 92570, 0, 2596, 0, 0, 41293, 0, 0, 2393, 7058, - 66432, 0, 68673, 0, 0, 0, 0, 0, 128558, 0, 0, 0, 0, 0, 64696, 0, 0, - 121086, 74165, 0, 0, 0, 0, 0, 0, 7063, 983182, 64893, 73096, 0, 68038, - 113757, 709, 0, 0, 1876, 0, 0, 120868, 8137, 110662, 67752, 70850, - 100832, 245, 100831, 11456, 41233, 7070, 0, 94046, 6136, 100835, 0, - 100781, 41235, 0, 0, 100782, 100642, 432, 0, 100784, 65437, 0, 100647, - 128909, 0, 100641, 100649, 0, 100648, 0, 43215, 0, 0, 0, 0, 9052, 0, 0, - 110826, 110827, 74784, 10580, 0, 100845, 0, 64640, 983175, 74455, 0, - 129670, 70035, 0, 12652, 12199, 127030, 0, 2566, 11971, 0, 0, 1065, 0, 0, - 0, 2576, 0, 66819, 0, 984005, 129852, 0, 0, 983050, 983845, 0, 2921, + 128279, 0, 71915, 0, 129742, 7282, 94066, 0, 0, 0, 0, 0, 5286, 83061, 0, + 3718, 0, 83057, 78933, 124906, 71905, 0, 128480, 0, 0, 0, 0, 9206, 82980, + 113824, 6802, 0, 41653, 0, 1241, 0, 0, 0, 0, 68124, 41651, 42937, 0, + 83042, 41650, 0, 83037, 0, 12914, 2814, 0, 119552, 120691, 0, 0, 71968, + 0, 0, 0, 917546, 71862, 0, 0, 0, 3494, 10189, 69784, 0, 0, 71861, 0, 0, + 65875, 0, 0, 127762, 0, 74215, 43065, 0, 0, 7200, 0, 3261, 0, 0, 0, + 65889, 71888, 71975, 0, 0, 0, 0, 0, 77793, 0, 0, 129424, 77791, 635, 0, + 0, 74753, 0, 92420, 73997, 0, 0, 43905, 0, 118834, 126125, 0, 6667, 0, + 983268, 0, 0, 125200, 0, 0, 0, 0, 83137, 0, 0, 0, 0, 0, 121104, 127856, + 125112, 71885, 0, 120125, 7866, 194573, 92770, 194574, 0, 120140, 126074, + 2849, 0, 0, 42157, 12960, 0, 11812, 0, 74509, 0, 69881, 0, 0, 0, 123156, + 7178, 0, 0, 0, 0, 129041, 11534, 1967, 0, 0, 71361, 7015, 120298, 72757, + 0, 12989, 0, 9368, 983638, 1624, 43270, 0, 0, 10818, 0, 83091, 0, 120908, + 0, 0, 0, 0, 0, 0, 6169, 12871, 0, 2798, 65176, 4958, 42752, 119025, 0, 0, + 0, 70346, 66448, 0, 113780, 68364, 0, 0, 0, 68360, 0, 73746, 120945, + 68352, 0, 73787, 83110, 2154, 7199, 64955, 0, 0, 0, 0, 71980, 66507, 0, + 69853, 0, 0, 0, 0, 0, 0, 0, 92517, 118882, 120301, 13297, 0, 129446, + 71963, 0, 0, 0, 6658, 8045, 0, 0, 983873, 92319, 83101, 0, 72126, 0, 0, + 0, 2416, 3310, 0, 0, 379, 0, 43755, 0, 0, 0, 68362, 1284, 0, 73756, 0, 0, + 83141, 70784, 71977, 0, 0, 0, 8515, 83144, 83143, 0, 0, 0, 8529, 93782, + 0, 7564, 0, 0, 0, 0, 73757, 73760, 42359, 0, 2031, 0, 7202, 129984, + 12676, 0, 0, 128418, 0, 7710, 1610, 73801, 0, 0, 118706, 983607, 43917, + 0, 9974, 228, 0, 10398, 0, 0, 0, 92241, 70062, 118927, 42999, 1725, + 65533, 8196, 9352, 0, 0, 66868, 0, 8502, 5762, 0, 0, 43898, 0, 0, 0, 0, + 43914, 0, 126507, 64598, 13001, 9326, 83082, 43916, 1557, 0, 983879, + 6330, 6805, 8631, 2545, 70052, 0, 0, 0, 42998, 70410, 0, 42762, 71941, + 42914, 126516, 262, 1637, 0, 83025, 129491, 83026, 128757, 0, 0, 0, + 128922, 0, 43658, 0, 0, 129183, 6419, 0, 0, 0, 0, 93989, 0, 128173, 7194, + 5291, 67395, 43666, 0, 0, 0, 0, 128293, 0, 12881, 123596, 0, 73842, 0, + 9011, 0, 0, 0, 70436, 179, 43644, 0, 0, 64747, 0, 118813, 0, 0, 121389, + 92649, 126629, 0, 73850, 2801, 119495, 42069, 119839, 119838, 119841, + 42072, 92736, 119842, 0, 0, 0, 8377, 0, 42070, 119313, 119834, 119310, + 4389, 43656, 1633, 119857, 118632, 119859, 11119, 119845, 119844, 9967, + 119846, 119849, 4612, 92867, 119850, 42913, 70456, 0, 71983, 10782, + 66898, 0, 119141, 0, 0, 0, 11541, 69636, 0, 0, 119614, 2731, 0, 0, 0, + 4102, 0, 73878, 0, 0, 0, 0, 0, 11283, 0, 0, 0, 0, 0, 43674, 0, 0, 126705, + 0, 0, 0, 0, 11142, 128304, 0, 12975, 0, 123208, 0, 0, 74072, 0, 55269, 0, + 0, 0, 78577, 78576, 0, 0, 82966, 82974, 70448, 0, 0, 82968, 0, 0, 0, 0, + 0, 113809, 0, 69399, 64909, 0, 11790, 74019, 0, 128066, 0, 8561, 94076, + 129481, 125045, 69259, 65674, 7230, 0, 0, 8778, 0, 0, 67725, 2071, 0, + 6459, 68325, 7628, 65092, 73903, 0, 11342, 129388, 0, 0, 93965, 94081, 0, + 11810, 70057, 10723, 967, 0, 71973, 73905, 0, 6387, 0, 12307, 43913, + 121089, 0, 127584, 0, 1886, 0, 43895, 870, 7648, 0, 7662, 7652, 876, 871, + 877, 7665, 878, 42015, 879, 43692, 4563, 0, 0, 0, 73072, 867, 9520, 872, + 7656, 868, 873, 7642, 7659, 869, 874, 7644, 0, 875, 790, 0, 0, 0, 0, 0, + 124899, 0, 0, 0, 0, 0, 68452, 0, 0, 42067, 0, 0, 0, 12292, 0, 0, 0, + 42012, 0, 0, 83388, 0, 0, 8494, 4611, 0, 72344, 0, 9679, 0, 0, 0, 0, + 93015, 0, 74364, 4628, 4245, 0, 0, 0, 1851, 0, 127189, 0, 0, 0, 118897, + 0, 64674, 124971, 983887, 8829, 983693, 128864, 0, 0, 0, 0, 8809, 983696, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 7427, 0, 4588, 43680, 72300, 74484, 0, 0, 0, + 0, 113787, 74363, 129043, 0, 793, 0, 11197, 0, 0, 0, 842, 0, 8208, 70833, + 0, 1647, 0, 70841, 0, 73508, 818, 0, 0, 0, 0, 0, 0, 120594, 0, 0, 70179, + 0, 13167, 66359, 0, 127172, 0, 4969, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2840, 0, + 0, 0, 66887, 65877, 9068, 0, 68194, 0, 0, 12991, 0, 2651, 68016, 983915, + 0, 983264, 70835, 0, 70844, 43648, 0, 0, 0, 0, 0, 0, 64372, 121064, 7458, + 655, 752, 7457, 7456, 7452, 3285, 74894, 11152, 73099, 0, 2391, 93766, + 92271, 671, 7435, 7434, 618, 668, 610, 42800, 7431, 7451, 42801, 640, + 42927, 7448, 7439, 628, 3905, 100742, 0, 0, 0, 67850, 0, 0, 0, 4605, 0, + 100745, 43372, 65945, 72710, 0, 119590, 0, 0, 70495, 987, 71229, 11572, + 0, 0, 10002, 9971, 70673, 0, 0, 0, 0, 0, 0, 11334, 0, 129493, 42364, + 11503, 0, 0, 0, 4627, 70090, 127784, 73473, 0, 74046, 68872, 92562, 0, 0, + 129900, 0, 129812, 0, 0, 42569, 64965, 0, 0, 10516, 129828, 12190, 0, + 42140, 0, 0, 0, 0, 9887, 0, 4000, 7429, 7428, 665, 7424, 0, 0, 7884, 0, + 0, 0, 0, 0, 2509, 0, 120573, 0, 0, 92449, 0, 10690, 0, 119114, 126226, 0, + 0, 73080, 4590, 0, 74440, 0, 0, 0, 1708, 0, 0, 983609, 0, 0, 69226, + 69974, 8813, 0, 1066, 0, 0, 71965, 127921, 70447, 0, 0, 0, 2202, 0, 7516, + 0, 0, 0, 8034, 0, 0, 3631, 110696, 0, 0, 8416, 110694, 71937, 0, 0, + 110692, 74621, 0, 70185, 0, 74850, 0, 0, 12099, 70475, 0, 6252, 0, 0, 0, + 0, 0, 0, 66368, 0, 64956, 7071, 129070, 70457, 128159, 118800, 0, 77757, + 0, 9357, 0, 1773, 0, 125092, 0, 68451, 7745, 9844, 0, 0, 94, 1880, + 120929, 0, 0, 0, 0, 0, 0, 0, 0, 11237, 0, 129173, 0, 0, 0, 1757, 6964, + 42480, 72823, 0, 120806, 0, 0, 7731, 0, 0, 127883, 0, 77777, 43988, + 70423, 74758, 0, 7592, 856, 74299, 0, 0, 0, 78138, 1459, 0, 0, 0, 0, 0, + 1504, 0, 0, 0, 0, 7529, 0, 0, 0, 0, 12594, 0, 0, 336, 0, 7509, 0, 0, 0, + 0, 127882, 0, 0, 0, 65859, 0, 983986, 43062, 124948, 0, 0, 0, 0, 12970, + 0, 0, 0, 0, 0, 0, 0, 119247, 0, 65068, 74291, 122938, 7069, 0, 0, 66977, + 11130, 2087, 0, 0, 0, 0, 126249, 0, 92747, 0, 92614, 2091, 0, 2090, 0, 0, + 7117, 2077, 72281, 0, 77889, 2083, 0, 71196, 0, 0, 71981, 0, 0, 0, 0, + 4165, 8746, 0, 0, 0, 0, 129572, 7066, 77779, 70415, 128135, 0, 0, 7786, + 127766, 2233, 0, 124965, 121122, 2302, 0, 0, 7056, 0, 0, 0, 0, 118639, 0, + 126506, 6920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 983099, 70438, 2613, 0, 0, + 110734, 0, 74571, 42760, 0, 0, 0, 0, 0, 0, 71843, 0, 0, 70506, 1246, + 74243, 0, 0, 41008, 0, 0, 0, 921, 70048, 0, 12702, 119500, 0, 1566, 8407, + 0, 64653, 0, 74617, 0, 0, 72711, 5313, 951, 0, 0, 0, 0, 77807, 4009, + 70277, 71844, 0, 83123, 0, 72250, 0, 119898, 113760, 0, 0, 0, 0, 70024, + 0, 0, 119892, 0, 0, 0, 119890, 2579, 119906, 3177, 11357, 69224, 0, 0, + 83130, 64734, 0, 9822, 110670, 70471, 110668, 66990, 110666, 66967, 0, 0, + 0, 9851, 983748, 110673, 9059, 110671, 77736, 0, 41687, 129054, 0, 71842, + 70178, 0, 66975, 1777, 67003, 10158, 69767, 122982, 42366, 70444, 0, 0, + 0, 70127, 71955, 5989, 110716, 74636, 126999, 0, 41685, 0, 0, 9769, + 41684, 0, 6225, 111328, 11740, 0, 118840, 0, 2600, 0, 70416, 0, 118720, + 3666, 70420, 127193, 71976, 0, 0, 74542, 69771, 0, 0, 0, 0, 0, 69765, + 77804, 252, 0, 69769, 0, 194616, 0, 69763, 0, 0, 0, 0, 0, 0, 0, 120947, + 0, 129410, 0, 118792, 0, 68323, 125219, 0, 119188, 0, 2177, 121335, 0, 0, + 0, 0, 0, 7764, 983745, 11094, 120825, 119490, 0, 92505, 8298, 0, 0, 0, 0, + 0, 64449, 0, 126650, 0, 0, 0, 70442, 0, 0, 0, 0, 7774, 10607, 0, 0, 0, 0, + 0, 120764, 0, 0, 77746, 0, 3458, 0, 70053, 0, 120995, 0, 2602, 0, 0, 0, + 74907, 0, 0, 0, 0, 172, 0, 4971, 70419, 1889, 7238, 0, 0, 0, 8257, 0, 0, + 78917, 129570, 0, 111342, 71948, 0, 43366, 43363, 9807, 0, 0, 0, 72247, + 64479, 0, 0, 0, 113707, 0, 10900, 121355, 0, 0, 12048, 0, 64292, 0, 0, 0, + 6099, 94084, 129486, 0, 0, 299, 0, 8525, 92356, 0, 0, 111338, 0, 92564, + 3075, 0, 94053, 0, 94050, 0, 0, 70440, 0, 123590, 0, 0, 0, 2581, 11395, + 0, 0, 0, 0, 128584, 0, 0, 129423, 101092, 118855, 0, 0, 0, 7204, 70065, + 2588, 2914, 7011, 55281, 0, 7466, 0, 2883, 42253, 83118, 0, 0, 0, 83116, + 0, 41230, 68299, 0, 43571, 0, 6219, 0, 9980, 41232, 92245, 0, 66036, + 41229, 118967, 0, 120666, 94016, 0, 12711, 0, 0, 74289, 68472, 42857, + 66950, 0, 0, 0, 127306, 119006, 0, 11380, 72348, 0, 0, 0, 0, 0, 0, 0, + 983579, 12722, 0, 922, 0, 0, 983127, 74958, 3218, 120471, 120470, 120469, + 120476, 120475, 8569, 11404, 70450, 120463, 3214, 120461, 120468, 74910, + 3207, 120465, 78729, 78728, 78727, 0, 120460, 7425, 3205, 0, 78737, + 78736, 71729, 43383, 78733, 78732, 2606, 78730, 73897, 0, 11496, 1173, 0, + 0, 129135, 0, 0, 0, 120737, 120953, 120872, 120629, 378, 2610, 0, 0, 0, + 0, 0, 37, 7068, 0, 120480, 70421, 3209, 120477, 0, 120483, 9768, 120481, + 0, 0, 0, 0, 0, 0, 65510, 0, 100625, 0, 0, 0, 100627, 0, 126633, 0, 7060, + 100628, 0, 127752, 0, 69284, 70428, 71463, 0, 7380, 0, 0, 100593, 126997, + 0, 124900, 0, 71465, 121030, 3243, 0, 0, 0, 7050, 0, 70050, 0, 0, 122983, + 71466, 8203, 71102, 68241, 0, 65211, 194599, 983406, 118636, 0, 779, + 125061, 64367, 100906, 69901, 8193, 55279, 0, 0, 0, 7065, 0, 4346, 0, 0, + 908, 0, 0, 8982, 0, 0, 0, 782, 0, 10883, 0, 0, 129396, 65542, 121302, 0, + 68650, 100575, 92244, 0, 0, 111351, 0, 4376, 0, 11787, 12961, 0, 0, + 42888, 0, 100610, 6231, 0, 65713, 100608, 1783, 0, 68238, 0, 0, 0, + 194945, 0, 0, 0, 68653, 0, 983051, 0, 764, 0, 0, 43531, 0, 9033, 0, 0, + 6223, 11042, 0, 0, 0, 0, 0, 917792, 0, 0, 0, 0, 0, 0, 120648, 0, 0, 0, 0, + 0, 0, 71971, 0, 1478, 78923, 11825, 2607, 0, 0, 0, 74543, 0, 0, 100588, + 6132, 0, 0, 0, 70058, 0, 0, 0, 43537, 6761, 10093, 4369, 0, 0, 73735, + 100564, 3947, 110778, 0, 0, 0, 0, 100942, 0, 0, 0, 0, 0, 0, 7686, 0, 0, + 0, 100934, 0, 100944, 66577, 41221, 0, 42281, 0, 74024, 12293, 0, 94014, + 11794, 0, 120893, 1737, 0, 0, 0, 7205, 0, 9335, 12850, 77810, 2272, 7055, + 0, 0, 0, 67751, 0, 124910, 6780, 65067, 0, 1327, 68393, 983574, 0, 41217, + 0, 10018, 0, 0, 0, 100611, 68176, 41219, 0, 4147, 983171, 41216, 983712, + 2616, 70197, 68461, 65234, 0, 0, 0, 0, 119660, 0, 0, 0, 0, 127930, + 119580, 70675, 64943, 2608, 1470, 0, 0, 6227, 0, 0, 74775, 0, 0, 72320, + 101024, 0, 73822, 67456, 0, 0, 0, 0, 10876, 92482, 0, 0, 5834, 0, 6222, + 0, 0, 12086, 0, 1600, 64309, 0, 0, 68883, 127957, 93836, 0, 8882, 0, + 129415, 2570, 0, 0, 194606, 0, 0, 1234, 0, 13115, 110743, 110740, 100923, + 5002, 110739, 41286, 100926, 127019, 0, 0, 0, 0, 0, 0, 0, 41289, 0, 0, + 75051, 41272, 0, 0, 0, 0, 0, 124978, 0, 41279, 0, 0, 0, 11081, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9637, 7112, 77975, 128984, 0, 10886, 0, 8548, 983860, + 0, 0, 0, 8076, 43048, 8290, 8291, 43051, 92570, 0, 2596, 0, 0, 41293, 0, + 0, 2393, 7058, 66432, 0, 68673, 0, 0, 0, 0, 0, 128558, 0, 0, 0, 0, 0, + 64696, 0, 0, 121086, 74165, 0, 0, 0, 0, 0, 0, 7063, 983183, 64893, 73096, + 0, 68038, 113757, 709, 0, 0, 1876, 0, 0, 120868, 8137, 110662, 67752, + 70850, 100832, 245, 100831, 11456, 41233, 7070, 0, 94046, 6136, 100835, + 0, 100781, 41235, 73474, 0, 100782, 100642, 432, 0, 100784, 65437, 0, + 100647, 128909, 0, 100641, 100649, 0, 100648, 0, 43215, 0, 0, 0, 0, 9052, + 0, 0, 110826, 110827, 74784, 10580, 0, 100845, 0, 64640, 983176, 74455, + 0, 129670, 70035, 0, 12652, 12199, 127030, 0, 2566, 11971, 0, 0, 1065, 0, + 0, 0, 2576, 0, 66819, 0, 984005, 129852, 0, 0, 983050, 983845, 0, 2921, 119104, 0, 5772, 12968, 70055, 0, 0, 0, 2580, 983841, 0, 0, 70032, 0, 0, 0, 128148, 0, 0, 121308, 11346, 0, 12054, 100824, 92426, 101112, 0, 13091, 0, 0, 100821, 100828, 0, 127026, 128334, 74821, 0, 66295, 68037, @@ -29395,13 +29592,13 @@ static const unsigned int code_hash[] = { 100776, 119319, 42356, 42432, 100778, 92823, 0, 0, 0, 78752, 70030, 66914, 0, 0, 7061, 0, 3854, 0, 70020, 68413, 0, 42319, 0, 0, 7067, 0, 0, 0, 0, 0, 0, 127797, 9029, 43543, 92820, 2353, 119316, 0, 100769, 0, - 100768, 983177, 0, 0, 43664, 0, 0, 0, 12277, 0, 78122, 11066, 65233, 0, + 100768, 983178, 0, 0, 43664, 0, 0, 0, 12277, 0, 78122, 11066, 65233, 0, 41224, 0, 0, 3747, 10522, 0, 77722, 1691, 41226, 0, 77724, 0, 41223, 121135, 121299, 697, 0, 121051, 4244, 0, 0, 0, 13121, 128573, 0, 0, 0, 0, 0, 0, 129879, 0, 65816, 68111, 0, 127933, 0, 0, 0, 0, 0, 0, 66895, 74602, 0, 7123, 70038, 5785, 9198, 0, 100810, 0, 7383, 64656, 0, 0, 0, 0, 0, 0, 0, 0, 13122, 0, 191, 70060, 8585, 126610, 64411, 0, 0, 64850, 41072, - 118996, 0, 0, 0, 0, 100754, 127010, 100753, 0, 100756, 683, 396, 0, + 118996, 0, 0, 0, 0, 78907, 127010, 100753, 0, 100756, 683, 396, 0, 100758, 0, 100757, 43058, 100760, 343, 7129, 42680, 0, 0, 0, 0, 0, 100761, 0, 74040, 0, 1724, 0, 119321, 0, 0, 2203, 0, 0, 0, 6592, 0, 983044, 0, 0, 0, 0, 3730, 1778, 0, 0, 128854, 121254, 0, 9018, 0, 0, 0, @@ -29410,269 +29607,272 @@ static const unsigned int code_hash[] = { 101084, 0, 92812, 68800, 42471, 0, 0, 67232, 64304, 42243, 101094, 2583, 0, 77728, 0, 0, 0, 71702, 3855, 0, 0, 0, 0, 0, 0, 0, 92416, 7132, 0, 92743, 0, 64756, 3798, 6578, 0, 0, 92481, 9774, 1275, 0, 119273, 983056, - 0, 120515, 7873, 77719, 0, 0, 0, 77717, 0, 73994, 73992, 0, 0, 0, 41851, - 0, 41846, 126485, 92337, 7633, 41849, 68385, 70726, 3224, 0, 69806, 0, 0, - 0, 1510, 68129, 0, 0, 0, 0, 12109, 0, 0, 0, 0, 0, 78377, 1910, 8671, - 78374, 127118, 70290, 0, 0, 0, 2654, 7893, 0, 0, 0, 72394, 0, 67394, 0, - 118970, 70066, 78372, 78371, 78370, 78369, 78368, 0, 0, 0, 1733, 0, 2568, - 0, 0, 0, 0, 41486, 0, 127839, 7116, 0, 0, 0, 7185, 0, 0, 0, 0, 0, 120575, - 120829, 0, 0, 0, 0, 92489, 0, 0, 0, 70022, 7171, 0, 340, 0, 0, 72980, 0, - 128535, 0, 124979, 94073, 0, 0, 0, 11392, 92509, 0, 0, 0, 0, 0, 0, 0, - 100632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11948, 0, 6999, 617, 983825, 0, 3675, - 10600, 0, 0, 74616, 2617, 0, 0, 0, 128446, 0, 0, 8630, 194771, 7288, - 983828, 5545, 983818, 2586, 0, 0, 73123, 983851, 0, 0, 0, 70847, 0, 0, 0, - 0, 11195, 71708, 0, 7835, 70040, 0, 0, 92285, 0, 0, 72973, 0, 0, 100852, - 71118, 10029, 983166, 0, 0, 70033, 11359, 0, 0, 194782, 0, 0, 118975, 0, - 0, 3903, 100893, 983858, 0, 120555, 0, 93036, 110645, 0, 983565, 0, 0, - 194773, 0, 0, 0, 127238, 983822, 100919, 0, 100918, 64752, 0, 983138, - 100920, 118642, 43045, 100904, 0, 0, 0, 66394, 7128, 0, 0, 0, 0, 0, - 43044, 2604, 0, 100851, 43046, 121421, 69985, 11768, 43043, 10470, 0, - 7122, 194789, 4390, 454, 41397, 194792, 0, 78762, 0, 0, 120576, 64572, 0, - 68091, 2394, 2575, 113749, 0, 0, 74802, 100913, 129280, 0, 0, 11989, 0, - 0, 128856, 0, 0, 8249, 128172, 0, 0, 6640, 74806, 2598, 513, 0, 6586, - 127521, 129301, 120710, 65008, 0, 0, 92515, 0, 194795, 66755, 0, 126585, - 0, 43152, 78637, 0, 194797, 0, 69893, 6582, 0, 0, 12839, 0, 0, 983218, 0, - 2444, 128759, 66620, 0, 0, 0, 0, 69894, 0, 0, 0, 0, 4238, 11071, 9459, - 68437, 78140, 78139, 0, 10079, 0, 0, 0, 0, 0, 11907, 43928, 0, 0, 0, 0, - 92490, 43929, 0, 43926, 64498, 0, 9506, 6978, 126234, 0, 0, 0, 0, 43934, - 0, 1122, 65564, 0, 71055, 0, 0, 1920, 0, 43930, 827, 0, 0, 0, 0, 6577, - 1304, 64733, 0, 10606, 0, 0, 69503, 9329, 92997, 9239, 74422, 0, 129373, - 1222, 11076, 0, 69229, 43615, 8262, 72280, 64627, 19909, 983554, 72279, - 0, 287, 0, 233, 0, 0, 42816, 0, 0, 65140, 128158, 8830, 0, 0, 10524, - 41175, 125033, 72294, 0, 5296, 0, 127559, 0, 0, 0, 127154, 74858, 6516, - 6515, 6514, 6513, 6512, 0, 70870, 0, 0, 0, 12122, 92462, 100868, 43976, - 1785, 92507, 0, 0, 917771, 5138, 0, 0, 0, 100884, 0, 0, 0, 123564, 0, - 5134, 69980, 322, 4643, 5132, 0, 194942, 0, 5143, 0, 72309, 119628, 0, 0, - 72112, 0, 129964, 0, 0, 0, 0, 0, 0, 73097, 0, 0, 0, 127923, 0, 0, 0, 0, - 0, 3234, 0, 100886, 0, 100889, 118924, 0, 0, 100875, 68231, 74489, - 100872, 120746, 0, 100876, 0, 12714, 0, 64585, 93775, 0, 0, 0, 129428, 0, - 11027, 0, 10059, 0, 64524, 9767, 789, 1749, 0, 66766, 984010, 320, 0, 0, - 0, 3049, 0, 6471, 0, 74479, 9925, 127356, 127355, 127358, 4960, 5549, - 127359, 127346, 127345, 127348, 5418, 127350, 3351, 120892, 127351, - 10610, 5414, 0, 0, 4286, 5421, 127344, 67867, 0, 127794, 0, 6653, 0, 0, - 64510, 0, 41868, 0, 128823, 0, 0, 11613, 70737, 12603, 7131, 11108, 4566, - 0, 0, 0, 0, 0, 124938, 127369, 0, 0, 5200, 0, 129484, 0, 9183, 127361, - 74458, 73075, 395, 5482, 1376, 4349, 0, 0, 5196, 0, 6113, 42009, 5205, 0, - 120530, 0, 118973, 70467, 0, 0, 129691, 0, 9126, 70498, 0, 0, 0, 0, 0, - 3203, 192, 0, 3385, 120785, 128620, 5383, 0, 0, 0, 5738, 69449, 3336, 0, - 5361, 9633, 0, 0, 0, 0, 8581, 0, 1260, 3149, 5359, 12962, 74955, 10441, - 5357, 0, 0, 0, 5364, 0, 11431, 0, 9101, 0, 0, 0, 0, 78378, 121155, 42917, - 0, 129179, 0, 0, 0, 43360, 78385, 78384, 78383, 78382, 78381, 78380, - 78379, 9319, 7097, 0, 127748, 0, 0, 0, 120632, 0, 71205, 0, 0, 0, 1720, - 0, 0, 0, 8622, 0, 70430, 68772, 0, 0, 0, 73084, 0, 0, 11921, 0, 11769, - 68782, 0, 0, 0, 0, 194571, 41586, 0, 0, 0, 3356, 194572, 64709, 194575, - 0, 7134, 0, 78389, 0, 677, 0, 0, 0, 129474, 68747, 0, 68751, 3349, 74125, - 0, 8927, 0, 0, 0, 0, 0, 0, 0, 6806, 0, 8384, 68755, 0, 0, 0, 0, 0, - 124924, 0, 7113, 7586, 0, 10852, 0, 0, 4606, 0, 0, 70084, 0, 0, 1046, - 7124, 121192, 68753, 0, 5171, 65539, 0, 0, 0, 42394, 0, 74849, 127823, 0, - 5169, 11935, 0, 0, 3175, 0, 1537, 0, 5176, 8905, 4136, 4871, 78388, 0, 0, - 0, 0, 1128, 0, 0, 0, 74066, 0, 73069, 0, 0, 3662, 113767, 3378, 0, 71298, - 0, 127995, 6320, 71302, 983162, 10163, 0, 5165, 5126, 0, 66902, 41389, 0, - 71368, 3374, 113740, 0, 7119, 0, 0, 3507, 0, 7629, 6848, 19925, 0, 68463, - 183, 127208, 127209, 70811, 10636, 0, 128465, 2250, 0, 78772, 0, 0, 0, - 78768, 6580, 4332, 123584, 0, 10726, 66686, 127203, 127204, 127205, - 127206, 0, 70813, 127201, 127202, 0, 0, 5448, 41058, 5446, 0, 0, 71369, - 5442, 7135, 0, 0, 5451, 0, 78470, 0, 0, 0, 0, 11243, 10859, 65867, 10345, - 10409, 123606, 0, 0, 129077, 42181, 0, 0, 2060, 0, 7111, 0, 0, 0, 0, - 72741, 0, 205, 93784, 72346, 93771, 0, 9862, 6588, 43257, 0, 0, 0, 5505, - 93789, 5503, 65376, 0, 7125, 9819, 0, 0, 0, 5507, 12044, 194567, 0, 0, 0, - 7109, 0, 0, 7911, 10329, 10393, 8991, 125104, 69778, 11133, 129619, 8550, - 0, 5592, 2919, 0, 0, 5595, 0, 0, 4367, 0, 0, 5591, 41060, 5594, 0, 0, - 13142, 5590, 0, 72274, 118909, 75069, 123586, 9731, 71225, 64633, 0, 0, - 71217, 121361, 71227, 0, 0, 0, 0, 7137, 0, 0, 0, 10551, 10710, 0, 0, 0, - 120570, 0, 92364, 9936, 3348, 0, 0, 1444, 119058, 0, 74206, 983106, 0, - 1442, 129080, 0, 120959, 0, 0, 0, 0, 0, 0, 0, 3334, 73068, 118803, 0, 0, - 71219, 69770, 1651, 0, 8861, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43626, 0, - 0, 3344, 0, 0, 12920, 0, 0, 0, 71853, 3438, 128711, 0, 0, 0, 0, 129068, - 0, 0, 65117, 0, 0, 0, 0, 66366, 128915, 0, 69772, 0, 0, 0, 0, 4973, 8784, - 0, 0, 0, 0, 0, 0, 0, 125198, 983285, 0, 0, 66413, 0, 0, 0, 0, 0, 9243, - 2464, 0, 0, 3372, 0, 0, 0, 70364, 7121, 0, 0, 0, 92163, 0, 0, 0, 0, 0, 0, - 0, 3354, 0, 0, 983103, 101233, 0, 3876, 0, 127983, 6858, 43696, 43380, 0, - 74240, 0, 0, 0, 983985, 75074, 6589, 0, 0, 120993, 0, 0, 69609, 0, 66962, - 0, 10630, 71960, 0, 121293, 0, 0, 121287, 917942, 121337, 121215, 0, 0, - 0, 0, 0, 917940, 3366, 0, 917938, 0, 0, 0, 71062, 0, 121197, 0, 6925, - 71856, 0, 917929, 66780, 66274, 0, 72768, 0, 917930, 129482, 11138, 0, - 6754, 7118, 0, 64672, 65296, 0, 118957, 0, 0, 12296, 68457, 121320, 0, - 5282, 0, 72278, 0, 0, 0, 0, 0, 0, 66355, 0, 0, 68073, 64343, 0, 92744, - 195058, 195029, 0, 0, 195056, 195027, 0, 0, 128814, 195025, 6584, 195026, - 10657, 0, 74544, 0, 1200, 12243, 92269, 195062, 0, 129300, 11545, 0, - 120493, 3343, 4424, 11047, 0, 69863, 3896, 0, 0, 2947, 0, 0, 42221, 0, - 68139, 13059, 7942, 0, 3381, 0, 0, 0, 0, 0, 0, 78235, 0, 0, 0, 7044, - 65800, 78236, 0, 7045, 7175, 7047, 127884, 11791, 0, 0, 3881, 0, 0, - 127395, 0, 0, 67075, 7106, 72000, 0, 0, 74211, 41897, 92513, 0, 73040, - 66745, 0, 0, 0, 0, 121245, 0, 64354, 73083, 8777, 0, 129108, 8884, 2385, - 73067, 92450, 0, 0, 0, 42027, 12114, 0, 0, 64936, 0, 0, 0, 0, 0, 126605, - 0, 0, 0, 0, 73064, 0, 0, 0, 0, 0, 0, 0, 73057, 0, 123587, 0, 0, 0, 0, 0, - 70803, 0, 0, 124953, 0, 0, 0, 7048, 11087, 123600, 92536, 7043, 9600, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 42050, 0, 55289, 0, 0, 657, 0, 195054, 4461, - 92903, 0, 92904, 126490, 0, 4468, 0, 0, 0, 4456, 73070, 10720, 123588, 0, - 123544, 0, 0, 0, 195046, 260, 7714, 74163, 2045, 0, 65064, 4466, 0, 0, - 128087, 0, 41403, 0, 0, 0, 41406, 120692, 0, 0, 73939, 0, 0, 0, 41404, - 1165, 0, 4451, 13087, 0, 11258, 0, 73855, 0, 43014, 5439, 12061, 74586, - 3375, 128869, 0, 0, 0, 0, 0, 0, 0, 113823, 67078, 0, 67079, 0, 0, 0, 0, - 68459, 0, 0, 0, 0, 0, 0, 7280, 0, 0, 0, 4868, 8297, 0, 0, 42791, 0, - 66737, 66739, 0, 0, 5182, 0, 0, 72764, 0, 4465, 0, 12135, 0, 4464, 0, 0, - 977, 4458, 43827, 0, 0, 120888, 0, 344, 67463, 0, 0, 0, 0, 92240, 0, - 64443, 126995, 73078, 129525, 0, 0, 0, 43026, 7612, 119591, 64413, 0, 0, - 0, 0, 0, 0, 0, 0, 123622, 0, 119160, 10204, 127947, 73063, 0, 0, 127236, - 0, 68746, 0, 8852, 0, 0, 0, 0, 128427, 123597, 7932, 92858, 128463, 0, 0, - 0, 0, 0, 0, 0, 74893, 9567, 0, 73095, 0, 8650, 0, 0, 0, 69900, 118872, 0, - 70868, 0, 6719, 0, 0, 0, 72836, 0, 0, 118991, 0, 123594, 73815, 4420, 0, - 10583, 7760, 0, 0, 128752, 71711, 0, 128407, 0, 0, 77809, 9066, 0, 74795, - 0, 0, 0, 0, 0, 0, 0, 42825, 41854, 5304, 0, 124942, 6919, 8619, 0, 10038, - 66454, 9592, 129049, 0, 0, 110771, 110777, 110772, 0, 0, 0, 0, 0, 78498, - 110773, 43624, 0, 7779, 0, 0, 9479, 78493, 0, 66956, 2224, 0, 0, 0, 0, 0, - 42378, 3368, 0, 66804, 7697, 69237, 0, 2030, 0, 68236, 8370, 0, 66953, 0, - 0, 983352, 127903, 983350, 983349, 5174, 42831, 983346, 70439, 983344, - 8881, 119047, 0, 70433, 0, 0, 0, 0, 0, 0, 9576, 0, 3347, 4160, 5154, 0, - 3794, 0, 0, 0, 0, 0, 127916, 73073, 8381, 4572, 69564, 126101, 0, 0, 0, - 0, 0, 0, 0, 92283, 0, 0, 5799, 983341, 70100, 983339, 983338, 983337, - 43031, 64425, 65128, 983333, 0, 73059, 0, 68616, 0, 0, 0, 0, 119826, 0, - 0, 123604, 0, 0, 283, 68665, 0, 532, 0, 0, 983827, 0, 0, 3370, 73077, - 119132, 5443, 71431, 0, 118630, 0, 0, 0, 2298, 0, 0, 0, 983332, 983331, - 983330, 983329, 7144, 983327, 119600, 983325, 983324, 983323, 0, 78816, - 128833, 0, 0, 0, 0, 0, 0, 0, 0, 73088, 0, 123592, 983952, 0, 0, 0, 0, - 5186, 7360, 127837, 0, 12108, 0, 65124, 0, 0, 0, 6326, 43344, 0, 0, - 42562, 0, 0, 0, 983322, 65495, 983320, 101066, 983318, 101065, 983316, - 65490, 983314, 125034, 0, 101070, 0, 55245, 128927, 1630, 128232, 65483, - 0, 0, 0, 65476, 0, 0, 119214, 9283, 10183, 0, 0, 65499, 0, 64593, 66758, - 3376, 0, 0, 0, 101077, 43872, 12940, 0, 0, 78587, 101078, 5957, 0, 8926, - 983312, 983311, 983310, 10745, 10174, 983307, 113793, 983305, 983304, - 983303, 0, 123593, 5056, 0, 0, 0, 120773, 0, 9812, 0, 4460, 127792, - 73066, 0, 128038, 0, 123608, 0, 64278, 0, 0, 0, 66760, 0, 0, 70122, 0, 0, - 917627, 0, 73823, 101071, 127922, 2276, 0, 42579, 0, 983302, 983301, - 127831, 983299, 983298, 983297, 983296, 983295, 74207, 121255, 10482, - 12863, 73002, 2412, 0, 9522, 0, 983906, 120674, 101059, 3384, 101058, - 10702, 830, 0, 128166, 0, 8451, 0, 0, 121380, 69739, 128957, 0, 0, 0, 0, - 0, 0, 0, 4243, 92454, 73093, 0, 129705, 4441, 0, 983292, 983291, 66618, - 983289, 125141, 411, 983286, 68068, 983284, 4056, 983913, 0, 92666, 0, - 983916, 983968, 0, 0, 3364, 42265, 64437, 129635, 118816, 0, 9684, 216, - 0, 1401, 0, 0, 0, 122643, 0, 0, 0, 11126, 5768, 3191, 0, 0, 0, 0, 0, 0, - 65895, 0, 0, 3338, 73935, 983280, 983279, 983278, 129605, 983276, 983275, - 2794, 8807, 0, 0, 110720, 0, 8312, 0, 110718, 11953, 11662, 0, 0, 0, 0, - 9534, 66767, 129040, 0, 11113, 0, 0, 73082, 0, 981, 0, 4330, 119244, - 120536, 1824, 0, 0, 7034, 41683, 123166, 0, 73754, 0, 0, 74478, 128259, - 983270, 983257, 983256, 43831, 983254, 66752, 983252, 983251, 0, 70288, - 65343, 0, 0, 43225, 0, 0, 0, 0, 126129, 0, 128608, 0, 0, 0, 120726, 0, - 983852, 11746, 0, 5216, 0, 0, 0, 0, 3468, 127149, 9230, 65942, 0, 0, - 5803, 120677, 0, 0, 13124, 0, 0, 0, 42843, 0, 0, 0, 66753, 11739, 128318, - 0, 128444, 0, 0, 0, 12448, 0, 121441, 13057, 73852, 124994, 0, 0, 0, 0, - 0, 0, 126612, 0, 68903, 0, 129470, 0, 917992, 0, 0, 0, 0, 0, 0, 0, 92457, - 0, 0, 0, 0, 0, 0, 0, 0, 125078, 0, 0, 0, 10970, 92208, 0, 0, 0, 19944, 0, - 9009, 8551, 0, 0, 0, 7575, 67484, 0, 128899, 0, 129609, 78847, 0, 78846, - 0, 0, 69256, 0, 0, 0, 0, 9775, 100682, 129191, 119052, 68629, 194703, 0, - 0, 78850, 92880, 0, 0, 0, 0, 0, 0, 0, 71273, 6184, 41540, 3303, 66182, - 11786, 66180, 66203, 3422, 0, 68290, 43007, 4478, 66178, 0, 0, 126216, 0, - 4477, 0, 69608, 66184, 66183, 66204, 66194, 0, 66198, 41880, 66188, - 66197, 78148, 66195, 66190, 66191, 41111, 66189, 73788, 7788, 0, 0, 0, 0, - 0, 2221, 78163, 6535, 78161, 78162, 430, 78160, 78156, 78158, 0, 0, 4945, - 0, 4950, 0, 78165, 0, 67118, 0, 5964, 12908, 0, 0, 0, 74477, 83390, 0, - 4949, 0, 443, 0, 4944, 5467, 119603, 983262, 0, 9364, 0, 119148, 4946, 0, - 3788, 126106, 983718, 0, 120847, 129858, 74441, 0, 0, 12072, 92248, 0, - 983708, 0, 128676, 12091, 0, 0, 0, 4673, 0, 4678, 0, 0, 65059, 43860, 0, - 0, 0, 128151, 1199, 0, 8356, 0, 0, 4677, 0, 0, 0, 2192, 78173, 78175, - 78171, 78172, 72255, 78170, 78166, 4674, 128450, 194944, 0, 124970, 0, - 119579, 0, 129919, 1855, 0, 0, 127806, 0, 0, 68912, 72323, 0, 12988, - 121000, 0, 0, 0, 4654, 6840, 983429, 0, 73993, 0, 4649, 65209, 983908, - 93839, 4648, 122635, 121169, 983433, 126231, 983424, 66846, 7828, 4650, - 983423, 72879, 0, 4653, 7822, 0, 0, 43187, 0, 983586, 6821, 0, 0, 0, 0, - 0, 0, 66756, 983430, 0, 0, 0, 8547, 0, 42165, 0, 119228, 6836, 0, 0, - 4662, 0, 0, 0, 9146, 599, 4657, 0, 120754, 0, 4656, 0, 0, 7811, 40994, 0, - 6414, 5967, 4658, 3725, 0, 5814, 4661, 127760, 194961, 0, 0, 64904, 0, - 10833, 0, 0, 4867, 128717, 0, 11459, 3054, 0, 40996, 0, 7605, 4622, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 19926, 0, 0, 65307, 4617, 0, 0, 0, 4616, 10518, 0, - 127160, 0, 5958, 0, 983446, 4618, 0, 983439, 120675, 4621, 0, 983441, - 522, 125213, 11139, 65803, 194972, 0, 12201, 6135, 121060, 983422, 0, - 983093, 0, 983420, 983413, 983434, 4638, 983418, 0, 78242, 5965, 78240, - 66569, 68646, 0, 983452, 74392, 5335, 0, 0, 4633, 0, 119045, 983448, - 4632, 0, 5542, 5333, 0, 983425, 68648, 5331, 4634, 0, 92870, 5338, 4637, - 0, 0, 43477, 0, 42493, 0, 42361, 0, 0, 73853, 0, 0, 0, 74204, 11343, 0, - 10358, 10422, 4758, 0, 1608, 5252, 0, 0, 4753, 78239, 11344, 78237, 0, - 5231, 74384, 0, 0, 118676, 0, 0, 0, 0, 71991, 5229, 4757, 0, 0, 5227, - 4752, 0, 65235, 5234, 73044, 0, 0, 0, 0, 0, 0, 7460, 0, 917936, 0, 0, - 74760, 65189, 0, 92230, 0, 0, 5574, 128980, 0, 65139, 5577, 0, 0, 118871, - 68641, 8965, 7635, 0, 5316, 70021, 5314, 74555, 5572, 0, 5312, 0, 5525, - 5330, 5319, 68292, 0, 65066, 0, 0, 983493, 0, 0, 127851, 0, 74851, 0, 0, - 64609, 0, 0, 128593, 0, 129339, 0, 8632, 0, 0, 0, 195012, 5735, 195013, - 1692, 70151, 4610, 122653, 4305, 0, 4609, 43478, 4614, 77753, 118534, - 5287, 5309, 5285, 0, 5961, 4647, 5283, 10743, 0, 71889, 601, 4613, 77759, - 0, 9208, 4608, 74044, 71107, 5190, 0, 0, 92410, 43965, 2265, 0, 0, 0, 0, - 0, 0, 0, 129953, 0, 0, 5960, 0, 8992, 65293, 0, 1782, 0, 0, 0, 0, 0, - 5501, 0, 42508, 69759, 120749, 129120, 0, 195023, 77740, 43900, 77741, 0, + 0, 120515, 7873, 77719, 129754, 0, 0, 77717, 0, 73994, 73992, 0, 0, 0, + 41851, 0, 41846, 126485, 92337, 7633, 41849, 68385, 70726, 3224, 0, + 69806, 0, 0, 0, 1510, 68129, 0, 0, 0, 0, 12109, 0, 0, 0, 0, 0, 78377, + 1910, 8671, 78374, 127118, 70290, 0, 0, 0, 2654, 7893, 0, 0, 0, 72394, 0, + 67394, 0, 118970, 70066, 78372, 78371, 78370, 78369, 78368, 0, 0, 0, + 1733, 0, 2568, 0, 0, 0, 0, 41486, 0, 127839, 7116, 0, 0, 0, 7185, 0, 0, + 0, 0, 0, 120575, 120829, 0, 0, 0, 0, 92489, 0, 0, 0, 70022, 7171, 0, 340, + 0, 0, 72980, 0, 128535, 0, 124979, 94073, 0, 0, 0, 11392, 92509, 0, 0, 0, + 0, 0, 0, 0, 100632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11948, 0, 6999, 617, + 983825, 0, 3675, 10600, 0, 0, 74616, 2617, 0, 0, 0, 128446, 0, 0, 8630, + 194771, 7288, 983828, 5545, 983818, 2586, 0, 0, 73123, 983851, 0, 0, 0, + 70847, 0, 0, 0, 0, 11195, 71708, 0, 7835, 70040, 0, 0, 92285, 0, 0, + 72973, 0, 0, 100852, 71118, 10029, 983167, 0, 0, 70033, 11359, 0, 0, + 194782, 0, 0, 118975, 0, 0, 3903, 100893, 983858, 0, 120555, 0, 93036, + 110645, 0, 983565, 0, 0, 194773, 0, 0, 0, 127238, 983822, 100919, 0, + 100918, 64752, 0, 983139, 100920, 118642, 43045, 100904, 0, 0, 0, 66394, + 7128, 0, 0, 0, 0, 0, 43044, 2604, 0, 100851, 43046, 121421, 69985, 11768, + 43043, 10470, 0, 7122, 194789, 4390, 454, 41397, 194792, 0, 78762, 0, 0, + 120576, 64572, 0, 68091, 2394, 2575, 113749, 0, 0, 74802, 100913, 129280, + 0, 0, 11989, 0, 0, 128856, 0, 0, 8249, 128172, 0, 0, 6640, 74806, 2598, + 513, 0, 6586, 127521, 129301, 120710, 65008, 0, 0, 92515, 0, 194795, + 66755, 0, 126585, 0, 43152, 78637, 0, 194797, 0, 69893, 6582, 0, 0, + 12839, 0, 78906, 983221, 0, 2444, 119489, 66620, 0, 0, 0, 0, 69894, 0, 0, + 0, 0, 4238, 11071, 9459, 68437, 78140, 78139, 0, 10079, 128985, 0, 0, 0, + 0, 11907, 43928, 0, 0, 0, 0, 92490, 43929, 0, 43926, 64498, 0, 9506, + 6978, 126234, 0, 0, 0, 0, 43934, 0, 1122, 65564, 0, 71055, 0, 0, 1920, 0, + 43930, 827, 0, 0, 0, 0, 6577, 1304, 64733, 0, 10606, 0, 0, 69503, 9329, + 92997, 9239, 74422, 0, 129373, 1222, 11076, 0, 69229, 43615, 8262, 72280, + 64627, 19909, 983554, 72279, 0, 287, 0, 233, 0, 0, 42816, 0, 0, 65140, + 128158, 8830, 0, 0, 10524, 41175, 125033, 72294, 0, 5296, 0, 127559, 0, + 0, 0, 127154, 74858, 6516, 6515, 6514, 6513, 6512, 0, 70870, 0, 0, 0, + 12122, 92462, 100868, 43976, 1785, 92507, 0, 0, 917771, 5138, 0, 0, 0, + 100884, 0, 0, 0, 123564, 0, 5134, 69980, 322, 4643, 5132, 0, 194942, 0, + 5143, 0, 72309, 119628, 0, 0, 72112, 0, 129964, 0, 0, 0, 0, 0, 0, 73097, + 0, 0, 0, 127923, 0, 0, 0, 0, 0, 3234, 0, 100886, 0, 100889, 118924, 0, 0, + 100875, 68231, 74489, 100872, 120746, 0, 100876, 0, 12714, 0, 64585, + 93775, 0, 0, 0, 129428, 0, 11027, 0, 10059, 0, 64524, 9767, 789, 1749, 0, + 66766, 984010, 320, 0, 0, 0, 3049, 0, 6471, 0, 74479, 9925, 127356, + 127355, 127358, 4960, 5549, 127359, 127346, 127345, 127348, 5418, 127350, + 3351, 120892, 127351, 10610, 5414, 93789, 0, 4286, 5421, 127344, 67867, + 0, 127794, 0, 6653, 122958, 0, 64510, 0, 41868, 0, 128823, 0, 0, 11613, + 70737, 12603, 7131, 11108, 4566, 0, 0, 0, 0, 0, 124938, 127369, 0, 0, + 5200, 0, 129484, 0, 9183, 127361, 74458, 73075, 395, 5482, 1376, 4349, 0, + 0, 5196, 0, 6113, 42009, 5205, 0, 120530, 0, 118973, 70467, 0, 0, 129691, + 0, 9126, 70498, 0, 0, 0, 0, 0, 3203, 192, 0, 3385, 120785, 128620, 5383, + 0, 0, 0, 5738, 69449, 3336, 0, 5361, 9633, 0, 0, 0, 0, 8581, 0, 1260, + 3149, 5359, 12962, 74955, 10441, 5357, 0, 0, 0, 5364, 0, 11431, 0, 9101, + 0, 0, 0, 0, 78378, 121155, 42917, 0, 129179, 0, 0, 0, 43360, 78385, + 78384, 78383, 78382, 78381, 78380, 78379, 9319, 7097, 0, 127748, 0, 0, 0, + 120632, 0, 71205, 0, 0, 0, 1720, 0, 0, 0, 8622, 0, 70430, 68772, 0, 0, 0, + 73084, 0, 0, 11921, 0, 11769, 68782, 0, 0, 0, 0, 194571, 41586, 0, 0, 0, + 3356, 194572, 64709, 194575, 0, 7134, 0, 78389, 0, 677, 0, 0, 0, 129474, + 68747, 0, 68751, 3349, 74125, 0, 8927, 0, 0, 0, 0, 0, 0, 0, 6806, 0, + 8384, 68755, 0, 0, 0, 0, 0, 124924, 0, 7113, 7586, 0, 10852, 0, 0, 4606, + 0, 0, 70084, 0, 0, 1046, 7124, 121192, 68753, 0, 5171, 65539, 0, 0, 0, + 42394, 0, 74849, 127823, 0, 5169, 11935, 0, 0, 3175, 0, 1537, 0, 5176, + 8905, 4136, 4871, 78388, 0, 0, 122661, 0, 1128, 0, 0, 0, 74066, 0, 73069, + 0, 0, 3662, 113767, 3378, 0, 71298, 0, 127995, 6320, 71302, 983163, + 10163, 0, 5165, 5126, 0, 66902, 41389, 0, 71368, 3374, 113740, 0, 7119, + 0, 0, 3507, 0, 7629, 6848, 19925, 0, 68463, 183, 127208, 127209, 70811, + 10636, 0, 128465, 2250, 0, 78772, 0, 0, 0, 78768, 6580, 4332, 123584, 0, + 10726, 66686, 127203, 127204, 127205, 127206, 0, 70813, 127201, 127202, + 0, 0, 5448, 41058, 5446, 0, 0, 71369, 5442, 7135, 0, 0, 5451, 0, 78470, + 0, 0, 0, 0, 11243, 10859, 65867, 10345, 10409, 123606, 0, 0, 129077, + 42181, 0, 0, 2060, 0, 7111, 0, 0, 0, 0, 72741, 0, 205, 93784, 72346, + 93771, 0, 9862, 6588, 43257, 0, 0, 0, 5505, 93760, 5503, 65376, 0, 7125, + 9819, 0, 0, 0, 5507, 12044, 194567, 0, 0, 0, 7109, 0, 0, 7911, 10329, + 10393, 8991, 125104, 69778, 11133, 129619, 8550, 0, 5592, 2919, 0, 0, + 5595, 0, 0, 4367, 0, 0, 5591, 41060, 5594, 0, 0, 13142, 5590, 0, 72274, + 118909, 75069, 123586, 9731, 71225, 64633, 0, 0, 71217, 121361, 71227, 0, + 0, 0, 0, 7137, 0, 0, 0, 10551, 10710, 0, 0, 0, 120570, 0, 92364, 9936, + 3348, 0, 0, 1444, 119058, 0, 74206, 983107, 0, 1442, 129080, 0, 120959, + 0, 0, 0, 0, 0, 0, 0, 3334, 73068, 118803, 0, 0, 71219, 69770, 1651, 0, + 8861, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43626, 0, 0, 3344, 0, 0, 12920, 0, + 0, 0, 71853, 3438, 128711, 0, 0, 0, 0, 129068, 0, 0, 65117, 0, 0, 0, 0, + 66366, 128915, 0, 69772, 0, 0, 0, 0, 4973, 8784, 0, 0, 0, 0, 0, 0, 0, + 125198, 983288, 0, 0, 66413, 0, 0, 0, 0, 122663, 9243, 2464, 0, 0, 3372, + 0, 0, 0, 70364, 7121, 0, 0, 0, 92163, 0, 0, 0, 0, 0, 0, 0, 3354, 0, 0, + 983104, 101233, 0, 3876, 0, 127983, 6858, 43696, 43380, 0, 74240, 0, 0, + 0, 983985, 75074, 6589, 0, 0, 120993, 0, 0, 69609, 0, 66962, 0, 10630, + 71960, 0, 121293, 0, 0, 121287, 917942, 121337, 121215, 0, 0, 0, 0, 0, + 917940, 3366, 0, 917938, 0, 0, 0, 71062, 0, 121197, 0, 6925, 71856, 0, + 917929, 66780, 66274, 0, 72768, 0, 917930, 129482, 11138, 0, 6754, 7118, + 0, 64672, 65296, 0, 118957, 0, 0, 12296, 68457, 121320, 0, 5282, 0, + 72278, 0, 0, 0, 0, 0, 0, 66355, 0, 0, 68073, 64343, 0, 92744, 195058, + 195029, 0, 0, 195056, 195027, 0, 0, 128814, 195025, 6584, 195026, 10657, + 0, 74544, 0, 1200, 12243, 92269, 195062, 0, 129300, 11545, 0, 120493, + 3343, 4424, 11047, 0, 69863, 3896, 0, 0, 2947, 0, 0, 42221, 0, 68139, + 13059, 7942, 0, 3381, 0, 0, 0, 0, 0, 0, 78235, 0, 0, 0, 7044, 65800, + 78236, 0, 7045, 7175, 7047, 127884, 11791, 0, 0, 3881, 0, 0, 127395, 0, + 0, 67075, 7106, 72000, 0, 0, 74211, 41897, 92513, 0, 73040, 66745, 0, 0, + 0, 0, 121245, 0, 64354, 73083, 8777, 0, 129108, 8884, 2385, 73067, 92450, + 0, 0, 0, 42027, 12114, 0, 0, 64936, 0, 0, 0, 0, 0, 126605, 0, 0, 0, 0, + 73064, 0, 0, 0, 0, 0, 0, 0, 73057, 0, 123587, 0, 0, 0, 0, 0, 70803, 0, 0, + 124953, 0, 0, 0, 7048, 11087, 123600, 92536, 7043, 9600, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 42050, 0, 55289, 0, 0, 657, 0, 195054, 4461, 92903, 0, 92904, + 126490, 0, 4468, 0, 0, 0, 4456, 73070, 10720, 123588, 0, 123544, 0, 0, 0, + 195046, 260, 7714, 74163, 2045, 0, 65064, 4466, 0, 0, 128087, 129768, + 41403, 0, 0, 0, 41406, 120692, 0, 0, 73939, 0, 0, 0, 41404, 1165, 0, + 4451, 13087, 0, 11258, 0, 73855, 0, 43014, 5439, 12061, 74586, 3375, + 128869, 0, 0, 0, 0, 0, 0, 0, 113823, 67078, 0, 67079, 0, 0, 0, 0, 68459, + 0, 0, 0, 0, 0, 0, 7280, 0, 0, 0, 4868, 8297, 0, 0, 42791, 0, 66737, + 66739, 0, 0, 5182, 0, 0, 72764, 0, 4465, 0, 12135, 0, 4464, 0, 0, 977, + 4458, 43827, 0, 0, 120888, 0, 344, 67463, 0, 0, 0, 0, 92240, 0, 64443, + 126995, 73078, 129525, 0, 0, 0, 43026, 7612, 119591, 64413, 0, 0, 0, 0, + 0, 0, 0, 0, 123622, 0, 119160, 10204, 127947, 73063, 0, 0, 127236, 0, + 68746, 0, 8852, 0, 0, 0, 0, 128427, 123597, 7932, 92858, 128463, 0, 0, + 72453, 0, 0, 0, 0, 74893, 9567, 0, 73095, 0, 8650, 0, 0, 0, 69900, + 118872, 0, 70868, 0, 6719, 0, 0, 0, 72836, 0, 0, 118991, 0, 123594, + 73815, 4420, 0, 10583, 7760, 0, 0, 128752, 71711, 0, 128407, 0, 0, 77809, + 9066, 0, 74795, 0, 0, 0, 0, 0, 0, 0, 42825, 41854, 5304, 0, 124942, 6919, + 8619, 0, 10038, 66454, 9592, 129049, 0, 0, 110771, 110777, 110772, 0, 0, + 0, 0, 0, 78498, 110773, 43624, 0, 7779, 0, 0, 9479, 78493, 0, 66956, + 2224, 0, 0, 0, 0, 0, 42378, 3368, 0, 66804, 7697, 69237, 0, 2030, 0, + 68236, 8370, 0, 66953, 0, 0, 983355, 127903, 983353, 983352, 5174, 42831, + 983349, 70439, 983347, 8881, 119047, 0, 70433, 0, 0, 0, 0, 0, 0, 9576, 0, + 3347, 4160, 5154, 0, 3794, 0, 0, 0, 0, 0, 127916, 73073, 8381, 4572, + 69564, 126101, 0, 0, 0, 0, 0, 0, 0, 92283, 0, 0, 5799, 983344, 70100, + 983342, 983341, 983340, 43031, 64425, 65128, 983336, 0, 73059, 0, 68616, + 0, 0, 0, 0, 119826, 0, 0, 123604, 0, 0, 283, 68665, 0, 532, 0, 0, 983827, + 0, 0, 3370, 73077, 119132, 5443, 71431, 0, 118630, 0, 0, 0, 2298, 0, 0, + 0, 983335, 983334, 983333, 983332, 7144, 983330, 119600, 983328, 983327, + 983326, 0, 78816, 128833, 0, 0, 0, 0, 0, 0, 0, 0, 73088, 0, 123592, + 983952, 0, 0, 0, 0, 5186, 7360, 127837, 0, 12108, 0, 65124, 0, 0, 0, + 6326, 43344, 0, 0, 42562, 0, 0, 0, 983325, 65495, 983323, 101066, 983321, + 101065, 983319, 65490, 983317, 125034, 0, 101070, 127178, 55245, 128927, + 1630, 128232, 65483, 0, 0, 0, 65476, 0, 0, 119214, 9283, 10183, 0, 0, + 65499, 0, 64593, 66758, 3376, 0, 0, 0, 101077, 43872, 12940, 0, 0, 78587, + 101078, 5957, 0, 8926, 983315, 983314, 983313, 10745, 10174, 983310, + 113793, 983308, 983307, 983306, 0, 123593, 5056, 0, 0, 0, 120773, 0, + 9812, 0, 4460, 127792, 73066, 0, 128038, 0, 123608, 0, 64278, 0, 0, 0, + 66760, 0, 0, 70122, 0, 0, 917627, 0, 73823, 101071, 127922, 2276, 0, + 42579, 0, 983305, 983304, 127831, 983302, 983301, 983300, 983299, 983298, + 74207, 121255, 10482, 12863, 73002, 2412, 0, 9522, 0, 983906, 120674, + 101059, 3384, 101058, 10702, 830, 0, 128166, 0, 8451, 0, 0, 121380, + 69739, 128957, 0, 0, 0, 0, 0, 0, 0, 4243, 92454, 73093, 0, 129705, 4441, + 0, 983295, 983294, 66618, 983292, 125141, 411, 983289, 68068, 983287, + 4056, 983913, 0, 92666, 0, 983916, 983968, 0, 0, 3364, 42265, 64437, + 129635, 118816, 0, 9684, 216, 0, 1401, 0, 0, 0, 122643, 0, 0, 0, 11126, + 5768, 3191, 0, 0, 0, 0, 0, 0, 65895, 0, 0, 3338, 73935, 983283, 983282, + 983281, 129605, 983279, 983278, 2794, 8807, 0, 0, 110720, 0, 8312, 0, + 110718, 11953, 11662, 0, 0, 0, 0, 9534, 66767, 129040, 0, 11113, 0, 0, + 73082, 0, 981, 0, 4330, 119244, 120536, 1824, 0, 0, 7034, 41683, 123166, + 0, 73754, 0, 0, 74478, 128259, 983273, 983260, 983259, 43831, 983257, + 66752, 983255, 983254, 0, 70288, 65343, 0, 0, 43225, 0, 0, 0, 0, 126129, + 0, 128608, 0, 0, 0, 120726, 0, 983852, 11746, 0, 5216, 0, 0, 0, 0, 3468, + 127149, 9230, 65942, 0, 0, 5803, 120677, 0, 0, 13124, 0, 0, 0, 42843, 0, + 0, 0, 66753, 11739, 128318, 0, 128444, 0, 0, 0, 12448, 0, 121441, 13057, + 73852, 124994, 0, 0, 0, 0, 0, 0, 126612, 0, 68903, 0, 129470, 0, 917992, + 0, 0, 0, 0, 0, 0, 0, 92457, 0, 0, 0, 0, 0, 0, 0, 0, 125078, 0, 0, 0, + 10970, 92208, 0, 0, 0, 19944, 0, 9009, 8551, 0, 0, 0, 7575, 67484, 0, + 128899, 0, 129609, 78847, 0, 78846, 73502, 0, 69256, 0, 0, 0, 0, 9775, + 100682, 129191, 119052, 68629, 194703, 0, 0, 78850, 92880, 0, 0, 0, 0, 0, + 0, 0, 71273, 6184, 41540, 3303, 66182, 11786, 66180, 66203, 3422, 0, + 68290, 43007, 4478, 66178, 0, 0, 126216, 0, 4477, 0, 69608, 66184, 66183, + 66204, 66194, 0, 66198, 41880, 66188, 66197, 78148, 66195, 66190, 66191, + 41111, 66189, 73788, 7788, 0, 0, 0, 0, 0, 2221, 78163, 6535, 78161, + 78162, 430, 78160, 78156, 78158, 0, 0, 4945, 0, 4950, 0, 78165, 0, 67118, + 0, 5964, 12908, 0, 0, 0, 74477, 83390, 0, 4949, 0, 443, 0, 4944, 5467, + 119603, 983265, 0, 9364, 0, 119148, 4946, 0, 3788, 126106, 983718, 0, + 120847, 129858, 74441, 0, 0, 12072, 92248, 0, 983708, 0, 128676, 12091, + 0, 0, 0, 4673, 0, 4678, 0, 0, 65059, 43860, 0, 0, 0, 128151, 1199, 0, + 8356, 0, 0, 4677, 0, 0, 0, 2192, 78173, 78175, 78171, 78172, 72255, + 78170, 78166, 4674, 128450, 194944, 0, 124970, 0, 119579, 0, 129919, + 1855, 0, 0, 127806, 0, 0, 68912, 72323, 0, 12988, 121000, 0, 0, 0, 4654, + 6840, 983432, 0, 73993, 0, 4649, 65209, 983908, 93839, 4648, 122635, + 121169, 983436, 126231, 983427, 66846, 7828, 4650, 983426, 72879, 0, + 4653, 7822, 0, 0, 43187, 0, 983586, 6821, 0, 0, 0, 0, 0, 0, 66756, + 983433, 0, 0, 0, 8547, 0, 42165, 0, 119228, 6836, 0, 0, 4662, 0, 0, 0, + 9146, 599, 4657, 0, 120754, 0, 4656, 0, 0, 7811, 40994, 0, 6414, 5967, + 4658, 3725, 0, 5814, 4661, 127760, 194961, 0, 0, 64904, 0, 10833, 0, 0, + 4867, 128717, 0, 11459, 3054, 0, 40996, 0, 7605, 4622, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 19926, 0, 0, 65307, 4617, 0, 0, 0, 4616, 10518, 0, 127160, 0, + 5958, 0, 983449, 4618, 0, 983442, 120675, 4621, 0, 983444, 522, 125213, + 11139, 65803, 194972, 0, 12201, 6135, 121060, 983425, 0, 983093, 0, + 983423, 983416, 983437, 4638, 983421, 0, 78242, 5965, 78240, 66569, + 68646, 0, 983455, 74392, 5335, 0, 0, 4633, 0, 119045, 983451, 4632, 0, + 5542, 5333, 0, 983428, 68648, 5331, 4634, 0, 92870, 5338, 4637, 0, 0, + 43477, 0, 42493, 0, 42361, 0, 0, 73853, 0, 0, 0, 74204, 11343, 0, 10358, + 10422, 4758, 0, 1608, 5252, 0, 0, 4753, 78239, 11344, 78237, 0, 5231, + 74384, 0, 0, 118676, 0, 0, 0, 0, 71991, 5229, 4757, 0, 0, 5227, 4752, 0, + 65235, 5234, 73044, 0, 0, 0, 0, 0, 0, 7460, 0, 917936, 0, 0, 74760, + 65189, 0, 92230, 0, 0, 5574, 128980, 0, 65139, 5577, 0, 0, 118871, 68641, + 8965, 7635, 0, 5316, 70021, 5314, 74555, 5572, 0, 5312, 0, 5525, 5330, + 5319, 68292, 0, 65066, 0, 0, 983496, 0, 0, 127851, 0, 74851, 0, 0, 64609, + 0, 0, 128593, 0, 129339, 0, 8632, 0, 0, 0, 195012, 5735, 195013, 1692, + 70151, 4610, 122653, 4305, 0, 4609, 43478, 4614, 77753, 118534, 5287, + 5309, 5285, 0, 5961, 4647, 5283, 10743, 0, 71889, 601, 4613, 77759, 0, + 9208, 4608, 74044, 71107, 5190, 0, 0, 92410, 43965, 2265, 0, 0, 0, 0, 0, + 0, 0, 129953, 0, 0, 5960, 0, 8992, 65293, 0, 1782, 0, 0, 0, 0, 0, 5501, + 0, 42508, 69759, 120749, 129120, 0, 195023, 77740, 43900, 77741, 0, 68134, 111180, 74209, 0, 64740, 0, 0, 0, 983935, 3767, 5737, 0, 4865, 0, 5740, 0, 5736, 7724, 0, 7193, 0, 0, 5739, 77744, 4866, 0, 0, 0, 4869, - 67093, 0, 0, 128514, 6650, 983485, 0, 983476, 78376, 4870, 0, 68661, - 6716, 983475, 2190, 69786, 68676, 0, 10122, 4864, 66568, 0, 0, 0, 9603, - 68652, 126213, 42734, 745, 0, 0, 0, 4777, 0, 77788, 68631, 42775, 68196, - 0, 0, 0, 0, 5966, 0, 4778, 127890, 0, 0, 4781, 127196, 64407, 0, 74132, - 8577, 71221, 0, 71223, 0, 4782, 0, 0, 120757, 68618, 43472, 43056, 68622, - 0, 92986, 4776, 0, 11492, 0, 0, 13176, 0, 0, 0, 0, 0, 0, 0, 4849, 8242, - 9561, 73922, 0, 0, 0, 0, 5963, 0, 125201, 0, 4850, 72121, 0, 590, 4853, - 0, 4854, 0, 5164, 0, 1605, 5124, 0, 111165, 0, 8471, 0, 111164, 12445, - 3785, 0, 111162, 0, 0, 4848, 2530, 0, 2068, 1964, 0, 0, 10796, 0, 0, 0, - 0, 0, 4794, 0, 0, 0, 4797, 68040, 111152, 43465, 4792, 0, 0, 0, 0, 0, - 110842, 983101, 92963, 0, 0, 0, 4221, 92360, 118869, 0, 0, 0, 70042, 0, - 0, 0, 0, 10739, 65090, 0, 119327, 126541, 0, 0, 119326, 0, 0, 4937, - 43376, 0, 0, 10597, 983442, 11722, 9248, 129566, 42879, 11725, 0, 0, - 7579, 11141, 73958, 4941, 0, 917538, 9140, 4936, 5261, 0, 0, 72298, 0, - 4942, 0, 4938, 0, 0, 5259, 9369, 983431, 111182, 5257, 0, 6844, 4964, - 5264, 0, 0, 0, 41411, 0, 121473, 73684, 128233, 9482, 4873, 41991, 64707, - 42526, 127989, 64480, 64725, 983444, 0, 0, 0, 0, 0, 0, 73043, 0, 389, - 10893, 7521, 0, 4872, 5463, 0, 3125, 111124, 0, 4878, 5459, 4604, 0, 0, - 5465, 0, 0, 0, 0, 9563, 0, 0, 128419, 125273, 82963, 0, 0, 0, 67735, 0, - 0, 0, 0, 0, 78179, 0, 129707, 0, 917833, 0, 917836, 0, 0, 3082, 0, 0, 0, - 0, 118621, 7079, 5856, 917842, 5163, 0, 0, 1817, 66724, 0, 0, 10564, - 7763, 13077, 0, 0, 68140, 111137, 0, 77782, 0, 111139, 123548, 77787, - 121457, 0, 0, 0, 983189, 73081, 0, 0, 983117, 983077, 0, 42156, 0, 0, 0, - 983080, 0, 0, 0, 119254, 120693, 0, 69386, 0, 118881, 0, 78189, 0, 78186, - 78188, 0, 0, 0, 0, 110877, 0, 3108, 9745, 0, 0, 0, 118825, 92785, 0, 0, - 0, 0, 10972, 92786, 0, 42768, 715, 983113, 121117, 9453, 5348, 10943, 0, - 983169, 92784, 0, 0, 983153, 0, 0, 11551, 128464, 0, 0, 9051, 0, 71728, - 0, 120791, 119523, 0, 6404, 66458, 68376, 11984, 9156, 65222, 74454, - 78180, 0, 3128, 4789, 5067, 5066, 0, 4784, 0, 8827, 1146, 5065, 78196, - 78192, 78193, 78190, 78191, 5064, 5326, 0, 9450, 5063, 120361, 78200, - 78201, 5062, 69733, 74146, 0, 0, 0, 0, 77992, 0, 3933, 77768, 0, 12337, - 0, 125023, 0, 0, 0, 194759, 0, 0, 82993, 42130, 0, 5151, 917832, 120357, - 0, 93980, 0, 7620, 3800, 0, 0, 0, 127952, 0, 0, 4786, 127991, 4185, 0, - 128742, 0, 983193, 73978, 0, 4593, 77715, 77727, 124909, 0, 110715, - 10532, 77732, 110714, 110711, 110712, 64759, 1325, 5166, 9888, 0, 5148, - 0, 0, 78205, 78206, 64140, 78204, 64131, 3119, 917814, 0, 983435, 917820, - 12095, 0, 0, 636, 128002, 0, 983466, 0, 78531, 7836, 42741, 64137, 0, - 118969, 0, 92431, 0, 0, 0, 0, 0, 8618, 0, 11865, 0, 0, 0, 3937, 12312, - 128261, 0, 0, 0, 912, 6349, 4536, 71964, 0, 126594, 0, 0, 0, 3935, - 120665, 0, 0, 0, 0, 118859, 0, 121116, 0, 0, 12046, 12599, 0, 0, 0, 0, - 7227, 0, 0, 0, 983066, 0, 0, 0, 113817, 2179, 78246, 0, 0, 0, 0, 0, - 127405, 101531, 0, 101530, 43907, 0, 0, 0, 0, 4644, 8818, 0, 0, 0, 0, - 93066, 66452, 126081, 1644, 101043, 9658, 43744, 11385, 65947, 983173, - 43983, 0, 0, 0, 8962, 0, 0, 2466, 42039, 67669, 0, 0, 42117, 100698, 0, - 0, 0, 0, 43745, 5318, 0, 77723, 0, 0, 0, 7054, 64147, 0, 917804, 68195, - 6698, 0, 0, 0, 70849, 11981, 12202, 0, 121364, 0, 7059, 11608, 975, 0, - 65843, 170, 0, 67239, 42708, 0, 0, 6058, 0, 0, 0, 70507, 0, 0, 9818, 0, - 0, 42106, 0, 983065, 4738, 42105, 7062, 0, 4737, 11779, 4742, 120564, - 92391, 0, 41374, 41375, 983378, 6715, 12700, 7049, 983376, 0, 0, 0, 4741, - 42108, 983367, 64159, 4736, 64148, 0, 849, 0, 128247, 983363, 0, 120913, - 917997, 0, 983381, 9496, 66371, 983405, 983379, 11322, 0, 93008, 3928, - 983152, 0, 10706, 7198, 0, 4842, 12053, 0, 0, 4841, 0, 4171, 12008, - 68416, 3923, 1490, 0, 0, 983395, 40972, 5245, 72288, 983397, 126578, 0, - 4845, 8332, 40974, 0, 4840, 9077, 2252, 2408, 72851, 4825, 0, 917574, 0, - 0, 126251, 0, 0, 983355, 0, 983356, 0, 4826, 42440, 0, 0, 1274, 0, 74315, - 0, 120384, 118614, 121200, 0, 0, 0, 4830, 983390, 129044, 0, 0, 119082, - 0, 64105, 0, 0, 4824, 120397, 0, 0, 1888, 64127, 7861, 125111, 78524, - 41836, 110613, 10873, 72439, 0, 64098, 12214, 0, 41834, 0, 358, 128120, - 41833, 11442, 0, 0, 0, 0, 64115, 0, 0, 0, 120721, 119053, 0, 119055, - 119054, 0, 0, 0, 0, 4017, 12827, 5241, 0, 73042, 41118, 3924, 0, 11366, - 0, 0, 0, 0, 41116, 69455, 0, 0, 0, 0, 11917, 0, 74000, 4721, 123551, - 983937, 0, 0, 0, 0, 0, 0, 122907, 0, 128702, 4722, 6816, 124974, 0, 4725, - 67099, 4726, 0, 129856, 123171, 0, 123194, 0, 0, 0, 4015, 0, 8052, 78766, - 123538, 0, 128294, 0, 0, 4720, 73090, 125003, 0, 0, 1656, 41831, 0, 0, - 41843, 92846, 0, 1452, 13111, 0, 0, 0, 8552, 64113, 41845, 64073, 120354, - 0, 0, 120066, 120067, 7064, 64070, 9948, 0, 0, 0, 92828, 2420, 92811, 0, - 0, 0, 120052, 120053, 120050, 74920, 3938, 120057, 120054, 92829, 120060, - 71920, 120058, 120059, 120064, 72203, 7955, 64074, 4713, 128196, 983107, - 0, 0, 0, 65152, 10198, 120044, 120045, 120042, 6713, 4532, 120049, - 120046, 120047, 4717, 7046, 0, 66450, 4712, 75055, 0, 121085, 0, 8155, - 4718, 3942, 4714, 9625, 0, 6383, 0, 12006, 0, 0, 0, 0, 0, 65414, 0, 0, - 129061, 66437, 66025, 74115, 0, 0, 11228, 4809, 0, 68211, 72352, 0, 0, 0, + 67093, 0, 0, 128514, 6650, 983488, 0, 983479, 78376, 4870, 0, 68661, + 6716, 983478, 2190, 69786, 68676, 0, 10122, 4864, 66568, 0, 0, 0, 9603, + 68652, 126213, 42734, 745, 0, 124131, 124130, 4777, 0, 77788, 68631, + 42775, 68196, 0, 124128, 124129, 0, 5966, 0, 4778, 127890, 0, 0, 4781, + 127196, 64407, 0, 74132, 8577, 71221, 0, 71223, 0, 4782, 0, 0, 120757, + 68618, 43472, 43056, 68622, 0, 92986, 4776, 0, 11492, 0, 0, 13176, 0, 0, + 0, 73558, 0, 0, 0, 4849, 8242, 9561, 73922, 0, 0, 0, 0, 5963, 0, 125201, + 0, 4850, 72121, 0, 590, 4853, 0, 4854, 0, 5164, 0, 1605, 5124, 0, 111165, + 0, 8471, 0, 111164, 12445, 3785, 0, 111162, 0, 0, 4848, 2530, 0, 2068, + 1964, 0, 0, 10796, 0, 0, 0, 0, 0, 4794, 0, 0, 0, 4797, 68040, 111152, + 43465, 4792, 0, 0, 0, 0, 0, 110842, 983102, 92963, 0, 0, 0, 4221, 92360, + 118869, 0, 0, 0, 70042, 0, 0, 0, 0, 10739, 65090, 0, 119327, 126541, 0, + 0, 119326, 0, 0, 4937, 43376, 0, 0, 10597, 983445, 11722, 9248, 129566, + 42879, 11725, 0, 0, 7579, 11141, 73958, 4941, 0, 917538, 9140, 4936, + 5261, 0, 0, 72298, 0, 4942, 0, 4938, 0, 0, 5259, 9369, 983434, 111182, + 5257, 78932, 6844, 4964, 5264, 0, 0, 0, 41411, 0, 121473, 73684, 128233, + 9482, 4873, 41991, 64707, 42526, 127989, 64480, 64725, 983447, 0, 0, 0, + 0, 0, 0, 73043, 0, 389, 10893, 7521, 0, 4872, 5463, 0, 3125, 111124, 0, + 4878, 5459, 4604, 0, 0, 5465, 0, 0, 0, 0, 9563, 0, 0, 128419, 125273, + 82963, 0, 0, 0, 67735, 0, 0, 0, 0, 0, 73560, 0, 129707, 0, 917833, 0, + 917836, 0, 0, 3082, 0, 0, 0, 0, 118621, 7079, 5856, 917842, 5163, 0, 0, + 1817, 66724, 0, 0, 10564, 7763, 13077, 124115, 0, 68140, 111137, 0, + 77782, 0, 111139, 123548, 77787, 121457, 0, 0, 0, 983190, 73081, 0, 0, + 983118, 124114, 0, 42156, 0, 0, 0, 983080, 0, 0, 0, 119254, 120693, 0, + 69386, 0, 118881, 0, 78189, 0, 78186, 78188, 129654, 0, 0, 0, 110877, 0, + 3108, 9745, 0, 0, 0, 118825, 92785, 0, 122954, 0, 0, 10972, 92786, 0, + 42768, 715, 983114, 121117, 9453, 5348, 10943, 0, 983170, 92784, 0, 0, + 983154, 0, 0, 11551, 128464, 0, 0, 9051, 0, 71728, 0, 120791, 119523, 0, + 6404, 66458, 68376, 11984, 9156, 65222, 74454, 78180, 0, 3128, 4789, + 5067, 5066, 0, 4784, 0, 8827, 1146, 5065, 78196, 78192, 78193, 78190, + 78191, 5064, 5326, 0, 9450, 5063, 120361, 78200, 78201, 5062, 69733, + 74146, 0, 0, 0, 0, 77992, 0, 3933, 77768, 0, 12337, 0, 125023, 0, 0, 0, + 194759, 0, 0, 82993, 42130, 0, 5151, 917832, 120357, 0, 73523, 0, 7620, + 3800, 0, 0, 0, 127952, 0, 0, 4786, 127991, 4185, 0, 128742, 0, 983194, + 73978, 0, 4593, 77715, 77727, 124909, 0, 110715, 10532, 77732, 110714, + 110711, 110712, 64759, 1325, 5166, 9888, 0, 5148, 0, 0, 78205, 78206, + 64140, 78204, 64131, 3119, 917814, 0, 983438, 917820, 12095, 0, 0, 636, + 128002, 0, 983469, 0, 78531, 7836, 42741, 64137, 0, 118969, 0, 92431, 0, + 0, 0, 0, 0, 8618, 0, 11865, 0, 0, 0, 3937, 12312, 128261, 0, 0, 0, 912, + 6349, 4536, 71964, 0, 126594, 0, 0, 0, 3935, 120665, 0, 0, 0, 0, 118859, + 0, 121116, 0, 0, 12046, 12599, 0, 0, 0, 0, 7227, 0, 0, 0, 983066, 0, 0, + 0, 113817, 2179, 78246, 0, 0, 0, 0, 0, 127405, 101531, 0, 101530, 43907, + 0, 0, 0, 0, 4644, 8818, 0, 0, 0, 0, 93066, 66452, 126081, 1644, 101043, + 9658, 43744, 11385, 65947, 983174, 43983, 0, 0, 0, 8962, 0, 0, 2466, + 42039, 67669, 0, 0, 42117, 100698, 0, 0, 0, 0, 43745, 5318, 0, 77723, 0, + 0, 0, 7054, 64147, 0, 917804, 68195, 6698, 0, 0, 0, 70849, 11981, 12202, + 0, 121364, 0, 7059, 11608, 975, 0, 65843, 170, 0, 67239, 42708, 0, 0, + 6058, 0, 0, 0, 70507, 0, 0, 9818, 0, 0, 42106, 0, 983065, 4738, 42105, + 7062, 0, 4737, 11779, 4742, 120564, 92391, 0, 41374, 41375, 983381, 6715, + 12700, 7049, 983379, 0, 0, 0, 4741, 42108, 983370, 64159, 4736, 64148, 0, + 849, 0, 128247, 983366, 0, 120913, 917997, 0, 983384, 9496, 66371, + 983408, 983382, 11322, 0, 93008, 3928, 983153, 0, 10706, 7198, 0, 4842, + 12053, 0, 0, 4841, 0, 4171, 12008, 68416, 3923, 1490, 0, 0, 983398, + 40972, 5245, 72288, 983400, 126578, 0, 4845, 8332, 40974, 0, 4840, 9077, + 2252, 2408, 72851, 4825, 0, 917574, 0, 0, 126251, 0, 0, 983358, 0, + 983359, 0, 4826, 42440, 0, 0, 1274, 0, 74315, 0, 120384, 118614, 121200, + 0, 0, 0, 4830, 983393, 129044, 0, 0, 119082, 0, 64105, 0, 0, 4824, + 120397, 0, 0, 1888, 64127, 7861, 125111, 78524, 41836, 110613, 10873, + 72439, 0, 64098, 12214, 124134, 41834, 0, 358, 128120, 41833, 11442, 0, + 0, 0, 0, 64115, 0, 0, 0, 120721, 119053, 0, 119055, 119054, 0, 0, 0, 0, + 4017, 12827, 5241, 0, 73042, 41118, 3924, 0, 11366, 0, 0, 0, 0, 41116, + 69455, 0, 0, 0, 0, 11917, 0, 74000, 4721, 123551, 983937, 0, 0, 0, 0, 0, + 0, 122907, 0, 128702, 4722, 6816, 124974, 0, 4725, 67099, 4726, 0, + 129856, 123171, 0, 123194, 0, 0, 0, 4015, 0, 8052, 78766, 123538, 0, + 128294, 0, 0, 4720, 73090, 125003, 0, 0, 1656, 41831, 0, 0, 41843, 92846, + 0, 1452, 13111, 0, 0, 0, 8552, 64113, 41845, 64073, 120354, 0, 0, 120066, + 120067, 7064, 64070, 9948, 0, 0, 0, 92828, 2420, 92811, 0, 0, 0, 120052, + 120053, 120050, 74920, 3938, 120057, 120054, 92829, 120060, 71920, + 120058, 120059, 120064, 72203, 7955, 64074, 4713, 128196, 983108, 0, 0, + 0, 65152, 10198, 120044, 120045, 120042, 6713, 4532, 120049, 120046, + 120047, 4717, 7046, 0, 66450, 4712, 75055, 0, 121085, 0, 8155, 4718, + 3942, 4714, 9625, 0, 6383, 0, 12006, 0, 0, 0, 0, 0, 65414, 0, 0, 129061, + 66437, 66025, 74115, 0, 0, 11228, 4809, 0, 68211, 72352, 0, 0, 983101, 65405, 129912, 0, 0, 2163, 4545, 0, 917566, 0, 4813, 78699, 0, 0, 4808, 0, 0, 65475, 0, 0, 4814, 72240, 4810, 0, 0, 68784, 10761, 67514, 3522, 0, 78693, 65404, 0, 0, 0, 0, 0, 6691, 70125, 0, 126223, 0, 0, 0, 43858, @@ -29683,35 +29883,35 @@ static const unsigned int code_hash[] = { 2315, 0, 1938, 0, 0, 0, 0, 0, 0, 0, 111135, 93794, 0, 0, 0, 93810, 0, 2291, 0, 0, 0, 0, 129429, 0, 10799, 0, 0, 66372, 0, 4193, 0, 0, 983057, 7998, 0, 0, 0, 0, 2316, 0, 0, 0, 0, 120106, 0, 0, 74140, 0, 0, 0, 0, - 3762, 93813, 120672, 93820, 0, 0, 0, 70098, 3780, 12808, 8163, 983154, 0, + 3762, 93813, 120672, 93820, 0, 0, 0, 70098, 3780, 12808, 8163, 983155, 0, 0, 3906, 12349, 0, 8326, 0, 65498, 3763, 0, 5618, 0, 3779, 0, 43613, 0, - 128007, 0, 0, 0, 0, 280, 0, 126252, 983450, 13072, 1894, 0, 0, 65478, - 43310, 7231, 0, 11773, 0, 0, 0, 101517, 0, 0, 7559, 11652, 10009, 110765, - 110766, 110763, 110764, 4470, 110762, 0, 0, 983443, 0, 5249, 0, 0, 8756, - 0, 0, 41694, 120585, 92349, 0, 0, 0, 69685, 123549, 983447, 113794, 0, - 6808, 41319, 13125, 66332, 127977, 0, 2290, 0, 983415, 0, 0, 3943, 0, - 41205, 0, 0, 0, 0, 5352, 0, 0, 41207, 0, 7384, 69647, 41204, 123552, - 41209, 69637, 0, 43607, 0, 0, 5420, 0, 10134, 0, 0, 4018, 7150, 0, 0, 0, - 0, 0, 129606, 2561, 65023, 0, 7148, 12076, 0, 0, 129201, 0, 6276, 1706, - 0, 0, 7146, 0, 128277, 41819, 74991, 0, 10847, 41822, 72248, 860, 0, 0, - 0, 69641, 10753, 41820, 126118, 0, 71898, 0, 92617, 128567, 0, 121514, - 43016, 0, 0, 92225, 0, 0, 0, 0, 4022, 0, 0, 110807, 0, 41691, 0, 75060, - 11866, 0, 65292, 0, 110812, 0, 3911, 110811, 110808, 110809, 0, 125191, - 7000, 3904, 118997, 72261, 0, 0, 0, 13123, 10846, 0, 0, 0, 0, 0, 74082, - 0, 123542, 0, 0, 3777, 128329, 0, 9636, 71726, 0, 0, 9367, 593, 0, 3999, - 0, 41713, 0, 0, 67677, 0, 0, 0, 9763, 120280, 120283, 12347, 124, 12981, - 41127, 92527, 0, 0, 0, 0, 0, 43987, 0, 0, 1769, 41715, 2463, 2151, 0, 0, - 71222, 1538, 93044, 0, 0, 123543, 7795, 120300, 0, 92493, 10955, 0, 0, - 72375, 78208, 9498, 78207, 127033, 78210, 120288, 3939, 120290, 120285, - 8943, 120287, 120286, 120297, 4491, 120299, 42602, 120293, 120292, - 120295, 120294, 0, 0, 0, 0, 0, 0, 1511, 9324, 0, 0, 0, 0, 0, 64536, 0, 0, - 0, 124935, 6822, 12862, 0, 0, 42143, 41828, 0, 917629, 70864, 118879, 0, - 0, 0, 41826, 128413, 0, 0, 13279, 7917, 0, 0, 0, 0, 0, 92800, 92332, 0, - 0, 43515, 0, 0, 0, 4013, 0, 66980, 0, 72224, 125266, 0, 68243, 2432, - 92834, 0, 0, 0, 0, 69952, 0, 0, 0, 10949, 0, 0, 0, 0, 0, 0, 0, 128574, - 43233, 0, 42517, 0, 0, 0, 0, 0, 64468, 119359, 6474, 119358, 43497, - 12656, 128122, 119353, 0, 1665, 0, 0, 0, 64512, 0, 0, 5256, 0, 0, 0, - 2859, 123563, 0, 0, 0, 0, 92801, 128220, 0, 770, 0, 811, 0, 0, 917551, + 128007, 0, 0, 0, 0, 280, 0, 126252, 983453, 13072, 1894, 0, 0, 65478, + 43310, 7231, 0, 11773, 0, 0, 0, 101517, 122662, 0, 7559, 11652, 10009, + 110765, 110766, 110763, 110764, 4470, 110762, 0, 0, 983446, 0, 5249, 0, + 0, 8756, 0, 0, 41694, 120585, 92349, 0, 0, 0, 69685, 123549, 983450, + 113794, 0, 6808, 41319, 13125, 66332, 127977, 0, 2290, 0, 983418, 0, 0, + 3943, 0, 41205, 0, 0, 0, 0, 5352, 0, 0, 41207, 0, 7384, 69647, 41204, + 123552, 41209, 69637, 0, 43607, 0, 0, 5420, 0, 10134, 0, 0, 4018, 7150, + 0, 0, 0, 0, 0, 129606, 2561, 65023, 0, 7148, 12076, 0, 0, 129201, 0, + 6276, 1706, 0, 0, 7146, 0, 128277, 41819, 74991, 0, 10847, 41822, 72248, + 860, 0, 0, 0, 69641, 10753, 41820, 126118, 0, 71898, 0, 92617, 128567, 0, + 121514, 43016, 0, 0, 92225, 0, 0, 0, 0, 4022, 0, 0, 110807, 0, 41691, 0, + 75060, 11866, 0, 65292, 0, 110812, 0, 3911, 110811, 110808, 110809, 0, + 125191, 7000, 3904, 118997, 72261, 0, 0, 0, 13123, 10846, 0, 0, 0, 0, 0, + 74082, 0, 123542, 0, 0, 3777, 128329, 0, 9636, 71726, 0, 0, 9367, 593, 0, + 3999, 0, 41713, 0, 0, 67677, 0, 0, 0, 9763, 120280, 120283, 12347, 124, + 12981, 41127, 92527, 0, 0, 0, 0, 0, 43987, 0, 0, 1769, 41715, 2463, 2151, + 0, 0, 71222, 1538, 93044, 0, 0, 123543, 7795, 120300, 0, 92493, 10955, 0, + 0, 72375, 78208, 9498, 78207, 127033, 78210, 120288, 3939, 120290, + 120285, 8943, 120287, 120286, 120297, 4491, 120299, 42602, 120293, + 120292, 120295, 120294, 0, 0, 0, 0, 0, 0, 1511, 9324, 0, 0, 0, 0, 0, + 64536, 0, 0, 0, 124935, 6822, 12862, 0, 0, 42143, 41828, 0, 917629, + 70864, 118879, 0, 0, 0, 41826, 128413, 0, 0, 13279, 7917, 0, 0, 0, 0, 0, + 92800, 92332, 0, 0, 43515, 0, 0, 0, 4013, 0, 66980, 0, 72224, 125266, 0, + 68243, 2432, 92834, 0, 0, 0, 0, 69952, 0, 0, 0, 10949, 0, 0, 0, 0, 0, 0, + 0, 128574, 43233, 0, 42517, 0, 0, 0, 0, 0, 64468, 119359, 6474, 119358, + 43497, 12656, 128122, 119353, 0, 1665, 0, 0, 0, 64512, 0, 0, 5256, 0, 0, + 0, 2859, 123563, 0, 0, 0, 0, 92801, 128220, 0, 770, 0, 811, 0, 0, 917551, 42244, 64427, 0, 72222, 0, 3895, 0, 74341, 12087, 0, 42859, 10193, 3116, 7747, 0, 0, 43496, 0, 0, 0, 0, 41877, 0, 65382, 64614, 0, 64296, 0, 6345, 0, 2663, 0, 121234, 0, 0, 10150, 0, 64308, 1522, 597, 0, 0, 41201, 64731, @@ -29746,19 +29946,19 @@ static const unsigned int code_hash[] = { 0, 67708, 0, 119346, 0, 5959, 0, 0, 66275, 43371, 0, 0, 0, 0, 0, 12769, 69793, 0, 1283, 0, 4779, 0, 3719, 4006, 0, 0, 71186, 68204, 124957, 0, 119331, 43028, 65493, 0, 125058, 5962, 65485, 92616, 0, 43501, 5827, 0, - 120951, 0, 65494, 0, 129365, 0, 0, 43879, 0, 0, 0, 0, 983203, 65467, 0, + 120951, 0, 65494, 0, 129365, 0, 0, 43879, 0, 0, 0, 0, 983205, 65467, 0, 0, 0, 0, 521, 0, 0, 983928, 0, 0, 483, 7096, 0, 0, 928, 0, 0, 0, 0, - 92983, 3989, 73972, 0, 0, 0, 0, 12145, 0, 73932, 0, 0, 3769, 67460, 0, 0, - 0, 0, 0, 65290, 92223, 0, 65855, 0, 0, 0, 0, 128811, 0, 0, 0, 0, 0, 0, - 73838, 0, 0, 13007, 67506, 0, 0, 12661, 7608, 75032, 12213, 0, 0, 0, 0, - 12195, 4001, 3112, 67474, 0, 7590, 0, 0, 421, 0, 0, 0, 4130, 127775, + 92983, 3989, 73972, 122980, 0, 0, 0, 12145, 0, 73932, 0, 0, 3769, 67460, + 0, 0, 0, 0, 0, 65290, 92223, 0, 65855, 0, 0, 0, 0, 128811, 0, 0, 0, 0, 0, + 0, 73838, 0, 0, 13007, 67506, 0, 0, 12661, 7608, 75032, 12213, 0, 0, 0, + 0, 12195, 4001, 3112, 67474, 0, 7590, 0, 0, 421, 0, 0, 0, 4130, 127775, 7595, 42588, 7600, 0, 0, 0, 0, 65851, 42607, 0, 92403, 8680, 0, 42134, 0, 0, 2846, 92605, 0, 0, 0, 0, 12979, 0, 0, 92558, 3740, 69843, 120437, 0, 120451, 65923, 120435, 0, 120434, 0, 93800, 3118, 74265, 93795, 93816, 93823, 93797, 8127, 92912, 93792, 7943, 93821, 93799, 10618, 2584, 93793, 0, 0, 9998, 0, 0, 0, 66350, 0, 0, 0, 121374, 8279, 128169, 0, 4975, 70075, 0, 118675, 1631, 0, 0, 0, 6290, 128994, 66386, 0, 64645, 0, 0, 0, - 0, 0, 9242, 93807, 93802, 93801, 983266, 93803, 3122, 93804, 7793, 0, 0, + 0, 0, 9242, 93807, 93802, 93801, 983269, 93803, 3122, 93804, 7793, 0, 0, 0, 0, 12604, 92885, 6615, 67650, 0, 3986, 44025, 0, 8912, 0, 7409, 0, 0, 0, 0, 0, 0, 8540, 11498, 0, 0, 0, 0, 0, 13060, 120682, 0, 0, 0, 0, 0, 121345, 0, 0, 7020, 120353, 3765, 92881, 0, 1606, 120348, 120351, 3093, @@ -29768,150 +29968,151 @@ static const unsigned int code_hash[] = { 42758, 12196, 128429, 0, 0, 0, 0, 128867, 94179, 0, 3120, 9797, 0, 0, 11086, 10389, 0, 101025, 4895, 128153, 124941, 4359, 0, 0, 3509, 70037, 486, 0, 0, 0, 0, 0, 7004, 0, 0, 0, 0, 4855, 128200, 0, 0, 0, 0, 0, 0, - 10381, 70839, 0, 0, 0, 0, 125121, 70837, 125070, 129431, 983374, 983362, - 0, 983361, 0, 120063, 0, 0, 0, 75048, 0, 74900, 0, 0, 120978, 12161, - 983353, 0, 10339, 0, 77808, 0, 0, 0, 77806, 0, 43032, 125010, 0, 983380, - 12671, 11384, 0, 0, 120901, 64797, 0, 5820, 0, 0, 0, 0, 0, 120650, 42137, - 9893, 8851, 12664, 0, 0, 13192, 0, 41799, 65530, 0, 0, 43039, 3114, 0, 0, - 0, 0, 0, 926, 77803, 72004, 77805, 77799, 77800, 77801, 77802, 43037, - 41798, 77797, 77798, 123214, 41801, 0, 0, 0, 4200, 12699, 8331, 70118, - 3091, 92980, 66298, 70293, 8360, 0, 78044, 0, 4229, 64543, 126227, 65563, - 0, 129310, 2861, 43793, 10095, 121428, 9195, 121381, 121132, 0, 129578, - 0, 0, 43041, 0, 43794, 0, 83167, 0, 43797, 8209, 0, 129132, 12973, 0, 0, - 0, 0, 0, 121235, 5760, 0, 743, 0, 0, 0, 118712, 0, 0, 83170, 128589, - 129537, 0, 119063, 0, 0, 0, 19919, 0, 64532, 0, 43710, 0, 0, 9483, 71115, - 0, 43697, 0, 0, 83211, 0, 0, 0, 7247, 0, 0, 0, 0, 0, 113674, 0, 7471, - 120823, 128743, 12682, 0, 0, 65679, 983143, 0, 0, 83201, 1099, 74241, 0, - 10501, 0, 0, 113743, 0, 64743, 128476, 67663, 0, 0, 92219, 0, 83197, - 64897, 9973, 1818, 0, 0, 8272, 127812, 0, 4218, 3087, 0, 127234, 0, - 101300, 65181, 9954, 10465, 0, 0, 0, 9106, 0, 67406, 0, 0, 0, 0, 43038, - 0, 0, 265, 0, 0, 0, 0, 0, 0, 69405, 0, 59, 0, 0, 0, 0, 126239, 41810, 0, - 126492, 0, 41809, 41888, 0, 41795, 0, 42213, 0, 0, 43033, 511, 42963, 0, - 13127, 0, 0, 0, 0, 111107, 0, 4467, 41812, 41215, 0, 41211, 917783, 4453, - 69575, 0, 129883, 0, 983409, 41213, 92864, 118716, 0, 0, 129730, 41841, - 6617, 130041, 0, 92995, 462, 0, 10493, 0, 55248, 0, 0, 74471, 6644, 0, 0, - 0, 983385, 100484, 9581, 67104, 3098, 0, 0, 983412, 125250, 0, 120621, 0, - 0, 0, 129584, 101011, 0, 118789, 74473, 3755, 64661, 7748, 7235, 3966, 0, - 0, 127510, 0, 0, 0, 5726, 66456, 42175, 100486, 0, 42212, 92681, 121443, - 2851, 43017, 120108, 121056, 4373, 0, 0, 9587, 0, 6671, 128840, 3100, 0, - 917790, 0, 0, 0, 917789, 73836, 8190, 12083, 917791, 0, 6689, 64629, 0, - 0, 0, 4419, 917787, 101017, 0, 69851, 0, 0, 8891, 3080, 0, 2347, 0, 0, - 8990, 0, 121201, 0, 92528, 249, 129008, 0, 69424, 0, 0, 0, 55253, 0, 0, - 11173, 995, 0, 121047, 119861, 0, 73708, 0, 0, 19945, 0, 558, 983396, - 12273, 0, 983881, 0, 69912, 120861, 129492, 67274, 94178, 0, 68019, - 43030, 3129, 0, 2102, 0, 0, 121450, 0, 7725, 0, 11120, 0, 126111, 69246, - 0, 0, 0, 41894, 0, 41898, 0, 41893, 74921, 128678, 3540, 11848, 0, 73005, - 120848, 0, 0, 126113, 73959, 0, 0, 128735, 120858, 0, 0, 9699, 128656, - 41896, 0, 83196, 69230, 74951, 0, 72736, 0, 0, 3095, 983689, 11946, - 983885, 0, 0, 0, 0, 0, 113677, 3672, 119864, 0, 0, 0, 128539, 8890, - 93826, 0, 128182, 0, 0, 0, 126568, 0, 0, 983617, 9516, 983438, 72109, 0, - 42220, 0, 4450, 0, 11547, 43417, 128542, 356, 0, 0, 0, 0, 64901, 0, 0, 0, - 0, 0, 0, 111302, 65940, 2541, 71231, 0, 123215, 126470, 3549, 0, 0, 0, - 2743, 0, 0, 0, 9097, 128896, 43015, 0, 0, 776, 2524, 0, 8573, 100665, - 126494, 0, 0, 42694, 71122, 8952, 10814, 118818, 0, 43646, 128598, 66944, - 0, 0, 128380, 100663, 0, 65853, 42707, 1897, 93071, 0, 0, 71907, 69410, - 0, 125106, 0, 0, 0, 68473, 66778, 43573, 92638, 0, 0, 0, 120955, 73986, - 0, 0, 43022, 0, 74841, 0, 67714, 0, 0, 0, 0, 0, 4553, 0, 0, 0, 0, 0, - 19921, 0, 0, 983687, 4567, 41891, 0, 983819, 55249, 194663, 0, 194662, 0, - 194665, 43042, 121291, 1377, 12869, 0, 0, 9250, 0, 0, 0, 129779, 125039, - 194642, 0, 74995, 0, 194644, 0, 0, 101328, 194668, 121166, 0, 70275, - 1898, 69556, 0, 0, 802, 0, 0, 0, 6648, 0, 2528, 0, 0, 194646, 194625, - 101330, 68804, 844, 0, 68824, 0, 68818, 194650, 0, 0, 0, 983743, 65464, - 0, 0, 0, 0, 83221, 0, 0, 100680, 42954, 0, 64371, 70665, 0, 194654, 0, 0, - 0, 0, 0, 6196, 6945, 0, 0, 0, 120491, 0, 68846, 6210, 0, 70274, 0, 0, 0, - 68067, 68834, 194715, 588, 9760, 129112, 0, 983723, 128798, 0, 127992, 0, - 0, 118905, 0, 0, 92485, 110839, 69396, 0, 3394, 70734, 194639, 0, 0, 0, - 0, 0, 0, 194656, 7817, 1841, 11055, 195001, 194979, 194983, 127011, - 67403, 194987, 7701, 194998, 0, 194995, 1946, 121404, 0, 0, 917631, 0, 0, - 10934, 0, 70376, 0, 0, 8071, 3538, 0, 2287, 65328, 0, 0, 7614, 0, 0, 0, - 12009, 43968, 0, 67852, 0, 0, 10841, 123640, 0, 0, 0, 0, 8960, 0, 0, - 65317, 128829, 0, 0, 70374, 0, 0, 0, 65315, 0, 0, 0, 0, 0, 119621, 0, - 11849, 12447, 0, 0, 110741, 0, 0, 0, 129976, 42767, 0, 0, 0, 43695, - 120520, 11975, 194941, 983445, 0, 2555, 0, 128640, 70070, 42936, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66714, 0, 0, 70076, 65596, 121034, 66710, 67658, - 0, 126994, 65338, 7792, 0, 0, 67871, 119027, 0, 8233, 43572, 0, 0, 0, - 3442, 0, 2841, 12543, 0, 1473, 42820, 64329, 127832, 917772, 126126, - 7937, 0, 1048, 0, 0, 983943, 0, 3406, 1054, 100701, 1040, 65450, 0, - 92329, 1069, 917763, 128367, 128940, 0, 917765, 0, 983724, 9693, 110873, - 0, 0, 0, 983948, 4353, 118653, 1059, 127530, 0, 0, 0, 127093, 118862, - 120500, 10646, 118708, 100710, 917762, 70424, 74830, 0, 0, 983720, 10221, - 100706, 68255, 0, 0, 74346, 119619, 100707, 64945, 12921, 0, 0, 0, 0, 0, - 983795, 43020, 0, 0, 74254, 0, 983785, 0, 0, 983792, 0, 71954, 0, 0, 0, - 0, 122625, 0, 120503, 70663, 0, 2755, 0, 0, 0, 4857, 0, 4428, 0, 0, - 983791, 0, 0, 0, 43842, 0, 122899, 0, 7978, 0, 70392, 127080, 11924, - 43812, 0, 65015, 67472, 563, 68340, 0, 12798, 0, 100727, 0, 0, 0, 74110, - 0, 94051, 0, 694, 0, 9876, 0, 119168, 0, 0, 0, 92361, 0, 0, 7229, 0, 0, - 0, 0, 64811, 0, 119087, 126478, 0, 7381, 0, 2525, 4852, 11586, 68465, - 41605, 126089, 0, 11582, 7151, 10155, 92578, 188, 0, 11592, 0, 74015, 0, - 0, 4858, 122645, 0, 0, 4861, 0, 2786, 121431, 4856, 8051, 0, 119609, 0, - 113797, 71133, 0, 78448, 0, 0, 67842, 68084, 0, 0, 0, 0, 0, 10234, 5843, - 0, 71865, 66728, 0, 3157, 0, 0, 75035, 72788, 983750, 0, 10822, 5149, - 129517, 0, 65142, 129454, 4565, 0, 0, 0, 12657, 0, 0, 386, 0, 8834, - 120974, 0, 43574, 0, 0, 0, 70113, 7220, 11839, 124984, 74883, 194752, 0, - 65241, 74503, 8160, 0, 194753, 0, 0, 0, 0, 0, 121265, 6847, 13303, 0, 0, - 194755, 0, 118865, 0, 194761, 0, 0, 74505, 0, 0, 0, 100518, 194721, 8780, - 100512, 0, 68745, 110626, 66697, 0, 2672, 3735, 983641, 0, 68752, 11205, - 10724, 41202, 0, 100714, 0, 0, 0, 0, 194765, 3842, 0, 78183, 12442, - 78182, 9791, 78181, 0, 42516, 67730, 64821, 195059, 78178, 0, 78464, - 119219, 78465, 127466, 194690, 195063, 0, 0, 0, 0, 78540, 78541, 78538, - 1962, 78490, 78476, 65930, 11660, 0, 2072, 0, 0, 78544, 194704, 78542, - 10669, 110859, 110860, 110857, 110858, 129749, 110856, 4105, 0, 194699, - 0, 0, 0, 13148, 195068, 78479, 9226, 0, 0, 10765, 127486, 71919, 6263, - 195050, 0, 195041, 0, 0, 0, 0, 0, 0, 92312, 7886, 0, 6682, 0, 6680, - 195042, 126473, 195052, 6679, 74412, 0, 72206, 74421, 66281, 0, 0, - 127478, 0, 0, 92861, 6681, 0, 12693, 0, 0, 0, 0, 0, 65442, 129055, 0, - 9989, 74415, 194673, 0, 0, 983788, 0, 0, 0, 0, 7042, 127240, 119026, - 7968, 0, 983768, 194741, 194736, 983793, 0, 69889, 74389, 128696, 0, 0, - 128979, 5781, 0, 78199, 0, 0, 11091, 0, 2719, 0, 0, 0, 64495, 0, 0, 0, - 65169, 42845, 0, 128551, 983766, 2200, 72435, 0, 0, 0, 917855, 66670, 0, - 983709, 0, 0, 0, 7902, 0, 65265, 0, 0, 0, 0, 0, 0, 0, 12994, 0, 10828, - 983974, 0, 4307, 3482, 0, 0, 72389, 0, 64299, 74573, 41194, 7343, 0, 0, - 41195, 0, 8169, 0, 8841, 66770, 516, 72981, 41197, 119051, 34, 128850, - 120186, 11504, 1612, 120187, 120182, 120181, 120184, 12001, 120178, - 120177, 120180, 120179, 71966, 120173, 7749, 120175, 0, 1758, 0, 10667, - 0, 120197, 0, 1935, 11517, 120193, 120196, 120195, 120190, 120189, - 120192, 120191, 1217, 64702, 128075, 825, 0, 0, 0, 0, 66748, 0, 11050, 0, - 123187, 0, 0, 74554, 110577, 0, 8677, 123188, 11313, 123185, 3403, 0, - 123186, 64364, 92683, 0, 0, 0, 0, 123189, 0, 0, 983880, 0, 69408, 41850, - 0, 3433, 127965, 0, 1594, 65607, 0, 66392, 0, 129291, 74565, 41353, - 125119, 0, 0, 0, 0, 918, 127280, 41351, 0, 0, 12140, 0, 12668, 72395, 0, - 128753, 0, 127302, 0, 127288, 129497, 127235, 573, 0, 0, 11417, 0, - 127283, 0, 0, 0, 72410, 0, 11482, 0, 3981, 74345, 0, 0, 0, 0, 0, 0, - 125238, 0, 0, 42195, 0, 123190, 0, 64602, 0, 0, 121366, 0, 121061, - 128690, 0, 8423, 0, 448, 66907, 9717, 0, 0, 0, 0, 0, 0, 0, 71910, 129898, - 0, 0, 120679, 65013, 78169, 0, 72390, 0, 0, 127917, 0, 74892, 0, 0, - 127798, 0, 0, 66982, 0, 0, 0, 12197, 125074, 0, 121447, 0, 0, 0, 0, 0, 0, - 0, 74563, 64828, 11419, 0, 8592, 0, 0, 0, 11381, 0, 0, 74529, 0, 0, - 83254, 0, 72796, 0, 83257, 0, 0, 0, 129437, 65672, 0, 0, 0, 0, 0, 0, 0, - 0, 9505, 0, 0, 756, 0, 125243, 100358, 110852, 7261, 0, 0, 0, 0, 0, - 64401, 65830, 41365, 0, 0, 0, 127834, 0, 0, 0, 0, 0, 74626, 123155, - 11578, 0, 2170, 0, 0, 0, 0, 74568, 0, 113684, 1794, 68310, 120218, - 120219, 120220, 120221, 120222, 120223, 3617, 120011, 64886, 94061, - 78202, 120213, 66999, 10225, 983060, 0, 65223, 983058, 0, 0, 4452, - 127779, 0, 0, 66981, 0, 0, 0, 11425, 0, 0, 1231, 0, 0, 0, 0, 8192, 0, 0, - 0, 10616, 8694, 0, 68867, 128332, 123595, 120200, 120201, 120202, 120203, - 9878, 120205, 119626, 120207, 0, 8799, 42131, 0, 127163, 0, 120198, - 120199, 837, 120015, 72384, 0, 983836, 2180, 11427, 0, 78154, 0, 70171, - 0, 78150, 42606, 0, 119615, 78147, 64637, 78146, 43060, 78145, 125009, - 3392, 0, 194783, 119067, 119650, 65468, 43498, 126083, 0, 0, 0, 194928, - 194937, 194938, 64681, 194930, 83264, 92451, 0, 194955, 83262, 983751, - 8973, 0, 194967, 70177, 194968, 0, 4800, 195018, 0, 0, 11820, 6852, 0, 0, - 4802, 4111, 111268, 0, 4805, 127308, 68193, 7885, 121220, 0, 0, 0, 4767, - 0, 0, 0, 0, 0, 125234, 100366, 43453, 0, 41340, 0, 0, 10005, 65856, - 41333, 0, 9518, 0, 0, 0, 42520, 100850, 0, 0, 917562, 100506, 0, 0, 0, 0, - 0, 0, 9167, 42151, 124958, 0, 2026, 100848, 0, 0, 100534, 12768, 0, 7582, - 0, 0, 0, 0, 129557, 0, 120539, 68879, 0, 43547, 119992, 8546, 126071, - 78520, 7604, 78518, 78519, 78514, 78517, 78511, 78512, 73802, 128140, 0, - 6708, 10535, 0, 68218, 55274, 68221, 92296, 0, 0, 0, 0, 0, 72385, 0, 0, - 0, 73727, 0, 120706, 74442, 66943, 0, 0, 4351, 0, 119887, 119888, 0, - 119886, 119891, 68866, 119889, 11433, 119895, 119896, 0, 119894, 65578, - 194693, 0, 0, 983070, 10681, 0, 0, 128737, 0, 983110, 0, 6722, 129364, 0, - 119997, 41546, 64860, 68394, 0, 41549, 118619, 72386, 0, 0, 0, 0, 64710, - 41547, 0, 0, 0, 78530, 78532, 78528, 78529, 71343, 78527, 78523, 78525, - 3537, 119908, 119905, 7155, 2264, 0, 78533, 67755, 0, 0, 0, 0, 0, 0, 0, - 64715, 0, 0, 537, 0, 4179, 0, 0, 0, 0, 0, 0, 0, 0, 12081, 0, 0, 4048, - 7053, 0, 0, 70459, 0, 124975, 0, 3059, 0, 0, 43491, 983833, 0, 0, 127993, - 4100, 920, 1811, 1355, 0, 0, 64383, 10078, 69398, 0, 118651, 0, 65870, 0, + 10381, 70839, 0, 0, 0, 0, 125121, 70837, 125070, 129431, 983377, 983365, + 0, 983364, 0, 120063, 0, 0, 0, 75048, 0, 74900, 0, 0, 120978, 12161, + 983356, 0, 10339, 0, 77808, 0, 0, 917846, 77806, 0, 43032, 125010, 0, + 983383, 12671, 11384, 0, 0, 120901, 64797, 0, 5820, 0, 0, 0, 0, 0, + 120650, 42137, 9893, 8851, 12664, 0, 0, 13192, 0, 41799, 65530, 0, 0, + 43039, 3114, 0, 0, 0, 0, 0, 926, 77803, 72004, 77805, 77799, 77800, + 77801, 77802, 43037, 41798, 77797, 77798, 123214, 41801, 0, 0, 0, 4200, + 12699, 8331, 70118, 3091, 92980, 66298, 70293, 8360, 0, 78044, 0, 4229, + 64543, 126227, 65563, 0, 129310, 2861, 43793, 10095, 121428, 9195, + 121381, 121132, 0, 129578, 0, 0, 43041, 0, 43794, 0, 83167, 0, 43797, + 8209, 0, 129132, 12973, 0, 0, 0, 0, 0, 121235, 5760, 0, 743, 0, 0, 0, + 118712, 0, 0, 83170, 128589, 129537, 0, 119063, 0, 0, 0, 19919, 0, 64532, + 0, 43710, 0, 0, 9483, 71115, 0, 43697, 0, 0, 83211, 0, 0, 0, 7247, 0, 0, + 0, 0, 0, 113674, 0, 7471, 120823, 128743, 12682, 0, 0, 65679, 983144, 0, + 0, 83201, 1099, 74241, 0, 10501, 0, 0, 113743, 0, 64743, 128476, 67663, + 0, 0, 92219, 0, 83197, 64897, 9973, 1818, 0, 0, 8272, 127812, 0, 4218, + 3087, 0, 127234, 122935, 101300, 65181, 9954, 10465, 0, 0, 0, 9106, 0, + 67406, 0, 0, 0, 0, 43038, 0, 0, 265, 70208, 0, 0, 0, 0, 0, 69405, 0, 59, + 0, 0, 0, 0, 126239, 41810, 0, 126492, 0, 41809, 41888, 0, 41795, 0, + 42213, 0, 0, 43033, 511, 42963, 0, 13127, 0, 0, 0, 0, 111107, 100489, + 4467, 41812, 41215, 0, 41211, 917783, 4453, 69575, 0, 129883, 0, 983412, + 41213, 92864, 118716, 0, 0, 129730, 41841, 6617, 130041, 0, 92995, 462, + 0, 10493, 0, 55248, 0, 0, 74471, 6644, 0, 0, 0, 983388, 100484, 9581, + 67104, 3098, 0, 0, 983415, 125250, 0, 120621, 0, 0, 0, 129584, 101011, 0, + 118789, 74473, 3755, 64661, 7748, 7235, 3966, 0, 0, 127510, 0, 0, 0, + 5726, 66456, 42175, 100486, 0, 42212, 92681, 121443, 2851, 43017, 120108, + 121056, 4373, 0, 0, 9587, 0, 6671, 128840, 3100, 0, 917790, 0, 0, 0, + 917789, 70209, 8190, 12083, 917791, 0, 6689, 64629, 0, 0, 0, 4419, + 917787, 101017, 0, 69851, 0, 0, 8891, 3080, 0, 2347, 0, 0, 8990, 0, + 121201, 0, 92528, 249, 129008, 0, 69424, 0, 0, 0, 55253, 0, 0, 11173, + 995, 0, 121047, 119861, 0, 73708, 0, 0, 19945, 0, 558, 983399, 12273, 0, + 983881, 0, 69912, 120861, 129492, 67274, 94178, 0, 68019, 43030, 3129, 0, + 2102, 0, 0, 121450, 0, 7725, 0, 11120, 0, 126111, 69246, 0, 0, 0, 41894, + 0, 41898, 0, 41893, 74921, 128678, 3540, 11848, 0, 73005, 120848, 0, 0, + 126113, 73959, 0, 0, 128735, 120858, 0, 0, 9699, 128656, 41896, 0, 83196, + 69230, 74951, 0, 72736, 0, 0, 3095, 983689, 11946, 983885, 0, 0, 0, 0, 0, + 113677, 3672, 111309, 0, 0, 0, 128539, 8890, 93826, 0, 128182, 0, 0, 0, + 126568, 0, 0, 983617, 9516, 983441, 72109, 0, 42220, 0, 4450, 0, 11547, + 43417, 128542, 356, 0, 0, 0, 0, 64901, 0, 0, 0, 0, 0, 0, 111302, 65940, + 2541, 71231, 0, 123215, 126470, 3549, 0, 0, 0, 2743, 0, 0, 0, 9097, + 128896, 43015, 0, 0, 776, 2524, 0, 8573, 100665, 126494, 0, 0, 42694, + 71122, 8952, 10814, 118818, 0, 43646, 128598, 66944, 0, 0, 128380, + 100663, 0, 65853, 42707, 1897, 93071, 0, 0, 71907, 69410, 0, 125106, 0, + 0, 0, 68473, 66778, 43573, 92638, 0, 0, 0, 120955, 73986, 0, 0, 43022, 0, + 74841, 0, 67714, 0, 0, 0, 0, 0, 4553, 0, 0, 0, 0, 0, 19921, 0, 0, 983687, + 4567, 41891, 0, 983819, 55249, 194663, 0, 194662, 0, 194665, 43042, + 121291, 1377, 12869, 0, 0, 9250, 0, 0, 0, 129779, 125039, 194642, 0, + 74995, 0, 194644, 0, 0, 101328, 194668, 121166, 0, 70275, 1898, 69556, 0, + 0, 802, 0, 0, 0, 6648, 0, 2528, 0, 0, 194646, 194625, 101330, 68804, 844, + 0, 68824, 0, 68818, 194650, 0, 0, 0, 983743, 65464, 0, 0, 0, 0, 83221, 0, + 0, 100680, 42954, 0, 64371, 70665, 0, 194654, 0, 0, 0, 0, 0, 6196, 6945, + 0, 0, 0, 120491, 0, 68846, 6210, 0, 70274, 0, 0, 0, 68067, 68834, 194715, + 588, 9760, 129112, 0, 983723, 119505, 0, 127992, 0, 0, 118905, 0, 0, + 92485, 110839, 69396, 0, 3394, 70734, 194639, 0, 0, 0, 0, 0, 0, 194656, + 7817, 1841, 11055, 195001, 194979, 194983, 127011, 67403, 194987, 7701, + 194998, 0, 194995, 1946, 121404, 0, 0, 917631, 0, 0, 10934, 0, 70376, 0, + 0, 8071, 3538, 0, 2287, 65328, 0, 0, 7614, 0, 0, 0, 12009, 43968, 0, + 67852, 0, 0, 10841, 123640, 0, 0, 0, 0, 8960, 0, 0, 65317, 128829, 0, 0, + 70374, 0, 0, 0, 65315, 0, 0, 0, 0, 0, 119621, 0, 11849, 12447, 0, 0, + 110741, 0, 0, 0, 129976, 42767, 0, 0, 0, 43695, 120520, 11975, 194941, + 983448, 0, 2555, 0, 128640, 70070, 42936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 66714, 0, 0, 70076, 65596, 121034, 66710, 67658, 0, 126994, 65338, + 7792, 0, 0, 67871, 119027, 0, 8233, 43572, 0, 0, 0, 3442, 110933, 2841, + 12543, 0, 1473, 42820, 64329, 127832, 917772, 126126, 7937, 0, 1048, 0, + 0, 983943, 0, 3406, 1054, 100701, 1040, 65450, 0, 92329, 1069, 917763, + 128367, 128940, 0, 917765, 0, 983724, 9693, 110873, 0, 0, 0, 983948, + 4353, 118653, 1059, 127530, 0, 0, 0, 127093, 118862, 120500, 10646, + 118708, 100710, 917762, 70424, 74830, 0, 0, 983720, 10221, 100706, 68255, + 0, 0, 74346, 119619, 100707, 64945, 12921, 0, 0, 0, 0, 0, 983795, 43020, + 0, 0, 74254, 0, 983785, 0, 0, 983792, 0, 71954, 0, 0, 0, 0, 122625, 0, + 120503, 70663, 0, 2755, 0, 0, 0, 4857, 0, 4428, 0, 0, 983791, 0, 0, 0, + 43842, 0, 122899, 0, 7978, 0, 70392, 127080, 11924, 43812, 0, 65015, + 67472, 563, 68340, 0, 12798, 0, 100727, 0, 0, 0, 74110, 0, 94051, 0, 694, + 0, 9876, 0, 119168, 0, 0, 0, 92361, 0, 0, 7229, 0, 0, 0, 0, 64811, 0, + 119087, 126478, 0, 7381, 0, 2525, 4852, 11586, 68465, 41605, 126089, 0, + 11582, 7151, 10155, 92578, 188, 0, 11592, 0, 74015, 0, 0, 4858, 122645, + 0, 0, 4861, 0, 2786, 121431, 4856, 8051, 0, 119609, 0, 113797, 71133, 0, + 78448, 0, 0, 67842, 68084, 0, 0, 0, 0, 0, 10234, 5843, 0, 71865, 66728, + 0, 3157, 0, 0, 75035, 72788, 983750, 0, 10822, 5149, 129517, 0, 65142, + 129454, 4565, 0, 0, 0, 12657, 0, 0, 386, 0, 8834, 120974, 0, 43574, 0, 0, + 0, 70113, 7220, 11839, 124984, 74883, 194752, 0, 65241, 74503, 8160, 0, + 194753, 0, 0, 0, 0, 0, 121265, 6847, 13303, 0, 0, 194755, 0, 118865, 0, + 194761, 0, 0, 74505, 0, 0, 0, 100518, 194721, 8780, 100512, 0, 68745, + 110626, 66697, 0, 2672, 3735, 983641, 0, 68752, 11205, 10724, 41202, 0, + 100714, 0, 0, 0, 0, 194765, 3842, 0, 78183, 12442, 78182, 9791, 78181, 0, + 42516, 67730, 64821, 195059, 78178, 0, 78464, 119219, 78465, 127466, + 194690, 195063, 0, 0, 0, 0, 78540, 78541, 78538, 1962, 78490, 78476, + 65930, 11660, 0, 2072, 0, 0, 78544, 194704, 78542, 10669, 110859, 110860, + 110857, 110858, 129749, 110856, 4105, 0, 194699, 0, 0, 0, 13148, 195068, + 78479, 9226, 0, 0, 10765, 127486, 71919, 6263, 195050, 0, 195041, 0, 0, + 0, 0, 0, 0, 92312, 7886, 0, 6682, 0, 6680, 195042, 126473, 195052, 6679, + 74412, 0, 72206, 74421, 66281, 0, 0, 127478, 0, 0, 92861, 6681, 0, 12693, + 0, 0, 0, 0, 0, 65442, 129055, 0, 9989, 74415, 194673, 0, 0, 983788, 0, 0, + 0, 0, 7042, 127240, 119026, 7968, 0, 983768, 194741, 194736, 983793, 0, + 69889, 74389, 128696, 0, 0, 128979, 5781, 0, 78199, 0, 124145, 11091, 0, + 2719, 0, 0, 0, 64495, 0, 0, 0, 65169, 42845, 0, 128551, 983766, 2200, + 72435, 0, 0, 0, 917855, 66670, 0, 983709, 0, 0, 0, 7902, 0, 65265, 0, 0, + 0, 0, 0, 0, 0, 12994, 0, 10828, 983974, 0, 4307, 3482, 0, 0, 72389, 0, + 64299, 74573, 41194, 7343, 0, 0, 41195, 0, 8169, 0, 8841, 66770, 516, + 72981, 41197, 119051, 34, 128850, 120186, 11504, 1612, 120187, 120182, + 120181, 120184, 12001, 120178, 120177, 120180, 120179, 71966, 120173, + 7749, 120175, 0, 1758, 0, 10667, 0, 120197, 0, 1935, 11517, 120193, + 120196, 78925, 120190, 120189, 120192, 120191, 1217, 64702, 128075, 825, + 0, 129824, 0, 0, 66748, 0, 11050, 0, 123187, 0, 0, 74554, 110577, 0, + 8677, 123188, 11313, 123185, 3403, 0, 123186, 64364, 92683, 0, 0, 0, 0, + 123189, 0, 0, 983880, 0, 69408, 41850, 0, 3433, 127965, 0, 1594, 65607, + 0, 66392, 0, 129291, 74565, 41353, 125119, 78926, 0, 0, 0, 918, 127280, + 41351, 0, 0, 12140, 0, 12668, 72395, 0, 128753, 0, 127302, 0, 127288, + 129497, 127235, 573, 0, 0, 11417, 0, 127283, 0, 0, 0, 72410, 0, 11482, 0, + 3981, 74345, 0, 0, 0, 0, 0, 0, 125238, 0, 0, 42195, 0, 123190, 129764, + 64602, 0, 0, 121366, 0, 121061, 128690, 0, 8423, 0, 448, 66907, 9717, 0, + 0, 0, 0, 0, 0, 0, 71910, 129898, 0, 0, 120679, 65013, 78169, 0, 72390, 0, + 0, 127917, 0, 74892, 0, 0, 127798, 0, 0, 66982, 0, 0, 0, 12197, 125074, + 0, 121447, 0, 0, 0, 0, 0, 0, 0, 74563, 64828, 11419, 0, 8592, 0, 0, 0, + 11381, 0, 0, 74529, 0, 0, 83254, 0, 72796, 0, 83257, 0, 0, 0, 129437, + 65672, 0, 0, 0, 0, 0, 0, 0, 0, 9505, 0, 0, 756, 0, 125243, 100358, + 110852, 7261, 0, 0, 0, 0, 0, 64401, 65830, 41365, 0, 0, 0, 127834, 0, 0, + 0, 0, 0, 74626, 123155, 11578, 0, 2170, 0, 0, 0, 0, 74568, 0, 113684, + 1794, 68310, 120218, 120219, 120220, 120221, 120222, 120223, 3617, + 120011, 64886, 94061, 78202, 120213, 66999, 10225, 983060, 0, 65223, + 983058, 0, 0, 4452, 127779, 0, 0, 66981, 0, 0, 0, 11425, 0, 0, 1231, 0, + 0, 0, 124121, 8192, 124118, 0, 0, 10616, 8694, 0, 68867, 128332, 123595, + 120200, 120201, 120202, 120203, 9878, 120205, 119626, 120207, 0, 8799, + 42131, 0, 127163, 0, 120198, 120199, 837, 120015, 72384, 0, 983836, 2180, + 11427, 0, 78154, 0, 70171, 0, 78150, 42606, 0, 119615, 78147, 64637, + 78146, 43060, 78145, 125009, 3392, 0, 194783, 119067, 119650, 65468, + 43498, 126083, 0, 0, 0, 194928, 194937, 194938, 64681, 194930, 83264, + 92451, 0, 194955, 83262, 983751, 8973, 0, 194967, 70177, 194968, 0, 4800, + 195018, 0, 0, 11820, 6852, 122981, 0, 4802, 4111, 111268, 0, 4805, + 127308, 68193, 7885, 121220, 0, 0, 0, 4767, 0, 0, 0, 0, 0, 125234, + 100366, 43453, 0, 41340, 0, 0, 10005, 65856, 41333, 0, 9518, 0, 0, 0, + 42520, 100850, 0, 0, 917562, 100506, 0, 0, 0, 0, 0, 0, 9167, 42151, + 124958, 0, 2026, 100848, 124139, 0, 100534, 12768, 0, 7582, 0, 0, 0, 0, + 129557, 0, 120539, 68879, 0, 43547, 119992, 8546, 126071, 78520, 7604, + 78518, 78519, 78514, 78517, 78511, 78512, 73802, 128140, 0, 6708, 10535, + 0, 68218, 55274, 68221, 92296, 0, 0, 0, 0, 0, 72385, 0, 0, 0, 73727, 0, + 120706, 74442, 66943, 0, 0, 4351, 0, 119887, 119888, 0, 119886, 119891, + 68866, 119889, 11433, 119895, 119896, 0, 119894, 65578, 194693, 0, 0, + 983070, 10681, 0, 0, 128737, 0, 983111, 0, 6722, 129364, 0, 119997, + 41546, 64860, 68394, 0, 41549, 118619, 72386, 0, 0, 0, 0, 64710, 41547, + 0, 0, 0, 78530, 78532, 78528, 78529, 71343, 78527, 78523, 78525, 3537, + 119908, 119905, 7155, 2264, 0, 78533, 67755, 0, 0, 0, 0, 0, 0, 0, 64715, + 0, 0, 537, 0, 4179, 0, 0, 0, 0, 0, 0, 0, 0, 12081, 0, 0, 4048, 7053, 0, + 0, 70459, 0, 124975, 0, 3059, 0, 0, 43491, 983833, 0, 0, 127993, 4100, + 920, 1811, 1355, 0, 0, 64383, 10078, 69398, 0, 118651, 0, 65870, 0, 129565, 0, 72400, 42918, 0, 66789, 0, 12865, 0, 73938, }; @@ -29920,7 +30121,7 @@ static const unsigned int code_hash[] = { #define code_poly 65581 static const unsigned int aliases_start = 0xf0000; -static const unsigned int aliases_end = 0xf01d6; +static const unsigned int aliases_end = 0xf01d9; static const unsigned int name_aliases[] = { 0x0000, 0x0000, @@ -29983,6 +30184,7 @@ static const unsigned int name_aliases[] = { 0x0018, 0x0019, 0x0019, + 0x0019, 0x001A, 0x001A, 0x001B, @@ -30083,6 +30285,7 @@ static const unsigned int name_aliases[] = { 0x01A2, 0x01A3, 0x034F, + 0x0616, 0x061C, 0x0709, 0x0CDE, @@ -30100,6 +30303,7 @@ static const unsigned int name_aliases[] = { 0x180D, 0x180E, 0x180F, + 0x1BBD, 0x200B, 0x200C, 0x200D, diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c index 93895c4f121..5f5297ba633 100644 --- a/Modules/xxlimited.c +++ b/Modules/xxlimited.c @@ -19,6 +19,7 @@ def __init__(self): # In the C class, "_x_attr" is not accessible from Python code self._x_attr = {} + self._x_exports = 0 def __getattr__(self, name): return self._x_attr[name] @@ -29,6 +30,13 @@ def __delattr__(self, name): del self._x_attr[name] + @property + def x_exports(self): + """Return the number of times an internal buffer is exported.""" + # Each Xxo instance has a 10-byte buffer that can be + # accessed via the buffer interface (e.g. `memoryview`). + return self._x_exports + def demo(o, /): if isinstance(o, str): return o @@ -57,6 +65,9 @@ #define Py_LIMITED_API 0x030b0000 #include "Python.h" +#include + +#define BUFSIZE 10 // Module state typedef struct { @@ -70,7 +81,9 @@ typedef struct { // Instance state typedef struct { PyObject_HEAD - PyObject *x_attr; /* Attributes dictionary */ + PyObject *x_attr; /* Attributes dictionary */ + char x_buffer[BUFSIZE]; /* buffer for Py_buffer */ + Py_ssize_t x_exports; /* how many buffer are exported */ } XxoObject; // XXX: no good way to do this yet @@ -89,18 +102,21 @@ newXxoObject(PyObject *module) return NULL; } self->x_attr = NULL; + memset(self->x_buffer, 0, BUFSIZE); + self->x_exports = 0; return self; } /* Xxo finalization */ static int -Xxo_traverse(XxoObject *self, visitproc visit, void *arg) +Xxo_traverse(PyObject *self_obj, visitproc visit, void *arg) { // Visit the type - Py_VISIT(Py_TYPE(self)); + Py_VISIT(Py_TYPE(self_obj)); // Visit the attribute dict + XxoObject *self = (XxoObject *)self_obj; Py_VISIT(self->x_attr); return 0; } @@ -113,14 +129,16 @@ Xxo_clear(XxoObject *self) } static void -Xxo_finalize(XxoObject *self) +Xxo_finalize(PyObject *self_obj) { + XxoObject *self = (XxoObject *)self_obj; Py_CLEAR(self->x_attr); } static void -Xxo_dealloc(XxoObject *self) +Xxo_dealloc(PyObject *self) { + PyObject_GC_UnTrack(self); Xxo_finalize(self); PyTypeObject *tp = Py_TYPE(self); freefunc free = PyType_GetSlot(tp, Py_tp_free); @@ -137,8 +155,7 @@ Xxo_getattro(XxoObject *self, PyObject *name) if (self->x_attr != NULL) { PyObject *v = PyDict_GetItemWithError(self->x_attr, name); if (v != NULL) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } else if (PyErr_Occurred()) { return NULL; @@ -192,31 +209,60 @@ Xxo_demo(XxoObject *self, PyTypeObject *defining_class, /* Test if the argument is "str" */ if (PyUnicode_Check(o)) { - Py_INCREF(o); - return o; + return Py_NewRef(o); } /* test if the argument is of the Xxo class */ if (PyObject_TypeCheck(o, defining_class)) { - Py_INCREF(o); - return o; + return Py_NewRef(o); } - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } static PyMethodDef Xxo_methods[] = { - {"demo", (PyCFunction)(void(*)(void))Xxo_demo, + {"demo", _PyCFunction_CAST(Xxo_demo), METH_METHOD | METH_FASTCALL | METH_KEYWORDS, PyDoc_STR("demo(o) -> o")}, {NULL, NULL} /* sentinel */ }; +/* Xxo buffer interface */ + +static int +Xxo_getbuffer(XxoObject *self, Py_buffer *view, int flags) +{ + int res = PyBuffer_FillInfo(view, (PyObject*)self, + (void *)self->x_buffer, BUFSIZE, + 0, flags); + if (res == 0) { + self->x_exports++; + } + return res; +} + +static void +Xxo_releasebuffer(XxoObject *self, Py_buffer *view) +{ + self->x_exports--; +} + +static PyObject * +Xxo_get_x_exports(XxoObject *self, void *c) +{ + return PyLong_FromSsize_t(self->x_exports); +} + /* Xxo type definition */ PyDoc_STRVAR(Xxo_doc, "A class that explicitly stores attributes in an internal dict"); +static PyGetSetDef Xxo_getsetlist[] = { + {"x_exports", (getter) Xxo_get_x_exports, NULL, NULL}, + {NULL}, +}; + + static PyType_Slot Xxo_Type_slots[] = { {Py_tp_doc, (char *)Xxo_doc}, {Py_tp_traverse, Xxo_traverse}, @@ -226,6 +272,9 @@ static PyType_Slot Xxo_Type_slots[] = { {Py_tp_getattro, Xxo_getattro}, {Py_tp_setattro, Xxo_setattro}, {Py_tp_methods, Xxo_methods}, + {Py_bf_getbuffer, Xxo_getbuffer}, + {Py_bf_releasebuffer, Xxo_releasebuffer}, + {Py_tp_getset, Xxo_getsetlist}, {0, 0}, /* sentinel */ }; diff --git a/Modules/xxlimited_35.c b/Modules/xxlimited_35.c index 647abf67212..361c7e76d77 100644 --- a/Modules/xxlimited_35.c +++ b/Modules/xxlimited_35.c @@ -64,11 +64,9 @@ Xxo_demo(XxoObject *self, PyObject *args) return NULL; /* Test availability of fast type checks */ if (o != NULL && PyUnicode_Check(o)) { - Py_INCREF(o); - return o; + return Py_NewRef(o); } - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } static PyMethodDef Xxo_methods[] = { @@ -83,8 +81,7 @@ Xxo_getattro(XxoObject *self, PyObject *name) if (self->x_attr != NULL) { PyObject *v = PyDict_GetItemWithError(self->x_attr, name); if (v != NULL) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } else if (PyErr_Occurred()) { return NULL; @@ -124,7 +121,7 @@ static PyType_Slot Xxo_Type_slots[] = { }; static PyType_Spec Xxo_Type_spec = { - "xxlimited.Xxo", + "xxlimited_35.Xxo", sizeof(XxoObject), 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, @@ -176,8 +173,7 @@ xx_roj(PyObject *self, PyObject *args) long b; if (!PyArg_ParseTuple(args, "O#:roj", &a, &b)) return NULL; - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } @@ -189,7 +185,7 @@ static PyType_Slot Str_Type_slots[] = { }; static PyType_Spec Str_Type_spec = { - "xxlimited.Str", + "xxlimited_35.Str", 0, 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, @@ -212,7 +208,7 @@ static PyType_Slot Null_Type_slots[] = { }; static PyType_Spec Null_Type_spec = { - "xxlimited.Null", + "xxlimited_35.Null", 0, /* basicsize */ 0, /* itemsize */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, @@ -248,40 +244,50 @@ xx_modexec(PyObject *m) Null_Type_slots[1].pfunc = PyType_GenericNew; Str_Type_slots[0].pfunc = &PyUnicode_Type; - Xxo_Type = PyType_FromSpec(&Xxo_Type_spec); - if (Xxo_Type == NULL) - goto fail; - /* Add some symbolic constants to the module */ if (ErrorObject == NULL) { - ErrorObject = PyErr_NewException("xxlimited.error", NULL, NULL); - if (ErrorObject == NULL) - goto fail; + ErrorObject = PyErr_NewException("xxlimited_35.error", NULL, NULL); + if (ErrorObject == NULL) { + return -1; + } } Py_INCREF(ErrorObject); - PyModule_AddObject(m, "error", ErrorObject); + if (PyModule_AddObject(m, "error", ErrorObject) < 0) { + Py_DECREF(ErrorObject); + return -1; + } /* Add Xxo */ - o = PyType_FromSpec(&Xxo_Type_spec); - if (o == NULL) - goto fail; - PyModule_AddObject(m, "Xxo", o); + Xxo_Type = PyType_FromSpec(&Xxo_Type_spec); + if (Xxo_Type == NULL) { + return -1; + } + if (PyModule_AddObject(m, "Xxo", Xxo_Type) < 0) { + Py_DECREF(Xxo_Type); + return -1; + } /* Add Str */ o = PyType_FromSpec(&Str_Type_spec); - if (o == NULL) - goto fail; - PyModule_AddObject(m, "Str", o); + if (o == NULL) { + return -1; + } + if (PyModule_AddObject(m, "Str", o) < 0) { + Py_DECREF(o); + return -1; + } /* Add Null */ o = PyType_FromSpec(&Null_Type_spec); - if (o == NULL) - goto fail; - PyModule_AddObject(m, "Null", o); + if (o == NULL) { + return -1; + } + if (PyModule_AddObject(m, "Null", o) < 0) { + Py_DECREF(o); + return -1; + } + return 0; - fail: - Py_XDECREF(m); - return -1; } diff --git a/Modules/xxmodule.c b/Modules/xxmodule.c index edcd62157c0..a676fdb4ec7 100644 --- a/Modules/xxmodule.c +++ b/Modules/xxmodule.c @@ -52,8 +52,7 @@ Xxo_demo(XxoObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, ":demo")) return NULL; - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } static PyMethodDef Xxo_methods[] = { @@ -68,8 +67,7 @@ Xxo_getattro(XxoObject *self, PyObject *name) if (self->x_attr != NULL) { PyObject *v = PyDict_GetItemWithError(self->x_attr, name); if (v != NULL) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } else if (PyErr_Occurred()) { return NULL; @@ -195,8 +193,7 @@ xx_bug(PyObject *self, PyObject *args) printf("\n"); /* Py_DECREF(item); */ - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } /* Test bad format character */ @@ -208,8 +205,7 @@ xx_roj(PyObject *self, PyObject *args) long b; if (!PyArg_ParseTuple(args, "O#:roj", &a, &b)) return NULL; - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } @@ -266,8 +262,7 @@ static PyTypeObject Str_Type = { static PyObject * null_richcompare(PyObject *self, PyObject *other, int op) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; + return Py_NewRef(Py_NotImplemented); } static PyTypeObject Null_Type = { @@ -358,31 +353,32 @@ xx_exec(PyObject *m) /* Finalize the type object including setting type of the new type * object; doing it here is required for portability, too. */ - if (PyType_Ready(&Xxo_Type) < 0) - goto fail; + if (PyType_Ready(&Xxo_Type) < 0) { + return -1; + } /* Add some symbolic constants to the module */ if (ErrorObject == NULL) { ErrorObject = PyErr_NewException("xx.error", NULL, NULL); - if (ErrorObject == NULL) - goto fail; + if (ErrorObject == NULL) { + return -1; + } + } + int rc = PyModule_AddType(m, (PyTypeObject *)ErrorObject); + Py_DECREF(ErrorObject); + if (rc < 0) { + return -1; } - Py_INCREF(ErrorObject); - PyModule_AddObject(m, "error", ErrorObject); - /* Add Str */ - if (PyType_Ready(&Str_Type) < 0) - goto fail; - PyModule_AddObject(m, "Str", (PyObject *)&Str_Type); + /* Add Str and Null types */ + if (PyModule_AddType(m, &Str_Type) < 0) { + return -1; + } + if (PyModule_AddType(m, &Null_Type) < 0) { + return -1; + } - /* Add Null */ - if (PyType_Ready(&Null_Type) < 0) - goto fail; - PyModule_AddObject(m, "Null", (PyObject *)&Null_Type); return 0; - fail: - Py_XDECREF(m); - return -1; } static struct PyModuleDef_Slot xx_slots[] = { diff --git a/Modules/xxsubtype.c b/Modules/xxsubtype.c index 7200337724e..8512baf7cd0 100644 --- a/Modules/xxsubtype.c +++ b/Modules/xxsubtype.c @@ -39,8 +39,7 @@ spamlist_setstate(spamlistobject *self, PyObject *args) if (!PyArg_ParseTuple(args, "i:setstate", &state)) return NULL; self->state = state; - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } static PyObject * @@ -53,12 +52,9 @@ spamlist_specialmeth(PyObject *self, PyObject *args, PyObject *kw) self = Py_None; if (kw == NULL) kw = Py_None; - Py_INCREF(self); - PyTuple_SET_ITEM(result, 0, self); - Py_INCREF(args); - PyTuple_SET_ITEM(result, 1, args); - Py_INCREF(kw); - PyTuple_SET_ITEM(result, 2, kw); + PyTuple_SET_ITEM(result, 0, Py_NewRef(self)); + PyTuple_SET_ITEM(result, 1, Py_NewRef(args)); + PyTuple_SET_ITEM(result, 2, Py_NewRef(kw)); } return result; } @@ -70,10 +66,10 @@ static PyMethodDef spamlist_methods[] = { PyDoc_STR("setstate(state)")}, /* These entries differ only in the flags; they are used by the tests in test.test_descr. */ - {"classmeth", (PyCFunction)(void(*)(void))spamlist_specialmeth, + {"classmeth", _PyCFunction_CAST(spamlist_specialmeth), METH_VARARGS | METH_KEYWORDS | METH_CLASS, PyDoc_STR("classmeth(*args, **kw)")}, - {"staticmeth", (PyCFunction)(void(*)(void))spamlist_specialmeth, + {"staticmeth", _PyCFunction_CAST(spamlist_specialmeth), METH_VARARGS | METH_KEYWORDS | METH_STATIC, PyDoc_STR("staticmeth(*args, **kw)")}, {NULL, NULL}, @@ -164,8 +160,7 @@ spamdict_setstate(spamdictobject *self, PyObject *args) if (!PyArg_ParseTuple(args, "i:setstate", &state)) return NULL; self->state = state; - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } static PyMethodDef spamdict_methods[] = { @@ -237,10 +232,11 @@ spam_bench(PyObject *self, PyObject *args) { PyObject *obj, *name, *res; int n = 1000; - time_t t0, t1; + time_t t0 = 0, t1 = 0; if (!PyArg_ParseTuple(args, "OU|i", &obj, &name, &n)) return NULL; +#ifdef HAVE_CLOCK t0 = clock(); while (--n >= 0) { res = PyObject_GetAttr(obj, name); @@ -249,6 +245,7 @@ spam_bench(PyObject *self, PyObject *args) Py_DECREF(res); } t1 = clock(); +#endif return PyFloat_FromDouble((double)(t1-t0) / CLOCKS_PER_SEC); } @@ -277,14 +274,12 @@ xxsubtype_exec(PyObject* m) if (PyType_Ready(&spamdict_type) < 0) return -1; - Py_INCREF(&spamlist_type); if (PyModule_AddObject(m, "spamlist", - (PyObject *) &spamlist_type) < 0) + Py_NewRef(&spamlist_type)) < 0) return -1; - Py_INCREF(&spamdict_type); if (PyModule_AddObject(m, "spamdict", - (PyObject *) &spamdict_type) < 0) + Py_NewRef(&spamdict_type)) < 0) return -1; return 0; } diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index 67bde701fa6..1cdfd013202 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -8,6 +8,11 @@ #include "Python.h" #include "structmember.h" // PyMemberDef #include "zlib.h" +#include "stdbool.h" + +#if defined(ZLIB_VERNUM) && ZLIB_VERNUM < 0x1221 +#error "At least zlib version 1.2.2.1 is required" +#endif // Blocks output buffer wrappers #include "pycore_blocks_output_buffer.h" @@ -171,9 +176,6 @@ OutputBuffer_WindowOnError(_BlocksOutputBuffer *buffer, _Uint32Window *window) } } while (0) #define LEAVE_ZLIB(obj) PyThread_release_lock((obj)->lock); -#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221 -# define AT_LEAST_ZLIB_1_2_2_1 -#endif /* The following parameters are copied from zutil.h, version 0.95 */ #define DEFLATED 8 @@ -185,12 +187,14 @@ OutputBuffer_WindowOnError(_BlocksOutputBuffer *buffer, _Uint32Window *window) /* Initial buffer size. */ #define DEF_BUF_SIZE (16*1024) +#define DEF_MAX_INITIAL_BUF_SIZE (16 * 1024 * 1024) static PyModuleDef zlibmodule; typedef struct { PyTypeObject *Comptype; PyTypeObject *Decomptype; + PyTypeObject *ZlibDecompressorType; PyObject *ZlibError; } zlibstate; @@ -209,7 +213,7 @@ typedef struct PyObject *unused_data; PyObject *unconsumed_tail; char eof; - int is_initialised; + bool is_initialised; PyObject *zdict; PyThread_type_lock lock; } compobject; @@ -320,7 +324,7 @@ static PyObject * zlib_compress_impl(PyObject *module, Py_buffer *data, int level, int wbits) /*[clinic end generated code: output=46bd152fadd66df2 input=c4d06ee5782a7e3f]*/ { - PyObject *RetVal; + PyObject *return_value; int flush; z_stream zst; _BlocksOutputBuffer buffer = {.list = NULL}; @@ -387,11 +391,11 @@ zlib_compress_impl(PyObject *module, Py_buffer *data, int level, int wbits) err = deflateEnd(&zst); if (err == Z_OK) { - RetVal = OutputBuffer_Finish(&buffer, zst.avail_out); - if (RetVal == NULL) { + return_value = OutputBuffer_Finish(&buffer, zst.avail_out); + if (return_value == NULL) { goto error; } - return RetVal; + return return_value; } else zlib_error(state, zst, err, "while finishing compression"); @@ -419,7 +423,7 @@ zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, Py_ssize_t bufsize) /*[clinic end generated code: output=77c7e35111dc8c42 input=a9ac17beff1f893f]*/ { - PyObject *RetVal; + PyObject *return_value; Byte *ibuf; Py_ssize_t ibuflen; int err, flush; @@ -514,9 +518,9 @@ zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, goto error; } - RetVal = OutputBuffer_WindowFinish(&buffer, &window, zst.avail_out); - if (RetVal != NULL) { - return RetVal; + return_value = OutputBuffer_WindowFinish(&buffer, &window, zst.avail_out); + if (return_value != NULL) { + return return_value; } error: @@ -667,26 +671,17 @@ zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict) self->zst.next_in = NULL; self->zst.avail_in = 0; if (zdict != NULL) { - Py_INCREF(zdict); - self->zdict = zdict; + self->zdict = Py_NewRef(zdict); } int err = inflateInit2(&self->zst, wbits); switch (err) { case Z_OK: self->is_initialised = 1; if (self->zdict != NULL && wbits < 0) { -#ifdef AT_LEAST_ZLIB_1_2_2_1 if (set_inflate_zdict(state, self) < 0) { Py_DECREF(self); return NULL; } -#else - PyErr_Format(state->ZlibError, - "zlib version %s does not allow raw inflate with dictionary", - ZLIB_VERSION); - Py_DECREF(self); - return NULL; -#endif } return (PyObject *)self; case Z_STREAM_ERROR: @@ -753,7 +748,7 @@ zlib_Compress_compress_impl(compobject *self, PyTypeObject *cls, Py_buffer *data) /*[clinic end generated code: output=6731b3f0ff357ca6 input=04d00f65ab01d260]*/ { - PyObject *RetVal; + PyObject *return_value; int err; _BlocksOutputBuffer buffer = {.list = NULL}; zlibstate *state = PyType_GetModuleState(cls); @@ -791,17 +786,17 @@ zlib_Compress_compress_impl(compobject *self, PyTypeObject *cls, } while (ibuflen != 0); - RetVal = OutputBuffer_Finish(&buffer, self->zst.avail_out); - if (RetVal != NULL) { + return_value = OutputBuffer_Finish(&buffer, self->zst.avail_out); + if (return_value != NULL) { goto success; } error: OutputBuffer_OnError(&buffer); - RetVal = NULL; + return_value = NULL; success: LEAVE_ZLIB(self); - return RetVal; + return return_value; } /* Helper for objdecompress() and flush(). Saves any unconsumed input data in @@ -875,7 +870,7 @@ zlib_Decompress_decompress_impl(compobject *self, PyTypeObject *cls, { int err = Z_OK; Py_ssize_t ibuflen; - PyObject *RetVal; + PyObject *return_value; _BlocksOutputBuffer buffer = {.list = NULL}; PyObject *module = PyType_GetModule(cls); @@ -953,17 +948,17 @@ zlib_Decompress_decompress_impl(compobject *self, PyTypeObject *cls, goto abort; } - RetVal = OutputBuffer_Finish(&buffer, self->zst.avail_out); - if (RetVal != NULL) { + return_value = OutputBuffer_Finish(&buffer, self->zst.avail_out); + if (return_value != NULL) { goto success; } abort: OutputBuffer_OnError(&buffer); - RetVal = NULL; + return_value = NULL; success: LEAVE_ZLIB(self); - return RetVal; + return return_value; } /*[clinic input] @@ -985,7 +980,7 @@ zlib_Compress_flush_impl(compobject *self, PyTypeObject *cls, int mode) /*[clinic end generated code: output=c7efd13efd62add2 input=286146e29442eb6c]*/ { int err; - PyObject *RetVal; + PyObject *return_value; _BlocksOutputBuffer buffer = {.list = NULL}; zlibstate *state = PyType_GetModuleState(cls); @@ -1042,17 +1037,17 @@ zlib_Compress_flush_impl(compobject *self, PyTypeObject *cls, int mode) goto error; } - RetVal = OutputBuffer_Finish(&buffer, self->zst.avail_out); - if (RetVal != NULL) { + return_value = OutputBuffer_Finish(&buffer, self->zst.avail_out); + if (return_value != NULL) { goto success; } error: OutputBuffer_OnError(&buffer); - RetVal = NULL; + return_value = NULL; success: LEAVE_ZLIB(self); - return RetVal; + return return_value; } #ifdef HAVE_ZLIB_COPY @@ -1071,14 +1066,14 @@ zlib_Compress_copy_impl(compobject *self, PyTypeObject *cls) { zlibstate *state = PyType_GetModuleState(cls); - compobject *retval = newcompobject(state->Comptype); - if (!retval) return NULL; + compobject *return_value = newcompobject(state->Comptype); + if (!return_value) return NULL; /* Copy the zstream state * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe */ ENTER_ZLIB(self); - int err = deflateCopy(&retval->zst, &self->zst); + int err = deflateCopy(&return_value->zst, &self->zst); switch (err) { case Z_OK: break; @@ -1093,23 +1088,20 @@ zlib_Compress_copy_impl(compobject *self, PyTypeObject *cls) zlib_error(state, self->zst, err, "while copying compression object"); goto error; } - Py_INCREF(self->unused_data); - Py_XSETREF(retval->unused_data, self->unused_data); - Py_INCREF(self->unconsumed_tail); - Py_XSETREF(retval->unconsumed_tail, self->unconsumed_tail); - Py_XINCREF(self->zdict); - Py_XSETREF(retval->zdict, self->zdict); - retval->eof = self->eof; + Py_XSETREF(return_value->unused_data, Py_NewRef(self->unused_data)); + Py_XSETREF(return_value->unconsumed_tail, Py_NewRef(self->unconsumed_tail)); + Py_XSETREF(return_value->zdict, Py_XNewRef(self->zdict)); + return_value->eof = self->eof; /* Mark it as being initialized */ - retval->is_initialised = 1; + return_value->is_initialised = 1; LEAVE_ZLIB(self); - return (PyObject *)retval; + return (PyObject *)return_value; error: LEAVE_ZLIB(self); - Py_XDECREF(retval); + Py_XDECREF(return_value); return NULL; } @@ -1158,14 +1150,14 @@ zlib_Decompress_copy_impl(compobject *self, PyTypeObject *cls) { zlibstate *state = PyType_GetModuleState(cls); - compobject *retval = newcompobject(state->Decomptype); - if (!retval) return NULL; + compobject *return_value = newcompobject(state->Decomptype); + if (!return_value) return NULL; /* Copy the zstream state * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe */ ENTER_ZLIB(self); - int err = inflateCopy(&retval->zst, &self->zst); + int err = inflateCopy(&return_value->zst, &self->zst); switch (err) { case Z_OK: break; @@ -1181,23 +1173,20 @@ zlib_Decompress_copy_impl(compobject *self, PyTypeObject *cls) goto error; } - Py_INCREF(self->unused_data); - Py_XSETREF(retval->unused_data, self->unused_data); - Py_INCREF(self->unconsumed_tail); - Py_XSETREF(retval->unconsumed_tail, self->unconsumed_tail); - Py_XINCREF(self->zdict); - Py_XSETREF(retval->zdict, self->zdict); - retval->eof = self->eof; + Py_XSETREF(return_value->unused_data, Py_NewRef(self->unused_data)); + Py_XSETREF(return_value->unconsumed_tail, Py_NewRef(self->unconsumed_tail)); + Py_XSETREF(return_value->zdict, Py_XNewRef(self->zdict)); + return_value->eof = self->eof; /* Mark it as being initialized */ - retval->is_initialised = 1; + return_value->is_initialised = 1; LEAVE_ZLIB(self); - return (PyObject *)retval; + return (PyObject *)return_value; error: LEAVE_ZLIB(self); - Py_XDECREF(retval); + Py_XDECREF(return_value); return NULL; } @@ -1252,7 +1241,7 @@ zlib_Decompress_flush_impl(compobject *self, PyTypeObject *cls, { int err, flush; Py_buffer data; - PyObject *RetVal; + PyObject *return_value; Py_ssize_t ibuflen; _BlocksOutputBuffer buffer = {.list = NULL}; _Uint32Window window; // output buffer's UINT32_MAX sliding window @@ -1269,12 +1258,13 @@ zlib_Decompress_flush_impl(compobject *self, PyTypeObject *cls, return NULL; } + ENTER_ZLIB(self); + if (PyObject_GetBuffer(self->unconsumed_tail, &data, PyBUF_SIMPLE) == -1) { + LEAVE_ZLIB(self); return NULL; } - ENTER_ZLIB(self); - self->zst.next_in = data.buf; ibuflen = data.len; @@ -1305,13 +1295,6 @@ zlib_Decompress_flush_impl(compobject *self, PyTypeObject *cls, case Z_STREAM_END: break; default: - if (err == Z_NEED_DICT && self->zdict != NULL) { - if (set_inflate_zdict(state, self) < 0) { - goto abort; - } - else - break; - } goto save; } @@ -1335,18 +1318,456 @@ zlib_Decompress_flush_impl(compobject *self, PyTypeObject *cls, } } - RetVal = OutputBuffer_WindowFinish(&buffer, &window, self->zst.avail_out); - if (RetVal != NULL) { + return_value = OutputBuffer_WindowFinish(&buffer, &window, self->zst.avail_out); + if (return_value != NULL) { goto success; } abort: OutputBuffer_WindowOnError(&buffer, &window); - RetVal = NULL; + return_value = NULL; success: PyBuffer_Release(&data); LEAVE_ZLIB(self); - return RetVal; + return return_value; +} + + +typedef struct { + PyObject_HEAD + z_stream zst; + PyObject *zdict; + PyThread_type_lock lock; + PyObject *unused_data; + uint8_t *input_buffer; + Py_ssize_t input_buffer_size; + /* zst>avail_in is only 32 bit, so we store the true length + separately. Conversion and looping is encapsulated in + decompress_buf() */ + Py_ssize_t avail_in_real; + bool is_initialised; + char eof; /* T_BOOL expects a char */ + char needs_input; +} ZlibDecompressor; + +/*[clinic input] +class zlib.ZlibDecompressor "ZlibDecompressor *" "&ZlibDecompressorType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=0658178ab94645df]*/ + +static void +ZlibDecompressor_dealloc(ZlibDecompressor *self) +{ + PyObject *type = (PyObject *)Py_TYPE(self); + PyThread_free_lock(self->lock); + if (self->is_initialised) { + inflateEnd(&self->zst); + } + PyMem_Free(self->input_buffer); + Py_CLEAR(self->unused_data); + Py_CLEAR(self->zdict); + PyObject_Free(self); + Py_DECREF(type); +} + +static int +set_inflate_zdict_ZlibDecompressor(zlibstate *state, ZlibDecompressor *self) +{ + Py_buffer zdict_buf; + if (PyObject_GetBuffer(self->zdict, &zdict_buf, PyBUF_SIMPLE) == -1) { + return -1; + } + if ((size_t)zdict_buf.len > UINT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "zdict length does not fit in an unsigned int"); + PyBuffer_Release(&zdict_buf); + return -1; + } + int err; + err = inflateSetDictionary(&self->zst, + zdict_buf.buf, (unsigned int)zdict_buf.len); + PyBuffer_Release(&zdict_buf); + if (err != Z_OK) { + zlib_error(state, self->zst, err, "while setting zdict"); + return -1; + } + return 0; +} + +static Py_ssize_t +arrange_output_buffer_with_maximum(uint32_t *avail_out, + uint8_t **next_out, + PyObject **buffer, + Py_ssize_t length, + Py_ssize_t max_length) +{ + Py_ssize_t occupied; + + if (*buffer == NULL) { + if (!(*buffer = PyBytes_FromStringAndSize(NULL, length))) + return -1; + occupied = 0; + } + else { + occupied = *next_out - (uint8_t *)PyBytes_AS_STRING(*buffer); + + if (length == occupied) { + Py_ssize_t new_length; + assert(length <= max_length); + /* can not scale the buffer over max_length */ + if (length == max_length) + return -2; + if (length <= (max_length >> 1)) + new_length = length << 1; + else + new_length = max_length; + if (_PyBytes_Resize(buffer, new_length) < 0) + return -1; + length = new_length; + } + } + + *avail_out = (uint32_t)Py_MIN((size_t)(length - occupied), UINT32_MAX); + *next_out = (uint8_t *)PyBytes_AS_STRING(*buffer) + occupied; + + return length; +} + +/* Decompress data of length self->avail_in_real in self->state.next_in. The + output buffer is allocated dynamically and returned. If the max_length is + of sufficiently low size, max_length is allocated immediately. At most + max_length bytes are returned, so some of the input may not be consumed. + self->state.next_in and self->avail_in_real are updated to reflect the + consumed input. */ +static PyObject* +decompress_buf(ZlibDecompressor *self, Py_ssize_t max_length) +{ + /* data_size is strictly positive, but because we repeatedly have to + compare against max_length and PyBytes_GET_SIZE we declare it as + signed */ + PyObject *return_value = NULL; + Py_ssize_t hard_limit; + Py_ssize_t obuflen; + zlibstate *state = PyType_GetModuleState(Py_TYPE(self)); + + int err = Z_OK; + + /* When sys.maxsize is passed as default use DEF_BUF_SIZE as start buffer. + In this particular case the data may not necessarily be very big, so + it is better to grow dynamically.*/ + if ((max_length < 0) || max_length == PY_SSIZE_T_MAX) { + hard_limit = PY_SSIZE_T_MAX; + obuflen = DEF_BUF_SIZE; + } else { + /* Assume that decompressor is used in file decompression with a fixed + block size of max_length. In that case we will reach max_length almost + always (except at the end of the file). So it makes sense to allocate + max_length. */ + hard_limit = max_length; + obuflen = max_length; + if (obuflen > DEF_MAX_INITIAL_BUF_SIZE){ + // Safeguard against memory overflow. + obuflen = DEF_MAX_INITIAL_BUF_SIZE; + } + } + + do { + arrange_input_buffer(&(self->zst), &(self->avail_in_real)); + + do { + obuflen = arrange_output_buffer_with_maximum(&(self->zst.avail_out), + &(self->zst.next_out), + &return_value, + obuflen, + hard_limit); + if (obuflen == -1){ + PyErr_SetString(PyExc_MemoryError, + "Insufficient memory for buffer allocation"); + goto error; + } + else if (obuflen == -2) { + break; + } + Py_BEGIN_ALLOW_THREADS + err = inflate(&self->zst, Z_SYNC_FLUSH); + Py_END_ALLOW_THREADS + switch (err) { + case Z_OK: /* fall through */ + case Z_BUF_ERROR: /* fall through */ + case Z_STREAM_END: + break; + default: + if (err == Z_NEED_DICT) { + goto error; + } + else { + break; + } + } + } while (self->zst.avail_out == 0); + } while(err != Z_STREAM_END && self->avail_in_real != 0); + + if (err == Z_STREAM_END) { + self->eof = 1; + self->is_initialised = 0; + /* Unlike the Decompress object we call inflateEnd here as there are no + backwards compatibility issues */ + err = inflateEnd(&self->zst); + if (err != Z_OK) { + zlib_error(state, self->zst, err, "while finishing decompression"); + goto error; + } + } else if (err != Z_OK && err != Z_BUF_ERROR) { + zlib_error(state, self->zst, err, "while decompressing data"); + } + + self->avail_in_real += self->zst.avail_in; + + if (_PyBytes_Resize(&return_value, self->zst.next_out - + (uint8_t *)PyBytes_AS_STRING(return_value)) != 0) { + goto error; + } + + goto success; +error: + Py_CLEAR(return_value); +success: + return return_value; +} + + +static PyObject * +decompress(ZlibDecompressor *self, uint8_t *data, + size_t len, Py_ssize_t max_length) +{ + bool input_buffer_in_use; + PyObject *result; + + /* Prepend unconsumed input if necessary */ + if (self->zst.next_in != NULL) { + size_t avail_now, avail_total; + + /* Number of bytes we can append to input buffer */ + avail_now = (self->input_buffer + self->input_buffer_size) + - (self->zst.next_in + self->avail_in_real); + + /* Number of bytes we can append if we move existing + contents to beginning of buffer (overwriting + consumed input) */ + avail_total = self->input_buffer_size - self->avail_in_real; + + if (avail_total < len) { + size_t offset = self->zst.next_in - self->input_buffer; + uint8_t *tmp; + size_t new_size = self->input_buffer_size + len - avail_now; + + /* Assign to temporary variable first, so we don't + lose address of allocated buffer if realloc fails */ + tmp = PyMem_Realloc(self->input_buffer, new_size); + if (tmp == NULL) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } + self->input_buffer = tmp; + self->input_buffer_size = new_size; + + self->zst.next_in = self->input_buffer + offset; + } + else if (avail_now < len) { + memmove(self->input_buffer, self->zst.next_in, + self->avail_in_real); + self->zst.next_in = self->input_buffer; + } + memcpy((void*)(self->zst.next_in + self->avail_in_real), data, len); + self->avail_in_real += len; + input_buffer_in_use = 1; + } + else { + self->zst.next_in = data; + self->avail_in_real = len; + input_buffer_in_use = 0; + } + + result = decompress_buf(self, max_length); + if(result == NULL) { + self->zst.next_in = NULL; + return NULL; + } + + if (self->eof) { + self->needs_input = 0; + + if (self->avail_in_real > 0) { + PyObject *unused_data = PyBytes_FromStringAndSize( + (char *)self->zst.next_in, self->avail_in_real); + if (unused_data == NULL) { + goto error; + } + Py_XSETREF(self->unused_data, unused_data); + } + } + else if (self->avail_in_real == 0) { + self->zst.next_in = NULL; + self->needs_input = 1; + } + else { + self->needs_input = 0; + + /* If we did not use the input buffer, we now have + to copy the tail from the caller's buffer into the + input buffer */ + if (!input_buffer_in_use) { + + /* Discard buffer if it's too small + (resizing it may needlessly copy the current contents) */ + if (self->input_buffer != NULL && + self->input_buffer_size < self->avail_in_real) { + PyMem_Free(self->input_buffer); + self->input_buffer = NULL; + } + + /* Allocate if necessary */ + if (self->input_buffer == NULL) { + self->input_buffer = PyMem_Malloc(self->avail_in_real); + if (self->input_buffer == NULL) { + PyErr_SetNone(PyExc_MemoryError); + goto error; + } + self->input_buffer_size = self->avail_in_real; + } + + /* Copy tail */ + memcpy(self->input_buffer, self->zst.next_in, self->avail_in_real); + self->zst.next_in = self->input_buffer; + } + } + return result; + +error: + Py_XDECREF(result); + return NULL; +} + +/*[clinic input] +zlib.ZlibDecompressor.decompress + + data: Py_buffer + max_length: Py_ssize_t=-1 + +Decompress *data*, returning uncompressed data as bytes. + +If *max_length* is nonnegative, returns at most *max_length* bytes of +decompressed data. If this limit is reached and further output can be +produced, *self.needs_input* will be set to ``False``. In this case, the next +call to *decompress()* may provide *data* as b'' to obtain more of the output. + +If all of the input data was decompressed and returned (either because this +was less than *max_length* bytes, or because *max_length* was negative), +*self.needs_input* will be set to True. + +Attempting to decompress data after the end of stream is reached raises an +EOFError. Any data found after the end of the stream is ignored and saved in +the unused_data attribute. +[clinic start generated code]*/ + +static PyObject * +zlib_ZlibDecompressor_decompress_impl(ZlibDecompressor *self, + Py_buffer *data, Py_ssize_t max_length) +/*[clinic end generated code: output=990d32787b775f85 input=0b29d99715250b96]*/ + +{ + PyObject *result = NULL; + + ENTER_ZLIB(self); + if (self->eof) { + PyErr_SetString(PyExc_EOFError, "End of stream already reached"); + } + else { + result = decompress(self, data->buf, data->len, max_length); + } + LEAVE_ZLIB(self); + return result; +} + +PyDoc_STRVAR(ZlibDecompressor__new____doc__, +"_ZlibDecompressor(wbits=15, zdict=b\'\')\n" +"--\n" +"\n" +"Create a decompressor object for decompressing data incrementally.\n" +"\n" +" wbits = 15\n" +" zdict\n" +" The predefined compression dictionary. This is a sequence of bytes\n" +" (such as a bytes object) containing subsequences that are expected\n" +" to occur frequently in the data that is to be compressed. Those\n" +" subsequences that are expected to be most common should come at the\n" +" end of the dictionary. This must be the same dictionary as used by the\n" +" compressor that produced the input data.\n" +"\n"); + +static PyObject * +ZlibDecompressor__new__(PyTypeObject *cls, + PyObject *args, + PyObject *kwargs) +{ + static char *keywords[] = {"wbits", "zdict", NULL}; + static const char * const format = "|iO:_ZlibDecompressor"; + int wbits = MAX_WBITS; + PyObject *zdict = NULL; + zlibstate *state = PyType_GetModuleState(cls); + + if (!PyArg_ParseTupleAndKeywords( + args, kwargs, format, keywords, &wbits, &zdict)) { + return NULL; + } + ZlibDecompressor *self = PyObject_New(ZlibDecompressor, cls); + self->eof = 0; + self->needs_input = 1; + self->avail_in_real = 0; + self->input_buffer = NULL; + self->input_buffer_size = 0; + self->zdict = Py_XNewRef(zdict); + self->zst.opaque = NULL; + self->zst.zalloc = PyZlib_Malloc; + self->zst.zfree = PyZlib_Free; + self->zst.next_in = NULL; + self->zst.avail_in = 0; + self->unused_data = PyBytes_FromStringAndSize(NULL, 0); + if (self->unused_data == NULL) { + Py_CLEAR(self); + return NULL; + } + self->lock = PyThread_allocate_lock(); + if (self->lock == NULL) { + Py_DECREF(self); + PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); + return NULL; + } + int err = inflateInit2(&(self->zst), wbits); + switch (err) { + case Z_OK: + self->is_initialised = 1; + if (self->zdict != NULL && wbits < 0) { + if (set_inflate_zdict_ZlibDecompressor(state, self) < 0) { + Py_DECREF(self); + return NULL; + } + } + return (PyObject *)self; + case Z_STREAM_ERROR: + Py_DECREF(self); + PyErr_SetString(PyExc_ValueError, "Invalid initialization option"); + return NULL; + case Z_MEM_ERROR: + Py_DECREF(self); + PyErr_SetString(PyExc_MemoryError, + "Can't allocate memory for decompression object"); + return NULL; + default: + zlib_error(state, self->zst, err, "while creating decompression object"); + Py_DECREF(self); + return NULL; + } } #include "clinic/zlibmodule.c.h" @@ -1371,6 +1792,11 @@ static PyMethodDef Decomp_methods[] = {NULL, NULL} }; +static PyMethodDef ZlibDecompressor_methods[] = { + ZLIB_ZLIBDECOMPRESSOR_DECOMPRESS_METHODDEF + {NULL} +}; + #define COMP_OFF(x) offsetof(compobject, x) static PyMemberDef Decomp_members[] = { {"unused_data", T_OBJECT, COMP_OFF(unused_data), READONLY}, @@ -1379,6 +1805,26 @@ static PyMemberDef Decomp_members[] = { {NULL}, }; +PyDoc_STRVAR(ZlibDecompressor_eof__doc__, +"True if the end-of-stream marker has been reached."); + +PyDoc_STRVAR(ZlibDecompressor_unused_data__doc__, +"Data found after the end of the compressed stream."); + +PyDoc_STRVAR(ZlibDecompressor_needs_input_doc, +"True if more input is needed before more decompressed data can be produced."); + +static PyMemberDef ZlibDecompressor_members[] = { + {"eof", T_BOOL, offsetof(ZlibDecompressor, eof), + READONLY, ZlibDecompressor_eof__doc__}, + {"unused_data", T_OBJECT_EX, offsetof(ZlibDecompressor, unused_data), + READONLY, ZlibDecompressor_unused_data__doc__}, + {"needs_input", T_BOOL, offsetof(ZlibDecompressor, needs_input), READONLY, + ZlibDecompressor_needs_input_doc}, + {NULL}, +}; + + /*[clinic input] zlib.adler32 @@ -1419,7 +1865,7 @@ zlib_adler32_impl(PyObject *module, Py_buffer *data, unsigned int value) } /*[clinic input] -zlib.crc32 +zlib.crc32 -> unsigned_int data: Py_buffer value: unsigned_int(bitwise=True) = 0 @@ -1431,12 +1877,10 @@ Compute a CRC-32 checksum of data. The returned checksum is an integer. [clinic start generated code]*/ -static PyObject * +static unsigned int zlib_crc32_impl(PyObject *module, Py_buffer *data, unsigned int value) -/*[clinic end generated code: output=63499fa20af7ea25 input=26c3ed430fa00b4c]*/ +/*[clinic end generated code: output=b217562e4fe6d6a6 input=1229cb2fb5ea948a]*/ { - int signed_val; - /* Releasing the GIL for very small buffers is inefficient and may lower performance */ if (data->len > 1024*5) { @@ -1451,12 +1895,12 @@ zlib_crc32_impl(PyObject *module, Py_buffer *data, unsigned int value) buf += (size_t) UINT_MAX; len -= (size_t) UINT_MAX; } - signed_val = crc32(value, buf, (unsigned int)len); + value = crc32(value, buf, (unsigned int)len); Py_END_ALLOW_THREADS } else { - signed_val = crc32(value, data->buf, (unsigned int)data->len); + value = crc32(value, data->buf, (unsigned int)data->len); } - return PyLong_FromUnsignedLong(signed_val & 0xffffffffU); + return value; } @@ -1498,6 +1942,25 @@ static PyType_Spec Decomptype_spec = { .slots = Decomptype_slots, }; +static PyType_Slot ZlibDecompressor_type_slots[] = { + {Py_tp_dealloc, ZlibDecompressor_dealloc}, + {Py_tp_members, ZlibDecompressor_members}, + {Py_tp_new, ZlibDecompressor__new__}, + {Py_tp_doc, (char *)ZlibDecompressor__new____doc__}, + {Py_tp_methods, ZlibDecompressor_methods}, + {0, 0}, +}; + +static PyType_Spec ZlibDecompressor_type_spec = { + .name = "zlib._ZlibDecompressor", + .basicsize = sizeof(ZlibDecompressor), + // Calling PyType_GetModuleState() on a subclass is not safe. + // ZlibDecompressor_type_spec does not have Py_TPFLAGS_BASETYPE flag + // which prevents to create a subclass. + // So calling PyType_GetModuleState() in this file is always safe. + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE), + .slots = ZlibDecompressor_type_slots, +}; PyDoc_STRVAR(zlib_module_documentation, "The functions in this module allow compression and decompression using the\n" "zlib library, which is based on GNU zip.\n" @@ -1519,6 +1982,7 @@ zlib_clear(PyObject *mod) zlibstate *state = get_zlib_state(mod); Py_CLEAR(state->Comptype); Py_CLEAR(state->Decomptype); + Py_CLEAR(state->ZlibDecompressorType); Py_CLEAR(state->ZlibError); return 0; } @@ -1529,6 +1993,7 @@ zlib_traverse(PyObject *mod, visitproc visit, void *arg) zlibstate *state = get_zlib_state(mod); Py_VISIT(state->Comptype); Py_VISIT(state->Decomptype); + Py_VISIT(state->ZlibDecompressorType); Py_VISIT(state->ZlibError); return 0; } @@ -1556,16 +2021,26 @@ zlib_exec(PyObject *mod) return -1; } + state->ZlibDecompressorType = (PyTypeObject *)PyType_FromModuleAndSpec( + mod, &ZlibDecompressor_type_spec, NULL); + if (state->ZlibDecompressorType == NULL) { + return -1; + } + state->ZlibError = PyErr_NewException("zlib.error", NULL, NULL); if (state->ZlibError == NULL) { return -1; } - Py_INCREF(state->ZlibError); - if (PyModule_AddObject(mod, "error", state->ZlibError) < 0) { + if (PyModule_AddObject(mod, "error", Py_NewRef(state->ZlibError)) < 0) { Py_DECREF(state->ZlibError); return -1; } + if (PyModule_AddObject(mod, "_ZlibDecompressor", + Py_NewRef(state->ZlibDecompressorType)) < 0) { + Py_DECREF(state->ZlibDecompressorType); + return -1; + } #define ZLIB_ADD_INT_MACRO(c) \ do { \ diff --git a/Objects/abstract.c b/Objects/abstract.c index 82599dd6eca..9dc74fb9c26 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -3,7 +3,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_call.h" // _PyObject_CallNoArgs() -#include "pycore_ceval.h" // _Py_EnterRecursiveCall() +#include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() #include "pycore_object.h" // _Py_CheckSlotResult() #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pystate.h" // _PyThreadState_GET() @@ -45,8 +45,7 @@ PyObject_Type(PyObject *o) } v = (PyObject *)Py_TYPE(o); - Py_INCREF(v); - return v; + return Py_NewRef(v); } Py_ssize_t @@ -92,7 +91,6 @@ PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue) { PyObject *hint, *result; Py_ssize_t res; - _Py_IDENTIFIER(__length_hint__); if (_PyObject_HasLen(o)) { res = PyObject_Length(o); if (res < 0) { @@ -107,7 +105,7 @@ PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue) return res; } } - hint = _PyObject_LookupSpecial(o, &PyId___length_hint__); + hint = _PyObject_LookupSpecial(o, &_Py_ID(__length_hint__)); if (hint == NULL) { if (PyErr_Occurred()) { return -1; @@ -177,21 +175,24 @@ PyObject_GetItem(PyObject *o, PyObject *key) if (PyType_Check(o)) { PyObject *meth, *result; - _Py_IDENTIFIER(__class_getitem__); // Special case type[int], but disallow other types so str[int] fails if ((PyTypeObject*)o == &PyType_Type) { return Py_GenericAlias(o, key); } - if (_PyObject_LookupAttrId(o, &PyId___class_getitem__, &meth) < 0) { + if (_PyObject_LookupAttr(o, &_Py_ID(__class_getitem__), &meth) < 0) { return NULL; } - if (meth) { + if (meth && meth != Py_None) { result = PyObject_CallOneArg(meth, key); Py_DECREF(meth); return result; } + Py_XDECREF(meth); + PyErr_Format(PyExc_TypeError, "type '%.200s' is not subscriptable", + ((PyTypeObject *)o)->tp_name); + return NULL; } return type_error("'%.200s' object is not subscriptable", o); @@ -474,7 +475,7 @@ PyBuffer_IsContiguous(const Py_buffer *view, char order) void* -PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices) +PyBuffer_GetPointer(const Py_buffer *view, const Py_ssize_t *indices) { char* pointer; int i; @@ -524,18 +525,12 @@ _Py_add_one_to_index_C(int nd, Py_ssize_t *index, const Py_ssize_t *shape) Py_ssize_t PyBuffer_SizeFromFormat(const char *format) { - PyObject *structmodule = NULL; PyObject *calcsize = NULL; PyObject *res = NULL; PyObject *fmt = NULL; Py_ssize_t itemsize = -1; - structmodule = PyImport_ImportModule("struct"); - if (structmodule == NULL) { - return itemsize; - } - - calcsize = PyObject_GetAttrString(structmodule, "calcsize"); + calcsize = _PyImport_GetModuleAttrString("struct", "calcsize"); if (calcsize == NULL) { goto done; } @@ -556,7 +551,6 @@ PyBuffer_SizeFromFormat(const char *format) } done: - Py_DECREF(structmodule); Py_XDECREF(calcsize); Py_XDECREF(fmt); Py_XDECREF(res); @@ -564,12 +558,13 @@ done: } int -PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort) +PyBuffer_FromContiguous(const Py_buffer *view, const void *buf, Py_ssize_t len, char fort) { int k; void (*addone)(int, Py_ssize_t *, const Py_ssize_t *); Py_ssize_t *indices, elements; - char *src, *ptr; + char *ptr; + const char *src; if (len > view->len) { len = view->len; @@ -726,9 +721,7 @@ PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, return -1; } - view->obj = obj; - if (obj) - Py_INCREF(obj); + view->obj = Py_XNewRef(obj); view->buf = buf; view->len = len; view->readonly = readonly; @@ -769,7 +762,6 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) PyObject *meth; PyObject *empty = NULL; PyObject *result = NULL; - _Py_IDENTIFIER(__format__); if (format_spec != NULL && !PyUnicode_Check(format_spec)) { PyErr_Format(PyExc_SystemError, @@ -781,8 +773,7 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) /* Fast path for common types. */ if (format_spec == NULL || PyUnicode_GET_LENGTH(format_spec) == 0) { if (PyUnicode_CheckExact(obj)) { - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } if (PyLong_CheckExact(obj)) { return PyObject_Str(obj); @@ -796,7 +787,7 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) } /* Find the (unbound!) __format__ method */ - meth = _PyObject_LookupSpecial(obj, &PyId___format__); + meth = _PyObject_LookupSpecial(obj, &_Py_ID(__format__)); if (meth == NULL) { PyThreadState *tstate = _PyThreadState_GET(); if (!_PyErr_Occurred(tstate)) { @@ -815,8 +806,7 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) PyErr_Format(PyExc_TypeError, "__format__ must return a str, not %.200s", Py_TYPE(result)->tp_name); - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); goto done; } @@ -1248,21 +1238,10 @@ INPLACE_BINOP(PyNumber_InPlaceAnd, nb_inplace_and, nb_and, "&=") INPLACE_BINOP(PyNumber_InPlaceLshift, nb_inplace_lshift, nb_lshift, "<<=") INPLACE_BINOP(PyNumber_InPlaceRshift, nb_inplace_rshift, nb_rshift, ">>=") INPLACE_BINOP(PyNumber_InPlaceSubtract, nb_inplace_subtract, nb_subtract, "-=") -INPLACE_BINOP(PyNumber_InMatrixMultiply, nb_inplace_matrix_multiply, nb_matrix_multiply, "@=") - -PyObject * -PyNumber_InPlaceFloorDivide(PyObject *v, PyObject *w) -{ - return binary_iop(v, w, NB_SLOT(nb_inplace_floor_divide), - NB_SLOT(nb_floor_divide), "//="); -} - -PyObject * -PyNumber_InPlaceTrueDivide(PyObject *v, PyObject *w) -{ - return binary_iop(v, w, NB_SLOT(nb_inplace_true_divide), - NB_SLOT(nb_true_divide), "/="); -} +INPLACE_BINOP(PyNumber_InPlaceMatrixMultiply, nb_inplace_matrix_multiply, nb_matrix_multiply, "@=") +INPLACE_BINOP(PyNumber_InPlaceFloorDivide, nb_inplace_floor_divide, nb_floor_divide, "//=") +INPLACE_BINOP(PyNumber_InPlaceTrueDivide, nb_inplace_true_divide, nb_true_divide, "/=") +INPLACE_BINOP(PyNumber_InPlaceRemainder, nb_inplace_remainder, nb_remainder, "%=") PyObject * PyNumber_InPlaceAdd(PyObject *v, PyObject *w) @@ -1316,20 +1295,6 @@ PyNumber_InPlaceMultiply(PyObject *v, PyObject *w) return result; } -PyObject * -PyNumber_InPlaceMatrixMultiply(PyObject *v, PyObject *w) -{ - return binary_iop(v, w, NB_SLOT(nb_inplace_matrix_multiply), - NB_SLOT(nb_matrix_multiply), "@="); -} - -PyObject * -PyNumber_InPlaceRemainder(PyObject *v, PyObject *w) -{ - return binary_iop(v, w, NB_SLOT(nb_inplace_remainder), - NB_SLOT(nb_remainder), "%="); -} - PyObject * PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z) { @@ -1435,8 +1400,7 @@ _PyNumber_Index(PyObject *item) } if (PyLong_Check(item)) { - Py_INCREF(item); - return item; + return Py_NewRef(item); } if (!_PyIndex_Check(item)) { PyErr_Format(PyExc_TypeError, @@ -1544,15 +1508,13 @@ PyNumber_Long(PyObject *o) PyNumberMethods *m; PyObject *trunc_func; Py_buffer view; - _Py_IDENTIFIER(__trunc__); if (o == NULL) { return null_error(); } if (PyLong_CheckExact(o)) { - Py_INCREF(o); - return o; + return Py_NewRef(o); } m = Py_TYPE(o)->tp_as_number; if (m && m->nb_int) { /* This should include subclasses of int */ @@ -1586,8 +1548,13 @@ PyNumber_Long(PyObject *o) if (m && m->nb_index) { return PyNumber_Index(o); } - trunc_func = _PyObject_LookupSpecial(o, &PyId___trunc__); + trunc_func = _PyObject_LookupSpecial(o, &_Py_ID(__trunc__)); if (trunc_func) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "The delegation of int() to __trunc__ is deprecated.", 1)) { + Py_DECREF(trunc_func); + return NULL; + } result = _PyObject_CallNoArgs(trunc_func); Py_DECREF(trunc_func); if (result == NULL || PyLong_CheckExact(result)) { @@ -2071,8 +2038,7 @@ PySequence_Tuple(PyObject *v) a tuple *subclass* instance as-is, hence the restriction to exact tuples here. In contrast, lists always make a copy, so there's no need for exactness below. */ - Py_INCREF(v); - return v; + return Py_NewRef(v); } if (PyList_CheckExact(v)) return PyList_AsTuple(v); @@ -2170,8 +2136,7 @@ PySequence_Fast(PyObject *v, const char *m) } if (PyList_CheckExact(v) || PyTuple_CheckExact(v)) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } it = PyObject_GetIter(v); @@ -2425,12 +2390,12 @@ PyMapping_HasKey(PyObject *o, PyObject *key) a helper for PyMapping_Keys(), PyMapping_Items() and PyMapping_Values(). */ static PyObject * -method_output_as_list(PyObject *o, _Py_Identifier *meth_id) +method_output_as_list(PyObject *o, PyObject *meth) { PyObject *it, *result, *meth_output; assert(o != NULL); - meth_output = _PyObject_CallMethodIdNoArgs(o, meth_id); + meth_output = PyObject_CallMethodNoArgs(o, meth); if (meth_output == NULL || PyList_CheckExact(meth_output)) { return meth_output; } @@ -2441,7 +2406,7 @@ method_output_as_list(PyObject *o, _Py_Identifier *meth_id) _PyErr_Format(tstate, PyExc_TypeError, "%.200s.%U() returned a non-iterable (type %.200s)", Py_TYPE(o)->tp_name, - _PyUnicode_FromId(meth_id), + meth, Py_TYPE(meth_output)->tp_name); } Py_DECREF(meth_output); @@ -2456,43 +2421,37 @@ method_output_as_list(PyObject *o, _Py_Identifier *meth_id) PyObject * PyMapping_Keys(PyObject *o) { - _Py_IDENTIFIER(keys); - if (o == NULL) { return null_error(); } if (PyDict_CheckExact(o)) { return PyDict_Keys(o); } - return method_output_as_list(o, &PyId_keys); + return method_output_as_list(o, &_Py_ID(keys)); } PyObject * PyMapping_Items(PyObject *o) { - _Py_IDENTIFIER(items); - if (o == NULL) { return null_error(); } if (PyDict_CheckExact(o)) { return PyDict_Items(o); } - return method_output_as_list(o, &PyId_items); + return method_output_as_list(o, &_Py_ID(items)); } PyObject * PyMapping_Values(PyObject *o) { - _Py_IDENTIFIER(values); - if (o == NULL) { return null_error(); } if (PyDict_CheckExact(o)) { return PyDict_Values(o); } - return method_output_as_list(o, &PyId_values); + return method_output_as_list(o, &_Py_ID(values)); } /* isinstance(), issubclass() */ @@ -2524,10 +2483,9 @@ PyMapping_Values(PyObject *o) static PyObject * abstract_get_bases(PyObject *cls) { - _Py_IDENTIFIER(__bases__); PyObject *bases; - (void)_PyObject_LookupAttrId(cls, &PyId___bases__, &bases); + (void)_PyObject_LookupAttr(cls, &_Py_ID(__bases__), &bases); if (bases != NULL && !PyTuple_Check(bases)) { Py_DECREF(bases); return NULL; @@ -2572,7 +2530,7 @@ abstract_issubclass(PyObject *derived, PyObject *cls) break; } assert(n >= 2); - if (Py_EnterRecursiveCall(" in __issubclass__")) { + if (_Py_EnterRecursiveCall(" in __issubclass__")) { Py_DECREF(bases); return -1; } @@ -2582,7 +2540,7 @@ abstract_issubclass(PyObject *derived, PyObject *cls) break; } } - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(bases); return r; } @@ -2608,11 +2566,10 @@ object_isinstance(PyObject *inst, PyObject *cls) { PyObject *icls; int retval; - _Py_IDENTIFIER(__class__); if (PyType_Check(cls)) { retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls); if (retval == 0) { - retval = _PyObject_LookupAttrId(inst, &PyId___class__, &icls); + retval = _PyObject_LookupAttr(inst, &_Py_ID(__class__), &icls); if (icls != NULL) { if (icls != (PyObject *)(Py_TYPE(inst)) && PyType_Check(icls)) { retval = PyType_IsSubtype( @@ -2630,7 +2587,7 @@ object_isinstance(PyObject *inst, PyObject *cls) if (!check_class(cls, "isinstance() arg 2 must be a type, a tuple of types, or a union")) return -1; - retval = _PyObject_LookupAttrId(inst, &PyId___class__, &icls); + retval = _PyObject_LookupAttr(inst, &_Py_ID(__class__), &icls); if (icls != NULL) { retval = abstract_issubclass(icls, cls); Py_DECREF(icls); @@ -2643,8 +2600,6 @@ object_isinstance(PyObject *inst, PyObject *cls) static int object_recursive_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls) { - _Py_IDENTIFIER(__instancecheck__); - /* Quick test for an exact match */ if (Py_IS_TYPE(inst, (PyTypeObject *)cls)) { return 1; @@ -2655,10 +2610,14 @@ object_recursive_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls return object_isinstance(inst, cls); } + if (_PyUnion_Check(cls)) { + cls = _Py_union_args(cls); + } + if (PyTuple_Check(cls)) { /* Not a general sequence -- that opens up the road to recursion and stack overflow. */ - if (_Py_EnterRecursiveCall(tstate, " in __instancecheck__")) { + if (_Py_EnterRecursiveCallTstate(tstate, " in __instancecheck__")) { return -1; } Py_ssize_t n = PyTuple_GET_SIZE(cls); @@ -2671,19 +2630,19 @@ object_recursive_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls break; } } - _Py_LeaveRecursiveCall(tstate); + _Py_LeaveRecursiveCallTstate(tstate); return r; } - PyObject *checker = _PyObject_LookupSpecial(cls, &PyId___instancecheck__); + PyObject *checker = _PyObject_LookupSpecial(cls, &_Py_ID(__instancecheck__)); if (checker != NULL) { - if (_Py_EnterRecursiveCall(tstate, " in __instancecheck__")) { + if (_Py_EnterRecursiveCallTstate(tstate, " in __instancecheck__")) { Py_DECREF(checker); return -1; } PyObject *res = PyObject_CallOneArg(checker, inst); - _Py_LeaveRecursiveCall(tstate); + _Py_LeaveRecursiveCallTstate(tstate); Py_DECREF(checker); if (res == NULL) { @@ -2734,7 +2693,6 @@ recursive_issubclass(PyObject *derived, PyObject *cls) static int object_issubclass(PyThreadState *tstate, PyObject *derived, PyObject *cls) { - _Py_IDENTIFIER(__subclasscheck__); PyObject *checker; /* We know what type's __subclasscheck__ does. */ @@ -2745,9 +2703,13 @@ object_issubclass(PyThreadState *tstate, PyObject *derived, PyObject *cls) return recursive_issubclass(derived, cls); } + if (_PyUnion_Check(cls)) { + cls = _Py_union_args(cls); + } + if (PyTuple_Check(cls)) { - if (_Py_EnterRecursiveCall(tstate, " in __subclasscheck__")) { + if (_Py_EnterRecursiveCallTstate(tstate, " in __subclasscheck__")) { return -1; } Py_ssize_t n = PyTuple_GET_SIZE(cls); @@ -2759,19 +2721,19 @@ object_issubclass(PyThreadState *tstate, PyObject *derived, PyObject *cls) /* either found it, or got an error */ break; } - _Py_LeaveRecursiveCall(tstate); + _Py_LeaveRecursiveCallTstate(tstate); return r; } - checker = _PyObject_LookupSpecial(cls, &PyId___subclasscheck__); + checker = _PyObject_LookupSpecial(cls, &_Py_ID(__subclasscheck__)); if (checker != NULL) { int ok = -1; - if (_Py_EnterRecursiveCall(tstate, " in __subclasscheck__")) { + if (_Py_EnterRecursiveCallTstate(tstate, " in __subclasscheck__")) { Py_DECREF(checker); return ok; } PyObject *res = PyObject_CallOneArg(checker, derived); - _Py_LeaveRecursiveCall(tstate); + _Py_LeaveRecursiveCallTstate(tstate); Py_DECREF(checker); if (res != NULL) { ok = PyObject_IsTrue(res); @@ -2828,8 +2790,7 @@ PyObject_GetIter(PyObject *o) "iter() returned non-iterator " "of type '%.100s'", Py_TYPE(res)->tp_name); - Py_DECREF(res); - res = NULL; + Py_SETREF(res, NULL); } return res; } @@ -2849,8 +2810,7 @@ PyObject_GetAIter(PyObject *o) { PyErr_Format(PyExc_TypeError, "aiter() returned not an async iterator of type '%.100s'", Py_TYPE(it)->tp_name); - Py_DECREF(it); - it = NULL; + Py_SETREF(it, NULL); } return it; } @@ -2898,7 +2858,6 @@ PyIter_Next(PyObject *iter) PySendResult PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result) { - _Py_IDENTIFIER(send); assert(arg != NULL); assert(result != NULL); if (Py_TYPE(iter)->tp_as_async && Py_TYPE(iter)->tp_as_async->am_send) { @@ -2910,7 +2869,7 @@ PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result) *result = Py_TYPE(iter)->tp_iternext(iter); } else { - *result = _PyObject_CallMethodIdOneArg(iter, &PyId_send, arg); + *result = PyObject_CallMethodOneArg(iter, &_Py_ID(send), arg); } if (*result != NULL) { return PYGEN_NEXT; diff --git a/Objects/accu.c b/Objects/accu.c deleted file mode 100644 index c8b5d382e38..00000000000 --- a/Objects/accu.c +++ /dev/null @@ -1,115 +0,0 @@ -/* Accumulator struct implementation */ - -#include "Python.h" -#include "pycore_accu.h" - -static PyObject * -join_list_unicode(PyObject *lst) -{ - /* return ''.join(lst) */ - PyObject *sep, *ret; - sep = PyUnicode_FromStringAndSize("", 0); - ret = PyUnicode_Join(sep, lst); - Py_DECREF(sep); - return ret; -} - -int -_PyAccu_Init(_PyAccu *acc) -{ - /* Lazily allocated */ - acc->large = NULL; - acc->small = PyList_New(0); - if (acc->small == NULL) - return -1; - return 0; -} - -static int -flush_accumulator(_PyAccu *acc) -{ - Py_ssize_t nsmall = PyList_GET_SIZE(acc->small); - if (nsmall) { - int ret; - PyObject *joined; - if (acc->large == NULL) { - acc->large = PyList_New(0); - if (acc->large == NULL) - return -1; - } - joined = join_list_unicode(acc->small); - if (joined == NULL) - return -1; - if (PyList_SetSlice(acc->small, 0, nsmall, NULL)) { - Py_DECREF(joined); - return -1; - } - ret = PyList_Append(acc->large, joined); - Py_DECREF(joined); - return ret; - } - return 0; -} - -int -_PyAccu_Accumulate(_PyAccu *acc, PyObject *unicode) -{ - Py_ssize_t nsmall; - assert(PyUnicode_Check(unicode)); - - if (PyList_Append(acc->small, unicode)) - return -1; - nsmall = PyList_GET_SIZE(acc->small); - /* Each item in a list of unicode objects has an overhead (in 64-bit - * builds) of: - * - 8 bytes for the list slot - * - 56 bytes for the header of the unicode object - * that is, 64 bytes. 100000 such objects waste more than 6 MiB - * compared to a single concatenated string. - */ - if (nsmall < 100000) - return 0; - return flush_accumulator(acc); -} - -PyObject * -_PyAccu_FinishAsList(_PyAccu *acc) -{ - int ret; - PyObject *res; - - ret = flush_accumulator(acc); - Py_CLEAR(acc->small); - if (ret) { - Py_CLEAR(acc->large); - return NULL; - } - res = acc->large; - acc->large = NULL; - return res; -} - -PyObject * -_PyAccu_Finish(_PyAccu *acc) -{ - PyObject *list, *res; - if (acc->large == NULL) { - list = acc->small; - acc->small = NULL; - } - else { - list = _PyAccu_FinishAsList(acc); - if (!list) - return NULL; - } - res = join_list_unicode(list); - Py_DECREF(list); - return res; -} - -void -_PyAccu_Destroy(_PyAccu *acc) -{ - Py_CLEAR(acc->small); - Py_CLEAR(acc->large); -} diff --git a/Objects/boolobject.c b/Objects/boolobject.c index 53f81926057..18666f88cbd 100644 --- a/Objects/boolobject.c +++ b/Objects/boolobject.c @@ -1,26 +1,16 @@ /* Boolean type, a subtype of int */ #include "Python.h" -#include "pycore_pyerrors.h" // _Py_FatalRefcountError() +#include "pycore_object.h" // _Py_FatalRefcountError() +#include "pycore_runtime.h" // _Py_ID() /* We define bool_repr to return "False" or "True" */ -static PyObject *false_str = NULL; -static PyObject *true_str = NULL; - static PyObject * bool_repr(PyObject *self) { - PyObject *s; - - if (self == Py_True) - s = true_str ? true_str : - (true_str = PyUnicode_InternFromString("True")); - else - s = false_str ? false_str : - (false_str = PyUnicode_InternFromString("False")); - Py_XINCREF(s); - return s; + PyObject *res = self == Py_True ? &_Py_ID(True) : &_Py_ID(False); + return Py_NewRef(res); } /* Function to return a bool from a C long */ @@ -33,8 +23,7 @@ PyObject *PyBool_FromLong(long ok) result = Py_True; else result = Py_False; - Py_INCREF(result); - return result; + return Py_NewRef(result); } /* We define bool_new to always return either Py_True or Py_False */ diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index a6009854221..072089e39aa 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -4,8 +4,10 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_bytes_methods.h" +#include "pycore_bytesobject.h" #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_strhex.h" // _Py_strhex_with_sep() +#include "pycore_long.h" // _PyLong_FromUnsignedChar() #include "bytesobject.h" /*[clinic input] @@ -311,34 +313,22 @@ bytearray_iconcat(PyByteArrayObject *self, PyObject *other) } memcpy(PyByteArray_AS_STRING(self) + size, vo.buf, vo.len); PyBuffer_Release(&vo); - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } static PyObject * bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count) { - PyByteArrayObject *result; - Py_ssize_t mysize; - Py_ssize_t size; - const char *buf; - if (count < 0) count = 0; - mysize = Py_SIZE(self); + const Py_ssize_t mysize = Py_SIZE(self); if (count > 0 && mysize > PY_SSIZE_T_MAX / count) return PyErr_NoMemory(); - size = mysize * count; - result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size); - buf = PyByteArray_AS_STRING(self); + Py_ssize_t size = mysize * count; + PyByteArrayObject* result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size); + const char* buf = PyByteArray_AS_STRING(self); if (result != NULL && size != 0) { - if (mysize == 1) - memset(result->ob_bytes, buf[0], size); - else { - Py_ssize_t i; - for (i = 0; i < count; i++) - memcpy(result->ob_bytes + i*mysize, buf, mysize); - } + _PyBytes_Repeat(result->ob_bytes, size, buf, mysize); } return (PyObject *)result; } @@ -346,30 +336,23 @@ bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count) static PyObject * bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count) { - Py_ssize_t mysize; - Py_ssize_t size; - char *buf; - if (count < 0) count = 0; - mysize = Py_SIZE(self); + else if (count == 1) { + return Py_NewRef(self); + } + + const Py_ssize_t mysize = Py_SIZE(self); if (count > 0 && mysize > PY_SSIZE_T_MAX / count) return PyErr_NoMemory(); - size = mysize * count; + const Py_ssize_t size = mysize * count; if (PyByteArray_Resize((PyObject *)self, size) < 0) return NULL; - buf = PyByteArray_AS_STRING(self); - if (mysize == 1) - memset(buf, buf[0], size); - else { - Py_ssize_t i; - for (i = 1; i < count; i++) - memcpy(buf + i*mysize, buf, mysize); - } + char* buf = PyByteArray_AS_STRING(self); + _PyBytes_Repeat(buf, size, buf, mysize); - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } static PyObject * @@ -379,7 +362,7 @@ bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i) PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); return NULL; } - return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i])); + return _PyLong_FromUnsignedChar((unsigned char)(self->ob_start[i])); } static PyObject * @@ -398,7 +381,7 @@ bytearray_subscript(PyByteArrayObject *self, PyObject *index) PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); return NULL; } - return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i])); + return _PyLong_FromUnsignedChar((unsigned char)(self->ob_start[i])); } else if (PySlice_Check(index)) { Py_ssize_t start, stop, step, slicelength, i; @@ -577,22 +560,28 @@ bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi, static int bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value) { - int ival; + int ival = -1; - if (i < 0) + // GH-91153: We need to do this *before* the size check, in case value has a + // nasty __index__ method that changes the size of the bytearray: + if (value && !_getbytevalue(value, &ival)) { + return -1; + } + + if (i < 0) { i += Py_SIZE(self); + } if (i < 0 || i >= Py_SIZE(self)) { PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); return -1; } - if (value == NULL) + if (value == NULL) { return bytearray_setslice(self, i, i+1, NULL); + } - if (!_getbytevalue(value, &ival)) - return -1; - + assert(0 <= ival && ival < 256); PyByteArray_AS_STRING(self)[i] = ival; return 0; } @@ -607,11 +596,21 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu if (_PyIndex_Check(index)) { Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) + if (i == -1 && PyErr_Occurred()) { return -1; + } - if (i < 0) + int ival = -1; + + // GH-91153: We need to do this *before* the size check, in case values + // has a nasty __index__ method that changes the size of the bytearray: + if (values && !_getbytevalue(values, &ival)) { + return -1; + } + + if (i < 0) { i += PyByteArray_GET_SIZE(self); + } if (i < 0 || i >= Py_SIZE(self)) { PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); @@ -626,9 +625,7 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu slicelen = 1; } else { - int ival; - if (!_getbytevalue(values, &ival)) - return -1; + assert(0 <= ival && ival < 256); buf[i] = (char)ival; return 0; } @@ -844,8 +841,33 @@ bytearray___init___impl(PyByteArrayObject *self, PyObject *arg, return -1; } - /* XXX Optimize this if the arguments is a list, tuple */ - + if (PyList_CheckExact(arg) || PyTuple_CheckExact(arg)) { + Py_ssize_t size = PySequence_Fast_GET_SIZE(arg); + if (PyByteArray_Resize((PyObject *)self, size) < 0) { + return -1; + } + PyObject **items = PySequence_Fast_ITEMS(arg); + char *s = PyByteArray_AS_STRING(self); + for (Py_ssize_t i = 0; i < size; i++) { + int value; + if (!PyLong_CheckExact(items[i])) { + /* Resize to 0 and go through slowpath */ + if (Py_SIZE(self) != 0) { + if (PyByteArray_Resize((PyObject *)self, 0) < 0) { + return -1; + } + } + goto slowpath; + } + int rc = _getbytevalue(items[i], &value); + if (!rc) { + return -1; + } + s[i] = value; + } + return 0; + } +slowpath: /* Get the iterator */ it = PyObject_GetIter(arg); if (it == NULL) { @@ -1074,6 +1096,7 @@ bytearray_dealloc(PyByteArrayObject *self) /* -------------------------------------------------------------------- */ /* Methods */ +#define STRINGLIB_IS_UNICODE 0 #define FASTSEARCH fastsearch #define STRINGLIB(F) stringlib_##F #define STRINGLIB_CHAR char @@ -1084,6 +1107,7 @@ bytearray_dealloc(PyByteArrayObject *self) #define STRINGLIB_ISSPACE Py_ISSPACE #define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r')) #define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact +#define STRINGLIB_FAST_MEMCHR memchr #define STRINGLIB_MUTABLE 1 #include "stringlib/fastsearch.h" @@ -1798,7 +1822,7 @@ bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index) if (PyByteArray_Resize((PyObject *)self, n - 1) < 0) return NULL; - return PyLong_FromLong((unsigned char)value); + return _PyLong_FromUnsignedChar((unsigned char)value); } /*[clinic input] @@ -1833,26 +1857,46 @@ bytearray_remove_impl(PyByteArrayObject *self, int value) Py_RETURN_NONE; } -/* XXX These two helpers could be optimized if argsize == 1 */ +#define LEFTSTRIP 0 +#define RIGHTSTRIP 1 +#define BOTHSTRIP 2 -static Py_ssize_t -lstrip_helper(const char *myptr, Py_ssize_t mysize, - const void *argptr, Py_ssize_t argsize) +static PyObject* +bytearray_strip_impl_helper(PyByteArrayObject* self, PyObject* bytes, int striptype) { - Py_ssize_t i = 0; - while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize)) - i++; - return i; -} + Py_ssize_t mysize, byteslen; + const char* myptr; + const char* bytesptr; + Py_buffer vbytes; -static Py_ssize_t -rstrip_helper(const char *myptr, Py_ssize_t mysize, - const void *argptr, Py_ssize_t argsize) -{ - Py_ssize_t i = mysize - 1; - while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize)) - i--; - return i + 1; + if (bytes == Py_None) { + bytesptr = "\t\n\r\f\v "; + byteslen = 6; + } + else { + if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0) + return NULL; + bytesptr = (const char*)vbytes.buf; + byteslen = vbytes.len; + } + myptr = PyByteArray_AS_STRING(self); + mysize = Py_SIZE(self); + + Py_ssize_t left = 0; + if (striptype != RIGHTSTRIP) { + while (left < mysize && memchr(bytesptr, (unsigned char)myptr[left], byteslen)) + left++; + } + Py_ssize_t right = mysize; + if (striptype != LEFTSTRIP) { + do { + right--; + } while (right >= left && memchr(bytesptr, (unsigned char)myptr[right], byteslen)); + right++; + } + if (bytes != Py_None) + PyBuffer_Release(&vbytes); + return PyByteArray_FromStringAndSize(myptr + left, right - left); } /*[clinic input] @@ -1870,31 +1914,7 @@ static PyObject * bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes) /*[clinic end generated code: output=760412661a34ad5a input=ef7bb59b09c21d62]*/ { - Py_ssize_t left, right, mysize, byteslen; - char *myptr; - const char *bytesptr; - Py_buffer vbytes; - - if (bytes == Py_None) { - bytesptr = "\t\n\r\f\v "; - byteslen = 6; - } - else { - if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0) - return NULL; - bytesptr = (const char *) vbytes.buf; - byteslen = vbytes.len; - } - myptr = PyByteArray_AS_STRING(self); - mysize = Py_SIZE(self); - left = lstrip_helper(myptr, mysize, bytesptr, byteslen); - if (left == mysize) - right = left; - else - right = rstrip_helper(myptr, mysize, bytesptr, byteslen); - if (bytes != Py_None) - PyBuffer_Release(&vbytes); - return PyByteArray_FromStringAndSize(myptr + left, right - left); + return bytearray_strip_impl_helper(self, bytes, BOTHSTRIP); } /*[clinic input] @@ -1912,28 +1932,7 @@ static PyObject * bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes) /*[clinic end generated code: output=d005c9d0ab909e66 input=80843f975dd7c480]*/ { - Py_ssize_t left, right, mysize, byteslen; - char *myptr; - const char *bytesptr; - Py_buffer vbytes; - - if (bytes == Py_None) { - bytesptr = "\t\n\r\f\v "; - byteslen = 6; - } - else { - if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0) - return NULL; - bytesptr = (const char *) vbytes.buf; - byteslen = vbytes.len; - } - myptr = PyByteArray_AS_STRING(self); - mysize = Py_SIZE(self); - left = lstrip_helper(myptr, mysize, bytesptr, byteslen); - right = mysize; - if (bytes != Py_None) - PyBuffer_Release(&vbytes); - return PyByteArray_FromStringAndSize(myptr + left, right - left); + return bytearray_strip_impl_helper(self, bytes, LEFTSTRIP); } /*[clinic input] @@ -1951,27 +1950,7 @@ static PyObject * bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes) /*[clinic end generated code: output=030e2fbd2f7276bd input=e728b994954cfd91]*/ { - Py_ssize_t right, mysize, byteslen; - char *myptr; - const char *bytesptr; - Py_buffer vbytes; - - if (bytes == Py_None) { - bytesptr = "\t\n\r\f\v "; - byteslen = 6; - } - else { - if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0) - return NULL; - bytesptr = (const char *) vbytes.buf; - byteslen = vbytes.len; - } - myptr = PyByteArray_AS_STRING(self); - mysize = Py_SIZE(self); - right = rstrip_helper(myptr, mysize, bytesptr, byteslen); - if (bytes != Py_None) - PyBuffer_Release(&vbytes); - return PyByteArray_FromStringAndSize(myptr, right); + return bytearray_strip_impl_helper(self, bytes, RIGHTSTRIP); } /*[clinic input] @@ -2033,7 +2012,7 @@ bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes) /*[clinic input] bytearray.splitlines - keepends: bool(accept={int}) = False + keepends: bool = False Return a list of the lines in the bytearray, breaking at line boundaries. @@ -2043,7 +2022,7 @@ true. static PyObject * bytearray_splitlines_impl(PyByteArrayObject *self, int keepends) -/*[clinic end generated code: output=4223c94b895f6ad9 input=99a27ad959b9cf6b]*/ +/*[clinic end generated code: output=4223c94b895f6ad9 input=66b2dcdea8d093bf]*/ { return stringlib_splitlines( (PyObject*) self, PyByteArray_AS_STRING(self), @@ -2110,36 +2089,26 @@ bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep, int bytes_per_sep) static PyObject * _common_reduce(PyByteArrayObject *self, int proto) { - PyObject *dict; - _Py_IDENTIFIER(__dict__); - char *buf; + PyObject *state; + const char *buf; - if (_PyObject_LookupAttrId((PyObject *)self, &PyId___dict__, &dict) < 0) { + state = _PyObject_GetState((PyObject *)self); + if (state == NULL) { return NULL; } - if (dict == NULL) { - dict = Py_None; - Py_INCREF(dict); - } + if (!Py_SIZE(self)) { + return Py_BuildValue("(O()N)", Py_TYPE(self), state); + } buf = PyByteArray_AS_STRING(self); if (proto < 3) { /* use str based reduction for backwards compatibility with Python 2.x */ - PyObject *latin1; - if (Py_SIZE(self)) - latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL); - else - latin1 = PyUnicode_FromString(""); - return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict); + PyObject *latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL); + return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", state); } else { /* use more efficient byte based reduction */ - if (Py_SIZE(self)) { - return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict); - } - else { - return Py_BuildValue("(O()N)", Py_TYPE(self), dict); - } + return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), state); } } @@ -2182,10 +2151,9 @@ static PyObject * bytearray_sizeof_impl(PyByteArrayObject *self) /*[clinic end generated code: output=738abdd17951c427 input=e27320fd98a4bc5a]*/ { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)) + self->ob_alloc * sizeof(char); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(self)); + res += (size_t)self->ob_alloc * sizeof(char); + return PyLong_FromSize_t(res); } static PySequenceMethods bytearray_as_sequence = { @@ -2387,7 +2355,6 @@ static PyObject * bytearrayiter_next(bytesiterobject *it) { PyByteArrayObject *seq; - PyObject *item; assert(it != NULL); seq = it->it_seq; @@ -2396,11 +2363,8 @@ bytearrayiter_next(bytesiterobject *it) assert(PyByteArray_Check(seq)); if (it->it_index < PyByteArray_GET_SIZE(seq)) { - item = PyLong_FromLong( - (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]); - if (item != NULL) - ++it->it_index; - return item; + return _PyLong_FromUnsignedChar( + (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index++]); } it->it_seq = NULL; @@ -2427,12 +2391,11 @@ PyDoc_STRVAR(length_hint_doc, static PyObject * bytearrayiter_reduce(bytesiterobject *it, PyObject *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(iter); if (it->it_seq != NULL) { - return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter), + return Py_BuildValue("N(O)n", _PyEval_GetBuiltin(&_Py_ID(iter)), it->it_seq, it->it_index); } else { - return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter)); + return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter))); } } @@ -2510,8 +2473,7 @@ bytearray_iter(PyObject *seq) if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyByteArrayObject *)seq; + it->it_seq = (PyByteArrayObject *)Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index 994fb8a73c6..6b8166385d3 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -431,6 +431,7 @@ _Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to) #define STRINGLIB(F) stringlib_##F #define STRINGLIB_CHAR char #define STRINGLIB_SIZEOF_CHAR 1 +#define STRINGLIB_FAST_MEMCHR memchr #include "stringlib/fastsearch.h" #include "stringlib/count.h" diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 66fd2ecc3c4..ba2c2e978c6 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -4,9 +4,11 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_bytesobject.h" // _PyBytes_Find(), _PyBytes_Repeat() #include "pycore_bytes_methods.h" // _Py_bytes_startswith() #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_format.h" // F_LJUST +#include "pycore_global_objects.h" // _Py_GET_GLOBAL_OBJECT() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_long.h" // _PyLong_DigitValue #include "pycore_object.h" // _PyObject_GC_TRACK @@ -22,8 +24,6 @@ class bytes "PyBytesObject *" "&PyBytes_Type" #include "clinic/bytesobject.c.h" -_Py_IDENTIFIER(__bytes__); - /* PyBytesObject_SIZE gives the basic size of a bytes object; any memory allocation for a bytes object of length n should request PyBytesObject_SIZE + n bytes. @@ -37,49 +37,23 @@ Py_LOCAL_INLINE(Py_ssize_t) _PyBytesWriter_GetSize(_PyBytesWriter *writer, char *str); -static struct _Py_bytes_state* -get_bytes_state(void) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - return &interp->bytes; -} +#define CHARACTERS _Py_SINGLETON(bytes_characters) +#define CHARACTER(ch) \ + ((PyBytesObject *)&(CHARACTERS[ch])); +#define EMPTY (&_Py_SINGLETON(bytes_empty)) // Return a borrowed reference to the empty bytes string singleton. static inline PyObject* bytes_get_empty(void) { - struct _Py_bytes_state *state = get_bytes_state(); - // bytes_get_empty() must not be called before _PyBytes_Init() - // or after _PyBytes_Fini() - assert(state->empty_string != NULL); - return state->empty_string; + return &EMPTY->ob_base.ob_base; } // Return a strong reference to the empty bytes string singleton. static inline PyObject* bytes_new_empty(void) { - PyObject *empty = bytes_get_empty(); - Py_INCREF(empty); - return (PyObject *)empty; -} - - -static int -bytes_create_empty_string_singleton(struct _Py_bytes_state *state) -{ - // Create the empty bytes string singleton - PyBytesObject *op = (PyBytesObject *)PyObject_Malloc(PyBytesObject_SIZE); - if (op == NULL) { - return -1; - } - _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, 0); - op->ob_shash = -1; - op->ob_sval[0] = '\0'; - - assert(state->empty_string == NULL); - state->empty_string = (PyObject *)op; - return 0; + return Py_NewRef(EMPTY); } @@ -130,7 +104,10 @@ _PyBytes_FromSize(Py_ssize_t size, int use_calloc) return PyErr_NoMemory(); } _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size); +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS op->ob_shash = -1; +_Py_COMP_DIAG_POP if (!use_calloc) { op->ob_sval[size] = '\0'; } @@ -147,12 +124,8 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) return NULL; } if (size == 1 && str != NULL) { - struct _Py_bytes_state *state = get_bytes_state(); - op = state->characters[*str & UCHAR_MAX]; - if (op != NULL) { - Py_INCREF(op); - return (PyObject *)op; - } + op = CHARACTER(*str & 255); + return Py_NewRef(op); } if (size == 0) { return bytes_new_empty(); @@ -165,12 +138,6 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) return (PyObject *) op; memcpy(op->ob_sval, str, size); - /* share short strings */ - if (size == 1) { - struct _Py_bytes_state *state = get_bytes_state(); - Py_INCREF(op); - state->characters[*str & UCHAR_MAX] = op; - } return (PyObject *) op; } @@ -188,16 +155,12 @@ PyBytes_FromString(const char *str) return NULL; } - struct _Py_bytes_state *state = get_bytes_state(); if (size == 0) { return bytes_new_empty(); } else if (size == 1) { - op = state->characters[*str & UCHAR_MAX]; - if (op != NULL) { - Py_INCREF(op); - return (PyObject *)op; - } + op = CHARACTER(*str & 255); + return Py_NewRef(op); } /* Inline PyObject_NewVar */ @@ -206,14 +169,11 @@ PyBytes_FromString(const char *str) return PyErr_NoMemory(); } _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size); +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS op->ob_shash = -1; +_Py_COMP_DIAG_POP memcpy(op->ob_sval, str, size+1); - /* share short strings */ - if (size == 1) { - assert(state->characters[*str & UCHAR_MAX] == NULL); - Py_INCREF(op); - state->characters[*str & UCHAR_MAX] = op; - } return (PyObject *) op; } @@ -414,11 +374,7 @@ PyBytes_FromFormat(const char *format, ...) PyObject* ret; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif ret = PyBytes_FromFormatV(format, vargs); va_end(vargs); return ret; @@ -452,6 +408,7 @@ formatfloat(PyObject *v, int flags, int prec, int type, PyObject *result; double x; size_t len; + int dtoa_flags = 0; x = PyFloat_AsDouble(v); if (x == -1.0 && PyErr_Occurred()) { @@ -463,8 +420,13 @@ formatfloat(PyObject *v, int flags, int prec, int type, if (prec < 0) prec = 6; - p = PyOS_double_to_string(x, type, prec, - (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL); + if (flags & F_ALT) { + dtoa_flags |= Py_DTSF_ALT; + } + if (flags & F_NO_NEG_0) { + dtoa_flags |= Py_DTSF_NO_NEG_0; + } + p = PyOS_double_to_string(x, type, prec, dtoa_flags, NULL); if (p == NULL) return NULL; @@ -472,8 +434,10 @@ formatfloat(PyObject *v, int flags, int prec, int type, len = strlen(p); if (writer != NULL) { str = _PyBytesWriter_Prepare(writer, str, len); - if (str == NULL) + if (str == NULL) { + PyMem_Free(p); return NULL; + } memcpy(str, p, len); PyMem_Free(p); str += len; @@ -562,17 +526,15 @@ format_obj(PyObject *v, const char **pbuf, Py_ssize_t *plen) if (PyBytes_Check(v)) { *pbuf = PyBytes_AS_STRING(v); *plen = PyBytes_GET_SIZE(v); - Py_INCREF(v); - return v; + return Py_NewRef(v); } if (PyByteArray_Check(v)) { *pbuf = PyByteArray_AS_STRING(v); *plen = PyByteArray_GET_SIZE(v); - Py_INCREF(v); - return v; + return Py_NewRef(v); } /* does it support __bytes__? */ - func = _PyObject_LookupSpecial(v, &PyId___bytes__); + func = _PyObject_LookupSpecial(v, &_Py_ID(__bytes__)); if (func != NULL) { result = _PyObject_CallNoArgs(func); Py_DECREF(func); @@ -743,6 +705,7 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len, case ' ': flags |= F_BLANK; continue; case '#': flags |= F_ALT; continue; case '0': flags |= F_ZERO; continue; + case 'z': flags |= F_NO_NEG_0; continue; } break; } @@ -1143,6 +1106,12 @@ PyObject *_PyBytes_DecodeEscape(const char *s, if (s < end && '0' <= *s && *s <= '7') c = (c<<3) + *s++ - '0'; } + if (c > 0377) { + if (*first_invalid_escape == NULL) { + *first_invalid_escape = s-3; /* Back up 3 chars, since we've + already incremented s. */ + } + } *p++ = c; break; case 'x': @@ -1209,11 +1178,24 @@ PyObject *PyBytes_DecodeEscape(const char *s, if (result == NULL) return NULL; if (first_invalid_escape != NULL) { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "invalid escape sequence '\\%c'", - (unsigned char)*first_invalid_escape) < 0) { - Py_DECREF(result); - return NULL; + unsigned char c = *first_invalid_escape; + if ('4' <= c && c <= '7') { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "invalid octal escape sequence '\\%.3s'", + first_invalid_escape) < 0) + { + Py_DECREF(result); + return NULL; + } + } + else { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "invalid escape sequence '\\%c'", + c) < 0) + { + Py_DECREF(result); + return NULL; + } } } return result; @@ -1277,6 +1259,7 @@ PyBytes_AsStringAndSize(PyObject *obj, #define STRINGLIB_GET_EMPTY() bytes_get_empty() #include "stringlib/stringdefs.h" +#define STRINGLIB_MUTABLE 0 #include "stringlib/fastsearch.h" #include "stringlib/count.h" @@ -1290,6 +1273,24 @@ PyBytes_AsStringAndSize(PyObject *obj, #undef STRINGLIB_GET_EMPTY +Py_ssize_t +_PyBytes_Find(const char *haystack, Py_ssize_t len_haystack, + const char *needle, Py_ssize_t len_needle, + Py_ssize_t offset) +{ + return stringlib_find(haystack, len_haystack, + needle, len_needle, offset); +} + +Py_ssize_t +_PyBytes_ReverseFind(const char *haystack, Py_ssize_t len_haystack, + const char *needle, Py_ssize_t len_needle, + Py_ssize_t offset) +{ + return stringlib_rfind(haystack, len_haystack, + needle, len_needle, offset); +} + PyObject * PyBytes_Repr(PyObject *obj, int smartquotes) { @@ -1407,13 +1408,11 @@ bytes_concat(PyObject *a, PyObject *b) /* Optimize end cases */ if (va.len == 0 && PyBytes_CheckExact(b)) { - result = b; - Py_INCREF(result); + result = Py_NewRef(b); goto done; } if (vb.len == 0 && PyBytes_CheckExact(a)) { - result = a; - Py_INCREF(result); + result = Py_NewRef(a); goto done; } @@ -1439,8 +1438,6 @@ bytes_concat(PyObject *a, PyObject *b) static PyObject * bytes_repeat(PyBytesObject *a, Py_ssize_t n) { - Py_ssize_t i; - Py_ssize_t j; Py_ssize_t size; PyBytesObject *op; size_t nbytes; @@ -1456,8 +1453,7 @@ bytes_repeat(PyBytesObject *a, Py_ssize_t n) } size = Py_SIZE(a) * n; if (size == Py_SIZE(a) && PyBytes_CheckExact(a)) { - Py_INCREF(a); - return (PyObject *)a; + return Py_NewRef(a); } nbytes = (size_t)size; if (nbytes + PyBytesObject_SIZE <= nbytes) { @@ -1470,22 +1466,14 @@ bytes_repeat(PyBytesObject *a, Py_ssize_t n) return PyErr_NoMemory(); } _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size); +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS op->ob_shash = -1; +_Py_COMP_DIAG_POP op->ob_sval[size] = '\0'; - if (Py_SIZE(a) == 1 && n > 0) { - memset(op->ob_sval, a->ob_sval[0] , n); - return (PyObject *) op; - } - i = 0; - if (i < size) { - memcpy(op->ob_sval, a->ob_sval, Py_SIZE(a)); - i = Py_SIZE(a); - } - while (i < size) { - j = (i <= size-i) ? i : size-i; - memcpy(op->ob_sval+i, op->ob_sval, j); - i += j; - } + + _PyBytes_Repeat(op->ob_sval, size, a->ob_sval, Py_SIZE(a)); + return (PyObject *) op; } @@ -1502,7 +1490,7 @@ bytes_item(PyBytesObject *a, Py_ssize_t i) PyErr_SetString(PyExc_IndexError, "index out of range"); return NULL; } - return PyLong_FromLong((unsigned char)a->ob_sval[i]); + return _PyLong_FromUnsignedChar((unsigned char)a->ob_sval[i]); } static int @@ -1586,11 +1574,14 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op) static Py_hash_t bytes_hash(PyBytesObject *a) { +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS if (a->ob_shash == -1) { /* Can't fail */ a->ob_shash = _Py_HashBytes(a->ob_sval, Py_SIZE(a)); } return a->ob_shash; +_Py_COMP_DIAG_POP } static PyObject* @@ -1607,7 +1598,7 @@ bytes_subscript(PyBytesObject* self, PyObject* item) "index out of range"); return NULL; } - return PyLong_FromLong((unsigned char)self->ob_sval[i]); + return _PyLong_FromUnsignedChar((unsigned char)self->ob_sval[i]); } else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength, i; @@ -1628,8 +1619,7 @@ bytes_subscript(PyBytesObject* self, PyObject* item) else if (start == 0 && step == 1 && slicelength == PyBytes_GET_SIZE(self) && PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else if (step == 1) { return PyBytes_FromStringAndSize( @@ -1699,8 +1689,7 @@ bytes___bytes___impl(PyBytesObject *self) /*[clinic end generated code: output=63a306a9bc0caac5 input=34ec5ddba98bd6bb]*/ { if (PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else { return PyBytes_FromStringAndSize(self->ob_sval, Py_SIZE(self)); @@ -1925,8 +1914,7 @@ do_xstrip(PyBytesObject *self, int striptype, PyObject *sepobj) PyBuffer_Release(&vsep); if (i == 0 && j == len && PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject*)self; + return Py_NewRef(self); } else return PyBytes_FromStringAndSize(s+i, j-i); @@ -1955,8 +1943,7 @@ do_strip(PyBytesObject *self, int striptype) } if (i == 0 && j == len && PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject*)self; + return Py_NewRef(self); } else return PyBytes_FromStringAndSize(s+i, j-i); @@ -2124,9 +2111,7 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table, changed = 1; } if (!changed && PyBytes_CheckExact(input_obj)) { - Py_INCREF(input_obj); - Py_DECREF(result); - result = input_obj; + Py_SETREF(result, Py_NewRef(input_obj)); } PyBuffer_Release(&del_table_view); PyBuffer_Release(&table_view); @@ -2155,8 +2140,7 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table, } if (!changed && PyBytes_CheckExact(input_obj)) { Py_DECREF(result); - Py_INCREF(input_obj); - return input_obj; + return Py_NewRef(input_obj); } /* Fix the size of the resulting byte string */ if (inlen > 0) @@ -2248,8 +2232,7 @@ bytes_removeprefix_impl(PyBytesObject *self, Py_buffer *prefix) } if (PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } return PyBytes_FromStringAndSize(self_start, self_len); @@ -2287,8 +2270,7 @@ bytes_removesuffix_impl(PyBytesObject *self, Py_buffer *suffix) } if (PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } return PyBytes_FromStringAndSize(self_start, self_len); @@ -2334,7 +2316,7 @@ bytes_decode_impl(PyBytesObject *self, const char *encoding, /*[clinic input] bytes.splitlines - keepends: bool(accept={int}) = False + keepends: bool = False Return a list of the lines in the bytes, breaking at line boundaries. @@ -2344,7 +2326,7 @@ true. static PyObject * bytes_splitlines_impl(PyBytesObject *self, int keepends) -/*[clinic end generated code: output=3484149a5d880ffb input=a8b32eb01ff5a5ed]*/ +/*[clinic end generated code: output=3484149a5d880ffb input=5d7b898af2fe55c0]*/ { return stringlib_splitlines( (PyObject*) self, PyBytes_AS_STRING(self), @@ -2395,7 +2377,7 @@ _PyBytes_FromHex(PyObject *string, int use_bytearray) if (!PyUnicode_IS_ASCII(string)) { const void *data = PyUnicode_DATA(string); - unsigned int kind = PyUnicode_KIND(string); + int kind = PyUnicode_KIND(string); Py_ssize_t i; /* search for the first non-ASCII character */ @@ -2623,7 +2605,7 @@ bytes_new_impl(PyTypeObject *type, PyObject *x, const char *encoding, /* We'd like to call PyObject_Bytes here, but we need to check for an integer argument before deferring to PyBytes_FromObject, something PyObject_Bytes doesn't do. */ - else if ((func = _PyObject_LookupSpecial(x, &PyId___bytes__)) != NULL) { + else if ((func = _PyObject_LookupSpecial(x, &_Py_ID(__bytes__))) != NULL) { bytes = _PyObject_CallNoArgs(func); Py_DECREF(func); if (bytes == NULL) @@ -2847,8 +2829,7 @@ PyBytes_FromObject(PyObject *x) } if (PyBytes_CheckExact(x)) { - Py_INCREF(x); - return x; + return Py_NewRef(x); } /* Use the modern buffer interface */ @@ -2879,6 +2860,25 @@ PyBytes_FromObject(PyObject *x) return NULL; } +/* This allocator is needed for subclasses don't want to use __new__. + * See https://github.com/python/cpython/issues/91020#issuecomment-1096793239 + * + * This allocator will be removed when ob_shash is removed. + */ +static PyObject * +bytes_alloc(PyTypeObject *self, Py_ssize_t nitems) +{ + PyBytesObject *obj = (PyBytesObject*)PyType_GenericAlloc(self, nitems); + if (obj == NULL) { + return NULL; + } +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS + obj->ob_shash = -1; +_Py_COMP_DIAG_POP + return (PyObject*)obj; +} + static PyObject * bytes_subtype_new(PyTypeObject *type, PyObject *tmp) { @@ -2892,8 +2892,11 @@ bytes_subtype_new(PyTypeObject *type, PyObject *tmp) if (pnew != NULL) { memcpy(PyBytes_AS_STRING(pnew), PyBytes_AS_STRING(tmp), n+1); +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS ((PyBytesObject *)pnew)->ob_shash = ((PyBytesObject *)tmp)->ob_shash; +_Py_COMP_DIAG_POP } return pnew; } @@ -2946,13 +2949,13 @@ PyTypeObject PyBytes_Type = { bytes_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ - &PyBaseObject_Type, /* tp_base */ + 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ - 0, /* tp_alloc */ + bytes_alloc, /* tp_alloc */ bytes_new, /* tp_new */ PyObject_Del, /* tp_free */ }; @@ -3075,7 +3078,10 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) sv = (PyBytesObject *) *pv; Py_SET_SIZE(sv, newsize); sv->ob_sval[newsize] = '\0'; +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS sv->ob_shash = -1; /* invalidate cached hash value */ +_Py_COMP_DIAG_POP return 0; error: *pv = 0; @@ -3086,26 +3092,24 @@ error: PyStatus -_PyBytes_Init(PyInterpreterState *interp) +_PyBytes_InitTypes(PyInterpreterState *interp) { - struct _Py_bytes_state *state = &interp->bytes; - if (bytes_create_empty_string_singleton(state) < 0) { - return _PyStatus_NO_MEMORY(); + if (!_Py_IsMainInterpreter(interp)) { + return _PyStatus_OK(); } + + if (PyType_Ready(&PyBytes_Type) < 0) { + return _PyStatus_ERR("Can't initialize bytes type"); + } + + if (PyType_Ready(&PyBytesIter_Type) < 0) { + return _PyStatus_ERR("Can't initialize bytes iterator type"); + } + return _PyStatus_OK(); } -void -_PyBytes_Fini(PyInterpreterState *interp) -{ - struct _Py_bytes_state* state = &interp->bytes; - for (int i = 0; i < UCHAR_MAX + 1; i++) { - Py_CLEAR(state->characters[i]); - } - Py_CLEAR(state->empty_string); -} - /*********************** Bytes Iterator ****************************/ typedef struct { @@ -3141,7 +3145,7 @@ striter_next(striterobject *it) assert(PyBytes_Check(seq)); if (it->it_index < PyBytes_GET_SIZE(seq)) { - return PyLong_FromLong( + return _PyLong_FromUnsignedChar( (unsigned char)seq->ob_sval[it->it_index++]); } @@ -3165,12 +3169,11 @@ PyDoc_STRVAR(length_hint_doc, static PyObject * striter_reduce(striterobject *it, PyObject *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(iter); if (it->it_seq != NULL) { - return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter), + return Py_BuildValue("N(O)n", _PyEval_GetBuiltin(&_Py_ID(iter)), it->it_seq, it->it_index); } else { - return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter)); + return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter))); } } @@ -3250,8 +3253,7 @@ bytes_iter(PyObject *seq) if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyBytesObject *)seq; + it->it_seq = (PyBytesObject *)Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } @@ -3466,7 +3468,7 @@ _PyBytesWriter_Alloc(_PyBytesWriter *writer, Py_ssize_t size) Don't modify the _PyBytesWriter structure (use a shorter small buffer) in debug mode to also be able to detect stack overflow when running tests in debug mode. The _PyBytesWriter is large (more than 512 bytes), - if Py_EnterRecursiveCall() is not used in deep C callback, we may hit a + if _Py_EnterRecursiveCall() is not used in deep C callback, we may hit a stack overflow. */ writer->allocated = Py_MIN(writer->allocated, 10); /* _PyBytesWriter_CheckConsistency() requires the last byte to be 0, @@ -3537,3 +3539,28 @@ _PyBytesWriter_WriteBytes(_PyBytesWriter *writer, void *ptr, return str; } + + +void +_PyBytes_Repeat(char* dest, Py_ssize_t len_dest, + const char* src, Py_ssize_t len_src) +{ + if (len_dest == 0) { + return; + } + if (len_src == 1) { + memset(dest, src[0], len_dest); + } + else { + if (src != dest) { + memcpy(dest, src, len_src); + } + Py_ssize_t copied = len_src; + while (copied < len_dest) { + Py_ssize_t bytes_to_copy = Py_MIN(copied, len_dest - copied); + memcpy(dest + copied, dest, bytes_to_copy); + copied += bytes_to_copy; + } + } +} + diff --git a/Objects/call.c b/Objects/call.c index 5e55518b04c..bd027e41f8a 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -1,11 +1,11 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgsTstate() -#include "pycore_ceval.h" // _PyEval_EvalFrame() -#include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() +#include "pycore_dict.h" // _PyDict_FromItems() +#include "pycore_object.h" // _PyCFunctionWithKeywords_TrampolineCall() #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_tuple.h" // _PyTuple_ITEMS() -#include "frameobject.h" // _PyFrame_New_NoTrack() static PyObject *const * @@ -109,7 +109,9 @@ _Py_CheckSlotResult(PyObject *obj, const char *slot_name, int success) PyObject * PyObject_CallNoArgs(PyObject *func) { - return _PyObject_CallNoArgs(func); + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); + PyThreadState *tstate = _PyThreadState_GET(); + return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); } @@ -209,10 +211,11 @@ _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable, } PyObject *result = NULL; - if (_Py_EnterRecursiveCall(tstate, " while calling a Python object") == 0) + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object") == 0) { - result = call(callable, argstuple, kwdict); - _Py_LeaveRecursiveCall(tstate); + result = _PyCFunctionWithKeywords_TrampolineCall( + (PyCFunctionWithKeywords)call, callable, argstuple, kwdict); + _Py_LeaveRecursiveCallTstate(tstate); } Py_DECREF(argstuple); @@ -321,7 +324,7 @@ _PyObject_Call(PyThreadState *tstate, PyObject *callable, assert(!_PyErr_Occurred(tstate)); assert(PyTuple_Check(args)); assert(kwargs == NULL || PyDict_Check(kwargs)); - + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, callable); vectorcallfunc vector_func = _PyVectorcall_Function(callable); if (vector_func != NULL) { return _PyVectorcall_Call(tstate, vector_func, callable, args, kwargs); @@ -335,13 +338,13 @@ _PyObject_Call(PyThreadState *tstate, PyObject *callable, return NULL; } - if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) { + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { return NULL; } result = (*call)(callable, args, kwargs); - _Py_LeaveRecursiveCall(tstate); + _Py_LeaveRecursiveCallTstate(tstate); return _Py_CheckFunctionResult(tstate, callable, result, NULL); } @@ -366,6 +369,7 @@ PyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs) PyObject * PyObject_CallOneArg(PyObject *func, PyObject *arg) { + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); assert(arg != NULL); PyObject *_args[2]; PyObject **args = _args + 1; // For PY_VECTORCALL_ARGUMENTS_OFFSET @@ -383,16 +387,17 @@ _PyFunction_Vectorcall(PyObject *func, PyObject* const* stack, size_t nargsf, PyObject *kwnames) { assert(PyFunction_Check(func)); - PyFrameConstructor *f = PyFunction_AS_FRAME_CONSTRUCTOR(func); + PyFunctionObject *f = (PyFunctionObject *)func; Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); assert(nargs >= 0); PyThreadState *tstate = _PyThreadState_GET(); assert(nargs == 0 || stack != NULL); - if (((PyCodeObject *)f->fc_code)->co_flags & CO_OPTIMIZED) { + EVAL_CALL_STAT_INC(EVAL_CALL_FUNCTION_VECTORCALL); + if (((PyCodeObject *)f->func_code)->co_flags & CO_OPTIMIZED) { return _PyEval_Vector(tstate, f, NULL, stack, nargs, kwnames); } else { - return _PyEval_Vector(tstate, f, f->fc_globals, stack, nargs, kwnames); + return _PyEval_Vector(tstate, f, f->func_globals, stack, nargs, kwnames); } } @@ -519,7 +524,7 @@ _PyObject_CallFunctionVa(PyThreadState *tstate, PyObject *callable, if (stack == NULL) { return NULL; } - + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, callable); if (nargs == 1 && PyTuple_Check(stack[0])) { /* Special cases for backward compatibility: - PyObject_CallFunction(func, "O", tuple) calls func(*tuple) @@ -607,7 +612,6 @@ callmethod(PyThreadState *tstate, PyObject* callable, const char *format, va_lis return _PyObject_CallFunctionVa(tstate, callable, format, va, is_size_t); } - PyObject * PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...) { @@ -658,6 +662,30 @@ PyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...) } +PyObject * +_PyObject_CallMethod(PyObject *obj, PyObject *name, + const char *format, ...) +{ + PyThreadState *tstate = _PyThreadState_GET(); + if (obj == NULL || name == NULL) { + return null_error(tstate); + } + + PyObject *callable = PyObject_GetAttr(obj, name); + if (callable == NULL) { + return NULL; + } + + va_list va; + va_start(va, format); + PyObject *retval = callmethod(tstate, callable, format, va, 1); + va_end(va); + + Py_DECREF(callable); + return retval; +} + + PyObject * _PyObject_CallMethodId(PyObject *obj, _Py_Identifier *name, const char *format, ...) @@ -682,6 +710,17 @@ _PyObject_CallMethodId(PyObject *obj, _Py_Identifier *name, } +PyObject * _PyObject_CallMethodFormat(PyThreadState *tstate, PyObject *callable, + const char *format, ...) +{ + va_list va; + va_start(va, format); + PyObject *retval = callmethod(tstate, callable, format, va, 0); + va_end(va); + return retval; +} + + PyObject * _PyObject_CallMethod_SizeT(PyObject *obj, const char *name, const char *format, ...) @@ -780,6 +819,11 @@ object_vacall(PyThreadState *tstate, PyObject *base, stack[i] = va_arg(vargs, PyObject *); } +#ifdef Py_STATS + if (PyFunction_Check(callable)) { + EVAL_CALL_STAT_INC(EVAL_CALL_API); + } +#endif /* Call the function */ result = _PyObject_VectorcallTstate(tstate, callable, stack, nargs, NULL); @@ -817,6 +861,7 @@ PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, args++; nargsf--; } + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_METHOD, callable); PyObject *result = _PyObject_VectorcallTstate(tstate, callable, args, nargsf, kwnames); Py_DECREF(callable); @@ -850,8 +895,7 @@ PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...) PyObject * -_PyObject_CallMethodIdObjArgs(PyObject *obj, - struct _Py_Identifier *name, ...) +_PyObject_CallMethodIdObjArgs(PyObject *obj, _Py_Identifier *name, ...) { PyThreadState *tstate = _PyThreadState_GET(); if (obj == NULL || name == NULL) { @@ -901,26 +945,11 @@ PyObject * _PyStack_AsDict(PyObject *const *values, PyObject *kwnames) { Py_ssize_t nkwargs; - PyObject *kwdict; - Py_ssize_t i; assert(kwnames != NULL); nkwargs = PyTuple_GET_SIZE(kwnames); - kwdict = _PyDict_NewPresized(nkwargs); - if (kwdict == NULL) { - return NULL; - } - - for (i = 0; i < nkwargs; i++) { - PyObject *key = PyTuple_GET_ITEM(kwnames, i); - PyObject *value = *values++; - /* If key already exists, replace it with the new value */ - if (PyDict_SetItem(kwdict, key, value)) { - Py_DECREF(kwdict); - return NULL; - } - } - return kwdict; + return _PyDict_FromItems(&PyTuple_GET_ITEM(kwnames, 0), 1, + values, 1, nkwargs); } @@ -972,8 +1001,7 @@ _PyStack_UnpackDict(PyThreadState *tstate, /* Copy positional arguments */ for (Py_ssize_t i = 0; i < nargs; i++) { - Py_INCREF(args[i]); - stack[i] = args[i]; + stack[i] = Py_NewRef(args[i]); } PyObject **kwstack = stack + nargs; @@ -985,10 +1013,8 @@ _PyStack_UnpackDict(PyThreadState *tstate, unsigned long keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; while (PyDict_Next(kwargs, &pos, &key, &value)) { keys_are_strings &= Py_TYPE(key)->tp_flags; - Py_INCREF(key); - Py_INCREF(value); - PyTuple_SET_ITEM(kwnames, i, key); - kwstack[i] = value; + PyTuple_SET_ITEM(kwnames, i, Py_NewRef(key)); + kwstack[i] = Py_NewRef(value); i++; } @@ -1019,3 +1045,11 @@ _PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, PyMem_Free((PyObject **)stack - 1); Py_DECREF(kwnames); } + +// Export for the stable ABI +#undef PyVectorcall_NARGS +Py_ssize_t +PyVectorcall_NARGS(size_t n) +{ + return _PyVectorcall_NARGS(n); +} diff --git a/Objects/capsule.c b/Objects/capsule.c index 800a6c4b25c..baaddb3f1f0 100644 --- a/Objects/capsule.c +++ b/Objects/capsule.c @@ -214,18 +214,13 @@ PyCapsule_Import(const char *name, int no_block) } if (object == NULL) { - if (no_block) { - object = PyImport_ImportModuleNoBlock(trace); - } else { - object = PyImport_ImportModule(trace); - if (!object) { - PyErr_Format(PyExc_ImportError, "PyCapsule_Import could not import module \"%s\"", trace); - } + object = PyImport_ImportModule(trace); + if (!object) { + PyErr_Format(PyExc_ImportError, "PyCapsule_Import could not import module \"%s\"", trace); } } else { PyObject *object2 = PyObject_GetAttrString(object, trace); - Py_DECREF(object); - object = object2; + Py_SETREF(object, object2); } if (!object) { goto EXIT; diff --git a/Objects/cellobject.c b/Objects/cellobject.c index 86a89f02e60..f516707f6f8 100644 --- a/Objects/cellobject.c +++ b/Objects/cellobject.c @@ -11,8 +11,7 @@ PyCell_New(PyObject *obj) op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type); if (op == NULL) return NULL; - op->ob_ref = obj; - Py_XINCREF(obj); + op->ob_ref = Py_XNewRef(obj); _PyObject_GC_TRACK(op); return (PyObject *)op; @@ -56,22 +55,20 @@ PyCell_Get(PyObject *op) PyErr_BadInternalCall(); return NULL; } - Py_XINCREF(((PyCellObject*)op)->ob_ref); - return PyCell_GET(op); + PyObject *value = PyCell_GET(op); + return Py_XNewRef(value); } int -PyCell_Set(PyObject *op, PyObject *obj) +PyCell_Set(PyObject *op, PyObject *value) { - PyObject* oldobj; if (!PyCell_Check(op)) { PyErr_BadInternalCall(); return -1; } - oldobj = PyCell_GET(op); - Py_XINCREF(obj); - PyCell_SET(op, obj); - Py_XDECREF(oldobj); + PyObject *old_value = PyCell_GET(op); + PyCell_SET(op, Py_XNewRef(value)); + Py_XDECREF(old_value); return 0; } @@ -136,15 +133,13 @@ cell_get_contents(PyCellObject *op, void *closure) PyErr_SetString(PyExc_ValueError, "Cell is empty"); return NULL; } - Py_INCREF(op->ob_ref); - return op->ob_ref; + return Py_NewRef(op->ob_ref); } static int cell_set_contents(PyCellObject *op, PyObject *obj, void *Py_UNUSED(ignored)) { - Py_XINCREF(obj); - Py_XSETREF(op->ob_ref, obj); + Py_XSETREF(op->ob_ref, Py_XNewRef(obj)); return 0; } diff --git a/Objects/classobject.c b/Objects/classobject.c index 9d4fc99f1f8..2cb192e725d 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -7,10 +7,15 @@ #include "pycore_pystate.h" // _PyThreadState_GET() #include "structmember.h" // PyMemberDef +#include "clinic/classobject.c.h" + #define TP_DESCR_GET(t) ((t)->tp_descr_get) -_Py_IDENTIFIER(__name__); -_Py_IDENTIFIER(__qualname__); +/*[clinic input] +class method "PyMethodObject *" "&PyMethod_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b16e47edf6107c23]*/ + PyObject * PyMethod_Function(PyObject *im) @@ -108,33 +113,33 @@ PyMethod_New(PyObject *func, PyObject *self) return NULL; } im->im_weakreflist = NULL; - Py_INCREF(func); - im->im_func = func; - Py_INCREF(self); - im->im_self = self; + im->im_func = Py_NewRef(func); + im->im_self = Py_NewRef(self); im->vectorcall = method_vectorcall; _PyObject_GC_TRACK(im); return (PyObject *)im; } -static PyObject * -method_reduce(PyMethodObject *im, PyObject *Py_UNUSED(ignored)) -{ - PyObject *self = PyMethod_GET_SELF(im); - PyObject *func = PyMethod_GET_FUNCTION(im); - PyObject *funcname; - _Py_IDENTIFIER(getattr); +/*[clinic input] +method.__reduce__ +[clinic start generated code]*/ - funcname = _PyObject_GetAttrId(func, &PyId___name__); +static PyObject * +method___reduce___impl(PyMethodObject *self) +/*[clinic end generated code: output=6c04506d0fa6fdcb input=143a0bf5e96de6e8]*/ +{ + PyObject *funcself = PyMethod_GET_SELF(self); + PyObject *func = PyMethod_GET_FUNCTION(self); + PyObject *funcname = PyObject_GetAttr(func, &_Py_ID(__name__)); if (funcname == NULL) { return NULL; } - return Py_BuildValue("N(ON)", _PyEval_GetBuiltinId(&PyId_getattr), - self, funcname); + return Py_BuildValue( + "N(ON)", _PyEval_GetBuiltin(&_Py_ID(getattr)), funcself, funcname); } static PyMethodDef method_methods[] = { - {"__reduce__", (PyCFunction)method_reduce, METH_NOARGS, NULL}, + METHOD___REDUCE___METHODDEF {NULL, NULL} }; @@ -160,13 +165,7 @@ static PyMemberDef method_memberlist[] = { static PyObject * method_get_doc(PyMethodObject *im, void *context) { - static PyObject *docstr; - if (docstr == NULL) { - docstr= PyUnicode_InternFromString("__doc__"); - if (docstr == NULL) - return NULL; - } - return PyObject_GetAttr(im->im_func, docstr); + return PyObject_GetAttr(im->im_func, &_Py_ID(__doc__)); } static PyGetSetDef method_getset[] = { @@ -194,42 +193,39 @@ method_getattro(PyObject *obj, PyObject *name) if (f != NULL) return f(descr, obj, (PyObject *)Py_TYPE(obj)); else { - Py_INCREF(descr); - return descr; + return Py_NewRef(descr); } } return PyObject_GetAttr(im->im_func, name); } -PyDoc_STRVAR(method_doc, -"method(function, instance)\n\ -\n\ -Create a bound instance method object."); +/*[clinic input] +@classmethod +method.__new__ as method_new + function: object + instance: object + / + +Create a bound instance method object. +[clinic start generated code]*/ static PyObject * -method_new(PyTypeObject* type, PyObject* args, PyObject *kw) +method_new_impl(PyTypeObject *type, PyObject *function, PyObject *instance) +/*[clinic end generated code: output=d33ef4ebf702e1f7 input=4e32facc3c3108ae]*/ { - PyObject *func; - PyObject *self; - - if (!_PyArg_NoKeywords("method", kw)) - return NULL; - if (!PyArg_UnpackTuple(args, "method", 2, 2, - &func, &self)) - return NULL; - if (!PyCallable_Check(func)) { + if (!PyCallable_Check(function)) { PyErr_SetString(PyExc_TypeError, "first argument must be callable"); return NULL; } - if (self == NULL || self == Py_None) { + if (instance == NULL || instance == Py_None) { PyErr_SetString(PyExc_TypeError, - "self must not be None"); + "instance must not be None"); return NULL; } - return PyMethod_New(func, self); + return PyMethod_New(function, instance); } static void @@ -268,8 +264,7 @@ method_richcompare(PyObject *self, PyObject *other, int op) res = eq ? Py_True : Py_False; else res = eq ? Py_False : Py_True; - Py_INCREF(res); - return res; + return Py_NewRef(res); } static PyObject * @@ -280,16 +275,15 @@ method_repr(PyMethodObject *a) PyObject *funcname, *result; const char *defname = "?"; - if (_PyObject_LookupAttrId(func, &PyId___qualname__, &funcname) < 0 || + if (_PyObject_LookupAttr(func, &_Py_ID(__qualname__), &funcname) < 0 || (funcname == NULL && - _PyObject_LookupAttrId(func, &PyId___name__, &funcname) < 0)) + _PyObject_LookupAttr(func, &_Py_ID(__name__), &funcname) < 0)) { return NULL; } if (funcname != NULL && !PyUnicode_Check(funcname)) { - Py_DECREF(funcname); - funcname = NULL; + Py_SETREF(funcname, NULL); } /* XXX Shouldn't use repr()/%R here! */ @@ -322,67 +316,45 @@ method_traverse(PyMethodObject *im, visitproc visit, void *arg) return 0; } -static PyObject * -method_descr_get(PyObject *meth, PyObject *obj, PyObject *cls) -{ - Py_INCREF(meth); - return meth; -} - PyTypeObject PyMethod_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "method", - sizeof(PyMethodObject), - 0, - (destructor)method_dealloc, /* tp_dealloc */ - offsetof(PyMethodObject, vectorcall), /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)method_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)method_hash, /* tp_hash */ - PyVectorcall_Call, /* tp_call */ - 0, /* tp_str */ - method_getattro, /* tp_getattro */ - PyObject_GenericSetAttr, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ - method_doc, /* tp_doc */ - (traverseproc)method_traverse, /* tp_traverse */ - 0, /* tp_clear */ - method_richcompare, /* tp_richcompare */ - offsetof(PyMethodObject, im_weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - method_methods, /* tp_methods */ - method_memberlist, /* tp_members */ - method_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - method_descr_get, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - method_new, /* tp_new */ + .tp_name = "method", + .tp_basicsize = sizeof(PyMethodObject), + .tp_dealloc = (destructor)method_dealloc, + .tp_vectorcall_offset = offsetof(PyMethodObject, vectorcall), + .tp_repr = (reprfunc)method_repr, + .tp_hash = (hashfunc)method_hash, + .tp_call = PyVectorcall_Call, + .tp_getattro = method_getattro, + .tp_setattro = PyObject_GenericSetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_HAVE_VECTORCALL, + .tp_doc = method_new__doc__, + .tp_traverse = (traverseproc)method_traverse, + .tp_richcompare = method_richcompare, + .tp_weaklistoffset = offsetof(PyMethodObject, im_weakreflist), + .tp_methods = method_methods, + .tp_members = method_memberlist, + .tp_getset = method_getset, + .tp_new = method_new, }; /* ------------------------------------------------------------------------ * instance method */ +/*[clinic input] +class instancemethod "PyInstanceMethodObject *" "&PyInstanceMethod_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=28c9762a9016f4d2]*/ + PyObject * PyInstanceMethod_New(PyObject *func) { PyInstanceMethodObject *method; method = PyObject_GC_New(PyInstanceMethodObject, &PyInstanceMethod_Type); if (method == NULL) return NULL; - Py_INCREF(func); - method->func = func; + method->func = Py_NewRef(func); _PyObject_GC_TRACK(method); return (PyObject *)method; } @@ -408,13 +380,8 @@ static PyMemberDef instancemethod_memberlist[] = { static PyObject * instancemethod_get_doc(PyObject *self, void *context) { - static PyObject *docstr; - if (docstr == NULL) { - docstr = PyUnicode_InternFromString("__doc__"); - if (docstr == NULL) - return NULL; - } - return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), docstr); + return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), + &_Py_ID(__doc__)); } static PyGetSetDef instancemethod_getset[] = { @@ -439,8 +406,7 @@ instancemethod_getattro(PyObject *self, PyObject *name) if (f != NULL) return f(descr, self, (PyObject *)Py_TYPE(self)); else { - Py_INCREF(descr); - return descr; + return Py_NewRef(descr); } } @@ -470,8 +436,7 @@ static PyObject * instancemethod_descr_get(PyObject *descr, PyObject *obj, PyObject *type) { PyObject *func = PyInstanceMethod_GET_FUNCTION(descr); if (obj == NULL) { - Py_INCREF(func); - return func; + return Py_NewRef(func); } else return PyMethod_New(func, obj); @@ -499,8 +464,7 @@ instancemethod_richcompare(PyObject *self, PyObject *other, int op) res = eq ? Py_True : Py_False; else res = eq ? Py_False : Py_True; - Py_INCREF(res); - return res; + return Py_NewRef(res); } static PyObject * @@ -515,12 +479,11 @@ instancemethod_repr(PyObject *self) return NULL; } - if (_PyObject_LookupAttrId(func, &PyId___name__, &funcname) < 0) { + if (_PyObject_LookupAttr(func, &_Py_ID(__name__), &funcname) < 0) { return NULL; } if (funcname != NULL && !PyUnicode_Check(funcname)) { - Py_DECREF(funcname); - funcname = NULL; + Py_SETREF(funcname, NULL); } result = PyUnicode_FromFormat("", @@ -530,83 +493,43 @@ instancemethod_repr(PyObject *self) return result; } -/* -static long -instancemethod_hash(PyObject *self) -{ - long x, y; - x = (long)self; - y = PyObject_Hash(PyInstanceMethod_GET_FUNCTION(self)); - if (y == -1) - return -1; - x = x ^ y; - if (x == -1) - x = -2; - return x; -} -*/ +/*[clinic input] +@classmethod +instancemethod.__new__ as instancemethod_new + function: object + / -PyDoc_STRVAR(instancemethod_doc, -"instancemethod(function)\n\ -\n\ -Bind a function to a class."); +Bind a function to a class. +[clinic start generated code]*/ static PyObject * -instancemethod_new(PyTypeObject* type, PyObject* args, PyObject *kw) +instancemethod_new_impl(PyTypeObject *type, PyObject *function) +/*[clinic end generated code: output=5e0397b2bdb750be input=cfc54e8b973664a8]*/ { - PyObject *func; - - if (!_PyArg_NoKeywords("instancemethod", kw)) - return NULL; - if (!PyArg_UnpackTuple(args, "instancemethod", 1, 1, &func)) - return NULL; - if (!PyCallable_Check(func)) { + if (!PyCallable_Check(function)) { PyErr_SetString(PyExc_TypeError, "first argument must be callable"); return NULL; } - return PyInstanceMethod_New(func); + return PyInstanceMethod_New(function); } PyTypeObject PyInstanceMethod_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "instancemethod", /* tp_name */ - sizeof(PyInstanceMethodObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - instancemethod_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)instancemethod_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /*(hashfunc)instancemethod_hash, tp_hash */ - instancemethod_call, /* tp_call */ - 0, /* tp_str */ - instancemethod_getattro, /* tp_getattro */ - PyObject_GenericSetAttr, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT - | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - instancemethod_doc, /* tp_doc */ - instancemethod_traverse, /* tp_traverse */ - 0, /* tp_clear */ - instancemethod_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - instancemethod_memberlist, /* tp_members */ - instancemethod_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - instancemethod_descr_get, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - instancemethod_new, /* tp_new */ + .tp_name = "instancemethod", + .tp_basicsize = sizeof(PyInstanceMethodObject), + .tp_dealloc = instancemethod_dealloc, + .tp_repr = (reprfunc)instancemethod_repr, + .tp_call = instancemethod_call, + .tp_getattro = instancemethod_getattro, + .tp_setattro = PyObject_GenericSetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_doc = instancemethod_new__doc__, + .tp_traverse = instancemethod_traverse, + .tp_richcompare = instancemethod_richcompare, + .tp_members = instancemethod_memberlist, + .tp_getset = instancemethod_getset, + .tp_descr_get = instancemethod_descr_get, + .tp_new = instancemethod_new, }; diff --git a/Objects/clinic/bytearrayobject.c.h b/Objects/clinic/bytearrayobject.c.h index 1e3f1975615..e7bf3183af8 100644 --- a/Objects/clinic/bytearrayobject.c.h +++ b/Objects/clinic/bytearrayobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static int bytearray___init___impl(PyByteArrayObject *self, PyObject *arg, const char *encoding, const char *errors); @@ -10,8 +16,31 @@ static int bytearray___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(source), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"source", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "bytearray", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "bytearray", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -200,7 +229,7 @@ PyDoc_STRVAR(bytearray_translate__doc__, "The remaining characters are mapped through the given translation table."); #define BYTEARRAY_TRANSLATE_METHODDEF \ - {"translate", (PyCFunction)(void(*)(void))bytearray_translate, METH_FASTCALL|METH_KEYWORDS, bytearray_translate__doc__}, + {"translate", _PyCFunction_CAST(bytearray_translate), METH_FASTCALL|METH_KEYWORDS, bytearray_translate__doc__}, static PyObject * bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, @@ -210,8 +239,31 @@ static PyObject * bytearray_translate(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(delete), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "delete", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "translate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "translate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *table; @@ -245,7 +297,7 @@ PyDoc_STRVAR(bytearray_maketrans__doc__, "The bytes objects frm and to must be of the same length."); #define BYTEARRAY_MAKETRANS_METHODDEF \ - {"maketrans", (PyCFunction)(void(*)(void))bytearray_maketrans, METH_FASTCALL|METH_STATIC, bytearray_maketrans__doc__}, + {"maketrans", _PyCFunction_CAST(bytearray_maketrans), METH_FASTCALL|METH_STATIC, bytearray_maketrans__doc__}, static PyObject * bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to); @@ -303,7 +355,7 @@ PyDoc_STRVAR(bytearray_replace__doc__, "replaced."); #define BYTEARRAY_REPLACE_METHODDEF \ - {"replace", (PyCFunction)(void(*)(void))bytearray_replace, METH_FASTCALL, bytearray_replace__doc__}, + {"replace", _PyCFunction_CAST(bytearray_replace), METH_FASTCALL, bytearray_replace__doc__}, static PyObject * bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old, @@ -380,7 +432,7 @@ PyDoc_STRVAR(bytearray_split__doc__, " -1 (the default value) means no limit."); #define BYTEARRAY_SPLIT_METHODDEF \ - {"split", (PyCFunction)(void(*)(void))bytearray_split, METH_FASTCALL|METH_KEYWORDS, bytearray_split__doc__}, + {"split", _PyCFunction_CAST(bytearray_split), METH_FASTCALL|METH_KEYWORDS, bytearray_split__doc__}, static PyObject * bytearray_split_impl(PyByteArrayObject *self, PyObject *sep, @@ -390,8 +442,31 @@ static PyObject * bytearray_split(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "split", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -479,7 +554,7 @@ PyDoc_STRVAR(bytearray_rsplit__doc__, "Splitting is done starting at the end of the bytearray and working to the front."); #define BYTEARRAY_RSPLIT_METHODDEF \ - {"rsplit", (PyCFunction)(void(*)(void))bytearray_rsplit, METH_FASTCALL|METH_KEYWORDS, bytearray_rsplit__doc__}, + {"rsplit", _PyCFunction_CAST(bytearray_rsplit), METH_FASTCALL|METH_KEYWORDS, bytearray_rsplit__doc__}, static PyObject * bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep, @@ -489,8 +564,31 @@ static PyObject * bytearray_rsplit(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rsplit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rsplit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -558,7 +656,7 @@ PyDoc_STRVAR(bytearray_insert__doc__, " The item to be inserted."); #define BYTEARRAY_INSERT_METHODDEF \ - {"insert", (PyCFunction)(void(*)(void))bytearray_insert, METH_FASTCALL, bytearray_insert__doc__}, + {"insert", _PyCFunction_CAST(bytearray_insert), METH_FASTCALL, bytearray_insert__doc__}, static PyObject * bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item); @@ -649,7 +747,7 @@ PyDoc_STRVAR(bytearray_pop__doc__, "If no index argument is given, will pop the last item."); #define BYTEARRAY_POP_METHODDEF \ - {"pop", (PyCFunction)(void(*)(void))bytearray_pop, METH_FASTCALL, bytearray_pop__doc__}, + {"pop", _PyCFunction_CAST(bytearray_pop), METH_FASTCALL, bytearray_pop__doc__}, static PyObject * bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index); @@ -724,7 +822,7 @@ PyDoc_STRVAR(bytearray_strip__doc__, "If the argument is omitted or None, strip leading and trailing ASCII whitespace."); #define BYTEARRAY_STRIP_METHODDEF \ - {"strip", (PyCFunction)(void(*)(void))bytearray_strip, METH_FASTCALL, bytearray_strip__doc__}, + {"strip", _PyCFunction_CAST(bytearray_strip), METH_FASTCALL, bytearray_strip__doc__}, static PyObject * bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes); @@ -758,7 +856,7 @@ PyDoc_STRVAR(bytearray_lstrip__doc__, "If the argument is omitted or None, strip leading ASCII whitespace."); #define BYTEARRAY_LSTRIP_METHODDEF \ - {"lstrip", (PyCFunction)(void(*)(void))bytearray_lstrip, METH_FASTCALL, bytearray_lstrip__doc__}, + {"lstrip", _PyCFunction_CAST(bytearray_lstrip), METH_FASTCALL, bytearray_lstrip__doc__}, static PyObject * bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes); @@ -792,7 +890,7 @@ PyDoc_STRVAR(bytearray_rstrip__doc__, "If the argument is omitted or None, strip trailing ASCII whitespace."); #define BYTEARRAY_RSTRIP_METHODDEF \ - {"rstrip", (PyCFunction)(void(*)(void))bytearray_rstrip, METH_FASTCALL, bytearray_rstrip__doc__}, + {"rstrip", _PyCFunction_CAST(bytearray_rstrip), METH_FASTCALL, bytearray_rstrip__doc__}, static PyObject * bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes); @@ -833,7 +931,7 @@ PyDoc_STRVAR(bytearray_decode__doc__, " can handle UnicodeDecodeErrors."); #define BYTEARRAY_DECODE_METHODDEF \ - {"decode", (PyCFunction)(void(*)(void))bytearray_decode, METH_FASTCALL|METH_KEYWORDS, bytearray_decode__doc__}, + {"decode", _PyCFunction_CAST(bytearray_decode), METH_FASTCALL|METH_KEYWORDS, bytearray_decode__doc__}, static PyObject * bytearray_decode_impl(PyByteArrayObject *self, const char *encoding, @@ -843,8 +941,31 @@ static PyObject * bytearray_decode(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *encoding = NULL; @@ -918,7 +1039,7 @@ PyDoc_STRVAR(bytearray_splitlines__doc__, "true."); #define BYTEARRAY_SPLITLINES_METHODDEF \ - {"splitlines", (PyCFunction)(void(*)(void))bytearray_splitlines, METH_FASTCALL|METH_KEYWORDS, bytearray_splitlines__doc__}, + {"splitlines", _PyCFunction_CAST(bytearray_splitlines), METH_FASTCALL|METH_KEYWORDS, bytearray_splitlines__doc__}, static PyObject * bytearray_splitlines_impl(PyByteArrayObject *self, int keepends); @@ -927,8 +1048,31 @@ static PyObject * bytearray_splitlines(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(keepends), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"keepends", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "splitlines", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "splitlines", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int keepends = 0; @@ -940,8 +1084,8 @@ bytearray_splitlines(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t if (!noptargs) { goto skip_optional_pos; } - keepends = _PyLong_AsInt(args[0]); - if (keepends == -1 && PyErr_Occurred()) { + keepends = PyObject_IsTrue(args[0]); + if (keepends < 0) { goto exit; } skip_optional_pos: @@ -1010,7 +1154,7 @@ PyDoc_STRVAR(bytearray_hex__doc__, "\'b901:ef\'"); #define BYTEARRAY_HEX_METHODDEF \ - {"hex", (PyCFunction)(void(*)(void))bytearray_hex, METH_FASTCALL|METH_KEYWORDS, bytearray_hex__doc__}, + {"hex", _PyCFunction_CAST(bytearray_hex), METH_FASTCALL|METH_KEYWORDS, bytearray_hex__doc__}, static PyObject * bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep, int bytes_per_sep); @@ -1019,8 +1163,31 @@ static PyObject * bytearray_hex(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = NULL; @@ -1075,7 +1242,7 @@ PyDoc_STRVAR(bytearray_reduce_ex__doc__, "Return state information for pickling."); #define BYTEARRAY_REDUCE_EX_METHODDEF \ - {"__reduce_ex__", (PyCFunction)(void(*)(void))bytearray_reduce_ex, METH_FASTCALL, bytearray_reduce_ex__doc__}, + {"__reduce_ex__", _PyCFunction_CAST(bytearray_reduce_ex), METH_FASTCALL, bytearray_reduce_ex__doc__}, static PyObject * bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto); @@ -1120,4 +1287,4 @@ bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) { return bytearray_sizeof_impl(self); } -/*[clinic end generated code: output=a82659f581e55629 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=022698e8b0faa272 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/bytesobject.c.h b/Objects/clinic/bytesobject.c.h index 103a3642813..060056dafbd 100644 --- a/Objects/clinic/bytesobject.c.h +++ b/Objects/clinic/bytesobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(bytes___bytes____doc__, "__bytes__($self, /)\n" "--\n" @@ -35,7 +41,7 @@ PyDoc_STRVAR(bytes_split__doc__, " -1 (the default value) means no limit."); #define BYTES_SPLIT_METHODDEF \ - {"split", (PyCFunction)(void(*)(void))bytes_split, METH_FASTCALL|METH_KEYWORDS, bytes_split__doc__}, + {"split", _PyCFunction_CAST(bytes_split), METH_FASTCALL|METH_KEYWORDS, bytes_split__doc__}, static PyObject * bytes_split_impl(PyBytesObject *self, PyObject *sep, Py_ssize_t maxsplit); @@ -44,8 +50,31 @@ static PyObject * bytes_split(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "split", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -186,7 +215,7 @@ PyDoc_STRVAR(bytes_rsplit__doc__, "Splitting is done starting at the end of the bytes and working to the front."); #define BYTES_RSPLIT_METHODDEF \ - {"rsplit", (PyCFunction)(void(*)(void))bytes_rsplit, METH_FASTCALL|METH_KEYWORDS, bytes_rsplit__doc__}, + {"rsplit", _PyCFunction_CAST(bytes_rsplit), METH_FASTCALL|METH_KEYWORDS, bytes_rsplit__doc__}, static PyObject * bytes_rsplit_impl(PyBytesObject *self, PyObject *sep, Py_ssize_t maxsplit); @@ -195,8 +224,31 @@ static PyObject * bytes_rsplit(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rsplit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rsplit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -258,7 +310,7 @@ PyDoc_STRVAR(bytes_strip__doc__, "If the argument is omitted or None, strip leading and trailing ASCII whitespace."); #define BYTES_STRIP_METHODDEF \ - {"strip", (PyCFunction)(void(*)(void))bytes_strip, METH_FASTCALL, bytes_strip__doc__}, + {"strip", _PyCFunction_CAST(bytes_strip), METH_FASTCALL, bytes_strip__doc__}, static PyObject * bytes_strip_impl(PyBytesObject *self, PyObject *bytes); @@ -292,7 +344,7 @@ PyDoc_STRVAR(bytes_lstrip__doc__, "If the argument is omitted or None, strip leading ASCII whitespace."); #define BYTES_LSTRIP_METHODDEF \ - {"lstrip", (PyCFunction)(void(*)(void))bytes_lstrip, METH_FASTCALL, bytes_lstrip__doc__}, + {"lstrip", _PyCFunction_CAST(bytes_lstrip), METH_FASTCALL, bytes_lstrip__doc__}, static PyObject * bytes_lstrip_impl(PyBytesObject *self, PyObject *bytes); @@ -326,7 +378,7 @@ PyDoc_STRVAR(bytes_rstrip__doc__, "If the argument is omitted or None, strip trailing ASCII whitespace."); #define BYTES_RSTRIP_METHODDEF \ - {"rstrip", (PyCFunction)(void(*)(void))bytes_rstrip, METH_FASTCALL, bytes_rstrip__doc__}, + {"rstrip", _PyCFunction_CAST(bytes_rstrip), METH_FASTCALL, bytes_rstrip__doc__}, static PyObject * bytes_rstrip_impl(PyBytesObject *self, PyObject *bytes); @@ -364,7 +416,7 @@ PyDoc_STRVAR(bytes_translate__doc__, "The remaining characters are mapped through the given translation table."); #define BYTES_TRANSLATE_METHODDEF \ - {"translate", (PyCFunction)(void(*)(void))bytes_translate, METH_FASTCALL|METH_KEYWORDS, bytes_translate__doc__}, + {"translate", _PyCFunction_CAST(bytes_translate), METH_FASTCALL|METH_KEYWORDS, bytes_translate__doc__}, static PyObject * bytes_translate_impl(PyBytesObject *self, PyObject *table, @@ -374,8 +426,31 @@ static PyObject * bytes_translate(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(delete), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "delete", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "translate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "translate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *table; @@ -409,7 +484,7 @@ PyDoc_STRVAR(bytes_maketrans__doc__, "The bytes objects frm and to must be of the same length."); #define BYTES_MAKETRANS_METHODDEF \ - {"maketrans", (PyCFunction)(void(*)(void))bytes_maketrans, METH_FASTCALL|METH_STATIC, bytes_maketrans__doc__}, + {"maketrans", _PyCFunction_CAST(bytes_maketrans), METH_FASTCALL|METH_STATIC, bytes_maketrans__doc__}, static PyObject * bytes_maketrans_impl(Py_buffer *frm, Py_buffer *to); @@ -467,7 +542,7 @@ PyDoc_STRVAR(bytes_replace__doc__, "replaced."); #define BYTES_REPLACE_METHODDEF \ - {"replace", (PyCFunction)(void(*)(void))bytes_replace, METH_FASTCALL, bytes_replace__doc__}, + {"replace", _PyCFunction_CAST(bytes_replace), METH_FASTCALL, bytes_replace__doc__}, static PyObject * bytes_replace_impl(PyBytesObject *self, Py_buffer *old, Py_buffer *new, @@ -624,7 +699,7 @@ PyDoc_STRVAR(bytes_decode__doc__, " can handle UnicodeDecodeErrors."); #define BYTES_DECODE_METHODDEF \ - {"decode", (PyCFunction)(void(*)(void))bytes_decode, METH_FASTCALL|METH_KEYWORDS, bytes_decode__doc__}, + {"decode", _PyCFunction_CAST(bytes_decode), METH_FASTCALL|METH_KEYWORDS, bytes_decode__doc__}, static PyObject * bytes_decode_impl(PyBytesObject *self, const char *encoding, @@ -634,8 +709,31 @@ static PyObject * bytes_decode(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *encoding = NULL; @@ -696,7 +794,7 @@ PyDoc_STRVAR(bytes_splitlines__doc__, "true."); #define BYTES_SPLITLINES_METHODDEF \ - {"splitlines", (PyCFunction)(void(*)(void))bytes_splitlines, METH_FASTCALL|METH_KEYWORDS, bytes_splitlines__doc__}, + {"splitlines", _PyCFunction_CAST(bytes_splitlines), METH_FASTCALL|METH_KEYWORDS, bytes_splitlines__doc__}, static PyObject * bytes_splitlines_impl(PyBytesObject *self, int keepends); @@ -705,8 +803,31 @@ static PyObject * bytes_splitlines(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(keepends), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"keepends", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "splitlines", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "splitlines", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int keepends = 0; @@ -718,8 +839,8 @@ bytes_splitlines(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, P if (!noptargs) { goto skip_optional_pos; } - keepends = _PyLong_AsInt(args[0]); - if (keepends == -1 && PyErr_Occurred()) { + keepends = PyObject_IsTrue(args[0]); + if (keepends < 0) { goto exit; } skip_optional_pos: @@ -788,7 +909,7 @@ PyDoc_STRVAR(bytes_hex__doc__, "\'b901:ef\'"); #define BYTES_HEX_METHODDEF \ - {"hex", (PyCFunction)(void(*)(void))bytes_hex, METH_FASTCALL|METH_KEYWORDS, bytes_hex__doc__}, + {"hex", _PyCFunction_CAST(bytes_hex), METH_FASTCALL|METH_KEYWORDS, bytes_hex__doc__}, static PyObject * bytes_hex_impl(PyBytesObject *self, PyObject *sep, int bytes_per_sep); @@ -797,8 +918,31 @@ static PyObject * bytes_hex(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = NULL; @@ -836,8 +980,31 @@ static PyObject * bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(source), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"source", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "bytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "bytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -896,4 +1063,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=d706344859f40122 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=31a9e4af85562612 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/classobject.c.h b/Objects/clinic/classobject.c.h new file mode 100644 index 00000000000..6c449829662 --- /dev/null +++ b/Objects/clinic/classobject.c.h @@ -0,0 +1,89 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(method___reduce____doc__, +"__reduce__($self, /)\n" +"--\n" +"\n"); + +#define METHOD___REDUCE___METHODDEF \ + {"__reduce__", (PyCFunction)method___reduce__, METH_NOARGS, method___reduce____doc__}, + +static PyObject * +method___reduce___impl(PyMethodObject *self); + +static PyObject * +method___reduce__(PyMethodObject *self, PyObject *Py_UNUSED(ignored)) +{ + return method___reduce___impl(self); +} + +PyDoc_STRVAR(method_new__doc__, +"method(function, instance, /)\n" +"--\n" +"\n" +"Create a bound instance method object."); + +static PyObject * +method_new_impl(PyTypeObject *type, PyObject *function, PyObject *instance); + +static PyObject * +method_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyObject *function; + PyObject *instance; + + if ((type == &PyMethod_Type || + type->tp_init == PyMethod_Type.tp_init) && + !_PyArg_NoKeywords("method", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("method", PyTuple_GET_SIZE(args), 2, 2)) { + goto exit; + } + function = PyTuple_GET_ITEM(args, 0); + instance = PyTuple_GET_ITEM(args, 1); + return_value = method_new_impl(type, function, instance); + +exit: + return return_value; +} + +PyDoc_STRVAR(instancemethod_new__doc__, +"instancemethod(function, /)\n" +"--\n" +"\n" +"Bind a function to a class."); + +static PyObject * +instancemethod_new_impl(PyTypeObject *type, PyObject *function); + +static PyObject * +instancemethod_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyObject *function; + + if ((type == &PyInstanceMethod_Type || + type->tp_init == PyInstanceMethod_Type.tp_init) && + !_PyArg_NoKeywords("instancemethod", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("instancemethod", PyTuple_GET_SIZE(args), 1, 1)) { + goto exit; + } + function = PyTuple_GET_ITEM(args, 0); + return_value = instancemethod_new_impl(type, function); + +exit: + return return_value; +} +/*[clinic end generated code: output=e3294c26a71d456d input=a9049054013a1b77]*/ diff --git a/Objects/clinic/codeobject.c.h b/Objects/clinic/codeobject.c.h index ee425f61bb1..da33f4a6a20 100644 --- a/Objects/clinic/codeobject.c.h +++ b/Objects/clinic/codeobject.c.h @@ -2,11 +2,17 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(code_new__doc__, "code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n" " flags, codestring, constants, names, varnames, filename, name,\n" -" qualname, firstlineno, linetable, endlinetable, columntable,\n" -" exceptiontable, freevars=(), cellvars=(), /)\n" +" qualname, firstlineno, linetable, exceptiontable, freevars=(),\n" +" cellvars=(), /)\n" "--\n" "\n" "Create a code object. Not for the faint of heart."); @@ -17,7 +23,6 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, - PyObject *endlinetable, PyObject *columntable, PyObject *exceptiontable, PyObject *freevars, PyObject *cellvars); @@ -40,8 +45,6 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyObject *qualname; int firstlineno; PyObject *linetable; - PyObject *endlinetable; - PyObject *columntable; PyObject *exceptiontable; PyObject *freevars = NULL; PyObject *cellvars = NULL; @@ -51,7 +54,7 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) !_PyArg_NoKeywords("code", kwargs)) { goto exit; } - if (!_PyArg_CheckPositional("code", PyTuple_GET_SIZE(args), 18, 20)) { + if (!_PyArg_CheckPositional("code", PyTuple_GET_SIZE(args), 16, 18)) { goto exit; } argcount = _PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); @@ -131,31 +134,29 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto exit; } linetable = PyTuple_GET_ITEM(args, 14); - endlinetable = PyTuple_GET_ITEM(args, 15); - columntable = PyTuple_GET_ITEM(args, 16); - if (!PyBytes_Check(PyTuple_GET_ITEM(args, 17))) { - _PyArg_BadArgument("code", "argument 18", "bytes", PyTuple_GET_ITEM(args, 17)); + if (!PyBytes_Check(PyTuple_GET_ITEM(args, 15))) { + _PyArg_BadArgument("code", "argument 16", "bytes", PyTuple_GET_ITEM(args, 15)); goto exit; } - exceptiontable = PyTuple_GET_ITEM(args, 17); - if (PyTuple_GET_SIZE(args) < 19) { + exceptiontable = PyTuple_GET_ITEM(args, 15); + if (PyTuple_GET_SIZE(args) < 17) { goto skip_optional; } - if (!PyTuple_Check(PyTuple_GET_ITEM(args, 18))) { - _PyArg_BadArgument("code", "argument 19", "tuple", PyTuple_GET_ITEM(args, 18)); + if (!PyTuple_Check(PyTuple_GET_ITEM(args, 16))) { + _PyArg_BadArgument("code", "argument 17", "tuple", PyTuple_GET_ITEM(args, 16)); goto exit; } - freevars = PyTuple_GET_ITEM(args, 18); - if (PyTuple_GET_SIZE(args) < 20) { + freevars = PyTuple_GET_ITEM(args, 16); + if (PyTuple_GET_SIZE(args) < 18) { goto skip_optional; } - if (!PyTuple_Check(PyTuple_GET_ITEM(args, 19))) { - _PyArg_BadArgument("code", "argument 20", "tuple", PyTuple_GET_ITEM(args, 19)); + if (!PyTuple_Check(PyTuple_GET_ITEM(args, 17))) { + _PyArg_BadArgument("code", "argument 18", "tuple", PyTuple_GET_ITEM(args, 17)); goto exit; } - cellvars = PyTuple_GET_ITEM(args, 19); + cellvars = PyTuple_GET_ITEM(args, 17); skip_optional: - return_value = code_new_impl(type, argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, qualname, firstlineno, linetable, endlinetable, columntable, exceptiontable, freevars, cellvars); + return_value = code_new_impl(type, argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, qualname, firstlineno, linetable, exceptiontable, freevars, cellvars); exit: return return_value; @@ -167,14 +168,13 @@ PyDoc_STRVAR(code_replace__doc__, " co_flags=-1, co_firstlineno=-1, co_code=None, co_consts=None,\n" " co_names=None, co_varnames=None, co_freevars=None,\n" " co_cellvars=None, co_filename=None, co_name=None,\n" -" co_qualname=None, co_linetable=None, co_endlinetable=None,\n" -" co_columntable=None, co_exceptiontable=None)\n" +" co_qualname=None, co_linetable=None, co_exceptiontable=None)\n" "--\n" "\n" "Return a copy of the code object with new values for the specified fields."); #define CODE_REPLACE_METHODDEF \ - {"replace", (PyCFunction)(void(*)(void))code_replace, METH_FASTCALL|METH_KEYWORDS, code_replace__doc__}, + {"replace", _PyCFunction_CAST(code_replace), METH_FASTCALL|METH_KEYWORDS, code_replace__doc__}, static PyObject * code_replace_impl(PyCodeObject *self, int co_argcount, @@ -185,16 +185,39 @@ code_replace_impl(PyCodeObject *self, int co_argcount, PyObject *co_varnames, PyObject *co_freevars, PyObject *co_cellvars, PyObject *co_filename, PyObject *co_name, PyObject *co_qualname, - PyBytesObject *co_linetable, PyObject *co_endlinetable, - PyObject *co_columntable, PyBytesObject *co_exceptiontable); + PyBytesObject *co_linetable, + PyBytesObject *co_exceptiontable); static PyObject * code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"co_argcount", "co_posonlyargcount", "co_kwonlyargcount", "co_nlocals", "co_stacksize", "co_flags", "co_firstlineno", "co_code", "co_consts", "co_names", "co_varnames", "co_freevars", "co_cellvars", "co_filename", "co_name", "co_qualname", "co_linetable", "co_endlinetable", "co_columntable", "co_exceptiontable", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "replace", 0}; - PyObject *argsbuf[20]; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 18 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(co_argcount), &_Py_ID(co_posonlyargcount), &_Py_ID(co_kwonlyargcount), &_Py_ID(co_nlocals), &_Py_ID(co_stacksize), &_Py_ID(co_flags), &_Py_ID(co_firstlineno), &_Py_ID(co_code), &_Py_ID(co_consts), &_Py_ID(co_names), &_Py_ID(co_varnames), &_Py_ID(co_freevars), &_Py_ID(co_cellvars), &_Py_ID(co_filename), &_Py_ID(co_name), &_Py_ID(co_qualname), &_Py_ID(co_linetable), &_Py_ID(co_exceptiontable), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"co_argcount", "co_posonlyargcount", "co_kwonlyargcount", "co_nlocals", "co_stacksize", "co_flags", "co_firstlineno", "co_code", "co_consts", "co_names", "co_varnames", "co_freevars", "co_cellvars", "co_filename", "co_name", "co_qualname", "co_linetable", "co_exceptiontable", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "replace", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[18]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int co_argcount = self->co_argcount; int co_posonlyargcount = self->co_posonlyargcount; @@ -203,18 +226,16 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje int co_stacksize = self->co_stacksize; int co_flags = self->co_flags; int co_firstlineno = self->co_firstlineno; - PyBytesObject *co_code = (PyBytesObject *)self->co_code; + PyBytesObject *co_code = NULL; PyObject *co_consts = self->co_consts; PyObject *co_names = self->co_names; - PyObject *co_varnames = self->co_varnames; - PyObject *co_freevars = self->co_freevars; - PyObject *co_cellvars = self->co_cellvars; + PyObject *co_varnames = NULL; + PyObject *co_freevars = NULL; + PyObject *co_cellvars = NULL; PyObject *co_filename = self->co_filename; PyObject *co_name = self->co_name; PyObject *co_qualname = self->co_qualname; PyBytesObject *co_linetable = (PyBytesObject *)self->co_linetable; - PyObject *co_endlinetable = self->co_endlinetable; - PyObject *co_columntable = self->co_columntable; PyBytesObject *co_exceptiontable = (PyBytesObject *)self->co_exceptiontable; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); @@ -396,25 +417,13 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje goto skip_optional_kwonly; } } - if (args[17]) { - co_endlinetable = args[17]; - if (!--noptargs) { - goto skip_optional_kwonly; - } - } - if (args[18]) { - co_columntable = args[18]; - if (!--noptargs) { - goto skip_optional_kwonly; - } - } - if (!PyBytes_Check(args[19])) { - _PyArg_BadArgument("replace", "argument 'co_exceptiontable'", "bytes", args[19]); + if (!PyBytes_Check(args[17])) { + _PyArg_BadArgument("replace", "argument 'co_exceptiontable'", "bytes", args[17]); goto exit; } - co_exceptiontable = (PyBytesObject *)args[19]; + co_exceptiontable = (PyBytesObject *)args[17]; skip_optional_kwonly: - return_value = code_replace_impl(self, co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags, co_firstlineno, co_code, co_consts, co_names, co_varnames, co_freevars, co_cellvars, co_filename, co_name, co_qualname, co_linetable, co_endlinetable, co_columntable, co_exceptiontable); + return_value = code_replace_impl(self, co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags, co_firstlineno, co_code, co_consts, co_names, co_varnames, co_freevars, co_cellvars, co_filename, co_name, co_qualname, co_linetable, co_exceptiontable); exit: return return_value; @@ -429,7 +438,7 @@ PyDoc_STRVAR(code__varname_from_oparg__doc__, "WARNING: this method is for internal use only and may change or go away."); #define CODE__VARNAME_FROM_OPARG_METHODDEF \ - {"_varname_from_oparg", (PyCFunction)(void(*)(void))code__varname_from_oparg, METH_FASTCALL|METH_KEYWORDS, code__varname_from_oparg__doc__}, + {"_varname_from_oparg", _PyCFunction_CAST(code__varname_from_oparg), METH_FASTCALL|METH_KEYWORDS, code__varname_from_oparg__doc__}, static PyObject * code__varname_from_oparg_impl(PyCodeObject *self, int oparg); @@ -438,8 +447,31 @@ static PyObject * code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(oparg), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"oparg", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_varname_from_oparg", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_varname_from_oparg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int oparg; @@ -456,4 +488,4 @@ code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t n exit: return return_value; } -/*[clinic end generated code: output=9e8c4a19474ec520 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b6c98f17c60ace53 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/complexobject.c.h b/Objects/clinic/complexobject.c.h index e7d8065e874..e92c6e98585 100644 --- a/Objects/clinic/complexobject.c.h +++ b/Objects/clinic/complexobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(complex_conjugate__doc__, "conjugate($self, /)\n" "--\n" @@ -102,8 +108,31 @@ static PyObject * complex_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(real), &_Py_ID(imag), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"real", "imag", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "complex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "complex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -131,4 +160,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=6d85094ace15677e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=52e85a1e258425d6 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/descrobject.c.h b/Objects/clinic/descrobject.c.h index d248b91bf48..75706437df8 100644 --- a/Objects/clinic/descrobject.c.h +++ b/Objects/clinic/descrobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping); @@ -9,8 +15,31 @@ static PyObject * mappingproxy_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(mapping), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"mapping", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "mappingproxy", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "mappingproxy", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -72,8 +101,31 @@ static int property_init(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fget), &_Py_ID(fset), &_Py_ID(fdel), &_Py_ID(doc), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fget", "fset", "fdel", "doc", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "property", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "property", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -115,4 +167,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=916624e717862abc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8dc1ddfcf764ac8e input=a9049054013a1b77]*/ diff --git a/Objects/clinic/dictobject.c.h b/Objects/clinic/dictobject.c.h index beb3f360f86..bc2452330e4 100644 --- a/Objects/clinic/dictobject.c.h +++ b/Objects/clinic/dictobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(dict_fromkeys__doc__, "fromkeys($type, iterable, value=None, /)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(dict_fromkeys__doc__, "Create a new dictionary with keys from iterable and values set to value."); #define DICT_FROMKEYS_METHODDEF \ - {"fromkeys", (PyCFunction)(void(*)(void))dict_fromkeys, METH_FASTCALL|METH_CLASS, dict_fromkeys__doc__}, + {"fromkeys", _PyCFunction_CAST(dict_fromkeys), METH_FASTCALL|METH_CLASS, dict_fromkeys__doc__}, static PyObject * dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value); @@ -52,7 +58,7 @@ PyDoc_STRVAR(dict_get__doc__, "Return the value for key if key is in the dictionary, else default."); #define DICT_GET_METHODDEF \ - {"get", (PyCFunction)(void(*)(void))dict_get, METH_FASTCALL, dict_get__doc__}, + {"get", _PyCFunction_CAST(dict_get), METH_FASTCALL, dict_get__doc__}, static PyObject * dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value); @@ -88,7 +94,7 @@ PyDoc_STRVAR(dict_setdefault__doc__, "Return the value for key if key is in the dictionary, else default."); #define DICT_SETDEFAULT_METHODDEF \ - {"setdefault", (PyCFunction)(void(*)(void))dict_setdefault, METH_FASTCALL, dict_setdefault__doc__}, + {"setdefault", _PyCFunction_CAST(dict_setdefault), METH_FASTCALL, dict_setdefault__doc__}, static PyObject * dict_setdefault_impl(PyDictObject *self, PyObject *key, @@ -126,7 +132,7 @@ PyDoc_STRVAR(dict_pop__doc__, "raise a KeyError."); #define DICT_POP_METHODDEF \ - {"pop", (PyCFunction)(void(*)(void))dict_pop, METH_FASTCALL, dict_pop__doc__}, + {"pop", _PyCFunction_CAST(dict_pop), METH_FASTCALL, dict_pop__doc__}, static PyObject * dict_pop_impl(PyDictObject *self, PyObject *key, PyObject *default_value); @@ -191,4 +197,4 @@ dict___reversed__(PyDictObject *self, PyObject *Py_UNUSED(ignored)) { return dict___reversed___impl(self); } -/*[clinic end generated code: output=7b77c16e43d6735a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c0064abbea6091c5 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/enumobject.c.h b/Objects/clinic/enumobject.c.h index 7513c9526ac..208a9e8be1a 100644 --- a/Objects/clinic/enumobject.c.h +++ b/Objects/clinic/enumobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(enum_new__doc__, "enumerate(iterable, start=0)\n" "--\n" @@ -24,8 +30,31 @@ static PyObject * enum_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(start), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"iterable", "start", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "enumerate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "enumerate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -78,4 +107,4 @@ reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=a3937b6b33499560 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=683261097bfd794a input=a9049054013a1b77]*/ diff --git a/Objects/clinic/floatobject.c.h b/Objects/clinic/floatobject.c.h index 88dc482e32e..1a81e173231 100644 --- a/Objects/clinic/floatobject.c.h +++ b/Objects/clinic/floatobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(float_is_integer__doc__, "is_integer($self, /)\n" "--\n" @@ -83,7 +89,7 @@ PyDoc_STRVAR(float___round____doc__, "When an argument is passed, work like built-in round(x, ndigits)."); #define FLOAT___ROUND___METHODDEF \ - {"__round__", (PyCFunction)(void(*)(void))float___round__, METH_FASTCALL, float___round____doc__}, + {"__round__", _PyCFunction_CAST(float___round__), METH_FASTCALL, float___round____doc__}, static PyObject * float___round___impl(PyObject *self, PyObject *o_ndigits); @@ -290,73 +296,6 @@ exit: return return_value; } -PyDoc_STRVAR(float___set_format____doc__, -"__set_format__($type, typestr, fmt, /)\n" -"--\n" -"\n" -"You probably don\'t want to use this function.\n" -"\n" -" typestr\n" -" Must be \'double\' or \'float\'.\n" -" fmt\n" -" Must be one of \'unknown\', \'IEEE, big-endian\' or \'IEEE, little-endian\',\n" -" and in addition can only be one of the latter two if it appears to\n" -" match the underlying C reality.\n" -"\n" -"It exists mainly to be used in Python\'s test suite.\n" -"\n" -"Override the automatic determination of C-level floating point type.\n" -"This affects how floats are converted to and from binary strings."); - -#define FLOAT___SET_FORMAT___METHODDEF \ - {"__set_format__", (PyCFunction)(void(*)(void))float___set_format__, METH_FASTCALL|METH_CLASS, float___set_format____doc__}, - -static PyObject * -float___set_format___impl(PyTypeObject *type, const char *typestr, - const char *fmt); - -static PyObject * -float___set_format__(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value = NULL; - const char *typestr; - const char *fmt; - - if (!_PyArg_CheckPositional("__set_format__", nargs, 2, 2)) { - goto exit; - } - if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("__set_format__", "argument 1", "str", args[0]); - goto exit; - } - Py_ssize_t typestr_length; - typestr = PyUnicode_AsUTF8AndSize(args[0], &typestr_length); - if (typestr == NULL) { - goto exit; - } - if (strlen(typestr) != (size_t)typestr_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; - } - if (!PyUnicode_Check(args[1])) { - _PyArg_BadArgument("__set_format__", "argument 2", "str", args[1]); - goto exit; - } - Py_ssize_t fmt_length; - fmt = PyUnicode_AsUTF8AndSize(args[1], &fmt_length); - if (fmt == NULL) { - goto exit; - } - if (strlen(fmt) != (size_t)fmt_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; - } - return_value = float___set_format___impl(type, typestr, fmt); - -exit: - return return_value; -} - PyDoc_STRVAR(float___format____doc__, "__format__($self, format_spec, /)\n" "--\n" @@ -388,4 +327,4 @@ float___format__(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=122a73f4c9d25806 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ac6374ac606a505e input=a9049054013a1b77]*/ diff --git a/Objects/clinic/funcobject.c.h b/Objects/clinic/funcobject.c.h index 17fb13fe085..c3a3a8edc39 100644 --- a/Objects/clinic/funcobject.c.h +++ b/Objects/clinic/funcobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(func_new__doc__, "function(code, globals, name=None, argdefs=None, closure=None)\n" "--\n" @@ -27,8 +33,31 @@ static PyObject * func_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(code), &_Py_ID(globals), &_Py_ID(name), &_Py_ID(argdefs), &_Py_ID(closure), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"code", "globals", "name", "argdefs", "closure", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "function", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "function", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -75,4 +104,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=3d96afa3396e5c82 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=777cead7b1f6fad3 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/listobject.c.h b/Objects/clinic/listobject.c.h index 75ed9f9df85..94852e99617 100644 --- a/Objects/clinic/listobject.c.h +++ b/Objects/clinic/listobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(list_insert__doc__, "insert($self, index, object, /)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(list_insert__doc__, "Insert object before index."); #define LIST_INSERT_METHODDEF \ - {"insert", (PyCFunction)(void(*)(void))list_insert, METH_FASTCALL, list_insert__doc__}, + {"insert", _PyCFunction_CAST(list_insert), METH_FASTCALL, list_insert__doc__}, static PyObject * list_insert_impl(PyListObject *self, Py_ssize_t index, PyObject *object); @@ -106,7 +112,7 @@ PyDoc_STRVAR(list_pop__doc__, "Raises IndexError if list is empty or index is out of range."); #define LIST_POP_METHODDEF \ - {"pop", (PyCFunction)(void(*)(void))list_pop, METH_FASTCALL, list_pop__doc__}, + {"pop", _PyCFunction_CAST(list_pop), METH_FASTCALL, list_pop__doc__}, static PyObject * list_pop_impl(PyListObject *self, Py_ssize_t index); @@ -157,7 +163,7 @@ PyDoc_STRVAR(list_sort__doc__, "The reverse flag can be set to sort in descending order."); #define LIST_SORT_METHODDEF \ - {"sort", (PyCFunction)(void(*)(void))list_sort, METH_FASTCALL|METH_KEYWORDS, list_sort__doc__}, + {"sort", _PyCFunction_CAST(list_sort), METH_FASTCALL|METH_KEYWORDS, list_sort__doc__}, static PyObject * list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse); @@ -166,8 +172,31 @@ static PyObject * list_sort(PyListObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(reverse), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "reverse", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sort", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sort", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *keyfunc = Py_None; @@ -186,8 +215,8 @@ list_sort(PyListObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject goto skip_optional_kwonly; } } - reverse = _PyLong_AsInt(args[1]); - if (reverse == -1 && PyErr_Occurred()) { + reverse = PyObject_IsTrue(args[1]); + if (reverse < 0) { goto exit; } skip_optional_kwonly: @@ -224,7 +253,7 @@ PyDoc_STRVAR(list_index__doc__, "Raises ValueError if the value is not present."); #define LIST_INDEX_METHODDEF \ - {"index", (PyCFunction)(void(*)(void))list_index, METH_FASTCALL, list_index__doc__}, + {"index", _PyCFunction_CAST(list_index), METH_FASTCALL, list_index__doc__}, static PyObject * list_index_impl(PyListObject *self, PyObject *value, Py_ssize_t start, @@ -353,4 +382,4 @@ list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored)) { return list___reversed___impl(self); } -/*[clinic end generated code: output=acb2f87736311930 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4e6f38b655394564 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h index d50c4af8096..206bffdd086 100644 --- a/Objects/clinic/longobject.c.h +++ b/Objects/clinic/longobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * long_new_impl(PyTypeObject *type, PyObject *x, PyObject *obase); @@ -9,8 +15,31 @@ static PyObject * long_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(base), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "base", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "int", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "int", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -59,7 +88,8 @@ int___getnewargs__(PyObject *self, PyObject *Py_UNUSED(ignored)) PyDoc_STRVAR(int___format____doc__, "__format__($self, format_spec, /)\n" "--\n" -"\n"); +"\n" +"Convert to a string according to format_spec."); #define INT___FORMAT___METHODDEF \ {"__format__", (PyCFunction)int___format__, METH_O, int___format____doc__}, @@ -96,7 +126,7 @@ PyDoc_STRVAR(int___round____doc__, "Rounding with an ndigits argument also returns an integer."); #define INT___ROUND___METHODDEF \ - {"__round__", (PyCFunction)(void(*)(void))int___round__, METH_FASTCALL, int___round____doc__}, + {"__round__", _PyCFunction_CAST(int___round__), METH_FASTCALL, int___round____doc__}, static PyObject * int___round___impl(PyObject *self, PyObject *o_ndigits); @@ -247,7 +277,7 @@ PyDoc_STRVAR(int_to_bytes__doc__, " is raised."); #define INT_TO_BYTES_METHODDEF \ - {"to_bytes", (PyCFunction)(void(*)(void))int_to_bytes, METH_FASTCALL|METH_KEYWORDS, int_to_bytes__doc__}, + {"to_bytes", _PyCFunction_CAST(int_to_bytes), METH_FASTCALL|METH_KEYWORDS, int_to_bytes__doc__}, static PyObject * int_to_bytes_impl(PyObject *self, Py_ssize_t length, PyObject *byteorder, @@ -257,8 +287,31 @@ static PyObject * int_to_bytes(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(length), &_Py_ID(byteorder), &_Py_ID(signed), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"length", "byteorder", "signed", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "to_bytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "to_bytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; Py_ssize_t length = 1; @@ -338,7 +391,7 @@ PyDoc_STRVAR(int_from_bytes__doc__, " Indicates whether two\'s complement is used to represent the integer."); #define INT_FROM_BYTES_METHODDEF \ - {"from_bytes", (PyCFunction)(void(*)(void))int_from_bytes, METH_FASTCALL|METH_KEYWORDS|METH_CLASS, int_from_bytes__doc__}, + {"from_bytes", _PyCFunction_CAST(int_from_bytes), METH_FASTCALL|METH_KEYWORDS|METH_CLASS, int_from_bytes__doc__}, static PyObject * int_from_bytes_impl(PyTypeObject *type, PyObject *bytes_obj, @@ -348,8 +401,31 @@ static PyObject * int_from_bytes(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(bytes), &_Py_ID(byteorder), &_Py_ID(signed), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"bytes", "byteorder", "signed", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "from_bytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "from_bytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *bytes_obj; @@ -391,4 +467,22 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=16a375d93769b227 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(int_is_integer__doc__, +"is_integer($self, /)\n" +"--\n" +"\n" +"Returns True. Exists for duck type compatibility with float.is_integer."); + +#define INT_IS_INTEGER_METHODDEF \ + {"is_integer", (PyCFunction)int_is_integer, METH_NOARGS, int_is_integer__doc__}, + +static PyObject * +int_is_integer_impl(PyObject *self); + +static PyObject * +int_is_integer(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return int_is_integer_impl(self); +} +/*[clinic end generated code: output=e518fe2b5d519322 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/memoryobject.c.h b/Objects/clinic/memoryobject.c.h index 4a682f69d65..ff7b50bb114 100644 --- a/Objects/clinic/memoryobject.c.h +++ b/Objects/clinic/memoryobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(memoryview__doc__, "memoryview(object)\n" "--\n" @@ -15,8 +21,31 @@ static PyObject * memoryview(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(object), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"object", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "memoryview", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "memoryview", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -58,7 +87,7 @@ PyDoc_STRVAR(memoryview_cast__doc__, "Cast a memoryview to a new format or shape."); #define MEMORYVIEW_CAST_METHODDEF \ - {"cast", (PyCFunction)(void(*)(void))memoryview_cast, METH_FASTCALL|METH_KEYWORDS, memoryview_cast__doc__}, + {"cast", _PyCFunction_CAST(memoryview_cast), METH_FASTCALL|METH_KEYWORDS, memoryview_cast__doc__}, static PyObject * memoryview_cast_impl(PyMemoryViewObject *self, PyObject *format, @@ -68,8 +97,31 @@ static PyObject * memoryview_cast(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(format), &_Py_ID(shape), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"format", "shape", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "cast", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cast", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *format; @@ -147,7 +199,7 @@ PyDoc_STRVAR(memoryview_tobytes__doc__, "to C first. order=None is the same as order=\'C\'."); #define MEMORYVIEW_TOBYTES_METHODDEF \ - {"tobytes", (PyCFunction)(void(*)(void))memoryview_tobytes, METH_FASTCALL|METH_KEYWORDS, memoryview_tobytes__doc__}, + {"tobytes", _PyCFunction_CAST(memoryview_tobytes), METH_FASTCALL|METH_KEYWORDS, memoryview_tobytes__doc__}, static PyObject * memoryview_tobytes_impl(PyMemoryViewObject *self, const char *order); @@ -156,8 +208,31 @@ static PyObject * memoryview_tobytes(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(order), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"order", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "tobytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "tobytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *order = NULL; @@ -218,7 +293,7 @@ PyDoc_STRVAR(memoryview_hex__doc__, "\'b901:ef\'"); #define MEMORYVIEW_HEX_METHODDEF \ - {"hex", (PyCFunction)(void(*)(void))memoryview_hex, METH_FASTCALL|METH_KEYWORDS, memoryview_hex__doc__}, + {"hex", _PyCFunction_CAST(memoryview_hex), METH_FASTCALL|METH_KEYWORDS, memoryview_hex__doc__}, static PyObject * memoryview_hex_impl(PyMemoryViewObject *self, PyObject *sep, @@ -228,8 +303,31 @@ static PyObject * memoryview_hex(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = NULL; @@ -258,4 +356,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=1b879bb934d18c66 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a832f2fc44e4794c input=a9049054013a1b77]*/ diff --git a/Objects/clinic/moduleobject.c.h b/Objects/clinic/moduleobject.c.h index c1534eaee25..861bcea6215 100644 --- a/Objects/clinic/moduleobject.c.h +++ b/Objects/clinic/moduleobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(module___init____doc__, "module(name, doc=None)\n" "--\n" @@ -17,8 +23,31 @@ static int module___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(doc), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", "doc", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "module", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "module", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -48,4 +77,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=680276bc3a496d7a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2f897c9e4721f03f input=a9049054013a1b77]*/ diff --git a/Objects/clinic/odictobject.c.h b/Objects/clinic/odictobject.c.h index a3ab9ea507f..115a134e3f7 100644 --- a/Objects/clinic/odictobject.c.h +++ b/Objects/clinic/odictobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(OrderedDict_fromkeys__doc__, "fromkeys($type, /, iterable, value=None)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(OrderedDict_fromkeys__doc__, "Create a new ordered dictionary with keys from iterable and values set to value."); #define ORDEREDDICT_FROMKEYS_METHODDEF \ - {"fromkeys", (PyCFunction)(void(*)(void))OrderedDict_fromkeys, METH_FASTCALL|METH_KEYWORDS|METH_CLASS, OrderedDict_fromkeys__doc__}, + {"fromkeys", _PyCFunction_CAST(OrderedDict_fromkeys), METH_FASTCALL|METH_KEYWORDS|METH_CLASS, OrderedDict_fromkeys__doc__}, static PyObject * OrderedDict_fromkeys_impl(PyTypeObject *type, PyObject *seq, PyObject *value); @@ -18,8 +24,31 @@ static PyObject * OrderedDict_fromkeys(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(value), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"iterable", "value", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fromkeys", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fromkeys", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *seq; @@ -50,7 +79,7 @@ PyDoc_STRVAR(OrderedDict_setdefault__doc__, "Return the value for key if key is in the dictionary, else default."); #define ORDEREDDICT_SETDEFAULT_METHODDEF \ - {"setdefault", (PyCFunction)(void(*)(void))OrderedDict_setdefault, METH_FASTCALL|METH_KEYWORDS, OrderedDict_setdefault__doc__}, + {"setdefault", _PyCFunction_CAST(OrderedDict_setdefault), METH_FASTCALL|METH_KEYWORDS, OrderedDict_setdefault__doc__}, static PyObject * OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key, @@ -60,8 +89,31 @@ static PyObject * OrderedDict_setdefault(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(default), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "setdefault", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "setdefault", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *key; @@ -93,7 +145,7 @@ PyDoc_STRVAR(OrderedDict_pop__doc__, "raise a KeyError."); #define ORDEREDDICT_POP_METHODDEF \ - {"pop", (PyCFunction)(void(*)(void))OrderedDict_pop, METH_FASTCALL|METH_KEYWORDS, OrderedDict_pop__doc__}, + {"pop", _PyCFunction_CAST(OrderedDict_pop), METH_FASTCALL|METH_KEYWORDS, OrderedDict_pop__doc__}, static PyObject * OrderedDict_pop_impl(PyODictObject *self, PyObject *key, @@ -103,8 +155,31 @@ static PyObject * OrderedDict_pop(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(default), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "pop", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "pop", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *key; @@ -135,7 +210,7 @@ PyDoc_STRVAR(OrderedDict_popitem__doc__, "Pairs are returned in LIFO order if last is true or FIFO order if false."); #define ORDEREDDICT_POPITEM_METHODDEF \ - {"popitem", (PyCFunction)(void(*)(void))OrderedDict_popitem, METH_FASTCALL|METH_KEYWORDS, OrderedDict_popitem__doc__}, + {"popitem", _PyCFunction_CAST(OrderedDict_popitem), METH_FASTCALL|METH_KEYWORDS, OrderedDict_popitem__doc__}, static PyObject * OrderedDict_popitem_impl(PyODictObject *self, int last); @@ -144,8 +219,31 @@ static PyObject * OrderedDict_popitem(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(last), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"last", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "popitem", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "popitem", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int last = 1; @@ -177,7 +275,7 @@ PyDoc_STRVAR(OrderedDict_move_to_end__doc__, "Raise KeyError if the element does not exist."); #define ORDEREDDICT_MOVE_TO_END_METHODDEF \ - {"move_to_end", (PyCFunction)(void(*)(void))OrderedDict_move_to_end, METH_FASTCALL|METH_KEYWORDS, OrderedDict_move_to_end__doc__}, + {"move_to_end", _PyCFunction_CAST(OrderedDict_move_to_end), METH_FASTCALL|METH_KEYWORDS, OrderedDict_move_to_end__doc__}, static PyObject * OrderedDict_move_to_end_impl(PyODictObject *self, PyObject *key, int last); @@ -186,8 +284,31 @@ static PyObject * OrderedDict_move_to_end(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(last), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "last", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "move_to_end", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "move_to_end", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *key; @@ -211,4 +332,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=e0afaad5b4bb47fe input=a9049054013a1b77]*/ +/*[clinic end generated code: output=76d85a9162d62ca8 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/structseq.c.h b/Objects/clinic/structseq.c.h index b3b4836543d..40ba18a544f 100644 --- a/Objects/clinic/structseq.c.h +++ b/Objects/clinic/structseq.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict); @@ -9,8 +15,31 @@ static PyObject * structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sequence), &_Py_ID(dict), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sequence", "dict", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "structseq", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "structseq", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -33,4 +62,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=ed3019acf49b656c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=802d5663c7d01024 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/tupleobject.c.h b/Objects/clinic/tupleobject.c.h index f65e5fa14eb..a4776e14fa0 100644 --- a/Objects/clinic/tupleobject.c.h +++ b/Objects/clinic/tupleobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(tuple_index__doc__, "index($self, value, start=0, stop=sys.maxsize, /)\n" "--\n" @@ -11,7 +17,7 @@ PyDoc_STRVAR(tuple_index__doc__, "Raises ValueError if the value is not present."); #define TUPLE_INDEX_METHODDEF \ - {"index", (PyCFunction)(void(*)(void))tuple_index, METH_FASTCALL, tuple_index__doc__}, + {"index", _PyCFunction_CAST(tuple_index), METH_FASTCALL, tuple_index__doc__}, static PyObject * tuple_index_impl(PyTupleObject *self, PyObject *value, Py_ssize_t start, @@ -112,4 +118,4 @@ tuple___getnewargs__(PyTupleObject *self, PyObject *Py_UNUSED(ignored)) { return tuple___getnewargs___impl(self); } -/*[clinic end generated code: output=72cc0bc4f7358116 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=441d2b880e865f87 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/typeobject.c.h b/Objects/clinic/typeobject.c.h index 8c70d76d916..dc9746abfbe 100644 --- a/Objects/clinic/typeobject.c.h +++ b/Objects/clinic/typeobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(type___instancecheck____doc__, "__instancecheck__($self, instance, /)\n" "--\n" @@ -130,6 +136,24 @@ type___sizeof__(PyTypeObject *self, PyObject *Py_UNUSED(ignored)) return type___sizeof___impl(self); } +PyDoc_STRVAR(object___getstate____doc__, +"__getstate__($self, /)\n" +"--\n" +"\n" +"Helper for pickle."); + +#define OBJECT___GETSTATE___METHODDEF \ + {"__getstate__", (PyCFunction)object___getstate__, METH_NOARGS, object___getstate____doc__}, + +static PyObject * +object___getstate___impl(PyObject *self); + +static PyObject * +object___getstate__(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return object___getstate___impl(self); +} + PyDoc_STRVAR(object___reduce____doc__, "__reduce__($self, /)\n" "--\n" @@ -180,7 +204,9 @@ PyDoc_STRVAR(object___format____doc__, "__format__($self, format_spec, /)\n" "--\n" "\n" -"Default object formatter."); +"Default object formatter.\n" +"\n" +"Return str(self) if format_spec is empty. Raise TypeError otherwise."); #define OBJECT___FORMAT___METHODDEF \ {"__format__", (PyCFunction)object___format__, METH_O, object___format____doc__}, @@ -243,4 +269,4 @@ object___dir__(PyObject *self, PyObject *Py_UNUSED(ignored)) { return object___dir___impl(self); } -/*[clinic end generated code: output=b4fb62939b08baf9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d2fc52440a89f2fa input=a9049054013a1b77]*/ diff --git a/Objects/clinic/unicodeobject.c.h b/Objects/clinic/unicodeobject.c.h index 9ef8ce2e353..f640c997577 100644 --- a/Objects/clinic/unicodeobject.c.h +++ b/Objects/clinic/unicodeobject.c.h @@ -2,6 +2,30 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(EncodingMap_size__doc__, +"size($self, /)\n" +"--\n" +"\n" +"Return the size (in bytes) of this object."); + +#define ENCODINGMAP_SIZE_METHODDEF \ + {"size", (PyCFunction)EncodingMap_size, METH_NOARGS, EncodingMap_size__doc__}, + +static PyObject * +EncodingMap_size_impl(struct encoding_map *self); + +static PyObject * +EncodingMap_size(struct encoding_map *self, PyObject *Py_UNUSED(ignored)) +{ + return EncodingMap_size_impl(self); +} + PyDoc_STRVAR(unicode_title__doc__, "title($self, /)\n" "--\n" @@ -71,7 +95,7 @@ PyDoc_STRVAR(unicode_center__doc__, "Padding is done using the specified fill character (default is a space)."); #define UNICODE_CENTER_METHODDEF \ - {"center", (PyCFunction)(void(*)(void))unicode_center, METH_FASTCALL, unicode_center__doc__}, + {"center", _PyCFunction_CAST(unicode_center), METH_FASTCALL, unicode_center__doc__}, static PyObject * unicode_center_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar); @@ -127,7 +151,7 @@ PyDoc_STRVAR(unicode_encode__doc__, " codecs.register_error that can handle UnicodeEncodeErrors."); #define UNICODE_ENCODE_METHODDEF \ - {"encode", (PyCFunction)(void(*)(void))unicode_encode, METH_FASTCALL|METH_KEYWORDS, unicode_encode__doc__}, + {"encode", _PyCFunction_CAST(unicode_encode), METH_FASTCALL|METH_KEYWORDS, unicode_encode__doc__}, static PyObject * unicode_encode_impl(PyObject *self, const char *encoding, const char *errors); @@ -136,8 +160,31 @@ static PyObject * unicode_encode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "encode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *encoding = NULL; @@ -197,7 +244,7 @@ PyDoc_STRVAR(unicode_expandtabs__doc__, "If tabsize is not given, a tab size of 8 characters is assumed."); #define UNICODE_EXPANDTABS_METHODDEF \ - {"expandtabs", (PyCFunction)(void(*)(void))unicode_expandtabs, METH_FASTCALL|METH_KEYWORDS, unicode_expandtabs__doc__}, + {"expandtabs", _PyCFunction_CAST(unicode_expandtabs), METH_FASTCALL|METH_KEYWORDS, unicode_expandtabs__doc__}, static PyObject * unicode_expandtabs_impl(PyObject *self, int tabsize); @@ -206,8 +253,31 @@ static PyObject * unicode_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tabsize), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"tabsize", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "expandtabs", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "expandtabs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int tabsize = 8; @@ -505,7 +575,7 @@ PyDoc_STRVAR(unicode_ljust__doc__, "Padding is done using the specified fill character (default is a space)."); #define UNICODE_LJUST_METHODDEF \ - {"ljust", (PyCFunction)(void(*)(void))unicode_ljust, METH_FASTCALL, unicode_ljust__doc__}, + {"ljust", _PyCFunction_CAST(unicode_ljust), METH_FASTCALL, unicode_ljust__doc__}, static PyObject * unicode_ljust_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar); @@ -572,7 +642,7 @@ PyDoc_STRVAR(unicode_strip__doc__, "If chars is given and not None, remove characters in chars instead."); #define UNICODE_STRIP_METHODDEF \ - {"strip", (PyCFunction)(void(*)(void))unicode_strip, METH_FASTCALL, unicode_strip__doc__}, + {"strip", _PyCFunction_CAST(unicode_strip), METH_FASTCALL, unicode_strip__doc__}, static PyObject * unicode_strip_impl(PyObject *self, PyObject *chars); @@ -606,7 +676,7 @@ PyDoc_STRVAR(unicode_lstrip__doc__, "If chars is given and not None, remove characters in chars instead."); #define UNICODE_LSTRIP_METHODDEF \ - {"lstrip", (PyCFunction)(void(*)(void))unicode_lstrip, METH_FASTCALL, unicode_lstrip__doc__}, + {"lstrip", _PyCFunction_CAST(unicode_lstrip), METH_FASTCALL, unicode_lstrip__doc__}, static PyObject * unicode_lstrip_impl(PyObject *self, PyObject *chars); @@ -640,7 +710,7 @@ PyDoc_STRVAR(unicode_rstrip__doc__, "If chars is given and not None, remove characters in chars instead."); #define UNICODE_RSTRIP_METHODDEF \ - {"rstrip", (PyCFunction)(void(*)(void))unicode_rstrip, METH_FASTCALL, unicode_rstrip__doc__}, + {"rstrip", _PyCFunction_CAST(unicode_rstrip), METH_FASTCALL, unicode_rstrip__doc__}, static PyObject * unicode_rstrip_impl(PyObject *self, PyObject *chars); @@ -679,7 +749,7 @@ PyDoc_STRVAR(unicode_replace__doc__, "replaced."); #define UNICODE_REPLACE_METHODDEF \ - {"replace", (PyCFunction)(void(*)(void))unicode_replace, METH_FASTCALL, unicode_replace__doc__}, + {"replace", _PyCFunction_CAST(unicode_replace), METH_FASTCALL, unicode_replace__doc__}, static PyObject * unicode_replace_impl(PyObject *self, PyObject *old, PyObject *new, @@ -814,7 +884,7 @@ PyDoc_STRVAR(unicode_rjust__doc__, "Padding is done using the specified fill character (default is a space)."); #define UNICODE_RJUST_METHODDEF \ - {"rjust", (PyCFunction)(void(*)(void))unicode_rjust, METH_FASTCALL, unicode_rjust__doc__}, + {"rjust", _PyCFunction_CAST(unicode_rjust), METH_FASTCALL, unicode_rjust__doc__}, static PyObject * unicode_rjust_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar); @@ -858,18 +928,24 @@ PyDoc_STRVAR(unicode_split__doc__, "split($self, /, sep=None, maxsplit=-1)\n" "--\n" "\n" -"Return a list of the words in the string, using sep as the delimiter string.\n" +"Return a list of the substrings in the string, using sep as the separator string.\n" "\n" " sep\n" -" The delimiter according which to split the string.\n" -" None (the default value) means split according to any whitespace,\n" -" and discard empty strings from the result.\n" +" The separator used to split the string.\n" +"\n" +" When set to None (the default value), will split on any whitespace\n" +" character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard\n" +" empty strings from the result.\n" " maxsplit\n" -" Maximum number of splits to do.\n" -" -1 (the default value) means no limit."); +" Maximum number of splits (starting from the left).\n" +" -1 (the default value) means no limit.\n" +"\n" +"Note, str.split() is mainly useful for data that has been intentionally\n" +"delimited. With natural text that includes punctuation, consider using\n" +"the regular expression module."); #define UNICODE_SPLIT_METHODDEF \ - {"split", (PyCFunction)(void(*)(void))unicode_split, METH_FASTCALL|METH_KEYWORDS, unicode_split__doc__}, + {"split", _PyCFunction_CAST(unicode_split), METH_FASTCALL|METH_KEYWORDS, unicode_split__doc__}, static PyObject * unicode_split_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit); @@ -878,8 +954,31 @@ static PyObject * unicode_split(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "split", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -953,20 +1052,22 @@ PyDoc_STRVAR(unicode_rsplit__doc__, "rsplit($self, /, sep=None, maxsplit=-1)\n" "--\n" "\n" -"Return a list of the words in the string, using sep as the delimiter string.\n" +"Return a list of the substrings in the string, using sep as the separator string.\n" "\n" " sep\n" -" The delimiter according which to split the string.\n" -" None (the default value) means split according to any whitespace,\n" -" and discard empty strings from the result.\n" +" The separator used to split the string.\n" +"\n" +" When set to None (the default value), will split on any whitespace\n" +" character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard\n" +" empty strings from the result.\n" " maxsplit\n" -" Maximum number of splits to do.\n" +" Maximum number of splits (starting from the left).\n" " -1 (the default value) means no limit.\n" "\n" -"Splits are done starting at the end of the string and working to the front."); +"Splitting starts at the end of the string and works to the front."); #define UNICODE_RSPLIT_METHODDEF \ - {"rsplit", (PyCFunction)(void(*)(void))unicode_rsplit, METH_FASTCALL|METH_KEYWORDS, unicode_rsplit__doc__}, + {"rsplit", _PyCFunction_CAST(unicode_rsplit), METH_FASTCALL|METH_KEYWORDS, unicode_rsplit__doc__}, static PyObject * unicode_rsplit_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit); @@ -975,8 +1076,31 @@ static PyObject * unicode_rsplit(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rsplit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rsplit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -1024,7 +1148,7 @@ PyDoc_STRVAR(unicode_splitlines__doc__, "true."); #define UNICODE_SPLITLINES_METHODDEF \ - {"splitlines", (PyCFunction)(void(*)(void))unicode_splitlines, METH_FASTCALL|METH_KEYWORDS, unicode_splitlines__doc__}, + {"splitlines", _PyCFunction_CAST(unicode_splitlines), METH_FASTCALL|METH_KEYWORDS, unicode_splitlines__doc__}, static PyObject * unicode_splitlines_impl(PyObject *self, int keepends); @@ -1033,8 +1157,31 @@ static PyObject * unicode_splitlines(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(keepends), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"keepends", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "splitlines", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "splitlines", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int keepends = 0; @@ -1046,8 +1193,8 @@ unicode_splitlines(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb if (!noptargs) { goto skip_optional_pos; } - keepends = _PyLong_AsInt(args[0]); - if (keepends == -1 && PyErr_Occurred()) { + keepends = PyObject_IsTrue(args[0]); + if (keepends < 0) { goto exit; } skip_optional_pos: @@ -1090,7 +1237,7 @@ PyDoc_STRVAR(unicode_maketrans__doc__, "must be a string, whose characters will be mapped to None in the result."); #define UNICODE_MAKETRANS_METHODDEF \ - {"maketrans", (PyCFunction)(void(*)(void))unicode_maketrans, METH_FASTCALL|METH_STATIC, unicode_maketrans__doc__}, + {"maketrans", _PyCFunction_CAST(unicode_maketrans), METH_FASTCALL|METH_STATIC, unicode_maketrans__doc__}, static PyObject * unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z); @@ -1267,8 +1414,31 @@ static PyObject * unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(object), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"object", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "str", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "str", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -1327,4 +1497,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=f10cf85d3935b3b7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=05d942840635dadf input=a9049054013a1b77]*/ diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 8de5c4d9c8a..ab31b6582cd 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1,15 +1,82 @@ #include #include "Python.h" -#include "code.h" #include "opcode.h" #include "structmember.h" // PyMemberDef #include "pycore_code.h" // _PyCodeConstructor +#include "pycore_frame.h" // FRAME_SPECIALS_SIZE #include "pycore_interp.h" // PyInterpreterState.co_extra_freefuncs +#include "pycore_opcode.h" // _PyOpcode_Deopt #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "clinic/codeobject.c.h" +static void +notify_code_watchers(PyCodeEvent event, PyCodeObject *co) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(interp->_initialized); + uint8_t bits = interp->active_code_watchers; + int i = 0; + while (bits) { + assert(i < CODE_MAX_WATCHERS); + if (bits & 1) { + PyCode_WatchCallback cb = interp->code_watchers[i]; + // callback must be non-null if the watcher bit is set + assert(cb != NULL); + if (cb(event, co) < 0) { + PyErr_WriteUnraisable((PyObject *) co); + } + } + i++; + bits >>= 1; + } +} + +int +PyCode_AddWatcher(PyCode_WatchCallback callback) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(interp->_initialized); + + for (int i = 0; i < CODE_MAX_WATCHERS; i++) { + if (!interp->code_watchers[i]) { + interp->code_watchers[i] = callback; + interp->active_code_watchers |= (1 << i); + return i; + } + } + + PyErr_SetString(PyExc_RuntimeError, "no more code watcher IDs available"); + return -1; +} + +static inline int +validate_watcher_id(PyInterpreterState *interp, int watcher_id) +{ + if (watcher_id < 0 || watcher_id >= CODE_MAX_WATCHERS) { + PyErr_Format(PyExc_ValueError, "Invalid code watcher ID %d", watcher_id); + return -1; + } + if (!interp->code_watchers[watcher_id]) { + PyErr_Format(PyExc_ValueError, "No code watcher set for ID %d", watcher_id); + return -1; + } + return 0; +} + +int +PyCode_ClearWatcher(int watcher_id) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(interp->_initialized); + if (validate_watcher_id(interp, watcher_id) < 0) { + return -1; + } + interp->code_watchers[watcher_id] = NULL; + interp->active_code_watchers &= ~(1 << watcher_id); + return 0; +} /****************** * generic helpers @@ -149,7 +216,22 @@ validate_and_copy_tuple(PyObject *tup) return newtuple; } +static int +init_co_cached(PyCodeObject *self) { + if (self->_co_cached == NULL) { + self->_co_cached = PyMem_New(_PyCoCached, 1); + if (self->_co_cached == NULL) { + PyErr_NoMemory(); + return -1; + } + self->_co_cached->_co_code = NULL; + self->_co_cached->_co_cellvars = NULL; + self->_co_cached->_co_freevars = NULL; + self->_co_cached->_co_varnames = NULL; + } + return 0; +} /****************** * _PyCode_New() ******************/ @@ -159,18 +241,16 @@ void _Py_set_localsplus_info(int offset, PyObject *name, _PyLocals_Kind kind, PyObject *names, PyObject *kinds) { - Py_INCREF(name); - PyTuple_SET_ITEM(names, offset, name); + PyTuple_SET_ITEM(names, offset, Py_NewRef(name)); _PyLocals_SetKind(kinds, offset, kind); } static void get_localsplus_counts(PyObject *names, PyObject *kinds, - int *pnlocals, int *pnplaincellvars, int *pncellvars, + int *pnlocals, int *pncellvars, int *pnfreevars) { int nlocals = 0; - int nplaincellvars = 0; int ncellvars = 0; int nfreevars = 0; Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(names); @@ -184,7 +264,6 @@ get_localsplus_counts(PyObject *names, PyObject *kinds, } else if (kind & CO_FAST_CELL) { ncellvars += 1; - nplaincellvars += 1; } else if (kind & CO_FAST_FREE) { nfreevars += 1; @@ -193,9 +272,6 @@ get_localsplus_counts(PyObject *names, PyObject *kinds, if (pnlocals != NULL) { *pnlocals = nlocals; } - if (pnplaincellvars != NULL) { - *pnplaincellvars = nplaincellvars; - } if (pncellvars != NULL) { *pncellvars = ncellvars; } @@ -219,8 +295,7 @@ get_localsplus_names(PyCodeObject *co, _PyLocals_Kind kind, int num) } assert(index < num); PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, offset); - Py_INCREF(name); - PyTuple_SET_ITEM(names, index, name); + PyTuple_SET_ITEM(names, index, Py_NewRef(name)); index += 1; } assert(index == num); @@ -245,10 +320,6 @@ _PyCode_Validate(struct _PyCodeConstructor *con) con->qualname == NULL || !PyUnicode_Check(con->qualname) || con->filename == NULL || !PyUnicode_Check(con->filename) || con->linetable == NULL || !PyBytes_Check(con->linetable) || - con->endlinetable == NULL || - (con->endlinetable != Py_None && !PyBytes_Check(con->endlinetable)) || - con->columntable == NULL || - (con->columntable != Py_None && !PyBytes_Check(con->columntable)) || con->exceptiontable == NULL || !PyBytes_Check(con->exceptiontable) ) { PyErr_BadInternalCall(); @@ -275,7 +346,7 @@ _PyCode_Validate(struct _PyCodeConstructor *con) * here to avoid the possibility of overflow (however remote). */ int nlocals; get_localsplus_counts(con->localsplusnames, con->localspluskinds, - &nlocals, NULL, NULL, NULL); + &nlocals, NULL, NULL); int nplainlocals = nlocals - con->argcount - con->kwonlyargcount - @@ -289,42 +360,29 @@ _PyCode_Validate(struct _PyCodeConstructor *con) return 0; } +extern void _PyCode_Quicken(PyCodeObject *code); + static void init_code(PyCodeObject *co, struct _PyCodeConstructor *con) { int nlocalsplus = (int)PyTuple_GET_SIZE(con->localsplusnames); - int nlocals, nplaincellvars, ncellvars, nfreevars; + int nlocals, ncellvars, nfreevars; get_localsplus_counts(con->localsplusnames, con->localspluskinds, - &nlocals, &nplaincellvars, &ncellvars, &nfreevars); + &nlocals, &ncellvars, &nfreevars); - Py_INCREF(con->filename); - co->co_filename = con->filename; - Py_INCREF(con->name); - co->co_name = con->name; - Py_INCREF(con->qualname); - co->co_qualname = con->qualname; + co->co_filename = Py_NewRef(con->filename); + co->co_name = Py_NewRef(con->name); + co->co_qualname = Py_NewRef(con->qualname); co->co_flags = con->flags; - Py_INCREF(con->code); - co->co_code = con->code; - co->co_firstinstr = (_Py_CODEUNIT *)PyBytes_AS_STRING(con->code); co->co_firstlineno = con->firstlineno; - Py_INCREF(con->linetable); - co->co_linetable = con->linetable; - Py_INCREF(con->endlinetable); - co->co_endlinetable = con->endlinetable; - Py_INCREF(con->columntable); - co->co_columntable = con->columntable; + co->co_linetable = Py_NewRef(con->linetable); - Py_INCREF(con->consts); - co->co_consts = con->consts; - Py_INCREF(con->names); - co->co_names = con->names; + co->co_consts = Py_NewRef(con->consts); + co->co_names = Py_NewRef(con->names); - Py_INCREF(con->localsplusnames); - co->co_localsplusnames = con->localsplusnames; - Py_INCREF(con->localspluskinds); - co->co_localspluskinds = con->localspluskinds; + co->co_localsplusnames = Py_NewRef(con->localsplusnames); + co->co_localspluskinds = Py_NewRef(con->localspluskinds); co->co_argcount = con->argcount; co->co_posonlyargcount = con->posonlyargcount; @@ -332,25 +390,126 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con) co->co_stacksize = con->stacksize; - Py_INCREF(con->exceptiontable); - co->co_exceptiontable = con->exceptiontable; + co->co_exceptiontable = Py_NewRef(con->exceptiontable); /* derived values */ co->co_nlocalsplus = nlocalsplus; co->co_nlocals = nlocals; - co->co_nplaincellvars = nplaincellvars; + co->co_framesize = nlocalsplus + con->stacksize + FRAME_SPECIALS_SIZE; co->co_ncellvars = ncellvars; co->co_nfreevars = nfreevars; - co->co_varnames = NULL; - co->co_cellvars = NULL; - co->co_freevars = NULL; - + co->co_version = _Py_next_func_version; + if (_Py_next_func_version != 0) { + _Py_next_func_version++; + } /* not set */ co->co_weakreflist = NULL; co->co_extra = NULL; + co->_co_cached = NULL; - co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE; - co->co_quickened = NULL; + co->_co_linearray_entry_size = 0; + co->_co_linearray = NULL; + memcpy(_PyCode_CODE(co), PyBytes_AS_STRING(con->code), + PyBytes_GET_SIZE(con->code)); + int entry_point = 0; + while (entry_point < Py_SIZE(co) && + _Py_OPCODE(_PyCode_CODE(co)[entry_point]) != RESUME) { + entry_point++; + } + co->_co_firsttraceable = entry_point; + _PyCode_Quicken(co); + notify_code_watchers(PY_CODE_EVENT_CREATE, co); +} + +static int +scan_varint(const uint8_t *ptr) +{ + unsigned int read = *ptr++; + unsigned int val = read & 63; + unsigned int shift = 0; + while (read & 64) { + read = *ptr++; + shift += 6; + val |= (read & 63) << shift; + } + return val; +} + +static int +scan_signed_varint(const uint8_t *ptr) +{ + unsigned int uval = scan_varint(ptr); + if (uval & 1) { + return -(int)(uval >> 1); + } + else { + return uval >> 1; + } +} + +static int +get_line_delta(const uint8_t *ptr) +{ + int code = ((*ptr) >> 3) & 15; + switch (code) { + case PY_CODE_LOCATION_INFO_NONE: + return 0; + case PY_CODE_LOCATION_INFO_NO_COLUMNS: + case PY_CODE_LOCATION_INFO_LONG: + return scan_signed_varint(ptr+1); + case PY_CODE_LOCATION_INFO_ONE_LINE0: + return 0; + case PY_CODE_LOCATION_INFO_ONE_LINE1: + return 1; + case PY_CODE_LOCATION_INFO_ONE_LINE2: + return 2; + default: + /* Same line */ + return 0; + } +} + +static PyObject * +remove_column_info(PyObject *locations) +{ + int offset = 0; + const uint8_t *data = (const uint8_t *)PyBytes_AS_STRING(locations); + PyObject *res = PyBytes_FromStringAndSize(NULL, 32); + if (res == NULL) { + PyErr_NoMemory(); + return NULL; + } + uint8_t *output = (uint8_t *)PyBytes_AS_STRING(res); + while (offset < PyBytes_GET_SIZE(locations)) { + Py_ssize_t write_offset = output - (uint8_t *)PyBytes_AS_STRING(res); + if (write_offset + 16 >= PyBytes_GET_SIZE(res)) { + if (_PyBytes_Resize(&res, PyBytes_GET_SIZE(res) * 2) < 0) { + return NULL; + } + output = (uint8_t *)PyBytes_AS_STRING(res) + write_offset; + } + int code = (data[offset] >> 3) & 15; + if (code == PY_CODE_LOCATION_INFO_NONE) { + *output++ = data[offset]; + } + else { + int blength = (data[offset] & 7)+1; + output += write_location_entry_start( + output, PY_CODE_LOCATION_INFO_NO_COLUMNS, blength); + int ldelta = get_line_delta(&data[offset]); + output += write_signed_varint(output, ldelta); + } + offset++; + while (offset < PyBytes_GET_SIZE(locations) && + (data[offset] & 128) == 0) { + offset++; + } + } + Py_ssize_t write_offset = output - (uint8_t *)PyBytes_AS_STRING(res); + if (_PyBytes_Resize(&res, write_offset)) { + return NULL; + } + return res; } /* The caller is responsible for ensuring that the given data is valid. */ @@ -379,20 +538,26 @@ _PyCode_New(struct _PyCodeConstructor *con) return NULL; } - // Discard the endlinetable and columntable if we are opted out of debug + PyObject *replacement_locations = NULL; + // Compact the linetable if we are opted out of debug // ranges. - if (_Py_GetConfig()->no_debug_ranges) { - con->endlinetable = Py_None; - con->columntable = Py_None; + if (!_Py_GetConfig()->code_debug_ranges) { + replacement_locations = remove_column_info(con->linetable); + if (replacement_locations == NULL) { + return NULL; + } + con->linetable = replacement_locations; } - PyCodeObject *co = PyObject_New(PyCodeObject, &PyCode_Type); + Py_ssize_t size = PyBytes_GET_SIZE(con->code) / sizeof(_Py_CODEUNIT); + PyCodeObject *co = PyObject_NewVar(PyCodeObject, &PyCode_Type, size); if (co == NULL) { + Py_XDECREF(replacement_locations); PyErr_NoMemory(); return NULL; } init_code(co, con); - + Py_XDECREF(replacement_locations); return co; } @@ -408,8 +573,8 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, - PyObject *linetable, PyObject *endlinetable, - PyObject *columntable, PyObject *exceptiontable) + PyObject *linetable, + PyObject *exceptiontable) { PyCodeObject *co = NULL; PyObject *localsplusnames = NULL; @@ -487,8 +652,6 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, .code = code, .firstlineno = firstlineno, .linetable = linetable, - .endlinetable = endlinetable, - .columntable = columntable, .consts = consts, .names = names, @@ -521,13 +684,6 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, goto error; } - Py_INCREF(varnames); - co->co_varnames = varnames; - Py_INCREF(cellvars); - co->co_cellvars = cellvars; - Py_INCREF(freevars); - co->co_freevars = freevars; - error: Py_XDECREF(localsplusnames); Py_XDECREF(localspluskinds); @@ -540,29 +696,44 @@ PyCode_New(int argcount, int kwonlyargcount, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, - int firstlineno, PyObject *linetable, PyObject *endlinetable, - PyObject *columntable, PyObject *exceptiontable) + int firstlineno, + PyObject *linetable, + PyObject *exceptiontable) { return PyCode_NewWithPosOnlyArgs(argcount, 0, kwonlyargcount, nlocals, stacksize, flags, code, consts, names, varnames, freevars, cellvars, filename, - name, qualname, firstlineno, linetable, - endlinetable, columntable, exceptiontable); + name, qualname, firstlineno, + linetable, + exceptiontable); } +// NOTE: When modifying the construction of PyCode_NewEmpty, please also change +// test.test_code.CodeLocationTest.test_code_new_empty to keep it in sync! + +static const uint8_t assert0[6] = { + RESUME, 0, + LOAD_ASSERTION_ERROR, 0, + RAISE_VARARGS, 1 +}; + +static const uint8_t linetable[2] = { + (1 << 7) // New entry. + | (PY_CODE_LOCATION_INFO_NO_COLUMNS << 3) + | (3 - 1), // Three code units. + 0, // Offset from co_firstlineno. +}; + PyCodeObject * PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) { - PyObject *emptystring = NULL; PyObject *nulltuple = NULL; PyObject *filename_ob = NULL; PyObject *funcname_ob = NULL; + PyObject *code_ob = NULL; + PyObject *linetable_ob = NULL; PyCodeObject *result = NULL; - emptystring = PyBytes_FromString(""); - if (emptystring == NULL) { - goto failed; - } nulltuple = PyTuple_New(0); if (nulltuple == NULL) { goto failed; @@ -575,29 +746,38 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) if (filename_ob == NULL) { goto failed; } + code_ob = PyBytes_FromStringAndSize((const char *)assert0, 6); + if (code_ob == NULL) { + goto failed; + } + linetable_ob = PyBytes_FromStringAndSize((const char *)linetable, 2); + if (linetable_ob == NULL) { + goto failed; + } +#define emptystring (PyObject *)&_Py_SINGLETON(bytes_empty) struct _PyCodeConstructor con = { .filename = filename_ob, .name = funcname_ob, .qualname = funcname_ob, - .code = emptystring, + .code = code_ob, .firstlineno = firstlineno, - .linetable = emptystring, - .endlinetable = emptystring, - .columntable = emptystring, + .linetable = linetable_ob, .consts = nulltuple, .names = nulltuple, .localsplusnames = nulltuple, .localspluskinds = emptystring, .exceptiontable = emptystring, + .stacksize = 1, }; result = _PyCode_New(&con); failed: - Py_XDECREF(emptystring); Py_XDECREF(nulltuple); Py_XDECREF(funcname_ob); Py_XDECREF(filename_ob); + Py_XDECREF(code_ob); + Py_XDECREF(linetable_ob); return result; } @@ -610,80 +790,69 @@ failed: lnotab_notes.txt for the details of the lnotab representation. */ +int +_PyCode_CreateLineArray(PyCodeObject *co) +{ + assert(co->_co_linearray == NULL); + PyCodeAddressRange bounds; + int size; + int max_line = 0; + _PyCode_InitAddressRange(co, &bounds); + while(_PyLineTable_NextAddressRange(&bounds)) { + if (bounds.ar_line > max_line) { + max_line = bounds.ar_line; + } + } + if (max_line < (1 << 15)) { + size = 2; + } + else { + size = 4; + } + co->_co_linearray = PyMem_Malloc(Py_SIZE(co)*size); + if (co->_co_linearray == NULL) { + PyErr_NoMemory(); + return -1; + } + co->_co_linearray_entry_size = size; + _PyCode_InitAddressRange(co, &bounds); + while(_PyLineTable_NextAddressRange(&bounds)) { + int start = bounds.ar_start / sizeof(_Py_CODEUNIT); + int end = bounds.ar_end / sizeof(_Py_CODEUNIT); + for (int index = start; index < end; index++) { + assert(index < (int)Py_SIZE(co)); + if (size == 2) { + assert(((int16_t)bounds.ar_line) == bounds.ar_line); + ((int16_t *)co->_co_linearray)[index] = bounds.ar_line; + } + else { + assert(size == 4); + ((int32_t *)co->_co_linearray)[index] = bounds.ar_line; + } + } + } + return 0; +} + int PyCode_Addr2Line(PyCodeObject *co, int addrq) { if (addrq < 0) { return co->co_firstlineno; } - assert(addrq >= 0 && addrq < PyBytes_GET_SIZE(co->co_code)); + assert(addrq >= 0 && addrq < _PyCode_NBYTES(co)); + if (co->_co_linearray) { + return _PyCode_LineNumberFromArray(co, addrq / sizeof(_Py_CODEUNIT)); + } PyCodeAddressRange bounds; _PyCode_InitAddressRange(co, &bounds); return _PyCode_CheckLineNumber(addrq, &bounds); } -int -PyCode_Addr2Location(PyCodeObject *co, int addrq, - int *start_line, int *start_column, - int *end_line, int *end_column) -{ - *start_line = PyCode_Addr2Line(co, addrq); - *start_column = _PyCode_Addr2Offset(co, addrq); - *end_line = _PyCode_Addr2EndLine(co, addrq); - *end_column = _PyCode_Addr2EndOffset(co, addrq); - return 1; -} - -int -_PyCode_Addr2EndLine(PyCodeObject* co, int addrq) -{ - if (addrq < 0) { - return co->co_firstlineno; - } - else if (co->co_endlinetable == Py_None) { - return -1; - } - - assert(addrq >= 0 && addrq < PyBytes_GET_SIZE(co->co_code)); - PyCodeAddressRange bounds; - _PyCode_InitEndAddressRange(co, &bounds); - return _PyCode_CheckLineNumber(addrq, &bounds); -} - -int -_PyCode_Addr2Offset(PyCodeObject* co, int addrq) -{ - if (co->co_columntable == Py_None || addrq < 0) { - return -1; - } - addrq /= sizeof(_Py_CODEUNIT); - if (addrq*2 >= PyBytes_GET_SIZE(co->co_columntable)) { - return -1; - } - - unsigned char* bytes = (unsigned char*)PyBytes_AS_STRING(co->co_columntable); - return bytes[addrq*2] - 1; -} - -int -_PyCode_Addr2EndOffset(PyCodeObject* co, int addrq) -{ - if (co->co_columntable == Py_None || addrq < 0) { - return -1; - } - addrq /= sizeof(_Py_CODEUNIT); - if (addrq*2+1 >= PyBytes_GET_SIZE(co->co_columntable)) { - return -1; - } - - unsigned char* bytes = (unsigned char*)PyBytes_AS_STRING(co->co_columntable); - return bytes[addrq*2+1] - 1; -} - void -PyLineTable_InitAddressRange(const char *linetable, Py_ssize_t length, int firstlineno, PyCodeAddressRange *range) +_PyLineTable_InitAddressRange(const char *linetable, Py_ssize_t length, int firstlineno, PyCodeAddressRange *range) { - range->opaque.lo_next = linetable; + range->opaque.lo_next = (const uint8_t *)linetable; range->opaque.limit = range->opaque.lo_next + length; range->ar_start = -1; range->ar_end = 0; @@ -694,18 +863,10 @@ PyLineTable_InitAddressRange(const char *linetable, Py_ssize_t length, int first int _PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds) { + assert(co->co_linetable != NULL); const char *linetable = PyBytes_AS_STRING(co->co_linetable); Py_ssize_t length = PyBytes_GET_SIZE(co->co_linetable); - PyLineTable_InitAddressRange(linetable, length, co->co_firstlineno, bounds); - return bounds->ar_line; -} - -int -_PyCode_InitEndAddressRange(PyCodeObject* co, PyCodeAddressRange* bounds) -{ - char* linetable = PyBytes_AS_STRING(co->co_endlinetable); - Py_ssize_t length = PyBytes_GET_SIZE(co->co_endlinetable); - PyLineTable_InitAddressRange(linetable, length, co->co_firstlineno, bounds); + _PyLineTable_InitAddressRange(linetable, length, co->co_firstlineno, bounds); return bounds->ar_line; } @@ -715,85 +876,224 @@ int _PyCode_CheckLineNumber(int lasti, PyCodeAddressRange *bounds) { while (bounds->ar_end <= lasti) { - if (!PyLineTable_NextAddressRange(bounds)) { + if (!_PyLineTable_NextAddressRange(bounds)) { return -1; } } while (bounds->ar_start > lasti) { - if (!PyLineTable_PreviousAddressRange(bounds)) { + if (!_PyLineTable_PreviousAddressRange(bounds)) { return -1; } } return bounds->ar_line; } +static int +is_no_line_marker(uint8_t b) +{ + return (b >> 3) == 0x1f; +} + + +#define ASSERT_VALID_BOUNDS(bounds) \ + assert(bounds->opaque.lo_next <= bounds->opaque.limit && \ + (bounds->ar_line == -1 || bounds->ar_line == bounds->opaque.computed_line) && \ + (bounds->opaque.lo_next == bounds->opaque.limit || \ + (*bounds->opaque.lo_next) & 128)) + +static int +next_code_delta(PyCodeAddressRange *bounds) +{ + assert((*bounds->opaque.lo_next) & 128); + return (((*bounds->opaque.lo_next) & 7) + 1) * sizeof(_Py_CODEUNIT); +} + +static int +previous_code_delta(PyCodeAddressRange *bounds) +{ + if (bounds->ar_start == 0) { + // If we looking at the first entry, the + // "previous" entry has an implicit length of 1. + return 1; + } + const uint8_t *ptr = bounds->opaque.lo_next-1; + while (((*ptr) & 128) == 0) { + ptr--; + } + return (((*ptr) & 7) + 1) * sizeof(_Py_CODEUNIT); +} + +static int +read_byte(PyCodeAddressRange *bounds) +{ + return *bounds->opaque.lo_next++; +} + +static int +read_varint(PyCodeAddressRange *bounds) +{ + unsigned int read = read_byte(bounds); + unsigned int val = read & 63; + unsigned int shift = 0; + while (read & 64) { + read = read_byte(bounds); + shift += 6; + val |= (read & 63) << shift; + } + return val; +} + +static int +read_signed_varint(PyCodeAddressRange *bounds) +{ + unsigned int uval = read_varint(bounds); + if (uval & 1) { + return -(int)(uval >> 1); + } + else { + return uval >> 1; + } +} + static void retreat(PyCodeAddressRange *bounds) { - int ldelta = ((signed char *)bounds->opaque.lo_next)[-1]; - if (ldelta == -128) { - ldelta = 0; - } - bounds->opaque.computed_line -= ldelta; - bounds->opaque.lo_next -= 2; + ASSERT_VALID_BOUNDS(bounds); + assert(bounds->ar_start >= 0); + do { + bounds->opaque.lo_next--; + } while (((*bounds->opaque.lo_next) & 128) == 0); + bounds->opaque.computed_line -= get_line_delta(bounds->opaque.lo_next); bounds->ar_end = bounds->ar_start; - bounds->ar_start -= ((unsigned char *)bounds->opaque.lo_next)[-2]; - ldelta = ((signed char *)bounds->opaque.lo_next)[-1]; - if (ldelta == -128) { + bounds->ar_start -= previous_code_delta(bounds); + if (is_no_line_marker(bounds->opaque.lo_next[-1])) { bounds->ar_line = -1; } else { bounds->ar_line = bounds->opaque.computed_line; } + ASSERT_VALID_BOUNDS(bounds); } static void advance(PyCodeAddressRange *bounds) { - bounds->ar_start = bounds->ar_end; - int delta = ((unsigned char *)bounds->opaque.lo_next)[0]; - bounds->ar_end += delta; - int ldelta = ((signed char *)bounds->opaque.lo_next)[1]; - bounds->opaque.lo_next += 2; - if (ldelta == -128) { + ASSERT_VALID_BOUNDS(bounds); + bounds->opaque.computed_line += get_line_delta(bounds->opaque.lo_next); + if (is_no_line_marker(*bounds->opaque.lo_next)) { bounds->ar_line = -1; } else { - bounds->opaque.computed_line += ldelta; bounds->ar_line = bounds->opaque.computed_line; } + bounds->ar_start = bounds->ar_end; + bounds->ar_end += next_code_delta(bounds); + do { + bounds->opaque.lo_next++; + } while (bounds->opaque.lo_next < bounds->opaque.limit && + ((*bounds->opaque.lo_next) & 128) == 0); + ASSERT_VALID_BOUNDS(bounds); } +static void +advance_with_locations(PyCodeAddressRange *bounds, int *endline, int *column, int *endcolumn) +{ + ASSERT_VALID_BOUNDS(bounds); + int first_byte = read_byte(bounds); + int code = (first_byte >> 3) & 15; + bounds->ar_start = bounds->ar_end; + bounds->ar_end = bounds->ar_start + ((first_byte & 7) + 1) * sizeof(_Py_CODEUNIT); + switch(code) { + case PY_CODE_LOCATION_INFO_NONE: + bounds->ar_line = *endline = -1; + *column = *endcolumn = -1; + break; + case PY_CODE_LOCATION_INFO_LONG: + { + bounds->opaque.computed_line += read_signed_varint(bounds); + bounds->ar_line = bounds->opaque.computed_line; + *endline = bounds->ar_line + read_varint(bounds); + *column = read_varint(bounds)-1; + *endcolumn = read_varint(bounds)-1; + break; + } + case PY_CODE_LOCATION_INFO_NO_COLUMNS: + { + /* No column */ + bounds->opaque.computed_line += read_signed_varint(bounds); + *endline = bounds->ar_line = bounds->opaque.computed_line; + *column = *endcolumn = -1; + break; + } + case PY_CODE_LOCATION_INFO_ONE_LINE0: + case PY_CODE_LOCATION_INFO_ONE_LINE1: + case PY_CODE_LOCATION_INFO_ONE_LINE2: + { + /* one line form */ + int line_delta = code - 10; + bounds->opaque.computed_line += line_delta; + *endline = bounds->ar_line = bounds->opaque.computed_line; + *column = read_byte(bounds); + *endcolumn = read_byte(bounds); + break; + } + default: + { + /* Short forms */ + int second_byte = read_byte(bounds); + assert((second_byte & 128) == 0); + *endline = bounds->ar_line = bounds->opaque.computed_line; + *column = code << 3 | (second_byte >> 4); + *endcolumn = *column + (second_byte & 15); + } + } + ASSERT_VALID_BOUNDS(bounds); +} +int +PyCode_Addr2Location(PyCodeObject *co, int addrq, + int *start_line, int *start_column, + int *end_line, int *end_column) +{ + if (addrq < 0) { + *start_line = *end_line = co->co_firstlineno; + *start_column = *end_column = 0; + return 1; + } + assert(addrq >= 0 && addrq < _PyCode_NBYTES(co)); + PyCodeAddressRange bounds; + _PyCode_InitAddressRange(co, &bounds); + _PyCode_CheckLineNumber(addrq, &bounds); + retreat(&bounds); + advance_with_locations(&bounds, end_line, start_column, end_column); + *start_line = bounds.ar_line; + return 1; +} + + static inline int at_end(PyCodeAddressRange *bounds) { return bounds->opaque.lo_next >= bounds->opaque.limit; } int -PyLineTable_PreviousAddressRange(PyCodeAddressRange *range) +_PyLineTable_PreviousAddressRange(PyCodeAddressRange *range) { if (range->ar_start <= 0) { return 0; } retreat(range); - while (range->ar_start == range->ar_end) { - assert(range->ar_start > 0); - retreat(range); - } + assert(range->ar_end > range->ar_start); return 1; } int -PyLineTable_NextAddressRange(PyCodeAddressRange *range) +_PyLineTable_NextAddressRange(PyCodeAddressRange *range) { if (at_end(range)) { return 0; } advance(range); - while (range->ar_start == range->ar_end) { - assert(!at_end(range)); - advance(range); - } + assert(range->ar_end > range->ar_start); return 1; } @@ -852,7 +1152,7 @@ decode_linetable(PyCodeObject *code) return NULL; } _PyCode_InitAddressRange(code, &bounds); - while (PyLineTable_NextAddressRange(&bounds)) { + while (_PyLineTable_NextAddressRange(&bounds)) { if (bounds.opaque.computed_line != line) { int bdelta = bounds.ar_start - code_offset; int ldelta = bounds.opaque.computed_line - line; @@ -873,7 +1173,6 @@ typedef struct { PyObject_HEAD PyCodeObject *li_code; PyCodeAddressRange li_line; - char *li_end; } lineiterator; @@ -884,42 +1183,35 @@ lineiter_dealloc(lineiterator *li) Py_TYPE(li)->tp_free(li); } +static PyObject * +_source_offset_converter(int *value) { + if (*value == -1) { + Py_RETURN_NONE; + } + return PyLong_FromLong(*value); +} + static PyObject * lineiter_next(lineiterator *li) { PyCodeAddressRange *bounds = &li->li_line; - if (!PyLineTable_NextAddressRange(bounds)) { + if (!_PyLineTable_NextAddressRange(bounds)) { return NULL; } - PyObject *start = NULL; - PyObject *end = NULL; - PyObject *line = NULL; - PyObject *result = PyTuple_New(3); - start = PyLong_FromLong(bounds->ar_start); - end = PyLong_FromLong(bounds->ar_end); - if (bounds->ar_line < 0) { - Py_INCREF(Py_None); - line = Py_None; + int start = bounds->ar_start; + int line = bounds->ar_line; + // Merge overlapping entries: + while (_PyLineTable_NextAddressRange(bounds)) { + if (bounds->ar_line != line) { + _PyLineTable_PreviousAddressRange(bounds); + break; + } } - else { - line = PyLong_FromLong(bounds->ar_line); - } - if (result == NULL || start == NULL || end == NULL || line == NULL) { - goto error; - } - PyTuple_SET_ITEM(result, 0, start); - PyTuple_SET_ITEM(result, 1, end); - PyTuple_SET_ITEM(result, 2, line); - return result; -error: - Py_XDECREF(start); - Py_XDECREF(end); - Py_XDECREF(line); - Py_XDECREF(result); - return result; + return Py_BuildValue("iiO&", start, bounds->ar_end, + _source_offset_converter, &line); } -static PyTypeObject LineIterator = { +PyTypeObject _PyLineIterator = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "line_iterator", /* tp_name */ sizeof(lineiterator), /* tp_basicsize */ @@ -965,12 +1257,11 @@ static PyTypeObject LineIterator = { static lineiterator * new_linesiterator(PyCodeObject *code) { - lineiterator *li = (lineiterator *)PyType_GenericAlloc(&LineIterator, 0); + lineiterator *li = (lineiterator *)PyType_GenericAlloc(&_PyLineIterator, 0); if (li == NULL) { return NULL; } - Py_INCREF(code); - li->li_code = code; + li->li_code = (PyCodeObject*)Py_NewRef(code); _PyCode_InitAddressRange(code, &li->li_line); return li; } @@ -979,7 +1270,11 @@ new_linesiterator(PyCodeObject *code) typedef struct { PyObject_HEAD PyCodeObject* pi_code; + PyCodeAddressRange pi_range; int pi_offset; + int pi_endline; + int pi_column; + int pi_endcolumn; } positionsiterator; static void @@ -989,38 +1284,27 @@ positionsiter_dealloc(positionsiterator* pi) Py_TYPE(pi)->tp_free(pi); } -static PyObject* -_source_offset_converter(int* value) { - if (*value == -1) { - Py_RETURN_NONE; - } - return PyLong_FromLong(*value); -} - static PyObject* positionsiter_next(positionsiterator* pi) { - if (pi->pi_offset >= PyBytes_GET_SIZE(pi->pi_code->co_code)) { - return NULL; + if (pi->pi_offset >= pi->pi_range.ar_end) { + assert(pi->pi_offset == pi->pi_range.ar_end); + if (at_end(&pi->pi_range)) { + return NULL; + } + advance_with_locations(&pi->pi_range, &pi->pi_endline, &pi->pi_column, &pi->pi_endcolumn); } - - int start_line, start_col, end_line, end_col; - if (!PyCode_Addr2Location(pi->pi_code, pi->pi_offset, &start_line, - &start_col, &end_line, &end_col)) { - return NULL; - } - pi->pi_offset += 2; return Py_BuildValue("(O&O&O&O&)", - _source_offset_converter, &start_line, - _source_offset_converter, &end_line, - _source_offset_converter, &start_col, - _source_offset_converter, &end_col); + _source_offset_converter, &pi->pi_range.ar_line, + _source_offset_converter, &pi->pi_endline, + _source_offset_converter, &pi->pi_column, + _source_offset_converter, &pi->pi_endcolumn); } -static PyTypeObject PositionsIterator = { +PyTypeObject _PyPositionsIterator = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "poisitions_iterator", /* tp_name */ + "positions_iterator", /* tp_name */ sizeof(positionsiterator), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ @@ -1064,13 +1348,13 @@ static PyTypeObject PositionsIterator = { static PyObject* code_positionsiterator(PyCodeObject* code, PyObject* Py_UNUSED(args)) { - positionsiterator* pi = (positionsiterator*)PyType_GenericAlloc(&PositionsIterator, 0); + positionsiterator* pi = (positionsiterator*)PyType_GenericAlloc(&_PyPositionsIterator, 0); if (pi == NULL) { return NULL; } - Py_INCREF(code); - pi->pi_code = code; - pi->pi_offset = 0; + pi->pi_code = (PyCodeObject*)Py_NewRef(code); + _PyCode_InitAddressRange(code, &pi->pi_range); + pi->pi_offset = pi->pi_range.ar_end; return (PyObject*)pi; } @@ -1097,7 +1381,7 @@ _PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra) PyCodeObject *o = (PyCodeObject*) code; _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) o->co_extra; - if (co_extra == NULL || co_extra->ce_size <= index) { + if (co_extra == NULL || index < 0 || co_extra->ce_size <= index) { *extra = NULL; return 0; } @@ -1153,51 +1437,109 @@ _PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra) * other PyCodeObject accessor functions ******************/ +static PyObject * +get_cached_locals(PyCodeObject *co, PyObject **cached_field, + _PyLocals_Kind kind, int num) +{ + assert(cached_field != NULL); + assert(co->_co_cached != NULL); + if (*cached_field != NULL) { + return Py_NewRef(*cached_field); + } + assert(*cached_field == NULL); + PyObject *varnames = get_localsplus_names(co, kind, num); + if (varnames == NULL) { + return NULL; + } + *cached_field = Py_NewRef(varnames); + return varnames; +} + PyObject * _PyCode_GetVarnames(PyCodeObject *co) { - if (co->co_varnames == NULL) { - // PyCodeObject owns this reference. - co->co_varnames = get_localsplus_names(co, CO_FAST_LOCAL, - co->co_nlocals); - if (co->co_varnames == NULL) { - return NULL; - } + if (init_co_cached(co)) { + return NULL; } - Py_INCREF(co->co_varnames); - return co->co_varnames; + return get_cached_locals(co, &co->_co_cached->_co_varnames, CO_FAST_LOCAL, co->co_nlocals); +} + +PyObject * +PyCode_GetVarnames(PyCodeObject *code) +{ + return _PyCode_GetVarnames(code); } PyObject * _PyCode_GetCellvars(PyCodeObject *co) { - if (co->co_cellvars == NULL) { - // PyCodeObject owns this reference. - co->co_cellvars = get_localsplus_names(co, CO_FAST_CELL, - co->co_ncellvars); - if (co->co_cellvars == NULL) { - return NULL; - } + if (init_co_cached(co)) { + return NULL; } - Py_INCREF(co->co_cellvars); - return co->co_cellvars; + return get_cached_locals(co, &co->_co_cached->_co_cellvars, CO_FAST_CELL, co->co_ncellvars); +} + +PyObject * +PyCode_GetCellvars(PyCodeObject *code) +{ + return _PyCode_GetCellvars(code); } PyObject * _PyCode_GetFreevars(PyCodeObject *co) { - if (co->co_freevars == NULL) { - // PyCodeObject owns this reference. - co->co_freevars = get_localsplus_names(co, CO_FAST_FREE, - co->co_nfreevars); - if (co->co_freevars == NULL) { - return NULL; - } + if (init_co_cached(co)) { + return NULL; } - Py_INCREF(co->co_freevars); - return co->co_freevars; + return get_cached_locals(co, &co->_co_cached->_co_freevars, CO_FAST_FREE, co->co_nfreevars); } +PyObject * +PyCode_GetFreevars(PyCodeObject *code) +{ + return _PyCode_GetFreevars(code); +} + +static void +deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len) +{ + for (int i = 0; i < len; i++) { + _Py_CODEUNIT instruction = instructions[i]; + int opcode = _PyOpcode_Deopt[_Py_OPCODE(instruction)]; + int caches = _PyOpcode_Caches[opcode]; + instructions[i].opcode = opcode; + while (caches--) { + instructions[++i].opcode = CACHE; + instructions[i].oparg = 0; + } + } +} + +PyObject * +_PyCode_GetCode(PyCodeObject *co) +{ + if (init_co_cached(co)) { + return NULL; + } + if (co->_co_cached->_co_code != NULL) { + return Py_NewRef(co->_co_cached->_co_code); + } + PyObject *code = PyBytes_FromStringAndSize((const char *)_PyCode_CODE(co), + _PyCode_NBYTES(co)); + if (code == NULL) { + return NULL; + } + deopt_code((_Py_CODEUNIT *)PyBytes_AS_STRING(code), Py_SIZE(co)); + assert(co->_co_cached->_co_code == NULL); + co->_co_cached->_co_code = Py_NewRef(code); + return code; +} + +PyObject * +PyCode_GetCode(PyCodeObject *co) +{ + return _PyCode_GetCode(co); +} /****************** * PyCode_Type @@ -1227,8 +1569,6 @@ code.__new__ as code_new qualname: unicode firstlineno: int linetable: object(subclass_of="&PyBytes_Type") - endlinetable: object - columntable: object exceptiontable: object(subclass_of="&PyBytes_Type") freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = () cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = () @@ -1243,10 +1583,9 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, - PyObject *endlinetable, PyObject *columntable, PyObject *exceptiontable, PyObject *freevars, PyObject *cellvars) -/*[clinic end generated code: output=e1d2086aa8da7c08 input=a06cd92369134063]*/ +/*[clinic end generated code: output=069fa20d299f9dda input=e31da3c41ad8064a]*/ { PyObject *co = NULL; PyObject *ournames = NULL; @@ -1254,8 +1593,8 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount, PyObject *ourfreevars = NULL; PyObject *ourcellvars = NULL; - if (PySys_Audit("code.__new__", "OOOOiiiiii", - code, filename, name, qualname, argcount, posonlyargcount, + if (PySys_Audit("code.__new__", "OOOiiiiii", + code, filename, name, argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize, flags) < 0) { goto cleanup; } @@ -1287,17 +1626,6 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount, goto cleanup; } - if (!Py_IsNone(endlinetable) && !PyBytes_Check(endlinetable)) { - PyErr_SetString(PyExc_ValueError, - "code: endlinetable must be None or bytes"); - goto cleanup; - } - if (!Py_IsNone(columntable) && !PyBytes_Check(columntable)) { - PyErr_SetString(PyExc_ValueError, - "code: columntable must be None or bytes"); - goto cleanup; - } - ournames = validate_and_copy_tuple(names); if (ournames == NULL) goto cleanup; @@ -1324,8 +1652,8 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount, ourvarnames, ourfreevars, ourcellvars, filename, name, qualname, firstlineno, - linetable, endlinetable, - columntable, exceptiontable + linetable, + exceptiontable ); cleanup: Py_XDECREF(ournames); @@ -1338,6 +1666,8 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount, static void code_dealloc(PyCodeObject *co) { + notify_code_watchers(PY_CODE_EVENT_DESTROY, co); + if (co->co_extra != NULL) { PyInterpreterState *interp = _PyInterpreterState_GET(); _PyCodeObjectExtra *co_extra = co->co_extra; @@ -1353,26 +1683,27 @@ code_dealloc(PyCodeObject *co) PyMem_Free(co_extra); } - Py_XDECREF(co->co_code); Py_XDECREF(co->co_consts); Py_XDECREF(co->co_names); Py_XDECREF(co->co_localsplusnames); Py_XDECREF(co->co_localspluskinds); - Py_XDECREF(co->co_varnames); - Py_XDECREF(co->co_freevars); - Py_XDECREF(co->co_cellvars); Py_XDECREF(co->co_filename); Py_XDECREF(co->co_name); Py_XDECREF(co->co_qualname); Py_XDECREF(co->co_linetable); - Py_XDECREF(co->co_endlinetable); - Py_XDECREF(co->co_columntable); Py_XDECREF(co->co_exceptiontable); - if (co->co_weakreflist != NULL) + if (co->_co_cached != NULL) { + Py_XDECREF(co->_co_cached->_co_code); + Py_XDECREF(co->_co_cached->_co_cellvars); + Py_XDECREF(co->_co_cached->_co_freevars); + Py_XDECREF(co->_co_cached->_co_varnames); + PyMem_Free(co->_co_cached); + } + if (co->co_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject*)co); - if (co->co_quickened) { - PyMem_Free(co->co_quickened); - _Py_QuickenedCount--; + } + if (co->_co_linearray) { + PyMem_Free(co->_co_linearray); } PyObject_Free(co); } @@ -1425,8 +1756,21 @@ code_richcompare(PyObject *self, PyObject *other, int op) if (!eq) goto unequal; eq = co->co_firstlineno == cp->co_firstlineno; if (!eq) goto unequal; - eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ); - if (eq <= 0) goto unequal; + eq = Py_SIZE(co) == Py_SIZE(cp); + if (!eq) { + goto unequal; + } + for (int i = 0; i < Py_SIZE(co); i++) { + _Py_CODEUNIT co_instr = _PyCode_CODE(co)[i]; + _Py_CODEUNIT cp_instr = _PyCode_CODE(cp)[i]; + co_instr.opcode = _PyOpcode_Deopt[_Py_OPCODE(co_instr)]; + cp_instr.opcode =_PyOpcode_Deopt[_Py_OPCODE(cp_instr)]; + eq = co_instr.cache == cp_instr.cache; + if (!eq) { + goto unequal; + } + i += _PyOpcode_Caches[_Py_OPCODE(co_instr)]; + } /* compare constants */ consts1 = _PyCode_ConstantKey(co->co_consts); @@ -1447,6 +1791,15 @@ code_richcompare(PyObject *self, PyObject *other, int op) eq = PyObject_RichCompareBool(co->co_localsplusnames, cp->co_localsplusnames, Py_EQ); if (eq <= 0) goto unequal; + eq = PyObject_RichCompareBool(co->co_linetable, cp->co_linetable, Py_EQ); + if (eq <= 0) { + goto unequal; + } + eq = PyObject_RichCompareBool(co->co_exceptiontable, + cp->co_exceptiontable, Py_EQ); + if (eq <= 0) { + goto unequal; + } if (op == Py_EQ) res = Py_True; @@ -1463,51 +1816,67 @@ code_richcompare(PyObject *self, PyObject *other, int op) res = Py_False; done: - Py_INCREF(res); - return res; + return Py_NewRef(res); } static Py_hash_t code_hash(PyCodeObject *co) { - Py_hash_t h, h0, h1, h2, h3, h4; - h0 = PyObject_Hash(co->co_name); - if (h0 == -1) return -1; - h1 = PyObject_Hash(co->co_code); - if (h1 == -1) return -1; - h2 = PyObject_Hash(co->co_consts); - if (h2 == -1) return -1; - h3 = PyObject_Hash(co->co_names); - if (h3 == -1) return -1; - h4 = PyObject_Hash(co->co_localsplusnames); - if (h4 == -1) return -1; - h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ - co->co_argcount ^ co->co_posonlyargcount ^ co->co_kwonlyargcount ^ - co->co_flags; - if (h == -1) h = -2; - return h; + Py_uhash_t uhash = 20221211; + #define SCRAMBLE_IN(H) do { \ + uhash ^= (Py_uhash_t)(H); \ + uhash *= _PyHASH_MULTIPLIER; \ + } while (0) + #define SCRAMBLE_IN_HASH(EXPR) do { \ + Py_hash_t h = PyObject_Hash(EXPR); \ + if (h == -1) { \ + return -1; \ + } \ + SCRAMBLE_IN(h); \ + } while (0) + + SCRAMBLE_IN_HASH(co->co_name); + SCRAMBLE_IN_HASH(co->co_consts); + SCRAMBLE_IN_HASH(co->co_names); + SCRAMBLE_IN_HASH(co->co_localsplusnames); + SCRAMBLE_IN_HASH(co->co_linetable); + SCRAMBLE_IN_HASH(co->co_exceptiontable); + SCRAMBLE_IN(co->co_argcount); + SCRAMBLE_IN(co->co_posonlyargcount); + SCRAMBLE_IN(co->co_kwonlyargcount); + SCRAMBLE_IN(co->co_flags); + SCRAMBLE_IN(co->co_firstlineno); + SCRAMBLE_IN(Py_SIZE(co)); + for (int i = 0; i < Py_SIZE(co); i++) { + int deop = _PyOpcode_Deopt[_Py_OPCODE(_PyCode_CODE(co)[i])]; + SCRAMBLE_IN(deop); + SCRAMBLE_IN(_Py_OPARG(_PyCode_CODE(co)[i])); + i += _PyOpcode_Caches[deop]; + } + if ((Py_hash_t)uhash == -1) { + return -2; + } + return (Py_hash_t)uhash; } #define OFF(x) offsetof(PyCodeObject, x) static PyMemberDef code_memberlist[] = { - {"co_argcount", T_INT, OFF(co_argcount), READONLY}, - {"co_posonlyargcount", T_INT, OFF(co_posonlyargcount), READONLY}, - {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), READONLY}, - {"co_stacksize",T_INT, OFF(co_stacksize), READONLY}, - {"co_flags", T_INT, OFF(co_flags), READONLY}, - {"co_code", T_OBJECT, OFF(co_code), READONLY}, - {"co_consts", T_OBJECT, OFF(co_consts), READONLY}, - {"co_names", T_OBJECT, OFF(co_names), READONLY}, - {"co_filename", T_OBJECT, OFF(co_filename), READONLY}, - {"co_name", T_OBJECT, OFF(co_name), READONLY}, - {"co_qualname", T_OBJECT, OFF(co_qualname), READONLY}, - {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY}, - {"co_linetable", T_OBJECT, OFF(co_linetable), READONLY}, - {"co_endlinetable", T_OBJECT, OFF(co_endlinetable), READONLY}, - {"co_columntable", T_OBJECT, OFF(co_columntable), READONLY}, - {"co_exceptiontable", T_OBJECT, OFF(co_exceptiontable), READONLY}, + {"co_argcount", T_INT, OFF(co_argcount), READONLY}, + {"co_posonlyargcount", T_INT, OFF(co_posonlyargcount), READONLY}, + {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), READONLY}, + {"co_stacksize", T_INT, OFF(co_stacksize), READONLY}, + {"co_flags", T_INT, OFF(co_flags), READONLY}, + {"co_nlocals", T_INT, OFF(co_nlocals), READONLY}, + {"co_consts", T_OBJECT, OFF(co_consts), READONLY}, + {"co_names", T_OBJECT, OFF(co_names), READONLY}, + {"co_filename", T_OBJECT, OFF(co_filename), READONLY}, + {"co_name", T_OBJECT, OFF(co_name), READONLY}, + {"co_qualname", T_OBJECT, OFF(co_qualname), READONLY}, + {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY}, + {"co_linetable", T_OBJECT, OFF(co_linetable), READONLY}, + {"co_exceptiontable", T_OBJECT, OFF(co_exceptiontable), READONLY}, {NULL} /* Sentinel */ }; @@ -1518,12 +1887,6 @@ code_getlnotab(PyCodeObject *code, void *closure) return decode_linetable(code); } -static PyObject * -code_getnlocals(PyCodeObject *code, void *closure) -{ - return PyLong_FromLong(code->co_nlocals); -} - static PyObject * code_getvarnames(PyCodeObject *code, void *closure) { @@ -1542,13 +1905,27 @@ code_getfreevars(PyCodeObject *code, void *closure) return _PyCode_GetFreevars(code); } +static PyObject * +code_getcodeadaptive(PyCodeObject *code, void *closure) +{ + return PyBytes_FromStringAndSize(code->co_code_adaptive, + _PyCode_NBYTES(code)); +} + +static PyObject * +code_getcode(PyCodeObject *code, void *closure) +{ + return _PyCode_GetCode(code); +} + static PyGetSetDef code_getsetlist[] = { - {"co_lnotab", (getter)code_getlnotab, NULL, NULL}, + {"co_lnotab", (getter)code_getlnotab, NULL, NULL}, + {"_co_code_adaptive", (getter)code_getcodeadaptive, NULL, NULL}, // The following old names are kept for backward compatibility. - {"co_nlocals", (getter)code_getnlocals, NULL, NULL}, - {"co_varnames", (getter)code_getvarnames, NULL, NULL}, - {"co_cellvars", (getter)code_getcellvars, NULL, NULL}, - {"co_freevars", (getter)code_getfreevars, NULL, NULL}, + {"co_varnames", (getter)code_getvarnames, NULL, NULL}, + {"co_cellvars", (getter)code_getcellvars, NULL, NULL}, + {"co_freevars", (getter)code_getfreevars, NULL, NULL}, + {"co_code", (getter)code_getcode, NULL, NULL}, {0} }; @@ -1556,22 +1933,13 @@ static PyGetSetDef code_getsetlist[] = { static PyObject * code_sizeof(PyCodeObject *co, PyObject *Py_UNUSED(args)) { - Py_ssize_t res = _PyObject_SIZE(Py_TYPE(co)); - + size_t res = _PyObject_VAR_SIZE(Py_TYPE(co), Py_SIZE(co)); _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) co->co_extra; if (co_extra != NULL) { - res += sizeof(_PyCodeObjectExtra) + - (co_extra->ce_size-1) * sizeof(co_extra->ce_extras[0]); + res += sizeof(_PyCodeObjectExtra); + res += ((size_t)co_extra->ce_size - 1) * sizeof(co_extra->ce_extras[0]); } - - if (co->co_quickened != NULL) { - Py_ssize_t count = co->co_quickened[0].entry.zero.cache_count; - count += (PyBytes_GET_SIZE(co->co_code)+sizeof(SpecializedCacheEntry)-1)/ - sizeof(SpecializedCacheEntry); - res += count * sizeof(SpecializedCacheEntry); - } - - return PyLong_FromSsize_t(res); + return PyLong_FromSize_t(res); } static PyObject * @@ -1591,18 +1959,16 @@ code.replace co_stacksize: int(c_default="self->co_stacksize") = -1 co_flags: int(c_default="self->co_flags") = -1 co_firstlineno: int(c_default="self->co_firstlineno") = -1 - co_code: PyBytesObject(c_default="(PyBytesObject *)self->co_code") = None + co_code: PyBytesObject(c_default="NULL") = None co_consts: object(subclass_of="&PyTuple_Type", c_default="self->co_consts") = None co_names: object(subclass_of="&PyTuple_Type", c_default="self->co_names") = None - co_varnames: object(subclass_of="&PyTuple_Type", c_default="self->co_varnames") = None - co_freevars: object(subclass_of="&PyTuple_Type", c_default="self->co_freevars") = None - co_cellvars: object(subclass_of="&PyTuple_Type", c_default="self->co_cellvars") = None + co_varnames: object(subclass_of="&PyTuple_Type", c_default="NULL") = None + co_freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = None + co_cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = None co_filename: unicode(c_default="self->co_filename") = None co_name: unicode(c_default="self->co_name") = None co_qualname: unicode(c_default="self->co_qualname") = None co_linetable: PyBytesObject(c_default="(PyBytesObject *)self->co_linetable") = None - co_endlinetable: object(c_default="self->co_endlinetable") = None - co_columntable: object(c_default="self->co_columntable") = None co_exceptiontable: PyBytesObject(c_default="(PyBytesObject *)self->co_exceptiontable") = None Return a copy of the code object with new values for the specified fields. @@ -1617,9 +1983,9 @@ code_replace_impl(PyCodeObject *self, int co_argcount, PyObject *co_varnames, PyObject *co_freevars, PyObject *co_cellvars, PyObject *co_filename, PyObject *co_name, PyObject *co_qualname, - PyBytesObject *co_linetable, PyObject *co_endlinetable, - PyObject *co_columntable, PyBytesObject *co_exceptiontable) -/*[clinic end generated code: output=f046bf0be3bab91f input=a63d09f248f00794]*/ + PyBytesObject *co_linetable, + PyBytesObject *co_exceptiontable) +/*[clinic end generated code: output=b6cd9988391d5711 input=f6f68e03571f8d7c]*/ { #define CHECK_INT_ARG(ARG) \ if (ARG < 0) { \ @@ -1638,8 +2004,17 @@ code_replace_impl(PyCodeObject *self, int co_argcount, #undef CHECK_INT_ARG - if (PySys_Audit("code.__new__", "OOOOiiiiii", - co_code, co_filename, co_name, co_qualname, co_argcount, + PyObject *code = NULL; + if (co_code == NULL) { + code = _PyCode_GetCode(self); + if (code == NULL) { + return NULL; + } + co_code = (PyBytesObject *)code; + } + + if (PySys_Audit("code.__new__", "OOOiiiiii", + co_code, co_filename, co_name, co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags) < 0) { return NULL; @@ -1671,26 +2046,15 @@ code_replace_impl(PyCodeObject *self, int co_argcount, co_freevars = freevars; } - if (!Py_IsNone(co_endlinetable) && !PyBytes_Check(co_endlinetable)) { - PyErr_SetString(PyExc_ValueError, - "co_endlinetable must be None or bytes"); - goto error; - } - if (!Py_IsNone(co_columntable) && !PyBytes_Check(co_columntable)) { - PyErr_SetString(PyExc_ValueError, - "co_columntable must be None or bytes"); - goto error; - } - co = PyCode_NewWithPosOnlyArgs( co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags, (PyObject*)co_code, co_consts, co_names, co_varnames, co_freevars, co_cellvars, co_filename, co_name, - co_qualname, co_firstlineno, (PyObject*)co_linetable, - (PyObject*)co_endlinetable, (PyObject*)co_columntable, - (PyObject*)co_exceptiontable); + co_qualname, co_firstlineno, + (PyObject*)co_linetable, (PyObject*)co_exceptiontable); error: + Py_XDECREF(code); Py_XDECREF(varnames); Py_XDECREF(cellvars); Py_XDECREF(freevars); @@ -1715,8 +2079,7 @@ code__varname_from_oparg_impl(PyCodeObject *self, int oparg) if (name == NULL) { return NULL; } - Py_INCREF(name); - return name; + return Py_NewRef(name); } /* XXX code objects need to participate in GC? */ @@ -1734,8 +2097,8 @@ static struct PyMethodDef code_methods[] = { PyTypeObject PyCode_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "code", - sizeof(PyCodeObject), - 0, + offsetof(PyCodeObject, co_code_adaptive), + sizeof(_Py_CODEUNIT), (destructor)code_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ @@ -1791,8 +2154,7 @@ _PyCode_ConstantKey(PyObject *op) { /* Objects of these types are always different from object of other * type and from tuples. */ - Py_INCREF(op); - key = op; + key = Py_NewRef(op); } else if (PyBool_Check(op) || PyBytes_CheckExact(op)) { /* Make booleans different from integers 0 and 1. @@ -1906,3 +2268,121 @@ _PyCode_ConstantKey(PyObject *op) } return key; } + +void +_PyStaticCode_Fini(PyCodeObject *co) +{ + deopt_code(_PyCode_CODE(co), Py_SIZE(co)); + PyMem_Free(co->co_extra); + if (co->_co_cached != NULL) { + Py_CLEAR(co->_co_cached->_co_code); + Py_CLEAR(co->_co_cached->_co_cellvars); + Py_CLEAR(co->_co_cached->_co_freevars); + Py_CLEAR(co->_co_cached->_co_varnames); + PyMem_Free(co->_co_cached); + co->_co_cached = NULL; + } + co->co_extra = NULL; + if (co->co_weakreflist != NULL) { + PyObject_ClearWeakRefs((PyObject *)co); + co->co_weakreflist = NULL; + } + if (co->_co_linearray) { + PyMem_Free(co->_co_linearray); + co->_co_linearray = NULL; + } +} + +int +_PyStaticCode_Init(PyCodeObject *co) +{ + int res = intern_strings(co->co_names); + if (res < 0) { + return -1; + } + res = intern_string_constants(co->co_consts, NULL); + if (res < 0) { + return -1; + } + res = intern_strings(co->co_localsplusnames); + if (res < 0) { + return -1; + } + _PyCode_Quicken(co); + return 0; +} + +#define MAX_CODE_UNITS_PER_LOC_ENTRY 8 + +PyCodeObject * +_Py_MakeShimCode(const _PyShimCodeDef *codedef) +{ + PyObject *name = NULL; + PyObject *co_code = NULL; + PyObject *lines = NULL; + PyCodeObject *codeobj = NULL; + uint8_t *loc_table = NULL; + + name = _PyUnicode_FromASCII(codedef->cname, strlen(codedef->cname)); + if (name == NULL) { + goto cleanup; + } + co_code = PyBytes_FromStringAndSize( + (const char *)codedef->code, codedef->codelen); + if (co_code == NULL) { + goto cleanup; + } + int code_units = codedef->codelen / sizeof(_Py_CODEUNIT); + int loc_entries = (code_units + MAX_CODE_UNITS_PER_LOC_ENTRY - 1) / + MAX_CODE_UNITS_PER_LOC_ENTRY; + loc_table = PyMem_Malloc(loc_entries); + if (loc_table == NULL) { + PyErr_NoMemory(); + goto cleanup; + } + for (int i = 0; i < loc_entries-1; i++) { + loc_table[i] = 0x80 | (PY_CODE_LOCATION_INFO_NONE << 3) | 7; + code_units -= MAX_CODE_UNITS_PER_LOC_ENTRY; + } + assert(loc_entries > 0); + assert(code_units > 0 && code_units <= MAX_CODE_UNITS_PER_LOC_ENTRY); + loc_table[loc_entries-1] = 0x80 | + (PY_CODE_LOCATION_INFO_NONE << 3) | (code_units-1); + lines = PyBytes_FromStringAndSize((const char *)loc_table, loc_entries); + PyMem_Free(loc_table); + if (lines == NULL) { + goto cleanup; + } + _Py_DECLARE_STR(shim_name, ""); + struct _PyCodeConstructor con = { + .filename = &_Py_STR(shim_name), + .name = name, + .qualname = name, + .flags = CO_NEWLOCALS | CO_OPTIMIZED, + + .code = co_code, + .firstlineno = 1, + .linetable = lines, + + .consts = (PyObject *)&_Py_SINGLETON(tuple_empty), + .names = (PyObject *)&_Py_SINGLETON(tuple_empty), + + .localsplusnames = (PyObject *)&_Py_SINGLETON(tuple_empty), + .localspluskinds = (PyObject *)&_Py_SINGLETON(bytes_empty), + + .argcount = 0, + .posonlyargcount = 0, + .kwonlyargcount = 0, + + .stacksize = codedef->stacksize, + + .exceptiontable = (PyObject *)&_Py_SINGLETON(bytes_empty), + }; + + codeobj = _PyCode_New(&con); +cleanup: + Py_XDECREF(name); + Py_XDECREF(co_code); + Py_XDECREF(lines); + return codeobj; +} diff --git a/Objects/complexobject.c b/Objects/complexobject.c index f658dbf336d..aee03ddfb07 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -281,9 +281,8 @@ static PyObject * try_complex_special_method(PyObject *op) { PyObject *f; - _Py_IDENTIFIER(__complex__); - f = _PyObject_LookupSpecial(op, &PyId___complex__); + f = _PyObject_LookupSpecial(op, &_Py_ID(__complex__)); if (f) { PyObject *res = _PyObject_CallNoArgs(f); Py_DECREF(f); @@ -450,8 +449,7 @@ to_complex(PyObject **pobj, Py_complex *pc) pc->real = PyFloat_AsDouble(obj); return 0; } - Py_INCREF(Py_NotImplemented); - *pobj = Py_NotImplemented; + *pobj = Py_NewRef(Py_NotImplemented); return -1; } @@ -554,8 +552,7 @@ static PyObject * complex_pos(PyComplexObject *v) { if (PyComplex_CheckExact(v)) { - Py_INCREF(v); - return (PyObject *)v; + return Py_NewRef(v); } else return PyComplex_FromCComplex(v->cval); @@ -632,8 +629,7 @@ complex_richcompare(PyObject *v, PyObject *w, int op) else res = Py_False; - Py_INCREF(res); - return res; + return Py_NewRef(res); Unimplemented: Py_RETURN_NOTIMPLEMENTED; @@ -706,8 +702,7 @@ complex___complex___impl(PyComplexObject *self) /*[clinic end generated code: output=e6b35ba3d275dc9c input=3589ada9d27db854]*/ { if (PyComplex_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else { return PyComplex_FromCComplex(self->cval); @@ -846,7 +841,7 @@ complex_from_string_inner(const char *s, Py_ssize_t len, void *type) if (s-start != len) goto parse_error; - return complex_subtype_from_doubles((PyTypeObject *)type, x, y); + return complex_subtype_from_doubles(_PyType_CAST(type), x, y); parse_error: PyErr_SetString(PyExc_ValueError, @@ -918,8 +913,7 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) to exact complexes here. If either the input or the output is a complex subclass, it will be handled below as a non-orthogonal vector. */ - Py_INCREF(r); - return r; + return Py_NewRef(r); } if (PyUnicode_Check(r)) { if (i != NULL) { diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 946ea6aa803..334be75e8df 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -1,13 +1,12 @@ /* Descriptors -- a new, flexible way to describe attributes */ #include "Python.h" -#include "pycore_ceval.h" // _Py_EnterRecursiveCall() +#include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "structmember.h" // PyMemberDef - -_Py_IDENTIFIER(getattr); +#include "pycore_descrobject.h" /*[clinic input] class mappingproxy "mappingproxyobject *" "&PyDictProxy_Type" @@ -15,6 +14,25 @@ class property "propertyobject *" "&PyProperty_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=556352653fd4c02e]*/ +// see pycore_object.h +#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) +#include +EM_JS(int, descr_set_trampoline_call, (setter set, PyObject *obj, PyObject *value, void *closure), { + return wasmTable.get(set)(obj, value, closure); +}); + +EM_JS(PyObject*, descr_get_trampoline_call, (getter get, PyObject *obj, void *closure), { + return wasmTable.get(get)(obj, closure); +}); +#else +#define descr_set_trampoline_call(set, obj, value, closure) \ + (set)((obj), (value), (closure)) + +#define descr_get_trampoline_call(get, obj, closure) \ + (get)((obj), (closure)) + +#endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE + static void descr_dealloc(PyDescrObject *descr) { @@ -182,7 +200,8 @@ getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) return NULL; } if (descr->d_getset->get != NULL) - return descr->d_getset->get(obj, descr->d_getset->closure); + return descr_get_trampoline_call( + descr->d_getset->get, obj, descr->d_getset->closure); PyErr_Format(PyExc_AttributeError, "attribute '%V' of '%.100s' objects is not readable", descr_name((PyDescrObject *)descr), "?", @@ -234,8 +253,9 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) return -1; } if (descr->d_getset->set != NULL) { - return descr->d_getset->set(obj, value, - descr->d_getset->closure); + return descr_set_trampoline_call( + descr->d_getset->set, obj, value, + descr->d_getset->closure); } PyErr_Format(PyExc_AttributeError, "attribute '%V' of '%.100s' objects is not writable", @@ -283,7 +303,7 @@ typedef void (*funcptr)(void); static inline funcptr method_enter_call(PyThreadState *tstate, PyObject *func) { - if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) { + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { return NULL; } return (funcptr)((PyMethodDescrObject *)func)->d_method->ml_meth; @@ -308,9 +328,10 @@ method_vectorcall_VARARGS( Py_DECREF(argstuple); return NULL; } - PyObject *result = meth(args[0], argstuple); + PyObject *result = _PyCFunction_TrampolineCall( + meth, args[0], argstuple); Py_DECREF(argstuple); - _Py_LeaveRecursiveCall(tstate); + _Py_LeaveRecursiveCallTstate(tstate); return result; } @@ -341,8 +362,9 @@ method_vectorcall_VARARGS_KEYWORDS( if (meth == NULL) { goto exit; } - result = meth(args[0], argstuple, kwdict); - _Py_LeaveRecursiveCall(tstate); + result = _PyCFunctionWithKeywords_TrampolineCall( + meth, args[0], argstuple, kwdict); + _Py_LeaveRecursiveCallTstate(tstate); exit: Py_DECREF(argstuple); Py_XDECREF(kwdict); @@ -365,7 +387,7 @@ method_vectorcall_FASTCALL_KEYWORDS_METHOD( PyObject *result = meth(args[0], ((PyMethodDescrObject *)func)->d_common.d_type, args+1, nargs-1, kwnames); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); return result; } @@ -384,7 +406,7 @@ method_vectorcall_FASTCALL( return NULL; } PyObject *result = meth(args[0], args+1, nargs-1); - _Py_LeaveRecursiveCall(tstate); + _Py_LeaveRecursiveCallTstate(tstate); return result; } @@ -403,7 +425,7 @@ method_vectorcall_FASTCALL_KEYWORDS( return NULL; } PyObject *result = meth(args[0], args+1, nargs-1, kwnames); - _Py_LeaveRecursiveCall(tstate); + _Py_LeaveRecursiveCallTstate(tstate); return result; } @@ -429,8 +451,8 @@ method_vectorcall_NOARGS( if (meth == NULL) { return NULL; } - PyObject *result = meth(args[0], NULL); - _Py_LeaveRecursiveCall(tstate); + PyObject *result = _PyCFunction_TrampolineCall(meth, args[0], NULL); + _Py_LeaveRecursiveCallTstate(tstate); return result; } @@ -457,8 +479,8 @@ method_vectorcall_O( if (meth == NULL) { return NULL; } - PyObject *result = meth(args[0], args[1]); - _Py_LeaveRecursiveCall(tstate); + PyObject *result = _PyCFunction_TrampolineCall(meth, args[0], args[1]); + _Py_LeaveRecursiveCallTstate(tstate); return result; } @@ -571,7 +593,6 @@ static PyObject * calculate_qualname(PyDescrObject *descr) { PyObject *type_qualname, *res; - _Py_IDENTIFIER(__qualname__); if (descr->d_name == NULL || !PyUnicode_Check(descr->d_name)) { PyErr_SetString(PyExc_TypeError, @@ -579,8 +600,8 @@ calculate_qualname(PyDescrObject *descr) return NULL; } - type_qualname = _PyObject_GetAttrId((PyObject *)descr->d_type, - &PyId___qualname__); + type_qualname = PyObject_GetAttr( + (PyObject *)descr->d_type, &_Py_ID(__qualname__)); if (type_qualname == NULL) return NULL; @@ -601,14 +622,13 @@ descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored)) { if (descr->d_qualname == NULL) descr->d_qualname = calculate_qualname(descr); - Py_XINCREF(descr->d_qualname); - return descr->d_qualname; + return Py_XNewRef(descr->d_qualname); } static PyObject * descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored)) { - return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr), + return Py_BuildValue("N(OO)", _PyEval_GetBuiltin(&_Py_ID(getattr)), PyDescr_TYPE(descr), PyDescr_NAME(descr)); } @@ -755,7 +775,7 @@ PyTypeObject PyClassMethodDescr_Type = { 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - descr_methods, /* tp_methods */ + 0, /* tp_methods */ descr_members, /* tp_members */ method_getset, /* tp_getset */ 0, /* tp_base */ @@ -883,12 +903,10 @@ descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name) descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0); if (descr != NULL) { - Py_XINCREF(type); - descr->d_type = type; + descr->d_type = (PyTypeObject*)Py_XNewRef(type); descr->d_name = PyUnicode_InternFromString(name); if (descr->d_name == NULL) { - Py_DECREF(descr); - descr = NULL; + Py_SETREF(descr, NULL); } else { descr->d_qualname = NULL; @@ -1086,8 +1104,7 @@ mappingproxy_get(mappingproxyobject *pp, PyObject *const *args, Py_ssize_t nargs { return NULL; } - _Py_IDENTIFIER(get); - return _PyObject_VectorcallMethodId(&PyId_get, newargs, + return _PyObject_VectorcallMethod(&_Py_ID(get), newargs, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); } @@ -1095,51 +1112,46 @@ mappingproxy_get(mappingproxyobject *pp, PyObject *const *args, Py_ssize_t nargs static PyObject * mappingproxy_keys(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(keys); - return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_keys); + return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(keys)); } static PyObject * mappingproxy_values(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(values); - return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_values); + return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(values)); } static PyObject * mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(items); - return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_items); + return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(items)); } static PyObject * mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(copy); - return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_copy); + return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(copy)); } static PyObject * mappingproxy_reversed(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(__reversed__); - return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId___reversed__); + return PyObject_CallMethodNoArgs(pp->mapping, &_Py_ID(__reversed__)); } /* WARNING: mappingproxy methods must not give access to the underlying mapping */ static PyMethodDef mappingproxy_methods[] = { - {"get", (PyCFunction)(void(*)(void))mappingproxy_get, METH_FASTCALL, + {"get", _PyCFunction_CAST(mappingproxy_get), METH_FASTCALL, PyDoc_STR("D.get(k[,d]) -> D[k] if k in D, else d." " d defaults to None.")}, {"keys", (PyCFunction)mappingproxy_keys, METH_NOARGS, - PyDoc_STR("D.keys() -> list of D's keys")}, + PyDoc_STR("D.keys() -> a set-like object providing a view on D's keys")}, {"values", (PyCFunction)mappingproxy_values, METH_NOARGS, - PyDoc_STR("D.values() -> list of D's values")}, + PyDoc_STR("D.values() -> an object providing a view on D's values")}, {"items", (PyCFunction)mappingproxy_items, METH_NOARGS, - PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")}, + PyDoc_STR("D.items() -> a set-like object providing a view on D's items")}, {"copy", (PyCFunction)mappingproxy_copy, METH_NOARGS, PyDoc_STR("D.copy() -> a shallow copy of D")}, {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, @@ -1163,6 +1175,12 @@ mappingproxy_getiter(mappingproxyobject *pp) return PyObject_GetIter(pp->mapping); } +static Py_hash_t +mappingproxy_hash(mappingproxyobject *pp) +{ + return PyObject_Hash(pp->mapping); +} + static PyObject * mappingproxy_str(mappingproxyobject *pp) { @@ -1223,8 +1241,7 @@ mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping) mappingproxy = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type); if (mappingproxy == NULL) return NULL; - Py_INCREF(mapping); - mappingproxy->mapping = mapping; + mappingproxy->mapping = Py_NewRef(mapping); _PyObject_GC_TRACK(mappingproxy); return (PyObject *)mappingproxy; } @@ -1239,8 +1256,7 @@ PyDictProxy_New(PyObject *mapping) pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type); if (pp != NULL) { - Py_INCREF(mapping); - pp->mapping = mapping; + pp->mapping = Py_NewRef(mapping); _PyObject_GC_TRACK(pp); } return (PyObject *)pp; @@ -1321,7 +1337,7 @@ wrapper_repr(wrapperobject *wp) static PyObject * wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored)) { - return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr), + return Py_BuildValue("N(OO)", _PyEval_GetBuiltin(&_Py_ID(getattr)), wp->self, PyDescr_NAME(wp->descr)); } @@ -1340,8 +1356,7 @@ wrapper_objclass(wrapperobject *wp, void *Py_UNUSED(ignored)) { PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr); - Py_INCREF(c); - return c; + return Py_NewRef(c); } static PyObject * @@ -1445,10 +1460,8 @@ PyWrapper_New(PyObject *d, PyObject *self) wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type); if (wp != NULL) { - Py_INCREF(descr); - wp->descr = descr; - Py_INCREF(self); - wp->self = self; + wp->descr = (PyWrapperDescrObject*)Py_NewRef(descr); + wp->self = Py_NewRef(self); _PyObject_GC_TRACK(wp); } return (PyObject *)wp; @@ -1472,31 +1485,21 @@ class property(object): if inst is None: return self if self.__get is None: - raise AttributeError, "unreadable attribute" + raise AttributeError, "property has no getter" return self.__get(inst) def __set__(self, inst, value): if self.__set is None: - raise AttributeError, "can't set attribute" + raise AttributeError, "property has no setter" return self.__set(inst, value) def __delete__(self, inst): if self.__del is None: - raise AttributeError, "can't delete attribute" + raise AttributeError, "property has no deleter" return self.__del(inst) */ -typedef struct { - PyObject_HEAD - PyObject *prop_get; - PyObject *prop_set; - PyObject *prop_del; - PyObject *prop_doc; - PyObject *prop_name; - int getter_doc; -} propertyobject; - static PyObject * property_copy(PyObject *, PyObject *, PyObject *, PyObject *); @@ -1510,7 +1513,7 @@ static PyMemberDef property_members[] = { PyDoc_STRVAR(getter_doc, - "Descriptor to change the getter on a property."); + "Descriptor to obtain a copy of the property with a different getter."); static PyObject * property_getter(PyObject *self, PyObject *getter) @@ -1520,7 +1523,7 @@ property_getter(PyObject *self, PyObject *getter) PyDoc_STRVAR(setter_doc, - "Descriptor to change the setter on a property."); + "Descriptor to obtain a copy of the property with a different setter."); static PyObject * property_setter(PyObject *self, PyObject *setter) @@ -1530,7 +1533,7 @@ property_setter(PyObject *self, PyObject *setter) PyDoc_STRVAR(deleter_doc, - "Descriptor to change the deleter on a property."); + "Descriptor to obtain a copy of the property with a different deleter."); static PyObject * property_deleter(PyObject *self, PyObject *deleter) @@ -1555,8 +1558,7 @@ property_set_name(PyObject *self, PyObject *args) { propertyobject *prop = (propertyobject *)self; PyObject *name = PyTuple_GET_ITEM(args, 1); - Py_XINCREF(name); - Py_XSETREF(prop->prop_name, name); + Py_XSETREF(prop->prop_name, Py_XNewRef(name)); Py_RETURN_NONE; } @@ -1588,18 +1590,27 @@ static PyObject * property_descr_get(PyObject *self, PyObject *obj, PyObject *type) { if (obj == NULL || obj == Py_None) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } propertyobject *gs = (propertyobject *)self; if (gs->prop_get == NULL) { - if (gs->prop_name != NULL) { - PyErr_Format(PyExc_AttributeError, "unreadable attribute %R", gs->prop_name); - } else { - PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); + PyObject *qualname = PyType_GetQualName(Py_TYPE(obj)); + if (gs->prop_name != NULL && qualname != NULL) { + PyErr_Format(PyExc_AttributeError, + "property %R of %R object has no getter", + gs->prop_name, + qualname); } - + else if (qualname != NULL) { + PyErr_Format(PyExc_AttributeError, + "property of %R object has no getter", + qualname); + } else { + PyErr_SetString(PyExc_AttributeError, + "property has no getter"); + } + Py_XDECREF(qualname); return NULL; } @@ -1620,19 +1631,32 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value) } if (func == NULL) { - if (gs->prop_name != NULL) { + PyObject *qualname = NULL; + if (obj != NULL) { + qualname = PyType_GetQualName(Py_TYPE(obj)); + } + if (gs->prop_name != NULL && qualname != NULL) { PyErr_Format(PyExc_AttributeError, value == NULL ? - "can't delete attribute %R" : - "can't set attribute %R", - gs->prop_name); + "property %R of %R object has no deleter" : + "property %R of %R object has no setter", + gs->prop_name, + qualname); + } + else if (qualname != NULL) { + PyErr_Format(PyExc_AttributeError, + value == NULL ? + "property of %R object has no deleter" : + "property of %R object has no setter", + qualname); } else { PyErr_SetString(PyExc_AttributeError, - value == NULL ? - "can't delete attribute" : - "can't set attribute"); + value == NULL ? + "property has no deleter" : + "property has no setter"); } + Py_XDECREF(qualname); return -1; } @@ -1640,6 +1664,7 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value) res = PyObject_CallOneArg(func, obj); } else { + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); PyObject *args[] = { obj, value }; res = PyObject_Vectorcall(func, args, 2, NULL); } @@ -1687,8 +1712,9 @@ property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del) if (new == NULL) return NULL; - Py_XINCREF(pold->prop_name); - Py_XSETREF(((propertyobject *) new)->prop_name, pold->prop_name); + if (PyObject_TypeCheck((new), &PyProperty_Type)) { + Py_XSETREF(((propertyobject *) new)->prop_name, Py_XNewRef(pold->prop_name)); + } return new; } @@ -1741,41 +1767,52 @@ property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset, if (fdel == Py_None) fdel = NULL; - Py_XINCREF(fget); - Py_XINCREF(fset); - Py_XINCREF(fdel); - Py_XINCREF(doc); - - Py_XSETREF(self->prop_get, fget); - Py_XSETREF(self->prop_set, fset); - Py_XSETREF(self->prop_del, fdel); - Py_XSETREF(self->prop_doc, doc); + Py_XSETREF(self->prop_get, Py_XNewRef(fget)); + Py_XSETREF(self->prop_set, Py_XNewRef(fset)); + Py_XSETREF(self->prop_del, Py_XNewRef(fdel)); + Py_XSETREF(self->prop_doc, NULL); Py_XSETREF(self->prop_name, NULL); self->getter_doc = 0; + PyObject *prop_doc = NULL; + if (doc != NULL && doc != Py_None) { + prop_doc = Py_XNewRef(doc); + } /* if no docstring given and the getter has one, use that one */ - if ((doc == NULL || doc == Py_None) && fget != NULL) { - _Py_IDENTIFIER(__doc__); - PyObject *get_doc; - int rc = _PyObject_LookupAttrId(fget, &PyId___doc__, &get_doc); + else if (fget != NULL) { + int rc = _PyObject_LookupAttr(fget, &_Py_ID(__doc__), &prop_doc); if (rc <= 0) { return rc; } - if (Py_IS_TYPE(self, &PyProperty_Type)) { - Py_XSETREF(self->prop_doc, get_doc); + if (prop_doc == Py_None) { + prop_doc = NULL; + Py_DECREF(Py_None); } - else { - /* If this is a property subclass, put __doc__ - in dict of the subclass instance instead, - otherwise it gets shadowed by __doc__ in the - class's dict. */ - int err = _PyObject_SetAttrId((PyObject *)self, &PyId___doc__, get_doc); - Py_DECREF(get_doc); - if (err < 0) - return -1; + if (prop_doc != NULL){ + self->getter_doc = 1; } - self->getter_doc = 1; + } + + /* At this point `prop_doc` is either NULL or + a non-None object with incremented ref counter */ + + if (Py_IS_TYPE(self, &PyProperty_Type)) { + Py_XSETREF(self->prop_doc, prop_doc); + } else { + /* If this is a property subclass, put __doc__ + in dict of the subclass instance instead, + otherwise it gets shadowed by __doc__ in the + class's dict. */ + + if (prop_doc == NULL) { + prop_doc = Py_NewRef(Py_None); + } + int err = PyObject_SetAttr( + (PyObject *)self, &_Py_ID(__doc__), prop_doc); + Py_XDECREF(prop_doc); + if (err < 0) + return -1; } return 0; @@ -1855,7 +1892,7 @@ PyTypeObject PyDictProxy_Type = { &mappingproxy_as_number, /* tp_as_number */ &mappingproxy_as_sequence, /* tp_as_sequence */ &mappingproxy_as_mapping, /* tp_as_mapping */ - 0, /* tp_hash */ + (hashfunc)mappingproxy_hash, /* tp_hash */ 0, /* tp_call */ (reprfunc)mappingproxy_str, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ diff --git a/Objects/dictnotes.txt b/Objects/dictnotes.txt index f89720c9f60..db6a3cf1d63 100644 --- a/Objects/dictnotes.txt +++ b/Objects/dictnotes.txt @@ -70,8 +70,8 @@ A values array Tunable Dictionary Parameters ----------------------------- -See comments for PyDict_MINSIZE_SPLIT, PyDict_MINSIZE_COMBINED, -USABLE_FRACTION and GROWTH_RATE in dictobject.c +See comments for PyDict_MINSIZE, USABLE_FRACTION and GROWTH_RATE in +dictobject.c Tune-ups should be measured across a broad range of applications and use cases. A change to any parameter will help in some situations and diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 475d92d3298..b9067213820 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -16,19 +16,20 @@ As of Python 3.6, this is compact and ordered. Basic idea is described here: layout: -+---------------+ -| dk_refcnt | -| dk_log2_size | -| dk_kind | -| dk_usable | -| dk_nentries | -+---------------+ -| dk_indices | -| | -+---------------+ -| dk_entries | -| | -+---------------+ ++---------------------+ +| dk_refcnt | +| dk_log2_size | +| dk_log2_index_bytes | +| dk_kind | +| dk_usable | +| dk_nentries | ++---------------------+ +| dk_indices[] | +| | ++---------------------+ +| dk_entries[] | +| | ++---------------------+ dk_indices is actual hashtable. It holds index in entries, or DKIX_EMPTY(-1) or DKIX_DUMMY(-2). @@ -39,8 +40,8 @@ Size of indices is dk_size. Type of each index in indices is vary on dk_size: * int32 for 2**16 <= dk_size <= 2**31 * int64 for 2**32 <= dk_size -dk_entries is array of PyDictKeyEntry. Its size is USABLE_FRACTION(dk_size). -DK_ENTRIES(dk) can be used to get pointer to entries. +dk_entries is array of PyDictKeyEntry when dk_kind == DICT_KEYS_GENERAL or +PyDictUnicodeEntry otherwise. Its length is USABLE_FRACTION(dk_size). NOTE: Since negative value is used for DKIX_EMPTY and DKIX_DUMMY, type of dk_indices entry is signed integer and int16 is used for table which @@ -114,6 +115,7 @@ As a consequence of this, split keys have a maximum size of 16. #include "Python.h" #include "pycore_bitutils.h" // _Py_bit_length #include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_code.h" // stats #include "pycore_dict.h" // PyDictKeysObject #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() #include "pycore_object.h" // _PyObject_GC_TRACK() @@ -121,6 +123,8 @@ As a consequence of this, split keys have a maximum size of 16. #include "pycore_pystate.h" // _PyThreadState_GET() #include "stringlib/eq.h" // unicode_eq() +#include + /*[clinic input] class dict "PyDictObject *" "&PyDict_Type" [clinic start generated code]*/ @@ -228,15 +232,10 @@ equally good collision statistics, needed less code & used less memory. */ -static int dictresize(PyDictObject *mp, uint8_t log_newsize); +static int dictresize(PyDictObject *mp, uint8_t log_newsize, int unicode); static PyObject* dict_iter(PyDictObject *dict); -/*Global counter used to set ma_version_tag field of dictionary. - * It is incremented each time that a dictionary is created and each - * time that a dictionary is modified. */ -uint64_t _pydict_global_version = 0; - #include "clinic/dictobject.c.h" @@ -278,6 +277,12 @@ _PyDict_Fini(PyInterpreterState *interp) #endif } +static inline Py_hash_t +unicode_get_hash(PyObject *o) +{ + assert(PyUnicode_CheckExact(o)); + return _PyASCIIObject_CAST(o)->hash; +} /* Print summary info about the state of the optimized allocator */ void @@ -291,7 +296,6 @@ _PyDict_DebugMallocStats(FILE *out) } #define DK_MASK(dk) (DK_SIZE(dk)-1) -#define IS_POWER_OF_2(x) (((x) & (x-1)) == 0) static void free_keys_object(PyDictKeysObject *keys); @@ -320,19 +324,19 @@ dictkeys_decref(PyDictKeysObject *dk) static inline Py_ssize_t dictkeys_get_index(const PyDictKeysObject *keys, Py_ssize_t i) { - Py_ssize_t s = DK_SIZE(keys); + int log2size = DK_LOG_SIZE(keys); Py_ssize_t ix; - if (s <= 0xff) { + if (log2size < 8) { const int8_t *indices = (const int8_t*)(keys->dk_indices); ix = indices[i]; } - else if (s <= 0xffff) { + else if (log2size < 16) { const int16_t *indices = (const int16_t*)(keys->dk_indices); ix = indices[i]; } #if SIZEOF_VOID_P > 4 - else if (s > 0xffffffff) { + else if (log2size >= 32) { const int64_t *indices = (const int64_t*)(keys->dk_indices); ix = indices[i]; } @@ -349,23 +353,23 @@ dictkeys_get_index(const PyDictKeysObject *keys, Py_ssize_t i) static inline void dictkeys_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix) { - Py_ssize_t s = DK_SIZE(keys); + int log2size = DK_LOG_SIZE(keys); assert(ix >= DKIX_DUMMY); assert(keys->dk_version == 0); - if (s <= 0xff) { + if (log2size < 8) { int8_t *indices = (int8_t*)(keys->dk_indices); assert(ix <= 0x7f); indices[i] = (char)ix; } - else if (s <= 0xffff) { + else if (log2size < 16) { int16_t *indices = (int16_t*)(keys->dk_indices); assert(ix <= 0x7fff); indices[i] = (int16_t)ix; } #if SIZEOF_VOID_P > 4 - else if (s > 0xffffffff) { + else if (log2size >= 32) { int64_t *indices = (int64_t*)(keys->dk_indices); indices[i] = ix; } @@ -444,7 +448,8 @@ estimate_log2_keysize(Py_ssize_t n) static PyDictKeysObject empty_keys_struct = { 1, /* dk_refcnt */ 0, /* dk_log2_size */ - DICT_KEYS_SPLIT, /* dk_kind */ + 0, /* dk_log2_index_bytes */ + DICT_KEYS_UNICODE, /* dk_kind */ 1, /* dk_version */ 0, /* dk_usable (immutable) */ 0, /* dk_nentries */ @@ -452,14 +457,10 @@ static PyDictKeysObject empty_keys_struct = { DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY}, /* dk_indices */ }; - -static PyDictValues empty_values_struct = { 0, { NULL }}; -#define empty_values (&empty_values_struct) - #define Py_EMPTY_KEYS &empty_keys_struct /* Uncomment to check the dict content in _PyDict_CheckConsistency() */ -/* #define DEBUG_PYDICT */ +// #define DEBUG_PYDICT #ifdef DEBUG_PYDICT # define ASSERT_CONSISTENT(op) assert(_PyDict_CheckConsistency((PyObject *)(op), 1)) @@ -470,11 +471,28 @@ static PyDictValues empty_values_struct = { 0, { NULL }}; static inline int get_index_from_order(PyDictObject *mp, Py_ssize_t i) { - assert(mp->ma_used <= 16); - int shift = (int)(mp->ma_used-1-i)*4; - return (int)(mp->ma_values->mv_order >> shift) & 15; + assert(mp->ma_used <= SHARED_KEYS_MAX_SIZE); + assert(i < (((char *)mp->ma_values)[-2])); + return ((char *)mp->ma_values)[-3-i]; } +#ifdef DEBUG_PYDICT +static void +dump_entries(PyDictKeysObject *dk) +{ + for (Py_ssize_t i = 0; i < dk->dk_nentries; i++) { + if (DK_IS_UNICODE(dk)) { + PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(dk)[i]; + printf("key=%p value=%p\n", ep->me_key, ep->me_value); + } + else { + PyDictKeyEntry *ep = &DK_ENTRIES(dk)[i]; + printf("key=%p hash=%lx value=%p\n", ep->me_key, ep->me_hash, ep->me_value); + } + } +} +#endif + int _PyDict_CheckConsistency(PyObject *op, int check_content) { @@ -496,41 +514,56 @@ _PyDict_CheckConsistency(PyObject *op, int check_content) if (!splitted) { /* combined table */ - CHECK(keys->dk_refcnt == 1); + CHECK(keys->dk_kind != DICT_KEYS_SPLIT); + CHECK(keys->dk_refcnt == 1 || keys == Py_EMPTY_KEYS); } else { + CHECK(keys->dk_kind == DICT_KEYS_SPLIT); CHECK(mp->ma_used <= SHARED_KEYS_MAX_SIZE); } if (check_content) { - PyDictKeyEntry *entries = DK_ENTRIES(keys); - for (Py_ssize_t i=0; i < DK_SIZE(keys); i++) { Py_ssize_t ix = dictkeys_get_index(keys, i); CHECK(DKIX_DUMMY <= ix && ix <= usable); } - for (Py_ssize_t i=0; i < usable; i++) { - PyDictKeyEntry *entry = &entries[i]; - PyObject *key = entry->me_key; + if (keys->dk_kind == DICT_KEYS_GENERAL) { + PyDictKeyEntry *entries = DK_ENTRIES(keys); + for (Py_ssize_t i=0; i < usable; i++) { + PyDictKeyEntry *entry = &entries[i]; + PyObject *key = entry->me_key; - if (key != NULL) { - if (PyUnicode_CheckExact(key)) { - Py_hash_t hash = ((PyASCIIObject *)key)->hash; - CHECK(hash != -1); - CHECK(entry->me_hash == hash); - } - else { + if (key != NULL) { /* test_dict fails if PyObject_Hash() is called again */ CHECK(entry->me_hash != -1); - } - if (!splitted) { CHECK(entry->me_value != NULL); + + if (PyUnicode_CheckExact(key)) { + Py_hash_t hash = unicode_get_hash(key); + CHECK(entry->me_hash == hash); + } } } + } + else { + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(keys); + for (Py_ssize_t i=0; i < usable; i++) { + PyDictUnicodeEntry *entry = &entries[i]; + PyObject *key = entry->me_key; - if (splitted) { - CHECK(entry->me_value == NULL); + if (key != NULL) { + CHECK(PyUnicode_CheckExact(key)); + Py_hash_t hash = unicode_get_hash(key); + CHECK(hash != -1); + if (!splitted) { + CHECK(entry->me_value != NULL); + } + } + + if (splitted) { + CHECK(entry->me_value == NULL); + } } } @@ -553,27 +586,29 @@ _PyDict_CheckConsistency(PyObject *op, int check_content) static PyDictKeysObject* -new_keys_object(uint8_t log2_size) +new_keys_object(uint8_t log2_size, bool unicode) { PyDictKeysObject *dk; - Py_ssize_t es, usable; + Py_ssize_t usable; + int log2_bytes; + size_t entry_size = unicode ? sizeof(PyDictUnicodeEntry) : sizeof(PyDictKeyEntry); assert(log2_size >= PyDict_LOG_MINSIZE); usable = USABLE_FRACTION(1< 4 - else if (log2_size <= 31) { - es = 4; + else if (log2_size >= 32) { + log2_bytes = log2_size + 3; } #endif else { - es = sizeof(Py_ssize_t); + log2_bytes = log2_size + 2; } #if PyDict_MAXFREELIST > 0 @@ -582,15 +617,16 @@ new_keys_object(uint8_t log2_size) // new_keys_object() must not be called after _PyDict_Fini() assert(state->keys_numfree != -1); #endif - if (log2_size == PyDict_LOG_MINSIZE && state->keys_numfree > 0) { + if (log2_size == PyDict_LOG_MINSIZE && unicode && state->keys_numfree > 0) { dk = state->keys_free_list[--state->keys_numfree]; + OBJECT_STAT_INC(from_freelist); } else #endif { dk = PyObject_Malloc(sizeof(PyDictKeysObject) - + (es<dk_refcnt = 1; dk->dk_log2_size = log2_size; - dk->dk_kind = DICT_KEYS_UNICODE; + dk->dk_log2_index_bytes = log2_bytes; + dk->dk_kind = unicode ? DICT_KEYS_UNICODE : DICT_KEYS_GENERAL; dk->dk_nentries = 0; dk->dk_usable = usable; dk->dk_version = 0; - memset(&dk->dk_indices[0], 0xff, es<dk_indices[0], 0xff, ((size_t)1 << log2_bytes)); + memset(&dk->dk_indices[(size_t)1 << log2_bytes], 0, entry_size * usable); return dk; } static void free_keys_object(PyDictKeysObject *keys) { - PyDictKeyEntry *entries = DK_ENTRIES(keys); - Py_ssize_t i, n; - for (i = 0, n = keys->dk_nentries; i < n; i++) { - Py_XDECREF(entries[i].me_key); - Py_XDECREF(entries[i].me_value); + assert(keys != Py_EMPTY_KEYS); + if (DK_IS_UNICODE(keys)) { + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(keys); + Py_ssize_t i, n; + for (i = 0, n = keys->dk_nentries; i < n; i++) { + Py_XDECREF(entries[i].me_key); + Py_XDECREF(entries[i].me_value); + } + } + else { + PyDictKeyEntry *entries = DK_ENTRIES(keys); + Py_ssize_t i, n; + for (i = 0, n = keys->dk_nentries; i < n; i++) { + Py_XDECREF(entries[i].me_key); + Py_XDECREF(entries[i].me_value); + } } #if PyDict_MAXFREELIST > 0 struct _Py_dict_state *state = get_dict_state(); @@ -625,8 +673,11 @@ free_keys_object(PyDictKeysObject *keys) // free_keys_object() must not be called after _PyDict_Fini() assert(state->keys_numfree != -1); #endif - if (DK_SIZE(keys) == PyDict_MINSIZE && state->keys_numfree < PyDict_MAXFREELIST) { + if (DK_LOG_SIZE(keys) == PyDict_LOG_MINSIZE + && state->keys_numfree < PyDict_MAXFREELIST + && DK_IS_UNICODE(keys)) { state->keys_free_list[state->keys_numfree++] = keys; + OBJECT_STAT_INC(to_freelist); return; } #endif @@ -634,13 +685,27 @@ free_keys_object(PyDictKeysObject *keys) } static inline PyDictValues* -new_values(Py_ssize_t size) +new_values(size_t size) { - Py_ssize_t n = sizeof(PyDictValues) + sizeof(PyObject *) * (size-1); - return (PyDictValues*)PyMem_Malloc(n); + assert(size >= 1); + size_t prefix_size = _Py_SIZE_ROUND_UP(size+2, sizeof(PyObject *)); + assert(prefix_size < 256); + size_t n = prefix_size + size * sizeof(PyObject *); + uint8_t *mem = PyMem_Malloc(n); + if (mem == NULL) { + return NULL; + } + assert(prefix_size % sizeof(PyObject *) == 0); + mem[prefix_size-1] = (uint8_t)prefix_size; + return (PyDictValues*)(mem + prefix_size); } -#define free_values(values) PyMem_Free(values) +static inline void +free_values(PyDictValues *values) +{ + int prefix_size = ((uint8_t *)values)[-1]; + PyMem_Free(((char *)values)-prefix_size); +} /* Consumes a reference to the keys object */ static PyObject * @@ -658,6 +723,7 @@ new_dict(PyDictKeysObject *keys, PyDictValues *values, Py_ssize_t used, int free mp = state->free_list[--state->numfree]; assert (mp != NULL); assert (Py_IS_TYPE(mp, &PyDict_Type)); + OBJECT_STAT_INC(from_freelist); _Py_NewReference((PyObject *)mp); } else @@ -680,27 +746,24 @@ new_dict(PyDictKeysObject *keys, PyDictValues *values, Py_ssize_t used, int free return (PyObject *)mp; } -static inline Py_ssize_t +static inline size_t shared_keys_usable_size(PyDictKeysObject *keys) { - return keys->dk_nentries + keys->dk_usable; + return (size_t)keys->dk_nentries + (size_t)keys->dk_usable; } /* Consumes a reference to the keys object */ static PyObject * new_dict_with_shared_keys(PyDictKeysObject *keys) { - PyDictValues *values; - Py_ssize_t i, size; - - size = shared_keys_usable_size(keys); - values = new_values(size); + size_t size = shared_keys_usable_size(keys); + PyDictValues *values = new_values(size); if (values == NULL) { dictkeys_decref(keys); return PyErr_NoMemory(); } - values->mv_order = 0; - for (i = 0; i < size; i++) { + ((char *)values)[-2] = 0; + for (size_t i = 0; i < size; i++) { values->values[i] = NULL; } return new_dict(keys, values, 0, 1); @@ -715,7 +778,7 @@ clone_combined_dict_keys(PyDictObject *orig) assert(orig->ma_values == NULL); assert(orig->ma_keys->dk_refcnt == 1); - Py_ssize_t keys_size = _PyDict_KeysSize(orig->ma_keys); + size_t keys_size = _PyDict_KeysSize(orig->ma_keys); PyDictKeysObject *keys = PyObject_Malloc(keys_size); if (keys == NULL) { PyErr_NoMemory(); @@ -727,15 +790,30 @@ clone_combined_dict_keys(PyDictObject *orig) /* After copying key/value pairs, we need to incref all keys and values and they are about to be co-owned by a new dict object. */ - PyDictKeyEntry *ep0 = DK_ENTRIES(keys); + PyObject **pkey, **pvalue; + size_t offs; + if (DK_IS_UNICODE(orig->ma_keys)) { + PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(keys); + pkey = &ep0->me_key; + pvalue = &ep0->me_value; + offs = sizeof(PyDictUnicodeEntry) / sizeof(PyObject*); + } + else { + PyDictKeyEntry *ep0 = DK_ENTRIES(keys); + pkey = &ep0->me_key; + pvalue = &ep0->me_value; + offs = sizeof(PyDictKeyEntry) / sizeof(PyObject*); + } + Py_ssize_t n = keys->dk_nentries; for (Py_ssize_t i = 0; i < n; i++) { - PyDictKeyEntry *entry = &ep0[i]; - PyObject *value = entry->me_value; + PyObject *value = *pvalue; if (value != NULL) { Py_INCREF(value); - Py_INCREF(entry->me_key); + Py_INCREF(*pkey); } + pvalue += offs; + pkey += offs; } /* Since we copied the keys table we now have an extra reference @@ -752,7 +830,7 @@ PyObject * PyDict_New(void) { dictkeys_incref(Py_EMPTY_KEYS); - return new_dict(Py_EMPTY_KEYS, empty_values, 0, 0); + return new_dict(Py_EMPTY_KEYS, NULL, 0, 0); } /* Search index of hash table from offset of entry table */ @@ -777,8 +855,99 @@ lookdict_index(PyDictKeysObject *k, Py_hash_t hash, Py_ssize_t index) Py_UNREACHABLE(); } +// Search non-Unicode key from Unicode table static Py_ssize_t -dictkeys_stringlookup(PyDictKeysObject* dk, PyObject *key, Py_hash_t hash) +unicodekeys_lookup_generic(PyDictObject *mp, PyDictKeysObject* dk, PyObject *key, Py_hash_t hash) +{ + PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(dk); + size_t mask = DK_MASK(dk); + size_t perturb = hash; + size_t i = (size_t)hash & mask; + Py_ssize_t ix; + for (;;) { + ix = dictkeys_get_index(dk, i); + if (ix >= 0) { + PyDictUnicodeEntry *ep = &ep0[ix]; + assert(ep->me_key != NULL); + assert(PyUnicode_CheckExact(ep->me_key)); + if (ep->me_key == key) { + return ix; + } + if (unicode_get_hash(ep->me_key) == hash) { + PyObject *startkey = ep->me_key; + Py_INCREF(startkey); + int cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); + Py_DECREF(startkey); + if (cmp < 0) { + return DKIX_ERROR; + } + if (dk == mp->ma_keys && ep->me_key == startkey) { + if (cmp > 0) { + return ix; + } + } + else { + /* The dict was mutated, restart */ + return DKIX_KEY_CHANGED; + } + } + } + else if (ix == DKIX_EMPTY) { + return DKIX_EMPTY; + } + perturb >>= PERTURB_SHIFT; + i = mask & (i*5 + perturb + 1); + } + Py_UNREACHABLE(); +} + +// Search Unicode key from Unicode table. +static Py_ssize_t _Py_HOT_FUNCTION +unicodekeys_lookup_unicode(PyDictKeysObject* dk, PyObject *key, Py_hash_t hash) +{ + PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(dk); + size_t mask = DK_MASK(dk); + size_t perturb = hash; + size_t i = (size_t)hash & mask; + Py_ssize_t ix; + for (;;) { + ix = dictkeys_get_index(dk, i); + if (ix >= 0) { + PyDictUnicodeEntry *ep = &ep0[ix]; + assert(ep->me_key != NULL); + assert(PyUnicode_CheckExact(ep->me_key)); + if (ep->me_key == key || + (unicode_get_hash(ep->me_key) == hash && unicode_eq(ep->me_key, key))) { + return ix; + } + } + else if (ix == DKIX_EMPTY) { + return DKIX_EMPTY; + } + perturb >>= PERTURB_SHIFT; + i = mask & (i*5 + perturb + 1); + ix = dictkeys_get_index(dk, i); + if (ix >= 0) { + PyDictUnicodeEntry *ep = &ep0[ix]; + assert(ep->me_key != NULL); + assert(PyUnicode_CheckExact(ep->me_key)); + if (ep->me_key == key || + (unicode_get_hash(ep->me_key) == hash && unicode_eq(ep->me_key, key))) { + return ix; + } + } + else if (ix == DKIX_EMPTY) { + return DKIX_EMPTY; + } + perturb >>= PERTURB_SHIFT; + i = mask & (i*5 + perturb + 1); + } + Py_UNREACHABLE(); +} + +// Search key from Generic table. +static Py_ssize_t +dictkeys_generic_lookup(PyDictObject *mp, PyDictKeysObject* dk, PyObject *key, Py_hash_t hash) { PyDictKeyEntry *ep0 = DK_ENTRIES(dk); size_t mask = DK_MASK(dk); @@ -790,25 +959,26 @@ dictkeys_stringlookup(PyDictKeysObject* dk, PyObject *key, Py_hash_t hash) if (ix >= 0) { PyDictKeyEntry *ep = &ep0[ix]; assert(ep->me_key != NULL); - assert(PyUnicode_CheckExact(ep->me_key)); - if (ep->me_key == key || - (ep->me_hash == hash && unicode_eq(ep->me_key, key))) { + if (ep->me_key == key) { return ix; } - } - else if (ix == DKIX_EMPTY) { - return DKIX_EMPTY; - } - perturb >>= PERTURB_SHIFT; - i = mask & (i*5 + perturb + 1); - ix = dictkeys_get_index(dk, i); - if (ix >= 0) { - PyDictKeyEntry *ep = &ep0[ix]; - assert(ep->me_key != NULL); - assert(PyUnicode_CheckExact(ep->me_key)); - if (ep->me_key == key || - (ep->me_hash == hash && unicode_eq(ep->me_key, key))) { - return ix; + if (ep->me_hash == hash) { + PyObject *startkey = ep->me_key; + Py_INCREF(startkey); + int cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); + Py_DECREF(startkey); + if (cmp < 0) { + return DKIX_ERROR; + } + if (dk == mp->ma_keys && ep->me_key == startkey) { + if (cmp > 0) { + return ix; + } + } + else { + /* The dict was mutated, restart */ + return DKIX_KEY_CHANGED; + } } } else if (ix == DKIX_EMPTY) { @@ -833,7 +1003,7 @@ _PyDictKeys_StringLookup(PyDictKeysObject* dk, PyObject *key) if (!PyUnicode_CheckExact(key) || kind == DICT_KEYS_GENERAL) { return DKIX_ERROR; } - Py_hash_t hash = ((PyASCIIObject *)key)->hash; + Py_hash_t hash = unicode_get_hash(key); if (hash == -1) { hash = PyUnicode_Type.tp_hash(key); if (hash == -1) { @@ -841,7 +1011,7 @@ _PyDictKeys_StringLookup(PyDictKeysObject* dk, PyObject *key) return DKIX_ERROR; } } - return dictkeys_stringlookup(dk, key, hash); + return unicodekeys_lookup_unicode(dk, key, hash); } /* @@ -859,74 +1029,53 @@ _Py_dict_lookup() is general-purpose, and may return DKIX_ERROR if (and only if) comparison raises an exception. When the key isn't found a DKIX_EMPTY is returned. */ -Py_ssize_t _Py_HOT_FUNCTION +Py_ssize_t _Py_dict_lookup(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject **value_addr) { PyDictKeysObject *dk; + DictKeysKind kind; + Py_ssize_t ix; + start: dk = mp->ma_keys; - DictKeysKind kind = dk->dk_kind; - if (PyUnicode_CheckExact(key) && kind != DICT_KEYS_GENERAL) { - Py_ssize_t ix = dictkeys_stringlookup(dk, key, hash); - if (ix == DKIX_EMPTY) { - *value_addr = NULL; - } - else if (kind == DICT_KEYS_SPLIT) { - *value_addr = mp->ma_values->values[ix]; + kind = dk->dk_kind; + + if (kind != DICT_KEYS_GENERAL) { + if (PyUnicode_CheckExact(key)) { + ix = unicodekeys_lookup_unicode(dk, key, hash); } else { - *value_addr = DK_ENTRIES(dk)[ix].me_value; - } - return ix; - } - PyDictKeyEntry *ep0 = DK_ENTRIES(dk); - size_t mask = DK_MASK(dk); - size_t perturb = hash; - size_t i = (size_t)hash & mask; - Py_ssize_t ix; - for (;;) { - ix = dictkeys_get_index(dk, i); - if (ix == DKIX_EMPTY) { - *value_addr = NULL; - return ix; + ix = unicodekeys_lookup_generic(mp, dk, key, hash); + if (ix == DKIX_KEY_CHANGED) { + goto start; + } } + if (ix >= 0) { - PyDictKeyEntry *ep = &ep0[ix]; - assert(ep->me_key != NULL); - if (ep->me_key == key) { - goto found; + if (kind == DICT_KEYS_SPLIT) { + *value_addr = mp->ma_values->values[ix]; } - if (ep->me_hash == hash) { - PyObject *startkey = ep->me_key; - Py_INCREF(startkey); - int cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); - Py_DECREF(startkey); - if (cmp < 0) { - *value_addr = NULL; - return DKIX_ERROR; - } - if (dk == mp->ma_keys && ep->me_key == startkey) { - if (cmp > 0) { - goto found; - } - } - else { - /* The dict was mutated, restart */ - goto start; - } + else { + *value_addr = DK_UNICODE_ENTRIES(dk)[ix].me_value; } } - perturb >>= PERTURB_SHIFT; - i = (i*5 + perturb + 1) & mask; - } - Py_UNREACHABLE(); -found: - if (dk->dk_kind == DICT_KEYS_SPLIT) { - *value_addr = mp->ma_values->values[ix]; + else { + *value_addr = NULL; + } } else { - *value_addr = ep0[ix].me_value; + ix = dictkeys_generic_lookup(mp, dk, key, hash); + if (ix == DKIX_KEY_CHANGED) { + goto start; + } + if (ix >= 0) { + *value_addr = DK_ENTRIES(dk)[ix].me_value; + } + else { + *value_addr = NULL; + } } + return ix; } @@ -961,31 +1110,40 @@ _PyDict_MaybeUntrack(PyObject *op) PyDictObject *mp; PyObject *value; Py_ssize_t i, numentries; - PyDictKeyEntry *ep0; if (!PyDict_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op)) return; mp = (PyDictObject *) op; - ep0 = DK_ENTRIES(mp->ma_keys); numentries = mp->ma_keys->dk_nentries; if (_PyDict_HasSplitTable(mp)) { for (i = 0; i < numentries; i++) { if ((value = mp->ma_values->values[i]) == NULL) continue; if (_PyObject_GC_MAY_BE_TRACKED(value)) { - assert(!_PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key)); return; } } } else { - for (i = 0; i < numentries; i++) { - if ((value = ep0[i].me_value) == NULL) - continue; - if (_PyObject_GC_MAY_BE_TRACKED(value) || - _PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key)) - return; + if (DK_IS_UNICODE(mp->ma_keys)) { + PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(mp->ma_keys); + for (i = 0; i < numentries; i++) { + if ((value = ep0[i].me_value) == NULL) + continue; + if (_PyObject_GC_MAY_BE_TRACKED(value)) + return; + } + } + else { + PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys); + for (i = 0; i < numentries; i++) { + if ((value = ep0[i].me_value) == NULL) + continue; + if (_PyObject_GC_MAY_BE_TRACKED(value) || + _PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key)) + return; + } } } _PyObject_GC_UNTRACK(op); @@ -1012,16 +1170,16 @@ find_empty_slot(PyDictKeysObject *keys, Py_hash_t hash) } static int -insertion_resize(PyDictObject *mp) +insertion_resize(PyDictObject *mp, int unicode) { - return dictresize(mp, calculate_log2_keysize(GROWTH_RATE(mp))); + return dictresize(mp, calculate_log2_keysize(GROWTH_RATE(mp)), unicode); } -static int +static Py_ssize_t insert_into_dictkeys(PyDictKeysObject *keys, PyObject *name) { assert(PyUnicode_CheckExact(name)); - Py_hash_t hash = ((PyASCIIObject *)name)->hash; + Py_hash_t hash = unicode_get_hash(name); if (hash == -1) { hash = PyUnicode_Type.tp_hash(name); if (hash == -1) { @@ -1029,26 +1187,24 @@ insert_into_dictkeys(PyDictKeysObject *keys, PyObject *name) return DKIX_EMPTY; } } - Py_ssize_t ix = dictkeys_stringlookup(keys, name, hash); + Py_ssize_t ix = unicodekeys_lookup_unicode(keys, name, hash); if (ix == DKIX_EMPTY) { if (keys->dk_usable <= 0) { return DKIX_EMPTY; } - Py_INCREF(name); /* Insert into new slot. */ keys->dk_version = 0; Py_ssize_t hashpos = find_empty_slot(keys, hash); ix = keys->dk_nentries; - PyDictKeyEntry *ep = &DK_ENTRIES(keys)[ix]; + PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(keys)[ix]; dictkeys_set_index(keys, hashpos, ix); assert(ep->me_key == NULL); - ep->me_key = name; - ep->me_hash = hash; + ep->me_key = Py_NewRef(name); keys->dk_usable--; keys->dk_nentries++; } assert (ix < SHARED_KEYS_MAX_SIZE); - return (int)ix; + return ix; } /* @@ -1061,11 +1217,11 @@ static int insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) { PyObject *old_value; - PyDictKeyEntry *ep; - if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) { - if (insertion_resize(mp) < 0) + if (DK_IS_UNICODE(mp->ma_keys) && !PyUnicode_CheckExact(key)) { + if (insertion_resize(mp, 0) < 0) goto Fail; + assert(mp->ma_keys->dk_kind == DICT_KEYS_GENERAL); } Py_ssize_t ix = _Py_dict_lookup(mp, key, hash, &old_value); @@ -1075,35 +1231,42 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) MAINTAIN_TRACKING(mp, key, value); if (ix == DKIX_EMPTY) { + uint64_t new_version = _PyDict_NotifyEvent(PyDict_EVENT_ADDED, mp, key, value); /* Insert into new slot. */ mp->ma_keys->dk_version = 0; assert(old_value == NULL); if (mp->ma_keys->dk_usable <= 0) { /* Need to resize. */ - if (insertion_resize(mp) < 0) + if (insertion_resize(mp, 1) < 0) goto Fail; } - if (!PyUnicode_CheckExact(key) && mp->ma_keys->dk_kind != DICT_KEYS_GENERAL) { - mp->ma_keys->dk_kind = DICT_KEYS_GENERAL; - } + Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash); - ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries); - ep->me_key = key; - ep->me_hash = hash; - if (mp->ma_values) { - Py_ssize_t index = mp->ma_keys->dk_nentries; - assert(index < SHARED_KEYS_MAX_SIZE); - assert((mp->ma_values->mv_order >> 60) == 0); - mp->ma_values->mv_order = ((mp->ma_values->mv_order)<<4) | index; - assert (mp->ma_values->values[index] == NULL); - mp->ma_values->values[index] = value; + + if (DK_IS_UNICODE(mp->ma_keys)) { + PyDictUnicodeEntry *ep; + ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; + ep->me_key = key; + if (mp->ma_values) { + Py_ssize_t index = mp->ma_keys->dk_nentries; + _PyDictValues_AddToInsertionOrder(mp->ma_values, index); + assert (mp->ma_values->values[index] == NULL); + mp->ma_values->values[index] = value; + } + else { + ep->me_value = value; + } } else { + PyDictKeyEntry *ep; + ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; + ep->me_key = key; + ep->me_hash = hash; ep->me_value = value; } mp->ma_used++; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; mp->ma_keys->dk_usable--; mp->ma_keys->dk_nentries++; assert(mp->ma_keys->dk_usable >= 0); @@ -1112,18 +1275,24 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) } if (old_value != value) { + uint64_t new_version = _PyDict_NotifyEvent(PyDict_EVENT_MODIFIED, mp, key, value); if (_PyDict_HasSplitTable(mp)) { mp->ma_values->values[ix] = value; if (old_value == NULL) { - mp->ma_values->mv_order = (mp->ma_values->mv_order << 4) | ix; + _PyDictValues_AddToInsertionOrder(mp->ma_values, ix); mp->ma_used++; } } else { assert(old_value != NULL); - DK_ENTRIES(mp->ma_keys)[ix].me_value = value; + if (DK_IS_UNICODE(mp->ma_keys)) { + DK_UNICODE_ENTRIES(mp->ma_keys)[ix].me_value = value; + } + else { + DK_ENTRIES(mp->ma_keys)[ix].me_value = value; + } } - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; } Py_XDECREF(old_value); /* which **CAN** re-enter (see issue #22653) */ ASSERT_CONSISTENT(mp); @@ -1144,15 +1313,15 @@ insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash, { assert(mp->ma_keys == Py_EMPTY_KEYS); - PyDictKeysObject *newkeys = new_keys_object(PyDict_LOG_MINSIZE); + uint64_t new_version = _PyDict_NotifyEvent(PyDict_EVENT_ADDED, mp, key, value); + + int unicode = PyUnicode_CheckExact(key); + PyDictKeysObject *newkeys = new_keys_object(PyDict_LOG_MINSIZE, unicode); if (newkeys == NULL) { Py_DECREF(key); Py_DECREF(value); return -1; } - if (!PyUnicode_CheckExact(key)) { - newkeys->dk_kind = DICT_KEYS_GENERAL; - } dictkeys_decref(Py_EMPTY_KEYS); mp->ma_keys = newkeys; mp->ma_values = NULL; @@ -1160,13 +1329,20 @@ insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash, MAINTAIN_TRACKING(mp, key, value); size_t hashpos = (size_t)hash & (PyDict_MINSIZE-1); - PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys); dictkeys_set_index(mp->ma_keys, hashpos, 0); - ep->me_key = key; - ep->me_hash = hash; - ep->me_value = value; + if (unicode) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(mp->ma_keys); + ep->me_key = key; + ep->me_value = value; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys); + ep->me_key = key; + ep->me_hash = hash; + ep->me_value = value; + } mp->ma_used++; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; mp->ma_keys->dk_usable--; mp->ma_keys->dk_nentries++; return 0; @@ -1176,9 +1352,9 @@ insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash, Internal routine used by dictresize() to build a hashtable of entries. */ static void -build_indices(PyDictKeysObject *keys, PyDictKeyEntry *ep, Py_ssize_t n) +build_indices_generic(PyDictKeysObject *keys, PyDictKeyEntry *ep, Py_ssize_t n) { - size_t mask = (size_t)DK_SIZE(keys) - 1; + size_t mask = DK_MASK(keys); for (Py_ssize_t ix = 0; ix != n; ix++, ep++) { Py_hash_t hash = ep->me_hash; size_t i = hash & mask; @@ -1190,6 +1366,22 @@ build_indices(PyDictKeysObject *keys, PyDictKeyEntry *ep, Py_ssize_t n) } } +static void +build_indices_unicode(PyDictKeysObject *keys, PyDictUnicodeEntry *ep, Py_ssize_t n) +{ + size_t mask = DK_MASK(keys); + for (Py_ssize_t ix = 0; ix != n; ix++, ep++) { + Py_hash_t hash = unicode_get_hash(ep->me_key); + assert(hash != -1); + size_t i = hash & mask; + for (size_t perturb = hash; dictkeys_get_index(keys, i) != DKIX_EMPTY;) { + perturb >>= PERTURB_SHIFT; + i = mask & (i*5 + perturb + 1); + } + dictkeys_set_index(keys, i, ix); + } +} + /* Restructure the table by allocating a new table and reinserting all items again. When entries have been deleted, the new table may @@ -1198,14 +1390,17 @@ If a table is split (its keys and hashes are shared, its values are not), then the values are temporarily copied into the table, it is resized as a combined table, then the me_value slots in the old table are NULLed out. After resizing a table is always combined. + +This function supports: + - Unicode split -> Unicode combined or Generic + - Unicode combined -> Unicode combined or Generic + - Generic -> Generic */ static int -dictresize(PyDictObject *mp, uint8_t log2_newsize) +dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) { - Py_ssize_t numentries; PyDictKeysObject *oldkeys; PyDictValues *oldvalues; - PyDictKeyEntry *oldentries, *newentries; if (log2_newsize >= SIZEOF_SIZE_T*8) { PyErr_NoMemory(); @@ -1214,6 +1409,11 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize) assert(log2_newsize >= PyDict_LOG_MINSIZE); oldkeys = mp->ma_keys; + oldvalues = mp->ma_values; + + if (!DK_IS_UNICODE(oldkeys)) { + unicode = 0; + } /* NOTE: Current odict checks mp->ma_keys to detect resize happen. * So we can't reuse oldkeys even if oldkeys->dk_size == newsize. @@ -1221,84 +1421,143 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize) */ /* Allocate a new table. */ - mp->ma_keys = new_keys_object(log2_newsize); + mp->ma_keys = new_keys_object(log2_newsize, unicode); if (mp->ma_keys == NULL) { mp->ma_keys = oldkeys; return -1; } // New table must be large enough. assert(mp->ma_keys->dk_usable >= mp->ma_used); - if (oldkeys->dk_kind == DICT_KEYS_GENERAL) - mp->ma_keys->dk_kind = DICT_KEYS_GENERAL; - numentries = mp->ma_used; - oldentries = DK_ENTRIES(oldkeys); - newentries = DK_ENTRIES(mp->ma_keys); - oldvalues = mp->ma_values; + Py_ssize_t numentries = mp->ma_used; + if (oldvalues != NULL) { + PyDictUnicodeEntry *oldentries = DK_UNICODE_ENTRIES(oldkeys); /* Convert split table into new combined table. * We must incref keys; we can transfer values. */ - for (Py_ssize_t i = 0; i < numentries; i++) { - int index = get_index_from_order(mp, i); - PyDictKeyEntry *ep = &oldentries[index]; - assert(oldvalues->values[index] != NULL); - Py_INCREF(ep->me_key); - newentries[i].me_key = ep->me_key; - newentries[i].me_hash = ep->me_hash; - newentries[i].me_value = oldvalues->values[index]; + if (mp->ma_keys->dk_kind == DICT_KEYS_GENERAL) { + // split -> generic + PyDictKeyEntry *newentries = DK_ENTRIES(mp->ma_keys); + + for (Py_ssize_t i = 0; i < numentries; i++) { + int index = get_index_from_order(mp, i); + PyDictUnicodeEntry *ep = &oldentries[index]; + assert(oldvalues->values[index] != NULL); + newentries[i].me_key = Py_NewRef(ep->me_key); + newentries[i].me_hash = unicode_get_hash(ep->me_key); + newentries[i].me_value = oldvalues->values[index]; + } + build_indices_generic(mp->ma_keys, newentries, numentries); + } + else { // split -> combined unicode + PyDictUnicodeEntry *newentries = DK_UNICODE_ENTRIES(mp->ma_keys); + + for (Py_ssize_t i = 0; i < numentries; i++) { + int index = get_index_from_order(mp, i); + PyDictUnicodeEntry *ep = &oldentries[index]; + assert(oldvalues->values[index] != NULL); + newentries[i].me_key = Py_NewRef(ep->me_key); + newentries[i].me_value = oldvalues->values[index]; + } + build_indices_unicode(mp->ma_keys, newentries, numentries); } dictkeys_decref(oldkeys); mp->ma_values = NULL; - if (oldvalues != empty_values) { - free_values(oldvalues); - } + free_values(oldvalues); } - else { // combined table. - if (oldkeys->dk_nentries == numentries) { - memcpy(newentries, oldentries, numentries * sizeof(PyDictKeyEntry)); + else { // oldkeys is combined. + if (oldkeys->dk_kind == DICT_KEYS_GENERAL) { + // generic -> generic + assert(mp->ma_keys->dk_kind == DICT_KEYS_GENERAL); + PyDictKeyEntry *oldentries = DK_ENTRIES(oldkeys); + PyDictKeyEntry *newentries = DK_ENTRIES(mp->ma_keys); + if (oldkeys->dk_nentries == numentries) { + memcpy(newentries, oldentries, numentries * sizeof(PyDictKeyEntry)); + } + else { + PyDictKeyEntry *ep = oldentries; + for (Py_ssize_t i = 0; i < numentries; i++) { + while (ep->me_value == NULL) + ep++; + newentries[i] = *ep++; + } + } + build_indices_generic(mp->ma_keys, newentries, numentries); } - else { - PyDictKeyEntry *ep = oldentries; - for (Py_ssize_t i = 0; i < numentries; i++) { - while (ep->me_value == NULL) + else { // oldkeys is combined unicode + PyDictUnicodeEntry *oldentries = DK_UNICODE_ENTRIES(oldkeys); + if (unicode) { // combined unicode -> combined unicode + PyDictUnicodeEntry *newentries = DK_UNICODE_ENTRIES(mp->ma_keys); + if (oldkeys->dk_nentries == numentries && mp->ma_keys->dk_kind == DICT_KEYS_UNICODE) { + memcpy(newentries, oldentries, numentries * sizeof(PyDictUnicodeEntry)); + } + else { + PyDictUnicodeEntry *ep = oldentries; + for (Py_ssize_t i = 0; i < numentries; i++) { + while (ep->me_value == NULL) + ep++; + newentries[i] = *ep++; + } + } + build_indices_unicode(mp->ma_keys, newentries, numentries); + } + else { // combined unicode -> generic + PyDictKeyEntry *newentries = DK_ENTRIES(mp->ma_keys); + PyDictUnicodeEntry *ep = oldentries; + for (Py_ssize_t i = 0; i < numentries; i++) { + while (ep->me_value == NULL) + ep++; + newentries[i].me_key = ep->me_key; + newentries[i].me_hash = unicode_get_hash(ep->me_key); + newentries[i].me_value = ep->me_value; ep++; - newentries[i] = *ep++; + } + build_indices_generic(mp->ma_keys, newentries, numentries); } } - assert(oldkeys->dk_kind != DICT_KEYS_SPLIT); - assert(oldkeys->dk_refcnt == 1); + // We can not use free_keys_object here because key's reference + // are moved already. #ifdef Py_REF_DEBUG _Py_RefTotal--; #endif -#if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(); -#ifdef Py_DEBUG - // dictresize() must not be called after _PyDict_Fini() - assert(state->keys_numfree != -1); -#endif - if (DK_SIZE(oldkeys) == PyDict_MINSIZE && - state->keys_numfree < PyDict_MAXFREELIST) - { - state->keys_free_list[state->keys_numfree++] = oldkeys; + if (oldkeys == Py_EMPTY_KEYS) { + oldkeys->dk_refcnt--; + assert(oldkeys->dk_refcnt > 0); } - else + else { + assert(oldkeys->dk_kind != DICT_KEYS_SPLIT); + assert(oldkeys->dk_refcnt == 1); +#if PyDict_MAXFREELIST > 0 + struct _Py_dict_state *state = get_dict_state(); +#ifdef Py_DEBUG + // dictresize() must not be called after _PyDict_Fini() + assert(state->keys_numfree != -1); #endif - { - PyObject_Free(oldkeys); + if (DK_LOG_SIZE(oldkeys) == PyDict_LOG_MINSIZE && + DK_IS_UNICODE(oldkeys) && + state->keys_numfree < PyDict_MAXFREELIST) + { + state->keys_free_list[state->keys_numfree++] = oldkeys; + OBJECT_STAT_INC(to_freelist); + } + else +#endif + { + PyObject_Free(oldkeys); + } } } - build_indices(mp->ma_keys, newentries, numentries); mp->ma_keys->dk_usable -= numentries; mp->ma_keys->dk_nentries = numentries; ASSERT_CONSISTENT(mp); return 0; } -PyObject * -_PyDict_NewPresized(Py_ssize_t minused) +static PyObject * +dict_new_presized(Py_ssize_t minused, bool unicode) { const uint8_t log2_max_presize = 17; const Py_ssize_t max_presize = ((Py_ssize_t)1) << log2_max_presize; @@ -1319,12 +1578,56 @@ _PyDict_NewPresized(Py_ssize_t minused) log2_newsize = estimate_log2_keysize(minused); } - new_keys = new_keys_object(log2_newsize); + new_keys = new_keys_object(log2_newsize, unicode); if (new_keys == NULL) return NULL; return new_dict(new_keys, NULL, 0, 0); } +PyObject * +_PyDict_NewPresized(Py_ssize_t minused) +{ + return dict_new_presized(minused, false); +} + +PyObject * +_PyDict_FromItems(PyObject *const *keys, Py_ssize_t keys_offset, + PyObject *const *values, Py_ssize_t values_offset, + Py_ssize_t length) +{ + bool unicode = true; + PyObject *const *ks = keys; + + for (Py_ssize_t i = 0; i < length; i++) { + if (!PyUnicode_CheckExact(*ks)) { + unicode = false; + break; + } + ks += keys_offset; + } + + PyObject *dict = dict_new_presized(length, unicode); + if (dict == NULL) { + return NULL; + } + + ks = keys; + PyObject *const *vs = values; + + for (Py_ssize_t i = 0; i < length; i++) { + PyObject *key = *ks; + PyObject *value = *vs; + if (PyDict_SetItem(dict, key, value) < 0) { + Py_DECREF(dict); + return NULL; + } + ks += keys_offset; + vs += values_offset; + } + + return dict; +} + /* Note that, for historical reasons, PyDict_GetItem() suppresses all errors * that may occur (originally dicts supported only string keys, and exceptions * weren't possible). So, while the original intent was that a NULL return @@ -1344,9 +1647,7 @@ PyDict_GetItem(PyObject *op, PyObject *key) PyDictObject *mp = (PyDictObject *)op; Py_hash_t hash; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) - { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) { PyErr_Clear(); @@ -1378,33 +1679,13 @@ PyDict_GetItem(PyObject *op, PyObject *key) } Py_ssize_t -_PyDict_GetItemHint(PyDictObject *mp, PyObject *key, - Py_ssize_t hint, PyObject **value) +_PyDict_LookupIndex(PyDictObject *mp, PyObject *key) { - assert(*value == NULL); + PyObject *value; assert(PyDict_CheckExact((PyObject*)mp)); assert(PyUnicode_CheckExact(key)); - if (hint >= 0 && hint < mp->ma_keys->dk_nentries) { - PyObject *res = NULL; - - PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys) + (size_t)hint; - if (ep->me_key == key) { - if (mp->ma_keys->dk_kind == DICT_KEYS_SPLIT) { - assert(mp->ma_values != NULL); - res = mp->ma_values->values[(size_t)hint]; - } - else { - res = ep->me_value; - } - if (res != NULL) { - *value = res; - return hint; - } - } - } - - Py_hash_t hash = ((PyASCIIObject *) key)->hash; + Py_hash_t hash = unicode_get_hash(key); if (hash == -1) { hash = PyObject_Hash(key); if (hash == -1) { @@ -1412,7 +1693,7 @@ _PyDict_GetItemHint(PyDictObject *mp, PyObject *key, } } - return _Py_dict_lookup(mp, key, hash, value); + return _Py_dict_lookup(mp, key, hash, &value); } /* Same as PyDict_GetItemWithError() but with hash supplied by caller. @@ -1452,8 +1733,7 @@ PyDict_GetItemWithError(PyObject *op, PyObject *key) PyErr_BadInternalCall(); return NULL; } - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) { @@ -1467,13 +1747,24 @@ PyDict_GetItemWithError(PyObject *op, PyObject *key) } PyObject * -_PyDict_GetItemIdWithError(PyObject *dp, struct _Py_Identifier *key) +_PyDict_GetItemWithError(PyObject *dp, PyObject *kv) +{ + assert(PyUnicode_CheckExact(kv)); + Py_hash_t hash = kv->ob_type->tp_hash(kv); + if (hash == -1) { + return NULL; + } + return _PyDict_GetItem_KnownHash(dp, kv, hash); +} + +PyObject * +_PyDict_GetItemIdWithError(PyObject *dp, _Py_Identifier *key) { PyObject *kv; kv = _PyUnicode_FromId(key); /* borrowed */ if (kv == NULL) return NULL; - Py_hash_t hash = ((PyASCIIObject *) kv)->hash; + Py_hash_t hash = unicode_get_hash(kv); assert (hash != -1); /* interned strings have their hash value initialised */ return _PyDict_GetItem_KnownHash(dp, kv, hash); } @@ -1508,9 +1799,7 @@ _PyDict_LoadGlobal(PyDictObject *globals, PyDictObject *builtins, PyObject *key) Py_hash_t hash; PyObject *value; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) - { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) return NULL; @@ -1537,9 +1826,7 @@ _PyDict_SetItem_Take2(PyDictObject *mp, PyObject *key, PyObject *value) assert(value); assert(PyDict_Check(mp)); Py_hash_t hash; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) - { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) { Py_DECREF(key); @@ -1569,9 +1856,8 @@ PyDict_SetItem(PyObject *op, PyObject *key, PyObject *value) } assert(key); assert(value); - Py_INCREF(key); - Py_INCREF(value); - return _PyDict_SetItem_Take2((PyDictObject *)op, key, value); + return _PyDict_SetItem_Take2((PyDictObject *)op, + Py_NewRef(key), Py_NewRef(value)); } int @@ -1589,58 +1875,64 @@ _PyDict_SetItem_KnownHash(PyObject *op, PyObject *key, PyObject *value, assert(hash != -1); mp = (PyDictObject *)op; - Py_INCREF(key); - Py_INCREF(value); if (mp->ma_keys == Py_EMPTY_KEYS) { - return insert_to_emptydict(mp, key, hash, value); + return insert_to_emptydict(mp, Py_NewRef(key), hash, Py_NewRef(value)); } /* insertdict() handles any resizing that might be necessary */ - return insertdict(mp, key, hash, value); + return insertdict(mp, Py_NewRef(key), hash, Py_NewRef(value)); } -static uint64_t -delete_index_from_order(uint64_t order, Py_ssize_t ix) -{ /* Update order */ - for (int i = 0;; i+= 4) { - assert (i < 64); - if (((order >> i) & 15) == (uint64_t)ix) { - /* Remove 4 bits at ith position */ - uint64_t high = ((order>>i)>>4)<ma_keys, hash, ix); assert(hashpos >= 0); mp->ma_used--; - mp->ma_version_tag = DICT_NEXT_VERSION(); - ep = &DK_ENTRIES(mp->ma_keys)[ix]; + mp->ma_version_tag = new_version; if (mp->ma_values) { assert(old_value == mp->ma_values->values[ix]); mp->ma_values->values[ix] = NULL; assert(ix < SHARED_KEYS_MAX_SIZE); /* Update order */ - mp->ma_values->mv_order = - delete_index_from_order(mp->ma_values->mv_order, ix); + delete_index_from_values(mp->ma_values, ix); ASSERT_CONSISTENT(mp); } else { mp->ma_keys->dk_version = 0; dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY); - old_key = ep->me_key; - ep->me_key = NULL; - ep->me_value = NULL; + if (DK_IS_UNICODE(mp->ma_keys)) { + PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[ix]; + old_key = ep->me_key; + ep->me_key = NULL; + ep->me_value = NULL; + } + else { + PyDictKeyEntry *ep = &DK_ENTRIES(mp->ma_keys)[ix]; + old_key = ep->me_key; + ep->me_key = NULL; + ep->me_value = NULL; + ep->me_hash = 0; + } Py_DECREF(old_key); } Py_DECREF(old_value); @@ -1654,8 +1946,7 @@ PyDict_DelItem(PyObject *op, PyObject *key) { Py_hash_t hash; assert(key); - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) return -1; @@ -1686,7 +1977,8 @@ _PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) return -1; } - return delitem_common(mp, hash, ix, old_value); + uint64_t new_version = _PyDict_NotifyEvent(PyDict_EVENT_DELETED, mp, key, NULL); + return delitem_common(mp, hash, ix, old_value, new_version); } /* This function promises that the predicate -> deletion sequence is atomic @@ -1727,10 +2019,12 @@ _PyDict_DelItemIf(PyObject *op, PyObject *key, hashpos = lookdict_index(mp->ma_keys, hash, ix); assert(hashpos >= 0); - if (res > 0) - return delitem_common(mp, hashpos, ix, old_value); - else + if (res > 0) { + uint64_t new_version = _PyDict_NotifyEvent(PyDict_EVENT_DELETED, mp, key, NULL); + return delitem_common(mp, hashpos, ix, old_value, new_version); + } else { return 0; + } } @@ -1747,14 +2041,16 @@ PyDict_Clear(PyObject *op) mp = ((PyDictObject *)op); oldkeys = mp->ma_keys; oldvalues = mp->ma_values; - if (oldvalues == empty_values) + if (oldkeys == Py_EMPTY_KEYS) { return; + } /* Empty the dict... */ + uint64_t new_version = _PyDict_NotifyEvent(PyDict_EVENT_CLEARED, mp, NULL, NULL); dictkeys_incref(Py_EMPTY_KEYS); mp->ma_keys = Py_EMPTY_KEYS; - mp->ma_values = empty_values; + mp->ma_values = NULL; mp->ma_used = 0; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; /* ...then clear the keys and values */ if (oldvalues != NULL) { n = oldkeys->dk_nentries; @@ -1781,8 +2077,8 @@ _PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, { Py_ssize_t i; PyDictObject *mp; - PyDictKeyEntry *entry_ptr; - PyObject *value; + PyObject *key, *value; + Py_hash_t hash; if (!PyDict_Check(op)) return 0; @@ -1793,30 +2089,48 @@ _PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, if (i < 0 || i >= mp->ma_used) return 0; int index = get_index_from_order(mp, i); - entry_ptr = &DK_ENTRIES(mp->ma_keys)[index]; value = mp->ma_values->values[index]; + + key = DK_UNICODE_ENTRIES(mp->ma_keys)[index].me_key; + hash = unicode_get_hash(key); assert(value != NULL); } else { Py_ssize_t n = mp->ma_keys->dk_nentries; if (i < 0 || i >= n) return 0; - entry_ptr = &DK_ENTRIES(mp->ma_keys)[i]; - while (i < n && entry_ptr->me_value == NULL) { - entry_ptr++; - i++; + if (DK_IS_UNICODE(mp->ma_keys)) { + PyDictUnicodeEntry *entry_ptr = &DK_UNICODE_ENTRIES(mp->ma_keys)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + return 0; + key = entry_ptr->me_key; + hash = unicode_get_hash(entry_ptr->me_key); + value = entry_ptr->me_value; + } + else { + PyDictKeyEntry *entry_ptr = &DK_ENTRIES(mp->ma_keys)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + return 0; + key = entry_ptr->me_key; + hash = entry_ptr->me_hash; + value = entry_ptr->me_value; } - if (i >= n) - return 0; - value = entry_ptr->me_value; } *ppos = i+1; if (pkey) - *pkey = entry_ptr->me_key; - if (phash) - *phash = entry_ptr->me_hash; + *pkey = key; if (pvalue) *pvalue = value; + if (phash) + *phash = hash; return 1; } @@ -1857,8 +2171,7 @@ _PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *d if (mp->ma_used == 0) { if (deflt) { - Py_INCREF(deflt); - return deflt; + return Py_NewRef(deflt); } _PyErr_SetKeyError(key); return NULL; @@ -1868,15 +2181,14 @@ _PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *d return NULL; if (ix == DKIX_EMPTY || old_value == NULL) { if (deflt) { - Py_INCREF(deflt); - return deflt; + return Py_NewRef(deflt); } _PyErr_SetKeyError(key); return NULL; } assert(old_value != NULL); - Py_INCREF(old_value); - delitem_common(mp, hash, ix, old_value); + uint64_t new_version = _PyDict_NotifyEvent(PyDict_EVENT_DELETED, mp, key, NULL); + delitem_common(mp, hash, ix, Py_NewRef(old_value), new_version); ASSERT_CONSISTENT(mp); return old_value; @@ -1889,14 +2201,12 @@ _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) if (((PyDictObject *)dict)->ma_used == 0) { if (deflt) { - Py_INCREF(deflt); - return deflt; + return Py_NewRef(deflt); } _PyErr_SetKeyError(key); return NULL; } - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) return NULL; @@ -1925,15 +2235,14 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) PyObject *key; Py_hash_t hash; - if (dictresize(mp, estimate_log2_keysize(PyDict_GET_SIZE(iterable)))) { + int unicode = DK_IS_UNICODE(((PyDictObject*)iterable)->ma_keys); + if (dictresize(mp, estimate_log2_keysize(PyDict_GET_SIZE(iterable)), unicode)) { Py_DECREF(d); return NULL; } while (_PyDict_Next(iterable, &pos, &key, &oldvalue, &hash)) { - Py_INCREF(key); - Py_INCREF(value); - if (insertdict(mp, key, hash, value)) { + if (insertdict(mp, Py_NewRef(key), hash, Py_NewRef(value))) { Py_DECREF(d); return NULL; } @@ -1946,15 +2255,13 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) PyObject *key; Py_hash_t hash; - if (dictresize(mp, estimate_log2_keysize(PySet_GET_SIZE(iterable)))) { + if (dictresize(mp, estimate_log2_keysize(PySet_GET_SIZE(iterable)), 0)) { Py_DECREF(d); return NULL; } while (_PySet_NextEntry(iterable, &pos, &key, &hash)) { - Py_INCREF(key); - Py_INCREF(value); - if (insertdict(mp, key, hash, value)) { + if (insertdict(mp, Py_NewRef(key), hash, Py_NewRef(value))) { Py_DECREF(d); return NULL; } @@ -2001,6 +2308,7 @@ Fail: static void dict_dealloc(PyDictObject *mp) { + _PyDict_NotifyEvent(PyDict_EVENT_DEALLOCATED, mp, NULL, NULL); PyDictValues *values = mp->ma_values; PyDictKeysObject *keys = mp->ma_keys; Py_ssize_t i, n; @@ -2009,16 +2317,14 @@ dict_dealloc(PyDictObject *mp) PyObject_GC_UnTrack(mp); Py_TRASHCAN_BEGIN(mp, dict_dealloc) if (values != NULL) { - if (values != empty_values) { - for (i = 0, n = mp->ma_keys->dk_nentries; i < n; i++) { - Py_XDECREF(values->values[i]); - } - free_values(values); + for (i = 0, n = mp->ma_keys->dk_nentries; i < n; i++) { + Py_XDECREF(values->values[i]); } + free_values(values); dictkeys_decref(keys); } else if (keys != NULL) { - assert(keys->dk_refcnt == 1); + assert(keys->dk_refcnt == 1 || keys == Py_EMPTY_KEYS); dictkeys_decref(keys); } #if PyDict_MAXFREELIST > 0 @@ -2029,6 +2335,7 @@ dict_dealloc(PyDictObject *mp) #endif if (state->numfree < PyDict_MAXFREELIST && Py_IS_TYPE(mp, &PyDict_Type)) { state->free_list[state->numfree++] = mp; + OBJECT_STAT_INC(to_freelist); } else #endif @@ -2135,8 +2442,7 @@ dict_subscript(PyDictObject *mp, PyObject *key) Py_hash_t hash; PyObject *value; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) return NULL; @@ -2148,8 +2454,8 @@ dict_subscript(PyDictObject *mp, PyObject *key) if (!PyDict_CheckExact(mp)) { /* Look up __missing__ method if we're a subclass. */ PyObject *missing, *res; - _Py_IDENTIFIER(__missing__); - missing = _PyObject_LookupSpecial((PyObject *)mp, &PyId___missing__); + missing = _PyObject_LookupSpecial( + (PyObject *)mp, &_Py_ID(__missing__)); if (missing != NULL) { res = PyObject_CallOneArg(missing, key); Py_DECREF(missing); @@ -2161,8 +2467,7 @@ dict_subscript(PyDictObject *mp, PyObject *key) _PyErr_SetKeyError(key); return NULL; } - Py_INCREF(value); - return value; + return Py_NewRef(value); } static int @@ -2184,10 +2489,7 @@ static PyObject * dict_keys(PyDictObject *mp) { PyObject *v; - Py_ssize_t i, j; - PyDictKeyEntry *ep; - Py_ssize_t n, offset; - PyObject **value_ptr; + Py_ssize_t n; again: n = mp->ma_used; @@ -2201,23 +2503,14 @@ dict_keys(PyDictObject *mp) Py_DECREF(v); goto again; } - ep = DK_ENTRIES(mp->ma_keys); - if (mp->ma_values) { - value_ptr = mp->ma_values->values; - offset = sizeof(PyObject *); - } - else { - value_ptr = &ep[0].me_value; - offset = sizeof(PyDictKeyEntry); - } - for (i = 0, j = 0; j < n; i++) { - if (*value_ptr != NULL) { - PyObject *key = ep[i].me_key; - Py_INCREF(key); - PyList_SET_ITEM(v, j, key); - j++; - } - value_ptr = (PyObject **)(((char *)value_ptr) + offset); + + /* Nothing we do below makes any function calls. */ + Py_ssize_t j = 0, pos = 0; + PyObject *key; + while (_PyDict_Next((PyObject*)mp, &pos, &key, NULL, NULL)) { + assert(j < n); + PyList_SET_ITEM(v, j, Py_NewRef(key)); + j++; } assert(j == n); return v; @@ -2227,10 +2520,7 @@ static PyObject * dict_values(PyDictObject *mp) { PyObject *v; - Py_ssize_t i, j; - PyDictKeyEntry *ep; - Py_ssize_t n, offset; - PyObject **value_ptr; + Py_ssize_t n; again: n = mp->ma_used; @@ -2244,23 +2534,14 @@ dict_values(PyDictObject *mp) Py_DECREF(v); goto again; } - ep = DK_ENTRIES(mp->ma_keys); - if (mp->ma_values) { - value_ptr = mp->ma_values->values; - offset = sizeof(PyObject *); - } - else { - value_ptr = &ep[0].me_value; - offset = sizeof(PyDictKeyEntry); - } - for (i = 0, j = 0; j < n; i++) { - PyObject *value = *value_ptr; - value_ptr = (PyObject **)(((char *)value_ptr) + offset); - if (value != NULL) { - Py_INCREF(value); - PyList_SET_ITEM(v, j, value); - j++; - } + + /* Nothing we do below makes any function calls. */ + Py_ssize_t j = 0, pos = 0; + PyObject *value; + while (_PyDict_Next((PyObject*)mp, &pos, NULL, &value, NULL)) { + assert(j < n); + PyList_SET_ITEM(v, j, Py_NewRef(value)); + j++; } assert(j == n); return v; @@ -2270,11 +2551,8 @@ static PyObject * dict_items(PyDictObject *mp) { PyObject *v; - Py_ssize_t i, j, n; - Py_ssize_t offset; - PyObject *item, *key; - PyDictKeyEntry *ep; - PyObject **value_ptr; + Py_ssize_t i, n; + PyObject *item; /* Preallocate the list of tuples, to avoid allocations during * the loop over the items, which could trigger GC, which @@ -2300,28 +2578,16 @@ dict_items(PyDictObject *mp) Py_DECREF(v); goto again; } + /* Nothing we do below makes any function calls. */ - ep = DK_ENTRIES(mp->ma_keys); - if (mp->ma_values) { - value_ptr = mp->ma_values->values; - offset = sizeof(PyObject *); - } - else { - value_ptr = &ep[0].me_value; - offset = sizeof(PyDictKeyEntry); - } - for (i = 0, j = 0; j < n; i++) { - PyObject *value = *value_ptr; - value_ptr = (PyObject **)(((char *)value_ptr) + offset); - if (value != NULL) { - key = ep[i].me_key; - item = PyList_GET_ITEM(v, j); - Py_INCREF(key); - PyTuple_SET_ITEM(item, 0, key); - Py_INCREF(value); - PyTuple_SET_ITEM(item, 1, value); - j++; - } + Py_ssize_t j = 0, pos = 0; + PyObject *key, *value; + while (_PyDict_Next((PyObject*)mp, &pos, &key, &value, NULL)) { + assert(j < n); + PyObject *item = PyList_GET_ITEM(v, j); + PyTuple_SET_ITEM(item, 0, Py_NewRef(key)); + PyTuple_SET_ITEM(item, 1, Py_NewRef(value)); + j++; } assert(j == n); return v; @@ -2351,9 +2617,8 @@ dict_update_arg(PyObject *self, PyObject *arg) if (PyDict_CheckExact(arg)) { return PyDict_Merge(self, arg, 1); } - _Py_IDENTIFIER(keys); PyObject *func; - if (_PyObject_LookupAttrId(arg, &PyId_keys, &func) < 0) { + if (_PyObject_LookupAttr(arg, &_Py_ID(keys), &func) < 0) { return -1; } if (func != NULL) { @@ -2496,8 +2761,6 @@ static int dict_merge(PyObject *a, PyObject *b, int override) { PyDictObject *mp, *other; - Py_ssize_t i, n; - PyDictKeyEntry *entry, *ep0; assert(0 <= override && override <= 2); @@ -2527,8 +2790,9 @@ dict_merge(PyObject *a, PyObject *b, int override) // If other is clean, combined, and just allocated, just clone it. if (other->ma_values == NULL && other->ma_used == okeys->dk_nentries && - (DK_SIZE(okeys) == PyDict_MINSIZE || + (DK_LOG_SIZE(okeys) == PyDict_LOG_MINSIZE || USABLE_FRACTION(DK_SIZE(okeys)/2) < other->ma_used)) { + uint64_t new_version = _PyDict_NotifyEvent(PyDict_EVENT_CLONED, mp, b, NULL); PyDictKeysObject *keys = clone_combined_dict_keys(other); if (keys == NULL) { return -1; @@ -2537,14 +2801,12 @@ dict_merge(PyObject *a, PyObject *b, int override) dictkeys_decref(mp->ma_keys); mp->ma_keys = keys; if (mp->ma_values != NULL) { - if (mp->ma_values != empty_values) { - free_values(mp->ma_values); - } + free_values(mp->ma_values); mp->ma_values = NULL; } mp->ma_used = other->ma_used; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; ASSERT_CONSISTENT(mp); if (_PyObject_GC_IS_TRACKED(other) && !_PyObject_GC_IS_TRACKED(mp)) { @@ -2560,58 +2822,48 @@ dict_merge(PyObject *a, PyObject *b, int override) * that there will be no (or few) overlapping keys. */ if (USABLE_FRACTION(DK_SIZE(mp->ma_keys)) < other->ma_used) { - if (dictresize(mp, estimate_log2_keysize(mp->ma_used + other->ma_used))) { + int unicode = DK_IS_UNICODE(other->ma_keys); + if (dictresize(mp, estimate_log2_keysize(mp->ma_used + other->ma_used), unicode)) { return -1; } } - ep0 = DK_ENTRIES(other->ma_keys); - for (i = 0, n = other->ma_keys->dk_nentries; i < n; i++) { - PyObject *key, *value; - Py_hash_t hash; - entry = &ep0[i]; - key = entry->me_key; - hash = entry->me_hash; - if (other->ma_values) - value = other->ma_values->values[i]; - else - value = entry->me_value; - if (value != NULL) { - int err = 0; - Py_INCREF(key); - Py_INCREF(value); - if (override == 1) { - Py_INCREF(key); - Py_INCREF(value); - err = insertdict(mp, key, hash, value); - } - else { - err = _PyDict_Contains_KnownHash(a, key, hash); - if (err == 0) { - Py_INCREF(key); - Py_INCREF(value); - err = insertdict(mp, key, hash, value); - } - else if (err > 0) { - if (override != 0) { - _PyErr_SetKeyError(key); - Py_DECREF(value); - Py_DECREF(key); - return -1; - } - err = 0; - } - } - Py_DECREF(value); - Py_DECREF(key); - if (err != 0) - return -1; + Py_ssize_t orig_size = other->ma_keys->dk_nentries; + Py_ssize_t pos = 0; + Py_hash_t hash; + PyObject *key, *value; - if (n != other->ma_keys->dk_nentries) { - PyErr_SetString(PyExc_RuntimeError, - "dict mutated during update"); - return -1; + while (_PyDict_Next((PyObject*)other, &pos, &key, &value, &hash)) { + int err = 0; + Py_INCREF(key); + Py_INCREF(value); + if (override == 1) { + err = insertdict(mp, Py_NewRef(key), hash, Py_NewRef(value)); + } + else { + err = _PyDict_Contains_KnownHash(a, key, hash); + if (err == 0) { + err = insertdict(mp, Py_NewRef(key), hash, Py_NewRef(value)); } + else if (err > 0) { + if (override != 0) { + _PyErr_SetKeyError(key); + Py_DECREF(value); + Py_DECREF(key); + return -1; + } + err = 0; + } + } + Py_DECREF(value); + Py_DECREF(key); + if (err != 0) + return -1; + + if (orig_size != other->ma_keys->dk_nentries) { + PyErr_SetString(PyExc_RuntimeError, + "dict mutated during update"); + return -1; } } } @@ -2704,7 +2956,6 @@ PyDict_Copy(PyObject *o) { PyObject *copy; PyDictObject *mp; - Py_ssize_t i, n; if (o == NULL || !PyDict_Check(o)) { PyErr_BadInternalCall(); @@ -2719,9 +2970,8 @@ PyDict_Copy(PyObject *o) if (_PyDict_HasSplitTable(mp)) { PyDictObject *split_copy; - Py_ssize_t size = shared_keys_usable_size(mp->ma_keys); - PyDictValues *newvalues; - newvalues = new_values(size); + size_t size = shared_keys_usable_size(mp->ma_keys); + PyDictValues *newvalues = new_values(size); if (newvalues == NULL) return PyErr_NoMemory(); split_copy = PyObject_GC_New(PyDictObject, &PyDict_Type); @@ -2729,16 +2979,16 @@ PyDict_Copy(PyObject *o) free_values(newvalues); return NULL; } - newvalues->mv_order = mp->ma_values->mv_order; + size_t prefix_size = ((uint8_t *)newvalues)[-1]; + memcpy(((char *)newvalues)-prefix_size, ((char *)mp->ma_values)-prefix_size, prefix_size-1); split_copy->ma_values = newvalues; split_copy->ma_keys = mp->ma_keys; split_copy->ma_used = mp->ma_used; split_copy->ma_version_tag = DICT_NEXT_VERSION(); dictkeys_incref(mp->ma_keys); - for (i = 0, n = size; i < n; i++) { + for (size_t i = 0; i < size; i++) { PyObject *value = mp->ma_values->values[i]; - Py_XINCREF(value); - split_copy->ma_values->values[i] = value; + split_copy->ma_values->values[i] = Py_XNewRef(value); } if (_PyObject_GC_IS_TRACKED(mp)) _PyObject_GC_TRACK(split_copy); @@ -2847,23 +3097,36 @@ dict_equal(PyDictObject *a, PyDictObject *b) return 0; /* Same # of entries -- check all of 'em. Exit early on any diff. */ for (i = 0; i < a->ma_keys->dk_nentries; i++) { - PyDictKeyEntry *ep = &DK_ENTRIES(a->ma_keys)[i]; - PyObject *aval; - if (a->ma_values) - aval = a->ma_values->values[i]; - else + PyObject *key, *aval; + Py_hash_t hash; + if (DK_IS_UNICODE(a->ma_keys)) { + PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(a->ma_keys)[i]; + key = ep->me_key; + if (key == NULL) { + continue; + } + hash = unicode_get_hash(key); + if (a->ma_values) + aval = a->ma_values->values[i]; + else + aval = ep->me_value; + } + else { + PyDictKeyEntry *ep = &DK_ENTRIES(a->ma_keys)[i]; + key = ep->me_key; aval = ep->me_value; + hash = ep->me_hash; + } if (aval != NULL) { int cmp; PyObject *bval; - PyObject *key = ep->me_key; /* temporarily bump aval's refcount to ensure it stays alive until we're done with it */ Py_INCREF(aval); /* ditto for key */ Py_INCREF(key); /* reuse the known hash value */ - _Py_dict_lookup(b, key, ep->me_hash, &bval); + _Py_dict_lookup(b, key, hash, &bval); if (bval == NULL) { Py_DECREF(key); Py_DECREF(aval); @@ -2900,8 +3163,7 @@ dict_richcompare(PyObject *v, PyObject *w, int op) } else res = Py_NotImplemented; - Py_INCREF(res); - return res; + return Py_NewRef(res); } /*[clinic input] @@ -2924,8 +3186,7 @@ dict___contains__(PyDictObject *self, PyObject *key) Py_ssize_t ix; PyObject *value; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) return NULL; @@ -2956,8 +3217,7 @@ dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value) Py_hash_t hash; Py_ssize_t ix; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) return NULL; @@ -2968,8 +3228,7 @@ dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value) if (ix == DKIX_EMPTY || val == NULL) { val = default_value; } - Py_INCREF(val); - return val; + return Py_NewRef(val); } PyObject * @@ -2984,25 +3243,24 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) return NULL; } - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) return NULL; } if (mp->ma_keys == Py_EMPTY_KEYS) { - Py_INCREF(key); - Py_INCREF(defaultobj); - if (insert_to_emptydict(mp, key, hash, defaultobj) < 0) { + if (insert_to_emptydict(mp, Py_NewRef(key), hash, + Py_NewRef(defaultobj)) < 0) { return NULL; } return defaultobj; } - if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) { - if (insertion_resize(mp) < 0) + if (!PyUnicode_CheckExact(key) && DK_IS_UNICODE(mp->ma_keys)) { + if (insertion_resize(mp, 0) < 0) { return NULL; + } } Py_ssize_t ix = _Py_dict_lookup(mp, key, hash, &value); @@ -3010,52 +3268,54 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) return NULL; if (ix == DKIX_EMPTY) { + uint64_t new_version = _PyDict_NotifyEvent(PyDict_EVENT_ADDED, mp, key, defaultobj); mp->ma_keys->dk_version = 0; - PyDictKeyEntry *ep, *ep0; value = defaultobj; if (mp->ma_keys->dk_usable <= 0) { - if (insertion_resize(mp) < 0) { + if (insertion_resize(mp, 1) < 0) { return NULL; } } - if (!PyUnicode_CheckExact(key) && mp->ma_keys->dk_kind != DICT_KEYS_GENERAL) { - mp->ma_keys->dk_kind = DICT_KEYS_GENERAL; - } Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash); - ep0 = DK_ENTRIES(mp->ma_keys); - ep = &ep0[mp->ma_keys->dk_nentries]; dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries); - Py_INCREF(key); - Py_INCREF(value); - MAINTAIN_TRACKING(mp, key, value); - ep->me_key = key; - ep->me_hash = hash; - if (_PyDict_HasSplitTable(mp)) { - int index = (int)mp->ma_keys->dk_nentries; - assert(index < SHARED_KEYS_MAX_SIZE); - assert(mp->ma_values->values[index] == NULL); - mp->ma_values->values[index] = value; - mp->ma_values->mv_order = (mp->ma_values->mv_order << 4) | index; + if (DK_IS_UNICODE(mp->ma_keys)) { + assert(PyUnicode_CheckExact(key)); + PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; + ep->me_key = Py_NewRef(key); + if (_PyDict_HasSplitTable(mp)) { + Py_ssize_t index = (int)mp->ma_keys->dk_nentries; + assert(index < SHARED_KEYS_MAX_SIZE); + assert(mp->ma_values->values[index] == NULL); + mp->ma_values->values[index] = Py_NewRef(value); + _PyDictValues_AddToInsertionOrder(mp->ma_values, index); + } + else { + ep->me_value = Py_NewRef(value); + } } else { - ep->me_value = value; + PyDictKeyEntry *ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; + ep->me_key = Py_NewRef(key); + ep->me_hash = hash; + ep->me_value = Py_NewRef(value); } + MAINTAIN_TRACKING(mp, key, value); mp->ma_used++; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; mp->ma_keys->dk_usable--; mp->ma_keys->dk_nentries++; assert(mp->ma_keys->dk_usable >= 0); } else if (value == NULL) { + uint64_t new_version = _PyDict_NotifyEvent(PyDict_EVENT_ADDED, mp, key, defaultobj); value = defaultobj; assert(_PyDict_HasSplitTable(mp)); assert(mp->ma_values->values[ix] == NULL); - Py_INCREF(value); MAINTAIN_TRACKING(mp, key, value); - mp->ma_values->values[ix] = value; - mp->ma_values->mv_order = (mp->ma_values->mv_order << 4) | ix; + mp->ma_values->values[ix] = Py_NewRef(value); + _PyDictValues_AddToInsertionOrder(mp->ma_values, ix); mp->ma_used++; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; } ASSERT_CONSISTENT(mp); @@ -3082,8 +3342,7 @@ dict_setdefault_impl(PyDictObject *self, PyObject *key, PyObject *val; val = PyDict_SetDefault((PyObject *)self, key, default_value); - Py_XINCREF(val); - return val; + return Py_XNewRef(val); } static PyObject * @@ -3127,8 +3386,8 @@ dict_popitem_impl(PyDictObject *self) /*[clinic end generated code: output=e65fcb04420d230d input=1c38a49f21f64941]*/ { Py_ssize_t i, j; - PyDictKeyEntry *ep0, *ep; PyObject *res; + uint64_t new_version; /* Allocate the result tuple before checking the size. Believe it * or not, this allocation could trigger a garbage collection which @@ -3149,7 +3408,7 @@ dict_popitem_impl(PyDictObject *self) } /* Convert split table to combined table */ if (self->ma_keys->dk_kind == DICT_KEYS_SPLIT) { - if (dictresize(self, DK_LOG_SIZE(self->ma_keys))) { + if (dictresize(self, DK_LOG_SIZE(self->ma_keys), 1)) { Py_DECREF(res); return NULL; } @@ -3157,27 +3416,51 @@ dict_popitem_impl(PyDictObject *self) self->ma_keys->dk_version = 0; /* Pop last item */ - ep0 = DK_ENTRIES(self->ma_keys); - i = self->ma_keys->dk_nentries - 1; - while (i >= 0 && ep0[i].me_value == NULL) { - i--; - } - assert(i >= 0); + PyObject *key, *value; + Py_hash_t hash; + if (DK_IS_UNICODE(self->ma_keys)) { + PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(self->ma_keys); + i = self->ma_keys->dk_nentries - 1; + while (i >= 0 && ep0[i].me_value == NULL) { + i--; + } + assert(i >= 0); - ep = &ep0[i]; - j = lookdict_index(self->ma_keys, ep->me_hash, i); + key = ep0[i].me_key; + new_version = _PyDict_NotifyEvent(PyDict_EVENT_DELETED, self, key, NULL); + hash = unicode_get_hash(key); + value = ep0[i].me_value; + ep0[i].me_key = NULL; + ep0[i].me_value = NULL; + } + else { + PyDictKeyEntry *ep0 = DK_ENTRIES(self->ma_keys); + i = self->ma_keys->dk_nentries - 1; + while (i >= 0 && ep0[i].me_value == NULL) { + i--; + } + assert(i >= 0); + + key = ep0[i].me_key; + new_version = _PyDict_NotifyEvent(PyDict_EVENT_DELETED, self, key, NULL); + hash = ep0[i].me_hash; + value = ep0[i].me_value; + ep0[i].me_key = NULL; + ep0[i].me_hash = -1; + ep0[i].me_value = NULL; + } + + j = lookdict_index(self->ma_keys, hash, i); assert(j >= 0); assert(dictkeys_get_index(self->ma_keys, j) == i); dictkeys_set_index(self->ma_keys, j, DKIX_DUMMY); - PyTuple_SET_ITEM(res, 0, ep->me_key); - PyTuple_SET_ITEM(res, 1, ep->me_value); - ep->me_key = NULL; - ep->me_value = NULL; + PyTuple_SET_ITEM(res, 0, key); + PyTuple_SET_ITEM(res, 1, value); /* We can't dk_usable++ since there is DKIX_DUMMY in indices */ self->ma_keys->dk_nentries = i; self->ma_used--; - self->ma_version_tag = DICT_NEXT_VERSION(); + self->ma_version_tag = new_version; ASSERT_CONSISTENT(self); return res; } @@ -3187,29 +3470,30 @@ dict_traverse(PyObject *op, visitproc visit, void *arg) { PyDictObject *mp = (PyDictObject *)op; PyDictKeysObject *keys = mp->ma_keys; - PyDictKeyEntry *entries = DK_ENTRIES(keys); Py_ssize_t i, n = keys->dk_nentries; - if (keys->dk_kind == DICT_KEYS_GENERAL) { - for (i = 0; i < n; i++) { - if (entries[i].me_value != NULL) { - Py_VISIT(entries[i].me_value); - Py_VISIT(entries[i].me_key); - } - } - } - else { + if (DK_IS_UNICODE(keys)) { if (mp->ma_values != NULL) { for (i = 0; i < n; i++) { Py_VISIT(mp->ma_values->values[i]); } } else { + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(keys); for (i = 0; i < n; i++) { Py_VISIT(entries[i].me_value); } } } + else { + PyDictKeyEntry *entries = DK_ENTRIES(keys); + for (i = 0; i < n; i++) { + if (entries[i].me_value != NULL) { + Py_VISIT(entries[i].me_value); + Py_VISIT(entries[i].me_key); + } + } + } return 0; } @@ -3225,31 +3509,28 @@ static PyObject *dictiter_new(PyDictObject *, PyTypeObject *); Py_ssize_t _PyDict_SizeOf(PyDictObject *mp) { - Py_ssize_t size, res; - - size = DK_SIZE(mp->ma_keys); - - res = _PyObject_SIZE(Py_TYPE(mp)); + size_t res = _PyObject_SIZE(Py_TYPE(mp)); if (mp->ma_values) { res += shared_keys_usable_size(mp->ma_keys) * sizeof(PyObject*); } /* If the dictionary is split, the keys portion is accounted-for in the type object. */ if (mp->ma_keys->dk_refcnt == 1) { - Py_ssize_t usable = USABLE_FRACTION(size); - res += (sizeof(PyDictKeysObject) - + DK_IXSIZE(mp->ma_keys) * size - + sizeof(PyDictKeyEntry) * usable); + res += _PyDict_KeysSize(mp->ma_keys); } - return res; + assert(res <= (size_t)PY_SSIZE_T_MAX); + return (Py_ssize_t)res; } -Py_ssize_t +size_t _PyDict_KeysSize(PyDictKeysObject *keys) { - return (sizeof(PyDictKeysObject) - + DK_IXSIZE(keys) * DK_SIZE(keys) - + USABLE_FRACTION(DK_SIZE(keys)) * sizeof(PyDictKeyEntry)); + size_t es = (keys->dk_kind == DICT_KEYS_GENERAL + ? sizeof(PyDictKeyEntry) : sizeof(PyDictUnicodeEntry)); + size_t size = sizeof(PyDictKeysObject); + size += (size_t)1 << keys->dk_log2_index_bytes; + size += USABLE_FRACTION((size_t)DK_SIZE(keys)) * es; + return size; } static PyObject * @@ -3281,11 +3562,11 @@ dict_ior(PyObject *self, PyObject *other) if (dict_update_arg(self, other)) { return NULL; } - Py_INCREF(self); - return self; + return Py_NewRef(self); } -PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]"); +PyDoc_STRVAR(getitem__doc__, +"__getitem__($self, key, /)\n--\n\nReturn self[key]."); PyDoc_STRVAR(sizeof__doc__, "D.__sizeof__() -> size of D in memory, in bytes"); @@ -3316,9 +3597,9 @@ PyDoc_STRVAR(values__doc__, static PyMethodDef mapp_methods[] = { DICT___CONTAINS___METHODDEF - {"__getitem__", (PyCFunction)(void(*)(void))dict_subscript, METH_O | METH_COEXIST, + {"__getitem__", _PyCFunction_CAST(dict_subscript), METH_O | METH_COEXIST, getitem__doc__}, - {"__sizeof__", (PyCFunction)(void(*)(void))dict_sizeof, METH_NOARGS, + {"__sizeof__", _PyCFunction_CAST(dict_sizeof), METH_NOARGS, sizeof__doc__}, DICT_GET_METHODDEF DICT_SETDEFAULT_METHODDEF @@ -3330,7 +3611,7 @@ static PyMethodDef mapp_methods[] = { items__doc__}, {"values", dictvalues_new, METH_NOARGS, values__doc__}, - {"update", (PyCFunction)(void(*)(void))dict_update, METH_VARARGS | METH_KEYWORDS, + {"update", _PyCFunction_CAST(dict_update), METH_VARARGS | METH_KEYWORDS, update__doc__}, DICT_FROMKEYS_METHODDEF {"clear", (PyCFunction)dict_clear, METH_NOARGS, @@ -3351,8 +3632,7 @@ PyDict_Contains(PyObject *op, PyObject *key) PyDictObject *mp = (PyDictObject *)op; PyObject *value; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) return -1; @@ -3378,7 +3658,7 @@ _PyDict_Contains_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) } int -_PyDict_ContainsId(PyObject *op, struct _Py_Identifier *key) +_PyDict_ContainsId(PyObject *op, _Py_Identifier *key) { PyObject *kv = _PyUnicode_FromId(key); /* borrowed */ if (kv == NULL) { @@ -3424,7 +3704,7 @@ dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) d->ma_version_tag = DICT_NEXT_VERSION(); dictkeys_incref(Py_EMPTY_KEYS); d->ma_keys = Py_EMPTY_KEYS; - d->ma_values = empty_values; + d->ma_values = NULL; ASSERT_CONSISTENT(d); if (type != &PyDict_Type) { @@ -3450,13 +3730,12 @@ static PyObject * dict_vectorcall(PyObject *type, PyObject * const*args, size_t nargsf, PyObject *kwnames) { - assert(PyType_Check(type)); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); if (!_PyArg_CheckPositional("dict", nargs, 0, 1)) { return NULL; } - PyObject *self = dict_new((PyTypeObject *)type, NULL, NULL); + PyObject *self = dict_new(_PyType_CAST(type), NULL, NULL); if (self == NULL) { return NULL; } @@ -3557,7 +3836,7 @@ PyDict_GetItemString(PyObject *v, const char *key) } int -_PyDict_SetItemId(PyObject *v, struct _Py_Identifier *key, PyObject *item) +_PyDict_SetItemId(PyObject *v, _Py_Identifier *key, PyObject *item) { PyObject *kv; kv = _PyUnicode_FromId(key); /* borrowed */ @@ -3621,8 +3900,7 @@ dictiter_new(PyDictObject *dict, PyTypeObject *itertype) if (di == NULL) { return NULL; } - Py_INCREF(dict); - di->di_dict = dict; + di->di_dict = (PyDictObject*)Py_NewRef(dict); di->di_used = dict->ma_used; di->len = dict->ma_used; if (itertype == &PyDictRevIterKey_Type || @@ -3689,9 +3967,9 @@ dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored)); PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); static PyMethodDef dictiter_methods[] = { - {"__length_hint__", (PyCFunction)(void(*)(void))dictiter_len, METH_NOARGS, + {"__length_hint__", _PyCFunction_CAST(dictiter_len), METH_NOARGS, length_hint_doc}, - {"__reduce__", (PyCFunction)(void(*)(void))dictiter_reduce, METH_NOARGS, + {"__reduce__", _PyCFunction_CAST(dictiter_reduce), METH_NOARGS, reduce_doc}, {NULL, NULL} /* sentinel */ }; @@ -3722,19 +4000,31 @@ dictiter_iternextkey(dictiterobject *di) if (i >= d->ma_used) goto fail; int index = get_index_from_order(d, i); - key = DK_ENTRIES(k)[index].me_key; + key = DK_UNICODE_ENTRIES(k)[index].me_key; assert(d->ma_values->values[index] != NULL); } else { Py_ssize_t n = k->dk_nentries; - PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i]; - while (i < n && entry_ptr->me_value == NULL) { - entry_ptr++; - i++; + if (DK_IS_UNICODE(k)) { + PyDictUnicodeEntry *entry_ptr = &DK_UNICODE_ENTRIES(k)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + goto fail; + key = entry_ptr->me_key; + } + else { + PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + goto fail; + key = entry_ptr->me_key; } - if (i >= n) - goto fail; - key = entry_ptr->me_key; } // We found an element (key), but did not expect it if (di->len == 0) { @@ -3744,8 +4034,7 @@ dictiter_iternextkey(dictiterobject *di) } di->di_pos = i+1; di->len--; - Py_INCREF(key); - return key; + return Py_NewRef(key); fail: di->di_dict = NULL; @@ -3815,14 +4104,26 @@ dictiter_iternextvalue(dictiterobject *di) } else { Py_ssize_t n = d->ma_keys->dk_nentries; - PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i]; - while (i < n && entry_ptr->me_value == NULL) { - entry_ptr++; - i++; + if (DK_IS_UNICODE(d->ma_keys)) { + PyDictUnicodeEntry *entry_ptr = &DK_UNICODE_ENTRIES(d->ma_keys)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + goto fail; + value = entry_ptr->me_value; + } + else { + PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + goto fail; + value = entry_ptr->me_value; } - if (i >= n) - goto fail; - value = entry_ptr->me_value; } // We found an element, but did not expect it if (di->len == 0) { @@ -3832,8 +4133,7 @@ dictiter_iternextvalue(dictiterobject *di) } di->di_pos = i+1; di->len--; - Py_INCREF(value); - return value; + return Py_NewRef(value); fail: di->di_dict = NULL; @@ -3898,21 +4198,34 @@ dictiter_iternextitem(dictiterobject *di) if (i >= d->ma_used) goto fail; int index = get_index_from_order(d, i); - key = DK_ENTRIES(d->ma_keys)[index].me_key; + key = DK_UNICODE_ENTRIES(d->ma_keys)[index].me_key; value = d->ma_values->values[index]; assert(value != NULL); } else { Py_ssize_t n = d->ma_keys->dk_nentries; - PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i]; - while (i < n && entry_ptr->me_value == NULL) { - entry_ptr++; - i++; + if (DK_IS_UNICODE(d->ma_keys)) { + PyDictUnicodeEntry *entry_ptr = &DK_UNICODE_ENTRIES(d->ma_keys)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + goto fail; + key = entry_ptr->me_key; + value = entry_ptr->me_value; + } + else { + PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + goto fail; + key = entry_ptr->me_key; + value = entry_ptr->me_value; } - if (i >= n) - goto fail; - key = entry_ptr->me_key; - value = entry_ptr->me_value; } // We found an element, but did not expect it if (di->len == 0) { @@ -3922,14 +4235,12 @@ dictiter_iternextitem(dictiterobject *di) } di->di_pos = i+1; di->len--; - Py_INCREF(key); - Py_INCREF(value); result = di->di_result; if (Py_REFCNT(result) == 1) { PyObject *oldkey = PyTuple_GET_ITEM(result, 0); PyObject *oldvalue = PyTuple_GET_ITEM(result, 1); - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + PyTuple_SET_ITEM(result, 0, Py_NewRef(key)); + PyTuple_SET_ITEM(result, 1, Py_NewRef(value)); Py_INCREF(result); Py_DECREF(oldkey); Py_DECREF(oldvalue); @@ -3943,8 +4254,8 @@ dictiter_iternextitem(dictiterobject *di) result = PyTuple_New(2); if (result == NULL) return NULL; - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + PyTuple_SET_ITEM(result, 0, Py_NewRef(key)); + PyTuple_SET_ITEM(result, 1, Py_NewRef(value)); } return result; @@ -4016,41 +4327,50 @@ dictreviter_iternext(dictiterobject *di) } if (d->ma_values) { int index = get_index_from_order(d, i); - key = DK_ENTRIES(k)[index].me_key; + key = DK_UNICODE_ENTRIES(k)[index].me_key; value = d->ma_values->values[index]; assert (value != NULL); } else { - PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i]; - while (entry_ptr->me_value == NULL) { - if (--i < 0) { - goto fail; + if (DK_IS_UNICODE(k)) { + PyDictUnicodeEntry *entry_ptr = &DK_UNICODE_ENTRIES(k)[i]; + while (entry_ptr->me_value == NULL) { + if (--i < 0) { + goto fail; + } + entry_ptr--; } - entry_ptr--; + key = entry_ptr->me_key; + value = entry_ptr->me_value; + } + else { + PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i]; + while (entry_ptr->me_value == NULL) { + if (--i < 0) { + goto fail; + } + entry_ptr--; + } + key = entry_ptr->me_key; + value = entry_ptr->me_value; } - key = entry_ptr->me_key; - value = entry_ptr->me_value; } di->di_pos = i-1; di->len--; if (Py_IS_TYPE(di, &PyDictRevIterKey_Type)) { - Py_INCREF(key); - return key; + return Py_NewRef(key); } else if (Py_IS_TYPE(di, &PyDictRevIterValue_Type)) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } else if (Py_IS_TYPE(di, &PyDictRevIterItem_Type)) { - Py_INCREF(key); - Py_INCREF(value); result = di->di_result; if (Py_REFCNT(result) == 1) { PyObject *oldkey = PyTuple_GET_ITEM(result, 0); PyObject *oldvalue = PyTuple_GET_ITEM(result, 1); - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + PyTuple_SET_ITEM(result, 0, Py_NewRef(key)); + PyTuple_SET_ITEM(result, 1, Py_NewRef(value)); Py_INCREF(result); Py_DECREF(oldkey); Py_DECREF(oldvalue); @@ -4065,8 +4385,8 @@ dictreviter_iternext(dictiterobject *di) if (result == NULL) { return NULL; } - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + PyTuple_SET_ITEM(result, 0, Py_NewRef(key)); + PyTuple_SET_ITEM(result, 1, Py_NewRef(value)); } return result; } @@ -4110,17 +4430,15 @@ dict___reversed___impl(PyDictObject *self) static PyObject * dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(iter); /* copy the iterator state */ dictiterobject tmp = *di; Py_XINCREF(tmp.di_dict); - PyObject *list = PySequence_List((PyObject*)&tmp); Py_XDECREF(tmp.di_dict); if (list == NULL) { return NULL; } - return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list); + return Py_BuildValue("N(N)", _PyEval_GetBuiltin(&_Py_ID(iter)), list); } PyTypeObject PyDictRevIterItem_Type = { @@ -4196,8 +4514,7 @@ _PyDictView_New(PyObject *dict, PyTypeObject *type) dv = PyObject_GC_New(_PyDictViewObject, type); if (dv == NULL) return NULL; - Py_INCREF(dict); - dv->dv_dict = (PyDictObject *)dict; + dv->dv_dict = (PyDictObject *)Py_NewRef(dict); _PyObject_GC_TRACK(dv); return (PyObject *)dv; } @@ -4308,8 +4625,7 @@ dictview_richcompare(PyObject *self, PyObject *other, int op) if (ok < 0) return NULL; result = ok ? Py_True : Py_False; - Py_INCREF(result); - return result; + return Py_NewRef(result); } static PyObject * @@ -4365,7 +4681,7 @@ static PySequenceMethods dictkeys_as_sequence = { (objobjproc)dictkeys_contains, /* sq_contains */ }; -// Create an set object from dictviews object. +// Create a set object from dictviews object. // Returns a new reference. // This utility function is used by set operations. static PyObject* @@ -4390,9 +4706,8 @@ dictviews_sub(PyObject *self, PyObject *other) return NULL; } - _Py_IDENTIFIER(difference_update); - PyObject *tmp = _PyObject_CallMethodIdOneArg( - result, &PyId_difference_update, other); + PyObject *tmp = PyObject_CallMethodOneArg( + result, &_Py_ID(difference_update), other); if (tmp == NULL) { Py_DECREF(result); return NULL; @@ -4428,8 +4743,8 @@ _PyDictView_Intersect(PyObject* self, PyObject *other) /* if other is a set and self is smaller than other, reuse set intersection logic */ if (PySet_CheckExact(other) && len_self <= PyObject_Size(other)) { - _Py_IDENTIFIER(intersection); - return _PyObject_CallMethodIdObjArgs(other, &PyId_intersection, self, NULL); + return PyObject_CallMethodObjArgs( + other, &_Py_ID(intersection), self, NULL); } /* if other is another dict view, and it is bigger than self, @@ -4569,9 +4884,8 @@ dictitems_xor(PyObject *self, PyObject *other) } key = val1 = val2 = NULL; - _Py_IDENTIFIER(items); - PyObject *remaining_pairs = _PyObject_CallMethodIdNoArgs(temp_dict, - &PyId_items); + PyObject *remaining_pairs = PyObject_CallMethodNoArgs( + temp_dict, &_Py_ID(items)); if (remaining_pairs == NULL) { goto error; } @@ -4603,9 +4917,8 @@ dictviews_xor(PyObject* self, PyObject *other) return NULL; } - _Py_IDENTIFIER(symmetric_difference_update); - PyObject *tmp = _PyObject_CallMethodIdOneArg( - result, &PyId_symmetric_difference_update, other); + PyObject *tmp = PyObject_CallMethodOneArg( + result, &_Py_ID(symmetric_difference_update), other); if (tmp == NULL) { Py_DECREF(result); return NULL; @@ -4696,7 +5009,7 @@ PyDoc_STRVAR(reversed_keys_doc, static PyMethodDef dictkeys_methods[] = { {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O, isdisjoint_doc}, - {"__reversed__", (PyCFunction)(void(*)(void))dictkeys_reversed, METH_NOARGS, + {"__reversed__", _PyCFunction_CAST(dictkeys_reversed), METH_NOARGS, reversed_keys_doc}, {NULL, NULL} /* sentinel */ }; @@ -4942,7 +5255,7 @@ dictvalues_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored)) PyDictKeysObject * _PyDict_NewKeysForClass(void) { - PyDictKeysObject *keys = new_keys_object(5); /* log2(32) */ + PyDictKeysObject *keys = new_keys_object(NEXT_LOG2_SHARED_KEYS_MAX_SIZE, 1); if (keys == NULL) { PyErr_Clear(); } @@ -4961,25 +5274,25 @@ static int init_inline_values(PyObject *obj, PyTypeObject *tp) { assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE); - assert(tp->tp_dictoffset > 0); - assert(tp->tp_inline_values_offset > 0); + // assert(type->tp_dictoffset > 0); -- TO DO Update this assert. + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); PyDictKeysObject *keys = CACHED_KEYS(tp); assert(keys != NULL); if (keys->dk_usable > 1) { keys->dk_usable--; } - Py_ssize_t size = shared_keys_usable_size(keys); - assert(size > 0); + size_t size = shared_keys_usable_size(keys); PyDictValues *values = new_values(size); if (values == NULL) { PyErr_NoMemory(); return -1; } - values->mv_order = 0; - for (int i = 0; i < size; i++) { + assert(((uint8_t *)values)[-1] >= (size + 2)); + ((uint8_t *)values)[-2] = 0; + for (size_t i = 0; i < size; i++) { values->values[i] = NULL; } - *((PyDictValues **)((char *)obj + tp->tp_inline_values_offset)) = values; + _PyDictOrValues_SetValues(_PyObject_DictOrValuesPointer(obj), values); return 0; } @@ -4990,7 +5303,8 @@ _PyObject_InitializeDict(PyObject *obj) if (tp->tp_dictoffset == 0) { return 0; } - if (tp->tp_inline_values_offset) { + if (tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + OBJECT_STAT_INC(new_values); return init_inline_values(obj, tp); } PyObject *dict; @@ -5004,7 +5318,7 @@ _PyObject_InitializeDict(PyObject *obj) if (dict == NULL) { return -1; } - PyObject **dictptr = _PyObject_DictPointer(obj); + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); *dictptr = dict; return 0; } @@ -5015,7 +5329,8 @@ make_dict_from_instance_attributes(PyDictKeysObject *keys, PyDictValues *values) dictkeys_incref(keys); Py_ssize_t used = 0; Py_ssize_t track = 0; - for (Py_ssize_t i = 0; i < shared_keys_usable_size(keys); i++) { + size_t size = shared_keys_usable_size(keys); + for (size_t i = 0; i < size; i++) { PyObject *val = values->values[i]; if (val != NULL) { used += 1; @@ -5032,8 +5347,8 @@ make_dict_from_instance_attributes(PyDictKeysObject *keys, PyDictValues *values) PyObject * _PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values) { - assert(Py_TYPE(obj)->tp_inline_values_offset != 0); PyDictKeysObject *keys = CACHED_KEYS(Py_TYPE(obj)); + OBJECT_STAT_INC(dict_materialized_on_request); return make_dict_from_instance_attributes(keys, values); } @@ -5041,44 +5356,91 @@ int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject *name, PyObject *value) { - assert(PyUnicode_CheckExact(name)); - PyTypeObject *tp = Py_TYPE(obj); PyDictKeysObject *keys = CACHED_KEYS(Py_TYPE(obj)); assert(keys != NULL); assert(values != NULL); - int ix = insert_into_dictkeys(keys, name); + assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + Py_ssize_t ix = DKIX_EMPTY; + if (PyUnicode_CheckExact(name)) { + ix = insert_into_dictkeys(keys, name); + } if (ix == DKIX_EMPTY) { - if (value == NULL) { - PyErr_SetObject(PyExc_AttributeError, name); - return -1; +#ifdef Py_STATS + if (PyUnicode_CheckExact(name)) { + if (shared_keys_usable_size(keys) == SHARED_KEYS_MAX_SIZE) { + OBJECT_STAT_INC(dict_materialized_too_big); + } + else { + OBJECT_STAT_INC(dict_materialized_new_key); + } } + else { + OBJECT_STAT_INC(dict_materialized_str_subclass); + } +#endif PyObject *dict = make_dict_from_instance_attributes(keys, values); if (dict == NULL) { return -1; } - *((PyDictValues **)((char *)obj + tp->tp_inline_values_offset)) = NULL; - *((PyObject **) ((char *)obj + tp->tp_dictoffset)) = dict; - return PyDict_SetItem(dict, name, value); + _PyObject_DictOrValuesPointer(obj)->dict = dict; + if (value == NULL) { + return PyDict_DelItem(dict, name); + } + else { + return PyDict_SetItem(dict, name, value); + } } PyObject *old_value = values->values[ix]; - Py_XINCREF(value); - values->values[ix] = value; + values->values[ix] = Py_XNewRef(value); if (old_value == NULL) { if (value == NULL) { - PyErr_SetObject(PyExc_AttributeError, name); + PyErr_Format(PyExc_AttributeError, + "'%.100s' object has no attribute '%U'", + Py_TYPE(obj)->tp_name, name); return -1; } - values->mv_order = (values->mv_order << 4) | ix; + _PyDictValues_AddToInsertionOrder(values, ix); } else { if (value == NULL) { - values->mv_order = delete_index_from_order(values->mv_order, ix); + delete_index_from_values(values, ix); } Py_DECREF(old_value); } return 0; } +/* Sanity check for managed dicts */ +#if 0 +#define CHECK(val) assert(val); if (!(val)) { return 0; } + +int +_PyObject_ManagedDictValidityCheck(PyObject *obj) +{ + PyTypeObject *tp = Py_TYPE(obj); + CHECK(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + int size = ((uint8_t *)values)[-2]; + int count = 0; + PyDictKeysObject *keys = CACHED_KEYS(tp); + for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { + if (values->values[i] != NULL) { + count++; + } + } + CHECK(size == count); + } + else { + if (dorv_ptr->dict != NULL) { + CHECK(PyDict_Check(dorv_ptr->dict)); + } + } + return 1; +} +#endif + PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject *name) @@ -5091,8 +5453,7 @@ _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values, return NULL; } PyObject *value = values->values[ix]; - Py_XINCREF(value); - return value; + return Py_XNewRef(value); } int @@ -5102,101 +5463,140 @@ _PyObject_IsInstanceDictEmpty(PyObject *obj) if (tp->tp_dictoffset == 0) { return 1; } - PyDictValues **values_ptr = _PyObject_ValuesPointer(obj); - if (values_ptr && *values_ptr) { - PyDictKeysObject *keys = CACHED_KEYS(tp); - for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - if ((*values_ptr)->values[i] != NULL) { - return 0; + PyObject *dict; + if (tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(dorv)) { + PyDictKeysObject *keys = CACHED_KEYS(tp); + for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { + if (_PyDictOrValues_GetValues(dorv)->values[i] != NULL) { + return 0; + } } + return 1; } - return 1; + dict = _PyDictOrValues_GetDict(dorv); + } + else { + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); + dict = *dictptr; } - PyObject **dictptr = _PyObject_DictPointer(obj); - PyObject *dict = *dictptr; if (dict == NULL) { return 1; } return ((PyDictObject *)dict)->ma_used == 0; } - -int -_PyObject_VisitInstanceAttributes(PyObject *self, visitproc visit, void *arg) +void +_PyObject_FreeInstanceAttributes(PyObject *self) { PyTypeObject *tp = Py_TYPE(self); - assert(tp->tp_inline_values_offset); - PyDictValues **values_ptr = _PyObject_ValuesPointer(self); - if (*values_ptr == NULL) { - return 0; + assert(Py_TYPE(self)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self); + if (!_PyDictOrValues_IsValues(dorv)) { + return; } + PyDictValues *values = _PyDictOrValues_GetValues(dorv); PyDictKeysObject *keys = CACHED_KEYS(tp); for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - Py_VISIT((*values_ptr)->values[i]); + Py_XDECREF(values->values[i]); + } + free_values(values); +} + +int +_PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg) +{ + PyTypeObject *tp = Py_TYPE(obj); + if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { + return 0; + } + assert(tp->tp_dictoffset); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(dorv)) { + PyDictValues *values = _PyDictOrValues_GetValues(dorv); + PyDictKeysObject *keys = CACHED_KEYS(tp); + for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { + Py_VISIT(values->values[i]); + } + } + else { + PyObject *dict = _PyDictOrValues_GetDict(dorv); + Py_VISIT(dict); } return 0; } void -_PyObject_ClearInstanceAttributes(PyObject *self) +_PyObject_ClearManagedDict(PyObject *obj) { - PyTypeObject *tp = Py_TYPE(self); - assert(tp->tp_inline_values_offset); - PyDictValues **values_ptr = _PyObject_ValuesPointer(self); - if (*values_ptr == NULL) { + PyTypeObject *tp = Py_TYPE(obj); + if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { return; } - PyDictKeysObject *keys = CACHED_KEYS(tp); - for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - Py_CLEAR((*values_ptr)->values[i]); + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + PyDictKeysObject *keys = CACHED_KEYS(tp); + for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { + Py_CLEAR(values->values[i]); + } + dorv_ptr->dict = NULL; + free_values(values); } -} - -void -_PyObject_FreeInstanceAttributes(PyObject *self) -{ - PyTypeObject *tp = Py_TYPE(self); - assert(tp->tp_inline_values_offset); - PyDictValues **values_ptr = _PyObject_ValuesPointer(self); - if (*values_ptr == NULL) { - return; + else { + PyObject *dict = dorv_ptr->dict; + if (dict) { + dorv_ptr->dict = NULL; + Py_DECREF(dict); + } } - PyDictKeysObject *keys = CACHED_KEYS(tp); - for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - Py_XDECREF((*values_ptr)->values[i]); - } - free_values(*values_ptr); } PyObject * PyObject_GenericGetDict(PyObject *obj, void *context) { - PyObject **dictptr = _PyObject_DictPointer(obj); - if (dictptr == NULL) { - PyErr_SetString(PyExc_AttributeError, - "This object has no __dict__"); - return NULL; - } - PyObject *dict = *dictptr; - if (dict == NULL) { - PyTypeObject *tp = Py_TYPE(obj); - PyDictValues **values_ptr = _PyObject_ValuesPointer(obj); - if (values_ptr && *values_ptr) { - *dictptr = dict = make_dict_from_instance_attributes(CACHED_KEYS(tp), *values_ptr); + PyObject *dict; + PyTypeObject *tp = Py_TYPE(obj); + if (_PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT)) { + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + OBJECT_STAT_INC(dict_materialized_on_request); + dict = make_dict_from_instance_attributes(CACHED_KEYS(tp), values); if (dict != NULL) { - *values_ptr = NULL; + dorv_ptr->dict = dict; } } - else if (_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE) && CACHED_KEYS(tp)) { - dictkeys_incref(CACHED_KEYS(tp)); - *dictptr = dict = new_dict_with_shared_keys(CACHED_KEYS(tp)); - } else { - *dictptr = dict = PyDict_New(); + dict = _PyDictOrValues_GetDict(*dorv_ptr); + if (dict == NULL) { + dictkeys_incref(CACHED_KEYS(tp)); + dict = new_dict_with_shared_keys(CACHED_KEYS(tp)); + dorv_ptr->dict = dict; + } } } - Py_XINCREF(dict); - return dict; + else { + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); + if (dictptr == NULL) { + PyErr_SetString(PyExc_AttributeError, + "This object has no __dict__"); + return NULL; + } + dict = *dictptr; + if (dict == NULL) { + PyTypeObject *tp = Py_TYPE(obj); + if (_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE) && CACHED_KEYS(tp)) { + dictkeys_incref(CACHED_KEYS(tp)); + *dictptr = dict = new_dict_with_shared_keys(CACHED_KEYS(tp)); + } + else { + *dictptr = dict = PyDict_New(); + } + } + } + return Py_XNewRef(dict); } int @@ -5248,17 +5648,107 @@ _PyDictKeys_DecRef(PyDictKeysObject *keys) dictkeys_decref(keys); } -static uint32_t next_dict_keys_version = 2; - uint32_t _PyDictKeys_GetVersionForCurrentState(PyDictKeysObject *dictkeys) { if (dictkeys->dk_version != 0) { return dictkeys->dk_version; } - if (next_dict_keys_version == 0) { + if (_PyRuntime.dict_state.next_keys_version == 0) { return 0; } - uint32_t v = next_dict_keys_version++; + uint32_t v = _PyRuntime.dict_state.next_keys_version++; dictkeys->dk_version = v; return v; } + +static inline int +validate_watcher_id(PyInterpreterState *interp, int watcher_id) +{ + if (watcher_id < 0 || watcher_id >= DICT_MAX_WATCHERS) { + PyErr_Format(PyExc_ValueError, "Invalid dict watcher ID %d", watcher_id); + return -1; + } + if (!interp->dict_state.watchers[watcher_id]) { + PyErr_Format(PyExc_ValueError, "No dict watcher set for ID %d", watcher_id); + return -1; + } + return 0; +} + +int +PyDict_Watch(int watcher_id, PyObject* dict) +{ + if (!PyDict_Check(dict)) { + PyErr_SetString(PyExc_ValueError, "Cannot watch non-dictionary"); + return -1; + } + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id)) { + return -1; + } + ((PyDictObject*)dict)->ma_version_tag |= (1LL << watcher_id); + return 0; +} + +int +PyDict_Unwatch(int watcher_id, PyObject* dict) +{ + if (!PyDict_Check(dict)) { + PyErr_SetString(PyExc_ValueError, "Cannot watch non-dictionary"); + return -1; + } + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id)) { + return -1; + } + ((PyDictObject*)dict)->ma_version_tag &= ~(1LL << watcher_id); + return 0; +} + +int +PyDict_AddWatcher(PyDict_WatchCallback callback) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + + for (int i = 0; i < DICT_MAX_WATCHERS; i++) { + if (!interp->dict_state.watchers[i]) { + interp->dict_state.watchers[i] = callback; + return i; + } + } + + PyErr_SetString(PyExc_RuntimeError, "no more dict watcher IDs available"); + return -1; +} + +int +PyDict_ClearWatcher(int watcher_id) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id)) { + return -1; + } + interp->dict_state.watchers[watcher_id] = NULL; + return 0; +} + +void +_PyDict_SendEvent(int watcher_bits, + PyDict_WatchEvent event, + PyDictObject *mp, + PyObject *key, + PyObject *value) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + for (int i = 0; i < DICT_MAX_WATCHERS; i++) { + if (watcher_bits & 1) { + PyDict_WatchCallback cb = interp->dict_state.watchers[i]; + if (cb && (cb(event, (PyObject*)mp, key, value) < 0)) { + // some dict modification paths (e.g. PyDict_Clear) can't raise, so we + // can't propagate exceptions from dict watchers. + PyErr_WriteUnraisable((PyObject *)mp); + } + } + watcher_bits >>= 1; + } +} diff --git a/Objects/enumobject.c b/Objects/enumobject.c index b78230ddaeb..c9d90584c26 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -16,9 +16,10 @@ class reversed "reversedobject *" "&PyReversed_Type" typedef struct { PyObject_HEAD Py_ssize_t en_index; /* current index of enumeration */ - PyObject* en_sit; /* secondary iterator of enumeration */ + PyObject* en_sit; /* secondary iterator of enumeration */ PyObject* en_result; /* result tuple */ PyObject* en_longindex; /* index for sequences >= PY_SSIZE_T_MAX */ + PyObject* one; /* borrowed reference */ } enumobject; @@ -78,43 +79,70 @@ enum_new_impl(PyTypeObject *type, PyObject *iterable, PyObject *start) Py_DECREF(en); return NULL; } + en->one = _PyLong_GetOne(); /* borrowed reference */ return (PyObject *)en; } +static int check_keyword(PyObject *kwnames, int index, + const char *name) +{ + PyObject *kw = PyTuple_GET_ITEM(kwnames, index); + if (!_PyUnicode_EqualToASCIIString(kw, name)) { + PyErr_Format(PyExc_TypeError, + "'%S' is an invalid keyword argument for enumerate()", kw); + return 0; + } + return 1; +} + // TODO: Use AC when bpo-43447 is supported static PyObject * enumerate_vectorcall(PyObject *type, PyObject *const *args, size_t nargsf, PyObject *kwnames) { - assert(PyType_Check(type)); - PyTypeObject *tp = (PyTypeObject *)type; + PyTypeObject *tp = _PyType_CAST(type); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); Py_ssize_t nkwargs = 0; - if (nargs == 0) { - PyErr_SetString(PyExc_TypeError, - "enumerate() missing required argument 'iterable'"); - return NULL; - } if (kwnames != NULL) { nkwargs = PyTuple_GET_SIZE(kwnames); } + // Manually implement enumerate(iterable, start=...) if (nargs + nkwargs == 2) { if (nkwargs == 1) { - PyObject *kw = PyTuple_GET_ITEM(kwnames, 0); - if (!_PyUnicode_EqualToASCIIString(kw, "start")) { - PyErr_Format(PyExc_TypeError, - "'%S' is an invalid keyword argument for enumerate()", kw); + if (!check_keyword(kwnames, 0, "start")) { return NULL; } + } else if (nkwargs == 2) { + PyObject *kw0 = PyTuple_GET_ITEM(kwnames, 0); + if (_PyUnicode_EqualToASCIIString(kw0, "start")) { + if (!check_keyword(kwnames, 1, "iterable")) { + return NULL; + } + return enum_new_impl(tp, args[1], args[0]); + } + if (!check_keyword(kwnames, 0, "iterable") || + !check_keyword(kwnames, 1, "start")) { + return NULL; + } + } return enum_new_impl(tp, args[0], args[1]); } - if (nargs == 1 && nkwargs == 0) { + if (nargs + nkwargs == 1) { + if (nkwargs == 1 && !check_keyword(kwnames, 0, "iterable")) { + return NULL; + } return enum_new_impl(tp, args[0], NULL); } + if (nargs == 0) { + PyErr_SetString(PyExc_TypeError, + "enumerate() missing required argument 'iterable'"); + return NULL; + } + PyErr_Format(PyExc_TypeError, "enumerate() takes at most 2 arguments (%d given)", nargs + nkwargs); return NULL; @@ -157,7 +185,7 @@ enum_next_long(enumobject *en, PyObject* next_item) } next_index = en->en_longindex; assert(next_index != NULL); - stepped_up = PyNumber_Add(next_index, _PyLong_GetOne()); + stepped_up = PyNumber_Add(next_index, en->one); if (stepped_up == NULL) { Py_DECREF(next_item); return NULL; @@ -328,9 +356,8 @@ reversed_new_impl(PyTypeObject *type, PyObject *seq) Py_ssize_t n; PyObject *reversed_meth; reversedobject *ro; - _Py_IDENTIFIER(__reversed__); - reversed_meth = _PyObject_LookupSpecial(seq, &PyId___reversed__); + reversed_meth = _PyObject_LookupSpecial(seq, &_Py_ID(__reversed__)); if (reversed_meth == Py_None) { Py_DECREF(reversed_meth); PyErr_Format(PyExc_TypeError, @@ -362,8 +389,7 @@ reversed_new_impl(PyTypeObject *type, PyObject *seq) return NULL; ro->index = n-1; - Py_INCREF(seq); - ro->seq = seq; + ro->seq = Py_NewRef(seq); return (PyObject *)ro; } @@ -371,8 +397,6 @@ static PyObject * reversed_vectorcall(PyObject *type, PyObject * const*args, size_t nargsf, PyObject *kwnames) { - assert(PyType_Check(type)); - if (!_PyArg_NoKwnames("reversed", kwnames)) { return NULL; } @@ -382,7 +406,7 @@ reversed_vectorcall(PyObject *type, PyObject * const*args, return NULL; } - return reversed_new_impl((PyTypeObject *)type, args[0]); + return reversed_new_impl(_PyType_CAST(type), args[0]); } static void diff --git a/Objects/exception_handling_notes.txt b/Objects/exception_handling_notes.txt index e738c2781ad..7de01fdbf5f 100644 --- a/Objects/exception_handling_notes.txt +++ b/Objects/exception_handling_notes.txt @@ -23,7 +23,7 @@ compiles as follows in 3.10: 3 2 LOAD_GLOBAL 0 (g) 4 LOAD_CONST 1 (0) - 6 CALL_FUNCTION 1 + 6 CALL_NO_KW 1 8 POP_TOP 10 POP_BLOCK 12 LOAD_CONST 0 (None) @@ -43,33 +43,36 @@ SETUP_FINALLY and POP_BLOCK. In 3.11, the SETUP_FINALLY and POP_BLOCK are eliminated, replaced with a table to determine where to jump to when an exception is raised. - 2 0 NOP + 1 0 RESUME 0 - 3 2 LOAD_GLOBAL 0 (g) - 4 LOAD_CONST 1 (0) - 6 CALL_FUNCTION 1 - 8 POP_TOP - 10 LOAD_CONST 0 (None) - 12 RETURN_VALUE - >> 14 PUSH_EXC_INFO + 2 2 NOP - 4 16 POP_TOP - 18 POP_TOP - 20 POP_TOP + 3 4 LOAD_GLOBAL 1 (NULL + g) + 16 LOAD_CONST 1 (0) + 18 PRECALL 1 + 22 CALL 1 + 32 POP_TOP + 34 LOAD_CONST 0 (None) + 36 RETURN_VALUE + >> 38 PUSH_EXC_INFO - 5 22 POP_EXCEPT - 24 LOAD_CONST 2 ('fail') - 26 RETURN_VALUE - >> 28 POP_EXCEPT_AND_RERAISE + 4 40 POP_TOP + + 5 42 POP_EXCEPT + 44 LOAD_CONST 2 ('fail') + 46 RETURN_VALUE + >> 48 COPY 3 + 50 POP_EXCEPT + 52 RERAISE 1 ExceptionTable: - 2 to 8 -> 14 [0] - 14 to 20 -> 28 [3] lasti + 4 to 32 -> 38 [0] + 38 to 40 -> 48 [1] lasti -(Note this code is from an early 3.11 alpha, the NOP may well have be removed before release). +(Note this code is from 3.11, later versions may have slightly different bytecode.) If an instruction raises an exception then its offset is used to find the target to jump to. -For example, the CALL_FUNCTION at offset 6, falls into the range 2 to 8. -So, if g() raises an exception, then control jumps to offset 14. +For example, the CALL at offset 22, falls into the range 4 to 32. +So, if g() raises an exception, then control jumps to offset 38. Unwinding @@ -84,9 +87,9 @@ This information is stored in the exception table, described below. If there is no relevant entry, the exception bubbles up to the caller. If there is an entry, then: - 1. pop values from the stack until it matches the stack depth for the handler, + 1. pop values from the stack until it matches the stack depth for the handler. 2. if 'lasti' is true, then push the offset that the exception was raised at. - 3. push the exception to the stack as three values: traceback, value, type, + 3. push the exception to the stack. 4. jump to the target offset and resume execution. diff --git a/Objects/exceptions.c b/Objects/exceptions.c index a5459da89a0..db6f7d52804 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -7,6 +7,8 @@ #define PY_SSIZE_T_CLEAN #include #include +#include "pycore_ceval.h" // _Py_EnterRecursiveCall +#include "pycore_exceptions.h" // struct _Py_exc_state #include "pycore_initconfig.h" #include "pycore_object.h" #include "structmember.h" // PyMemberDef @@ -14,10 +16,10 @@ /* Compatibility aliases */ -PyObject *PyExc_EnvironmentError = NULL; -PyObject *PyExc_IOError = NULL; +PyObject *PyExc_EnvironmentError = NULL; // borrowed ref +PyObject *PyExc_IOError = NULL; // borrowed ref #ifdef MS_WINDOWS -PyObject *PyExc_WindowsError = NULL; +PyObject *PyExc_WindowsError = NULL; // borrowed ref #endif @@ -46,12 +48,12 @@ BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; /* the dict is created on the fly in PyObject_GenericSetAttr */ self->dict = NULL; + self->notes = NULL; self->traceback = self->cause = self->context = NULL; self->suppress_context = 0; if (args) { - self->args = args; - Py_INCREF(args); + self->args = Py_NewRef(args); return (PyObject *)self; } @@ -70,9 +72,7 @@ BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds) if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds)) return -1; - Py_INCREF(args); - Py_XSETREF(self->args, args); - + Py_XSETREF(self->args, Py_NewRef(args)); return 0; } @@ -81,6 +81,7 @@ BaseException_clear(PyBaseExceptionObject *self) { Py_CLEAR(self->dict); Py_CLEAR(self->args); + Py_CLEAR(self->notes); Py_CLEAR(self->traceback); Py_CLEAR(self->cause); Py_CLEAR(self->context); @@ -105,6 +106,7 @@ BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg) { Py_VISIT(self->dict); Py_VISIT(self->args); + Py_VISIT(self->notes); Py_VISIT(self->traceback); Py_VISIT(self->cause); Py_VISIT(self->context); @@ -162,8 +164,14 @@ BaseException_setstate(PyObject *self, PyObject *state) return NULL; } while (PyDict_Next(state, &i, &d_key, &d_value)) { - if (PyObject_SetAttr(self, d_key, d_value) < 0) + Py_INCREF(d_key); + Py_INCREF(d_value); + int res = PyObject_SetAttr(self, d_key, d_value); + Py_DECREF(d_value); + Py_DECREF(d_key); + if (res < 0) { return NULL; + } } } Py_RETURN_NONE; @@ -174,20 +182,69 @@ BaseException_with_traceback(PyObject *self, PyObject *tb) { if (PyException_SetTraceback(self, tb)) return NULL; - Py_INCREF(self); - return self; + return Py_NewRef(self); } PyDoc_STRVAR(with_traceback_doc, "Exception.with_traceback(tb) --\n\ set self.__traceback__ to tb and return self."); +static inline PyBaseExceptionObject* +_PyBaseExceptionObject_cast(PyObject *exc) +{ + assert(PyExceptionInstance_Check(exc)); + return (PyBaseExceptionObject *)exc; +} + +static PyObject * +BaseException_add_note(PyObject *self, PyObject *note) +{ + if (!PyUnicode_Check(note)) { + PyErr_Format(PyExc_TypeError, + "note must be a str, not '%s'", + Py_TYPE(note)->tp_name); + return NULL; + } + + if (!PyObject_HasAttr(self, &_Py_ID(__notes__))) { + PyObject *new_notes = PyList_New(0); + if (new_notes == NULL) { + return NULL; + } + if (PyObject_SetAttr(self, &_Py_ID(__notes__), new_notes) < 0) { + Py_DECREF(new_notes); + return NULL; + } + Py_DECREF(new_notes); + } + PyObject *notes = PyObject_GetAttr(self, &_Py_ID(__notes__)); + if (notes == NULL) { + return NULL; + } + if (!PyList_Check(notes)) { + Py_DECREF(notes); + PyErr_SetString(PyExc_TypeError, "Cannot add note: __notes__ is not a list"); + return NULL; + } + if (PyList_Append(notes, note) < 0) { + Py_DECREF(notes); + return NULL; + } + Py_DECREF(notes); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(add_note_doc, +"Exception.add_note(note) --\n\ + add a note to the exception"); static PyMethodDef BaseException_methods[] = { {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS }, {"__setstate__", (PyCFunction)BaseException_setstate, METH_O }, {"with_traceback", (PyCFunction)BaseException_with_traceback, METH_O, with_traceback_doc}, + {"add_note", (PyCFunction)BaseException_add_note, METH_O, + add_note_doc}, {NULL, NULL, 0, NULL}, }; @@ -197,8 +254,7 @@ BaseException_get_args(PyBaseExceptionObject *self, void *Py_UNUSED(ignored)) if (self->args == NULL) { Py_RETURN_NONE; } - Py_INCREF(self->args); - return self->args; + return Py_NewRef(self->args); } static int @@ -222,8 +278,7 @@ BaseException_get_tb(PyBaseExceptionObject *self, void *Py_UNUSED(ignored)) if (self->traceback == NULL) { Py_RETURN_NONE; } - Py_INCREF(self->traceback); - return self->traceback; + return Py_NewRef(self->traceback); } static int @@ -239,8 +294,7 @@ BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb, void *Py_UNUSED( return -1; } - Py_INCREF(tb); - Py_XSETREF(self->traceback, tb); + Py_XSETREF(self->traceback, Py_NewRef(tb)); return 0; } @@ -315,20 +369,11 @@ static PyGetSetDef BaseException_getset[] = { }; -static inline PyBaseExceptionObject* -_PyBaseExceptionObject_cast(PyObject *exc) -{ - assert(PyExceptionInstance_Check(exc)); - return (PyBaseExceptionObject *)exc; -} - - PyObject * PyException_GetTraceback(PyObject *self) { PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self); - Py_XINCREF(base_self->traceback); - return base_self->traceback; + return Py_XNewRef(base_self->traceback); } @@ -342,8 +387,7 @@ PyObject * PyException_GetCause(PyObject *self) { PyObject *cause = _PyBaseExceptionObject_cast(self)->cause; - Py_XINCREF(cause); - return cause; + return Py_XNewRef(cause); } /* Steals a reference to cause */ @@ -359,8 +403,7 @@ PyObject * PyException_GetContext(PyObject *self) { PyObject *context = _PyBaseExceptionObject_cast(self)->context; - Py_XINCREF(context); - return context; + return Py_XNewRef(context); } /* Steals a reference to context */ @@ -526,8 +569,7 @@ StopIteration_init(PyStopIterationObject *self, PyObject *args, PyObject *kwds) value = PyTuple_GET_ITEM(args, 0); else value = Py_None; - Py_INCREF(value); - self->value = value; + self->value = Py_NewRef(value); return 0; } @@ -553,17 +595,9 @@ StopIteration_traverse(PyStopIterationObject *self, visitproc visit, void *arg) return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); } -ComplexExtendsException( - PyExc_Exception, /* base */ - StopIteration, /* name */ - StopIteration, /* prefix for *_init, etc */ - 0, /* new */ - 0, /* methods */ - StopIteration_members, /* members */ - 0, /* getset */ - 0, /* str */ - "Signal the end from iterator.__next__()." -); +ComplexExtendsException(PyExc_Exception, StopIteration, StopIteration, + 0, 0, StopIteration_members, 0, 0, + "Signal the end from iterator.__next__()."); /* @@ -588,12 +622,10 @@ SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds) if (size == 0) return 0; if (size == 1) { - Py_INCREF(PyTuple_GET_ITEM(args, 0)); - Py_XSETREF(self->code, PyTuple_GET_ITEM(args, 0)); + Py_XSETREF(self->code, Py_NewRef(PyTuple_GET_ITEM(args, 0))); } else { /* size > 1 */ - Py_INCREF(args); - Py_XSETREF(self->code, args); + Py_XSETREF(self->code, Py_NewRef(args)); } return 0; } @@ -653,7 +685,10 @@ BaseExceptionGroup_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *message = NULL; PyObject *exceptions = NULL; - if (!PyArg_ParseTuple(args, "UO", &message, &exceptions)) { + if (!PyArg_ParseTuple(args, + "UO:BaseExceptionGroup.__new__", + &message, + &exceptions)) { return NULL; } @@ -718,7 +753,19 @@ BaseExceptionGroup_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } else { - /* Do nothing - we don't interfere with subclasses */ + /* user-defined subclass */ + if (nested_base_exceptions) { + int nonbase = PyObject_IsSubclass((PyObject*)cls, PyExc_Exception); + if (nonbase == -1) { + goto error; + } + else if (nonbase == 1) { + PyErr_Format(PyExc_TypeError, + "Cannot nest BaseExceptions in '%.200s'", + cls->tp_name); + goto error; + } + } } if (!cls) { @@ -741,6 +788,23 @@ error: return NULL; } +PyObject * +_PyExc_CreateExceptionGroup(const char *msg_str, PyObject *excs) +{ + PyObject *msg = PyUnicode_FromString(msg_str); + if (!msg) { + return NULL; + } + PyObject *args = PyTuple_Pack(2, msg, excs); + Py_DECREF(msg); + if (!args) { + return NULL; + } + PyObject *result = PyObject_CallObject(PyExc_BaseExceptionGroup, args); + Py_DECREF(args); + return result; +} + static int BaseExceptionGroup_init(PyBaseExceptionGroupObject *self, PyObject *args, PyObject *kwds) @@ -784,7 +848,12 @@ BaseExceptionGroup_str(PyBaseExceptionGroupObject *self) { assert(self->msg); assert(PyUnicode_Check(self->msg)); - return Py_NewRef(self->msg); + + assert(PyTuple_CheckExact(self->excs)); + Py_ssize_t num_excs = PyTuple_Size(self->excs); + return PyUnicode_FromFormat( + "%S (%zd sub-exception%s)", + self->msg, num_excs, num_excs > 1 ? "s" : ""); } static PyObject * @@ -846,12 +915,40 @@ exceptiongroup_subset( if (tb) { int res = PyException_SetTraceback(eg, tb); Py_DECREF(tb); - if (res == -1) { + if (res < 0) { goto error; } } PyException_SetContext(eg, PyException_GetContext(orig)); PyException_SetCause(eg, PyException_GetCause(orig)); + + if (PyObject_HasAttr(orig, &_Py_ID(__notes__))) { + PyObject *notes = PyObject_GetAttr(orig, &_Py_ID(__notes__)); + if (notes == NULL) { + goto error; + } + if (PySequence_Check(notes)) { + /* Make a copy so the parts have independent notes lists. */ + PyObject *notes_copy = PySequence_List(notes); + Py_DECREF(notes); + if (notes_copy == NULL) { + goto error; + } + int res = PyObject_SetAttr(eg, &_Py_ID(__notes__), notes_copy); + Py_DECREF(notes_copy); + if (res < 0) { + goto error; + } + } + else { + /* __notes__ is supposed to be a list, and split() is not a + * good place to report earlier user errors, so we just ignore + * notes of non-sequence type. + */ + Py_DECREF(notes); + } + } + *result = eg; return 0; error: @@ -864,26 +961,41 @@ typedef enum { EXCEPTION_GROUP_MATCH_BY_TYPE = 0, /* A PyFunction returning True for matching exceptions */ EXCEPTION_GROUP_MATCH_BY_PREDICATE = 1, - /* An instance or container thereof, checked with equality - * This matcher type is only used internally by the - * interpreter, it is not exposed to python code */ - EXCEPTION_GROUP_MATCH_INSTANCES = 2 + /* A set of the IDs of leaf exceptions to include in the result. + * This matcher type is used internally by the interpreter + * to construct reraised exceptions. + */ + EXCEPTION_GROUP_MATCH_INSTANCE_IDS = 2 } _exceptiongroup_split_matcher_type; static int get_matcher_type(PyObject *value, - _exceptiongroup_split_matcher_type *type) + _exceptiongroup_split_matcher_type *type) { - /* the python API supports only BY_TYPE and BY_PREDICATE */ - if (PyExceptionClass_Check(value) || - PyTuple_CheckExact(value)) { - *type = EXCEPTION_GROUP_MATCH_BY_TYPE; - return 0; - } + assert(value); + if (PyFunction_Check(value)) { *type = EXCEPTION_GROUP_MATCH_BY_PREDICATE; return 0; } + + if (PyExceptionClass_Check(value)) { + *type = EXCEPTION_GROUP_MATCH_BY_TYPE; + return 0; + } + + if (PyTuple_CheckExact(value)) { + Py_ssize_t n = PyTuple_GET_SIZE(value); + for (Py_ssize_t i=0; iexcs, i); _exceptiongroup_split_result rec_result; - if (Py_EnterRecursiveCall(" in exceptiongroup_split_recursive")) { + if (_Py_EnterRecursiveCall(" in exceptiongroup_split_recursive")) { goto done; } if (exceptiongroup_split_recursive( e, matcher_type, matcher_value, - construct_rest, &rec_result) == -1) { + construct_rest, &rec_result) < 0) { assert(!rec_result.match); assert(!rec_result.rest); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); goto done; } - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (rec_result.match) { assert(PyList_CheckExact(match_list)); - if (PyList_Append(match_list, rec_result.match) == -1) { + if (PyList_Append(match_list, rec_result.match) < 0) { Py_DECREF(rec_result.match); + Py_XDECREF(rec_result.rest); goto done; } Py_DECREF(rec_result.match); @@ -1005,7 +1125,7 @@ exceptiongroup_split_recursive(PyObject *exc, if (rec_result.rest) { assert(construct_rest); assert(PyList_CheckExact(rest_list)); - if (PyList_Append(rest_list, rec_result.rest) == -1) { + if (PyList_Append(rest_list, rec_result.rest) < 0) { Py_DECREF(rec_result.rest); goto done; } @@ -1014,13 +1134,13 @@ exceptiongroup_split_recursive(PyObject *exc, } /* construct result */ - if (exceptiongroup_subset(eg, match_list, &result->match) == -1) { + if (exceptiongroup_subset(eg, match_list, &result->match) < 0) { goto done; } if (construct_rest) { assert(PyList_CheckExact(rest_list)); - if (exceptiongroup_subset(eg, rest_list, &result->rest) == -1) { + if (exceptiongroup_subset(eg, rest_list, &result->rest) < 0) { Py_CLEAR(result->match); goto done; } @@ -1029,7 +1149,7 @@ exceptiongroup_split_recursive(PyObject *exc, done: Py_DECREF(match_list); Py_XDECREF(rest_list); - if (retval == -1) { + if (retval < 0) { Py_CLEAR(result->match); Py_CLEAR(result->rest); } @@ -1045,7 +1165,7 @@ BaseExceptionGroup_split(PyObject *self, PyObject *args) } _exceptiongroup_split_matcher_type matcher_type; - if (get_matcher_type(matcher_value, &matcher_type) == -1) { + if (get_matcher_type(matcher_value, &matcher_type) < 0) { return NULL; } @@ -1053,7 +1173,7 @@ BaseExceptionGroup_split(PyObject *self, PyObject *args) bool construct_rest = true; if (exceptiongroup_split_recursive( self, matcher_type, matcher_value, - construct_rest, &split_result) == -1) { + construct_rest, &split_result) < 0) { return NULL; } @@ -1076,7 +1196,7 @@ BaseExceptionGroup_subgroup(PyObject *self, PyObject *args) } _exceptiongroup_split_matcher_type matcher_type; - if (get_matcher_type(matcher_value, &matcher_type) == -1) { + if (get_matcher_type(matcher_value, &matcher_type) < 0) { return NULL; } @@ -1084,7 +1204,7 @@ BaseExceptionGroup_subgroup(PyObject *self, PyObject *args) bool construct_rest = false; if (exceptiongroup_split_recursive( self, matcher_type, matcher_value, - construct_rest, &split_result) == -1) { + construct_rest, &split_result) < 0) { return NULL; } @@ -1096,6 +1216,204 @@ BaseExceptionGroup_subgroup(PyObject *self, PyObject *args) return result; } +static int +collect_exception_group_leaf_ids(PyObject *exc, PyObject *leaf_ids) +{ + if (Py_IsNone(exc)) { + return 0; + } + + assert(PyExceptionInstance_Check(exc)); + assert(PySet_Check(leaf_ids)); + + /* Add IDs of all leaf exceptions in exc to the leaf_ids set */ + + if (!_PyBaseExceptionGroup_Check(exc)) { + PyObject *exc_id = PyLong_FromVoidPtr(exc); + if (exc_id == NULL) { + return -1; + } + int res = PySet_Add(leaf_ids, exc_id); + Py_DECREF(exc_id); + return res; + } + PyBaseExceptionGroupObject *eg = _PyBaseExceptionGroupObject_cast(exc); + Py_ssize_t num_excs = PyTuple_GET_SIZE(eg->excs); + /* recursive calls */ + for (Py_ssize_t i = 0; i < num_excs; i++) { + PyObject *e = PyTuple_GET_ITEM(eg->excs, i); + if (_Py_EnterRecursiveCall(" in collect_exception_group_leaf_ids")) { + return -1; + } + int res = collect_exception_group_leaf_ids(e, leaf_ids); + _Py_LeaveRecursiveCall(); + if (res < 0) { + return -1; + } + } + return 0; +} + +/* This function is used by the interpreter to construct reraised + * exception groups. It takes an exception group eg and a list + * of exception groups keep and returns the sub-exception group + * of eg which contains all leaf exceptions that are contained + * in any exception group in keep. + */ +static PyObject * +exception_group_projection(PyObject *eg, PyObject *keep) +{ + assert(_PyBaseExceptionGroup_Check(eg)); + assert(PyList_CheckExact(keep)); + + PyObject *leaf_ids = PySet_New(NULL); + if (!leaf_ids) { + return NULL; + } + + Py_ssize_t n = PyList_GET_SIZE(keep); + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *e = PyList_GET_ITEM(keep, i); + assert(e != NULL); + assert(_PyBaseExceptionGroup_Check(e)); + if (collect_exception_group_leaf_ids(e, leaf_ids) < 0) { + Py_DECREF(leaf_ids); + return NULL; + } + } + + _exceptiongroup_split_result split_result; + bool construct_rest = false; + int err = exceptiongroup_split_recursive( + eg, EXCEPTION_GROUP_MATCH_INSTANCE_IDS, leaf_ids, + construct_rest, &split_result); + Py_DECREF(leaf_ids); + if (err < 0) { + return NULL; + } + + PyObject *result = split_result.match ? + split_result.match : Py_NewRef(Py_None); + assert(split_result.rest == NULL); + return result; +} + +static bool +is_same_exception_metadata(PyObject *exc1, PyObject *exc2) +{ + assert(PyExceptionInstance_Check(exc1)); + assert(PyExceptionInstance_Check(exc2)); + + PyBaseExceptionObject *e1 = (PyBaseExceptionObject *)exc1; + PyBaseExceptionObject *e2 = (PyBaseExceptionObject *)exc2; + + return (e1->notes == e2->notes && + e1->traceback == e2->traceback && + e1->cause == e2->cause && + e1->context == e2->context); +} + +/* + This function is used by the interpreter to calculate + the exception group to be raised at the end of a + try-except* construct. + + orig: the original except that was caught. + excs: a list of exceptions that were raised/reraised + in the except* clauses. + + Calculates an exception group to raise. It contains + all exceptions in excs, where those that were reraised + have same nesting structure as in orig, and those that + were raised (if any) are added as siblings in a new EG. + + Returns NULL and sets an exception on failure. +*/ +PyObject * +_PyExc_PrepReraiseStar(PyObject *orig, PyObject *excs) +{ + assert(PyExceptionInstance_Check(orig)); + assert(PyList_Check(excs)); + + Py_ssize_t numexcs = PyList_GET_SIZE(excs); + + if (numexcs == 0) { + return Py_NewRef(Py_None); + } + + if (!_PyBaseExceptionGroup_Check(orig)) { + /* a naked exception was caught and wrapped. Only one except* clause + * could have executed,so there is at most one exception to raise. + */ + + assert(numexcs == 1 || (numexcs == 2 && PyList_GET_ITEM(excs, 1) == Py_None)); + + PyObject *e = PyList_GET_ITEM(excs, 0); + assert(e != NULL); + return Py_NewRef(e); + } + + PyObject *raised_list = PyList_New(0); + if (raised_list == NULL) { + return NULL; + } + PyObject* reraised_list = PyList_New(0); + if (reraised_list == NULL) { + Py_DECREF(raised_list); + return NULL; + } + + /* Now we are holding refs to raised_list and reraised_list */ + + PyObject *result = NULL; + + /* Split excs into raised and reraised by comparing metadata with orig */ + for (Py_ssize_t i = 0; i < numexcs; i++) { + PyObject *e = PyList_GET_ITEM(excs, i); + assert(e != NULL); + if (Py_IsNone(e)) { + continue; + } + bool is_reraise = is_same_exception_metadata(e, orig); + PyObject *append_list = is_reraise ? reraised_list : raised_list; + if (PyList_Append(append_list, e) < 0) { + goto done; + } + } + + PyObject *reraised_eg = exception_group_projection(orig, reraised_list); + if (reraised_eg == NULL) { + goto done; + } + + if (!Py_IsNone(reraised_eg)) { + assert(is_same_exception_metadata(reraised_eg, orig)); + } + Py_ssize_t num_raised = PyList_GET_SIZE(raised_list); + if (num_raised == 0) { + result = reraised_eg; + } + else if (num_raised > 0) { + int res = 0; + if (!Py_IsNone(reraised_eg)) { + res = PyList_Append(raised_list, reraised_eg); + } + Py_DECREF(reraised_eg); + if (res < 0) { + goto done; + } + result = _PyExc_CreateExceptionGroup("", raised_list); + if (result == NULL) { + goto done; + } + } + +done: + Py_XDECREF(raised_list); + Py_XDECREF(reraised_list); + return result; +} + static PyMemberDef BaseExceptionGroup_members[] = { {"message", T_OBJECT, offsetof(PyBaseExceptionGroupObject, msg), READONLY, PyDoc_STR("exception message")}, @@ -1154,11 +1472,12 @@ SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt, static int ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds) { - static char *kwlist[] = {"name", "path", 0}; + static char *kwlist[] = {"name", "path", "name_from", 0}; PyObject *empty_tuple; PyObject *msg = NULL; PyObject *name = NULL; PyObject *path = NULL; + PyObject *name_from = NULL; if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) return -1; @@ -1166,22 +1485,19 @@ ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds) empty_tuple = PyTuple_New(0); if (!empty_tuple) return -1; - if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:ImportError", kwlist, - &name, &path)) { + if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OOO:ImportError", kwlist, + &name, &path, &name_from)) { Py_DECREF(empty_tuple); return -1; } Py_DECREF(empty_tuple); - Py_XINCREF(name); - Py_XSETREF(self->name, name); - - Py_XINCREF(path); - Py_XSETREF(self->path, path); + Py_XSETREF(self->name, Py_XNewRef(name)); + Py_XSETREF(self->path, Py_XNewRef(path)); + Py_XSETREF(self->name_from, Py_XNewRef(name_from)); if (PyTuple_GET_SIZE(args) == 1) { - msg = PyTuple_GET_ITEM(args, 0); - Py_INCREF(msg); + msg = Py_NewRef(PyTuple_GET_ITEM(args, 0)); } Py_XSETREF(self->msg, msg); @@ -1194,6 +1510,7 @@ ImportError_clear(PyImportErrorObject *self) Py_CLEAR(self->msg); Py_CLEAR(self->name); Py_CLEAR(self->path); + Py_CLEAR(self->name_from); return BaseException_clear((PyBaseExceptionObject *)self); } @@ -1211,6 +1528,7 @@ ImportError_traverse(PyImportErrorObject *self, visitproc visit, void *arg) Py_VISIT(self->msg); Py_VISIT(self->name); Py_VISIT(self->path); + Py_VISIT(self->name_from); return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); } @@ -1218,8 +1536,7 @@ static PyObject * ImportError_str(PyImportErrorObject *self) { if (self->msg && PyUnicode_CheckExact(self->msg)) { - Py_INCREF(self->msg); - return self->msg; + return Py_NewRef(self->msg); } else { return BaseException_str((PyBaseExceptionObject *)self); @@ -1230,25 +1547,26 @@ static PyObject * ImportError_getstate(PyImportErrorObject *self) { PyObject *dict = ((PyBaseExceptionObject *)self)->dict; - if (self->name || self->path) { - _Py_IDENTIFIER(name); - _Py_IDENTIFIER(path); + if (self->name || self->path || self->name_from) { dict = dict ? PyDict_Copy(dict) : PyDict_New(); if (dict == NULL) return NULL; - if (self->name && _PyDict_SetItemId(dict, &PyId_name, self->name) < 0) { + if (self->name && PyDict_SetItem(dict, &_Py_ID(name), self->name) < 0) { Py_DECREF(dict); return NULL; } - if (self->path && _PyDict_SetItemId(dict, &PyId_path, self->path) < 0) { + if (self->path && PyDict_SetItem(dict, &_Py_ID(path), self->path) < 0) { + Py_DECREF(dict); + return NULL; + } + if (self->name_from && PyDict_SetItem(dict, &_Py_ID(name_from), self->name_from) < 0) { Py_DECREF(dict); return NULL; } return dict; } else if (dict) { - Py_INCREF(dict); - return dict; + return Py_NewRef(dict); } else { Py_RETURN_NONE; @@ -1280,6 +1598,8 @@ static PyMemberDef ImportError_members[] = { PyDoc_STR("module name")}, {"path", T_OBJECT, offsetof(PyImportErrorObject, path), 0, PyDoc_STR("module path")}, + {"name_from", T_OBJECT, offsetof(PyImportErrorObject, name_from), 0, + PyDoc_STR("name imported from module")}, {NULL} /* Sentinel */ }; @@ -1363,14 +1683,7 @@ oserror_parse_args(PyObject **p_args, winerrcode = PyLong_AsLong(*winerror); if (winerrcode == -1 && PyErr_Occurred()) return -1; - /* Set errno to the corresponding POSIX errno (overriding - first argument). Windows Socket error codes (>= 10000) - have the same value as their POSIX counterparts. - */ - if (winerrcode < 10000) - errcode = winerror_to_errno(winerrcode); - else - errcode = winerrcode; + errcode = winerror_to_errno(winerrcode); *myerrno = PyLong_FromLong(errcode); if (!*myerrno) return -1; @@ -1380,8 +1693,7 @@ oserror_parse_args(PyObject **p_args, PyTuple_SET_ITEM(newargs, 0, *myerrno); for (i = 1; i < nargs; i++) { PyObject *val = PyTuple_GET_ITEM(args, i); - Py_INCREF(val); - PyTuple_SET_ITEM(newargs, i, val); + PyTuple_SET_ITEM(newargs, i, Py_NewRef(val)); } Py_DECREF(args); args = *p_args = newargs; @@ -1416,12 +1728,10 @@ oserror_init(PyOSErrorObject *self, PyObject **p_args, return -1; } else { - Py_INCREF(filename); - self->filename = filename; + self->filename = Py_NewRef(filename); if (filename2 && filename2 != Py_None) { - Py_INCREF(filename2); - self->filename2 = filename2; + self->filename2 = Py_NewRef(filename2); } if (nargs >= 2 && nargs <= 5) { @@ -1436,15 +1746,10 @@ oserror_init(PyOSErrorObject *self, PyObject **p_args, } } } - Py_XINCREF(myerrno); - self->myerrno = myerrno; - - Py_XINCREF(strerror); - self->strerror = strerror; - + self->myerrno = Py_XNewRef(myerrno); + self->strerror = Py_XNewRef(strerror); #ifdef MS_WINDOWS - Py_XINCREF(winerror); - self->winerror = winerror; + self->winerror = Py_XNewRef(winerror); #endif /* Steals the reference to args */ @@ -1510,8 +1815,7 @@ OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *newtype; newtype = PyDict_GetItemWithError(state->errnomap, myerrno); if (newtype) { - assert(PyType_Check(newtype)); - type = (PyTypeObject *) newtype; + type = _PyType_CAST(newtype); } else if (PyErr_Occurred()) goto error; @@ -1671,7 +1975,7 @@ static PyObject * OSError_reduce(PyOSErrorObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *args = self->args; - PyObject *res = NULL, *tmp; + PyObject *res = NULL; /* self->args is only the first two real arguments if there was a * file name given to OSError. */ @@ -1681,16 +1985,9 @@ OSError_reduce(PyOSErrorObject *self, PyObject *Py_UNUSED(ignored)) if (!args) return NULL; - tmp = PyTuple_GET_ITEM(self->args, 0); - Py_INCREF(tmp); - PyTuple_SET_ITEM(args, 0, tmp); - - tmp = PyTuple_GET_ITEM(self->args, 1); - Py_INCREF(tmp); - PyTuple_SET_ITEM(args, 1, tmp); - - Py_INCREF(self->filename); - PyTuple_SET_ITEM(args, 2, self->filename); + PyTuple_SET_ITEM(args, 0, Py_NewRef(PyTuple_GET_ITEM(self->args, 0))); + PyTuple_SET_ITEM(args, 1, Py_NewRef(PyTuple_GET_ITEM(self->args, 1))); + PyTuple_SET_ITEM(args, 2, Py_NewRef(self->filename)); if (self->filename2) { /* @@ -1698,12 +1995,10 @@ OSError_reduce(PyOSErrorObject *self, PyObject *Py_UNUSED(ignored)) * So, to recreate filename2, we need to pass in * winerror as well. */ - Py_INCREF(Py_None); - PyTuple_SET_ITEM(args, 3, Py_None); + PyTuple_SET_ITEM(args, 3, Py_NewRef(Py_None)); /* filename2 */ - Py_INCREF(self->filename2); - PyTuple_SET_ITEM(args, 4, self->filename2); + PyTuple_SET_ITEM(args, 4, Py_NewRef(self->filename2)); } } else Py_INCREF(args); @@ -1864,8 +2159,7 @@ NameError_init(PyNameErrorObject *self, PyObject *args, PyObject *kwds) } Py_DECREF(empty_tuple); - Py_XINCREF(name); - Py_XSETREF(self->name, name); + Py_XSETREF(self->name, Py_XNewRef(name)); return 0; } @@ -1939,11 +2233,8 @@ AttributeError_init(PyAttributeErrorObject *self, PyObject *args, PyObject *kwds } Py_DECREF(empty_tuple); - Py_XINCREF(name); - Py_XSETREF(self->name, name); - - Py_XINCREF(obj); - Py_XSETREF(self->obj, obj); + Py_XSETREF(self->name, Py_XNewRef(name)); + Py_XSETREF(self->obj, Py_XNewRef(obj)); return 0; } @@ -2001,8 +2292,7 @@ SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds) return -1; if (lenargs >= 1) { - Py_INCREF(PyTuple_GET_ITEM(args, 0)); - Py_XSETREF(self->msg, PyTuple_GET_ITEM(args, 0)); + Py_XSETREF(self->msg, Py_NewRef(PyTuple_GET_ITEM(args, 0))); } if (lenargs == 2) { info = PyTuple_GET_ITEM(args, 1); @@ -2098,8 +2388,7 @@ my_basename(PyObject *name) return PyUnicode_Substring(name, offset, size); } else { - Py_INCREF(name); - return name; + return Py_NewRef(name); } } @@ -2251,8 +2540,7 @@ get_string(PyObject *attr, const char *name) PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name); return NULL; } - Py_INCREF(attr); - return attr; + return Py_NewRef(attr); } static PyObject * @@ -2268,8 +2556,7 @@ get_unicode(PyObject *attr, const char *name) "%.200s attribute must be unicode", name); return NULL; } - Py_INCREF(attr); - return attr; + return Py_NewRef(attr); } static int @@ -2921,6 +3208,7 @@ MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self = state->memerrors_freelist; self->args = PyTuple_New(0); /* This shouldn't happen since the empty tuple is persistent */ + if (self->args == NULL) { return NULL; } @@ -2936,6 +3224,8 @@ MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static void MemoryError_dealloc(PyBaseExceptionObject *self) { + _PyObject_GC_UNTRACK(self); + BaseException_clear(self); /* If this is a subclass of MemoryError, we don't need to @@ -2945,8 +3235,6 @@ MemoryError_dealloc(PyBaseExceptionObject *self) return; } - _PyObject_GC_UNTRACK(self); - struct _Py_exc_state *state = get_exc_state(); if (state->memerrors_numfree >= MEMERRORS_SAVE) { Py_TYPE(self)->tp_free((PyObject *)self); @@ -3157,19 +3445,152 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning, #endif #endif /* MS_WINDOWS */ +struct static_exception { + PyTypeObject *exc; + const char *name; +}; + +static struct static_exception static_exceptions[] = { +#define ITEM(NAME) {&_PyExc_##NAME, #NAME} + // Level 1 + ITEM(BaseException), + + // Level 2: BaseException subclasses + ITEM(BaseExceptionGroup), + ITEM(Exception), + ITEM(GeneratorExit), + ITEM(KeyboardInterrupt), + ITEM(SystemExit), + + // Level 3: Exception(BaseException) subclasses + ITEM(ArithmeticError), + ITEM(AssertionError), + ITEM(AttributeError), + ITEM(BufferError), + ITEM(EOFError), + //ITEM(ExceptionGroup), + ITEM(ImportError), + ITEM(LookupError), + ITEM(MemoryError), + ITEM(NameError), + ITEM(OSError), + ITEM(ReferenceError), + ITEM(RuntimeError), + ITEM(StopAsyncIteration), + ITEM(StopIteration), + ITEM(SyntaxError), + ITEM(SystemError), + ITEM(TypeError), + ITEM(ValueError), + ITEM(Warning), + + // Level 4: ArithmeticError(Exception) subclasses + ITEM(FloatingPointError), + ITEM(OverflowError), + ITEM(ZeroDivisionError), + + // Level 4: Warning(Exception) subclasses + ITEM(BytesWarning), + ITEM(DeprecationWarning), + ITEM(EncodingWarning), + ITEM(FutureWarning), + ITEM(ImportWarning), + ITEM(PendingDeprecationWarning), + ITEM(ResourceWarning), + ITEM(RuntimeWarning), + ITEM(SyntaxWarning), + ITEM(UnicodeWarning), + ITEM(UserWarning), + + // Level 4: OSError(Exception) subclasses + ITEM(BlockingIOError), + ITEM(ChildProcessError), + ITEM(ConnectionError), + ITEM(FileExistsError), + ITEM(FileNotFoundError), + ITEM(InterruptedError), + ITEM(IsADirectoryError), + ITEM(NotADirectoryError), + ITEM(PermissionError), + ITEM(ProcessLookupError), + ITEM(TimeoutError), + + // Level 4: Other subclasses + ITEM(IndentationError), // base: SyntaxError(Exception) + ITEM(IndexError), // base: LookupError(Exception) + ITEM(KeyError), // base: LookupError(Exception) + ITEM(ModuleNotFoundError), // base: ImportError(Exception) + ITEM(NotImplementedError), // base: RuntimeError(Exception) + ITEM(RecursionError), // base: RuntimeError(Exception) + ITEM(UnboundLocalError), // base: NameError(Exception) + ITEM(UnicodeError), // base: ValueError(Exception) + + // Level 5: ConnectionError(OSError) subclasses + ITEM(BrokenPipeError), + ITEM(ConnectionAbortedError), + ITEM(ConnectionRefusedError), + ITEM(ConnectionResetError), + + // Level 5: IndentationError(SyntaxError) subclasses + ITEM(TabError), // base: IndentationError + + // Level 5: UnicodeError(ValueError) subclasses + ITEM(UnicodeDecodeError), + ITEM(UnicodeEncodeError), + ITEM(UnicodeTranslateError), +#undef ITEM +}; + + +int +_PyExc_InitTypes(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + return 0; + } + + for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) { + PyTypeObject *exc = static_exceptions[i].exc; + if (_PyStaticType_InitBuiltin(exc) < 0) { + return -1; + } + } + return 0; +} + + +static void +_PyExc_FiniTypes(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + return; + } + + for (Py_ssize_t i=Py_ARRAY_LENGTH(static_exceptions) - 1; i >= 0; i--) { + PyTypeObject *exc = static_exceptions[i].exc; + _PyStaticType_Dealloc(exc); + } +} + + PyStatus -_PyExc_Init(PyInterpreterState *interp) +_PyExc_InitGlobalObjects(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + return _PyStatus_OK(); + } + + if (preallocate_memerrors() < 0) { + return _PyStatus_NO_MEMORY(); + } + return _PyStatus_OK(); +} + +PyStatus +_PyExc_InitState(PyInterpreterState *interp) { struct _Py_exc_state *state = &interp->exc_state; -#define PRE_INIT(TYPE) \ - if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \ - if (PyType_Ready(&_PyExc_ ## TYPE) < 0) { \ - return _PyStatus_ERR("exceptions bootstrapping error."); \ - } \ - Py_INCREF(PyExc_ ## TYPE); \ - } - #define ADD_ERRNO(TYPE, CODE) \ do { \ PyObject *_code = PyLong_FromLong(CODE); \ @@ -3181,80 +3602,6 @@ _PyExc_Init(PyInterpreterState *interp) Py_DECREF(_code); \ } while (0) - PRE_INIT(BaseException); - PRE_INIT(BaseExceptionGroup); - PRE_INIT(Exception); - PRE_INIT(TypeError); - PRE_INIT(StopAsyncIteration); - PRE_INIT(StopIteration); - PRE_INIT(GeneratorExit); - PRE_INIT(SystemExit); - PRE_INIT(KeyboardInterrupt); - PRE_INIT(ImportError); - PRE_INIT(ModuleNotFoundError); - PRE_INIT(OSError); - PRE_INIT(EOFError); - PRE_INIT(RuntimeError); - PRE_INIT(RecursionError); - PRE_INIT(NotImplementedError); - PRE_INIT(NameError); - PRE_INIT(UnboundLocalError); - PRE_INIT(AttributeError); - PRE_INIT(SyntaxError); - PRE_INIT(IndentationError); - PRE_INIT(TabError); - PRE_INIT(LookupError); - PRE_INIT(IndexError); - PRE_INIT(KeyError); - PRE_INIT(ValueError); - PRE_INIT(UnicodeError); - PRE_INIT(UnicodeEncodeError); - PRE_INIT(UnicodeDecodeError); - PRE_INIT(UnicodeTranslateError); - PRE_INIT(AssertionError); - PRE_INIT(ArithmeticError); - PRE_INIT(FloatingPointError); - PRE_INIT(OverflowError); - PRE_INIT(ZeroDivisionError); - PRE_INIT(SystemError); - PRE_INIT(ReferenceError); - PRE_INIT(MemoryError); - PRE_INIT(BufferError); - PRE_INIT(Warning); - PRE_INIT(UserWarning); - PRE_INIT(EncodingWarning); - PRE_INIT(DeprecationWarning); - PRE_INIT(PendingDeprecationWarning); - PRE_INIT(SyntaxWarning); - PRE_INIT(RuntimeWarning); - PRE_INIT(FutureWarning); - PRE_INIT(ImportWarning); - PRE_INIT(UnicodeWarning); - PRE_INIT(BytesWarning); - PRE_INIT(ResourceWarning); - - /* OSError subclasses */ - PRE_INIT(ConnectionError); - - PRE_INIT(BlockingIOError); - PRE_INIT(BrokenPipeError); - PRE_INIT(ChildProcessError); - PRE_INIT(ConnectionAbortedError); - PRE_INIT(ConnectionRefusedError); - PRE_INIT(ConnectionResetError); - PRE_INIT(FileExistsError); - PRE_INIT(FileNotFoundError); - PRE_INIT(IsADirectoryError); - PRE_INIT(NotADirectoryError); - PRE_INIT(InterruptedError); - PRE_INIT(PermissionError); - PRE_INIT(ProcessLookupError); - PRE_INIT(TimeoutError); - - if (preallocate_memerrors() < 0) { - return _PyStatus_NO_MEMORY(); - } - /* Add exceptions to errnomap */ assert(state->errnomap == NULL); state->errnomap = PyDict_New(); @@ -3281,127 +3628,62 @@ _PyExc_Init(PyInterpreterState *interp) ADD_ERRNO(InterruptedError, EINTR); ADD_ERRNO(PermissionError, EACCES); ADD_ERRNO(PermissionError, EPERM); +#ifdef ENOTCAPABLE + // Extension for WASI capability-based security. Process lacks + // capability to access a resource. + ADD_ERRNO(PermissionError, ENOTCAPABLE); +#endif ADD_ERRNO(ProcessLookupError, ESRCH); ADD_ERRNO(TimeoutError, ETIMEDOUT); return _PyStatus_OK(); -#undef PRE_INIT #undef ADD_ERRNO } /* Add exception types to the builtins module */ -PyStatus +int _PyBuiltins_AddExceptions(PyObject *bltinmod) { -#define POST_INIT(TYPE) \ - if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) { \ - return _PyStatus_ERR("Module dictionary insertion problem."); \ + PyObject *mod_dict = PyModule_GetDict(bltinmod); + if (mod_dict == NULL) { + return -1; } -#define INIT_ALIAS(NAME, TYPE) \ - do { \ - Py_INCREF(PyExc_ ## TYPE); \ - Py_XDECREF(PyExc_ ## NAME); \ - PyExc_ ## NAME = PyExc_ ## TYPE; \ - if (PyDict_SetItemString(bdict, # NAME, PyExc_ ## NAME)) { \ - return _PyStatus_ERR("Module dictionary insertion problem."); \ - } \ - } while (0) + for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) { + struct static_exception item = static_exceptions[i]; - PyObject *bdict; - - bdict = PyModule_GetDict(bltinmod); - if (bdict == NULL) { - return _PyStatus_ERR("exceptions bootstrapping error."); + if (PyDict_SetItemString(mod_dict, item.name, (PyObject*)item.exc)) { + return -1; + } } PyObject *PyExc_ExceptionGroup = create_exception_group_class(); if (!PyExc_ExceptionGroup) { - return _PyStatus_ERR("exceptions bootstrapping error."); + return -1; + } + if (PyDict_SetItemString(mod_dict, "ExceptionGroup", PyExc_ExceptionGroup)) { + return -1; } - POST_INIT(BaseException); - POST_INIT(Exception); - POST_INIT(BaseExceptionGroup); - POST_INIT(ExceptionGroup); - POST_INIT(TypeError); - POST_INIT(StopAsyncIteration); - POST_INIT(StopIteration); - POST_INIT(GeneratorExit); - POST_INIT(SystemExit); - POST_INIT(KeyboardInterrupt); - POST_INIT(ImportError); - POST_INIT(ModuleNotFoundError); - POST_INIT(OSError); +#define INIT_ALIAS(NAME, TYPE) \ + do { \ + PyExc_ ## NAME = PyExc_ ## TYPE; \ + if (PyDict_SetItemString(mod_dict, # NAME, PyExc_ ## TYPE)) { \ + return -1; \ + } \ + } while (0) + INIT_ALIAS(EnvironmentError, OSError); INIT_ALIAS(IOError, OSError); #ifdef MS_WINDOWS INIT_ALIAS(WindowsError, OSError); #endif - POST_INIT(EOFError); - POST_INIT(RuntimeError); - POST_INIT(RecursionError); - POST_INIT(NotImplementedError); - POST_INIT(NameError); - POST_INIT(UnboundLocalError); - POST_INIT(AttributeError); - POST_INIT(SyntaxError); - POST_INIT(IndentationError); - POST_INIT(TabError); - POST_INIT(LookupError); - POST_INIT(IndexError); - POST_INIT(KeyError); - POST_INIT(ValueError); - POST_INIT(UnicodeError); - POST_INIT(UnicodeEncodeError); - POST_INIT(UnicodeDecodeError); - POST_INIT(UnicodeTranslateError); - POST_INIT(AssertionError); - POST_INIT(ArithmeticError); - POST_INIT(FloatingPointError); - POST_INIT(OverflowError); - POST_INIT(ZeroDivisionError); - POST_INIT(SystemError); - POST_INIT(ReferenceError); - POST_INIT(MemoryError); - POST_INIT(BufferError); - POST_INIT(Warning); - POST_INIT(UserWarning); - POST_INIT(EncodingWarning); - POST_INIT(DeprecationWarning); - POST_INIT(PendingDeprecationWarning); - POST_INIT(SyntaxWarning); - POST_INIT(RuntimeWarning); - POST_INIT(FutureWarning); - POST_INIT(ImportWarning); - POST_INIT(UnicodeWarning); - POST_INIT(BytesWarning); - POST_INIT(ResourceWarning); - /* OSError subclasses */ - POST_INIT(ConnectionError); - - POST_INIT(BlockingIOError); - POST_INIT(BrokenPipeError); - POST_INIT(ChildProcessError); - POST_INIT(ConnectionAbortedError); - POST_INIT(ConnectionRefusedError); - POST_INIT(ConnectionResetError); - POST_INIT(FileExistsError); - POST_INIT(FileNotFoundError); - POST_INIT(IsADirectoryError); - POST_INIT(NotADirectoryError); - POST_INIT(InterruptedError); - POST_INIT(PermissionError); - POST_INIT(ProcessLookupError); - POST_INIT(TimeoutError); - - return _PyStatus_OK(); - -#undef POST_INIT #undef INIT_ALIAS + + return 0; } void @@ -3417,6 +3699,8 @@ _PyExc_Fini(PyInterpreterState *interp) struct _Py_exc_state *state = &interp->exc_state; free_preallocated_memerrors(state); Py_CLEAR(state->errnomap); + + _PyExc_FiniTypes(interp); } /* Helper to do the equivalent of "raise X from Y" in C, but always using @@ -3453,7 +3737,6 @@ _PyErr_TrySetFromCause(const char *format, ...) PyObject* msg_prefix; PyObject *exc, *val, *tb; PyTypeObject *caught_type; - PyObject **dictptr; PyObject *instance_args; Py_ssize_t num_args, caught_type_size, base_exc_size; PyObject *new_exc, *new_val, *new_tb; @@ -3469,7 +3752,7 @@ _PyErr_TrySetFromCause(const char *format, ...) base_exc_size = _PyExc_BaseException.tp_basicsize; same_basic_size = ( caught_type_size == base_exc_size || - (PyType_SUPPORTS_WEAKREFS(caught_type) && + (_PyType_SUPPORTS_WEAKREFS(caught_type) && (caught_type_size == base_exc_size + (Py_ssize_t)sizeof(PyObject *)) ) ); @@ -3499,9 +3782,7 @@ _PyErr_TrySetFromCause(const char *format, ...) } /* Ensure the instance dict is also empty */ - dictptr = _PyObject_GetDictPtr(val); - if (dictptr != NULL && *dictptr != NULL && - PyDict_GET_SIZE(*dictptr) > 0) { + if (!_PyObject_IsInstanceDictEmpty(val)) { /* While we could potentially copy a non-empty instance dictionary * to the replacement exception, for now we take the more * conservative path of leaving exceptions with attributes set @@ -3526,11 +3807,7 @@ _PyErr_TrySetFromCause(const char *format, ...) Py_DECREF(tb); } -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif msg_prefix = PyUnicode_FromFormatV(format, vargs); va_end(vargs); if (msg_prefix == NULL) { diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 8ca56a802b9..e99e155f2b8 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -26,24 +26,22 @@ extern "C" { #endif -_Py_IDENTIFIER(open); - /* External C interface */ PyObject * PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const char *encoding, const char *errors, const char *newline, int closefd) { - PyObject *io, *stream; + PyObject *open, *stream; /* import _io in case we are being used to open io.py */ - io = PyImport_ImportModule("_io"); - if (io == NULL) + open = _PyImport_GetModuleAttrString("_io", "open"); + if (open == NULL) return NULL; - stream = _PyObject_CallMethodId(io, &PyId_open, "isisssO", fd, mode, - buffering, encoding, errors, - newline, closefd ? Py_True : Py_False); - Py_DECREF(io); + stream = PyObject_CallFunction(open, "isisssO", fd, mode, + buffering, encoding, errors, + newline, closefd ? Py_True : Py_False); + Py_DECREF(open); if (stream == NULL) return NULL; /* ignore name attribute because the name attribute of _BufferedIOMixin @@ -54,7 +52,6 @@ PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const c PyObject * PyFile_GetLine(PyObject *f, int n) { - _Py_IDENTIFIER(readline); PyObject *result; if (f == NULL) { @@ -63,15 +60,14 @@ PyFile_GetLine(PyObject *f, int n) } if (n <= 0) { - result = _PyObject_CallMethodIdNoArgs(f, &PyId_readline); + result = PyObject_CallMethodNoArgs(f, &_Py_ID(readline)); } else { - result = _PyObject_CallMethodId(f, &PyId_readline, "i", n); + result = _PyObject_CallMethod(f, &_Py_ID(readline), "i", n); } if (result != NULL && !PyBytes_Check(result) && !PyUnicode_Check(result)) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); PyErr_SetString(PyExc_TypeError, "object.readline() returned non-string"); } @@ -80,8 +76,7 @@ PyFile_GetLine(PyObject *f, int n) const char *s = PyBytes_AS_STRING(result); Py_ssize_t len = PyBytes_GET_SIZE(result); if (len == 0) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); PyErr_SetString(PyExc_EOFError, "EOF when reading a line"); } @@ -91,24 +86,21 @@ PyFile_GetLine(PyObject *f, int n) else { PyObject *v; v = PyBytes_FromStringAndSize(s, len-1); - Py_DECREF(result); - result = v; + Py_SETREF(result, v); } } } if (n < 0 && result != NULL && PyUnicode_Check(result)) { Py_ssize_t len = PyUnicode_GET_LENGTH(result); if (len == 0) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); PyErr_SetString(PyExc_EOFError, "EOF when reading a line"); } else if (PyUnicode_READ_CHAR(result, len-1) == '\n') { PyObject *v; v = PyUnicode_Substring(result, 0, len-1); - Py_DECREF(result); - result = v; + Py_SETREF(result, v); } } return result; @@ -120,13 +112,12 @@ int PyFile_WriteObject(PyObject *v, PyObject *f, int flags) { PyObject *writer, *value, *result; - _Py_IDENTIFIER(write); if (f == NULL) { PyErr_SetString(PyExc_TypeError, "writeobject with NULL file"); return -1; } - writer = _PyObject_GetAttrId(f, &PyId_write); + writer = PyObject_GetAttr(f, &_Py_ID(write)); if (writer == NULL) return -1; if (flags & Py_PRINT_RAW) { @@ -182,12 +173,11 @@ PyObject_AsFileDescriptor(PyObject *o) { int fd; PyObject *meth; - _Py_IDENTIFIER(fileno); if (PyLong_Check(o)) { fd = _PyLong_AsInt(o); } - else if (_PyObject_LookupAttrId(o, &PyId_fileno, &meth) < 0) { + else if (_PyObject_LookupAttr(o, &_Py_ID(fileno), &meth) < 0) { return -1; } else if (meth != NULL) { @@ -235,16 +225,8 @@ _PyLong_FileDescriptor_Converter(PyObject *o, void *ptr) return 1; } -/* -** Py_UniversalNewlineFgets is an fgets variation that understands -** all of \r, \n and \r\n conventions. -** The stream should be opened in binary mode. -** The fobj parameter exists solely for legacy reasons and must be NULL. -** Note that we need no error handling: fgets() treats error and eof -** identically. -*/ char * -Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj) +_Py_UniversalNewlineFgetsWithSize(char *buf, int n, FILE *stream, PyObject *fobj, size_t* size) { char *p = buf; int c; @@ -270,11 +252,28 @@ Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj) } FUNLOCKFILE(stream); *p = '\0'; - if (p == buf) + if (p == buf) { return NULL; + } + *size = p - buf; return buf; } +/* +** Py_UniversalNewlineFgets is an fgets variation that understands +** all of \r, \n and \r\n conventions. +** The stream should be opened in binary mode. +** The fobj parameter exists solely for legacy reasons and must be NULL. +** Note that we need no error handling: fgets() treats error and eof +** identically. +*/ + +char * +Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj) { + size_t size; + return _Py_UniversalNewlineFgetsWithSize(buf, n, stream, fobj, &size); +} + /* **************************** std printer **************************** * The stdprinter is used during the boot strapping phase as a preliminary * file like object for sys.stderr. @@ -495,7 +494,7 @@ PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData) { PyObject * PyFile_OpenCodeObject(PyObject *path) { - PyObject *iomod, *f = NULL; + PyObject *f = NULL; if (!PyUnicode_Check(path)) { PyErr_Format(PyExc_TypeError, "'path' must be 'str', not '%.200s'", @@ -507,11 +506,10 @@ PyFile_OpenCodeObject(PyObject *path) if (hook) { f = hook(path, _PyRuntime.open_code_userdata); } else { - iomod = PyImport_ImportModule("_io"); - if (iomod) { - f = _PyObject_CallMethodId(iomod, &PyId_open, "Os", - path, "rb"); - Py_DECREF(iomod); + PyObject *open = _PyImport_GetModuleAttrString("_io", "open"); + if (open) { + f = PyObject_CallFunction(open, "Os", path, "rb"); + Py_DECREF(open); } } diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 7fc192e7201..912b742f797 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -6,11 +6,13 @@ #include "Python.h" #include "pycore_dtoa.h" // _Py_dg_dtoa() #include "pycore_floatobject.h" // _PyFloat_FormatAdvancedWriter() +#include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_interp.h" // _PyInterpreterState.float_state #include "pycore_long.h" // _PyLong_GetOne() #include "pycore_object.h" // _PyObject_Init() -#include "pycore_pymath.h" // _Py_ADJUST_ERANGE1() +#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR #include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_structseq.h" // _PyStructSequence_FiniType() #include #include @@ -69,7 +71,7 @@ static PyStructSequence_Field floatinfo_fields[] = { {"min_exp", "DBL_MIN_EXP -- minimum int e such that radix**(e-1) " "is a normalized float"}, {"min_10_exp", "DBL_MIN_10_EXP -- minimum int e such that 10**e is " - "a normalized"}, + "a normalized float"}, {"dig", "DBL_DIG -- maximum number of decimal digits that " "can be faithfully represented in a float"}, {"mant_dig", "DBL_MANT_DIG -- mantissa digits"}, @@ -139,6 +141,7 @@ PyFloat_FromDouble(double fval) #endif state->free_list = (PyFloatObject *) Py_TYPE(op); state->numfree--; + OBJECT_STAT_INC(from_freelist); } else #endif @@ -159,11 +162,18 @@ float_from_string_inner(const char *s, Py_ssize_t len, void *obj) double x; const char *end; const char *last = s + len; - /* strip space */ + /* strip leading whitespace */ while (s < last && Py_ISSPACE(*s)) { s++; } + if (s == last) { + PyErr_Format(PyExc_ValueError, + "could not convert string to float: " + "%R", obj); + return NULL; + } + /* strip trailing whitespace */ while (s < last - 1 && Py_ISSPACE(last[-1])) { last--; } @@ -236,28 +246,42 @@ PyFloat_FromString(PyObject *v) return result; } -static void -float_dealloc(PyFloatObject *op) +void +_PyFloat_ExactDealloc(PyObject *obj) { + assert(PyFloat_CheckExact(obj)); + PyFloatObject *op = (PyFloatObject *)obj; +#if PyFloat_MAXFREELIST > 0 + struct _Py_float_state *state = get_float_state(); +#ifdef Py_DEBUG + // float_dealloc() must not be called after _PyFloat_Fini() + assert(state->numfree != -1); +#endif + if (state->numfree >= PyFloat_MAXFREELIST) { + PyObject_Free(op); + return; + } + state->numfree++; + Py_SET_TYPE(op, (PyTypeObject *)state->free_list); + state->free_list = op; + OBJECT_STAT_INC(to_freelist); +#else + PyObject_Free(op); +#endif +} + +static void +float_dealloc(PyObject *op) +{ + assert(PyFloat_Check(op)); #if PyFloat_MAXFREELIST > 0 if (PyFloat_CheckExact(op)) { - struct _Py_float_state *state = get_float_state(); -#ifdef Py_DEBUG - // float_dealloc() must not be called after _PyFloat_Fini() - assert(state->numfree != -1); -#endif - if (state->numfree >= PyFloat_MAXFREELIST) { - PyObject_Free(op); - return; - } - state->numfree++; - Py_SET_TYPE(op, (PyTypeObject *)state->free_list); - state->free_list = op; + _PyFloat_ExactDealloc(op); } else #endif { - Py_TYPE(op)->tp_free((PyObject *)op); + Py_TYPE(op)->tp_free(op); } } @@ -347,8 +371,7 @@ convert_to_double(PyObject **v, double *dbl) } } else { - Py_INCREF(Py_NotImplemented); - *v = Py_NotImplemented; + *v = Py_NewRef(Py_NotImplemented); return -1; } return 0; @@ -508,20 +531,17 @@ float_richcompare(PyObject *v, PyObject *w, int op) temp = _PyLong_Lshift(ww, 1); if (temp == NULL) goto Error; - Py_DECREF(ww); - ww = temp; + Py_SETREF(ww, temp); temp = _PyLong_Lshift(vv, 1); if (temp == NULL) goto Error; - Py_DECREF(vv); - vv = temp; + Py_SETREF(vv, temp); temp = PyNumber_Or(vv, _PyLong_GetOne()); if (temp == NULL) goto Error; - Py_DECREF(vv); - vv = temp; + Py_SETREF(vv, temp); } r = PyObject_RichCompareBool(vv, ww, op); @@ -880,8 +900,7 @@ float_is_integer_impl(PyObject *self) PyExc_ValueError); return NULL; } - Py_INCREF(o); - return o; + return Py_NewRef(o); } /*[clinic input] @@ -930,7 +949,7 @@ float___ceil___impl(PyObject *self) ndigits <= 323). Returns a Python float, or sets a Python error and returns NULL on failure (OverflowError and memory errors are possible). */ -#ifndef PY_NO_SHORT_FLOAT_REPR +#if _PY_SHORT_FLOAT_REPR == 1 /* version of double_round that uses the correctly-rounded string<->double conversions from Python/dtoa.c */ @@ -987,7 +1006,7 @@ double_round(double x, int ndigits) { return result; } -#else /* PY_NO_SHORT_FLOAT_REPR */ +#else // _PY_SHORT_FLOAT_REPR == 0 /* fallback version, to be used when correctly rounded binary<->decimal conversions aren't available */ @@ -1037,7 +1056,7 @@ double_round(double x, int ndigits) { return PyFloat_FromDouble(z); } -#endif /* PY_NO_SHORT_FLOAT_REPR */ +#endif // _PY_SHORT_FLOAT_REPR == 0 /* round a Python float v to the closest multiple of 10**-ndigits */ @@ -1100,11 +1119,12 @@ float___round___impl(PyObject *self, PyObject *o_ndigits) static PyObject * float_float(PyObject *v) { - if (PyFloat_CheckExact(v)) - Py_INCREF(v); - else - v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval); - return v; + if (PyFloat_CheckExact(v)) { + return Py_NewRef(v); + } + else { + return PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval); + } } /*[clinic input] @@ -1684,7 +1704,7 @@ float_vectorcall(PyObject *type, PyObject * const*args, } PyObject *x = nargs >= 1 ? args[0] : NULL; - return float_new_impl((PyTypeObject *)type, x); + return float_new_impl(_PyType_CAST(type), x); } @@ -1700,13 +1720,14 @@ float___getnewargs___impl(PyObject *self) } /* this is for the benefit of the pack/unpack routines below */ +typedef enum _py_float_format_type float_format_type; +#define unknown_format _py_float_format_unknown +#define ieee_big_endian_format _py_float_format_ieee_big_endian +#define ieee_little_endian_format _py_float_format_ieee_little_endian -typedef enum { - unknown_format, ieee_big_endian_format, ieee_little_endian_format -} float_format_type; +#define float_format (_PyRuntime.float_state.float_format) +#define double_format (_PyRuntime.float_state.double_format) -static float_format_type double_format, float_format; -static float_format_type detected_double_format, detected_float_format; /*[clinic input] @classmethod @@ -1758,78 +1779,6 @@ float___getformat___impl(PyTypeObject *type, const char *typestr) } } -/*[clinic input] -@classmethod -float.__set_format__ - - typestr: str - Must be 'double' or 'float'. - fmt: str - Must be one of 'unknown', 'IEEE, big-endian' or 'IEEE, little-endian', - and in addition can only be one of the latter two if it appears to - match the underlying C reality. - / - -You probably don't want to use this function. - -It exists mainly to be used in Python's test suite. - -Override the automatic determination of C-level floating point type. -This affects how floats are converted to and from binary strings. -[clinic start generated code]*/ - -static PyObject * -float___set_format___impl(PyTypeObject *type, const char *typestr, - const char *fmt) -/*[clinic end generated code: output=504460f5dc85acbd input=5306fa2b81a997e4]*/ -{ - float_format_type f; - float_format_type detected; - float_format_type *p; - - if (strcmp(typestr, "double") == 0) { - p = &double_format; - detected = detected_double_format; - } - else if (strcmp(typestr, "float") == 0) { - p = &float_format; - detected = detected_float_format; - } - else { - PyErr_SetString(PyExc_ValueError, - "__setformat__() argument 1 must " - "be 'double' or 'float'"); - return NULL; - } - - if (strcmp(fmt, "unknown") == 0) { - f = unknown_format; - } - else if (strcmp(fmt, "IEEE, little-endian") == 0) { - f = ieee_little_endian_format; - } - else if (strcmp(fmt, "IEEE, big-endian") == 0) { - f = ieee_big_endian_format; - } - else { - PyErr_SetString(PyExc_ValueError, - "__setformat__() argument 2 must be " - "'unknown', 'IEEE, little-endian' or " - "'IEEE, big-endian'"); - return NULL; - - } - - if (f != unknown_format && f != detected) { - PyErr_Format(PyExc_ValueError, - "can only set %s format to 'unknown' or the " - "detected platform value", typestr); - return NULL; - } - - *p = f; - Py_RETURN_NONE; -} static PyObject * float_getreal(PyObject *v, void *closure) @@ -1883,7 +1832,6 @@ static PyMethodDef float_methods[] = { FLOAT_IS_INTEGER_METHODDEF FLOAT___GETNEWARGS___METHODDEF FLOAT___GETFORMAT___METHODDEF - FLOAT___SET_FORMAT___METHODDEF FLOAT___FORMAT___METHODDEF {NULL, NULL} /* sentinel */ }; @@ -1980,9 +1928,11 @@ PyTypeObject PyFloat_Type = { .tp_vectorcall = (vectorcallfunc)float_vectorcall, }; -void -_PyFloat_Init(void) +static void +_init_global_state(void) { + float_format_type detected_double_format, detected_float_format; + /* We attempt to determine if this machine is using IEEE floating point formats by peering at the bits of some carefully chosen values. If it looks like we are on an @@ -2030,16 +1980,35 @@ _PyFloat_Init(void) float_format = detected_float_format; } -int -_PyFloat_InitTypes(void) +void +_PyFloat_InitState(PyInterpreterState *interp) { + if (!_Py_IsMainInterpreter(interp)) { + return; + } + _init_global_state(); +} + +PyStatus +_PyFloat_InitTypes(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + return _PyStatus_OK(); + } + + if (PyType_Ready(&PyFloat_Type) < 0) { + return _PyStatus_ERR("Can't initialize float type"); + } + /* Init float info */ if (FloatInfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&FloatInfoType, &floatinfo_desc) < 0) { - return -1; + if (_PyStructSequence_InitBuiltin(&FloatInfoType, + &floatinfo_desc) < 0) { + return _PyStatus_ERR("can't init float info type"); } } - return 0; + + return _PyStatus_OK(); } void @@ -2068,6 +2037,14 @@ _PyFloat_Fini(PyInterpreterState *interp) #endif } +void +_PyFloat_FiniType(PyInterpreterState *interp) +{ + if (_Py_IsMainInterpreter(interp)) { + _PyStructSequence_FiniType(&FloatInfoType); + } +} + /* Print summary info about the state of the optimized allocator */ void _PyFloat_DebugMallocStats(FILE *out) @@ -2082,7 +2059,7 @@ _PyFloat_DebugMallocStats(FILE *out) /*---------------------------------------------------------------------------- - * _PyFloat_{Pack,Unpack}{2,4,8}. See floatobject.h. + * PyFloat_{Pack,Unpack}{2,4,8}. See floatobject.h. * To match the NPY_HALF_ROUND_TIES_TO_EVEN behavior in: * https://github.com/numpy/numpy/blob/master/numpy/core/src/npymath/halffloat.c * We use: @@ -2093,8 +2070,9 @@ _PyFloat_DebugMallocStats(FILE *out) */ int -_PyFloat_Pack2(double x, unsigned char *p, int le) +PyFloat_Pack2(double x, char *data, int le) { + unsigned char *p = (unsigned char *)data; unsigned char sign; int e; double f; @@ -2197,8 +2175,9 @@ _PyFloat_Pack2(double x, unsigned char *p, int le) } int -_PyFloat_Pack4(double x, unsigned char *p, int le) +PyFloat_Pack4(double x, char *data, int le) { + unsigned char *p = (unsigned char *)data; if (float_format == unknown_format) { unsigned char sign; int e; @@ -2304,8 +2283,9 @@ _PyFloat_Pack4(double x, unsigned char *p, int le) } int -_PyFloat_Pack8(double x, unsigned char *p, int le) +PyFloat_Pack8(double x, char *data, int le) { + unsigned char *p = (unsigned char *)data; if (double_format == unknown_format) { unsigned char sign; int e; @@ -2433,8 +2413,9 @@ _PyFloat_Pack8(double x, unsigned char *p, int le) } double -_PyFloat_Unpack2(const unsigned char *p, int le) +PyFloat_Unpack2(const char *data, int le) { + unsigned char *p = (unsigned char *)data; unsigned char sign; int e; unsigned int f; @@ -2456,24 +2437,16 @@ _PyFloat_Unpack2(const unsigned char *p, int le) f |= *p; if (e == 0x1f) { -#ifdef PY_NO_SHORT_FLOAT_REPR +#if _PY_SHORT_FLOAT_REPR == 0 if (f == 0) { /* Infinity */ return sign ? -Py_HUGE_VAL : Py_HUGE_VAL; } else { /* NaN */ -#ifdef Py_NAN return sign ? -Py_NAN : Py_NAN; -#else - PyErr_SetString( - PyExc_ValueError, - "can't unpack IEEE 754 NaN " - "on platform that does not support NaNs"); - return -1; -#endif /* #ifdef Py_NAN */ } -#else +#else // _PY_SHORT_FLOAT_REPR == 1 if (f == 0) { /* Infinity */ return _Py_dg_infinity(sign); @@ -2482,7 +2455,7 @@ _PyFloat_Unpack2(const unsigned char *p, int le) /* NaN */ return _Py_dg_stdnan(sign); } -#endif /* #ifdef PY_NO_SHORT_FLOAT_REPR */ +#endif // _PY_SHORT_FLOAT_REPR == 1 } x = (double)f / 1024.0; @@ -2503,8 +2476,9 @@ _PyFloat_Unpack2(const unsigned char *p, int le) } double -_PyFloat_Unpack4(const unsigned char *p, int le) +PyFloat_Unpack4(const char *data, int le) { + unsigned char *p = (unsigned char *)data; if (float_format == unknown_format) { unsigned char sign; int e; @@ -2581,8 +2555,9 @@ _PyFloat_Unpack4(const unsigned char *p, int le) } double -_PyFloat_Unpack8(const unsigned char *p, int le) +PyFloat_Unpack8(const char *data, int le) { + unsigned char *p = (unsigned char *)data; if (double_format == unknown_format) { unsigned char sign; int e; diff --git a/Objects/frame_layout.md b/Objects/frame_layout.md new file mode 100644 index 00000000000..2f95214db56 --- /dev/null +++ b/Objects/frame_layout.md @@ -0,0 +1,132 @@ +# The Frame Stack + +Each call to a Python function has an activation record, +commonly known as a "frame". +Python semantics allows frames to outlive the activation, +so they have (before 3.11) been allocated on the heap. +This is expensive as it requires many allocations and +results in poor locality of reference. + +In 3.11, rather than have these frames scattered about memory, +as happens for heap-allocated objects, frames are allocated +contiguously in a per-thread stack. +This improves performance significantly for two reasons: +* It reduces allocation overhead to a pointer comparison and increment. +* Stack allocated data has the best possible locality and will always be in + CPU cache. + +Generator and coroutines still need heap allocated activation records, but +can be linked into the per-thread stack so as to not impact performance too much. + +## Layout + +Each activation record consists of four conceptual sections: + +* Local variables (including arguments, cells and free variables) +* Evaluation stack +* Specials: The per-frame object references needed by the VM: globals dict, + code object, etc. +* Linkage: Pointer to the previous activation record, stack depth, etc. + +### Layout + +The specials and linkage sections are a fixed size, so are grouped together. + +Each activation record is laid out as: +* Specials and linkage +* Locals +* Stack + +This seems to provide the best performance without excessive complexity. +It needs the interpreter to hold two pointers, a frame pointer and a stack pointer. + +#### Alternative layout + +An alternative layout that was used for part of 3.11 alpha was: + +* Locals +* Specials and linkage +* Stack + +This has the advantage that no copying is required when making a call, +as the arguments on the stack are (usually) already in the correct +location for the parameters. However, it requires the VM to maintain +an extra pointer for the locals, which can hurt performance. + +A variant that only needs the need two pointers is to reverse the numbering +of the locals, so that the last one is numbered `0`, and the first in memory +is numbered `N-1`. +This allows the locals, specials and linkage to accessed from the frame pointer. +We may implement this in the future. + +#### Note: + +> In a contiguous stack, we would need to save one fewer registers, as the +> top of the caller's activation record would be the same at the base of the +> callee's. However, since some activation records are kept on the heap we +> cannot do this. + +### Generators and Coroutines + +Generators and coroutines contain a `_PyInterpreterFrame` +The specials sections contains the following pointers: + +* Globals dict +* Builtins dict +* Locals dict (not the "fast" locals, but the locals for eval and class creation) +* Code object +* Heap allocated `PyFrameObject` for this activation record, if any. +* The function. + +The pointer to the function is not strictly required, but it is cheaper to +store a strong reference to the function and borrowed references to the globals +and builtins, than strong references to both globals and builtins. + +### Frame objects + +When creating a backtrace or when calling `sys._getframe()` the frame becomes +visible to Python code. When this happens a new `PyFrameObject` is created +and a strong reference to it placed in the `frame_obj` field of the specials +section. The `frame_obj` field is initially `NULL`. + +The `PyFrameObject` may outlive a stack-allocated `_PyInterpreterFrame`. +If it does then `_PyInterpreterFrame` is copied into the `PyFrameObject`, +except the evaluation stack which must be empty at this point. +The linkage section is updated to reflect the new location of the frame. + +This mechanism provides the appearance of persistent, heap-allocated +frames for each activation, but with low runtime overhead. + +### Generators and Coroutines + + +Generator objects have a `_PyInterpreterFrame` embedded in them. +This means that creating a generator requires only a single allocation, +reducing allocation overhead and improving locality of reference. +The embedded frame is linked into the per-thread frame when iterated or +awaited. + +If a frame object associated with a generator outlives the generator, then +the embedded `_PyInterpreterFrame` is copied into the frame object. + + +All the above applies to coroutines and async generators as well. + +### Field names + +Many of the fields in `_PyInterpreterFrame` were copied from the 3.10 `PyFrameObject`. +Thus, some of the field names may be a bit misleading. + +For example the `f_globals` field has a `f_` prefix implying it belongs to the +`PyFrameObject` struct, although it belongs to the `_PyInterpreterFrame` struct. +We may rationalize this naming scheme for 3.12. + + +### Shim frames + +On entry to `_PyEval_EvalFrameDefault()` a shim `_PyInterpreterFrame` is pushed. +This frame is stored on the C stack, and popped when `_PyEval_EvalFrameDefault()` +returns. This extra frame is inserted so that `RETURN_VALUE`, `YIELD_VALUE`, and +`RETURN_GENERATOR` do not need to check whether the current frame is the entry frame. +The shim frame points to a special code object containing the `INTERPRETER_EXIT` +instruction which cleans up the shim frame and returns. diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 09857c7fa00..6bc04bc8e84 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -2,9 +2,11 @@ #include "Python.h" #include "pycore_ceval.h" // _PyEval_BuiltinsFromGlobals() +#include "pycore_code.h" // CO_FAST_LOCAL, etc. +#include "pycore_function.h" // _PyFunction_FromConstructor() #include "pycore_moduleobject.h" // _PyModule_GetDict() #include "pycore_object.h" // _PyObject_GC_UNTRACK() -#include "pycore_code.h" // CO_FAST_LOCAL, etc. +#include "pycore_opcode.h" // _PyOpcode_Caches #include "frameobject.h" // PyFrameObject #include "pycore_frame.h" @@ -19,15 +21,6 @@ static PyMemberDef frame_memberlist[] = { {NULL} /* Sentinel */ }; -#if PyFrame_MAXFREELIST > 0 -static struct _Py_frame_state * -get_frame_state(void) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - return &interp->frame; -} -#endif - static PyObject * frame_getlocals(PyFrameObject *f, void *closure) @@ -35,8 +28,7 @@ frame_getlocals(PyFrameObject *f, void *closure) if (PyFrame_FastToLocalsWithError(f) < 0) return NULL; PyObject *locals = f->f_frame->f_locals; - Py_INCREF(locals); - return locals; + return Py_NewRef(locals); } int @@ -47,7 +39,7 @@ PyFrame_GetLineNumber(PyFrameObject *f) return f->f_lineno; } else { - return PyCode_Addr2Line(f->f_frame->f_code, f->f_frame->f_lasti*sizeof(_Py_CODEUNIT)); + return _PyInterpreterFrame_GetLine(f->f_frame); } } @@ -66,10 +58,11 @@ frame_getlineno(PyFrameObject *f, void *closure) static PyObject * frame_getlasti(PyFrameObject *f, void *closure) { - if (f->f_frame->f_lasti < 0) { + int lasti = _PyInterpreterFrame_LASTI(f->f_frame); + if (lasti < 0) { return PyLong_FromLong(-1); } - return PyLong_FromLong(f->f_frame->f_lasti*sizeof(_Py_CODEUNIT)); + return PyLong_FromLong(lasti * sizeof(_Py_CODEUNIT)); } static PyObject * @@ -79,8 +72,7 @@ frame_getglobals(PyFrameObject *f, void *closure) if (globals == NULL) { globals = Py_None; } - Py_INCREF(globals); - return globals; + return Py_NewRef(globals); } static PyObject * @@ -90,8 +82,7 @@ frame_getbuiltins(PyFrameObject *f, void *closure) if (builtins == NULL) { builtins = Py_None; } - Py_INCREF(builtins); - return builtins; + return Py_NewRef(builtins); } static PyObject * @@ -113,8 +104,9 @@ frame_getback(PyFrameObject *f, void *closure) return res; } -/* Given the index of the effective opcode, - scan back to construct the oparg with EXTENDED_ARG */ +// Given the index of the effective opcode, scan back to construct the oparg +// with EXTENDED_ARG. This only works correctly with *unquickened* code, +// obtained via a call to _PyCode_GetCode! static unsigned int get_arg(const _Py_CODEUNIT *codestr, Py_ssize_t i) { @@ -142,9 +134,25 @@ typedef enum kind { Iterator = 1, Except = 2, Object = 3, + Null = 4, + Lasti = 5, } Kind; -#define BITS_PER_BLOCK 2 +static int +compatible_kind(Kind from, Kind to) { + if (to == 0) { + return 0; + } + if (to == Object) { + return from != Null; + } + if (to == Null) { + return 1; + } + return from == to; +} + +#define BITS_PER_BLOCK 3 #define UNINITIALIZED -2 #define OVERFLOWED -1 @@ -152,6 +160,8 @@ typedef enum kind { #define MAX_STACK_ENTRIES (63/BITS_PER_BLOCK) #define WILL_OVERFLOW (1ULL<<((MAX_STACK_ENTRIES-1)*BITS_PER_BLOCK)) +#define EMPTY_STACK 0 + static inline int64_t push_value(int64_t stack, Kind kind) { @@ -169,31 +179,126 @@ pop_value(int64_t stack) return Py_ARITHMETIC_RIGHT_SHIFT(int64_t, stack, BITS_PER_BLOCK); } +#define MASK ((1<= 1); + return (stack>>(BITS_PER_BLOCK*(n-1))) & MASK; +} + +static Kind +stack_swap(int64_t stack, int n) +{ + assert(n >= 1); + Kind to_swap = peek(stack, n); + Kind top = top_of_stack(stack); + int shift = BITS_PER_BLOCK*(n-1); + int64_t replaced_low = (stack & ~(MASK << shift)) | (top << shift); + int64_t replaced_top = (replaced_low & ~MASK) | to_swap; + return replaced_top; +} + +static int64_t +pop_to_level(int64_t stack, int level) { + if (level == 0) { + return EMPTY_STACK; + } + int64_t max_item = (1< level_max_stack) { + stack = pop_value(stack); + } + return stack; +} + +#if 0 +/* These functions are useful for debugging the stack marking code */ + +static char +tos_char(int64_t stack) { + switch(top_of_stack(stack)) { + case Iterator: + return 'I'; + case Except: + return 'E'; + case Object: + return 'O'; + case Lasti: + return 'L'; + case Null: + return 'N'; + } + return '?'; +} + +static void +print_stack(int64_t stack) { + if (stack < 0) { + if (stack == UNINITIALIZED) { + printf("---"); + } + else if (stack == OVERFLOWED) { + printf("OVERFLOWED"); + } + else { + printf("??"); + } + return; + } + while (stack) { + printf("%c", tos_char(stack)); + stack = pop_value(stack); + } +} + +static void +print_stacks(int64_t *stacks, int n) { + for (int i = 0; i < n; i++) { + printf("%d: ", i); + print_stack(stacks[i]); + printf("\n"); + } +} + +#endif + static int64_t * mark_stacks(PyCodeObject *code_obj, int len) { - const _Py_CODEUNIT *code = - (const _Py_CODEUNIT *)PyBytes_AS_STRING(code_obj->co_code); + PyObject *co_code = _PyCode_GetCode(code_obj); + if (co_code == NULL) { + return NULL; + } + _Py_CODEUNIT *code = (_Py_CODEUNIT *)PyBytes_AS_STRING(co_code); int64_t *stacks = PyMem_New(int64_t, len+1); int i, j, opcode; if (stacks == NULL) { PyErr_NoMemory(); + Py_DECREF(co_code); return NULL; } for (int i = 1; i <= len; i++) { stacks[i] = UNINITIALIZED; } - stacks[0] = 0; + stacks[0] = EMPTY_STACK; + if (code_obj->co_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) + { + // Generators get sent None while starting: + stacks[0] = push_value(stacks[0], Object); + } int todo = 1; while (todo) { todo = 0; + /* Scan instructions */ for (i = 0; i < len; i++) { int64_t next_stack = stacks[i]; if (next_stack == UNINITIALIZED) { @@ -205,20 +310,16 @@ mark_stacks(PyCodeObject *code_obj, int len) case JUMP_IF_TRUE_OR_POP: case POP_JUMP_IF_FALSE: case POP_JUMP_IF_TRUE: - case JUMP_IF_NOT_EXC_MATCH: { int64_t target_stack; int j = get_arg(code, i); + j += i + 1; assert(j < len); if (stacks[j] == UNINITIALIZED && j < i) { todo = 1; } - if (opcode == JUMP_IF_NOT_EXC_MATCH) { - next_stack = pop_value(pop_value(next_stack)); - target_stack = next_stack; - } - else if (opcode == JUMP_IF_FALSE_OR_POP || - opcode == JUMP_IF_TRUE_OR_POP) + if (opcode == JUMP_IF_FALSE_OR_POP || + opcode == JUMP_IF_TRUE_OR_POP) { target_stack = next_stack; next_stack = pop_value(next_stack); @@ -232,8 +333,23 @@ mark_stacks(PyCodeObject *code_obj, int len) stacks[i+1] = next_stack; break; } - case JUMP_ABSOLUTE: - j = get_arg(code, i); + case SEND: + j = get_arg(code, i) + i + 1; + assert(j < len); + assert(stacks[j] == UNINITIALIZED || stacks[j] == pop_value(next_stack)); + stacks[j] = pop_value(next_stack); + stacks[i+1] = next_stack; + break; + case JUMP_FORWARD: + j = get_arg(code, i) + i + 1; + assert(j < len); + assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack); + stacks[j] = next_stack; + break; + case JUMP_BACKWARD: + case JUMP_BACKWARD_NO_INTERRUPT: + j = i + 1 - get_arg(code, i); + assert(j >= 0); assert(j < len); if (stacks[j] == UNINITIALIZED && j < i) { todo = 1; @@ -241,12 +357,9 @@ mark_stacks(PyCodeObject *code_obj, int len) assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack); stacks[j] = next_stack; break; - case POP_EXCEPT: - next_stack = pop_value(pop_value(pop_value(next_stack))); - stacks[i+1] = next_stack; - break; - - case JUMP_FORWARD: + case COMPARE_AND_BRANCH: + next_stack = pop_value(pop_value(next_stack)); + i++; j = get_arg(code, i) + i + 1; assert(j < len); assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack); @@ -259,35 +372,91 @@ mark_stacks(PyCodeObject *code_obj, int len) break; case FOR_ITER: { - int64_t target_stack = pop_value(next_stack); - stacks[i+1] = push_value(next_stack, Object); - j = get_arg(code, i) + i + 1; + int64_t target_stack = push_value(next_stack, Object); + stacks[i+1] = target_stack; + j = get_arg(code, i) + 1 + INLINE_CACHE_ENTRIES_FOR_ITER + i; assert(j < len); assert(stacks[j] == UNINITIALIZED || stacks[j] == target_stack); stacks[j] = target_stack; break; } case END_ASYNC_FOR: - next_stack = pop_value(pop_value(pop_value(next_stack))); + next_stack = pop_value(pop_value(next_stack)); stacks[i+1] = next_stack; break; case PUSH_EXC_INFO: - next_stack = push_value(next_stack, Except); - next_stack = push_value(next_stack, Except); next_stack = push_value(next_stack, Except); stacks[i+1] = next_stack; + break; + case POP_EXCEPT: + assert(top_of_stack(next_stack) == Except); + next_stack = pop_value(next_stack); + stacks[i+1] = next_stack; + break; case RETURN_VALUE: + assert(pop_value(next_stack) == EMPTY_STACK); + assert(top_of_stack(next_stack) == Object); + break; case RAISE_VARARGS: + break; case RERAISE: - case POP_EXCEPT_AND_RERAISE: + assert(top_of_stack(next_stack) == Except); /* End of block */ break; - case GEN_START: + case PUSH_NULL: + next_stack = push_value(next_stack, Null); stacks[i+1] = next_stack; break; + case LOAD_GLOBAL: + { + int j = get_arg(code, i); + if (j & 1) { + next_stack = push_value(next_stack, Null); + } + next_stack = push_value(next_stack, Object); + stacks[i+1] = next_stack; + break; + } + case LOAD_ATTR: + { + assert(top_of_stack(next_stack) == Object); + int j = get_arg(code, i); + if (j & 1) { + next_stack = pop_value(next_stack); + next_stack = push_value(next_stack, Null); + next_stack = push_value(next_stack, Object); + } + stacks[i+1] = next_stack; + break; + } + case CALL: + { + int args = get_arg(code, i); + for (int j = 0; j < args+2; j++) { + next_stack = pop_value(next_stack); + } + next_stack = push_value(next_stack, Object); + stacks[i+1] = next_stack; + break; + } + case SWAP: + { + int n = get_arg(code, i); + next_stack = stack_swap(next_stack, n); + stacks[i+1] = next_stack; + break; + } + case COPY: + { + int n = get_arg(code, i); + next_stack = push_value(next_stack, peek(next_stack, n)); + stacks[i+1] = next_stack; + break; + } default: { - int delta = PyCompile_OpcodeStackEffect(opcode, _Py_OPARG(code[i])); + int delta = PyCompile_OpcodeStackEffect(opcode, get_arg(code, i)); + assert(delta != PY_INVALID_STACK_EFFECT); while (delta < 0) { next_stack = pop_value(next_stack); delta++; @@ -300,21 +469,39 @@ mark_stacks(PyCodeObject *code_obj, int len) } } } + /* Scan exception table */ + unsigned char *start = (unsigned char *)PyBytes_AS_STRING(code_obj->co_exceptiontable); + unsigned char *end = start + PyBytes_GET_SIZE(code_obj->co_exceptiontable); + unsigned char *scan = start; + while (scan < end) { + int start_offset, size, handler; + scan = parse_varint(scan, &start_offset); + assert(start_offset >= 0 && start_offset < len); + scan = parse_varint(scan, &size); + assert(size >= 0 && start_offset+size <= len); + scan = parse_varint(scan, &handler); + assert(handler >= 0 && handler < len); + int depth_and_lasti; + scan = parse_varint(scan, &depth_and_lasti); + int level = depth_and_lasti >> 1; + int lasti = depth_and_lasti & 1; + if (stacks[start_offset] != UNINITIALIZED) { + if (stacks[handler] == UNINITIALIZED) { + todo = 1; + uint64_t target_stack = pop_to_level(stacks[start_offset], level); + if (lasti) { + target_stack = push_value(target_stack, Lasti); + } + target_stack = push_value(target_stack, Except); + stacks[handler] = target_stack; + } + } + } } + Py_DECREF(co_code); return stacks; } -static int -compatible_kind(Kind from, Kind to) { - if (to == 0) { - return 0; - } - if (to == Object) { - return 1; - } - return from == to; -} - static int compatible_stack(int64_t from_stack, int64_t to_stack) { @@ -350,8 +537,11 @@ explain_incompatible_stack(int64_t to_stack) switch(target_kind) { case Except: return "can't jump into an 'except' block as there's no exception"; + case Lasti: + return "can't jump into a re-raising block as there's no location"; case Object: - return "differing stack depth"; + case Null: + return "incompatible stacks"; case Iterator: return "can't jump into the body of a for loop"; default: @@ -365,6 +555,7 @@ marklines(PyCodeObject *code, int len) PyCodeAddressRange bounds; _PyCode_InitAddressRange(code, &bounds); assert (bounds.ar_end == 0); + int last_line = -1; int *linestarts = PyMem_New(int, len); if (linestarts == NULL) { @@ -374,9 +565,12 @@ marklines(PyCodeObject *code, int len) linestarts[i] = -1; } - while (PyLineTable_NextAddressRange(&bounds)) { - assert(bounds.ar_start/(int)sizeof(_Py_CODEUNIT) < len); - linestarts[bounds.ar_start/sizeof(_Py_CODEUNIT)] = bounds.ar_line; + while (_PyLineTable_NextAddressRange(&bounds)) { + assert(bounds.ar_start / (int)sizeof(_Py_CODEUNIT) < len); + if (bounds.ar_line != last_line && bounds.ar_line != -1) { + linestarts[bounds.ar_start / sizeof(_Py_CODEUNIT)] = bounds.ar_line; + last_line = bounds.ar_line; + } } return linestarts; } @@ -396,11 +590,39 @@ first_line_not_before(int *lines, int len, int line) return result; } -static void -frame_stack_pop(PyFrameObject *f) +static PyFrameState +_PyFrame_GetState(PyFrameObject *frame) { - PyObject *v = _PyFrame_StackPop(f->f_frame); - Py_DECREF(v); + assert(!_PyFrame_IsIncomplete(frame->f_frame)); + if (frame->f_frame->stacktop == 0) { + return FRAME_CLEARED; + } + switch(frame->f_frame->owner) { + case FRAME_OWNED_BY_GENERATOR: + { + PyGenObject *gen = _PyFrame_GetGenerator(frame->f_frame); + return gen->gi_frame_state; + } + case FRAME_OWNED_BY_THREAD: + { + if (_PyInterpreterFrame_LASTI(frame->f_frame) < 0) { + return FRAME_CREATED; + } + switch (_Py_OPCODE(*frame->f_frame->prev_instr)) + { + case COPY_FREE_VARS: + case MAKE_CELL: + case RETURN_GENERATOR: + /* Frame not fully initialized */ + return FRAME_CREATED; + default: + return FRAME_EXECUTING; + } + } + case FRAME_OWNED_BY_FRAME_OBJECT: + return FRAME_COMPLETED; + } + Py_UNREACHABLE(); } /* Setter for f_lineno - you can set f_lineno from within a trace function in @@ -431,6 +653,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore return -1; } + PyFrameState state = _PyFrame_GetState(f); /* * This code preserves the historical restrictions on * setting the line number of a frame. @@ -439,28 +662,31 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore * In addition, jumps are forbidden when not tracing, * as this is a debugging feature. */ - switch(f->f_frame->f_state) { - case FRAME_CREATED: - PyErr_Format(PyExc_ValueError, - "can't jump from the 'call' trace event of a new frame"); - return -1; - case FRAME_RETURNED: - case FRAME_UNWINDING: - case FRAME_RAISED: - case FRAME_CLEARED: + switch(PyThreadState_GET()->tracing_what) { + case PyTrace_EXCEPTION: PyErr_SetString(PyExc_ValueError, "can only jump from a 'line' trace event"); return -1; - case FRAME_EXECUTING: - case FRAME_SUSPENDED: - /* You can only do this from within a trace function, not via - * _getframe or similar hackery. */ - if (!f->f_trace) { - PyErr_Format(PyExc_ValueError, - "f_lineno can only be set by a trace function"); - return -1; - } + case PyTrace_CALL: + PyErr_Format(PyExc_ValueError, + "can't jump from the 'call' trace event of a new frame"); + return -1; + case PyTrace_LINE: break; + case PyTrace_RETURN: + if (state == FRAME_SUSPENDED) { + break; + } + /* fall through */ + default: + PyErr_SetString(PyExc_ValueError, + "can only jump from a 'line' trace event"); + return -1; + } + if (!f->f_trace) { + PyErr_Format(PyExc_ValueError, + "f_lineno can only be set by a trace function"); + return -1; } int new_lineno; @@ -490,7 +716,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore /* PyCode_NewWithPosOnlyArgs limits co_code to be under INT_MAX so this * should never overflow. */ - int len = (int)(PyBytes_GET_SIZE(f->f_frame->f_code->co_code) / sizeof(_Py_CODEUNIT)); + int len = (int)Py_SIZE(f->f_frame->f_code); int *lines = marklines(f->f_frame->f_code, len); if (lines == NULL) { return -1; @@ -513,7 +739,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore int64_t best_stack = OVERFLOWED; int best_addr = -1; - int64_t start_stack = stacks[f->f_frame->f_lasti]; + int64_t start_stack = stacks[_PyInterpreterFrame_LASTI(f->f_frame)]; int err = -1; const char *msg = "cannot find bytecode for specified line"; for (int i = 0; i < len; i++) { @@ -531,7 +757,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore msg = "stack to deep to analyze"; } else if (start_stack == UNINITIALIZED) { - msg = "can't jump from within an exception handler"; + msg = "can't jump from unreachable code"; } else { msg = explain_incompatible_stack(target_stack); @@ -546,18 +772,55 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore PyErr_SetString(PyExc_ValueError, msg); return -1; } - /* Unwind block stack. */ - if (f->f_frame->f_state == FRAME_SUSPENDED) { + // Populate any NULL locals that the compiler might have "proven" to exist + // in the new location. Rather than crashing or changing co_code, just bind + // None instead: + int unbound = 0; + for (int i = 0; i < f->f_frame->f_code->co_nlocalsplus; i++) { + // Counting every unbound local is overly-cautious, but a full flow + // analysis (like we do in the compiler) is probably too expensive: + unbound += f->f_frame->localsplus[i] == NULL; + } + if (unbound) { + const char *e = "assigning None to %d unbound local%s"; + const char *s = (unbound == 1) ? "" : "s"; + if (PyErr_WarnFormat(PyExc_RuntimeWarning, 0, e, unbound, s)) { + return -1; + } + // Do this in a second pass to avoid writing a bunch of Nones when + // warnings are being treated as errors and the previous bit raises: + for (int i = 0; i < f->f_frame->f_code->co_nlocalsplus; i++) { + if (f->f_frame->localsplus[i] == NULL) { + f->f_frame->localsplus[i] = Py_NewRef(Py_None); + unbound--; + } + } + assert(unbound == 0); + } + if (state == FRAME_SUSPENDED) { /* Account for value popped by yield */ start_stack = pop_value(start_stack); } while (start_stack > best_stack) { - frame_stack_pop(f); + if (top_of_stack(start_stack) == Except) { + /* Pop exception stack as well as the evaluation stack */ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_StackItem *exc_info = tstate->exc_info; + PyObject *value = exc_info->exc_value; + PyObject *exc = _PyFrame_StackPop(f->f_frame); + assert(PyExceptionInstance_Check(exc) || exc == Py_None); + exc_info->exc_value = exc; + Py_XDECREF(value); + } + else { + PyObject *v = _PyFrame_StackPop(f->f_frame); + Py_XDECREF(v); + } start_stack = pop_value(start_stack); } /* Finally set the new lasti and return OK. */ f->f_lineno = 0; - f->f_frame->f_lasti = best_addr; + f->f_frame->prev_instr = _PyCode_CODE(f->f_frame->f_code) + best_addr; return 0; } @@ -565,13 +828,9 @@ static PyObject * frame_gettrace(PyFrameObject *f, void *closure) { PyObject* trace = f->f_trace; - if (trace == NULL) trace = Py_None; - - Py_INCREF(trace); - - return trace; + return Py_NewRef(trace); } static int @@ -580,9 +839,7 @@ frame_settrace(PyFrameObject *f, PyObject* v, void *closure) if (v == Py_None) { v = NULL; } - Py_XINCREF(v); - Py_XSETREF(f->f_trace, v); - + Py_XSETREF(f->f_trace, Py_XNewRef(v)); return 0; } @@ -600,18 +857,15 @@ static PyGetSetDef frame_getsetlist[] = { {0} }; -/* Stack frames are allocated and deallocated at a considerable rate. - In an attempt to improve the speed of function calls, we maintain - a separate free list of stack frames (just like floats are - allocated in a special way -- see floatobject.c). When a stack - frame is on the free list, only the following members have a meaning: - ob_type == &Frametype - f_back next item on free list, or NULL -*/ - -static void _Py_HOT_FUNCTION +static void frame_dealloc(PyFrameObject *f) { + /* It is the responsibility of the owning generator/coroutine + * to have cleared the generator pointer */ + + assert(f->f_frame->owner != FRAME_OWNED_BY_GENERATOR || + _PyFrame_GetGenerator(f->f_frame)->gi_frame_state == FRAME_CLEARED); + if (_PyObject_GC_IS_TRACKED(f)) { _PyObject_GC_UNTRACK(f); } @@ -620,40 +874,22 @@ frame_dealloc(PyFrameObject *f) PyCodeObject *co = NULL; /* Kill all local variables including specials, if we own them */ - if (f->f_own_locals_memory) { - f->f_own_locals_memory = 0; - InterpreterFrame *frame = f->f_frame; + if (f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT) { + assert(f->f_frame == (_PyInterpreterFrame *)f->_f_frame_data); + _PyInterpreterFrame *frame = (_PyInterpreterFrame *)f->_f_frame_data; /* Don't clear code object until the end */ co = frame->f_code; frame->f_code = NULL; - Py_CLEAR(frame->f_globals); - Py_CLEAR(frame->f_builtins); + Py_CLEAR(frame->f_funcobj); Py_CLEAR(frame->f_locals); PyObject **locals = _PyFrame_GetLocalsArray(frame); for (int i = 0; i < frame->stacktop; i++) { Py_CLEAR(locals[i]); } - PyMem_Free(frame); } Py_CLEAR(f->f_back); Py_CLEAR(f->f_trace); -#if PyFrame_MAXFREELIST > 0 - struct _Py_frame_state *state = get_frame_state(); -#ifdef Py_DEBUG - // frame_dealloc() must not be called after _PyFrame_Fini() - assert(state->numfree != -1); -#endif - if (state->numfree < PyFrame_MAXFREELIST) { - ++state->numfree; - f->f_back = state->free_list; - state->free_list = f; - } - else -#endif - { - PyObject_GC_Del(f); - } - + PyObject_GC_Del(f); Py_XDECREF(co); Py_TRASHCAN_END; } @@ -663,7 +899,7 @@ frame_traverse(PyFrameObject *f, visitproc visit, void *arg) { Py_VISIT(f->f_back); Py_VISIT(f->f_trace); - if (f->f_own_locals_memory == 0) { + if (f->f_frame->owner != FRAME_OWNED_BY_FRAME_OBJECT) { return 0; } assert(f->f_frame->frame_obj == NULL); @@ -673,13 +909,6 @@ frame_traverse(PyFrameObject *f, visitproc visit, void *arg) static int frame_tp_clear(PyFrameObject *f) { - /* Before anything else, make sure that this frame is clearly marked - * as being defunct! Else, e.g., a generator reachable from this - * frame may also point to this frame, believe itself to still be - * active, and try cleaning up this frame again. - */ - f->f_frame->f_state = FRAME_CLEARED; - Py_CLEAR(f->f_trace); /* locals and stack */ @@ -695,17 +924,25 @@ frame_tp_clear(PyFrameObject *f) static PyObject * frame_clear(PyFrameObject *f, PyObject *Py_UNUSED(ignored)) { - if (_PyFrame_IsExecuting(f->f_frame)) { - PyErr_SetString(PyExc_RuntimeError, - "cannot clear an executing frame"); - return NULL; + if (f->f_frame->owner == FRAME_OWNED_BY_GENERATOR) { + PyGenObject *gen = _PyFrame_GetGenerator(f->f_frame); + if (gen->gi_frame_state == FRAME_EXECUTING) { + goto running; + } + _PyGen_Finalize((PyObject *)gen); } - if (f->f_frame->generator) { - _PyGen_Finalize(f->f_frame->generator); - assert(f->f_frame->generator == NULL); + else if (f->f_frame->owner == FRAME_OWNED_BY_THREAD) { + goto running; + } + else { + assert(f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT); + (void)frame_tp_clear(f); } - (void)frame_tp_clear(f); Py_RETURN_NONE; +running: + PyErr_SetString(PyExc_RuntimeError, + "cannot clear an executing frame"); + return NULL; } PyDoc_STRVAR(clear__doc__, @@ -715,11 +952,9 @@ static PyObject * frame_sizeof(PyFrameObject *f, PyObject *Py_UNUSED(ignored)) { Py_ssize_t res; - res = sizeof(PyFrameObject); - if (f->f_own_locals_memory) { - PyCodeObject *code = f->f_frame->f_code; - res += (code->co_nlocalsplus+code->co_stacksize) * sizeof(PyObject *); - } + res = offsetof(PyFrameObject, _f_frame_data) + offsetof(_PyInterpreterFrame, localsplus); + PyCodeObject *code = f->f_frame->f_code; + res += _PyFrame_NumSlotsForCodeObject(code) * sizeof(PyObject *); return PyLong_FromSsize_t(res); } @@ -747,7 +982,8 @@ static PyMethodDef frame_methods[] = { PyTypeObject PyFrame_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "frame", - sizeof(PyFrameObject), + offsetof(PyFrameObject, _f_frame_data) + + offsetof(_PyInterpreterFrame, localsplus), sizeof(PyObject *), (destructor)frame_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ @@ -779,69 +1015,21 @@ PyTypeObject PyFrame_Type = { 0, /* tp_dict */ }; -_Py_IDENTIFIER(__builtins__); - -static InterpreterFrame * -allocate_heap_frame(PyFrameConstructor *con, PyObject *locals) +static void +init_frame(_PyInterpreterFrame *frame, PyFunctionObject *func, PyObject *locals) { - PyCodeObject *code = (PyCodeObject *)con->fc_code; - int size = code->co_nlocalsplus+code->co_stacksize + FRAME_SPECIALS_SIZE; - InterpreterFrame *frame = (InterpreterFrame *)PyMem_Malloc(sizeof(PyObject *)*size); - if (frame == NULL) { - PyErr_NoMemory(); - return NULL; - } - _PyFrame_InitializeSpecials(frame, con, locals, code->co_nlocalsplus); - for (Py_ssize_t i = 0; i < code->co_nlocalsplus; i++) { - frame->localsplus[i] = NULL; - } - return frame; + PyCodeObject *code = (PyCodeObject *)func->func_code; + _PyFrame_Initialize(frame, (PyFunctionObject*)Py_NewRef(func), + Py_XNewRef(locals), code, 0); + frame->previous = NULL; } -static inline PyFrameObject* -frame_alloc(InterpreterFrame *frame, int owns) +PyFrameObject* +_PyFrame_New_NoTrack(PyCodeObject *code) { - PyFrameObject *f; -#if PyFrame_MAXFREELIST > 0 - struct _Py_frame_state *state = get_frame_state(); - if (state->free_list == NULL) -#endif - { - f = PyObject_GC_New(PyFrameObject, &PyFrame_Type); - if (f == NULL) { - if (owns) { - Py_XDECREF(frame->f_code); - Py_XDECREF(frame->f_builtins); - Py_XDECREF(frame->f_globals); - Py_XDECREF(frame->f_locals); - PyMem_Free(frame); - } - return NULL; - } - } -#if PyFrame_MAXFREELIST > 0 - else - { -#ifdef Py_DEBUG - // frame_alloc() must not be called after _PyFrame_Fini() - assert(state->numfree != -1); -#endif - assert(state->numfree > 0); - --state->numfree; - f = state->free_list; - state->free_list = state->free_list->f_back; - _Py_NewReference((PyObject *)f); - } -#endif - f->f_frame = frame; - f->f_own_locals_memory = owns; - return f; -} - -PyFrameObject* _Py_HOT_FUNCTION -_PyFrame_New_NoTrack(InterpreterFrame *frame, int owns) -{ - PyFrameObject *f = frame_alloc(frame, owns); + CALL_STAT_INC(frame_objects_created); + int slots = code->co_nlocalsplus + code->co_stacksize; + PyFrameObject *f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type, slots); if (f == NULL) { return NULL; } @@ -849,6 +1037,7 @@ _PyFrame_New_NoTrack(InterpreterFrame *frame, int owns) f->f_trace = NULL; f->f_trace_lines = 1; f->f_trace_opcodes = 0; + f->f_fast_as_locals = 0; f->f_lineno = 0; return f; } @@ -872,89 +1061,151 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, .fc_kwdefaults = NULL, .fc_closure = NULL }; - InterpreterFrame *frame = allocate_heap_frame(&desc, locals); - if (frame == NULL) { + PyFunctionObject *func = _PyFunction_FromConstructor(&desc); + if (func == NULL) { return NULL; } - PyFrameObject *f = _PyFrame_New_NoTrack(frame, 1); - if (f) { - _PyObject_GC_TRACK(f); + PyFrameObject *f = _PyFrame_New_NoTrack(code); + if (f == NULL) { + Py_DECREF(func); + return NULL; } + init_frame((_PyInterpreterFrame *)f->_f_frame_data, func, locals); + f->f_frame = (_PyInterpreterFrame *)f->_f_frame_data; + f->f_frame->owner = FRAME_OWNED_BY_FRAME_OBJECT; + // This frame needs to be "complete", so pretend that the first RESUME ran: + f->f_frame->prev_instr = _PyCode_CODE(code) + code->_co_firsttraceable; + assert(!_PyFrame_IsIncomplete(f->f_frame)); + Py_DECREF(func); + _PyObject_GC_TRACK(f); return f; } static int -_PyFrame_OpAlreadyRan(InterpreterFrame *frame, int opcode, int oparg) +_PyFrame_OpAlreadyRan(_PyInterpreterFrame *frame, int opcode, int oparg) { - const _Py_CODEUNIT *code = - (const _Py_CODEUNIT *)PyBytes_AS_STRING(frame->f_code->co_code); - for (int i = 0; i < frame->f_lasti; i++) { - if (_Py_OPCODE(code[i]) == opcode && _Py_OPARG(code[i]) == oparg) { + // This only works when opcode is a non-quickened form: + assert(_PyOpcode_Deopt[opcode] == opcode); + int check_oparg = 0; + for (_Py_CODEUNIT *instruction = _PyCode_CODE(frame->f_code); + instruction < frame->prev_instr; instruction++) + { + int check_opcode = _PyOpcode_Deopt[_Py_OPCODE(*instruction)]; + check_oparg |= _Py_OPARG(*instruction); + if (check_opcode == opcode && check_oparg == oparg) { return 1; } + if (check_opcode == EXTENDED_ARG) { + check_oparg <<= 8; + } + else { + check_oparg = 0; + } + instruction += _PyOpcode_Caches[check_opcode]; } return 0; } + +// Initialize frame free variables if needed +static void +frame_init_get_vars(_PyInterpreterFrame *frame) +{ + // COPY_FREE_VARS has no quickened forms, so no need to use _PyOpcode_Deopt + // here: + PyCodeObject *co = frame->f_code; + int lasti = _PyInterpreterFrame_LASTI(frame); + if (!(lasti < 0 && _Py_OPCODE(_PyCode_CODE(co)[0]) == COPY_FREE_VARS + && PyFunction_Check(frame->f_funcobj))) + { + /* Free vars are initialized */ + return; + } + + /* Free vars have not been initialized -- Do that */ + PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure; + int offset = PyCode_GetFirstFree(co); + for (int i = 0; i < co->co_nfreevars; ++i) { + PyObject *o = PyTuple_GET_ITEM(closure, i); + frame->localsplus[offset + i] = Py_NewRef(o); + } + // COPY_FREE_VARS doesn't have inline CACHEs, either: + frame->prev_instr = _PyCode_CODE(frame->f_code); +} + + +static int +frame_get_var(_PyInterpreterFrame *frame, PyCodeObject *co, int i, + PyObject **pvalue) +{ + _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i); + + /* If the namespace is unoptimized, then one of the + following cases applies: + 1. It does not contain free variables, because it + uses import * or is a top-level namespace. + 2. It is a class namespace. + We don't want to accidentally copy free variables + into the locals dict used by the class. + */ + if (kind & CO_FAST_FREE && !(co->co_flags & CO_OPTIMIZED)) { + return 0; + } + + PyObject *value = frame->localsplus[i]; + if (frame->stacktop) { + if (kind & CO_FAST_FREE) { + // The cell was set by COPY_FREE_VARS. + assert(value != NULL && PyCell_Check(value)); + value = PyCell_GET(value); + } + else if (kind & CO_FAST_CELL) { + // Note that no *_DEREF ops can happen before MAKE_CELL + // executes. So there's no need to duplicate the work + // that MAKE_CELL would otherwise do later, if it hasn't + // run yet. + if (value != NULL) { + if (PyCell_Check(value) && + _PyFrame_OpAlreadyRan(frame, MAKE_CELL, i)) { + // (likely) MAKE_CELL must have executed already. + value = PyCell_GET(value); + } + // (likely) Otherwise it it is an arg (kind & CO_FAST_LOCAL), + // with the initial value set when the frame was created... + // (unlikely) ...or it was set to some initial value by + // an earlier call to PyFrame_LocalsToFast(). + } + } + } + else { + assert(value == NULL); + } + *pvalue = value; + return 1; +} + int -_PyFrame_FastToLocalsWithError(InterpreterFrame *frame) { +_PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame) +{ /* Merge fast locals into f->f_locals */ - PyObject *locals; - PyObject **fast; - PyCodeObject *co; - locals = frame->f_locals; + PyObject *locals = frame->f_locals; if (locals == NULL) { locals = frame->f_locals = PyDict_New(); - if (locals == NULL) + if (locals == NULL) { return -1; + } } - co = frame->f_code; - fast = _PyFrame_GetLocalsArray(frame); - for (int i = 0; i < co->co_nlocalsplus; i++) { - _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i); - /* If the namespace is unoptimized, then one of the - following cases applies: - 1. It does not contain free variables, because it - uses import * or is a top-level namespace. - 2. It is a class namespace. - We don't want to accidentally copy free variables - into the locals dict used by the class. - */ - if (kind & CO_FAST_FREE && !(co->co_flags & CO_OPTIMIZED)) { + frame_init_get_vars(frame); + + PyCodeObject *co = frame->f_code; + for (int i = 0; i < co->co_nlocalsplus; i++) { + PyObject *value; // borrowed reference + if (!frame_get_var(frame, co, i, &value)) { continue; } PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i); - PyObject *value = fast[i]; - if (frame->f_state != FRAME_CLEARED) { - if (kind & CO_FAST_FREE) { - // The cell was set when the frame was created from - // the function's closure. - assert(value != NULL && PyCell_Check(value)); - value = PyCell_GET(value); - } - else if (kind & CO_FAST_CELL) { - // Note that no *_DEREF ops can happen before MAKE_CELL - // executes. So there's no need to duplicate the work - // that MAKE_CELL would otherwise do later, if it hasn't - // run yet. - if (value != NULL) { - if (PyCell_Check(value) && - _PyFrame_OpAlreadyRan(frame, MAKE_CELL, i)) { - // (likely) MAKE_CELL must have executed already. - value = PyCell_GET(value); - } - // (likely) Otherwise it it is an arg (kind & CO_FAST_LOCAL), - // with the initial value set when the frame was created... - // (unlikely) ...or it was set to some initial value by - // an earlier call to PyFrame_LocalsToFast(). - } - } - } - else { - assert(value == NULL); - } if (value == NULL) { if (PyObject_DelItem(locals, name) != 0) { if (PyErr_ExceptionMatches(PyExc_KeyError)) { @@ -974,21 +1225,74 @@ _PyFrame_FastToLocalsWithError(InterpreterFrame *frame) { return 0; } + +PyObject * +PyFrame_GetVar(PyFrameObject *frame_obj, PyObject *name) +{ + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, "name must be str, not %s", + Py_TYPE(name)->tp_name); + return NULL; + } + + _PyInterpreterFrame *frame = frame_obj->f_frame; + frame_init_get_vars(frame); + + PyCodeObject *co = frame->f_code; + for (int i = 0; i < co->co_nlocalsplus; i++) { + PyObject *var_name = PyTuple_GET_ITEM(co->co_localsplusnames, i); + if (!_PyUnicode_Equal(var_name, name)) { + continue; + } + + PyObject *value; // borrowed reference + if (!frame_get_var(frame, co, i, &value)) { + break; + } + if (value == NULL) { + break; + } + return Py_NewRef(value); + } + + PyErr_Format(PyExc_NameError, "variable %R does not exist", name); + return NULL; +} + + +PyObject * +PyFrame_GetVarString(PyFrameObject *frame, const char *name) +{ + PyObject *name_obj = PyUnicode_FromString(name); + if (name_obj == NULL) { + return NULL; + } + PyObject *value = PyFrame_GetVar(frame, name_obj); + Py_DECREF(name_obj); + return value; +} + + int PyFrame_FastToLocalsWithError(PyFrameObject *f) { + assert(!_PyFrame_IsIncomplete(f->f_frame)); if (f == NULL) { PyErr_BadInternalCall(); return -1; } - return _PyFrame_FastToLocalsWithError(f->f_frame); + int err = _PyFrame_FastToLocalsWithError(f->f_frame); + if (err == 0) { + f->f_fast_as_locals = 1; + } + return err; } void PyFrame_FastToLocals(PyFrameObject *f) { int res; - + assert(!_PyFrame_IsIncomplete(f->f_frame)); assert(!PyErr_Occurred()); res = PyFrame_FastToLocalsWithError(f); @@ -997,7 +1301,7 @@ PyFrame_FastToLocals(PyFrameObject *f) } void -_PyFrame_LocalsToFast(InterpreterFrame *frame, int clear) +_PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear) { /* Merge locals into fast locals */ PyObject *locals; @@ -1005,8 +1309,9 @@ _PyFrame_LocalsToFast(InterpreterFrame *frame, int clear) PyObject *error_type, *error_value, *error_traceback; PyCodeObject *co; locals = frame->f_locals; - if (locals == NULL) + if (locals == NULL) { return; + } fast = _PyFrame_GetLocalsArray(frame); co = frame->f_code; @@ -1048,14 +1353,22 @@ _PyFrame_LocalsToFast(InterpreterFrame *frame, int clear) if (cell != NULL) { oldvalue = PyCell_GET(cell); if (value != oldvalue) { + PyCell_SET(cell, Py_XNewRef(value)); Py_XDECREF(oldvalue); - Py_XINCREF(value); - PyCell_SET(cell, value); } } else if (value != oldvalue) { - Py_XINCREF(value); - Py_XSETREF(fast[i], value); + if (value == NULL) { + // Probably can't delete this, since the compiler's flow + // analysis may have already "proven" that it exists here: + const char *e = "assigning None to unbound local %R"; + if (PyErr_WarnFormat(PyExc_RuntimeWarning, 0, e, name)) { + // It's okay if frame_obj is NULL, just try anyways: + PyErr_WriteUnraisable((PyObject *)frame->frame_obj); + } + value = Py_NewRef(Py_None); + } + Py_XSETREF(fast[i], Py_NewRef(value)); } Py_XDECREF(value); } @@ -1065,59 +1378,30 @@ _PyFrame_LocalsToFast(InterpreterFrame *frame, int clear) void PyFrame_LocalsToFast(PyFrameObject *f, int clear) { - if (f == NULL || f->f_frame->f_state == FRAME_CLEARED) { - return; + assert(!_PyFrame_IsIncomplete(f->f_frame)); + if (f && f->f_fast_as_locals && _PyFrame_GetState(f) != FRAME_CLEARED) { + _PyFrame_LocalsToFast(f->f_frame, clear); + f->f_fast_as_locals = 0; } - _PyFrame_LocalsToFast(f->f_frame, clear); } -/* Clear out the free list */ -void -_PyFrame_ClearFreeList(PyInterpreterState *interp) +int +_PyFrame_IsEntryFrame(PyFrameObject *frame) { -#if PyFrame_MAXFREELIST > 0 - struct _Py_frame_state *state = &interp->frame; - while (state->free_list != NULL) { - PyFrameObject *f = state->free_list; - state->free_list = state->free_list->f_back; - PyObject_GC_Del(f); - --state->numfree; - } - assert(state->numfree == 0); -#endif + assert(frame != NULL); + _PyInterpreterFrame *f = frame->f_frame; + assert(!_PyFrame_IsIncomplete(f)); + return f->previous && f->previous->owner == FRAME_OWNED_BY_CSTACK; } -void -_PyFrame_Fini(PyInterpreterState *interp) -{ - _PyFrame_ClearFreeList(interp); -#if defined(Py_DEBUG) && PyFrame_MAXFREELIST > 0 - struct _Py_frame_state *state = &interp->frame; - state->numfree = -1; -#endif -} - -/* Print summary info about the state of the optimized allocator */ -void -_PyFrame_DebugMallocStats(FILE *out) -{ -#if PyFrame_MAXFREELIST > 0 - struct _Py_frame_state *state = get_frame_state(); - _PyDebugAllocatorStats(out, - "free PyFrameObject", - state->numfree, sizeof(PyFrameObject)); -#endif -} - - PyCodeObject * PyFrame_GetCode(PyFrameObject *frame) { assert(frame != NULL); + assert(!_PyFrame_IsIncomplete(frame->f_frame)); PyCodeObject *code = frame->f_frame->f_code; assert(code != NULL); - Py_INCREF(code); - return code; + return (PyCodeObject*)Py_NewRef(code); } @@ -1125,18 +1409,65 @@ PyFrameObject* PyFrame_GetBack(PyFrameObject *frame) { assert(frame != NULL); + assert(!_PyFrame_IsIncomplete(frame->f_frame)); PyFrameObject *back = frame->f_back; - if (back == NULL && frame->f_frame->previous != NULL) { - back = _PyFrame_GetFrameObject(frame->f_frame->previous); + if (back == NULL) { + _PyInterpreterFrame *prev = frame->f_frame->previous; + prev = _PyFrame_GetFirstComplete(prev); + if (prev) { + back = _PyFrame_GetFrameObject(prev); + } } - Py_XINCREF(back); - return back; + return (PyFrameObject*)Py_XNewRef(back); +} + +PyObject* +PyFrame_GetLocals(PyFrameObject *frame) +{ + assert(!_PyFrame_IsIncomplete(frame->f_frame)); + return frame_getlocals(frame, NULL); +} + +PyObject* +PyFrame_GetGlobals(PyFrameObject *frame) +{ + assert(!_PyFrame_IsIncomplete(frame->f_frame)); + return frame_getglobals(frame, NULL); +} + +PyObject* +PyFrame_GetBuiltins(PyFrameObject *frame) +{ + assert(!_PyFrame_IsIncomplete(frame->f_frame)); + return frame_getbuiltins(frame, NULL); +} + +int +PyFrame_GetLasti(PyFrameObject *frame) +{ + assert(!_PyFrame_IsIncomplete(frame->f_frame)); + int lasti = _PyInterpreterFrame_LASTI(frame->f_frame); + if (lasti < 0) { + return -1; + } + return lasti * sizeof(_Py_CODEUNIT); +} + +PyObject * +PyFrame_GetGenerator(PyFrameObject *frame) +{ + assert(!_PyFrame_IsIncomplete(frame->f_frame)); + if (frame->f_frame->owner != FRAME_OWNED_BY_GENERATOR) { + return NULL; + } + PyGenObject *gen = _PyFrame_GetGenerator(frame->f_frame); + return Py_NewRef(gen); } PyObject* _PyEval_BuiltinsFromGlobals(PyThreadState *tstate, PyObject *globals) { - PyObject *builtins = _PyDict_GetItemIdWithError(globals, &PyId___builtins__); + PyObject *builtins = PyDict_GetItemWithError(globals, &_Py_ID(__builtins__)); if (builtins) { if (PyModule_Check(builtins)) { builtins = _PyModule_GetDict(builtins); diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 5a170380cb3..baa360381a7 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -3,11 +3,107 @@ #include "Python.h" #include "pycore_ceval.h" // _PyEval_BuiltinsFromGlobals() +#include "pycore_code.h" // _Py_next_func_version #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "structmember.h" // PyMemberDef -static uint32_t next_func_version = 1; +static void +notify_func_watchers(PyInterpreterState *interp, PyFunction_WatchEvent event, + PyFunctionObject *func, PyObject *new_value) +{ + uint8_t bits = interp->active_func_watchers; + int i = 0; + while (bits) { + assert(i < FUNC_MAX_WATCHERS); + if (bits & 1) { + PyFunction_WatchCallback cb = interp->func_watchers[i]; + // callback must be non-null if the watcher bit is set + assert(cb != NULL); + if (cb(event, func, new_value) < 0) { + PyErr_WriteUnraisable((PyObject *) func); + } + } + i++; + bits >>= 1; + } +} + +static inline void +handle_func_event(PyFunction_WatchEvent event, PyFunctionObject *func, + PyObject *new_value) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(interp->_initialized); + if (interp->active_func_watchers) { + notify_func_watchers(interp, event, func, new_value); + } +} + +int +PyFunction_AddWatcher(PyFunction_WatchCallback callback) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(interp->_initialized); + for (int i = 0; i < FUNC_MAX_WATCHERS; i++) { + if (interp->func_watchers[i] == NULL) { + interp->func_watchers[i] = callback; + interp->active_func_watchers |= (1 << i); + return i; + } + } + PyErr_SetString(PyExc_RuntimeError, "no more func watcher IDs available"); + return -1; +} + +int +PyFunction_ClearWatcher(int watcher_id) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (watcher_id < 0 || watcher_id >= FUNC_MAX_WATCHERS) { + PyErr_Format(PyExc_ValueError, "invalid func watcher ID %d", + watcher_id); + return -1; + } + if (!interp->func_watchers[watcher_id]) { + PyErr_Format(PyExc_ValueError, "no func watcher set for ID %d", + watcher_id); + return -1; + } + interp->func_watchers[watcher_id] = NULL; + interp->active_func_watchers &= ~(1 << watcher_id); + return 0; +} +PyFunctionObject * +_PyFunction_FromConstructor(PyFrameConstructor *constr) +{ + + PyFunctionObject *op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type); + if (op == NULL) { + return NULL; + } + op->func_globals = Py_NewRef(constr->fc_globals); + op->func_builtins = Py_NewRef(constr->fc_builtins); + op->func_name = Py_NewRef(constr->fc_name); + op->func_qualname = Py_NewRef(constr->fc_qualname); + op->func_code = Py_NewRef(constr->fc_code); + op->func_defaults = NULL; + op->func_kwdefaults = NULL; + op->func_closure = Py_XNewRef(constr->fc_closure); + op->func_doc = Py_NewRef(Py_None); + op->func_dict = NULL; + op->func_weakreflist = NULL; + op->func_module = Py_XNewRef(PyDict_GetItem(op->func_globals, &_Py_ID(__name__))); + if (!op->func_module) { + PyErr_Clear(); + } + op->func_annotations = NULL; + op->vectorcall = _PyFunction_Vectorcall; + op->func_version = 0; + _PyObject_GC_TRACK(op); + handle_func_event(PyFunction_EVENT_CREATE, op, NULL); + return op; +} PyObject * PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname) @@ -18,12 +114,10 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname PyThreadState *tstate = _PyThreadState_GET(); - PyCodeObject *code_obj = (PyCodeObject *)code; - Py_INCREF(code_obj); + PyCodeObject *code_obj = (PyCodeObject *)Py_NewRef(code); - PyObject *name = code_obj->co_name; - assert(name != NULL); - Py_INCREF(name); + assert(code_obj->co_name != NULL); + PyObject *name = Py_NewRef(code_obj->co_name); if (!qualname) { qualname = code_obj->co_qualname; @@ -46,8 +140,7 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname Py_INCREF(doc); // __module__: Use globals['__name__'] if it exists, or NULL. - _Py_IDENTIFIER(__name__); - PyObject *module = _PyDict_GetItemIdWithError(globals, &PyId___name__); + PyObject *module = PyDict_GetItemWithError(globals, &_Py_ID(__name__)); PyObject *builtins = NULL; if (module == NULL && _PyErr_Occurred(tstate)) { goto error; @@ -83,6 +176,7 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname op->vectorcall = _PyFunction_Vectorcall; op->func_version = 0; _PyObject_GC_TRACK(op); + handle_func_event(PyFunction_EVENT_CREATE, op, NULL); return (PyObject *)op; error: @@ -101,10 +195,13 @@ uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func) if (func->func_version != 0) { return func->func_version; } - if (next_func_version == 0) { + if (func->vectorcall != _PyFunction_Vectorcall) { return 0; } - uint32_t v = next_func_version++; + if (_PyRuntime.func_state.next_version == 0) { + return 0; + } + uint32_t v = _PyRuntime.func_state.next_version++; func->func_version = v; return v; } @@ -171,11 +268,21 @@ PyFunction_SetDefaults(PyObject *op, PyObject *defaults) PyErr_SetString(PyExc_SystemError, "non-tuple default args"); return -1; } + handle_func_event(PyFunction_EVENT_MODIFY_DEFAULTS, + (PyFunctionObject *) op, defaults); ((PyFunctionObject *)op)->func_version = 0; Py_XSETREF(((PyFunctionObject *)op)->func_defaults, defaults); return 0; } +void +PyFunction_SetVectorcall(PyFunctionObject *func, vectorcallfunc vectorcall) +{ + assert(func != NULL); + func->func_version = 0; + func->vectorcall = vectorcall; +} + PyObject * PyFunction_GetKwDefaults(PyObject *op) { @@ -203,6 +310,8 @@ PyFunction_SetKwDefaults(PyObject *op, PyObject *defaults) "non-dict keyword only default args"); return -1; } + handle_func_event(PyFunction_EVENT_MODIFY_KWDEFAULTS, + (PyFunctionObject *) op, defaults); ((PyFunctionObject *)op)->func_version = 0; Py_XSETREF(((PyFunctionObject *)op)->func_kwdefaults, defaults); return 0; @@ -241,6 +350,36 @@ PyFunction_SetClosure(PyObject *op, PyObject *closure) return 0; } +static PyObject * +func_get_annotation_dict(PyFunctionObject *op) +{ + if (op->func_annotations == NULL) { + return NULL; + } + if (PyTuple_CheckExact(op->func_annotations)) { + PyObject *ann_tuple = op->func_annotations; + PyObject *ann_dict = PyDict_New(); + if (ann_dict == NULL) { + return NULL; + } + + assert(PyTuple_GET_SIZE(ann_tuple) % 2 == 0); + + for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(ann_tuple); i += 2) { + int err = PyDict_SetItem(ann_dict, + PyTuple_GET_ITEM(ann_tuple, i), + PyTuple_GET_ITEM(ann_tuple, i + 1)); + + if (err < 0) { + return NULL; + } + } + Py_SETREF(op->func_annotations, ann_dict); + } + assert(PyDict_Check(op->func_annotations)); + return op->func_annotations; +} + PyObject * PyFunction_GetAnnotations(PyObject *op) { @@ -248,7 +387,7 @@ PyFunction_GetAnnotations(PyObject *op) PyErr_BadInternalCall(); return NULL; } - return ((PyFunctionObject *) op) -> func_annotations; + return func_get_annotation_dict((PyFunctionObject *)op); } int @@ -293,8 +432,7 @@ func_get_code(PyFunctionObject *op, void *Py_UNUSED(ignored)) return NULL; } - Py_INCREF(op->func_code); - return op->func_code; + return Py_NewRef(op->func_code); } static int @@ -327,17 +465,16 @@ func_set_code(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) nclosure, nfree); return -1; } + handle_func_event(PyFunction_EVENT_MODIFY_CODE, op, value); op->func_version = 0; - Py_INCREF(value); - Py_XSETREF(op->func_code, value); + Py_XSETREF(op->func_code, Py_NewRef(value)); return 0; } static PyObject * func_get_name(PyFunctionObject *op, void *Py_UNUSED(ignored)) { - Py_INCREF(op->func_name); - return op->func_name; + return Py_NewRef(op->func_name); } static int @@ -350,16 +487,14 @@ func_set_name(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) "__name__ must be set to a string object"); return -1; } - Py_INCREF(value); - Py_XSETREF(op->func_name, value); + Py_XSETREF(op->func_name, Py_NewRef(value)); return 0; } static PyObject * func_get_qualname(PyFunctionObject *op, void *Py_UNUSED(ignored)) { - Py_INCREF(op->func_qualname); - return op->func_qualname; + return Py_NewRef(op->func_qualname); } static int @@ -372,8 +507,7 @@ func_set_qualname(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored "__qualname__ must be set to a string object"); return -1; } - Py_INCREF(value); - Py_XSETREF(op->func_qualname, value); + Py_XSETREF(op->func_qualname, Py_NewRef(value)); return 0; } @@ -386,8 +520,7 @@ func_get_defaults(PyFunctionObject *op, void *Py_UNUSED(ignored)) if (op->func_defaults == NULL) { Py_RETURN_NONE; } - Py_INCREF(op->func_defaults); - return op->func_defaults; + return Py_NewRef(op->func_defaults); } static int @@ -412,9 +545,9 @@ func_set_defaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored return -1; } + handle_func_event(PyFunction_EVENT_MODIFY_DEFAULTS, op, value); op->func_version = 0; - Py_XINCREF(value); - Py_XSETREF(op->func_defaults, value); + Py_XSETREF(op->func_defaults, Py_XNewRef(value)); return 0; } @@ -428,8 +561,7 @@ func_get_kwdefaults(PyFunctionObject *op, void *Py_UNUSED(ignored)) if (op->func_kwdefaults == NULL) { Py_RETURN_NONE; } - Py_INCREF(op->func_kwdefaults); - return op->func_kwdefaults; + return Py_NewRef(op->func_kwdefaults); } static int @@ -454,9 +586,9 @@ func_set_kwdefaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignor return -1; } + handle_func_event(PyFunction_EVENT_MODIFY_KWDEFAULTS, op, value); op->func_version = 0; - Py_XINCREF(value); - Py_XSETREF(op->func_kwdefaults, value); + Py_XSETREF(op->func_kwdefaults, Py_XNewRef(value)); return 0; } @@ -468,27 +600,8 @@ func_get_annotations(PyFunctionObject *op, void *Py_UNUSED(ignored)) if (op->func_annotations == NULL) return NULL; } - if (PyTuple_CheckExact(op->func_annotations)) { - PyObject *ann_tuple = op->func_annotations; - PyObject *ann_dict = PyDict_New(); - if (ann_dict == NULL) { - return NULL; - } - - assert(PyTuple_GET_SIZE(ann_tuple) % 2 == 0); - - for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(ann_tuple); i += 2) { - int err = PyDict_SetItem(ann_dict, - PyTuple_GET_ITEM(ann_tuple, i), - PyTuple_GET_ITEM(ann_tuple, i + 1)); - - if (err < 0) - return NULL; - } - Py_SETREF(op->func_annotations, ann_dict); - } - Py_INCREF(op->func_annotations); - return op->func_annotations; + PyObject *d = func_get_annotation_dict(op); + return Py_XNewRef(d); } static int @@ -505,8 +618,7 @@ func_set_annotations(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(igno return -1; } op->func_version = 0; - Py_XINCREF(value); - Py_XSETREF(op->func_annotations, value); + Py_XSETREF(op->func_annotations, Py_XNewRef(value)); return 0; } @@ -616,16 +728,13 @@ func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals, return NULL; } if (name != Py_None) { - Py_INCREF(name); - Py_SETREF(newfunc->func_name, name); + Py_SETREF(newfunc->func_name, Py_NewRef(name)); } if (defaults != Py_None) { - Py_INCREF(defaults); - newfunc->func_defaults = defaults; + newfunc->func_defaults = Py_NewRef(defaults); } if (closure != Py_None) { - Py_INCREF(closure); - newfunc->func_closure = closure; + newfunc->func_closure = Py_NewRef(closure); } return (PyObject *)newfunc; @@ -635,11 +744,8 @@ static int func_clear(PyFunctionObject *op) { op->func_version = 0; - Py_CLEAR(op->func_code); Py_CLEAR(op->func_globals); Py_CLEAR(op->func_builtins); - Py_CLEAR(op->func_name); - Py_CLEAR(op->func_qualname); Py_CLEAR(op->func_module); Py_CLEAR(op->func_defaults); Py_CLEAR(op->func_kwdefaults); @@ -647,17 +753,29 @@ func_clear(PyFunctionObject *op) Py_CLEAR(op->func_dict); Py_CLEAR(op->func_closure); Py_CLEAR(op->func_annotations); + // Don't Py_CLEAR(op->func_code), since code is always required + // to be non-NULL. Similarly, name and qualname shouldn't be NULL. + // However, name and qualname could be str subclasses, so they + // could have reference cycles. The solution is to replace them + // with a genuinely immutable string. + Py_SETREF(op->func_name, Py_NewRef(&_Py_STR(empty))); + Py_SETREF(op->func_qualname, Py_NewRef(&_Py_STR(empty))); return 0; } static void func_dealloc(PyFunctionObject *op) { + handle_func_event(PyFunction_EVENT_DESTROY, op, NULL); _PyObject_GC_UNTRACK(op); if (op->func_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) op); } (void)func_clear(op); + // These aren't cleared by func_clear(). + Py_DECREF(op->func_code); + Py_DECREF(op->func_name); + Py_DECREF(op->func_qualname); PyObject_GC_Del(op); } @@ -691,8 +809,7 @@ static PyObject * func_descr_get(PyObject *func, PyObject *obj, PyObject *type) { if (obj == Py_None || obj == NULL) { - Py_INCREF(func); - return func; + return Py_NewRef(func); } return PyMethod_New(func, obj); } @@ -764,12 +881,7 @@ functools_wraps(PyObject *wrapper, PyObject *wrapped) { #define COPY_ATTR(ATTR) \ do { \ - _Py_IDENTIFIER(ATTR); \ - PyObject *attr = _PyUnicode_FromId(&PyId_ ## ATTR); \ - if (attr == NULL) { \ - return -1; \ - } \ - if (functools_copy_attr(wrapper, wrapped, attr) < 0) { \ + if (functools_copy_attr(wrapper, wrapped, &_Py_ID(ATTR)) < 0) { \ return -1; \ } \ } while (0) \ @@ -866,8 +978,7 @@ cm_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; if (!PyArg_UnpackTuple(args, "classmethod", 1, 1, &callable)) return -1; - Py_INCREF(callable); - Py_XSETREF(cm->cm_callable, callable); + Py_XSETREF(cm->cm_callable, Py_NewRef(callable)); if (functools_wraps((PyObject *)cm, cm->cm_callable) < 0) { return -1; @@ -977,8 +1088,7 @@ PyClassMethod_New(PyObject *callable) classmethod *cm = (classmethod *) PyType_GenericAlloc(&PyClassMethod_Type, 0); if (cm != NULL) { - Py_INCREF(callable); - cm->cm_callable = callable; + cm->cm_callable = Py_NewRef(callable); } return (PyObject *)cm; } @@ -1043,8 +1153,7 @@ sm_descr_get(PyObject *self, PyObject *obj, PyObject *type) "uninitialized staticmethod object"); return NULL; } - Py_INCREF(sm->sm_callable); - return sm->sm_callable; + return Py_NewRef(sm->sm_callable); } static int @@ -1057,8 +1166,7 @@ sm_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; if (!PyArg_UnpackTuple(args, "staticmethod", 1, 1, &callable)) return -1; - Py_INCREF(callable); - Py_XSETREF(sm->sm_callable, callable); + Py_XSETREF(sm->sm_callable, Py_NewRef(callable)); if (functools_wraps((PyObject *)sm, sm->sm_callable) < 0) { return -1; @@ -1173,8 +1281,7 @@ PyStaticMethod_New(PyObject *callable) staticmethod *sm = (staticmethod *) PyType_GenericAlloc(&PyStaticMethod_Type, 0); if (sm != NULL) { - Py_INCREF(callable); - sm->sm_callable = callable; + sm->sm_callable = Py_NewRef(callable); } return (PyObject *)sm; } diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index dbe5d89b739..675fd496eef 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -5,14 +5,24 @@ #include "pycore_unionobject.h" // _Py_union_type_or, _PyGenericAlias_Check #include "structmember.h" // PyMemberDef +#include + typedef struct { PyObject_HEAD PyObject *origin; PyObject *args; PyObject *parameters; - PyObject* weakreflist; + PyObject *weakreflist; + // Whether we're a starred type, e.g. *tuple[int]. + bool starred; + vectorcallfunc vectorcall; } gaobject; +typedef struct { + PyObject_HEAD + PyObject *obj; /* Set to NULL when iterator is exhausted */ +} gaiterobject; + static void ga_dealloc(PyObject *self) { @@ -41,10 +51,6 @@ ga_traverse(PyObject *self, visitproc visit, void *arg) static int ga_repr_item(_PyUnicodeWriter *writer, PyObject *p) { - _Py_IDENTIFIER(__module__); - _Py_IDENTIFIER(__qualname__); - _Py_IDENTIFIER(__origin__); - _Py_IDENTIFIER(__args__); PyObject *qualname = NULL; PyObject *module = NULL; PyObject *r = NULL; @@ -57,12 +63,12 @@ ga_repr_item(_PyUnicodeWriter *writer, PyObject *p) goto done; } - if (_PyObject_LookupAttrId(p, &PyId___origin__, &tmp) < 0) { + if (_PyObject_LookupAttr(p, &_Py_ID(__origin__), &tmp) < 0) { goto done; } if (tmp != NULL) { Py_DECREF(tmp); - if (_PyObject_LookupAttrId(p, &PyId___args__, &tmp) < 0) { + if (_PyObject_LookupAttr(p, &_Py_ID(__args__), &tmp) < 0) { goto done; } if (tmp != NULL) { @@ -72,13 +78,13 @@ ga_repr_item(_PyUnicodeWriter *writer, PyObject *p) } } - if (_PyObject_LookupAttrId(p, &PyId___qualname__, &qualname) < 0) { + if (_PyObject_LookupAttr(p, &_Py_ID(__qualname__), &qualname) < 0) { goto done; } if (qualname == NULL) { goto use_repr; } - if (_PyObject_LookupAttrId(p, &PyId___module__, &module) < 0) { + if (_PyObject_LookupAttr(p, &_Py_ID(__module__), &module) < 0) { goto done; } if (module == NULL || module == Py_None) { @@ -124,6 +130,11 @@ ga_repr(PyObject *self) _PyUnicodeWriter writer; _PyUnicodeWriter_Init(&writer); + if (alias->starred) { + if (_PyUnicodeWriter_WriteASCIIString(&writer, "*", 1) < 0) { + goto error; + } + } if (ga_repr_item(&writer, alias->origin) < 0) { goto error; } @@ -156,25 +167,6 @@ error: return NULL; } -// isinstance(obj, TypeVar) without importing typing.py. -// Returns -1 for errors. -static int -is_typevar(PyObject *obj) -{ - PyTypeObject *type = Py_TYPE(obj); - if (strcmp(type->tp_name, "TypeVar") != 0) { - return 0; - } - PyObject *module = PyObject_GetAttrString((PyObject *)type, "__module__"); - if (module == NULL) { - return -1; - } - int res = PyUnicode_Check(module) - && _PyUnicode_EqualToASCIIString(module, "typing"); - Py_DECREF(module); - return res; -} - // Index of item in self[:len], or -1 if not found (self is a tuple) static Py_ssize_t tuple_index(PyObject *self, Py_ssize_t len, PyObject *item) @@ -191,13 +183,28 @@ static int tuple_add(PyObject *self, Py_ssize_t len, PyObject *item) { if (tuple_index(self, len, item) < 0) { - Py_INCREF(item); - PyTuple_SET_ITEM(self, len, item); + PyTuple_SET_ITEM(self, len, Py_NewRef(item)); return 1; } return 0; } +static Py_ssize_t +tuple_extend(PyObject **dst, Py_ssize_t dstindex, + PyObject **src, Py_ssize_t count) +{ + assert(count >= 0); + if (_PyTuple_Resize(dst, PyTuple_GET_SIZE(*dst) + count - 1) != 0) { + return -1; + } + assert(dstindex + count <= PyTuple_GET_SIZE(*dst)); + for (Py_ssize_t i = 0; i < count; ++i) { + PyObject *item = src[i]; + PyTuple_SET_ITEM(*dst, dstindex + i, Py_NewRef(item)); + } + return dstindex + count; +} + PyObject * _Py_make_parameters(PyObject *args) { @@ -209,18 +216,23 @@ _Py_make_parameters(PyObject *args) Py_ssize_t iparam = 0; for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { PyObject *t = PyTuple_GET_ITEM(args, iarg); - int typevar = is_typevar(t); - if (typevar < 0) { + PyObject *subst; + // We don't want __parameters__ descriptor of a bare Python class. + if (PyType_Check(t)) { + continue; + } + if (_PyObject_LookupAttr(t, &_Py_ID(__typing_subst__), &subst) < 0) { Py_DECREF(parameters); return NULL; } - if (typevar) { + if (subst) { iparam += tuple_add(parameters, iparam, t); + Py_DECREF(subst); } else { - _Py_IDENTIFIER(__parameters__); PyObject *subparams; - if (_PyObject_LookupAttrId(t, &PyId___parameters__, &subparams) < 0) { + if (_PyObject_LookupAttr(t, &_Py_ID(__parameters__), + &subparams) < 0) { Py_DECREF(parameters); return NULL; } @@ -258,11 +270,11 @@ _Py_make_parameters(PyObject *args) If obj doesn't have a __parameters__ attribute or that's not a non-empty tuple, return a new reference to obj. */ static PyObject * -subs_tvars(PyObject *obj, PyObject *params, PyObject **argitems) +subs_tvars(PyObject *obj, PyObject *params, + PyObject **argitems, Py_ssize_t nargs) { - _Py_IDENTIFIER(__parameters__); PyObject *subparams; - if (_PyObject_LookupAttrId(obj, &PyId___parameters__, &subparams) < 0) { + if (_PyObject_LookupAttr(obj, &_Py_ID(__parameters__), &subparams) < 0) { return NULL; } if (subparams && PyTuple_Check(subparams) && PyTuple_GET_SIZE(subparams)) { @@ -273,15 +285,27 @@ subs_tvars(PyObject *obj, PyObject *params, PyObject **argitems) Py_DECREF(subparams); return NULL; } + Py_ssize_t j = 0; for (Py_ssize_t i = 0; i < nsubargs; ++i) { PyObject *arg = PyTuple_GET_ITEM(subparams, i); Py_ssize_t iparam = tuple_index(params, nparams, arg); if (iparam >= 0) { + PyObject *param = PyTuple_GET_ITEM(params, iparam); arg = argitems[iparam]; + if (Py_TYPE(param)->tp_iter && PyTuple_Check(arg)) { // TypeVarTuple + j = tuple_extend(&subargs, j, + &PyTuple_GET_ITEM(arg, 0), + PyTuple_GET_SIZE(arg)); + if (j < 0) { + return NULL; + } + continue; + } } - Py_INCREF(arg); - PyTuple_SET_ITEM(subargs, i, arg); + PyTuple_SET_ITEM(subargs, j, Py_NewRef(arg)); + j++; } + assert(j == PyTuple_GET_SIZE(subargs)); obj = PyObject_GetItem(obj, subargs); @@ -294,23 +318,127 @@ subs_tvars(PyObject *obj, PyObject *params, PyObject **argitems) return obj; } +static int +_is_unpacked_typevartuple(PyObject *arg) +{ + PyObject *tmp; + if (PyType_Check(arg)) { // TODO: Add test + return 0; + } + int res = _PyObject_LookupAttr(arg, &_Py_ID(__typing_is_unpacked_typevartuple__), &tmp); + if (res > 0) { + res = PyObject_IsTrue(tmp); + Py_DECREF(tmp); + } + return res; +} + +static PyObject * +_unpacked_tuple_args(PyObject *arg) +{ + PyObject *result; + assert(!PyType_Check(arg)); + // Fast path + if (_PyGenericAlias_Check(arg) && + ((gaobject *)arg)->starred && + ((gaobject *)arg)->origin == (PyObject *)&PyTuple_Type) + { + result = ((gaobject *)arg)->args; + return Py_NewRef(result); + } + + if (_PyObject_LookupAttr(arg, &_Py_ID(__typing_unpacked_tuple_args__), &result) > 0) { + if (result == Py_None) { + Py_DECREF(result); + return NULL; + } + return result; + } + return NULL; +} + +static PyObject * +_unpack_args(PyObject *item) +{ + PyObject *newargs = PyList_New(0); + if (newargs == NULL) { + return NULL; + } + int is_tuple = PyTuple_Check(item); + Py_ssize_t nitems = is_tuple ? PyTuple_GET_SIZE(item) : 1; + PyObject **argitems = is_tuple ? &PyTuple_GET_ITEM(item, 0) : &item; + for (Py_ssize_t i = 0; i < nitems; i++) { + item = argitems[i]; + if (!PyType_Check(item)) { + PyObject *subargs = _unpacked_tuple_args(item); + if (subargs != NULL && + PyTuple_Check(subargs) && + !(PyTuple_GET_SIZE(subargs) && + PyTuple_GET_ITEM(subargs, PyTuple_GET_SIZE(subargs)-1) == Py_Ellipsis)) + { + if (PyList_SetSlice(newargs, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, subargs) < 0) { + Py_DECREF(subargs); + Py_DECREF(newargs); + return NULL; + } + Py_DECREF(subargs); + continue; + } + Py_XDECREF(subargs); + if (PyErr_Occurred()) { + Py_DECREF(newargs); + return NULL; + } + } + if (PyList_Append(newargs, item) < 0) { + Py_DECREF(newargs); + return NULL; + } + } + Py_SETREF(newargs, PySequence_Tuple(newargs)); + return newargs; +} + PyObject * _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObject *item) { Py_ssize_t nparams = PyTuple_GET_SIZE(parameters); if (nparams == 0) { return PyErr_Format(PyExc_TypeError, - "There are no type variables left in %R", + "%R is not a generic class", self); } + item = _unpack_args(item); + for (Py_ssize_t i = 0; i < nparams; i++) { + PyObject *param = PyTuple_GET_ITEM(parameters, i); + PyObject *prepare, *tmp; + if (_PyObject_LookupAttr(param, &_Py_ID(__typing_prepare_subst__), &prepare) < 0) { + Py_DECREF(item); + return NULL; + } + if (prepare && prepare != Py_None) { + if (PyTuple_Check(item)) { + tmp = PyObject_CallFunction(prepare, "OO", self, item); + } + else { + tmp = PyObject_CallFunction(prepare, "O(O)", self, item); + } + Py_DECREF(prepare); + Py_SETREF(item, tmp); + if (item == NULL) { + return NULL; + } + } + } int is_tuple = PyTuple_Check(item); Py_ssize_t nitems = is_tuple ? PyTuple_GET_SIZE(item) : 1; PyObject **argitems = is_tuple ? &PyTuple_GET_ITEM(item, 0) : &item; if (nitems != nparams) { + Py_DECREF(item); return PyErr_Format(PyExc_TypeError, - "Too %s arguments for %R", + "Too %s arguments for %R; actual %zd, expected %zd", nitems > nparams ? "many" : "few", - self); + self, nitems, nparams); } /* Replace all type variables (specified by parameters) with corresponding values specified by argitems. @@ -321,34 +449,67 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje Py_ssize_t nargs = PyTuple_GET_SIZE(args); PyObject *newargs = PyTuple_New(nargs); if (newargs == NULL) { + Py_DECREF(item); return NULL; } - for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { + for (Py_ssize_t iarg = 0, jarg = 0; iarg < nargs; iarg++) { PyObject *arg = PyTuple_GET_ITEM(args, iarg); - int typevar = is_typevar(arg); - if (typevar < 0) { + if (PyType_Check(arg)) { + PyTuple_SET_ITEM(newargs, jarg, Py_NewRef(arg)); + jarg++; + continue; + } + + int unpack = _is_unpacked_typevartuple(arg); + if (unpack < 0) { Py_DECREF(newargs); + Py_DECREF(item); return NULL; } - if (typevar) { + PyObject *subst; + if (_PyObject_LookupAttr(arg, &_Py_ID(__typing_subst__), &subst) < 0) { + Py_DECREF(newargs); + Py_DECREF(item); + return NULL; + } + if (subst) { Py_ssize_t iparam = tuple_index(parameters, nparams, arg); assert(iparam >= 0); - arg = argitems[iparam]; - Py_INCREF(arg); + arg = PyObject_CallOneArg(subst, argitems[iparam]); + Py_DECREF(subst); } else { - arg = subs_tvars(arg, parameters, argitems); - if (arg == NULL) { - Py_DECREF(newargs); + arg = subs_tvars(arg, parameters, argitems, nitems); + } + if (arg == NULL) { + Py_DECREF(newargs); + Py_DECREF(item); + return NULL; + } + if (unpack) { + jarg = tuple_extend(&newargs, jarg, + &PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg)); + Py_DECREF(arg); + if (jarg < 0) { + Py_DECREF(item); return NULL; } } - PyTuple_SET_ITEM(newargs, iarg, arg); + else { + PyTuple_SET_ITEM(newargs, jarg, arg); + jarg++; + } } + Py_DECREF(item); return newargs; } +PyDoc_STRVAR(genericalias__doc__, +"Represent a PEP 585 generic type\n" +"\n" +"E.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,)."); + static PyObject * ga_getitem(PyObject *self, PyObject *item) { @@ -367,6 +528,7 @@ ga_getitem(PyObject *self, PyObject *item) } PyObject *res = Py_GenericAlias(alias->origin, newargs); + ((gaobject *)res)->starred = alias->starred; Py_DECREF(newargs); return res; @@ -392,13 +554,11 @@ ga_hash(PyObject *self) return h0 ^ h1; } -static PyObject * -ga_call(PyObject *self, PyObject *args, PyObject *kwds) +static inline PyObject * +set_orig_class(PyObject *obj, PyObject *self) { - gaobject *alias = (gaobject *)self; - PyObject *obj = PyObject_Call(alias->origin, args, kwds); if (obj != NULL) { - if (PyObject_SetAttrString(obj, "__orig_class__", self) < 0) { + if (PyObject_SetAttr(obj, &_Py_ID(__orig_class__), self) < 0) { if (!PyErr_ExceptionMatches(PyExc_AttributeError) && !PyErr_ExceptionMatches(PyExc_TypeError)) { @@ -411,10 +571,30 @@ ga_call(PyObject *self, PyObject *args, PyObject *kwds) return obj; } +static PyObject * +ga_call(PyObject *self, PyObject *args, PyObject *kwds) +{ + gaobject *alias = (gaobject *)self; + PyObject *obj = PyObject_Call(alias->origin, args, kwds); + return set_orig_class(obj, self); +} + +static PyObject * +ga_vectorcall(PyObject *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + gaobject *alias = (gaobject *) self; + PyObject *obj = PyVectorcall_Function(alias->origin)(alias->origin, args, nargsf, kwnames); + return set_orig_class(obj, self); +} + static const char* const attr_exceptions[] = { + "__class__", "__origin__", "__args__", + "__unpacked__", "__parameters__", + "__typing_unpacked_tuple_args__", "__mro_entries__", "__reduce_ex__", // needed so we don't look up object.__reduce_ex__ "__reduce__", @@ -464,6 +644,9 @@ ga_richcompare(PyObject *a, PyObject *b, int op) gaobject *aa = (gaobject *)a; gaobject *bb = (gaobject *)b; + if (aa->starred != bb->starred) { + Py_RETURN_FALSE; + } int eq = PyObject_RichCompareBool(aa->origin, bb->origin, Py_EQ); if (eq < 0) { return NULL; @@ -501,6 +684,16 @@ static PyObject * ga_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) { gaobject *alias = (gaobject *)self; + if (alias->starred) { + PyObject *tmp = Py_GenericAlias(alias->origin, alias->args); + if (tmp != NULL) { + Py_SETREF(tmp, PyObject_GetIter(tmp)); + } + if (tmp == NULL) { + return NULL; + } + return Py_BuildValue("N(N)", _PyEval_GetBuiltin(&_Py_ID(next)), tmp); + } return Py_BuildValue("O(OO)", Py_TYPE(alias), alias->origin, alias->args); } @@ -555,6 +748,7 @@ static PyMethodDef ga_methods[] = { static PyMemberDef ga_members[] = { {"__origin__", T_OBJECT, offsetof(gaobject, origin), READONLY}, {"__args__", T_OBJECT, offsetof(gaobject, args), READONLY}, + {"__unpacked__", T_BOOL, offsetof(gaobject, starred), READONLY}, {0} }; @@ -568,12 +762,22 @@ ga_parameters(PyObject *self, void *unused) return NULL; } } - Py_INCREF(alias->parameters); - return alias->parameters; + return Py_NewRef(alias->parameters); +} + +static PyObject * +ga_unpacked_tuple_args(PyObject *self, void *unused) +{ + gaobject *alias = (gaobject *)self; + if (alias->starred && alias->origin == (PyObject *)&PyTuple_Type) { + return Py_NewRef(alias->args); + } + Py_RETURN_NONE; } static PyGetSetDef ga_properties[] = { {"__parameters__", ga_parameters, (setter)NULL, "Type variables in the GenericAlias.", NULL}, + {"__typing_unpacked_tuple_args__", ga_unpacked_tuple_args, (setter)NULL, NULL}, {0} }; @@ -592,11 +796,18 @@ setup_ga(gaobject *alias, PyObject *origin, PyObject *args) { Py_INCREF(args); } - Py_INCREF(origin); - alias->origin = origin; + alias->origin = Py_NewRef(origin); alias->args = args; alias->parameters = NULL; alias->weakreflist = NULL; + + if (PyVectorcall_Function(origin) != NULL) { + alias->vectorcall = ga_vectorcall; + } + else { + alias->vectorcall = NULL; + } + return 1; } @@ -626,16 +837,88 @@ static PyNumberMethods ga_as_number = { .nb_or = _Py_union_type_or, // Add __or__ function }; +static PyObject * +ga_iternext(gaiterobject *gi) { + if (gi->obj == NULL) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + gaobject *alias = (gaobject *)gi->obj; + PyObject *starred_alias = Py_GenericAlias(alias->origin, alias->args); + if (starred_alias == NULL) { + return NULL; + } + ((gaobject *)starred_alias)->starred = true; + Py_SETREF(gi->obj, NULL); + return starred_alias; +} + +static void +ga_iter_dealloc(gaiterobject *gi) { + PyObject_GC_UnTrack(gi); + Py_XDECREF(gi->obj); + PyObject_GC_Del(gi); +} + +static int +ga_iter_traverse(gaiterobject *gi, visitproc visit, void *arg) +{ + Py_VISIT(gi->obj); + return 0; +} + +static int +ga_iter_clear(PyObject *self) { + gaiterobject *gi = (gaiterobject *)self; + Py_CLEAR(gi->obj); + return 0; +} + +static PyObject * +ga_iter_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + gaiterobject *gi = (gaiterobject *)self; + return Py_BuildValue("N(O)", _PyEval_GetBuiltin(&_Py_ID(iter)), gi->obj); +} + +static PyMethodDef ga_iter_methods[] = { + {"__reduce__", ga_iter_reduce, METH_NOARGS}, + {0} +}; + +// gh-91632: _Py_GenericAliasIterType is exported to be cleared +// in _PyTypes_FiniTypes. +PyTypeObject _Py_GenericAliasIterType = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + .tp_name = "generic_alias_iterator", + .tp_basicsize = sizeof(gaiterobject), + .tp_iter = PyObject_SelfIter, + .tp_iternext = (iternextfunc)ga_iternext, + .tp_traverse = (traverseproc)ga_iter_traverse, + .tp_methods = ga_iter_methods, + .tp_dealloc = (destructor)ga_iter_dealloc, + .tp_clear = (inquiry)ga_iter_clear, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, +}; + +static PyObject * +ga_iter(PyObject *self) { + gaiterobject *gi = PyObject_GC_New(gaiterobject, &_Py_GenericAliasIterType); + if (gi == NULL) { + return NULL; + } + gi->obj = Py_NewRef(self); + PyObject_GC_Track(gi); + return (PyObject *)gi; +} + // TODO: // - argument clinic? -// - __doc__? // - cache? PyTypeObject Py_GenericAliasType = { PyVarObject_HEAD_INIT(&PyType_Type, 0) .tp_name = "types.GenericAlias", - .tp_doc = "Represent a PEP 585 generic type\n" - "\n" - "E.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", + .tp_doc = genericalias__doc__, .tp_basicsize = sizeof(gaobject), .tp_dealloc = ga_dealloc, .tp_repr = ga_repr, @@ -644,7 +927,7 @@ PyTypeObject Py_GenericAliasType = { .tp_hash = ga_hash, .tp_call = ga_call, .tp_getattro = ga_getattro, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL, .tp_traverse = ga_traverse, .tp_richcompare = ga_richcompare, .tp_weaklistoffset = offsetof(gaobject, weakreflist), @@ -654,6 +937,8 @@ PyTypeObject Py_GenericAliasType = { .tp_new = ga_new, .tp_free = PyObject_GC_Del, .tp_getset = ga_properties, + .tp_iter = (getiterfunc)ga_iter, + .tp_vectorcall_offset = offsetof(gaobject, vectorcall), }; PyObject * diff --git a/Objects/genobject.c b/Objects/genobject.c index efd255d33f9..35246653c45 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1,15 +1,18 @@ /* Generator object implementation */ +#define _PY_INTERPRETER + #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _PyEval_EvalFrame() +#include "pycore_frame.h" // _PyInterpreterFrame +#include "pycore_genobject.h" // struct _Py_async_gen_state #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_pyerrors.h" // _PyErr_ClearExcState() #include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_frame.h" // InterpreterFrame -#include "frameobject.h" // PyFrameObject #include "structmember.h" // PyMemberDef -#include "opcode.h" // YIELD_FROM +#include "opcode.h" // SEND +#include "pystats.h" static PyObject *gen_close(PyGenObject *, PyObject *); static PyObject *async_gen_asend_new(PyAsyncGenObject *, PyObject *); @@ -24,9 +27,7 @@ static const char *ASYNC_GEN_IGNORED_EXIT_MSG = static inline int exc_state_traverse(_PyErr_StackItem *exc_state, visitproc visit, void *arg) { - Py_VISIT(exc_state->exc_type); Py_VISIT(exc_state->exc_value); - Py_VISIT(exc_state->exc_traceback); return 0; } @@ -36,9 +37,10 @@ gen_traverse(PyGenObject *gen, visitproc visit, void *arg) Py_VISIT(gen->gi_code); Py_VISIT(gen->gi_name); Py_VISIT(gen->gi_qualname); - InterpreterFrame *frame = gen->gi_xframe; - if (frame != NULL) { - assert(frame->frame_obj == NULL || frame->frame_obj->f_own_locals_memory == 0); + if (gen->gi_frame_state < FRAME_CLEARED) { + _PyInterpreterFrame *frame = (_PyInterpreterFrame *)(gen->gi_iframe); + assert(frame->frame_obj == NULL || + frame->frame_obj->f_frame->owner == FRAME_OWNED_BY_GENERATOR); int err = _PyFrame_Traverse(frame, visit, arg); if (err) { return err; @@ -56,14 +58,14 @@ _PyGen_Finalize(PyObject *self) PyObject *res = NULL; PyObject *error_type, *error_value, *error_traceback; - if (gen->gi_xframe == NULL || _PyFrameHasCompleted(gen->gi_xframe)) { + if (gen->gi_frame_state >= FRAME_COMPLETED) { /* Generator isn't paused, so no need to close */ return; } if (PyAsyncGen_CheckExact(self)) { PyAsyncGenObject *agen = (PyAsyncGenObject*)self; - PyObject *finalizer = agen->ag_finalizer; + PyObject *finalizer = agen->ag_origin_or_finalizer; if (finalizer && !agen->ag_closed) { /* Save the current exception, if any. */ PyErr_Fetch(&error_type, &error_value, &error_traceback); @@ -88,7 +90,7 @@ _PyGen_Finalize(PyObject *self) issue a RuntimeWarning. */ if (gen->gi_code != NULL && ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE && - gen->gi_xframe->f_lasti == -1) + gen->gi_frame_state == FRAME_CREATED) { _PyErr_WarnUnawaitedCoroutine((PyObject *)gen); } @@ -129,16 +131,16 @@ gen_dealloc(PyGenObject *gen) /* We have to handle this case for asynchronous generators right here, because this code has to be between UNTRACK and GC_Del. */ - Py_CLEAR(((PyAsyncGenObject*)gen)->ag_finalizer); + Py_CLEAR(((PyAsyncGenObject*)gen)->ag_origin_or_finalizer); } - InterpreterFrame *frame = gen->gi_xframe; - if (frame != NULL) { - gen->gi_xframe = NULL; + if (gen->gi_frame_state < FRAME_CLEARED) { + _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; + gen->gi_frame_state = FRAME_CLEARED; frame->previous = NULL; - _PyFrame_Clear(frame, 1); + _PyFrame_Clear(frame); } if (((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE) { - Py_CLEAR(((PyCoroObject *)gen)->cr_origin); + Py_CLEAR(((PyCoroObject *)gen)->cr_origin_or_finalizer); } Py_CLEAR(gen->gi_code); Py_CLEAR(gen->gi_name); @@ -152,11 +154,24 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, int exc, int closing) { PyThreadState *tstate = _PyThreadState_GET(); - InterpreterFrame *frame = gen->gi_xframe; + _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; PyObject *result; *presult = NULL; - if (frame != NULL && _PyFrame_IsExecuting(frame)) { + if (gen->gi_frame_state == FRAME_CREATED && arg && arg != Py_None) { + const char *msg = "can't send non-None value to a " + "just-started generator"; + if (PyCoro_CheckExact(gen)) { + msg = NON_INIT_CORO_MSG; + } + else if (PyAsyncGen_CheckExact(gen)) { + msg = "can't send non-None value to a " + "just-started async generator"; + } + PyErr_SetString(PyExc_TypeError, msg); + return PYGEN_ERROR; + } + if (gen->gi_frame_state == FRAME_EXECUTING) { const char *msg = "generator already executing"; if (PyCoro_CheckExact(gen)) { msg = "coroutine already executing"; @@ -167,7 +182,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, PyErr_SetString(PyExc_ValueError, msg); return PYGEN_ERROR; } - if (frame == NULL || _PyFrameHasCompleted(frame)) { + if (gen->gi_frame_state >= FRAME_COMPLETED) { if (PyCoro_CheckExact(gen) && !closing) { /* `gen` is an exhausted coroutine: raise an error, except when called from gen_close(), which should @@ -179,23 +194,19 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, else if (arg && !exc) { /* `gen` is an exhausted generator: only return value if called from send(). */ - *presult = Py_None; - Py_INCREF(*presult); + *presult = Py_NewRef(Py_None); return PYGEN_RETURN; } return PYGEN_ERROR; } - assert(_PyFrame_IsRunnable(frame)); - assert(frame->f_lasti >= 0 || ((unsigned char *)PyBytes_AS_STRING(gen->gi_code->co_code))[0] == GEN_START); + assert(gen->gi_frame_state < FRAME_EXECUTING); /* Push arg onto the frame's value stack */ result = arg ? arg : Py_None; - Py_INCREF(result); - _PyFrame_StackPush(frame, result); + _PyFrame_StackPush(frame, Py_NewRef(result)); - frame->previous = tstate->cframe->current_frame; - - gen->gi_exc_state.previous_item = tstate->exc_info; + _PyErr_StackItem *prev_exc_info = tstate->exc_info; + gen->gi_exc_state.previous_item = prev_exc_info; tstate->exc_info = &gen->gi_exc_state; if (exc) { @@ -203,20 +214,18 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, _PyErr_ChainStackItem(NULL); } + gen->gi_frame_state = FRAME_EXECUTING; + EVAL_CALL_STAT_INC(EVAL_CALL_GENERATOR); result = _PyEval_EvalFrame(tstate, frame, exc); - tstate->exc_info = gen->gi_exc_state.previous_item; - gen->gi_exc_state.previous_item = NULL; - - assert(tstate->cframe->current_frame == frame->previous); - /* Don't keep the reference to previous any longer than necessary. It - * may keep a chain of frames alive or it could create a reference - * cycle. */ - frame->previous = NULL; + assert(tstate->exc_info == prev_exc_info); + assert(gen->gi_exc_state.previous_item == NULL); + assert(gen->gi_frame_state != FRAME_EXECUTING); + assert(frame->previous == NULL); /* If the generator just returned (as opposed to yielding), signal * that the generator is exhausted. */ if (result) { - if (!_PyFrameHasCompleted(frame)) { + if (gen->gi_frame_state == FRAME_SUSPENDED) { *presult = result; return PYGEN_NEXT; } @@ -227,34 +236,16 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, } } else { - if (PyErr_ExceptionMatches(PyExc_StopIteration)) { - const char *msg = "generator raised StopIteration"; - if (PyCoro_CheckExact(gen)) { - msg = "coroutine raised StopIteration"; - } - else if (PyAsyncGen_CheckExact(gen)) { - msg = "async generator raised StopIteration"; - } - _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg); - } - else if (PyAsyncGen_CheckExact(gen) && - PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) - { - /* code in `gen` raised a StopAsyncIteration error: - raise a RuntimeError. - */ - const char *msg = "async generator raised StopAsyncIteration"; - _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg); - } + assert(!PyErr_ExceptionMatches(PyExc_StopIteration)); + assert(!PyAsyncGen_CheckExact(gen) || + !PyErr_ExceptionMatches(PyExc_StopAsyncIteration)); } /* generator can't be rerun, so release the frame */ /* first clean reference cycle through stored exception traceback */ _PyErr_ClearExcState(&gen->gi_exc_state); - frame->generator = NULL; - gen->gi_xframe = NULL; - _PyFrame_Clear(frame, 1); + assert(gen->gi_frame_state == FRAME_CLEARED); *presult = result; return result ? PYGEN_RETURN : PYGEN_ERROR; } @@ -307,7 +298,6 @@ static int gen_close_iter(PyObject *yf) { PyObject *retval = NULL; - _Py_IDENTIFIER(close); if (PyGen_CheckExact(yf) || PyCoro_CheckExact(yf)) { retval = gen_close((PyGenObject *)yf, NULL); @@ -316,7 +306,7 @@ gen_close_iter(PyObject *yf) } else { PyObject *meth; - if (_PyObject_LookupAttrId(yf, &PyId_close, &meth) < 0) { + if (_PyObject_LookupAttr(yf, &_Py_ID(close), &meth) < 0) { PyErr_WriteUnraisable(yf); } if (meth) { @@ -335,23 +325,23 @@ _PyGen_yf(PyGenObject *gen) { PyObject *yf = NULL; - if (gen->gi_xframe) { - InterpreterFrame *frame = gen->gi_xframe; - PyObject *bytecode = gen->gi_code->co_code; - unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode); + if (gen->gi_frame_state < FRAME_CLEARED) { + _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; - if (frame->f_lasti < 0) { - /* Return immediately if the frame didn't start yet. YIELD_FROM + if (gen->gi_frame_state == FRAME_CREATED) { + /* Return immediately if the frame didn't start yet. SEND always come after LOAD_CONST: a code object should not start - with YIELD_FROM */ - assert(code[0] != YIELD_FROM); + with SEND */ + assert(_Py_OPCODE(_PyCode_CODE(gen->gi_code)[0]) != SEND); return NULL; } - - if (code[(frame->f_lasti+1)*sizeof(_Py_CODEUNIT)] != YIELD_FROM) + _Py_CODEUNIT next = frame->prev_instr[1]; + if (_Py_OPCODE(next) != RESUME || _Py_OPARG(next) < 2) + { + /* Not in a yield from */ return NULL; - yf = _PyFrame_StackPeek(frame); - Py_INCREF(yf); + } + yf = Py_NewRef(_PyFrame_StackPeek(frame)); } return yf; @@ -364,15 +354,37 @@ gen_close(PyGenObject *gen, PyObject *args) PyObject *yf = _PyGen_yf(gen); int err = 0; + if (gen->gi_frame_state == FRAME_CREATED) { + gen->gi_frame_state = FRAME_COMPLETED; + Py_RETURN_NONE; + } + if (gen->gi_frame_state >= FRAME_COMPLETED) { + Py_RETURN_NONE; + } if (yf) { - PyFrameState state = gen->gi_xframe->f_state; - gen->gi_xframe->f_state = FRAME_EXECUTING; + PyFrameState state = gen->gi_frame_state; + gen->gi_frame_state = FRAME_EXECUTING; err = gen_close_iter(yf); - gen->gi_xframe->f_state = state; + gen->gi_frame_state = state; Py_DECREF(yf); } - if (err == 0) + _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; + /* It is possible for the previous instruction to not be a + * YIELD_VALUE if the debugger has changed the lineno. */ + if (err == 0 && frame->prev_instr->opcode == YIELD_VALUE) { + assert(frame->prev_instr[1].opcode == RESUME); + int exception_handler_depth = frame->prev_instr->oparg; + assert(exception_handler_depth > 0); + /* We can safely ignore the outermost try block + * as it automatically generated to handle + * StopIteration. */ + if (exception_handler_depth == 1) { + Py_RETURN_NONE; + } + } + if (err == 0) { PyErr_SetNone(PyExc_GeneratorExit); + } retval = gen_send_ex(gen, Py_None, 1, 1); if (retval) { const char *msg = "generator ignored GeneratorExit"; @@ -395,17 +407,22 @@ gen_close(PyGenObject *gen, PyObject *args) PyDoc_STRVAR(throw_doc, -"throw(typ[,val[,tb]]) -> raise exception in generator,\n\ -return next yielded value or raise StopIteration."); +"throw(value)\n\ +throw(type[,value[,tb]])\n\ +\n\ +Raise exception in generator, return next yielded value or raise\n\ +StopIteration.\n\ +the (type, val, tb) signature is deprecated, \n\ +and may be removed in a future version of Python."); static PyObject * _gen_throw(PyGenObject *gen, int close_on_genexit, PyObject *typ, PyObject *val, PyObject *tb) { PyObject *yf = _PyGen_yf(gen); - _Py_IDENTIFIER(throw); if (yf) { + _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; PyObject *ret; int err; if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) && @@ -415,10 +432,10 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, We have to allow some awaits to work it through, hence the `close_on_genexit` parameter here. */ - PyFrameState state = gen->gi_xframe->f_state; - gen->gi_xframe->f_state = FRAME_EXECUTING; + PyFrameState state = gen->gi_frame_state; + gen->gi_frame_state = FRAME_EXECUTING; err = gen_close_iter(yf); - gen->gi_xframe->f_state = state; + gen->gi_frame_state = state; Py_DECREF(yf); if (err < 0) return gen_send_ex(gen, Py_None, 1, 0); @@ -427,30 +444,27 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, if (PyGen_CheckExact(yf) || PyCoro_CheckExact(yf)) { /* `yf` is a generator or a coroutine. */ PyThreadState *tstate = _PyThreadState_GET(); - InterpreterFrame *frame = gen->gi_xframe; - - /* Since we are fast-tracking things by skipping the eval loop, we need to update the current frame so the stack trace will be reported correctly to the user. */ /* XXX We should probably be updating the current frame somewhere in ceval.c. */ - InterpreterFrame *prev = tstate->cframe->current_frame; + _PyInterpreterFrame *prev = tstate->cframe->current_frame; frame->previous = prev; tstate->cframe->current_frame = frame; /* Close the generator that we are currently iterating with 'yield from' or awaiting on with 'await'. */ - PyFrameState state = gen->gi_xframe->f_state; - gen->gi_xframe->f_state = FRAME_EXECUTING; + PyFrameState state = gen->gi_frame_state; + gen->gi_frame_state = FRAME_EXECUTING; ret = _gen_throw((PyGenObject *)yf, close_on_genexit, typ, val, tb); - gen->gi_xframe->f_state = state; + gen->gi_frame_state = state; tstate->cframe->current_frame = prev; frame->previous = NULL; } else { /* `yf` is an iterator or a coroutine-like object. */ PyObject *meth; - if (_PyObject_LookupAttrId(yf, &PyId_throw, &meth) < 0) { + if (_PyObject_LookupAttr(yf, &_Py_ID(throw), &meth) < 0) { Py_DECREF(yf); return NULL; } @@ -458,28 +472,15 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, Py_DECREF(yf); goto throw_here; } - PyFrameState state = gen->gi_xframe->f_state; - gen->gi_xframe->f_state = FRAME_EXECUTING; + PyFrameState state = gen->gi_frame_state; + gen->gi_frame_state = FRAME_EXECUTING; ret = PyObject_CallFunctionObjArgs(meth, typ, val, tb, NULL); - gen->gi_xframe->f_state = state; + gen->gi_frame_state = state; Py_DECREF(meth); } Py_DECREF(yf); if (!ret) { - PyObject *val; - /* Pop subiterator from stack */ - ret = _PyFrame_StackPop(gen->gi_xframe); - assert(ret == yf); - Py_DECREF(ret); - /* Termination repetition of YIELD_FROM */ - assert(gen->gi_xframe->f_lasti >= 0); - gen->gi_xframe->f_lasti += 1; - if (_PyGen_FetchStopIterationValue(&val) == 0) { - ret = gen_send(gen, val); - Py_DECREF(val); - } else { - ret = gen_send_ex(gen, Py_None, 1, 0); - } + ret = gen_send_ex(gen, Py_None, 1, 0); } return ret; } @@ -512,10 +513,8 @@ throw_here: } else { /* Normalize to raise , */ - Py_XDECREF(val); - val = typ; - typ = PyExceptionInstance_Class(typ); - Py_INCREF(typ); + Py_XSETREF(val, typ); + typ = Py_NewRef(PyExceptionInstance_Class(typ)); if (tb == NULL) /* Returns NULL if there's no traceback */ @@ -544,16 +543,31 @@ failed_throw: static PyObject * -gen_throw(PyGenObject *gen, PyObject *args) +gen_throw(PyGenObject *gen, PyObject *const *args, Py_ssize_t nargs) { PyObject *typ; PyObject *tb = NULL; PyObject *val = NULL; - if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb)) { + if (!_PyArg_CheckPositional("throw", nargs, 1, 3)) { return NULL; } - + if (nargs > 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "the (type, exc, tb) signature of throw() is deprecated, " + "use the single-arg signature instead.", + 1) < 0) { + return NULL; + } + } + typ = args[0]; + if (nargs == 3) { + val = args[1]; + tb = args[2]; + } + else if (nargs == 2) { + val = args[1]; + } return _gen_throw(gen, 1, typ, val, tb); } @@ -628,8 +642,7 @@ _PyGen_FetchStopIterationValue(PyObject **pvalue) if (ev) { /* exception will usually be normalised already */ if (PyObject_TypeCheck(ev, (PyTypeObject *) et)) { - value = ((PyStopIterationObject *)ev)->value; - Py_INCREF(value); + value = Py_NewRef(((PyStopIterationObject *)ev)->value); Py_DECREF(ev); } else if (et == PyExc_StopIteration && !PyTuple_Check(ev)) { /* Avoid normalisation and take ev as value. @@ -648,8 +661,7 @@ _PyGen_FetchStopIterationValue(PyObject **pvalue) PyErr_Restore(et, ev, tb); return -1; } - value = ((PyStopIterationObject *)ev)->value; - Py_INCREF(value); + value = Py_NewRef(((PyStopIterationObject *)ev)->value); Py_DECREF(ev); } } @@ -659,8 +671,7 @@ _PyGen_FetchStopIterationValue(PyObject **pvalue) return -1; } if (value == NULL) { - value = Py_None; - Py_INCREF(value); + value = Py_NewRef(Py_None); } *pvalue = value; return 0; @@ -676,8 +687,7 @@ gen_repr(PyGenObject *gen) static PyObject * gen_get_name(PyGenObject *op, void *Py_UNUSED(ignored)) { - Py_INCREF(op->gi_name); - return op->gi_name; + return Py_NewRef(op->gi_name); } static int @@ -690,16 +700,14 @@ gen_set_name(PyGenObject *op, PyObject *value, void *Py_UNUSED(ignored)) "__name__ must be set to a string object"); return -1; } - Py_INCREF(value); - Py_XSETREF(op->gi_name, value); + Py_XSETREF(op->gi_name, Py_NewRef(value)); return 0; } static PyObject * gen_get_qualname(PyGenObject *op, void *Py_UNUSED(ignored)) { - Py_INCREF(op->gi_qualname); - return op->gi_qualname; + return Py_NewRef(op->gi_qualname); } static int @@ -712,8 +720,7 @@ gen_set_qualname(PyGenObject *op, PyObject *value, void *Py_UNUSED(ignored)) "__qualname__ must be set to a string object"); return -1; } - Py_INCREF(value); - Py_XSETREF(op->gi_qualname, value); + Py_XSETREF(op->gi_qualname, Py_NewRef(value)); return 0; } @@ -730,10 +737,16 @@ gen_getyieldfrom(PyGenObject *gen, void *Py_UNUSED(ignored)) static PyObject * gen_getrunning(PyGenObject *gen, void *Py_UNUSED(ignored)) { - if (gen->gi_xframe == NULL) { - Py_RETURN_FALSE; + if (gen->gi_frame_state == FRAME_EXECUTING) { + Py_RETURN_TRUE; } - return PyBool_FromLong(_PyFrame_IsExecuting(gen->gi_xframe)); + Py_RETURN_FALSE; +} + +static PyObject * +gen_getsuspended(PyGenObject *gen, void *Py_UNUSED(ignored)) +{ + return PyBool_FromLong(gen->gi_frame_state == FRAME_SUSPENDED); } static PyObject * @@ -742,10 +755,10 @@ _gen_getframe(PyGenObject *gen, const char *const name) if (PySys_Audit("object.__getattr__", "Os", gen, name) < 0) { return NULL; } - if (gen->gi_xframe == NULL) { + if (gen->gi_frame_state == FRAME_CLEARED) { Py_RETURN_NONE; } - return _Py_XNewRef((PyObject *)_PyFrame_GetFrameObject(gen->gi_xframe)); + return _Py_XNewRef((PyObject *)_PyFrame_GetFrameObject((_PyInterpreterFrame *)gen->gi_iframe)); } static PyObject * @@ -763,6 +776,7 @@ static PyGetSetDef gen_getsetlist[] = { PyDoc_STR("object being iterated by yield from, or None")}, {"gi_running", (getter)gen_getrunning, NULL, NULL}, {"gi_frame", (getter)gen_getframe, NULL, NULL}, + {"gi_suspended", (getter)gen_getsuspended, NULL, NULL}, {NULL} /* Sentinel */ }; @@ -771,10 +785,24 @@ static PyMemberDef gen_memberlist[] = { {NULL} /* Sentinel */ }; +static PyObject * +gen_sizeof(PyGenObject *gen, PyObject *Py_UNUSED(ignored)) +{ + Py_ssize_t res; + res = offsetof(PyGenObject, gi_iframe) + offsetof(_PyInterpreterFrame, localsplus); + PyCodeObject *code = gen->gi_code; + res += _PyFrame_NumSlotsForCodeObject(code) * sizeof(PyObject *); + return PyLong_FromSsize_t(res); +} + +PyDoc_STRVAR(sizeof__doc__, +"gen.__sizeof__() -> size of gen in memory, in bytes"); + static PyMethodDef gen_methods[] = { {"send",(PyCFunction)gen_send, METH_O, send_doc}, - {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc}, + {"throw",_PyCFunction_CAST(gen_throw), METH_FASTCALL, throw_doc}, {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc}, + {"__sizeof__", (PyCFunction)gen_sizeof, METH_NOARGS, sizeof__doc__}, {NULL, NULL} /* Sentinel */ }; @@ -789,8 +817,9 @@ static PyAsyncMethods gen_as_async = { PyTypeObject PyGen_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "generator", /* tp_name */ - sizeof(PyGenObject), /* tp_basicsize */ - 0, /* tp_itemsize */ + offsetof(PyGenObject, gi_iframe) + + offsetof(_PyInterpreterFrame, localsplus), /* tp_basicsize */ + sizeof(PyObject *), /* tp_itemsize */ /* methods */ (destructor)gen_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ @@ -840,63 +869,53 @@ PyTypeObject PyGen_Type = { }; static PyObject * -make_gen(PyTypeObject *type, PyFrameConstructor *con, InterpreterFrame *frame) +make_gen(PyTypeObject *type, PyFunctionObject *func) { - PyGenObject *gen = PyObject_GC_New(PyGenObject, type); + PyCodeObject *code = (PyCodeObject *)func->func_code; + int slots = _PyFrame_NumSlotsForCodeObject(code); + PyGenObject *gen = PyObject_GC_NewVar(PyGenObject, type, slots); if (gen == NULL) { - assert(frame->frame_obj == NULL); - _PyFrame_Clear(frame, 1); return NULL; } - gen->gi_xframe = frame; - frame->generator = (PyObject *)gen; - gen->gi_code = frame->f_code; - Py_INCREF(gen->gi_code); + gen->gi_frame_state = FRAME_CLEARED; + gen->gi_code = (PyCodeObject *)Py_NewRef(func->func_code); gen->gi_weakreflist = NULL; - gen->gi_exc_state.exc_type = NULL; gen->gi_exc_state.exc_value = NULL; - gen->gi_exc_state.exc_traceback = NULL; gen->gi_exc_state.previous_item = NULL; - if (con->fc_name != NULL) - gen->gi_name = con->fc_name; - else - gen->gi_name = gen->gi_code->co_name; - Py_INCREF(gen->gi_name); - if (con->fc_qualname != NULL) - gen->gi_qualname = con->fc_qualname; - else - gen->gi_qualname = gen->gi_name; - Py_INCREF(gen->gi_qualname); + assert(func->func_name != NULL); + gen->gi_name = Py_NewRef(func->func_name); + assert(func->func_qualname != NULL); + gen->gi_qualname = Py_NewRef(func->func_qualname); _PyObject_GC_TRACK(gen); return (PyObject *)gen; } static PyObject * -compute_cr_origin(int origin_depth); +compute_cr_origin(int origin_depth, _PyInterpreterFrame *current_frame); PyObject * -_Py_MakeCoro(PyFrameConstructor *con, InterpreterFrame *frame) +_Py_MakeCoro(PyFunctionObject *func) { - int coro_flags = ((PyCodeObject *)con->fc_code)->co_flags & + int coro_flags = ((PyCodeObject *)func->func_code)->co_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR); assert(coro_flags); if (coro_flags == CO_GENERATOR) { - return make_gen(&PyGen_Type, con, frame); + return make_gen(&PyGen_Type, func); } if (coro_flags == CO_ASYNC_GENERATOR) { PyAsyncGenObject *o; - o = (PyAsyncGenObject *)make_gen(&PyAsyncGen_Type, con, frame); + o = (PyAsyncGenObject *)make_gen(&PyAsyncGen_Type, func); if (o == NULL) { return NULL; } - o->ag_finalizer = NULL; + o->ag_origin_or_finalizer = NULL; o->ag_closed = 0; o->ag_hooks_inited = 0; o->ag_running_async = 0; return (PyObject*)o; } assert (coro_flags == CO_COROUTINE); - PyObject *coro = make_gen(&PyCoro_Type, con, frame); + PyObject *coro = make_gen(&PyCoro_Type, func); if (!coro) { return NULL; } @@ -904,16 +923,19 @@ _Py_MakeCoro(PyFrameConstructor *con, InterpreterFrame *frame) int origin_depth = tstate->coroutine_origin_tracking_depth; if (origin_depth == 0) { - ((PyCoroObject *)coro)->cr_origin = NULL; + ((PyCoroObject *)coro)->cr_origin_or_finalizer = NULL; } else { - PyObject *cr_origin = compute_cr_origin(origin_depth); - ((PyCoroObject *)coro)->cr_origin = cr_origin; + _PyInterpreterFrame *frame = tstate->cframe->current_frame; + assert(frame); + assert(_PyFrame_IsIncomplete(frame)); + frame = _PyFrame_GetFirstComplete(frame->previous); + PyObject *cr_origin = compute_cr_origin(origin_depth, frame); + ((PyCoroObject *)coro)->cr_origin_or_finalizer = cr_origin; if (!cr_origin) { Py_DECREF(coro); return NULL; } } - return coro; } @@ -921,37 +943,37 @@ static PyObject * gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f, PyObject *name, PyObject *qualname) { - PyGenObject *gen = PyObject_GC_New(PyGenObject, type); + PyCodeObject *code = f->f_frame->f_code; + int size = code->co_nlocalsplus + code->co_stacksize; + PyGenObject *gen = PyObject_GC_NewVar(PyGenObject, type, size); if (gen == NULL) { Py_DECREF(f); return NULL; } - - /* Take ownership of the frame */ + /* Copy the frame */ assert(f->f_frame->frame_obj == NULL); - assert(f->f_own_locals_memory); - gen->gi_xframe = f->f_frame; - gen->gi_xframe->frame_obj = f; - f->f_own_locals_memory = 0; - gen->gi_xframe->generator = (PyObject *) gen; + assert(f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT); + _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; + _PyFrame_Copy((_PyInterpreterFrame *)f->_f_frame_data, frame); + gen->gi_frame_state = FRAME_CREATED; + assert(frame->frame_obj == f); + f->f_frame = frame; + frame->owner = FRAME_OWNED_BY_GENERATOR; assert(PyObject_GC_IsTracked((PyObject *)f)); - gen->gi_code = PyFrame_GetCode(f); + Py_INCREF(gen->gi_code); + Py_DECREF(f); gen->gi_weakreflist = NULL; - gen->gi_exc_state.exc_type = NULL; gen->gi_exc_state.exc_value = NULL; - gen->gi_exc_state.exc_traceback = NULL; gen->gi_exc_state.previous_item = NULL; if (name != NULL) - gen->gi_name = name; + gen->gi_name = Py_NewRef(name); else - gen->gi_name = gen->gi_code->co_name; - Py_INCREF(gen->gi_name); + gen->gi_name = Py_NewRef(gen->gi_code->co_name); if (qualname != NULL) - gen->gi_qualname = qualname; + gen->gi_qualname = Py_NewRef(qualname); else - gen->gi_qualname = gen->gi_code->co_qualname; - Py_INCREF(gen->gi_qualname); + gen->gi_qualname = Py_NewRef(gen->gi_code->co_qualname); _PyObject_GC_TRACK(gen); return (PyObject *)gen; } @@ -1003,8 +1025,7 @@ _PyCoro_GetAwaitableIter(PyObject *o) if (PyCoro_CheckExact(o) || gen_is_coroutine(o)) { /* 'o' is a coroutine. */ - Py_INCREF(o); - return o; + return Py_NewRef(o); } ot = Py_TYPE(o); @@ -1051,8 +1072,7 @@ coro_await(PyCoroObject *coro) if (cw == NULL) { return NULL; } - Py_INCREF(coro); - cw->cw_coroutine = coro; + cw->cw_coroutine = (PyCoroObject*)Py_NewRef(coro); _PyObject_GC_TRACK(cw); return (PyObject *)cw; } @@ -1066,13 +1086,22 @@ coro_get_cr_await(PyCoroObject *coro, void *Py_UNUSED(ignored)) return yf; } +static PyObject * +cr_getsuspended(PyCoroObject *coro, void *Py_UNUSED(ignored)) +{ + if (coro->cr_frame_state == FRAME_SUSPENDED) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + static PyObject * cr_getrunning(PyCoroObject *coro, void *Py_UNUSED(ignored)) { - if (coro->cr_xframe == NULL) { - Py_RETURN_FALSE; + if (coro->cr_frame_state == FRAME_EXECUTING) { + Py_RETURN_TRUE; } - return PyBool_FromLong(_PyFrame_IsExecuting(coro->cr_xframe)); + Py_RETURN_FALSE; } static PyObject * @@ -1091,12 +1120,13 @@ static PyGetSetDef coro_getsetlist[] = { PyDoc_STR("object being awaited on, or None")}, {"cr_running", (getter)cr_getrunning, NULL, NULL}, {"cr_frame", (getter)cr_getframe, NULL, NULL}, + {"cr_suspended", (getter)cr_getsuspended, NULL, NULL}, {NULL} /* Sentinel */ }; static PyMemberDef coro_memberlist[] = { {"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY|PY_AUDIT_READ}, - {"cr_origin", T_OBJECT, offsetof(PyCoroObject, cr_origin), READONLY}, + {"cr_origin", T_OBJECT, offsetof(PyCoroObject, cr_origin_or_finalizer), READONLY}, {NULL} /* Sentinel */ }; @@ -1105,16 +1135,23 @@ PyDoc_STRVAR(coro_send_doc, return next iterated value or raise StopIteration."); PyDoc_STRVAR(coro_throw_doc, -"throw(typ[,val[,tb]]) -> raise exception in coroutine,\n\ -return next iterated value or raise StopIteration."); +"throw(value)\n\ +throw(type[,value[,traceback]])\n\ +\n\ +Raise exception in coroutine, return next iterated value or raise\n\ +StopIteration.\n\ +the (type, val, tb) signature is deprecated, \n\ +and may be removed in a future version of Python."); + PyDoc_STRVAR(coro_close_doc, "close() -> raise GeneratorExit inside coroutine."); static PyMethodDef coro_methods[] = { {"send",(PyCFunction)gen_send, METH_O, coro_send_doc}, - {"throw",(PyCFunction)gen_throw, METH_VARARGS, coro_throw_doc}, + {"throw",_PyCFunction_CAST(gen_throw), METH_FASTCALL, coro_throw_doc}, {"close",(PyCFunction)gen_close, METH_NOARGS, coro_close_doc}, + {"__sizeof__", (PyCFunction)gen_sizeof, METH_NOARGS, sizeof__doc__}, {NULL, NULL} /* Sentinel */ }; @@ -1128,8 +1165,9 @@ static PyAsyncMethods coro_as_async = { PyTypeObject PyCoro_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "coroutine", /* tp_name */ - sizeof(PyCoroObject), /* tp_basicsize */ - 0, /* tp_itemsize */ + offsetof(PyCoroObject, cr_iframe) + + offsetof(_PyInterpreterFrame, localsplus), /* tp_basicsize */ + sizeof(PyObject *), /* tp_itemsize */ /* methods */ (destructor)gen_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ @@ -1198,9 +1236,9 @@ coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg) } static PyObject * -coro_wrapper_throw(PyCoroWrapper *cw, PyObject *args) +coro_wrapper_throw(PyCoroWrapper *cw, PyObject *const *args, Py_ssize_t nargs) { - return gen_throw((PyGenObject *)cw->cw_coroutine, args); + return gen_throw((PyGenObject *)cw->cw_coroutine, args, nargs); } static PyObject * @@ -1218,7 +1256,8 @@ coro_wrapper_traverse(PyCoroWrapper *cw, visitproc visit, void *arg) static PyMethodDef coro_wrapper_methods[] = { {"send",(PyCFunction)coro_wrapper_send, METH_O, coro_send_doc}, - {"throw",(PyCFunction)coro_wrapper_throw, METH_VARARGS, coro_throw_doc}, + {"throw",_PyCFunction_CAST(coro_wrapper_throw), + METH_FASTCALL, coro_throw_doc}, {"close",(PyCFunction)coro_wrapper_close, METH_NOARGS, coro_close_doc}, {NULL, NULL} /* Sentinel */ }; @@ -1266,13 +1305,13 @@ PyTypeObject _PyCoroWrapper_Type = { }; static PyObject * -compute_cr_origin(int origin_depth) +compute_cr_origin(int origin_depth, _PyInterpreterFrame *current_frame) { - InterpreterFrame *frame = _PyEval_GetFrame(); + _PyInterpreterFrame *frame = current_frame; /* First count how many frames we have */ int frame_count = 0; for (; frame && frame_count < origin_depth; ++frame_count) { - frame = frame->previous; + frame = _PyFrame_GetFirstComplete(frame->previous); } /* Now collect them */ @@ -1280,19 +1319,18 @@ compute_cr_origin(int origin_depth) if (cr_origin == NULL) { return NULL; } - frame = _PyEval_GetFrame(); + frame = current_frame; for (int i = 0; i < frame_count; ++i) { PyCodeObject *code = frame->f_code; - PyObject *frameinfo = Py_BuildValue("OiO", - code->co_filename, - PyCode_Addr2Line(frame->f_code, frame->f_lasti*sizeof(_Py_CODEUNIT)), + int line = _PyInterpreterFrame_GetLine(frame); + PyObject *frameinfo = Py_BuildValue("OiO", code->co_filename, line, code->co_name); if (!frameinfo) { Py_DECREF(cr_origin); return NULL; } PyTuple_SET_ITEM(cr_origin, i, frameinfo); - frame = frame->previous; + frame = _PyFrame_GetFirstComplete(frame->previous); } return cr_origin; @@ -1310,10 +1348,10 @@ PyCoro_New(PyFrameObject *f, PyObject *name, PyObject *qualname) int origin_depth = tstate->coroutine_origin_tracking_depth; if (origin_depth == 0) { - ((PyCoroObject *)coro)->cr_origin = NULL; + ((PyCoroObject *)coro)->cr_origin_or_finalizer = NULL; } else { - PyObject *cr_origin = compute_cr_origin(origin_depth); - ((PyCoroObject *)coro)->cr_origin = cr_origin; + PyObject *cr_origin = compute_cr_origin(origin_depth, _PyEval_GetFrame()); + ((PyCoroObject *)coro)->cr_origin_or_finalizer = cr_origin; if (!cr_origin) { Py_DECREF(coro); return NULL; @@ -1374,7 +1412,7 @@ typedef struct _PyAsyncGenWrappedValue { static int async_gen_traverse(PyAsyncGenObject *gen, visitproc visit, void *arg) { - Py_VISIT(gen->ag_finalizer); + Py_VISIT(gen->ag_origin_or_finalizer); return gen_traverse((PyGenObject*)gen, visit, arg); } @@ -1404,8 +1442,7 @@ async_gen_init_hooks(PyAsyncGenObject *o) finalizer = tstate->async_gen_finalizer; if (finalizer) { - Py_INCREF(finalizer); - o->ag_finalizer = finalizer; + o->ag_origin_or_finalizer = Py_NewRef(finalizer); } firstiter = tstate->async_gen_firstiter; @@ -1457,6 +1494,14 @@ async_gen_aclose(PyAsyncGenObject *o, PyObject *arg) static PyObject * async_gen_athrow(PyAsyncGenObject *o, PyObject *args) { + if (PyTuple_GET_SIZE(args) > 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "the (type, exc, tb) signature of athrow() is deprecated, " + "use the single-arg signature instead.", + 1) < 0) { + return NULL; + } + } if (async_gen_init_hooks(o)) { return NULL; } @@ -1494,12 +1539,18 @@ PyDoc_STRVAR(async_asend_doc, "asend(v) -> send 'v' in generator."); PyDoc_STRVAR(async_athrow_doc, -"athrow(typ[,val[,tb]]) -> raise exception in generator."); +"athrow(value)\n\ +athrow(type[,value[,tb]])\n\ +\n\ +raise exception in generator.\n\ +the (type, val, tb) signature is deprecated, \n\ +and may be removed in a future version of Python."); static PyMethodDef async_gen_methods[] = { {"asend", (PyCFunction)async_gen_asend, METH_O, async_asend_doc}, {"athrow",(PyCFunction)async_gen_athrow, METH_VARARGS, async_athrow_doc}, {"aclose", (PyCFunction)async_gen_aclose, METH_NOARGS, async_aclose_doc}, + {"__sizeof__", (PyCFunction)gen_sizeof, METH_NOARGS, sizeof__doc__}, {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, {NULL, NULL} /* Sentinel */ @@ -1517,8 +1568,9 @@ static PyAsyncMethods async_gen_as_async = { PyTypeObject PyAsyncGen_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "async_generator", /* tp_name */ - sizeof(PyAsyncGenObject), /* tp_basicsize */ - 0, /* tp_itemsize */ + offsetof(PyAsyncGenObject, ag_iframe) + + offsetof(_PyInterpreterFrame, localsplus), /* tp_basicsize */ + sizeof(PyObject *), /* tp_itemsize */ /* methods */ (destructor)gen_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ @@ -1586,7 +1638,7 @@ PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname) if (o == NULL) { return NULL; } - o->ag_finalizer = NULL; + o->ag_origin_or_finalizer = NULL; o->ag_closed = 0; o->ag_hooks_inited = 0; o->ag_running_async = 0; @@ -1739,7 +1791,7 @@ async_gen_asend_iternext(PyAsyncGenASend *o) static PyObject * -async_gen_asend_throw(PyAsyncGenASend *o, PyObject *args) +async_gen_asend_throw(PyAsyncGenASend *o, PyObject *const *args, Py_ssize_t nargs) { PyObject *result; @@ -1750,7 +1802,7 @@ async_gen_asend_throw(PyAsyncGenASend *o, PyObject *args) return NULL; } - result = gen_throw((PyGenObject*)o->ags_gen, args); + result = gen_throw((PyGenObject*)o->ags_gen, args, nargs); result = async_gen_unwrap_value(o->ags_gen, result); if (result == NULL) { @@ -1771,7 +1823,7 @@ async_gen_asend_close(PyAsyncGenASend *o, PyObject *args) static PyMethodDef async_gen_asend_methods[] = { {"send", (PyCFunction)async_gen_asend_send, METH_O, send_doc}, - {"throw", (PyCFunction)async_gen_asend_throw, METH_VARARGS, throw_doc}, + {"throw", _PyCFunction_CAST(async_gen_asend_throw), METH_FASTCALL, throw_doc}, {"close", (PyCFunction)async_gen_asend_close, METH_NOARGS, close_doc}, {NULL, NULL} /* Sentinel */ }; @@ -1852,11 +1904,9 @@ async_gen_asend_new(PyAsyncGenObject *gen, PyObject *sendval) } } - Py_INCREF(gen); - o->ags_gen = gen; + o->ags_gen = (PyAsyncGenObject*)Py_NewRef(gen); - Py_XINCREF(sendval); - o->ags_sendval = sendval; + o->ags_sendval = Py_XNewRef(sendval); o->ags_state = AWAITABLE_STATE_INIT; @@ -1882,6 +1932,7 @@ async_gen_wrapped_val_dealloc(_PyAsyncGenWrappedValue *o) if (state->value_numfree < _PyAsyncGen_MAXFREELIST) { assert(_PyAsyncGenWrappedValue_CheckExact(o)); state->value_freelist[state->value_numfree++] = o; + OBJECT_STAT_INC(to_freelist); } else #endif @@ -1944,13 +1995,13 @@ PyTypeObject _PyAsyncGenWrappedValue_Type = { PyObject * -_PyAsyncGenValueWrapperNew(PyObject *val) +_PyAsyncGenValueWrapperNew(PyThreadState *tstate, PyObject *val) { _PyAsyncGenWrappedValue *o; assert(val); #if _PyAsyncGen_MAXFREELIST > 0 - struct _Py_async_gen_state *state = get_async_gen_state(); + struct _Py_async_gen_state *state = &tstate->interp->async_gen; #ifdef Py_DEBUG // _PyAsyncGenValueWrapperNew() must not be called after _PyAsyncGen_Fini() assert(state->value_numfree != -1); @@ -1958,6 +2009,7 @@ _PyAsyncGenValueWrapperNew(PyObject *val) if (state->value_numfree) { state->value_numfree--; o = state->value_freelist[state->value_numfree]; + OBJECT_STAT_INC(from_freelist); assert(_PyAsyncGenWrappedValue_CheckExact(o)); _Py_NewReference((PyObject*)o); } @@ -1970,8 +2022,7 @@ _PyAsyncGenValueWrapperNew(PyObject *val) return NULL; } } - o->agw_val = val; - Py_INCREF(val); + o->agw_val = Py_NewRef(val); _PyObject_GC_TRACK((PyObject*)o); return (PyObject*)o; } @@ -2003,7 +2054,6 @@ static PyObject * async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) { PyGenObject *gen = (PyGenObject*)o->agt_gen; - InterpreterFrame *frame = gen->gi_xframe; PyObject *retval; if (o->agt_state == AWAITABLE_STATE_CLOSED) { @@ -2013,7 +2063,7 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) return NULL; } - if (frame == NULL || _PyFrameHasCompleted(frame)) { + if (gen->gi_frame_state >= FRAME_COMPLETED) { o->agt_state = AWAITABLE_STATE_CLOSED; PyErr_SetNone(PyExc_StopIteration); return NULL; @@ -2133,7 +2183,7 @@ check_error: static PyObject * -async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args) +async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *const *args, Py_ssize_t nargs) { PyObject *retval; @@ -2144,7 +2194,7 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args) return NULL; } - retval = gen_throw((PyGenObject*)o->agt_gen, args); + retval = gen_throw((PyGenObject*)o->agt_gen, args, nargs); if (o->agt_args) { return async_gen_unwrap_value(o->agt_gen, retval); } else { @@ -2189,7 +2239,8 @@ async_gen_athrow_close(PyAsyncGenAThrow *o, PyObject *args) static PyMethodDef async_gen_athrow_methods[] = { {"send", (PyCFunction)async_gen_athrow_send, METH_O, send_doc}, - {"throw", (PyCFunction)async_gen_athrow_throw, METH_VARARGS, throw_doc}, + {"throw", _PyCFunction_CAST(async_gen_athrow_throw), + METH_FASTCALL, throw_doc}, {"close", (PyCFunction)async_gen_athrow_close, METH_NOARGS, close_doc}, {NULL, NULL} /* Sentinel */ }; @@ -2254,11 +2305,9 @@ async_gen_athrow_new(PyAsyncGenObject *gen, PyObject *args) if (o == NULL) { return NULL; } - o->agt_gen = gen; - o->agt_args = args; + o->agt_gen = (PyAsyncGenObject*)Py_NewRef(gen); + o->agt_args = Py_XNewRef(args); o->agt_state = AWAITABLE_STATE_INIT; - Py_INCREF(gen); - Py_XINCREF(args); _PyObject_GC_TRACK((PyObject*)o); return (PyObject*)o; } diff --git a/Objects/iterobject.c b/Objects/iterobject.c index 5db6bc10fb3..cfd6d0a7c95 100644 --- a/Objects/iterobject.c +++ b/Objects/iterobject.c @@ -10,8 +10,6 @@ typedef struct { PyObject *it_seq; /* Set to NULL when iterator is exhausted */ } seqiterobject; -_Py_IDENTIFIER(iter); - PyObject * PySeqIter_New(PyObject *seq) { @@ -25,8 +23,7 @@ PySeqIter_New(PyObject *seq) if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = seq; + it->it_seq = Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } @@ -106,10 +103,10 @@ static PyObject * iter_reduce(seqiterobject *it, PyObject *Py_UNUSED(ignored)) { if (it->it_seq != NULL) - return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter), + return Py_BuildValue("N(O)n", _PyEval_GetBuiltin(&_Py_ID(iter)), it->it_seq, it->it_index); else - return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter)); + return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter))); } PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); @@ -185,10 +182,8 @@ PyCallIter_New(PyObject *callable, PyObject *sentinel) it = PyObject_GC_New(calliterobject, &PyCallIter_Type); if (it == NULL) return NULL; - Py_INCREF(callable); - it->it_callable = callable; - Py_INCREF(sentinel); - it->it_sentinel = sentinel; + it->it_callable = Py_NewRef(callable); + it->it_sentinel = Py_NewRef(sentinel); _PyObject_GC_TRACK(it); return (PyObject *)it; } @@ -245,10 +240,10 @@ static PyObject * calliter_reduce(calliterobject *it, PyObject *Py_UNUSED(ignored)) { if (it->it_callable != NULL && it->it_sentinel != NULL) - return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_iter), + return Py_BuildValue("N(OO)", _PyEval_GetBuiltin(&_Py_ID(iter)), it->it_callable, it->it_sentinel); else - return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter)); + return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter))); } static PyMethodDef calliter_methods[] = { @@ -430,8 +425,13 @@ return next yielded value or raise StopIteration."); PyDoc_STRVAR(throw_doc, -"throw(typ[,val[,tb]]) -> raise exception in the wrapped iterator,\n\ -return next yielded value or raise StopIteration."); +"throw(value)\n\ +throw(typ[,val[,tb]])\n\ +\n\ +raise exception in the wrapped iterator, return next yielded value\n\ +or raise StopIteration.\n\ +the (type, val, tb) signature is deprecated, \n\ +and may be removed in a future version of Python."); PyDoc_STRVAR(close_doc, @@ -493,10 +493,8 @@ PyAnextAwaitable_New(PyObject *awaitable, PyObject *default_value) if (anext == NULL) { return NULL; } - Py_INCREF(awaitable); - anext->wrapped = awaitable; - Py_INCREF(default_value); - anext->default_value = default_value; + anext->wrapped = Py_NewRef(awaitable); + anext->default_value = Py_NewRef(default_value); _PyObject_GC_TRACK(anext); return (PyObject *)anext; } diff --git a/Objects/listobject.c b/Objects/listobject.c index be84cf9c330..6629775604b 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_interp.h" // PyInterpreterState.list +#include "pycore_list.h" // struct _Py_list_state, _PyListIterObject #include "pycore_object.h" // _PyObject_GC_TRACK() #include "pycore_tuple.h" // _PyTuple_FromArray() #include @@ -14,6 +15,8 @@ class list "PyListObject *" "&PyList_Type" #include "clinic/listobject.c.h" +_Py_DECLARE_STR(list_err, "list index out of range"); + #if PyList_MAXFREELIST > 0 static struct _Py_list_state * get_list_state(void) @@ -73,8 +76,14 @@ list_resize(PyListObject *self, Py_ssize_t newsize) if (newsize == 0) new_allocated = 0; - num_allocated_bytes = new_allocated * sizeof(PyObject *); - items = (PyObject **)PyMem_Realloc(self->ob_item, num_allocated_bytes); + if (new_allocated <= (size_t)PY_SSIZE_T_MAX / sizeof(PyObject *)) { + num_allocated_bytes = new_allocated * sizeof(PyObject *); + items = (PyObject **)PyMem_Realloc(self->ob_item, num_allocated_bytes); + } + else { + // integer overflow + items = NULL; + } if (items == NULL) { PyErr_NoMemory(); return -1; @@ -91,6 +100,12 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size) assert(self->ob_item == NULL); assert(size > 0); + /* Since the Python memory allocator has granularity of 16 bytes on 64-bit + * platforms (8 on 32-bit), there is no benefit of allocating space for + * the odd number of items, and there is no drawback of rounding the + * allocated size up to the nearest even number. + */ + size = (size + 1) & ~(size_t)1; PyObject **items = PyMem_New(PyObject*, size); if (items == NULL) { PyErr_NoMemory(); @@ -155,6 +170,7 @@ PyList_New(Py_ssize_t size) if (PyList_MAXFREELIST && state->numfree) { state->numfree--; op = state->free_list[state->numfree]; + OBJECT_STAT_INC(from_freelist); _Py_NewReference((PyObject *)op); } else @@ -223,8 +239,6 @@ valid_index(Py_ssize_t i, Py_ssize_t limit) return (size_t) i < (size_t) limit; } -static PyObject *indexerr = NULL; - PyObject * PyList_GetItem(PyObject *op, Py_ssize_t i) { @@ -233,13 +247,8 @@ PyList_GetItem(PyObject *op, Py_ssize_t i) return NULL; } if (!valid_index(i, Py_SIZE(op))) { - if (indexerr == NULL) { - indexerr = PyUnicode_FromString( - "list index out of range"); - if (indexerr == NULL) - return NULL; - } - PyErr_SetObject(PyExc_IndexError, indexerr); + _Py_DECLARE_STR(list_err, "list index out of range"); + PyErr_SetObject(PyExc_IndexError, &_Py_STR(list_err)); return NULL; } return ((PyListObject *)op) -> ob_item[i]; @@ -290,8 +299,7 @@ ins1(PyListObject *self, Py_ssize_t where, PyObject *v) items = self->ob_item; for (i = n; --i >= where; ) items[i+1] = items[i]; - Py_INCREF(v); - items[where] = v; + items[where] = Py_NewRef(v); return 0; } @@ -305,26 +313,26 @@ PyList_Insert(PyObject *op, Py_ssize_t where, PyObject *newitem) return ins1((PyListObject *)op, where, newitem); } -static int -app1(PyListObject *self, PyObject *v) +/* internal, used by _PyList_AppendTakeRef */ +int +_PyList_AppendTakeRefListResize(PyListObject *self, PyObject *newitem) { - Py_ssize_t n = PyList_GET_SIZE(self); - - assert (v != NULL); - assert((size_t)n + 1 < PY_SSIZE_T_MAX); - if (list_resize(self, n+1) < 0) + Py_ssize_t len = PyList_GET_SIZE(self); + assert(self->allocated == -1 || self->allocated == len); + if (list_resize(self, len + 1) < 0) { + Py_DECREF(newitem); return -1; - - Py_INCREF(v); - PyList_SET_ITEM(self, n, v); + } + PyList_SET_ITEM(self, len, newitem); return 0; } int PyList_Append(PyObject *op, PyObject *newitem) { - if (PyList_Check(op) && (newitem != NULL)) - return app1((PyListObject *)op, newitem); + if (PyList_Check(op) && (newitem != NULL)) { + return _PyList_AppendTakeRef((PyListObject *)op, Py_NewRef(newitem)); + } PyErr_BadInternalCall(); return -1; } @@ -356,6 +364,7 @@ list_dealloc(PyListObject *op) #endif if (state->numfree < PyList_MAXFREELIST && PyList_CheckExact(op)) { state->free_list[state->numfree++] = op; + OBJECT_STAT_INC(to_freelist); } else #endif @@ -447,17 +456,10 @@ static PyObject * list_item(PyListObject *a, Py_ssize_t i) { if (!valid_index(i, Py_SIZE(a))) { - if (indexerr == NULL) { - indexerr = PyUnicode_FromString( - "list index out of range"); - if (indexerr == NULL) - return NULL; - } - PyErr_SetObject(PyExc_IndexError, indexerr); + PyErr_SetObject(PyExc_IndexError, &_Py_STR(list_err)); return NULL; } - Py_INCREF(a->ob_item[i]); - return a->ob_item[i]; + return Py_NewRef(a->ob_item[i]); } static PyObject * @@ -478,8 +480,7 @@ list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh) dest = np->ob_item; for (i = 0; i < len; i++) { PyObject *v = src[i]; - Py_INCREF(v); - dest[i] = v; + dest[i] = Py_NewRef(v); } Py_SET_SIZE(np, len); return (PyObject *)np; @@ -534,15 +535,13 @@ list_concat(PyListObject *a, PyObject *bb) dest = np->ob_item; for (i = 0; i < Py_SIZE(a); i++) { PyObject *v = src[i]; - Py_INCREF(v); - dest[i] = v; + dest[i] = Py_NewRef(v); } src = b->ob_item; dest = np->ob_item + Py_SIZE(a); for (i = 0; i < Py_SIZE(b); i++) { PyObject *v = src[i]; - Py_INCREF(v); - dest[i] = v; + dest[i] = Py_NewRef(v); } Py_SET_SIZE(np, size); return (PyObject *)np; @@ -552,42 +551,41 @@ list_concat(PyListObject *a, PyObject *bb) static PyObject * list_repeat(PyListObject *a, Py_ssize_t n) { - Py_ssize_t i, j; - Py_ssize_t size; - PyListObject *np; - PyObject **p, **items; - PyObject *elem; - if (n < 0) - n = 0; - if (n > 0 && Py_SIZE(a) > PY_SSIZE_T_MAX / n) - return PyErr_NoMemory(); - size = Py_SIZE(a) * n; - if (size == 0) + const Py_ssize_t input_size = Py_SIZE(a); + if (input_size == 0 || n <= 0) return PyList_New(0); - np = (PyListObject *) list_new_prealloc(size); + assert(n > 0); + + if (input_size > PY_SSIZE_T_MAX / n) + return PyErr_NoMemory(); + Py_ssize_t output_size = input_size * n; + + PyListObject *np = (PyListObject *) list_new_prealloc(output_size); if (np == NULL) return NULL; - if (Py_SIZE(a) == 1) { - items = np->ob_item; - elem = a->ob_item[0]; - for (i = 0; i < n; i++) { - items[i] = elem; - Py_INCREF(elem); + PyObject **dest = np->ob_item; + if (input_size == 1) { + PyObject *elem = a->ob_item[0]; + _Py_RefcntAdd(elem, n); + PyObject **dest_end = dest + output_size; + while (dest < dest_end) { + *dest++ = elem; } } else { - p = np->ob_item; - items = a->ob_item; - for (i = 0; i < n; i++) { - for (j = 0; j < Py_SIZE(a); j++) { - *p = items[j]; - Py_INCREF(*p); - p++; - } + PyObject **src = a->ob_item; + PyObject **src_end = src + input_size; + while (src < src_end) { + _Py_RefcntAdd(*src, n); + *dest++ = *src++; } + + _Py_memory_repeat((char *)np->ob_item, sizeof(PyObject *)*output_size, + sizeof(PyObject *)*input_size); } - Py_SET_SIZE(np, size); + + Py_SET_SIZE(np, output_size); return (PyObject *) np; } @@ -712,8 +710,7 @@ list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) } for (k = 0; k < n; k++, ilow++) { PyObject *w = vitem[k]; - Py_XINCREF(w); - item[ilow] = w; + item[ilow] = Py_XNewRef(w); } for (k = norig - 1; k >= 0; --k) Py_XDECREF(recycle[k]); @@ -739,40 +736,32 @@ PyList_SetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) static PyObject * list_inplace_repeat(PyListObject *self, Py_ssize_t n) { - PyObject **items; - Py_ssize_t size, i, j, p; - - - size = PyList_GET_SIZE(self); - if (size == 0 || n == 1) { - Py_INCREF(self); - return (PyObject *)self; + Py_ssize_t input_size = PyList_GET_SIZE(self); + if (input_size == 0 || n == 1) { + return Py_NewRef(self); } if (n < 1) { (void)_list_clear(self); - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } - if (size > PY_SSIZE_T_MAX / n) { + if (input_size > PY_SSIZE_T_MAX / n) { return PyErr_NoMemory(); } + Py_ssize_t output_size = input_size * n; - if (list_resize(self, size*n) < 0) + if (list_resize(self, output_size) < 0) return NULL; - p = size; - items = self->ob_item; - for (i = 1; i < n; i++) { /* Start counting at 1, not 0 */ - for (j = 0; j < size; j++) { - PyObject *o = items[j]; - Py_INCREF(o); - items[p++] = o; - } + PyObject **items = self->ob_item; + for (Py_ssize_t j = 0; j < input_size; j++) { + _Py_RefcntAdd(items[j], n-1); } - Py_INCREF(self); - return (PyObject *)self; + _Py_memory_repeat((char *)items, sizeof(PyObject *)*output_size, + sizeof(PyObject *)*input_size); + + return Py_NewRef(self); } static int @@ -785,8 +774,7 @@ list_ass_item(PyListObject *a, Py_ssize_t i, PyObject *v) } if (v == NULL) return list_ass_slice(a, i, i+1, v); - Py_INCREF(v); - Py_SETREF(a->ob_item[i], v); + Py_SETREF(a->ob_item[i], Py_NewRef(v)); return 0; } @@ -849,9 +837,10 @@ static PyObject * list_append(PyListObject *self, PyObject *object) /*[clinic end generated code: output=7c096003a29c0eae input=43a3fe48a7066e91]*/ { - if (app1(self, object) == 0) - Py_RETURN_NONE; - return NULL; + if (_PyList_AppendTakeRef(self, Py_NewRef(object)) < 0) { + return NULL; + } + Py_RETURN_NONE; } /*[clinic input] @@ -870,7 +859,6 @@ list_extend(PyListObject *self, PyObject *iterable) PyObject *it; /* iter(v) */ Py_ssize_t m; /* size of self */ Py_ssize_t n; /* guess for size of iterable */ - Py_ssize_t mn; /* m + n */ Py_ssize_t i; PyObject *(*iternext)(PyObject *); @@ -894,7 +882,13 @@ list_extend(PyListObject *self, PyObject *iterable) /* It should not be possible to allocate a list large enough to cause an overflow on any relevant platform */ assert(m < PY_SSIZE_T_MAX - n); - if (list_resize(self, m + n) < 0) { + if (self->ob_item == NULL) { + if (list_preallocate_exact(self, n) < 0) { + return NULL; + } + Py_SET_SIZE(self, n); + } + else if (list_resize(self, m + n) < 0) { Py_DECREF(iterable); return NULL; } @@ -908,8 +902,7 @@ list_extend(PyListObject *self, PyObject *iterable) dest = self->ob_item + m; for (i = 0; i < n; i++) { PyObject *o = src[i]; - Py_INCREF(o); - dest[i] = o; + dest[i] = Py_NewRef(o); } Py_DECREF(iterable); Py_RETURN_NONE; @@ -933,10 +926,13 @@ list_extend(PyListObject *self, PyObject *iterable) * eventually run out of memory during the loop. */ } + else if (self->ob_item == NULL) { + if (n && list_preallocate_exact(self, n) < 0) + goto error; + } else { - mn = m + n; /* Make room. */ - if (list_resize(self, mn) < 0) + if (list_resize(self, m + n) < 0) goto error; /* Make the list sane again. */ Py_SET_SIZE(self, m); @@ -960,9 +956,7 @@ list_extend(PyListObject *self, PyObject *iterable) Py_SET_SIZE(self, Py_SIZE(self) + 1); } else { - int status = app1(self, item); - Py_DECREF(item); /* append creates a new ref */ - if (status < 0) + if (_PyList_AppendTakeRef(self, item) < 0) goto error; } } @@ -996,8 +990,7 @@ list_inplace_concat(PyListObject *self, PyObject *other) if (result == NULL) return result; Py_DECREF(result); - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } /*[clinic input] @@ -1029,21 +1022,29 @@ list_pop_impl(PyListObject *self, Py_ssize_t index) PyErr_SetString(PyExc_IndexError, "pop index out of range"); return NULL; } - v = self->ob_item[index]; - if (index == Py_SIZE(self) - 1) { - status = list_resize(self, Py_SIZE(self) - 1); - if (status >= 0) - return v; /* and v now owns the reference the list had */ - else - return NULL; + + PyObject **items = self->ob_item; + v = items[index]; + const Py_ssize_t size_after_pop = Py_SIZE(self) - 1; + if (size_after_pop == 0) { + Py_INCREF(v); + status = _list_clear(self); } - Py_INCREF(v); - status = list_ass_slice(self, index, index+1, (PyObject *)NULL); - if (status < 0) { - Py_DECREF(v); + else { + if ((size_after_pop - index) > 0) { + memmove(&items[index], &items[index+1], (size_after_pop - index) * sizeof(PyObject *)); + } + status = list_resize(self, size_after_pop); + } + if (status >= 0) { + return v; // and v now owns the reference the list had + } + else { + // list resize failed, need to restore + memmove(&items[index+1], &items[index], (size_after_pop - index)* sizeof(PyObject *)); + items[index] = v; return NULL; } - return v; } /* Reverse a slice of a list in place, from lo up to (exclusive) hi. */ @@ -1215,13 +1216,6 @@ struct s_MergeState { * of tuples. It may be set to safe_object_compare, but the idea is that hopefully * we can assume more, and use one of the special-case compares. */ int (*tuple_elem_compare)(PyObject *, PyObject *, MergeState *); - - /* Used by unsafe_tuple_compare to record whether the very first tuple - * elements resolved the last comparison attempt. If so, next time a - * method that may avoid PyObject_RichCompareBool() entirely is tried. - * 0 for false, 1 for true. - */ - int first_tuple_items_resolved_it; }; /* binarysort is the best method for sorting small arrays: it does @@ -1568,8 +1562,10 @@ static void merge_freemem(MergeState *ms) { assert(ms != NULL); - if (ms->a.keys != ms->temparray) + if (ms->a.keys != ms->temparray) { PyMem_Free(ms->a.keys); + ms->a.keys = NULL; + } } /* Ensure enough temp memory for 'need' array slots is available. @@ -2192,24 +2188,7 @@ unsafe_float_compare(PyObject *v, PyObject *w, MergeState *ms) * using the same pre-sort check as we use for ms->key_compare, * but run on the list [x[0] for x in L]. This allows us to optimize compares * on two levels (as long as [x[0] for x in L] is type-homogeneous.) The idea is - * that most tuple compares don't involve x[1:]. - * However, that may not be right. When it is right, we can win by calling the - * relatively cheap ms->tuple_elem_compare on the first pair of elements, to - * see whether v[0] < w[0] or w[0] < v[0]. If either are so, we're done. - * Else we proceed as in the tuple compare, comparing the remaining pairs via - * the probably more expensive PyObject_RichCompareBool(..., Py_EQ) until (if - * ever) that says "no, not equal!". Then, if we're still on the first pair, - * ms->tuple_elem_compare can resolve it, else PyObject_RichCompareBool(..., - * Py_LT) finishes the job. - * In any case, ms->first_tuple_items_resolved_it keeps track of whether the - * most recent tuple comparison was resolved by the first pair. If so, the - * next attempt starts by trying the cheap tests on the first pair again, else - * PyObject_RichCompareBool(..., Py_EQ) is used from the start. - * There are cases where PyObject_RichCompareBool(..., Py_EQ) is much cheaper! - * For example, that can return "almost immediately" if passed the same - * object twice (it special-cases object identity for Py_EQ), which can, - * potentially, be unboundedly faster than ms->tuple_elem_compare. - */ + * that most tuple compares don't involve x[1:]. */ static int unsafe_tuple_compare(PyObject *v, PyObject *w, MergeState *ms) { @@ -2225,52 +2204,26 @@ unsafe_tuple_compare(PyObject *v, PyObject *w, MergeState *ms) vt = (PyTupleObject *)v; wt = (PyTupleObject *)w; - i = 0; - if (ms->first_tuple_items_resolved_it) { - /* See whether fast compares of the first elements settle it. */ - k = ms->tuple_elem_compare(vt->ob_item[0], wt->ob_item[0], ms); - if (k) /* error, or v < w */ - return k; - k = ms->tuple_elem_compare(wt->ob_item[0], vt->ob_item[0], ms); - if (k > 0) /* w < v */ - return 0; - if (k < 0) /* error */ - return -1; - /* We have - * not (v[0] < w[0]) and not (w[0] < v[0]) - * which implies, for a total order, that the first elements are - * equal. So skip them in the loop. - */ - i = 1; - ms->first_tuple_items_resolved_it = 0; - } - /* Now first_tuple_items_resolved_it was 0 on entry, or was forced to 0 - * at the end of the `if` block just above. - */ - assert(! ms->first_tuple_items_resolved_it); vlen = Py_SIZE(vt); wlen = Py_SIZE(wt); - for (; i < vlen && i < wlen; i++) { + + for (i = 0; i < vlen && i < wlen; i++) { k = PyObject_RichCompareBool(vt->ob_item[i], wt->ob_item[i], Py_EQ); - if (!k) { /* not equal */ - if (i) { - return PyObject_RichCompareBool(vt->ob_item[i], wt->ob_item[i], - Py_LT); - } - else { - ms->first_tuple_items_resolved_it = 1; - return ms->tuple_elem_compare(vt->ob_item[0], wt->ob_item[0], - ms); - } - } if (k < 0) return -1; + if (!k) + break; } - /* all equal until we fell off the end */ - return vlen < wlen; - } + if (i >= vlen || i >= wlen) + return vlen < wlen; + + if (i == 0) + return ms->tuple_elem_compare(vt->ob_item[i], wt->ob_item[i], ms); + else + return PyObject_RichCompareBool(vt->ob_item[i], wt->ob_item[i], Py_LT); +} /* An adaptive, stable, natural mergesort. See listsort.txt. * Returns Py_None on success, NULL on error. Even in case of error, the @@ -2282,7 +2235,7 @@ list.sort * key as keyfunc: object = None - reverse: bool(accept={int}) = False + reverse: bool = False Sort the list in ascending order and return None. @@ -2297,7 +2250,7 @@ The reverse flag can be set to sort in descending order. static PyObject * list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) -/*[clinic end generated code: output=57b9f9c5e23fbe42 input=cb56cd179a713060]*/ +/*[clinic end generated code: output=57b9f9c5e23fbe42 input=a74c4cd3ec6b5c08]*/ { MergeState ms; Py_ssize_t nremaining; @@ -2453,7 +2406,6 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) } ms.key_compare = unsafe_tuple_compare; - ms.first_tuple_items_resolved_it = 1; /* be optimistic */ } } /* End of pre-sort check: ms is now set properly! */ @@ -2555,8 +2507,7 @@ keyfunc_fail: } PyMem_Free(final_ob_item); } - Py_XINCREF(result); - return result; + return Py_XNewRef(result); } #undef IFLT #undef ISLT @@ -2614,6 +2565,27 @@ PyList_AsTuple(PyObject *v) return _PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v)); } +PyObject * +_PyList_FromArraySteal(PyObject *const *src, Py_ssize_t n) +{ + if (n == 0) { + return PyList_New(0); + } + + PyListObject *list = (PyListObject *)PyList_New(n); + if (list == NULL) { + for (Py_ssize_t i = 0; i < n; i++) { + Py_DECREF(src[i]); + } + return NULL; + } + + PyObject **dst = list->ob_item; + memcpy(dst, src, n * sizeof(PyObject *)); + + return (PyObject *)list; +} + /*[clinic input] list.index @@ -2819,19 +2791,6 @@ list___init___impl(PyListObject *self, PyObject *iterable) (void)_list_clear(self); } if (iterable != NULL) { - if (_PyObject_HasLen(iterable)) { - Py_ssize_t iter_len = PyObject_Size(iterable); - if (iter_len == -1) { - if (!PyErr_ExceptionMatches(PyExc_TypeError)) { - return -1; - } - PyErr_Clear(); - } - if (iter_len > 0 && self->ob_item == NULL - && list_preallocate_exact(self, iter_len)) { - return -1; - } - } PyObject *rv = list_extend(self, iterable); if (rv == NULL) return -1; @@ -2852,8 +2811,7 @@ list_vectorcall(PyObject *type, PyObject * const*args, return NULL; } - assert(PyType_Check(type)); - PyObject *list = PyType_GenericAlloc((PyTypeObject *)type, 0); + PyObject *list = PyType_GenericAlloc(_PyType_CAST(type), 0); if (list == NULL) { return NULL; } @@ -2877,17 +2835,17 @@ static PyObject * list___sizeof___impl(PyListObject *self) /*[clinic end generated code: output=3417541f95f9a53e input=b8030a5d5ce8a187]*/ { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * sizeof(void*); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(self)); + res += (size_t)self->allocated * sizeof(void*); + return PyLong_FromSize_t(res); } static PyObject *list_iter(PyObject *seq); static PyObject *list_subscript(PyListObject*, PyObject*); static PyMethodDef list_methods[] = { - {"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, "x.__getitem__(y) <==> x[y]"}, + {"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, + PyDoc_STR("__getitem__($self, index, /)\n--\n\nReturn self[index].")}, LIST___REVERSED___METHODDEF LIST___SIZEOF___METHODDEF LIST_CLEAR_METHODDEF @@ -2957,8 +2915,7 @@ list_subscript(PyListObject* self, PyObject* item) dest = ((PyListObject *)result)->ob_item; for (cur = start, i = 0; i < slicelength; cur += (size_t)step, i++) { - it = src[cur]; - Py_INCREF(it); + it = Py_NewRef(src[cur]); dest[i] = it; } Py_SET_SIZE(result, slicelength); @@ -3113,8 +3070,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) for (cur = start, i = 0; i < slicelength; cur += (size_t)step, i++) { garbage[i] = selfitems[cur]; - ins = seqitems[i]; - Py_INCREF(ins); + ins = Py_NewRef(seqitems[i]); selfitems[cur] = ins; } @@ -3189,19 +3145,13 @@ PyTypeObject PyList_Type = { /*********************** List Iterator **************************/ -typedef struct { - PyObject_HEAD - Py_ssize_t it_index; - PyListObject *it_seq; /* Set to NULL when iterator is exhausted */ -} listiterobject; - -static void listiter_dealloc(listiterobject *); -static int listiter_traverse(listiterobject *, visitproc, void *); -static PyObject *listiter_next(listiterobject *); -static PyObject *listiter_len(listiterobject *, PyObject *); +static void listiter_dealloc(_PyListIterObject *); +static int listiter_traverse(_PyListIterObject *, visitproc, void *); +static PyObject *listiter_next(_PyListIterObject *); +static PyObject *listiter_len(_PyListIterObject *, PyObject *); static PyObject *listiter_reduce_general(void *_it, int forward); -static PyObject *listiter_reduce(listiterobject *, PyObject *); -static PyObject *listiter_setstate(listiterobject *, PyObject *state); +static PyObject *listiter_reduce(_PyListIterObject *, PyObject *); +static PyObject *listiter_setstate(_PyListIterObject *, PyObject *state); PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); @@ -3217,7 +3167,7 @@ static PyMethodDef listiter_methods[] = { PyTypeObject PyListIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "list_iterator", /* tp_name */ - sizeof(listiterobject), /* tp_basicsize */ + sizeof(_PyListIterObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)listiter_dealloc, /* tp_dealloc */ @@ -3251,24 +3201,23 @@ PyTypeObject PyListIter_Type = { static PyObject * list_iter(PyObject *seq) { - listiterobject *it; + _PyListIterObject *it; if (!PyList_Check(seq)) { PyErr_BadInternalCall(); return NULL; } - it = PyObject_GC_New(listiterobject, &PyListIter_Type); + it = PyObject_GC_New(_PyListIterObject, &PyListIter_Type); if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyListObject *)seq; + it->it_seq = (PyListObject *)Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } static void -listiter_dealloc(listiterobject *it) +listiter_dealloc(_PyListIterObject *it) { _PyObject_GC_UNTRACK(it); Py_XDECREF(it->it_seq); @@ -3276,14 +3225,14 @@ listiter_dealloc(listiterobject *it) } static int -listiter_traverse(listiterobject *it, visitproc visit, void *arg) +listiter_traverse(_PyListIterObject *it, visitproc visit, void *arg) { Py_VISIT(it->it_seq); return 0; } static PyObject * -listiter_next(listiterobject *it) +listiter_next(_PyListIterObject *it) { PyListObject *seq; PyObject *item; @@ -3297,8 +3246,7 @@ listiter_next(listiterobject *it) if (it->it_index < PyList_GET_SIZE(seq)) { item = PyList_GET_ITEM(seq, it->it_index); ++it->it_index; - Py_INCREF(item); - return item; + return Py_NewRef(item); } it->it_seq = NULL; @@ -3307,7 +3255,7 @@ listiter_next(listiterobject *it) } static PyObject * -listiter_len(listiterobject *it, PyObject *Py_UNUSED(ignored)) +listiter_len(_PyListIterObject *it, PyObject *Py_UNUSED(ignored)) { Py_ssize_t len; if (it->it_seq) { @@ -3319,13 +3267,13 @@ listiter_len(listiterobject *it, PyObject *Py_UNUSED(ignored)) } static PyObject * -listiter_reduce(listiterobject *it, PyObject *Py_UNUSED(ignored)) +listiter_reduce(_PyListIterObject *it, PyObject *Py_UNUSED(ignored)) { return listiter_reduce_general(it, 1); } static PyObject * -listiter_setstate(listiterobject *it, PyObject *state) +listiter_setstate(_PyListIterObject *it, PyObject *state) { Py_ssize_t index = PyLong_AsSsize_t(state); if (index == -1 && PyErr_Occurred()) @@ -3412,8 +3360,7 @@ list___reversed___impl(PyListObject *self) return NULL; assert(PyList_Check(self)); it->it_index = PyList_GET_SIZE(self) - 1; - Py_INCREF(self); - it->it_seq = self; + it->it_seq = (PyListObject*)Py_NewRef(self); PyObject_GC_Track(it); return (PyObject *)it; } @@ -3451,8 +3398,7 @@ listreviter_next(listreviterobject *it) if (index>=0 && index < PyList_GET_SIZE(seq)) { item = PyList_GET_ITEM(seq, index); it->it_index--; - Py_INCREF(item); - return item; + return Py_NewRef(item); } it->it_index = -1; it->it_seq = NULL; @@ -3496,25 +3442,25 @@ listreviter_setstate(listreviterobject *it, PyObject *state) static PyObject * listiter_reduce_general(void *_it, int forward) { - _Py_IDENTIFIER(iter); - _Py_IDENTIFIER(reversed); PyObject *list; /* the objects are not the same, index is of different types! */ if (forward) { - listiterobject *it = (listiterobject *)_it; - if (it->it_seq) - return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter), + _PyListIterObject *it = (_PyListIterObject *)_it; + if (it->it_seq) { + return Py_BuildValue("N(O)n", _PyEval_GetBuiltin(&_Py_ID(iter)), it->it_seq, it->it_index); + } } else { listreviterobject *it = (listreviterobject *)_it; - if (it->it_seq) - return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_reversed), + if (it->it_seq) { + return Py_BuildValue("N(O)n", _PyEval_GetBuiltin(&_Py_ID(reversed)), it->it_seq, it->it_index); + } } /* empty iterator, create an empty list */ list = PyList_New(0); if (list == NULL) return NULL; - return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list); + return Py_BuildValue("N(N)", _PyEval_GetBuiltin(&_Py_ID(iter)), list); } diff --git a/Objects/lnotab_notes.txt b/Objects/lnotab_notes.txt index e52e437c650..362b87a86a4 100644 --- a/Objects/lnotab_notes.txt +++ b/Objects/lnotab_notes.txt @@ -188,7 +188,7 @@ which compiles to this: 3 6 LOAD_GLOBAL 0 (print) 8 LOAD_CONST 1 (1) - 10 CALL_FUNCTION 1 + 10 CALL_NO_KW 1 12 POP_TOP 4 14 BREAK_LOOP @@ -197,7 +197,7 @@ which compiles to this: 6 20 LOAD_GLOBAL 0 (print) 22 LOAD_CONST 2 (2) - 24 CALL_FUNCTION 1 + 24 CALL_NO_KW 1 26 POP_TOP >> 28 LOAD_CONST 0 (None) 30 RETURN_VALUE diff --git a/Objects/locations.md b/Objects/locations.md new file mode 100644 index 00000000000..18a338a9597 --- /dev/null +++ b/Objects/locations.md @@ -0,0 +1,69 @@ +# Locations table + +For versions up to 3.10 see ./lnotab_notes.txt + +In version 3.11 the `co_linetable` bytes object of code objects contains a compact representation of the positions returned by the `co_positions()` iterator. + +The `co_linetable` consists of a sequence of location entries. +Each entry starts with a byte with the most significant bit set, followed by zero or more bytes with most significant bit unset. + +Each entry contains the following information: +* The number of code units covered by this entry (length) +* The start line +* The end line +* The start column +* The end column + +The first byte has the following format: + +Bit 7 | Bits 3-6 | Bits 0-2 + ---- | ---- | ---- + 1 | Code | Length (in code units) - 1 + +The codes are enumerated in the `_PyCodeLocationInfoKind` enum. + +## Variable length integer encodings + +Integers are often encoded using a variable length integer encoding + +### Unsigned integers (varint) + +Unsigned integers are encoded in 6 bit chunks, least significant first. +Each chunk but the last has bit 6 set. +For example: + +* 63 is encoded as `0x3f` +* 200 is encoded as `0x48`, `0x03` + +### Signed integers (svarint) + +Signed integers are encoded by converting them to unsigned integers, using the following function: +```Python +def convert(s): + if s < 0: + return ((-s)<<1) | 1 + else: + return (s<<1) +``` + +## Location entries + +The meaning of the codes and the following bytes are as follows: + +Code | Meaning | Start line | End line | Start column | End column + ---- | ---- | ---- | ---- | ---- | ---- + 0-9 | Short form | Δ 0 | Δ 0 | See below | See below + 10-12 | One line form | Δ (code - 10) | Δ 0 | unsigned byte | unsigned byte + 13 | No column info | Δ svarint | Δ 0 | None | None + 14 | Long form | Δ svarint | Δ varint | varint | varint + 15 | No location | None | None | None | None + +The Δ means the value is encoded as a delta from another value: +* Start line: Delta from the previous start line, or `co_firstlineno` for the first entry. +* End line: Delta from the start line + +### The short forms + +Codes 0-9 are the short forms. The short form consists of two bytes, the second byte holding additional column information. The code is the start column divided by 8 (and rounded down). +* Start column: `(code*8) + ((second_byte>>4)&7)` +* End column: `start_column + (second_byte&15)` diff --git a/Objects/longobject.c b/Objects/longobject.c index ce4f0d72540..51ac86961c9 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4,10 +4,12 @@ #include "Python.h" #include "pycore_bitutils.h" // _Py_popcount32() -#include "pycore_runtime.h" // _PY_NSMALLPOSINTS +#include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_long.h" // _Py_SmallInts #include "pycore_object.h" // _PyObject_InitVar() #include "pycore_pystate.h" // _Py_IsMainInterpreter() +#include "pycore_runtime.h" // _PY_NSMALLPOSINTS +#include "pycore_structseq.h" // _PyStructSequence_FiniType() #include #include @@ -20,9 +22,6 @@ class int "PyObject *" "&PyLong_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ec0275e3422a36e3]*/ -_Py_IDENTIFIER(little); -_Py_IDENTIFIER(big); - /* Is this PyLong of size 1, 0 or -1? */ #define IS_MEDIUM_VALUE(x) (((size_t)Py_SIZE(x)) + 1U < 3U) @@ -37,7 +36,21 @@ medium_value(PyLongObject *x) #define IS_SMALL_INT(ival) (-_PY_NSMALLNEGINTS <= (ival) && (ival) < _PY_NSMALLPOSINTS) #define IS_SMALL_UINT(ival) ((ival) < _PY_NSMALLPOSINTS) -static inline int is_medium_int(stwodigits x) +#define _MAX_STR_DIGITS_ERROR_FMT_TO_INT "Exceeds the limit (%d digits) for integer string conversion: value has %zd digits; use sys.set_int_max_str_digits() to increase the limit" +#define _MAX_STR_DIGITS_ERROR_FMT_TO_STR "Exceeds the limit (%d digits) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit" + +/* If defined, use algorithms from the _pylong.py module */ +#define WITH_PYLONG_MODULE 1 + +static inline void +_Py_DECREF_INT(PyLongObject *op) +{ + assert(PyLong_CheckExact(op)); + _Py_DECREF_SPECIALIZED((PyObject *)op, (destructor)PyObject_Free); +} + +static inline int +is_medium_int(stwodigits x) { /* Take care that we are comparing unsigned values. */ twodigits x_plus_mask = ((twodigits)x) + PyLong_MASK; @@ -48,9 +61,8 @@ static PyObject * get_small_int(sdigit ival) { assert(IS_SMALL_INT(ival)); - PyObject *v = (PyObject *)&_PyRuntime.small_ints[_PY_NSMALLNEGINTS + ival]; - Py_INCREF(v); - return v; + PyObject *v = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + ival]; + return Py_NewRef(v); } static PyLongObject * @@ -59,7 +71,7 @@ maybe_small_long(PyLongObject *v) if (v && IS_MEDIUM_VALUE(v)) { stwodigits ival = medium_value(v); if (IS_SMALL_INT(ival)) { - Py_DECREF(v); + _Py_DECREF_INT(v); return (PyLongObject *)get_small_int((sdigit)ival); } } @@ -73,12 +85,34 @@ maybe_small_long(PyLongObject *v) #define KARATSUBA_CUTOFF 70 #define KARATSUBA_SQUARE_CUTOFF (2 * KARATSUBA_CUTOFF) -/* For exponentiation, use the binary left-to-right algorithm - * unless the exponent contains more than FIVEARY_CUTOFF digits. - * In that case, do 5 bits at a time. The potential drawback is that - * a table of 2**5 intermediate results is computed. +/* For exponentiation, use the binary left-to-right algorithm unless the + ^ exponent contains more than HUGE_EXP_CUTOFF bits. In that case, do + * (no more than) EXP_WINDOW_SIZE bits at a time. The potential drawback is + * that a table of 2**(EXP_WINDOW_SIZE - 1) intermediate results is + * precomputed. */ -#define FIVEARY_CUTOFF 8 +#define EXP_WINDOW_SIZE 5 +#define EXP_TABLE_LEN (1 << (EXP_WINDOW_SIZE - 1)) +/* Suppose the exponent has bit length e. All ways of doing this + * need e squarings. The binary method also needs a multiply for + * each bit set. In a k-ary method with window width w, a multiply + * for each non-zero window, so at worst (and likely!) + * ceiling(e/w). The k-ary sliding window method has the same + * worst case, but the window slides so it can sometimes skip + * over an all-zero window that the fixed-window method can't + * exploit. In addition, the windowing methods need multiplies + * to precompute a table of small powers. + * + * For the sliding window method with width 5, 16 precomputation + * multiplies are needed. Assuming about half the exponent bits + * are set, then, the binary method needs about e/2 extra mults + * and the window method about 16 + e/5. + * + * The latter is smaller for e > 53 1/3. We don't have direct + * access to the bit length, though, so call it 60, which is a + * multiple of a long digit's max bit length (15 or 30 so far). + */ +#define HUGE_EXP_CUTOFF 60 #define SIGCHECK(PyTryBlock) \ do { \ @@ -233,6 +267,38 @@ _PyLong_FromSTwoDigits(stwodigits x) return _PyLong_FromLarge(x); } +int +_PyLong_AssignValue(PyObject **target, Py_ssize_t value) +{ + PyObject *old = *target; + if (IS_SMALL_INT(value)) { + *target = get_small_int(Py_SAFE_DOWNCAST(value, Py_ssize_t, sdigit)); + Py_XDECREF(old); + return 0; + } + else if (old != NULL && PyLong_CheckExact(old) && + Py_REFCNT(old) == 1 && Py_SIZE(old) == 1 && + (size_t)value <= PyLong_MASK) + { + // Mutate in place if there are no other references the old + // object. This avoids an allocation in a common case. + // Since the primary use-case is iterating over ranges, which + // are typically positive, only do this optimization + // for positive integers (for now). + ((PyLongObject *)old)->ob_digit[0] = + Py_SAFE_DOWNCAST(value, Py_ssize_t, digit); + return 0; + } + else { + *target = PyLong_FromSsize_t(value); + Py_XDECREF(old); + if (*target == NULL) { + return -1; + } + return 0; + } +} + /* If a freshly-allocated int is already shared, it must be a small integer, so negating it must go to PyLong_FromLong */ Py_LOCAL_INLINE(void) @@ -251,44 +317,40 @@ _PyLong_Negate(PyLongObject **x_p) } /* Create a new int object from a C long int */ + PyObject * PyLong_FromLong(long ival) { + PyLongObject *v; + unsigned long abs_ival, t; + int ndigits; + + /* Handle small and medium cases. */ if (IS_SMALL_INT(ival)) { return get_small_int((sdigit)ival); } - unsigned long abs_ival; - int sign; - if (ival < 0) { - /* negate: can't write this as abs_ival = -ival since that - invokes undefined behaviour when ival is LONG_MIN */ - abs_ival = 0U-(twodigits)ival; - sign = -1; - } - else { - abs_ival = (unsigned long)ival; - sign = 1; - } - /* Fast path for single-digit ints */ - if (!(abs_ival >> PyLong_SHIFT)) { + if (-(long)PyLong_MASK <= ival && ival <= (long)PyLong_MASK) { return _PyLong_FromMedium((sdigit)ival); } - /* Must be at least two digits. - * Do shift in two steps to avoid undefined behavior. */ - unsigned long t = (abs_ival >> PyLong_SHIFT) >> PyLong_SHIFT; - Py_ssize_t ndigits = 2; + + /* Count digits (at least two - smaller cases were handled above). */ + abs_ival = ival < 0 ? 0U-(unsigned long)ival : (unsigned long)ival; + /* Do shift in two steps to avoid possible undefined behavior. */ + t = abs_ival >> PyLong_SHIFT >> PyLong_SHIFT; + ndigits = 2; while (t) { ++ndigits; t >>= PyLong_SHIFT; } - PyLongObject *v = _PyLong_New(ndigits); + + /* Construct output value. */ + v = _PyLong_New(ndigits); if (v != NULL) { digit *p = v->ob_digit; - Py_SET_SIZE(v, ndigits * sign); + Py_SET_SIZE(v, ival < 0 ? -ndigits : ndigits); t = abs_ival; while (t) { - *p++ = Py_SAFE_DOWNCAST( - t & PyLong_MASK, unsigned long, digit); + *p++ = (digit)(t & PyLong_MASK); t >>= PyLong_SHIFT; } } @@ -746,7 +808,10 @@ _PyLong_Sign(PyObject *vv) static int bit_length_digit(digit x) { - Py_BUILD_ASSERT(PyLong_SHIFT <= sizeof(unsigned long) * 8); + // digit can be larger than unsigned long, but only PyLong_SHIFT bits + // of it will be ever used. + static_assert(PyLong_SHIFT <= sizeof(unsigned long) * 8, + "digit is larger than unsigned long"); return _Py_bit_length((unsigned long)x); } @@ -888,7 +953,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n, } Py_SET_SIZE(v, is_signed ? -idigit : idigit); - return (PyObject *)long_normalize(v); + return (PyObject *)maybe_small_long(long_normalize(v)); } int @@ -1084,38 +1149,32 @@ PyObject * PyLong_FromLongLong(long long ival) { PyLongObject *v; - unsigned long long abs_ival; - unsigned long long t; /* unsigned so >> doesn't propagate sign bit */ - int ndigits = 0; - int negative = 0; + unsigned long long abs_ival, t; + int ndigits; + /* Handle small and medium cases. */ if (IS_SMALL_INT(ival)) { return get_small_int((sdigit)ival); } - - if (ival < 0) { - /* avoid signed overflow on negation; see comments - in PyLong_FromLong above. */ - abs_ival = (unsigned long long)(-1-ival) + 1; - negative = 1; - } - else { - abs_ival = (unsigned long long)ival; + if (-(long long)PyLong_MASK <= ival && ival <= (long long)PyLong_MASK) { + return _PyLong_FromMedium((sdigit)ival); } - /* Count the number of Python digits. - We used to pick 5 ("big enough for anything"), but that's a - waste of time and space given that 5*15 = 75 bits are rarely - needed. */ - t = abs_ival; + /* Count digits (at least two - smaller cases were handled above). */ + abs_ival = ival < 0 ? 0U-(unsigned long long)ival : (unsigned long long)ival; + /* Do shift in two steps to avoid possible undefined behavior. */ + t = abs_ival >> PyLong_SHIFT >> PyLong_SHIFT; + ndigits = 2; while (t) { ++ndigits; t >>= PyLong_SHIFT; } + + /* Construct output value. */ v = _PyLong_New(ndigits); if (v != NULL) { digit *p = v->ob_digit; - Py_SET_SIZE(v, negative ? -ndigits : ndigits); + Py_SET_SIZE(v, ival < 0 ? -ndigits : ndigits); t = abs_ival; while (t) { *p++ = (digit)(t & PyLong_MASK); @@ -1593,25 +1652,41 @@ v_rshift(digit *z, digit *a, Py_ssize_t m, int d) in pout, and returning the remainder. pin and pout point at the LSD. It's OK for pin == pout on entry, which saves oodles of mallocs/frees in _PyLong_Format, but that should be done with great care since ints are - immutable. */ + immutable. + This version of the code can be 20% faster than the pre-2022 version + on todays compilers on architectures like amd64. It evolved from Mark + Dickinson observing that a 128:64 divide instruction was always being + generated by the compiler despite us working with 30-bit digit values. + See the thread for full context: + + https://mail.python.org/archives/list/python-dev@python.org/thread/ZICIMX5VFCX4IOFH5NUPVHCUJCQ4Q7QM/#NEUNFZU3TQU4CPTYZNF3WCN7DOJBBTK5 + + If you ever want to change this code, pay attention to performance using + different compilers, optimization levels, and cpu architectures. Beware of + PGO/FDO builds doing value specialization such as a fast path for //10. :) + + Verify that 17 isn't specialized and this works as a quick test: + python -m timeit -s 'x = 10**1000; r=x//10; assert r == 10**999, r' 'x//17' +*/ static digit inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n) { - twodigits rem = 0; + digit remainder = 0; assert(n > 0 && n <= PyLong_MASK); - pin += size; - pout += size; while (--size >= 0) { - digit hi; - rem = (rem << PyLong_SHIFT) | *--pin; - *--pout = hi = (digit)(rem / n); - rem -= (twodigits)hi * n; + twodigits dividend; + dividend = ((twodigits)remainder << PyLong_SHIFT) | pin[size]; + digit quotient; + quotient = (digit)(dividend / n); + remainder = dividend % n; + pout[size] = quotient; } - return (digit)rem; + return remainder; } + /* Divide an integer by a digit, returning both the quotient (as function result) and the remainder (through *prem). The sign of a is ignored; n should not be zero. */ @@ -1630,6 +1705,101 @@ divrem1(PyLongObject *a, digit n, digit *prem) return long_normalize(z); } +/* Remainder of long pin, w/ size digits, by non-zero digit n, + returning the remainder. pin points at the LSD. */ + +static digit +inplace_rem1(digit *pin, Py_ssize_t size, digit n) +{ + twodigits rem = 0; + + assert(n > 0 && n <= PyLong_MASK); + while (--size >= 0) + rem = ((rem << PyLong_SHIFT) | pin[size]) % n; + return (digit)rem; +} + +/* Get the remainder of an integer divided by a digit, returning + the remainder as the result of the function. The sign of a is + ignored; n should not be zero. */ + +static PyLongObject * +rem1(PyLongObject *a, digit n) +{ + const Py_ssize_t size = Py_ABS(Py_SIZE(a)); + + assert(n > 0 && n <= PyLong_MASK); + return (PyLongObject *)PyLong_FromLong( + (long)inplace_rem1(a->ob_digit, size, n) + ); +} + +#ifdef WITH_PYLONG_MODULE +/* asymptotically faster long_to_decimal_string, using _pylong.py */ +static int +pylong_int_to_decimal_string(PyObject *aa, + PyObject **p_output, + _PyUnicodeWriter *writer, + _PyBytesWriter *bytes_writer, + char **bytes_str) +{ + PyObject *s = NULL; + PyObject *mod = PyImport_ImportModule("_pylong"); + if (mod == NULL) { + return -1; + } + s = PyObject_CallMethod(mod, "int_to_decimal_string", "O", aa); + if (s == NULL) { + goto error; + } + if (!PyUnicode_Check(s)) { + PyErr_SetString(PyExc_TypeError, + "_pylong.int_to_decimal_string did not return a str"); + goto error; + } + if (writer) { + Py_ssize_t size = PyUnicode_GET_LENGTH(s); + if (_PyUnicodeWriter_Prepare(writer, size, '9') == -1) { + goto error; + } + if (_PyUnicodeWriter_WriteStr(writer, s) < 0) { + goto error; + } + goto success; + } + else if (bytes_writer) { + Py_ssize_t size = PyUnicode_GET_LENGTH(s); + const void *data = PyUnicode_DATA(s); + int kind = PyUnicode_KIND(s); + *bytes_str = _PyBytesWriter_Prepare(bytes_writer, *bytes_str, size); + if (*bytes_str == NULL) { + goto error; + } + char *p = *bytes_str; + for (Py_ssize_t i=0; i < size; i++) { + Py_UCS4 ch = PyUnicode_READ(kind, data, i); + *p++ = (char) ch; + } + (*bytes_str) = p; + goto success; + } + else { + *p_output = Py_NewRef(s); + goto success; + } + +error: + Py_DECREF(mod); + Py_XDECREF(s); + return -1; + +success: + Py_DECREF(mod); + Py_DECREF(s); + return 0; +} +#endif /* WITH_PYLONG_MODULE */ + /* Convert an integer to a base 10 string. Returns a new non-shared string. (Return value is non-shared so that callers can modify the returned value if necessary.) */ @@ -1647,7 +1817,7 @@ long_to_decimal_string_internal(PyObject *aa, digit *pout, *pin, rem, tenpow; int negative; int d; - enum PyUnicode_Kind kind; + int kind; a = (PyLongObject *)aa; if (a == NULL || !PyLong_Check(a)) { @@ -1657,6 +1827,34 @@ long_to_decimal_string_internal(PyObject *aa, size_a = Py_ABS(Py_SIZE(a)); negative = Py_SIZE(a) < 0; + /* quick and dirty pre-check for overflowing the decimal digit limit, + based on the inequality 10/3 >= log2(10) + + explanation in https://github.com/python/cpython/pull/96537 + */ + if (size_a >= 10 * _PY_LONG_MAX_STR_DIGITS_THRESHOLD + / (3 * PyLong_SHIFT) + 2) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + int max_str_digits = interp->long_state.max_str_digits; + if ((max_str_digits > 0) && + (max_str_digits / (3 * PyLong_SHIFT) <= (size_a - 11) / 10)) { + PyErr_Format(PyExc_ValueError, _MAX_STR_DIGITS_ERROR_FMT_TO_STR, + max_str_digits); + return -1; + } + } + +#if WITH_PYLONG_MODULE + if (size_a > 1000) { + /* Switch to _pylong.int_to_decimal_string(). */ + return pylong_int_to_decimal_string(aa, + p_output, + writer, + bytes_writer, + bytes_str); + } +#endif + /* quick and dirty upper bound for the number of digits required to express a in base _PyLong_DECIMAL_BASE: @@ -1716,6 +1914,17 @@ long_to_decimal_string_internal(PyObject *aa, tenpow *= 10; strlen++; } + if (strlen > _PY_LONG_MAX_STR_DIGITS_THRESHOLD) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + int max_str_digits = interp->long_state.max_str_digits; + Py_ssize_t strlen_nosign = strlen - negative; + if ((max_str_digits > 0) && (strlen_nosign > max_str_digits)) { + Py_DECREF(scratch); + PyErr_Format(PyExc_ValueError, _MAX_STR_DIGITS_ERROR_FMT_TO_STR, + max_str_digits); + return -1; + } + } if (writer) { if (_PyUnicodeWriter_Prepare(writer, strlen, '9') == -1) { Py_DECREF(scratch); @@ -1800,7 +2009,7 @@ long_to_decimal_string_internal(PyObject *aa, #undef WRITE_DIGITS #undef WRITE_UNICODE_DIGITS - Py_DECREF(scratch); + _Py_DECREF_INT(scratch); if (writer) { writer->pos += strlen; } @@ -1837,7 +2046,7 @@ long_format_binary(PyObject *aa, int base, int alternate, PyObject *v = NULL; Py_ssize_t sz; Py_ssize_t size_a; - enum PyUnicode_Kind kind; + int kind; int negative; int bits; @@ -2063,23 +2272,23 @@ unsigned char _PyLong_DigitValue[256] = { 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, }; -/* *str points to the first digit in a string of base `base` digits. base - * is a power of 2 (2, 4, 8, 16, or 32). *str is set to point to the first - * non-digit (which may be *str!). A normalized int is returned. - * The point to this routine is that it takes time linear in the number of - * string characters. +/* `start` and `end` point to the start and end of a string of base `base` + * digits. base is a power of 2 (2, 4, 8, 16, or 32). An unnormalized int is + * returned in *res. The string should be already validated by the caller and + * consists only of valid digit characters and underscores. `digits` gives the + * number of digit characters. + * + * The point to this routine is that it takes time linear in the + * number of string characters. * * Return values: * -1 on syntax error (exception needs to be set, *res is untouched) * 0 else (exception may be set, in that case *res is set to NULL) */ static int -long_from_binary_base(const char **str, int base, PyLongObject **res) +long_from_binary_base(const char *start, const char *end, Py_ssize_t digits, int base, PyLongObject **res) { - const char *p = *str; - const char *start = p; - char prev = 0; - Py_ssize_t digits = 0; + const char *p; int bits_per_char; Py_ssize_t n; PyLongObject *z; @@ -2092,26 +2301,7 @@ long_from_binary_base(const char **str, int base, PyLongObject **res) for (bits_per_char = -1; n; ++bits_per_char) { n >>= 1; } - /* count digits and set p to end-of-string */ - while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base || *p == '_') { - if (*p == '_') { - if (prev == '_') { - *str = p - 1; - return -1; - } - } else { - ++digits; - } - prev = *p; - ++p; - } - if (prev == '_') { - /* Trailing underscore not allowed. */ - *str = p - 1; - return -1; - } - *str = p; /* n <- the number of Python digits needed, = ceiling((digits * bits_per_char) / PyLong_SHIFT). */ if (digits > (PY_SSIZE_T_MAX - (PyLong_SHIFT - 1)) / bits_per_char) { @@ -2132,6 +2322,7 @@ long_from_binary_base(const char **str, int base, PyLongObject **res) accum = 0; bits_in_accum = 0; pdigit = z->ob_digit; + p = end; while (--p >= start) { int k; if (*p == '_') { @@ -2156,87 +2347,50 @@ long_from_binary_base(const char **str, int base, PyLongObject **res) } while (pdigit - z->ob_digit < n) *pdigit++ = 0; - *res = long_normalize(z); + *res = z; return 0; } -/* Parses an int from a bytestring. Leading and trailing whitespace will be - * ignored. - * - * If successful, a PyLong object will be returned and 'pend' will be pointing - * to the first unused byte unless it's NULL. - * - * If unsuccessful, NULL will be returned. - */ -PyObject * -PyLong_FromString(const char *str, char **pend, int base) +static PyObject *long_neg(PyLongObject *v); + +#ifdef WITH_PYLONG_MODULE +/* asymptotically faster str-to-long conversion for base 10, using _pylong.py */ +static int +pylong_int_from_string(const char *start, const char *end, PyLongObject **res) { - int sign = 1, error_if_nonzero = 0; - const char *start, *orig_str = str; - PyLongObject *z = NULL; - PyObject *strobj; - Py_ssize_t slen; + PyObject *mod = PyImport_ImportModule("_pylong"); + if (mod == NULL) { + goto error; + } + PyObject *s = PyUnicode_FromStringAndSize(start, end-start); + if (s == NULL) { + Py_DECREF(mod); + goto error; + } + PyObject *result = PyObject_CallMethod(mod, "int_from_string", "O", s); + Py_DECREF(s); + Py_DECREF(mod); + if (result == NULL) { + goto error; + } + if (!PyLong_Check(result)) { + Py_DECREF(result); + PyErr_SetString(PyExc_TypeError, + "_pylong.int_from_string did not return an int"); + goto error; + } + *res = (PyLongObject *)result; + return 0; +error: + *res = NULL; + return 0; // See the long_from_string_base() API comment. +} +#endif /* WITH_PYLONG_MODULE */ - if ((base != 0 && base < 2) || base > 36) { - PyErr_SetString(PyExc_ValueError, - "int() arg 2 must be >= 2 and <= 36"); - return NULL; - } - while (*str != '\0' && Py_ISSPACE(*str)) { - str++; - } - if (*str == '+') { - ++str; - } - else if (*str == '-') { - ++str; - sign = -1; - } - if (base == 0) { - if (str[0] != '0') { - base = 10; - } - else if (str[1] == 'x' || str[1] == 'X') { - base = 16; - } - else if (str[1] == 'o' || str[1] == 'O') { - base = 8; - } - else if (str[1] == 'b' || str[1] == 'B') { - base = 2; - } - else { - /* "old" (C-style) octal literal, now invalid. - it might still be zero though */ - error_if_nonzero = 1; - base = 10; - } - } - if (str[0] == '0' && - ((base == 16 && (str[1] == 'x' || str[1] == 'X')) || - (base == 8 && (str[1] == 'o' || str[1] == 'O')) || - (base == 2 && (str[1] == 'b' || str[1] == 'B')))) { - str += 2; - /* One underscore allowed here. */ - if (*str == '_') { - ++str; - } - } - if (str[0] == '_') { - /* May not start with underscores. */ - goto onError; - } - - start = str; - if ((base & (base - 1)) == 0) { - int res = long_from_binary_base(&str, base, &z); - if (res < 0) { - /* Syntax error. */ - goto onError; - } - } - else { /*** +long_from_non_binary_base: parameters and return values are the same as +long_from_binary_base. + Binary bases can be converted in time linear in the number of digits, because Python's representation base is binary. Other bases (including decimal!) use the simple quadratic-time algorithm below, complicated by some speed tricks. @@ -2321,160 +2475,317 @@ that triggers it(!). Instead the code was tested by artificially allocating just 1 digit at the start, so that the copying code was exercised for every digit beyond the first. ***/ - twodigits c; /* current input character */ - Py_ssize_t size_z; - Py_ssize_t digits = 0; - int i; - int convwidth; - twodigits convmultmax, convmult; - digit *pz, *pzstop; - const char *scan, *lastdigit; - char prev = 0; +static int +long_from_non_binary_base(const char *start, const char *end, Py_ssize_t digits, int base, PyLongObject **res) +{ + twodigits c; /* current input character */ + Py_ssize_t size_z; + int i; + int convwidth; + twodigits convmultmax, convmult; + digit *pz, *pzstop; + PyLongObject *z; + const char *p; - static double log_base_BASE[37] = {0.0e0,}; - static int convwidth_base[37] = {0,}; - static twodigits convmultmax_base[37] = {0,}; + static double log_base_BASE[37] = {0.0e0,}; + static int convwidth_base[37] = {0,}; + static twodigits convmultmax_base[37] = {0,}; - if (log_base_BASE[base] == 0.0) { - twodigits convmax = base; - int i = 1; + if (log_base_BASE[base] == 0.0) { + twodigits convmax = base; + int i = 1; - log_base_BASE[base] = (log((double)base) / - log((double)PyLong_BASE)); - for (;;) { - twodigits next = convmax * base; - if (next > PyLong_BASE) { - break; - } - convmax = next; - ++i; + log_base_BASE[base] = (log((double)base) / + log((double)PyLong_BASE)); + for (;;) { + twodigits next = convmax * base; + if (next > PyLong_BASE) { + break; } - convmultmax_base[base] = convmax; - assert(i > 0); - convwidth_base[base] = i; + convmax = next; + ++i; } + convmultmax_base[base] = convmax; + assert(i > 0); + convwidth_base[base] = i; + } - /* Find length of the string of numeric characters. */ - scan = str; - lastdigit = str; + /* Create an int object that can contain the largest possible + * integer with this base and length. Note that there's no + * need to initialize z->ob_digit -- no slot is read up before + * being stored into. + */ + double fsize_z = (double)digits * log_base_BASE[base] + 1.0; + if (fsize_z > (double)MAX_LONG_DIGITS) { + /* The same exception as in _PyLong_New(). */ + PyErr_SetString(PyExc_OverflowError, + "too many digits in integer"); + *res = NULL; + return 0; + } + size_z = (Py_ssize_t)fsize_z; + /* Uncomment next line to test exceedingly rare copy code */ + /* size_z = 1; */ + assert(size_z > 0); + z = _PyLong_New(size_z); + if (z == NULL) { + *res = NULL; + return 0; + } + Py_SET_SIZE(z, 0); - while (_PyLong_DigitValue[Py_CHARMASK(*scan)] < base || *scan == '_') { - if (*scan == '_') { - if (prev == '_') { - /* Only one underscore allowed. */ - str = lastdigit + 1; - goto onError; - } - } - else { - ++digits; - lastdigit = scan; - } - prev = *scan; - ++scan; + /* `convwidth` consecutive input digits are treated as a single + * digit in base `convmultmax`. + */ + convwidth = convwidth_base[base]; + convmultmax = convmultmax_base[base]; + + /* Work ;-) */ + p = start; + while (p < end) { + if (*p == '_') { + p++; + continue; } - if (prev == '_') { - /* Trailing underscore not allowed. */ - /* Set error pointer to first underscore. */ - str = lastdigit + 1; - goto onError; - } - - /* Create an int object that can contain the largest possible - * integer with this base and length. Note that there's no - * need to initialize z->ob_digit -- no slot is read up before - * being stored into. - */ - double fsize_z = (double)digits * log_base_BASE[base] + 1.0; - if (fsize_z > (double)MAX_LONG_DIGITS) { - /* The same exception as in _PyLong_New(). */ - PyErr_SetString(PyExc_OverflowError, - "too many digits in integer"); - return NULL; - } - size_z = (Py_ssize_t)fsize_z; - /* Uncomment next line to test exceedingly rare copy code */ - /* size_z = 1; */ - assert(size_z > 0); - z = _PyLong_New(size_z); - if (z == NULL) { - return NULL; - } - Py_SET_SIZE(z, 0); - - /* `convwidth` consecutive input digits are treated as a single - * digit in base `convmultmax`. - */ - convwidth = convwidth_base[base]; - convmultmax = convmultmax_base[base]; - - /* Work ;-) */ - while (str < scan) { - if (*str == '_') { - str++; + /* grab up to convwidth digits from the input string */ + c = (digit)_PyLong_DigitValue[Py_CHARMASK(*p++)]; + for (i = 1; i < convwidth && p != end; ++p) { + if (*p == '_') { continue; } - /* grab up to convwidth digits from the input string */ - c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)]; - for (i = 1; i < convwidth && str != scan; ++str) { - if (*str == '_') { - continue; - } - i++; - c = (twodigits)(c * base + - (int)_PyLong_DigitValue[Py_CHARMASK(*str)]); - assert(c < PyLong_BASE); - } + i++; + c = (twodigits)(c * base + + (int)_PyLong_DigitValue[Py_CHARMASK(*p)]); + assert(c < PyLong_BASE); + } - convmult = convmultmax; - /* Calculate the shift only if we couldn't get - * convwidth digits. - */ - if (i != convwidth) { - convmult = base; - for ( ; i > 1; --i) { - convmult *= base; - } + convmult = convmultmax; + /* Calculate the shift only if we couldn't get + * convwidth digits. + */ + if (i != convwidth) { + convmult = base; + for ( ; i > 1; --i) { + convmult *= base; } + } - /* Multiply z by convmult, and add c. */ - pz = z->ob_digit; - pzstop = pz + Py_SIZE(z); - for (; pz < pzstop; ++pz) { - c += (twodigits)*pz * convmult; - *pz = (digit)(c & PyLong_MASK); - c >>= PyLong_SHIFT; + /* Multiply z by convmult, and add c. */ + pz = z->ob_digit; + pzstop = pz + Py_SIZE(z); + for (; pz < pzstop; ++pz) { + c += (twodigits)*pz * convmult; + *pz = (digit)(c & PyLong_MASK); + c >>= PyLong_SHIFT; + } + /* carry off the current end? */ + if (c) { + assert(c < PyLong_BASE); + if (Py_SIZE(z) < size_z) { + *pz = (digit)c; + Py_SET_SIZE(z, Py_SIZE(z) + 1); } - /* carry off the current end? */ - if (c) { - assert(c < PyLong_BASE); - if (Py_SIZE(z) < size_z) { - *pz = (digit)c; - Py_SET_SIZE(z, Py_SIZE(z) + 1); - } - else { - PyLongObject *tmp; - /* Extremely rare. Get more space. */ - assert(Py_SIZE(z) == size_z); - tmp = _PyLong_New(size_z + 1); - if (tmp == NULL) { - Py_DECREF(z); - return NULL; - } - memcpy(tmp->ob_digit, - z->ob_digit, - sizeof(digit) * size_z); + else { + PyLongObject *tmp; + /* Extremely rare. Get more space. */ + assert(Py_SIZE(z) == size_z); + tmp = _PyLong_New(size_z + 1); + if (tmp == NULL) { Py_DECREF(z); - z = tmp; - z->ob_digit[size_z] = (digit)c; - ++size_z; + *res = NULL; + return 0; } + memcpy(tmp->ob_digit, + z->ob_digit, + sizeof(digit) * size_z); + Py_SETREF(z, tmp); + z->ob_digit[size_z] = (digit)c; + ++size_z; } } } - if (z == NULL) { + *res = z; + return 0; +} + +/* *str points to the first digit in a string of base `base` digits. base is an + * integer from 2 to 36 inclusive. Here we don't need to worry about prefixes + * like 0x or leading +- signs. The string should be null terminated consisting + * of ASCII digits and separating underscores possibly with trailing whitespace + * but we have to validate all of those points here. + * + * If base is a power of 2 then the complexity is linear in the number of + * characters in the string. Otherwise a quadratic algorithm is used for + * non-binary bases. + * + * Return values: + * + * - Returns -1 on syntax error (exception needs to be set, *res is untouched) + * - Returns 0 and sets *res to NULL for MemoryError, OverflowError, or + * _pylong.int_from_string() errors. + * - Returns 0 and sets *res to an unsigned, unnormalized PyLong (success!). + * + * Afterwards *str is set to point to the first non-digit (which may be *str!). + */ +static int +long_from_string_base(const char **str, int base, PyLongObject **res) +{ + const char *start, *end, *p; + char prev = 0; + Py_ssize_t digits = 0; + int is_binary_base = (base & (base - 1)) == 0; + + /* Here we do four things: + * + * - Find the `end` of the string. + * - Validate the string. + * - Count the number of `digits` (rather than underscores) + * - Point *str to the end-of-string or first invalid character. + */ + start = p = *str; + /* Leading underscore not allowed. */ + if (*start == '_') { + return -1; + } + /* Verify all characters are digits and underscores. */ + while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base || *p == '_') { + if (*p == '_') { + /* Double underscore not allowed. */ + if (prev == '_') { + *str = p - 1; + return -1; + } + } else { + ++digits; + } + prev = *p; + ++p; + } + /* Trailing underscore not allowed. */ + if (prev == '_') { + *str = p - 1; + return -1; + } + *str = end = p; + /* Reject empty strings */ + if (start == end) { + return -1; + } + /* Allow only trailing whitespace after `end` */ + while (*p && Py_ISSPACE(*p)) { + p++; + } + *str = p; + if (*p != '\0') { + return -1; + } + + /* + * Pass a validated string consisting of only valid digits and underscores + * to long_from_xxx_base. + */ + if (is_binary_base) { + /* Use the linear algorithm for binary bases. */ + return long_from_binary_base(start, end, digits, base, res); + } + else { + /* Limit the size to avoid excessive computation attacks exploiting the + * quadratic algorithm. */ + if (digits > _PY_LONG_MAX_STR_DIGITS_THRESHOLD) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + int max_str_digits = interp->long_state.max_str_digits; + if ((max_str_digits > 0) && (digits > max_str_digits)) { + PyErr_Format(PyExc_ValueError, _MAX_STR_DIGITS_ERROR_FMT_TO_INT, + max_str_digits, digits); + *res = NULL; + return 0; + } + } +#if WITH_PYLONG_MODULE + if (digits > 6000 && base == 10) { + /* Switch to _pylong.int_from_string() */ + return pylong_int_from_string(start, end, res); + } +#endif + /* Use the quadratic algorithm for non binary bases. */ + return long_from_non_binary_base(start, end, digits, base, res); + } +} + +/* Parses an int from a bytestring. Leading and trailing whitespace will be + * ignored. + * + * If successful, a PyLong object will be returned and 'pend' will be pointing + * to the first unused byte unless it's NULL. + * + * If unsuccessful, NULL will be returned. + */ +PyObject * +PyLong_FromString(const char *str, char **pend, int base) +{ + int sign = 1, error_if_nonzero = 0; + const char *orig_str = str; + PyLongObject *z = NULL; + PyObject *strobj; + Py_ssize_t slen; + + if ((base != 0 && base < 2) || base > 36) { + PyErr_SetString(PyExc_ValueError, + "int() arg 2 must be >= 2 and <= 36"); return NULL; } + while (*str != '\0' && Py_ISSPACE(*str)) { + ++str; + } + if (*str == '+') { + ++str; + } + else if (*str == '-') { + ++str; + sign = -1; + } + if (base == 0) { + if (str[0] != '0') { + base = 10; + } + else if (str[1] == 'x' || str[1] == 'X') { + base = 16; + } + else if (str[1] == 'o' || str[1] == 'O') { + base = 8; + } + else if (str[1] == 'b' || str[1] == 'B') { + base = 2; + } + else { + /* "old" (C-style) octal literal, now invalid. + it might still be zero though */ + error_if_nonzero = 1; + base = 10; + } + } + if (str[0] == '0' && + ((base == 16 && (str[1] == 'x' || str[1] == 'X')) || + (base == 8 && (str[1] == 'o' || str[1] == 'O')) || + (base == 2 && (str[1] == 'b' || str[1] == 'B')))) { + str += 2; + /* One underscore allowed here. */ + if (*str == '_') { + ++str; + } + } + + /* long_from_string_base is the main workhorse here. */ + int ret = long_from_string_base(&str, base, &z); + if (ret == -1) { + /* Syntax error. */ + goto onError; + } + if (z == NULL) { + /* Error. exception already set. */ + return NULL; + } + if (error_if_nonzero) { /* reset the base to 0, else the exception message doesn't make too much sense */ @@ -2485,23 +2796,14 @@ digit beyond the first. /* there might still be other problems, therefore base remains zero here for the same reason */ } - if (str == start) { - goto onError; - } + + /* Set sign and normalize */ if (sign < 0) { Py_SET_SIZE(z, -(Py_SIZE(z))); } - while (*str && Py_ISSPACE(*str)) { - str++; - } - if (*str != '\0') { - goto onError; - } long_normalize(z); z = maybe_small_long(z); - if (z == NULL) { - return NULL; - } + if (pend != NULL) { *pend = (char *)str; } @@ -2606,8 +2908,7 @@ long_divrem(PyLongObject *a, PyLongObject *b, return -1; } PyObject *zero = _PyLong_GetZero(); - Py_INCREF(zero); - *pdiv = (PyLongObject*)zero; + *pdiv = (PyLongObject*)Py_NewRef(zero); return 0; } if (size_b == 1) { @@ -2623,6 +2924,7 @@ long_divrem(PyLongObject *a, PyLongObject *b, } else { z = x_divrem(a, b, prem); + *prem = maybe_small_long(*prem); if (z == NULL) return -1; } @@ -2649,6 +2951,48 @@ long_divrem(PyLongObject *a, PyLongObject *b, return 0; } +/* Int remainder, top-level routine */ + +static int +long_rem(PyLongObject *a, PyLongObject *b, PyLongObject **prem) +{ + Py_ssize_t size_a = Py_ABS(Py_SIZE(a)), size_b = Py_ABS(Py_SIZE(b)); + + if (size_b == 0) { + PyErr_SetString(PyExc_ZeroDivisionError, + "integer modulo by zero"); + return -1; + } + if (size_a < size_b || + (size_a == size_b && + a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) { + /* |a| < |b|. */ + *prem = (PyLongObject *)long_long((PyObject *)a); + return -(*prem == NULL); + } + if (size_b == 1) { + *prem = rem1(a, b->ob_digit[0]); + if (*prem == NULL) + return -1; + } + else { + /* Slow path using divrem. */ + Py_XDECREF(x_divrem(a, b, prem)); + *prem = maybe_small_long(*prem); + if (*prem == NULL) + return -1; + } + /* Set the sign. */ + if (Py_SIZE(a) < 0 && Py_SIZE(*prem) != 0) { + _PyLong_Negate(prem); + if (*prem == NULL) { + Py_CLEAR(*prem); + return -1; + } + } + return 0; +} + /* Unsigned int division with remainder -- the algorithm. The arguments v1 and w1 should satisfy 2 <= Py_ABS(Py_SIZE(w1)) <= Py_ABS(Py_SIZE(v1)). */ @@ -2727,8 +3071,15 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) vtop = vk[size_w]; assert(vtop <= wm1); vv = ((twodigits)vtop << PyLong_SHIFT) | vk[size_w-1]; + /* The code used to compute the remainder via + * r = (digit)(vv - (twodigits)wm1 * q); + * and compilers generally generated code to do the * and -. + * But modern processors generally compute q and r with a single + * instruction, and modern optimizing compilers exploit that if we + * _don't_ try to optimize it. + */ q = (digit)(vv / wm1); - r = (digit)(vv - (twodigits)wm1 * q); /* r = vv % wm1 */ + r = (digit)(vv % wm1); while ((twodigits)wm2 * q > (((twodigits)r << PyLong_SHIFT) | vk[size_w-2])) { --q; @@ -3214,12 +3565,12 @@ x_mul(PyLongObject *a, PyLongObject *b) * via exploiting that each entry in the multiplication * pyramid appears twice (except for the size_a squares). */ + digit *paend = a->ob_digit + size_a; for (i = 0; i < size_a; ++i) { twodigits carry; twodigits f = a->ob_digit[i]; digit *pz = z->ob_digit + (i << 1); digit *pa = a->ob_digit + i + 1; - digit *paend = a->ob_digit + size_a; SIGCHECK({ Py_DECREF(z); @@ -3242,13 +3593,27 @@ x_mul(PyLongObject *a, PyLongObject *b) assert(carry <= (PyLong_MASK << 1)); } if (carry) { + /* See comment below. pz points at the highest possible + * carry position from the last outer loop iteration, so + * *pz is at most 1. + */ + assert(*pz <= 1); carry += *pz; - *pz++ = (digit)(carry & PyLong_MASK); + *pz = (digit)(carry & PyLong_MASK); carry >>= PyLong_SHIFT; + if (carry) { + /* If there's still a carry, it must be into a position + * that still holds a 0. Where the base + ^ B is 1 << PyLong_SHIFT, the last add was of a carry no + * more than 2*B - 2 to a stored digit no more than 1. + * So the sum was no more than 2*B - 1, so the current + * carry no more than floor((2*B - 1)/B) = 1. + */ + assert(carry == 1); + assert(pz[1] == 0); + pz[1] = (digit)carry; + } } - if (carry) - *pz += (digit)(carry & PyLong_MASK); - assert((carry >> PyLong_SHIFT) == 0); } } else { /* a is not the same as b -- gradeschool int mult */ @@ -3378,10 +3743,8 @@ k_mul(PyLongObject *a, PyLongObject *b) assert(Py_SIZE(ah) > 0); /* the split isn't degenerate */ if (a == b) { - bh = ah; - bl = al; - Py_INCREF(bh); - Py_INCREF(bl); + bh = (PyLongObject*)Py_NewRef(ah); + bl = (PyLongObject*)Py_NewRef(al); } else if (kmul_split(b, shift, &bh, &bl) < 0) goto fail; @@ -3441,32 +3804,31 @@ k_mul(PyLongObject *a, PyLongObject *b) */ i = Py_SIZE(ret) - shift; /* # digits after shift */ (void)v_isub(ret->ob_digit + shift, i, t2->ob_digit, Py_SIZE(t2)); - Py_DECREF(t2); + _Py_DECREF_INT(t2); (void)v_isub(ret->ob_digit + shift, i, t1->ob_digit, Py_SIZE(t1)); - Py_DECREF(t1); + _Py_DECREF_INT(t1); /* 6. t3 <- (ah+al)(bh+bl), and add into result. */ if ((t1 = x_add(ah, al)) == NULL) goto fail; - Py_DECREF(ah); - Py_DECREF(al); + _Py_DECREF_INT(ah); + _Py_DECREF_INT(al); ah = al = NULL; if (a == b) { - t2 = t1; - Py_INCREF(t2); + t2 = (PyLongObject*)Py_NewRef(t1); } else if ((t2 = x_add(bh, bl)) == NULL) { Py_DECREF(t1); goto fail; } - Py_DECREF(bh); - Py_DECREF(bl); + _Py_DECREF_INT(bh); + _Py_DECREF_INT(bl); bh = bl = NULL; t3 = k_mul(t1, t2); - Py_DECREF(t1); - Py_DECREF(t2); + _Py_DECREF_INT(t1); + _Py_DECREF_INT(t2); if (t3 == NULL) goto fail; assert(Py_SIZE(t3) >= 0); @@ -3474,7 +3836,7 @@ k_mul(PyLongObject *a, PyLongObject *b) * See the (*) comment after this function. */ (void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, Py_SIZE(t3)); - Py_DECREF(t3); + _Py_DECREF_INT(t3); return long_normalize(ret); @@ -3579,13 +3941,13 @@ k_lopsided_mul(PyLongObject *a, PyLongObject *b) /* Add into result. */ (void)v_iadd(ret->ob_digit + nbdone, Py_SIZE(ret) - nbdone, product->ob_digit, Py_SIZE(product)); - Py_DECREF(product); + _Py_DECREF_INT(product); bsize -= nbtouse; nbdone += nbtouse; } - Py_DECREF(bslice); + _Py_DECREF_INT(bslice); return long_normalize(ret); fail: @@ -3668,6 +4030,46 @@ fast_floor_div(PyLongObject *a, PyLongObject *b) return PyLong_FromLong(div); } +#ifdef WITH_PYLONG_MODULE +/* asymptotically faster divmod, using _pylong.py */ +static int +pylong_int_divmod(PyLongObject *v, PyLongObject *w, + PyLongObject **pdiv, PyLongObject **pmod) +{ + PyObject *mod = PyImport_ImportModule("_pylong"); + if (mod == NULL) { + return -1; + } + PyObject *result = PyObject_CallMethod(mod, "int_divmod", "OO", v, w); + Py_DECREF(mod); + if (result == NULL) { + return -1; + } + if (!PyTuple_Check(result)) { + Py_DECREF(result); + PyErr_SetString(PyExc_ValueError, + "tuple is required from int_divmod()"); + return -1; + } + PyObject *q = PyTuple_GET_ITEM(result, 0); + PyObject *r = PyTuple_GET_ITEM(result, 1); + if (!PyLong_Check(q) || !PyLong_Check(r)) { + Py_DECREF(result); + PyErr_SetString(PyExc_ValueError, + "tuple of int is required from int_divmod()"); + return -1; + } + if (pdiv != NULL) { + *pdiv = (PyLongObject *)Py_NewRef(q); + } + if (pmod != NULL) { + *pmod = (PyLongObject *)Py_NewRef(r); + } + Py_DECREF(result); + return 0; +} +#endif /* WITH_PYLONG_MODULE */ + /* The / and % operators are now defined in terms of divmod(). The expression a mod b has the value a - b*floor(a/b). The long_divrem function gives the remainder after division of @@ -3719,14 +4121,25 @@ l_divmod(PyLongObject *v, PyLongObject *w, } return 0; } +#if WITH_PYLONG_MODULE + Py_ssize_t size_v = Py_ABS(Py_SIZE(v)); /* digits in numerator */ + Py_ssize_t size_w = Py_ABS(Py_SIZE(w)); /* digits in denominator */ + if (size_w > 300 && (size_v - size_w) > 150) { + /* Switch to _pylong.int_divmod(). If the quotient is small then + "schoolbook" division is linear-time so don't use in that case. + These limits are empirically determined and should be slightly + conservative so that _pylong is used in cases it is likely + to be faster. See Tools/scripts/divmod_threshold.py. */ + return pylong_int_divmod(v, w, pdiv, pmod); + } +#endif if (long_divrem(v, w, &div, &mod) < 0) return -1; if ((Py_SIZE(mod) < 0 && Py_SIZE(w) > 0) || (Py_SIZE(mod) > 0 && Py_SIZE(w) < 0)) { PyLongObject *temp; temp = (PyLongObject *) long_add(mod, w); - Py_DECREF(mod); - mod = temp; + Py_SETREF(mod, temp); if (mod == NULL) { Py_DECREF(div); return -1; @@ -3737,8 +4150,7 @@ l_divmod(PyLongObject *v, PyLongObject *w, Py_DECREF(div); return -1; } - Py_DECREF(div); - div = temp; + Py_SETREF(div, temp); } if (pdiv != NULL) *pdiv = div; @@ -3753,6 +4165,36 @@ l_divmod(PyLongObject *v, PyLongObject *w, return 0; } +/* Compute + * *pmod = v % w + * pmod cannot be NULL. The caller owns a reference to pmod. + */ +static int +l_mod(PyLongObject *v, PyLongObject *w, PyLongObject **pmod) +{ + PyLongObject *mod; + + assert(pmod); + if (Py_ABS(Py_SIZE(v)) == 1 && Py_ABS(Py_SIZE(w)) == 1) { + /* Fast path for single-digit longs */ + *pmod = (PyLongObject *)fast_mod(v, w); + return -(*pmod == NULL); + } + if (long_rem(v, w, &mod) < 0) + return -1; + if ((Py_SIZE(mod) < 0 && Py_SIZE(w) > 0) || + (Py_SIZE(mod) > 0 && Py_SIZE(w) < 0)) { + PyLongObject *temp; + temp = (PyLongObject *) long_add(mod, w); + Py_SETREF(mod, temp); + if (mod == NULL) + return -1; + } + *pmod = mod; + + return 0; +} + static PyObject * long_div(PyObject *a, PyObject *b) { @@ -3984,8 +4426,7 @@ long_true_divide(PyObject *v, PyObject *w) else { PyLongObject *div, *rem; div = x_divrem(x, b, &rem); - Py_DECREF(x); - x = div; + Py_SETREF(x, div); if (x == NULL) goto error; if (Py_SIZE(rem)) @@ -4039,11 +4480,7 @@ long_mod(PyObject *a, PyObject *b) CHECK_BINOP(a, b); - if (Py_ABS(Py_SIZE(a)) == 1 && Py_ABS(Py_SIZE(b)) == 1) { - return fast_mod((PyLongObject*)a, (PyLongObject*)b); - } - - if (l_divmod((PyLongObject*)a, (PyLongObject*)b, NULL, &mod) < 0) + if (l_mod((PyLongObject*)a, (PyLongObject*)b, &mod) < 0) mod = NULL; return (PyObject *)mod; } @@ -4119,8 +4556,7 @@ long_invmod(PyLongObject *a, PyLongObject *n) if (l_divmod(a, n, &q, &r) == -1) { goto Error; } - Py_DECREF(a); - a = n; + Py_SETREF(a, n); n = r; t = (PyLongObject *)long_mul(q, c); Py_DECREF(q); @@ -4132,8 +4568,7 @@ long_invmod(PyLongObject *a, PyLongObject *n) if (s == NULL) { goto Error; } - Py_DECREF(b); - b = c; + Py_SETREF(b, c); c = s; } /* references now owned: a, b, c, n */ @@ -4171,22 +4606,27 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) int negativeOutput = 0; /* if x<0 return negative output */ PyLongObject *z = NULL; /* accumulated result */ - Py_ssize_t i, j, k; /* counters */ + Py_ssize_t i, j; /* counters */ PyLongObject *temp = NULL; + PyLongObject *a2 = NULL; /* may temporarily hold a**2 % c */ - /* 5-ary values. If the exponent is large enough, table is - * precomputed so that table[i] == a**i % c for i in range(32). + /* k-ary values. If the exponent is large enough, table is + * precomputed so that table[i] == a**(2*i+1) % c for i in + * range(EXP_TABLE_LEN). + * Note: this is uninitialized stack trash: don't pay to set it to known + * values unless it's needed. Instead ensure that num_table_entries is + * set to the number of entries actually filled whenever a branch to the + * Error or Done labels is possible. */ - PyLongObject *table[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + PyLongObject *table[EXP_TABLE_LEN]; + Py_ssize_t num_table_entries = 0; /* a, b, c = v, w, x */ CHECK_BINOP(v, w); - a = (PyLongObject*)v; Py_INCREF(a); - b = (PyLongObject*)w; Py_INCREF(b); + a = (PyLongObject*)Py_NewRef(v); + b = (PyLongObject*)Py_NewRef(w); if (PyLong_Check(x)) { - c = (PyLongObject *)x; - Py_INCREF(x); + c = (PyLongObject *)Py_NewRef(x); } else if (x == Py_None) c = NULL; @@ -4223,8 +4663,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) temp = (PyLongObject *)_PyLong_Copy(c); if (temp == NULL) goto Error; - Py_DECREF(c); - c = temp; + Py_SETREF(c, temp); temp = NULL; _PyLong_Negate(&c); if (c == NULL) @@ -4244,8 +4683,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) temp = (PyLongObject *)_PyLong_Copy(b); if (temp == NULL) goto Error; - Py_DECREF(b); - b = temp; + Py_SETREF(b, temp); temp = NULL; _PyLong_Negate(&b); if (b == NULL) @@ -4254,8 +4692,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) temp = long_invmod(a, c); if (temp == NULL) goto Error; - Py_DECREF(a); - a = temp; + Py_SETREF(a, temp); temp = NULL; } @@ -4266,13 +4703,12 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) while the "large exponent" case multiplies directly by base 31 times. It can be unboundedly faster to multiply by base % modulus instead. - We could _always_ do this reduction, but l_divmod() isn't cheap, + We could _always_ do this reduction, but l_mod() isn't cheap, so we only do it when it buys something. */ if (Py_SIZE(a) < 0 || Py_SIZE(a) > Py_SIZE(c)) { - if (l_divmod(a, c, NULL, &temp) < 0) + if (l_mod(a, c, &temp) < 0) goto Error; - Py_DECREF(a); - a = temp; + Py_SETREF(a, temp); temp = NULL; } } @@ -4290,7 +4726,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) #define REDUCE(X) \ do { \ if (c != NULL) { \ - if (l_divmod(X, c, NULL, &temp) < 0) \ + if (l_mod(X, c, &temp) < 0) \ goto Error; \ Py_XDECREF(X); \ X = temp; \ @@ -4331,7 +4767,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) } /* else bi is 0, and z==1 is correct */ } - else if (i <= FIVEARY_CUTOFF) { + else if (i <= HUGE_EXP_CUTOFF / PyLong_SHIFT ) { /* Left-to-right binary exponentiation (HAC Algorithm 14.79) */ /* http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf */ @@ -4339,9 +4775,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) * because we're primarily trying to cut overhead for small powers. */ assert(bi); /* else there is no significant bit */ - Py_INCREF(a); - Py_DECREF(z); - z = a; + Py_SETREF(z, (PyLongObject*)Py_NewRef(a)); for (bit = 2; ; bit <<= 1) { if (bit > bi) { /* found the first bit */ assert((bi & bit) == 0); @@ -4365,31 +4799,69 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) } } else { - /* Left-to-right 5-ary exponentiation (HAC Algorithm 14.82) */ - Py_INCREF(z); /* still holds 1L */ - table[0] = z; - for (i = 1; i < 32; ++i) - MULT(table[i-1], a, table[i]); + /* Left-to-right k-ary sliding window exponentiation + * (Handbook of Applied Cryptography (HAC) Algorithm 14.85) + */ + table[0] = (PyLongObject*)Py_NewRef(a); + num_table_entries = 1; + MULT(a, a, a2); + /* table[i] == a**(2*i + 1) % c */ + for (i = 1; i < EXP_TABLE_LEN; ++i) { + table[i] = NULL; /* must set to known value for MULT */ + MULT(table[i-1], a2, table[i]); + ++num_table_entries; /* incremented iff MULT succeeded */ + } + Py_CLEAR(a2); + + /* Repeatedly extract the next (no more than) EXP_WINDOW_SIZE bits + * into `pending`, starting with the next 1 bit. The current bit + * length of `pending` is `blen`. + */ + int pending = 0, blen = 0; +#define ABSORB_PENDING do { \ + int ntz = 0; /* number of trailing zeroes in `pending` */ \ + assert(pending && blen); \ + assert(pending >> (blen - 1)); \ + assert(pending >> blen == 0); \ + while ((pending & 1) == 0) { \ + ++ntz; \ + pending >>= 1; \ + } \ + assert(ntz < blen); \ + blen -= ntz; \ + do { \ + MULT(z, z, z); \ + } while (--blen); \ + MULT(z, table[pending >> 1], z); \ + while (ntz-- > 0) \ + MULT(z, z, z); \ + assert(blen == 0); \ + pending = 0; \ + } while(0) for (i = Py_SIZE(b) - 1; i >= 0; --i) { const digit bi = b->ob_digit[i]; - - for (j = PyLong_SHIFT - 5; j >= 0; j -= 5) { - const int index = (bi >> j) & 0x1f; - for (k = 0; k < 5; ++k) + for (j = PyLong_SHIFT - 1; j >= 0; --j) { + const int bit = (bi >> j) & 1; + pending = (pending << 1) | bit; + if (pending) { + ++blen; + if (blen == EXP_WINDOW_SIZE) + ABSORB_PENDING; + } + else /* absorb strings of 0 bits */ MULT(z, z, z); - if (index) - MULT(z, table[index], z); } } + if (pending) + ABSORB_PENDING; } if (negativeOutput && (Py_SIZE(z) != 0)) { temp = (PyLongObject *)long_sub(z, c); if (temp == NULL) goto Error; - Py_DECREF(z); - z = temp; + Py_SETREF(z, temp); temp = NULL; } goto Done; @@ -4398,13 +4870,12 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) Py_CLEAR(z); /* fall through */ Done: - if (Py_SIZE(b) > FIVEARY_CUTOFF) { - for (i = 0; i < 32; ++i) - Py_XDECREF(table[i]); - } + for (i = 0; i < num_table_entries; ++i) + Py_DECREF(table[i]); Py_DECREF(a); Py_DECREF(b); Py_XDECREF(c); + Py_XDECREF(a2); Py_XDECREF(temp); return (PyObject *)z; } @@ -4485,43 +4956,93 @@ divmod_shift(PyObject *shiftby, Py_ssize_t *wordshift, digit *remshift) return 0; } +/* Inner function for both long_rshift and _PyLong_Rshift, shifting an + integer right by PyLong_SHIFT*wordshift + remshift bits. + wordshift should be nonnegative. */ + static PyObject * long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) { PyLongObject *z = NULL; - Py_ssize_t newsize, hishift, i, j; - digit lomask, himask; + Py_ssize_t newsize, hishift, size_a; + twodigits accum; + int a_negative; - if (Py_SIZE(a) < 0) { - /* Right shifting negative numbers is harder */ - PyLongObject *a1, *a2; - a1 = (PyLongObject *) long_invert(a); - if (a1 == NULL) - return NULL; - a2 = (PyLongObject *) long_rshift1(a1, wordshift, remshift); - Py_DECREF(a1); - if (a2 == NULL) - return NULL; - z = (PyLongObject *) long_invert(a2); - Py_DECREF(a2); + /* Total number of bits shifted must be nonnegative. */ + assert(wordshift >= 0); + assert(remshift < PyLong_SHIFT); + + /* Fast path for small a. */ + if (IS_MEDIUM_VALUE(a)) { + stwodigits m, x; + digit shift; + m = medium_value(a); + shift = wordshift == 0 ? remshift : PyLong_SHIFT; + x = m < 0 ? ~(~m >> shift) : m >> shift; + return _PyLong_FromSTwoDigits(x); } - else { - newsize = Py_SIZE(a) - wordshift; - if (newsize <= 0) - return PyLong_FromLong(0); - hishift = PyLong_SHIFT - remshift; - lomask = ((digit)1 << hishift) - 1; - himask = PyLong_MASK ^ lomask; - z = _PyLong_New(newsize); - if (z == NULL) - return NULL; - for (i = 0, j = wordshift; i < newsize; i++, j++) { - z->ob_digit[i] = (a->ob_digit[j] >> remshift) & lomask; - if (i+1 < newsize) - z->ob_digit[i] |= (a->ob_digit[j+1] << hishift) & himask; + + a_negative = Py_SIZE(a) < 0; + size_a = Py_ABS(Py_SIZE(a)); + + if (a_negative) { + /* For negative 'a', adjust so that 0 < remshift <= PyLong_SHIFT, + while keeping PyLong_SHIFT*wordshift + remshift the same. This + ensures that 'newsize' is computed correctly below. */ + if (remshift == 0) { + if (wordshift == 0) { + /* Can only happen if the original shift was 0. */ + return long_long((PyObject *)a); + } + remshift = PyLong_SHIFT; + --wordshift; } - z = maybe_small_long(long_normalize(z)); } + + assert(wordshift >= 0); + newsize = size_a - wordshift; + if (newsize <= 0) { + /* Shifting all the bits of 'a' out gives either -1 or 0. */ + return PyLong_FromLong(-a_negative); + } + z = _PyLong_New(newsize); + if (z == NULL) { + return NULL; + } + hishift = PyLong_SHIFT - remshift; + + accum = a->ob_digit[wordshift]; + if (a_negative) { + /* + For a positive integer a and nonnegative shift, we have: + + (-a) >> shift == -((a + 2**shift - 1) >> shift). + + In the addition `a + (2**shift - 1)`, the low `wordshift` digits of + `2**shift - 1` all have value `PyLong_MASK`, so we get a carry out + from the bottom `wordshift` digits when at least one of the least + significant `wordshift` digits of `a` is nonzero. Digit `wordshift` + of `2**shift - 1` has value `PyLong_MASK >> hishift`. + */ + Py_SET_SIZE(z, -newsize); + + digit sticky = 0; + for (Py_ssize_t j = 0; j < wordshift; j++) { + sticky |= a->ob_digit[j]; + } + accum += (PyLong_MASK >> hishift) + (digit)(sticky != 0); + } + + accum >>= remshift; + for (Py_ssize_t i = 0, j = wordshift + 1; j < size_a; i++, j++) { + accum += (twodigits)a->ob_digit[j] << hishift; + z->ob_digit[i] = (digit)(accum & PyLong_MASK); + accum >>= PyLong_SHIFT; + } + assert(accum <= PyLong_MASK); + z->ob_digit[newsize - 1] = (digit)accum; + + z = maybe_small_long(long_normalize(z)); return (PyObject *)z; } @@ -4564,11 +5085,17 @@ _PyLong_Rshift(PyObject *a, size_t shiftby) static PyObject * long_lshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) { - /* This version due to Tim Peters */ PyLongObject *z = NULL; Py_ssize_t oldsize, newsize, i, j; twodigits accum; + if (wordshift == 0 && IS_MEDIUM_VALUE(a)) { + stwodigits m = medium_value(a); + // bypass undefined shift operator behavior + stwodigits x = m < 0 ? -(-m << remshift) : m << remshift; + return _PyLong_FromSTwoDigits(x); + } + oldsize = Py_ABS(Py_SIZE(a)); newsize = oldsize + wordshift; if (remshift) @@ -4583,7 +5110,7 @@ long_lshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) for (i = 0; i < wordshift; i++) z->ob_digit[i] = 0; accum = 0; - for (i = wordshift, j = 0; j < oldsize; i++, j++) { + for (j = 0; j < oldsize; i++, j++) { accum |= (twodigits)a->ob_digit[j] << remshift; z->ob_digit[i] = (digit)(accum & PyLong_MASK); accum >>= PyLong_SHIFT; @@ -4811,11 +5338,12 @@ long_or(PyObject *a, PyObject *b) static PyObject * long_long(PyObject *v) { - if (PyLong_CheckExact(v)) - Py_INCREF(v); - else - v = _PyLong_Copy((PyLongObject *)v); - return v; + if (PyLong_CheckExact(v)) { + return Py_NewRef(v); + } + else { + return _PyLong_Copy((PyLongObject *)v); + } } PyObject * @@ -4900,10 +5428,9 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) if (k == 0) { /* no progress; do a Euclidean step */ - if (l_divmod(a, b, NULL, &r) < 0) + if (l_mod(a, b, &r) < 0) goto error; - Py_DECREF(a); - a = b; + Py_SETREF(a, b); b = r; alloc_a = alloc_b; alloc_b = Py_SIZE(b); @@ -4922,8 +5449,7 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) Py_SET_SIZE(c, size_a); } else if (Py_REFCNT(a) == 1) { - Py_INCREF(a); - c = a; + c = (PyLongObject*)Py_NewRef(a); } else { alloc_a = size_a; @@ -4936,8 +5462,7 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) Py_SET_SIZE(d, size_a); } else if (Py_REFCNT(b) == 1 && size_a <= alloc_b) { - Py_INCREF(b); - d = b; + d = (PyLongObject*)Py_NewRef(b); Py_SET_SIZE(d, size_a); } else { @@ -5064,6 +5589,7 @@ long_new_impl(PyTypeObject *type, PyObject *x, PyObject *obase) } return PyLong_FromLong(0L); } + /* default base and limit, forward to standard implementation */ if (obase == NULL) return PyNumber_Long(x); @@ -5112,6 +5638,11 @@ long_subtype_new(PyTypeObject *type, PyObject *x, PyObject *obase) n = Py_SIZE(tmp); if (n < 0) n = -n; + /* Fast operations for single digit integers (including zero) + * assume that there is always at least one digit present. */ + if (n == 0) { + n = 1; + } newobj = (PyLongObject *)type->tp_alloc(type, n); if (newobj == NULL) { Py_DECREF(tmp); @@ -5154,11 +5685,13 @@ int.__format__ format_spec: unicode / + +Convert to a string according to format_spec. [clinic start generated code]*/ static PyObject * int___format___impl(PyObject *self, PyObject *format_spec) -/*[clinic end generated code: output=b4929dee9ae18689 input=e31944a9b3e428b7]*/ +/*[clinic end generated code: output=b4929dee9ae18689 input=d5e1254a47e8d1dc]*/ { _PyUnicodeWriter writer; int ret; @@ -5223,8 +5756,7 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) goto error; if (quo_is_neg) { temp = long_neg((PyLongObject*)twice_rem); - Py_DECREF(twice_rem); - twice_rem = temp; + Py_SETREF(twice_rem, temp); if (twice_rem == NULL) goto error; } @@ -5238,8 +5770,7 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) temp = long_sub(quo, (PyLongObject *)one); else temp = long_add(quo, (PyLongObject *)one); - Py_DECREF(quo); - quo = (PyLongObject *)temp; + Py_SETREF(quo, (PyLongObject *)temp); if (quo == NULL) goto error; /* and remainder */ @@ -5247,8 +5778,7 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) temp = long_add(rem, (PyLongObject *)b); else temp = long_sub(rem, (PyLongObject *)b); - Py_DECREF(rem); - rem = (PyLongObject *)temp; + Py_SETREF(rem, (PyLongObject *)temp); if (rem == NULL) goto error; } @@ -5314,8 +5844,7 @@ int___round___impl(PyObject *self, PyObject *o_ndigits) /* result = self - divmod_near(self, 10 ** -ndigits)[1] */ temp = long_neg((PyLongObject*)ndigits); - Py_DECREF(ndigits); - ndigits = temp; + Py_SETREF(ndigits, temp); if (ndigits == NULL) return NULL; @@ -5327,21 +5856,18 @@ int___round___impl(PyObject *self, PyObject *o_ndigits) temp = long_pow(result, ndigits, Py_None); Py_DECREF(ndigits); - Py_DECREF(result); - result = temp; + Py_SETREF(result, temp); if (result == NULL) return NULL; temp = _PyLong_DivmodNear(self, result); - Py_DECREF(result); - result = temp; + Py_SETREF(result, temp); if (result == NULL) return NULL; temp = long_sub((PyLongObject *)self, (PyLongObject *)PyTuple_GET_ITEM(result, 1)); - Py_DECREF(result); - result = temp; + Py_SETREF(result, temp); return result; } @@ -5358,7 +5884,10 @@ int___sizeof___impl(PyObject *self) { Py_ssize_t res; - res = offsetof(PyLongObject, ob_digit) + Py_ABS(Py_SIZE(self))*sizeof(digit); + res = offsetof(PyLongObject, ob_digit) + /* using Py_MAX(..., 1) because we always allocate space for at least + one digit, even though the integer zero has a Py_SIZE of 0 */ + + Py_MAX(Py_ABS(Py_SIZE(self)), 1)*sizeof(digit); return res; } @@ -5406,8 +5935,7 @@ int_bit_length_impl(PyObject *self) Py_DECREF(x); if (y == NULL) goto error; - Py_DECREF(result); - result = y; + Py_SETREF(result, y); x = (PyLongObject *)PyLong_FromLong((long)msd_bits); if (x == NULL) @@ -5416,8 +5944,7 @@ int_bit_length_impl(PyObject *self) Py_DECREF(x); if (y == NULL) goto error; - Py_DECREF(result); - result = y; + Py_SETREF(result, y); return (PyObject *)result; @@ -5431,7 +5958,7 @@ popcount_digit(digit d) { // digit can be larger than uint32_t, but only PyLong_SHIFT bits // of it will be ever used. - Py_BUILD_ASSERT(PyLong_SHIFT <= 32); + static_assert(PyLong_SHIFT <= 32, "digit is larger than uint32_t"); return _Py_popcount32((uint32_t)d); } @@ -5483,8 +6010,7 @@ int_bit_count_impl(PyObject *self) if (y == NULL) { goto error; } - Py_DECREF(result); - result = y; + Py_SETREF(result, y); } return result; @@ -5556,9 +6082,9 @@ int_to_bytes_impl(PyObject *self, Py_ssize_t length, PyObject *byteorder, if (byteorder == NULL) little_endian = 0; - else if (_PyUnicode_EqualToASCIIId(byteorder, &PyId_little)) + else if (_PyUnicode_Equal(byteorder, &_Py_ID(little))) little_endian = 1; - else if (_PyUnicode_EqualToASCIIId(byteorder, &PyId_big)) + else if (_PyUnicode_Equal(byteorder, &_Py_ID(big))) little_endian = 0; else { PyErr_SetString(PyExc_ValueError, @@ -5618,9 +6144,9 @@ int_from_bytes_impl(PyTypeObject *type, PyObject *bytes_obj, if (byteorder == NULL) little_endian = 0; - else if (_PyUnicode_EqualToASCIIId(byteorder, &PyId_little)) + else if (_PyUnicode_Equal(byteorder, &_Py_ID(little))) little_endian = 1; - else if (_PyUnicode_EqualToASCIIId(byteorder, &PyId_big)) + else if (_PyUnicode_Equal(byteorder, &_Py_ID(big))) little_endian = 0; else { PyErr_SetString(PyExc_ValueError, @@ -5650,6 +6176,19 @@ long_long_meth(PyObject *self, PyObject *Py_UNUSED(ignored)) return long_long(self); } +/*[clinic input] +int.is_integer + +Returns True. Exists for duck type compatibility with float.is_integer. +[clinic start generated code]*/ + +static PyObject * +int_is_integer_impl(PyObject *self) +/*[clinic end generated code: output=90f8e794ce5430ef input=7e41c4d4416e05f2]*/ +{ + Py_RETURN_TRUE; +} + static PyMethodDef long_methods[] = { {"conjugate", long_long_meth, METH_NOARGS, "Returns self, the complex conjugate of any int."}, @@ -5668,6 +6207,7 @@ static PyMethodDef long_methods[] = { INT___GETNEWARGS___METHODDEF INT___FORMAT___METHODDEF INT___SIZEOF___METHODDEF + INT_IS_INTEGER_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -5785,7 +6325,7 @@ PyTypeObject PyLong_Type = { 0, /* tp_init */ 0, /* tp_alloc */ long_new, /* tp_new */ - PyObject_Del, /* tp_free */ + PyObject_Free, /* tp_free */ }; static PyTypeObject Int_InfoType; @@ -5799,6 +6339,8 @@ internal representation of integers. The attributes are read only."); static PyStructSequence_Field int_info_fields[] = { {"bits_per_digit", "size of a digit in bits"}, {"sizeof_digit", "size in bytes of the C type used to represent a digit"}, + {"default_max_str_digits", "maximum string conversion digits limitation"}, + {"str_digits_check_threshold", "minimum positive value for int_max_str_digits"}, {NULL, NULL} }; @@ -5806,7 +6348,7 @@ static PyStructSequence_Desc int_info_desc = { "sys.int_info", /* name */ int_info__doc__, /* doc */ int_info_fields, /* fields */ - 2 /* number of fields */ + 4 /* number of fields */ }; PyObject * @@ -5821,6 +6363,17 @@ PyLong_GetInfo(void) PyLong_FromLong(PyLong_SHIFT)); PyStructSequence_SET_ITEM(int_info, field++, PyLong_FromLong(sizeof(digit))); + /* + * The following two fields were added after investigating uses of + * sys.int_info in the wild: Exceedingly rarely used. The ONLY use found was + * numba using sys.int_info.bits_per_digit as attribute access rather than + * sequence unpacking. Cython and sympy also refer to sys.int_info but only + * as info for debugging. No concern about adding these in a backport. + */ + PyStructSequence_SET_ITEM(int_info, field++, + PyLong_FromLong(_PY_LONG_DEFAULT_MAX_STR_DIGITS)); + PyStructSequence_SET_ITEM(int_info, field++, + PyLong_FromLong(_PY_LONG_MAX_STR_DIGITS_THRESHOLD)); if (PyErr_Occurred()) { Py_CLEAR(int_info); return NULL; @@ -5828,35 +6381,37 @@ PyLong_GetInfo(void) return int_info; } -void -_PyLong_Init(PyInterpreterState *interp) -{ - if (_PyRuntime.small_ints[0].ob_base.ob_base.ob_refcnt == 0) { - for (Py_ssize_t i=0; i < _PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS; i++) { - sdigit ival = (sdigit)i - _PY_NSMALLNEGINTS; - int size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1); - _PyRuntime.small_ints[i].ob_base.ob_base.ob_refcnt = 1; - _PyRuntime.small_ints[i].ob_base.ob_base.ob_type = &PyLong_Type; - _PyRuntime.small_ints[i].ob_base.ob_size = size; - _PyRuntime.small_ints[i].ob_digit[0] = (digit)abs(ival); - } - } -} -int -_PyLong_InitTypes(void) +/* runtime lifecycle */ + +PyStatus +_PyLong_InitTypes(PyInterpreterState *interp) { + if (!_Py_IsMainInterpreter(interp)) { + return _PyStatus_OK(); + } + + if (PyType_Ready(&PyLong_Type) < 0) { + return _PyStatus_ERR("Can't initialize int type"); + } + /* initialize int_info */ if (Int_InfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) { - return -1; + if (_PyStructSequence_InitBuiltin(&Int_InfoType, &int_info_desc) < 0) { + return _PyStatus_ERR("can't init int info type"); } } - return 0; + + return _PyStatus_OK(); } + void -_PyLong_Fini(PyInterpreterState *interp) +_PyLong_FiniTypes(PyInterpreterState *interp) { - (void)interp; + if (!_Py_IsMainInterpreter(interp)) { + return; + } + + _PyStructSequence_FiniType(&Int_InfoType); } diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 6257455d347..1d6cc3b5084 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -67,14 +67,6 @@ class memoryview "PyMemoryViewObject *" "&PyMemoryView_Type" */ -#define CHECK_MBUF_RELEASED(mbuf) \ - if (((_PyManagedBufferObject *)mbuf)->flags&_Py_MANAGED_BUFFER_RELEASED) { \ - PyErr_SetString(PyExc_ValueError, \ - "operation forbidden on released memoryview object"); \ - return NULL; \ - } - - static inline _PyManagedBufferObject * mbuf_alloc(void) { @@ -201,6 +193,11 @@ PyTypeObject _PyManagedBuffer_Type = { return -1; \ } +/* See gh-92888. These macros signal that we need to check the memoryview + again due to possible read after frees. */ +#define CHECK_RELEASED_AGAIN(mv) CHECK_RELEASED(mv) +#define CHECK_RELEASED_INT_AGAIN(mv) CHECK_RELEASED_INT(mv) + #define CHECK_LIST_OR_TUPLE(v) \ if (!PyList_Check(v) && !PyTuple_Check(v)) { \ PyErr_SetString(PyExc_TypeError, \ @@ -389,8 +386,9 @@ copy_rec(const Py_ssize_t *shape, Py_ssize_t ndim, Py_ssize_t itemsize, /* Faster copying of one-dimensional arrays. */ static int -copy_single(Py_buffer *dest, Py_buffer *src) +copy_single(PyMemoryViewObject *self, const Py_buffer *dest, const Py_buffer *src) { + CHECK_RELEASED_INT_AGAIN(self); char *mem = NULL; assert(dest->ndim == 1); @@ -421,7 +419,7 @@ copy_single(Py_buffer *dest, Py_buffer *src) structure. Copying is atomic, the function never fails with a partial copy. */ static int -copy_buffer(Py_buffer *dest, Py_buffer *src) +copy_buffer(const Py_buffer *dest, const Py_buffer *src) { char *mem = NULL; @@ -479,7 +477,7 @@ init_fortran_strides_from_shape(Py_buffer *view) or 'A' (Any). Assumptions: src has PyBUF_FULL information, src->ndim >= 1, len(mem) == src->len. */ static int -buffer_to_contiguous(char *mem, Py_buffer *src, char order) +buffer_to_contiguous(char *mem, const Py_buffer *src, char order) { Py_buffer dest; Py_ssize_t *strides; @@ -684,8 +682,7 @@ mbuf_add_view(_PyManagedBufferObject *mbuf, const Py_buffer *src) init_suboffsets(dest, src); init_flags(mv); - mv->mbuf = mbuf; - Py_INCREF(mbuf); + mv->mbuf = (_PyManagedBufferObject*)Py_NewRef(mbuf); mbuf->exports++; return (PyObject *)mv; @@ -715,8 +712,7 @@ mbuf_add_incomplete_view(_PyManagedBufferObject *mbuf, const Py_buffer *src, dest = &mv->view; init_shared_values(dest, src); - mv->mbuf = mbuf; - Py_INCREF(mbuf); + mv->mbuf = (_PyManagedBufferObject*)Py_NewRef(mbuf); mbuf->exports++; return (PyObject *)mv; @@ -755,7 +751,7 @@ PyMemoryView_FromMemory(char *mem, Py_ssize_t size, int flags) without full information. Because of this fact init_shape_strides() must be able to reconstruct missing values. */ PyObject * -PyMemoryView_FromBuffer(Py_buffer *info) +PyMemoryView_FromBuffer(const Py_buffer *info) { _PyManagedBufferObject *mbuf; PyObject *mv; @@ -840,7 +836,7 @@ mbuf_copy_format(_PyManagedBufferObject *mbuf, const char *fmt) passes the altered format pointer to PyBuffer_Release(). */ static PyObject * -memory_from_contiguous_copy(Py_buffer *src, char order) +memory_from_contiguous_copy(const Py_buffer *src, char order) { _PyManagedBufferObject *mbuf; PyMemoryViewObject *mv; @@ -982,7 +978,7 @@ typedef struct { } Py_buffer_full; int -PyBuffer_ToContiguous(void *buf, Py_buffer *src, Py_ssize_t len, char order) +PyBuffer_ToContiguous(void *buf, const Py_buffer *src, Py_ssize_t len, char order) { Py_buffer_full *fb = NULL; int ret; @@ -1104,8 +1100,7 @@ static PyObject * memory_enter(PyObject *self, PyObject *args) { CHECK_RELEASED(self); - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * @@ -1137,6 +1132,7 @@ get_native_fmtchar(char *result, const char *fmt) case 'n': case 'N': size = sizeof(Py_ssize_t); break; case 'f': size = sizeof(float); break; case 'd': size = sizeof(double); break; + case 'e': size = sizeof(float) / 2; break; case '?': size = sizeof(_Bool); break; case 'P': size = sizeof(void *); break; } @@ -1180,6 +1176,7 @@ get_native_fmtstr(const char *fmt) case 'N': RETURN("N"); case 'f': RETURN("f"); case 'd': RETURN("d"); + case 'e': RETURN("e"); case '?': RETURN("?"); case 'P': RETURN("P"); } @@ -1515,8 +1512,7 @@ memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags) } - view->obj = (PyObject *)self; - Py_INCREF(view->obj); + view->obj = Py_NewRef(self); self->exports++; return 0; @@ -1685,7 +1681,7 @@ pylong_as_zu(PyObject *item) module syntax. This function is very sensitive to small changes. With this layout gcc automatically generates a fast jump table. */ static inline PyObject * -unpack_single(const char *ptr, const char *fmt) +unpack_single(PyMemoryViewObject *self, const char *ptr, const char *fmt) { unsigned long long llu; unsigned long lu; @@ -1697,6 +1693,14 @@ unpack_single(const char *ptr, const char *fmt) unsigned char uc; void *p; + CHECK_RELEASED_AGAIN(self); + +#if PY_LITTLE_ENDIAN + int endian = 1; +#else + int endian = 0; +#endif + switch (fmt[0]) { /* signed integers and fast path for 'B' */ @@ -1725,6 +1729,7 @@ unpack_single(const char *ptr, const char *fmt) /* floats */ case 'f': UNPACK_SINGLE(d, ptr, float); goto convert_double; case 'd': UNPACK_SINGLE(d, ptr, double); goto convert_double; + case 'e': d = PyFloat_Unpack2(ptr, endian); goto convert_double; /* bytes object */ case 'c': goto convert_bytes; @@ -1775,7 +1780,7 @@ err_format: /* Pack a single item. 'fmt' can be any native format character in struct module syntax. */ static int -pack_single(char *ptr, PyObject *item, const char *fmt) +pack_single(PyMemoryViewObject *self, char *ptr, PyObject *item, const char *fmt) { unsigned long long llu; unsigned long lu; @@ -1786,12 +1791,18 @@ pack_single(char *ptr, PyObject *item, const char *fmt) double d; void *p; +#if PY_LITTLE_ENDIAN + int endian = 1; +#else + int endian = 0; +#endif switch (fmt[0]) { /* signed integers */ case 'b': case 'h': case 'i': case 'l': ld = pylong_as_ld(item); if (ld == -1 && PyErr_Occurred()) goto err_occurred; + CHECK_RELEASED_INT_AGAIN(self); switch (fmt[0]) { case 'b': if (ld < SCHAR_MIN || ld > SCHAR_MAX) goto err_range; @@ -1812,6 +1823,7 @@ pack_single(char *ptr, PyObject *item, const char *fmt) lu = pylong_as_lu(item); if (lu == (unsigned long)-1 && PyErr_Occurred()) goto err_occurred; + CHECK_RELEASED_INT_AGAIN(self); switch (fmt[0]) { case 'B': if (lu > UCHAR_MAX) goto err_range; @@ -1832,12 +1844,14 @@ pack_single(char *ptr, PyObject *item, const char *fmt) lld = pylong_as_lld(item); if (lld == -1 && PyErr_Occurred()) goto err_occurred; + CHECK_RELEASED_INT_AGAIN(self); PACK_SINGLE(ptr, lld, long long); break; case 'Q': llu = pylong_as_llu(item); if (llu == (unsigned long long)-1 && PyErr_Occurred()) goto err_occurred; + CHECK_RELEASED_INT_AGAIN(self); PACK_SINGLE(ptr, llu, unsigned long long); break; @@ -1846,26 +1860,34 @@ pack_single(char *ptr, PyObject *item, const char *fmt) zd = pylong_as_zd(item); if (zd == -1 && PyErr_Occurred()) goto err_occurred; + CHECK_RELEASED_INT_AGAIN(self); PACK_SINGLE(ptr, zd, Py_ssize_t); break; case 'N': zu = pylong_as_zu(item); if (zu == (size_t)-1 && PyErr_Occurred()) goto err_occurred; + CHECK_RELEASED_INT_AGAIN(self); PACK_SINGLE(ptr, zu, size_t); break; /* floats */ - case 'f': case 'd': + case 'f': case 'd': case 'e': d = PyFloat_AsDouble(item); if (d == -1.0 && PyErr_Occurred()) goto err_occurred; + CHECK_RELEASED_INT_AGAIN(self); if (fmt[0] == 'f') { PACK_SINGLE(ptr, d, float); } - else { + else if (fmt[0] == 'd') { PACK_SINGLE(ptr, d, double); } + else { + if (PyFloat_Pack2(d, ptr, endian) < 0) { + goto err_occurred; + } + } break; /* bool */ @@ -1873,8 +1895,9 @@ pack_single(char *ptr, PyObject *item, const char *fmt) ld = PyObject_IsTrue(item); if (ld < 0) return -1; /* preserve original error */ + CHECK_RELEASED_INT_AGAIN(self); PACK_SINGLE(ptr, ld, _Bool); - break; + break; /* bytes object */ case 'c': @@ -1890,6 +1913,7 @@ pack_single(char *ptr, PyObject *item, const char *fmt) p = PyLong_AsVoidPtr(item); if (p == NULL && PyErr_Occurred()) goto err_occurred; + CHECK_RELEASED_INT_AGAIN(self); PACK_SINGLE(ptr, p, void *); break; @@ -1958,18 +1982,12 @@ unpacker_free(struct unpacker *x) static struct unpacker * struct_get_unpacker(const char *fmt, Py_ssize_t itemsize) { - PyObject *structmodule; /* XXX cache these two */ - PyObject *Struct = NULL; /* XXX in globals? */ + PyObject *Struct = NULL; /* XXX cache it in globals? */ PyObject *structobj = NULL; PyObject *format = NULL; struct unpacker *x = NULL; - structmodule = PyImport_ImportModule("struct"); - if (structmodule == NULL) - return NULL; - - Struct = PyObject_GetAttrString(structmodule, "Struct"); - Py_DECREF(structmodule); + Struct = _PyImport_GetModuleAttrString("struct", "Struct"); if (Struct == NULL) return NULL; @@ -2025,10 +2043,9 @@ struct_unpack_single(const char *ptr, struct unpacker *x) return NULL; if (PyTuple_GET_SIZE(v) == 1) { - PyObject *tmp = PyTuple_GET_ITEM(v, 0); - Py_INCREF(tmp); + PyObject *res = Py_NewRef(PyTuple_GET_ITEM(v, 0)); Py_DECREF(v); - return tmp; + return res; } return v; @@ -2056,7 +2073,7 @@ adjust_fmt(const Py_buffer *view) /* Base case for multi-dimensional unpacking. Assumption: ndim == 1. */ static PyObject * -tolist_base(const char *ptr, const Py_ssize_t *shape, +tolist_base(PyMemoryViewObject *self, const char *ptr, const Py_ssize_t *shape, const Py_ssize_t *strides, const Py_ssize_t *suboffsets, const char *fmt) { @@ -2069,7 +2086,7 @@ tolist_base(const char *ptr, const Py_ssize_t *shape, for (i = 0; i < shape[0]; ptr+=strides[0], i++) { const char *xptr = ADJUST_PTR(ptr, suboffsets, 0); - item = unpack_single(xptr, fmt); + item = unpack_single(self, xptr, fmt); if (item == NULL) { Py_DECREF(lst); return NULL; @@ -2083,7 +2100,7 @@ tolist_base(const char *ptr, const Py_ssize_t *shape, /* Unpack a multi-dimensional array into a nested list. Assumption: ndim >= 1. */ static PyObject * -tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape, +tolist_rec(PyMemoryViewObject *self, const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape, const Py_ssize_t *strides, const Py_ssize_t *suboffsets, const char *fmt) { @@ -2095,7 +2112,7 @@ tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape, assert(strides != NULL); if (ndim == 1) - return tolist_base(ptr, shape, strides, suboffsets, fmt); + return tolist_base(self, ptr, shape, strides, suboffsets, fmt); lst = PyList_New(shape[0]); if (lst == NULL) @@ -2103,7 +2120,7 @@ tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape, for (i = 0; i < shape[0]; ptr+=strides[0], i++) { const char *xptr = ADJUST_PTR(ptr, suboffsets, 0); - item = tolist_rec(xptr, ndim-1, shape+1, + item = tolist_rec(self, xptr, ndim-1, shape+1, strides+1, suboffsets ? suboffsets+1 : NULL, fmt); if (item == NULL) { @@ -2137,15 +2154,15 @@ memoryview_tolist_impl(PyMemoryViewObject *self) if (fmt == NULL) return NULL; if (view->ndim == 0) { - return unpack_single(view->buf, fmt); + return unpack_single(self, view->buf, fmt); } else if (view->ndim == 1) { - return tolist_base(view->buf, view->shape, + return tolist_base(self, view->buf, view->shape, view->strides, view->suboffsets, fmt); } else { - return tolist_rec(view->buf, view->ndim, view->shape, + return tolist_rec(self, view->buf, view->ndim, view->shape, view->strides, view->suboffsets, fmt); } @@ -2271,7 +2288,7 @@ memory_repr(PyMemoryViewObject *self) /**************************************************************************/ static char * -lookup_dimension(Py_buffer *view, char *ptr, int dim, Py_ssize_t index) +lookup_dimension(const Py_buffer *view, char *ptr, int dim, Py_ssize_t index) { Py_ssize_t nitems; /* items in the given dimension */ @@ -2297,7 +2314,7 @@ lookup_dimension(Py_buffer *view, char *ptr, int dim, Py_ssize_t index) /* Get the pointer to the item at index. */ static char * -ptr_from_index(Py_buffer *view, Py_ssize_t index) +ptr_from_index(const Py_buffer *view, Py_ssize_t index) { char *ptr = (char *)view->buf; return lookup_dimension(view, ptr, 0, index); @@ -2305,7 +2322,7 @@ ptr_from_index(Py_buffer *view, Py_ssize_t index) /* Get the pointer to the item at tuple. */ static char * -ptr_from_tuple(Py_buffer *view, PyObject *tup) +ptr_from_tuple(const Py_buffer *view, PyObject *tup) { char *ptr = (char *)view->buf; Py_ssize_t dim, nindices = PyTuple_GET_SIZE(tup); @@ -2353,7 +2370,7 @@ memory_item(PyMemoryViewObject *self, Py_ssize_t index) char *ptr = ptr_from_index(view, index); if (ptr == NULL) return NULL; - return unpack_single(ptr, fmt); + return unpack_single(self, ptr, fmt); } PyErr_SetString(PyExc_NotImplementedError, @@ -2384,7 +2401,7 @@ memory_item_multi(PyMemoryViewObject *self, PyObject *tup) ptr = ptr_from_tuple(view, tup); if (ptr == NULL) return NULL; - return unpack_single(ptr, fmt); + return unpack_single(self, ptr, fmt); } static inline int @@ -2471,11 +2488,10 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key) const char *fmt = adjust_fmt(view); if (fmt == NULL) return NULL; - return unpack_single(view->buf, fmt); + return unpack_single(self, view->buf, fmt); } else if (key == Py_Ellipsis) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else { PyErr_SetString(PyExc_TypeError, @@ -2546,7 +2562,7 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) if (key == Py_Ellipsis || (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) { ptr = (char *)view->buf; - return pack_single(ptr, value, fmt); + return pack_single(self, ptr, value, fmt); } else { PyErr_SetString(PyExc_TypeError, @@ -2568,7 +2584,7 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) ptr = ptr_from_index(view, index); if (ptr == NULL) return -1; - return pack_single(ptr, value, fmt); + return pack_single(self, ptr, value, fmt); } /* one-dimensional: fast path */ if (PySlice_Check(key) && view->ndim == 1) { @@ -2591,7 +2607,7 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) goto end_block; dest.len = dest.shape[0] * dest.itemsize; - ret = copy_single(&dest, &src); + ret = copy_single(self, &dest, &src); end_block: PyBuffer_Release(&src); @@ -2607,7 +2623,7 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) ptr = ptr_from_tuple(view, key); if (ptr == NULL) return -1; - return pack_single(ptr, value, fmt); + return pack_single(self, ptr, value, fmt); } if (PySlice_Check(key) || is_multislice(key)) { /* Call memory_subscript() to produce a sliced lvalue, then copy @@ -2745,6 +2761,17 @@ unpack_cmp(const char *p, const char *q, char fmt, /* XXX DBL_EPSILON? */ case 'f': CMP_SINGLE(p, q, float); return equal; case 'd': CMP_SINGLE(p, q, double); return equal; + case 'e': { +#if PY_LITTLE_ENDIAN + int endian = 1; +#else + int endian = 0; +#endif + /* Note: PyFloat_Unpack2 should never fail */ + double u = PyFloat_Unpack2(p, endian); + double v = PyFloat_Unpack2(q, endian); + return (u == v); + } /* bytes object */ case 'c': return *p == *q; @@ -2924,8 +2951,7 @@ result: unpacker_free(unpack_v); unpacker_free(unpack_w); - Py_XINCREF(res); - return res; + return Py_XNewRef(res); } /**************************************************************************/ @@ -3019,8 +3045,7 @@ memory_obj_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) if (view->obj == NULL) { Py_RETURN_NONE; } - Py_INCREF(view->obj); - return view->obj; + return Py_NewRef(view->obj); } static PyObject * @@ -3164,7 +3189,7 @@ static PyMethodDef memory_methods[] = { /* Memoryview Iterator */ /**************************************************************************/ -static PyTypeObject PyMemoryIter_Type; +PyTypeObject _PyMemoryIter_Type; typedef struct { PyObject_HEAD @@ -3208,7 +3233,7 @@ memoryiter_next(memoryiterobject *it) if (ptr == NULL) { return NULL; } - return unpack_single(ptr, it->it_fmt); + return unpack_single(seq, ptr, it->it_fmt); } it->it_seq = NULL; @@ -3241,20 +3266,19 @@ memory_iter(PyObject *seq) } memoryiterobject *it; - it = PyObject_GC_New(memoryiterobject, &PyMemoryIter_Type); + it = PyObject_GC_New(memoryiterobject, &_PyMemoryIter_Type); if (it == NULL) { return NULL; } it->it_fmt = fmt; it->it_length = memory_length(obj); it->it_index = 0; - Py_INCREF(seq); - it->it_seq = obj; + it->it_seq = (PyMemoryViewObject*)Py_NewRef(obj); _PyObject_GC_TRACK(it); return (PyObject *)it; } -static PyTypeObject PyMemoryIter_Type = { +PyTypeObject _PyMemoryIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) .tp_name = "memory_iterator", .tp_basicsize = sizeof(memoryiterobject), diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 2df63cfdf6a..51752dec3dd 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -2,7 +2,7 @@ /* Method object implementation */ #include "Python.h" -#include "pycore_ceval.h" // _Py_EnterRecursiveCall() +#include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() #include "pycore_object.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" // _PyThreadState_GET() @@ -88,8 +88,7 @@ PyCMethod_New(PyMethodDef *ml, PyObject *self, PyObject *module, PyTypeObject *c if (om == NULL) { return NULL; } - Py_INCREF(cls); - om->mm_class = cls; + om->mm_class = (PyTypeObject*)Py_NewRef(cls); op = (PyCFunctionObject *)om; } else { if (cls) { @@ -106,10 +105,8 @@ PyCMethod_New(PyMethodDef *ml, PyObject *self, PyObject *module, PyTypeObject *c op->m_weakreflist = NULL; op->m_ml = ml; - Py_XINCREF(self); - op->m_self = self; - Py_XINCREF(module); - op->m_module = module; + op->m_self = Py_XNewRef(self); + op->m_module = Py_XNewRef(module); op->vectorcall = vectorcall; _PyObject_GC_TRACK(op); return (PyObject *)op; @@ -179,12 +176,10 @@ meth_dealloc(PyCFunctionObject *m) static PyObject * meth_reduce(PyCFunctionObject *m, PyObject *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(getattr); - if (m->m_self == NULL || PyModule_Check(m->m_self)) return PyUnicode_FromString(m->m_ml->ml_name); - return Py_BuildValue("N(Os)", _PyEval_GetBuiltinId(&PyId_getattr), + return Py_BuildValue("N(Os)", _PyEval_GetBuiltin(&_Py_ID(getattr)), m->m_self, m->m_ml->ml_name); } @@ -223,14 +218,13 @@ meth_get__qualname__(PyCFunctionObject *m, void *closure) Otherwise return type(m.__self__).__qualname__ + '.' + m.__name__ (e.g. [].append.__qualname__ == 'list.append') */ PyObject *type, *type_qualname, *res; - _Py_IDENTIFIER(__qualname__); if (m->m_self == NULL || PyModule_Check(m->m_self)) return PyUnicode_FromString(m->m_ml->ml_name); type = PyType_Check(m->m_self) ? m->m_self : (PyObject*)Py_TYPE(m->m_self); - type_qualname = _PyObject_GetAttrId(type, &PyId___qualname__); + type_qualname = PyObject_GetAttr(type, &_Py_ID(__qualname__)); if (type_qualname == NULL) return NULL; @@ -263,8 +257,7 @@ meth_get__self__(PyCFunctionObject *m, void *closure) self = PyCFunction_GET_SELF(m); if (self == NULL) self = Py_None; - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyGetSetDef meth_getsets [] = { @@ -317,8 +310,7 @@ meth_richcompare(PyObject *self, PyObject *other, int op) res = eq ? Py_True : Py_False; else res = eq ? Py_False : Py_True; - Py_INCREF(res); - return res; + return Py_NewRef(res); } static Py_hash_t @@ -406,7 +398,7 @@ typedef void (*funcptr)(void); static inline funcptr cfunction_enter_call(PyThreadState *tstate, PyObject *func) { - if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) { + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { return NULL; } return (funcptr)PyCFunction_GET_FUNCTION(func); @@ -428,7 +420,7 @@ cfunction_vectorcall_FASTCALL( return NULL; } PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs); - _Py_LeaveRecursiveCall(tstate); + _Py_LeaveRecursiveCallTstate(tstate); return result; } @@ -444,7 +436,7 @@ cfunction_vectorcall_FASTCALL_KEYWORDS( return NULL; } PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs, kwnames); - _Py_LeaveRecursiveCall(tstate); + _Py_LeaveRecursiveCallTstate(tstate); return result; } @@ -460,7 +452,7 @@ cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD( return NULL; } PyObject *result = meth(PyCFunction_GET_SELF(func), cls, args, nargs, kwnames); - _Py_LeaveRecursiveCall(tstate); + _Py_LeaveRecursiveCallTstate(tstate); return result; } @@ -486,8 +478,9 @@ cfunction_vectorcall_NOARGS( if (meth == NULL) { return NULL; } - PyObject *result = meth(PyCFunction_GET_SELF(func), NULL); - _Py_LeaveRecursiveCall(tstate); + PyObject *result = _PyCFunction_TrampolineCall( + meth, PyCFunction_GET_SELF(func), NULL); + _Py_LeaveRecursiveCallTstate(tstate); return result; } @@ -513,8 +506,9 @@ cfunction_vectorcall_O( if (meth == NULL) { return NULL; } - PyObject *result = meth(PyCFunction_GET_SELF(func), args[0]); - _Py_LeaveRecursiveCall(tstate); + PyObject *result = _PyCFunction_TrampolineCall( + meth, PyCFunction_GET_SELF(func), args[0]); + _Py_LeaveRecursiveCallTstate(tstate); return result; } @@ -540,7 +534,9 @@ cfunction_call(PyObject *func, PyObject *args, PyObject *kwargs) PyObject *result; if (flags & METH_KEYWORDS) { - result = (*(PyCFunctionWithKeywords)(void(*)(void))meth)(self, args, kwargs); + result = _PyCFunctionWithKeywords_TrampolineCall( + (*(PyCFunctionWithKeywords)(void(*)(void))meth), + self, args, kwargs); } else { if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { @@ -549,7 +545,15 @@ cfunction_call(PyObject *func, PyObject *args, PyObject *kwargs) ((PyCFunctionObject*)func)->m_ml->ml_name); return NULL; } - result = meth(self, args); + result = _PyCFunction_TrampolineCall(meth, self, args); } return _Py_CheckFunctionResult(tstate, func, result, NULL); } + +#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) +#include + +EM_JS(PyObject*, _PyCFunctionWithKeywords_TrampolineCall, (PyCFunctionWithKeywords func, PyObject *self, PyObject *args, PyObject *kw), { + return wasmTable.get(func)(self, args, kw); +}); +#endif diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 1d649a79320..24190e320ee 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -4,18 +4,11 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_interp.h" // PyInterpreterState.importlib +#include "pycore_object.h" // _PyType_AllocNoTrack #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_moduleobject.h" // _PyModule_GetDef() #include "structmember.h" // PyMemberDef -static Py_ssize_t max_module_number; - -_Py_IDENTIFIER(__doc__); -_Py_IDENTIFIER(__name__); -_Py_IDENTIFIER(__spec__); -_Py_IDENTIFIER(__dict__); -_Py_IDENTIFIER(__dir__); -_Py_IDENTIFIER(__annotations__); static PyMemberDef module_members[] = { {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY}, @@ -26,7 +19,7 @@ static PyMemberDef module_members[] = { PyTypeObject PyModuleDef_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "moduledef", /* tp_name */ - sizeof(struct PyModuleDef), /* tp_basicsize */ + sizeof(PyModuleDef), /* tp_basicsize */ 0, /* tp_itemsize */ }; @@ -39,20 +32,20 @@ _PyModule_IsExtension(PyObject *obj) } PyModuleObject *module = (PyModuleObject*)obj; - struct PyModuleDef *def = module->md_def; + PyModuleDef *def = module->md_def; return (def != NULL && def->m_methods != NULL); } PyObject* -PyModuleDef_Init(struct PyModuleDef* def) +PyModuleDef_Init(PyModuleDef* def) { assert(PyModuleDef_Type.tp_flags & Py_TPFLAGS_READY); if (def->m_base.m_index == 0) { - max_module_number++; + _PyRuntime.imports.last_module_index++; Py_SET_REFCNT(def, 1); Py_SET_TYPE(def, &PyModuleDef_Type); - def->m_base.m_index = max_module_number; + def->m_base.m_index = _PyRuntime.imports.last_module_index; } return (PyObject*)def; } @@ -61,26 +54,22 @@ static int module_init_dict(PyModuleObject *mod, PyObject *md_dict, PyObject *name, PyObject *doc) { - _Py_IDENTIFIER(__package__); - _Py_IDENTIFIER(__loader__); - assert(md_dict != NULL); if (doc == NULL) doc = Py_None; - if (_PyDict_SetItemId(md_dict, &PyId___name__, name) != 0) + if (PyDict_SetItem(md_dict, &_Py_ID(__name__), name) != 0) return -1; - if (_PyDict_SetItemId(md_dict, &PyId___doc__, doc) != 0) + if (PyDict_SetItem(md_dict, &_Py_ID(__doc__), doc) != 0) return -1; - if (_PyDict_SetItemId(md_dict, &PyId___package__, Py_None) != 0) + if (PyDict_SetItem(md_dict, &_Py_ID(__package__), Py_None) != 0) return -1; - if (_PyDict_SetItemId(md_dict, &PyId___loader__, Py_None) != 0) + if (PyDict_SetItem(md_dict, &_Py_ID(__loader__), Py_None) != 0) return -1; - if (_PyDict_SetItemId(md_dict, &PyId___spec__, Py_None) != 0) + if (PyDict_SetItem(md_dict, &_Py_ID(__spec__), Py_None) != 0) return -1; if (PyUnicode_CheckExact(name)) { - Py_INCREF(name); - Py_XSETREF(mod->md_name, name); + Py_XSETREF(mod->md_name, Py_NewRef(name)); } return 0; @@ -90,7 +79,7 @@ static PyModuleObject * new_module_notrack(PyTypeObject *mt) { PyModuleObject *m; - m = PyObject_GC_New(PyModuleObject, mt); + m = (PyModuleObject *)_PyType_AllocNoTrack(mt, 0); if (m == NULL) return NULL; m->md_def = NULL; @@ -192,7 +181,7 @@ _add_methods_to_object(PyObject *module, PyObject *name, PyMethodDef *functions) } PyObject * -PyModule_Create2(struct PyModuleDef* module, int module_api_version) +PyModule_Create2(PyModuleDef* module, int module_api_version) { if (!_PyImport_IsInitialized(_PyInterpreterState_GET())) { PyErr_SetString(PyExc_SystemError, @@ -203,7 +192,7 @@ PyModule_Create2(struct PyModuleDef* module, int module_api_version) } PyObject * -_PyModule_CreateInitialized(struct PyModuleDef* module, int module_api_version) +_PyModule_CreateInitialized(PyModuleDef* module, int module_api_version) { const char* name; PyModuleObject *m; @@ -229,6 +218,7 @@ _PyModule_CreateInitialized(struct PyModuleDef* module, int module_api_version) _Py_PackageContext, and PyModule_Create*() will substitute this (if the name actually matches). */ +#define _Py_PackageContext (_PyRuntime.imports.pkgcontext) if (_Py_PackageContext != NULL) { const char *p = strrchr(_Py_PackageContext, '.'); if (p != NULL && strcmp(module->m_name, p+1) == 0) { @@ -236,6 +226,7 @@ _PyModule_CreateInitialized(struct PyModuleDef* module, int module_api_version) _Py_PackageContext = NULL; } } +#undef _Py_PackageContext if ((m = (PyModuleObject*)PyModule_New(name)) == NULL) return NULL; @@ -266,7 +257,7 @@ _PyModule_CreateInitialized(struct PyModuleDef* module, int module_api_version) } PyObject * -PyModule_FromDefAndSpec2(struct PyModuleDef* def, PyObject *spec, int module_api_version) +PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_version) { PyModuleDef_Slot* cur_slot; PyObject *(*create)(PyObject *, PyModuleDef*) = NULL; @@ -300,23 +291,27 @@ PyModule_FromDefAndSpec2(struct PyModuleDef* def, PyObject *spec, int module_api } for (cur_slot = def->m_slots; cur_slot && cur_slot->slot; cur_slot++) { - if (cur_slot->slot == Py_mod_create) { - if (create) { + switch (cur_slot->slot) { + case Py_mod_create: + if (create) { + PyErr_Format( + PyExc_SystemError, + "module %s has multiple create slots", + name); + goto error; + } + create = cur_slot->value; + break; + case Py_mod_exec: + has_execution_slots = 1; + break; + default: + assert(cur_slot->slot < 0 || cur_slot->slot > _Py_mod_LAST_SLOT); PyErr_Format( PyExc_SystemError, - "module %s has multiple create slots", - name); + "module %s uses unknown slot ID %i", + name, cur_slot->slot); goto error; - } - create = cur_slot->value; - } else if (cur_slot->slot < 0 || cur_slot->slot > _Py_mod_LAST_SLOT) { - PyErr_Format( - PyExc_SystemError, - "module %s uses unknown slot ID %i", - name, cur_slot->slot); - goto error; - } else { - has_execution_slots = 1; } } @@ -332,9 +327,10 @@ PyModule_FromDefAndSpec2(struct PyModuleDef* def, PyObject *spec, int module_api goto error; } else { if (PyErr_Occurred()) { - PyErr_Format(PyExc_SystemError, - "creation of module %s raised unreported exception", - name); + _PyErr_FormatFromCause( + PyExc_SystemError, + "creation of module %s raised unreported exception", + name); goto error; } } @@ -436,7 +432,7 @@ PyModule_ExecDef(PyObject *module, PyModuleDef *def) return -1; } if (PyErr_Occurred()) { - PyErr_Format( + _PyErr_FormatFromCause( PyExc_SystemError, "execution of module %s raised unreported exception", name); @@ -474,7 +470,7 @@ PyModule_SetDocString(PyObject *m, const char *doc) PyObject *v; v = PyUnicode_FromString(doc); - if (v == NULL || _PyObject_SetAttrId(m, &PyId___doc__, v) != 0) { + if (v == NULL || PyObject_SetAttr(m, &_Py_ID(__doc__), v) != 0) { Py_XDECREF(v); return -1; } @@ -503,7 +499,7 @@ PyModule_GetNameObject(PyObject *m) } d = ((PyModuleObject *)m)->md_dict; if (d == NULL || !PyDict_Check(d) || - (name = _PyDict_GetItemIdWithError(d, &PyId___name__)) == NULL || + (name = PyDict_GetItemWithError(d, &_Py_ID(__name__))) == NULL || !PyUnicode_Check(name)) { if (!PyErr_Occurred()) { @@ -511,16 +507,17 @@ PyModule_GetNameObject(PyObject *m) } return NULL; } - Py_INCREF(name); - return name; + return Py_NewRef(name); } const char * PyModule_GetName(PyObject *m) { PyObject *name = PyModule_GetNameObject(m); - if (name == NULL) + if (name == NULL) { return NULL; + } + assert(Py_REFCNT(name) >= 2); Py_DECREF(name); /* module dict has still a reference */ return PyUnicode_AsUTF8(name); } @@ -528,7 +525,6 @@ PyModule_GetName(PyObject *m) PyObject* PyModule_GetFilenameObject(PyObject *m) { - _Py_IDENTIFIER(__file__); PyObject *d; PyObject *fileobj; if (!PyModule_Check(m)) { @@ -537,7 +533,7 @@ PyModule_GetFilenameObject(PyObject *m) } d = ((PyModuleObject *)m)->md_dict; if (d == NULL || - (fileobj = _PyDict_GetItemIdWithError(d, &PyId___file__)) == NULL || + (fileobj = PyDict_GetItemWithError(d, &_Py_ID(__file__))) == NULL || !PyUnicode_Check(fileobj)) { if (!PyErr_Occurred()) { @@ -545,8 +541,7 @@ PyModule_GetFilenameObject(PyObject *m) } return NULL; } - Py_INCREF(fileobj); - return fileobj; + return Py_NewRef(fileobj); } const char * @@ -726,8 +721,7 @@ int _PyModuleSpec_IsInitializing(PyObject *spec) { if (spec != NULL) { - _Py_IDENTIFIER(_initializing); - PyObject *value = _PyObject_GetAttrId(spec, &PyId__initializing); + PyObject *value = PyObject_GetAttr(spec, &_Py_ID(_initializing)); if (value != NULL) { int initializing = PyObject_IsTrue(value); Py_DECREF(value); @@ -750,8 +744,7 @@ _PyModuleSpec_IsUninitializedSubmodule(PyObject *spec, PyObject *name) return 0; } - _Py_IDENTIFIER(_uninitialized_submodules); - PyObject *value = _PyObject_GetAttrId(spec, &PyId__uninitialized_submodules); + PyObject *value = PyObject_GetAttr(spec, &_Py_ID(_uninitialized_submodules)); if (value == NULL) { return 0; } @@ -774,18 +767,17 @@ module_getattro(PyModuleObject *m, PyObject *name) } PyErr_Clear(); assert(m->md_dict != NULL); - _Py_IDENTIFIER(__getattr__); - getattr = _PyDict_GetItemIdWithError(m->md_dict, &PyId___getattr__); + getattr = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__getattr__)); if (getattr) { return PyObject_CallOneArg(getattr, name); } if (PyErr_Occurred()) { return NULL; } - mod_name = _PyDict_GetItemIdWithError(m->md_dict, &PyId___name__); + mod_name = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__name__)); if (mod_name && PyUnicode_Check(mod_name)) { Py_INCREF(mod_name); - PyObject *spec = _PyDict_GetItemIdWithError(m->md_dict, &PyId___spec__); + PyObject *spec = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__spec__)); if (spec == NULL && PyErr_Occurred()) { Py_DECREF(mod_name); return NULL; @@ -861,11 +853,11 @@ static PyObject * module_dir(PyObject *self, PyObject *args) { PyObject *result = NULL; - PyObject *dict = _PyObject_GetAttrId(self, &PyId___dict__); + PyObject *dict = PyObject_GetAttr(self, &_Py_ID(__dict__)); if (dict != NULL) { if (PyDict_Check(dict)) { - PyObject *dirfunc = _PyDict_GetItemIdWithError(dict, &PyId___dir__); + PyObject *dirfunc = PyDict_GetItemWithError(dict, &_Py_ID(__dir__)); if (dirfunc) { result = _PyObject_CallNoArgs(dirfunc); } @@ -891,7 +883,7 @@ static PyMethodDef module_methods[] = { static PyObject * module_get_annotations(PyModuleObject *m, void *Py_UNUSED(ignored)) { - PyObject *dict = _PyObject_GetAttrId((PyObject *)m, &PyId___dict__); + PyObject *dict = PyObject_GetAttr((PyObject *)m, &_Py_ID(__dict__)); if ((dict == NULL) || !PyDict_Check(dict)) { PyErr_Format(PyExc_TypeError, ".__dict__ is not a dictionary"); @@ -901,8 +893,8 @@ module_get_annotations(PyModuleObject *m, void *Py_UNUSED(ignored)) PyObject *annotations; /* there's no _PyDict_GetItemId without WithError, so let's LBYL. */ - if (_PyDict_ContainsId(dict, &PyId___annotations__)) { - annotations = _PyDict_GetItemIdWithError(dict, &PyId___annotations__); + if (PyDict_Contains(dict, &_Py_ID(__annotations__))) { + annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__)); /* ** _PyDict_GetItemIdWithError could still fail, ** for instance with a well-timed Ctrl-C or a MemoryError. @@ -914,7 +906,8 @@ module_get_annotations(PyModuleObject *m, void *Py_UNUSED(ignored)) } else { annotations = PyDict_New(); if (annotations) { - int result = _PyDict_SetItemId(dict, &PyId___annotations__, annotations); + int result = PyDict_SetItem( + dict, &_Py_ID(__annotations__), annotations); if (result) { Py_CLEAR(annotations); } @@ -928,7 +921,7 @@ static int module_set_annotations(PyModuleObject *m, PyObject *value, void *Py_UNUSED(ignored)) { int ret = -1; - PyObject *dict = _PyObject_GetAttrId((PyObject *)m, &PyId___dict__); + PyObject *dict = PyObject_GetAttr((PyObject *)m, &_Py_ID(__dict__)); if ((dict == NULL) || !PyDict_Check(dict)) { PyErr_Format(PyExc_TypeError, ".__dict__ is not a dictionary"); @@ -937,17 +930,17 @@ module_set_annotations(PyModuleObject *m, PyObject *value, void *Py_UNUSED(ignor if (value != NULL) { /* set */ - ret = _PyDict_SetItemId(dict, &PyId___annotations__, value); + ret = PyDict_SetItem(dict, &_Py_ID(__annotations__), value); goto exit; } /* delete */ - if (!_PyDict_ContainsId(dict, &PyId___annotations__)) { + if (!PyDict_Contains(dict, &_Py_ID(__annotations__))) { PyErr_Format(PyExc_AttributeError, "__annotations__"); goto exit; } - ret = _PyDict_DelItemId(dict, &PyId___annotations__); + ret = PyDict_DelItem(dict, &_Py_ID(__annotations__)); exit: Py_XDECREF(dict); diff --git a/Objects/namespaceobject.c b/Objects/namespaceobject.c index 7875e7cafec..2cc4ddd3c91 100644 --- a/Objects/namespaceobject.c +++ b/Objects/namespaceobject.c @@ -85,9 +85,8 @@ namespace_repr(PyObject *ns) if (pairs == NULL) goto error; - d = ((_PyNamespaceObject *)ns)->ns_dict; - assert(d != NULL); - Py_INCREF(d); + assert(((_PyNamespaceObject *)ns)->ns_dict != NULL); + d = Py_NewRef(((_PyNamespaceObject *)ns)->ns_dict); keys = PyDict_Keys(d); if (keys == NULL) diff --git a/Objects/object.c b/Objects/object.c index 25f5a2133d5..e940222c657 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -3,19 +3,18 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() -#include "pycore_ceval.h" // _Py_EnterRecursiveCall() +#include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() +#include "pycore_context.h" // _PyContextTokenMissing_Type #include "pycore_dict.h" // _PyObject_MakeDictFromInstanceAttributes() #include "pycore_floatobject.h" // _PyFloat_DebugMallocStats() #include "pycore_initconfig.h" // _PyStatus_EXCEPTION() #include "pycore_namespace.h" // _PyNamespace_Type -#include "pycore_object.h" // _PyType_CheckConsistency() +#include "pycore_object.h" // _PyType_CheckConsistency(), _Py_FatalRefcountError() #include "pycore_pyerrors.h" // _PyErr_Occurred() -#include "pycore_pylifecycle.h" // _PyTypes_InitSlotDefs() #include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_symtable.h" // PySTEntry_Type #include "pycore_unionobject.h" // _PyUnion_Type -#include "frameobject.h" // PyFrame_Type #include "pycore_interpreteridobject.h" // _PyInterpreterID_Type #ifdef Py_LIMITED_API @@ -30,11 +29,6 @@ extern "C" { /* Defined in tracemalloc.c */ extern void _PyMem_DumpTraceback(int fd, const void *ptr); -_Py_IDENTIFIER(Py_Repr); -_Py_IDENTIFIER(__bytes__); -_Py_IDENTIFIER(__dir__); -_Py_IDENTIFIER(__isabstractmethod__); - int _PyObject_CheckConsistency(PyObject *op, int check_content) @@ -65,12 +59,7 @@ Py_ssize_t _Py_RefTotal; Py_ssize_t _Py_GetRefTotal(void) { - PyObject *o; - Py_ssize_t total = _Py_RefTotal; - o = _PySet_Dummy; - if (o != NULL) - total -= Py_REFCNT(o); - return total; + return _Py_RefTotal; } void @@ -283,11 +272,8 @@ PyObject_Print(PyObject *op, FILE *fp, int flags) } else { if (Py_REFCNT(op) <= 0) { - /* XXX(twouters) cast refcount to long until %zd is - universally available */ Py_BEGIN_ALLOW_THREADS - fprintf(fp, "", - (long)Py_REFCNT(op), (void *)op); + fprintf(fp, "", Py_REFCNT(op), (void *)op); Py_END_ALLOW_THREADS } else { @@ -296,31 +282,22 @@ PyObject_Print(PyObject *op, FILE *fp, int flags) s = PyObject_Str(op); else s = PyObject_Repr(op); - if (s == NULL) + if (s == NULL) { ret = -1; - else if (PyBytes_Check(s)) { - fwrite(PyBytes_AS_STRING(s), 1, - PyBytes_GET_SIZE(s), fp); } - else if (PyUnicode_Check(s)) { - PyObject *t; - t = PyUnicode_AsEncodedString(s, "utf-8", "backslashreplace"); + else { + assert(PyUnicode_Check(s)); + const char *t; + Py_ssize_t len; + t = PyUnicode_AsUTF8AndSize(s, &len); if (t == NULL) { ret = -1; } else { - fwrite(PyBytes_AS_STRING(t), 1, - PyBytes_GET_SIZE(t), fp); - Py_DECREF(t); + fwrite(t, 1, len, fp); } + Py_DECREF(s); } - else { - PyErr_Format(PyExc_TypeError, - "str() or repr() returned '%.100s'", - Py_TYPE(s)->tp_name); - ret = -1; - } - Py_XDECREF(s); } } if (ret == 0) { @@ -380,9 +357,7 @@ _PyObject_Dump(PyObject* op) /* first, write fields which are the least likely to crash */ fprintf(stderr, "object address : %p\n", (void *)op); - /* XXX(twouters) cast refcount to long until %zd is - universally available */ - fprintf(stderr, "object refcount : %ld\n", (long)Py_REFCNT(op)); + fprintf(stderr, "object refcount : %zd\n", Py_REFCNT(op)); fflush(stderr); PyTypeObject *type = Py_TYPE(op); @@ -436,12 +411,12 @@ PyObject_Repr(PyObject *v) /* It is possible for a type to have a tp_repr representation that loops infinitely. */ - if (_Py_EnterRecursiveCall(tstate, - " while getting the repr of an object")) { + if (_Py_EnterRecursiveCallTstate(tstate, + " while getting the repr of an object")) { return NULL; } res = (*Py_TYPE(v)->tp_repr)(v); - _Py_LeaveRecursiveCall(tstate); + _Py_LeaveRecursiveCallTstate(tstate); if (res == NULL) { return NULL; @@ -480,8 +455,7 @@ PyObject_Str(PyObject *v) if (PyUnicode_READY(v) < 0) return NULL; #endif - Py_INCREF(v); - return v; + return Py_NewRef(v); } if (Py_TYPE(v)->tp_str == NULL) return PyObject_Repr(v); @@ -496,11 +470,11 @@ PyObject_Str(PyObject *v) /* It is possible for a type to have a tp_str representation that loops infinitely. */ - if (_Py_EnterRecursiveCall(tstate, " while getting the str of an object")) { + if (_Py_EnterRecursiveCallTstate(tstate, " while getting the str of an object")) { return NULL; } res = (*Py_TYPE(v)->tp_str)(v); - _Py_LeaveRecursiveCall(tstate); + _Py_LeaveRecursiveCallTstate(tstate); if (res == NULL) { return NULL; @@ -557,11 +531,10 @@ PyObject_Bytes(PyObject *v) return PyBytes_FromString(""); if (PyBytes_CheckExact(v)) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } - func = _PyObject_LookupSpecial(v, &PyId___bytes__); + func = _PyObject_LookupSpecial(v, &_Py_ID(__bytes__)); if (func != NULL) { result = _PyObject_CallNoArgs(func); Py_DECREF(func); @@ -599,12 +572,9 @@ def _PyObject_FunctionStr(x): PyObject * _PyObject_FunctionStr(PyObject *x) { - _Py_IDENTIFIER(__module__); - _Py_IDENTIFIER(__qualname__); - _Py_IDENTIFIER(builtins); assert(!PyErr_Occurred()); PyObject *qualname; - int ret = _PyObject_LookupAttrId(x, &PyId___qualname__, &qualname); + int ret = _PyObject_LookupAttr(x, &_Py_ID(__qualname__), &qualname); if (qualname == NULL) { if (ret < 0) { return NULL; @@ -613,13 +583,9 @@ _PyObject_FunctionStr(PyObject *x) } PyObject *module; PyObject *result = NULL; - ret = _PyObject_LookupAttrId(x, &PyId___module__, &module); + ret = _PyObject_LookupAttr(x, &_Py_ID(__module__), &module); if (module != NULL && module != Py_None) { - PyObject *builtinsname = _PyUnicode_FromId(&PyId_builtins); - if (builtinsname == NULL) { - goto done; - } - ret = PyObject_RichCompareBool(module, builtinsname, Py_NE); + ret = PyObject_RichCompareBool(module, &_Py_ID(builtins), Py_NE); if (ret < 0) { // error goto done; @@ -721,8 +687,7 @@ do_richcompare(PyThreadState *tstate, PyObject *v, PyObject *w, int op) Py_TYPE(w)->tp_name); return NULL; } - Py_INCREF(res); - return res; + return Py_NewRef(res); } /* Perform a rich comparison with object result. This wraps do_richcompare() @@ -740,11 +705,11 @@ PyObject_RichCompare(PyObject *v, PyObject *w, int op) } return NULL; } - if (_Py_EnterRecursiveCall(tstate, " in comparison")) { + if (_Py_EnterRecursiveCallTstate(tstate, " in comparison")) { return NULL; } PyObject *res = do_richcompare(tstate, v, w, op); - _Py_LeaveRecursiveCall(tstate); + _Py_LeaveRecursiveCallTstate(tstate); return res; } @@ -857,7 +822,7 @@ _PyObject_IsAbstract(PyObject *obj) if (obj == NULL) return 0; - res = _PyObject_LookupAttrId(obj, &PyId___isabstractmethod__, &isabstract); + res = _PyObject_LookupAttr(obj, &_Py_ID(__isabstractmethod__), &isabstract); if (res > 0) { res = PyObject_IsTrue(isabstract); Py_DECREF(isabstract); @@ -891,21 +856,29 @@ static inline int set_attribute_error_context(PyObject* v, PyObject* name) { assert(PyErr_Occurred()); - _Py_IDENTIFIER(name); - _Py_IDENTIFIER(obj); - // Intercept AttributeError exceptions and augment them to offer - // suggestions later. - if (PyErr_ExceptionMatches(PyExc_AttributeError)){ - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); - PyErr_NormalizeException(&type, &value, &traceback); - if (PyErr_GivenExceptionMatches(value, PyExc_AttributeError) && - (_PyObject_SetAttrId(value, &PyId_name, name) || - _PyObject_SetAttrId(value, &PyId_obj, v))) { - return 1; - } - PyErr_Restore(type, value, traceback); + if (!PyErr_ExceptionMatches(PyExc_AttributeError)){ + return 0; } + // Intercept AttributeError exceptions and augment them to offer suggestions later. + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + PyErr_NormalizeException(&type, &value, &traceback); + // Check if the normalized exception is indeed an AttributeError + if (!PyErr_GivenExceptionMatches(value, PyExc_AttributeError)) { + goto restore; + } + PyAttributeErrorObject* the_exc = (PyAttributeErrorObject*) value; + // Check if this exception was already augmented + if (the_exc->name || the_exc->obj) { + goto restore; + } + // Augment the exception with the name and object + if (PyObject_SetAttr(value, &_Py_ID(name), name) || + PyObject_SetAttr(value, &_Py_ID(obj), v)) { + return 1; + } +restore: + PyErr_Restore(type, value, traceback); return 0; } @@ -966,7 +939,15 @@ _PyObject_LookupAttr(PyObject *v, PyObject *name, PyObject **result) } return 0; } - if (tp->tp_getattro != NULL) { + if (tp->tp_getattro == (getattrofunc)_Py_type_getattro) { + int supress_missing_attribute_exception = 0; + *result = _Py_type_getattro_impl((PyTypeObject*)v, name, &supress_missing_attribute_exception); + if (supress_missing_attribute_exception) { + // return 0 without having to clear the exception + return 0; + } + } + else if (tp->tp_getattro != NULL) { *result = (*tp->tp_getattro)(v, name); } else if (tp->tp_getattr != NULL) { @@ -1068,22 +1049,27 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) } PyObject ** -_PyObject_DictPointer(PyObject *obj) +_PyObject_ComputedDictPointer(PyObject *obj) { - Py_ssize_t dictoffset; PyTypeObject *tp = Py_TYPE(obj); + assert((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); - dictoffset = tp->tp_dictoffset; - if (dictoffset == 0) + Py_ssize_t dictoffset = tp->tp_dictoffset; + if (dictoffset == 0) { return NULL; + } + if (dictoffset < 0) { + assert(dictoffset != -1); + Py_ssize_t tsize = Py_SIZE(obj); if (tsize < 0) { tsize = -tsize; } size_t size = _PyObject_VAR_SIZE(tp, tsize); + assert(size <= (size_t)PY_SSIZE_T_MAX); + dictoffset += (Py_ssize_t)size; - dictoffset += (long)size; _PyObject_ASSERT(obj, dictoffset > 0); _PyObject_ASSERT(obj, dictoffset % SIZEOF_VOID_P == 0); } @@ -1092,38 +1078,33 @@ _PyObject_DictPointer(PyObject *obj) /* Helper to get a pointer to an object's __dict__ slot, if any. * Creates the dict from inline attributes if necessary. - * Does not set an exception. */ + * Does not set an exception. + * + * Note that the tp_dictoffset docs used to recommend this function, + * so it should be treated as part of the public API. + */ PyObject ** _PyObject_GetDictPtr(PyObject *obj) { - PyObject **dict_ptr = _PyObject_DictPointer(obj); - if (dict_ptr == NULL) { - return NULL; + if ((Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { + return _PyObject_ComputedDictPointer(obj); } - if (*dict_ptr != NULL) { - return dict_ptr; + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyObject *dict = _PyObject_MakeDictFromInstanceAttributes(obj, _PyDictOrValues_GetValues(*dorv_ptr)); + if (dict == NULL) { + PyErr_Clear(); + return NULL; + } + dorv_ptr->dict = dict; } - PyDictValues **values_ptr = _PyObject_ValuesPointer(obj); - if (values_ptr == NULL || *values_ptr == NULL) { - return dict_ptr; - } - PyObject *dict = _PyObject_MakeDictFromInstanceAttributes(obj, *values_ptr); - if (dict == NULL) { - PyErr_Clear(); - return NULL; - } - assert(*dict_ptr == NULL); - assert(*values_ptr != NULL); - *values_ptr = NULL; - *dict_ptr = dict; - return dict_ptr; + return &dorv_ptr->dict; } PyObject * PyObject_SelfIter(PyObject *obj) { - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } /* Helper used when the __next__ method is removed from a type: @@ -1185,34 +1166,46 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) } } } - PyDictValues **values_ptr = _PyObject_ValuesPointer(obj); - if (values_ptr && *values_ptr) { - assert(*_PyObject_DictPointer(obj) == NULL); - PyObject *attr = _PyObject_GetInstanceAttribute(obj, *values_ptr, name); - if (attr != NULL) { - *method = attr; - Py_XDECREF(descr); - return 0; + PyObject *dict; + if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + PyDictOrValues* dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + PyObject *attr = _PyObject_GetInstanceAttribute(obj, values, name); + if (attr != NULL) { + *method = attr; + Py_XDECREF(descr); + return 0; + } + dict = NULL; + } + else { + dict = dorv_ptr->dict; } } else { - PyObject **dictptr = _PyObject_DictPointer(obj); - PyObject *dict; - if (dictptr != NULL && (dict = *dictptr) != NULL) { - Py_INCREF(dict); - PyObject *attr = PyDict_GetItemWithError(dict, name); - if (attr != NULL) { - *method = Py_NewRef(attr); - Py_DECREF(dict); - Py_XDECREF(descr); - return 0; - } + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); + if (dictptr != NULL) { + dict = *dictptr; + } + else { + dict = NULL; + } + } + if (dict != NULL) { + Py_INCREF(dict); + PyObject *attr = PyDict_GetItemWithError(dict, name); + if (attr != NULL) { + *method = Py_NewRef(attr); Py_DECREF(dict); + Py_XDECREF(descr); + return 0; + } + Py_DECREF(dict); - if (PyErr_Occurred()) { - Py_XDECREF(descr); - return 0; - } + if (PyErr_Occurred()) { + Py_XDECREF(descr); + return 0; } } @@ -1240,17 +1233,6 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) return 0; } -PyDictValues ** -_PyObject_ValuesPointer(PyObject *obj) -{ - PyTypeObject *tp = Py_TYPE(obj); - Py_ssize_t offset = tp->tp_inline_values_offset; - if (offset == 0) { - return NULL; - } - return (PyDictValues **) ((char *)obj + offset); -} - /* Generic GetAttr functions - put these in your tp_[gs]etattro slot. */ PyObject * @@ -1267,8 +1249,6 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *descr = NULL; PyObject *res = NULL; descrgetfunc f; - Py_ssize_t dictoffset; - PyObject **dictptr; if (!PyUnicode_Check(name)){ PyErr_Format(PyExc_TypeError, @@ -1299,43 +1279,32 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, } } if (dict == NULL) { - PyDictValues **values_ptr = _PyObject_ValuesPointer(obj); - if (values_ptr && *values_ptr) { - if (PyUnicode_CheckExact(name)) { - assert(*_PyObject_DictPointer(obj) == NULL); - res = _PyObject_GetInstanceAttribute(obj, *values_ptr, name); - if (res != NULL) { - goto done; + if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + PyDictOrValues* dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + if (PyUnicode_CheckExact(name)) { + res = _PyObject_GetInstanceAttribute(obj, values, name); + if (res != NULL) { + goto done; + } + } + else { + dict = _PyObject_MakeDictFromInstanceAttributes(obj, values); + if (dict == NULL) { + res = NULL; + goto done; + } + dorv_ptr->dict = dict; } } else { - dictptr = _PyObject_DictPointer(obj); - assert(dictptr != NULL && *dictptr == NULL); - *dictptr = dict = _PyObject_MakeDictFromInstanceAttributes(obj, *values_ptr); - if (dict == NULL) { - res = NULL; - goto done; - } - *values_ptr = NULL; + dict = _PyDictOrValues_GetDict(*dorv_ptr); } } else { - /* Inline _PyObject_DictPointer */ - dictoffset = tp->tp_dictoffset; - if (dictoffset != 0) { - if (dictoffset < 0) { - Py_ssize_t tsize = Py_SIZE(obj); - if (tsize < 0) { - tsize = -tsize; - } - size_t size = _PyObject_VAR_SIZE(tp, tsize); - _PyObject_ASSERT(obj, size <= PY_SSIZE_T_MAX); - - dictoffset += (Py_ssize_t)size; - _PyObject_ASSERT(obj, dictoffset > 0); - _PyObject_ASSERT(obj, dictoffset % SIZEOF_VOID_P == 0); - } - dictptr = (PyObject **) ((char *)obj + dictoffset); + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); + if (dictptr) { dict = *dictptr; } } @@ -1380,6 +1349,8 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyErr_Format(PyExc_AttributeError, "'%.50s' object has no attribute '%U'", tp->tp_name, name); + + set_attribute_error_context(obj, name); } done: Py_XDECREF(descr); @@ -1413,7 +1384,7 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, return -1; Py_INCREF(name); - + Py_INCREF(tp); descr = _PyType_Lookup(tp, name); if (descr != NULL) { @@ -1426,28 +1397,34 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, } if (dict == NULL) { - PyDictValues **values_ptr = _PyObject_ValuesPointer(obj); - if (values_ptr && *values_ptr) { - res = _PyObject_StoreInstanceAttribute(obj, *values_ptr, name, value); + PyObject **dictptr; + if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + res = _PyObject_StoreInstanceAttribute( + obj, _PyDictOrValues_GetValues(*dorv_ptr), name, value); + goto error_check; + } + dictptr = &dorv_ptr->dict; } else { - PyObject **dictptr = _PyObject_DictPointer(obj); - if (dictptr == NULL) { - if (descr == NULL) { - PyErr_Format(PyExc_AttributeError, - "'%.100s' object has no attribute '%U'", - tp->tp_name, name); - } - else { - PyErr_Format(PyExc_AttributeError, - "'%.50s' object attribute '%U' is read-only", - tp->tp_name, name); - } - goto done; + dictptr = _PyObject_ComputedDictPointer(obj); + } + if (dictptr == NULL) { + if (descr == NULL) { + PyErr_Format(PyExc_AttributeError, + "'%.100s' object has no attribute '%U'", + tp->tp_name, name); } else { - res = _PyObjectDict_SetItem(tp, dictptr, name, value); + PyErr_Format(PyExc_AttributeError, + "'%.50s' object attribute '%U' is read-only", + tp->tp_name, name); } + goto done; + } + else { + res = _PyObjectDict_SetItem(tp, dictptr, name, value); } } else { @@ -1458,11 +1435,22 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, res = PyDict_SetItem(dict, name, value); Py_DECREF(dict); } - if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) - PyErr_SetObject(PyExc_AttributeError, name); - + error_check: + if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) { + if (PyType_IsSubtype(tp, &PyType_Type)) { + PyErr_Format(PyExc_AttributeError, + "type object '%.50s' has no attribute '%U'", + ((PyTypeObject*)obj)->tp_name, name); + } + else { + PyErr_Format(PyExc_AttributeError, + "'%.100s' object has no attribute '%U'", + tp->tp_name, name); + } + } done: Py_XDECREF(descr); + Py_DECREF(tp); Py_DECREF(name); return res; } @@ -1478,8 +1466,9 @@ PyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context) { PyObject **dictptr = _PyObject_GetDictPtr(obj); if (dictptr == NULL) { - PyDictValues** values_ptr = _PyObject_ValuesPointer(obj); - if (values_ptr != NULL && *values_ptr != NULL) { + if (_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_MANAGED_DICT) && + _PyDictOrValues_IsValues(*_PyObject_DictOrValuesPointer(obj))) + { /* Was unable to convert to dict */ PyErr_NoMemory(); } @@ -1499,8 +1488,7 @@ PyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context) "not a '%.200s'", Py_TYPE(value)->tp_name); return -1; } - Py_INCREF(value); - Py_XSETREF(*dictptr, value); + Py_XSETREF(*dictptr, Py_NewRef(value)); return 0; } @@ -1591,7 +1579,7 @@ static PyObject * _dir_object(PyObject *obj) { PyObject *result, *sorted; - PyObject *dirfunc = _PyObject_LookupSpecial(obj, &PyId___dir__); + PyObject *dirfunc = _PyObject_LookupSpecial(obj, &_Py_ID(__dir__)); assert(obj != NULL); if (dirfunc == NULL) { @@ -1661,6 +1649,11 @@ none_bool(PyObject *v) return 0; } +static Py_hash_t none_hash(PyObject *v) +{ + return 0xFCA86420; +} + static PyNumberMethods none_as_number = { 0, /* nb_add */ 0, /* nb_subtract */ @@ -1712,7 +1705,7 @@ PyTypeObject _PyNone_Type = { &none_as_number, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ - 0, /*tp_hash */ + (hashfunc)none_hash,/*tp_hash */ 0, /*tp_call */ 0, /*tp_str */ 0, /*tp_getattro */ @@ -1845,125 +1838,186 @@ PyObject _Py_NotImplementedStruct = { 1, &_PyNotImplemented_Type }; +#ifdef MS_WINDOWS +extern PyTypeObject PyHKEY_Type; +#endif +extern PyTypeObject _Py_GenericAliasIterType; +extern PyTypeObject _PyMemoryIter_Type; +extern PyTypeObject _PyLineIterator; +extern PyTypeObject _PyPositionsIterator; + +static PyTypeObject* static_types[] = { + // The two most important base types: must be initialized first and + // deallocated last. + &PyBaseObject_Type, + &PyType_Type, + + // Static types with base=&PyBaseObject_Type + &PyAsyncGen_Type, + &PyByteArrayIter_Type, + &PyByteArray_Type, + &PyBytesIter_Type, + &PyBytes_Type, + &PyCFunction_Type, + &PyCallIter_Type, + &PyCapsule_Type, + &PyCell_Type, + &PyClassMethodDescr_Type, + &PyClassMethod_Type, + &PyCode_Type, + &PyComplex_Type, + &PyContextToken_Type, + &PyContextVar_Type, + &PyContext_Type, + &PyCoro_Type, + &PyDictItems_Type, + &PyDictIterItem_Type, + &PyDictIterKey_Type, + &PyDictIterValue_Type, + &PyDictKeys_Type, + &PyDictProxy_Type, + &PyDictRevIterItem_Type, + &PyDictRevIterKey_Type, + &PyDictRevIterValue_Type, + &PyDictValues_Type, + &PyDict_Type, + &PyEllipsis_Type, + &PyEnum_Type, + &PyFilter_Type, + &PyFloat_Type, + &PyFrame_Type, + &PyFrozenSet_Type, + &PyFunction_Type, + &PyGen_Type, + &PyGetSetDescr_Type, +#ifdef MS_WINDOWS + &PyHKEY_Type, +#endif + &PyInstanceMethod_Type, + &PyListIter_Type, + &PyListRevIter_Type, + &PyList_Type, + &PyLongRangeIter_Type, + &PyLong_Type, + &PyMap_Type, + &PyMemberDescr_Type, + &PyMemoryView_Type, + &PyMethodDescr_Type, + &PyMethod_Type, + &PyModuleDef_Type, + &PyModule_Type, + &PyODictIter_Type, + &PyPickleBuffer_Type, + &PyProperty_Type, + &PyRangeIter_Type, + &PyRange_Type, + &PyReversed_Type, + &PySTEntry_Type, + &PySeqIter_Type, + &PySetIter_Type, + &PySet_Type, + &PySlice_Type, + &PyStaticMethod_Type, + &PyStdPrinter_Type, + &PySuper_Type, + &PyTraceBack_Type, + &PyTupleIter_Type, + &PyTuple_Type, + &PyUnicodeIter_Type, + &PyUnicode_Type, + &PyWrapperDescr_Type, + &PyZip_Type, + &Py_GenericAliasType, + &_PyAnextAwaitable_Type, + &_PyAsyncGenASend_Type, + &_PyAsyncGenAThrow_Type, + &_PyAsyncGenWrappedValue_Type, + &_PyContextTokenMissing_Type, + &_PyCoroWrapper_Type, + &_Py_GenericAliasIterType, + &_PyHamtItems_Type, + &_PyHamtKeys_Type, + &_PyHamtValues_Type, + &_PyHamt_ArrayNode_Type, + &_PyHamt_BitmapNode_Type, + &_PyHamt_CollisionNode_Type, + &_PyHamt_Type, + &_PyInterpreterID_Type, + &_PyLineIterator, + &_PyManagedBuffer_Type, + &_PyMemoryIter_Type, + &_PyMethodWrapper_Type, + &_PyNamespace_Type, + &_PyNone_Type, + &_PyNotImplemented_Type, + &_PyPositionsIterator, + &_PyUnicodeASCIIIter_Type, + &_PyUnion_Type, + &_PyWeakref_CallableProxyType, + &_PyWeakref_ProxyType, + &_PyWeakref_RefType, + + // subclasses: _PyTypes_FiniTypes() deallocates them before their base + // class + &PyBool_Type, // base=&PyLong_Type + &PyCMethod_Type, // base=&PyCFunction_Type + &PyODictItems_Type, // base=&PyDictItems_Type + &PyODictKeys_Type, // base=&PyDictKeys_Type + &PyODictValues_Type, // base=&PyDictValues_Type + &PyODict_Type, // base=&PyDict_Type +}; + + PyStatus -_PyTypes_Init(void) +_PyTypes_InitTypes(PyInterpreterState *interp) { - PyStatus status = _PyTypes_InitSlotDefs(); - if (_PyStatus_EXCEPTION(status)) { - return status; + if (!_Py_IsMainInterpreter(interp)) { + return _PyStatus_OK(); } -#define INIT_TYPE(TYPE) \ - do { \ - if (PyType_Ready(&(TYPE)) < 0) { \ - return _PyStatus_ERR("Can't initialize " #TYPE " type"); \ - } \ - } while (0) - - // Base types - INIT_TYPE(PyBaseObject_Type); - INIT_TYPE(PyType_Type); - assert(PyBaseObject_Type.tp_base == NULL); - assert(PyType_Type.tp_base == &PyBaseObject_Type); - - // All other static types - INIT_TYPE(PyAsyncGen_Type); - INIT_TYPE(PyBool_Type); - INIT_TYPE(PyByteArrayIter_Type); - INIT_TYPE(PyByteArray_Type); - INIT_TYPE(PyBytesIter_Type); - INIT_TYPE(PyBytes_Type); - INIT_TYPE(PyCFunction_Type); - INIT_TYPE(PyCMethod_Type); - INIT_TYPE(PyCallIter_Type); - INIT_TYPE(PyCapsule_Type); - INIT_TYPE(PyCell_Type); - INIT_TYPE(PyClassMethodDescr_Type); - INIT_TYPE(PyClassMethod_Type); - INIT_TYPE(PyCode_Type); - INIT_TYPE(PyComplex_Type); - INIT_TYPE(PyCoro_Type); - INIT_TYPE(PyDictItems_Type); - INIT_TYPE(PyDictIterItem_Type); - INIT_TYPE(PyDictIterKey_Type); - INIT_TYPE(PyDictIterValue_Type); - INIT_TYPE(PyDictKeys_Type); - INIT_TYPE(PyDictProxy_Type); - INIT_TYPE(PyDictRevIterItem_Type); - INIT_TYPE(PyDictRevIterKey_Type); - INIT_TYPE(PyDictRevIterValue_Type); - INIT_TYPE(PyDictValues_Type); - INIT_TYPE(PyDict_Type); - INIT_TYPE(PyEllipsis_Type); - INIT_TYPE(PyEnum_Type); - INIT_TYPE(PyFloat_Type); - INIT_TYPE(PyFrame_Type); - INIT_TYPE(PyFrozenSet_Type); - INIT_TYPE(PyFunction_Type); - INIT_TYPE(PyGen_Type); - INIT_TYPE(PyGetSetDescr_Type); - INIT_TYPE(PyInstanceMethod_Type); - INIT_TYPE(PyListIter_Type); - INIT_TYPE(PyListRevIter_Type); - INIT_TYPE(PyList_Type); - INIT_TYPE(PyLongRangeIter_Type); - INIT_TYPE(PyLong_Type); - INIT_TYPE(PyMemberDescr_Type); - INIT_TYPE(PyMemoryView_Type); - INIT_TYPE(PyMethodDescr_Type); - INIT_TYPE(PyMethod_Type); - INIT_TYPE(PyModuleDef_Type); - INIT_TYPE(PyModule_Type); - INIT_TYPE(PyODictItems_Type); - INIT_TYPE(PyODictIter_Type); - INIT_TYPE(PyODictKeys_Type); - INIT_TYPE(PyODictValues_Type); - INIT_TYPE(PyODict_Type); - INIT_TYPE(PyPickleBuffer_Type); - INIT_TYPE(PyProperty_Type); - INIT_TYPE(PyRangeIter_Type); - INIT_TYPE(PyRange_Type); - INIT_TYPE(PyReversed_Type); - INIT_TYPE(PySTEntry_Type); - INIT_TYPE(PySeqIter_Type); - INIT_TYPE(PySetIter_Type); - INIT_TYPE(PySet_Type); - INIT_TYPE(PySlice_Type); - INIT_TYPE(PyStaticMethod_Type); - INIT_TYPE(PyStdPrinter_Type); - INIT_TYPE(PySuper_Type); - INIT_TYPE(PyTraceBack_Type); - INIT_TYPE(PyTupleIter_Type); - INIT_TYPE(PyTuple_Type); - INIT_TYPE(PyUnicodeIter_Type); - INIT_TYPE(PyUnicode_Type); - INIT_TYPE(PyWrapperDescr_Type); - INIT_TYPE(Py_GenericAliasType); - INIT_TYPE(_PyAnextAwaitable_Type); - INIT_TYPE(_PyAsyncGenASend_Type); - INIT_TYPE(_PyAsyncGenAThrow_Type); - INIT_TYPE(_PyAsyncGenWrappedValue_Type); - INIT_TYPE(_PyCoroWrapper_Type); - INIT_TYPE(_PyInterpreterID_Type); - INIT_TYPE(_PyManagedBuffer_Type); - INIT_TYPE(_PyMethodWrapper_Type); - INIT_TYPE(_PyNamespace_Type); - INIT_TYPE(_PyNone_Type); - INIT_TYPE(_PyNotImplemented_Type); - INIT_TYPE(_PyWeakref_CallableProxyType); - INIT_TYPE(_PyWeakref_ProxyType); - INIT_TYPE(_PyWeakref_RefType); - INIT_TYPE(_PyUnion_Type); + // All other static types (unless initialized elsewhere) + for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) { + PyTypeObject *type = static_types[i]; + if (_PyStaticType_InitBuiltin(type) < 0) { + return _PyStatus_ERR("Can't initialize builtin type"); + } + if (type == &PyType_Type) { + // Sanitify checks of the two most important types + assert(PyBaseObject_Type.tp_base == NULL); + assert(PyType_Type.tp_base == &PyBaseObject_Type); + } + } return _PyStatus_OK(); -#undef INIT_TYPE +} + + +// Best-effort function clearing static types. +// +// Don't deallocate a type if it still has subclasses. If a Py_Finalize() +// sub-function is interrupted by CTRL+C or fails with MemoryError, some +// subclasses are not cleared properly. Leave the static type unchanged in this +// case. +void +_PyTypes_FiniTypes(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + return; + } + + // Deallocate types in the reverse order to deallocate subclasses before + // their base classes. + for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types)-1; i>=0; i--) { + PyTypeObject *type = static_types[i]; + _PyStaticType_Dealloc(type); + } } void _Py_NewReference(PyObject *op) { - if (_Py_tracemalloc_config.tracing) { + if (_PyRuntime.tracemalloc.config.tracing) { _PyTraceMalloc_NewReference(op); } #ifdef Py_REF_DEBUG @@ -2080,7 +2134,6 @@ _PyObject_DebugTypeStats(FILE *out) { _PyDict_DebugMallocStats(out); _PyFloat_DebugMallocStats(out); - _PyFrame_DebugMallocStats(out); _PyList_DebugMallocStats(out); _PyTuple_DebugMallocStats(out); } @@ -2109,7 +2162,7 @@ Py_ReprEnter(PyObject *obj) early on startup. */ if (dict == NULL) return 0; - list = _PyDict_GetItemIdWithError(dict, &PyId_Py_Repr); + list = PyDict_GetItemWithError(dict, &_Py_ID(Py_Repr)); if (list == NULL) { if (PyErr_Occurred()) { return -1; @@ -2117,7 +2170,7 @@ Py_ReprEnter(PyObject *obj) list = PyList_New(0); if (list == NULL) return -1; - if (_PyDict_SetItemId(dict, &PyId_Py_Repr, list) < 0) + if (PyDict_SetItem(dict, &_Py_ID(Py_Repr), list) < 0) return -1; Py_DECREF(list); } @@ -2145,7 +2198,7 @@ Py_ReprLeave(PyObject *obj) if (dict == NULL) goto finally; - list = _PyDict_GetItemIdWithError(dict, &PyId_Py_Repr); + list = PyDict_GetItemWithError(dict, &_Py_ID(Py_Repr)); if (list == NULL || !PyList_Check(list)) goto finally; @@ -2172,22 +2225,20 @@ finally: * object, with refcount 0. Py_DECREF must already have been called on it. */ static void -_PyTrash_thread_deposit_object(PyObject *op) +_PyTrash_thread_deposit_object(struct _py_trashcan *trash, PyObject *op) { - PyThreadState *tstate = _PyThreadState_GET(); _PyObject_ASSERT(op, _PyObject_IS_GC(op)); _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op)); _PyObject_ASSERT(op, Py_REFCNT(op) == 0); - _PyGCHead_SET_PREV(_Py_AS_GC(op), tstate->trash_delete_later); - tstate->trash_delete_later = op; + _PyGCHead_SET_PREV(_Py_AS_GC(op), (PyGC_Head*)trash->delete_later); + trash->delete_later = op; } /* Deallocate all the objects in the gcstate->trash_delete_later list. * Called when the call-stack unwinds again. */ static void -_PyTrash_thread_destroy_chain(void) +_PyTrash_thread_destroy_chain(struct _py_trashcan *trash) { - PyThreadState *tstate = _PyThreadState_GET(); /* We need to increase trash_delete_nesting here, otherwise, _PyTrash_thread_destroy_chain will be called recursively and then possibly crash. An example that may crash without @@ -2199,13 +2250,13 @@ _PyTrash_thread_destroy_chain(void) tups = [(tup,) for tup in tups] del tups */ - assert(tstate->trash_delete_nesting == 0); - ++tstate->trash_delete_nesting; - while (tstate->trash_delete_later) { - PyObject *op = tstate->trash_delete_later; + assert(trash->delete_nesting == 0); + ++trash->delete_nesting; + while (trash->delete_later) { + PyObject *op = trash->delete_later; destructor dealloc = Py_TYPE(op)->tp_dealloc; - tstate->trash_delete_later = + trash->delete_later = (PyObject*) _PyGCHead_PREV(_Py_AS_GC(op)); /* Call the deallocator directly. This used to try to @@ -2216,22 +2267,64 @@ _PyTrash_thread_destroy_chain(void) */ _PyObject_ASSERT(op, Py_REFCNT(op) == 0); (*dealloc)(op); - assert(tstate->trash_delete_nesting == 1); + assert(trash->delete_nesting == 1); + } + --trash->delete_nesting; +} + + +static struct _py_trashcan * +_PyTrash_get_state(PyThreadState *tstate) +{ + if (tstate != NULL) { + return &tstate->trash; + } + // The current thread must be finalizing. + // Fall back to using thread-local state. + // XXX Use thread-local variable syntax? + assert(PyThread_tss_is_created(&_PyRuntime.trashTSSkey)); + struct _py_trashcan *trash = + (struct _py_trashcan *)PyThread_tss_get(&_PyRuntime.trashTSSkey); + if (trash == NULL) { + trash = PyMem_RawMalloc(sizeof(struct _py_trashcan)); + if (trash == NULL) { + Py_FatalError("Out of memory"); + } + PyThread_tss_set(&_PyRuntime.trashTSSkey, (void *)trash); + } + return trash; +} + +static void +_PyTrash_clear_state(PyThreadState *tstate) +{ + if (tstate != NULL) { + assert(tstate->trash.delete_later == NULL); + return; + } + if (PyThread_tss_is_created(&_PyRuntime.trashTSSkey)) { + struct _py_trashcan *trash = + (struct _py_trashcan *)PyThread_tss_get(&_PyRuntime.trashTSSkey); + if (trash != NULL) { + PyThread_tss_set(&_PyRuntime.trashTSSkey, (void *)NULL); + PyMem_RawFree(trash); + } } - --tstate->trash_delete_nesting; } int _PyTrash_begin(PyThreadState *tstate, PyObject *op) { - if (tstate->trash_delete_nesting >= _PyTrash_UNWIND_LEVEL) { + // XXX Make sure the GIL is held. + struct _py_trashcan *trash = _PyTrash_get_state(tstate); + if (trash->delete_nesting >= _PyTrash_UNWIND_LEVEL) { /* Store the object (to be deallocated later) and jump past * Py_TRASHCAN_END, skipping the body of the deallocator */ - _PyTrash_thread_deposit_object(op); + _PyTrash_thread_deposit_object(trash, op); return 1; } - ++tstate->trash_delete_nesting; + ++trash->delete_nesting; return 0; } @@ -2239,9 +2332,14 @@ _PyTrash_begin(PyThreadState *tstate, PyObject *op) void _PyTrash_end(PyThreadState *tstate) { - --tstate->trash_delete_nesting; - if (tstate->trash_delete_later && tstate->trash_delete_nesting <= 0) { - _PyTrash_thread_destroy_chain(); + // XXX Make sure the GIL is held. + struct _py_trashcan *trash = _PyTrash_get_state(tstate); + --trash->delete_nesting; + if (trash->delete_nesting <= 0) { + if (trash->delete_later != NULL) { + _PyTrash_thread_destroy_chain(trash); + } + _PyTrash_clear_state(tstate); } } @@ -2314,11 +2412,45 @@ _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg, void _Py_Dealloc(PyObject *op) { - destructor dealloc = Py_TYPE(op)->tp_dealloc; + PyTypeObject *type = Py_TYPE(op); + destructor dealloc = type->tp_dealloc; +#ifdef Py_DEBUG + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *old_exc_type = tstate != NULL ? tstate->curexc_type : NULL; + // Keep the old exception type alive to prevent undefined behavior + // on (tstate->curexc_type != old_exc_type) below + Py_XINCREF(old_exc_type); + // Make sure that type->tp_name remains valid + Py_INCREF(type); +#endif + #ifdef Py_TRACE_REFS _Py_ForgetReference(op); #endif (*dealloc)(op); + +#ifdef Py_DEBUG + // gh-89373: The tp_dealloc function must leave the current exception + // unchanged. + if (tstate != NULL && tstate->curexc_type != old_exc_type) { + const char *err; + if (old_exc_type == NULL) { + err = "Deallocator of type '%s' raised an exception"; + } + else if (tstate->curexc_type == NULL) { + err = "Deallocator of type '%s' cleared the current exception"; + } + else { + // It can happen if dealloc() normalized the current exception. + // A deallocator function must not change the current exception, + // not even normalize it. + err = "Deallocator of type '%s' overrode the current exception"; + } + _Py_FatalErrorFormat(__func__, err, type->tp_name); + } + Py_XDECREF(old_exc_type); + Py_DECREF(type); +#endif } diff --git a/Objects/object_layout.md b/Objects/object_layout.md new file mode 100644 index 00000000000..9380b57938c --- /dev/null +++ b/Objects/object_layout.md @@ -0,0 +1,82 @@ +# Object layout + +## Common header + +Each Python object starts with two fields: + +* ob_refcnt +* ob_type + +which the form the header common to all Python objects, for all versions, +and hold the reference count and class of the object, respectively. + +## Pre-header + +Since the introduction of the cycle GC, there has also been a pre-header. +Before 3.11, this pre-header was two words in size. +It should be considered opaque to all code except the cycle GC. + +## 3.11 pre-header + +In 3.11 the pre-header was extended to include pointers to the VM managed ``__dict__``. +The reason for moving the ``__dict__`` to the pre-header is that it allows +faster access, as it is at a fixed offset, and it also allows object's +dictionaries to be lazily created when the ``__dict__`` attribute is +specifically asked for. + +In the 3.11 the non-GC part of the pre-header consists of two pointers: + +* dict +* values + +The values pointer refers to the ``PyDictValues`` array which holds the +values of the objects's attributes. +Should the dictionary be needed, then ``values`` is set to ``NULL`` +and the ``dict`` field points to the dictionary. + +## 3.12 pre-header + +In 3.12 the the pointer to the list of weak references is added to the +pre-header. In order to make space for it, the ``dict`` and ``values`` +pointers are combined into a single tagged pointer: + +* weakreflist +* dict_or_values + +If the object has no physical dictionary, then the ``dict_or_values`` +has its low bit set to one, and points to the values array. +If the object has a physical dictioanry, then the ``dict_or_values`` +has its low bit set to zero, and points to the dictionary. + +The untagged form is chosen for the dictionary pointer, rather than +the values pointer, to enable the (legacy) C-API function +`_PyObject_GetDictPtr(PyObject *obj)` to work. + + +## Layout of a "normal" Python object in 3.12: + +* weakreflist +* dict_or_values +* GC 1 +* GC 2 +* ob_refcnt +* ob_type + +For a "normal" Python object, that is one that doesn't inherit from a builtin +class or have slots, the header and pre-header form the entire object. + +![Layout of "normal" object in 3.12](./object_layout_312.png) + +There are several advantages to this layout: + +* It allows lazy `__dict__`s, as described above. +* The regular layout allows us to create tailored traversal and deallocation + functions based on layout, rather than inheritance. +* Multiple inheritance works properly, + as the weakrefs and dict are always at the same offset. + +The full layout object, with an opaque part defined by a C extension, +and `__slots__` looks like this: + +![Layout of "full" object in 3.12](./object_layout_full_312.png) + diff --git a/Objects/object_layout_312.gv b/Objects/object_layout_312.gv new file mode 100644 index 00000000000..c0068d78568 --- /dev/null +++ b/Objects/object_layout_312.gv @@ -0,0 +1,50 @@ +digraph ideal { + + rankdir = "LR" + + + object [ + shape = none + label = < + + + + + + + +
    object
    weakrefs
    dict or values
    GC info 0
    GC info 1
    refcount
    __class__
    > + ] + + values [ + shape = none + label = < + + + + +
    values
    values[0]
    values[1]
    ...
    > + + ] + + class [ + shape = none + label = < + + + + + +
    class
    ...
    dict_offset
    ...
    cached_keys
    > + ] + + keys [label = "dictionary keys"; fillcolor="lightgreen"; style="filled"] + NULL [ label = " NULL"; shape="plain"] + object:w -> NULL + object:h -> class:head + object:dv -> values:0 + class:k -> keys + + oop [ label = "pointer"; shape="plain"] + oop -> object:r +} diff --git a/Objects/object_layout_312.png b/Objects/object_layout_312.png new file mode 100644 index 00000000000..396dab183b3 Binary files /dev/null and b/Objects/object_layout_312.png differ diff --git a/Objects/object_layout_full_312.gv b/Objects/object_layout_full_312.gv new file mode 100644 index 00000000000..522fa32b066 --- /dev/null +++ b/Objects/object_layout_full_312.gv @@ -0,0 +1,25 @@ +digraph ideal { + + rankdir = "LR" + + + object [ + shape = none + label = < + + + + + + + + + + + +
    object
    weakrefs
    dict or values
    GC info 0
    GC info 1
    refcount
    __class__
    opaque (extension) data
    ...
    __slot__ 0
    ...
    > + ] + + oop [ label = "pointer"; shape="plain"] + oop -> object:r +} diff --git a/Objects/object_layout_full_312.png b/Objects/object_layout_full_312.png new file mode 100644 index 00000000000..4f46ca86091 Binary files /dev/null and b/Objects/object_layout_full_312.png differ diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index 4e17bf44b4e..276c5a276c0 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -1,8 +1,16 @@ #include "Python.h" -#include "pycore_pymem.h" // _PyTraceMalloc_Config +#include "pycore_code.h" // stats +#include "pycore_pystate.h" // _PyInterpreterState_GET + +#include "pycore_obmalloc.h" +#include "pycore_pymem.h" -#include #include // malloc() +#include + + +#undef uint +#define uint pymem_uint /* Defined in tracemalloc.c */ @@ -11,25 +19,154 @@ extern void _PyMem_DumpTraceback(int fd, const void *ptr); /* Python's malloc wrappers (see pymem.h) */ -#undef uint -#define uint unsigned int /* assuming >= 16 bits */ - -/* Forward declaration */ -static void* _PyMem_DebugRawMalloc(void *ctx, size_t size); -static void* _PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize); -static void* _PyMem_DebugRawRealloc(void *ctx, void *ptr, size_t size); -static void _PyMem_DebugRawFree(void *ctx, void *ptr); - -static void* _PyMem_DebugMalloc(void *ctx, size_t size); -static void* _PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize); -static void* _PyMem_DebugRealloc(void *ctx, void *ptr, size_t size); -static void _PyMem_DebugFree(void *ctx, void *p); - static void _PyObject_DebugDumpAddress(const void *p); static void _PyMem_DebugCheckAddress(const char *func, char api_id, const void *p); static void _PyMem_SetupDebugHooksDomain(PyMemAllocatorDomain domain); + +/***************************************/ +/* low-level allocator implementations */ +/***************************************/ + +/* the default raw allocator (wraps malloc) */ + +void * +_PyMem_RawMalloc(void *Py_UNUSED(ctx), size_t size) +{ + /* PyMem_RawMalloc(0) means malloc(1). Some systems would return NULL + for malloc(0), which would be treated as an error. Some platforms would + return a pointer with no memory behind it, which would break pymalloc. + To solve these problems, allocate an extra byte. */ + if (size == 0) + size = 1; + return malloc(size); +} + +void * +_PyMem_RawCalloc(void *Py_UNUSED(ctx), size_t nelem, size_t elsize) +{ + /* PyMem_RawCalloc(0, 0) means calloc(1, 1). Some systems would return NULL + for calloc(0, 0), which would be treated as an error. Some platforms + would return a pointer with no memory behind it, which would break + pymalloc. To solve these problems, allocate an extra byte. */ + if (nelem == 0 || elsize == 0) { + nelem = 1; + elsize = 1; + } + return calloc(nelem, elsize); +} + +void * +_PyMem_RawRealloc(void *Py_UNUSED(ctx), void *ptr, size_t size) +{ + if (size == 0) + size = 1; + return realloc(ptr, size); +} + +void +_PyMem_RawFree(void *Py_UNUSED(ctx), void *ptr) +{ + free(ptr); +} + +#define MALLOC_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree} +#define PYRAW_ALLOC MALLOC_ALLOC + +/* the default object allocator */ + +// The actual implementation is further down. + +#ifdef WITH_PYMALLOC +void* _PyObject_Malloc(void *ctx, size_t size); +void* _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize); +void _PyObject_Free(void *ctx, void *p); +void* _PyObject_Realloc(void *ctx, void *ptr, size_t size); +# define PYMALLOC_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free} +# define PYOBJ_ALLOC PYMALLOC_ALLOC +#else +# define PYOBJ_ALLOC MALLOC_ALLOC +#endif // WITH_PYMALLOC + +#define PYMEM_ALLOC PYOBJ_ALLOC + +/* the default debug allocators */ + +// The actual implementation is further down. + +void* _PyMem_DebugRawMalloc(void *ctx, size_t size); +void* _PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize); +void* _PyMem_DebugRawRealloc(void *ctx, void *ptr, size_t size); +void _PyMem_DebugRawFree(void *ctx, void *ptr); + +void* _PyMem_DebugMalloc(void *ctx, size_t size); +void* _PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize); +void* _PyMem_DebugRealloc(void *ctx, void *ptr, size_t size); +void _PyMem_DebugFree(void *ctx, void *p); + +#define PYDBGRAW_ALLOC \ + {&_PyRuntime.allocators.debug.raw, _PyMem_DebugRawMalloc, _PyMem_DebugRawCalloc, _PyMem_DebugRawRealloc, _PyMem_DebugRawFree} +#define PYDBGMEM_ALLOC \ + {&_PyRuntime.allocators.debug.mem, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} +#define PYDBGOBJ_ALLOC \ + {&_PyRuntime.allocators.debug.obj, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} + +/* the low-level virtual memory allocator */ + +#ifdef WITH_PYMALLOC +# ifdef MS_WINDOWS +# include +# elif defined(HAVE_MMAP) +# include +# ifdef MAP_ANONYMOUS +# define ARENAS_USE_MMAP +# endif +# endif +#endif + +void * +_PyMem_ArenaAlloc(void *Py_UNUSED(ctx), size_t size) +{ +#ifdef MS_WINDOWS + return VirtualAlloc(NULL, size, + MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); +#elif defined(ARENAS_USE_MMAP) + void *ptr; + ptr = mmap(NULL, size, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if (ptr == MAP_FAILED) + return NULL; + assert(ptr != NULL); + return ptr; +#else + return malloc(size); +#endif +} + +void +_PyMem_ArenaFree(void *Py_UNUSED(ctx), void *ptr, +#if defined(ARENAS_USE_MMAP) + size_t size +#else + size_t Py_UNUSED(size) +#endif +) +{ +#ifdef MS_WINDOWS + VirtualFree(ptr, 0, MEM_RELEASE); +#elif defined(ARENAS_USE_MMAP) + munmap(ptr, size); +#else + free(ptr); +#endif +} + +/*******************************************/ +/* end low-level allocator implementations */ +/*******************************************/ + + #if defined(__has_feature) /* Clang */ # if __has_feature(address_sanitizer) /* is ASAN enabled? */ # define _Py_NO_SANITIZE_ADDRESS \ @@ -63,163 +200,12 @@ static void _PyMem_SetupDebugHooksDomain(PyMemAllocatorDomain domain); # define _Py_NO_SANITIZE_MEMORY #endif -#ifdef WITH_PYMALLOC -#ifdef MS_WINDOWS -# include -#elif defined(HAVE_MMAP) -# include -# ifdef MAP_ANONYMOUS -# define ARENAS_USE_MMAP -# endif -#endif - -/* Forward declaration */ -static void* _PyObject_Malloc(void *ctx, size_t size); -static void* _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize); -static void _PyObject_Free(void *ctx, void *p); -static void* _PyObject_Realloc(void *ctx, void *ptr, size_t size); -#endif - - -/* bpo-35053: Declare tracemalloc configuration here rather than - Modules/_tracemalloc.c because _tracemalloc can be compiled as dynamic - library, whereas _Py_NewReference() requires it. */ -struct _PyTraceMalloc_Config _Py_tracemalloc_config = _PyTraceMalloc_Config_INIT; - - -static void * -_PyMem_RawMalloc(void *ctx, size_t size) -{ - /* PyMem_RawMalloc(0) means malloc(1). Some systems would return NULL - for malloc(0), which would be treated as an error. Some platforms would - return a pointer with no memory behind it, which would break pymalloc. - To solve these problems, allocate an extra byte. */ - if (size == 0) - size = 1; - return malloc(size); -} - -static void * -_PyMem_RawCalloc(void *ctx, size_t nelem, size_t elsize) -{ - /* PyMem_RawCalloc(0, 0) means calloc(1, 1). Some systems would return NULL - for calloc(0, 0), which would be treated as an error. Some platforms - would return a pointer with no memory behind it, which would break - pymalloc. To solve these problems, allocate an extra byte. */ - if (nelem == 0 || elsize == 0) { - nelem = 1; - elsize = 1; - } - return calloc(nelem, elsize); -} - -static void * -_PyMem_RawRealloc(void *ctx, void *ptr, size_t size) -{ - if (size == 0) - size = 1; - return realloc(ptr, size); -} - -static void -_PyMem_RawFree(void *ctx, void *ptr) -{ - free(ptr); -} - - -#ifdef MS_WINDOWS -static void * -_PyObject_ArenaVirtualAlloc(void *ctx, size_t size) -{ - return VirtualAlloc(NULL, size, - MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); -} - -static void -_PyObject_ArenaVirtualFree(void *ctx, void *ptr, size_t size) -{ - VirtualFree(ptr, 0, MEM_RELEASE); -} - -#elif defined(ARENAS_USE_MMAP) -static void * -_PyObject_ArenaMmap(void *ctx, size_t size) -{ - void *ptr; - ptr = mmap(NULL, size, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); - if (ptr == MAP_FAILED) - return NULL; - assert(ptr != NULL); - return ptr; -} - -static void -_PyObject_ArenaMunmap(void *ctx, void *ptr, size_t size) -{ - munmap(ptr, size); -} - -#else -static void * -_PyObject_ArenaMalloc(void *ctx, size_t size) -{ - return malloc(size); -} - -static void -_PyObject_ArenaFree(void *ctx, void *ptr, size_t size) -{ - free(ptr); -} -#endif - -#define MALLOC_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree} -#ifdef WITH_PYMALLOC -# define PYMALLOC_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free} -#endif - -#define PYRAW_ALLOC MALLOC_ALLOC -#ifdef WITH_PYMALLOC -# define PYOBJ_ALLOC PYMALLOC_ALLOC -#else -# define PYOBJ_ALLOC MALLOC_ALLOC -#endif -#define PYMEM_ALLOC PYOBJ_ALLOC - -typedef struct { - /* We tag each block with an API ID in order to tag API violations */ - char api_id; - PyMemAllocatorEx alloc; -} debug_alloc_api_t; -static struct { - debug_alloc_api_t raw; - debug_alloc_api_t mem; - debug_alloc_api_t obj; -} _PyMem_Debug = { - {'r', PYRAW_ALLOC}, - {'m', PYMEM_ALLOC}, - {'o', PYOBJ_ALLOC} - }; - -#define PYDBGRAW_ALLOC \ - {&_PyMem_Debug.raw, _PyMem_DebugRawMalloc, _PyMem_DebugRawCalloc, _PyMem_DebugRawRealloc, _PyMem_DebugRawFree} -#define PYDBGMEM_ALLOC \ - {&_PyMem_Debug.mem, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} -#define PYDBGOBJ_ALLOC \ - {&_PyMem_Debug.obj, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} - -#ifdef Py_DEBUG -static PyMemAllocatorEx _PyMem_Raw = PYDBGRAW_ALLOC; -static PyMemAllocatorEx _PyMem = PYDBGMEM_ALLOC; -static PyMemAllocatorEx _PyObject = PYDBGOBJ_ALLOC; -#else -static PyMemAllocatorEx _PyMem_Raw = PYRAW_ALLOC; -static PyMemAllocatorEx _PyMem = PYMEM_ALLOC; -static PyMemAllocatorEx _PyObject = PYOBJ_ALLOC; -#endif +#define _PyMem_Raw (_PyRuntime.allocators.standard.raw) +#define _PyMem (_PyRuntime.allocators.standard.mem) +#define _PyObject (_PyRuntime.allocators.standard.obj) +#define _PyMem_Debug (_PyRuntime.allocators.debug) +#define _PyObject_Arena (_PyRuntime.allocators.obj_arena) static int @@ -422,26 +408,6 @@ _PyMem_GetCurrentAllocatorName(void) } -#undef MALLOC_ALLOC -#undef PYMALLOC_ALLOC -#undef PYRAW_ALLOC -#undef PYMEM_ALLOC -#undef PYOBJ_ALLOC -#undef PYDBGRAW_ALLOC -#undef PYDBGMEM_ALLOC -#undef PYDBGOBJ_ALLOC - - -static PyObjectArenaAllocator _PyObject_Arena = {NULL, -#ifdef MS_WINDOWS - _PyObject_ArenaVirtualAlloc, _PyObject_ArenaVirtualFree -#elif defined(ARENAS_USE_MMAP) - _PyObject_ArenaMmap, _PyObject_ArenaMunmap -#else - _PyObject_ArenaMalloc, _PyObject_ArenaFree -#endif - }; - #ifdef WITH_PYMALLOC static int _PyMem_DebugEnabled(void) @@ -615,6 +581,10 @@ PyMem_Malloc(size_t size) /* see PyMem_RawMalloc() */ if (size > (size_t)PY_SSIZE_T_MAX) return NULL; + OBJECT_STAT_INC_COND(allocations512, size < 512); + OBJECT_STAT_INC_COND(allocations4k, size >= 512 && size < 4094); + OBJECT_STAT_INC_COND(allocations_big, size >= 4094); + OBJECT_STAT_INC(allocations); return _PyMem.malloc(_PyMem.ctx, size); } @@ -624,6 +594,10 @@ PyMem_Calloc(size_t nelem, size_t elsize) /* see PyMem_RawMalloc() */ if (elsize != 0 && nelem > (size_t)PY_SSIZE_T_MAX / elsize) return NULL; + OBJECT_STAT_INC_COND(allocations512, elsize < 512); + OBJECT_STAT_INC_COND(allocations4k, elsize >= 512 && elsize < 4094); + OBJECT_STAT_INC_COND(allocations_big, elsize >= 4094); + OBJECT_STAT_INC(allocations); return _PyMem.calloc(_PyMem.ctx, nelem, elsize); } @@ -639,6 +613,7 @@ PyMem_Realloc(void *ptr, size_t new_size) void PyMem_Free(void *ptr) { + OBJECT_STAT_INC(frees); _PyMem.free(_PyMem.ctx, ptr); } @@ -695,6 +670,10 @@ PyObject_Malloc(size_t size) /* see PyMem_RawMalloc() */ if (size > (size_t)PY_SSIZE_T_MAX) return NULL; + OBJECT_STAT_INC_COND(allocations512, size < 512); + OBJECT_STAT_INC_COND(allocations4k, size >= 512 && size < 4094); + OBJECT_STAT_INC_COND(allocations_big, size >= 4094); + OBJECT_STAT_INC(allocations); return _PyObject.malloc(_PyObject.ctx, size); } @@ -704,6 +683,10 @@ PyObject_Calloc(size_t nelem, size_t elsize) /* see PyMem_RawMalloc() */ if (elsize != 0 && nelem > (size_t)PY_SSIZE_T_MAX / elsize) return NULL; + OBJECT_STAT_INC_COND(allocations512, elsize < 512); + OBJECT_STAT_INC_COND(allocations4k, elsize >= 512 && elsize < 4094); + OBJECT_STAT_INC_COND(allocations_big, elsize >= 4094); + OBJECT_STAT_INC(allocations); return _PyObject.calloc(_PyObject.ctx, nelem, elsize); } @@ -719,6 +702,7 @@ PyObject_Realloc(void *ptr, size_t new_size) void PyObject_Free(void *ptr) { + OBJECT_STAT_INC(frees); _PyObject.free(_PyObject.ctx, ptr); } @@ -743,517 +727,15 @@ static int running_on_valgrind = -1; #endif -/* An object allocator for Python. - - Here is an introduction to the layers of the Python memory architecture, - showing where the object allocator is actually used (layer +2), It is - called for every object allocation and deallocation (PyObject_New/Del), - unless the object-specific allocators implement a proprietary allocation - scheme (ex.: ints use a simple free list). This is also the place where - the cyclic garbage collector operates selectively on container objects. - - - Object-specific allocators - _____ ______ ______ ________ - [ int ] [ dict ] [ list ] ... [ string ] Python core | -+3 | <----- Object-specific memory -----> | <-- Non-object memory --> | - _______________________________ | | - [ Python's object allocator ] | | -+2 | ####### Object memory ####### | <------ Internal buffers ------> | - ______________________________________________________________ | - [ Python's raw memory allocator (PyMem_ API) ] | -+1 | <----- Python memory (under PyMem manager's control) ------> | | - __________________________________________________________________ - [ Underlying general-purpose allocator (ex: C library malloc) ] - 0 | <------ Virtual memory allocated for the python process -------> | - - ========================================================================= - _______________________________________________________________________ - [ OS-specific Virtual Memory Manager (VMM) ] --1 | <--- Kernel dynamic storage allocation & management (page-based) ---> | - __________________________________ __________________________________ - [ ] [ ] --2 | <-- Physical memory: ROM/RAM --> | | <-- Secondary storage (swap) --> | - -*/ -/*==========================================================================*/ - -/* A fast, special-purpose memory allocator for small blocks, to be used - on top of a general-purpose malloc -- heavily based on previous art. */ - -/* Vladimir Marangozov -- August 2000 */ - -/* - * "Memory management is where the rubber meets the road -- if we do the wrong - * thing at any level, the results will not be good. And if we don't make the - * levels work well together, we are in serious trouble." (1) - * - * (1) Paul R. Wilson, Mark S. Johnstone, Michael Neely, and David Boles, - * "Dynamic Storage Allocation: A Survey and Critical Review", - * in Proc. 1995 Int'l. Workshop on Memory Management, September 1995. - */ - -/* #undef WITH_MEMORY_LIMITS */ /* disable mem limit checks */ - -/*==========================================================================*/ - -/* - * Allocation strategy abstract: - * - * For small requests, the allocator sub-allocates blocks of memory. - * Requests greater than SMALL_REQUEST_THRESHOLD bytes are routed to the - * system's allocator. - * - * Small requests are grouped in size classes spaced 8 bytes apart, due - * to the required valid alignment of the returned address. Requests of - * a particular size are serviced from memory pools of 4K (one VMM page). - * Pools are fragmented on demand and contain free lists of blocks of one - * particular size class. In other words, there is a fixed-size allocator - * for each size class. Free pools are shared by the different allocators - * thus minimizing the space reserved for a particular size class. - * - * This allocation strategy is a variant of what is known as "simple - * segregated storage based on array of free lists". The main drawback of - * simple segregated storage is that we might end up with lot of reserved - * memory for the different free lists, which degenerate in time. To avoid - * this, we partition each free list in pools and we share dynamically the - * reserved space between all free lists. This technique is quite efficient - * for memory intensive programs which allocate mainly small-sized blocks. - * - * For small requests we have the following table: - * - * Request in bytes Size of allocated block Size class idx - * ---------------------------------------------------------------- - * 1-8 8 0 - * 9-16 16 1 - * 17-24 24 2 - * 25-32 32 3 - * 33-40 40 4 - * 41-48 48 5 - * 49-56 56 6 - * 57-64 64 7 - * 65-72 72 8 - * ... ... ... - * 497-504 504 62 - * 505-512 512 63 - * - * 0, SMALL_REQUEST_THRESHOLD + 1 and up: routed to the underlying - * allocator. - */ - -/*==========================================================================*/ - -/* - * -- Main tunable settings section -- - */ - -/* - * Alignment of addresses returned to the user. 8-bytes alignment works - * on most current architectures (with 32-bit or 64-bit address buses). - * The alignment value is also used for grouping small requests in size - * classes spaced ALIGNMENT bytes apart. - * - * You shouldn't change this unless you know what you are doing. - */ - -#if SIZEOF_VOID_P > 4 -#define ALIGNMENT 16 /* must be 2^N */ -#define ALIGNMENT_SHIFT 4 -#else -#define ALIGNMENT 8 /* must be 2^N */ -#define ALIGNMENT_SHIFT 3 -#endif - -/* Return the number of bytes in size class I, as a uint. */ -#define INDEX2SIZE(I) (((uint)(I) + 1) << ALIGNMENT_SHIFT) - -/* - * Max size threshold below which malloc requests are considered to be - * small enough in order to use preallocated memory pools. You can tune - * this value according to your application behaviour and memory needs. - * - * Note: a size threshold of 512 guarantees that newly created dictionaries - * will be allocated from preallocated memory pools on 64-bit. - * - * The following invariants must hold: - * 1) ALIGNMENT <= SMALL_REQUEST_THRESHOLD <= 512 - * 2) SMALL_REQUEST_THRESHOLD is evenly divisible by ALIGNMENT - * - * Although not required, for better performance and space efficiency, - * it is recommended that SMALL_REQUEST_THRESHOLD is set to a power of 2. - */ -#define SMALL_REQUEST_THRESHOLD 512 -#define NB_SMALL_SIZE_CLASSES (SMALL_REQUEST_THRESHOLD / ALIGNMENT) - -/* - * The system's VMM page size can be obtained on most unices with a - * getpagesize() call or deduced from various header files. To make - * things simpler, we assume that it is 4K, which is OK for most systems. - * It is probably better if this is the native page size, but it doesn't - * have to be. In theory, if SYSTEM_PAGE_SIZE is larger than the native page - * size, then `POOL_ADDR(p)->arenaindex' could rarely cause a segmentation - * violation fault. 4K is apparently OK for all the platforms that python - * currently targets. - */ -#define SYSTEM_PAGE_SIZE (4 * 1024) -#define SYSTEM_PAGE_SIZE_MASK (SYSTEM_PAGE_SIZE - 1) - -/* - * Maximum amount of memory managed by the allocator for small requests. - */ -#ifdef WITH_MEMORY_LIMITS -#ifndef SMALL_MEMORY_LIMIT -#define SMALL_MEMORY_LIMIT (64 * 1024 * 1024) /* 64 MB -- more? */ -#endif -#endif - -#if !defined(WITH_PYMALLOC_RADIX_TREE) -/* Use radix-tree to track arena memory regions, for address_in_range(). - * Enable by default since it allows larger pool sizes. Can be disabled - * using -DWITH_PYMALLOC_RADIX_TREE=0 */ -#define WITH_PYMALLOC_RADIX_TREE 1 -#endif - -#if SIZEOF_VOID_P > 4 -/* on 64-bit platforms use larger pools and arenas if we can */ -#define USE_LARGE_ARENAS -#if WITH_PYMALLOC_RADIX_TREE -/* large pools only supported if radix-tree is enabled */ -#define USE_LARGE_POOLS -#endif -#endif - -/* - * The allocator sub-allocates blocks of memory (called arenas) aligned - * on a page boundary. This is a reserved virtual address space for the - * current process (obtained through a malloc()/mmap() call). In no way this - * means that the memory arenas will be used entirely. A malloc() is - * usually an address range reservation for bytes, unless all pages within - * this space are referenced subsequently. So malloc'ing big blocks and not - * using them does not mean "wasting memory". It's an addressable range - * wastage... - * - * Arenas are allocated with mmap() on systems supporting anonymous memory - * mappings to reduce heap fragmentation. - */ -#ifdef USE_LARGE_ARENAS -#define ARENA_BITS 20 /* 1 MiB */ -#else -#define ARENA_BITS 18 /* 256 KiB */ -#endif -#define ARENA_SIZE (1 << ARENA_BITS) -#define ARENA_SIZE_MASK (ARENA_SIZE - 1) - -#ifdef WITH_MEMORY_LIMITS -#define MAX_ARENAS (SMALL_MEMORY_LIMIT / ARENA_SIZE) -#endif - -/* - * Size of the pools used for small blocks. Must be a power of 2. - */ -#ifdef USE_LARGE_POOLS -#define POOL_BITS 14 /* 16 KiB */ -#else -#define POOL_BITS 12 /* 4 KiB */ -#endif -#define POOL_SIZE (1 << POOL_BITS) -#define POOL_SIZE_MASK (POOL_SIZE - 1) - -#if !WITH_PYMALLOC_RADIX_TREE -#if POOL_SIZE != SYSTEM_PAGE_SIZE -# error "pool size must be equal to system page size" -#endif -#endif - -#define MAX_POOLS_IN_ARENA (ARENA_SIZE / POOL_SIZE) -#if MAX_POOLS_IN_ARENA * POOL_SIZE != ARENA_SIZE -# error "arena size not an exact multiple of pool size" -#endif - -/* - * -- End of tunable settings section -- - */ - -/*==========================================================================*/ - -/* When you say memory, my mind reasons in terms of (pointers to) blocks */ -typedef uint8_t block; - -/* Pool for small blocks. */ -struct pool_header { - union { block *_padding; - uint count; } ref; /* number of allocated blocks */ - block *freeblock; /* pool's free list head */ - struct pool_header *nextpool; /* next pool of this size class */ - struct pool_header *prevpool; /* previous pool "" */ - uint arenaindex; /* index into arenas of base adr */ - uint szidx; /* block size class index */ - uint nextoffset; /* bytes to virgin block */ - uint maxnextoffset; /* largest valid nextoffset */ -}; - -typedef struct pool_header *poolp; - -/* Record keeping for arenas. */ -struct arena_object { - /* The address of the arena, as returned by malloc. Note that 0 - * will never be returned by a successful malloc, and is used - * here to mark an arena_object that doesn't correspond to an - * allocated arena. - */ - uintptr_t address; - - /* Pool-aligned pointer to the next pool to be carved off. */ - block* pool_address; - - /* The number of available pools in the arena: free pools + never- - * allocated pools. - */ - uint nfreepools; - - /* The total number of pools in the arena, whether or not available. */ - uint ntotalpools; - - /* Singly-linked list of available pools. */ - struct pool_header* freepools; - - /* Whenever this arena_object is not associated with an allocated - * arena, the nextarena member is used to link all unassociated - * arena_objects in the singly-linked `unused_arena_objects` list. - * The prevarena member is unused in this case. - * - * When this arena_object is associated with an allocated arena - * with at least one available pool, both members are used in the - * doubly-linked `usable_arenas` list, which is maintained in - * increasing order of `nfreepools` values. - * - * Else this arena_object is associated with an allocated arena - * all of whose pools are in use. `nextarena` and `prevarena` - * are both meaningless in this case. - */ - struct arena_object* nextarena; - struct arena_object* prevarena; -}; - -#define POOL_OVERHEAD _Py_SIZE_ROUND_UP(sizeof(struct pool_header), ALIGNMENT) - -#define DUMMY_SIZE_IDX 0xffff /* size class of newly cached pools */ - -/* Round pointer P down to the closest pool-aligned address <= P, as a poolp */ -#define POOL_ADDR(P) ((poolp)_Py_ALIGN_DOWN((P), POOL_SIZE)) - -/* Return total number of blocks in pool of size index I, as a uint. */ -#define NUMBLOCKS(I) ((uint)(POOL_SIZE - POOL_OVERHEAD) / INDEX2SIZE(I)) - -/*==========================================================================*/ - -/* - * Pool table -- headed, circular, doubly-linked lists of partially used pools. - -This is involved. For an index i, usedpools[i+i] is the header for a list of -all partially used pools holding small blocks with "size class idx" i. So -usedpools[0] corresponds to blocks of size 8, usedpools[2] to blocks of size -16, and so on: index 2*i <-> blocks of size (i+1)<freeblock points to -the start of a singly-linked list of free blocks within the pool. When a -block is freed, it's inserted at the front of its pool's freeblock list. Note -that the available blocks in a pool are *not* linked all together when a pool -is initialized. Instead only "the first two" (lowest addresses) blocks are -set up, returning the first such block, and setting pool->freeblock to a -one-block list holding the second such block. This is consistent with that -pymalloc strives at all levels (arena, pool, and block) never to touch a piece -of memory until it's actually needed. - -So long as a pool is in the used state, we're certain there *is* a block -available for allocating, and pool->freeblock is not NULL. If pool->freeblock -points to the end of the free list before we've carved the entire pool into -blocks, that means we simply haven't yet gotten to one of the higher-address -blocks. The offset from the pool_header to the start of "the next" virgin -block is stored in the pool_header nextoffset member, and the largest value -of nextoffset that makes sense is stored in the maxnextoffset member when a -pool is initialized. All the blocks in a pool have been passed out at least -once when and only when nextoffset > maxnextoffset. - - -Major obscurity: While the usedpools vector is declared to have poolp -entries, it doesn't really. It really contains two pointers per (conceptual) -poolp entry, the nextpool and prevpool members of a pool_header. The -excruciating initialization code below fools C so that - - usedpool[i+i] - -"acts like" a genuine poolp, but only so long as you only reference its -nextpool and prevpool members. The "- 2*sizeof(block *)" gibberish is -compensating for that a pool_header's nextpool and prevpool members -immediately follow a pool_header's first two members: - - union { block *_padding; - uint count; } ref; - block *freeblock; - -each of which consume sizeof(block *) bytes. So what usedpools[i+i] really -contains is a fudged-up pointer p such that *if* C believes it's a poolp -pointer, then p->nextpool and p->prevpool are both p (meaning that the headed -circular list is empty). - -It's unclear why the usedpools setup is so convoluted. It could be to -minimize the amount of cache required to hold this heavily-referenced table -(which only *needs* the two interpool pointer members of a pool_header). OTOH, -referencing code has to remember to "double the index" and doing so isn't -free, usedpools[0] isn't a strictly legal pointer, and we're crucially relying -on that C doesn't insert any padding anywhere in a pool_header at or before -the prevpool member. -**************************************************************************** */ - -#define PTA(x) ((poolp )((uint8_t *)&(usedpools[2*(x)]) - 2*sizeof(block *))) -#define PT(x) PTA(x), PTA(x) - -static poolp usedpools[2 * ((NB_SMALL_SIZE_CLASSES + 7) / 8) * 8] = { - PT(0), PT(1), PT(2), PT(3), PT(4), PT(5), PT(6), PT(7) -#if NB_SMALL_SIZE_CLASSES > 8 - , PT(8), PT(9), PT(10), PT(11), PT(12), PT(13), PT(14), PT(15) -#if NB_SMALL_SIZE_CLASSES > 16 - , PT(16), PT(17), PT(18), PT(19), PT(20), PT(21), PT(22), PT(23) -#if NB_SMALL_SIZE_CLASSES > 24 - , PT(24), PT(25), PT(26), PT(27), PT(28), PT(29), PT(30), PT(31) -#if NB_SMALL_SIZE_CLASSES > 32 - , PT(32), PT(33), PT(34), PT(35), PT(36), PT(37), PT(38), PT(39) -#if NB_SMALL_SIZE_CLASSES > 40 - , PT(40), PT(41), PT(42), PT(43), PT(44), PT(45), PT(46), PT(47) -#if NB_SMALL_SIZE_CLASSES > 48 - , PT(48), PT(49), PT(50), PT(51), PT(52), PT(53), PT(54), PT(55) -#if NB_SMALL_SIZE_CLASSES > 56 - , PT(56), PT(57), PT(58), PT(59), PT(60), PT(61), PT(62), PT(63) -#if NB_SMALL_SIZE_CLASSES > 64 -#error "NB_SMALL_SIZE_CLASSES should be less than 64" -#endif /* NB_SMALL_SIZE_CLASSES > 64 */ -#endif /* NB_SMALL_SIZE_CLASSES > 56 */ -#endif /* NB_SMALL_SIZE_CLASSES > 48 */ -#endif /* NB_SMALL_SIZE_CLASSES > 40 */ -#endif /* NB_SMALL_SIZE_CLASSES > 32 */ -#endif /* NB_SMALL_SIZE_CLASSES > 24 */ -#endif /* NB_SMALL_SIZE_CLASSES > 16 */ -#endif /* NB_SMALL_SIZE_CLASSES > 8 */ -}; - -/*========================================================================== -Arena management. - -`arenas` is a vector of arena_objects. It contains maxarenas entries, some of -which may not be currently used (== they're arena_objects that aren't -currently associated with an allocated arena). Note that arenas proper are -separately malloc'ed. - -Prior to Python 2.5, arenas were never free()'ed. Starting with Python 2.5, -we do try to free() arenas, and use some mild heuristic strategies to increase -the likelihood that arenas eventually can be freed. - -unused_arena_objects - - This is a singly-linked list of the arena_objects that are currently not - being used (no arena is associated with them). Objects are taken off the - head of the list in new_arena(), and are pushed on the head of the list in - PyObject_Free() when the arena is empty. Key invariant: an arena_object - is on this list if and only if its .address member is 0. - -usable_arenas - - This is a doubly-linked list of the arena_objects associated with arenas - that have pools available. These pools are either waiting to be reused, - or have not been used before. The list is sorted to have the most- - allocated arenas first (ascending order based on the nfreepools member). - This means that the next allocation will come from a heavily used arena, - which gives the nearly empty arenas a chance to be returned to the system. - In my unscientific tests this dramatically improved the number of arenas - that could be freed. - -Note that an arena_object associated with an arena all of whose pools are -currently in use isn't on either list. - -Changed in Python 3.8: keeping usable_arenas sorted by number of free pools -used to be done by one-at-a-time linear search when an arena's number of -free pools changed. That could, overall, consume time quadratic in the -number of arenas. That didn't really matter when there were only a few -hundred arenas (typical!), but could be a timing disaster when there were -hundreds of thousands. See bpo-37029. - -Now we have a vector of "search fingers" to eliminate the need to search: -nfp2lasta[nfp] returns the last ("rightmost") arena in usable_arenas -with nfp free pools. This is NULL if and only if there is no arena with -nfp free pools in usable_arenas. -*/ - -/* Array of objects used to track chunks of memory (arenas). */ -static struct arena_object* arenas = NULL; -/* Number of slots currently allocated in the `arenas` vector. */ -static uint maxarenas = 0; - -/* The head of the singly-linked, NULL-terminated list of available - * arena_objects. - */ -static struct arena_object* unused_arena_objects = NULL; - -/* The head of the doubly-linked, NULL-terminated at each end, list of - * arena_objects associated with arenas that have pools available. - */ -static struct arena_object* usable_arenas = NULL; - -/* nfp2lasta[nfp] is the last arena in usable_arenas with nfp free pools */ -static struct arena_object* nfp2lasta[MAX_POOLS_IN_ARENA + 1] = { NULL }; - -/* How many arena_objects do we initially allocate? - * 16 = can allocate 16 arenas = 16 * ARENA_SIZE = 4MB before growing the - * `arenas` vector. - */ -#define INITIAL_ARENA_OBJECTS 16 - -/* Number of arenas allocated that haven't been free()'d. */ -static size_t narenas_currently_allocated = 0; - -/* Total number of times malloc() called to allocate an arena. */ -static size_t ntimes_arena_allocated = 0; -/* High water mark (max value ever seen) for narenas_currently_allocated. */ -static size_t narenas_highwater = 0; - -static Py_ssize_t raw_allocated_blocks; +#define allarenas (_PyRuntime.obmalloc.mgmt.arenas) +#define maxarenas (_PyRuntime.obmalloc.mgmt.maxarenas) +#define unused_arena_objects (_PyRuntime.obmalloc.mgmt.unused_arena_objects) +#define usable_arenas (_PyRuntime.obmalloc.mgmt.usable_arenas) +#define nfp2lasta (_PyRuntime.obmalloc.mgmt.nfp2lasta) +#define narenas_currently_allocated (_PyRuntime.obmalloc.mgmt.narenas_currently_allocated) +#define ntimes_arena_allocated (_PyRuntime.obmalloc.mgmt.ntimes_arena_allocated) +#define narenas_highwater (_PyRuntime.obmalloc.mgmt.narenas_highwater) +#define raw_allocated_blocks (_PyRuntime.obmalloc.mgmt.raw_allocated_blocks) Py_ssize_t _Py_GetAllocatedBlocks(void) @@ -1262,15 +744,15 @@ _Py_GetAllocatedBlocks(void) /* add up allocated blocks for used pools */ for (uint i = 0; i < maxarenas; ++i) { /* Skip arenas which are not allocated. */ - if (arenas[i].address == 0) { + if (allarenas[i].address == 0) { continue; } - uintptr_t base = (uintptr_t)_Py_ALIGN_UP(arenas[i].address, POOL_SIZE); + uintptr_t base = (uintptr_t)_Py_ALIGN_UP(allarenas[i].address, POOL_SIZE); /* visit every pool in the arena */ - assert(base <= (uintptr_t) arenas[i].pool_address); - for (; base < (uintptr_t) arenas[i].pool_address; base += POOL_SIZE) { + assert(base <= (uintptr_t) allarenas[i].pool_address); + for (; base < (uintptr_t) allarenas[i].pool_address; base += POOL_SIZE) { poolp p = (poolp)base; n += p->ref.count; } @@ -1280,155 +762,18 @@ _Py_GetAllocatedBlocks(void) #if WITH_PYMALLOC_RADIX_TREE /*==========================================================================*/ -/* radix tree for tracking arena usage. If enabled, used to implement - address_in_range(). - - memory address bit allocation for keys - - 64-bit pointers, IGNORE_BITS=0 and 2^20 arena size: - 15 -> MAP_TOP_BITS - 15 -> MAP_MID_BITS - 14 -> MAP_BOT_BITS - 20 -> ideal aligned arena - ---- - 64 - - 64-bit pointers, IGNORE_BITS=16, and 2^20 arena size: - 16 -> IGNORE_BITS - 10 -> MAP_TOP_BITS - 10 -> MAP_MID_BITS - 8 -> MAP_BOT_BITS - 20 -> ideal aligned arena - ---- - 64 - - 32-bit pointers and 2^18 arena size: - 14 -> MAP_BOT_BITS - 18 -> ideal aligned arena - ---- - 32 - -*/ - -#if SIZEOF_VOID_P == 8 - -/* number of bits in a pointer */ -#define POINTER_BITS 64 - -/* High bits of memory addresses that will be ignored when indexing into the - * radix tree. Setting this to zero is the safe default. For most 64-bit - * machines, setting this to 16 would be safe. The kernel would not give - * user-space virtual memory addresses that have significant information in - * those high bits. The main advantage to setting IGNORE_BITS > 0 is that less - * virtual memory will be used for the top and middle radix tree arrays. Those - * arrays are allocated in the BSS segment and so will typically consume real - * memory only if actually accessed. - */ -#define IGNORE_BITS 0 - -/* use the top and mid layers of the radix tree */ -#define USE_INTERIOR_NODES - -#elif SIZEOF_VOID_P == 4 - -#define POINTER_BITS 32 -#define IGNORE_BITS 0 - -#else - - /* Currently this code works for 64-bit or 32-bit pointers only. */ -#error "obmalloc radix tree requires 64-bit or 32-bit pointers." - -#endif /* SIZEOF_VOID_P */ - -/* arena_coverage_t members require this to be true */ -#if ARENA_BITS >= 32 -# error "arena size must be < 2^32" -#endif - -/* the lower bits of the address that are not ignored */ -#define ADDRESS_BITS (POINTER_BITS - IGNORE_BITS) +/* radix tree for tracking arena usage. */ +#define arena_map_root (_PyRuntime.obmalloc.usage.arena_map_root) #ifdef USE_INTERIOR_NODES -/* number of bits used for MAP_TOP and MAP_MID nodes */ -#define INTERIOR_BITS ((ADDRESS_BITS - ARENA_BITS + 2) / 3) -#else -#define INTERIOR_BITS 0 -#endif - -#define MAP_TOP_BITS INTERIOR_BITS -#define MAP_TOP_LENGTH (1 << MAP_TOP_BITS) -#define MAP_TOP_MASK (MAP_TOP_LENGTH - 1) - -#define MAP_MID_BITS INTERIOR_BITS -#define MAP_MID_LENGTH (1 << MAP_MID_BITS) -#define MAP_MID_MASK (MAP_MID_LENGTH - 1) - -#define MAP_BOT_BITS (ADDRESS_BITS - ARENA_BITS - 2*INTERIOR_BITS) -#define MAP_BOT_LENGTH (1 << MAP_BOT_BITS) -#define MAP_BOT_MASK (MAP_BOT_LENGTH - 1) - -#define MAP_BOT_SHIFT ARENA_BITS -#define MAP_MID_SHIFT (MAP_BOT_BITS + MAP_BOT_SHIFT) -#define MAP_TOP_SHIFT (MAP_MID_BITS + MAP_MID_SHIFT) - -#define AS_UINT(p) ((uintptr_t)(p)) -#define MAP_BOT_INDEX(p) ((AS_UINT(p) >> MAP_BOT_SHIFT) & MAP_BOT_MASK) -#define MAP_MID_INDEX(p) ((AS_UINT(p) >> MAP_MID_SHIFT) & MAP_MID_MASK) -#define MAP_TOP_INDEX(p) ((AS_UINT(p) >> MAP_TOP_SHIFT) & MAP_TOP_MASK) - -#if IGNORE_BITS > 0 -/* Return the ignored part of the pointer address. Those bits should be same - * for all valid pointers if IGNORE_BITS is set correctly. - */ -#define HIGH_BITS(p) (AS_UINT(p) >> ADDRESS_BITS) -#else -#define HIGH_BITS(p) 0 -#endif - - -/* This is the leaf of the radix tree. See arena_map_mark_used() for the - * meaning of these members. */ -typedef struct { - int32_t tail_hi; - int32_t tail_lo; -} arena_coverage_t; - -typedef struct arena_map_bot { - /* The members tail_hi and tail_lo are accessed together. So, it - * better to have them as an array of structs, rather than two - * arrays. - */ - arena_coverage_t arenas[MAP_BOT_LENGTH]; -} arena_map_bot_t; - -#ifdef USE_INTERIOR_NODES -typedef struct arena_map_mid { - struct arena_map_bot *ptrs[MAP_MID_LENGTH]; -} arena_map_mid_t; - -typedef struct arena_map_top { - struct arena_map_mid *ptrs[MAP_TOP_LENGTH]; -} arena_map_top_t; -#endif - -/* The root of radix tree. Note that by initializing like this, the memory - * should be in the BSS. The OS will only memory map pages as the MAP_MID - * nodes get used (OS pages are demand loaded as needed). - */ -#ifdef USE_INTERIOR_NODES -static arena_map_top_t arena_map_root; -/* accounting for number of used interior nodes */ -static int arena_map_mid_count; -static int arena_map_bot_count; -#else -static arena_map_bot_t arena_map_root; +#define arena_map_mid_count (_PyRuntime.obmalloc.usage.arena_map_mid_count) +#define arena_map_bot_count (_PyRuntime.obmalloc.usage.arena_map_bot_count) #endif /* Return a pointer to a bottom tree node, return NULL if it doesn't exist or * it cannot be created */ -static arena_map_bot_t * -arena_map_get(block *p, int create) +static Py_ALWAYS_INLINE arena_map_bot_t * +arena_map_get(pymem_block *p, int create) { #ifdef USE_INTERIOR_NODES /* sanity check that IGNORE_BITS is correct */ @@ -1493,12 +838,12 @@ arena_map_mark_used(uintptr_t arena_base, int is_used) { /* sanity check that IGNORE_BITS is correct */ assert(HIGH_BITS(arena_base) == HIGH_BITS(&arena_map_root)); - arena_map_bot_t *n_hi = arena_map_get((block *)arena_base, is_used); + arena_map_bot_t *n_hi = arena_map_get((pymem_block *)arena_base, is_used); if (n_hi == NULL) { assert(is_used); /* otherwise node should already exist */ return 0; /* failed to allocate space for node */ } - int i3 = MAP_BOT_INDEX((block *)arena_base); + int i3 = MAP_BOT_INDEX((pymem_block *)arena_base); int32_t tail = (int32_t)(arena_base & ARENA_SIZE_MASK); if (tail == 0) { /* is ideal arena address */ @@ -1518,7 +863,7 @@ arena_map_mark_used(uintptr_t arena_base, int is_used) * must overflow to 0. However, that would mean arena_base was * "ideal" and we should not be in this case. */ assert(arena_base < arena_base_next); - arena_map_bot_t *n_lo = arena_map_get((block *)arena_base_next, is_used); + arena_map_bot_t *n_lo = arena_map_get((pymem_block *)arena_base_next, is_used); if (n_lo == NULL) { assert(is_used); /* otherwise should already exist */ n_hi->arenas[i3].tail_hi = 0; @@ -1533,7 +878,7 @@ arena_map_mark_used(uintptr_t arena_base, int is_used) /* Return true if 'p' is a pointer inside an obmalloc arena. * _PyObject_Free() calls this so it needs to be very fast. */ static int -arena_map_is_used(block *p) +arena_map_is_used(pymem_block *p) { arena_map_bot_t *n = arena_map_get(p, 0); if (n == NULL) { @@ -1563,14 +908,16 @@ new_arena(void) struct arena_object* arenaobj; uint excess; /* number of bytes above pool alignment */ void *address; - static int debug_stats = -1; + int debug_stats = _PyRuntime.obmalloc.dump_debug_stats; if (debug_stats == -1) { const char *opt = Py_GETENV("PYTHONMALLOCSTATS"); debug_stats = (opt != NULL && *opt != '\0'); + _PyRuntime.obmalloc.dump_debug_stats = debug_stats; } - if (debug_stats) + if (debug_stats) { _PyObject_DebugMallocStats(stderr); + } if (unused_arena_objects == NULL) { uint i; @@ -1584,14 +931,14 @@ new_arena(void) if (numarenas <= maxarenas) return NULL; /* overflow */ #if SIZEOF_SIZE_T <= SIZEOF_INT - if (numarenas > SIZE_MAX / sizeof(*arenas)) + if (numarenas > SIZE_MAX / sizeof(*allarenas)) return NULL; /* overflow */ #endif - nbytes = numarenas * sizeof(*arenas); - arenaobj = (struct arena_object *)PyMem_RawRealloc(arenas, nbytes); + nbytes = numarenas * sizeof(*allarenas); + arenaobj = (struct arena_object *)PyMem_RawRealloc(allarenas, nbytes); if (arenaobj == NULL) return NULL; - arenas = arenaobj; + allarenas = arenaobj; /* We might need to fix pointers that were copied. However, * new_arena only gets called when all the pages in the @@ -1604,13 +951,13 @@ new_arena(void) /* Put the new arenas on the unused_arena_objects list. */ for (i = maxarenas; i < numarenas; ++i) { - arenas[i].address = 0; /* mark as unassociated */ - arenas[i].nextarena = i < numarenas - 1 ? - &arenas[i+1] : NULL; + allarenas[i].address = 0; /* mark as unassociated */ + allarenas[i].nextarena = i < numarenas - 1 ? + &allarenas[i+1] : NULL; } /* Update globals. */ - unused_arena_objects = &arenas[maxarenas]; + unused_arena_objects = &allarenas[maxarenas]; maxarenas = numarenas; } @@ -1646,7 +993,7 @@ new_arena(void) arenaobj->freepools = NULL; /* pool_address <- first pool-aligned address in the arena nfreepools <- number of whole pools that fit after alignment */ - arenaobj->pool_address = (block*)arenaobj->address; + arenaobj->pool_address = (pymem_block*)arenaobj->address; arenaobj->nfreepools = MAX_POOLS_IN_ARENA; excess = (uint)(arenaobj->address & POOL_SIZE_MASK); if (excess != 0) { @@ -1665,7 +1012,7 @@ new_arena(void) pymalloc. When the radix tree is used, 'poolp' is unused. */ static bool -address_in_range(void *p, poolp pool) +address_in_range(void *p, poolp Py_UNUSED(pool)) { return arena_map_is_used(p); } @@ -1757,14 +1104,16 @@ address_in_range(void *p, poolp pool) // only once. uint arenaindex = *((volatile uint *)&pool->arenaindex); return arenaindex < maxarenas && - (uintptr_t)p - arenas[arenaindex].address < ARENA_SIZE && - arenas[arenaindex].address != 0; + (uintptr_t)p - allarenas[arenaindex].address < ARENA_SIZE && + allarenas[arenaindex].address != 0; } #endif /* !WITH_PYMALLOC_RADIX_TREE */ /*==========================================================================*/ +#define usedpools (_PyRuntime.obmalloc.pools.used) + // Called when freelist is exhausted. Extend the freelist if there is // space for a block. Otherwise, remove this pool from usedpools. static void @@ -1772,9 +1121,9 @@ pymalloc_pool_extend(poolp pool, uint size) { if (UNLIKELY(pool->nextoffset <= pool->maxnextoffset)) { /* There is room for another block. */ - pool->freeblock = (block*)pool + pool->nextoffset; + pool->freeblock = (pymem_block*)pool + pool->nextoffset; pool->nextoffset += INDEX2SIZE(size); - *(block **)(pool->freeblock) = NULL; + *(pymem_block **)(pool->freeblock) = NULL; return; } @@ -1854,7 +1203,7 @@ allocate_from_new_pool(uint size) */ assert(usable_arenas->freepools != NULL || usable_arenas->pool_address <= - (block*)usable_arenas->address + + (pymem_block*)usable_arenas->address + ARENA_SIZE - POOL_SIZE); } } @@ -1863,10 +1212,10 @@ allocate_from_new_pool(uint size) assert(usable_arenas->nfreepools > 0); assert(usable_arenas->freepools == NULL); pool = (poolp)usable_arenas->pool_address; - assert((block*)pool <= (block*)usable_arenas->address + + assert((pymem_block*)pool <= (pymem_block*)usable_arenas->address + ARENA_SIZE - POOL_SIZE); - pool->arenaindex = (uint)(usable_arenas - arenas); - assert(&arenas[pool->arenaindex] == usable_arenas); + pool->arenaindex = (uint)(usable_arenas - allarenas); + assert(&allarenas[pool->arenaindex] == usable_arenas); pool->szidx = DUMMY_SIZE_IDX; usable_arenas->pool_address += POOL_SIZE; --usable_arenas->nfreepools; @@ -1885,7 +1234,7 @@ allocate_from_new_pool(uint size) } /* Frontlink to used pools. */ - block *bp; + pymem_block *bp; poolp next = usedpools[size + size]; /* == prev */ pool->nextpool = next; pool->prevpool = next; @@ -1899,7 +1248,7 @@ allocate_from_new_pool(uint size) */ bp = pool->freeblock; assert(bp != NULL); - pool->freeblock = *(block **)bp; + pool->freeblock = *(pymem_block **)bp; return bp; } /* @@ -1909,11 +1258,11 @@ allocate_from_new_pool(uint size) */ pool->szidx = size; size = INDEX2SIZE(size); - bp = (block *)pool + POOL_OVERHEAD; + bp = (pymem_block *)pool + POOL_OVERHEAD; pool->nextoffset = POOL_OVERHEAD + (size << 1); pool->maxnextoffset = POOL_SIZE - size; pool->freeblock = bp + size; - *(block **)(pool->freeblock) = NULL; + *(pymem_block **)(pool->freeblock) = NULL; return bp; } @@ -1926,7 +1275,7 @@ allocate_from_new_pool(uint size) or when the max memory limit has been reached. */ static inline void* -pymalloc_alloc(void *ctx, size_t nbytes) +pymalloc_alloc(void *Py_UNUSED(ctx), size_t nbytes) { #ifdef WITH_VALGRIND if (UNLIKELY(running_on_valgrind == -1)) { @@ -1946,7 +1295,7 @@ pymalloc_alloc(void *ctx, size_t nbytes) uint size = (uint)(nbytes - 1) >> ALIGNMENT_SHIFT; poolp pool = usedpools[size + size]; - block *bp; + pymem_block *bp; if (LIKELY(pool != pool->nextpool)) { /* @@ -1957,7 +1306,7 @@ pymalloc_alloc(void *ctx, size_t nbytes) bp = pool->freeblock; assert(bp != NULL); - if (UNLIKELY((pool->freeblock = *(block **)bp) == NULL)) { + if (UNLIKELY((pool->freeblock = *(pymem_block **)bp) == NULL)) { // Reached the end of the free list, try to extend it. pymalloc_pool_extend(pool, size); } @@ -1973,7 +1322,7 @@ pymalloc_alloc(void *ctx, size_t nbytes) } -static void * +void * _PyObject_Malloc(void *ctx, size_t nbytes) { void* ptr = pymalloc_alloc(ctx, nbytes); @@ -1989,7 +1338,7 @@ _PyObject_Malloc(void *ctx, size_t nbytes) } -static void * +void * _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize) { assert(elsize == 0 || nelem <= (size_t)PY_SSIZE_T_MAX / elsize); @@ -2036,7 +1385,7 @@ insert_to_freepool(poolp pool) /* Link the pool to freepools. This is a singly-linked * list, and pool->prevpool isn't used there. */ - struct arena_object *ao = &arenas[pool->arenaindex]; + struct arena_object *ao = &allarenas[pool->arenaindex]; pool->nextpool = ao->freepools; ao->freepools = pool; uint nf = ao->nfreepools; @@ -2196,7 +1545,7 @@ insert_to_freepool(poolp pool) Return 1 if it was freed. Return 0 if the block was not allocated by pymalloc_alloc(). */ static inline int -pymalloc_free(void *ctx, void *p) +pymalloc_free(void *Py_UNUSED(ctx), void *p) { assert(p != NULL); @@ -2219,9 +1568,9 @@ pymalloc_free(void *ctx, void *p) * list in any case). */ assert(pool->ref.count > 0); /* else it was empty */ - block *lastfree = pool->freeblock; - *(block **)p = lastfree; - pool->freeblock = (block *)p; + pymem_block *lastfree = pool->freeblock; + *(pymem_block **)p = lastfree; + pool->freeblock = (pymem_block *)p; pool->ref.count--; if (UNLIKELY(lastfree == NULL)) { @@ -2253,7 +1602,7 @@ pymalloc_free(void *ctx, void *p) } -static void +void _PyObject_Free(void *ctx, void *p) { /* PyObject_Free(NULL) has no effect */ @@ -2339,7 +1688,7 @@ pymalloc_realloc(void *ctx, void **newptr_p, void *p, size_t nbytes) } -static void * +void * _PyObject_Realloc(void *ctx, void *ptr, size_t nbytes) { void *ptr2; @@ -2516,13 +1865,13 @@ _PyMem_DebugRawAlloc(int use_calloc, void *ctx, size_t nbytes) return data; } -static void * +void * _PyMem_DebugRawMalloc(void *ctx, size_t nbytes) { return _PyMem_DebugRawAlloc(0, ctx, nbytes); } -static void * +void * _PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize) { size_t nbytes; @@ -2537,7 +1886,7 @@ _PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize) Then fills the original bytes with PYMEM_DEADBYTE. Then calls the underlying free. */ -static void +void _PyMem_DebugRawFree(void *ctx, void *p) { /* PyMem_Free(NULL) has no effect */ @@ -2557,7 +1906,7 @@ _PyMem_DebugRawFree(void *ctx, void *p) } -static void * +void * _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes) { if (p == NULL) { @@ -2667,14 +2016,14 @@ _PyMem_DebugCheckGIL(const char *func) } } -static void * +void * _PyMem_DebugMalloc(void *ctx, size_t nbytes) { _PyMem_DebugCheckGIL(__func__); return _PyMem_DebugRawMalloc(ctx, nbytes); } -static void * +void * _PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize) { _PyMem_DebugCheckGIL(__func__); @@ -2682,7 +2031,7 @@ _PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize) } -static void +void _PyMem_DebugFree(void *ctx, void *ptr) { _PyMem_DebugCheckGIL(__func__); @@ -2690,7 +2039,7 @@ _PyMem_DebugFree(void *ctx, void *ptr) } -static void * +void * _PyMem_DebugRealloc(void *ctx, void *ptr, size_t nbytes) { _PyMem_DebugCheckGIL(__func__); @@ -2980,15 +2329,14 @@ _PyObject_DebugMallocStats(FILE *out) * will be living in full pools -- would be a shame to miss them. */ for (i = 0; i < maxarenas; ++i) { - uint j; - uintptr_t base = arenas[i].address; + uintptr_t base = allarenas[i].address; /* Skip arenas which are not allocated. */ - if (arenas[i].address == (uintptr_t)NULL) + if (allarenas[i].address == (uintptr_t)NULL) continue; narenas += 1; - numfreepools += arenas[i].nfreepools; + numfreepools += allarenas[i].nfreepools; /* round up to pool alignment */ if (base & (uintptr_t)POOL_SIZE_MASK) { @@ -2998,9 +2346,8 @@ _PyObject_DebugMallocStats(FILE *out) } /* visit every pool in the arena */ - assert(base <= (uintptr_t) arenas[i].pool_address); - for (j = 0; base < (uintptr_t) arenas[i].pool_address; - ++j, base += POOL_SIZE) { + assert(base <= (uintptr_t) allarenas[i].pool_address); + for (; base < (uintptr_t) allarenas[i].pool_address; base += POOL_SIZE) { poolp p = (poolp)base; const uint sz = p->szidx; uint freeblocks; @@ -3008,7 +2355,7 @@ _PyObject_DebugMallocStats(FILE *out) if (p->ref.count == 0) { /* currently unused */ #ifdef Py_DEBUG - assert(pool_is_in_list(p, arenas[i].freepools)); + assert(pool_is_in_list(p, allarenas[i].freepools)); #endif continue; } diff --git a/Objects/odictobject.c b/Objects/odictobject.c index 9af45c685ab..4976b70b5df 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -525,8 +525,6 @@ struct _odictnode { #define _odict_FOREACH(od, node) \ for (node = _odict_FIRST(od); node != NULL; node = _odictnode_NEXT(node)) -_Py_IDENTIFIER(items); - /* Return the index into the hash table, regardless of a valid node. */ static Py_ssize_t _odict_get_index_raw(PyODictObject *od, PyObject *key, Py_hash_t hash) @@ -891,8 +889,7 @@ odict_inplace_or(PyObject *self, PyObject *other) if (mutablemapping_update_arg(self, other) < 0) { return NULL; } - Py_INCREF(self); - return self; + return Py_NewRef(self); } /* tp_as_number */ @@ -949,31 +946,20 @@ PyDoc_STRVAR(odict_reduce__doc__, "Return state information for pickling"); static PyObject * odict_reduce(register PyODictObject *od, PyObject *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(__dict__); - PyObject *dict = NULL, *result = NULL; + PyObject *state, *result = NULL; PyObject *items_iter, *items, *args = NULL; /* capture any instance state */ - dict = _PyObject_GetAttrId((PyObject *)od, &PyId___dict__); - if (dict == NULL) + state = _PyObject_GetState((PyObject *)od); + if (state == NULL) goto Done; - else { - /* od.__dict__ isn't necessarily a dict... */ - Py_ssize_t dict_len = PyObject_Length(dict); - if (dict_len == -1) - goto Done; - if (!dict_len) { - /* nothing to pickle in od.__dict__ */ - Py_CLEAR(dict); - } - } /* build the result */ args = PyTuple_New(0); if (args == NULL) goto Done; - items = _PyObject_CallMethodIdNoArgs((PyObject *)od, &PyId_items); + items = PyObject_CallMethodNoArgs((PyObject *)od, &_Py_ID(items)); if (items == NULL) goto Done; @@ -982,11 +968,11 @@ odict_reduce(register PyODictObject *od, PyObject *Py_UNUSED(ignored)) if (items_iter == NULL) goto Done; - result = PyTuple_Pack(5, Py_TYPE(od), args, dict ? dict : Py_None, Py_None, items_iter); + result = PyTuple_Pack(5, Py_TYPE(od), args, state, Py_None, items_iter); Py_DECREF(items_iter); Done: - Py_XDECREF(dict); + Py_XDECREF(state); Py_XDECREF(args); return result; @@ -1020,8 +1006,7 @@ OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key, return NULL; assert(_odict_find_node(self, key) == NULL); if (PyODict_SetItem((PyObject *)self, key, default_value) >= 0) { - result = default_value; - Py_INCREF(result); + result = Py_NewRef(default_value); } } else { @@ -1037,8 +1022,7 @@ OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key, result = PyObject_GetItem((PyObject *)self, key); } else if (PyObject_SetItem((PyObject *)self, key, default_value) >= 0) { - result = default_value; - Py_INCREF(result); + result = Py_NewRef(default_value); } } @@ -1068,8 +1052,7 @@ _odict_popkey_hash(PyObject *od, PyObject *key, PyObject *failobj, else if (value == NULL && !PyErr_Occurred()) { /* Apply the fallback value, if necessary. */ if (failobj) { - value = failobj; - Py_INCREF(failobj); + value = Py_NewRef(failobj); } else { PyErr_SetObject(PyExc_KeyError, key); @@ -1131,8 +1114,7 @@ OrderedDict_popitem_impl(PyODictObject *self, int last) } node = last ? _odict_LAST(self) : _odict_FIRST(self); - key = _odictnode_KEY(node); - Py_INCREF(key); + key = Py_NewRef(_odictnode_KEY(node)); value = _odict_popkey_hash((PyObject *)self, key, NULL, _odictnode_HASH(node)); if (value == NULL) return NULL; @@ -1249,6 +1231,7 @@ PyDoc_STRVAR(odict_reversed__doc__, "od.__reversed__() <==> reversed(od)"); #define _odict_ITER_REVERSED 1 #define _odict_ITER_KEYS 2 #define _odict_ITER_VALUES 4 +#define _odict_ITER_ITEMS (_odict_ITER_KEYS|_odict_ITER_VALUES) /* forward */ static PyObject * odictiter_new(PyODictObject *, int); @@ -1329,7 +1312,7 @@ static PyMethodDef odict_methods[] = { odict_values__doc__}, {"items", odictitems_new, METH_NOARGS, odict_items__doc__}, - {"update", (PyCFunction)(void(*)(void))odict_update, METH_VARARGS | METH_KEYWORDS, + {"update", _PyCFunction_CAST(odict_update), METH_VARARGS | METH_KEYWORDS, odict_update__doc__}, {"clear", (PyCFunction)odict_clear, METH_NOARGS, odict_clear__doc__}, @@ -1430,8 +1413,8 @@ odict_repr(PyODictObject *self) } } else { - PyObject *items = _PyObject_CallMethodIdNoArgs((PyObject *)self, - &PyId_items); + PyObject *items = PyObject_CallMethodNoArgs( + (PyObject *)self, &_Py_ID(items)); if (items == NULL) goto Done; pieces = PySequence_List(items); @@ -1509,8 +1492,7 @@ odict_richcompare(PyObject *v, PyObject *w, int op) return NULL; res = (eq == (op == Py_EQ)) ? Py_True : Py_False; - Py_INCREF(res); - return res; + return Py_NewRef(res); } else { Py_RETURN_NOTIMPLEMENTED; } @@ -1666,7 +1648,7 @@ odictiter_dealloc(odictiterobject *di) _PyObject_GC_UNTRACK(di); Py_XDECREF(di->di_odict); Py_XDECREF(di->di_current); - if (di->kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)) { + if ((di->kind & _odict_ITER_ITEMS) == _odict_ITER_ITEMS) { Py_DECREF(di->di_result); } PyObject_GC_Del(di); @@ -1726,8 +1708,7 @@ odictiter_nextkey(odictiterobject *di) di->di_current = NULL; } else { - di->di_current = _odictnode_KEY(node); - Py_INCREF(di->di_current); + di->di_current = Py_NewRef(_odictnode_KEY(node)); } return key; @@ -1807,7 +1788,6 @@ PyDoc_STRVAR(reduce_doc, "Return state information for pickling"); static PyObject * odictiter_reduce(odictiterobject *di, PyObject *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(iter); /* copy the iterator state */ odictiterobject tmp = *di; Py_XINCREF(tmp.di_odict); @@ -1820,7 +1800,7 @@ odictiter_reduce(odictiterobject *di, PyObject *Py_UNUSED(ignored)) if (list == NULL) { return NULL; } - return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list); + return Py_BuildValue("N(N)", _PyEval_GetBuiltin(&_Py_ID(iter)), list); } static PyMethodDef odictiter_methods[] = { @@ -1872,24 +1852,23 @@ odictiter_new(PyODictObject *od, int kind) if (di == NULL) return NULL; - if (kind & (_odict_ITER_KEYS | _odict_ITER_VALUES)){ + if ((kind & _odict_ITER_ITEMS) == _odict_ITER_ITEMS) { di->di_result = PyTuple_Pack(2, Py_None, Py_None); if (di->di_result == NULL) { Py_DECREF(di); return NULL; } } - else + else { di->di_result = NULL; + } di->kind = kind; node = reversed ? _odict_LAST(od) : _odict_FIRST(od); - di->di_current = node ? _odictnode_KEY(node) : NULL; - Py_XINCREF(di->di_current); + di->di_current = node ? Py_NewRef(_odictnode_KEY(node)) : NULL; di->di_size = PyODict_SIZE(od); di->di_state = od->od_state; - di->di_odict = od; - Py_INCREF(od); + di->di_odict = (PyODictObject*)Py_NewRef(od); _PyObject_GC_TRACK(di); return (PyObject *)di; @@ -2215,9 +2194,8 @@ mutablemapping_update_arg(PyObject *self, PyObject *arg) Py_DECREF(items); return res; } - _Py_IDENTIFIER(keys); PyObject *func; - if (_PyObject_LookupAttrId(arg, &PyId_keys, &func) < 0) { + if (_PyObject_LookupAttr(arg, &_Py_ID(keys), &func) < 0) { return -1; } if (func != NULL) { @@ -2249,7 +2227,7 @@ mutablemapping_update_arg(PyObject *self, PyObject *arg) } return 0; } - if (_PyObject_LookupAttrId(arg, &PyId_items, &func) < 0) { + if (_PyObject_LookupAttr(arg, &_Py_ID(items), &func) < 0) { return -1; } if (func != NULL) { diff --git a/Objects/picklebufobject.c b/Objects/picklebufobject.c index a135e5575e2..aaa852cfbb0 100644 --- a/Objects/picklebufobject.c +++ b/Objects/picklebufobject.c @@ -206,7 +206,7 @@ static PyMethodDef picklebuf_methods[] = { PyTypeObject PyPickleBuffer_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "pickle.PickleBuffer", - .tp_doc = "Wrapper for potentially out-of-band buffers", + .tp_doc = PyDoc_STR("Wrapper for potentially out-of-band buffers"), .tp_basicsize = sizeof(PyPickleBufferObject), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_new = picklebuf_new, diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index a848d67a651..b4d0bbf32c8 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -2,6 +2,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_range.h" #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "structmember.h" // PyMemberDef @@ -21,8 +22,6 @@ typedef struct { PyObject *length; } rangeobject; -_Py_IDENTIFIER(iter); - /* Helper function for validating step. Always returns a new reference or NULL on error. */ @@ -106,10 +105,8 @@ range_from_array(PyTypeObject *type, PyObject *const *args, Py_ssize_t num_args) if (!stop) { return NULL; } - start = _PyLong_GetZero(); - Py_INCREF(start); - step = _PyLong_GetOne(); - Py_INCREF(step); + start = Py_NewRef(_PyLong_GetZero()); + step = Py_NewRef(_PyLong_GetOne()); break; case 0: PyErr_SetString(PyExc_TypeError, @@ -174,6 +171,49 @@ range_dealloc(rangeobject *r) PyObject_Free(r); } +static unsigned long +get_len_of_range(long lo, long hi, long step); + +/* Return the length as a long, -2 for an overflow and -1 for any other type of error + * + * In case of an overflow no error is set + */ +static long compute_range_length_long(PyObject *start, + PyObject *stop, PyObject *step) { + int overflow = 0; + + long long_start = PyLong_AsLongAndOverflow(start, &overflow); + if (overflow) { + return -2; + } + if (long_start == -1 && PyErr_Occurred()) { + return -1; + } + long long_stop = PyLong_AsLongAndOverflow(stop, &overflow); + if (overflow) { + return -2; + } + if (long_stop == -1 && PyErr_Occurred()) { + return -1; + } + long long_step = PyLong_AsLongAndOverflow(step, &overflow); + if (overflow) { + return -2; + } + if (long_step == -1 && PyErr_Occurred()) { + return -1; + } + + unsigned long ulen = get_len_of_range(long_start, long_stop, long_step); + if (ulen > (unsigned long)LONG_MAX) { + /* length too large for a long */ + return -2; + } + else { + return (long)ulen; + } +} + /* Return number of items in range (lo, hi, step) as a PyLong object, * when arguments are PyLong objects. Arguments MUST return 1 with * PyLong_Check(). Return NULL when there is an error. @@ -194,6 +234,21 @@ compute_range_length(PyObject *start, PyObject *stop, PyObject *step) PyObject *zero = _PyLong_GetZero(); // borrowed reference PyObject *one = _PyLong_GetOne(); // borrowed reference + assert(PyLong_Check(start)); + assert(PyLong_Check(stop)); + assert(PyLong_Check(step)); + + /* fast path when all arguments fit into a long integer */ + long len = compute_range_length_long(start, stop, step); + if (len >= 0) { + return PyLong_FromLong(len); + } + else if (len == -1) { + /* unexpected error from compute_range_length_long, we propagate to the caller */ + return NULL; + } + assert(len == -2); + cmp_result = PyObject_RichCompareBool(step, zero, Py_GT); if (cmp_result == -1) return NULL; @@ -217,8 +272,7 @@ compute_range_length(PyObject *start, PyObject *stop, PyObject *step) if (cmp_result < 0) return NULL; result = zero; - Py_INCREF(result); - return result; + return Py_NewRef(result); } if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL) @@ -298,8 +352,7 @@ compute_range_item(rangeobject *r, PyObject *arg) return NULL; } } else { - i = arg; - Py_INCREF(i); + i = Py_NewRef(arg); } /* PyLong equivalent to: @@ -523,30 +576,24 @@ range_hash(rangeobject *r) t = PyTuple_New(3); if (!t) return -1; - Py_INCREF(r->length); - PyTuple_SET_ITEM(t, 0, r->length); + PyTuple_SET_ITEM(t, 0, Py_NewRef(r->length)); cmp_result = PyObject_Not(r->length); if (cmp_result == -1) goto end; if (cmp_result == 1) { - Py_INCREF(Py_None); - Py_INCREF(Py_None); - PyTuple_SET_ITEM(t, 1, Py_None); - PyTuple_SET_ITEM(t, 2, Py_None); + PyTuple_SET_ITEM(t, 1, Py_NewRef(Py_None)); + PyTuple_SET_ITEM(t, 2, Py_NewRef(Py_None)); } else { - Py_INCREF(r->start); - PyTuple_SET_ITEM(t, 1, r->start); + PyTuple_SET_ITEM(t, 1, Py_NewRef(r->start)); cmp_result = PyObject_RichCompareBool(r->length, _PyLong_GetOne(), Py_EQ); if (cmp_result == -1) goto end; if (cmp_result == 1) { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(t, 2, Py_None); + PyTuple_SET_ITEM(t, 2, Py_NewRef(Py_None)); } else { - Py_INCREF(r->step); - PyTuple_SET_ITEM(t, 2, r->step); + PyTuple_SET_ITEM(t, 2, Py_NewRef(r->step)); } } result = PyObject_Hash(t); @@ -764,36 +811,29 @@ PyTypeObject PyRange_Type = { in the normal case, but possible for any numeric value. */ -typedef struct { - PyObject_HEAD - long index; - long start; - long step; - long len; -} rangeiterobject; - static PyObject * -rangeiter_next(rangeiterobject *r) +rangeiter_next(_PyRangeIterObject *r) { - if (r->index < r->len) - /* cast to unsigned to avoid possible signed overflow - in intermediate calculations. */ - return PyLong_FromLong((long)(r->start + - (unsigned long)(r->index++) * r->step)); + if (r->len > 0) { + long result = r->start; + r->start = result + r->step; + r->len--; + return PyLong_FromLong(result); + } return NULL; } static PyObject * -rangeiter_len(rangeiterobject *r, PyObject *Py_UNUSED(ignored)) +rangeiter_len(_PyRangeIterObject *r, PyObject *Py_UNUSED(ignored)) { - return PyLong_FromLong(r->len - r->index); + return PyLong_FromLong(r->len); } PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored)) +rangeiter_reduce(_PyRangeIterObject *r, PyObject *Py_UNUSED(ignored)) { PyObject *start=NULL, *stop=NULL, *step=NULL; PyObject *range; @@ -813,8 +853,8 @@ rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored)) if (range == NULL) goto err; /* return the result */ - return Py_BuildValue("N(N)l", _PyEval_GetBuiltinId(&PyId_iter), - range, r->index); + return Py_BuildValue("N(N)O", _PyEval_GetBuiltin(&_Py_ID(iter)), + range, Py_None); err: Py_XDECREF(start); Py_XDECREF(stop); @@ -823,7 +863,7 @@ err: } static PyObject * -rangeiter_setstate(rangeiterobject *r, PyObject *state) +rangeiter_setstate(_PyRangeIterObject *r, PyObject *state) { long index = PyLong_AsLong(state); if (index == -1 && PyErr_Occurred()) @@ -833,7 +873,8 @@ rangeiter_setstate(rangeiterobject *r, PyObject *state) index = 0; else if (index > r->len) index = r->len; /* exhausted iterator */ - r->index = index; + r->start += index * r->step; + r->len -= index; Py_RETURN_NONE; } @@ -852,8 +893,8 @@ static PyMethodDef rangeiter_methods[] = { PyTypeObject PyRangeIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "range_iterator", /* tp_name */ - sizeof(rangeiterobject), /* tp_basicsize */ + "range_iterator", /* tp_name */ + sizeof(_PyRangeIterObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)PyObject_Del, /* tp_dealloc */ @@ -917,19 +958,17 @@ get_len_of_range(long lo, long hi, long step) static PyObject * fast_range_iter(long start, long stop, long step, long len) { - rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type); + _PyRangeIterObject *it = PyObject_New(_PyRangeIterObject, &PyRangeIter_Type); if (it == NULL) return NULL; it->start = start; it->step = step; it->len = len; - it->index = 0; return (PyObject *)it; } typedef struct { PyObject_HEAD - PyObject *index; PyObject *start; PyObject *step; PyObject *len; @@ -938,7 +977,8 @@ typedef struct { static PyObject * longrangeiter_len(longrangeiterobject *r, PyObject *no_args) { - return PyNumber_Subtract(r->len, r->index); + Py_INCREF(r->len); + return r->len; } static PyObject * @@ -955,10 +995,8 @@ longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored)) Py_DECREF(product); if (stop == NULL) return NULL; - Py_INCREF(r->start); - Py_INCREF(r->step); range = (PyObject*)make_range_object(&PyRange_Type, - r->start, stop, r->step); + Py_NewRef(r->start), stop, Py_NewRef(r->step)); if (range == NULL) { Py_DECREF(r->start); Py_DECREF(stop); @@ -967,8 +1005,8 @@ longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored)) } /* return the result */ - return Py_BuildValue("N(N)O", _PyEval_GetBuiltinId(&PyId_iter), - range, r->index); + return Py_BuildValue("N(N)O", _PyEval_GetBuiltin(&_Py_ID(iter)), + range, Py_None); } static PyObject * @@ -991,8 +1029,22 @@ longrangeiter_setstate(longrangeiterobject *r, PyObject *state) if (cmp > 0) state = r->len; } - Py_INCREF(state); - Py_XSETREF(r->index, state); + PyObject *product = PyNumber_Multiply(state, r->step); + if (product == NULL) + return NULL; + PyObject *new_start = PyNumber_Add(r->start, product); + Py_DECREF(product); + if (new_start == NULL) + return NULL; + PyObject *new_len = PyNumber_Subtract(r->len, state); + if (new_len == NULL) { + Py_DECREF(new_start); + return NULL; + } + PyObject *tmp = r->start; + r->start = new_start; + Py_SETREF(r->len, new_len); + Py_DECREF(tmp); Py_RETURN_NONE; } @@ -1009,7 +1061,6 @@ static PyMethodDef longrangeiter_methods[] = { static void longrangeiter_dealloc(longrangeiterobject *r) { - Py_XDECREF(r->index); Py_XDECREF(r->start); Py_XDECREF(r->step); Py_XDECREF(r->len); @@ -1019,29 +1070,21 @@ longrangeiter_dealloc(longrangeiterobject *r) static PyObject * longrangeiter_next(longrangeiterobject *r) { - PyObject *product, *new_index, *result; - if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1) + if (PyObject_RichCompareBool(r->len, _PyLong_GetZero(), Py_GT) != 1) return NULL; - new_index = PyNumber_Add(r->index, _PyLong_GetOne()); - if (!new_index) - return NULL; - - product = PyNumber_Multiply(r->index, r->step); - if (!product) { - Py_DECREF(new_index); + PyObject *new_start = PyNumber_Add(r->start, r->step); + if (new_start == NULL) { return NULL; } - - result = PyNumber_Add(r->start, product); - Py_DECREF(product); - if (result) { - Py_SETREF(r->index, new_index); + PyObject *new_len = PyNumber_Subtract(r->len, _PyLong_GetOne()); + if (new_len == NULL) { + Py_DECREF(new_start); + return NULL; } - else { - Py_DECREF(new_index); - } - + PyObject *result = r->start; + r->start = new_start; + Py_SETREF(r->len, new_len); return result; } @@ -1127,14 +1170,9 @@ range_iter(PyObject *seq) if (it == NULL) return NULL; - it->start = r->start; - it->step = r->step; - it->len = r->length; - it->index = _PyLong_GetZero(); - Py_INCREF(it->start); - Py_INCREF(it->step); - Py_INCREF(it->len); - Py_INCREF(it->index); + it->start = Py_NewRef(r->start); + it->step = Py_NewRef(r->step); + it->len = Py_NewRef(r->length); return (PyObject *)it; } @@ -1212,11 +1250,10 @@ long_range: it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type); if (it == NULL) return NULL; - it->index = it->start = it->step = NULL; + it->start = it->step = NULL; /* start + (len - 1) * step */ - it->len = range->length; - Py_INCREF(it->len); + it->len = Py_NewRef(range->length); diff = PyNumber_Subtract(it->len, _PyLong_GetOne()); if (!diff) @@ -1237,8 +1274,6 @@ long_range: if (!it->step) goto create_failure; - it->index = _PyLong_GetZero(); - Py_INCREF(it->index); return (PyObject *)it; create_failure: diff --git a/Objects/setobject.c b/Objects/setobject.c index 0be067857d6..fcdda2a0bca 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -346,7 +346,7 @@ set_add_key(PySetObject *so, PyObject *key) Py_hash_t hash; if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + (hash = _PyASCIIObject_CAST(key)->hash) == -1) { hash = PyObject_Hash(key); if (hash == -1) return -1; @@ -360,7 +360,7 @@ set_contains_key(PySetObject *so, PyObject *key) Py_hash_t hash; if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + (hash = _PyASCIIObject_CAST(key)->hash) == -1) { hash = PyObject_Hash(key); if (hash == -1) return -1; @@ -374,7 +374,7 @@ set_discard_key(PySetObject *so, PyObject *key) Py_hash_t hash; if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + (hash = _PyASCIIObject_CAST(key)->hash) == -1) { hash = PyObject_Hash(key); if (hash == -1) return -1; @@ -588,8 +588,7 @@ set_merge(PySetObject *so, PyObject *otherset) key = other_entry->key; if (key != NULL) { assert(so_entry->key == NULL); - Py_INCREF(key); - so_entry->key = key; + so_entry->key = Py_NewRef(key); so_entry->hash = other_entry->hash; } } @@ -607,8 +606,8 @@ set_merge(PySetObject *so, PyObject *otherset) for (i = other->mask + 1; i > 0 ; i--, other_entry++) { key = other_entry->key; if (key != NULL && key != dummy) { - Py_INCREF(key); - set_insert_clean(newtable, newmask, key, other_entry->hash); + set_insert_clean(newtable, newmask, Py_NewRef(key), + other_entry->hash); } } return 0; @@ -770,7 +769,6 @@ static PyObject *setiter_iternext(setiterobject *si); static PyObject * setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(iter); /* copy the iterator state */ setiterobject tmp = *si; Py_XINCREF(tmp.si_set); @@ -781,7 +779,7 @@ setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored)) if (list == NULL) { return NULL; } - return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list); + return Py_BuildValue("N(N)", _PyEval_GetBuiltin(&_Py_ID(iter)), list); } PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); @@ -821,8 +819,7 @@ static PyObject *setiter_iternext(setiterobject *si) goto fail; si->len--; key = entry[i].key; - Py_INCREF(key); - return key; + return Py_NewRef(key); fail: si->si_set = NULL; @@ -869,8 +866,7 @@ set_iter(PySetObject *so) setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type); if (si == NULL) return NULL; - Py_INCREF(so); - si->si_set = so; + si->si_set = (PySetObject*)Py_NewRef(so); si->si_used = so->used; si->si_pos = 0; si->len = so->used; @@ -998,10 +994,9 @@ make_new_frozenset(PyTypeObject *type, PyObject *iterable) if (iterable != NULL && PyFrozenSet_CheckExact(iterable)) { /* frozenset(f) is idempotent */ - Py_INCREF(iterable); - return iterable; + return Py_NewRef(iterable); } - return make_new_set((PyTypeObject *)type, iterable); + return make_new_set(type, iterable); } static PyObject * @@ -1036,7 +1031,7 @@ frozenset_vectorcall(PyObject *type, PyObject * const*args, } PyObject *iterable = (nargs ? args[0] : NULL); - return make_new_frozenset((PyTypeObject *)type, iterable); + return make_new_frozenset(_PyType_CAST(type), iterable); } static PyObject * @@ -1101,8 +1096,7 @@ static PyObject * frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored)) { if (PyFrozenSet_CheckExact(so)) { - Py_INCREF(so); - return (PyObject *)so; + return Py_NewRef(so); } return set_copy(so, NULL); } @@ -1174,8 +1168,7 @@ set_ior(PySetObject *so, PyObject *other) if (set_update_internal(so, other)) return NULL; - Py_INCREF(so); - return (PyObject *)so; + return Py_NewRef(so); } static PyObject * @@ -1206,17 +1199,21 @@ set_intersection(PySetObject *so, PyObject *other) while (set_next((PySetObject *)other, &pos, &entry)) { key = entry->key; hash = entry->hash; + Py_INCREF(key); rv = set_contains_entry(so, key, hash); if (rv < 0) { Py_DECREF(result); + Py_DECREF(key); return NULL; } if (rv) { if (set_add_entry(result, key, hash)) { Py_DECREF(result); + Py_DECREF(key); return NULL; } } + Py_DECREF(key); } return (PyObject *)result; } @@ -1237,6 +1234,10 @@ set_intersection(PySetObject *so, PyObject *other) if (rv) { if (set_add_entry(result, key, hash)) goto error; + if (PySet_GET_SIZE(result) >= PySet_GET_SIZE(so)) { + Py_DECREF(key); + break; + } } Py_DECREF(key); } @@ -1257,12 +1258,11 @@ static PyObject * set_intersection_multi(PySetObject *so, PyObject *args) { Py_ssize_t i; - PyObject *result = (PyObject *)so; if (PyTuple_GET_SIZE(args) == 0) return set_copy(so, NULL); - Py_INCREF(so); + PyObject *result = Py_NewRef(so); for (i=0 ; ikey, entry->hash); - if (rv < 0) + PyObject *key = entry->key; + Py_INCREF(key); + rv = set_contains_entry(so, key, entry->hash); + Py_DECREF(key); + if (rv < 0) { return NULL; - if (rv) + } + if (rv) { Py_RETURN_FALSE; + } } Py_RETURN_TRUE; } @@ -1370,14 +1373,7 @@ set_isdisjoint(PySetObject *so, PyObject *other) return NULL; while ((key = PyIter_Next(it)) != NULL) { - Py_hash_t hash = PyObject_Hash(key); - - if (hash == -1) { - Py_DECREF(key); - Py_DECREF(it); - return NULL; - } - rv = set_contains_entry(so, key, hash); + rv = set_contains_key(so, key); Py_DECREF(key); if (rv < 0) { Py_DECREF(it); @@ -1419,11 +1415,16 @@ set_difference_update_internal(PySetObject *so, PyObject *other) Py_INCREF(other); } - while (set_next((PySetObject *)other, &pos, &entry)) - if (set_discard_entry(so, entry->key, entry->hash) < 0) { + while (set_next((PySetObject *)other, &pos, &entry)) { + PyObject *key = entry->key; + Py_INCREF(key); + if (set_discard_entry(so, key, entry->hash) < 0) { Py_DECREF(other); + Py_DECREF(key); return -1; } + Py_DECREF(key); + } Py_DECREF(other); } else { @@ -1514,17 +1515,21 @@ set_difference(PySetObject *so, PyObject *other) while (set_next(so, &pos, &entry)) { key = entry->key; hash = entry->hash; + Py_INCREF(key); rv = _PyDict_Contains_KnownHash(other, key, hash); if (rv < 0) { Py_DECREF(result); + Py_DECREF(key); return NULL; } if (!rv) { if (set_add_entry((PySetObject *)result, key, hash)) { Py_DECREF(result); + Py_DECREF(key); return NULL; } } + Py_DECREF(key); } return result; } @@ -1533,17 +1538,21 @@ set_difference(PySetObject *so, PyObject *other) while (set_next(so, &pos, &entry)) { key = entry->key; hash = entry->hash; + Py_INCREF(key); rv = set_contains_entry((PySetObject *)other, key, hash); if (rv < 0) { Py_DECREF(result); + Py_DECREF(key); return NULL; } if (!rv) { if (set_add_entry((PySetObject *)result, key, hash)) { Py_DECREF(result); + Py_DECREF(key); return NULL; } } + Py_DECREF(key); } return result; } @@ -1591,8 +1600,7 @@ set_isub(PySetObject *so, PyObject *other) Py_RETURN_NOTIMPLEMENTED; if (set_difference_update_internal(so, other)) return NULL; - Py_INCREF(so); - return (PyObject *)so; + return Py_NewRef(so); } static PyObject * @@ -1629,8 +1637,7 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other) } if (PyAnySet_Check(other)) { - Py_INCREF(other); - otherset = (PySetObject *)other; + otherset = (PySetObject *)Py_NewRef(other); } else { otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other); if (otherset == NULL) @@ -1640,17 +1647,21 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other) while (set_next(otherset, &pos, &entry)) { key = entry->key; hash = entry->hash; + Py_INCREF(key); rv = set_discard_entry(so, key, hash); if (rv < 0) { Py_DECREF(otherset); + Py_DECREF(key); return NULL; } if (rv == DISCARD_NOTFOUND) { if (set_add_entry(so, key, hash)) { Py_DECREF(otherset); + Py_DECREF(key); return NULL; } } + Py_DECREF(key); } Py_DECREF(otherset); Py_RETURN_NONE; @@ -1701,8 +1712,7 @@ set_ixor(PySetObject *so, PyObject *other) if (result == NULL) return NULL; Py_DECREF(result); - Py_INCREF(so); - return (PyObject *)so; + return Py_NewRef(so); } static PyObject * @@ -1713,23 +1723,28 @@ set_issubset(PySetObject *so, PyObject *other) int rv; if (!PyAnySet_Check(other)) { - PyObject *tmp, *result; - tmp = make_new_set(&PySet_Type, other); - if (tmp == NULL) + PyObject *tmp = set_intersection(so, other); + if (tmp == NULL) { return NULL; - result = set_issubset(so, tmp); + } + int result = (PySet_GET_SIZE(tmp) == PySet_GET_SIZE(so)); Py_DECREF(tmp); - return result; + return PyBool_FromLong(result); } if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other)) Py_RETURN_FALSE; while (set_next(so, &pos, &entry)) { - rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash); - if (rv < 0) + PyObject *key = entry->key; + Py_INCREF(key); + rv = set_contains_entry((PySetObject *)other, key, entry->hash); + Py_DECREF(key); + if (rv < 0) { return NULL; - if (!rv) + } + if (!rv) { Py_RETURN_FALSE; + } } Py_RETURN_TRUE; } @@ -1739,17 +1754,31 @@ PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set."); static PyObject * set_issuperset(PySetObject *so, PyObject *other) { - PyObject *tmp, *result; - - if (!PyAnySet_Check(other)) { - tmp = make_new_set(&PySet_Type, other); - if (tmp == NULL) - return NULL; - result = set_issuperset(so, tmp); - Py_DECREF(tmp); - return result; + if (PyAnySet_Check(other)) { + return set_issubset((PySetObject *)other, (PyObject *)so); } - return set_issubset((PySetObject *)other, (PyObject *)so); + + PyObject *key, *it = PyObject_GetIter(other); + if (it == NULL) { + return NULL; + } + while ((key = PyIter_Next(it)) != NULL) { + int rv = set_contains_key(so, key); + Py_DECREF(key); + if (rv < 0) { + Py_DECREF(it); + return NULL; + } + if (!rv) { + Py_DECREF(it); + Py_RETURN_FALSE; + } + } + Py_DECREF(it); + if (PyErr_Occurred()) { + return NULL; + } + Py_RETURN_TRUE; } PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set."); @@ -1900,13 +1929,13 @@ set_discard(PySetObject *so, PyObject *key) PyDoc_STRVAR(discard_doc, "Remove an element from a set if it is a member.\n\ \n\ -If the element is not a member, do nothing."); +Unlike set.remove(), the discard() method does not raise\n\ +an exception when an element is missing from the set."); static PyObject * set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored)) { - PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL; - _Py_IDENTIFIER(__dict__); + PyObject *keys=NULL, *args=NULL, *result=NULL, *state=NULL; keys = PySequence_List((PyObject *)so); if (keys == NULL) @@ -1914,30 +1943,25 @@ set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored)) args = PyTuple_Pack(1, keys); if (args == NULL) goto done; - if (_PyObject_LookupAttrId((PyObject *)so, &PyId___dict__, &dict) < 0) { + state = _PyObject_GetState((PyObject *)so); + if (state == NULL) goto done; - } - if (dict == NULL) { - dict = Py_None; - Py_INCREF(dict); - } - result = PyTuple_Pack(3, Py_TYPE(so), args, dict); + result = PyTuple_Pack(3, Py_TYPE(so), args, state); done: Py_XDECREF(args); Py_XDECREF(keys); - Py_XDECREF(dict); + Py_XDECREF(state); return result; } static PyObject * set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored)) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(so)); - if (so->table != so->smalltable) - res = res + (so->mask + 1) * sizeof(setentry); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(so)); + if (so->table != so->smalltable) { + res += ((size_t)so->mask + 1) * sizeof(setentry); + } + return PyLong_FromSize_t(res); } PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes"); @@ -1946,9 +1970,7 @@ set_init(PySetObject *self, PyObject *args, PyObject *kwds) { PyObject *iterable = NULL; - if ((Py_IS_TYPE(self, &PySet_Type) || - Py_TYPE(self)->tp_new == PySet_Type.tp_new) && - !_PyArg_NoKeywords("set", kwds)) + if (!_PyArg_NoKeywords("set", kwds)) return -1; if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable)) return -1; @@ -1976,10 +1998,10 @@ set_vectorcall(PyObject *type, PyObject * const*args, } if (nargs) { - return make_new_set((PyTypeObject *)type, args[0]); + return make_new_set(_PyType_CAST(type), args[0]); } - return make_new_set((PyTypeObject *)type, NULL); + return make_new_set(_PyType_CAST(type), NULL); } static PySequenceMethods set_as_sequence = { diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 22fb7c61c35..5694bd9c661 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -26,8 +26,7 @@ ellipsis_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyErr_SetString(PyExc_TypeError, "EllipsisType takes no arguments"); return NULL; } - Py_INCREF(Py_Ellipsis); - return Py_Ellipsis; + return Py_NewRef(Py_Ellipsis); } static PyObject * @@ -110,6 +109,37 @@ void _PySlice_Fini(PyInterpreterState *interp) index is present. */ +static PySliceObject * +_PyBuildSlice_Consume2(PyObject *start, PyObject *stop, PyObject *step) +{ + assert(start != NULL && stop != NULL && step != NULL); + + PyInterpreterState *interp = _PyInterpreterState_GET(); + PySliceObject *obj; + if (interp->slice_cache != NULL) { + obj = interp->slice_cache; + interp->slice_cache = NULL; + _Py_NewReference((PyObject *)obj); + } + else { + obj = PyObject_GC_New(PySliceObject, &PySlice_Type); + if (obj == NULL) { + goto error; + } + } + + obj->start = start; + obj->stop = stop; + obj->step = Py_NewRef(step); + + _PyObject_GC_TRACK(obj); + return obj; +error: + Py_DECREF(start); + Py_DECREF(stop); + return NULL; +} + PyObject * PySlice_New(PyObject *start, PyObject *stop, PyObject *step) { @@ -122,30 +152,15 @@ PySlice_New(PyObject *start, PyObject *stop, PyObject *step) if (stop == NULL) { stop = Py_None; } + return (PyObject *)_PyBuildSlice_Consume2(Py_NewRef(start), + Py_NewRef(stop), step); +} - PyInterpreterState *interp = _PyInterpreterState_GET(); - PySliceObject *obj; - if (interp->slice_cache != NULL) { - obj = interp->slice_cache; - interp->slice_cache = NULL; - _Py_NewReference((PyObject *)obj); - } - else { - obj = PyObject_GC_New(PySliceObject, &PySlice_Type); - if (obj == NULL) { - return NULL; - } - } - - Py_INCREF(step); - obj->step = step; - Py_INCREF(start); - obj->start = start; - Py_INCREF(stop); - obj->stop = stop; - - _PyObject_GC_TRACK(obj); - return (PyObject *) obj; +PyObject * +_PyBuildSlice_ConsumeRefs(PyObject *start, PyObject *stop) +{ + assert(start != NULL && stop != NULL); + return (PyObject *)_PyBuildSlice_Consume2(start, stop, Py_None); } PyObject * @@ -206,7 +221,8 @@ PySlice_Unpack(PyObject *_r, PySliceObject *r = (PySliceObject*)_r; /* this is harder to get right than you might think */ - Py_BUILD_ASSERT(PY_SSIZE_T_MIN + 1 <= -PY_SSIZE_T_MAX); + static_assert(PY_SSIZE_T_MIN + 1 <= -PY_SSIZE_T_MAX, + "-PY_SSIZE_T_MAX < PY_SSIZE_T_MIN + 1"); if (r->step == Py_None) { *step = 1; @@ -388,8 +404,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, /* Convert step to an integer; raise for zero step. */ if (self->step == Py_None) { - step = _PyLong_GetOne(); - Py_INCREF(step); + step = Py_NewRef(_PyLong_GetOne()); step_is_negative = 0; } else { @@ -417,16 +432,13 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, goto error; } else { - lower = _PyLong_GetZero(); - Py_INCREF(lower); - upper = length; - Py_INCREF(upper); + lower = Py_NewRef(_PyLong_GetZero()); + upper = Py_NewRef(length); } /* Compute start. */ if (self->start == Py_None) { - start = step_is_negative ? upper : lower; - Py_INCREF(start); + start = Py_NewRef(step_is_negative ? upper : lower); } else { start = evaluate_slice_index(self->start); @@ -436,8 +448,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, if (_PyLong_Sign(start) < 0) { /* start += length */ PyObject *tmp = PyNumber_Add(start, length); - Py_DECREF(start); - start = tmp; + Py_SETREF(start, tmp); if (start == NULL) goto error; @@ -445,9 +456,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, if (cmp_result < 0) goto error; if (cmp_result) { - Py_INCREF(lower); - Py_DECREF(start); - start = lower; + Py_SETREF(start, Py_NewRef(lower)); } } else { @@ -455,17 +464,14 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, if (cmp_result < 0) goto error; if (cmp_result) { - Py_INCREF(upper); - Py_DECREF(start); - start = upper; + Py_SETREF(start, Py_NewRef(upper)); } } } /* Compute stop. */ if (self->stop == Py_None) { - stop = step_is_negative ? lower : upper; - Py_INCREF(stop); + stop = Py_NewRef(step_is_negative ? lower : upper); } else { stop = evaluate_slice_index(self->stop); @@ -475,8 +481,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, if (_PyLong_Sign(stop) < 0) { /* stop += length */ PyObject *tmp = PyNumber_Add(stop, length); - Py_DECREF(stop); - stop = tmp; + Py_SETREF(stop, tmp); if (stop == NULL) goto error; @@ -484,9 +489,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, if (cmp_result < 0) goto error; if (cmp_result) { - Py_INCREF(lower); - Py_DECREF(stop); - stop = lower; + Py_SETREF(stop, Py_NewRef(lower)); } } else { @@ -494,9 +497,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, if (cmp_result < 0) goto error; if (cmp_result) { - Py_INCREF(upper); - Py_DECREF(stop); - stop = upper; + Py_SETREF(stop, Py_NewRef(upper)); } } } @@ -591,8 +592,7 @@ slice_richcompare(PyObject *v, PyObject *w, int op) res = Py_False; break; } - Py_INCREF(res); - return res; + return Py_NewRef(res); } diff --git a/Objects/stringlib/asciilib.h b/Objects/stringlib/asciilib.h index 7749e8fb339..b3016bfbbb0 100644 --- a/Objects/stringlib/asciilib.h +++ b/Objects/stringlib/asciilib.h @@ -20,6 +20,8 @@ #define STRINGLIB_NEW(STR,LEN) _PyUnicode_FromASCII((const char*)(STR),(LEN)) #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact +#define STRINGLIB_MUTABLE 0 +#define STRINGLIB_FAST_MEMCHR memchr #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_ASCII diff --git a/Objects/stringlib/clinic/transmogrify.h.h b/Objects/stringlib/clinic/transmogrify.h.h index a5135a0cba0..49388cf043c 100644 --- a/Objects/stringlib/clinic/transmogrify.h.h +++ b/Objects/stringlib/clinic/transmogrify.h.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(stringlib_expandtabs__doc__, "expandtabs($self, /, tabsize=8)\n" "--\n" @@ -11,7 +17,7 @@ PyDoc_STRVAR(stringlib_expandtabs__doc__, "If tabsize is not given, a tab size of 8 characters is assumed."); #define STRINGLIB_EXPANDTABS_METHODDEF \ - {"expandtabs", (PyCFunction)(void(*)(void))stringlib_expandtabs, METH_FASTCALL|METH_KEYWORDS, stringlib_expandtabs__doc__}, + {"expandtabs", _PyCFunction_CAST(stringlib_expandtabs), METH_FASTCALL|METH_KEYWORDS, stringlib_expandtabs__doc__}, static PyObject * stringlib_expandtabs_impl(PyObject *self, int tabsize); @@ -20,8 +26,31 @@ static PyObject * stringlib_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tabsize), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"tabsize", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "expandtabs", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "expandtabs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int tabsize = 8; @@ -53,7 +82,7 @@ PyDoc_STRVAR(stringlib_ljust__doc__, "Padding is done using the specified fill character."); #define STRINGLIB_LJUST_METHODDEF \ - {"ljust", (PyCFunction)(void(*)(void))stringlib_ljust, METH_FASTCALL, stringlib_ljust__doc__}, + {"ljust", _PyCFunction_CAST(stringlib_ljust), METH_FASTCALL, stringlib_ljust__doc__}, static PyObject * stringlib_ljust_impl(PyObject *self, Py_ssize_t width, char fillchar); @@ -109,7 +138,7 @@ PyDoc_STRVAR(stringlib_rjust__doc__, "Padding is done using the specified fill character."); #define STRINGLIB_RJUST_METHODDEF \ - {"rjust", (PyCFunction)(void(*)(void))stringlib_rjust, METH_FASTCALL, stringlib_rjust__doc__}, + {"rjust", _PyCFunction_CAST(stringlib_rjust), METH_FASTCALL, stringlib_rjust__doc__}, static PyObject * stringlib_rjust_impl(PyObject *self, Py_ssize_t width, char fillchar); @@ -165,7 +194,7 @@ PyDoc_STRVAR(stringlib_center__doc__, "Padding is done using the specified fill character."); #define STRINGLIB_CENTER_METHODDEF \ - {"center", (PyCFunction)(void(*)(void))stringlib_center, METH_FASTCALL, stringlib_center__doc__}, + {"center", _PyCFunction_CAST(stringlib_center), METH_FASTCALL, stringlib_center__doc__}, static PyObject * stringlib_center_impl(PyObject *self, Py_ssize_t width, char fillchar); @@ -249,4 +278,4 @@ stringlib_zfill(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=2d9abc7b1cffeca6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d44a269805f6739e input=a9049054013a1b77]*/ diff --git a/Objects/stringlib/codecs.h b/Objects/stringlib/codecs.h index b17cda18f54..958cc861478 100644 --- a/Objects/stringlib/codecs.h +++ b/Objects/stringlib/codecs.h @@ -387,8 +387,19 @@ STRINGLIB(utf8_encoder)(_PyBytesWriter *writer, if (!rep) goto error; - /* subtract preallocated bytes */ - writer->min_size -= max_char_size * (newpos - startpos); + if (newpos < startpos) { + writer->overallocate = 1; + p = _PyBytesWriter_Prepare(writer, p, + max_char_size * (startpos - newpos)); + if (p == NULL) + goto error; + } + else { + /* subtract preallocated bytes */ + writer->min_size -= max_char_size * (newpos - startpos); + /* Only overallocate the buffer if it's not the last write */ + writer->overallocate = (newpos < size); + } if (PyBytes_Check(rep)) { p = _PyBytesWriter_WriteBytes(writer, p, diff --git a/Objects/stringlib/count.h b/Objects/stringlib/count.h index f48500bf561..e20edcd104b 100644 --- a/Objects/stringlib/count.h +++ b/Objects/stringlib/count.h @@ -4,6 +4,11 @@ #error must include "stringlib/fastsearch.h" before including this module #endif +// gh-97982: Implementing asciilib_count() is not worth it, FASTSEARCH() does +// not specialize the code for ASCII strings. Use ucs1lib_count() for ASCII and +// UCS1 strings: it's the same than asciilib_count(). +#if !STRINGLIB_IS_UNICODE || STRINGLIB_MAX_CHAR > 0x7Fu + Py_LOCAL_INLINE(Py_ssize_t) STRINGLIB(count)(const STRINGLIB_CHAR* str, Py_ssize_t str_len, const STRINGLIB_CHAR* sub, Py_ssize_t sub_len, @@ -24,4 +29,4 @@ STRINGLIB(count)(const STRINGLIB_CHAR* str, Py_ssize_t str_len, return count; } - +#endif diff --git a/Objects/stringlib/eq.h b/Objects/stringlib/eq.h index 9c1058b86cb..2eac4baf5ca 100644 --- a/Objects/stringlib/eq.h +++ b/Objects/stringlib/eq.h @@ -4,16 +4,8 @@ * unicode_eq() is called when the hash of two unicode objects is equal. */ Py_LOCAL_INLINE(int) -unicode_eq(PyObject *aa, PyObject *bb) +unicode_eq(PyObject *a, PyObject *b) { - assert(PyUnicode_Check(aa)); - assert(PyUnicode_Check(bb)); - assert(PyUnicode_IS_READY(aa)); - assert(PyUnicode_IS_READY(bb)); - - PyUnicodeObject *a = (PyUnicodeObject *)aa; - PyUnicodeObject *b = (PyUnicodeObject *)bb; - if (PyUnicode_GET_LENGTH(a) != PyUnicode_GET_LENGTH(b)) return 0; if (PyUnicode_GET_LENGTH(a) == 0) diff --git a/Objects/stringlib/fastsearch.h b/Objects/stringlib/fastsearch.h index b91082bd523..257b7bd6788 100644 --- a/Objects/stringlib/fastsearch.h +++ b/Objects/stringlib/fastsearch.h @@ -18,7 +18,8 @@ algorithm, which has worst-case O(n) runtime and best-case O(n/k). Also compute a table of shifts to achieve O(n/k) in more cases, and often (data dependent) deduce larger shifts than pure C&P can - deduce. */ + deduce. See stringlib_find_two_way_notes.txt in this folder for a + detailed explanation. */ #define FAST_COUNT 0 #define FAST_SEARCH 1 @@ -39,7 +40,7 @@ #define STRINGLIB_BLOOM(mask, ch) \ ((mask & (1UL << ((ch) & (STRINGLIB_BLOOM_WIDTH -1))))) -#if STRINGLIB_SIZEOF_CHAR == 1 +#ifdef STRINGLIB_FAST_MEMCHR # define MEMCHR_CUT_OFF 15 #else # define MEMCHR_CUT_OFF 40 @@ -53,8 +54,8 @@ STRINGLIB(find_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) p = s; e = s + n; if (n > MEMCHR_CUT_OFF) { -#if STRINGLIB_SIZEOF_CHAR == 1 - p = memchr(s, ch, n); +#ifdef STRINGLIB_FAST_MEMCHR + p = STRINGLIB_FAST_MEMCHR(s, ch, n); if (p != NULL) return (p - s); return -1; @@ -102,16 +103,26 @@ STRINGLIB(find_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) return -1; } +#undef MEMCHR_CUT_OFF + +#if STRINGLIB_SIZEOF_CHAR == 1 +# define MEMRCHR_CUT_OFF 15 +#else +# define MEMRCHR_CUT_OFF 40 +#endif + + Py_LOCAL_INLINE(Py_ssize_t) STRINGLIB(rfind_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) { const STRINGLIB_CHAR *p; #ifdef HAVE_MEMRCHR - /* memrchr() is a GNU extension, available since glibc 2.1.91. - it doesn't seem as optimized as memchr(), but is still quite - faster than our hand-written loop below */ + /* memrchr() is a GNU extension, available since glibc 2.1.91. it + doesn't seem as optimized as memchr(), but is still quite + faster than our hand-written loop below. There is no wmemrchr + for 4-byte chars. */ - if (n > MEMCHR_CUT_OFF) { + if (n > MEMRCHR_CUT_OFF) { #if STRINGLIB_SIZEOF_CHAR == 1 p = memrchr(s, ch, n); if (p != NULL) @@ -139,11 +150,11 @@ STRINGLIB(rfind_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) if (*p == ch) return n; /* False positive */ - if (n1 - n > MEMCHR_CUT_OFF) + if (n1 - n > MEMRCHR_CUT_OFF) continue; - if (n <= MEMCHR_CUT_OFF) + if (n <= MEMRCHR_CUT_OFF) break; - s1 = p - MEMCHR_CUT_OFF; + s1 = p - MEMRCHR_CUT_OFF; while (p > s1) { p--; if (*p == ch) @@ -151,7 +162,7 @@ STRINGLIB(rfind_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) } n = p - s; } - while (n > MEMCHR_CUT_OFF); + while (n > MEMRCHR_CUT_OFF); } #endif } @@ -165,7 +176,7 @@ STRINGLIB(rfind_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) return -1; } -#undef MEMCHR_CUT_OFF +#undef MEMRCHR_CUT_OFF /* Change to a 1 to see logging comments walk through the algorithm. */ #if 0 && STRINGLIB_SIZEOF_CHAR == 1 @@ -345,7 +356,7 @@ STRINGLIB(_preprocess)(const STRINGLIB_CHAR *needle, Py_ssize_t len_needle, } // Fill up a compressed Boyer-Moore "Bad Character" table Py_ssize_t not_found_shift = Py_MIN(len_needle, MAX_SHIFT); - for (Py_ssize_t i = 0; i < TABLE_SIZE; i++) { + for (Py_ssize_t i = 0; i < (Py_ssize_t)TABLE_SIZE; i++) { p->table[i] = Py_SAFE_DOWNCAST(not_found_shift, Py_ssize_t, SHIFT_TYPE); } @@ -388,7 +399,7 @@ STRINGLIB(_two_way)(const STRINGLIB_CHAR *haystack, Py_ssize_t len_haystack, if (window_last >= haystack_end) { return -1; } - LOG("Horspool skip"); + LOG("Horspool skip\n"); } no_shift: window = window_last - len_needle + 1; @@ -447,7 +458,7 @@ STRINGLIB(_two_way)(const STRINGLIB_CHAR *haystack, Py_ssize_t len_haystack, if (window_last >= haystack_end) { return -1; } - LOG("Horspool skip"); + LOG("Horspool skip\n"); } window = window_last - len_needle + 1; assert((window[len_needle - 1] & TABLE_MASK) == diff --git a/Objects/stringlib/join.h b/Objects/stringlib/join.h index 62e4c98de7f..de6bd83ffe4 100644 --- a/Objects/stringlib/join.h +++ b/Objects/stringlib/join.h @@ -32,7 +32,7 @@ STRINGLIB(bytes_join)(PyObject *sep, PyObject *iterable) Py_DECREF(seq); return STRINGLIB_NEW(NULL, 0); } -#ifndef STRINGLIB_MUTABLE +#if !STRINGLIB_MUTABLE if (seqlen == 1) { item = PySequence_Fast_GET_ITEM(seq, 0); if (STRINGLIB_CHECK_EXACT(item)) { @@ -63,8 +63,7 @@ STRINGLIB(bytes_join)(PyObject *sep, PyObject *iterable) item = PySequence_Fast_GET_ITEM(seq, i); if (PyBytes_CheckExact(item)) { /* Fast path. */ - Py_INCREF(item); - buffers[i].obj = item; + buffers[i].obj = Py_NewRef(item); buffers[i].buf = PyBytes_AS_STRING(item); buffers[i].len = PyBytes_GET_SIZE(item); } diff --git a/Objects/stringlib/localeutil.h b/Objects/stringlib/localeutil.h index bd16e0a1728..d77715ec0de 100644 --- a/Objects/stringlib/localeutil.h +++ b/Objects/stringlib/localeutil.h @@ -75,7 +75,7 @@ InsertThousandsGrouping_fill(_PyUnicodeWriter *writer, Py_ssize_t *buffer_pos, if (n_zeros) { *buffer_pos -= n_zeros; - enum PyUnicode_Kind kind = PyUnicode_KIND(writer->buffer); + int kind = PyUnicode_KIND(writer->buffer); void *data = PyUnicode_DATA(writer->buffer); unicode_fill(kind, data, '0', *buffer_pos, n_zeros); } diff --git a/Objects/stringlib/replace.h b/Objects/stringlib/replace.h index ef318ed6dd5..123c9f850f5 100644 --- a/Objects/stringlib/replace.h +++ b/Objects/stringlib/replace.h @@ -29,9 +29,9 @@ STRINGLIB(replace_1char_inplace)(STRINGLIB_CHAR* s, STRINGLIB_CHAR* end, if (!--attempts) { /* if u1 was not found for attempts iterations, use FASTSEARCH() or memchr() */ -#if STRINGLIB_SIZEOF_CHAR == 1 +#ifdef STRINGLIB_FAST_MEMCHR s++; - s = memchr(s, u1, end - s); + s = STRINGLIB_FAST_MEMCHR(s, u1, end - s); if (s == NULL) return; #else diff --git a/Objects/stringlib/split.h b/Objects/stringlib/split.h index 068047f9874..0c11b7214e9 100644 --- a/Objects/stringlib/split.h +++ b/Objects/stringlib/split.h @@ -70,7 +70,7 @@ STRINGLIB(split_whitespace)(PyObject* str_obj, j = i; i++; while (i < str_len && !STRINGLIB_ISSPACE(str[i])) i++; -#ifndef STRINGLIB_MUTABLE +#if !STRINGLIB_MUTABLE if (j == 0 && i == str_len && STRINGLIB_CHECK_EXACT(str_obj)) { /* No whitespace in str_obj, so just use it as list[0] */ Py_INCREF(str_obj); @@ -122,7 +122,7 @@ STRINGLIB(split_char)(PyObject* str_obj, } } } -#ifndef STRINGLIB_MUTABLE +#if !STRINGLIB_MUTABLE if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) { /* ch not in str_obj, so just use str_obj as list[0] */ Py_INCREF(str_obj); @@ -170,7 +170,7 @@ STRINGLIB(split)(PyObject* str_obj, SPLIT_ADD(str, i, j); i = j + sep_len; } -#ifndef STRINGLIB_MUTABLE +#if !STRINGLIB_MUTABLE if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) { /* No match in str_obj, so just use it as list[0] */ Py_INCREF(str_obj); @@ -209,7 +209,7 @@ STRINGLIB(rsplit_whitespace)(PyObject* str_obj, j = i; i--; while (i >= 0 && !STRINGLIB_ISSPACE(str[i])) i--; -#ifndef STRINGLIB_MUTABLE +#if !STRINGLIB_MUTABLE if (j == str_len - 1 && i < 0 && STRINGLIB_CHECK_EXACT(str_obj)) { /* No whitespace in str_obj, so just use it as list[0] */ Py_INCREF(str_obj); @@ -262,7 +262,7 @@ STRINGLIB(rsplit_char)(PyObject* str_obj, } } } -#ifndef STRINGLIB_MUTABLE +#if !STRINGLIB_MUTABLE if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) { /* ch not in str_obj, so just use str_obj as list[0] */ Py_INCREF(str_obj); @@ -311,7 +311,7 @@ STRINGLIB(rsplit)(PyObject* str_obj, SPLIT_ADD(str, pos + sep_len, j); j = pos; } -#ifndef STRINGLIB_MUTABLE +#if !STRINGLIB_MUTABLE if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) { /* No match in str_obj, so just use it as list[0] */ Py_INCREF(str_obj); @@ -370,7 +370,7 @@ STRINGLIB(splitlines)(PyObject* str_obj, if (keepends) eol = i; } -#ifndef STRINGLIB_MUTABLE +#if !STRINGLIB_MUTABLE if (j == 0 && eol == str_len && STRINGLIB_CHECK_EXACT(str_obj)) { /* No linebreak in str_obj, so just use it as list[0] */ if (PyList_Append(list, str_obj)) diff --git a/Objects/stringlib/stringdefs.h b/Objects/stringlib/stringdefs.h index 88641b25d47..484b98b7291 100644 --- a/Objects/stringlib/stringdefs.h +++ b/Objects/stringlib/stringdefs.h @@ -24,4 +24,5 @@ #define STRINGLIB_CHECK_EXACT PyBytes_CheckExact #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_Repr +#define STRINGLIB_FAST_MEMCHR memchr #endif /* !STRINGLIB_STRINGDEFS_H */ diff --git a/Objects/stringlib/stringlib_find_two_way_notes.txt b/Objects/stringlib/stringlib_find_two_way_notes.txt index afe45431a75..f97615b42ff 100644 --- a/Objects/stringlib/stringlib_find_two_way_notes.txt +++ b/Objects/stringlib/stringlib_find_two_way_notes.txt @@ -239,7 +239,7 @@ We cut as AA + bAAbAAbA, and then the algorithm runs as follows: ~~ AA != bA at the cut bbbAbbAAbAAbAAbbbAAbAAbAAbAA AAbAAbAAbA - ^^^^X 7-3=4 match, and the 5th misses. + ^^^^X 7-3=4 match, and the 5th misses. bbbAbbAAbAAbAAbbbAAbAAbAAbAA AAbAAbAAbA ~ A != b at the cut @@ -395,7 +395,7 @@ of their proof goes something like this (this is far from complete): needle == (a + w) + (w + b), meaning there's a bad equality w == w, it's impossible for w + b to be bigger than both b and w + w + b, so this can't happen. We thus have all of - the ineuqalities with no question marks. + the inequalities with no question marks. * By maximality, the right part is not a substring of the left part. Thus, we have all of the inequalities involving no left-side question marks. diff --git a/Objects/stringlib/transmogrify.h b/Objects/stringlib/transmogrify.h index e1165ea38e8..71099bb586e 100644 --- a/Objects/stringlib/transmogrify.h +++ b/Objects/stringlib/transmogrify.h @@ -17,8 +17,7 @@ return_self(PyObject *self) { #if !STRINGLIB_MUTABLE if (STRINGLIB_CHECK_EXACT(self)) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } #endif return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self)); diff --git a/Objects/stringlib/ucs1lib.h b/Objects/stringlib/ucs1lib.h index 5b0b8a025e8..1b9b65ecbaa 100644 --- a/Objects/stringlib/ucs1lib.h +++ b/Objects/stringlib/ucs1lib.h @@ -20,6 +20,8 @@ #define STRINGLIB_NEW _PyUnicode_FromUCS1 #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact +#define STRINGLIB_FAST_MEMCHR memchr +#define STRINGLIB_MUTABLE 0 #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_ASCII diff --git a/Objects/stringlib/ucs2lib.h b/Objects/stringlib/ucs2lib.h index 6af01511c5f..4b49bbb31d7 100644 --- a/Objects/stringlib/ucs2lib.h +++ b/Objects/stringlib/ucs2lib.h @@ -20,6 +20,11 @@ #define STRINGLIB_NEW _PyUnicode_FromUCS2 #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact +#define STRINGLIB_MUTABLE 0 +#if SIZEOF_WCHAR_T == 2 +#define STRINGLIB_FAST_MEMCHR(s, c, n) \ + (Py_UCS2 *)wmemchr((const wchar_t *)(s), c, n) +#endif #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_ASCII diff --git a/Objects/stringlib/ucs4lib.h b/Objects/stringlib/ucs4lib.h index 39071a0cdf0..def4ca5d17d 100644 --- a/Objects/stringlib/ucs4lib.h +++ b/Objects/stringlib/ucs4lib.h @@ -20,6 +20,11 @@ #define STRINGLIB_NEW _PyUnicode_FromUCS4 #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact +#define STRINGLIB_MUTABLE 0 +#if SIZEOF_WCHAR_T == 4 +#define STRINGLIB_FAST_MEMCHR(s, c, n) \ + (Py_UCS4 *)wmemchr((const wchar_t *)(s), c, n) +#endif #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_ASCII diff --git a/Objects/stringlib/undef.h b/Objects/stringlib/undef.h index c41e254fde6..cc873a2ec4e 100644 --- a/Objects/stringlib/undef.h +++ b/Objects/stringlib/undef.h @@ -1,10 +1,11 @@ -#undef FASTSEARCH -#undef STRINGLIB -#undef STRINGLIB_SIZEOF_CHAR -#undef STRINGLIB_MAX_CHAR -#undef STRINGLIB_CHAR -#undef STRINGLIB_STR -#undef STRINGLIB_LEN -#undef STRINGLIB_NEW +#undef FASTSEARCH +#undef STRINGLIB +#undef STRINGLIB_SIZEOF_CHAR +#undef STRINGLIB_MAX_CHAR +#undef STRINGLIB_CHAR +#undef STRINGLIB_STR +#undef STRINGLIB_LEN +#undef STRINGLIB_NEW #undef STRINGLIB_IS_UNICODE - +#undef STRINGLIB_MUTABLE +#undef STRINGLIB_FAST_MEMCHR diff --git a/Objects/stringlib/unicode_format.h b/Objects/stringlib/unicode_format.h index a4eea7b9198..ccd7c77c0a0 100644 --- a/Objects/stringlib/unicode_format.h +++ b/Objects/stringlib/unicode_format.h @@ -473,8 +473,7 @@ get_field_object(SubString *input, PyObject *args, PyObject *kwargs, goto error; /* assign to obj */ - Py_DECREF(obj); - obj = tmp; + Py_SETREF(obj, tmp); } /* end of iterator, this is the non-error case */ if (ok == 1) @@ -825,8 +824,7 @@ output_markup(SubString *field_name, SubString *format_spec, goto done; /* do the assignment, transferring ownership: fieldobj = tmp */ - Py_DECREF(fieldobj); - fieldobj = tmp; + Py_SETREF(fieldobj, tmp); tmp = NULL; } @@ -1042,8 +1040,7 @@ formatteriter_next(formatteriterobject *it) otherwise create a one length string with the conversion character */ if (conversion == '\0') { - conversion_str = Py_None; - Py_INCREF(conversion_str); + conversion_str = Py_NewRef(Py_None); } else conversion_str = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, @@ -1121,8 +1118,7 @@ formatter_parser(PyObject *ignored, PyObject *self) return NULL; /* take ownership, give the object to the iterator */ - Py_INCREF(self); - it->str = self; + it->str = Py_NewRef(self); /* initialize the contained MarkupIterator */ MarkupIterator_init(&it->it_markup, (PyObject*)self, 0, PyUnicode_GET_LENGTH(self)); @@ -1265,8 +1261,7 @@ formatter_field_name_split(PyObject *ignored, PyObject *self) /* take ownership, give the object to the iterator. this is just to keep the field_name alive */ - Py_INCREF(self); - it->str = self; + it->str = Py_NewRef(self); /* Pass in auto_number = NULL. We'll return an empty string for first_obj in that case. */ diff --git a/Objects/stringlib/unicodedefs.h b/Objects/stringlib/unicodedefs.h deleted file mode 100644 index 5ea79cd4f50..00000000000 --- a/Objects/stringlib/unicodedefs.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef STRINGLIB_UNICODEDEFS_H -#define STRINGLIB_UNICODEDEFS_H - -/* this is sort of a hack. there's at least one place (formatting - floats) where some stringlib code takes a different path if it's - compiled as unicode. */ -#define STRINGLIB_IS_UNICODE 1 - -#define FASTSEARCH fastsearch -#define STRINGLIB(F) stringlib_##F -#define STRINGLIB_OBJECT PyUnicodeObject -#define STRINGLIB_SIZEOF_CHAR Py_UNICODE_SIZE -#define STRINGLIB_CHAR Py_UNICODE -#define STRINGLIB_TYPE_NAME "unicode" -#define STRINGLIB_PARSE_CODE "U" -#define STRINGLIB_ISSPACE Py_UNICODE_ISSPACE -#define STRINGLIB_ISLINEBREAK BLOOM_LINEBREAK -#define STRINGLIB_ISDECIMAL Py_UNICODE_ISDECIMAL -#define STRINGLIB_TODECIMAL Py_UNICODE_TODECIMAL -#define STRINGLIB_STR PyUnicode_AS_UNICODE -#define STRINGLIB_LEN PyUnicode_GET_SIZE -#define STRINGLIB_NEW PyUnicode_FromUnicode -#define STRINGLIB_CHECK PyUnicode_Check -#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact - -#define STRINGLIB_TOSTR PyObject_Str -#define STRINGLIB_TOASCII PyObject_ASCII - -#define STRINGLIB_WANT_CONTAINS_OBJ 1 - -#endif /* !STRINGLIB_UNICODEDEFS_H */ diff --git a/Objects/structseq.c b/Objects/structseq.c index 73795b677b4..100ccfef0a2 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -12,6 +12,7 @@ #include "pycore_object.h" // _PyObject_GC_TRACK() #include "structmember.h" // PyMemberDef #include "pycore_structseq.h" // PyStructSequence_InitType() +#include "pycore_initconfig.h" // _PyStatus_OK() static const char visible_length_key[] = "n_sequence_fields"; static const char real_length_key[] = "n_fields"; @@ -22,17 +23,9 @@ static const char match_args_key[] = "__match_args__"; They are only allowed for indices < n_visible_fields. */ const char * const PyStructSequence_UnnamedField = "unnamed field"; -_Py_IDENTIFIER(n_sequence_fields); -_Py_IDENTIFIER(n_fields); -_Py_IDENTIFIER(n_unnamed_fields); - static Py_ssize_t -get_type_attr_as_size(PyTypeObject *tp, _Py_Identifier *id) +get_type_attr_as_size(PyTypeObject *tp, PyObject *name) { - PyObject *name = _PyUnicode_FromId(id); - if (name == NULL) { - return -1; - } PyObject *v = PyDict_GetItemWithError(tp->tp_dict, name); if (v == NULL && !PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, @@ -43,11 +36,14 @@ get_type_attr_as_size(PyTypeObject *tp, _Py_Identifier *id) } #define VISIBLE_SIZE(op) Py_SIZE(op) -#define VISIBLE_SIZE_TP(tp) get_type_attr_as_size(tp, &PyId_n_sequence_fields) -#define REAL_SIZE_TP(tp) get_type_attr_as_size(tp, &PyId_n_fields) +#define VISIBLE_SIZE_TP(tp) \ + get_type_attr_as_size(tp, &_Py_ID(n_sequence_fields)) +#define REAL_SIZE_TP(tp) \ + get_type_attr_as_size(tp, &_Py_ID(n_fields)) #define REAL_SIZE(op) REAL_SIZE_TP(Py_TYPE(op)) -#define UNNAMED_FIELDS_TP(tp) get_type_attr_as_size(tp, &PyId_n_unnamed_fields) +#define UNNAMED_FIELDS_TP(tp) \ + get_type_attr_as_size(tp, &_Py_ID(n_unnamed_fields)) #define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP(Py_TYPE(op)) @@ -107,10 +103,9 @@ static void structseq_dealloc(PyStructSequence *obj) { Py_ssize_t i, size; - PyTypeObject *tp; PyObject_GC_UnTrack(obj); - tp = (PyTypeObject *) Py_TYPE(obj); + PyTypeObject *tp = Py_TYPE(obj); size = REAL_SIZE(obj); for (i = 0; i < size; ++i) { Py_XDECREF(obj->ob_item[i]); @@ -205,8 +200,7 @@ structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict) } for (i = 0; i < len; ++i) { PyObject *v = PySequence_Fast_GET_ITEM(arg, i); - Py_INCREF(v); - res->ob_item[i] = v; + res->ob_item[i] = Py_NewRef(v); } Py_DECREF(arg); for (; i < max_len; ++i) { @@ -224,8 +218,7 @@ structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict) ob = Py_None; } } - Py_INCREF(ob); - res->ob_item[i] = ob; + res->ob_item[i] = Py_NewRef(ob); } _PyObject_GC_TRACK(res); @@ -437,11 +430,21 @@ error: return -1; } -static void -initialize_members(PyStructSequence_Desc *desc, PyMemberDef* members, - Py_ssize_t n_members) { - Py_ssize_t i, k; +static PyMemberDef * +initialize_members(PyStructSequence_Desc *desc, + Py_ssize_t *pn_members, Py_ssize_t *pn_unnamed_members) +{ + PyMemberDef *members; + Py_ssize_t n_members, n_unnamed_members; + n_members = count_members(desc, &n_unnamed_members); + members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1); + if (members == NULL) { + PyErr_NoMemory(); + return NULL; + } + + Py_ssize_t i, k; for (i = k = 0; i < n_members; ++i) { if (desc->fields[i].name == PyStructSequence_UnnamedField) { continue; @@ -458,12 +461,78 @@ initialize_members(PyStructSequence_Desc *desc, PyMemberDef* members, k++; } members[k].name = NULL; + + *pn_members = n_members; + *pn_unnamed_members = n_unnamed_members; + return members; } +static void +initialize_static_fields(PyTypeObject *type, PyStructSequence_Desc *desc, + PyMemberDef *tp_members, unsigned long tp_flags) +{ + type->tp_name = desc->name; + type->tp_basicsize = sizeof(PyStructSequence) - sizeof(PyObject *); + type->tp_itemsize = sizeof(PyObject *); + type->tp_dealloc = (destructor)structseq_dealloc; + type->tp_repr = (reprfunc)structseq_repr; + type->tp_doc = desc->doc; + type->tp_base = &PyTuple_Type; + type->tp_methods = structseq_methods; + type->tp_new = structseq_new; + type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | tp_flags; + type->tp_traverse = (traverseproc) structseq_traverse; + type->tp_members = tp_members; +} + +static int +initialize_static_type(PyTypeObject *type, PyStructSequence_Desc *desc, + Py_ssize_t n_members, Py_ssize_t n_unnamed_members) { + /* initialize_static_fields() should have been called already. */ + if (PyType_Ready(type) < 0) { + return -1; + } + Py_INCREF(type); + + if (initialize_structseq_dict( + desc, type->tp_dict, n_members, n_unnamed_members) < 0) { + Py_DECREF(type); + return -1; + } + + return 0; +} + int -_PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc, - unsigned long tp_flags) +_PyStructSequence_InitBuiltinWithFlags(PyTypeObject *type, + PyStructSequence_Desc *desc, + unsigned long tp_flags) +{ + PyMemberDef *members; + Py_ssize_t n_members, n_unnamed_members; + + members = initialize_members(desc, &n_members, &n_unnamed_members); + if (members == NULL) { + return -1; + } + initialize_static_fields(type, desc, members, tp_flags); + if (_PyStaticType_InitBuiltin(type) < 0) { + PyMem_Free(members); + PyErr_Format(PyExc_RuntimeError, + "Can't initialize builtin type %s", + desc->name); + return -1; + } + if (initialize_static_type(type, desc, n_members, n_unnamed_members) < 0) { + PyMem_Free(members); + return -1; + } + return 0; +} + +int +PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) { PyMemberDef *members; Py_ssize_t n_members, n_unnamed_members; @@ -482,57 +551,59 @@ _PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc, return -1; } - type->tp_name = desc->name; - type->tp_basicsize = sizeof(PyStructSequence) - sizeof(PyObject *); - type->tp_itemsize = sizeof(PyObject *); - type->tp_dealloc = (destructor)structseq_dealloc; - type->tp_repr = (reprfunc)structseq_repr; - type->tp_doc = desc->doc; - type->tp_base = &PyTuple_Type; - type->tp_methods = structseq_methods; - type->tp_new = structseq_new; - type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | tp_flags; - type->tp_traverse = (traverseproc) structseq_traverse; - - n_members = count_members(desc, &n_unnamed_members); - members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1); + members = initialize_members(desc, &n_members, &n_unnamed_members); if (members == NULL) { - PyErr_NoMemory(); return -1; } - initialize_members(desc, members, n_members); - type->tp_members = members; - - if (PyType_Ready(type) < 0) { + initialize_static_fields(type, desc, members, 0); + if (initialize_static_type(type, desc, n_members, n_unnamed_members) < 0) { PyMem_Free(members); return -1; } - Py_INCREF(type); - - if (initialize_structseq_dict( - desc, type->tp_dict, n_members, n_unnamed_members) < 0) { - PyMem_Free(members); - Py_DECREF(type); - return -1; - } - return 0; } -int -PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) -{ - return _PyStructSequence_InitType(type, desc, 0); -} - void PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) { (void)PyStructSequence_InitType2(type, desc); } + +void +_PyStructSequence_FiniType(PyTypeObject *type) +{ + // Ensure that the type is initialized + assert(type->tp_name != NULL); + assert(type->tp_base == &PyTuple_Type); + + // Cannot delete a type if it still has subclasses + if (_PyType_HasSubclasses(type)) { + return; + } + + // Undo PyStructSequence_NewType() + type->tp_name = NULL; + PyMem_Free(type->tp_members); + + _PyStaticType_Dealloc(type); + assert(Py_REFCNT(type) == 1); + // Undo Py_INCREF(type) of _PyStructSequence_InitType(). + // Don't use Py_DECREF(): static type must not be deallocated + Py_SET_REFCNT(type, 0); +#ifdef Py_REF_DEBUG + _Py_RefTotal--; +#endif + + // Make sure that _PyStructSequence_InitType() will initialize + // the type again + assert(Py_REFCNT(type) == 0); + assert(type->tp_name == NULL); +} + + PyTypeObject * -PyStructSequence_NewType(PyStructSequence_Desc *desc) +_PyStructSequence_NewType(PyStructSequence_Desc *desc, unsigned long tp_flags) { PyMemberDef *members; PyTypeObject *type; @@ -541,13 +612,10 @@ PyStructSequence_NewType(PyStructSequence_Desc *desc) Py_ssize_t n_members, n_unnamed_members; /* Initialize MemberDefs */ - n_members = count_members(desc, &n_unnamed_members); - members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1); + members = initialize_members(desc, &n_members, &n_unnamed_members); if (members == NULL) { - PyErr_NoMemory(); return NULL; } - initialize_members(desc, members, n_members); /* Initialize Slots */ slots[0] = (PyType_Slot){Py_tp_dealloc, (destructor)structseq_dealloc}; @@ -565,7 +633,7 @@ PyStructSequence_NewType(PyStructSequence_Desc *desc) spec.name = desc->name; spec.basicsize = sizeof(PyStructSequence) - sizeof(PyObject *); spec.itemsize = sizeof(PyObject *); - spec.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC; + spec.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | tp_flags; spec.slots = slots; type = (PyTypeObject *)PyType_FromSpecWithBases(&spec, (PyObject *)&PyTuple_Type); @@ -583,13 +651,9 @@ PyStructSequence_NewType(PyStructSequence_Desc *desc) return type; } -int _PyStructSequence_Init(void) + +PyTypeObject * +PyStructSequence_NewType(PyStructSequence_Desc *desc) { - if (_PyUnicode_FromId(&PyId_n_sequence_fields) == NULL - || _PyUnicode_FromId(&PyId_n_fields) == NULL - || _PyUnicode_FromId(&PyId_n_unnamed_fields) == NULL) - { - return -1; - } - return 0; + return _PyStructSequence_NewType(desc, 0); } diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index e9d1b5926ab..e1b9953226c 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -5,8 +5,7 @@ #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() #include "pycore_initconfig.h" // _PyStatus_OK() -#include "pycore_object.h" // _PyObject_GC_TRACK() -#include "pycore_pyerrors.h" // _Py_FatalRefcountError() +#include "pycore_object.h" // _PyObject_GC_TRACK(), _Py_FatalRefcountError() /*[clinic input] class tuple "PyTupleObject *" "&PyTuple_Type" @@ -16,32 +15,10 @@ class tuple "PyTupleObject *" "&PyTuple_Type" #include "clinic/tupleobject.c.h" -#if PyTuple_MAXSAVESIZE > 0 -static struct _Py_tuple_state * -get_tuple_state(void) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - return &interp->tuple; -} -#endif +static inline PyTupleObject * maybe_freelist_pop(Py_ssize_t); +static inline int maybe_freelist_push(PyTupleObject *); -/* Print summary info about the state of the optimized allocator */ -void -_PyTuple_DebugMallocStats(FILE *out) -{ -#if PyTuple_MAXSAVESIZE > 0 - struct _Py_tuple_state *state = get_tuple_state(); - for (int i = 1; i < PyTuple_MAXSAVESIZE; i++) { - char buf[128]; - PyOS_snprintf(buf, sizeof(buf), - "free %d-sized PyTupleObject", i); - _PyDebugAllocatorStats(out, buf, state->numfree[i], - _PyObject_VAR_SIZE(&PyTuple_Type, i)); - } -#endif -} - /* Allocate an uninitialized tuple object. Before making it public, following steps must be done: @@ -55,38 +32,16 @@ _PyTuple_DebugMallocStats(FILE *out) static PyTupleObject * tuple_alloc(Py_ssize_t size) { - PyTupleObject *op; -#if PyTuple_MAXSAVESIZE > 0 - // If Python is built with the empty tuple singleton, - // tuple_alloc(0) must not be called. - assert(size != 0); -#endif if (size < 0) { PyErr_BadInternalCall(); return NULL; } - -// Check for max save size > 1. Empty tuple singleton is special case. -#if PyTuple_MAXSAVESIZE > 1 - struct _Py_tuple_state *state = get_tuple_state(); #ifdef Py_DEBUG - // tuple_alloc() must not be called after _PyTuple_Fini() - assert(state->numfree[0] != -1); + assert(size != 0); // The empty tuple is statically allocated. #endif - if (size < PyTuple_MAXSAVESIZE && (op = state->free_list[size]) != NULL) { - assert(size != 0); - state->free_list[size] = (PyTupleObject *) op->ob_item[0]; - state->numfree[size]--; - /* Inlined _PyObject_InitVar() without _PyType_HasFeature() test */ -#ifdef Py_TRACE_REFS - Py_SET_SIZE(op, size); - Py_SET_TYPE(op, &PyTuple_Type); -#endif - _Py_NewReference((PyObject *)op); - } - else -#endif - { + + PyTupleObject *op = maybe_freelist_pop(size); + if (op == NULL) { /* Check for overflow */ if ((size_t)size > ((size_t)PY_SSIZE_T_MAX - (sizeof(PyTupleObject) - sizeof(PyObject *))) / sizeof(PyObject *)) { @@ -99,58 +54,23 @@ tuple_alloc(Py_ssize_t size) return op; } -static int -tuple_create_empty_tuple_singleton(struct _Py_tuple_state *state) -{ -#if PyTuple_MAXSAVESIZE > 0 - assert(state->free_list[0] == NULL); +// The empty tuple singleton is not tracked by the GC. +// It does not contain any Python object. +// Note that tuple subclasses have their own empty instances. - PyTupleObject *op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, 0); - if (op == NULL) { - return -1; - } - // The empty tuple singleton is not tracked by the GC. - // It does not contain any Python object. - - state->free_list[0] = op; - state->numfree[0]++; - - assert(state->numfree[0] == 1); -#endif - return 0; -} - - -static PyObject * +static inline PyObject * tuple_get_empty(void) { -#if PyTuple_MAXSAVESIZE > 0 - struct _Py_tuple_state *state = get_tuple_state(); - PyTupleObject *op = state->free_list[0]; - // tuple_get_empty() must not be called before _PyTuple_Init() - // or after _PyTuple_Fini() - assert(op != NULL); -#ifdef Py_DEBUG - assert(state->numfree[0] != -1); -#endif - - Py_INCREF(op); - return (PyObject *) op; -#else - return PyTuple_New(0); -#endif + return Py_NewRef(&_Py_SINGLETON(tuple_empty)); } - PyObject * PyTuple_New(Py_ssize_t size) { PyTupleObject *op; -#if PyTuple_MAXSAVESIZE > 0 if (size == 0) { return tuple_get_empty(); } -#endif op = tuple_alloc(size); if (op == NULL) { return NULL; @@ -250,8 +170,7 @@ PyTuple_Pack(Py_ssize_t n, ...) items = result->ob_item; for (i = 0; i < n; i++) { o = va_arg(vargs, PyObject *); - Py_INCREF(o); - items[i] = o; + items[i] = Py_NewRef(o); } va_end(vargs); _PyObject_GC_TRACK(result); @@ -264,47 +183,33 @@ PyTuple_Pack(Py_ssize_t n, ...) static void tupledealloc(PyTupleObject *op) { - Py_ssize_t len = Py_SIZE(op); + if (Py_SIZE(op) == 0) { + /* The empty tuple is statically allocated. */ + if (op == &_Py_SINGLETON(tuple_empty)) { +#ifdef Py_DEBUG + _Py_FatalRefcountError("deallocating the empty tuple singleton"); +#else + return; +#endif + } +#ifdef Py_DEBUG + /* tuple subclasses have their own empty instances. */ + assert(!PyTuple_CheckExact(op)); +#endif + } + PyObject_GC_UnTrack(op); Py_TRASHCAN_BEGIN(op, tupledealloc) - if (len > 0) { - Py_ssize_t i = len; - while (--i >= 0) { - Py_XDECREF(op->ob_item[i]); - } -#if PyTuple_MAXSAVESIZE > 0 - struct _Py_tuple_state *state = get_tuple_state(); -#ifdef Py_DEBUG - // tupledealloc() must not be called after _PyTuple_Fini() - assert(state->numfree[0] != -1); -#endif - if (len < PyTuple_MAXSAVESIZE - && state->numfree[len] < PyTuple_MAXFREELIST - && Py_IS_TYPE(op, &PyTuple_Type)) - { - op->ob_item[0] = (PyObject *) state->free_list[len]; - state->numfree[len]++; - state->free_list[len] = op; - goto done; /* return */ - } -#endif - } -#if defined(Py_DEBUG) && PyTuple_MAXSAVESIZE > 0 - else { - assert(len == 0); - struct _Py_tuple_state *state = get_tuple_state(); - // The empty tuple singleton must only be deallocated by - // _PyTuple_Fini(): not before, not after - if (op == state->free_list[0] && state->numfree[0] != 0) { - _Py_FatalRefcountError("deallocating the empty tuple singleton"); - } - } -#endif - Py_TYPE(op)->tp_free((PyObject *)op); -#if PyTuple_MAXSAVESIZE > 0 -done: -#endif + Py_ssize_t i = Py_SIZE(op); + while (--i >= 0) { + Py_XDECREF(op->ob_item[i]); + } + // This will abort on the empty singleton (if there is one). + if (!maybe_freelist_push(op)) { + Py_TYPE(op)->tp_free((PyObject *)op); + } + Py_TRASHCAN_END } @@ -460,8 +365,7 @@ tupleitem(PyTupleObject *a, Py_ssize_t i) PyErr_SetString(PyExc_IndexError, "tuple index out of range"); return NULL; } - Py_INCREF(a->ob_item[i]); - return a->ob_item[i]; + return Py_NewRef(a->ob_item[i]); } PyObject * @@ -478,8 +382,7 @@ _PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) PyObject **dst = tuple->ob_item; for (Py_ssize_t i = 0; i < n; i++) { PyObject *item = src[i]; - Py_INCREF(item); - dst[i] = item; + dst[i] = Py_NewRef(item); } _PyObject_GC_TRACK(tuple); return (PyObject *)tuple; @@ -518,8 +421,7 @@ tupleslice(PyTupleObject *a, Py_ssize_t ilow, if (ihigh < ilow) ihigh = ilow; if (ilow == 0 && ihigh == Py_SIZE(a) && PyTuple_CheckExact(a)) { - Py_INCREF(a); - return (PyObject *)a; + return Py_NewRef(a); } return _PyTuple_FromArray(a->ob_item + ilow, ihigh - ilow); } @@ -542,8 +444,7 @@ tupleconcat(PyTupleObject *a, PyObject *bb) PyObject **src, **dest; PyTupleObject *np; if (Py_SIZE(a) == 0 && PyTuple_CheckExact(bb)) { - Py_INCREF(bb); - return bb; + return Py_NewRef(bb); } if (!PyTuple_Check(bb)) { PyErr_Format(PyExc_TypeError, @@ -554,8 +455,7 @@ tupleconcat(PyTupleObject *a, PyObject *bb) PyTupleObject *b = (PyTupleObject *)bb; if (Py_SIZE(b) == 0 && PyTuple_CheckExact(a)) { - Py_INCREF(a); - return (PyObject *)a; + return Py_NewRef(a); } assert((size_t)Py_SIZE(a) + (size_t)Py_SIZE(b) < PY_SSIZE_T_MAX); size = Py_SIZE(a) + Py_SIZE(b); @@ -571,15 +471,13 @@ tupleconcat(PyTupleObject *a, PyObject *bb) dest = np->ob_item; for (i = 0; i < Py_SIZE(a); i++) { PyObject *v = src[i]; - Py_INCREF(v); - dest[i] = v; + dest[i] = Py_NewRef(v); } src = b->ob_item; dest = np->ob_item + Py_SIZE(a); for (i = 0; i < Py_SIZE(b); i++) { PyObject *v = src[i]; - Py_INCREF(v); - dest[i] = v; + dest[i] = Py_NewRef(v); } _PyObject_GC_TRACK(np); return (PyObject *)np; @@ -588,36 +486,47 @@ tupleconcat(PyTupleObject *a, PyObject *bb) static PyObject * tuplerepeat(PyTupleObject *a, Py_ssize_t n) { - Py_ssize_t i, j; - Py_ssize_t size; - PyTupleObject *np; - PyObject **p, **items; - if (Py_SIZE(a) == 0 || n == 1) { + const Py_ssize_t input_size = Py_SIZE(a); + if (input_size == 0 || n == 1) { if (PyTuple_CheckExact(a)) { /* Since tuples are immutable, we can return a shared copy in this case */ - Py_INCREF(a); - return (PyObject *)a; + return Py_NewRef(a); } } - if (Py_SIZE(a) == 0 || n <= 0) { + if (input_size == 0 || n <= 0) { return tuple_get_empty(); } - if (n > PY_SSIZE_T_MAX / Py_SIZE(a)) + assert(n>0); + + if (input_size > PY_SSIZE_T_MAX / n) return PyErr_NoMemory(); - size = Py_SIZE(a) * n; - np = tuple_alloc(size); + Py_ssize_t output_size = input_size * n; + + PyTupleObject *np = tuple_alloc(output_size); if (np == NULL) return NULL; - p = np->ob_item; - items = a->ob_item; - for (i = 0; i < n; i++) { - for (j = 0; j < Py_SIZE(a); j++) { - *p = items[j]; - Py_INCREF(*p); - p++; + + PyObject **dest = np->ob_item; + if (input_size == 1) { + PyObject *elem = a->ob_item[0]; + _Py_RefcntAdd(elem, n); + PyObject **dest_end = dest + output_size; + while (dest < dest_end) { + *dest++ = elem; } } + else { + PyObject **src = a->ob_item; + PyObject **src_end = src + input_size; + while (src < src_end) { + _Py_RefcntAdd(*src, n); + *dest++ = *src++; + } + + _Py_memory_repeat((char *)np->ob_item, sizeof(PyObject *)*output_size, + sizeof(PyObject *)*input_size); + } _PyObject_GC_TRACK(np); return (PyObject *) np; } @@ -799,7 +708,7 @@ tuple_vectorcall(PyObject *type, PyObject * const*args, } if (nargs) { - return tuple_new_impl((PyTypeObject *)type, args[0]); + return tuple_new_impl(_PyType_CAST(type), args[0]); } else { return tuple_get_empty(); @@ -820,6 +729,7 @@ tuple_subtype_new(PyTypeObject *type, PyObject *iterable) if (tmp == NULL) return NULL; assert(PyTuple_Check(tmp)); + /* This may allocate an empty tuple that is not the global one. */ newobj = type->tp_alloc(type, n = PyTuple_GET_SIZE(tmp)); if (newobj == NULL) { Py_DECREF(tmp); @@ -827,8 +737,7 @@ tuple_subtype_new(PyTypeObject *type, PyObject *iterable) } for (i = 0; i < n; i++) { item = PyTuple_GET_ITEM(tmp, i); - Py_INCREF(item); - PyTuple_SET_ITEM(newobj, i, item); + PyTuple_SET_ITEM(newobj, i, Py_NewRef(item)); } Py_DECREF(tmp); @@ -879,8 +788,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item) else if (start == 0 && step == 1 && slicelength == PyTuple_GET_SIZE(self) && PyTuple_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else { PyTupleObject* result = tuple_alloc(slicelength); @@ -890,8 +798,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item) dest = result->ob_item; for (cur = start, i = 0; i < slicelength; cur += step, i++) { - it = src[cur]; - Py_INCREF(it); + it = Py_NewRef(src[cur]); dest[i] = it; } @@ -1002,14 +909,22 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) PyErr_BadInternalCall(); return -1; } - oldsize = Py_SIZE(v); - if (oldsize == newsize) - return 0; + oldsize = Py_SIZE(v); + if (oldsize == newsize) { + return 0; + } + if (newsize == 0) { + Py_DECREF(v); + *pv = tuple_get_empty(); + return 0; + } if (oldsize == 0) { - /* Empty tuples are often shared, so we should never - resize them in-place even if we do own the only - (current) reference */ +#ifdef Py_DEBUG + assert(v == &_Py_SINGLETON(tuple_empty)); +#endif + /* The empty tuple is statically allocated so we never + resize it in-place. */ Py_DECREF(v); *pv = PyTuple_New(newsize); return *pv == NULL ? -1 : 0; @@ -1045,67 +960,44 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) return 0; } -void -_PyTuple_ClearFreeList(PyInterpreterState *interp) -{ -#if PyTuple_MAXSAVESIZE > 0 - struct _Py_tuple_state *state = &interp->tuple; - for (Py_ssize_t i = 1; i < PyTuple_MAXSAVESIZE; i++) { - PyTupleObject *p = state->free_list[i]; - state->free_list[i] = NULL; - state->numfree[i] = 0; - while (p) { - PyTupleObject *q = p; - p = (PyTupleObject *)(p->ob_item[0]); - PyObject_GC_Del(q); - } - } - // the empty tuple singleton is only cleared by _PyTuple_Fini() -#endif -} - PyStatus -_PyTuple_Init(PyInterpreterState *interp) +_PyTuple_InitTypes(PyInterpreterState *interp) { - struct _Py_tuple_state *state = &interp->tuple; - if (tuple_create_empty_tuple_singleton(state) < 0) { - return _PyStatus_NO_MEMORY(); + if (!_Py_IsMainInterpreter(interp)) { + return _PyStatus_OK(); } + + if (PyType_Ready(&PyTuple_Type) < 0) { + return _PyStatus_ERR("Can't initialize tuple type"); + } + + if (PyType_Ready(&PyTupleIter_Type) < 0) { + return _PyStatus_ERR("Can't initialize tuple iterator type"); + } + return _PyStatus_OK(); } +static void maybe_freelist_clear(PyInterpreterState *, int); void _PyTuple_Fini(PyInterpreterState *interp) { -#if PyTuple_MAXSAVESIZE > 0 - struct _Py_tuple_state *state = &interp->tuple; - // The empty tuple singleton must not be tracked by the GC - assert(!_PyObject_GC_IS_TRACKED(state->free_list[0])); + maybe_freelist_clear(interp, 1); +} -#ifdef Py_DEBUG - state->numfree[0] = 0; -#endif - Py_CLEAR(state->free_list[0]); -#ifdef Py_DEBUG - state->numfree[0] = -1; -#endif - - _PyTuple_ClearFreeList(interp); -#endif +void +_PyTuple_ClearFreeList(PyInterpreterState *interp) +{ + maybe_freelist_clear(interp, 0); } /*********************** Tuple Iterator **************************/ -typedef struct { - PyObject_HEAD - Py_ssize_t it_index; - PyTupleObject *it_seq; /* Set to NULL when iterator is exhausted */ -} tupleiterobject; static void -tupleiter_dealloc(tupleiterobject *it) +tupleiter_dealloc(_PyTupleIterObject *it) { _PyObject_GC_UNTRACK(it); Py_XDECREF(it->it_seq); @@ -1113,14 +1005,14 @@ tupleiter_dealloc(tupleiterobject *it) } static int -tupleiter_traverse(tupleiterobject *it, visitproc visit, void *arg) +tupleiter_traverse(_PyTupleIterObject *it, visitproc visit, void *arg) { Py_VISIT(it->it_seq); return 0; } static PyObject * -tupleiter_next(tupleiterobject *it) +tupleiter_next(_PyTupleIterObject *it) { PyTupleObject *seq; PyObject *item; @@ -1134,8 +1026,7 @@ tupleiter_next(tupleiterobject *it) if (it->it_index < PyTuple_GET_SIZE(seq)) { item = PyTuple_GET_ITEM(seq, it->it_index); ++it->it_index; - Py_INCREF(item); - return item; + return Py_NewRef(item); } it->it_seq = NULL; @@ -1144,7 +1035,7 @@ tupleiter_next(tupleiterobject *it) } static PyObject * -tupleiter_len(tupleiterobject *it, PyObject *Py_UNUSED(ignored)) +tupleiter_len(_PyTupleIterObject *it, PyObject *Py_UNUSED(ignored)) { Py_ssize_t len = 0; if (it->it_seq) @@ -1155,18 +1046,17 @@ tupleiter_len(tupleiterobject *it, PyObject *Py_UNUSED(ignored)) PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -tupleiter_reduce(tupleiterobject *it, PyObject *Py_UNUSED(ignored)) +tupleiter_reduce(_PyTupleIterObject *it, PyObject *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(iter); if (it->it_seq) - return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter), + return Py_BuildValue("N(O)n", _PyEval_GetBuiltin(&_Py_ID(iter)), it->it_seq, it->it_index); else - return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter)); + return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter))); } static PyObject * -tupleiter_setstate(tupleiterobject *it, PyObject *state) +tupleiter_setstate(_PyTupleIterObject *it, PyObject *state) { Py_ssize_t index = PyLong_AsSsize_t(state); if (index == -1 && PyErr_Occurred()) @@ -1194,7 +1084,7 @@ static PyMethodDef tupleiter_methods[] = { PyTypeObject PyTupleIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "tuple_iterator", /* tp_name */ - sizeof(tupleiterobject), /* tp_basicsize */ + sizeof(_PyTupleIterObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)tupleiter_dealloc, /* tp_dealloc */ @@ -1227,18 +1117,129 @@ PyTypeObject PyTupleIter_Type = { static PyObject * tuple_iter(PyObject *seq) { - tupleiterobject *it; + _PyTupleIterObject *it; if (!PyTuple_Check(seq)) { PyErr_BadInternalCall(); return NULL; } - it = PyObject_GC_New(tupleiterobject, &PyTupleIter_Type); + it = PyObject_GC_New(_PyTupleIterObject, &PyTupleIter_Type); if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyTupleObject *)seq; + it->it_seq = (PyTupleObject *)Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } + + +/************* + * freelists * + *************/ + +#define STATE (interp->tuple) +#define FREELIST_FINALIZED (STATE.numfree[0] < 0) + +static inline PyTupleObject * +maybe_freelist_pop(Py_ssize_t size) +{ +#if PyTuple_NFREELISTS > 0 + PyInterpreterState *interp = _PyInterpreterState_GET(); +#ifdef Py_DEBUG + /* maybe_freelist_pop() must not be called after maybe_freelist_fini(). */ + assert(!FREELIST_FINALIZED); +#endif + if (size == 0) { + return NULL; + } + assert(size > 0); + if (size < PyTuple_MAXSAVESIZE) { + Py_ssize_t index = size - 1; + PyTupleObject *op = STATE.free_list[index]; + if (op != NULL) { + /* op is the head of a linked list, with the first item + pointing to the next node. Here we pop off the old head. */ + STATE.free_list[index] = (PyTupleObject *) op->ob_item[0]; + STATE.numfree[index]--; + /* Inlined _PyObject_InitVar() without _PyType_HasFeature() test */ +#ifdef Py_TRACE_REFS + /* maybe_freelist_push() ensures these were already set. */ + // XXX Can we drop these? See commit 68055ce6fe01 (GvR, Dec 1998). + Py_SET_SIZE(op, size); + Py_SET_TYPE(op, &PyTuple_Type); +#endif + _Py_NewReference((PyObject *)op); + /* END inlined _PyObject_InitVar() */ + OBJECT_STAT_INC(from_freelist); + return op; + } + } +#endif + return NULL; +} + +static inline int +maybe_freelist_push(PyTupleObject *op) +{ +#if PyTuple_NFREELISTS > 0 + PyInterpreterState *interp = _PyInterpreterState_GET(); +#ifdef Py_DEBUG + /* maybe_freelist_push() must not be called after maybe_freelist_fini(). */ + assert(!FREELIST_FINALIZED); +#endif + if (Py_SIZE(op) == 0) { + return 0; + } + Py_ssize_t index = Py_SIZE(op) - 1; + if (index < PyTuple_NFREELISTS + && STATE.numfree[index] < PyTuple_MAXFREELIST + && Py_IS_TYPE(op, &PyTuple_Type)) + { + /* op is the head of a linked list, with the first item + pointing to the next node. Here we set op as the new head. */ + op->ob_item[0] = (PyObject *) STATE.free_list[index]; + STATE.free_list[index] = op; + STATE.numfree[index]++; + OBJECT_STAT_INC(to_freelist); + return 1; + } +#endif + return 0; +} + +static void +maybe_freelist_clear(PyInterpreterState *interp, int fini) +{ +#if PyTuple_NFREELISTS > 0 + for (Py_ssize_t i = 0; i < PyTuple_NFREELISTS; i++) { + PyTupleObject *p = STATE.free_list[i]; + STATE.free_list[i] = NULL; + STATE.numfree[i] = fini ? -1 : 0; + while (p) { + PyTupleObject *q = p; + p = (PyTupleObject *)(p->ob_item[0]); + PyObject_GC_Del(q); + } + } +#endif +} + +/* Print summary info about the state of the optimized allocator */ +void +_PyTuple_DebugMallocStats(FILE *out) +{ +#if PyTuple_NFREELISTS > 0 + PyInterpreterState *interp = _PyInterpreterState_GET(); + for (int i = 0; i < PyTuple_NFREELISTS; i++) { + int len = i + 1; + char buf[128]; + PyOS_snprintf(buf, sizeof(buf), + "free %d-sized PyTupleObject", len); + _PyDebugAllocatorStats(out, buf, STATE.numfree[i], + _PyObject_VAR_SIZE(&PyTuple_Type, len)); + } +#endif +} + +#undef STATE +#undef FREELIST_FINALIZED diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 4180a9d13c4..59e0bf2995b 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4,14 +4,15 @@ #include "pycore_call.h" #include "pycore_code.h" // CO_FAST_FREE #include "pycore_compile.h" // _Py_Mangle() +#include "pycore_dict.h" // _PyDict_KeysSize() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_moduleobject.h" // _PyModule_GetDef() #include "pycore_object.h" // _PyType_HasFeature() #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_typeobject.h" // struct type_cache #include "pycore_unionobject.h" // _Py_union_type_or -#include "frameobject.h" // PyFrameObject -#include "pycore_frame.h" // InterpreterFrame +#include "pycore_frame.h" // _PyInterpreterFrame #include "opcode.h" // MAKE_CELL #include "structmember.h" // PyMemberDef @@ -43,9 +44,7 @@ class object "PyObject *" "&PyBaseObject_Type" PyUnicode_IS_READY(name) && \ (PyUnicode_GET_LENGTH(name) <= MCACHE_MAX_ATTR_SIZE) -// bpo-42745: next_version_tag remains shared by all interpreters because of static types -// Used to set PyTypeObject.tp_version_tag -static unsigned int next_version_tag = 1; +#define next_version_tag (_PyRuntime.types.next_version_tag) typedef struct PySlot_Offset { short subslot_offset; @@ -53,42 +52,105 @@ typedef struct PySlot_Offset { } PySlot_Offset; -/* alphabetical order */ -_Py_IDENTIFIER(__abstractmethods__); -_Py_IDENTIFIER(__annotations__); -_Py_IDENTIFIER(__class__); -_Py_IDENTIFIER(__class_getitem__); -_Py_IDENTIFIER(__classcell__); -_Py_IDENTIFIER(__delitem__); -_Py_IDENTIFIER(__dict__); -_Py_IDENTIFIER(__doc__); -_Py_IDENTIFIER(__getattribute__); -_Py_IDENTIFIER(__getitem__); -_Py_IDENTIFIER(__hash__); -_Py_IDENTIFIER(__init_subclass__); -_Py_IDENTIFIER(__len__); -_Py_IDENTIFIER(__module__); -_Py_IDENTIFIER(__name__); -_Py_IDENTIFIER(__new__); -_Py_IDENTIFIER(__qualname__); -_Py_IDENTIFIER(__set_name__); -_Py_IDENTIFIER(__setitem__); -_Py_IDENTIFIER(__weakref__); -_Py_IDENTIFIER(builtins); -_Py_IDENTIFIER(mro); - static PyObject * slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds); -static void -clear_slotdefs(void); - static PyObject * -lookup_maybe_method(PyObject *self, _Py_Identifier *attrid, int *unbound); +lookup_maybe_method(PyObject *self, PyObject *attr, int *unbound); static int slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value); +static inline PyTypeObject * subclass_from_ref(PyObject *ref); + + +/* helpers for for static builtin types */ + +#ifndef NDEBUG +static inline int +static_builtin_index_is_set(PyTypeObject *self) +{ + return self->tp_subclasses != NULL; +} +#endif + +static inline size_t +static_builtin_index_get(PyTypeObject *self) +{ + assert(static_builtin_index_is_set(self)); + /* We store a 1-based index so 0 can mean "not initialized". */ + return (size_t)self->tp_subclasses - 1; +} + +static inline void +static_builtin_index_set(PyTypeObject *self, size_t index) +{ + assert(index < _Py_MAX_STATIC_BUILTIN_TYPES); + /* We store a 1-based index so 0 can mean "not initialized". */ + self->tp_subclasses = (PyObject *)(index + 1); +} + +static inline void +static_builtin_index_clear(PyTypeObject *self) +{ + self->tp_subclasses = NULL; +} + +static inline static_builtin_state * +static_builtin_state_get(PyInterpreterState *interp, PyTypeObject *self) +{ + return &(interp->types.builtins[static_builtin_index_get(self)]); +} + +/* For static types we store some state in an array on each interpreter. */ +static_builtin_state * +_PyStaticType_GetState(PyTypeObject *self) +{ + assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); + PyInterpreterState *interp = _PyInterpreterState_GET(); + return static_builtin_state_get(interp, self); +} + +static void +static_builtin_state_init(PyTypeObject *self) +{ + /* Set the type's per-interpreter state. */ + PyInterpreterState *interp = _PyInterpreterState_GET(); + + /* It should only be called once for each builtin type. */ + assert(!static_builtin_index_is_set(self)); + + static_builtin_index_set(self, interp->types.num_builtins_initialized); + interp->types.num_builtins_initialized++; + + static_builtin_state *state = static_builtin_state_get(interp, self); + state->type = self; + /* state->tp_subclasses is left NULL until init_subclasses() sets it. */ + /* state->tp_weaklist is left NULL until insert_head() or insert_after() + (in weakrefobject.c) sets it. */ +} + +static void +static_builtin_state_clear(PyTypeObject *self) +{ + /* Reset the type's per-interpreter state. + This basically undoes what static_builtin_state_init() did. */ + PyInterpreterState *interp = _PyInterpreterState_GET(); + + static_builtin_state *state = static_builtin_state_get(interp, self); + state->type = NULL; + assert(state->tp_weaklist == NULL); // It was already cleared out. + static_builtin_index_clear(self); + + assert(interp->types.num_builtins_initialized > 0); + interp->types.num_builtins_initialized--; +} + +// Also see _PyStaticType_InitBuiltin() and _PyStaticType_Dealloc(). + +/* end static builtin helpers */ + + /* * finds the beginning of the docstring's introspection signature. * if present, returns a pointer pointing to the first '('. @@ -169,7 +231,7 @@ _PyType_CheckConsistency(PyTypeObject *type) if (type->tp_flags & Py_TPFLAGS_DISALLOW_INSTANTIATION) { CHECK(type->tp_new == NULL); - CHECK(_PyDict_ContainsId(type->tp_dict, &PyId___new__) == 0); + CHECK(PyDict_Contains(type->tp_dict, &_Py_ID(__new__)) == 0); } return 1; @@ -228,7 +290,7 @@ static struct type_cache* get_type_cache(void) { PyInterpreterState *interp = _PyInterpreterState_GET(); - return &interp->type_cache; + return &interp->types.type_cache; } @@ -247,7 +309,7 @@ type_cache_clear(struct type_cache *cache, PyObject *value) void _PyType_InitCache(PyInterpreterState *interp) { - struct type_cache *cache = &interp->type_cache; + struct type_cache *cache = &interp->types.type_cache; for (Py_ssize_t i = 0; i < (1 << MCACHE_SIZE_EXP); i++) { struct type_cache_entry *entry = &cache->hashtable[i]; assert(entry->name == NULL); @@ -264,19 +326,7 @@ _PyType_InitCache(PyInterpreterState *interp) static unsigned int _PyType_ClearCache(PyInterpreterState *interp) { - struct type_cache *cache = &interp->type_cache; -#if MCACHE_STATS - size_t total = cache->hits + cache->collisions + cache->misses; - fprintf(stderr, "-- Method cache hits = %zd (%d%%)\n", - cache->hits, (int) (100.0 * cache->hits / total)); - fprintf(stderr, "-- Method cache true misses = %zd (%d%%)\n", - cache->misses, (int) (100.0 * cache->misses / total)); - fprintf(stderr, "-- Method cache collisions = %zd (%d%%)\n", - cache->collisions, (int) (100.0 * cache->collisions / total)); - fprintf(stderr, "-- Method cache size = %zd KiB\n", - sizeof(cache->hashtable) / 1024); -#endif - + struct type_cache *cache = &interp->types.type_cache; // Set to None, rather than NULL, so _PyType_Lookup() can // use Py_SETREF() rather than using slower Py_XSETREF(). type_cache_clear(cache, Py_None); @@ -294,16 +344,98 @@ PyType_ClearCache(void) void -_PyType_Fini(PyInterpreterState *interp) +_PyTypes_Fini(PyInterpreterState *interp) { - struct type_cache *cache = &interp->type_cache; + struct type_cache *cache = &interp->types.type_cache; type_cache_clear(cache, NULL); - if (_Py_IsMainInterpreter(interp)) { - clear_slotdefs(); + + assert(interp->types.num_builtins_initialized == 0); + // All the static builtin types should have been finalized already. + for (size_t i = 0; i < _Py_MAX_STATIC_BUILTIN_TYPES; i++) { + assert(interp->types.builtins[i].type == NULL); } } +static PyObject * lookup_subclasses(PyTypeObject *); + +int +PyType_AddWatcher(PyType_WatchCallback callback) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + + for (int i = 0; i < TYPE_MAX_WATCHERS; i++) { + if (!interp->type_watchers[i]) { + interp->type_watchers[i] = callback; + return i; + } + } + + PyErr_SetString(PyExc_RuntimeError, "no more type watcher IDs available"); + return -1; +} + +static inline int +validate_watcher_id(PyInterpreterState *interp, int watcher_id) +{ + if (watcher_id < 0 || watcher_id >= TYPE_MAX_WATCHERS) { + PyErr_Format(PyExc_ValueError, "Invalid type watcher ID %d", watcher_id); + return -1; + } + if (!interp->type_watchers[watcher_id]) { + PyErr_Format(PyExc_ValueError, "No type watcher set for ID %d", watcher_id); + return -1; + } + return 0; +} + +int +PyType_ClearWatcher(int watcher_id) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id) < 0) { + return -1; + } + interp->type_watchers[watcher_id] = NULL; + return 0; +} + +static int assign_version_tag(PyTypeObject *type); + +int +PyType_Watch(int watcher_id, PyObject* obj) +{ + if (!PyType_Check(obj)) { + PyErr_SetString(PyExc_ValueError, "Cannot watch non-type"); + return -1; + } + PyTypeObject *type = (PyTypeObject *)obj; + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id) < 0) { + return -1; + } + // ensure we will get a callback on the next modification + assign_version_tag(type); + type->tp_watched |= (1 << watcher_id); + return 0; +} + +int +PyType_Unwatch(int watcher_id, PyObject* obj) +{ + if (!PyType_Check(obj)) { + PyErr_SetString(PyExc_ValueError, "Cannot watch non-type"); + return -1; + } + PyTypeObject *type = (PyTypeObject *)obj; + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id)) { + return -1; + } + type->tp_watched &= ~(1 << watcher_id); + return 0; +} + void PyType_Modified(PyTypeObject *type) { @@ -322,24 +454,43 @@ PyType_Modified(PyTypeObject *type) We don't assign new version tags eagerly, but only as needed. */ - PyObject *raw, *ref; - Py_ssize_t i; - - if (!_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) + if (!_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) { return; + } - raw = type->tp_subclasses; - if (raw != NULL) { - assert(PyDict_CheckExact(raw)); - i = 0; - while (PyDict_Next(raw, &i, NULL, &ref)) { - assert(PyWeakref_CheckRef(ref)); - ref = PyWeakref_GET_OBJECT(ref); - if (ref != Py_None) { - PyType_Modified((PyTypeObject *)ref); + PyObject *subclasses = lookup_subclasses(type); + if (subclasses != NULL) { + assert(PyDict_CheckExact(subclasses)); + + Py_ssize_t i = 0; + PyObject *ref; + while (PyDict_Next(subclasses, &i, NULL, &ref)) { + PyTypeObject *subclass = subclass_from_ref(ref); // borrowed + if (subclass == NULL) { + continue; } + PyType_Modified(subclass); } } + + // Notify registered type watchers, if any + if (type->tp_watched) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + int bits = type->tp_watched; + int i = 0; + while (bits) { + assert(i < TYPE_MAX_WATCHERS); + if (bits & 1) { + PyType_WatchCallback cb = interp->type_watchers[i]; + if (cb && (cb(type) < 0)) { + PyErr_WriteUnraisable((PyObject *)type); + } + } + i++; + bits >>= 1; + } + } + type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; type->tp_version_tag = 0; /* 0 is not a valid version tag */ } @@ -361,30 +512,31 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { Py_ssize_t i, n; int custom = !Py_IS_TYPE(type, &PyType_Type); int unbound; - PyObject *mro_meth = NULL; - PyObject *type_mro_meth = NULL; if (custom) { + PyObject *mro_meth, *type_mro_meth; mro_meth = lookup_maybe_method( - (PyObject *)type, &PyId_mro, &unbound); - if (mro_meth == NULL) + (PyObject *)type, &_Py_ID(mro), &unbound); + if (mro_meth == NULL) { goto clear; + } type_mro_meth = lookup_maybe_method( - (PyObject *)&PyType_Type, &PyId_mro, &unbound); - if (type_mro_meth == NULL) + (PyObject *)&PyType_Type, &_Py_ID(mro), &unbound); + if (type_mro_meth == NULL) { + Py_DECREF(mro_meth); goto clear; - if (mro_meth != type_mro_meth) + } + int custom_mro = (mro_meth != type_mro_meth); + Py_DECREF(mro_meth); + Py_DECREF(type_mro_meth); + if (custom_mro) { goto clear; - Py_XDECREF(mro_meth); - Py_XDECREF(type_mro_meth); + } } n = PyTuple_GET_SIZE(bases); for (i = 0; i < n; i++) { PyObject *b = PyTuple_GET_ITEM(bases, i); - PyTypeObject *cls; - - assert(PyType_Check(b)); - cls = (PyTypeObject *)b; + PyTypeObject *cls = _PyType_CAST(b); if (!PyType_IsSubtype(type, cls)) { goto clear; @@ -392,27 +544,24 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { } return; clear: - Py_XDECREF(mro_meth); - Py_XDECREF(type_mro_meth); type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; type->tp_version_tag = 0; /* 0 is not a valid version tag */ } static int -assign_version_tag(struct type_cache *cache, PyTypeObject *type) +assign_version_tag(PyTypeObject *type) { /* Ensure that the tp_version_tag is valid and set Py_TPFLAGS_VALID_VERSION_TAG. To respect the invariant, this must first be done on all super classes. Return 0 if this cannot be done, 1 if Py_TPFLAGS_VALID_VERSION_TAG. */ - Py_ssize_t i, n; - PyObject *bases; - - if (_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) + if (_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) { return 1; - if (!_PyType_HasFeature(type, Py_TPFLAGS_READY)) + } + if (!_PyType_HasFeature(type, Py_TPFLAGS_READY)) { return 0; + } if (next_version_tag == 0) { /* We have run out of version numbers */ @@ -421,12 +570,11 @@ assign_version_tag(struct type_cache *cache, PyTypeObject *type) type->tp_version_tag = next_version_tag++; assert (type->tp_version_tag != 0); - bases = type->tp_bases; - n = PyTuple_GET_SIZE(bases); - for (i = 0; i < n; i++) { + PyObject *bases = type->tp_bases; + Py_ssize_t n = PyTuple_GET_SIZE(bases); + for (Py_ssize_t i = 0; i < n; i++) { PyObject *b = PyTuple_GET_ITEM(bases, i); - assert(PyType_Check(b)); - if (!assign_version_tag(cache, (PyTypeObject *)b)) + if (!assign_version_tag(_PyType_CAST(b))) return 0; } type->tp_flags |= Py_TPFLAGS_VALID_VERSION_TAG; @@ -438,6 +586,8 @@ static PyMemberDef type_members[] = { {"__basicsize__", T_PYSSIZET, offsetof(PyTypeObject,tp_basicsize),READONLY}, {"__itemsize__", T_PYSSIZET, offsetof(PyTypeObject, tp_itemsize), READONLY}, {"__flags__", T_ULONG, offsetof(PyTypeObject, tp_flags), READONLY}, + /* Note that this value is misleading for static builtin types, + since the memory at this offset will always be NULL. */ {"__weakrefoffset__", T_PYSSIZET, offsetof(PyTypeObject, tp_weaklistoffset), READONLY}, {"__base__", T_OBJECT, offsetof(PyTypeObject, tp_base), READONLY}, @@ -491,8 +641,7 @@ type_name(PyTypeObject *type, void *context) if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { PyHeapTypeObject* et = (PyHeapTypeObject*)type; - Py_INCREF(et->ht_name); - return et->ht_name; + return Py_NewRef(et->ht_name); } else { return PyUnicode_FromString(_PyType_Name(type)); @@ -504,8 +653,7 @@ type_qualname(PyTypeObject *type, void *context) { if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { PyHeapTypeObject* et = (PyHeapTypeObject*)type; - Py_INCREF(et->ht_qualname); - return et->ht_qualname; + return Py_NewRef(et->ht_qualname); } else { return PyUnicode_FromString(_PyType_Name(type)); @@ -537,8 +685,7 @@ type_set_name(PyTypeObject *type, PyObject *value, void *context) } type->tp_name = tp_name; - Py_INCREF(value); - Py_SETREF(((PyHeapTypeObject*)type)->ht_name, value); + Py_SETREF(((PyHeapTypeObject*)type)->ht_name, Py_NewRef(value)); return 0; } @@ -558,8 +705,7 @@ type_set_qualname(PyTypeObject *type, PyObject *value, void *context) } et = (PyHeapTypeObject*)type; - Py_INCREF(value); - Py_SETREF(et->ht_qualname, value); + Py_SETREF(et->ht_qualname, Py_NewRef(value)); return 0; } @@ -569,7 +715,7 @@ type_module(PyTypeObject *type, void *context) PyObject *mod; if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { - mod = _PyDict_GetItemIdWithError(type->tp_dict, &PyId___module__); + mod = PyDict_GetItemWithError(type->tp_dict, &_Py_ID(__module__)); if (mod == NULL) { if (!PyErr_Occurred()) { PyErr_Format(PyExc_AttributeError, "__module__"); @@ -587,8 +733,7 @@ type_module(PyTypeObject *type, void *context) PyUnicode_InternInPlace(&mod); } else { - mod = _PyUnicode_FromId(&PyId_builtins); - Py_XINCREF(mod); + mod = Py_NewRef(&_Py_ID(builtins)); } } return mod; @@ -602,7 +747,7 @@ type_set_module(PyTypeObject *type, PyObject *value, void *context) PyType_Modified(type); - return _PyDict_SetItemId(type->tp_dict, &PyId___module__, value); + return PyDict_SetItem(type->tp_dict, &_Py_ID(__module__), value); } static PyObject * @@ -612,17 +757,15 @@ type_abstractmethods(PyTypeObject *type, void *context) /* type itself has an __abstractmethods__ descriptor (this). Don't return that. */ if (type != &PyType_Type) - mod = _PyDict_GetItemIdWithError(type->tp_dict, &PyId___abstractmethods__); + mod = PyDict_GetItemWithError(type->tp_dict, + &_Py_ID(__abstractmethods__)); if (!mod) { if (!PyErr_Occurred()) { - PyObject *message = _PyUnicode_FromId(&PyId___abstractmethods__); - if (message) - PyErr_SetObject(PyExc_AttributeError, message); + PyErr_SetObject(PyExc_AttributeError, &_Py_ID(__abstractmethods__)); } return NULL; } - Py_INCREF(mod); - return mod; + return Py_NewRef(mod); } static int @@ -637,15 +780,13 @@ type_set_abstractmethods(PyTypeObject *type, PyObject *value, void *context) abstract = PyObject_IsTrue(value); if (abstract < 0) return -1; - res = _PyDict_SetItemId(type->tp_dict, &PyId___abstractmethods__, value); + res = PyDict_SetItem(type->tp_dict, &_Py_ID(__abstractmethods__), value); } else { abstract = 0; - res = _PyDict_DelItemId(type->tp_dict, &PyId___abstractmethods__); + res = PyDict_DelItem(type->tp_dict, &_Py_ID(__abstractmethods__)); if (res && PyErr_ExceptionMatches(PyExc_KeyError)) { - PyObject *message = _PyUnicode_FromId(&PyId___abstractmethods__); - if (message) - PyErr_SetObject(PyExc_AttributeError, message); + PyErr_SetObject(PyExc_AttributeError, &_Py_ID(__abstractmethods__)); return -1; } } @@ -662,8 +803,7 @@ type_set_abstractmethods(PyTypeObject *type, PyObject *value, void *context) static PyObject * type_get_bases(PyTypeObject *type, void *context) { - Py_INCREF(type->tp_bases); - return type->tp_bases; + return Py_NewRef(type->tp_bases); } static PyTypeObject *best_base(PyObject *); @@ -677,7 +817,7 @@ static void remove_all_subclasses(PyTypeObject *type, PyObject *bases); static void update_all_slots(PyTypeObject *); typedef int (*update_callback)(PyTypeObject *, void *); -static int update_subclasses(PyTypeObject *type, PyObject *name, +static int update_subclasses(PyTypeObject *type, PyObject *attr_name, update_callback callback, void *data); static int recurse_down_subclasses(PyTypeObject *type, PyObject *name, update_callback callback, void *data); @@ -685,27 +825,28 @@ static int recurse_down_subclasses(PyTypeObject *type, PyObject *name, static int mro_hierarchy(PyTypeObject *type, PyObject *temp) { - int res; - PyObject *new_mro, *old_mro; - PyObject *tuple; - PyObject *subclasses; - Py_ssize_t i, n; - - res = mro_internal(type, &old_mro); - if (res <= 0) + PyObject *old_mro; + int res = mro_internal(type, &old_mro); + if (res <= 0) { /* error / reentrance */ return res; - new_mro = type->tp_mro; + } + PyObject *new_mro = type->tp_mro; - if (old_mro != NULL) + PyObject *tuple; + if (old_mro != NULL) { tuple = PyTuple_Pack(3, type, new_mro, old_mro); - else + } + else { tuple = PyTuple_Pack(2, type, new_mro); + } - if (tuple != NULL) + if (tuple != NULL) { res = PyList_Append(temp, tuple); - else + } + else { res = -1; + } Py_XDECREF(tuple); if (res < 0) { @@ -715,28 +856,33 @@ mro_hierarchy(PyTypeObject *type, PyObject *temp) } Py_XDECREF(old_mro); - /* Obtain a copy of subclasses list to iterate over. + // Avoid creating an empty list if there is no subclass + if (_PyType_HasSubclasses(type)) { + /* Obtain a copy of subclasses list to iterate over. - Otherwise type->tp_subclasses might be altered - in the middle of the loop, for example, through a custom mro(), - by invoking type_set_bases on some subclass of the type - which in turn calls remove_subclass/add_subclass on this type. + Otherwise type->tp_subclasses might be altered + in the middle of the loop, for example, through a custom mro(), + by invoking type_set_bases on some subclass of the type + which in turn calls remove_subclass/add_subclass on this type. - Finally, this makes things simple avoiding the need to deal - with dictionary iterators and weak references. - */ - subclasses = type___subclasses___impl(type); - if (subclasses == NULL) - return -1; - n = PyList_GET_SIZE(subclasses); - for (i = 0; i < n; i++) { - PyTypeObject *subclass; - subclass = (PyTypeObject *)PyList_GET_ITEM(subclasses, i); - res = mro_hierarchy(subclass, temp); - if (res < 0) - break; + Finally, this makes things simple avoiding the need to deal + with dictionary iterators and weak references. + */ + PyObject *subclasses = _PyType_GetSubclasses(type); + if (subclasses == NULL) { + return -1; + } + + Py_ssize_t n = PyList_GET_SIZE(subclasses); + for (Py_ssize_t i = 0; i < n; i++) { + PyTypeObject *subclass = _PyType_CAST(PyList_GET_ITEM(subclasses, i)); + res = mro_hierarchy(subclass, temp); + if (res < 0) { + break; + } + } + Py_DECREF(subclasses); } - Py_DECREF(subclasses); return res; } @@ -744,14 +890,12 @@ mro_hierarchy(PyTypeObject *type, PyObject *temp) static int type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) { - int res = 0; - PyObject *temp; - PyObject *old_bases; - PyTypeObject *new_base, *old_base; - Py_ssize_t i; - - if (!check_set_special_type_attr(type, new_bases, "__bases__")) + // Check arguments + if (!check_set_special_type_attr(type, new_bases, "__bases__")) { return -1; + } + assert(new_bases != NULL); + if (!PyTuple_Check(new_bases)) { PyErr_Format(PyExc_TypeError, "can only assign tuple to %s.__bases__, not %s", @@ -764,19 +908,17 @@ type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) type->tp_name); return -1; } - for (i = 0; i < PyTuple_GET_SIZE(new_bases); i++) { - PyObject *ob; - PyTypeObject *base; - - ob = PyTuple_GET_ITEM(new_bases, i); + Py_ssize_t n = PyTuple_GET_SIZE(new_bases); + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *ob = PyTuple_GET_ITEM(new_bases, i); if (!PyType_Check(ob)) { PyErr_Format(PyExc_TypeError, "%s.__bases__ must be tuple of classes, not '%s'", type->tp_name, Py_TYPE(ob)->tp_name); return -1; } + PyTypeObject *base = (PyTypeObject*)ob; - base = (PyTypeObject*)ob; if (PyType_IsSubtype(base, type) || /* In case of reentering here again through a custom mro() the above check is not enough since it relies on @@ -787,39 +929,42 @@ type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) below), which in turn may cause an inheritance cycle through tp_base chain. And this is definitely not what you want to ever happen. */ - (base->tp_mro != NULL && type_is_subtype_base_chain(base, type))) { - + (base->tp_mro != NULL && type_is_subtype_base_chain(base, type))) + { PyErr_SetString(PyExc_TypeError, "a __bases__ item causes an inheritance cycle"); return -1; } } - new_base = best_base(new_bases); + // Compute the new MRO and the new base class + PyTypeObject *new_base = best_base(new_bases); if (new_base == NULL) return -1; - if (!compatible_for_assignment(type->tp_base, new_base, "__bases__")) + if (!compatible_for_assignment(type->tp_base, new_base, "__bases__")) { return -1; + } - Py_INCREF(new_bases); - Py_INCREF(new_base); + PyObject *old_bases = type->tp_bases; + assert(old_bases != NULL); + PyTypeObject *old_base = type->tp_base; - old_bases = type->tp_bases; - old_base = type->tp_base; + type->tp_bases = Py_NewRef(new_bases); + type->tp_base = (PyTypeObject *)Py_NewRef(new_base); - type->tp_bases = new_bases; - type->tp_base = new_base; - - temp = PyList_New(0); - if (temp == NULL) + PyObject *temp = PyList_New(0); + if (temp == NULL) { goto bail; - if (mro_hierarchy(type, temp) < 0) + } + if (mro_hierarchy(type, temp) < 0) { goto undo; + } Py_DECREF(temp); /* Take no action in case if type->tp_bases has been replaced through reentrance. */ + int res; if (type->tp_bases == new_bases) { /* any base that was in __bases__ but now isn't, we need to remove |type| from its tp_subclasses. @@ -832,6 +977,9 @@ type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) res = add_all_subclasses(type, new_bases); update_all_slots(type); } + else { + res = 0; + } Py_DECREF(old_bases); Py_DECREF(old_base); @@ -840,7 +988,8 @@ type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) return res; undo: - for (i = PyList_GET_SIZE(temp) - 1; i >= 0; i--) { + n = PyList_GET_SIZE(temp); + for (Py_ssize_t i = n - 1; i >= 0; i--) { PyTypeObject *cls; PyObject *new_mro, *old_mro = NULL; @@ -848,8 +997,7 @@ type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) "", 2, 3, &cls, &new_mro, &old_mro); /* Do not rollback if cls has a newer version of MRO. */ if (cls->tp_mro == new_mro) { - Py_XINCREF(old_mro); - cls->tp_mro = old_mro; + cls->tp_mro = Py_XNewRef(old_mro); Py_DECREF(new_mro); } } @@ -890,11 +1038,10 @@ type_get_doc(PyTypeObject *type, void *context) if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) { return _PyType_GetDocFromInternalDoc(type->tp_name, type->tp_doc); } - result = _PyDict_GetItemIdWithError(type->tp_dict, &PyId___doc__); + result = PyDict_GetItemWithError(type->tp_dict, &_Py_ID(__doc__)); if (result == NULL) { if (!PyErr_Occurred()) { - result = Py_None; - Py_INCREF(result); + result = Py_NewRef(Py_None); } } else if (Py_TYPE(result)->tp_descr_get) { @@ -919,7 +1066,7 @@ type_set_doc(PyTypeObject *type, PyObject *value, void *context) if (!check_set_special_type_attr(type, value, "__doc__")) return -1; PyType_Modified(type); - return _PyDict_SetItemId(type->tp_dict, &PyId___doc__, value); + return PyDict_SetItem(type->tp_dict, &_Py_ID(__doc__), value); } static PyObject * @@ -932,17 +1079,18 @@ type_get_annotations(PyTypeObject *type, void *context) PyObject *annotations; /* there's no _PyDict_GetItemId without WithError, so let's LBYL. */ - if (_PyDict_ContainsId(type->tp_dict, &PyId___annotations__)) { - annotations = _PyDict_GetItemIdWithError(type->tp_dict, &PyId___annotations__); + if (PyDict_Contains(type->tp_dict, &_Py_ID(__annotations__))) { + annotations = PyDict_GetItemWithError( + type->tp_dict, &_Py_ID(__annotations__)); /* - ** _PyDict_GetItemIdWithError could still fail, + ** PyDict_GetItemWithError could still fail, ** for instance with a well-timed Ctrl-C or a MemoryError. ** so let's be totally safe. */ if (annotations) { if (Py_TYPE(annotations)->tp_descr_get) { - annotations = Py_TYPE(annotations)->tp_descr_get(annotations, NULL, - (PyObject *)type); + annotations = Py_TYPE(annotations)->tp_descr_get( + annotations, NULL, (PyObject *)type); } else { Py_INCREF(annotations); } @@ -950,7 +1098,8 @@ type_get_annotations(PyTypeObject *type, void *context) } else { annotations = PyDict_New(); if (annotations) { - int result = _PyDict_SetItemId(type->tp_dict, &PyId___annotations__, annotations); + int result = PyDict_SetItem( + type->tp_dict, &_Py_ID(__annotations__), annotations); if (result) { Py_CLEAR(annotations); } else { @@ -974,14 +1123,14 @@ type_set_annotations(PyTypeObject *type, PyObject *value, void *context) int result; if (value != NULL) { /* set */ - result = _PyDict_SetItemId(type->tp_dict, &PyId___annotations__, value); + result = PyDict_SetItem(type->tp_dict, &_Py_ID(__annotations__), value); } else { /* delete */ - if (!_PyDict_ContainsId(type->tp_dict, &PyId___annotations__)) { + if (!PyDict_Contains(type->tp_dict, &_Py_ID(__annotations__))) { PyErr_Format(PyExc_AttributeError, "__annotations__"); return -1; } - result = _PyDict_DelItemId(type->tp_dict, &PyId___annotations__); + result = PyDict_DelItem(type->tp_dict, &_Py_ID(__annotations__)); } if (result == 0) { @@ -1053,8 +1202,7 @@ type_repr(PyTypeObject *type) if (mod == NULL) PyErr_Clear(); else if (!PyUnicode_Check(mod)) { - Py_DECREF(mod); - mod = NULL; + Py_SETREF(mod, NULL); } name = type_qualname(type, NULL); if (name == NULL) { @@ -1062,7 +1210,7 @@ type_repr(PyTypeObject *type) return NULL; } - if (mod != NULL && !_PyUnicode_EqualToASCIIId(mod, &PyId_builtins)) + if (mod != NULL && !_PyUnicode_Equal(mod, &_Py_ID(builtins))) rtn = PyUnicode_FromFormat("", mod, name); else rtn = PyUnicode_FromFormat("", type->tp_name); @@ -1094,8 +1242,7 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) if (nargs == 1 && (kwds == NULL || !PyDict_GET_SIZE(kwds))) { obj = (PyObject *) Py_TYPE(PyTuple_GET_ITEM(args, 0)); - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } /* SF bug 475327 -- if that didn't trigger, we need 3 @@ -1129,8 +1276,7 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) int res = type->tp_init(obj, args, kwds); if (res < 0) { assert(_PyErr_Occurred(tstate)); - Py_DECREF(obj); - obj = NULL; + Py_SETREF(obj, NULL); } else { assert(!_PyErr_Occurred(tstate)); @@ -1143,20 +1289,25 @@ PyObject * _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems) { PyObject *obj; + /* The +1 on nitems is needed for most types but not all. We could save a + * bit of space by allocating one less item in certain cases, depending on + * the type. However, given the extra complexity (e.g. an additional type + * flag to indicate when that is safe) it does not seem worth the memory + * savings. An example type that doesn't need the +1 is a subclass of + * tuple. See GH-100659 and GH-81381. */ const size_t size = _PyObject_VAR_SIZE(type, nitems+1); - /* note that we need to add one, for the sentinel */ - if (_PyType_IS_GC(type)) { - obj = _PyObject_GC_Malloc(size); - } - else { - obj = (PyObject *)PyObject_Malloc(size); - } - - if (obj == NULL) { + const size_t presize = _PyType_PreHeaderSize(type); + char *alloc = PyObject_Malloc(size + presize); + if (alloc == NULL) { return PyErr_NoMemory(); } - + obj = (PyObject *)(alloc + presize); + if (presize) { + ((PyObject **)alloc)[0] = NULL; + ((PyObject **)alloc)[1] = NULL; + _PyObject_GC_Link(obj); + } memset(obj, '\0', size); if (type->tp_itemsize == 0) { @@ -1197,7 +1348,7 @@ traverse_slots(PyTypeObject *type, PyObject *self, visitproc visit, void *arg) PyMemberDef *mp; n = Py_SIZE(type); - mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); + mp = _PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (i = 0; i < n; i++, mp++) { if (mp->type == T_OBJECT_EX) { char *addr = (char *)self + mp->offset; @@ -1232,18 +1383,21 @@ subtype_traverse(PyObject *self, visitproc visit, void *arg) assert(base); } - if (type->tp_inline_values_offset) { - assert(type->tp_dictoffset); - int err = _PyObject_VisitInstanceAttributes(self, visit, arg); - if (err) { - return err; - } - } - if (type->tp_dictoffset != base->tp_dictoffset) { - PyObject **dictptr = _PyObject_DictPointer(self); - if (dictptr && *dictptr) - Py_VISIT(*dictptr); + assert(base->tp_dictoffset == 0); + if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + assert(type->tp_dictoffset == -1); + int err = _PyObject_VisitManagedDict(self, visit, arg); + if (err) { + return err; + } + } + else { + PyObject **dictptr = _PyObject_ComputedDictPointer(self); + if (dictptr && *dictptr) { + Py_VISIT(*dictptr); + } + } } if (type->tp_flags & Py_TPFLAGS_HEAPTYPE @@ -1269,7 +1423,7 @@ clear_slots(PyTypeObject *type, PyObject *self) PyMemberDef *mp; n = Py_SIZE(type); - mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); + mp = _PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (i = 0; i < n; i++, mp++) { if (mp->type == T_OBJECT_EX && !(mp->flags & READONLY)) { char *addr = (char *)self + mp->offset; @@ -1301,11 +1455,13 @@ subtype_clear(PyObject *self) /* Clear the instance dict (if any), to break cycles involving only __dict__ slots (as in the case 'self.__dict__ is self'). */ - if (type->tp_inline_values_offset) { - _PyObject_ClearInstanceAttributes(self); + if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + if ((base->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { + _PyObject_ClearManagedDict(self); + } } - if (type->tp_dictoffset != base->tp_dictoffset) { - PyObject **dictptr = _PyObject_DictPointer(self); + else if (type->tp_dictoffset != base->tp_dictoffset) { + PyObject **dictptr = _PyObject_ComputedDictPointer(self); if (dictptr && *dictptr) Py_CLEAR(*dictptr); } @@ -1360,6 +1516,8 @@ subtype_dealloc(PyObject *self) int type_needs_decref = (type->tp_flags & Py_TPFLAGS_HEAPTYPE && !(base->tp_flags & Py_TPFLAGS_HEAPTYPE)); + assert((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); + /* Call the base tp_dealloc() */ assert(basedealloc); basedealloc(self); @@ -1409,8 +1567,9 @@ subtype_dealloc(PyObject *self) and if self is tracked at that point, it will look like trash to GC and GC will try to delete self again. */ - if (type->tp_weaklistoffset && !base->tp_weaklistoffset) + if (type->tp_weaklistoffset && !base->tp_weaklistoffset) { PyObject_ClearWeakRefs(self); + } if (type->tp_del) { _PyObject_GC_TRACK(self); @@ -1427,11 +1586,15 @@ subtype_dealloc(PyObject *self) finalizers since they might rely on part of the object being finalized that has already been destroyed. */ if (type->tp_weaklistoffset && !base->tp_weaklistoffset) { - /* Modeled after GET_WEAKREFS_LISTPTR() */ - PyWeakReference **list = (PyWeakReference **) \ - _PyObject_GET_WEAKREFS_LISTPTR(self); - while (*list) + /* Modeled after GET_WEAKREFS_LISTPTR(). + + This is never triggered for static types so we can avoid the + (slightly) more costly _PyObject_GET_WEAKREFS_LISTPTR(). */ + PyWeakReference **list = \ + _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(self); + while (*list) { _PyWeakref_ClearRef(*list); + } } } @@ -1445,11 +1608,18 @@ subtype_dealloc(PyObject *self) } /* If we added a dict, DECREF it, or free inline values. */ - if (type->tp_inline_values_offset) { - _PyObject_FreeInstanceAttributes(self); + if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(self); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + _PyObject_FreeInstanceAttributes(self); + } + else { + Py_XDECREF(_PyDictOrValues_GetDict(*dorv_ptr)); + } + dorv_ptr->values = NULL; } - if (type->tp_dictoffset && !base->tp_dictoffset) { - PyObject **dictptr = _PyObject_DictPointer(self); + else if (type->tp_dictoffset && !base->tp_dictoffset) { + PyObject **dictptr = _PyObject_ComputedDictPointer(self); if (dictptr != NULL) { PyObject *dict = *dictptr; if (dict != NULL) { @@ -1581,11 +1751,11 @@ PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b) */ PyObject * -_PyObject_LookupSpecial(PyObject *self, _Py_Identifier *attrid) +_PyObject_LookupSpecial(PyObject *self, PyObject *attr) { PyObject *res; - res = _PyType_LookupId(Py_TYPE(self), attrid); + res = _PyType_Lookup(Py_TYPE(self), attr); if (res != NULL) { descrgetfunc f; if ((f = Py_TYPE(res)->tp_descr_get) == NULL) @@ -1596,10 +1766,19 @@ _PyObject_LookupSpecial(PyObject *self, _Py_Identifier *attrid) return res; } -static PyObject * -lookup_maybe_method(PyObject *self, _Py_Identifier *attrid, int *unbound) +PyObject * +_PyObject_LookupSpecialId(PyObject *self, _Py_Identifier *attrid) { - PyObject *res = _PyType_LookupId(Py_TYPE(self), attrid); + PyObject *attr = _PyUnicode_FromId(attrid); /* borrowed */ + if (attr == NULL) + return NULL; + return _PyObject_LookupSpecial(self, attr); +} + +static PyObject * +lookup_maybe_method(PyObject *self, PyObject *attr, int *unbound) +{ + PyObject *res = _PyType_Lookup(Py_TYPE(self), attr); if (res == NULL) { return NULL; } @@ -1623,11 +1802,11 @@ lookup_maybe_method(PyObject *self, _Py_Identifier *attrid, int *unbound) } static PyObject * -lookup_method(PyObject *self, _Py_Identifier *attrid, int *unbound) +lookup_method(PyObject *self, PyObject *attr, int *unbound) { - PyObject *res = lookup_maybe_method(self, attrid, unbound); + PyObject *res = lookup_maybe_method(self, attr, unbound); if (res == NULL && !PyErr_Occurred()) { - PyErr_SetObject(PyExc_AttributeError, _PyUnicode_FromId(attrid)); + PyErr_SetObject(PyExc_AttributeError, attr); } return res; } @@ -1644,6 +1823,7 @@ vectorcall_unbound(PyThreadState *tstate, int unbound, PyObject *func, args++; nargsf = nargsf - 1 + PY_VECTORCALL_ARGUMENTS_OFFSET; } + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_SLOT, func); return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL); } @@ -1664,8 +1844,7 @@ call_unbound_noarg(int unbound, PyObject *func, PyObject *self) args is an argument vector of length nargs. The first element in this vector is the special object "self" which is used for the method lookup */ static PyObject * -vectorcall_method(_Py_Identifier *name, - PyObject *const *args, Py_ssize_t nargs) +vectorcall_method(PyObject *name, PyObject *const *args, Py_ssize_t nargs) { assert(nargs >= 1); @@ -1684,7 +1863,7 @@ vectorcall_method(_Py_Identifier *name, /* Clone of vectorcall_method() that returns NotImplemented * when the lookup fails. */ static PyObject * -vectorcall_maybe(PyThreadState *tstate, _Py_Identifier *name, +vectorcall_maybe(PyThreadState *tstate, PyObject *name, PyObject *const *args, Py_ssize_t nargs) { assert(nargs >= 1); @@ -1747,7 +1926,7 @@ static PyObject * class_name(PyObject *cls) { PyObject *name; - if (_PyObject_LookupAttrId(cls, &PyId___name__, &name) == 0) { + if (_PyObject_LookupAttr(cls, &_Py_ID(__name__), &name) == 0) { name = PyObject_Repr(cls); } return name; @@ -1917,21 +2096,15 @@ pmerge(PyObject *acc, PyObject **to_merge, Py_ssize_t to_merge_size) static PyObject * mro_implementation(PyTypeObject *type) { - PyObject *result; - PyObject *bases; - PyObject **to_merge; - Py_ssize_t i, n; - if (!_PyType_IsReady(type)) { if (PyType_Ready(type) < 0) return NULL; } - bases = type->tp_bases; - assert(PyTuple_Check(bases)); - n = PyTuple_GET_SIZE(bases); - for (i = 0; i < n; i++) { - PyTypeObject *base = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); + PyObject *bases = type->tp_bases; + Py_ssize_t n = PyTuple_GET_SIZE(bases); + for (Py_ssize_t i = 0; i < n; i++) { + PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(bases, i)); if (base->tp_mro == NULL) { PyErr_Format(PyExc_TypeError, "Cannot extend an incomplete type '%.100s'", @@ -1945,18 +2118,18 @@ mro_implementation(PyTypeObject *type) /* Fast path: if there is a single base, constructing the MRO * is trivial. */ - PyTypeObject *base = (PyTypeObject *)PyTuple_GET_ITEM(bases, 0); + PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(bases, 0)); Py_ssize_t k = PyTuple_GET_SIZE(base->tp_mro); - result = PyTuple_New(k + 1); + PyObject *result = PyTuple_New(k + 1); if (result == NULL) { return NULL; } - Py_INCREF(type); - PyTuple_SET_ITEM(result, 0, (PyObject *) type); - for (i = 0; i < k; i++) { + + ; + PyTuple_SET_ITEM(result, 0, Py_NewRef(type)); + for (Py_ssize_t i = 0; i < k; i++) { PyObject *cls = PyTuple_GET_ITEM(base->tp_mro, i); - Py_INCREF(cls); - PyTuple_SET_ITEM(result, i + 1, cls); + PyTuple_SET_ITEM(result, i + 1, Py_NewRef(cls)); } return result; } @@ -1974,32 +2147,30 @@ mro_implementation(PyTypeObject *type) linearization implied by a base class. The last element of to_merge is the declared tuple of bases. */ - - to_merge = PyMem_New(PyObject *, n + 1); + PyObject **to_merge = PyMem_New(PyObject *, n + 1); if (to_merge == NULL) { PyErr_NoMemory(); return NULL; } - for (i = 0; i < n; i++) { - PyTypeObject *base = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); + for (Py_ssize_t i = 0; i < n; i++) { + PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(bases, i)); to_merge[i] = base->tp_mro; } to_merge[n] = bases; - result = PyList_New(1); + PyObject *result = PyList_New(1); if (result == NULL) { PyMem_Free(to_merge); return NULL; } - Py_INCREF(type); - PyList_SET_ITEM(result, 0, (PyObject *)type); + PyList_SET_ITEM(result, 0, Py_NewRef(type)); if (pmerge(result, to_merge, n + 1) < 0) { Py_CLEAR(result); } - PyMem_Free(to_merge); + return result; } @@ -2031,19 +2202,16 @@ mro_check(PyTypeObject *type, PyObject *mro) n = PyTuple_GET_SIZE(mro); for (i = 0; i < n; i++) { - PyTypeObject *base; - PyObject *tmp; - - tmp = PyTuple_GET_ITEM(mro, i); - if (!PyType_Check(tmp)) { + PyObject *obj = PyTuple_GET_ITEM(mro, i); + if (!PyType_Check(obj)) { PyErr_Format( PyExc_TypeError, "mro() returned a non-class ('%.500s')", - Py_TYPE(tmp)->tp_name); + Py_TYPE(obj)->tp_name); return -1; } + PyTypeObject *base = (PyTypeObject*)obj; - base = (PyTypeObject*)tmp; if (!PyType_IsSubtype(solid, solid_base(base))) { PyErr_Format( PyExc_TypeError, @@ -2079,8 +2247,8 @@ mro_invoke(PyTypeObject *type) if (custom) { int unbound; - PyObject *mro_meth = lookup_method((PyObject *)type, &PyId_mro, - &unbound); + PyObject *mro_meth = lookup_method( + (PyObject *)type, &_Py_ID(mro), &unbound); if (mro_meth == NULL) return NULL; mro_result = call_unbound_noarg(unbound, mro_meth, (PyObject *)type); @@ -2142,8 +2310,7 @@ mro_internal(PyTypeObject *type, PyObject **p_old_mro) /* Keep a reference to be able to do a reentrancy check below. Don't let old_mro be GC'ed and its address be reused for another object, like (suddenly!) a new tp_mro. */ - old_mro = type->tp_mro; - Py_XINCREF(old_mro); + old_mro = Py_XNewRef(type->tp_mro); new_mro = mro_invoke(type); /* might cause reentrance */ reent = (type->tp_mro != old_mro); Py_XDECREF(old_mro); @@ -2180,8 +2347,7 @@ static PyTypeObject * best_base(PyObject *bases) { Py_ssize_t i, n; - PyTypeObject *base, *winner, *candidate, *base_i; - PyObject *base_proto; + PyTypeObject *base, *winner, *candidate; assert(PyTuple_Check(bases)); n = PyTuple_GET_SIZE(bases); @@ -2189,14 +2355,15 @@ best_base(PyObject *bases) base = NULL; winner = NULL; for (i = 0; i < n; i++) { - base_proto = PyTuple_GET_ITEM(bases, i); + PyObject *base_proto = PyTuple_GET_ITEM(bases, i); if (!PyType_Check(base_proto)) { PyErr_SetString( PyExc_TypeError, "bases must be types"); return NULL; } - base_i = (PyTypeObject *)base_proto; + PyTypeObject *base_i = (PyTypeObject *)base_proto; + if (!_PyType_IsReady(base_i)) { if (PyType_Ready(base_i) < 0) return NULL; @@ -2232,30 +2399,12 @@ best_base(PyObject *bases) } static int -extra_ivars(PyTypeObject *type, PyTypeObject *base) +shape_differs(PyTypeObject *t1, PyTypeObject *t2) { - size_t t_size = type->tp_basicsize; - size_t b_size = base->tp_basicsize; - - assert(t_size >= b_size); /* Else type smaller than base! */ - if (type->tp_itemsize || base->tp_itemsize) { - /* If itemsize is involved, stricter rules */ - return t_size != b_size || - type->tp_itemsize != base->tp_itemsize; - } - if (type->tp_inline_values_offset && base->tp_inline_values_offset == 0 && - type->tp_inline_values_offset + sizeof(PyDictValues *) == t_size && - type->tp_flags & Py_TPFLAGS_HEAPTYPE) - t_size -= sizeof(PyDictValues *); - if (type->tp_weaklistoffset && base->tp_weaklistoffset == 0 && - type->tp_weaklistoffset + sizeof(PyObject *) == t_size && - type->tp_flags & Py_TPFLAGS_HEAPTYPE) - t_size -= sizeof(PyObject *); - if (type->tp_dictoffset && base->tp_dictoffset == 0 && - type->tp_dictoffset + sizeof(PyObject *) == t_size && - type->tp_flags & Py_TPFLAGS_HEAPTYPE) - t_size -= sizeof(PyObject *); - return t_size != b_size; + return ( + t1->tp_basicsize != t2->tp_basicsize || + t1->tp_itemsize != t2->tp_itemsize + ); } static PyTypeObject * @@ -2263,14 +2412,18 @@ solid_base(PyTypeObject *type) { PyTypeObject *base; - if (type->tp_base) + if (type->tp_base) { base = solid_base(type->tp_base); - else + } + else { base = &PyBaseObject_Type; - if (extra_ivars(type, base)) + } + if (shape_differs(type, base)) { return type; - else + } + else { return base; + } } static void object_dealloc(PyObject *); @@ -2303,7 +2456,7 @@ get_dict_descriptor(PyTypeObject *type) { PyObject *descr; - descr = _PyType_LookupId(type, &PyId___dict__); + descr = _PyType_Lookup(type, &_Py_ID(__dict__)); if (descr == NULL || !PyDescr_IsData(descr)) return NULL; @@ -2375,8 +2528,7 @@ subtype_setdict(PyObject *obj, PyObject *value, void *context) "not a '%.200s'", Py_TYPE(value)->tp_name); return -1; } - Py_XINCREF(value); - Py_XSETREF(*dictptr, value); + Py_XSETREF(*dictptr, Py_XNewRef(value)); return 0; } @@ -2393,17 +2545,17 @@ subtype_getweakref(PyObject *obj, void *context) return NULL; } _PyObject_ASSERT((PyObject *)type, - type->tp_weaklistoffset > 0); + type->tp_weaklistoffset > 0 || + type->tp_weaklistoffset == MANAGED_WEAKREF_OFFSET); _PyObject_ASSERT((PyObject *)type, - ((type->tp_weaklistoffset + sizeof(PyObject *)) - <= (size_t)(type->tp_basicsize))); + ((type->tp_weaklistoffset + (Py_ssize_t)sizeof(PyObject *)) + <= type->tp_basicsize)); weaklistptr = (PyObject **)((char *)obj + type->tp_weaklistoffset); if (*weaklistptr == NULL) result = Py_None; else result = *weaklistptr; - Py_INCREF(result); - return result; + return Py_NewRef(result); } /* Three variants on the subtype_getsets list. */ @@ -2467,12 +2619,21 @@ type_init(PyObject *cls, PyObject *args, PyObject *kwds) return 0; } + unsigned long PyType_GetFlags(PyTypeObject *type) { return type->tp_flags; } + +int +PyType_SUPPORTS_WEAKREFS(PyTypeObject *type) +{ + return _PyType_SUPPORTS_WEAKREFS(type); +} + + /* Determine the most derived metatype. */ PyTypeObject * _PyType_CalculateMetaclass(PyTypeObject *metatype, PyObject *bases) @@ -2543,7 +2704,7 @@ type_new_visit_slots(type_new_ctx *ctx) return -1; } assert(PyUnicode_Check(name)); - if (_PyUnicode_EqualToASCIIId(name, &PyId___dict__)) { + if (_PyUnicode_Equal(name, &_Py_ID(__dict__))) { if (!ctx->may_add_dict || ctx->add_dict != 0) { PyErr_SetString(PyExc_TypeError, "__dict__ slot disallowed: " @@ -2552,12 +2713,11 @@ type_new_visit_slots(type_new_ctx *ctx) } ctx->add_dict++; } - if (_PyUnicode_EqualToASCIIId(name, &PyId___weakref__)) { + if (_PyUnicode_Equal(name, &_Py_ID(__weakref__))) { if (!ctx->may_add_weak || ctx->add_weak != 0) { PyErr_SetString(PyExc_TypeError, "__weakref__ slot disallowed: " - "either we already got one, " - "or __itemsize__ != 0"); + "we already got one"); return -1; } ctx->add_weak++; @@ -2586,10 +2746,8 @@ type_new_copy_slots(type_new_ctx *ctx, PyObject *dict) Py_ssize_t j = 0; for (Py_ssize_t i = 0; i < nslot; i++) { PyObject *slot = PyTuple_GET_ITEM(slots, i); - if ((ctx->add_dict && - _PyUnicode_EqualToASCIIId(slot, &PyId___dict__)) || - (ctx->add_weak && - _PyUnicode_EqualToASCIIString(slot, "__weakref__"))) + if ((ctx->add_dict && _PyUnicode_Equal(slot, &_Py_ID(__dict__))) || + (ctx->add_weak && _PyUnicode_Equal(slot, &_Py_ID(__weakref__)))) { continue; } @@ -2608,8 +2766,8 @@ type_new_copy_slots(type_new_ctx *ctx, PyObject *dict) /* CPython inserts __qualname__ and __classcell__ (when needed) into the namespace when creating a class. They will be deleted below so won't act as class variables. */ - if (!_PyUnicode_EqualToASCIIId(slot, &PyId___qualname__) && - !_PyUnicode_EqualToASCIIId(slot, &PyId___classcell__)) + if (!_PyUnicode_Equal(slot, &_Py_ID(__qualname__)) && + !_PyUnicode_Equal(slot, &_Py_ID(__classcell__))) { PyErr_Format(PyExc_ValueError, "%R in __slots__ conflicts with class variable", @@ -2650,21 +2808,20 @@ type_new_slots_bases(type_new_ctx *ctx) (ctx->may_add_weak && ctx->add_weak == 0))) { for (Py_ssize_t i = 0; i < nbases; i++) { - PyObject *base = PyTuple_GET_ITEM(ctx->bases, i); - if (base == (PyObject *)ctx->base) { + PyObject *obj = PyTuple_GET_ITEM(ctx->bases, i); + if (obj == (PyObject *)ctx->base) { /* Skip primary base */ continue; } + PyTypeObject *base = _PyType_CAST(obj); - assert(PyType_Check(base)); - PyTypeObject *type = (PyTypeObject *)base; if (ctx->may_add_dict && ctx->add_dict == 0 && - type->tp_dictoffset != 0) + base->tp_dictoffset != 0) { ctx->add_dict++; } if (ctx->may_add_weak && ctx->add_weak == 0 && - type->tp_weaklistoffset != 0) + base->tp_weaklistoffset != 0) { ctx->add_weak++; } @@ -2805,7 +2962,7 @@ type_new_set_name(const type_new_ctx *ctx, PyTypeObject *type) static int type_new_set_module(PyTypeObject *type) { - int r = _PyDict_ContainsId(type->tp_dict, &PyId___module__); + int r = PyDict_Contains(type->tp_dict, &_Py_ID(__module__)); if (r < 0) { return -1; } @@ -2818,7 +2975,7 @@ type_new_set_module(PyTypeObject *type) return 0; } - PyObject *module = _PyDict_GetItemIdWithError(globals, &PyId___name__); + PyObject *module = PyDict_GetItemWithError(globals, &_Py_ID(__name__)); if (module == NULL) { if (PyErr_Occurred()) { return -1; @@ -2826,7 +2983,7 @@ type_new_set_module(PyTypeObject *type) return 0; } - if (_PyDict_SetItemId(type->tp_dict, &PyId___module__, module) < 0) { + if (PyDict_SetItem(type->tp_dict, &_Py_ID(__module__), module) < 0) { return -1; } return 0; @@ -2839,8 +2996,8 @@ static int type_new_set_ht_name(PyTypeObject *type) { PyHeapTypeObject *et = (PyHeapTypeObject *)type; - PyObject *qualname = _PyDict_GetItemIdWithError(type->tp_dict, - &PyId___qualname__); + PyObject *qualname = PyDict_GetItemWithError( + type->tp_dict, &_Py_ID(__qualname__)); if (qualname != NULL) { if (!PyUnicode_Check(qualname)) { PyErr_Format(PyExc_TypeError, @@ -2849,7 +3006,7 @@ type_new_set_ht_name(PyTypeObject *type) return -1; } et->ht_qualname = Py_NewRef(qualname); - if (_PyDict_DelItemId(type->tp_dict, &PyId___qualname__) < 0) { + if (PyDict_DelItem(type->tp_dict, &_Py_ID(__qualname__)) < 0) { return -1; } } @@ -2869,7 +3026,7 @@ type_new_set_ht_name(PyTypeObject *type) static int type_new_set_doc(PyTypeObject *type) { - PyObject *doc = _PyDict_GetItemIdWithError(type->tp_dict, &PyId___doc__); + PyObject *doc = PyDict_GetItemWithError(type->tp_dict, &_Py_ID(__doc__)); if (doc == NULL) { if (PyErr_Occurred()) { return -1; @@ -2902,9 +3059,9 @@ type_new_set_doc(PyTypeObject *type) static int -type_new_staticmethod(PyTypeObject *type, _Py_Identifier *attr_id) +type_new_staticmethod(PyTypeObject *type, PyObject *attr) { - PyObject *func = _PyDict_GetItemIdWithError(type->tp_dict, attr_id); + PyObject *func = PyDict_GetItemWithError(type->tp_dict, attr); if (func == NULL) { if (PyErr_Occurred()) { return -1; @@ -2919,7 +3076,7 @@ type_new_staticmethod(PyTypeObject *type, _Py_Identifier *attr_id) if (static_func == NULL) { return -1; } - if (_PyDict_SetItemId(type->tp_dict, attr_id, static_func) < 0) { + if (PyDict_SetItem(type->tp_dict, attr, static_func) < 0) { Py_DECREF(static_func); return -1; } @@ -2929,9 +3086,9 @@ type_new_staticmethod(PyTypeObject *type, _Py_Identifier *attr_id) static int -type_new_classmethod(PyTypeObject *type, _Py_Identifier *attr_id) +type_new_classmethod(PyTypeObject *type, PyObject *attr) { - PyObject *func = _PyDict_GetItemIdWithError(type->tp_dict, attr_id); + PyObject *func = PyDict_GetItemWithError(type->tp_dict, attr); if (func == NULL) { if (PyErr_Occurred()) { return -1; @@ -2947,7 +3104,7 @@ type_new_classmethod(PyTypeObject *type, _Py_Identifier *attr_id) return -1; } - if (_PyDict_SetItemId(type->tp_dict, attr_id, method) < 0) { + if (PyDict_SetItem(type->tp_dict, attr, method) < 0) { Py_DECREF(method); return -1; } @@ -2963,7 +3120,7 @@ type_new_descriptors(const type_new_ctx *ctx, PyTypeObject *type) PyHeapTypeObject *et = (PyHeapTypeObject *)type; Py_ssize_t slotoffset = ctx->base->tp_basicsize; if (et->ht_slots != NULL) { - PyMemberDef *mp = PyHeapType_GET_MEMBERS(et); + PyMemberDef *mp = _PyHeapType_GET_MEMBERS(et); Py_ssize_t nslot = PyTuple_GET_SIZE(et->ht_slots); for (Py_ssize_t i = 0; i < nslot; i++, mp++) { mp->name = PyUnicode_AsUTF8( @@ -2982,32 +3139,20 @@ type_new_descriptors(const type_new_ctx *ctx, PyTypeObject *type) } } - if (ctx->add_dict) { - if (ctx->base->tp_itemsize) { - type->tp_dictoffset = -(long)sizeof(PyObject *); - } - else { - type->tp_dictoffset = slotoffset; - } - slotoffset += sizeof(PyObject *); - } - if (ctx->add_weak) { - assert(!ctx->base->tp_itemsize); - type->tp_weaklistoffset = slotoffset; - slotoffset += sizeof(PyObject *); + assert((type->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF) == 0); + type->tp_flags |= Py_TPFLAGS_MANAGED_WEAKREF; + type->tp_weaklistoffset = MANAGED_WEAKREF_OFFSET; } - if (type->tp_dictoffset > 0) { - type->tp_inline_values_offset = slotoffset; - slotoffset += sizeof(PyDictValues *); - } - else { - type->tp_inline_values_offset = 0; + if (ctx->add_dict) { + assert((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); + type->tp_flags |= Py_TPFLAGS_MANAGED_DICT; + type->tp_dictoffset = -1; } type->tp_basicsize = slotoffset; type->tp_itemsize = ctx->base->tp_itemsize; - type->tp_members = PyHeapType_GET_MEMBERS(et); + type->tp_members = _PyHeapType_GET_MEMBERS(et); return 0; } @@ -3045,8 +3190,8 @@ type_new_set_slots(const type_new_ctx *ctx, PyTypeObject *type) static int type_new_set_classcell(PyTypeObject *type) { - PyObject *cell = _PyDict_GetItemIdWithError(type->tp_dict, - &PyId___classcell__); + PyObject *cell = PyDict_GetItemWithError( + type->tp_dict, &_Py_ID(__classcell__)); if (cell == NULL) { if (PyErr_Occurred()) { return -1; @@ -3063,7 +3208,7 @@ type_new_set_classcell(PyTypeObject *type) } (void)PyCell_Set(cell, (PyObject *) type); - if (_PyDict_DelItemId(type->tp_dict, &PyId___classcell__) < 0) { + if (PyDict_DelItem(type->tp_dict, &_Py_ID(__classcell__)) < 0) { return -1; } return 0; @@ -3091,16 +3236,16 @@ type_new_set_attrs(const type_new_ctx *ctx, PyTypeObject *type) /* Special-case __new__: if it's a plain function, make it a static function */ - if (type_new_staticmethod(type, &PyId___new__) < 0) { + if (type_new_staticmethod(type, &_Py_ID(__new__)) < 0) { return -1; } /* Special-case __init_subclass__ and __class_getitem__: if they are plain functions, make them classmethods */ - if (type_new_classmethod(type, &PyId___init_subclass__) < 0) { + if (type_new_classmethod(type, &_Py_ID(__init_subclass__)) < 0) { return -1; } - if (type_new_classmethod(type, &PyId___class_getitem__) < 0) { + if (type_new_classmethod(type, &_Py_ID(__class_getitem__)) < 0) { return -1; } @@ -3120,8 +3265,7 @@ type_new_set_attrs(const type_new_ctx *ctx, PyTypeObject *type) static int type_new_get_slots(type_new_ctx *ctx, PyObject *dict) { - _Py_IDENTIFIER(__slots__); - PyObject *slots = _PyDict_GetItemIdWithError(dict, &PyId___slots__); + PyObject *slots = PyDict_GetItemWithError(dict, &_Py_ID(__slots__)); if (slots == NULL) { if (PyErr_Occurred()) { return -1; @@ -3206,12 +3350,6 @@ type_new_impl(type_new_ctx *ctx) // Put the proper slots in place fixup_slot_dispatchers(type); - if (type->tp_inline_values_offset) { - assert(type->tp_dictoffset > 0); - PyHeapTypeObject *et = (PyHeapTypeObject*)type; - et->ht_cached_keys = _PyDict_NewKeysForClass(); - } - if (type_new_set_names(type) < 0) { goto error; } @@ -3245,15 +3383,14 @@ type_new_get_bases(type_new_ctx *ctx, PyObject **type) return 0; } - _Py_IDENTIFIER(__mro_entries__); for (Py_ssize_t i = 0; i < nbases; i++) { PyObject *base = PyTuple_GET_ITEM(ctx->bases, i); if (PyType_Check(base)) { continue; } PyObject *mro_entries; - if (_PyObject_LookupAttrId(base, &PyId___mro_entries__, - &mro_entries) < 0) { + if (_PyObject_LookupAttr(base, &_Py_ID(__mro_entries__), + &mro_entries) < 0) { return -1; } if (mro_entries != NULL) { @@ -3378,29 +3515,125 @@ static const PySlot_Offset pyslot_offsets[] = { #include "typeslots.inc" }; -PyObject * -PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) +/* Given a PyType_FromMetaclass `bases` argument (NULL, type, or tuple of + * types), return a tuple of types. + */ +inline static PyObject * +get_bases_tuple(PyObject *bases_in, PyType_Spec *spec) { - return PyType_FromModuleAndSpec(NULL, spec, bases); + if (!bases_in) { + /* Default: look in the spec, fall back to (type,). */ + PyTypeObject *base = &PyBaseObject_Type; // borrowed ref + PyObject *bases = NULL; // borrowed ref + const PyType_Slot *slot; + for (slot = spec->slots; slot->slot; slot++) { + switch (slot->slot) { + case Py_tp_base: + base = slot->pfunc; + break; + case Py_tp_bases: + bases = slot->pfunc; + break; + } + } + if (!bases) { + return PyTuple_Pack(1, base); + } + if (PyTuple_Check(bases)) { + return Py_NewRef(bases); + } + PyErr_SetString(PyExc_SystemError, "Py_tp_bases is not a tuple"); + return NULL; + } + if (PyTuple_Check(bases_in)) { + return Py_NewRef(bases_in); + } + // Not a tuple, should be a single type + return PyTuple_Pack(1, bases_in); +} + +static inline int +check_basicsize_includes_size_and_offsets(PyTypeObject* type) +{ + if (type->tp_alloc != PyType_GenericAlloc) { + // Custom allocators can ignore tp_basicsize + return 1; + } + Py_ssize_t max = (Py_ssize_t)type->tp_basicsize; + + if (type->tp_base && type->tp_base->tp_basicsize > type->tp_basicsize) { + PyErr_Format(PyExc_TypeError, + "tp_basicsize for type '%s' (%d) is too small for base '%s' (%d)", + type->tp_name, type->tp_basicsize, + type->tp_base->tp_name, type->tp_base->tp_basicsize); + return 0; + } + if (type->tp_weaklistoffset + (Py_ssize_t)sizeof(PyObject*) > max) { + PyErr_Format(PyExc_TypeError, + "weaklist offset %d is out of bounds for type '%s' (tp_basicsize = %d)", + type->tp_weaklistoffset, + type->tp_name, type->tp_basicsize); + return 0; + } + if (type->tp_dictoffset + (Py_ssize_t)sizeof(PyObject*) > max) { + PyErr_Format(PyExc_TypeError, + "dict offset %d is out of bounds for type '%s' (tp_basicsize = %d)", + type->tp_dictoffset, + type->tp_name, type->tp_basicsize); + return 0; + } + if (type->tp_vectorcall_offset + (Py_ssize_t)sizeof(vectorcallfunc*) > max) { + PyErr_Format(PyExc_TypeError, + "vectorcall offset %d is out of bounds for type '%s' (tp_basicsize = %d)", + type->tp_vectorcall_offset, + type->tp_name, type->tp_basicsize); + return 0; + } + return 1; } PyObject * -PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) +PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, + PyType_Spec *spec, PyObject *bases_in) { - PyHeapTypeObject *res; - PyObject *modname; - PyTypeObject *type, *base; + /* Invariant: A non-NULL value in one of these means this function holds + * a strong reference or owns allocated memory. + * These get decrefed/freed/returned at the end, on both success and error. + */ + PyHeapTypeObject *res = NULL; + PyTypeObject *type; + PyObject *bases = NULL; + char *tp_doc = NULL; + PyObject *ht_name = NULL; + char *_ht_tpname = NULL; + int r; + /* Prepare slots that need special handling. + * Keep in mind that a slot can be given multiple times: + * if that would cause trouble (leaks, UB, ...), raise an exception. + */ + const PyType_Slot *slot; - Py_ssize_t nmembers, weaklistoffset, dictoffset, vectorcalloffset; + Py_ssize_t nmembers = 0; + Py_ssize_t weaklistoffset, dictoffset, vectorcalloffset; char *res_start; - short slot_offset, subslot_offset; nmembers = weaklistoffset = dictoffset = vectorcalloffset = 0; for (slot = spec->slots; slot->slot; slot++) { - if (slot->slot == Py_tp_members) { - nmembers = 0; + if (slot->slot < 0 + || (size_t)slot->slot >= Py_ARRAY_LENGTH(pyslot_offsets)) { + PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); + goto finally; + } + switch (slot->slot) { + case Py_tp_members: + if (nmembers != 0) { + PyErr_SetString( + PyExc_SystemError, + "Multiple Py_tp_members slots are not supported."); + goto finally; + } for (const PyMemberDef *memb = slot->pfunc; memb->name != NULL; memb++) { nmembers++; if (strcmp(memb->name, "__weaklistoffset__") == 0) { @@ -3422,25 +3655,41 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) vectorcalloffset = memb->offset; } } + break; + case Py_tp_doc: + /* For the docstring slot, which usually points to a static string + literal, we need to make a copy */ + if (tp_doc != NULL) { + PyErr_SetString( + PyExc_SystemError, + "Multiple Py_tp_doc slots are not supported."); + goto finally; + } + if (slot->pfunc == NULL) { + PyObject_Free(tp_doc); + tp_doc = NULL; + } + else { + size_t len = strlen(slot->pfunc)+1; + tp_doc = PyObject_Malloc(len); + if (tp_doc == NULL) { + PyErr_NoMemory(); + goto finally; + } + memcpy(tp_doc, slot->pfunc, len); + } + break; } } - res = (PyHeapTypeObject*)PyType_GenericAlloc(&PyType_Type, nmembers); - if (res == NULL) - return NULL; - res_start = (char*)res; + /* Prepare the type name and qualname */ if (spec->name == NULL) { PyErr_SetString(PyExc_SystemError, "Type spec does not define the name field."); - goto fail; + goto finally; } - type = &res->ht_type; - /* The flags must be initialized early, before the GC traverses us */ - type->tp_flags = spec->flags | Py_TPFLAGS_HEAPTYPE; - - /* Set the type name and qualname */ const char *s = strrchr(spec->name, '.'); if (s == NULL) { s = spec->name; @@ -3449,11 +3698,10 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) s++; } - res->ht_name = PyUnicode_FromString(s); - if (!res->ht_name) { - goto fail; + ht_name = PyUnicode_FromString(s); + if (!ht_name) { + goto finally; } - res->ht_qualname = Py_NewRef(res->ht_name); /* Copy spec->name to a buffer we own. * @@ -3465,119 +3713,158 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) * deallocated with the type (if it's non-NULL). */ Py_ssize_t name_buf_len = strlen(spec->name) + 1; - res->_ht_tpname = PyMem_Malloc(name_buf_len); - if (res->_ht_tpname == NULL) { - goto fail; + _ht_tpname = PyMem_Malloc(name_buf_len); + if (_ht_tpname == NULL) { + goto finally; } - type->tp_name = memcpy(res->_ht_tpname, spec->name, name_buf_len); + memcpy(_ht_tpname, spec->name, name_buf_len); - res->ht_module = Py_XNewRef(module); - - /* Adjust for empty tuple bases */ + /* Get a tuple of bases. + * bases is a strong reference (unlike bases_in). + */ + bases = get_bases_tuple(bases_in, spec); if (!bases) { - base = &PyBaseObject_Type; - /* See whether Py_tp_base(s) was specified */ - for (slot = spec->slots; slot->slot; slot++) { - if (slot->slot == Py_tp_base) - base = slot->pfunc; - else if (slot->slot == Py_tp_bases) { - bases = slot->pfunc; + goto finally; + } + + /* If this is an immutable type, check if all bases are also immutable, + * and (for now) fire a deprecation warning if not. + * (This isn't necessary for static types: those can't have heap bases, + * and only heap types can be mutable.) + */ + if (spec->flags & Py_TPFLAGS_IMMUTABLETYPE) { + for (int i=0; iname, + b->tp_name)) + { + goto finally; + } } } - if (!bases) { - bases = PyTuple_Pack(1, base); - if (!bases) - goto fail; - } - else if (!PyTuple_Check(bases)) { - PyErr_SetString(PyExc_SystemError, "Py_tp_bases is not a tuple"); - goto fail; - } - else { - Py_INCREF(bases); - } } - else if (!PyTuple_Check(bases)) { - bases = PyTuple_Pack(1, bases); - if (!bases) - goto fail; + + /* Calculate the metaclass */ + + if (!metaclass) { + metaclass = &PyType_Type; } - else { - Py_INCREF(bases); + metaclass = _PyType_CalculateMetaclass(metaclass, bases); + if (metaclass == NULL) { + goto finally; + } + if (!PyType_Check(metaclass)) { + PyErr_Format(PyExc_TypeError, + "Metaclass '%R' is not a subclass of 'type'.", + metaclass); + goto finally; + } + if (metaclass->tp_new != PyType_Type.tp_new) { + PyErr_SetString(PyExc_TypeError, + "Metaclasses with custom tp_new are not supported."); + goto finally; } /* Calculate best base, and check that all bases are type objects */ - base = best_base(bases); + PyTypeObject *base = best_base(bases); // borrowed ref if (base == NULL) { - Py_DECREF(bases); - goto fail; + goto finally; } - if (!_PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)) { - PyErr_Format(PyExc_TypeError, - "type '%.100s' is not an acceptable base type", - base->tp_name); - Py_DECREF(bases); - goto fail; + // best_base should check Py_TPFLAGS_BASETYPE & raise a proper exception, + // here we just check its work + assert(_PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)); + + /* Allocate the new type + * + * Between here and PyType_Ready, we should limit: + * - calls to Python code + * - raising exceptions + * - memory allocations + */ + + res = (PyHeapTypeObject*)metaclass->tp_alloc(metaclass, nmembers); + if (res == NULL) { + goto finally; } + res_start = (char*)res; + + type = &res->ht_type; + /* The flags must be initialized early, before the GC traverses us */ + type->tp_flags = spec->flags | Py_TPFLAGS_HEAPTYPE; + + res->ht_module = Py_XNewRef(module); /* Initialize essential fields */ + type->tp_as_async = &res->as_async; type->tp_as_number = &res->as_number; type->tp_as_sequence = &res->as_sequence; type->tp_as_mapping = &res->as_mapping; type->tp_as_buffer = &res->as_buffer; - /* Set tp_base and tp_bases */ + + /* Set slots we have prepared */ + + type->tp_base = (PyTypeObject *)Py_NewRef(base); type->tp_bases = bases; - Py_INCREF(base); - type->tp_base = base; + bases = NULL; // We give our reference to bases to the type + + type->tp_doc = tp_doc; + tp_doc = NULL; // Give ownership of the allocated memory to the type + + res->ht_qualname = Py_NewRef(ht_name); + res->ht_name = ht_name; + ht_name = NULL; // Give our reference to to the type + + type->tp_name = _ht_tpname; + res->_ht_tpname = _ht_tpname; + _ht_tpname = NULL; // Give ownership to to the type + + /* Copy the sizes */ type->tp_basicsize = spec->basicsize; type->tp_itemsize = spec->itemsize; + /* Copy all the ordinary slots */ + for (slot = spec->slots; slot->slot; slot++) { - if (slot->slot < 0 - || (size_t)slot->slot >= Py_ARRAY_LENGTH(pyslot_offsets)) { - PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); - goto fail; - } - else if (slot->slot == Py_tp_base || slot->slot == Py_tp_bases) { + switch (slot->slot) { + case Py_tp_base: + case Py_tp_bases: + case Py_tp_doc: /* Processed above */ - continue; - } - else if (slot->slot == Py_tp_doc) { - /* For the docstring slot, which usually points to a static string - literal, we need to make a copy */ - if (slot->pfunc == NULL) { - type->tp_doc = NULL; - continue; + break; + case Py_tp_members: + { + /* Move the slots to the heap type itself */ + size_t len = Py_TYPE(type)->tp_itemsize * nmembers; + memcpy(_PyHeapType_GET_MEMBERS(res), slot->pfunc, len); + type->tp_members = _PyHeapType_GET_MEMBERS(res); } - size_t len = strlen(slot->pfunc)+1; - char *tp_doc = PyObject_Malloc(len); - if (tp_doc == NULL) { - type->tp_doc = NULL; - PyErr_NoMemory(); - goto fail; - } - memcpy(tp_doc, slot->pfunc, len); - type->tp_doc = tp_doc; - } - else if (slot->slot == Py_tp_members) { - /* Move the slots to the heap type itself */ - size_t len = Py_TYPE(type)->tp_itemsize * nmembers; - memcpy(PyHeapType_GET_MEMBERS(res), slot->pfunc, len); - type->tp_members = PyHeapType_GET_MEMBERS(res); - } - else { - /* Copy other slots directly */ - PySlot_Offset slotoffsets = pyslot_offsets[slot->slot]; - slot_offset = slotoffsets.slot_offset; - if (slotoffsets.subslot_offset == -1) { - *(void**)((char*)res_start + slot_offset) = slot->pfunc; - } else { - void *parent_slot = *(void**)((char*)res_start + slot_offset); - subslot_offset = slotoffsets.subslot_offset; - *(void**)((char*)parent_slot + subslot_offset) = slot->pfunc; + break; + default: + { + /* Copy other slots directly */ + PySlot_Offset slotoffsets = pyslot_offsets[slot->slot]; + short slot_offset = slotoffsets.slot_offset; + if (slotoffsets.subslot_offset == -1) { + *(void**)((char*)res_start + slot_offset) = slot->pfunc; + } + else { + void *procs = *(void**)((char*)res_start + slot_offset); + short subslot_offset = slotoffsets.subslot_offset; + *(void**)((char*)procs + subslot_offset) = slot->pfunc; + } } + break; } } if (type->tp_dealloc == NULL) { @@ -3587,76 +3874,105 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) type->tp_dealloc = subtype_dealloc; } - if (vectorcalloffset) { - type->tp_vectorcall_offset = vectorcalloffset; + /* Set up offsets */ + + type->tp_vectorcall_offset = vectorcalloffset; + type->tp_weaklistoffset = weaklistoffset; + type->tp_dictoffset = dictoffset; + + /* Ready the type (which includes inheritance). + * + * After this call we should generally only touch up what's + * accessible to Python code, like __dict__. + */ + + if (PyType_Ready(type) < 0) { + goto finally; } - if (PyType_Ready(type) < 0) - goto fail; - - if (type->tp_inline_values_offset) { - assert(type->tp_dictoffset > 0); - res->ht_cached_keys = _PyDict_NewKeysForClass(); + if (!check_basicsize_includes_size_and_offsets(type)) { + goto finally; } if (type->tp_doc) { PyObject *__doc__ = PyUnicode_FromString(_PyType_DocWithoutSignature(type->tp_name, type->tp_doc)); - if (!__doc__) - goto fail; - r = _PyDict_SetItemId(type->tp_dict, &PyId___doc__, __doc__); + if (!__doc__) { + goto finally; + } + r = PyDict_SetItem(type->tp_dict, &_Py_ID(__doc__), __doc__); Py_DECREF(__doc__); - if (r < 0) - goto fail; + if (r < 0) { + goto finally; + } } if (weaklistoffset) { - type->tp_weaklistoffset = weaklistoffset; - if (PyDict_DelItemString((PyObject *)type->tp_dict, "__weaklistoffset__") < 0) - goto fail; + if (PyDict_DelItem((PyObject *)type->tp_dict, &_Py_ID(__weaklistoffset__)) < 0) { + goto finally; + } } if (dictoffset) { - type->tp_dictoffset = dictoffset; - if (PyDict_DelItemString((PyObject *)type->tp_dict, "__dictoffset__") < 0) - goto fail; + if (PyDict_DelItem((PyObject *)type->tp_dict, &_Py_ID(__dictoffset__)) < 0) { + goto finally; + } } /* Set type.__module__ */ - r = _PyDict_ContainsId(type->tp_dict, &PyId___module__); + r = PyDict_Contains(type->tp_dict, &_Py_ID(__module__)); if (r < 0) { - goto fail; + goto finally; } if (r == 0) { s = strrchr(spec->name, '.'); if (s != NULL) { - modname = PyUnicode_FromStringAndSize( + PyObject *modname = PyUnicode_FromStringAndSize( spec->name, (Py_ssize_t)(s - spec->name)); if (modname == NULL) { - goto fail; + goto finally; } - r = _PyDict_SetItemId(type->tp_dict, &PyId___module__, modname); + r = PyDict_SetItem(type->tp_dict, &_Py_ID(__module__), modname); Py_DECREF(modname); - if (r != 0) - goto fail; - } else { + if (r != 0) { + goto finally; + } + } + else { if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, "builtin type %.200s has no __module__ attribute", spec->name)) - goto fail; + goto finally; } } assert(_PyType_CheckConsistency(type)); - return (PyObject*)res; - fail: - Py_DECREF(res); - return NULL; + finally: + if (PyErr_Occurred()) { + Py_CLEAR(res); + } + Py_XDECREF(bases); + PyObject_Free(tp_doc); + Py_XDECREF(ht_name); + PyMem_Free(_ht_tpname); + return (PyObject*)res; +} + +PyObject * +PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) +{ + return PyType_FromMetaclass(NULL, module, spec, bases); +} + +PyObject * +PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) +{ + return PyType_FromMetaclass(NULL, NULL, spec, bases); } PyObject * PyType_FromSpec(PyType_Spec *spec) { - return PyType_FromSpecWithBases(spec, NULL); + return PyType_FromMetaclass(NULL, NULL, spec, NULL); } PyObject * @@ -3730,13 +4046,9 @@ PyType_GetModuleState(PyTypeObject *type) /* Get the module of the first superclass where the module has the * given PyModuleDef. - * Implemented by walking the MRO, is relatively slow. - * - * This is internal API for experimentation within stdlib. Discussion: - * https://mail.python.org/archives/list/capi-sig@python.org/thread/T3P2QNLNLBRFHWSKYSTPMVEIL2EEKFJU/ */ PyObject * -_PyType_GetModuleByDef(PyTypeObject *type, struct PyModuleDef *def) +PyType_GetModuleByDef(PyTypeObject *type, PyModuleDef *def) { assert(PyType_Check(type)); @@ -3748,26 +4060,24 @@ _PyType_GetModuleByDef(PyTypeObject *type, struct PyModuleDef *def) // to check i < PyTuple_GET_SIZE(mro) at the first loop iteration. assert(PyTuple_GET_SIZE(mro) >= 1); - Py_ssize_t i = 0; - do { + Py_ssize_t n = PyTuple_GET_SIZE(mro); + for (Py_ssize_t i = 0; i < n; i++) { PyObject *super = PyTuple_GET_ITEM(mro, i); - // _PyType_GetModuleByDef() must only be called on a heap type created - // by PyType_FromModuleAndSpec() or on its subclasses. - // type_ready_mro() ensures that a static type cannot inherit from a - // heap type. - assert(_PyType_HasFeature((PyTypeObject *)type, Py_TPFLAGS_HEAPTYPE)); + if(!_PyType_HasFeature((PyTypeObject *)super, Py_TPFLAGS_HEAPTYPE)) { + // Static types in the MRO need to be skipped + continue; + } PyHeapTypeObject *ht = (PyHeapTypeObject*)super; PyObject *module = ht->ht_module; if (module && _PyModule_GetDef(module) == def) { return module; } - i++; - } while (i < PyTuple_GET_SIZE(mro)); + } PyErr_Format( PyExc_TypeError, - "_PyType_GetModuleByDef: No superclass of '%s' has the given module", + "PyType_GetModuleByDef: No superclass of '%s' has the given module", type->tp_name); return NULL; } @@ -3779,12 +4089,9 @@ _PyType_GetModuleByDef(PyTypeObject *type, struct PyModuleDef *def) static PyObject * find_name_in_mro(PyTypeObject *type, PyObject *name, int *error) { - Py_ssize_t i, n; - PyObject *mro, *res, *base, *dict; Py_hash_t hash; - if (!PyUnicode_CheckExact(name) || - (hash = ((PyASCIIObject *) name)->hash) == -1) + (hash = _PyASCIIObject_CAST(name)->hash) == -1) { hash = PyObject_Hash(name); if (hash == -1) { @@ -3794,8 +4101,7 @@ find_name_in_mro(PyTypeObject *type, PyObject *name, int *error) } /* Look in tp_dict of types in MRO */ - mro = type->tp_mro; - + PyObject *mro = type->tp_mro; if (mro == NULL) { if ((type->tp_flags & Py_TPFLAGS_READYING) == 0) { if (PyType_Ready(type) < 0) { @@ -3810,20 +4116,19 @@ find_name_in_mro(PyTypeObject *type, PyObject *name, int *error) } } - res = NULL; + PyObject *res = NULL; /* Keep a strong reference to mro because type->tp_mro can be replaced during dict lookup, e.g. when comparing to non-string keys. */ Py_INCREF(mro); - assert(PyTuple_Check(mro)); - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - base = PyTuple_GET_ITEM(mro, i); - assert(PyType_Check(base)); - dict = ((PyTypeObject *)base)->tp_dict; + Py_ssize_t n = PyTuple_GET_SIZE(mro); + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *base = PyTuple_GET_ITEM(mro, i); + PyObject *dict = _PyType_CAST(base)->tp_dict; assert(dict && PyDict_Check(dict)); res = _PyDict_GetItem_KnownHash(dict, name, hash); - if (res != NULL) + if (res != NULL) { break; + } if (PyErr_Occurred()) { *error = -1; goto done; @@ -3835,6 +4140,24 @@ done: return res; } +/* Check if the "readied" PyUnicode name + is a double-underscore special name. */ +static int +is_dunder_name(PyObject *name) +{ + Py_ssize_t length = PyUnicode_GET_LENGTH(name); + int kind = PyUnicode_KIND(name); + /* Special names contain at least "__x__" and are always ASCII. */ + if (length > 4 && kind == PyUnicode_1BYTE_KIND) { + const Py_UCS1 *characters = PyUnicode_1BYTE_DATA(name); + return ( + ((characters[length-2] == '_') && (characters[length-1] == '_')) && + ((characters[0] == '_') && (characters[1] == '_')) + ); + } + return 0; +} + /* Internal API to look for a name through the MRO. This returns a borrowed reference, and doesn't set an exception! */ PyObject * @@ -3848,12 +4171,13 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name) struct type_cache_entry *entry = &cache->hashtable[h]; if (entry->version == type->tp_version_tag && entry->name == name) { -#if MCACHE_STATS - cache->hits++; -#endif assert(_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)); + OBJECT_STAT_INC_COND(type_cache_hits, !is_dunder_name(name)); + OBJECT_STAT_INC_COND(type_cache_dunder_hits, is_dunder_name(name)); return entry->value; } + OBJECT_STAT_INC_COND(type_cache_misses, !is_dunder_name(name)); + OBJECT_STAT_INC_COND(type_cache_dunder_misses, is_dunder_name(name)); /* We may end up clearing live exceptions below, so make sure it's ours. */ assert(!PyErr_Occurred()); @@ -3875,20 +4199,13 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name) return NULL; } - if (MCACHE_CACHEABLE_NAME(name) && assign_version_tag(cache, type)) { + if (MCACHE_CACHEABLE_NAME(name) && assign_version_tag(type)) { h = MCACHE_HASH_METHOD(type, name); struct type_cache_entry *entry = &cache->hashtable[h]; entry->version = type->tp_version_tag; entry->value = res; /* borrowed */ - assert(((PyASCIIObject *)(name))->hash != -1); -#if MCACHE_STATS - if (entry->name != Py_None && entry->name != name) { - cache->collisions++; - } - else { - cache->misses++; - } -#endif + assert(_PyASCIIObject_CAST(name)->hash != -1); + OBJECT_STAT_INC_COND(type_cache_collisions, entry->name != Py_None && entry->name != name); assert(_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)); Py_SETREF(entry->name, Py_NewRef(name)); } @@ -3896,7 +4213,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name) } PyObject * -_PyType_LookupId(PyTypeObject *type, struct _Py_Identifier *name) +_PyType_LookupId(PyTypeObject *type, _Py_Identifier *name) { PyObject *oname; oname = _PyUnicode_FromId(name); /* borrowed */ @@ -3905,28 +4222,20 @@ _PyType_LookupId(PyTypeObject *type, struct _Py_Identifier *name) return _PyType_Lookup(type, oname); } -/* Check if the "readied" PyUnicode name - is a double-underscore special name. */ -static int -is_dunder_name(PyObject *name) -{ - Py_ssize_t length = PyUnicode_GET_LENGTH(name); - int kind = PyUnicode_KIND(name); - /* Special names contain at least "__x__" and are always ASCII. */ - if (length > 4 && kind == PyUnicode_1BYTE_KIND) { - const Py_UCS1 *characters = PyUnicode_1BYTE_DATA(name); - return ( - ((characters[length-2] == '_') && (characters[length-1] == '_')) && - ((characters[0] == '_') && (characters[1] == '_')) - ); - } - return 0; -} - /* This is similar to PyObject_GenericGetAttr(), - but uses _PyType_Lookup() instead of just looking in type->tp_dict. */ -static PyObject * -type_getattro(PyTypeObject *type, PyObject *name) + but uses _PyType_Lookup() instead of just looking in type->tp_dict. + + The argument suppress_missing_attribute is used to provide a + fast path for hasattr. The possible values are: + + * NULL: do not suppress the exception + * Non-zero pointer: suppress the PyExc_AttributeError and + set *suppress_missing_attribute to 1 to signal we are returning NULL while + having suppressed the exception (other exceptions are not suppressed) + + */ +PyObject * +_Py_type_getattro_impl(PyTypeObject *type, PyObject *name, int * suppress_missing_attribute) { PyTypeObject *metatype = Py_TYPE(type); PyObject *meta_attribute, *attribute; @@ -4006,12 +4315,25 @@ type_getattro(PyTypeObject *type, PyObject *name) } /* Give up */ - PyErr_Format(PyExc_AttributeError, - "type object '%.50s' has no attribute '%U'", - type->tp_name, name); + if (suppress_missing_attribute == NULL) { + PyErr_Format(PyExc_AttributeError, + "type object '%.50s' has no attribute '%U'", + type->tp_name, name); + } else { + // signal the caller we have not set an PyExc_AttributeError and gave up + *suppress_missing_attribute = 1; + } return NULL; } +/* This is similar to PyObject_GenericGetAttr(), + but uses _PyType_Lookup() instead of just looking in type->tp_dict. */ +PyObject * +_Py_type_getattro(PyTypeObject *type, PyObject *name) +{ + return _Py_type_getattro_impl(type, name, NULL); +} + static int type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) { @@ -4034,6 +4356,7 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) if (name == NULL) return -1; } + /* bpo-40521: Interned strings are shared by all subinterpreters */ if (!PyUnicode_CHECK_INTERNED(name)) { PyUnicode_InternInPlace(&name); if (!PyUnicode_CHECK_INTERNED(name)) { @@ -4069,30 +4392,119 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) extern void _PyDictKeys_DecRef(PyDictKeysObject *keys); + +static void +type_dealloc_common(PyTypeObject *type) +{ + if (type->tp_bases != NULL) { + PyObject *tp, *val, *tb; + PyErr_Fetch(&tp, &val, &tb); + remove_all_subclasses(type, type->tp_bases); + PyErr_Restore(tp, val, tb); + } +} + + +static void clear_subclasses(PyTypeObject *self); + +static void +clear_static_tp_subclasses(PyTypeObject *type) +{ + PyObject *subclasses = lookup_subclasses(type); + if (subclasses == NULL) { + return; + } + + /* Normally it would be a problem to finalize the type if its + tp_subclasses wasn't cleared first. However, this is only + ever called at the end of runtime finalization, so we can be + more liberal in cleaning up. If the given type still has + subtypes at this point then some extension module did not + correctly finalize its objects. + + We can safely obliterate such subtypes since the extension + module and its objects won't be used again, except maybe if + the runtime were re-initialized. In that case the sticky + situation would only happen if the module were re-imported + then and only if the subtype were stored in a global and only + if that global were not overwritten during import. We'd be + fine since the extension is otherwise unsafe and unsupported + in that situation, and likely problematic already. + + In any case, this situation means at least some memory is + going to leak. This mostly only affects embedding scenarios. + */ + + // For now we just do a sanity check and then clear tp_subclasses. + Py_ssize_t i = 0; + PyObject *key, *ref; // borrowed ref + while (PyDict_Next(subclasses, &i, &key, &ref)) { + PyTypeObject *subclass = subclass_from_ref(ref); // borrowed + if (subclass == NULL) { + continue; + } + // All static builtin subtypes should have been finalized already. + assert(!(subclass->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); + } + + clear_subclasses(type); +} + +void +_PyStaticType_Dealloc(PyTypeObject *type) +{ + assert(!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)); + + type_dealloc_common(type); + + Py_CLEAR(type->tp_dict); + Py_CLEAR(type->tp_bases); + Py_CLEAR(type->tp_mro); + Py_CLEAR(type->tp_cache); + clear_static_tp_subclasses(type); + + // PyObject_ClearWeakRefs() raises an exception if Py_REFCNT() != 0 + if (Py_REFCNT(type) == 0) { + PyObject_ClearWeakRefs((PyObject *)type); + } + + type->tp_flags &= ~Py_TPFLAGS_READY; + + if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + _PyStaticType_ClearWeakRefs(type); + static_builtin_state_clear(type); + /* We leave _Py_TPFLAGS_STATIC_BUILTIN set on tp_flags. */ + } +} + + static void type_dealloc(PyTypeObject *type) { - PyHeapTypeObject *et; - PyObject *tp, *val, *tb; - - /* Assert this is a heap-allocated type object */ + // Assert this is a heap-allocated type object _PyObject_ASSERT((PyObject *)type, type->tp_flags & Py_TPFLAGS_HEAPTYPE); + _PyObject_GC_UNTRACK(type); - PyErr_Fetch(&tp, &val, &tb); - remove_all_subclasses(type, type->tp_bases); - PyErr_Restore(tp, val, tb); + + type_dealloc_common(type); + + // PyObject_ClearWeakRefs() raises an exception if Py_REFCNT() != 0 + assert(Py_REFCNT(type) == 0); PyObject_ClearWeakRefs((PyObject *)type); - et = (PyHeapTypeObject *)type; + Py_XDECREF(type->tp_base); Py_XDECREF(type->tp_dict); Py_XDECREF(type->tp_bases); Py_XDECREF(type->tp_mro); Py_XDECREF(type->tp_cache); - Py_XDECREF(type->tp_subclasses); + clear_subclasses(type); + /* A type's tp_doc is heap allocated, unlike the tp_doc slots * of most other objects. It's okay to cast it to char *. */ PyObject_Free((char *)type->tp_doc); + + PyHeapTypeObject *et = (PyHeapTypeObject *)type; Py_XDECREF(et->ht_name); Py_XDECREF(et->ht_qualname); Py_XDECREF(et->ht_slots); @@ -4104,6 +4516,64 @@ type_dealloc(PyTypeObject *type) Py_TYPE(type)->tp_free((PyObject *)type); } + +static PyObject * +lookup_subclasses(PyTypeObject *self) +{ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + static_builtin_state *state = _PyStaticType_GetState(self); + assert(state != NULL); + return state->tp_subclasses; + } + return (PyObject *)self->tp_subclasses; +} + +int +_PyType_HasSubclasses(PyTypeObject *self) +{ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN && + _PyStaticType_GetState(self) == NULL) { + return 0; + } + if (lookup_subclasses(self) == NULL) { + return 0; + } + return 1; +} + +PyObject* +_PyType_GetSubclasses(PyTypeObject *self) +{ + PyObject *list = PyList_New(0); + if (list == NULL) { + return NULL; + } + + PyObject *subclasses = lookup_subclasses(self); // borrowed ref + if (subclasses == NULL) { + return list; + } + assert(PyDict_CheckExact(subclasses)); + // The loop cannot modify tp_subclasses, there is no need + // to hold a strong reference (use a borrowed reference). + + Py_ssize_t i = 0; + PyObject *ref; // borrowed ref + while (PyDict_Next(subclasses, &i, NULL, &ref)) { + PyTypeObject *subclass = subclass_from_ref(ref); // borrowed + if (subclass == NULL) { + continue; + } + + if (PyList_Append(list, _PyObject_CAST(subclass)) < 0) { + Py_DECREF(list); + return NULL; + } + } + return list; +} + + /*[clinic input] type.__subclasses__ @@ -4114,28 +4584,7 @@ static PyObject * type___subclasses___impl(PyTypeObject *self) /*[clinic end generated code: output=eb5eb54485942819 input=5af66132436f9a7b]*/ { - PyObject *list, *raw, *ref; - Py_ssize_t i; - - list = PyList_New(0); - if (list == NULL) - return NULL; - raw = self->tp_subclasses; - if (raw == NULL) - return list; - assert(PyDict_CheckExact(raw)); - i = 0; - while (PyDict_Next(raw, &i, NULL, &ref)) { - assert(PyWeakref_CheckRef(ref)); - ref = PyWeakref_GET_OBJECT(ref); - if (ref != Py_None) { - if (PyList_Append(list, ref) < 0) { - Py_DECREF(list); - return NULL; - } - } - } - return list; + return _PyType_GetSubclasses(self); } static PyObject * @@ -4145,6 +4594,7 @@ type_prepare(PyObject *self, PyObject *const *args, Py_ssize_t nargs, return PyDict_New(); } + /* Merge the __dict__ of aclass into dict, and recursively also all the __dict__s of aclass's base classes. The order of merging isn't @@ -4158,13 +4608,12 @@ merge_class_dict(PyObject *dict, PyObject *aclass) { PyObject *classdict; PyObject *bases; - _Py_IDENTIFIER(__bases__); assert(PyDict_Check(dict)); assert(aclass); /* Merge in the type's dict (if any). */ - if (_PyObject_LookupAttrId(aclass, &PyId___dict__, &classdict) < 0) { + if (_PyObject_LookupAttr(aclass, &_Py_ID(__dict__), &classdict) < 0) { return -1; } if (classdict != NULL) { @@ -4175,7 +4624,7 @@ merge_class_dict(PyObject *dict, PyObject *aclass) } /* Recursively merge in the base types' (if any) dicts. */ - if (_PyObject_LookupAttrId(aclass, &PyId___bases__, &bases) < 0) { + if (_PyObject_LookupAttr(aclass, &_Py_ID(__bases__), &bases) < 0) { return -1; } if (bases != NULL) { @@ -4241,22 +4690,23 @@ static PyObject * type___sizeof___impl(PyTypeObject *self) /*[clinic end generated code: output=766f4f16cd3b1854 input=99398f24b9cf45d6]*/ { - Py_ssize_t size; + size_t size; if (self->tp_flags & Py_TPFLAGS_HEAPTYPE) { PyHeapTypeObject* et = (PyHeapTypeObject*)self; size = sizeof(PyHeapTypeObject); if (et->ht_cached_keys) size += _PyDict_KeysSize(et->ht_cached_keys); } - else + else { size = sizeof(PyTypeObject); - return PyLong_FromSsize_t(size); + } + return PyLong_FromSize_t(size); } static PyMethodDef type_methods[] = { TYPE_MRO_METHODDEF TYPE___SUBCLASSES___METHODDEF - {"__prepare__", (PyCFunction)(void(*)(void))type_prepare, + {"__prepare__", _PyCFunction_CAST(type_prepare), METH_FASTCALL | METH_KEYWORDS | METH_CLASS, PyDoc_STR("__prepare__() -> dict\n" "used to create the namespace for the class statement")}, @@ -4375,7 +4825,7 @@ PyTypeObject PyType_Type = { 0, /* tp_hash */ (ternaryfunc)type_call, /* tp_call */ 0, /* tp_str */ - (getattrofunc)type_getattro, /* tp_getattro */ + (getattrofunc)_Py_type_getattro, /* tp_getattro */ (setattrofunc)type_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | @@ -4498,11 +4948,10 @@ object_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *abstract_methods; PyObject *sorted_methods; PyObject *joined; - PyObject *comma; - _Py_static_string(comma_id, ", "); + PyObject* comma_w_quotes_sep; Py_ssize_t method_count; - /* Compute ", ".join(sorted(type.__abstractmethods__)) + /* Compute "', '".join(sorted(type.__abstractmethods__)) into joined. */ abstract_methods = type_abstractmethods(type, NULL); if (abstract_methods == NULL) @@ -4515,26 +4964,28 @@ object_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_DECREF(sorted_methods); return NULL; } - comma = _PyUnicode_FromId(&comma_id); - if (comma == NULL) { - Py_DECREF(sorted_methods); - return NULL; - } - joined = PyUnicode_Join(comma, sorted_methods); + comma_w_quotes_sep = PyUnicode_FromString("', '"); + joined = PyUnicode_Join(comma_w_quotes_sep, sorted_methods); method_count = PyObject_Length(sorted_methods); Py_DECREF(sorted_methods); - if (joined == NULL) + if (joined == NULL) { + Py_DECREF(comma_w_quotes_sep); return NULL; - if (method_count == -1) + } + if (method_count == -1) { + Py_DECREF(comma_w_quotes_sep); + Py_DECREF(joined); return NULL; + } PyErr_Format(PyExc_TypeError, "Can't instantiate abstract class %s " - "with abstract method%s %U", + "without an implementation for abstract method%s '%U'", type->tp_name, method_count > 1 ? "s" : "", joined); Py_DECREF(joined); + Py_DECREF(comma_w_quotes_sep); return NULL; } PyObject *obj = type->tp_alloc(type, 0); @@ -4565,15 +5016,14 @@ object_repr(PyObject *self) if (mod == NULL) PyErr_Clear(); else if (!PyUnicode_Check(mod)) { - Py_DECREF(mod); - mod = NULL; + Py_SETREF(mod, NULL); } name = type_qualname(type, NULL); if (name == NULL) { Py_XDECREF(mod); return NULL; } - if (mod != NULL && !_PyUnicode_EqualToASCIIId(mod, &PyId_builtins)) + if (mod != NULL && !_PyUnicode_Equal(mod, &_Py_ID(builtins))) rtn = PyUnicode_FromFormat("<%U.%U object at %p>", mod, name, self); else rtn = PyUnicode_FromFormat("<%s object at %p>", @@ -4605,16 +5055,14 @@ object_richcompare(PyObject *self, PyObject *other, int op) /* Return NotImplemented instead of False, so if two objects are compared, both get a chance at the comparison. See issue #1393. */ - res = (self == other) ? Py_True : Py_NotImplemented; - Py_INCREF(res); + res = Py_NewRef((self == other) ? Py_True : Py_NotImplemented); break; case Py_NE: /* By default, __ne__() delegates to __eq__() and inverts the result, unless the latter returns NotImplemented. */ if (Py_TYPE(self)->tp_richcompare == NULL) { - res = Py_NotImplemented; - Py_INCREF(res); + res = Py_NewRef(Py_NotImplemented); break; } res = (*Py_TYPE(self)->tp_richcompare)(self, other, Py_EQ); @@ -4625,17 +5073,15 @@ object_richcompare(PyObject *self, PyObject *other, int op) res = NULL; else { if (ok) - res = Py_False; + res = Py_NewRef(Py_False); else - res = Py_True; - Py_INCREF(res); + res = Py_NewRef(Py_True); } } break; default: - res = Py_NotImplemented; - Py_INCREF(res); + res = Py_NewRef(Py_NotImplemented); break; } @@ -4645,8 +5091,7 @@ object_richcompare(PyObject *self, PyObject *other, int op) static PyObject * object_get_class(PyObject *self, void *closure) { - Py_INCREF(Py_TYPE(self)); - return (PyObject *)(Py_TYPE(self)); + return Py_NewRef(Py_TYPE(self)); } static int @@ -4658,7 +5103,6 @@ compatible_with_tp_base(PyTypeObject *child) child->tp_itemsize == parent->tp_itemsize && child->tp_dictoffset == parent->tp_dictoffset && child->tp_weaklistoffset == parent->tp_weaklistoffset && - child->tp_inline_values_offset == parent->tp_inline_values_offset && ((child->tp_flags & Py_TPFLAGS_HAVE_GC) == (parent->tp_flags & Py_TPFLAGS_HAVE_GC)) && (child->tp_dealloc == subtype_dealloc || @@ -4678,8 +5122,6 @@ same_slots_added(PyTypeObject *a, PyTypeObject *b) size += sizeof(PyObject *); if (a->tp_weaklistoffset == size && b->tp_weaklistoffset == size) size += sizeof(PyObject *); - if (a->tp_inline_values_offset == size && b->tp_inline_values_offset == size) - size += sizeof(PyObject *); /* Check slots compliance */ if (!(a->tp_flags & Py_TPFLAGS_HEAPTYPE) || @@ -4729,23 +5171,28 @@ compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, const char* if (newbase != oldbase && (newbase->tp_base != oldbase->tp_base || !same_slots_added(newbase, oldbase))) { - PyErr_Format(PyExc_TypeError, - "%s assignment: " - "'%s' object layout differs from '%s'", - attr, - newto->tp_name, - oldto->tp_name); - return 0; + goto differs; } - - return 1; + /* The above does not check for the preheader */ + if ((oldto->tp_flags & Py_TPFLAGS_PREHEADER) == + ((newto->tp_flags & Py_TPFLAGS_PREHEADER))) + { + return 1; + } +differs: + PyErr_Format(PyExc_TypeError, + "%s assignment: " + "'%s' object layout differs from '%s'", + attr, + newto->tp_name, + oldto->tp_name); + return 0; } static int object_set_class(PyObject *self, PyObject *value, void *closure) { PyTypeObject *oldto = Py_TYPE(self); - PyTypeObject *newto; if (value == NULL) { PyErr_SetString(PyExc_TypeError, @@ -4758,12 +5205,13 @@ object_set_class(PyObject *self, PyObject *value, void *closure) Py_TYPE(value)->tp_name); return -1; } + PyTypeObject *newto = (PyTypeObject *)value; + if (PySys_Audit("object.__setattr__", "OsO", self, "__class__", value) < 0) { return -1; } - newto = (PyTypeObject *)value; /* In versions of CPython prior to 3.5, the code in compatible_for_assignment was not set up to correctly check for memory layout / slot / etc. compatibility for non-HEAPTYPE classes, so we just @@ -4826,15 +5274,15 @@ object_set_class(PyObject *self, PyObject *value, void *closure) if (compatible_for_assignment(oldto, newto, "__class__")) { /* Changing the class will change the implicit dict keys, * so we must materialize the dictionary first. */ - assert(oldto->tp_inline_values_offset == newto->tp_inline_values_offset); + assert((oldto->tp_flags & Py_TPFLAGS_PREHEADER) == (newto->tp_flags & Py_TPFLAGS_PREHEADER)); _PyObject_GetDictPtr(self); - PyDictValues** values_ptr = _PyObject_ValuesPointer(self); - if (values_ptr != NULL && *values_ptr != NULL) { + if (oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT && + _PyDictOrValues_IsValues(*_PyObject_DictOrValuesPointer(self))) + { /* Was unable to convert to dict */ PyErr_NoMemory(); return -1; } - assert(_PyObject_ValuesPointer(self) == NULL || *_PyObject_ValuesPointer(self) == NULL); if (newto->tp_flags & Py_TPFLAGS_HEAPTYPE) { Py_INCREF(newto); } @@ -4865,27 +5313,19 @@ static PyGetSetDef object_getsets[] = { static PyObject * import_copyreg(void) { - PyObject *copyreg_str; - PyObject *copyreg_module; - _Py_IDENTIFIER(copyreg); - - copyreg_str = _PyUnicode_FromId(&PyId_copyreg); - if (copyreg_str == NULL) { - return NULL; - } /* Try to fetch cached copy of copyreg from sys.modules first in an attempt to avoid the import overhead. Previously this was implemented by storing a reference to the cached module in a static variable, but this broke when multiple embedded interpreters were in use (see issue #17408 and #19088). */ - copyreg_module = PyImport_GetModule(copyreg_str); + PyObject *copyreg_module = PyImport_GetModule(&_Py_ID(copyreg)); if (copyreg_module != NULL) { return copyreg_module; } if (PyErr_Occurred()) { return NULL; } - return PyImport_Import(copyreg_str); + return PyImport_Import(&_Py_ID(copyreg)); } static PyObject * @@ -4893,13 +5333,11 @@ _PyType_GetSlotNames(PyTypeObject *cls) { PyObject *copyreg; PyObject *slotnames; - _Py_IDENTIFIER(__slotnames__); - _Py_IDENTIFIER(_slotnames); assert(PyType_Check(cls)); /* Get the slot names from the cache in the class if possible. */ - slotnames = _PyDict_GetItemIdWithError(cls->tp_dict, &PyId___slotnames__); + slotnames = PyDict_GetItemWithError(cls->tp_dict, &_Py_ID(__slotnames__)); if (slotnames != NULL) { if (slotnames != Py_None && !PyList_Check(slotnames)) { PyErr_Format(PyExc_TypeError, @@ -4908,8 +5346,7 @@ _PyType_GetSlotNames(PyTypeObject *cls) cls->tp_name, Py_TYPE(slotnames)->tp_name); return NULL; } - Py_INCREF(slotnames); - return slotnames; + return Py_NewRef(slotnames); } else { if (PyErr_Occurred()) { @@ -4925,8 +5362,8 @@ _PyType_GetSlotNames(PyTypeObject *cls) /* Use _slotnames function from the copyreg module to find the slots by this class and its bases. This function will cache the result in __slotnames__. */ - slotnames = _PyObject_CallMethodIdOneArg(copyreg, &PyId__slotnames, - (PyObject *)cls); + slotnames = PyObject_CallMethodOneArg( + copyreg, &_Py_ID(_slotnames), (PyObject *)cls); Py_DECREF(copyreg); if (slotnames == NULL) return NULL; @@ -4942,151 +5379,176 @@ _PyType_GetSlotNames(PyTypeObject *cls) } static PyObject * -_PyObject_GetState(PyObject *obj, int required) +object_getstate_default(PyObject *obj, int required) { PyObject *state; - PyObject *getstate; - _Py_IDENTIFIER(__getstate__); + PyObject *slotnames; - if (_PyObject_LookupAttrId(obj, &PyId___getstate__, &getstate) < 0) { + if (required && Py_TYPE(obj)->tp_itemsize) { + PyErr_Format(PyExc_TypeError, + "cannot pickle %.200s objects", + Py_TYPE(obj)->tp_name); return NULL; } - if (getstate == NULL) { - PyObject *slotnames; - if (required && Py_TYPE(obj)->tp_itemsize) { + if (_PyObject_IsInstanceDictEmpty(obj)) { + state = Py_NewRef(Py_None); + } + else { + state = PyObject_GenericGetDict(obj, NULL); + if (state == NULL) { + return NULL; + } + } + + slotnames = _PyType_GetSlotNames(Py_TYPE(obj)); + if (slotnames == NULL) { + Py_DECREF(state); + return NULL; + } + + assert(slotnames == Py_None || PyList_Check(slotnames)); + if (required) { + Py_ssize_t basicsize = PyBaseObject_Type.tp_basicsize; + if (Py_TYPE(obj)->tp_dictoffset && + (Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) + { + basicsize += sizeof(PyObject *); + } + if (Py_TYPE(obj)->tp_weaklistoffset > 0) { + basicsize += sizeof(PyObject *); + } + if (slotnames != Py_None) { + basicsize += sizeof(PyObject *) * PyList_GET_SIZE(slotnames); + } + if (Py_TYPE(obj)->tp_basicsize > basicsize) { + Py_DECREF(slotnames); + Py_DECREF(state); PyErr_Format(PyExc_TypeError, "cannot pickle '%.200s' object", Py_TYPE(obj)->tp_name); return NULL; } - if (_PyObject_IsInstanceDictEmpty(obj)) { - state = Py_None; - Py_INCREF(state); - } - else { - state = PyObject_GenericGetDict(obj, NULL); - if (state == NULL) { - return NULL; - } - } + } - slotnames = _PyType_GetSlotNames(Py_TYPE(obj)); - if (slotnames == NULL) { + if (slotnames != Py_None && PyList_GET_SIZE(slotnames) > 0) { + PyObject *slots; + Py_ssize_t slotnames_size, i; + + slots = PyDict_New(); + if (slots == NULL) { + Py_DECREF(slotnames); Py_DECREF(state); return NULL; } - assert(slotnames == Py_None || PyList_Check(slotnames)); - if (required) { - Py_ssize_t basicsize = PyBaseObject_Type.tp_basicsize; - if (Py_TYPE(obj)->tp_dictoffset) { - basicsize += sizeof(PyObject *); + slotnames_size = PyList_GET_SIZE(slotnames); + for (i = 0; i < slotnames_size; i++) { + PyObject *name, *value; + + name = Py_NewRef(PyList_GET_ITEM(slotnames, i)); + if (_PyObject_LookupAttr(obj, name, &value) < 0) { + Py_DECREF(name); + goto error; } - if (Py_TYPE(obj)->tp_weaklistoffset) { - basicsize += sizeof(PyObject *); + if (value == NULL) { + Py_DECREF(name); + /* It is not an error if the attribute is not present. */ } - if (Py_TYPE(obj)->tp_inline_values_offset) { - basicsize += sizeof(PyDictValues *); + else { + int err = PyDict_SetItem(slots, name, value); + Py_DECREF(name); + Py_DECREF(value); + if (err) { + goto error; + } } - if (slotnames != Py_None) { - basicsize += sizeof(PyObject *) * PyList_GET_SIZE(slotnames); + + /* The list is stored on the class so it may mutate while we + iterate over it */ + if (slotnames_size != PyList_GET_SIZE(slotnames)) { + PyErr_Format(PyExc_RuntimeError, + "__slotsname__ changed size during iteration"); + goto error; } - if (Py_TYPE(obj)->tp_basicsize > basicsize) { + + /* We handle errors within the loop here. */ + if (0) { + error: Py_DECREF(slotnames); + Py_DECREF(slots); Py_DECREF(state); - PyErr_Format(PyExc_TypeError, - "cannot pickle '%.200s' object", - Py_TYPE(obj)->tp_name); return NULL; } } - if (slotnames != Py_None && PyList_GET_SIZE(slotnames) > 0) { - PyObject *slots; - Py_ssize_t slotnames_size, i; + /* If we found some slot attributes, pack them in a tuple along + the original attribute dictionary. */ + if (PyDict_GET_SIZE(slots) > 0) { + PyObject *state2; - slots = PyDict_New(); - if (slots == NULL) { + state2 = PyTuple_Pack(2, state, slots); + Py_DECREF(state); + if (state2 == NULL) { Py_DECREF(slotnames); - Py_DECREF(state); + Py_DECREF(slots); return NULL; } - - slotnames_size = PyList_GET_SIZE(slotnames); - for (i = 0; i < slotnames_size; i++) { - PyObject *name, *value; - - name = PyList_GET_ITEM(slotnames, i); - Py_INCREF(name); - if (_PyObject_LookupAttr(obj, name, &value) < 0) { - goto error; - } - if (value == NULL) { - Py_DECREF(name); - /* It is not an error if the attribute is not present. */ - } - else { - int err = PyDict_SetItem(slots, name, value); - Py_DECREF(name); - Py_DECREF(value); - if (err) { - goto error; - } - } - - /* The list is stored on the class so it may mutate while we - iterate over it */ - if (slotnames_size != PyList_GET_SIZE(slotnames)) { - PyErr_Format(PyExc_RuntimeError, - "__slotsname__ changed size during iteration"); - goto error; - } - - /* We handle errors within the loop here. */ - if (0) { - error: - Py_DECREF(slotnames); - Py_DECREF(slots); - Py_DECREF(state); - return NULL; - } - } - - /* If we found some slot attributes, pack them in a tuple along - the original attribute dictionary. */ - if (PyDict_GET_SIZE(slots) > 0) { - PyObject *state2; - - state2 = PyTuple_Pack(2, state, slots); - Py_DECREF(state); - if (state2 == NULL) { - Py_DECREF(slotnames); - Py_DECREF(slots); - return NULL; - } - state = state2; - } - Py_DECREF(slots); + state = state2; } - Py_DECREF(slotnames); - } - else { /* getstate != NULL */ - state = _PyObject_CallNoArgs(getstate); - Py_DECREF(getstate); - if (state == NULL) - return NULL; + Py_DECREF(slots); } + Py_DECREF(slotnames); return state; } +static PyObject * +object_getstate(PyObject *obj, int required) +{ + PyObject *getstate, *state; + + getstate = PyObject_GetAttr(obj, &_Py_ID(__getstate__)); + if (getstate == NULL) { + return NULL; + } + if (PyCFunction_Check(getstate) && + PyCFunction_GET_SELF(getstate) == obj && + PyCFunction_GET_FUNCTION(getstate) == object___getstate__) + { + /* If __getstate__ is not overridden pass the required argument. */ + state = object_getstate_default(obj, required); + } + else { + state = _PyObject_CallNoArgs(getstate); + } + Py_DECREF(getstate); + return state; +} + +PyObject * +_PyObject_GetState(PyObject *obj) +{ + return object_getstate(obj, 0); +} + +/*[clinic input] +object.__getstate__ + +Helper for pickle. +[clinic start generated code]*/ + +static PyObject * +object___getstate___impl(PyObject *self) +/*[clinic end generated code: output=5a2500dcb6217e9e input=692314d8fbe194ee]*/ +{ + return object_getstate_default(self, 0); +} + static int _PyObject_GetNewArguments(PyObject *obj, PyObject **args, PyObject **kwargs) { PyObject *getnewargs, *getnewargs_ex; - _Py_IDENTIFIER(__getnewargs_ex__); - _Py_IDENTIFIER(__getnewargs__); if (args == NULL || kwargs == NULL) { PyErr_BadInternalCall(); @@ -5095,7 +5557,7 @@ _PyObject_GetNewArguments(PyObject *obj, PyObject **args, PyObject **kwargs) /* We first attempt to fetch the arguments for __new__ by calling __getnewargs_ex__ on the object. */ - getnewargs_ex = _PyObject_LookupSpecial(obj, &PyId___getnewargs_ex__); + getnewargs_ex = _PyObject_LookupSpecial(obj, &_Py_ID(__getnewargs_ex__)); if (getnewargs_ex != NULL) { PyObject *newargs = _PyObject_CallNoArgs(getnewargs_ex); Py_DECREF(getnewargs_ex); @@ -5116,10 +5578,8 @@ _PyObject_GetNewArguments(PyObject *obj, PyObject **args, PyObject **kwargs) Py_DECREF(newargs); return -1; } - *args = PyTuple_GET_ITEM(newargs, 0); - Py_INCREF(*args); - *kwargs = PyTuple_GET_ITEM(newargs, 1); - Py_INCREF(*kwargs); + *args = Py_NewRef(PyTuple_GET_ITEM(newargs, 0)); + *kwargs = Py_NewRef(PyTuple_GET_ITEM(newargs, 1)); Py_DECREF(newargs); /* XXX We should perhaps allow None to be passed here. */ @@ -5148,7 +5608,7 @@ _PyObject_GetNewArguments(PyObject *obj, PyObject **args, PyObject **kwargs) /* The object does not have __getnewargs_ex__ so we fallback on using __getnewargs__ instead. */ - getnewargs = _PyObject_LookupSpecial(obj, &PyId___getnewargs__); + getnewargs = _PyObject_LookupSpecial(obj, &_Py_ID(__getnewargs__)); if (getnewargs != NULL) { *args = _PyObject_CallNoArgs(getnewargs); Py_DECREF(getnewargs); @@ -5187,8 +5647,7 @@ _PyObject_GetItemsIter(PyObject *obj, PyObject **listitems, } if (!PyList_Check(obj)) { - *listitems = Py_None; - Py_INCREF(*listitems); + *listitems = Py_NewRef(Py_None); } else { *listitems = PyObject_GetIter(obj); @@ -5197,14 +5656,10 @@ _PyObject_GetItemsIter(PyObject *obj, PyObject **listitems, } if (!PyDict_Check(obj)) { - *dictitems = Py_None; - Py_INCREF(*dictitems); + *dictitems = Py_NewRef(Py_None); } else { - PyObject *items; - _Py_IDENTIFIER(items); - - items = _PyObject_CallMethodIdNoArgs(obj, &PyId_items); + PyObject *items = PyObject_CallMethodNoArgs(obj, &_Py_ID(items)); if (items == NULL) { Py_CLEAR(*listitems); return -1; @@ -5248,12 +5703,11 @@ reduce_newobj(PyObject *obj) } hasargs = (args != NULL); if (kwargs == NULL || PyDict_GET_SIZE(kwargs) == 0) { - _Py_IDENTIFIER(__newobj__); PyObject *cls; Py_ssize_t i, n; Py_XDECREF(kwargs); - newobj = _PyObject_GetAttrId(copyreg, &PyId___newobj__); + newobj = PyObject_GetAttr(copyreg, &_Py_ID(__newobj__)); Py_DECREF(copyreg); if (newobj == NULL) { Py_XDECREF(args); @@ -5267,19 +5721,15 @@ reduce_newobj(PyObject *obj) return NULL; } cls = (PyObject *) Py_TYPE(obj); - Py_INCREF(cls); - PyTuple_SET_ITEM(newargs, 0, cls); + PyTuple_SET_ITEM(newargs, 0, Py_NewRef(cls)); for (i = 0; i < n; i++) { PyObject *v = PyTuple_GET_ITEM(args, i); - Py_INCREF(v); - PyTuple_SET_ITEM(newargs, i+1, v); + PyTuple_SET_ITEM(newargs, i+1, Py_NewRef(v)); } Py_XDECREF(args); } else if (args != NULL) { - _Py_IDENTIFIER(__newobj_ex__); - - newobj = _PyObject_GetAttrId(copyreg, &PyId___newobj_ex__); + newobj = PyObject_GetAttr(copyreg, &_Py_ID(__newobj_ex__)); Py_DECREF(copyreg); if (newobj == NULL) { Py_DECREF(args); @@ -5301,8 +5751,7 @@ reduce_newobj(PyObject *obj) return NULL; } - state = _PyObject_GetState(obj, - !hasargs && !PyList_Check(obj) && !PyDict_Check(obj)); + state = object_getstate(obj, !(hasargs || PyList_Check(obj) || PyDict_Check(obj))); if (state == NULL) { Py_DECREF(newobj); Py_DECREF(newargs); @@ -5383,19 +5832,19 @@ static PyObject * object___reduce_ex___impl(PyObject *self, int protocol) /*[clinic end generated code: output=2e157766f6b50094 input=f326b43fb8a4c5ff]*/ { - static PyObject *objreduce; +#define objreduce \ + (_Py_INTERP_CACHED_OBJECT(_PyInterpreterState_Get(), objreduce)) PyObject *reduce, *res; - _Py_IDENTIFIER(__reduce__); if (objreduce == NULL) { - objreduce = _PyDict_GetItemIdWithError(PyBaseObject_Type.tp_dict, - &PyId___reduce__); + objreduce = PyDict_GetItemWithError( + PyBaseObject_Type.tp_dict, &_Py_ID(__reduce__)); if (objreduce == NULL && PyErr_Occurred()) { return NULL; } } - if (_PyObject_LookupAttrId(self, &PyId___reduce__, &reduce) < 0) { + if (_PyObject_LookupAttr(self, &_Py_ID(__reduce__), &reduce) < 0) { return NULL; } if (reduce != NULL) { @@ -5403,7 +5852,7 @@ object___reduce_ex___impl(PyObject *self, int protocol) int override; cls = (PyObject *) Py_TYPE(self); - clsreduce = _PyObject_GetAttrId(cls, &PyId___reduce__); + clsreduce = PyObject_GetAttr(cls, &_Py_ID(__reduce__)); if (clsreduce == NULL) { Py_DECREF(reduce); return NULL; @@ -5420,6 +5869,7 @@ object___reduce_ex___impl(PyObject *self, int protocol) } return _common_reduce(self, protocol); +#undef objreduce } static PyObject * @@ -5455,11 +5905,13 @@ object.__format__ / Default object formatter. + +Return str(self) if format_spec is empty. Raise TypeError otherwise. [clinic start generated code]*/ static PyObject * object___format___impl(PyObject *self, PyObject *format_spec) -/*[clinic end generated code: output=34897efb543a974b input=7c3b3bc53a6fb7fa]*/ +/*[clinic end generated code: output=34897efb543a974b input=b94d8feb006689ea]*/ { /* Issue 7994: If we're converting to a string, we should reject format specifications */ @@ -5511,7 +5963,7 @@ object___dir___impl(PyObject *self) PyObject *itsclass = NULL; /* Get __dict__ (which may or may not be a real dict...) */ - if (_PyObject_LookupAttrId(self, &PyId___dict__, &dict) < 0) { + if (_PyObject_LookupAttr(self, &_Py_ID(__dict__), &dict) < 0) { return NULL; } if (dict == NULL) { @@ -5524,15 +5976,14 @@ object___dir___impl(PyObject *self) else { /* Copy __dict__ to avoid mutating it. */ PyObject *temp = PyDict_Copy(dict); - Py_DECREF(dict); - dict = temp; + Py_SETREF(dict, temp); } if (dict == NULL) goto error; /* Merge in attrs reachable from its class. */ - if (_PyObject_LookupAttrId(self, &PyId___class__, &itsclass) < 0) { + if (_PyObject_LookupAttr(self, &_Py_ID(__class__), &itsclass) < 0) { goto error; } /* XXX(tomer): Perhaps fall back to Py_TYPE(obj) if no @@ -5551,6 +6002,7 @@ error: static PyMethodDef object_methods[] = { OBJECT___REDUCE_EX___METHODDEF OBJECT___REDUCE___METHODDEF + OBJECT___GETSTATE___METHODDEF {"__subclasshook__", object_subclasshook, METH_CLASS | METH_VARARGS, object_subclasshook_doc}, {"__init_subclass__", object_init_subclass, METH_CLASS | METH_NOARGS, @@ -5749,6 +6201,7 @@ inherit_special(PyTypeObject *type, PyTypeObject *base) if (type->tp_clear == NULL) type->tp_clear = base->tp_clear; } + type->tp_flags |= (base->tp_flags & Py_TPFLAGS_PREHEADER); if (type->tp_basicsize == 0) type->tp_basicsize = base->tp_basicsize; @@ -5761,7 +6214,7 @@ inherit_special(PyTypeObject *type, PyTypeObject *base) COPYVAL(tp_itemsize); COPYVAL(tp_weaklistoffset); COPYVAL(tp_dictoffset); - COPYVAL(tp_inline_values_offset); + #undef COPYVAL /* Setup fast subclass flags */ @@ -5798,12 +6251,11 @@ static int overrides_hash(PyTypeObject *type) { PyObject *dict = type->tp_dict; - _Py_IDENTIFIER(__eq__); assert(dict != NULL); - int r = _PyDict_ContainsId(dict, &PyId___eq__); + int r = PyDict_Contains(dict, &_Py_ID(__eq__)); if (r == 0) { - r = _PyDict_ContainsId(dict, &PyId___hash__); + r = PyDict_Contains(dict, &_Py_ID(__hash__)); } return r; } @@ -5936,11 +6388,9 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) * won't be used automatically. */ COPYSLOT(tp_vectorcall_offset); - /* Inherit Py_TPFLAGS_HAVE_VECTORCALL for non-heap types - * if tp_call is not overridden */ + /* Inherit Py_TPFLAGS_HAVE_VECTORCALL if tp_call is not overridden */ if (!type->tp_call && - _PyType_HasFeature(base, Py_TPFLAGS_HAVE_VECTORCALL) && - _PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) + _PyType_HasFeature(base, Py_TPFLAGS_HAVE_VECTORCALL)) { type->tp_flags |= Py_TPFLAGS_HAVE_VECTORCALL; } @@ -6118,7 +6568,7 @@ type_ready_set_dict(PyTypeObject *type) static int type_dict_set_doc(PyTypeObject *type) { - int r = _PyDict_ContainsId(type->tp_dict, &PyId___doc__); + int r = PyDict_Contains(type->tp_dict, &_Py_ID(__doc__)); if (r < 0) { return -1; } @@ -6134,14 +6584,14 @@ type_dict_set_doc(PyTypeObject *type) return -1; } - if (_PyDict_SetItemId(type->tp_dict, &PyId___doc__, doc) < 0) { + if (PyDict_SetItem(type->tp_dict, &_Py_ID(__doc__), doc) < 0) { Py_DECREF(doc); return -1; } Py_DECREF(doc); } else { - if (_PyDict_SetItemId(type->tp_dict, &PyId___doc__, Py_None) < 0) { + if (PyDict_SetItem(type->tp_dict, &_Py_ID(__doc__), Py_None) < 0) { return -1; } } @@ -6171,6 +6621,33 @@ type_ready_fill_dict(PyTypeObject *type) return 0; } +static int +type_ready_preheader(PyTypeObject *type) +{ + if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + if (type->tp_dictoffset > 0 || type->tp_dictoffset < -1) { + PyErr_Format(PyExc_TypeError, + "type %s has the Py_TPFLAGS_MANAGED_DICT flag " + "but tp_dictoffset is set", + type->tp_name); + return -1; + } + type->tp_dictoffset = -1; + } + if (type->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF) { + if (type->tp_weaklistoffset != 0 && + type->tp_weaklistoffset != MANAGED_WEAKREF_OFFSET) + { + PyErr_Format(PyExc_TypeError, + "type %s has the Py_TPFLAGS_MANAGED_WEAKREF flag " + "but tp_weaklistoffset is set", + type->tp_name); + return -1; + } + type->tp_weaklistoffset = MANAGED_WEAKREF_OFFSET; + } + return 0; +} static int type_ready_mro(PyTypeObject *type) @@ -6187,8 +6664,8 @@ type_ready_mro(PyTypeObject *type) PyObject *mro = type->tp_mro; Py_ssize_t n = PyTuple_GET_SIZE(mro); for (Py_ssize_t i = 0; i < n; i++) { - PyTypeObject *base = (PyTypeObject *)PyTuple_GET_ITEM(mro, i); - if (PyType_Check(base) && (base->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(mro, i)); + if (base->tp_flags & Py_TPFLAGS_HEAPTYPE) { PyErr_Format(PyExc_TypeError, "type '%.100s' is not dynamically allocated but " "its base type '%.100s' is dynamically allocated", @@ -6289,7 +6766,7 @@ type_ready_set_hash(PyTypeObject *type) return 0; } - int r = _PyDict_ContainsId(type->tp_dict, &PyId___hash__); + int r = PyDict_Contains(type->tp_dict, &_Py_ID(__hash__)); if (r < 0) { return -1; } @@ -6297,7 +6774,7 @@ type_ready_set_hash(PyTypeObject *type) return 0; } - if (_PyDict_SetItemId(type->tp_dict, &PyId___hash__, Py_None) < 0) { + if (PyDict_SetItem(type->tp_dict, &_Py_ID(__hash__), Py_None) < 0) { return -1; } type->tp_hash = PyObject_HashNotImplemented; @@ -6364,6 +6841,29 @@ type_ready_set_new(PyTypeObject *type) return 0; } +static int +type_ready_managed_dict(PyTypeObject *type) +{ + if (!(type->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + return 0; + } + if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + PyErr_Format(PyExc_SystemError, + "type %s has the Py_TPFLAGS_MANAGED_DICT flag " + "but not Py_TPFLAGS_HEAPTYPE flag", + type->tp_name); + return -1; + } + PyHeapTypeObject* et = (PyHeapTypeObject*)type; + if (et->ht_cached_keys == NULL) { + et->ht_cached_keys = _PyDict_NewKeysForClass(); + if (et->ht_cached_keys == NULL) { + PyErr_NoMemory(); + return -1; + } + } + return 0; +} static int type_ready_post_checks(PyTypeObject *type) @@ -6379,6 +6879,21 @@ type_ready_post_checks(PyTypeObject *type) type->tp_name); return -1; } + if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + if (type->tp_dictoffset != -1) { + PyErr_Format(PyExc_SystemError, + "type %s has the Py_TPFLAGS_MANAGED_DICT flag " + "but tp_dictoffset is set to incompatible value", + type->tp_name); + return -1; + } + } + else if (type->tp_dictoffset < (Py_ssize_t)sizeof(PyObject)) { + if (type->tp_dictoffset + type->tp_basicsize <= 0) { + PyErr_Format(PyExc_SystemError, + "type %s has a tp_dictoffset that is too small"); + } + } return 0; } @@ -6418,12 +6933,18 @@ type_ready(PyTypeObject *type) if (type_ready_inherit(type) < 0) { return -1; } + if (type_ready_preheader(type) < 0) { + return -1; + } if (type_ready_set_hash(type) < 0) { return -1; } if (type_ready_add_subclasses(type) < 0) { return -1; } + if (type_ready_managed_dict(type) < 0) { + return -1; + } if (type_ready_post_checks(type) < 0) { return -1; } @@ -6459,28 +6980,80 @@ PyType_Ready(PyTypeObject *type) return 0; } +int +_PyStaticType_InitBuiltin(PyTypeObject *self) +{ + self->tp_flags = self->tp_flags | _Py_TPFLAGS_STATIC_BUILTIN; + + static_builtin_state_init(self); + + int res = PyType_Ready(self); + if (res < 0) { + static_builtin_state_clear(self); + } + return res; +} + + +static PyObject * +init_subclasses(PyTypeObject *self) +{ + PyObject *subclasses = PyDict_New(); + if (subclasses == NULL) { + return NULL; + } + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + static_builtin_state *state = _PyStaticType_GetState(self); + state->tp_subclasses = subclasses; + return subclasses; + } + self->tp_subclasses = (void *)subclasses; + return subclasses; +} + +static void +clear_subclasses(PyTypeObject *self) +{ + /* Delete the dictionary to save memory. _PyStaticType_Dealloc() + callers also test if tp_subclasses is NULL to check if a static type + has no subclass. */ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + static_builtin_state *state = _PyStaticType_GetState(self); + Py_CLEAR(state->tp_subclasses); + return; + } + Py_CLEAR(self->tp_subclasses); +} static int add_subclass(PyTypeObject *base, PyTypeObject *type) { - int result = -1; - PyObject *dict, *key, *newobj; - - dict = base->tp_subclasses; - if (dict == NULL) { - base->tp_subclasses = dict = PyDict_New(); - if (dict == NULL) - return -1; - } - assert(PyDict_CheckExact(dict)); - key = PyLong_FromVoidPtr((void *) type); + PyObject *key = PyLong_FromVoidPtr((void *) type); if (key == NULL) return -1; - newobj = PyWeakref_NewRef((PyObject *)type, NULL); - if (newobj != NULL) { - result = PyDict_SetItem(dict, key, newobj); - Py_DECREF(newobj); + + PyObject *ref = PyWeakref_NewRef((PyObject *)type, NULL); + if (ref == NULL) { + Py_DECREF(key); + return -1; } + + // Only get tp_subclasses after creating the key and value. + // PyWeakref_NewRef() can trigger a garbage collection which can execute + // arbitrary Python code and so modify base->tp_subclasses. + PyObject *subclasses = lookup_subclasses(base); + if (subclasses == NULL) { + subclasses = init_subclasses(base); + if (subclasses == NULL) { + Py_DECREF(key); + Py_DECREF(ref); + return -1; + } + } + assert(PyDict_CheckExact(subclasses)); + + int result = PyDict_SetItem(subclasses, key, ref); + Py_DECREF(ref); Py_DECREF(key); return result; } @@ -6488,52 +7061,95 @@ add_subclass(PyTypeObject *base, PyTypeObject *type) static int add_all_subclasses(PyTypeObject *type, PyObject *bases) { + Py_ssize_t n = PyTuple_GET_SIZE(bases); int res = 0; - - if (bases) { - Py_ssize_t i; - for (i = 0; i < PyTuple_GET_SIZE(bases); i++) { - PyObject *base = PyTuple_GET_ITEM(bases, i); - if (PyType_Check(base) && - add_subclass((PyTypeObject*)base, type) < 0) - res = -1; + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *obj = PyTuple_GET_ITEM(bases, i); + // bases tuple must only contain types + PyTypeObject *base = _PyType_CAST(obj); + if (add_subclass(base, type) < 0) { + res = -1; } } - return res; } +static inline PyTypeObject * +subclass_from_ref(PyObject *ref) +{ + assert(PyWeakref_CheckRef(ref)); + PyObject *obj = PyWeakref_GET_OBJECT(ref); // borrowed ref + assert(obj != NULL); + if (obj == Py_None) { + return NULL; + } + assert(PyType_Check(obj)); + return _PyType_CAST(obj); +} + +static PyObject * +get_subclasses_key(PyTypeObject *type, PyTypeObject *base) +{ + PyObject *key = PyLong_FromVoidPtr((void *) type); + if (key != NULL) { + return key; + } + PyErr_Clear(); + + /* This basically means we're out of memory. + We fall back to manually traversing the values. */ + Py_ssize_t i = 0; + PyObject *ref; // borrowed ref + PyObject *subclasses = lookup_subclasses(base); + if (subclasses != NULL) { + while (PyDict_Next(subclasses, &i, &key, &ref)) { + PyTypeObject *subclass = subclass_from_ref(ref); // borrowed + if (subclass == type) { + return Py_NewRef(key); + } + } + } + /* It wasn't found. */ + return NULL; +} + static void remove_subclass(PyTypeObject *base, PyTypeObject *type) { - PyObject *dict, *key; - - dict = base->tp_subclasses; - if (dict == NULL) { + PyObject *subclasses = lookup_subclasses(base); // borrowed ref + if (subclasses == NULL) { return; } - assert(PyDict_CheckExact(dict)); - key = PyLong_FromVoidPtr((void *) type); - if (key == NULL || PyDict_DelItem(dict, key)) { + assert(PyDict_CheckExact(subclasses)); + + PyObject *key = get_subclasses_key(type, base); + if (key != NULL && PyDict_DelItem(subclasses, key)) { /* This can happen if the type initialization errored out before the base subclasses were updated (e.g. a non-str __qualname__ was passed in the type dict). */ PyErr_Clear(); } Py_XDECREF(key); + + if (PyDict_Size(subclasses) == 0) { + clear_subclasses(base); + } } static void remove_all_subclasses(PyTypeObject *type, PyObject *bases) { - if (bases) { - Py_ssize_t i; - for (i = 0; i < PyTuple_GET_SIZE(bases); i++) { - PyObject *base = PyTuple_GET_ITEM(bases, i); - if (PyType_Check(base)) - remove_subclass((PyTypeObject*) base, type); + assert(bases != NULL); + // remove_subclass() can clear the current exception + assert(!PyErr_Occurred()); + + for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(bases); i++) { + PyObject *base = PyTuple_GET_ITEM(bases, i); + if (PyType_Check(base)) { + remove_subclass((PyTypeObject*) base, type); } } + assert(!PyErr_Occurred()); } static int @@ -6825,7 +7441,7 @@ hackcheck(PyObject *self, setattrofunc func, const char *what) PyTypeObject *defining_type = type; Py_ssize_t i; for (i = PyTuple_GET_SIZE(mro) - 1; i >= 0; i--) { - PyTypeObject *base = (PyTypeObject*) PyTuple_GET_ITEM(mro, i); + PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(mro, i)); if (base->tp_setattro == slot_tp_setattro) { /* Ignore Python classes: they never define their own C-level setattro. */ @@ -6978,7 +7594,7 @@ wrap_descr_get(PyObject *self, PyObject *args, void *wrapped) obj = NULL; if (type == Py_None) type = NULL; - if (type == NULL &&obj == NULL) { + if (type == NULL && obj == NULL) { PyErr_SetString(PyExc_TypeError, "__get__(None, None) is invalid"); return NULL; @@ -7030,7 +7646,7 @@ wrap_init(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds) static PyObject * tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds) { - PyTypeObject *type, *subtype, *staticbase; + PyTypeObject *staticbase; PyObject *arg0, *res; if (self == NULL || !PyType_Check(self)) { @@ -7038,7 +7654,7 @@ tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds) "__new__() called with non-type 'self'"); return NULL; } - type = (PyTypeObject *)self; + PyTypeObject *type = (PyTypeObject *)self; if (!PyTuple_Check(args) || PyTuple_GET_SIZE(args) < 1) { PyErr_Format(PyExc_TypeError, @@ -7054,7 +7670,8 @@ tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds) Py_TYPE(arg0)->tp_name); return NULL; } - subtype = (PyTypeObject *)arg0; + PyTypeObject *subtype = (PyTypeObject *)arg0; + if (!PyType_IsSubtype(subtype, type)) { PyErr_Format(PyExc_TypeError, "%s.__new__(%s): %s is not a subtype of %s", @@ -7091,7 +7708,7 @@ tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds) } static struct PyMethodDef tp_new_methoddef[] = { - {"__new__", (PyCFunction)(void(*)(void))tp_new_wrapper, METH_VARARGS|METH_KEYWORDS, + {"__new__", _PyCFunction_CAST(tp_new_wrapper), METH_VARARGS|METH_KEYWORDS, PyDoc_STR("__new__($type, *args, **kwargs)\n--\n\n" "Create and return a new object. " "See help(type) for accurate signature.")}, @@ -7101,7 +7718,7 @@ static struct PyMethodDef tp_new_methoddef[] = { static int add_tp_new_wrapper(PyTypeObject *type) { - int r = _PyDict_ContainsId(type->tp_dict, &PyId___new__); + int r = PyDict_Contains(type->tp_dict, &_Py_ID(__new__)); if (r > 0) { return 0; } @@ -7113,7 +7730,7 @@ add_tp_new_wrapper(PyTypeObject *type) if (func == NULL) { return -1; } - r = _PyDict_SetItemId(type->tp_dict, &PyId___new__, func); + r = PyDict_SetItem(type->tp_dict, &_Py_ID(__new__), func); Py_DECREF(func); return r; } @@ -7121,33 +7738,31 @@ add_tp_new_wrapper(PyTypeObject *type) /* Slot wrappers that call the corresponding __foo__ slot. See comments below at override_slots() for more explanation. */ -#define SLOT0(FUNCNAME, OPSTR) \ +#define SLOT0(FUNCNAME, DUNDER) \ static PyObject * \ FUNCNAME(PyObject *self) \ { \ PyObject* stack[1] = {self}; \ - _Py_static_string(id, OPSTR); \ - return vectorcall_method(&id, stack, 1); \ + return vectorcall_method(&_Py_ID(DUNDER), stack, 1); \ } -#define SLOT1(FUNCNAME, OPSTR, ARG1TYPE) \ +#define SLOT1(FUNCNAME, DUNDER, ARG1TYPE) \ static PyObject * \ FUNCNAME(PyObject *self, ARG1TYPE arg1) \ { \ PyObject* stack[2] = {self, arg1}; \ - _Py_static_string(id, OPSTR); \ - return vectorcall_method(&id, stack, 2); \ + return vectorcall_method(&_Py_ID(DUNDER), stack, 2); \ } /* Boolean helper for SLOT1BINFULL(). right.__class__ is a nontrivial subclass of left.__class__. */ static int -method_is_overloaded(PyObject *left, PyObject *right, struct _Py_Identifier *name) +method_is_overloaded(PyObject *left, PyObject *right, PyObject *name) { PyObject *a, *b; int ok; - if (_PyObject_LookupAttrId((PyObject *)(Py_TYPE(right)), name, &b) < 0) { + if (_PyObject_LookupAttr((PyObject *)(Py_TYPE(right)), name, &b) < 0) { return -1; } if (b == NULL) { @@ -7155,7 +7770,7 @@ method_is_overloaded(PyObject *left, PyObject *right, struct _Py_Identifier *nam return 0; } - if (_PyObject_LookupAttrId((PyObject *)(Py_TYPE(left)), name, &a) < 0) { + if (_PyObject_LookupAttr((PyObject *)(Py_TYPE(left)), name, &a) < 0) { Py_DECREF(b); return -1; } @@ -7172,14 +7787,12 @@ method_is_overloaded(PyObject *left, PyObject *right, struct _Py_Identifier *nam } -#define SLOT1BINFULL(FUNCNAME, TESTFUNC, SLOTNAME, OPSTR, ROPSTR) \ +#define SLOT1BINFULL(FUNCNAME, TESTFUNC, SLOTNAME, DUNDER, RDUNDER) \ static PyObject * \ FUNCNAME(PyObject *self, PyObject *other) \ { \ PyObject* stack[2]; \ PyThreadState *tstate = _PyThreadState_GET(); \ - _Py_static_string(op_id, OPSTR); \ - _Py_static_string(rop_id, ROPSTR); \ int do_other = !Py_IS_TYPE(self, Py_TYPE(other)) && \ Py_TYPE(other)->tp_as_number != NULL && \ Py_TYPE(other)->tp_as_number->SLOTNAME == TESTFUNC; \ @@ -7187,14 +7800,14 @@ FUNCNAME(PyObject *self, PyObject *other) \ Py_TYPE(self)->tp_as_number->SLOTNAME == TESTFUNC) { \ PyObject *r; \ if (do_other && PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self))) { \ - int ok = method_is_overloaded(self, other, &rop_id); \ + int ok = method_is_overloaded(self, other, &_Py_ID(RDUNDER)); \ if (ok < 0) { \ return NULL; \ } \ if (ok) { \ stack[0] = other; \ stack[1] = self; \ - r = vectorcall_maybe(tstate, &rop_id, stack, 2); \ + r = vectorcall_maybe(tstate, &_Py_ID(RDUNDER), stack, 2); \ if (r != Py_NotImplemented) \ return r; \ Py_DECREF(r); \ @@ -7203,7 +7816,7 @@ FUNCNAME(PyObject *self, PyObject *other) \ } \ stack[0] = self; \ stack[1] = other; \ - r = vectorcall_maybe(tstate, &op_id, stack, 2); \ + r = vectorcall_maybe(tstate, &_Py_ID(DUNDER), stack, 2); \ if (r != Py_NotImplemented || \ Py_IS_TYPE(other, Py_TYPE(self))) \ return r; \ @@ -7212,19 +7825,19 @@ FUNCNAME(PyObject *self, PyObject *other) \ if (do_other) { \ stack[0] = other; \ stack[1] = self; \ - return vectorcall_maybe(tstate, &rop_id, stack, 2); \ + return vectorcall_maybe(tstate, &_Py_ID(RDUNDER), stack, 2); \ } \ Py_RETURN_NOTIMPLEMENTED; \ } -#define SLOT1BIN(FUNCNAME, SLOTNAME, OPSTR, ROPSTR) \ - SLOT1BINFULL(FUNCNAME, FUNCNAME, SLOTNAME, OPSTR, ROPSTR) +#define SLOT1BIN(FUNCNAME, SLOTNAME, DUNDER, RDUNDER) \ + SLOT1BINFULL(FUNCNAME, FUNCNAME, SLOTNAME, DUNDER, RDUNDER) static Py_ssize_t slot_sq_length(PyObject *self) { PyObject* stack[1] = {self}; - PyObject *res = vectorcall_method(&PyId___len__, stack, 1); + PyObject *res = vectorcall_method(&_Py_ID(__len__), stack, 1); Py_ssize_t len; if (res == NULL) @@ -7256,7 +7869,7 @@ slot_sq_item(PyObject *self, Py_ssize_t i) return NULL; } PyObject *stack[2] = {self, ival}; - PyObject *retval = vectorcall_method(&PyId___getitem__, stack, 2); + PyObject *retval = vectorcall_method(&_Py_ID(__getitem__), stack, 2); Py_DECREF(ival); return retval; } @@ -7276,11 +7889,11 @@ slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value) stack[0] = self; stack[1] = index_obj; if (value == NULL) { - res = vectorcall_method(&PyId___delitem__, stack, 2); + res = vectorcall_method(&_Py_ID(__delitem__), stack, 2); } else { stack[2] = value; - res = vectorcall_method(&PyId___setitem__, stack, 3); + res = vectorcall_method(&_Py_ID(__setitem__), stack, 3); } Py_DECREF(index_obj); @@ -7297,9 +7910,8 @@ slot_sq_contains(PyObject *self, PyObject *value) PyThreadState *tstate = _PyThreadState_GET(); PyObject *func, *res; int result = -1, unbound; - _Py_IDENTIFIER(__contains__); - func = lookup_maybe_method(self, &PyId___contains__, &unbound); + func = lookup_maybe_method(self, &_Py_ID(__contains__), &unbound); if (func == Py_None) { Py_DECREF(func); PyErr_Format(PyExc_TypeError, @@ -7326,7 +7938,7 @@ slot_sq_contains(PyObject *self, PyObject *value) #define slot_mp_length slot_sq_length -SLOT1(slot_mp_subscript, "__getitem__", PyObject *) +SLOT1(slot_mp_subscript, __getitem__, PyObject *) static int slot_mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value) @@ -7337,11 +7949,11 @@ slot_mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value) stack[0] = self; stack[1] = key; if (value == NULL) { - res = vectorcall_method(&PyId___delitem__, stack, 2); + res = vectorcall_method(&_Py_ID(__delitem__), stack, 2); } else { stack[2] = value; - res = vectorcall_method(&PyId___setitem__, stack, 3); + res = vectorcall_method(&_Py_ID(__setitem__), stack, 3); } if (res == NULL) @@ -7350,23 +7962,20 @@ slot_mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value) return 0; } -SLOT1BIN(slot_nb_add, nb_add, "__add__", "__radd__") -SLOT1BIN(slot_nb_subtract, nb_subtract, "__sub__", "__rsub__") -SLOT1BIN(slot_nb_multiply, nb_multiply, "__mul__", "__rmul__") -SLOT1BIN(slot_nb_matrix_multiply, nb_matrix_multiply, "__matmul__", "__rmatmul__") -SLOT1BIN(slot_nb_remainder, nb_remainder, "__mod__", "__rmod__") -SLOT1BIN(slot_nb_divmod, nb_divmod, "__divmod__", "__rdivmod__") +SLOT1BIN(slot_nb_add, nb_add, __add__, __radd__) +SLOT1BIN(slot_nb_subtract, nb_subtract, __sub__, __rsub__) +SLOT1BIN(slot_nb_multiply, nb_multiply, __mul__, __rmul__) +SLOT1BIN(slot_nb_matrix_multiply, nb_matrix_multiply, __matmul__, __rmatmul__) +SLOT1BIN(slot_nb_remainder, nb_remainder, __mod__, __rmod__) +SLOT1BIN(slot_nb_divmod, nb_divmod, __divmod__, __rdivmod__) static PyObject *slot_nb_power(PyObject *, PyObject *, PyObject *); -SLOT1BINFULL(slot_nb_power_binary, slot_nb_power, - nb_power, "__pow__", "__rpow__") +SLOT1BINFULL(slot_nb_power_binary, slot_nb_power, nb_power, __pow__, __rpow__) static PyObject * slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus) { - _Py_IDENTIFIER(__pow__); - if (modulus == Py_None) return slot_nb_power_binary(self, other); /* Three-arg power doesn't use __rpow__. But ternary_op @@ -7375,14 +7984,14 @@ slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus) if (Py_TYPE(self)->tp_as_number != NULL && Py_TYPE(self)->tp_as_number->nb_power == slot_nb_power) { PyObject* stack[3] = {self, other, modulus}; - return vectorcall_method(&PyId___pow__, stack, 3); + return vectorcall_method(&_Py_ID(__pow__), stack, 3); } Py_RETURN_NOTIMPLEMENTED; } -SLOT0(slot_nb_negative, "__neg__") -SLOT0(slot_nb_positive, "__pos__") -SLOT0(slot_nb_absolute, "__abs__") +SLOT0(slot_nb_negative, __neg__) +SLOT0(slot_nb_positive, __pos__) +SLOT0(slot_nb_absolute, __abs__) static int slot_nb_bool(PyObject *self) @@ -7390,15 +7999,14 @@ slot_nb_bool(PyObject *self) PyObject *func, *value; int result, unbound; int using_len = 0; - _Py_IDENTIFIER(__bool__); - func = lookup_maybe_method(self, &PyId___bool__, &unbound); + func = lookup_maybe_method(self, &_Py_ID(__bool__), &unbound); if (func == NULL) { if (PyErr_Occurred()) { return -1; } - func = lookup_maybe_method(self, &PyId___len__, &unbound); + func = lookup_maybe_method(self, &_Py_ID(__len__), &unbound); if (func == NULL) { if (PyErr_Occurred()) { return -1; @@ -7441,53 +8049,50 @@ error: static PyObject * slot_nb_index(PyObject *self) { - _Py_IDENTIFIER(__index__); PyObject *stack[1] = {self}; - return vectorcall_method(&PyId___index__, stack, 1); + return vectorcall_method(&_Py_ID(__index__), stack, 1); } -SLOT0(slot_nb_invert, "__invert__") -SLOT1BIN(slot_nb_lshift, nb_lshift, "__lshift__", "__rlshift__") -SLOT1BIN(slot_nb_rshift, nb_rshift, "__rshift__", "__rrshift__") -SLOT1BIN(slot_nb_and, nb_and, "__and__", "__rand__") -SLOT1BIN(slot_nb_xor, nb_xor, "__xor__", "__rxor__") -SLOT1BIN(slot_nb_or, nb_or, "__or__", "__ror__") +SLOT0(slot_nb_invert, __invert__) +SLOT1BIN(slot_nb_lshift, nb_lshift, __lshift__, __rlshift__) +SLOT1BIN(slot_nb_rshift, nb_rshift, __rshift__, __rrshift__) +SLOT1BIN(slot_nb_and, nb_and, __and__, __rand__) +SLOT1BIN(slot_nb_xor, nb_xor, __xor__, __rxor__) +SLOT1BIN(slot_nb_or, nb_or, __or__, __ror__) -SLOT0(slot_nb_int, "__int__") -SLOT0(slot_nb_float, "__float__") -SLOT1(slot_nb_inplace_add, "__iadd__", PyObject *) -SLOT1(slot_nb_inplace_subtract, "__isub__", PyObject *) -SLOT1(slot_nb_inplace_multiply, "__imul__", PyObject *) -SLOT1(slot_nb_inplace_matrix_multiply, "__imatmul__", PyObject *) -SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject *) +SLOT0(slot_nb_int, __int__) +SLOT0(slot_nb_float, __float__) +SLOT1(slot_nb_inplace_add, __iadd__, PyObject *) +SLOT1(slot_nb_inplace_subtract, __isub__, PyObject *) +SLOT1(slot_nb_inplace_multiply, __imul__, PyObject *) +SLOT1(slot_nb_inplace_matrix_multiply, __imatmul__, PyObject *) +SLOT1(slot_nb_inplace_remainder, __imod__, PyObject *) /* Can't use SLOT1 here, because nb_inplace_power is ternary */ static PyObject * slot_nb_inplace_power(PyObject *self, PyObject * arg1, PyObject *arg2) { PyObject *stack[2] = {self, arg1}; - _Py_IDENTIFIER(__ipow__); - return vectorcall_method(&PyId___ipow__, stack, 2); + return vectorcall_method(&_Py_ID(__ipow__), stack, 2); } -SLOT1(slot_nb_inplace_lshift, "__ilshift__", PyObject *) -SLOT1(slot_nb_inplace_rshift, "__irshift__", PyObject *) -SLOT1(slot_nb_inplace_and, "__iand__", PyObject *) -SLOT1(slot_nb_inplace_xor, "__ixor__", PyObject *) -SLOT1(slot_nb_inplace_or, "__ior__", PyObject *) +SLOT1(slot_nb_inplace_lshift, __ilshift__, PyObject *) +SLOT1(slot_nb_inplace_rshift, __irshift__, PyObject *) +SLOT1(slot_nb_inplace_and, __iand__, PyObject *) +SLOT1(slot_nb_inplace_xor, __ixor__, PyObject *) +SLOT1(slot_nb_inplace_or, __ior__, PyObject *) SLOT1BIN(slot_nb_floor_divide, nb_floor_divide, - "__floordiv__", "__rfloordiv__") -SLOT1BIN(slot_nb_true_divide, nb_true_divide, "__truediv__", "__rtruediv__") -SLOT1(slot_nb_inplace_floor_divide, "__ifloordiv__", PyObject *) -SLOT1(slot_nb_inplace_true_divide, "__itruediv__", PyObject *) + __floordiv__, __rfloordiv__) +SLOT1BIN(slot_nb_true_divide, nb_true_divide, __truediv__, __rtruediv__) +SLOT1(slot_nb_inplace_floor_divide, __ifloordiv__, PyObject *) +SLOT1(slot_nb_inplace_true_divide, __itruediv__, PyObject *) static PyObject * slot_tp_repr(PyObject *self) { PyObject *func, *res; - _Py_IDENTIFIER(__repr__); int unbound; - func = lookup_maybe_method(self, &PyId___repr__, &unbound); + func = lookup_maybe_method(self, &_Py_ID(__repr__), &unbound); if (func != NULL) { res = call_unbound_noarg(unbound, func, self); Py_DECREF(func); @@ -7498,7 +8103,7 @@ slot_tp_repr(PyObject *self) Py_TYPE(self)->tp_name, self); } -SLOT0(slot_tp_str, "__str__") +SLOT0(slot_tp_str, __str__) static Py_hash_t slot_tp_hash(PyObject *self) @@ -7507,11 +8112,10 @@ slot_tp_hash(PyObject *self) Py_ssize_t h; int unbound; - func = lookup_maybe_method(self, &PyId___hash__, &unbound); + func = lookup_maybe_method(self, &_Py_ID(__hash__), &unbound); if (func == Py_None) { - Py_DECREF(func); - func = NULL; + Py_SETREF(func, NULL); } if (func == NULL) { @@ -7552,10 +8156,9 @@ static PyObject * slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds) { PyThreadState *tstate = _PyThreadState_GET(); - _Py_IDENTIFIER(__call__); int unbound; - PyObject *meth = lookup_method(self, &PyId___call__, &unbound); + PyObject *meth = lookup_method(self, &_Py_ID(__call__), &unbound); if (meth == NULL) { return NULL; } @@ -7574,26 +8177,33 @@ slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds) /* There are two slot dispatch functions for tp_getattro. - - slot_tp_getattro() is used when __getattribute__ is overridden + - _Py_slot_tp_getattro() is used when __getattribute__ is overridden but no __getattr__ hook is present; - - slot_tp_getattr_hook() is used when a __getattr__ hook is present. + - _Py_slot_tp_getattr_hook() is used when a __getattr__ hook is present. - The code in update_one_slot() always installs slot_tp_getattr_hook(); this - detects the absence of __getattr__ and then installs the simpler slot if - necessary. */ + The code in update_one_slot() always installs _Py_slot_tp_getattr_hook(); + this detects the absence of __getattr__ and then installs the simpler + slot if necessary. */ -static PyObject * -slot_tp_getattro(PyObject *self, PyObject *name) +PyObject * +_Py_slot_tp_getattro(PyObject *self, PyObject *name) { PyObject *stack[2] = {self, name}; - return vectorcall_method(&PyId___getattribute__, stack, 2); + return vectorcall_method(&_Py_ID(__getattribute__), stack, 2); } -static PyObject * +static inline PyObject * call_attribute(PyObject *self, PyObject *attr, PyObject *name) { PyObject *res, *descr = NULL; + + if (_PyType_HasFeature(Py_TYPE(attr), Py_TPFLAGS_METHOD_DESCRIPTOR)) { + PyObject *args[] = { self, name }; + res = PyObject_Vectorcall(attr, args, 2, NULL); + return res; + } + descrgetfunc f = Py_TYPE(attr)->tp_descr_get; if (f != NULL) { @@ -7608,23 +8218,22 @@ call_attribute(PyObject *self, PyObject *attr, PyObject *name) return res; } -static PyObject * -slot_tp_getattr_hook(PyObject *self, PyObject *name) +PyObject * +_Py_slot_tp_getattr_hook(PyObject *self, PyObject *name) { PyTypeObject *tp = Py_TYPE(self); PyObject *getattr, *getattribute, *res; - _Py_IDENTIFIER(__getattr__); /* speed hack: we could use lookup_maybe, but that would resolve the method fully for each attribute lookup for classes with __getattr__, even when the attribute is present. So we use _PyType_Lookup and create the method only when needed, with call_attribute. */ - getattr = _PyType_LookupId(tp, &PyId___getattr__); + getattr = _PyType_Lookup(tp, &_Py_ID(__getattr__)); if (getattr == NULL) { /* No __getattr__ hook: use a simpler dispatcher */ - tp->tp_getattro = slot_tp_getattro; - return slot_tp_getattro(self, name); + tp->tp_getattro = _Py_slot_tp_getattro; + return _Py_slot_tp_getattro(self, name); } Py_INCREF(getattr); /* speed hack: we could use lookup_maybe, but that would resolve the @@ -7632,7 +8241,7 @@ slot_tp_getattr_hook(PyObject *self, PyObject *name) __getattr__, even when self has the default __getattribute__ method. So we use _PyType_Lookup and create the method only when needed, with call_attribute. */ - getattribute = _PyType_LookupId(tp, &PyId___getattribute__); + getattribute = _PyType_Lookup(tp, &_Py_ID(__getattribute__)); if (getattribute == NULL || (Py_IS_TYPE(getattribute, &PyWrapperDescr_Type) && ((PyWrapperDescrObject *)getattribute)->d_wrapped == @@ -7656,17 +8265,15 @@ slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value) { PyObject *stack[3]; PyObject *res; - _Py_IDENTIFIER(__delattr__); - _Py_IDENTIFIER(__setattr__); stack[0] = self; stack[1] = name; if (value == NULL) { - res = vectorcall_method(&PyId___delattr__, stack, 2); + res = vectorcall_method(&_Py_ID(__delattr__), stack, 2); } else { stack[2] = value; - res = vectorcall_method(&PyId___setattr__, stack, 3); + res = vectorcall_method(&_Py_ID(__setattr__), stack, 3); } if (res == NULL) return -1; @@ -7674,13 +8281,13 @@ slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value) return 0; } -static _Py_Identifier name_op[] = { - _Py_static_string_init("__lt__"), - _Py_static_string_init("__le__"), - _Py_static_string_init("__eq__"), - _Py_static_string_init("__ne__"), - _Py_static_string_init("__gt__"), - _Py_static_string_init("__ge__"), +static PyObject *name_op[] = { + &_Py_ID(__lt__), + &_Py_ID(__le__), + &_Py_ID(__eq__), + &_Py_ID(__ne__), + &_Py_ID(__gt__), + &_Py_ID(__ge__), }; static PyObject * @@ -7689,7 +8296,7 @@ slot_tp_richcompare(PyObject *self, PyObject *other, int op) PyThreadState *tstate = _PyThreadState_GET(); int unbound; - PyObject *func = lookup_maybe_method(self, &name_op[op], &unbound); + PyObject *func = lookup_maybe_method(self, name_op[op], &unbound); if (func == NULL) { PyErr_Clear(); Py_RETURN_NOTIMPLEMENTED; @@ -7706,9 +8313,8 @@ slot_tp_iter(PyObject *self) { int unbound; PyObject *func, *res; - _Py_IDENTIFIER(__iter__); - func = lookup_maybe_method(self, &PyId___iter__, &unbound); + func = lookup_maybe_method(self, &_Py_ID(__iter__), &unbound); if (func == Py_None) { Py_DECREF(func); PyErr_Format(PyExc_TypeError, @@ -7724,7 +8330,7 @@ slot_tp_iter(PyObject *self) } PyErr_Clear(); - func = lookup_maybe_method(self, &PyId___getitem__, &unbound); + func = lookup_maybe_method(self, &_Py_ID(__getitem__), &unbound); if (func == NULL) { PyErr_Format(PyExc_TypeError, "'%.200s' object is not iterable", @@ -7738,9 +8344,8 @@ slot_tp_iter(PyObject *self) static PyObject * slot_tp_iternext(PyObject *self) { - _Py_IDENTIFIER(__next__); PyObject *stack[1] = {self}; - return vectorcall_method(&PyId___next__, stack, 1); + return vectorcall_method(&_Py_ID(__next__), stack, 1); } static PyObject * @@ -7748,21 +8353,20 @@ slot_tp_descr_get(PyObject *self, PyObject *obj, PyObject *type) { PyTypeObject *tp = Py_TYPE(self); PyObject *get; - _Py_IDENTIFIER(__get__); - get = _PyType_LookupId(tp, &PyId___get__); + get = _PyType_Lookup(tp, &_Py_ID(__get__)); if (get == NULL) { /* Avoid further slowdowns */ if (tp->tp_descr_get == slot_tp_descr_get) tp->tp_descr_get = NULL; - Py_INCREF(self); - return self; + return Py_NewRef(self); } if (obj == NULL) obj = Py_None; if (type == NULL) type = Py_None; - return PyObject_CallFunctionObjArgs(get, self, obj, type, NULL); + PyObject *stack[3] = {self, obj, type}; + return PyObject_Vectorcall(get, stack, 3, NULL); } static int @@ -7770,17 +8374,15 @@ slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value) { PyObject* stack[3]; PyObject *res; - _Py_IDENTIFIER(__delete__); - _Py_IDENTIFIER(__set__); stack[0] = self; stack[1] = target; if (value == NULL) { - res = vectorcall_method(&PyId___delete__, stack, 2); + res = vectorcall_method(&_Py_ID(__delete__), stack, 2); } else { stack[2] = value; - res = vectorcall_method(&PyId___set__, stack, 3); + res = vectorcall_method(&_Py_ID(__set__), stack, 3); } if (res == NULL) return -1; @@ -7793,9 +8395,8 @@ slot_tp_init(PyObject *self, PyObject *args, PyObject *kwds) { PyThreadState *tstate = _PyThreadState_GET(); - _Py_IDENTIFIER(__init__); int unbound; - PyObject *meth = lookup_method(self, &PyId___init__, &unbound); + PyObject *meth = lookup_method(self, &_Py_ID(__init__), &unbound); if (meth == NULL) { return -1; } @@ -7827,7 +8428,7 @@ slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyThreadState *tstate = _PyThreadState_GET(); PyObject *func, *result; - func = _PyObject_GetAttrId((PyObject *)type, &PyId___new__); + func = PyObject_GetAttr((PyObject *)type, &_Py_ID(__new__)); if (func == NULL) { return NULL; } @@ -7840,7 +8441,6 @@ slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static void slot_tp_finalize(PyObject *self) { - _Py_IDENTIFIER(__del__); int unbound; PyObject *del, *res; PyObject *error_type, *error_value, *error_traceback; @@ -7849,7 +8449,7 @@ slot_tp_finalize(PyObject *self) PyErr_Fetch(&error_type, &error_value, &error_traceback); /* Execute __del__ method, if any. */ - del = lookup_maybe_method(self, &PyId___del__, &unbound); + del = lookup_maybe_method(self, &_Py_ID(__del__), &unbound); if (del != NULL) { res = call_unbound_noarg(unbound, del, self); if (res == NULL) @@ -7868,9 +8468,8 @@ slot_am_await(PyObject *self) { int unbound; PyObject *func, *res; - _Py_IDENTIFIER(__await__); - func = lookup_maybe_method(self, &PyId___await__, &unbound); + func = lookup_maybe_method(self, &_Py_ID(__await__), &unbound); if (func != NULL) { res = call_unbound_noarg(unbound, func, self); Py_DECREF(func); @@ -7887,9 +8486,8 @@ slot_am_aiter(PyObject *self) { int unbound; PyObject *func, *res; - _Py_IDENTIFIER(__aiter__); - func = lookup_maybe_method(self, &PyId___aiter__, &unbound); + func = lookup_maybe_method(self, &_Py_ID(__aiter__), &unbound); if (func != NULL) { res = call_unbound_noarg(unbound, func, self); Py_DECREF(func); @@ -7906,9 +8504,8 @@ slot_am_anext(PyObject *self) { int unbound; PyObject *func, *res; - _Py_IDENTIFIER(__anext__); - func = lookup_maybe_method(self, &PyId___anext__, &unbound); + func = lookup_maybe_method(self, &_Py_ID(__anext__), &unbound); if (func != NULL) { res = call_unbound_noarg(unbound, func, self); Py_DECREF(func); @@ -7928,12 +8525,9 @@ which incorporates the additional structures used for numbers, sequences and mappings. Note that multiple names may map to the same slot (e.g. __eq__, __ne__ etc. all map to tp_richcompare) and one name may map to multiple slots (e.g. __str__ affects tp_str as well as tp_repr). The table is terminated with -an all-zero entry. (This table is further initialized in -_PyTypes_InitSlotDefs().) +an all-zero entry. */ -typedef struct wrapperbase slotdef; - #undef TPSLOT #undef FLSLOT #undef AMSLOT @@ -7947,14 +8541,14 @@ typedef struct wrapperbase slotdef; #undef RBINSLOT #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ - {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ - PyDoc_STR(DOC)} + {#NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ + PyDoc_STR(DOC), .name_strobj = &_Py_ID(NAME)} #define FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS) \ - {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ - PyDoc_STR(DOC), FLAGS} + {#NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ + PyDoc_STR(DOC), FLAGS, .name_strobj = &_Py_ID(NAME) } #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ - {NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ - PyDoc_STR(DOC)} + {#NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ + PyDoc_STR(DOC), .name_strobj = &_Py_ID(NAME) } #define AMSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ETSLOT(NAME, as_async.SLOT, FUNCTION, WRAPPER, DOC) #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ @@ -7965,204 +8559,204 @@ typedef struct wrapperbase slotdef; ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC) #define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ - NAME "($self, /)\n--\n\n" DOC) + #NAME "($self, /)\n--\n\n" DOC) #define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ - NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") + #NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") #define BINSLOT(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ - NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") + #NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") #define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ - NAME "($self, value, /)\n--\n\nReturn value" DOC "self.") + #NAME "($self, value, /)\n--\n\nReturn value" DOC "self.") #define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ - NAME "($self, value, /)\n--\n\n" DOC) + #NAME "($self, value, /)\n--\n\n" DOC) #define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ - NAME "($self, value, /)\n--\n\n" DOC) + #NAME "($self, value, /)\n--\n\n" DOC) -static slotdef slotdefs[] = { - TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""), - TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""), - TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""), - TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""), - TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc, +static pytype_slotdef slotdefs[] = { + TPSLOT(__getattribute__, tp_getattr, NULL, NULL, ""), + TPSLOT(__getattr__, tp_getattr, NULL, NULL, ""), + TPSLOT(__setattr__, tp_setattr, NULL, NULL, ""), + TPSLOT(__delattr__, tp_setattr, NULL, NULL, ""), + TPSLOT(__repr__, tp_repr, slot_tp_repr, wrap_unaryfunc, "__repr__($self, /)\n--\n\nReturn repr(self)."), - TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc, + TPSLOT(__hash__, tp_hash, slot_tp_hash, wrap_hashfunc, "__hash__($self, /)\n--\n\nReturn hash(self)."), - FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)(void(*)(void))wrap_call, + FLSLOT(__call__, tp_call, slot_tp_call, (wrapperfunc)(void(*)(void))wrap_call, "__call__($self, /, *args, **kwargs)\n--\n\nCall self as a function.", PyWrapperFlag_KEYWORDS), - TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc, + TPSLOT(__str__, tp_str, slot_tp_str, wrap_unaryfunc, "__str__($self, /)\n--\n\nReturn str(self)."), - TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, + TPSLOT(__getattribute__, tp_getattro, _Py_slot_tp_getattr_hook, wrap_binaryfunc, "__getattribute__($self, name, /)\n--\n\nReturn getattr(self, name)."), - TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""), - TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr, + TPSLOT(__getattr__, tp_getattro, _Py_slot_tp_getattr_hook, NULL, ""), + TPSLOT(__setattr__, tp_setattro, slot_tp_setattro, wrap_setattr, "__setattr__($self, name, value, /)\n--\n\nImplement setattr(self, name, value)."), - TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr, + TPSLOT(__delattr__, tp_setattro, slot_tp_setattro, wrap_delattr, "__delattr__($self, name, /)\n--\n\nImplement delattr(self, name)."), - TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt, + TPSLOT(__lt__, tp_richcompare, slot_tp_richcompare, richcmp_lt, "__lt__($self, value, /)\n--\n\nReturn selfvalue."), - TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge, + TPSLOT(__ge__, tp_richcompare, slot_tp_richcompare, richcmp_ge, "__ge__($self, value, /)\n--\n\nReturn self>=value."), - TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc, + TPSLOT(__iter__, tp_iter, slot_tp_iter, wrap_unaryfunc, "__iter__($self, /)\n--\n\nImplement iter(self)."), - TPSLOT("__next__", tp_iternext, slot_tp_iternext, wrap_next, + TPSLOT(__next__, tp_iternext, slot_tp_iternext, wrap_next, "__next__($self, /)\n--\n\nImplement next(self)."), - TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get, - "__get__($self, instance, owner, /)\n--\n\nReturn an attribute of instance, which is of type owner."), - TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set, + TPSLOT(__get__, tp_descr_get, slot_tp_descr_get, wrap_descr_get, + "__get__($self, instance, owner=None, /)\n--\n\nReturn an attribute of instance, which is of type owner."), + TPSLOT(__set__, tp_descr_set, slot_tp_descr_set, wrap_descr_set, "__set__($self, instance, value, /)\n--\n\nSet an attribute of instance to value."), - TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set, + TPSLOT(__delete__, tp_descr_set, slot_tp_descr_set, wrap_descr_delete, "__delete__($self, instance, /)\n--\n\nDelete an attribute of instance."), - FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)(void(*)(void))wrap_init, + FLSLOT(__init__, tp_init, slot_tp_init, (wrapperfunc)(void(*)(void))wrap_init, "__init__($self, /, *args, **kwargs)\n--\n\n" "Initialize self. See help(type(self)) for accurate signature.", PyWrapperFlag_KEYWORDS), - TPSLOT("__new__", tp_new, slot_tp_new, NULL, + TPSLOT(__new__, tp_new, slot_tp_new, NULL, "__new__(type, /, *args, **kwargs)\n--\n\n" "Create and return new object. See help(type) for accurate signature."), - TPSLOT("__del__", tp_finalize, slot_tp_finalize, (wrapperfunc)wrap_del, ""), + TPSLOT(__del__, tp_finalize, slot_tp_finalize, (wrapperfunc)wrap_del, ""), - AMSLOT("__await__", am_await, slot_am_await, wrap_unaryfunc, + AMSLOT(__await__, am_await, slot_am_await, wrap_unaryfunc, "__await__($self, /)\n--\n\nReturn an iterator to be used in await expression."), - AMSLOT("__aiter__", am_aiter, slot_am_aiter, wrap_unaryfunc, + AMSLOT(__aiter__, am_aiter, slot_am_aiter, wrap_unaryfunc, "__aiter__($self, /)\n--\n\nReturn an awaitable, that resolves in asynchronous iterator."), - AMSLOT("__anext__", am_anext, slot_am_anext, wrap_unaryfunc, + AMSLOT(__anext__, am_anext, slot_am_anext, wrap_unaryfunc, "__anext__($self, /)\n--\n\nReturn a value or raise StopAsyncIteration."), - BINSLOT("__add__", nb_add, slot_nb_add, + BINSLOT(__add__, nb_add, slot_nb_add, "+"), - RBINSLOT("__radd__", nb_add, slot_nb_add, + RBINSLOT(__radd__, nb_add, slot_nb_add, "+"), - BINSLOT("__sub__", nb_subtract, slot_nb_subtract, + BINSLOT(__sub__, nb_subtract, slot_nb_subtract, "-"), - RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract, + RBINSLOT(__rsub__, nb_subtract, slot_nb_subtract, "-"), - BINSLOT("__mul__", nb_multiply, slot_nb_multiply, + BINSLOT(__mul__, nb_multiply, slot_nb_multiply, "*"), - RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply, + RBINSLOT(__rmul__, nb_multiply, slot_nb_multiply, "*"), - BINSLOT("__mod__", nb_remainder, slot_nb_remainder, + BINSLOT(__mod__, nb_remainder, slot_nb_remainder, "%"), - RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder, + RBINSLOT(__rmod__, nb_remainder, slot_nb_remainder, "%"), - BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod, + BINSLOTNOTINFIX(__divmod__, nb_divmod, slot_nb_divmod, "Return divmod(self, value)."), - RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod, + RBINSLOTNOTINFIX(__rdivmod__, nb_divmod, slot_nb_divmod, "Return divmod(value, self)."), - NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc, + NBSLOT(__pow__, nb_power, slot_nb_power, wrap_ternaryfunc, "__pow__($self, value, mod=None, /)\n--\n\nReturn pow(self, value, mod)."), - NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r, + NBSLOT(__rpow__, nb_power, slot_nb_power, wrap_ternaryfunc_r, "__rpow__($self, value, mod=None, /)\n--\n\nReturn pow(value, self, mod)."), - UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-self"), - UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+self"), - UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc, + UNSLOT(__neg__, nb_negative, slot_nb_negative, wrap_unaryfunc, "-self"), + UNSLOT(__pos__, nb_positive, slot_nb_positive, wrap_unaryfunc, "+self"), + UNSLOT(__abs__, nb_absolute, slot_nb_absolute, wrap_unaryfunc, "abs(self)"), - UNSLOT("__bool__", nb_bool, slot_nb_bool, wrap_inquirypred, - "self != 0"), - UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~self"), - BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"), - RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"), - BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"), - RBINSLOT("__rrshift__", nb_rshift, slot_nb_rshift, ">>"), - BINSLOT("__and__", nb_and, slot_nb_and, "&"), - RBINSLOT("__rand__", nb_and, slot_nb_and, "&"), - BINSLOT("__xor__", nb_xor, slot_nb_xor, "^"), - RBINSLOT("__rxor__", nb_xor, slot_nb_xor, "^"), - BINSLOT("__or__", nb_or, slot_nb_or, "|"), - RBINSLOT("__ror__", nb_or, slot_nb_or, "|"), - UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc, + UNSLOT(__bool__, nb_bool, slot_nb_bool, wrap_inquirypred, + "True if self else False"), + UNSLOT(__invert__, nb_invert, slot_nb_invert, wrap_unaryfunc, "~self"), + BINSLOT(__lshift__, nb_lshift, slot_nb_lshift, "<<"), + RBINSLOT(__rlshift__, nb_lshift, slot_nb_lshift, "<<"), + BINSLOT(__rshift__, nb_rshift, slot_nb_rshift, ">>"), + RBINSLOT(__rrshift__, nb_rshift, slot_nb_rshift, ">>"), + BINSLOT(__and__, nb_and, slot_nb_and, "&"), + RBINSLOT(__rand__, nb_and, slot_nb_and, "&"), + BINSLOT(__xor__, nb_xor, slot_nb_xor, "^"), + RBINSLOT(__rxor__, nb_xor, slot_nb_xor, "^"), + BINSLOT(__or__, nb_or, slot_nb_or, "|"), + RBINSLOT(__ror__, nb_or, slot_nb_or, "|"), + UNSLOT(__int__, nb_int, slot_nb_int, wrap_unaryfunc, "int(self)"), - UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc, + UNSLOT(__float__, nb_float, slot_nb_float, wrap_unaryfunc, "float(self)"), - IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, + IBSLOT(__iadd__, nb_inplace_add, slot_nb_inplace_add, wrap_binaryfunc, "+="), - IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract, + IBSLOT(__isub__, nb_inplace_subtract, slot_nb_inplace_subtract, wrap_binaryfunc, "-="), - IBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply, + IBSLOT(__imul__, nb_inplace_multiply, slot_nb_inplace_multiply, wrap_binaryfunc, "*="), - IBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder, + IBSLOT(__imod__, nb_inplace_remainder, slot_nb_inplace_remainder, wrap_binaryfunc, "%="), - IBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power, + IBSLOT(__ipow__, nb_inplace_power, slot_nb_inplace_power, wrap_ternaryfunc, "**="), - IBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift, + IBSLOT(__ilshift__, nb_inplace_lshift, slot_nb_inplace_lshift, wrap_binaryfunc, "<<="), - IBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift, + IBSLOT(__irshift__, nb_inplace_rshift, slot_nb_inplace_rshift, wrap_binaryfunc, ">>="), - IBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and, + IBSLOT(__iand__, nb_inplace_and, slot_nb_inplace_and, wrap_binaryfunc, "&="), - IBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor, + IBSLOT(__ixor__, nb_inplace_xor, slot_nb_inplace_xor, wrap_binaryfunc, "^="), - IBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or, + IBSLOT(__ior__, nb_inplace_or, slot_nb_inplace_or, wrap_binaryfunc, "|="), - BINSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide, "//"), - RBINSLOT("__rfloordiv__", nb_floor_divide, slot_nb_floor_divide, "//"), - BINSLOT("__truediv__", nb_true_divide, slot_nb_true_divide, "/"), - RBINSLOT("__rtruediv__", nb_true_divide, slot_nb_true_divide, "/"), - IBSLOT("__ifloordiv__", nb_inplace_floor_divide, + BINSLOT(__floordiv__, nb_floor_divide, slot_nb_floor_divide, "//"), + RBINSLOT(__rfloordiv__, nb_floor_divide, slot_nb_floor_divide, "//"), + BINSLOT(__truediv__, nb_true_divide, slot_nb_true_divide, "/"), + RBINSLOT(__rtruediv__, nb_true_divide, slot_nb_true_divide, "/"), + IBSLOT(__ifloordiv__, nb_inplace_floor_divide, slot_nb_inplace_floor_divide, wrap_binaryfunc, "//="), - IBSLOT("__itruediv__", nb_inplace_true_divide, + IBSLOT(__itruediv__, nb_inplace_true_divide, slot_nb_inplace_true_divide, wrap_binaryfunc, "/="), - NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, + NBSLOT(__index__, nb_index, slot_nb_index, wrap_unaryfunc, "__index__($self, /)\n--\n\n" "Return self converted to an integer, if self is suitable " "for use as an index into a list."), - BINSLOT("__matmul__", nb_matrix_multiply, slot_nb_matrix_multiply, + BINSLOT(__matmul__, nb_matrix_multiply, slot_nb_matrix_multiply, "@"), - RBINSLOT("__rmatmul__", nb_matrix_multiply, slot_nb_matrix_multiply, + RBINSLOT(__rmatmul__, nb_matrix_multiply, slot_nb_matrix_multiply, "@"), - IBSLOT("__imatmul__", nb_inplace_matrix_multiply, slot_nb_inplace_matrix_multiply, + IBSLOT(__imatmul__, nb_inplace_matrix_multiply, slot_nb_inplace_matrix_multiply, wrap_binaryfunc, "@="), - MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc, + MPSLOT(__len__, mp_length, slot_mp_length, wrap_lenfunc, "__len__($self, /)\n--\n\nReturn len(self)."), - MPSLOT("__getitem__", mp_subscript, slot_mp_subscript, + MPSLOT(__getitem__, mp_subscript, slot_mp_subscript, wrap_binaryfunc, "__getitem__($self, key, /)\n--\n\nReturn self[key]."), - MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript, + MPSLOT(__setitem__, mp_ass_subscript, slot_mp_ass_subscript, wrap_objobjargproc, "__setitem__($self, key, value, /)\n--\n\nSet self[key] to value."), - MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript, + MPSLOT(__delitem__, mp_ass_subscript, slot_mp_ass_subscript, wrap_delitem, "__delitem__($self, key, /)\n--\n\nDelete self[key]."), - SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc, + SQSLOT(__len__, sq_length, slot_sq_length, wrap_lenfunc, "__len__($self, /)\n--\n\nReturn len(self)."), /* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL. The logic in abstract.c always falls back to nb_add/nb_multiply in this case. Defining both the nb_* and the sq_* slots to call the user-defined methods has unexpected side-effects, as shown by test_descr.notimplemented() */ - SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc, + SQSLOT(__add__, sq_concat, NULL, wrap_binaryfunc, "__add__($self, value, /)\n--\n\nReturn self+value."), - SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc, + SQSLOT(__mul__, sq_repeat, NULL, wrap_indexargfunc, "__mul__($self, value, /)\n--\n\nReturn self*value."), - SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc, + SQSLOT(__rmul__, sq_repeat, NULL, wrap_indexargfunc, "__rmul__($self, value, /)\n--\n\nReturn value*self."), - SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item, + SQSLOT(__getitem__, sq_item, slot_sq_item, wrap_sq_item, "__getitem__($self, key, /)\n--\n\nReturn self[key]."), - SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, + SQSLOT(__setitem__, sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, "__setitem__($self, key, value, /)\n--\n\nSet self[key] to value."), - SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem, + SQSLOT(__delitem__, sq_ass_item, slot_sq_ass_item, wrap_sq_delitem, "__delitem__($self, key, /)\n--\n\nDelete self[key]."), - SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc, - "__contains__($self, key, /)\n--\n\nReturn key in self."), - SQSLOT("__iadd__", sq_inplace_concat, NULL, + SQSLOT(__contains__, sq_contains, slot_sq_contains, wrap_objobjproc, + "__contains__($self, key, /)\n--\n\nReturn bool(key in self)."), + SQSLOT(__iadd__, sq_inplace_concat, NULL, wrap_binaryfunc, "__iadd__($self, value, /)\n--\n\nImplement self+=value."), - SQSLOT("__imul__", sq_inplace_repeat, NULL, + SQSLOT(__imul__, sq_inplace_repeat, NULL, wrap_indexargfunc, "__imul__($self, value, /)\n--\n\nImplement self*=value."), @@ -8207,12 +8801,6 @@ slotptr(PyTypeObject *type, int ioffset) return (void **)ptr; } -/* Length of array of slotdef pointers used to store slots with the - same __name__. There should be at most MAX_EQUIV-1 slotdef entries with - the same __name__, for any __name__. Since that's a static property, it is - appropriate to declare fixed-size arrays for this. */ -#define MAX_EQUIV 10 - /* Return a slot pointer for a given name, but ONLY if the attribute has exactly one slot function. The name must be an interned string. */ static void ** @@ -8221,9 +8809,10 @@ resolve_slotdups(PyTypeObject *type, PyObject *name) /* XXX Maybe this could be optimized more -- but is it worth it? */ /* pname and ptrs act as a little cache */ - static PyObject *pname; - static slotdef *ptrs[MAX_EQUIV]; - slotdef *p, **pp; + PyInterpreterState *interp = _PyInterpreterState_Get(); +#define pname _Py_INTERP_CACHED_OBJECT(interp, type_slots_pname) +#define ptrs _Py_INTERP_CACHED_OBJECT(interp, type_slots_ptrs) + pytype_slotdef *p, **pp; void **res, **ptr; if (pname != name) { @@ -8250,6 +8839,8 @@ resolve_slotdups(PyTypeObject *type, PyObject *name) res = ptr; } return res; +#undef pname +#undef ptrs } @@ -8307,13 +8898,22 @@ resolve_slotdups(PyTypeObject *type, PyObject *name) * When done, return a pointer to the next slotdef with a different offset, * because that's convenient for fixup_slot_dispatchers(). This function never * sets an exception: if an internal error happens (unlikely), it's ignored. */ -static slotdef * -update_one_slot(PyTypeObject *type, slotdef *p) +static pytype_slotdef * +update_one_slot(PyTypeObject *type, pytype_slotdef *p) { PyObject *descr; PyWrapperDescrObject *d; - void *generic = NULL, *specific = NULL; + + // The correct specialized C function, like "tp_repr of str" in the + // example above + void *specific = NULL; + + // A generic wrapper that uses method lookup (safe but slow) + void *generic = NULL; + + // Set to 1 if the generic wrapper is necessary int use_generic = 0; + int offset = p->offset; int error; void **ptr = slotptr(type, offset); @@ -8366,7 +8966,7 @@ update_one_slot(PyTypeObject *type, slotdef *p) } else if (Py_IS_TYPE(descr, &PyCFunction_Type) && PyCFunction_GET_FUNCTION(descr) == - (PyCFunction)(void(*)(void))tp_new_wrapper && + _PyCFunction_CAST(tp_new_wrapper) && ptr == (void**)&type->tp_new) { /* The __new__ wrapper is not a wrapper descriptor, @@ -8396,6 +8996,10 @@ update_one_slot(PyTypeObject *type, slotdef *p) else { use_generic = 1; generic = p->function; + if (p->function == slot_tp_call) { + /* A generic __call__ is incompatible with vectorcall */ + type->tp_flags &= ~Py_TPFLAGS_HAVE_VECTORCALL; + } } } while ((++p)->offset == offset); if (specific && !use_generic) @@ -8410,61 +9014,31 @@ update_one_slot(PyTypeObject *type, slotdef *p) static int update_slots_callback(PyTypeObject *type, void *data) { - slotdef **pp = (slotdef **)data; - - for (; *pp; pp++) + pytype_slotdef **pp = (pytype_slotdef **)data; + for (; *pp; pp++) { update_one_slot(type, *pp); + } return 0; } -static int slotdefs_initialized = 0; -/* Initialize the slotdefs table by adding interned string objects for the - names. */ -PyStatus -_PyTypes_InitSlotDefs(void) -{ - if (slotdefs_initialized) { - return _PyStatus_OK(); - } - - for (slotdef *p = slotdefs; p->name; p++) { - /* Slots must be ordered by their offset in the PyHeapTypeObject. */ - assert(!p[1].name || p->offset <= p[1].offset); - p->name_strobj = PyUnicode_InternFromString(p->name); - if (!p->name_strobj || !PyUnicode_CHECK_INTERNED(p->name_strobj)) { - return _PyStatus_NO_MEMORY(); - } - } - slotdefs_initialized = 1; - return _PyStatus_OK(); -} - -/* Undo _PyTypes_InitSlotDefs(), releasing the interned strings. */ -static void clear_slotdefs(void) -{ - for (slotdef *p = slotdefs; p->name; p++) { - Py_CLEAR(p->name_strobj); - } - slotdefs_initialized = 0; -} - /* Update the slots after assignment to a class (type) attribute. */ static int update_slot(PyTypeObject *type, PyObject *name) { - slotdef *ptrs[MAX_EQUIV]; - slotdef *p; - slotdef **pp; + pytype_slotdef *ptrs[MAX_EQUIV]; + pytype_slotdef *p; + pytype_slotdef **pp; int offset; assert(PyUnicode_CheckExact(name)); assert(PyUnicode_CHECK_INTERNED(name)); - assert(slotdefs_initialized); pp = ptrs; for (p = slotdefs; p->name; p++) { assert(PyUnicode_CheckExact(p->name_strobj)); + assert(PyUnicode_CHECK_INTERNED(p->name_strobj)); assert(PyUnicode_CheckExact(name)); + /* bpo-40521: Using interned strings. */ if (p->name_strobj == name) { *pp++ = p; } @@ -8490,8 +9064,7 @@ static void fixup_slot_dispatchers(PyTypeObject *type) { assert(!PyErr_Occurred()); - assert(slotdefs_initialized); - for (slotdef *p = slotdefs; p->name; ) { + for (pytype_slotdef *p = slotdefs; p->name; ) { p = update_one_slot(type, p); } } @@ -8499,12 +9072,11 @@ fixup_slot_dispatchers(PyTypeObject *type) static void update_all_slots(PyTypeObject* type) { - slotdef *p; + pytype_slotdef *p; /* Clear the VALID_VERSION flag of 'type' and all its subclasses. */ PyType_Modified(type); - assert(slotdefs_initialized); for (p = slotdefs; p->name; p++) { /* update_slot returns int but can't actually fail */ update_slot(type, p->name_strobj); @@ -8525,7 +9097,8 @@ type_new_set_names(PyTypeObject *type) Py_ssize_t i = 0; PyObject *key, *value; while (PyDict_Next(names_to_set, &i, &key, &value)) { - PyObject *set_name = _PyObject_LookupSpecial(value, &PyId___set_name__); + PyObject *set_name = _PyObject_LookupSpecial(value, + &_Py_ID(__set_name__)); if (set_name == NULL) { if (PyErr_Occurred()) { goto error; @@ -8565,7 +9138,7 @@ type_new_init_subclass(PyTypeObject *type, PyObject *kwds) return -1; } - PyObject *func = _PyObject_GetAttrId(super, &PyId___init_subclass__); + PyObject *func = PyObject_GetAttr(super, &_Py_ID(__init_subclass__)); Py_DECREF(super); if (func == NULL) { return -1; @@ -8584,50 +9157,54 @@ type_new_init_subclass(PyTypeObject *type, PyObject *kwds) /* recurse_down_subclasses() and update_subclasses() are mutually recursive functions to call a callback for all subclasses, - but refraining from recursing into subclasses that define 'name'. */ + but refraining from recursing into subclasses that define 'attr_name'. */ static int -update_subclasses(PyTypeObject *type, PyObject *name, +update_subclasses(PyTypeObject *type, PyObject *attr_name, update_callback callback, void *data) { - if (callback(type, data) < 0) + if (callback(type, data) < 0) { return -1; - return recurse_down_subclasses(type, name, callback, data); + } + return recurse_down_subclasses(type, attr_name, callback, data); } static int -recurse_down_subclasses(PyTypeObject *type, PyObject *name, +recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name, update_callback callback, void *data) { - PyTypeObject *subclass; - PyObject *ref, *subclasses, *dict; - Py_ssize_t i; - - subclasses = type->tp_subclasses; - if (subclasses == NULL) + // It is safe to use a borrowed reference because update_subclasses() is + // only used with update_slots_callback() which doesn't modify + // tp_subclasses. + PyObject *subclasses = lookup_subclasses(type); // borrowed ref + if (subclasses == NULL) { return 0; + } assert(PyDict_CheckExact(subclasses)); - i = 0; + + Py_ssize_t i = 0; + PyObject *ref; while (PyDict_Next(subclasses, &i, NULL, &ref)) { - assert(PyWeakref_CheckRef(ref)); - subclass = (PyTypeObject *)PyWeakref_GET_OBJECT(ref); - assert(subclass != NULL); - if ((PyObject *)subclass == Py_None) + PyTypeObject *subclass = subclass_from_ref(ref); // borrowed + if (subclass == NULL) { continue; - assert(PyType_Check(subclass)); + } + /* Avoid recursing down into unaffected classes */ - dict = subclass->tp_dict; + PyObject *dict = subclass->tp_dict; if (dict != NULL && PyDict_Check(dict)) { - int r = PyDict_Contains(dict, name); - if (r > 0) { - continue; - } + int r = PyDict_Contains(dict, attr_name); if (r < 0) { return -1; } + if (r > 0) { + continue; + } } - if (update_subclasses(subclass, name, callback, data) < 0) + + if (update_subclasses(subclass, attr_name, callback, data) < 0) { return -1; + } } return 0; } @@ -8666,11 +9243,10 @@ static int add_operators(PyTypeObject *type) { PyObject *dict = type->tp_dict; - slotdef *p; + pytype_slotdef *p; PyObject *descr; void **ptr; - assert(slotdefs_initialized); for (p = slotdefs; p->name; p++) { if (p->wrapper == NULL) continue; @@ -8768,7 +9344,7 @@ super_getattro(PyObject *self, PyObject *name) (i.e. super, or a subclass), not the class of su->obj. */ if (PyUnicode_Check(name) && PyUnicode_GET_LENGTH(name) == 9 && - _PyUnicode_EqualToASCIIId(name, &PyId___class__)) + _PyUnicode_Equal(name, &_Py_ID(__class__))) goto skip; mro = starttype->tp_mro; @@ -8791,28 +9367,23 @@ super_getattro(PyObject *self, PyObject *name) replaced during PyDict_GetItemWithError(dict, name) */ Py_INCREF(mro); do { - PyObject *res, *tmp, *dict; - descrgetfunc f; - - tmp = PyTuple_GET_ITEM(mro, i); - assert(PyType_Check(tmp)); - - dict = ((PyTypeObject *)tmp)->tp_dict; + PyObject *obj = PyTuple_GET_ITEM(mro, i); + PyObject *dict = _PyType_CAST(obj)->tp_dict; assert(dict != NULL && PyDict_Check(dict)); - res = PyDict_GetItemWithError(dict, name); + PyObject *res = PyDict_GetItemWithError(dict, name); if (res != NULL) { Py_INCREF(res); - f = Py_TYPE(res)->tp_descr_get; + descrgetfunc f = Py_TYPE(res)->tp_descr_get; if (f != NULL) { - tmp = f(res, + PyObject *res2; + res2 = f(res, /* Only pass 'obj' param if this is instance-mode super (See SF ID #743627) */ (su->obj == (PyObject *)starttype) ? NULL : su->obj, (PyObject *)starttype); - Py_DECREF(res); - res = tmp; + Py_SETREF(res, res2); } Py_DECREF(mro); @@ -8851,20 +9422,18 @@ supercheck(PyTypeObject *type, PyObject *obj) /* Check for first bullet above (special case) */ if (PyType_Check(obj) && PyType_IsSubtype((PyTypeObject *)obj, type)) { - Py_INCREF(obj); - return (PyTypeObject *)obj; + return (PyTypeObject *)Py_NewRef(obj); } /* Normal case */ if (PyType_IsSubtype(Py_TYPE(obj), type)) { - Py_INCREF(Py_TYPE(obj)); - return Py_TYPE(obj); + return (PyTypeObject*)Py_NewRef(Py_TYPE(obj)); } else { /* Try the slow way */ PyObject *class_attr; - if (_PyObject_LookupAttrId(obj, &PyId___class__, &class_attr) < 0) { + if (_PyObject_LookupAttr(obj, &_Py_ID(__class__), &class_attr) < 0) { return NULL; } if (class_attr != NULL && @@ -8873,8 +9442,9 @@ supercheck(PyTypeObject *type, PyObject *obj) { int ok = PyType_IsSubtype( (PyTypeObject *)class_attr, type); - if (ok) + if (ok) { return (PyTypeObject *)class_attr; + } } Py_XDECREF(class_attr); } @@ -8893,8 +9463,7 @@ super_descr_get(PyObject *self, PyObject *obj, PyObject *type) if (obj == NULL || obj == Py_None || su->obj != NULL) { /* Not binding to an object, or already bound */ - Py_INCREF(self); - return self; + return Py_NewRef(self); } if (!Py_IS_TYPE(su, &PySuper_Type)) /* If su is an instance of a (strict) subclass of super, @@ -8910,17 +9479,15 @@ super_descr_get(PyObject *self, PyObject *obj, PyObject *type) NULL, NULL); if (newobj == NULL) return NULL; - Py_INCREF(su->type); - Py_INCREF(obj); - newobj->type = su->type; - newobj->obj = obj; + newobj->type = (PyTypeObject*)Py_NewRef(su->type); + newobj->obj = Py_NewRef(obj); newobj->obj_type = obj_type; return (PyObject *)newobj; } } static int -super_init_without_args(PyFrameObject *f, PyCodeObject *co, +super_init_without_args(_PyInterpreterFrame *cframe, PyCodeObject *co, PyTypeObject **type_p, PyObject **obj_p) { if (co->co_argcount == 0) { @@ -8929,14 +9496,17 @@ super_init_without_args(PyFrameObject *f, PyCodeObject *co, return -1; } - assert(f->f_frame->f_code->co_nlocalsplus > 0); - PyObject *firstarg = _PyFrame_GetLocalsArray(f->f_frame)[0]; + assert(cframe->f_code->co_nlocalsplus > 0); + PyObject *firstarg = _PyFrame_GetLocalsArray(cframe)[0]; // The first argument might be a cell. if (firstarg != NULL && (_PyLocals_GetKind(co->co_localspluskinds, 0) & CO_FAST_CELL)) { // "firstarg" is a cell here unless (very unlikely) super() // was called from the C-API before the first MAKE_CELL op. - if (f->f_frame->f_lasti >= 0) { - assert(_Py_OPCODE(*co->co_firstinstr) == MAKE_CELL); + if (_PyInterpreterFrame_LASTI(cframe) >= 0) { + // MAKE_CELL and COPY_FREE_VARS have no quickened forms, so no need + // to use _PyOpcode_Deopt here: + assert(_Py_OPCODE(_PyCode_CODE(co)[0]) == MAKE_CELL || + _Py_OPCODE(_PyCode_CODE(co)[0]) == COPY_FREE_VARS); assert(PyCell_Check(firstarg)); firstarg = PyCell_GET(firstarg); } @@ -8949,13 +9519,13 @@ super_init_without_args(PyFrameObject *f, PyCodeObject *co, // Look for __class__ in the free vars. PyTypeObject *type = NULL; - int i = co->co_nlocals + co->co_nplaincellvars; + int i = PyCode_GetFirstFree(co); for (; i < co->co_nlocalsplus; i++) { assert((_PyLocals_GetKind(co->co_localspluskinds, i) & CO_FAST_FREE) != 0); PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i); assert(PyUnicode_Check(name)); - if (_PyUnicode_EqualToASCIIId(name, &PyId___class__)) { - PyObject *cell = _PyFrame_GetLocalsArray(f->f_frame)[i]; + if (_PyUnicode_Equal(name, &_Py_ID(__class__))) { + PyObject *cell = _PyFrame_GetLocalsArray(cframe)[i]; if (cell == NULL || !PyCell_Check(cell)) { PyErr_SetString(PyExc_RuntimeError, "super(): bad __class__ cell"); @@ -8987,34 +9557,39 @@ super_init_without_args(PyFrameObject *f, PyCodeObject *co, return 0; } +static int super_init_impl(PyObject *self, PyTypeObject *type, PyObject *obj); + static int super_init(PyObject *self, PyObject *args, PyObject *kwds) { - superobject *su = (superobject *)self; PyTypeObject *type = NULL; PyObject *obj = NULL; - PyTypeObject *obj_type = NULL; if (!_PyArg_NoKeywords("super", kwds)) return -1; if (!PyArg_ParseTuple(args, "|O!O:super", &PyType_Type, &type, &obj)) return -1; + if (super_init_impl(self, type, obj) < 0) { + return -1; + } + return 0; +} +static inline int +super_init_impl(PyObject *self, PyTypeObject *type, PyObject *obj) { + superobject *su = (superobject *)self; + PyTypeObject *obj_type = NULL; if (type == NULL) { /* Call super(), without args -- fill in from __class__ and first local variable on the stack. */ PyThreadState *tstate = _PyThreadState_GET(); - PyFrameObject *frame = PyThreadState_GetFrame(tstate); + _PyInterpreterFrame *frame = _PyThreadState_GetFrame(tstate); if (frame == NULL) { PyErr_SetString(PyExc_RuntimeError, "super(): no current frame"); return -1; } - - PyCodeObject *code = PyFrame_GetCode(frame); - int res = super_init_without_args(frame, code, &type, &obj); - Py_DECREF(frame); - Py_DECREF(code); + int res = super_init_without_args(frame, frame->f_code, &type, &obj); if (res < 0) { return -1; @@ -9029,8 +9604,7 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; Py_INCREF(obj); } - Py_INCREF(type); - Py_XSETREF(su->type, type); + Py_XSETREF(su->type, (PyTypeObject*)Py_NewRef(type)); Py_XSETREF(su->obj, obj); Py_XSETREF(su->obj_type, obj_type); return 0; @@ -9063,6 +9637,47 @@ super_traverse(PyObject *self, visitproc visit, void *arg) return 0; } +static PyObject * +super_vectorcall(PyObject *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + assert(PyType_Check(self)); + if (!_PyArg_NoKwnames("super", kwnames)) { + return NULL; + } + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (!_PyArg_CheckPositional("super()", nargs, 0, 2)) { + return NULL; + } + PyTypeObject *type = NULL; + PyObject *obj = NULL; + PyTypeObject *self_type = (PyTypeObject *)self; + PyObject *su = self_type->tp_alloc(self_type, 0); + if (su == NULL) { + return NULL; + } + // 1 or 2 argument form super(). + if (nargs != 0) { + PyObject *arg0 = args[0]; + if (!PyType_Check(arg0)) { + PyErr_Format(PyExc_TypeError, + "super() argument 1 must be a type, not %.200s", Py_TYPE(arg0)->tp_name); + goto fail; + } + type = (PyTypeObject *)arg0; + } + if (nargs == 2) { + obj = args[1]; + } + if (super_init_impl(su, type, obj) < 0) { + goto fail; + } + return su; +fail: + Py_DECREF(su); + return NULL; +} + PyTypeObject PySuper_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "super", /* tp_name */ @@ -9105,4 +9720,5 @@ PyTypeObject PySuper_Type = { PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ PyObject_GC_Del, /* tp_free */ + .tp_vectorcall = (vectorcallfunc)super_vectorcall, }; diff --git a/Objects/unicodectype.c b/Objects/unicodectype.c index d8c95c8b44c..aa5c5b2a4ad 100644 --- a/Objects/unicodectype.c +++ b/Objects/unicodectype.c @@ -14,8 +14,6 @@ #define DECIMAL_MASK 0x02 #define DIGIT_MASK 0x04 #define LOWER_MASK 0x08 -#define LINEBREAK_MASK 0x10 -#define SPACE_MASK 0x20 #define TITLE_MASK 0x40 #define UPPER_MASK 0x80 #define XID_START_MASK 0x100 diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 61fc34d71da..f0c7aa7707f 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -42,17 +42,19 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_atomic_funcs.h" // _Py_atomic_size_get() +#include "pycore_bytesobject.h" // _PyBytes_Repeat() #include "pycore_bytes_methods.h" // _Py_bytes_lower() #include "pycore_format.h" // F_LJUST #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_interp.h" // PyInterpreterState.fs_codec #include "pycore_long.h" // _PyLong_FormatWriter() -#include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_object.h" // _PyObject_GC_TRACK(), _Py_FatalRefcountError() #include "pycore_pathconfig.h" // _Py_DumpPathConfig() -#include "pycore_pyerrors.h" // _Py_FatalRefcountError() #include "pycore_pylifecycle.h" // _Py_SetFileSystemEncoding() #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI +#include "pycore_unicodeobject.h" // struct _Py_unicode_state +#include "pycore_unicodeobject_generated.h" // _PyUnicode_InitStaticStrings() #include "stringlib/eq.h" // unicode_eq() #ifdef MS_WINDOWS @@ -60,7 +62,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #endif #ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION -#include "pycore_fileutils.h" // _Py_LocaleUsesNonUnicodeWchar() +# include "pycore_fileutils.h" // _Py_LocaleUsesNonUnicodeWchar() #endif /* Uncomment to display statistics on interned strings at exit @@ -111,61 +113,39 @@ extern "C" { #endif #define _PyUnicode_UTF8(op) \ - (((PyCompactUnicodeObject*)(op))->utf8) + (_PyCompactUnicodeObject_CAST(op)->utf8) #define PyUnicode_UTF8(op) \ (assert(_PyUnicode_CHECK(op)), \ - assert(PyUnicode_IS_READY(op)), \ PyUnicode_IS_COMPACT_ASCII(op) ? \ - ((char*)((PyASCIIObject*)(op) + 1)) : \ + ((char*)(_PyASCIIObject_CAST(op) + 1)) : \ _PyUnicode_UTF8(op)) #define _PyUnicode_UTF8_LENGTH(op) \ - (((PyCompactUnicodeObject*)(op))->utf8_length) + (_PyCompactUnicodeObject_CAST(op)->utf8_length) #define PyUnicode_UTF8_LENGTH(op) \ (assert(_PyUnicode_CHECK(op)), \ - assert(PyUnicode_IS_READY(op)), \ PyUnicode_IS_COMPACT_ASCII(op) ? \ - ((PyASCIIObject*)(op))->length : \ + _PyASCIIObject_CAST(op)->length : \ _PyUnicode_UTF8_LENGTH(op)) -#define _PyUnicode_WSTR(op) \ - (((PyASCIIObject*)(op))->wstr) -/* Don't use deprecated macro of unicodeobject.h */ -#undef PyUnicode_WSTR_LENGTH -#define PyUnicode_WSTR_LENGTH(op) \ - (PyUnicode_IS_COMPACT_ASCII(op) ? \ - ((PyASCIIObject*)op)->length : \ - ((PyCompactUnicodeObject*)op)->wstr_length) -#define _PyUnicode_WSTR_LENGTH(op) \ - (((PyCompactUnicodeObject*)(op))->wstr_length) #define _PyUnicode_LENGTH(op) \ - (((PyASCIIObject *)(op))->length) + (_PyASCIIObject_CAST(op)->length) #define _PyUnicode_STATE(op) \ - (((PyASCIIObject *)(op))->state) + (_PyASCIIObject_CAST(op)->state) #define _PyUnicode_HASH(op) \ - (((PyASCIIObject *)(op))->hash) + (_PyASCIIObject_CAST(op)->hash) #define _PyUnicode_KIND(op) \ (assert(_PyUnicode_CHECK(op)), \ - ((PyASCIIObject *)(op))->state.kind) + _PyASCIIObject_CAST(op)->state.kind) #define _PyUnicode_GET_LENGTH(op) \ (assert(_PyUnicode_CHECK(op)), \ - ((PyASCIIObject *)(op))->length) + _PyASCIIObject_CAST(op)->length) #define _PyUnicode_DATA_ANY(op) \ - (((PyUnicodeObject*)(op))->data.any) - -#undef PyUnicode_READY -#define PyUnicode_READY(op) \ - (assert(_PyUnicode_CHECK(op)), \ - (PyUnicode_IS_READY(op) ? \ - 0 : \ - _PyUnicode_Ready(op))) + (_PyUnicodeObject_CAST(op)->data.any) #define _PyUnicode_SHARE_UTF8(op) \ (assert(_PyUnicode_CHECK(op)), \ assert(!PyUnicode_IS_COMPACT_ASCII(op)), \ (_PyUnicode_UTF8(op) == PyUnicode_DATA(op))) -#define _PyUnicode_SHARE_WSTR(op) \ - (assert(_PyUnicode_CHECK(op)), \ - (_PyUnicode_WSTR(unicode) == PyUnicode_DATA(op))) /* true if the Unicode object has an allocated UTF-8 memory block (not shared with other data) */ @@ -174,13 +154,6 @@ extern "C" { && _PyUnicode_UTF8(op) \ && _PyUnicode_UTF8(op) != PyUnicode_DATA(op))) -/* true if the Unicode object has an allocated wstr memory block - (not shared with other data) */ -#define _PyUnicode_HAS_WSTR_MEMORY(op) \ - ((_PyUnicode_WSTR(op) && \ - (!PyUnicode_IS_READY(op) || \ - _PyUnicode_WSTR(op) != PyUnicode_DATA(op)))) - /* Generic helper macro to convert characters of different types. from_type and to_type have to be valid type names, begin and end are pointers to the source characters which should be of type @@ -188,7 +161,7 @@ extern "C" { buffer where the result characters are written to. */ #define _PyUnicode_CONVERT_BYTES(from_type, to_type, begin, end, to) \ do { \ - to_type *_to = (to_type *)(to); \ + to_type *_to = (to_type *)(to); \ const from_type *_iter = (const from_type *)(begin);\ const from_type *_end = (const from_type *)(end);\ Py_ssize_t n = (_end) - (_iter); \ @@ -205,6 +178,11 @@ extern "C" { *_to++ = (to_type) *_iter++; \ } while (0) +#define LATIN1(ch) \ + (ch < 128 \ + ? (PyObject*)&_Py_SINGLETON(strings).ascii[ch] \ + : (PyObject*)&_Py_SINGLETON(strings).latin1[ch - 128]) + #ifdef MS_WINDOWS /* On Windows, overallocate by 50% is the best factor */ # define OVERALLOCATE_FACTOR 2 @@ -213,7 +191,6 @@ extern "C" { # define OVERALLOCATE_FACTOR 4 #endif - /* Forward declaration */ static inline int _PyUnicodeWriter_WriteCharInline(_PyUnicodeWriter *writer, Py_UCS4 ch); @@ -232,22 +209,11 @@ static int unicode_is_singleton(PyObject *unicode); #endif -static struct _Py_unicode_state* -get_unicode_state(void) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - return &interp->unicode; -} - - // Return a borrowed reference to the empty string singleton. static inline PyObject* unicode_get_empty(void) { - struct _Py_unicode_state *state = get_unicode_state(); - // unicode_get_empty() must not be called before _PyUnicode_Init() - // or after _PyUnicode_Fini() - assert(state->empty_string != NULL); - return state->empty_string; + _Py_DECLARE_STR(empty, ""); + return &_Py_STR(empty); } @@ -255,8 +221,24 @@ static inline PyObject* unicode_get_empty(void) static inline PyObject* unicode_new_empty(void) { PyObject *empty = unicode_get_empty(); - Py_INCREF(empty); - return empty; + return Py_NewRef(empty); +} + +/* This dictionary holds all interned unicode strings. Note that references + to strings in this dictionary are *not* counted in the string's ob_refcnt. + When the interned string reaches a refcnt of 0 the string deallocation + function will delete the reference from this dictionary. + Another way to look at this is that to say that the actual reference + count of a string is: s->ob_refcnt + (s->state ? 2 : 0) +*/ +static inline PyObject *get_interned_dict(void) +{ + return _Py_CACHED_OBJECT(interned_strings); +} + +static inline void set_interned_dict(PyObject *dict) +{ + _Py_CACHED_OBJECT(interned_strings) = dict; } #define _Py_RETURN_UNICODE_EMPTY() \ @@ -265,11 +247,10 @@ static inline PyObject* unicode_new_empty(void) } while (0) static inline void -unicode_fill(enum PyUnicode_Kind kind, void *data, Py_UCS4 value, +unicode_fill(int kind, void *data, Py_UCS4 value, Py_ssize_t start, Py_ssize_t length) { assert(0 <= start); - assert(kind != PyUnicode_WCHAR_KIND); switch (kind) { case PyUnicode_1BYTE_KIND: { assert(value <= 0xff); @@ -331,7 +312,6 @@ const unsigned char _Py_ascii_whitespace[] = { }; /* forward */ -static PyUnicodeObject *_PyUnicode_New(Py_ssize_t length); static PyObject* get_latin1_char(unsigned char ch); static int unicode_modifiable(PyObject *unicode); @@ -386,6 +366,7 @@ static const unsigned char ascii_linebreak[] = { static int convert_uc(PyObject *obj, void *addr); +struct encoding_map; #include "clinic/unicodeobject.c.h" _Py_error_handler @@ -473,7 +454,14 @@ unicode_check_encoding_errors(const char *encoding, const char *errors) return 0; } - if (encoding != NULL) { + if (encoding != NULL + // Fast path for the most common built-in encodings. Even if the codec + // is cached, _PyCodec_Lookup() decodes the bytes string from UTF-8 to + // create a temporary Unicode string (the key in the cache). + && strcmp(encoding, "utf-8") != 0 + && strcmp(encoding, "utf8") != 0 + && strcmp(encoding, "ascii") != 0) + { PyObject *handler = _PyCodec_Lookup(encoding); if (handler == NULL) { return -1; @@ -481,7 +469,14 @@ unicode_check_encoding_errors(const char *encoding, const char *errors) Py_DECREF(handler); } - if (errors != NULL) { + if (errors != NULL + // Fast path for the most common built-in error handlers. + && strcmp(errors, "strict") != 0 + && strcmp(errors, "ignore") != 0 + && strcmp(errors, "replace") != 0 + && strcmp(errors, "surrogateescape") != 0 + && strcmp(errors, "surrogatepass") != 0) + { PyObject *handler = PyCodec_LookupError(errors); if (handler == NULL) { return -1; @@ -498,21 +493,17 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) #define CHECK(expr) \ do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0) - PyASCIIObject *ascii; - unsigned int kind; - assert(op != NULL); CHECK(PyUnicode_Check(op)); - ascii = (PyASCIIObject *)op; - kind = ascii->state.kind; + PyASCIIObject *ascii = _PyASCIIObject_CAST(op); + int kind = ascii->state.kind; if (ascii->state.ascii == 1 && ascii->state.compact == 1) { CHECK(kind == PyUnicode_1BYTE_KIND); - CHECK(ascii->state.ready == 1); } else { - PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op; + PyCompactUnicodeObject *compact = _PyCompactUnicodeObject_CAST(op); void *data; if (ascii->state.compact == 1) { @@ -521,62 +512,32 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) || kind == PyUnicode_2BYTE_KIND || kind == PyUnicode_4BYTE_KIND); CHECK(ascii->state.ascii == 0); - CHECK(ascii->state.ready == 1); CHECK(compact->utf8 != data); } else { - PyUnicodeObject *unicode = (PyUnicodeObject *)op; + PyUnicodeObject *unicode = _PyUnicodeObject_CAST(op); data = unicode->data.any; - if (kind == PyUnicode_WCHAR_KIND) { - CHECK(ascii->length == 0); - CHECK(ascii->hash == -1); - CHECK(ascii->state.compact == 0); - CHECK(ascii->state.ascii == 0); - CHECK(ascii->state.ready == 0); - CHECK(ascii->state.interned == SSTATE_NOT_INTERNED); - CHECK(ascii->wstr != NULL); - CHECK(data == NULL); - CHECK(compact->utf8 == NULL); + CHECK(kind == PyUnicode_1BYTE_KIND + || kind == PyUnicode_2BYTE_KIND + || kind == PyUnicode_4BYTE_KIND); + CHECK(ascii->state.compact == 0); + CHECK(data != NULL); + if (ascii->state.ascii) { + CHECK(compact->utf8 == data); + CHECK(compact->utf8_length == ascii->length); } else { - CHECK(kind == PyUnicode_1BYTE_KIND - || kind == PyUnicode_2BYTE_KIND - || kind == PyUnicode_4BYTE_KIND); - CHECK(ascii->state.compact == 0); - CHECK(ascii->state.ready == 1); - CHECK(data != NULL); - if (ascii->state.ascii) { - CHECK(compact->utf8 == data); - CHECK(compact->utf8_length == ascii->length); - } - else - CHECK(compact->utf8 != data); + CHECK(compact->utf8 != data); } } - if (kind != PyUnicode_WCHAR_KIND) { - if ( -#if SIZEOF_WCHAR_T == 2 - kind == PyUnicode_2BYTE_KIND -#else - kind == PyUnicode_4BYTE_KIND -#endif - ) - { - CHECK(ascii->wstr == data); - CHECK(compact->wstr_length == ascii->length); - } else - CHECK(ascii->wstr != data); - } if (compact->utf8 == NULL) CHECK(compact->utf8_length == 0); - if (ascii->wstr == NULL) - CHECK(compact->wstr_length == 0); } /* check that the best kind is used: O(n) operation */ - if (check_content && kind != PyUnicode_WCHAR_KIND) { + if (check_content) { Py_ssize_t i; Py_UCS4 maxchar = 0; const void *data; @@ -612,47 +573,12 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) #undef CHECK } - static PyObject* -unicode_result_wchar(PyObject *unicode) +unicode_result(PyObject *unicode) { -#ifndef Py_DEBUG - Py_ssize_t len; + assert(_PyUnicode_CHECK(unicode)); - len = _PyUnicode_WSTR_LENGTH(unicode); - if (len == 0) { - Py_DECREF(unicode); - _Py_RETURN_UNICODE_EMPTY(); - } - - if (len == 1) { - wchar_t ch = _PyUnicode_WSTR(unicode)[0]; - if ((Py_UCS4)ch < 256) { - Py_DECREF(unicode); - return get_latin1_char((unsigned char)ch); - } - } - - if (_PyUnicode_Ready(unicode) < 0) { - Py_DECREF(unicode); - return NULL; - } -#else - assert(Py_REFCNT(unicode) == 1); - - /* don't make the result ready in debug mode to ensure that the caller - makes the string ready before using it */ - assert(_PyUnicode_CheckConsistency(unicode, 1)); -#endif - return unicode; -} - -static PyObject* -unicode_result_ready(PyObject *unicode) -{ - Py_ssize_t length; - - length = PyUnicode_GET_LENGTH(unicode); + Py_ssize_t length = PyUnicode_GET_LENGTH(unicode); if (length == 0) { PyObject *empty = unicode_get_empty(); if (unicode != empty) { @@ -667,24 +593,12 @@ unicode_result_ready(PyObject *unicode) if (kind == PyUnicode_1BYTE_KIND) { const Py_UCS1 *data = PyUnicode_1BYTE_DATA(unicode); Py_UCS1 ch = data[0]; - struct _Py_unicode_state *state = get_unicode_state(); - PyObject *latin1_char = state->latin1[ch]; - if (latin1_char != NULL) { - if (unicode != latin1_char) { - Py_INCREF(latin1_char); - Py_DECREF(unicode); - } - return latin1_char; + PyObject *latin1_char = LATIN1(ch); + if (unicode != latin1_char) { + Py_INCREF(latin1_char); + Py_DECREF(unicode); } - else { - assert(_PyUnicode_CheckConsistency(unicode, 1)); - Py_INCREF(unicode); - state->latin1[ch] = unicode; - return unicode; - } - } - else { - assert(PyUnicode_READ_CHAR(unicode, 0) >= 256); + return latin1_char; } } @@ -692,24 +606,11 @@ unicode_result_ready(PyObject *unicode) return unicode; } -static PyObject* -unicode_result(PyObject *unicode) -{ - assert(_PyUnicode_CHECK(unicode)); - if (PyUnicode_IS_READY(unicode)) - return unicode_result_ready(unicode); - else - return unicode_result_wchar(unicode); -} - static PyObject* unicode_result_unchanged(PyObject *unicode) { if (PyUnicode_CheckExact(unicode)) { - if (PyUnicode_READY(unicode) == -1) - return NULL; - Py_INCREF(unicode); - return unicode; + return Py_NewRef(unicode); } else /* Subtype -- return genuine unicode string with the same value. */ @@ -724,10 +625,9 @@ backslashreplace(_PyBytesWriter *writer, char *str, { Py_ssize_t size, i; Py_UCS4 ch; - enum PyUnicode_Kind kind; + int kind; const void *data; - assert(PyUnicode_IS_READY(unicode)); kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); @@ -791,10 +691,9 @@ xmlcharrefreplace(_PyBytesWriter *writer, char *str, { Py_ssize_t size, i; Py_UCS4 ch; - enum PyUnicode_Kind kind; + int kind; const void *data; - assert(PyUnicode_IS_READY(unicode)); kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); @@ -918,7 +817,7 @@ ensure_unicode(PyObject *obj) Py_TYPE(obj)->tp_name); return -1; } - return PyUnicode_READY(obj); + return 0; } /* Compilation of templated routines */ @@ -964,15 +863,6 @@ ensure_unicode(PyObject *obj) #include "stringlib/find_max_char.h" #include "stringlib/undef.h" -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS -#include "stringlib/unicodedefs.h" -#include "stringlib/fastsearch.h" -#include "stringlib/count.h" -#include "stringlib/find.h" -#include "stringlib/undef.h" -_Py_COMP_DIAG_POP - #undef STRINGLIB_GET_EMPTY /* --- Unicode Object ----------------------------------------------------- */ @@ -1032,14 +922,12 @@ resize_compact(PyObject *unicode, Py_ssize_t length) Py_ssize_t char_size; Py_ssize_t struct_size; Py_ssize_t new_size; - int share_wstr; PyObject *new_unicode; #ifdef Py_DEBUG Py_ssize_t old_length = _PyUnicode_LENGTH(unicode); #endif assert(unicode_modifiable(unicode)); - assert(PyUnicode_IS_READY(unicode)); assert(PyUnicode_IS_COMPACT(unicode)); char_size = PyUnicode_KIND(unicode); @@ -1047,7 +935,6 @@ resize_compact(PyObject *unicode, Py_ssize_t length) struct_size = sizeof(PyASCIIObject); else struct_size = sizeof(PyCompactUnicodeObject); - share_wstr = _PyUnicode_SHARE_WSTR(unicode); if (length > ((PY_SSIZE_T_MAX - struct_size) / char_size - 1)) { PyErr_NoMemory(); @@ -1077,17 +964,6 @@ resize_compact(PyObject *unicode, Py_ssize_t length) _Py_NewReference(unicode); _PyUnicode_LENGTH(unicode) = length; - if (share_wstr) { - _PyUnicode_WSTR(unicode) = PyUnicode_DATA(unicode); - if (!PyUnicode_IS_ASCII(unicode)) - _PyUnicode_WSTR_LENGTH(unicode) = length; - } - else if (_PyUnicode_HAS_WSTR_MEMORY(unicode)) { - PyObject_Free(_PyUnicode_WSTR(unicode)); - _PyUnicode_WSTR(unicode) = NULL; - if (!PyUnicode_IS_ASCII(unicode)) - _PyUnicode_WSTR_LENGTH(unicode) = 0; - } #ifdef Py_DEBUG unicode_fill_invalid(unicode, old_length); #endif @@ -1100,78 +976,55 @@ resize_compact(PyObject *unicode, Py_ssize_t length) static int resize_inplace(PyObject *unicode, Py_ssize_t length) { - wchar_t *wstr; - Py_ssize_t new_size; assert(!PyUnicode_IS_COMPACT(unicode)); assert(Py_REFCNT(unicode) == 1); - if (PyUnicode_IS_READY(unicode)) { - Py_ssize_t char_size; - int share_wstr, share_utf8; - void *data; + Py_ssize_t new_size; + Py_ssize_t char_size; + int share_utf8; + void *data; #ifdef Py_DEBUG - Py_ssize_t old_length = _PyUnicode_LENGTH(unicode); + Py_ssize_t old_length = _PyUnicode_LENGTH(unicode); #endif - data = _PyUnicode_DATA_ANY(unicode); - char_size = PyUnicode_KIND(unicode); - share_wstr = _PyUnicode_SHARE_WSTR(unicode); - share_utf8 = _PyUnicode_SHARE_UTF8(unicode); + data = _PyUnicode_DATA_ANY(unicode); + char_size = PyUnicode_KIND(unicode); + share_utf8 = _PyUnicode_SHARE_UTF8(unicode); - if (length > (PY_SSIZE_T_MAX / char_size - 1)) { - PyErr_NoMemory(); - return -1; - } - new_size = (length + 1) * char_size; - - if (!share_utf8 && _PyUnicode_HAS_UTF8_MEMORY(unicode)) - { - PyObject_Free(_PyUnicode_UTF8(unicode)); - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - } - - data = (PyObject *)PyObject_Realloc(data, new_size); - if (data == NULL) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_DATA_ANY(unicode) = data; - if (share_wstr) { - _PyUnicode_WSTR(unicode) = data; - _PyUnicode_WSTR_LENGTH(unicode) = length; - } - if (share_utf8) { - _PyUnicode_UTF8(unicode) = data; - _PyUnicode_UTF8_LENGTH(unicode) = length; - } - _PyUnicode_LENGTH(unicode) = length; - PyUnicode_WRITE(PyUnicode_KIND(unicode), data, length, 0); -#ifdef Py_DEBUG - unicode_fill_invalid(unicode, old_length); -#endif - if (share_wstr || _PyUnicode_WSTR(unicode) == NULL) { - assert(_PyUnicode_CheckConsistency(unicode, 0)); - return 0; - } + if (length > (PY_SSIZE_T_MAX / char_size - 1)) { + PyErr_NoMemory(); + return -1; } - assert(_PyUnicode_WSTR(unicode) != NULL); + new_size = (length + 1) * char_size; + + if (!share_utf8 && _PyUnicode_HAS_UTF8_MEMORY(unicode)) + { + PyObject_Free(_PyUnicode_UTF8(unicode)); + _PyUnicode_UTF8(unicode) = NULL; + _PyUnicode_UTF8_LENGTH(unicode) = 0; + } + + data = (PyObject *)PyObject_Realloc(data, new_size); + if (data == NULL) { + PyErr_NoMemory(); + return -1; + } + _PyUnicode_DATA_ANY(unicode) = data; + if (share_utf8) { + _PyUnicode_UTF8(unicode) = data; + _PyUnicode_UTF8_LENGTH(unicode) = length; + } + _PyUnicode_LENGTH(unicode) = length; + PyUnicode_WRITE(PyUnicode_KIND(unicode), data, length, 0); +#ifdef Py_DEBUG + unicode_fill_invalid(unicode, old_length); +#endif /* check for integer overflow */ if (length > PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(wchar_t) - 1) { PyErr_NoMemory(); return -1; } - new_size = sizeof(wchar_t) * (length + 1); - wstr = _PyUnicode_WSTR(unicode); - wstr = PyObject_Realloc(wstr, new_size); - if (!wstr) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_WSTR(unicode) = wstr; - _PyUnicode_WSTR(unicode)[length] = 0; - _PyUnicode_WSTR_LENGTH(unicode) = length; assert(_PyUnicode_CheckConsistency(unicode, 0)); return 0; } @@ -1180,99 +1033,15 @@ static PyObject* resize_copy(PyObject *unicode, Py_ssize_t length) { Py_ssize_t copy_length; - if (_PyUnicode_KIND(unicode) != PyUnicode_WCHAR_KIND) { - PyObject *copy; + PyObject *copy; - assert(PyUnicode_IS_READY(unicode)); - - copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode)); - if (copy == NULL) - return NULL; - - copy_length = Py_MIN(length, PyUnicode_GET_LENGTH(unicode)); - _PyUnicode_FastCopyCharacters(copy, 0, unicode, 0, copy_length); - return copy; - } - else { - PyObject *w; - - w = (PyObject*)_PyUnicode_New(length); - if (w == NULL) - return NULL; - copy_length = _PyUnicode_WSTR_LENGTH(unicode); - copy_length = Py_MIN(copy_length, length); - memcpy(_PyUnicode_WSTR(w), _PyUnicode_WSTR(unicode), - copy_length * sizeof(wchar_t)); - return w; - } -} - -/* We allocate one more byte to make sure the string is - Ux0000 terminated; some code (e.g. new_identifier) - relies on that. - - XXX This allocator could further be enhanced by assuring that the - free list never reduces its size below 1. - -*/ - -static PyUnicodeObject * -_PyUnicode_New(Py_ssize_t length) -{ - PyUnicodeObject *unicode; - size_t new_size; - - /* Optimization for empty strings */ - if (length == 0) { - return (PyUnicodeObject *)unicode_new_empty(); - } - - /* Ensure we won't overflow the size. */ - if (length > ((PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(Py_UNICODE)) - 1)) { - return (PyUnicodeObject *)PyErr_NoMemory(); - } - if (length < 0) { - PyErr_SetString(PyExc_SystemError, - "Negative size passed to _PyUnicode_New"); + copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode)); + if (copy == NULL) return NULL; - } - unicode = PyObject_New(PyUnicodeObject, &PyUnicode_Type); - if (unicode == NULL) - return NULL; - new_size = sizeof(Py_UNICODE) * ((size_t)length + 1); - - _PyUnicode_WSTR_LENGTH(unicode) = length; - _PyUnicode_HASH(unicode) = -1; - _PyUnicode_STATE(unicode).interned = 0; - _PyUnicode_STATE(unicode).kind = 0; - _PyUnicode_STATE(unicode).compact = 0; - _PyUnicode_STATE(unicode).ready = 0; - _PyUnicode_STATE(unicode).ascii = 0; - _PyUnicode_DATA_ANY(unicode) = NULL; - _PyUnicode_LENGTH(unicode) = 0; - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - - _PyUnicode_WSTR(unicode) = (Py_UNICODE*) PyObject_Malloc(new_size); - if (!_PyUnicode_WSTR(unicode)) { - Py_DECREF(unicode); - PyErr_NoMemory(); - return NULL; - } - - /* Initialize the first element to guard against cases where - * the caller fails before initializing str -- unicode_resize() - * reads str[0], and the Keep-Alive optimization can keep memory - * allocated for str alive across a call to unicode_dealloc(unicode). - * We don't want unicode_resize to read uninitialized memory in - * that case. - */ - _PyUnicode_WSTR(unicode)[0] = 0; - _PyUnicode_WSTR(unicode)[length] = 0; - - assert(_PyUnicode_CheckConsistency((PyObject *)unicode, 0)); - return unicode; + copy_length = Py_MIN(length, PyUnicode_GET_LENGTH(unicode)); + _PyUnicode_FastCopyCharacters(copy, 0, unicode, 0, copy_length); + return copy; } static const char* @@ -1282,8 +1051,6 @@ unicode_kind_name(PyObject *unicode) _PyUnicode_Dump() */ if (!PyUnicode_IS_COMPACT(unicode)) { - if (!PyUnicode_IS_READY(unicode)) - return "wstr"; switch (PyUnicode_KIND(unicode)) { case PyUnicode_1BYTE_KIND: @@ -1299,7 +1066,6 @@ unicode_kind_name(PyObject *unicode) return ""; } } - assert(PyUnicode_IS_READY(unicode)); switch (PyUnicode_KIND(unicode)) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(unicode)) @@ -1331,8 +1097,8 @@ const void *_PyUnicode_data(void *unicode_raw) { printf("obj %p\n", (void*)unicode); printf("compact %d\n", PyUnicode_IS_COMPACT(unicode)); printf("compact ascii %d\n", PyUnicode_IS_COMPACT_ASCII(unicode)); - printf("ascii op %p\n", ((void*)((PyASCIIObject*)(unicode) + 1))); - printf("compact op %p\n", ((void*)((PyCompactUnicodeObject*)(unicode) + 1))); + printf("ascii op %p\n", (void*)(_PyASCIIObject_CAST(unicode) + 1)); + printf("compact op %p\n", (void*)(_PyCompactUnicodeObject_CAST(unicode) + 1)); printf("compact data %p\n", _PyUnicode_COMPACT_DATA(unicode)); return PyUnicode_DATA(unicode); } @@ -1340,9 +1106,9 @@ const void *_PyUnicode_data(void *unicode_raw) { void _PyUnicode_Dump(PyObject *op) { - PyASCIIObject *ascii = (PyASCIIObject *)op; - PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op; - PyUnicodeObject *unicode = (PyUnicodeObject *)op; + PyASCIIObject *ascii = _PyASCIIObject_CAST(op); + PyCompactUnicodeObject *compact = _PyCompactUnicodeObject_CAST(op); + PyUnicodeObject *unicode = _PyUnicodeObject_CAST(op); const void *data; if (ascii->state.compact) @@ -1356,40 +1122,13 @@ _PyUnicode_Dump(PyObject *op) data = unicode->data.any; printf("%s: len=%zu, ", unicode_kind_name(op), ascii->length); - if (ascii->wstr == data) - printf("shared "); - printf("wstr=%p", (void *)ascii->wstr); - - if (!(ascii->state.ascii == 1 && ascii->state.compact == 1)) { - printf(" (%zu), ", compact->wstr_length); - if (!ascii->state.compact && compact->utf8 == unicode->data.any) { - printf("shared "); - } + if (!ascii->state.ascii) { printf("utf8=%p (%zu)", (void *)compact->utf8, compact->utf8_length); } printf(", data=%p\n", data); } #endif -static int -unicode_create_empty_string_singleton(struct _Py_unicode_state *state) -{ - // Use size=1 rather than size=0, so PyUnicode_New(0, maxchar) can be - // optimized to always use state->empty_string without having to check if - // it is NULL or not. - PyObject *empty = PyUnicode_New(1, 0); - if (empty == NULL) { - return -1; - } - PyUnicode_1BYTE_DATA(empty)[0] = 0; - _PyUnicode_LENGTH(empty) = 0; - assert(_PyUnicode_CheckConsistency(empty, 1)); - - assert(state->empty_string == NULL); - state->empty_string = empty; - return 0; -} - PyObject * PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) @@ -1402,13 +1141,12 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) PyObject *obj; PyCompactUnicodeObject *unicode; void *data; - enum PyUnicode_Kind kind; - int is_sharing, is_ascii; + int kind; + int is_ascii; Py_ssize_t char_size; Py_ssize_t struct_size; is_ascii = 0; - is_sharing = 0; struct_size = sizeof(PyCompactUnicodeObject); if (maxchar < 128) { kind = PyUnicode_1BYTE_KIND; @@ -1423,8 +1161,6 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) else if (maxchar < 65536) { kind = PyUnicode_2BYTE_KIND; char_size = 2; - if (sizeof(wchar_t) == 2) - is_sharing = 1; } else { if (maxchar > MAX_UNICODE) { @@ -1434,8 +1170,6 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) } kind = PyUnicode_4BYTE_KIND; char_size = 4; - if (sizeof(wchar_t) == 4) - is_sharing = 1; } /* Ensure we won't overflow the size. */ @@ -1467,16 +1201,12 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) _PyUnicode_STATE(unicode).interned = 0; _PyUnicode_STATE(unicode).kind = kind; _PyUnicode_STATE(unicode).compact = 1; - _PyUnicode_STATE(unicode).ready = 1; _PyUnicode_STATE(unicode).ascii = is_ascii; if (is_ascii) { ((char*)data)[size] = 0; - _PyUnicode_WSTR(unicode) = NULL; } else if (kind == PyUnicode_1BYTE_KIND) { ((char*)data)[size] = 0; - _PyUnicode_WSTR(unicode) = NULL; - _PyUnicode_WSTR_LENGTH(unicode) = 0; unicode->utf8 = NULL; unicode->utf8_length = 0; } @@ -1487,14 +1217,6 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) ((Py_UCS2*)data)[size] = 0; else /* kind == PyUnicode_4BYTE_KIND */ ((Py_UCS4*)data)[size] = 0; - if (is_sharing) { - _PyUnicode_WSTR_LENGTH(unicode) = size; - _PyUnicode_WSTR(unicode) = (wchar_t *)data; - } - else { - _PyUnicode_WSTR_LENGTH(unicode) = 0; - _PyUnicode_WSTR(unicode) = NULL; - } } #ifdef Py_DEBUG unicode_fill_invalid((PyObject*)unicode, 0); @@ -1559,7 +1281,7 @@ _copy_characters(PyObject *to, Py_ssize_t to_start, PyObject *from, Py_ssize_t from_start, Py_ssize_t how_many, int check_maxchar) { - unsigned int from_kind, to_kind; + int from_kind, to_kind; const void *from_data; void *to_data; @@ -1567,11 +1289,9 @@ _copy_characters(PyObject *to, Py_ssize_t to_start, assert(0 <= from_start); assert(0 <= to_start); assert(PyUnicode_Check(from)); - assert(PyUnicode_IS_READY(from)); assert(from_start + how_many <= PyUnicode_GET_LENGTH(from)); assert(PyUnicode_Check(to)); - assert(PyUnicode_IS_READY(to)); assert(to_start + how_many <= PyUnicode_GET_LENGTH(to)); if (how_many == 0) @@ -1716,11 +1436,6 @@ PyUnicode_CopyCharacters(PyObject *to, Py_ssize_t to_start, return -1; } - if (PyUnicode_READY(from) == -1) - return -1; - if (PyUnicode_READY(to) == -1) - return -1; - if ((size_t)from_start > (size_t)PyUnicode_GET_LENGTH(from)) { PyErr_SetString(PyExc_IndexError, "string index out of range"); return -1; @@ -1805,135 +1520,6 @@ find_maxchar_surrogates(const wchar_t *begin, const wchar_t *end, return 0; } -int -_PyUnicode_Ready(PyObject *unicode) -{ - wchar_t *end; - Py_UCS4 maxchar = 0; - Py_ssize_t num_surrogates; -#if SIZEOF_WCHAR_T == 2 - Py_ssize_t length_wo_surrogates; -#endif - - /* _PyUnicode_Ready() is only intended for old-style API usage where - strings were created using _PyObject_New() and where no canonical - representation (the str field) has been set yet aka strings - which are not yet ready. */ - assert(_PyUnicode_CHECK(unicode)); - assert(_PyUnicode_KIND(unicode) == PyUnicode_WCHAR_KIND); - assert(_PyUnicode_WSTR(unicode) != NULL); - assert(_PyUnicode_DATA_ANY(unicode) == NULL); - assert(_PyUnicode_UTF8(unicode) == NULL); - /* Actually, it should neither be interned nor be anything else: */ - assert(_PyUnicode_STATE(unicode).interned == SSTATE_NOT_INTERNED); - - end = _PyUnicode_WSTR(unicode) + _PyUnicode_WSTR_LENGTH(unicode); - if (find_maxchar_surrogates(_PyUnicode_WSTR(unicode), end, - &maxchar, &num_surrogates) == -1) - return -1; - - if (maxchar < 256) { - _PyUnicode_DATA_ANY(unicode) = PyObject_Malloc(_PyUnicode_WSTR_LENGTH(unicode) + 1); - if (!_PyUnicode_DATA_ANY(unicode)) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_CONVERT_BYTES(wchar_t, unsigned char, - _PyUnicode_WSTR(unicode), end, - PyUnicode_1BYTE_DATA(unicode)); - PyUnicode_1BYTE_DATA(unicode)[_PyUnicode_WSTR_LENGTH(unicode)] = '\0'; - _PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); - _PyUnicode_STATE(unicode).kind = PyUnicode_1BYTE_KIND; - if (maxchar < 128) { - _PyUnicode_STATE(unicode).ascii = 1; - _PyUnicode_UTF8(unicode) = _PyUnicode_DATA_ANY(unicode); - _PyUnicode_UTF8_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); - } - else { - _PyUnicode_STATE(unicode).ascii = 0; - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - } - PyObject_Free(_PyUnicode_WSTR(unicode)); - _PyUnicode_WSTR(unicode) = NULL; - _PyUnicode_WSTR_LENGTH(unicode) = 0; - } - /* In this case we might have to convert down from 4-byte native - wchar_t to 2-byte unicode. */ - else if (maxchar < 65536) { - assert(num_surrogates == 0 && - "FindMaxCharAndNumSurrogatePairs() messed up"); - -#if SIZEOF_WCHAR_T == 2 - /* We can share representations and are done. */ - _PyUnicode_DATA_ANY(unicode) = _PyUnicode_WSTR(unicode); - PyUnicode_2BYTE_DATA(unicode)[_PyUnicode_WSTR_LENGTH(unicode)] = '\0'; - _PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); - _PyUnicode_STATE(unicode).kind = PyUnicode_2BYTE_KIND; - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; -#else - /* sizeof(wchar_t) == 4 */ - _PyUnicode_DATA_ANY(unicode) = PyObject_Malloc( - 2 * (_PyUnicode_WSTR_LENGTH(unicode) + 1)); - if (!_PyUnicode_DATA_ANY(unicode)) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_CONVERT_BYTES(wchar_t, Py_UCS2, - _PyUnicode_WSTR(unicode), end, - PyUnicode_2BYTE_DATA(unicode)); - PyUnicode_2BYTE_DATA(unicode)[_PyUnicode_WSTR_LENGTH(unicode)] = '\0'; - _PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); - _PyUnicode_STATE(unicode).kind = PyUnicode_2BYTE_KIND; - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - PyObject_Free(_PyUnicode_WSTR(unicode)); - _PyUnicode_WSTR(unicode) = NULL; - _PyUnicode_WSTR_LENGTH(unicode) = 0; -#endif - } - /* maxchar exceeds 16 bit, wee need 4 bytes for unicode characters */ - else { -#if SIZEOF_WCHAR_T == 2 - /* in case the native representation is 2-bytes, we need to allocate a - new normalized 4-byte version. */ - length_wo_surrogates = _PyUnicode_WSTR_LENGTH(unicode) - num_surrogates; - if (length_wo_surrogates > PY_SSIZE_T_MAX / 4 - 1) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_DATA_ANY(unicode) = PyObject_Malloc(4 * (length_wo_surrogates + 1)); - if (!_PyUnicode_DATA_ANY(unicode)) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_LENGTH(unicode) = length_wo_surrogates; - _PyUnicode_STATE(unicode).kind = PyUnicode_4BYTE_KIND; - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - /* unicode_convert_wchar_to_ucs4() requires a ready string */ - _PyUnicode_STATE(unicode).ready = 1; - unicode_convert_wchar_to_ucs4(_PyUnicode_WSTR(unicode), end, unicode); - PyObject_Free(_PyUnicode_WSTR(unicode)); - _PyUnicode_WSTR(unicode) = NULL; - _PyUnicode_WSTR_LENGTH(unicode) = 0; -#else - assert(num_surrogates == 0); - - _PyUnicode_DATA_ANY(unicode) = _PyUnicode_WSTR(unicode); - _PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - _PyUnicode_STATE(unicode).kind = PyUnicode_4BYTE_KIND; -#endif - PyUnicode_4BYTE_DATA(unicode)[_PyUnicode_LENGTH(unicode)] = '\0'; - } - _PyUnicode_STATE(unicode).ready = 1; - assert(_PyUnicode_CheckConsistency(unicode, 1)); - return 0; -} - static void unicode_dealloc(PyObject *unicode) { @@ -1942,14 +1528,8 @@ unicode_dealloc(PyObject *unicode) _Py_FatalRefcountError("deallocating an Unicode singleton"); } #endif - - switch (PyUnicode_CHECK_INTERNED(unicode)) { - case SSTATE_NOT_INTERNED: - break; - - case SSTATE_INTERNED_MORTAL: - { - struct _Py_unicode_state *state = get_unicode_state(); + PyObject *interned = get_interned_dict(); + if (PyUnicode_CHECK_INTERNED(unicode)) { /* Revive the dead object temporarily. PyDict_DelItem() removes two references (key and value) which were ignored by PyUnicode_InternInPlace(). Use refcnt=3 rather than refcnt=2 @@ -1957,26 +1537,14 @@ unicode_dealloc(PyObject *unicode) PyDict_DelItem(). */ assert(Py_REFCNT(unicode) == 0); Py_SET_REFCNT(unicode, 3); - if (PyDict_DelItem(state->interned, unicode) != 0) { + if (PyDict_DelItem(interned, unicode) != 0) { _PyErr_WriteUnraisableMsg("deletion of interned string failed", NULL); } assert(Py_REFCNT(unicode) == 1); Py_SET_REFCNT(unicode, 0); - break; } - case SSTATE_INTERNED_IMMORTAL: - _PyObject_ASSERT_FAILED_MSG(unicode, "Immortal interned string died"); - break; - - default: - Py_UNREACHABLE(); - } - - if (_PyUnicode_HAS_WSTR_MEMORY(unicode)) { - PyObject_Free(_PyUnicode_WSTR(unicode)); - } if (_PyUnicode_HAS_UTF8_MEMORY(unicode)) { PyObject_Free(_PyUnicode_UTF8(unicode)); } @@ -1991,14 +1559,14 @@ unicode_dealloc(PyObject *unicode) static int unicode_is_singleton(PyObject *unicode) { - struct _Py_unicode_state *state = get_unicode_state(); - if (unicode == state->empty_string) { + if (unicode == &_Py_STR(empty)) { return 1; } - PyASCIIObject *ascii = (PyASCIIObject *)unicode; - if (ascii->state.kind != PyUnicode_WCHAR_KIND && ascii->length == 1) { + + PyASCIIObject *ascii = _PyASCIIObject_CAST(unicode); + if (ascii->length == 1) { Py_UCS4 ch = PyUnicode_READ_CHAR(unicode, 0); - if (ch < 256 && state->latin1[ch] == unicode) { + if (ch < 256 && LATIN1(ch) == unicode) { return 1; } } @@ -2038,10 +1606,7 @@ unicode_resize(PyObject **p_unicode, Py_ssize_t length) assert(PyUnicode_Check(unicode)); assert(0 <= length); - if (_PyUnicode_KIND(unicode) == PyUnicode_WCHAR_KIND) - old_length = PyUnicode_WSTR_LENGTH(unicode); - else - old_length = PyUnicode_GET_LENGTH(unicode); + old_length = PyUnicode_GET_LENGTH(unicode); if (old_length == length) return 0; @@ -2095,7 +1660,7 @@ static void unicode_write_cstr(PyObject *unicode, Py_ssize_t index, const char *str, Py_ssize_t len) { - enum PyUnicode_Kind kind = PyUnicode_KIND(unicode); + int kind = PyUnicode_KIND(unicode); const void *data = PyUnicode_DATA(unicode); const char *end = str + len; @@ -2141,25 +1706,7 @@ unicode_write_cstr(PyObject *unicode, Py_ssize_t index, static PyObject* get_latin1_char(Py_UCS1 ch) { - struct _Py_unicode_state *state = get_unicode_state(); - - PyObject *unicode = state->latin1[ch]; - if (unicode) { - Py_INCREF(unicode); - return unicode; - } - - unicode = PyUnicode_New(1, ch); - if (!unicode) { - return NULL; - } - - PyUnicode_1BYTE_DATA(unicode)[0] = ch; - assert(_PyUnicode_CheckConsistency(unicode, 1)); - - Py_INCREF(unicode); - state->latin1[ch] = unicode; - return unicode; + return Py_NewRef(LATIN1(ch)); } static PyObject* @@ -2188,28 +1735,6 @@ unicode_char(Py_UCS4 ch) return unicode; } -PyObject * -PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size) -{ - if (u == NULL) { - if (size > 0) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PyUnicode_FromUnicode(NULL, size) is deprecated; " - "use PyUnicode_New() instead", 1) < 0) { - return NULL; - } - } - return (PyObject*)_PyUnicode_New(size); - } - - if (size < 0) { - PyErr_BadInternalCall(); - return NULL; - } - - return PyUnicode_FromWideChar(u, size); -} - PyObject * PyUnicode_FromWideChar(const wchar_t *u, Py_ssize_t size) { @@ -2303,16 +1828,12 @@ PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size) if (u != NULL) { return PyUnicode_DecodeUTF8Stateful(u, size, NULL, NULL); } - else { - if (size > 0) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PyUnicode_FromStringAndSize(NULL, size) is deprecated; " - "use PyUnicode_New() instead", 1) < 0) { - return NULL; - } - } - return (PyObject *)_PyUnicode_New(size); + if (size > 0) { + PyErr_SetString(PyExc_SystemError, + "NULL string with positive size with NULL passed to PyUnicode_FromStringAndSize"); + return NULL; } + return unicode_new_empty(); } PyObject * @@ -2335,7 +1856,7 @@ _PyUnicode_FromId(_Py_Identifier *id) Py_ssize_t index = _Py_atomic_size_get(&id->index); if (index < 0) { - struct _Py_unicode_runtime_ids *rt_ids = &interp->runtime->unicode_ids; + struct _Py_unicode_runtime_ids *rt_ids = &interp->runtime->unicode_state.ids; PyThread_acquire_lock(rt_ids->lock, WAIT_LOCK); // Check again to detect concurrent access. Another thread can have @@ -2426,7 +1947,7 @@ _PyUnicode_FromASCII(const char *buffer, Py_ssize_t size) } static Py_UCS4 -kind_maxchar_limit(unsigned int kind) +kind_maxchar_limit(int kind) { switch (kind) { case PyUnicode_1BYTE_KIND: @@ -2540,10 +2061,9 @@ PyUnicode_FromKindAndData(int kind, const void *buffer, Py_ssize_t size) Py_UCS4 _PyUnicode_FindMaxChar(PyObject *unicode, Py_ssize_t start, Py_ssize_t end) { - enum PyUnicode_Kind kind; + int kind; const void *startptr, *endptr; - assert(PyUnicode_IS_READY(unicode)); assert(0 <= start); assert(end <= PyUnicode_GET_LENGTH(unicode)); assert(start <= end); @@ -2582,11 +2102,10 @@ unicode_adjust_maxchar(PyObject **p_unicode) PyObject *unicode, *copy; Py_UCS4 max_char; Py_ssize_t len; - unsigned int kind; + int kind; assert(p_unicode != NULL); unicode = *p_unicode; - assert(PyUnicode_IS_READY(unicode)); if (PyUnicode_IS_ASCII(unicode)) return; @@ -2630,8 +2149,6 @@ _PyUnicode_Copy(PyObject *unicode) PyErr_BadInternalCall(); return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; length = PyUnicode_GET_LENGTH(unicode); copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode)); @@ -2650,7 +2167,7 @@ _PyUnicode_Copy(PyObject *unicode) character. Return NULL on error. */ static void* -unicode_askind(unsigned int skind, void const *data, Py_ssize_t len, unsigned int kind) +unicode_askind(int skind, void const *data, Py_ssize_t len, int kind) { void *result; @@ -2700,8 +2217,6 @@ as_ucs4(PyObject *string, Py_UCS4 *target, Py_ssize_t targetsize, int kind; const void *data; Py_ssize_t len, targetlen; - if (PyUnicode_READY(string) == -1) - return NULL; kind = PyUnicode_KIND(string); data = PyUnicode_DATA(string); len = PyUnicode_GET_LENGTH(string); @@ -2772,9 +2287,6 @@ unicode_fromformat_write_str(_PyUnicodeWriter *writer, PyObject *str, Py_ssize_t length, fill, arglen; Py_UCS4 maxchar; - if (PyUnicode_READY(str) == -1) - return -1; - length = PyUnicode_GET_LENGTH(str); if ((precision == -1 || precision >= length) && width <= length) @@ -2848,6 +2360,13 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, p = f; f++; + if (*f == '%') { + if (_PyUnicodeWriter_WriteCharInline(writer, '%') < 0) + return NULL; + f++; + return f; + } + zeropad = 0; if (*f == '0') { zeropad = 1; @@ -2885,14 +2404,6 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, f++; } } - if (*f == '%') { - /* "%.3%s" => f points to "3" */ - f--; - } - } - if (*f == '\0') { - /* bogus format "%.123" => go backward, f points to "3" */ - f--; } /* Handle %ld, %lu, %lld and %llu. */ @@ -2916,7 +2427,7 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, ++f; } - if (f[1] == '\0') + if (f[0] != '\0' && f[1] == '\0') writer->overallocate = 0; switch (*f) { @@ -2975,21 +2486,34 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, } assert(len >= 0); - if (precision < len) - precision = len; + int negative = (buffer[0] == '-'); + len -= negative; + + precision = Py_MAX(precision, len); + width = Py_MAX(width, precision + negative); arglen = Py_MAX(precision, width); if (_PyUnicodeWriter_Prepare(writer, arglen, 127) == -1) return NULL; if (width > precision) { - Py_UCS4 fillchar; - fill = width - precision; - fillchar = zeropad?'0':' '; + if (negative && zeropad) { + if (_PyUnicodeWriter_WriteChar(writer, '-') == -1) + return NULL; + } + + Py_UCS4 fillchar = zeropad?'0':' '; + fill = width - precision - negative; if (PyUnicode_Fill(writer->buffer, writer->pos, fill, fillchar) == -1) return NULL; writer->pos += fill; + + if (negative && !zeropad) { + if (_PyUnicodeWriter_WriteChar(writer, '-') == -1) + return NULL; + } } + if (precision > len) { fill = precision - len; if (PyUnicode_Fill(writer->buffer, writer->pos, fill, '0') == -1) @@ -2997,7 +2521,7 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, writer->pos += fill; } - if (_PyUnicodeWriter_WriteASCIIString(writer, buffer, len) < 0) + if (_PyUnicodeWriter_WriteASCIIString(writer, &buffer[negative], len) < 0) return NULL; break; } @@ -3109,21 +2633,9 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, break; } - case '%': - if (_PyUnicodeWriter_WriteCharInline(writer, '%') < 0) - return NULL; - break; - default: - /* if we stumble upon an unknown formatting code, copy the rest - of the format string to the output string. (we cannot just - skip the code, since there's no way to know what's in the - argument list) */ - len = strlen(p); - if (_PyUnicodeWriter_WriteLatin1String(writer, p, len) == -1) - return NULL; - f = p+len; - return f; + PyErr_Format(PyExc_SystemError, "invalid format string: %s", p); + return NULL; } f++; @@ -3193,11 +2705,7 @@ PyUnicode_FromFormat(const char *format, ...) PyObject* ret; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif ret = PyUnicode_FromFormatV(format, vargs); va_end(vargs); return ret; @@ -3211,13 +2719,6 @@ unicode_get_widechar_size(PyObject *unicode) assert(unicode != NULL); assert(_PyUnicode_CHECK(unicode)); -#if USE_UNICODE_WCHAR_CACHE - if (_PyUnicode_WSTR(unicode) != NULL) { - return PyUnicode_WSTR_LENGTH(unicode); - } -#endif /* USE_UNICODE_WCHAR_CACHE */ - assert(PyUnicode_IS_READY(unicode)); - res = _PyUnicode_LENGTH(unicode); #if SIZEOF_WCHAR_T == 2 if (PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND) { @@ -3239,19 +2740,10 @@ unicode_copy_as_widechar(PyObject *unicode, wchar_t *w, Py_ssize_t size) assert(unicode != NULL); assert(_PyUnicode_CHECK(unicode)); -#if USE_UNICODE_WCHAR_CACHE - const wchar_t *wstr = _PyUnicode_WSTR(unicode); - if (wstr != NULL) { - memcpy(w, wstr, size * sizeof(wchar_t)); - return; - } -#else /* USE_UNICODE_WCHAR_CACHE */ if (PyUnicode_KIND(unicode) == sizeof(wchar_t)) { memcpy(w, PyUnicode_DATA(unicode), size * sizeof(wchar_t)); return; } -#endif /* USE_UNICODE_WCHAR_CACHE */ - assert(PyUnicode_IS_READY(unicode)); if (PyUnicode_KIND(unicode) == PyUnicode_1BYTE_KIND) { const Py_UCS1 *s = PyUnicode_1BYTE_DATA(unicode); @@ -3326,7 +2818,7 @@ PyUnicode_AsWideChar(PyObject *unicode, } unicode_copy_as_widechar(unicode, w, size); -#if HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION +#ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION /* Oracle Solaris uses non-Unicode internal wchar_t form for non-Unicode locales and hence needs conversion first. */ if (_Py_LocaleUsesNonUnicodeWchar()) { @@ -3356,14 +2848,14 @@ PyUnicode_AsWideCharString(PyObject *unicode, } buflen = unicode_get_widechar_size(unicode); - buffer = (wchar_t *) PyMem_NEW(wchar_t, (buflen + 1)); + buffer = (wchar_t *) PyMem_New(wchar_t, (buflen + 1)); if (buffer == NULL) { PyErr_NoMemory(); return NULL; } unicode_copy_as_widechar(unicode, buffer, buflen + 1); -#if HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION +#ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION /* Oracle Solaris uses non-Unicode internal wchar_t form for non-Unicode locales and hence needs conversion first. */ if (_Py_LocaleUsesNonUnicodeWchar()) { @@ -3392,26 +2884,16 @@ _PyUnicode_WideCharString_Converter(PyObject *obj, void *ptr) { wchar_t **p = (wchar_t **)ptr; if (obj == NULL) { -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(*p); -#endif /* USE_UNICODE_WCHAR_CACHE */ *p = NULL; return 1; } if (PyUnicode_Check(obj)) { -#if USE_UNICODE_WCHAR_CACHE - *p = (wchar_t *)_PyUnicode_AsUnicode(obj); - if (*p == NULL) { - return 0; - } - return 1; -#else /* USE_UNICODE_WCHAR_CACHE */ *p = PyUnicode_AsWideCharString(obj, NULL); if (*p == NULL) { return 0; } return Py_CLEANUP_SUPPORTED; -#endif /* USE_UNICODE_WCHAR_CACHE */ } PyErr_Format(PyExc_TypeError, "argument must be str, not %.50s", @@ -3424,9 +2906,7 @@ _PyUnicode_WideCharString_Opt_Converter(PyObject *obj, void *ptr) { wchar_t **p = (wchar_t **)ptr; if (obj == NULL) { -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(*p); -#endif /* USE_UNICODE_WCHAR_CACHE */ *p = NULL; return 1; } @@ -3435,19 +2915,11 @@ _PyUnicode_WideCharString_Opt_Converter(PyObject *obj, void *ptr) return 1; } if (PyUnicode_Check(obj)) { -#if USE_UNICODE_WCHAR_CACHE - *p = (wchar_t *)_PyUnicode_AsUnicode(obj); - if (*p == NULL) { - return 0; - } - return 1; -#else /* USE_UNICODE_WCHAR_CACHE */ *p = PyUnicode_AsWideCharString(obj, NULL); if (*p == NULL) { return 0; } return Py_CLEANUP_SUPPORTED; -#endif /* USE_UNICODE_WCHAR_CACHE */ } PyErr_Format(PyExc_TypeError, "argument must be str or None, not %.50s", @@ -3473,10 +2945,7 @@ PyUnicode_FromObject(PyObject *obj) /* XXX Perhaps we should make this API an alias of PyObject_Str() instead ?! */ if (PyUnicode_CheckExact(obj)) { - if (PyUnicode_READY(obj) == -1) - return NULL; - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } if (PyUnicode_Check(obj)) { /* For a Unicode subtype that's not a Unicode object, @@ -4147,48 +3616,25 @@ PyUnicode_FSConverter(PyObject* arg, void* addr) int PyUnicode_FSDecoder(PyObject* arg, void* addr) { - int is_buffer = 0; - PyObject *path = NULL; - PyObject *output = NULL; if (arg == NULL) { Py_DECREF(*(PyObject**)addr); *(PyObject**)addr = NULL; return 1; } - is_buffer = PyObject_CheckBuffer(arg); - if (!is_buffer) { - path = PyOS_FSPath(arg); - if (path == NULL) { - return 0; - } - } - else { - path = arg; - Py_INCREF(arg); + PyObject *path = PyOS_FSPath(arg); + if (path == NULL) { + return 0; } + PyObject *output = NULL; if (PyUnicode_Check(path)) { output = path; } - else if (PyBytes_Check(path) || is_buffer) { - PyObject *path_bytes = NULL; - - if (!PyBytes_Check(path) && - PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "path should be string, bytes, or os.PathLike, not %.200s", - Py_TYPE(arg)->tp_name)) { - Py_DECREF(path); - return 0; - } - path_bytes = PyBytes_FromObject(path); + else if (PyBytes_Check(path)) { + output = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AS_STRING(path), + PyBytes_GET_SIZE(path)); Py_DECREF(path); - if (!path_bytes) { - return 0; - } - output = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AS_STRING(path_bytes), - PyBytes_GET_SIZE(path_bytes)); - Py_DECREF(path_bytes); if (!output) { return 0; } @@ -4200,10 +3646,7 @@ PyUnicode_FSDecoder(PyObject* arg, void* addr) Py_DECREF(path); return 0; } - if (PyUnicode_READY(output) == -1) { - Py_DECREF(output); - return 0; - } + if (findchar(PyUnicode_DATA(output), PyUnicode_KIND(output), PyUnicode_GET_LENGTH(output), 0, 1) >= 0) { PyErr_SetString(PyExc_ValueError, "embedded null character"); @@ -4224,8 +3667,6 @@ PyUnicode_AsUTF8AndSize(PyObject *unicode, Py_ssize_t *psize) PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; if (PyUnicode_UTF8(unicode) == NULL) { if (unicode_fill_utf8(unicode) == -1) { @@ -4244,85 +3685,22 @@ PyUnicode_AsUTF8(PyObject *unicode) return PyUnicode_AsUTF8AndSize(unicode, NULL); } -Py_UNICODE * -PyUnicode_AsUnicodeAndSize(PyObject *unicode, Py_ssize_t *size) -{ - if (!PyUnicode_Check(unicode)) { - PyErr_BadArgument(); - return NULL; - } - Py_UNICODE *w = _PyUnicode_WSTR(unicode); - if (w == NULL) { - /* Non-ASCII compact unicode object */ - assert(_PyUnicode_KIND(unicode) != PyUnicode_WCHAR_KIND); - assert(PyUnicode_IS_READY(unicode)); +/* +PyUnicode_GetSize() has been deprecated since Python 3.3 +because it returned length of Py_UNICODE. - Py_ssize_t wlen = unicode_get_widechar_size(unicode); - if ((size_t)wlen > PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) { - PyErr_NoMemory(); - return NULL; - } - w = (wchar_t *) PyObject_Malloc(sizeof(wchar_t) * (wlen + 1)); - if (w == NULL) { - PyErr_NoMemory(); - return NULL; - } - unicode_copy_as_widechar(unicode, w, wlen + 1); - _PyUnicode_WSTR(unicode) = w; - if (!PyUnicode_IS_COMPACT_ASCII(unicode)) { - _PyUnicode_WSTR_LENGTH(unicode) = wlen; - } - } - if (size != NULL) - *size = PyUnicode_WSTR_LENGTH(unicode); - return w; -} - -/* Deprecated APIs */ - -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - -Py_UNICODE * -PyUnicode_AsUnicode(PyObject *unicode) -{ - return PyUnicode_AsUnicodeAndSize(unicode, NULL); -} - -const Py_UNICODE * -_PyUnicode_AsUnicode(PyObject *unicode) -{ - Py_ssize_t size; - const Py_UNICODE *wstr; - - wstr = PyUnicode_AsUnicodeAndSize(unicode, &size); - if (wstr && wcslen(wstr) != (size_t)size) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - return NULL; - } - return wstr; -} - - -Py_ssize_t +But this function is part of stable abi, because it don't +include Py_UNICODE in signature and it was not excluded from +stable abi in PEP 384. +*/ +PyAPI_FUNC(Py_ssize_t) PyUnicode_GetSize(PyObject *unicode) { - if (!PyUnicode_Check(unicode)) { - PyErr_BadArgument(); - goto onError; - } - if (_PyUnicode_WSTR(unicode) == NULL) { - if (PyUnicode_AsUnicode(unicode) == NULL) - goto onError; - } - return PyUnicode_WSTR_LENGTH(unicode); - - onError: + PyErr_SetString(PyExc_RuntimeError, + "PyUnicode_GetSize has been removed."); return -1; } -_Py_COMP_DIAG_POP - Py_ssize_t PyUnicode_GetLength(PyObject *unicode) { @@ -4330,8 +3708,6 @@ PyUnicode_GetLength(PyObject *unicode) PyErr_BadArgument(); return -1; } - if (PyUnicode_READY(unicode) == -1) - return -1; return PyUnicode_GET_LENGTH(unicode); } @@ -4345,9 +3721,6 @@ PyUnicode_ReadChar(PyObject *unicode, Py_ssize_t index) PyErr_BadArgument(); return (Py_UCS4)-1; } - if (PyUnicode_READY(unicode) == -1) { - return (Py_UCS4)-1; - } if (index < 0 || index >= PyUnicode_GET_LENGTH(unicode)) { PyErr_SetString(PyExc_IndexError, "string index out of range"); return (Py_UCS4)-1; @@ -4364,7 +3737,6 @@ PyUnicode_WriteChar(PyObject *unicode, Py_ssize_t index, Py_UCS4 ch) PyErr_BadArgument(); return -1; } - assert(PyUnicode_IS_READY(unicode)); if (index < 0 || index >= PyUnicode_GET_LENGTH(unicode)) { PyErr_SetString(PyExc_IndexError, "string index out of range"); return -1; @@ -4497,19 +3869,10 @@ unicode_decode_call_errorhandler_wchar( goto onError; } -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - repwlen = PyUnicode_GetSize(repunicode); - if (repwlen < 0) - goto onError; -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ repwlen = PyUnicode_AsWideChar(repunicode, NULL, 0); if (repwlen < 0) goto onError; repwlen--; -#endif /* USE_UNICODE_WCHAR_CACHE */ /* need more space? (at least enough for what we have+the replacement+the rest of the string (starting at the new input position), so we won't have to check space @@ -4959,8 +4322,6 @@ _PyUnicode_EncodeUTF7(PyObject *str, char * out; const char * start; - if (PyUnicode_READY(str) == -1) - return NULL; kind = PyUnicode_KIND(str); data = PyUnicode_DATA(str); len = PyUnicode_GET_LENGTH(str); @@ -5169,6 +4530,9 @@ unicode_decode_utf8(const char *s, Py_ssize_t size, } s += ascii_decode(s, end, PyUnicode_1BYTE_DATA(u)); if (s == end) { + if (consumed) { + *consumed = size; + } return u; } @@ -5336,7 +4700,7 @@ _Py_DecodeUTF8Ex(const char *s, Py_ssize_t size, wchar_t **wstr, size_t *wlen, /* Note: size will always be longer than the resulting Unicode character count */ - if (PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(wchar_t) < (size + 1)) { + if (PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(wchar_t) - 1 < size) { return -1; } @@ -5589,14 +4953,11 @@ unicode_encode_utf8(PyObject *unicode, _Py_error_handler error_handler, return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; - if (PyUnicode_UTF8(unicode)) return PyBytes_FromStringAndSize(PyUnicode_UTF8(unicode), PyUnicode_UTF8_LENGTH(unicode)); - enum PyUnicode_Kind kind = PyUnicode_KIND(unicode); + int kind = PyUnicode_KIND(unicode); const void *data = PyUnicode_DATA(unicode); Py_ssize_t size = PyUnicode_GET_LENGTH(unicode); @@ -5632,7 +4993,7 @@ unicode_fill_utf8(PyObject *unicode) /* the string cannot be ASCII, or PyUnicode_UTF8() would be set */ assert(!PyUnicode_IS_ASCII(unicode)); - enum PyUnicode_Kind kind = PyUnicode_KIND(unicode); + int kind = PyUnicode_KIND(unicode); const void *data = PyUnicode_DATA(unicode); Py_ssize_t size = PyUnicode_GET_LENGTH(unicode); @@ -5767,7 +5128,7 @@ PyUnicode_DecodeUTF32Stateful(const char *s, Py_UCS4 maxch = PyUnicode_MAX_CHAR_VALUE(writer.buffer); if (e - q >= 4) { - enum PyUnicode_Kind kind = writer.kind; + int kind = writer.kind; void *data = writer.data; const unsigned char *last = e - 4; Py_ssize_t pos = writer.pos; @@ -5852,7 +5213,7 @@ _PyUnicode_EncodeUTF32(PyObject *str, const char *errors, int byteorder) { - enum PyUnicode_Kind kind; + int kind; const void *data; Py_ssize_t len; PyObject *v; @@ -5872,8 +5233,6 @@ _PyUnicode_EncodeUTF32(PyObject *str, PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(str) == -1) - return NULL; kind = PyUnicode_KIND(str); data = PyUnicode_DATA(str); len = PyUnicode_GET_LENGTH(str); @@ -5907,7 +5266,7 @@ _PyUnicode_EncodeUTF32(PyObject *str, pos = 0; while (pos < len) { - Py_ssize_t repsize, moreunits; + Py_ssize_t newpos, repsize, moreunits; if (kind == PyUnicode_2BYTE_KIND) { pos += ucs2lib_utf32_encode((const Py_UCS2 *)data + pos, len - pos, @@ -5924,7 +5283,7 @@ _PyUnicode_EncodeUTF32(PyObject *str, rep = unicode_encode_call_errorhandler( errors, &errorHandler, encoding, "surrogates not allowed", - str, &exc, pos, pos + 1, &pos); + str, &exc, pos, pos + 1, &newpos); if (!rep) goto error; @@ -5932,7 +5291,7 @@ _PyUnicode_EncodeUTF32(PyObject *str, repsize = PyBytes_GET_SIZE(rep); if (repsize & 3) { raise_encode_exception(&exc, encoding, - str, pos - 1, pos, + str, pos, pos + 1, "surrogates not allowed"); goto error; } @@ -5940,33 +5299,33 @@ _PyUnicode_EncodeUTF32(PyObject *str, } else { assert(PyUnicode_Check(rep)); - if (PyUnicode_READY(rep) < 0) - goto error; moreunits = repsize = PyUnicode_GET_LENGTH(rep); if (!PyUnicode_IS_ASCII(rep)) { raise_encode_exception(&exc, encoding, - str, pos - 1, pos, + str, pos, pos + 1, "surrogates not allowed"); goto error; } } + moreunits += pos - newpos; + pos = newpos; /* four bytes are reserved for each surrogate */ - if (moreunits > 1) { + if (moreunits > 0) { Py_ssize_t outpos = out - (uint32_t*) PyBytes_AS_STRING(v); if (moreunits >= (PY_SSIZE_T_MAX - PyBytes_GET_SIZE(v)) / 4) { /* integer overflow */ PyErr_NoMemory(); goto error; } - if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + 4 * (moreunits - 1)) < 0) + if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + 4 * moreunits) < 0) goto error; out = (uint32_t*) PyBytes_AS_STRING(v) + outpos; } if (PyBytes_Check(rep)) { memcpy(out, PyBytes_AS_STRING(rep), repsize); - out += moreunits; + out += repsize / 4; } else /* rep is unicode */ { assert(PyUnicode_KIND(rep) == PyUnicode_1BYTE_KIND); ucs1lib_utf32_encode(PyUnicode_1BYTE_DATA(rep), repsize, @@ -6171,7 +5530,7 @@ _PyUnicode_EncodeUTF16(PyObject *str, const char *errors, int byteorder) { - enum PyUnicode_Kind kind; + int kind; const void *data; Py_ssize_t len; PyObject *v; @@ -6192,8 +5551,6 @@ _PyUnicode_EncodeUTF16(PyObject *str, PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(str) == -1) - return NULL; kind = PyUnicode_KIND(str); data = PyUnicode_DATA(str); len = PyUnicode_GET_LENGTH(str); @@ -6244,7 +5601,7 @@ _PyUnicode_EncodeUTF16(PyObject *str, pos = 0; while (pos < len) { - Py_ssize_t repsize, moreunits; + Py_ssize_t newpos, repsize, moreunits; if (kind == PyUnicode_2BYTE_KIND) { pos += ucs2lib_utf16_encode((const Py_UCS2 *)data + pos, len - pos, @@ -6261,7 +5618,7 @@ _PyUnicode_EncodeUTF16(PyObject *str, rep = unicode_encode_call_errorhandler( errors, &errorHandler, encoding, "surrogates not allowed", - str, &exc, pos, pos + 1, &pos); + str, &exc, pos, pos + 1, &newpos); if (!rep) goto error; @@ -6269,7 +5626,7 @@ _PyUnicode_EncodeUTF16(PyObject *str, repsize = PyBytes_GET_SIZE(rep); if (repsize & 1) { raise_encode_exception(&exc, encoding, - str, pos - 1, pos, + str, pos, pos + 1, "surrogates not allowed"); goto error; } @@ -6277,33 +5634,33 @@ _PyUnicode_EncodeUTF16(PyObject *str, } else { assert(PyUnicode_Check(rep)); - if (PyUnicode_READY(rep) < 0) - goto error; moreunits = repsize = PyUnicode_GET_LENGTH(rep); if (!PyUnicode_IS_ASCII(rep)) { raise_encode_exception(&exc, encoding, - str, pos - 1, pos, + str, pos, pos + 1, "surrogates not allowed"); goto error; } } + moreunits += pos - newpos; + pos = newpos; /* two bytes are reserved for each surrogate */ - if (moreunits > 1) { + if (moreunits > 0) { Py_ssize_t outpos = out - (unsigned short*) PyBytes_AS_STRING(v); if (moreunits >= (PY_SSIZE_T_MAX - PyBytes_GET_SIZE(v)) / 2) { /* integer overflow */ PyErr_NoMemory(); goto error; } - if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + 2 * (moreunits - 1)) < 0) + if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + 2 * moreunits) < 0) goto error; out = (unsigned short*) PyBytes_AS_STRING(v) + outpos; } if (PyBytes_Check(rep)) { memcpy(out, PyBytes_AS_STRING(rep), repsize); - out += moreunits; + out += repsize / 2; } else /* rep is unicode */ { assert(PyUnicode_KIND(rep) == PyUnicode_1BYTE_KIND); ucs1lib_utf16_encode(PyUnicode_1BYTE_DATA(rep), repsize, @@ -6340,8 +5697,6 @@ PyUnicode_AsUTF16String(PyObject *unicode) /* --- Unicode Escape Codec ----------------------------------------------- */ -static _PyUnicode_Name_CAPI *ucnhash_capi = NULL; - PyObject * _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, Py_ssize_t size, @@ -6354,6 +5709,8 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, const char *end; PyObject *errorHandler = NULL; PyObject *exc = NULL; + _PyUnicode_Name_CAPI *ucnhash_capi; + PyInterpreterState *interp = _PyInterpreterState_Get(); // so we can remember if we've seen an invalid escape char or not *first_invalid_escape = NULL; @@ -6443,6 +5800,12 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, ch = (ch<<3) + *s++ - '0'; } } + if (ch > 0377) { + if (*first_invalid_escape == NULL) { + *first_invalid_escape = s-3; /* Back up 3 chars, since we've + already incremented s. */ + } + } WRITE_CHAR(ch); continue; @@ -6495,6 +5858,7 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, /* \N{name} */ case 'N': + ucnhash_capi = interp->unicode.ucnhash_capi; if (ucnhash_capi == NULL) { /* load the unicode data module */ ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import( @@ -6506,6 +5870,7 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, ); goto onError; } + interp->unicode.ucnhash_capi = ucnhash_capi; } message = "malformed \\N character escape"; @@ -6593,11 +5958,24 @@ _PyUnicode_DecodeUnicodeEscapeStateful(const char *s, if (result == NULL) return NULL; if (first_invalid_escape != NULL) { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "invalid escape sequence '\\%c'", - (unsigned char)*first_invalid_escape) < 0) { - Py_DECREF(result); - return NULL; + unsigned char c = *first_invalid_escape; + if ('4' <= c && c <= '7') { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "invalid octal escape sequence '\\%.3s'", + first_invalid_escape) < 0) + { + Py_DECREF(result); + return NULL; + } + } + else { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "invalid escape sequence '\\%c'", + c) < 0) + { + Py_DECREF(result); + return NULL; + } } } return result; @@ -6619,7 +5997,7 @@ PyUnicode_AsUnicodeEscapeString(PyObject *unicode) Py_ssize_t i, len; PyObject *repr; char *p; - enum PyUnicode_Kind kind; + int kind; const void *data; Py_ssize_t expandsize; @@ -6635,9 +6013,6 @@ PyUnicode_AsUnicodeEscapeString(PyObject *unicode) PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(unicode) == -1) { - return NULL; - } len = PyUnicode_GET_LENGTH(unicode); if (len == 0) { @@ -6892,9 +6267,6 @@ PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(unicode) == -1) { - return NULL; - } kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); len = PyUnicode_GET_LENGTH(unicode); @@ -7031,8 +6403,6 @@ unicode_encode_call_errorhandler(const char *errors, return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; len = PyUnicode_GET_LENGTH(unicode); make_encode_exception(exceptionObject, @@ -7090,8 +6460,6 @@ unicode_encode_ucs1(PyObject *unicode, /* output object */ _PyBytesWriter writer; - if (PyUnicode_READY(unicode) == -1) - return NULL; size = PyUnicode_GET_LENGTH(unicode); kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); @@ -7187,8 +6555,19 @@ unicode_encode_ucs1(PyObject *unicode, if (rep == NULL) goto onError; - /* subtract preallocated bytes */ - writer.min_size -= newpos - collstart; + if (newpos < collstart) { + writer.overallocate = 1; + str = _PyBytesWriter_Prepare(&writer, str, + collstart - newpos); + if (str == NULL) + goto onError; + } + else { + /* subtract preallocated bytes */ + writer.min_size -= newpos - collstart; + /* Only overallocate the buffer if it's not the last write */ + writer.overallocate = (newpos < size); + } if (PyBytes_Check(rep)) { /* Directly copy bytes result to output. */ @@ -7199,9 +6578,6 @@ unicode_encode_ucs1(PyObject *unicode, else { assert(PyUnicode_Check(rep)); - if (PyUnicode_READY(rep) < 0) - goto onError; - if (limit == 256 ? PyUnicode_KIND(rep) != PyUnicode_1BYTE_KIND : !PyUnicode_IS_ASCII(rep)) @@ -7248,8 +6624,6 @@ _PyUnicode_AsLatin1String(PyObject *unicode, const char *errors) PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; /* Fast path: if it is a one-byte string, construct bytes object directly. */ if (PyUnicode_KIND(unicode) == PyUnicode_1BYTE_KIND) @@ -7374,8 +6748,6 @@ _PyUnicode_AsASCIIString(PyObject *unicode, const char *errors) PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; /* Fast path: if it is an ASCII-only string, construct bytes object directly. Else defer to above function to raise the exception. */ if (PyUnicode_IS_ASCII(unicode)) @@ -7763,22 +7135,11 @@ encode_code_page_strict(UINT code_page, PyObject **outbytes, substring = PyUnicode_Substring(unicode, offset, offset+len); if (substring == NULL) return -1; -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - p = PyUnicode_AsUnicodeAndSize(substring, &size); - if (p == NULL) { - Py_DECREF(substring); - return -1; - } -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ p = PyUnicode_AsWideCharString(substring, &size); Py_CLEAR(substring); if (p == NULL) { return -1; } -#endif /* USE_UNICODE_WCHAR_CACHE */ assert(size <= INT_MAX); /* First get the size of the result */ @@ -7829,11 +7190,7 @@ _Py_COMP_DIAG_POP ret = 0; done: -#if USE_UNICODE_WCHAR_CACHE - Py_DECREF(substring); -#else /* USE_UNICODE_WCHAR_CACHE */ PyMem_Free(p); -#endif /* USE_UNICODE_WCHAR_CACHE */ return ret; error: @@ -7964,13 +7321,14 @@ encode_code_page_errors(UINT code_page, PyObject **outbytes, pos, pos + 1, &newpos); if (rep == NULL) goto error; - pos = newpos; + Py_ssize_t morebytes = pos - newpos; if (PyBytes_Check(rep)) { outsize = PyBytes_GET_SIZE(rep); - if (outsize != 1) { + morebytes += outsize; + if (morebytes > 0) { Py_ssize_t offset = out - PyBytes_AS_STRING(*outbytes); - newoutsize = PyBytes_GET_SIZE(*outbytes) + (outsize - 1); + newoutsize = PyBytes_GET_SIZE(*outbytes) + morebytes; if (_PyBytes_Resize(outbytes, newoutsize) < 0) { Py_DECREF(rep); goto error; @@ -7982,18 +7340,14 @@ encode_code_page_errors(UINT code_page, PyObject **outbytes, } else { Py_ssize_t i; - enum PyUnicode_Kind kind; + int kind; const void *data; - if (PyUnicode_READY(rep) == -1) { - Py_DECREF(rep); - goto error; - } - outsize = PyUnicode_GET_LENGTH(rep); - if (outsize != 1) { + morebytes += outsize; + if (morebytes > 0) { Py_ssize_t offset = out - PyBytes_AS_STRING(*outbytes); - newoutsize = PyBytes_GET_SIZE(*outbytes) + (outsize - 1); + newoutsize = PyBytes_GET_SIZE(*outbytes) + morebytes; if (_PyBytes_Resize(outbytes, newoutsize) < 0) { Py_DECREF(rep); goto error; @@ -8016,6 +7370,7 @@ encode_code_page_errors(UINT code_page, PyObject **outbytes, out++; } } + pos = newpos; Py_DECREF(rep); } /* write a NUL byte */ @@ -8048,8 +7403,6 @@ encode_code_page(int code_page, return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; len = PyUnicode_GET_LENGTH(unicode); if (code_page < 0) { @@ -8126,14 +7479,11 @@ charmap_decode_string(const char *s, Py_ssize_t startinpos, endinpos; PyObject *errorHandler = NULL, *exc = NULL; Py_ssize_t maplen; - enum PyUnicode_Kind mapkind; + int mapkind; const void *mapdata; Py_UCS4 x; unsigned char ch; - if (PyUnicode_READY(mapping) == -1) - return -1; - maplen = PyUnicode_GET_LENGTH(mapping); mapdata = PyUnicode_DATA(mapping); mapkind = PyUnicode_KIND(mapping); @@ -8167,7 +7517,7 @@ charmap_decode_string(const char *s, while (s < e) { if (mapkind == PyUnicode_2BYTE_KIND && maplen >= 256) { - enum PyUnicode_Kind outkind = writer->kind; + int outkind = writer->kind; const Py_UCS2 *mapdata_ucs2 = (const Py_UCS2 *)mapdata; if (outkind == PyUnicode_1BYTE_KIND) { Py_UCS1 *outdata = (Py_UCS1 *)writer->data; @@ -8286,8 +7636,6 @@ charmap_decode_mapping(const char *s, goto onError; } else if (PyUnicode_Check(item)) { - if (PyUnicode_READY(item) == -1) - goto onError; if (PyUnicode_GET_LENGTH(item) == 1) { Py_UCS4 value = PyUnicode_READ_CHAR(item, 0); if (value == 0xFFFE) @@ -8371,6 +7719,11 @@ PyUnicode_DecodeCharmap(const char *s, /* Charmap encoding: the lookup table */ +/*[clinic input] +class EncodingMap "struct encoding_map *" "&EncodingMapType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=14e46bbb6c522d22]*/ + struct encoding_map { PyObject_HEAD unsigned char level1[32]; @@ -8378,62 +7731,32 @@ struct encoding_map { unsigned char level23[1]; }; -static PyObject* -encoding_map_size(PyObject *obj, PyObject* args) +/*[clinic input] +EncodingMap.size + +Return the size (in bytes) of this object. +[clinic start generated code]*/ + +static PyObject * +EncodingMap_size_impl(struct encoding_map *self) +/*[clinic end generated code: output=c4c969e4c99342a4 input=004ff13f26bb5366]*/ { - struct encoding_map *map = (struct encoding_map*)obj; - return PyLong_FromLong(sizeof(*map) - 1 + 16*map->count2 + - 128*map->count3); + return PyLong_FromLong((sizeof(*self) - 1) + 16*self->count2 + + 128*self->count3); } static PyMethodDef encoding_map_methods[] = { - {"size", encoding_map_size, METH_NOARGS, - PyDoc_STR("Return the size (in bytes) of this object") }, - { 0 } + ENCODINGMAP_SIZE_METHODDEF + {NULL, NULL} }; static PyTypeObject EncodingMapType = { PyVarObject_HEAD_INIT(NULL, 0) - "EncodingMap", /*tp_name*/ - sizeof(struct encoding_map), /*tp_basicsize*/ - 0, /*tp_itemsize*/ + .tp_name = "EncodingMap", + .tp_basicsize = sizeof(struct encoding_map), /* methods */ - 0, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - encoding_map_methods, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - 0, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_methods = encoding_map_methods, }; PyObject* @@ -8713,7 +8036,7 @@ charmap_encoding_error( PyObject *repunicode = NULL; /* initialize to prevent gcc warning */ Py_ssize_t size, repsize; Py_ssize_t newpos; - enum PyUnicode_Kind kind; + int kind; const void *data; Py_ssize_t index; /* startpos for collecting unencodable chars */ @@ -8726,8 +8049,6 @@ charmap_encoding_error( Py_UCS4 ch; int val; - if (PyUnicode_READY(unicode) == -1) - return -1; size = PyUnicode_GET_LENGTH(unicode); /* find all unencodable characters */ while (collendpos < size) { @@ -8823,10 +8144,6 @@ charmap_encoding_error( break; } /* generate replacement */ - if (PyUnicode_READY(repunicode) == -1) { - Py_DECREF(repunicode); - return -1; - } repsize = PyUnicode_GET_LENGTH(repunicode); data = PyUnicode_DATA(repunicode); kind = PyUnicode_KIND(repunicode); @@ -8867,8 +8184,6 @@ _PyUnicode_EncodeCharmap(PyObject *unicode, const void *data; int kind; - if (PyUnicode_READY(unicode) == -1) - return NULL; size = PyUnicode_GET_LENGTH(unicode); data = PyUnicode_DATA(unicode); kind = PyUnicode_KIND(unicode); @@ -9147,10 +8462,6 @@ unicode_fast_translate_lookup(PyObject *mapping, Py_UCS1 ch, else if (PyUnicode_Check(item)) { Py_UCS4 replace; - if (PyUnicode_READY(item) == -1) { - Py_DECREF(item); - return -1; - } if (PyUnicode_GET_LENGTH(item) != 1) goto exit; @@ -9247,8 +8558,6 @@ _PyUnicode_TranslateCharmap(PyObject *input, return NULL; } - if (PyUnicode_READY(input) == -1) - return NULL; data = PyUnicode_DATA(input); kind = PyUnicode_KIND(input); size = PyUnicode_GET_LENGTH(input); @@ -9264,8 +8573,6 @@ _PyUnicode_TranslateCharmap(PyObject *input, ignore = (errors != NULL && strcmp(errors, "ignore") == 0); - if (PyUnicode_READY(input) == -1) - return NULL; if (PyUnicode_IS_ASCII(input)) { res = unicode_fast_translate(input, mapping, &writer, ignore, &i); if (res < 0) { @@ -9361,12 +8668,9 @@ _PyUnicode_TransformDecimalAndSpaceToASCII(PyObject *unicode) PyErr_BadInternalCall(); return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; if (PyUnicode_IS_ASCII(unicode)) { /* If the string is already ASCII, just return the same string */ - Py_INCREF(unicode); - return unicode; + return Py_NewRef(unicode); } Py_ssize_t len = PyUnicode_GET_LENGTH(unicode); @@ -9554,15 +8858,6 @@ _PyUnicode_InsertThousandsGrouping( assert(0 <= n_digits); assert(grouping != NULL); - if (digits != NULL) { - if (PyUnicode_READY(digits) == -1) { - return -1; - } - } - if (PyUnicode_READY(thousands_sep) == -1) { - return -1; - } - Py_ssize_t count = 0; Py_ssize_t n_zeros; int loop_broken = 0; @@ -9648,21 +8943,20 @@ _PyUnicode_InsertThousandsGrouping( return count; } - -Py_ssize_t -PyUnicode_Count(PyObject *str, - PyObject *substr, - Py_ssize_t start, - Py_ssize_t end) +static Py_ssize_t +unicode_count_impl(PyObject *str, + PyObject *substr, + Py_ssize_t start, + Py_ssize_t end) { + assert(PyUnicode_Check(str)); + assert(PyUnicode_Check(substr)); + Py_ssize_t result; int kind1, kind2; const void *buf1 = NULL, *buf2 = NULL; Py_ssize_t len1, len2; - if (ensure_unicode(str) < 0 || ensure_unicode(substr) < 0) - return -1; - kind1 = PyUnicode_KIND(str); kind2 = PyUnicode_KIND(substr); if (kind1 < kind2) @@ -9682,18 +8976,13 @@ PyUnicode_Count(PyObject *str, goto onError; } + // We don't reuse `anylib_count` here because of the explicit casts. switch (kind1) { case PyUnicode_1BYTE_KIND: - if (PyUnicode_IS_ASCII(str) && PyUnicode_IS_ASCII(substr)) - result = asciilib_count( - ((const Py_UCS1*)buf1) + start, end - start, - buf2, len2, PY_SSIZE_T_MAX - ); - else - result = ucs1lib_count( - ((const Py_UCS1*)buf1) + start, end - start, - buf2, len2, PY_SSIZE_T_MAX - ); + result = ucs1lib_count( + ((const Py_UCS1*)buf1) + start, end - start, + buf2, len2, PY_SSIZE_T_MAX + ); break; case PyUnicode_2BYTE_KIND: result = ucs2lib_count( @@ -9723,6 +9012,18 @@ PyUnicode_Count(PyObject *str, return -1; } +Py_ssize_t +PyUnicode_Count(PyObject *str, + PyObject *substr, + Py_ssize_t start, + Py_ssize_t end) +{ + if (ensure_unicode(str) < 0 || ensure_unicode(substr) < 0) + return -1; + + return unicode_count_impl(str, substr, start, end); +} + Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *substr, @@ -9743,8 +9044,6 @@ PyUnicode_FindChar(PyObject *str, Py_UCS4 ch, { int kind; Py_ssize_t len, result; - if (PyUnicode_READY(str) == -1) - return -2; len = PyUnicode_GET_LENGTH(str); ADJUST_INDICES(start, end, len); if (end - start < 1) @@ -9773,10 +9072,6 @@ tailmatch(PyObject *self, Py_ssize_t i; Py_ssize_t end_sub; - if (PyUnicode_READY(self) == -1 || - PyUnicode_READY(substring) == -1) - return -1; - ADJUST_INDICES(start, end, PyUnicode_GET_LENGTH(self)); end -= PyUnicode_GET_LENGTH(substring); if (end < start) @@ -10035,8 +9330,6 @@ case_operation(PyObject *self, void *outdata; Py_UCS4 maxchar = 0, *tmp, *tmpend; - assert(PyUnicode_IS_READY(self)); - kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); length = PyUnicode_GET_LENGTH(self); @@ -10109,7 +9402,7 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject *const *items, Py_ssize_t seq int use_memcpy; unsigned char *res_data = NULL, *sep_data = NULL; PyObject *last_obj; - unsigned int kind = 0; + int kind = 0; /* If empty sequence, return u"". */ if (seqlen == 0) { @@ -10121,8 +9414,7 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject *const *items, Py_ssize_t seq if (seqlen == 1) { if (PyUnicode_CheckExact(items[0])) { res = items[0]; - Py_INCREF(res); - return res; + return Py_NewRef(res); } seplen = 0; maxchar = 0; @@ -10145,8 +9437,6 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject *const *items, Py_ssize_t seq Py_TYPE(separator)->tp_name); goto onError; } - if (PyUnicode_READY(separator)) - goto onError; sep = separator; seplen = PyUnicode_GET_LENGTH(separator); maxchar = PyUnicode_MAX_CHAR_VALUE(separator); @@ -10178,8 +9468,6 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject *const *items, Py_ssize_t seq i, Py_TYPE(item)->tp_name); goto onError; } - if (PyUnicode_READY(item) == -1) - goto onError; add_sz = PyUnicode_GET_LENGTH(item); item_maxchar = PyUnicode_MAX_CHAR_VALUE(item); maxchar = Py_MAX(maxchar, item_maxchar); @@ -10272,9 +9560,8 @@ void _PyUnicode_FastFill(PyObject *unicode, Py_ssize_t start, Py_ssize_t length, Py_UCS4 fill_char) { - const enum PyUnicode_Kind kind = PyUnicode_KIND(unicode); + const int kind = PyUnicode_KIND(unicode); void *data = PyUnicode_DATA(unicode); - assert(PyUnicode_IS_READY(unicode)); assert(unicode_modifiable(unicode)); assert(fill_char <= PyUnicode_MAX_CHAR_VALUE(unicode)); assert(start >= 0); @@ -10292,8 +9579,6 @@ PyUnicode_Fill(PyObject *unicode, Py_ssize_t start, Py_ssize_t length, PyErr_BadInternalCall(); return -1; } - if (PyUnicode_READY(unicode) == -1) - return -1; if (unicode_check_modifiable(unicode)) return -1; @@ -10402,53 +9687,53 @@ split(PyObject *self, const void *buf1, *buf2; Py_ssize_t len1, len2; PyObject* out; + len1 = PyUnicode_GET_LENGTH(self); + kind1 = PyUnicode_KIND(self); - if (maxcount < 0) - maxcount = PY_SSIZE_T_MAX; - - if (PyUnicode_READY(self) == -1) - return NULL; - - if (substring == NULL) - switch (PyUnicode_KIND(self)) { + if (substring == NULL) { + if (maxcount < 0) { + maxcount = (len1 - 1) / 2 + 1; + } + switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(self)) return asciilib_split_whitespace( self, PyUnicode_1BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); else return ucs1lib_split_whitespace( self, PyUnicode_1BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); case PyUnicode_2BYTE_KIND: return ucs2lib_split_whitespace( self, PyUnicode_2BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); case PyUnicode_4BYTE_KIND: return ucs4lib_split_whitespace( self, PyUnicode_4BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); default: Py_UNREACHABLE(); } + } - if (PyUnicode_READY(substring) == -1) - return NULL; - - kind1 = PyUnicode_KIND(self); kind2 = PyUnicode_KIND(substring); - len1 = PyUnicode_GET_LENGTH(self); len2 = PyUnicode_GET_LENGTH(substring); + if (maxcount < 0) { + // if len2 == 0, it will raise ValueError. + maxcount = len2 == 0 ? 0 : (len1 / len2) + 1; + // handle expected overflow case: (Py_SSIZE_T_MAX / 1) + 1 + maxcount = maxcount < 0 ? len1 : maxcount; + } if (kind1 < kind2 || len1 < len2) { out = PyList_New(1); if (out == NULL) return NULL; - Py_INCREF(self); - PyList_SET_ITEM(out, 0, self); + PyList_SET_ITEM(out, 0, Py_NewRef(self)); return out; } buf1 = PyUnicode_DATA(self); @@ -10495,52 +9780,52 @@ rsplit(PyObject *self, Py_ssize_t len1, len2; PyObject* out; - if (maxcount < 0) - maxcount = PY_SSIZE_T_MAX; + len1 = PyUnicode_GET_LENGTH(self); + kind1 = PyUnicode_KIND(self); - if (PyUnicode_READY(self) == -1) - return NULL; - - if (substring == NULL) - switch (PyUnicode_KIND(self)) { + if (substring == NULL) { + if (maxcount < 0) { + maxcount = (len1 - 1) / 2 + 1; + } + switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(self)) return asciilib_rsplit_whitespace( self, PyUnicode_1BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); else return ucs1lib_rsplit_whitespace( self, PyUnicode_1BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); case PyUnicode_2BYTE_KIND: return ucs2lib_rsplit_whitespace( self, PyUnicode_2BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); case PyUnicode_4BYTE_KIND: return ucs4lib_rsplit_whitespace( self, PyUnicode_4BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); default: Py_UNREACHABLE(); } - - if (PyUnicode_READY(substring) == -1) - return NULL; - - kind1 = PyUnicode_KIND(self); + } kind2 = PyUnicode_KIND(substring); - len1 = PyUnicode_GET_LENGTH(self); len2 = PyUnicode_GET_LENGTH(substring); + if (maxcount < 0) { + // if len2 == 0, it will raise ValueError. + maxcount = len2 == 0 ? 0 : (len1 / len2) + 1; + // handle expected overflow case: (Py_SSIZE_T_MAX / 1) + 1 + maxcount = maxcount < 0 ? len1 : maxcount; + } if (kind1 < kind2 || len1 < len2) { out = PyList_New(1); if (out == NULL) return NULL; - Py_INCREF(self); - PyList_SET_ITEM(out, 0, self); + PyList_SET_ITEM(out, 0, Py_NewRef(self)); return out; } buf1 = PyUnicode_DATA(self); @@ -10601,10 +9886,7 @@ anylib_count(int kind, PyObject *sstr, const void* sbuf, Py_ssize_t slen, { switch (kind) { case PyUnicode_1BYTE_KIND: - if (PyUnicode_IS_ASCII(sstr) && PyUnicode_IS_ASCII(str1)) - return asciilib_count(sbuf, slen, buf1, len1, maxcount); - else - return ucs1lib_count(sbuf, slen, buf1, len1, maxcount); + return ucs1lib_count(sbuf, slen, buf1, len1, maxcount); case PyUnicode_2BYTE_KIND: return ucs2lib_count(sbuf, slen, buf1, len1, maxcount); case PyUnicode_4BYTE_KIND: @@ -10932,8 +10214,6 @@ static PyObject * unicode_title_impl(PyObject *self) /*[clinic end generated code: output=c75ae03809574902 input=fa945d669b26e683]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; return case_operation(self, do_title); } @@ -10950,8 +10230,6 @@ static PyObject * unicode_capitalize_impl(PyObject *self) /*[clinic end generated code: output=e49a4c333cdb7667 input=f4cbf1016938da6d]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; if (PyUnicode_GET_LENGTH(self) == 0) return unicode_result_unchanged(self); return case_operation(self, do_capitalize); @@ -10967,8 +10245,6 @@ static PyObject * unicode_casefold_impl(PyObject *self) /*[clinic end generated code: output=0120daf657ca40af input=384d66cc2ae30daf]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; if (PyUnicode_IS_ASCII(self)) return ascii_upper_or_lower(self, 1); return case_operation(self, do_casefold); @@ -10988,8 +10264,6 @@ convert_uc(PyObject *obj, void *addr) "not %.100s", Py_TYPE(obj)->tp_name); return 0; } - if (PyUnicode_READY(obj) < 0) - return 0; if (PyUnicode_GET_LENGTH(obj) != 1) { PyErr_SetString(PyExc_TypeError, "The fill character must be exactly one character long"); @@ -11017,9 +10291,6 @@ unicode_center_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar) { Py_ssize_t marg, left; - if (PyUnicode_READY(self) == -1) - return NULL; - if (PyUnicode_GET_LENGTH(self) >= width) return unicode_result_unchanged(self); @@ -11168,15 +10439,22 @@ unicode_compare_eq(PyObject *str1, PyObject *str2) return (cmp == 0); } +int +_PyUnicode_Equal(PyObject *str1, PyObject *str2) +{ + assert(PyUnicode_Check(str1)); + assert(PyUnicode_Check(str2)); + if (str1 == str2) { + return 1; + } + return unicode_compare_eq(str1, str2); +} + int PyUnicode_Compare(PyObject *left, PyObject *right) { if (PyUnicode_Check(left) && PyUnicode_Check(right)) { - if (PyUnicode_READY(left) == -1 || - PyUnicode_READY(right) == -1) - return -1; - /* a string is equal to itself */ if (left == right) return 0; @@ -11196,24 +10474,8 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str) Py_ssize_t i; int kind; Py_UCS4 chr; - const unsigned char *ustr = (const unsigned char *)str; assert(_PyUnicode_CHECK(uni)); - if (!PyUnicode_IS_READY(uni)) { - const wchar_t *ws = _PyUnicode_WSTR(uni); - /* Compare Unicode string and source character set string */ - for (i = 0; (chr = ws[i]) && ustr[i]; i++) { - if (chr != ustr[i]) - return (chr < ustr[i]) ? -1 : 1; - } - /* This check keeps Python strings that end in '\0' from comparing equal - to C strings identical up to that point. */ - if (_PyUnicode_WSTR_LENGTH(uni) != i || chr) - return 1; /* uni is longer */ - if (ustr[i]) - return -1; /* str is longer */ - return 0; - } kind = PyUnicode_KIND(uni); if (kind == PyUnicode_1BYTE_KIND) { const void *data = PyUnicode_1BYTE_DATA(uni); @@ -11251,24 +10513,6 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str) } } -static int -non_ready_unicode_equal_to_ascii_string(PyObject *unicode, const char *str) -{ - size_t i, len; - const wchar_t *p; - len = (size_t)_PyUnicode_WSTR_LENGTH(unicode); - if (strlen(str) != len) - return 0; - p = _PyUnicode_WSTR(unicode); - assert(p); - for (i = 0; i < len; i++) { - unsigned char c = (unsigned char)str[i]; - if (c >= 128 || p[i] != (wchar_t)c) - return 0; - } - return 1; -} - int _PyUnicode_EqualToASCIIString(PyObject *unicode, const char *str) { @@ -11280,11 +10524,6 @@ _PyUnicode_EqualToASCIIString(PyObject *unicode, const char *str) assert((unsigned char)*p < 128); } #endif - if (PyUnicode_READY(unicode) == -1) { - /* Memory error or bad data */ - PyErr_Clear(); - return non_ready_unicode_equal_to_ascii_string(unicode, str); - } if (!PyUnicode_IS_ASCII(unicode)) return 0; len = (size_t)PyUnicode_GET_LENGTH(unicode); @@ -11305,12 +10544,6 @@ _PyUnicode_EqualToASCIIId(PyObject *left, _Py_Identifier *right) } #endif - if (PyUnicode_READY(left) == -1) { - /* memory error or bad data */ - PyErr_Clear(); - return non_ready_unicode_equal_to_ascii_string(left, right->string); - } - if (!PyUnicode_IS_ASCII(left)) return 0; @@ -11344,10 +10577,6 @@ PyUnicode_RichCompare(PyObject *left, PyObject *right, int op) if (!PyUnicode_Check(left) || !PyUnicode_Check(right)) Py_RETURN_NOTIMPLEMENTED; - if (PyUnicode_READY(left) == -1 || - PyUnicode_READY(right) == -1) - return NULL; - if (left == right) { switch (op) { case Py_EQ: @@ -11395,8 +10624,6 @@ PyUnicode_Contains(PyObject *str, PyObject *substr) Py_TYPE(substr)->tp_name); return -1; } - if (PyUnicode_READY(substr) == -1) - return -1; if (ensure_unicode(str) < 0) return -1; @@ -11460,8 +10687,6 @@ PyUnicode_Concat(PyObject *left, PyObject *right) Py_TYPE(right)->tp_name); return NULL; } - if (PyUnicode_READY(right) < 0) - return NULL; /* Shortcuts */ PyObject *empty = unicode_get_empty(); // Borrowed reference @@ -11515,17 +10740,11 @@ PyUnicode_Append(PyObject **p_left, PyObject *right) goto error; } - if (PyUnicode_READY(left) == -1) - goto error; - if (PyUnicode_READY(right) == -1) - goto error; - /* Shortcuts */ PyObject *empty = unicode_get_empty(); // Borrowed reference if (left == empty) { Py_DECREF(left); - Py_INCREF(right); - *p_left = right; + *p_left = Py_NewRef(right); return; } if (right == empty) { @@ -11586,7 +10805,7 @@ PyUnicode_AppendAndDel(PyObject **pleft, PyObject *right) } /* -Wraps stringlib_parse_args_finds() and additionally ensures that the +Wraps asciilib_parse_args_finds() and additionally ensures that the first argument is a unicode object. */ @@ -11595,8 +10814,7 @@ parse_args_finds_unicode(const char * function_name, PyObject *args, PyObject **substring, Py_ssize_t *start, Py_ssize_t *end) { - if(stringlib_parse_args_finds(function_name, args, substring, - start, end)) { + if (asciilib_parse_args_finds(function_name, args, substring, start, end)) { if (ensure_unicode(*substring) < 0) return 0; return 1; @@ -11617,62 +10835,16 @@ unicode_count(PyObject *self, PyObject *args) PyObject *substring = NULL; /* initialize to fix a compiler warning */ Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; - PyObject *result; - int kind1, kind2; - const void *buf1, *buf2; - Py_ssize_t len1, len2, iresult; + Py_ssize_t result; if (!parse_args_finds_unicode("count", args, &substring, &start, &end)) return NULL; - kind1 = PyUnicode_KIND(self); - kind2 = PyUnicode_KIND(substring); - if (kind1 < kind2) - return PyLong_FromLong(0); + result = unicode_count_impl(self, substring, start, end); + if (result == -1) + return NULL; - len1 = PyUnicode_GET_LENGTH(self); - len2 = PyUnicode_GET_LENGTH(substring); - ADJUST_INDICES(start, end, len1); - if (end - start < len2) - return PyLong_FromLong(0); - - buf1 = PyUnicode_DATA(self); - buf2 = PyUnicode_DATA(substring); - if (kind2 != kind1) { - buf2 = unicode_askind(kind2, buf2, len2, kind1); - if (!buf2) - return NULL; - } - switch (kind1) { - case PyUnicode_1BYTE_KIND: - iresult = ucs1lib_count( - ((const Py_UCS1*)buf1) + start, end - start, - buf2, len2, PY_SSIZE_T_MAX - ); - break; - case PyUnicode_2BYTE_KIND: - iresult = ucs2lib_count( - ((const Py_UCS2*)buf1) + start, end - start, - buf2, len2, PY_SSIZE_T_MAX - ); - break; - case PyUnicode_4BYTE_KIND: - iresult = ucs4lib_count( - ((const Py_UCS4*)buf1) + start, end - start, - buf2, len2, PY_SSIZE_T_MAX - ); - break; - default: - Py_UNREACHABLE(); - } - - result = PyLong_FromSsize_t(iresult); - - assert((kind2 == kind1) == (buf2 == PyUnicode_DATA(substring))); - if (kind2 != kind1) - PyMem_Free((void *)buf2); - - return result; + return PyLong_FromSsize_t(result); } /*[clinic input] @@ -11719,9 +10891,6 @@ unicode_expandtabs_impl(PyObject *self, int tabsize) int kind; int found; - if (PyUnicode_READY(self) == -1) - return NULL; - /* First pass: determine size of output string */ src_len = PyUnicode_GET_LENGTH(self); i = j = line_pos = 0; @@ -11807,9 +10976,6 @@ unicode_find(PyObject *self, PyObject *args) if (!parse_args_finds_unicode("find", args, &substring, &start, &end)) return NULL; - if (PyUnicode_READY(self) == -1) - return NULL; - result = any_find_slice(self, substring, start, end, 1); if (result == -2) @@ -11822,16 +10988,13 @@ static PyObject * unicode_getitem(PyObject *self, Py_ssize_t index) { const void *data; - enum PyUnicode_Kind kind; + int kind; Py_UCS4 ch; if (!PyUnicode_Check(self)) { PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(self) == -1) { - return NULL; - } if (index < 0 || index >= PyUnicode_GET_LENGTH(self)) { PyErr_SetString(PyExc_IndexError, "string index out of range"); return NULL; @@ -11854,8 +11017,6 @@ unicode_hash(PyObject *self) #endif if (_PyUnicode_HASH(self) != -1) return _PyUnicode_HASH(self); - if (PyUnicode_READY(self) == -1) - return -1; x = _Py_HashBytes(PyUnicode_DATA(self), PyUnicode_GET_LENGTH(self) * PyUnicode_KIND(self)); @@ -11884,9 +11045,6 @@ unicode_index(PyObject *self, PyObject *args) if (!parse_args_finds_unicode("index", args, &substring, &start, &end)) return NULL; - if (PyUnicode_READY(self) == -1) - return NULL; - result = any_find_slice(self, substring, start, end, 1); if (result == -2) @@ -11913,9 +11071,6 @@ static PyObject * unicode_isascii_impl(PyObject *self) /*[clinic end generated code: output=c5910d64b5a8003f input=5a43cbc6399621d5]*/ { - if (PyUnicode_READY(self) == -1) { - return NULL; - } return PyBool_FromLong(PyUnicode_IS_ASCII(self)); } @@ -11937,8 +11092,6 @@ unicode_islower_impl(PyObject *self) const void *data; int cased; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -11982,8 +11135,6 @@ unicode_isupper_impl(PyObject *self) const void *data; int cased; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12027,8 +11178,6 @@ unicode_istitle_impl(PyObject *self) const void *data; int cased, previous_is_cased; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12084,8 +11233,6 @@ unicode_isspace_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12124,8 +11271,6 @@ unicode_isalpha_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12163,9 +11308,6 @@ unicode_isalnum_impl(PyObject *self) const void *data; Py_ssize_t len, i; - if (PyUnicode_READY(self) == -1) - return NULL; - kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); len = PyUnicode_GET_LENGTH(self); @@ -12205,8 +11347,6 @@ unicode_isdecimal_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12244,8 +11384,6 @@ unicode_isdigit_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12284,8 +11422,6 @@ unicode_isnumeric_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12310,9 +11446,6 @@ Py_ssize_t _PyUnicode_ScanIdentifier(PyObject *self) { Py_ssize_t i; - if (PyUnicode_READY(self) == -1) - return -1; - Py_ssize_t len = PyUnicode_GET_LENGTH(self); if (len == 0) { /* an empty string is not a valid identifier */ @@ -12346,54 +11479,10 @@ _PyUnicode_ScanIdentifier(PyObject *self) int PyUnicode_IsIdentifier(PyObject *self) { - if (PyUnicode_IS_READY(self)) { - Py_ssize_t i = _PyUnicode_ScanIdentifier(self); - Py_ssize_t len = PyUnicode_GET_LENGTH(self); - /* an empty string is not a valid identifier */ - return len && i == len; - } - else { -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - Py_ssize_t i = 0, len = PyUnicode_GET_SIZE(self); - if (len == 0) { - /* an empty string is not a valid identifier */ - return 0; - } - - const wchar_t *wstr = _PyUnicode_WSTR(self); - Py_UCS4 ch = wstr[i++]; -#if SIZEOF_WCHAR_T == 2 - if (Py_UNICODE_IS_HIGH_SURROGATE(ch) - && i < len - && Py_UNICODE_IS_LOW_SURROGATE(wstr[i])) - { - ch = Py_UNICODE_JOIN_SURROGATES(ch, wstr[i]); - i++; - } -#endif - if (!_PyUnicode_IsXidStart(ch) && ch != 0x5F /* LOW LINE */) { - return 0; - } - - while (i < len) { - ch = wstr[i++]; -#if SIZEOF_WCHAR_T == 2 - if (Py_UNICODE_IS_HIGH_SURROGATE(ch) - && i < len - && Py_UNICODE_IS_LOW_SURROGATE(wstr[i])) - { - ch = Py_UNICODE_JOIN_SURROGATES(ch, wstr[i]); - i++; - } -#endif - if (!_PyUnicode_IsXidContinue(ch)) { - return 0; - } - } - return 1; -_Py_COMP_DIAG_POP - } + Py_ssize_t i = _PyUnicode_ScanIdentifier(self); + Py_ssize_t len = PyUnicode_GET_LENGTH(self); + /* an empty string is not a valid identifier */ + return len && i == len; } /*[clinic input] @@ -12429,8 +11518,6 @@ unicode_isprintable_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12472,8 +11559,6 @@ unicode_join(PyObject *self, PyObject *iterable) static Py_ssize_t unicode_length(PyObject *self) { - if (PyUnicode_READY(self) == -1) - return -1; return PyUnicode_GET_LENGTH(self); } @@ -12493,9 +11578,6 @@ static PyObject * unicode_ljust_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar) /*[clinic end generated code: output=1cce0e0e0a0b84b3 input=3ab599e335e60a32]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; - if (PyUnicode_GET_LENGTH(self) >= width) return unicode_result_unchanged(self); @@ -12512,8 +11594,6 @@ static PyObject * unicode_lower_impl(PyObject *self) /*[clinic end generated code: output=84ef9ed42efad663 input=60a2984b8beff23a]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; if (PyUnicode_IS_ASCII(self)) return ascii_upper_or_lower(self, 1); return case_operation(self, do_lower); @@ -12538,9 +11618,6 @@ _PyUnicode_XStrip(PyObject *self, int striptype, PyObject *sepobj) BLOOM_MASK sepmask; Py_ssize_t seplen; - if (PyUnicode_READY(self) == -1 || PyUnicode_READY(sepobj) == -1) - return NULL; - kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); len = PyUnicode_GET_LENGTH(self); @@ -12586,9 +11663,6 @@ PyUnicode_Substring(PyObject *self, Py_ssize_t start, Py_ssize_t end) int kind; Py_ssize_t length; - if (PyUnicode_READY(self) == -1) - return NULL; - length = PyUnicode_GET_LENGTH(self); end = Py_MIN(end, length); @@ -12621,9 +11695,6 @@ do_strip(PyObject *self, int striptype) { Py_ssize_t len, i, j; - if (PyUnicode_READY(self) == -1) - return NULL; - len = PyUnicode_GET_LENGTH(self); if (PyUnicode_IS_ASCII(self)) { @@ -12770,9 +11841,6 @@ unicode_repeat(PyObject *str, Py_ssize_t len) if (len == 1) return unicode_result_unchanged(str); - if (PyUnicode_READY(str) == -1) - return NULL; - if (PyUnicode_GET_LENGTH(str) > PY_SSIZE_T_MAX / len) { PyErr_SetString(PyExc_OverflowError, "repeated string is too long"); @@ -12804,17 +11872,10 @@ unicode_repeat(PyObject *str, Py_ssize_t len) } } else { - /* number of characters copied this far */ - Py_ssize_t done = PyUnicode_GET_LENGTH(str); Py_ssize_t char_size = PyUnicode_KIND(str); char *to = (char *) PyUnicode_DATA(u); - memcpy(to, PyUnicode_DATA(str), - PyUnicode_GET_LENGTH(str) * char_size); - while (done < nchars) { - n = (done <= nchars-done) ? done : nchars-done; - memcpy(to + (done * char_size), to, n * char_size); - done += n; - } + _PyBytes_Repeat(to, nchars * char_size, PyUnicode_DATA(str), + PyUnicode_GET_LENGTH(str) * char_size); } assert(_PyUnicode_CheckConsistency(u, 1)); @@ -12854,8 +11915,6 @@ unicode_replace_impl(PyObject *self, PyObject *old, PyObject *new, Py_ssize_t count) /*[clinic end generated code: output=b63f1a8b5eebf448 input=147d12206276ebeb]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; return replace(self, old, new, count); } @@ -12925,9 +11984,6 @@ unicode_repr(PyObject *unicode) const void *idata; void *odata; - if (PyUnicode_READY(unicode) == -1) - return NULL; - isize = PyUnicode_GET_LENGTH(unicode); idata = PyUnicode_DATA(unicode); @@ -13100,9 +12156,6 @@ unicode_rfind(PyObject *self, PyObject *args) if (!parse_args_finds_unicode("rfind", args, &substring, &start, &end)) return NULL; - if (PyUnicode_READY(self) == -1) - return NULL; - result = any_find_slice(self, substring, start, end, -1); if (result == -2) @@ -13132,9 +12185,6 @@ unicode_rindex(PyObject *self, PyObject *args) if (!parse_args_finds_unicode("rindex", args, &substring, &start, &end)) return NULL; - if (PyUnicode_READY(self) == -1) - return NULL; - result = any_find_slice(self, substring, start, end, -1); if (result == -2) @@ -13164,9 +12214,6 @@ static PyObject * unicode_rjust_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar) /*[clinic end generated code: output=804a1a57fbe8d5cf input=d05f550b5beb1f72]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; - if (PyUnicode_GET_LENGTH(self) >= width) return unicode_result_unchanged(self); @@ -13186,19 +12233,26 @@ PyUnicode_Split(PyObject *s, PyObject *sep, Py_ssize_t maxsplit) str.split as unicode_split sep: object = None - The delimiter according which to split the string. - None (the default value) means split according to any whitespace, - and discard empty strings from the result. + The separator used to split the string. + + When set to None (the default value), will split on any whitespace + character (including \\n \\r \\t \\f and spaces) and will discard + empty strings from the result. maxsplit: Py_ssize_t = -1 - Maximum number of splits to do. + Maximum number of splits (starting from the left). -1 (the default value) means no limit. -Return a list of the words in the string, using sep as the delimiter string. +Return a list of the substrings in the string, using sep as the separator string. + +Note, str.split() is mainly useful for data that has been intentionally +delimited. With natural text that includes punctuation, consider using +the regular expression module. + [clinic start generated code]*/ static PyObject * unicode_split_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) -/*[clinic end generated code: output=3a65b1db356948dc input=606e750488a82359]*/ +/*[clinic end generated code: output=3a65b1db356948dc input=906d953b44efc43b]*/ { if (sep == Py_None) return split(self, NULL, maxsplit); @@ -13369,14 +12423,14 @@ PyUnicode_RSplit(PyObject *s, PyObject *sep, Py_ssize_t maxsplit) /*[clinic input] str.rsplit as unicode_rsplit = str.split -Return a list of the words in the string, using sep as the delimiter string. +Return a list of the substrings in the string, using sep as the separator string. -Splits are done starting at the end of the string and working to the front. +Splitting starts at the end of the string and works to the front. [clinic start generated code]*/ static PyObject * unicode_rsplit_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) -/*[clinic end generated code: output=c2b815c63bcabffc input=12ad4bf57dd35f15]*/ +/*[clinic end generated code: output=c2b815c63bcabffc input=ea78406060fce33c]*/ { if (sep == Py_None) return rsplit(self, NULL, maxsplit); @@ -13392,7 +12446,7 @@ unicode_rsplit_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) /*[clinic input] str.splitlines as unicode_splitlines - keepends: bool(accept={int}) = False + keepends: bool = False Return a list of the lines in the string, breaking at line boundaries. @@ -13402,7 +12456,7 @@ true. static PyObject * unicode_splitlines_impl(PyObject *self, int keepends) -/*[clinic end generated code: output=f664dcdad153ec40 input=b508e180459bdd8b]*/ +/*[clinic end generated code: output=f664dcdad153ec40 input=ba6ad05ee85d2b55]*/ { return PyUnicode_Splitlines(self, keepends); } @@ -13423,8 +12477,6 @@ static PyObject * unicode_swapcase_impl(PyObject *self) /*[clinic end generated code: output=5d28966bf6d7b2af input=3f3ef96d5798a7bb]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; return case_operation(self, do_swapcase); } @@ -13590,8 +12642,6 @@ static PyObject * unicode_upper_impl(PyObject *self) /*[clinic end generated code: output=1b7ddd16bbcdc092 input=db3d55682dfe2e6c]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; if (PyUnicode_IS_ASCII(self)) return ascii_upper_or_lower(self, 0); return case_operation(self, do_upper); @@ -13618,9 +12668,6 @@ unicode_zfill_impl(PyObject *self, Py_ssize_t width) const void *data; Py_UCS4 chr; - if (PyUnicode_READY(self) == -1) - return NULL; - if (PyUnicode_GET_LENGTH(self) >= width) return unicode_result_unchanged(self); @@ -13645,14 +12692,6 @@ unicode_zfill_impl(PyObject *self, Py_ssize_t width) return u; } -#if 0 -static PyObject * -unicode__decimal2ascii(PyObject *self) -{ - return PyUnicode_TransformDecimalAndSpaceToASCII(self); -} -#endif - PyDoc_STRVAR(startswith__doc__, "S.startswith(prefix[, start[, end]]) -> bool\n\ \n\ @@ -13671,7 +12710,7 @@ unicode_startswith(PyObject *self, Py_ssize_t end = PY_SSIZE_T_MAX; int result; - if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end)) + if (!asciilib_parse_args_finds("startswith", args, &subobj, &start, &end)) return NULL; if (PyTuple_Check(subobj)) { Py_ssize_t i; @@ -13725,7 +12764,7 @@ unicode_endswith(PyObject *self, Py_ssize_t end = PY_SSIZE_T_MAX; int result; - if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end)) + if (!asciilib_parse_args_finds("endswith", args, &subobj, &start, &end)) return NULL; if (PyTuple_Check(subobj)) { Py_ssize_t i; @@ -13772,7 +12811,7 @@ _PyUnicodeWriter_Update(_PyUnicodeWriter *writer) else { /* use a value smaller than PyUnicode_1BYTE_KIND() so _PyUnicodeWriter_PrepareKind() will copy the buffer. */ - writer->kind = PyUnicode_WCHAR_KIND; + writer->kind = 0; assert(writer->kind <= PyUnicode_1BYTE_KIND); /* Copy-on-write mode: set buffer size to 0 so @@ -13792,7 +12831,7 @@ _PyUnicodeWriter_Init(_PyUnicodeWriter *writer) /* use a value smaller than PyUnicode_1BYTE_KIND() so _PyUnicodeWriter_PrepareKind() will copy the buffer. */ - writer->kind = PyUnicode_WCHAR_KIND; + writer->kind = 0; assert(writer->kind <= PyUnicode_1BYTE_KIND); } @@ -13885,7 +12924,7 @@ _PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer, int _PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer, - enum PyUnicode_Kind kind) + int kind) { Py_UCS4 maxchar; @@ -13927,8 +12966,6 @@ _PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, PyObject *str) Py_UCS4 maxchar; Py_ssize_t len; - if (PyUnicode_READY(str) == -1) - return -1; len = PyUnicode_GET_LENGTH(str); if (len == 0) return 0; @@ -13937,8 +12974,7 @@ _PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, PyObject *str) if (writer->buffer == NULL && !writer->overallocate) { assert(_PyUnicode_CheckConsistency(str, 1)); writer->readonly = 1; - Py_INCREF(str); - writer->buffer = str; + writer->buffer = Py_NewRef(str); _PyUnicodeWriter_Update(writer); writer->pos += len; return 0; @@ -13959,9 +12995,6 @@ _PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, PyObject *str, Py_UCS4 maxchar; Py_ssize_t len; - if (PyUnicode_READY(str) == -1) - return -1; - assert(0 <= start); assert(end <= PyUnicode_GET_LENGTH(str)); assert(start <= end); @@ -14090,7 +13123,7 @@ _PyUnicodeWriter_Finish(_PyUnicodeWriter *writer) } assert(_PyUnicode_CheckConsistency(str, 1)); - return unicode_result_ready(str); + return unicode_result(str); } void @@ -14129,8 +13162,6 @@ unicode___format___impl(PyObject *self, PyObject *format_spec) _PyUnicodeWriter writer; int ret; - if (PyUnicode_READY(self) == -1) - return NULL; _PyUnicodeWriter_Init(&writer); ret = _PyUnicode_FormatAdvancedWriter(&writer, self, format_spec, 0, @@ -14156,11 +13187,13 @@ unicode_sizeof_impl(PyObject *self) /* If it's a compact object, account for base structure + character data. */ - if (PyUnicode_IS_COMPACT_ASCII(self)) + if (PyUnicode_IS_COMPACT_ASCII(self)) { size = sizeof(PyASCIIObject) + PyUnicode_GET_LENGTH(self) + 1; - else if (PyUnicode_IS_COMPACT(self)) + } + else if (PyUnicode_IS_COMPACT(self)) { size = sizeof(PyCompactUnicodeObject) + (PyUnicode_GET_LENGTH(self) + 1) * PyUnicode_KIND(self); + } else { /* If it is a two-block object, account for base object, and for character block if present. */ @@ -14169,10 +13202,6 @@ unicode_sizeof_impl(PyObject *self) size += (PyUnicode_GET_LENGTH(self) + 1) * PyUnicode_KIND(self); } - /* If the wstr pointer is present, account for it unless it is shared - with the data pointer. Check if the data is not shared. */ - if (_PyUnicode_HAS_WSTR_MEMORY(self)) - size += (PyUnicode_WSTR_LENGTH(self) + 1) * sizeof(wchar_t); if (_PyUnicode_HAS_UTF8_MEMORY(self)) size += PyUnicode_UTF8_LENGTH(self) + 1; @@ -14233,16 +13262,11 @@ static PyMethodDef unicode_methods[] = { UNICODE_ISIDENTIFIER_METHODDEF UNICODE_ISPRINTABLE_METHODDEF UNICODE_ZFILL_METHODDEF - {"format", (PyCFunction)(void(*)(void)) do_string_format, METH_VARARGS | METH_KEYWORDS, format__doc__}, + {"format", _PyCFunction_CAST(do_string_format), METH_VARARGS | METH_KEYWORDS, format__doc__}, {"format_map", (PyCFunction) do_string_format_map, METH_O, format_map__doc__}, UNICODE___FORMAT___METHODDEF UNICODE_MAKETRANS_METHODDEF UNICODE_SIZEOF_METHODDEF -#if 0 - /* These methods are just used for debugging the implementation. */ - {"_decimal2ascii", (PyCFunction) unicode__decimal2ascii, METH_NOARGS}, -#endif - {"__getnewargs__", unicode_getnewargs, METH_NOARGS}, {NULL, NULL} }; @@ -14276,9 +13300,6 @@ static PySequenceMethods unicode_as_sequence = { static PyObject* unicode_subscript(PyObject* self, PyObject* item) { - if (PyUnicode_READY(self) == -1) - return NULL; - if (_PyIndex_Check(item)) { Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) @@ -14361,7 +13382,7 @@ struct unicode_formatter_t { Py_ssize_t arglen, argidx; PyObject *dict; - enum PyUnicode_Kind fmtkind; + int fmtkind; Py_ssize_t fmtcnt, fmtpos; const void *fmtdata; PyObject *fmtstr; @@ -14409,7 +13430,7 @@ formatfloat(PyObject *v, struct unicode_format_arg_t *arg, double x; Py_ssize_t len; int prec; - int dtoa_flags; + int dtoa_flags = 0; x = PyFloat_AsDouble(v); if (x == -1.0 && PyErr_Occurred()) @@ -14420,9 +13441,9 @@ formatfloat(PyObject *v, struct unicode_format_arg_t *arg, prec = 6; if (arg->flags & F_ALT) - dtoa_flags = Py_DTSF_ALT; - else - dtoa_flags = 0; + dtoa_flags |= Py_DTSF_ALT; + if (arg->flags & F_NO_NEG_0) + dtoa_flags |= Py_DTSF_NO_NEG_0; p = PyOS_double_to_string(x, arg->ch, prec, dtoa_flags, NULL); if (p == NULL) return -1; @@ -14502,7 +13523,6 @@ _PyUnicode_FormatLong(PyObject *val, int alt, int prec, int type) return NULL; assert(unicode_modifiable(result)); - assert(PyUnicode_IS_READY(result)); assert(PyUnicode_IS_ASCII(result)); /* To modify the string in-place, there can only be one reference. */ @@ -14557,8 +13577,7 @@ _PyUnicode_FormatLong(PyObject *val, int alt, int prec, int type) for (i = 0; i < numdigits; i++) *b1++ = *buf++; *b1 = '\0'; - Py_DECREF(result); - result = r1; + Py_SETREF(result, r1); buf = PyBytes_AS_STRING(result); len = numnondigits + prec; } @@ -14575,8 +13594,7 @@ _PyUnicode_FormatLong(PyObject *val, int alt, int prec, int type) || buf != PyUnicode_DATA(result)) { PyObject *unicode; unicode = _PyUnicode_FromASCII(buf, len); - Py_DECREF(result); - result = unicode; + Py_SETREF(result, unicode); } else if (len != PyUnicode_GET_LENGTH(result)) { if (PyUnicode_Resize(&result, len) < 0) @@ -14617,8 +13635,7 @@ mainformatlong(PyObject *v, assert(PyLong_Check(iobj)); } else { - iobj = v; - Py_INCREF(iobj); + iobj = Py_NewRef(v); } if (PyLong_CheckExact(v) @@ -14941,8 +13958,7 @@ unicode_format_arg_format(struct unicode_formatter_t *ctx, } if (PyUnicode_CheckExact(v) && arg->ch == 's') { - *p_str = v; - Py_INCREF(*p_str); + *p_str = Py_NewRef(v); } else { if (arg->ch == 's') @@ -15024,7 +14040,7 @@ unicode_format_arg_output(struct unicode_formatter_t *ctx, PyObject *str) { Py_ssize_t len; - enum PyUnicode_Kind kind; + int kind; const void *pbuf; Py_ssize_t pindex; Py_UCS4 signchar; @@ -15038,9 +14054,6 @@ unicode_format_arg_output(struct unicode_formatter_t *ctx, if (arg->sign && arg->flags & F_ZERO) fill = '0'; - if (PyUnicode_READY(str) == -1) - return -1; - len = PyUnicode_GET_LENGTH(str); if ((arg->width == -1 || arg->width <= len) && (arg->prec == -1 || arg->prec >= len) @@ -15342,15 +14355,12 @@ unicode_subtype_new(PyTypeObject *type, PyObject *unicode) { PyObject *self; Py_ssize_t length, char_size; - int share_wstr, share_utf8; - unsigned int kind; + int share_utf8; + int kind; void *data; assert(PyType_IsSubtype(type, &PyUnicode_Type)); assert(_PyUnicode_CHECK(unicode)); - if (PyUnicode_READY(unicode) == -1) { - return NULL; - } self = type->tp_alloc(type, 0); if (self == NULL) { @@ -15369,15 +14379,11 @@ unicode_subtype_new(PyTypeObject *type, PyObject *unicode) _PyUnicode_STATE(self).kind = kind; _PyUnicode_STATE(self).compact = 0; _PyUnicode_STATE(self).ascii = _PyUnicode_STATE(unicode).ascii; - _PyUnicode_STATE(self).ready = 1; - _PyUnicode_WSTR(self) = NULL; _PyUnicode_UTF8_LENGTH(self) = 0; _PyUnicode_UTF8(self) = NULL; - _PyUnicode_WSTR_LENGTH(self) = 0; _PyUnicode_DATA_ANY(self) = NULL; share_utf8 = 0; - share_wstr = 0; if (kind == PyUnicode_1BYTE_KIND) { char_size = 1; if (PyUnicode_MAX_CHAR_VALUE(unicode) < 128) @@ -15385,14 +14391,10 @@ unicode_subtype_new(PyTypeObject *type, PyObject *unicode) } else if (kind == PyUnicode_2BYTE_KIND) { char_size = 2; - if (sizeof(wchar_t) == 2) - share_wstr = 1; } else { assert(kind == PyUnicode_4BYTE_KIND); char_size = 4; - if (sizeof(wchar_t) == 4) - share_wstr = 1; } /* Ensure we won't overflow the length. */ @@ -15411,13 +14413,8 @@ unicode_subtype_new(PyTypeObject *type, PyObject *unicode) _PyUnicode_UTF8_LENGTH(self) = length; _PyUnicode_UTF8(self) = data; } - if (share_wstr) { - _PyUnicode_WSTR_LENGTH(self) = length; - _PyUnicode_WSTR(self) = (wchar_t *)data; - } - memcpy(data, PyUnicode_DATA(unicode), - kind * (length + 1)); + memcpy(data, PyUnicode_DATA(unicode), kind * (length + 1)); assert(_PyUnicode_CheckConsistency(self, 1)); #ifdef Py_DEBUG _PyUnicode_HASH(self) = _PyUnicode_HASH(unicode); @@ -15429,6 +14426,13 @@ onError: return NULL; } +void +_PyUnicode_ExactDealloc(PyObject *op) +{ + assert(PyUnicode_CheckExact(op)); + unicode_dealloc(op); +} + PyDoc_STRVAR(unicode_doc, "str(object='') -> str\n\ str(bytes_or_buffer[, encoding[, errors]]) -> str\n\ @@ -15477,7 +14481,7 @@ PyTypeObject PyUnicode_Type = { unicode_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ - &PyBaseObject_Type, /* tp_base */ + 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ @@ -15490,51 +14494,88 @@ PyTypeObject PyUnicode_Type = { /* Initialize the Unicode implementation */ -PyStatus -_PyUnicode_Init(PyInterpreterState *interp) +static void +_init_global_state(void) { - struct _Py_unicode_state *state = &interp->unicode; - if (unicode_create_empty_string_singleton(state) < 0) { - return _PyStatus_NO_MEMORY(); + static int initialized = 0; + if (initialized) { + return; + } + initialized = 1; + + /* initialize the linebreak bloom filter */ + const Py_UCS2 linebreak[] = { + 0x000A, /* LINE FEED */ + 0x000D, /* CARRIAGE RETURN */ + 0x001C, /* FILE SEPARATOR */ + 0x001D, /* GROUP SEPARATOR */ + 0x001E, /* RECORD SEPARATOR */ + 0x0085, /* NEXT LINE */ + 0x2028, /* LINE SEPARATOR */ + 0x2029, /* PARAGRAPH SEPARATOR */ + }; + bloom_linebreak = make_bloom_mask( + PyUnicode_2BYTE_KIND, linebreak, + Py_ARRAY_LENGTH(linebreak)); +} + +void +_PyUnicode_InitState(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + return; + } + _init_global_state(); +} + + +PyStatus +_PyUnicode_InitGlobalObjects(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + return _PyStatus_OK(); } - if (_Py_IsMainInterpreter(interp)) { - /* initialize the linebreak bloom filter */ - const Py_UCS2 linebreak[] = { - 0x000A, /* LINE FEED */ - 0x000D, /* CARRIAGE RETURN */ - 0x001C, /* FILE SEPARATOR */ - 0x001D, /* GROUP SEPARATOR */ - 0x001E, /* RECORD SEPARATOR */ - 0x0085, /* NEXT LINE */ - 0x2028, /* LINE SEPARATOR */ - 0x2029, /* PARAGRAPH SEPARATOR */ - }; - bloom_linebreak = make_bloom_mask( - PyUnicode_2BYTE_KIND, linebreak, - Py_ARRAY_LENGTH(linebreak)); + /* Intern statically allocated string identifiers and deepfreeze strings. + * This must be done before any module initialization so that statically + * allocated string identifiers are used instead of heap allocated strings. + * Deepfreeze uses the interned identifiers if present to save space + * else generates them and they are interned to speed up dict lookups. + */ + _PyUnicode_InitStaticStrings(); + +#ifdef Py_DEBUG + assert(_PyUnicode_CheckConsistency(&_Py_STR(empty), 1)); + + for (int i = 0; i < 256; i++) { + assert(_PyUnicode_CheckConsistency(LATIN1(i), 1)); } +#endif return _PyStatus_OK(); } PyStatus -_PyUnicode_InitTypes(void) +_PyUnicode_InitTypes(PyInterpreterState *interp) { - if (PyType_Ready(&PyUnicode_Type) < 0) { - return _PyStatus_ERR("Can't initialize unicode type"); + if (!_Py_IsMainInterpreter(interp)) { + return _PyStatus_OK(); } - if (PyType_Ready(&EncodingMapType) < 0) { - return _PyStatus_ERR("Can't initialize encoding map type"); + + if (_PyStaticType_InitBuiltin(&EncodingMapType) < 0) { + goto error; } - if (PyType_Ready(&PyFieldNameIter_Type) < 0) { - return _PyStatus_ERR("Can't initialize field name iterator type"); + if (_PyStaticType_InitBuiltin(&PyFieldNameIter_Type) < 0) { + goto error; } - if (PyType_Ready(&PyFormatterIter_Type) < 0) { - return _PyStatus_ERR("Can't initialize formatter iter type"); + if (_PyStaticType_InitBuiltin(&PyFormatterIter_Type) < 0) { + goto error; } return _PyStatus_OK(); + +error: + return _PyStatus_ERR("Can't initialize unicode types"); } @@ -15561,29 +14602,24 @@ PyUnicode_InternInPlace(PyObject **p) return; } - if (PyUnicode_READY(s) == -1) { - PyErr_Clear(); - return; - } - - struct _Py_unicode_state *state = get_unicode_state(); - if (state->interned == NULL) { - state->interned = PyDict_New(); - if (state->interned == NULL) { + PyObject *interned = get_interned_dict(); + if (interned == NULL) { + interned = PyDict_New(); + if (interned == NULL) { PyErr_Clear(); /* Don't leave an exception */ return; } + set_interned_dict(interned); } - PyObject *t = PyDict_SetDefault(state->interned, s, s); + PyObject *t = PyDict_SetDefault(interned, s, s); if (t == NULL) { PyErr_Clear(); return; } if (t != s) { - Py_INCREF(t); - Py_SETREF(*p, t); + Py_SETREF(*p, Py_NewRef(t)); return; } @@ -15591,27 +14627,17 @@ PyUnicode_InternInPlace(PyObject **p) refcnt. unicode_dealloc() and _PyUnicode_ClearInterned() take care of this. */ Py_SET_REFCNT(s, Py_REFCNT(s) - 2); - _PyUnicode_STATE(s).interned = SSTATE_INTERNED_MORTAL; + _PyUnicode_STATE(s).interned = 1; } - +// Function kept for the stable ABI. +PyAPI_FUNC(void) PyUnicode_InternImmortal(PyObject **); void PyUnicode_InternImmortal(PyObject **p) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PyUnicode_InternImmortal() is deprecated; " - "use PyUnicode_InternInPlace() instead", 1) < 0) - { - // The function has no return value, the exception cannot - // be reported to the caller, so just log it. - PyErr_WriteUnraisable(NULL); - } - PyUnicode_InternInPlace(p); - if (PyUnicode_CHECK_INTERNED(*p) != SSTATE_INTERNED_IMMORTAL) { - _PyUnicode_STATE(*p).interned = SSTATE_INTERNED_IMMORTAL; - Py_INCREF(*p); - } + // Leak a reference on purpose + Py_INCREF(*p); } PyObject * @@ -15628,11 +14654,16 @@ PyUnicode_InternFromString(const char *cp) void _PyUnicode_ClearInterned(PyInterpreterState *interp) { - struct _Py_unicode_state *state = &interp->unicode; - if (state->interned == NULL) { + if (!_Py_IsMainInterpreter(interp)) { + // interned dict is shared by all interpreters return; } - assert(PyDict_CheckExact(state->interned)); + + PyObject *interned = get_interned_dict(); + if (interned == NULL) { + return; + } + assert(PyDict_CheckExact(interned)); /* Interned unicode strings are not forcibly deallocated; rather, we give them their stolen references back, and then clear and DECREF the @@ -15640,45 +14671,32 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp) #ifdef INTERNED_STATS fprintf(stderr, "releasing %zd interned strings\n", - PyDict_GET_SIZE(state->interned)); + PyDict_GET_SIZE(interned)); - Py_ssize_t immortal_size = 0, mortal_size = 0; + Py_ssize_t total_length = 0; #endif Py_ssize_t pos = 0; PyObject *s, *ignored_value; - while (PyDict_Next(state->interned, &pos, &s, &ignored_value)) { - assert(PyUnicode_IS_READY(s)); + while (PyDict_Next(interned, &pos, &s, &ignored_value)) { + assert(PyUnicode_CHECK_INTERNED(s)); + // Restore the two references (key and value) ignored + // by PyUnicode_InternInPlace(). + Py_SET_REFCNT(s, Py_REFCNT(s) + 2); +#ifdef INTERNED_STATS + total_length += PyUnicode_GET_LENGTH(s); +#endif - switch (PyUnicode_CHECK_INTERNED(s)) { - case SSTATE_INTERNED_IMMORTAL: - Py_SET_REFCNT(s, Py_REFCNT(s) + 1); -#ifdef INTERNED_STATS - immortal_size += PyUnicode_GET_LENGTH(s); -#endif - break; - case SSTATE_INTERNED_MORTAL: - // Restore the two references (key and value) ignored - // by PyUnicode_InternInPlace(). - Py_SET_REFCNT(s, Py_REFCNT(s) + 2); -#ifdef INTERNED_STATS - mortal_size += PyUnicode_GET_LENGTH(s); -#endif - break; - case SSTATE_NOT_INTERNED: - /* fall through */ - default: - Py_UNREACHABLE(); - } - _PyUnicode_STATE(s).interned = SSTATE_NOT_INTERNED; + _PyUnicode_STATE(s).interned = 0; } #ifdef INTERNED_STATS fprintf(stderr, - "total size of all interned strings: %zd/%zd mortal/immortal\n", - mortal_size, immortal_size); + "total length of all interned strings: %zd characters\n", + total_length); #endif - PyDict_Clear(state->interned); - Py_CLEAR(state->interned); + PyDict_Clear(interned); + Py_DECREF(interned); + set_interned_dict(NULL); } @@ -15708,7 +14726,7 @@ unicodeiter_traverse(unicodeiterobject *it, visitproc visit, void *arg) static PyObject * unicodeiter_next(unicodeiterobject *it) { - PyObject *seq, *item; + PyObject *seq; assert(it != NULL); seq = it->it_seq; @@ -15720,10 +14738,8 @@ unicodeiter_next(unicodeiterobject *it) int kind = PyUnicode_KIND(seq); const void *data = PyUnicode_DATA(seq); Py_UCS4 chr = PyUnicode_READ(kind, data, it->it_index); - item = PyUnicode_FromOrdinal(chr); - if (item != NULL) - ++it->it_index; - return item; + it->it_index++; + return unicode_char(chr); } it->it_seq = NULL; @@ -15731,6 +14747,29 @@ unicodeiter_next(unicodeiterobject *it) return NULL; } +static PyObject * +unicode_ascii_iter_next(unicodeiterobject *it) +{ + assert(it != NULL); + PyObject *seq = it->it_seq; + if (seq == NULL) { + return NULL; + } + assert(_PyUnicode_CHECK(seq)); + assert(PyUnicode_IS_COMPACT_ASCII(seq)); + if (it->it_index < PyUnicode_GET_LENGTH(seq)) { + const void *data = ((void*)(_PyASCIIObject_CAST(seq) + 1)); + Py_UCS1 chr = (Py_UCS1)PyUnicode_READ(PyUnicode_1BYTE_KIND, + data, it->it_index); + it->it_index++; + PyObject *item = (PyObject*)&_Py_SINGLETON(strings).ascii[chr]; + return Py_NewRef(item); + } + it->it_seq = NULL; + Py_DECREF(seq); + return NULL; +} + static PyObject * unicodeiter_len(unicodeiterobject *it, PyObject *Py_UNUSED(ignored)) { @@ -15745,15 +14784,14 @@ PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list( static PyObject * unicodeiter_reduce(unicodeiterobject *it, PyObject *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(iter); if (it->it_seq != NULL) { - return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter), + return Py_BuildValue("N(O)n", _PyEval_GetBuiltin(&_Py_ID(iter)), it->it_seq, it->it_index); } else { - PyObject *u = (PyObject *)_PyUnicode_New(0); + PyObject *u = unicode_new_empty(); if (u == NULL) return NULL; - return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), u); + return Py_BuildValue("N(N)", _PyEval_GetBuiltin(&_Py_ID(iter)), u); } } @@ -15820,6 +14858,19 @@ PyTypeObject PyUnicodeIter_Type = { 0, }; +PyTypeObject _PyUnicodeASCIIIter_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + .tp_name = "str_ascii_iterator", + .tp_basicsize = sizeof(unicodeiterobject), + .tp_dealloc = (destructor)unicodeiter_dealloc, + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = (traverseproc)unicodeiter_traverse, + .tp_iter = PyObject_SelfIter, + .tp_iternext = (iternextfunc)unicode_ascii_iter_next, + .tp_methods = unicodeiter_methods, +}; + static PyObject * unicode_iter(PyObject *seq) { @@ -15829,14 +14880,16 @@ unicode_iter(PyObject *seq) PyErr_BadInternalCall(); return NULL; } - if (PyUnicode_READY(seq) == -1) - return NULL; - it = PyObject_GC_New(unicodeiterobject, &PyUnicodeIter_Type); + if (PyUnicode_IS_COMPACT_ASCII(seq)) { + it = PyObject_GC_New(unicodeiterobject, &_PyUnicodeASCIIIter_Type); + } + else { + it = PyObject_GC_New(unicodeiterobject, &PyUnicodeIter_Type); + } if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = seq; + it->it_seq = Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } @@ -16049,31 +15102,42 @@ _PyUnicode_EnableLegacyWindowsFSEncoding(void) static inline int unicode_is_finalizing(void) { - struct _Py_unicode_state *state = get_unicode_state(); - return (state->interned == NULL); + return (get_interned_dict() == NULL); } #endif +void +_PyUnicode_FiniTypes(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + return; + } + + _PyStaticType_Dealloc(&EncodingMapType); + _PyStaticType_Dealloc(&PyFieldNameIter_Type); + _PyStaticType_Dealloc(&PyFormatterIter_Type); +} + + void _PyUnicode_Fini(PyInterpreterState *interp) { struct _Py_unicode_state *state = &interp->unicode; - // _PyUnicode_ClearInterned() must be called before - assert(state->interned == NULL); + if (_Py_IsMainInterpreter(interp)) { + // _PyUnicode_ClearInterned() must be called before _PyUnicode_Fini() + assert(get_interned_dict() == NULL); + // bpo-47182: force a unicodedata CAPI capsule re-import on + // subsequent initialization of main interpreter. + } _PyUnicode_FiniEncodings(&state->fs_codec); + interp->unicode.ucnhash_capi = NULL; unicode_clear_identifiers(state); - - for (Py_ssize_t i = 0; i < 256; i++) { - Py_CLEAR(state->latin1[i]); - } - Py_CLEAR(state->empty_string); } - /* A _string module, to export formatter_parser and formatter_field_name_split to the string.Formatter class implemented in Python. */ diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h index fb8bb9fc7ed..22f8243eaec 100644 --- a/Objects/unicodetype_db.h +++ b/Objects/unicodetype_db.h @@ -2,7 +2,6 @@ /* a list of unique character type descriptors */ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { - {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 32}, {0, 0, 0, 0, 0, 48}, @@ -1783,508 +1782,74 @@ static const unsigned short index1[] = { 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 126, 127, 128, 129, 130, 131, 132, 34, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 34, 34, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 143, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 143, 175, 176, 143, 177, 178, 179, 180, - 143, 181, 182, 183, 184, 185, 186, 143, 143, 187, 188, 189, 190, 143, - 191, 143, 192, 34, 34, 34, 34, 34, 34, 34, 193, 194, 34, 195, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 196, 34, 34, 34, 34, 34, 34, 34, 34, 197, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 34, 34, 34, 34, 198, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 34, 34, 34, 34, 199, 200, 201, 202, 143, 143, 143, 143, 203, - 204, 205, 206, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 125, 143, 144, 145, 146, 147, 148, 149, 34, 34, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 125, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 125, 174, 175, 125, 176, 177, 178, 179, + 125, 180, 181, 182, 183, 184, 185, 186, 125, 187, 188, 189, 190, 125, + 191, 192, 193, 34, 34, 34, 34, 34, 34, 34, 194, 195, 34, 196, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 197, 34, 34, 34, 34, 34, 34, 34, 34, 198, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 34, 34, 34, 34, 199, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 34, 34, 34, 34, 200, 201, 202, 203, 125, 125, 125, 125, 204, + 205, 206, 207, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 207, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 208, 209, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 210, 34, 34, 211, 34, 34, 212, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 213, 214, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 215, 216, 64, 217, - 218, 219, 220, 221, 222, 143, 223, 224, 225, 226, 227, 228, 229, 230, 64, - 64, 64, 64, 231, 232, 143, 143, 143, 143, 143, 143, 143, 143, 233, 143, - 234, 143, 235, 143, 143, 236, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 237, 34, 238, 239, 143, 143, 143, 143, 143, 240, 241, 242, 143, 243, - 244, 143, 143, 245, 246, 247, 248, 249, 143, 64, 250, 64, 64, 64, 64, 64, - 251, 252, 253, 254, 255, 64, 64, 256, 257, 64, 258, 143, 143, 143, 143, - 143, 143, 143, 143, 259, 260, 261, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 86, 262, 34, 263, 264, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 208, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 209, 210, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 211, 34, 34, 212, 34, 34, 213, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 214, 215, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 216, 217, 64, 218, + 219, 220, 221, 222, 223, 125, 224, 225, 226, 227, 228, 229, 230, 231, 64, + 64, 64, 64, 232, 233, 125, 125, 125, 125, 125, 125, 125, 125, 234, 125, + 235, 236, 237, 125, 125, 238, 125, 125, 125, 239, 125, 125, 125, 125, + 125, 240, 34, 241, 242, 125, 125, 125, 125, 125, 243, 244, 245, 125, 246, + 247, 125, 125, 248, 249, 250, 251, 252, 125, 64, 253, 64, 64, 64, 64, 64, + 254, 255, 256, 257, 258, 64, 64, 259, 260, 64, 261, 125, 125, 125, 125, + 125, 125, 125, 125, 262, 263, 264, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 86, 265, 34, 266, 267, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 265, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 266, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 267, + 34, 34, 34, 34, 34, 34, 268, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 269, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 270, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 268, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 271, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 269, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 272, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 270, 34, 271, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 273, 34, 274, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 272, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 275, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 273, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 34, 265, 34, 34, 274, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 276, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 34, 268, 34, 34, 277, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 275, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 276, 143, 277, 278, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 125, 125, 125, 125, 125, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 278, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 279, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, @@ -2321,7 +1886,6 @@ static const unsigned short index1[] = { 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 279, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, @@ -2357,1864 +1921,2320 @@ static const unsigned short index1[] = { 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 279, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 280, 125, 281, 282, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, }; static const unsigned short index2[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 3, 2, 4, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 6, 5, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 6, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 5, 5, 5, 6, 18, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 5, - 5, 5, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 5, 5, 5, 5, 5, 5, 5, 6, 5, 20, 5, 5, - 21, 5, 6, 5, 5, 22, 23, 6, 24, 5, 25, 6, 26, 20, 5, 27, 27, 27, 5, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 5, 17, 17, 17, 17, 17, 17, 17, 28, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 5, 19, 19, 19, 19, 19, 19, 19, 29, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 32, 33, 30, 31, 30, 31, 30, 31, 20, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 34, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 35, 30, 31, 30, 31, 30, 31, 36, 37, 38, 30, 31, 30, 31, 39, - 30, 31, 40, 40, 30, 31, 20, 41, 42, 43, 30, 31, 40, 44, 45, 46, 47, 30, - 31, 48, 20, 46, 49, 50, 51, 30, 31, 30, 31, 30, 31, 52, 30, 31, 52, 20, - 20, 30, 31, 52, 30, 31, 53, 53, 30, 31, 30, 31, 54, 30, 31, 20, 55, 30, - 31, 20, 56, 55, 55, 55, 55, 57, 58, 59, 57, 58, 59, 57, 58, 59, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 60, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 61, 57, 58, - 59, 30, 31, 62, 63, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 64, 20, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 20, 20, 20, 20, 20, 20, 65, - 30, 31, 66, 67, 68, 68, 30, 31, 69, 70, 71, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 72, 73, 74, 75, 76, 20, 77, 77, 20, 78, 20, 79, 80, 20, 20, - 20, 77, 81, 20, 82, 20, 83, 84, 20, 85, 86, 84, 87, 88, 20, 20, 86, 20, - 89, 90, 20, 20, 91, 20, 20, 20, 20, 20, 20, 20, 92, 20, 20, 93, 20, 94, - 93, 20, 20, 20, 95, 93, 96, 97, 97, 98, 20, 20, 20, 20, 20, 99, 20, 55, - 20, 20, 20, 20, 20, 20, 20, 20, 100, 101, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 103, 103, 103, 103, 103, 103, 103, 102, 102, 6, 6, 6, 6, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 102, 102, 102, 102, 102, 6, 6, 6, 6, 6, 6, 6, - 103, 6, 103, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 104, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 30, 31, 30, 31, 103, 6, 30, 31, 0, 0, 105, 50, 50, 50, 5, 106, 0, - 0, 0, 0, 6, 6, 107, 25, 108, 108, 108, 0, 109, 0, 110, 110, 111, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 112, 113, 113, 113, 114, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 115, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 116, 117, 117, 118, 119, 120, 121, 121, 121, 122, 123, - 124, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 125, 126, 127, 128, 129, 130, 5, 30, 31, 131, - 30, 31, 20, 64, 64, 64, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 133, - 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, - 133, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 5, - 25, 25, 25, 25, 25, 6, 6, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 134, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 135, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 0, 136, 136, 136, 136, 136, 136, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 2, 2, 1, 3, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 5, 4, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 4, 4, 4, 4, 4, 4, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 4, 4, 4, 5, 17, 5, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 4, + 4, 4, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 4, 4, 4, 4, 5, 4, 19, 4, 4, + 20, 4, 5, 4, 4, 21, 22, 5, 23, 4, 24, 5, 25, 19, 4, 26, 26, 26, 4, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 4, 16, 16, 16, 16, 16, 16, 16, 27, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 4, 18, 18, 18, 18, 18, 18, 18, 28, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 31, 32, 29, 30, 29, 30, 29, 30, 19, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 33, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 34, 29, 30, 29, 30, 29, 30, 35, 36, 37, 29, 30, 29, 30, 38, + 29, 30, 39, 39, 29, 30, 19, 40, 41, 42, 29, 30, 39, 43, 44, 45, 46, 29, + 30, 47, 19, 45, 48, 49, 50, 29, 30, 29, 30, 29, 30, 51, 29, 30, 51, 19, + 19, 29, 30, 51, 29, 30, 52, 52, 29, 30, 29, 30, 53, 29, 30, 19, 54, 29, + 30, 19, 55, 54, 54, 54, 54, 56, 57, 58, 56, 57, 58, 56, 57, 58, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 59, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 60, 56, 57, + 58, 29, 30, 61, 62, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 63, 19, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 19, 19, 19, 19, 19, 19, 64, + 29, 30, 65, 66, 67, 67, 29, 30, 68, 69, 70, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 71, 72, 73, 74, 75, 19, 76, 76, 19, 77, 19, 78, 79, 19, 19, + 19, 76, 80, 19, 81, 19, 82, 83, 19, 84, 85, 83, 86, 87, 19, 19, 85, 19, + 88, 89, 19, 19, 90, 19, 19, 19, 19, 19, 19, 19, 91, 19, 19, 92, 19, 93, + 92, 19, 19, 19, 94, 92, 95, 96, 96, 97, 19, 19, 19, 19, 19, 98, 19, 54, + 19, 19, 19, 19, 19, 19, 19, 19, 99, 100, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 102, 102, 102, 102, 102, 102, 102, 101, 101, 5, 5, 5, 5, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 101, 101, 101, 101, 101, 5, 5, 5, 5, 5, 5, 5, + 102, 5, 102, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 103, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 29, 30, 29, 30, 102, 5, 29, 30, 0, 0, 104, 49, 49, 49, 4, 105, 0, + 0, 0, 0, 5, 5, 106, 24, 107, 107, 107, 0, 108, 0, 109, 109, 110, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 111, 112, 112, 112, 113, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 114, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 115, 116, 116, 117, 118, 119, 120, 120, 120, 121, 122, + 123, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 124, 125, 126, 127, 128, 129, 4, 29, 30, 130, + 29, 30, 19, 63, 63, 63, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 4, + 24, 24, 24, 24, 24, 5, 5, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 133, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 134, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 0, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 0, 0, 102, 4, 4, 4, 4, 4, 5, 19, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 0, 0, 103, 5, 5, 5, 5, 5, 6, 20, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 138, 20, 5, 5, 0, 0, 5, 5, 5, 0, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 5, 25, 5, 25, 25, 5, 25, 25, 5, 25, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 55, 55, - 55, 55, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, - 21, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 5, 5, 5, 5, 55, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 5, 55, 25, 25, 25, 25, 25, 25, 25, 21, 5, 25, 25, 25, 25, 25, 25, - 103, 103, 25, 25, 5, 25, 25, 25, 25, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 55, 55, 55, 5, 5, 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 0, 21, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 103, 103, 5, 5, 5, 5, 103, 0, 0, 25, - 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 25, 25, 25, 25, 103, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 103, 25, 25, 25, 103, 25, 25, 25, 25, 25, 0, 0, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 0, 0, - 5, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 6, 55, 55, 55, 55, 55, 55, 0, 21, 21, 0, 0, 0, 0, 0, 0, - 25, 25, 25, 25, 25, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 21, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 25, 18, 25, 55, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 18, 18, 18, - 18, 25, 18, 18, 55, 25, 25, 25, 25, 25, 25, 25, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 25, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, - 103, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, - 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 0, 0, 55, 55, 55, 55, 0, 0, - 25, 55, 18, 18, 18, 25, 25, 25, 25, 0, 0, 18, 18, 0, 0, 18, 18, 25, 55, - 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 55, 55, 0, 55, 55, 55, 25, 25, 0, - 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 55, 5, 5, 27, 27, 27, 27, 27, - 27, 5, 5, 55, 5, 25, 0, 0, 25, 25, 18, 0, 55, 55, 55, 55, 55, 55, 0, 0, - 0, 0, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, - 55, 0, 55, 55, 0, 55, 55, 0, 0, 25, 0, 18, 18, 18, 25, 25, 0, 0, 0, 0, - 25, 25, 0, 0, 25, 25, 25, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, - 55, 0, 55, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 25, - 25, 55, 55, 55, 25, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 18, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, - 55, 55, 55, 55, 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 0, 0, 25, 55, - 18, 18, 18, 25, 25, 25, 25, 25, 0, 25, 25, 18, 0, 18, 18, 25, 0, 0, 55, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 25, 25, 0, 0, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 0, 0, 0, 0, 0, 0, 0, 55, 25, 25, 25, - 25, 25, 25, 0, 25, 18, 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, - 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 0, 55, - 55, 55, 55, 55, 0, 0, 25, 55, 18, 25, 18, 25, 25, 25, 25, 0, 0, 18, 18, - 0, 0, 18, 18, 25, 0, 0, 0, 0, 0, 0, 0, 25, 25, 18, 0, 0, 0, 0, 55, 55, 0, - 55, 55, 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 55, 27, - 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 55, 0, 55, 55, 55, - 55, 55, 55, 0, 0, 0, 55, 55, 55, 0, 55, 55, 55, 55, 0, 0, 0, 55, 55, 0, - 55, 0, 55, 55, 0, 0, 0, 55, 55, 0, 0, 0, 55, 55, 55, 0, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 18, 18, 25, 18, 18, 0, 0, - 0, 18, 18, 18, 0, 18, 18, 18, 25, 0, 0, 55, 0, 0, 0, 0, 0, 0, 18, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 25, 18, 18, 18, 25, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, - 55, 25, 25, 25, 18, 18, 18, 18, 0, 25, 25, 25, 0, 25, 25, 25, 25, 0, 0, - 0, 0, 0, 0, 0, 25, 25, 0, 55, 55, 55, 0, 0, 55, 0, 0, 55, 55, 25, 25, 0, - 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 5, 27, 27, - 27, 27, 27, 27, 27, 5, 55, 25, 18, 18, 5, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 55, 55, 55, 55, 55, 0, 0, 25, 55, 18, 25, 18, 18, 18, 18, 18, - 0, 25, 18, 18, 0, 18, 18, 25, 25, 0, 0, 0, 0, 0, 0, 0, 18, 18, 0, 0, 0, - 0, 0, 0, 55, 55, 0, 55, 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 0, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 18, 18, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 25, 25, 55, 18, 18, 18, 25, 25, 25, 25, 0, 18, 18, 18, 0, 18, 18, 18, 25, - 55, 5, 0, 0, 0, 0, 55, 55, 55, 18, 27, 27, 27, 27, 27, 27, 27, 55, 55, - 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 5, 55, 55, 55, 55, 55, 55, 0, 25, 18, 18, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 25, 0, 0, 0, 0, 18, 18, 18, 25, - 25, 25, 0, 25, 0, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 18, 18, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 55, 139, - 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 5, 55, 55, 55, 55, 55, 55, 103, - 25, 25, 25, 25, 25, 25, 25, 25, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 0, 55, 0, 55, 55, - 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 55, 139, 25, 25, 25, 25, 25, 25, 25, 25, 25, 55, 0, - 0, 55, 55, 55, 55, 55, 0, 103, 0, 25, 25, 25, 25, 25, 25, 0, 0, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 0, 0, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, + 136, 136, 136, 136, 136, 136, 137, 19, 4, 4, 0, 0, 4, 4, 4, 0, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 4, 24, 4, 24, 24, 4, 24, 24, 4, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 54, 54, + 54, 54, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, + 20, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 4, 4, 4, 4, 54, 54, 24, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 4, 54, 24, 24, 24, 24, 24, 24, 24, 20, 4, 24, 24, 24, 24, 24, 24, + 102, 102, 24, 24, 4, 24, 24, 24, 24, 54, 54, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 54, 54, 54, 4, 4, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 0, 20, 54, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 102, 102, 4, 4, 4, 4, 102, 0, 0, 24, 4, + 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 24, 24, 24, 24, 102, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 102, 24, 24, 24, 102, 24, 24, 24, 24, 24, 0, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 0, 0, + 4, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 5, 54, 54, 54, 54, 54, 54, 0, 20, 20, 0, 0, 0, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 20, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 17, 24, 54, 17, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 17, + 17, 24, 17, 17, 54, 24, 24, 24, 24, 24, 24, 24, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 24, 24, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 102, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 17, + 0, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 0, 0, 0, 54, 54, 54, 54, 0, 0, 24, + 54, 17, 17, 17, 24, 24, 24, 24, 0, 0, 17, 17, 0, 0, 17, 17, 24, 54, 0, 0, + 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 54, 54, 0, 54, 54, 54, 24, 24, 0, 0, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, 4, 4, 26, 26, 26, 26, 26, 26, 4, + 4, 54, 4, 24, 0, 0, 24, 24, 17, 0, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, + 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, + 54, 54, 0, 54, 54, 0, 0, 24, 0, 17, 17, 17, 24, 24, 0, 0, 0, 0, 24, 24, + 0, 0, 24, 24, 24, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 0, + 54, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 24, 54, + 54, 54, 24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 17, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, 54, 0, 0, 24, 54, 17, 17, + 17, 24, 24, 24, 24, 24, 0, 24, 24, 17, 0, 17, 17, 24, 0, 0, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 24, 24, 0, 0, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 4, 4, 0, 0, 0, 0, 0, 0, 0, 54, 24, 24, 24, 24, 24, + 24, 0, 24, 17, 17, 0, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, + 54, 54, 0, 0, 24, 54, 17, 24, 17, 24, 24, 24, 24, 0, 0, 17, 17, 0, 0, 17, + 17, 24, 0, 0, 0, 0, 0, 0, 0, 24, 24, 17, 0, 0, 0, 0, 54, 54, 0, 54, 54, + 54, 24, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 54, 26, 26, 26, + 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 54, 0, 54, 54, 54, 54, 54, + 54, 0, 0, 0, 54, 54, 54, 0, 54, 54, 54, 54, 0, 0, 0, 54, 54, 0, 54, 0, + 54, 54, 0, 0, 0, 54, 54, 0, 0, 0, 54, 54, 54, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 17, 17, 24, 17, 17, 0, 0, 0, + 17, 17, 17, 0, 17, 17, 17, 24, 0, 0, 54, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 26, + 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 24, 17, 17, 17, 24, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 24, 54, + 24, 24, 24, 17, 17, 17, 17, 0, 24, 24, 24, 0, 24, 24, 24, 24, 0, 0, 0, 0, + 0, 0, 0, 24, 24, 0, 54, 54, 54, 0, 0, 54, 0, 0, 54, 54, 24, 24, 0, 0, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 4, 26, 26, 26, 26, + 26, 26, 26, 4, 54, 24, 17, 17, 4, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 54, 54, 54, 54, 54, 0, 0, 24, 54, 17, 24, 17, 17, 17, 17, 17, 0, + 24, 17, 17, 0, 17, 17, 24, 24, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, + 0, 0, 54, 54, 0, 54, 54, 24, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 0, 54, 54, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 17, 17, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 24, 54, 17, 17, 17, 24, 24, 24, 24, 0, 17, 17, 17, 0, 17, 17, 17, 24, + 54, 4, 0, 0, 0, 0, 54, 54, 54, 17, 26, 26, 26, 26, 26, 26, 26, 54, 54, + 54, 24, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 4, 54, 54, 54, 54, 54, 54, 0, 24, 17, 17, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 24, 0, 0, 0, 0, 17, 17, 17, 24, 24, + 24, 0, 24, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 0, 0, 17, 17, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 54, 138, 24, 24, + 24, 24, 24, 24, 24, 0, 0, 0, 0, 4, 54, 54, 54, 54, 54, 54, 102, 24, 24, + 24, 24, 24, 24, 24, 24, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 25, 25, 5, 5, 5, 5, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 5, 25, 5, 25, 5, 25, 5, 5, 5, 5, 18, 18, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 5, 25, 25, 55, - 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 5, 5, - 5, 5, 5, 5, 5, 5, 25, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 18, 18, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 25, 18, 25, 25, 18, - 18, 25, 25, 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 5, 5, 5, 5, - 55, 55, 55, 55, 55, 55, 18, 18, 25, 25, 55, 55, 55, 55, 25, 25, 25, 55, - 18, 18, 18, 55, 55, 18, 18, 18, 18, 18, 18, 18, 55, 55, 55, 25, 25, 25, - 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 18, 25, - 25, 18, 18, 18, 18, 18, 18, 25, 55, 18, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 18, 18, 18, 25, 5, 5, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 0, 54, 0, 54, 54, 54, 54, 54, + 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 24, 54, 138, 24, 24, 24, 24, 24, 24, 24, 24, 24, 54, 0, 0, 54, 54, + 54, 54, 54, 0, 102, 0, 24, 24, 24, 24, 24, 24, 24, 0, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 0, 0, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 24, 4, 4, + 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 4, 24, 4, 24, 4, 24, 4, 4, 4, 4, 17, 17, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 17, 24, 24, 24, 24, 24, 4, 24, 24, 54, 54, 54, 54, 54, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 24, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 24, + 24, 24, 24, 17, 24, 24, 24, 24, 24, 24, 17, 24, 24, 17, 17, 24, 24, 54, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 54, + 54, 17, 17, 24, 24, 54, 54, 54, 54, 24, 24, 24, 54, 17, 17, 17, 54, 54, + 17, 17, 17, 17, 17, 17, 17, 54, 54, 54, 24, 24, 24, 24, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 17, 24, 24, 17, 17, 17, 17, + 17, 17, 24, 54, 17, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 17, 17, 24, + 4, 4, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 0, 139, 0, 0, 0, + 0, 0, 139, 0, 0, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 0, 140, 0, 0, 0, 0, 0, 140, 0, 0, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 5, 103, 141, 141, 141, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 55, - 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, - 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 0, 0, 237, 238, 239, 240, 241, - 242, 0, 0, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 2, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 5, 5, 5, 243, 243, 243, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 25, 25, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, - 18, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, - 0, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 18, 25, 25, 25, 25, 25, - 25, 25, 18, 18, 18, 18, 18, 18, 18, 18, 25, 18, 18, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 5, 5, 5, 103, 5, 5, 5, 5, 55, 25, 0, 0, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, - 25, 21, 25, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, - 0, 0, 0, 0, 55, 55, 55, 55, 55, 244, 244, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 25, 55, 0, 0, 0, 0, 0, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 25, 25, 25, - 18, 18, 18, 18, 25, 25, 18, 18, 18, 0, 0, 0, 0, 18, 18, 25, 18, 18, 18, - 18, 18, 18, 25, 25, 25, 0, 0, 0, 0, 5, 0, 0, 0, 5, 5, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 142, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 25, 25, 18, 18, 25, 0, 0, 5, 5, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 18, 25, - 25, 25, 25, 25, 25, 25, 0, 25, 18, 25, 18, 18, 25, 25, 25, 25, 25, 25, - 25, 25, 18, 18, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 0, 0, 25, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 103, - 5, 5, 5, 5, 5, 5, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 6, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 140, 140, 140, 140, 4, 101, 140, 140, 140, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, + 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 0, 54, 54, 54, 54, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 0, 54, 0, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 24, 24, 24, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 141, 142, 143, 144, 145, 146, 147, 148, 149, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, + 0, 0, 0, 0, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 0, 0, 236, 237, 238, 239, 240, 241, 0, 0, 4, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 1, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, + 242, 242, 242, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 17, 4, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 0, 24, 24, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 24, 24, 17, 24, 24, 24, 24, 24, 24, 24, 17, 17, 17, + 17, 17, 17, 17, 17, 24, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 4, 4, 4, 102, 4, 4, 4, 4, 54, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, + 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 24, 24, 20, 24, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 243, 243, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 24, 54, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 24, 24, 24, 17, 17, 17, 17, 24, 24, + 17, 17, 17, 0, 0, 0, 0, 17, 17, 24, 17, 17, 17, 17, 17, 17, 24, 24, 24, + 0, 0, 0, 0, 4, 0, 0, 0, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 141, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 24, 17, 17, 24, 0, 0, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 17, 24, 17, 24, 24, 24, 24, 24, 24, 24, 0, + 24, 17, 24, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 17, 17, 17, + 17, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 24, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, + 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 102, 4, 4, 4, 4, 4, 4, 0, 0, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 25, 25, 25, 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, - 18, 25, 25, 25, 25, 25, 18, 25, 18, 18, 18, 18, 18, 25, 18, 18, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 25, 25, 18, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 25, 25, 25, 18, 18, 25, 25, - 18, 25, 25, 25, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 25, 18, 25, 25, 18, 18, 18, 25, 18, 25, 25, 25, 18, - 18, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 18, 18, 18, 18, 18, - 25, 25, 25, 25, 25, 25, 25, 25, 18, 18, 25, 25, 0, 0, 0, 5, 5, 5, 5, 5, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 55, 55, 55, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 103, 103, 103, 103, 103, 103, 5, 5, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 0, 0, 0, 0, 0, 0, 0, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 0, 0, 254, 254, 254, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 5, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 25, 25, 55, 55, 55, 55, - 25, 55, 55, 55, 55, 55, 55, 25, 55, 55, 18, 25, 25, 55, 0, 0, 0, 0, 0, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 102, 255, 20, 20, 20, 256, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 257, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 258, 259, 260, 261, 262, 263, 20, 20, 264, 20, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 265, 265, 265, 265, 265, 265, 265, 265, 266, 266, 266, 266, 266, - 266, 266, 266, 265, 265, 265, 265, 265, 265, 0, 0, 266, 266, 266, 266, - 266, 266, 0, 0, 265, 265, 265, 265, 265, 265, 265, 265, 266, 266, 266, - 266, 266, 266, 266, 266, 265, 265, 265, 265, 265, 265, 265, 265, 266, - 266, 266, 266, 266, 266, 266, 266, 265, 265, 265, 265, 265, 265, 0, 0, - 266, 266, 266, 266, 266, 266, 0, 0, 267, 265, 268, 265, 269, 265, 270, - 265, 0, 266, 0, 266, 0, 266, 0, 266, 265, 265, 265, 265, 265, 265, 265, - 265, 266, 266, 266, 266, 266, 266, 266, 266, 271, 271, 272, 272, 272, - 272, 273, 273, 274, 274, 275, 275, 276, 276, 0, 0, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 265, 265, 325, 326, 327, 0, 328, 329, 266, 266, 330, 330, 331, - 6, 332, 6, 6, 6, 333, 334, 335, 0, 336, 337, 338, 338, 338, 338, 339, 6, - 6, 6, 265, 265, 340, 341, 0, 0, 342, 343, 266, 266, 344, 344, 0, 6, 6, 6, - 265, 265, 345, 346, 347, 127, 348, 349, 266, 266, 350, 350, 131, 6, 6, 6, - 0, 0, 351, 352, 353, 0, 354, 355, 356, 356, 357, 357, 358, 6, 6, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 21, 21, 5, 5, 5, 5, 5, 5, 5, 5, 6, - 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 6, 3, 3, 21, 21, 21, 21, 21, 2, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 18, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, - 21, 21, 21, 21, 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 359, 102, - 0, 0, 360, 361, 362, 363, 364, 365, 5, 5, 5, 5, 5, 102, 359, 26, 22, 23, - 360, 361, 362, 363, 364, 365, 5, 5, 5, 5, 5, 0, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 6, 6, 6, 6, 25, 6, 6, 6, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 121, 5, 5, 5, 5, 121, 5, 5, 20, 121, 121, 121, 20, 20, 121, 121, - 121, 20, 5, 121, 5, 5, 366, 121, 121, 121, 121, 121, 5, 5, 5, 5, 5, 5, - 121, 5, 367, 5, 121, 5, 368, 369, 121, 121, 366, 20, 121, 121, 370, 121, - 20, 55, 55, 55, 55, 20, 5, 5, 20, 20, 121, 121, 5, 5, 5, 5, 5, 121, 20, - 20, 20, 20, 5, 5, 5, 5, 371, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 373, 373, 373, 373, 373, 373, 373, 373, - 373, 373, 373, 373, 373, 373, 373, 373, 243, 243, 243, 30, 31, 243, 243, - 243, 243, 27, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 22, 23, 360, 361, 362, 363, 364, 365, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 22, 23, 360, 361, 362, - 363, 364, 365, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 22, 23, - 360, 361, 362, 363, 364, 365, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 375, - 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, - 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 359, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, - 359, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 26, - 22, 23, 360, 361, 362, 363, 364, 365, 27, 26, 22, 23, 360, 361, 362, 363, - 364, 365, 27, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 30, 31, 376, - 377, 378, 379, 380, 30, 31, 30, 31, 30, 31, 381, 382, 383, 384, 20, 30, - 31, 20, 30, 31, 20, 20, 20, 20, 20, 102, 102, 385, 385, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 20, 5, 5, 5, 5, 5, 5, 30, 31, 30, 31, 25, 25, 25, - 30, 31, 0, 0, 0, 0, 0, 5, 5, 5, 5, 27, 5, 5, 386, 386, 386, 386, 386, - 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, - 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, - 386, 386, 386, 386, 386, 0, 386, 0, 0, 0, 0, 0, 386, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 0, 0, 0, 0, 0, 103, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, - 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 387, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 2, 5, 5, 5, 5, 103, - 55, 243, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 243, 243, 243, 243, 243, 243, 243, 243, 243, 25, 25, 25, 25, - 18, 18, 5, 103, 103, 103, 103, 103, 5, 5, 243, 243, 243, 103, 55, 5, 5, - 5, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, - 6, 6, 103, 103, 55, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 5, 103, 103, 103, 55, 0, 0, 0, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 5, 5, 27, 27, 27, 27, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 27, 27, 27, 27, 27, 27, 27, 27, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 388, 55, 55, 388, 55, 55, 55, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 388, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 388, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 55, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 388, 55, 388, 388, 388, 55, 55, 55, 55, 55, 55, 388, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 388, 388, 388, 388, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 388, 388, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, - 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 103, 103, 103, 103, 103, 103, 5, 5, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, 5, 5, 5, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 55, 25, 6, 6, 6, 5, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 5, 103, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 102, 102, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 25, 25, - 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 6, 6, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 20, 20, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 102, 20, 20, 20, 20, 20, 20, 20, - 20, 30, 31, 30, 31, 389, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 103, 6, - 6, 30, 31, 390, 20, 55, 30, 31, 30, 31, 391, 20, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 392, 393, 394, - 395, 392, 20, 396, 397, 398, 399, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 400, 401, 402, 30, 31, 30, 31, 0, 0, 0, 0, 0, 30, - 31, 0, 20, 0, 20, 30, 31, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103, 103, 103, 30, 31, 55, 102, 102, 20, - 55, 55, 55, 55, 55, 55, 55, 25, 55, 55, 55, 25, 55, 55, 55, 55, 25, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 18, 18, 25, 25, 18, 5, 5, 5, 5, 25, 0, 0, 0, 27, 27, 27, - 27, 27, 27, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 18, - 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 25, 25, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 55, 55, 55, 55, 55, 55, 5, 5, 5, 55, 5, 55, 55, 25, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, - 25, 25, 25, 25, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 25, 25, 25, 18, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 25, 18, 18, 25, 25, 25, 25, 18, 18, 25, 25, 18, - 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 103, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 0, 0, 0, 0, 5, 5, 55, 55, 55, 55, 55, 25, 103, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 18, 18, - 25, 25, 18, 18, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 25, 55, - 55, 55, 55, 55, 55, 55, 55, 25, 18, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 0, 0, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 103, 55, 55, 55, 55, 55, 55, 5, 5, 5, 55, 18, 25, 18, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 55, 25, 25, 25, - 55, 55, 25, 25, 55, 55, 55, 55, 55, 25, 25, 55, 25, 55, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 103, 5, 5, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 25, 18, 18, 5, 5, 55, - 103, 103, 18, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, - 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 403, 20, 20, 20, 20, 20, 20, 20, 6, 102, 102, 102, 102, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 103, 6, 6, 0, 0, 0, 0, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, - 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, - 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, - 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 483, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 18, 18, 25, 18, 18, 25, 18, 18, 5, 18, 25, 0, 0, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, - 55, 55, 388, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 484, 485, 486, 487, 488, 489, - 490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 491, 492, 493, 494, 495, 0, 0, - 0, 0, 0, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 0, 55, 0, - 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 496, 496, 496, 496, 496, 496, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 496, 496, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, - 5, 5, 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 18, 18, 18, 5, 5, 6, 0, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 0, 0, 496, 55, 496, 55, 496, 0, - 496, 55, 496, 55, 496, 55, 496, 55, 496, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 21, 0, 5, 5, 5, 5, 5, 5, 6, - 5, 5, 5, 5, 5, 5, 6, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 6, 5, 5, 5, - 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 6, 18, 6, 19, 19, 19, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 17, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 24, 24, 24, 24, 24, 17, 24, + 17, 17, 17, 17, 17, 24, 17, 17, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 0, 24, 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 17, 24, 24, 24, 24, 17, 17, 24, 24, 17, 24, 24, 24, 54, 54, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 24, + 24, 17, 17, 17, 24, 17, 24, 24, 24, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 17, 17, 17, 17, 17, 17, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 17, + 17, 24, 24, 0, 0, 0, 4, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 54, 54, 54, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 102, 102, 102, 102, 102, 102, 4, 4, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 0, 0, 0, 0, 0, 0, 0, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 0, 0, + 253, 253, 253, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, + 24, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 24, 24, + 24, 24, 24, 24, 24, 54, 54, 54, 54, 24, 54, 54, 54, 54, 54, 54, 24, 54, + 54, 17, 24, 24, 54, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 103, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 497, 497, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 55, 55, 55, 55, - 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, - 55, 55, 55, 0, 0, 0, 5, 5, 5, 6, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 5, 5, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, - 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 101, 254, 19, 19, 19, 255, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 256, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 257, 258, 259, 260, 261, 262, 19, + 19, 263, 19, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 264, 264, 264, 264, 264, 264, 264, + 264, 265, 265, 265, 265, 265, 265, 265, 265, 264, 264, 264, 264, 264, + 264, 0, 0, 265, 265, 265, 265, 265, 265, 0, 0, 264, 264, 264, 264, 264, + 264, 264, 264, 265, 265, 265, 265, 265, 265, 265, 265, 264, 264, 264, + 264, 264, 264, 264, 264, 265, 265, 265, 265, 265, 265, 265, 265, 264, + 264, 264, 264, 264, 264, 0, 0, 265, 265, 265, 265, 265, 265, 0, 0, 266, + 264, 267, 264, 268, 264, 269, 264, 0, 265, 0, 265, 0, 265, 0, 265, 264, + 264, 264, 264, 264, 264, 264, 264, 265, 265, 265, 265, 265, 265, 265, + 265, 270, 270, 271, 271, 271, 271, 272, 272, 273, 273, 274, 274, 275, + 275, 0, 0, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 264, 264, 324, 325, 326, 0, 327, + 328, 265, 265, 329, 329, 330, 5, 331, 5, 5, 5, 332, 333, 334, 0, 335, + 336, 337, 337, 337, 337, 338, 5, 5, 5, 264, 264, 339, 340, 0, 0, 341, + 342, 265, 265, 343, 343, 0, 5, 5, 5, 264, 264, 344, 345, 346, 126, 347, + 348, 265, 265, 349, 349, 130, 5, 5, 5, 0, 0, 350, 351, 352, 0, 353, 354, + 355, 355, 356, 356, 357, 5, 5, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, + 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 5, 4, 4, 5, 2, 2, 20, 20, 20, 20, 20, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 17, 17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 20, 20, 20, 20, 20, 0, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 358, 101, 0, 0, 359, 360, 361, 362, 363, + 364, 4, 4, 4, 4, 4, 101, 358, 25, 21, 22, 359, 360, 361, 362, 363, 364, + 4, 4, 4, 4, 4, 0, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, + 5, 5, 5, 24, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 120, 4, 4, 4, 4, 120, 4, + 4, 19, 120, 120, 120, 19, 19, 120, 120, 120, 19, 4, 120, 4, 4, 365, 120, + 120, 120, 120, 120, 4, 4, 4, 4, 4, 4, 120, 4, 366, 4, 120, 4, 367, 368, + 120, 120, 365, 19, 120, 120, 369, 120, 19, 54, 54, 54, 54, 19, 4, 4, 19, + 19, 120, 120, 4, 4, 4, 4, 4, 120, 19, 19, 19, 19, 4, 4, 4, 4, 370, 4, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 371, 371, + 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, + 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 372, 372, 242, 242, 242, 29, 30, 242, 242, 242, 242, 26, 4, 4, 0, 0, 0, + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 373, 373, 373, 374, 374, 374, 374, 374, 374, 374, + 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, + 374, 374, 374, 374, 374, 358, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 25, + 21, 22, 359, 360, 361, 362, 363, 364, 26, 358, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 25, 21, 22, 359, 360, 361, 362, + 363, 364, 26, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 25, 21, 22, + 359, 360, 361, 362, 363, 364, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 29, 30, 375, 376, 377, 378, 379, 29, + 30, 29, 30, 29, 30, 380, 381, 382, 383, 19, 29, 30, 19, 29, 30, 19, 19, + 19, 19, 19, 101, 101, 384, 384, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 19, 4, 4, 4, 4, 4, 4, 29, 30, 29, 30, 24, 24, 24, 29, 30, 0, 0, 0, 0, 0, + 4, 4, 4, 4, 26, 4, 4, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 0, + 385, 0, 0, 0, 0, 0, 385, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 102, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, + 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, + 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 386, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 0, 0, 0, 0, 1, 4, 4, 4, 4, 102, 54, 242, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 24, 24, 24, 24, 17, 17, 4, 102, 102, 102, + 102, 102, 4, 4, 242, 242, 242, 102, 54, 4, 4, 4, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 24, 24, 5, 5, 102, 102, 54, 4, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 4, 102, 102, 102, 54, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 0, 4, 4, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 26, 26, 26, 26, 26, 26, + 26, 26, 4, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, 54, + 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 387, 54, 54, 387, 54, 54, 54, 387, + 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 387, 54, 387, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 387, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 387, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 387, 54, + 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 387, 387, 387, + 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 387, + 387, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, + 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 387, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 387, 387, 54, 387, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 387, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, + 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 102, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, + 102, 102, 102, 102, 102, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 102, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 54, 24, 5, 5, 5, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, + 102, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 101, 101, 24, 24, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 24, 24, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 102, 102, 102, 102, 102, 102, 102, 102, 102, 5, 5, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 19, 19, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 101, 19, 19, 19, 19, 19, 19, 19, 19, 29, 30, 29, 30, 388, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 102, 5, 5, 29, 30, 389, 19, 54, 29, 30, 29, + 30, 390, 19, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 391, 392, 393, 394, 391, 19, 395, 396, 397, 398, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 399, 400, + 401, 29, 30, 29, 30, 0, 0, 0, 0, 0, 29, 30, 0, 19, 0, 19, 29, 30, 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 5, 5, 5, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 27, 27, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 101, 101, 101, 29, 30, 54, 101, 101, 19, 54, 54, 54, 54, 54, 54, 54, 24, + 54, 54, 54, 24, 54, 54, 54, 54, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 24, 24, + 17, 4, 4, 4, 4, 24, 0, 0, 0, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 54, 54, 54, 54, 54, 54, 4, 4, 4, 54, + 4, 54, 54, 24, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 24, + 24, 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 17, 24, + 24, 24, 24, 17, 17, 24, 24, 17, 17, 17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 0, 102, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 4, 4, 54, + 54, 54, 54, 54, 24, 102, 54, 54, 54, 54, 54, 54, 54, 54, 54, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 24, 24, 24, 17, 17, 24, 24, 17, 17, 24, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 54, 54, 24, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 0, 0, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 4, 4, 4, 4, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, 54, 54, 54, 54, 54, 54, 4, + 4, 4, 54, 17, 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 24, 54, 24, 24, 24, 54, 54, 24, 24, 54, 54, 54, 54, 54, 24, 24, 54, + 24, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 54, 102, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, + 24, 24, 17, 17, 4, 4, 54, 102, 102, 17, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, + 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 54, 54, 54, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 402, 19, 19, 19, 19, 19, 19, 19, 5, 101, 101, + 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 5, 5, 0, 0, 0, 0, 403, + 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, + 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, + 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 477, 478, 479, 480, 481, 482, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 24, 17, 17, 24, 17, 17, + 4, 17, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 243, 55, 55, 55, - 55, 55, 55, 55, 55, 243, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 0, 0, - 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 5, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 5, 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 498, 498, 498, 498, 498, 498, + 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 387, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 387, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 483, 484, 485, 486, 487, 488, 489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 490, 491, 492, 493, 494, 0, 0, 0, 0, 0, 54, 24, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 54, 54, 54, 54, 54, 0, 54, 0, 54, 54, 0, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 495, + 495, 495, 495, 495, 495, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 495, 495, + 4, 4, 4, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 17, 17, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 17, 17, 17, + 4, 4, 5, 0, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, + 4, 4, 4, 4, 0, 0, 0, 0, 495, 54, 495, 54, 495, 0, 495, 54, 495, 54, 495, + 54, 495, 54, 495, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 20, 0, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 5, 4, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 4, 4, 4, 4, 4, 4, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 4, 4, 4, 5, 17, 5, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 496, 496, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, + 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 0, 0, 0, + 4, 4, 4, 5, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 20, 20, 20, 4, 4, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 4, 4, + 4, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 26, + 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 26, 26, 4, + 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 242, 54, 54, 54, 54, 54, 54, 54, 54, 242, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 24, 24, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 4, 242, 242, 242, + 242, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, - 498, 498, 498, 498, 498, 498, 499, 499, 499, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 498, 498, 498, 498, 498, 498, 498, 498, + 498, 498, 498, 498, 498, 498, 498, 498, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 497, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 497, 0, 0, 0, 0, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 0, - 0, 0, 0, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 499, 499, 0, 0, 0, 0, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 500, 500, 500, 500, + 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 0, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 0, 499, + 499, 499, 499, 499, 499, 499, 0, 499, 499, 0, 500, 500, 500, 500, 500, + 500, 500, 500, 500, 500, 500, 0, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 0, 500, 500, 500, 500, 500, 500, 500, - 500, 500, 500, 500, 500, 500, 500, 500, 0, 500, 500, 500, 500, 500, 500, - 500, 0, 500, 500, 0, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, - 501, 0, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, - 501, 501, 0, 501, 501, 501, 501, 501, 501, 501, 0, 501, 501, 0, 0, 0, 0, + 0, 500, 500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 102, 102, 101, 101, 101, 0, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 0, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 102, 103, 103, 102, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 0, 54, 54, 0, 0, 0, 54, 0, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 4, + 26, 26, 26, 26, 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 26, 26, 26, 26, + 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 0, + 0, 0, 0, 26, 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 26, 26, 26, 26, 26, 26, 0, 0, + 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 0, 0, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, - 55, 55, 0, 0, 0, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 5, 27, 27, 27, 27, 27, - 27, 27, 27, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 27, 27, 27, 27, 27, 27, 27, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 26, 26, 54, 54, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 54, 24, 24, 24, 0, 24, 24, 0, 0, 0, 0, 0, 24, + 24, 24, 24, 54, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 24, 24, 24, 0, 0, 0, 0, 24, 25, 21, 22, 359, 26, + 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 26, 26, 4, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 0, 0, 0, 0, 0, 27, 27, 27, 27, - 27, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 27, 27, 27, 27, 27, 27, 0, 0, 0, 5, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 54, 54, 54, 54, 54, 54, 54, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 24, 24, 0, 0, 0, 0, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 26, 26, + 26, 26, 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, + 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 27, 27, 55, 55, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 55, 25, 25, 25, 0, 25, 25, 0, 0, 0, 0, 0, 25, 25, 25, 25, 55, 55, - 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 25, 25, 25, 0, 0, 0, 0, 25, 26, 22, 23, 360, 27, 27, 27, 27, 27, 0, 0, 0, - 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 27, 27, 5, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 0, 0, 0, - 0, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 27, 27, 27, 27, 27, 27, - 27, 27, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, - 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, - 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 0, 0, 0, 0, 0, 0, 0, 27, 27, - 27, 27, 27, 27, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, + 0, 26, 26, 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 25, 25, 5, 0, 0, 55, 55, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 55, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 27, 27, 27, 27, - 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 25, 18, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 25, 55, 55, 25, 25, - 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 18, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 18, 18, 25, 25, 5, 5, 21, 5, 5, - 5, 5, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, - 0, 0, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 25, 25, 25, - 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 5, 5, 55, 18, 18, 55, 0, 0, - 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 25, 5, 5, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 18, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 18, 18, 55, 55, 55, 55, 5, 5, 5, 5, 25, 25, 25, 25, 5, - 18, 25, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 5, 55, 5, 5, 5, 0, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, - 18, 18, 25, 25, 25, 18, 18, 25, 18, 25, 25, 5, 5, 5, 5, 5, 5, 25, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 0, 55, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 18, 18, 25, 25, - 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 0, 0, 0, 0, 0, 0, 25, 25, 18, 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 0, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, - 55, 0, 55, 55, 55, 55, 55, 0, 25, 25, 55, 18, 18, 25, 18, 18, 18, 18, 0, - 0, 18, 18, 0, 0, 18, 18, 18, 0, 0, 55, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, - 0, 55, 55, 55, 55, 55, 18, 18, 0, 0, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, - 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, - 25, 25, 25, 25, 25, 18, 18, 25, 25, 25, 18, 25, 55, 55, 55, 55, 5, 5, 5, - 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 0, 5, 25, 55, 55, 55, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, - 18, 25, 25, 25, 25, 25, 25, 18, 25, 18, 18, 18, 18, 25, 25, 18, 25, 25, - 55, 55, 5, 55, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 0, 0, 18, 18, 18, 18, 25, 25, - 18, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 55, 55, 55, 55, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 25, - 25, 25, 25, 18, 18, 25, 18, 25, 25, 5, 5, 5, 55, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 25, 18, 18, 25, 25, - 25, 25, 25, 25, 18, 25, 55, 5, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, - 25, 25, 18, 18, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 0, 0, 0, 0, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, 5, 5, 5, 5, 55, 55, 55, 55, 55, - 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, - 18, 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, 25, 25, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 24, 24, 4, 0, 0, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, + 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 26, 26, 26, 26, 4, 4, 4, 4, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, + 24, 24, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 24, + 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, + 4, 4, 4, 0, 0, 0, 0, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 24, 54, 54, 24, 24, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 17, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 24, 17, 17, 24, + 24, 4, 4, 20, 4, 4, 4, 4, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 17, 24, 24, 24, + 24, 24, 24, 24, 24, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 4, 4, 4, + 54, 17, 17, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 4, 4, 54, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 24, 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, + 17, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 54, 54, 54, 54, 4, 4, 4, + 4, 24, 24, 24, 24, 4, 17, 24, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 4, + 54, 4, 4, 4, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 17, 17, 24, 17, 24, 24, 4, 4, 4, + 4, 4, 4, 24, 54, 54, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 0, 54, 0, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 4, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 17, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 17, 17, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, + 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, 54, 0, 24, 24, 54, 17, + 17, 24, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0, 17, 17, 17, 0, 0, 54, 0, 0, + 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 17, 17, 0, 0, 24, 24, + 24, 24, 24, 24, 24, 0, 0, 0, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 17, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 24, 24, 24, 17, + 24, 54, 54, 54, 54, 4, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, + 4, 0, 4, 24, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 24, 24, 24, 17, 24, 17, 17, 17, + 17, 24, 24, 17, 24, 24, 54, 54, 4, 54, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 24, 0, 0, + 17, 17, 17, 17, 24, 24, 17, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 24, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, + 17, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 24, 17, 24, 24, 4, 4, 4, 54, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, + 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 17, 24, 17, 17, 24, 24, 24, 24, 24, 24, 17, 24, 54, 4, 0, 0, 0, 0, 0, 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 24, 24, 24, 17, 17, 24, 24, 24, 24, 17, 24, 24, 24, + 24, 24, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 26, 26, 4, 4, 4, + 4, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 24, + 24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, + 17, 17, 17, 0, 17, 17, 0, 0, 24, 24, 17, 24, 54, 17, 54, 17, 24, 4, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 24, 0, 0, 24, 24, + 17, 17, 17, 17, 24, 54, 4, 54, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 17, 54, 24, 24, 24, + 24, 4, 4, 4, 4, 4, 4, 4, 4, 24, 0, 0, 0, 0, 0, 0, 0, 0, 54, 24, 24, 24, + 24, 24, 24, 17, 17, 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 24, 24, 4, 4, 4, + 54, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, + 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 17, 24, 24, 24, 24, 24, 24, 24, 0, 24, 24, 24, 24, 24, 24, 17, 24, + 54, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 0, 0, 0, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 0, 17, 24, 24, 24, 24, 24, 24, 24, 17, 24, + 24, 17, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 24, 24, 24, 0, 0, 0, 24, 0, 24, 24, 0, 24, 24, 24, 24, 24, 24, + 24, 54, 24, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, 17, 17, 0, 24, 24, 0, + 17, 17, 24, 17, 24, 54, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 17, 17, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 24, 24, 54, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 17, 17, 24, 24, 24, 24, 24, 0, 0, 0, 17, 17, 24, 17, 24, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 0, 4, 4, 4, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 24, + 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, + 0, 0, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 0, 24, 24, 24, 24, 24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 102, 102, 102, 102, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 26, 26, 26, 26, 26, 26, 26, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 0, 0, 0, 24, 54, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 19, 19, 19, 19, 19, 19, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 4, 102, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 0, 102, + 102, 102, 102, 102, 102, 102, 0, 102, 102, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 0, 0, 4, 24, 24, 4, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 17, 17, 24, 24, 24, 4, 4, 4, 17, 17, + 17, 17, 17, 17, 20, 20, 20, 20, 20, 20, 20, 20, 24, 24, 24, 24, 24, 24, + 24, 24, 4, 4, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 24, 24, + 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 24, 24, 24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 0, 0, 0, 0, 0, 0, 0, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, 0, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 18, 18, 18, 0, 18, - 18, 0, 0, 25, 25, 18, 25, 55, 18, 55, 18, 25, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 0, 0, 25, 25, 18, 18, 18, 18, - 25, 55, 5, 55, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 18, 55, 25, 25, 25, 25, 5, 5, 5, - 5, 5, 5, 5, 5, 25, 0, 0, 0, 0, 0, 0, 0, 0, 55, 25, 25, 25, 25, 25, 25, - 18, 18, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, 25, 25, 5, 5, 5, 55, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 25, 25, 25, 25, 25, 25, - 0, 25, 25, 25, 25, 25, 25, 18, 25, 55, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 5, 5, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 18, - 25, 25, 25, 25, 25, 25, 25, 18, 25, 25, 18, 25, 25, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, - 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 0, 0, 0, 25, 0, 25, - 25, 0, 25, 25, 25, 25, 25, 25, 25, 55, 25, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 0, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, - 18, 18, 18, 18, 0, 25, 25, 0, 18, 18, 25, 18, 25, 55, 0, 0, 0, 0, 0, 0, - 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 25, 25, 18, 18, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 5, 5, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, 25, 25, 25, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 103, 103, - 103, 103, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 0, 27, 27, 27, 27, 27, 27, 27, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 25, 55, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 103, 103, 5, 103, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 103, 103, 103, 103, 0, 103, 103, 103, 103, 103, 103, 103, - 0, 103, 103, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, - 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 5, 25, 25, 5, - 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 18, 18, 25, 25, 25, 5, 5, 5, 18, 18, 18, 18, 18, 18, 21, 21, - 21, 21, 21, 21, 21, 21, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 25, 25, 25, - 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, 20, - 20, 20, 20, 20, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 0, 121, 121, 0, 0, 121, 0, - 0, 121, 121, 0, 0, 121, 121, 121, 121, 0, 121, 121, 121, 121, 121, 121, - 121, 121, 20, 20, 20, 20, 0, 20, 0, 20, 20, 20, 20, 20, 20, 20, 0, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, 0, - 121, 121, 121, 121, 0, 0, 121, 121, 121, 121, 121, 121, 121, 121, 0, 121, - 121, 121, 121, 121, 121, 121, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, - 0, 121, 121, 121, 121, 0, 121, 121, 121, 121, 121, 0, 121, 0, 0, 0, 121, - 121, 121, 121, 121, 121, 121, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 5, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 5, 20, 20, 20, 20, - 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 5, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 5, 20, 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 5, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 5, 20, 20, - 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 5, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 5, 20, 20, 20, 20, 20, 20, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 5, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 5, 20, 20, 20, 20, 20, 20, 121, 20, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 25, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 25, 25, 25, 25, 25, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 55, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 0, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 0, 25, 25, 0, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 103, 103, 103, 103, 103, 103, 103, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 0, 0, 0, 0, 55, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, - 25, 25, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 19, 19, 120, 0, 120, 120, 0, 0, 120, 0, 0, 120, 120, 0, 0, 120, 120, 120, + 120, 0, 120, 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, 0, 19, 0, + 19, 19, 19, 19, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 120, 120, 0, 120, 120, 120, 120, 0, 0, 120, 120, 120, + 120, 120, 120, 120, 120, 0, 120, 120, 120, 120, 120, 120, 120, 0, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 120, 120, 0, 120, 120, 120, 120, 0, 120, 120, + 120, 120, 120, 0, 120, 0, 0, 0, 120, 120, 120, 120, 120, 120, 120, 0, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 0, 0, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 4, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 4, 19, 19, 19, 19, 19, 19, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 4, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 4, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 4, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 4, 19, 19, 19, 19, 19, 19, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 4, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 4, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 4, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 4, 19, 19, 19, 19, + 19, 19, 120, 19, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, + 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, + 4, 4, 4, 4, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 4, 4, 4, 4, + 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, + 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 54, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, + 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 24, 24, 24, 24, 24, 24, 24, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 0, 0, 24, 24, 24, 24, 24, 24, 24, 0, 24, 24, + 0, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 102, + 102, 102, 102, 102, 102, 102, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 0, 54, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, 24, 24, 24, 24, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 24, 24, 24, 24, 24, 24, 24, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 501, 501, 501, 501, + 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, + 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, + 501, 501, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, - 502, 502, 502, 502, 502, 502, 502, 503, 503, 503, 503, 503, 503, 503, + 502, 502, 502, 502, 502, 502, 502, 502, 24, 24, 24, 24, 24, 24, 24, 102, + 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 4, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 4, 26, 26, 26, 4, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 4, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 0, + 0, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 0, + 54, 0, 54, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 54, 0, 54, 0, 54, 0, 54, 54, + 54, 0, 54, 54, 0, 54, 0, 0, 54, 0, 54, 0, 54, 0, 54, 0, 54, 0, 54, 54, 0, + 54, 0, 0, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, + 54, 0, 54, 54, 54, 54, 0, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, + 0, 0, 0, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 358, 358, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, - 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 25, 25, - 25, 25, 25, 25, 25, 103, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 503, 503, 503, 4, 4, 4, 4, 4, 4, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 4, 4, 4, 4, 4, 4, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 503, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, + 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 54, 387, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, + 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 27, 27, 27, 5, 27, 27, 27, 27, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 0, 55, 0, 0, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 55, 0, 55, 0, 55, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, - 55, 0, 55, 0, 55, 0, 55, 55, 55, 0, 55, 55, 0, 55, 0, 0, 55, 0, 55, 0, - 55, 0, 55, 0, 55, 0, 55, 55, 0, 55, 0, 0, 55, 55, 55, 55, 0, 55, 55, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 55, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 55, 55, 55, 0, 55, 55, 55, - 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 359, 359, 26, 22, 23, 360, 361, - 362, 363, 364, 365, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 504, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 5, 5, 5, 5, 5, 5, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 5, 5, 5, 5, 5, 5, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 0, - 0, 0, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, - 0, 0, 0, 0, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, - 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, + 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, }; /* Returns the numeric value as double for Unicode characters @@ -4291,10 +4311,12 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C50: case 0x11D50: case 0x11DA0: + case 0x11F50: case 0x16A60: case 0x16AC0: case 0x16B50: case 0x16E80: + case 0x1D2C0: case 0x1D2E0: case 0x1D7CE: case 0x1D7D8: @@ -4303,6 +4325,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7F6: case 0x1E140: case 0x1E2F0: + case 0x1E4F0: case 0x1E950: case 0x1F100: case 0x1F101: @@ -4420,6 +4443,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5A: case 0x11D51: case 0x11DA1: + case 0x11F51: case 0x12415: case 0x1241E: case 0x1242C: @@ -4431,6 +4455,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16B51: case 0x16E81: case 0x16E94: + case 0x1D2C1: case 0x1D2E1: case 0x1D360: case 0x1D372: @@ -4442,6 +4467,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7F7: case 0x1E141: case 0x1E2F1: + case 0x1E4F1: case 0x1E8C7: case 0x1E951: case 0x1EC71: @@ -4599,6 +4625,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C63: case 0x16B5B: case 0x16E8A: + case 0x1D2CA: case 0x1D2EA: case 0x1D369: case 0x1EC7A: @@ -4706,6 +4733,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2492: case 0x24EB: case 0x16E8B: + case 0x1D2CB: case 0x1D2EB: return (double) 11.0; case 0x109BC: @@ -4719,6 +4747,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2493: case 0x24EC: case 0x16E8C: + case 0x1D2CC: case 0x1D2EC: return (double) 12.0; case 0x246C: @@ -4726,6 +4755,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2494: case 0x24ED: case 0x16E8D: + case 0x1D2CD: case 0x1D2ED: return (double) 13.0; case 0x0F30: @@ -4735,6 +4765,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2495: case 0x24EE: case 0x16E8E: + case 0x1D2CE: case 0x1D2EE: return (double) 14.0; case 0x246E: @@ -4742,6 +4773,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2496: case 0x24EF: case 0x16E8F: + case 0x1D2CF: case 0x1D2EF: return (double) 15.0; case 0x0F31: @@ -4752,6 +4784,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2497: case 0x24F0: case 0x16E90: + case 0x1D2D0: case 0x1D2F0: return (double) 16.0; case 0x16EE: @@ -4760,6 +4793,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2498: case 0x24F1: case 0x16E91: + case 0x1D2D1: case 0x1D2F1: return (double) 17.0; case 0x0F32: @@ -4770,6 +4804,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2499: case 0x24F2: case 0x16E92: + case 0x1D2D2: case 0x1D2F2: return (double) 18.0; case 0x16F0: @@ -4778,6 +4813,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x249A: case 0x24F3: case 0x16E93: + case 0x1D2D3: case 0x1D2F3: return (double) 19.0; case 0x0032: @@ -4885,6 +4921,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5B: case 0x11D52: case 0x11DA2: + case 0x11F52: case 0x12400: case 0x12416: case 0x1241F: @@ -4900,6 +4937,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16B52: case 0x16E82: case 0x16E95: + case 0x1D2C2: case 0x1D2E2: case 0x1D361: case 0x1D373: @@ -4910,6 +4948,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7F8: case 0x1E142: case 0x1E2F2: + case 0x1E4F2: case 0x1E8C8: case 0x1E952: case 0x1EC72: @@ -5111,6 +5150,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5C: case 0x11D53: case 0x11DA3: + case 0x11F53: case 0x12401: case 0x12408: case 0x12417: @@ -5131,6 +5171,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16B53: case 0x16E83: case 0x16E96: + case 0x1D2C3: case 0x1D2E3: case 0x1D362: case 0x1D374: @@ -5141,6 +5182,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7F9: case 0x1E143: case 0x1E2F3: + case 0x1E4F3: case 0x1E8C9: case 0x1E953: case 0x1EC73: @@ -5334,6 +5376,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5D: case 0x11D54: case 0x11DA4: + case 0x11F54: case 0x12402: case 0x12409: case 0x1240F: @@ -5354,6 +5397,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC4: case 0x16B54: case 0x16E84: + case 0x1D2C4: case 0x1D2E4: case 0x1D363: case 0x1D375: @@ -5364,6 +5408,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FA: case 0x1E144: case 0x1E2F4: + case 0x1E4F4: case 0x1E8CA: case 0x1E954: case 0x1EC74: @@ -5533,6 +5578,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5E: case 0x11D55: case 0x11DA5: + case 0x11F55: case 0x12403: case 0x1240A: case 0x12410: @@ -5549,6 +5595,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC5: case 0x16B55: case 0x16E85: + case 0x1D2C5: case 0x1D2E5: case 0x1D364: case 0x1D376: @@ -5560,6 +5607,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FB: case 0x1E145: case 0x1E2F5: + case 0x1E4F5: case 0x1E8CB: case 0x1E955: case 0x1EC75: @@ -5729,6 +5777,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5F: case 0x11D56: case 0x11DA6: + case 0x11F56: case 0x12404: case 0x1240B: case 0x12411: @@ -5741,6 +5790,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC6: case 0x16B56: case 0x16E86: + case 0x1D2C6: case 0x1D2E6: case 0x1D365: case 0x1D7D4: @@ -5750,6 +5800,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FC: case 0x1E146: case 0x1E2F6: + case 0x1E4F6: case 0x1E8CC: case 0x1E956: case 0x1EC76: @@ -5878,6 +5929,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C60: case 0x11D57: case 0x11DA7: + case 0x11F57: case 0x12405: case 0x1240C: case 0x12412: @@ -5891,6 +5943,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC7: case 0x16B57: case 0x16E87: + case 0x1D2C7: case 0x1D2E7: case 0x1D366: case 0x1D7D5: @@ -5900,6 +5953,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FD: case 0x1E147: case 0x1E2F7: + case 0x1E4F7: case 0x1E8CD: case 0x1E957: case 0x1EC77: @@ -6029,6 +6083,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C61: case 0x11D58: case 0x11DA8: + case 0x11F58: case 0x12406: case 0x1240D: case 0x12413: @@ -6041,6 +6096,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC8: case 0x16B58: case 0x16E88: + case 0x1D2C8: case 0x1D2E8: case 0x1D367: case 0x1D7D6: @@ -6050,6 +6106,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FE: case 0x1E148: case 0x1E2F8: + case 0x1E4F8: case 0x1E8CE: case 0x1E958: case 0x1EC78: @@ -6174,6 +6231,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C62: case 0x11D59: case 0x11DA9: + case 0x11F59: case 0x12407: case 0x1240E: case 0x12414: @@ -6188,6 +6246,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC9: case 0x16B59: case 0x16E89: + case 0x1D2C9: case 0x1D2E9: case 0x1D368: case 0x1D7D7: @@ -6197,6 +6256,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FF: case 0x1E149: case 0x1E2F9: + case 0x1E4F9: case 0x1E8CF: case 0x1E959: case 0x1EC79: diff --git a/Objects/unionobject.c b/Objects/unionobject.c index 80c70389ab3..f273f7d15ef 100644 --- a/Objects/unionobject.c +++ b/Objects/unionobject.c @@ -48,73 +48,6 @@ union_hash(PyObject *self) return hash; } -static int -is_generic_alias_in_args(PyObject *args) -{ - Py_ssize_t nargs = PyTuple_GET_SIZE(args); - for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { - PyObject *arg = PyTuple_GET_ITEM(args, iarg); - if (_PyGenericAlias_Check(arg)) { - return 0; - } - } - return 1; -} - -static PyObject * -union_instancecheck(PyObject *self, PyObject *instance) -{ - unionobject *alias = (unionobject *) self; - Py_ssize_t nargs = PyTuple_GET_SIZE(alias->args); - if (!is_generic_alias_in_args(alias->args)) { - PyErr_SetString(PyExc_TypeError, - "isinstance() argument 2 cannot contain a parameterized generic"); - return NULL; - } - for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { - PyObject *arg = PyTuple_GET_ITEM(alias->args, iarg); - if (PyType_Check(arg)) { - int res = PyObject_IsInstance(instance, arg); - if (res < 0) { - return NULL; - } - if (res) { - Py_RETURN_TRUE; - } - } - } - Py_RETURN_FALSE; -} - -static PyObject * -union_subclasscheck(PyObject *self, PyObject *instance) -{ - if (!PyType_Check(instance)) { - PyErr_SetString(PyExc_TypeError, "issubclass() arg 1 must be a class"); - return NULL; - } - unionobject *alias = (unionobject *)self; - if (!is_generic_alias_in_args(alias->args)) { - PyErr_SetString(PyExc_TypeError, - "issubclass() argument 2 cannot contain a parameterized generic"); - return NULL; - } - Py_ssize_t nargs = PyTuple_GET_SIZE(alias->args); - for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { - PyObject *arg = PyTuple_GET_ITEM(alias->args, iarg); - if (PyType_Check(arg)) { - int res = PyObject_IsSubclass(instance, arg); - if (res < 0) { - return NULL; - } - if (res) { - Py_RETURN_TRUE; - } - } - } - Py_RETURN_FALSE; -} - static PyObject * union_richcompare(PyObject *a, PyObject *b, int op) { @@ -137,93 +70,78 @@ union_richcompare(PyObject *a, PyObject *b, int op) return result; } -static PyObject* -flatten_args(PyObject* args) +static int +is_same(PyObject *left, PyObject *right) { - Py_ssize_t arg_length = PyTuple_GET_SIZE(args); - Py_ssize_t total_args = 0; - // Get number of total args once it's flattened. - for (Py_ssize_t i = 0; i < arg_length; i++) { - PyObject *arg = PyTuple_GET_ITEM(args, i); - if (_PyUnion_Check(arg)) { - total_args += PyTuple_GET_SIZE(((unionobject*) arg)->args); - } else { - total_args++; - } - } - // Create new tuple of flattened args. - PyObject *flattened_args = PyTuple_New(total_args); - if (flattened_args == NULL) { - return NULL; - } - Py_ssize_t pos = 0; - for (Py_ssize_t i = 0; i < arg_length; i++) { - PyObject *arg = PyTuple_GET_ITEM(args, i); - if (_PyUnion_Check(arg)) { - PyObject* nested_args = ((unionobject*)arg)->args; - Py_ssize_t nested_arg_length = PyTuple_GET_SIZE(nested_args); - for (Py_ssize_t j = 0; j < nested_arg_length; j++) { - PyObject* nested_arg = PyTuple_GET_ITEM(nested_args, j); - Py_INCREF(nested_arg); - PyTuple_SET_ITEM(flattened_args, pos, nested_arg); - pos++; - } - } else { - if (arg == Py_None) { - arg = (PyObject *)&_PyNone_Type; - } - Py_INCREF(arg); - PyTuple_SET_ITEM(flattened_args, pos, arg); - pos++; - } - } - assert(pos == total_args); - return flattened_args; + int is_ga = _PyGenericAlias_Check(left) && _PyGenericAlias_Check(right); + return is_ga ? PyObject_RichCompareBool(left, right, Py_EQ) : left == right; } -static PyObject* -dedup_and_flatten_args(PyObject* args) +static int +contains(PyObject **items, Py_ssize_t size, PyObject *obj) { - args = flatten_args(args); - if (args == NULL) { - return NULL; + for (int i = 0; i < size; i++) { + int is_duplicate = is_same(items[i], obj); + if (is_duplicate) { // -1 or 1 + return is_duplicate; + } } - Py_ssize_t arg_length = PyTuple_GET_SIZE(args); - PyObject *new_args = PyTuple_New(arg_length); - if (new_args == NULL) { - Py_DECREF(args); - return NULL; - } - // Add unique elements to an array. - Py_ssize_t added_items = 0; - for (Py_ssize_t i = 0; i < arg_length; i++) { - int is_duplicate = 0; - PyObject* i_element = PyTuple_GET_ITEM(args, i); - for (Py_ssize_t j = 0; j < added_items; j++) { - PyObject* j_element = PyTuple_GET_ITEM(new_args, j); - int is_ga = _PyGenericAlias_Check(i_element) && - _PyGenericAlias_Check(j_element); - // RichCompare to also deduplicate GenericAlias types (slower) - is_duplicate = is_ga ? PyObject_RichCompareBool(i_element, j_element, Py_EQ) - : i_element == j_element; - // Should only happen if RichCompare fails - if (is_duplicate < 0) { - Py_DECREF(args); - Py_DECREF(new_args); + return 0; +} + +static PyObject * +merge(PyObject **items1, Py_ssize_t size1, + PyObject **items2, Py_ssize_t size2) +{ + PyObject *tuple = NULL; + Py_ssize_t pos = 0; + + for (int i = 0; i < size2; i++) { + PyObject *arg = items2[i]; + int is_duplicate = contains(items1, size1, arg); + if (is_duplicate < 0) { + Py_XDECREF(tuple); + return NULL; + } + if (is_duplicate) { + continue; + } + + if (tuple == NULL) { + tuple = PyTuple_New(size1 + size2 - i); + if (tuple == NULL) { return NULL; } - if (is_duplicate) - break; - } - if (!is_duplicate) { - Py_INCREF(i_element); - PyTuple_SET_ITEM(new_args, added_items, i_element); - added_items++; + for (; pos < size1; pos++) { + PyObject *a = items1[pos]; + PyTuple_SET_ITEM(tuple, pos, Py_NewRef(a)); + } } + PyTuple_SET_ITEM(tuple, pos, Py_NewRef(arg)); + pos++; + } + + if (tuple) { + (void) _PyTuple_Resize(&tuple, pos); + } + return tuple; +} + +static PyObject ** +get_types(PyObject **obj, Py_ssize_t *size) +{ + if (*obj == Py_None) { + *obj = (PyObject *)&_PyNone_Type; + } + if (_PyUnion_Check(*obj)) { + PyObject *args = ((unionobject *) *obj)->args; + *size = PyTuple_GET_SIZE(args); + return &PyTuple_GET_ITEM(args, 0); + } + else { + *size = 1; + return obj; } - Py_DECREF(args); - _PyTuple_Resize(&new_args, added_items); - return new_args; } static int @@ -242,9 +160,15 @@ _Py_union_type_or(PyObject* self, PyObject* other) Py_RETURN_NOTIMPLEMENTED; } - PyObject *tuple = PyTuple_Pack(2, self, other); + Py_ssize_t size1, size2; + PyObject **items1 = get_types(&self, &size1); + PyObject **items2 = get_types(&other, &size2); + PyObject *tuple = merge(items1, size1, items2, size2); if (tuple == NULL) { - return NULL; + if (PyErr_Occurred()) { + return NULL; + } + return Py_NewRef(self); } PyObject *new_union = make_union(tuple); @@ -255,10 +179,6 @@ _Py_union_type_or(PyObject* self, PyObject* other) static int union_repr_item(_PyUnicodeWriter *writer, PyObject *p) { - _Py_IDENTIFIER(__module__); - _Py_IDENTIFIER(__qualname__); - _Py_IDENTIFIER(__origin__); - _Py_IDENTIFIER(__args__); PyObject *qualname = NULL; PyObject *module = NULL; PyObject *tmp; @@ -269,13 +189,13 @@ union_repr_item(_PyUnicodeWriter *writer, PyObject *p) return _PyUnicodeWriter_WriteASCIIString(writer, "None", 4); } - if (_PyObject_LookupAttrId(p, &PyId___origin__, &tmp) < 0) { + if (_PyObject_LookupAttr(p, &_Py_ID(__origin__), &tmp) < 0) { goto exit; } if (tmp) { Py_DECREF(tmp); - if (_PyObject_LookupAttrId(p, &PyId___args__, &tmp) < 0) { + if (_PyObject_LookupAttr(p, &_Py_ID(__args__), &tmp) < 0) { goto exit; } if (tmp) { @@ -285,13 +205,13 @@ union_repr_item(_PyUnicodeWriter *writer, PyObject *p) } } - if (_PyObject_LookupAttrId(p, &PyId___qualname__, &qualname) < 0) { + if (_PyObject_LookupAttr(p, &_Py_ID(__qualname__), &qualname) < 0) { goto exit; } if (qualname == NULL) { goto use_repr; } - if (_PyObject_LookupAttrId(p, &PyId___module__, &module) < 0) { + if (_PyObject_LookupAttr(p, &_Py_ID(__module__), &module) < 0) { goto exit; } if (module == NULL || module == Py_None) { @@ -352,12 +272,6 @@ static PyMemberDef union_members[] = { {0} }; -static PyMethodDef union_methods[] = { - {"__instancecheck__", union_instancecheck, METH_O}, - {"__subclasscheck__", union_subclasscheck, METH_O}, - {0}}; - - static PyObject * union_getitem(PyObject *self, PyObject *item) { @@ -381,8 +295,7 @@ union_getitem(PyObject *self, PyObject *item) res = make_union(newargs); } else { - res = PyTuple_GET_ITEM(newargs, 0); - Py_INCREF(res); + res = Py_NewRef(PyTuple_GET_ITEM(newargs, 0)); for (Py_ssize_t iarg = 1; iarg < nargs; iarg++) { PyObject *arg = PyTuple_GET_ITEM(newargs, iarg); Py_SETREF(res, PyNumber_Or(res, arg)); @@ -409,8 +322,7 @@ union_parameters(PyObject *self, void *Py_UNUSED(unused)) return NULL; } } - Py_INCREF(alias->parameters); - return alias->parameters; + return Py_NewRef(alias->parameters); } static PyGetSetDef union_properties[] = { @@ -444,12 +356,19 @@ union_getattro(PyObject *self, PyObject *name) return PyObject_GenericGetAttr(self, name); } +PyObject * +_Py_union_args(PyObject *self) +{ + assert(_PyUnion_Check(self)); + return ((unionobject *) self)->args; +} + PyTypeObject _PyUnion_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) .tp_name = "types.UnionType", - .tp_doc = "Represent a PEP 604 union type\n" + .tp_doc = PyDoc_STR("Represent a PEP 604 union type\n" "\n" - "E.g. for int | str", + "E.g. for int | str"), .tp_basicsize = sizeof(unionobject), .tp_dealloc = unionobject_dealloc, .tp_alloc = PyType_GenericAlloc, @@ -459,7 +378,6 @@ PyTypeObject _PyUnion_Type = { .tp_hash = union_hash, .tp_getattro = union_getattro, .tp_members = union_members, - .tp_methods = union_methods, .tp_richcompare = union_richcompare, .tp_as_mapping = &union_as_mapping, .tp_as_number = &union_as_number, @@ -472,25 +390,13 @@ make_union(PyObject *args) { assert(PyTuple_CheckExact(args)); - args = dedup_and_flatten_args(args); - if (args == NULL) { - return NULL; - } - if (PyTuple_GET_SIZE(args) == 1) { - PyObject *result1 = PyTuple_GET_ITEM(args, 0); - Py_INCREF(result1); - Py_DECREF(args); - return result1; - } - unionobject *result = PyObject_GC_New(unionobject, &_PyUnion_Type); if (result == NULL) { - Py_DECREF(args); return NULL; } result->parameters = NULL; - result->args = args; + result->args = Py_NewRef(args); _PyObject_GC_TRACK(result); return (PyObject*)result; } diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index 89227689752..bd7720e2753 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -19,6 +19,7 @@ _PyWeakref_GetWeakrefCount(PyWeakReference *head) return count; } +static PyObject *weakref_vectorcall(PyWeakReference *self, PyObject *const *args, size_t nargsf, PyObject *kwnames); static void init_weakref(PyWeakReference *self, PyObject *ob, PyObject *callback) @@ -27,8 +28,8 @@ init_weakref(PyWeakReference *self, PyObject *ob, PyObject *callback) self->wr_object = ob; self->wr_prev = NULL; self->wr_next = NULL; - Py_XINCREF(callback); - self->wr_callback = callback; + self->wr_callback = Py_XNewRef(callback); + self->vectorcall = (vectorcallfunc)weakref_vectorcall; } static PyWeakReference * @@ -128,19 +129,19 @@ gc_clear(PyWeakReference *self) static PyObject * -weakref_call(PyWeakReference *self, PyObject *args, PyObject *kw) +weakref_vectorcall(PyWeakReference *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames) { - static char *kwlist[] = {NULL}; - - if (PyArg_ParseTupleAndKeywords(args, kw, ":__call__", kwlist)) { - PyObject *object = PyWeakref_GET_OBJECT(self); - Py_INCREF(object); - return (object); + if (!_PyArg_NoKwnames("weakref", kwnames)) { + return NULL; } - return NULL; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (!_PyArg_CheckPositional("weakref", nargs, 0, 0)) { + return NULL; + } + return Py_NewRef(PyWeakref_GET_OBJECT(self)); } - static Py_hash_t weakref_hash(PyWeakReference *self) { @@ -162,7 +163,6 @@ static PyObject * weakref_repr(PyWeakReference *self) { PyObject *name, *repr; - _Py_IDENTIFIER(__name__); PyObject* obj = PyWeakref_GET_OBJECT(self); if (obj == Py_None) { @@ -170,7 +170,7 @@ weakref_repr(PyWeakReference *self) } Py_INCREF(obj); - if (_PyObject_LookupAttrId(obj, &PyId___name__, &name) < 0) { + if (_PyObject_LookupAttr(obj, &_Py_ID(__name__), &name) < 0) { Py_DECREF(obj); return NULL; } @@ -298,7 +298,7 @@ weakref___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyWeakReference *ref, *proxy; PyWeakReference **list; - if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) { + if (!_PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) { PyErr_Format(PyExc_TypeError, "cannot create weak reference to '%s' object", Py_TYPE(ob)->tp_name); @@ -311,8 +311,7 @@ weakref___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (callback == NULL && type == &_PyWeakref_RefType) { if (ref != NULL) { /* We can re-use an existing reference. */ - Py_INCREF(ref); - return (PyObject *)ref; + return Py_NewRef(ref); } } /* We have to create a new reference. */ @@ -371,45 +370,24 @@ static PyMethodDef weakref_methods[] = { PyTypeObject _PyWeakref_RefType = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "weakref", - sizeof(PyWeakReference), - 0, - weakref_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - (reprfunc)weakref_repr, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - (hashfunc)weakref_hash, /*tp_hash*/ - (ternaryfunc)weakref_call, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC - | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - 0, /*tp_doc*/ - (traverseproc)gc_traverse, /*tp_traverse*/ - (inquiry)gc_clear, /*tp_clear*/ - (richcmpfunc)weakref_richcompare, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - weakref_methods, /*tp_methods*/ - weakref_members, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - weakref___init__, /*tp_init*/ - PyType_GenericAlloc, /*tp_alloc*/ - weakref___new__, /*tp_new*/ - PyObject_GC_Del, /*tp_free*/ + .tp_name = "weakref.ReferenceType", + .tp_basicsize = sizeof(PyWeakReference), + .tp_dealloc = weakref_dealloc, + .tp_vectorcall_offset = offsetof(PyWeakReference, vectorcall), + .tp_call = PyVectorcall_Call, + .tp_repr = (reprfunc)weakref_repr, + .tp_hash = (hashfunc)weakref_hash, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_BASETYPE, + .tp_traverse = (traverseproc)gc_traverse, + .tp_clear = (inquiry)gc_clear, + .tp_richcompare = (richcmpfunc)weakref_richcompare, + .tp_methods = weakref_methods, + .tp_members = weakref_members, + .tp_init = weakref___init__, + .tp_alloc = PyType_GenericAlloc, + .tp_new = weakref___new__, + .tp_free = PyObject_GC_Del, }; @@ -479,13 +457,12 @@ proxy_checkref(PyWeakReference *proxy) return res; \ } -#define WRAP_METHOD(method, special) \ +#define WRAP_METHOD(method, SPECIAL) \ static PyObject * \ method(PyObject *proxy, PyObject *Py_UNUSED(ignored)) { \ - _Py_IDENTIFIER(special); \ UNWRAP(proxy); \ Py_INCREF(proxy); \ - PyObject* res = _PyObject_CallMethodIdNoArgs(proxy, &PyId_##special); \ + PyObject* res = PyObject_CallMethodNoArgs(proxy, &_Py_ID(SPECIAL)); \ Py_DECREF(proxy); \ return res; \ } @@ -580,6 +557,7 @@ proxy_bool(PyWeakReference *proxy) static void proxy_dealloc(PyWeakReference *self) { + PyObject_GC_UnTrack(self); if (self->wr_callback != NULL) PyObject_GC_UnTrack((PyObject *)self); clear_weakref(self); @@ -741,7 +719,7 @@ static PyMappingMethods proxy_as_mapping = { PyTypeObject _PyWeakref_ProxyType = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "weakproxy", + "weakref.ProxyType", sizeof(PyWeakReference), 0, /* methods */ @@ -776,7 +754,7 @@ _PyWeakref_ProxyType = { PyTypeObject _PyWeakref_CallableProxyType = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "weakcallableproxy", + "weakref.CallableProxyType", sizeof(PyWeakReference), 0, /* methods */ @@ -814,7 +792,7 @@ PyWeakref_NewRef(PyObject *ob, PyObject *callback) PyWeakReference **list; PyWeakReference *ref, *proxy; - if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) { + if (!_PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) { PyErr_Format(PyExc_TypeError, "cannot create weak reference to '%s' object", Py_TYPE(ob)->tp_name); @@ -846,9 +824,7 @@ PyWeakref_NewRef(PyObject *ob, PyObject *callback) during GC. Return that one instead of this one to avoid violating the invariants of the list of weakrefs for ob. */ - Py_DECREF(result); - Py_INCREF(ref); - result = ref; + Py_SETREF(result, (PyWeakReference*)Py_NewRef(ref)); } } else { @@ -873,7 +849,7 @@ PyWeakref_NewProxy(PyObject *ob, PyObject *callback) PyWeakReference **list; PyWeakReference *ref, *proxy; - if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) { + if (!_PyType_SUPPORTS_WEAKREFS(Py_TYPE(ob))) { PyErr_Format(PyExc_TypeError, "cannot create weak reference to '%s' object", Py_TYPE(ob)->tp_name); @@ -911,9 +887,7 @@ PyWeakref_NewProxy(PyObject *ob, PyObject *callback) during GC. Return that one instead of this one to avoid violating the invariants of the list of weakrefs for ob. */ - Py_DECREF(result); - result = proxy; - Py_INCREF(result); + Py_SETREF(result, (PyWeakReference*)Py_NewRef(proxy)); goto skip_insert; } prev = ref; @@ -969,7 +943,7 @@ PyObject_ClearWeakRefs(PyObject *object) PyWeakReference **list; if (object == NULL - || !PyType_SUPPORTS_WEAKREFS(Py_TYPE(object)) + || !_PyType_SUPPORTS_WEAKREFS(Py_TYPE(object)) || Py_REFCNT(object) != 0) { PyErr_BadInternalCall(); @@ -1014,8 +988,7 @@ PyObject_ClearWeakRefs(PyObject *object) PyWeakReference *next = current->wr_next; if (Py_REFCNT((PyObject *)current) > 0) { - Py_INCREF(current); - PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current); + PyTuple_SET_ITEM(tuple, i * 2, Py_NewRef(current)); PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback); } else { @@ -1040,3 +1013,22 @@ PyObject_ClearWeakRefs(PyObject *object) PyErr_Restore(err_type, err_value, err_tb); } } + +/* This function is called by _PyStaticType_Dealloc() to clear weak references. + * + * This is called at the end of runtime finalization, so we can just + * wipe out the type's weaklist. We don't bother with callbacks + * or anything else. + */ +void +_PyStaticType_ClearWeakRefs(PyTypeObject *type) +{ + static_builtin_state *state = _PyStaticType_GetState(type); + PyObject **list = _PyStaticType_GET_WEAKREFS_LISTPTR(state); + while (*list != NULL) { + /* Note that clear_weakref() pops the first ref off the type's + weaklist before clearing its wr_object and wr_callback. + That is how we're able to loop over the list. */ + clear_weakref((PyWeakReference *)*list); + } +} diff --git a/PC/_msi.c b/PC/_msi.c index 01516e85ccf..b104e3c6ef5 100644 --- a/PC/_msi.c +++ b/PC/_msi.c @@ -172,9 +172,7 @@ static FNFCIGETTEMPFILE(cb_gettempfile) static FNFCISTATUS(cb_status) { if (pv) { - _Py_IDENTIFIER(status); - - PyObject *result = _PyObject_CallMethodId(pv, &PyId_status, "iii", typeStatus, cb1, cb2); + PyObject *result = PyObject_CallMethod(pv, "status", "iii", typeStatus, cb1, cb2); if (result == NULL) return -1; Py_DECREF(result); @@ -185,9 +183,7 @@ static FNFCISTATUS(cb_status) static FNFCIGETNEXTCABINET(cb_getnextcabinet) { if (pv) { - _Py_IDENTIFIER(getnextcabinet); - - PyObject *result = _PyObject_CallMethodId(pv, &PyId_getnextcabinet, "i", pccab->iCab); + PyObject *result = PyObject_CallMethod(pv, "getnextcabinet", "i", pccab->iCab); if (result == NULL) return -1; if (!PyBytes_Check(result)) { @@ -360,7 +356,7 @@ msierror(int status) int code; char buf[2000]; char *res = buf; - DWORD size = sizeof(buf); + DWORD size = Py_ARRAY_LENGTH(buf); MSIHANDLE err = MsiGetLastErrorRecord(); if (err == 0) { @@ -484,7 +480,7 @@ _msi_Record_GetString_impl(msiobj *self, unsigned int field) unsigned int status; WCHAR buf[2000]; WCHAR *res = buf; - DWORD size = sizeof(buf); + DWORD size = Py_ARRAY_LENGTH(buf); PyObject* string; status = MsiRecordGetStringW(self->h, field, res, &size); @@ -705,8 +701,7 @@ _msi_SummaryInformation_GetProperty_impl(msiobj *self, int field) result = PyBytes_FromStringAndSize(sval, ssize); break; case VT_EMPTY: - Py_INCREF(Py_None); - result = Py_None; + result = Py_NewRef(Py_None); break; default: PyErr_Format(PyExc_NotImplementedError, "result of type %d", type); @@ -757,19 +752,13 @@ _msi_SummaryInformation_SetProperty_impl(msiobj *self, int field, int status; if (PyUnicode_Check(data)) { -#if USE_UNICODE_WCHAR_CACHE - const WCHAR *value = _PyUnicode_AsUnicode(data); -#else /* USE_UNICODE_WCHAR_CACHE */ WCHAR *value = PyUnicode_AsWideCharString(data, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (value == NULL) { return NULL; } status = MsiSummaryInfoSetPropertyW(self->h, field, VT_LPSTR, 0, NULL, value); -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(value); -#endif /* USE_UNICODE_WCHAR_CACHE */ } else if (PyLong_CheckExact(data)) { long value = PyLong_AsLong(data); if (value == -1 && PyErr_Occurred()) { diff --git a/PC/_testconsole.c b/PC/_testconsole.c index db84f73c774..a8308835d8f 100644 --- a/PC/_testconsole.c +++ b/PC/_testconsole.c @@ -1,11 +1,15 @@ - /* Testing module for multi-phase initialization of extension modules (PEP 489) */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + #include "Python.h" #ifdef MS_WINDOWS +#include "pycore_fileutils.h" // _Py_get_osfhandle() #include "..\modules\_io\_iomodule.h" #define WIN32_LEAN_AND_MEAN diff --git a/PC/_wmimodule.cpp b/PC/_wmimodule.cpp new file mode 100644 index 00000000000..310aa86d94d --- /dev/null +++ b/PC/_wmimodule.cpp @@ -0,0 +1,323 @@ +// +// Helper library for querying WMI using its COM-based query API. +// +// Copyright (c) Microsoft Corporation +// Licensed to PSF under a contributor agreement +// + +// Version history +// 2022-08: Initial contribution (Steve Dower) + +#define _WIN32_DCOM +#include +#include +#include +#include + +#include + + +#if _MSVC_LANG >= 202002L +// We can use clinic directly when the C++ compiler supports C++20 +#include "clinic/_wmimodule.cpp.h" +#else +// Cannot use clinic because of missing C++20 support, so create a simpler +// API instead. This won't impact releases, so fine to omit the docstring. +static PyObject *_wmi_exec_query_impl(PyObject *module, PyObject *query); +#define _WMI_EXEC_QUERY_METHODDEF {"exec_query", _wmi_exec_query_impl, METH_O, NULL}, +#endif + + +/*[clinic input] +module _wmi +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7ca95dad1453d10d]*/ + + + +struct _query_data { + LPCWSTR query; + HANDLE writePipe; + HANDLE readPipe; +}; + + +static DWORD WINAPI +_query_thread(LPVOID param) +{ + IWbemLocator *locator = NULL; + IWbemServices *services = NULL; + IEnumWbemClassObject* enumerator = NULL; + BSTR bstrQuery = NULL; + struct _query_data *data = (struct _query_data*)param; + + HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + if (FAILED(hr)) { + CloseHandle(data->writePipe); + return (DWORD)hr; + } + + hr = CoInitializeSecurity( + NULL, -1, NULL, NULL, + RPC_C_AUTHN_LEVEL_DEFAULT, + RPC_C_IMP_LEVEL_IMPERSONATE, + NULL, EOAC_NONE, NULL + ); + // gh-96684: CoInitializeSecurity will fail if another part of the app has + // already called it. Hopefully they passed lenient enough settings that we + // can complete the WMI query, so keep going. + if (hr == RPC_E_TOO_LATE) { + hr = 0; + } + if (SUCCEEDED(hr)) { + hr = CoCreateInstance( + CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, + IID_IWbemLocator, (LPVOID *)&locator + ); + } + if (SUCCEEDED(hr)) { + hr = locator->ConnectServer( + bstr_t(L"ROOT\\CIMV2"), + NULL, NULL, 0, NULL, 0, 0, &services + ); + } + if (SUCCEEDED(hr)) { + hr = CoSetProxyBlanket( + services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, + RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, + NULL, EOAC_NONE + ); + } + if (SUCCEEDED(hr)) { + bstrQuery = SysAllocString(data->query); + if (!bstrQuery) { + hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); + } + } + if (SUCCEEDED(hr)) { + hr = services->ExecQuery( + bstr_t("WQL"), + bstrQuery, + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + NULL, + &enumerator + ); + } + + // Okay, after all that, at this stage we should have an enumerator + // to the query results and can start writing them to the pipe! + IWbemClassObject *value = NULL; + int startOfEnum = TRUE; + int endOfEnum = FALSE; + while (SUCCEEDED(hr) && !endOfEnum) { + ULONG got = 0; + DWORD written; + hr = enumerator->Next(WBEM_INFINITE, 1, &value, &got); + if (hr == WBEM_S_FALSE) { + // Could be at the end, but still got a result this time + endOfEnum = TRUE; + hr = 0; + break; + } + if (FAILED(hr) || got != 1 || !value) { + continue; + } + if (!startOfEnum && !WriteFile(data->writePipe, (LPVOID)L"\0", 2, &written, NULL)) { + hr = HRESULT_FROM_WIN32(GetLastError()); + break; + } + startOfEnum = FALSE; + // Okay, now we have each resulting object it's time to + // enumerate its members + hr = value->BeginEnumeration(0); + if (FAILED(hr)) { + value->Release(); + break; + } + while (SUCCEEDED(hr)) { + BSTR propName; + VARIANT propValue; + long flavor; + hr = value->Next(0, &propName, &propValue, NULL, &flavor); + if (hr == WBEM_S_NO_MORE_DATA) { + hr = 0; + break; + } + if (SUCCEEDED(hr) && (flavor & WBEM_FLAVOR_MASK_ORIGIN) != WBEM_FLAVOR_ORIGIN_SYSTEM) { + WCHAR propStr[8192]; + hr = VariantToString(propValue, propStr, sizeof(propStr) / sizeof(propStr[0])); + if (SUCCEEDED(hr)) { + DWORD cbStr1, cbStr2; + cbStr1 = (DWORD)(wcslen(propName) * sizeof(propName[0])); + cbStr2 = (DWORD)(wcslen(propStr) * sizeof(propStr[0])); + if (!WriteFile(data->writePipe, propName, cbStr1, &written, NULL) || + !WriteFile(data->writePipe, (LPVOID)L"=", 2, &written, NULL) || + !WriteFile(data->writePipe, propStr, cbStr2, &written, NULL) || + !WriteFile(data->writePipe, (LPVOID)L"\0", 2, &written, NULL) + ) { + hr = HRESULT_FROM_WIN32(GetLastError()); + } + } + VariantClear(&propValue); + SysFreeString(propName); + } + } + value->EndEnumeration(); + value->Release(); + } + + if (bstrQuery) { + SysFreeString(bstrQuery); + } + if (enumerator) { + enumerator->Release(); + } + if (services) { + services->Release(); + } + if (locator) { + locator->Release(); + } + CoUninitialize(); + CloseHandle(data->writePipe); + return (DWORD)hr; +} + + +/*[clinic input] +_wmi.exec_query + + query: unicode + +Runs a WMI query against the local machine. + +This returns a single string with 'name=value' pairs in a flat array separated +by null characters. +[clinic start generated code]*/ + +static PyObject * +_wmi_exec_query_impl(PyObject *module, PyObject *query) +/*[clinic end generated code: output=a62303d5bb5e003f input=48d2d0a1e1a7e3c2]*/ + +/*[clinic end generated code]*/ +{ + PyObject *result = NULL; + HANDLE hThread = NULL; + int err = 0; + WCHAR buffer[8192]; + DWORD offset = 0; + DWORD bytesRead; + struct _query_data data = {0}; + + if (PySys_Audit("_wmi.exec_query", "O", query) < 0) { + return NULL; + } + + data.query = PyUnicode_AsWideCharString(query, NULL); + if (!data.query) { + return NULL; + } + + if (0 != _wcsnicmp(data.query, L"select ", 7)) { + PyMem_Free((void *)data.query); + PyErr_SetString(PyExc_ValueError, "only SELECT queries are supported"); + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + + if (!CreatePipe(&data.readPipe, &data.writePipe, NULL, 0)) { + err = GetLastError(); + } else { + hThread = CreateThread(NULL, 0, _query_thread, (LPVOID*)&data, 0, NULL); + if (!hThread) { + err = GetLastError(); + // Normally the thread proc closes this handle, but since we never started + // we need to close it here. + CloseHandle(data.writePipe); + } + } + + while (!err) { + if (ReadFile( + data.readPipe, + (LPVOID)&buffer[offset / sizeof(buffer[0])], + sizeof(buffer) - offset, + &bytesRead, + NULL + )) { + offset += bytesRead; + if (offset >= sizeof(buffer)) { + err = ERROR_MORE_DATA; + } + } else { + err = GetLastError(); + } + } + + if (data.readPipe) { + CloseHandle(data.readPipe); + } + + // Allow the thread some time to clean up + switch (WaitForSingleObject(hThread, 1000)) { + case WAIT_OBJECT_0: + // Thread ended cleanly + if (!GetExitCodeThread(hThread, (LPDWORD)&err)) { + err = GetLastError(); + } + break; + case WAIT_TIMEOUT: + // Probably stuck - there's not much we can do, unfortunately + if (err == 0 || err == ERROR_BROKEN_PIPE) { + err = WAIT_TIMEOUT; + } + break; + default: + if (err == 0 || err == ERROR_BROKEN_PIPE) { + err = GetLastError(); + } + break; + } + + CloseHandle(hThread); + hThread = NULL; + + Py_END_ALLOW_THREADS + + PyMem_Free((void *)data.query); + + if (err == ERROR_MORE_DATA) { + PyErr_Format(PyExc_OSError, "Query returns more than %zd characters", Py_ARRAY_LENGTH(buffer)); + return NULL; + } else if (err) { + PyErr_SetFromWindowsErr(err); + return NULL; + } + + if (!offset) { + return PyUnicode_FromStringAndSize(NULL, 0); + } + return PyUnicode_FromWideChar(buffer, offset / sizeof(buffer[0]) - 1); +} + + +static PyMethodDef wmi_functions[] = { + _WMI_EXEC_QUERY_METHODDEF + { NULL, NULL, 0, NULL } +}; + +static PyModuleDef wmi_def = { + PyModuleDef_HEAD_INIT, + "_wmi", + NULL, // doc + 0, // m_size + wmi_functions +}; + +extern "C" { + PyMODINIT_FUNC PyInit__wmi(void) + { + return PyModuleDef_Init(&wmi_def); + } +} diff --git a/PC/classicAppCompat.can.xml b/PC/classicAppCompat.can.xml index f00475c8da3..df361f8e3e2 100644 --- a/PC/classicAppCompat.can.xml +++ b/PC/classicAppCompat.can.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/PC/classicAppCompat.sccd b/PC/classicAppCompat.sccd index 97648985a2c..d7a70cdd053 100644 --- a/PC/classicAppCompat.sccd +++ b/PC/classicAppCompat.sccd @@ -1,28 +1,41 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - MIIq5AYJKoZIhvcNAQcCoIIq1TCCKtECAQExDzANBglghkgBZQMEAgEFADCCARAGCSsGAQQBgjcKAaCCAQEwgf4wDAYKKwYBBAGCNwwBAQQQaM+L42jwBUGvBczrtolMmhcNMTgxMTMwMDA1OTAzWjAOBgorBgEEAYI3DAEDBQAwgbwwKgQUWKcU3R38DGPlKK33XGIwKtVL1r4xEjAQBgorBgEEAYI3DAIDMQKCADCBjQQg3K+KBOQX7HfxjRNZC9cx8gIPkEhPRO1nJFRdWQrVEJ4xaTAQBgorBgEEAYI3DAIDMQKCADBVBgorBgEEAYI3AgEEMUcwRTAQBgorBgEEAYI3AgEZogKAADAxMA0GCWCGSAFlAwQCAQUABCDcr4oE5Bfsd/GNE1kL1zHyAg+QSE9E7WckVF1ZCtUQnqCCFFAwggZSMIIEOqADAgECAhMzAAMu49KhfNamygpWAAIAAy7jMA0GCSqGSIb3DQEBCwUAMIGMMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMQ0wCwYDVQQLEwRNT1BSMScwJQYDVQQDEx5NaWNyb3NvZnQgTWFya2V0cGxhY2UgQ0EgRyAwMTMwHhcNMTgxMTMwMDA1NTA1WhcNMTgxMjAzMDA1NTA1WjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwpcimfAx3HEpba1GLL/gDaRVddHE5PXTRmwlgaz8kt6/rq5rlrPFnCnbIc5818v0xJIznastbmrq26xyCEHyMLBKnyneTKE36I7+TGjcY0D7ow+o2vY7LDKMCTGlh31fx1Tvrl+5xTbWX5jdLU/3MB5faeOGh+0Knzwx1KDoXWgPtfXnD8I5jxJieoWoCwCjKTJgBOklLy9nbOalxf0h+xQRy2p5fj+PxAwQPgHWft36AF7/IMbt9FcXMtg4xdpnTYz4OV3dFOPz4m3M8HwVgNMv89W/1Ozc7uOyZt0Ij1baT6r2L3IjYg5ftzpGqaDOFcWlyDFSdhMR6BIKW8xEpAgMBAAGjggHCMIIBvjAYBgNVHSUBAf8EDjAMBgorBgEEAYI3TBwBMB0GA1UdDgQWBBRdpGYiCytx83FYzPSl+o97YzpxGzAPBgNVHREECDAGggRNT1BSMB8GA1UdIwQYMBaAFEnYB1RFhpclHtZZcRLDcpt0OE3oMGIGA1UdHwRbMFkwV6BVoFOGUWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyME1hcmtldHBsYWNlJTIwQ0ElMjBHJTIwMDEzKDIpLmNybDBvBggrBgEFBQcBAQRjMGEwXwYIKwYBBQUHMAKGU2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwTWFya2V0cGxhY2UlMjBDQSUyMEclMjAwMTMoMikuY3J0MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMDwGCSsGAQQBgjcVBwQvMC0GJSsGAQQBgjcVCIOS9kTqrxCDkY0wgqzgLIKinDE0g+6NOIaE7wACAWQCARYwIAYJKwYBBAGCNxUKAQH/BBAwDjAMBgorBgEEAYI3TBwBMA0GCSqGSIb3DQEBCwUAA4ICAQB3Dk3rXH52CDq/z1fwqn9xI5WGjGmu6oAE4HSc3sNdFrSVMMGm4gTlYGWSZ0wJUUf16mVr/rdXhxuR3MZn+m4Bhdl8KQqYjYbIvCUVj0o9nZ+yT6foeY8bKnB+K5h6rol+mjDj5IfcutC4x2Kx5RrtDtRTSoKA63iZ74DYngPpBGBBgaS2c/QzgqPRAMMRqy2KBDP0miCnpR3F4YlzHGyOZwyHhESjYd9kwF47+msuHS04JZpnGHIvBppKN9XQzH3WezNnnX3lz4AyAUMsMFuARqEnacUhrAHL9n5zMv9CzxDYN1r1/aDh/788RuGuZM+E3NtmbxJJ7j6T5/VtXNBRgKtIq8d2+11j6qvKLigOTxSC25/A70BZBEvllLFnvc1vA2LrC9drwt1KpSmWie1nvpilw7o+gHMOG9utUxGha2VuVizuVNGCywTRRjvmGS1QqTfaun1URVrLfnDINXuTgN1Vwp0J5IGpJ3D8yj01NDQ/RworE+3W/R531NBYova9QRhU/igEw/Aa/q8wjZ4Pzxr9oBIo0Ta3Tv6qIggaWXw0U9+F0J7SCqIhn0d0ATO+E1Qs/SxZIAICLwmqzoLYUAh8q153esBs4uesueqgt5ueyHK8V3WjMS4wxEyVN5ZMET3hFtEshsZC31tLDdjq750U4SgQVmoYSm3F3ZOKQDCCBtcwggS/oAMCAQICCmESRKIAAAAAAAIwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDExMB4XDTExMDMyODIxMDkzOVoXDTMxMDMyODIxMTkzOVowfTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEnMCUGA1UEAxMeTWljcm9zb2Z0IE1hcmtldFBsYWNlIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAubUaSwGYVsE3MAnPfvmozUhAB3qxBABgJRW1vDp4+tVinXxD32f7k1K89JQ6zDOgS/iDgULC+yFK1K/1Qjac/0M7P6c8v5LSjnWGlERLa/qY32j46S7SLQcit3g2jgoTTO03eUG+9yHZUTGV/FJdRYB8uXhrznJBa+Y+yGwiQKF+m6XFeBH/KORoKFx+dmMoy9EWJ/m/o9IiUj2kzm9C691+vZ/I2w0Bj93W9SPPkV2PCNHlzgfIAoeajWpHmi38Wi3xZHonkzAVBHxPsCBppOoNsWvmAfUM7eBthkSPvFruekyDCPNEYhfGqgqtqLkoBebXLZCOVybF7wTQaLvse60//3P003icRcCoQYgY4NAqrF7j80o5U7DkeXxcB0xvengsaKgiAaV1DKkRbpe98wCqr1AASvm5rAJUYMU+mXmOieV2EelY2jGrenWe9FQpNXYV1NoWBh0WKoFxttoWYAnF705bIWtSZsz08ZfK6WLX4GXNLcPBlgCzfTm1sdKYASWdBbH2haaNhPapFhQQBJHKwnVW2iXErImhuPi45W3MVTZ5D9ASshZx69cLYY6xAdIa+89Kf/uRrsGOVZfahDuDw+NI183iAyzC8z/QRt2P32LYxP0xrCdqVh+DJo2i4NoE8Uk1usCdbVRuBMBQl/AwpOTq7IMvHGElf65CqzUCAwEAAaOCAUswggFHMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBQPU8s/FmEl/mCJHdO5fOiQrbOU0TAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCjuZmM8ZVNDgp9wHsL4RY8KJ8nLinvxFTphNGCrxaLknkYG5pmMhVlX+UB/tSiW8W13W60nggz9u5xwMx7v/1t/Tgm6g2brVyOKI5A7u6/2SIJwkJKFw953K0YIKVT28w9zl8dSJnmRnyR0G86ncWbF6CLQ6A6lBQ9o2mTGVqDr4m35WKAnc6YxUUM1y74mbzFFZr63VHsCcOp3pXWnUqAY1rb6Q6NX1b3clncKqLFm0EjKHcQ56grTbwuuB7pMdh/IFCJR01MQzQbDtpEisbOeZUi43YVAAHKqI1EO9bRwg3frCjwAbml9MmI4utMW94gWFgvrMxIX+n42RBDIjf3Ot3jkT6gt3XeTTmO9bptgblZimhERdkFRUFpVtkocJeLoGuuzP93uH/Yp032wzRH+XmMgujfZv+vnfllJqxdowoQLx55FxLLeTeYfwi/xMSjZO2gNven3U/3KeSCd1kUOFS3AOrwZ0UNOXJeW5JQC6Vfd1BavFZ6FAta1fMLu3WFvNB+FqeHUaU3ya7rmtxJnzk29DeSqXgGNmVSywBS4NajI5jJIKAA6UhNJlsg8CHYwUOKf5ej8OoQCkbadUxXygAfxCfW2YBbujtI+PoyejRFxWUjYFWO5LeTI62UMyqfOEiqugoYjNxmQZla2s4YHVuqIC34R85FQlg9pKQBsDCCBxswggUDoAMCAQICEzMAAABCs21EHGjyqKYAAAAAAEIwDQYJKoZIhvcNAQELBQAwfTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEnMCUGA1UEAxMeTWljcm9zb2Z0IE1hcmtldFBsYWNlIFBDQSAyMDExMB4XDTE4MDQyMDE2NDI0NFoXDTIxMDQyMDE2NDI0NFowgYwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xDTALBgNVBAsTBE1PUFIxJzAlBgNVBAMTHk1pY3Jvc29mdCBNYXJrZXRwbGFjZSBDQSBHIDAxMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOZ2KM9Pq1YCOiqWOivmHjUtkMgznTMP/Mr2YfzZeIIJySg1F4WxFZc4jagGHHNof9NRT+GGnktWsXkZuH1DzQEG4Ps1ln8+4vhbDglqu5ymDnd6RmsyoD+8xfc8bBIvE5o6R+ES4/GVD5TqNsOrWbwETaIZVbmTulJLoTS1WSsSjowmbc+sHqZiY8BNJNThUEmXSjuHqkQKKshuiFWYEqOTitp71mBLyH1wN7/jThRzGpolOeFusRNJdb8sEqvNzEN9Qh+Kp6ndzrnjE+t8ixXW3lShyyOOZqQMwsQn9q9T0v7Q69GuojBTFBOHKwigcCHr4xahuN+ZYMk0xGg+sm3Uj7I9mrWTSTiIRMZNIWq3sFg4+rFg48NYfRlXUpONmL7vXq6v1pIU99d2MXQ6uUrnUr1/n5ZiHGCeFcvWwqO8BYHdcTlrSOkayfFp7W9oCk9QO4Xy0h9cQRedRo2kvdTHxIuJS70Hdv6oePPF2ZFaLucUzzwsR4/XMAVKY8Vsm950omsSSOImsMtzavUdQM+wZFxvHTRqVDkF3quPdME0bCZOWB4hQJmd+o2clw+1mpwPu0/M92nA9FJg7MGPxkFaYW7g26jSqUJZ9AcX+Xa5TSIeqMZt3cRVjMTx0T/v73Sv8TpalqIQ5Fde1+hFK07sOAm3TwgzvlVJnbYgp0/rAgMBAAGjggGCMIIBfjASBgkrBgEEAYI3FQEEBQIDAgACMCMGCSsGAQQBgjcVAgQWBBSbJnDhuc3nQXuKuACsPflEbwjbozAdBgNVHQ4EFgQUSdgHVEWGlyUe1llxEsNym3Q4TegwEQYDVR0gBAowCDAGBgRVHSAAMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMB8GA1UdIwQYMBaAFA9Tyz8WYSX+YIkd07l86JCts5TRMFcGA1UdHwRQME4wTKBKoEiGRmh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY01hclBDQTIwMTFfMjAxMS0wMy0yOC5jcmwwWwYIKwYBBQUHAQEETzBNMEsGCCsGAQUFBzAChj9odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY01hclBDQTIwMTFfMjAxMS0wMy0yOC5jcnQwDQYJKoZIhvcNAQELBQADggIBAIa2oa6kvuIHCNfz7anlL0W9tOCt8gQNkxOGRK3yliQIelNQahDJojyEFlHQ2BcHL5oZit3WeSDoYddhojx6YzJIWwfGwtVqgc0JFDKJJ2ZXRYMRsuy01Hn25xob+zRMS6VmV1axQn6uwOSMcgYmzoroh6edjPKu7qXcpt6LmhF2qFvLySA7wBCwfI/rR5/PX6I7a07Av7PpbY6/+2ujd8m1H3hwMrb4Hq3z6gcq62zJ3nDXUbC0Bp6Jt2kV9f0rEFpDK9oxE2qrGBUf8c3O2XirHOgAjRyWjWWtVms+MP8qBIA1NSLrBmToEWVP3sEkQZWMkoZWo4rYEJZpX7UIgdDc9zYNakgTCJqPhqn8AE1sgSSnpqAdMkkP41rTlFCv2ig2QVzDerjGfEv+uPDnlAT0kucbBJxHHvUC4aqUxaTSa0sy2bZ6NWFx8/u0gW8JahzxYvvvZL8SfwaA9P4ETb8pH1jw+6N/LfM2zJrNKhf5hjKa0VDOXUpkYq60OqVVnWJ6oJaSIWNkZKfzPnl/UHA8Bh4qfVrhc9H5PExPhhB9WVTsjf4r+OOVuolJldThcWQqljiPjk5rultr63G5xLyFpxNi4BCrcNQBJFB5wKgOWOyjQTVWTmh2ESaeqZ2aWBjftFHlxJ/qYc7WOGJV0+cHGkB/dvFxmKnv6tuWexiMMYIVUTCCFU0CAQEwgaQwgYwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xDTALBgNVBAsTBE1PUFIxJzAlBgNVBAMTHk1pY3Jvc29mdCBNYXJrZXRwbGFjZSBDQSBHIDAxMwITMwADLuPSoXzWpsoKVgACAAMu4zANBglghkgBZQMEAgEFAKCBlTAYBgkqhkiG9w0BCQMxCwYJKwYBBAGCNwoBMC8GCSqGSIb3DQEJBDEiBCAS0d3bw2YOODvKFr0S4e3BDnaDcZXUKeBO77yvkWzVojBIBgorBgEEAYI3AgEMMTowOKAegBwATQBpAGMAcgBvAHMAbwBmAHQAIABDAG8AcgBwoRaAFGh0dHA6Ly9NaWNyb3NvZnQuY29tMA0GCSqGSIb3DQEBAQUABIIBABoap3Y+2k+zFz2cCmkc8xxHnpIygLsUSRMXeXdjPVcYx3o5cPLIixnL6p8+LIrlIagPg23mzTEmnjZaO4aaexk+3XojlHj22w/bEigEDnKyWt5bHeS0UNHJbxEFYRfd84IP1+mSH4c4+GuU9p3LsAMh6wN03MYrGmczUOnlP6YlxHNQbQxnV0sl14yOE5ni9oT4y+l+SllvbV3/Jhwpov68aoP/2MazqxR4QyGfSxhCPJ4UuDHU7IrpnTxGBTL1/oUU8ED0FxyDoH/Sc5OhTLInFqbZaVzm5Mpr12wYUBL4nE5h0Kf6BCKdgM8a+Ti3wMUsBoC79ff3jE9U/xwSneOhghLlMIIS4QYKKwYBBAGCNwMDATGCEtEwghLNBgkqhkiG9w0BBwKgghK+MIISugIBAzEPMA0GCWCGSAFlAwQCAQUAMIIBUQYLKoZIhvcNAQkQAQSgggFABIIBPDCCATgCAQEGCisGAQQBhFkKAwEwMTANBglghkgBZQMEAgEFAAQghPy22lwuCYESw8jYhb4F9ZDPJ1LPgSSZgJDkyXYzVt4CBlv98KtAoBgTMjAxODExMzAwMTA1MTkuMTM4WjAEgAIB9KCB0KSBzTCByjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046RDA4Mi00QkZELUVFQkExJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIHNlcnZpY2Wggg48MIIE8TCCA9mgAwIBAgITMwAAAOIYOHtm6erB2AAAAAAA4jANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAeFw0xODA4MjMyMDI3MDNaFw0xOTExMjMyMDI3MDNaMIHKMQswCQYDVQQGEwJVUzELMAkGA1UECBMCV0ExEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpEMDgyLTRCRkQtRUVCQTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgc2VydmljZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKirA72FF3NCLW5mfLO/D0EZ5Ycs00oiMSissXLB6WF9GNdP78QzFwAypxW/+qZSczqaHbDH8hlbxkzf3DiYgAdpQjnGkLujwKtWSaP29/lVf7jFqHy9v6eH+LdOi0LvtrPRW34MyCvpxZyOW4H1h3PkxCBL5Ra21sDqgcVL1me0osw8QTURXmI4LyeLdTH3CcI2AgNDXTjsFBf3QsO+JYyAOYWrTcLnywVN6DrigmgrDJk5w+wR4VrHfl2T9PRZbZ+UDt13wwyB9d6IURuzV8lHsAVfF8t9S0aGVPmkQ3c2waOhHpsp6VEM+T5D2Ph8xJX1r82z67WRlmGcOP2NWC0CAwEAAaOCARswggEXMB0GA1UdDgQWBBSJPpD6BsP2p+crDJL232voEtLxezAfBgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNUaW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQARQHu7ISeBuJSHKuDRI04704cH0B7BYzeEIrD15awviMRcYIfIOHpvGzZOWQgP2Hm0Rr7kvTUu1VrSSaQ7i1gPWdhqMmw5WBnSS5bxeMhhx9UsASeE84vUu82NeZapGSjH38YAb4WT+TtiTkcoI59rA+CTCq108ttIxVfZcr3id76OETIH0HvhlnxOOWjwGy4ul6Za5RoTLG/oo2rrGmVi3FwrNWGezYLBODuEsjzG36lCRtBKC2ZAHfbOz5wtkUHbqh79mUKocjP4r3qxf5TN87yf6g1uTx+J8pdnAi5iHt+ZtangWqnVTE8PoIREWhBVlGFfQdkELUx2Or90aAqWMIIGcTCCBFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcNMjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEwRA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQedGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKxXf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4GkbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEAAaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0gAQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOhIW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS+7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlKkVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon/VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOiPPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCIIYdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7aKLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQcdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+NR4Iuto229Nfj950iEkSoYICzjCCAjcCAQEwgfihgdCkgc0wgcoxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJXQTEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOkQwODItNEJGRC1FRUJBMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBzZXJ2aWNloiMKAQEwBwYFKw4DAhoDFQByQCUheEOevaI9Zc/3QGrkX42iC6CBgzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBBQUAAgUA36ppYDAiGA8yMDE4MTEyOTIxMzQyNFoYDzIwMTgxMTMwMjEzNDI0WjB3MD0GCisGAQQBhFkKBAExLzAtMAoCBQDfqmlgAgEAMAoCAQACAitfAgH/MAcCAQACAhGtMAoCBQDfq7rgAgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQEFBQADgYEAbAXXPR9wy4NA0892GGqetaZF+pNClpGcfEpSuHABaZ4Gzr1nY1nmrhexTtr/U6omHALRWzkQwthk0cy+mnEHXyOZGmoEEpgrLgK3AAP5NbK/XbtHQRyZJQyhZScFbOyQycoE8QQalSVOhWxk/bbBMQaQiYVMIexNd/T0KgaDDUMxggMNMIIDCQIBATCBkzB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAOIYOHtm6erB2AAAAAAA4jANBglghkgBZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJBDEiBCCr9IiSbx6s8MLdxldRG49+4h6CbicW8hWXAicI3jNmhDCB+gYLKoZIhvcNAQkQAi8xgeowgecwgeQwgb0EIN8BpJSmQCGubWwVa4tW+aMveoHMX/nDnVN8fiDOMsrLMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAADiGDh7ZunqwdgAAAAAAOIwIgQgTkOfRvGEZNbr5/hgWclsL4/Q7SOZihE/U0lz2wEMIGcwDQYJKoZIhvcNAQELBQAEggEATlxnCfTzFfTMDvK085zlYPVCroKYW6gKFYnbAhNmrNzcxqALKmIYXpFU7B6HH/vYzkUfCyXpf5tsyEWu0oTySOjyAZ9+2vdaG8nEgjOp0L737lcitgusIjpWtta3Ik0b+mzffnvyjrgTSuKDDni3mxGfvJU77k1Ctempma4H2FJso6Bur0PRH99vIYDu4lHigOSLbeyjR5CiDciBwEVUSA0FxhoFNX1yfpxz3sukOvkaoTduREIjH5LxUjNI1ZTMK/ZkeETI8IPRpWVzAc8q7CujErHKo4sdKej/O2cfUTUHplFLVCGGExpJUCg5FH5jVUUFt75ad8503sdGplggVQ== + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MIIucgYJKoZIhvcNAQcCoIIuYzCCLl8CAQExDzANBglghkgBZQMEAgEFADCCARAGCSsGAQQBgjcKAaCCAQEwgf4wDAYKKwYBBAGCNwwBAQQQ293slyDTMUOmVyeQqmcNSBcNMjIwMjA0MDkwNjU2WjAOBgorBgEEAYI3DAEDBQAwgbwwKgQUdgFpbn9QXi/ly4CZFKA2Eimoq6YxEjAQBgorBgEEAYI3DAIDMQKCADCBjQQg3YHMbvV3unL0mx/RJ8ihTJd1C/SYSnMHbN0yMrWijuQxaTAQBgorBgEEAYI3DAIDMQKCADBVBgorBgEEAYI3AgEEMUcwRTAQBgorBgEEAYI3AgEZogKAADAxMA0GCWCGSAFlAwQCAQUABCDdgcxu9Xe6cvSbH9EnyKFMl3UL9JhKcwds3TIytaKO5KCCE8owggYEMIID7KADAgECAhMzAA/d9uEraWrDsxZGAAAAD932MA0GCSqGSIb3DQEBCwUAMIGLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMQwwCgYDVQQLEwNBT0MxJzAlBgNVBAMTHk1pY3Jvc29mdCBNYXJrZXRwbGFjZSBDQSBHIDAyMjAeFw0yMjAyMDQwODU5MzZaFw0yMjAyMDcwODU5MzZaMC8xLTArBgNVBAMTJDQ2ZTIwYzY2LTUxNTEtNDNhOS05MWQ4LTMwNDY0ZGZhMDg4ZjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALaMR5Ajlp2POidTxT0N47z5sukiE9fqMuI1QimTXIfB2/gPdMsNUbVCD57ha8J1DUJQpO5nuunbk3SONwfDTdWKx9u7zWubpEmgG7hZ8LTKFlF+xhS6lS/FBSSHyXpdScWPg62BMnDysqHMH/AjLw26HNPRWK8A0vx9jsalFwLg15u4MPuKN3Bpawr/OL0B+7eh/dGO3PutAqJ4aZs2lUCIyODg0q3Tzhgi7SIvFacFWJ8Qj6+D3AfasOv8oanfpNLLPhPlxXGEK9sMKHOOb8mTU9V/ibERqEKTHkJ24Vu+BwrXq5eVedtwmHT2WWR7teaIvrUT9AiPmMhx4hIF/0MCAwEAAaOCAbowggG2MBgGA1UdJQEB/wQOMAwGCisGAQQBgjdMHAEwHQYDVR0OBBYEFB4NpkpeSLk/j691tPw97rB4XKDJMA0GA1UdEQQGMASCAlVTMB8GA1UdIwQYMBaAFPeC7EkBPjJR1eFAcP4hAMeQ72IPMF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyME1hcmtldHBsYWNlJTIwQ0ElMjBHJTIwMDIyLmNybDBsBggrBgEFBQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwTWFya2V0cGxhY2UlMjBDQSUyMEclMjAwMjIuY3J0MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMDwGCSsGAQQBgjcVBwQvMC0GJSsGAQQBgjcVCIOS9kTqrxCDkY0wgqzgLIKinDE0g+6NOIaE7wACAWQCARcwIAYJKwYBBAGCNxUKAQH/BBAwDjAMBgorBgEEAYI3TBwBMA0GCSqGSIb3DQEBCwUAA4ICAQBAiJuIJeMS+PMrxG+kwPWT7yy7A6P8trchwtXyYep/WXu7xT2tH2ys3wuP4DYG5CY4nKekjTKraQhZGuYj4r4KrUviShe8ZWMIcK4MRduXAU81UOd/fsCq5djQ6NDN4Bzq1TxjwZKiEMEWmXaunj6XAlDSX3SgyyMb/ywmur8VVKO+xFVkOxAqCjNo1VaCv3zEvr3Y6dUwO9gYQui1bAQVQzdxRYUPEJlsFBmbNL1AnZ39r4/9K/6orxavU4qwkj4cXnhtMYKDjTIIbTBrfD4glP6mnmkcZpN0ItfEAVgU9rGpXg84hQLeP83nBs2Y8DrF3bBF9867dJCl90c5rK1DMcelmH3oUAwqZ3U+jIIj3HGyfefAQ6HPL0yiY9OYLXQZUxcZF13m92l5s7dy2C21cIh0W0iTcWPIhNn9cia4Hr7FabTC0RoQkO1bg0PKvPMnoe0AqEVmPKImNDncg538AjPy2qeUxn7+0kcuZWEdKVAPwWfzh5qvSAmYKk4XNBfN2E40GQ0ruRdvMVMFeYBLXKm4SJR6zoiBa5v7qzt1uQqZf6GD4BNFZivBp0P2B9lTubEAU6SmUsazRnEVmekIO+x7gDuXbMS8tv6mb1pbGCtIV/wRcIYNcDkHKTHMbW5xR/OmGTM3mPRxoMQtaWtxIeagZkU2nl+pElA/0h7pIjCCBtcwggS/oAMCAQICCmESRKIAAAAAAAIwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDExMB4XDTExMDMyODIxMDkzOVoXDTMxMDMyODIxMTkzOVowfTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEnMCUGA1UEAxMeTWljcm9zb2Z0IE1hcmtldFBsYWNlIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAubUaSwGYVsE3MAnPfvmozUhAB3qxBABgJRW1vDp4+tVinXxD32f7k1K89JQ6zDOgS/iDgULC+yFK1K/1Qjac/0M7P6c8v5LSjnWGlERLa/qY32j46S7SLQcit3g2jgoTTO03eUG+9yHZUTGV/FJdRYB8uXhrznJBa+Y+yGwiQKF+m6XFeBH/KORoKFx+dmMoy9EWJ/m/o9IiUj2kzm9C691+vZ/I2w0Bj93W9SPPkV2PCNHlzgfIAoeajWpHmi38Wi3xZHonkzAVBHxPsCBppOoNsWvmAfUM7eBthkSPvFruekyDCPNEYhfGqgqtqLkoBebXLZCOVybF7wTQaLvse60//3P003icRcCoQYgY4NAqrF7j80o5U7DkeXxcB0xvengsaKgiAaV1DKkRbpe98wCqr1AASvm5rAJUYMU+mXmOieV2EelY2jGrenWe9FQpNXYV1NoWBh0WKoFxttoWYAnF705bIWtSZsz08ZfK6WLX4GXNLcPBlgCzfTm1sdKYASWdBbH2haaNhPapFhQQBJHKwnVW2iXErImhuPi45W3MVTZ5D9ASshZx69cLYY6xAdIa+89Kf/uRrsGOVZfahDuDw+NI183iAyzC8z/QRt2P32LYxP0xrCdqVh+DJo2i4NoE8Uk1usCdbVRuBMBQl/AwpOTq7IMvHGElf65CqzUCAwEAAaOCAUswggFHMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBQPU8s/FmEl/mCJHdO5fOiQrbOU0TAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCjuZmM8ZVNDgp9wHsL4RY8KJ8nLinvxFTphNGCrxaLknkYG5pmMhVlX+UB/tSiW8W13W60nggz9u5xwMx7v/1t/Tgm6g2brVyOKI5A7u6/2SIJwkJKFw953K0YIKVT28w9zl8dSJnmRnyR0G86ncWbF6CLQ6A6lBQ9o2mTGVqDr4m35WKAnc6YxUUM1y74mbzFFZr63VHsCcOp3pXWnUqAY1rb6Q6NX1b3clncKqLFm0EjKHcQ56grTbwuuB7pMdh/IFCJR01MQzQbDtpEisbOeZUi43YVAAHKqI1EO9bRwg3frCjwAbml9MmI4utMW94gWFgvrMxIX+n42RBDIjf3Ot3jkT6gt3XeTTmO9bptgblZimhERdkFRUFpVtkocJeLoGuuzP93uH/Yp032wzRH+XmMgujfZv+vnfllJqxdowoQLx55FxLLeTeYfwi/xMSjZO2gNven3U/3KeSCd1kUOFS3AOrwZ0UNOXJeW5JQC6Vfd1BavFZ6FAta1fMLu3WFvNB+FqeHUaU3ya7rmtxJnzk29DeSqXgGNmVSywBS4NajI5jJIKAA6UhNJlsg8CHYwUOKf5ej8OoQCkbadUxXygAfxCfW2YBbujtI+PoyejRFxWUjYFWO5LeTI62UMyqfOEiqugoYjNxmQZla2s4YHVuqIC34R85FQlg9pKQBsDCCBuMwggTLoAMCAQICEzMAAABLZz0Eed1JFCkAAAAAAEswDQYJKoZIhvcNAQELBQAwfTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEnMCUGA1UEAxMeTWljcm9zb2Z0IE1hcmtldFBsYWNlIFBDQSAyMDExMB4XDTE5MDQxODIwNDUwNFoXDTI0MDQxODIwNDUwNFowgYsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xDDAKBgNVBAsTA0FPQzEnMCUGA1UEAxMeTWljcm9zb2Z0IE1hcmtldHBsYWNlIENBIEcgMDIyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzGfV5tDxZ3oPG8aq2OwrBLSRFC61lYvWtkqOdKswlBHVncuoOIzekLIFNsMwluoK0plNZ5w/JPmwkGTGIrt9ftbWQz0k7XRfacXvQQfhCaBgjkybvvDx7CTL0UDEUiXfEEkylUcQKOdm9LApPDP4oO/V8RS4ugkqkjsuVaOyfYv0TytjVVQon72W+wR/AyrBAXgfwzzEb85403GTJRzQMlTw1YqdgS/o9SCsvH9dRZTGlWCatIl+a00eTG5zgeu0xCtqwgERhw9UT6mlPqmp6RqJ8XMgKylh9Ss+jI53EmraAFlelph16kuqF6n3vNnRBfhQ+gmNdtKi9s3jI8Di7ip8hYGPHGGhtcw0AYUg5r/VQhIfXxO45zO7SFvjujX0ji0b3WKB/xD9Sg1KO1fiTpj82ifyPqHvL+iwn5dV98C4ru0dQ0hfK7tA4K5qkW+2gym0fBjGYWq81/smrj6LbPdNqCotgTMU4dCMBhmSJOD9fSiPUybrbHJrHGR5YNs5VJbHH5u1ia8UrgsSrGTb1bh38Tb10matJpBI7NwDWTkV7kMvgNRQsGO/1+dg47PLW3X7TbiZniTPC+oAqOh1CiF+ODnem4Nw1iRw854LN3yqibLHgTi093mCBtPGWZxg2sTcHUX4fo/UHNbSh8bERJznnennm4gEJXAYtpnEFSUCAwEAAaOCAUswggFHMA4GA1UdDwEB/wQEAwIBhjAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQU94LsSQE+MlHV4UBw/iEAx5DvYg8wGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwEgYDVR0TAQH/BAgwBgEB/wIBADAfBgNVHSMEGDAWgBQPU8s/FmEl/mCJHdO5fOiQrbOU0TBXBgNVHR8EUDBOMEygSqBIhkZodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNNYXJQQ0EyMDExXzIwMTEtMDMtMjguY3JsMFsGCCsGAQUFBwEBBE8wTTBLBggrBgEFBQcwAoY/aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNNYXJQQ0EyMDExXzIwMTEtMDMtMjguY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQAbTWps31OnBv77EVpCaU68drubToSKtpw9fYt4MvAhorXGRrRRfS6qou5o45QZAKjwzbOrr33dWxF4P3gCGqZxCotW32p6hlXGP7BnYlVw6242nlX0PahgpyWVWBmi0ElKH8N6HYhJqAW74tUNCzY7ALNMwk/JVEMKpWq+5XqutAEmtP0SdoSZPRwPtdiRjMLS8yyjP4HVAiKJ+m0wV3bLBtCG20BttEGkly7fYa2/E0ps41PLeX3T2yKRgmnGjhD16NUcMDdRpBh7MCXktwpISDEanB8QySJNdErU+NaKukgOW68+Oyk7lGiiZcG3boCGNec9JkM7dQdpA4tneQg0FI/o0mkDZR5aVItbAjRfMgAXpm6Hfu9DqOP+/R0K9v+CwyhwEjF3+SeL8YBAijXHD5YaiWzwZzBDtNQpuOXc91NmF7ifdHVy9IE1EhuIIQsMio3l0Uo87vGdwQ50po8o1F72zi1vfvKfDmszVezk6fF7cy7fZYh8I0ceVbZ4XY4xJ76TdYMItUAoPkvVdDq5B/d4oI7/xHfomRsEw08fuLxCRE8/BcvzSlDpnxu4wL6IULqVwHE+fbQ82Lr5ZDLxa1dYUw8zBGgCnx/ObVPj1RO1CaVi13wCxm8yaHeflKJWw7ZHOLeOGQyMRT+f9cFFk+5fzCA9GcwiSlEyYj4ilzGCGWUwghlhAgEBMIGjMIGLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMQwwCgYDVQQLEwNBT0MxJzAlBgNVBAMTHk1pY3Jvc29mdCBNYXJrZXRwbGFjZSBDQSBHIDAyMgITMwAP3fbhK2lqw7MWRgAAAA/d9jANBglghkgBZQMEAgEFAKCBjzAYBgkqhkiG9w0BCQMxCwYJKwYBBAGCNwoBMC8GCSqGSIb3DQEJBDEiBCBDgOMhvMousTIzk/P1eC2qGiSJLdSm3brGanFMLa41+DBCBgorBgEEAYI3AgEMMTQwMqAUgBIATQBpAGMAcgBvAHMAbwBmAHShGoAYaHR0cDovL3d3dy5taWNyb3NvZnQuY29tMA0GCSqGSIb3DQEBAQUABIIBAJ8LEwzLh2rDfLOOOodKT10yXoCzHPaQLv9sMwei+650mqV0iHaw9bUolBZAdBnF7JBRjY+yb9AIF7M/Av9pHRKvuLHWDntlo49RrfvNucHaJqPjCMm81h/GAuimPSBMpRtTCW+HHDWrw+HoGbRWQ+N/Vpt//pzj9gAzOzs8W9gU0RMz3ub4Hfgunm/CGACjFu5Hi2sjJbgigNlyRnxjI4+h3J7dGVOfR8hlhRB9YjXDB700F0bzaKqxC9LH7kZbAjiHPgLLCWz7OQ/rTo7wV5/e6v9GCKpamydPy/0MObq4TDi0fn75aVHTJJrzlwt1BJKyVPdAsOhiFUH3Mq4WheKhghcAMIIW/AYKKwYBBAGCNwMDATGCFuwwghboBgkqhkiG9w0BBwKgghbZMIIW1QIBAzEPMA0GCWCGSAFlAwQCAQUAMIIBUQYLKoZIhvcNAQkQAQSgggFABIIBPDCCATgCAQEGCisGAQQBhFkKAwEwMTANBglghkgBZQMEAgEFAAQgr34HNu5gF3j5DAITqq38vc6sNxs6ZqLz9i9zU2oQDtoCBmH66bcTCRgTMjAyMjAyMDQwOTA5NDkuNTkxWjAEgAIB9KCB0KSBzTCByjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046REQ4Qy1FMzM3LTJGQUUxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WgghFXMIIHDDCCBPSgAwIBAgITMwAAAZwPpk1h0p5LKAABAAABnDANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAeFw0yMTEyMDIxOTA1MTlaFw0yMzAyMjgxOTA1MTlaMIHKMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpERDhDLUUzMzctMkZBRTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANtSKgwZXUkWP6zrXazTaYq7bco9Q2zvU6MN4ka3GRMX2tJZOK4DxeBiQACL/n7YV/sKTslwpD0f9cPU4rCDX9sfcTWo7XPxdHLQ+WkaGbKKWATsqw69bw8hkJ/bjcp2V2A6vGsvwcqJCh07BK3JPmUtZikyy5PZ8fyTyiKGN7hOWlaIU9oIoucUNoAHQJzLq8h20eNgHUh7eI5k+Kyq4v6810LHuA6EHyKJOZN2xTw5JSkLy0FN5Mhg/OaFrFBl3iag2Tqp4InKLt+Jbh/Jd0etnei2aDHFrmlfPmlRSv5wSNX5zAhgEyRpjmQcz1zp0QaSAefRkMm923/ngU51IbrVbAeHj569SHC9doHgsIxkh0K3lpw582+0ONXcIfIU6nkBT+qADAZ+0dT1uu/gRTBy614QAofjo258TbSX9aOU1SHuAC+3bMoyM7jNdHEJROH+msFDBcmJRl4VKsReI5+S69KUGeLIBhhmnmQ6drF8Ip0ZiO+vhAsD3e9AnqnY7Hcge850I9oKvwuwpVwWnKnwwSGElMz7UvCocmoUMXk7Vn2aNti+bdH28+GQb5EMsqhOmvuZOCRpOWN33G+b3g5unwEP0eTiY+LnWa2AuK43z/pplURJVle29K42QPkOcglB6sjLmNpEpb9basJ72eA0Mlp1LtH3oYZGXsggTfuXAgMBAAGjggE2MIIBMjAdBgNVHQ4EFgQUu2kJZ1Ndjl2112SynL6jGMID+rIwHwYDVR0jBBgwFoAUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXwYDVR0fBFgwVjBUoFKgUIZOaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3JsMGwGCCsGAQUFBwEBBGAwXjBcBggrBgEFBQcwAoZQaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcnQwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDCDANBgkqhkiG9w0BAQsFAAOCAgEApwAqpiMYRzNNYyz3PSbtijbeyCpUXcvIrqA4zPtMIcAk34W9u9mRDndWS+tlR3WwTpr1OgaV1wmc6YFzqK6EGWm903UEsFE7xBJMPXjfdVOPhcJB3vfvA0PX56oobcF2OvNsOSwTB8bi/ns+Cs39Puzs+QSNQZd8iAVBCSvxNCL78dln2RGU1xyB4AKqV9vi4Y/Gfmx2FA+jF0y+YLeob0M40nlSxL0q075t7L6iFRMNr0u8ROhzhDPLl+4ePYfUmyYJoobvydel9anAEsHFlhKl+aXb2ic3yNwbsoPycZJL/vo8OVvYYxCy+/5FrQmAvoW0ZEaBiYcKkzrNWt/hX9r5KgdwL61x0ZiTZopTko6W/58UTefTbhX7Pni0MApH3Pvyt6N0IFap+/LlwFRD1zn7e6ccPTwESnuo/auCmgPznq80OATA7vufsRZPvqeX8jKtsraSNscvNQymEWlcqdXV9hYkjb4T/Qse9cUYaoXg68wFHFuslWfTdPYPLl1vqzlPMnNJpC8KtdioDgcq+y1BaSqSm8EdNfwzT37+/JFtVc3Gs915fDqgPZDgOSzKQIV+fw3aPYt2LET3AbmKKW/r13Oy8cg3+D0D362GQBAJVv0NRI5NowgaCw6oNgWOFPrN72WSEcca/8QQiTGP2XpLiGpRDJZ6sWRpRYNdydkwggdxMIIFWaADAgECAhMzAAAAFcXna54Cm0mZAAAAAAAVMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMyMjVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51yMo1V/YBf2xK4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY6GB9alKDRLemjkZrBxTzxXb1hlDcwUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9cmmvHaus9ja+NSZk2pg7uhp7M62AW36MEBydUv626GIl3GoPz130/o5Tz9bshVZN7928jaTjkY+yOSxRnOlwaQ3KNi1wjjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDuaRr3tpK56KTesy+uDRedGbsoy1cCGMFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74kpEeHT39IM9zfUGaRnXNxF803RKJ1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2K26oElHovwUDo9Fzpk03dJQcNIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5TI4CvEJoLhDqhFFG4tG9ahhaYQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZki1ugpoMhXV8wdJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9QBXpsxREdcu+N+VLEhReTwDwV2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3PmriLq0CAwEAAaOCAd0wggHZMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUCBBYEFCqnUv5kxJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJlpxtTNRnpcjBcBgNVHSAEVTBTMFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wEwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwDQYJKoZIhvcNAQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/ypb+pcFLY+TkdkeLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulmZzpTTd2YurYeeNg2LpypglYAA7AFvonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM9W0jVOR4U3UkV7ndn/OOPcbzaN9l9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECWOKz3+SmJw7wXsFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4FOmRsqlb30mjdAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3UwxTSwethQ/gpY3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPXfx5bRAGOWhmRaw2fpCjcZxkoJLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVXVAmxaQFEfnyhYWxz/gq77EFmPWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGConsXHRWJjXD+57XQKBqJC4822rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU5nR0W2rRnj7tfqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEGahC0HVUzWLOhcGbyoYICzjCCAjcCAQEwgfihgdCkgc0wgcoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOkREOEMtRTMzNy0yRkFFMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMKAQEwBwYFKw4DAhoDFQDN2Wnq3fCz9ucStub1zQz7129TQKCBgzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBBQUAAgUA5adiZjAiGA8yMDIyMDIwNDE2MjkyNloYDzIwMjIwMjA1MTYyOTI2WjB3MD0GCisGAQQBhFkKBAExLzAtMAoCBQDlp2JmAgEAMAoCAQACAh92AgH/MAcCAQACAhFfMAoCBQDlqLPmAgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQEFBQADgYEAbKzHReDTwgAKGSkgO/zxCAV/RcxwGpZK4M2bWgwqHVIi+/xiAKdQOSKeMz3UwRO4LI4EN4BjeK+ATpruzOtVGkyA8yzwdJFPv99j4O/Hc5kJSvovfECah62tBB3siNIFaAYNK+BF76k3j4+y9q9lF5yjQ8ZylVYbOfOjlJ2uevsxggQNMIIECQIBATCBkzB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAZwPpk1h0p5LKAABAAABnDANBglghkgBZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJBDEiBCD10XWSucJFd8jLe5PaC9h9/GHXK7ZZ0kb4BGFNqgWk9DCB+gYLKoZIhvcNAQkQAi8xgeowgecwgeQwgb0EIDcPRYUgjSzKOhF39d4QgbRZQgrPO7Lo/qE5GtvSeqa8MIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAGcD6ZNYdKeSygAAQAAAZwwIgQgPTEmgx6rn5xpH+xmlpYkcn0dL16GyYRqyG8uRajrfTYwDQYJKoZIhvcNAQELBQAEggIAxmSLisdd5cs+7liXX7vsF8zX3Y1rbtyPZ0M466WBaVULlfeuu9RMzOhWha7bkfYmKs5hXOQNBJrIHxnHbWeDu/V7EVF80IQ7/6qWiVPNcLtMnS8+uyw3Tby2gEhshO/HHOJRqllrgtUGuPl8FoAAPbPKV7X7jrg1kqOWoqpwyiSzt5cN/qijwfTcTIaPeON5wMd8wRT2l5F9e/JDBSq0WuzYb2r0kifv9wq21orm4sQkbg5GgDa/oCr3PQVCNSvPb2G7HANcqJXHeRKyoCeVhX5UaFrCQbdxGFytOc5GzptQKNn18yGg4VYrFpigUcglLbuREqqlPabwZh/QfgKdp4b4uVA6On5HIV5e9XdJ9TXhvDArEQ+Kgyao5xlgb4MkvPO9Thh9UIbw9r3JhQ+uKnCvXyiE2SpTLq1OXTjt/RrLZb+qsZW4nrDRBlBswa4G5OVW/svvI8N2/+YYrSdaCWt4unWSnSxeVUWZkugBmWdeoEJpfs5Qy8NwC+g1TyXcMjolOFTfBB6JYpHCbk6Euh2gKxq5weBb7puxVN4cvawYY2zorp6ZXtAmQGflZTl02nWld+nvDoF/zi6IUmP7PTKvbEVs8T+QkCiIM7cpLMs4NFK29f33lu1iZeGwJAxCYsV/P7geuRfA++bpDutTXjLKMqUTgf00sqJ/5HGuwLE= diff --git a/PC/clinic/_msi.c.h b/PC/clinic/_msi.c.h index 85c4d226ee4..c77f0703927 100644 --- a/PC/clinic/_msi.c.h +++ b/PC/clinic/_msi.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_msi_UuidCreate__doc__, "UuidCreate($module, /)\n" "--\n" @@ -33,7 +39,7 @@ PyDoc_STRVAR(_msi_FCICreate__doc__, " and the name of the file inside the CAB file"); #define _MSI_FCICREATE_METHODDEF \ - {"FCICreate", (PyCFunction)(void(*)(void))_msi_FCICreate, METH_FASTCALL, _msi_FCICreate__doc__}, + {"FCICreate", _PyCFunction_CAST(_msi_FCICreate), METH_FASTCALL, _msi_FCICreate__doc__}, static PyObject * _msi_FCICreate_impl(PyObject *module, const char *cabname, PyObject *files); @@ -185,7 +191,7 @@ PyDoc_STRVAR(_msi_Record_SetString__doc__, "Set field to a string value."); #define _MSI_RECORD_SETSTRING_METHODDEF \ - {"SetString", (PyCFunction)(void(*)(void))_msi_Record_SetString, METH_FASTCALL, _msi_Record_SetString__doc__}, + {"SetString", _PyCFunction_CAST(_msi_Record_SetString), METH_FASTCALL, _msi_Record_SetString__doc__}, static PyObject * _msi_Record_SetString_impl(msiobj *self, int field, const Py_UNICODE *value); @@ -195,7 +201,7 @@ _msi_Record_SetString(msiobj *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; int field; - const Py_UNICODE *value; + const Py_UNICODE *value = NULL; if (!_PyArg_CheckPositional("SetString", nargs, 2, 2)) { goto exit; @@ -208,11 +214,7 @@ _msi_Record_SetString(msiobj *self, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("SetString", "argument 2", "str", args[1]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - value = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ value = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (value == NULL) { goto exit; } @@ -220,9 +222,7 @@ _msi_Record_SetString(msiobj *self, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for value */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)value); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -234,7 +234,7 @@ PyDoc_STRVAR(_msi_Record_SetStream__doc__, "Set field to the contents of the file named value."); #define _MSI_RECORD_SETSTREAM_METHODDEF \ - {"SetStream", (PyCFunction)(void(*)(void))_msi_Record_SetStream, METH_FASTCALL, _msi_Record_SetStream__doc__}, + {"SetStream", _PyCFunction_CAST(_msi_Record_SetStream), METH_FASTCALL, _msi_Record_SetStream__doc__}, static PyObject * _msi_Record_SetStream_impl(msiobj *self, int field, const Py_UNICODE *value); @@ -244,7 +244,7 @@ _msi_Record_SetStream(msiobj *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; int field; - const Py_UNICODE *value; + const Py_UNICODE *value = NULL; if (!_PyArg_CheckPositional("SetStream", nargs, 2, 2)) { goto exit; @@ -257,11 +257,7 @@ _msi_Record_SetStream(msiobj *self, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("SetStream", "argument 2", "str", args[1]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - value = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ value = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (value == NULL) { goto exit; } @@ -269,9 +265,7 @@ _msi_Record_SetStream(msiobj *self, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for value */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)value); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -283,7 +277,7 @@ PyDoc_STRVAR(_msi_Record_SetInteger__doc__, "Set field to an integer value."); #define _MSI_RECORD_SETINTEGER_METHODDEF \ - {"SetInteger", (PyCFunction)(void(*)(void))_msi_Record_SetInteger, METH_FASTCALL, _msi_Record_SetInteger__doc__}, + {"SetInteger", _PyCFunction_CAST(_msi_Record_SetInteger), METH_FASTCALL, _msi_Record_SetInteger__doc__}, static PyObject * _msi_Record_SetInteger_impl(msiobj *self, int field, int value); @@ -373,7 +367,7 @@ PyDoc_STRVAR(_msi_SummaryInformation_SetProperty__doc__, " the new value of the property (integer or string)"); #define _MSI_SUMMARYINFORMATION_SETPROPERTY_METHODDEF \ - {"SetProperty", (PyCFunction)(void(*)(void))_msi_SummaryInformation_SetProperty, METH_FASTCALL, _msi_SummaryInformation_SetProperty__doc__}, + {"SetProperty", _PyCFunction_CAST(_msi_SummaryInformation_SetProperty), METH_FASTCALL, _msi_SummaryInformation_SetProperty__doc__}, static PyObject * _msi_SummaryInformation_SetProperty_impl(msiobj *self, int field, @@ -492,7 +486,7 @@ PyDoc_STRVAR(_msi_View_Modify__doc__, " a record describing the new data"); #define _MSI_VIEW_MODIFY_METHODDEF \ - {"Modify", (PyCFunction)(void(*)(void))_msi_View_Modify, METH_FASTCALL, _msi_View_Modify__doc__}, + {"Modify", _PyCFunction_CAST(_msi_View_Modify), METH_FASTCALL, _msi_View_Modify__doc__}, static PyObject * _msi_View_Modify_impl(msiobj *self, int kind, PyObject *data); @@ -555,17 +549,13 @@ static PyObject * _msi_Database_OpenView(msiobj *self, PyObject *arg) { PyObject *return_value = NULL; - const Py_UNICODE *sql; + const Py_UNICODE *sql = NULL; if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("OpenView", "argument", "str", arg); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - sql = _PyUnicode_AsUnicode(arg); - #else /* USE_UNICODE_WCHAR_CACHE */ sql = PyUnicode_AsWideCharString(arg, NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (sql == NULL) { goto exit; } @@ -573,9 +563,7 @@ _msi_Database_OpenView(msiobj *self, PyObject *arg) exit: /* Cleanup for sql */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sql); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -641,7 +629,7 @@ PyDoc_STRVAR(_msi_OpenDatabase__doc__, " the persistence mode"); #define _MSI_OPENDATABASE_METHODDEF \ - {"OpenDatabase", (PyCFunction)(void(*)(void))_msi_OpenDatabase, METH_FASTCALL, _msi_OpenDatabase__doc__}, + {"OpenDatabase", _PyCFunction_CAST(_msi_OpenDatabase), METH_FASTCALL, _msi_OpenDatabase__doc__}, static PyObject * _msi_OpenDatabase_impl(PyObject *module, const Py_UNICODE *path, int persist); @@ -650,7 +638,7 @@ static PyObject * _msi_OpenDatabase(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - const Py_UNICODE *path; + const Py_UNICODE *path = NULL; int persist; if (!_PyArg_CheckPositional("OpenDatabase", nargs, 2, 2)) { @@ -660,11 +648,7 @@ _msi_OpenDatabase(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("OpenDatabase", "argument 1", "str", args[0]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - path = _PyUnicode_AsUnicode(args[0]); - #else /* USE_UNICODE_WCHAR_CACHE */ path = PyUnicode_AsWideCharString(args[0], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (path == NULL) { goto exit; } @@ -676,9 +660,7 @@ _msi_OpenDatabase(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for path */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)path); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -713,4 +695,4 @@ _msi_CreateRecord(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=49debf733ee5cab2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7d083c61679eed83 input=a9049054013a1b77]*/ diff --git a/PC/clinic/_testconsole.c.h b/PC/clinic/_testconsole.c.h index cf5e4ee0906..b2f3b4ce8b0 100644 --- a/PC/clinic/_testconsole.c.h +++ b/PC/clinic/_testconsole.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(MS_WINDOWS) PyDoc_STRVAR(_testconsole_write_input__doc__, @@ -11,7 +17,7 @@ PyDoc_STRVAR(_testconsole_write_input__doc__, "Writes UTF-16-LE encoded bytes to the console as if typed by a user."); #define _TESTCONSOLE_WRITE_INPUT_METHODDEF \ - {"write_input", (PyCFunction)(void(*)(void))_testconsole_write_input, METH_FASTCALL|METH_KEYWORDS, _testconsole_write_input__doc__}, + {"write_input", _PyCFunction_CAST(_testconsole_write_input), METH_FASTCALL|METH_KEYWORDS, _testconsole_write_input__doc__}, static PyObject * _testconsole_write_input_impl(PyObject *module, PyObject *file, @@ -21,8 +27,31 @@ static PyObject * _testconsole_write_input(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(s), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"file", "s", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "write_input", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "write_input", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *file; PyBytesObject *s; @@ -54,7 +83,7 @@ PyDoc_STRVAR(_testconsole_read_output__doc__, "Reads a str from the console as written to stdout."); #define _TESTCONSOLE_READ_OUTPUT_METHODDEF \ - {"read_output", (PyCFunction)(void(*)(void))_testconsole_read_output, METH_FASTCALL|METH_KEYWORDS, _testconsole_read_output__doc__}, + {"read_output", _PyCFunction_CAST(_testconsole_read_output), METH_FASTCALL|METH_KEYWORDS, _testconsole_read_output__doc__}, static PyObject * _testconsole_read_output_impl(PyObject *module, PyObject *file); @@ -63,8 +92,31 @@ static PyObject * _testconsole_read_output(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"file", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "read_output", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "read_output", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *file; @@ -88,4 +140,4 @@ exit: #ifndef _TESTCONSOLE_READ_OUTPUT_METHODDEF #define _TESTCONSOLE_READ_OUTPUT_METHODDEF #endif /* !defined(_TESTCONSOLE_READ_OUTPUT_METHODDEF) */ -/*[clinic end generated code: output=dd8b093a91b62753 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=208c72e2c873555b input=a9049054013a1b77]*/ diff --git a/PC/clinic/_wmimodule.cpp.h b/PC/clinic/_wmimodule.cpp.h new file mode 100644 index 00000000000..e2b947f339d --- /dev/null +++ b/PC/clinic/_wmimodule.cpp.h @@ -0,0 +1,75 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(_wmi_exec_query__doc__, +"exec_query($module, /, query)\n" +"--\n" +"\n" +"Runs a WMI query against the local machine.\n" +"\n" +"This returns a single string with \'name=value\' pairs in a flat array separated\n" +"by null characters."); + +#define _WMI_EXEC_QUERY_METHODDEF \ + {"exec_query", _PyCFunction_CAST(_wmi_exec_query), METH_FASTCALL|METH_KEYWORDS, _wmi_exec_query__doc__}, + +static PyObject * +_wmi_exec_query_impl(PyObject *module, PyObject *query); + +static PyObject * +_wmi_exec_query(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(query), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"query", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "exec_query", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *query; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("exec_query", "argument 'query'", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + query = args[0]; + return_value = _wmi_exec_query_impl(module, query); + +exit: + return return_value; +} +/*[clinic end generated code: output=7fdf0c0579ddb566 input=a9049054013a1b77]*/ diff --git a/PC/clinic/msvcrtmodule.c.h b/PC/clinic/msvcrtmodule.c.h index 1ac82cb965b..d808ef0bbd0 100644 --- a/PC/clinic/msvcrtmodule.c.h +++ b/PC/clinic/msvcrtmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(msvcrt_heapmin__doc__, "heapmin($module, /)\n" "--\n" @@ -37,7 +43,7 @@ PyDoc_STRVAR(msvcrt_locking__doc__, "individually."); #define MSVCRT_LOCKING_METHODDEF \ - {"locking", (PyCFunction)(void(*)(void))msvcrt_locking, METH_FASTCALL, msvcrt_locking__doc__}, + {"locking", _PyCFunction_CAST(msvcrt_locking), METH_FASTCALL, msvcrt_locking__doc__}, static PyObject * msvcrt_locking_impl(PyObject *module, int fd, int mode, long nbytes); @@ -83,7 +89,7 @@ PyDoc_STRVAR(msvcrt_setmode__doc__, "Return value is the previous mode."); #define MSVCRT_SETMODE_METHODDEF \ - {"setmode", (PyCFunction)(void(*)(void))msvcrt_setmode, METH_FASTCALL, msvcrt_setmode__doc__}, + {"setmode", _PyCFunction_CAST(msvcrt_setmode), METH_FASTCALL, msvcrt_setmode__doc__}, static long msvcrt_setmode_impl(PyObject *module, int fd, int flags); @@ -128,7 +134,7 @@ PyDoc_STRVAR(msvcrt_open_osfhandle__doc__, "to os.fdopen() to create a file object."); #define MSVCRT_OPEN_OSFHANDLE_METHODDEF \ - {"open_osfhandle", (PyCFunction)(void(*)(void))msvcrt_open_osfhandle, METH_FASTCALL, msvcrt_open_osfhandle__doc__}, + {"open_osfhandle", _PyCFunction_CAST(msvcrt_open_osfhandle), METH_FASTCALL, msvcrt_open_osfhandle__doc__}, static long msvcrt_open_osfhandle_impl(PyObject *module, void *handle, int flags); @@ -141,8 +147,15 @@ msvcrt_open_osfhandle(PyObject *module, PyObject *const *args, Py_ssize_t nargs) int flags; long _return_value; - if (!_PyArg_ParseStack(args, nargs, ""_Py_PARSE_UINTPTR"i:open_osfhandle", - &handle, &flags)) { + if (!_PyArg_CheckPositional("open_osfhandle", nargs, 2, 2)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + flags = _PyLong_AsInt(args[1]); + if (flags == -1 && PyErr_Occurred()) { goto exit; } _return_value = msvcrt_open_osfhandle_impl(module, handle, flags); @@ -475,7 +488,7 @@ PyDoc_STRVAR(msvcrt_CrtSetReportFile__doc__, "Only available on Debug builds."); #define MSVCRT_CRTSETREPORTFILE_METHODDEF \ - {"CrtSetReportFile", (PyCFunction)(void(*)(void))msvcrt_CrtSetReportFile, METH_FASTCALL, msvcrt_CrtSetReportFile__doc__}, + {"CrtSetReportFile", _PyCFunction_CAST(msvcrt_CrtSetReportFile), METH_FASTCALL, msvcrt_CrtSetReportFile__doc__}, static void * msvcrt_CrtSetReportFile_impl(PyObject *module, int type, void *file); @@ -488,8 +501,15 @@ msvcrt_CrtSetReportFile(PyObject *module, PyObject *const *args, Py_ssize_t narg void *file; void *_return_value; - if (!_PyArg_ParseStack(args, nargs, "i"_Py_PARSE_UINTPTR":CrtSetReportFile", - &type, &file)) { + if (!_PyArg_CheckPositional("CrtSetReportFile", nargs, 2, 2)) { + goto exit; + } + type = _PyLong_AsInt(args[0]); + if (type == -1 && PyErr_Occurred()) { + goto exit; + } + file = PyLong_AsVoidPtr(args[1]); + if (!file && PyErr_Occurred()) { goto exit; } _return_value = msvcrt_CrtSetReportFile_impl(module, type, file); @@ -515,7 +535,7 @@ PyDoc_STRVAR(msvcrt_CrtSetReportMode__doc__, "Only available on Debug builds."); #define MSVCRT_CRTSETREPORTMODE_METHODDEF \ - {"CrtSetReportMode", (PyCFunction)(void(*)(void))msvcrt_CrtSetReportMode, METH_FASTCALL, msvcrt_CrtSetReportMode__doc__}, + {"CrtSetReportMode", _PyCFunction_CAST(msvcrt_CrtSetReportMode), METH_FASTCALL, msvcrt_CrtSetReportMode__doc__}, static long msvcrt_CrtSetReportMode_impl(PyObject *module, int type, int mode); @@ -647,4 +667,4 @@ exit: #ifndef MSVCRT_SET_ERROR_MODE_METHODDEF #define MSVCRT_SET_ERROR_MODE_METHODDEF #endif /* !defined(MSVCRT_SET_ERROR_MODE_METHODDEF) */ -/*[clinic end generated code: output=20dfbc768edce7c0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=204bae9fee7f6124 input=a9049054013a1b77]*/ diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h index 183301f0618..2834d9967a7 100644 --- a/PC/clinic/winreg.c.h +++ b/PC/clinic/winreg.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(winreg_HKEYType_Close__doc__, "Close($self, /)\n" "--\n" @@ -77,7 +83,7 @@ PyDoc_STRVAR(winreg_HKEYType___exit____doc__, "\n"); #define WINREG_HKEYTYPE___EXIT___METHODDEF \ - {"__exit__", (PyCFunction)(void(*)(void))winreg_HKEYType___exit__, METH_FASTCALL|METH_KEYWORDS, winreg_HKEYType___exit____doc__}, + {"__exit__", _PyCFunction_CAST(winreg_HKEYType___exit__), METH_FASTCALL|METH_KEYWORDS, winreg_HKEYType___exit____doc__}, static PyObject * winreg_HKEYType___exit___impl(PyHKEYObject *self, PyObject *exc_type, @@ -87,8 +93,31 @@ static PyObject * winreg_HKEYType___exit__(PyHKEYObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(exc_type), &_Py_ID(exc_value), &_Py_ID(traceback), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"exc_type", "exc_value", "traceback", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "__exit__", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__exit__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject *exc_type; PyObject *exc_value; @@ -138,7 +167,7 @@ PyDoc_STRVAR(winreg_ConnectRegistry__doc__, "If the function fails, an OSError exception is raised."); #define WINREG_CONNECTREGISTRY_METHODDEF \ - {"ConnectRegistry", (PyCFunction)(void(*)(void))winreg_ConnectRegistry, METH_FASTCALL, winreg_ConnectRegistry__doc__}, + {"ConnectRegistry", _PyCFunction_CAST(winreg_ConnectRegistry), METH_FASTCALL, winreg_ConnectRegistry__doc__}, static HKEY winreg_ConnectRegistry_impl(PyObject *module, @@ -148,7 +177,7 @@ static PyObject * winreg_ConnectRegistry(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - const Py_UNICODE *computer_name; + const Py_UNICODE *computer_name = NULL; HKEY key; HKEY _return_value; @@ -159,11 +188,7 @@ winreg_ConnectRegistry(PyObject *module, PyObject *const *args, Py_ssize_t nargs computer_name = NULL; } else if (PyUnicode_Check(args[0])) { - #if USE_UNICODE_WCHAR_CACHE - computer_name = _PyUnicode_AsUnicode(args[0]); - #else /* USE_UNICODE_WCHAR_CACHE */ computer_name = PyUnicode_AsWideCharString(args[0], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (computer_name == NULL) { goto exit; } @@ -183,9 +208,7 @@ winreg_ConnectRegistry(PyObject *module, PyObject *const *args, Py_ssize_t nargs exit: /* Cleanup for computer_name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)computer_name); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -210,7 +233,7 @@ PyDoc_STRVAR(winreg_CreateKey__doc__, "If the function fails, an OSError exception is raised."); #define WINREG_CREATEKEY_METHODDEF \ - {"CreateKey", (PyCFunction)(void(*)(void))winreg_CreateKey, METH_FASTCALL, winreg_CreateKey__doc__}, + {"CreateKey", _PyCFunction_CAST(winreg_CreateKey), METH_FASTCALL, winreg_CreateKey__doc__}, static HKEY winreg_CreateKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key); @@ -220,7 +243,7 @@ winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *sub_key; + const Py_UNICODE *sub_key = NULL; HKEY _return_value; if (!_PyArg_CheckPositional("CreateKey", nargs, 2, 2)) { @@ -233,11 +256,7 @@ winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) sub_key = NULL; } else if (PyUnicode_Check(args[1])) { - #if USE_UNICODE_WCHAR_CACHE - sub_key = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ sub_key = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (sub_key == NULL) { goto exit; } @@ -254,9 +273,7 @@ winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -287,7 +304,7 @@ PyDoc_STRVAR(winreg_CreateKeyEx__doc__, "If the function fails, an OSError exception is raised."); #define WINREG_CREATEKEYEX_METHODDEF \ - {"CreateKeyEx", (PyCFunction)(void(*)(void))winreg_CreateKeyEx, METH_FASTCALL|METH_KEYWORDS, winreg_CreateKeyEx__doc__}, + {"CreateKeyEx", _PyCFunction_CAST(winreg_CreateKeyEx), METH_FASTCALL|METH_KEYWORDS, winreg_CreateKeyEx__doc__}, static HKEY winreg_CreateKeyEx_impl(PyObject *module, HKEY key, @@ -298,18 +315,76 @@ static PyObject * winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(sub_key), &_Py_ID(reserved), &_Py_ID(access), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; - static _PyArg_Parser _parser = {"O&O&|ii:CreateKeyEx", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "CreateKeyEx", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; HKEY key; - const Py_UNICODE *sub_key; + const Py_UNICODE *sub_key = NULL; int reserved = 0; REGSAM access = KEY_WRITE; HKEY _return_value; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &reserved, &access)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 4, 0, argsbuf); + if (!args) { goto exit; } + if (!clinic_HKEY_converter(args[0], &key)) { + goto exit; + } + if (args[1] == Py_None) { + sub_key = NULL; + } + else if (PyUnicode_Check(args[1])) { + sub_key = PyUnicode_AsWideCharString(args[1], NULL); + if (sub_key == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("CreateKeyEx", "argument 'sub_key'", "str or None", args[1]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[2]) { + reserved = _PyLong_AsInt(args[2]); + if (reserved == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + access = _PyLong_AsInt(args[3]); + if (access == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: _return_value = winreg_CreateKeyEx_impl(module, key, sub_key, reserved, access); if (_return_value == NULL) { goto exit; @@ -318,9 +393,7 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -344,7 +417,7 @@ PyDoc_STRVAR(winreg_DeleteKey__doc__, "is removed. If the function fails, an OSError exception is raised."); #define WINREG_DELETEKEY_METHODDEF \ - {"DeleteKey", (PyCFunction)(void(*)(void))winreg_DeleteKey, METH_FASTCALL, winreg_DeleteKey__doc__}, + {"DeleteKey", _PyCFunction_CAST(winreg_DeleteKey), METH_FASTCALL, winreg_DeleteKey__doc__}, static PyObject * winreg_DeleteKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key); @@ -354,7 +427,7 @@ winreg_DeleteKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *sub_key; + const Py_UNICODE *sub_key = NULL; if (!_PyArg_CheckPositional("DeleteKey", nargs, 2, 2)) { goto exit; @@ -366,11 +439,7 @@ winreg_DeleteKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("DeleteKey", "argument 2", "str", args[1]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - sub_key = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ sub_key = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (sub_key == NULL) { goto exit; } @@ -378,9 +447,7 @@ winreg_DeleteKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -390,7 +457,7 @@ PyDoc_STRVAR(winreg_DeleteKeyEx__doc__, " reserved=0)\n" "--\n" "\n" -"Deletes the specified key (64-bit OS only).\n" +"Deletes the specified key (intended for 64-bit OS).\n" "\n" " key\n" " An already open key, or any one of the predefined HKEY_* constants.\n" @@ -404,6 +471,9 @@ PyDoc_STRVAR(winreg_DeleteKeyEx__doc__, " reserved\n" " A reserved integer, and must be zero. Default is zero.\n" "\n" +"While this function is intended to be used for 64-bit OS, it is also\n" +" available on 32-bit systems.\n" +"\n" "This method can not delete keys with subkeys.\n" "\n" "If the function succeeds, the entire key, including all of its values,\n" @@ -411,7 +481,7 @@ PyDoc_STRVAR(winreg_DeleteKeyEx__doc__, "On unsupported Windows versions, NotImplementedError is raised."); #define WINREG_DELETEKEYEX_METHODDEF \ - {"DeleteKeyEx", (PyCFunction)(void(*)(void))winreg_DeleteKeyEx, METH_FASTCALL|METH_KEYWORDS, winreg_DeleteKeyEx__doc__}, + {"DeleteKeyEx", _PyCFunction_CAST(winreg_DeleteKeyEx), METH_FASTCALL|METH_KEYWORDS, winreg_DeleteKeyEx__doc__}, static PyObject * winreg_DeleteKeyEx_impl(PyObject *module, HKEY key, @@ -422,24 +492,75 @@ static PyObject * winreg_DeleteKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(sub_key), &_Py_ID(access), &_Py_ID(reserved), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "sub_key", "access", "reserved", NULL}; - static _PyArg_Parser _parser = {"O&O&|ii:DeleteKeyEx", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "DeleteKeyEx", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; HKEY key; - const Py_UNICODE *sub_key; + const Py_UNICODE *sub_key = NULL; REGSAM access = KEY_WOW64_64KEY; int reserved = 0; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Converter, &sub_key, &access, &reserved)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 4, 0, argsbuf); + if (!args) { goto exit; } + if (!clinic_HKEY_converter(args[0], &key)) { + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("DeleteKeyEx", "argument 'sub_key'", "str", args[1]); + goto exit; + } + sub_key = PyUnicode_AsWideCharString(args[1], NULL); + if (sub_key == NULL) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[2]) { + access = _PyLong_AsInt(args[2]); + if (access == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + reserved = _PyLong_AsInt(args[3]); + if (reserved == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: return_value = winreg_DeleteKeyEx_impl(module, key, sub_key, access, reserved); exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -456,7 +577,7 @@ PyDoc_STRVAR(winreg_DeleteValue__doc__, " A string that identifies the value to remove."); #define WINREG_DELETEVALUE_METHODDEF \ - {"DeleteValue", (PyCFunction)(void(*)(void))winreg_DeleteValue, METH_FASTCALL, winreg_DeleteValue__doc__}, + {"DeleteValue", _PyCFunction_CAST(winreg_DeleteValue), METH_FASTCALL, winreg_DeleteValue__doc__}, static PyObject * winreg_DeleteValue_impl(PyObject *module, HKEY key, const Py_UNICODE *value); @@ -466,7 +587,7 @@ winreg_DeleteValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *value; + const Py_UNICODE *value = NULL; if (!_PyArg_CheckPositional("DeleteValue", nargs, 2, 2)) { goto exit; @@ -478,11 +599,7 @@ winreg_DeleteValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) value = NULL; } else if (PyUnicode_Check(args[1])) { - #if USE_UNICODE_WCHAR_CACHE - value = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ value = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (value == NULL) { goto exit; } @@ -495,9 +612,7 @@ winreg_DeleteValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for value */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)value); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -518,7 +633,7 @@ PyDoc_STRVAR(winreg_EnumKey__doc__, "raised, indicating no more values are available."); #define WINREG_ENUMKEY_METHODDEF \ - {"EnumKey", (PyCFunction)(void(*)(void))winreg_EnumKey, METH_FASTCALL, winreg_EnumKey__doc__}, + {"EnumKey", _PyCFunction_CAST(winreg_EnumKey), METH_FASTCALL, winreg_EnumKey__doc__}, static PyObject * winreg_EnumKey_impl(PyObject *module, HKEY key, int index); @@ -571,7 +686,7 @@ PyDoc_STRVAR(winreg_EnumValue__doc__, " An integer that identifies the type of the value data."); #define WINREG_ENUMVALUE_METHODDEF \ - {"EnumValue", (PyCFunction)(void(*)(void))winreg_EnumValue, METH_FASTCALL, winreg_EnumValue__doc__}, + {"EnumValue", _PyCFunction_CAST(winreg_EnumValue), METH_FASTCALL, winreg_EnumValue__doc__}, static PyObject * winreg_EnumValue_impl(PyObject *module, HKEY key, int index); @@ -616,17 +731,13 @@ static PyObject * winreg_ExpandEnvironmentStrings(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - const Py_UNICODE *string; + const Py_UNICODE *string = NULL; if (!PyUnicode_Check(arg)) { _PyArg_BadArgument("ExpandEnvironmentStrings", "argument", "str", arg); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - string = _PyUnicode_AsUnicode(arg); - #else /* USE_UNICODE_WCHAR_CACHE */ string = PyUnicode_AsWideCharString(arg, NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (string == NULL) { goto exit; } @@ -634,9 +745,7 @@ winreg_ExpandEnvironmentStrings(PyObject *module, PyObject *arg) exit: /* Cleanup for string */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)string); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -710,7 +819,7 @@ PyDoc_STRVAR(winreg_LoadKey__doc__, "tree."); #define WINREG_LOADKEY_METHODDEF \ - {"LoadKey", (PyCFunction)(void(*)(void))winreg_LoadKey, METH_FASTCALL, winreg_LoadKey__doc__}, + {"LoadKey", _PyCFunction_CAST(winreg_LoadKey), METH_FASTCALL, winreg_LoadKey__doc__}, static PyObject * winreg_LoadKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key, @@ -721,8 +830,8 @@ winreg_LoadKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *sub_key; - const Py_UNICODE *file_name; + const Py_UNICODE *sub_key = NULL; + const Py_UNICODE *file_name = NULL; if (!_PyArg_CheckPositional("LoadKey", nargs, 3, 3)) { goto exit; @@ -734,11 +843,7 @@ winreg_LoadKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("LoadKey", "argument 2", "str", args[1]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - sub_key = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ sub_key = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (sub_key == NULL) { goto exit; } @@ -746,11 +851,7 @@ winreg_LoadKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("LoadKey", "argument 3", "str", args[2]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - file_name = _PyUnicode_AsUnicode(args[2]); - #else /* USE_UNICODE_WCHAR_CACHE */ file_name = PyUnicode_AsWideCharString(args[2], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (file_name == NULL) { goto exit; } @@ -758,13 +859,9 @@ winreg_LoadKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ /* Cleanup for file_name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)file_name); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -789,7 +886,7 @@ PyDoc_STRVAR(winreg_OpenKey__doc__, "If the function fails, an OSError exception is raised."); #define WINREG_OPENKEY_METHODDEF \ - {"OpenKey", (PyCFunction)(void(*)(void))winreg_OpenKey, METH_FASTCALL|METH_KEYWORDS, winreg_OpenKey__doc__}, + {"OpenKey", _PyCFunction_CAST(winreg_OpenKey), METH_FASTCALL|METH_KEYWORDS, winreg_OpenKey__doc__}, static HKEY winreg_OpenKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key, @@ -799,18 +896,76 @@ static PyObject * winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(sub_key), &_Py_ID(reserved), &_Py_ID(access), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; - static _PyArg_Parser _parser = {"O&O&|ii:OpenKey", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "OpenKey", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; HKEY key; - const Py_UNICODE *sub_key; + const Py_UNICODE *sub_key = NULL; int reserved = 0; REGSAM access = KEY_READ; HKEY _return_value; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &reserved, &access)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 4, 0, argsbuf); + if (!args) { goto exit; } + if (!clinic_HKEY_converter(args[0], &key)) { + goto exit; + } + if (args[1] == Py_None) { + sub_key = NULL; + } + else if (PyUnicode_Check(args[1])) { + sub_key = PyUnicode_AsWideCharString(args[1], NULL); + if (sub_key == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("OpenKey", "argument 'sub_key'", "str or None", args[1]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[2]) { + reserved = _PyLong_AsInt(args[2]); + if (reserved == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + access = _PyLong_AsInt(args[3]); + if (access == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: _return_value = winreg_OpenKey_impl(module, key, sub_key, reserved, access); if (_return_value == NULL) { goto exit; @@ -819,9 +974,7 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -846,7 +999,7 @@ PyDoc_STRVAR(winreg_OpenKeyEx__doc__, "If the function fails, an OSError exception is raised."); #define WINREG_OPENKEYEX_METHODDEF \ - {"OpenKeyEx", (PyCFunction)(void(*)(void))winreg_OpenKeyEx, METH_FASTCALL|METH_KEYWORDS, winreg_OpenKeyEx__doc__}, + {"OpenKeyEx", _PyCFunction_CAST(winreg_OpenKeyEx), METH_FASTCALL|METH_KEYWORDS, winreg_OpenKeyEx__doc__}, static HKEY winreg_OpenKeyEx_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key, @@ -856,18 +1009,76 @@ static PyObject * winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(sub_key), &_Py_ID(reserved), &_Py_ID(access), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; - static _PyArg_Parser _parser = {"O&O&|ii:OpenKeyEx", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "OpenKeyEx", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; HKEY key; - const Py_UNICODE *sub_key; + const Py_UNICODE *sub_key = NULL; int reserved = 0; REGSAM access = KEY_READ; HKEY _return_value; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &reserved, &access)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 4, 0, argsbuf); + if (!args) { goto exit; } + if (!clinic_HKEY_converter(args[0], &key)) { + goto exit; + } + if (args[1] == Py_None) { + sub_key = NULL; + } + else if (PyUnicode_Check(args[1])) { + sub_key = PyUnicode_AsWideCharString(args[1], NULL); + if (sub_key == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("OpenKeyEx", "argument 'sub_key'", "str or None", args[1]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[2]) { + reserved = _PyLong_AsInt(args[2]); + if (reserved == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + access = _PyLong_AsInt(args[3]); + if (access == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: _return_value = winreg_OpenKeyEx_impl(module, key, sub_key, reserved, access); if (_return_value == NULL) { goto exit; @@ -876,9 +1087,7 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -940,7 +1149,7 @@ PyDoc_STRVAR(winreg_QueryValue__doc__, "completeness."); #define WINREG_QUERYVALUE_METHODDEF \ - {"QueryValue", (PyCFunction)(void(*)(void))winreg_QueryValue, METH_FASTCALL, winreg_QueryValue__doc__}, + {"QueryValue", _PyCFunction_CAST(winreg_QueryValue), METH_FASTCALL, winreg_QueryValue__doc__}, static PyObject * winreg_QueryValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key); @@ -950,7 +1159,7 @@ winreg_QueryValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *sub_key; + const Py_UNICODE *sub_key = NULL; if (!_PyArg_CheckPositional("QueryValue", nargs, 2, 2)) { goto exit; @@ -962,11 +1171,7 @@ winreg_QueryValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) sub_key = NULL; } else if (PyUnicode_Check(args[1])) { - #if USE_UNICODE_WCHAR_CACHE - sub_key = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ sub_key = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (sub_key == NULL) { goto exit; } @@ -979,9 +1184,7 @@ winreg_QueryValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -1003,7 +1206,7 @@ PyDoc_STRVAR(winreg_QueryValueEx__doc__, "The return value is a tuple of the value and the type_id."); #define WINREG_QUERYVALUEEX_METHODDEF \ - {"QueryValueEx", (PyCFunction)(void(*)(void))winreg_QueryValueEx, METH_FASTCALL, winreg_QueryValueEx__doc__}, + {"QueryValueEx", _PyCFunction_CAST(winreg_QueryValueEx), METH_FASTCALL, winreg_QueryValueEx__doc__}, static PyObject * winreg_QueryValueEx_impl(PyObject *module, HKEY key, const Py_UNICODE *name); @@ -1013,7 +1216,7 @@ winreg_QueryValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *name; + const Py_UNICODE *name = NULL; if (!_PyArg_CheckPositional("QueryValueEx", nargs, 2, 2)) { goto exit; @@ -1025,11 +1228,7 @@ winreg_QueryValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) name = NULL; } else if (PyUnicode_Check(args[1])) { - #if USE_UNICODE_WCHAR_CACHE - name = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ name = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (name == NULL) { goto exit; } @@ -1042,9 +1241,7 @@ winreg_QueryValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)name); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -1071,7 +1268,7 @@ PyDoc_STRVAR(winreg_SaveKey__doc__, "to the API."); #define WINREG_SAVEKEY_METHODDEF \ - {"SaveKey", (PyCFunction)(void(*)(void))winreg_SaveKey, METH_FASTCALL, winreg_SaveKey__doc__}, + {"SaveKey", _PyCFunction_CAST(winreg_SaveKey), METH_FASTCALL, winreg_SaveKey__doc__}, static PyObject * winreg_SaveKey_impl(PyObject *module, HKEY key, const Py_UNICODE *file_name); @@ -1081,7 +1278,7 @@ winreg_SaveKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *file_name; + const Py_UNICODE *file_name = NULL; if (!_PyArg_CheckPositional("SaveKey", nargs, 2, 2)) { goto exit; @@ -1093,11 +1290,7 @@ winreg_SaveKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("SaveKey", "argument 2", "str", args[1]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - file_name = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ file_name = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (file_name == NULL) { goto exit; } @@ -1105,9 +1298,7 @@ winreg_SaveKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for file_name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)file_name); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -1139,7 +1330,7 @@ PyDoc_STRVAR(winreg_SetValue__doc__, "KEY_SET_VALUE access."); #define WINREG_SETVALUE_METHODDEF \ - {"SetValue", (PyCFunction)(void(*)(void))winreg_SetValue, METH_FASTCALL, winreg_SetValue__doc__}, + {"SetValue", _PyCFunction_CAST(winreg_SetValue), METH_FASTCALL, winreg_SetValue__doc__}, static PyObject * winreg_SetValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key, @@ -1150,21 +1341,45 @@ winreg_SetValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *sub_key; + const Py_UNICODE *sub_key = NULL; DWORD type; PyObject *value_obj; - if (!_PyArg_ParseStack(args, nargs, "O&O&kU:SetValue", - clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &type, &value_obj)) { + if (!_PyArg_CheckPositional("SetValue", nargs, 4, 4)) { goto exit; } + if (!clinic_HKEY_converter(args[0], &key)) { + goto exit; + } + if (args[1] == Py_None) { + sub_key = NULL; + } + else if (PyUnicode_Check(args[1])) { + sub_key = PyUnicode_AsWideCharString(args[1], NULL); + if (sub_key == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("SetValue", "argument 2", "str or None", args[1]); + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[2], &type)) { + goto exit; + } + if (!PyUnicode_Check(args[3])) { + _PyArg_BadArgument("SetValue", "argument 4", "str", args[3]); + goto exit; + } + if (PyUnicode_READY(args[3]) == -1) { + goto exit; + } + value_obj = args[3]; return_value = winreg_SetValue_impl(module, key, sub_key, type, value_obj); exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -1213,7 +1428,7 @@ PyDoc_STRVAR(winreg_SetValueEx__doc__, "the configuration registry to help the registry perform efficiently."); #define WINREG_SETVALUEEX_METHODDEF \ - {"SetValueEx", (PyCFunction)(void(*)(void))winreg_SetValueEx, METH_FASTCALL, winreg_SetValueEx__doc__}, + {"SetValueEx", _PyCFunction_CAST(winreg_SetValueEx), METH_FASTCALL, winreg_SetValueEx__doc__}, static PyObject * winreg_SetValueEx_impl(PyObject *module, HKEY key, @@ -1225,22 +1440,40 @@ winreg_SetValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HKEY key; - const Py_UNICODE *value_name; + const Py_UNICODE *value_name = NULL; PyObject *reserved; DWORD type; PyObject *value; - if (!_PyArg_ParseStack(args, nargs, "O&O&OkO:SetValueEx", - clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &value_name, &reserved, &type, &value)) { + if (!_PyArg_CheckPositional("SetValueEx", nargs, 5, 5)) { goto exit; } + if (!clinic_HKEY_converter(args[0], &key)) { + goto exit; + } + if (args[1] == Py_None) { + value_name = NULL; + } + else if (PyUnicode_Check(args[1])) { + value_name = PyUnicode_AsWideCharString(args[1], NULL); + if (value_name == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("SetValueEx", "argument 2", "str or None", args[1]); + goto exit; + } + reserved = args[2]; + if (!_PyLong_UnsignedLong_Converter(args[3], &type)) { + goto exit; + } + value = args[4]; return_value = winreg_SetValueEx_impl(module, key, value_name, reserved, type, value); exit: /* Cleanup for value_name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)value_name); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -1346,4 +1579,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=497a2e804821d5c9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7e817dc5edc914d3 input=a9049054013a1b77]*/ diff --git a/PC/clinic/winsound.c.h b/PC/clinic/winsound.c.h index c5458990baa..241d547c267 100644 --- a/PC/clinic/winsound.c.h +++ b/PC/clinic/winsound.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(winsound_PlaySound__doc__, "PlaySound($module, /, sound, flags)\n" "--\n" @@ -14,7 +20,7 @@ PyDoc_STRVAR(winsound_PlaySound__doc__, " Flag values, ored together. See module documentation."); #define WINSOUND_PLAYSOUND_METHODDEF \ - {"PlaySound", (PyCFunction)(void(*)(void))winsound_PlaySound, METH_FASTCALL|METH_KEYWORDS, winsound_PlaySound__doc__}, + {"PlaySound", _PyCFunction_CAST(winsound_PlaySound), METH_FASTCALL|METH_KEYWORDS, winsound_PlaySound__doc__}, static PyObject * winsound_PlaySound_impl(PyObject *module, PyObject *sound, int flags); @@ -23,8 +29,31 @@ static PyObject * winsound_PlaySound(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sound), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sound", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "PlaySound", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "PlaySound", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *sound; int flags; @@ -57,7 +86,7 @@ PyDoc_STRVAR(winsound_Beep__doc__, " How long the sound should play, in milliseconds."); #define WINSOUND_BEEP_METHODDEF \ - {"Beep", (PyCFunction)(void(*)(void))winsound_Beep, METH_FASTCALL|METH_KEYWORDS, winsound_Beep__doc__}, + {"Beep", _PyCFunction_CAST(winsound_Beep), METH_FASTCALL|METH_KEYWORDS, winsound_Beep__doc__}, static PyObject * winsound_Beep_impl(PyObject *module, int frequency, int duration); @@ -66,8 +95,31 @@ static PyObject * winsound_Beep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(frequency), &_Py_ID(duration), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"frequency", "duration", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Beep", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Beep", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int frequency; int duration; @@ -99,7 +151,7 @@ PyDoc_STRVAR(winsound_MessageBeep__doc__, "x defaults to MB_OK."); #define WINSOUND_MESSAGEBEEP_METHODDEF \ - {"MessageBeep", (PyCFunction)(void(*)(void))winsound_MessageBeep, METH_FASTCALL|METH_KEYWORDS, winsound_MessageBeep__doc__}, + {"MessageBeep", _PyCFunction_CAST(winsound_MessageBeep), METH_FASTCALL|METH_KEYWORDS, winsound_MessageBeep__doc__}, static PyObject * winsound_MessageBeep_impl(PyObject *module, int type); @@ -108,8 +160,31 @@ static PyObject * winsound_MessageBeep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(type), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"type", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "MessageBeep", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "MessageBeep", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int type = MB_OK; @@ -131,4 +206,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=16b3c1a96861cd3a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f70b7730127208d8 input=a9049054013a1b77]*/ diff --git a/PC/config_minimal.c b/PC/config_minimal.c index adb1c44a724..928a4efd32e 100644 --- a/PC/config_minimal.c +++ b/PC/config_minimal.c @@ -5,6 +5,10 @@ #include "Python.h" +/* Define extern variables omitted from minimal builds */ +void *PyWin_DLLhModule = NULL; + + extern PyObject* PyInit_faulthandler(void); extern PyObject* PyInit__tracemalloc(void); extern PyObject* PyInit_gc(void); diff --git a/PC/empty.c b/PC/empty.c deleted file mode 100644 index 846b4d0d646..00000000000 --- a/PC/empty.c +++ /dev/null @@ -1,6 +0,0 @@ -#include -int __stdcall -WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) -{ - return 0; -} \ No newline at end of file diff --git a/PC/errmap.mak b/PC/errmap.mak deleted file mode 100644 index 646bcd0a209..00000000000 --- a/PC/errmap.mak +++ /dev/null @@ -1,5 +0,0 @@ -errmap.h: generrmap.exe - .\generrmap.exe > errmap.h - -genermap.exe: generrmap.c - cl generrmap.c diff --git a/PC/getpathp.c b/PC/getpathp.c deleted file mode 100644 index a27348024d2..00000000000 --- a/PC/getpathp.c +++ /dev/null @@ -1,1174 +0,0 @@ - -/* Return the initial module search path. */ -/* Used by DOS, Windows 3.1, Windows 95/98, Windows NT. */ - -/* ---------------------------------------------------------------- - PATH RULES FOR WINDOWS: - This describes how sys.path is formed on Windows. It describes the - functionality, not the implementation (ie, the order in which these - are actually fetched is different). The presence of a python._pth or - pythonXY._pth file alongside the program overrides these rules - see - below. - - * Python always adds an empty entry at the start, which corresponds - to the current directory. - - * If the PYTHONPATH env. var. exists, its entries are added next. - - * We look in the registry for "application paths" - that is, sub-keys - under the main PythonPath registry key. These are added next (the - order of sub-key processing is undefined). - HKEY_CURRENT_USER is searched and added first. - HKEY_LOCAL_MACHINE is searched and added next. - (Note that all known installers only use HKLM, so HKCU is typically - empty) - - * We attempt to locate the "Python Home" - if the PYTHONHOME env var - is set, we believe it. Otherwise, we use the path of our host .EXE's - to try and locate one of our "landmarks" and deduce our home. - - If we DO have a Python Home: The relevant sub-directories (Lib, - DLLs, etc) are based on the Python Home - - If we DO NOT have a Python Home, the core Python Path is - loaded from the registry. (This is the main PythonPath key, - and both HKLM and HKCU are combined to form the path) - - * Iff - we can not locate the Python Home, have not had a PYTHONPATH - specified, and can't locate any Registry entries (ie, we have _nothing_ - we can assume is a good path), a default path with relative entries is - used (eg. .\Lib;.\DLLs, etc) - - - If a '._pth' file exists adjacent to the executable with the same base name - (e.g. python._pth adjacent to python.exe) or adjacent to the shared library - (e.g. python36._pth adjacent to python36.dll), it is used in preference to - the above process. The shared library file takes precedence over the - executable. The path file must contain a list of paths to add to sys.path, - one per line. Each path is relative to the directory containing the file. - Blank lines and comments beginning with '#' are permitted. - - In the presence of this ._pth file, no other paths are added to the search - path, the registry finder is not enabled, site.py is not imported and - isolated mode is enabled. The site package can be enabled by including a - line reading "import site"; no other imports are recognized. Any invalid - entry (other than directories that do not exist) will result in immediate - termination of the program. - - - The end result of all this is: - * When running python.exe, or any other .exe in the main Python directory - (either an installed version, or directly from the PCbuild directory), - the core path is deduced, and the core paths in the registry are - ignored. Other "application paths" in the registry are always read. - - * When Python is hosted in another exe (different directory, embedded via - COM, etc), the Python Home will not be deduced, so the core path from - the registry is used. Other "application paths" in the registry are - always read. - - * If Python can't find its home and there is no registry (eg, frozen - exe, some very strange installation setup) you get a path with - some default, but relative, paths. - - * An embedding application can use Py_SetPath() to override all of - these automatic path computations. - - * An install of Python can fully specify the contents of sys.path using - either a 'EXENAME._pth' or 'DLLNAME._pth' file, optionally including - "import site" to enable the site module. - - ---------------------------------------------------------------- */ - - -#include "Python.h" -#include "pycore_fileutils.h" // _Py_add_relfile() -#include "pycore_initconfig.h" // PyStatus -#include "pycore_pathconfig.h" // _PyPathConfig -#include "osdefs.h" // SEP, ALTSEP -#include - -#ifndef MS_WINDOWS -#error getpathp.c should only be built on Windows -#endif - -#include -#include - -#ifdef HAVE_SYS_TYPES_H -#include -#endif /* HAVE_SYS_TYPES_H */ - -#ifdef HAVE_SYS_STAT_H -#include -#endif /* HAVE_SYS_STAT_H */ - -#include - -/* Search in some common locations for the associated Python libraries. - * - * Py_GetPath() tries to return a sensible Python module search path. - * - * The approach is an adaptation for Windows of the strategy used in - * ../Modules/getpath.c; it uses the Windows Registry as one of its - * information sources. - * - * Py_SetPath() can be used to override this mechanism. Call Py_SetPath - * with a semicolon separated path prior to calling Py_Initialize. - */ - -#define STDLIB_SUBDIR L"lib" - -#define INIT_ERR_BUFFER_OVERFLOW() _PyStatus_ERR("buffer overflow") - - -typedef struct { - const wchar_t *path_env; /* PATH environment variable */ - const wchar_t *home; /* PYTHONHOME environment variable */ - - /* Registry key "Software\Python\PythonCore\X.Y\PythonPath" - where X.Y is the Python version (major.minor) */ - wchar_t *machine_path; /* from HKEY_LOCAL_MACHINE */ - wchar_t *user_path; /* from HKEY_CURRENT_USER */ - - const wchar_t *pythonpath_env; -} PyCalculatePath; - - -/* determine if "ch" is a separator character */ -static int -is_sep(wchar_t ch) -{ -#ifdef ALTSEP - return ch == SEP || ch == ALTSEP; -#else - return ch == SEP; -#endif -} - - -/* assumes 'dir' null terminated in bounds. Never writes - beyond existing terminator. */ -static void -reduce(wchar_t *dir) -{ - size_t i = wcsnlen_s(dir, MAXPATHLEN+1); - if (i >= MAXPATHLEN+1) { - Py_FatalError("buffer overflow in getpathp.c's reduce()"); - } - - while (i > 0 && !is_sep(dir[i])) - --i; - dir[i] = '\0'; -} - - -static int -change_ext(wchar_t *dest, const wchar_t *src, const wchar_t *ext) -{ - if (src && src != dest) { - size_t src_len = wcsnlen_s(src, MAXPATHLEN+1); - size_t i = src_len; - if (i >= MAXPATHLEN+1) { - Py_FatalError("buffer overflow in getpathp.c's reduce()"); - } - - while (i > 0 && src[i] != '.' && !is_sep(src[i])) - --i; - - if (i == 0) { - dest[0] = '\0'; - return -1; - } - - if (is_sep(src[i])) { - i = src_len; - } - - if (wcsncpy_s(dest, MAXPATHLEN+1, src, i)) { - dest[0] = '\0'; - return -1; - } - } else { - wchar_t *s = wcsrchr(dest, L'.'); - if (s) { - s[0] = '\0'; - } - } - - if (wcscat_s(dest, MAXPATHLEN+1, ext)) { - dest[0] = '\0'; - return -1; - } - - return 0; -} - - -static int -exists(const wchar_t *filename) -{ - return GetFileAttributesW(filename) != 0xFFFFFFFF; -} - - -/* Is module -- check for .pyc too. - Assumes 'filename' MAXPATHLEN+1 bytes long - - may extend 'filename' by one character. */ -static int -ismodule(wchar_t *filename) -{ - size_t n; - - if (exists(filename)) { - return 1; - } - - /* Check for the compiled version of prefix. */ - n = wcsnlen_s(filename, MAXPATHLEN+1); - if (n < MAXPATHLEN) { - int exist = 0; - filename[n] = L'c'; - filename[n + 1] = L'\0'; - exist = exists(filename); - // Drop the 'c' we just added. - filename[n] = L'\0'; - return exist; - } - return 0; -} - - -/* Add a path component, by appending stuff to buffer. - buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a - NUL-terminated string with no more than MAXPATHLEN characters (not counting - the trailing NUL). It's a fatal error if it contains a string longer than - that (callers must be careful!). If these requirements are met, it's - guaranteed that buffer will still be a NUL-terminated string with no more - than MAXPATHLEN characters at exit. If stuff is too long, only as much of - stuff as fits will be appended. -*/ - -static void -join(wchar_t *buffer, const wchar_t *stuff) -{ - if (_Py_add_relfile(buffer, stuff, MAXPATHLEN+1) < 0) { - Py_FatalError("buffer overflow in getpathp.c's join()"); - } -} - -/* Call PathCchCanonicalizeEx(path): remove navigation elements such as "." - and ".." to produce a direct, well-formed path. */ -static PyStatus -canonicalize(wchar_t *buffer, const wchar_t *path) -{ - if (buffer == NULL) { - return _PyStatus_NO_MEMORY(); - } - - const wchar_t *pathTail; - if (FAILED(PathCchSkipRoot(path, &pathTail)) || path == pathTail) { - wchar_t buff[MAXPATHLEN + 1]; - if (!GetCurrentDirectoryW(MAXPATHLEN, buff)) { - return _PyStatus_ERR("unable to find current working directory"); - } - if (FAILED(PathCchCombineEx(buff, MAXPATHLEN + 1, buff, path, PATHCCH_ALLOW_LONG_PATHS))) { - return INIT_ERR_BUFFER_OVERFLOW(); - } - if (FAILED(PathCchCanonicalizeEx(buffer, MAXPATHLEN + 1, buff, PATHCCH_ALLOW_LONG_PATHS))) { - return INIT_ERR_BUFFER_OVERFLOW(); - } - return _PyStatus_OK(); - } - - if (FAILED(PathCchCanonicalizeEx(buffer, MAXPATHLEN + 1, path, PATHCCH_ALLOW_LONG_PATHS))) { - return INIT_ERR_BUFFER_OVERFLOW(); - } - return _PyStatus_OK(); -} - -static int -is_stdlibdir(wchar_t *stdlibdir) -{ - wchar_t *filename = stdlibdir; -#ifndef LANDMARK -# define LANDMARK L"os.py" -#endif - /* join() ensures 'landmark' can not overflow prefix if too long. */ - join(filename, LANDMARK); - return ismodule(filename); -} - -/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd. - assumption provided by only caller, calculate_path() */ -static int -search_for_prefix(wchar_t *prefix, const wchar_t *argv0_path) -{ - /* Search from argv0_path, until LANDMARK is found. - We guarantee 'prefix' is null terminated in bounds. */ - wcscpy_s(prefix, MAXPATHLEN+1, argv0_path); - if (!prefix[0]) { - return 0; - } - wchar_t stdlibdir[MAXPATHLEN+1]; - wcscpy_s(stdlibdir, Py_ARRAY_LENGTH(stdlibdir), prefix); - /* We initialize with the longest possible path, in case it doesn't fit. - This also gives us an initial SEP at stdlibdir[wcslen(prefix)]. */ - join(stdlibdir, STDLIB_SUBDIR); - do { - assert(stdlibdir[wcslen(prefix)] == SEP); - /* Due to reduce() and our initial value, this result - is guaranteed to fit. */ - wcscpy(&stdlibdir[wcslen(prefix) + 1], STDLIB_SUBDIR); - if (is_stdlibdir(stdlibdir)) { - return 1; - } - reduce(prefix); - } while (prefix[0]); - return 0; -} - - -static int -get_dllpath(wchar_t *dllpath) -{ -#ifdef Py_ENABLE_SHARED - extern HANDLE PyWin_DLLhModule; - if (PyWin_DLLhModule && GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN)) { - return 0; - } -#endif - return -1; -} - - -#ifdef Py_ENABLE_SHARED - -/* a string loaded from the DLL at startup.*/ -extern const char *PyWin_DLLVersionString; - -/* Load a PYTHONPATH value from the registry. - Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER. - - Works in both Unicode and 8bit environments. Only uses the - Ex family of functions so it also works with Windows CE. - - Returns NULL, or a pointer that should be freed. - - XXX - this code is pretty strange, as it used to also - work on Win16, where the buffer sizes were not available - in advance. It could be simplied now Win16/Win32s is dead! -*/ -static wchar_t * -getpythonregpath(HKEY keyBase, int skipcore) -{ - HKEY newKey = 0; - DWORD dataSize = 0; - DWORD numKeys = 0; - LONG rc; - wchar_t *retval = NULL; - WCHAR *dataBuf = NULL; - static const WCHAR keyPrefix[] = L"Software\\Python\\PythonCore\\"; - static const WCHAR keySuffix[] = L"\\PythonPath"; - size_t versionLen, keyBufLen; - DWORD index; - WCHAR *keyBuf = NULL; - WCHAR *keyBufPtr; - WCHAR **ppPaths = NULL; - - /* Tried to use sysget("winver") but here is too early :-( */ - versionLen = strlen(PyWin_DLLVersionString); - /* Space for all the chars, plus one \0 */ - keyBufLen = sizeof(keyPrefix) + - sizeof(WCHAR)*(versionLen-1) + - sizeof(keySuffix); - keyBuf = keyBufPtr = PyMem_RawMalloc(keyBufLen); - if (keyBuf==NULL) { - goto done; - } - - memcpy_s(keyBufPtr, keyBufLen, keyPrefix, sizeof(keyPrefix)-sizeof(WCHAR)); - keyBufPtr += Py_ARRAY_LENGTH(keyPrefix) - 1; - mbstowcs(keyBufPtr, PyWin_DLLVersionString, versionLen); - keyBufPtr += versionLen; - /* NULL comes with this one! */ - memcpy(keyBufPtr, keySuffix, sizeof(keySuffix)); - /* Open the root Python key */ - rc=RegOpenKeyExW(keyBase, - keyBuf, /* subkey */ - 0, /* reserved */ - KEY_READ, - &newKey); - if (rc!=ERROR_SUCCESS) { - goto done; - } - /* Find out how big our core buffer is, and how many subkeys we have */ - rc = RegQueryInfoKeyW(newKey, NULL, NULL, NULL, &numKeys, NULL, NULL, - NULL, NULL, &dataSize, NULL, NULL); - if (rc!=ERROR_SUCCESS) { - goto done; - } - if (skipcore) { - dataSize = 0; /* Only count core ones if we want them! */ - } - /* Allocate a temp array of char buffers, so we only need to loop - reading the registry once - */ - ppPaths = PyMem_RawCalloc(numKeys, sizeof(WCHAR *)); - if (ppPaths==NULL) { - goto done; - } - /* Loop over all subkeys, allocating a temp sub-buffer. */ - for(index=0;index 0) { - *(szCur++) = L';'; - dataSize--; - } - if (ppPaths[index]) { - Py_ssize_t len = wcslen(ppPaths[index]); - wcsncpy(szCur, ppPaths[index], len); - szCur += len; - assert(dataSize > (DWORD)len); - dataSize -= (DWORD)len; - } - } - if (skipcore) { - *szCur = '\0'; - } - else { - /* If we have no values, we don't need a ';' */ - if (numKeys) { - *(szCur++) = L';'; - dataSize--; - } - /* Now append the core path entries - - this will include the NULL - */ - rc = RegQueryValueExW(newKey, NULL, 0, NULL, - (LPBYTE)szCur, &dataSize); - if (rc != ERROR_SUCCESS) { - PyMem_RawFree(dataBuf); - goto done; - } - } - /* And set the result - caller must free */ - retval = dataBuf; - } -done: - /* Loop freeing my temp buffers */ - if (ppPaths) { - for(index=0; indexbase_executable == NULL) { - pathconfig->base_executable = PyMem_RawMalloc( - sizeof(wchar_t) * (MAXPATHLEN + 1)); - if (pathconfig->base_executable == NULL) { - return _PyStatus_NO_MEMORY(); - } - - status = canonicalize(pathconfig->base_executable, - program_full_path); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - wcscpy_s(program_full_path, MAXPATHLEN+1, pyvenv_launcher); - /* bpo-35873: Clear the environment variable to avoid it being - * inherited by child processes. */ - _wputenv_s(L"__PYVENV_LAUNCHER__", L""); - } - - if (pathconfig->program_full_path == NULL) { - pathconfig->program_full_path = PyMem_RawMalloc( - sizeof(wchar_t) * (MAXPATHLEN + 1)); - if (pathconfig->program_full_path == NULL) { - return _PyStatus_NO_MEMORY(); - } - - status = canonicalize(pathconfig->program_full_path, - program_full_path); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - return _PyStatus_OK(); -} - - -static PyStatus -read_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix, const wchar_t *path, - int *found) -{ - PyStatus status; - wchar_t *buf = NULL; - wchar_t *wline = NULL; - FILE *sp_file; - - sp_file = _Py_wfopen(path, L"r"); - if (sp_file == NULL) { - return _PyStatus_OK(); - } - - wcscpy_s(prefix, MAXPATHLEN+1, path); - reduce(prefix); - pathconfig->isolated = 1; - pathconfig->site_import = 0; - - size_t bufsiz = MAXPATHLEN; - size_t prefixlen = wcslen(prefix); - - buf = (wchar_t*)PyMem_RawMalloc(bufsiz * sizeof(wchar_t)); - if (buf == NULL) { - status = _PyStatus_NO_MEMORY(); - goto done; - } - buf[0] = '\0'; - - while (!feof(sp_file)) { - char line[MAXPATHLEN + 1]; - char *p = fgets(line, Py_ARRAY_LENGTH(line), sp_file); - if (!p) { - break; - } - if (*p == '\0' || *p == '\r' || *p == '\n' || *p == '#') { - continue; - } - while (*++p) { - if (*p == '\r' || *p == '\n') { - *p = '\0'; - break; - } - } - - if (strcmp(line, "import site") == 0) { - pathconfig->site_import = 1; - continue; - } - else if (strncmp(line, "import ", 7) == 0) { - status = _PyStatus_ERR("only 'import site' is supported " - "in ._pth file"); - goto done; - } - - DWORD wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, NULL, 0); - wchar_t *wline = (wchar_t*)PyMem_RawMalloc((wn + 1) * sizeof(wchar_t)); - if (wline == NULL) { - status = _PyStatus_NO_MEMORY(); - goto done; - } - wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, wline, wn + 1); - wline[wn] = '\0'; - - size_t usedsiz = wcslen(buf); - while (usedsiz + wn + prefixlen + 4 > bufsiz) { - bufsiz += MAXPATHLEN; - wchar_t *tmp = (wchar_t*)PyMem_RawRealloc(buf, (bufsiz + 1) * - sizeof(wchar_t)); - if (tmp == NULL) { - status = _PyStatus_NO_MEMORY(); - goto done; - } - buf = tmp; - } - - if (usedsiz) { - wcscat_s(buf, bufsiz, L";"); - usedsiz += 1; - } - - errno_t result; - _Py_BEGIN_SUPPRESS_IPH - result = wcscat_s(buf, bufsiz, prefix); - _Py_END_SUPPRESS_IPH - - if (result == EINVAL) { - status = _PyStatus_ERR("invalid argument during ._pth processing"); - goto done; - } else if (result == ERANGE) { - status = _PyStatus_ERR("buffer overflow during ._pth processing"); - goto done; - } - - wchar_t *b = &buf[usedsiz]; - join(b, wline); - - PyMem_RawFree(wline); - wline = NULL; - } - - if (pathconfig->module_search_path == NULL) { - pathconfig->module_search_path = _PyMem_RawWcsdup(buf); - if (pathconfig->module_search_path == NULL) { - status = _PyStatus_NO_MEMORY(); - goto done; - } - } - - *found = 1; - status = _PyStatus_OK(); - goto done; - -done: - PyMem_RawFree(buf); - PyMem_RawFree(wline); - fclose(sp_file); - return status; -} - - -static int -get_pth_filename(PyCalculatePath *calculate, wchar_t *filename, - const _PyPathConfig *pathconfig) -{ - if (!get_dllpath(filename) && - !change_ext(filename, filename, L"._pth") && - exists(filename)) - { - return 1; - } - if (pathconfig->program_full_path[0] && - !change_ext(filename, pathconfig->program_full_path, L"._pth") && - exists(filename)) - { - return 1; - } - return 0; -} - - -static PyStatus -calculate_pth_file(PyCalculatePath *calculate, _PyPathConfig *pathconfig, - wchar_t *prefix, int *found) -{ - wchar_t filename[MAXPATHLEN+1]; - - if (!get_pth_filename(calculate, filename, pathconfig)) { - return _PyStatus_OK(); - } - - return read_pth_file(pathconfig, prefix, filename, found); -} - - -/* Search for an environment configuration file, first in the - executable's directory and then in the parent directory. - If found, open it for use when searching for prefixes. -*/ -static PyStatus -calculate_pyvenv_file(PyCalculatePath *calculate, - wchar_t *argv0_path, size_t argv0_path_len) -{ - wchar_t filename[MAXPATHLEN+1]; - const wchar_t *env_cfg = L"pyvenv.cfg"; - - /* Filename: / "pyvenv.cfg" */ - wcscpy_s(filename, MAXPATHLEN+1, argv0_path); - join(filename, env_cfg); - - FILE *env_file = _Py_wfopen(filename, L"r"); - if (env_file == NULL) { - errno = 0; - - /* Filename: / "pyvenv.cfg" */ - reduce(filename); - reduce(filename); - join(filename, env_cfg); - - env_file = _Py_wfopen(filename, L"r"); - if (env_file == NULL) { - errno = 0; - return _PyStatus_OK(); - } - } - - /* Look for a 'home' variable and set argv0_path to it, if found */ - wchar_t *home = NULL; - PyStatus status = _Py_FindEnvConfigValue(env_file, L"home", &home); - if (_PyStatus_EXCEPTION(status)) { - fclose(env_file); - return status; - } - if (home) { - wcscpy_s(argv0_path, argv0_path_len, home); - PyMem_RawFree(home); - } - fclose(env_file); - return _PyStatus_OK(); -} - - -static void -calculate_home_prefix(PyCalculatePath *calculate, - const wchar_t *argv0_path, - const wchar_t *zip_path, - wchar_t *prefix) -{ - if (calculate->home == NULL || *calculate->home == '\0') { - if (zip_path[0] && exists(zip_path)) { - wcscpy_s(prefix, MAXPATHLEN+1, zip_path); - reduce(prefix); - calculate->home = prefix; - } - else if (search_for_prefix(prefix, argv0_path)) { - calculate->home = prefix; - } - else { - calculate->home = NULL; - } - } - else { - wcscpy_s(prefix, MAXPATHLEN+1, calculate->home); - } -} - - -static PyStatus -calculate_module_search_path(PyCalculatePath *calculate, - _PyPathConfig *pathconfig, - const wchar_t *argv0_path, - wchar_t *prefix, - const wchar_t *zip_path) -{ - int skiphome = calculate->home==NULL ? 0 : 1; -#ifdef Py_ENABLE_SHARED - if (!Py_IgnoreEnvironmentFlag) { - calculate->machine_path = getpythonregpath(HKEY_LOCAL_MACHINE, - skiphome); - calculate->user_path = getpythonregpath(HKEY_CURRENT_USER, skiphome); - } -#endif - /* We only use the default relative PYTHONPATH if we haven't - anything better to use! */ - int skipdefault = (calculate->pythonpath_env != NULL || - calculate->home != NULL || - calculate->machine_path != NULL || - calculate->user_path != NULL); - - /* We need to construct a path from the following parts. - (1) the PYTHONPATH environment variable, if set; - (2) for Win32, the zip archive file path; - (3) for Win32, the machine_path and user_path, if set; - (4) the PYTHONPATH config macro, with the leading "." - of each component replaced with home, if set; - (5) the directory containing the executable (argv0_path). - The length calculation calculates #4 first. - Extra rules: - - If PYTHONHOME is set (in any way) item (3) is ignored. - - If registry values are used, (4) and (5) are ignored. - */ - - /* Calculate size of return buffer */ - size_t bufsz = 0; - if (calculate->home != NULL) { - const wchar_t *p; - bufsz = 1; - for (p = PYTHONPATH; *p; p++) { - if (*p == DELIM) { - bufsz++; /* number of DELIM plus one */ - } - } - bufsz *= wcslen(calculate->home); - } - bufsz += wcslen(PYTHONPATH) + 1; - bufsz += wcslen(argv0_path) + 1; - if (calculate->user_path) { - bufsz += wcslen(calculate->user_path) + 1; - } - if (calculate->machine_path) { - bufsz += wcslen(calculate->machine_path) + 1; - } - bufsz += wcslen(zip_path) + 1; - if (calculate->pythonpath_env != NULL) { - bufsz += wcslen(calculate->pythonpath_env) + 1; - } - - wchar_t *buf, *start_buf; - buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t)); - if (buf == NULL) { - return _PyStatus_NO_MEMORY(); - } - start_buf = buf; - - if (calculate->pythonpath_env) { - if (wcscpy_s(buf, bufsz - (buf - start_buf), - calculate->pythonpath_env)) { - return INIT_ERR_BUFFER_OVERFLOW(); - } - buf = wcschr(buf, L'\0'); - *buf++ = DELIM; - } - if (zip_path[0]) { - if (wcscpy_s(buf, bufsz - (buf - start_buf), zip_path)) { - return INIT_ERR_BUFFER_OVERFLOW(); - } - buf = wcschr(buf, L'\0'); - *buf++ = DELIM; - } - if (calculate->user_path) { - if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->user_path)) { - return INIT_ERR_BUFFER_OVERFLOW(); - } - buf = wcschr(buf, L'\0'); - *buf++ = DELIM; - } - if (calculate->machine_path) { - if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->machine_path)) { - return INIT_ERR_BUFFER_OVERFLOW(); - } - buf = wcschr(buf, L'\0'); - *buf++ = DELIM; - } - if (calculate->home == NULL) { - if (!skipdefault) { - if (wcscpy_s(buf, bufsz - (buf - start_buf), PYTHONPATH)) { - return INIT_ERR_BUFFER_OVERFLOW(); - } - buf = wcschr(buf, L'\0'); - *buf++ = DELIM; - } - } else { - const wchar_t *p = PYTHONPATH; - const wchar_t *q; - size_t n; - for (;;) { - q = wcschr(p, DELIM); - if (q == NULL) { - n = wcslen(p); - } - else { - n = q-p; - } - if (p[0] == '.' && is_sep(p[1])) { - if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->home)) { - return INIT_ERR_BUFFER_OVERFLOW(); - } - buf = wcschr(buf, L'\0'); - p++; - n--; - } - wcsncpy(buf, p, n); - buf += n; - *buf++ = DELIM; - if (q == NULL) { - break; - } - p = q+1; - } - } - if (argv0_path) { - wcscpy(buf, argv0_path); - buf = wcschr(buf, L'\0'); - *buf++ = DELIM; - } - *(buf - 1) = L'\0'; - - /* Now to pull one last hack/trick. If sys.prefix is - empty, then try and find it somewhere on the paths - we calculated. We scan backwards, as our general policy - is that Python core directories are at the *end* of - sys.path. We assume that our "lib" directory is - on the path, and that our 'prefix' directory is - the parent of that. - */ - if (prefix[0] == L'\0') { - PyStatus status; - wchar_t lookBuf[MAXPATHLEN+1]; - const wchar_t *look = buf - 1; /* 'buf' is at the end of the buffer */ - while (1) { - Py_ssize_t nchars; - const wchar_t *lookEnd = look; - /* 'look' will end up one character before the - start of the path in question - even if this - is one character before the start of the buffer - */ - while (look >= start_buf && *look != DELIM) - look--; - nchars = lookEnd-look; - wcsncpy(lookBuf, look+1, nchars); - lookBuf[nchars] = L'\0'; - status = canonicalize(lookBuf, lookBuf); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - /* Up one level to the parent */ - reduce(lookBuf); - if (search_for_prefix(prefix, lookBuf)) { - break; - } - /* If we are out of paths to search - give up */ - if (look < start_buf) { - break; - } - look--; - } - } - - pathconfig->module_search_path = start_buf; - return _PyStatus_OK(); -} - - -static PyStatus -calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig) -{ - PyStatus status; - - status = get_program_full_path(pathconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - /* program_full_path guaranteed \0 terminated in MAXPATH+1 bytes. */ - wchar_t argv0_path[MAXPATHLEN+1]; - memset(argv0_path, 0, sizeof(argv0_path)); - - wcscpy_s(argv0_path, MAXPATHLEN+1, pathconfig->program_full_path); - reduce(argv0_path); - - wchar_t prefix[MAXPATHLEN+1]; - memset(prefix, 0, sizeof(prefix)); - - /* Search for a sys.path file */ - int pth_found = 0; - status = calculate_pth_file(calculate, pathconfig, prefix, &pth_found); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - if (pth_found) { - goto done; - } - - status = calculate_pyvenv_file(calculate, - argv0_path, Py_ARRAY_LENGTH(argv0_path)); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - /* Calculate zip archive path from DLL or exe path */ - wchar_t zip_path[MAXPATHLEN+1]; - memset(zip_path, 0, sizeof(zip_path)); - - if (get_dllpath(zip_path) || change_ext(zip_path, zip_path, L".zip")) - { - if (change_ext(zip_path, pathconfig->program_full_path, L".zip")) { - zip_path[0] = L'\0'; - } - } - - calculate_home_prefix(calculate, argv0_path, zip_path, prefix); - - if (pathconfig->module_search_path == NULL) { - status = calculate_module_search_path(calculate, pathconfig, - argv0_path, prefix, zip_path); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - -done: - if (pathconfig->stdlib_dir == NULL) { - pathconfig->stdlib_dir = _Py_join_relfile(prefix, STDLIB_SUBDIR); - if (pathconfig->stdlib_dir == NULL) { - return _PyStatus_NO_MEMORY(); - } - } - if (pathconfig->prefix == NULL) { - pathconfig->prefix = _PyMem_RawWcsdup(prefix); - if (pathconfig->prefix == NULL) { - return _PyStatus_NO_MEMORY(); - } - } - if (pathconfig->exec_prefix == NULL) { - pathconfig->exec_prefix = _PyMem_RawWcsdup(prefix); - if (pathconfig->exec_prefix == NULL) { - return _PyStatus_NO_MEMORY(); - } - } - - return _PyStatus_OK(); -} - - -static PyStatus -calculate_init(PyCalculatePath *calculate, _PyPathConfig *pathconfig, - const PyConfig *config) -{ - calculate->home = pathconfig->home; - calculate->path_env = _wgetenv(L"PATH"); - - calculate->pythonpath_env = config->pythonpath_env; - - return _PyStatus_OK(); -} - - -static void -calculate_free(PyCalculatePath *calculate) -{ - PyMem_RawFree(calculate->machine_path); - PyMem_RawFree(calculate->user_path); -} - - -/* Calculate the Python path configuration. - - Inputs: - - - PyConfig.pythonpath_env: PYTHONPATH environment variable - - _PyPathConfig.home: Py_SetPythonHome() or PYTHONHOME environment variable - - PATH environment variable - - __PYVENV_LAUNCHER__ environment variable - - GetModuleFileNameW(NULL): fully qualified path of the executable file of - the current process - - ._pth configuration file - - pyvenv.cfg configuration file - - Registry key "Software\Python\PythonCore\X.Y\PythonPath" - of HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE where X.Y is the Python - version. - - Outputs, 'pathconfig' fields: - - - base_executable - - program_full_path - - module_search_path - - prefix - - exec_prefix - - isolated - - site_import - - If a field is already set (non NULL), it is left unchanged. */ -PyStatus -_PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config) -{ - PyStatus status; - PyCalculatePath calculate; - memset(&calculate, 0, sizeof(calculate)); - - status = calculate_init(&calculate, pathconfig, config); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - status = calculate_path(&calculate, pathconfig); - -done: - calculate_free(&calculate); - return status; -} - - -/* Load python3.dll before loading any extension module that might refer - to it. That way, we can be sure that always the python3.dll corresponding - to this python DLL is loaded, not a python3.dll that might be on the path - by chance. - Return whether the DLL was found. -*/ -static int python3_checked = 0; -static HANDLE hPython3; -int -_Py_CheckPython3(void) -{ - wchar_t py3path[MAXPATHLEN+1]; - if (python3_checked) { - return hPython3 != NULL; - } - python3_checked = 1; - - /* If there is a python3.dll next to the python3y.dll, - use that DLL */ - if (!get_dllpath(py3path)) { - reduce(py3path); - join(py3path, PY3_DLLNAME); - hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); - if (hPython3 != NULL) { - return 1; - } - } - - /* If we can locate python3.dll in our application dir, - use that DLL */ - hPython3 = LoadLibraryExW(PY3_DLLNAME, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR); - if (hPython3 != NULL) { - return 1; - } - - /* For back-compat, also search {sys.prefix}\DLLs, though - that has not been a normal install layout for a while */ - wcscpy(py3path, Py_GetPrefix()); - if (py3path[0]) { - join(py3path, L"DLLs\\" PY3_DLLNAME); - hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); - } - return hPython3 != NULL; -} diff --git a/PC/icons/logox128.png b/PC/icons/logox128.png index d2655c72e7d..a403de5818c 100644 Binary files a/PC/icons/logox128.png and b/PC/icons/logox128.png differ diff --git a/PC/icons/py.png b/PC/icons/py.png index 5c184e6a745..629022a70bd 100644 Binary files a/PC/icons/py.png and b/PC/icons/py.png differ diff --git a/PC/icons/pythonwx150.png b/PC/icons/pythonwx150.png index 4c3eb316739..589873aeb10 100644 Binary files a/PC/icons/pythonwx150.png and b/PC/icons/pythonwx150.png differ diff --git a/PC/icons/pythonwx44.png b/PC/icons/pythonwx44.png index e3b32a871f9..8cd8dd0286f 100644 Binary files a/PC/icons/pythonwx44.png and b/PC/icons/pythonwx44.png differ diff --git a/PC/icons/pythonx150.png b/PC/icons/pythonx150.png index 5f8d3041838..e00aa758edc 100644 Binary files a/PC/icons/pythonx150.png and b/PC/icons/pythonx150.png differ diff --git a/PC/icons/pythonx44.png b/PC/icons/pythonx44.png index 3881daaef23..db0e9b91d40 100644 Binary files a/PC/icons/pythonx44.png and b/PC/icons/pythonx44.png differ diff --git a/PC/icons/pythonx50.png b/PC/icons/pythonx50.png index 7cc3aecd024..8eb5ffce221 100644 Binary files a/PC/icons/pythonx50.png and b/PC/icons/pythonx50.png differ diff --git a/PC/launcher-usage.txt b/PC/launcher-usage.txt new file mode 100644 index 00000000000..aad103509da --- /dev/null +++ b/PC/launcher-usage.txt @@ -0,0 +1,31 @@ +Python Launcher for Windows Version %s + +usage: +%s [launcher-args] [python-args] [script [script-args]] + +Launcher arguments: +-2 : Launch the latest Python 2.x version +-3 : Launch the latest Python 3.x version +-X.Y : Launch the specified Python version + +The above default to an architecture native runtime, but will select any +available. Add a "-32" to the argument to only launch 32-bit runtimes, +or add "-64" to omit 32-bit runtimes (this latter option is deprecated). + +To select a specific runtime, use the -V: options. + +-V:TAG : Launch a Python runtime with the specified tag +-V:COMPANY/TAG : Launch a Python runtime from the specified company and + with the specified tag + +-0 --list : List the available pythons +-0p --list-paths : List with paths + +If no options are given but a script is specified, the script is checked for a +shebang line. Otherwise, an active virtual environment or global default will +be selected. + +See https://docs.python.org/using/windows.html#python-launcher-for-windows for +additional configuration. + +The following help text is from Python: diff --git a/PC/launcher.c b/PC/launcher.c index fbfb49ae857..da566a18016 100644 --- a/PC/launcher.c +++ b/PC/launcher.c @@ -344,7 +344,7 @@ _locate_pythons_for_key(HKEY root, LPCWSTR subkey, REGSAM flags, int bits, } else if (attrs & FILE_ATTRIBUTE_DIRECTORY) { debug(L"locate_pythons_for_key: '%ls' is a directory\n", - ip->executable, attrs); + ip->executable); } else if (find_existing_python(ip->executable)) { debug(L"locate_pythons_for_key: %ls: already found\n", @@ -542,8 +542,17 @@ find_python_by_version(wchar_t const * wanted_ver) } for (i = 0; i < num_installed_pythons; i++, ip++) { n = wcslen(ip->version); - if (n > wlen) + /* + * If wlen is greater than 1, we're probably trying to find a specific + * version and thus want an exact match: 3.1 != 3.10. Otherwise, we + * just want a prefix match. + */ + if ((wlen > 1) && (n != wlen)) { + continue; + } + if (n > wlen) { n = wlen; + } if ((wcsncmp(ip->version, wanted_ver, n) == 0) && /* bits == 0 => don't care */ ((bits == 0) || (ip->bits == bits))) { @@ -1259,7 +1268,9 @@ static PYC_MAGIC magic_values[] = { { 3400, 3419, L"3.8" }, { 3420, 3429, L"3.9" }, { 3430, 3449, L"3.10" }, - { 3450, 3469, L"3.11" }, + /* Allow 50 magic numbers per version from here on */ + { 3450, 3499, L"3.11" }, + { 3500, 3549, L"3.12" }, { 0 } }; @@ -1915,27 +1926,35 @@ process(int argc, wchar_t ** argv) if (!cch) { error(0, L"Cannot determine memory for home path"); } - cch += (DWORD)wcslen(PYTHON_EXECUTABLE) + 1 + 1; /* include sep and null */ + cch += (DWORD)wcslen(PYTHON_EXECUTABLE) + 4; /* include sep, null and quotes */ executable = (wchar_t *)malloc(cch * sizeof(wchar_t)); if (executable == NULL) { error(RC_NO_MEMORY, L"A memory allocation failed"); } - cch_actual = MultiByteToWideChar(CP_UTF8, 0, start, len, executable, cch); + /* start with a quote - we'll skip this ahead, but want it for the final string */ + executable[0] = L'"'; + cch_actual = MultiByteToWideChar(CP_UTF8, 0, start, len, &executable[1], cch - 1); if (!cch_actual) { error(RC_BAD_VENV_CFG, L"Cannot decode home path in '%ls'", venv_cfg_path); } + cch_actual += 1; /* account for the first quote */ + executable[cch_actual] = L'\0'; if (executable[cch_actual - 1] != L'\\') { executable[cch_actual++] = L'\\'; executable[cch_actual] = L'\0'; } - if (wcscat_s(executable, cch, PYTHON_EXECUTABLE)) { + if (wcscat_s(&executable[1], cch - 1, PYTHON_EXECUTABLE)) { error(RC_BAD_VENV_CFG, L"Cannot create executable path from '%ls'", venv_cfg_path); } - if (GetFileAttributesW(executable) == INVALID_FILE_ATTRIBUTES) { + /* there's no trailing quote, so we only have to skip one character for the test */ + if (GetFileAttributesW(&executable[1]) == INVALID_FILE_ATTRIBUTES) { error(RC_NO_PYTHON, L"No Python at '%ls'", executable); } + /* now append the final quote */ + wcscat_s(executable, cch, L"\""); + /* smuggle our original path through */ if (!SetEnvironmentVariableW(L"__PYVENV_LAUNCHER__", argv0)) { error(0, L"Failed to set launcher environment"); } diff --git a/PC/launcher2.c b/PC/launcher2.c new file mode 100644 index 00000000000..2052a2ffeb5 --- /dev/null +++ b/PC/launcher2.c @@ -0,0 +1,2666 @@ +/* + * Rewritten Python launcher for Windows + * + * This new rewrite properly handles PEP 514 and allows any registered Python + * runtime to be launched. It also enables auto-install of versions when they + * are requested but no installation can be found. + */ + +#define __STDC_WANT_LIB_EXT1__ 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MS_WINDOWS +#include "patchlevel.h" + +#define MAXLEN PATHCCH_MAX_CCH +#define MSGSIZE 1024 + +#define RC_NO_STD_HANDLES 100 +#define RC_CREATE_PROCESS 101 +#define RC_BAD_VIRTUAL_PATH 102 +#define RC_NO_PYTHON 103 +#define RC_NO_MEMORY 104 +#define RC_NO_SCRIPT 105 +#define RC_NO_VENV_CFG 106 +#define RC_BAD_VENV_CFG 107 +#define RC_NO_COMMANDLINE 108 +#define RC_INTERNAL_ERROR 109 +#define RC_DUPLICATE_ITEM 110 +#define RC_INSTALLING 111 +#define RC_NO_PYTHON_AT_ALL 112 +#define RC_NO_SHEBANG 113 +#define RC_RECURSIVE_SHEBANG 114 + +static FILE * log_fp = NULL; + +void +debug(wchar_t * format, ...) +{ + va_list va; + + if (log_fp != NULL) { + wchar_t buffer[MAXLEN]; + int r = 0; + va_start(va, format); + r = vswprintf_s(buffer, MAXLEN, format, va); + va_end(va); + + if (r <= 0) { + return; + } + fputws(buffer, log_fp); + while (r && isspace(buffer[r])) { + buffer[r--] = L'\0'; + } + if (buffer[0]) { + OutputDebugStringW(buffer); + } + } +} + + +void +formatWinerror(int rc, wchar_t * message, int size) +{ + FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + message, size, NULL); +} + + +void +winerror(int err, wchar_t * format, ... ) +{ + va_list va; + wchar_t message[MSGSIZE]; + wchar_t win_message[MSGSIZE]; + int len; + + if (err == 0) { + err = GetLastError(); + } + + va_start(va, format); + len = _vsnwprintf_s(message, MSGSIZE, _TRUNCATE, format, va); + va_end(va); + + formatWinerror(err, win_message, MSGSIZE); + if (len >= 0) { + _snwprintf_s(&message[len], MSGSIZE - len, _TRUNCATE, L": %s", + win_message); + } + +#if !defined(_WINDOWS) + fwprintf(stderr, L"%s\n", message); +#else + MessageBoxW(NULL, message, L"Python Launcher is sorry to say ...", + MB_OK); +#endif +} + + +void +error(wchar_t * format, ... ) +{ + va_list va; + wchar_t message[MSGSIZE]; + + va_start(va, format); + _vsnwprintf_s(message, MSGSIZE, _TRUNCATE, format, va); + va_end(va); + +#if !defined(_WINDOWS) + fwprintf(stderr, L"%s\n", message); +#else + MessageBoxW(NULL, message, L"Python Launcher is sorry to say ...", + MB_OK); +#endif +} + + +typedef BOOL (*PIsWow64Process2)(HANDLE, USHORT*, USHORT*); + + +USHORT +_getNativeMachine() +{ + static USHORT _nativeMachine = IMAGE_FILE_MACHINE_UNKNOWN; + if (_nativeMachine == IMAGE_FILE_MACHINE_UNKNOWN) { + USHORT processMachine; + HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll"); + PIsWow64Process2 IsWow64Process2 = kernel32 ? + (PIsWow64Process2)GetProcAddress(kernel32, "IsWow64Process2") : + NULL; + if (!IsWow64Process2) { + BOOL wow64Process; + if (!IsWow64Process(NULL, &wow64Process)) { + winerror(0, L"Checking process type"); + } else if (wow64Process) { + // We should always be a 32-bit executable, so if running + // under emulation, it must be a 64-bit host. + _nativeMachine = IMAGE_FILE_MACHINE_AMD64; + } else { + // Not running under emulation, and an old enough OS to not + // have IsWow64Process2, so assume it's x86. + _nativeMachine = IMAGE_FILE_MACHINE_I386; + } + } else if (!IsWow64Process2(NULL, &processMachine, &_nativeMachine)) { + winerror(0, L"Checking process type"); + } + } + return _nativeMachine; +} + + +bool +isAMD64Host() +{ + return _getNativeMachine() == IMAGE_FILE_MACHINE_AMD64; +} + + +bool +isARM64Host() +{ + return _getNativeMachine() == IMAGE_FILE_MACHINE_ARM64; +} + + +bool +isEnvVarSet(const wchar_t *name) +{ + /* only looking for non-empty, which means at least one character + and the null terminator */ + return GetEnvironmentVariableW(name, NULL, 0) >= 2; +} + + +bool +join(wchar_t *buffer, size_t bufferLength, const wchar_t *fragment) +{ + if (SUCCEEDED(PathCchCombineEx(buffer, bufferLength, buffer, fragment, PATHCCH_ALLOW_LONG_PATHS))) { + return true; + } + return false; +} + + +int +_compare(const wchar_t *x, int xLen, const wchar_t *y, int yLen) +{ + // Empty strings sort first + if (!x || !xLen) { + return (!y || !yLen) ? 0 : -1; + } else if (!y || !yLen) { + return 1; + } + switch (CompareStringEx( + LOCALE_NAME_INVARIANT, NORM_IGNORECASE | SORT_DIGITSASNUMBERS, + x, xLen, y, yLen, + NULL, NULL, 0 + )) { + case CSTR_LESS_THAN: + return -1; + case CSTR_EQUAL: + return 0; + case CSTR_GREATER_THAN: + return 1; + default: + winerror(0, L"Error comparing '%.*s' and '%.*s' (compare)", xLen, x, yLen, y); + return -1; + } +} + + +int +_compareArgument(const wchar_t *x, int xLen, const wchar_t *y, int yLen) +{ + // Empty strings sort first + if (!x || !xLen) { + return (!y || !yLen) ? 0 : -1; + } else if (!y || !yLen) { + return 1; + } + switch (CompareStringEx( + LOCALE_NAME_INVARIANT, 0, + x, xLen, y, yLen, + NULL, NULL, 0 + )) { + case CSTR_LESS_THAN: + return -1; + case CSTR_EQUAL: + return 0; + case CSTR_GREATER_THAN: + return 1; + default: + winerror(0, L"Error comparing '%.*s' and '%.*s' (compareArgument)", xLen, x, yLen, y); + return -1; + } +} + +int +_comparePath(const wchar_t *x, int xLen, const wchar_t *y, int yLen) +{ + // Empty strings sort first + if (!x || !xLen) { + return !y || !yLen ? 0 : -1; + } else if (!y || !yLen) { + return 1; + } + switch (CompareStringOrdinal(x, xLen, y, yLen, TRUE)) { + case CSTR_LESS_THAN: + return -1; + case CSTR_EQUAL: + return 0; + case CSTR_GREATER_THAN: + return 1; + default: + winerror(0, L"Error comparing '%.*s' and '%.*s' (comparePath)", xLen, x, yLen, y); + return -1; + } +} + + +bool +_startsWith(const wchar_t *x, int xLen, const wchar_t *y, int yLen) +{ + if (!x || !y) { + return false; + } + yLen = yLen < 0 ? (int)wcsnlen_s(y, MAXLEN) : yLen; + xLen = xLen < 0 ? (int)wcsnlen_s(x, MAXLEN) : xLen; + return xLen >= yLen && 0 == _compare(x, yLen, y, yLen); +} + + +bool +_startsWithArgument(const wchar_t *x, int xLen, const wchar_t *y, int yLen) +{ + if (!x || !y) { + return false; + } + yLen = yLen < 0 ? (int)wcsnlen_s(y, MAXLEN) : yLen; + xLen = xLen < 0 ? (int)wcsnlen_s(x, MAXLEN) : xLen; + return xLen >= yLen && 0 == _compareArgument(x, yLen, y, yLen); +} + + +/******************************************************************************\ + *** HELP TEXT *** +\******************************************************************************/ + + +int +showHelpText(wchar_t ** argv) +{ + // The help text is stored in launcher-usage.txt, which is compiled into + // the launcher and loaded at runtime if needed. + // + // The file must be UTF-8. There are two substitutions: + // %ls - PY_VERSION (as wchar_t*) + // %ls - argv[0] (as wchar_t*) + HRSRC res = FindResourceExW(NULL, L"USAGE", MAKEINTRESOURCE(1), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)); + HGLOBAL resData = res ? LoadResource(NULL, res) : NULL; + const char *usage = resData ? (const char*)LockResource(resData) : NULL; + if (usage == NULL) { + winerror(0, L"Unable to load usage text"); + return RC_INTERNAL_ERROR; + } + + DWORD cbData = SizeofResource(NULL, res); + DWORD cchUsage = MultiByteToWideChar(CP_UTF8, 0, usage, cbData, NULL, 0); + if (!cchUsage) { + winerror(0, L"Unable to preprocess usage text"); + return RC_INTERNAL_ERROR; + } + + cchUsage += 1; + wchar_t *wUsage = (wchar_t*)malloc(cchUsage * sizeof(wchar_t)); + cchUsage = MultiByteToWideChar(CP_UTF8, 0, usage, cbData, wUsage, cchUsage); + if (!cchUsage) { + winerror(0, L"Unable to preprocess usage text"); + free((void *)wUsage); + return RC_INTERNAL_ERROR; + } + // Ensure null termination + wUsage[cchUsage] = L'\0'; + + fwprintf(stdout, wUsage, (L"" PY_VERSION), argv[0]); + fflush(stdout); + + free((void *)wUsage); + + return 0; +} + + +/******************************************************************************\ + *** SEARCH INFO *** +\******************************************************************************/ + + +struct _SearchInfoBuffer { + struct _SearchInfoBuffer *next; + wchar_t buffer[0]; +}; + + +typedef struct { + // the original string, managed by the OS + const wchar_t *originalCmdLine; + // pointer into the cmdline to mark what we've consumed + const wchar_t *restOfCmdLine; + // if known/discovered, the full executable path of our runtime + const wchar_t *executablePath; + // pointer and length into cmdline for the file to check for a + // shebang line, if any. Length can be -1 if the string is null + // terminated. + const wchar_t *scriptFile; + int scriptFileLength; + // pointer and length into cmdline or a static string with the + // name of the target executable. Length can be -1 if the string + // is null terminated. + const wchar_t *executable; + int executableLength; + // pointer and length into a string with additional interpreter + // arguments to include before restOfCmdLine. Length can be -1 if + // the string is null terminated. + const wchar_t *executableArgs; + int executableArgsLength; + // pointer and length into cmdline or a static string with the + // company name for PEP 514 lookup. Length can be -1 if the string + // is null terminated. + const wchar_t *company; + int companyLength; + // pointer and length into cmdline or a static string with the + // tag for PEP 514 lookup. Length can be -1 if the string is + // null terminated. + const wchar_t *tag; + int tagLength; + // if true, treats 'tag' as a non-PEP 514 filter + bool oldStyleTag; + // if true, ignores 'tag' when a high priority environment is found + // gh-92817: This is currently set when a tag is read from configuration or + // the environment, rather than the command line or a shebang line, and the + // only currently possible high priority environment is an active virtual + // environment + bool lowPriorityTag; + // if true, allow PEP 514 lookup to override 'executable' + bool allowExecutableOverride; + // if true, allow a nearby pyvenv.cfg to locate the executable + bool allowPyvenvCfg; + // if true, allow defaults (env/py.ini) to clarify/override tags + bool allowDefaults; + // if true, prefer windowed (console-less) executable + bool windowed; + // if true, only list detected runtimes without launching + bool list; + // if true, only list detected runtimes with paths without launching + bool listPaths; + // if true, display help message before contiuning + bool help; + // dynamically allocated buffers to free later + struct _SearchInfoBuffer *_buffer; +} SearchInfo; + + +wchar_t * +allocSearchInfoBuffer(SearchInfo *search, int wcharCount) +{ + struct _SearchInfoBuffer *buffer = (struct _SearchInfoBuffer*)malloc( + sizeof(struct _SearchInfoBuffer) + + wcharCount * sizeof(wchar_t) + ); + if (!buffer) { + return NULL; + } + buffer->next = search->_buffer; + search->_buffer = buffer; + return buffer->buffer; +} + + +void +freeSearchInfo(SearchInfo *search) +{ + struct _SearchInfoBuffer *b = search->_buffer; + search->_buffer = NULL; + while (b) { + struct _SearchInfoBuffer *nextB = b->next; + free((void *)b); + b = nextB; + } +} + + +void +_debugStringAndLength(const wchar_t *s, int len, const wchar_t *name) +{ + if (!s) { + debug(L"%s: (null)\n", name); + } else if (len == 0) { + debug(L"%s: (empty)\n", name); + } else if (len < 0) { + debug(L"%s: %s\n", name, s); + } else { + debug(L"%s: %.*ls\n", name, len, s); + } +} + + +void +dumpSearchInfo(SearchInfo *search) +{ + if (!log_fp) { + return; + } + +#ifdef __clang__ +#define DEBUGNAME(s) L # s +#else +#define DEBUGNAME(s) # s +#endif +#define DEBUG(s) debug(L"SearchInfo." DEBUGNAME(s) L": %s\n", (search->s) ? (search->s) : L"(null)") +#define DEBUG_2(s, sl) _debugStringAndLength((search->s), (search->sl), L"SearchInfo." DEBUGNAME(s)) +#define DEBUG_BOOL(s) debug(L"SearchInfo." DEBUGNAME(s) L": %s\n", (search->s) ? L"True" : L"False") + DEBUG(originalCmdLine); + DEBUG(restOfCmdLine); + DEBUG(executablePath); + DEBUG_2(scriptFile, scriptFileLength); + DEBUG_2(executable, executableLength); + DEBUG_2(executableArgs, executableArgsLength); + DEBUG_2(company, companyLength); + DEBUG_2(tag, tagLength); + DEBUG_BOOL(oldStyleTag); + DEBUG_BOOL(lowPriorityTag); + DEBUG_BOOL(allowDefaults); + DEBUG_BOOL(allowExecutableOverride); + DEBUG_BOOL(windowed); + DEBUG_BOOL(list); + DEBUG_BOOL(listPaths); + DEBUG_BOOL(help); +#undef DEBUG_BOOL +#undef DEBUG_2 +#undef DEBUG +#undef DEBUGNAME +} + + +int +findArgv0Length(const wchar_t *buffer, int bufferLength) +{ + // Note: this implements semantics that are only valid for argv0. + // Specifically, there is no escaping of quotes, and quotes within + // the argument have no effect. A quoted argv0 must start and end + // with a double quote character; otherwise, it ends at the first + // ' ' or '\t'. + int quoted = buffer[0] == L'"'; + for (int i = 1; bufferLength < 0 || i < bufferLength; ++i) { + switch (buffer[i]) { + case L'\0': + return i; + case L' ': + case L'\t': + if (!quoted) { + return i; + } + break; + case L'"': + if (quoted) { + return i + 1; + } + break; + } + } + return bufferLength; +} + + +const wchar_t * +findArgv0End(const wchar_t *buffer, int bufferLength) +{ + return &buffer[findArgv0Length(buffer, bufferLength)]; +} + + +/******************************************************************************\ + *** COMMAND-LINE PARSING *** +\******************************************************************************/ + + +int +parseCommandLine(SearchInfo *search) +{ + if (!search || !search->originalCmdLine) { + return RC_NO_COMMANDLINE; + } + + const wchar_t *argv0End = findArgv0End(search->originalCmdLine, -1); + const wchar_t *tail = argv0End; // will be start of the executable name + const wchar_t *end = argv0End; // will be end of the executable name + search->restOfCmdLine = argv0End; // will be first space after argv0 + while (--tail != search->originalCmdLine) { + if (*tail == L'"' && end == argv0End) { + // Move the "end" up to the quote, so we also allow moving for + // a period later on. + end = argv0End = tail; + } else if (*tail == L'.' && end == argv0End) { + end = tail; + } else if (*tail == L'\\' || *tail == L'/') { + ++tail; + break; + } + } + if (tail == search->originalCmdLine && tail[0] == L'"') { + ++tail; + } + // Without special cases, we can now fill in the search struct + int tailLen = (int)(end ? (end - tail) : wcsnlen_s(tail, MAXLEN)); + search->executableLength = -1; + + // Our special cases are as follows +#define MATCHES(s) (0 == _comparePath(tail, tailLen, (s), -1)) +#define STARTSWITH(s) _startsWith(tail, tailLen, (s), -1) + if (MATCHES(L"py")) { + search->executable = L"python.exe"; + search->allowExecutableOverride = true; + search->allowDefaults = true; + } else if (MATCHES(L"pyw")) { + search->executable = L"pythonw.exe"; + search->allowExecutableOverride = true; + search->allowDefaults = true; + search->windowed = true; + } else if (MATCHES(L"py_d")) { + search->executable = L"python_d.exe"; + search->allowExecutableOverride = true; + search->allowDefaults = true; + } else if (MATCHES(L"pyw_d")) { + search->executable = L"pythonw_d.exe"; + search->allowExecutableOverride = true; + search->allowDefaults = true; + search->windowed = true; + } else if (STARTSWITH(L"python3")) { + search->executable = L"python.exe"; + search->tag = &tail[6]; + search->tagLength = tailLen - 6; + search->allowExecutableOverride = true; + search->oldStyleTag = true; + search->allowPyvenvCfg = true; + } else if (STARTSWITH(L"pythonw3")) { + search->executable = L"pythonw.exe"; + search->tag = &tail[7]; + search->tagLength = tailLen - 7; + search->allowExecutableOverride = true; + search->oldStyleTag = true; + search->allowPyvenvCfg = true; + search->windowed = true; + } else { + search->executable = tail; + search->executableLength = tailLen; + search->allowPyvenvCfg = true; + } +#undef STARTSWITH +#undef MATCHES + + // First argument might be one of our options. If so, consume it, + // update flags and then set restOfCmdLine. + const wchar_t *arg = search->restOfCmdLine; + while(*arg && isspace(*arg)) { ++arg; } +#define MATCHES(s) (0 == _compareArgument(arg, argLen, (s), -1)) +#define STARTSWITH(s) _startsWithArgument(arg, argLen, (s), -1) + if (*arg && *arg == L'-' && *++arg) { + tail = arg; + while (*tail && !isspace(*tail)) { ++tail; } + int argLen = (int)(tail - arg); + if (argLen > 0) { + if (STARTSWITH(L"2") || STARTSWITH(L"3")) { + // All arguments starting with 2 or 3 are assumed to be version tags + search->tag = arg; + search->tagLength = argLen; + search->oldStyleTag = true; + search->restOfCmdLine = tail; + } else if (STARTSWITH(L"V:") || STARTSWITH(L"-version:")) { + // Arguments starting with 'V:' specify company and/or tag + const wchar_t *argStart = wcschr(arg, L':') + 1; + const wchar_t *tagStart = wcschr(argStart, L'/') ; + if (tagStart) { + search->company = argStart; + search->companyLength = (int)(tagStart - argStart); + search->tag = tagStart + 1; + } else { + search->tag = argStart; + } + search->tagLength = (int)(tail - search->tag); + search->allowDefaults = false; + search->restOfCmdLine = tail; + } else if (MATCHES(L"0") || MATCHES(L"-list")) { + search->list = true; + search->restOfCmdLine = tail; + } else if (MATCHES(L"0p") || MATCHES(L"-list-paths")) { + search->listPaths = true; + search->restOfCmdLine = tail; + } else if (MATCHES(L"h") || MATCHES(L"-help")) { + search->help = true; + // Do not update restOfCmdLine so that we trigger the help + // message from whichever interpreter we select + } + } + } +#undef STARTSWITH +#undef MATCHES + + // Might have a script filename. If it looks like a filename, add + // it to the SearchInfo struct for later reference. + arg = search->restOfCmdLine; + while(*arg && isspace(*arg)) { ++arg; } + if (*arg && *arg != L'-') { + search->scriptFile = arg; + if (*arg == L'"') { + ++search->scriptFile; + while (*++arg && *arg != L'"') { } + } else { + while (*arg && !isspace(*arg)) { ++arg; } + } + search->scriptFileLength = (int)(arg - search->scriptFile); + } + + return 0; +} + + +int +_decodeShebang(SearchInfo *search, const char *buffer, int bufferLength, bool onlyUtf8, wchar_t **decoded, int *decodedLength) +{ + DWORD cp = CP_UTF8; + int wideLen = MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, buffer, bufferLength, NULL, 0); + if (!wideLen) { + cp = CP_ACP; + wideLen = MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, buffer, bufferLength, NULL, 0); + if (!wideLen) { + debug(L"# Failed to decode shebang line (0x%08X)\n", GetLastError()); + return RC_BAD_VIRTUAL_PATH; + } + } + wchar_t *b = allocSearchInfoBuffer(search, wideLen + 1); + if (!b) { + return RC_NO_MEMORY; + } + wideLen = MultiByteToWideChar(cp, 0, buffer, bufferLength, b, wideLen + 1); + if (!wideLen) { + debug(L"# Failed to decode shebang line (0x%08X)\n", GetLastError()); + return RC_BAD_VIRTUAL_PATH; + } + b[wideLen] = L'\0'; + *decoded = b; + *decodedLength = wideLen; + return 0; +} + + +bool +_shebangStartsWith(const wchar_t *buffer, int bufferLength, const wchar_t *prefix, const wchar_t **rest, int *firstArgumentLength) +{ + int prefixLength = (int)wcsnlen_s(prefix, MAXLEN); + if (bufferLength < prefixLength || !_startsWithArgument(buffer, bufferLength, prefix, prefixLength)) { + return false; + } + if (rest) { + *rest = &buffer[prefixLength]; + } + if (firstArgumentLength) { + int i = prefixLength; + while (i < bufferLength && !isspace(buffer[i])) { + i += 1; + } + *firstArgumentLength = i - prefixLength; + } + return true; +} + + +int +searchPath(SearchInfo *search, const wchar_t *shebang, int shebangLength) +{ + if (isEnvVarSet(L"PYLAUNCHER_NO_SEARCH_PATH")) { + return RC_NO_SHEBANG; + } + + wchar_t *command; + int commandLength; + if (!_shebangStartsWith(shebang, shebangLength, L"/usr/bin/env ", &command, &commandLength)) { + return RC_NO_SHEBANG; + } + + if (!commandLength || commandLength == MAXLEN) { + return RC_BAD_VIRTUAL_PATH; + } + + int lastDot = commandLength; + while (lastDot > 0 && command[lastDot] != L'.') { + lastDot -= 1; + } + if (!lastDot) { + lastDot = commandLength; + } + + wchar_t filename[MAXLEN]; + if (wcsncpy_s(filename, MAXLEN, command, lastDot)) { + return RC_BAD_VIRTUAL_PATH; + } + + const wchar_t *ext = L".exe"; + // If the command already has an extension, we do not want to add it again + if (!lastDot || _comparePath(&filename[lastDot], -1, ext, -1)) { + if (wcscat_s(filename, MAXLEN, L".exe")) { + return RC_BAD_VIRTUAL_PATH; + } + } + + wchar_t pathVariable[MAXLEN]; + int n = GetEnvironmentVariableW(L"PATH", pathVariable, MAXLEN); + if (!n) { + if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) { + return RC_NO_SHEBANG; + } + winerror(0, L"Failed to read PATH\n", filename); + return RC_INTERNAL_ERROR; + } + + wchar_t buffer[MAXLEN]; + n = SearchPathW(pathVariable, filename, NULL, MAXLEN, buffer, NULL); + if (!n) { + if (GetLastError() == ERROR_FILE_NOT_FOUND) { + debug(L"# Did not find %s on PATH\n", filename); + // If we didn't find it on PATH, let normal handling take over + return RC_NO_SHEBANG; + } + // Other errors should cause us to break + winerror(0, L"Failed to find %s on PATH\n", filename); + return RC_BAD_VIRTUAL_PATH; + } + + // Check that we aren't going to call ourselves again + // If we are, pretend there was no shebang and let normal handling take over + if (GetModuleFileNameW(NULL, filename, MAXLEN) && + 0 == _comparePath(filename, -1, buffer, -1)) { + debug(L"# ignoring recursive shebang command\n"); + return RC_RECURSIVE_SHEBANG; + } + + wchar_t *buf = allocSearchInfoBuffer(search, n + 1); + if (!buf || wcscpy_s(buf, n + 1, buffer)) { + return RC_NO_MEMORY; + } + + search->executablePath = buf; + search->executableArgs = &command[commandLength]; + search->executableArgsLength = shebangLength - commandLength; + debug(L"# Found %s on PATH\n", buf); + + return 0; +} + + +int +_readIni(const wchar_t *section, const wchar_t *settingName, wchar_t *buffer, int bufferLength) +{ + wchar_t iniPath[MAXLEN]; + int n; + if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, iniPath)) && + join(iniPath, MAXLEN, L"py.ini")) { + debug(L"# Reading from %s for %s/%s\n", iniPath, section, settingName); + n = GetPrivateProfileStringW(section, settingName, NULL, buffer, bufferLength, iniPath); + if (n) { + debug(L"# Found %s in %s\n", settingName, iniPath); + return n; + } else if (GetLastError() == ERROR_FILE_NOT_FOUND) { + debug(L"# Did not find file %s\n", iniPath); + } else { + winerror(0, L"Failed to read from %s\n", iniPath); + } + } + if (GetModuleFileNameW(NULL, iniPath, MAXLEN) && + SUCCEEDED(PathCchRemoveFileSpec(iniPath, MAXLEN)) && + join(iniPath, MAXLEN, L"py.ini")) { + debug(L"# Reading from %s for %s/%s\n", iniPath, section, settingName); + n = GetPrivateProfileStringW(section, settingName, NULL, buffer, MAXLEN, iniPath); + if (n) { + debug(L"# Found %s in %s\n", settingName, iniPath); + return n; + } else if (GetLastError() == ERROR_FILE_NOT_FOUND) { + debug(L"# Did not find file %s\n", iniPath); + } else { + winerror(0, L"Failed to read from %s\n", iniPath); + } + } + return 0; +} + + +bool +_findCommand(SearchInfo *search, const wchar_t *command, int commandLength) +{ + wchar_t commandBuffer[MAXLEN]; + wchar_t buffer[MAXLEN]; + wcsncpy_s(commandBuffer, MAXLEN, command, commandLength); + int n = _readIni(L"commands", commandBuffer, buffer, MAXLEN); + if (!n) { + return false; + } + wchar_t *path = allocSearchInfoBuffer(search, n + 1); + if (!path) { + return false; + } + wcscpy_s(path, n + 1, buffer); + search->executablePath = path; + return true; +} + + +int +_useShebangAsExecutable(SearchInfo *search, const wchar_t *shebang, int shebangLength) +{ + wchar_t buffer[MAXLEN]; + wchar_t script[MAXLEN]; + wchar_t command[MAXLEN]; + + int commandLength = 0; + int inQuote = 0; + + if (!shebang || !shebangLength) { + return 0; + } + + wchar_t *pC = command; + for (int i = 0; i < shebangLength; ++i) { + wchar_t c = shebang[i]; + if (isspace(c) && !inQuote) { + commandLength = i; + break; + } else if (c == L'"') { + inQuote = !inQuote; + } else if (c == L'/' || c == L'\\') { + *pC++ = L'\\'; + } else { + *pC++ = c; + } + } + *pC = L'\0'; + + if (!GetCurrentDirectoryW(MAXLEN, buffer) || + wcsncpy_s(script, MAXLEN, search->scriptFile, search->scriptFileLength) || + FAILED(PathCchCombineEx(buffer, MAXLEN, buffer, script, + PATHCCH_ALLOW_LONG_PATHS)) || + FAILED(PathCchRemoveFileSpec(buffer, MAXLEN)) || + FAILED(PathCchCombineEx(buffer, MAXLEN, buffer, command, + PATHCCH_ALLOW_LONG_PATHS)) + ) { + return RC_NO_MEMORY; + } + + int n = (int)wcsnlen(buffer, MAXLEN); + wchar_t *path = allocSearchInfoBuffer(search, n + 1); + if (!path) { + return RC_NO_MEMORY; + } + wcscpy_s(path, n + 1, buffer); + search->executablePath = path; + if (commandLength) { + search->executableArgs = &shebang[commandLength]; + search->executableArgsLength = shebangLength - commandLength; + } + return 0; +} + + +int +checkShebang(SearchInfo *search) +{ + // Do not check shebang if a tag was provided or if no script file + // was found on the command line. + if (search->tag || !search->scriptFile) { + return 0; + } + + if (search->scriptFileLength < 0) { + search->scriptFileLength = (int)wcsnlen_s(search->scriptFile, MAXLEN); + } + + wchar_t *scriptFile = (wchar_t*)malloc(sizeof(wchar_t) * (search->scriptFileLength + 1)); + if (!scriptFile) { + return RC_NO_MEMORY; + } + + wcsncpy_s(scriptFile, search->scriptFileLength + 1, + search->scriptFile, search->scriptFileLength); + + HANDLE hFile = CreateFileW(scriptFile, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, 0, NULL); + + if (hFile == INVALID_HANDLE_VALUE) { + debug(L"# Failed to open %s for shebang parsing (0x%08X)\n", + scriptFile, GetLastError()); + free(scriptFile); + return 0; + } + + DWORD bytesRead = 0; + char buffer[4096]; + if (!ReadFile(hFile, buffer, sizeof(buffer), &bytesRead, NULL)) { + debug(L"# Failed to read %s for shebang parsing (0x%08X)\n", + scriptFile, GetLastError()); + free(scriptFile); + return 0; + } + + CloseHandle(hFile); + debug(L"# Read %d bytes from %s to find shebang line\n", bytesRead, scriptFile); + free(scriptFile); + + + char *b = buffer; + bool onlyUtf8 = false; + if (bytesRead > 3 && *b == 0xEF) { + if (*++b == 0xBB && *++b == 0xBF) { + // Allow a UTF-8 BOM + ++b; + bytesRead -= 3; + onlyUtf8 = true; + } else { + debug(L"# Invalid BOM in shebang line"); + return 0; + } + } + if (bytesRead <= 2 || b[0] != '#' || b[1] != '!') { + // No shebang (#!) at start of line + debug(L"# No valid shebang line"); + return 0; + } + ++b; + --bytesRead; + while (--bytesRead > 0 && isspace(*++b)) { } + char *start = b; + while (--bytesRead > 0 && *++b != '\r' && *b != '\n') { } + wchar_t *shebang; + int shebangLength; + // We add 1 when bytesRead==0, as in that case we hit EOF and b points + // to the last character in the file, not the newline + int exitCode = _decodeShebang(search, start, (int)(b - start + (bytesRead == 0)), onlyUtf8, &shebang, &shebangLength); + if (exitCode) { + return exitCode; + } + debug(L"Shebang: %s\n", shebang); + + // Handle shebangs that we should search PATH for + exitCode = searchPath(search, shebang, shebangLength); + if (exitCode != RC_NO_SHEBANG) { + return exitCode; + } + + // Handle some known, case-sensitive shebangs + const wchar_t *command; + int commandLength; + // Each template must end with "python" + static const wchar_t *shebangTemplates[] = { + L"/usr/bin/env python", + L"/usr/bin/python", + L"/usr/local/bin/python", + L"python", + NULL + }; + + for (const wchar_t **tmpl = shebangTemplates; *tmpl; ++tmpl) { + // Just to make sure we don't mess this up in the future + assert(0 == wcscmp(L"python", (*tmpl) + wcslen(*tmpl) - 6)); + + if (_shebangStartsWith(shebang, shebangLength, *tmpl, &command, &commandLength)) { + // Search for "python{command}" overrides. All templates end with + // "python", so we prepend it by jumping back 6 characters + if (_findCommand(search, &command[-6], commandLength + 6)) { + search->executableArgs = &command[commandLength]; + search->executableArgsLength = shebangLength - commandLength; + debug(L"# Treating shebang command '%.*s' as %s\n", + commandLength + 6, &command[-6], search->executablePath); + return 0; + } + + search->tag = command; + search->tagLength = commandLength; + // If we had 'python3.12.exe' then we want to strip the suffix + // off of the tag + if (search->tagLength > 4) { + const wchar_t *suffix = &search->tag[search->tagLength - 4]; + if (0 == _comparePath(suffix, 4, L".exe", -1)) { + search->tagLength -= 4; + } + } + // If we had 'python3_d' then we want to strip the '_d' (any + // '.exe' is already gone) + if (search->tagLength > 2) { + const wchar_t *suffix = &search->tag[search->tagLength - 2]; + if (0 == _comparePath(suffix, 2, L"_d", -1)) { + search->tagLength -= 2; + } + } + search->oldStyleTag = true; + search->executableArgs = &command[commandLength]; + search->executableArgsLength = shebangLength - commandLength; + if (search->tag && search->tagLength) { + debug(L"# Treating shebang command '%.*s' as 'py -%.*s'\n", + commandLength, command, search->tagLength, search->tag); + } else { + debug(L"# Treating shebang command '%.*s' as 'py'\n", + commandLength, command); + } + return 0; + } + } + + // Unrecognised executables are first tried as command aliases + commandLength = 0; + while (commandLength < shebangLength && !isspace(shebang[commandLength])) { + commandLength += 1; + } + if (_findCommand(search, shebang, commandLength)) { + search->executableArgs = &shebang[commandLength]; + search->executableArgsLength = shebangLength - commandLength; + debug(L"# Treating shebang command '%.*s' as %s\n", + commandLength, shebang, search->executablePath); + return 0; + } + + // Unrecognised commands are joined to the script's directory and treated + // as the executable path + return _useShebangAsExecutable(search, shebang, shebangLength); +} + + +int +checkDefaults(SearchInfo *search) +{ + if (!search->allowDefaults) { + return 0; + } + + // Only resolve old-style (or absent) tags to defaults + if (search->tag && search->tagLength && !search->oldStyleTag) { + return 0; + } + + // If tag is only a major version number, expand it from the environment + // or an ini file + const wchar_t *iniSettingName = NULL; + const wchar_t *envSettingName = NULL; + if (!search->tag || !search->tagLength) { + iniSettingName = L"python"; + envSettingName = L"py_python"; + } else if (0 == wcsncmp(search->tag, L"3", search->tagLength)) { + iniSettingName = L"python3"; + envSettingName = L"py_python3"; + } else if (0 == wcsncmp(search->tag, L"2", search->tagLength)) { + iniSettingName = L"python2"; + envSettingName = L"py_python2"; + } else { + debug(L"# Cannot select defaults for tag '%.*s'\n", search->tagLength, search->tag); + return 0; + } + + // First, try to read an environment variable + wchar_t buffer[MAXLEN]; + int n = GetEnvironmentVariableW(envSettingName, buffer, MAXLEN); + + // If none found, check in our two .ini files instead + if (!n) { + n = _readIni(L"defaults", iniSettingName, buffer, MAXLEN); + } + + if (n) { + wchar_t *tag = allocSearchInfoBuffer(search, n + 1); + if (!tag) { + return RC_NO_MEMORY; + } + wcscpy_s(tag, n + 1, buffer); + wchar_t *slash = wcschr(tag, L'/'); + if (!slash) { + search->tag = tag; + search->tagLength = n; + search->oldStyleTag = true; + } else { + search->company = tag; + search->companyLength = (int)(slash - tag); + search->tag = slash + 1; + search->tagLength = n - (search->companyLength + 1); + search->oldStyleTag = false; + } + // gh-92817: allow a high priority env to be selected even if it + // doesn't match the tag + search->lowPriorityTag = true; + } + + return 0; +} + +/******************************************************************************\ + *** ENVIRONMENT SEARCH *** +\******************************************************************************/ + +typedef struct EnvironmentInfo { + /* We use a binary tree and sort on insert */ + struct EnvironmentInfo *prev; + struct EnvironmentInfo *next; + /* parent is only used when constructing */ + struct EnvironmentInfo *parent; + const wchar_t *company; + const wchar_t *tag; + int internalSortKey; + const wchar_t *installDir; + const wchar_t *executablePath; + const wchar_t *executableArgs; + const wchar_t *architecture; + const wchar_t *displayName; + bool highPriority; +} EnvironmentInfo; + + +int +copyWstr(const wchar_t **dest, const wchar_t *src) +{ + if (!dest) { + return RC_NO_MEMORY; + } + if (!src) { + *dest = NULL; + return 0; + } + size_t n = wcsnlen_s(src, MAXLEN - 1) + 1; + wchar_t *buffer = (wchar_t*)malloc(n * sizeof(wchar_t)); + if (!buffer) { + return RC_NO_MEMORY; + } + wcsncpy_s(buffer, n, src, n - 1); + *dest = (const wchar_t*)buffer; + return 0; +} + + +EnvironmentInfo * +newEnvironmentInfo(const wchar_t *company, const wchar_t *tag) +{ + EnvironmentInfo *env = (EnvironmentInfo *)malloc(sizeof(EnvironmentInfo)); + if (!env) { + return NULL; + } + memset(env, 0, sizeof(EnvironmentInfo)); + int exitCode = copyWstr(&env->company, company); + if (exitCode) { + free((void *)env); + return NULL; + } + exitCode = copyWstr(&env->tag, tag); + if (exitCode) { + free((void *)env->company); + free((void *)env); + return NULL; + } + return env; +} + + +void +freeEnvironmentInfo(EnvironmentInfo *env) +{ + if (env) { + free((void *)env->company); + free((void *)env->tag); + free((void *)env->installDir); + free((void *)env->executablePath); + free((void *)env->executableArgs); + free((void *)env->displayName); + freeEnvironmentInfo(env->prev); + env->prev = NULL; + freeEnvironmentInfo(env->next); + env->next = NULL; + free((void *)env); + } +} + + +/* Specific string comparisons for sorting the tree */ + +int +_compareCompany(const wchar_t *x, const wchar_t *y) +{ + if (!x && !y) { + return 0; + } else if (!x) { + return -1; + } else if (!y) { + return 1; + } + + bool coreX = 0 == _compare(x, -1, L"PythonCore", -1); + bool coreY = 0 == _compare(y, -1, L"PythonCore", -1); + if (coreX) { + return coreY ? 0 : -1; + } else if (coreY) { + return 1; + } + return _compare(x, -1, y, -1); +} + + +int +_compareTag(const wchar_t *x, const wchar_t *y) +{ + if (!x && !y) { + return 0; + } else if (!x) { + return -1; + } else if (!y) { + return 1; + } + + // Compare up to the first dash. If not equal, that's our sort order + const wchar_t *xDash = wcschr(x, L'-'); + const wchar_t *yDash = wcschr(y, L'-'); + int xToDash = xDash ? (int)(xDash - x) : -1; + int yToDash = yDash ? (int)(yDash - y) : -1; + int r = _compare(x, xToDash, y, yToDash); + if (r) { + return r; + } + // If we're equal up to the first dash, we want to sort one with + // no dash *after* one with a dash. Otherwise, a reversed compare. + // This works out because environments are sorted in descending tag + // order, so that higher versions (probably) come first. + // For PythonCore, our "X.Y" structure ensures that higher versions + // come first. Everyone else will just have to deal with it. + if (xDash && yDash) { + return _compare(yDash, -1, xDash, -1); + } else if (xDash) { + return -1; + } else if (yDash) { + return 1; + } + return 0; +} + + +int +addEnvironmentInfo(EnvironmentInfo **root, EnvironmentInfo* parent, EnvironmentInfo *node) +{ + EnvironmentInfo *r = *root; + if (!r) { + *root = node; + node->parent = parent; + return 0; + } + // Sort by company name + switch (_compareCompany(node->company, r->company)) { + case -1: + return addEnvironmentInfo(&r->prev, r, node); + case 1: + return addEnvironmentInfo(&r->next, r, node); + case 0: + break; + } + // Then by tag (descending) + switch (_compareTag(node->tag, r->tag)) { + case -1: + return addEnvironmentInfo(&r->next, r, node); + case 1: + return addEnvironmentInfo(&r->prev, r, node); + case 0: + break; + } + // Then keep the one with the lowest internal sort key + if (node->internalSortKey < r->internalSortKey) { + // Replace the current node + node->parent = r->parent; + if (node->parent) { + if (node->parent->prev == r) { + node->parent->prev = node; + } else if (node->parent->next == r) { + node->parent->next = node; + } else { + debug(L"# Inconsistent parent value in tree\n"); + freeEnvironmentInfo(node); + return RC_INTERNAL_ERROR; + } + } else { + // If node has no parent, then it is the root. + *root = node; + } + + node->next = r->next; + node->prev = r->prev; + + debug(L"# replaced %s/%s/%i in tree\n", node->company, node->tag, node->internalSortKey); + freeEnvironmentInfo(r); + } else { + debug(L"# not adding %s/%s/%i to tree\n", node->company, node->tag, node->internalSortKey); + return RC_DUPLICATE_ITEM; + } + return 0; +} + + +/******************************************************************************\ + *** REGISTRY SEARCH *** +\******************************************************************************/ + + +int +_registryReadString(const wchar_t **dest, HKEY root, const wchar_t *subkey, const wchar_t *value) +{ + // Note that this is bytes (hence 'cb'), not characters ('cch') + DWORD cbData = 0; + DWORD flags = RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ; + + if (ERROR_SUCCESS != RegGetValueW(root, subkey, value, flags, NULL, NULL, &cbData)) { + return 0; + } + + wchar_t *buffer = (wchar_t*)malloc(cbData); + if (!buffer) { + return RC_NO_MEMORY; + } + + if (ERROR_SUCCESS == RegGetValueW(root, subkey, value, flags, NULL, buffer, &cbData)) { + *dest = buffer; + } else { + free((void *)buffer); + } + return 0; +} + + +int +_combineWithInstallDir(const wchar_t **dest, const wchar_t *installDir, const wchar_t *fragment, int fragmentLength) +{ + wchar_t buffer[MAXLEN]; + wchar_t fragmentBuffer[MAXLEN]; + if (wcsncpy_s(fragmentBuffer, MAXLEN, fragment, fragmentLength)) { + return RC_NO_MEMORY; + } + + if (FAILED(PathCchCombineEx(buffer, MAXLEN, installDir, fragmentBuffer, PATHCCH_ALLOW_LONG_PATHS))) { + return RC_NO_MEMORY; + } + + return copyWstr(dest, buffer); +} + + +bool +_isLegacyVersion(EnvironmentInfo *env) +{ + // Check if backwards-compatibility is required. + // Specifically PythonCore versions 2.X and 3.0 - 3.5 do not implement PEP 514. + if (0 != _compare(env->company, -1, L"PythonCore", -1)) { + return false; + } + + int versionMajor, versionMinor; + int n = swscanf_s(env->tag, L"%d.%d", &versionMajor, &versionMinor); + if (n != 2) { + debug(L"# %s/%s has an invalid version tag\n", env->company, env->tag); + return false; + } + + return versionMajor == 2 + || (versionMajor == 3 && versionMinor >= 0 && versionMinor <= 5); +} + +int +_registryReadLegacyEnvironment(const SearchInfo *search, HKEY root, EnvironmentInfo *env, const wchar_t *fallbackArch) +{ + // Backwards-compatibility for PythonCore versions which do not implement PEP 514. + int exitCode = _combineWithInstallDir( + &env->executablePath, + env->installDir, + search->executable, + search->executableLength + ); + if (exitCode) { + return exitCode; + } + + if (search->windowed) { + exitCode = _registryReadString(&env->executableArgs, root, L"InstallPath", L"WindowedExecutableArguments"); + } + else { + exitCode = _registryReadString(&env->executableArgs, root, L"InstallPath", L"ExecutableArguments"); + } + if (exitCode) { + return exitCode; + } + + if (fallbackArch) { + copyWstr(&env->architecture, fallbackArch); + } else { + DWORD binaryType; + BOOL success = GetBinaryTypeW(env->executablePath, &binaryType); + if (!success) { + return RC_NO_PYTHON; + } + + switch (binaryType) { + case SCS_32BIT_BINARY: + copyWstr(&env->architecture, L"32bit"); + break; + case SCS_64BIT_BINARY: + copyWstr(&env->architecture, L"64bit"); + break; + default: + return RC_NO_PYTHON; + } + } + + if (0 == _compare(env->architecture, -1, L"32bit", -1)) { + size_t tagLength = wcslen(env->tag); + if (tagLength <= 3 || 0 != _compare(&env->tag[tagLength - 3], 3, L"-32", 3)) { + const wchar_t *rawTag = env->tag; + wchar_t *realTag = (wchar_t*) malloc(sizeof(wchar_t) * (tagLength + 4)); + if (!realTag) { + return RC_NO_MEMORY; + } + + int count = swprintf_s(realTag, tagLength + 4, L"%s-32", env->tag); + if (count == -1) { + free(realTag); + return RC_INTERNAL_ERROR; + } + + env->tag = realTag; + free((void*)rawTag); + } + } + + wchar_t buffer[MAXLEN]; + if (swprintf_s(buffer, MAXLEN, L"Python %s", env->tag)) { + copyWstr(&env->displayName, buffer); + } + + return 0; +} + + +int +_registryReadEnvironment(const SearchInfo *search, HKEY root, EnvironmentInfo *env, const wchar_t *fallbackArch) +{ + int exitCode = _registryReadString(&env->installDir, root, L"InstallPath", NULL); + if (exitCode) { + return exitCode; + } + if (!env->installDir) { + return RC_NO_PYTHON; + } + + if (_isLegacyVersion(env)) { + return _registryReadLegacyEnvironment(search, root, env, fallbackArch); + } + + // If pythonw.exe requested, check specific value + if (search->windowed) { + exitCode = _registryReadString(&env->executablePath, root, L"InstallPath", L"WindowedExecutablePath"); + if (!exitCode && env->executablePath) { + exitCode = _registryReadString(&env->executableArgs, root, L"InstallPath", L"WindowedExecutableArguments"); + } + } + if (exitCode) { + return exitCode; + } + + // Missing windowed path or non-windowed request means we use ExecutablePath + if (!env->executablePath) { + exitCode = _registryReadString(&env->executablePath, root, L"InstallPath", L"ExecutablePath"); + if (!exitCode && env->executablePath) { + exitCode = _registryReadString(&env->executableArgs, root, L"InstallPath", L"ExecutableArguments"); + } + } + if (exitCode) { + return exitCode; + } + + if (!env->executablePath) { + debug(L"# %s/%s has no executable path\n", env->company, env->tag); + return RC_NO_PYTHON; + } + + exitCode = _registryReadString(&env->architecture, root, NULL, L"SysArchitecture"); + if (exitCode) { + return exitCode; + } + + exitCode = _registryReadString(&env->displayName, root, NULL, L"DisplayName"); + if (exitCode) { + return exitCode; + } + + return 0; +} + +int +_registrySearchTags(const SearchInfo *search, EnvironmentInfo **result, HKEY root, int sortKey, const wchar_t *company, const wchar_t *fallbackArch) +{ + wchar_t buffer[256]; + int err = 0; + int exitCode = 0; + for (int i = 0; exitCode == 0; ++i) { + DWORD cchBuffer = sizeof(buffer) / sizeof(buffer[0]); + err = RegEnumKeyExW(root, i, buffer, &cchBuffer, NULL, NULL, NULL, NULL); + if (err) { + if (err != ERROR_NO_MORE_ITEMS) { + winerror(0, L"Failed to read installs (tags) from the registry"); + } + break; + } + HKEY subkey; + if (ERROR_SUCCESS == RegOpenKeyExW(root, buffer, 0, KEY_READ, &subkey)) { + EnvironmentInfo *env = newEnvironmentInfo(company, buffer); + env->internalSortKey = sortKey; + exitCode = _registryReadEnvironment(search, subkey, env, fallbackArch); + RegCloseKey(subkey); + if (exitCode == RC_NO_PYTHON) { + freeEnvironmentInfo(env); + exitCode = 0; + } else if (!exitCode) { + exitCode = addEnvironmentInfo(result, NULL, env); + if (exitCode) { + freeEnvironmentInfo(env); + if (exitCode == RC_DUPLICATE_ITEM) { + exitCode = 0; + } + } + } + } + } + return exitCode; +} + + +int +registrySearch(const SearchInfo *search, EnvironmentInfo **result, HKEY root, int sortKey, const wchar_t *fallbackArch) +{ + wchar_t buffer[256]; + int err = 0; + int exitCode = 0; + for (int i = 0; exitCode == 0; ++i) { + DWORD cchBuffer = sizeof(buffer) / sizeof(buffer[0]); + err = RegEnumKeyExW(root, i, buffer, &cchBuffer, NULL, NULL, NULL, NULL); + if (err) { + if (err != ERROR_NO_MORE_ITEMS) { + winerror(0, L"Failed to read distributors (company) from the registry"); + } + break; + } + HKEY subkey; + if (ERROR_SUCCESS == RegOpenKeyExW(root, buffer, 0, KEY_READ, &subkey)) { + exitCode = _registrySearchTags(search, result, subkey, sortKey, buffer, fallbackArch); + RegCloseKey(subkey); + } + } + return exitCode; +} + + +/******************************************************************************\ + *** APP PACKAGE SEARCH *** +\******************************************************************************/ + +int +appxSearch(const SearchInfo *search, EnvironmentInfo **result, const wchar_t *packageFamilyName, const wchar_t *tag, int sortKey) +{ + wchar_t realTag[32]; + wchar_t buffer[MAXLEN]; + const wchar_t *exeName = search->executable; + if (!exeName || search->allowExecutableOverride) { + exeName = search->windowed ? L"pythonw.exe" : L"python.exe"; + } + + if (FAILED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, buffer)) || + !join(buffer, MAXLEN, L"Microsoft\\WindowsApps") || + !join(buffer, MAXLEN, packageFamilyName) || + !join(buffer, MAXLEN, exeName)) { + return RC_INTERNAL_ERROR; + } + + if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(buffer)) { + return RC_NO_PYTHON; + } + + // Assume packages are native architecture, which means we need to append + // the '-arm64' on ARM64 host. + wcscpy_s(realTag, 32, tag); + if (isARM64Host()) { + wcscat_s(realTag, 32, L"-arm64"); + } + + EnvironmentInfo *env = newEnvironmentInfo(L"PythonCore", realTag); + if (!env) { + return RC_NO_MEMORY; + } + env->internalSortKey = sortKey; + if (isAMD64Host()) { + copyWstr(&env->architecture, L"64bit"); + } else if (isARM64Host()) { + copyWstr(&env->architecture, L"ARM64"); + } + + copyWstr(&env->executablePath, buffer); + + if (swprintf_s(buffer, MAXLEN, L"Python %s (Store)", tag)) { + copyWstr(&env->displayName, buffer); + } + + int exitCode = addEnvironmentInfo(result, NULL, env); + if (exitCode) { + freeEnvironmentInfo(env); + if (exitCode == RC_DUPLICATE_ITEM) { + exitCode = 0; + } + } + + + return exitCode; +} + + +/******************************************************************************\ + *** OVERRIDDEN EXECUTABLE PATH *** +\******************************************************************************/ + + +int +explicitOverrideSearch(const SearchInfo *search, EnvironmentInfo **result) +{ + if (!search->executablePath) { + return 0; + } + + EnvironmentInfo *env = newEnvironmentInfo(NULL, NULL); + if (!env) { + return RC_NO_MEMORY; + } + env->internalSortKey = 10; + int exitCode = copyWstr(&env->executablePath, search->executablePath); + if (exitCode) { + goto abort; + } + exitCode = copyWstr(&env->displayName, L"Explicit override"); + if (exitCode) { + goto abort; + } + exitCode = addEnvironmentInfo(result, NULL, env); + if (exitCode) { + goto abort; + } + return 0; + +abort: + freeEnvironmentInfo(env); + if (exitCode == RC_DUPLICATE_ITEM) { + exitCode = 0; + } + return exitCode; +} + + +/******************************************************************************\ + *** ACTIVE VIRTUAL ENVIRONMENT SEARCH *** +\******************************************************************************/ + +int +virtualenvSearch(const SearchInfo *search, EnvironmentInfo **result) +{ + int exitCode = 0; + EnvironmentInfo *env = NULL; + wchar_t buffer[MAXLEN]; + int n = GetEnvironmentVariableW(L"VIRTUAL_ENV", buffer, MAXLEN); + if (!n || !join(buffer, MAXLEN, L"Scripts") || !join(buffer, MAXLEN, search->executable)) { + return 0; + } + + if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(buffer)) { + debug(L"Python executable %s missing from virtual env\n", buffer); + return 0; + } + + env = newEnvironmentInfo(NULL, NULL); + if (!env) { + return RC_NO_MEMORY; + } + env->highPriority = true; + env->internalSortKey = 20; + exitCode = copyWstr(&env->displayName, L"Active venv"); + if (exitCode) { + goto abort; + } + exitCode = copyWstr(&env->executablePath, buffer); + if (exitCode) { + goto abort; + } + exitCode = addEnvironmentInfo(result, NULL, env); + if (exitCode) { + goto abort; + } + return 0; + +abort: + freeEnvironmentInfo(env); + if (exitCode == RC_DUPLICATE_ITEM) { + return 0; + } + return exitCode; +} + +/******************************************************************************\ + *** COLLECT ENVIRONMENTS *** +\******************************************************************************/ + + +struct RegistrySearchInfo { + // Registry subkey to search + const wchar_t *subkey; + // Registry hive to search + HKEY hive; + // Flags to use when opening the subkey + DWORD flags; + // Internal sort key to select between "identical" environments discovered + // through different methods + int sortKey; + // Fallback value to assume for PythonCore entries missing a SysArchitecture value + const wchar_t *fallbackArch; +}; + + +struct RegistrySearchInfo REGISTRY_SEARCH[] = { + { + L"Software\\Python", + HKEY_CURRENT_USER, + KEY_READ, + 1, + NULL + }, + { + L"Software\\Python", + HKEY_LOCAL_MACHINE, + KEY_READ | KEY_WOW64_64KEY, + 3, + L"64bit" + }, + { + L"Software\\Python", + HKEY_LOCAL_MACHINE, + KEY_READ | KEY_WOW64_32KEY, + 4, + L"32bit" + }, + { NULL, 0, 0, 0, NULL } +}; + + +struct AppxSearchInfo { + // The package family name. Can be found for an installed package using the + // Powershell "Get-AppxPackage" cmdlet + const wchar_t *familyName; + // The tag to treat the installation as + const wchar_t *tag; + // Internal sort key to select between "identical" environments discovered + // through different methods + int sortKey; +}; + + +struct AppxSearchInfo APPX_SEARCH[] = { + // Releases made through the Store + { L"PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0", L"3.12", 10 }, + { L"PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0", L"3.11", 10 }, + { L"PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0", L"3.10", 10 }, + { L"PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0", L"3.9", 10 }, + { L"PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0", L"3.8", 10 }, + + // Side-loadable releases. Note that the publisher ID changes whenever we + // renew our code-signing certificate, so the newer ID has a higher + // priority (lower sortKey) + { L"PythonSoftwareFoundation.Python.3.12_3847v3x7pw1km", L"3.12", 11 }, + { L"PythonSoftwareFoundation.Python.3.11_3847v3x7pw1km", L"3.11", 11 }, + { L"PythonSoftwareFoundation.Python.3.11_hd69rhyc2wevp", L"3.11", 12 }, + { L"PythonSoftwareFoundation.Python.3.10_3847v3x7pw1km", L"3.10", 11 }, + { L"PythonSoftwareFoundation.Python.3.10_hd69rhyc2wevp", L"3.10", 12 }, + { L"PythonSoftwareFoundation.Python.3.9_3847v3x7pw1km", L"3.9", 11 }, + { L"PythonSoftwareFoundation.Python.3.9_hd69rhyc2wevp", L"3.9", 12 }, + { L"PythonSoftwareFoundation.Python.3.8_hd69rhyc2wevp", L"3.8", 12 }, + { NULL, NULL, 0 } +}; + + +int +collectEnvironments(const SearchInfo *search, EnvironmentInfo **result) +{ + int exitCode = 0; + HKEY root; + EnvironmentInfo *env = NULL; + + if (!result) { + return RC_INTERNAL_ERROR; + } + *result = NULL; + + exitCode = explicitOverrideSearch(search, result); + if (exitCode) { + return exitCode; + } + + exitCode = virtualenvSearch(search, result); + if (exitCode) { + return exitCode; + } + + // If we aren't collecting all items to list them, we can exit now. + if (env && !(search->list || search->listPaths)) { + return 0; + } + + for (struct RegistrySearchInfo *info = REGISTRY_SEARCH; info->subkey; ++info) { + if (ERROR_SUCCESS == RegOpenKeyExW(info->hive, info->subkey, 0, info->flags, &root)) { + exitCode = registrySearch(search, result, root, info->sortKey, info->fallbackArch); + RegCloseKey(root); + } + if (exitCode) { + return exitCode; + } + } + + for (struct AppxSearchInfo *info = APPX_SEARCH; info->familyName; ++info) { + exitCode = appxSearch(search, result, info->familyName, info->tag, info->sortKey); + if (exitCode && exitCode != RC_NO_PYTHON) { + return exitCode; + } + } + + return 0; +} + + +/******************************************************************************\ + *** INSTALL ON DEMAND *** +\******************************************************************************/ + +struct StoreSearchInfo { + // The tag a user is looking for + const wchar_t *tag; + // The Store ID for a package if it can be installed from the Microsoft + // Store. These are obtained from the dashboard at + // https://partner.microsoft.com/dashboard + const wchar_t *storeId; +}; + + +struct StoreSearchInfo STORE_SEARCH[] = { + { L"3", /* 3.11 */ L"9NRWMJP3717K" }, + { L"3.12", L"9NCVDN91XZQP" }, + { L"3.11", L"9NRWMJP3717K" }, + { L"3.10", L"9PJPW5LDXLZ5" }, + { L"3.9", L"9P7QFQMJRFP7" }, + { L"3.8", L"9MSSZTT1N39L" }, + { NULL, NULL } +}; + + +int +_installEnvironment(const wchar_t *command, const wchar_t *arguments) +{ + SHELLEXECUTEINFOW siw = { + sizeof(SHELLEXECUTEINFOW), + SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE, + NULL, NULL, + command, arguments, NULL, + SW_SHOWNORMAL + }; + + debug(L"# Installing with %s %s\n", command, arguments); + if (isEnvVarSet(L"PYLAUNCHER_DRYRUN")) { + debug(L"# Exiting due to PYLAUNCHER_DRYRUN\n"); + fflush(stdout); + int mode = _setmode(_fileno(stdout), _O_U8TEXT); + if (arguments) { + fwprintf_s(stdout, L"\"%s\" %s\n", command, arguments); + } else { + fwprintf_s(stdout, L"\"%s\"\n", command); + } + fflush(stdout); + if (mode >= 0) { + _setmode(_fileno(stdout), mode); + } + return RC_INSTALLING; + } + + if (!ShellExecuteExW(&siw)) { + return RC_NO_PYTHON; + } + + if (!siw.hProcess) { + return RC_INSTALLING; + } + + WaitForSingleObjectEx(siw.hProcess, INFINITE, FALSE); + DWORD exitCode = 0; + if (GetExitCodeProcess(siw.hProcess, &exitCode) && exitCode == 0) { + return 0; + } + return RC_INSTALLING; +} + + +const wchar_t *WINGET_COMMAND = L"Microsoft\\WindowsApps\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\\winget.exe"; +const wchar_t *WINGET_ARGUMENTS = L"install -q %s --exact --accept-package-agreements --source msstore"; + +const wchar_t *MSSTORE_COMMAND = L"ms-windows-store://pdp/?productid=%s"; + +int +installEnvironment(const SearchInfo *search) +{ + // No tag? No installing + if (!search->tag || !search->tagLength) { + debug(L"# Cannot install Python with no tag specified\n"); + return RC_NO_PYTHON; + } + + // PEP 514 tag but not PythonCore? No installing + if (!search->oldStyleTag && + search->company && search->companyLength && + 0 != _compare(search->company, search->companyLength, L"PythonCore", -1)) { + debug(L"# Cannot install for company %.*s\n", search->companyLength, search->company); + return RC_NO_PYTHON; + } + + const wchar_t *storeId = NULL; + for (struct StoreSearchInfo *info = STORE_SEARCH; info->tag; ++info) { + if (0 == _compare(search->tag, search->tagLength, info->tag, -1)) { + storeId = info->storeId; + break; + } + } + + if (!storeId) { + return RC_NO_PYTHON; + } + + int exitCode; + wchar_t command[MAXLEN]; + wchar_t arguments[MAXLEN]; + if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, command)) && + join(command, MAXLEN, WINGET_COMMAND) && + swprintf_s(arguments, MAXLEN, WINGET_ARGUMENTS, storeId)) { + if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(command)) { + formatWinerror(GetLastError(), arguments, MAXLEN); + debug(L"# Skipping %s: %s\n", command, arguments); + } else { + fputws(L"Launching winget to install Python. The following output is from the install process\n\ +***********************************************************************\n", stdout); + exitCode = _installEnvironment(command, arguments); + if (exitCode == RC_INSTALLING) { + fputws(L"***********************************************************************\n\ +Please check the install status and run your command again.", stderr); + return exitCode; + } else if (exitCode) { + return exitCode; + } + fputws(L"***********************************************************************\n\ +Install appears to have succeeded. Searching for new matching installs.\n", stdout); + return 0; + } + } + + if (swprintf_s(command, MAXLEN, MSSTORE_COMMAND, storeId)) { + fputws(L"Opening the Microsoft Store to install Python. After installation, " + L"please run your command again.\n", stderr); + exitCode = _installEnvironment(command, NULL); + if (exitCode) { + return exitCode; + } + return 0; + } + + return RC_NO_PYTHON; +} + +/******************************************************************************\ + *** ENVIRONMENT SELECT *** +\******************************************************************************/ + +bool +_companyMatches(const SearchInfo *search, const EnvironmentInfo *env) +{ + if (!search->company || !search->companyLength) { + return true; + } + return 0 == _compare(env->company, -1, search->company, search->companyLength); +} + + +bool +_tagMatches(const SearchInfo *search, const EnvironmentInfo *env) +{ + if (!search->tag || !search->tagLength) { + return true; + } + return _startsWith(env->tag, -1, search->tag, search->tagLength); +} + + +bool +_is32Bit(const EnvironmentInfo *env) +{ + if (env->architecture) { + return 0 == _compare(env->architecture, -1, L"32bit", -1); + } + return false; +} + + +int +_selectEnvironment(const SearchInfo *search, EnvironmentInfo *env, EnvironmentInfo **best) +{ + int exitCode = 0; + while (env) { + exitCode = _selectEnvironment(search, env->prev, best); + + if (exitCode && exitCode != RC_NO_PYTHON) { + return exitCode; + } else if (!exitCode && *best) { + return 0; + } + + if (env->highPriority && search->lowPriorityTag) { + // This environment is marked high priority, and the search allows + // it to be selected even though a tag is specified, so select it + // gh-92817: this allows an active venv to be selected even when a + // default tag has been found in py.ini or the environment + *best = env; + return 0; + } + + if (!search->oldStyleTag) { + if (_companyMatches(search, env) && _tagMatches(search, env)) { + // Because of how our sort tree is set up, we will walk up the + // "prev" side and implicitly select the "best" best. By + // returning straight after a match, we skip the entire "next" + // branch and won't ever select a "worse" best. + *best = env; + return 0; + } + } else if (0 == _compare(env->company, -1, L"PythonCore", -1)) { + // Old-style tags can only match PythonCore entries + + // If the tag ends with -64, we want to exclude 32-bit runtimes + // (If the tag ends with -32, it will be filtered later) + int tagLength = search->tagLength; + bool exclude32Bit = false, only32Bit = false; + if (tagLength > 3) { + if (0 == _compareArgument(&search->tag[tagLength - 3], 3, L"-64", 3)) { + tagLength -= 3; + exclude32Bit = true; + } else if (0 == _compareArgument(&search->tag[tagLength - 3], 3, L"-32", 3)) { + tagLength -= 3; + only32Bit = true; + } + } + + if (_startsWith(env->tag, -1, search->tag, tagLength)) { + if (exclude32Bit && _is32Bit(env)) { + debug(L"# Excluding %s/%s because it looks like 32bit\n", env->company, env->tag); + } else if (only32Bit && !_is32Bit(env)) { + debug(L"# Excluding %s/%s because it doesn't look 32bit\n", env->company, env->tag); + } else { + *best = env; + return 0; + } + } + } + + env = env->next; + } + return RC_NO_PYTHON; +} + +int +selectEnvironment(const SearchInfo *search, EnvironmentInfo *root, EnvironmentInfo **best) +{ + if (!best) { + return RC_INTERNAL_ERROR; + } + if (!root) { + *best = NULL; + return RC_NO_PYTHON_AT_ALL; + } + if (!root->next && !root->prev) { + *best = root; + return 0; + } + + EnvironmentInfo *result = NULL; + int exitCode = _selectEnvironment(search, root, &result); + if (!exitCode) { + *best = result; + } + + return exitCode; +} + + +/******************************************************************************\ + *** LIST ENVIRONMENTS *** +\******************************************************************************/ + +#define TAGWIDTH 16 + +int +_printEnvironment(const EnvironmentInfo *env, FILE *out, bool showPath, const wchar_t *argument) +{ + if (showPath) { + if (env->executablePath && env->executablePath[0]) { + if (env->executableArgs && env->executableArgs[0]) { + fwprintf(out, L" %-*s %s %s\n", TAGWIDTH, argument, env->executablePath, env->executableArgs); + } else { + fwprintf(out, L" %-*s %s\n", TAGWIDTH, argument, env->executablePath); + } + } else if (env->installDir && env->installDir[0]) { + fwprintf(out, L" %-*s %s\n", TAGWIDTH, argument, env->installDir); + } else { + fwprintf(out, L" %s\n", argument); + } + } else if (env->displayName) { + fwprintf(out, L" %-*s %s\n", TAGWIDTH, argument, env->displayName); + } else { + fwprintf(out, L" %s\n", argument); + } + return 0; +} + + +int +_listAllEnvironments(EnvironmentInfo *env, FILE * out, bool showPath, EnvironmentInfo *defaultEnv) +{ + wchar_t buffer[256]; + const int bufferSize = 256; + while (env) { + int exitCode = _listAllEnvironments(env->prev, out, showPath, defaultEnv); + if (exitCode) { + return exitCode; + } + + if (!env->company || !env->tag) { + buffer[0] = L'\0'; + } else if (0 == _compare(env->company, -1, L"PythonCore", -1)) { + swprintf_s(buffer, bufferSize, L"-V:%s", env->tag); + } else { + swprintf_s(buffer, bufferSize, L"-V:%s/%s", env->company, env->tag); + } + + if (env == defaultEnv) { + wcscat_s(buffer, bufferSize, L" *"); + } + + if (buffer[0]) { + exitCode = _printEnvironment(env, out, showPath, buffer); + if (exitCode) { + return exitCode; + } + } + + env = env->next; + } + return 0; +} + + +int +listEnvironments(EnvironmentInfo *env, FILE * out, bool showPath, EnvironmentInfo *defaultEnv) +{ + if (!env) { + fwprintf_s(stdout, L"No installed Pythons found!\n"); + return 0; + } + + /* TODO: Do we want to display these? + In favour, helps users see that '-3' is a good option + Against, repeats the next line of output + SearchInfo majorSearch; + EnvironmentInfo *major; + int exitCode; + + if (showPath) { + memset(&majorSearch, 0, sizeof(majorSearch)); + majorSearch.company = L"PythonCore"; + majorSearch.companyLength = -1; + majorSearch.tag = L"3"; + majorSearch.tagLength = -1; + majorSearch.oldStyleTag = true; + major = NULL; + exitCode = selectEnvironment(&majorSearch, env, &major); + if (!exitCode && major) { + exitCode = _printEnvironment(major, out, showPath, L"-3 *"); + isDefault = false; + if (exitCode) { + return exitCode; + } + } + majorSearch.tag = L"2"; + major = NULL; + exitCode = selectEnvironment(&majorSearch, env, &major); + if (!exitCode && major) { + exitCode = _printEnvironment(major, out, showPath, L"-2"); + if (exitCode) { + return exitCode; + } + } + } + */ + + int mode = _setmode(_fileno(out), _O_U8TEXT); + int exitCode = _listAllEnvironments(env, out, showPath, defaultEnv); + fflush(out); + if (mode >= 0) { + _setmode(_fileno(out), mode); + } + return exitCode; +} + + +/******************************************************************************\ + *** INTERPRETER LAUNCH *** +\******************************************************************************/ + + +int +calculateCommandLine(const SearchInfo *search, const EnvironmentInfo *launch, wchar_t *buffer, int bufferLength) +{ + int exitCode = 0; + const wchar_t *executablePath = NULL; + + // Construct command line from a search override, or else the selected + // environment's executablePath + if (search->executablePath) { + executablePath = search->executablePath; + } else if (launch && launch->executablePath) { + executablePath = launch->executablePath; + } + + // If we have an executable path, put it at the start of the command, but + // only if the search allowed an override. + // Otherwise, use the environment's installDir and the search's default + // executable name. + if (executablePath && search->allowExecutableOverride) { + if (wcschr(executablePath, L' ') && executablePath[0] != L'"') { + buffer[0] = L'"'; + exitCode = wcscpy_s(&buffer[1], bufferLength - 1, executablePath); + if (!exitCode) { + exitCode = wcscat_s(buffer, bufferLength, L"\""); + } + } else { + exitCode = wcscpy_s(buffer, bufferLength, executablePath); + } + } else if (launch) { + if (!launch->installDir) { + fwprintf_s(stderr, L"Cannot launch %s %s because no install directory was specified", + launch->company, launch->tag); + exitCode = RC_NO_PYTHON; + } else if (!search->executable || !search->executableLength) { + fwprintf_s(stderr, L"Cannot launch %s %s because no executable name is available", + launch->company, launch->tag); + exitCode = RC_NO_PYTHON; + } else { + wchar_t executable[256]; + wcsncpy_s(executable, 256, search->executable, search->executableLength); + if ((wcschr(launch->installDir, L' ') && launch->installDir[0] != L'"') || + (wcschr(executable, L' ') && executable[0] != L'"')) { + buffer[0] = L'"'; + exitCode = wcscpy_s(&buffer[1], bufferLength - 1, launch->installDir); + if (!exitCode) { + exitCode = join(buffer, bufferLength, executable) ? 0 : RC_NO_MEMORY; + } + if (!exitCode) { + exitCode = wcscat_s(buffer, bufferLength, L"\""); + } + } else { + exitCode = wcscpy_s(buffer, bufferLength, launch->installDir); + if (!exitCode) { + exitCode = join(buffer, bufferLength, executable) ? 0 : RC_NO_MEMORY; + } + } + } + } else { + exitCode = RC_NO_PYTHON; + } + + if (!exitCode && launch && launch->executableArgs) { + exitCode = wcscat_s(buffer, bufferLength, L" "); + if (!exitCode) { + exitCode = wcscat_s(buffer, bufferLength, launch->executableArgs); + } + } + + if (!exitCode && search->executableArgs) { + if (search->executableArgsLength < 0) { + exitCode = wcscat_s(buffer, bufferLength, search->executableArgs); + } else if (search->executableArgsLength > 0) { + int end = (int)wcsnlen_s(buffer, MAXLEN); + if (end < bufferLength - (search->executableArgsLength + 1)) { + exitCode = wcsncpy_s(&buffer[end], bufferLength - end, + search->executableArgs, search->executableArgsLength); + } + } + } + + if (!exitCode && search->restOfCmdLine) { + exitCode = wcscat_s(buffer, bufferLength, search->restOfCmdLine); + } + + return exitCode; +} + + + +BOOL +_safeDuplicateHandle(HANDLE in, HANDLE * pout, const wchar_t *nameForError) +{ + BOOL ok; + HANDLE process = GetCurrentProcess(); + DWORD rc; + + *pout = NULL; + ok = DuplicateHandle(process, in, process, pout, 0, TRUE, + DUPLICATE_SAME_ACCESS); + if (!ok) { + rc = GetLastError(); + if (rc == ERROR_INVALID_HANDLE) { + debug(L"DuplicateHandle returned ERROR_INVALID_HANDLE\n"); + ok = TRUE; + } + else { + winerror(0, L"Failed to duplicate %s handle", nameForError); + } + } + return ok; +} + +BOOL WINAPI +ctrl_c_handler(DWORD code) +{ + return TRUE; /* We just ignore all control events. */ +} + + +int +launchEnvironment(const SearchInfo *search, const EnvironmentInfo *launch, wchar_t *launchCommand) +{ + HANDLE job; + JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; + DWORD rc; + BOOL ok; + STARTUPINFOW si; + PROCESS_INFORMATION pi; + + // If this is a dryrun, do not actually launch + if (isEnvVarSet(L"PYLAUNCHER_DRYRUN")) { + debug(L"LaunchCommand: %s\n", launchCommand); + debug(L"# Exiting due to PYLAUNCHER_DRYRUN variable\n"); + fflush(stdout); + int mode = _setmode(_fileno(stdout), _O_U8TEXT); + fwprintf(stdout, L"%s\n", launchCommand); + fflush(stdout); + if (mode >= 0) { + _setmode(_fileno(stdout), mode); + } + return 0; + } + +#if defined(_WINDOWS) + /* + When explorer launches a Windows (GUI) application, it displays + the "app starting" (the "pointer + hourglass") cursor for a number + of seconds, or until the app does something UI-ish (eg, creating a + window, or fetching a message). As this launcher doesn't do this + directly, that cursor remains even after the child process does these + things. We avoid that by doing a simple post+get message. + See http://bugs.python.org/issue17290 and + https://bitbucket.org/vinay.sajip/pylauncher/issue/20/busy-cursor-for-a-long-time-when-running + */ + MSG msg; + + PostMessage(0, 0, 0, 0); + GetMessage(&msg, 0, 0, 0); +#endif + + debug(L"# about to run: %s\n", launchCommand); + job = CreateJobObject(NULL, NULL); + ok = QueryInformationJobObject(job, JobObjectExtendedLimitInformation, + &info, sizeof(info), &rc); + if (!ok || (rc != sizeof(info)) || !job) { + winerror(0, L"Failed to query job information"); + return RC_CREATE_PROCESS; + } + info.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | + JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK; + ok = SetInformationJobObject(job, JobObjectExtendedLimitInformation, &info, + sizeof(info)); + if (!ok) { + winerror(0, L"Failed to update job information"); + return RC_CREATE_PROCESS; + } + memset(&si, 0, sizeof(si)); + GetStartupInfoW(&si); + if (!_safeDuplicateHandle(GetStdHandle(STD_INPUT_HANDLE), &si.hStdInput, L"stdin") || + !_safeDuplicateHandle(GetStdHandle(STD_OUTPUT_HANDLE), &si.hStdOutput, L"stdout") || + !_safeDuplicateHandle(GetStdHandle(STD_ERROR_HANDLE), &si.hStdError, L"stderr")) { + return RC_NO_STD_HANDLES; + } + + ok = SetConsoleCtrlHandler(ctrl_c_handler, TRUE); + if (!ok) { + winerror(0, L"Failed to update Control-C handler"); + return RC_NO_STD_HANDLES; + } + + si.dwFlags = STARTF_USESTDHANDLES; + ok = CreateProcessW(NULL, launchCommand, NULL, NULL, TRUE, + 0, NULL, NULL, &si, &pi); + if (!ok) { + winerror(0, L"Unable to create process using '%s'", launchCommand); + return RC_CREATE_PROCESS; + } + AssignProcessToJobObject(job, pi.hProcess); + CloseHandle(pi.hThread); + WaitForSingleObjectEx(pi.hProcess, INFINITE, FALSE); + ok = GetExitCodeProcess(pi.hProcess, &rc); + if (!ok) { + winerror(0, L"Failed to get exit code of process"); + return RC_CREATE_PROCESS; + } + debug(L"child process exit code: %d\n", rc); + return rc; +} + + +/******************************************************************************\ + *** PROCESS CONTROLLER *** +\******************************************************************************/ + + +int +performSearch(SearchInfo *search, EnvironmentInfo **envs) +{ + // First parse the command line for options + int exitCode = parseCommandLine(search); + if (exitCode) { + return exitCode; + } + + // Check for a shebang line in our script file + // (or return quickly if no script file was specified) + exitCode = checkShebang(search); + switch (exitCode) { + case 0: + case RC_NO_SHEBANG: + case RC_RECURSIVE_SHEBANG: + break; + default: + return exitCode; + } + + // Resolve old-style tags (possibly from a shebang) against py.ini entries + // and environment variables. + exitCode = checkDefaults(search); + if (exitCode) { + return exitCode; + } + + // If debugging is enabled, list our search criteria + dumpSearchInfo(search); + + // Find all matching environments + exitCode = collectEnvironments(search, envs); + if (exitCode) { + return exitCode; + } + + return 0; +} + + +int +process(int argc, wchar_t ** argv) +{ + int exitCode = 0; + int searchExitCode = 0; + SearchInfo search = {0}; + EnvironmentInfo *envs = NULL; + EnvironmentInfo *env = NULL; + wchar_t launchCommand[MAXLEN]; + + memset(launchCommand, 0, sizeof(launchCommand)); + + if (isEnvVarSet(L"PYLAUNCHER_DEBUG")) { + setvbuf(stderr, (char *)NULL, _IONBF, 0); + log_fp = stderr; + debug(L"argv0: %s\nversion: %S\n", argv[0], PY_VERSION); + } + + search.originalCmdLine = GetCommandLineW(); + + exitCode = performSearch(&search, &envs); + if (exitCode) { + goto abort; + } + + // Display the help text, but only exit on error + if (search.help) { + exitCode = showHelpText(argv); + if (exitCode) { + goto abort; + } + } + + // Select best environment + // This is early so that we can show the default when listing, but all + // responses to any errors occur later. + searchExitCode = selectEnvironment(&search, envs, &env); + + // List all environments, then exit + if (search.list || search.listPaths) { + exitCode = listEnvironments(envs, stdout, search.listPaths, env); + goto abort; + } + + // When debugging, list all discovered environments anyway + if (log_fp) { + exitCode = listEnvironments(envs, log_fp, true, NULL); + if (exitCode) { + goto abort; + } + } + + // We searched earlier, so if we didn't find anything, now we react + exitCode = searchExitCode; + // If none found, and if permitted, install it + if (exitCode == RC_NO_PYTHON && isEnvVarSet(L"PYLAUNCHER_ALLOW_INSTALL") || + isEnvVarSet(L"PYLAUNCHER_ALWAYS_INSTALL")) { + exitCode = installEnvironment(&search); + if (!exitCode) { + // Successful install, so we need to re-scan and select again + env = NULL; + exitCode = performSearch(&search, &envs); + if (exitCode) { + goto abort; + } + exitCode = selectEnvironment(&search, envs, &env); + } + } + if (exitCode == RC_NO_PYTHON) { + fputws(L"No suitable Python runtime found\n", stderr); + fputws(L"Pass --list (-0) to see all detected environments on your machine\n", stderr); + if (!isEnvVarSet(L"PYLAUNCHER_ALLOW_INSTALL") && search.oldStyleTag) { + fputws(L"or set environment variable PYLAUNCHER_ALLOW_INSTALL to use winget\n" + L"or open the Microsoft Store to the requested version.\n", stderr); + } + goto abort; + } + if (exitCode == RC_NO_PYTHON_AT_ALL) { + fputws(L"No installed Python found!\n", stderr); + goto abort; + } + if (exitCode) { + goto abort; + } + + if (env) { + debug(L"env.company: %s\nenv.tag: %s\n", env->company, env->tag); + } else { + debug(L"env.company: (null)\nenv.tag: (null)\n"); + } + + exitCode = calculateCommandLine(&search, env, launchCommand, sizeof(launchCommand) / sizeof(launchCommand[0])); + if (exitCode) { + goto abort; + } + + // Launch selected runtime + exitCode = launchEnvironment(&search, env, launchCommand); + +abort: + freeSearchInfo(&search); + freeEnvironmentInfo(envs); + return exitCode; +} + + +#if defined(_WINDOWS) + +int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPWSTR lpstrCmd, int nShow) +{ + return process(__argc, __wargv); +} + +#else + +int cdecl wmain(int argc, wchar_t ** argv) +{ + return process(argc, argv); +} + +#endif diff --git a/PC/layout/main.py b/PC/layout/main.py index fb6f5265859..c9246007d47 100644 --- a/PC/layout/main.py +++ b/PC/layout/main.py @@ -8,11 +8,8 @@ __author__ = "Steve Dower " __version__ = "3.8" import argparse -import functools import os -import re import shutil -import subprocess import sys import tempfile import zipfile @@ -38,7 +35,7 @@ TEST_DIRS_ONLY = FileNameSet("test", "tests") IDLE_DIRS_ONLY = FileNameSet("idlelib") -TCLTK_PYDS_ONLY = FileStemSet("tcl*", "tk*", "_tkinter") +TCLTK_PYDS_ONLY = FileStemSet("tcl*", "tk*", "_tkinter", "zlib1") TCLTK_DIRS_ONLY = FileNameSet("tkinter", "turtledemo") TCLTK_FILES_ONLY = FileNameSet("turtle.py") @@ -61,7 +58,7 @@ CDF_FILES = FileSuffixSet(".cdf") DATA_DIRS = FileNameSet("data") -TOOLS_DIRS = FileNameSet("scripts", "i18n", "pynche", "demo", "parser") +TOOLS_DIRS = FileNameSet("scripts", "i18n", "parser") TOOLS_FILES = FileSuffixSet(".py", ".pyw", ".txt") diff --git a/PC/layout/support/appxmanifest.py b/PC/layout/support/appxmanifest.py index 747c97a0069..1fb03380278 100644 --- a/PC/layout/support/appxmanifest.py +++ b/PC/layout/support/appxmanifest.py @@ -6,13 +6,11 @@ __author__ = "Steve Dower " __version__ = "3.8" -import collections import ctypes import io import os -import sys -from pathlib import Path, PureWindowsPath +from pathlib import PureWindowsPath from xml.etree import ElementTree as ET from .constants import * @@ -88,7 +86,8 @@ APPXMANIFEST_NS = { } APPXMANIFEST_TEMPLATE = """ - (10, 0, 17763): + # Only for Python 3.11 and later. Older versions do not disable virtualization + if (VER_MAJOR, VER_MINOR) >= (3, 11) and winver > (10, 0, 17763): disable_registry_virtualization(xml) app = add_application( @@ -430,7 +437,7 @@ def get_appxmanifest(ns): ["python", "python{}".format(VER_MAJOR), "python{}".format(VER_DOT)], PYTHON_VE_DATA, "console", - ("python.file", [".py"], '"%1"', "Python File", PY_PNG), + ("python.file", [".py"], '"%1" %*', "Python File", PY_PNG), ) add_application( @@ -441,7 +448,7 @@ def get_appxmanifest(ns): ["pythonw", "pythonw{}".format(VER_MAJOR), "pythonw{}".format(VER_DOT)], PYTHONW_VE_DATA, "windows", - ("python.windowedfile", [".pyw"], '"%1"', "Python File (no console)", PY_PNG), + ("python.windowedfile", [".pyw"], '"%1" %*', "Python File (no console)", PY_PNG), ) if ns.include_pip and ns.include_launchers: diff --git a/PC/layout/support/catalog.py b/PC/layout/support/catalog.py index 43121187ed1..c9d87cb8948 100644 --- a/PC/layout/support/catalog.py +++ b/PC/layout/support/catalog.py @@ -6,8 +6,6 @@ __author__ = "Steve Dower " __version__ = "3.8" -import sys - __all__ = ["PYTHON_CAT_NAME", "PYTHON_CDF_NAME"] diff --git a/PC/layout/support/constants.py b/PC/layout/support/constants.py index 6cf0fe1d34c..8195c3dc30c 100644 --- a/PC/layout/support/constants.py +++ b/PC/layout/support/constants.py @@ -6,7 +6,6 @@ __author__ = "Steve Dower " __version__ = "3.8" import os -import re import struct import sys @@ -16,7 +15,7 @@ def _unpack_hexversion(): hexversion = int(os.getenv("PYTHON_HEXVERSION"), 16) except (TypeError, ValueError): hexversion = sys.hexversion - return struct.pack(">i", sys.hexversion) + return struct.pack(">i", hexversion) def _get_suffix(field4): diff --git a/PC/layout/support/filesets.py b/PC/layout/support/filesets.py index 47f727c0578..3f63f686a9f 100644 --- a/PC/layout/support/filesets.py +++ b/PC/layout/support/filesets.py @@ -93,6 +93,8 @@ def _return_true(f): def rglob(root, patterns, condition=None): + if not os.path.isdir(root): + return if isinstance(patterns, tuple): for p in patterns: yield from _rglob(root, p, condition or _return_true) diff --git a/PC/layout/support/options.py b/PC/layout/support/options.py index 9faf20c0fdc..26d13f5377a 100644 --- a/PC/layout/support/options.py +++ b/PC/layout/support/options.py @@ -18,7 +18,6 @@ OPTIONS = { "stable": {"help": "stable ABI stub"}, "pip": {"help": "pip"}, "pip-user": {"help": "pip.ini file for default --user"}, - "distutils": {"help": "distutils"}, "tcltk": {"help": "Tcl, Tk and tkinter"}, "idle": {"help": "Idle"}, "tests": {"help": "test suite"}, @@ -43,7 +42,6 @@ PRESETS = { "stable", "pip", "pip-user", - "distutils", "tcltk", "idle", "venv", @@ -57,10 +55,8 @@ PRESETS = { "help": "nuget package", "options": [ "dev", - "tools", "pip", "stable", - "distutils", "venv", "props", "nuspec", @@ -72,15 +68,13 @@ PRESETS = { "options": [ "stable", "pip", - "distutils", "tcltk", "idle", "tests", - "tools", "venv", "dev", "symbols", - "chm", + "html-doc", ], }, "embed": { diff --git a/PC/layout/support/props.py b/PC/layout/support/props.py index 1eb9b7c06da..c7a7a0ce777 100644 --- a/PC/layout/support/props.py +++ b/PC/layout/support/props.py @@ -36,7 +36,6 @@ PROPS_TEMPLATE = r""" {PYTHON_VERSION} true - false false false @@ -68,7 +67,6 @@ PROPS_TEMPLATE = r""" DLLs\%(Filename)%(Extension) <_PythonRuntimeLib Include="$(PythonHome)\Lib\**\*" Exclude="$(PythonHome)\Lib\**\*.pyc;$(PythonHome)\Lib\site-packages\**\*" /> - <_PythonRuntimeLib Remove="$(PythonHome)\Lib\distutils\**\*" Condition="$(IncludeDistutils) != 'true'" /> <_PythonRuntimeLib Remove="$(PythonHome)\Lib\lib2to3\**\*" Condition="$(IncludeLib2To3) != 'true'" /> <_PythonRuntimeLib Remove="$(PythonHome)\Lib\ensurepip\**\*" Condition="$(IncludeVEnv) != 'true'" /> <_PythonRuntimeLib Remove="$(PythonHome)\Lib\venv\**\*" Condition="$(IncludeVEnv) != 'true'" /> diff --git a/PC/layout/support/python.props b/PC/layout/support/python.props index 4cc70083ebe..e46891aafcb 100644 --- a/PC/layout/support/python.props +++ b/PC/layout/support/python.props @@ -6,9 +6,8 @@ $(PythonHome)\libs $$PYTHON_TAG$$ $$PYTHON_VERSION$$ - + true - false false false @@ -41,7 +40,6 @@ DLLs\%(Filename)%(Extension) <_PythonRuntimeLib Include="$(PythonHome)\Lib\**\*" Exclude="$(PythonHome)\Lib\**\*.pyc;$(PythonHome)\Lib\site-packages\**\*" /> - <_PythonRuntimeLib Remove="$(PythonHome)\Lib\distutils\**\*" Condition="$(IncludeDistutils) != 'true'" /> <_PythonRuntimeLib Remove="$(PythonHome)\Lib\lib2to3\**\*" Condition="$(IncludeLib2To3) != 'true'" /> <_PythonRuntimeLib Remove="$(PythonHome)\Lib\ensurepip\**\*" Condition="$(IncludeVEnv) != 'true'" /> <_PythonRuntimeLib Remove="$(PythonHome)\Lib\venv\**\*" Condition="$(IncludeVEnv) != 'true'" /> @@ -50,7 +48,7 @@ - + diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c index 1f78d99c790..988d9c95aaa 100644 --- a/PC/msvcrtmodule.c +++ b/PC/msvcrtmodule.c @@ -38,6 +38,14 @@ class HANDLE_converter(CConverter): type = 'void *' format_unit = '"_Py_PARSE_UINTPTR"' + def parse_arg(self, argname, displayname): + return """ + {paramname} = PyLong_AsVoidPtr({argname}); + if (!{paramname} && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.parser_name) + class HANDLE_return_converter(CReturnConverter): type = 'void *' @@ -66,7 +74,7 @@ class wchar_t_return_converter(CReturnConverter): data.return_conversion.append( 'return_value = PyUnicode_FromOrdinal(_return_value);\n') [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=d102511df3cda2eb]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=1e8e9fa3538ec08f]*/ /*[clinic input] module msvcrt diff --git a/PC/pyconfig.h b/PC/pyconfig.h index b3e73d4dabe..f5166a1506c 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -66,9 +66,6 @@ WIN32 is still required for the locale module. #define MS_WIN32 /* only support win32 and greater. */ #define MS_WINDOWS -#ifndef PYTHONPATH -# define PYTHONPATH L".\\DLLs;.\\lib" -#endif #define NT_THREADS #define WITH_THREAD #ifndef NETSCAPE_PI @@ -79,30 +76,26 @@ WIN32 is still required for the locale module. /* Compiler specific defines */ /* ------------------------------------------------------------------------*/ -/* Microsoft C defines _MSC_VER */ +/* Microsoft C defines _MSC_VER, as does clang-cl.exe */ #ifdef _MSC_VER /* We want COMPILER to expand to a string containing _MSC_VER's *value*. * This is horridly tricky, because the stringization operator only works * on macro arguments, and doesn't evaluate macros passed *as* arguments. - * Attempts simpler than the following appear doomed to produce "_MSC_VER" - * literally in the string. */ #define _Py_PASTE_VERSION(SUFFIX) \ ("[MSC v." _Py_STRINGIZE(_MSC_VER) " " SUFFIX "]") /* e.g., this produces, after compile-time string catenation, - * ("[MSC v.1200 32 bit (Intel)]") + * ("[MSC v.1900 64 bit (Intel)]") * * _Py_STRINGIZE(_MSC_VER) expands to - * _Py_STRINGIZE1((_MSC_VER)) expands to - * _Py_STRINGIZE2(_MSC_VER) but as this call is the result of token-pasting - * it's scanned again for macros and so further expands to (under MSVC 6) - * _Py_STRINGIZE2(1200) which then expands to - * "1200" + * _Py_STRINGIZE1(_MSC_VER) and this second macro call is scanned + * again for macros and so further expands to + * _Py_STRINGIZE1(1900) which then expands to + * "1900" */ -#define _Py_STRINGIZE(X) _Py_STRINGIZE1((X)) -#define _Py_STRINGIZE1(X) _Py_STRINGIZE2 ## X -#define _Py_STRINGIZE2(X) #X +#define _Py_STRINGIZE(X) _Py_STRINGIZE1(X) +#define _Py_STRINGIZE1(X) #X /* MSVC defines _WINxx to differentiate the windows platform types @@ -116,20 +109,33 @@ WIN32 is still required for the locale module. #define MS_WIN64 #endif -/* set the COMPILER */ +/* set the COMPILER and support tier + * + * win_amd64 MSVC (x86_64-pc-windows-msvc): 1 + * win32 MSVC (i686-pc-windows-msvc): 1 + * win_arm64 MSVC (aarch64-pc-windows-msvc): 3 + * other archs and ICC: 0 + */ #ifdef MS_WIN64 #if defined(_M_X64) || defined(_M_AMD64) -#if defined(__INTEL_COMPILER) +#if defined(__clang__) +#define COMPILER ("[Clang " __clang_version__ "] 64 bit (AMD64) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") +#define PY_SUPPORT_TIER 0 +#elif defined(__INTEL_COMPILER) #define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 64 bit (amd64) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") +#define PY_SUPPORT_TIER 0 #else #define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)") -#endif /* __INTEL_COMPILER */ +#define PY_SUPPORT_TIER 1 +#endif /* __clang__ */ #define PYD_PLATFORM_TAG "win_amd64" #elif defined(_M_ARM64) #define COMPILER _Py_PASTE_VERSION("64 bit (ARM64)") +#define PY_SUPPORT_TIER 3 #define PYD_PLATFORM_TAG "win_arm64" #else #define COMPILER _Py_PASTE_VERSION("64 bit (Unknown)") +#define PY_SUPPORT_TIER 0 #endif #endif /* MS_WIN64 */ @@ -165,24 +171,33 @@ WIN32 is still required for the locale module. /* Define like size_t, omitting the "unsigned" */ #ifdef MS_WIN64 typedef __int64 Py_ssize_t; +# define PY_SSIZE_T_MAX LLONG_MAX #else typedef _W64 int Py_ssize_t; +# define PY_SSIZE_T_MAX INT_MAX #endif #define HAVE_PY_SSIZE_T 1 #if defined(MS_WIN32) && !defined(MS_WIN64) #if defined(_M_IX86) -#if defined(__INTEL_COMPILER) +#if defined(__clang__) +#define COMPILER ("[Clang " __clang_version__ "] 32 bit (Intel) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") +#define PY_SUPPORT_TIER 0 +#elif defined(__INTEL_COMPILER) #define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 32 bit (Intel) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") +#define PY_SUPPORT_TIER 0 #else #define COMPILER _Py_PASTE_VERSION("32 bit (Intel)") -#endif /* __INTEL_COMPILER */ +#define PY_SUPPORT_TIER 1 +#endif /* __clang__ */ #define PYD_PLATFORM_TAG "win32" #elif defined(_M_ARM) #define COMPILER _Py_PASTE_VERSION("32 bit (ARM)") #define PYD_PLATFORM_TAG "win_arm32" +#define PY_SUPPORT_TIER 0 #else #define COMPILER _Py_PASTE_VERSION("32 bit (Unknown)") +#define PY_SUPPORT_TIER 0 #endif #endif /* MS_WIN32 && !MS_WIN64 */ @@ -196,6 +211,16 @@ typedef int pid_t; #endif /* _MSC_VER */ +/* ------------------------------------------------------------------------*/ +/* mingw and mingw-w64 define __MINGW32__ */ +#ifdef __MINGW32__ + +#ifdef _WIN64 +#define MS_WIN64 +#endif + +#endif /* __MINGW32__*/ + /* ------------------------------------------------------------------------*/ /* egcs/gnu-win32 defines __GNUC__ and _WIN32 */ #if defined(__GNUC__) && defined(_WIN32) @@ -262,11 +287,11 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ file in their Makefile (other compilers are generally taken care of by distutils.) */ # if defined(_DEBUG) -# pragma comment(lib,"python311_d.lib") +# pragma comment(lib,"python312_d.lib") # elif defined(Py_LIMITED_API) # pragma comment(lib,"python3.lib") # else -# pragma comment(lib,"python311.lib") +# pragma comment(lib,"python312.lib") # endif /* _DEBUG */ # endif /* _MSC_VER */ # endif /* Py_BUILD_CORE */ @@ -517,6 +542,9 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ /* Define if you have siginterrupt. */ /* #undef HAVE_SIGINTERRUPT */ +/* Define to 1 if you have the `shutdown' function. */ +#define HAVE_SHUTDOWN 1 + /* Define if you have symlink. */ /* #undef HAVE_SYMLINK */ @@ -529,6 +557,9 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ /* Define if you have times. */ /* #undef HAVE_TIMES */ +/* Define to 1 if you have the `umask' function. */ +#define HAVE_UMASK 1 + /* Define if you have uname. */ /* #undef HAVE_UNAME */ @@ -564,9 +595,6 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ /* Define to 1 if you have the header file. */ #define HAVE_SIGNAL_H 1 -/* Define if you have the prototypes. */ -#define HAVE_STDARG_PROTOTYPES - /* Define if you have the header file. */ #define HAVE_STDDEF_H 1 @@ -659,8 +687,28 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ /* Define to 1 if you have the `erfc' function. */ #define HAVE_ERFC 1 -/* Define if you have the 'inet_pton' function. */ +// netdb.h functions (provided by winsock.h) +#define HAVE_GETHOSTNAME 1 +#define HAVE_GETHOSTBYADDR 1 +#define HAVE_GETHOSTBYNAME 1 +#define HAVE_GETPROTOBYNAME 1 +#define HAVE_GETSERVBYNAME 1 +#define HAVE_GETSERVBYPORT 1 +// sys/socket.h functions (provided by winsock.h) #define HAVE_INET_PTON 1 +#define HAVE_INET_NTOA 1 +#define HAVE_ACCEPT 1 +#define HAVE_BIND 1 +#define HAVE_CONNECT 1 +#define HAVE_GETSOCKNAME 1 +#define HAVE_LISTEN 1 +#define HAVE_RECVFROM 1 +#define HAVE_SENDTO 1 +#define HAVE_SETSOCKOPT 1 +#define HAVE_SOCKET 1 + +/* Define to 1 if you have the `dup' function. */ +#define HAVE_DUP 1 /* framework name */ #define _PYTHONFRAMEWORK "" @@ -668,6 +716,4 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ /* Define if libssl has X509_VERIFY_PARAM_set1_host and related function */ #define HAVE_X509_VERIFY_PARAM_SET1_HOST 1 -#define PLATLIBDIR "lib" - #endif /* !Py_CONFIG_H */ diff --git a/PC/pylauncher.rc b/PC/pylauncher.rc index ff7e71e0fdb..11862643aa6 100644 --- a/PC/pylauncher.rc +++ b/PC/pylauncher.rc @@ -25,6 +25,9 @@ 7 ICON DISCARDABLE "icons\setup.ico" #endif +1 USAGE "launcher-usage.txt" + + ///////////////////////////////////////////////////////////////////////////// // // Version diff --git a/PC/python3dll.c b/PC/python3dll.c index d2a87070de5..931f316bb99 100755 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -1,7 +1,7 @@ /* Re-export stable Python ABI */ -/* Generated by Tools/scripts/stable_abi.py */ +/* Generated by Tools/build/stable_abi.py */ #ifdef _M_IX86 #define DECORATE "_" @@ -19,6 +19,7 @@ EXPORT_FUNC(_Py_CheckRecursiveCall) EXPORT_FUNC(_Py_Dealloc) EXPORT_FUNC(_Py_DecRef) EXPORT_FUNC(_Py_IncRef) +EXPORT_FUNC(_Py_NegativeRefcount) EXPORT_FUNC(_Py_VaBuildValue_SizeT) EXPORT_FUNC(_PyArg_Parse_SizeT) EXPORT_FUNC(_PyArg_ParseTuple_SizeT) @@ -28,7 +29,6 @@ EXPORT_FUNC(_PyArg_VaParseTupleAndKeywords_SizeT) EXPORT_FUNC(_PyErr_BadInternalCall) EXPORT_FUNC(_PyObject_CallFunction_SizeT) EXPORT_FUNC(_PyObject_CallMethod_SizeT) -EXPORT_FUNC(_PyObject_GC_Malloc) EXPORT_FUNC(_PyObject_GC_New) EXPORT_FUNC(_PyObject_GC_NewVar) EXPORT_FUNC(_PyObject_GC_Resize) @@ -95,6 +95,14 @@ EXPORT_FUNC(PyArg_ValidateKeywordArguments) EXPORT_FUNC(PyArg_VaParse) EXPORT_FUNC(PyArg_VaParseTupleAndKeywords) EXPORT_FUNC(PyBool_FromLong) +EXPORT_FUNC(PyBuffer_FillContiguousStrides) +EXPORT_FUNC(PyBuffer_FillInfo) +EXPORT_FUNC(PyBuffer_FromContiguous) +EXPORT_FUNC(PyBuffer_GetPointer) +EXPORT_FUNC(PyBuffer_IsContiguous) +EXPORT_FUNC(PyBuffer_Release) +EXPORT_FUNC(PyBuffer_SizeFromFormat) +EXPORT_FUNC(PyBuffer_ToContiguous) EXPORT_FUNC(PyByteArray_AsString) EXPORT_FUNC(PyByteArray_Concat) EXPORT_FUNC(PyByteArray_FromObject) @@ -189,6 +197,7 @@ EXPORT_FUNC(PyErr_Fetch) EXPORT_FUNC(PyErr_Format) EXPORT_FUNC(PyErr_FormatV) EXPORT_FUNC(PyErr_GetExcInfo) +EXPORT_FUNC(PyErr_GetHandledException) EXPORT_FUNC(PyErr_GivenExceptionMatches) EXPORT_FUNC(PyErr_NewException) EXPORT_FUNC(PyErr_NewExceptionWithDoc) @@ -211,6 +220,7 @@ EXPORT_FUNC(PyErr_SetFromErrnoWithFilenameObject) EXPORT_FUNC(PyErr_SetFromErrnoWithFilenameObjects) EXPORT_FUNC(PyErr_SetFromWindowsErr) EXPORT_FUNC(PyErr_SetFromWindowsErrWithFilename) +EXPORT_FUNC(PyErr_SetHandledException) EXPORT_FUNC(PyErr_SetImportError) EXPORT_FUNC(PyErr_SetImportErrorSubclass) EXPORT_FUNC(PyErr_SetInterrupt) @@ -353,6 +363,7 @@ EXPORT_FUNC(PyMem_Malloc) EXPORT_FUNC(PyMem_Realloc) EXPORT_FUNC(PyMember_GetOne) EXPORT_FUNC(PyMember_SetOne) +EXPORT_FUNC(PyMemoryView_FromBuffer) EXPORT_FUNC(PyMemoryView_FromMemory) EXPORT_FUNC(PyMemoryView_FromObject) EXPORT_FUNC(PyMemoryView_GetContiguous) @@ -427,8 +438,10 @@ EXPORT_FUNC(PyObject_CallMethodObjArgs) EXPORT_FUNC(PyObject_CallNoArgs) EXPORT_FUNC(PyObject_CallObject) EXPORT_FUNC(PyObject_Calloc) +EXPORT_FUNC(PyObject_CheckBuffer) EXPORT_FUNC(PyObject_CheckReadBuffer) EXPORT_FUNC(PyObject_ClearWeakRefs) +EXPORT_FUNC(PyObject_CopyData) EXPORT_FUNC(PyObject_DelItem) EXPORT_FUNC(PyObject_DelItemString) EXPORT_FUNC(PyObject_Dir) @@ -446,6 +459,7 @@ EXPORT_FUNC(PyObject_GenericSetDict) EXPORT_FUNC(PyObject_GetAIter) EXPORT_FUNC(PyObject_GetAttr) EXPORT_FUNC(PyObject_GetAttrString) +EXPORT_FUNC(PyObject_GetBuffer) EXPORT_FUNC(PyObject_GetItem) EXPORT_FUNC(PyObject_GetIter) EXPORT_FUNC(PyObject_HasAttr) @@ -471,6 +485,9 @@ EXPORT_FUNC(PyObject_SetItem) EXPORT_FUNC(PyObject_Size) EXPORT_FUNC(PyObject_Str) EXPORT_FUNC(PyObject_Type) +EXPORT_FUNC(PyObject_Vectorcall) +EXPORT_FUNC(PyObject_VectorcallMethod) +EXPORT_FUNC(PyOS_CheckStack) EXPORT_FUNC(PyOS_double_to_string) EXPORT_FUNC(PyOS_FSPath) EXPORT_FUNC(PyOS_getsig) @@ -584,6 +601,7 @@ EXPORT_FUNC(PyTuple_Pack) EXPORT_FUNC(PyTuple_SetItem) EXPORT_FUNC(PyTuple_Size) EXPORT_FUNC(PyType_ClearCache) +EXPORT_FUNC(PyType_FromMetaclass) EXPORT_FUNC(PyType_FromModuleAndSpec) EXPORT_FUNC(PyType_FromSpec) EXPORT_FUNC(PyType_FromSpecWithBases) @@ -707,6 +725,8 @@ EXPORT_FUNC(PyUnicodeTranslateError_GetStart) EXPORT_FUNC(PyUnicodeTranslateError_SetEnd) EXPORT_FUNC(PyUnicodeTranslateError_SetReason) EXPORT_FUNC(PyUnicodeTranslateError_SetStart) +EXPORT_FUNC(PyVectorcall_Call) +EXPORT_FUNC(PyVectorcall_NARGS) EXPORT_FUNC(PyWeakref_GetObject) EXPORT_FUNC(PyWeakref_NewProxy) EXPORT_FUNC(PyWeakref_NewRef) @@ -716,6 +736,7 @@ EXPORT_DATA(_Py_EllipsisObject) EXPORT_DATA(_Py_FalseStruct) EXPORT_DATA(_Py_NoneStruct) EXPORT_DATA(_Py_NotImplementedStruct) +EXPORT_DATA(_Py_RefTotal) EXPORT_DATA(_Py_SwappedOp) EXPORT_DATA(_Py_TrueStruct) EXPORT_DATA(_PyWeakref_CallableProxyType) @@ -726,6 +747,7 @@ EXPORT_DATA(Py_FileSystemDefaultEncoding) EXPORT_DATA(Py_GenericAliasType) EXPORT_DATA(Py_HasFileSystemDefaultEncoding) EXPORT_DATA(Py_UTF8Mode) +EXPORT_DATA(Py_Version) EXPORT_DATA(PyBaseObject_Type) EXPORT_DATA(PyBool_Type) EXPORT_DATA(PyByteArray_Type) diff --git a/PC/python_uwp.cpp b/PC/python_uwp.cpp index 88369e8fbfe..2beea60e5af 100644 --- a/PC/python_uwp.cpp +++ b/PC/python_uwp.cpp @@ -10,6 +10,7 @@ #include +#include #include #include @@ -27,6 +28,35 @@ const wchar_t *PROGNAME = L"python.exe"; #endif #endif +static std::wstring +get_package_family() +{ + try { + UINT32 nameLength = MAX_PATH; + std::wstring name; + name.resize(nameLength); + DWORD rc = GetCurrentPackageFamilyName(&nameLength, name.data()); + if (rc == ERROR_SUCCESS) { + name.resize(nameLength - 1); + return name; + } + else if (rc != ERROR_INSUFFICIENT_BUFFER) { + throw rc; + } + name.resize(nameLength); + rc = GetCurrentPackageFamilyName(&nameLength, name.data()); + if (rc != ERROR_SUCCESS) { + throw rc; + } + name.resize(nameLength - 1); + return name; + } + catch (...) { + } + + return std::wstring(); +} + static std::wstring get_user_base() { @@ -35,31 +65,14 @@ get_user_base() if (appData) { const auto localCache = appData.LocalCacheFolder(); if (localCache) { - auto path = localCache.Path(); + std::wstring path { localCache.Path().c_str() }; if (!path.empty()) { - return std::wstring(path) + L"\\local-packages"; + return path + L"\\local-packages"; } } } } catch (...) { } - return std::wstring(); -} - -static std::wstring -get_package_family() -{ - try { - const auto package = winrt::Windows::ApplicationModel::Package::Current(); - if (package) { - const auto id = package.Id(); - if (id) { - return std::wstring(id.FamilyName()); - } - } - } - catch (...) { - } return std::wstring(); } @@ -68,13 +81,24 @@ static std::wstring get_package_home() { try { - const auto package = winrt::Windows::ApplicationModel::Package::Current(); - if (package) { - const auto path = package.InstalledLocation(); - if (path) { - return std::wstring(path.Path()); - } + UINT32 pathLength = MAX_PATH; + std::wstring path; + path.resize(pathLength); + DWORD rc = GetCurrentPackagePath(&pathLength, path.data()); + if (rc == ERROR_SUCCESS) { + path.resize(pathLength - 1); + return path; } + else if (rc != ERROR_INSUFFICIENT_BUFFER) { + throw rc; + } + path.resize(pathLength); + rc = GetCurrentPackagePath(&pathLength, path.data()); + if (rc != ERROR_SUCCESS) { + throw rc; + } + path.resize(pathLength - 1); + return path; } catch (...) { } diff --git a/PC/python_ver_rc.h b/PC/python_ver_rc.h index 90fc6ba1a14..5b55b810cd2 100644 --- a/PC/python_ver_rc.h +++ b/PC/python_ver_rc.h @@ -5,7 +5,7 @@ #include "winver.h" #define PYTHON_COMPANY "Python Software Foundation" -#define PYTHON_COPYRIGHT "Copyright \xA9 2001-2021 Python Software Foundation. Copyright \xA9 2000 BeOpen.com. Copyright \xA9 1995-2001 CNRI. Copyright \xA9 1991-1995 SMC." +#define PYTHON_COPYRIGHT "Copyright \xA9 2001-2023 Python Software Foundation. Copyright \xA9 2000 BeOpen.com. Copyright \xA9 1995-2001 CNRI. Copyright \xA9 1991-1995 SMC." #define MS_WINDOWS #include "modsupport.h" diff --git a/PC/readme.txt b/PC/readme.txt index 0a96d269b09..bef5111c591 100644 --- a/PC/readme.txt +++ b/PC/readme.txt @@ -18,7 +18,7 @@ All PC ports use this scheme to try to set up a module search path: 1) The script location; the current directory without script. 2) The PYTHONPATH variable, if set. - 3) For Win32 platforms (NT/95), paths specified in the Registry. + 3) Paths specified in the Registry. 4) Default directories lib, lib/win, lib/test, lib/tkinter; these are searched relative to the environment variable PYTHONHOME, if set, or relative to the executable and its @@ -26,8 +26,8 @@ All PC ports use this scheme to try to set up a module search path: or the current directory (not useful). 5) The directory containing the executable. -The best installation strategy is to put the Python executable (and -DLL, for Win32 platforms) in some convenient directory such as +The best installation strategy is to put the Python executable and +DLL in some convenient directory such as C:/python, and copy all library files and subdirectories (using XCOPY) to C:/python/lib. Then you don't need to set PYTHONPATH. Otherwise, set the environment variable PYTHONPATH to your Python search path. @@ -51,12 +51,6 @@ config.c The list of C modules to include in the Python PC version. Manually edit this file to add or remove Python modules. -testpy.py A Python test program. Run this to test your - Python port. It should produce copious output, - ending in a report on how many tests were OK, how many - failed, and how many were skipped. Don't worry about - skipped tests (these test unavailable optional features). - Additional files and subdirectories for 32-bit Windows ====================================================== diff --git a/PC/testpy.py b/PC/testpy.py deleted file mode 100644 index 709f35c4525..00000000000 --- a/PC/testpy.py +++ /dev/null @@ -1,30 +0,0 @@ -import sys - -# This is a test module for Python. It looks in the standard -# places for various *.py files. If these are moved, you must -# change this module too. - -try: - import os -except: - print("""Could not import the standard "os" module. - Please check your PYTHONPATH environment variable.""") - sys.exit(1) - -try: - import symbol -except: - print("""Could not import the standard "symbol" module. If this is - a PC, you should add the dos_8x3 directory to your PYTHONPATH.""") - sys.exit(1) - -for dir in sys.path: - file = os.path.join(dir, "os.py") - if os.path.isfile(file): - test = os.path.join(dir, "test") - if os.path.isdir(test): - # Add the "test" directory to PYTHONPATH. - sys.path = sys.path + [test] - -import libregrtest # Standard Python tester. -libregrtest.main() diff --git a/PC/winreg.c b/PC/winreg.c index 004a89a5355..63b37be526a 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -217,13 +217,11 @@ class winreg.HKEYType "PyHKEYObject *" "&PyHKEY_Type" /*[clinic end generated code: output=da39a3ee5e6b4b0d input=4c964eba3bf914d6]*/ /*[python input] -class REGSAM_converter(CConverter): +class REGSAM_converter(int_converter): type = 'REGSAM' - format_unit = 'i' -class DWORD_converter(CConverter): +class DWORD_converter(unsigned_long_converter): type = 'DWORD' - format_unit = 'k' class HKEY_converter(CConverter): type = 'HKEY' @@ -249,7 +247,7 @@ class self_return_converter(CReturnConverter): data.return_conversion.append( 'return_value = (PyObject *)_return_value;\n') [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=22f7aedc6d68e80e]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=2ebb7a4922d408d6]*/ #include "clinic/winreg.c.h" @@ -310,8 +308,7 @@ static PyHKEYObject * winreg_HKEYType___enter___impl(PyHKEYObject *self) /*[clinic end generated code: output=52c34986dab28990 input=c40fab1f0690a8e2]*/ { - Py_XINCREF(self); - return self; + return (PyHKEYObject*)Py_XNewRef(self); } @@ -564,42 +561,54 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize) { Py_ssize_t i,j; switch (typ) { - case REG_DWORD: - if (value != Py_None && !PyLong_Check(value)) - return FALSE; - *retDataBuf = (BYTE *)PyMem_NEW(DWORD, 1); - if (*retDataBuf == NULL){ - PyErr_NoMemory(); - return FALSE; - } - *retDataSize = sizeof(DWORD); - if (value == Py_None) { - DWORD zero = 0; - memcpy(*retDataBuf, &zero, sizeof(DWORD)); - } - else { - DWORD d = PyLong_AsUnsignedLong(value); + case REG_DWORD: + { + if (value != Py_None && !PyLong_Check(value)) { + return FALSE; + } + DWORD d; + if (value == Py_None) { + d = 0; + } + else if (PyLong_Check(value)) { + d = PyLong_AsUnsignedLong(value); + if (d == (DWORD)(-1) && PyErr_Occurred()) { + return FALSE; + } + } + *retDataBuf = (BYTE *)PyMem_NEW(DWORD, 1); + if (*retDataBuf == NULL) { + PyErr_NoMemory(); + return FALSE; + } memcpy(*retDataBuf, &d, sizeof(DWORD)); + *retDataSize = sizeof(DWORD); + break; } - break; - case REG_QWORD: - if (value != Py_None && !PyLong_Check(value)) - return FALSE; - *retDataBuf = (BYTE *)PyMem_NEW(DWORD64, 1); - if (*retDataBuf == NULL){ - PyErr_NoMemory(); - return FALSE; - } - *retDataSize = sizeof(DWORD64); - if (value == Py_None) { - DWORD64 zero = 0; - memcpy(*retDataBuf, &zero, sizeof(DWORD64)); - } - else { - DWORD64 d = PyLong_AsUnsignedLongLong(value); + case REG_QWORD: + { + if (value != Py_None && !PyLong_Check(value)) { + return FALSE; + } + DWORD64 d; + if (value == Py_None) { + d = 0; + } + else if (PyLong_Check(value)) { + d = PyLong_AsUnsignedLongLong(value); + if (d == (DWORD64)(-1) && PyErr_Occurred()) { + return FALSE; + } + } + *retDataBuf = (BYTE *)PyMem_NEW(DWORD64, 1); + if (*retDataBuf == NULL) { + PyErr_NoMemory(); + return FALSE; + } memcpy(*retDataBuf, &d, sizeof(DWORD64)); + *retDataSize = sizeof(DWORD64); + break; } - break; case REG_SZ: case REG_EXPAND_SZ: { @@ -645,19 +654,9 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize) t = PyList_GET_ITEM(value, j); if (!PyUnicode_Check(t)) return FALSE; -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - len = PyUnicode_GetSize(t); - if (len < 0) - return FALSE; - len++; -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ len = PyUnicode_AsWideChar(t, NULL, 0); if (len < 0) return FALSE; -#endif /* USE_UNICODE_WCHAR_CACHE */ size += Py_SAFE_DOWNCAST(len * sizeof(wchar_t), size_t, DWORD); } @@ -796,8 +795,7 @@ Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ) support it natively, we should handle the bits. */ default: if (retDataSize == 0) { - Py_INCREF(Py_None); - obData = Py_None; + obData = Py_NewRef(Py_None); } else obData = PyBytes_FromStringAndSize( @@ -991,7 +989,9 @@ winreg_DeleteKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key) (Py_ssize_t)0) < 0) { return NULL; } - rc = RegDeleteKeyW(key, sub_key ); + Py_BEGIN_ALLOW_THREADS + rc = RegDeleteKeyW(key, sub_key); + Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKey"); Py_RETURN_NONE; @@ -1012,7 +1012,10 @@ winreg.DeleteKeyEx reserved: int = 0 A reserved integer, and must be zero. Default is zero. -Deletes the specified key (64-bit OS only). +Deletes the specified key (intended for 64-bit OS). + +While this function is intended to be used for 64-bit OS, it is also + available on 32-bit systems. This method can not delete keys with subkeys. @@ -1025,34 +1028,17 @@ static PyObject * winreg_DeleteKeyEx_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key, REGSAM access, int reserved) -/*[clinic end generated code: output=52a1c8b374ebc003 input=711d9d89e7ecbed7]*/ +/*[clinic end generated code: output=52a1c8b374ebc003 input=a3186db079b3bf85]*/ { - HMODULE hMod; - typedef LONG (WINAPI *RDKEFunc)(HKEY, const wchar_t*, REGSAM, int); - RDKEFunc pfn = NULL; long rc; - if (PySys_Audit("winreg.DeleteKey", "nun", (Py_ssize_t)key, sub_key, (Py_ssize_t)access) < 0) { return NULL; } - /* Only available on 64bit platforms, so we must load it - dynamically. */ Py_BEGIN_ALLOW_THREADS - hMod = GetModuleHandleW(L"advapi32.dll"); - if (hMod) - pfn = (RDKEFunc)GetProcAddress(hMod, "RegDeleteKeyExW"); + rc = RegDeleteKeyExW(key, sub_key, access, reserved); Py_END_ALLOW_THREADS - if (!pfn) { - PyErr_SetString(PyExc_NotImplementedError, - "not implemented on this platform"); - return NULL; - } - Py_BEGIN_ALLOW_THREADS - rc = (*pfn)(key, sub_key, access, reserved); - Py_END_ALLOW_THREADS - if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKeyEx"); Py_RETURN_NONE; @@ -1709,40 +1695,27 @@ winreg_SetValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key, return NULL; } -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - const wchar_t *value = PyUnicode_AsUnicodeAndSize(value_obj, &value_length); -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ wchar_t *value = PyUnicode_AsWideCharString(value_obj, &value_length); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (value == NULL) { return NULL; } if ((Py_ssize_t)(DWORD)value_length != value_length) { PyErr_SetString(PyExc_OverflowError, "value is too long"); -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(value); -#endif /* USE_UNICODE_WCHAR_CACHE */ return NULL; } if (PySys_Audit("winreg.SetValue", "nunu#", (Py_ssize_t)key, sub_key, (Py_ssize_t)type, value, value_length) < 0) { -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(value); -#endif /* USE_UNICODE_WCHAR_CACHE */ return NULL; } Py_BEGIN_ALLOW_THREADS rc = RegSetValueW(key, sub_key, REG_SZ, value, (DWORD)(value_length + 1)); Py_END_ALLOW_THREADS -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(value); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValue"); Py_RETURN_NONE; @@ -2046,11 +2019,9 @@ PyMODINIT_FUNC PyInit_winreg(void) PyHKEY_Type.tp_doc = PyHKEY_doc; if (PyType_Ready(&PyHKEY_Type) < 0) return NULL; - Py_INCREF(&PyHKEY_Type); if (PyDict_SetItemString(d, "HKEYType", (PyObject *)&PyHKEY_Type) != 0) return NULL; - Py_INCREF(PyExc_OSError); if (PyDict_SetItemString(d, "error", PyExc_OSError) != 0) return NULL; @@ -2116,5 +2087,3 @@ PyMODINIT_FUNC PyInit_winreg(void) ADD_INT(REG_RESOURCE_REQUIREMENTS_LIST); return m; } - - diff --git a/PC/winsound.c b/PC/winsound.c index fd04e1e55b5..65025ddc5e1 100644 --- a/PC/winsound.c +++ b/PC/winsound.c @@ -94,17 +94,25 @@ winsound_PlaySound_impl(PyObject *module, PyObject *sound, int flags) return NULL; } wsound = (wchar_t *)view.buf; + } else if (PyBytes_Check(sound)) { + PyErr_Format(PyExc_TypeError, + "'sound' must be str, os.PathLike, or None, not '%s'", + Py_TYPE(sound)->tp_name); + return NULL; } else { - if (!PyUnicode_Check(sound)) { + PyObject *obj = PyOS_FSPath(sound); + // Either is unicode/bytes/NULL, or a helpful message + // has been surfaced to the user about how they gave a non-path. + if (obj == NULL) return NULL; + if (PyBytes_Check(obj)) { PyErr_Format(PyExc_TypeError, - "'sound' must be str or None, not '%s'", - Py_TYPE(sound)->tp_name); - return NULL; - } - wsound = PyUnicode_AsWideCharString(sound, NULL); - if (wsound == NULL) { + "'sound' must resolve to str, not bytes"); + Py_DECREF(obj); return NULL; } + wsound = PyUnicode_AsWideCharString(obj, NULL); + Py_DECREF(obj); + if (wsound == NULL) return NULL; } diff --git a/PCbuild/Directory.Build.props b/PCbuild/Directory.Build.props new file mode 100644 index 00000000000..3d2fe550784 --- /dev/null +++ b/PCbuild/Directory.Build.props @@ -0,0 +1,4 @@ + + + + diff --git a/PCbuild/Directory.Build.targets b/PCbuild/Directory.Build.targets new file mode 100644 index 00000000000..3d2fe550784 --- /dev/null +++ b/PCbuild/Directory.Build.targets @@ -0,0 +1,4 @@ + + + + diff --git a/PCbuild/_ctypes.vcxproj b/PCbuild/_ctypes.vcxproj index 69e4271a9bd..253da31e9ce 100644 --- a/PCbuild/_ctypes.vcxproj +++ b/PCbuild/_ctypes.vcxproj @@ -94,7 +94,7 @@ - FFI_BUILDING;%(PreprocessorDefinitions) + USING_MALLOC_CLOSURE_DOT_C=1;%(PreprocessorDefinitions) /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) @@ -102,7 +102,6 @@ - diff --git a/PCbuild/_ctypes.vcxproj.filters b/PCbuild/_ctypes.vcxproj.filters index 118c4f0698c..a38473e3e81 100644 --- a/PCbuild/_ctypes.vcxproj.filters +++ b/PCbuild/_ctypes.vcxproj.filters @@ -15,9 +15,6 @@ Header Files - - Header Files - diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj index 6a91776b9d8..4f39756019e 100644 --- a/PCbuild/_freeze_module.vcxproj +++ b/PCbuild/_freeze_module.vcxproj @@ -89,10 +89,13 @@ Py_NO_ENABLE_SHARED;Py_BUILD_CORE;_CONSOLE;%(PreprocessorDefinitions) + Disabled + false Console version.lib;ws2_32.lib;pathcch.lib;bcrypt.lib;%(AdditionalDependencies) + Default @@ -104,8 +107,10 @@ + + @@ -116,7 +121,6 @@ - @@ -168,7 +172,6 @@ - @@ -197,16 +200,19 @@ + + + @@ -226,7 +232,9 @@ - + + VPATH="$(PyVPath)";%(PreprocessorDefinitions) + @@ -302,6 +310,21 @@ $(IntDir)stat.g.h $(PySourcePath)Python\frozen_modules\stat.h + + importlib.util + $(IntDir)importlib.util.g.h + $(PySourcePath)Python\frozen_modules\importlib.util.h + + + importlib.machinery + $(IntDir)importlib.machinery.g.h + $(PySourcePath)Python\frozen_modules\importlib.machinery.h + + + runpy + $(IntDir)runpy.g.h + $(PySourcePath)Python\frozen_modules\runpy.h + __hello__ $(IntDir)__hello__.g.h @@ -334,9 +357,29 @@ + + + + getpath + $(IntDir)getpath.g.h + $(PySourcePath)Python\frozen_modules\getpath.h + + + + + + + + + + + @@ -349,9 +392,45 @@ + + + + + + + + + diff --git a/PCbuild/_freeze_module.vcxproj.filters b/PCbuild/_freeze_module.vcxproj.filters index 5894909e0fb..7d7c4587b9a 100644 --- a/PCbuild/_freeze_module.vcxproj.filters +++ b/PCbuild/_freeze_module.vcxproj.filters @@ -13,6 +13,404 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Python Files + @@ -58,6 +456,15 @@ Python Files + + Python Files + + + Python Files + + + Python Files + Python Files diff --git a/PCbuild/_socket.vcxproj b/PCbuild/_socket.vcxproj index 8fd75f90e7e..78fa4d6729a 100644 --- a/PCbuild/_socket.vcxproj +++ b/PCbuild/_socket.vcxproj @@ -93,7 +93,7 @@ - ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) + ws2_32.lib;iphlpapi.lib;Rpcrt4.lib;%(AdditionalDependencies) diff --git a/PCbuild/_sqlite3.vcxproj b/PCbuild/_sqlite3.vcxproj index e268c473f4c..57c7413671e 100644 --- a/PCbuild/_sqlite3.vcxproj +++ b/PCbuild/_sqlite3.vcxproj @@ -94,6 +94,7 @@ $(sqlite3Dir);%(AdditionalIncludeDirectories) + PY_SQLITE_HAVE_SERIALIZE;PY_SQLITE_ENABLE_LOAD_EXTENSION;%(PreprocessorDefinitions) @@ -105,6 +106,7 @@ + @@ -115,6 +117,7 @@ + diff --git a/PCbuild/_sqlite3.vcxproj.filters b/PCbuild/_sqlite3.vcxproj.filters index 79fc17b53fb..f4a265eba7d 100644 --- a/PCbuild/_sqlite3.vcxproj.filters +++ b/PCbuild/_sqlite3.vcxproj.filters @@ -36,6 +36,9 @@ Header Files + + Header Files + @@ -62,6 +65,9 @@ Source Files + + Source Files + diff --git a/PCbuild/_ssl.vcxproj b/PCbuild/_ssl.vcxproj index 4907f49b662..226ff506f8c 100644 --- a/PCbuild/_ssl.vcxproj +++ b/PCbuild/_ssl.vcxproj @@ -119,4 +119,4 @@ - \ No newline at end of file + diff --git a/PCbuild/_testcapi.vcxproj b/PCbuild/_testcapi.vcxproj index c1a19437253..58bf4e1eacb 100644 --- a/PCbuild/_testcapi.vcxproj +++ b/PCbuild/_testcapi.vcxproj @@ -94,6 +94,19 @@ + + + + + + + + + + + + + @@ -103,6 +116,10 @@ {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} false + + {885d4898-d08d-4091-9c40-c700cfe3fc5a} + false + diff --git a/PCbuild/_testcapi.vcxproj.filters b/PCbuild/_testcapi.vcxproj.filters index 53f64b7aa1e..101c5322761 100644 --- a/PCbuild/_testcapi.vcxproj.filters +++ b/PCbuild/_testcapi.vcxproj.filters @@ -12,6 +12,45 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + diff --git a/PCbuild/_testsinglephase.vcxproj b/PCbuild/_testsinglephase.vcxproj new file mode 100644 index 00000000000..fb4bcd95392 --- /dev/null +++ b/PCbuild/_testsinglephase.vcxproj @@ -0,0 +1,115 @@ + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + PGInstrument + ARM + + + PGInstrument + ARM64 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + ARM + + + PGUpdate + ARM64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {2097F1C1-597C-4167-93E3-656A7D6339B2} + Win32Proj + _testsinglephase + false + + + + + DynamicLibrary + NotSet + + + + .pyd + + + + + + + + + + + _CONSOLE;%(PreprocessorDefinitions) + + + Console + + + + + + + + + + + {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} + false + + + + + + diff --git a/PCbuild/_testsinglephase.vcxproj.filters b/PCbuild/_testsinglephase.vcxproj.filters new file mode 100644 index 00000000000..2a0e0ef66c1 --- /dev/null +++ b/PCbuild/_testsinglephase.vcxproj.filters @@ -0,0 +1,23 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Resource Files + + + diff --git a/PCbuild/_tkinter.vcxproj b/PCbuild/_tkinter.vcxproj index af813b77c1d..30cedcbb43d 100644 --- a/PCbuild/_tkinter.vcxproj +++ b/PCbuild/_tkinter.vcxproj @@ -111,6 +111,7 @@ <_TclTkDLL Include="$(tcltkdir)\bin\$(tclDllName)" /> <_TclTkDLL Include="$(tcltkdir)\bin\$(tkDllName)" /> + <_TclTkDLL Include="$(tcltkdir)\bin\$(tclZlibDllName)" /> diff --git a/PCbuild/_wmi.vcxproj b/PCbuild/_wmi.vcxproj new file mode 100644 index 00000000000..c1914a3fa5a --- /dev/null +++ b/PCbuild/_wmi.vcxproj @@ -0,0 +1,119 @@ + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + PGInstrument + ARM + + + PGInstrument + ARM64 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + ARM + + + PGUpdate + ARM64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {54B1431F-B86B-4ACB-B28C-88BCF93191D8} + _wmi + Win32Proj + false + + + + + DynamicLibrary + NotSet + + + + .pyd + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + + + + /std:c++20 %(AdditionalOptions) + + + wbemuuid.lib;propsys.lib;%(AdditionalDependencies) + ole32.dll + + + + + + + + + + + {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} + false + + + + + + \ No newline at end of file diff --git a/PCbuild/_wmi.vcxproj.filters b/PCbuild/_wmi.vcxproj.filters new file mode 100644 index 00000000000..fa8046237a0 --- /dev/null +++ b/PCbuild/_wmi.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {4fa4dbfa-e069-4ab4-86a6-ad389b2ec407} + + + + + Source Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/PCbuild/find_python.bat b/PCbuild/find_python.bat index d0e4a86b01f..11d6cba7a17 100644 --- a/PCbuild/find_python.bat +++ b/PCbuild/find_python.bat @@ -6,6 +6,11 @@ @rem changing any other persistent state. @rem +@set _Py_D=%~dp0 + +@rem First argument -q means only show the command in output +@if '%1' EQU '-q' (shift && set _Py_Quiet=1) + @rem No arguments provided means do full search @if '%1' EQU '' goto :begin_search @@ -28,16 +33,16 @@ @if NOT "%VIRTUAL_ENV%"=="" (set PYTHON="%VIRTUAL_ENV%\Scripts\python.exe") & (set _Py_Python_Source=found in virtual env) & goto :found @set _Py_EXTERNALS_DIR=%EXTERNALS_DIR% -@if "%_Py_EXTERNALS_DIR%"=="" (set _Py_EXTERNALS_DIR=%~dp0\..\externals) +@if "%_Py_EXTERNALS_DIR%"=="" (set _Py_EXTERNALS_DIR=%_Py_D%\..\externals) @rem If we have Python in externals, use that one -@if exist "%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe" (set PYTHON="%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe") & (set _Py_Python_Source=found in externals directory) & goto :found +@if exist "%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe" ("%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe" -Ec "import sys; assert sys.version_info[:2] >= (3, 8)" >nul 2>nul) && (set PYTHON="%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe") && (set _Py_Python_Source=found in externals directory) && goto :found || rmdir /Q /S "%_Py_EXTERNALS_DIR%\pythonx86" @rem If HOST_PYTHON is recent enough, use that -@if NOT "%HOST_PYTHON%"=="" @%HOST_PYTHON% -Ec "import sys; assert sys.version_info[:2] >= (3, 8)" >nul 2>nul && (set PYTHON="%HOST_PYTHON%") && (set _Py_Python_Source=found as HOST_PYTHON) && goto :found +@if NOT "%HOST_PYTHON%"=="" @%HOST_PYTHON% -Ec "import sys; assert sys.version_info[:2] >= (3, 9)" >nul 2>nul && (set PYTHON="%HOST_PYTHON%") && (set _Py_Python_Source=found as HOST_PYTHON) && goto :found @rem If py.exe finds a recent enough version, use that one -@for %%p in (3.9 3.8) do @py -%%p -EV >nul 2>&1 && (set PYTHON=py -%%p) && (set _Py_Python_Source=found %%p with py.exe) && goto :found +@for %%p in (3.10 3.9) do @py -%%p -EV >nul 2>&1 && (set PYTHON=py -%%p) && (set _Py_Python_Source=found %%p with py.exe) && goto :found @if NOT exist "%_Py_EXTERNALS_DIR%" mkdir "%_Py_EXTERNALS_DIR%" @set _Py_NUGET=%NUGET% @@ -53,15 +58,18 @@ @rem If it fails, retry with any available copy of Python @powershell.exe -Command Invoke-WebRequest %_Py_NUGET_URL% -OutFile '%_Py_NUGET%' @if errorlevel 1 ( - @%_Py_HOST_PYTHON% -E "%~dp0\urlretrieve.py" "%_Py_NUGET_URL%" "%_Py_NUGET%" + @%_Py_HOST_PYTHON% -E "%_Py_D%\urlretrieve.py" "%_Py_NUGET_URL%" "%_Py_NUGET%" ) ) -@echo Installing Python via nuget... + +@if not "%_Py_Quiet%"=="1" @echo Installing Python via nuget... @"%_Py_NUGET%" install pythonx86 -ExcludeVersion -OutputDirectory "%_Py_EXTERNALS_DIR%" @rem Quote it here; it's not quoted later because "py -x.y" wouldn't work @if not errorlevel 1 (set PYTHON="%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe") & (set _Py_Python_Source=found on nuget.org) & goto :found +@set _Py_D= +@set _Py_Quiet= @set _Py_Python_Source= @set _Py_EXTERNALS_DIR= @set _Py_NUGET= @@ -70,7 +78,10 @@ @exit /b 1 :found -@echo Using %PYTHON% (%_Py_Python_Source%) +@if "%_Py_Quiet%"=="1" (@echo %PYTHON%) else @echo Using %PYTHON% (%_Py_Python_Source%) + +@set _Py_D= +@set _Py_Quiet= @set _Py_Python_Source= @set _Py_EXTERNALS_DIR= @set _Py_NUGET= diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index 207f91baba5..0a41d131a3e 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -51,15 +51,15 @@ if NOT DEFINED PYTHON ( echo.Fetching external libraries... set libraries= -set libraries=%libraries% bzip2-1.0.6 -if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.4.2 -if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1l -set libraries=%libraries% sqlite-3.36.0.0 -if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.12.0 -if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.12.0 +set libraries=%libraries% bzip2-1.0.8 +if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.4.3 +if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1s +set libraries=%libraries% sqlite-3.39.4.0 +if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.13.0 +if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.13.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tix-8.4.3.6 -set libraries=%libraries% xz-5.2.2 -set libraries=%libraries% zlib-1.2.11 +set libraries=%libraries% xz-5.2.5 +set libraries=%libraries% zlib-1.2.13 for %%e in (%libraries%) do ( if exist "%EXTERNALS_DIR%\%%e" ( @@ -76,9 +76,9 @@ for %%e in (%libraries%) do ( echo.Fetching external binaries... set binaries= -if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.4.2 -if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1l -if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.12.0 +if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.4.3 +if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1s +if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.13.0 if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 for %%b in (%binaries%) do ( diff --git a/PCbuild/lib.pyproj b/PCbuild/lib.pyproj deleted file mode 100644 index 7dd40ad64a7..00000000000 --- a/PCbuild/lib.pyproj +++ /dev/null @@ -1,1824 +0,0 @@ - - - - Debug - 2.0 - {cb12a4c2-3757-4e67-8f51-c533876cefd1} - ..\Lib\ - abc.py - - . - . - {888888a0-9f3d-457c-b088-3a5042f75d52} - Standard Python launcher - - - - - - 10.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PCbuild/liblzma.vcxproj b/PCbuild/liblzma.vcxproj index a6bd59ec0ba..4dd42ab98a9 100644 --- a/PCbuild/liblzma.vcxproj +++ b/PCbuild/liblzma.vcxproj @@ -92,7 +92,7 @@ WIN32;HAVE_CONFIG_H;_LIB;%(PreprocessorDefinitions) - $(lzmaDir)windows;$(lzmaDir)src/liblzma/common;$(lzmaDir)src/common;$(lzmaDir)src/liblzma/api;$(lzmaDir)src/liblzma/check;$(lzmaDir)src/liblzma/delta;$(lzmaDir)src/liblzma/lz;$(lzmaDir)src/liblzma/lzma;$(lzmaDir)src/liblzma/rangecoder;$(lzmaDir)src/liblzma/simple;%(AdditionalIncludeDirectories) + $(lzmaDir)windows/vs2019;$(lzmaDir)src/liblzma/common;$(lzmaDir)src/common;$(lzmaDir)src/liblzma/api;$(lzmaDir)src/liblzma/check;$(lzmaDir)src/liblzma/delta;$(lzmaDir)src/liblzma/lz;$(lzmaDir)src/liblzma/lzma;$(lzmaDir)src/liblzma/rangecoder;$(lzmaDir)src/liblzma/simple;%(AdditionalIncludeDirectories) 4028;4113;4133;4244;4267;4996;%(DisableSpecificWarnings) @@ -238,7 +238,7 @@ - + diff --git a/PCbuild/liblzma.vcxproj.filters b/PCbuild/liblzma.vcxproj.filters index 3f58351fa9e..ebe2a7d5fa9 100644 --- a/PCbuild/liblzma.vcxproj.filters +++ b/PCbuild/liblzma.vcxproj.filters @@ -428,7 +428,7 @@ Header Files - + Header Files diff --git a/PCbuild/openssl.props b/PCbuild/openssl.props index a7e16793c7f..7071bb57c06 100644 --- a/PCbuild/openssl.props +++ b/PCbuild/openssl.props @@ -13,6 +13,7 @@ <_DLLSuffix>-1_1 <_DLLSuffix Condition="$(Platform) == 'ARM'">$(_DLLSuffix)-arm <_DLLSuffix Condition="$(Platform) == 'ARM64'">$(_DLLSuffix)-arm64 + $(_DLLSuffix) <_SSLDLL Include="$(opensslOutDir)\libcrypto$(_DLLSuffix).dll" /> @@ -20,10 +21,14 @@ <_SSLDLL Include="$(opensslOutDir)\libssl$(_DLLSuffix).dll" /> <_SSLDLL Include="$(opensslOutDir)\libssl$(_DLLSuffix).pdb" /> - + - + - \ No newline at end of file + diff --git a/PCbuild/pcbuild.proj b/PCbuild/pcbuild.proj index f32422a0acf..e13a0d40929 100644 --- a/PCbuild/pcbuild.proj +++ b/PCbuild/pcbuild.proj @@ -64,7 +64,7 @@ - + @@ -73,11 +73,11 @@ - + - + @@ -125,6 +125,12 @@ StopOnFirstFailure="false" Condition="%(CleanTarget) != ''" Targets="%(CleanTarget)" /> + @@ -140,6 +146,12 @@ StopOnFirstFailure="false" Condition="%(CleanAllTarget) != ''" Targets="%(CleanAllTarget)" /> + diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index 3629a8508a3..848d5950438 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -10,7 +10,42 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" ProjectSection(ProjectDependencies) = postProject + {9E48B300-37D1-11DD-8C41-005056C00008} = {9E48B300-37D1-11DD-8C41-005056C00008} + {9EC7190A-249F-4180-A900-548FDCF3055F} = {9EC7190A-249F-4180-A900-548FDCF3055F} + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687} = {78D80A15-BD8C-44E2-B49E-1F05B0A0A687} + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D} = {6901D91C-6E48-4BB7-9FEC-700C8131DF1D} + {54B1431F-B86B-4ACB-B28C-88BCF93191D8} = {54B1431F-B86B-4ACB-B28C-88BCF93191D8} + {F749B822-B489-4CA5-A3AD-CE078F5F338A} = {F749B822-B489-4CA5-A3AD-CE078F5F338A} + {D06B6426-4762-44CC-8BAD-D79052507F2F} = {D06B6426-4762-44CC-8BAD-D79052507F2F} + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781} = {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781} + {CB435430-EBB1-478B-8F4E-C256F6838F55} = {CB435430-EBB1-478B-8F4E-C256F6838F55} + {17E1E049-C309-4D79-843F-AE483C264AEA} = {17E1E049-C309-4D79-843F-AE483C264AEA} + {384C224A-7474-476E-A01B-750EA7DE918C} = {384C224A-7474-476E-A01B-750EA7DE918C} + {12728250-16EC-4DC6-94D7-E21DD88947F8} = {12728250-16EC-4DC6-94D7-E21DD88947F8} + {86937F53-C189-40EF-8CE8-8759D8E7D480} = {86937F53-C189-40EF-8CE8-8759D8E7D480} + {28B5D777-DDF2-4B6B-B34F-31D938813856} = {28B5D777-DDF2-4B6B-B34F-31D938813856} + {31FFC478-7B4A-43E8-9954-8D03E2187E9C} = {31FFC478-7B4A-43E8-9954-8D03E2187E9C} + {F9D71780-F393-11E0-BE50-0800200C9A66} = {F9D71780-F393-11E0-BE50-0800200C9A66} + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D} = {494BAC80-A60C-43A9-99E7-ACB691CE2C4D} + {C6E20F84-3247-4AD6-B051-B073268F73BA} = {C6E20F84-3247-4AD6-B051-B073268F73BA} + {B244E787-C445-441C-BDF4-5A4F1A3A1E51} = {B244E787-C445-441C-BDF4-5A4F1A3A1E51} + {18CAE28C-B454-46C1-87A0-493D91D97F03} = {18CAE28C-B454-46C1-87A0-493D91D97F03} + {13CECB97-4119-4316-9D42-8534019A5A44} = {13CECB97-4119-4316-9D42-8534019A5A44} + {885D4898-D08D-4091-9C40-C700CFE3FC5A} = {885D4898-D08D-4091-9C40-C700CFE3FC5A} + {447F05A8-F581-4CAC-A466-5AC7936E207E} = {447F05A8-F581-4CAC-A466-5AC7936E207E} + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881} = {ECC7CEAC-A5E5-458E-BB9E-2413CC847881} + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF} = {4946ECAC-2E69-4BF8-A90A-F5136F5094DF} + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D} = {FDB84CBB-2FB6-47C8-A2D6-091E0833239D} + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5} = {73FCD2BD-F133-46B7-8EC1-144CD82A59D5} + {2097F1C1-597C-4167-93E3-656A7D6339B2} = {2097F1C1-597C-4167-93E3-656A7D6339B2} + {A2697BD3-28C1-4AEC-9106-8B748639FD16} = {A2697BD3-28C1-4AEC-9106-8B748639FD16} + {900342D7-516A-4469-B1AD-59A66E49A25F} = {900342D7-516A-4469-B1AD-59A66E49A25F} + {6DAC66D9-E703-4624-BE03-49112AB5AA62} = {6DAC66D9-E703-4624-BE03-49112AB5AA62} + {0E9791DB-593A-465F-98BC-681011311617} = {0E9791DB-593A-465F-98BC-681011311617} {0E9791DB-593A-465F-98BC-681011311618} = {0E9791DB-593A-465F-98BC-681011311618} + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E} = {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E} + {16BFE6F0-22EF-40B5-B831-7E937119EF10} = {16BFE6F0-22EF-40B5-B831-7E937119EF10} + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742} = {FCBE1EF2-E0F0-40B1-88B5-00A35D378742} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" @@ -19,6 +54,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vc EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw", "pythonw.vcxproj", "{F4229CC3-873C-49AE-9729-DD308ED4CD4A}" + ProjectSection(ProjectDependencies) = postProject + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winsound", "winsound.vcxproj", "{28B5D777-DDF2-4B6B-B34F-31D938813856}" EndProject @@ -86,6 +124,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testembed", "_testembed.vc EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testmultiphase", "_testmultiphase.vcxproj", "{16BFE6F0-22EF-40B5-B831-7E937119EF10}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testsinglephase", "_testsinglephase.vcxproj", "{2097F1C1-597C-4167-93E3-656A7D6339B2}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyshellext", "pyshellext.vcxproj", "{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testconsole", "_testconsole.vcxproj", "{B244E787-C445-441C-BDF4-5A4F1A3A1E51}" @@ -99,15 +139,23 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblzma", "liblzma.vcxproj", "{12728250-16EC-4DC6-94D7-E21DD88947F8}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python_uwp", "python_uwp.vcxproj", "{9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}" + ProjectSection(ProjectDependencies) = postProject + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "venvlauncher", "venvlauncher.vcxproj", "{494BAC80-A60C-43A9-99E7-ACB691CE2C4D}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "venvwlauncher", "venvwlauncher.vcxproj", "{FDB84CBB-2FB6-47C8-A2D6-091E0833239D}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw_uwp", "pythonw_uwp.vcxproj", "{AB603547-1E2A-45B3-9E09-B04596006393}" + ProjectSection(ProjectDependencies) = postProject + {F4229CC3-873C-49AE-9729-DD308ED4CD4A} = {F4229CC3-873C-49AE-9729-DD308ED4CD4A} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_uuid", "_uuid.vcxproj", "{CB435430-EBB1-478B-8F4E-C256F6838F55}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_wmi", "_wmi.vcxproj", "{54B1431F-B86B-4ACB-B28C-88BCF93191D8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -1166,6 +1214,36 @@ Global {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|Win32.Build.0 = Release|Win32 {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|x64.ActiveCfg = Release|x64 {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|x64.Build.0 = Release|x64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Debug|ARM.ActiveCfg = Debug|ARM + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Debug|ARM.Build.0 = Debug|ARM + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Debug|ARM64.Build.0 = Debug|ARM64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Debug|Win32.ActiveCfg = Debug|Win32 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Debug|Win32.Build.0 = Debug|Win32 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Debug|x64.ActiveCfg = Debug|x64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Debug|x64.Build.0 = Debug|x64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGInstrument|x64.ActiveCfg = Release|x64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGUpdate|Win32.Build.0 = Release|Win32 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGUpdate|x64.ActiveCfg = Release|x64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGUpdate|x64.Build.0 = Release|x64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|ARM.ActiveCfg = Release|ARM + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|ARM.Build.0 = Release|ARM + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|ARM64.ActiveCfg = Release|ARM64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|ARM64.Build.0 = Release|ARM64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|Win32.ActiveCfg = Release|Win32 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|Win32.Build.0 = Release|Win32 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|x64.ActiveCfg = Release|x64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|x64.Build.0 = Release|x64 {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|ARM.ActiveCfg = Debug|ARM {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|ARM.Build.0 = Debug|ARM {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -1503,6 +1581,38 @@ Global {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|Win32.Build.0 = Release|Win32 {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|x64.ActiveCfg = Release|x64 {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|x64.Build.0 = Release|x64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Debug|ARM.ActiveCfg = Debug|ARM + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Debug|ARM.Build.0 = Debug|ARM + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Debug|ARM64.Build.0 = Debug|ARM64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Debug|Win32.ActiveCfg = Debug|Win32 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Debug|Win32.Build.0 = Debug|Win32 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Debug|x64.ActiveCfg = Debug|x64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Debug|x64.Build.0 = Debug|x64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|ARM.ActiveCfg = Release|ARM + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|ARM.Build.0 = Release|ARM + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|ARM64.ActiveCfg = Release|ARM64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|ARM64.Build.0 = Release|ARM64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|Win32.ActiveCfg = Release|Win32 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|Win32.Build.0 = Release|Win32 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|x64.ActiveCfg = Release|x64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PCbuild/prepare_tcltk.bat b/PCbuild/prepare_tcltk.bat index 77075af94f2..4a43ed1582c 100644 --- a/PCbuild/prepare_tcltk.bat +++ b/PCbuild/prepare_tcltk.bat @@ -53,3 +53,7 @@ call "%PCBUILD%\get_externals.bat" --tkinter-src %ORG_SETTING% %MSBUILD% "%PCBUILD%\tcl.vcxproj" /p:Configuration=Release /p:Platform=x64 %MSBUILD% "%PCBUILD%\tk.vcxproj" /p:Configuration=Release /p:Platform=x64 %MSBUILD% "%PCBUILD%\tix.vcxproj" /p:Configuration=Release /p:Platform=x64 + +%MSBUILD% "%PCBUILD%\tcl.vcxproj" /p:Configuration=Release /p:Platform=ARM64 +%MSBUILD% "%PCBUILD%\tk.vcxproj" /p:Configuration=Release /p:Platform=ARM64 +%MSBUILD% "%PCBUILD%\tix.vcxproj" /p:Configuration=Release /p:Platform=ARM64 diff --git a/PCbuild/pylauncher.vcxproj b/PCbuild/pylauncher.vcxproj index 550e0842300..35f2f7e505b 100644 --- a/PCbuild/pylauncher.vcxproj +++ b/PCbuild/pylauncher.vcxproj @@ -76,7 +76,7 @@ Application - MultiByte + Unicode @@ -95,12 +95,12 @@ MultiThreaded - version.lib;%(AdditionalDependencies) + shell32.lib;pathcch.lib;%(AdditionalDependencies) Console - + diff --git a/PCbuild/pyproject.props b/PCbuild/pyproject.props index bbcabb5cdb4..92c7849d3bc 100644 --- a/PCbuild/pyproject.props +++ b/PCbuild/pyproject.props @@ -18,13 +18,15 @@ true false false + false <_DebugPreprocessorDefinition>NDEBUG; <_DebugPreprocessorDefinition Condition="$(Configuration) == 'Debug'">_DEBUG; <_PlatformPreprocessorDefinition>_WIN32; - <_PlatformPreprocessorDefinition Condition="$(Platform) == 'x64'">_WIN64;_M_X64; + <_PlatformPreprocessorDefinition Condition="$(Platform) == 'x64'">_WIN64; + <_PlatformPreprocessorDefinition Condition="$(Platform) == 'x64' and $(PlatformToolset) != 'ClangCL'">_M_X64;$(_PlatformPreprocessorDefinition) <_Py3NamePreprocessorDefinition>PY3_DLLNAME=L"$(Py3DllName)"; @@ -44,7 +46,10 @@ true true $(EnableControlFlowGuard) + true /utf-8 %(AdditionalOptions) + -Wno-deprecated-non-prototype -Wno-unused-label -Wno-pointer-sign -Wno-incompatible-pointer-types-discards-qualifiers -Wno-unused-function %(AdditionalOptions) + -flto %(AdditionalOptions) OnlyExplicitInline @@ -225,4 +230,17 @@ public override bool Execute() { + + + + + + + @(_CmdExeLines) + + + + diff --git a/PCbuild/python.props b/PCbuild/python.props index b739e417fba..971c1490d9f 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -11,8 +11,8 @@ We set BasePlatformToolset for ICC's benefit, it's otherwise ignored. --> - v142 - v142 + v143 + v142 v141 v140 v120 @@ -53,21 +53,25 @@ $(BuildPath)\ $(BuildPath)instrumented\ + + ..\\.. + ..\\..\\.. + $(EXTERNALS_DIR) $([System.IO.Path]::GetFullPath(`$(PySourcePath)externals`)) $(ExternalsDir)\ - $(ExternalsDir)sqlite-3.36.0.0\ - $(ExternalsDir)bzip2-1.0.6\ - $(ExternalsDir)xz-5.2.2\ - $(ExternalsDir)libffi-3.4.2\ - $(ExternalsDir)libffi-3.4.2\$(ArchName)\ + $(ExternalsDir)sqlite-3.39.4.0\ + $(ExternalsDir)bzip2-1.0.8\ + $(ExternalsDir)xz-5.2.5\ + $(ExternalsDir)libffi-3.4.3\ + $(ExternalsDir)libffi-3.4.3\$(ArchName)\ $(libffiOutDir)include - $(ExternalsDir)openssl-1.1.1l\ - $(ExternalsDir)openssl-bin-1.1.1l\$(ArchName)\ + $(ExternalsDir)openssl-1.1.1s\ + $(ExternalsDir)openssl-bin-1.1.1s\$(ArchName)\ $(opensslOutDir)include $(ExternalsDir)\nasm-2.11.06\ - $(ExternalsDir)\zlib-1.2.11\ + $(ExternalsDir)\zlib-1.2.13\ _d diff --git a/PCbuild/python.vcxproj b/PCbuild/python.vcxproj index b58945a4d19..d07db3a6815 100644 --- a/PCbuild/python.vcxproj +++ b/PCbuild/python.vcxproj @@ -94,7 +94,8 @@ Console - 2000000 + 2000000 + 4000000 @@ -117,6 +118,10 @@ + + + + ucrtbase @@ -128,9 +133,6 @@ set PYTHONPATH=$(PySourcePath)Lib - <_PGOPath Condition="$(Configuration) == 'PGInstrument' and $(Platform) == 'Win32'">@set PATH=%PATH%%3B$(VCInstallDir)bin - <_PGOPath Condition="$(Configuration) == 'PGInstrument' and $(Platform) == 'x64'">@set PATH=%PATH%%3B$(VCInstallDir)bin\amd64 - <_PGOPath Condition="$(Configuration) == 'PGInstrument' and $(VC_PGO_RunTime_Dir) != ''">@set PATH=%PATH%%3B$(VC_PGO_RunTime_Dir) <_Content>@rem This script invokes the most recently built Python with all arguments @rem passed through to the interpreter. This file is generated by the @rem build process and any changes *will* be thrown away by the next @@ -140,11 +142,21 @@ set PYTHONPATH=$(PySourcePath)Lib @echo Running $(Configuration)^|$(Platform) interpreter... @setlocal @set PYTHONHOME=$(PySourcePath) -$(_PGOPath) @"$(OutDir)python$(PyDebugExt).exe" %* <_ExistingContent Condition="Exists('$(PySourcePath)python.bat')">$([System.IO.File]::ReadAllText('$(PySourcePath)python.bat')) + + + <_PGORT Include="$(VCToolsInstallDir)bin\Hostx86\x86\pgort140.dll" Condition="$(Platform) == 'Win32'" /> + <_PGORT Include="$(VCToolsInstallDir)bin\Hostx64\x64\pgort140.dll" Condition="$(Platform) == 'x64'" /> + <_PGORT Include="$(VCToolsInstallDir)bin\arm64\pgort140.dll" Condition="$(Platform) == 'ARM64'" /> + + + + + + diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 70f05563fa3..d3bd5b378e0 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -109,6 +109,19 @@ version.lib;ws2_32.lib;pathcch.lib;bcrypt.lib;%(AdditionalDependencies) + + + + PREFIX=NULL; + EXEC_PREFIX=NULL; + VERSION=NULL; + VPATH="$(PyVPath)"; + PYDEBUGEXT="$(PyDebugExt)"; + PLATLIBDIR="DLLs"; + %(PreprocessorDefinitions) + + + @@ -116,7 +129,6 @@ - @@ -128,7 +140,9 @@ + + @@ -141,7 +155,9 @@ + + @@ -152,11 +168,14 @@ + + + @@ -175,7 +194,6 @@ - @@ -183,46 +201,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -240,6 +286,7 @@ + @@ -251,10 +298,12 @@ + + @@ -262,7 +311,6 @@ - @@ -271,9 +319,6 @@ - - - @@ -297,12 +342,10 @@ - - @@ -335,19 +378,25 @@ - + + + + - + + USE_ZLIB_CRC32;%(PreprocessorDefinitions) + + @@ -386,7 +435,6 @@ - @@ -441,7 +489,6 @@ - @@ -469,16 +516,19 @@ + + + @@ -498,16 +548,25 @@ - + + VPATH="$(PyVPath)";%(PreprocessorDefinitions) + + + + + + - + + 4244 + @@ -545,12 +604,12 @@ - + GITVERSION="$(GitVersion)";GITTAG="$(GitTag)";GITBRANCH="$(GitBranch)";%(PreprocessorDefinitions) - + @@ -565,4 +624,8 @@ + + + + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index b19f0279ec3..c1b531fd818 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -132,9 +132,6 @@ Include - - Include - Include @@ -147,6 +144,9 @@ Include + + Include + Include @@ -174,6 +174,9 @@ Include + + Include + Include @@ -189,6 +192,9 @@ Include + + Include + Include @@ -210,9 +216,6 @@ Include - - Include - Include @@ -234,15 +237,6 @@ Modules - - Modules - - - Modules - - - Modules - Modules\_io @@ -315,15 +309,9 @@ Python - - Python - Python - - Python - Include @@ -363,9 +351,15 @@ Include + + Include + Include\cpython + + Include\cpython + Include\cpython @@ -390,6 +384,9 @@ Include + + Include + Include @@ -405,6 +402,9 @@ Include\cpython + + Include\cpython + Include\cpython @@ -435,6 +435,9 @@ Include\cpython + + Include\cpython + Include\cpython @@ -459,6 +462,12 @@ Include\cpython + + Include\cpython + + + Include\cpython + Include\cpython @@ -468,15 +477,18 @@ Include\cpython + + Include\internal + + + Include\internal + Include\internal Include\internal - - Include\internal - Include\internal @@ -498,12 +510,18 @@ Include\internal + + Include\internal + Include\internal Include\internal + + Include\internal + Include\internal @@ -516,9 +534,24 @@ Include\internal + + Include\internal + + + Include\internal + + + Include\internal + Include\internal + + Include\internal + + + Include\internal + Include\internal @@ -528,15 +561,27 @@ Include\internal + + Include\internal + Include\internal + + Include\internal + Include\internal Include\internal + + Include\internal + + + Include\internal + Include\internal @@ -555,6 +600,9 @@ Include\cpython + + Include\cpython + Include\internal @@ -570,6 +618,12 @@ Include\internal + + Include\internal + + + Include\internal + Include\internal @@ -588,12 +642,33 @@ Include\internal + + Include\internal + Include\internal + + Include\internal + + + Include\internal + Include\internal + + Include\internal + + + Include\internal + + + Include\internal + + + Include\internal + Include\internal @@ -603,12 +678,24 @@ Include\internal + + Include\internal + + + Include\internal + Include\internal + + Include\internal + Include\internal + + Include\internal + Include\internal @@ -648,6 +735,9 @@ Modules\zlib + + Include\internal + @@ -698,9 +788,18 @@ Modules - + Modules + + Modules + + + Modules + + + Modules + Modules @@ -971,9 +1070,6 @@ PC - - PC - PC @@ -1043,6 +1139,9 @@ Python + + Python + Modules @@ -1055,6 +1154,9 @@ Python + + Source Files + Python @@ -1070,6 +1172,9 @@ Python + + Python + Python @@ -1229,6 +1334,21 @@ Objects + + Python + + + Modules + + + Python + + + Python + + + Modules + diff --git a/PCbuild/pywlauncher.vcxproj b/PCbuild/pywlauncher.vcxproj index 44e3fc29272..e50b69aefe2 100644 --- a/PCbuild/pywlauncher.vcxproj +++ b/PCbuild/pywlauncher.vcxproj @@ -95,12 +95,12 @@ MultiThreaded - version.lib;%(AdditionalDependencies) + shell32.lib;pathcch.lib;%(AdditionalDependencies) Windows - + diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index 26b42a80320..3ed26a47b06 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -1,7 +1,7 @@ Quick Start Guide ----------------- -1. Install Microsoft Visual Studio 2017 with Python workload and +1. Install Microsoft Visual Studio 2017 or later with Python workload and Python native development component. 1a. Optionally install Python 3.6 or later. If not installed, get_externals.bat (via build.bat) will download and use Python via @@ -13,12 +13,10 @@ Quick Start Guide Building Python using Microsoft Visual C++ ------------------------------------------ -This directory is used to build CPython for Microsoft Windows NT version -6.0 or higher (Windows Vista, Windows Server 2008, or later) on 32 and 64 +This directory is used to build CPython for Microsoft Windows on 32- and 64- bit platforms. Using this directory requires an installation of -Microsoft Visual Studio 2017 (MSVC 14.1) with the *Python workload* and -its optional *Python native development* component selected. (For -command-line builds, Visual Studio 2015 may also be used.) +Microsoft Visual Studio (MSVC) with the *Python workload* and +its optional *Python native development* component selected. Building from the command line is recommended in order to obtain any external dependencies. To build, simply run the "build.bat" script without @@ -105,7 +103,7 @@ pythonw Prompt window pylauncher py.exe, the Python Launcher for Windows, see - http://docs.python.org/3/using/windows.html#launcher + https://docs.python.org/3/using/windows.html#launcher pywlauncher pyw.exe, a variant of py.exe that doesn't open a Command Prompt window @@ -149,6 +147,7 @@ _testcapi _testconsole _testimportmultiple _testmultiphase +_testsinglephase _tkinter pyexpat select @@ -162,20 +161,20 @@ interpreter, but they do implement several major features. See the about getting the source for building these libraries. The sub-projects are: _bz2 - Python wrapper for version 1.0.6 of the libbzip2 compression library + Python wrapper for version 1.0.8 of the libbzip2 compression library Homepage: http://www.bzip.org/ _lzma Python wrapper for version 5.2.2 of the liblzma compression library Homepage: - http://tukaani.org/xz/ + https://tukaani.org/xz/ _ssl - Python wrapper for version 1.1.1k of the OpenSSL secure sockets + Python wrapper for version 1.1.1q of the OpenSSL secure sockets library, which is downloaded from our binaries repository at https://github.com/python/cpython-bin-deps. Homepage: - http://www.openssl.org/ + https://www.openssl.org/ Building OpenSSL requires Perl on your path, and can be performed by running PCbuild\prepare_ssl.bat. This will retrieve the version of @@ -189,16 +188,16 @@ _ssl again when building. _sqlite3 - Wraps SQLite 3.36.0, which is itself built by sqlite3.vcxproj + Wraps SQLite 3.39.4, which is itself built by sqlite3.vcxproj Homepage: - http://www.sqlite.org/ + https://www.sqlite.org/ _tkinter Wraps version 8.6.6 of the Tk windowing system, which is downloaded from our binaries repository at https://github.com/python/cpython-bin-deps. Homepage: - http://www.tcl.tk/ + https://www.tcl.tk/ Building Tcl and Tk can be performed by running PCbuild\prepare_tcltk.bat. This will retrieve the version of the @@ -257,7 +256,7 @@ It creates the PGI files, runs the unit test suite or PyBench with the PGI python, and finally creates the optimized files. See - http://msdn.microsoft.com/en-us/library/e7k32f4k(VS.140).aspx + https://docs.microsoft.com/en-us/cpp/build/profile-guided-optimizations for more on this topic. diff --git a/PCbuild/regen.targets b/PCbuild/regen.targets index c0bde1ec6ba..aeb7e2e185d 100644 --- a/PCbuild/regen.targets +++ b/PCbuild/regen.targets @@ -1,11 +1,5 @@ - - - $(PYTHON) - - - <_PegenSources Include="$(PySourcePath)Grammar\python.gram;$(PySourcePath)Grammar\Tokens" /> <_PegenOutputs Include="$(PySourcePath)Parser\parser.c" /> @@ -19,13 +13,13 @@ <_ASTOutputs Include="$(PySourcePath)Python\Python-ast.c"> -C - <_OpcodeSources Include="$(PySourcePath)Tools\scripts\generate_opcode_h.py;$(PySourcePath)Lib\opcode.py" /> - <_OpcodeOutputs Include="$(PySourcePath)Include\opcode.h;$(PySourcePath)Python\opcode_targets.h" /> + <_OpcodeSources Include="$(PySourcePath)Tools\build\generate_opcode_h.py;$(PySourcePath)Lib\opcode.py" /> + <_OpcodeOutputs Include="$(PySourcePath)Include\opcode.h;$(PySourcePath)Include\internal\pycore_opcode.h;$(PySourcePath)Python\opcode_targets.h" /> <_TokenSources Include="$(PySourcePath)Grammar\Tokens" /> <_TokenOutputs Include="$(PySourcePath)Doc\library\token-list.inc"> rst - <_TokenOutputs Include="$(PySourcePath)Include\token.h"> + <_TokenOutputs Include="$(PySourcePath)Include\internal\pycore_token.h"> h <_TokenOutputs Include="$(PySourcePath)Parser\token.c"> @@ -44,43 +38,60 @@ AlwaysCreate="False" /> - + - + - + - - + - - + + + + + + + DependsOnTargets="_TouchRegenSources;_RegenPegen;_RegenAST_H;_RegenOpcodes;_RegenTokens;_RegenKeywords;_RegenGlobalObjects"> diff --git a/PCbuild/sqlite3.vcxproj b/PCbuild/sqlite3.vcxproj index 310795c4e4d..c502d51833b 100644 --- a/PCbuild/sqlite3.vcxproj +++ b/PCbuild/sqlite3.vcxproj @@ -98,7 +98,7 @@ $(sqlite3Dir);%(AdditionalIncludeDirectories) - SQLITE_ENABLE_MATH_FUNCTIONS;SQLITE_ENABLE_JSON1;SQLITE_ENABLE_FTS4;SQLITE_ENABLE_FTS5;SQLITE_ENABLE_RTREE;SQLITE_OMIT_AUTOINIT;SQLITE_API=__declspec(dllexport);%(PreprocessorDefinitions) + SQLITE_ENABLE_MATH_FUNCTIONS;SQLITE_ENABLE_FTS4;SQLITE_ENABLE_FTS5;SQLITE_ENABLE_RTREE;SQLITE_OMIT_AUTOINIT;SQLITE_API=__declspec(dllexport);%(PreprocessorDefinitions) Level1 diff --git a/PCbuild/tcl.vcxproj b/PCbuild/tcl.vcxproj index 4536cbc925b..ab68db9210f 100644 --- a/PCbuild/tcl.vcxproj +++ b/PCbuild/tcl.vcxproj @@ -33,6 +33,10 @@ Release x64 + + Release + ARM64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283} @@ -59,8 +63,8 @@ setlocal set VCINSTALLDIR=$(VCInstallDir) cd /D "$(tclDir)win" -nmake -f makefile.vc MACHINE=$(TclMachine) OPTS=$(TclOpts) $(TclDirs) $(DebugFlags) $(WarningsFlags) core shell dlls -nmake -f makefile.vc MACHINE=$(TclMachine) OPTS=$(TclOpts) $(TclDirs) $(DebugFlags) $(WarningsFlags) install-binaries install-libraries +nmake -f makefile.vc MACHINE=$(TclMachine) OPTS=$(TclOpts) $(TclDirs) $(DebugFlags) $(WarningsFlags) TCLSH_NATIVE="$(tclWin32Exe)" core shell dlls +nmake -f makefile.vc MACHINE=$(TclMachine) OPTS=$(TclOpts) $(TclDirs) $(DebugFlags) $(WarningsFlags) TCLSH_NATIVE="$(tclWin32Exe)" install-binaries install-libraries copy /Y ..\license.terms "$(OutDir)\tcllicense.terms" diff --git a/PCbuild/tcltk.props b/PCbuild/tcltk.props index 16dc35d45eb..15c03e20fe2 100644 --- a/PCbuild/tcltk.props +++ b/PCbuild/tcltk.props @@ -4,7 +4,7 @@ 8 6 - 12 + 13 0 $(TclMajorVersion) $(TclMinorVersion) @@ -18,17 +18,22 @@ $(ExternalsDir)tk-$(TkMajorVersion).$(TkMinorVersion).$(TkPatchLevel).$(TkRevision)\ $(ExternalsDir)tix-$(TixMajorVersion).$(TixMinorVersion).$(TixPatchLevel).$(TixRevision)\ $(ExternalsDir)tcltk-$(TclMajorVersion).$(TclMinorVersion).$(TclPatchLevel).$(TclRevision)\$(ArchName)\ + $(tcltkDir)\bin\tclsh$(TclMajorVersion)$(TclMinorVersion)t.exe + $(tcltkDir)\..\win32\bin\tclsh$(TclMajorVersion)$(TclMinorVersion)t.exe + tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).dll tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).lib tclsh$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).exe tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).dll tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).lib + zlib1.dll tix$(TixMajorVersion)$(TixMinorVersion)$(TclDebugExt).dll $(tcltkDir)lib\tix$(TixMajorVersion).$(TixMinorVersion).$(TixPatchLevel)\$(tixDLLName) $(tcltkDir)lib\tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).lib;$(tcltkDir)lib\tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).lib IX86 AMD64 + ARM64 TCL_MAJOR_VERSION=$(TclMajorVersion) TCL_MINOR_VERSION=$(TclMinorVersion) TCL_PATCH_LEVEL=$(TclPatchLevel) TCL_MAJOR=$(TclMajorVersion) TCL_MINOR=$(TclMinorVersion) TCL_PATCH=$(TclPatchLevel) TK_MAJOR_VERSION=$(TkMajorVersion) TK_MINOR_VERSION=$(TkMinorVersion) TK_PATCH_LEVEL=$(TkPatchLevel) diff --git a/PCbuild/tix.vcxproj b/PCbuild/tix.vcxproj index 51682094cb8..48abcd27c87 100644 --- a/PCbuild/tix.vcxproj +++ b/PCbuild/tix.vcxproj @@ -33,6 +33,10 @@ Release x64 + + Release + ARM64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555} @@ -53,7 +57,7 @@ - BUILDDIRTOP="$(BuildDirTop)" TCL_DIR="$(tclDir.TrimEnd(`\`))" TK_DIR="$(tkDir.TrimEnd(`\`))" INSTALL_DIR="$(OutDir.TrimEnd(`\`))" + BUILDDIRTOP="$(BuildDirTop)" TCL_DIR="$(tclDir.TrimEnd(`\`))" TK_DIR="$(tkDir.TrimEnd(`\`))" INSTALL_DIR="$(OutDir.TrimEnd(`\`))" TCLSH_EXE="$(tclWin32Exe)" DEBUG=1 NODEBUG=0 TCL_DBGX=g TK_DBGX=g DEBUG=0 NODEBUG=1 -c -W3 -nologo -MD -wd4028 -wd4090 -wd4244 -wd4267 -wd4312 diff --git a/PCbuild/tk.vcxproj b/PCbuild/tk.vcxproj index 70b5459a081..b111969ca5d 100644 --- a/PCbuild/tk.vcxproj +++ b/PCbuild/tk.vcxproj @@ -32,6 +32,10 @@ Release x64 + + + Release + ARM64 @@ -60,8 +64,8 @@ setlocal set VCINSTALLDIR=$(VCInstallDir) cd /D "$(tkDir)win" -nmake /nologo -f makefile.vc RC=rc MACHINE=$(TclMachine) OPTS=$(TkOpts) $(TkDirs) $(DebugFlags) $(WarningsFlags) all -nmake /nologo -f makefile.vc RC=rc MACHINE=$(TclMachine) OPTS=$(TkOpts) $(TkDirs) $(DebugFlags) $(WarningsFlags) install-binaries install-libraries +nmake /nologo -f makefile.vc RC=rc MACHINE=$(TclMachine) OPTS=$(TkOpts) $(TkDirs) $(DebugFlags) $(WarningsFlags) TCLSH_NATIVE="$(tclWin32Exe)" all +nmake /nologo -f makefile.vc RC=rc MACHINE=$(TclMachine) OPTS=$(TkOpts) $(TkDirs) $(DebugFlags) $(WarningsFlags) TCLSH_NATIVE="$(tclWin32Exe)" install-binaries install-libraries copy /Y ..\license.terms "$(OutDir)\tklicense.terms" diff --git a/Parser/Python.asdl b/Parser/Python.asdl index 85225fc88c5..e9423a7c984 100644 --- a/Parser/Python.asdl +++ b/Parser/Python.asdl @@ -40,6 +40,7 @@ module Python | Raise(expr? exc, expr? cause) | Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody) + | TryStar(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody) | Assert(expr test, expr? msg) | Import(alias* names) @@ -74,7 +75,7 @@ module Python -- x < 4 < 3 and (x < 4) < 3 | Compare(expr left, cmpop* ops, expr* comparators) | Call(expr func, expr* args, keyword* keywords) - | FormattedValue(expr value, int? conversion, expr? format_spec) + | FormattedValue(expr value, int conversion, expr? format_spec) | JoinedStr(expr* values) | Constant(constant value, string? kind) diff --git a/Parser/action_helpers.c b/Parser/action_helpers.c index e5d7b667f7f..46390966892 100644 --- a/Parser/action_helpers.c +++ b/Parser/action_helpers.c @@ -2,28 +2,12 @@ #include "pegen.h" #include "string_parser.h" - -static PyObject * -_create_dummy_identifier(Parser *p) -{ - return _PyPegen_new_identifier(p, ""); -} +#include "pycore_runtime.h" // _PyRuntime void * _PyPegen_dummy_name(Parser *p, ...) { - static void *cache = NULL; - - if (cache != NULL) { - return cache; - } - - PyObject *id = _create_dummy_identifier(p); - if (!id) { - return NULL; - } - cache = _PyAST_Name(id, Load, 1, 0, 1, 0, p->arena); - return cache; + return &_PyRuntime.parser.dummy_name; } /* Creates a single-element asdl_seq* that contains a */ @@ -1145,7 +1129,7 @@ _PyPegen_get_expr_name(expr_ty e) } } -static inline expr_ty +expr_ty _PyPegen_get_last_comprehension_item(comprehension_ty comprehension) { if (comprehension->ifs == NULL || asdl_seq_LEN(comprehension->ifs) == 0) { return comprehension->iter; @@ -1286,4 +1270,4 @@ _PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq _PyPegen_get_last_comprehension_item(last_comprehension), "Generator expression must be parenthesized" ); -} \ No newline at end of file +} diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index 37925a5783d..3e307610b63 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -1,7 +1,6 @@ #! /usr/bin/env python """Generate C code from an ASDL description.""" -import os import sys import textwrap import types @@ -488,13 +487,19 @@ class Obj2ModPrototypeVisitor(PickleVisitor): class Obj2ModVisitor(PickleVisitor): + + attribute_special_defaults = { + "end_lineno": "lineno", + "end_col_offset": "col_offset", + } + @contextmanager def recursive_call(self, node, level): - self.emit('if (Py_EnterRecursiveCall(" while traversing \'%s\' node")) {' % node, level, reflow=False) + self.emit('if (_Py_EnterRecursiveCall(" while traversing \'%s\' node")) {' % node, level, reflow=False) self.emit('goto failed;', level + 1) self.emit('}', level) yield - self.emit('Py_LeaveRecursiveCall();', level) + self.emit('_Py_LeaveRecursiveCall();', level) def funcHeader(self, name): ctype = get_c_type(name) @@ -637,7 +642,13 @@ class Obj2ModVisitor(PickleVisitor): self.emit("if (tmp == NULL || tmp == Py_None) {", depth) self.emit("Py_CLEAR(tmp);", depth+1) if self.isNumeric(field): - self.emit("%s = 0;" % field.name, depth+1) + if field.name in self.attribute_special_defaults: + self.emit( + "%s = %s;" % (field.name, self.attribute_special_defaults[field.name]), + depth+1, + ) + else: + self.emit("%s = 0;" % field.name, depth+1) elif not self.isSimpleType(field): self.emit("%s = NULL;" % field.name, depth+1) else: @@ -664,8 +675,7 @@ class Obj2ModVisitor(PickleVisitor): self.emit("if (%s == NULL) goto failed;" % field.name, depth+1) self.emit("for (i = 0; i < len; i++) {", depth+1) self.emit("%s val;" % ctype, depth+2) - self.emit("PyObject *tmp2 = PyList_GET_ITEM(tmp, i);", depth+2) - self.emit("Py_INCREF(tmp2);", depth+2) + self.emit("PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));", depth+2) with self.recursive_call(name, depth+2): self.emit("res = obj2ast_%s(state, tmp2, &val, arena);" % field.type, depth+2, reflow=False) @@ -984,10 +994,11 @@ static PyObject* ast2obj_list(struct ast_state *state, asdl_seq *seq, PyObject* static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), void *o) { - if (!o) - o = Py_None; - Py_INCREF((PyObject*)o); - return (PyObject*)o; + PyObject *op = (PyObject*)o; + if (!op) { + op = Py_None; + } + return Py_NewRef(op); } #define ast2obj_constant ast2obj_object #define ast2obj_identifier ast2obj_object @@ -1009,9 +1020,11 @@ static int obj2ast_object(struct ast_state *Py_UNUSED(state), PyObject* obj, PyO *out = NULL; return -1; } - Py_INCREF(obj); + *out = Py_NewRef(obj); + } + else { + *out = NULL; } - *out = obj; return 0; } @@ -1021,8 +1034,7 @@ static int obj2ast_constant(struct ast_state *Py_UNUSED(state), PyObject* obj, P *out = NULL; return -1; } - Py_INCREF(obj); - *out = obj; + *out = Py_NewRef(obj); return 0; } @@ -1101,6 +1113,8 @@ static int add_ast_fields(struct ast_state *state) for dfn in mod.dfns: self.visit(dfn) self.file.write(textwrap.dedent(''' + state->recursion_depth = 0; + state->recursion_limit = 0; state->initialized = 1; return 1; } @@ -1248,8 +1262,14 @@ class ObjVisitor(PickleVisitor): self.emit('if (!o) {', 1) self.emit("Py_RETURN_NONE;", 2) self.emit("}", 1) + self.emit("if (++state->recursion_depth > state->recursion_limit) {", 1) + self.emit("PyErr_SetString(PyExc_RecursionError,", 2) + self.emit('"maximum recursion depth exceeded during ast construction");', 3) + self.emit("return 0;", 2) + self.emit("}", 1) def func_end(self): + self.emit("state->recursion_depth--;", 1) self.emit("return result;", 1) self.emit("failed:", 0) self.emit("Py_XDECREF(value);", 1) @@ -1282,8 +1302,7 @@ class ObjVisitor(PickleVisitor): self.emit("switch(o) {", 1) for t in sum.types: self.emit("case %s:" % t.name, 2) - self.emit("Py_INCREF(state->%s_singleton);" % t.name, 3) - self.emit("return state->%s_singleton;" % t.name, 3) + self.emit("return Py_NewRef(state->%s_singleton);" % t.name, 3) self.emit("}", 1) self.emit("Py_UNREACHABLE();", 1); self.emit("}", 0) @@ -1360,7 +1379,29 @@ PyObject* PyAST_mod2obj(mod_ty t) if (state == NULL) { return NULL; } - return ast2obj_mod(state, t); + + int starting_recursion_depth; + /* Be careful here to prevent overflow. */ + int COMPILER_STACK_FRAME_SCALE = 3; + PyThreadState *tstate = _PyThreadState_GET(); + if (!tstate) { + return 0; + } + state->recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; + int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining; + starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE; + state->recursion_depth = starting_recursion_depth; + + PyObject *result = ast2obj_mod(state, t); + + /* Check that the recursion depth counting balanced correctly */ + if (result && state->recursion_depth != starting_recursion_depth) { + PyErr_Format(PyExc_SystemError, + "AST constructor recursion depth mismatch (before=%d, after=%d)", + starting_recursion_depth, state->recursion_depth); + return 0; + } + return result; } /* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */ @@ -1426,6 +1467,8 @@ class ChainOfVisitors: def generate_ast_state(module_state, f): f.write('struct ast_state {\n') f.write(' int initialized;\n') + f.write(' int recursion_depth;\n') + f.write(' int recursion_limit;\n') for s in module_state: f.write(' PyObject *' + s + ';\n') f.write('};') @@ -1441,6 +1484,10 @@ def generate_ast_fini(module_state, f): for s in module_state: f.write(" Py_CLEAR(state->" + s + ');\n') f.write(textwrap.dedent(""" + if (_PyInterpreterState_Get() == _PyInterpreterState_Main()) { + Py_CLEAR(_Py_CACHED_OBJECT(str_replace_inf)); + } + #if !defined(NDEBUG) state->initialized = -1; #else @@ -1482,9 +1529,10 @@ def generate_module_def(mod, metadata, f, internal_h): print(textwrap.dedent(""" #include "Python.h" #include "pycore_ast.h" - #include "pycore_ast_state.h" // struct ast_state - #include "pycore_interp.h" // _PyInterpreterState.ast - #include "pycore_pystate.h" // _PyInterpreterState_GET() + #include "pycore_ast_state.h" // struct ast_state + #include "pycore_ceval.h" // _Py_EnterRecursiveCall + #include "pycore_interp.h" // _PyInterpreterState.ast + #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "structmember.h" #include diff --git a/Parser/myreadline.c b/Parser/myreadline.c index b10d306255b..d55fcefbb6f 100644 --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -247,7 +247,8 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) assert(tstate != NULL); #ifdef MS_WINDOWS - if (!Py_LegacyWindowsStdioFlag && sys_stdin == stdin) { + const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp); + if (!config->legacy_windows_stdio && sys_stdin == stdin) { HANDLE hStdIn, hStdErr; hStdIn = _Py_get_osfhandle_noraise(fileno(sys_stdin)); diff --git a/Parser/parser.c b/Parser/parser.c index b3aa35989ed..845c1739d63 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -1,62 +1,68 @@ -// @generated by pegen from ./Grammar/python.gram +// @generated by pegen from python.gram #include "pegen.h" #if defined(Py_DEBUG) && defined(Py_BUILD_CORE) -# define D(x) if (Py_DebugFlag) x; +# define D(x) if (p->debug) { x; } #else # define D(x) #endif + +#ifdef __wasi__ +# define MAXSTACK 4000 +#else +# define MAXSTACK 6000 +#endif static const int n_keyword_lists = 9; static KeywordToken *reserved_keywords[] = { (KeywordToken[]) {{NULL, -1}}, (KeywordToken[]) {{NULL, -1}}, (KeywordToken[]) { - {"if", 627}, - {"as", 625}, - {"in", 634}, - {"or", 571}, - {"is", 579}, + {"if", 641}, + {"as", 639}, + {"in", 650}, + {"or", 574}, + {"is", 582}, {NULL, -1}, }, (KeywordToken[]) { - {"del", 600}, - {"def", 635}, - {"for", 633}, - {"try", 612}, - {"and", 572}, - {"not", 578}, + {"del", 603}, + {"def", 651}, + {"for", 649}, + {"try", 623}, + {"and", 575}, + {"not", 581}, {NULL, -1}, }, (KeywordToken[]) { - {"from", 569}, + {"from", 607}, {"pass", 504}, - {"with", 609}, - {"elif", 629}, - {"else", 630}, - {"None", 598}, - {"True", 597}, + {"with", 614}, + {"elif", 643}, + {"else", 644}, + {"None", 601}, + {"True", 600}, {NULL, -1}, }, (KeywordToken[]) { {"raise", 522}, - {"yield", 570}, + {"yield", 573}, {"break", 508}, - {"class", 636}, - {"while", 632}, - {"False", 599}, + {"class", 653}, + {"while", 646}, + {"False", 602}, {NULL, -1}, }, (KeywordToken[]) { {"return", 519}, - {"import", 531}, + {"import", 606}, {"assert", 526}, {"global", 523}, - {"except", 623}, - {"lambda", 583}, + {"except", 636}, + {"lambda", 586}, {NULL, -1}, }, (KeywordToken[]) { - {"finally", 620}, + {"finally", 632}, {NULL, -1}, }, (KeywordToken[]) { @@ -114,395 +120,445 @@ static char *soft_keywords[] = { #define star_etc_type 1040 #define kwds_type 1041 #define param_no_default_type 1042 -#define param_with_default_type 1043 -#define param_maybe_default_type 1044 -#define param_type 1045 -#define annotation_type 1046 -#define default_type 1047 -#define if_stmt_type 1048 -#define elif_stmt_type 1049 -#define else_block_type 1050 -#define while_stmt_type 1051 -#define for_stmt_type 1052 -#define with_stmt_type 1053 -#define with_item_type 1054 -#define try_stmt_type 1055 -#define except_block_type 1056 -#define finally_block_type 1057 -#define match_stmt_type 1058 -#define subject_expr_type 1059 -#define case_block_type 1060 -#define guard_type 1061 -#define patterns_type 1062 -#define pattern_type 1063 -#define as_pattern_type 1064 -#define or_pattern_type 1065 -#define closed_pattern_type 1066 -#define literal_pattern_type 1067 -#define literal_expr_type 1068 -#define complex_number_type 1069 -#define signed_number_type 1070 -#define signed_real_number_type 1071 -#define real_number_type 1072 -#define imaginary_number_type 1073 -#define capture_pattern_type 1074 -#define pattern_capture_target_type 1075 -#define wildcard_pattern_type 1076 -#define value_pattern_type 1077 -#define attr_type 1078 // Left-recursive -#define name_or_attr_type 1079 // Left-recursive -#define group_pattern_type 1080 -#define sequence_pattern_type 1081 -#define open_sequence_pattern_type 1082 -#define maybe_sequence_pattern_type 1083 -#define maybe_star_pattern_type 1084 -#define star_pattern_type 1085 -#define mapping_pattern_type 1086 -#define items_pattern_type 1087 -#define key_value_pattern_type 1088 -#define double_star_pattern_type 1089 -#define class_pattern_type 1090 -#define positional_patterns_type 1091 -#define keyword_patterns_type 1092 -#define keyword_pattern_type 1093 -#define expressions_type 1094 -#define expression_type 1095 -#define yield_expr_type 1096 -#define star_expressions_type 1097 -#define star_expression_type 1098 -#define star_named_expressions_type 1099 -#define star_named_expression_type 1100 -#define assignment_expression_type 1101 -#define named_expression_type 1102 -#define disjunction_type 1103 -#define conjunction_type 1104 -#define inversion_type 1105 -#define comparison_type 1106 -#define compare_op_bitwise_or_pair_type 1107 -#define eq_bitwise_or_type 1108 -#define noteq_bitwise_or_type 1109 -#define lte_bitwise_or_type 1110 -#define lt_bitwise_or_type 1111 -#define gte_bitwise_or_type 1112 -#define gt_bitwise_or_type 1113 -#define notin_bitwise_or_type 1114 -#define in_bitwise_or_type 1115 -#define isnot_bitwise_or_type 1116 -#define is_bitwise_or_type 1117 -#define bitwise_or_type 1118 // Left-recursive -#define bitwise_xor_type 1119 // Left-recursive -#define bitwise_and_type 1120 // Left-recursive -#define shift_expr_type 1121 // Left-recursive -#define sum_type 1122 // Left-recursive -#define term_type 1123 // Left-recursive -#define factor_type 1124 -#define power_type 1125 -#define await_primary_type 1126 -#define primary_type 1127 // Left-recursive -#define slices_type 1128 -#define slice_type 1129 -#define atom_type 1130 -#define group_type 1131 -#define lambdef_type 1132 -#define lambda_params_type 1133 -#define lambda_parameters_type 1134 -#define lambda_slash_no_default_type 1135 -#define lambda_slash_with_default_type 1136 -#define lambda_star_etc_type 1137 -#define lambda_kwds_type 1138 -#define lambda_param_no_default_type 1139 -#define lambda_param_with_default_type 1140 -#define lambda_param_maybe_default_type 1141 -#define lambda_param_type 1142 -#define strings_type 1143 -#define list_type 1144 -#define tuple_type 1145 -#define set_type 1146 -#define dict_type 1147 -#define double_starred_kvpairs_type 1148 -#define double_starred_kvpair_type 1149 -#define kvpair_type 1150 -#define for_if_clauses_type 1151 -#define for_if_clause_type 1152 -#define listcomp_type 1153 -#define setcomp_type 1154 -#define genexp_type 1155 -#define dictcomp_type 1156 -#define arguments_type 1157 -#define args_type 1158 -#define kwargs_type 1159 -#define starred_expression_type 1160 -#define kwarg_or_starred_type 1161 -#define kwarg_or_double_starred_type 1162 -#define star_targets_type 1163 -#define star_targets_list_seq_type 1164 -#define star_targets_tuple_seq_type 1165 -#define star_target_type 1166 -#define target_with_star_atom_type 1167 -#define star_atom_type 1168 -#define single_target_type 1169 -#define single_subscript_attribute_target_type 1170 -#define t_primary_type 1171 // Left-recursive -#define t_lookahead_type 1172 -#define del_targets_type 1173 -#define del_target_type 1174 -#define del_t_atom_type 1175 -#define type_expressions_type 1176 -#define func_type_comment_type 1177 -#define invalid_arguments_type 1178 -#define invalid_kwarg_type 1179 -#define expression_without_invalid_type 1180 -#define invalid_legacy_expression_type 1181 -#define invalid_expression_type 1182 -#define invalid_named_expression_type 1183 -#define invalid_assignment_type 1184 -#define invalid_ann_assign_target_type 1185 -#define invalid_del_stmt_type 1186 -#define invalid_block_type 1187 -#define invalid_comprehension_type 1188 -#define invalid_dict_comprehension_type 1189 -#define invalid_parameters_type 1190 -#define invalid_parameters_helper_type 1191 -#define invalid_lambda_parameters_type 1192 -#define invalid_lambda_parameters_helper_type 1193 -#define invalid_star_etc_type 1194 -#define invalid_lambda_star_etc_type 1195 -#define invalid_double_type_comments_type 1196 -#define invalid_with_item_type 1197 -#define invalid_for_target_type 1198 -#define invalid_group_type 1199 -#define invalid_import_from_targets_type 1200 -#define invalid_with_stmt_type 1201 -#define invalid_with_stmt_indent_type 1202 -#define invalid_try_stmt_type 1203 -#define invalid_except_stmt_type 1204 -#define invalid_finally_stmt_type 1205 -#define invalid_except_stmt_indent_type 1206 -#define invalid_match_stmt_type 1207 -#define invalid_case_block_type 1208 -#define invalid_as_pattern_type 1209 -#define invalid_class_pattern_type 1210 -#define invalid_class_argument_pattern_type 1211 -#define invalid_if_stmt_type 1212 -#define invalid_elif_stmt_type 1213 -#define invalid_else_stmt_type 1214 -#define invalid_while_stmt_type 1215 -#define invalid_for_stmt_type 1216 -#define invalid_def_raw_type 1217 -#define invalid_class_def_raw_type 1218 -#define invalid_double_starred_kvpairs_type 1219 -#define invalid_kvpair_type 1220 -#define _loop0_1_type 1221 -#define _loop0_2_type 1222 -#define _loop1_3_type 1223 -#define _loop0_5_type 1224 -#define _gather_4_type 1225 -#define _tmp_6_type 1226 -#define _tmp_7_type 1227 -#define _tmp_8_type 1228 -#define _tmp_9_type 1229 -#define _tmp_10_type 1230 -#define _tmp_11_type 1231 -#define _tmp_12_type 1232 -#define _tmp_13_type 1233 -#define _loop1_14_type 1234 -#define _tmp_15_type 1235 -#define _tmp_16_type 1236 -#define _tmp_17_type 1237 -#define _loop0_19_type 1238 -#define _gather_18_type 1239 -#define _loop0_21_type 1240 -#define _gather_20_type 1241 -#define _tmp_22_type 1242 -#define _tmp_23_type 1243 -#define _loop0_24_type 1244 -#define _loop1_25_type 1245 -#define _loop0_27_type 1246 -#define _gather_26_type 1247 -#define _tmp_28_type 1248 -#define _loop0_30_type 1249 -#define _gather_29_type 1250 -#define _tmp_31_type 1251 -#define _loop1_32_type 1252 -#define _tmp_33_type 1253 -#define _tmp_34_type 1254 -#define _tmp_35_type 1255 -#define _loop0_36_type 1256 -#define _loop0_37_type 1257 -#define _loop0_38_type 1258 -#define _loop1_39_type 1259 -#define _loop0_40_type 1260 -#define _loop1_41_type 1261 -#define _loop1_42_type 1262 -#define _loop1_43_type 1263 -#define _loop0_44_type 1264 -#define _loop1_45_type 1265 -#define _loop0_46_type 1266 -#define _loop1_47_type 1267 -#define _loop0_48_type 1268 -#define _loop1_49_type 1269 -#define _loop0_51_type 1270 -#define _gather_50_type 1271 -#define _loop0_53_type 1272 -#define _gather_52_type 1273 -#define _loop0_55_type 1274 -#define _gather_54_type 1275 -#define _loop0_57_type 1276 -#define _gather_56_type 1277 -#define _tmp_58_type 1278 -#define _loop1_59_type 1279 -#define _tmp_60_type 1280 -#define _loop1_61_type 1281 -#define _loop0_63_type 1282 -#define _gather_62_type 1283 -#define _tmp_64_type 1284 -#define _tmp_65_type 1285 -#define _tmp_66_type 1286 -#define _tmp_67_type 1287 -#define _loop0_69_type 1288 -#define _gather_68_type 1289 -#define _loop0_71_type 1290 -#define _gather_70_type 1291 -#define _tmp_72_type 1292 -#define _loop0_74_type 1293 -#define _gather_73_type 1294 -#define _loop0_76_type 1295 -#define _gather_75_type 1296 -#define _loop1_77_type 1297 -#define _loop1_78_type 1298 -#define _loop0_80_type 1299 -#define _gather_79_type 1300 -#define _loop1_81_type 1301 -#define _loop1_82_type 1302 -#define _loop1_83_type 1303 -#define _tmp_84_type 1304 -#define _loop0_86_type 1305 -#define _gather_85_type 1306 -#define _tmp_87_type 1307 -#define _tmp_88_type 1308 -#define _tmp_89_type 1309 -#define _tmp_90_type 1310 -#define _tmp_91_type 1311 -#define _loop0_92_type 1312 -#define _loop0_93_type 1313 -#define _loop0_94_type 1314 -#define _loop1_95_type 1315 -#define _loop0_96_type 1316 -#define _loop1_97_type 1317 -#define _loop1_98_type 1318 -#define _loop1_99_type 1319 -#define _loop0_100_type 1320 -#define _loop1_101_type 1321 -#define _loop0_102_type 1322 -#define _loop1_103_type 1323 -#define _loop0_104_type 1324 -#define _loop1_105_type 1325 -#define _loop1_106_type 1326 -#define _tmp_107_type 1327 -#define _loop0_109_type 1328 -#define _gather_108_type 1329 -#define _loop1_110_type 1330 -#define _loop0_111_type 1331 -#define _loop0_112_type 1332 -#define _tmp_113_type 1333 -#define _loop0_115_type 1334 -#define _gather_114_type 1335 -#define _tmp_116_type 1336 -#define _loop0_118_type 1337 -#define _gather_117_type 1338 -#define _loop0_120_type 1339 -#define _gather_119_type 1340 -#define _loop0_122_type 1341 -#define _gather_121_type 1342 -#define _loop0_124_type 1343 -#define _gather_123_type 1344 -#define _loop0_125_type 1345 -#define _loop0_127_type 1346 -#define _gather_126_type 1347 -#define _loop1_128_type 1348 -#define _tmp_129_type 1349 -#define _loop0_131_type 1350 -#define _gather_130_type 1351 -#define _loop0_133_type 1352 -#define _gather_132_type 1353 -#define _loop0_135_type 1354 -#define _gather_134_type 1355 -#define _loop0_137_type 1356 -#define _gather_136_type 1357 -#define _loop0_139_type 1358 -#define _gather_138_type 1359 -#define _tmp_140_type 1360 -#define _tmp_141_type 1361 -#define _tmp_142_type 1362 -#define _tmp_143_type 1363 -#define _tmp_144_type 1364 -#define _tmp_145_type 1365 -#define _tmp_146_type 1366 -#define _tmp_147_type 1367 -#define _tmp_148_type 1368 -#define _loop0_149_type 1369 -#define _loop0_150_type 1370 -#define _loop0_151_type 1371 -#define _tmp_152_type 1372 -#define _tmp_153_type 1373 -#define _tmp_154_type 1374 -#define _tmp_155_type 1375 -#define _loop0_156_type 1376 -#define _loop0_157_type 1377 -#define _loop1_158_type 1378 -#define _loop1_159_type 1379 -#define _loop0_160_type 1380 -#define _loop0_161_type 1381 -#define _loop0_163_type 1382 -#define _gather_162_type 1383 -#define _loop1_164_type 1384 -#define _tmp_165_type 1385 -#define _tmp_166_type 1386 -#define _tmp_167_type 1387 -#define _loop0_169_type 1388 -#define _gather_168_type 1389 -#define _loop0_171_type 1390 -#define _gather_170_type 1391 -#define _loop0_173_type 1392 -#define _gather_172_type 1393 -#define _loop0_175_type 1394 -#define _gather_174_type 1395 -#define _tmp_176_type 1396 -#define _tmp_177_type 1397 -#define _tmp_178_type 1398 -#define _tmp_179_type 1399 -#define _tmp_180_type 1400 -#define _tmp_181_type 1401 -#define _tmp_182_type 1402 -#define _loop0_184_type 1403 -#define _gather_183_type 1404 -#define _tmp_185_type 1405 -#define _tmp_186_type 1406 -#define _tmp_187_type 1407 -#define _tmp_188_type 1408 -#define _tmp_189_type 1409 -#define _tmp_190_type 1410 -#define _tmp_191_type 1411 -#define _tmp_192_type 1412 -#define _tmp_193_type 1413 -#define _tmp_194_type 1414 -#define _tmp_195_type 1415 -#define _tmp_196_type 1416 -#define _tmp_197_type 1417 -#define _tmp_198_type 1418 -#define _tmp_199_type 1419 -#define _tmp_200_type 1420 -#define _tmp_201_type 1421 -#define _tmp_202_type 1422 -#define _tmp_203_type 1423 -#define _tmp_204_type 1424 -#define _tmp_205_type 1425 -#define _tmp_206_type 1426 -#define _tmp_207_type 1427 -#define _tmp_208_type 1428 -#define _tmp_209_type 1429 -#define _tmp_210_type 1430 -#define _tmp_211_type 1431 +#define param_no_default_star_annotation_type 1043 +#define param_with_default_type 1044 +#define param_maybe_default_type 1045 +#define param_type 1046 +#define param_star_annotation_type 1047 +#define annotation_type 1048 +#define star_annotation_type 1049 +#define default_type 1050 +#define if_stmt_type 1051 +#define elif_stmt_type 1052 +#define else_block_type 1053 +#define while_stmt_type 1054 +#define for_stmt_type 1055 +#define with_stmt_type 1056 +#define with_item_type 1057 +#define try_stmt_type 1058 +#define except_block_type 1059 +#define except_star_block_type 1060 +#define finally_block_type 1061 +#define match_stmt_type 1062 +#define subject_expr_type 1063 +#define case_block_type 1064 +#define guard_type 1065 +#define patterns_type 1066 +#define pattern_type 1067 +#define as_pattern_type 1068 +#define or_pattern_type 1069 +#define closed_pattern_type 1070 +#define literal_pattern_type 1071 +#define literal_expr_type 1072 +#define complex_number_type 1073 +#define signed_number_type 1074 +#define signed_real_number_type 1075 +#define real_number_type 1076 +#define imaginary_number_type 1077 +#define capture_pattern_type 1078 +#define pattern_capture_target_type 1079 +#define wildcard_pattern_type 1080 +#define value_pattern_type 1081 +#define attr_type 1082 // Left-recursive +#define name_or_attr_type 1083 // Left-recursive +#define group_pattern_type 1084 +#define sequence_pattern_type 1085 +#define open_sequence_pattern_type 1086 +#define maybe_sequence_pattern_type 1087 +#define maybe_star_pattern_type 1088 +#define star_pattern_type 1089 +#define mapping_pattern_type 1090 +#define items_pattern_type 1091 +#define key_value_pattern_type 1092 +#define double_star_pattern_type 1093 +#define class_pattern_type 1094 +#define positional_patterns_type 1095 +#define keyword_patterns_type 1096 +#define keyword_pattern_type 1097 +#define expressions_type 1098 +#define expression_type 1099 +#define yield_expr_type 1100 +#define star_expressions_type 1101 +#define star_expression_type 1102 +#define star_named_expressions_type 1103 +#define star_named_expression_type 1104 +#define assignment_expression_type 1105 +#define named_expression_type 1106 +#define disjunction_type 1107 +#define conjunction_type 1108 +#define inversion_type 1109 +#define comparison_type 1110 +#define compare_op_bitwise_or_pair_type 1111 +#define eq_bitwise_or_type 1112 +#define noteq_bitwise_or_type 1113 +#define lte_bitwise_or_type 1114 +#define lt_bitwise_or_type 1115 +#define gte_bitwise_or_type 1116 +#define gt_bitwise_or_type 1117 +#define notin_bitwise_or_type 1118 +#define in_bitwise_or_type 1119 +#define isnot_bitwise_or_type 1120 +#define is_bitwise_or_type 1121 +#define bitwise_or_type 1122 // Left-recursive +#define bitwise_xor_type 1123 // Left-recursive +#define bitwise_and_type 1124 // Left-recursive +#define shift_expr_type 1125 // Left-recursive +#define sum_type 1126 // Left-recursive +#define term_type 1127 // Left-recursive +#define factor_type 1128 +#define power_type 1129 +#define await_primary_type 1130 +#define primary_type 1131 // Left-recursive +#define slices_type 1132 +#define slice_type 1133 +#define atom_type 1134 +#define group_type 1135 +#define lambdef_type 1136 +#define lambda_params_type 1137 +#define lambda_parameters_type 1138 +#define lambda_slash_no_default_type 1139 +#define lambda_slash_with_default_type 1140 +#define lambda_star_etc_type 1141 +#define lambda_kwds_type 1142 +#define lambda_param_no_default_type 1143 +#define lambda_param_with_default_type 1144 +#define lambda_param_maybe_default_type 1145 +#define lambda_param_type 1146 +#define strings_type 1147 +#define list_type 1148 +#define tuple_type 1149 +#define set_type 1150 +#define dict_type 1151 +#define double_starred_kvpairs_type 1152 +#define double_starred_kvpair_type 1153 +#define kvpair_type 1154 +#define for_if_clauses_type 1155 +#define for_if_clause_type 1156 +#define listcomp_type 1157 +#define setcomp_type 1158 +#define genexp_type 1159 +#define dictcomp_type 1160 +#define arguments_type 1161 +#define args_type 1162 +#define kwargs_type 1163 +#define starred_expression_type 1164 +#define kwarg_or_starred_type 1165 +#define kwarg_or_double_starred_type 1166 +#define star_targets_type 1167 +#define star_targets_list_seq_type 1168 +#define star_targets_tuple_seq_type 1169 +#define star_target_type 1170 +#define target_with_star_atom_type 1171 +#define star_atom_type 1172 +#define single_target_type 1173 +#define single_subscript_attribute_target_type 1174 +#define t_primary_type 1175 // Left-recursive +#define t_lookahead_type 1176 +#define del_targets_type 1177 +#define del_target_type 1178 +#define del_t_atom_type 1179 +#define type_expressions_type 1180 +#define func_type_comment_type 1181 +#define invalid_arguments_type 1182 +#define invalid_kwarg_type 1183 +#define expression_without_invalid_type 1184 +#define invalid_legacy_expression_type 1185 +#define invalid_expression_type 1186 +#define invalid_named_expression_type 1187 +#define invalid_assignment_type 1188 +#define invalid_ann_assign_target_type 1189 +#define invalid_del_stmt_type 1190 +#define invalid_block_type 1191 +#define invalid_comprehension_type 1192 +#define invalid_dict_comprehension_type 1193 +#define invalid_parameters_type 1194 +#define invalid_default_type 1195 +#define invalid_star_etc_type 1196 +#define invalid_kwds_type 1197 +#define invalid_parameters_helper_type 1198 +#define invalid_lambda_parameters_type 1199 +#define invalid_lambda_parameters_helper_type 1200 +#define invalid_lambda_star_etc_type 1201 +#define invalid_lambda_kwds_type 1202 +#define invalid_double_type_comments_type 1203 +#define invalid_with_item_type 1204 +#define invalid_for_target_type 1205 +#define invalid_group_type 1206 +#define invalid_import_type 1207 +#define invalid_import_from_targets_type 1208 +#define invalid_with_stmt_type 1209 +#define invalid_with_stmt_indent_type 1210 +#define invalid_try_stmt_type 1211 +#define invalid_except_stmt_type 1212 +#define invalid_finally_stmt_type 1213 +#define invalid_except_stmt_indent_type 1214 +#define invalid_except_star_stmt_indent_type 1215 +#define invalid_match_stmt_type 1216 +#define invalid_case_block_type 1217 +#define invalid_as_pattern_type 1218 +#define invalid_class_pattern_type 1219 +#define invalid_class_argument_pattern_type 1220 +#define invalid_if_stmt_type 1221 +#define invalid_elif_stmt_type 1222 +#define invalid_else_stmt_type 1223 +#define invalid_while_stmt_type 1224 +#define invalid_for_stmt_type 1225 +#define invalid_def_raw_type 1226 +#define invalid_class_def_raw_type 1227 +#define invalid_double_starred_kvpairs_type 1228 +#define invalid_kvpair_type 1229 +#define invalid_starred_expression_type 1230 +#define _loop0_1_type 1231 +#define _loop0_2_type 1232 +#define _loop1_3_type 1233 +#define _loop0_5_type 1234 +#define _gather_4_type 1235 +#define _tmp_6_type 1236 +#define _tmp_7_type 1237 +#define _tmp_8_type 1238 +#define _tmp_9_type 1239 +#define _tmp_10_type 1240 +#define _tmp_11_type 1241 +#define _tmp_12_type 1242 +#define _tmp_13_type 1243 +#define _loop1_14_type 1244 +#define _tmp_15_type 1245 +#define _tmp_16_type 1246 +#define _tmp_17_type 1247 +#define _loop0_19_type 1248 +#define _gather_18_type 1249 +#define _loop0_21_type 1250 +#define _gather_20_type 1251 +#define _tmp_22_type 1252 +#define _tmp_23_type 1253 +#define _loop0_24_type 1254 +#define _loop1_25_type 1255 +#define _loop0_27_type 1256 +#define _gather_26_type 1257 +#define _tmp_28_type 1258 +#define _loop0_30_type 1259 +#define _gather_29_type 1260 +#define _tmp_31_type 1261 +#define _loop1_32_type 1262 +#define _tmp_33_type 1263 +#define _tmp_34_type 1264 +#define _tmp_35_type 1265 +#define _loop0_36_type 1266 +#define _loop0_37_type 1267 +#define _loop0_38_type 1268 +#define _loop1_39_type 1269 +#define _loop0_40_type 1270 +#define _loop1_41_type 1271 +#define _loop1_42_type 1272 +#define _loop1_43_type 1273 +#define _loop0_44_type 1274 +#define _loop1_45_type 1275 +#define _loop0_46_type 1276 +#define _loop1_47_type 1277 +#define _loop0_48_type 1278 +#define _loop0_49_type 1279 +#define _loop1_50_type 1280 +#define _loop0_52_type 1281 +#define _gather_51_type 1282 +#define _loop0_54_type 1283 +#define _gather_53_type 1284 +#define _loop0_56_type 1285 +#define _gather_55_type 1286 +#define _loop0_58_type 1287 +#define _gather_57_type 1288 +#define _tmp_59_type 1289 +#define _loop1_60_type 1290 +#define _loop1_61_type 1291 +#define _tmp_62_type 1292 +#define _tmp_63_type 1293 +#define _loop1_64_type 1294 +#define _loop0_66_type 1295 +#define _gather_65_type 1296 +#define _tmp_67_type 1297 +#define _tmp_68_type 1298 +#define _tmp_69_type 1299 +#define _tmp_70_type 1300 +#define _loop0_72_type 1301 +#define _gather_71_type 1302 +#define _loop0_74_type 1303 +#define _gather_73_type 1304 +#define _tmp_75_type 1305 +#define _loop0_77_type 1306 +#define _gather_76_type 1307 +#define _loop0_79_type 1308 +#define _gather_78_type 1309 +#define _loop1_80_type 1310 +#define _loop1_81_type 1311 +#define _loop0_83_type 1312 +#define _gather_82_type 1313 +#define _loop1_84_type 1314 +#define _loop1_85_type 1315 +#define _loop1_86_type 1316 +#define _tmp_87_type 1317 +#define _loop0_89_type 1318 +#define _gather_88_type 1319 +#define _tmp_90_type 1320 +#define _tmp_91_type 1321 +#define _tmp_92_type 1322 +#define _tmp_93_type 1323 +#define _tmp_94_type 1324 +#define _loop0_95_type 1325 +#define _loop0_96_type 1326 +#define _loop0_97_type 1327 +#define _loop1_98_type 1328 +#define _loop0_99_type 1329 +#define _loop1_100_type 1330 +#define _loop1_101_type 1331 +#define _loop1_102_type 1332 +#define _loop0_103_type 1333 +#define _loop1_104_type 1334 +#define _loop0_105_type 1335 +#define _loop1_106_type 1336 +#define _loop0_107_type 1337 +#define _loop1_108_type 1338 +#define _loop1_109_type 1339 +#define _tmp_110_type 1340 +#define _loop0_112_type 1341 +#define _gather_111_type 1342 +#define _loop1_113_type 1343 +#define _loop0_114_type 1344 +#define _loop0_115_type 1345 +#define _tmp_116_type 1346 +#define _loop0_118_type 1347 +#define _gather_117_type 1348 +#define _tmp_119_type 1349 +#define _loop0_121_type 1350 +#define _gather_120_type 1351 +#define _loop0_123_type 1352 +#define _gather_122_type 1353 +#define _loop0_125_type 1354 +#define _gather_124_type 1355 +#define _loop0_127_type 1356 +#define _gather_126_type 1357 +#define _loop0_128_type 1358 +#define _loop0_130_type 1359 +#define _gather_129_type 1360 +#define _loop1_131_type 1361 +#define _tmp_132_type 1362 +#define _loop0_134_type 1363 +#define _gather_133_type 1364 +#define _loop0_136_type 1365 +#define _gather_135_type 1366 +#define _loop0_138_type 1367 +#define _gather_137_type 1368 +#define _loop0_140_type 1369 +#define _gather_139_type 1370 +#define _loop0_142_type 1371 +#define _gather_141_type 1372 +#define _tmp_143_type 1373 +#define _tmp_144_type 1374 +#define _tmp_145_type 1375 +#define _tmp_146_type 1376 +#define _tmp_147_type 1377 +#define _tmp_148_type 1378 +#define _tmp_149_type 1379 +#define _tmp_150_type 1380 +#define _tmp_151_type 1381 +#define _tmp_152_type 1382 +#define _tmp_153_type 1383 +#define _loop0_154_type 1384 +#define _loop0_155_type 1385 +#define _loop0_156_type 1386 +#define _tmp_157_type 1387 +#define _tmp_158_type 1388 +#define _tmp_159_type 1389 +#define _tmp_160_type 1390 +#define _tmp_161_type 1391 +#define _loop0_162_type 1392 +#define _loop0_163_type 1393 +#define _loop0_164_type 1394 +#define _loop1_165_type 1395 +#define _tmp_166_type 1396 +#define _loop0_167_type 1397 +#define _tmp_168_type 1398 +#define _loop0_169_type 1399 +#define _loop1_170_type 1400 +#define _tmp_171_type 1401 +#define _tmp_172_type 1402 +#define _tmp_173_type 1403 +#define _loop0_174_type 1404 +#define _tmp_175_type 1405 +#define _tmp_176_type 1406 +#define _loop1_177_type 1407 +#define _tmp_178_type 1408 +#define _loop0_179_type 1409 +#define _loop0_180_type 1410 +#define _loop0_181_type 1411 +#define _loop0_183_type 1412 +#define _gather_182_type 1413 +#define _tmp_184_type 1414 +#define _loop0_185_type 1415 +#define _tmp_186_type 1416 +#define _loop0_187_type 1417 +#define _loop1_188_type 1418 +#define _loop1_189_type 1419 +#define _tmp_190_type 1420 +#define _tmp_191_type 1421 +#define _loop0_192_type 1422 +#define _tmp_193_type 1423 +#define _tmp_194_type 1424 +#define _tmp_195_type 1425 +#define _loop0_197_type 1426 +#define _gather_196_type 1427 +#define _loop0_199_type 1428 +#define _gather_198_type 1429 +#define _loop0_201_type 1430 +#define _gather_200_type 1431 +#define _loop0_203_type 1432 +#define _gather_202_type 1433 +#define _tmp_204_type 1434 +#define _loop0_205_type 1435 +#define _loop1_206_type 1436 +#define _tmp_207_type 1437 +#define _loop0_208_type 1438 +#define _loop1_209_type 1439 +#define _tmp_210_type 1440 +#define _tmp_211_type 1441 +#define _tmp_212_type 1442 +#define _tmp_213_type 1443 +#define _tmp_214_type 1444 +#define _tmp_215_type 1445 +#define _tmp_216_type 1446 +#define _tmp_217_type 1447 +#define _tmp_218_type 1448 +#define _tmp_219_type 1449 +#define _loop0_221_type 1450 +#define _gather_220_type 1451 +#define _tmp_222_type 1452 +#define _tmp_223_type 1453 +#define _tmp_224_type 1454 +#define _tmp_225_type 1455 +#define _tmp_226_type 1456 +#define _tmp_227_type 1457 +#define _tmp_228_type 1458 +#define _tmp_229_type 1459 +#define _tmp_230_type 1460 +#define _tmp_231_type 1461 +#define _tmp_232_type 1462 +#define _tmp_233_type 1463 +#define _tmp_234_type 1464 +#define _tmp_235_type 1465 +#define _tmp_236_type 1466 +#define _tmp_237_type 1467 +#define _tmp_238_type 1468 +#define _tmp_239_type 1469 +#define _tmp_240_type 1470 +#define _tmp_241_type 1471 +#define _tmp_242_type 1472 +#define _tmp_243_type 1473 +#define _tmp_244_type 1474 +#define _tmp_245_type 1475 +#define _tmp_246_type 1476 +#define _tmp_247_type 1477 +#define _tmp_248_type 1478 +#define _tmp_249_type 1479 +#define _tmp_250_type 1480 +#define _tmp_251_type 1481 static mod_ty file_rule(Parser *p); static mod_ty interactive_rule(Parser *p); @@ -547,10 +603,13 @@ static SlashWithDefault* slash_with_default_rule(Parser *p); static StarEtc* star_etc_rule(Parser *p); static arg_ty kwds_rule(Parser *p); static arg_ty param_no_default_rule(Parser *p); +static arg_ty param_no_default_star_annotation_rule(Parser *p); static NameDefaultPair* param_with_default_rule(Parser *p); static NameDefaultPair* param_maybe_default_rule(Parser *p); static arg_ty param_rule(Parser *p); +static arg_ty param_star_annotation_rule(Parser *p); static expr_ty annotation_rule(Parser *p); +static expr_ty star_annotation_rule(Parser *p); static expr_ty default_rule(Parser *p); static stmt_ty if_stmt_rule(Parser *p); static stmt_ty elif_stmt_rule(Parser *p); @@ -561,6 +620,7 @@ static stmt_ty with_stmt_rule(Parser *p); static withitem_ty with_item_rule(Parser *p); static stmt_ty try_stmt_rule(Parser *p); static excepthandler_ty except_block_rule(Parser *p); +static excepthandler_ty except_star_block_rule(Parser *p); static asdl_stmt_seq* finally_block_rule(Parser *p); static stmt_ty match_stmt_rule(Parser *p); static expr_ty subject_expr_rule(Parser *p); @@ -695,15 +755,19 @@ static void *invalid_block_rule(Parser *p); static void *invalid_comprehension_rule(Parser *p); static void *invalid_dict_comprehension_rule(Parser *p); static void *invalid_parameters_rule(Parser *p); +static void *invalid_default_rule(Parser *p); +static void *invalid_star_etc_rule(Parser *p); +static void *invalid_kwds_rule(Parser *p); static void *invalid_parameters_helper_rule(Parser *p); static void *invalid_lambda_parameters_rule(Parser *p); static void *invalid_lambda_parameters_helper_rule(Parser *p); -static void *invalid_star_etc_rule(Parser *p); static void *invalid_lambda_star_etc_rule(Parser *p); +static void *invalid_lambda_kwds_rule(Parser *p); static void *invalid_double_type_comments_rule(Parser *p); static void *invalid_with_item_rule(Parser *p); static void *invalid_for_target_rule(Parser *p); static void *invalid_group_rule(Parser *p); +static void *invalid_import_rule(Parser *p); static void *invalid_import_from_targets_rule(Parser *p); static void *invalid_with_stmt_rule(Parser *p); static void *invalid_with_stmt_indent_rule(Parser *p); @@ -711,6 +775,7 @@ static void *invalid_try_stmt_rule(Parser *p); static void *invalid_except_stmt_rule(Parser *p); static void *invalid_finally_stmt_rule(Parser *p); static void *invalid_except_stmt_indent_rule(Parser *p); +static void *invalid_except_star_stmt_indent_rule(Parser *p); static void *invalid_match_stmt_rule(Parser *p); static void *invalid_case_block_rule(Parser *p); static void *invalid_as_pattern_rule(Parser *p); @@ -725,6 +790,7 @@ static void *invalid_def_raw_rule(Parser *p); static void *invalid_class_def_raw_rule(Parser *p); static void *invalid_double_starred_kvpairs_rule(Parser *p); static void *invalid_kvpair_rule(Parser *p); +static void *invalid_starred_expression_rule(Parser *p); static asdl_seq *_loop0_1_rule(Parser *p); static asdl_seq *_loop0_2_rule(Parser *p); static asdl_seq *_loop1_3_rule(Parser *p); @@ -773,185 +839,228 @@ static asdl_seq *_loop1_45_rule(Parser *p); static asdl_seq *_loop0_46_rule(Parser *p); static asdl_seq *_loop1_47_rule(Parser *p); static asdl_seq *_loop0_48_rule(Parser *p); -static asdl_seq *_loop1_49_rule(Parser *p); -static asdl_seq *_loop0_51_rule(Parser *p); -static asdl_seq *_gather_50_rule(Parser *p); -static asdl_seq *_loop0_53_rule(Parser *p); -static asdl_seq *_gather_52_rule(Parser *p); -static asdl_seq *_loop0_55_rule(Parser *p); -static asdl_seq *_gather_54_rule(Parser *p); -static asdl_seq *_loop0_57_rule(Parser *p); -static asdl_seq *_gather_56_rule(Parser *p); -static void *_tmp_58_rule(Parser *p); -static asdl_seq *_loop1_59_rule(Parser *p); -static void *_tmp_60_rule(Parser *p); +static asdl_seq *_loop0_49_rule(Parser *p); +static asdl_seq *_loop1_50_rule(Parser *p); +static asdl_seq *_loop0_52_rule(Parser *p); +static asdl_seq *_gather_51_rule(Parser *p); +static asdl_seq *_loop0_54_rule(Parser *p); +static asdl_seq *_gather_53_rule(Parser *p); +static asdl_seq *_loop0_56_rule(Parser *p); +static asdl_seq *_gather_55_rule(Parser *p); +static asdl_seq *_loop0_58_rule(Parser *p); +static asdl_seq *_gather_57_rule(Parser *p); +static void *_tmp_59_rule(Parser *p); +static asdl_seq *_loop1_60_rule(Parser *p); static asdl_seq *_loop1_61_rule(Parser *p); -static asdl_seq *_loop0_63_rule(Parser *p); -static asdl_seq *_gather_62_rule(Parser *p); -static void *_tmp_64_rule(Parser *p); -static void *_tmp_65_rule(Parser *p); -static void *_tmp_66_rule(Parser *p); +static void *_tmp_62_rule(Parser *p); +static void *_tmp_63_rule(Parser *p); +static asdl_seq *_loop1_64_rule(Parser *p); +static asdl_seq *_loop0_66_rule(Parser *p); +static asdl_seq *_gather_65_rule(Parser *p); static void *_tmp_67_rule(Parser *p); -static asdl_seq *_loop0_69_rule(Parser *p); -static asdl_seq *_gather_68_rule(Parser *p); -static asdl_seq *_loop0_71_rule(Parser *p); -static asdl_seq *_gather_70_rule(Parser *p); -static void *_tmp_72_rule(Parser *p); +static void *_tmp_68_rule(Parser *p); +static void *_tmp_69_rule(Parser *p); +static void *_tmp_70_rule(Parser *p); +static asdl_seq *_loop0_72_rule(Parser *p); +static asdl_seq *_gather_71_rule(Parser *p); static asdl_seq *_loop0_74_rule(Parser *p); static asdl_seq *_gather_73_rule(Parser *p); -static asdl_seq *_loop0_76_rule(Parser *p); -static asdl_seq *_gather_75_rule(Parser *p); -static asdl_seq *_loop1_77_rule(Parser *p); -static asdl_seq *_loop1_78_rule(Parser *p); -static asdl_seq *_loop0_80_rule(Parser *p); -static asdl_seq *_gather_79_rule(Parser *p); +static void *_tmp_75_rule(Parser *p); +static asdl_seq *_loop0_77_rule(Parser *p); +static asdl_seq *_gather_76_rule(Parser *p); +static asdl_seq *_loop0_79_rule(Parser *p); +static asdl_seq *_gather_78_rule(Parser *p); +static asdl_seq *_loop1_80_rule(Parser *p); static asdl_seq *_loop1_81_rule(Parser *p); -static asdl_seq *_loop1_82_rule(Parser *p); -static asdl_seq *_loop1_83_rule(Parser *p); -static void *_tmp_84_rule(Parser *p); -static asdl_seq *_loop0_86_rule(Parser *p); -static asdl_seq *_gather_85_rule(Parser *p); +static asdl_seq *_loop0_83_rule(Parser *p); +static asdl_seq *_gather_82_rule(Parser *p); +static asdl_seq *_loop1_84_rule(Parser *p); +static asdl_seq *_loop1_85_rule(Parser *p); +static asdl_seq *_loop1_86_rule(Parser *p); static void *_tmp_87_rule(Parser *p); -static void *_tmp_88_rule(Parser *p); -static void *_tmp_89_rule(Parser *p); +static asdl_seq *_loop0_89_rule(Parser *p); +static asdl_seq *_gather_88_rule(Parser *p); static void *_tmp_90_rule(Parser *p); static void *_tmp_91_rule(Parser *p); -static asdl_seq *_loop0_92_rule(Parser *p); -static asdl_seq *_loop0_93_rule(Parser *p); -static asdl_seq *_loop0_94_rule(Parser *p); -static asdl_seq *_loop1_95_rule(Parser *p); +static void *_tmp_92_rule(Parser *p); +static void *_tmp_93_rule(Parser *p); +static void *_tmp_94_rule(Parser *p); +static asdl_seq *_loop0_95_rule(Parser *p); static asdl_seq *_loop0_96_rule(Parser *p); -static asdl_seq *_loop1_97_rule(Parser *p); +static asdl_seq *_loop0_97_rule(Parser *p); static asdl_seq *_loop1_98_rule(Parser *p); -static asdl_seq *_loop1_99_rule(Parser *p); -static asdl_seq *_loop0_100_rule(Parser *p); +static asdl_seq *_loop0_99_rule(Parser *p); +static asdl_seq *_loop1_100_rule(Parser *p); static asdl_seq *_loop1_101_rule(Parser *p); -static asdl_seq *_loop0_102_rule(Parser *p); -static asdl_seq *_loop1_103_rule(Parser *p); -static asdl_seq *_loop0_104_rule(Parser *p); -static asdl_seq *_loop1_105_rule(Parser *p); +static asdl_seq *_loop1_102_rule(Parser *p); +static asdl_seq *_loop0_103_rule(Parser *p); +static asdl_seq *_loop1_104_rule(Parser *p); +static asdl_seq *_loop0_105_rule(Parser *p); static asdl_seq *_loop1_106_rule(Parser *p); -static void *_tmp_107_rule(Parser *p); -static asdl_seq *_loop0_109_rule(Parser *p); -static asdl_seq *_gather_108_rule(Parser *p); -static asdl_seq *_loop1_110_rule(Parser *p); -static asdl_seq *_loop0_111_rule(Parser *p); +static asdl_seq *_loop0_107_rule(Parser *p); +static asdl_seq *_loop1_108_rule(Parser *p); +static asdl_seq *_loop1_109_rule(Parser *p); +static void *_tmp_110_rule(Parser *p); static asdl_seq *_loop0_112_rule(Parser *p); -static void *_tmp_113_rule(Parser *p); +static asdl_seq *_gather_111_rule(Parser *p); +static asdl_seq *_loop1_113_rule(Parser *p); +static asdl_seq *_loop0_114_rule(Parser *p); static asdl_seq *_loop0_115_rule(Parser *p); -static asdl_seq *_gather_114_rule(Parser *p); static void *_tmp_116_rule(Parser *p); static asdl_seq *_loop0_118_rule(Parser *p); static asdl_seq *_gather_117_rule(Parser *p); -static asdl_seq *_loop0_120_rule(Parser *p); -static asdl_seq *_gather_119_rule(Parser *p); -static asdl_seq *_loop0_122_rule(Parser *p); -static asdl_seq *_gather_121_rule(Parser *p); -static asdl_seq *_loop0_124_rule(Parser *p); -static asdl_seq *_gather_123_rule(Parser *p); +static void *_tmp_119_rule(Parser *p); +static asdl_seq *_loop0_121_rule(Parser *p); +static asdl_seq *_gather_120_rule(Parser *p); +static asdl_seq *_loop0_123_rule(Parser *p); +static asdl_seq *_gather_122_rule(Parser *p); static asdl_seq *_loop0_125_rule(Parser *p); +static asdl_seq *_gather_124_rule(Parser *p); static asdl_seq *_loop0_127_rule(Parser *p); static asdl_seq *_gather_126_rule(Parser *p); -static asdl_seq *_loop1_128_rule(Parser *p); -static void *_tmp_129_rule(Parser *p); -static asdl_seq *_loop0_131_rule(Parser *p); -static asdl_seq *_gather_130_rule(Parser *p); -static asdl_seq *_loop0_133_rule(Parser *p); -static asdl_seq *_gather_132_rule(Parser *p); -static asdl_seq *_loop0_135_rule(Parser *p); -static asdl_seq *_gather_134_rule(Parser *p); -static asdl_seq *_loop0_137_rule(Parser *p); -static asdl_seq *_gather_136_rule(Parser *p); -static asdl_seq *_loop0_139_rule(Parser *p); -static asdl_seq *_gather_138_rule(Parser *p); -static void *_tmp_140_rule(Parser *p); -static void *_tmp_141_rule(Parser *p); -static void *_tmp_142_rule(Parser *p); +static asdl_seq *_loop0_128_rule(Parser *p); +static asdl_seq *_loop0_130_rule(Parser *p); +static asdl_seq *_gather_129_rule(Parser *p); +static asdl_seq *_loop1_131_rule(Parser *p); +static void *_tmp_132_rule(Parser *p); +static asdl_seq *_loop0_134_rule(Parser *p); +static asdl_seq *_gather_133_rule(Parser *p); +static asdl_seq *_loop0_136_rule(Parser *p); +static asdl_seq *_gather_135_rule(Parser *p); +static asdl_seq *_loop0_138_rule(Parser *p); +static asdl_seq *_gather_137_rule(Parser *p); +static asdl_seq *_loop0_140_rule(Parser *p); +static asdl_seq *_gather_139_rule(Parser *p); +static asdl_seq *_loop0_142_rule(Parser *p); +static asdl_seq *_gather_141_rule(Parser *p); static void *_tmp_143_rule(Parser *p); static void *_tmp_144_rule(Parser *p); static void *_tmp_145_rule(Parser *p); static void *_tmp_146_rule(Parser *p); static void *_tmp_147_rule(Parser *p); static void *_tmp_148_rule(Parser *p); -static asdl_seq *_loop0_149_rule(Parser *p); -static asdl_seq *_loop0_150_rule(Parser *p); -static asdl_seq *_loop0_151_rule(Parser *p); +static void *_tmp_149_rule(Parser *p); +static void *_tmp_150_rule(Parser *p); +static void *_tmp_151_rule(Parser *p); static void *_tmp_152_rule(Parser *p); static void *_tmp_153_rule(Parser *p); -static void *_tmp_154_rule(Parser *p); -static void *_tmp_155_rule(Parser *p); +static asdl_seq *_loop0_154_rule(Parser *p); +static asdl_seq *_loop0_155_rule(Parser *p); static asdl_seq *_loop0_156_rule(Parser *p); -static asdl_seq *_loop0_157_rule(Parser *p); -static asdl_seq *_loop1_158_rule(Parser *p); -static asdl_seq *_loop1_159_rule(Parser *p); -static asdl_seq *_loop0_160_rule(Parser *p); -static asdl_seq *_loop0_161_rule(Parser *p); +static void *_tmp_157_rule(Parser *p); +static void *_tmp_158_rule(Parser *p); +static void *_tmp_159_rule(Parser *p); +static void *_tmp_160_rule(Parser *p); +static void *_tmp_161_rule(Parser *p); +static asdl_seq *_loop0_162_rule(Parser *p); static asdl_seq *_loop0_163_rule(Parser *p); -static asdl_seq *_gather_162_rule(Parser *p); -static asdl_seq *_loop1_164_rule(Parser *p); -static void *_tmp_165_rule(Parser *p); +static asdl_seq *_loop0_164_rule(Parser *p); +static asdl_seq *_loop1_165_rule(Parser *p); static void *_tmp_166_rule(Parser *p); -static void *_tmp_167_rule(Parser *p); +static asdl_seq *_loop0_167_rule(Parser *p); +static void *_tmp_168_rule(Parser *p); static asdl_seq *_loop0_169_rule(Parser *p); -static asdl_seq *_gather_168_rule(Parser *p); -static asdl_seq *_loop0_171_rule(Parser *p); -static asdl_seq *_gather_170_rule(Parser *p); -static asdl_seq *_loop0_173_rule(Parser *p); -static asdl_seq *_gather_172_rule(Parser *p); -static asdl_seq *_loop0_175_rule(Parser *p); -static asdl_seq *_gather_174_rule(Parser *p); +static asdl_seq *_loop1_170_rule(Parser *p); +static void *_tmp_171_rule(Parser *p); +static void *_tmp_172_rule(Parser *p); +static void *_tmp_173_rule(Parser *p); +static asdl_seq *_loop0_174_rule(Parser *p); +static void *_tmp_175_rule(Parser *p); static void *_tmp_176_rule(Parser *p); -static void *_tmp_177_rule(Parser *p); +static asdl_seq *_loop1_177_rule(Parser *p); static void *_tmp_178_rule(Parser *p); -static void *_tmp_179_rule(Parser *p); -static void *_tmp_180_rule(Parser *p); -static void *_tmp_181_rule(Parser *p); -static void *_tmp_182_rule(Parser *p); -static asdl_seq *_loop0_184_rule(Parser *p); -static asdl_seq *_gather_183_rule(Parser *p); -static void *_tmp_185_rule(Parser *p); +static asdl_seq *_loop0_179_rule(Parser *p); +static asdl_seq *_loop0_180_rule(Parser *p); +static asdl_seq *_loop0_181_rule(Parser *p); +static asdl_seq *_loop0_183_rule(Parser *p); +static asdl_seq *_gather_182_rule(Parser *p); +static void *_tmp_184_rule(Parser *p); +static asdl_seq *_loop0_185_rule(Parser *p); static void *_tmp_186_rule(Parser *p); -static void *_tmp_187_rule(Parser *p); -static void *_tmp_188_rule(Parser *p); -static void *_tmp_189_rule(Parser *p); +static asdl_seq *_loop0_187_rule(Parser *p); +static asdl_seq *_loop1_188_rule(Parser *p); +static asdl_seq *_loop1_189_rule(Parser *p); static void *_tmp_190_rule(Parser *p); static void *_tmp_191_rule(Parser *p); -static void *_tmp_192_rule(Parser *p); +static asdl_seq *_loop0_192_rule(Parser *p); static void *_tmp_193_rule(Parser *p); static void *_tmp_194_rule(Parser *p); static void *_tmp_195_rule(Parser *p); -static void *_tmp_196_rule(Parser *p); -static void *_tmp_197_rule(Parser *p); -static void *_tmp_198_rule(Parser *p); -static void *_tmp_199_rule(Parser *p); -static void *_tmp_200_rule(Parser *p); -static void *_tmp_201_rule(Parser *p); -static void *_tmp_202_rule(Parser *p); -static void *_tmp_203_rule(Parser *p); +static asdl_seq *_loop0_197_rule(Parser *p); +static asdl_seq *_gather_196_rule(Parser *p); +static asdl_seq *_loop0_199_rule(Parser *p); +static asdl_seq *_gather_198_rule(Parser *p); +static asdl_seq *_loop0_201_rule(Parser *p); +static asdl_seq *_gather_200_rule(Parser *p); +static asdl_seq *_loop0_203_rule(Parser *p); +static asdl_seq *_gather_202_rule(Parser *p); static void *_tmp_204_rule(Parser *p); -static void *_tmp_205_rule(Parser *p); -static void *_tmp_206_rule(Parser *p); +static asdl_seq *_loop0_205_rule(Parser *p); +static asdl_seq *_loop1_206_rule(Parser *p); static void *_tmp_207_rule(Parser *p); -static void *_tmp_208_rule(Parser *p); -static void *_tmp_209_rule(Parser *p); +static asdl_seq *_loop0_208_rule(Parser *p); +static asdl_seq *_loop1_209_rule(Parser *p); static void *_tmp_210_rule(Parser *p); static void *_tmp_211_rule(Parser *p); +static void *_tmp_212_rule(Parser *p); +static void *_tmp_213_rule(Parser *p); +static void *_tmp_214_rule(Parser *p); +static void *_tmp_215_rule(Parser *p); +static void *_tmp_216_rule(Parser *p); +static void *_tmp_217_rule(Parser *p); +static void *_tmp_218_rule(Parser *p); +static void *_tmp_219_rule(Parser *p); +static asdl_seq *_loop0_221_rule(Parser *p); +static asdl_seq *_gather_220_rule(Parser *p); +static void *_tmp_222_rule(Parser *p); +static void *_tmp_223_rule(Parser *p); +static void *_tmp_224_rule(Parser *p); +static void *_tmp_225_rule(Parser *p); +static void *_tmp_226_rule(Parser *p); +static void *_tmp_227_rule(Parser *p); +static void *_tmp_228_rule(Parser *p); +static void *_tmp_229_rule(Parser *p); +static void *_tmp_230_rule(Parser *p); +static void *_tmp_231_rule(Parser *p); +static void *_tmp_232_rule(Parser *p); +static void *_tmp_233_rule(Parser *p); +static void *_tmp_234_rule(Parser *p); +static void *_tmp_235_rule(Parser *p); +static void *_tmp_236_rule(Parser *p); +static void *_tmp_237_rule(Parser *p); +static void *_tmp_238_rule(Parser *p); +static void *_tmp_239_rule(Parser *p); +static void *_tmp_240_rule(Parser *p); +static void *_tmp_241_rule(Parser *p); +static void *_tmp_242_rule(Parser *p); +static void *_tmp_243_rule(Parser *p); +static void *_tmp_244_rule(Parser *p); +static void *_tmp_245_rule(Parser *p); +static void *_tmp_246_rule(Parser *p); +static void *_tmp_247_rule(Parser *p); +static void *_tmp_248_rule(Parser *p); +static void *_tmp_249_rule(Parser *p); +static void *_tmp_250_rule(Parser *p); +static void *_tmp_251_rule(Parser *p); // file: statements? $ static mod_ty file_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } mod_ty _res = NULL; int _mark = p->mark; { // statements? $ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> file[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statements? $")); @@ -967,7 +1076,7 @@ file_rule(Parser *p) _res = _PyPegen_make_module ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -978,7 +1087,7 @@ file_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -986,16 +1095,19 @@ file_rule(Parser *p) static mod_ty interactive_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } mod_ty _res = NULL; int _mark = p->mark; { // statement_newline if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> interactive[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement_newline")); @@ -1008,7 +1120,7 @@ interactive_rule(Parser *p) _res = _PyAST_Interactive ( a , p -> arena ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -1019,7 +1131,7 @@ interactive_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -1027,16 +1139,19 @@ interactive_rule(Parser *p) static mod_ty eval_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } mod_ty _res = NULL; int _mark = p->mark; { // expressions NEWLINE* $ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> eval[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions NEWLINE* $")); @@ -1055,7 +1170,7 @@ eval_rule(Parser *p) _res = _PyAST_Expression ( a , p -> arena ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -1066,7 +1181,7 @@ eval_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -1074,16 +1189,19 @@ eval_rule(Parser *p) static mod_ty func_type_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } mod_ty _res = NULL; int _mark = p->mark; { // '(' type_expressions? ')' '->' expression NEWLINE* $ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> func_type[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' type_expressions? ')' '->' expression NEWLINE* $")); @@ -1114,7 +1232,7 @@ func_type_rule(Parser *p) _res = _PyAST_FunctionType ( a , b , p -> arena ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -1125,7 +1243,7 @@ func_type_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -1133,16 +1251,19 @@ func_type_rule(Parser *p) static expr_ty fstring_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; { // star_expressions if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> fstring[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); @@ -1161,7 +1282,7 @@ fstring_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -1169,16 +1290,19 @@ fstring_rule(Parser *p) static asdl_stmt_seq* statements_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_stmt_seq* _res = NULL; int _mark = p->mark; { // statement+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> statements[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement+")); @@ -1191,7 +1315,7 @@ statements_rule(Parser *p) _res = ( asdl_stmt_seq* ) _PyPegen_seq_flatten ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -1202,7 +1326,7 @@ statements_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -1210,16 +1334,19 @@ statements_rule(Parser *p) static asdl_stmt_seq* statement_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_stmt_seq* _res = NULL; int _mark = p->mark; { // compound_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> statement[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compound_stmt")); @@ -1232,7 +1359,7 @@ statement_rule(Parser *p) _res = ( asdl_stmt_seq* ) _PyPegen_singleton_seq ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -1243,7 +1370,7 @@ statement_rule(Parser *p) } { // simple_stmts if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> statement[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmts")); @@ -1256,7 +1383,7 @@ statement_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -1267,7 +1394,7 @@ statement_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -1275,16 +1402,19 @@ statement_rule(Parser *p) static asdl_stmt_seq* statement_newline_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_stmt_seq* _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -1293,7 +1423,7 @@ statement_newline_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // compound_stmt NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> statement_newline[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compound_stmt NEWLINE")); @@ -1309,7 +1439,7 @@ statement_newline_rule(Parser *p) _res = ( asdl_stmt_seq* ) _PyPegen_singleton_seq ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -1320,7 +1450,7 @@ statement_newline_rule(Parser *p) } { // simple_stmts if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> statement_newline[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmts")); @@ -1339,7 +1469,7 @@ statement_newline_rule(Parser *p) } { // NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> statement_newline[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); @@ -1351,7 +1481,7 @@ statement_newline_rule(Parser *p) D(fprintf(stderr, "%*c+ statement_newline[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -1361,7 +1491,7 @@ statement_newline_rule(Parser *p) _res = ( asdl_stmt_seq* ) _PyPegen_singleton_seq ( p , CHECK ( stmt_ty , _PyAST_Pass ( EXTRA ) ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -1372,7 +1502,7 @@ statement_newline_rule(Parser *p) } { // $ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> statement_newline[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "$")); @@ -1385,7 +1515,7 @@ statement_newline_rule(Parser *p) _res = _PyPegen_interactive_exit ( p ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -1396,7 +1526,7 @@ statement_newline_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -1404,16 +1534,19 @@ statement_newline_rule(Parser *p) static asdl_stmt_seq* simple_stmts_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_stmt_seq* _res = NULL; int _mark = p->mark; { // simple_stmt !';' NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> simple_stmts[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt !';' NEWLINE")); @@ -1431,7 +1564,7 @@ simple_stmts_rule(Parser *p) _res = ( asdl_stmt_seq* ) _PyPegen_singleton_seq ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -1442,7 +1575,7 @@ simple_stmts_rule(Parser *p) } { // ';'.simple_stmt+ ';'? NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> simple_stmts[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';'.simple_stmt+ ';'? NEWLINE")); @@ -1462,7 +1595,7 @@ simple_stmts_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -1473,7 +1606,7 @@ simple_stmts_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -1494,20 +1627,23 @@ simple_stmts_rule(Parser *p) static stmt_ty simple_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; if (_PyPegen_is_memoized(p, simple_stmt_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -1516,7 +1652,7 @@ simple_stmt_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // assignment if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment")); @@ -1535,7 +1671,7 @@ simple_stmt_rule(Parser *p) } { // star_expressions if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); @@ -1547,7 +1683,7 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -1557,7 +1693,7 @@ simple_stmt_rule(Parser *p) _res = _PyAST_Expr ( e , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -1568,7 +1704,7 @@ simple_stmt_rule(Parser *p) } { // &'return' return_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'return' return_stmt")); @@ -1589,7 +1725,7 @@ simple_stmt_rule(Parser *p) } { // &('import' | 'from') import_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('import' | 'from') import_stmt")); @@ -1610,7 +1746,7 @@ simple_stmt_rule(Parser *p) } { // &'raise' raise_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'raise' raise_stmt")); @@ -1631,7 +1767,7 @@ simple_stmt_rule(Parser *p) } { // 'pass' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'pass'")); @@ -1643,7 +1779,7 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'pass'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -1653,7 +1789,7 @@ simple_stmt_rule(Parser *p) _res = _PyAST_Pass ( EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -1664,13 +1800,13 @@ simple_stmt_rule(Parser *p) } { // &'del' del_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'del' del_stmt")); stmt_ty del_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 600) // token='del' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 603) // token='del' && (del_stmt_var = del_stmt_rule(p)) // del_stmt ) @@ -1685,13 +1821,13 @@ simple_stmt_rule(Parser *p) } { // &'yield' yield_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'yield' yield_stmt")); stmt_ty yield_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 570) // token='yield' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 573) // token='yield' && (yield_stmt_var = yield_stmt_rule(p)) // yield_stmt ) @@ -1706,7 +1842,7 @@ simple_stmt_rule(Parser *p) } { // &'assert' assert_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'assert' assert_stmt")); @@ -1727,7 +1863,7 @@ simple_stmt_rule(Parser *p) } { // 'break' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'break'")); @@ -1739,7 +1875,7 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'break'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -1749,7 +1885,7 @@ simple_stmt_rule(Parser *p) _res = _PyAST_Break ( EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -1760,7 +1896,7 @@ simple_stmt_rule(Parser *p) } { // 'continue' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'continue'")); @@ -1772,7 +1908,7 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'continue'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -1782,7 +1918,7 @@ simple_stmt_rule(Parser *p) _res = _PyAST_Continue ( EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -1793,7 +1929,7 @@ simple_stmt_rule(Parser *p) } { // &'global' global_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'global' global_stmt")); @@ -1814,7 +1950,7 @@ simple_stmt_rule(Parser *p) } { // &'nonlocal' nonlocal_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'nonlocal' nonlocal_stmt")); @@ -1836,7 +1972,7 @@ simple_stmt_rule(Parser *p) _res = NULL; done: _PyPegen_insert_memo(p, _mark, simple_stmt_type, _res); - D(p->level--); + p->level--; return _res; } @@ -1852,16 +1988,19 @@ simple_stmt_rule(Parser *p) static stmt_ty compound_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; { // &('def' | '@' | ASYNC) function_def if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('def' | '@' | ASYNC) function_def")); @@ -1882,13 +2021,13 @@ compound_stmt_rule(Parser *p) } { // &'if' if_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'if' if_stmt")); stmt_ty if_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 627) // token='if' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 641) // token='if' && (if_stmt_var = if_stmt_rule(p)) // if_stmt ) @@ -1903,7 +2042,7 @@ compound_stmt_rule(Parser *p) } { // &('class' | '@') class_def if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('class' | '@') class_def")); @@ -1924,7 +2063,7 @@ compound_stmt_rule(Parser *p) } { // &('with' | ASYNC) with_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('with' | ASYNC) with_stmt")); @@ -1945,7 +2084,7 @@ compound_stmt_rule(Parser *p) } { // &('for' | ASYNC) for_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('for' | ASYNC) for_stmt")); @@ -1966,13 +2105,13 @@ compound_stmt_rule(Parser *p) } { // &'try' try_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'try' try_stmt")); stmt_ty try_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 612) // token='try' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 623) // token='try' && (try_stmt_var = try_stmt_rule(p)) // try_stmt ) @@ -1987,13 +2126,13 @@ compound_stmt_rule(Parser *p) } { // &'while' while_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'while' while_stmt")); stmt_ty while_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 632) // token='while' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 646) // token='while' && (while_stmt_var = while_stmt_rule(p)) // while_stmt ) @@ -2008,7 +2147,7 @@ compound_stmt_rule(Parser *p) } { // match_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "match_stmt")); @@ -2027,7 +2166,7 @@ compound_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -2040,16 +2179,19 @@ compound_stmt_rule(Parser *p) static stmt_ty assignment_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -2058,7 +2200,7 @@ assignment_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // NAME ':' expression ['=' annotated_rhs] if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME ':' expression ['=' annotated_rhs]")); @@ -2079,7 +2221,7 @@ assignment_rule(Parser *p) D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME ':' expression ['=' annotated_rhs]")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -2089,7 +2231,7 @@ assignment_rule(Parser *p) _res = CHECK_VERSION ( stmt_ty , 6 , "Variable annotation syntax is" , _PyAST_AnnAssign ( CHECK ( expr_ty , _PyPegen_set_expr_context ( p , a , Store ) ) , b , c , 1 , EXTRA ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2100,7 +2242,7 @@ assignment_rule(Parser *p) } { // ('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs] if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs]")); @@ -2121,7 +2263,7 @@ assignment_rule(Parser *p) D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs]")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -2131,7 +2273,7 @@ assignment_rule(Parser *p) _res = CHECK_VERSION ( stmt_ty , 6 , "Variable annotations syntax is" , _PyAST_AnnAssign ( a , b , c , 0 , EXTRA ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2142,7 +2284,7 @@ assignment_rule(Parser *p) } { // ((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT?")); @@ -2162,7 +2304,7 @@ assignment_rule(Parser *p) D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -2172,7 +2314,7 @@ assignment_rule(Parser *p) _res = _PyAST_Assign ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2183,7 +2325,7 @@ assignment_rule(Parser *p) } { // single_target augassign ~ (yield_expr | star_expressions) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "single_target augassign ~ (yield_expr | star_expressions)")); @@ -2204,7 +2346,7 @@ assignment_rule(Parser *p) D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "single_target augassign ~ (yield_expr | star_expressions)")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -2214,7 +2356,7 @@ assignment_rule(Parser *p) _res = _PyAST_AugAssign ( a , b -> kind , c , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2223,13 +2365,13 @@ assignment_rule(Parser *p) D(fprintf(stderr, "%*c%s assignment[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "single_target augassign ~ (yield_expr | star_expressions)")); if (_cut_var) { - D(p->level--); + p->level--; return NULL; } } if (p->call_invalid_rules) { // invalid_assignment if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_assignment")); @@ -2248,7 +2390,7 @@ assignment_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -2256,16 +2398,19 @@ assignment_rule(Parser *p) static expr_ty annotated_rhs_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; { // yield_expr if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> annotated_rhs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); @@ -2284,7 +2429,7 @@ annotated_rhs_rule(Parser *p) } { // star_expressions if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> annotated_rhs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); @@ -2303,7 +2448,7 @@ annotated_rhs_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -2324,16 +2469,19 @@ annotated_rhs_rule(Parser *p) static AugOperator* augassign_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } AugOperator* _res = NULL; int _mark = p->mark; { // '+=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+='")); @@ -2346,7 +2494,7 @@ augassign_rule(Parser *p) _res = _PyPegen_augoperator ( p , Add ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2357,7 +2505,7 @@ augassign_rule(Parser *p) } { // '-=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-='")); @@ -2370,7 +2518,7 @@ augassign_rule(Parser *p) _res = _PyPegen_augoperator ( p , Sub ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2381,7 +2529,7 @@ augassign_rule(Parser *p) } { // '*=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*='")); @@ -2394,7 +2542,7 @@ augassign_rule(Parser *p) _res = _PyPegen_augoperator ( p , Mult ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2405,7 +2553,7 @@ augassign_rule(Parser *p) } { // '@=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@='")); @@ -2418,7 +2566,7 @@ augassign_rule(Parser *p) _res = CHECK_VERSION ( AugOperator* , 5 , "The '@' operator is" , _PyPegen_augoperator ( p , MatMult ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2429,7 +2577,7 @@ augassign_rule(Parser *p) } { // '/=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/='")); @@ -2442,7 +2590,7 @@ augassign_rule(Parser *p) _res = _PyPegen_augoperator ( p , Div ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2453,7 +2601,7 @@ augassign_rule(Parser *p) } { // '%=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'%='")); @@ -2466,7 +2614,7 @@ augassign_rule(Parser *p) _res = _PyPegen_augoperator ( p , Mod ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2477,7 +2625,7 @@ augassign_rule(Parser *p) } { // '&=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'&='")); @@ -2490,7 +2638,7 @@ augassign_rule(Parser *p) _res = _PyPegen_augoperator ( p , BitAnd ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2501,7 +2649,7 @@ augassign_rule(Parser *p) } { // '|=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|='")); @@ -2514,7 +2662,7 @@ augassign_rule(Parser *p) _res = _PyPegen_augoperator ( p , BitOr ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2525,7 +2673,7 @@ augassign_rule(Parser *p) } { // '^=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'^='")); @@ -2538,7 +2686,7 @@ augassign_rule(Parser *p) _res = _PyPegen_augoperator ( p , BitXor ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2549,7 +2697,7 @@ augassign_rule(Parser *p) } { // '<<=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'<<='")); @@ -2562,7 +2710,7 @@ augassign_rule(Parser *p) _res = _PyPegen_augoperator ( p , LShift ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2573,7 +2721,7 @@ augassign_rule(Parser *p) } { // '>>=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'>>='")); @@ -2586,7 +2734,7 @@ augassign_rule(Parser *p) _res = _PyPegen_augoperator ( p , RShift ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2597,7 +2745,7 @@ augassign_rule(Parser *p) } { // '**=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**='")); @@ -2610,7 +2758,7 @@ augassign_rule(Parser *p) _res = _PyPegen_augoperator ( p , Pow ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2621,7 +2769,7 @@ augassign_rule(Parser *p) } { // '//=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> augassign[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'//='")); @@ -2634,7 +2782,7 @@ augassign_rule(Parser *p) _res = _PyPegen_augoperator ( p , FloorDiv ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2645,7 +2793,7 @@ augassign_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -2653,16 +2801,19 @@ augassign_rule(Parser *p) static stmt_ty return_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -2671,7 +2822,7 @@ return_stmt_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // 'return' star_expressions? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> return_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'return' star_expressions?")); @@ -2686,7 +2837,7 @@ return_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ return_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'return' star_expressions?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -2696,7 +2847,7 @@ return_stmt_rule(Parser *p) _res = _PyAST_Return ( a , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2707,7 +2858,7 @@ return_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -2715,16 +2866,19 @@ return_stmt_rule(Parser *p) static stmt_ty raise_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -2733,7 +2887,7 @@ raise_stmt_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // 'raise' expression ['from' expression] if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> raise_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'raise' expression ['from' expression]")); @@ -2751,7 +2905,7 @@ raise_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ raise_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'raise' expression ['from' expression]")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -2761,7 +2915,7 @@ raise_stmt_rule(Parser *p) _res = _PyAST_Raise ( a , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2772,7 +2926,7 @@ raise_stmt_rule(Parser *p) } { // 'raise' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> raise_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'raise'")); @@ -2784,7 +2938,7 @@ raise_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ raise_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'raise'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -2794,7 +2948,7 @@ raise_stmt_rule(Parser *p) _res = _PyAST_Raise ( NULL , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2805,7 +2959,7 @@ raise_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -2813,16 +2967,19 @@ raise_stmt_rule(Parser *p) static stmt_ty global_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -2831,7 +2988,7 @@ global_stmt_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // 'global' ','.NAME+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> global_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'global' ','.NAME+")); @@ -2846,7 +3003,7 @@ global_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ global_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'global' ','.NAME+")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -2856,7 +3013,7 @@ global_stmt_rule(Parser *p) _res = _PyAST_Global ( CHECK ( asdl_identifier_seq* , _PyPegen_map_names_to_ids ( p , a ) ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2867,7 +3024,7 @@ global_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -2875,16 +3032,19 @@ global_stmt_rule(Parser *p) static stmt_ty nonlocal_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -2893,7 +3053,7 @@ nonlocal_stmt_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // 'nonlocal' ','.NAME+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> nonlocal_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'nonlocal' ','.NAME+")); @@ -2908,7 +3068,7 @@ nonlocal_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ nonlocal_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'nonlocal' ','.NAME+")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -2918,7 +3078,7 @@ nonlocal_stmt_rule(Parser *p) _res = _PyAST_Nonlocal ( CHECK ( asdl_identifier_seq* , _PyPegen_map_names_to_ids ( p , a ) ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2929,7 +3089,7 @@ nonlocal_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -2937,16 +3097,19 @@ nonlocal_stmt_rule(Parser *p) static stmt_ty del_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -2955,14 +3118,14 @@ del_stmt_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // 'del' del_targets &(';' | NEWLINE) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> del_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'del' del_targets &(';' | NEWLINE)")); Token * _keyword; asdl_expr_seq* a; if ( - (_keyword = _PyPegen_expect_token(p, 600)) // token='del' + (_keyword = _PyPegen_expect_token(p, 603)) // token='del' && (a = del_targets_rule(p)) // del_targets && @@ -2972,7 +3135,7 @@ del_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ del_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'del' del_targets &(';' | NEWLINE)")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -2982,7 +3145,7 @@ del_stmt_rule(Parser *p) _res = _PyAST_Delete ( a , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -2993,7 +3156,7 @@ del_stmt_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_del_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> del_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_del_stmt")); @@ -3012,7 +3175,7 @@ del_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -3020,16 +3183,19 @@ del_stmt_rule(Parser *p) static stmt_ty yield_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -3038,7 +3204,7 @@ yield_stmt_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // yield_expr if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> yield_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); @@ -3050,7 +3216,7 @@ yield_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ yield_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -3060,7 +3226,7 @@ yield_stmt_rule(Parser *p) _res = _PyAST_Expr ( y , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -3071,7 +3237,7 @@ yield_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -3079,16 +3245,19 @@ yield_stmt_rule(Parser *p) static stmt_ty assert_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -3097,7 +3266,7 @@ assert_stmt_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // 'assert' expression [',' expression] if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> assert_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'assert' expression [',' expression]")); @@ -3115,7 +3284,7 @@ assert_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ assert_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'assert' expression [',' expression]")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -3125,7 +3294,7 @@ assert_stmt_rule(Parser *p) _res = _PyAST_Assert ( a , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -3136,24 +3305,46 @@ assert_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// import_stmt: import_name | import_from +// import_stmt: invalid_import | import_name | import_from static stmt_ty import_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; + if (p->call_invalid_rules) { // invalid_import + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> import_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_import")); + void *invalid_import_var; + if ( + (invalid_import_var = invalid_import_rule(p)) // invalid_import + ) + { + D(fprintf(stderr, "%*c+ import_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_import")); + _res = invalid_import_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s import_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_import")); + } { // import_name if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> import_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_name")); @@ -3172,7 +3363,7 @@ import_stmt_rule(Parser *p) } { // import_from if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> import_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from")); @@ -3191,7 +3382,7 @@ import_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -3199,16 +3390,19 @@ import_stmt_rule(Parser *p) static stmt_ty import_name_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -3217,14 +3411,14 @@ import_name_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // 'import' dotted_as_names if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> import_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import' dotted_as_names")); Token * _keyword; asdl_alias_seq* a; if ( - (_keyword = _PyPegen_expect_token(p, 531)) // token='import' + (_keyword = _PyPegen_expect_token(p, 606)) // token='import' && (a = dotted_as_names_rule(p)) // dotted_as_names ) @@ -3232,7 +3426,7 @@ import_name_rule(Parser *p) D(fprintf(stderr, "%*c+ import_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import' dotted_as_names")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -3242,7 +3436,7 @@ import_name_rule(Parser *p) _res = _PyAST_Import ( a , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -3253,7 +3447,7 @@ import_name_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -3263,16 +3457,19 @@ import_name_rule(Parser *p) static stmt_ty import_from_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -3281,7 +3478,7 @@ import_from_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // 'from' (('.' | '...'))* dotted_name 'import' import_from_targets if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> import_from[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))* dotted_name 'import' import_from_targets")); @@ -3291,13 +3488,13 @@ import_from_rule(Parser *p) expr_ty b; asdl_alias_seq* c; if ( - (_keyword = _PyPegen_expect_token(p, 569)) // token='from' + (_keyword = _PyPegen_expect_token(p, 607)) // token='from' && (a = _loop0_24_rule(p)) // (('.' | '...'))* && (b = dotted_name_rule(p)) // dotted_name && - (_keyword_1 = _PyPegen_expect_token(p, 531)) // token='import' + (_keyword_1 = _PyPegen_expect_token(p, 606)) // token='import' && (c = import_from_targets_rule(p)) // import_from_targets ) @@ -3305,7 +3502,7 @@ import_from_rule(Parser *p) D(fprintf(stderr, "%*c+ import_from[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))* dotted_name 'import' import_from_targets")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -3315,7 +3512,7 @@ import_from_rule(Parser *p) _res = _PyAST_ImportFrom ( b -> v . Name . id , c , _PyPegen_seq_count_dots ( a ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -3326,7 +3523,7 @@ import_from_rule(Parser *p) } { // 'from' (('.' | '...'))+ 'import' import_from_targets if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> import_from[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))+ 'import' import_from_targets")); @@ -3335,11 +3532,11 @@ import_from_rule(Parser *p) asdl_seq * a; asdl_alias_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 569)) // token='from' + (_keyword = _PyPegen_expect_token(p, 607)) // token='from' && (a = _loop1_25_rule(p)) // (('.' | '...'))+ && - (_keyword_1 = _PyPegen_expect_token(p, 531)) // token='import' + (_keyword_1 = _PyPegen_expect_token(p, 606)) // token='import' && (b = import_from_targets_rule(p)) // import_from_targets ) @@ -3347,7 +3544,7 @@ import_from_rule(Parser *p) D(fprintf(stderr, "%*c+ import_from[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' (('.' | '...'))+ 'import' import_from_targets")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -3357,7 +3554,7 @@ import_from_rule(Parser *p) _res = _PyAST_ImportFrom ( NULL , b , _PyPegen_seq_count_dots ( a ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -3368,7 +3565,7 @@ import_from_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -3380,16 +3577,19 @@ import_from_rule(Parser *p) static asdl_alias_seq* import_from_targets_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_alias_seq* _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -3398,7 +3598,7 @@ import_from_targets_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '(' import_from_as_names ','? ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' import_from_as_names ','? ')'")); @@ -3421,7 +3621,7 @@ import_from_targets_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -3432,7 +3632,7 @@ import_from_targets_rule(Parser *p) } { // import_from_as_names !',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_names !','")); @@ -3453,7 +3653,7 @@ import_from_targets_rule(Parser *p) } { // '*' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); @@ -3465,7 +3665,7 @@ import_from_targets_rule(Parser *p) D(fprintf(stderr, "%*c+ import_from_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -3475,7 +3675,7 @@ import_from_targets_rule(Parser *p) _res = ( asdl_alias_seq* ) _PyPegen_singleton_seq ( p , CHECK ( alias_ty , _PyPegen_alias_for_star ( p , EXTRA ) ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -3486,7 +3686,7 @@ import_from_targets_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_import_from_targets if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_import_from_targets")); @@ -3505,7 +3705,7 @@ import_from_targets_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -3513,16 +3713,19 @@ import_from_targets_rule(Parser *p) static asdl_alias_seq* import_from_as_names_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_alias_seq* _res = NULL; int _mark = p->mark; { // ','.import_from_as_name+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> import_from_as_names[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.import_from_as_name+")); @@ -3535,7 +3738,7 @@ import_from_as_names_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -3546,7 +3749,7 @@ import_from_as_names_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -3554,16 +3757,19 @@ import_from_as_names_rule(Parser *p) static alias_ty import_from_as_name_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } alias_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -3572,7 +3778,7 @@ import_from_as_name_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // NAME ['as' NAME] if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> import_from_as_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME ['as' NAME]")); @@ -3587,7 +3793,7 @@ import_from_as_name_rule(Parser *p) D(fprintf(stderr, "%*c+ import_from_as_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME ['as' NAME]")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -3597,7 +3803,7 @@ import_from_as_name_rule(Parser *p) _res = _PyAST_alias ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Name . id : NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -3608,7 +3814,7 @@ import_from_as_name_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -3616,16 +3822,19 @@ import_from_as_name_rule(Parser *p) static asdl_alias_seq* dotted_as_names_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_alias_seq* _res = NULL; int _mark = p->mark; { // ','.dotted_as_name+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> dotted_as_names[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.dotted_as_name+")); @@ -3638,7 +3847,7 @@ dotted_as_names_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -3649,7 +3858,7 @@ dotted_as_names_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -3657,16 +3866,19 @@ dotted_as_names_rule(Parser *p) static alias_ty dotted_as_name_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } alias_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -3675,7 +3887,7 @@ dotted_as_name_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // dotted_name ['as' NAME] if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> dotted_as_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_name ['as' NAME]")); @@ -3690,7 +3902,7 @@ dotted_as_name_rule(Parser *p) D(fprintf(stderr, "%*c+ dotted_as_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_name ['as' NAME]")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -3700,7 +3912,7 @@ dotted_as_name_rule(Parser *p) _res = _PyAST_alias ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Name . id : NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -3711,7 +3923,7 @@ dotted_as_name_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -3721,10 +3933,13 @@ static expr_ty dotted_name_raw(Parser *); static expr_ty dotted_name_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, dotted_name_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; @@ -3732,37 +3947,40 @@ dotted_name_rule(Parser *p) while (1) { int tmpvar_0 = _PyPegen_update_memo(p, _mark, dotted_name_type, _res); if (tmpvar_0) { - D(p->level--); + p->level--; return _res; } p->mark = _mark; - p->in_raw_rule++; void *_raw = dotted_name_raw(p); - p->in_raw_rule--; - if (p->error_indicator) + if (p->error_indicator) { + p->level--; return NULL; + } if (_raw == NULL || p->mark <= _resmark) break; _resmark = p->mark; _res = _raw; } p->mark = _resmark; - D(p->level--); + p->level--; return _res; } static expr_ty dotted_name_raw(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; { // dotted_name '.' NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> dotted_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_name '.' NAME")); @@ -3781,7 +3999,7 @@ dotted_name_raw(Parser *p) _res = _PyPegen_join_names_with_dot ( p , a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -3792,7 +4010,7 @@ dotted_name_raw(Parser *p) } { // NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> dotted_name[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); @@ -3811,7 +4029,7 @@ dotted_name_raw(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -3819,20 +4037,23 @@ dotted_name_raw(Parser *p) static asdl_stmt_seq* block_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_stmt_seq* _res = NULL; if (_PyPegen_is_memoized(p, block_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; { // NEWLINE INDENT statements DEDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT statements DEDENT")); @@ -3854,7 +4075,7 @@ block_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -3865,7 +4086,7 @@ block_rule(Parser *p) } { // simple_stmts if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmts")); @@ -3884,7 +4105,7 @@ block_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_block")); @@ -3904,7 +4125,7 @@ block_rule(Parser *p) _res = NULL; done: _PyPegen_insert_memo(p, _mark, block_type, _res); - D(p->level--); + p->level--; return _res; } @@ -3912,16 +4133,19 @@ block_rule(Parser *p) static asdl_expr_seq* decorators_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_expr_seq* _res = NULL; int _mark = p->mark; { // (('@' named_expression NEWLINE))+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> decorators[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(('@' named_expression NEWLINE))+")); @@ -3934,7 +4158,7 @@ decorators_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -3945,7 +4169,7 @@ decorators_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -3953,16 +4177,19 @@ decorators_rule(Parser *p) static stmt_ty class_def_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; { // decorators class_def_raw if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> class_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "decorators class_def_raw")); @@ -3978,7 +4205,7 @@ class_def_rule(Parser *p) _res = _PyPegen_class_def_decorators ( p , a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -3989,7 +4216,7 @@ class_def_rule(Parser *p) } { // class_def_raw if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> class_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "class_def_raw")); @@ -4008,24 +4235,27 @@ class_def_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// class_def_raw: invalid_class_def_raw | 'class' NAME ['(' arguments? ')'] &&':' block +// class_def_raw: invalid_class_def_raw | 'class' NAME ['(' arguments? ')'] ':' block static stmt_ty class_def_raw_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -4034,7 +4264,7 @@ class_def_raw_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro if (p->call_invalid_rules) { // invalid_class_def_raw if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> class_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_class_def_raw")); @@ -4051,33 +4281,33 @@ class_def_raw_rule(Parser *p) D(fprintf(stderr, "%*c%s class_def_raw[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_class_def_raw")); } - { // 'class' NAME ['(' arguments? ')'] &&':' block + { // 'class' NAME ['(' arguments? ')'] ':' block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> class_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] &&':' block")); + D(fprintf(stderr, "%*c> class_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' block")); Token * _keyword; Token * _literal; expr_ty a; void *b; asdl_stmt_seq* c; if ( - (_keyword = _PyPegen_expect_token(p, 636)) // token='class' + (_keyword = _PyPegen_expect_token(p, 653)) // token='class' && (a = _PyPegen_name_token(p)) // NAME && (b = _tmp_33_rule(p), !p->error_indicator) // ['(' arguments? ')'] && - (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' + (_literal = _PyPegen_expect_token(p, 11)) // token=':' && (c = block_rule(p)) // block ) { - D(fprintf(stderr, "%*c+ class_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] &&':' block")); + D(fprintf(stderr, "%*c+ class_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -4087,18 +4317,18 @@ class_def_raw_rule(Parser *p) _res = _PyAST_ClassDef ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , c , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s class_def_raw[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'class' NAME ['(' arguments? ')'] &&':' block")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' block")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -4106,16 +4336,19 @@ class_def_raw_rule(Parser *p) static stmt_ty function_def_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; { // decorators function_def_raw if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> function_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "decorators function_def_raw")); @@ -4131,7 +4364,7 @@ function_def_rule(Parser *p) _res = _PyPegen_function_def_decorators ( p , d , f ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4142,7 +4375,7 @@ function_def_rule(Parser *p) } { // function_def_raw if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> function_def[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "function_def_raw")); @@ -4161,7 +4394,7 @@ function_def_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -4172,16 +4405,19 @@ function_def_rule(Parser *p) static stmt_ty function_def_raw_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -4190,7 +4426,7 @@ function_def_raw_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro if (p->call_invalid_rules) { // invalid_def_raw if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> function_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_def_raw")); @@ -4209,7 +4445,7 @@ function_def_raw_rule(Parser *p) } { // 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> function_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); @@ -4223,7 +4459,7 @@ function_def_raw_rule(Parser *p) void *params; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 635)) // token='def' + (_keyword = _PyPegen_expect_token(p, 651)) // token='def' && (n = _PyPegen_name_token(p)) // NAME && @@ -4245,7 +4481,7 @@ function_def_raw_rule(Parser *p) D(fprintf(stderr, "%*c+ function_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -4255,7 +4491,7 @@ function_def_raw_rule(Parser *p) _res = _PyAST_FunctionDef ( n -> v . Name . id , ( params ) ? params : CHECK ( arguments_ty , _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4266,7 +4502,7 @@ function_def_raw_rule(Parser *p) } { // ASYNC 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> function_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); @@ -4283,7 +4519,7 @@ function_def_raw_rule(Parser *p) if ( (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' && - (_keyword = _PyPegen_expect_token(p, 635)) // token='def' + (_keyword = _PyPegen_expect_token(p, 651)) // token='def' && (n = _PyPegen_name_token(p)) // NAME && @@ -4305,7 +4541,7 @@ function_def_raw_rule(Parser *p) D(fprintf(stderr, "%*c+ function_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -4315,7 +4551,7 @@ function_def_raw_rule(Parser *p) _res = CHECK_VERSION ( stmt_ty , 5 , "Async functions are" , _PyAST_AsyncFunctionDef ( n -> v . Name . id , ( params ) ? params : CHECK ( arguments_ty , _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4326,7 +4562,7 @@ function_def_raw_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -4334,16 +4570,19 @@ function_def_raw_rule(Parser *p) static arguments_ty params_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } arguments_ty _res = NULL; int _mark = p->mark; if (p->call_invalid_rules) { // invalid_parameters if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_parameters")); @@ -4362,7 +4601,7 @@ params_rule(Parser *p) } { // parameters if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "parameters")); @@ -4381,7 +4620,7 @@ params_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -4394,16 +4633,19 @@ params_rule(Parser *p) static arguments_ty parameters_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } arguments_ty _res = NULL; int _mark = p->mark; { // slash_no_default param_no_default* param_with_default* star_etc? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default param_no_default* param_with_default* star_etc?")); @@ -4422,10 +4664,10 @@ parameters_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default param_no_default* param_with_default* star_etc?")); - _res = _PyPegen_make_arguments ( p , a , NULL , b , c , d ); + _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , a , NULL , b , c , d ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4436,7 +4678,7 @@ parameters_rule(Parser *p) } { // slash_with_default param_with_default* star_etc? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default param_with_default* star_etc?")); @@ -4452,10 +4694,10 @@ parameters_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default param_with_default* star_etc?")); - _res = _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ); + _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4466,7 +4708,7 @@ parameters_rule(Parser *p) } { // param_no_default+ param_with_default* star_etc? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default+ param_with_default* star_etc?")); @@ -4485,7 +4727,7 @@ parameters_rule(Parser *p) _res = _PyPegen_make_arguments ( p , NULL , NULL , a , b , c ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4496,7 +4738,7 @@ parameters_rule(Parser *p) } { // param_with_default+ star_etc? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+ star_etc?")); @@ -4512,7 +4754,7 @@ parameters_rule(Parser *p) _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4523,7 +4765,7 @@ parameters_rule(Parser *p) } { // star_etc if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_etc")); @@ -4536,7 +4778,7 @@ parameters_rule(Parser *p) _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , NULL , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4547,7 +4789,7 @@ parameters_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -4555,16 +4797,19 @@ parameters_rule(Parser *p) static asdl_arg_seq* slash_no_default_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_arg_seq* _res = NULL; int _mark = p->mark; { // param_no_default+ '/' ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default+ '/' ','")); @@ -4583,7 +4828,7 @@ slash_no_default_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4594,7 +4839,7 @@ slash_no_default_rule(Parser *p) } { // param_no_default+ '/' &')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default+ '/' &')'")); @@ -4612,7 +4857,7 @@ slash_no_default_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4623,7 +4868,7 @@ slash_no_default_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -4633,16 +4878,19 @@ slash_no_default_rule(Parser *p) static SlashWithDefault* slash_with_default_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } SlashWithDefault* _res = NULL; int _mark = p->mark; { // param_no_default* param_with_default+ '/' ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> slash_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* param_with_default+ '/' ','")); @@ -4664,7 +4912,7 @@ slash_with_default_rule(Parser *p) _res = _PyPegen_slash_with_default ( p , ( asdl_arg_seq* ) a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4675,7 +4923,7 @@ slash_with_default_rule(Parser *p) } { // param_no_default* param_with_default+ '/' &')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> slash_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* param_with_default+ '/' &')'")); @@ -4696,7 +4944,7 @@ slash_with_default_rule(Parser *p) _res = _PyPegen_slash_with_default ( p , ( asdl_arg_seq* ) a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4707,28 +4955,51 @@ slash_with_default_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } // star_etc: +// | invalid_star_etc // | '*' param_no_default param_maybe_default* kwds? +// | '*' param_no_default_star_annotation param_maybe_default* kwds? // | '*' ',' param_maybe_default+ kwds? // | kwds -// | invalid_star_etc static StarEtc* star_etc_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } StarEtc* _res = NULL; int _mark = p->mark; + if (p->call_invalid_rules) { // invalid_star_etc + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_star_etc")); + void *invalid_star_etc_var; + if ( + (invalid_star_etc_var = invalid_star_etc_rule(p)) // invalid_star_etc + ) + { + D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_star_etc")); + _res = invalid_star_etc_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_star_etc")); + } { // '*' param_no_default param_maybe_default* kwds? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' param_no_default param_maybe_default* kwds?")); @@ -4750,7 +5021,7 @@ star_etc_rule(Parser *p) _res = _PyPegen_star_etc ( p , a , b , c ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4759,9 +5030,42 @@ star_etc_rule(Parser *p) D(fprintf(stderr, "%*c%s star_etc[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' param_no_default param_maybe_default* kwds?")); } + { // '*' param_no_default_star_annotation param_maybe_default* kwds? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' param_no_default_star_annotation param_maybe_default* kwds?")); + Token * _literal; + arg_ty a; + asdl_seq * b; + void *c; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (a = param_no_default_star_annotation_rule(p)) // param_no_default_star_annotation + && + (b = _loop0_49_rule(p)) // param_maybe_default* + && + (c = kwds_rule(p), !p->error_indicator) // kwds? + ) + { + D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' param_no_default_star_annotation param_maybe_default* kwds?")); + _res = _PyPegen_star_etc ( p , a , b , c ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' param_no_default_star_annotation param_maybe_default* kwds?")); + } { // '*' ',' param_maybe_default+ kwds? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' ',' param_maybe_default+ kwds?")); @@ -4774,7 +5078,7 @@ star_etc_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (b = _loop1_49_rule(p)) // param_maybe_default+ + (b = _loop1_50_rule(p)) // param_maybe_default+ && (c = kwds_rule(p), !p->error_indicator) // kwds? ) @@ -4783,7 +5087,7 @@ star_etc_rule(Parser *p) _res = _PyPegen_star_etc ( p , NULL , b , c ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4794,7 +5098,7 @@ star_etc_rule(Parser *p) } { // kwds if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwds")); @@ -4807,7 +5111,7 @@ star_etc_rule(Parser *p) _res = _PyPegen_star_etc ( p , NULL , NULL , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4816,45 +5120,48 @@ star_etc_rule(Parser *p) D(fprintf(stderr, "%*c%s star_etc[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwds")); } - if (p->call_invalid_rules) { // invalid_star_etc - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_star_etc")); - void *invalid_star_etc_var; - if ( - (invalid_star_etc_var = invalid_star_etc_rule(p)) // invalid_star_etc - ) - { - D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_star_etc")); - _res = invalid_star_etc_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_star_etc")); - } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// kwds: '**' param_no_default +// kwds: invalid_kwds | '**' param_no_default static arg_ty kwds_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } arg_ty _res = NULL; int _mark = p->mark; + if (p->call_invalid_rules) { // invalid_kwds + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_kwds")); + void *invalid_kwds_var; + if ( + (invalid_kwds_var = invalid_kwds_rule(p)) // invalid_kwds + ) + { + D(fprintf(stderr, "%*c+ kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_kwds")); + _res = invalid_kwds_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_kwds")); + } { // '**' param_no_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' param_no_default")); @@ -4870,7 +5177,7 @@ kwds_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4881,7 +5188,7 @@ kwds_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -4889,16 +5196,19 @@ kwds_rule(Parser *p) static arg_ty param_no_default_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } arg_ty _res = NULL; int _mark = p->mark; { // param ',' TYPE_COMMENT? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> param_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param ',' TYPE_COMMENT?")); @@ -4917,7 +5227,7 @@ param_no_default_rule(Parser *p) _res = _PyPegen_add_type_comment_to_arg ( p , a , tc ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4928,7 +5238,7 @@ param_no_default_rule(Parser *p) } { // param TYPE_COMMENT? &')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> param_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param TYPE_COMMENT? &')'")); @@ -4946,7 +5256,7 @@ param_no_default_rule(Parser *p) _res = _PyPegen_add_type_comment_to_arg ( p , a , tc ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -4957,7 +5267,88 @@ param_no_default_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; + return _res; +} + +// param_no_default_star_annotation: +// | param_star_annotation ',' TYPE_COMMENT? +// | param_star_annotation TYPE_COMMENT? &')' +static arg_ty +param_no_default_star_annotation_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + arg_ty _res = NULL; + int _mark = p->mark; + { // param_star_annotation ',' TYPE_COMMENT? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> param_no_default_star_annotation[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_star_annotation ',' TYPE_COMMENT?")); + Token * _literal; + arg_ty a; + void *tc; + if ( + (a = param_star_annotation_rule(p)) // param_star_annotation + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? + ) + { + D(fprintf(stderr, "%*c+ param_no_default_star_annotation[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_star_annotation ',' TYPE_COMMENT?")); + _res = _PyPegen_add_type_comment_to_arg ( p , a , tc ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s param_no_default_star_annotation[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_star_annotation ',' TYPE_COMMENT?")); + } + { // param_star_annotation TYPE_COMMENT? &')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> param_no_default_star_annotation[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_star_annotation TYPE_COMMENT? &')'")); + arg_ty a; + void *tc; + if ( + (a = param_star_annotation_rule(p)) // param_star_annotation + && + (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? + && + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 8) // token=')' + ) + { + D(fprintf(stderr, "%*c+ param_no_default_star_annotation[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_star_annotation TYPE_COMMENT? &')'")); + _res = _PyPegen_add_type_comment_to_arg ( p , a , tc ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s param_no_default_star_annotation[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_star_annotation TYPE_COMMENT? &')'")); + } + _res = NULL; + done: + p->level--; return _res; } @@ -4965,16 +5356,19 @@ param_no_default_rule(Parser *p) static NameDefaultPair* param_with_default_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } NameDefaultPair* _res = NULL; int _mark = p->mark; { // param default ',' TYPE_COMMENT? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> param_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param default ',' TYPE_COMMENT?")); @@ -4996,7 +5390,7 @@ param_with_default_rule(Parser *p) _res = _PyPegen_name_default_pair ( p , a , c , tc ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -5007,7 +5401,7 @@ param_with_default_rule(Parser *p) } { // param default TYPE_COMMENT? &')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> param_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param default TYPE_COMMENT? &')'")); @@ -5028,7 +5422,7 @@ param_with_default_rule(Parser *p) _res = _PyPegen_name_default_pair ( p , a , c , tc ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -5039,7 +5433,7 @@ param_with_default_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -5049,16 +5443,19 @@ param_with_default_rule(Parser *p) static NameDefaultPair* param_maybe_default_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } NameDefaultPair* _res = NULL; int _mark = p->mark; { // param default? ',' TYPE_COMMENT? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> param_maybe_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param default? ',' TYPE_COMMENT?")); @@ -5080,7 +5477,7 @@ param_maybe_default_rule(Parser *p) _res = _PyPegen_name_default_pair ( p , a , c , tc ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -5091,7 +5488,7 @@ param_maybe_default_rule(Parser *p) } { // param default? TYPE_COMMENT? &')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> param_maybe_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param default? TYPE_COMMENT? &')'")); @@ -5112,7 +5509,7 @@ param_maybe_default_rule(Parser *p) _res = _PyPegen_name_default_pair ( p , a , c , tc ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -5123,7 +5520,7 @@ param_maybe_default_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -5131,16 +5528,19 @@ param_maybe_default_rule(Parser *p) static arg_ty param_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } arg_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -5149,7 +5549,7 @@ param_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // NAME annotation? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME annotation?")); @@ -5164,7 +5564,7 @@ param_rule(Parser *p) D(fprintf(stderr, "%*c+ param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME annotation?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -5174,7 +5574,7 @@ param_rule(Parser *p) _res = _PyAST_arg ( a -> v . Name . id , b , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -5185,7 +5585,72 @@ param_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; + return _res; +} + +// param_star_annotation: NAME star_annotation +static arg_ty +param_star_annotation_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + arg_ty _res = NULL; + int _mark = p->mark; + if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { + p->error_indicator = 1; + p->level--; + return NULL; + } + int _start_lineno = p->tokens[_mark]->lineno; + UNUSED(_start_lineno); // Only used by EXTRA macro + int _start_col_offset = p->tokens[_mark]->col_offset; + UNUSED(_start_col_offset); // Only used by EXTRA macro + { // NAME star_annotation + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> param_star_annotation[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME star_annotation")); + expr_ty a; + expr_ty b; + if ( + (a = _PyPegen_name_token(p)) // NAME + && + (b = star_annotation_rule(p)) // star_annotation + ) + { + D(fprintf(stderr, "%*c+ param_star_annotation[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME star_annotation")); + Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); + if (_token == NULL) { + p->level--; + return NULL; + } + int _end_lineno = _token->end_lineno; + UNUSED(_end_lineno); // Only used by EXTRA macro + int _end_col_offset = _token->end_col_offset; + UNUSED(_end_col_offset); // Only used by EXTRA macro + _res = _PyAST_arg ( a -> v . Name . id , b , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s param_star_annotation[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME star_annotation")); + } + _res = NULL; + done: + p->level--; return _res; } @@ -5193,16 +5658,19 @@ param_rule(Parser *p) static expr_ty annotation_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; { // ':' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> annotation[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression")); @@ -5218,7 +5686,7 @@ annotation_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -5229,24 +5697,74 @@ annotation_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// default: '=' expression +// star_annotation: ':' star_expression +static expr_ty +star_annotation_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // ':' star_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_annotation[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' star_expression")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (a = star_expression_rule(p)) // star_expression + ) + { + D(fprintf(stderr, "%*c+ star_annotation[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' star_expression")); + _res = a; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_annotation[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':' star_expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// default: '=' expression | invalid_default static expr_ty default_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; { // '=' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' expression")); @@ -5262,7 +5780,7 @@ default_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -5271,9 +5789,28 @@ default_rule(Parser *p) D(fprintf(stderr, "%*c%s default[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'=' expression")); } + if (p->call_invalid_rules) { // invalid_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_default")); + void *invalid_default_var; + if ( + (invalid_default_var = invalid_default_rule(p)) // invalid_default + ) + { + D(fprintf(stderr, "%*c+ default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_default")); + _res = invalid_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_default")); + } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -5284,16 +5821,19 @@ default_rule(Parser *p) static stmt_ty if_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -5302,7 +5842,7 @@ if_stmt_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro if (p->call_invalid_rules) { // invalid_if_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> if_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_if_stmt")); @@ -5321,7 +5861,7 @@ if_stmt_rule(Parser *p) } { // 'if' named_expression ':' block elif_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> if_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' block elif_stmt")); @@ -5331,7 +5871,7 @@ if_stmt_rule(Parser *p) asdl_stmt_seq* b; stmt_ty c; if ( - (_keyword = _PyPegen_expect_token(p, 627)) // token='if' + (_keyword = _PyPegen_expect_token(p, 641)) // token='if' && (a = named_expression_rule(p)) // named_expression && @@ -5345,7 +5885,7 @@ if_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ if_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' block elif_stmt")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -5355,7 +5895,7 @@ if_stmt_rule(Parser *p) _res = _PyAST_If ( a , b , CHECK ( asdl_stmt_seq* , _PyPegen_singleton_seq ( p , c ) ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -5366,7 +5906,7 @@ if_stmt_rule(Parser *p) } { // 'if' named_expression ':' block else_block? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> if_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' block else_block?")); @@ -5376,7 +5916,7 @@ if_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 627)) // token='if' + (_keyword = _PyPegen_expect_token(p, 641)) // token='if' && (a = named_expression_rule(p)) // named_expression && @@ -5390,7 +5930,7 @@ if_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ if_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' block else_block?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -5400,7 +5940,7 @@ if_stmt_rule(Parser *p) _res = _PyAST_If ( a , b , c , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -5411,7 +5951,7 @@ if_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -5422,16 +5962,19 @@ if_stmt_rule(Parser *p) static stmt_ty elif_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -5440,7 +5983,7 @@ elif_stmt_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro if (p->call_invalid_rules) { // invalid_elif_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> elif_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_elif_stmt")); @@ -5459,7 +6002,7 @@ elif_stmt_rule(Parser *p) } { // 'elif' named_expression ':' block elif_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> elif_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' block elif_stmt")); @@ -5469,7 +6012,7 @@ elif_stmt_rule(Parser *p) asdl_stmt_seq* b; stmt_ty c; if ( - (_keyword = _PyPegen_expect_token(p, 629)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 643)) // token='elif' && (a = named_expression_rule(p)) // named_expression && @@ -5483,7 +6026,7 @@ elif_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ elif_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' block elif_stmt")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -5493,7 +6036,7 @@ elif_stmt_rule(Parser *p) _res = _PyAST_If ( a , b , CHECK ( asdl_stmt_seq* , _PyPegen_singleton_seq ( p , c ) ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -5504,7 +6047,7 @@ elif_stmt_rule(Parser *p) } { // 'elif' named_expression ':' block else_block? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> elif_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' block else_block?")); @@ -5514,7 +6057,7 @@ elif_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 629)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 643)) // token='elif' && (a = named_expression_rule(p)) // named_expression && @@ -5528,7 +6071,7 @@ elif_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ elif_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' block else_block?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -5538,7 +6081,7 @@ elif_stmt_rule(Parser *p) _res = _PyAST_If ( a , b , c , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -5549,7 +6092,7 @@ elif_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -5557,16 +6100,19 @@ elif_stmt_rule(Parser *p) static asdl_stmt_seq* else_block_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_stmt_seq* _res = NULL; int _mark = p->mark; if (p->call_invalid_rules) { // invalid_else_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> else_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_else_stmt")); @@ -5585,7 +6131,7 @@ else_block_rule(Parser *p) } { // 'else' &&':' block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> else_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else' &&':' block")); @@ -5593,7 +6139,7 @@ else_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 630)) // token='else' + (_keyword = _PyPegen_expect_token(p, 644)) // token='else' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -5604,7 +6150,7 @@ else_block_rule(Parser *p) _res = b; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -5615,7 +6161,7 @@ else_block_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -5623,16 +6169,19 @@ else_block_rule(Parser *p) static stmt_ty while_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -5641,7 +6190,7 @@ while_stmt_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro if (p->call_invalid_rules) { // invalid_while_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> while_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_while_stmt")); @@ -5660,7 +6209,7 @@ while_stmt_rule(Parser *p) } { // 'while' named_expression ':' block else_block? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> while_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'while' named_expression ':' block else_block?")); @@ -5670,7 +6219,7 @@ while_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 632)) // token='while' + (_keyword = _PyPegen_expect_token(p, 646)) // token='while' && (a = named_expression_rule(p)) // named_expression && @@ -5684,7 +6233,7 @@ while_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ while_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'while' named_expression ':' block else_block?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -5694,7 +6243,7 @@ while_stmt_rule(Parser *p) _res = _PyAST_While ( a , b , c , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -5705,28 +6254,31 @@ while_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } // for_stmt: // | invalid_for_stmt -// | 'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block? -// | ASYNC 'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block? +// | 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block? +// | ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block? // | invalid_for_target static stmt_ty for_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -5735,7 +6287,7 @@ for_stmt_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro if (p->call_invalid_rules) { // invalid_for_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_for_stmt")); @@ -5752,12 +6304,12 @@ for_stmt_rule(Parser *p) D(fprintf(stderr, "%*c%s for_stmt[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_for_stmt")); } - { // 'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block? + { // 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block?")); + D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); int _cut_var = 0; Token * _keyword; Token * _keyword_1; @@ -5768,17 +6320,17 @@ for_stmt_rule(Parser *p) expr_ty t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 633)) // token='for' + (_keyword = _PyPegen_expect_token(p, 649)) // token='for' && (t = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 634)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 650)) // token='in' && (_cut_var = 1) && (ex = star_expressions_rule(p)) // star_expressions && - (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' + (_literal = _PyPegen_expect_token(p, 11)) // token=':' && (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? && @@ -5787,10 +6339,10 @@ for_stmt_rule(Parser *p) (el = else_block_rule(p), !p->error_indicator) // else_block? ) { - D(fprintf(stderr, "%*c+ for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block?")); + D(fprintf(stderr, "%*c+ for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -5800,25 +6352,25 @@ for_stmt_rule(Parser *p) _res = _PyAST_For ( t , ex , b , el , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s for_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block?")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); if (_cut_var) { - D(p->level--); + p->level--; return NULL; } } - { // ASYNC 'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block? + { // ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block?")); + D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); int _cut_var = 0; Token * _keyword; Token * _keyword_1; @@ -5832,17 +6384,17 @@ for_stmt_rule(Parser *p) if ( (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' && - (_keyword = _PyPegen_expect_token(p, 633)) // token='for' + (_keyword = _PyPegen_expect_token(p, 649)) // token='for' && (t = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 634)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 650)) // token='in' && (_cut_var = 1) && (ex = star_expressions_rule(p)) // star_expressions && - (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' + (_literal = _PyPegen_expect_token(p, 11)) // token=':' && (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? && @@ -5851,10 +6403,10 @@ for_stmt_rule(Parser *p) (el = else_block_rule(p), !p->error_indicator) // else_block? ) { - D(fprintf(stderr, "%*c+ for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block?")); + D(fprintf(stderr, "%*c+ for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -5864,22 +6416,22 @@ for_stmt_rule(Parser *p) _res = CHECK_VERSION ( stmt_ty , 5 , "Async for loops are" , _PyAST_AsyncFor ( t , ex , b , el , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s for_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions &&':' TYPE_COMMENT? block else_block?")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ star_expressions ':' TYPE_COMMENT? block else_block?")); if (_cut_var) { - D(p->level--); + p->level--; return NULL; } } if (p->call_invalid_rules) { // invalid_for_target if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_for_target")); @@ -5898,7 +6450,7 @@ for_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -5912,16 +6464,19 @@ for_stmt_rule(Parser *p) static stmt_ty with_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -5930,7 +6485,7 @@ with_stmt_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro if (p->call_invalid_rules) { // invalid_with_stmt_indent if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_with_stmt_indent")); @@ -5949,7 +6504,7 @@ with_stmt_rule(Parser *p) } { // 'with' '(' ','.with_item+ ','? ')' ':' block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' block")); @@ -5962,11 +6517,11 @@ with_stmt_rule(Parser *p) asdl_withitem_seq* a; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 609)) // token='with' + (_keyword = _PyPegen_expect_token(p, 614)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = (asdl_withitem_seq*)_gather_50_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_51_rule(p)) // ','.with_item+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -5980,17 +6535,17 @@ with_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; UNUSED(_end_lineno); // Only used by EXTRA macro int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro - _res = _PyAST_With ( a , b , NULL , EXTRA ); + _res = CHECK_VERSION ( stmt_ty , 9 , "Parenthesized context managers are" , _PyAST_With ( a , b , NULL , EXTRA ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -6001,7 +6556,7 @@ with_stmt_rule(Parser *p) } { // 'with' ','.with_item+ ':' TYPE_COMMENT? block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with' ','.with_item+ ':' TYPE_COMMENT? block")); @@ -6011,9 +6566,9 @@ with_stmt_rule(Parser *p) asdl_stmt_seq* b; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 609)) // token='with' + (_keyword = _PyPegen_expect_token(p, 614)) // token='with' && - (a = (asdl_withitem_seq*)_gather_52_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_53_rule(p)) // ','.with_item+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -6025,7 +6580,7 @@ with_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with' ','.with_item+ ':' TYPE_COMMENT? block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -6035,7 +6590,7 @@ with_stmt_rule(Parser *p) _res = _PyAST_With ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -6046,7 +6601,7 @@ with_stmt_rule(Parser *p) } { // ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block")); @@ -6062,11 +6617,11 @@ with_stmt_rule(Parser *p) if ( (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' && - (_keyword = _PyPegen_expect_token(p, 609)) // token='with' + (_keyword = _PyPegen_expect_token(p, 614)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = (asdl_withitem_seq*)_gather_54_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_55_rule(p)) // ','.with_item+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -6080,7 +6635,7 @@ with_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -6090,7 +6645,7 @@ with_stmt_rule(Parser *p) _res = CHECK_VERSION ( stmt_ty , 5 , "Async with statements are" , _PyAST_AsyncWith ( a , b , NULL , EXTRA ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -6101,7 +6656,7 @@ with_stmt_rule(Parser *p) } { // ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block")); @@ -6114,9 +6669,9 @@ with_stmt_rule(Parser *p) if ( (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' && - (_keyword = _PyPegen_expect_token(p, 609)) // token='with' + (_keyword = _PyPegen_expect_token(p, 614)) // token='with' && - (a = (asdl_withitem_seq*)_gather_56_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_57_rule(p)) // ','.with_item+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -6128,7 +6683,7 @@ with_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'with' ','.with_item+ ':' TYPE_COMMENT? block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -6138,7 +6693,7 @@ with_stmt_rule(Parser *p) _res = CHECK_VERSION ( stmt_ty , 5 , "Async with statements are" , _PyAST_AsyncWith ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -6149,7 +6704,7 @@ with_stmt_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_with_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_with_stmt")); @@ -6168,7 +6723,7 @@ with_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -6179,16 +6734,19 @@ with_stmt_rule(Parser *p) static withitem_ty with_item_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } withitem_ty _res = NULL; int _mark = p->mark; { // expression 'as' star_target &(',' | ')' | ':') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression 'as' star_target &(',' | ')' | ':')")); @@ -6198,18 +6756,18 @@ with_item_rule(Parser *p) if ( (e = expression_rule(p)) // expression && - (_keyword = _PyPegen_expect_token(p, 625)) // token='as' + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' && (t = star_target_rule(p)) // star_target && - _PyPegen_lookahead(1, _tmp_58_rule, p) + _PyPegen_lookahead(1, _tmp_59_rule, p) ) { D(fprintf(stderr, "%*c+ with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' star_target &(',' | ')' | ':')")); _res = _PyAST_withitem ( e , t , p -> arena ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -6220,7 +6778,7 @@ with_item_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_with_item if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_with_item")); @@ -6239,7 +6797,7 @@ with_item_rule(Parser *p) } { // expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression")); @@ -6252,7 +6810,7 @@ with_item_rule(Parser *p) _res = _PyAST_withitem ( e , NULL , p -> arena ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -6263,7 +6821,7 @@ with_item_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -6271,19 +6829,23 @@ with_item_rule(Parser *p) // | invalid_try_stmt // | 'try' &&':' block finally_block // | 'try' &&':' block except_block+ else_block? finally_block? +// | 'try' &&':' block except_star_block+ else_block? finally_block? static stmt_ty try_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -6292,7 +6854,7 @@ try_stmt_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro if (p->call_invalid_rules) { // invalid_try_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_try_stmt")); @@ -6311,7 +6873,7 @@ try_stmt_rule(Parser *p) } { // 'try' &&':' block finally_block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' &&':' block finally_block")); @@ -6320,7 +6882,7 @@ try_stmt_rule(Parser *p) asdl_stmt_seq* b; asdl_stmt_seq* f; if ( - (_keyword = _PyPegen_expect_token(p, 612)) // token='try' + (_keyword = _PyPegen_expect_token(p, 623)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -6332,7 +6894,7 @@ try_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' &&':' block finally_block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -6342,7 +6904,7 @@ try_stmt_rule(Parser *p) _res = _PyAST_Try ( b , NULL , NULL , f , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -6353,7 +6915,7 @@ try_stmt_rule(Parser *p) } { // 'try' &&':' block except_block+ else_block? finally_block? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' &&':' block except_block+ else_block? finally_block?")); @@ -6364,13 +6926,13 @@ try_stmt_rule(Parser *p) asdl_excepthandler_seq* ex; void *f; if ( - (_keyword = _PyPegen_expect_token(p, 612)) // token='try' + (_keyword = _PyPegen_expect_token(p, 623)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && (b = block_rule(p)) // block && - (ex = (asdl_excepthandler_seq*)_loop1_59_rule(p)) // except_block+ + (ex = (asdl_excepthandler_seq*)_loop1_60_rule(p)) // except_block+ && (el = else_block_rule(p), !p->error_indicator) // else_block? && @@ -6380,7 +6942,7 @@ try_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' &&':' block except_block+ else_block? finally_block?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -6390,7 +6952,7 @@ try_stmt_rule(Parser *p) _res = _PyAST_Try ( b , ex , el , f , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -6399,9 +6961,57 @@ try_stmt_rule(Parser *p) D(fprintf(stderr, "%*c%s try_stmt[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'try' &&':' block except_block+ else_block? finally_block?")); } + { // 'try' &&':' block except_star_block+ else_block? finally_block? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' &&':' block except_star_block+ else_block? finally_block?")); + Token * _keyword; + Token * _literal; + asdl_stmt_seq* b; + void *el; + asdl_excepthandler_seq* ex; + void *f; + if ( + (_keyword = _PyPegen_expect_token(p, 623)) // token='try' + && + (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' + && + (b = block_rule(p)) // block + && + (ex = (asdl_excepthandler_seq*)_loop1_61_rule(p)) // except_star_block+ + && + (el = else_block_rule(p), !p->error_indicator) // else_block? + && + (f = finally_block_rule(p), !p->error_indicator) // finally_block? + ) + { + D(fprintf(stderr, "%*c+ try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' &&':' block except_star_block+ else_block? finally_block?")); + Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); + if (_token == NULL) { + p->level--; + return NULL; + } + int _end_lineno = _token->end_lineno; + UNUSED(_end_lineno); // Only used by EXTRA macro + int _end_col_offset = _token->end_col_offset; + UNUSED(_end_col_offset); // Only used by EXTRA macro + _res = CHECK_VERSION ( stmt_ty , 11 , "Exception groups are" , _PyAST_TryStar ( b , ex , el , f , EXTRA ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s try_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'try' &&':' block except_star_block+ else_block? finally_block?")); + } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -6413,16 +7023,19 @@ try_stmt_rule(Parser *p) static excepthandler_ty except_block_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } excepthandler_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -6431,7 +7044,7 @@ except_block_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro if (p->call_invalid_rules) { // invalid_except_stmt_indent if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> except_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_except_stmt_indent")); @@ -6450,7 +7063,7 @@ except_block_rule(Parser *p) } { // 'except' expression ['as' NAME] ':' block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> except_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] ':' block")); @@ -6460,11 +7073,11 @@ except_block_rule(Parser *p) expr_ty e; void *t; if ( - (_keyword = _PyPegen_expect_token(p, 623)) // token='except' + (_keyword = _PyPegen_expect_token(p, 636)) // token='except' && (e = expression_rule(p)) // expression && - (t = _tmp_60_rule(p), !p->error_indicator) // ['as' NAME] + (t = _tmp_62_rule(p), !p->error_indicator) // ['as' NAME] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -6474,7 +7087,7 @@ except_block_rule(Parser *p) D(fprintf(stderr, "%*c+ except_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] ':' block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -6484,7 +7097,7 @@ except_block_rule(Parser *p) _res = _PyAST_ExceptHandler ( e , ( t ) ? ( ( expr_ty ) t ) -> v . Name . id : NULL , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -6495,7 +7108,7 @@ except_block_rule(Parser *p) } { // 'except' ':' block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> except_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' ':' block")); @@ -6503,7 +7116,7 @@ except_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 623)) // token='except' + (_keyword = _PyPegen_expect_token(p, 636)) // token='except' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -6513,7 +7126,7 @@ except_block_rule(Parser *p) D(fprintf(stderr, "%*c+ except_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' ':' block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -6523,7 +7136,7 @@ except_block_rule(Parser *p) _res = _PyAST_ExceptHandler ( NULL , NULL , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -6534,7 +7147,7 @@ except_block_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_except_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> except_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_except_stmt")); @@ -6553,7 +7166,125 @@ except_block_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; + return _res; +} + +// except_star_block: +// | invalid_except_star_stmt_indent +// | 'except' '*' expression ['as' NAME] ':' block +// | invalid_except_stmt +static excepthandler_ty +except_star_block_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + excepthandler_ty _res = NULL; + int _mark = p->mark; + if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { + p->error_indicator = 1; + p->level--; + return NULL; + } + int _start_lineno = p->tokens[_mark]->lineno; + UNUSED(_start_lineno); // Only used by EXTRA macro + int _start_col_offset = p->tokens[_mark]->col_offset; + UNUSED(_start_col_offset); // Only used by EXTRA macro + if (p->call_invalid_rules) { // invalid_except_star_stmt_indent + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> except_star_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_except_star_stmt_indent")); + void *invalid_except_star_stmt_indent_var; + if ( + (invalid_except_star_stmt_indent_var = invalid_except_star_stmt_indent_rule(p)) // invalid_except_star_stmt_indent + ) + { + D(fprintf(stderr, "%*c+ except_star_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_except_star_stmt_indent")); + _res = invalid_except_star_stmt_indent_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s except_star_block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_except_star_stmt_indent")); + } + { // 'except' '*' expression ['as' NAME] ':' block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> except_star_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' '*' expression ['as' NAME] ':' block")); + Token * _keyword; + Token * _literal; + Token * _literal_1; + asdl_stmt_seq* b; + expr_ty e; + void *t; + if ( + (_keyword = _PyPegen_expect_token(p, 636)) // token='except' + && + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (e = expression_rule(p)) // expression + && + (t = _tmp_63_rule(p), !p->error_indicator) // ['as' NAME] + && + (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' + && + (b = block_rule(p)) // block + ) + { + D(fprintf(stderr, "%*c+ except_star_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*' expression ['as' NAME] ':' block")); + Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); + if (_token == NULL) { + p->level--; + return NULL; + } + int _end_lineno = _token->end_lineno; + UNUSED(_end_lineno); // Only used by EXTRA macro + int _end_col_offset = _token->end_col_offset; + UNUSED(_end_col_offset); // Only used by EXTRA macro + _res = _PyAST_ExceptHandler ( e , ( t ) ? ( ( expr_ty ) t ) -> v . Name . id : NULL , b , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s except_star_block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' '*' expression ['as' NAME] ':' block")); + } + if (p->call_invalid_rules) { // invalid_except_stmt + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> except_star_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_except_stmt")); + void *invalid_except_stmt_var; + if ( + (invalid_except_stmt_var = invalid_except_stmt_rule(p)) // invalid_except_stmt + ) + { + D(fprintf(stderr, "%*c+ except_star_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_except_stmt")); + _res = invalid_except_stmt_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s except_star_block[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_except_stmt")); + } + _res = NULL; + done: + p->level--; return _res; } @@ -6561,16 +7292,19 @@ except_block_rule(Parser *p) static asdl_stmt_seq* finally_block_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_stmt_seq* _res = NULL; int _mark = p->mark; if (p->call_invalid_rules) { // invalid_finally_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> finally_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_finally_stmt")); @@ -6589,7 +7323,7 @@ finally_block_rule(Parser *p) } { // 'finally' &&':' block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> finally_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally' &&':' block")); @@ -6597,7 +7331,7 @@ finally_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* a; if ( - (_keyword = _PyPegen_expect_token(p, 620)) // token='finally' + (_keyword = _PyPegen_expect_token(p, 632)) // token='finally' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -6608,7 +7342,7 @@ finally_block_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -6619,7 +7353,7 @@ finally_block_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -6629,16 +7363,19 @@ finally_block_rule(Parser *p) static stmt_ty match_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } stmt_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -6647,7 +7384,7 @@ match_stmt_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // "match" subject_expr ':' NEWLINE INDENT case_block+ DEDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> match_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"match\" subject_expr ':' NEWLINE INDENT case_block+ DEDENT")); @@ -6669,7 +7406,7 @@ match_stmt_rule(Parser *p) && (indent_var = _PyPegen_expect_token(p, INDENT)) // token='INDENT' && - (cases = (asdl_match_case_seq*)_loop1_61_rule(p)) // case_block+ + (cases = (asdl_match_case_seq*)_loop1_64_rule(p)) // case_block+ && (dedent_var = _PyPegen_expect_token(p, DEDENT)) // token='DEDENT' ) @@ -6677,7 +7414,7 @@ match_stmt_rule(Parser *p) D(fprintf(stderr, "%*c+ match_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"match\" subject_expr ':' NEWLINE INDENT case_block+ DEDENT")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -6687,7 +7424,7 @@ match_stmt_rule(Parser *p) _res = CHECK_VERSION ( stmt_ty , 10 , "Pattern matching is" , _PyAST_Match ( subject , cases , EXTRA ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -6698,7 +7435,7 @@ match_stmt_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_match_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> match_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_match_stmt")); @@ -6717,7 +7454,7 @@ match_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -6725,16 +7462,19 @@ match_stmt_rule(Parser *p) static expr_ty subject_expr_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -6743,7 +7483,7 @@ subject_expr_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // star_named_expression ',' star_named_expressions? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> subject_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); @@ -6761,7 +7501,7 @@ subject_expr_rule(Parser *p) D(fprintf(stderr, "%*c+ subject_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -6771,7 +7511,7 @@ subject_expr_rule(Parser *p) _res = _PyAST_Tuple ( CHECK ( asdl_expr_seq* , _PyPegen_seq_insert_in_front ( p , value , values ) ) , Load , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -6782,7 +7522,7 @@ subject_expr_rule(Parser *p) } { // named_expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> subject_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression")); @@ -6801,7 +7541,7 @@ subject_expr_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -6809,16 +7549,19 @@ subject_expr_rule(Parser *p) static match_case_ty case_block_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } match_case_ty _res = NULL; int _mark = p->mark; if (p->call_invalid_rules) { // invalid_case_block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> case_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_case_block")); @@ -6837,7 +7580,7 @@ case_block_rule(Parser *p) } { // "case" patterns guard? ':' block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> case_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? ':' block")); @@ -6862,7 +7605,7 @@ case_block_rule(Parser *p) _res = _PyAST_match_case ( pattern , guard , body , p -> arena ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -6873,7 +7616,7 @@ case_block_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -6881,23 +7624,26 @@ case_block_rule(Parser *p) static expr_ty guard_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; { // 'if' named_expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> guard[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' named_expression")); Token * _keyword; expr_ty guard; if ( - (_keyword = _PyPegen_expect_token(p, 627)) // token='if' + (_keyword = _PyPegen_expect_token(p, 641)) // token='if' && (guard = named_expression_rule(p)) // named_expression ) @@ -6906,7 +7652,7 @@ guard_rule(Parser *p) _res = guard; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -6917,7 +7663,7 @@ guard_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -6925,16 +7671,19 @@ guard_rule(Parser *p) static pattern_ty patterns_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } pattern_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -6943,7 +7692,7 @@ patterns_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // open_sequence_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> patterns[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "open_sequence_pattern")); @@ -6955,7 +7704,7 @@ patterns_rule(Parser *p) D(fprintf(stderr, "%*c+ patterns[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "open_sequence_pattern")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -6965,7 +7714,7 @@ patterns_rule(Parser *p) _res = _PyAST_MatchSequence ( patterns , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -6976,7 +7725,7 @@ patterns_rule(Parser *p) } { // pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> patterns[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern")); @@ -6995,7 +7744,7 @@ patterns_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -7003,16 +7752,19 @@ patterns_rule(Parser *p) static pattern_ty pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } pattern_ty _res = NULL; int _mark = p->mark; { // as_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "as_pattern")); @@ -7031,7 +7783,7 @@ pattern_rule(Parser *p) } { // or_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "or_pattern")); @@ -7050,7 +7802,7 @@ pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -7058,16 +7810,19 @@ pattern_rule(Parser *p) static pattern_ty as_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } pattern_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -7076,7 +7831,7 @@ as_pattern_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // or_pattern 'as' pattern_capture_target if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> as_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "or_pattern 'as' pattern_capture_target")); @@ -7086,7 +7841,7 @@ as_pattern_rule(Parser *p) if ( (pattern = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 625)) // token='as' + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' && (target = pattern_capture_target_rule(p)) // pattern_capture_target ) @@ -7094,7 +7849,7 @@ as_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ as_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "or_pattern 'as' pattern_capture_target")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -7104,7 +7859,7 @@ as_pattern_rule(Parser *p) _res = _PyAST_MatchAs ( pattern , target -> v . Name . id , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -7115,7 +7870,7 @@ as_pattern_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_as_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> as_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_as_pattern")); @@ -7134,7 +7889,7 @@ as_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -7142,16 +7897,19 @@ as_pattern_rule(Parser *p) static pattern_ty or_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } pattern_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -7160,19 +7918,19 @@ or_pattern_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '|'.closed_pattern+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> or_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|'.closed_pattern+")); asdl_pattern_seq* patterns; if ( - (patterns = (asdl_pattern_seq*)_gather_62_rule(p)) // '|'.closed_pattern+ + (patterns = (asdl_pattern_seq*)_gather_65_rule(p)) // '|'.closed_pattern+ ) { D(fprintf(stderr, "%*c+ or_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'|'.closed_pattern+")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -7182,7 +7940,7 @@ or_pattern_rule(Parser *p) _res = asdl_seq_LEN ( patterns ) == 1 ? asdl_seq_GET ( patterns , 0 ) : _PyAST_MatchOr ( patterns , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -7193,7 +7951,7 @@ or_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -7209,16 +7967,23 @@ or_pattern_rule(Parser *p) static pattern_ty closed_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } pattern_ty _res = NULL; + if (_PyPegen_is_memoized(p, closed_pattern_type, &_res)) { + p->level--; + return _res; + } int _mark = p->mark; { // literal_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> closed_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "literal_pattern")); @@ -7237,7 +8002,7 @@ closed_pattern_rule(Parser *p) } { // capture_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> closed_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "capture_pattern")); @@ -7256,7 +8021,7 @@ closed_pattern_rule(Parser *p) } { // wildcard_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> closed_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "wildcard_pattern")); @@ -7275,7 +8040,7 @@ closed_pattern_rule(Parser *p) } { // value_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> closed_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "value_pattern")); @@ -7294,7 +8059,7 @@ closed_pattern_rule(Parser *p) } { // group_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> closed_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "group_pattern")); @@ -7313,7 +8078,7 @@ closed_pattern_rule(Parser *p) } { // sequence_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> closed_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "sequence_pattern")); @@ -7332,7 +8097,7 @@ closed_pattern_rule(Parser *p) } { // mapping_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> closed_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "mapping_pattern")); @@ -7351,7 +8116,7 @@ closed_pattern_rule(Parser *p) } { // class_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> closed_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "class_pattern")); @@ -7370,7 +8135,8 @@ closed_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + _PyPegen_insert_memo(p, _mark, closed_pattern_type, _res); + p->level--; return _res; } @@ -7384,16 +8150,19 @@ closed_pattern_rule(Parser *p) static pattern_ty literal_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } pattern_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -7402,7 +8171,7 @@ literal_pattern_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // signed_number !('+' | '-') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "signed_number !('+' | '-')")); @@ -7410,13 +8179,13 @@ literal_pattern_rule(Parser *p) if ( (value = signed_number_rule(p)) // signed_number && - _PyPegen_lookahead(0, _tmp_64_rule, p) + _PyPegen_lookahead(0, _tmp_67_rule, p) ) { D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "signed_number !('+' | '-')")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -7426,7 +8195,7 @@ literal_pattern_rule(Parser *p) _res = _PyAST_MatchValue ( value , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -7437,7 +8206,7 @@ literal_pattern_rule(Parser *p) } { // complex_number if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "complex_number")); @@ -7449,7 +8218,7 @@ literal_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "complex_number")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -7459,7 +8228,7 @@ literal_pattern_rule(Parser *p) _res = _PyAST_MatchValue ( value , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -7470,7 +8239,7 @@ literal_pattern_rule(Parser *p) } { // strings if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "strings")); @@ -7482,7 +8251,7 @@ literal_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "strings")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -7492,7 +8261,7 @@ literal_pattern_rule(Parser *p) _res = _PyAST_MatchValue ( value , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -7503,19 +8272,19 @@ literal_pattern_rule(Parser *p) } { // 'None' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 598)) // token='None' + (_keyword = _PyPegen_expect_token(p, 601)) // token='None' ) { D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -7525,7 +8294,7 @@ literal_pattern_rule(Parser *p) _res = _PyAST_MatchSingleton ( Py_None , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -7536,19 +8305,19 @@ literal_pattern_rule(Parser *p) } { // 'True' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 597)) // token='True' + (_keyword = _PyPegen_expect_token(p, 600)) // token='True' ) { D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -7558,7 +8327,7 @@ literal_pattern_rule(Parser *p) _res = _PyAST_MatchSingleton ( Py_True , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -7569,19 +8338,19 @@ literal_pattern_rule(Parser *p) } { // 'False' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 599)) // token='False' + (_keyword = _PyPegen_expect_token(p, 602)) // token='False' ) { D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -7591,7 +8360,7 @@ literal_pattern_rule(Parser *p) _res = _PyAST_MatchSingleton ( Py_False , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -7602,7 +8371,7 @@ literal_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -7616,16 +8385,19 @@ literal_pattern_rule(Parser *p) static expr_ty literal_expr_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -7634,7 +8406,7 @@ literal_expr_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // signed_number !('+' | '-') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "signed_number !('+' | '-')")); @@ -7642,7 +8414,7 @@ literal_expr_rule(Parser *p) if ( (signed_number_var = signed_number_rule(p)) // signed_number && - _PyPegen_lookahead(0, _tmp_65_rule, p) + _PyPegen_lookahead(0, _tmp_68_rule, p) ) { D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "signed_number !('+' | '-')")); @@ -7655,7 +8427,7 @@ literal_expr_rule(Parser *p) } { // complex_number if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "complex_number")); @@ -7674,7 +8446,7 @@ literal_expr_rule(Parser *p) } { // strings if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "strings")); @@ -7693,19 +8465,19 @@ literal_expr_rule(Parser *p) } { // 'None' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 598)) // token='None' + (_keyword = _PyPegen_expect_token(p, 601)) // token='None' ) { D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -7715,7 +8487,7 @@ literal_expr_rule(Parser *p) _res = _PyAST_Constant ( Py_None , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -7726,19 +8498,19 @@ literal_expr_rule(Parser *p) } { // 'True' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 597)) // token='True' + (_keyword = _PyPegen_expect_token(p, 600)) // token='True' ) { D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -7748,7 +8520,7 @@ literal_expr_rule(Parser *p) _res = _PyAST_Constant ( Py_True , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -7759,19 +8531,19 @@ literal_expr_rule(Parser *p) } { // 'False' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 599)) // token='False' + (_keyword = _PyPegen_expect_token(p, 602)) // token='False' ) { D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -7781,7 +8553,7 @@ literal_expr_rule(Parser *p) _res = _PyAST_Constant ( Py_False , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -7792,7 +8564,7 @@ literal_expr_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -7802,16 +8574,19 @@ literal_expr_rule(Parser *p) static expr_ty complex_number_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -7820,7 +8595,7 @@ complex_number_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // signed_real_number '+' imaginary_number if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> complex_number[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "signed_real_number '+' imaginary_number")); @@ -7838,7 +8613,7 @@ complex_number_rule(Parser *p) D(fprintf(stderr, "%*c+ complex_number[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "signed_real_number '+' imaginary_number")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -7848,7 +8623,7 @@ complex_number_rule(Parser *p) _res = _PyAST_BinOp ( real , Add , imag , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -7859,7 +8634,7 @@ complex_number_rule(Parser *p) } { // signed_real_number '-' imaginary_number if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> complex_number[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "signed_real_number '-' imaginary_number")); @@ -7877,7 +8652,7 @@ complex_number_rule(Parser *p) D(fprintf(stderr, "%*c+ complex_number[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "signed_real_number '-' imaginary_number")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -7887,7 +8662,7 @@ complex_number_rule(Parser *p) _res = _PyAST_BinOp ( real , Sub , imag , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -7898,7 +8673,7 @@ complex_number_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -7906,16 +8681,19 @@ complex_number_rule(Parser *p) static expr_ty signed_number_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -7924,7 +8702,7 @@ signed_number_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // NUMBER if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> signed_number[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NUMBER")); @@ -7943,7 +8721,7 @@ signed_number_rule(Parser *p) } { // '-' NUMBER if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> signed_number[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-' NUMBER")); @@ -7958,7 +8736,7 @@ signed_number_rule(Parser *p) D(fprintf(stderr, "%*c+ signed_number[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-' NUMBER")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -7968,7 +8746,7 @@ signed_number_rule(Parser *p) _res = _PyAST_UnaryOp ( USub , number , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -7979,7 +8757,7 @@ signed_number_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -7987,16 +8765,19 @@ signed_number_rule(Parser *p) static expr_ty signed_real_number_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -8005,7 +8786,7 @@ signed_real_number_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // real_number if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> signed_real_number[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "real_number")); @@ -8024,7 +8805,7 @@ signed_real_number_rule(Parser *p) } { // '-' real_number if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> signed_real_number[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-' real_number")); @@ -8039,7 +8820,7 @@ signed_real_number_rule(Parser *p) D(fprintf(stderr, "%*c+ signed_real_number[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-' real_number")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -8049,7 +8830,7 @@ signed_real_number_rule(Parser *p) _res = _PyAST_UnaryOp ( USub , real , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -8060,7 +8841,7 @@ signed_real_number_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -8068,16 +8849,19 @@ signed_real_number_rule(Parser *p) static expr_ty real_number_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; { // NUMBER if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> real_number[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NUMBER")); @@ -8090,7 +8874,7 @@ real_number_rule(Parser *p) _res = _PyPegen_ensure_real ( p , real ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -8101,7 +8885,7 @@ real_number_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -8109,16 +8893,19 @@ real_number_rule(Parser *p) static expr_ty imaginary_number_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; { // NUMBER if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> imaginary_number[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NUMBER")); @@ -8131,7 +8918,7 @@ imaginary_number_rule(Parser *p) _res = _PyPegen_ensure_imaginary ( p , imag ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -8142,7 +8929,7 @@ imaginary_number_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -8150,16 +8937,19 @@ imaginary_number_rule(Parser *p) static pattern_ty capture_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } pattern_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -8168,7 +8958,7 @@ capture_pattern_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // pattern_capture_target if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> capture_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern_capture_target")); @@ -8180,7 +8970,7 @@ capture_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ capture_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "pattern_capture_target")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -8190,7 +8980,7 @@ capture_pattern_rule(Parser *p) _res = _PyAST_MatchAs ( NULL , target -> v . Name . id , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -8201,7 +8991,7 @@ capture_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -8209,16 +8999,19 @@ capture_pattern_rule(Parser *p) static expr_ty pattern_capture_target_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; { // !"_" NAME !('.' | '(' | '=') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> pattern_capture_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!\"_\" NAME !('.' | '(' | '=')")); @@ -8228,14 +9021,14 @@ pattern_capture_target_rule(Parser *p) && (name = _PyPegen_name_token(p)) // NAME && - _PyPegen_lookahead(0, _tmp_66_rule, p) + _PyPegen_lookahead(0, _tmp_69_rule, p) ) { D(fprintf(stderr, "%*c+ pattern_capture_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!\"_\" NAME !('.' | '(' | '=')")); _res = _PyPegen_set_expr_context ( p , name , Store ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -8246,7 +9039,7 @@ pattern_capture_target_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -8254,16 +9047,19 @@ pattern_capture_target_rule(Parser *p) static pattern_ty wildcard_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } pattern_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -8272,7 +9068,7 @@ wildcard_pattern_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // "_" if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> wildcard_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"_\"")); @@ -8284,7 +9080,7 @@ wildcard_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ wildcard_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"_\"")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -8294,7 +9090,7 @@ wildcard_pattern_rule(Parser *p) _res = _PyAST_MatchAs ( NULL , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -8305,7 +9101,7 @@ wildcard_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -8313,16 +9109,19 @@ wildcard_pattern_rule(Parser *p) static pattern_ty value_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } pattern_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -8331,7 +9130,7 @@ value_pattern_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // attr !('.' | '(' | '=') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> value_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "attr !('.' | '(' | '=')")); @@ -8339,13 +9138,13 @@ value_pattern_rule(Parser *p) if ( (attr = attr_rule(p)) // attr && - _PyPegen_lookahead(0, _tmp_67_rule, p) + _PyPegen_lookahead(0, _tmp_70_rule, p) ) { D(fprintf(stderr, "%*c+ value_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "attr !('.' | '(' | '=')")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -8355,7 +9154,7 @@ value_pattern_rule(Parser *p) _res = _PyAST_MatchValue ( attr , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -8366,7 +9165,7 @@ value_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -8376,10 +9175,13 @@ static expr_ty attr_raw(Parser *); static expr_ty attr_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, attr_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; @@ -8387,37 +9189,40 @@ attr_rule(Parser *p) while (1) { int tmpvar_1 = _PyPegen_update_memo(p, _mark, attr_type, _res); if (tmpvar_1) { - D(p->level--); + p->level--; return _res; } p->mark = _mark; - p->in_raw_rule++; void *_raw = attr_raw(p); - p->in_raw_rule--; - if (p->error_indicator) + if (p->error_indicator) { + p->level--; return NULL; + } if (_raw == NULL || p->mark <= _resmark) break; _resmark = p->mark; _res = _raw; } p->mark = _resmark; - D(p->level--); + p->level--; return _res; } static expr_ty attr_raw(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -8426,7 +9231,7 @@ attr_raw(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // name_or_attr '.' NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> attr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "name_or_attr '.' NAME")); @@ -8444,7 +9249,7 @@ attr_raw(Parser *p) D(fprintf(stderr, "%*c+ attr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "name_or_attr '.' NAME")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -8454,7 +9259,7 @@ attr_raw(Parser *p) _res = _PyAST_Attribute ( value , attr -> v . Name . id , Load , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -8465,7 +9270,7 @@ attr_raw(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -8474,16 +9279,19 @@ attr_raw(Parser *p) static expr_ty name_or_attr_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; { // attr if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> name_or_attr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "attr")); @@ -8502,7 +9310,7 @@ name_or_attr_rule(Parser *p) } { // NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> name_or_attr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); @@ -8521,7 +9329,7 @@ name_or_attr_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -8529,16 +9337,19 @@ name_or_attr_rule(Parser *p) static pattern_ty group_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } pattern_ty _res = NULL; int _mark = p->mark; { // '(' pattern ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> group_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' pattern ')'")); @@ -8557,7 +9368,7 @@ group_pattern_rule(Parser *p) _res = pattern; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -8568,7 +9379,7 @@ group_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -8576,16 +9387,19 @@ group_pattern_rule(Parser *p) static pattern_ty sequence_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } pattern_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -8594,7 +9408,7 @@ sequence_pattern_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '[' maybe_sequence_pattern? ']' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> sequence_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' maybe_sequence_pattern? ']'")); @@ -8612,7 +9426,7 @@ sequence_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ sequence_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' maybe_sequence_pattern? ']'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -8622,7 +9436,7 @@ sequence_pattern_rule(Parser *p) _res = _PyAST_MatchSequence ( patterns , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -8633,7 +9447,7 @@ sequence_pattern_rule(Parser *p) } { // '(' open_sequence_pattern? ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> sequence_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' open_sequence_pattern? ')'")); @@ -8651,7 +9465,7 @@ sequence_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ sequence_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' open_sequence_pattern? ')'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -8661,7 +9475,7 @@ sequence_pattern_rule(Parser *p) _res = _PyAST_MatchSequence ( patterns , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -8672,7 +9486,7 @@ sequence_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -8680,16 +9494,19 @@ sequence_pattern_rule(Parser *p) static asdl_seq* open_sequence_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq* _res = NULL; int _mark = p->mark; { // maybe_star_pattern ',' maybe_sequence_pattern? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> open_sequence_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern ',' maybe_sequence_pattern?")); @@ -8708,7 +9525,7 @@ open_sequence_pattern_rule(Parser *p) _res = _PyPegen_seq_insert_in_front ( p , pattern , patterns ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -8719,7 +9536,7 @@ open_sequence_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -8727,16 +9544,19 @@ open_sequence_pattern_rule(Parser *p) static asdl_seq* maybe_sequence_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq* _res = NULL; int _mark = p->mark; { // ','.maybe_star_pattern+ ','? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> maybe_sequence_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.maybe_star_pattern+ ','?")); @@ -8744,7 +9564,7 @@ maybe_sequence_pattern_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_seq * patterns; if ( - (patterns = _gather_68_rule(p)) // ','.maybe_star_pattern+ + (patterns = _gather_71_rule(p)) // ','.maybe_star_pattern+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -8753,7 +9573,7 @@ maybe_sequence_pattern_rule(Parser *p) _res = patterns; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -8764,7 +9584,7 @@ maybe_sequence_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -8772,16 +9592,19 @@ maybe_sequence_pattern_rule(Parser *p) static pattern_ty maybe_star_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } pattern_ty _res = NULL; int _mark = p->mark; { // star_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> maybe_star_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_pattern")); @@ -8800,7 +9623,7 @@ maybe_star_pattern_rule(Parser *p) } { // pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> maybe_star_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern")); @@ -8819,7 +9642,7 @@ maybe_star_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -8827,16 +9650,23 @@ maybe_star_pattern_rule(Parser *p) static pattern_ty star_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } pattern_ty _res = NULL; + if (_PyPegen_is_memoized(p, star_pattern_type, &_res)) { + p->level--; + return _res; + } int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -8845,7 +9675,7 @@ star_pattern_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '*' pattern_capture_target if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' pattern_capture_target")); @@ -8860,7 +9690,7 @@ star_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ star_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' pattern_capture_target")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -8870,7 +9700,7 @@ star_pattern_rule(Parser *p) _res = _PyAST_MatchStar ( target -> v . Name . id , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -8881,7 +9711,7 @@ star_pattern_rule(Parser *p) } { // '*' wildcard_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' wildcard_pattern")); @@ -8896,7 +9726,7 @@ star_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ star_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' wildcard_pattern")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -8906,7 +9736,7 @@ star_pattern_rule(Parser *p) _res = _PyAST_MatchStar ( NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -8917,7 +9747,8 @@ star_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + _PyPegen_insert_memo(p, _mark, star_pattern_type, _res); + p->level--; return _res; } @@ -8929,16 +9760,19 @@ star_pattern_rule(Parser *p) static pattern_ty mapping_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } pattern_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -8947,7 +9781,7 @@ mapping_pattern_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '{' '}' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> mapping_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' '}'")); @@ -8962,7 +9796,7 @@ mapping_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ mapping_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' '}'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -8972,7 +9806,7 @@ mapping_pattern_rule(Parser *p) _res = _PyAST_MatchMapping ( NULL , NULL , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -8983,7 +9817,7 @@ mapping_pattern_rule(Parser *p) } { // '{' double_star_pattern ','? '}' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> mapping_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' double_star_pattern ','? '}'")); @@ -9005,7 +9839,7 @@ mapping_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ mapping_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' double_star_pattern ','? '}'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -9015,7 +9849,7 @@ mapping_pattern_rule(Parser *p) _res = _PyAST_MatchMapping ( NULL , NULL , rest -> v . Name . id , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -9026,7 +9860,7 @@ mapping_pattern_rule(Parser *p) } { // '{' items_pattern ',' double_star_pattern ','? '}' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> mapping_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' items_pattern ',' double_star_pattern ','? '}'")); @@ -9054,7 +9888,7 @@ mapping_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ mapping_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' items_pattern ',' double_star_pattern ','? '}'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -9064,7 +9898,7 @@ mapping_pattern_rule(Parser *p) _res = _PyAST_MatchMapping ( CHECK ( asdl_expr_seq* , _PyPegen_get_pattern_keys ( p , items ) ) , CHECK ( asdl_pattern_seq* , _PyPegen_get_patterns ( p , items ) ) , rest -> v . Name . id , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -9075,7 +9909,7 @@ mapping_pattern_rule(Parser *p) } { // '{' items_pattern ','? '}' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> mapping_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' items_pattern ','? '}'")); @@ -9097,7 +9931,7 @@ mapping_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ mapping_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' items_pattern ','? '}'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -9107,7 +9941,7 @@ mapping_pattern_rule(Parser *p) _res = _PyAST_MatchMapping ( CHECK ( asdl_expr_seq* , _PyPegen_get_pattern_keys ( p , items ) ) , CHECK ( asdl_pattern_seq* , _PyPegen_get_patterns ( p , items ) ) , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -9118,7 +9952,7 @@ mapping_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -9126,26 +9960,29 @@ mapping_pattern_rule(Parser *p) static asdl_seq* items_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq* _res = NULL; int _mark = p->mark; { // ','.key_value_pattern+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> items_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.key_value_pattern+")); - asdl_seq * _gather_70_var; + asdl_seq * _gather_73_var; if ( - (_gather_70_var = _gather_70_rule(p)) // ','.key_value_pattern+ + (_gather_73_var = _gather_73_rule(p)) // ','.key_value_pattern+ ) { D(fprintf(stderr, "%*c+ items_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.key_value_pattern+")); - _res = _gather_70_var; + _res = _gather_73_var; goto done; } p->mark = _mark; @@ -9154,7 +9991,7 @@ items_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -9162,16 +9999,19 @@ items_pattern_rule(Parser *p) static KeyPatternPair* key_value_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } KeyPatternPair* _res = NULL; int _mark = p->mark; { // (literal_expr | attr) ':' pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> key_value_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(literal_expr | attr) ':' pattern")); @@ -9179,7 +10019,7 @@ key_value_pattern_rule(Parser *p) void *key; pattern_ty pattern; if ( - (key = _tmp_72_rule(p)) // literal_expr | attr + (key = _tmp_75_rule(p)) // literal_expr | attr && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -9190,7 +10030,7 @@ key_value_pattern_rule(Parser *p) _res = _PyPegen_key_pattern_pair ( p , key , pattern ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -9201,7 +10041,7 @@ key_value_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -9209,16 +10049,19 @@ key_value_pattern_rule(Parser *p) static expr_ty double_star_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; { // '**' pattern_capture_target if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> double_star_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' pattern_capture_target")); @@ -9234,7 +10077,7 @@ double_star_pattern_rule(Parser *p) _res = target; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -9245,7 +10088,7 @@ double_star_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -9258,16 +10101,19 @@ double_star_pattern_rule(Parser *p) static pattern_ty class_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } pattern_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -9276,7 +10122,7 @@ class_pattern_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // name_or_attr '(' ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> class_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' ')'")); @@ -9294,7 +10140,7 @@ class_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ class_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' ')'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -9304,7 +10150,7 @@ class_pattern_rule(Parser *p) _res = _PyAST_MatchClass ( cls , NULL , NULL , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -9315,7 +10161,7 @@ class_pattern_rule(Parser *p) } { // name_or_attr '(' positional_patterns ','? ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> class_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' positional_patterns ','? ')'")); @@ -9340,7 +10186,7 @@ class_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ class_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' positional_patterns ','? ')'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -9350,7 +10196,7 @@ class_pattern_rule(Parser *p) _res = _PyAST_MatchClass ( cls , patterns , NULL , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -9361,7 +10207,7 @@ class_pattern_rule(Parser *p) } { // name_or_attr '(' keyword_patterns ','? ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> class_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' keyword_patterns ','? ')'")); @@ -9386,7 +10232,7 @@ class_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ class_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' keyword_patterns ','? ')'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -9396,7 +10242,7 @@ class_pattern_rule(Parser *p) _res = _PyAST_MatchClass ( cls , NULL , CHECK ( asdl_identifier_seq* , _PyPegen_map_names_to_ids ( p , CHECK ( asdl_expr_seq* , _PyPegen_get_pattern_keys ( p , keywords ) ) ) ) , CHECK ( asdl_pattern_seq* , _PyPegen_get_patterns ( p , keywords ) ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -9407,7 +10253,7 @@ class_pattern_rule(Parser *p) } { // name_or_attr '(' positional_patterns ',' keyword_patterns ','? ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> class_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' positional_patterns ',' keyword_patterns ','? ')'")); @@ -9438,7 +10284,7 @@ class_pattern_rule(Parser *p) D(fprintf(stderr, "%*c+ class_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' positional_patterns ',' keyword_patterns ','? ')'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -9448,7 +10294,7 @@ class_pattern_rule(Parser *p) _res = _PyAST_MatchClass ( cls , patterns , CHECK ( asdl_identifier_seq* , _PyPegen_map_names_to_ids ( p , CHECK ( asdl_expr_seq* , _PyPegen_get_pattern_keys ( p , keywords ) ) ) ) , CHECK ( asdl_pattern_seq* , _PyPegen_get_patterns ( p , keywords ) ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -9459,7 +10305,7 @@ class_pattern_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_class_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> class_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_class_pattern")); @@ -9478,7 +10324,7 @@ class_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -9486,29 +10332,32 @@ class_pattern_rule(Parser *p) static asdl_pattern_seq* positional_patterns_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_pattern_seq* _res = NULL; int _mark = p->mark; { // ','.pattern+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> positional_patterns[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.pattern+")); asdl_pattern_seq* args; if ( - (args = (asdl_pattern_seq*)_gather_73_rule(p)) // ','.pattern+ + (args = (asdl_pattern_seq*)_gather_76_rule(p)) // ','.pattern+ ) { D(fprintf(stderr, "%*c+ positional_patterns[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.pattern+")); _res = args; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -9519,7 +10368,7 @@ positional_patterns_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -9527,26 +10376,29 @@ positional_patterns_rule(Parser *p) static asdl_seq* keyword_patterns_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq* _res = NULL; int _mark = p->mark; { // ','.keyword_pattern+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> keyword_patterns[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.keyword_pattern+")); - asdl_seq * _gather_75_var; + asdl_seq * _gather_78_var; if ( - (_gather_75_var = _gather_75_rule(p)) // ','.keyword_pattern+ + (_gather_78_var = _gather_78_rule(p)) // ','.keyword_pattern+ ) { D(fprintf(stderr, "%*c+ keyword_patterns[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.keyword_pattern+")); - _res = _gather_75_var; + _res = _gather_78_var; goto done; } p->mark = _mark; @@ -9555,7 +10407,7 @@ keyword_patterns_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -9563,16 +10415,19 @@ keyword_patterns_rule(Parser *p) static KeyPatternPair* keyword_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } KeyPatternPair* _res = NULL; int _mark = p->mark; { // NAME '=' pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> keyword_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '=' pattern")); @@ -9591,7 +10446,7 @@ keyword_pattern_rule(Parser *p) _res = _PyPegen_key_pattern_pair ( p , arg , value ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -9602,7 +10457,7 @@ keyword_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -9610,16 +10465,19 @@ keyword_pattern_rule(Parser *p) static expr_ty expressions_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -9628,7 +10486,7 @@ expressions_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // expression ((',' expression))+ ','? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ((',' expression))+ ','?")); @@ -9639,7 +10497,7 @@ expressions_rule(Parser *p) if ( (a = expression_rule(p)) // expression && - (b = _loop1_77_rule(p)) // ((',' expression))+ + (b = _loop1_80_rule(p)) // ((',' expression))+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -9647,7 +10505,7 @@ expressions_rule(Parser *p) D(fprintf(stderr, "%*c+ expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ((',' expression))+ ','?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -9657,7 +10515,7 @@ expressions_rule(Parser *p) _res = _PyAST_Tuple ( CHECK ( asdl_expr_seq* , _PyPegen_seq_insert_in_front ( p , a , b ) ) , Load , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -9668,7 +10526,7 @@ expressions_rule(Parser *p) } { // expression ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ','")); @@ -9683,7 +10541,7 @@ expressions_rule(Parser *p) D(fprintf(stderr, "%*c+ expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ','")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -9693,7 +10551,7 @@ expressions_rule(Parser *p) _res = _PyAST_Tuple ( CHECK ( asdl_expr_seq* , _PyPegen_singleton_seq ( p , a ) ) , Load , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -9704,7 +10562,7 @@ expressions_rule(Parser *p) } { // expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression")); @@ -9723,7 +10581,7 @@ expressions_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -9736,20 +10594,23 @@ expressions_rule(Parser *p) static expr_ty expression_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, expression_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -9758,7 +10619,7 @@ expression_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro if (p->call_invalid_rules) { // invalid_expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_expression")); @@ -9777,7 +10638,7 @@ expression_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_legacy_expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_legacy_expression")); @@ -9796,7 +10657,7 @@ expression_rule(Parser *p) } { // disjunction 'if' disjunction 'else' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction 'else' expression")); @@ -9808,11 +10669,11 @@ expression_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 627)) // token='if' + (_keyword = _PyPegen_expect_token(p, 641)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 630)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 644)) // token='else' && (c = expression_rule(p)) // expression ) @@ -9820,7 +10681,7 @@ expression_rule(Parser *p) D(fprintf(stderr, "%*c+ expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction 'else' expression")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -9830,7 +10691,7 @@ expression_rule(Parser *p) _res = _PyAST_IfExp ( b , a , c , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -9841,7 +10702,7 @@ expression_rule(Parser *p) } { // disjunction if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "disjunction")); @@ -9860,7 +10721,7 @@ expression_rule(Parser *p) } { // lambdef if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambdef")); @@ -9880,7 +10741,7 @@ expression_rule(Parser *p) _res = NULL; done: _PyPegen_insert_memo(p, _mark, expression_type, _res); - D(p->level--); + p->level--; return _res; } @@ -9888,16 +10749,19 @@ expression_rule(Parser *p) static expr_ty yield_expr_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -9906,7 +10770,7 @@ yield_expr_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // 'yield' 'from' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> yield_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'yield' 'from' expression")); @@ -9914,9 +10778,9 @@ yield_expr_rule(Parser *p) Token * _keyword_1; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 570)) // token='yield' + (_keyword = _PyPegen_expect_token(p, 573)) // token='yield' && - (_keyword_1 = _PyPegen_expect_token(p, 569)) // token='from' + (_keyword_1 = _PyPegen_expect_token(p, 607)) // token='from' && (a = expression_rule(p)) // expression ) @@ -9924,7 +10788,7 @@ yield_expr_rule(Parser *p) D(fprintf(stderr, "%*c+ yield_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'yield' 'from' expression")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -9934,7 +10798,7 @@ yield_expr_rule(Parser *p) _res = _PyAST_YieldFrom ( a , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -9945,14 +10809,14 @@ yield_expr_rule(Parser *p) } { // 'yield' star_expressions? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> yield_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'yield' star_expressions?")); Token * _keyword; void *a; if ( - (_keyword = _PyPegen_expect_token(p, 570)) // token='yield' + (_keyword = _PyPegen_expect_token(p, 573)) // token='yield' && (a = star_expressions_rule(p), !p->error_indicator) // star_expressions? ) @@ -9960,7 +10824,7 @@ yield_expr_rule(Parser *p) D(fprintf(stderr, "%*c+ yield_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'yield' star_expressions?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -9970,7 +10834,7 @@ yield_expr_rule(Parser *p) _res = _PyAST_Yield ( a , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -9981,7 +10845,7 @@ yield_expr_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -9992,16 +10856,19 @@ yield_expr_rule(Parser *p) static expr_ty star_expressions_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -10010,7 +10877,7 @@ star_expressions_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // star_expression ((',' star_expression))+ ','? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expression ((',' star_expression))+ ','?")); @@ -10021,7 +10888,7 @@ star_expressions_rule(Parser *p) if ( (a = star_expression_rule(p)) // star_expression && - (b = _loop1_78_rule(p)) // ((',' star_expression))+ + (b = _loop1_81_rule(p)) // ((',' star_expression))+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -10029,7 +10896,7 @@ star_expressions_rule(Parser *p) D(fprintf(stderr, "%*c+ star_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expression ((',' star_expression))+ ','?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -10039,7 +10906,7 @@ star_expressions_rule(Parser *p) _res = _PyAST_Tuple ( CHECK ( asdl_expr_seq* , _PyPegen_seq_insert_in_front ( p , a , b ) ) , Load , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -10050,7 +10917,7 @@ star_expressions_rule(Parser *p) } { // star_expression ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expression ','")); @@ -10065,7 +10932,7 @@ star_expressions_rule(Parser *p) D(fprintf(stderr, "%*c+ star_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expression ','")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -10075,7 +10942,7 @@ star_expressions_rule(Parser *p) _res = _PyAST_Tuple ( CHECK ( asdl_expr_seq* , _PyPegen_singleton_seq ( p , a ) ) , Load , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -10086,7 +10953,7 @@ star_expressions_rule(Parser *p) } { // star_expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expression")); @@ -10105,7 +10972,7 @@ star_expressions_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -10113,20 +10980,23 @@ star_expressions_rule(Parser *p) static expr_ty star_expression_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, star_expression_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -10135,7 +11005,7 @@ star_expression_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '*' bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or")); @@ -10150,7 +11020,7 @@ star_expression_rule(Parser *p) D(fprintf(stderr, "%*c+ star_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -10160,7 +11030,7 @@ star_expression_rule(Parser *p) _res = _PyAST_Starred ( a , Load , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -10171,7 +11041,7 @@ star_expression_rule(Parser *p) } { // expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression")); @@ -10191,7 +11061,7 @@ star_expression_rule(Parser *p) _res = NULL; done: _PyPegen_insert_memo(p, _mark, star_expression_type, _res); - D(p->level--); + p->level--; return _res; } @@ -10199,16 +11069,19 @@ star_expression_rule(Parser *p) static asdl_expr_seq* star_named_expressions_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_expr_seq* _res = NULL; int _mark = p->mark; { // ','.star_named_expression+ ','? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_named_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.star_named_expression+ ','?")); @@ -10216,7 +11089,7 @@ star_named_expressions_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_79_rule(p)) // ','.star_named_expression+ + (a = (asdl_expr_seq*)_gather_82_rule(p)) // ','.star_named_expression+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -10225,7 +11098,7 @@ star_named_expressions_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -10236,7 +11109,7 @@ star_named_expressions_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -10244,16 +11117,19 @@ star_named_expressions_rule(Parser *p) static expr_ty star_named_expression_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -10262,7 +11138,7 @@ star_named_expression_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '*' bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or")); @@ -10277,7 +11153,7 @@ star_named_expression_rule(Parser *p) D(fprintf(stderr, "%*c+ star_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' bitwise_or")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -10287,7 +11163,7 @@ star_named_expression_rule(Parser *p) _res = _PyAST_Starred ( a , Load , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -10298,7 +11174,7 @@ star_named_expression_rule(Parser *p) } { // named_expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression")); @@ -10317,7 +11193,7 @@ star_named_expression_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -10325,16 +11201,19 @@ star_named_expression_rule(Parser *p) static expr_ty assignment_expression_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -10343,7 +11222,7 @@ assignment_expression_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // NAME ':=' ~ expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> assignment_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME ':=' ~ expression")); @@ -10364,17 +11243,17 @@ assignment_expression_rule(Parser *p) D(fprintf(stderr, "%*c+ assignment_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME ':=' ~ expression")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; UNUSED(_end_lineno); // Only used by EXTRA macro int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro - _res = _PyAST_NamedExpr ( CHECK ( expr_ty , _PyPegen_set_expr_context ( p , a , Store ) ) , b , EXTRA ); + _res = CHECK_VERSION ( expr_ty , 8 , "Assignment expressions are" , _PyAST_NamedExpr ( CHECK ( expr_ty , _PyPegen_set_expr_context ( p , a , Store ) ) , b , EXTRA ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -10383,13 +11262,13 @@ assignment_expression_rule(Parser *p) D(fprintf(stderr, "%*c%s assignment_expression[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME ':=' ~ expression")); if (_cut_var) { - D(p->level--); + p->level--; return NULL; } } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -10397,16 +11276,19 @@ assignment_expression_rule(Parser *p) static expr_ty named_expression_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; { // assignment_expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); @@ -10425,7 +11307,7 @@ named_expression_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_named_expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_named_expression")); @@ -10444,7 +11326,7 @@ named_expression_rule(Parser *p) } { // expression !':=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); @@ -10465,7 +11347,7 @@ named_expression_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -10473,20 +11355,23 @@ named_expression_rule(Parser *p) static expr_ty disjunction_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, disjunction_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -10495,7 +11380,7 @@ disjunction_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // conjunction (('or' conjunction))+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> disjunction[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "conjunction (('or' conjunction))+")); @@ -10504,13 +11389,13 @@ disjunction_rule(Parser *p) if ( (a = conjunction_rule(p)) // conjunction && - (b = _loop1_81_rule(p)) // (('or' conjunction))+ + (b = _loop1_84_rule(p)) // (('or' conjunction))+ ) { D(fprintf(stderr, "%*c+ disjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "conjunction (('or' conjunction))+")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -10520,7 +11405,7 @@ disjunction_rule(Parser *p) _res = _PyAST_BoolOp ( Or , CHECK ( asdl_expr_seq* , _PyPegen_seq_insert_in_front ( p , a , b ) ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -10531,7 +11416,7 @@ disjunction_rule(Parser *p) } { // conjunction if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> disjunction[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "conjunction")); @@ -10551,7 +11436,7 @@ disjunction_rule(Parser *p) _res = NULL; done: _PyPegen_insert_memo(p, _mark, disjunction_type, _res); - D(p->level--); + p->level--; return _res; } @@ -10559,20 +11444,23 @@ disjunction_rule(Parser *p) static expr_ty conjunction_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, conjunction_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -10581,7 +11469,7 @@ conjunction_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // inversion (('and' inversion))+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> conjunction[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "inversion (('and' inversion))+")); @@ -10590,13 +11478,13 @@ conjunction_rule(Parser *p) if ( (a = inversion_rule(p)) // inversion && - (b = _loop1_82_rule(p)) // (('and' inversion))+ + (b = _loop1_85_rule(p)) // (('and' inversion))+ ) { D(fprintf(stderr, "%*c+ conjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "inversion (('and' inversion))+")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -10606,7 +11494,7 @@ conjunction_rule(Parser *p) _res = _PyAST_BoolOp ( And , CHECK ( asdl_expr_seq* , _PyPegen_seq_insert_in_front ( p , a , b ) ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -10617,7 +11505,7 @@ conjunction_rule(Parser *p) } { // inversion if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> conjunction[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "inversion")); @@ -10637,7 +11525,7 @@ conjunction_rule(Parser *p) _res = NULL; done: _PyPegen_insert_memo(p, _mark, conjunction_type, _res); - D(p->level--); + p->level--; return _res; } @@ -10645,20 +11533,23 @@ conjunction_rule(Parser *p) static expr_ty inversion_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, inversion_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -10667,14 +11558,14 @@ inversion_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // 'not' inversion if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> inversion[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'not' inversion")); Token * _keyword; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 578)) // token='not' + (_keyword = _PyPegen_expect_token(p, 581)) // token='not' && (a = inversion_rule(p)) // inversion ) @@ -10682,7 +11573,7 @@ inversion_rule(Parser *p) D(fprintf(stderr, "%*c+ inversion[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'not' inversion")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -10692,7 +11583,7 @@ inversion_rule(Parser *p) _res = _PyAST_UnaryOp ( Not , a , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -10703,7 +11594,7 @@ inversion_rule(Parser *p) } { // comparison if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> inversion[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "comparison")); @@ -10723,7 +11614,7 @@ inversion_rule(Parser *p) _res = NULL; done: _PyPegen_insert_memo(p, _mark, inversion_type, _res); - D(p->level--); + p->level--; return _res; } @@ -10731,16 +11622,19 @@ inversion_rule(Parser *p) static expr_ty comparison_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -10749,7 +11643,7 @@ comparison_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // bitwise_or compare_op_bitwise_or_pair+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> comparison[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_or compare_op_bitwise_or_pair+")); @@ -10758,13 +11652,13 @@ comparison_rule(Parser *p) if ( (a = bitwise_or_rule(p)) // bitwise_or && - (b = _loop1_83_rule(p)) // compare_op_bitwise_or_pair+ + (b = _loop1_86_rule(p)) // compare_op_bitwise_or_pair+ ) { D(fprintf(stderr, "%*c+ comparison[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_or compare_op_bitwise_or_pair+")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -10774,7 +11668,7 @@ comparison_rule(Parser *p) _res = _PyAST_Compare ( a , CHECK ( asdl_int_seq* , _PyPegen_get_cmpops ( p , b ) ) , CHECK ( asdl_expr_seq* , _PyPegen_get_exprs ( p , b ) ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -10785,7 +11679,7 @@ comparison_rule(Parser *p) } { // bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> comparison[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_or")); @@ -10804,7 +11698,7 @@ comparison_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -10822,16 +11716,19 @@ comparison_rule(Parser *p) static CmpopExprPair* compare_op_bitwise_or_pair_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } CmpopExprPair* _res = NULL; int _mark = p->mark; { // eq_bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "eq_bitwise_or")); @@ -10850,7 +11747,7 @@ compare_op_bitwise_or_pair_rule(Parser *p) } { // noteq_bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "noteq_bitwise_or")); @@ -10869,7 +11766,7 @@ compare_op_bitwise_or_pair_rule(Parser *p) } { // lte_bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lte_bitwise_or")); @@ -10888,7 +11785,7 @@ compare_op_bitwise_or_pair_rule(Parser *p) } { // lt_bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lt_bitwise_or")); @@ -10907,7 +11804,7 @@ compare_op_bitwise_or_pair_rule(Parser *p) } { // gte_bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "gte_bitwise_or")); @@ -10926,7 +11823,7 @@ compare_op_bitwise_or_pair_rule(Parser *p) } { // gt_bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "gt_bitwise_or")); @@ -10945,7 +11842,7 @@ compare_op_bitwise_or_pair_rule(Parser *p) } { // notin_bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "notin_bitwise_or")); @@ -10964,7 +11861,7 @@ compare_op_bitwise_or_pair_rule(Parser *p) } { // in_bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "in_bitwise_or")); @@ -10983,7 +11880,7 @@ compare_op_bitwise_or_pair_rule(Parser *p) } { // isnot_bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "isnot_bitwise_or")); @@ -11002,7 +11899,7 @@ compare_op_bitwise_or_pair_rule(Parser *p) } { // is_bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> compare_op_bitwise_or_pair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "is_bitwise_or")); @@ -11021,7 +11918,7 @@ compare_op_bitwise_or_pair_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -11029,16 +11926,19 @@ compare_op_bitwise_or_pair_rule(Parser *p) static CmpopExprPair* eq_bitwise_or_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } CmpopExprPair* _res = NULL; int _mark = p->mark; { // '==' bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> eq_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'==' bitwise_or")); @@ -11054,7 +11954,7 @@ eq_bitwise_or_rule(Parser *p) _res = _PyPegen_cmpop_expr_pair ( p , Eq , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -11065,7 +11965,7 @@ eq_bitwise_or_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -11073,23 +11973,26 @@ eq_bitwise_or_rule(Parser *p) static CmpopExprPair* noteq_bitwise_or_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } CmpopExprPair* _res = NULL; int _mark = p->mark; { // ('!=') bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> noteq_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('!=') bitwise_or")); - void *_tmp_84_var; + void *_tmp_87_var; expr_ty a; if ( - (_tmp_84_var = _tmp_84_rule(p)) // '!=' + (_tmp_87_var = _tmp_87_rule(p)) // '!=' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -11098,7 +12001,7 @@ noteq_bitwise_or_rule(Parser *p) _res = _PyPegen_cmpop_expr_pair ( p , NotEq , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -11109,7 +12012,7 @@ noteq_bitwise_or_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -11117,16 +12020,19 @@ noteq_bitwise_or_rule(Parser *p) static CmpopExprPair* lte_bitwise_or_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } CmpopExprPair* _res = NULL; int _mark = p->mark; { // '<=' bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lte_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'<=' bitwise_or")); @@ -11142,7 +12048,7 @@ lte_bitwise_or_rule(Parser *p) _res = _PyPegen_cmpop_expr_pair ( p , LtE , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -11153,7 +12059,7 @@ lte_bitwise_or_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -11161,16 +12067,19 @@ lte_bitwise_or_rule(Parser *p) static CmpopExprPair* lt_bitwise_or_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } CmpopExprPair* _res = NULL; int _mark = p->mark; { // '<' bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lt_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'<' bitwise_or")); @@ -11186,7 +12095,7 @@ lt_bitwise_or_rule(Parser *p) _res = _PyPegen_cmpop_expr_pair ( p , Lt , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -11197,7 +12106,7 @@ lt_bitwise_or_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -11205,16 +12114,19 @@ lt_bitwise_or_rule(Parser *p) static CmpopExprPair* gte_bitwise_or_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } CmpopExprPair* _res = NULL; int _mark = p->mark; { // '>=' bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> gte_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'>=' bitwise_or")); @@ -11230,7 +12142,7 @@ gte_bitwise_or_rule(Parser *p) _res = _PyPegen_cmpop_expr_pair ( p , GtE , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -11241,7 +12153,7 @@ gte_bitwise_or_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -11249,16 +12161,19 @@ gte_bitwise_or_rule(Parser *p) static CmpopExprPair* gt_bitwise_or_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } CmpopExprPair* _res = NULL; int _mark = p->mark; { // '>' bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> gt_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'>' bitwise_or")); @@ -11274,7 +12189,7 @@ gt_bitwise_or_rule(Parser *p) _res = _PyPegen_cmpop_expr_pair ( p , Gt , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -11285,7 +12200,7 @@ gt_bitwise_or_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -11293,16 +12208,19 @@ gt_bitwise_or_rule(Parser *p) static CmpopExprPair* notin_bitwise_or_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } CmpopExprPair* _res = NULL; int _mark = p->mark; { // 'not' 'in' bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> notin_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'not' 'in' bitwise_or")); @@ -11310,9 +12228,9 @@ notin_bitwise_or_rule(Parser *p) Token * _keyword_1; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 578)) // token='not' + (_keyword = _PyPegen_expect_token(p, 581)) // token='not' && - (_keyword_1 = _PyPegen_expect_token(p, 634)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 650)) // token='in' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -11321,7 +12239,7 @@ notin_bitwise_or_rule(Parser *p) _res = _PyPegen_cmpop_expr_pair ( p , NotIn , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -11332,7 +12250,7 @@ notin_bitwise_or_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -11340,23 +12258,26 @@ notin_bitwise_or_rule(Parser *p) static CmpopExprPair* in_bitwise_or_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } CmpopExprPair* _res = NULL; int _mark = p->mark; { // 'in' bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> in_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'in' bitwise_or")); Token * _keyword; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 634)) // token='in' + (_keyword = _PyPegen_expect_token(p, 650)) // token='in' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -11365,7 +12286,7 @@ in_bitwise_or_rule(Parser *p) _res = _PyPegen_cmpop_expr_pair ( p , In , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -11376,7 +12297,7 @@ in_bitwise_or_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -11384,16 +12305,19 @@ in_bitwise_or_rule(Parser *p) static CmpopExprPair* isnot_bitwise_or_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } CmpopExprPair* _res = NULL; int _mark = p->mark; { // 'is' 'not' bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> isnot_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'is' 'not' bitwise_or")); @@ -11401,9 +12325,9 @@ isnot_bitwise_or_rule(Parser *p) Token * _keyword_1; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 579)) // token='is' + (_keyword = _PyPegen_expect_token(p, 582)) // token='is' && - (_keyword_1 = _PyPegen_expect_token(p, 578)) // token='not' + (_keyword_1 = _PyPegen_expect_token(p, 581)) // token='not' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -11412,7 +12336,7 @@ isnot_bitwise_or_rule(Parser *p) _res = _PyPegen_cmpop_expr_pair ( p , IsNot , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -11423,7 +12347,7 @@ isnot_bitwise_or_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -11431,23 +12355,26 @@ isnot_bitwise_or_rule(Parser *p) static CmpopExprPair* is_bitwise_or_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } CmpopExprPair* _res = NULL; int _mark = p->mark; { // 'is' bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> is_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'is' bitwise_or")); Token * _keyword; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 579)) // token='is' + (_keyword = _PyPegen_expect_token(p, 582)) // token='is' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -11456,7 +12383,7 @@ is_bitwise_or_rule(Parser *p) _res = _PyPegen_cmpop_expr_pair ( p , Is , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -11467,7 +12394,7 @@ is_bitwise_or_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -11477,10 +12404,13 @@ static expr_ty bitwise_or_raw(Parser *); static expr_ty bitwise_or_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, bitwise_or_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; @@ -11488,37 +12418,40 @@ bitwise_or_rule(Parser *p) while (1) { int tmpvar_2 = _PyPegen_update_memo(p, _mark, bitwise_or_type, _res); if (tmpvar_2) { - D(p->level--); + p->level--; return _res; } p->mark = _mark; - p->in_raw_rule++; void *_raw = bitwise_or_raw(p); - p->in_raw_rule--; - if (p->error_indicator) + if (p->error_indicator) { + p->level--; return NULL; + } if (_raw == NULL || p->mark <= _resmark) break; _resmark = p->mark; _res = _raw; } p->mark = _resmark; - D(p->level--); + p->level--; return _res; } static expr_ty bitwise_or_raw(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -11527,7 +12460,7 @@ bitwise_or_raw(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // bitwise_or '|' bitwise_xor if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_or '|' bitwise_xor")); @@ -11545,7 +12478,7 @@ bitwise_or_raw(Parser *p) D(fprintf(stderr, "%*c+ bitwise_or[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_or '|' bitwise_xor")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -11555,7 +12488,7 @@ bitwise_or_raw(Parser *p) _res = _PyAST_BinOp ( a , BitOr , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -11566,7 +12499,7 @@ bitwise_or_raw(Parser *p) } { // bitwise_xor if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_xor")); @@ -11585,7 +12518,7 @@ bitwise_or_raw(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -11595,10 +12528,13 @@ static expr_ty bitwise_xor_raw(Parser *); static expr_ty bitwise_xor_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, bitwise_xor_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; @@ -11606,37 +12542,40 @@ bitwise_xor_rule(Parser *p) while (1) { int tmpvar_3 = _PyPegen_update_memo(p, _mark, bitwise_xor_type, _res); if (tmpvar_3) { - D(p->level--); + p->level--; return _res; } p->mark = _mark; - p->in_raw_rule++; void *_raw = bitwise_xor_raw(p); - p->in_raw_rule--; - if (p->error_indicator) + if (p->error_indicator) { + p->level--; return NULL; + } if (_raw == NULL || p->mark <= _resmark) break; _resmark = p->mark; _res = _raw; } p->mark = _resmark; - D(p->level--); + p->level--; return _res; } static expr_ty bitwise_xor_raw(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -11645,7 +12584,7 @@ bitwise_xor_raw(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // bitwise_xor '^' bitwise_and if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> bitwise_xor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_xor '^' bitwise_and")); @@ -11663,7 +12602,7 @@ bitwise_xor_raw(Parser *p) D(fprintf(stderr, "%*c+ bitwise_xor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_xor '^' bitwise_and")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -11673,7 +12612,7 @@ bitwise_xor_raw(Parser *p) _res = _PyAST_BinOp ( a , BitXor , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -11684,7 +12623,7 @@ bitwise_xor_raw(Parser *p) } { // bitwise_and if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> bitwise_xor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_and")); @@ -11703,7 +12642,7 @@ bitwise_xor_raw(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -11713,10 +12652,13 @@ static expr_ty bitwise_and_raw(Parser *); static expr_ty bitwise_and_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, bitwise_and_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; @@ -11724,37 +12666,40 @@ bitwise_and_rule(Parser *p) while (1) { int tmpvar_4 = _PyPegen_update_memo(p, _mark, bitwise_and_type, _res); if (tmpvar_4) { - D(p->level--); + p->level--; return _res; } p->mark = _mark; - p->in_raw_rule++; void *_raw = bitwise_and_raw(p); - p->in_raw_rule--; - if (p->error_indicator) + if (p->error_indicator) { + p->level--; return NULL; + } if (_raw == NULL || p->mark <= _resmark) break; _resmark = p->mark; _res = _raw; } p->mark = _resmark; - D(p->level--); + p->level--; return _res; } static expr_ty bitwise_and_raw(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -11763,7 +12708,7 @@ bitwise_and_raw(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // bitwise_and '&' shift_expr if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> bitwise_and[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "bitwise_and '&' shift_expr")); @@ -11781,7 +12726,7 @@ bitwise_and_raw(Parser *p) D(fprintf(stderr, "%*c+ bitwise_and[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_and '&' shift_expr")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -11791,7 +12736,7 @@ bitwise_and_raw(Parser *p) _res = _PyAST_BinOp ( a , BitAnd , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -11802,7 +12747,7 @@ bitwise_and_raw(Parser *p) } { // shift_expr if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> bitwise_and[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "shift_expr")); @@ -11821,7 +12766,7 @@ bitwise_and_raw(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -11831,10 +12776,13 @@ static expr_ty shift_expr_raw(Parser *); static expr_ty shift_expr_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, shift_expr_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; @@ -11842,37 +12790,40 @@ shift_expr_rule(Parser *p) while (1) { int tmpvar_5 = _PyPegen_update_memo(p, _mark, shift_expr_type, _res); if (tmpvar_5) { - D(p->level--); + p->level--; return _res; } p->mark = _mark; - p->in_raw_rule++; void *_raw = shift_expr_raw(p); - p->in_raw_rule--; - if (p->error_indicator) + if (p->error_indicator) { + p->level--; return NULL; + } if (_raw == NULL || p->mark <= _resmark) break; _resmark = p->mark; _res = _raw; } p->mark = _resmark; - D(p->level--); + p->level--; return _res; } static expr_ty shift_expr_raw(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -11881,7 +12832,7 @@ shift_expr_raw(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // shift_expr '<<' sum if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> shift_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "shift_expr '<<' sum")); @@ -11899,7 +12850,7 @@ shift_expr_raw(Parser *p) D(fprintf(stderr, "%*c+ shift_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "shift_expr '<<' sum")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -11909,7 +12860,7 @@ shift_expr_raw(Parser *p) _res = _PyAST_BinOp ( a , LShift , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -11920,7 +12871,7 @@ shift_expr_raw(Parser *p) } { // shift_expr '>>' sum if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> shift_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "shift_expr '>>' sum")); @@ -11938,7 +12889,7 @@ shift_expr_raw(Parser *p) D(fprintf(stderr, "%*c+ shift_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "shift_expr '>>' sum")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -11948,7 +12899,7 @@ shift_expr_raw(Parser *p) _res = _PyAST_BinOp ( a , RShift , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -11959,7 +12910,7 @@ shift_expr_raw(Parser *p) } { // sum if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> shift_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "sum")); @@ -11978,7 +12929,7 @@ shift_expr_raw(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -11988,10 +12939,13 @@ static expr_ty sum_raw(Parser *); static expr_ty sum_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, sum_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; @@ -11999,37 +12953,40 @@ sum_rule(Parser *p) while (1) { int tmpvar_6 = _PyPegen_update_memo(p, _mark, sum_type, _res); if (tmpvar_6) { - D(p->level--); + p->level--; return _res; } p->mark = _mark; - p->in_raw_rule++; void *_raw = sum_raw(p); - p->in_raw_rule--; - if (p->error_indicator) + if (p->error_indicator) { + p->level--; return NULL; + } if (_raw == NULL || p->mark <= _resmark) break; _resmark = p->mark; _res = _raw; } p->mark = _resmark; - D(p->level--); + p->level--; return _res; } static expr_ty sum_raw(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -12038,7 +12995,7 @@ sum_raw(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // sum '+' term if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> sum[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "sum '+' term")); @@ -12056,7 +13013,7 @@ sum_raw(Parser *p) D(fprintf(stderr, "%*c+ sum[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "sum '+' term")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -12066,7 +13023,7 @@ sum_raw(Parser *p) _res = _PyAST_BinOp ( a , Add , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -12077,7 +13034,7 @@ sum_raw(Parser *p) } { // sum '-' term if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> sum[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "sum '-' term")); @@ -12095,7 +13052,7 @@ sum_raw(Parser *p) D(fprintf(stderr, "%*c+ sum[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "sum '-' term")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -12105,7 +13062,7 @@ sum_raw(Parser *p) _res = _PyAST_BinOp ( a , Sub , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -12116,7 +13073,7 @@ sum_raw(Parser *p) } { // term if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> sum[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term")); @@ -12135,7 +13092,7 @@ sum_raw(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -12151,10 +13108,13 @@ static expr_ty term_raw(Parser *); static expr_ty term_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, term_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; @@ -12162,37 +13122,40 @@ term_rule(Parser *p) while (1) { int tmpvar_7 = _PyPegen_update_memo(p, _mark, term_type, _res); if (tmpvar_7) { - D(p->level--); + p->level--; return _res; } p->mark = _mark; - p->in_raw_rule++; void *_raw = term_raw(p); - p->in_raw_rule--; - if (p->error_indicator) + if (p->error_indicator) { + p->level--; return NULL; + } if (_raw == NULL || p->mark <= _resmark) break; _resmark = p->mark; _res = _raw; } p->mark = _resmark; - D(p->level--); + p->level--; return _res; } static expr_ty term_raw(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -12201,7 +13164,7 @@ term_raw(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // term '*' factor if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '*' factor")); @@ -12219,7 +13182,7 @@ term_raw(Parser *p) D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '*' factor")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -12229,7 +13192,7 @@ term_raw(Parser *p) _res = _PyAST_BinOp ( a , Mult , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -12240,7 +13203,7 @@ term_raw(Parser *p) } { // term '/' factor if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '/' factor")); @@ -12258,7 +13221,7 @@ term_raw(Parser *p) D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '/' factor")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -12268,7 +13231,7 @@ term_raw(Parser *p) _res = _PyAST_BinOp ( a , Div , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -12279,7 +13242,7 @@ term_raw(Parser *p) } { // term '//' factor if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '//' factor")); @@ -12297,7 +13260,7 @@ term_raw(Parser *p) D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '//' factor")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -12307,7 +13270,7 @@ term_raw(Parser *p) _res = _PyAST_BinOp ( a , FloorDiv , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -12318,7 +13281,7 @@ term_raw(Parser *p) } { // term '%' factor if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '%' factor")); @@ -12336,7 +13299,7 @@ term_raw(Parser *p) D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '%' factor")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -12346,7 +13309,7 @@ term_raw(Parser *p) _res = _PyAST_BinOp ( a , Mod , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -12357,7 +13320,7 @@ term_raw(Parser *p) } { // term '@' factor if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "term '@' factor")); @@ -12375,7 +13338,7 @@ term_raw(Parser *p) D(fprintf(stderr, "%*c+ term[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "term '@' factor")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -12385,7 +13348,7 @@ term_raw(Parser *p) _res = CHECK_VERSION ( expr_ty , 5 , "The '@' operator is" , _PyAST_BinOp ( a , MatMult , b , EXTRA ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -12396,7 +13359,7 @@ term_raw(Parser *p) } { // factor if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> term[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "factor")); @@ -12415,7 +13378,7 @@ term_raw(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -12423,20 +13386,23 @@ term_raw(Parser *p) static expr_ty factor_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, factor_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -12445,7 +13411,7 @@ factor_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '+' factor if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+' factor")); @@ -12460,7 +13426,7 @@ factor_rule(Parser *p) D(fprintf(stderr, "%*c+ factor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+' factor")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -12470,7 +13436,7 @@ factor_rule(Parser *p) _res = _PyAST_UnaryOp ( UAdd , a , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -12481,7 +13447,7 @@ factor_rule(Parser *p) } { // '-' factor if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-' factor")); @@ -12496,7 +13462,7 @@ factor_rule(Parser *p) D(fprintf(stderr, "%*c+ factor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-' factor")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -12506,7 +13472,7 @@ factor_rule(Parser *p) _res = _PyAST_UnaryOp ( USub , a , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -12517,7 +13483,7 @@ factor_rule(Parser *p) } { // '~' factor if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'~' factor")); @@ -12532,7 +13498,7 @@ factor_rule(Parser *p) D(fprintf(stderr, "%*c+ factor[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'~' factor")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -12542,7 +13508,7 @@ factor_rule(Parser *p) _res = _PyAST_UnaryOp ( Invert , a , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -12553,7 +13519,7 @@ factor_rule(Parser *p) } { // power if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> factor[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "power")); @@ -12573,7 +13539,7 @@ factor_rule(Parser *p) _res = NULL; done: _PyPegen_insert_memo(p, _mark, factor_type, _res); - D(p->level--); + p->level--; return _res; } @@ -12581,16 +13547,19 @@ factor_rule(Parser *p) static expr_ty power_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -12599,7 +13568,7 @@ power_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // await_primary '**' factor if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> power[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "await_primary '**' factor")); @@ -12617,7 +13586,7 @@ power_rule(Parser *p) D(fprintf(stderr, "%*c+ power[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "await_primary '**' factor")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -12627,7 +13596,7 @@ power_rule(Parser *p) _res = _PyAST_BinOp ( a , Pow , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -12638,7 +13607,7 @@ power_rule(Parser *p) } { // await_primary if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> power[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "await_primary")); @@ -12657,7 +13626,7 @@ power_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -12665,20 +13634,23 @@ power_rule(Parser *p) static expr_ty await_primary_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, await_primary_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -12687,7 +13659,7 @@ await_primary_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // AWAIT primary if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> await_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "AWAIT primary")); @@ -12702,7 +13674,7 @@ await_primary_rule(Parser *p) D(fprintf(stderr, "%*c+ await_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "AWAIT primary")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -12712,7 +13684,7 @@ await_primary_rule(Parser *p) _res = CHECK_VERSION ( expr_ty , 5 , "Await expressions are" , _PyAST_Await ( a , EXTRA ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -12723,7 +13695,7 @@ await_primary_rule(Parser *p) } { // primary if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> await_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary")); @@ -12743,7 +13715,7 @@ await_primary_rule(Parser *p) _res = NULL; done: _PyPegen_insert_memo(p, _mark, await_primary_type, _res); - D(p->level--); + p->level--; return _res; } @@ -12758,10 +13730,13 @@ static expr_ty primary_raw(Parser *); static expr_ty primary_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, primary_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; @@ -12769,37 +13744,40 @@ primary_rule(Parser *p) while (1) { int tmpvar_8 = _PyPegen_update_memo(p, _mark, primary_type, _res); if (tmpvar_8) { - D(p->level--); + p->level--; return _res; } p->mark = _mark; - p->in_raw_rule++; void *_raw = primary_raw(p); - p->in_raw_rule--; - if (p->error_indicator) + if (p->error_indicator) { + p->level--; return NULL; + } if (_raw == NULL || p->mark <= _resmark) break; _resmark = p->mark; _res = _raw; } p->mark = _resmark; - D(p->level--); + p->level--; return _res; } static expr_ty primary_raw(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -12808,7 +13786,7 @@ primary_raw(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // primary '.' NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary '.' NAME")); @@ -12826,7 +13804,7 @@ primary_raw(Parser *p) D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary '.' NAME")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -12836,7 +13814,7 @@ primary_raw(Parser *p) _res = _PyAST_Attribute ( a , b -> v . Name . id , Load , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -12847,7 +13825,7 @@ primary_raw(Parser *p) } { // primary genexp if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary genexp")); @@ -12862,7 +13840,7 @@ primary_raw(Parser *p) D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary genexp")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -12872,7 +13850,7 @@ primary_raw(Parser *p) _res = _PyAST_Call ( a , CHECK ( asdl_expr_seq* , ( asdl_expr_seq* ) _PyPegen_singleton_seq ( p , b ) ) , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -12883,7 +13861,7 @@ primary_raw(Parser *p) } { // primary '(' arguments? ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary '(' arguments? ')'")); @@ -12904,7 +13882,7 @@ primary_raw(Parser *p) D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary '(' arguments? ')'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -12914,7 +13892,7 @@ primary_raw(Parser *p) _res = _PyAST_Call ( a , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -12925,7 +13903,7 @@ primary_raw(Parser *p) } { // primary '[' slices ']' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "primary '[' slices ']'")); @@ -12946,7 +13924,7 @@ primary_raw(Parser *p) D(fprintf(stderr, "%*c+ primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "primary '[' slices ']'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -12956,7 +13934,7 @@ primary_raw(Parser *p) _res = _PyAST_Subscript ( a , b , Load , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -12967,7 +13945,7 @@ primary_raw(Parser *p) } { // atom if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "atom")); @@ -12986,24 +13964,27 @@ primary_raw(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// slices: slice !',' | ','.slice+ ','? +// slices: slice !',' | ','.(slice | starred_expression)+ ','? static expr_ty slices_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -13012,7 +13993,7 @@ slices_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // slice !',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> slices[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice !','")); @@ -13027,7 +14008,7 @@ slices_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13036,25 +14017,25 @@ slices_rule(Parser *p) D(fprintf(stderr, "%*c%s slices[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slice !','")); } - { // ','.slice+ ','? + { // ','.(slice | starred_expression)+ ','? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> slices[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.slice+ ','?")); + D(fprintf(stderr, "%*c> slices[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.(slice | starred_expression)+ ','?")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_85_rule(p)) // ','.slice+ + (a = (asdl_expr_seq*)_gather_88_rule(p)) // ','.(slice | starred_expression)+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) { - D(fprintf(stderr, "%*c+ slices[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.slice+ ','?")); + D(fprintf(stderr, "%*c+ slices[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(slice | starred_expression)+ ','?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -13064,18 +14045,18 @@ slices_rule(Parser *p) _res = _PyAST_Tuple ( a , Load , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s slices[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.slice+ ','?")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.(slice | starred_expression)+ ','?")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -13083,16 +14064,19 @@ slices_rule(Parser *p) static expr_ty slice_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -13101,7 +14085,7 @@ slice_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // expression? ':' expression? [':' expression?] if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> slice[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression? ':' expression? [':' expression?]")); @@ -13116,13 +14100,13 @@ slice_rule(Parser *p) && (b = expression_rule(p), !p->error_indicator) // expression? && - (c = _tmp_87_rule(p), !p->error_indicator) // [':' expression?] + (c = _tmp_90_rule(p), !p->error_indicator) // [':' expression?] ) { D(fprintf(stderr, "%*c+ slice[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression? ':' expression? [':' expression?]")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -13132,7 +14116,7 @@ slice_rule(Parser *p) _res = _PyAST_Slice ( a , b , c , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13143,7 +14127,7 @@ slice_rule(Parser *p) } { // named_expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> slice[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression")); @@ -13156,7 +14140,7 @@ slice_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13167,7 +14151,7 @@ slice_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -13185,16 +14169,19 @@ slice_rule(Parser *p) static expr_ty atom_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -13203,7 +14190,7 @@ atom_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); @@ -13222,19 +14209,19 @@ atom_rule(Parser *p) } { // 'True' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 597)) // token='True' + (_keyword = _PyPegen_expect_token(p, 600)) // token='True' ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -13244,7 +14231,7 @@ atom_rule(Parser *p) _res = _PyAST_Constant ( Py_True , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13255,19 +14242,19 @@ atom_rule(Parser *p) } { // 'False' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 599)) // token='False' + (_keyword = _PyPegen_expect_token(p, 602)) // token='False' ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -13277,7 +14264,7 @@ atom_rule(Parser *p) _res = _PyAST_Constant ( Py_False , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13288,19 +14275,19 @@ atom_rule(Parser *p) } { // 'None' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 598)) // token='None' + (_keyword = _PyPegen_expect_token(p, 601)) // token='None' ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -13310,7 +14297,7 @@ atom_rule(Parser *p) _res = _PyAST_Constant ( Py_None , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13321,7 +14308,7 @@ atom_rule(Parser *p) } { // &STRING strings if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&STRING strings")); @@ -13342,7 +14329,7 @@ atom_rule(Parser *p) } { // NUMBER if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NUMBER")); @@ -13361,19 +14348,19 @@ atom_rule(Parser *p) } { // &'(' (tuple | group | genexp) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'(' (tuple | group | genexp)")); - void *_tmp_88_var; + void *_tmp_91_var; if ( _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 7) // token='(' && - (_tmp_88_var = _tmp_88_rule(p)) // tuple | group | genexp + (_tmp_91_var = _tmp_91_rule(p)) // tuple | group | genexp ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'(' (tuple | group | genexp)")); - _res = _tmp_88_var; + _res = _tmp_91_var; goto done; } p->mark = _mark; @@ -13382,19 +14369,19 @@ atom_rule(Parser *p) } { // &'[' (list | listcomp) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'[' (list | listcomp)")); - void *_tmp_89_var; + void *_tmp_92_var; if ( _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 9) // token='[' && - (_tmp_89_var = _tmp_89_rule(p)) // list | listcomp + (_tmp_92_var = _tmp_92_rule(p)) // list | listcomp ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'[' (list | listcomp)")); - _res = _tmp_89_var; + _res = _tmp_92_var; goto done; } p->mark = _mark; @@ -13403,19 +14390,19 @@ atom_rule(Parser *p) } { // &'{' (dict | set | dictcomp | setcomp) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'{' (dict | set | dictcomp | setcomp)")); - void *_tmp_90_var; + void *_tmp_93_var; if ( _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 25) // token='{' && - (_tmp_90_var = _tmp_90_rule(p)) // dict | set | dictcomp | setcomp + (_tmp_93_var = _tmp_93_rule(p)) // dict | set | dictcomp | setcomp ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'{' (dict | set | dictcomp | setcomp)")); - _res = _tmp_90_var; + _res = _tmp_93_var; goto done; } p->mark = _mark; @@ -13424,7 +14411,7 @@ atom_rule(Parser *p) } { // '...' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); @@ -13436,7 +14423,7 @@ atom_rule(Parser *p) D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -13446,7 +14433,7 @@ atom_rule(Parser *p) _res = _PyAST_Constant ( Py_Ellipsis , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13457,7 +14444,7 @@ atom_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -13465,16 +14452,19 @@ atom_rule(Parser *p) static expr_ty group_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; { // '(' (yield_expr | named_expression) ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> group[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' (yield_expr | named_expression) ')'")); @@ -13484,7 +14474,7 @@ group_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = _tmp_91_rule(p)) // yield_expr | named_expression + (a = _tmp_94_rule(p)) // yield_expr | named_expression && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) @@ -13493,7 +14483,7 @@ group_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13504,7 +14494,7 @@ group_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_group if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> group[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_group")); @@ -13523,7 +14513,7 @@ group_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -13531,16 +14521,19 @@ group_rule(Parser *p) static expr_ty lambdef_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -13549,7 +14542,7 @@ lambdef_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // 'lambda' lambda_params? ':' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambdef[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' expression")); @@ -13558,7 +14551,7 @@ lambdef_rule(Parser *p) void *a; expr_ty b; if ( - (_keyword = _PyPegen_expect_token(p, 583)) // token='lambda' + (_keyword = _PyPegen_expect_token(p, 586)) // token='lambda' && (a = lambda_params_rule(p), !p->error_indicator) // lambda_params? && @@ -13570,7 +14563,7 @@ lambdef_rule(Parser *p) D(fprintf(stderr, "%*c+ lambdef[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' expression")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -13580,7 +14573,7 @@ lambdef_rule(Parser *p) _res = _PyAST_Lambda ( ( a ) ? a : CHECK ( arguments_ty , _PyPegen_empty_arguments ( p ) ) , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13591,7 +14584,7 @@ lambdef_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -13599,16 +14592,19 @@ lambdef_rule(Parser *p) static arguments_ty lambda_params_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } arguments_ty _res = NULL; int _mark = p->mark; if (p->call_invalid_rules) { // invalid_lambda_parameters if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_lambda_parameters")); @@ -13627,7 +14623,7 @@ lambda_params_rule(Parser *p) } { // lambda_parameters if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_parameters")); @@ -13646,7 +14642,7 @@ lambda_params_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -13659,16 +14655,19 @@ lambda_params_rule(Parser *p) static arguments_ty lambda_parameters_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } arguments_ty _res = NULL; int _mark = p->mark; { // lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc?")); @@ -13679,18 +14678,18 @@ lambda_parameters_rule(Parser *p) if ( (a = lambda_slash_no_default_rule(p)) // lambda_slash_no_default && - (b = (asdl_arg_seq*)_loop0_92_rule(p)) // lambda_param_no_default* + (b = (asdl_arg_seq*)_loop0_95_rule(p)) // lambda_param_no_default* && - (c = _loop0_93_rule(p)) // lambda_param_with_default* + (c = _loop0_96_rule(p)) // lambda_param_with_default* && (d = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? ) { D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default lambda_param_no_default* lambda_param_with_default* lambda_star_etc?")); - _res = _PyPegen_make_arguments ( p , a , NULL , b , c , d ); + _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , a , NULL , b , c , d ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13701,7 +14700,7 @@ lambda_parameters_rule(Parser *p) } { // lambda_slash_with_default lambda_param_with_default* lambda_star_etc? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default lambda_param_with_default* lambda_star_etc?")); @@ -13711,16 +14710,16 @@ lambda_parameters_rule(Parser *p) if ( (a = lambda_slash_with_default_rule(p)) // lambda_slash_with_default && - (b = _loop0_94_rule(p)) // lambda_param_with_default* + (b = _loop0_97_rule(p)) // lambda_param_with_default* && (c = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? ) { D(fprintf(stderr, "%*c+ lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default lambda_param_with_default* lambda_star_etc?")); - _res = _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ); + _res = CHECK_VERSION ( arguments_ty , 8 , "Positional-only parameters are" , _PyPegen_make_arguments ( p , NULL , a , NULL , b , c ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13731,7 +14730,7 @@ lambda_parameters_rule(Parser *p) } { // lambda_param_no_default+ lambda_param_with_default* lambda_star_etc? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ lambda_param_with_default* lambda_star_etc?")); @@ -13739,9 +14738,9 @@ lambda_parameters_rule(Parser *p) asdl_seq * b; void *c; if ( - (a = (asdl_arg_seq*)_loop1_95_rule(p)) // lambda_param_no_default+ + (a = (asdl_arg_seq*)_loop1_98_rule(p)) // lambda_param_no_default+ && - (b = _loop0_96_rule(p)) // lambda_param_with_default* + (b = _loop0_99_rule(p)) // lambda_param_with_default* && (c = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? ) @@ -13750,7 +14749,7 @@ lambda_parameters_rule(Parser *p) _res = _PyPegen_make_arguments ( p , NULL , NULL , a , b , c ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13761,14 +14760,14 @@ lambda_parameters_rule(Parser *p) } { // lambda_param_with_default+ lambda_star_etc? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+ lambda_star_etc?")); asdl_seq * a; void *b; if ( - (a = _loop1_97_rule(p)) // lambda_param_with_default+ + (a = _loop1_100_rule(p)) // lambda_param_with_default+ && (b = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? ) @@ -13777,7 +14776,7 @@ lambda_parameters_rule(Parser *p) _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13788,7 +14787,7 @@ lambda_parameters_rule(Parser *p) } { // lambda_star_etc if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_star_etc")); @@ -13801,7 +14800,7 @@ lambda_parameters_rule(Parser *p) _res = _PyPegen_make_arguments ( p , NULL , NULL , NULL , NULL , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13812,7 +14811,7 @@ lambda_parameters_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -13822,16 +14821,19 @@ lambda_parameters_rule(Parser *p) static asdl_arg_seq* lambda_slash_no_default_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_arg_seq* _res = NULL; int _mark = p->mark; { // lambda_param_no_default+ '/' ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ '/' ','")); @@ -13839,7 +14841,7 @@ lambda_slash_no_default_rule(Parser *p) Token * _literal_1; asdl_arg_seq* a; if ( - (a = (asdl_arg_seq*)_loop1_98_rule(p)) // lambda_param_no_default+ + (a = (asdl_arg_seq*)_loop1_101_rule(p)) // lambda_param_no_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -13850,7 +14852,7 @@ lambda_slash_no_default_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13861,14 +14863,14 @@ lambda_slash_no_default_rule(Parser *p) } { // lambda_param_no_default+ '/' &':' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_slash_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default+ '/' &':'")); Token * _literal; asdl_arg_seq* a; if ( - (a = (asdl_arg_seq*)_loop1_99_rule(p)) // lambda_param_no_default+ + (a = (asdl_arg_seq*)_loop1_102_rule(p)) // lambda_param_no_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -13879,7 +14881,7 @@ lambda_slash_no_default_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13890,7 +14892,7 @@ lambda_slash_no_default_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -13900,16 +14902,19 @@ lambda_slash_no_default_rule(Parser *p) static SlashWithDefault* lambda_slash_with_default_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } SlashWithDefault* _res = NULL; int _mark = p->mark; { // lambda_param_no_default* lambda_param_with_default+ '/' ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_slash_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' ','")); @@ -13918,9 +14923,9 @@ lambda_slash_with_default_rule(Parser *p) asdl_seq * a; asdl_seq * b; if ( - (a = _loop0_100_rule(p)) // lambda_param_no_default* + (a = _loop0_103_rule(p)) // lambda_param_no_default* && - (b = _loop1_101_rule(p)) // lambda_param_with_default+ + (b = _loop1_104_rule(p)) // lambda_param_with_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -13931,7 +14936,7 @@ lambda_slash_with_default_rule(Parser *p) _res = _PyPegen_slash_with_default ( p , ( asdl_arg_seq* ) a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13942,7 +14947,7 @@ lambda_slash_with_default_rule(Parser *p) } { // lambda_param_no_default* lambda_param_with_default+ '/' &':' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_slash_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* lambda_param_with_default+ '/' &':'")); @@ -13950,9 +14955,9 @@ lambda_slash_with_default_rule(Parser *p) asdl_seq * a; asdl_seq * b; if ( - (a = _loop0_102_rule(p)) // lambda_param_no_default* + (a = _loop0_105_rule(p)) // lambda_param_no_default* && - (b = _loop1_103_rule(p)) // lambda_param_with_default+ + (b = _loop1_106_rule(p)) // lambda_param_with_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -13963,7 +14968,7 @@ lambda_slash_with_default_rule(Parser *p) _res = _PyPegen_slash_with_default ( p , ( asdl_arg_seq* ) a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -13974,118 +14979,31 @@ lambda_slash_with_default_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } // lambda_star_etc: +// | invalid_lambda_star_etc // | '*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds? // | '*' ',' lambda_param_maybe_default+ lambda_kwds? // | lambda_kwds -// | invalid_lambda_star_etc static StarEtc* lambda_star_etc_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } StarEtc* _res = NULL; int _mark = p->mark; - { // '*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds? - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds?")); - Token * _literal; - arg_ty a; - asdl_seq * b; - void *c; - if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - && - (a = lambda_param_no_default_rule(p)) // lambda_param_no_default - && - (b = _loop0_104_rule(p)) // lambda_param_maybe_default* - && - (c = lambda_kwds_rule(p), !p->error_indicator) // lambda_kwds? - ) - { - D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds?")); - _res = _PyPegen_star_etc ( p , a , b , c ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - D(p->level--); - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds?")); - } - { // '*' ',' lambda_param_maybe_default+ lambda_kwds? - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' ',' lambda_param_maybe_default+ lambda_kwds?")); - Token * _literal; - Token * _literal_1; - asdl_seq * b; - void *c; - if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' - && - (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' - && - (b = _loop1_105_rule(p)) // lambda_param_maybe_default+ - && - (c = lambda_kwds_rule(p), !p->error_indicator) // lambda_kwds? - ) - { - D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' ',' lambda_param_maybe_default+ lambda_kwds?")); - _res = _PyPegen_star_etc ( p , NULL , b , c ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - D(p->level--); - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' ',' lambda_param_maybe_default+ lambda_kwds?")); - } - { // lambda_kwds - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_kwds")); - arg_ty a; - if ( - (a = lambda_kwds_rule(p)) // lambda_kwds - ) - { - D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_kwds")); - _res = _PyPegen_star_etc ( p , NULL , NULL , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - D(p->level--); - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_kwds")); - } if (p->call_invalid_rules) { // invalid_lambda_star_etc if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_lambda_star_etc")); @@ -14102,26 +15020,138 @@ lambda_star_etc_rule(Parser *p) D(fprintf(stderr, "%*c%s lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_lambda_star_etc")); } + { // '*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds?")); + Token * _literal; + arg_ty a; + asdl_seq * b; + void *c; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (a = lambda_param_no_default_rule(p)) // lambda_param_no_default + && + (b = _loop0_107_rule(p)) // lambda_param_maybe_default* + && + (c = lambda_kwds_rule(p), !p->error_indicator) // lambda_kwds? + ) + { + D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds?")); + _res = _PyPegen_star_etc ( p , a , b , c ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds?")); + } + { // '*' ',' lambda_param_maybe_default+ lambda_kwds? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' ',' lambda_param_maybe_default+ lambda_kwds?")); + Token * _literal; + Token * _literal_1; + asdl_seq * b; + void *c; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && + (b = _loop1_108_rule(p)) // lambda_param_maybe_default+ + && + (c = lambda_kwds_rule(p), !p->error_indicator) // lambda_kwds? + ) + { + D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' ',' lambda_param_maybe_default+ lambda_kwds?")); + _res = _PyPegen_star_etc ( p , NULL , b , c ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' ',' lambda_param_maybe_default+ lambda_kwds?")); + } + { // lambda_kwds + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_kwds")); + arg_ty a; + if ( + (a = lambda_kwds_rule(p)) // lambda_kwds + ) + { + D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_kwds")); + _res = _PyPegen_star_etc ( p , NULL , NULL , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_kwds")); + } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// lambda_kwds: '**' lambda_param_no_default +// lambda_kwds: invalid_lambda_kwds | '**' lambda_param_no_default static arg_ty lambda_kwds_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } arg_ty _res = NULL; int _mark = p->mark; + if (p->call_invalid_rules) { // invalid_lambda_kwds + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_lambda_kwds")); + void *invalid_lambda_kwds_var; + if ( + (invalid_lambda_kwds_var = invalid_lambda_kwds_rule(p)) // invalid_lambda_kwds + ) + { + D(fprintf(stderr, "%*c+ lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_lambda_kwds")); + _res = invalid_lambda_kwds_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_lambda_kwds")); + } { // '**' lambda_param_no_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' lambda_param_no_default")); @@ -14137,7 +15167,7 @@ lambda_kwds_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14148,7 +15178,7 @@ lambda_kwds_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -14156,16 +15186,19 @@ lambda_kwds_rule(Parser *p) static arg_ty lambda_param_no_default_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } arg_ty _res = NULL; int _mark = p->mark; { // lambda_param ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_param_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param ','")); @@ -14181,7 +15214,7 @@ lambda_param_no_default_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14192,7 +15225,7 @@ lambda_param_no_default_rule(Parser *p) } { // lambda_param &':' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_param_no_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param &':'")); @@ -14207,7 +15240,7 @@ lambda_param_no_default_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14218,7 +15251,7 @@ lambda_param_no_default_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -14226,16 +15259,19 @@ lambda_param_no_default_rule(Parser *p) static NameDefaultPair* lambda_param_with_default_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } NameDefaultPair* _res = NULL; int _mark = p->mark; { // lambda_param default ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_param_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param default ','")); @@ -14254,7 +15290,7 @@ lambda_param_with_default_rule(Parser *p) _res = _PyPegen_name_default_pair ( p , a , c , NULL ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14265,7 +15301,7 @@ lambda_param_with_default_rule(Parser *p) } { // lambda_param default &':' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_param_with_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param default &':'")); @@ -14283,7 +15319,7 @@ lambda_param_with_default_rule(Parser *p) _res = _PyPegen_name_default_pair ( p , a , c , NULL ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14294,7 +15330,7 @@ lambda_param_with_default_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -14302,16 +15338,19 @@ lambda_param_with_default_rule(Parser *p) static NameDefaultPair* lambda_param_maybe_default_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } NameDefaultPair* _res = NULL; int _mark = p->mark; { // lambda_param default? ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_param_maybe_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param default? ','")); @@ -14330,7 +15369,7 @@ lambda_param_maybe_default_rule(Parser *p) _res = _PyPegen_name_default_pair ( p , a , c , NULL ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14341,7 +15380,7 @@ lambda_param_maybe_default_rule(Parser *p) } { // lambda_param default? &':' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_param_maybe_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param default? &':'")); @@ -14359,7 +15398,7 @@ lambda_param_maybe_default_rule(Parser *p) _res = _PyPegen_name_default_pair ( p , a , c , NULL ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14370,7 +15409,7 @@ lambda_param_maybe_default_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -14378,16 +15417,19 @@ lambda_param_maybe_default_rule(Parser *p) static arg_ty lambda_param_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } arg_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -14396,7 +15438,7 @@ lambda_param_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> lambda_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); @@ -14408,7 +15450,7 @@ lambda_param_rule(Parser *p) D(fprintf(stderr, "%*c+ lambda_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -14418,7 +15460,7 @@ lambda_param_rule(Parser *p) _res = _PyAST_arg ( a -> v . Name . id , NULL , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14429,7 +15471,7 @@ lambda_param_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -14437,33 +15479,36 @@ lambda_param_rule(Parser *p) static expr_ty strings_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, strings_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; { // STRING+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> strings[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING+")); asdl_seq * a; if ( - (a = _loop1_106_rule(p)) // STRING+ + (a = _loop1_109_rule(p)) // STRING+ ) { D(fprintf(stderr, "%*c+ strings[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "STRING+")); _res = _PyPegen_concatenate_strings ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14475,7 +15520,7 @@ strings_rule(Parser *p) _res = NULL; done: _PyPegen_insert_memo(p, _mark, strings_type, _res); - D(p->level--); + p->level--; return _res; } @@ -14483,16 +15528,19 @@ strings_rule(Parser *p) static expr_ty list_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -14501,7 +15549,7 @@ list_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '[' star_named_expressions? ']' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> list[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' star_named_expressions? ']'")); @@ -14519,7 +15567,7 @@ list_rule(Parser *p) D(fprintf(stderr, "%*c+ list[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' star_named_expressions? ']'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -14529,7 +15577,7 @@ list_rule(Parser *p) _res = _PyAST_List ( a , Load , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14540,7 +15588,7 @@ list_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -14548,16 +15596,19 @@ list_rule(Parser *p) static expr_ty tuple_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -14566,7 +15617,7 @@ tuple_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '(' [star_named_expression ',' star_named_expressions?] ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> tuple[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' [star_named_expression ',' star_named_expressions?] ')'")); @@ -14576,7 +15627,7 @@ tuple_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = _tmp_107_rule(p), !p->error_indicator) // [star_named_expression ',' star_named_expressions?] + (a = _tmp_110_rule(p), !p->error_indicator) // [star_named_expression ',' star_named_expressions?] && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) @@ -14584,7 +15635,7 @@ tuple_rule(Parser *p) D(fprintf(stderr, "%*c+ tuple[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' [star_named_expression ',' star_named_expressions?] ')'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -14594,7 +15645,7 @@ tuple_rule(Parser *p) _res = _PyAST_Tuple ( a , Load , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14605,7 +15656,7 @@ tuple_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -14613,16 +15664,19 @@ tuple_rule(Parser *p) static expr_ty set_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -14631,7 +15685,7 @@ set_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '{' star_named_expressions '}' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> set[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' star_named_expressions '}'")); @@ -14649,7 +15703,7 @@ set_rule(Parser *p) D(fprintf(stderr, "%*c+ set[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' star_named_expressions '}'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -14659,7 +15713,7 @@ set_rule(Parser *p) _res = _PyAST_Set ( a , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14670,7 +15724,7 @@ set_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -14678,16 +15732,19 @@ set_rule(Parser *p) static expr_ty dict_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -14696,7 +15753,7 @@ dict_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '{' double_starred_kvpairs? '}' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> dict[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' double_starred_kvpairs? '}'")); @@ -14714,7 +15771,7 @@ dict_rule(Parser *p) D(fprintf(stderr, "%*c+ dict[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' double_starred_kvpairs? '}'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -14724,7 +15781,7 @@ dict_rule(Parser *p) _res = _PyAST_Dict ( CHECK ( asdl_expr_seq* , _PyPegen_get_keys ( p , a ) ) , CHECK ( asdl_expr_seq* , _PyPegen_get_values ( p , a ) ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14735,7 +15792,7 @@ dict_rule(Parser *p) } { // '{' invalid_double_starred_kvpairs '}' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> dict[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' invalid_double_starred_kvpairs '}'")); @@ -14760,7 +15817,7 @@ dict_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -14768,16 +15825,19 @@ dict_rule(Parser *p) static asdl_seq* double_starred_kvpairs_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq* _res = NULL; int _mark = p->mark; { // ','.double_starred_kvpair+ ','? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> double_starred_kvpairs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ','?")); @@ -14785,7 +15845,7 @@ double_starred_kvpairs_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_seq * a; if ( - (a = _gather_108_rule(p)) // ','.double_starred_kvpair+ + (a = _gather_111_rule(p)) // ','.double_starred_kvpair+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -14794,7 +15854,7 @@ double_starred_kvpairs_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14805,7 +15865,7 @@ double_starred_kvpairs_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -14813,16 +15873,19 @@ double_starred_kvpairs_rule(Parser *p) static KeyValuePair* double_starred_kvpair_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } KeyValuePair* _res = NULL; int _mark = p->mark; { // '**' bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> double_starred_kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' bitwise_or")); @@ -14838,7 +15901,7 @@ double_starred_kvpair_rule(Parser *p) _res = _PyPegen_key_value_pair ( p , NULL , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14849,7 +15912,7 @@ double_starred_kvpair_rule(Parser *p) } { // kvpair if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> double_starred_kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kvpair")); @@ -14868,7 +15931,7 @@ double_starred_kvpair_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -14876,16 +15939,19 @@ double_starred_kvpair_rule(Parser *p) static KeyValuePair* kvpair_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } KeyValuePair* _res = NULL; int _mark = p->mark; { // expression ':' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':' expression")); @@ -14904,7 +15970,7 @@ kvpair_rule(Parser *p) _res = _PyPegen_key_value_pair ( p , a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14915,7 +15981,7 @@ kvpair_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -14923,29 +15989,32 @@ kvpair_rule(Parser *p) static asdl_comprehension_seq* for_if_clauses_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_comprehension_seq* _res = NULL; int _mark = p->mark; { // for_if_clause+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> for_if_clauses[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "for_if_clause+")); asdl_comprehension_seq* a; if ( - (a = (asdl_comprehension_seq*)_loop1_110_rule(p)) // for_if_clause+ + (a = (asdl_comprehension_seq*)_loop1_113_rule(p)) // for_if_clause+ ) { D(fprintf(stderr, "%*c+ for_if_clauses[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "for_if_clause+")); _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -14956,7 +16025,7 @@ for_if_clauses_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -14967,16 +16036,19 @@ for_if_clauses_rule(Parser *p) static comprehension_ty for_if_clause_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } comprehension_ty _res = NULL; int _mark = p->mark; { // ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))* if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> for_if_clause[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); @@ -14990,24 +16062,24 @@ for_if_clause_rule(Parser *p) if ( (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' && - (_keyword = _PyPegen_expect_token(p, 633)) // token='for' + (_keyword = _PyPegen_expect_token(p, 649)) // token='for' && (a = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 634)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 650)) // token='in' && (_cut_var = 1) && (b = disjunction_rule(p)) // disjunction && - (c = (asdl_expr_seq*)_loop0_111_rule(p)) // (('if' disjunction))* + (c = (asdl_expr_seq*)_loop0_114_rule(p)) // (('if' disjunction))* ) { D(fprintf(stderr, "%*c+ for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); _res = CHECK_VERSION ( comprehension_ty , 6 , "Async comprehensions are" , _PyAST_comprehension ( a , b , c , 1 , p -> arena ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -15016,13 +16088,13 @@ for_if_clause_rule(Parser *p) D(fprintf(stderr, "%*c%s for_if_clause[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); if (_cut_var) { - D(p->level--); + p->level--; return NULL; } } { // 'for' star_targets 'in' ~ disjunction (('if' disjunction))* if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> for_if_clause[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); @@ -15033,24 +16105,24 @@ for_if_clause_rule(Parser *p) expr_ty b; asdl_expr_seq* c; if ( - (_keyword = _PyPegen_expect_token(p, 633)) // token='for' + (_keyword = _PyPegen_expect_token(p, 649)) // token='for' && (a = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 634)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 650)) // token='in' && (_cut_var = 1) && (b = disjunction_rule(p)) // disjunction && - (c = (asdl_expr_seq*)_loop0_112_rule(p)) // (('if' disjunction))* + (c = (asdl_expr_seq*)_loop0_115_rule(p)) // (('if' disjunction))* ) { D(fprintf(stderr, "%*c+ for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); _res = _PyAST_comprehension ( a , b , c , 0 , p -> arena ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -15059,13 +16131,13 @@ for_if_clause_rule(Parser *p) D(fprintf(stderr, "%*c%s for_if_clause[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); if (_cut_var) { - D(p->level--); + p->level--; return NULL; } } if (p->call_invalid_rules) { // invalid_for_target if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> for_if_clause[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_for_target")); @@ -15084,7 +16156,7 @@ for_if_clause_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -15092,16 +16164,19 @@ for_if_clause_rule(Parser *p) static expr_ty listcomp_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -15110,7 +16185,7 @@ listcomp_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '[' named_expression for_if_clauses ']' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> listcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' named_expression for_if_clauses ']'")); @@ -15131,7 +16206,7 @@ listcomp_rule(Parser *p) D(fprintf(stderr, "%*c+ listcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' named_expression for_if_clauses ']'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -15141,7 +16216,7 @@ listcomp_rule(Parser *p) _res = _PyAST_ListComp ( a , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -15152,7 +16227,7 @@ listcomp_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_comprehension if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> listcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_comprehension")); @@ -15171,7 +16246,7 @@ listcomp_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -15179,16 +16254,19 @@ listcomp_rule(Parser *p) static expr_ty setcomp_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -15197,7 +16275,7 @@ setcomp_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '{' named_expression for_if_clauses '}' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> setcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' named_expression for_if_clauses '}'")); @@ -15218,7 +16296,7 @@ setcomp_rule(Parser *p) D(fprintf(stderr, "%*c+ setcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' named_expression for_if_clauses '}'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -15228,7 +16306,7 @@ setcomp_rule(Parser *p) _res = _PyAST_SetComp ( a , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -15239,7 +16317,7 @@ setcomp_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_comprehension if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> setcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_comprehension")); @@ -15258,7 +16336,7 @@ setcomp_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -15268,16 +16346,19 @@ setcomp_rule(Parser *p) static expr_ty genexp_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -15286,7 +16367,7 @@ genexp_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '(' (assignment_expression | expression !':=') for_if_clauses ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> genexp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' (assignment_expression | expression !':=') for_if_clauses ')'")); @@ -15297,7 +16378,7 @@ genexp_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = _tmp_113_rule(p)) // assignment_expression | expression !':=' + (a = _tmp_116_rule(p)) // assignment_expression | expression !':=' && (b = for_if_clauses_rule(p)) // for_if_clauses && @@ -15307,7 +16388,7 @@ genexp_rule(Parser *p) D(fprintf(stderr, "%*c+ genexp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' (assignment_expression | expression !':=') for_if_clauses ')'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -15317,7 +16398,7 @@ genexp_rule(Parser *p) _res = _PyAST_GeneratorExp ( a , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -15328,7 +16409,7 @@ genexp_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_comprehension if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> genexp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_comprehension")); @@ -15347,7 +16428,7 @@ genexp_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -15355,16 +16436,19 @@ genexp_rule(Parser *p) static expr_ty dictcomp_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -15373,7 +16457,7 @@ dictcomp_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '{' kvpair for_if_clauses '}' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> dictcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' kvpair for_if_clauses '}'")); @@ -15394,7 +16478,7 @@ dictcomp_rule(Parser *p) D(fprintf(stderr, "%*c+ dictcomp[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' kvpair for_if_clauses '}'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -15404,7 +16488,7 @@ dictcomp_rule(Parser *p) _res = _PyAST_DictComp ( a -> key , a -> value , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -15415,7 +16499,7 @@ dictcomp_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_dict_comprehension if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> dictcomp[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_dict_comprehension")); @@ -15434,7 +16518,7 @@ dictcomp_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -15442,20 +16526,23 @@ dictcomp_rule(Parser *p) static expr_ty arguments_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, arguments_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; { // args ','? &')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ','? &')'")); @@ -15474,7 +16561,7 @@ arguments_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -15485,7 +16572,7 @@ arguments_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_arguments if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_arguments")); @@ -15505,7 +16592,7 @@ arguments_rule(Parser *p) _res = NULL; done: _PyPegen_insert_memo(p, _mark, arguments_type, _res); - D(p->level--); + p->level--; return _res; } @@ -15515,16 +16602,19 @@ arguments_rule(Parser *p) static expr_ty args_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -15533,22 +16623,22 @@ args_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ [',' kwargs] if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> args[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ [',' kwargs]")); asdl_expr_seq* a; void *b; if ( - (a = (asdl_expr_seq*)_gather_114_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ + (a = (asdl_expr_seq*)_gather_117_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ && - (b = _tmp_116_rule(p), !p->error_indicator) // [',' kwargs] + (b = _tmp_119_rule(p), !p->error_indicator) // [',' kwargs] ) { D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ [',' kwargs]")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -15558,7 +16648,7 @@ args_rule(Parser *p) _res = _PyPegen_collect_call_seqs ( p , a , b , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -15569,7 +16659,7 @@ args_rule(Parser *p) } { // kwargs if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> args[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwargs")); @@ -15581,7 +16671,7 @@ args_rule(Parser *p) D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwargs")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -15591,7 +16681,7 @@ args_rule(Parser *p) _res = _PyAST_Call ( _PyPegen_dummy_name ( p ) , CHECK_NULL_ALLOWED ( asdl_expr_seq* , _PyPegen_seq_extract_starred_exprs ( p , a ) ) , CHECK_NULL_ALLOWED ( asdl_keyword_seq* , _PyPegen_seq_delete_starred_exprs ( p , a ) ) , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -15602,7 +16692,7 @@ args_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -15613,16 +16703,19 @@ args_rule(Parser *p) static asdl_seq* kwargs_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq* _res = NULL; int _mark = p->mark; { // ','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+")); @@ -15630,18 +16723,18 @@ kwargs_rule(Parser *p) asdl_seq * a; asdl_seq * b; if ( - (a = _gather_117_rule(p)) // ','.kwarg_or_starred+ + (a = _gather_120_rule(p)) // ','.kwarg_or_starred+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (b = _gather_119_rule(p)) // ','.kwarg_or_double_starred+ + (b = _gather_122_rule(p)) // ','.kwarg_or_double_starred+ ) { D(fprintf(stderr, "%*c+ kwargs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+")); _res = _PyPegen_join_sequences ( p , a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -15652,17 +16745,17 @@ kwargs_rule(Parser *p) } { // ','.kwarg_or_starred+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+")); - asdl_seq * _gather_121_var; + asdl_seq * _gather_124_var; if ( - (_gather_121_var = _gather_121_rule(p)) // ','.kwarg_or_starred+ + (_gather_124_var = _gather_124_rule(p)) // ','.kwarg_or_starred+ ) { D(fprintf(stderr, "%*c+ kwargs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+")); - _res = _gather_121_var; + _res = _gather_124_var; goto done; } p->mark = _mark; @@ -15671,17 +16764,17 @@ kwargs_rule(Parser *p) } { // ','.kwarg_or_double_starred+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_double_starred+")); - asdl_seq * _gather_123_var; + asdl_seq * _gather_126_var; if ( - (_gather_123_var = _gather_123_rule(p)) // ','.kwarg_or_double_starred+ + (_gather_126_var = _gather_126_rule(p)) // ','.kwarg_or_double_starred+ ) { D(fprintf(stderr, "%*c+ kwargs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_double_starred+")); - _res = _gather_123_var; + _res = _gather_126_var; goto done; } p->mark = _mark; @@ -15690,33 +16783,55 @@ kwargs_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// starred_expression: '*' expression +// starred_expression: invalid_starred_expression | '*' expression static expr_ty starred_expression_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; UNUSED(_start_lineno); // Only used by EXTRA macro int _start_col_offset = p->tokens[_mark]->col_offset; UNUSED(_start_col_offset); // Only used by EXTRA macro + if (p->call_invalid_rules) { // invalid_starred_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> starred_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_starred_expression")); + void *invalid_starred_expression_var; + if ( + (invalid_starred_expression_var = invalid_starred_expression_rule(p)) // invalid_starred_expression + ) + { + D(fprintf(stderr, "%*c+ starred_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_starred_expression")); + _res = invalid_starred_expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s starred_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_starred_expression")); + } { // '*' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> starred_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' expression")); @@ -15731,7 +16846,7 @@ starred_expression_rule(Parser *p) D(fprintf(stderr, "%*c+ starred_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' expression")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -15741,7 +16856,7 @@ starred_expression_rule(Parser *p) _res = _PyAST_Starred ( a , Load , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -15752,7 +16867,7 @@ starred_expression_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -15760,16 +16875,19 @@ starred_expression_rule(Parser *p) static KeywordOrStarred* kwarg_or_starred_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } KeywordOrStarred* _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -15778,7 +16896,7 @@ kwarg_or_starred_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro if (p->call_invalid_rules) { // invalid_kwarg if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> kwarg_or_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_kwarg")); @@ -15797,7 +16915,7 @@ kwarg_or_starred_rule(Parser *p) } { // NAME '=' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> kwarg_or_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '=' expression")); @@ -15815,7 +16933,7 @@ kwarg_or_starred_rule(Parser *p) D(fprintf(stderr, "%*c+ kwarg_or_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' expression")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -15825,7 +16943,7 @@ kwarg_or_starred_rule(Parser *p) _res = _PyPegen_keyword_or_starred ( p , CHECK ( keyword_ty , _PyAST_keyword ( a -> v . Name . id , b , EXTRA ) ) , 1 ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -15836,7 +16954,7 @@ kwarg_or_starred_rule(Parser *p) } { // starred_expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> kwarg_or_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); @@ -15849,7 +16967,7 @@ kwarg_or_starred_rule(Parser *p) _res = _PyPegen_keyword_or_starred ( p , a , 0 ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -15860,7 +16978,7 @@ kwarg_or_starred_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -15868,16 +16986,19 @@ kwarg_or_starred_rule(Parser *p) static KeywordOrStarred* kwarg_or_double_starred_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } KeywordOrStarred* _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -15886,7 +17007,7 @@ kwarg_or_double_starred_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro if (p->call_invalid_rules) { // invalid_kwarg if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> kwarg_or_double_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_kwarg")); @@ -15905,7 +17026,7 @@ kwarg_or_double_starred_rule(Parser *p) } { // NAME '=' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> kwarg_or_double_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '=' expression")); @@ -15923,7 +17044,7 @@ kwarg_or_double_starred_rule(Parser *p) D(fprintf(stderr, "%*c+ kwarg_or_double_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' expression")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -15933,7 +17054,7 @@ kwarg_or_double_starred_rule(Parser *p) _res = _PyPegen_keyword_or_starred ( p , CHECK ( keyword_ty , _PyAST_keyword ( a -> v . Name . id , b , EXTRA ) ) , 1 ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -15944,7 +17065,7 @@ kwarg_or_double_starred_rule(Parser *p) } { // '**' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> kwarg_or_double_starred[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' expression")); @@ -15959,7 +17080,7 @@ kwarg_or_double_starred_rule(Parser *p) D(fprintf(stderr, "%*c+ kwarg_or_double_starred[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' expression")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -15969,7 +17090,7 @@ kwarg_or_double_starred_rule(Parser *p) _res = _PyPegen_keyword_or_starred ( p , CHECK ( keyword_ty , _PyAST_keyword ( NULL , a , EXTRA ) ) , 1 ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -15980,7 +17101,7 @@ kwarg_or_double_starred_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -15988,16 +17109,19 @@ kwarg_or_double_starred_rule(Parser *p) static expr_ty star_targets_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -16006,7 +17130,7 @@ star_targets_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // star_target !',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target !','")); @@ -16021,7 +17145,7 @@ star_targets_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16032,7 +17156,7 @@ star_targets_rule(Parser *p) } { // star_target ((',' star_target))* ','? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))* ','?")); @@ -16043,7 +17167,7 @@ star_targets_rule(Parser *p) if ( (a = star_target_rule(p)) // star_target && - (b = _loop0_125_rule(p)) // ((',' star_target))* + (b = _loop0_128_rule(p)) // ((',' star_target))* && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -16051,7 +17175,7 @@ star_targets_rule(Parser *p) D(fprintf(stderr, "%*c+ star_targets[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))* ','?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -16061,7 +17185,7 @@ star_targets_rule(Parser *p) _res = _PyAST_Tuple ( CHECK ( asdl_expr_seq* , _PyPegen_seq_insert_in_front ( p , a , b ) ) , Store , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16072,7 +17196,7 @@ star_targets_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -16080,16 +17204,19 @@ star_targets_rule(Parser *p) static asdl_expr_seq* star_targets_list_seq_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_expr_seq* _res = NULL; int _mark = p->mark; { // ','.star_target+ ','? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_targets_list_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.star_target+ ','?")); @@ -16097,7 +17224,7 @@ star_targets_list_seq_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_126_rule(p)) // ','.star_target+ + (a = (asdl_expr_seq*)_gather_129_rule(p)) // ','.star_target+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -16106,7 +17233,7 @@ star_targets_list_seq_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16117,7 +17244,7 @@ star_targets_list_seq_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -16125,16 +17252,19 @@ star_targets_list_seq_rule(Parser *p) static asdl_expr_seq* star_targets_tuple_seq_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_expr_seq* _res = NULL; int _mark = p->mark; { // star_target ((',' star_target))+ ','? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_targets_tuple_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target ((',' star_target))+ ','?")); @@ -16145,7 +17275,7 @@ star_targets_tuple_seq_rule(Parser *p) if ( (a = star_target_rule(p)) // star_target && - (b = _loop1_128_rule(p)) // ((',' star_target))+ + (b = _loop1_131_rule(p)) // ((',' star_target))+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -16154,7 +17284,7 @@ star_targets_tuple_seq_rule(Parser *p) _res = ( asdl_expr_seq* ) _PyPegen_seq_insert_in_front ( p , a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16165,7 +17295,7 @@ star_targets_tuple_seq_rule(Parser *p) } { // star_target ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_targets_tuple_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target ','")); @@ -16181,7 +17311,7 @@ star_targets_tuple_seq_rule(Parser *p) _res = ( asdl_expr_seq* ) _PyPegen_singleton_seq ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16192,7 +17322,7 @@ star_targets_tuple_seq_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -16200,20 +17330,23 @@ star_targets_tuple_seq_rule(Parser *p) static expr_ty star_target_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, star_target_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -16222,7 +17355,7 @@ star_target_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // '*' (!'*' star_target) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (!'*' star_target)")); @@ -16231,13 +17364,13 @@ star_target_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (a = _tmp_129_rule(p)) // !'*' star_target + (a = _tmp_132_rule(p)) // !'*' star_target ) { D(fprintf(stderr, "%*c+ star_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (!'*' star_target)")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -16247,7 +17380,7 @@ star_target_rule(Parser *p) _res = _PyAST_Starred ( CHECK ( expr_ty , _PyPegen_set_expr_context ( p , a , Store ) ) , Store , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16258,7 +17391,7 @@ star_target_rule(Parser *p) } { // target_with_star_atom if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "target_with_star_atom")); @@ -16278,7 +17411,7 @@ star_target_rule(Parser *p) _res = NULL; done: _PyPegen_insert_memo(p, _mark, star_target_type, _res); - D(p->level--); + p->level--; return _res; } @@ -16289,20 +17422,23 @@ star_target_rule(Parser *p) static expr_ty target_with_star_atom_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, target_with_star_atom_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -16311,7 +17447,7 @@ target_with_star_atom_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // t_primary '.' NAME !t_lookahead if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> target_with_star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); @@ -16331,7 +17467,7 @@ target_with_star_atom_rule(Parser *p) D(fprintf(stderr, "%*c+ target_with_star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -16341,7 +17477,7 @@ target_with_star_atom_rule(Parser *p) _res = _PyAST_Attribute ( a , b -> v . Name . id , Store , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16352,7 +17488,7 @@ target_with_star_atom_rule(Parser *p) } { // t_primary '[' slices ']' !t_lookahead if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> target_with_star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); @@ -16375,7 +17511,7 @@ target_with_star_atom_rule(Parser *p) D(fprintf(stderr, "%*c+ target_with_star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -16385,7 +17521,7 @@ target_with_star_atom_rule(Parser *p) _res = _PyAST_Subscript ( a , b , Store , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16396,7 +17532,7 @@ target_with_star_atom_rule(Parser *p) } { // star_atom if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> target_with_star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_atom")); @@ -16416,7 +17552,7 @@ target_with_star_atom_rule(Parser *p) _res = NULL; done: _PyPegen_insert_memo(p, _mark, target_with_star_atom_type, _res); - D(p->level--); + p->level--; return _res; } @@ -16428,16 +17564,19 @@ target_with_star_atom_rule(Parser *p) static expr_ty star_atom_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -16446,7 +17585,7 @@ star_atom_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); @@ -16459,7 +17598,7 @@ star_atom_rule(Parser *p) _res = _PyPegen_set_expr_context ( p , a , Store ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16470,7 +17609,7 @@ star_atom_rule(Parser *p) } { // '(' target_with_star_atom ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' target_with_star_atom ')'")); @@ -16489,7 +17628,7 @@ star_atom_rule(Parser *p) _res = _PyPegen_set_expr_context ( p , a , Store ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16500,7 +17639,7 @@ star_atom_rule(Parser *p) } { // '(' star_targets_tuple_seq? ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' star_targets_tuple_seq? ')'")); @@ -16518,7 +17657,7 @@ star_atom_rule(Parser *p) D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' star_targets_tuple_seq? ')'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -16528,7 +17667,7 @@ star_atom_rule(Parser *p) _res = _PyAST_Tuple ( a , Store , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16539,7 +17678,7 @@ star_atom_rule(Parser *p) } { // '[' star_targets_list_seq? ']' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> star_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' star_targets_list_seq? ']'")); @@ -16557,7 +17696,7 @@ star_atom_rule(Parser *p) D(fprintf(stderr, "%*c+ star_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' star_targets_list_seq? ']'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -16567,7 +17706,7 @@ star_atom_rule(Parser *p) _res = _PyAST_List ( a , Store , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16578,7 +17717,7 @@ star_atom_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -16586,16 +17725,19 @@ star_atom_rule(Parser *p) static expr_ty single_target_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; { // single_subscript_attribute_target if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> single_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "single_subscript_attribute_target")); @@ -16614,7 +17756,7 @@ single_target_rule(Parser *p) } { // NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> single_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); @@ -16627,7 +17769,7 @@ single_target_rule(Parser *p) _res = _PyPegen_set_expr_context ( p , a , Store ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16638,7 +17780,7 @@ single_target_rule(Parser *p) } { // '(' single_target ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> single_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'")); @@ -16657,7 +17799,7 @@ single_target_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16668,7 +17810,7 @@ single_target_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -16678,16 +17820,19 @@ single_target_rule(Parser *p) static expr_ty single_subscript_attribute_target_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -16696,7 +17841,7 @@ single_subscript_attribute_target_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // t_primary '.' NAME !t_lookahead if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> single_subscript_attribute_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); @@ -16716,7 +17861,7 @@ single_subscript_attribute_target_rule(Parser *p) D(fprintf(stderr, "%*c+ single_subscript_attribute_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -16726,7 +17871,7 @@ single_subscript_attribute_target_rule(Parser *p) _res = _PyAST_Attribute ( a , b -> v . Name . id , Store , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16737,7 +17882,7 @@ single_subscript_attribute_target_rule(Parser *p) } { // t_primary '[' slices ']' !t_lookahead if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> single_subscript_attribute_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); @@ -16760,7 +17905,7 @@ single_subscript_attribute_target_rule(Parser *p) D(fprintf(stderr, "%*c+ single_subscript_attribute_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -16770,7 +17915,7 @@ single_subscript_attribute_target_rule(Parser *p) _res = _PyAST_Subscript ( a , b , Store , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16781,7 +17926,7 @@ single_subscript_attribute_target_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -16796,10 +17941,13 @@ static expr_ty t_primary_raw(Parser *); static expr_ty t_primary_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, t_primary_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; @@ -16807,37 +17955,40 @@ t_primary_rule(Parser *p) while (1) { int tmpvar_9 = _PyPegen_update_memo(p, _mark, t_primary_type, _res); if (tmpvar_9) { - D(p->level--); + p->level--; return _res; } p->mark = _mark; - p->in_raw_rule++; void *_raw = t_primary_raw(p); - p->in_raw_rule--; - if (p->error_indicator) + if (p->error_indicator) { + p->level--; return NULL; + } if (_raw == NULL || p->mark <= _resmark) break; _resmark = p->mark; _res = _raw; } p->mark = _resmark; - D(p->level--); + p->level--; return _res; } static expr_ty t_primary_raw(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -16846,7 +17997,7 @@ t_primary_raw(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // t_primary '.' NAME &t_lookahead if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME &t_lookahead")); @@ -16866,7 +18017,7 @@ t_primary_raw(Parser *p) D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME &t_lookahead")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -16876,7 +18027,7 @@ t_primary_raw(Parser *p) _res = _PyAST_Attribute ( a , b -> v . Name . id , Load , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16887,7 +18038,7 @@ t_primary_raw(Parser *p) } { // t_primary '[' slices ']' &t_lookahead if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' &t_lookahead")); @@ -16910,7 +18061,7 @@ t_primary_raw(Parser *p) D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' &t_lookahead")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -16920,7 +18071,7 @@ t_primary_raw(Parser *p) _res = _PyAST_Subscript ( a , b , Load , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16931,7 +18082,7 @@ t_primary_raw(Parser *p) } { // t_primary genexp &t_lookahead if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary genexp &t_lookahead")); @@ -16948,7 +18099,7 @@ t_primary_raw(Parser *p) D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary genexp &t_lookahead")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -16958,7 +18109,7 @@ t_primary_raw(Parser *p) _res = _PyAST_Call ( a , CHECK ( asdl_expr_seq* , ( asdl_expr_seq* ) _PyPegen_singleton_seq ( p , b ) ) , NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -16969,7 +18120,7 @@ t_primary_raw(Parser *p) } { // t_primary '(' arguments? ')' &t_lookahead if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '(' arguments? ')' &t_lookahead")); @@ -16992,7 +18143,7 @@ t_primary_raw(Parser *p) D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '(' arguments? ')' &t_lookahead")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -17002,7 +18153,7 @@ t_primary_raw(Parser *p) _res = _PyAST_Call ( a , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17013,7 +18164,7 @@ t_primary_raw(Parser *p) } { // atom &t_lookahead if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> t_primary[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "atom &t_lookahead")); @@ -17028,7 +18179,7 @@ t_primary_raw(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17039,7 +18190,7 @@ t_primary_raw(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -17047,16 +18198,19 @@ t_primary_raw(Parser *p) static void * t_lookahead_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '(' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> t_lookahead[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); @@ -17075,7 +18229,7 @@ t_lookahead_rule(Parser *p) } { // '[' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> t_lookahead[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); @@ -17094,7 +18248,7 @@ t_lookahead_rule(Parser *p) } { // '.' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> t_lookahead[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); @@ -17113,7 +18267,7 @@ t_lookahead_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -17121,16 +18275,19 @@ t_lookahead_rule(Parser *p) static asdl_expr_seq* del_targets_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_expr_seq* _res = NULL; int _mark = p->mark; { // ','.del_target+ ','? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> del_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.del_target+ ','?")); @@ -17138,7 +18295,7 @@ del_targets_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_130_rule(p)) // ','.del_target+ + (a = (asdl_expr_seq*)_gather_133_rule(p)) // ','.del_target+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -17147,7 +18304,7 @@ del_targets_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17158,7 +18315,7 @@ del_targets_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -17169,20 +18326,23 @@ del_targets_rule(Parser *p) static expr_ty del_target_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, del_target_type, &_res)) { - D(p->level--); + p->level--; return _res; } int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -17191,7 +18351,7 @@ del_target_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // t_primary '.' NAME !t_lookahead if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> del_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); @@ -17211,7 +18371,7 @@ del_target_rule(Parser *p) D(fprintf(stderr, "%*c+ del_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -17221,7 +18381,7 @@ del_target_rule(Parser *p) _res = _PyAST_Attribute ( a , b -> v . Name . id , Del , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17232,7 +18392,7 @@ del_target_rule(Parser *p) } { // t_primary '[' slices ']' !t_lookahead if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> del_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); @@ -17255,7 +18415,7 @@ del_target_rule(Parser *p) D(fprintf(stderr, "%*c+ del_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -17265,7 +18425,7 @@ del_target_rule(Parser *p) _res = _PyAST_Subscript ( a , b , Del , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17276,7 +18436,7 @@ del_target_rule(Parser *p) } { // del_t_atom if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> del_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_t_atom")); @@ -17296,7 +18456,7 @@ del_target_rule(Parser *p) _res = NULL; done: _PyPegen_insert_memo(p, _mark, del_target_type, _res); - D(p->level--); + p->level--; return _res; } @@ -17304,16 +18464,19 @@ del_target_rule(Parser *p) static expr_ty del_t_atom_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -17322,7 +18485,7 @@ del_t_atom_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> del_t_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME")); @@ -17335,7 +18498,7 @@ del_t_atom_rule(Parser *p) _res = _PyPegen_set_expr_context ( p , a , Del ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17346,7 +18509,7 @@ del_t_atom_rule(Parser *p) } { // '(' del_target ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> del_t_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' del_target ')'")); @@ -17365,7 +18528,7 @@ del_t_atom_rule(Parser *p) _res = _PyPegen_set_expr_context ( p , a , Del ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17376,7 +18539,7 @@ del_t_atom_rule(Parser *p) } { // '(' del_targets? ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> del_t_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' del_targets? ')'")); @@ -17394,7 +18557,7 @@ del_t_atom_rule(Parser *p) D(fprintf(stderr, "%*c+ del_t_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' del_targets? ')'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -17404,7 +18567,7 @@ del_t_atom_rule(Parser *p) _res = _PyAST_Tuple ( a , Del , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17415,7 +18578,7 @@ del_t_atom_rule(Parser *p) } { // '[' del_targets? ']' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> del_t_atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' del_targets? ']'")); @@ -17433,7 +18596,7 @@ del_t_atom_rule(Parser *p) D(fprintf(stderr, "%*c+ del_t_atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' del_targets? ']'")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -17443,7 +18606,7 @@ del_t_atom_rule(Parser *p) _res = _PyAST_List ( a , Del , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17454,7 +18617,7 @@ del_t_atom_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -17469,16 +18632,19 @@ del_t_atom_rule(Parser *p) static asdl_expr_seq* type_expressions_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_expr_seq* _res = NULL; int _mark = p->mark; { // ','.expression+ ',' '*' expression ',' '**' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '*' expression ',' '**' expression")); @@ -17490,7 +18656,7 @@ type_expressions_rule(Parser *p) expr_ty b; expr_ty c; if ( - (a = _gather_132_rule(p)) // ','.expression+ + (a = _gather_135_rule(p)) // ','.expression+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && @@ -17509,7 +18675,7 @@ type_expressions_rule(Parser *p) _res = ( asdl_expr_seq* ) _PyPegen_seq_append_to_end ( p , CHECK ( asdl_seq* , _PyPegen_seq_append_to_end ( p , a , b ) ) , c ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17520,7 +18686,7 @@ type_expressions_rule(Parser *p) } { // ','.expression+ ',' '*' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '*' expression")); @@ -17529,7 +18695,7 @@ type_expressions_rule(Parser *p) asdl_seq * a; expr_ty b; if ( - (a = _gather_134_rule(p)) // ','.expression+ + (a = _gather_137_rule(p)) // ','.expression+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && @@ -17542,7 +18708,7 @@ type_expressions_rule(Parser *p) _res = ( asdl_expr_seq* ) _PyPegen_seq_append_to_end ( p , a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17553,7 +18719,7 @@ type_expressions_rule(Parser *p) } { // ','.expression+ ',' '**' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+ ',' '**' expression")); @@ -17562,7 +18728,7 @@ type_expressions_rule(Parser *p) asdl_seq * a; expr_ty b; if ( - (a = _gather_136_rule(p)) // ','.expression+ + (a = _gather_139_rule(p)) // ','.expression+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && @@ -17575,7 +18741,7 @@ type_expressions_rule(Parser *p) _res = ( asdl_expr_seq* ) _PyPegen_seq_append_to_end ( p , a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17586,7 +18752,7 @@ type_expressions_rule(Parser *p) } { // '*' expression ',' '**' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' expression ',' '**' expression")); @@ -17611,7 +18777,7 @@ type_expressions_rule(Parser *p) _res = ( asdl_expr_seq* ) _PyPegen_seq_append_to_end ( p , CHECK ( asdl_seq* , _PyPegen_singleton_seq ( p , a ) ) , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17622,7 +18788,7 @@ type_expressions_rule(Parser *p) } { // '*' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' expression")); @@ -17638,7 +18804,7 @@ type_expressions_rule(Parser *p) _res = ( asdl_expr_seq* ) _PyPegen_singleton_seq ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17649,7 +18815,7 @@ type_expressions_rule(Parser *p) } { // '**' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' expression")); @@ -17665,7 +18831,7 @@ type_expressions_rule(Parser *p) _res = ( asdl_expr_seq* ) _PyPegen_singleton_seq ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17676,20 +18842,20 @@ type_expressions_rule(Parser *p) } { // ','.expression+ if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+")); asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_138_rule(p)) // ','.expression+ + (a = (asdl_expr_seq*)_gather_141_rule(p)) // ','.expression+ ) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+")); _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17700,7 +18866,7 @@ type_expressions_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -17711,16 +18877,19 @@ type_expressions_rule(Parser *p) static Token* func_type_comment_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } Token* _res = NULL; int _mark = p->mark; { // NEWLINE TYPE_COMMENT &(NEWLINE INDENT) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> func_type_comment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE TYPE_COMMENT &(NEWLINE INDENT)")); @@ -17731,14 +18900,14 @@ func_type_comment_rule(Parser *p) && (t = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT' && - _PyPegen_lookahead(1, _tmp_140_rule, p) + _PyPegen_lookahead(1, _tmp_143_rule, p) ) { D(fprintf(stderr, "%*c+ func_type_comment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE TYPE_COMMENT &(NEWLINE INDENT)")); _res = t; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17749,7 +18918,7 @@ func_type_comment_rule(Parser *p) } if (p->call_invalid_rules) { // invalid_double_type_comments if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> func_type_comment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_double_type_comments")); @@ -17768,7 +18937,7 @@ func_type_comment_rule(Parser *p) } { // TYPE_COMMENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> func_type_comment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "TYPE_COMMENT")); @@ -17787,7 +18956,7 @@ func_type_comment_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -17795,22 +18964,26 @@ func_type_comment_rule(Parser *p) // | args ',' '*' // | expression for_if_clauses ',' [args | expression for_if_clauses] // | NAME '=' expression for_if_clauses +// | [(args ',')] NAME '=' &(',' | ')') // | args for_if_clauses // | args ',' expression for_if_clauses // | args ',' args static void * invalid_arguments_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // args ',' '*' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ',' '*'")); @@ -17829,7 +19002,7 @@ invalid_arguments_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "iterable argument unpacking follows keyword argument unpacking" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17840,7 +19013,7 @@ invalid_arguments_rule(Parser *p) } { // expression for_if_clauses ',' [args | expression for_if_clauses] if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses ',' [args | expression for_if_clauses]")); @@ -17856,14 +19029,14 @@ invalid_arguments_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_opt_var = _tmp_141_rule(p), !p->error_indicator) // [args | expression for_if_clauses] + (_opt_var = _tmp_144_rule(p), !p->error_indicator) // [args | expression for_if_clauses] ) { D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses ',' [args | expression for_if_clauses]")); - _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , PyPegen_last_item ( b , comprehension_ty ) -> target , "Generator expression must be parenthesized" ); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , _PyPegen_get_last_comprehension_item ( PyPegen_last_item ( b , comprehension_ty ) ) , "Generator expression must be parenthesized" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17874,7 +19047,7 @@ invalid_arguments_rule(Parser *p) } { // NAME '=' expression for_if_clauses if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '=' expression for_if_clauses")); @@ -17896,7 +19069,7 @@ invalid_arguments_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "invalid syntax. Maybe you meant '==' or ':=' instead of '='?" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17905,9 +19078,42 @@ invalid_arguments_rule(Parser *p) D(fprintf(stderr, "%*c%s invalid_arguments[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '=' expression for_if_clauses")); } + { // [(args ',')] NAME '=' &(',' | ')') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(args ',')] NAME '=' &(',' | ')')")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty a; + Token * b; + if ( + (_opt_var = _tmp_145_rule(p), !p->error_indicator) // [(args ',')] + && + (a = _PyPegen_name_token(p)) // NAME + && + (b = _PyPegen_expect_token(p, 22)) // token='=' + && + _PyPegen_lookahead(1, _tmp_146_rule, p) + ) + { + D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "[(args ',')] NAME '=' &(',' | ')')")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "expected argument value expression" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_arguments[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "[(args ',')] NAME '=' &(',' | ')')")); + } { // args for_if_clauses if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args for_if_clauses")); @@ -17923,7 +19129,7 @@ invalid_arguments_rule(Parser *p) _res = _PyPegen_nonparen_genexp_in_call ( p , a , b ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17934,7 +19140,7 @@ invalid_arguments_rule(Parser *p) } { // args ',' expression for_if_clauses if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ',' expression for_if_clauses")); @@ -17953,10 +19159,10 @@ invalid_arguments_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ',' expression for_if_clauses")); - _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , asdl_seq_GET ( b , b -> size - 1 ) -> target , "Generator expression must be parenthesized" ); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , _PyPegen_get_last_comprehension_item ( PyPegen_last_item ( b , comprehension_ty ) ) , "Generator expression must be parenthesized" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17967,7 +19173,7 @@ invalid_arguments_rule(Parser *p) } { // args ',' args if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ',' args")); @@ -17986,7 +19192,7 @@ invalid_arguments_rule(Parser *p) _res = _PyPegen_arguments_parsing_error ( p , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -17997,7 +19203,7 @@ invalid_arguments_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -18005,26 +19211,30 @@ invalid_arguments_rule(Parser *p) // | ('True' | 'False' | 'None') '=' // | NAME '=' expression for_if_clauses // | !(NAME '=') expression '=' +// | '**' expression '=' expression static void * invalid_kwarg_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ('True' | 'False' | 'None') '=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_kwarg[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('True' | 'False' | 'None') '='")); Token* a; Token * b; if ( - (a = (Token*)_tmp_142_rule(p)) // 'True' | 'False' | 'None' + (a = (Token*)_tmp_147_rule(p)) // 'True' | 'False' | 'None' && (b = _PyPegen_expect_token(p, 22)) // token='=' ) @@ -18033,7 +19243,7 @@ invalid_kwarg_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot assign to %s" , PyBytes_AS_STRING ( a -> bytes ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18044,7 +19254,7 @@ invalid_kwarg_rule(Parser *p) } { // NAME '=' expression for_if_clauses if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_kwarg[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '=' expression for_if_clauses")); @@ -18066,7 +19276,7 @@ invalid_kwarg_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "invalid syntax. Maybe you meant '==' or ':=' instead of '='?" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18077,14 +19287,14 @@ invalid_kwarg_rule(Parser *p) } { // !(NAME '=') expression '=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_kwarg[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!(NAME '=') expression '='")); expr_ty a; Token * b; if ( - _PyPegen_lookahead(0, _tmp_143_rule, p) + _PyPegen_lookahead(0, _tmp_148_rule, p) && (a = expression_rule(p)) // expression && @@ -18095,7 +19305,7 @@ invalid_kwarg_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "expression cannot contain assignment, perhaps you meant \"==\"?" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18104,9 +19314,42 @@ invalid_kwarg_rule(Parser *p) D(fprintf(stderr, "%*c%s invalid_kwarg[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "!(NAME '=') expression '='")); } + { // '**' expression '=' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_kwarg[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' expression '=' expression")); + Token * _literal; + Token * a; + expr_ty b; + expr_ty expression_var; + if ( + (a = _PyPegen_expect_token(p, 35)) // token='**' + && + (expression_var = expression_rule(p)) // expression + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + && + (b = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ invalid_kwarg[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' expression '=' expression")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot assign to keyword argument unpacking" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_kwarg[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' expression '=' expression")); + } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -18117,16 +19360,23 @@ invalid_kwarg_rule(Parser *p) static expr_ty expression_without_invalid_rule(Parser *p) { - D(p->level++); + int _prev_call_invalid = p->call_invalid_rules; + p->call_invalid_rules = 0; + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->call_invalid_rules = _prev_call_invalid; + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - D(p->level--); + p->call_invalid_rules = _prev_call_invalid; + p->level--; return NULL; } int _start_lineno = p->tokens[_mark]->lineno; @@ -18135,7 +19385,8 @@ expression_without_invalid_rule(Parser *p) UNUSED(_start_col_offset); // Only used by EXTRA macro { // disjunction 'if' disjunction 'else' expression if (p->error_indicator) { - D(p->level--); + p->call_invalid_rules = _prev_call_invalid; + p->level--; return NULL; } D(fprintf(stderr, "%*c> expression_without_invalid[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction 'else' expression")); @@ -18147,11 +19398,11 @@ expression_without_invalid_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 627)) // token='if' + (_keyword = _PyPegen_expect_token(p, 641)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 630)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 644)) // token='else' && (c = expression_rule(p)) // expression ) @@ -18159,7 +19410,8 @@ expression_without_invalid_rule(Parser *p) D(fprintf(stderr, "%*c+ expression_without_invalid[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction 'else' expression")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { - D(p->level--); + p->call_invalid_rules = _prev_call_invalid; + p->level--; return NULL; } int _end_lineno = _token->end_lineno; @@ -18169,7 +19421,8 @@ expression_without_invalid_rule(Parser *p) _res = _PyAST_IfExp ( b , a , c , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->call_invalid_rules = _prev_call_invalid; + p->level--; return NULL; } goto done; @@ -18180,7 +19433,8 @@ expression_without_invalid_rule(Parser *p) } { // disjunction if (p->error_indicator) { - D(p->level--); + p->call_invalid_rules = _prev_call_invalid; + p->level--; return NULL; } D(fprintf(stderr, "%*c> expression_without_invalid[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "disjunction")); @@ -18199,7 +19453,8 @@ expression_without_invalid_rule(Parser *p) } { // lambdef if (p->error_indicator) { - D(p->level--); + p->call_invalid_rules = _prev_call_invalid; + p->level--; return NULL; } D(fprintf(stderr, "%*c> expression_without_invalid[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambdef")); @@ -18218,7 +19473,8 @@ expression_without_invalid_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->call_invalid_rules = _prev_call_invalid; + p->level--; return _res; } @@ -18226,16 +19482,19 @@ expression_without_invalid_rule(Parser *p) static void * invalid_legacy_expression_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // NAME !'(' star_expressions if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_legacy_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME !'(' star_expressions")); @@ -18253,7 +19512,7 @@ invalid_legacy_expression_rule(Parser *p) _res = _PyPegen_check_legacy_stmt ( p , a ) ? RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "Missing parentheses in call to '%U'. Did you mean %U(...)?" , a -> v . Name . id , a -> v . Name . id ) : NULL; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18264,7 +19523,7 @@ invalid_legacy_expression_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -18274,23 +19533,26 @@ invalid_legacy_expression_rule(Parser *p) static void * invalid_expression_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // !(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid")); expr_ty a; expr_ty b; if ( - _PyPegen_lookahead(0, _tmp_144_rule, p) + _PyPegen_lookahead(0, _tmp_149_rule, p) && (a = disjunction_rule(p)) // disjunction && @@ -18298,10 +19560,10 @@ invalid_expression_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid")); - _res = _PyPegen_check_legacy_stmt ( p , a ) ? NULL : RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "invalid syntax. Perhaps you forgot a comma?" ); + _res = _PyPegen_check_legacy_stmt ( p , a ) ? NULL : p -> tokens [p -> mark - 1] -> level == 0 ? NULL : RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "invalid syntax. Perhaps you forgot a comma?" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18312,7 +19574,7 @@ invalid_expression_rule(Parser *p) } { // disjunction 'if' disjunction !('else' | ':') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction !('else' | ':')")); @@ -18322,18 +19584,18 @@ invalid_expression_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 627)) // token='if' + (_keyword = _PyPegen_expect_token(p, 641)) // token='if' && (b = disjunction_rule(p)) // disjunction && - _PyPegen_lookahead(0, _tmp_145_rule, p) + _PyPegen_lookahead(0, _tmp_150_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction !('else' | ':')")); _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "expected 'else' after 'if' expression" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18344,7 +19606,7 @@ invalid_expression_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -18355,16 +19617,23 @@ invalid_expression_rule(Parser *p) static void * invalid_named_expression_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; + if (_PyPegen_is_memoized(p, invalid_named_expression_type, &_res)) { + p->level--; + return _res; + } int _mark = p->mark; { // expression ':=' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':=' expression")); @@ -18383,7 +19652,7 @@ invalid_named_expression_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use assignment expressions with %s" , _PyPegen_get_expr_name ( a ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18394,7 +19663,7 @@ invalid_named_expression_rule(Parser *p) } { // NAME '=' bitwise_or !('=' | ':=') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '=' bitwise_or !('=' | ':=')")); @@ -18408,14 +19677,14 @@ invalid_named_expression_rule(Parser *p) && (b = bitwise_or_rule(p)) // bitwise_or && - _PyPegen_lookahead(0, _tmp_146_rule, p) + _PyPegen_lookahead(0, _tmp_151_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' bitwise_or !('=' | ':=')")); - _res = p -> in_raw_rule ? NULL : RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "invalid syntax. Maybe you meant '==' or ':=' instead of '='?" ); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "invalid syntax. Maybe you meant '==' or ':=' instead of '='?" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18426,7 +19695,7 @@ invalid_named_expression_rule(Parser *p) } { // !(list | tuple | genexp | 'True' | 'None' | 'False') bitwise_or '=' bitwise_or !('=' | ':=') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_named_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!(list | tuple | genexp | 'True' | 'None' | 'False') bitwise_or '=' bitwise_or !('=' | ':=')")); @@ -18434,7 +19703,7 @@ invalid_named_expression_rule(Parser *p) Token * b; expr_ty bitwise_or_var; if ( - _PyPegen_lookahead(0, _tmp_147_rule, p) + _PyPegen_lookahead(0, _tmp_152_rule, p) && (a = bitwise_or_rule(p)) // bitwise_or && @@ -18442,14 +19711,14 @@ invalid_named_expression_rule(Parser *p) && (bitwise_or_var = bitwise_or_rule(p)) // bitwise_or && - _PyPegen_lookahead(0, _tmp_148_rule, p) + _PyPegen_lookahead(0, _tmp_153_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!(list | tuple | genexp | 'True' | 'None' | 'False') bitwise_or '=' bitwise_or !('=' | ':=')")); - _res = p -> in_raw_rule ? NULL : RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot assign to %s here. Maybe you meant '==' instead of '='?" , _PyPegen_get_expr_name ( a ) ); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot assign to %s here. Maybe you meant '==' instead of '='?" , _PyPegen_get_expr_name ( a ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18460,7 +19729,8 @@ invalid_named_expression_rule(Parser *p) } _res = NULL; done: - D(p->level--); + _PyPegen_insert_memo(p, _mark, invalid_named_expression_type, _res); + p->level--; return _res; } @@ -18474,16 +19744,19 @@ invalid_named_expression_rule(Parser *p) static void * invalid_assignment_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // invalid_ann_assign_target ':' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_ann_assign_target ':' expression")); @@ -18502,7 +19775,7 @@ invalid_assignment_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "only single target (not %s) can be annotated" , _PyPegen_get_expr_name ( a ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18513,13 +19786,13 @@ invalid_assignment_rule(Parser *p) } { // star_named_expression ',' star_named_expressions* ':' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions* ':' expression")); Token * _literal; Token * _literal_1; - asdl_seq * _loop0_149_var; + asdl_seq * _loop0_154_var; expr_ty a; expr_ty expression_var; if ( @@ -18527,7 +19800,7 @@ invalid_assignment_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_loop0_149_var = _loop0_149_rule(p)) // star_named_expressions* + (_loop0_154_var = _loop0_154_rule(p)) // star_named_expressions* && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -18538,7 +19811,7 @@ invalid_assignment_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "only single target (not tuple) can be annotated" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18549,7 +19822,7 @@ invalid_assignment_rule(Parser *p) } { // expression ':' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':' expression")); @@ -18568,7 +19841,7 @@ invalid_assignment_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "illegal target for annotation" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18579,15 +19852,15 @@ invalid_assignment_rule(Parser *p) } { // ((star_targets '='))* star_expressions '=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='")); Token * _literal; - asdl_seq * _loop0_150_var; + asdl_seq * _loop0_155_var; expr_ty a; if ( - (_loop0_150_var = _loop0_150_rule(p)) // ((star_targets '='))* + (_loop0_155_var = _loop0_155_rule(p)) // ((star_targets '='))* && (a = star_expressions_rule(p)) // star_expressions && @@ -18598,7 +19871,7 @@ invalid_assignment_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( STAR_TARGETS , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18609,15 +19882,15 @@ invalid_assignment_rule(Parser *p) } { // ((star_targets '='))* yield_expr '=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='")); Token * _literal; - asdl_seq * _loop0_151_var; + asdl_seq * _loop0_156_var; expr_ty a; if ( - (_loop0_151_var = _loop0_151_rule(p)) // ((star_targets '='))* + (_loop0_156_var = _loop0_156_rule(p)) // ((star_targets '='))* && (a = yield_expr_rule(p)) // yield_expr && @@ -18628,7 +19901,7 @@ invalid_assignment_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "assignment to yield expression not possible" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18639,11 +19912,11 @@ invalid_assignment_rule(Parser *p) } { // star_expressions augassign (yield_expr | star_expressions) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); - void *_tmp_152_var; + void *_tmp_157_var; expr_ty a; AugOperator* augassign_var; if ( @@ -18651,14 +19924,14 @@ invalid_assignment_rule(Parser *p) && (augassign_var = augassign_rule(p)) // augassign && - (_tmp_152_var = _tmp_152_rule(p)) // yield_expr | star_expressions + (_tmp_157_var = _tmp_157_rule(p)) // yield_expr | star_expressions ) { D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "'%s' is an illegal expression for augmented assignment" , _PyPegen_get_expr_name ( a ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18669,7 +19942,7 @@ invalid_assignment_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -18677,16 +19950,19 @@ invalid_assignment_rule(Parser *p) static expr_ty invalid_ann_assign_target_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } expr_ty _res = NULL; int _mark = p->mark; { // list if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_ann_assign_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); @@ -18705,7 +19981,7 @@ invalid_ann_assign_target_rule(Parser *p) } { // tuple if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_ann_assign_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); @@ -18724,7 +20000,7 @@ invalid_ann_assign_target_rule(Parser *p) } { // '(' invalid_ann_assign_target ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_ann_assign_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' invalid_ann_assign_target ')'")); @@ -18743,7 +20019,7 @@ invalid_ann_assign_target_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18754,7 +20030,7 @@ invalid_ann_assign_target_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -18762,23 +20038,26 @@ invalid_ann_assign_target_rule(Parser *p) static void * invalid_del_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'del' star_expressions if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_del_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'del' star_expressions")); Token * _keyword; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 600)) // token='del' + (_keyword = _PyPegen_expect_token(p, 603)) // token='del' && (a = star_expressions_rule(p)) // star_expressions ) @@ -18787,7 +20066,7 @@ invalid_del_stmt_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( DEL_TARGETS , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18798,7 +20077,7 @@ invalid_del_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -18806,16 +20085,19 @@ invalid_del_stmt_rule(Parser *p) static void * invalid_block_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE !INDENT")); @@ -18830,7 +20112,7 @@ invalid_block_rule(Parser *p) _res = RAISE_INDENTATION_ERROR ( "expected an indented block" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18841,7 +20123,7 @@ invalid_block_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -18852,24 +20134,27 @@ invalid_block_rule(Parser *p) static void * invalid_comprehension_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ('[' | '(' | '{') starred_expression for_if_clauses if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses")); - void *_tmp_153_var; + void *_tmp_158_var; expr_ty a; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_153_var = _tmp_153_rule(p)) // '[' | '(' | '{' + (_tmp_158_var = _tmp_158_rule(p)) // '[' | '(' | '{' && (a = starred_expression_rule(p)) // starred_expression && @@ -18880,7 +20165,7 @@ invalid_comprehension_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "iterable unpacking cannot be used in comprehension" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18891,17 +20176,17 @@ invalid_comprehension_rule(Parser *p) } { // ('[' | '{') star_named_expression ',' star_named_expressions for_if_clauses if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' star_named_expressions for_if_clauses")); Token * _literal; - void *_tmp_154_var; + void *_tmp_159_var; expr_ty a; asdl_expr_seq* b; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_154_var = _tmp_154_rule(p)) // '[' | '{' + (_tmp_159_var = _tmp_159_rule(p)) // '[' | '{' && (a = star_named_expression_rule(p)) // star_named_expression && @@ -18916,7 +20201,7 @@ invalid_comprehension_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , PyPegen_last_item ( b , expr_ty ) , "did you forget parentheses around the comprehension target?" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18927,16 +20212,16 @@ invalid_comprehension_rule(Parser *p) } { // ('[' | '{') star_named_expression ',' for_if_clauses if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' for_if_clauses")); - void *_tmp_155_var; + void *_tmp_160_var; expr_ty a; Token * b; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_155_var = _tmp_155_rule(p)) // '[' | '{' + (_tmp_160_var = _tmp_160_rule(p)) // '[' | '{' && (a = star_named_expression_rule(p)) // star_named_expression && @@ -18949,7 +20234,7 @@ invalid_comprehension_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "did you forget parentheses around the comprehension target?" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -18960,7 +20245,7 @@ invalid_comprehension_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -18968,16 +20253,19 @@ invalid_comprehension_rule(Parser *p) static void * invalid_dict_comprehension_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '{' '**' bitwise_or for_if_clauses '}' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_dict_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' '**' bitwise_or for_if_clauses '}'")); @@ -19002,7 +20290,7 @@ invalid_dict_comprehension_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "dict unpacking cannot be used in dict comprehension" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -19013,71 +20301,139 @@ invalid_dict_comprehension_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } // invalid_parameters: -// | param_no_default* invalid_parameters_helper param_no_default +// | "/" ',' +// | (slash_no_default | slash_with_default) param_maybe_default* '/' +// | slash_no_default? param_no_default* invalid_parameters_helper param_no_default // | param_no_default* '(' param_no_default+ ','? ')' +// | [(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/' +// | param_maybe_default+ '/' '*' static void * invalid_parameters_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; - { // param_no_default* invalid_parameters_helper param_no_default + { // "/" ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* invalid_parameters_helper param_no_default")); - asdl_seq * _loop0_156_var; - arg_ty a; - void *invalid_parameters_helper_var; + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"/\" ','")); + Token * _literal; + Token * a; if ( - (_loop0_156_var = _loop0_156_rule(p)) // param_no_default* + (a = _PyPegen_expect_token(p, 17)) // token='/' && - (invalid_parameters_helper_var = invalid_parameters_helper_rule(p)) // invalid_parameters_helper - && - (a = param_no_default_rule(p)) // param_no_default + (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default* invalid_parameters_helper param_no_default")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "non-default argument follows default argument" ); + D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"/\" ','")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "at least one argument must precede /" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default* invalid_parameters_helper param_no_default")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"/\" ','")); + } + { // (slash_no_default | slash_with_default) param_maybe_default* '/' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'")); + asdl_seq * _loop0_162_var; + void *_tmp_161_var; + Token * a; + if ( + (_tmp_161_var = _tmp_161_rule(p)) // slash_no_default | slash_with_default + && + (_loop0_162_var = _loop0_162_rule(p)) // param_maybe_default* + && + (a = _PyPegen_expect_token(p, 17)) // token='/' + ) + { + D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "/ may appear only once" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'")); + } + { // slash_no_default? param_no_default* invalid_parameters_helper param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default? param_no_default* invalid_parameters_helper param_no_default")); + asdl_seq * _loop0_163_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + arg_ty a; + void *invalid_parameters_helper_var; + if ( + (_opt_var = slash_no_default_rule(p), !p->error_indicator) // slash_no_default? + && + (_loop0_163_var = _loop0_163_rule(p)) // param_no_default* + && + (invalid_parameters_helper_var = invalid_parameters_helper_rule(p)) // invalid_parameters_helper + && + (a = param_no_default_rule(p)) // param_no_default + ) + { + D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default? param_no_default* invalid_parameters_helper param_no_default")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "parameter without a default follows parameter with a default" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default? param_no_default* invalid_parameters_helper param_no_default")); } { // param_no_default* '(' param_no_default+ ','? ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* '(' param_no_default+ ','? ')'")); - asdl_seq * _loop0_157_var; - asdl_seq * _loop1_158_var; + asdl_seq * _loop0_164_var; + asdl_seq * _loop1_165_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; Token * b; if ( - (_loop0_157_var = _loop0_157_rule(p)) // param_no_default* + (_loop0_164_var = _loop0_164_rule(p)) // param_no_default* && (a = _PyPegen_expect_token(p, 7)) // token='(' && - (_loop1_158_var = _loop1_158_rule(p)) // param_no_default+ + (_loop1_165_var = _loop1_165_rule(p)) // param_no_default+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -19088,7 +20444,7 @@ invalid_parameters_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "Function parameters cannot be parenthesized" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -19097,250 +20453,165 @@ invalid_parameters_rule(Parser *p) D(fprintf(stderr, "%*c%s invalid_parameters[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default* '(' param_no_default+ ','? ')'")); } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// invalid_parameters_helper: slash_with_default | param_with_default+ -static void * -invalid_parameters_helper_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // slash_with_default + { // [(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); - SlashWithDefault* a; - if ( - (a = slash_with_default_rule(p)) // slash_with_default - ) - { - D(fprintf(stderr, "%*c+ invalid_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); - _res = _PyPegen_singleton_seq ( p , a ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - D(p->level--); - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_parameters_helper[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); - } - { // param_with_default+ - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> invalid_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - asdl_seq * _loop1_159_var; - if ( - (_loop1_159_var = _loop1_159_rule(p)) // param_with_default+ - ) - { - D(fprintf(stderr, "%*c+ invalid_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - _res = _loop1_159_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_parameters_helper[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default+")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// invalid_lambda_parameters: -// | lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default -// | lambda_param_no_default* '(' ','.lambda_param+ ','? ')' -static void * -invalid_lambda_parameters_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); - asdl_seq * _loop0_160_var; - arg_ty a; - void *invalid_lambda_parameters_helper_var; - if ( - (_loop0_160_var = _loop0_160_rule(p)) // lambda_param_no_default* - && - (invalid_lambda_parameters_helper_var = invalid_lambda_parameters_helper_rule(p)) // invalid_lambda_parameters_helper - && - (a = lambda_param_no_default_rule(p)) // lambda_param_no_default - ) - { - D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "non-default argument follows default argument" ); - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - D(p->level--); - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); - } - { // lambda_param_no_default* '(' ','.lambda_param+ ','? ')' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); - asdl_seq * _gather_162_var; - asdl_seq * _loop0_161_var; + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/'")); + Token * _literal; + asdl_seq * _loop0_167_var; + asdl_seq * _loop0_169_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings + void *_tmp_168_var; Token * a; - Token * b; if ( - (_loop0_161_var = _loop0_161_rule(p)) // lambda_param_no_default* + (_opt_var = _tmp_166_rule(p), !p->error_indicator) // [(slash_no_default | slash_with_default)] && - (a = _PyPegen_expect_token(p, 7)) // token='(' + (_loop0_167_var = _loop0_167_rule(p)) // param_maybe_default* && - (_gather_162_var = _gather_162_rule(p)) // ','.lambda_param+ + (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + (_tmp_168_var = _tmp_168_rule(p)) // ',' | param_no_default && - (b = _PyPegen_expect_token(p, 8)) // token=')' + (_loop0_169_var = _loop0_169_rule(p)) // param_maybe_default* + && + (a = _PyPegen_expect_token(p, 17)) // token='/' ) { - D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); - _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "Lambda expression parameters cannot be parenthesized" ); + D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "[(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "/ must be ahead of *" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); + D(fprintf(stderr, "%*c%s invalid_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "[(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/'")); + } + { // param_maybe_default+ '/' '*' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default+ '/' '*'")); + Token * _literal; + asdl_seq * _loop1_170_var; + Token * a; + if ( + (_loop1_170_var = _loop1_170_rule(p)) // param_maybe_default+ + && + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + && + (a = _PyPegen_expect_token(p, 16)) // token='*' + ) + { + D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_maybe_default+ '/' '*'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "expected comma between / and *" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default+ '/' '*'")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// invalid_lambda_parameters_helper: -// | lambda_slash_with_default -// | lambda_param_with_default+ +// invalid_default: '=' &(')' | ',') static void * -invalid_lambda_parameters_helper_rule(Parser *p) +invalid_default_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; - { // lambda_slash_with_default + { // '=' &(')' | ',') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_lambda_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); - SlashWithDefault* a; + D(fprintf(stderr, "%*c> invalid_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' &(')' | ',')")); + Token * a; if ( - (a = lambda_slash_with_default_rule(p)) // lambda_slash_with_default + (a = _PyPegen_expect_token(p, 22)) // token='=' + && + _PyPegen_lookahead(1, _tmp_171_rule, p) ) { - D(fprintf(stderr, "%*c+ invalid_lambda_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); - _res = _PyPegen_singleton_seq ( p , a ); + D(fprintf(stderr, "%*c+ invalid_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' &(')' | ',')")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "expected default value expression" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_lambda_parameters_helper[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); - } - { // lambda_param_with_default+ - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> invalid_lambda_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); - asdl_seq * _loop1_164_var; - if ( - (_loop1_164_var = _loop1_164_rule(p)) // lambda_param_with_default+ - ) - { - D(fprintf(stderr, "%*c+ invalid_lambda_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); - _res = _loop1_164_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_lambda_parameters_helper[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default+")); + D(fprintf(stderr, "%*c%s invalid_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'=' &(')' | ',')")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// invalid_star_etc: '*' (')' | ',' (')' | '**')) | '*' ',' TYPE_COMMENT +// invalid_star_etc: +// | '*' (')' | ',' (')' | '**')) +// | '*' ',' TYPE_COMMENT +// | '*' param '=' +// | '*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',') static void * invalid_star_etc_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '*' (')' | ',' (')' | '**')) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); - void *_tmp_165_var; + void *_tmp_172_var; Token * a; if ( (a = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_165_var = _tmp_165_rule(p)) // ')' | ',' (')' | '**') + (_tmp_172_var = _tmp_172_rule(p)) // ')' | ',' (')' | '**') ) { D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "named arguments must follow bare *" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -19351,7 +20622,7 @@ invalid_star_etc_rule(Parser *p) } { // '*' ',' TYPE_COMMENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' ',' TYPE_COMMENT")); @@ -19370,7 +20641,7 @@ invalid_star_etc_rule(Parser *p) _res = RAISE_SYNTAX_ERROR ( "bare * has associated type comment" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -19379,42 +20650,582 @@ invalid_star_etc_rule(Parser *p) D(fprintf(stderr, "%*c%s invalid_star_etc[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' ',' TYPE_COMMENT")); } + { // '*' param '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' param '='")); + Token * _literal; + Token * a; + arg_ty param_var; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (param_var = param_rule(p)) // param + && + (a = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' param '='")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "var-positional argument cannot have default value" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' param '='")); + } + { // '*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')")); + Token * _literal; + asdl_seq * _loop0_174_var; + void *_tmp_173_var; + void *_tmp_175_var; + Token * a; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (_tmp_173_var = _tmp_173_rule(p)) // param_no_default | ',' + && + (_loop0_174_var = _loop0_174_rule(p)) // param_maybe_default* + && + (a = _PyPegen_expect_token(p, 16)) // token='*' + && + (_tmp_175_var = _tmp_175_rule(p)) // param_no_default | ',' + ) + { + D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "* argument may appear only once" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')")); + } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// invalid_lambda_star_etc: '*' (':' | ',' (':' | '**')) +// invalid_kwds: '**' param '=' | '**' param ',' param | '**' param ',' ('*' | '**' | '/') +static void * +invalid_kwds_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '**' param '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' param '='")); + Token * _literal; + Token * a; + arg_ty param_var; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (param_var = param_rule(p)) // param + && + (a = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ invalid_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' param '='")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "var-keyword argument cannot have default value" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' param '='")); + } + { // '**' param ',' param + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' param ',' param")); + Token * _literal; + Token * _literal_1; + arg_ty a; + arg_ty param_var; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (param_var = param_rule(p)) // param + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && + (a = param_rule(p)) // param + ) + { + D(fprintf(stderr, "%*c+ invalid_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' param ',' param")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "arguments cannot follow var-keyword argument" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' param ',' param")); + } + { // '**' param ',' ('*' | '**' | '/') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' param ',' ('*' | '**' | '/')")); + Token * _literal; + Token * _literal_1; + Token* a; + arg_ty param_var; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (param_var = param_rule(p)) // param + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && + (a = (Token*)_tmp_176_rule(p)) // '*' | '**' | '/' + ) + { + D(fprintf(stderr, "%*c+ invalid_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' param ',' ('*' | '**' | '/')")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "arguments cannot follow var-keyword argument" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' param ',' ('*' | '**' | '/')")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_parameters_helper: slash_with_default | param_with_default+ +static void * +invalid_parameters_helper_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // slash_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + SlashWithDefault* a; + if ( + (a = slash_with_default_rule(p)) // slash_with_default + ) + { + D(fprintf(stderr, "%*c+ invalid_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + _res = _PyPegen_singleton_seq ( p , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_parameters_helper[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); + } + { // param_with_default+ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+")); + asdl_seq * _loop1_177_var; + if ( + (_loop1_177_var = _loop1_177_rule(p)) // param_with_default+ + ) + { + D(fprintf(stderr, "%*c+ invalid_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+")); + _res = _loop1_177_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_parameters_helper[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_lambda_parameters: +// | "/" ',' +// | (lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/' +// | lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default +// | lambda_param_no_default* '(' ','.lambda_param+ ','? ')' +// | [(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/' +// | lambda_param_maybe_default+ '/' '*' +static void * +invalid_lambda_parameters_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // "/" ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"/\" ','")); + Token * _literal; + Token * a; + if ( + (a = _PyPegen_expect_token(p, 17)) // token='/' + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"/\" ','")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "at least one argument must precede /" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"/\" ','")); + } + { // (lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'")); + asdl_seq * _loop0_179_var; + void *_tmp_178_var; + Token * a; + if ( + (_tmp_178_var = _tmp_178_rule(p)) // lambda_slash_no_default | lambda_slash_with_default + && + (_loop0_179_var = _loop0_179_rule(p)) // lambda_param_maybe_default* + && + (a = _PyPegen_expect_token(p, 17)) // token='/' + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "/ may appear only once" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'")); + } + { // lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); + asdl_seq * _loop0_180_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + arg_ty a; + void *invalid_lambda_parameters_helper_var; + if ( + (_opt_var = lambda_slash_no_default_rule(p), !p->error_indicator) // lambda_slash_no_default? + && + (_loop0_180_var = _loop0_180_rule(p)) // lambda_param_no_default* + && + (invalid_lambda_parameters_helper_var = invalid_lambda_parameters_helper_rule(p)) // invalid_lambda_parameters_helper + && + (a = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "parameter without a default follows parameter with a default" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); + } + { // lambda_param_no_default* '(' ','.lambda_param+ ','? ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); + asdl_seq * _gather_182_var; + asdl_seq * _loop0_181_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + Token * a; + Token * b; + if ( + (_loop0_181_var = _loop0_181_rule(p)) // lambda_param_no_default* + && + (a = _PyPegen_expect_token(p, 7)) // token='(' + && + (_gather_182_var = _gather_182_rule(p)) // ','.lambda_param+ + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && + (b = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "Lambda expression parameters cannot be parenthesized" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); + } + { // [(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/'")); + Token * _literal; + asdl_seq * _loop0_185_var; + asdl_seq * _loop0_187_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + void *_tmp_186_var; + Token * a; + if ( + (_opt_var = _tmp_184_rule(p), !p->error_indicator) // [(lambda_slash_no_default | lambda_slash_with_default)] + && + (_loop0_185_var = _loop0_185_rule(p)) // lambda_param_maybe_default* + && + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (_tmp_186_var = _tmp_186_rule(p)) // ',' | lambda_param_no_default + && + (_loop0_187_var = _loop0_187_rule(p)) // lambda_param_maybe_default* + && + (a = _PyPegen_expect_token(p, 17)) // token='/' + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "[(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "/ must be ahead of *" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "[(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/'")); + } + { // lambda_param_maybe_default+ '/' '*' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default+ '/' '*'")); + Token * _literal; + asdl_seq * _loop1_188_var; + Token * a; + if ( + (_loop1_188_var = _loop1_188_rule(p)) // lambda_param_maybe_default+ + && + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + && + (a = _PyPegen_expect_token(p, 16)) // token='*' + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default+ '/' '*'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "expected comma between / and *" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default+ '/' '*'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_lambda_parameters_helper: +// | lambda_slash_with_default +// | lambda_param_with_default+ +static void * +invalid_lambda_parameters_helper_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // lambda_slash_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + SlashWithDefault* a; + if ( + (a = lambda_slash_with_default_rule(p)) // lambda_slash_with_default + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + _res = _PyPegen_singleton_seq ( p , a ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_parameters_helper[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); + } + { // lambda_param_with_default+ + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); + asdl_seq * _loop1_189_var; + if ( + (_loop1_189_var = _loop1_189_rule(p)) // lambda_param_with_default+ + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); + _res = _loop1_189_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_parameters_helper[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default+")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_lambda_star_etc: +// | '*' (':' | ',' (':' | '**')) +// | '*' lambda_param '=' +// | '*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',') static void * invalid_lambda_star_etc_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '*' (':' | ',' (':' | '**')) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); Token * _literal; - void *_tmp_166_var; + void *_tmp_190_var; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_166_var = _tmp_166_rule(p)) // ':' | ',' (':' | '**') + (_tmp_190_var = _tmp_190_rule(p)) // ':' | ',' (':' | '**') ) { D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); _res = RAISE_SYNTAX_ERROR ( "named arguments must follow bare *" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -19423,9 +21234,194 @@ invalid_lambda_star_etc_rule(Parser *p) D(fprintf(stderr, "%*c%s invalid_lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); } + { // '*' lambda_param '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' lambda_param '='")); + Token * _literal; + Token * a; + arg_ty lambda_param_var; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (lambda_param_var = lambda_param_rule(p)) // lambda_param + && + (a = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' lambda_param '='")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "var-positional argument cannot have default value" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' lambda_param '='")); + } + { // '*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')")); + Token * _literal; + asdl_seq * _loop0_192_var; + void *_tmp_191_var; + void *_tmp_193_var; + Token * a; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (_tmp_191_var = _tmp_191_rule(p)) // lambda_param_no_default | ',' + && + (_loop0_192_var = _loop0_192_rule(p)) // lambda_param_maybe_default* + && + (a = _PyPegen_expect_token(p, 16)) // token='*' + && + (_tmp_193_var = _tmp_193_rule(p)) // lambda_param_no_default | ',' + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "* argument may appear only once" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')")); + } _res = NULL; done: - D(p->level--); + p->level--; + return _res; +} + +// invalid_lambda_kwds: +// | '**' lambda_param '=' +// | '**' lambda_param ',' lambda_param +// | '**' lambda_param ',' ('*' | '**' | '/') +static void * +invalid_lambda_kwds_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '**' lambda_param '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' lambda_param '='")); + Token * _literal; + Token * a; + arg_ty lambda_param_var; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (lambda_param_var = lambda_param_rule(p)) // lambda_param + && + (a = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' lambda_param '='")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "var-keyword argument cannot have default value" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' lambda_param '='")); + } + { // '**' lambda_param ',' lambda_param + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' lambda_param ',' lambda_param")); + Token * _literal; + Token * _literal_1; + arg_ty a; + arg_ty lambda_param_var; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (lambda_param_var = lambda_param_rule(p)) // lambda_param + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && + (a = lambda_param_rule(p)) // lambda_param + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' lambda_param ',' lambda_param")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "arguments cannot follow var-keyword argument" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' lambda_param ',' lambda_param")); + } + { // '**' lambda_param ',' ('*' | '**' | '/') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' lambda_param ',' ('*' | '**' | '/')")); + Token * _literal; + Token * _literal_1; + Token* a; + arg_ty lambda_param_var; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (lambda_param_var = lambda_param_rule(p)) // lambda_param + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && + (a = (Token*)_tmp_194_rule(p)) // '*' | '**' | '/' + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' lambda_param ',' ('*' | '**' | '/')")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "arguments cannot follow var-keyword argument" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' lambda_param ',' ('*' | '**' | '/')")); + } + _res = NULL; + done: + p->level--; return _res; } @@ -19433,16 +21429,19 @@ invalid_lambda_star_etc_rule(Parser *p) static void * invalid_double_type_comments_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_double_type_comments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT")); @@ -19467,7 +21466,7 @@ invalid_double_type_comments_rule(Parser *p) _res = RAISE_SYNTAX_ERROR ( "Cannot have two type comments on def" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -19478,7 +21477,7 @@ invalid_double_type_comments_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -19486,16 +21485,19 @@ invalid_double_type_comments_rule(Parser *p) static void * invalid_with_item_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // expression 'as' expression &(',' | ')' | ':') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_with_item[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression 'as' expression &(',' | ')' | ':')")); @@ -19505,18 +21507,18 @@ invalid_with_item_rule(Parser *p) if ( (expression_var = expression_rule(p)) // expression && - (_keyword = _PyPegen_expect_token(p, 625)) // token='as' + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' && (a = expression_rule(p)) // expression && - _PyPegen_lookahead(1, _tmp_167_rule, p) + _PyPegen_lookahead(1, _tmp_195_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' expression &(',' | ')' | ':')")); _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( STAR_TARGETS , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -19527,7 +21529,7 @@ invalid_with_item_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -19535,16 +21537,19 @@ invalid_with_item_rule(Parser *p) static void * invalid_for_target_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ASYNC? 'for' star_expressions if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_for_target[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_expressions")); @@ -19555,7 +21560,7 @@ invalid_for_target_rule(Parser *p) if ( (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? && - (_keyword = _PyPegen_expect_token(p, 633)) // token='for' + (_keyword = _PyPegen_expect_token(p, 649)) // token='for' && (a = star_expressions_rule(p)) // star_expressions ) @@ -19564,7 +21569,7 @@ invalid_for_target_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_INVALID_TARGET ( FOR_TARGETS , a ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -19575,7 +21580,7 @@ invalid_for_target_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -19583,16 +21588,19 @@ invalid_for_target_rule(Parser *p) static void * invalid_group_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '(' starred_expression ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_group[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' starred_expression ')'")); @@ -19611,7 +21619,7 @@ invalid_group_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use starred expression here" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -19622,7 +21630,7 @@ invalid_group_rule(Parser *p) } { // '(' '**' expression ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_group[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' '**' expression ')'")); @@ -19644,7 +21652,7 @@ invalid_group_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use double starred expression here" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -19655,7 +21663,60 @@ invalid_group_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; + return _res; +} + +// invalid_import: 'import' dotted_name 'from' dotted_name +static void * +invalid_import_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // 'import' dotted_name 'from' dotted_name + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_import[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import' dotted_name 'from' dotted_name")); + Token * _keyword; + Token * a; + expr_ty dotted_name_var; + expr_ty dotted_name_var_1; + if ( + (a = _PyPegen_expect_token(p, 606)) // token='import' + && + (dotted_name_var = dotted_name_rule(p)) // dotted_name + && + (_keyword = _PyPegen_expect_token(p, 607)) // token='from' + && + (dotted_name_var_1 = dotted_name_rule(p)) // dotted_name + ) + { + D(fprintf(stderr, "%*c+ invalid_import[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import' dotted_name 'from' dotted_name")); + _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "Did you mean to use 'from ... import ...' instead?" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_import[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'import' dotted_name 'from' dotted_name")); + } + _res = NULL; + done: + p->level--; return _res; } @@ -19663,16 +21724,19 @@ invalid_group_rule(Parser *p) static void * invalid_import_from_targets_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // import_from_as_names ',' NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_import_from_targets[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_names ',' NEWLINE")); @@ -19691,7 +21755,7 @@ invalid_import_from_targets_rule(Parser *p) _res = RAISE_SYNTAX_ERROR ( "trailing comma not allowed without surrounding parentheses" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -19702,94 +21766,107 @@ invalid_import_from_targets_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } // invalid_with_stmt: -// | ASYNC? 'with' ','.(expression ['as' star_target])+ &&':' -// | ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':' +// | ASYNC? 'with' ','.(expression ['as' star_target])+ NEWLINE +// | ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE static void * invalid_with_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; - { // ASYNC? 'with' ','.(expression ['as' star_target])+ &&':' + { // ASYNC? 'with' ','.(expression ['as' star_target])+ NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ &&':'")); - asdl_seq * _gather_168_var; + D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ NEWLINE")); + asdl_seq * _gather_196_var; Token * _keyword; - Token * _literal; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings + Token * newline_var; if ( (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? && - (_keyword = _PyPegen_expect_token(p, 609)) // token='with' + (_keyword = _PyPegen_expect_token(p, 614)) // token='with' && - (_gather_168_var = _gather_168_rule(p)) // ','.(expression ['as' star_target])+ + (_gather_196_var = _gather_196_rule(p)) // ','.(expression ['as' star_target])+ && - (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ invalid_with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ &&':'")); - _res = _PyPegen_dummy_name(p, _opt_var, _keyword, _gather_168_var, _literal); + D(fprintf(stderr, "%*c+ invalid_with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ NEWLINE")); + _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_with_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ &&':'")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ NEWLINE")); } - { // ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':' + { // ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':'")); - asdl_seq * _gather_170_var; + D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE")); + asdl_seq * _gather_198_var; Token * _keyword; Token * _literal; Token * _literal_1; - Token * _literal_2; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings void *_opt_var_1; UNUSED(_opt_var_1); // Silence compiler warnings + Token * newline_var; if ( (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? && - (_keyword = _PyPegen_expect_token(p, 609)) // token='with' + (_keyword = _PyPegen_expect_token(p, 614)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_170_var = _gather_170_rule(p)) // ','.(expressions ['as' star_target])+ + (_gather_198_var = _gather_198_rule(p)) // ','.(expressions ['as' star_target])+ && (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' && - (_literal_2 = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ invalid_with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':'")); - _res = _PyPegen_dummy_name(p, _opt_var, _keyword, _literal, _gather_170_var, _opt_var_1, _literal_1, _literal_2); + D(fprintf(stderr, "%*c+ invalid_with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE")); + _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_with_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':'")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -19799,20 +21876,23 @@ invalid_with_stmt_rule(Parser *p) static void * invalid_with_stmt_indent_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ASYNC? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT")); - asdl_seq * _gather_172_var; + asdl_seq * _gather_200_var; Token * _literal; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings @@ -19821,9 +21901,9 @@ invalid_with_stmt_indent_rule(Parser *p) if ( (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? && - (a = _PyPegen_expect_token(p, 609)) // token='with' + (a = _PyPegen_expect_token(p, 614)) // token='with' && - (_gather_172_var = _gather_172_rule(p)) // ','.(expression ['as' star_target])+ + (_gather_200_var = _gather_200_rule(p)) // ','.(expression ['as' star_target])+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -19836,7 +21916,7 @@ invalid_with_stmt_indent_rule(Parser *p) _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'with' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -19847,11 +21927,11 @@ invalid_with_stmt_indent_rule(Parser *p) } { // ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT")); - asdl_seq * _gather_174_var; + asdl_seq * _gather_202_var; Token * _literal; Token * _literal_1; Token * _literal_2; @@ -19864,11 +21944,11 @@ invalid_with_stmt_indent_rule(Parser *p) if ( (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? && - (a = _PyPegen_expect_token(p, 609)) // token='with' + (a = _PyPegen_expect_token(p, 614)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_174_var = _gather_174_rule(p)) // ','.(expressions ['as' star_target])+ + (_gather_202_var = _gather_202_rule(p)) // ','.(expressions ['as' star_target])+ && (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -19885,7 +21965,7 @@ invalid_with_stmt_indent_rule(Parser *p) _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'with' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -19896,24 +21976,31 @@ invalid_with_stmt_indent_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// invalid_try_stmt: 'try' ':' NEWLINE !INDENT | 'try' ':' block !('except' | 'finally') +// invalid_try_stmt: +// | 'try' ':' NEWLINE !INDENT +// | 'try' ':' block !('except' | 'finally') +// | 'try' ':' block* except_block+ 'except' '*' expression ['as' NAME] ':' +// | 'try' ':' block* except_star_block+ 'except' [expression ['as' NAME]] ':' static void * invalid_try_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'try' ':' NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' ':' NEWLINE !INDENT")); @@ -19921,7 +22008,7 @@ invalid_try_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 612)) // token='try' + (a = _PyPegen_expect_token(p, 623)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -19934,7 +22021,7 @@ invalid_try_stmt_rule(Parser *p) _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'try' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -19945,7 +22032,7 @@ invalid_try_stmt_rule(Parser *p) } { // 'try' ':' block !('except' | 'finally') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' ':' block !('except' | 'finally')")); @@ -19953,20 +22040,20 @@ invalid_try_stmt_rule(Parser *p) Token * _literal; asdl_stmt_seq* block_var; if ( - (_keyword = _PyPegen_expect_token(p, 612)) // token='try' + (_keyword = _PyPegen_expect_token(p, 623)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && (block_var = block_rule(p)) // block && - _PyPegen_lookahead(0, _tmp_176_rule, p) + _PyPegen_lookahead(0, _tmp_204_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block !('except' | 'finally')")); _res = RAISE_SYNTAX_ERROR ( "expected 'except' or 'finally' block" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -19975,41 +22062,141 @@ invalid_try_stmt_rule(Parser *p) D(fprintf(stderr, "%*c%s invalid_try_stmt[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'try' ':' block !('except' | 'finally')")); } + { // 'try' ':' block* except_block+ 'except' '*' expression ['as' NAME] ':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' ':' block* except_block+ 'except' '*' expression ['as' NAME] ':'")); + Token * _keyword; + Token * _literal; + Token * _literal_1; + asdl_seq * _loop0_205_var; + asdl_seq * _loop1_206_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + Token * a; + Token * b; + expr_ty expression_var; + if ( + (_keyword = _PyPegen_expect_token(p, 623)) // token='try' + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (_loop0_205_var = _loop0_205_rule(p)) // block* + && + (_loop1_206_var = _loop1_206_rule(p)) // except_block+ + && + (a = _PyPegen_expect_token(p, 636)) // token='except' + && + (b = _PyPegen_expect_token(p, 16)) // token='*' + && + (expression_var = expression_rule(p)) // expression + && + (_opt_var = _tmp_207_rule(p), !p->error_indicator) // ['as' NAME] + && + (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block* except_block+ 'except' '*' expression ['as' NAME] ':'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot have both 'except' and 'except*' on the same 'try'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_try_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'try' ':' block* except_block+ 'except' '*' expression ['as' NAME] ':'")); + } + { // 'try' ':' block* except_star_block+ 'except' [expression ['as' NAME]] ':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' ':' block* except_star_block+ 'except' [expression ['as' NAME]] ':'")); + Token * _keyword; + Token * _literal; + Token * _literal_1; + asdl_seq * _loop0_208_var; + asdl_seq * _loop1_209_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + Token * a; + if ( + (_keyword = _PyPegen_expect_token(p, 623)) // token='try' + && + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (_loop0_208_var = _loop0_208_rule(p)) // block* + && + (_loop1_209_var = _loop1_209_rule(p)) // except_star_block+ + && + (a = _PyPegen_expect_token(p, 636)) // token='except' + && + (_opt_var = _tmp_210_rule(p), !p->error_indicator) // [expression ['as' NAME]] + && + (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block* except_star_block+ 'except' [expression ['as' NAME]] ':'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot have both 'except' and 'except*' on the same 'try'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_try_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'try' ':' block* except_star_block+ 'except' [expression ['as' NAME]] ':'")); + } _res = NULL; done: - D(p->level--); + p->level--; return _res; } // invalid_except_stmt: -// | 'except' expression ',' expressions ['as' NAME] ':' -// | 'except' expression ['as' NAME] NEWLINE +// | 'except' '*'? expression ',' expressions ['as' NAME] ':' +// | 'except' '*'? expression ['as' NAME] NEWLINE // | 'except' NEWLINE +// | 'except' '*' (NEWLINE | ':') static void * invalid_except_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; - { // 'except' expression ',' expressions ['as' NAME] ':' + { // 'except' '*'? expression ',' expressions ['as' NAME] ':' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' expression ',' expressions ['as' NAME] ':'")); + D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' '*'? expression ',' expressions ['as' NAME] ':'")); Token * _keyword; Token * _literal; Token * _literal_1; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings + void *_opt_var_1; + UNUSED(_opt_var_1); // Silence compiler warnings expr_ty a; expr_ty expressions_var; if ( - (_keyword = _PyPegen_expect_token(p, 623)) // token='except' + (_keyword = _PyPegen_expect_token(p, 636)) // token='except' + && + (_opt_var = _PyPegen_expect_token(p, 16), !p->error_indicator) // '*'? && (a = expression_rule(p)) // expression && @@ -20017,68 +22204,72 @@ invalid_except_stmt_rule(Parser *p) && (expressions_var = expressions_rule(p)) // expressions && - (_opt_var = _tmp_177_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var_1 = _tmp_211_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' expression ',' expressions ['as' NAME] ':'")); + D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*'? expression ',' expressions ['as' NAME] ':'")); _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "multiple exception types must be parenthesized" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_except_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' expression ',' expressions ['as' NAME] ':'")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' '*'? expression ',' expressions ['as' NAME] ':'")); } - { // 'except' expression ['as' NAME] NEWLINE + { // 'except' '*'? expression ['as' NAME] NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] NEWLINE")); + D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' '*'? expression ['as' NAME] NEWLINE")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings + void *_opt_var_1; + UNUSED(_opt_var_1); // Silence compiler warnings Token * a; expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 623)) // token='except' + (a = _PyPegen_expect_token(p, 636)) // token='except' + && + (_opt_var = _PyPegen_expect_token(p, 16), !p->error_indicator) // '*'? && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_178_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var_1 = _tmp_212_rule(p), !p->error_indicator) // ['as' NAME] && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] NEWLINE")); + D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*'? expression ['as' NAME] NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_except_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' expression ['as' NAME] NEWLINE")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' '*'? expression ['as' NAME] NEWLINE")); } { // 'except' NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' NEWLINE")); Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 623)) // token='except' + (a = _PyPegen_expect_token(p, 636)) // token='except' && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -20087,7 +22278,7 @@ invalid_except_stmt_rule(Parser *p) _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20096,9 +22287,39 @@ invalid_except_stmt_rule(Parser *p) D(fprintf(stderr, "%*c%s invalid_except_stmt[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' NEWLINE")); } + { // 'except' '*' (NEWLINE | ':') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); + Token * _literal; + void *_tmp_213_var; + Token * a; + if ( + (a = _PyPegen_expect_token(p, 636)) // token='except' + && + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (_tmp_213_var = _tmp_213_rule(p)) // NEWLINE | ':' + ) + { + D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); + _res = RAISE_SYNTAX_ERROR ( "expected one or more exception types" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_except_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' '*' (NEWLINE | ':')")); + } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -20106,16 +22327,19 @@ invalid_except_stmt_rule(Parser *p) static void * invalid_finally_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'finally' ':' NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_finally_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally' ':' NEWLINE !INDENT")); @@ -20123,7 +22347,7 @@ invalid_finally_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 620)) // token='finally' + (a = _PyPegen_expect_token(p, 632)) // token='finally' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -20136,7 +22360,7 @@ invalid_finally_stmt_rule(Parser *p) _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'finally' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20147,7 +22371,7 @@ invalid_finally_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -20157,16 +22381,19 @@ invalid_finally_stmt_rule(Parser *p) static void * invalid_except_stmt_indent_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'except' expression ['as' NAME] ':' NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_except_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' expression ['as' NAME] ':' NEWLINE !INDENT")); @@ -20177,11 +22404,11 @@ invalid_except_stmt_indent_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 623)) // token='except' + (a = _PyPegen_expect_token(p, 636)) // token='except' && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_179_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_214_rule(p), !p->error_indicator) // ['as' NAME] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -20194,7 +22421,7 @@ invalid_except_stmt_indent_rule(Parser *p) _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'except' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20205,7 +22432,7 @@ invalid_except_stmt_indent_rule(Parser *p) } { // 'except' ':' NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_except_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' ':' NEWLINE !INDENT")); @@ -20213,7 +22440,7 @@ invalid_except_stmt_indent_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 623)) // token='except' + (a = _PyPegen_expect_token(p, 636)) // token='except' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -20223,10 +22450,10 @@ invalid_except_stmt_indent_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_except_stmt_indent[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' ':' NEWLINE !INDENT")); - _res = RAISE_SYNTAX_ERROR ( "expected an indented block after except statement on line %d" , a -> lineno ); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'except' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20237,55 +22464,122 @@ invalid_except_stmt_indent_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// invalid_match_stmt: -// | "match" subject_expr !':' -// | "match" subject_expr ':' NEWLINE !INDENT +// invalid_except_star_stmt_indent: +// | 'except' '*' expression ['as' NAME] ':' NEWLINE !INDENT static void * -invalid_match_stmt_rule(Parser *p) +invalid_except_star_stmt_indent_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; - { // "match" subject_expr !':' + { // 'except' '*' expression ['as' NAME] ':' NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_match_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"match\" subject_expr !':'")); + D(fprintf(stderr, "%*c> invalid_except_star_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' '*' expression ['as' NAME] ':' NEWLINE !INDENT")); + Token * _literal; + Token * _literal_1; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + Token * a; + expr_ty expression_var; + Token * newline_var; + if ( + (a = _PyPegen_expect_token(p, 636)) // token='except' + && + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (expression_var = expression_rule(p)) // expression + && + (_opt_var = _tmp_215_rule(p), !p->error_indicator) // ['as' NAME] + && + (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, INDENT) // token=INDENT + ) + { + D(fprintf(stderr, "%*c+ invalid_except_star_stmt_indent[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*' expression ['as' NAME] ':' NEWLINE !INDENT")); + _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'except*' statement on line %d" , a -> lineno ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_except_star_stmt_indent[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except' '*' expression ['as' NAME] ':' NEWLINE !INDENT")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_match_stmt: +// | "match" subject_expr NEWLINE +// | "match" subject_expr ':' NEWLINE !INDENT +static void * +invalid_match_stmt_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // "match" subject_expr NEWLINE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_match_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"match\" subject_expr NEWLINE")); expr_ty _keyword; + Token * newline_var; expr_ty subject_expr_var; if ( (_keyword = _PyPegen_expect_soft_keyword(p, "match")) // soft_keyword='"match"' && (subject_expr_var = subject_expr_rule(p)) // subject_expr && - _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 11) // token=':' + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ invalid_match_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"match\" subject_expr !':'")); + D(fprintf(stderr, "%*c+ invalid_match_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"match\" subject_expr NEWLINE")); _res = CHECK_VERSION ( void* , 10 , "Pattern matching is" , RAISE_SYNTAX_ERROR ( "expected ':'" ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_match_stmt[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"match\" subject_expr !':'")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"match\" subject_expr NEWLINE")); } { // "match" subject_expr ':' NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_match_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"match\" subject_expr ':' NEWLINE !INDENT")); @@ -20309,7 +22603,7 @@ invalid_match_stmt_rule(Parser *p) _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'match' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20320,32 +22614,36 @@ invalid_match_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } // invalid_case_block: -// | "case" patterns guard? !':' +// | "case" patterns guard? NEWLINE // | "case" patterns guard? ':' NEWLINE !INDENT static void * invalid_case_block_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; - { // "case" patterns guard? !':' + { // "case" patterns guard? NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_case_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? !':'")); + D(fprintf(stderr, "%*c> invalid_case_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? NEWLINE")); expr_ty _keyword; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings + Token * newline_var; pattern_ty patterns_var; if ( (_keyword = _PyPegen_expect_soft_keyword(p, "case")) // soft_keyword='"case"' @@ -20354,25 +22652,25 @@ invalid_case_block_rule(Parser *p) && (_opt_var = guard_rule(p), !p->error_indicator) // guard? && - _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 11) // token=':' + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ invalid_case_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? !':'")); + D(fprintf(stderr, "%*c+ invalid_case_block[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? NEWLINE")); _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_case_block[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"case\" patterns guard? !':'")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"case\" patterns guard? NEWLINE")); } { // "case" patterns guard? ':' NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_case_block[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? ':' NEWLINE !INDENT")); @@ -20400,7 +22698,7 @@ invalid_case_block_rule(Parser *p) _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'case' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20411,7 +22709,7 @@ invalid_case_block_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -20419,16 +22717,19 @@ invalid_case_block_rule(Parser *p) static void * invalid_as_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // or_pattern 'as' "_" if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_as_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "or_pattern 'as' \"_\"")); @@ -20438,7 +22739,7 @@ invalid_as_pattern_rule(Parser *p) if ( (or_pattern_var = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 625)) // token='as' + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' && (a = _PyPegen_expect_soft_keyword(p, "_")) // soft_keyword='"_"' ) @@ -20447,7 +22748,7 @@ invalid_as_pattern_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot use '_' as a target" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20458,7 +22759,7 @@ invalid_as_pattern_rule(Parser *p) } { // or_pattern 'as' !NAME expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_as_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "or_pattern 'as' !NAME expression")); @@ -20468,7 +22769,7 @@ invalid_as_pattern_rule(Parser *p) if ( (or_pattern_var = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 625)) // token='as' + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' && _PyPegen_lookahead_with_name(0, _PyPegen_name_token, p) && @@ -20479,7 +22780,7 @@ invalid_as_pattern_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "invalid pattern target" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20490,7 +22791,7 @@ invalid_as_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -20498,16 +22799,19 @@ invalid_as_pattern_rule(Parser *p) static void * invalid_class_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // name_or_attr '(' invalid_class_argument_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_class_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "name_or_attr '(' invalid_class_argument_pattern")); @@ -20526,7 +22830,7 @@ invalid_class_pattern_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( PyPegen_first_item ( a , pattern_ty ) , PyPegen_last_item ( a , pattern_ty ) , "positional patterns follow keyword patterns" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20537,7 +22841,7 @@ invalid_class_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -20546,16 +22850,19 @@ invalid_class_pattern_rule(Parser *p) static asdl_pattern_seq* invalid_class_argument_pattern_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_pattern_seq* _res = NULL; int _mark = p->mark; { // [positional_patterns ','] keyword_patterns ',' positional_patterns if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_class_argument_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[positional_patterns ','] keyword_patterns ',' positional_patterns")); @@ -20565,7 +22872,7 @@ invalid_class_argument_pattern_rule(Parser *p) asdl_pattern_seq* a; asdl_seq* keyword_patterns_var; if ( - (_opt_var = _tmp_180_rule(p), !p->error_indicator) // [positional_patterns ','] + (_opt_var = _tmp_216_rule(p), !p->error_indicator) // [positional_patterns ','] && (keyword_patterns_var = keyword_patterns_rule(p)) // keyword_patterns && @@ -20578,7 +22885,7 @@ invalid_class_argument_pattern_rule(Parser *p) _res = a; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20589,7 +22896,7 @@ invalid_class_argument_pattern_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -20599,16 +22906,19 @@ invalid_class_argument_pattern_rule(Parser *p) static void * invalid_if_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'if' named_expression NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_if_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' named_expression NEWLINE")); @@ -20616,7 +22926,7 @@ invalid_if_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 627)) // token='if' + (_keyword = _PyPegen_expect_token(p, 641)) // token='if' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -20627,7 +22937,7 @@ invalid_if_stmt_rule(Parser *p) _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20638,7 +22948,7 @@ invalid_if_stmt_rule(Parser *p) } { // 'if' named_expression ':' NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_if_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' named_expression ':' NEWLINE !INDENT")); @@ -20647,7 +22957,7 @@ invalid_if_stmt_rule(Parser *p) expr_ty a_1; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 627)) // token='if' + (a = _PyPegen_expect_token(p, 641)) // token='if' && (a_1 = named_expression_rule(p)) // named_expression && @@ -20662,7 +22972,7 @@ invalid_if_stmt_rule(Parser *p) _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'if' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20673,7 +22983,7 @@ invalid_if_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -20683,16 +22993,19 @@ invalid_if_stmt_rule(Parser *p) static void * invalid_elif_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'elif' named_expression NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_elif_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'elif' named_expression NEWLINE")); @@ -20700,7 +23013,7 @@ invalid_elif_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 629)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 643)) // token='elif' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -20711,7 +23024,7 @@ invalid_elif_stmt_rule(Parser *p) _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20722,7 +23035,7 @@ invalid_elif_stmt_rule(Parser *p) } { // 'elif' named_expression ':' NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_elif_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'elif' named_expression ':' NEWLINE !INDENT")); @@ -20731,7 +23044,7 @@ invalid_elif_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 629)) // token='elif' + (a = _PyPegen_expect_token(p, 643)) // token='elif' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -20746,7 +23059,7 @@ invalid_elif_stmt_rule(Parser *p) _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'elif' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20757,7 +23070,7 @@ invalid_elif_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -20765,16 +23078,19 @@ invalid_elif_stmt_rule(Parser *p) static void * invalid_else_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'else' ':' NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_else_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else' ':' NEWLINE !INDENT")); @@ -20782,7 +23098,7 @@ invalid_else_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 630)) // token='else' + (a = _PyPegen_expect_token(p, 644)) // token='else' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -20795,7 +23111,7 @@ invalid_else_stmt_rule(Parser *p) _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'else' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20806,7 +23122,7 @@ invalid_else_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -20816,16 +23132,19 @@ invalid_else_stmt_rule(Parser *p) static void * invalid_while_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'while' named_expression NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_while_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'while' named_expression NEWLINE")); @@ -20833,7 +23152,7 @@ invalid_while_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 632)) // token='while' + (_keyword = _PyPegen_expect_token(p, 646)) // token='while' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -20844,7 +23163,7 @@ invalid_while_stmt_rule(Parser *p) _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20855,7 +23174,7 @@ invalid_while_stmt_rule(Parser *p) } { // 'while' named_expression ':' NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_while_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'while' named_expression ':' NEWLINE !INDENT")); @@ -20864,7 +23183,7 @@ invalid_while_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 632)) // token='while' + (a = _PyPegen_expect_token(p, 646)) // token='while' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -20879,7 +23198,7 @@ invalid_while_stmt_rule(Parser *p) _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'while' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20890,24 +23209,69 @@ invalid_while_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// invalid_for_stmt: ASYNC? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT +// invalid_for_stmt: +// | ASYNC? 'for' star_targets 'in' star_expressions NEWLINE +// | ASYNC? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT static void * invalid_for_stmt_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; + { // ASYNC? 'for' star_targets 'in' star_expressions NEWLINE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_targets 'in' star_expressions NEWLINE")); + Token * _keyword; + Token * _keyword_1; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + Token * newline_var; + expr_ty star_expressions_var; + expr_ty star_targets_var; + if ( + (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? + && + (_keyword = _PyPegen_expect_token(p, 649)) // token='for' + && + (star_targets_var = star_targets_rule(p)) // star_targets + && + (_keyword_1 = _PyPegen_expect_token(p, 650)) // token='in' + && + (star_expressions_var = star_expressions_rule(p)) // star_expressions + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { + D(fprintf(stderr, "%*c+ invalid_for_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_targets 'in' star_expressions NEWLINE")); + _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_for_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC? 'for' star_targets 'in' star_expressions NEWLINE")); + } { // ASYNC? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_for_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT")); @@ -20922,11 +23286,11 @@ invalid_for_stmt_rule(Parser *p) if ( (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? && - (a = _PyPegen_expect_token(p, 633)) // token='for' + (a = _PyPegen_expect_token(p, 649)) // token='for' && (star_targets_var = star_targets_rule(p)) // star_targets && - (_keyword = _PyPegen_expect_token(p, 634)) // token='in' + (_keyword = _PyPegen_expect_token(p, 650)) // token='in' && (star_expressions_var = star_expressions_rule(p)) // star_expressions && @@ -20941,7 +23305,7 @@ invalid_for_stmt_rule(Parser *p) _res = RAISE_INDENTATION_ERROR ( "expected an indented block after 'for' statement on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -20952,7 +23316,7 @@ invalid_for_stmt_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -20961,16 +23325,19 @@ invalid_for_stmt_rule(Parser *p) static void * invalid_def_raw_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ASYNC? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'def' NAME '(' params? ')' ['->' expression] ':' NEWLINE !INDENT")); @@ -20989,7 +23356,7 @@ invalid_def_raw_rule(Parser *p) if ( (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? && - (a = _PyPegen_expect_token(p, 635)) // token='def' + (a = _PyPegen_expect_token(p, 651)) // token='def' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -20999,7 +23366,7 @@ invalid_def_raw_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' && - (_opt_var_2 = _tmp_181_rule(p), !p->error_indicator) // ['->' expression] + (_opt_var_2 = _tmp_217_rule(p), !p->error_indicator) // ['->' expression] && (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -21012,7 +23379,7 @@ invalid_def_raw_rule(Parser *p) _res = RAISE_INDENTATION_ERROR ( "expected an indented block after function definition on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -21023,24 +23390,63 @@ invalid_def_raw_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// invalid_class_def_raw: 'class' NAME ['(' arguments? ')'] ':' NEWLINE !INDENT +// invalid_class_def_raw: +// | 'class' NAME ['(' arguments? ')'] NEWLINE +// | 'class' NAME ['(' arguments? ')'] ':' NEWLINE !INDENT static void * invalid_class_def_raw_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; + { // 'class' NAME ['(' arguments? ')'] NEWLINE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_class_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] NEWLINE")); + Token * _keyword; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty name_var; + Token * newline_var; + if ( + (_keyword = _PyPegen_expect_token(p, 653)) // token='class' + && + (name_var = _PyPegen_name_token(p)) // NAME + && + (_opt_var = _tmp_218_rule(p), !p->error_indicator) // ['(' arguments? ')'] + && + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { + D(fprintf(stderr, "%*c+ invalid_class_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] NEWLINE")); + _res = RAISE_SYNTAX_ERROR ( "expected ':'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_class_def_raw[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'class' NAME ['(' arguments? ')'] NEWLINE")); + } { // 'class' NAME ['(' arguments? ')'] ':' NEWLINE !INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_class_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' NEWLINE !INDENT")); @@ -21051,11 +23457,11 @@ invalid_class_def_raw_rule(Parser *p) expr_ty name_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 636)) // token='class' + (a = _PyPegen_expect_token(p, 653)) // token='class' && (name_var = _PyPegen_name_token(p)) // NAME && - (_opt_var = _tmp_182_rule(p), !p->error_indicator) // ['(' arguments? ')'] + (_opt_var = _tmp_219_rule(p), !p->error_indicator) // ['(' arguments? ')'] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -21068,7 +23474,7 @@ invalid_class_def_raw_rule(Parser *p) _res = RAISE_INDENTATION_ERROR ( "expected an indented block after class definition on line %d" , a -> lineno ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -21079,7 +23485,7 @@ invalid_class_def_raw_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -21090,24 +23496,27 @@ invalid_class_def_raw_rule(Parser *p) static void * invalid_double_starred_kvpairs_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ','.double_starred_kvpair+ ',' invalid_kvpair if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_double_starred_kvpairs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair")); - asdl_seq * _gather_183_var; + asdl_seq * _gather_220_var; Token * _literal; void *invalid_kvpair_var; if ( - (_gather_183_var = _gather_183_rule(p)) // ','.double_starred_kvpair+ + (_gather_220_var = _gather_220_rule(p)) // ','.double_starred_kvpair+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && @@ -21115,7 +23524,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair")); - _res = _PyPegen_dummy_name(p, _gather_183_var, _literal, invalid_kvpair_var); + _res = _PyPegen_dummy_name(p, _gather_220_var, _literal, invalid_kvpair_var); goto done; } p->mark = _mark; @@ -21124,7 +23533,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) } { // expression ':' '*' bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_double_starred_kvpairs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':' '*' bitwise_or")); @@ -21146,7 +23555,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "cannot use a starred expression in a dictionary value" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -21157,7 +23566,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) } { // expression ':' &('}' | ',') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_double_starred_kvpairs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); @@ -21168,14 +23577,14 @@ invalid_double_starred_kvpairs_rule(Parser *p) && (a = _PyPegen_expect_token(p, 11)) // token=':' && - _PyPegen_lookahead(1, _tmp_185_rule, p) + _PyPegen_lookahead(1, _tmp_222_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "expression expected after dictionary key and ':'" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -21186,24 +23595,30 @@ invalid_double_starred_kvpairs_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// invalid_kvpair: expression !(':') | expression ':' '*' bitwise_or | expression ':' +// invalid_kvpair: +// | expression !(':') +// | expression ':' '*' bitwise_or +// | expression ':' &('}' | ',') static void * invalid_kvpair_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // expression !(':') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !(':')")); @@ -21218,7 +23633,7 @@ invalid_kvpair_rule(Parser *p) _res = RAISE_ERROR_KNOWN_LOCATION ( p , PyExc_SyntaxError , a -> lineno , a -> end_col_offset - 1 , a -> end_lineno , - 1 , "':' expected after dictionary key" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -21229,7 +23644,7 @@ invalid_kvpair_rule(Parser *p) } { // expression ':' '*' bitwise_or if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> invalid_kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':' '*' bitwise_or")); @@ -21251,7 +23666,7 @@ invalid_kvpair_rule(Parser *p) _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "cannot use a starred expression in a dictionary value" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -21260,36 +23675,91 @@ invalid_kvpair_rule(Parser *p) D(fprintf(stderr, "%*c%s invalid_kvpair[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ':' '*' bitwise_or")); } - { // expression ':' + { // expression ':' &('}' | ',') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':'")); + D(fprintf(stderr, "%*c> invalid_kvpair[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); Token * a; expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression && (a = _PyPegen_expect_token(p, 11)) // token=':' + && + _PyPegen_lookahead(1, _tmp_223_rule, p) ) { - D(fprintf(stderr, "%*c+ invalid_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':'")); + D(fprintf(stderr, "%*c+ invalid_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "expression expected after dictionary key and ':'" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_kvpair[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ':'")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ':' &('}' | ',')")); } _res = NULL; done: - D(p->level--); + p->level--; + return _res; +} + +// invalid_starred_expression: '*' expression '=' expression +static void * +invalid_starred_expression_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '*' expression '=' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_starred_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' expression '=' expression")); + Token * _literal; + Token * a; + expr_ty b; + expr_ty expression_var; + if ( + (a = _PyPegen_expect_token(p, 16)) // token='*' + && + (expression_var = expression_rule(p)) // expression + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + && + (b = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ invalid_starred_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' expression '=' expression")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot assign to iterable argument unpacking" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_starred_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' expression '=' expression")); + } + _res = NULL; + done: + p->level--; return _res; } @@ -21297,9 +23767,12 @@ invalid_kvpair_rule(Parser *p) static asdl_seq * _loop0_1_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -21309,14 +23782,14 @@ _loop0_1_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop0_1[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); @@ -21330,9 +23803,10 @@ _loop0_1_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -21349,13 +23823,13 @@ _loop0_1_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_1_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -21363,9 +23837,12 @@ _loop0_1_rule(Parser *p) static asdl_seq * _loop0_2_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -21375,14 +23852,14 @@ _loop0_2_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop0_2[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); @@ -21396,9 +23873,10 @@ _loop0_2_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -21415,13 +23893,13 @@ _loop0_2_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_2_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -21429,9 +23907,12 @@ _loop0_2_rule(Parser *p) static asdl_seq * _loop1_3_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -21441,14 +23922,14 @@ _loop1_3_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // statement if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop1_3[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement")); @@ -21462,9 +23943,10 @@ _loop1_3_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -21478,7 +23960,7 @@ _loop1_3_rule(Parser *p) } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -21486,13 +23968,13 @@ _loop1_3_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_3_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -21500,9 +23982,12 @@ _loop1_3_rule(Parser *p) static asdl_seq * _loop0_5_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -21512,14 +23997,14 @@ _loop0_5_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ';' simple_stmt if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop0_5[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';' simple_stmt")); @@ -21535,16 +24020,17 @@ _loop0_5_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -21561,13 +24047,13 @@ _loop0_5_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_5_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -21575,16 +24061,19 @@ _loop0_5_rule(Parser *p) static asdl_seq * _gather_4_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; { // simple_stmt _loop0_5 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _gather_4[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt _loop0_5")); @@ -21606,7 +24095,7 @@ _gather_4_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -21614,22 +24103,25 @@ _gather_4_rule(Parser *p) static void * _tmp_6_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'import' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_6[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 531)) // token='import' + (_keyword = _PyPegen_expect_token(p, 606)) // token='import' ) { D(fprintf(stderr, "%*c+ _tmp_6[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import'")); @@ -21642,13 +24134,13 @@ _tmp_6_rule(Parser *p) } { // 'from' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_6[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 569)) // token='from' + (_keyword = _PyPegen_expect_token(p, 607)) // token='from' ) { D(fprintf(stderr, "%*c+ _tmp_6[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from'")); @@ -21661,7 +24153,7 @@ _tmp_6_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -21669,22 +24161,25 @@ _tmp_6_rule(Parser *p) static void * _tmp_7_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'def' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 635)) // token='def' + (_keyword = _PyPegen_expect_token(p, 651)) // token='def' ) { D(fprintf(stderr, "%*c+ _tmp_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'def'")); @@ -21697,7 +24192,7 @@ _tmp_7_rule(Parser *p) } { // '@' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'")); @@ -21716,7 +24211,7 @@ _tmp_7_rule(Parser *p) } { // ASYNC if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC")); @@ -21735,7 +24230,7 @@ _tmp_7_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -21743,22 +24238,25 @@ _tmp_7_rule(Parser *p) static void * _tmp_8_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'class' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 636)) // token='class' + (_keyword = _PyPegen_expect_token(p, 653)) // token='class' ) { D(fprintf(stderr, "%*c+ _tmp_8[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class'")); @@ -21771,7 +24269,7 @@ _tmp_8_rule(Parser *p) } { // '@' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'")); @@ -21790,7 +24288,7 @@ _tmp_8_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -21798,22 +24296,25 @@ _tmp_8_rule(Parser *p) static void * _tmp_9_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'with' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 609)) // token='with' + (_keyword = _PyPegen_expect_token(p, 614)) // token='with' ) { D(fprintf(stderr, "%*c+ _tmp_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with'")); @@ -21826,7 +24327,7 @@ _tmp_9_rule(Parser *p) } { // ASYNC if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC")); @@ -21845,7 +24346,7 @@ _tmp_9_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -21853,22 +24354,25 @@ _tmp_9_rule(Parser *p) static void * _tmp_10_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'for' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_10[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 633)) // token='for' + (_keyword = _PyPegen_expect_token(p, 649)) // token='for' ) { D(fprintf(stderr, "%*c+ _tmp_10[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for'")); @@ -21881,7 +24385,7 @@ _tmp_10_rule(Parser *p) } { // ASYNC if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_10[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC")); @@ -21900,7 +24404,7 @@ _tmp_10_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -21908,16 +24412,19 @@ _tmp_10_rule(Parser *p) static void * _tmp_11_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '=' annotated_rhs if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_11[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); @@ -21933,7 +24440,7 @@ _tmp_11_rule(Parser *p) _res = d; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -21944,7 +24451,7 @@ _tmp_11_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -21952,16 +24459,19 @@ _tmp_11_rule(Parser *p) static void * _tmp_12_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '(' single_target ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_12[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'")); @@ -21980,7 +24490,7 @@ _tmp_12_rule(Parser *p) _res = b; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -21991,7 +24501,7 @@ _tmp_12_rule(Parser *p) } { // single_subscript_attribute_target if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_12[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "single_subscript_attribute_target")); @@ -22010,7 +24520,7 @@ _tmp_12_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -22018,16 +24528,19 @@ _tmp_12_rule(Parser *p) static void * _tmp_13_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '=' annotated_rhs if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_13[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); @@ -22043,7 +24556,7 @@ _tmp_13_rule(Parser *p) _res = d; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -22054,7 +24567,7 @@ _tmp_13_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -22062,9 +24575,12 @@ _tmp_13_rule(Parser *p) static asdl_seq * _loop1_14_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -22074,30 +24590,31 @@ _loop1_14_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // (star_targets '=') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop1_14[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_186_var; + void *_tmp_224_var; while ( - (_tmp_186_var = _tmp_186_rule(p)) // star_targets '=' + (_tmp_224_var = _tmp_224_rule(p)) // star_targets '=' ) { - _res = _tmp_186_var; + _res = _tmp_224_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -22111,7 +24628,7 @@ _loop1_14_rule(Parser *p) } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -22119,13 +24636,13 @@ _loop1_14_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_14_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -22133,16 +24650,19 @@ _loop1_14_rule(Parser *p) static void * _tmp_15_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // yield_expr if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); @@ -22161,7 +24681,7 @@ _tmp_15_rule(Parser *p) } { // star_expressions if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); @@ -22180,7 +24700,7 @@ _tmp_15_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -22188,16 +24708,19 @@ _tmp_15_rule(Parser *p) static void * _tmp_16_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // yield_expr if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_16[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); @@ -22216,7 +24739,7 @@ _tmp_16_rule(Parser *p) } { // star_expressions if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_16[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); @@ -22235,7 +24758,7 @@ _tmp_16_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -22243,23 +24766,26 @@ _tmp_16_rule(Parser *p) static void * _tmp_17_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'from' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_17[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' expression")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 569)) // token='from' + (_keyword = _PyPegen_expect_token(p, 607)) // token='from' && (z = expression_rule(p)) // expression ) @@ -22268,7 +24794,7 @@ _tmp_17_rule(Parser *p) _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -22279,7 +24805,7 @@ _tmp_17_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -22287,9 +24813,12 @@ _tmp_17_rule(Parser *p) static asdl_seq * _loop0_19_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -22299,14 +24828,14 @@ _loop0_19_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop0_19[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' NAME")); @@ -22322,16 +24851,17 @@ _loop0_19_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -22348,13 +24878,13 @@ _loop0_19_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_19_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -22362,16 +24892,19 @@ _loop0_19_rule(Parser *p) static asdl_seq * _gather_18_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; { // NAME _loop0_19 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _gather_18[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME _loop0_19")); @@ -22393,7 +24926,7 @@ _gather_18_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -22401,9 +24934,12 @@ _gather_18_rule(Parser *p) static asdl_seq * _loop0_21_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -22413,14 +24949,14 @@ _loop0_21_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop0_21[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' NAME")); @@ -22436,16 +24972,17 @@ _loop0_21_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -22462,13 +24999,13 @@ _loop0_21_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_21_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -22476,16 +25013,19 @@ _loop0_21_rule(Parser *p) static asdl_seq * _gather_20_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; { // NAME _loop0_21 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _gather_20[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME _loop0_21")); @@ -22507,7 +25047,7 @@ _gather_20_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -22515,16 +25055,19 @@ _gather_20_rule(Parser *p) static void * _tmp_22_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ';' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_22[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';'")); @@ -22543,7 +25086,7 @@ _tmp_22_rule(Parser *p) } { // NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_22[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); @@ -22562,7 +25105,7 @@ _tmp_22_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -22570,16 +25113,19 @@ _tmp_22_rule(Parser *p) static void * _tmp_23_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ',' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_23[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); @@ -22595,7 +25141,7 @@ _tmp_23_rule(Parser *p) _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -22606,7 +25152,7 @@ _tmp_23_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -22614,9 +25160,12 @@ _tmp_23_rule(Parser *p) static asdl_seq * _loop0_24_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -22626,30 +25175,31 @@ _loop0_24_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ('.' | '...') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop0_24[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_187_var; + void *_tmp_225_var; while ( - (_tmp_187_var = _tmp_187_rule(p)) // '.' | '...' + (_tmp_225_var = _tmp_225_rule(p)) // '.' | '...' ) { - _res = _tmp_187_var; + _res = _tmp_225_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -22666,13 +25216,13 @@ _loop0_24_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_24_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -22680,9 +25230,12 @@ _loop0_24_rule(Parser *p) static asdl_seq * _loop1_25_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -22692,30 +25245,31 @@ _loop1_25_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ('.' | '...') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop1_25[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_188_var; + void *_tmp_226_var; while ( - (_tmp_188_var = _tmp_188_rule(p)) // '.' | '...' + (_tmp_226_var = _tmp_226_rule(p)) // '.' | '...' ) { - _res = _tmp_188_var; + _res = _tmp_226_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -22729,7 +25283,7 @@ _loop1_25_rule(Parser *p) } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -22737,13 +25291,13 @@ _loop1_25_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_25_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -22751,9 +25305,12 @@ _loop1_25_rule(Parser *p) static asdl_seq * _loop0_27_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -22763,14 +25320,14 @@ _loop0_27_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' import_from_as_name if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop0_27[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' import_from_as_name")); @@ -22786,16 +25343,17 @@ _loop0_27_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -22812,13 +25370,13 @@ _loop0_27_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_27_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -22826,16 +25384,19 @@ _loop0_27_rule(Parser *p) static asdl_seq * _gather_26_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; { // import_from_as_name _loop0_27 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _gather_26[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_name _loop0_27")); @@ -22857,7 +25418,7 @@ _gather_26_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -22865,23 +25426,26 @@ _gather_26_rule(Parser *p) static void * _tmp_28_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'as' NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_28[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 625)) // token='as' + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' && (z = _PyPegen_name_token(p)) // NAME ) @@ -22890,7 +25454,7 @@ _tmp_28_rule(Parser *p) _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -22901,7 +25465,7 @@ _tmp_28_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -22909,9 +25473,12 @@ _tmp_28_rule(Parser *p) static asdl_seq * _loop0_30_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -22921,14 +25488,14 @@ _loop0_30_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' dotted_as_name if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop0_30[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' dotted_as_name")); @@ -22944,16 +25511,17 @@ _loop0_30_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -22970,13 +25538,13 @@ _loop0_30_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_30_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -22984,16 +25552,19 @@ _loop0_30_rule(Parser *p) static asdl_seq * _gather_29_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; { // dotted_as_name _loop0_30 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _gather_29[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_as_name _loop0_30")); @@ -23015,7 +25586,7 @@ _gather_29_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -23023,23 +25594,26 @@ _gather_29_rule(Parser *p) static void * _tmp_31_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'as' NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_31[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 625)) // token='as' + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' && (z = _PyPegen_name_token(p)) // NAME ) @@ -23048,7 +25622,7 @@ _tmp_31_rule(Parser *p) _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -23059,7 +25633,7 @@ _tmp_31_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -23067,9 +25641,12 @@ _tmp_31_rule(Parser *p) static asdl_seq * _loop1_32_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -23079,30 +25656,31 @@ _loop1_32_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ('@' named_expression NEWLINE) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop1_32[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)")); - void *_tmp_189_var; + void *_tmp_227_var; while ( - (_tmp_189_var = _tmp_189_rule(p)) // '@' named_expression NEWLINE + (_tmp_227_var = _tmp_227_rule(p)) // '@' named_expression NEWLINE ) { - _res = _tmp_189_var; + _res = _tmp_227_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -23116,7 +25694,7 @@ _loop1_32_rule(Parser *p) } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -23124,13 +25702,13 @@ _loop1_32_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_32_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -23138,16 +25716,19 @@ _loop1_32_rule(Parser *p) static void * _tmp_33_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '(' arguments? ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_33[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); @@ -23166,7 +25747,7 @@ _tmp_33_rule(Parser *p) _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -23177,7 +25758,7 @@ _tmp_33_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -23185,16 +25766,19 @@ _tmp_33_rule(Parser *p) static void * _tmp_34_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '->' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_34[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); @@ -23210,7 +25794,7 @@ _tmp_34_rule(Parser *p) _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -23221,7 +25805,7 @@ _tmp_34_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -23229,16 +25813,19 @@ _tmp_34_rule(Parser *p) static void * _tmp_35_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '->' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_35[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); @@ -23254,7 +25841,7 @@ _tmp_35_rule(Parser *p) _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; @@ -23265,7 +25852,7 @@ _tmp_35_rule(Parser *p) } _res = NULL; done: - D(p->level--); + p->level--; return _res; } @@ -23273,9 +25860,12 @@ _tmp_35_rule(Parser *p) static asdl_seq * _loop0_36_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -23285,14 +25875,14 @@ _loop0_36_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_no_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop0_36[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); @@ -23306,9 +25896,10 @@ _loop0_36_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -23325,13 +25916,13 @@ _loop0_36_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_36_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -23339,9 +25930,12 @@ _loop0_36_rule(Parser *p) static asdl_seq * _loop0_37_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -23351,14 +25945,14 @@ _loop0_37_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_with_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop0_37[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); @@ -23372,9 +25966,10 @@ _loop0_37_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -23391,13 +25986,13 @@ _loop0_37_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_37_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -23405,9 +26000,12 @@ _loop0_37_rule(Parser *p) static asdl_seq * _loop0_38_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -23417,14 +26015,14 @@ _loop0_38_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_with_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop0_38[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); @@ -23438,9 +26036,10 @@ _loop0_38_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -23457,13 +26056,13 @@ _loop0_38_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_38_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -23471,9 +26070,12 @@ _loop0_38_rule(Parser *p) static asdl_seq * _loop1_39_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -23483,14 +26085,14 @@ _loop1_39_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_no_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop1_39[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); @@ -23504,9 +26106,10 @@ _loop1_39_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -23520,7 +26123,7 @@ _loop1_39_rule(Parser *p) } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -23528,13 +26131,13 @@ _loop1_39_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_39_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -23542,9 +26145,12 @@ _loop1_39_rule(Parser *p) static asdl_seq * _loop0_40_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -23554,14 +26160,14 @@ _loop0_40_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_with_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop0_40[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); @@ -23575,9 +26181,10 @@ _loop0_40_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -23594,13 +26201,13 @@ _loop0_40_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_40_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -23608,9 +26215,12 @@ _loop0_40_rule(Parser *p) static asdl_seq * _loop1_41_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -23620,14 +26230,14 @@ _loop1_41_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_with_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop1_41[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); @@ -23641,9 +26251,10 @@ _loop1_41_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -23657,7 +26268,7 @@ _loop1_41_rule(Parser *p) } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -23665,13 +26276,13 @@ _loop1_41_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_41_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -23679,9 +26290,12 @@ _loop1_41_rule(Parser *p) static asdl_seq * _loop1_42_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -23691,14 +26305,14 @@ _loop1_42_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_no_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop1_42[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); @@ -23712,9 +26326,10 @@ _loop1_42_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -23728,7 +26343,7 @@ _loop1_42_rule(Parser *p) } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -23736,13 +26351,13 @@ _loop1_42_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_42_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -23750,9 +26365,12 @@ _loop1_42_rule(Parser *p) static asdl_seq * _loop1_43_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -23762,14 +26380,14 @@ _loop1_43_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_no_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop1_43[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); @@ -23783,9 +26401,10 @@ _loop1_43_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -23799,7 +26418,7 @@ _loop1_43_rule(Parser *p) } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -23807,13 +26426,13 @@ _loop1_43_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_43_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -23821,9 +26440,12 @@ _loop1_43_rule(Parser *p) static asdl_seq * _loop0_44_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -23833,14 +26455,14 @@ _loop0_44_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_no_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop0_44[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); @@ -23854,9 +26476,10 @@ _loop0_44_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -23873,13 +26496,13 @@ _loop0_44_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_44_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -23887,9 +26510,12 @@ _loop0_44_rule(Parser *p) static asdl_seq * _loop1_45_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -23899,14 +26525,14 @@ _loop1_45_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_with_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop1_45[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); @@ -23920,9 +26546,10 @@ _loop1_45_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -23936,7 +26563,7 @@ _loop1_45_rule(Parser *p) } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -23944,13 +26571,13 @@ _loop1_45_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_45_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -23958,9 +26585,12 @@ _loop1_45_rule(Parser *p) static asdl_seq * _loop0_46_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -23970,14 +26600,14 @@ _loop0_46_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_no_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop0_46[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); @@ -23991,9 +26621,10 @@ _loop0_46_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -24010,13 +26641,13 @@ _loop0_46_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_46_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -24024,9 +26655,12 @@ _loop0_46_rule(Parser *p) static asdl_seq * _loop1_47_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -24036,14 +26670,14 @@ _loop1_47_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_with_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop1_47[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); @@ -24057,9 +26691,10 @@ _loop1_47_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -24073,7 +26708,7 @@ _loop1_47_rule(Parser *p) } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -24081,13 +26716,13 @@ _loop1_47_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_47_type, _seq); - D(p->level--); + p->level--; return _seq; } @@ -24095,9 +26730,12 @@ _loop1_47_rule(Parser *p) static asdl_seq * _loop0_48_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -24107,14 +26745,14 @@ _loop0_48_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_maybe_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop0_48[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); @@ -24128,9 +26766,10 @@ _loop0_48_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -24147,23 +26786,26 @@ _loop0_48_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_48_type, _seq); - D(p->level--); + p->level--; return _seq; } -// _loop1_49: param_maybe_default +// _loop0_49: param_maybe_default static asdl_seq * -_loop1_49_rule(Parser *p) +_loop0_49_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -24173,17 +26815,17 @@ _loop1_49_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_maybe_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_49[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_49[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -24194,9 +26836,10 @@ _loop1_49_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -24205,12 +26848,82 @@ _loop1_49_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_49[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_49[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_49_type, _seq); + p->level--; + return _seq; +} + +// _loop1_50: param_maybe_default +static asdl_seq * +_loop1_50_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_50[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + ) + { + _res = param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_50[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -24218,23 +26931,26 @@ _loop1_49_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_49_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop1_50_type, _seq); + p->level--; return _seq; } -// _loop0_51: ',' with_item +// _loop0_52: ',' with_item static asdl_seq * -_loop0_51_rule(Parser *p) +_loop0_52_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -24244,17 +26960,17 @@ _loop0_51_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' with_item if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_51[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + D(fprintf(stderr, "%*c> _loop0_52[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); Token * _literal; withitem_ty elem; while ( @@ -24267,16 +26983,17 @@ _loop0_51_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -24285,7 +27002,7 @@ _loop0_51_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_51[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_52[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -24293,62 +27010,68 @@ _loop0_51_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_51_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_52_type, _seq); + p->level--; return _seq; } -// _gather_50: with_item _loop0_51 +// _gather_51: with_item _loop0_52 static asdl_seq * -_gather_50_rule(Parser *p) +_gather_51_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // with_item _loop0_51 + { // with_item _loop0_52 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_50[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_51")); + D(fprintf(stderr, "%*c> _gather_51[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_52")); withitem_ty elem; asdl_seq * seq; if ( (elem = with_item_rule(p)) // with_item && - (seq = _loop0_51_rule(p)) // _loop0_51 + (seq = _loop0_52_rule(p)) // _loop0_52 ) { - D(fprintf(stderr, "%*c+ _gather_50[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_51")); + D(fprintf(stderr, "%*c+ _gather_51[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_52")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_50[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_51")); + D(fprintf(stderr, "%*c%s _gather_51[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_52")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_53: ',' with_item +// _loop0_54: ',' with_item static asdl_seq * -_loop0_53_rule(Parser *p) +_loop0_54_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -24358,17 +27081,17 @@ _loop0_53_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' with_item if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_53[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + D(fprintf(stderr, "%*c> _loop0_54[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); Token * _literal; withitem_ty elem; while ( @@ -24381,16 +27104,17 @@ _loop0_53_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -24399,7 +27123,7 @@ _loop0_53_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_53[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_54[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -24407,62 +27131,68 @@ _loop0_53_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_53_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_54_type, _seq); + p->level--; return _seq; } -// _gather_52: with_item _loop0_53 +// _gather_53: with_item _loop0_54 static asdl_seq * -_gather_52_rule(Parser *p) +_gather_53_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // with_item _loop0_53 + { // with_item _loop0_54 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_52[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_53")); + D(fprintf(stderr, "%*c> _gather_53[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_54")); withitem_ty elem; asdl_seq * seq; if ( (elem = with_item_rule(p)) // with_item && - (seq = _loop0_53_rule(p)) // _loop0_53 + (seq = _loop0_54_rule(p)) // _loop0_54 ) { - D(fprintf(stderr, "%*c+ _gather_52[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_53")); + D(fprintf(stderr, "%*c+ _gather_53[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_54")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_52[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_53")); + D(fprintf(stderr, "%*c%s _gather_53[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_54")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_55: ',' with_item +// _loop0_56: ',' with_item static asdl_seq * -_loop0_55_rule(Parser *p) +_loop0_56_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -24472,17 +27202,17 @@ _loop0_55_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' with_item if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_55[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + D(fprintf(stderr, "%*c> _loop0_56[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); Token * _literal; withitem_ty elem; while ( @@ -24495,16 +27225,17 @@ _loop0_55_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -24513,7 +27244,7 @@ _loop0_55_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_55[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_56[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -24521,62 +27252,68 @@ _loop0_55_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_55_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_56_type, _seq); + p->level--; return _seq; } -// _gather_54: with_item _loop0_55 +// _gather_55: with_item _loop0_56 static asdl_seq * -_gather_54_rule(Parser *p) +_gather_55_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // with_item _loop0_55 + { // with_item _loop0_56 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_54[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_55")); + D(fprintf(stderr, "%*c> _gather_55[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_56")); withitem_ty elem; asdl_seq * seq; if ( (elem = with_item_rule(p)) // with_item && - (seq = _loop0_55_rule(p)) // _loop0_55 + (seq = _loop0_56_rule(p)) // _loop0_56 ) { - D(fprintf(stderr, "%*c+ _gather_54[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_55")); + D(fprintf(stderr, "%*c+ _gather_55[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_56")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_54[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_55")); + D(fprintf(stderr, "%*c%s _gather_55[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_56")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_57: ',' with_item +// _loop0_58: ',' with_item static asdl_seq * -_loop0_57_rule(Parser *p) +_loop0_58_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -24586,17 +27323,17 @@ _loop0_57_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' with_item if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_57[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + D(fprintf(stderr, "%*c> _loop0_58[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); Token * _literal; withitem_ty elem; while ( @@ -24609,16 +27346,17 @@ _loop0_57_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -24627,7 +27365,7 @@ _loop0_57_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_57[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_58[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -24635,136 +27373,145 @@ _loop0_57_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_57_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_58_type, _seq); + p->level--; return _seq; } -// _gather_56: with_item _loop0_57 +// _gather_57: with_item _loop0_58 static asdl_seq * -_gather_56_rule(Parser *p) +_gather_57_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // with_item _loop0_57 + { // with_item _loop0_58 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_56[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_57")); + D(fprintf(stderr, "%*c> _gather_57[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_58")); withitem_ty elem; asdl_seq * seq; if ( (elem = with_item_rule(p)) // with_item && - (seq = _loop0_57_rule(p)) // _loop0_57 + (seq = _loop0_58_rule(p)) // _loop0_58 ) { - D(fprintf(stderr, "%*c+ _gather_56[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_57")); + D(fprintf(stderr, "%*c+ _gather_57[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_58")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_56[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_57")); + D(fprintf(stderr, "%*c%s _gather_57[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_58")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_58: ',' | ')' | ':' +// _tmp_59: ',' | ')' | ':' static void * -_tmp_58_rule(Parser *p) +_tmp_59_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_58[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_58[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_59[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_58[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_59[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_58[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_58[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_59[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_58[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_59[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ':' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_58[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_58[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_59[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_58[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_59[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop1_59: except_block +// _loop1_60: except_block static asdl_seq * -_loop1_59_rule(Parser *p) +_loop1_60_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -24774,17 +27521,17 @@ _loop1_59_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // except_block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); + D(fprintf(stderr, "%*c> _loop1_60[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); excepthandler_ty except_block_var; while ( (except_block_var = except_block_rule(p)) // except_block @@ -24795,9 +27542,10 @@ _loop1_59_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -24806,12 +27554,12 @@ _loop1_59_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_59[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_60[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_block")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -24819,67 +27567,26 @@ _loop1_59_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_59_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop1_60_type, _seq); + p->level--; return _seq; } -// _tmp_60: 'as' NAME -static void * -_tmp_60_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // 'as' NAME - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_60[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - Token * _keyword; - expr_ty z; - if ( - (_keyword = _PyPegen_expect_token(p, 625)) // token='as' - && - (z = _PyPegen_name_token(p)) // NAME - ) - { - D(fprintf(stderr, "%*c+ _tmp_60[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - _res = z; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - D(p->level--); - return NULL; - } - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_60[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _loop1_61: case_block +// _loop1_61: except_star_block static asdl_seq * _loop1_61_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -24889,17 +27596,186 @@ _loop1_61_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // except_star_block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_61[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); + excepthandler_ty except_star_block_var; + while ( + (except_star_block_var = except_star_block_rule(p)) // except_star_block + ) + { + _res = except_star_block_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_61[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_star_block")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop1_61_type, _seq); + p->level--; + return _seq; +} + +// _tmp_62: 'as' NAME +static void * +_tmp_62_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // 'as' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_62[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty z; + if ( + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' + && + (z = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ _tmp_62[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _res = z; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_62[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_63: 'as' NAME +static void * +_tmp_63_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // 'as' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_63[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty z; + if ( + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' + && + (z = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ _tmp_63[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _res = z; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_63[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop1_64: case_block +static asdl_seq * +_loop1_64_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // case_block if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_61[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "case_block")); + D(fprintf(stderr, "%*c> _loop1_64[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "case_block")); match_case_ty case_block_var; while ( (case_block_var = case_block_rule(p)) // case_block @@ -24910,9 +27786,10 @@ _loop1_61_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -24921,12 +27798,12 @@ _loop1_61_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_61[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_64[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "case_block")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -24934,23 +27811,26 @@ _loop1_61_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_61_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop1_64_type, _seq); + p->level--; return _seq; } -// _loop0_63: '|' closed_pattern +// _loop0_66: '|' closed_pattern static asdl_seq * -_loop0_63_rule(Parser *p) +_loop0_66_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -24960,17 +27840,17 @@ _loop0_63_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // '|' closed_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_63[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|' closed_pattern")); + D(fprintf(stderr, "%*c> _loop0_66[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|' closed_pattern")); Token * _literal; pattern_ty elem; while ( @@ -24983,16 +27863,17 @@ _loop0_63_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -25001,7 +27882,7 @@ _loop0_63_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_63[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_66[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'|' closed_pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -25009,320 +27890,338 @@ _loop0_63_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_63_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_66_type, _seq); + p->level--; return _seq; } -// _gather_62: closed_pattern _loop0_63 +// _gather_65: closed_pattern _loop0_66 static asdl_seq * -_gather_62_rule(Parser *p) +_gather_65_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // closed_pattern _loop0_63 + { // closed_pattern _loop0_66 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_62[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_63")); + D(fprintf(stderr, "%*c> _gather_65[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_66")); pattern_ty elem; asdl_seq * seq; if ( (elem = closed_pattern_rule(p)) // closed_pattern && - (seq = _loop0_63_rule(p)) // _loop0_63 + (seq = _loop0_66_rule(p)) // _loop0_66 ) { - D(fprintf(stderr, "%*c+ _gather_62[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_63")); + D(fprintf(stderr, "%*c+ _gather_65[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_66")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_62[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "closed_pattern _loop0_63")); + D(fprintf(stderr, "%*c%s _gather_65[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "closed_pattern _loop0_66")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_64: '+' | '-' -static void * -_tmp_64_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // '+' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_64[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 14)) // token='+' - ) - { - D(fprintf(stderr, "%*c+ _tmp_64[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_64[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'+'")); - } - { // '-' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_64[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 15)) // token='-' - ) - { - D(fprintf(stderr, "%*c+ _tmp_64[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_64[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-'")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _tmp_65: '+' | '-' -static void * -_tmp_65_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // '+' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_65[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 14)) // token='+' - ) - { - D(fprintf(stderr, "%*c+ _tmp_65[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_65[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'+'")); - } - { // '-' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_65[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 15)) // token='-' - ) - { - D(fprintf(stderr, "%*c+ _tmp_65[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_65[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-'")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _tmp_66: '.' | '(' | '=' -static void * -_tmp_66_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // '.' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_66[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 23)) // token='.' - ) - { - D(fprintf(stderr, "%*c+ _tmp_66[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_66[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); - } - { // '(' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_66[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - ) - { - D(fprintf(stderr, "%*c+ _tmp_66[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_66[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); - } - { // '=' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_66[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 22)) // token='=' - ) - { - D(fprintf(stderr, "%*c+ _tmp_66[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_66[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _tmp_67: '.' | '(' | '=' +// _tmp_67: '+' | '-' static void * _tmp_67_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '+' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 14)) // token='+' + ) + { + D(fprintf(stderr, "%*c+ _tmp_67[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_67[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'+'")); + } + { // '-' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 15)) // token='-' + ) + { + D(fprintf(stderr, "%*c+ _tmp_67[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_67[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_68: '+' | '-' +static void * +_tmp_68_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '+' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 14)) // token='+' + ) + { + D(fprintf(stderr, "%*c+ _tmp_68[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_68[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'+'")); + } + { // '-' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 15)) // token='-' + ) + { + D(fprintf(stderr, "%*c+ _tmp_68[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_68[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_69: '.' | '(' | '=' +static void * +_tmp_69_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '.' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_67[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_67[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '(' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' ) { - D(fprintf(stderr, "%*c+ _tmp_67[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_67[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); } { // '=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_67[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_67[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_69: ',' maybe_star_pattern -static asdl_seq * -_loop0_69_rule(Parser *p) +// _tmp_70: '.' | '(' | '=' +static void * +_tmp_70_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '.' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 23)) // token='.' + ) + { + D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); + } + { // '(' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + ) + { + D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); + } + { // '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_72: ',' maybe_star_pattern +static asdl_seq * +_loop0_72_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void *_res = NULL; @@ -25332,17 +28231,17 @@ _loop0_69_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' maybe_star_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' maybe_star_pattern")); + D(fprintf(stderr, "%*c> _loop0_72[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' maybe_star_pattern")); Token * _literal; pattern_ty elem; while ( @@ -25355,16 +28254,17 @@ _loop0_69_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -25373,7 +28273,7 @@ _loop0_69_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_69[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_72[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' maybe_star_pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -25381,62 +28281,68 @@ _loop0_69_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_69_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_72_type, _seq); + p->level--; return _seq; } -// _gather_68: maybe_star_pattern _loop0_69 +// _gather_71: maybe_star_pattern _loop0_72 static asdl_seq * -_gather_68_rule(Parser *p) +_gather_71_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // maybe_star_pattern _loop0_69 + { // maybe_star_pattern _loop0_72 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_69")); + D(fprintf(stderr, "%*c> _gather_71[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_72")); pattern_ty elem; asdl_seq * seq; if ( (elem = maybe_star_pattern_rule(p)) // maybe_star_pattern && - (seq = _loop0_69_rule(p)) // _loop0_69 + (seq = _loop0_72_rule(p)) // _loop0_72 ) { - D(fprintf(stderr, "%*c+ _gather_68[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_69")); + D(fprintf(stderr, "%*c+ _gather_71[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_72")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_68[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "maybe_star_pattern _loop0_69")); + D(fprintf(stderr, "%*c%s _gather_71[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "maybe_star_pattern _loop0_72")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_71: ',' key_value_pattern +// _loop0_74: ',' key_value_pattern static asdl_seq * -_loop0_71_rule(Parser *p) +_loop0_74_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -25446,17 +28352,17 @@ _loop0_71_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' key_value_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_71[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' key_value_pattern")); + D(fprintf(stderr, "%*c> _loop0_74[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' key_value_pattern")); Token * _literal; KeyPatternPair* elem; while ( @@ -25469,185 +28375,17 @@ _loop0_71_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_71[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' key_value_pattern")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_71_type, _seq); - D(p->level--); - return _seq; -} - -// _gather_70: key_value_pattern _loop0_71 -static asdl_seq * -_gather_70_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // key_value_pattern _loop0_71 - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _gather_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_71")); - KeyPatternPair* elem; - asdl_seq * seq; - if ( - (elem = key_value_pattern_rule(p)) // key_value_pattern - && - (seq = _loop0_71_rule(p)) // _loop0_71 - ) - { - D(fprintf(stderr, "%*c+ _gather_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_71")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_70[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "key_value_pattern _loop0_71")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _tmp_72: literal_expr | attr -static void * -_tmp_72_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // literal_expr - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_72[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "literal_expr")); - expr_ty literal_expr_var; - if ( - (literal_expr_var = literal_expr_rule(p)) // literal_expr - ) - { - D(fprintf(stderr, "%*c+ _tmp_72[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "literal_expr")); - _res = literal_expr_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_72[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "literal_expr")); - } - { // attr - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_72[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "attr")); - expr_ty attr_var; - if ( - (attr_var = attr_rule(p)) // attr - ) - { - D(fprintf(stderr, "%*c+ _tmp_72[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "attr")); - _res = attr_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_72[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "attr")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _loop0_74: ',' pattern -static asdl_seq * -_loop0_74_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // ',' pattern - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_74[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' pattern")); - Token * _literal; - pattern_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = pattern_rule(p)) // pattern - ) - { - _res = elem; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - PyMem_Free(_children); - D(p->level--); - return NULL; - } - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -25657,6 +28395,185 @@ _loop0_74_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s _loop0_74[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' key_value_pattern")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_74_type, _seq); + p->level--; + return _seq; +} + +// _gather_73: key_value_pattern _loop0_74 +static asdl_seq * +_gather_73_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // key_value_pattern _loop0_74 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_73[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_74")); + KeyPatternPair* elem; + asdl_seq * seq; + if ( + (elem = key_value_pattern_rule(p)) // key_value_pattern + && + (seq = _loop0_74_rule(p)) // _loop0_74 + ) + { + D(fprintf(stderr, "%*c+ _gather_73[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_74")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_73[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "key_value_pattern _loop0_74")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_75: literal_expr | attr +static void * +_tmp_75_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // literal_expr + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_75[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "literal_expr")); + expr_ty literal_expr_var; + if ( + (literal_expr_var = literal_expr_rule(p)) // literal_expr + ) + { + D(fprintf(stderr, "%*c+ _tmp_75[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "literal_expr")); + _res = literal_expr_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_75[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "literal_expr")); + } + { // attr + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_75[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "attr")); + expr_ty attr_var; + if ( + (attr_var = attr_rule(p)) // attr + ) + { + D(fprintf(stderr, "%*c+ _tmp_75[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "attr")); + _res = attr_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_75[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "attr")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_77: ',' pattern +static asdl_seq * +_loop0_77_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' pattern + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_77[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' pattern")); + Token * _literal; + pattern_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = pattern_rule(p)) // pattern + ) + { + _res = elem; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + PyMem_Free(_children); + p->level--; + return NULL; + } + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_77[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -25664,62 +28581,68 @@ _loop0_74_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_74_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_77_type, _seq); + p->level--; return _seq; } -// _gather_73: pattern _loop0_74 +// _gather_76: pattern _loop0_77 static asdl_seq * -_gather_73_rule(Parser *p) +_gather_76_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // pattern _loop0_74 + { // pattern _loop0_77 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_73[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern _loop0_74")); + D(fprintf(stderr, "%*c> _gather_76[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern _loop0_77")); pattern_ty elem; asdl_seq * seq; if ( (elem = pattern_rule(p)) // pattern && - (seq = _loop0_74_rule(p)) // _loop0_74 + (seq = _loop0_77_rule(p)) // _loop0_77 ) { - D(fprintf(stderr, "%*c+ _gather_73[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "pattern _loop0_74")); + D(fprintf(stderr, "%*c+ _gather_76[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "pattern _loop0_77")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_73[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "pattern _loop0_74")); + D(fprintf(stderr, "%*c%s _gather_76[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "pattern _loop0_77")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_76: ',' keyword_pattern +// _loop0_79: ',' keyword_pattern static asdl_seq * -_loop0_76_rule(Parser *p) +_loop0_79_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -25729,17 +28652,17 @@ _loop0_76_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' keyword_pattern if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_76[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' keyword_pattern")); + D(fprintf(stderr, "%*c> _loop0_79[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' keyword_pattern")); Token * _literal; KeyPatternPair* elem; while ( @@ -25752,16 +28675,17 @@ _loop0_76_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -25770,7 +28694,7 @@ _loop0_76_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_76[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_79[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' keyword_pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -25778,62 +28702,68 @@ _loop0_76_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_76_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_79_type, _seq); + p->level--; return _seq; } -// _gather_75: keyword_pattern _loop0_76 +// _gather_78: keyword_pattern _loop0_79 static asdl_seq * -_gather_75_rule(Parser *p) +_gather_78_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // keyword_pattern _loop0_76 + { // keyword_pattern _loop0_79 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_75[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_76")); + D(fprintf(stderr, "%*c> _gather_78[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_79")); KeyPatternPair* elem; asdl_seq * seq; if ( (elem = keyword_pattern_rule(p)) // keyword_pattern && - (seq = _loop0_76_rule(p)) // _loop0_76 + (seq = _loop0_79_rule(p)) // _loop0_79 ) { - D(fprintf(stderr, "%*c+ _gather_75[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_76")); + D(fprintf(stderr, "%*c+ _gather_78[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_79")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_75[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "keyword_pattern _loop0_76")); + D(fprintf(stderr, "%*c%s _gather_78[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "keyword_pattern _loop0_79")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop1_77: (',' expression) +// _loop1_80: (',' expression) static asdl_seq * -_loop1_77_rule(Parser *p) +_loop1_80_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -25843,30 +28773,31 @@ _loop1_77_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // (',' expression) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_77[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); - void *_tmp_190_var; + D(fprintf(stderr, "%*c> _loop1_80[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); + void *_tmp_228_var; while ( - (_tmp_190_var = _tmp_190_rule(p)) // ',' expression + (_tmp_228_var = _tmp_228_rule(p)) // ',' expression ) { - _res = _tmp_190_var; + _res = _tmp_228_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -25875,12 +28806,12 @@ _loop1_77_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_77[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_80[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' expression)")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -25888,23 +28819,26 @@ _loop1_77_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_77_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop1_80_type, _seq); + p->level--; return _seq; } -// _loop1_78: (',' star_expression) +// _loop1_81: (',' star_expression) static asdl_seq * -_loop1_78_rule(Parser *p) +_loop1_81_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -25914,215 +28848,31 @@ _loop1_78_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // (',' star_expression) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_78[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); - void *_tmp_191_var; + D(fprintf(stderr, "%*c> _loop1_81[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); + void *_tmp_229_var; while ( - (_tmp_191_var = _tmp_191_rule(p)) // ',' star_expression + (_tmp_229_var = _tmp_229_rule(p)) // ',' star_expression ) { - _res = _tmp_191_var; + _res = _tmp_229_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_78[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_expression)")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - D(p->level--); - return NULL; - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_78_type, _seq); - D(p->level--); - return _seq; -} - -// _loop0_80: ',' star_named_expression -static asdl_seq * -_loop0_80_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // ',' star_named_expression - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_80[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_named_expression")); - Token * _literal; - expr_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = star_named_expression_rule(p)) // star_named_expression - ) - { - _res = elem; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - PyMem_Free(_children); - D(p->level--); - return NULL; - } - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_80[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_named_expression")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_80_type, _seq); - D(p->level--); - return _seq; -} - -// _gather_79: star_named_expression _loop0_80 -static asdl_seq * -_gather_79_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // star_named_expression _loop0_80 - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _gather_79[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_80")); - expr_ty elem; - asdl_seq * seq; - if ( - (elem = star_named_expression_rule(p)) // star_named_expression - && - (seq = _loop0_80_rule(p)) // _loop0_80 - ) - { - D(fprintf(stderr, "%*c+ _gather_79[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_80")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_79[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression _loop0_80")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _loop1_81: ('or' conjunction) -static asdl_seq * -_loop1_81_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // ('or' conjunction) - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_81[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); - void *_tmp_192_var; - while ( - (_tmp_192_var = _tmp_192_rule(p)) // 'or' conjunction - ) - { - _res = _tmp_192_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -26132,11 +28882,11 @@ _loop1_81_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s _loop1_81[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('or' conjunction)")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_expression)")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26144,23 +28894,26 @@ _loop1_81_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_81_type, _seq); - D(p->level--); + p->level--; return _seq; } -// _loop1_82: ('and' inversion) +// _loop0_83: ',' star_named_expression static asdl_seq * -_loop1_82_rule(Parser *p) +_loop0_83_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -26170,30 +28923,40 @@ _loop1_82_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // ('and' inversion) + { // ',' star_named_expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_82[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); - void *_tmp_193_var; + D(fprintf(stderr, "%*c> _loop0_83[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_named_expression")); + Token * _literal; + expr_ty elem; while ( - (_tmp_193_var = _tmp_193_rule(p)) // 'and' inversion + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = star_named_expression_rule(p)) // star_named_expression ) { - _res = _tmp_193_var; + _res = elem; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + PyMem_Free(_children); + p->level--; + return NULL; + } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -26202,36 +28965,76 @@ _loop1_82_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_82[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('and' inversion)")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - D(p->level--); - return NULL; + D(fprintf(stderr, "%*c%s _loop0_83[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_named_expression")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_82_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_83_type, _seq); + p->level--; return _seq; } -// _loop1_83: compare_op_bitwise_or_pair +// _gather_82: star_named_expression _loop0_83 static asdl_seq * -_loop1_83_rule(Parser *p) +_gather_82_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // star_named_expression _loop0_83 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_82[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_83")); + expr_ty elem; + asdl_seq * seq; + if ( + (elem = star_named_expression_rule(p)) // star_named_expression + && + (seq = _loop0_83_rule(p)) // _loop0_83 + ) + { + D(fprintf(stderr, "%*c+ _gather_82[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_83")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_82[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression _loop0_83")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop1_84: ('or' conjunction) +static asdl_seq * +_loop1_84_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void *_res = NULL; @@ -26241,17 +29044,167 @@ _loop1_83_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ('or' conjunction) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_84[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); + void *_tmp_230_var; + while ( + (_tmp_230_var = _tmp_230_rule(p)) // 'or' conjunction + ) + { + _res = _tmp_230_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_84[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('or' conjunction)")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop1_84_type, _seq); + p->level--; + return _seq; +} + +// _loop1_85: ('and' inversion) +static asdl_seq * +_loop1_85_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ('and' inversion) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_85[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); + void *_tmp_231_var; + while ( + (_tmp_231_var = _tmp_231_rule(p)) // 'and' inversion + ) + { + _res = _tmp_231_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_85[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('and' inversion)")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop1_85_type, _seq); + p->level--; + return _seq; +} + +// _loop1_86: compare_op_bitwise_or_pair +static asdl_seq * +_loop1_86_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // compare_op_bitwise_or_pair if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_83[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compare_op_bitwise_or_pair")); + D(fprintf(stderr, "%*c> _loop1_86[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compare_op_bitwise_or_pair")); CmpopExprPair* compare_op_bitwise_or_pair_var; while ( (compare_op_bitwise_or_pair_var = compare_op_bitwise_or_pair_rule(p)) // compare_op_bitwise_or_pair @@ -26262,9 +29215,10 @@ _loop1_83_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -26273,12 +29227,12 @@ _loop1_83_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_83[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_86[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "compare_op_bitwise_or_pair")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26286,64 +29240,70 @@ _loop1_83_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_83_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop1_86_type, _seq); + p->level--; return _seq; } -// _tmp_84: '!=' +// _tmp_87: '!=' static void * -_tmp_84_rule(Parser *p) +_tmp_87_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '!=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_84[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!='")); + D(fprintf(stderr, "%*c> _tmp_87[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!='")); Token * tok; if ( (tok = _PyPegen_expect_token(p, 28)) // token='!=' ) { - D(fprintf(stderr, "%*c+ _tmp_84[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!='")); + D(fprintf(stderr, "%*c+ _tmp_87[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!='")); _res = _PyPegen_check_barry_as_flufl ( p , tok ) ? NULL : tok; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_84[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_87[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!='")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_86: ',' slice +// _loop0_89: ',' (slice | starred_expression) static asdl_seq * -_loop0_86_rule(Parser *p) +_loop0_89_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -26353,39 +29313,40 @@ _loop0_86_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // ',' slice + { // ',' (slice | starred_expression) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_86[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' slice")); + D(fprintf(stderr, "%*c> _loop0_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (slice | starred_expression)")); Token * _literal; - expr_ty elem; + void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = slice_rule(p)) // slice + (elem = _tmp_232_rule(p)) // slice | starred_expression ) { _res = elem; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -26394,80 +29355,86 @@ _loop0_86_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_86[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' slice")); + D(fprintf(stderr, "%*c%s _loop0_89[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (slice | starred_expression)")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_86_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_89_type, _seq); + p->level--; return _seq; } -// _gather_85: slice _loop0_86 +// _gather_88: (slice | starred_expression) _loop0_89 static asdl_seq * -_gather_85_rule(Parser *p) +_gather_88_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // slice _loop0_86 + { // (slice | starred_expression) _loop0_89 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_85[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice _loop0_86")); - expr_ty elem; + D(fprintf(stderr, "%*c> _gather_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slice | starred_expression) _loop0_89")); + void *elem; asdl_seq * seq; if ( - (elem = slice_rule(p)) // slice + (elem = _tmp_232_rule(p)) // slice | starred_expression && - (seq = _loop0_86_rule(p)) // _loop0_86 + (seq = _loop0_89_rule(p)) // _loop0_89 ) { - D(fprintf(stderr, "%*c+ _gather_85[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice _loop0_86")); + D(fprintf(stderr, "%*c+ _gather_88[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(slice | starred_expression) _loop0_89")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_85[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slice _loop0_86")); + D(fprintf(stderr, "%*c%s _gather_88[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(slice | starred_expression) _loop0_89")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_87: ':' expression? +// _tmp_90: ':' expression? static void * -_tmp_87_rule(Parser *p) +_tmp_90_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ':' expression? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_87[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression?")); + D(fprintf(stderr, "%*c> _tmp_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression?")); Token * _literal; void *d; if ( @@ -26476,309 +29443,324 @@ _tmp_87_rule(Parser *p) (d = expression_rule(p), !p->error_indicator) // expression? ) { - D(fprintf(stderr, "%*c+ _tmp_87[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression?")); + D(fprintf(stderr, "%*c+ _tmp_90[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression?")); _res = d; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_87[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_90[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':' expression?")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_88: tuple | group | genexp +// _tmp_91: tuple | group | genexp static void * -_tmp_88_rule(Parser *p) +_tmp_91_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // tuple if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c> _tmp_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); expr_ty tuple_var; if ( (tuple_var = tuple_rule(p)) // tuple ) { - D(fprintf(stderr, "%*c+ _tmp_88[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c+ _tmp_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); _res = tuple_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_88[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_91[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple")); } { // group if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "group")); + D(fprintf(stderr, "%*c> _tmp_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "group")); expr_ty group_var; if ( (group_var = group_rule(p)) // group ) { - D(fprintf(stderr, "%*c+ _tmp_88[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "group")); + D(fprintf(stderr, "%*c+ _tmp_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "group")); _res = group_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_88[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_91[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "group")); } { // genexp if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c> _tmp_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); expr_ty genexp_var; if ( (genexp_var = genexp_rule(p)) // genexp ) { - D(fprintf(stderr, "%*c+ _tmp_88[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c+ _tmp_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); _res = genexp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_88[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_91[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "genexp")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_89: list | listcomp +// _tmp_92: list | listcomp static void * -_tmp_89_rule(Parser *p) +_tmp_92_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // list if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); + D(fprintf(stderr, "%*c> _tmp_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); expr_ty list_var; if ( (list_var = list_rule(p)) // list ) { - D(fprintf(stderr, "%*c+ _tmp_89[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); + D(fprintf(stderr, "%*c+ _tmp_92[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); _res = list_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_89[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_92[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "list")); } { // listcomp if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "listcomp")); + D(fprintf(stderr, "%*c> _tmp_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "listcomp")); expr_ty listcomp_var; if ( (listcomp_var = listcomp_rule(p)) // listcomp ) { - D(fprintf(stderr, "%*c+ _tmp_89[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "listcomp")); + D(fprintf(stderr, "%*c+ _tmp_92[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "listcomp")); _res = listcomp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_89[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_92[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "listcomp")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_90: dict | set | dictcomp | setcomp +// _tmp_93: dict | set | dictcomp | setcomp static void * -_tmp_90_rule(Parser *p) +_tmp_93_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // dict if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dict")); + D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dict")); expr_ty dict_var; if ( (dict_var = dict_rule(p)) // dict ) { - D(fprintf(stderr, "%*c+ _tmp_90[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dict")); + D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dict")); _res = dict_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_90[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dict")); } { // set if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "set")); + D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "set")); expr_ty set_var; if ( (set_var = set_rule(p)) // set ) { - D(fprintf(stderr, "%*c+ _tmp_90[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "set")); + D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "set")); _res = set_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_90[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "set")); } { // dictcomp if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dictcomp")); + D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dictcomp")); expr_ty dictcomp_var; if ( (dictcomp_var = dictcomp_rule(p)) // dictcomp ) { - D(fprintf(stderr, "%*c+ _tmp_90[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dictcomp")); + D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dictcomp")); _res = dictcomp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_90[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dictcomp")); } { // setcomp if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "setcomp")); + D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "setcomp")); expr_ty setcomp_var; if ( (setcomp_var = setcomp_rule(p)) // setcomp ) { - D(fprintf(stderr, "%*c+ _tmp_90[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "setcomp")); + D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "setcomp")); _res = setcomp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_90[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "setcomp")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_91: yield_expr | named_expression +// _tmp_94: yield_expr | named_expression static void * -_tmp_91_rule(Parser *p) +_tmp_94_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // yield_expr if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_91[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // named_expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression")); + D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression")); expr_ty named_expression_var; if ( (named_expression_var = named_expression_rule(p)) // named_expression ) { - D(fprintf(stderr, "%*c+ _tmp_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression")); + D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression")); _res = named_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_91[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "named_expression")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_92: lambda_param_no_default +// _loop0_95: lambda_param_no_default static asdl_seq * -_loop0_92_rule(Parser *p) +_loop0_95_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -26788,17 +29770,17 @@ _loop0_92_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // lambda_param_no_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -26809,9 +29791,10 @@ _loop0_92_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -26820,7 +29803,7 @@ _loop0_92_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_92[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_95[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26828,216 +29811,13 @@ _loop0_92_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_92_type, _seq); - D(p->level--); - return _seq; -} - -// _loop0_93: lambda_param_with_default -static asdl_seq * -_loop0_93_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // lambda_param_with_default - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); - NameDefaultPair* lambda_param_with_default_var; - while ( - (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default - ) - { - _res = lambda_param_with_default_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_93[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_93_type, _seq); - D(p->level--); - return _seq; -} - -// _loop0_94: lambda_param_with_default -static asdl_seq * -_loop0_94_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // lambda_param_with_default - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); - NameDefaultPair* lambda_param_with_default_var; - while ( - (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default - ) - { - _res = lambda_param_with_default_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_94[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_94_type, _seq); - D(p->level--); - return _seq; -} - -// _loop1_95: lambda_param_no_default -static asdl_seq * -_loop1_95_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // lambda_param_no_default - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); - arg_ty lambda_param_no_default_var; - while ( - (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default - ) - { - _res = lambda_param_no_default_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_95[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - D(p->level--); - return NULL; - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_95_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_95_type, _seq); + p->level--; return _seq; } @@ -27045,9 +29825,12 @@ _loop1_95_rule(Parser *p) static asdl_seq * _loop0_96_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -27057,14 +29840,14 @@ _loop0_96_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // lambda_param_with_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop0_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); @@ -27078,9 +29861,10 @@ _loop0_96_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -27097,23 +29881,26 @@ _loop0_96_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_96_type, _seq); - D(p->level--); + p->level--; return _seq; } -// _loop1_97: lambda_param_with_default +// _loop0_97: lambda_param_with_default static asdl_seq * -_loop1_97_rule(Parser *p) +_loop0_97_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -27123,17 +29910,17 @@ _loop1_97_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // lambda_param_with_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop0_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -27144,9 +29931,10 @@ _loop1_97_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -27155,26 +29943,21 @@ _loop1_97_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_97[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_97[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - D(p->level--); - return NULL; - } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_97_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_97_type, _seq); + p->level--; return _seq; } @@ -27182,9 +29965,12 @@ _loop1_97_rule(Parser *p) static asdl_seq * _loop1_98_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -27194,14 +29980,14 @@ _loop1_98_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // lambda_param_no_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _loop1_98[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); @@ -27215,9 +30001,10 @@ _loop1_98_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -27231,7 +30018,7 @@ _loop1_98_rule(Parser *p) } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27239,23 +30026,26 @@ _loop1_98_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_98_type, _seq); - D(p->level--); + p->level--; return _seq; } -// _loop1_99: lambda_param_no_default +// _loop0_99: lambda_param_with_default static asdl_seq * -_loop1_99_rule(Parser *p) +_loop0_99_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -27265,154 +30055,17 @@ _loop1_99_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // lambda_param_no_default - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _loop1_99[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); - arg_ty lambda_param_no_default_var; - while ( - (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default - ) - { - _res = lambda_param_no_default_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_99[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - D(p->level--); - return NULL; - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_99_type, _seq); - D(p->level--); - return _seq; -} - -// _loop0_100: lambda_param_no_default -static asdl_seq * -_loop0_100_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // lambda_param_no_default - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_100[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); - arg_ty lambda_param_no_default_var; - while ( - (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default - ) - { - _res = lambda_param_no_default_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_100[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_100_type, _seq); - D(p->level--); - return _seq; -} - -// _loop1_101: lambda_param_with_default -static asdl_seq * -_loop1_101_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // lambda_param_with_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_101[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop0_99[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -27423,9 +30076,155 @@ _loop1_101_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_99[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_99_type, _seq); + p->level--; + return _seq; +} + +// _loop1_100: lambda_param_with_default +static asdl_seq * +_loop1_100_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_100[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + NameDefaultPair* lambda_param_with_default_var; + while ( + (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default + ) + { + _res = lambda_param_with_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_100[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop1_100_type, _seq); + p->level--; + return _seq; +} + +// _loop1_101: lambda_param_no_default +static asdl_seq * +_loop1_101_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_101[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + while ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { + _res = lambda_param_no_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; return NULL; } _children = _new_children; @@ -27435,11 +30234,11 @@ _loop1_101_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s _loop1_101[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27447,23 +30246,26 @@ _loop1_101_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop1_101_type, _seq); - D(p->level--); + p->level--; return _seq; } -// _loop0_102: lambda_param_no_default +// _loop1_102: lambda_param_no_default static asdl_seq * -_loop0_102_rule(Parser *p) +_loop1_102_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -27473,17 +30275,17 @@ _loop0_102_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // lambda_param_no_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_102[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop1_102[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -27494,9 +30296,10 @@ _loop0_102_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -27505,31 +30308,39 @@ _loop0_102_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_102[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_102[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_102_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop1_102_type, _seq); + p->level--; return _seq; } -// _loop1_103: lambda_param_with_default +// _loop0_103: lambda_param_no_default static asdl_seq * -_loop1_103_rule(Parser *p) +_loop0_103_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -27539,17 +30350,87 @@ _loop1_103_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_103[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + while ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { + _res = lambda_param_no_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_103[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_103_type, _seq); + p->level--; + return _seq; +} + +// _loop1_104: lambda_param_with_default +static asdl_seq * +_loop1_104_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // lambda_param_with_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_103[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop1_104[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -27560,9 +30441,10 @@ _loop1_103_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -27571,12 +30453,12 @@ _loop1_103_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_103[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_104[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27584,23 +30466,26 @@ _loop1_103_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_103_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop1_104_type, _seq); + p->level--; return _seq; } -// _loop0_104: lambda_param_maybe_default +// _loop0_105: lambda_param_no_default static asdl_seq * -_loop0_104_rule(Parser *p) +_loop0_105_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -27610,17 +30495,162 @@ _loop0_104_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_105[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + while ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { + _res = lambda_param_no_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_105[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_105_type, _seq); + p->level--; + return _seq; +} + +// _loop1_106: lambda_param_with_default +static asdl_seq * +_loop1_106_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_106[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + NameDefaultPair* lambda_param_with_default_var; + while ( + (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default + ) + { + _res = lambda_param_with_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_106[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop1_106_type, _seq); + p->level--; + return _seq; +} + +// _loop0_107: lambda_param_maybe_default +static asdl_seq * +_loop0_107_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // lambda_param_maybe_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_104[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_107[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -27631,9 +30661,10 @@ _loop0_104_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -27642,7 +30673,7 @@ _loop0_104_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_104[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_107[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27650,23 +30681,26 @@ _loop0_104_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_104_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_107_type, _seq); + p->level--; return _seq; } -// _loop1_105: lambda_param_maybe_default +// _loop1_108: lambda_param_maybe_default static asdl_seq * -_loop1_105_rule(Parser *p) +_loop1_108_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -27676,17 +30710,17 @@ _loop1_105_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // lambda_param_maybe_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_105[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop1_108[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -27697,9 +30731,10 @@ _loop1_105_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -27708,12 +30743,12 @@ _loop1_105_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_105[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_108[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27721,23 +30756,26 @@ _loop1_105_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_105_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop1_108_type, _seq); + p->level--; return _seq; } -// _loop1_106: STRING +// _loop1_109: STRING static asdl_seq * -_loop1_106_rule(Parser *p) +_loop1_109_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -27747,17 +30785,17 @@ _loop1_106_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // STRING if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_106[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING")); + D(fprintf(stderr, "%*c> _loop1_109[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING")); expr_ty string_var; while ( (string_var = _PyPegen_string_token(p)) // STRING @@ -27768,9 +30806,10 @@ _loop1_106_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -27779,12 +30818,12 @@ _loop1_106_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_106[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_109[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "STRING")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27792,33 +30831,36 @@ _loop1_106_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_106_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop1_109_type, _seq); + p->level--; return _seq; } -// _tmp_107: star_named_expression ',' star_named_expressions? +// _tmp_110: star_named_expression ',' star_named_expressions? static void * -_tmp_107_rule(Parser *p) +_tmp_110_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // star_named_expression ',' star_named_expressions? if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_107[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); + D(fprintf(stderr, "%*c> _tmp_110[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); Token * _literal; expr_ty y; void *z; @@ -27830,32 +30872,35 @@ _tmp_107_rule(Parser *p) (z = star_named_expressions_rule(p), !p->error_indicator) // star_named_expressions? ) { - D(fprintf(stderr, "%*c+ _tmp_107[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); + D(fprintf(stderr, "%*c+ _tmp_110[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); _res = _PyPegen_seq_insert_in_front ( p , y , z ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_107[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_110[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression ',' star_named_expressions?")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_109: ',' double_starred_kvpair +// _loop0_112: ',' double_starred_kvpair static asdl_seq * -_loop0_109_rule(Parser *p) +_loop0_112_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -27865,17 +30910,17 @@ _loop0_109_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' double_starred_kvpair if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_109[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); + D(fprintf(stderr, "%*c> _loop0_112[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); Token * _literal; KeyValuePair* elem; while ( @@ -27888,16 +30933,17 @@ _loop0_109_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -27906,7 +30952,7 @@ _loop0_109_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_109[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_112[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' double_starred_kvpair")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27914,62 +30960,68 @@ _loop0_109_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_109_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_112_type, _seq); + p->level--; return _seq; } -// _gather_108: double_starred_kvpair _loop0_109 +// _gather_111: double_starred_kvpair _loop0_112 static asdl_seq * -_gather_108_rule(Parser *p) +_gather_111_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // double_starred_kvpair _loop0_109 + { // double_starred_kvpair _loop0_112 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_108[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_109")); + D(fprintf(stderr, "%*c> _gather_111[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_112")); KeyValuePair* elem; asdl_seq * seq; if ( (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair && - (seq = _loop0_109_rule(p)) // _loop0_109 + (seq = _loop0_112_rule(p)) // _loop0_112 ) { - D(fprintf(stderr, "%*c+ _gather_108[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_109")); + D(fprintf(stderr, "%*c+ _gather_111[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_112")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_108[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_109")); + D(fprintf(stderr, "%*c%s _gather_111[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_112")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop1_110: for_if_clause +// _loop1_113: for_if_clause static asdl_seq * -_loop1_110_rule(Parser *p) +_loop1_113_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -27979,17 +31031,17 @@ _loop1_110_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // for_if_clause if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_110[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "for_if_clause")); + D(fprintf(stderr, "%*c> _loop1_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "for_if_clause")); comprehension_ty for_if_clause_var; while ( (for_if_clause_var = for_if_clause_rule(p)) // for_if_clause @@ -28000,9 +31052,10 @@ _loop1_110_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -28011,12 +31064,12 @@ _loop1_110_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_110[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_113[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "for_if_clause")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28024,23 +31077,26 @@ _loop1_110_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_110_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop1_113_type, _seq); + p->level--; return _seq; } -// _loop0_111: ('if' disjunction) +// _loop0_114: ('if' disjunction) static asdl_seq * -_loop0_111_rule(Parser *p) +_loop0_114_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -28050,30 +31106,31 @@ _loop0_111_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ('if' disjunction) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_111[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_194_var; + D(fprintf(stderr, "%*c> _loop0_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); + void *_tmp_233_var; while ( - (_tmp_194_var = _tmp_194_rule(p)) // 'if' disjunction + (_tmp_233_var = _tmp_233_rule(p)) // 'if' disjunction ) { - _res = _tmp_194_var; + _res = _tmp_233_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -28082,7 +31139,7 @@ _loop0_111_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_111[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_114[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('if' disjunction)")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28090,146 +31147,26 @@ _loop0_111_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_111_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_114_type, _seq); + p->level--; return _seq; } -// _loop0_112: ('if' disjunction) -static asdl_seq * -_loop0_112_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // ('if' disjunction) - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_112[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_195_var; - while ( - (_tmp_195_var = _tmp_195_rule(p)) // 'if' disjunction - ) - { - _res = _tmp_195_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_112[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('if' disjunction)")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_112_type, _seq); - D(p->level--); - return _seq; -} - -// _tmp_113: assignment_expression | expression !':=' -static void * -_tmp_113_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // assignment_expression - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); - expr_ty assignment_expression_var; - if ( - (assignment_expression_var = assignment_expression_rule(p)) // assignment_expression - ) - { - D(fprintf(stderr, "%*c+ _tmp_113[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); - _res = assignment_expression_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_113[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); - } - { // expression !':=' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); - expr_ty expression_var; - if ( - (expression_var = expression_rule(p)) // expression - && - _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' - ) - { - D(fprintf(stderr, "%*c+ _tmp_113[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); - _res = expression_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_113[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _loop0_115: ',' (starred_expression | (assignment_expression | expression !':=') !'=') +// _loop0_115: ('if' disjunction) static asdl_seq * _loop0_115_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -28239,39 +31176,31 @@ _loop0_115_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // ',' (starred_expression | (assignment_expression | expression !':=') !'=') + { // ('if' disjunction) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); - Token * _literal; - void *elem; + D(fprintf(stderr, "%*c> _loop0_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); + void *_tmp_234_var; while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = _tmp_196_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + (_tmp_234_var = _tmp_234_rule(p)) // 'if' disjunction ) { - _res = elem; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - PyMem_Free(_children); - D(p->level--); - return NULL; - } + _res = _tmp_234_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -28281,114 +31210,93 @@ _loop0_115_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s _loop0_115[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('if' disjunction)")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_115_type, _seq); - D(p->level--); + p->level--; return _seq; } -// _gather_114: -// | (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_115 -static asdl_seq * -_gather_114_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_115 - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _gather_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_115")); - void *elem; - asdl_seq * seq; - if ( - (elem = _tmp_196_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' - && - (seq = _loop0_115_rule(p)) // _loop0_115 - ) - { - D(fprintf(stderr, "%*c+ _gather_114[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_115")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_114[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_115")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _tmp_116: ',' kwargs +// _tmp_116: assignment_expression | expression !':=' static void * _tmp_116_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; - { // ',' kwargs + { // assignment_expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_116[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwargs")); - Token * _literal; - asdl_seq* k; + D(fprintf(stderr, "%*c> _tmp_116[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + expr_ty assignment_expression_var; if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (k = kwargs_rule(p)) // kwargs + (assignment_expression_var = assignment_expression_rule(p)) // assignment_expression ) { - D(fprintf(stderr, "%*c+ _tmp_116[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' kwargs")); - _res = k; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - D(p->level--); - return NULL; - } + D(fprintf(stderr, "%*c+ _tmp_116[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + _res = assignment_expression_var; goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s _tmp_116[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwargs")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); + } + { // expression !':=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_116[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_116[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); + _res = expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_116[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_118: ',' kwarg_or_starred +// _loop0_118: ',' (starred_expression | (assignment_expression | expression !':=') !'=') static asdl_seq * _loop0_118_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -28398,39 +31306,40 @@ _loop0_118_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // ',' kwarg_or_starred + { // ',' (starred_expression | (assignment_expression | expression !':=') !'=') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_118[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); + D(fprintf(stderr, "%*c> _loop0_118[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); Token * _literal; - KeywordOrStarred* elem; + void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred + (elem = _tmp_235_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' ) { _res = elem; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -28440,183 +31349,123 @@ _loop0_118_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s _loop0_118[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_118_type, _seq); - D(p->level--); + p->level--; return _seq; } -// _gather_117: kwarg_or_starred _loop0_118 +// _gather_117: +// | (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_118 static asdl_seq * _gather_117_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // kwarg_or_starred _loop0_118 + { // (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_118 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_118")); - KeywordOrStarred* elem; + D(fprintf(stderr, "%*c> _gather_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_118")); + void *elem; asdl_seq * seq; if ( - (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred + (elem = _tmp_235_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' && (seq = _loop0_118_rule(p)) // _loop0_118 ) { - D(fprintf(stderr, "%*c+ _gather_117[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_118")); + D(fprintf(stderr, "%*c+ _gather_117[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_118")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s _gather_117[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_118")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_118")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_120: ',' kwarg_or_double_starred -static asdl_seq * -_loop0_120_rule(Parser *p) +// _tmp_119: ',' kwargs +static void * +_tmp_119_rule(Parser *p) { - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { + if (p->level++ == MAXSTACK) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + } + if (p->error_indicator) { + p->level--; return NULL; } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // ',' kwarg_or_double_starred + void * _res = NULL; + int _mark = p->mark; + { // ',' kwargs if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); + D(fprintf(stderr, "%*c> _tmp_119[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwargs")); Token * _literal; - KeywordOrStarred* elem; - while ( + asdl_seq* k; + if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred + (k = kwargs_rule(p)) // kwargs ) { - _res = elem; + D(fprintf(stderr, "%*c+ _tmp_119[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' kwargs")); + _res = k; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_120[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_120_type, _seq); - D(p->level--); - return _seq; -} - -// _gather_119: kwarg_or_double_starred _loop0_120 -static asdl_seq * -_gather_119_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // kwarg_or_double_starred _loop0_120 - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _gather_119[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_120")); - KeywordOrStarred* elem; - asdl_seq * seq; - if ( - (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred - && - (seq = _loop0_120_rule(p)) // _loop0_120 - ) - { - D(fprintf(stderr, "%*c+ _gather_119[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_120")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_119[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_120")); + D(fprintf(stderr, "%*c%s _tmp_119[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwargs")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_122: ',' kwarg_or_starred +// _loop0_121: ',' kwarg_or_starred static asdl_seq * -_loop0_122_rule(Parser *p) +_loop0_121_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -28626,17 +31475,17 @@ _loop0_122_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' kwarg_or_starred if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); + D(fprintf(stderr, "%*c> _loop0_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); Token * _literal; KeywordOrStarred* elem; while ( @@ -28649,16 +31498,17 @@ _loop0_122_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -28667,7 +31517,7 @@ _loop0_122_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_122[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_121[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28675,62 +31525,68 @@ _loop0_122_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_122_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_121_type, _seq); + p->level--; return _seq; } -// _gather_121: kwarg_or_starred _loop0_122 +// _gather_120: kwarg_or_starred _loop0_121 static asdl_seq * -_gather_121_rule(Parser *p) +_gather_120_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // kwarg_or_starred _loop0_122 + { // kwarg_or_starred _loop0_121 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_122")); + D(fprintf(stderr, "%*c> _gather_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_121")); KeywordOrStarred* elem; asdl_seq * seq; if ( (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred && - (seq = _loop0_122_rule(p)) // _loop0_122 + (seq = _loop0_121_rule(p)) // _loop0_121 ) { - D(fprintf(stderr, "%*c+ _gather_121[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_122")); + D(fprintf(stderr, "%*c+ _gather_120[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_121")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_121[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_122")); + D(fprintf(stderr, "%*c%s _gather_120[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_121")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_124: ',' kwarg_or_double_starred +// _loop0_123: ',' kwarg_or_double_starred static asdl_seq * -_loop0_124_rule(Parser *p) +_loop0_123_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -28740,17 +31596,17 @@ _loop0_124_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' kwarg_or_double_starred if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_124[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); + D(fprintf(stderr, "%*c> _loop0_123[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); Token * _literal; KeywordOrStarred* elem; while ( @@ -28763,16 +31619,17 @@ _loop0_124_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -28781,7 +31638,7 @@ _loop0_124_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_124[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_123[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28789,62 +31646,68 @@ _loop0_124_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_124_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_123_type, _seq); + p->level--; return _seq; } -// _gather_123: kwarg_or_double_starred _loop0_124 +// _gather_122: kwarg_or_double_starred _loop0_123 static asdl_seq * -_gather_123_rule(Parser *p) +_gather_122_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // kwarg_or_double_starred _loop0_124 + { // kwarg_or_double_starred _loop0_123 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_123[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_124")); + D(fprintf(stderr, "%*c> _gather_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_123")); KeywordOrStarred* elem; asdl_seq * seq; if ( (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred && - (seq = _loop0_124_rule(p)) // _loop0_124 + (seq = _loop0_123_rule(p)) // _loop0_123 ) { - D(fprintf(stderr, "%*c+ _gather_123[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_124")); + D(fprintf(stderr, "%*c+ _gather_122[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_123")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_123[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_124")); + D(fprintf(stderr, "%*c%s _gather_122[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_123")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_125: (',' star_target) +// _loop0_125: ',' kwarg_or_starred static asdl_seq * _loop0_125_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -28854,30 +31717,40 @@ _loop0_125_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // (',' star_target) + { // ',' kwarg_or_starred if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_125[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_197_var; + D(fprintf(stderr, "%*c> _loop0_125[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); + Token * _literal; + KeywordOrStarred* elem; while ( - (_tmp_197_var = _tmp_197_rule(p)) // ',' star_target + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred ) { - _res = _tmp_197_var; + _res = elem; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + PyMem_Free(_children); + p->level--; + return NULL; + } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -28887,30 +31760,75 @@ _loop0_125_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s _loop0_125[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_target)")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_125_type, _seq); - D(p->level--); + p->level--; return _seq; } -// _loop0_127: ',' star_target +// _gather_124: kwarg_or_starred _loop0_125 +static asdl_seq * +_gather_124_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // kwarg_or_starred _loop0_125 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_124[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_125")); + KeywordOrStarred* elem; + asdl_seq * seq; + if ( + (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred + && + (seq = _loop0_125_rule(p)) // _loop0_125 + ) + { + D(fprintf(stderr, "%*c+ _gather_124[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_125")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_124[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_125")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_127: ',' kwarg_or_double_starred static asdl_seq * _loop0_127_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -28920,39 +31838,40 @@ _loop0_127_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // ',' star_target + { // ',' kwarg_or_double_starred if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _loop0_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); Token * _literal; - expr_ty elem; + KeywordOrStarred* elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = star_target_rule(p)) // star_target + (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred ) { _res = elem; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -28962,6 +31881,197 @@ _loop0_127_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s _loop0_127[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_127_type, _seq); + p->level--; + return _seq; +} + +// _gather_126: kwarg_or_double_starred _loop0_127 +static asdl_seq * +_gather_126_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // kwarg_or_double_starred _loop0_127 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_126[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_127")); + KeywordOrStarred* elem; + asdl_seq * seq; + if ( + (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred + && + (seq = _loop0_127_rule(p)) // _loop0_127 + ) + { + D(fprintf(stderr, "%*c+ _gather_126[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_127")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_126[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_127")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_128: (',' star_target) +static asdl_seq * +_loop0_128_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // (',' star_target) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); + void *_tmp_236_var; + while ( + (_tmp_236_var = _tmp_236_rule(p)) // ',' star_target + ) + { + _res = _tmp_236_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_128[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_target)")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_128_type, _seq); + p->level--; + return _seq; +} + +// _loop0_130: ',' star_target +static asdl_seq * +_loop0_130_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' star_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + Token * _literal; + expr_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = star_target_rule(p)) // star_target + ) + { + _res = elem; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + PyMem_Free(_children); + p->level--; + return NULL; + } + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_130[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28969,62 +32079,68 @@ _loop0_127_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_127_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_130_type, _seq); + p->level--; return _seq; } -// _gather_126: star_target _loop0_127 +// _gather_129: star_target _loop0_130 static asdl_seq * -_gather_126_rule(Parser *p) +_gather_129_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // star_target _loop0_127 + { // star_target _loop0_130 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_126[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target _loop0_127")); + D(fprintf(stderr, "%*c> _gather_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target _loop0_130")); expr_ty elem; asdl_seq * seq; if ( (elem = star_target_rule(p)) // star_target && - (seq = _loop0_127_rule(p)) // _loop0_127 + (seq = _loop0_130_rule(p)) // _loop0_130 ) { - D(fprintf(stderr, "%*c+ _gather_126[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target _loop0_127")); + D(fprintf(stderr, "%*c+ _gather_129[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target _loop0_130")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_126[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target _loop0_127")); + D(fprintf(stderr, "%*c%s _gather_129[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target _loop0_130")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop1_128: (',' star_target) +// _loop1_131: (',' star_target) static asdl_seq * -_loop1_128_rule(Parser *p) +_loop1_131_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -29034,30 +32150,31 @@ _loop1_128_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // (',' star_target) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_198_var; + D(fprintf(stderr, "%*c> _loop1_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); + void *_tmp_237_var; while ( - (_tmp_198_var = _tmp_198_rule(p)) // ',' star_target + (_tmp_237_var = _tmp_237_rule(p)) // ',' star_target ) { - _res = _tmp_198_var; + _res = _tmp_237_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -29066,12 +32183,12 @@ _loop1_128_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_128[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_131[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_target)")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29079,33 +32196,36 @@ _loop1_128_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_128_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop1_131_type, _seq); + p->level--; return _seq; } -// _tmp_129: !'*' star_target +// _tmp_132: !'*' star_target static void * -_tmp_129_rule(Parser *p) +_tmp_132_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // !'*' star_target if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!'*' star_target")); + D(fprintf(stderr, "%*c> _tmp_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!'*' star_target")); expr_ty star_target_var; if ( _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 16) // token='*' @@ -29113,27 +32233,30 @@ _tmp_129_rule(Parser *p) (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_129[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!'*' star_target")); + D(fprintf(stderr, "%*c+ _tmp_132[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!'*' star_target")); _res = star_target_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_129[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_132[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "!'*' star_target")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_131: ',' del_target +// _loop0_134: ',' del_target static asdl_seq * -_loop0_131_rule(Parser *p) +_loop0_134_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -29143,17 +32266,17 @@ _loop0_131_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' del_target if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' del_target")); + D(fprintf(stderr, "%*c> _loop0_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' del_target")); Token * _literal; expr_ty elem; while ( @@ -29166,16 +32289,17 @@ _loop0_131_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -29184,7 +32308,7 @@ _loop0_131_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_131[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_134[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' del_target")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29192,62 +32316,68 @@ _loop0_131_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_131_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_134_type, _seq); + p->level--; return _seq; } -// _gather_130: del_target _loop0_131 +// _gather_133: del_target _loop0_134 static asdl_seq * -_gather_130_rule(Parser *p) +_gather_133_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // del_target _loop0_131 + { // del_target _loop0_134 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_target _loop0_131")); + D(fprintf(stderr, "%*c> _gather_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_target _loop0_134")); expr_ty elem; asdl_seq * seq; if ( (elem = del_target_rule(p)) // del_target && - (seq = _loop0_131_rule(p)) // _loop0_131 + (seq = _loop0_134_rule(p)) // _loop0_134 ) { - D(fprintf(stderr, "%*c+ _gather_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "del_target _loop0_131")); + D(fprintf(stderr, "%*c+ _gather_133[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "del_target _loop0_134")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_130[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "del_target _loop0_131")); + D(fprintf(stderr, "%*c%s _gather_133[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "del_target _loop0_134")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_133: ',' expression +// _loop0_136: ',' expression static asdl_seq * -_loop0_133_rule(Parser *p) +_loop0_136_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -29257,17 +32387,17 @@ _loop0_133_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _loop0_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty elem; while ( @@ -29280,16 +32410,17 @@ _loop0_133_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -29298,7 +32429,7 @@ _loop0_133_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_133[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_136[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29306,62 +32437,68 @@ _loop0_133_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_133_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_136_type, _seq); + p->level--; return _seq; } -// _gather_132: expression _loop0_133 +// _gather_135: expression _loop0_136 static asdl_seq * -_gather_132_rule(Parser *p) +_gather_135_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // expression _loop0_133 + { // expression _loop0_136 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_133")); + D(fprintf(stderr, "%*c> _gather_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_136")); expr_ty elem; asdl_seq * seq; if ( (elem = expression_rule(p)) // expression && - (seq = _loop0_133_rule(p)) // _loop0_133 + (seq = _loop0_136_rule(p)) // _loop0_136 ) { - D(fprintf(stderr, "%*c+ _gather_132[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_133")); + D(fprintf(stderr, "%*c+ _gather_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_136")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_132[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_133")); + D(fprintf(stderr, "%*c%s _gather_135[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_136")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_135: ',' expression +// _loop0_138: ',' expression static asdl_seq * -_loop0_135_rule(Parser *p) +_loop0_138_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -29371,17 +32508,17 @@ _loop0_135_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _loop0_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty elem; while ( @@ -29394,16 +32531,17 @@ _loop0_135_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -29412,7 +32550,7 @@ _loop0_135_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_135[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_138[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29420,62 +32558,68 @@ _loop0_135_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_135_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_138_type, _seq); + p->level--; return _seq; } -// _gather_134: expression _loop0_135 +// _gather_137: expression _loop0_138 static asdl_seq * -_gather_134_rule(Parser *p) +_gather_137_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // expression _loop0_135 + { // expression _loop0_138 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_135")); + D(fprintf(stderr, "%*c> _gather_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_138")); expr_ty elem; asdl_seq * seq; if ( (elem = expression_rule(p)) // expression && - (seq = _loop0_135_rule(p)) // _loop0_135 + (seq = _loop0_138_rule(p)) // _loop0_138 ) { - D(fprintf(stderr, "%*c+ _gather_134[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_135")); + D(fprintf(stderr, "%*c+ _gather_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_138")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_134[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_135")); + D(fprintf(stderr, "%*c%s _gather_137[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_138")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_137: ',' expression +// _loop0_140: ',' expression static asdl_seq * -_loop0_137_rule(Parser *p) +_loop0_140_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -29485,17 +32629,17 @@ _loop0_137_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _loop0_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty elem; while ( @@ -29508,16 +32652,17 @@ _loop0_137_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -29526,7 +32671,7 @@ _loop0_137_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_137[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_140[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29534,62 +32679,68 @@ _loop0_137_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_137_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_140_type, _seq); + p->level--; return _seq; } -// _gather_136: expression _loop0_137 +// _gather_139: expression _loop0_140 static asdl_seq * -_gather_136_rule(Parser *p) +_gather_139_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // expression _loop0_137 + { // expression _loop0_140 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_137")); + D(fprintf(stderr, "%*c> _gather_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_140")); expr_ty elem; asdl_seq * seq; if ( (elem = expression_rule(p)) // expression && - (seq = _loop0_137_rule(p)) // _loop0_137 + (seq = _loop0_140_rule(p)) // _loop0_140 ) { - D(fprintf(stderr, "%*c+ _gather_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_137")); + D(fprintf(stderr, "%*c+ _gather_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_140")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_136[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_137")); + D(fprintf(stderr, "%*c%s _gather_139[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_140")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_139: ',' expression +// _loop0_142: ',' expression static asdl_seq * -_loop0_139_rule(Parser *p) +_loop0_142_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -29599,17 +32750,17 @@ _loop0_139_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _loop0_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty elem; while ( @@ -29622,16 +32773,17 @@ _loop0_139_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -29640,7 +32792,7 @@ _loop0_139_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_139[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_142[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29648,72 +32800,78 @@ _loop0_139_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_139_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_142_type, _seq); + p->level--; return _seq; } -// _gather_138: expression _loop0_139 +// _gather_141: expression _loop0_142 static asdl_seq * -_gather_138_rule(Parser *p) +_gather_141_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // expression _loop0_139 + { // expression _loop0_142 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_139")); + D(fprintf(stderr, "%*c> _gather_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_142")); expr_ty elem; asdl_seq * seq; if ( (elem = expression_rule(p)) // expression && - (seq = _loop0_139_rule(p)) // _loop0_139 + (seq = _loop0_142_rule(p)) // _loop0_142 ) { - D(fprintf(stderr, "%*c+ _gather_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_139")); + D(fprintf(stderr, "%*c+ _gather_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_142")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_138[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_139")); + D(fprintf(stderr, "%*c%s _gather_141[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_142")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_140: NEWLINE INDENT +// _tmp_143: NEWLINE INDENT static void * -_tmp_140_rule(Parser *p) +_tmp_143_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // NEWLINE INDENT if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT")); + D(fprintf(stderr, "%*c> _tmp_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT")); Token * indent_var; Token * newline_var; if ( @@ -29722,56 +32880,59 @@ _tmp_140_rule(Parser *p) (indent_var = _PyPegen_expect_token(p, INDENT)) // token='INDENT' ) { - D(fprintf(stderr, "%*c+ _tmp_140[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT")); + D(fprintf(stderr, "%*c+ _tmp_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT")); _res = _PyPegen_dummy_name(p, newline_var, indent_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_140[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_143[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE INDENT")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_141: args | expression for_if_clauses +// _tmp_144: args | expression for_if_clauses static void * -_tmp_141_rule(Parser *p) +_tmp_144_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // args if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args")); + D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args")); expr_ty args_var; if ( (args_var = args_rule(p)) // args ) { - D(fprintf(stderr, "%*c+ _tmp_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args")); + D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args")); _res = args_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_141[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args")); } { // expression for_if_clauses if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); + D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); expr_ty expression_var; asdl_comprehension_seq* for_if_clauses_var; if ( @@ -29780,378 +32941,143 @@ _tmp_141_rule(Parser *p) (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses ) { - D(fprintf(stderr, "%*c+ _tmp_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); + D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); _res = _PyPegen_dummy_name(p, expression_var, for_if_clauses_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_141[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression for_if_clauses")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_142: 'True' | 'False' | 'None' -static void * -_tmp_142_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // 'True' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 597)) // token='True' - ) - { - D(fprintf(stderr, "%*c+ _tmp_142[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); - _res = _keyword; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_142[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'")); - } - { // 'False' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 599)) // token='False' - ) - { - D(fprintf(stderr, "%*c+ _tmp_142[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); - _res = _keyword; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_142[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); - } - { // 'None' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 598)) // token='None' - ) - { - D(fprintf(stderr, "%*c+ _tmp_142[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); - _res = _keyword; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_142[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _tmp_143: NAME '=' -static void * -_tmp_143_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // NAME '=' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '='")); - Token * _literal; - expr_ty name_var; - if ( - (name_var = _PyPegen_name_token(p)) // NAME - && - (_literal = _PyPegen_expect_token(p, 22)) // token='=' - ) - { - D(fprintf(stderr, "%*c+ _tmp_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '='")); - _res = _PyPegen_dummy_name(p, name_var, _literal); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_143[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '='")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _tmp_144: NAME STRING | SOFT_KEYWORD -static void * -_tmp_144_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // NAME STRING - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME STRING")); - expr_ty name_var; - expr_ty string_var; - if ( - (name_var = _PyPegen_name_token(p)) // NAME - && - (string_var = _PyPegen_string_token(p)) // STRING - ) - { - D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME STRING")); - _res = _PyPegen_dummy_name(p, name_var, string_var); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME STRING")); - } - { // SOFT_KEYWORD - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); - expr_ty soft_keyword_var; - if ( - (soft_keyword_var = _PyPegen_soft_keyword_token(p)) // SOFT_KEYWORD - ) - { - D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); - _res = soft_keyword_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "SOFT_KEYWORD")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _tmp_145: 'else' | ':' +// _tmp_145: args ',' static void * _tmp_145_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; - { // 'else' + { // args ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 630)) // token='else' - ) - { - D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'")); - _res = _keyword; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'else'")); - } - { // ':' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ','")); Token * _literal; + expr_ty args_var; if ( - (_literal = _PyPegen_expect_token(p, 11)) // token=':' + (args_var = args_rule(p)) // args + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); - _res = _literal; + D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ','")); + _res = _PyPegen_dummy_name(p, args_var, _literal); goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args ','")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_146: '=' | ':=' +// _tmp_146: ',' | ')' static void * _tmp_146_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; - { // '=' + { // ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( - (_literal = _PyPegen_expect_token(p, 22)) // token='=' + (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s _tmp_146[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } - { // ':=' + { // ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( - (_literal = _PyPegen_expect_token(p, 53)) // token=':=' + (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s _tmp_146[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_147: list | tuple | genexp | 'True' | 'None' | 'False' +// _tmp_147: 'True' | 'False' | 'None' static void * _tmp_147_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; - { // list - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); - expr_ty list_var; - if ( - (list_var = list_rule(p)) // list - ) - { - D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); - _res = list_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "list")); - } - { // tuple - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); - expr_ty tuple_var; - if ( - (tuple_var = tuple_rule(p)) // tuple - ) - { - D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); - _res = tuple_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple")); - } - { // genexp - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); - expr_ty genexp_var; - if ( - (genexp_var = genexp_rule(p)) // genexp - ) - { - D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); - _res = genexp_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "genexp")); - } { // 'True' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 597)) // token='True' + (_keyword = _PyPegen_expect_token(p, 600)) // token='True' ) { D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); @@ -30162,34 +33088,15 @@ _tmp_147_rule(Parser *p) D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'")); } - { // 'None' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 598)) // token='None' - ) - { - D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); - _res = _keyword; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); - } { // 'False' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 599)) // token='False' + (_keyword = _PyPegen_expect_token(p, 602)) // token='False' ) { D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); @@ -30200,74 +33107,452 @@ _tmp_147_rule(Parser *p) D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); } + { // 'None' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 601)) // token='None' + ) + { + D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); + } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_148: '=' | ':=' +// _tmp_148: NAME '=' static void * _tmp_148_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // NAME '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '='")); + Token * _literal; + expr_ty name_var; + if ( + (name_var = _PyPegen_name_token(p)) // NAME + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '='")); + _res = _PyPegen_dummy_name(p, name_var, _literal); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_149: NAME STRING | SOFT_KEYWORD +static void * +_tmp_149_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // NAME STRING + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME STRING")); + expr_ty name_var; + expr_ty string_var; + if ( + (name_var = _PyPegen_name_token(p)) // NAME + && + (string_var = _PyPegen_string_token(p)) // STRING + ) + { + D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME STRING")); + _res = _PyPegen_dummy_name(p, name_var, string_var); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME STRING")); + } + { // SOFT_KEYWORD + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); + expr_ty soft_keyword_var; + if ( + (soft_keyword_var = _PyPegen_soft_keyword_token(p)) // SOFT_KEYWORD + ) + { + D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); + _res = soft_keyword_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "SOFT_KEYWORD")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_150: 'else' | ':' +static void * +_tmp_150_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // 'else' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 644)) // token='else' + ) + { + D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'else'")); + } + { // ':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_151: '=' | ':=' +static void * +_tmp_151_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } { // ':=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 53)) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_149: star_named_expressions -static asdl_seq * -_loop0_149_rule(Parser *p) +// _tmp_152: list | tuple | genexp | 'True' | 'None' | 'False' +static void * +_tmp_152_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // list + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); + expr_ty list_var; + if ( + (list_var = list_rule(p)) // list + ) + { + D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); + _res = list_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "list")); + } + { // tuple + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); + expr_ty tuple_var; + if ( + (tuple_var = tuple_rule(p)) // tuple + ) + { + D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); + _res = tuple_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple")); + } + { // genexp + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); + expr_ty genexp_var; + if ( + (genexp_var = genexp_rule(p)) // genexp + ) + { + D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); + _res = genexp_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "genexp")); + } + { // 'True' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 600)) // token='True' + ) + { + D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'")); + } + { // 'None' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 601)) // token='None' + ) + { + D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); + } + { // 'False' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 602)) // token='False' + ) + { + D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_153: '=' | ':=' +static void * +_tmp_153_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); + } + { // ':=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 53)) // token=':=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_154: star_named_expressions +static asdl_seq * +_loop0_154_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void *_res = NULL; @@ -30277,17 +33562,17 @@ _loop0_149_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // star_named_expressions if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); + D(fprintf(stderr, "%*c> _loop0_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); asdl_expr_seq* star_named_expressions_var; while ( (star_named_expressions_var = star_named_expressions_rule(p)) // star_named_expressions @@ -30298,9 +33583,10 @@ _loop0_149_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -30309,7 +33595,7 @@ _loop0_149_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_149[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_154[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expressions")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30317,23 +33603,26 @@ _loop0_149_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_149_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_154_type, _seq); + p->level--; return _seq; } -// _loop0_150: (star_targets '=') +// _loop0_155: (star_targets '=') static asdl_seq * -_loop0_150_rule(Parser *p) +_loop0_155_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -30343,30 +33632,31 @@ _loop0_150_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // (star_targets '=') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_199_var; + D(fprintf(stderr, "%*c> _loop0_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_238_var; while ( - (_tmp_199_var = _tmp_199_rule(p)) // star_targets '=' + (_tmp_238_var = _tmp_238_rule(p)) // star_targets '=' ) { - _res = _tmp_199_var; + _res = _tmp_238_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -30375,7 +33665,7 @@ _loop0_150_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_150[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_155[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30383,328 +33673,26 @@ _loop0_150_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_150_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_155_type, _seq); + p->level--; return _seq; } -// _loop0_151: (star_targets '=') -static asdl_seq * -_loop0_151_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // (star_targets '=') - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _loop0_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_200_var; - while ( - (_tmp_200_var = _tmp_200_rule(p)) // star_targets '=' - ) - { - _res = _tmp_200_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_151[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - D(p->level--); - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_151_type, _seq); - D(p->level--); - return _seq; -} - -// _tmp_152: yield_expr | star_expressions -static void * -_tmp_152_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // yield_expr - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); - expr_ty yield_expr_var; - if ( - (yield_expr_var = yield_expr_rule(p)) // yield_expr - ) - { - D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); - _res = yield_expr_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); - } - { // star_expressions - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); - expr_ty star_expressions_var; - if ( - (star_expressions_var = star_expressions_rule(p)) // star_expressions - ) - { - D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); - _res = star_expressions_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _tmp_153: '[' | '(' | '{' -static void * -_tmp_153_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // '[' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 9)) // token='[' - ) - { - D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); - } - { // '(' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - ) - { - D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); - } - { // '{' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 25)) // token='{' - ) - { - D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _tmp_154: '[' | '{' -static void * -_tmp_154_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // '[' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 9)) // token='[' - ) - { - D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); - } - { // '{' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 25)) // token='{' - ) - { - D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _tmp_155: '[' | '{' -static void * -_tmp_155_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // '[' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 9)) // token='[' - ) - { - D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); - } - { // '{' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 25)) // token='{' - ) - { - D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _loop0_156: param_no_default +// _loop0_156: (star_targets '=') static asdl_seq * _loop0_156_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -30714,30 +33702,31 @@ _loop0_156_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // param_no_default + { // (star_targets '=') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); - arg_ty param_no_default_var; + D(fprintf(stderr, "%*c> _loop0_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_239_var; while ( - (param_no_default_var = param_no_default_rule(p)) // param_no_default + (_tmp_239_var = _tmp_239_rule(p)) // star_targets '=' ) { - _res = param_no_default_var; + _res = _tmp_239_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -30747,30 +33736,342 @@ _loop0_156_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s _loop0_156[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); _PyPegen_insert_memo(p, _start_mark, _loop0_156_type, _seq); - D(p->level--); + p->level--; return _seq; } -// _loop0_157: param_no_default -static asdl_seq * -_loop0_157_rule(Parser *p) +// _tmp_157: yield_expr | star_expressions +static void * +_tmp_157_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // yield_expr + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + expr_ty yield_expr_var; + if ( + (yield_expr_var = yield_expr_rule(p)) // yield_expr + ) + { + D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + _res = yield_expr_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); + } + { // star_expressions + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + expr_ty star_expressions_var; + if ( + (star_expressions_var = star_expressions_rule(p)) // star_expressions + ) + { + D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + _res = star_expressions_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_158: '[' | '(' | '{' +static void * +_tmp_158_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '[' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + ) + { + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); + } + { // '(' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + ) + { + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); + } + { // '{' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + ) + { + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_159: '[' | '{' +static void * +_tmp_159_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '[' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + ) + { + D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); + } + { // '{' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + ) + { + D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_160: '[' | '{' +static void * +_tmp_160_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '[' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + ) + { + D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); + } + { // '{' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + ) + { + D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_161: slash_no_default | slash_with_default +static void * +_tmp_161_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // slash_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + asdl_arg_seq* slash_no_default_var; + if ( + (slash_no_default_var = slash_no_default_rule(p)) // slash_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_161[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + _res = slash_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_161[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default")); + } + { // slash_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + SlashWithDefault* slash_with_default_var; + if ( + (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_161[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + _res = slash_with_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_161[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_162: param_maybe_default +static asdl_seq * +_loop0_162_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void *_res = NULL; @@ -30780,17 +34081,87 @@ _loop0_157_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + ) + { + _res = param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_162[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_162_type, _seq); + p->level--; + return _seq; +} + +// _loop0_163: param_no_default +static asdl_seq * +_loop0_163_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_no_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -30801,9 +34172,10 @@ _loop0_157_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -30812,7 +34184,7 @@ _loop0_157_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_157[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_163[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30820,23 +34192,26 @@ _loop0_157_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_157_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_163_type, _seq); + p->level--; return _seq; } -// _loop1_158: param_no_default +// _loop0_164: param_no_default static asdl_seq * -_loop1_158_rule(Parser *p) +_loop0_164_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -30846,17 +34221,17 @@ _loop1_158_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_no_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -30867,9 +34242,10 @@ _loop1_158_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -30878,12 +34254,82 @@ _loop1_158_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_158[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_164[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_164_type, _seq); + p->level--; + return _seq; +} + +// _loop1_165: param_no_default +static asdl_seq * +_loop1_165_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + while ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default + ) + { + _res = param_no_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_165[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30891,23 +34337,84 @@ _loop1_158_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_158_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop1_165_type, _seq); + p->level--; return _seq; } -// _loop1_159: param_with_default -static asdl_seq * -_loop1_159_rule(Parser *p) +// _tmp_166: slash_no_default | slash_with_default +static void * +_tmp_166_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // slash_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + asdl_arg_seq* slash_no_default_var; + if ( + (slash_no_default_var = slash_no_default_rule(p)) // slash_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + _res = slash_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default")); + } + { // slash_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + SlashWithDefault* slash_with_default_var; + if ( + (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + _res = slash_with_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_167: param_maybe_default +static asdl_seq * +_loop0_167_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void *_res = NULL; @@ -30917,17 +34424,672 @@ _loop1_159_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + ) + { + _res = param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_167[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_167_type, _seq); + p->level--; + return _seq; +} + +// _tmp_168: ',' | param_no_default +static void * +_tmp_168_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + { // param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + if ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + _res = param_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_169: param_maybe_default +static asdl_seq * +_loop0_169_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + ) + { + _res = param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_169[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_169_type, _seq); + p->level--; + return _seq; +} + +// _loop1_170: param_maybe_default +static asdl_seq * +_loop1_170_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + ) + { + _res = param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_170[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop1_170_type, _seq); + p->level--; + return _seq; +} + +// _tmp_171: ')' | ',' +static void * +_tmp_171_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ _tmp_171[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_171[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); + } + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_171[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_171[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_172: ')' | ',' (')' | '**') +static void * +_tmp_172_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ _tmp_172[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_172[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); + } + { // ',' (')' | '**') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + Token * _literal; + void *_tmp_240_var; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (_tmp_240_var = _tmp_240_rule(p)) // ')' | '**' + ) + { + D(fprintf(stderr, "%*c+ _tmp_172[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_240_var); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_172[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_173: param_no_default | ',' +static void * +_tmp_173_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + if ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + _res = param_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + } + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_174: param_maybe_default +static asdl_seq * +_loop0_174_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + ) + { + _res = param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_174[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_174_type, _seq); + p->level--; + return _seq; +} + +// _tmp_175: param_no_default | ',' +static void * +_tmp_175_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + if ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_175[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + _res = param_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_175[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + } + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_175[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_175[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_176: '*' | '**' | '/' +static void * +_tmp_176_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '*' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + ) + { + D(fprintf(stderr, "%*c+ _tmp_176[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_176[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); + } + { // '**' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + ) + { + D(fprintf(stderr, "%*c+ _tmp_176[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_176[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); + } + { // '/' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + ) + { + D(fprintf(stderr, "%*c+ _tmp_176[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_176[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop1_177: param_with_default +static asdl_seq * +_loop1_177_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // param_with_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop1_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -30938,9 +35100,10 @@ _loop1_159_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -30949,12 +35112,12 @@ _loop1_159_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_159[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_177[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30962,23 +35125,84 @@ _loop1_159_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_159_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop1_177_type, _seq); + p->level--; return _seq; } -// _loop0_160: lambda_param_no_default -static asdl_seq * -_loop0_160_rule(Parser *p) +// _tmp_178: lambda_slash_no_default | lambda_slash_with_default +static void * +_tmp_178_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // lambda_slash_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + asdl_arg_seq* lambda_slash_no_default_var; + if ( + (lambda_slash_no_default_var = lambda_slash_no_default_rule(p)) // lambda_slash_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + _res = lambda_slash_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); + } + { // lambda_slash_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + SlashWithDefault* lambda_slash_with_default_var; + if ( + (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + _res = lambda_slash_with_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_179: lambda_param_maybe_default +static asdl_seq * +_loop0_179_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void *_res = NULL; @@ -30988,17 +35212,87 @@ _loop0_160_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; + while ( + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default + ) + { + _res = lambda_param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_179[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_179_type, _seq); + p->level--; + return _seq; +} + +// _loop0_180: lambda_param_no_default +static asdl_seq * +_loop0_180_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // lambda_param_no_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -31009,9 +35303,10 @@ _loop0_160_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -31020,7 +35315,7 @@ _loop0_160_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_160[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_180[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31028,23 +35323,26 @@ _loop0_160_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_160_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_180_type, _seq); + p->level--; return _seq; } -// _loop0_161: lambda_param_no_default +// _loop0_181: lambda_param_no_default static asdl_seq * -_loop0_161_rule(Parser *p) +_loop0_181_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -31054,17 +35352,17 @@ _loop0_161_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // lambda_param_no_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -31075,9 +35373,10 @@ _loop0_161_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -31086,7 +35385,7 @@ _loop0_161_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_161[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_181[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31094,23 +35393,26 @@ _loop0_161_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_161_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_181_type, _seq); + p->level--; return _seq; } -// _loop0_163: ',' lambda_param +// _loop0_183: ',' lambda_param static asdl_seq * -_loop0_163_rule(Parser *p) +_loop0_183_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -31120,17 +35422,17 @@ _loop0_163_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' lambda_param if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param")); + D(fprintf(stderr, "%*c> _loop0_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param")); Token * _literal; arg_ty elem; while ( @@ -31143,16 +35445,17 @@ _loop0_163_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -31161,7 +35464,7 @@ _loop0_163_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_163[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_183[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' lambda_param")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31169,62 +35472,126 @@ _loop0_163_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_163_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_183_type, _seq); + p->level--; return _seq; } -// _gather_162: lambda_param _loop0_163 +// _gather_182: lambda_param _loop0_183 static asdl_seq * -_gather_162_rule(Parser *p) +_gather_182_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // lambda_param _loop0_163 + { // lambda_param _loop0_183 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_163")); + D(fprintf(stderr, "%*c> _gather_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_183")); arg_ty elem; asdl_seq * seq; if ( (elem = lambda_param_rule(p)) // lambda_param && - (seq = _loop0_163_rule(p)) // _loop0_163 + (seq = _loop0_183_rule(p)) // _loop0_183 ) { - D(fprintf(stderr, "%*c+ _gather_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_163")); + D(fprintf(stderr, "%*c+ _gather_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_183")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_162[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_163")); + D(fprintf(stderr, "%*c%s _gather_182[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_183")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop1_164: lambda_param_with_default -static asdl_seq * -_loop1_164_rule(Parser *p) +// _tmp_184: lambda_slash_no_default | lambda_slash_with_default +static void * +_tmp_184_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // lambda_slash_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + asdl_arg_seq* lambda_slash_no_default_var; + if ( + (lambda_slash_no_default_var = lambda_slash_no_default_rule(p)) // lambda_slash_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_184[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + _res = lambda_slash_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); + } + { // lambda_slash_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + SlashWithDefault* lambda_slash_with_default_var; + if ( + (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_184[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + _res = lambda_slash_with_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_185: lambda_param_maybe_default +static asdl_seq * +_loop0_185_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void *_res = NULL; @@ -31234,17 +35601,290 @@ _loop1_164_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; + while ( + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default + ) + { + _res = lambda_param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_185[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_185_type, _seq); + p->level--; + return _seq; +} + +// _tmp_186: ',' | lambda_param_no_default +static void * +_tmp_186_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_186[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_186[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + { // lambda_param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + if ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_186[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + _res = lambda_param_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_186[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_187: lambda_param_maybe_default +static asdl_seq * +_loop0_187_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; + while ( + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default + ) + { + _res = lambda_param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_187[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_187_type, _seq); + p->level--; + return _seq; +} + +// _loop1_188: lambda_param_maybe_default +static asdl_seq * +_loop1_188_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; + while ( + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default + ) + { + _res = lambda_param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_188[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop1_188_type, _seq); + p->level--; + return _seq; +} + +// _loop1_189: lambda_param_with_default +static asdl_seq * +_loop1_189_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // lambda_param_with_default if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop1_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -31255,9 +35895,10 @@ _loop1_164_rule(Parser *p) _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -31266,12 +35907,12 @@ _loop1_164_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_164[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_189[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31279,213 +35920,427 @@ _loop1_164_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_164_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop1_189_type, _seq); + p->level--; return _seq; } -// _tmp_165: ')' | ',' (')' | '**') +// _tmp_190: ':' | ',' (':' | '**') static void * -_tmp_165_rule(Parser *p) +_tmp_190_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // ')' - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); - } - { // ',' (')' | '**') - if (p->error_indicator) { - D(p->level--); - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); - Token * _literal; - void *_tmp_201_var; - if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (_tmp_201_var = _tmp_201_rule(p)) // ')' | '**' - ) - { - D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_201_var); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')")); - } - _res = NULL; - done: - D(p->level--); - return _res; -} - -// _tmp_166: ':' | ',' (':' | '**') -static void * -_tmp_166_rule(Parser *p) -{ - D(p->level++); - if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ':' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_190[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_190[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // ',' (':' | '**') if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + D(fprintf(stderr, "%*c> _tmp_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); Token * _literal; - void *_tmp_202_var; + void *_tmp_241_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_202_var = _tmp_202_rule(p)) // ':' | '**' + (_tmp_241_var = _tmp_241_rule(p)) // ':' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_202_var); + D(fprintf(stderr, "%*c+ _tmp_190[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_241_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_190[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (':' | '**')")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_167: ',' | ')' | ':' +// _tmp_191: lambda_param_no_default | ',' static void * -_tmp_167_rule(Parser *p) +_tmp_191_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // lambda_param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + if ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + _res = lambda_param_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + } + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_192: lambda_param_maybe_default +static asdl_seq * +_loop0_192_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; + while ( + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default + ) + { + _res = lambda_param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_192[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_192_type, _seq); + p->level--; + return _seq; +} + +// _tmp_193: lambda_param_no_default | ',' +static void * +_tmp_193_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // lambda_param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + if ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + _res = lambda_param_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + } + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_194: '*' | '**' | '/' +static void * +_tmp_194_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '*' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + ) + { + D(fprintf(stderr, "%*c+ _tmp_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_194[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); + } + { // '**' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + ) + { + D(fprintf(stderr, "%*c+ _tmp_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_194[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); + } + { // '/' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + ) + { + D(fprintf(stderr, "%*c+ _tmp_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_194[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_195: ',' | ')' | ':' +static void * +_tmp_195_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_195[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_195[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_195[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_195[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ':' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_195[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_195[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_169: ',' (expression ['as' star_target]) +// _loop0_197: ',' (expression ['as' star_target]) static asdl_seq * -_loop0_169_rule(Parser *p) +_loop0_197_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -31495,39 +36350,40 @@ _loop0_169_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' (expression ['as' star_target]) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_203_rule(p)) // expression ['as' star_target] + (elem = _tmp_242_rule(p)) // expression ['as' star_target] ) { _res = elem; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -31536,7 +36392,7 @@ _loop0_169_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_169[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_197[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31544,62 +36400,68 @@ _loop0_169_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_169_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_197_type, _seq); + p->level--; return _seq; } -// _gather_168: (expression ['as' star_target]) _loop0_169 +// _gather_196: (expression ['as' star_target]) _loop0_197 static asdl_seq * -_gather_168_rule(Parser *p) +_gather_196_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expression ['as' star_target]) _loop0_169 + { // (expression ['as' star_target]) _loop0_197 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_169")); + D(fprintf(stderr, "%*c> _gather_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_197")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_203_rule(p)) // expression ['as' star_target] + (elem = _tmp_242_rule(p)) // expression ['as' star_target] && - (seq = _loop0_169_rule(p)) // _loop0_169 + (seq = _loop0_197_rule(p)) // _loop0_197 ) { - D(fprintf(stderr, "%*c+ _gather_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_169")); + D(fprintf(stderr, "%*c+ _gather_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_197")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_168[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_169")); + D(fprintf(stderr, "%*c%s _gather_196[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_197")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_171: ',' (expressions ['as' star_target]) +// _loop0_199: ',' (expressions ['as' star_target]) static asdl_seq * -_loop0_171_rule(Parser *p) +_loop0_199_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -31609,39 +36471,40 @@ _loop0_171_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' (expressions ['as' star_target]) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_204_rule(p)) // expressions ['as' star_target] + (elem = _tmp_243_rule(p)) // expressions ['as' star_target] ) { _res = elem; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -31650,7 +36513,7 @@ _loop0_171_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_171[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_199[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31658,62 +36521,68 @@ _loop0_171_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_171_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_199_type, _seq); + p->level--; return _seq; } -// _gather_170: (expressions ['as' star_target]) _loop0_171 +// _gather_198: (expressions ['as' star_target]) _loop0_199 static asdl_seq * -_gather_170_rule(Parser *p) +_gather_198_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expressions ['as' star_target]) _loop0_171 + { // (expressions ['as' star_target]) _loop0_199 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_171")); + D(fprintf(stderr, "%*c> _gather_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_199")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_204_rule(p)) // expressions ['as' star_target] + (elem = _tmp_243_rule(p)) // expressions ['as' star_target] && - (seq = _loop0_171_rule(p)) // _loop0_171 + (seq = _loop0_199_rule(p)) // _loop0_199 ) { - D(fprintf(stderr, "%*c+ _gather_170[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_171")); + D(fprintf(stderr, "%*c+ _gather_198[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_199")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_170[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_171")); + D(fprintf(stderr, "%*c%s _gather_198[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_199")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_173: ',' (expression ['as' star_target]) +// _loop0_201: ',' (expression ['as' star_target]) static asdl_seq * -_loop0_173_rule(Parser *p) +_loop0_201_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -31723,39 +36592,40 @@ _loop0_173_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' (expression ['as' star_target]) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_205_rule(p)) // expression ['as' star_target] + (elem = _tmp_244_rule(p)) // expression ['as' star_target] ) { _res = elem; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -31764,7 +36634,7 @@ _loop0_173_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_173[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_201[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31772,62 +36642,68 @@ _loop0_173_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_173_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_201_type, _seq); + p->level--; return _seq; } -// _gather_172: (expression ['as' star_target]) _loop0_173 +// _gather_200: (expression ['as' star_target]) _loop0_201 static asdl_seq * -_gather_172_rule(Parser *p) +_gather_200_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expression ['as' star_target]) _loop0_173 + { // (expression ['as' star_target]) _loop0_201 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_173")); + D(fprintf(stderr, "%*c> _gather_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_201")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_205_rule(p)) // expression ['as' star_target] + (elem = _tmp_244_rule(p)) // expression ['as' star_target] && - (seq = _loop0_173_rule(p)) // _loop0_173 + (seq = _loop0_201_rule(p)) // _loop0_201 ) { - D(fprintf(stderr, "%*c+ _gather_172[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_173")); + D(fprintf(stderr, "%*c+ _gather_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_201")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_172[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_173")); + D(fprintf(stderr, "%*c%s _gather_200[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_201")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_175: ',' (expressions ['as' star_target]) +// _loop0_203: ',' (expressions ['as' star_target]) static asdl_seq * -_loop0_175_rule(Parser *p) +_loop0_203_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void *_res = NULL; @@ -31837,39 +36713,40 @@ _loop0_175_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' (expressions ['as' star_target]) if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_206_rule(p)) // expressions ['as' star_target] + (elem = _tmp_245_rule(p)) // expressions ['as' star_target] ) { _res = elem; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -31878,7 +36755,7 @@ _loop0_175_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_175[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_203[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31886,244 +36763,737 @@ _loop0_175_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_175_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_203_type, _seq); + p->level--; return _seq; } -// _gather_174: (expressions ['as' star_target]) _loop0_175 +// _gather_202: (expressions ['as' star_target]) _loop0_203 static asdl_seq * -_gather_174_rule(Parser *p) +_gather_202_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expressions ['as' star_target]) _loop0_175 + { // (expressions ['as' star_target]) _loop0_203 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_175")); + D(fprintf(stderr, "%*c> _gather_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_203")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_206_rule(p)) // expressions ['as' star_target] + (elem = _tmp_245_rule(p)) // expressions ['as' star_target] && - (seq = _loop0_175_rule(p)) // _loop0_175 + (seq = _loop0_203_rule(p)) // _loop0_203 ) { - D(fprintf(stderr, "%*c+ _gather_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_175")); + D(fprintf(stderr, "%*c+ _gather_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_203")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_174[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_175")); + D(fprintf(stderr, "%*c%s _gather_202[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_203")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_176: 'except' | 'finally' +// _tmp_204: 'except' | 'finally' static void * -_tmp_176_rule(Parser *p) +_tmp_204_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'except' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); + D(fprintf(stderr, "%*c> _tmp_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 623)) // token='except' + (_keyword = _PyPegen_expect_token(p, 636)) // token='except' ) { - D(fprintf(stderr, "%*c+ _tmp_176[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); + D(fprintf(stderr, "%*c+ _tmp_204[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_176[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_204[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except'")); } { // 'finally' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); + D(fprintf(stderr, "%*c> _tmp_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 620)) // token='finally' + (_keyword = _PyPegen_expect_token(p, 632)) // token='finally' ) { - D(fprintf(stderr, "%*c+ _tmp_176[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); + D(fprintf(stderr, "%*c+ _tmp_204[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_176[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_204[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'finally'")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_177: 'as' NAME -static void * -_tmp_177_rule(Parser *p) +// _loop0_205: block +static asdl_seq * +_loop0_205_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); + asdl_stmt_seq* block_var; + while ( + (block_var = block_rule(p)) // block + ) + { + _res = block_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_205[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_205_type, _seq); + p->level--; + return _seq; +} + +// _loop1_206: except_block +static asdl_seq * +_loop1_206_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // except_block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); + excepthandler_ty except_block_var; + while ( + (except_block_var = except_block_rule(p)) // except_block + ) + { + _res = except_block_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_206[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_block")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop1_206_type, _seq); + p->level--; + return _seq; +} + +// _tmp_207: 'as' NAME +static void * +_tmp_207_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'as' NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 625)) // token='as' + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_177[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_207[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_177[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_207[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_178: 'as' NAME -static void * -_tmp_178_rule(Parser *p) +// _loop0_208: block +static asdl_seq * +_loop0_208_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); + asdl_stmt_seq* block_var; + while ( + (block_var = block_rule(p)) // block + ) + { + _res = block_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_208[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_208_type, _seq); + p->level--; + return _seq; +} + +// _loop1_209: except_star_block +static asdl_seq * +_loop1_209_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // except_star_block + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); + excepthandler_ty except_star_block_var; + while ( + (except_star_block_var = except_star_block_rule(p)) // except_star_block + ) + { + _res = except_star_block_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_209[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_star_block")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop1_209_type, _seq); + p->level--; + return _seq; +} + +// _tmp_210: expression ['as' NAME] +static void * +_tmp_210_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // expression ['as' NAME] + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty expression_var; + if ( + (expression_var = expression_rule(p)) // expression + && + (_opt_var = _tmp_246_rule(p), !p->error_indicator) // ['as' NAME] + ) + { + D(fprintf(stderr, "%*c+ _tmp_210[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); + _res = _PyPegen_dummy_name(p, expression_var, _opt_var); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_210[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' NAME]")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_211: 'as' NAME +static void * +_tmp_211_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'as' NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 625)) // token='as' + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_211[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_211[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_179: 'as' NAME +// _tmp_212: 'as' NAME static void * -_tmp_179_rule(Parser *p) +_tmp_212_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'as' NAME if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 625)) // token='as' + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_212[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_180: positional_patterns ',' +// _tmp_213: NEWLINE | ':' static void * -_tmp_180_rule(Parser *p) +_tmp_213_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // NEWLINE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + Token * newline_var; + if ( + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { + D(fprintf(stderr, "%*c+ _tmp_213[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + _res = newline_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_213[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); + } + { // ':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + D(fprintf(stderr, "%*c+ _tmp_213[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_213[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_214: 'as' NAME +static void * +_tmp_214_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // 'as' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; + if ( + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' + && + (name_var = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ _tmp_214[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _res = _PyPegen_dummy_name(p, _keyword, name_var); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_214[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_215: 'as' NAME +static void * +_tmp_215_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // 'as' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; + if ( + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' + && + (name_var = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ _tmp_215[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _res = _PyPegen_dummy_name(p, _keyword, name_var); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_215[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_216: positional_patterns ',' +static void * +_tmp_216_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // positional_patterns ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + D(fprintf(stderr, "%*c> _tmp_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); Token * _literal; asdl_pattern_seq* positional_patterns_var; if ( @@ -32132,37 +37502,40 @@ _tmp_180_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + D(fprintf(stderr, "%*c+ _tmp_216[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); _res = _PyPegen_dummy_name(p, positional_patterns_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_180[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_216[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "positional_patterns ','")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_181: '->' expression +// _tmp_217: '->' expression static void * -_tmp_181_rule(Parser *p) +_tmp_217_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '->' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c> _tmp_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); Token * _literal; expr_ty expression_var; if ( @@ -32171,37 +37544,40 @@ _tmp_181_rule(Parser *p) (expression_var = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c+ _tmp_217[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); _res = _PyPegen_dummy_name(p, _literal, expression_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_217[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_182: '(' arguments? ')' +// _tmp_218: '(' arguments? ')' static void * -_tmp_182_rule(Parser *p) +_tmp_218_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '(' arguments? ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c> _tmp_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); Token * _literal; Token * _literal_1; void *_opt_var; @@ -32214,27 +37590,76 @@ _tmp_182_rule(Parser *p) (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c+ _tmp_218[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_218[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _loop0_184: ',' double_starred_kvpair -static asdl_seq * -_loop0_184_rule(Parser *p) +// _tmp_219: '(' arguments? ')' +static void * +_tmp_219_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '(' arguments? ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + Token * _literal; + Token * _literal_1; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (_opt_var = arguments_rule(p), !p->error_indicator) // arguments? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ _tmp_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_219[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_221: ',' double_starred_kvpair +static asdl_seq * +_loop0_221_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void *_res = NULL; @@ -32244,17 +37669,17 @@ _loop0_184_rule(Parser *p) if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; { // ',' double_starred_kvpair if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); + D(fprintf(stderr, "%*c> _loop0_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); Token * _literal; KeyValuePair* elem; while ( @@ -32267,16 +37692,17 @@ _loop0_184_rule(Parser *p) if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; PyMem_Free(_children); - D(p->level--); + p->level--; return NULL; } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); if (!_new_children) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } _children = _new_children; @@ -32285,7 +37711,7 @@ _loop0_184_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_184[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_221[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' double_starred_kvpair")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -32293,127 +37719,194 @@ _loop0_184_rule(Parser *p) PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); - D(p->level--); + p->level--; return NULL; } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_184_type, _seq); - D(p->level--); + _PyPegen_insert_memo(p, _start_mark, _loop0_221_type, _seq); + p->level--; return _seq; } -// _gather_183: double_starred_kvpair _loop0_184 +// _gather_220: double_starred_kvpair _loop0_221 static asdl_seq * -_gather_183_rule(Parser *p) +_gather_220_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } asdl_seq * _res = NULL; int _mark = p->mark; - { // double_starred_kvpair _loop0_184 + { // double_starred_kvpair _loop0_221 if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_184")); + D(fprintf(stderr, "%*c> _gather_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_221")); KeyValuePair* elem; asdl_seq * seq; if ( (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair && - (seq = _loop0_184_rule(p)) // _loop0_184 + (seq = _loop0_221_rule(p)) // _loop0_221 ) { - D(fprintf(stderr, "%*c+ _gather_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_184")); + D(fprintf(stderr, "%*c+ _gather_220[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_221")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_183[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_184")); + D(fprintf(stderr, "%*c%s _gather_220[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_221")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_185: '}' | ',' +// _tmp_222: '}' | ',' static void * -_tmp_185_rule(Parser *p) +_tmp_222_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '}' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_185[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_185[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_222[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } { // ',' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_185[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_185[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_222[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_186: star_targets '=' +// _tmp_223: '}' | ',' static void * -_tmp_186_rule(Parser *p) +_tmp_223_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '}' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 26)) // token='}' + ) + { + D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); + } + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_224: star_targets '=' +static void * +_tmp_224_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // star_targets '=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty z; if ( @@ -32422,152 +37915,161 @@ _tmp_186_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_186[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_186[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_187: '.' | '...' +// _tmp_225: '.' | '...' static void * -_tmp_187_rule(Parser *p) +_tmp_225_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '.' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_187[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_187[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_187[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_187[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_188: '.' | '...' +// _tmp_226: '.' | '...' static void * -_tmp_188_rule(Parser *p) +_tmp_226_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '.' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_188[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_188[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_189: '@' named_expression NEWLINE +// _tmp_227: '@' named_expression NEWLINE static void * -_tmp_189_rule(Parser *p) +_tmp_227_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // '@' named_expression NEWLINE if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); Token * _literal; expr_ty f; Token * newline_var; @@ -32579,42 +38081,45 @@ _tmp_189_rule(Parser *p) (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_189[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); _res = f; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_189[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_227[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@' named_expression NEWLINE")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_190: ',' expression +// _tmp_228: ',' expression static void * -_tmp_190_rule(Parser *p) +_tmp_228_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ',' expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _tmp_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty c; if ( @@ -32623,42 +38128,45 @@ _tmp_190_rule(Parser *p) (c = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_190[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c+ _tmp_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_190[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_228[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_191: ',' star_expression +// _tmp_229: ',' star_expression static void * -_tmp_191_rule(Parser *p) +_tmp_229_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ',' star_expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c> _tmp_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); Token * _literal; expr_ty c; if ( @@ -32667,275 +38175,351 @@ _tmp_191_rule(Parser *p) (c = star_expression_rule(p)) // star_expression ) { - D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c+ _tmp_229[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_229[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_expression")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_192: 'or' conjunction +// _tmp_230: 'or' conjunction static void * -_tmp_192_rule(Parser *p) +_tmp_230_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'or' conjunction if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); Token * _keyword; expr_ty c; if ( - (_keyword = _PyPegen_expect_token(p, 571)) // token='or' + (_keyword = _PyPegen_expect_token(p, 574)) // token='or' && (c = conjunction_rule(p)) // conjunction ) { - D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'or' conjunction")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_193: 'and' inversion +// _tmp_231: 'and' inversion static void * -_tmp_193_rule(Parser *p) +_tmp_231_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'and' inversion if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); Token * _keyword; expr_ty c; if ( - (_keyword = _PyPegen_expect_token(p, 572)) // token='and' + (_keyword = _PyPegen_expect_token(p, 575)) // token='and' && (c = inversion_rule(p)) // inversion ) { - D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'and' inversion")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_194: 'if' disjunction +// _tmp_232: slice | starred_expression static void * -_tmp_194_rule(Parser *p) +_tmp_232_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // slice + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice")); + expr_ty slice_var; + if ( + (slice_var = slice_rule(p)) // slice + ) + { + D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice")); + _res = slice_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slice")); + } + { // starred_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + expr_ty starred_expression_var; + if ( + (starred_expression_var = starred_expression_rule(p)) // starred_expression + ) + { + D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + _res = starred_expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_233: 'if' disjunction +static void * +_tmp_233_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'if' disjunction if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 627)) // token='if' + (_keyword = _PyPegen_expect_token(p, 641)) // token='if' && (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_194[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_195: 'if' disjunction +// _tmp_234: 'if' disjunction static void * -_tmp_195_rule(Parser *p) +_tmp_234_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'if' disjunction if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 627)) // token='if' + (_keyword = _PyPegen_expect_token(p, 641)) // token='if' && (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_195[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_195[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_196: starred_expression | (assignment_expression | expression !':=') !'=' +// _tmp_235: starred_expression | (assignment_expression | expression !':=') !'=' static void * -_tmp_196_rule(Parser *p) +_tmp_235_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // starred_expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); expr_ty starred_expression_var; if ( (starred_expression_var = starred_expression_rule(p)) // starred_expression ) { - D(fprintf(stderr, "%*c+ _tmp_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); _res = starred_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_196[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); } { // (assignment_expression | expression !':=') !'=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - void *_tmp_207_var; + D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + void *_tmp_247_var; if ( - (_tmp_207_var = _tmp_207_rule(p)) // assignment_expression | expression !':=' + (_tmp_247_var = _tmp_247_rule(p)) // assignment_expression | expression !':=' && _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - _res = _tmp_207_var; + D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + _res = _tmp_247_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_196[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(assignment_expression | expression !':=') !'='")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_197: ',' star_target +// _tmp_236: ',' star_target static void * -_tmp_197_rule(Parser *p) +_tmp_236_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ',' star_target if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -32944,42 +38528,45 @@ _tmp_197_rule(Parser *p) (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_197[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_198: ',' star_target +// _tmp_237: ',' star_target static void * -_tmp_198_rule(Parser *p) +_tmp_237_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ',' star_target if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -32988,42 +38575,45 @@ _tmp_198_rule(Parser *p) (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_198[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - D(p->level--); + p->level--; return NULL; } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_198[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_199: star_targets '=' +// _tmp_238: star_targets '=' static void * -_tmp_199_rule(Parser *p) +_tmp_238_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // star_targets '=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -33032,37 +38622,40 @@ _tmp_199_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_199[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = _PyPegen_dummy_name(p, star_targets_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_199[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_200: star_targets '=' +// _tmp_239: star_targets '=' static void * -_tmp_200_rule(Parser *p) +_tmp_239_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // star_targets '=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -33071,326 +38664,389 @@ _tmp_200_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = _PyPegen_dummy_name(p, star_targets_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_201: ')' | '**' +// _tmp_240: ')' | '**' static void * -_tmp_201_rule(Parser *p) +_tmp_240_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ')' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // '**' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_202: ':' | '**' +// _tmp_241: ':' | '**' static void * -_tmp_202_rule(Parser *p) +_tmp_241_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // ':' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '**' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_203: expression ['as' star_target] +// _tmp_242: expression ['as' star_target] static void * -_tmp_203_rule(Parser *p) +_tmp_242_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // expression ['as' star_target] if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_208_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_248_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); _res = _PyPegen_dummy_name(p, expression_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_203[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_204: expressions ['as' star_target] +// _tmp_243: expressions ['as' star_target] static void * -_tmp_204_rule(Parser *p) +_tmp_243_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // expressions ['as' star_target] if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expressions_var; if ( (expressions_var = expressions_rule(p)) // expressions && - (_opt_var = _tmp_209_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_249_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_204[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); _res = _PyPegen_dummy_name(p, expressions_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_204[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_243[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_205: expression ['as' star_target] +// _tmp_244: expression ['as' star_target] static void * -_tmp_205_rule(Parser *p) +_tmp_244_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // expression ['as' star_target] if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_210_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_250_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_205[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_244[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); _res = _PyPegen_dummy_name(p, expression_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_205[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_244[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_206: expressions ['as' star_target] +// _tmp_245: expressions ['as' star_target] static void * -_tmp_206_rule(Parser *p) +_tmp_245_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // expressions ['as' star_target] if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expressions_var; if ( (expressions_var = expressions_rule(p)) // expressions && - (_opt_var = _tmp_211_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_251_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_206[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); _res = _PyPegen_dummy_name(p, expressions_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_206[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_245[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_207: assignment_expression | expression !':=' +// _tmp_246: 'as' NAME static void * -_tmp_207_rule(Parser *p) +_tmp_246_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // 'as' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; + if ( + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' + && + (name_var = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _res = _PyPegen_dummy_name(p, _keyword, name_var); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_246[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_247: assignment_expression | expression !':=' +static void * +_tmp_247_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // assignment_expression if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); expr_ty assignment_expression_var; if ( (assignment_expression_var = assignment_expression_rule(p)) // assignment_expression ) { - D(fprintf(stderr, "%*c+ _tmp_207[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); _res = assignment_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_207[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_247[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); } { // expression !':=' if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression @@ -33398,173 +39054,185 @@ _tmp_207_rule(Parser *p) _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_207[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); _res = expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_207[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_247[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_208: 'as' star_target +// _tmp_248: 'as' star_target static void * -_tmp_208_rule(Parser *p) +_tmp_248_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'as' star_target if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( - (_keyword = _PyPegen_expect_token(p, 625)) // token='as' + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' && (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_208[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_208[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_209: 'as' star_target +// _tmp_249: 'as' star_target static void * -_tmp_209_rule(Parser *p) +_tmp_249_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'as' star_target if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( - (_keyword = _PyPegen_expect_token(p, 625)) // token='as' + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' && (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_209[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_209[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_210: 'as' star_target +// _tmp_250: 'as' star_target static void * -_tmp_210_rule(Parser *p) +_tmp_250_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'as' star_target if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( - (_keyword = _PyPegen_expect_token(p, 625)) // token='as' + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' && (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_210[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_210[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } -// _tmp_211: 'as' star_target +// _tmp_251: 'as' star_target static void * -_tmp_211_rule(Parser *p) +_tmp_251_rule(Parser *p) { - D(p->level++); + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } void * _res = NULL; int _mark = p->mark; { // 'as' star_target if (p->error_indicator) { - D(p->level--); + p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( - (_keyword = _PyPegen_expect_token(p, 625)) // token='as' + (_keyword = _PyPegen_expect_token(p, 639)) // token='as' && (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_211[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_211[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_251[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; done: - D(p->level--); + p->level--; return _res; } diff --git a/Parser/pegen.c b/Parser/pegen.c index 4f51c63c443..d84e06861ed 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -1,5 +1,6 @@ #include #include "pycore_ast.h" // _PyAST_Validate(), +#include "pycore_pystate.h" // _PyThreadState_GET() #include #include "tokenizer.h" @@ -37,17 +38,6 @@ _PyPegen_byte_offset_to_character_offset(PyObject *line, Py_ssize_t col_offset) return size; } -#if 0 -static const char * -token_name(int type) -{ - if (0 <= type && type <= N_TOKENS) { - return _PyParser_TokenNames[type]; - } - return ""; -} -#endif - // Here, mark is the start of the node, while p->mark is the end. // If node==NULL, they should be the same. int @@ -88,13 +78,7 @@ init_normalization(Parser *p) if (p->normalize) { return 1; } - PyObject *m = PyImport_ImportModuleNoBlock("unicodedata"); - if (!m) - { - return 0; - } - p->normalize = PyObject_GetAttrString(m, "normalize"); - Py_DECREF(m); + p->normalize = _PyImport_GetModuleAttrString("unicodedata", "normalize"); if (!p->normalize) { return 0; @@ -139,16 +123,18 @@ growable_comment_array_deallocate(growable_comment_array *arr) { } static int -_get_keyword_or_name_type(Parser *p, const char *name, int name_len) +_get_keyword_or_name_type(Parser *p, struct token *new_token) { + int name_len = new_token->end_col_offset - new_token->col_offset; assert(name_len > 0); + if (name_len >= p->n_keyword_lists || p->keywords[name_len] == NULL || p->keywords[name_len]->type == -1) { return NAME; } for (KeywordToken *k = p->keywords[name_len]; k != NULL && k->type != -1; k++) { - if (strncmp(k->str, name, name_len) == 0) { + if (strncmp(k->str, new_token->start, name_len) == 0) { return k->type; } } @@ -156,31 +142,26 @@ _get_keyword_or_name_type(Parser *p, const char *name, int name_len) } static int -initialize_token(Parser *p, Token *token, const char *start, const char *end, int token_type) { - assert(token != NULL); +initialize_token(Parser *p, Token *parser_token, struct token *new_token, int token_type) { + assert(parser_token != NULL); - token->type = (token_type == NAME) ? _get_keyword_or_name_type(p, start, (int)(end - start)) : token_type; - token->bytes = PyBytes_FromStringAndSize(start, end - start); - if (token->bytes == NULL) { + parser_token->type = (token_type == NAME) ? _get_keyword_or_name_type(p, new_token) : token_type; + parser_token->bytes = PyBytes_FromStringAndSize(new_token->start, new_token->end - new_token->start); + if (parser_token->bytes == NULL) { + return -1; + } + if (_PyArena_AddPyObject(p->arena, parser_token->bytes) < 0) { + Py_DECREF(parser_token->bytes); return -1; } - if (_PyArena_AddPyObject(p->arena, token->bytes) < 0) { - Py_DECREF(token->bytes); - return -1; - } - - const char *line_start = token_type == STRING ? p->tok->multi_line_start : p->tok->line_start; - int lineno = token_type == STRING ? p->tok->first_lineno : p->tok->lineno; - int end_lineno = p->tok->lineno; - - int col_offset = (start != NULL && start >= line_start) ? (int)(start - line_start) : -1; - int end_col_offset = (end != NULL && end >= p->tok->line_start) ? (int)(end - p->tok->line_start) : -1; - - token->lineno = p->starting_lineno + lineno; - token->col_offset = p->tok->lineno == 1 ? p->starting_col_offset + col_offset : col_offset; - token->end_lineno = p->starting_lineno + end_lineno; - token->end_col_offset = p->tok->lineno == 1 ? p->starting_col_offset + end_col_offset : end_col_offset; + parser_token->level = new_token->level; + parser_token->lineno = new_token->lineno; + parser_token->col_offset = p->tok->lineno == p->starting_lineno ? p->starting_col_offset + new_token->col_offset + : new_token->col_offset; + parser_token->end_lineno = new_token->end_lineno; + parser_token->end_col_offset = p->tok->lineno == p->starting_lineno ? p->starting_col_offset + new_token->end_col_offset + : new_token->end_col_offset; p->fill += 1; @@ -216,26 +197,25 @@ _resize_tokens_array(Parser *p) { int _PyPegen_fill_token(Parser *p) { - const char *start; - const char *end; - int type = _PyTokenizer_Get(p->tok, &start, &end); + struct token new_token; + int type = _PyTokenizer_Get(p->tok, &new_token); // Record and skip '# type: ignore' comments while (type == TYPE_IGNORE) { - Py_ssize_t len = end - start; + Py_ssize_t len = new_token.end_col_offset - new_token.col_offset; char *tag = PyMem_Malloc(len + 1); if (tag == NULL) { PyErr_NoMemory(); return -1; } - strncpy(tag, start, len); + strncpy(tag, new_token.start, len); tag[len] = '\0'; // Ownership of tag passes to the growable array if (!growable_comment_array_add(&p->type_ignore_comments, p->tok->lineno, tag)) { PyErr_NoMemory(); return -1; } - type = _PyTokenizer_Get(p->tok, &start, &end); + type = _PyTokenizer_Get(p->tok, &new_token); } // If we have reached the end and we are in single input mode we need to insert a newline and reset the parsing @@ -258,7 +238,7 @@ _PyPegen_fill_token(Parser *p) } Token *t = p->tokens[p->fill]; - return initialize_token(p, t, start, end, type); + return initialize_token(p, t, &new_token, type); } #if defined(Py_DEBUG) @@ -266,8 +246,8 @@ _PyPegen_fill_token(Parser *p) // The array counts the number of tokens skipped by memoization, // indexed by type. -#define NSTATISTICS 2000 -static long memo_statistics[NSTATISTICS]; +#define NSTATISTICS _PYPEGEN_NSTATISTICS +#define memo_statistics _PyRuntime.parser.memo_statistics void _PyPegen_clear_memo_statistics() @@ -660,6 +640,28 @@ _PyPegen_number_token(Parser *p) if (c == NULL) { p->error_indicator = 1; + PyThreadState *tstate = _PyThreadState_GET(); + // The only way a ValueError should happen in _this_ code is via + // PyLong_FromString hitting a length limit. + if (tstate->curexc_type == PyExc_ValueError && + tstate->curexc_value != NULL) { + PyObject *type, *value, *tb; + // This acts as PyErr_Clear() as we're replacing curexc. + PyErr_Fetch(&type, &value, &tb); + Py_XDECREF(tb); + Py_DECREF(type); + /* Intentionally omitting columns to avoid a wall of 1000s of '^'s + * on the error message. Nobody is going to overlook their huge + * numeric literal once given the line. */ + RAISE_ERROR_KNOWN_LOCATION( + p, PyExc_SyntaxError, + t->lineno, -1 /* col_offset */, + t->end_lineno, -1 /* end_col_offset */, + "%S - Consider hexadecimal for huge integer literals " + "to avoid decimal conversion limits.", + value); + Py_DECREF(value); + } return NULL; } @@ -673,31 +675,13 @@ _PyPegen_number_token(Parser *p) t->end_col_offset, p->arena); } -static int // bool -newline_in_string(Parser *p, const char *cur) -{ - for (const char *c = cur; c >= p->tok->buf; c--) { - if (*c == '\'' || *c == '"') { - return 1; - } - } - return 0; -} - /* Check that the source for a single input statement really is a single statement by looking at what is left in the buffer after parsing. Trailing whitespace and comments are OK. */ static int // bool bad_single_statement(Parser *p) { - const char *cur = strchr(p->tok->buf, '\n'); - - /* Newlines are allowed if preceded by a line continuation character - or if they appear inside a string. */ - if (!cur || (cur != p->tok->buf && *(cur - 1) == '\\') - || newline_in_string(p, cur)) { - return 0; - } + char *cur = p->tok->cur; char c = *cur; for (;;) { @@ -742,6 +726,9 @@ compute_parser_flags(PyCompilerFlags *flags) if ((flags->cf_flags & PyCF_ONLY_AST) && flags->cf_feature_version < 7) { parser_flags |= PyPARSE_ASYNC_HACKS; } + if (flags->cf_flags & PyCF_ALLOW_INCOMPLETE_INPUT) { + parser_flags |= PyPARSE_ALLOW_INCOMPLETE_INPUT; + } return parser_flags; } @@ -768,7 +755,7 @@ _PyPegen_Parser_New(struct tok_state *tok, int start_rule, int flags, return (Parser *) PyErr_NoMemory(); } p->tokens[0] = PyMem_Calloc(1, sizeof(Token)); - if (!p->tokens) { + if (!p->tokens[0]) { PyMem_Free(p->tokens); PyMem_Free(p); return (Parser *) PyErr_NoMemory(); @@ -798,7 +785,9 @@ _PyPegen_Parser_New(struct tok_state *tok, int start_rule, int flags, p->known_err_token = NULL; p->level = 0; p->call_invalid_rules = 0; - p->in_raw_rule = 0; +#ifdef Py_DEBUG + p->debug = _Py_GetConfig()->parser_debug; +#endif return p; } @@ -827,15 +816,26 @@ reset_parser_state_for_error_pass(Parser *p) p->tok->interactive_underflow = IUNDERFLOW_STOP; } +static inline int +_is_end_of_source(Parser *p) { + int err = p->tok->done; + return err == E_EOF || err == E_EOFS || err == E_EOLS; +} + void * _PyPegen_run_parser(Parser *p) { void *res = _PyPegen_parse(p); + assert(p->level == 0); if (res == NULL) { + if ((p->flags & PyPARSE_ALLOW_INCOMPLETE_INPUT) && _is_end_of_source(p)) { + PyErr_Clear(); + return RAISE_SYNTAX_ERROR("incomplete input"); + } if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_SyntaxError)) { return NULL; } - // Make a second parser pass. In this pass we activate heavier and slower checks + // Make a second parser pass. In this pass we activate heavier and slower checks // to produce better error messages and more complete diagnostics. Extra "invalid_*" // rules will be active during parsing. Token *last_token = p->tokens[p->fill - 1]; @@ -885,8 +885,7 @@ _PyPegen_run_parser_from_file_pointer(FILE *fp, int start_rule, PyObject *filena tok->fp_interactive = 1; } // This transfers the ownership to the tokenizer - tok->filename = filename_ob; - Py_INCREF(filename_ob); + tok->filename = Py_NewRef(filename_ob); // From here on we need to clean up even if there's an error mod_ty result = NULL; @@ -925,8 +924,7 @@ _PyPegen_run_parser_from_string(const char *str, int start_rule, PyObject *filen return NULL; } // This transfers the ownership to the tokenizer - tok->filename = filename_ob; - Py_INCREF(filename_ob); + tok->filename = Py_NewRef(filename_ob); // We need to clear up from here on mod_ty result = NULL; @@ -946,4 +944,4 @@ _PyPegen_run_parser_from_string(const char *str, int start_rule, PyObject *filen error: _PyTokenizer_Free(tok); return result; -} \ No newline at end of file +} diff --git a/Parser/pegen.h b/Parser/pegen.h index e5e712ab26b..ad5c97f5f7e 100644 --- a/Parser/pegen.h +++ b/Parser/pegen.h @@ -3,8 +3,8 @@ #define PY_SSIZE_T_CLEAN #include -#include #include +#include #if 0 #define PyPARSE_YIELD_IS_KEYWORD 0x0001 @@ -22,6 +22,7 @@ #define PyPARSE_BARRY_AS_BDFL 0x0020 #define PyPARSE_TYPE_COMMENTS 0x0040 #define PyPARSE_ASYNC_HACKS 0x0080 +#define PyPARSE_ALLOW_INCOMPLETE_INPUT 0x0100 #define CURRENT_POS (-5) @@ -35,12 +36,13 @@ typedef struct _memo { typedef struct { int type; PyObject *bytes; + int level; int lineno, col_offset, end_lineno, end_col_offset; Memo *memo; } Token; typedef struct { - char *str; + const char *str; int type; } KeywordToken; @@ -76,7 +78,7 @@ typedef struct { Token *known_err_token; int level; int call_invalid_rules; - int in_raw_rule; + int debug; } Parser; typedef struct { @@ -226,8 +228,9 @@ _RAISE_SYNTAX_ERROR_INVALID_TARGET(Parser *p, TARGETS_TYPE type, void *e) msg, _PyPegen_get_expr_name(invalid_target) ); + return RAISE_SYNTAX_ERROR_KNOWN_LOCATION(invalid_target, "invalid syntax"); } - return RAISE_SYNTAX_ERROR("invalid syntax"); + return NULL; } // Action utility functions @@ -322,6 +325,7 @@ int _PyPegen_check_barry_as_flufl(Parser *, Token *); int _PyPegen_check_legacy_stmt(Parser *p, expr_ty t); mod_ty _PyPegen_make_module(Parser *, asdl_stmt_seq *); void *_PyPegen_arguments_parsing_error(Parser *, expr_ty); +expr_ty _PyPegen_get_last_comprehension_item(comprehension_ty comprehension); void *_PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq *comprehensions); // Parser API diff --git a/Parser/pegen_errors.c b/Parser/pegen_errors.c index 694184a03b0..6ea7600119b 100644 --- a/Parser/pegen_errors.c +++ b/Parser/pegen_errors.c @@ -164,12 +164,15 @@ _PyPegen_tokenize_full_source_to_check_for_errors(Parser *p) { Py_ssize_t current_err_line = current_token->lineno; int ret = 0; + struct token new_token; for (;;) { - const char *start; - const char *end; - switch (_PyTokenizer_Get(p->tok, &start, &end)) { + switch (_PyTokenizer_Get(p->tok, &new_token)) { case ERRORTOKEN: + if (PyErr_Occurred()) { + ret = -1; + goto exit; + } if (p->tok->level != 0) { int error_lineno = p->tok->parenlinenostack[p->tok->level-1]; if (current_err_line > error_lineno) { @@ -245,13 +248,29 @@ get_error_line_from_tokenizer_buffers(Parser *p, Py_ssize_t lineno) * (multi-line) statement are stored in p->tok->interactive_src_start. * If not, we're parsing from a string, which means that the whole source * is stored in p->tok->str. */ - assert((p->tok->fp == NULL && p->tok->str != NULL) || p->tok->fp == stdin); + assert((p->tok->fp == NULL && p->tok->str != NULL) || p->tok->fp != NULL); char *cur_line = p->tok->fp_interactive ? p->tok->interactive_src_start : p->tok->str; - assert(cur_line != NULL); + if (cur_line == NULL) { + assert(p->tok->fp_interactive); + // We can reach this point if the tokenizer buffers for interactive source have not been + // initialized because we failed to decode the original source with the given locale. + return PyUnicode_FromStringAndSize("", 0); + } - for (int i = 0; i < lineno - 1; i++) { - cur_line = strchr(cur_line, '\n') + 1; + Py_ssize_t relative_lineno = p->starting_lineno ? lineno - p->starting_lineno + 1 : lineno; + const char* buf_end = p->tok->fp_interactive ? p->tok->interactive_src_end : p->tok->inp; + + for (int i = 0; i < relative_lineno - 1; i++) { + char *new_line = strchr(cur_line, '\n'); + // The assert is here for debug builds but the conditional that + // follows is there so in release builds we do not crash at the cost + // to report a potentially wrong line. + assert(new_line != NULL && new_line + 1 < buf_end); + if (new_line == NULL || new_line + 1 > buf_end) { + break; + } + cur_line = new_line + 1; } char *next_newline; @@ -300,7 +319,7 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, goto error; } - if (p->tok->fp_interactive) { + if (p->tok->fp_interactive && p->tok->interactive_src_start != NULL) { error_line = get_error_line_from_tokenizer_buffers(p, lineno); } else if (p->start_rule == Py_file_input) { @@ -355,7 +374,7 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, } } } - tmp = Py_BuildValue("(OiiNii)", p->tok->filename, lineno, col_number, error_line, end_lineno, end_col_number); + tmp = Py_BuildValue("(OnnNnn)", p->tok->filename, lineno, col_number, error_line, end_lineno, end_col_number); if (!tmp) { goto error; } @@ -388,7 +407,8 @@ _Pypegen_set_syntax_error(Parser* p, Token* last_token) { if (PyErr_Occurred()) { // Prioritize tokenizer errors to custom syntax errors raised // on the second phase only if the errors come from the parser. - if (p->tok->done == E_DONE && PyErr_ExceptionMatches(PyExc_SyntaxError)) { + int is_tok_ok = (p->tok->done == E_DONE || p->tok->done == E_OK); + if (is_tok_ok && PyErr_ExceptionMatches(PyExc_SyntaxError)) { _PyPegen_tokenize_full_source_to_check_for_errors(p); } // Propagate the existing syntax error. @@ -399,7 +419,7 @@ _Pypegen_set_syntax_error(Parser* p, Token* last_token) { RAISE_SYNTAX_ERROR("error at start before reading any input"); } // Parser encountered EOF (End of File) unexpectedtly - if (p->tok->done == E_EOF) { + if (last_token->type == ERRORTOKEN && p->tok->done == E_EOF) { if (p->tok->level) { raise_unclosed_parentheses_error(p); } else { @@ -422,4 +442,4 @@ _Pypegen_set_syntax_error(Parser* p, Token* last_token) { // _PyPegen_tokenize_full_source_to_check_for_errors will override the existing // generic SyntaxError we just raised if errors are found. _PyPegen_tokenize_full_source_to_check_for_errors(p); -} \ No newline at end of file +} diff --git a/Parser/string_parser.c b/Parser/string_parser.c index c6fe99c885d..c096bea7426 100644 --- a/Parser/string_parser.c +++ b/Parser/string_parser.c @@ -9,16 +9,28 @@ //// STRING HANDLING FUNCTIONS //// static int -warn_invalid_escape_sequence(Parser *p, unsigned char first_invalid_escape_char, Token *t) +warn_invalid_escape_sequence(Parser *p, const char *first_invalid_escape, Token *t) { + unsigned char c = *first_invalid_escape; + int octal = ('4' <= c && c <= '7'); PyObject *msg = - PyUnicode_FromFormat("invalid escape sequence '\\%c'", first_invalid_escape_char); + octal + ? PyUnicode_FromFormat("invalid octal escape sequence '\\%.3s'", + first_invalid_escape) + : PyUnicode_FromFormat("invalid escape sequence '\\%c'", c); if (msg == NULL) { return -1; } - if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, msg, p->tok->filename, + PyObject *category; + if (p->feature_version >= 12) { + category = PyExc_SyntaxWarning; + } + else { + category = PyExc_DeprecationWarning; + } + if (PyErr_WarnExplicitObject(category, msg, p->tok->filename, t->lineno, NULL, NULL) < 0) { - if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) { + if (PyErr_ExceptionMatches(category)) { /* Replace the DeprecationWarning exception with a SyntaxError to get a more accurate error report */ PyErr_Clear(); @@ -27,7 +39,13 @@ warn_invalid_escape_sequence(Parser *p, unsigned char first_invalid_escape_char, since _PyPegen_raise_error uses p->tokens[p->fill - 1] for the error location, if p->known_err_token is not set. */ p->known_err_token = t; - RAISE_SYNTAX_ERROR("invalid escape sequence '\\%c'", first_invalid_escape_char); + if (octal) { + RAISE_SYNTAX_ERROR("invalid octal escape sequence '\\%.3s'", + first_invalid_escape); + } + else { + RAISE_SYNTAX_ERROR("invalid escape sequence '\\%c'", c); + } } Py_DECREF(msg); return -1; @@ -118,7 +136,7 @@ decode_unicode_with_escapes(Parser *parser, const char *s, size_t len, Token *t) v = _PyUnicode_DecodeUnicodeEscapeInternal(s, len, NULL, NULL, &first_invalid_escape); if (v != NULL && first_invalid_escape != NULL) { - if (warn_invalid_escape_sequence(parser, *first_invalid_escape, t) < 0) { + if (warn_invalid_escape_sequence(parser, first_invalid_escape, t) < 0) { /* We have not decref u before because first_invalid_escape points inside u. */ Py_XDECREF(u); @@ -140,7 +158,7 @@ decode_bytes_with_escapes(Parser *p, const char *s, Py_ssize_t len, Token *t) } if (first_invalid_escape != NULL) { - if (warn_invalid_escape_sequence(p, *first_invalid_escape, t) < 0) { + if (warn_invalid_escape_sequence(p, first_invalid_escape, t) < 0) { Py_DECREF(result); return NULL; } @@ -315,6 +333,9 @@ fstring_find_expr_location(Token *parent, const char* expr_start, char *expr_str start--; } *p_cols += (int)(expr_start - start); + if (*start == '\n') { + *p_cols -= 1; + } } /* adjust the start based on the number of newlines encountered before the f-string expression */ @@ -357,7 +378,12 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end, break; } } + if (s == expr_end) { + if (*expr_end == '!' || *expr_end == ':' || *expr_end == '=') { + RAISE_SYNTAX_ERROR("f-string: expression required before '%c'", *expr_end); + return NULL; + } RAISE_SYNTAX_ERROR("f-string: empty expression not allowed"); return NULL; } @@ -391,13 +417,14 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end, PyMem_Free(str); return NULL; } - Py_INCREF(p->tok->filename); - tok->filename = p->tok->filename; + tok->filename = Py_NewRef(p->tok->filename); + tok->lineno = t->lineno + lines - 1; Parser *p2 = _PyPegen_Parser_New(tok, Py_fstring_input, p->flags, p->feature_version, NULL, p->arena); - p2->starting_lineno = t->lineno + lines - 1; - p2->starting_col_offset = t->col_offset + cols; + + p2->starting_lineno = t->lineno + lines; + p2->starting_col_offset = lines != 0 ? cols : t->col_offset + cols; expr = _PyPegen_run_parser(p2); @@ -439,14 +466,25 @@ fstring_find_literal(Parser *p, const char **str, const char *end, int raw, if (!raw && ch == '\\' && s < end) { ch = *s++; if (ch == 'N') { + /* We need to look at and skip matching braces for "\N{name}" + sequences because otherwise we'll think the opening '{' + starts an expression, which is not the case with "\N". + Keep looking for either a matched '{' '}' pair, or the end + of the string. */ + if (s < end && *s++ == '{') { while (s < end && *s++ != '}') { } continue; } - break; + + /* This is an invalid "\N" sequence, since it's a "\N" not + followed by a "{". Just keep parsing this literal. This + error will be caught later by + decode_unicode_with_escapes(). */ + continue; } - if (ch == '{' && warn_invalid_escape_sequence(p, ch, t) < 0) { + if (ch == '{' && warn_invalid_escape_sequence(p, s-1, t) < 0) { return -1; } } @@ -488,7 +526,8 @@ done: *literal = PyUnicode_DecodeUTF8Stateful(literal_start, s - literal_start, NULL, NULL); - } else { + } + else { *literal = decode_unicode_with_escapes(p, literal_start, s - literal_start, t); } @@ -651,12 +690,12 @@ fstring_find_expr(Parser *p, const char **str, const char *end, int raw, int rec *str += 1; continue; } - /* Don't get out of the loop for these, if they're single - chars (not part of 2-char tokens). If by themselves, they - don't end an expression (unlike say '!'). */ - if (ch == '>' || ch == '<') { - continue; - } + } + /* Don't get out of the loop for these, if they're single + chars (not part of 2-char tokens). If by themselves, they + don't end an expression (unlike say '!'). */ + if (ch == '>' || ch == '<') { + continue; } /* Normal way out of this loop. */ @@ -683,10 +722,10 @@ fstring_find_expr(Parser *p, const char **str, const char *end, int raw, int rec } } expr_end = *str; - /* If we leave this loop in a string or with mismatched parens, we - don't care. We'll get a syntax error when compiling the - expression. But, we can produce a better error message, so - let's just do that.*/ + /* If we leave the above loop in a string or with mismatched parens, we + don't really care. We'll get a syntax error when compiling the + expression. But, we can produce a better error message, so let's just + do that.*/ if (quote_char) { RAISE_SYNTAX_ERROR("f-string: unterminated string"); goto error; @@ -725,7 +764,9 @@ fstring_find_expr(Parser *p, const char **str, const char *end, int raw, int rec while (Py_ISSPACE(**str)) { *str += 1; } - + if (*str >= end) { + goto unexpected_end_of_string; + } /* Set *expr_text to the text of the expression. */ *expr_text = PyUnicode_FromStringAndSize(expr_start, *str-expr_start); if (!*expr_text) { @@ -736,27 +777,43 @@ fstring_find_expr(Parser *p, const char **str, const char *end, int raw, int rec /* Check for a conversion char, if present. */ if (**str == '!') { *str += 1; - if (*str >= end) { - goto unexpected_end_of_string; + const char *conv_start = *str; + while (1) { + if (*str >= end) { + goto unexpected_end_of_string; + } + if (**str == '}' || **str == ':') { + break; + } + *str += 1; + } + if (*str == conv_start) { + RAISE_SYNTAX_ERROR( + "f-string: missed conversion character"); + goto error; } - conversion = (unsigned char)**str; - *str += 1; - + conversion = (unsigned char)*conv_start; /* Validate the conversion. */ - if (!(conversion == 's' || conversion == 'r' || conversion == 'a')) { - RAISE_SYNTAX_ERROR( - "f-string: invalid conversion character: " - "expected 's', 'r', or 'a'"); + if ((*str != conv_start + 1) || + !(conversion == 's' || conversion == 'r' || conversion == 'a')) + { + PyObject *conv_obj = PyUnicode_FromStringAndSize(conv_start, + *str-conv_start); + if (conv_obj) { + RAISE_SYNTAX_ERROR( + "f-string: invalid conversion character %R: " + "expected 's', 'r', or 'a'", + conv_obj); + Py_DECREF(conv_obj); + } goto error; } } /* Check for the format spec, if present. */ - if (*str >= end) { - goto unexpected_end_of_string; - } + assert(*str < end); if (**str == ':') { *str += 1; if (*str >= end) { diff --git a/Parser/token.c b/Parser/token.c index 74bca0eff65..6299ad2f563 100644 --- a/Parser/token.c +++ b/Parser/token.c @@ -1,7 +1,7 @@ -/* Auto-generated by Tools/scripts/generate_token.py */ +/* Auto-generated by Tools/build/generate_token.py */ #include "Python.h" -#include "token.h" +#include "pycore_token.h" /* Token names */ @@ -76,7 +76,7 @@ const char * const _PyParser_TokenNames[] = { /* Return the token corresponding to a single character */ int -PyToken_OneChar(int c1) +_PyToken_OneChar(int c1) { switch (c1) { case '%': return PERCENT; @@ -107,7 +107,7 @@ PyToken_OneChar(int c1) } int -PyToken_TwoChars(int c1, int c2) +_PyToken_TwoChars(int c1, int c2) { switch (c1) { case '!': @@ -191,7 +191,7 @@ PyToken_TwoChars(int c1, int c2) } int -PyToken_ThreeChars(int c1, int c2, int c3) +_PyToken_ThreeChars(int c1, int c2, int c3) { switch (c1) { case '*': diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index 6358cdf654e..463c0e00ca1 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -36,11 +36,18 @@ /* Don't ever change this -- it would break the portability of Python code */ #define TABSIZE 8 +#define MAKE_TOKEN(token_type) token_setup(tok, token, token_type, p_start, p_end) +#define MAKE_TYPE_COMMENT_TOKEN(token_type, col_offset, end_col_offset) (\ + type_comment_token_setup(tok, token, token_type, col_offset, end_col_offset, p_start, p_end)) +#define ADVANCE_LINENO() \ + tok->lineno++; \ + tok->col_offset = 0; + /* Forward */ static struct tok_state *tok_new(void); static int tok_nextc(struct tok_state *tok); static void tok_backup(struct tok_state *tok, int c); - +static int syntaxerror(struct tok_state *tok, const char *format, ...); /* Spaces in this constant are treated as "zero or more spaces or tabs" when tokenizing. */ @@ -71,6 +78,8 @@ tok_new(void) tok->pendin = 0; tok->prompt = tok->nextprompt = NULL; tok->lineno = 0; + tok->starting_col_offset = -1; + tok->col_offset = -1; tok->level = 0; tok->altindstack[0] = 0; tok->decoding_state = STATE_INIT; @@ -88,6 +97,10 @@ tok_new(void) tok->async_def_nl = 0; tok->interactive_underflow = IUNDERFLOW_NORMAL; tok->str = NULL; + tok->report_warnings = 1; +#ifdef Py_DEBUG + tok->debug = _Py_GetConfig()->parser_debug; +#endif return tok; } @@ -282,30 +295,6 @@ check_bom(int get_char(struct tok_state *), unget_char(ch1, tok); return 1; } -#if 0 - /* Disable support for UTF-16 BOMs until a decision - is made whether this needs to be supported. */ - } else if (ch1 == 0xFE) { - ch2 = get_char(tok); - if (ch2 != 0xFF) { - unget_char(ch2, tok); - unget_char(ch1, tok); - return 1; - } - if (!set_readline(tok, "utf-16-be")) - return 0; - tok->decoding_state = STATE_NORMAL; - } else if (ch1 == 0xFF) { - ch2 = get_char(tok); - if (ch2 != 0xFE) { - unget_char(ch2, tok); - unget_char(ch1, tok); - return 1; - } - if (!set_readline(tok, "utf-16-le")) - return 0; - tok->decoding_state = STATE_NORMAL; -#endif } else { unget_char(ch1, tok); return 1; @@ -329,6 +318,10 @@ tok_concatenate_interactive_new_line(struct tok_state *tok, const char *line) { Py_ssize_t current_size = tok->interactive_src_end - tok->interactive_src_start; Py_ssize_t line_size = strlen(line); + char last_char = line[line_size > 0 ? line_size - 1 : line_size]; + if (last_char != '\n') { + line_size += 1; + } char* new_str = tok->interactive_src_start; new_str = PyMem_Realloc(new_str, current_size + line_size + 1); @@ -342,7 +335,11 @@ tok_concatenate_interactive_new_line(struct tok_state *tok, const char *line) { return -1; } strcpy(new_str + current_size, line); - + if (last_char != '\n') { + /* Last line does not end in \n, fake one */ + new_str[current_size + line_size - 1] = '\n'; + new_str[current_size + line_size] = '\0'; + } tok->interactive_src_start = new_str; tok->interactive_src_end = new_str + current_size + line_size; return 0; @@ -391,6 +388,11 @@ tok_reserve_buf(struct tok_state *tok, Py_ssize_t size) return 1; } +static inline int +contains_null_bytes(const char* str, size_t size) { + return memchr(str, 0, size) != NULL; +} + static int tok_readline_recode(struct tok_state *tok) { PyObject *line; @@ -412,7 +414,11 @@ tok_readline_recode(struct tok_state *tok) { error_ret(tok); goto error; } - if (!tok_reserve_buf(tok, buflen + 1)) { + // Make room for the null terminator *and* potentially + // an extra newline character that we may need to artificially + // add. + size_t buffer_size = buflen + 2; + if (!tok_reserve_buf(tok, buffer_size)) { goto error; } memcpy(tok->inp, buf, buflen); @@ -442,9 +448,7 @@ error: static int fp_setreadl(struct tok_state *tok, const char* enc) { - PyObject *readline, *io, *stream; - _Py_IDENTIFIER(open); - _Py_IDENTIFIER(readline); + PyObject *readline, *open, *stream; int fd; long pos; @@ -461,26 +465,29 @@ fp_setreadl(struct tok_state *tok, const char* enc) return 0; } - io = PyImport_ImportModuleNoBlock("io"); - if (io == NULL) + open = _PyImport_GetModuleAttrString("io", "open"); + if (open == NULL) { return 0; - - stream = _PyObject_CallMethodId(io, &PyId_open, "isisOOO", + } + stream = PyObject_CallFunction(open, "isisOOO", fd, "r", -1, enc, Py_None, Py_None, Py_False); - Py_DECREF(io); - if (stream == NULL) + Py_DECREF(open); + if (stream == NULL) { return 0; + } - readline = _PyObject_GetAttrId(stream, &PyId_readline); + readline = PyObject_GetAttr(stream, &_Py_ID(readline)); Py_DECREF(stream); - if (readline == NULL) + if (readline == NULL) { return 0; + } Py_XSETREF(tok->decoding_readline, readline); if (pos > 0) { PyObject *bufobj = _PyObject_CallNoArgs(readline); - if (bufobj == NULL) + if (bufobj == NULL) { return 0; + } Py_DECREF(bufobj); } @@ -501,25 +508,59 @@ static void fp_ungetc(int c, struct tok_state *tok) { /* Check whether the characters at s start a valid UTF-8 sequence. Return the number of characters forming - the sequence if yes, 0 if not. */ -static int valid_utf8(const unsigned char* s) + the sequence if yes, 0 if not. The special cases match + those in stringlib/codecs.h:utf8_decode. +*/ +static int +valid_utf8(const unsigned char* s) { int expected = 0; int length; - if (*s < 0x80) + if (*s < 0x80) { /* single-byte code */ return 1; - if (*s < 0xc0) - /* following byte */ - return 0; - if (*s < 0xE0) + } + else if (*s < 0xE0) { + /* \xC2\x80-\xDF\xBF -- 0080-07FF */ + if (*s < 0xC2) { + /* invalid sequence + \x80-\xBF -- continuation byte + \xC0-\xC1 -- fake 0000-007F */ + return 0; + } expected = 1; - else if (*s < 0xF0) + } + else if (*s < 0xF0) { + /* \xE0\xA0\x80-\xEF\xBF\xBF -- 0800-FFFF */ + if (*s == 0xE0 && *(s + 1) < 0xA0) { + /* invalid sequence + \xE0\x80\x80-\xE0\x9F\xBF -- fake 0000-0800 */ + return 0; + } + else if (*s == 0xED && *(s + 1) >= 0xA0) { + /* Decoding UTF-8 sequences in range \xED\xA0\x80-\xED\xBF\xBF + will result in surrogates in range D800-DFFF. Surrogates are + not valid UTF-8 so they are rejected. + See https://www.unicode.org/versions/Unicode5.2.0/ch03.pdf + (table 3-7) and http://www.rfc-editor.org/rfc/rfc3629.txt */ + return 0; + } expected = 2; - else if (*s < 0xF8) + } + else if (*s < 0xF5) { + /* \xF0\x90\x80\x80-\xF4\x8F\xBF\xBF -- 10000-10FFFF */ + if (*(s + 1) < 0x90 ? *s == 0xF0 : *s == 0xF4) { + /* invalid sequence -- one of: + \xF0\x80\x80\x80-\xF0\x8F\xBF\xBF -- fake 0000-FFFF + \xF4\x90\x80\x80- -- 110000- overflow */ + return 0; + } expected = 3; - else + } + else { + /* invalid start byte */ return 0; + } length = expected + 1; for (; expected; expected--) if (s[expected] < 0x80 || s[expected] >= 0xC0) @@ -540,14 +581,12 @@ ensure_utf8(char *line, struct tok_state *tok) } } if (badchar) { - /* Need to add 1 to the line number, since this line - has not been counted, yet. */ PyErr_Format(PyExc_SyntaxError, "Non-UTF-8 code starting with '\\x%.2x' " "in file %U on line %i, " "but no encoding declared; " - "see https://python.org/dev/peps/pep-0263/ for details", - badchar, tok->filename, tok->lineno + 1); + "see https://peps.python.org/pep-0263/ for details", + badchar, tok->filename, tok->lineno); return 0; } return 1; @@ -809,9 +848,9 @@ tok_readline_raw(struct tok_state *tok) if (!tok_reserve_buf(tok, BUFSIZ)) { return 0; } - char *line = Py_UniversalNewlineFgets(tok->inp, - (int)(tok->end - tok->inp), - tok->fp, NULL); + int n_chars = (int)(tok->end - tok->inp); + size_t line_size = 0; + char *line = _Py_UniversalNewlineFgetsWithSize(tok->inp, n_chars, tok->fp, NULL, &line_size); if (line == NULL) { return 1; } @@ -819,10 +858,10 @@ tok_readline_raw(struct tok_state *tok) tok_concatenate_interactive_new_line(tok, line) == -1) { return 0; } - if (*tok->inp == '\0') { + tok->inp += line_size; + if (tok->inp == tok->buf) { return 0; } - tok->inp = strchr(tok->inp, '\0'); } while (tok->inp[-1] != '\n'); return 1; } @@ -844,7 +883,7 @@ tok_underflow_string(struct tok_state *tok) { tok->buf = tok->cur; } tok->line_start = tok->cur; - tok->lineno++; + ADVANCE_LINENO(); tok->inp = end; return 1; } @@ -855,7 +894,7 @@ tok_underflow_interactive(struct tok_state *tok) { tok->done = E_INTERACT_STOP; return 1; } - char *newtok = PyOS_Readline(stdin, stdout, tok->prompt); + char *newtok = PyOS_Readline(tok->fp ? tok->fp : stdin, stdout, tok->prompt); if (newtok != NULL) { char *translated = translate_newlines(newtok, 0, tok); PyMem_Free(newtok); @@ -903,7 +942,7 @@ tok_underflow_interactive(struct tok_state *tok) { else if (tok->start != NULL) { Py_ssize_t cur_multi_line_start = tok->multi_line_start - tok->buf; size_t size = strlen(newtok); - tok->lineno++; + ADVANCE_LINENO(); if (!tok_reserve_buf(tok, size + 1)) { PyMem_Free(tok->buf); tok->buf = NULL; @@ -916,7 +955,7 @@ tok_underflow_interactive(struct tok_state *tok) { tok->multi_line_start = tok->buf + cur_multi_line_start; } else { - tok->lineno++; + ADVANCE_LINENO(); PyMem_Free(tok->buf); tok->buf = newtok; tok->cur = tok->buf; @@ -966,12 +1005,13 @@ tok_underflow_file(struct tok_state *tok) { return 0; } if (tok->inp[-1] != '\n') { + assert(tok->inp + 1 < tok->end); /* Last line does not end in \n, fake one */ *tok->inp++ = '\n'; *tok->inp = '\0'; } - tok->lineno++; + ADVANCE_LINENO(); if (tok->decoding_state != STATE_NORMAL) { if (tok->lineno > 2) { tok->decoding_state = STATE_NORMAL; @@ -984,12 +1024,9 @@ tok_underflow_file(struct tok_state *tok) { } /* The default encoding is UTF-8, so make sure we don't have any non-UTF-8 sequences in it. */ - if (!tok->encoding - && (tok->decoding_state != STATE_NORMAL || tok->lineno >= 2)) { - if (!ensure_utf8(tok->cur, tok)) { - error_ret(tok); - return 0; - } + if (!tok->encoding && !ensure_utf8(tok->cur, tok)) { + error_ret(tok); + return 0; } assert(tok->done == E_OK); return tok->done == E_OK; @@ -1032,10 +1069,12 @@ tok_nextc(struct tok_state *tok) int rc; for (;;) { if (tok->cur != tok->inp) { + tok->col_offset++; return Py_CHARMASK(*tok->cur++); /* Fast path */ } - if (tok->done != E_OK) - return EOF; + if (tok->done != E_OK) { + return EOF; + } if (tok->fp == NULL) { rc = tok_underflow_string(tok); } @@ -1046,7 +1085,7 @@ tok_nextc(struct tok_state *tok) rc = tok_underflow_file(tok); } #if defined(Py_DEBUG) - if (Py_DebugFlag) { + if (tok->debug) { fprintf(stderr, "line[%d] = ", tok->lineno); print_escape(stderr, tok->cur, tok->inp - tok->cur); fprintf(stderr, " tok->done = %d\n", tok->done); @@ -1057,6 +1096,12 @@ tok_nextc(struct tok_state *tok) return EOF; } tok->line_start = tok->cur; + + if (contains_null_bytes(tok->line_start, tok->inp - tok->line_start)) { + syntaxerror(tok, "source code cannot contain null bytes"); + tok->cur = tok->inp; + return EOF; + } } Py_UNREACHABLE(); } @@ -1073,6 +1118,7 @@ tok_backup(struct tok_state *tok, int c) if ((int)(unsigned char)*tok->cur != c) { Py_FatalError("tok_backup: wrong character"); } + tok->col_offset--; } } @@ -1127,11 +1173,7 @@ static int syntaxerror(struct tok_state *tok, const char *format, ...) { va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif int ret = _syntaxerror_range(tok, format, -1, -1, vargs); va_end(vargs); return ret; @@ -1143,18 +1185,12 @@ syntaxerror_known_range(struct tok_state *tok, const char *format, ...) { va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif int ret = _syntaxerror_range(tok, format, col_offset, end_col_offset, vargs); va_end(vargs); return ret; } - - static int indenterror(struct tok_state *tok) { @@ -1164,24 +1200,24 @@ indenterror(struct tok_state *tok) } static int -parser_warn(struct tok_state *tok, const char *format, ...) +parser_warn(struct tok_state *tok, PyObject *category, const char *format, ...) { + if (!tok->report_warnings) { + return 0; + } + PyObject *errmsg; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif errmsg = PyUnicode_FromFormatV(format, vargs); va_end(vargs); if (!errmsg) { goto error; } - if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, errmsg, tok->filename, + if (PyErr_WarnExplicitObject(category, errmsg, tok->filename, tok->lineno, NULL, NULL) < 0) { - if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) { + if (PyErr_ExceptionMatches(category)) { /* Replace the DeprecationWarning exception with a SyntaxError to get a more accurate error report */ PyErr_Clear(); @@ -1254,9 +1290,14 @@ verify_end_of_number(struct tok_state *tok, int c, const char *kind) else if (c == 'o') { r = lookahead(tok, "r"); } + else if (c == 'n') { + r = lookahead(tok, "ot"); + } if (r) { tok_backup(tok, c); - if (parser_warn(tok, "invalid %s literal", kind)) { + if (parser_warn(tok, PyExc_SyntaxWarning, + "invalid %s literal", kind)) + { return 0; } tok_nextc(tok); @@ -1350,15 +1391,66 @@ tok_decimal_tail(struct tok_state *tok) /* Get next token, after space stripping etc. */ +static inline int +tok_continuation_line(struct tok_state *tok) { + int c = tok_nextc(tok); + if (c != '\n') { + tok->done = E_LINECONT; + return -1; + } + c = tok_nextc(tok); + if (c == EOF) { + tok->done = E_EOF; + tok->cur = tok->inp; + return -1; + } else { + tok_backup(tok, c); + } + return c; +} + static int -tok_get(struct tok_state *tok, const char **p_start, const char **p_end) +type_comment_token_setup(struct tok_state *tok, struct token *token, int type, int col_offset, + int end_col_offset, const char *start, const char *end) +{ + token->level = tok->level; + token->lineno = token->end_lineno = tok->lineno; + token->col_offset = col_offset; + token->end_col_offset = end_col_offset; + token->start = start; + token->end = end; + return type; +} + +static int +token_setup(struct tok_state *tok, struct token *token, int type, const char *start, const char *end) +{ + assert((start == NULL && end == NULL) || (start != NULL && end != NULL)); + token->level = tok->level; + token->lineno = type == STRING ? tok->first_lineno : tok->lineno; + token->end_lineno = tok->lineno; + token->col_offset = token->end_col_offset = -1; + token->start = start; + token->end = end; + + if (start != NULL && end != NULL) { + token->col_offset = tok->starting_col_offset; + token->end_col_offset = tok->col_offset; + } + return type; +} + +static int +tok_get(struct tok_state *tok, struct token *token) { int c; int blankline, nonascii; - *p_start = *p_end = NULL; + const char *p_start = NULL; + const char *p_end = NULL; nextline: tok->start = NULL; + tok->starting_col_offset = -1; blankline = 0; /* Get indentation level */ @@ -1366,6 +1458,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) int col = 0; int altcol = 0; tok->atbol = 0; + int cont_line_col = 0; for (;;) { c = tok_nextc(tok); if (c == ' ') { @@ -1378,14 +1471,23 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) else if (c == '\014') {/* Control-L (formfeed) */ col = altcol = 0; /* For Emacs users */ } + else if (c == '\\') { + // Indentation cannot be split over multiple physical lines + // using backslashes. This means that if we found a backslash + // preceded by whitespace, **the first one we find** determines + // the level of indentation of whatever comes next. + cont_line_col = cont_line_col ? cont_line_col : col; + if ((c = tok_continuation_line(tok)) == -1) { + return MAKE_TOKEN(ERRORTOKEN); + } + } else { break; } } tok_backup(tok, c); - if (c == '#' || c == '\n' || c == '\\') { + if (c == '#' || c == '\n') { /* Lines with only whitespace and/or comments - and/or a line continuation character shouldn't affect the indentation and are not passed to the parser as NEWLINE tokens, except *totally* empty lines in interactive @@ -1406,10 +1508,12 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) may need to skip to the end of a comment */ } if (!blankline && tok->level == 0) { + col = cont_line_col ? cont_line_col : col; + altcol = cont_line_col ? cont_line_col : altcol; if (col == tok->indstack[tok->indent]) { /* No change */ if (altcol != tok->altindstack[tok->indent]) { - return indenterror(tok); + return MAKE_TOKEN(indenterror(tok)); } } else if (col > tok->indstack[tok->indent]) { @@ -1417,10 +1521,10 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) if (tok->indent+1 >= MAXINDENT) { tok->done = E_TOODEEP; tok->cur = tok->inp; - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } if (altcol <= tok->altindstack[tok->indent]) { - return indenterror(tok); + return MAKE_TOKEN(indenterror(tok)); } tok->pendin++; tok->indstack[++tok->indent] = col; @@ -1436,26 +1540,27 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) if (col != tok->indstack[tok->indent]) { tok->done = E_DEDENT; tok->cur = tok->inp; - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } if (altcol != tok->altindstack[tok->indent]) { - return indenterror(tok); + return MAKE_TOKEN(indenterror(tok)); } } } } tok->start = tok->cur; + tok->starting_col_offset = tok->col_offset; /* Return pending indents/dedents */ if (tok->pendin != 0) { if (tok->pendin < 0) { tok->pendin++; - return DEDENT; + return MAKE_TOKEN(DEDENT); } else { tok->pendin--; - return INDENT; + return MAKE_TOKEN(INDENT); } } @@ -1492,11 +1597,13 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } while (c == ' ' || c == '\t' || c == '\014'); /* Set start of current token */ - tok->start = tok->cur - 1; + tok->start = tok->cur == NULL ? NULL : tok->cur - 1; + tok->starting_col_offset = tok->col_offset - 1; /* Skip comment, unless it's a type comment */ if (c == '#') { const char *prefix, *p, *type_start; + int current_starting_col_offset; while (c != EOF && c != '\n') { c = tok_nextc(tok); @@ -1504,14 +1611,17 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) if (tok->type_comments) { p = tok->start; + current_starting_col_offset = tok->starting_col_offset; prefix = type_comment_prefix; while (*prefix && p < tok->cur) { if (*prefix == ' ') { while (*p == ' ' || *p == '\t') { p++; + current_starting_col_offset++; } } else if (*prefix == *p) { p++; + current_starting_col_offset++; } else { break; } @@ -1522,7 +1632,9 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) /* This is a type comment if we matched all of type_comment_prefix. */ if (!*prefix) { int is_type_ignore = 1; + // +6 in order to skip the word 'ignore' const char *ignore_end = p + 6; + const int ignore_end_col_offset = current_starting_col_offset + 6; tok_backup(tok, c); /* don't eat the newline or EOF */ type_start = p; @@ -1535,34 +1647,34 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) && ((unsigned char)ignore_end[0] >= 128 || Py_ISALNUM(ignore_end[0])))); if (is_type_ignore) { - *p_start = ignore_end; - *p_end = tok->cur; + p_start = ignore_end; + p_end = tok->cur; /* If this type ignore is the only thing on the line, consume the newline also. */ if (blankline) { tok_nextc(tok); tok->atbol = 1; } - return TYPE_IGNORE; + return MAKE_TYPE_COMMENT_TOKEN(TYPE_IGNORE, ignore_end_col_offset, tok->col_offset); } else { - *p_start = type_start; /* after type_comment_prefix */ - *p_end = tok->cur; - return TYPE_COMMENT; + p_start = type_start; + p_end = tok->cur; + return MAKE_TYPE_COMMENT_TOKEN(TYPE_COMMENT, current_starting_col_offset, tok->col_offset); } } } } if (tok->done == E_INTERACT_STOP) { - return ENDMARKER; + return MAKE_TOKEN(ENDMARKER); } /* Check for EOF and errors now */ if (c == EOF) { if (tok->level) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } - return tok->done == E_EOF ? ENDMARKER : ERRORTOKEN; + return MAKE_TOKEN(tok->done == E_EOF ? ENDMARKER : ERRORTOKEN); } /* Identifier (most frequent token!) */ @@ -1602,11 +1714,11 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } tok_backup(tok, c); if (nonascii && !verify_identifier(tok)) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } - *p_start = tok->start; - *p_end = tok->cur; + p_start = tok->start; + p_end = tok->cur; /* async/await parsing block. */ if (tok->cur - tok->start == 5 && tok->start[0] == 'a') { @@ -1621,10 +1733,10 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) if (!tok->async_hacks || tok->async_def) { /* Always recognize the keywords. */ if (memcmp(tok->start, "async", 5) == 0) { - return ASYNC; + return MAKE_TOKEN(ASYNC); } if (memcmp(tok->start, "await", 5) == 0) { - return AWAIT; + return MAKE_TOKEN(AWAIT); } } else if (memcmp(tok->start, "async", 5) == 0) { @@ -1632,13 +1744,11 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) Look ahead one token to see if that is 'def'. */ struct tok_state ahead_tok; - const char *ahead_tok_start = NULL; - const char *ahead_tok_end = NULL; + struct token ahead_token; int ahead_tok_kind; memcpy(&ahead_tok, tok, sizeof(ahead_tok)); - ahead_tok_kind = tok_get(&ahead_tok, &ahead_tok_start, - &ahead_tok_end); + ahead_tok_kind = tok_get(&ahead_tok, &ahead_token); if (ahead_tok_kind == NAME && ahead_tok.cur - ahead_tok.start == 3 @@ -1648,12 +1758,12 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) returning a plain NAME token, return ASYNC. */ tok->async_def_indent = tok->indent; tok->async_def = 1; - return ASYNC; + return MAKE_TOKEN(ASYNC); } } } - return NAME; + return MAKE_TOKEN(NAME); } /* Newline */ @@ -1662,15 +1772,15 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) if (blankline || tok->level > 0) { goto nextline; } - *p_start = tok->start; - *p_end = tok->cur - 1; /* Leave '\n' out of the string */ + p_start = tok->start; + p_end = tok->cur - 1; /* Leave '\n' out of the string */ tok->cont_line = 0; if (tok->async_def) { /* We're somewhere inside an 'async def' function, and we've encountered a NEWLINE after its signature. */ tok->async_def_nl = 1; } - return NEWLINE; + return MAKE_TOKEN(NEWLINE); } /* Period or number starting with period? */ @@ -1681,9 +1791,9 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } else if (c == '.') { c = tok_nextc(tok); if (c == '.') { - *p_start = tok->start; - *p_end = tok->cur; - return ELLIPSIS; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(ELLIPSIS); } else { tok_backup(tok, c); @@ -1693,9 +1803,9 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) else { tok_backup(tok, c); } - *p_start = tok->start; - *p_end = tok->cur; - return DOT; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(DOT); } /* Number */ @@ -1712,14 +1822,14 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } if (!isxdigit(c)) { tok_backup(tok, c); - return syntaxerror(tok, "invalid hexadecimal literal"); + return MAKE_TOKEN(syntaxerror(tok, "invalid hexadecimal literal")); } do { c = tok_nextc(tok); } while (isxdigit(c)); } while (c == '_'); if (!verify_end_of_number(tok, c, "hexadecimal")) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } else if (c == 'o' || c == 'O') { @@ -1731,12 +1841,12 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } if (c < '0' || c >= '8') { if (isdigit(c)) { - return syntaxerror(tok, - "invalid digit '%c' in octal literal", c); + return MAKE_TOKEN(syntaxerror(tok, + "invalid digit '%c' in octal literal", c)); } else { tok_backup(tok, c); - return syntaxerror(tok, "invalid octal literal"); + return MAKE_TOKEN(syntaxerror(tok, "invalid octal literal")); } } do { @@ -1744,11 +1854,11 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } while ('0' <= c && c < '8'); } while (c == '_'); if (isdigit(c)) { - return syntaxerror(tok, - "invalid digit '%c' in octal literal", c); + return MAKE_TOKEN(syntaxerror(tok, + "invalid digit '%c' in octal literal", c)); } if (!verify_end_of_number(tok, c, "octal")) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } else if (c == 'b' || c == 'B') { @@ -1760,12 +1870,11 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } if (c != '0' && c != '1') { if (isdigit(c)) { - return syntaxerror(tok, - "invalid digit '%c' in binary literal", c); + return MAKE_TOKEN(syntaxerror(tok, "invalid digit '%c' in binary literal", c)); } else { tok_backup(tok, c); - return syntaxerror(tok, "invalid binary literal"); + return MAKE_TOKEN(syntaxerror(tok, "invalid binary literal")); } } do { @@ -1773,11 +1882,10 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } while (c == '0' || c == '1'); } while (c == '_'); if (isdigit(c)) { - return syntaxerror(tok, - "invalid digit '%c' in binary literal", c); + return MAKE_TOKEN(syntaxerror(tok, "invalid digit '%c' in binary literal", c)); } if (!verify_end_of_number(tok, c, "binary")) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } else { @@ -1789,7 +1897,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) c = tok_nextc(tok); if (!isdigit(c)) { tok_backup(tok, c); - return syntaxerror(tok, "invalid decimal literal"); + return MAKE_TOKEN(syntaxerror(tok, "invalid decimal literal")); } } if (c != '0') { @@ -1802,7 +1910,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) nonzero = 1; c = tok_decimal_tail(tok); if (c == 0) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } if (c == '.') { @@ -1818,15 +1926,15 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) else if (nonzero) { /* Old-style octal: now disallowed. */ tok_backup(tok, c); - return syntaxerror_known_range( + return MAKE_TOKEN(syntaxerror_known_range( tok, (int)(tok->start + 1 - tok->line_start), (int)(zeros_end - tok->line_start), "leading zeros in decimal integer " "literals are not permitted; " - "use an 0o prefix for octal integers"); + "use an 0o prefix for octal integers")); } if (!verify_end_of_number(tok, c, "decimal")) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } } @@ -1834,7 +1942,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) /* Decimal */ c = tok_decimal_tail(tok); if (c == 0) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } { /* Accept floating point numbers. */ @@ -1845,7 +1953,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) if (isdigit(c)) { c = tok_decimal_tail(tok); if (c == 0) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } } @@ -1859,21 +1967,21 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) c = tok_nextc(tok); if (!isdigit(c)) { tok_backup(tok, c); - return syntaxerror(tok, "invalid decimal literal"); + return MAKE_TOKEN(syntaxerror(tok, "invalid decimal literal")); } } else if (!isdigit(c)) { tok_backup(tok, c); if (!verify_end_of_number(tok, e, "decimal")) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } tok_backup(tok, e); - *p_start = tok->start; - *p_end = tok->cur; - return NUMBER; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(NUMBER); } c = tok_decimal_tail(tok); if (c == 0) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } if (c == 'j' || c == 'J') { @@ -1881,18 +1989,18 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) imaginary: c = tok_nextc(tok); if (!verify_end_of_number(tok, c, "imaginary")) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } else if (!verify_end_of_number(tok, c, "decimal")) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } } tok_backup(tok, c); - *p_start = tok->start; - *p_end = tok->cur; - return NUMBER; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(NUMBER); } letter_quote: @@ -1927,6 +2035,8 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) /* Get rest of string */ while (end_quote_size != quote_size) { c = tok_nextc(tok); + if (tok->done == E_DECODE) + break; if (c == EOF || (quote_size == 1 && c == '\n')) { assert(tok->multi_line_start != NULL); // shift the tok_state's location into @@ -1937,16 +2047,21 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) tok->line_start = tok->multi_line_start; int start = tok->lineno; tok->lineno = tok->first_lineno; - if (quote_size == 3) { - return syntaxerror(tok, - "unterminated triple-quoted string literal" - " (detected at line %d)", start); + syntaxerror(tok, "unterminated triple-quoted string literal" + " (detected at line %d)", start); + if (c != '\n') { + tok->done = E_EOFS; + } + return MAKE_TOKEN(ERRORTOKEN); } else { - return syntaxerror(tok, - "unterminated string literal (detected at" - " line %d)", start); + syntaxerror(tok, "unterminated string literal (detected at" + " line %d)", start); + if (c != '\n') { + tok->done = E_EOLS; + } + return MAKE_TOKEN(ERRORTOKEN); } } if (c == quote) { @@ -1960,25 +2075,15 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } } - *p_start = tok->start; - *p_end = tok->cur; - return STRING; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(STRING); } /* Line continuation */ if (c == '\\') { - c = tok_nextc(tok); - if (c != '\n') { - tok->done = E_LINECONT; - return ERRORTOKEN; - } - c = tok_nextc(tok); - if (c == EOF) { - tok->done = E_EOF; - tok->cur = tok->inp; - return ERRORTOKEN; - } else { - tok_backup(tok, c); + if ((c = tok_continuation_line(tok)) == -1) { + return MAKE_TOKEN(ERRORTOKEN); } tok->cont_line = 1; goto again; /* Read next line */ @@ -1987,19 +2092,19 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) /* Check for two-character token */ { int c2 = tok_nextc(tok); - int token = PyToken_TwoChars(c, c2); - if (token != OP) { + int current_token = _PyToken_TwoChars(c, c2); + if (current_token != OP) { int c3 = tok_nextc(tok); - int token3 = PyToken_ThreeChars(c, c2, c3); - if (token3 != OP) { - token = token3; + int current_token3 = _PyToken_ThreeChars(c, c2, c3); + if (current_token3 != OP) { + current_token = current_token3; } else { tok_backup(tok, c3); } - *p_start = tok->start; - *p_end = tok->cur; - return token; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(current_token); } tok_backup(tok, c2); } @@ -2010,7 +2115,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) case '[': case '{': if (tok->level >= MAXLEVEL) { - return syntaxerror(tok, "too many nested parentheses"); + return MAKE_TOKEN(syntaxerror(tok, "too many nested parentheses")); } tok->parenstack[tok->level] = c; tok->parenlinenostack[tok->level] = tok->lineno; @@ -2021,7 +2126,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) case ']': case '}': if (!tok->level) { - return syntaxerror(tok, "unmatched '%c'", c); + return MAKE_TOKEN(syntaxerror(tok, "unmatched '%c'", c)); } tok->level--; int opening = tok->parenstack[tok->level]; @@ -2030,16 +2135,16 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) (opening == '{' && c == '}'))) { if (tok->parenlinenostack[tok->level] != tok->lineno) { - return syntaxerror(tok, + return MAKE_TOKEN(syntaxerror(tok, "closing parenthesis '%c' does not match " "opening parenthesis '%c' on line %d", - c, opening, tok->parenlinenostack[tok->level]); + c, opening, tok->parenlinenostack[tok->level])); } else { - return syntaxerror(tok, + return MAKE_TOKEN(syntaxerror(tok, "closing parenthesis '%c' does not match " "opening parenthesis '%c'", - c, opening); + c, opening)); } } break; @@ -2048,20 +2153,19 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) if (!Py_UNICODE_ISPRINTABLE(c)) { char hex[9]; (void)PyOS_snprintf(hex, sizeof(hex), "%04X", c); - return syntaxerror(tok, "invalid non-printable character U+%s", hex); + return MAKE_TOKEN(syntaxerror(tok, "invalid non-printable character U+%s", hex)); } /* Punctuation character */ - *p_start = tok->start; - *p_end = tok->cur; - return PyToken_OneChar(c); + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(_PyToken_OneChar(c)); } int -_PyTokenizer_Get(struct tok_state *tok, - const char **p_start, const char **p_end) +_PyTokenizer_Get(struct tok_state *tok, struct token *token) { - int result = tok_get(tok, p_start, p_end); + int result = tok_get(tok, token); if (tok->decoding_erred) { result = ERRORTOKEN; tok->done = E_DECODE; @@ -2069,6 +2173,39 @@ _PyTokenizer_Get(struct tok_state *tok, return result; } +#if defined(__wasi__) || (defined(__EMSCRIPTEN__) && (__EMSCRIPTEN_major__ >= 3)) +// fdopen() with borrowed fd. WASI does not provide dup() and Emscripten's +// dup() emulation with open() is slow. +typedef union { + void *cookie; + int fd; +} borrowed; + +static ssize_t +borrow_read(void *cookie, char *buf, size_t size) +{ + borrowed b = {.cookie = cookie}; + return read(b.fd, (void *)buf, size); +} + +static FILE * +fdopen_borrow(int fd) { + // supports only reading. seek fails. close and write are no-ops. + cookie_io_functions_t io_cb = {borrow_read, NULL, NULL, NULL}; + borrowed b = {.fd = fd}; + return fopencookie(b.cookie, "r", io_cb); +} +#else +static FILE * +fdopen_borrow(int fd) { + fd = _Py_dup(fd); + if (fd < 0) { + return NULL; + } + return fdopen(fd, "r"); +} +#endif + /* Get the encoding of a Python file. Check for the coding cookie and check if the file starts with a BOM. @@ -2084,16 +2221,9 @@ _PyTokenizer_FindEncodingFilename(int fd, PyObject *filename) { struct tok_state *tok; FILE *fp; - const char *p_start = NULL; - const char *p_end = NULL; char *encoding = NULL; - fd = _Py_dup(fd); - if (fd < 0) { - return NULL; - } - - fp = fdopen(fd, "r"); + fp = fdopen_borrow(fd); if (fp == NULL) { return NULL; } @@ -2103,8 +2233,7 @@ _PyTokenizer_FindEncodingFilename(int fd, PyObject *filename) return NULL; } if (filename != NULL) { - Py_INCREF(filename); - tok->filename = filename; + tok->filename = Py_NewRef(filename); } else { tok->filename = PyUnicode_FromString(""); @@ -2114,8 +2243,12 @@ _PyTokenizer_FindEncodingFilename(int fd, PyObject *filename) return encoding; } } + struct token token; + // We don't want to report warnings here because it could cause infinite recursion + // if fetching the encoding shows a warning. + tok->report_warnings = 0; while (tok->lineno < 2 && tok->done == E_OK) { - _PyTokenizer_Get(tok, &p_start, &p_end); + _PyTokenizer_Get(tok, &token); } fclose(fp); if (tok->encoding) { diff --git a/Parser/tokenizer.h b/Parser/tokenizer.h index 0cb665104b2..16a94d5f51d 100644 --- a/Parser/tokenizer.h +++ b/Parser/tokenizer.h @@ -8,7 +8,7 @@ extern "C" { /* Tokenizer interface */ -#include "token.h" /* For token types */ +#include "pycore_token.h" /* For token types */ #define MAXINDENT 100 /* Max indentation level */ #define MAXLEVEL 200 /* Max parentheses level */ @@ -27,6 +27,12 @@ enum interactive_underflow_t { IUNDERFLOW_STOP, }; +struct token { + int level; + int lineno, col_offset, end_lineno, end_col_offset; + const char *start, *end; +}; + /* Tokenizer state */ struct tok_state { /* Input state; buf <= cur <= inp <= end */ @@ -51,6 +57,8 @@ struct tok_state { int lineno; /* Current line number */ int first_lineno; /* First line of a single line or multi line string expression (cf. issue 16806) */ + int starting_col_offset; /* The column offset at the beginning of a token */ + int col_offset; /* Current col offset */ int level; /* () [] {} Parentheses nesting level */ /* Used to allow free continuations inside them */ char parenstack[MAXLEVEL]; @@ -84,6 +92,10 @@ struct tok_state { NEWLINE token after it. */ /* How to proceed when asked for a new token in interactive mode */ enum interactive_underflow_t interactive_underflow; + int report_warnings; +#ifdef Py_DEBUG + int debug; +#endif }; extern struct tok_state *_PyTokenizer_FromString(const char *, int); @@ -91,7 +103,7 @@ extern struct tok_state *_PyTokenizer_FromUTF8(const char *, int); extern struct tok_state *_PyTokenizer_FromFile(FILE *, const char*, const char *, const char *); extern void _PyTokenizer_Free(struct tok_state *); -extern int _PyTokenizer_Get(struct tok_state *, const char **, const char **); +extern int _PyTokenizer_Get(struct tok_state *, struct token *); #define tok_dump _Py_tok_dump diff --git a/Programs/_bootstrap_python.c b/Programs/_bootstrap_python.c new file mode 100644 index 00000000000..6c388fc7033 --- /dev/null +++ b/Programs/_bootstrap_python.c @@ -0,0 +1,122 @@ + +/* Frozen modules bootstrap + * + * Limited and restricted Python interpreter to run + * "Tools/build/deepfreeze.py" on systems with no or older Python + * interpreter. + */ + +#include "Python.h" +#include "pycore_import.h" + +/* Includes for frozen modules: */ +#include "Python/frozen_modules/importlib._bootstrap.h" +#include "Python/frozen_modules/importlib._bootstrap_external.h" +#include "Python/frozen_modules/zipimport.h" +/* End includes */ + +uint32_t _Py_next_func_version = 1; + +/* Empty initializer for deepfrozen modules */ +int _Py_Deepfreeze_Init(void) +{ + return 0; +} +/* Empty finalizer for deepfrozen modules */ +void +_Py_Deepfreeze_Fini(void) +{ +} + +/* Note that a negative size indicates a package. */ + +static const struct _frozen bootstrap_modules[] = { + {"_frozen_importlib", _Py_M__importlib__bootstrap, (int)sizeof(_Py_M__importlib__bootstrap)}, + {"_frozen_importlib_external", _Py_M__importlib__bootstrap_external, (int)sizeof(_Py_M__importlib__bootstrap_external)}, + {"zipimport", _Py_M__zipimport, (int)sizeof(_Py_M__zipimport)}, + {0, 0, 0} /* bootstrap sentinel */ +}; +static const struct _frozen stdlib_modules[] = { + {0, 0, 0} /* stdlib sentinel */ +}; +static const struct _frozen test_modules[] = { + {0, 0, 0} /* test sentinel */ +}; +const struct _frozen *_PyImport_FrozenBootstrap = bootstrap_modules; +const struct _frozen *_PyImport_FrozenStdlib = stdlib_modules; +const struct _frozen *_PyImport_FrozenTest = test_modules; + +static const struct _module_alias aliases[] = { + {"_frozen_importlib", "importlib._bootstrap"}, + {"_frozen_importlib_external", "importlib._bootstrap_external"}, + {0, 0} /* aliases sentinel */ +}; +const struct _module_alias *_PyImport_FrozenAliases = aliases; + +/* Embedding apps may change this pointer to point to their favorite + collection of frozen modules: */ + +const struct _frozen *PyImport_FrozenModules = NULL; + +int +#ifdef MS_WINDOWS +wmain(int argc, wchar_t **argv) +#else +main(int argc, char **argv) +#endif +{ + PyStatus status; + + PyConfig config; + PyConfig_InitIsolatedConfig(&config); + // don't warn, pybuilddir.txt does not exist yet + config.pathconfig_warnings = 0; + // parse arguments + config.parse_argv = 1; + // add current script dir to sys.path + config.isolated = 0; + config.safe_path = 0; + +#ifdef MS_WINDOWS + status = PyConfig_SetArgv(&config, argc, argv); +#else + status = PyConfig_SetBytesArgv(&config, argc, argv); +#endif + if (PyStatus_Exception(status)) { + goto error; + } + + status = PyConfig_Read(&config); + if (config.run_filename == NULL) { + status = PyStatus_Error("Run filename expected"); + goto error; + } + +#define CLEAR(ATTR) \ + do { \ + PyMem_RawFree(ATTR); \ + ATTR = NULL; \ + } while (0) + + // isolate from system Python + CLEAR(config.base_prefix); + CLEAR(config.prefix); + CLEAR(config.base_exec_prefix); + CLEAR(config.exec_prefix); + + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + goto error; + } + PyConfig_Clear(&config); + + return Py_RunMain(); + +error: + PyConfig_Clear(&config); + if (PyStatus_IsExit(status)) { + return status.exitcode; + } + Py_ExitStatusException(status); +} + diff --git a/Programs/_freeze_module.c b/Programs/_freeze_module.c index e3f6c11c8b0..90fc2dc6e87 100644 --- a/Programs/_freeze_module.c +++ b/Programs/_freeze_module.c @@ -2,13 +2,17 @@ modules into frozen modules (like Lib/importlib/_bootstrap.py into Python/importlib.h). - This is used directly by Tools/scripts/freeze_modules.py, and indirectly by "make regen-frozen". + This is used directly by Tools/build/freeze_modules.py, and indirectly by "make regen-frozen". See Python/frozen.c for more info. + + Keep this file in sync with Programs/_freeze_module.py. */ + #include #include +#include "pycore_fileutils.h" // _Py_stat_struct #include #include @@ -19,6 +23,19 @@ #include #endif +uint32_t _Py_next_func_version = 1; + +/* Empty initializer for deepfrozen modules */ +int _Py_Deepfreeze_Init(void) +{ + return 0; +} +/* Empty finalizer for deepfrozen modules */ +void +_Py_Deepfreeze_Fini(void) +{ +} + /* To avoid a circular dependency on frozen.o, we create our own structure of frozen modules instead, left deliberately blank so as to avoid unintentional import of a stale version of _frozen_importlib. */ @@ -180,6 +197,7 @@ write_frozen(const char *outpath, const char *inpath, const char *name, if (ferror(outfile)) { fprintf(stderr, "error when writing to '%s'\n", outpath); + fclose(outfile); return -1; } fclose(outfile); @@ -232,3 +250,4 @@ error: Py_Finalize(); return 1; } + diff --git a/Programs/_freeze_module.py b/Programs/_freeze_module.py new file mode 100644 index 00000000000..ba638eef6c4 --- /dev/null +++ b/Programs/_freeze_module.py @@ -0,0 +1,68 @@ +"""Python implementation of Programs/_freeze_module.c + +The pure Python implementation uses same functions and arguments as the C +implementation. + +The generated byte code is slightly different because +compile() sets the PyCF_SOURCE_IS_UTF8 flag and objects have a +reference count > 1. Marshal adds the `FLAG_REF` flag and creates a +reference `hashtable`. +""" + +import marshal +import sys + +header = "/* Auto-generated by Programs/_freeze_module.py */" + + +def read_text(inpath: str) -> bytes: + with open(inpath, "rb") as f: + return f.read() + + +def compile_and_marshal(name: str, text: bytes) -> bytes: + filename = f"" + # exec == Py_file_input + code = compile(text, filename, "exec", optimize=0, dont_inherit=True) + return marshal.dumps(code) + + +def get_varname(name: str, prefix: str) -> str: + return f"{prefix}{name.replace('.', '_')}" + + +def write_code(outfile, marshalled: bytes, varname: str) -> None: + data_size = len(marshalled) + + outfile.write(f"const unsigned char {varname}[] = {{\n") + + for n in range(0, data_size, 16): + outfile.write(" ") + outfile.write(",".join(str(i) for i in marshalled[n : n + 16])) + outfile.write(",\n") + outfile.write("};\n") + + +def write_frozen(outpath: str, inpath: str, name: str, marshalled: bytes) -> None: + with open(outpath, "w") as outfile: + outfile.write(header) + outfile.write("\n") + arrayname = get_varname(name, "_Py_M__") + write_code(outfile, marshalled, arrayname) + + +def main(): + if len(sys.argv) != 4: + sys.exit("need to specify the name, input and output paths\n") + + name = sys.argv[1] + inpath = sys.argv[2] + outpath = sys.argv[3] + + text = read_text(inpath) + marshalled = compile_and_marshal(name, text) + write_frozen(outpath, inpath, name, marshalled) + + +if __name__ == "__main__": + main() diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 8077c470c07..a6ce3f7b200 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -15,16 +15,22 @@ #include // putenv() #include +int main_argc; +char **main_argv; + /********************************************************* * Embedded interpreter tests that need a custom exe * - * Executed via 'EmbeddingTests' in Lib/test/test_capi.py + * Executed via Lib/test/test_embed.py *********************************************************/ +// Use to display the usage +#define PROGRAM "test_embed" + /* Use path starting with "./" avoids a search along the PATH */ #define PROGRAM_NAME L"./_testembed" -#define INIT_LOOPS 16 +#define INIT_LOOPS 4 // Ignore Py_DEPRECATED() compiler warnings: deprecated functions are // tested on purpose here. @@ -39,10 +45,45 @@ static void error(const char *msg) } +static void config_set_string(PyConfig *config, wchar_t **config_str, const wchar_t *str) +{ + PyStatus status = PyConfig_SetString(config, config_str, str); + if (PyStatus_Exception(status)) { + PyConfig_Clear(config); + Py_ExitStatusException(status); + } +} + + +static void config_set_program_name(PyConfig *config) +{ + const wchar_t *program_name = PROGRAM_NAME; + config_set_string(config, &config->program_name, program_name); +} + + +static void init_from_config_clear(PyConfig *config) +{ + PyStatus status = Py_InitializeFromConfig(config); + PyConfig_Clear(config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } +} + + +static void _testembed_Py_InitializeFromConfig(void) +{ + PyConfig config; + _PyConfig_InitCompatConfig(&config); + config_set_program_name(&config); + init_from_config_clear(&config); +} + static void _testembed_Py_Initialize(void) { - Py_SetProgramName(PROGRAM_NAME); - Py_Initialize(); + Py_SetProgramName(PROGRAM_NAME); + Py_Initialize(); } @@ -74,7 +115,7 @@ static int test_repeated_init_and_subinterpreters(void) for (int i=1; i <= INIT_LOOPS; i++) { printf("--- Pass %d ---\n", i); - _testembed_Py_Initialize(); + _testembed_Py_InitializeFromConfig(); mainstate = PyThreadState_Get(); PyEval_ReleaseThread(mainstate); @@ -113,6 +154,53 @@ PyInit_embedded_ext(void) return PyModule_Create(&embedded_ext); } +/**************************************************************************** + * Call Py_Initialize()/Py_Finalize() multiple times and execute Python code + ***************************************************************************/ + +// Used by bpo-46417 to test that structseq types used by the sys module are +// cleared properly and initialized again properly when Python is finalized +// multiple times. +static int test_repeated_init_exec(void) +{ + if (main_argc < 3) { + fprintf(stderr, "usage: %s test_repeated_init_exec CODE\n", PROGRAM); + exit(1); + } + const char *code = main_argv[2]; + + for (int i=1; i <= INIT_LOOPS; i++) { + fprintf(stderr, "--- Loop #%d ---\n", i); + fflush(stderr); + + _testembed_Py_InitializeFromConfig(); + int err = PyRun_SimpleString(code); + Py_Finalize(); + if (err) { + return 1; + } + } + return 0; +} + +/**************************************************************************** + * Test the Py_Initialize(Ex) convenience/compatibility wrappers + ***************************************************************************/ +// This is here to help ensure there are no wrapper resource leaks (gh-96853) +static int test_repeated_simple_init(void) +{ + for (int i=1; i <= INIT_LOOPS; i++) { + fprintf(stderr, "--- Loop #%d ---\n", i); + fflush(stderr); + + _testembed_Py_Initialize(); + Py_Finalize(); + printf("Finalized\n"); // Give test_embed some output to check + } + return 0; +} + + /***************************************************** * Test forcing a particular IO encoding *****************************************************/ @@ -133,7 +221,7 @@ static void check_stdio_details(const char *encoding, const char * errors) fflush(stdout); /* Force the given IO encoding */ Py_SetStandardStreamEncoding(encoding, errors); - _testembed_Py_Initialize(); + _testembed_Py_InitializeFromConfig(); PyRun_SimpleString( "import sys;" "print('stdin: {0.encoding}:{0.errors}'.format(sys.stdin));" @@ -213,7 +301,7 @@ static int test_pre_initialization_sys_options(void) * relying on the caller to keep the passed in strings alive. */ const wchar_t *static_warnoption = L"once"; - const wchar_t *static_xoption = L"utf8=1"; + const wchar_t *static_xoption = L"also_not_an_option=2"; size_t warnoption_len = wcslen(static_warnoption); size_t xoption_len = wcslen(static_xoption); wchar_t *dynamic_once_warnoption = \ @@ -232,7 +320,7 @@ static int test_pre_initialization_sys_options(void) PySys_AddWarnOption(L"module"); PySys_AddWarnOption(L"default"); _Py_EMBED_PREINIT_CHECK("Checking PySys_AddXOption\n"); - PySys_AddXOption(L"dev=2"); + PySys_AddXOption(L"not_an_option=1"); PySys_AddXOption(dynamic_xoption); /* Delete the dynamic options early */ @@ -242,7 +330,7 @@ static int test_pre_initialization_sys_options(void) dynamic_xoption = NULL; _Py_EMBED_PREINIT_CHECK("Initializing interpreter\n"); - _testembed_Py_Initialize(); + _testembed_Py_InitializeFromConfig(); _Py_EMBED_PREINIT_CHECK("Check sys module contents\n"); PyRun_SimpleString("import sys; " "print('sys.warnoptions:', sys.warnoptions); " @@ -286,7 +374,7 @@ static int test_bpo20891(void) return 1; } - _testembed_Py_Initialize(); + _testembed_Py_InitializeFromConfig(); unsigned long thrd = PyThread_start_new_thread(bpo20891_thread, &lock); if (thrd == PYTHREAD_INVALID_THREAD_ID) { @@ -302,12 +390,14 @@ static int test_bpo20891(void) PyThread_free_lock(lock); + Py_Finalize(); + return 0; } static int test_initialize_twice(void) { - _testembed_Py_Initialize(); + _testembed_Py_InitializeFromConfig(); /* bpo-33932: Calling Py_Initialize() twice should do nothing * (and not crash!). */ @@ -325,7 +415,7 @@ static int test_initialize_pymain(void) L"print(f'Py_Main() after Py_Initialize: " L"sys.argv={sys.argv}')"), L"arg2"}; - _testembed_Py_Initialize(); + _testembed_Py_InitializeFromConfig(); /* bpo-34008: Calling Py_Main() after Py_Initialize() must not crash */ Py_Main(Py_ARRAY_LENGTH(argv), argv); @@ -348,23 +438,13 @@ dump_config(void) static int test_init_initialize_config(void) { - _testembed_Py_Initialize(); + _testembed_Py_InitializeFromConfig(); dump_config(); Py_Finalize(); return 0; } -static void config_set_string(PyConfig *config, wchar_t **config_str, const wchar_t *str) -{ - PyStatus status = PyConfig_SetString(config, config_str, str); - if (PyStatus_Exception(status)) { - PyConfig_Clear(config); - Py_ExitStatusException(status); - } -} - - static void config_set_argv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv) { PyStatus status = PyConfig_SetArgv(config, argc, argv); @@ -387,23 +467,6 @@ config_set_wide_string_list(PyConfig *config, PyWideStringList *list, } -static void config_set_program_name(PyConfig *config) -{ - const wchar_t *program_name = PROGRAM_NAME; - config_set_string(config, &config->program_name, program_name); -} - - -static void init_from_config_clear(PyConfig *config) -{ - PyStatus status = Py_InitializeFromConfig(config); - PyConfig_Clear(config); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } -} - - static int check_init_compat_config(int preinit) { PyStatus status; @@ -531,7 +594,7 @@ static int test_init_from_config(void) config.import_time = 1; putenv("PYTHONNODEBUGRANGES=0"); - config.no_debug_ranges = 1; + config.code_debug_ranges = 0; config.show_ref_count = 1; /* FIXME: test dump_refs: bpo-34223 */ @@ -550,7 +613,7 @@ static int test_init_from_config(void) L"-W", L"cmdline_warnoption", L"-X", - L"dev", + L"cmdline_xoption", L"-c", L"pass", L"arg2", @@ -558,9 +621,10 @@ static int test_init_from_config(void) config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); config.parse_argv = 1; - wchar_t* xoptions[2] = { - L"dev=3", - L"utf8", + wchar_t* xoptions[3] = { + L"config_xoption1=3", + L"config_xoption2=", + L"config_xoption3", }; config_set_wide_string_list(&config, &config.xoptions, Py_ARRAY_LENGTH(xoptions), xoptions); @@ -637,7 +701,10 @@ static int test_init_from_config(void) Py_FrozenFlag = 0; config.pathconfig_warnings = 0; - config._isolated_interpreter = 1; + config.safe_path = 1; + + putenv("PYTHONINTMAXSTRDIGITS=6666"); + config.int_max_str_digits = 31337; init_from_config_clear(&config); @@ -703,6 +770,8 @@ static void set_most_env_vars(void) putenv("PYTHONFAULTHANDLER=1"); putenv("PYTHONIOENCODING=iso8859-1:replace"); putenv("PYTHONPLATLIBDIR=env_platlibdir"); + putenv("PYTHONSAFEPATH=1"); + putenv("PYTHONINTMAXSTRDIGITS=4567"); } @@ -720,7 +789,7 @@ static int test_init_compat_env(void) /* Test initialization from environment variables */ Py_IgnoreEnvironmentFlag = 0; set_all_env_vars(); - _testembed_Py_Initialize(); + _testembed_Py_InitializeFromConfig(); dump_config(); Py_Finalize(); return 0; @@ -756,7 +825,7 @@ static int test_init_env_dev_mode(void) /* Test initialization from environment variables */ Py_IgnoreEnvironmentFlag = 0; set_all_env_vars_dev_mode(); - _testembed_Py_Initialize(); + _testembed_Py_InitializeFromConfig(); dump_config(); Py_Finalize(); return 0; @@ -769,7 +838,7 @@ static int test_init_env_dev_mode_alloc(void) Py_IgnoreEnvironmentFlag = 0; set_all_env_vars_dev_mode(); putenv("PYTHONMALLOC=malloc"); - _testembed_Py_Initialize(); + _testembed_Py_InitializeFromConfig(); dump_config(); Py_Finalize(); return 0; @@ -784,6 +853,10 @@ static int test_init_isolated_flag(void) Py_IsolatedFlag = 0; config.isolated = 1; + // These options are set to 1 by isolated=1 + config.safe_path = 0; + config.use_environment = 1; + config.user_site_directory = 1; config_set_program_name(&config); set_all_env_vars(); @@ -862,6 +935,7 @@ static int test_preinit_dont_parse_argv(void) wchar_t *argv[] = {L"python3", L"-E", L"-I", + L"-P", L"-X", L"dev", L"-X", L"utf8", L"script.py"}; @@ -895,7 +969,7 @@ static int test_preinit_parse_argv(void) /* Pre-initialize implicitly using argv: make sure that -X dev is used to configure the allocation in preinitialization */ - wchar_t *argv[] = {L"python3", L"-X", L"dev", L"script.py"}; + wchar_t *argv[] = {L"python3", L"-X", L"dev", L"-P", L"script.py"}; config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); config_set_program_name(&config); init_from_config_clear(&config); @@ -1104,7 +1178,7 @@ static int test_open_code_hook(void) } Py_IgnoreEnvironmentFlag = 0; - _testembed_Py_Initialize(); + _testembed_Py_InitializeFromConfig(); result = 0; PyObject *r = PyFile_OpenCode("$$test-filename"); @@ -1168,7 +1242,7 @@ static int _test_audit(Py_ssize_t setValue) Py_IgnoreEnvironmentFlag = 0; PySys_AddAuditHook(_audit_hook, &sawSet); - _testembed_Py_Initialize(); + _testembed_Py_InitializeFromConfig(); if (PySys_Audit("_testembed.raise", NULL) == 0) { printf("No error raised"); @@ -1224,7 +1298,7 @@ static int test_audit_subinterpreter(void) { Py_IgnoreEnvironmentFlag = 0; PySys_AddAuditHook(_audit_subinterpreter_hook, NULL); - _testembed_Py_Initialize(); + _testembed_Py_InitializeFromConfig(); Py_NewInterpreter(); Py_NewInterpreter(); @@ -1376,6 +1450,7 @@ fail: static int test_init_sys_add(void) { + PySys_AddXOption(L"sysadd_xoption"); PySys_AddXOption(L"faulthandler"); PySys_AddWarnOption(L"ignore:::sysadd_warnoption"); @@ -1387,14 +1462,14 @@ static int test_init_sys_add(void) L"-W", L"ignore:::cmdline_warnoption", L"-X", - L"utf8", + L"cmdline_xoption", }; config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); config.parse_argv = 1; PyStatus status; status = PyWideStringList_Append(&config.xoptions, - L"dev"); + L"config_xoption"); if (PyStatus_Exception(status)) { goto fail; } @@ -1503,6 +1578,46 @@ static int test_init_setpythonhome(void) } +static int test_init_is_python_build(void) +{ + // gh-91985: in-tree builds fail to check for build directory landmarks + // under the effect of 'home' or PYTHONHOME environment variable. + char *env = getenv("TESTHOME"); + if (!env) { + error("missing TESTHOME env var"); + return 1; + } + wchar_t *home = Py_DecodeLocale(env, NULL); + if (home == NULL) { + error("failed to decode TESTHOME"); + return 1; + } + + PyConfig config; + _PyConfig_InitCompatConfig(&config); + config_set_program_name(&config); + config_set_string(&config, &config.home, home); + PyMem_RawFree(home); + putenv("TESTHOME="); + + // Use an impossible value so we can detect whether it isn't updated + // during initialization. + config._is_python_build = INT_MAX; + env = getenv("NEGATIVE_ISPYTHONBUILD"); + if (env && strcmp(env, "0") != 0) { + config._is_python_build = INT_MIN; + } + init_from_config_clear(&config); + Py_Finalize(); + // Second initialization + config._is_python_build = -1; + init_from_config_clear(&config); + dump_config(); // home and _is_python_build are cached in _Py_path_config + Py_Finalize(); + return 0; +} + + static int test_init_warnoptions(void) { putenv("PYTHONWARNINGS=ignore:::env1,ignore:::env2"); @@ -1775,16 +1890,23 @@ static int test_unicode_id_init(void) { // bpo-42882: Test that _PyUnicode_FromId() works // when Python is initialized multiples times. - _Py_IDENTIFIER(test_unicode_id_init); + + // This is equivalent to `_Py_IDENTIFIER(test_unicode_id_init)` + // but since `_Py_IDENTIFIER` is disabled when `Py_BUILD_CORE` + // is defined, it is manually expanded here. + static _Py_Identifier PyId_test_unicode_id_init = { + .string = "test_unicode_id_init", + .index = -1, + }; // Initialize Python once without using the identifier - _testembed_Py_Initialize(); + _testembed_Py_InitializeFromConfig(); Py_Finalize(); // Now initialize Python multiple times and use the identifier. // The first _PyUnicode_FromId() call initializes the identifier index. for (int i=0; i<3; i++) { - _testembed_Py_Initialize(); + _testembed_Py_InitializeFromConfig(); PyObject *str1, *str2; @@ -1806,6 +1928,18 @@ static int test_unicode_id_init(void) } +static int test_init_main_interpreter_settings(void) +{ + _testembed_Py_Initialize(); + (void) PyRun_SimpleStringFlags( + "import _testinternalcapi, json; " + "print(json.dumps(_testinternalcapi.get_interp_settings(0)))", + 0); + Py_Finalize(); + return 0; +} + + #ifndef MS_WINDOWS #include "test_frozenmain.h" // M_test_frozenmain @@ -1827,26 +1961,6 @@ static int test_frozenmain(void) } #endif // !MS_WINDOWS - -// List frozen modules. -// Command used by Tools/scripts/generate_stdlib_module_names.py script. -static int list_frozen(void) -{ - const struct _frozen *p; - for (p = _PyImport_FrozenBootstrap; ; p++) { - if (p->name == NULL) - break; - printf("%s\n", p->name); - } - for (p = _PyImport_FrozenStdlib; ; p++) { - if (p->name == NULL) - break; - printf("%s\n", p->name); - } - return 0; -} - - static int test_repeated_init_and_inittab(void) { // bpo-44441: Py_RunMain() must reset PyImport_Inittab at exit. @@ -1879,6 +1993,73 @@ static int test_repeated_init_and_inittab(void) return 0; } +static void wrap_allocator(PyMemAllocatorEx *allocator); +static void unwrap_allocator(PyMemAllocatorEx *allocator); + +static void * +malloc_wrapper(void *ctx, size_t size) +{ + PyMemAllocatorEx *allocator = (PyMemAllocatorEx *)ctx; + unwrap_allocator(allocator); + PyEval_GetFrame(); // BOOM! + wrap_allocator(allocator); + return allocator->malloc(allocator->ctx, size); +} + +static void * +calloc_wrapper(void *ctx, size_t nelem, size_t elsize) +{ + PyMemAllocatorEx *allocator = (PyMemAllocatorEx *)ctx; + return allocator->calloc(allocator->ctx, nelem, elsize); +} + +static void * +realloc_wrapper(void *ctx, void *ptr, size_t new_size) +{ + PyMemAllocatorEx *allocator = (PyMemAllocatorEx *)ctx; + return allocator->realloc(allocator->ctx, ptr, new_size); +} + +static void +free_wrapper(void *ctx, void *ptr) +{ + PyMemAllocatorEx *allocator = (PyMemAllocatorEx *)ctx; + allocator->free(allocator->ctx, ptr); +} + +static void +wrap_allocator(PyMemAllocatorEx *allocator) +{ + PyMem_GetAllocator(PYMEM_DOMAIN_OBJ, allocator); + PyMemAllocatorEx wrapper = { + .malloc = &malloc_wrapper, + .calloc = &calloc_wrapper, + .realloc = &realloc_wrapper, + .free = &free_wrapper, + .ctx = allocator, + }; + PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &wrapper); +} + +static void +unwrap_allocator(PyMemAllocatorEx *allocator) +{ + PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, allocator); +} + +static int +test_get_incomplete_frame(void) +{ + _testembed_Py_InitializeFromConfig(); + PyMemAllocatorEx allocator; + wrap_allocator(&allocator); + // Force an allocation with an incomplete (generator) frame: + int result = PyRun_SimpleString("(_ for _ in ())"); + unwrap_allocator(&allocator); + Py_Finalize(); + return result; +} + /* ********************************************************* * List of test cases and the function that implements it. @@ -1900,6 +2081,8 @@ struct TestCase static struct TestCase TestCases[] = { // Python initialization + {"test_repeated_init_exec", test_repeated_init_exec}, + {"test_repeated_simple_init", test_repeated_simple_init}, {"test_forced_io_encoding", test_forced_io_encoding}, {"test_repeated_init_and_subinterpreters", test_repeated_init_and_subinterpreters}, {"test_repeated_init_and_inittab", test_repeated_init_and_inittab}, @@ -1937,12 +2120,14 @@ static struct TestCase TestCases[] = { {"test_init_setpath", test_init_setpath}, {"test_init_setpath_config", test_init_setpath_config}, {"test_init_setpythonhome", test_init_setpythonhome}, + {"test_init_is_python_build", test_init_is_python_build}, {"test_init_warnoptions", test_init_warnoptions}, {"test_init_set_config", test_init_set_config}, {"test_run_main", test_run_main}, {"test_run_main_loop", test_run_main_loop}, {"test_get_argc_argv", test_get_argc_argv}, {"test_init_use_frozen_modules", test_init_use_frozen_modules}, + {"test_init_main_interpreter_settings", test_init_main_interpreter_settings}, // Audit {"test_open_code_hook", test_open_code_hook}, @@ -1959,15 +2144,17 @@ static struct TestCase TestCases[] = { #ifndef MS_WINDOWS {"test_frozenmain", test_frozenmain}, #endif + {"test_get_incomplete_frame", test_get_incomplete_frame}, - // Command - {"list_frozen", list_frozen}, {NULL, NULL} }; int main(int argc, char *argv[]) { + main_argc = argc; + main_argv = argv; + if (argc > 1) { for (struct TestCase *tc = TestCases; tc && tc->name; tc++) { if (strcmp(argv[1], tc->name) == 0) diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index 2c789915bf5..95f78b19e65 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -1,35 +1,39 @@ // Auto-generated by Programs/freeze_test_frozenmain.py unsigned char M_test_frozenmain[] = { - 227,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0, - 0,0,0,0,0,115,86,0,0,0,100,0,100,1,108,0, - 90,0,100,0,100,1,108,1,90,1,101,2,100,2,131,1, - 1,0,101,2,100,3,101,0,106,3,131,2,1,0,101,1, - 106,4,131,0,100,4,25,0,90,5,100,5,68,0,93,14, - 90,6,101,2,100,6,101,6,155,0,100,7,101,5,101,6, - 25,0,155,0,157,4,131,1,1,0,113,26,100,1,83,0, - 41,8,233,0,0,0,0,78,122,18,70,114,111,122,101,110, - 32,72,101,108,108,111,32,87,111,114,108,100,122,8,115,121, - 115,46,97,114,103,118,218,6,99,111,110,102,105,103,41,5, - 90,12,112,114,111,103,114,97,109,95,110,97,109,101,218,10, - 101,120,101,99,117,116,97,98,108,101,90,15,117,115,101,95, - 101,110,118,105,114,111,110,109,101,110,116,90,17,99,111,110, - 102,105,103,117,114,101,95,99,95,115,116,100,105,111,90,14, - 98,117,102,102,101,114,101,100,95,115,116,100,105,111,122,7, - 99,111,110,102,105,103,32,122,2,58,32,41,7,218,3,115, - 121,115,90,17,95,116,101,115,116,105,110,116,101,114,110,97, - 108,99,97,112,105,218,5,112,114,105,110,116,218,4,97,114, - 103,118,90,11,103,101,116,95,99,111,110,102,105,103,115,114, - 2,0,0,0,218,3,107,101,121,169,0,243,0,0,0,0, - 250,18,116,101,115,116,95,102,114,111,122,101,110,109,97,105, - 110,46,112,121,218,8,60,109,111,100,117,108,101,62,114,11, - 0,0,0,1,0,0,0,115,16,0,0,0,8,3,8,1, - 8,2,12,1,12,1,8,1,26,7,4,249,115,18,0,0, - 0,8,3,8,1,8,2,12,1,12,1,2,7,4,1,2, - 249,30,7,115,86,0,0,0,1,11,1,11,1,11,1,11, - 1,25,1,25,1,25,1,25,1,6,7,27,1,28,1,28, - 1,6,7,17,19,22,19,27,1,28,1,28,10,27,10,39, - 10,41,42,50,10,51,1,7,12,2,1,42,1,42,5,8, - 5,10,11,41,21,24,11,41,11,41,28,34,35,38,28,39, - 11,41,11,41,5,42,5,42,5,42,1,42,1,42,114,9, - 0,0,0, + 227,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0, + 0,0,0,0,0,243,184,0,0,0,151,0,100,0,100,1, + 108,0,90,0,100,0,100,1,108,1,90,1,2,0,101,2, + 100,2,171,1,0,0,0,0,0,0,0,0,1,0,2,0, + 101,2,100,3,101,0,106,6,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,171,2,0,0,0,0, + 0,0,0,0,1,0,2,0,101,1,106,8,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,171,0, + 0,0,0,0,0,0,0,0,100,4,25,0,0,0,0,0, + 0,0,0,0,90,5,100,5,68,0,93,23,0,0,90,6, + 2,0,101,2,100,6,101,6,155,0,100,7,101,5,101,6, + 25,0,0,0,0,0,0,0,0,0,155,0,157,4,171,1, + 0,0,0,0,0,0,0,0,1,0,140,25,4,0,100,1, + 83,0,41,8,233,0,0,0,0,78,122,18,70,114,111,122, + 101,110,32,72,101,108,108,111,32,87,111,114,108,100,122,8, + 115,121,115,46,97,114,103,118,218,6,99,111,110,102,105,103, + 41,5,218,12,112,114,111,103,114,97,109,95,110,97,109,101, + 218,10,101,120,101,99,117,116,97,98,108,101,218,15,117,115, + 101,95,101,110,118,105,114,111,110,109,101,110,116,218,17,99, + 111,110,102,105,103,117,114,101,95,99,95,115,116,100,105,111, + 218,14,98,117,102,102,101,114,101,100,95,115,116,100,105,111, + 122,7,99,111,110,102,105,103,32,122,2,58,32,41,7,218, + 3,115,121,115,218,17,95,116,101,115,116,105,110,116,101,114, + 110,97,108,99,97,112,105,218,5,112,114,105,110,116,218,4, + 97,114,103,118,218,11,103,101,116,95,99,111,110,102,105,103, + 115,114,3,0,0,0,218,3,107,101,121,169,0,243,0,0, + 0,0,250,18,116,101,115,116,95,102,114,111,122,101,110,109, + 97,105,110,46,112,121,250,8,60,109,111,100,117,108,101,62, + 114,18,0,0,0,1,0,0,0,115,100,0,0,0,240,3, + 1,1,1,243,8,0,1,11,219,0,24,225,0,5,208,6, + 26,213,0,27,217,0,5,128,106,144,35,151,40,145,40,213, + 0,27,216,9,38,208,9,26,215,9,38,209,9,38,212,9, + 40,168,24,212,9,50,128,6,240,2,6,12,2,242,0,7, + 1,42,128,67,241,14,0,5,10,208,10,40,144,67,209,10, + 40,152,54,160,35,156,59,209,10,40,214,4,41,242,15,7, + 1,42,114,16,0,0,0, }; diff --git a/Python/Python-ast.c b/Python/Python-ast.c index ce6e6a93ea7..d113c47b953 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -2,9 +2,10 @@ #include "Python.h" #include "pycore_ast.h" -#include "pycore_ast_state.h" // struct ast_state -#include "pycore_interp.h" // _PyInterpreterState.ast -#include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_ast_state.h" // struct ast_state +#include "pycore_ceval.h" // _Py_EnterRecursiveCall +#include "pycore_interp.h" // _PyInterpreterState.ast +#include "pycore_pystate.h" // _PyInterpreterState_GET() #include "structmember.h" #include @@ -146,6 +147,7 @@ void _PyAST_Fini(PyInterpreterState *interp) Py_CLEAR(state->Sub_singleton); Py_CLEAR(state->Sub_type); Py_CLEAR(state->Subscript_type); + Py_CLEAR(state->TryStar_type); Py_CLEAR(state->Try_type); Py_CLEAR(state->Tuple_type); Py_CLEAR(state->TypeIgnore_type); @@ -261,6 +263,10 @@ void _PyAST_Fini(PyInterpreterState *interp) Py_CLEAR(state->vararg); Py_CLEAR(state->withitem_type); + if (_PyInterpreterState_Get() == _PyInterpreterState_Main()) { + Py_CLEAR(_Py_CACHED_OBJECT(str_replace_inf)); + } + #if !defined(NDEBUG) state->initialized = -1; #else @@ -486,6 +492,12 @@ static const char * const Try_fields[]={ "orelse", "finalbody", }; +static const char * const TryStar_fields[]={ + "body", + "handlers", + "orelse", + "finalbody", +}; static const char * const Assert_fields[]={ "test", "msg", @@ -985,10 +997,11 @@ static PyObject* ast2obj_list(struct ast_state *state, asdl_seq *seq, PyObject* static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), void *o) { - if (!o) - o = Py_None; - Py_INCREF((PyObject*)o); - return (PyObject*)o; + PyObject *op = (PyObject*)o; + if (!op) { + op = Py_None; + } + return Py_NewRef(op); } #define ast2obj_constant ast2obj_object #define ast2obj_identifier ast2obj_object @@ -1010,9 +1023,11 @@ static int obj2ast_object(struct ast_state *Py_UNUSED(state), PyObject* obj, PyO *out = NULL; return -1; } - Py_INCREF(obj); + *out = Py_NewRef(obj); + } + else { + *out = NULL; } - *out = obj; return 0; } @@ -1022,8 +1037,7 @@ static int obj2ast_constant(struct ast_state *Py_UNUSED(state), PyObject* obj, P *out = NULL; return -1; } - Py_INCREF(obj); - *out = obj; + *out = Py_NewRef(obj); return 0; } @@ -1139,6 +1153,7 @@ init_types(struct ast_state *state) " | Match(expr subject, match_case* cases)\n" " | Raise(expr? exc, expr? cause)\n" " | Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)\n" + " | TryStar(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)\n" " | Assert(expr test, expr? msg)\n" " | Import(alias* names)\n" " | ImportFrom(identifier? module, alias* names, int? level)\n" @@ -1254,6 +1269,10 @@ init_types(struct ast_state *state) state->Try_type = make_type(state, "Try", state->stmt_type, Try_fields, 4, "Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)"); if (!state->Try_type) return 0; + state->TryStar_type = make_type(state, "TryStar", state->stmt_type, + TryStar_fields, 4, + "TryStar(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)"); + if (!state->TryStar_type) return 0; state->Assert_type = make_type(state, "Assert", state->stmt_type, Assert_fields, 2, "Assert(expr test, expr? msg)"); @@ -1312,7 +1331,7 @@ init_types(struct ast_state *state) " | YieldFrom(expr value)\n" " | Compare(expr left, cmpop* ops, expr* comparators)\n" " | Call(expr func, expr* args, keyword* keywords)\n" - " | FormattedValue(expr value, int? conversion, expr? format_spec)\n" + " | FormattedValue(expr value, int conversion, expr? format_spec)\n" " | JoinedStr(expr* values)\n" " | Constant(constant value, string? kind)\n" " | Attribute(expr value, identifier attr, expr_context ctx)\n" @@ -1402,11 +1421,8 @@ init_types(struct ast_state *state) state->FormattedValue_type = make_type(state, "FormattedValue", state->expr_type, FormattedValue_fields, 3, - "FormattedValue(expr value, int? conversion, expr? format_spec)"); + "FormattedValue(expr value, int conversion, expr? format_spec)"); if (!state->FormattedValue_type) return 0; - if (PyObject_SetAttr(state->FormattedValue_type, state->conversion, - Py_None) == -1) - return 0; if (PyObject_SetAttr(state->FormattedValue_type, state->format_spec, Py_None) == -1) return 0; @@ -1841,6 +1857,8 @@ init_types(struct ast_state *state) "TypeIgnore(int lineno, string tag)"); if (!state->TypeIgnore_type) return 0; + state->recursion_depth = 0; + state->recursion_limit = 0; state->initialized = 1; return 1; } @@ -2379,6 +2397,28 @@ _PyAST_Try(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, return p; } +stmt_ty +_PyAST_TryStar(asdl_stmt_seq * body, asdl_excepthandler_seq * handlers, + asdl_stmt_seq * orelse, asdl_stmt_seq * finalbody, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena + *arena) +{ + stmt_ty p; + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = TryStar_kind; + p->v.TryStar.body = body; + p->v.TryStar.handlers = handlers; + p->v.TryStar.orelse = orelse; + p->v.TryStar.finalbody = finalbody; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + stmt_ty _PyAST_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) @@ -3578,6 +3618,11 @@ ast2obj_mod(struct ast_state *state, void* _o) if (!o) { Py_RETURN_NONE; } + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during ast construction"); + return 0; + } switch (o->kind) { case Module_kind: tp = (PyTypeObject *)state->Module_type; @@ -3633,6 +3678,7 @@ ast2obj_mod(struct ast_state *state, void* _o) Py_DECREF(value); break; } + state->recursion_depth--; return result; failed: Py_XDECREF(value); @@ -3649,6 +3695,11 @@ ast2obj_stmt(struct ast_state *state, void* _o) if (!o) { Py_RETURN_NONE; } + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during ast construction"); + return 0; + } switch (o->kind) { case FunctionDef_kind: tp = (PyTypeObject *)state->FunctionDef_type; @@ -4049,6 +4100,34 @@ ast2obj_stmt(struct ast_state *state, void* _o) goto failed; Py_DECREF(value); break; + case TryStar_kind: + tp = (PyTypeObject *)state->TryStar_type; + result = PyType_GenericNew(tp, NULL, NULL); + if (!result) goto failed; + value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.body, ast2obj_stmt); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->body, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.handlers, + ast2obj_excepthandler); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->handlers, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.orelse, + ast2obj_stmt); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->orelse, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.finalbody, + ast2obj_stmt); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->finalbody, value) == -1) + goto failed; + Py_DECREF(value); + break; case Assert_kind: tp = (PyTypeObject *)state->Assert_type; result = PyType_GenericNew(tp, NULL, NULL); @@ -4164,6 +4243,7 @@ ast2obj_stmt(struct ast_state *state, void* _o) if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); + state->recursion_depth--; return result; failed: Py_XDECREF(value); @@ -4180,6 +4260,11 @@ ast2obj_expr(struct ast_state *state, void* _o) if (!o) { Py_RETURN_NONE; } + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during ast construction"); + return 0; + } switch (o->kind) { case BoolOp_kind: tp = (PyTypeObject *)state->BoolOp_type; @@ -4641,6 +4726,7 @@ ast2obj_expr(struct ast_state *state, void* _o) if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); + state->recursion_depth--; return result; failed: Py_XDECREF(value); @@ -4652,14 +4738,11 @@ PyObject* ast2obj_expr_context(struct ast_state *state, expr_context_ty o) { switch(o) { case Load: - Py_INCREF(state->Load_singleton); - return state->Load_singleton; + return Py_NewRef(state->Load_singleton); case Store: - Py_INCREF(state->Store_singleton); - return state->Store_singleton; + return Py_NewRef(state->Store_singleton); case Del: - Py_INCREF(state->Del_singleton); - return state->Del_singleton; + return Py_NewRef(state->Del_singleton); } Py_UNREACHABLE(); } @@ -4667,11 +4750,9 @@ PyObject* ast2obj_boolop(struct ast_state *state, boolop_ty o) { switch(o) { case And: - Py_INCREF(state->And_singleton); - return state->And_singleton; + return Py_NewRef(state->And_singleton); case Or: - Py_INCREF(state->Or_singleton); - return state->Or_singleton; + return Py_NewRef(state->Or_singleton); } Py_UNREACHABLE(); } @@ -4679,44 +4760,31 @@ PyObject* ast2obj_operator(struct ast_state *state, operator_ty o) { switch(o) { case Add: - Py_INCREF(state->Add_singleton); - return state->Add_singleton; + return Py_NewRef(state->Add_singleton); case Sub: - Py_INCREF(state->Sub_singleton); - return state->Sub_singleton; + return Py_NewRef(state->Sub_singleton); case Mult: - Py_INCREF(state->Mult_singleton); - return state->Mult_singleton; + return Py_NewRef(state->Mult_singleton); case MatMult: - Py_INCREF(state->MatMult_singleton); - return state->MatMult_singleton; + return Py_NewRef(state->MatMult_singleton); case Div: - Py_INCREF(state->Div_singleton); - return state->Div_singleton; + return Py_NewRef(state->Div_singleton); case Mod: - Py_INCREF(state->Mod_singleton); - return state->Mod_singleton; + return Py_NewRef(state->Mod_singleton); case Pow: - Py_INCREF(state->Pow_singleton); - return state->Pow_singleton; + return Py_NewRef(state->Pow_singleton); case LShift: - Py_INCREF(state->LShift_singleton); - return state->LShift_singleton; + return Py_NewRef(state->LShift_singleton); case RShift: - Py_INCREF(state->RShift_singleton); - return state->RShift_singleton; + return Py_NewRef(state->RShift_singleton); case BitOr: - Py_INCREF(state->BitOr_singleton); - return state->BitOr_singleton; + return Py_NewRef(state->BitOr_singleton); case BitXor: - Py_INCREF(state->BitXor_singleton); - return state->BitXor_singleton; + return Py_NewRef(state->BitXor_singleton); case BitAnd: - Py_INCREF(state->BitAnd_singleton); - return state->BitAnd_singleton; + return Py_NewRef(state->BitAnd_singleton); case FloorDiv: - Py_INCREF(state->FloorDiv_singleton); - return state->FloorDiv_singleton; + return Py_NewRef(state->FloorDiv_singleton); } Py_UNREACHABLE(); } @@ -4724,17 +4792,13 @@ PyObject* ast2obj_unaryop(struct ast_state *state, unaryop_ty o) { switch(o) { case Invert: - Py_INCREF(state->Invert_singleton); - return state->Invert_singleton; + return Py_NewRef(state->Invert_singleton); case Not: - Py_INCREF(state->Not_singleton); - return state->Not_singleton; + return Py_NewRef(state->Not_singleton); case UAdd: - Py_INCREF(state->UAdd_singleton); - return state->UAdd_singleton; + return Py_NewRef(state->UAdd_singleton); case USub: - Py_INCREF(state->USub_singleton); - return state->USub_singleton; + return Py_NewRef(state->USub_singleton); } Py_UNREACHABLE(); } @@ -4742,35 +4806,25 @@ PyObject* ast2obj_cmpop(struct ast_state *state, cmpop_ty o) { switch(o) { case Eq: - Py_INCREF(state->Eq_singleton); - return state->Eq_singleton; + return Py_NewRef(state->Eq_singleton); case NotEq: - Py_INCREF(state->NotEq_singleton); - return state->NotEq_singleton; + return Py_NewRef(state->NotEq_singleton); case Lt: - Py_INCREF(state->Lt_singleton); - return state->Lt_singleton; + return Py_NewRef(state->Lt_singleton); case LtE: - Py_INCREF(state->LtE_singleton); - return state->LtE_singleton; + return Py_NewRef(state->LtE_singleton); case Gt: - Py_INCREF(state->Gt_singleton); - return state->Gt_singleton; + return Py_NewRef(state->Gt_singleton); case GtE: - Py_INCREF(state->GtE_singleton); - return state->GtE_singleton; + return Py_NewRef(state->GtE_singleton); case Is: - Py_INCREF(state->Is_singleton); - return state->Is_singleton; + return Py_NewRef(state->Is_singleton); case IsNot: - Py_INCREF(state->IsNot_singleton); - return state->IsNot_singleton; + return Py_NewRef(state->IsNot_singleton); case In: - Py_INCREF(state->In_singleton); - return state->In_singleton; + return Py_NewRef(state->In_singleton); case NotIn: - Py_INCREF(state->NotIn_singleton); - return state->NotIn_singleton; + return Py_NewRef(state->NotIn_singleton); } Py_UNREACHABLE(); } @@ -4783,6 +4837,11 @@ ast2obj_comprehension(struct ast_state *state, void* _o) if (!o) { Py_RETURN_NONE; } + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during ast construction"); + return 0; + } tp = (PyTypeObject *)state->comprehension_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; @@ -4806,6 +4865,7 @@ ast2obj_comprehension(struct ast_state *state, void* _o) if (PyObject_SetAttr(result, state->is_async, value) == -1) goto failed; Py_DECREF(value); + state->recursion_depth--; return result; failed: Py_XDECREF(value); @@ -4822,6 +4882,11 @@ ast2obj_excepthandler(struct ast_state *state, void* _o) if (!o) { Py_RETURN_NONE; } + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during ast construction"); + return 0; + } switch (o->kind) { case ExceptHandler_kind: tp = (PyTypeObject *)state->ExceptHandler_type; @@ -4865,6 +4930,7 @@ ast2obj_excepthandler(struct ast_state *state, void* _o) if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); + state->recursion_depth--; return result; failed: Py_XDECREF(value); @@ -4881,6 +4947,11 @@ ast2obj_arguments(struct ast_state *state, void* _o) if (!o) { Py_RETURN_NONE; } + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during ast construction"); + return 0; + } tp = (PyTypeObject *)state->arguments_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; @@ -4919,6 +4990,7 @@ ast2obj_arguments(struct ast_state *state, void* _o) if (PyObject_SetAttr(result, state->defaults, value) == -1) goto failed; Py_DECREF(value); + state->recursion_depth--; return result; failed: Py_XDECREF(value); @@ -4935,6 +5007,11 @@ ast2obj_arg(struct ast_state *state, void* _o) if (!o) { Py_RETURN_NONE; } + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during ast construction"); + return 0; + } tp = (PyTypeObject *)state->arg_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; @@ -4973,6 +5050,7 @@ ast2obj_arg(struct ast_state *state, void* _o) if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); + state->recursion_depth--; return result; failed: Py_XDECREF(value); @@ -4989,6 +5067,11 @@ ast2obj_keyword(struct ast_state *state, void* _o) if (!o) { Py_RETURN_NONE; } + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during ast construction"); + return 0; + } tp = (PyTypeObject *)state->keyword_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; @@ -5022,6 +5105,7 @@ ast2obj_keyword(struct ast_state *state, void* _o) if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); + state->recursion_depth--; return result; failed: Py_XDECREF(value); @@ -5038,6 +5122,11 @@ ast2obj_alias(struct ast_state *state, void* _o) if (!o) { Py_RETURN_NONE; } + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during ast construction"); + return 0; + } tp = (PyTypeObject *)state->alias_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; @@ -5071,6 +5160,7 @@ ast2obj_alias(struct ast_state *state, void* _o) if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); + state->recursion_depth--; return result; failed: Py_XDECREF(value); @@ -5087,6 +5177,11 @@ ast2obj_withitem(struct ast_state *state, void* _o) if (!o) { Py_RETURN_NONE; } + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during ast construction"); + return 0; + } tp = (PyTypeObject *)state->withitem_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; @@ -5100,6 +5195,7 @@ ast2obj_withitem(struct ast_state *state, void* _o) if (PyObject_SetAttr(result, state->optional_vars, value) == -1) goto failed; Py_DECREF(value); + state->recursion_depth--; return result; failed: Py_XDECREF(value); @@ -5116,6 +5212,11 @@ ast2obj_match_case(struct ast_state *state, void* _o) if (!o) { Py_RETURN_NONE; } + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during ast construction"); + return 0; + } tp = (PyTypeObject *)state->match_case_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; @@ -5134,6 +5235,7 @@ ast2obj_match_case(struct ast_state *state, void* _o) if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); + state->recursion_depth--; return result; failed: Py_XDECREF(value); @@ -5150,6 +5252,11 @@ ast2obj_pattern(struct ast_state *state, void* _o) if (!o) { Py_RETURN_NONE; } + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during ast construction"); + return 0; + } switch (o->kind) { case MatchValue_kind: tp = (PyTypeObject *)state->MatchValue_type; @@ -5289,6 +5396,7 @@ ast2obj_pattern(struct ast_state *state, void* _o) if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); + state->recursion_depth--; return result; failed: Py_XDECREF(value); @@ -5305,6 +5413,11 @@ ast2obj_type_ignore(struct ast_state *state, void* _o) if (!o) { Py_RETURN_NONE; } + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during ast construction"); + return 0; + } switch (o->kind) { case TypeIgnore_kind: tp = (PyTypeObject *)state->TypeIgnore_type; @@ -5322,6 +5435,7 @@ ast2obj_type_ignore(struct ast_state *state, void* _o) Py_DECREF(value); break; } + state->recursion_depth--; return result; failed: Py_XDECREF(value); @@ -5371,13 +5485,12 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Module' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Module' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -5408,13 +5521,12 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) if (type_ignores == NULL) goto failed; for (i = 0; i < len; i++) { type_ignore_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Module' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Module' node")) { goto failed; } res = obj2ast_type_ignore(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -5457,13 +5569,12 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Interactive' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Interactive' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -5495,11 +5606,11 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Expression' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Expression' node")) { goto failed; } res = obj2ast_expr(state, tmp, &body, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -5536,13 +5647,12 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) if (argtypes == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'FunctionType' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'FunctionType' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -5562,11 +5672,11 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'FunctionType' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'FunctionType' node")) { goto failed; } res = obj2ast_expr(state, tmp, &returns, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -5607,11 +5717,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'stmt' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'stmt' node")) { goto failed; } res = obj2ast_int(state, tmp, &lineno, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -5624,11 +5734,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'stmt' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'stmt' node")) { goto failed; } res = obj2ast_int(state, tmp, &col_offset, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -5637,15 +5747,15 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); - end_lineno = 0; + end_lineno = lineno; } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'stmt' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'stmt' node")) { goto failed; } res = obj2ast_int(state, tmp, &end_lineno, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -5654,15 +5764,15 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); - end_col_offset = 0; + end_col_offset = col_offset; } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'stmt' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'stmt' node")) { goto failed; } res = obj2ast_int(state, tmp, &end_col_offset, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -5688,11 +5798,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { goto failed; } res = obj2ast_identifier(state, tmp, &name, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -5705,11 +5815,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { goto failed; } res = obj2ast_arguments(state, tmp, &args, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -5733,13 +5843,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -5770,13 +5879,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (decorator_list == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -5796,11 +5904,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { goto failed; } res = obj2ast_expr(state, tmp, &returns, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -5813,11 +5921,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { goto failed; } res = obj2ast_string(state, tmp, &type_comment, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -5849,11 +5957,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { goto failed; } res = obj2ast_identifier(state, tmp, &name, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -5866,11 +5974,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { goto failed; } res = obj2ast_arguments(state, tmp, &args, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -5894,13 +6002,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -5931,13 +6038,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (decorator_list == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -5957,11 +6063,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { goto failed; } res = obj2ast_expr(state, tmp, &returns, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -5974,11 +6080,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { goto failed; } res = obj2ast_string(state, tmp, &type_comment, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6010,11 +6116,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { goto failed; } res = obj2ast_identifier(state, tmp, &name, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6038,13 +6144,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (bases == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -6075,13 +6180,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (keywords == NULL) goto failed; for (i = 0; i < len; i++) { keyword_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { goto failed; } res = obj2ast_keyword(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -6112,13 +6216,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -6149,13 +6252,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (decorator_list == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -6189,11 +6291,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Return' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Return' node")) { goto failed; } res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6230,13 +6332,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (targets == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Delete' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Delete' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -6282,13 +6383,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (targets == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Assign' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Assign' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -6308,11 +6408,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Assign' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Assign' node")) { goto failed; } res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6325,11 +6425,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Assign' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Assign' node")) { goto failed; } res = obj2ast_string(state, tmp, &type_comment, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6357,11 +6457,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'AugAssign' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'AugAssign' node")) { goto failed; } res = obj2ast_expr(state, tmp, &target, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6374,11 +6474,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'AugAssign' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'AugAssign' node")) { goto failed; } res = obj2ast_operator(state, tmp, &op, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6391,11 +6491,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'AugAssign' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'AugAssign' node")) { goto failed; } res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6424,11 +6524,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) { goto failed; } res = obj2ast_expr(state, tmp, &target, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6441,11 +6541,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) { goto failed; } res = obj2ast_expr(state, tmp, &annotation, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6458,11 +6558,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) { goto failed; } res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6475,11 +6575,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'AnnAssign' node")) { goto failed; } res = obj2ast_int(state, tmp, &simple, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6509,11 +6609,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'For' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'For' node")) { goto failed; } res = obj2ast_expr(state, tmp, &target, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6526,11 +6626,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'For' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'For' node")) { goto failed; } res = obj2ast_expr(state, tmp, &iter, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6554,13 +6654,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'For' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'For' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -6591,13 +6690,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'For' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'For' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -6617,11 +6715,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'For' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'For' node")) { goto failed; } res = obj2ast_string(state, tmp, &type_comment, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6651,11 +6749,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { goto failed; } res = obj2ast_expr(state, tmp, &target, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6668,11 +6766,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { goto failed; } res = obj2ast_expr(state, tmp, &iter, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6696,13 +6794,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -6733,13 +6830,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -6759,11 +6855,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { goto failed; } res = obj2ast_string(state, tmp, &type_comment, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6792,11 +6888,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'While' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'While' node")) { goto failed; } res = obj2ast_expr(state, tmp, &test, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6820,13 +6916,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'While' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'While' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -6857,13 +6952,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'While' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'While' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -6898,11 +6992,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'If' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'If' node")) { goto failed; } res = obj2ast_expr(state, tmp, &test, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -6926,13 +7020,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'If' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'If' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -6963,13 +7056,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'If' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'If' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -7015,13 +7107,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (items == NULL) goto failed; for (i = 0; i < len; i++) { withitem_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'With' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'With' node")) { goto failed; } res = obj2ast_withitem(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -7052,13 +7143,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'With' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'With' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -7078,11 +7168,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'With' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'With' node")) { goto failed; } res = obj2ast_string(state, tmp, &type_comment, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -7121,13 +7211,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (items == NULL) goto failed; for (i = 0; i < len; i++) { withitem_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) { goto failed; } res = obj2ast_withitem(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -7158,13 +7247,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -7184,11 +7272,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) { goto failed; } res = obj2ast_string(state, tmp, &type_comment, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -7215,11 +7303,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Match' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Match' node")) { goto failed; } res = obj2ast_expr(state, tmp, &subject, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -7243,13 +7331,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (cases == NULL) goto failed; for (i = 0; i < len; i++) { match_case_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Match' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Match' node")) { goto failed; } res = obj2ast_match_case(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -7283,11 +7370,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Raise' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Raise' node")) { goto failed; } res = obj2ast_expr(state, tmp, &exc, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -7300,11 +7387,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Raise' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Raise' node")) { goto failed; } res = obj2ast_expr(state, tmp, &cause, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -7344,13 +7431,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Try' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Try' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -7381,13 +7467,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (handlers == NULL) goto failed; for (i = 0; i < len; i++) { excepthandler_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Try' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Try' node")) { goto failed; } res = obj2ast_excepthandler(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -7418,13 +7503,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Try' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Try' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -7455,13 +7539,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (finalbody == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Try' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Try' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -7477,6 +7560,166 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (*out == NULL) goto failed; return 0; } + tp = state->TryStar_type; + isinstance = PyObject_IsInstance(obj, tp); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + asdl_stmt_seq* body; + asdl_excepthandler_seq* handlers; + asdl_stmt_seq* orelse; + asdl_stmt_seq* finalbody; + + if (_PyObject_LookupAttr(obj, state->body, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from TryStar"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "TryStar field \"body\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + body = _Py_asdl_stmt_seq_new(len, arena); + if (body == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'TryStar' node")) { + goto failed; + } + res = obj2ast_stmt(state, tmp2, &val, arena); + _Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "TryStar field \"body\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(body, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->handlers, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from TryStar"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "TryStar field \"handlers\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + handlers = _Py_asdl_excepthandler_seq_new(len, arena); + if (handlers == NULL) goto failed; + for (i = 0; i < len; i++) { + excepthandler_ty val; + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'TryStar' node")) { + goto failed; + } + res = obj2ast_excepthandler(state, tmp2, &val, arena); + _Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "TryStar field \"handlers\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(handlers, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->orelse, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from TryStar"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "TryStar field \"orelse\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + orelse = _Py_asdl_stmt_seq_new(len, arena); + if (orelse == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'TryStar' node")) { + goto failed; + } + res = obj2ast_stmt(state, tmp2, &val, arena); + _Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "TryStar field \"orelse\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(orelse, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->finalbody, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"finalbody\" missing from TryStar"); + return 1; + } + else { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "TryStar field \"finalbody\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + finalbody = _Py_asdl_stmt_seq_new(len, arena); + if (finalbody == NULL) goto failed; + for (i = 0; i < len; i++) { + stmt_ty val; + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'TryStar' node")) { + goto failed; + } + res = obj2ast_stmt(state, tmp2, &val, arena); + _Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "TryStar field \"finalbody\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(finalbody, i, val); + } + Py_CLEAR(tmp); + } + *out = _PyAST_TryStar(body, handlers, orelse, finalbody, lineno, + col_offset, end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } tp = state->Assert_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { @@ -7495,11 +7738,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Assert' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Assert' node")) { goto failed; } res = obj2ast_expr(state, tmp, &test, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -7512,11 +7755,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Assert' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Assert' node")) { goto failed; } res = obj2ast_expr(state, tmp, &msg, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -7553,13 +7796,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (names == NULL) goto failed; for (i = 0; i < len; i++) { alias_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Import' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Import' node")) { goto failed; } res = obj2ast_alias(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -7594,11 +7836,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) { goto failed; } res = obj2ast_identifier(state, tmp, &module, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -7622,13 +7864,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (names == NULL) goto failed; for (i = 0; i < len; i++) { alias_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) { goto failed; } res = obj2ast_alias(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -7648,11 +7889,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) { goto failed; } res = obj2ast_int(state, tmp, &level, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -7689,13 +7930,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (names == NULL) goto failed; for (i = 0; i < len; i++) { identifier val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Global' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Global' node")) { goto failed; } res = obj2ast_identifier(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -7739,13 +7979,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (names == NULL) goto failed; for (i = 0; i < len; i++) { identifier val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Nonlocal' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Nonlocal' node")) { goto failed; } res = obj2ast_identifier(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -7778,11 +8017,11 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Expr' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Expr' node")) { goto failed; } res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -7860,11 +8099,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'expr' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'expr' node")) { goto failed; } res = obj2ast_int(state, tmp, &lineno, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -7877,11 +8116,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'expr' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'expr' node")) { goto failed; } res = obj2ast_int(state, tmp, &col_offset, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -7890,15 +8129,15 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); - end_lineno = 0; + end_lineno = lineno; } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'expr' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'expr' node")) { goto failed; } res = obj2ast_int(state, tmp, &end_lineno, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -7907,15 +8146,15 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); - end_col_offset = 0; + end_col_offset = col_offset; } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'expr' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'expr' node")) { goto failed; } res = obj2ast_int(state, tmp, &end_col_offset, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -7937,11 +8176,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'BoolOp' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'BoolOp' node")) { goto failed; } res = obj2ast_boolop(state, tmp, &op, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -7965,13 +8204,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (values == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'BoolOp' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'BoolOp' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -8005,11 +8243,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'NamedExpr' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'NamedExpr' node")) { goto failed; } res = obj2ast_expr(state, tmp, &target, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8022,11 +8260,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'NamedExpr' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'NamedExpr' node")) { goto failed; } res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8054,11 +8292,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'BinOp' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'BinOp' node")) { goto failed; } res = obj2ast_expr(state, tmp, &left, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8071,11 +8309,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'BinOp' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'BinOp' node")) { goto failed; } res = obj2ast_operator(state, tmp, &op, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8088,11 +8326,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'BinOp' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'BinOp' node")) { goto failed; } res = obj2ast_expr(state, tmp, &right, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8119,11 +8357,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'UnaryOp' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'UnaryOp' node")) { goto failed; } res = obj2ast_unaryop(state, tmp, &op, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8136,11 +8374,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'UnaryOp' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'UnaryOp' node")) { goto failed; } res = obj2ast_expr(state, tmp, &operand, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8167,11 +8405,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Lambda' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Lambda' node")) { goto failed; } res = obj2ast_arguments(state, tmp, &args, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8184,11 +8422,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Lambda' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Lambda' node")) { goto failed; } res = obj2ast_expr(state, tmp, &body, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8216,11 +8454,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'IfExp' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'IfExp' node")) { goto failed; } res = obj2ast_expr(state, tmp, &test, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8233,11 +8471,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'IfExp' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'IfExp' node")) { goto failed; } res = obj2ast_expr(state, tmp, &body, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8250,11 +8488,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'IfExp' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'IfExp' node")) { goto failed; } res = obj2ast_expr(state, tmp, &orelse, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8292,13 +8530,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (keys == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Dict' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Dict' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -8329,13 +8566,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (values == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Dict' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Dict' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -8379,13 +8615,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (elts == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Set' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Set' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -8419,11 +8654,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'ListComp' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'ListComp' node")) { goto failed; } res = obj2ast_expr(state, tmp, &elt, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8447,13 +8682,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (generators == NULL) goto failed; for (i = 0; i < len; i++) { comprehension_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'ListComp' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'ListComp' node")) { goto failed; } res = obj2ast_comprehension(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -8487,11 +8721,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'SetComp' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'SetComp' node")) { goto failed; } res = obj2ast_expr(state, tmp, &elt, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8515,13 +8749,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (generators == NULL) goto failed; for (i = 0; i < len; i++) { comprehension_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'SetComp' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'SetComp' node")) { goto failed; } res = obj2ast_comprehension(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -8556,11 +8789,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'DictComp' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'DictComp' node")) { goto failed; } res = obj2ast_expr(state, tmp, &key, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8573,11 +8806,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'DictComp' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'DictComp' node")) { goto failed; } res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8601,13 +8834,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (generators == NULL) goto failed; for (i = 0; i < len; i++) { comprehension_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'DictComp' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'DictComp' node")) { goto failed; } res = obj2ast_comprehension(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -8641,11 +8873,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'GeneratorExp' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'GeneratorExp' node")) { goto failed; } res = obj2ast_expr(state, tmp, &elt, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8669,13 +8901,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (generators == NULL) goto failed; for (i = 0; i < len; i++) { comprehension_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'GeneratorExp' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'GeneratorExp' node")) { goto failed; } res = obj2ast_comprehension(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -8708,11 +8939,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Await' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Await' node")) { goto failed; } res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8738,11 +8969,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Yield' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Yield' node")) { goto failed; } res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8768,11 +8999,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'YieldFrom' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'YieldFrom' node")) { goto failed; } res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8800,11 +9031,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Compare' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Compare' node")) { goto failed; } res = obj2ast_expr(state, tmp, &left, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8828,13 +9059,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (ops == NULL) goto failed; for (i = 0; i < len; i++) { cmpop_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Compare' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Compare' node")) { goto failed; } res = obj2ast_cmpop(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -8865,13 +9095,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (comparators == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Compare' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Compare' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -8906,11 +9135,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Call' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Call' node")) { goto failed; } res = obj2ast_expr(state, tmp, &func, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -8934,13 +9163,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (args == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Call' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Call' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -8971,13 +9199,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (keywords == NULL) goto failed; for (i = 0; i < len; i++) { keyword_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Call' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Call' node")) { goto failed; } res = obj2ast_keyword(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -9012,28 +9239,28 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'FormattedValue' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'FormattedValue' node")) { goto failed; } res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } if (_PyObject_LookupAttr(obj, state->conversion, &tmp) < 0) { return 1; } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - conversion = 0; + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"conversion\" missing from FormattedValue"); + return 1; } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'FormattedValue' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'FormattedValue' node")) { goto failed; } res = obj2ast_int(state, tmp, &conversion, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9046,11 +9273,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'FormattedValue' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'FormattedValue' node")) { goto failed; } res = obj2ast_expr(state, tmp, &format_spec, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9088,13 +9315,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (values == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'JoinedStr' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'JoinedStr' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -9128,11 +9354,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Constant' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Constant' node")) { goto failed; } res = obj2ast_constant(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9145,11 +9371,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Constant' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Constant' node")) { goto failed; } res = obj2ast_string(state, tmp, &kind, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9177,11 +9403,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Attribute' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Attribute' node")) { goto failed; } res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9194,11 +9420,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Attribute' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Attribute' node")) { goto failed; } res = obj2ast_identifier(state, tmp, &attr, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9211,11 +9437,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Attribute' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Attribute' node")) { goto failed; } res = obj2ast_expr_context(state, tmp, &ctx, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9243,11 +9469,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Subscript' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Subscript' node")) { goto failed; } res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9260,11 +9486,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Subscript' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Subscript' node")) { goto failed; } res = obj2ast_expr(state, tmp, &slice, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9277,11 +9503,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Subscript' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Subscript' node")) { goto failed; } res = obj2ast_expr_context(state, tmp, &ctx, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9308,11 +9534,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Starred' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Starred' node")) { goto failed; } res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9325,11 +9551,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Starred' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Starred' node")) { goto failed; } res = obj2ast_expr_context(state, tmp, &ctx, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9356,11 +9582,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Name' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Name' node")) { goto failed; } res = obj2ast_identifier(state, tmp, &id, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9373,11 +9599,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Name' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Name' node")) { goto failed; } res = obj2ast_expr_context(state, tmp, &ctx, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9415,13 +9641,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (elts == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'List' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'List' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -9441,11 +9666,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'List' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'List' node")) { goto failed; } res = obj2ast_expr_context(state, tmp, &ctx, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9483,13 +9708,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (elts == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'Tuple' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'Tuple' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -9509,11 +9733,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Tuple' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Tuple' node")) { goto failed; } res = obj2ast_expr_context(state, tmp, &ctx, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9541,11 +9765,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Slice' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Slice' node")) { goto failed; } res = obj2ast_expr(state, tmp, &lower, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9558,11 +9782,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Slice' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Slice' node")) { goto failed; } res = obj2ast_expr(state, tmp, &upper, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9575,11 +9799,11 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'Slice' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'Slice' node")) { goto failed; } res = obj2ast_expr(state, tmp, &step, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9925,11 +10149,11 @@ obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'comprehension' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'comprehension' node")) { goto failed; } res = obj2ast_expr(state, tmp, &target, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9942,11 +10166,11 @@ obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'comprehension' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'comprehension' node")) { goto failed; } res = obj2ast_expr(state, tmp, &iter, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -9970,13 +10194,12 @@ obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty* if (ifs == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'comprehension' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'comprehension' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -9996,11 +10219,11 @@ obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'comprehension' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'comprehension' node")) { goto failed; } res = obj2ast_int(state, tmp, &is_async, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10037,11 +10260,11 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) { goto failed; } res = obj2ast_int(state, tmp, &lineno, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10054,11 +10277,11 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) { goto failed; } res = obj2ast_int(state, tmp, &col_offset, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10067,15 +10290,15 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); - end_lineno = 0; + end_lineno = lineno; } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) { goto failed; } res = obj2ast_int(state, tmp, &end_lineno, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10084,15 +10307,15 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); - end_col_offset = 0; + end_col_offset = col_offset; } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'excepthandler' node")) { goto failed; } res = obj2ast_int(state, tmp, &end_col_offset, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10115,11 +10338,11 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'ExceptHandler' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'ExceptHandler' node")) { goto failed; } res = obj2ast_expr(state, tmp, &type, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10132,11 +10355,11 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'ExceptHandler' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'ExceptHandler' node")) { goto failed; } res = obj2ast_identifier(state, tmp, &name, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10160,13 +10383,12 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'ExceptHandler' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'ExceptHandler' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -10222,13 +10444,12 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, if (posonlyargs == NULL) goto failed; for (i = 0; i < len; i++) { arg_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) { goto failed; } res = obj2ast_arg(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -10259,13 +10480,12 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, if (args == NULL) goto failed; for (i = 0; i < len; i++) { arg_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) { goto failed; } res = obj2ast_arg(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -10285,11 +10505,11 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) { goto failed; } res = obj2ast_arg(state, tmp, &vararg, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10313,13 +10533,12 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, if (kwonlyargs == NULL) goto failed; for (i = 0; i < len; i++) { arg_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) { goto failed; } res = obj2ast_arg(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -10350,13 +10569,12 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, if (kw_defaults == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -10376,11 +10594,11 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) { goto failed; } res = obj2ast_arg(state, tmp, &kwarg, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10404,13 +10622,12 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, if (defaults == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'arguments' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -10450,11 +10667,11 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'arg' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'arg' node")) { goto failed; } res = obj2ast_identifier(state, tmp, &arg, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10467,11 +10684,11 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'arg' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'arg' node")) { goto failed; } res = obj2ast_expr(state, tmp, &annotation, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10484,11 +10701,11 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'arg' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'arg' node")) { goto failed; } res = obj2ast_string(state, tmp, &type_comment, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10501,11 +10718,11 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'arg' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'arg' node")) { goto failed; } res = obj2ast_int(state, tmp, &lineno, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10518,11 +10735,11 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'arg' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'arg' node")) { goto failed; } res = obj2ast_int(state, tmp, &col_offset, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10531,15 +10748,15 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); - end_lineno = 0; + end_lineno = lineno; } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'arg' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'arg' node")) { goto failed; } res = obj2ast_int(state, tmp, &end_lineno, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10548,15 +10765,15 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); - end_col_offset = 0; + end_col_offset = col_offset; } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'arg' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'arg' node")) { goto failed; } res = obj2ast_int(state, tmp, &end_col_offset, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10589,11 +10806,11 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'keyword' node")) { goto failed; } res = obj2ast_identifier(state, tmp, &arg, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10606,11 +10823,11 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'keyword' node")) { goto failed; } res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10623,11 +10840,11 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'keyword' node")) { goto failed; } res = obj2ast_int(state, tmp, &lineno, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10640,11 +10857,11 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'keyword' node")) { goto failed; } res = obj2ast_int(state, tmp, &col_offset, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10653,15 +10870,15 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); - end_lineno = 0; + end_lineno = lineno; } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'keyword' node")) { goto failed; } res = obj2ast_int(state, tmp, &end_lineno, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10670,15 +10887,15 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); - end_col_offset = 0; + end_col_offset = col_offset; } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'keyword' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'keyword' node")) { goto failed; } res = obj2ast_int(state, tmp, &end_col_offset, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10711,11 +10928,11 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'alias' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'alias' node")) { goto failed; } res = obj2ast_identifier(state, tmp, &name, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10728,11 +10945,11 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'alias' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'alias' node")) { goto failed; } res = obj2ast_identifier(state, tmp, &asname, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10745,11 +10962,11 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'alias' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'alias' node")) { goto failed; } res = obj2ast_int(state, tmp, &lineno, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10762,11 +10979,11 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'alias' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'alias' node")) { goto failed; } res = obj2ast_int(state, tmp, &col_offset, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10775,15 +10992,15 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); - end_lineno = 0; + end_lineno = lineno; } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'alias' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'alias' node")) { goto failed; } res = obj2ast_int(state, tmp, &end_lineno, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10792,15 +11009,15 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* } if (tmp == NULL || tmp == Py_None) { Py_CLEAR(tmp); - end_col_offset = 0; + end_col_offset = col_offset; } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'alias' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'alias' node")) { goto failed; } res = obj2ast_int(state, tmp, &end_col_offset, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10829,11 +11046,11 @@ obj2ast_withitem(struct ast_state *state, PyObject* obj, withitem_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'withitem' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'withitem' node")) { goto failed; } res = obj2ast_expr(state, tmp, &context_expr, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10846,11 +11063,11 @@ obj2ast_withitem(struct ast_state *state, PyObject* obj, withitem_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'withitem' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'withitem' node")) { goto failed; } res = obj2ast_expr(state, tmp, &optional_vars, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10879,11 +11096,11 @@ obj2ast_match_case(struct ast_state *state, PyObject* obj, match_case_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'match_case' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'match_case' node")) { goto failed; } res = obj2ast_pattern(state, tmp, &pattern, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10896,11 +11113,11 @@ obj2ast_match_case(struct ast_state *state, PyObject* obj, match_case_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'match_case' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'match_case' node")) { goto failed; } res = obj2ast_expr(state, tmp, &guard, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10924,13 +11141,12 @@ obj2ast_match_case(struct ast_state *state, PyObject* obj, match_case_ty* out, if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'match_case' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'match_case' node")) { goto failed; } res = obj2ast_stmt(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -10974,11 +11190,11 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'pattern' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'pattern' node")) { goto failed; } res = obj2ast_int(state, tmp, &lineno, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -10991,11 +11207,11 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'pattern' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'pattern' node")) { goto failed; } res = obj2ast_int(state, tmp, &col_offset, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -11008,11 +11224,11 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'pattern' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'pattern' node")) { goto failed; } res = obj2ast_int(state, tmp, &end_lineno, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -11025,11 +11241,11 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'pattern' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'pattern' node")) { goto failed; } res = obj2ast_int(state, tmp, &end_col_offset, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -11050,11 +11266,11 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'MatchValue' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'MatchValue' node")) { goto failed; } res = obj2ast_expr(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -11080,11 +11296,11 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'MatchSingleton' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'MatchSingleton' node")) { goto failed; } res = obj2ast_constant(state, tmp, &value, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -11121,13 +11337,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, if (patterns == NULL) goto failed; for (i = 0; i < len; i++) { pattern_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'MatchSequence' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'MatchSequence' node")) { goto failed; } res = obj2ast_pattern(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -11173,13 +11388,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, if (keys == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) { goto failed; } res = obj2ast_expr(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -11210,13 +11424,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, if (patterns == NULL) goto failed; for (i = 0; i < len; i++) { pattern_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) { goto failed; } res = obj2ast_pattern(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -11236,11 +11449,11 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) { goto failed; } res = obj2ast_identifier(state, tmp, &rest, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -11269,11 +11482,11 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { goto failed; } res = obj2ast_expr(state, tmp, &cls, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -11297,13 +11510,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, if (patterns == NULL) goto failed; for (i = 0; i < len; i++) { pattern_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { goto failed; } res = obj2ast_pattern(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -11334,13 +11546,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, if (kwd_attrs == NULL) goto failed; for (i = 0; i < len; i++) { identifier val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { goto failed; } res = obj2ast_identifier(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -11371,13 +11582,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, if (kwd_patterns == NULL) goto failed; for (i = 0; i < len; i++) { pattern_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { goto failed; } res = obj2ast_pattern(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -11411,11 +11621,11 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'MatchStar' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'MatchStar' node")) { goto failed; } res = obj2ast_identifier(state, tmp, &name, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -11442,11 +11652,11 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'MatchAs' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'MatchAs' node")) { goto failed; } res = obj2ast_pattern(state, tmp, &pattern, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -11459,11 +11669,11 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'MatchAs' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'MatchAs' node")) { goto failed; } res = obj2ast_identifier(state, tmp, &name, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -11500,13 +11710,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, if (patterns == NULL) goto failed; for (i = 0; i < len; i++) { pattern_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); - if (Py_EnterRecursiveCall(" while traversing 'MatchOr' node")) { + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'MatchOr' node")) { goto failed; } res = obj2ast_pattern(state, tmp2, &val, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); Py_DECREF(tmp2); if (res != 0) goto failed; if (len != PyList_GET_SIZE(tmp)) { @@ -11560,11 +11769,11 @@ obj2ast_type_ignore(struct ast_state *state, PyObject* obj, type_ignore_ty* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'TypeIgnore' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'TypeIgnore' node")) { goto failed; } res = obj2ast_int(state, tmp, &lineno, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -11577,11 +11786,11 @@ obj2ast_type_ignore(struct ast_state *state, PyObject* obj, type_ignore_ty* } else { int res; - if (Py_EnterRecursiveCall(" while traversing 'TypeIgnore' node")) { + if (_Py_EnterRecursiveCall(" while traversing 'TypeIgnore' node")) { goto failed; } res = obj2ast_string(state, tmp, &tag, arena); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(); if (res != 0) goto failed; Py_CLEAR(tmp); } @@ -11687,6 +11896,9 @@ astmodule_exec(PyObject *m) if (PyModule_AddObjectRef(m, "Try", state->Try_type) < 0) { return -1; } + if (PyModule_AddObjectRef(m, "TryStar", state->TryStar_type) < 0) { + return -1; + } if (PyModule_AddObjectRef(m, "Assert", state->Assert_type) < 0) { return -1; } @@ -12007,7 +12219,29 @@ PyObject* PyAST_mod2obj(mod_ty t) if (state == NULL) { return NULL; } - return ast2obj_mod(state, t); + + int starting_recursion_depth; + /* Be careful here to prevent overflow. */ + int COMPILER_STACK_FRAME_SCALE = 3; + PyThreadState *tstate = _PyThreadState_GET(); + if (!tstate) { + return 0; + } + state->recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; + int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining; + starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE; + state->recursion_depth = starting_recursion_depth; + + PyObject *result = ast2obj_mod(state, t); + + /* Check that the recursion depth counting balanced correctly */ + if (result && state->recursion_depth != starting_recursion_depth) { + PyErr_Format(PyExc_SystemError, + "AST constructor recursion depth mismatch (before=%d, after=%d)", + starting_recursion_depth, state->recursion_depth); + return 0; + } + return result; } /* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */ diff --git a/Python/Python-tokenize.c b/Python/Python-tokenize.c index d3ebbe1331a..8daa9877254 100644 --- a/Python/Python-tokenize.c +++ b/Python/Python-tokenize.c @@ -13,8 +13,9 @@ get_tokenize_state(PyObject *module) { } #define _tokenize_get_state_by_type(type) \ - get_tokenize_state(_PyType_GetModuleByDef(type, &_tokenizemodule)) + get_tokenize_state(PyType_GetModuleByDef(type, &_tokenizemodule)) +#include "pycore_runtime.h" #include "clinic/Python-tokenize.c.h" /*[clinic input] @@ -59,9 +60,8 @@ tokenizeriter_new_impl(PyTypeObject *type, const char *source) static PyObject * tokenizeriter_next(tokenizeriterobject *it) { - const char *start; - const char *end; - int type = _PyTokenizer_Get(it->tok, &start, &end); + struct token token; + int type = _PyTokenizer_Get(it->tok, &token); if (type == ERRORTOKEN && PyErr_Occurred()) { return NULL; } @@ -70,11 +70,11 @@ tokenizeriter_next(tokenizeriterobject *it) return NULL; } PyObject *str = NULL; - if (start == NULL || end == NULL) { + if (token.start == NULL || token.end == NULL) { str = PyUnicode_FromString(""); } else { - str = PyUnicode_FromStringAndSize(start, end - start); + str = PyUnicode_FromStringAndSize(token.start, token.end - token.start); } if (str == NULL) { return NULL; @@ -91,11 +91,11 @@ tokenizeriter_next(tokenizeriterobject *it) int end_lineno = it->tok->lineno; int col_offset = -1; int end_col_offset = -1; - if (start != NULL && start >= line_start) { - col_offset = (int)(start - line_start); + if (token.start != NULL && token.start >= line_start) { + col_offset = (int)(token.start - line_start); } - if (end != NULL && end >= it->tok->line_start) { - end_col_offset = (int)(end - it->tok->line_start); + if (token.end != NULL && token.end >= it->tok->line_start) { + end_col_offset = (int)(token.end - it->tok->line_start); } return Py_BuildValue("(NiiiiiN)", str, type, lineno, end_lineno, col_offset, end_col_offset, line); diff --git a/Python/_warnings.c b/Python/_warnings.c index cf2110d31c3..e78f21644f3 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -4,7 +4,6 @@ #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_pyerrors.h" #include "pycore_pystate.h" // _PyThreadState_GET() -#include "frameobject.h" // PyFrame_GetBack() #include "pycore_frame.h" #include "clinic/_warnings.c.h" @@ -14,30 +13,45 @@ PyDoc_STRVAR(warnings__doc__, MODULE_NAME " provides basic warning filtering support.\n" "It is a helper module to speed up interpreter start-up."); -_Py_IDENTIFIER(stderr); -#ifndef Py_DEBUG -_Py_IDENTIFIER(default); -_Py_IDENTIFIER(ignore); -#endif - /*************************************************************************/ typedef struct _warnings_runtime_state WarningsState; -_Py_IDENTIFIER(__name__); - -/* Given a module object, get its per-module state. */ -static WarningsState * -warnings_get_state(void) +static inline int +check_interp(PyInterpreterState *interp) { - PyInterpreterState *interp = _PyInterpreterState_GET(); if (interp == NULL) { PyErr_SetString(PyExc_RuntimeError, "warnings_get_state: could not identify " "current interpreter"); + return 0; + } + return 1; +} + +static inline PyInterpreterState * +get_current_interp(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return check_interp(interp) ? interp : NULL; +} + +static inline PyThreadState * +get_current_tstate(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate == NULL) { + (void)check_interp(NULL); return NULL; } + return check_interp(tstate->interp) ? tstate : NULL; +} + +/* Given a module object, get its per-module state. */ +static WarningsState * +warnings_get_state(PyInterpreterState *interp) +{ return &interp->warnings; } @@ -52,13 +66,9 @@ warnings_clear_state(WarningsState *st) #ifndef Py_DEBUG static PyObject * -create_filter(PyObject *category, _Py_Identifier *id, const char *modname) +create_filter(PyObject *category, PyObject *action_str, const char *modname) { PyObject *modname_obj = NULL; - PyObject *action_str = _PyUnicode_FromId(id); - if (action_str == NULL) { - return NULL; - } /* Default to "no module name" for initial filter set */ if (modname != NULL) { @@ -79,7 +89,7 @@ create_filter(PyObject *category, _Py_Identifier *id, const char *modname) #endif static PyObject * -init_filters(void) +init_filters(PyInterpreterState *interp) { #ifdef Py_DEBUG /* Py_DEBUG builds show all warnings by default */ @@ -92,16 +102,15 @@ init_filters(void) } size_t pos = 0; /* Post-incremented in each use. */ - PyList_SET_ITEM(filters, pos++, - create_filter(PyExc_DeprecationWarning, &PyId_default, "__main__")); - PyList_SET_ITEM(filters, pos++, - create_filter(PyExc_DeprecationWarning, &PyId_ignore, NULL)); - PyList_SET_ITEM(filters, pos++, - create_filter(PyExc_PendingDeprecationWarning, &PyId_ignore, NULL)); - PyList_SET_ITEM(filters, pos++, - create_filter(PyExc_ImportWarning, &PyId_ignore, NULL)); - PyList_SET_ITEM(filters, pos++, - create_filter(PyExc_ResourceWarning, &PyId_ignore, NULL)); +#define ADD(TYPE, ACTION, MODNAME) \ + PyList_SET_ITEM(filters, pos++, \ + create_filter(TYPE, &_Py_ID(ACTION), MODNAME)); + ADD(PyExc_DeprecationWarning, default, "__main__"); + ADD(PyExc_DeprecationWarning, ignore, NULL); + ADD(PyExc_PendingDeprecationWarning, ignore, NULL); + ADD(PyExc_ImportWarning, ignore, NULL); + ADD(PyExc_ResourceWarning, ignore, NULL); +#undef ADD for (size_t x = 0; x < pos; x++) { if (PyList_GET_ITEM(filters, x) == NULL) { @@ -120,7 +129,7 @@ _PyWarnings_InitState(PyInterpreterState *interp) WarningsState *st = &interp->warnings; if (st->filters == NULL) { - st->filters = init_filters(); + st->filters = init_filters(interp); if (st->filters == NULL) { return -1; } @@ -148,10 +157,9 @@ _PyWarnings_InitState(PyInterpreterState *interp) /*************************************************************************/ static int -check_matched(PyObject *obj, PyObject *arg) +check_matched(PyInterpreterState *interp, PyObject *obj, PyObject *arg) { PyObject *result; - _Py_IDENTIFIER(match); int rc; /* A 'None' filter always matches */ @@ -168,7 +176,7 @@ check_matched(PyObject *obj, PyObject *arg) } /* Otherwise assume a regex filter and call its match() method */ - result = _PyObject_CallMethodIdOneArg(obj, &PyId_match, arg); + result = PyObject_CallMethodOneArg(obj, &_Py_ID(match), arg); if (result == NULL) return -1; @@ -177,25 +185,21 @@ check_matched(PyObject *obj, PyObject *arg) return rc; } +#define GET_WARNINGS_ATTR(interp, ATTR, try_import) \ + get_warnings_attr(interp, &_Py_ID(ATTR), try_import) + /* Returns a new reference. A NULL return value can mean false or an error. */ static PyObject * -get_warnings_attr(_Py_Identifier *attr_id, int try_import) +get_warnings_attr(PyInterpreterState *interp, PyObject *attr, int try_import) { - PyObject *warnings_str; PyObject *warnings_module, *obj; - _Py_IDENTIFIER(warnings); - - warnings_str = _PyUnicode_FromId(&PyId_warnings); - if (warnings_str == NULL) { - return NULL; - } /* don't try to import after the start of the Python finallization */ if (try_import && !_Py_IsFinalizing()) { - warnings_module = PyImport_Import(warnings_str); + warnings_module = PyImport_Import(&_Py_ID(warnings)); if (warnings_module == NULL) { /* Fallback to the C implementation if we cannot get the Python implementation */ @@ -210,27 +214,31 @@ get_warnings_attr(_Py_Identifier *attr_id, int try_import) gone, then we can't even use PyImport_GetModule without triggering an interpreter abort. */ - if (!_PyInterpreterState_GET()->modules) { + if (!interp->modules) { return NULL; } - warnings_module = PyImport_GetModule(warnings_str); + warnings_module = PyImport_GetModule(&_Py_ID(warnings)); if (warnings_module == NULL) return NULL; } - (void)_PyObject_LookupAttrId(warnings_module, attr_id, &obj); + (void)_PyObject_LookupAttr(warnings_module, attr, &obj); Py_DECREF(warnings_module); return obj; } static PyObject * -get_once_registry(WarningsState *st) +get_once_registry(PyInterpreterState *interp) { PyObject *registry; - _Py_IDENTIFIER(onceregistry); - registry = get_warnings_attr(&PyId_onceregistry, 0); + WarningsState *st = warnings_get_state(interp); + if (st == NULL) { + return NULL; + } + + registry = GET_WARNINGS_ATTR(interp, onceregistry, 0); if (registry == NULL) { if (PyErr_Occurred()) return NULL; @@ -251,12 +259,16 @@ get_once_registry(WarningsState *st) static PyObject * -get_default_action(WarningsState *st) +get_default_action(PyInterpreterState *interp) { PyObject *default_action; - _Py_IDENTIFIER(defaultaction); - default_action = get_warnings_attr(&PyId_defaultaction, 0); + WarningsState *st = warnings_get_state(interp); + if (st == NULL) { + return NULL; + } + + default_action = GET_WARNINGS_ATTR(interp, defaultaction, 0); if (default_action == NULL) { if (PyErr_Occurred()) { return NULL; @@ -279,19 +291,19 @@ get_default_action(WarningsState *st) /* The item is a new reference. */ static PyObject* -get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, +get_filter(PyInterpreterState *interp, PyObject *category, + PyObject *text, Py_ssize_t lineno, PyObject *module, PyObject **item) { PyObject *action; Py_ssize_t i; PyObject *warnings_filters; - _Py_IDENTIFIER(filters); - WarningsState *st = warnings_get_state(); + WarningsState *st = warnings_get_state(interp); if (st == NULL) { return NULL; } - warnings_filters = get_warnings_attr(&PyId_filters, 0); + warnings_filters = GET_WARNINGS_ATTR(interp, filters, 0); if (warnings_filters == NULL) { if (PyErr_Occurred()) return NULL; @@ -336,13 +348,13 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, return NULL; } - good_msg = check_matched(msg, text); + good_msg = check_matched(interp, msg, text); if (good_msg == -1) { Py_DECREF(tmp_item); return NULL; } - good_mod = check_matched(mod, module); + good_mod = check_matched(interp, mod, module); if (good_mod == -1) { Py_DECREF(tmp_item); return NULL; @@ -368,10 +380,9 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, Py_DECREF(tmp_item); } - action = get_default_action(st); + action = get_default_action(interp); if (action != NULL) { - Py_INCREF(Py_None); - *item = Py_None; + *item = Py_NewRef(Py_None); return action; } @@ -380,19 +391,19 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, static int -already_warned(PyObject *registry, PyObject *key, int should_set) +already_warned(PyInterpreterState *interp, PyObject *registry, PyObject *key, + int should_set) { PyObject *version_obj, *already_warned; - _Py_IDENTIFIER(version); if (key == NULL) return -1; - WarningsState *st = warnings_get_state(); + WarningsState *st = warnings_get_state(interp); if (st == NULL) { return -1; } - version_obj = _PyDict_GetItemIdWithError(registry, &PyId_version); + version_obj = _PyDict_GetItemWithError(registry, &_Py_ID(version)); if (version_obj == NULL || !PyLong_CheckExact(version_obj) || PyLong_AsLong(version_obj) != st->filters_version) @@ -404,7 +415,7 @@ already_warned(PyObject *registry, PyObject *key, int should_set) version_obj = PyLong_FromLong(st->filters_version); if (version_obj == NULL) return -1; - if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) { + if (PyDict_SetItem(registry, &_Py_ID(version), version_obj) < 0) { Py_DECREF(version_obj); return -1; } @@ -456,15 +467,14 @@ normalize_module(PyObject *filename) module = PyUnicode_Substring(filename, 0, len-3); } else { - module = filename; - Py_INCREF(module); + module = Py_NewRef(filename); } return module; } static int -update_registry(PyObject *registry, PyObject *text, PyObject *category, - int add_zero) +update_registry(PyInterpreterState *interp, PyObject *registry, PyObject *text, + PyObject *category, int add_zero) { PyObject *altkey; int rc; @@ -474,14 +484,14 @@ update_registry(PyObject *registry, PyObject *text, PyObject *category, else altkey = PyTuple_Pack(2, text, category); - rc = already_warned(registry, altkey, 1); + rc = already_warned(interp, registry, altkey, 1); Py_XDECREF(altkey); return rc; } static void -show_warning(PyObject *filename, int lineno, PyObject *text, - PyObject *category, PyObject *sourceline) +show_warning(PyThreadState *tstate, PyObject *filename, int lineno, + PyObject *text, PyObject *category, PyObject *sourceline) { PyObject *f_stderr; PyObject *name; @@ -489,12 +499,12 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno); - name = _PyObject_GetAttrId(category, &PyId___name__); + name = PyObject_GetAttr(category, &_Py_ID(__name__)); if (name == NULL) { goto error; } - f_stderr = _PySys_GetObjectId(&PyId_stderr); + f_stderr = _PySys_GetAttr(tstate, &_Py_ID(stderr)); if (f_stderr == NULL) { fprintf(stderr, "lost sys.stderr\n"); goto error; @@ -553,22 +563,22 @@ error: } static int -call_show_warning(PyObject *category, PyObject *text, PyObject *message, +call_show_warning(PyThreadState *tstate, PyObject *category, + PyObject *text, PyObject *message, PyObject *filename, int lineno, PyObject *lineno_obj, PyObject *sourceline, PyObject *source) { PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL; - _Py_IDENTIFIER(_showwarnmsg); - _Py_IDENTIFIER(WarningMessage); + PyInterpreterState *interp = tstate->interp; /* If the source parameter is set, try to get the Python implementation. The Python implementation is able to log the traceback where the source was allocated, whereas the C implementation doesn't. */ - show_fn = get_warnings_attr(&PyId__showwarnmsg, source != NULL); + show_fn = GET_WARNINGS_ATTR(interp, _showwarnmsg, source != NULL); if (show_fn == NULL) { if (PyErr_Occurred()) return -1; - show_warning(filename, lineno, text, category, sourceline); + show_warning(tstate, filename, lineno, text, category, sourceline); return 0; } @@ -578,7 +588,7 @@ call_show_warning(PyObject *category, PyObject *text, PyObject *message, goto error; } - warnmsg_cls = get_warnings_attr(&PyId_WarningMessage, 0); + warnmsg_cls = GET_WARNINGS_ATTR(interp, WarningMessage, 0); if (warnmsg_cls == NULL) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_RuntimeError, @@ -610,7 +620,7 @@ error: } static PyObject * -warn_explicit(PyObject *category, PyObject *message, +warn_explicit(PyThreadState *tstate, PyObject *category, PyObject *message, PyObject *filename, int lineno, PyObject *module, PyObject *registry, PyObject *sourceline, PyObject *source) @@ -619,6 +629,7 @@ warn_explicit(PyObject *category, PyObject *message, PyObject *item = NULL; PyObject *action; int rc; + PyInterpreterState *interp = tstate->interp; /* module can be None if a warning is emitted late during Python shutdown. In this case, the Python warnings module was probably unloaded, filters @@ -674,7 +685,7 @@ warn_explicit(PyObject *category, PyObject *message, goto cleanup; if ((registry != NULL) && (registry != Py_None)) { - rc = already_warned(registry, key, 0); + rc = already_warned(interp, registry, key, 0); if (rc == -1) goto cleanup; else if (rc == 1) @@ -682,7 +693,7 @@ warn_explicit(PyObject *category, PyObject *message, /* Else this warning hasn't been generated before. */ } - action = get_filter(category, text, lineno, module, &item); + action = get_filter(interp, category, text, lineno, module, &item); if (action == NULL) goto cleanup; @@ -707,21 +718,17 @@ warn_explicit(PyObject *category, PyObject *message, if (_PyUnicode_EqualToASCIIString(action, "once")) { if (registry == NULL || registry == Py_None) { - WarningsState *st = warnings_get_state(); - if (st == NULL) { - goto cleanup; - } - registry = get_once_registry(st); + registry = get_once_registry(interp); if (registry == NULL) goto cleanup; } /* WarningsState.once_registry[(text, category)] = 1 */ - rc = update_registry(registry, text, category, 0); + rc = update_registry(interp, registry, text, category, 0); } else if (_PyUnicode_EqualToASCIIString(action, "module")) { /* registry[(text, category, 0)] = 1 */ if (registry != NULL && registry != Py_None) - rc = update_registry(registry, text, category, 0); + rc = update_registry(interp, registry, text, category, 0); } else if (!_PyUnicode_EqualToASCIIString(action, "default")) { PyErr_Format(PyExc_RuntimeError, @@ -734,16 +741,15 @@ warn_explicit(PyObject *category, PyObject *message, if (rc == 1) /* Already warned for this module. */ goto return_none; if (rc == 0) { - if (call_show_warning(category, text, message, filename, lineno, - lineno_obj, sourceline, source) < 0) + if (call_show_warning(tstate, category, text, message, filename, + lineno, lineno_obj, sourceline, source) < 0) goto cleanup; } else /* if (rc == -1) */ goto cleanup; return_none: - result = Py_None; - Py_INCREF(result); + result = Py_NewRef(Py_None); cleanup: Py_XDECREF(item); @@ -755,108 +761,147 @@ warn_explicit(PyObject *category, PyObject *message, return result; /* Py_None or NULL. */ } -static int -is_internal_frame(PyFrameObject *frame) +static PyObject * +get_frame_filename(PyFrameObject *frame) { - static PyObject *importlib_string = NULL; - static PyObject *bootstrap_string = NULL; - int contains; - - if (importlib_string == NULL) { - importlib_string = PyUnicode_FromString("importlib"); - if (importlib_string == NULL) { - return 0; - } - - bootstrap_string = PyUnicode_FromString("_bootstrap"); - if (bootstrap_string == NULL) { - Py_DECREF(importlib_string); - return 0; - } - Py_INCREF(importlib_string); - Py_INCREF(bootstrap_string); - } - - if (frame == NULL) { - return 0; - } - PyCodeObject *code = PyFrame_GetCode(frame); PyObject *filename = code->co_filename; Py_DECREF(code); + return filename; +} - if (filename == NULL) { - return 0; - } +static bool +is_internal_filename(PyObject *filename) +{ if (!PyUnicode_Check(filename)) { - return 0; + return false; } - contains = PyUnicode_Contains(filename, importlib_string); + int contains = PyUnicode_Contains(filename, &_Py_ID(importlib)); if (contains < 0) { - return 0; + return false; } else if (contains > 0) { - contains = PyUnicode_Contains(filename, bootstrap_string); + contains = PyUnicode_Contains(filename, &_Py_ID(_bootstrap)); if (contains < 0) { - return 0; + return false; } else if (contains > 0) { - return 1; + return true; } } - return 0; + return false; +} + +static bool +is_filename_to_skip(PyObject *filename, PyTupleObject *skip_file_prefixes) +{ + if (skip_file_prefixes) { + if (!PyUnicode_Check(filename)) { + return false; + } + + Py_ssize_t prefixes = PyTuple_GET_SIZE(skip_file_prefixes); + for (Py_ssize_t idx = 0; idx < prefixes; ++idx) + { + PyObject *prefix = PyTuple_GET_ITEM(skip_file_prefixes, idx); + Py_ssize_t found = PyUnicode_Tailmatch(filename, prefix, 0, -1, -1); + if (found == 1) { + return true; + } + if (found < 0) { + return false; + } + } + } + return false; +} + +static bool +is_internal_frame(PyFrameObject *frame) +{ + if (frame == NULL) { + return false; + } + + PyObject *filename = get_frame_filename(frame); + if (filename == NULL) { + return false; + } + + return is_internal_filename(filename); } static PyFrameObject * -next_external_frame(PyFrameObject *frame) +next_external_frame(PyFrameObject *frame, PyTupleObject *skip_file_prefixes) { + PyObject *frame_filename; do { PyFrameObject *back = PyFrame_GetBack(frame); - Py_DECREF(frame); - frame = back; - } while (frame != NULL && is_internal_frame(frame)); + Py_SETREF(frame, back); + } while (frame != NULL && (frame_filename = get_frame_filename(frame)) && + (is_internal_filename(frame_filename) || + is_filename_to_skip(frame_filename, skip_file_prefixes))); return frame; } /* filename, module, and registry are new refs, globals is borrowed */ +/* skip_file_prefixes is either NULL or a tuple of strs. */ /* Returns 0 on error (no new refs), 1 on success */ static int -setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, +setup_context(Py_ssize_t stack_level, + PyTupleObject *skip_file_prefixes, + PyObject **filename, int *lineno, PyObject **module, PyObject **registry) { - _Py_IDENTIFIER(__warningregistry__); PyObject *globals; /* Setup globals, filename and lineno. */ - PyThreadState *tstate = _PyThreadState_GET(); + PyThreadState *tstate = get_current_tstate(); + if (tstate == NULL) { + return 0; + } + if (skip_file_prefixes) { + /* Type check our data structure up front. Later code that uses it + * isn't structured to report errors. */ + Py_ssize_t prefixes = PyTuple_GET_SIZE(skip_file_prefixes); + for (Py_ssize_t idx = 0; idx < prefixes; ++idx) + { + PyObject *prefix = PyTuple_GET_ITEM(skip_file_prefixes, idx); + if (!PyUnicode_Check(prefix)) { + PyErr_Format(PyExc_TypeError, + "Found non-str '%s' in skip_file_prefixes.", + Py_TYPE(prefix)->tp_name); + return 0; + } + } + } + PyInterpreterState *interp = tstate->interp; PyFrameObject *f = PyThreadState_GetFrame(tstate); // Stack level comparisons to Python code is off by one as there is no // warnings-related stack level to avoid. if (stack_level <= 0 || is_internal_frame(f)) { while (--stack_level > 0 && f != NULL) { PyFrameObject *back = PyFrame_GetBack(f); - Py_DECREF(f); - f = back; + Py_SETREF(f, back); } } else { while (--stack_level > 0 && f != NULL) { - f = next_external_frame(f); + f = next_external_frame(f, skip_file_prefixes); } } if (f == NULL) { - globals = tstate->interp->sysdict; + globals = interp->sysdict; *filename = PyUnicode_FromString("sys"); *lineno = 1; } else { globals = f->f_frame->f_globals; - *filename = f->f_frame->f_code->co_filename; - Py_INCREF(*filename); + *filename = Py_NewRef(f->f_frame->f_code->co_filename); *lineno = PyFrame_GetLineNumber(f); Py_DECREF(f); } @@ -866,7 +911,7 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, /* Setup registry. */ assert(globals != NULL); assert(PyDict_Check(globals)); - *registry = _PyDict_GetItemIdWithError(globals, &PyId___warningregistry__); + *registry = _PyDict_GetItemWithError(globals, &_Py_ID(__warningregistry__)); if (*registry == NULL) { int rc; @@ -877,7 +922,7 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, if (*registry == NULL) goto handle_error; - rc = _PyDict_SetItemId(globals, &PyId___warningregistry__, *registry); + rc = PyDict_SetItem(globals, &_Py_ID(__warningregistry__), *registry); if (rc < 0) goto handle_error; } @@ -885,7 +930,7 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, Py_INCREF(*registry); /* Setup module. */ - *module = _PyDict_GetItemIdWithError(globals, &PyId___name__); + *module = _PyDict_GetItemWithError(globals, &_Py_ID(__name__)); if (*module == Py_None || (*module != NULL && PyUnicode_Check(*module))) { Py_INCREF(*module); } @@ -938,15 +983,21 @@ get_category(PyObject *message, PyObject *category) static PyObject * do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level, - PyObject *source) + PyObject *source, PyTupleObject *skip_file_prefixes) { PyObject *filename, *module, *registry, *res; int lineno; - if (!setup_context(stack_level, &filename, &lineno, &module, ®istry)) + PyThreadState *tstate = get_current_tstate(); + if (tstate == NULL) { + return NULL; + } + + if (!setup_context(stack_level, skip_file_prefixes, + &filename, &lineno, &module, ®istry)) return NULL; - res = warn_explicit(category, message, filename, lineno, module, registry, + res = warn_explicit(tstate, category, message, filename, lineno, module, registry, NULL, source); Py_DECREF(filename); Py_DECREF(registry); @@ -958,29 +1009,48 @@ do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level, warn as warnings_warn message: object + Text of the warning message. category: object = None + The Warning category subclass. Defaults to UserWarning. stacklevel: Py_ssize_t = 1 + How far up the call stack to make this warning appear. A value of 2 for + example attributes the warning to the caller of the code calling warn(). source: object = None + If supplied, the destroyed object which emitted a ResourceWarning + * + skip_file_prefixes: object(type='PyTupleObject *', subclass_of='&PyTuple_Type') = NULL + An optional tuple of module filename prefixes indicating frames to skip + during stacklevel computations for stack frame attribution. Issue a warning, or maybe ignore it or raise an exception. [clinic start generated code]*/ static PyObject * warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category, - Py_ssize_t stacklevel, PyObject *source) -/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/ + Py_ssize_t stacklevel, PyObject *source, + PyTupleObject *skip_file_prefixes) +/*[clinic end generated code: output=a68e0f6906c65f80 input=eb37c6a18bec4ea1]*/ { category = get_category(message, category); if (category == NULL) return NULL; - return do_warn(message, category, stacklevel, source); + if (skip_file_prefixes) { + if (PyTuple_GET_SIZE(skip_file_prefixes) > 0) { + if (stacklevel < 2) { + stacklevel = 2; + } + } else { + Py_DECREF((PyObject *)skip_file_prefixes); + skip_file_prefixes = NULL; + } + } + return do_warn(message, category, stacklevel, source, skip_file_prefixes); } static PyObject * -get_source_line(PyObject *module_globals, int lineno) +get_source_line(PyInterpreterState *interp, PyObject *module_globals, int lineno) { - _Py_IDENTIFIER(get_source); - _Py_IDENTIFIER(__loader__); + PyObject *external; PyObject *loader; PyObject *module_name; PyObject *get_source; @@ -988,13 +1058,19 @@ get_source_line(PyObject *module_globals, int lineno) PyObject *source_list; PyObject *source_line; - /* Check/get the requisite pieces needed for the loader. */ - loader = _PyDict_GetItemIdWithError(module_globals, &PyId___loader__); + /* stolen from import.c */ + external = PyObject_GetAttrString(interp->importlib, "_bootstrap_external"); + if (external == NULL) { + return NULL; + } + + loader = PyObject_CallMethod(external, "_bless_my_loader", "O", module_globals, NULL); + Py_DECREF(external); if (loader == NULL) { return NULL; } - Py_INCREF(loader); - module_name = _PyDict_GetItemIdWithError(module_globals, &PyId___name__); + + module_name = _PyDict_GetItemWithError(module_globals, &_Py_ID(__name__)); if (!module_name) { Py_DECREF(loader); return NULL; @@ -1002,7 +1078,7 @@ get_source_line(PyObject *module_globals, int lineno) Py_INCREF(module_name); /* Make sure the loader implements the optional get_source() method. */ - (void)_PyObject_LookupAttrId(loader, &PyId_get_source, &get_source); + (void)_PyObject_LookupAttr(loader, &_Py_ID(get_source), &get_source); Py_DECREF(loader); if (!get_source) { Py_DECREF(module_name); @@ -1034,27 +1110,35 @@ get_source_line(PyObject *module_globals, int lineno) return source_line; } +/*[clinic input] +warn_explicit as warnings_warn_explicit + + message: object + category: object + filename: unicode + lineno: int + module as mod: object = NULL + registry: object = None + module_globals: object = None + source as sourceobj: object = None + +Issue a warning, or maybe ignore it or raise an exception. +[clinic start generated code]*/ + static PyObject * -warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) +warnings_warn_explicit_impl(PyObject *module, PyObject *message, + PyObject *category, PyObject *filename, + int lineno, PyObject *mod, PyObject *registry, + PyObject *module_globals, PyObject *sourceobj) +/*[clinic end generated code: output=c49c62b15a49a186 input=df6eeb8b45e712f1]*/ { - static char *kwd_list[] = {"message", "category", "filename", "lineno", - "module", "registry", "module_globals", - "source", 0}; - PyObject *message; - PyObject *category; - PyObject *filename; - int lineno; - PyObject *module = NULL; - PyObject *registry = NULL; - PyObject *module_globals = NULL; - PyObject *sourceobj = NULL; PyObject *source_line = NULL; PyObject *returned; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit", - kwd_list, &message, &category, &filename, &lineno, &module, - ®istry, &module_globals, &sourceobj)) + PyThreadState *tstate = get_current_tstate(); + if (tstate == NULL) { return NULL; + } if (module_globals && module_globals != Py_None) { if (!PyDict_Check(module_globals)) { @@ -1064,21 +1148,31 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) return NULL; } - source_line = get_source_line(module_globals, lineno); + source_line = get_source_line(tstate->interp, module_globals, lineno); if (source_line == NULL && PyErr_Occurred()) { return NULL; } } - returned = warn_explicit(category, message, filename, lineno, module, - registry, source_line, sourceobj); + returned = warn_explicit(tstate, category, message, filename, lineno, + mod, registry, source_line, sourceobj); Py_XDECREF(source_line); return returned; } +/*[clinic input] +_filters_mutated as warnings_filters_mutated + +[clinic start generated code]*/ + static PyObject * -warnings_filters_mutated(PyObject *self, PyObject *args) +warnings_filters_mutated_impl(PyObject *module) +/*[clinic end generated code: output=8ce517abd12b88f4 input=35ecbf08ee2491b2]*/ { - WarningsState *st = warnings_get_state(); + PyInterpreterState *interp = get_current_interp(); + if (interp == NULL) { + return NULL; + } + WarningsState *st = warnings_get_state(interp); if (st == NULL) { return NULL; } @@ -1098,7 +1192,7 @@ warn_unicode(PyObject *category, PyObject *message, if (category == NULL) category = PyExc_RuntimeWarning; - res = do_warn(message, category, stack_level, source); + res = do_warn(message, category, stack_level, source, NULL); if (res == NULL) return -1; Py_DECREF(res); @@ -1130,11 +1224,7 @@ PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, int res; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs); va_end(vargs); return res; @@ -1147,11 +1237,7 @@ _PyErr_WarnFormat(PyObject *source, PyObject *category, Py_ssize_t stack_level, int res; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif res = _PyErr_WarnFormatV(source, category, stack_level, format, vargs); va_end(vargs); return res; @@ -1164,11 +1250,7 @@ PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level, int res; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning, stack_level, format, vargs); va_end(vargs); @@ -1208,7 +1290,11 @@ PyErr_WarnExplicitObject(PyObject *category, PyObject *message, PyObject *res; if (category == NULL) category = PyExc_RuntimeWarning; - res = warn_explicit(category, message, filename, lineno, + PyThreadState *tstate = get_current_tstate(); + if (tstate == NULL) { + return -1; + } + res = warn_explicit(tstate, category, message, filename, lineno, module, registry, NULL, NULL); if (res == NULL) return -1; @@ -1264,20 +1350,19 @@ PyErr_WarnExplicitFormat(PyObject *category, goto exit; } -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif message = PyUnicode_FromFormatV(format, vargs); if (message != NULL) { PyObject *res; - res = warn_explicit(category, message, filename, lineno, - module, registry, NULL, NULL); - Py_DECREF(message); - if (res != NULL) { - Py_DECREF(res); - ret = 0; + PyThreadState *tstate = get_current_tstate(); + if (tstate != NULL) { + res = warn_explicit(tstate, category, message, filename, lineno, + module, registry, NULL, NULL); + Py_DECREF(message); + if (res != NULL) { + Py_DECREF(res); + ret = 0; + } } } va_end(vargs); @@ -1309,9 +1394,10 @@ _PyErr_WarnUnawaitedCoroutine(PyObject *coro) Since this is called from __del__ context, it's careful to never raise an exception. */ - _Py_IDENTIFIER(_warn_unawaited_coroutine); int warned = 0; - PyObject *fn = get_warnings_attr(&PyId__warn_unawaited_coroutine, 1); + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(interp != NULL); + PyObject *fn = GET_WARNINGS_ATTR(interp, _warn_unawaited_coroutine, 1); if (fn) { PyObject *res = PyObject_CallOneArg(fn, coro); Py_DECREF(fn); @@ -1334,15 +1420,10 @@ _PyErr_WarnUnawaitedCoroutine(PyObject *coro) } } -PyDoc_STRVAR(warn_explicit_doc, -"Low-level interface to warnings functionality."); - static PyMethodDef warnings_functions[] = { WARNINGS_WARN_METHODDEF - {"warn_explicit", (PyCFunction)(void(*)(void))warnings_warn_explicit, - METH_VARARGS | METH_KEYWORDS, warn_explicit_doc}, - {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS, - NULL}, + WARNINGS_WARN_EXPLICIT_METHODDEF + WARNINGS_FILTERS_MUTATED_METHODDEF /* XXX(brett.cannon): add showwarning? */ /* XXX(brett.cannon): Reasonable to add formatwarning? */ {NULL, NULL} /* sentinel */ @@ -1352,7 +1433,11 @@ static PyMethodDef warnings_functions[] = { static int warnings_module_exec(PyObject *module) { - WarningsState *st = warnings_get_state(); + PyInterpreterState *interp = get_current_interp(); + if (interp == NULL) { + return -1; + } + WarningsState *st = warnings_get_state(interp); if (st == NULL) { return -1; } diff --git a/Python/adaptive.md b/Python/adaptive.md index 81880ce8cf2..d978c089b23 100644 --- a/Python/adaptive.md +++ b/Python/adaptive.md @@ -11,30 +11,29 @@ A family of instructions has the following fundamental properties: generated by the bytecode compiler. * It has a single adaptive instruction that records an execution count and, at regular intervals, attempts to specialize itself. If not specializing, - it executes the non-adaptive instruction. + it executes the base implementation. * It has at least one specialized form of the instruction that is tailored for a particular value or set of values at runtime. -* All members of the family have access to the same number of cache entries. - Individual family members do not need to use all of the entries. +* All members of the family must have the same number of inline cache entries, + to ensure correct execution. + Individual family members do not need to use all of the entries, + but must skip over any unused entries when executing. The current implementation also requires the following, although these are not fundamental and may change: -* If a family uses one or more entries, then the first entry must be a - `_PyAdaptiveEntry` entry. -* If a family uses no cache entries, then the `oparg` is used as the - counter for the adaptive instruction. -* All instruction names should start with the name of the non-adaptive +* All families use one or more inline cache entries, + the first entry is always the counter. +* All instruction names should start with the name of the adaptive instruction. -* The adaptive instruction should end in `_ADAPTIVE`. * Specialized forms should have names describing their specialization. ## Example family -The `LOAD_GLOBAL` instruction (in Python/ceval.c) already has an adaptive +The `LOAD_GLOBAL` instruction (in Python/bytecodes.c) already has an adaptive family that serves as a relatively simple example. -The `LOAD_GLOBAL_ADAPTIVE` instruction performs adaptive specialization, +The `LOAD_GLOBAL` instruction performs adaptive specialization, calling `_Py_Specialize_LoadGlobal()` when the counter reaches zero. There are two specialized instructions in the family, `LOAD_GLOBAL_MODULE` @@ -76,6 +75,10 @@ keeping `Ti` low which means minimizing branches and dependent memory accesses (pointer chasing). These two objectives may be in conflict, requiring judgement and experimentation to design the family of instructions. +The size of the inline cache should as small as possible, +without impairing performance, to reduce the number of +`EXTENDED_ARG` jumps, and to reduce pressure on the CPU's data cache. + ### Gathering data Before choosing how to specialize an instruction, it is important to gather @@ -106,7 +109,7 @@ This can be tested quickly: * `globals->keys->dk_version == expected_version` and the operation can be performed quickly: -* `value = globals->keys->entries[index].value`. +* `value = entries[cache->index].me_value;`. Because it is impossible to measure the performance of an instruction without also measuring unrelated factors, the assessment of the quality of a @@ -119,8 +122,7 @@ base instruction. In general, specialized instructions should be implemented in two parts: 1. A sequence of guards, each of the form - `DEOPT_IF(guard-condition-is-false, BASE_NAME)`, - followed by a `record_cache_hit()`. + `DEOPT_IF(guard-condition-is-false, BASE_NAME)`. 2. The operation, which should ideally have no branches and a minimum number of dependent memory accesses. @@ -129,3 +131,11 @@ can be re-used in the operation. If there are branches in the operation, then consider further specialization to eliminate the branches. + +### Maintaining stats + +Finally, take care that stats are gather correctly. +After the last `DEOPT_IF` has passed, a hit should be recorded with +`STAT_INC(BASE_INSTRUCTION, hit)`. +After an optimization has been deferred in the adaptive instruction, +that should be recorded with `STAT_INC(BASE_INSTRUCTION, deferred)`. diff --git a/Python/asm_trampoline.S b/Python/asm_trampoline.S new file mode 100644 index 00000000000..460707717df --- /dev/null +++ b/Python/asm_trampoline.S @@ -0,0 +1,28 @@ + .text + .globl _Py_trampoline_func_start +# The following assembly is equivalent to: +# PyObject * +# trampoline(PyThreadState *ts, _PyInterpreterFrame *f, +# int throwflag, py_evaluator evaluator) +# { +# return evaluator(ts, f, throwflag); +# } +_Py_trampoline_func_start: +#ifdef __x86_64__ + sub $8, %rsp + call *%rcx + add $8, %rsp + ret +#endif // __x86_64__ +#if defined(__aarch64__) && defined(__AARCH64EL__) && !defined(__ILP32__) + // ARM64 little endian, 64bit ABI + // generate with aarch64-linux-gnu-gcc 12.1 + stp x29, x30, [sp, -16]! + mov x29, sp + blr x3 + ldp x29, x30, [sp], 16 + ret +#endif + .globl _Py_trampoline_func_end +_Py_trampoline_func_end: + .section .note.GNU-stack,"",@progbits diff --git a/Python/ast.c b/Python/ast.c index 0c3121d3ee7..50fc8e01fb3 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -22,6 +22,27 @@ static int validate_stmt(struct validator *, stmt_ty); static int validate_expr(struct validator *, expr_ty, expr_context_ty); static int validate_pattern(struct validator *, pattern_ty, int); +#define VALIDATE_POSITIONS(node) \ + if (node->lineno > node->end_lineno) { \ + PyErr_Format(PyExc_ValueError, \ + "AST node line range (%d, %d) is not valid", \ + node->lineno, node->end_lineno); \ + return 0; \ + } \ + if ((node->lineno < 0 && node->end_lineno != node->lineno) || \ + (node->col_offset < 0 && node->col_offset != node->end_col_offset)) { \ + PyErr_Format(PyExc_ValueError, \ + "AST node column range (%d, %d) for line range (%d, %d) is not valid", \ + node->col_offset, node->end_col_offset, node->lineno, node->end_lineno); \ + return 0; \ + } \ + if (node->lineno == node->end_lineno && node->col_offset > node->end_col_offset) { \ + PyErr_Format(PyExc_ValueError, \ + "line %d, column %d-%d is not a valid range", \ + node->lineno, node->col_offset, node->end_col_offset); \ + return 0; \ + } + static int validate_name(PyObject *name) { @@ -75,6 +96,7 @@ validate_args(struct validator *state, asdl_arg_seq *args) Py_ssize_t i; for (i = 0; i < asdl_seq_LEN(args); i++) { arg_ty arg = asdl_seq_GET(args, i); + VALIDATE_POSITIONS(arg); if (arg->annotation && !validate_expr(state, arg->annotation, Load)) return 0; } @@ -183,6 +205,7 @@ validate_constant(struct validator *state, PyObject *value) static int validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) { + VALIDATE_POSITIONS(exp); int ret = -1; if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, @@ -505,6 +528,7 @@ validate_capture(PyObject *name) static int validate_pattern(struct validator *state, pattern_ty p, int star_ok) { + VALIDATE_POSITIONS(p); int ret = -1; if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, @@ -674,6 +698,7 @@ validate_body(struct validator *state, asdl_stmt_seq *body, const char *owner) static int validate_stmt(struct validator *state, stmt_ty stmt) { + VALIDATE_POSITIONS(stmt); int ret = -1; Py_ssize_t i; if (++state->recursion_depth > state->recursion_limit) { @@ -807,6 +832,7 @@ validate_stmt(struct validator *state, stmt_ty stmt) } for (i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) { excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i); + VALIDATE_POSITIONS(handler); if ((handler->v.ExceptHandler.type && !validate_expr(state, handler->v.ExceptHandler.type, Load)) || !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler")) @@ -817,6 +843,31 @@ validate_stmt(struct validator *state, stmt_ty stmt) (!asdl_seq_LEN(stmt->v.Try.orelse) || validate_stmts(state, stmt->v.Try.orelse)); break; + case TryStar_kind: + if (!validate_body(state, stmt->v.TryStar.body, "TryStar")) + return 0; + if (!asdl_seq_LEN(stmt->v.TryStar.handlers) && + !asdl_seq_LEN(stmt->v.TryStar.finalbody)) { + PyErr_SetString(PyExc_ValueError, "TryStar has neither except handlers nor finalbody"); + return 0; + } + if (!asdl_seq_LEN(stmt->v.TryStar.handlers) && + asdl_seq_LEN(stmt->v.TryStar.orelse)) { + PyErr_SetString(PyExc_ValueError, "TryStar has orelse but no except handlers"); + return 0; + } + for (i = 0; i < asdl_seq_LEN(stmt->v.TryStar.handlers); i++) { + excepthandler_ty handler = asdl_seq_GET(stmt->v.TryStar.handlers, i); + if ((handler->v.ExceptHandler.type && + !validate_expr(state, handler->v.ExceptHandler.type, Load)) || + !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler")) + return 0; + } + ret = (!asdl_seq_LEN(stmt->v.TryStar.finalbody) || + validate_stmts(state, stmt->v.TryStar.finalbody)) && + (!asdl_seq_LEN(stmt->v.TryStar.orelse) || + validate_stmts(state, stmt->v.TryStar.orelse)); + break; case Assert_kind: ret = validate_expr(state, stmt->v.Assert.test, Load) && (!stmt->v.Assert.msg || validate_expr(state, stmt->v.Assert.msg, Load)); @@ -924,7 +975,6 @@ _PyAST_Validate(mod_ty mod) int res = -1; struct validator state; PyThreadState *tstate; - int recursion_limit = Py_GetRecursionLimit(); int starting_recursion_depth; /* Setup recursion depth check counters */ @@ -933,12 +983,10 @@ _PyAST_Validate(mod_ty mod) return 0; } /* Be careful here to prevent overflow. */ - int recursion_depth = tstate->recursion_limit - tstate->recursion_remaining; - starting_recursion_depth = (recursion_depth< INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_depth * COMPILER_STACK_FRAME_SCALE : recursion_depth; + int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining; + starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE; state.recursion_depth = starting_recursion_depth; - state.recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit; + state.recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; switch (mod->kind) { case Module_kind: diff --git a/Python/ast_opt.c b/Python/ast_opt.c index 356f60e2d53..1a0b2a05b1c 100644 --- a/Python/ast_opt.c +++ b/Python/ast_opt.c @@ -268,15 +268,10 @@ parse_literal(PyObject *fmt, Py_ssize_t *ppos, PyArena *arena) PyObject *str = PyUnicode_Substring(fmt, start, pos); /* str = str.replace('%%', '%') */ if (str && has_percents) { - _Py_static_string(PyId_double_percent, "%%"); - _Py_static_string(PyId_percent, "%"); - PyObject *double_percent = _PyUnicode_FromId(&PyId_double_percent); - PyObject *percent = _PyUnicode_FromId(&PyId_percent); - if (!double_percent || !percent) { - Py_DECREF(str); - return NULL; - } - Py_SETREF(str, PyUnicode_Replace(str, double_percent, percent, -1)); + _Py_DECLARE_STR(percent, "%"); + _Py_DECLARE_STR(dbl_percent, "%%"); + Py_SETREF(str, PyUnicode_Replace(str, &_Py_STR(dbl_percent), + &_Py_STR(percent), -1)); } if (!str) { return NULL; @@ -315,6 +310,7 @@ simple_format_arg_parse(PyObject *fmt, Py_ssize_t *ppos, case ' ': *flags |= F_BLANK; continue; case '#': *flags |= F_ALT; continue; case '0': *flags |= F_ZERO; continue; + case 'z': *flags |= F_NO_NEG_0; continue; } break; } @@ -537,8 +533,7 @@ make_const_tuple(asdl_expr_seq *elts) for (int i = 0; i < asdl_seq_LEN(elts); i++) { expr_ty e = (expr_ty)asdl_seq_GET(elts, i); PyObject *v = e->v.Constant.value; - Py_INCREF(v); - PyTuple_SET_ITEM(newval, i, v); + PyTuple_SET_ITEM(newval, i, Py_NewRef(v)); } return newval; } @@ -618,7 +613,6 @@ fold_compare(expr_ty node, PyArena *arena, _PyASTOptimizeState *state) ops = node->v.Compare.ops; args = node->v.Compare.comparators; - /* TODO: optimize cases with literal arguments. */ /* Change literal list or set in 'in' or 'not in' into tuple or frozenset respectively. */ i = asdl_seq_LEN(ops) - 1; @@ -661,15 +655,6 @@ static int astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState } \ } -#define CALL_INT_SEQ(FUNC, TYPE, ARG) { \ - int i; \ - asdl_int_seq *seq = (ARG); /* avoid variable capture */ \ - for (i = 0; i < asdl_seq_LEN(seq); i++) { \ - TYPE elt = (TYPE)asdl_seq_GET(seq, i); \ - if (!FUNC(elt, ctx_, state)) \ - return 0; \ - } \ -} static int astfold_body(asdl_stmt_seq *stmts, PyArena *ctx_, _PyASTOptimizeState *state) @@ -973,6 +958,12 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) CALL_SEQ(astfold_stmt, stmt, node_->v.Try.orelse); CALL_SEQ(astfold_stmt, stmt, node_->v.Try.finalbody); break; + case TryStar_kind: + CALL_SEQ(astfold_stmt, stmt, node_->v.TryStar.body); + CALL_SEQ(astfold_excepthandler, excepthandler, node_->v.TryStar.handlers); + CALL_SEQ(astfold_stmt, stmt, node_->v.TryStar.orelse); + CALL_SEQ(astfold_stmt, stmt, node_->v.TryStar.finalbody); + break; case Assert_kind: CALL(astfold_expr, expr_ty, node_->v.Assert.test); CALL_OPT(astfold_expr, expr_ty, node_->v.Assert.msg); @@ -1080,7 +1071,6 @@ astfold_match_case(match_case_ty node_, PyArena *ctx_, _PyASTOptimizeState *stat #undef CALL #undef CALL_OPT #undef CALL_SEQ -#undef CALL_INT_SEQ /* See comments in symtable.c. */ #define COMPILER_STACK_FRAME_SCALE 3 @@ -1089,7 +1079,6 @@ int _PyAST_Optimize(mod_ty mod, PyArena *arena, _PyASTOptimizeState *state) { PyThreadState *tstate; - int recursion_limit = Py_GetRecursionLimit(); int starting_recursion_depth; /* Setup recursion depth check counters */ @@ -1098,12 +1087,10 @@ _PyAST_Optimize(mod_ty mod, PyArena *arena, _PyASTOptimizeState *state) return 0; } /* Be careful here to prevent overflow. */ - int recursion_depth = tstate->recursion_limit - tstate->recursion_remaining; - starting_recursion_depth = (recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_depth * COMPILER_STACK_FRAME_SCALE : recursion_depth; + int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining; + starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE; state->recursion_depth = starting_recursion_depth; - state->recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit; + state->recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; int ret = astfold_mod(mod, arena, state); assert(ret || PyErr_Occurred()); diff --git a/Python/ast_unparse.c b/Python/ast_unparse.c index 126e9047d58..79b2e2f15ba 100644 --- a/Python/ast_unparse.c +++ b/Python/ast_unparse.c @@ -1,5 +1,6 @@ #include "Python.h" #include "pycore_ast.h" // expr_ty +#include "pycore_runtime.h" // _Py_ID() #include // DBL_MAX_10_EXP #include @@ -8,12 +9,11 @@ * See ast.unparse for a full unparser (written in Python) */ -static PyObject *_str_open_br; -static PyObject *_str_dbl_open_br; -static PyObject *_str_close_br; -static PyObject *_str_dbl_close_br; -static PyObject *_str_inf; -static PyObject *_str_replace_inf; +_Py_DECLARE_STR(open_br, "{"); +_Py_DECLARE_STR(dbl_open_br, "{{"); +_Py_DECLARE_STR(close_br, "}"); +_Py_DECLARE_STR(dbl_close_br, "}}"); +#define _str_replace_inf _Py_CACHED_OBJECT(str_replace_inf) /* Forward declarations for recursion via helper functions. */ static PyObject * @@ -80,7 +80,7 @@ append_repr(_PyUnicodeWriter *writer, PyObject *obj) { PyObject *new_repr = PyUnicode_Replace( repr, - _str_inf, + &_Py_ID(inf), _str_replace_inf, -1 ); @@ -575,11 +575,11 @@ escape_braces(PyObject *orig) { PyObject *temp; PyObject *result; - temp = PyUnicode_Replace(orig, _str_open_br, _str_dbl_open_br, -1); + temp = PyUnicode_Replace(orig, &_Py_STR(open_br), &_Py_STR(dbl_open_br), -1); if (!temp) { return NULL; } - result = PyUnicode_Replace(temp, _str_close_br, _str_dbl_close_br, -1); + result = PyUnicode_Replace(temp, &_Py_STR(close_br), &_Py_STR(dbl_close_br), -1); Py_DECREF(temp); return result; } @@ -673,7 +673,7 @@ append_formattedvalue(_PyUnicodeWriter *writer, expr_ty e) if (!temp_fv_str) { return -1; } - if (PyUnicode_Find(temp_fv_str, _str_open_br, 0, 1, 1) == 0) { + if (PyUnicode_Find(temp_fv_str, &_Py_STR(open_br), 0, 1, 1) == 0) { /* Expression starts with a brace, split it with a space from the outer one. */ outer_brace = "{ "; @@ -786,19 +786,8 @@ static int append_ast_subscript(_PyUnicodeWriter *writer, expr_ty e) { APPEND_EXPR(e->v.Subscript.value, PR_ATOM); - int level = PR_TUPLE; - expr_ty slice = e->v.Subscript.slice; - if (slice->kind == Tuple_kind) { - for (Py_ssize_t i = 0; i < asdl_seq_LEN(slice->v.Tuple.elts); i++) { - expr_ty element = asdl_seq_GET(slice->v.Tuple.elts, i); - if (element->kind == Starred_kind) { - ++level; - break; - } - } - } APPEND_STR("["); - APPEND_EXPR(e->v.Subscript.slice, level); + APPEND_EXPR(e->v.Subscript.slice, PR_TUPLE); APPEND_STR_FINISH("]"); } @@ -927,26 +916,6 @@ append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level) static int maybe_init_static_strings(void) { - if (!_str_open_br && - !(_str_open_br = PyUnicode_InternFromString("{"))) { - return -1; - } - if (!_str_dbl_open_br && - !(_str_dbl_open_br = PyUnicode_InternFromString("{{"))) { - return -1; - } - if (!_str_close_br && - !(_str_close_br = PyUnicode_InternFromString("}"))) { - return -1; - } - if (!_str_dbl_close_br && - !(_str_dbl_close_br = PyUnicode_InternFromString("}}"))) { - return -1; - } - if (!_str_inf && - !(_str_inf = PyUnicode_FromString("inf"))) { - return -1; - } if (!_str_replace_inf && !(_str_replace_inf = PyUnicode_FromFormat("1e%d", 1 + DBL_MAX_10_EXP))) { return -1; diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 9e3b25c59a5..f97dd67269a 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -11,21 +11,6 @@ #include "pycore_tuple.h" // _PyTuple_FromArray() #include "pycore_ceval.h" // _PyEval_Vector() -_Py_IDENTIFIER(__builtins__); -_Py_IDENTIFIER(__dict__); -_Py_IDENTIFIER(__prepare__); -_Py_IDENTIFIER(__round__); -_Py_IDENTIFIER(__mro_entries__); -_Py_IDENTIFIER(encoding); -_Py_IDENTIFIER(errors); -_Py_IDENTIFIER(fileno); -_Py_IDENTIFIER(flush); -_Py_IDENTIFIER(metaclass); -_Py_IDENTIFIER(sort); -_Py_IDENTIFIER(stdin); -_Py_IDENTIFIER(stdout); -_Py_IDENTIFIER(stderr); - #include "clinic/bltinmodule.c.h" static PyObject* @@ -47,7 +32,7 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs) } continue; } - if (_PyObject_LookupAttrId(base, &PyId___mro_entries__, &meth) < 0) { + if (_PyObject_LookupAttr(base, &_Py_ID(__mro_entries__), &meth) < 0) { goto error; } if (!meth) { @@ -78,8 +63,7 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs) } for (j = 0; j < i; j++) { base = args[j]; - PyList_SET_ITEM(new_bases, j, base); - Py_INCREF(base); + PyList_SET_ITEM(new_bases, j, Py_NewRef(base)); } } j = PyList_GET_SIZE(new_bases); @@ -148,10 +132,10 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, goto error; } - meta = _PyDict_GetItemIdWithError(mkw, &PyId_metaclass); + meta = _PyDict_GetItemWithError(mkw, &_Py_ID(metaclass)); if (meta != NULL) { Py_INCREF(meta); - if (_PyDict_DelItemId(mkw, &PyId_metaclass) < 0) { + if (PyDict_DelItem(mkw, &_Py_ID(metaclass)) < 0) { goto error; } /* metaclass is explicitly given, check if it's indeed a class */ @@ -184,14 +168,12 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, goto error; } if (winner != meta) { - Py_DECREF(meta); - meta = winner; - Py_INCREF(meta); + Py_SETREF(meta, Py_NewRef(winner)); } } /* else: meta is not a class, so we cannot do the metaclass calculation, so we will use the explicitly given object as it is */ - if (_PyObject_LookupAttrId(meta, &PyId___prepare__, &prep) < 0) { + if (_PyObject_LookupAttr(meta, &_Py_ID(__prepare__), &prep) < 0) { ns = NULL; } else if (prep == NULL) { @@ -212,9 +194,9 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, Py_TYPE(ns)->tp_name); goto error; } - PyFrameConstructor *f = PyFunction_AS_FRAME_CONSTRUCTOR(func); PyThreadState *tstate = _PyThreadState_GET(); - cell = _PyEval_Vector(tstate, f, ns, NULL, 0, NULL); + EVAL_CALL_STAT_INC(EVAL_CALL_BUILD_CLASS); + cell = _PyEval_Vector(tstate, (PyFunctionObject *)func, ns, NULL, 0, NULL); if (cell != NULL) { if (bases != orig_bases) { if (PyMapping_SetItemString(ns, "__orig_bases__", orig_bases) < 0) { @@ -236,8 +218,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, "__class__ set to %.200R defining %.200R as %.200R"; PyErr_Format(PyExc_TypeError, msg, cell_cls, name, cls); } - Py_DECREF(cls); - cls = NULL; + Py_SETREF(cls, NULL); goto error; } } @@ -259,38 +240,41 @@ PyDoc_STRVAR(build_class_doc, \n\ Internal helper function used by the class statement."); -static PyObject * -builtin___import__(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"name", "globals", "locals", "fromlist", - "level", 0}; - PyObject *name, *globals = NULL, *locals = NULL, *fromlist = NULL; - int level = 0; +/*[clinic input] +__import__ as builtin___import__ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "U|OOOi:__import__", - kwlist, &name, &globals, &locals, &fromlist, &level)) - return NULL; + name: object + globals: object(c_default="NULL") = None + locals: object(c_default="NULL") = None + fromlist: object(c_default="NULL") = () + level: int = 0 + +Import a module. + +Because this function is meant for use by the Python +interpreter and not for general use, it is better to use +importlib.import_module() to programmatically import a module. + +The globals argument is only used to determine the context; +they are not modified. The locals argument is unused. The fromlist +should be a list of names to emulate ``from name import ...``, or an +empty list to emulate ``import name``. +When importing a module from a package, note that __import__('A.B', ...) +returns package A when fromlist is empty, but its submodule B when +fromlist is not empty. The level argument is used to determine whether to +perform absolute or relative imports: 0 is absolute, while a positive number +is the number of parent directories to search relative to the current module. +[clinic start generated code]*/ + +static PyObject * +builtin___import___impl(PyObject *module, PyObject *name, PyObject *globals, + PyObject *locals, PyObject *fromlist, int level) +/*[clinic end generated code: output=4febeda88a0cd245 input=73f4b960ea5b9dd6]*/ +{ return PyImport_ImportModuleLevelObject(name, globals, locals, fromlist, level); } -PyDoc_STRVAR(import_doc, -"__import__(name, globals=None, locals=None, fromlist=(), level=0) -> module\n\ -\n\ -Import a module. Because this function is meant for use by the Python\n\ -interpreter and not for general use, it is better to use\n\ -importlib.import_module() to programmatically import a module.\n\ -\n\ -The globals argument is only used to determine the context;\n\ -they are not modified. The locals argument is unused. The fromlist\n\ -should be a list of names to emulate ``from name import ...'', or an\n\ -empty list to emulate ``import name''.\n\ -When importing a module from a package, note that __import__('A.B', ...)\n\ -returns package A when fromlist is empty, but its submodule B when\n\ -fromlist is not empty. The level argument is used to determine whether to\n\ -perform absolute or relative imports: 0 is absolute, while a positive number\n\ -is the number of parent directories to search relative to the current module."); - /*[clinic input] abs as builtin_abs @@ -537,7 +521,7 @@ static PyObject * filter_vectorcall(PyObject *type, PyObject * const*args, size_t nargsf, PyObject *kwnames) { - PyTypeObject *tp = (PyTypeObject *)type; + PyTypeObject *tp = _PyType_CAST(type); if (tp == &PyFilter_Type && !_PyArg_NoKwnames("filter", kwnames)) { return NULL; } @@ -626,7 +610,7 @@ filter_reduce(filterobject *lz, PyObject *Py_UNUSED(ignored)) PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); static PyMethodDef filter_methods[] = { - {"__reduce__", (PyCFunction)filter_reduce, METH_NOARGS, reduce_doc}, + {"__reduce__", _PyCFunction_CAST(filter_reduce), METH_NOARGS, reduce_doc}, {NULL, NULL} /* sentinel */ }; @@ -689,16 +673,19 @@ format as builtin_format format_spec: unicode(c_default="NULL") = '' / -Return value.__format__(format_spec) +Return type(value).__format__(value, format_spec) -format_spec defaults to the empty string. -See the Format Specification Mini-Language section of help('FORMATTING') for -details. +Many built-in types implement format_spec according to the +Format Specification Mini-language. See help('FORMATTING'). + +If type(value) does not supply a method named __format__ +and format_spec is empty, then str(value) is returned. +See also help('SPECIALMETHODS'). [clinic start generated code]*/ static PyObject * builtin_format_impl(PyObject *module, PyObject *value, PyObject *format_spec) -/*[clinic end generated code: output=2f40bdfa4954b077 input=88339c93ea522b33]*/ +/*[clinic end generated code: output=2f40bdfa4954b077 input=45ef3934b86d5624]*/ { return PyObject_Format(value, format_spec); } @@ -727,7 +714,7 @@ compile as builtin_compile filename: object(converter="PyUnicode_FSDecoder") mode: str flags: int = 0 - dont_inherit: bool(accept={int}) = False + dont_inherit: bool = False optimize: int = -1 * _feature_version as feature_version: int = -1 @@ -750,7 +737,7 @@ static PyObject * builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, const char *mode, int flags, int dont_inherit, int optimize, int feature_version) -/*[clinic end generated code: output=b0c09c84f116d3d7 input=40171fb92c1d580d]*/ +/*[clinic end generated code: output=b0c09c84f116d3d7 input=cc78e20e7c7682ba]*/ { PyObject *source_copy; const char *str; @@ -813,8 +800,7 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, goto error; if (is_ast) { if (flags & PyCF_ONLY_AST) { - Py_INCREF(source); - result = source; + result = Py_NewRef(source); } else { PyArena *arena; @@ -851,31 +837,33 @@ finally: return result; } -/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ -static PyObject * -builtin_dir(PyObject *self, PyObject *args) -{ - PyObject *arg = NULL; +/*[clinic input] +dir as builtin_dir - if (!PyArg_UnpackTuple(args, "dir", 0, 1, &arg)) - return NULL; + arg: object = NULL + / + +Show attributes of an object. + +If called without an argument, return the names in the current scope. +Else, return an alphabetized list of names comprising (some of) the attributes +of the given object, and of attributes reachable from it. +If the object supplies a method named __dir__, it will be used; otherwise +the default dir() logic is used and returns: + for a module object: the module's attributes. + for a class object: its attributes, and recursively the attributes + of its bases. + for any other object: its attributes, its class's attributes, and + recursively the attributes of its class's base classes. +[clinic start generated code]*/ + +static PyObject * +builtin_dir_impl(PyObject *module, PyObject *arg) +/*[clinic end generated code: output=24f2c7a52c1e3b08 input=ed6d6ccb13d52251]*/ +{ return PyObject_Dir(arg); } -PyDoc_STRVAR(dir_doc, -"dir([object]) -> list of strings\n" -"\n" -"If called without an argument, return the names in the current scope.\n" -"Else, return an alphabetized list of names comprising (some of) the attributes\n" -"of the given object, and of attributes reachable from it.\n" -"If the object supplies a method named __dir__, it will be used; otherwise\n" -"the default dir() logic is used and returns:\n" -" for a module object: the module's attributes.\n" -" for a class object: its attributes, and recursively the attributes\n" -" of its bases.\n" -" for any other object: its attributes, its class's attributes, and\n" -" recursively the attributes of its class's base classes."); - /*[clinic input] divmod as builtin_divmod @@ -947,10 +935,9 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, return NULL; } - int r = _PyDict_ContainsId(globals, &PyId___builtins__); + int r = PyDict_Contains(globals, &_Py_ID(__builtins__)); if (r == 0) { - r = _PyDict_SetItemId(globals, &PyId___builtins__, - PyEval_GetBuiltins()); + r = PyDict_SetItem(globals, &_Py_ID(__builtins__), PyEval_GetBuiltins()); } if (r < 0) { return NULL; @@ -991,6 +978,8 @@ exec as builtin_exec globals: object = None locals: object = None / + * + closure: object(c_default="NULL") = None Execute the given source in the context of globals and locals. @@ -999,12 +988,14 @@ or a code object as returned by compile(). The globals must be a dictionary and locals can be any mapping, defaulting to the current globals and locals. If only globals is given, locals defaults to it. +The closure must be a tuple of cellvars, and can only be used +when source is a code object requiring exactly that many cellvars. [clinic start generated code]*/ static PyObject * builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, - PyObject *locals) -/*[clinic end generated code: output=3c90efc6ab68ef5d input=01ca3e1c01692829]*/ + PyObject *locals, PyObject *closure) +/*[clinic end generated code: output=7579eb4e7646743d input=f13a7e2b503d1d9a]*/ { PyObject *v; @@ -1035,29 +1026,68 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, Py_TYPE(locals)->tp_name); return NULL; } - int r = _PyDict_ContainsId(globals, &PyId___builtins__); + int r = PyDict_Contains(globals, &_Py_ID(__builtins__)); if (r == 0) { - r = _PyDict_SetItemId(globals, &PyId___builtins__, - PyEval_GetBuiltins()); + r = PyDict_SetItem(globals, &_Py_ID(__builtins__), PyEval_GetBuiltins()); } if (r < 0) { return NULL; } + if (closure == Py_None) { + closure = NULL; + } + if (PyCode_Check(source)) { + Py_ssize_t num_free = PyCode_GetNumFree((PyCodeObject *)source); + if (num_free == 0) { + if (closure) { + PyErr_SetString(PyExc_TypeError, + "cannot use a closure with this code object"); + return NULL; + } + } else { + int closure_is_ok = + closure + && PyTuple_CheckExact(closure) + && (PyTuple_GET_SIZE(closure) == num_free); + if (closure_is_ok) { + for (Py_ssize_t i = 0; i < num_free; i++) { + PyObject *cell = PyTuple_GET_ITEM(closure, i); + if (!PyCell_Check(cell)) { + closure_is_ok = 0; + break; + } + } + } + if (!closure_is_ok) { + PyErr_Format(PyExc_TypeError, + "code object requires a closure of exactly length %zd", + num_free); + return NULL; + } + } + if (PySys_Audit("exec", "O", source) < 0) { return NULL; } - if (PyCode_GetNumFree((PyCodeObject *)source) > 0) { - PyErr_SetString(PyExc_TypeError, - "code object passed to exec() may not " - "contain free variables"); - return NULL; + if (!closure) { + v = PyEval_EvalCode(source, globals, locals); + } else { + v = PyEval_EvalCodeEx(source, globals, locals, + NULL, 0, + NULL, 0, + NULL, 0, + NULL, + closure); } - v = PyEval_EvalCode(source, globals, locals); } else { + if (closure != NULL) { + PyErr_SetString(PyExc_TypeError, + "closure can only be used when source is a code object"); + } PyObject *source_copy; const char *str; PyCompilerFlags cf = _PyCompilerFlags_INIT; @@ -1081,42 +1111,39 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, } -/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ +/*[clinic input] +getattr as builtin_getattr + + object: object + name: object + default: object = NULL + / + +Get a named attribute from an object. + +getattr(x, 'y') is equivalent to x.y +When a default argument is given, it is returned when the attribute doesn't +exist; without it, an exception is raised in that case. +[clinic start generated code]*/ + static PyObject * -builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +builtin_getattr_impl(PyObject *module, PyObject *object, PyObject *name, + PyObject *default_value) +/*[clinic end generated code: output=74ad0e225e3f701c input=d7562cd4c3556171]*/ { - PyObject *v, *name, *result; + PyObject *result; - if (!_PyArg_CheckPositional("getattr", nargs, 2, 3)) - return NULL; - - v = args[0]; - name = args[1]; - if (!PyUnicode_Check(name)) { - PyErr_SetString(PyExc_TypeError, - "getattr(): attribute name must be string"); - return NULL; - } - if (nargs > 2) { - if (_PyObject_LookupAttr(v, name, &result) == 0) { - PyObject *dflt = args[2]; - Py_INCREF(dflt); - return dflt; + if (default_value != NULL) { + if (_PyObject_LookupAttr(object, name, &result) == 0) { + return Py_NewRef(default_value); } } else { - result = PyObject_GetAttr(v, name); + result = PyObject_GetAttr(object, name); } return result; } -PyDoc_STRVAR(getattr_doc, -"getattr(object, name[, default]) -> value\n\ -\n\ -Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.\n\ -When a default argument is given, it is returned when the attribute doesn't\n\ -exist; without it, an exception is raised in that case."); - /*[clinic input] globals as builtin_globals @@ -1134,8 +1161,7 @@ builtin_globals_impl(PyObject *module) PyObject *d; d = PyEval_GetGlobals(); - Py_XINCREF(d); - return d; + return Py_XNewRef(d); } @@ -1157,11 +1183,6 @@ builtin_hasattr_impl(PyObject *module, PyObject *obj, PyObject *name) { PyObject *v; - if (!PyUnicode_Check(name)) { - PyErr_SetString(PyExc_TypeError, - "hasattr(): attribute name must be string"); - return NULL; - } if (_PyObject_LookupAttr(obj, name, &v) < 0) { return NULL; } @@ -1262,7 +1283,7 @@ static PyObject * map_vectorcall(PyObject *type, PyObject * const*args, size_t nargsf, PyObject *kwnames) { - PyTypeObject *tp = (PyTypeObject *)type; + PyTypeObject *tp = _PyType_CAST(type); if (tp == &PyMap_Type && !_PyArg_NoKwnames("map", kwnames)) { return NULL; } @@ -1367,19 +1388,17 @@ map_reduce(mapobject *lz, PyObject *Py_UNUSED(ignored)) Py_ssize_t i; if (args == NULL) return NULL; - Py_INCREF(lz->func); - PyTuple_SET_ITEM(args, 0, lz->func); + PyTuple_SET_ITEM(args, 0, Py_NewRef(lz->func)); for (i = 0; iiters, i); - Py_INCREF(it); - PyTuple_SET_ITEM(args, i+1, it); + PyTuple_SET_ITEM(args, i+1, Py_NewRef(it)); } return Py_BuildValue("ON", Py_TYPE(lz), args); } static PyMethodDef map_methods[] = { - {"__reduce__", (PyCFunction)map_reduce, METH_NOARGS, reduce_doc}, + {"__reduce__", _PyCFunction_CAST(map_reduce), METH_NOARGS, reduce_doc}, {NULL, NULL} /* sentinel */ }; @@ -1436,35 +1455,43 @@ PyTypeObject PyMap_Type = { }; -/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ +/*[clinic input] +next as builtin_next + + iterator: object + default: object = NULL + / + +Return the next item from the iterator. + +If default is given and the iterator is exhausted, +it is returned instead of raising StopIteration. +[clinic start generated code]*/ + static PyObject * -builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +builtin_next_impl(PyObject *module, PyObject *iterator, + PyObject *default_value) +/*[clinic end generated code: output=a38a94eeb447fef9 input=180f9984f182020f]*/ { - PyObject *it, *res; + PyObject *res; - if (!_PyArg_CheckPositional("next", nargs, 1, 2)) - return NULL; - - it = args[0]; - if (!PyIter_Check(it)) { + if (!PyIter_Check(iterator)) { PyErr_Format(PyExc_TypeError, "'%.200s' object is not an iterator", - Py_TYPE(it)->tp_name); + Py_TYPE(iterator)->tp_name); return NULL; } - res = (*Py_TYPE(it)->tp_iternext)(it); + res = (*Py_TYPE(iterator)->tp_iternext)(iterator); if (res != NULL) { return res; - } else if (nargs > 1) { - PyObject *def = args[1]; + } else if (default_value != NULL) { if (PyErr_Occurred()) { if(!PyErr_ExceptionMatches(PyExc_StopIteration)) return NULL; PyErr_Clear(); } - Py_INCREF(def); - return def; + return Py_NewRef(default_value); } else if (PyErr_Occurred()) { return NULL; } else { @@ -1473,12 +1500,6 @@ builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs) } } -PyDoc_STRVAR(next_doc, -"next(iterator[, default])\n\ -\n\ -Return the next item from the iterator. If default is given and the iterator\n\ -is exhausted, it is returned instead of raising StopIteration."); - /*[clinic input] setattr as builtin_setattr @@ -1490,13 +1511,13 @@ setattr as builtin_setattr Sets the named attribute on the given object to the specified value. -setattr(x, 'y', v) is equivalent to ``x.y = v'' +setattr(x, 'y', v) is equivalent to ``x.y = v`` [clinic start generated code]*/ static PyObject * builtin_setattr_impl(PyObject *module, PyObject *obj, PyObject *name, PyObject *value) -/*[clinic end generated code: output=dc2ce1d1add9acb4 input=bd2b7ca6875a1899]*/ +/*[clinic end generated code: output=dc2ce1d1add9acb4 input=5e26417f2e8598d4]*/ { if (PyObject_SetAttr(obj, name, value) != 0) return NULL; @@ -1513,12 +1534,12 @@ delattr as builtin_delattr Deletes the named attribute from the given object. -delattr(x, 'y') is equivalent to ``del x.y'' +delattr(x, 'y') is equivalent to ``del x.y`` [clinic start generated code]*/ static PyObject * builtin_delattr_impl(PyObject *module, PyObject *obj, PyObject *name) -/*[clinic end generated code: output=85134bc58dff79fa input=db16685d6b4b9410]*/ +/*[clinic end generated code: output=85134bc58dff79fa input=164865623abe7216]*/ { if (PyObject_SetAttr(obj, name, (PyObject *)NULL) != 0) return NULL; @@ -1571,34 +1592,33 @@ builtin_hex(PyObject *module, PyObject *number) } -/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ -static PyObject * -builtin_iter(PyObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *v; +/*[clinic input] +iter as builtin_iter - if (!_PyArg_CheckPositional("iter", nargs, 1, 2)) - return NULL; - v = args[0]; - if (nargs == 1) - return PyObject_GetIter(v); - if (!PyCallable_Check(v)) { + object: object + sentinel: object = NULL + / + +Get an iterator from an object. + +In the first form, the argument must supply its own iterator, or be a sequence. +In the second form, the callable is called until it returns the sentinel. +[clinic start generated code]*/ + +static PyObject * +builtin_iter_impl(PyObject *module, PyObject *object, PyObject *sentinel) +/*[clinic end generated code: output=12cf64203c195a94 input=a5d64d9d81880ba6]*/ +{ + if (sentinel == NULL) + return PyObject_GetIter(object); + if (!PyCallable_Check(object)) { PyErr_SetString(PyExc_TypeError, - "iter(v, w): v must be callable"); + "iter(object, sentinel): object must be callable"); return NULL; } - PyObject *sentinel = args[1]; - return PyCallIter_New(v, sentinel); + return PyCallIter_New(object, sentinel); } -PyDoc_STRVAR(iter_doc, -"iter(iterable) -> iterator\n\ -iter(callable, sentinel) -> iterator\n\ -\n\ -Get an iterator from an object. In the first form, the argument must\n\ -supply its own iterator, or be a sequence.\n\ -In the second form, the callable is called until it returns the sentinel."); - /*[clinic input] aiter as builtin_aiter @@ -1700,8 +1720,7 @@ builtin_locals_impl(PyObject *module) PyObject *d; d = PyEval_GetLocals(); - Py_XINCREF(d); - return d; + return Py_XNewRef(d); } @@ -1762,8 +1781,7 @@ min_max(PyObject *args, PyObject *kwds, int op) } /* no key function; the value is the item */ else { - val = item; - Py_INCREF(val); + val = Py_NewRef(item); } /* maximum value and item are unset; set them */ @@ -1793,11 +1811,10 @@ min_max(PyObject *args, PyObject *kwds, int op) if (maxval == NULL) { assert(maxitem == NULL); if (defaultval != NULL) { - Py_INCREF(defaultval); - maxitem = defaultval; + maxitem = Py_NewRef(defaultval); } else { PyErr_Format(PyExc_ValueError, - "%s() arg is an empty sequence", name); + "%s() iterable argument is empty", name); } } else @@ -1971,7 +1988,8 @@ builtin_print_impl(PyObject *module, PyObject *args, PyObject *sep, int i, err; if (file == Py_None) { - file = _PySys_GetObjectId(&PyId_stdout); + PyThreadState *tstate = _PyThreadState_GET(); + file = _PySys_GetAttr(tstate, &_Py_ID(stdout)); if (file == NULL) { PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); return NULL; @@ -2031,7 +2049,7 @@ builtin_print_impl(PyObject *module, PyObject *args, PyObject *sep, } if (flush) { - PyObject *tmp = _PyObject_CallMethodIdNoArgs(file, &PyId_flush); + PyObject *tmp = PyObject_CallMethodNoArgs(file, &_Py_ID(flush)); if (tmp == NULL) { return NULL; } @@ -2045,7 +2063,7 @@ builtin_print_impl(PyObject *module, PyObject *args, PyObject *sep, /*[clinic input] input as builtin_input - prompt: object(c_default="NULL") = None + prompt: object(c_default="NULL") = "" / Read a string from standard input. The trailing newline is stripped. @@ -2059,11 +2077,15 @@ On *nix systems, readline is used if available. static PyObject * builtin_input_impl(PyObject *module, PyObject *prompt) -/*[clinic end generated code: output=83db5a191e7a0d60 input=5e8bb70c2908fe3c]*/ +/*[clinic end generated code: output=83db5a191e7a0d60 input=159c46d4ae40977e]*/ { - PyObject *fin = _PySys_GetObjectId(&PyId_stdin); - PyObject *fout = _PySys_GetObjectId(&PyId_stdout); - PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *fin = _PySys_GetAttr( + tstate, &_Py_ID(stdin)); + PyObject *fout = _PySys_GetAttr( + tstate, &_Py_ID(stdout)); + PyObject *ferr = _PySys_GetAttr( + tstate, &_Py_ID(stderr)); PyObject *tmp; long fd; int tty; @@ -2090,7 +2112,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) } /* First of all, flush stderr */ - tmp = _PyObject_CallMethodIdNoArgs(ferr, &PyId_flush); + tmp = PyObject_CallMethodNoArgs(ferr, &_Py_ID(flush)); if (tmp == NULL) PyErr_Clear(); else @@ -2099,7 +2121,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) /* We should only use (GNU) readline if Python's sys.stdin and sys.stdout are the same as C's stdin and stdout, because we need to pass it those. */ - tmp = _PyObject_CallMethodIdNoArgs(fin, &PyId_fileno); + tmp = PyObject_CallMethodNoArgs(fin, &_Py_ID(fileno)); if (tmp == NULL) { PyErr_Clear(); tty = 0; @@ -2112,7 +2134,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) tty = fd == fileno(stdin) && isatty(fd); } if (tty) { - tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_fileno); + tmp = PyObject_CallMethodNoArgs(fout, &_Py_ID(fileno)); if (tmp == NULL) { PyErr_Clear(); tty = 0; @@ -2138,8 +2160,8 @@ builtin_input_impl(PyObject *module, PyObject *prompt) size_t len; /* stdin is a text stream, so it must have an encoding. */ - stdin_encoding = _PyObject_GetAttrId(fin, &PyId_encoding); - stdin_errors = _PyObject_GetAttrId(fin, &PyId_errors); + stdin_encoding = PyObject_GetAttr(fin, &_Py_ID(encoding)); + stdin_errors = PyObject_GetAttr(fin, &_Py_ID(errors)); if (!stdin_encoding || !stdin_errors || !PyUnicode_Check(stdin_encoding) || !PyUnicode_Check(stdin_errors)) { @@ -2150,7 +2172,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) stdin_errors_str = PyUnicode_AsUTF8(stdin_errors); if (!stdin_encoding_str || !stdin_errors_str) goto _readline_errors; - tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_flush); + tmp = PyObject_CallMethodNoArgs(fout, &_Py_ID(flush)); if (tmp == NULL) PyErr_Clear(); else @@ -2159,8 +2181,8 @@ builtin_input_impl(PyObject *module, PyObject *prompt) /* We have a prompt, encode it as stdout would */ const char *stdout_encoding_str, *stdout_errors_str; PyObject *stringpo; - stdout_encoding = _PyObject_GetAttrId(fout, &PyId_encoding); - stdout_errors = _PyObject_GetAttrId(fout, &PyId_errors); + stdout_encoding = PyObject_GetAttr(fout, &_Py_ID(encoding)); + stdout_errors = PyObject_GetAttr(fout, &_Py_ID(errors)); if (!stdout_encoding || !stdout_errors || !PyUnicode_Check(stdout_encoding) || !PyUnicode_Check(stdout_errors)) { @@ -2245,7 +2267,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) if (PyFile_WriteObject(prompt, fout, Py_PRINT_RAW) != 0) return NULL; } - tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_flush); + tmp = PyObject_CallMethodNoArgs(fout, &_Py_ID(flush)); if (tmp == NULL) PyErr_Clear(); else @@ -2296,7 +2318,7 @@ builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits) return NULL; } - round = _PyObject_LookupSpecial(number, &PyId___round__); + round = _PyObject_LookupSpecial(number, &_Py_ID(__round__)); if (round == NULL) { if (!PyErr_Occurred()) PyErr_Format(PyExc_TypeError, @@ -2341,7 +2363,7 @@ PyDoc_STRVAR(builtin_sorted__doc__, "reverse flag can be set to request the result in descending order."); #define BUILTIN_SORTED_METHODDEF \ - {"sorted", (PyCFunction)(void(*)(void))builtin_sorted, METH_FASTCALL | METH_KEYWORDS, builtin_sorted__doc__}, + {"sorted", _PyCFunction_CAST(builtin_sorted), METH_FASTCALL | METH_KEYWORDS, builtin_sorted__doc__}, static PyObject * builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -2357,7 +2379,7 @@ builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject if (newlist == NULL) return NULL; - callable = _PyObject_GetAttrId(newlist, &PyId_sort); + callable = PyObject_GetAttr(newlist, &_Py_ID(sort)); if (callable == NULL) { Py_DECREF(newlist); return NULL; @@ -2375,21 +2397,29 @@ builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject } -/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ +/*[clinic input] +vars as builtin_vars + + object: object = NULL + / + +Show vars. + +Without arguments, equivalent to locals(). +With an argument, equivalent to object.__dict__. +[clinic start generated code]*/ + static PyObject * -builtin_vars(PyObject *self, PyObject *args) +builtin_vars_impl(PyObject *module, PyObject *object) +/*[clinic end generated code: output=840a7f64007a3e0a input=80cbdef9182c4ba3]*/ { - PyObject *v = NULL; PyObject *d; - if (!PyArg_UnpackTuple(args, "vars", 0, 1, &v)) - return NULL; - if (v == NULL) { - d = PyEval_GetLocals(); - Py_XINCREF(d); + if (object == NULL) { + d = Py_XNewRef(PyEval_GetLocals()); } else { - if (_PyObject_LookupAttrId(v, &PyId___dict__, &d) == 0) { + if (_PyObject_LookupAttr(object, &_Py_ID(__dict__), &d) == 0) { PyErr_SetString(PyExc_TypeError, "vars() argument must have __dict__ attribute"); } @@ -2397,12 +2427,6 @@ builtin_vars(PyObject *self, PyObject *args) return d; } -PyDoc_STRVAR(vars_doc, -"vars([object]) -> dictionary\n\ -\n\ -Without arguments, equivalent to locals().\n\ -With an argument, equivalent to object.__dict__."); - /*[clinic input] sum as builtin_sum @@ -2468,8 +2492,7 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) long i_result = PyLong_AsLongAndOverflow(result, &overflow); /* If this already overflowed, don't even enter the loop. */ if (overflow == 0) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); } while(result == NULL) { item = PyIter_Next(iter); @@ -2519,19 +2542,34 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) if (PyFloat_CheckExact(result)) { double f_result = PyFloat_AS_DOUBLE(result); - Py_DECREF(result); - result = NULL; + double c = 0.0; + Py_SETREF(result, NULL); while(result == NULL) { item = PyIter_Next(iter); if (item == NULL) { Py_DECREF(iter); if (PyErr_Occurred()) return NULL; + /* Avoid losing the sign on a negative result, + and don't let adding the compensation convert + an infinite or overflowed sum to a NaN. */ + if (c && Py_IS_FINITE(c)) { + f_result += c; + } return PyFloat_FromDouble(f_result); } if (PyFloat_CheckExact(item)) { - f_result += PyFloat_AS_DOUBLE(item); - Py_DECREF(item); + // Improved Kahan–BabuÅ¡ka algorithm by Arnold Neumaier + // https://www.mat.univie.ac.at/~neum/scan/01.pdf + double x = PyFloat_AS_DOUBLE(item); + double t = f_result + x; + if (fabs(f_result) >= fabs(x)) { + c += (f_result - t) + x; + } else { + c += (x - t) + f_result; + } + f_result = t; + _Py_DECREF_SPECIALIZED(item, _PyFloat_ExactDealloc); continue; } if (PyLong_Check(item)) { @@ -2544,6 +2582,9 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) continue; } } + if (c && Py_IS_FINITE(c)) { + f_result += c; + } result = PyFloat_FromDouble(f_result); if (result == NULL) { Py_DECREF(item); @@ -2567,8 +2608,7 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) if (item == NULL) { /* error, or end-of-sequence */ if (PyErr_Occurred()) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); } break; } @@ -2709,8 +2749,7 @@ zip_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } for (i=0 ; i < tuplesize ; i++) { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(result, i, Py_None); + PyTuple_SET_ITEM(result, i, Py_NewRef(Py_None)); } /* create zipobject structure */ @@ -2859,8 +2898,8 @@ zip_setstate(zipobject *lz, PyObject *state) } static PyMethodDef zip_methods[] = { - {"__reduce__", (PyCFunction)zip_reduce, METH_NOARGS, reduce_doc}, - {"__setstate__", (PyCFunction)zip_setstate, METH_O, setstate_doc}, + {"__reduce__", _PyCFunction_CAST(zip_reduce), METH_NOARGS, reduce_doc}, + {"__setstate__", _PyCFunction_CAST(zip_setstate), METH_O, setstate_doc}, {NULL} /* sentinel */ }; @@ -2924,25 +2963,25 @@ PyTypeObject PyZip_Type = { static PyMethodDef builtin_methods[] = { - {"__build_class__", (PyCFunction)(void(*)(void))builtin___build_class__, + {"__build_class__", _PyCFunction_CAST(builtin___build_class__), METH_FASTCALL | METH_KEYWORDS, build_class_doc}, - {"__import__", (PyCFunction)(void(*)(void))builtin___import__, METH_VARARGS | METH_KEYWORDS, import_doc}, + BUILTIN___IMPORT___METHODDEF BUILTIN_ABS_METHODDEF BUILTIN_ALL_METHODDEF BUILTIN_ANY_METHODDEF BUILTIN_ASCII_METHODDEF BUILTIN_BIN_METHODDEF - {"breakpoint", (PyCFunction)(void(*)(void))builtin_breakpoint, METH_FASTCALL | METH_KEYWORDS, breakpoint_doc}, + {"breakpoint", _PyCFunction_CAST(builtin_breakpoint), METH_FASTCALL | METH_KEYWORDS, breakpoint_doc}, BUILTIN_CALLABLE_METHODDEF BUILTIN_CHR_METHODDEF BUILTIN_COMPILE_METHODDEF BUILTIN_DELATTR_METHODDEF - {"dir", builtin_dir, METH_VARARGS, dir_doc}, + BUILTIN_DIR_METHODDEF BUILTIN_DIVMOD_METHODDEF BUILTIN_EVAL_METHODDEF BUILTIN_EXEC_METHODDEF BUILTIN_FORMAT_METHODDEF - {"getattr", (PyCFunction)(void(*)(void))builtin_getattr, METH_FASTCALL, getattr_doc}, + BUILTIN_GETATTR_METHODDEF BUILTIN_GLOBALS_METHODDEF BUILTIN_HASATTR_METHODDEF BUILTIN_HASH_METHODDEF @@ -2951,13 +2990,13 @@ static PyMethodDef builtin_methods[] = { BUILTIN_INPUT_METHODDEF BUILTIN_ISINSTANCE_METHODDEF BUILTIN_ISSUBCLASS_METHODDEF - {"iter", (PyCFunction)(void(*)(void))builtin_iter, METH_FASTCALL, iter_doc}, + BUILTIN_ITER_METHODDEF BUILTIN_AITER_METHODDEF BUILTIN_LEN_METHODDEF BUILTIN_LOCALS_METHODDEF - {"max", (PyCFunction)(void(*)(void))builtin_max, METH_VARARGS | METH_KEYWORDS, max_doc}, - {"min", (PyCFunction)(void(*)(void))builtin_min, METH_VARARGS | METH_KEYWORDS, min_doc}, - {"next", (PyCFunction)(void(*)(void))builtin_next, METH_FASTCALL, next_doc}, + {"max", _PyCFunction_CAST(builtin_max), METH_VARARGS | METH_KEYWORDS, max_doc}, + {"min", _PyCFunction_CAST(builtin_min), METH_VARARGS | METH_KEYWORDS, min_doc}, + BUILTIN_NEXT_METHODDEF BUILTIN_ANEXT_METHODDEF BUILTIN_OCT_METHODDEF BUILTIN_ORD_METHODDEF @@ -2968,7 +3007,7 @@ static PyMethodDef builtin_methods[] = { BUILTIN_SETATTR_METHODDEF BUILTIN_SORTED_METHODDEF BUILTIN_SUM_METHODDEF - {"vars", builtin_vars, METH_VARARGS, vars_doc}, + BUILTIN_VARS_METHODDEF {NULL, NULL}, }; @@ -2997,11 +3036,6 @@ _PyBuiltin_Init(PyInterpreterState *interp) const PyConfig *config = _PyInterpreterState_GetConfig(interp); - if (PyType_Ready(&PyFilter_Type) < 0 || - PyType_Ready(&PyMap_Type) < 0 || - PyType_Ready(&PyZip_Type) < 0) - return NULL; - mod = _PyModule_CreateInitialized(&builtinsmodule, PYTHON_API_VERSION); if (mod == NULL) return NULL; diff --git a/Python/bootstrap_frozen.c b/Python/bootstrap_frozen.c deleted file mode 100644 index 68ba147a727..00000000000 --- a/Python/bootstrap_frozen.c +++ /dev/null @@ -1,45 +0,0 @@ - -/* Frozen modules bootstrap */ - -/* This file is linked with "bootstrap Python" - which is used (only) to run Tools/scripts/deepfreeze.py. */ - -#include "Python.h" -#include "pycore_import.h" - -/* Includes for frozen modules: */ -#include "frozen_modules/importlib._bootstrap.h" -#include "frozen_modules/importlib._bootstrap_external.h" -#include "frozen_modules/zipimport.h" -/* End includes */ - -/* Note that a negative size indicates a package. */ - -static const struct _frozen bootstrap_modules[] = { - {"_frozen_importlib", _Py_M__importlib__bootstrap, (int)sizeof(_Py_M__importlib__bootstrap)}, - {"_frozen_importlib_external", _Py_M__importlib__bootstrap_external, (int)sizeof(_Py_M__importlib__bootstrap_external)}, - {"zipimport", _Py_M__zipimport, (int)sizeof(_Py_M__zipimport)}, - {0, 0, 0} /* bootstrap sentinel */ -}; -static const struct _frozen stdlib_modules[] = { - {0, 0, 0} /* stdlib sentinel */ -}; -static const struct _frozen test_modules[] = { - {0, 0, 0} /* test sentinel */ -}; -const struct _frozen *_PyImport_FrozenBootstrap = bootstrap_modules; -const struct _frozen *_PyImport_FrozenStdlib = stdlib_modules; -const struct _frozen *_PyImport_FrozenTest = test_modules; - -static const struct _module_alias aliases[] = { - {"_frozen_importlib", "importlib._bootstrap"}, - {"_frozen_importlib_external", "importlib._bootstrap_external"}, - {0, 0} /* aliases sentinel */ -}; -const struct _module_alias *_PyImport_FrozenAliases = aliases; - - -/* Embedding apps may change this pointer to point to their favorite - collection of frozen modules: */ - -const struct _frozen *PyImport_FrozenModules = NULL; diff --git a/Python/bootstrap_hash.c b/Python/bootstrap_hash.c index 144f7cb4a21..587063ef1ab 100644 --- a/Python/bootstrap_hash.c +++ b/Python/bootstrap_hash.c @@ -1,5 +1,8 @@ #include "Python.h" #include "pycore_initconfig.h" +#include "pycore_fileutils.h" // _Py_fstat_noraise() +#include "pycore_runtime.h" // _PyRuntime + #ifdef MS_WINDOWS # include # include @@ -261,11 +264,7 @@ py_getentropy(char *buffer, Py_ssize_t size, int raise) #endif /* defined(HAVE_GETENTROPY) && !(defined(__sun) && defined(__SVR4)) */ -static struct { - int fd; - dev_t st_dev; - ino_t st_ino; -} urandom_cache = { -1 }; +#define urandom_cache (_PyRuntime.pyhash_state.urandom_cache) /* Read random bytes from the /dev/urandom device: @@ -400,6 +399,9 @@ dev_urandom_close(void) urandom_cache.fd = -1; } } + +#undef urandom_cache + #endif /* !MS_WINDOWS */ diff --git a/Python/bytecodes.c b/Python/bytecodes.c new file mode 100644 index 00000000000..fb00b887732 --- /dev/null +++ b/Python/bytecodes.c @@ -0,0 +1,3311 @@ +// This file contains instruction definitions. +// It is read by Tools/cases_generator/generate_cases.py +// to generate Python/generated_cases.c.h. +// Note that there is some dummy C code at the top and bottom of the file +// to fool text editors like VS Code into believing this is valid C code. +// The actual instruction definitions start at // BEGIN BYTECODES //. +// See Tools/cases_generator/README.md for more information. + +#include "Python.h" +#include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_call.h" // _PyObject_FastCallDictTstate() +#include "pycore_ceval.h" // _PyEval_SignalAsyncExc() +#include "pycore_code.h" +#include "pycore_function.h" +#include "pycore_intrinsics.h" +#include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_moduleobject.h" // PyModuleObject +#include "pycore_opcode.h" // EXTRA_CASES +#include "pycore_pyerrors.h" // _PyErr_Fetch() +#include "pycore_pymem.h" // _PyMem_IsPtrFreed() +#include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_range.h" // _PyRangeIterObject +#include "pycore_sliceobject.h" // _PyBuildSlice_ConsumeRefs +#include "pycore_sysmodule.h" // _PySys_Audit() +#include "pycore_tuple.h" // _PyTuple_ITEMS() +#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS + +#include "pycore_dict.h" +#include "dictobject.h" +#include "pycore_frame.h" +#include "opcode.h" +#include "pydtrace.h" +#include "setobject.h" +#include "structmember.h" // struct PyMemberDef, T_OFFSET_EX + +#define USE_COMPUTED_GOTOS 0 +#include "ceval_macros.h" + +/* Flow control macros */ +#define DEOPT_IF(cond, instname) ((void)0) +#define ERROR_IF(cond, labelname) ((void)0) +#define GO_TO_INSTRUCTION(instname) ((void)0) +#define PREDICT(opname) ((void)0) + +#define inst(name, ...) case name: +#define op(name, ...) /* NAME is ignored */ +#define macro(name) static int MACRO_##name +#define super(name) static int SUPER_##name +#define family(name, ...) static int family_##name + +// Dummy variables for stack effects. +static PyObject *value, *value1, *value2, *left, *right, *res, *sum, *prod, *sub; +static PyObject *container, *start, *stop, *v, *lhs, *rhs, *res2; +static PyObject *list, *tuple, *dict, *owner, *set, *str, *tup, *map, *keys; +static PyObject *exit_func, *lasti, *val, *retval, *obj, *iter; +static PyObject *aiter, *awaitable, *iterable, *w, *exc_value, *bc; +static PyObject *orig, *excs, *update, *b, *fromlist, *level, *from; +static PyObject **pieces, **values; +static size_t jump; +// Dummy variables for cache effects +static uint16_t invert, counter, index, hint; +static uint32_t type_version; + +static PyObject * +dummy_func( + PyThreadState *tstate, + _PyInterpreterFrame *frame, + unsigned char opcode, + unsigned int oparg, + _Py_atomic_int * const eval_breaker, + _PyCFrame cframe, + PyObject *names, + PyObject *consts, + _Py_CODEUNIT *next_instr, + PyObject **stack_pointer, + PyObject *kwnames, + int throwflag, + binaryfunc binary_ops[] +) +{ + _PyInterpreterFrame entry_frame; + + switch (opcode) { + +// BEGIN BYTECODES // + inst(NOP, (--)) { + } + + inst(RESUME, (--)) { + assert(tstate->cframe == &cframe); + assert(frame == cframe.current_frame); + if (_Py_atomic_load_relaxed_int32(eval_breaker) && oparg < 2) { + goto handle_eval_breaker; + } + } + + inst(LOAD_CLOSURE, (-- value)) { + /* We keep LOAD_CLOSURE so that the bytecode stays more readable. */ + value = GETLOCAL(oparg); + ERROR_IF(value == NULL, unbound_local_error); + Py_INCREF(value); + } + + inst(LOAD_FAST_CHECK, (-- value)) { + value = GETLOCAL(oparg); + ERROR_IF(value == NULL, unbound_local_error); + Py_INCREF(value); + } + + inst(LOAD_FAST, (-- value)) { + value = GETLOCAL(oparg); + assert(value != NULL); + Py_INCREF(value); + } + + inst(LOAD_CONST, (-- value)) { + value = GETITEM(consts, oparg); + Py_INCREF(value); + } + + inst(STORE_FAST, (value --)) { + SETLOCAL(oparg, value); + } + + super(LOAD_FAST__LOAD_FAST) = LOAD_FAST + LOAD_FAST; + super(LOAD_FAST__LOAD_CONST) = LOAD_FAST + LOAD_CONST; + super(STORE_FAST__LOAD_FAST) = STORE_FAST + LOAD_FAST; + super(STORE_FAST__STORE_FAST) = STORE_FAST + STORE_FAST; + super(LOAD_CONST__LOAD_FAST) = LOAD_CONST + LOAD_FAST; + + inst(POP_TOP, (value --)) { + DECREF_INPUTS(); + } + + inst(PUSH_NULL, (-- res)) { + res = NULL; + } + + macro(END_FOR) = POP_TOP + POP_TOP; + + inst(UNARY_NEGATIVE, (value -- res)) { + res = PyNumber_Negative(value); + DECREF_INPUTS(); + ERROR_IF(res == NULL, error); + } + + inst(UNARY_NOT, (value -- res)) { + int err = PyObject_IsTrue(value); + DECREF_INPUTS(); + ERROR_IF(err < 0, error); + if (err == 0) { + res = Py_True; + } + else { + res = Py_False; + } + Py_INCREF(res); + } + + inst(UNARY_INVERT, (value -- res)) { + res = PyNumber_Invert(value); + DECREF_INPUTS(); + ERROR_IF(res == NULL, error); + } + + family(binary_op, INLINE_CACHE_ENTRIES_BINARY_OP) = { + BINARY_OP, + BINARY_OP_ADD_FLOAT, + BINARY_OP_ADD_INT, + BINARY_OP_ADD_UNICODE, + // BINARY_OP_INPLACE_ADD_UNICODE, // This is an odd duck. + BINARY_OP_MULTIPLY_FLOAT, + BINARY_OP_MULTIPLY_INT, + BINARY_OP_SUBTRACT_FLOAT, + BINARY_OP_SUBTRACT_INT, + }; + + + inst(BINARY_OP_MULTIPLY_INT, (unused/1, left, right -- prod)) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); + prod = _PyLong_Multiply((PyLongObject *)left, (PyLongObject *)right); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + ERROR_IF(prod == NULL, error); + } + + inst(BINARY_OP_MULTIPLY_FLOAT, (unused/1, left, right -- prod)) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); + double dprod = ((PyFloatObject *)left)->ob_fval * + ((PyFloatObject *)right)->ob_fval; + prod = PyFloat_FromDouble(dprod); + _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); + _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); + ERROR_IF(prod == NULL, error); + } + + inst(BINARY_OP_SUBTRACT_INT, (unused/1, left, right -- sub)) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); + sub = _PyLong_Subtract((PyLongObject *)left, (PyLongObject *)right); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + ERROR_IF(sub == NULL, error); + } + + inst(BINARY_OP_SUBTRACT_FLOAT, (unused/1, left, right -- sub)) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); + double dsub = ((PyFloatObject *)left)->ob_fval - ((PyFloatObject *)right)->ob_fval; + sub = PyFloat_FromDouble(dsub); + _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); + _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); + ERROR_IF(sub == NULL, error); + } + + inst(BINARY_OP_ADD_UNICODE, (unused/1, left, right -- res)) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + STAT_INC(BINARY_OP, hit); + res = PyUnicode_Concat(left, right); + _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); + _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); + ERROR_IF(res == NULL, error); + } + + // This is a subtle one. It's a super-instruction for + // BINARY_OP_ADD_UNICODE followed by STORE_FAST + // where the store goes into the left argument. + // So the inputs are the same as for all BINARY_OP + // specializations, but there is no output. + // At the end we just skip over the STORE_FAST. + inst(BINARY_OP_INPLACE_ADD_UNICODE, (left, right --)) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + _Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP]; + assert(_Py_OPCODE(true_next) == STORE_FAST || + _Py_OPCODE(true_next) == STORE_FAST__LOAD_FAST); + PyObject **target_local = &GETLOCAL(_Py_OPARG(true_next)); + DEOPT_IF(*target_local != left, BINARY_OP); + STAT_INC(BINARY_OP, hit); + /* Handle `left = left + right` or `left += right` for str. + * + * When possible, extend `left` in place rather than + * allocating a new PyUnicodeObject. This attempts to avoid + * quadratic behavior when one neglects to use str.join(). + * + * If `left` has only two references remaining (one from + * the stack, one in the locals), DECREFing `left` leaves + * only the locals reference, so PyUnicode_Append knows + * that the string is safe to mutate. + */ + assert(Py_REFCNT(left) >= 2); + _Py_DECREF_NO_DEALLOC(left); + PyUnicode_Append(target_local, right); + _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); + ERROR_IF(*target_local == NULL, error); + // The STORE_FAST is already done. + JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP + 1); + } + + inst(BINARY_OP_ADD_FLOAT, (unused/1, left, right -- sum)) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + STAT_INC(BINARY_OP, hit); + double dsum = ((PyFloatObject *)left)->ob_fval + + ((PyFloatObject *)right)->ob_fval; + sum = PyFloat_FromDouble(dsum); + _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); + _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); + ERROR_IF(sum == NULL, error); + } + + inst(BINARY_OP_ADD_INT, (unused/1, left, right -- sum)) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + STAT_INC(BINARY_OP, hit); + sum = _PyLong_Add((PyLongObject *)left, (PyLongObject *)right); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + ERROR_IF(sum == NULL, error); + } + + family(binary_subscr, INLINE_CACHE_ENTRIES_BINARY_SUBSCR) = { + BINARY_SUBSCR, + BINARY_SUBSCR_DICT, + BINARY_SUBSCR_GETITEM, + BINARY_SUBSCR_LIST_INT, + BINARY_SUBSCR_TUPLE_INT, + }; + + inst(BINARY_SUBSCR, (unused/4, container, sub -- res)) { + #if ENABLE_SPECIALIZATION + _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + assert(cframe.use_tracing == 0); + next_instr--; + _Py_Specialize_BinarySubscr(container, sub, next_instr); + DISPATCH_SAME_OPARG(); + } + STAT_INC(BINARY_SUBSCR, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + res = PyObject_GetItem(container, sub); + DECREF_INPUTS(); + ERROR_IF(res == NULL, error); + } + + inst(BINARY_SLICE, (container, start, stop -- res)) { + PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop); + // Can't use ERROR_IF() here, because we haven't + // DECREF'ed container yet, and we still own slice. + if (slice == NULL) { + res = NULL; + } + else { + res = PyObject_GetItem(container, slice); + Py_DECREF(slice); + } + Py_DECREF(container); + ERROR_IF(res == NULL, error); + } + + inst(STORE_SLICE, (v, container, start, stop -- )) { + PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop); + int err; + if (slice == NULL) { + err = 1; + } + else { + err = PyObject_SetItem(container, slice, v); + Py_DECREF(slice); + } + Py_DECREF(v); + Py_DECREF(container); + ERROR_IF(err, error); + } + + inst(BINARY_SUBSCR_LIST_INT, (unused/4, list, sub -- res)) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); + DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR); + + // Deopt unless 0 <= sub < PyList_Size(list) + DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR); + assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0); + Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; + DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + res = PyList_GET_ITEM(list, index); + assert(res != NULL); + Py_INCREF(res); + _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + Py_DECREF(list); + } + + inst(BINARY_SUBSCR_TUPLE_INT, (unused/4, tuple, sub -- res)) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); + DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR); + + // Deopt unless 0 <= sub < PyTuple_Size(list) + DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR); + assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0); + Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; + DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + res = PyTuple_GET_ITEM(tuple, index); + assert(res != NULL); + Py_INCREF(res); + _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + Py_DECREF(tuple); + } + + inst(BINARY_SUBSCR_DICT, (unused/4, dict, sub -- res)) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyDict_CheckExact(dict), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + res = PyDict_GetItemWithError(dict, sub); + if (res == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetKeyError(sub); + } + Py_DECREF(dict); + Py_DECREF(sub); + ERROR_IF(true, error); + } + Py_INCREF(res); // Do this before DECREF'ing dict, sub + DECREF_INPUTS(); + } + + inst(BINARY_SUBSCR_GETITEM, (unused/1, type_version/2, func_version/1, container, sub -- unused)) { + PyTypeObject *tp = Py_TYPE(container); + DEOPT_IF(tp->tp_version_tag != type_version, BINARY_SUBSCR); + assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE); + PyObject *cached = ((PyHeapTypeObject *)tp)->_spec_cache.getitem; + assert(PyFunction_Check(cached)); + PyFunctionObject *getitem = (PyFunctionObject *)cached; + DEOPT_IF(getitem->func_version != func_version, BINARY_SUBSCR); + PyCodeObject *code = (PyCodeObject *)getitem->func_code; + assert(code->co_argcount == 2); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + Py_INCREF(getitem); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2); + STACK_SHRINK(2); + new_frame->localsplus[0] = container; + new_frame->localsplus[1] = sub; + JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); + DISPATCH_INLINED(new_frame); + } + + inst(LIST_APPEND, (list, unused[oparg-1], v -- list, unused[oparg-1])) { + ERROR_IF(_PyList_AppendTakeRef((PyListObject *)list, v) < 0, error); + PREDICT(JUMP_BACKWARD); + } + + inst(SET_ADD, (set, unused[oparg-1], v -- set, unused[oparg-1])) { + int err = PySet_Add(set, v); + Py_DECREF(v); + ERROR_IF(err, error); + PREDICT(JUMP_BACKWARD); + } + + family(store_subscr) = { + STORE_SUBSCR, + STORE_SUBSCR_DICT, + STORE_SUBSCR_LIST_INT, + }; + + inst(STORE_SUBSCR, (counter/1, v, container, sub -- )) { + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + assert(cframe.use_tracing == 0); + next_instr--; + _Py_Specialize_StoreSubscr(container, sub, next_instr); + DISPATCH_SAME_OPARG(); + } + STAT_INC(STORE_SUBSCR, deferred); + _PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr; + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #else + (void)counter; // Unused. + #endif /* ENABLE_SPECIALIZATION */ + /* container[sub] = v */ + int err = PyObject_SetItem(container, sub, v); + DECREF_INPUTS(); + ERROR_IF(err, error); + } + + inst(STORE_SUBSCR_LIST_INT, (unused/1, value, list, sub -- )) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyLong_CheckExact(sub), STORE_SUBSCR); + DEOPT_IF(!PyList_CheckExact(list), STORE_SUBSCR); + + // Ensure nonnegative, zero-or-one-digit ints. + DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), STORE_SUBSCR); + Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; + // Ensure index < len(list) + DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR); + STAT_INC(STORE_SUBSCR, hit); + + PyObject *old_value = PyList_GET_ITEM(list, index); + PyList_SET_ITEM(list, index, value); + assert(old_value != NULL); + Py_DECREF(old_value); + _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + Py_DECREF(list); + } + + inst(STORE_SUBSCR_DICT, (unused/1, value, dict, sub -- )) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyDict_CheckExact(dict), STORE_SUBSCR); + STAT_INC(STORE_SUBSCR, hit); + int err = _PyDict_SetItem_Take2((PyDictObject *)dict, sub, value); + Py_DECREF(dict); + ERROR_IF(err, error); + } + + inst(DELETE_SUBSCR, (container, sub --)) { + /* del container[sub] */ + int err = PyObject_DelItem(container, sub); + DECREF_INPUTS(); + ERROR_IF(err, error); + } + + inst(CALL_INTRINSIC_1, (value -- res)) { + assert(oparg <= MAX_INTRINSIC_1); + res = _PyIntrinsics_UnaryFunctions[oparg](tstate, value); + Py_DECREF(value); + ERROR_IF(res == NULL, error); + } + + inst(RAISE_VARARGS, (args[oparg] -- )) { + PyObject *cause = NULL, *exc = NULL; + switch (oparg) { + case 2: + cause = args[1]; + /* fall through */ + case 1: + exc = args[0]; + /* fall through */ + case 0: + ERROR_IF(do_raise(tstate, exc, cause), exception_unwind); + break; + default: + _PyErr_SetString(tstate, PyExc_SystemError, + "bad RAISE_VARARGS oparg"); + break; + } + ERROR_IF(true, error); + } + + inst(INTERPRETER_EXIT, (retval --)) { + assert(frame == &entry_frame); + assert(_PyFrame_IsIncomplete(frame)); + STACK_SHRINK(1); // Since we're not going to DISPATCH() + assert(EMPTY()); + /* Restore previous cframe and return. */ + tstate->cframe = cframe.previous; + tstate->cframe->use_tracing = cframe.use_tracing; + assert(tstate->cframe->current_frame == frame->previous); + assert(!_PyErr_Occurred(tstate)); + _Py_LeaveRecursiveCallTstate(tstate); + return retval; + } + + inst(RETURN_VALUE, (retval --)) { + STACK_SHRINK(1); + assert(EMPTY()); + _PyFrame_SetStackPointer(frame, stack_pointer); + TRACE_FUNCTION_EXIT(); + DTRACE_FUNCTION_EXIT(); + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = cframe.current_frame = dying->previous; + _PyEvalFrameClearAndPop(tstate, dying); + _PyFrame_StackPush(frame, retval); + goto resume_frame; + } + + inst(GET_AITER, (obj -- iter)) { + unaryfunc getter = NULL; + PyTypeObject *type = Py_TYPE(obj); + + if (type->tp_as_async != NULL) { + getter = type->tp_as_async->am_aiter; + } + + if (getter == NULL) { + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' requires an object with " + "__aiter__ method, got %.100s", + type->tp_name); + DECREF_INPUTS(); + ERROR_IF(true, error); + } + + iter = (*getter)(obj); + DECREF_INPUTS(); + ERROR_IF(iter == NULL, error); + + if (Py_TYPE(iter)->tp_as_async == NULL || + Py_TYPE(iter)->tp_as_async->am_anext == NULL) { + + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' received an object from __aiter__ " + "that does not implement __anext__: %.100s", + Py_TYPE(iter)->tp_name); + Py_DECREF(iter); + ERROR_IF(true, error); + } + } + + inst(GET_ANEXT, (aiter -- aiter, awaitable)) { + unaryfunc getter = NULL; + PyObject *next_iter = NULL; + PyTypeObject *type = Py_TYPE(aiter); + + if (PyAsyncGen_CheckExact(aiter)) { + awaitable = type->tp_as_async->am_anext(aiter); + if (awaitable == NULL) { + goto error; + } + } else { + if (type->tp_as_async != NULL){ + getter = type->tp_as_async->am_anext; + } + + if (getter != NULL) { + next_iter = (*getter)(aiter); + if (next_iter == NULL) { + goto error; + } + } + else { + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' requires an iterator with " + "__anext__ method, got %.100s", + type->tp_name); + goto error; + } + + awaitable = _PyCoro_GetAwaitableIter(next_iter); + if (awaitable == NULL) { + _PyErr_FormatFromCause( + PyExc_TypeError, + "'async for' received an invalid object " + "from __anext__: %.100s", + Py_TYPE(next_iter)->tp_name); + + Py_DECREF(next_iter); + goto error; + } else { + Py_DECREF(next_iter); + } + } + + PREDICT(LOAD_CONST); + } + + inst(GET_AWAITABLE, (iterable -- iter)) { + iter = _PyCoro_GetAwaitableIter(iterable); + + if (iter == NULL) { + format_awaitable_error(tstate, Py_TYPE(iterable), oparg); + } + + DECREF_INPUTS(); + + if (iter != NULL && PyCoro_CheckExact(iter)) { + PyObject *yf = _PyGen_yf((PyGenObject*)iter); + if (yf != NULL) { + /* `iter` is a coroutine object that is being + awaited, `yf` is a pointer to the current awaitable + being awaited on. */ + Py_DECREF(yf); + Py_CLEAR(iter); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "coroutine is being awaited already"); + /* The code below jumps to `error` if `iter` is NULL. */ + } + } + + ERROR_IF(iter == NULL, error); + + PREDICT(LOAD_CONST); + } + + // error: SEND stack effect depends on jump flag + inst(SEND) { + assert(frame != &entry_frame); + assert(STACK_LEVEL() >= 2); + PyObject *v = POP(); + PyObject *receiver = TOP(); + PySendResult gen_status; + PyObject *retval; + if (tstate->c_tracefunc == NULL) { + gen_status = PyIter_Send(receiver, v, &retval); + } else { + if (Py_IsNone(v) && PyIter_Check(receiver)) { + retval = Py_TYPE(receiver)->tp_iternext(receiver); + } + else { + retval = PyObject_CallMethodOneArg(receiver, &_Py_ID(send), v); + } + if (retval == NULL) { + if (tstate->c_tracefunc != NULL + && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) + call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, frame); + if (_PyGen_FetchStopIterationValue(&retval) == 0) { + gen_status = PYGEN_RETURN; + } + else { + gen_status = PYGEN_ERROR; + } + } + else { + gen_status = PYGEN_NEXT; + } + } + Py_DECREF(v); + if (gen_status == PYGEN_ERROR) { + assert(retval == NULL); + goto error; + } + if (gen_status == PYGEN_RETURN) { + assert(retval != NULL); + Py_DECREF(receiver); + SET_TOP(retval); + JUMPBY(oparg); + } + else { + assert(gen_status == PYGEN_NEXT); + assert(retval != NULL); + PUSH(retval); + } + } + + inst(YIELD_VALUE, (retval -- unused)) { + // NOTE: It's important that YIELD_VALUE never raises an exception! + // The compiler treats any exception raised here as a failed close() + // or throw() call. + assert(frame != &entry_frame); + PyGenObject *gen = _PyFrame_GetGenerator(frame); + gen->gi_frame_state = FRAME_SUSPENDED; + _PyFrame_SetStackPointer(frame, stack_pointer - 1); + TRACE_FUNCTION_EXIT(); + DTRACE_FUNCTION_EXIT(); + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *gen_frame = frame; + frame = cframe.current_frame = frame->previous; + gen_frame->previous = NULL; + frame->prev_instr -= frame->yield_offset; + _PyFrame_StackPush(frame, retval); + goto resume_frame; + } + + inst(POP_EXCEPT, (exc_value -- )) { + _PyErr_StackItem *exc_info = tstate->exc_info; + Py_XSETREF(exc_info->exc_value, exc_value); + } + + // stack effect: (__0 -- ) + inst(RERAISE) { + if (oparg) { + PyObject *lasti = PEEK(oparg + 1); + if (PyLong_Check(lasti)) { + frame->prev_instr = _PyCode_CODE(frame->f_code) + PyLong_AsLong(lasti); + assert(!_PyErr_Occurred(tstate)); + } + else { + assert(PyLong_Check(lasti)); + _PyErr_SetString(tstate, PyExc_SystemError, "lasti is not an int"); + goto error; + } + } + PyObject *val = POP(); + assert(val && PyExceptionInstance_Check(val)); + PyObject *exc = Py_NewRef(PyExceptionInstance_Class(val)); + PyObject *tb = PyException_GetTraceback(val); + _PyErr_Restore(tstate, exc, val, tb); + goto exception_unwind; + } + + inst(PREP_RERAISE_STAR, (orig, excs -- val)) { + assert(PyList_Check(excs)); + + val = _PyExc_PrepReraiseStar(orig, excs); + DECREF_INPUTS(); + + ERROR_IF(val == NULL, error); + } + + // stack effect: (__0, __1 -- ) + inst(END_ASYNC_FOR) { + PyObject *val = POP(); + assert(val && PyExceptionInstance_Check(val)); + if (PyErr_GivenExceptionMatches(val, PyExc_StopAsyncIteration)) { + Py_DECREF(val); + Py_DECREF(POP()); + } + else { + PyObject *exc = Py_NewRef(PyExceptionInstance_Class(val)); + PyObject *tb = PyException_GetTraceback(val); + _PyErr_Restore(tstate, exc, val, tb); + goto exception_unwind; + } + } + + // stack effect: (__0, __1 -- ) + inst(CLEANUP_THROW) { + assert(throwflag); + PyObject *exc_value = TOP(); + assert(exc_value && PyExceptionInstance_Check(exc_value)); + if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) { + PyObject *value = ((PyStopIterationObject *)exc_value)->value; + Py_INCREF(value); + Py_DECREF(POP()); // The StopIteration. + Py_DECREF(POP()); // The last sent value. + Py_DECREF(POP()); // The delegated sub-iterator. + PUSH(value); + } + else { + PyObject *exc_type = Py_NewRef(Py_TYPE(exc_value)); + PyObject *exc_traceback = PyException_GetTraceback(exc_value); + _PyErr_Restore(tstate, exc_type, Py_NewRef(exc_value), exc_traceback); + goto exception_unwind; + } + } + + inst(LOAD_ASSERTION_ERROR, ( -- value)) { + value = Py_NewRef(PyExc_AssertionError); + } + + inst(LOAD_BUILD_CLASS, ( -- bc)) { + if (PyDict_CheckExact(BUILTINS())) { + bc = _PyDict_GetItemWithError(BUILTINS(), + &_Py_ID(__build_class__)); + if (bc == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_NameError, + "__build_class__ not found"); + } + ERROR_IF(true, error); + } + Py_INCREF(bc); + } + else { + bc = PyObject_GetItem(BUILTINS(), &_Py_ID(__build_class__)); + if (bc == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) + _PyErr_SetString(tstate, PyExc_NameError, + "__build_class__ not found"); + ERROR_IF(true, error); + } + } + } + + inst(STORE_NAME, (v -- )) { + PyObject *name = GETITEM(names, oparg); + PyObject *ns = LOCALS(); + int err; + if (ns == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals found when storing %R", name); + DECREF_INPUTS(); + ERROR_IF(true, error); + } + if (PyDict_CheckExact(ns)) + err = PyDict_SetItem(ns, name, v); + else + err = PyObject_SetItem(ns, name, v); + DECREF_INPUTS(); + ERROR_IF(err, error); + } + + inst(DELETE_NAME, (--)) { + PyObject *name = GETITEM(names, oparg); + PyObject *ns = LOCALS(); + int err; + if (ns == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals when deleting %R", name); + goto error; + } + err = PyObject_DelItem(ns, name); + // Can't use ERROR_IF here. + if (err != 0) { + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, + name); + goto error; + } + } + + // stack effect: (__0 -- __array[oparg]) + inst(UNPACK_SEQUENCE) { + #if ENABLE_SPECIALIZATION + _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + assert(cframe.use_tracing == 0); + PyObject *seq = TOP(); + next_instr--; + _Py_Specialize_UnpackSequence(seq, next_instr, oparg); + DISPATCH_SAME_OPARG(); + } + STAT_INC(UNPACK_SEQUENCE, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + PyObject *seq = POP(); + PyObject **top = stack_pointer + oparg; + if (!unpack_iterable(tstate, seq, oparg, -1, top)) { + Py_DECREF(seq); + goto error; + } + STACK_GROW(oparg); + Py_DECREF(seq); + JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); + } + + // stack effect: (__0 -- __array[oparg]) + inst(UNPACK_SEQUENCE_TWO_TUPLE) { + PyObject *seq = TOP(); + DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); + DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE); + STAT_INC(UNPACK_SEQUENCE, hit); + SET_TOP(Py_NewRef(PyTuple_GET_ITEM(seq, 1))); + PUSH(Py_NewRef(PyTuple_GET_ITEM(seq, 0))); + Py_DECREF(seq); + JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); + } + + // stack effect: (__0 -- __array[oparg]) + inst(UNPACK_SEQUENCE_TUPLE) { + PyObject *seq = TOP(); + DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); + DEOPT_IF(PyTuple_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); + STAT_INC(UNPACK_SEQUENCE, hit); + STACK_SHRINK(1); + PyObject **items = _PyTuple_ITEMS(seq); + while (oparg--) { + PUSH(Py_NewRef(items[oparg])); + } + Py_DECREF(seq); + JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); + } + + // stack effect: (__0 -- __array[oparg]) + inst(UNPACK_SEQUENCE_LIST) { + PyObject *seq = TOP(); + DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE); + DEOPT_IF(PyList_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); + STAT_INC(UNPACK_SEQUENCE, hit); + STACK_SHRINK(1); + PyObject **items = _PyList_ITEMS(seq); + while (oparg--) { + PUSH(Py_NewRef(items[oparg])); + } + Py_DECREF(seq); + JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); + } + + // error: UNPACK_EX has irregular stack effect + inst(UNPACK_EX) { + int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); + PyObject *seq = POP(); + PyObject **top = stack_pointer + totalargs; + if (!unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, top)) { + Py_DECREF(seq); + goto error; + } + STACK_GROW(totalargs); + Py_DECREF(seq); + } + + family(store_attr) = { + STORE_ATTR, + STORE_ATTR_INSTANCE_VALUE, + STORE_ATTR_SLOT, + STORE_ATTR_WITH_HINT, + }; + + inst(STORE_ATTR, (counter/1, unused/3, v, owner --)) { + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + assert(cframe.use_tracing == 0); + PyObject *name = GETITEM(names, oparg); + next_instr--; + _Py_Specialize_StoreAttr(owner, next_instr, name); + DISPATCH_SAME_OPARG(); + } + STAT_INC(STORE_ATTR, deferred); + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #else + (void)counter; // Unused. + #endif /* ENABLE_SPECIALIZATION */ + PyObject *name = GETITEM(names, oparg); + int err = PyObject_SetAttr(owner, name, v); + Py_DECREF(v); + Py_DECREF(owner); + ERROR_IF(err, error); + } + + inst(DELETE_ATTR, (owner --)) { + PyObject *name = GETITEM(names, oparg); + int err = PyObject_SetAttr(owner, name, (PyObject *)NULL); + Py_DECREF(owner); + ERROR_IF(err, error); + } + + inst(STORE_GLOBAL, (v --)) { + PyObject *name = GETITEM(names, oparg); + int err = PyDict_SetItem(GLOBALS(), name, v); + Py_DECREF(v); + ERROR_IF(err, error); + } + + inst(DELETE_GLOBAL, (--)) { + PyObject *name = GETITEM(names, oparg); + int err; + err = PyDict_DelItem(GLOBALS(), name); + // Can't use ERROR_IF here. + if (err != 0) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + } + + inst(LOAD_NAME, ( -- v)) { + PyObject *name = GETITEM(names, oparg); + PyObject *locals = LOCALS(); + if (locals == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals when loading %R", name); + goto error; + } + if (PyDict_CheckExact(locals)) { + v = PyDict_GetItemWithError(locals, name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + } + else { + v = PyObject_GetItem(locals, name); + if (v == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) + goto error; + _PyErr_Clear(tstate); + } + } + if (v == NULL) { + v = PyDict_GetItemWithError(GLOBALS(), name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + else { + if (PyDict_CheckExact(BUILTINS())) { + v = PyDict_GetItemWithError(BUILTINS(), name); + if (v == NULL) { + if (!_PyErr_Occurred(tstate)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + Py_INCREF(v); + } + else { + v = PyObject_GetItem(BUILTINS(), name); + if (v == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + } + } + } + } + + // error: LOAD_GLOBAL has irregular stack effect + inst(LOAD_GLOBAL) { + #if ENABLE_SPECIALIZATION + _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + assert(cframe.use_tracing == 0); + PyObject *name = GETITEM(names, oparg>>1); + next_instr--; + _Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name); + DISPATCH_SAME_OPARG(); + } + STAT_INC(LOAD_GLOBAL, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + int push_null = oparg & 1; + PEEK(0) = NULL; + PyObject *name = GETITEM(names, oparg>>1); + PyObject *v; + if (PyDict_CheckExact(GLOBALS()) + && PyDict_CheckExact(BUILTINS())) + { + v = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(), + (PyDictObject *)BUILTINS(), + name); + if (v == NULL) { + if (!_PyErr_Occurred(tstate)) { + /* _PyDict_LoadGlobal() returns NULL without raising + * an exception if the key doesn't exist */ + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + Py_INCREF(v); + } + else { + /* Slow-path if globals or builtins is not a dict */ + + /* namespace 1: globals */ + v = PyObject_GetItem(GLOBALS(), name); + if (v == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + goto error; + } + _PyErr_Clear(tstate); + + /* namespace 2: builtins */ + v = PyObject_GetItem(BUILTINS(), name); + if (v == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + } + } + /* Skip over inline cache */ + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); + STACK_GROW(push_null); + PUSH(v); + } + + // error: LOAD_GLOBAL has irregular stack effect + inst(LOAD_GLOBAL_MODULE) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); + PyDictObject *dict = (PyDictObject *)GLOBALS(); + _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; + uint32_t version = read_u32(cache->module_keys_version); + DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); + assert(DK_IS_UNICODE(dict->ma_keys)); + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); + PyObject *res = entries[cache->index].me_value; + DEOPT_IF(res == NULL, LOAD_GLOBAL); + int push_null = oparg & 1; + PEEK(0) = NULL; + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); + STAT_INC(LOAD_GLOBAL, hit); + STACK_GROW(push_null+1); + SET_TOP(Py_NewRef(res)); + } + + // error: LOAD_GLOBAL has irregular stack effect + inst(LOAD_GLOBAL_BUILTIN) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); + DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL); + PyDictObject *mdict = (PyDictObject *)GLOBALS(); + PyDictObject *bdict = (PyDictObject *)BUILTINS(); + _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; + uint32_t mod_version = read_u32(cache->module_keys_version); + uint16_t bltn_version = cache->builtin_keys_version; + DEOPT_IF(mdict->ma_keys->dk_version != mod_version, LOAD_GLOBAL); + DEOPT_IF(bdict->ma_keys->dk_version != bltn_version, LOAD_GLOBAL); + assert(DK_IS_UNICODE(bdict->ma_keys)); + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); + PyObject *res = entries[cache->index].me_value; + DEOPT_IF(res == NULL, LOAD_GLOBAL); + int push_null = oparg & 1; + PEEK(0) = NULL; + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); + STAT_INC(LOAD_GLOBAL, hit); + STACK_GROW(push_null+1); + SET_TOP(Py_NewRef(res)); + } + + inst(DELETE_FAST, (--)) { + PyObject *v = GETLOCAL(oparg); + ERROR_IF(v == NULL, unbound_local_error); + SETLOCAL(oparg, NULL); + } + + inst(MAKE_CELL, (--)) { + // "initial" is probably NULL but not if it's an arg (or set + // via PyFrame_LocalsToFast() before MAKE_CELL has run). + PyObject *initial = GETLOCAL(oparg); + PyObject *cell = PyCell_New(initial); + if (cell == NULL) { + goto resume_with_error; + } + SETLOCAL(oparg, cell); + } + + inst(DELETE_DEREF, (--)) { + PyObject *cell = GETLOCAL(oparg); + PyObject *oldobj = PyCell_GET(cell); + // Can't use ERROR_IF here. + // Fortunately we don't need its superpower. + if (oldobj == NULL) { + format_exc_unbound(tstate, frame->f_code, oparg); + goto error; + } + PyCell_SET(cell, NULL); + Py_DECREF(oldobj); + } + + inst(LOAD_CLASSDEREF, ( -- value)) { + PyObject *name, *locals = LOCALS(); + assert(locals); + assert(oparg >= 0 && oparg < frame->f_code->co_nlocalsplus); + name = PyTuple_GET_ITEM(frame->f_code->co_localsplusnames, oparg); + if (PyDict_CheckExact(locals)) { + value = PyDict_GetItemWithError(locals, name); + if (value != NULL) { + Py_INCREF(value); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + } + else { + value = PyObject_GetItem(locals, name); + if (value == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + goto error; + } + _PyErr_Clear(tstate); + } + } + if (!value) { + PyObject *cell = GETLOCAL(oparg); + value = PyCell_GET(cell); + if (value == NULL) { + format_exc_unbound(tstate, frame->f_code, oparg); + goto error; + } + Py_INCREF(value); + } + } + + inst(LOAD_DEREF, ( -- value)) { + PyObject *cell = GETLOCAL(oparg); + value = PyCell_GET(cell); + if (value == NULL) { + format_exc_unbound(tstate, frame->f_code, oparg); + ERROR_IF(true, error); + } + Py_INCREF(value); + } + + inst(STORE_DEREF, (v --)) { + PyObject *cell = GETLOCAL(oparg); + PyObject *oldobj = PyCell_GET(cell); + PyCell_SET(cell, v); + Py_XDECREF(oldobj); + } + + inst(COPY_FREE_VARS, (--)) { + /* Copy closure variables to free variables */ + PyCodeObject *co = frame->f_code; + assert(PyFunction_Check(frame->f_funcobj)); + PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure; + assert(oparg == co->co_nfreevars); + int offset = co->co_nlocalsplus - oparg; + for (int i = 0; i < oparg; ++i) { + PyObject *o = PyTuple_GET_ITEM(closure, i); + frame->localsplus[offset + i] = Py_NewRef(o); + } + } + + inst(BUILD_STRING, (pieces[oparg] -- str)) { + str = _PyUnicode_JoinArray(&_Py_STR(empty), pieces, oparg); + for (int i = 0; i < oparg; i++) { + Py_DECREF(pieces[i]); + } + ERROR_IF(str == NULL, error); + } + + inst(BUILD_TUPLE, (values[oparg] -- tup)) { + tup = _PyTuple_FromArraySteal(values, oparg); + ERROR_IF(tup == NULL, error); + } + + inst(BUILD_LIST, (values[oparg] -- list)) { + list = _PyList_FromArraySteal(values, oparg); + ERROR_IF(list == NULL, error); + } + + inst(LIST_EXTEND, (list, unused[oparg-1], iterable -- list, unused[oparg-1])) { + PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); + if (none_val == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && + (Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable))) + { + _PyErr_Clear(tstate); + _PyErr_Format(tstate, PyExc_TypeError, + "Value after * must be an iterable, not %.200s", + Py_TYPE(iterable)->tp_name); + } + DECREF_INPUTS(); + ERROR_IF(true, error); + } + Py_DECREF(none_val); + DECREF_INPUTS(); + } + + inst(SET_UPDATE, (set, unused[oparg-1], iterable -- set, unused[oparg-1])) { + int err = _PySet_Update(set, iterable); + DECREF_INPUTS(); + ERROR_IF(err < 0, error); + } + + inst(BUILD_SET, (values[oparg] -- set)) { + set = PySet_New(NULL); + int err = 0; + for (int i = 0; i < oparg; i++) { + PyObject *item = values[i]; + if (err == 0) + err = PySet_Add(set, item); + Py_DECREF(item); + } + if (err != 0) { + Py_DECREF(set); + ERROR_IF(true, error); + } + } + + inst(BUILD_MAP, (values[oparg*2] -- map)) { + map = _PyDict_FromItems( + values, 2, + values+1, 2, + oparg); + if (map == NULL) + goto error; + + for (int i = 0; i < oparg; i++) { + Py_DECREF(values[i*2]); + Py_DECREF(values[i*2+1]); + } + ERROR_IF(map == NULL, error); + } + + inst(SETUP_ANNOTATIONS, (--)) { + int err; + PyObject *ann_dict; + if (LOCALS() == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals found when setting up annotations"); + ERROR_IF(true, error); + } + /* check if __annotations__ in locals()... */ + if (PyDict_CheckExact(LOCALS())) { + ann_dict = _PyDict_GetItemWithError(LOCALS(), + &_Py_ID(__annotations__)); + if (ann_dict == NULL) { + ERROR_IF(_PyErr_Occurred(tstate), error); + /* ...if not, create a new one */ + ann_dict = PyDict_New(); + ERROR_IF(ann_dict == NULL, error); + err = PyDict_SetItem(LOCALS(), &_Py_ID(__annotations__), + ann_dict); + Py_DECREF(ann_dict); + ERROR_IF(err, error); + } + } + else { + /* do the same if locals() is not a dict */ + ann_dict = PyObject_GetItem(LOCALS(), &_Py_ID(__annotations__)); + if (ann_dict == NULL) { + ERROR_IF(!_PyErr_ExceptionMatches(tstate, PyExc_KeyError), error); + _PyErr_Clear(tstate); + ann_dict = PyDict_New(); + ERROR_IF(ann_dict == NULL, error); + err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__), + ann_dict); + Py_DECREF(ann_dict); + ERROR_IF(err, error); + } + else { + Py_DECREF(ann_dict); + } + } + } + + inst(BUILD_CONST_KEY_MAP, (values[oparg], keys -- map)) { + if (!PyTuple_CheckExact(keys) || + PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { + _PyErr_SetString(tstate, PyExc_SystemError, + "bad BUILD_CONST_KEY_MAP keys argument"); + goto error; // Pop the keys and values. + } + map = _PyDict_FromItems( + &PyTuple_GET_ITEM(keys, 0), 1, + values, 1, oparg); + Py_DECREF(keys); + for (int i = 0; i < oparg; i++) { + Py_DECREF(values[i]); + } + ERROR_IF(map == NULL, error); + } + + inst(DICT_UPDATE, (update --)) { + PyObject *dict = PEEK(oparg + 1); // update is still on the stack + if (PyDict_Update(dict, update) < 0) { + if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object is not a mapping", + Py_TYPE(update)->tp_name); + } + DECREF_INPUTS(); + ERROR_IF(true, error); + } + DECREF_INPUTS(); + } + + inst(DICT_MERGE, (update --)) { + PyObject *dict = PEEK(oparg + 1); // update is still on the stack + + if (_PyDict_MergeEx(dict, update, 2) < 0) { + format_kwargs_error(tstate, PEEK(3 + oparg), update); + DECREF_INPUTS(); + ERROR_IF(true, error); + } + DECREF_INPUTS(); + PREDICT(CALL_FUNCTION_EX); + } + + inst(MAP_ADD, (key, value --)) { + PyObject *dict = PEEK(oparg + 2); // key, value are still on the stack + assert(PyDict_CheckExact(dict)); + /* dict[key] = value */ + // Do not DECREF INPUTS because the function steals the references + ERROR_IF(_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0, error); + PREDICT(JUMP_BACKWARD); + } + + inst(LOAD_ATTR, (unused/9, owner -- res2 if (oparg & 1), res)) { + #if ENABLE_SPECIALIZATION + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + assert(cframe.use_tracing == 0); + PyObject *name = GETITEM(names, oparg>>1); + next_instr--; + _Py_Specialize_LoadAttr(owner, next_instr, name); + DISPATCH_SAME_OPARG(); + } + STAT_INC(LOAD_ATTR, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + PyObject *name = GETITEM(names, oparg >> 1); + if (oparg & 1) { + /* Designed to work in tandem with CALL, pushes two values. */ + PyObject* meth = NULL; + if (_PyObject_GetMethod(owner, name, &meth)) { + /* We can bypass temporary bound method object. + meth is unbound method and obj is self. + + meth | self | arg1 | ... | argN + */ + assert(meth != NULL); // No errors on this branch + res2 = meth; + res = owner; // Transfer ownership + } + else { + /* meth is not an unbound method (but a regular attr, or + something was returned by a descriptor protocol). Set + the second element of the stack to NULL, to signal + CALL that it's not a method call. + + NULL | meth | arg1 | ... | argN + */ + Py_DECREF(owner); + ERROR_IF(meth == NULL, error); + res2 = NULL; + res = meth; + } + } + else { + /* Classic, pushes one value. */ + res = PyObject_GetAttr(owner, name); + Py_DECREF(owner); + ERROR_IF(res == NULL, error); + } + } + + // error: LOAD_ATTR has irregular stack effect + inst(LOAD_ATTR_INSTANCE_VALUE) { + assert(cframe.use_tracing == 0); + PyObject *owner = TOP(); + PyObject *res; + PyTypeObject *tp = Py_TYPE(owner); + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + uint32_t type_version = read_u32(cache->version); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + assert(tp->tp_dictoffset < 0); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + res = _PyDictOrValues_GetValues(dorv)->values[cache->index]; + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + SET_TOP(NULL); + STACK_GROW((oparg & 1)); + SET_TOP(res); + Py_DECREF(owner); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + } + + // error: LOAD_ATTR has irregular stack effect + inst(LOAD_ATTR_MODULE) { + assert(cframe.use_tracing == 0); + PyObject *owner = TOP(); + PyObject *res; + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR); + PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; + assert(dict != NULL); + DEOPT_IF(dict->ma_keys->dk_version != read_u32(cache->version), + LOAD_ATTR); + assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); + assert(cache->index < dict->ma_keys->dk_nentries); + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + cache->index; + res = ep->me_value; + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + SET_TOP(NULL); + STACK_GROW((oparg & 1)); + SET_TOP(res); + Py_DECREF(owner); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + } + + // error: LOAD_ATTR has irregular stack effect + inst(LOAD_ATTR_WITH_HINT) { + assert(cframe.use_tracing == 0); + PyObject *owner = TOP(); + PyObject *res; + PyTypeObject *tp = Py_TYPE(owner); + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + uint32_t type_version = read_u32(cache->version); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + DEOPT_IF(dict == NULL, LOAD_ATTR); + assert(PyDict_CheckExact((PyObject *)dict)); + PyObject *name = GETITEM(names, oparg>>1); + uint16_t hint = cache->index; + DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR); + if (DK_IS_UNICODE(dict->ma_keys)) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, LOAD_ATTR); + res = ep->me_value; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, LOAD_ATTR); + res = ep->me_value; + } + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + SET_TOP(NULL); + STACK_GROW((oparg & 1)); + SET_TOP(res); + Py_DECREF(owner); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + } + + // error: LOAD_ATTR has irregular stack effect + inst(LOAD_ATTR_SLOT) { + assert(cframe.use_tracing == 0); + PyObject *owner = TOP(); + PyObject *res; + PyTypeObject *tp = Py_TYPE(owner); + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + uint32_t type_version = read_u32(cache->version); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + char *addr = (char *)owner + cache->index; + res = *(PyObject **)addr; + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + SET_TOP(NULL); + STACK_GROW((oparg & 1)); + SET_TOP(res); + Py_DECREF(owner); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + } + + // error: LOAD_ATTR has irregular stack effect + inst(LOAD_ATTR_CLASS) { + assert(cframe.use_tracing == 0); + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; + + PyObject *cls = TOP(); + DEOPT_IF(!PyType_Check(cls), LOAD_ATTR); + uint32_t type_version = read_u32(cache->type_version); + DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != type_version, + LOAD_ATTR); + assert(type_version != 0); + + STAT_INC(LOAD_ATTR, hit); + PyObject *res = read_obj(cache->descr); + assert(res != NULL); + Py_INCREF(res); + SET_TOP(NULL); + STACK_GROW((oparg & 1)); + SET_TOP(res); + Py_DECREF(cls); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + } + + // error: LOAD_ATTR has irregular stack effect + inst(LOAD_ATTR_PROPERTY) { + assert(cframe.use_tracing == 0); + DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; + + PyObject *owner = TOP(); + PyTypeObject *cls = Py_TYPE(owner); + uint32_t type_version = read_u32(cache->type_version); + DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); + assert(type_version != 0); + PyObject *fget = read_obj(cache->descr); + assert(Py_IS_TYPE(fget, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)fget; + uint32_t func_version = read_u32(cache->keys_version); + assert(func_version != 0); + DEOPT_IF(f->func_version != func_version, LOAD_ATTR); + PyCodeObject *code = (PyCodeObject *)f->func_code; + assert(code->co_argcount == 1); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(fget); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 1); + SET_TOP(NULL); + int shrink_stack = !(oparg & 1); + STACK_SHRINK(shrink_stack); + new_frame->localsplus[0] = owner; + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + DISPATCH_INLINED(new_frame); + } + + // error: LOAD_ATTR has irregular stack effect + inst(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN) { + assert(cframe.use_tracing == 0); + DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; + PyObject *owner = TOP(); + PyTypeObject *cls = Py_TYPE(owner); + uint32_t type_version = read_u32(cache->type_version); + DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); + assert(type_version != 0); + PyObject *getattribute = read_obj(cache->descr); + assert(Py_IS_TYPE(getattribute, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)getattribute; + uint32_t func_version = read_u32(cache->keys_version); + assert(func_version != 0); + DEOPT_IF(f->func_version != func_version, LOAD_ATTR); + PyCodeObject *code = (PyCodeObject *)f->func_code; + assert(code->co_argcount == 2); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + + PyObject *name = GETITEM(names, oparg >> 1); + Py_INCREF(f); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 2); + SET_TOP(NULL); + int shrink_stack = !(oparg & 1); + STACK_SHRINK(shrink_stack); + new_frame->localsplus[0] = owner; + new_frame->localsplus[1] = Py_NewRef(name); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + DISPATCH_INLINED(new_frame); + } + + inst(STORE_ATTR_INSTANCE_VALUE, (unused/1, type_version/2, index/1, value, owner --)) { + assert(cframe.use_tracing == 0); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), STORE_ATTR); + STAT_INC(STORE_ATTR, hit); + PyDictValues *values = _PyDictOrValues_GetValues(dorv); + PyObject *old_value = values->values[index]; + values->values[index] = value; + if (old_value == NULL) { + _PyDictValues_AddToInsertionOrder(values, index); + } + else { + Py_DECREF(old_value); + } + Py_DECREF(owner); + } + + inst(STORE_ATTR_WITH_HINT, (unused/1, type_version/2, hint/1, value, owner --)) { + assert(cframe.use_tracing == 0); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(_PyDictOrValues_IsValues(dorv), STORE_ATTR); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + DEOPT_IF(dict == NULL, STORE_ATTR); + assert(PyDict_CheckExact((PyObject *)dict)); + PyObject *name = GETITEM(names, oparg); + DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, STORE_ATTR); + PyObject *old_value; + uint64_t new_version; + if (DK_IS_UNICODE(dict->ma_keys)) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, STORE_ATTR); + old_value = ep->me_value; + DEOPT_IF(old_value == NULL, STORE_ATTR); + new_version = _PyDict_NotifyEvent(PyDict_EVENT_MODIFIED, dict, name, value); + ep->me_value = value; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, STORE_ATTR); + old_value = ep->me_value; + DEOPT_IF(old_value == NULL, STORE_ATTR); + new_version = _PyDict_NotifyEvent(PyDict_EVENT_MODIFIED, dict, name, value); + ep->me_value = value; + } + Py_DECREF(old_value); + STAT_INC(STORE_ATTR, hit); + /* Ensure dict is GC tracked if it needs to be */ + if (!_PyObject_GC_IS_TRACKED(dict) && _PyObject_GC_MAY_BE_TRACKED(value)) { + _PyObject_GC_TRACK(dict); + } + /* PEP 509 */ + dict->ma_version_tag = new_version; + Py_DECREF(owner); + } + + inst(STORE_ATTR_SLOT, (unused/1, type_version/2, index/1, value, owner --)) { + assert(cframe.use_tracing == 0); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + char *addr = (char *)owner + index; + STAT_INC(STORE_ATTR, hit); + PyObject *old_value = *(PyObject **)addr; + *(PyObject **)addr = value; + Py_XDECREF(old_value); + Py_DECREF(owner); + } + + inst(COMPARE_OP, (unused/1, left, right -- res)) { + STAT_INC(COMPARE_OP, deferred); + assert((oparg >> 4) <= Py_GE); + res = PyObject_RichCompare(left, right, oparg>>4); + Py_DECREF(left); + Py_DECREF(right); + ERROR_IF(res == NULL, error); + } + + family(compare_and_branch) = { + COMPARE_AND_BRANCH, + COMPARE_AND_BRANCH_FLOAT, + COMPARE_AND_BRANCH_INT, + COMPARE_AND_BRANCH_STR, + }; + + inst(COMPARE_AND_BRANCH, (unused/2, left, right -- )) { + #if ENABLE_SPECIALIZATION + _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + assert(cframe.use_tracing == 0); + next_instr--; + _Py_Specialize_CompareAndBranch(left, right, next_instr, oparg); + DISPATCH_SAME_OPARG(); + } + STAT_INC(COMPARE_AND_BRANCH, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + assert((oparg >> 4) <= Py_GE); + PyObject *cond = PyObject_RichCompare(left, right, oparg>>4); + Py_DECREF(left); + Py_DECREF(right); + ERROR_IF(cond == NULL, error); + assert(_Py_OPCODE(next_instr[1]) == POP_JUMP_IF_FALSE || + _Py_OPCODE(next_instr[1]) == POP_JUMP_IF_TRUE); + bool jump_on_true = _Py_OPCODE(next_instr[1]) == POP_JUMP_IF_TRUE; + int offset = _Py_OPARG(next_instr[1]); + int err = PyObject_IsTrue(cond); + Py_DECREF(cond); + if (err < 0) { + goto error; + } + if (jump_on_true == (err != 0)) { + JUMPBY(offset); + } + } + + inst(COMPARE_AND_BRANCH_FLOAT, (unused/2, left, right -- )) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_AND_BRANCH); + DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_AND_BRANCH); + STAT_INC(COMPARE_AND_BRANCH, hit); + double dleft = PyFloat_AS_DOUBLE(left); + double dright = PyFloat_AS_DOUBLE(right); + // 1 if NaN, 2 if <, 4 if >, 8 if ==; this matches low four bits of the oparg + int sign_ish = COMPARISON_BIT(dleft, dright); + _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); + _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); + if (sign_ish & oparg) { + int offset = _Py_OPARG(next_instr[1]); + JUMPBY(offset); + } + } + + // Similar to COMPARE_AND_BRANCH_FLOAT + inst(COMPARE_AND_BRANCH_INT, (unused/2, left, right -- )) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyLong_CheckExact(left), COMPARE_AND_BRANCH); + DEOPT_IF(!PyLong_CheckExact(right), COMPARE_AND_BRANCH); + DEOPT_IF((size_t)(Py_SIZE(left) + 1) > 2, COMPARE_AND_BRANCH); + DEOPT_IF((size_t)(Py_SIZE(right) + 1) > 2, COMPARE_AND_BRANCH); + STAT_INC(COMPARE_AND_BRANCH, hit); + assert(Py_ABS(Py_SIZE(left)) <= 1 && Py_ABS(Py_SIZE(right)) <= 1); + Py_ssize_t ileft = Py_SIZE(left) * ((PyLongObject *)left)->ob_digit[0]; + Py_ssize_t iright = Py_SIZE(right) * ((PyLongObject *)right)->ob_digit[0]; + // 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg + int sign_ish = COMPARISON_BIT(ileft, iright); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + if (sign_ish & oparg) { + int offset = _Py_OPARG(next_instr[1]); + JUMPBY(offset); + } + } + + // Similar to COMPARE_AND_BRANCH_FLOAT, but for ==, != only + inst(COMPARE_AND_BRANCH_STR, (unused/2, left, right -- )) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_AND_BRANCH); + DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_AND_BRANCH); + STAT_INC(COMPARE_AND_BRANCH, hit); + int res = _PyUnicode_Equal(left, right); + assert((oparg >>4) == Py_EQ || (oparg >>4) == Py_NE); + _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); + _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); + assert(res == 0 || res == 1); + assert((oparg & 0xf) == COMPARISON_NOT_EQUALS || (oparg & 0xf) == COMPARISON_EQUALS); + assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS); + if ((res + COMPARISON_NOT_EQUALS) & oparg) { + int offset = _Py_OPARG(next_instr[1]); + JUMPBY(offset); + } + } + + inst(IS_OP, (left, right -- b)) { + int res = Py_Is(left, right) ^ oparg; + DECREF_INPUTS(); + b = Py_NewRef(res ? Py_True : Py_False); + } + + inst(CONTAINS_OP, (left, right -- b)) { + int res = PySequence_Contains(right, left); + DECREF_INPUTS(); + ERROR_IF(res < 0, error); + b = Py_NewRef((res^oparg) ? Py_True : Py_False); + } + + inst(CHECK_EG_MATCH, (exc_value, match_type -- rest, match)) { + if (check_except_star_type_valid(tstate, match_type) < 0) { + DECREF_INPUTS(); + ERROR_IF(true, error); + } + + match = NULL; + rest = NULL; + int res = exception_group_match(exc_value, match_type, + &match, &rest); + DECREF_INPUTS(); + ERROR_IF(res < 0, error); + + assert((match == NULL) == (rest == NULL)); + ERROR_IF(match == NULL, error); + + if (!Py_IsNone(match)) { + PyErr_SetExcInfo(NULL, Py_NewRef(match), NULL); + } + } + + inst(CHECK_EXC_MATCH, (left, right -- left, b)) { + assert(PyExceptionInstance_Check(left)); + if (check_except_type_valid(tstate, right) < 0) { + DECREF_INPUTS(); + ERROR_IF(true, error); + } + + int res = PyErr_GivenExceptionMatches(left, right); + DECREF_INPUTS(); + b = Py_NewRef(res ? Py_True : Py_False); + } + + inst(IMPORT_NAME, (level, fromlist -- res)) { + PyObject *name = GETITEM(names, oparg); + res = import_name(tstate, frame, name, fromlist, level); + DECREF_INPUTS(); + ERROR_IF(res == NULL, error); + } + + inst(IMPORT_FROM, (from -- from, res)) { + PyObject *name = GETITEM(names, oparg); + res = import_from(tstate, from, name); + ERROR_IF(res == NULL, error); + } + + inst(JUMP_FORWARD, (--)) { + JUMPBY(oparg); + } + + inst(JUMP_BACKWARD, (--)) { + assert(oparg < INSTR_OFFSET()); + JUMPBY(-oparg); + CHECK_EVAL_BREAKER(); + } + + // stack effect: (__0 -- ) + inst(POP_JUMP_IF_FALSE) { + PyObject *cond = POP(); + if (Py_IsTrue(cond)) { + _Py_DECREF_NO_DEALLOC(cond); + } + else if (Py_IsFalse(cond)) { + _Py_DECREF_NO_DEALLOC(cond); + JUMPBY(oparg); + } + else { + int err = PyObject_IsTrue(cond); + Py_DECREF(cond); + if (err > 0) + ; + else if (err == 0) { + JUMPBY(oparg); + } + else + goto error; + } + } + + // stack effect: (__0 -- ) + inst(POP_JUMP_IF_TRUE) { + PyObject *cond = POP(); + if (Py_IsFalse(cond)) { + _Py_DECREF_NO_DEALLOC(cond); + } + else if (Py_IsTrue(cond)) { + _Py_DECREF_NO_DEALLOC(cond); + JUMPBY(oparg); + } + else { + int err = PyObject_IsTrue(cond); + Py_DECREF(cond); + if (err > 0) { + JUMPBY(oparg); + } + else if (err == 0) + ; + else + goto error; + } + } + + // stack effect: (__0 -- ) + inst(POP_JUMP_IF_NOT_NONE) { + PyObject *value = POP(); + if (!Py_IsNone(value)) { + JUMPBY(oparg); + } + Py_DECREF(value); + } + + // stack effect: (__0 -- ) + inst(POP_JUMP_IF_NONE) { + PyObject *value = POP(); + if (Py_IsNone(value)) { + _Py_DECREF_NO_DEALLOC(value); + JUMPBY(oparg); + } + else { + Py_DECREF(value); + } + } + + // error: JUMP_IF_FALSE_OR_POP stack effect depends on jump flag + inst(JUMP_IF_FALSE_OR_POP) { + PyObject *cond = TOP(); + int err; + if (Py_IsTrue(cond)) { + STACK_SHRINK(1); + _Py_DECREF_NO_DEALLOC(cond); + } + else if (Py_IsFalse(cond)) { + JUMPBY(oparg); + } + else { + err = PyObject_IsTrue(cond); + if (err > 0) { + STACK_SHRINK(1); + Py_DECREF(cond); + } + else if (err == 0) { + JUMPBY(oparg); + } + else { + goto error; + } + } + } + + // error: JUMP_IF_TRUE_OR_POP stack effect depends on jump flag + inst(JUMP_IF_TRUE_OR_POP) { + PyObject *cond = TOP(); + int err; + if (Py_IsFalse(cond)) { + STACK_SHRINK(1); + _Py_DECREF_NO_DEALLOC(cond); + } + else if (Py_IsTrue(cond)) { + JUMPBY(oparg); + } + else { + err = PyObject_IsTrue(cond); + if (err > 0) { + JUMPBY(oparg); + } + else if (err == 0) { + STACK_SHRINK(1); + Py_DECREF(cond); + } + else { + goto error; + } + } + } + + // stack effect: ( -- ) + inst(JUMP_BACKWARD_NO_INTERRUPT) { + /* This bytecode is used in the `yield from` or `await` loop. + * If there is an interrupt, we want it handled in the innermost + * generator or coroutine, so we deliberately do not check it here. + * (see bpo-30039). + */ + JUMPBY(-oparg); + } + + // stack effect: ( -- __0) + inst(GET_LEN) { + // PUSH(len(TOS)) + Py_ssize_t len_i = PyObject_Length(TOP()); + if (len_i < 0) { + goto error; + } + PyObject *len_o = PyLong_FromSsize_t(len_i); + if (len_o == NULL) { + goto error; + } + PUSH(len_o); + } + + inst(MATCH_CLASS, (subject, type, names -- attrs)) { + // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or + // None on failure. + assert(PyTuple_CheckExact(names)); + attrs = match_class(tstate, subject, type, oparg, names); + DECREF_INPUTS(); + if (attrs) { + assert(PyTuple_CheckExact(attrs)); // Success! + } + else { + ERROR_IF(_PyErr_Occurred(tstate), error); // Error! + attrs = Py_NewRef(Py_None); // Failure! + } + } + + inst(MATCH_MAPPING, (subject -- subject, res)) { + int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; + res = Py_NewRef(match ? Py_True : Py_False); + PREDICT(POP_JUMP_IF_FALSE); + } + + inst(MATCH_SEQUENCE, (subject -- subject, res)) { + int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; + res = Py_NewRef(match ? Py_True : Py_False); + PREDICT(POP_JUMP_IF_FALSE); + } + + inst(MATCH_KEYS, (subject, keys -- subject, keys, values_or_none)) { + // On successful match, PUSH(values). Otherwise, PUSH(None). + values_or_none = match_keys(tstate, subject, keys); + ERROR_IF(values_or_none == NULL, error); + } + + // stack effect: ( -- ) + inst(GET_ITER) { + /* before: [obj]; after [getiter(obj)] */ + PyObject *iterable = TOP(); + PyObject *iter = PyObject_GetIter(iterable); + Py_DECREF(iterable); + SET_TOP(iter); + if (iter == NULL) + goto error; + } + + // stack effect: ( -- ) + inst(GET_YIELD_FROM_ITER) { + /* before: [obj]; after [getiter(obj)] */ + PyObject *iterable = TOP(); + PyObject *iter; + if (PyCoro_CheckExact(iterable)) { + /* `iterable` is a coroutine */ + if (!(frame->f_code->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) { + /* and it is used in a 'yield from' expression of a + regular generator. */ + Py_DECREF(iterable); + SET_TOP(NULL); + _PyErr_SetString(tstate, PyExc_TypeError, + "cannot 'yield from' a coroutine object " + "in a non-coroutine generator"); + goto error; + } + } + else if (!PyGen_CheckExact(iterable)) { + /* `iterable` is not a generator. */ + iter = PyObject_GetIter(iterable); + Py_DECREF(iterable); + SET_TOP(iter); + if (iter == NULL) + goto error; + } + PREDICT(LOAD_CONST); + } + + // stack effect: ( -- __0) + inst(FOR_ITER) { + #if ENABLE_SPECIALIZATION + _PyForIterCache *cache = (_PyForIterCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + assert(cframe.use_tracing == 0); + next_instr--; + _Py_Specialize_ForIter(TOP(), next_instr, oparg); + DISPATCH_SAME_OPARG(); + } + STAT_INC(FOR_ITER, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + /* before: [iter]; after: [iter, iter()] *or* [] */ + PyObject *iter = TOP(); + PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter); + if (next != NULL) { + PUSH(next); + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER); + } + else { + if (_PyErr_Occurred(tstate)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + goto error; + } + else if (tstate->c_tracefunc != NULL) { + call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, frame); + } + _PyErr_Clear(tstate); + } + /* iterator ended normally */ + assert(_Py_OPCODE(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg]) == END_FOR); + STACK_SHRINK(1); + Py_DECREF(iter); + /* Skip END_FOR */ + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + } + } + + // stack effect: ( -- __0) + inst(FOR_ITER_LIST) { + assert(cframe.use_tracing == 0); + _PyListIterObject *it = (_PyListIterObject *)TOP(); + DEOPT_IF(Py_TYPE(it) != &PyListIter_Type, FOR_ITER); + STAT_INC(FOR_ITER, hit); + PyListObject *seq = it->it_seq; + if (seq) { + if (it->it_index < PyList_GET_SIZE(seq)) { + PyObject *next = PyList_GET_ITEM(seq, it->it_index++); + PUSH(Py_NewRef(next)); + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER); + goto end_for_iter_list; // End of this instruction + } + it->it_seq = NULL; + Py_DECREF(seq); + } + STACK_SHRINK(1); + Py_DECREF(it); + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + end_for_iter_list: + } + + // stack effect: ( -- __0) + inst(FOR_ITER_TUPLE) { + assert(cframe.use_tracing == 0); + _PyTupleIterObject *it = (_PyTupleIterObject *)TOP(); + DEOPT_IF(Py_TYPE(it) != &PyTupleIter_Type, FOR_ITER); + STAT_INC(FOR_ITER, hit); + PyTupleObject *seq = it->it_seq; + if (seq) { + if (it->it_index < PyTuple_GET_SIZE(seq)) { + PyObject *next = PyTuple_GET_ITEM(seq, it->it_index++); + PUSH(Py_NewRef(next)); + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER); + goto end_for_iter_tuple; // End of this instruction + } + it->it_seq = NULL; + Py_DECREF(seq); + } + STACK_SHRINK(1); + Py_DECREF(it); + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + end_for_iter_tuple: + } + + // stack effect: ( -- __0) + inst(FOR_ITER_RANGE) { + assert(cframe.use_tracing == 0); + _PyRangeIterObject *r = (_PyRangeIterObject *)TOP(); + DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); + STAT_INC(FOR_ITER, hit); + _Py_CODEUNIT next = next_instr[INLINE_CACHE_ENTRIES_FOR_ITER]; + assert(_PyOpcode_Deopt[_Py_OPCODE(next)] == STORE_FAST); + if (r->len <= 0) { + STACK_SHRINK(1); + Py_DECREF(r); + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + } + else { + long value = r->start; + r->start = value + r->step; + r->len--; + if (_PyLong_AssignValue(&GETLOCAL(_Py_OPARG(next)), value) < 0) { + goto error; + } + // The STORE_FAST is already done. + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + 1); + } + } + + inst(FOR_ITER_GEN) { + assert(cframe.use_tracing == 0); + PyGenObject *gen = (PyGenObject *)TOP(); + DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER); + DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, FOR_ITER); + STAT_INC(FOR_ITER, hit); + _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + frame->yield_offset = oparg; + _PyFrame_StackPush(gen_frame, Py_NewRef(Py_None)); + gen->gi_frame_state = FRAME_EXECUTING; + gen->gi_exc_state.previous_item = tstate->exc_info; + tstate->exc_info = &gen->gi_exc_state; + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg); + assert(_Py_OPCODE(*next_instr) == END_FOR); + DISPATCH_INLINED(gen_frame); + } + + // stack effect: ( -- __0) + inst(BEFORE_ASYNC_WITH) { + PyObject *mgr = TOP(); + PyObject *res; + PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__)); + if (enter == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "asynchronous context manager protocol", + Py_TYPE(mgr)->tp_name); + } + goto error; + } + PyObject *exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__aexit__)); + if (exit == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "asynchronous context manager protocol " + "(missed __aexit__ method)", + Py_TYPE(mgr)->tp_name); + } + Py_DECREF(enter); + goto error; + } + SET_TOP(exit); + Py_DECREF(mgr); + res = _PyObject_CallNoArgs(enter); + Py_DECREF(enter); + if (res == NULL) + goto error; + PUSH(res); + PREDICT(GET_AWAITABLE); + } + + // stack effect: ( -- __0) + inst(BEFORE_WITH) { + PyObject *mgr = TOP(); + PyObject *res; + PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__enter__)); + if (enter == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "context manager protocol", + Py_TYPE(mgr)->tp_name); + } + goto error; + } + PyObject *exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__)); + if (exit == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "context manager protocol " + "(missed __exit__ method)", + Py_TYPE(mgr)->tp_name); + } + Py_DECREF(enter); + goto error; + } + SET_TOP(exit); + Py_DECREF(mgr); + res = _PyObject_CallNoArgs(enter); + Py_DECREF(enter); + if (res == NULL) { + goto error; + } + PUSH(res); + } + + inst(WITH_EXCEPT_START, (exit_func, lasti, unused, val -- exit_func, lasti, unused, val, res)) { + /* At the top of the stack are 4 values: + - val: TOP = exc_info() + - unused: SECOND = previous exception + - lasti: THIRD = lasti of exception in exc_info() + - exit_func: FOURTH = the context.__exit__ bound method + We call FOURTH(type(TOP), TOP, GetTraceback(TOP)). + Then we push the __exit__ return value. + */ + PyObject *exc, *tb; + + assert(val && PyExceptionInstance_Check(val)); + exc = PyExceptionInstance_Class(val); + tb = PyException_GetTraceback(val); + Py_XDECREF(tb); + assert(PyLong_Check(lasti)); + (void)lasti; // Shut up compiler warning if asserts are off + PyObject *stack[4] = {NULL, exc, val, tb}; + res = PyObject_Vectorcall(exit_func, stack + 1, + 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + ERROR_IF(res == NULL, error); + } + + // stack effect: ( -- __0) + inst(PUSH_EXC_INFO) { + PyObject *value = TOP(); + + _PyErr_StackItem *exc_info = tstate->exc_info; + if (exc_info->exc_value != NULL) { + SET_TOP(exc_info->exc_value); + } + else { + SET_TOP(Py_NewRef(Py_None)); + } + + PUSH(Py_NewRef(value)); + assert(PyExceptionInstance_Check(value)); + exc_info->exc_value = value; + + } + + // error: LOAD_ATTR has irregular stack effect + inst(LOAD_ATTR_METHOD_WITH_VALUES) { + /* Cached method object */ + assert(cframe.use_tracing == 0); + PyObject *self = TOP(); + PyTypeObject *self_cls = Py_TYPE(self); + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; + uint32_t type_version = read_u32(cache->type_version); + assert(type_version != 0); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); + assert(self_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + PyHeapTypeObject *self_heap_type = (PyHeapTypeObject *)self_cls; + DEOPT_IF(self_heap_type->ht_cached_keys->dk_version != + read_u32(cache->keys_version), LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + PyObject *res = read_obj(cache->descr); + assert(res != NULL); + assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); + SET_TOP(Py_NewRef(res)); + PUSH(self); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + } + + // error: LOAD_ATTR has irregular stack effect + inst(LOAD_ATTR_METHOD_NO_DICT) { + assert(cframe.use_tracing == 0); + PyObject *self = TOP(); + PyTypeObject *self_cls = Py_TYPE(self); + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; + uint32_t type_version = read_u32(cache->type_version); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); + assert(self_cls->tp_dictoffset == 0); + STAT_INC(LOAD_ATTR, hit); + PyObject *res = read_obj(cache->descr); + assert(res != NULL); + assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); + SET_TOP(Py_NewRef(res)); + PUSH(self); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + } + + // error: LOAD_ATTR has irregular stack effect + inst(LOAD_ATTR_METHOD_LAZY_DICT) { + assert(cframe.use_tracing == 0); + PyObject *self = TOP(); + PyTypeObject *self_cls = Py_TYPE(self); + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; + uint32_t type_version = read_u32(cache->type_version); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); + Py_ssize_t dictoffset = self_cls->tp_dictoffset; + assert(dictoffset > 0); + PyObject *dict = *(PyObject **)((char *)self + dictoffset); + /* This object has a __dict__, just not yet created */ + DEOPT_IF(dict != NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + PyObject *res = read_obj(cache->descr); + assert(res != NULL); + assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); + SET_TOP(Py_NewRef(res)); + PUSH(self); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_BOUND_METHOD_EXACT_ARGS) { + DEOPT_IF(is_method(stack_pointer, oparg), CALL); + PyObject *function = PEEK(oparg + 1); + DEOPT_IF(Py_TYPE(function) != &PyMethod_Type, CALL); + STAT_INC(CALL, hit); + PyObject *self = ((PyMethodObject *)function)->im_self; + PEEK(oparg + 1) = Py_NewRef(self); + PyObject *meth = ((PyMethodObject *)function)->im_func; + PEEK(oparg + 2) = Py_NewRef(meth); + Py_DECREF(function); + GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS); + } + + // stack effect: ( -- ) + inst(KW_NAMES) { + assert(kwnames == NULL); + assert(oparg < PyTuple_GET_SIZE(consts)); + kwnames = GETITEM(consts, oparg); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL) { + #if ENABLE_SPECIALIZATION + _PyCallCache *cache = (_PyCallCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + assert(cframe.use_tracing == 0); + int is_meth = is_method(stack_pointer, oparg); + int nargs = oparg + is_meth; + PyObject *callable = PEEK(nargs + 1); + next_instr--; + _Py_Specialize_Call(callable, next_instr, nargs, kwnames); + DISPATCH_SAME_OPARG(); + } + STAT_INC(CALL, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + int total_args, is_meth; + is_meth = is_method(stack_pointer, oparg); + PyObject *function = PEEK(oparg + 1); + if (!is_meth && Py_TYPE(function) == &PyMethod_Type) { + PyObject *self = ((PyMethodObject *)function)->im_self; + PEEK(oparg+1) = Py_NewRef(self); + PyObject *meth = ((PyMethodObject *)function)->im_func; + PEEK(oparg+2) = Py_NewRef(meth); + Py_DECREF(function); + is_meth = 1; + } + total_args = oparg + is_meth; + function = PEEK(total_args + 1); + int positional_args = total_args - KWNAMES_LEN(); + // Check if the call can be inlined or not + if (Py_TYPE(function) == &PyFunction_Type && + tstate->interp->eval_frame == NULL && + ((PyFunctionObject *)function)->vectorcall == _PyFunction_Vectorcall) + { + int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(function))->co_flags; + PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(function)); + STACK_SHRINK(total_args); + _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit( + tstate, (PyFunctionObject *)function, locals, + stack_pointer, positional_args, kwnames + ); + kwnames = NULL; + STACK_SHRINK(2-is_meth); + // The frame has stolen all the arguments from the stack, + // so there is no need to clean them up. + if (new_frame == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + DISPATCH_INLINED(new_frame); + } + /* Callable is not a normal Python function */ + PyObject *res; + if (cframe.use_tracing) { + res = trace_call_function( + tstate, function, stack_pointer-total_args, + positional_args, kwnames); + } + else { + res = PyObject_Vectorcall( + function, stack_pointer-total_args, + positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET, + kwnames); + } + kwnames = NULL; + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(function); + /* Clear the stack */ + STACK_SHRINK(total_args); + for (int i = 0; i < total_args; i++) { + Py_DECREF(stack_pointer[i]); + } + STACK_SHRINK(2-is_meth); + PUSH(res); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_PY_EXACT_ARGS) { + assert(kwnames == NULL); + DEOPT_IF(tstate->interp->eval_frame, CALL); + _PyCallCache *cache = (_PyCallCache *)next_instr; + int is_meth = is_method(stack_pointer, oparg); + int argcount = oparg + is_meth; + PyObject *callable = PEEK(argcount + 1); + DEOPT_IF(!PyFunction_Check(callable), CALL); + PyFunctionObject *func = (PyFunctionObject *)callable; + DEOPT_IF(func->func_version != read_u32(cache->func_version), CALL); + PyCodeObject *code = (PyCodeObject *)func->func_code; + DEOPT_IF(code->co_argcount != argcount, CALL); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); + STAT_INC(CALL, hit); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, argcount); + STACK_SHRINK(argcount); + for (int i = 0; i < argcount; i++) { + new_frame->localsplus[i] = stack_pointer[i]; + } + STACK_SHRINK(2-is_meth); + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + DISPATCH_INLINED(new_frame); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_PY_WITH_DEFAULTS) { + assert(kwnames == NULL); + DEOPT_IF(tstate->interp->eval_frame, CALL); + _PyCallCache *cache = (_PyCallCache *)next_instr; + int is_meth = is_method(stack_pointer, oparg); + int argcount = oparg + is_meth; + PyObject *callable = PEEK(argcount + 1); + DEOPT_IF(!PyFunction_Check(callable), CALL); + PyFunctionObject *func = (PyFunctionObject *)callable; + DEOPT_IF(func->func_version != read_u32(cache->func_version), CALL); + PyCodeObject *code = (PyCodeObject *)func->func_code; + DEOPT_IF(argcount > code->co_argcount, CALL); + int minargs = cache->min_args; + DEOPT_IF(argcount < minargs, CALL); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); + STAT_INC(CALL, hit); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, code->co_argcount); + STACK_SHRINK(argcount); + for (int i = 0; i < argcount; i++) { + new_frame->localsplus[i] = stack_pointer[i]; + } + for (int i = argcount; i < code->co_argcount; i++) { + PyObject *def = PyTuple_GET_ITEM(func->func_defaults, + i - minargs); + new_frame->localsplus[i] = Py_NewRef(def); + } + STACK_SHRINK(2-is_meth); + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + DISPATCH_INLINED(new_frame); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_NO_KW_TYPE_1) { + assert(kwnames == NULL); + assert(cframe.use_tracing == 0); + assert(oparg == 1); + DEOPT_IF(is_method(stack_pointer, 1), CALL); + PyObject *obj = TOP(); + PyObject *callable = SECOND(); + DEOPT_IF(callable != (PyObject *)&PyType_Type, CALL); + STAT_INC(CALL, hit); + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + PyObject *res = Py_NewRef(Py_TYPE(obj)); + Py_DECREF(callable); + Py_DECREF(obj); + STACK_SHRINK(2); + SET_TOP(res); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_NO_KW_STR_1) { + assert(kwnames == NULL); + assert(cframe.use_tracing == 0); + assert(oparg == 1); + DEOPT_IF(is_method(stack_pointer, 1), CALL); + PyObject *callable = PEEK(2); + DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL); + STAT_INC(CALL, hit); + PyObject *arg = TOP(); + PyObject *res = PyObject_Str(arg); + Py_DECREF(arg); + Py_DECREF(&PyUnicode_Type); + STACK_SHRINK(2); + SET_TOP(res); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_NO_KW_TUPLE_1) { + assert(kwnames == NULL); + assert(oparg == 1); + DEOPT_IF(is_method(stack_pointer, 1), CALL); + PyObject *callable = PEEK(2); + DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL); + STAT_INC(CALL, hit); + PyObject *arg = TOP(); + PyObject *res = PySequence_Tuple(arg); + Py_DECREF(arg); + Py_DECREF(&PyTuple_Type); + STACK_SHRINK(2); + SET_TOP(res); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_BUILTIN_CLASS) { + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + int kwnames_len = KWNAMES_LEN(); + PyObject *callable = PEEK(total_args + 1); + DEOPT_IF(!PyType_Check(callable), CALL); + PyTypeObject *tp = (PyTypeObject *)callable; + DEOPT_IF(tp->tp_vectorcall == NULL, CALL); + STAT_INC(CALL, hit); + STACK_SHRINK(total_args); + PyObject *res = tp->tp_vectorcall((PyObject *)tp, stack_pointer, + total_args-kwnames_len, kwnames); + kwnames = NULL; + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(stack_pointer[i]); + } + Py_DECREF(tp); + STACK_SHRINK(1-is_meth); + SET_TOP(res); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_NO_KW_BUILTIN_O) { + assert(cframe.use_tracing == 0); + /* Builtin METH_O functions */ + assert(kwnames == NULL); + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + DEOPT_IF(total_args != 1, CALL); + PyObject *callable = PEEK(total_args + 1); + DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_O, CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); + // This is slower but CPython promises to check all non-vectorcall + // function calls. + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { + goto error; + } + PyObject *arg = TOP(); + PyObject *res = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable), arg); + _Py_LeaveRecursiveCallTstate(tstate); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + Py_DECREF(arg); + Py_DECREF(callable); + STACK_SHRINK(2-is_meth); + SET_TOP(res); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_NO_KW_BUILTIN_FAST) { + assert(cframe.use_tracing == 0); + /* Builtin METH_FASTCALL functions, without keywords */ + assert(kwnames == NULL); + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + PyObject *callable = PEEK(total_args + 1); + DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_FASTCALL, + CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); + STACK_SHRINK(total_args); + /* res = func(self, args, nargs) */ + PyObject *res = ((_PyCFunctionFast)(void(*)(void))cfunc)( + PyCFunction_GET_SELF(callable), + stack_pointer, + total_args); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(stack_pointer[i]); + } + STACK_SHRINK(2-is_meth); + PUSH(res); + Py_DECREF(callable); + if (res == NULL) { + /* Not deopting because this doesn't mean our optimization was + wrong. `res` can be NULL for valid reasons. Eg. getattr(x, + 'invalid'). In those cases an exception is set, so we must + handle it. + */ + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_BUILTIN_FAST_WITH_KEYWORDS) { + assert(cframe.use_tracing == 0); + /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + PyObject *callable = PEEK(total_args + 1); + DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != + (METH_FASTCALL | METH_KEYWORDS), CALL); + STAT_INC(CALL, hit); + STACK_SHRINK(total_args); + /* res = func(self, args, nargs, kwnames) */ + _PyCFunctionFastWithKeywords cfunc = + (_PyCFunctionFastWithKeywords)(void(*)(void)) + PyCFunction_GET_FUNCTION(callable); + PyObject *res = cfunc( + PyCFunction_GET_SELF(callable), + stack_pointer, + total_args - KWNAMES_LEN(), + kwnames + ); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + kwnames = NULL; + + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(stack_pointer[i]); + } + STACK_SHRINK(2-is_meth); + PUSH(res); + Py_DECREF(callable); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_NO_KW_LEN) { + assert(cframe.use_tracing == 0); + assert(kwnames == NULL); + /* len(o) */ + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + DEOPT_IF(total_args != 1, CALL); + PyObject *callable = PEEK(total_args + 1); + PyInterpreterState *interp = _PyInterpreterState_GET(); + DEOPT_IF(callable != interp->callable_cache.len, CALL); + STAT_INC(CALL, hit); + PyObject *arg = TOP(); + Py_ssize_t len_i = PyObject_Length(arg); + if (len_i < 0) { + goto error; + } + PyObject *res = PyLong_FromSsize_t(len_i); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + STACK_SHRINK(2-is_meth); + SET_TOP(res); + Py_DECREF(callable); + Py_DECREF(arg); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_NO_KW_ISINSTANCE) { + assert(cframe.use_tracing == 0); + assert(kwnames == NULL); + /* isinstance(o, o2) */ + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + PyObject *callable = PEEK(total_args + 1); + DEOPT_IF(total_args != 2, CALL); + PyInterpreterState *interp = _PyInterpreterState_GET(); + DEOPT_IF(callable != interp->callable_cache.isinstance, CALL); + STAT_INC(CALL, hit); + PyObject *cls = POP(); + PyObject *inst = TOP(); + int retval = PyObject_IsInstance(inst, cls); + if (retval < 0) { + Py_DECREF(cls); + goto error; + } + PyObject *res = PyBool_FromLong(retval); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + STACK_SHRINK(2-is_meth); + SET_TOP(res); + Py_DECREF(inst); + Py_DECREF(cls); + Py_DECREF(callable); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_NO_KW_LIST_APPEND) { + assert(cframe.use_tracing == 0); + assert(kwnames == NULL); + assert(oparg == 1); + PyObject *callable = PEEK(3); + PyInterpreterState *interp = _PyInterpreterState_GET(); + DEOPT_IF(callable != interp->callable_cache.list_append, CALL); + PyObject *list = SECOND(); + DEOPT_IF(!PyList_Check(list), CALL); + STAT_INC(CALL, hit); + PyObject *arg = POP(); + if (_PyList_AppendTakeRef((PyListObject *)list, arg) < 0) { + goto error; + } + STACK_SHRINK(2); + Py_DECREF(list); + Py_DECREF(callable); + // CALL + POP_TOP + JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1); + assert(_Py_OPCODE(next_instr[-1]) == POP_TOP); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_NO_KW_METHOD_DESCRIPTOR_O) { + assert(kwnames == NULL); + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + PyMethodDescrObject *callable = + (PyMethodDescrObject *)PEEK(total_args + 1); + DEOPT_IF(total_args != 2, CALL); + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = callable->d_method; + DEOPT_IF(meth->ml_flags != METH_O, CALL); + PyObject *arg = TOP(); + PyObject *self = SECOND(); + DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = meth->ml_meth; + // This is slower but CPython promises to check all non-vectorcall + // function calls. + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { + goto error; + } + PyObject *res = _PyCFunction_TrampolineCall(cfunc, self, arg); + _Py_LeaveRecursiveCallTstate(tstate); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(self); + Py_DECREF(arg); + STACK_SHRINK(oparg + 1); + SET_TOP(res); + Py_DECREF(callable); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS) { + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + PyMethodDescrObject *callable = + (PyMethodDescrObject *)PEEK(total_args + 1); + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = callable->d_method; + DEOPT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS), CALL); + PyTypeObject *d_type = callable->d_common.d_type; + PyObject *self = PEEK(total_args); + DEOPT_IF(!Py_IS_TYPE(self, d_type), CALL); + STAT_INC(CALL, hit); + int nargs = total_args-1; + STACK_SHRINK(nargs); + _PyCFunctionFastWithKeywords cfunc = + (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; + PyObject *res = cfunc(self, stack_pointer, nargs - KWNAMES_LEN(), + kwnames); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + kwnames = NULL; + + /* Free the arguments. */ + for (int i = 0; i < nargs; i++) { + Py_DECREF(stack_pointer[i]); + } + Py_DECREF(self); + STACK_SHRINK(2-is_meth); + SET_TOP(res); + Py_DECREF(callable); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS) { + assert(kwnames == NULL); + assert(oparg == 0 || oparg == 1); + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + DEOPT_IF(total_args != 1, CALL); + PyMethodDescrObject *callable = (PyMethodDescrObject *)SECOND(); + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = callable->d_method; + PyObject *self = TOP(); + DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + DEOPT_IF(meth->ml_flags != METH_NOARGS, CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = meth->ml_meth; + // This is slower but CPython promises to check all non-vectorcall + // function calls. + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { + goto error; + } + PyObject *res = _PyCFunction_TrampolineCall(cfunc, self, NULL); + _Py_LeaveRecursiveCallTstate(tstate); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(self); + STACK_SHRINK(oparg + 1); + SET_TOP(res); + Py_DECREF(callable); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + } + + // stack effect: (__0, __array[oparg] -- ) + inst(CALL_NO_KW_METHOD_DESCRIPTOR_FAST) { + assert(kwnames == NULL); + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + PyMethodDescrObject *callable = + (PyMethodDescrObject *)PEEK(total_args + 1); + /* Builtin METH_FASTCALL methods, without keywords */ + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = callable->d_method; + DEOPT_IF(meth->ml_flags != METH_FASTCALL, CALL); + PyObject *self = PEEK(total_args); + DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + STAT_INC(CALL, hit); + _PyCFunctionFast cfunc = + (_PyCFunctionFast)(void(*)(void))meth->ml_meth; + int nargs = total_args-1; + STACK_SHRINK(nargs); + PyObject *res = cfunc(self, stack_pointer, nargs); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + /* Clear the stack of the arguments. */ + for (int i = 0; i < nargs; i++) { + Py_DECREF(stack_pointer[i]); + } + Py_DECREF(self); + STACK_SHRINK(2-is_meth); + SET_TOP(res); + Py_DECREF(callable); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + } + + // error: CALL_FUNCTION_EX has irregular stack effect + inst(CALL_FUNCTION_EX) { + PyObject *func, *callargs, *kwargs = NULL, *result; + if (oparg & 0x01) { + kwargs = POP(); + // DICT_MERGE is called before this opcode if there are kwargs. + // It converts all dict subtypes in kwargs into regular dicts. + assert(PyDict_CheckExact(kwargs)); + } + callargs = POP(); + func = TOP(); + if (!PyTuple_CheckExact(callargs)) { + if (check_args_iterable(tstate, func, callargs) < 0) { + Py_DECREF(callargs); + goto error; + } + Py_SETREF(callargs, PySequence_Tuple(callargs)); + if (callargs == NULL) { + goto error; + } + } + assert(PyTuple_CheckExact(callargs)); + + result = do_call_core(tstate, func, callargs, kwargs, cframe.use_tracing); + Py_DECREF(func); + Py_DECREF(callargs); + Py_XDECREF(kwargs); + + STACK_SHRINK(1); + assert(TOP() == NULL); + SET_TOP(result); + if (result == NULL) { + goto error; + } + CHECK_EVAL_BREAKER(); + } + + // error: MAKE_FUNCTION has irregular stack effect + inst(MAKE_FUNCTION) { + PyObject *codeobj = POP(); + PyFunctionObject *func = (PyFunctionObject *) + PyFunction_New(codeobj, GLOBALS()); + + Py_DECREF(codeobj); + if (func == NULL) { + goto error; + } + + if (oparg & 0x08) { + assert(PyTuple_CheckExact(TOP())); + func->func_closure = POP(); + } + if (oparg & 0x04) { + assert(PyTuple_CheckExact(TOP())); + func->func_annotations = POP(); + } + if (oparg & 0x02) { + assert(PyDict_CheckExact(TOP())); + func->func_kwdefaults = POP(); + } + if (oparg & 0x01) { + assert(PyTuple_CheckExact(TOP())); + func->func_defaults = POP(); + } + + func->func_version = ((PyCodeObject *)codeobj)->co_version; + PUSH((PyObject *)func); + } + + // stack effect: ( -- ) + inst(RETURN_GENERATOR) { + assert(PyFunction_Check(frame->f_funcobj)); + PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; + PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); + if (gen == NULL) { + goto error; + } + assert(EMPTY()); + _PyFrame_SetStackPointer(frame, stack_pointer); + _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + _PyFrame_Copy(frame, gen_frame); + assert(frame->frame_obj == NULL); + gen->gi_frame_state = FRAME_CREATED; + gen_frame->owner = FRAME_OWNED_BY_GENERATOR; + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + _PyInterpreterFrame *prev = frame->previous; + _PyThreadState_PopFrame(tstate, frame); + frame = cframe.current_frame = prev; + _PyFrame_StackPush(frame, (PyObject *)gen); + goto resume_frame; + } + + // error: BUILD_SLICE has irregular stack effect + inst(BUILD_SLICE) { + PyObject *start, *stop, *step, *slice; + if (oparg == 3) + step = POP(); + else + step = NULL; + stop = POP(); + start = TOP(); + slice = PySlice_New(start, stop, step); + Py_DECREF(start); + Py_DECREF(stop); + Py_XDECREF(step); + SET_TOP(slice); + if (slice == NULL) + goto error; + } + + // error: FORMAT_VALUE has irregular stack effect + inst(FORMAT_VALUE) { + /* Handles f-string value formatting. */ + PyObject *result; + PyObject *fmt_spec; + PyObject *value; + PyObject *(*conv_fn)(PyObject *); + int which_conversion = oparg & FVC_MASK; + int have_fmt_spec = (oparg & FVS_MASK) == FVS_HAVE_SPEC; + + fmt_spec = have_fmt_spec ? POP() : NULL; + value = POP(); + + /* See if any conversion is specified. */ + switch (which_conversion) { + case FVC_NONE: conv_fn = NULL; break; + case FVC_STR: conv_fn = PyObject_Str; break; + case FVC_REPR: conv_fn = PyObject_Repr; break; + case FVC_ASCII: conv_fn = PyObject_ASCII; break; + default: + _PyErr_Format(tstate, PyExc_SystemError, + "unexpected conversion flag %d", + which_conversion); + goto error; + } + + /* If there's a conversion function, call it and replace + value with that result. Otherwise, just use value, + without conversion. */ + if (conv_fn != NULL) { + result = conv_fn(value); + Py_DECREF(value); + if (result == NULL) { + Py_XDECREF(fmt_spec); + goto error; + } + value = result; + } + + /* If value is a unicode object, and there's no fmt_spec, + then we know the result of format(value) is value + itself. In that case, skip calling format(). I plan to + move this optimization in to PyObject_Format() + itself. */ + if (PyUnicode_CheckExact(value) && fmt_spec == NULL) { + /* Do nothing, just transfer ownership to result. */ + result = value; + } else { + /* Actually call format(). */ + result = PyObject_Format(value, fmt_spec); + Py_DECREF(value); + Py_XDECREF(fmt_spec); + if (result == NULL) { + goto error; + } + } + + PUSH(result); + } + + // stack effect: ( -- __0) + inst(COPY) { + assert(oparg != 0); + PyObject *peek = PEEK(oparg); + PUSH(Py_NewRef(peek)); + } + + inst(BINARY_OP, (unused/1, lhs, rhs -- res)) { + #if ENABLE_SPECIALIZATION + _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + assert(cframe.use_tracing == 0); + next_instr--; + _Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, &GETLOCAL(0)); + DISPATCH_SAME_OPARG(); + } + STAT_INC(BINARY_OP, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + assert(0 <= oparg); + assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); + assert(binary_ops[oparg]); + res = binary_ops[oparg](lhs, rhs); + Py_DECREF(lhs); + Py_DECREF(rhs); + ERROR_IF(res == NULL, error); + } + + // stack effect: ( -- ) + inst(SWAP) { + assert(oparg != 0); + PyObject *top = TOP(); + SET_TOP(PEEK(oparg)); + PEEK(oparg) = top; + } + + // stack effect: ( -- ) + inst(EXTENDED_ARG) { + assert(oparg); + assert(cframe.use_tracing == 0); + opcode = _Py_OPCODE(*next_instr); + oparg = oparg << 8 | _Py_OPARG(*next_instr); + PRE_DISPATCH_GOTO(); + DISPATCH_GOTO(); + } + + // stack effect: ( -- ) + inst(CACHE) { + Py_UNREACHABLE(); + } + + +// END BYTECODES // + + } + dispatch_opcode: + error: + exception_unwind: + exit_unwind: + handle_eval_breaker: + resume_frame: + resume_with_error: + start_frame: + unbound_local_error: + ; +} + +// Future families go below this point // + +family(call) = { + CALL, CALL_PY_EXACT_ARGS, + CALL_PY_WITH_DEFAULTS, CALL_BOUND_METHOD_EXACT_ARGS, CALL_BUILTIN_CLASS, + CALL_BUILTIN_FAST_WITH_KEYWORDS, CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, CALL_NO_KW_BUILTIN_FAST, + CALL_NO_KW_BUILTIN_O, CALL_NO_KW_ISINSTANCE, CALL_NO_KW_LEN, + CALL_NO_KW_LIST_APPEND, CALL_NO_KW_METHOD_DESCRIPTOR_FAST, CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, + CALL_NO_KW_METHOD_DESCRIPTOR_O, CALL_NO_KW_STR_1, CALL_NO_KW_TUPLE_1, + CALL_NO_KW_TYPE_1 }; +family(for_iter) = { + FOR_ITER, FOR_ITER_LIST, + FOR_ITER_RANGE }; +family(load_attr) = { + LOAD_ATTR, LOAD_ATTR_CLASS, + LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, LOAD_ATTR_INSTANCE_VALUE, LOAD_ATTR_MODULE, + LOAD_ATTR_PROPERTY, LOAD_ATTR_SLOT, LOAD_ATTR_WITH_HINT, + LOAD_ATTR_METHOD_LAZY_DICT, LOAD_ATTR_METHOD_NO_DICT, + LOAD_ATTR_METHOD_WITH_VALUES }; +family(load_global) = { + LOAD_GLOBAL, LOAD_GLOBAL_BUILTIN, + LOAD_GLOBAL_MODULE }; +family(store_fast) = { STORE_FAST, STORE_FAST__LOAD_FAST, STORE_FAST__STORE_FAST }; +family(unpack_sequence) = { + UNPACK_SEQUENCE, UNPACK_SEQUENCE_LIST, + UNPACK_SEQUENCE_TUPLE, UNPACK_SEQUENCE_TWO_TUPLE }; diff --git a/Python/ceval.c b/Python/ceval.c index 9e56b50ee84..2e6fed580de 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1,34 +1,29 @@ /* Execute compiled code */ -/* XXX TO DO: - XXX speed up searching for keywords by using a dictionary - XXX document it! - */ - -/* enable more aggressive intra-module optimizations, where available */ -/* affects both release and debug builds - see bpo-43271 */ -#define PY_LOCAL_AGGRESSIVE +#define _PY_INTERPRETER #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_call.h" // _PyObject_FastCallDictTstate() #include "pycore_ceval.h" // _PyEval_SignalAsyncExc() #include "pycore_code.h" -#include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_function.h" +#include "pycore_intrinsics.h" #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_object.h" // _PyObject_GC_TRACK() #include "pycore_moduleobject.h" // PyModuleObject +#include "pycore_opcode.h" // EXTRA_CASES #include "pycore_pyerrors.h" // _PyErr_Fetch() -#include "pycore_pylifecycle.h" // _PyErr_Print() #include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_range.h" // _PyRangeIterObject +#include "pycore_sliceobject.h" // _PyBuildSlice_ConsumeRefs #include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_tuple.h" // _PyTuple_ITEMS() +#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS -#include "code.h" #include "pycore_dict.h" #include "dictobject.h" -#include "frameobject.h" #include "pycore_frame.h" #include "opcode.h" #include "pydtrace.h" @@ -36,18 +31,66 @@ #include "structmember.h" // struct PyMemberDef, T_OFFSET_EX #include +#include #ifdef Py_DEBUG -/* For debugging the interpreter: */ -#define LLTRACE 1 /* Low-level trace feature */ -#define CHECKEXC 1 /* Double-check exception checking */ + /* For debugging the interpreter: */ +# define LLTRACE 1 /* Low-level trace feature */ #endif #if !defined(Py_BUILD_CORE) # error "ceval.c must be build with Py_BUILD_CORE define for best performance" #endif -_Py_IDENTIFIER(__name__); +#if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) +// GH-89279: The MSVC compiler does not inline these static inline functions +// in PGO build in _PyEval_EvalFrameDefault(), because this function is over +// the limit of PGO, and that limit cannot be configured. +// Define them as macros to make sure that they are always inlined by the +// preprocessor. + +#undef Py_DECREF +#define Py_DECREF(arg) \ + do { \ + _Py_DECREF_STAT_INC(); \ + PyObject *op = _PyObject_CAST(arg); \ + if (--op->ob_refcnt == 0) { \ + destructor dealloc = Py_TYPE(op)->tp_dealloc; \ + (*dealloc)(op); \ + } \ + } while (0) + +#undef Py_XDECREF +#define Py_XDECREF(arg) \ + do { \ + PyObject *xop = _PyObject_CAST(arg); \ + if (xop != NULL) { \ + Py_DECREF(xop); \ + } \ + } while (0) + +#undef Py_IS_TYPE +#define Py_IS_TYPE(ob, type) \ + (_PyObject_CAST(ob)->ob_type == (type)) + +#undef _Py_DECREF_SPECIALIZED +#define _Py_DECREF_SPECIALIZED(arg, dealloc) \ + do { \ + _Py_DECREF_STAT_INC(); \ + PyObject *op = _PyObject_CAST(arg); \ + if (--op->ob_refcnt == 0) { \ + destructor d = (destructor)(dealloc); \ + d(op); \ + } \ + } while (0) +#endif + +// GH-89279: Similar to above, force inlining by using a macro. +#if defined(_MSC_VER) && SIZEOF_INT == 4 +#define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) (assert(sizeof((ATOMIC_VAL)->_value) == 4), *((volatile int*)&((ATOMIC_VAL)->_value))) +#else +#define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) _Py_atomic_load_relaxed(ATOMIC_VAL) +#endif /* Forward declarations */ static PyObject *trace_call_function( @@ -58,69 +101,124 @@ static PyObject * do_call_core( PyObject *callargs, PyObject *kwdict, int use_tracing); #ifdef LLTRACE -static int lltrace; -static int prtrace(PyThreadState *, PyObject *, const char *); -static void lltrace_instruction(InterpreterFrame *frame, int opcode, int oparg) +static void +dump_stack(_PyInterpreterFrame *frame, PyObject **stack_pointer) { - if (HAS_ARG(opcode)) { - printf("%d: %d, %d\n", - frame->f_lasti, opcode, oparg); + PyObject **stack_base = _PyFrame_Stackbase(frame); + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + printf(" stack=["); + for (PyObject **ptr = stack_base; ptr < stack_pointer; ptr++) { + if (ptr != stack_base) { + printf(", "); + } + if (PyObject_Print(*ptr, stdout, 0) != 0) { + PyErr_Clear(); + printf("<%s object at %p>", + Py_TYPE(*ptr)->tp_name, (void *)(*ptr)); + } + } + printf("]\n"); + fflush(stdout); + PyErr_Restore(type, value, traceback); +} + +static void +lltrace_instruction(_PyInterpreterFrame *frame, + PyObject **stack_pointer, + _Py_CODEUNIT *next_instr) +{ + /* This dump_stack() operation is risky, since the repr() of some + objects enters the interpreter recursively. It is also slow. + So you might want to comment it out. */ + dump_stack(frame, stack_pointer); + int oparg = _Py_OPARG(*next_instr); + int opcode = _Py_OPCODE(*next_instr); + const char *opname = _PyOpcode_OpName[opcode]; + assert(opname != NULL); + int offset = (int)(next_instr - _PyCode_CODE(frame->f_code)); + if (HAS_ARG((int)_PyOpcode_Deopt[opcode])) { + printf("%d: %s %d\n", offset * 2, opname, oparg); } else { - printf("%d: %d\n", - frame->f_lasti, opcode); + printf("%d: %s\n", offset * 2, opname); } + fflush(stdout); +} +static void +lltrace_resume_frame(_PyInterpreterFrame *frame) +{ + PyObject *fobj = frame->f_funcobj; + if (frame->owner == FRAME_OWNED_BY_CSTACK || + fobj == NULL || + !PyFunction_Check(fobj) + ) { + printf("\nResuming frame.\n"); + return; + } + PyFunctionObject *f = (PyFunctionObject *)fobj; + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + PyObject *name = f->func_qualname; + if (name == NULL) { + name = f->func_name; + } + printf("\nResuming frame"); + if (name) { + printf(" for "); + if (PyObject_Print(name, stdout, 0) < 0) { + PyErr_Clear(); + } + } + if (f->func_module) { + printf(" in module "); + if (PyObject_Print(f->func_module, stdout, 0) < 0) { + PyErr_Clear(); + } + } + printf("\n"); + fflush(stdout); + PyErr_Restore(type, value, traceback); } #endif static int call_trace(Py_tracefunc, PyObject *, - PyThreadState *, InterpreterFrame *, + PyThreadState *, _PyInterpreterFrame *, int, PyObject *); static int call_trace_protected(Py_tracefunc, PyObject *, - PyThreadState *, InterpreterFrame *, + PyThreadState *, _PyInterpreterFrame *, int, PyObject *); static void call_exc_trace(Py_tracefunc, PyObject *, - PyThreadState *, InterpreterFrame *); + PyThreadState *, _PyInterpreterFrame *); static int maybe_call_line_trace(Py_tracefunc, PyObject *, - PyThreadState *, InterpreterFrame *, int); -static void maybe_dtrace_line(InterpreterFrame *, PyTraceInfo *, int); -static void dtrace_function_entry(InterpreterFrame *); -static void dtrace_function_return(InterpreterFrame *); + PyThreadState *, _PyInterpreterFrame *, int); +static void maybe_dtrace_line(_PyInterpreterFrame *, PyTraceInfo *, int); +static void dtrace_function_entry(_PyInterpreterFrame *); +static void dtrace_function_return(_PyInterpreterFrame *); -static PyObject * import_name(PyThreadState *, InterpreterFrame *, +static PyObject * import_name(PyThreadState *, _PyInterpreterFrame *, PyObject *, PyObject *, PyObject *); static PyObject * import_from(PyThreadState *, PyObject *, PyObject *); -static int import_all_from(PyThreadState *, PyObject *, PyObject *); static void format_exc_check_arg(PyThreadState *, PyObject *, const char *, PyObject *); static void format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg); static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg); +static int check_except_type_valid(PyThreadState *tstate, PyObject* right); +static int check_except_star_type_valid(PyThreadState *tstate, PyObject* right); static void format_kwargs_error(PyThreadState *, PyObject *func, PyObject *kwargs); -static void format_awaitable_error(PyThreadState *, PyTypeObject *, int, int); +static void format_awaitable_error(PyThreadState *, PyTypeObject *, int); static int get_exception_handler(PyCodeObject *, int, int*, int*, int*); -static InterpreterFrame * -_PyEvalFramePushAndInit(PyThreadState *tstate, PyFrameConstructor *con, +static _PyInterpreterFrame * +_PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func, PyObject *locals, PyObject* const* args, size_t argcount, PyObject *kwnames); -static int -_PyEvalFrameClearAndPop(PyThreadState *tstate, InterpreterFrame * frame); +static void +_PyEvalFrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame *frame); -#define NAME_ERROR_MSG \ - "name '%.200s' is not defined" #define UNBOUNDLOCAL_ERROR_MSG \ "cannot access local variable '%s' where it is not associated with a value" #define UNBOUNDFREE_ERROR_MSG \ "cannot access free variable '%s' where it is not associated with a" \ " value in enclosing scope" -/* Dynamic execution profile */ -#ifdef DYNAMIC_EXECUTION_PROFILE -#ifdef DXPAIRS -static long dxpairs[257][256]; -#define dxp dxpairs[256] -#else -static long dxp[256]; -#endif -#endif - #ifndef NDEBUG /* Ensure that tstate is valid: sanity check for PyEval_AcquireThread() and PyEval_RestoreThread(). Detect if tstate memory was freed. It can happen @@ -136,644 +234,9 @@ is_tstate_valid(PyThreadState *tstate) #endif -/* This can set eval_breaker to 0 even though gil_drop_request became - 1. We believe this is all right because the eval loop will release - the GIL eventually anyway. */ -static inline void -COMPUTE_EVAL_BREAKER(PyInterpreterState *interp, - struct _ceval_runtime_state *ceval, - struct _ceval_state *ceval2) -{ - _Py_atomic_store_relaxed(&ceval2->eval_breaker, - _Py_atomic_load_relaxed(&ceval2->gil_drop_request) - | (_Py_atomic_load_relaxed(&ceval->signals_pending) - && _Py_ThreadCanHandleSignals(interp)) - | (_Py_atomic_load_relaxed(&ceval2->pending.calls_to_do) - && _Py_ThreadCanHandlePendingCalls()) - | ceval2->pending.async_exc); -} - - -static inline void -SET_GIL_DROP_REQUEST(PyInterpreterState *interp) -{ - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 1); - _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); -} - - -static inline void -RESET_GIL_DROP_REQUEST(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 0); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -SIGNAL_PENDING_CALLS(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->pending.calls_to_do, 1); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -UNSIGNAL_PENDING_CALLS(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->pending.calls_to_do, 0); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -SIGNAL_PENDING_SIGNALS(PyInterpreterState *interp, int force) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval->signals_pending, 1); - if (force) { - _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); - } - else { - /* eval_breaker is not set to 1 if thread_can_handle_signals() is false */ - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); - } -} - - -static inline void -UNSIGNAL_PENDING_SIGNALS(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval->signals_pending, 0); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -SIGNAL_ASYNC_EXC(PyInterpreterState *interp) -{ - struct _ceval_state *ceval2 = &interp->ceval; - ceval2->pending.async_exc = 1; - _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); -} - - -static inline void -UNSIGNAL_ASYNC_EXC(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - ceval2->pending.async_exc = 0; - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - #ifdef HAVE_ERRNO_H #include #endif -#include "ceval_gil.h" - -void _Py_NO_RETURN -_Py_FatalError_TstateNULL(const char *func) -{ - _Py_FatalErrorFunc(func, - "the function must be called with the GIL held, " - "but the GIL is released " - "(the current Python thread state is NULL)"); -} - -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS -int -_PyEval_ThreadsInitialized(PyInterpreterState *interp) -{ - return gil_created(&interp->ceval.gil); -} - -int -PyEval_ThreadsInitialized(void) -{ - // Fatal error if there is no current interpreter - PyInterpreterState *interp = PyInterpreterState_Get(); - return _PyEval_ThreadsInitialized(interp); -} -#else -int -_PyEval_ThreadsInitialized(_PyRuntimeState *runtime) -{ - return gil_created(&runtime->ceval.gil); -} - -int -PyEval_ThreadsInitialized(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; - return _PyEval_ThreadsInitialized(runtime); -} -#endif - -PyStatus -_PyEval_InitGIL(PyThreadState *tstate) -{ -#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - if (!_Py_IsMainInterpreter(tstate->interp)) { - /* Currently, the GIL is shared by all interpreters, - and only the main interpreter is responsible to create - and destroy it. */ - return _PyStatus_OK(); - } -#endif - -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - struct _gil_runtime_state *gil = &tstate->interp->ceval.gil; -#else - struct _gil_runtime_state *gil = &tstate->interp->runtime->ceval.gil; -#endif - assert(!gil_created(gil)); - - PyThread_init_thread(); - create_gil(gil); - - take_gil(tstate); - - assert(gil_created(gil)); - return _PyStatus_OK(); -} - -void -_PyEval_FiniGIL(PyInterpreterState *interp) -{ -#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - if (!_Py_IsMainInterpreter(interp)) { - /* Currently, the GIL is shared by all interpreters, - and only the main interpreter is responsible to create - and destroy it. */ - return; - } -#endif - -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - struct _gil_runtime_state *gil = &interp->ceval.gil; -#else - struct _gil_runtime_state *gil = &interp->runtime->ceval.gil; -#endif - if (!gil_created(gil)) { - /* First Py_InitializeFromConfig() call: the GIL doesn't exist - yet: do nothing. */ - return; - } - - destroy_gil(gil); - assert(!gil_created(gil)); -} - -void -PyEval_InitThreads(void) -{ - /* Do nothing: kept for backward compatibility */ -} - -void -_PyEval_Fini(void) -{ -#if PRINT_SPECIALIZATION_STATS - _Py_PrintSpecializationStats(); -#endif -} - -void -PyEval_AcquireLock(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - _Py_EnsureTstateNotNULL(tstate); - - take_gil(tstate); -} - -void -PyEval_ReleaseLock(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - /* This function must succeed when the current thread state is NULL. - We therefore avoid PyThreadState_Get() which dumps a fatal error - in debug mode. */ - struct _ceval_runtime_state *ceval = &runtime->ceval; - struct _ceval_state *ceval2 = &tstate->interp->ceval; - drop_gil(ceval, ceval2, tstate); -} - -void -_PyEval_ReleaseLock(PyThreadState *tstate) -{ - struct _ceval_runtime_state *ceval = &tstate->interp->runtime->ceval; - struct _ceval_state *ceval2 = &tstate->interp->ceval; - drop_gil(ceval, ceval2, tstate); -} - -void -PyEval_AcquireThread(PyThreadState *tstate) -{ - _Py_EnsureTstateNotNULL(tstate); - - take_gil(tstate); - - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - (void)_PyThreadState_Swap(gilstate, tstate); -#else - if (_PyThreadState_Swap(gilstate, tstate) != NULL) { - Py_FatalError("non-NULL old thread state"); - } -#endif -} - -void -PyEval_ReleaseThread(PyThreadState *tstate) -{ - assert(is_tstate_valid(tstate)); - - _PyRuntimeState *runtime = tstate->interp->runtime; - PyThreadState *new_tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); - if (new_tstate != tstate) { - Py_FatalError("wrong thread state"); - } - struct _ceval_runtime_state *ceval = &runtime->ceval; - struct _ceval_state *ceval2 = &tstate->interp->ceval; - drop_gil(ceval, ceval2, tstate); -} - -#ifdef HAVE_FORK -/* This function is called from PyOS_AfterFork_Child to destroy all threads - which are not running in the child process, and clear internal locks - which might be held by those threads. */ -PyStatus -_PyEval_ReInitThreads(PyThreadState *tstate) -{ - _PyRuntimeState *runtime = tstate->interp->runtime; - -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - struct _gil_runtime_state *gil = &tstate->interp->ceval.gil; -#else - struct _gil_runtime_state *gil = &runtime->ceval.gil; -#endif - if (!gil_created(gil)) { - return _PyStatus_OK(); - } - recreate_gil(gil); - - take_gil(tstate); - - struct _pending_calls *pending = &tstate->interp->ceval.pending; - if (_PyThread_at_fork_reinit(&pending->lock) < 0) { - return _PyStatus_ERR("Can't reinitialize pending calls lock"); - } - - /* Destroy all threads except the current one */ - _PyThreadState_DeleteExcept(runtime, tstate); - return _PyStatus_OK(); -} -#endif - -/* This function is used to signal that async exceptions are waiting to be - raised. */ - -void -_PyEval_SignalAsyncExc(PyInterpreterState *interp) -{ - SIGNAL_ASYNC_EXC(interp); -} - -PyThreadState * -PyEval_SaveThread(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - PyThreadState *old_tstate = _PyThreadState_GET(); - PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, old_tstate); -#else - PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); -#endif - _Py_EnsureTstateNotNULL(tstate); - - struct _ceval_runtime_state *ceval = &runtime->ceval; - struct _ceval_state *ceval2 = &tstate->interp->ceval; -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - assert(gil_created(&ceval2->gil)); -#else - assert(gil_created(&ceval->gil)); -#endif - drop_gil(ceval, ceval2, tstate); - return tstate; -} - -void -PyEval_RestoreThread(PyThreadState *tstate) -{ - _Py_EnsureTstateNotNULL(tstate); - - take_gil(tstate); - - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; - _PyThreadState_Swap(gilstate, tstate); -} - - -/* Mechanism whereby asynchronously executing callbacks (e.g. UNIX - signal handlers or Mac I/O completion routines) can schedule calls - to a function to be called synchronously. - The synchronous function is called with one void* argument. - It should return 0 for success or -1 for failure -- failure should - be accompanied by an exception. - - If registry succeeds, the registry function returns 0; if it fails - (e.g. due to too many pending calls) it returns -1 (without setting - an exception condition). - - Note that because registry may occur from within signal handlers, - or other asynchronous events, calling malloc() is unsafe! - - Any thread can schedule pending calls, but only the main thread - will execute them. - There is no facility to schedule calls to a particular thread, but - that should be easy to change, should that ever be required. In - that case, the static variables here should go into the python - threadstate. -*/ - -void -_PyEval_SignalReceived(PyInterpreterState *interp) -{ -#ifdef MS_WINDOWS - // bpo-42296: On Windows, _PyEval_SignalReceived() is called from a signal - // handler which can run in a thread different than the Python thread, in - // which case _Py_ThreadCanHandleSignals() is wrong. Ignore - // _Py_ThreadCanHandleSignals() and always set eval_breaker to 1. - // - // The next eval_frame_handle_pending() call will call - // _Py_ThreadCanHandleSignals() to recompute eval_breaker. - int force = 1; -#else - int force = 0; -#endif - /* bpo-30703: Function called when the C signal handler of Python gets a - signal. We cannot queue a callback using _PyEval_AddPendingCall() since - that function is not async-signal-safe. */ - SIGNAL_PENDING_SIGNALS(interp, force); -} - -/* Push one item onto the queue while holding the lock. */ -static int -_push_pending_call(struct _pending_calls *pending, - int (*func)(void *), void *arg) -{ - int i = pending->last; - int j = (i + 1) % NPENDINGCALLS; - if (j == pending->first) { - return -1; /* Queue full */ - } - pending->calls[i].func = func; - pending->calls[i].arg = arg; - pending->last = j; - return 0; -} - -/* Pop one item off the queue while holding the lock. */ -static void -_pop_pending_call(struct _pending_calls *pending, - int (**func)(void *), void **arg) -{ - int i = pending->first; - if (i == pending->last) { - return; /* Queue empty */ - } - - *func = pending->calls[i].func; - *arg = pending->calls[i].arg; - pending->first = (i + 1) % NPENDINGCALLS; -} - -/* This implementation is thread-safe. It allows - scheduling to be made from any thread, and even from an executing - callback. - */ - -int -_PyEval_AddPendingCall(PyInterpreterState *interp, - int (*func)(void *), void *arg) -{ - struct _pending_calls *pending = &interp->ceval.pending; - - /* Ensure that _PyEval_InitPendingCalls() was called - and that _PyEval_FiniPendingCalls() is not called yet. */ - assert(pending->lock != NULL); - - PyThread_acquire_lock(pending->lock, WAIT_LOCK); - int result = _push_pending_call(pending, func, arg); - PyThread_release_lock(pending->lock); - - /* signal main loop */ - SIGNAL_PENDING_CALLS(interp); - return result; -} - -int -Py_AddPendingCall(int (*func)(void *), void *arg) -{ - /* Best-effort to support subinterpreters and calls with the GIL released. - - First attempt _PyThreadState_GET() since it supports subinterpreters. - - If the GIL is released, _PyThreadState_GET() returns NULL . In this - case, use PyGILState_GetThisThreadState() which works even if the GIL - is released. - - Sadly, PyGILState_GetThisThreadState() doesn't support subinterpreters: - see bpo-10915 and bpo-15751. - - Py_AddPendingCall() doesn't require the caller to hold the GIL. */ - PyThreadState *tstate = _PyThreadState_GET(); - if (tstate == NULL) { - tstate = PyGILState_GetThisThreadState(); - } - - PyInterpreterState *interp; - if (tstate != NULL) { - interp = tstate->interp; - } - else { - /* Last resort: use the main interpreter */ - interp = _PyRuntime.interpreters.main; - } - return _PyEval_AddPendingCall(interp, func, arg); -} - -static int -handle_signals(PyThreadState *tstate) -{ - assert(is_tstate_valid(tstate)); - if (!_Py_ThreadCanHandleSignals(tstate->interp)) { - return 0; - } - - UNSIGNAL_PENDING_SIGNALS(tstate->interp); - if (_PyErr_CheckSignalsTstate(tstate) < 0) { - /* On failure, re-schedule a call to handle_signals(). */ - SIGNAL_PENDING_SIGNALS(tstate->interp, 0); - return -1; - } - return 0; -} - -static int -make_pending_calls(PyInterpreterState *interp) -{ - /* only execute pending calls on main thread */ - if (!_Py_ThreadCanHandlePendingCalls()) { - return 0; - } - - /* don't perform recursive pending calls */ - static int busy = 0; - if (busy) { - return 0; - } - busy = 1; - - /* unsignal before starting to call callbacks, so that any callback - added in-between re-signals */ - UNSIGNAL_PENDING_CALLS(interp); - int res = 0; - - /* perform a bounded number of calls, in case of recursion */ - struct _pending_calls *pending = &interp->ceval.pending; - for (int i=0; ilock, WAIT_LOCK); - _pop_pending_call(pending, &func, &arg); - PyThread_release_lock(pending->lock); - - /* having released the lock, perform the callback */ - if (func == NULL) { - break; - } - res = func(arg); - if (res) { - goto error; - } - } - - busy = 0; - return res; - -error: - busy = 0; - SIGNAL_PENDING_CALLS(interp); - return res; -} - -void -_Py_FinishPendingCalls(PyThreadState *tstate) -{ - assert(PyGILState_Check()); - assert(is_tstate_valid(tstate)); - - struct _pending_calls *pending = &tstate->interp->ceval.pending; - - if (!_Py_atomic_load_relaxed(&(pending->calls_to_do))) { - return; - } - - if (make_pending_calls(tstate->interp) < 0) { - PyObject *exc, *val, *tb; - _PyErr_Fetch(tstate, &exc, &val, &tb); - PyErr_BadInternalCall(); - _PyErr_ChainExceptions(exc, val, tb); - _PyErr_Print(tstate); - } -} - -/* Py_MakePendingCalls() is a simple wrapper for the sake - of backward-compatibility. */ -int -Py_MakePendingCalls(void) -{ - assert(PyGILState_Check()); - - PyThreadState *tstate = _PyThreadState_GET(); - assert(is_tstate_valid(tstate)); - - /* Python signal handler doesn't really queue a callback: it only signals - that a signal was received, see _PyEval_SignalReceived(). */ - int res = handle_signals(tstate); - if (res != 0) { - return res; - } - - res = make_pending_calls(tstate->interp); - if (res != 0) { - return res; - } - - return 0; -} - -/* The interpreter's recursion limit */ - -#ifndef Py_DEFAULT_RECURSION_LIMIT -# define Py_DEFAULT_RECURSION_LIMIT 1000 -#endif - -void -_PyEval_InitRuntimeState(struct _ceval_runtime_state *ceval) -{ -#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - _gil_initialize(&ceval->gil); -#endif -} - -int -_PyEval_InitState(struct _ceval_state *ceval) -{ - ceval->recursion_limit = Py_DEFAULT_RECURSION_LIMIT; - - struct _pending_calls *pending = &ceval->pending; - assert(pending->lock == NULL); - - pending->lock = PyThread_allocate_lock(); - if (pending->lock == NULL) { - return -1; - } - -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - _gil_initialize(&ceval->gil); -#endif - - return 0; -} - -void -_PyEval_FiniState(struct _ceval_state *ceval) -{ - struct _pending_calls *pending = &ceval->pending; - if (pending->lock != NULL) { - PyThread_free_lock(pending->lock); - pending->lock = NULL; - } -} int Py_GetRecursionLimit(void) @@ -787,47 +250,39 @@ Py_SetRecursionLimit(int new_limit) { PyInterpreterState *interp = _PyInterpreterState_GET(); interp->ceval.recursion_limit = new_limit; - for (PyThreadState *p = interp->tstate_head; p != NULL; p = p->next) { - int depth = p->recursion_limit - p->recursion_remaining; - p->recursion_limit = new_limit; - p->recursion_remaining = new_limit - depth; + for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) { + int depth = p->py_recursion_limit - p->py_recursion_remaining; + p->py_recursion_limit = new_limit; + p->py_recursion_remaining = new_limit - depth; } } -/* The function _Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall() +/* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall() if the recursion_depth reaches recursion_limit. */ int _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) { - /* Check against global limit first. */ - int depth = tstate->recursion_limit - tstate->recursion_remaining; - if (depth < tstate->interp->ceval.recursion_limit) { - tstate->recursion_limit = tstate->interp->ceval.recursion_limit; - tstate->recursion_remaining = tstate->recursion_limit - depth; - assert(tstate->recursion_remaining > 0); - return 0; - } #ifdef USE_STACKCHECK if (PyOS_CheckStack()) { - ++tstate->recursion_remaining; + ++tstate->c_recursion_remaining; _PyErr_SetString(tstate, PyExc_MemoryError, "Stack overflow"); return -1; } #endif if (tstate->recursion_headroom) { - if (tstate->recursion_remaining < -50) { + if (tstate->c_recursion_remaining < -50) { /* Overflowing while handling an overflow. Give up. */ Py_FatalError("Cannot recover from stack overflow."); } } else { - if (tstate->recursion_remaining <= 0) { + if (tstate->c_recursion_remaining <= 0) { tstate->recursion_headroom++; _PyErr_Format(tstate, PyExc_RecursionError, "maximum recursion depth exceeded%s", where); tstate->recursion_headroom--; - ++tstate->recursion_remaining; + ++tstate->c_recursion_remaining; return -1; } } @@ -882,18 +337,12 @@ match_keys(PyThreadState *tstate, PyObject *map, PyObject *keys) PyObject *seen = NULL; PyObject *dummy = NULL; PyObject *values = NULL; - PyObject *get_name = NULL; PyObject *get = NULL; // We use the two argument form of map.get(key, default) for two reasons: // - Atomically check for a key and get its value without error handling. // - Don't cause key creation or resizing in dict subclasses like // collections.defaultdict that define __missing__ (or similar). - _Py_IDENTIFIER(get); - get_name = _PyUnicode_FromId(&PyId_get); // borrowed - if (get_name == NULL) { - return NULL; - } - int meth_found = _PyObject_GetMethod(map, get_name, &get); + int meth_found = _PyObject_GetMethod(map, &_Py_ID(get), &get); if (get == NULL) { goto fail; } @@ -936,8 +385,7 @@ match_keys(PyThreadState *tstate, PyObject *map, PyObject *keys) Py_DECREF(value); Py_DECREF(values); // Return None: - Py_INCREF(Py_None); - values = Py_None; + values = Py_NewRef(Py_None); goto done; } PyTuple_SET_ITEM(values, i, value); @@ -1093,26 +541,12 @@ fail: static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause); +static int exception_group_match( + PyObject* exc_value, PyObject *match_type, + PyObject **match, PyObject **rest); + static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **); -#ifdef Py_DEBUG -static void -_assert_exception_type_is_redundant(PyObject* type, PyObject* val) -{ - if (type == NULL || type == Py_None) { - assert(val == NULL || val == Py_None); - } - else { - assert(PyExceptionInstance_Check(val)); - assert(PyExceptionInstance_Class(val) == type); - } -} - -#define ASSERT_EXC_TYPE_IS_REDUNDANT(t, v) _assert_exception_type_is_redundant(t, v) -#else -#define ASSERT_EXC_TYPE_IS_REDUNDANT(t, v) -#endif - PyObject * PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) { @@ -1134,7 +568,14 @@ PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) .fc_kwdefaults = NULL, .fc_closure = NULL }; - return _PyEval_Vector(tstate, &desc, locals, NULL, 0, NULL); + PyFunctionObject *func = _PyFunction_FromConstructor(&desc); + if (func == NULL) { + return NULL; + } + EVAL_CALL_STAT_INC(EVAL_CALL_LEGACY); + PyObject *res = _PyEval_Vector(tstate, func, locals, NULL, 0, NULL); + Py_DECREF(func); + return res; } @@ -1155,382 +596,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) return _PyEval_EvalFrame(tstate, f->f_frame, throwflag); } - -/* Handle signals, pending calls, GIL drop request - and asynchronous exception */ -static int -eval_frame_handle_pending(PyThreadState *tstate) -{ - _PyRuntimeState * const runtime = &_PyRuntime; - struct _ceval_runtime_state *ceval = &runtime->ceval; - - /* Pending signals */ - if (_Py_atomic_load_relaxed(&ceval->signals_pending)) { - if (handle_signals(tstate) != 0) { - return -1; - } - } - - /* Pending calls */ - struct _ceval_state *ceval2 = &tstate->interp->ceval; - if (_Py_atomic_load_relaxed(&ceval2->pending.calls_to_do)) { - if (make_pending_calls(tstate->interp) != 0) { - return -1; - } - } - - /* GIL drop request */ - if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request)) { - /* Give another thread a chance */ - if (_PyThreadState_Swap(&runtime->gilstate, NULL) != tstate) { - Py_FatalError("tstate mix-up"); - } - drop_gil(ceval, ceval2, tstate); - - /* Other threads may run now */ - - take_gil(tstate); - -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - (void)_PyThreadState_Swap(&runtime->gilstate, tstate); -#else - if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { - Py_FatalError("orphan tstate"); - } -#endif - } - - /* Check for asynchronous exception. */ - if (tstate->async_exc != NULL) { - PyObject *exc = tstate->async_exc; - tstate->async_exc = NULL; - UNSIGNAL_ASYNC_EXC(tstate->interp); - _PyErr_SetNone(tstate, exc); - Py_DECREF(exc); - return -1; - } - -#ifdef MS_WINDOWS - // bpo-42296: On Windows, _PyEval_SignalReceived() can be called in a - // different thread than the Python thread, in which case - // _Py_ThreadCanHandleSignals() is wrong. Recompute eval_breaker in the - // current Python thread with the correct _Py_ThreadCanHandleSignals() - // value. It prevents to interrupt the eval loop at every instruction if - // the current Python thread cannot handle signals (if - // _Py_ThreadCanHandleSignals() is false). - COMPUTE_EVAL_BREAKER(tstate->interp, ceval, ceval2); -#endif - - return 0; -} - - -/* Computed GOTOs, or - the-optimization-commonly-but-improperly-known-as-"threaded code" - using gcc's labels-as-values extension - (http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html). - - The traditional bytecode evaluation loop uses a "switch" statement, which - decent compilers will optimize as a single indirect branch instruction - combined with a lookup table of jump addresses. However, since the - indirect jump instruction is shared by all opcodes, the CPU will have a - hard time making the right prediction for where to jump next (actually, - it will be always wrong except in the uncommon case of a sequence of - several identical opcodes). - - "Threaded code" in contrast, uses an explicit jump table and an explicit - indirect jump instruction at the end of each opcode. Since the jump - instruction is at a different address for each opcode, the CPU will make a - separate prediction for each of these instructions, which is equivalent to - predicting the second opcode of each opcode pair. These predictions have - a much better chance to turn out valid, especially in small bytecode loops. - - A mispredicted branch on a modern CPU flushes the whole pipeline and - can cost several CPU cycles (depending on the pipeline depth), - and potentially many more instructions (depending on the pipeline width). - A correctly predicted branch, however, is nearly free. - - At the time of this writing, the "threaded code" version is up to 15-20% - faster than the normal "switch" version, depending on the compiler and the - CPU architecture. - - We disable the optimization if DYNAMIC_EXECUTION_PROFILE is defined, - because it would render the measurements invalid. - - - NOTE: care must be taken that the compiler doesn't try to "optimize" the - indirect jumps by sharing them between all opcodes. Such optimizations - can be disabled on gcc by using the -fno-gcse flag (or possibly - -fno-crossjumping). -*/ - -/* Use macros rather than inline functions, to make it as clear as possible - * to the C compiler that the tracing check is a simple test then branch. - * We want to be sure that the compiler knows this before it generates - * the CFG. - */ -#ifdef LLTRACE -#define LLTRACE_INSTR() if (lltrace) { lltrace_instruction(frame, opcode, oparg); } -#else -#define LLTRACE_INSTR() ((void)0) -#endif - -#ifdef WITH_DTRACE -#define OR_DTRACE_LINE | (PyDTrace_LINE_ENABLED() ? 255 : 0) -#else -#define OR_DTRACE_LINE -#endif - -#ifdef DYNAMIC_EXECUTION_PROFILE -#undef USE_COMPUTED_GOTOS -#define USE_COMPUTED_GOTOS 0 -#endif - -#ifdef HAVE_COMPUTED_GOTOS - #ifndef USE_COMPUTED_GOTOS - #define USE_COMPUTED_GOTOS 1 - #endif -#else - #if defined(USE_COMPUTED_GOTOS) && USE_COMPUTED_GOTOS - #error "Computed gotos are not supported on this compiler." - #endif - #undef USE_COMPUTED_GOTOS - #define USE_COMPUTED_GOTOS 0 -#endif - -#define INSTRUCTION_START() frame->f_lasti = INSTR_OFFSET(); next_instr++ - -#if USE_COMPUTED_GOTOS -#define TARGET(op) TARGET_##op: INSTRUCTION_START(); -#define DISPATCH_GOTO() goto *opcode_targets[opcode] -#else -#define TARGET(op) case op: INSTRUCTION_START(); -#define DISPATCH_GOTO() goto dispatch_opcode -#endif - -/* RECORD_DXPROFILE() records the dxprofile information, if enabled. Normally a no-op */ -#ifdef DYNAMIC_EXECUTION_PROFILE -#ifdef DXPAIRS -#define RECORD_DXPROFILE() \ - do { \ - dxpairs[lastopcode][opcode]++; \ - lastopcode = opcode; \ - dxp[opcode]++; \ - } while (0) -#else - #define RECORD_DXPROFILE() \ - do { \ - dxp[opcode]++; \ - } while (0) -#endif -#else -#define RECORD_DXPROFILE() ((void)0) -#endif - -/* PRE_DISPATCH_GOTO() does lltrace and dxprofile if either is enabled. Normally a no-op */ -#ifndef LLTRACE -#ifndef DYNAMIC_EXECUTION_PROFILE -#define PRE_DISPATCH_GOTO() ((void)0) -#endif -#endif -#ifndef PRE_DISPATCH_GOTO -#define PRE_DISPATCH_GOTO() do { LLTRACE_INSTR(); RECORD_DXPROFILE(); } while (0) -#endif - -#define NOTRACE_DISPATCH() \ - { \ - NEXTOPARG(); \ - PRE_DISPATCH_GOTO(); \ - DISPATCH_GOTO(); \ - } - -/* Do interpreter dispatch accounting for tracing and instrumentation */ -#define DISPATCH() \ - { \ - NEXTOPARG(); \ - PRE_DISPATCH_GOTO(); \ - assert(cframe.use_tracing == 0 || cframe.use_tracing == 255); \ - opcode |= cframe.use_tracing OR_DTRACE_LINE; \ - DISPATCH_GOTO(); \ - } - -#define CHECK_EVAL_BREAKER() \ - if (_Py_atomic_load_relaxed(eval_breaker)) { \ - goto check_eval_breaker; \ - } - - -/* Tuple access macros */ - -#ifndef Py_DEBUG -#define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i)) -#else -#define GETITEM(v, i) PyTuple_GetItem((v), (i)) -#endif - -/* Code access macros */ - -/* The integer overflow is checked by an assertion below. */ -#define INSTR_OFFSET() ((int)(next_instr - first_instr)) -#define NEXTOPARG() do { \ - _Py_CODEUNIT word = *next_instr; \ - opcode = _Py_OPCODE(word); \ - oparg = _Py_OPARG(word); \ - } while (0) -#define JUMPTO(x) (next_instr = first_instr + (x)) -#define JUMPBY(x) (next_instr += (x)) - -/* Get opcode and oparg from original instructions, not quickened form. */ -#define TRACING_NEXTOPARG() do { \ - _Py_CODEUNIT word = ((_Py_CODEUNIT *)PyBytes_AS_STRING(co->co_code))[INSTR_OFFSET()]; \ - opcode = _Py_OPCODE(word); \ - oparg = _Py_OPARG(word); \ - } while (0) - -/* OpCode prediction macros - Some opcodes tend to come in pairs thus making it possible to - predict the second code when the first is run. For example, - COMPARE_OP is often followed by POP_JUMP_IF_FALSE or POP_JUMP_IF_TRUE. - - Verifying the prediction costs a single high-speed test of a register - variable against a constant. If the pairing was good, then the - processor's own internal branch predication has a high likelihood of - success, resulting in a nearly zero-overhead transition to the - next opcode. A successful prediction saves a trip through the eval-loop - including its unpredictable switch-case branch. Combined with the - processor's internal branch prediction, a successful PREDICT has the - effect of making the two opcodes run as if they were a single new opcode - with the bodies combined. - - If collecting opcode statistics, your choices are to either keep the - predictions turned-on and interpret the results as if some opcodes - had been combined or turn-off predictions so that the opcode frequency - counter updates for both opcodes. - - Opcode prediction is disabled with threaded code, since the latter allows - the CPU to record separate branch prediction information for each - opcode. - -*/ - -#define PREDICT_ID(op) PRED_##op - -#if defined(DYNAMIC_EXECUTION_PROFILE) || USE_COMPUTED_GOTOS -#define PREDICT(op) if (0) goto PREDICT_ID(op) -#else -#define PREDICT(op) \ - do { \ - _Py_CODEUNIT word = *next_instr; \ - opcode = _Py_OPCODE(word) | cframe.use_tracing OR_DTRACE_LINE; \ - if (opcode == op) { \ - oparg = _Py_OPARG(word); \ - INSTRUCTION_START(); \ - goto PREDICT_ID(op); \ - } \ - } while(0) -#endif -#define PREDICTED(op) PREDICT_ID(op): - - -/* Stack manipulation macros */ - -/* The stack can grow at most MAXINT deep, as co_nlocals and - co_stacksize are ints. */ -#define STACK_LEVEL() ((int)(stack_pointer - _PyFrame_Stackbase(frame))) -#define EMPTY() (STACK_LEVEL() == 0) -#define TOP() (stack_pointer[-1]) -#define SECOND() (stack_pointer[-2]) -#define THIRD() (stack_pointer[-3]) -#define FOURTH() (stack_pointer[-4]) -#define PEEK(n) (stack_pointer[-(n)]) -#define SET_TOP(v) (stack_pointer[-1] = (v)) -#define SET_SECOND(v) (stack_pointer[-2] = (v)) -#define SET_THIRD(v) (stack_pointer[-3] = (v)) -#define SET_FOURTH(v) (stack_pointer[-4] = (v)) -#define BASIC_STACKADJ(n) (stack_pointer += n) -#define BASIC_PUSH(v) (*stack_pointer++ = (v)) -#define BASIC_POP() (*--stack_pointer) - -#ifdef LLTRACE -#define PUSH(v) { (void)(BASIC_PUSH(v), \ - lltrace && prtrace(tstate, TOP(), "push")); \ - assert(STACK_LEVEL() <= co->co_stacksize); } -#define POP() ((void)(lltrace && prtrace(tstate, TOP(), "pop")), \ - BASIC_POP()) -#define STACK_GROW(n) do { \ - assert(n >= 0); \ - (void)(BASIC_STACKADJ(n), \ - lltrace && prtrace(tstate, TOP(), "stackadj")); \ - assert(STACK_LEVEL() <= co->co_stacksize); \ - } while (0) -#define STACK_SHRINK(n) do { \ - assert(n >= 0); \ - (void)(lltrace && prtrace(tstate, TOP(), "stackadj")); \ - (void)(BASIC_STACKADJ(-(n))); \ - assert(STACK_LEVEL() <= co->co_stacksize); \ - } while (0) -#define EXT_POP(STACK_POINTER) ((void)(lltrace && \ - prtrace(tstate, (STACK_POINTER)[-1], "ext_pop")), \ - *--(STACK_POINTER)) -#else -#define PUSH(v) BASIC_PUSH(v) -#define POP() BASIC_POP() -#define STACK_GROW(n) BASIC_STACKADJ(n) -#define STACK_SHRINK(n) BASIC_STACKADJ(-(n)) -#define EXT_POP(STACK_POINTER) (*--(STACK_POINTER)) -#endif - -/* Local variable macros */ - -#define GETLOCAL(i) (frame->localsplus[i]) - -/* The SETLOCAL() macro must not DECREF the local variable in-place and - then store the new value; it must copy the old value to a temporary - value, then store the new value, and then DECREF the temporary value. - This is because it is possible that during the DECREF the frame is - accessed by other code (e.g. a __del__ method or gc.collect()) and the - variable would be pointing to already-freed memory. */ -#define SETLOCAL(i, value) do { PyObject *tmp = GETLOCAL(i); \ - GETLOCAL(i) = value; \ - Py_XDECREF(tmp); } while (0) - -#define JUMP_TO_INSTRUCTION(op) goto PREDICT_ID(op) - -#define GET_CACHE() \ - _GetSpecializedCacheEntryForInstruction(first_instr, INSTR_OFFSET(), oparg) - - -#define DEOPT_IF(cond, instname) if (cond) { goto instname ## _miss; } - -#define UPDATE_PREV_INSTR_OPARG(instr, oparg) ((uint8_t*)(instr))[-1] = (oparg) - - -#define GLOBALS() frame->f_globals -#define BUILTINS() frame->f_builtins -#define LOCALS() frame->f_locals - -/* Shared opcode macros */ - -// shared by LOAD_ATTR_MODULE and LOAD_METHOD_MODULE -#define LOAD_MODULE_ATTR_OR_METHOD(attr_or_method) \ - SpecializedCacheEntry *caches = GET_CACHE(); \ - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; \ - _PyAttrCache *cache1 = &caches[-1].attr; \ - DEOPT_IF(!PyModule_CheckExact(owner), LOAD_##attr_or_method); \ - PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; \ - assert(dict != NULL); \ - DEOPT_IF(dict->ma_keys->dk_version != cache1->dk_version_or_hint, \ - LOAD_##attr_or_method); \ - assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); \ - assert(cache0->index < dict->ma_keys->dk_nentries); \ - PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + cache0->index; \ - res = ep->me_value; \ - DEOPT_IF(res == NULL, LOAD_##attr_or_method); \ - STAT_INC(LOAD_##attr_or_method, hit); \ - Py_INCREF(res); +#include "ceval_macros.h" static int -trace_function_entry(PyThreadState *tstate, InterpreterFrame *frame) +trace_function_entry(PyThreadState *tstate, _PyInterpreterFrame *frame) { if (tstate->c_tracefunc != NULL) { /* tstate->c_tracefunc, if defined, is a @@ -1568,131 +637,198 @@ trace_function_entry(PyThreadState *tstate, InterpreterFrame *frame) return 0; } -static PyObject * -make_coro(PyThreadState *tstate, PyFrameConstructor *con, - PyObject *locals, - PyObject* const* args, size_t argcount, - PyObject *kwnames); - static int -skip_backwards_over_extended_args(PyCodeObject *code, int offset) { - _Py_CODEUNIT *instrs = (_Py_CODEUNIT *)PyBytes_AS_STRING(code->co_code); - while (offset > 0 && _Py_OPCODE(instrs[offset-1]) == EXTENDED_ARG) { - offset--; +trace_function_exit(PyThreadState *tstate, _PyInterpreterFrame *frame, PyObject *retval) +{ + if (tstate->c_tracefunc) { + if (call_trace_protected(tstate->c_tracefunc, tstate->c_traceobj, + tstate, frame, PyTrace_RETURN, retval)) { + return -1; + } } - return offset; + if (tstate->c_profilefunc) { + if (call_trace_protected(tstate->c_profilefunc, tstate->c_profileobj, + tstate, frame, PyTrace_RETURN, retval)) { + return -1; + } + } + return 0; } + +int _Py_CheckRecursiveCallPy( + PyThreadState *tstate) +{ + if (tstate->recursion_headroom) { + if (tstate->py_recursion_remaining < -50) { + /* Overflowing while handling an overflow. Give up. */ + Py_FatalError("Cannot recover from Python stack overflow."); + } + } + else { + if (tstate->py_recursion_remaining <= 0) { + tstate->recursion_headroom++; + _PyErr_Format(tstate, PyExc_RecursionError, + "maximum recursion depth exceeded"); + tstate->recursion_headroom--; + return -1; + } + } + return 0; +} + +static inline int _Py_EnterRecursivePy(PyThreadState *tstate) { + return (tstate->py_recursion_remaining-- <= 0) && + _Py_CheckRecursiveCallPy(tstate); +} + + +static inline void _Py_LeaveRecursiveCallPy(PyThreadState *tstate) { + tstate->py_recursion_remaining++; +} + + +// GH-89279: Must be a macro to be sure it's inlined by MSVC. +#define is_method(stack_pointer, args) (PEEK((args)+2) != NULL) + +#define KWNAMES_LEN() \ + (kwnames == NULL ? 0 : ((int)PyTuple_GET_SIZE(kwnames))) + +/* Disable unused label warnings. They are handy for debugging, even + if computed gotos aren't used. */ + +/* TBD - what about other compilers? */ +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-label" +#elif defined(_MSC_VER) /* MS_WINDOWS */ +# pragma warning(push) +# pragma warning(disable:4102) +#endif + PyObject* _Py_HOT_FUNCTION -_PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int throwflag) +_PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag) { _Py_EnsureTstateNotNULL(tstate); + CALL_STAT_INC(pyeval_calls); #if USE_COMPUTED_GOTOS /* Import the static jump table */ #include "opcode_targets.h" #endif -#ifdef DXPAIRS +#ifdef Py_STATS int lastopcode = 0; #endif - int opcode; /* Current opcode */ + // opcode is an 8-bit value to improve the code generated by MSVC + // for the big switch below (in combination with the EXTRA_CASES macro). + uint8_t opcode; /* Current opcode */ int oparg; /* Current opcode argument, if any */ - PyObject *retval = NULL; /* Return value */ _Py_atomic_int * const eval_breaker = &tstate->interp->ceval.eval_breaker; +#ifdef LLTRACE + int lltrace = 0; +#endif - CFrame cframe; + _PyCFrame cframe; + _PyInterpreterFrame entry_frame; + PyObject *kwnames = NULL; // Borrowed reference. Reset by CALL instructions. - /* WARNING: Because the CFrame lives on the C stack, + /* WARNING: Because the _PyCFrame lives on the C stack, * but can be accessed from a heap allocated object (tstate) * strict stack discipline must be maintained. */ - CFrame *prev_cframe = tstate->cframe; + _PyCFrame *prev_cframe = tstate->cframe; cframe.use_tracing = prev_cframe->use_tracing; cframe.previous = prev_cframe; tstate->cframe = &cframe; - assert(frame->depth == 0); + assert(tstate->interp->interpreter_trampoline != NULL); +#ifdef Py_DEBUG + /* Set these to invalid but identifiable values for debugging. */ + entry_frame.f_funcobj = (PyObject*)0xaaa0; + entry_frame.f_locals = (PyObject*)0xaaa1; + entry_frame.frame_obj = (PyFrameObject*)0xaaa2; + entry_frame.f_globals = (PyObject*)0xaaa3; + entry_frame.f_builtins = (PyObject*)0xaaa4; +#endif + entry_frame.f_code = tstate->interp->interpreter_trampoline; + entry_frame.prev_instr = + _PyCode_CODE(tstate->interp->interpreter_trampoline); + entry_frame.stacktop = 0; + entry_frame.owner = FRAME_OWNED_BY_CSTACK; + entry_frame.yield_offset = 0; /* Push frame */ - frame->previous = prev_cframe->current_frame; + entry_frame.previous = prev_cframe->current_frame; + frame->previous = &entry_frame; cframe.current_frame = frame; + if (_Py_EnterRecursiveCallTstate(tstate, "")) { + tstate->c_recursion_remaining--; + tstate->py_recursion_remaining--; + goto exit_unwind; + } + + /* support for generator.throw() */ + if (throwflag) { + if (_Py_EnterRecursivePy(tstate)) { + goto exit_unwind; + } + TRACE_FUNCTION_THROW_ENTRY(); + DTRACE_FUNCTION_ENTRY(); + goto resume_with_error; + } + + /* Local "register" variables. + * These are cached values from the frame and code object. */ + + PyObject *names; + PyObject *consts; + _Py_CODEUNIT *next_instr; + PyObject **stack_pointer; + +/* Sets the above local variables from the frame */ +#define SET_LOCALS_FROM_FRAME() \ + { \ + PyCodeObject *co = frame->f_code; \ + names = co->co_names; \ + consts = co->co_consts; \ + } \ + assert(_PyInterpreterFrame_LASTI(frame) >= -1); \ + /* Jump back to the last instruction executed... */ \ + next_instr = frame->prev_instr + 1; \ + stack_pointer = _PyFrame_GetStackPointer(frame); \ + /* Set stackdepth to -1. \ + Update when returning or calling trace function. \ + Having stackdepth <= 0 ensures that invalid \ + values are not visible to the cycle GC. \ + We choose -1 rather than 0 to assist debugging. \ + */ \ + frame->stacktop = -1; + + start_frame: - if (_Py_EnterRecursiveCall(tstate, "")) { - tstate->recursion_remaining--; - goto exit_eval_frame; - } - - assert(tstate->cframe == &cframe); - assert(frame == cframe.current_frame); - - if (cframe.use_tracing) { - if (trace_function_entry(tstate, frame)) { - goto exit_eval_frame; - } - } - - if (PyDTrace_FUNCTION_ENTRY_ENABLED()) - dtrace_function_entry(frame); - - PyCodeObject *co = frame->f_code; - /* Increment the warmup counter and quicken if warm enough - * _Py_Quicken is idempotent so we don't worry about overflow */ - if (!PyCodeObject_IsWarmedUp(co)) { - PyCodeObject_IncrementWarmup(co); - if (PyCodeObject_IsWarmedUp(co)) { - if (_Py_Quicken(co)) { - goto exit_eval_frame; - } - } + if (_Py_EnterRecursivePy(tstate)) { + goto exit_unwind; } resume_frame: - co = frame->f_code; - PyObject *names = co->co_names; - PyObject *consts = co->co_consts; - _Py_CODEUNIT *first_instr = co->co_firstinstr; - /* - frame->f_lasti refers to the index of the last instruction, - unless it's -1 in which case next_instr should be first_instr. - - YIELD_FROM sets frame->f_lasti to itself, in order to repeatedly yield - multiple values. - - When the PREDICT() macros are enabled, some opcode pairs follow in - direct succession. A successful prediction effectively links the two - codes together as if they were a single new opcode, but the value - of frame->f_lasti is correctly updated so potential inlined calls - or lookups of frame->f_lasti are aways correct when the macros are used. - */ - assert(frame->f_lasti >= -1); - _Py_CODEUNIT *next_instr = first_instr + frame->f_lasti + 1; - PyObject **stack_pointer = _PyFrame_GetStackPointer(frame); - /* Set stackdepth to -1. - * Update when returning or calling trace function. - Having stackdepth <= 0 ensures that invalid - values are not visible to the cycle GC. - We choose -1 rather than 0 to assist debugging. - */ - frame->stacktop = -1; - frame->f_state = FRAME_EXECUTING; + SET_LOCALS_FROM_FRAME(); #ifdef LLTRACE - _Py_IDENTIFIER(__ltrace__); { - int r = _PyDict_ContainsId(GLOBALS(), &PyId___ltrace__); - if (r < 0) { - goto exit_eval_frame; + if (frame != &entry_frame) { + int r = PyDict_Contains(GLOBALS(), &_Py_ID(__lltrace__)); + if (r < 0) { + goto exit_unwind; + } + lltrace = r; + } + if (lltrace) { + lltrace_resume_frame(frame); } - lltrace = r; } #endif - if (throwflag) { /* support for generator.throw() */ - throwflag = 0; - goto error; - } - #ifdef Py_DEBUG /* _PyEval_EvalFrameDefault() must not be called with an exception set, because it can clear it (directly or indirectly) and so the @@ -1700,3247 +836,128 @@ resume_frame: assert(!_PyErr_Occurred(tstate)); #endif -check_eval_breaker: - { - assert(STACK_LEVEL() >= 0); /* else underflow */ - assert(STACK_LEVEL() <= co->co_stacksize); /* else overflow */ - assert(!_PyErr_Occurred(tstate)); - - /* Do periodic things. Doing this every time through - the loop would add too much overhead, so we do it - only every Nth instruction. We also do it if - ``pending.calls_to_do'' is set, i.e. when an asynchronous - event needs attention (e.g. a signal handler or - async I/O handler); see Py_AddPendingCall() and - Py_MakePendingCalls() above. */ - - if (_Py_atomic_load_relaxed(eval_breaker)) { - opcode = _Py_OPCODE(*next_instr); - if (opcode != BEFORE_ASYNC_WITH && - opcode != YIELD_FROM) { - /* Few cases where we skip running signal handlers and other - pending calls: - - If we're about to enter the 'with:'. It will prevent - emitting a resource warning in the common idiom - 'with open(path) as file:'. - - If we're about to enter the 'async with:'. - - If we're about to enter the 'try:' of a try/finally (not - *very* useful, but might help in some cases and it's - traditional) - - If we're resuming a chain of nested 'yield from' or - 'await' calls, then each frame is parked with YIELD_FROM - as its next opcode. If the user hit control-C we want to - wait until we've reached the innermost frame before - running the signal handler and raising KeyboardInterrupt - (see bpo-30039). - */ - if (eval_frame_handle_pending(tstate) != 0) { - goto error; - } - } - } - DISPATCH(); - /* Start instructions */ -#if USE_COMPUTED_GOTOS +handle_eval_breaker: + + /* Do periodic things, like check for signals and async I/0. + * We need to do reasonably frequently, but not too frequently. + * All loops should include a check of the eval breaker. + * We also check on return from any builtin function. + */ + if (_Py_HandlePending(tstate) != 0) { + goto error; + } + DISPATCH(); + { -#else + /* Start instructions */ +#if !USE_COMPUTED_GOTOS dispatch_opcode: - switch (opcode) { + switch (opcode) #endif + { - /* Variables used for making calls */ - PyObject *kwnames; - int nargs; - int postcall_shrink; - - /* BEWARE! - It is essential that any operation that fails must goto error - and that all operation that succeed call DISPATCH() ! */ - - TARGET(NOP) { - DISPATCH(); - } - - TARGET(LOAD_CLOSURE) { - /* We keep LOAD_CLOSURE so that the bytecode stays more readable. */ - PyObject *value = GETLOCAL(oparg); - if (value == NULL) { - goto unbound_local_error; - } - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - TARGET(LOAD_FAST) { - PyObject *value = GETLOCAL(oparg); - if (value == NULL) { - goto unbound_local_error; - } - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - TARGET(LOAD_CONST) { - PREDICTED(LOAD_CONST); - PyObject *value = GETITEM(consts, oparg); - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - TARGET(STORE_FAST) { - PREDICTED(STORE_FAST); - PyObject *value = POP(); - SETLOCAL(oparg, value); - DISPATCH(); - } - - TARGET(LOAD_FAST__LOAD_FAST) { - PyObject *value = GETLOCAL(oparg); - if (value == NULL) { - goto unbound_local_error; - } - NEXTOPARG(); - next_instr++; - Py_INCREF(value); - PUSH(value); - value = GETLOCAL(oparg); - if (value == NULL) { - goto unbound_local_error; - } - Py_INCREF(value); - PUSH(value); - NOTRACE_DISPATCH(); - } - - TARGET(LOAD_FAST__LOAD_CONST) { - PyObject *value = GETLOCAL(oparg); - if (value == NULL) { - goto unbound_local_error; - } - NEXTOPARG(); - next_instr++; - Py_INCREF(value); - PUSH(value); - value = GETITEM(consts, oparg); - Py_INCREF(value); - PUSH(value); - NOTRACE_DISPATCH(); - } - - TARGET(STORE_FAST__LOAD_FAST) { - PyObject *value = POP(); - SETLOCAL(oparg, value); - NEXTOPARG(); - next_instr++; - value = GETLOCAL(oparg); - if (value == NULL) { - goto unbound_local_error; - } - Py_INCREF(value); - PUSH(value); - NOTRACE_DISPATCH(); - } - - TARGET(STORE_FAST__STORE_FAST) { - PyObject *value = POP(); - SETLOCAL(oparg, value); - NEXTOPARG(); - next_instr++; - value = POP(); - SETLOCAL(oparg, value); - NOTRACE_DISPATCH(); - } - - TARGET(LOAD_CONST__LOAD_FAST) { - PyObject *value = GETITEM(consts, oparg); - NEXTOPARG(); - next_instr++; - Py_INCREF(value); - PUSH(value); - value = GETLOCAL(oparg); - if (value == NULL) { - goto unbound_local_error; - } - Py_INCREF(value); - PUSH(value); - NOTRACE_DISPATCH(); - } - - TARGET(POP_TOP) { - PyObject *value = POP(); - Py_DECREF(value); - DISPATCH(); - } - - TARGET(ROT_TWO) { - PyObject *top = TOP(); - PyObject *second = SECOND(); - SET_TOP(second); - SET_SECOND(top); - DISPATCH(); - } - - TARGET(ROT_THREE) { - PyObject *top = TOP(); - PyObject *second = SECOND(); - PyObject *third = THIRD(); - SET_TOP(second); - SET_SECOND(third); - SET_THIRD(top); - DISPATCH(); - } - - TARGET(ROT_FOUR) { - PyObject *top = TOP(); - PyObject *second = SECOND(); - PyObject *third = THIRD(); - PyObject *fourth = FOURTH(); - SET_TOP(second); - SET_SECOND(third); - SET_THIRD(fourth); - SET_FOURTH(top); - DISPATCH(); - } - - TARGET(DUP_TOP) { - PyObject *top = TOP(); - Py_INCREF(top); - PUSH(top); - DISPATCH(); - } - - TARGET(DUP_TOP_TWO) { - PyObject *top = TOP(); - PyObject *second = SECOND(); - Py_INCREF(top); - Py_INCREF(second); - STACK_GROW(2); - SET_TOP(top); - SET_SECOND(second); - DISPATCH(); - } - - TARGET(UNARY_POSITIVE) { - PyObject *value = TOP(); - PyObject *res = PyNumber_Positive(value); - Py_DECREF(value); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(UNARY_NEGATIVE) { - PyObject *value = TOP(); - PyObject *res = PyNumber_Negative(value); - Py_DECREF(value); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(UNARY_NOT) { - PyObject *value = TOP(); - int err = PyObject_IsTrue(value); - Py_DECREF(value); - if (err == 0) { - Py_INCREF(Py_True); - SET_TOP(Py_True); - DISPATCH(); - } - else if (err > 0) { - Py_INCREF(Py_False); - SET_TOP(Py_False); - DISPATCH(); - } - STACK_SHRINK(1); - goto error; - } - - TARGET(UNARY_INVERT) { - PyObject *value = TOP(); - PyObject *res = PyNumber_Invert(value); - Py_DECREF(value); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(BINARY_OP_MULTIPLY_INT) { - PyObject *left = SECOND(); - PyObject *right = TOP(); - DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); - STAT_INC(BINARY_OP, hit); - PyObject *prod = _PyLong_Multiply((PyLongObject *)left, (PyLongObject *)right); - SET_SECOND(prod); - Py_DECREF(right); - Py_DECREF(left); - STACK_SHRINK(1); - if (prod == NULL) { - goto error; - } - DISPATCH(); - } - - TARGET(BINARY_OP_MULTIPLY_FLOAT) { - PyObject *left = SECOND(); - PyObject *right = TOP(); - DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); - STAT_INC(BINARY_OP, hit); - double dprod = ((PyFloatObject *)left)->ob_fval * - ((PyFloatObject *)right)->ob_fval; - PyObject *prod = PyFloat_FromDouble(dprod); - SET_SECOND(prod); - Py_DECREF(right); - Py_DECREF(left); - STACK_SHRINK(1); - if (prod == NULL) { - goto error; - } - DISPATCH(); - } - - TARGET(BINARY_OP_SUBTRACT_INT) { - PyObject *left = SECOND(); - PyObject *right = TOP(); - DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); - STAT_INC(BINARY_OP, hit); - PyObject *sub = _PyLong_Subtract((PyLongObject *)left, (PyLongObject *)right); - SET_SECOND(sub); - Py_DECREF(right); - Py_DECREF(left); - STACK_SHRINK(1); - if (sub == NULL) { - goto error; - } - DISPATCH(); - } - - TARGET(BINARY_OP_SUBTRACT_FLOAT) { - PyObject *left = SECOND(); - PyObject *right = TOP(); - DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); - STAT_INC(BINARY_OP, hit); - double dsub = ((PyFloatObject *)left)->ob_fval - ((PyFloatObject *)right)->ob_fval; - PyObject *sub = PyFloat_FromDouble(dsub); - SET_SECOND(sub); - Py_DECREF(right); - Py_DECREF(left); - STACK_SHRINK(1); - if (sub == NULL) { - goto error; - } - DISPATCH(); - } - - TARGET(BINARY_OP_ADD_UNICODE) { - PyObject *left = SECOND(); - PyObject *right = TOP(); - DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); - DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); - STAT_INC(BINARY_OP, hit); - PyObject *res = PyUnicode_Concat(left, right); - STACK_SHRINK(1); - SET_TOP(res); - Py_DECREF(left); - Py_DECREF(right); - if (TOP() == NULL) { - goto error; - } - DISPATCH(); - } - - TARGET(BINARY_OP_INPLACE_ADD_UNICODE) { - PyObject *left = SECOND(); - PyObject *right = TOP(); - DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); - DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); - DEOPT_IF(Py_REFCNT(left) != 2, BINARY_OP); - int next_oparg = _Py_OPARG(*next_instr); - assert(_Py_OPCODE(*next_instr) == STORE_FAST); - /* In the common case, there are 2 references to the value - * stored in 'variable' when the v = v + ... is performed: one - * on the value stack (in 'v') and one still stored in the - * 'variable'. We try to delete the variable now to reduce - * the refcnt to 1. - */ - PyObject *var = GETLOCAL(next_oparg); - DEOPT_IF(var != left, BINARY_OP); - STAT_INC(BINARY_OP, hit); - GETLOCAL(next_oparg) = NULL; - Py_DECREF(left); - STACK_SHRINK(1); - PyUnicode_Append(&TOP(), right); - Py_DECREF(right); - if (TOP() == NULL) { - goto error; - } - DISPATCH(); - } - - TARGET(BINARY_OP_ADD_FLOAT) { - PyObject *left = SECOND(); - PyObject *right = TOP(); - DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); - DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); - STAT_INC(BINARY_OP, hit); - double dsum = ((PyFloatObject *)left)->ob_fval + - ((PyFloatObject *)right)->ob_fval; - PyObject *sum = PyFloat_FromDouble(dsum); - SET_SECOND(sum); - Py_DECREF(right); - Py_DECREF(left); - STACK_SHRINK(1); - if (sum == NULL) { - goto error; - } - DISPATCH(); - } - - TARGET(BINARY_OP_ADD_INT) { - PyObject *left = SECOND(); - PyObject *right = TOP(); - DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); - DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); - STAT_INC(BINARY_OP, hit); - PyObject *sum = _PyLong_Add((PyLongObject *)left, (PyLongObject *)right); - SET_SECOND(sum); - Py_DECREF(right); - Py_DECREF(left); - STACK_SHRINK(1); - if (sum == NULL) { - goto error; - } - DISPATCH(); - } - - TARGET(BINARY_SUBSCR) { - PREDICTED(BINARY_SUBSCR); - STAT_INC(BINARY_SUBSCR, unquickened); - PyObject *sub = POP(); - PyObject *container = TOP(); - PyObject *res = PyObject_GetItem(container, sub); - Py_DECREF(container); - Py_DECREF(sub); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(BINARY_SUBSCR_ADAPTIVE) { - SpecializedCacheEntry *cache = GET_CACHE(); - if (cache->adaptive.counter == 0) { - PyObject *sub = TOP(); - PyObject *container = SECOND(); - next_instr--; - if (_Py_Specialize_BinarySubscr(container, sub, next_instr, cache) < 0) { - goto error; - } - DISPATCH(); - } - else { - STAT_INC(BINARY_SUBSCR, deferred); - cache->adaptive.counter--; - assert(cache->adaptive.original_oparg == 0); - /* No need to set oparg here; it isn't used by BINARY_SUBSCR */ - STAT_DEC(BINARY_SUBSCR, unquickened); - JUMP_TO_INSTRUCTION(BINARY_SUBSCR); - } - } - - TARGET(BINARY_SUBSCR_LIST_INT) { - PyObject *sub = TOP(); - PyObject *list = SECOND(); - DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); - DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR); - - // Deopt unless 0 <= sub < PyList_Size(list) - Py_ssize_t signed_magnitude = Py_SIZE(sub); - DEOPT_IF(((size_t)signed_magnitude) > 1, BINARY_SUBSCR); - assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0); - Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; - DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR); - STAT_INC(BINARY_SUBSCR, hit); - PyObject *res = PyList_GET_ITEM(list, index); - assert(res != NULL); - Py_INCREF(res); - STACK_SHRINK(1); - Py_DECREF(sub); - SET_TOP(res); - Py_DECREF(list); - DISPATCH(); - } - - TARGET(BINARY_SUBSCR_TUPLE_INT) { - PyObject *sub = TOP(); - PyObject *tuple = SECOND(); - DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); - DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR); - - // Deopt unless 0 <= sub < PyTuple_Size(list) - Py_ssize_t signed_magnitude = Py_SIZE(sub); - DEOPT_IF(((size_t)signed_magnitude) > 1, BINARY_SUBSCR); - assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0); - Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; - DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR); - STAT_INC(BINARY_SUBSCR, hit); - PyObject *res = PyTuple_GET_ITEM(tuple, index); - assert(res != NULL); - Py_INCREF(res); - STACK_SHRINK(1); - Py_DECREF(sub); - SET_TOP(res); - Py_DECREF(tuple); - DISPATCH(); - } - - TARGET(BINARY_SUBSCR_DICT) { - PyObject *dict = SECOND(); - DEOPT_IF(!PyDict_CheckExact(SECOND()), BINARY_SUBSCR); - STAT_INC(BINARY_SUBSCR, hit); - PyObject *sub = TOP(); - PyObject *res = PyDict_GetItemWithError(dict, sub); - if (res == NULL) { - goto binary_subscr_dict_error; - } - Py_INCREF(res); - STACK_SHRINK(1); - Py_DECREF(sub); - SET_TOP(res); - Py_DECREF(dict); - DISPATCH(); - } - - TARGET(BINARY_SUBSCR_GETITEM) { - PyObject *sub = TOP(); - PyObject *container = SECOND(); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - _PyObjectCache *cache1 = &caches[-1].obj; - PyFunctionObject *getitem = (PyFunctionObject *)cache1->obj; - DEOPT_IF(Py_TYPE(container)->tp_version_tag != cache0->version, BINARY_SUBSCR); - DEOPT_IF(getitem->func_version != cache0->index, BINARY_SUBSCR); - PyCodeObject *code = (PyCodeObject *)getitem->func_code; - size_t size = code->co_nlocalsplus + code->co_stacksize + FRAME_SPECIALS_SIZE; - assert(code->co_argcount == 2); - InterpreterFrame *new_frame = _PyThreadState_BumpFramePointer(tstate, size); - if (new_frame == NULL) { - goto error; - } - _PyFrame_InitializeSpecials(new_frame, PyFunction_AS_FRAME_CONSTRUCTOR(getitem), - NULL, code->co_nlocalsplus); - STACK_SHRINK(2); - new_frame->localsplus[0] = container; - new_frame->localsplus[1] = sub; - for (int i = 2; i < code->co_nlocalsplus; i++) { - new_frame->localsplus[i] = NULL; - } - _PyFrame_SetStackPointer(frame, stack_pointer); - new_frame->previous = frame; - frame = cframe.current_frame = new_frame; - new_frame->depth = frame->depth + 1; - goto start_frame; - } - - TARGET(LIST_APPEND) { - PyObject *v = POP(); - PyObject *list = PEEK(oparg); - int err; - err = PyList_Append(list, v); - Py_DECREF(v); - if (err != 0) - goto error; - PREDICT(JUMP_ABSOLUTE); - DISPATCH(); - } - - TARGET(SET_ADD) { - PyObject *v = POP(); - PyObject *set = PEEK(oparg); - int err; - err = PySet_Add(set, v); - Py_DECREF(v); - if (err != 0) - goto error; - PREDICT(JUMP_ABSOLUTE); - DISPATCH(); - } - - TARGET(STORE_SUBSCR) { - PREDICTED(STORE_SUBSCR); - STAT_INC(STORE_SUBSCR, unquickened); - PyObject *sub = TOP(); - PyObject *container = SECOND(); - PyObject *v = THIRD(); - int err; - STACK_SHRINK(3); - /* container[sub] = v */ - err = PyObject_SetItem(container, sub, v); - Py_DECREF(v); - Py_DECREF(container); - Py_DECREF(sub); - if (err != 0) - goto error; - DISPATCH(); - } - - TARGET(STORE_SUBSCR_ADAPTIVE) { - if (oparg == 0) { - PyObject *sub = TOP(); - PyObject *container = SECOND(); - next_instr--; - if (_Py_Specialize_StoreSubscr(container, sub, next_instr) < 0) { - goto error; - } - DISPATCH(); - } - else { - STAT_INC(STORE_SUBSCR, deferred); - // oparg is the adaptive cache counter - UPDATE_PREV_INSTR_OPARG(next_instr, oparg - 1); - STAT_DEC(STORE_SUBSCR, unquickened); - JUMP_TO_INSTRUCTION(STORE_SUBSCR); - } - } - - TARGET(STORE_SUBSCR_LIST_INT) { - PyObject *sub = TOP(); - PyObject *list = SECOND(); - PyObject *value = THIRD(); - DEOPT_IF(!PyLong_CheckExact(sub), STORE_SUBSCR); - DEOPT_IF(!PyList_CheckExact(list), STORE_SUBSCR); - - // Ensure nonnegative, zero-or-one-digit ints. - DEOPT_IF(((size_t)Py_SIZE(sub)) > 1, STORE_SUBSCR); - Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; - // Ensure index < len(list) - DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR); - STAT_INC(STORE_SUBSCR, hit); - - PyObject *old_value = PyList_GET_ITEM(list, index); - PyList_SET_ITEM(list, index, value); - STACK_SHRINK(3); - assert(old_value != NULL); - Py_DECREF(old_value); - Py_DECREF(sub); - Py_DECREF(list); - DISPATCH(); - } - - TARGET(STORE_SUBSCR_DICT) { - PyObject *sub = TOP(); - PyObject *dict = SECOND(); - PyObject *value = THIRD(); - DEOPT_IF(!PyDict_CheckExact(dict), STORE_SUBSCR); - STACK_SHRINK(3); - STAT_INC(STORE_SUBSCR, hit); - int err = _PyDict_SetItem_Take2((PyDictObject *)dict, sub, value); - Py_DECREF(dict); - if (err != 0) { - goto error; - } - DISPATCH(); - } - - TARGET(DELETE_SUBSCR) { - PyObject *sub = TOP(); - PyObject *container = SECOND(); - int err; - STACK_SHRINK(2); - /* del container[sub] */ - err = PyObject_DelItem(container, sub); - Py_DECREF(container); - Py_DECREF(sub); - if (err != 0) - goto error; - DISPATCH(); - } - - TARGET(PRINT_EXPR) { - _Py_IDENTIFIER(displayhook); - PyObject *value = POP(); - PyObject *hook = _PySys_GetObjectId(&PyId_displayhook); - PyObject *res; - if (hook == NULL) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "lost sys.displayhook"); - Py_DECREF(value); - goto error; - } - res = PyObject_CallOneArg(hook, value); - Py_DECREF(value); - if (res == NULL) - goto error; - Py_DECREF(res); - DISPATCH(); - } - - TARGET(RAISE_VARARGS) { - PyObject *cause = NULL, *exc = NULL; - switch (oparg) { - case 2: - cause = POP(); /* cause */ - /* fall through */ - case 1: - exc = POP(); /* exc */ - /* fall through */ - case 0: - if (do_raise(tstate, exc, cause)) { - goto exception_unwind; - } - break; - default: - _PyErr_SetString(tstate, PyExc_SystemError, - "bad RAISE_VARARGS oparg"); - break; - } - goto error; - } - - TARGET(RETURN_VALUE) { - retval = POP(); - assert(EMPTY()); - frame->f_state = FRAME_RETURNED; - _PyFrame_SetStackPointer(frame, stack_pointer); - goto exiting; - } - - TARGET(GET_AITER) { - unaryfunc getter = NULL; - PyObject *iter = NULL; - PyObject *obj = TOP(); - PyTypeObject *type = Py_TYPE(obj); - - if (type->tp_as_async != NULL) { - getter = type->tp_as_async->am_aiter; - } - - if (getter != NULL) { - iter = (*getter)(obj); - Py_DECREF(obj); - if (iter == NULL) { - SET_TOP(NULL); - goto error; - } - } - else { - SET_TOP(NULL); - _PyErr_Format(tstate, PyExc_TypeError, - "'async for' requires an object with " - "__aiter__ method, got %.100s", - type->tp_name); - Py_DECREF(obj); - goto error; - } - - if (Py_TYPE(iter)->tp_as_async == NULL || - Py_TYPE(iter)->tp_as_async->am_anext == NULL) { - - SET_TOP(NULL); - _PyErr_Format(tstate, PyExc_TypeError, - "'async for' received an object from __aiter__ " - "that does not implement __anext__: %.100s", - Py_TYPE(iter)->tp_name); - Py_DECREF(iter); - goto error; - } - - SET_TOP(iter); - DISPATCH(); - } - - TARGET(GET_ANEXT) { - unaryfunc getter = NULL; - PyObject *next_iter = NULL; - PyObject *awaitable = NULL; - PyObject *aiter = TOP(); - PyTypeObject *type = Py_TYPE(aiter); - - if (PyAsyncGen_CheckExact(aiter)) { - awaitable = type->tp_as_async->am_anext(aiter); - if (awaitable == NULL) { - goto error; - } - } else { - if (type->tp_as_async != NULL){ - getter = type->tp_as_async->am_anext; - } - - if (getter != NULL) { - next_iter = (*getter)(aiter); - if (next_iter == NULL) { - goto error; - } - } - else { - _PyErr_Format(tstate, PyExc_TypeError, - "'async for' requires an iterator with " - "__anext__ method, got %.100s", - type->tp_name); - goto error; - } - - awaitable = _PyCoro_GetAwaitableIter(next_iter); - if (awaitable == NULL) { - _PyErr_FormatFromCause( - PyExc_TypeError, - "'async for' received an invalid object " - "from __anext__: %.100s", - Py_TYPE(next_iter)->tp_name); - - Py_DECREF(next_iter); - goto error; - } else { - Py_DECREF(next_iter); - } - } - - PUSH(awaitable); - PREDICT(LOAD_CONST); - DISPATCH(); - } - - TARGET(GET_AWAITABLE) { - PREDICTED(GET_AWAITABLE); - PyObject *iterable = TOP(); - PyObject *iter = _PyCoro_GetAwaitableIter(iterable); - - if (iter == NULL) { - int opcode_at_minus_3 = 0; - if ((next_instr - first_instr) > 2) { - opcode_at_minus_3 = _Py_OPCODE(next_instr[-3]); - } - format_awaitable_error(tstate, Py_TYPE(iterable), - opcode_at_minus_3, - _Py_OPCODE(next_instr[-2])); - } - - Py_DECREF(iterable); - - if (iter != NULL && PyCoro_CheckExact(iter)) { - PyObject *yf = _PyGen_yf((PyGenObject*)iter); - if (yf != NULL) { - /* `iter` is a coroutine object that is being - awaited, `yf` is a pointer to the current awaitable - being awaited on. */ - Py_DECREF(yf); - Py_CLEAR(iter); - _PyErr_SetString(tstate, PyExc_RuntimeError, - "coroutine is being awaited already"); - /* The code below jumps to `error` if `iter` is NULL. */ - } - } - - SET_TOP(iter); /* Even if it's NULL */ - - if (iter == NULL) { - goto error; - } - - PREDICT(LOAD_CONST); - DISPATCH(); - } - - TARGET(YIELD_FROM) { - PyObject *v = POP(); - PyObject *receiver = TOP(); - PySendResult gen_status; - if (tstate->c_tracefunc == NULL) { - gen_status = PyIter_Send(receiver, v, &retval); - } else { - _Py_IDENTIFIER(send); - if (Py_IsNone(v) && PyIter_Check(receiver)) { - retval = Py_TYPE(receiver)->tp_iternext(receiver); - } - else { - retval = _PyObject_CallMethodIdOneArg(receiver, &PyId_send, v); - } - if (retval == NULL) { - if (tstate->c_tracefunc != NULL - && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, frame); - if (_PyGen_FetchStopIterationValue(&retval) == 0) { - gen_status = PYGEN_RETURN; - } - else { - gen_status = PYGEN_ERROR; - } - } - else { - gen_status = PYGEN_NEXT; - } - } - Py_DECREF(v); - if (gen_status == PYGEN_ERROR) { - assert (retval == NULL); - goto error; - } - if (gen_status == PYGEN_RETURN) { - assert (retval != NULL); - - Py_DECREF(receiver); - SET_TOP(retval); - retval = NULL; - DISPATCH(); - } - assert (gen_status == PYGEN_NEXT); - /* receiver remains on stack, retval is value to be yielded */ - /* and repeat... */ - assert(frame->f_lasti > 0); - frame->f_lasti -= 1; - frame->f_state = FRAME_SUSPENDED; - _PyFrame_SetStackPointer(frame, stack_pointer); - goto exiting; - } - - TARGET(YIELD_VALUE) { - retval = POP(); - - if (co->co_flags & CO_ASYNC_GENERATOR) { - PyObject *w = _PyAsyncGenValueWrapperNew(retval); - Py_DECREF(retval); - if (w == NULL) { - retval = NULL; - goto error; - } - retval = w; - } - frame->f_state = FRAME_SUSPENDED; - _PyFrame_SetStackPointer(frame, stack_pointer); - goto exiting; - } - - TARGET(GEN_START) { - PyObject *none = POP(); - Py_DECREF(none); - if (!Py_IsNone(none)) { - if (oparg > 2) { - _PyErr_SetString(tstate, PyExc_SystemError, - "Illegal kind for GEN_START"); - } - else { - static const char *gen_kind[3] = { - "generator", - "coroutine", - "async generator" - }; - _PyErr_Format(tstate, PyExc_TypeError, - "can't send non-None value to a " - "just-started %s", - gen_kind[oparg]); - } - goto error; - } - DISPATCH(); - } - - TARGET(POP_EXCEPT) { - PyObject *type, *value, *traceback; - _PyErr_StackItem *exc_info; - exc_info = tstate->exc_info; - type = exc_info->exc_type; - value = exc_info->exc_value; - traceback = exc_info->exc_traceback; - exc_info->exc_type = POP(); - exc_info->exc_value = POP(); - exc_info->exc_traceback = POP(); - ASSERT_EXC_TYPE_IS_REDUNDANT(exc_info->exc_type, exc_info->exc_value); - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(traceback); - DISPATCH(); - } - - TARGET(POP_EXCEPT_AND_RERAISE) { - PyObject *lasti = PEEK(4); - if (PyLong_Check(lasti)) { - frame->f_lasti = PyLong_AsLong(lasti); - assert(!_PyErr_Occurred(tstate)); - } - else { - _PyErr_SetString(tstate, PyExc_SystemError, "lasti is not an int"); - goto error; - } - PyObject *type, *value, *traceback; - _PyErr_StackItem *exc_info; - type = POP(); - value = POP(); - traceback = POP(); - ASSERT_EXC_TYPE_IS_REDUNDANT(type, value); - Py_DECREF(POP()); /* lasti */ - _PyErr_Restore(tstate, type, value, traceback); - exc_info = tstate->exc_info; - type = exc_info->exc_type; - value = exc_info->exc_value; - traceback = exc_info->exc_traceback; - exc_info->exc_type = POP(); - exc_info->exc_value = POP(); - exc_info->exc_traceback = POP(); - ASSERT_EXC_TYPE_IS_REDUNDANT(exc_info->exc_type, exc_info->exc_value); - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(traceback); - goto exception_unwind; - } - - TARGET(RERAISE) { - if (oparg) { - PyObject *lasti = PEEK(oparg+3); - if (PyLong_Check(lasti)) { - frame->f_lasti = PyLong_AsLong(lasti); - assert(!_PyErr_Occurred(tstate)); - } - else { - assert(PyLong_Check(lasti)); - _PyErr_SetString(tstate, PyExc_SystemError, "lasti is not an int"); - goto error; - } - } - PyObject *exc = POP(); - PyObject *val = POP(); - PyObject *tb = POP(); - ASSERT_EXC_TYPE_IS_REDUNDANT(exc, val); - assert(PyExceptionClass_Check(exc)); - _PyErr_Restore(tstate, exc, val, tb); - goto exception_unwind; - } - - TARGET(END_ASYNC_FOR) { - PyObject *exc = POP(); - PyObject *val = POP(); - PyObject *tb = POP(); - ASSERT_EXC_TYPE_IS_REDUNDANT(exc, val); - assert(PyExceptionClass_Check(exc)); - if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) { - Py_DECREF(exc); - Py_DECREF(val); - Py_DECREF(tb); - Py_DECREF(POP()); - DISPATCH(); - } - else { - _PyErr_Restore(tstate, exc, val, tb); - goto exception_unwind; - } - } - - TARGET(LOAD_ASSERTION_ERROR) { - PyObject *value = PyExc_AssertionError; - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - TARGET(LOAD_BUILD_CLASS) { - _Py_IDENTIFIER(__build_class__); - - PyObject *bc; - if (PyDict_CheckExact(BUILTINS())) { - bc = _PyDict_GetItemIdWithError(BUILTINS(), &PyId___build_class__); - if (bc == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_SetString(tstate, PyExc_NameError, - "__build_class__ not found"); - } - goto error; - } - Py_INCREF(bc); - } - else { - PyObject *build_class_str = _PyUnicode_FromId(&PyId___build_class__); - if (build_class_str == NULL) - goto error; - bc = PyObject_GetItem(BUILTINS(), build_class_str); - if (bc == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) - _PyErr_SetString(tstate, PyExc_NameError, - "__build_class__ not found"); - goto error; - } - } - PUSH(bc); - DISPATCH(); - } - - TARGET(STORE_NAME) { - PyObject *name = GETITEM(names, oparg); - PyObject *v = POP(); - PyObject *ns = LOCALS(); - int err; - if (ns == NULL) { - _PyErr_Format(tstate, PyExc_SystemError, - "no locals found when storing %R", name); - Py_DECREF(v); - goto error; - } - if (PyDict_CheckExact(ns)) - err = PyDict_SetItem(ns, name, v); - else - err = PyObject_SetItem(ns, name, v); - Py_DECREF(v); - if (err != 0) - goto error; - DISPATCH(); - } - - TARGET(DELETE_NAME) { - PyObject *name = GETITEM(names, oparg); - PyObject *ns = LOCALS(); - int err; - if (ns == NULL) { - _PyErr_Format(tstate, PyExc_SystemError, - "no locals when deleting %R", name); - goto error; - } - err = PyObject_DelItem(ns, name); - if (err != 0) { - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, - name); - goto error; - } - DISPATCH(); - } - - TARGET(UNPACK_SEQUENCE) { - PREDICTED(UNPACK_SEQUENCE); - PyObject *seq = POP(), *item, **items; - if (PyTuple_CheckExact(seq) && - PyTuple_GET_SIZE(seq) == oparg) { - items = ((PyTupleObject *)seq)->ob_item; - while (oparg--) { - item = items[oparg]; - Py_INCREF(item); - PUSH(item); - } - } else if (PyList_CheckExact(seq) && - PyList_GET_SIZE(seq) == oparg) { - items = ((PyListObject *)seq)->ob_item; - while (oparg--) { - item = items[oparg]; - Py_INCREF(item); - PUSH(item); - } - } else if (unpack_iterable(tstate, seq, oparg, -1, - stack_pointer + oparg)) { - STACK_GROW(oparg); - } else { - /* unpack_iterable() raised an exception */ - Py_DECREF(seq); - goto error; - } - Py_DECREF(seq); - DISPATCH(); - } - - TARGET(UNPACK_EX) { - int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); - PyObject *seq = POP(); - - if (unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, - stack_pointer + totalargs)) { - stack_pointer += totalargs; - } else { - Py_DECREF(seq); - goto error; - } - Py_DECREF(seq); - DISPATCH(); - } - - TARGET(STORE_ATTR) { - PREDICTED(STORE_ATTR); - STAT_INC(STORE_ATTR, unquickened); - PyObject *name = GETITEM(names, oparg); - PyObject *owner = TOP(); - PyObject *v = SECOND(); - int err; - STACK_SHRINK(2); - err = PyObject_SetAttr(owner, name, v); - Py_DECREF(v); - Py_DECREF(owner); - if (err != 0) - goto error; - DISPATCH(); - } - - TARGET(DELETE_ATTR) { - PyObject *name = GETITEM(names, oparg); - PyObject *owner = POP(); - int err; - err = PyObject_SetAttr(owner, name, (PyObject *)NULL); - Py_DECREF(owner); - if (err != 0) - goto error; - DISPATCH(); - } - - TARGET(STORE_GLOBAL) { - PyObject *name = GETITEM(names, oparg); - PyObject *v = POP(); - int err; - err = PyDict_SetItem(GLOBALS(), name, v); - Py_DECREF(v); - if (err != 0) - goto error; - DISPATCH(); - } - - TARGET(DELETE_GLOBAL) { - PyObject *name = GETITEM(names, oparg); - int err; - err = PyDict_DelItem(GLOBALS(), name); - if (err != 0) { - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; - } - DISPATCH(); - } - - TARGET(LOAD_NAME) { - PyObject *name = GETITEM(names, oparg); - PyObject *locals = LOCALS(); - PyObject *v; - if (locals == NULL) { - _PyErr_Format(tstate, PyExc_SystemError, - "no locals when loading %R", name); - goto error; - } - if (PyDict_CheckExact(locals)) { - v = PyDict_GetItemWithError(locals, name); - if (v != NULL) { - Py_INCREF(v); - } - else if (_PyErr_Occurred(tstate)) { - goto error; - } - } - else { - v = PyObject_GetItem(locals, name); - if (v == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) - goto error; - _PyErr_Clear(tstate); - } - } - if (v == NULL) { - v = PyDict_GetItemWithError(GLOBALS(), name); - if (v != NULL) { - Py_INCREF(v); - } - else if (_PyErr_Occurred(tstate)) { - goto error; - } - else { - if (PyDict_CheckExact(BUILTINS())) { - v = PyDict_GetItemWithError(BUILTINS(), name); - if (v == NULL) { - if (!_PyErr_Occurred(tstate)) { - format_exc_check_arg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; - } - Py_INCREF(v); - } - else { - v = PyObject_GetItem(BUILTINS(), name); - if (v == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - format_exc_check_arg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; - } - } - } - } - PUSH(v); - DISPATCH(); - } - - TARGET(LOAD_GLOBAL) { - PREDICTED(LOAD_GLOBAL); - STAT_INC(LOAD_GLOBAL, unquickened); - PyObject *name = GETITEM(names, oparg); - PyObject *v; - if (PyDict_CheckExact(GLOBALS()) - && PyDict_CheckExact(BUILTINS())) - { - v = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(), - (PyDictObject *)BUILTINS(), - name); - if (v == NULL) { - if (!_PyErr_Occurred(tstate)) { - /* _PyDict_LoadGlobal() returns NULL without raising - * an exception if the key doesn't exist */ - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; - } - Py_INCREF(v); - } - else { - /* Slow-path if globals or builtins is not a dict */ - - /* namespace 1: globals */ - name = GETITEM(names, oparg); - v = PyObject_GetItem(GLOBALS(), name); - if (v == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - goto error; - } - _PyErr_Clear(tstate); - - /* namespace 2: builtins */ - v = PyObject_GetItem(BUILTINS(), name); - if (v == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - format_exc_check_arg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; - } - } - } - PUSH(v); - DISPATCH(); - } - - TARGET(LOAD_GLOBAL_ADAPTIVE) { - assert(cframe.use_tracing == 0); - SpecializedCacheEntry *cache = GET_CACHE(); - if (cache->adaptive.counter == 0) { - PyObject *name = GETITEM(names, cache->adaptive.original_oparg); - next_instr--; - if (_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name, cache) < 0) { - goto error; - } - DISPATCH(); - } - else { - STAT_INC(LOAD_GLOBAL, deferred); - cache->adaptive.counter--; - oparg = cache->adaptive.original_oparg; - STAT_DEC(LOAD_GLOBAL, unquickened); - JUMP_TO_INSTRUCTION(LOAD_GLOBAL); - } - } - - TARGET(LOAD_GLOBAL_MODULE) { - assert(cframe.use_tracing == 0); - DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); - PyDictObject *dict = (PyDictObject *)GLOBALS(); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - _PyLoadGlobalCache *cache1 = &caches[-1].load_global; - DEOPT_IF(dict->ma_keys->dk_version != cache1->module_keys_version, LOAD_GLOBAL); - PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + cache0->index; - PyObject *res = ep->me_value; - DEOPT_IF(res == NULL, LOAD_GLOBAL); - STAT_INC(LOAD_GLOBAL, hit); - Py_INCREF(res); - PUSH(res); - DISPATCH(); - } - - TARGET(LOAD_GLOBAL_BUILTIN) { - assert(cframe.use_tracing == 0); - DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); - DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL); - PyDictObject *mdict = (PyDictObject *)GLOBALS(); - PyDictObject *bdict = (PyDictObject *)BUILTINS(); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - _PyLoadGlobalCache *cache1 = &caches[-1].load_global; - DEOPT_IF(mdict->ma_keys->dk_version != cache1->module_keys_version, LOAD_GLOBAL); - DEOPT_IF(bdict->ma_keys->dk_version != cache1->builtin_keys_version, LOAD_GLOBAL); - PyDictKeyEntry *ep = DK_ENTRIES(bdict->ma_keys) + cache0->index; - PyObject *res = ep->me_value; - DEOPT_IF(res == NULL, LOAD_GLOBAL); - STAT_INC(LOAD_GLOBAL, hit); - Py_INCREF(res); - PUSH(res); - DISPATCH(); - } - - TARGET(DELETE_FAST) { - PyObject *v = GETLOCAL(oparg); - if (v != NULL) { - SETLOCAL(oparg, NULL); - DISPATCH(); - } - format_exc_check_arg( - tstate, PyExc_UnboundLocalError, - UNBOUNDLOCAL_ERROR_MSG, - PyTuple_GetItem(co->co_localsplusnames, oparg) - ); - goto error; - } - - TARGET(MAKE_CELL) { - // "initial" is probably NULL but not if it's an arg (or set - // via PyFrame_LocalsToFast() before MAKE_CELL has run). - PyObject *initial = GETLOCAL(oparg); - PyObject *cell = PyCell_New(initial); - if (cell == NULL) { - goto error; - } - SETLOCAL(oparg, cell); - DISPATCH(); - } - - TARGET(DELETE_DEREF) { - PyObject *cell = GETLOCAL(oparg); - PyObject *oldobj = PyCell_GET(cell); - if (oldobj != NULL) { - PyCell_SET(cell, NULL); - Py_DECREF(oldobj); - DISPATCH(); - } - format_exc_unbound(tstate, co, oparg); - goto error; - } - - TARGET(LOAD_CLASSDEREF) { - PyObject *name, *value, *locals = LOCALS(); - assert(locals); - assert(oparg >= 0 && oparg < co->co_nlocalsplus); - name = PyTuple_GET_ITEM(co->co_localsplusnames, oparg); - if (PyDict_CheckExact(locals)) { - value = PyDict_GetItemWithError(locals, name); - if (value != NULL) { - Py_INCREF(value); - } - else if (_PyErr_Occurred(tstate)) { - goto error; - } - } - else { - value = PyObject_GetItem(locals, name); - if (value == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - goto error; - } - _PyErr_Clear(tstate); - } - } - if (!value) { - PyObject *cell = GETLOCAL(oparg); - value = PyCell_GET(cell); - if (value == NULL) { - format_exc_unbound(tstate, co, oparg); - goto error; - } - Py_INCREF(value); - } - PUSH(value); - DISPATCH(); - } - - TARGET(LOAD_DEREF) { - PyObject *cell = GETLOCAL(oparg); - PyObject *value = PyCell_GET(cell); - if (value == NULL) { - format_exc_unbound(tstate, co, oparg); - goto error; - } - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - TARGET(STORE_DEREF) { - PyObject *v = POP(); - PyObject *cell = GETLOCAL(oparg); - PyObject *oldobj = PyCell_GET(cell); - PyCell_SET(cell, v); - Py_XDECREF(oldobj); - DISPATCH(); - } - - TARGET(BUILD_STRING) { - PyObject *str; - PyObject *empty = PyUnicode_New(0, 0); - if (empty == NULL) { - goto error; - } - str = _PyUnicode_JoinArray(empty, stack_pointer - oparg, oparg); - Py_DECREF(empty); - if (str == NULL) - goto error; - while (--oparg >= 0) { - PyObject *item = POP(); - Py_DECREF(item); - } - PUSH(str); - DISPATCH(); - } - - TARGET(BUILD_TUPLE) { - PyObject *tup = PyTuple_New(oparg); - if (tup == NULL) - goto error; - while (--oparg >= 0) { - PyObject *item = POP(); - PyTuple_SET_ITEM(tup, oparg, item); - } - PUSH(tup); - DISPATCH(); - } - - TARGET(BUILD_LIST) { - PyObject *list = PyList_New(oparg); - if (list == NULL) - goto error; - while (--oparg >= 0) { - PyObject *item = POP(); - PyList_SET_ITEM(list, oparg, item); - } - PUSH(list); - DISPATCH(); - } - - TARGET(LIST_TO_TUPLE) { - PyObject *list = POP(); - PyObject *tuple = PyList_AsTuple(list); - Py_DECREF(list); - if (tuple == NULL) { - goto error; - } - PUSH(tuple); - DISPATCH(); - } - - TARGET(LIST_EXTEND) { - PyObject *iterable = POP(); - PyObject *list = PEEK(oparg); - PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); - if (none_val == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && - (Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable))) - { - _PyErr_Clear(tstate); - _PyErr_Format(tstate, PyExc_TypeError, - "Value after * must be an iterable, not %.200s", - Py_TYPE(iterable)->tp_name); - } - Py_DECREF(iterable); - goto error; - } - Py_DECREF(none_val); - Py_DECREF(iterable); - DISPATCH(); - } - - TARGET(SET_UPDATE) { - PyObject *iterable = POP(); - PyObject *set = PEEK(oparg); - int err = _PySet_Update(set, iterable); - Py_DECREF(iterable); - if (err < 0) { - goto error; - } - DISPATCH(); - } - - TARGET(BUILD_SET) { - PyObject *set = PySet_New(NULL); - int err = 0; - int i; - if (set == NULL) - goto error; - for (i = oparg; i > 0; i--) { - PyObject *item = PEEK(i); - if (err == 0) - err = PySet_Add(set, item); - Py_DECREF(item); - } - STACK_SHRINK(oparg); - if (err != 0) { - Py_DECREF(set); - goto error; - } - PUSH(set); - DISPATCH(); - } - - TARGET(BUILD_MAP) { - Py_ssize_t i; - PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg); - if (map == NULL) - goto error; - for (i = oparg; i > 0; i--) { - int err; - PyObject *key = PEEK(2*i); - PyObject *value = PEEK(2*i - 1); - err = PyDict_SetItem(map, key, value); - if (err != 0) { - Py_DECREF(map); - goto error; - } - } - - while (oparg--) { - Py_DECREF(POP()); - Py_DECREF(POP()); - } - PUSH(map); - DISPATCH(); - } - - TARGET(SETUP_ANNOTATIONS) { - _Py_IDENTIFIER(__annotations__); - int err; - PyObject *ann_dict; - if (LOCALS() == NULL) { - _PyErr_Format(tstate, PyExc_SystemError, - "no locals found when setting up annotations"); - goto error; - } - /* check if __annotations__ in locals()... */ - if (PyDict_CheckExact(LOCALS())) { - ann_dict = _PyDict_GetItemIdWithError(LOCALS(), - &PyId___annotations__); - if (ann_dict == NULL) { - if (_PyErr_Occurred(tstate)) { - goto error; - } - /* ...if not, create a new one */ - ann_dict = PyDict_New(); - if (ann_dict == NULL) { - goto error; - } - err = _PyDict_SetItemId(LOCALS(), - &PyId___annotations__, ann_dict); - Py_DECREF(ann_dict); - if (err != 0) { - goto error; - } - } - } - else { - /* do the same if locals() is not a dict */ - PyObject *ann_str = _PyUnicode_FromId(&PyId___annotations__); - if (ann_str == NULL) { - goto error; - } - ann_dict = PyObject_GetItem(LOCALS(), ann_str); - if (ann_dict == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - goto error; - } - _PyErr_Clear(tstate); - ann_dict = PyDict_New(); - if (ann_dict == NULL) { - goto error; - } - err = PyObject_SetItem(LOCALS(), ann_str, ann_dict); - Py_DECREF(ann_dict); - if (err != 0) { - goto error; - } - } - else { - Py_DECREF(ann_dict); - } - } - DISPATCH(); - } - - TARGET(BUILD_CONST_KEY_MAP) { - Py_ssize_t i; - PyObject *map; - PyObject *keys = TOP(); - if (!PyTuple_CheckExact(keys) || - PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { - _PyErr_SetString(tstate, PyExc_SystemError, - "bad BUILD_CONST_KEY_MAP keys argument"); - goto error; - } - map = _PyDict_NewPresized((Py_ssize_t)oparg); - if (map == NULL) { - goto error; - } - for (i = oparg; i > 0; i--) { - int err; - PyObject *key = PyTuple_GET_ITEM(keys, oparg - i); - PyObject *value = PEEK(i + 1); - err = PyDict_SetItem(map, key, value); - if (err != 0) { - Py_DECREF(map); - goto error; - } - } - - Py_DECREF(POP()); - while (oparg--) { - Py_DECREF(POP()); - } - PUSH(map); - DISPATCH(); - } - - TARGET(DICT_UPDATE) { - PyObject *update = POP(); - PyObject *dict = PEEK(oparg); - if (PyDict_Update(dict, update) < 0) { - if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object is not a mapping", - Py_TYPE(update)->tp_name); - } - Py_DECREF(update); - goto error; - } - Py_DECREF(update); - DISPATCH(); - } - - TARGET(DICT_MERGE) { - PyObject *update = POP(); - PyObject *dict = PEEK(oparg); - - if (_PyDict_MergeEx(dict, update, 2) < 0) { - format_kwargs_error(tstate, PEEK(2 + oparg), update); - Py_DECREF(update); - goto error; - } - Py_DECREF(update); - PREDICT(CALL_FUNCTION_EX); - DISPATCH(); - } - - TARGET(MAP_ADD) { - PyObject *value = TOP(); - PyObject *key = SECOND(); - PyObject *map; - STACK_SHRINK(2); - map = PEEK(oparg); /* dict */ - assert(PyDict_CheckExact(map)); - /* map[key] = value */ - if (_PyDict_SetItem_Take2((PyDictObject *)map, key, value) != 0) { - goto error; - } - PREDICT(JUMP_ABSOLUTE); - DISPATCH(); - } - - TARGET(LOAD_ATTR) { - PREDICTED(LOAD_ATTR); - STAT_INC(LOAD_ATTR, unquickened); - PyObject *name = GETITEM(names, oparg); - PyObject *owner = TOP(); - PyObject *res = PyObject_GetAttr(owner, name); - if (res == NULL) { - goto error; - } - Py_DECREF(owner); - SET_TOP(res); - DISPATCH(); - } - - TARGET(LOAD_ATTR_ADAPTIVE) { - assert(cframe.use_tracing == 0); - SpecializedCacheEntry *cache = GET_CACHE(); - if (cache->adaptive.counter == 0) { - PyObject *owner = TOP(); - PyObject *name = GETITEM(names, cache->adaptive.original_oparg); - next_instr--; - if (_Py_Specialize_LoadAttr(owner, next_instr, name, cache) < 0) { - goto error; - } - DISPATCH(); - } - else { - STAT_INC(LOAD_ATTR, deferred); - cache->adaptive.counter--; - oparg = cache->adaptive.original_oparg; - STAT_DEC(LOAD_ATTR, unquickened); - JUMP_TO_INSTRUCTION(LOAD_ATTR); - } - } - - TARGET(LOAD_ATTR_INSTANCE_VALUE) { - assert(cframe.use_tracing == 0); - PyObject *owner = TOP(); - PyObject *res; - PyTypeObject *tp = Py_TYPE(owner); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - _PyAttrCache *cache1 = &caches[-1].attr; - assert(cache1->tp_version != 0); - DEOPT_IF(tp->tp_version_tag != cache1->tp_version, LOAD_ATTR); - assert(tp->tp_dictoffset > 0); - assert(tp->tp_inline_values_offset > 0); - PyDictValues *values = *(PyDictValues **)(((char *)owner) + tp->tp_inline_values_offset); - DEOPT_IF(values == NULL, LOAD_ATTR); - res = values->values[cache0->index]; - DEOPT_IF(res == NULL, LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - Py_INCREF(res); - SET_TOP(res); - Py_DECREF(owner); - DISPATCH(); - } - - TARGET(LOAD_ATTR_MODULE) { - assert(cframe.use_tracing == 0); - // shared with LOAD_METHOD_MODULE - PyObject *owner = TOP(); - PyObject *res; - LOAD_MODULE_ATTR_OR_METHOD(ATTR); - SET_TOP(res); - Py_DECREF(owner); - DISPATCH(); - } - - TARGET(LOAD_ATTR_WITH_HINT) { - assert(cframe.use_tracing == 0); - PyObject *owner = TOP(); - PyObject *res; - PyTypeObject *tp = Py_TYPE(owner); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - _PyAttrCache *cache1 = &caches[-1].attr; - assert(cache1->tp_version != 0); - DEOPT_IF(tp->tp_version_tag != cache1->tp_version, LOAD_ATTR); - assert(tp->tp_dictoffset > 0); - PyDictObject *dict = *(PyDictObject **)(((char *)owner) + tp->tp_dictoffset); - DEOPT_IF(dict == NULL, LOAD_ATTR); - assert(PyDict_CheckExact((PyObject *)dict)); - PyObject *name = GETITEM(names, cache0->original_oparg); - uint32_t hint = cache1->dk_version_or_hint; - DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR); - PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, LOAD_ATTR); - res = ep->me_value; - DEOPT_IF(res == NULL, LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - Py_INCREF(res); - SET_TOP(res); - Py_DECREF(owner); - DISPATCH(); - } - - TARGET(LOAD_ATTR_SLOT) { - assert(cframe.use_tracing == 0); - PyObject *owner = TOP(); - PyObject *res; - PyTypeObject *tp = Py_TYPE(owner); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - _PyAttrCache *cache1 = &caches[-1].attr; - assert(cache1->tp_version != 0); - DEOPT_IF(tp->tp_version_tag != cache1->tp_version, LOAD_ATTR); - char *addr = (char *)owner + cache0->index; - res = *(PyObject **)addr; - DEOPT_IF(res == NULL, LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - Py_INCREF(res); - SET_TOP(res); - Py_DECREF(owner); - DISPATCH(); - } - - TARGET(STORE_ATTR_ADAPTIVE) { - assert(cframe.use_tracing == 0); - SpecializedCacheEntry *cache = GET_CACHE(); - if (cache->adaptive.counter == 0) { - PyObject *owner = TOP(); - PyObject *name = GETITEM(names, cache->adaptive.original_oparg); - next_instr--; - if (_Py_Specialize_StoreAttr(owner, next_instr, name, cache) < 0) { - goto error; - } - DISPATCH(); - } - else { - STAT_INC(STORE_ATTR, deferred); - cache->adaptive.counter--; - oparg = cache->adaptive.original_oparg; - STAT_DEC(STORE_ATTR, unquickened); - JUMP_TO_INSTRUCTION(STORE_ATTR); - } - } - - TARGET(STORE_ATTR_INSTANCE_VALUE) { - assert(cframe.use_tracing == 0); - PyObject *owner = TOP(); - PyTypeObject *tp = Py_TYPE(owner); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - _PyAttrCache *cache1 = &caches[-1].attr; - assert(cache1->tp_version != 0); - DEOPT_IF(tp->tp_version_tag != cache1->tp_version, STORE_ATTR); - assert(tp->tp_dictoffset > 0); - assert(tp->tp_inline_values_offset > 0); - PyDictValues *values = *(PyDictValues **)(((char *)owner) + tp->tp_inline_values_offset); - DEOPT_IF(values == NULL, STORE_ATTR); - STAT_INC(STORE_ATTR, hit); - int index = cache0->index; - STACK_SHRINK(1); - PyObject *value = POP(); - PyObject *old_value = values->values[index]; - values->values[index] = value; - if (old_value == NULL) { - assert(index < 16); - values->mv_order = (values->mv_order << 4) | index; - } - else { - Py_DECREF(old_value); - } - Py_DECREF(owner); - DISPATCH(); - } - - TARGET(STORE_ATTR_WITH_HINT) { - assert(cframe.use_tracing == 0); - PyObject *owner = TOP(); - PyTypeObject *tp = Py_TYPE(owner); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - _PyAttrCache *cache1 = &caches[-1].attr; - assert(cache1->tp_version != 0); - DEOPT_IF(tp->tp_version_tag != cache1->tp_version, STORE_ATTR); - assert(tp->tp_dictoffset > 0); - PyDictObject *dict = *(PyDictObject **)(((char *)owner) + tp->tp_dictoffset); - DEOPT_IF(dict == NULL, STORE_ATTR); - assert(PyDict_CheckExact((PyObject *)dict)); - PyObject *name = GETITEM(names, cache0->original_oparg); - uint32_t hint = cache1->dk_version_or_hint; - DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, STORE_ATTR); - PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, STORE_ATTR); - PyObject *old_value = ep->me_value; - DEOPT_IF(old_value == NULL, STORE_ATTR); - STAT_INC(STORE_ATTR, hit); - STACK_SHRINK(1); - PyObject *value = POP(); - ep->me_value = value; - Py_DECREF(old_value); - /* Ensure dict is GC tracked if it needs to be */ - if (!_PyObject_GC_IS_TRACKED(dict) && _PyObject_GC_MAY_BE_TRACKED(value)) { - _PyObject_GC_TRACK(dict); - } - /* PEP 509 */ - dict->ma_version_tag = DICT_NEXT_VERSION(); - Py_DECREF(owner); - DISPATCH(); - } - - TARGET(STORE_ATTR_SLOT) { - assert(cframe.use_tracing == 0); - PyObject *owner = TOP(); - PyTypeObject *tp = Py_TYPE(owner); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - _PyAttrCache *cache1 = &caches[-1].attr; - assert(cache1->tp_version != 0); - DEOPT_IF(tp->tp_version_tag != cache1->tp_version, STORE_ATTR); - char *addr = (char *)owner + cache0->index; - STAT_INC(STORE_ATTR, hit); - STACK_SHRINK(1); - PyObject *value = POP(); - PyObject *old_value = *(PyObject **)addr; - *(PyObject **)addr = value; - Py_XDECREF(old_value); - Py_DECREF(owner); - DISPATCH(); - } - - TARGET(COMPARE_OP) { - assert(oparg <= Py_GE); - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyObject_RichCompare(left, right, oparg); - SET_TOP(res); - Py_DECREF(left); - Py_DECREF(right); - if (res == NULL) - goto error; - PREDICT(POP_JUMP_IF_FALSE); - PREDICT(POP_JUMP_IF_TRUE); - DISPATCH(); - } - - TARGET(IS_OP) { - PyObject *right = POP(); - PyObject *left = TOP(); - int res = Py_Is(left, right) ^ oparg; - PyObject *b = res ? Py_True : Py_False; - Py_INCREF(b); - SET_TOP(b); - Py_DECREF(left); - Py_DECREF(right); - PREDICT(POP_JUMP_IF_FALSE); - PREDICT(POP_JUMP_IF_TRUE); - DISPATCH(); - } - - TARGET(CONTAINS_OP) { - PyObject *right = POP(); - PyObject *left = POP(); - int res = PySequence_Contains(right, left); - Py_DECREF(left); - Py_DECREF(right); - if (res < 0) { - goto error; - } - PyObject *b = (res^oparg) ? Py_True : Py_False; - Py_INCREF(b); - PUSH(b); - PREDICT(POP_JUMP_IF_FALSE); - PREDICT(POP_JUMP_IF_TRUE); - DISPATCH(); - } - - TARGET(JUMP_IF_NOT_EXC_MATCH) { - const char *cannot_catch_msg = "catching classes that do not " - "inherit from BaseException is not " - "allowed"; - PyObject *right = POP(); - PyObject *left = TOP(); - if (PyTuple_Check(right)) { - Py_ssize_t i, length; - length = PyTuple_GET_SIZE(right); - for (i = 0; i < length; i++) { - PyObject *exc = PyTuple_GET_ITEM(right, i); - if (!PyExceptionClass_Check(exc)) { - _PyErr_SetString(tstate, PyExc_TypeError, - cannot_catch_msg); - Py_DECREF(right); - goto error; - } - } - } - else { - if (!PyExceptionClass_Check(right)) { - _PyErr_SetString(tstate, PyExc_TypeError, - cannot_catch_msg); - Py_DECREF(right); - goto error; - } - } - int res = PyErr_GivenExceptionMatches(left, right); - Py_DECREF(right); - if (res > 0) { - /* Exception matches -- Do nothing */; - } - else if (res == 0) { - JUMPTO(oparg); - } - else { - goto error; - } - DISPATCH(); - } - - TARGET(IMPORT_NAME) { - PyObject *name = GETITEM(names, oparg); - PyObject *fromlist = POP(); - PyObject *level = TOP(); - PyObject *res; - res = import_name(tstate, frame, name, fromlist, level); - Py_DECREF(level); - Py_DECREF(fromlist); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(IMPORT_STAR) { - PyObject *from = POP(), *locals; - int err; - if (_PyFrame_FastToLocalsWithError(frame) < 0) { - Py_DECREF(from); - goto error; - } - - locals = LOCALS(); - if (locals == NULL) { - _PyErr_SetString(tstate, PyExc_SystemError, - "no locals found during 'import *'"); - Py_DECREF(from); - goto error; - } - err = import_all_from(tstate, locals, from); - _PyFrame_LocalsToFast(frame, 0); - Py_DECREF(from); - if (err != 0) - goto error; - DISPATCH(); - } - - TARGET(IMPORT_FROM) { - PyObject *name = GETITEM(names, oparg); - PyObject *from = TOP(); - PyObject *res; - res = import_from(tstate, from, name); - PUSH(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(JUMP_FORWARD) { - JUMPBY(oparg); - DISPATCH(); - } - - TARGET(POP_JUMP_IF_FALSE) { - PREDICTED(POP_JUMP_IF_FALSE); - PyObject *cond = POP(); - int err; - if (Py_IsTrue(cond)) { - Py_DECREF(cond); - DISPATCH(); - } - if (Py_IsFalse(cond)) { - Py_DECREF(cond); - JUMPTO(oparg); - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - err = PyObject_IsTrue(cond); - Py_DECREF(cond); - if (err > 0) - ; - else if (err == 0) { - JUMPTO(oparg); - CHECK_EVAL_BREAKER(); - } - else - goto error; - DISPATCH(); - } - - TARGET(POP_JUMP_IF_TRUE) { - PREDICTED(POP_JUMP_IF_TRUE); - PyObject *cond = POP(); - int err; - if (Py_IsFalse(cond)) { - Py_DECREF(cond); - DISPATCH(); - } - if (Py_IsTrue(cond)) { - Py_DECREF(cond); - JUMPTO(oparg); - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - err = PyObject_IsTrue(cond); - Py_DECREF(cond); - if (err > 0) { - JUMPTO(oparg); - CHECK_EVAL_BREAKER(); - } - else if (err == 0) - ; - else - goto error; - DISPATCH(); - } - - TARGET(JUMP_IF_FALSE_OR_POP) { - PyObject *cond = TOP(); - int err; - if (Py_IsTrue(cond)) { - STACK_SHRINK(1); - Py_DECREF(cond); - DISPATCH(); - } - if (Py_IsFalse(cond)) { - JUMPTO(oparg); - DISPATCH(); - } - err = PyObject_IsTrue(cond); - if (err > 0) { - STACK_SHRINK(1); - Py_DECREF(cond); - } - else if (err == 0) - JUMPTO(oparg); - else - goto error; - DISPATCH(); - } - - TARGET(JUMP_IF_TRUE_OR_POP) { - PyObject *cond = TOP(); - int err; - if (Py_IsFalse(cond)) { - STACK_SHRINK(1); - Py_DECREF(cond); - DISPATCH(); - } - if (Py_IsTrue(cond)) { - JUMPTO(oparg); - DISPATCH(); - } - err = PyObject_IsTrue(cond); - if (err > 0) { - JUMPTO(oparg); - } - else if (err == 0) { - STACK_SHRINK(1); - Py_DECREF(cond); - } - else - goto error; - DISPATCH(); - } - - TARGET(JUMP_ABSOLUTE) { - PREDICTED(JUMP_ABSOLUTE); - assert(oparg < INSTR_OFFSET()); - /* Increment the warmup counter and quicken if warm enough - * _Py_Quicken is idempotent so we don't worry about overflow */ - if (!PyCodeObject_IsWarmedUp(co)) { - PyCodeObject_IncrementWarmup(co); - if (PyCodeObject_IsWarmedUp(co)) { - if (_Py_Quicken(co)) { - goto error; - } - int nexti = INSTR_OFFSET(); - first_instr = co->co_firstinstr; - next_instr = first_instr + nexti; - } - } - JUMPTO(oparg); - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - - TARGET(JUMP_ABSOLUTE_QUICK) { - assert(oparg < INSTR_OFFSET()); - JUMPTO(oparg); - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - - TARGET(GET_LEN) { - // PUSH(len(TOS)) - Py_ssize_t len_i = PyObject_Length(TOP()); - if (len_i < 0) { - goto error; - } - PyObject *len_o = PyLong_FromSsize_t(len_i); - if (len_o == NULL) { - goto error; - } - PUSH(len_o); - DISPATCH(); - } - - TARGET(MATCH_CLASS) { - // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or - // None on failure. - PyObject *names = POP(); - PyObject *type = POP(); - PyObject *subject = TOP(); - assert(PyTuple_CheckExact(names)); - PyObject *attrs = match_class(tstate, subject, type, oparg, names); - Py_DECREF(names); - Py_DECREF(type); - if (attrs) { - // Success! - assert(PyTuple_CheckExact(attrs)); - SET_TOP(attrs); - } - else if (_PyErr_Occurred(tstate)) { - // Error! - goto error; - } - else { - // Failure! - Py_INCREF(Py_None); - SET_TOP(Py_None); - } - Py_DECREF(subject); - DISPATCH(); - } - - TARGET(MATCH_MAPPING) { - PyObject *subject = TOP(); - int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; - PyObject *res = match ? Py_True : Py_False; - Py_INCREF(res); - PUSH(res); - PREDICT(POP_JUMP_IF_FALSE); - DISPATCH(); - } - - TARGET(MATCH_SEQUENCE) { - PyObject *subject = TOP(); - int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; - PyObject *res = match ? Py_True : Py_False; - Py_INCREF(res); - PUSH(res); - PREDICT(POP_JUMP_IF_FALSE); - DISPATCH(); - } - - TARGET(MATCH_KEYS) { - // On successful match, PUSH(values). Otherwise, PUSH(None). - PyObject *keys = TOP(); - PyObject *subject = SECOND(); - PyObject *values_or_none = match_keys(tstate, subject, keys); - if (values_or_none == NULL) { - goto error; - } - PUSH(values_or_none); - DISPATCH(); - } - - TARGET(GET_ITER) { - /* before: [obj]; after [getiter(obj)] */ - PyObject *iterable = TOP(); - PyObject *iter = PyObject_GetIter(iterable); - Py_DECREF(iterable); - SET_TOP(iter); - if (iter == NULL) - goto error; - PREDICT(FOR_ITER); - PREDICT(CALL_FUNCTION); - DISPATCH(); - } - - TARGET(GET_YIELD_FROM_ITER) { - /* before: [obj]; after [getiter(obj)] */ - PyObject *iterable = TOP(); - PyObject *iter; - if (PyCoro_CheckExact(iterable)) { - /* `iterable` is a coroutine */ - if (!(co->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) { - /* and it is used in a 'yield from' expression of a - regular generator. */ - Py_DECREF(iterable); - SET_TOP(NULL); - _PyErr_SetString(tstate, PyExc_TypeError, - "cannot 'yield from' a coroutine object " - "in a non-coroutine generator"); - goto error; - } - } - else if (!PyGen_CheckExact(iterable)) { - /* `iterable` is not a generator. */ - iter = PyObject_GetIter(iterable); - Py_DECREF(iterable); - SET_TOP(iter); - if (iter == NULL) - goto error; - } - PREDICT(LOAD_CONST); - DISPATCH(); - } - - TARGET(FOR_ITER) { - PREDICTED(FOR_ITER); - /* before: [iter]; after: [iter, iter()] *or* [] */ - PyObject *iter = TOP(); - PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter); - if (next != NULL) { - PUSH(next); - PREDICT(STORE_FAST); - PREDICT(UNPACK_SEQUENCE); - DISPATCH(); - } - if (_PyErr_Occurred(tstate)) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { - goto error; - } - else if (tstate->c_tracefunc != NULL) { - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, frame); - } - _PyErr_Clear(tstate); - } - /* iterator ended normally */ - STACK_SHRINK(1); - Py_DECREF(iter); - JUMPBY(oparg); - DISPATCH(); - } - - TARGET(BEFORE_ASYNC_WITH) { - _Py_IDENTIFIER(__aenter__); - _Py_IDENTIFIER(__aexit__); - PyObject *mgr = TOP(); - PyObject *res; - PyObject *enter = _PyObject_LookupSpecial(mgr, &PyId___aenter__); - if (enter == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object does not support the " - "asynchronous context manager protocol", - Py_TYPE(mgr)->tp_name); - } - goto error; - } - PyObject *exit = _PyObject_LookupSpecial(mgr, &PyId___aexit__); - if (exit == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object does not support the " - "asynchronous context manager protocol " - "(missed __aexit__ method)", - Py_TYPE(mgr)->tp_name); - } - Py_DECREF(enter); - goto error; - } - SET_TOP(exit); - Py_DECREF(mgr); - res = _PyObject_CallNoArgs(enter); - Py_DECREF(enter); - if (res == NULL) - goto error; - PUSH(res); - PREDICT(GET_AWAITABLE); - DISPATCH(); - } - - TARGET(BEFORE_WITH) { - _Py_IDENTIFIER(__enter__); - _Py_IDENTIFIER(__exit__); - PyObject *mgr = TOP(); - PyObject *res; - PyObject *enter = _PyObject_LookupSpecial(mgr, &PyId___enter__); - if (enter == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object does not support the " - "context manager protocol", - Py_TYPE(mgr)->tp_name); - } - goto error; - } - PyObject *exit = _PyObject_LookupSpecial(mgr, &PyId___exit__); - if (exit == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object does not support the " - "context manager protocol " - "(missed __exit__ method)", - Py_TYPE(mgr)->tp_name); - } - Py_DECREF(enter); - goto error; - } - SET_TOP(exit); - Py_DECREF(mgr); - res = _PyObject_CallNoArgs(enter); - Py_DECREF(enter); - if (res == NULL) { - goto error; - } - PUSH(res); - DISPATCH(); - } - - TARGET(WITH_EXCEPT_START) { - /* At the top of the stack are 8 values: - - (TOP, SECOND, THIRD) = exc_info() - - (FOURTH, FIFTH, SIXTH) = previous exception - - SEVENTH: lasti of exception in exc_info() - - EIGHTH: the context.__exit__ bound method - We call EIGHTH(TOP, SECOND, THIRD). - Then we push again the TOP exception and the __exit__ - return value. - */ - PyObject *exit_func; - PyObject *exc, *val, *tb, *res; - - exc = TOP(); - val = SECOND(); - tb = THIRD(); - ASSERT_EXC_TYPE_IS_REDUNDANT(exc, val); - assert(!Py_IsNone(exc)); - assert(!PyLong_Check(exc)); - assert(PyLong_Check(PEEK(7))); - exit_func = PEEK(8); - PyObject *stack[4] = {NULL, exc, val, tb}; - res = PyObject_Vectorcall(exit_func, stack + 1, - 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); - if (res == NULL) - goto error; - - PUSH(res); - DISPATCH(); - } - - TARGET(PUSH_EXC_INFO) { - PyObject *type = TOP(); - PyObject *value = SECOND(); - PyObject *tb = THIRD(); - ASSERT_EXC_TYPE_IS_REDUNDANT(type, value); - _PyErr_StackItem *exc_info = tstate->exc_info; - SET_THIRD(exc_info->exc_traceback); - SET_SECOND(exc_info->exc_value); - if (exc_info->exc_type != NULL) { - SET_TOP(exc_info->exc_type); - } - else { - Py_INCREF(Py_None); - SET_TOP(Py_None); - } - Py_INCREF(tb); - PUSH(tb); - exc_info->exc_traceback = tb; - - Py_INCREF(value); - PUSH(value); - assert(PyExceptionInstance_Check(value)); - exc_info->exc_value = value; - - Py_INCREF(type); - PUSH(type); - assert(PyExceptionClass_Check(type)); - exc_info->exc_type = type; - - DISPATCH(); - } - - TARGET(LOAD_METHOD) { - PREDICTED(LOAD_METHOD); - STAT_INC(LOAD_METHOD, unquickened); - /* Designed to work in tandem with CALL_METHOD. */ - PyObject *name = GETITEM(names, oparg); - PyObject *obj = TOP(); - PyObject *meth = NULL; - - int meth_found = _PyObject_GetMethod(obj, name, &meth); - - if (meth == NULL) { - /* Most likely attribute wasn't found. */ - goto error; - } - - if (meth_found) { - /* We can bypass temporary bound method object. - meth is unbound method and obj is self. - - meth | self | arg1 | ... | argN - */ - SET_TOP(meth); - PUSH(obj); // self - } - else { - /* meth is not an unbound method (but a regular attr, or - something was returned by a descriptor protocol). Set - the second element of the stack to NULL, to signal - CALL_METHOD that it's not a method call. - - NULL | meth | arg1 | ... | argN - */ - SET_TOP(NULL); - Py_DECREF(obj); - PUSH(meth); - } - DISPATCH(); - } - - TARGET(LOAD_METHOD_ADAPTIVE) { - assert(cframe.use_tracing == 0); - SpecializedCacheEntry *cache = GET_CACHE(); - if (cache->adaptive.counter == 0) { - PyObject *owner = TOP(); - PyObject *name = GETITEM(names, cache->adaptive.original_oparg); - next_instr--; - if (_Py_Specialize_LoadMethod(owner, next_instr, name, cache) < 0) { - goto error; - } - DISPATCH(); - } - else { - STAT_INC(LOAD_METHOD, deferred); - cache->adaptive.counter--; - oparg = cache->adaptive.original_oparg; - STAT_DEC(LOAD_METHOD, unquickened); - JUMP_TO_INSTRUCTION(LOAD_METHOD); - } - } - - TARGET(LOAD_METHOD_CACHED) { - /* LOAD_METHOD, with cached method object */ - assert(cframe.use_tracing == 0); - PyObject *self = TOP(); - PyTypeObject *self_cls = Py_TYPE(self); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAttrCache *cache1 = &caches[-1].attr; - _PyObjectCache *cache2 = &caches[-2].obj; - - DEOPT_IF(self_cls->tp_version_tag != cache1->tp_version, LOAD_METHOD); - assert(self_cls->tp_dictoffset > 0); - assert(self_cls->tp_inline_values_offset > 0); - PyDictObject *dict = *(PyDictObject **)(((char *)self) + self_cls->tp_dictoffset); - DEOPT_IF(dict != NULL, LOAD_METHOD); - DEOPT_IF(((PyHeapTypeObject *)self_cls)->ht_cached_keys->dk_version != cache1->dk_version_or_hint, LOAD_METHOD); - STAT_INC(LOAD_METHOD, hit); - PyObject *res = cache2->obj; - assert(res != NULL); - assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); - Py_INCREF(res); - SET_TOP(res); - PUSH(self); - DISPATCH(); - } - - TARGET(LOAD_METHOD_NO_DICT) { - PyObject *self = TOP(); - PyTypeObject *self_cls = Py_TYPE(self); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAttrCache *cache1 = &caches[-1].attr; - _PyObjectCache *cache2 = &caches[-2].obj; - DEOPT_IF(self_cls->tp_version_tag != cache1->tp_version, LOAD_METHOD); - assert(self_cls->tp_dictoffset == 0); - STAT_INC(LOAD_METHOD, hit); - PyObject *res = cache2->obj; - assert(res != NULL); - assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); - Py_INCREF(res); - SET_TOP(res); - PUSH(self); - DISPATCH(); - } - - TARGET(LOAD_METHOD_MODULE) { - /* LOAD_METHOD, for module methods */ - assert(cframe.use_tracing == 0); - PyObject *owner = TOP(); - PyObject *res; - LOAD_MODULE_ATTR_OR_METHOD(METHOD); - SET_TOP(NULL); - Py_DECREF(owner); - PUSH(res); - DISPATCH(); - } - - TARGET(LOAD_METHOD_CLASS) { - /* LOAD_METHOD, for class methods */ - assert(cframe.use_tracing == 0); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAttrCache *cache1 = &caches[-1].attr; - _PyObjectCache *cache2 = &caches[-2].obj; - - PyObject *cls = TOP(); - DEOPT_IF(!PyType_Check(cls), LOAD_METHOD); - DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != cache1->tp_version, - LOAD_METHOD); - assert(cache1->tp_version != 0); - - STAT_INC(LOAD_METHOD, hit); - PyObject *res = cache2->obj; - assert(res != NULL); - Py_INCREF(res); - SET_TOP(NULL); - Py_DECREF(cls); - PUSH(res); - DISPATCH(); - } - - TARGET(CALL_METHOD) { - /* Designed to work in tamdem with LOAD_METHOD. */ - /* `meth` is NULL when LOAD_METHOD thinks that it's not - a method call. - - Stack layout: - - ... | NULL | callable | arg1 | ... | argN - ^- TOP() - ^- (-oparg) - ^- (-oparg-1) - ^- (-oparg-2) - - `callable` will be POPed by call_function. - NULL will will be POPed manually later. - If `meth` isn't NULL, it's a method call. Stack layout: - - ... | method | self | arg1 | ... | argN - ^- TOP() - ^- (-oparg) - ^- (-oparg-1) - ^- (-oparg-2) - - `self` and `method` will be POPed by call_function. - We'll be passing `oparg + 1` to call_function, to - make it accept the `self` as a first argument. - */ - int is_method = (PEEK(oparg + 2) != NULL); - oparg += is_method; - nargs = oparg; - kwnames = NULL; - postcall_shrink = 2-is_method; - goto call_function; - } - - TARGET(CALL_METHOD_KW) { - /* Designed to work in tandem with LOAD_METHOD. Same as CALL_METHOD - but pops TOS to get a tuple of keyword names. */ - kwnames = POP(); - int is_method = (PEEK(oparg + 2) != NULL); - oparg += is_method; - nargs = oparg - (int)PyTuple_GET_SIZE(kwnames); - postcall_shrink = 2-is_method; - goto call_function; - } - - TARGET(CALL_FUNCTION_KW) { - kwnames = POP(); - nargs = oparg - (int)PyTuple_GET_SIZE(kwnames); - postcall_shrink = 1; - goto call_function; - } - - TARGET(CALL_FUNCTION) { - PREDICTED(CALL_FUNCTION); - STAT_INC(CALL_FUNCTION, unquickened); - PyObject *function; - nargs = oparg; - kwnames = NULL; - postcall_shrink = 1; - call_function: - function = PEEK(oparg + 1); - if (Py_TYPE(function) == &PyMethod_Type) { - PyObject *meth = ((PyMethodObject *)function)->im_func; - PyObject *self = ((PyMethodObject *)function)->im_self; - Py_INCREF(meth); - Py_INCREF(self); - PEEK(oparg + 1) = self; - Py_DECREF(function); - function = meth; - oparg++; - nargs++; - assert(postcall_shrink >= 1); - postcall_shrink--; - } - // Check if the call can be inlined or not - if (Py_TYPE(function) == &PyFunction_Type && tstate->interp->eval_frame == NULL) { - int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(function))->co_flags; - int is_generator = code_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR); - if (!is_generator) { - PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : PyFunction_GET_GLOBALS(function); - STACK_SHRINK(oparg); - InterpreterFrame *new_frame = _PyEvalFramePushAndInit( - tstate, PyFunction_AS_FRAME_CONSTRUCTOR(function), locals, - stack_pointer, - nargs, kwnames); - STACK_SHRINK(postcall_shrink); - // The frame has stolen all the arguments from the stack, - // so there is no need to clean them up. - Py_XDECREF(kwnames); - Py_DECREF(function); - if (new_frame == NULL) { - goto error; - } - _PyFrame_SetStackPointer(frame, stack_pointer); - new_frame->previous = frame; - cframe.current_frame = frame = new_frame; - new_frame->depth = frame->depth + 1; - goto start_frame; - } - } - /* Callable is not a normal Python function */ - PyObject *res; - if (cframe.use_tracing) { - res = trace_call_function(tstate, function, stack_pointer-oparg, nargs, kwnames); - } - else { - res = PyObject_Vectorcall(function, stack_pointer-oparg, - nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); - } - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - Py_DECREF(function); - Py_XDECREF(kwnames); - /* Clear the stack */ - STACK_SHRINK(oparg); - for (int i = 0; i < oparg; i++) { - Py_DECREF(stack_pointer[i]); - } - STACK_SHRINK(postcall_shrink); - PUSH(res); - if (res == NULL) { - goto error; - } - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - - TARGET(CALL_FUNCTION_ADAPTIVE) { - SpecializedCacheEntry *cache = GET_CACHE(); - nargs = cache->adaptive.original_oparg; - if (cache->adaptive.counter == 0) { - next_instr--; - if (_Py_Specialize_CallFunction( - PEEK(nargs + 1), next_instr, nargs, cache, BUILTINS()) < 0) { - goto error; - } - DISPATCH(); - } - else { - STAT_INC(CALL_FUNCTION, deferred); - cache->adaptive.counter--; - oparg = nargs; - kwnames = NULL; - postcall_shrink = 1; - goto call_function; - } - } - - TARGET(CALL_FUNCTION_PY_SIMPLE) { - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - int argcount = cache0->original_oparg; - _PyCallCache *cache1 = &caches[-1].call; - PyObject *callable = PEEK(argcount+1); - DEOPT_IF(!PyFunction_Check(callable), CALL_FUNCTION); - PyFunctionObject *func = (PyFunctionObject *)callable; - DEOPT_IF(func->func_version != cache1->func_version, CALL_FUNCTION); - /* PEP 523 */ - DEOPT_IF(tstate->interp->eval_frame != NULL, CALL_FUNCTION); - STAT_INC(CALL_FUNCTION, hit); - PyCodeObject *code = (PyCodeObject *)func->func_code; - size_t size = code->co_nlocalsplus + code->co_stacksize + FRAME_SPECIALS_SIZE; - InterpreterFrame *new_frame = _PyThreadState_BumpFramePointer(tstate, size); - if (new_frame == NULL) { - goto error; - } - _PyFrame_InitializeSpecials(new_frame, PyFunction_AS_FRAME_CONSTRUCTOR(func), - NULL, code->co_nlocalsplus); - STACK_SHRINK(argcount); - for (int i = 0; i < argcount; i++) { - new_frame->localsplus[i] = stack_pointer[i]; - } - int deflen = cache1->defaults_len; - for (int i = 0; i < deflen; i++) { - PyObject *def = PyTuple_GET_ITEM(func->func_defaults, cache1->defaults_start+i); - Py_INCREF(def); - new_frame->localsplus[argcount+i] = def; - } - for (int i = argcount+deflen; i < code->co_nlocalsplus; i++) { - new_frame->localsplus[i] = NULL; - } - STACK_SHRINK(1); - Py_DECREF(func); - _PyFrame_SetStackPointer(frame, stack_pointer); - new_frame->previous = frame; - frame = cframe.current_frame = new_frame; - new_frame->depth = frame->depth + 1; - goto start_frame; - } - - TARGET(CALL_FUNCTION_BUILTIN_O) { - assert(cframe.use_tracing == 0); - /* Builtin METH_O functions */ - - PyObject *callable = SECOND(); - DEOPT_IF(!PyCFunction_CheckExact(callable), CALL_FUNCTION); - DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_O, CALL_FUNCTION); - STAT_INC(CALL_FUNCTION, hit); - - PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); - // This is slower but CPython promises to check all non-vectorcall - // function calls. - if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) { - goto error; - } - PyObject *arg = POP(); - PyObject *res = cfunc(PyCFunction_GET_SELF(callable), arg); - _Py_LeaveRecursiveCall(tstate); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - - /* Clear the stack of the function object. */ - Py_DECREF(arg); - Py_DECREF(callable); - SET_TOP(res); - if (res == NULL) { - goto error; - } - DISPATCH(); - } - - TARGET(CALL_FUNCTION_BUILTIN_FAST) { - assert(cframe.use_tracing == 0); - /* Builtin METH_FASTCALL functions, without keywords */ - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - int nargs = cache0->original_oparg; - PyObject **pfunc = &PEEK(nargs + 1); - PyObject *callable = *pfunc; - DEOPT_IF(!PyCFunction_CheckExact(callable), CALL_FUNCTION); - DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_FASTCALL, - CALL_FUNCTION); - STAT_INC(CALL_FUNCTION, hit); - - PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); - /* res = func(self, args, nargs) */ - PyObject *res = ((_PyCFunctionFast)(void(*)(void))cfunc)( - PyCFunction_GET_SELF(callable), - &PEEK(nargs), - nargs); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - - /* Clear the stack of the function object. */ - while (stack_pointer > pfunc) { - PyObject *x = POP(); - Py_DECREF(x); - } - PUSH(res); - if (res == NULL) { - /* Not deopting because this doesn't mean our optimization was - wrong. `res` can be NULL for valid reasons. Eg. getattr(x, - 'invalid'). In those cases an exception is set, so we must - handle it. - */ - goto error; - } - DISPATCH(); - } - - TARGET(CALL_FUNCTION_LEN) { - assert(cframe.use_tracing == 0); - /* len(o) */ - SpecializedCacheEntry *caches = GET_CACHE(); - assert(caches[0].adaptive.original_oparg == 1); - _PyObjectCache *cache1 = &caches[-1].obj; - - PyObject *callable = SECOND(); - DEOPT_IF(callable != cache1->obj, CALL_FUNCTION); - STAT_INC(CALL_FUNCTION, hit); - - Py_ssize_t len_i = PyObject_Length(TOP()); - if (len_i < 0) { - goto error; - } - PyObject *res = PyLong_FromSsize_t(len_i); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - - /* Clear the stack of the function object. */ - Py_DECREF(POP()); - Py_DECREF(callable); - SET_TOP(res); - if (res == NULL) { - goto error; - } - DISPATCH(); - } - - TARGET(CALL_FUNCTION_ISINSTANCE) { - assert(cframe.use_tracing == 0); - /* isinstance(o, o2) */ - SpecializedCacheEntry *caches = GET_CACHE(); - assert(caches[0].adaptive.original_oparg == 2); - _PyObjectCache *cache1 = &caches[-1].obj; - - PyObject *callable = THIRD(); - DEOPT_IF(callable != cache1->obj, CALL_FUNCTION); - STAT_INC(CALL_FUNCTION, hit); - - int retval = PyObject_IsInstance(SECOND(), TOP()); - if (retval < 0) { - goto error; - } - PyObject *res = PyBool_FromLong(retval); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - - /* Clear the stack of the function object. */ - Py_DECREF(POP()); - Py_DECREF(POP()); - Py_DECREF(callable); - SET_TOP(res); - if (res == NULL) { - goto error; - } - DISPATCH(); - } - - TARGET(CALL_FUNCTION_EX) { - PREDICTED(CALL_FUNCTION_EX); - PyObject *func, *callargs, *kwargs = NULL, *result; - if (oparg & 0x01) { - kwargs = POP(); - if (!PyDict_CheckExact(kwargs)) { - PyObject *d = PyDict_New(); - if (d == NULL) - goto error; - if (_PyDict_MergeEx(d, kwargs, 2) < 0) { - Py_DECREF(d); - format_kwargs_error(tstate, SECOND(), kwargs); - Py_DECREF(kwargs); - goto error; - } - Py_DECREF(kwargs); - kwargs = d; - } - assert(PyDict_CheckExact(kwargs)); - } - callargs = POP(); - func = TOP(); - if (!PyTuple_CheckExact(callargs)) { - if (check_args_iterable(tstate, func, callargs) < 0) { - Py_DECREF(callargs); - goto error; - } - Py_SETREF(callargs, PySequence_Tuple(callargs)); - if (callargs == NULL) { - goto error; - } - } - assert(PyTuple_CheckExact(callargs)); - - result = do_call_core(tstate, func, callargs, kwargs, cframe.use_tracing); - Py_DECREF(func); - Py_DECREF(callargs); - Py_XDECREF(kwargs); - - SET_TOP(result); - if (result == NULL) { - goto error; - } - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - - TARGET(MAKE_FUNCTION) { - PyObject *codeobj = POP(); - PyFunctionObject *func = (PyFunctionObject *) - PyFunction_New(codeobj, GLOBALS()); - - Py_DECREF(codeobj); - if (func == NULL) { - goto error; - } - - if (oparg & 0x08) { - assert(PyTuple_CheckExact(TOP())); - func->func_closure = POP(); - } - if (oparg & 0x04) { - assert(PyTuple_CheckExact(TOP())); - func->func_annotations = POP(); - } - if (oparg & 0x02) { - assert(PyDict_CheckExact(TOP())); - func->func_kwdefaults = POP(); - } - if (oparg & 0x01) { - assert(PyTuple_CheckExact(TOP())); - func->func_defaults = POP(); - } - - PUSH((PyObject *)func); - DISPATCH(); - } - - TARGET(BUILD_SLICE) { - PyObject *start, *stop, *step, *slice; - if (oparg == 3) - step = POP(); - else - step = NULL; - stop = POP(); - start = TOP(); - slice = PySlice_New(start, stop, step); - Py_DECREF(start); - Py_DECREF(stop); - Py_XDECREF(step); - SET_TOP(slice); - if (slice == NULL) - goto error; - DISPATCH(); - } - - TARGET(FORMAT_VALUE) { - /* Handles f-string value formatting. */ - PyObject *result; - PyObject *fmt_spec; - PyObject *value; - PyObject *(*conv_fn)(PyObject *); - int which_conversion = oparg & FVC_MASK; - int have_fmt_spec = (oparg & FVS_MASK) == FVS_HAVE_SPEC; - - fmt_spec = have_fmt_spec ? POP() : NULL; - value = POP(); - - /* See if any conversion is specified. */ - switch (which_conversion) { - case FVC_NONE: conv_fn = NULL; break; - case FVC_STR: conv_fn = PyObject_Str; break; - case FVC_REPR: conv_fn = PyObject_Repr; break; - case FVC_ASCII: conv_fn = PyObject_ASCII; break; - default: - _PyErr_Format(tstate, PyExc_SystemError, - "unexpected conversion flag %d", - which_conversion); - goto error; - } - - /* If there's a conversion function, call it and replace - value with that result. Otherwise, just use value, - without conversion. */ - if (conv_fn != NULL) { - result = conv_fn(value); - Py_DECREF(value); - if (result == NULL) { - Py_XDECREF(fmt_spec); - goto error; - } - value = result; - } - - /* If value is a unicode object, and there's no fmt_spec, - then we know the result of format(value) is value - itself. In that case, skip calling format(). I plan to - move this optimization in to PyObject_Format() - itself. */ - if (PyUnicode_CheckExact(value) && fmt_spec == NULL) { - /* Do nothing, just transfer ownership to result. */ - result = value; - } else { - /* Actually call format(). */ - result = PyObject_Format(value, fmt_spec); - Py_DECREF(value); - Py_XDECREF(fmt_spec); - if (result == NULL) { - goto error; - } - } - - PUSH(result); - DISPATCH(); - } - - TARGET(ROT_N) { - PyObject *top = TOP(); - memmove(&PEEK(oparg - 1), &PEEK(oparg), - sizeof(PyObject*) * (oparg - 1)); - PEEK(oparg) = top; - DISPATCH(); - } - - TARGET(COPY) { - assert(oparg != 0); - PyObject *peek = PEEK(oparg); - Py_INCREF(peek); - PUSH(peek); - DISPATCH(); - } - - TARGET(BINARY_OP) { - PREDICTED(BINARY_OP); - STAT_INC(BINARY_OP, unquickened); - PyObject *rhs = POP(); - PyObject *lhs = TOP(); - assert(0 <= oparg); - assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); - assert(binary_ops[oparg]); - PyObject *res = binary_ops[oparg](lhs, rhs); - Py_DECREF(lhs); - Py_DECREF(rhs); - SET_TOP(res); - if (res == NULL) { - goto error; - } - DISPATCH(); - } - - TARGET(BINARY_OP_ADAPTIVE) { - assert(cframe.use_tracing == 0); - SpecializedCacheEntry *cache = GET_CACHE(); - if (cache->adaptive.counter == 0) { - PyObject *lhs = SECOND(); - PyObject *rhs = TOP(); - next_instr--; - _Py_Specialize_BinaryOp(lhs, rhs, next_instr, cache); - DISPATCH(); - } - else { - STAT_INC(BINARY_OP, deferred); - cache->adaptive.counter--; - oparg = cache->adaptive.original_oparg; - STAT_DEC(BINARY_OP, unquickened); - JUMP_TO_INSTRUCTION(BINARY_OP); - } - } - - TARGET(EXTENDED_ARG) { - int oldoparg = oparg; - NEXTOPARG(); - oparg |= oldoparg << 8; - PRE_DISPATCH_GOTO(); - DISPATCH_GOTO(); - } +#include "generated_cases.c.h" #if USE_COMPUTED_GOTOS - TARGET_DO_TRACING: { + TARGET_DO_TRACING: #else - case DO_TRACING: { + case DO_TRACING: #endif - int instr_prev = skip_backwards_over_extended_args(co, frame->f_lasti); - frame->f_lasti = INSTR_OFFSET(); - TRACING_NEXTOPARG(); - if (PyDTrace_LINE_ENABLED()) { - maybe_dtrace_line(frame, &tstate->trace_info, instr_prev); - } - /* line-by-line tracing support */ - - if (cframe.use_tracing && - tstate->c_tracefunc != NULL && !tstate->tracing) { - int err; - /* see maybe_call_line_trace() - for expository comments */ - _PyFrame_SetStackPointer(frame, stack_pointer); - - err = maybe_call_line_trace(tstate->c_tracefunc, - tstate->c_traceobj, - tstate, frame, instr_prev); - if (err) { - /* trace function raised an exception */ - next_instr++; - goto error; + { + assert(cframe.use_tracing); + assert(tstate->tracing == 0); + if (INSTR_OFFSET() >= frame->f_code->_co_firsttraceable) { + int instr_prev = _PyInterpreterFrame_LASTI(frame); + frame->prev_instr = next_instr; + NEXTOPARG(); + // No _PyOpcode_Deopt here, since RESUME has no optimized forms: + if (opcode == RESUME) { + if (oparg < 2) { + CHECK_EVAL_BREAKER(); } - /* Reload possibly changed frame fields */ - JUMPTO(frame->f_lasti); - - stack_pointer = _PyFrame_GetStackPointer(frame); - frame->stacktop = -1; - TRACING_NEXTOPARG(); + /* Call tracing */ + TRACE_FUNCTION_ENTRY(); + DTRACE_FUNCTION_ENTRY(); } - PRE_DISPATCH_GOTO(); - DISPATCH_GOTO(); - } + else { + /* line-by-line tracing support */ + if (PyDTrace_LINE_ENABLED()) { + maybe_dtrace_line(frame, &tstate->trace_info, instr_prev); + } + if (cframe.use_tracing && + tstate->c_tracefunc != NULL && !tstate->tracing) { + int err; + /* see maybe_call_line_trace() + for expository comments */ + _PyFrame_SetStackPointer(frame, stack_pointer); + + err = maybe_call_line_trace(tstate->c_tracefunc, + tstate->c_traceobj, + tstate, frame, instr_prev); + // Reload possibly changed frame fields: + stack_pointer = _PyFrame_GetStackPointer(frame); + frame->stacktop = -1; + // next_instr is only reloaded if tracing *does not* raise. + // This is consistent with the behavior of older Python + // versions. If a trace function sets a new f_lineno and + // *then* raises, we use the *old* location when searching + // for an exception handler, displaying the traceback, and + // so on: + if (err) { + // next_instr wasn't incremented at the start of this + // instruction. Increment it before handling the error, + // so that it looks the same as a "normal" instruction: + next_instr++; + goto error; + } + // Reload next_instr. Don't increment it, though, since + // we're going to re-dispatch to the "true" instruction now: + next_instr = frame->prev_instr; + } + } + } + NEXTOPARG(); + PRE_DISPATCH_GOTO(); + // No _PyOpcode_Deopt here, since EXTENDED_ARG has no optimized forms: + while (opcode == EXTENDED_ARG) { + // CPython hasn't ever traced the instruction after an EXTENDED_ARG. + // Inline the EXTENDED_ARG here, so we can avoid branching there: + INSTRUCTION_START(EXTENDED_ARG); + opcode = _Py_OPCODE(*next_instr); + oparg = oparg << 8 | _Py_OPARG(*next_instr); + // Make sure the next instruction isn't a RESUME, since that needs + // to trace properly (and shouldn't have an EXTENDED_ARG, anyways): + assert(opcode != RESUME); + PRE_DISPATCH_GOTO(); + } + opcode = _PyOpcode_Deopt[opcode]; + if (_PyOpcode_Caches[opcode]) { + uint16_t *counter = &next_instr[1].cache; + // The instruction is going to decrement the counter, so we need to + // increment it here to make sure it doesn't try to specialize: + if (!ADAPTIVE_COUNTER_IS_MAX(*counter)) { + INCREMENT_ADAPTIVE_COUNTER(*counter); + } + } + DISPATCH_GOTO(); + } #if USE_COMPUTED_GOTOS _unknown_opcode: #else - default: + EXTRA_CASES // From opcode.h, a 'case' for each unused opcode #endif - fprintf(stderr, - "XXX lineno: %d, opcode: %d\n", - PyCode_Addr2Line(frame->f_code, frame->f_lasti*sizeof(_Py_CODEUNIT)), - opcode); - _PyErr_SetString(tstate, PyExc_SystemError, "unknown opcode"); + /* Tell C compilers not to hold the opcode variable in the loop. + next_instr points the current instruction without TARGET(). */ + opcode = _Py_OPCODE(*next_instr); + _PyErr_Format(tstate, PyExc_SystemError, + "%U:%d: unknown opcode %d", + frame->f_code->co_filename, + _PyInterpreterFrame_GetLine(frame), + opcode); goto error; } /* End instructions */ @@ -4949,69 +966,25 @@ check_eval_breaker: or goto error. */ Py_UNREACHABLE(); -/* Specialization misses */ - -#define MISS_WITH_CACHE(opname) \ -opname ## _miss: \ - { \ - STAT_INC(opname, miss); \ - _PyAdaptiveEntry *cache = &GET_CACHE()->adaptive; \ - cache->counter--; \ - if (cache->counter == 0) { \ - next_instr[-1] = _Py_MAKECODEUNIT(opname ## _ADAPTIVE, _Py_OPARG(next_instr[-1])); \ - STAT_INC(opname, deopt); \ - cache_backoff(cache); \ - } \ - oparg = cache->original_oparg; \ - STAT_DEC(opname, unquickened); \ - JUMP_TO_INSTRUCTION(opname); \ - } - -#define MISS_WITH_OPARG_COUNTER(opname) \ -opname ## _miss: \ - { \ - STAT_INC(opname, miss); \ - uint8_t oparg = _Py_OPARG(next_instr[-1])-1; \ - UPDATE_PREV_INSTR_OPARG(next_instr, oparg); \ - assert(_Py_OPARG(next_instr[-1]) == oparg); \ - if (oparg == 0) /* too many cache misses */ { \ - oparg = ADAPTIVE_CACHE_BACKOFF; \ - next_instr[-1] = _Py_MAKECODEUNIT(opname ## _ADAPTIVE, oparg); \ - STAT_INC(opname, deopt); \ - } \ - STAT_DEC(opname, unquickened); \ - JUMP_TO_INSTRUCTION(opname); \ - } - -MISS_WITH_CACHE(LOAD_ATTR) -MISS_WITH_CACHE(STORE_ATTR) -MISS_WITH_CACHE(LOAD_GLOBAL) -MISS_WITH_CACHE(LOAD_METHOD) -MISS_WITH_CACHE(CALL_FUNCTION) -MISS_WITH_CACHE(BINARY_OP) -MISS_WITH_CACHE(BINARY_SUBSCR) -MISS_WITH_OPARG_COUNTER(STORE_SUBSCR) - -binary_subscr_dict_error: - { - PyObject *sub = POP(); - if (!_PyErr_Occurred(tstate)) { - _PyErr_SetKeyError(sub); - } - Py_DECREF(sub); - goto error; - } - unbound_local_error: { format_exc_check_arg(tstate, PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, - PyTuple_GetItem(co->co_localsplusnames, oparg) + PyTuple_GetItem(frame->f_code->co_localsplusnames, oparg) ); goto error; } +pop_4_error: + STACK_SHRINK(1); +pop_3_error: + STACK_SHRINK(1); +pop_2_error: + STACK_SHRINK(1); +pop_1_error: + STACK_SHRINK(1); error: + kwnames = NULL; /* Double-check exception status. */ #ifdef NDEBUG if (!_PyErr_Occurred(tstate)) { @@ -5023,122 +996,103 @@ error: #endif /* Log traceback info. */ - PyFrameObject *f = _PyFrame_GetFrameObject(frame); - if (f != NULL) { - PyTraceBack_Here(f); + assert(frame != &entry_frame); + if (!_PyFrame_IsIncomplete(frame)) { + PyFrameObject *f = _PyFrame_GetFrameObject(frame); + if (f != NULL) { + PyTraceBack_Here(f); + } } if (tstate->c_tracefunc != NULL) { - /* Make sure state is set to FRAME_EXECUTING for tracing */ - assert(frame->f_state == FRAME_EXECUTING); - frame->f_state = FRAME_UNWINDING; + /* Make sure state is set to FRAME_UNWINDING for tracing */ call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, frame); } exception_unwind: - frame->f_state = FRAME_UNWINDING; - /* We can't use frame->f_lasti here, as RERAISE may have set it */ - int offset = INSTR_OFFSET()-1; - int level, handler, lasti; - if (get_exception_handler(co, offset, &level, &handler, &lasti) == 0) { - // No handlers, so exit. - assert(retval == NULL); - assert(_PyErr_Occurred(tstate)); + { + /* We can't use frame->f_lasti here, as RERAISE may have set it */ + int offset = INSTR_OFFSET()-1; + int level, handler, lasti; + if (get_exception_handler(frame->f_code, offset, &level, &handler, &lasti) == 0) { + // No handlers, so exit. + assert(_PyErr_Occurred(tstate)); - /* Pop remaining stack entries. */ - PyObject **stackbase = _PyFrame_Stackbase(frame); - while (stack_pointer > stackbase) { - PyObject *o = POP(); - Py_XDECREF(o); + /* Pop remaining stack entries. */ + PyObject **stackbase = _PyFrame_Stackbase(frame); + while (stack_pointer > stackbase) { + PyObject *o = POP(); + Py_XDECREF(o); + } + assert(STACK_LEVEL() == 0); + _PyFrame_SetStackPointer(frame, stack_pointer); + TRACE_FUNCTION_UNWIND(); + DTRACE_FUNCTION_EXIT(); + goto exit_unwind; } - assert(STACK_LEVEL() == 0); - _PyFrame_SetStackPointer(frame, stack_pointer); - frame->f_state = FRAME_RAISED; - goto exiting; - } - assert(STACK_LEVEL() >= level); - PyObject **new_top = _PyFrame_Stackbase(frame) + level; - while (stack_pointer > new_top) { - PyObject *v = POP(); - Py_XDECREF(v); - } - PyObject *exc, *val, *tb; - if (lasti) { - PyObject *lasti = PyLong_FromLong(frame->f_lasti); - if (lasti == NULL) { - goto exception_unwind; + assert(STACK_LEVEL() >= level); + PyObject **new_top = _PyFrame_Stackbase(frame) + level; + while (stack_pointer > new_top) { + PyObject *v = POP(); + Py_XDECREF(v); } - PUSH(lasti); - } - _PyErr_Fetch(tstate, &exc, &val, &tb); - /* Make the raw exception data - available to the handler, - so a program can emulate the - Python main loop. */ - _PyErr_NormalizeException(tstate, &exc, &val, &tb); - if (tb != NULL) - PyException_SetTraceback(val, tb); - else - PyException_SetTraceback(val, Py_None); - if (tb == NULL) { - tb = Py_None; - Py_INCREF(Py_None); - } - PUSH(tb); - PUSH(val); - PUSH(exc); - ASSERT_EXC_TYPE_IS_REDUNDANT(exc, val); - JUMPTO(handler); - /* Resume normal execution */ - frame->f_state = FRAME_EXECUTING; - DISPATCH(); - } - -exiting: - if (cframe.use_tracing) { - if (tstate->c_tracefunc) { - if (call_trace_protected(tstate->c_tracefunc, tstate->c_traceobj, - tstate, frame, PyTrace_RETURN, retval)) { - Py_CLEAR(retval); - } - } - if (tstate->c_profilefunc) { - if (call_trace_protected(tstate->c_profilefunc, tstate->c_profileobj, - tstate, frame, PyTrace_RETURN, retval)) { - Py_CLEAR(retval); + PyObject *exc, *val, *tb; + if (lasti) { + int frame_lasti = _PyInterpreterFrame_LASTI(frame); + PyObject *lasti = PyLong_FromLong(frame_lasti); + if (lasti == NULL) { + goto exception_unwind; + } + PUSH(lasti); } + _PyErr_Fetch(tstate, &exc, &val, &tb); + /* Make the raw exception data + available to the handler, + so a program can emulate the + Python main loop. */ + _PyErr_NormalizeException(tstate, &exc, &val, &tb); + if (tb != NULL) + PyException_SetTraceback(val, tb); + else + PyException_SetTraceback(val, Py_None); + Py_XDECREF(tb); + Py_XDECREF(exc); + PUSH(val); + JUMPTO(handler); + /* Resume normal execution */ + DISPATCH(); } } - /* pop frame */ -exit_eval_frame: - if (PyDTrace_FUNCTION_RETURN_ENABLED()) - dtrace_function_return(frame); - _Py_LeaveRecursiveCall(tstate); - - if (frame->depth) { - cframe.current_frame = frame->previous; - _PyFrame_StackPush(cframe.current_frame, retval); - if (_PyEvalFrameClearAndPop(tstate, frame)) { - retval = NULL; - } - frame = cframe.current_frame; - if (retval == NULL) { - assert(_PyErr_Occurred(tstate)); - throwflag = 1; - } - retval = NULL; - goto resume_frame; +exit_unwind: + assert(_PyErr_Occurred(tstate)); + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = cframe.current_frame = dying->previous; + _PyEvalFrameClearAndPop(tstate, dying); + if (frame == &entry_frame) { + /* Restore previous cframe and exit */ + tstate->cframe = cframe.previous; + tstate->cframe->use_tracing = cframe.use_tracing; + assert(tstate->cframe->current_frame == frame->previous); + _Py_LeaveRecursiveCallTstate(tstate); + return NULL; } - /* Restore previous cframe. */ - tstate->cframe = cframe.previous; - tstate->cframe->use_tracing = cframe.use_tracing; - assert(tstate->cframe->current_frame == frame->previous); - return _Py_CheckFunctionResult(tstate, NULL, retval, __func__); +resume_with_error: + SET_LOCALS_FROM_FRAME(); + goto error; + } +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#elif defined(_MSC_VER) /* MS_WINDOWS */ +# pragma warning(pop) +#endif static void format_missing(PyThreadState *tstate, const char *kind, @@ -5362,20 +1316,6 @@ fail: } -/* Exception table parsing code. - * See Objects/exception_table_notes.txt for details. - */ - -static inline unsigned char * -parse_varint(unsigned char *p, int *result) { - int val = p[0] & 63; - while (p[0] & 64) { - p++; - val = (val << 6) | (p[0] & 63); - } - *result = val; - return p+1; -} static inline unsigned char * scan_back_to_entry_start(unsigned char *p) { @@ -5445,11 +1385,11 @@ get_exception_handler(PyCodeObject *code, int index, int *level, int *handler, i } static int -initialize_locals(PyThreadState *tstate, PyFrameConstructor *con, +initialize_locals(PyThreadState *tstate, PyFunctionObject *func, PyObject **localsplus, PyObject *const *args, Py_ssize_t argcount, PyObject *kwnames) { - PyCodeObject *co = (PyCodeObject*)con->fc_code; + PyCodeObject *co = (PyCodeObject*)func->func_code; const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount; /* Create a dictionary for keyword parameters (**kwags) */ @@ -5488,7 +1428,13 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con, /* Pack other positional arguments into the *args argument */ if (co->co_flags & CO_VARARGS) { PyObject *u = NULL; - u = _PyTuple_FromArraySteal(args + n, argcount - n); + if (argcount == n) { + u = Py_NewRef(&_Py_SINGLETON(tuple_empty)); + } + else { + assert(args != NULL); + u = _PyTuple_FromArraySteal(args + n, argcount - n); + } if (u == NULL) { goto fail_post_positional; } @@ -5514,7 +1460,7 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con, if (keyword == NULL || !PyUnicode_Check(keyword)) { _PyErr_Format(tstate, PyExc_TypeError, "%U() keywords must be strings", - con->fc_qualname); + func->func_qualname); goto kw_fail; } @@ -5546,14 +1492,14 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con, if (co->co_posonlyargcount && positional_only_passed_as_keyword(tstate, co, kwcount, kwnames, - con->fc_qualname)) + func->func_qualname)) { goto kw_fail; } _PyErr_Format(tstate, PyExc_TypeError, "%U() got an unexpected keyword argument '%S'", - con->fc_qualname, keyword); + func->func_qualname, keyword); goto kw_fail; } @@ -5574,7 +1520,7 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con, if (localsplus[j] != NULL) { _PyErr_Format(tstate, PyExc_TypeError, "%U() got multiple values for argument '%S'", - con->fc_qualname, keyword); + func->func_qualname, keyword); goto kw_fail; } localsplus[j] = value; @@ -5583,14 +1529,14 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con, /* Check the number of positional arguments */ if ((argcount > co->co_argcount) && !(co->co_flags & CO_VARARGS)) { - too_many_positional(tstate, co, argcount, con->fc_defaults, localsplus, - con->fc_qualname); + too_many_positional(tstate, co, argcount, func->func_defaults, localsplus, + func->func_qualname); goto fail_post_args; } /* Add missing positional arguments (copy default values from defs) */ if (argcount < co->co_argcount) { - Py_ssize_t defcount = con->fc_defaults == NULL ? 0 : PyTuple_GET_SIZE(con->fc_defaults); + Py_ssize_t defcount = func->func_defaults == NULL ? 0 : PyTuple_GET_SIZE(func->func_defaults); Py_ssize_t m = co->co_argcount - defcount; Py_ssize_t missing = 0; for (i = argcount; i < m; i++) { @@ -5600,7 +1546,7 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con, } if (missing) { missing_arguments(tstate, co, missing, defcount, localsplus, - con->fc_qualname); + func->func_qualname); goto fail_post_args; } if (n > m) @@ -5608,12 +1554,11 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con, else i = 0; if (defcount) { - PyObject **defs = &PyTuple_GET_ITEM(con->fc_defaults, 0); + PyObject **defs = &PyTuple_GET_ITEM(func->func_defaults, 0); for (; i < defcount; i++) { if (localsplus[m+i] == NULL) { PyObject *def = defs[i]; - Py_INCREF(def); - localsplus[m+i] = def; + localsplus[m+i] = Py_NewRef(def); } } } @@ -5626,11 +1571,10 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con, if (localsplus[i] != NULL) continue; PyObject *varname = PyTuple_GET_ITEM(co->co_localsplusnames, i); - if (con->fc_kwdefaults != NULL) { - PyObject *def = PyDict_GetItemWithError(con->fc_kwdefaults, varname); + if (func->func_kwdefaults != NULL) { + PyObject *def = PyDict_GetItemWithError(func->func_kwdefaults, varname); if (def) { - Py_INCREF(def); - localsplus[i] = def; + localsplus[i] = Py_NewRef(def); continue; } else if (_PyErr_Occurred(tstate)) { @@ -5641,16 +1585,10 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con, } if (missing) { missing_arguments(tstate, co, missing, -1, localsplus, - con->fc_qualname); + func->func_qualname); goto fail_post_args; } } - /* Copy closure variables to free variables */ - for (i = 0; i < co->co_nfreevars; ++i) { - PyObject *o = PyTuple_GET_ITEM(con->fc_closure, i); - Py_INCREF(o); - localsplus[co->co_nlocals + co->co_nplaincellvars + i] = o; - } return 0; fail_pre_positional: @@ -5670,83 +1608,23 @@ fail_post_args: return -1; } -static InterpreterFrame * -make_coro_frame(PyThreadState *tstate, - PyFrameConstructor *con, PyObject *locals, - PyObject *const *args, Py_ssize_t argcount, - PyObject *kwnames) -{ - assert(is_tstate_valid(tstate)); - assert(con->fc_defaults == NULL || PyTuple_CheckExact(con->fc_defaults)); - PyCodeObject *code = (PyCodeObject *)con->fc_code; - int size = code->co_nlocalsplus+code->co_stacksize + FRAME_SPECIALS_SIZE; - InterpreterFrame *frame = (InterpreterFrame *)PyMem_Malloc(sizeof(PyObject *)*size); - if (frame == NULL) { - goto fail_no_memory; - } - _PyFrame_InitializeSpecials(frame, con, locals, code->co_nlocalsplus); - for (int i = 0; i < code->co_nlocalsplus; i++) { - frame->localsplus[i] = NULL; - } - assert(frame->frame_obj == NULL); - if (initialize_locals(tstate, con, frame->localsplus, args, argcount, kwnames)) { - _PyFrame_Clear(frame, 1); - return NULL; - } - return frame; -fail_no_memory: - /* Consume the references */ - for (Py_ssize_t i = 0; i < argcount; i++) { - Py_DECREF(args[i]); - } - if (kwnames) { - Py_ssize_t kwcount = PyTuple_GET_SIZE(kwnames); - for (Py_ssize_t i = 0; i < kwcount; i++) { - Py_DECREF(args[i+argcount]); - } - } - PyErr_NoMemory(); - return NULL; -} - -/* Consumes all the references to the args */ -static PyObject * -make_coro(PyThreadState *tstate, PyFrameConstructor *con, - PyObject *locals, - PyObject* const* args, size_t argcount, - PyObject *kwnames) -{ - assert (((PyCodeObject *)con->fc_code)->co_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)); - InterpreterFrame *frame = make_coro_frame(tstate, con, locals, args, argcount, kwnames); - if (frame == NULL) { - return NULL; - } - PyObject *gen = _Py_MakeCoro(con, frame); - if (gen == NULL) { - return NULL; - } - return gen; -} - -/* Consumes all the references to the args */ -static InterpreterFrame * -_PyEvalFramePushAndInit(PyThreadState *tstate, PyFrameConstructor *con, +/* Consumes references to func, locals and all the args */ +static _PyInterpreterFrame * +_PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func, PyObject *locals, PyObject* const* args, size_t argcount, PyObject *kwnames) { - PyCodeObject * code = (PyCodeObject *)con->fc_code; - size_t size = code->co_nlocalsplus + code->co_stacksize + FRAME_SPECIALS_SIZE; - InterpreterFrame *frame = _PyThreadState_BumpFramePointer(tstate, size); + PyCodeObject * code = (PyCodeObject *)func->func_code; + CALL_STAT_INC(frames_pushed); + _PyInterpreterFrame *frame = _PyThreadState_PushFrame(tstate, code->co_framesize); if (frame == NULL) { goto fail; } - _PyFrame_InitializeSpecials(frame, con, locals, code->co_nlocalsplus); + _PyFrame_Initialize(frame, func, locals, code, 0); PyObject **localsarray = &frame->localsplus[0]; - for (int i = 0; i < code->co_nlocalsplus; i++) { - localsarray[i] = NULL; - } - if (initialize_locals(tstate, con, localsarray, args, argcount, kwnames)) { - _PyFrame_Clear(frame, 0); + if (initialize_locals(tstate, func, localsarray, args, argcount, kwnames)) { + assert(frame->owner != FRAME_OWNED_BY_GENERATOR); + _PyEvalFrameClearAndPop(tstate, frame); return NULL; } return frame; @@ -5765,30 +1643,59 @@ fail: return NULL; } -static int -_PyEvalFrameClearAndPop(PyThreadState *tstate, InterpreterFrame * frame) +static void +clear_thread_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) { - --tstate->recursion_remaining; - assert(frame->frame_obj == NULL || frame->frame_obj->f_own_locals_memory == 0); - if (_PyFrame_Clear(frame, 0)) { - ++tstate->recursion_remaining; - return -1; - } - ++tstate->recursion_remaining; + assert(frame->owner == FRAME_OWNED_BY_THREAD); + // Make sure that this is, indeed, the top frame. We can't check this in + // _PyThreadState_PopFrame, since f_code is already cleared at that point: + assert((PyObject **)frame + frame->f_code->co_framesize == + tstate->datastack_top); + tstate->c_recursion_remaining--; + assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame); + _PyFrame_Clear(frame); + tstate->c_recursion_remaining++; _PyThreadState_PopFrame(tstate, frame); - return 0; } +static void +clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) +{ + assert(frame->owner == FRAME_OWNED_BY_GENERATOR); + PyGenObject *gen = _PyFrame_GetGenerator(frame); + gen->gi_frame_state = FRAME_CLEARED; + assert(tstate->exc_info == &gen->gi_exc_state); + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + tstate->c_recursion_remaining--; + assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame); + _PyFrame_Clear(frame); + tstate->c_recursion_remaining++; + frame->previous = NULL; +} + +static void +_PyEvalFrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame * frame) +{ + if (frame->owner == FRAME_OWNED_BY_THREAD) { + clear_thread_frame(tstate, frame); + } + else { + clear_gen_frame(tstate, frame); + } +} + + PyObject * -_PyEval_Vector(PyThreadState *tstate, PyFrameConstructor *con, +_PyEval_Vector(PyThreadState *tstate, PyFunctionObject *func, PyObject *locals, PyObject* const* args, size_t argcount, PyObject *kwnames) { - PyCodeObject *code = (PyCodeObject *)con->fc_code; - /* _PyEvalFramePushAndInit and make_coro consume - * all the references to their arguments - */ + /* _PyEvalFramePushAndInit consumes the references + * to func, locals and all its arguments */ + Py_INCREF(func); + Py_XINCREF(locals); for (size_t i = 0; i < argcount; i++) { Py_INCREF(args[i]); } @@ -5798,22 +1705,13 @@ _PyEval_Vector(PyThreadState *tstate, PyFrameConstructor *con, Py_INCREF(args[i+argcount]); } } - int is_coro = code->co_flags & - (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR); - if (is_coro) { - return make_coro(tstate, con, locals, args, argcount, kwnames); - } - InterpreterFrame *frame = _PyEvalFramePushAndInit( - tstate, con, locals, args, argcount, kwnames); + _PyInterpreterFrame *frame = _PyEvalFramePushAndInit( + tstate, func, locals, args, argcount, kwnames); if (frame == NULL) { return NULL; } - PyObject *retval = _PyEval_EvalFrame(tstate, frame, 0); - assert(_PyFrame_GetStackPointer(frame) == _PyFrame_Stackbase(frame)); - if (_PyEvalFrameClearAndPop(tstate, frame)) { - retval = NULL; - } - return retval; + EVAL_CALL_STAT_INC(EVAL_CALL_VECTOR); + return _PyEval_EvalFrame(tstate, frame, 0); } /* Legacy API */ @@ -5825,7 +1723,7 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, PyObject *kwdefs, PyObject *closure) { PyThreadState *tstate = _PyThreadState_GET(); - PyObject *res; + PyObject *res = NULL; PyObject *defaults = _PyTuple_FromArray(defs, defcount); if (defaults == NULL) { return NULL; @@ -5838,45 +1736,33 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, if (locals == NULL) { locals = globals; } - PyObject *kwnames; + PyObject *kwnames = NULL; PyObject *const *allargs; - PyObject **newargs; + PyObject **newargs = NULL; + PyFunctionObject *func = NULL; if (kwcount == 0) { allargs = args; - kwnames = NULL; } else { kwnames = PyTuple_New(kwcount); if (kwnames == NULL) { - res = NULL; goto fail; } newargs = PyMem_Malloc(sizeof(PyObject *)*(kwcount+argcount)); if (newargs == NULL) { - res = NULL; - Py_DECREF(kwnames); goto fail; } for (int i = 0; i < argcount; i++) { newargs[i] = args[i]; } for (int i = 0; i < kwcount; i++) { - Py_INCREF(kws[2*i]); - PyTuple_SET_ITEM(kwnames, i, kws[2*i]); + PyTuple_SET_ITEM(kwnames, i, Py_NewRef(kws[2*i])); newargs[argcount+i] = kws[2*i+1]; } allargs = newargs; } - PyObject **kwargs = PyMem_Malloc(sizeof(PyObject *)*kwcount); - if (kwargs == NULL) { - res = NULL; - Py_DECREF(kwnames); - goto fail; - } for (int i = 0; i < kwcount; i++) { - Py_INCREF(kws[2*i]); - PyTuple_SET_ITEM(kwnames, i, kws[2*i]); - kwargs[i] = kws[2*i+1]; + PyTuple_SET_ITEM(kwnames, i, Py_NewRef(kws[2*i])); } PyFrameConstructor constr = { .fc_globals = globals, @@ -5888,14 +1774,18 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, .fc_kwdefaults = kwdefs, .fc_closure = closure }; - res = _PyEval_Vector(tstate, &constr, locals, + func = _PyFunction_FromConstructor(&constr); + if (func == NULL) { + goto fail; + } + EVAL_CALL_STAT_INC(EVAL_CALL_LEGACY); + res = _PyEval_Vector(tstate, func, locals, allargs, argcount, kwnames); - if (kwcount) { - Py_DECREF(kwnames); - PyMem_Free(newargs); - } fail: + Py_XDECREF(func); + Py_XDECREF(kwnames); + PyMem_Free(newargs); Py_DECREF(defaults); return res; } @@ -5911,18 +1801,17 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) if (exc == NULL) { /* Reraise */ _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate); - PyObject *tb; - type = exc_info->exc_type; value = exc_info->exc_value; - tb = exc_info->exc_traceback; - if (Py_IsNone(type) || type == NULL) { + if (Py_IsNone(value) || value == NULL) { _PyErr_SetString(tstate, PyExc_RuntimeError, "No active exception to reraise"); return 0; } + assert(PyExceptionInstance_Check(value)); + type = PyExceptionInstance_Class(value); Py_XINCREF(type); Py_XINCREF(value); - Py_XINCREF(tb); + PyObject *tb = PyException_GetTraceback(value); /* new ref */ _PyErr_Restore(tstate, type, value, tb); return 1; } @@ -5999,6 +1888,66 @@ raise_error: return 0; } +/* Logic for matching an exception in an except* clause (too + complicated for inlining). +*/ + +static int +exception_group_match(PyObject* exc_value, PyObject *match_type, + PyObject **match, PyObject **rest) +{ + if (Py_IsNone(exc_value)) { + *match = Py_NewRef(Py_None); + *rest = Py_NewRef(Py_None); + return 0; + } + assert(PyExceptionInstance_Check(exc_value)); + + if (PyErr_GivenExceptionMatches(exc_value, match_type)) { + /* Full match of exc itself */ + bool is_eg = _PyBaseExceptionGroup_Check(exc_value); + if (is_eg) { + *match = Py_NewRef(exc_value); + } + else { + /* naked exception - wrap it */ + PyObject *excs = PyTuple_Pack(1, exc_value); + if (excs == NULL) { + return -1; + } + PyObject *wrapped = _PyExc_CreateExceptionGroup("", excs); + Py_DECREF(excs); + if (wrapped == NULL) { + return -1; + } + *match = wrapped; + } + *rest = Py_NewRef(Py_None); + return 0; + } + + /* exc_value does not match match_type. + * Check for partial match if it's an exception group. + */ + if (_PyBaseExceptionGroup_Check(exc_value)) { + PyObject *pair = PyObject_CallMethod(exc_value, "split", "(O)", + match_type); + if (pair == NULL) { + return -1; + } + assert(PyTuple_CheckExact(pair)); + assert(PyTuple_GET_SIZE(pair) == 2); + *match = Py_NewRef(PyTuple_GET_ITEM(pair, 0)); + *rest = Py_NewRef(PyTuple_GET_ITEM(pair, 1)); + Py_DECREF(pair); + return 0; + } + /* no match */ + *match = Py_NewRef(Py_None); + *rest = Py_NewRef(exc_value); + return 0; +} + /* Iterate v argcnt times and store the results on the stack (via decreasing sp). Return 1 for success, 0 if error. @@ -6099,34 +2048,16 @@ Error: return 0; } -#ifdef LLTRACE -static int -prtrace(PyThreadState *tstate, PyObject *v, const char *str) -{ - printf("%s ", str); - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); - if (PyObject_Print(v, stdout, 0) != 0) { - /* Don't know what else to do */ - _PyErr_Clear(tstate); - } - printf("\n"); - PyErr_Restore(type, value, traceback); - return 1; -} -#endif - static void call_exc_trace(Py_tracefunc func, PyObject *self, PyThreadState *tstate, - InterpreterFrame *f) + _PyInterpreterFrame *f) { PyObject *type, *value, *traceback, *orig_traceback, *arg; int err; _PyErr_Fetch(tstate, &type, &value, &orig_traceback); if (value == NULL) { - value = Py_None; - Py_INCREF(value); + value = Py_NewRef(Py_None); } _PyErr_NormalizeException(tstate, &type, &value, &orig_traceback); traceback = (orig_traceback != NULL) ? orig_traceback : Py_None; @@ -6149,7 +2080,7 @@ call_exc_trace(Py_tracefunc func, PyObject *self, static int call_trace_protected(Py_tracefunc func, PyObject *obj, - PyThreadState *tstate, InterpreterFrame *frame, + PyThreadState *tstate, _PyInterpreterFrame *frame, int what, PyObject *arg) { PyObject *type, *value, *traceback; @@ -6170,7 +2101,7 @@ call_trace_protected(Py_tracefunc func, PyObject *obj, } static void -initialize_trace_info(PyTraceInfo *trace_info, InterpreterFrame *frame) +initialize_trace_info(PyTraceInfo *trace_info, _PyInterpreterFrame *frame) { PyCodeObject *code = frame->f_code; if (trace_info->code != code) { @@ -6179,45 +2110,62 @@ initialize_trace_info(PyTraceInfo *trace_info, InterpreterFrame *frame) } } +void +PyThreadState_EnterTracing(PyThreadState *tstate) +{ + tstate->tracing++; + tstate->cframe->use_tracing = 0; +} + +void +PyThreadState_LeaveTracing(PyThreadState *tstate) +{ + assert(tstate->tracing > 0 && tstate->cframe->use_tracing == 0); + tstate->tracing--; + _PyThreadState_UpdateTracingState(tstate); +} + static int call_trace(Py_tracefunc func, PyObject *obj, - PyThreadState *tstate, InterpreterFrame *frame, + PyThreadState *tstate, _PyInterpreterFrame *frame, int what, PyObject *arg) { int result; - if (tstate->tracing) + if (tstate->tracing) { return 0; - tstate->tracing++; - _PyThreadState_PauseTracing(tstate); + } PyFrameObject *f = _PyFrame_GetFrameObject(frame); if (f == NULL) { return -1; } - if (frame->f_lasti < 0) { - f->f_lineno = frame->f_code->co_firstlineno; - } - else { - initialize_trace_info(&tstate->trace_info, frame); - f->f_lineno = _PyCode_CheckLineNumber(frame->f_lasti*sizeof(_Py_CODEUNIT), &tstate->trace_info.bounds); + int old_what = tstate->tracing_what; + tstate->tracing_what = what; + PyThreadState_EnterTracing(tstate); + assert(_PyInterpreterFrame_LASTI(frame) >= 0); + if (_PyCode_InitLineArray(frame->f_code)) { + return -1; } + f->f_lineno = _PyCode_LineNumberFromArray(frame->f_code, _PyInterpreterFrame_LASTI(frame)); result = func(obj, f, what, arg); f->f_lineno = 0; - _PyThreadState_ResumeTracing(tstate); - tstate->tracing--; + PyThreadState_LeaveTracing(tstate); + tstate->tracing_what = old_what; return result; } -PyObject * +PyObject* _PyEval_CallTracing(PyObject *func, PyObject *args) { + // Save and disable tracing PyThreadState *tstate = _PyThreadState_GET(); int save_tracing = tstate->tracing; int save_use_tracing = tstate->cframe->use_tracing; - PyObject *result; - tstate->tracing = 0; - _PyThreadState_ResumeTracing(tstate); - result = PyObject_Call(func, args, NULL); + + // Call the tracing function + PyObject *result = PyObject_Call(func, args, NULL); + + // Restore tracing tstate->tracing = save_tracing; tstate->cframe->use_tracing = save_use_tracing; return result; @@ -6226,7 +2174,7 @@ _PyEval_CallTracing(PyObject *func, PyObject *args) /* See Objects/lnotab_notes.txt for a description of how tracing works. */ static int maybe_call_line_trace(Py_tracefunc func, PyObject *obj, - PyThreadState *tstate, InterpreterFrame *frame, int instr_prev) + PyThreadState *tstate, _PyInterpreterFrame *frame, int instr_prev) { int result = 0; @@ -6234,21 +2182,34 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj, represents a jump backwards, update the frame's line number and then call the trace function if we're tracing source lines. */ - initialize_trace_info(&tstate->trace_info, frame); - int lastline = _PyCode_CheckLineNumber(instr_prev*sizeof(_Py_CODEUNIT), &tstate->trace_info.bounds); - int line = _PyCode_CheckLineNumber(frame->f_lasti*sizeof(_Py_CODEUNIT), &tstate->trace_info.bounds); + if (_PyCode_InitLineArray(frame->f_code)) { + return -1; + } + int lastline; + if (instr_prev <= frame->f_code->_co_firsttraceable) { + lastline = -1; + } + else { + lastline = _PyCode_LineNumberFromArray(frame->f_code, instr_prev); + } + int line = _PyCode_LineNumberFromArray(frame->f_code, _PyInterpreterFrame_LASTI(frame)); PyFrameObject *f = _PyFrame_GetFrameObject(frame); if (f == NULL) { return -1; } if (line != -1 && f->f_trace_lines) { - /* Trace backward edges or if line number has changed */ - if (frame->f_lasti < instr_prev || line != lastline) { + /* Trace backward edges (except in 'yield from') or if line number has changed */ + int trace = line != lastline || + (_PyInterpreterFrame_LASTI(frame) < instr_prev && + // SEND has no quickened forms, so no need to use _PyOpcode_Deopt + // here: + _Py_OPCODE(*frame->prev_instr) != SEND); + if (trace) { result = call_trace(func, obj, tstate, frame, PyTrace_LINE, Py_None); } } /* Always emit an opcode event if we're tracing all opcodes. */ - if (f->f_trace_opcodes) { + if (f->f_trace_opcodes && result == 0) { result = call_trace(func, obj, tstate, frame, PyTrace_OPCODE, Py_None); } return result; @@ -6268,20 +2229,16 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) return -1; } - PyObject *profileobj = tstate->c_profileobj; - - tstate->c_profilefunc = NULL; - tstate->c_profileobj = NULL; - /* Must make sure that tracing is not ignored if 'profileobj' is freed */ - _PyThreadState_ResumeTracing(tstate); - Py_XDECREF(profileobj); - - Py_XINCREF(arg); - tstate->c_profileobj = arg; tstate->c_profilefunc = func; - + PyObject *old_profileobj = tstate->c_profileobj; + tstate->c_profileobj = Py_XNewRef(arg); /* Flag that tracing or profiling is turned on */ - _PyThreadState_ResumeTracing(tstate); + _PyThreadState_UpdateTracingState(tstate); + + // gh-98257: Only call Py_XDECREF() once the new profile function is fully + // set, so it's safe to call sys.setprofile() again (reentrant call). + Py_XDECREF(old_profileobj); + return 0; } @@ -6295,6 +2252,27 @@ PyEval_SetProfile(Py_tracefunc func, PyObject *arg) } } +void +PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *arg) +{ + PyThreadState *this_tstate = _PyThreadState_GET(); + PyInterpreterState* interp = this_tstate->interp; + + _PyRuntimeState *runtime = &_PyRuntime; + HEAD_LOCK(runtime); + PyThreadState* ts = PyInterpreterState_ThreadHead(interp); + HEAD_UNLOCK(runtime); + + while (ts) { + if (_PyEval_SetProfile(ts, func, arg) < 0) { + _PyErr_WriteUnraisableMsg("in PyEval_SetProfileAllThreads", NULL); + } + HEAD_LOCK(runtime); + ts = PyThreadState_Next(ts); + HEAD_UNLOCK(runtime); + } +} + int _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) { @@ -6309,20 +2287,15 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) return -1; } - PyObject *traceobj = tstate->c_traceobj; - - tstate->c_tracefunc = NULL; - tstate->c_traceobj = NULL; - /* Must make sure that profiling is not ignored if 'traceobj' is freed */ - _PyThreadState_ResumeTracing(tstate); - Py_XDECREF(traceobj); - - Py_XINCREF(arg); - tstate->c_traceobj = arg; tstate->c_tracefunc = func; - + PyObject *old_traceobj = tstate->c_traceobj; + tstate->c_traceobj = Py_XNewRef(arg); /* Flag that tracing or profiling is turned on */ - _PyThreadState_ResumeTracing(tstate); + _PyThreadState_UpdateTracingState(tstate); + + // gh-98257: Only call Py_XDECREF() once the new trace function is fully + // set, so it's safe to call sys.settrace() again (reentrant call). + Py_XDECREF(old_traceobj); return 0; } @@ -6337,14 +2310,40 @@ PyEval_SetTrace(Py_tracefunc func, PyObject *arg) } } - void -_PyEval_SetCoroutineOriginTrackingDepth(PyThreadState *tstate, int new_depth) +PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *arg) { - assert(new_depth >= 0); - tstate->coroutine_origin_tracking_depth = new_depth; + PyThreadState *this_tstate = _PyThreadState_GET(); + PyInterpreterState* interp = this_tstate->interp; + + _PyRuntimeState *runtime = &_PyRuntime; + HEAD_LOCK(runtime); + PyThreadState* ts = PyInterpreterState_ThreadHead(interp); + HEAD_UNLOCK(runtime); + + while (ts) { + if (_PyEval_SetTrace(ts, func, arg) < 0) { + _PyErr_WriteUnraisableMsg("in PyEval_SetTraceAllThreads", NULL); + } + HEAD_LOCK(runtime); + ts = PyThreadState_Next(ts); + HEAD_UNLOCK(runtime); + } } +int +_PyEval_SetCoroutineOriginTrackingDepth(int depth) +{ + PyThreadState *tstate = _PyThreadState_GET(); + if (depth < 0) { + _PyErr_SetString(tstate, PyExc_ValueError, "depth must be >= 0"); + return -1; + } + tstate->coroutine_origin_tracking_depth = depth; + return 0; +} + + int _PyEval_GetCoroutineOriginTrackingDepth(void) { @@ -6361,8 +2360,7 @@ _PyEval_SetAsyncGenFirstiter(PyObject *firstiter) return -1; } - Py_XINCREF(firstiter); - Py_XSETREF(tstate->async_gen_firstiter, firstiter); + Py_XSETREF(tstate->async_gen_firstiter, Py_XNewRef(firstiter)); return 0; } @@ -6382,8 +2380,7 @@ _PyEval_SetAsyncGenFinalizer(PyObject *finalizer) return -1; } - Py_XINCREF(finalizer); - Py_XSETREF(tstate->async_gen_finalizer, finalizer); + Py_XSETREF(tstate->async_gen_finalizer, Py_XNewRef(finalizer)); return 0; } @@ -6394,21 +2391,21 @@ _PyEval_GetAsyncGenFinalizer(void) return tstate->async_gen_finalizer; } -InterpreterFrame * +_PyInterpreterFrame * _PyEval_GetFrame(void) { PyThreadState *tstate = _PyThreadState_GET(); - return tstate->cframe->current_frame; + return _PyThreadState_GetFrame(tstate); } PyFrameObject * PyEval_GetFrame(void) { - PyThreadState *tstate = _PyThreadState_GET(); - if (tstate->cframe->current_frame == NULL) { + _PyInterpreterFrame *frame = _PyEval_GetFrame(); + if (frame == NULL) { return NULL; } - PyFrameObject *f = _PyFrame_GetFrameObject(tstate->cframe->current_frame); + PyFrameObject *f = _PyFrame_GetFrameObject(frame); if (f == NULL) { PyErr_Clear(); } @@ -6418,7 +2415,7 @@ PyEval_GetFrame(void) PyObject * _PyEval_GetBuiltins(PyThreadState *tstate) { - InterpreterFrame *frame = tstate->cframe->current_frame; + _PyInterpreterFrame *frame = _PyThreadState_GetFrame(tstate); if (frame != NULL) { return frame->f_builtins; } @@ -6434,24 +2431,30 @@ PyEval_GetBuiltins(void) /* Convenience function to get a builtin from its name */ PyObject * -_PyEval_GetBuiltinId(_Py_Identifier *name) +_PyEval_GetBuiltin(PyObject *name) { PyThreadState *tstate = _PyThreadState_GET(); - PyObject *attr = _PyDict_GetItemIdWithError(PyEval_GetBuiltins(), name); + PyObject *attr = PyDict_GetItemWithError(PyEval_GetBuiltins(), name); if (attr) { Py_INCREF(attr); } else if (!_PyErr_Occurred(tstate)) { - _PyErr_SetObject(tstate, PyExc_AttributeError, _PyUnicode_FromId(name)); + _PyErr_SetObject(tstate, PyExc_AttributeError, name); } return attr; } +PyObject * +_PyEval_GetBuiltinId(_Py_Identifier *name) +{ + return _PyEval_GetBuiltin(_PyUnicode_FromId(name)); +} + PyObject * PyEval_GetLocals(void) { PyThreadState *tstate = _PyThreadState_GET(); - InterpreterFrame *current_frame = tstate->cframe->current_frame; + _PyInterpreterFrame *current_frame = _PyThreadState_GetFrame(tstate); if (current_frame == NULL) { _PyErr_SetString(tstate, PyExc_SystemError, "frame does not exist"); return NULL; @@ -6470,7 +2473,7 @@ PyObject * PyEval_GetGlobals(void) { PyThreadState *tstate = _PyThreadState_GET(); - InterpreterFrame *current_frame = tstate->cframe->current_frame; + _PyInterpreterFrame *current_frame = _PyThreadState_GetFrame(tstate); if (current_frame == NULL) { return NULL; } @@ -6481,7 +2484,7 @@ int PyEval_MergeCompilerFlags(PyCompilerFlags *cf) { PyThreadState *tstate = _PyThreadState_GET(); - InterpreterFrame *current_frame = tstate->cframe->current_frame; + _PyInterpreterFrame *current_frame = tstate->cframe->current_frame; int result = cf->cf_flags != 0; if (current_frame != NULL) { @@ -6491,12 +2494,6 @@ PyEval_MergeCompilerFlags(PyCompilerFlags *cf) result = 1; cf->cf_flags |= compilerflags; } -#if 0 /* future keyword */ - if (codeflags & CO_GENERATOR_ALLOWED) { - result = 1; - cf->cf_flags |= CO_GENERATOR_ALLOWED; - } -#endif } return result; } @@ -6603,7 +2600,6 @@ do_call_core(PyThreadState *tstate, ) { PyObject *result; - if (PyCFunction_CheckExact(func) || PyCMethod_CheckExact(func)) { C_TRACE(result, PyObject_Call(func, callargs, kwdict)); return result; @@ -6633,6 +2629,7 @@ do_call_core(PyThreadState *tstate, return result; } } + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_FUNCTION_EX, func); return PyObject_Call(func, callargs, kwdict); } @@ -6685,14 +2682,13 @@ _PyEval_SliceIndexNotNone(PyObject *v, Py_ssize_t *pi) } static PyObject * -import_name(PyThreadState *tstate, InterpreterFrame *frame, +import_name(PyThreadState *tstate, _PyInterpreterFrame *frame, PyObject *name, PyObject *fromlist, PyObject *level) { - _Py_IDENTIFIER(__import__); PyObject *import_func, *res; PyObject* stack[5]; - import_func = _PyDict_GetItemIdWithError(frame->f_builtins, &PyId___import__); + import_func = _PyDict_GetItemWithError(frame->f_builtins, &_Py_ID(__import__)); if (import_func == NULL) { if (!_PyErr_Occurred(tstate)) { _PyErr_SetString(tstate, PyExc_ImportError, "__import__ not found"); @@ -6739,7 +2735,7 @@ import_from(PyThreadState *tstate, PyObject *v, PyObject *name) /* Issue #17636: in case this failed because of a circular relative import, try to fallback on reading the module directly from sys.modules. */ - pkgname = _PyObject_GetAttrId(v, &PyId___name__); + pkgname = PyObject_GetAttr(v, &_Py_ID(__name__)); if (pkgname == NULL) { goto error; } @@ -6778,11 +2774,10 @@ import_from(PyThreadState *tstate, PyObject *v, PyObject *name) name, pkgname_or_unknown ); /* NULL checks for errmsg and pkgname done by PyErr_SetImportError. */ - PyErr_SetImportError(errmsg, pkgname, NULL); + _PyErr_SetImportErrorWithNameFrom(errmsg, pkgname, NULL, name); } else { - _Py_IDENTIFIER(__spec__); - PyObject *spec = _PyObject_GetAttrId(v, &PyId___spec__); + PyObject *spec = PyObject_GetAttr(v, &_Py_ID(__spec__)); const char *fmt = _PyModuleSpec_IsInitializing(spec) ? "cannot import name %R from partially initialized module %R " @@ -6792,7 +2787,7 @@ import_from(PyThreadState *tstate, PyObject *v, PyObject *name) errmsg = PyUnicode_FromFormat(fmt, name, pkgname_or_unknown, pkgpath); /* NULL checks for errmsg and pkgname done by PyErr_SetImportError. */ - PyErr_SetImportError(errmsg, pkgname, pkgpath); + _PyErr_SetImportErrorWithNameFrom(errmsg, pkgname, pkgpath, name); } Py_XDECREF(errmsg); @@ -6801,95 +2796,72 @@ import_from(PyThreadState *tstate, PyObject *v, PyObject *name) return NULL; } +#define CANNOT_CATCH_MSG "catching classes that do not inherit from "\ + "BaseException is not allowed" + +#define CANNOT_EXCEPT_STAR_EG "catching ExceptionGroup with except* "\ + "is not allowed. Use except instead." + static int -import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v) +check_except_type_valid(PyThreadState *tstate, PyObject* right) { - _Py_IDENTIFIER(__all__); - _Py_IDENTIFIER(__dict__); - PyObject *all, *dict, *name, *value; - int skip_leading_underscores = 0; - int pos, err; - - if (_PyObject_LookupAttrId(v, &PyId___all__, &all) < 0) { - return -1; /* Unexpected error */ + if (PyTuple_Check(right)) { + Py_ssize_t i, length; + length = PyTuple_GET_SIZE(right); + for (i = 0; i < length; i++) { + PyObject *exc = PyTuple_GET_ITEM(right, i); + if (!PyExceptionClass_Check(exc)) { + _PyErr_SetString(tstate, PyExc_TypeError, + CANNOT_CATCH_MSG); + return -1; + } + } } - if (all == NULL) { - if (_PyObject_LookupAttrId(v, &PyId___dict__, &dict) < 0) { + else { + if (!PyExceptionClass_Check(right)) { + _PyErr_SetString(tstate, PyExc_TypeError, + CANNOT_CATCH_MSG); return -1; } - if (dict == NULL) { - _PyErr_SetString(tstate, PyExc_ImportError, - "from-import-* object has no __dict__ and no __all__"); - return -1; - } - all = PyMapping_Keys(dict); - Py_DECREF(dict); - if (all == NULL) - return -1; - skip_leading_underscores = 1; + } + return 0; +} + +static int +check_except_star_type_valid(PyThreadState *tstate, PyObject* right) +{ + if (check_except_type_valid(tstate, right) < 0) { + return -1; } - for (pos = 0, err = 0; ; pos++) { - name = PySequence_GetItem(all, pos); - if (name == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_IndexError)) { - err = -1; + /* reject except *ExceptionGroup */ + + int is_subclass = 0; + if (PyTuple_Check(right)) { + Py_ssize_t length = PyTuple_GET_SIZE(right); + for (Py_ssize_t i = 0; i < length; i++) { + PyObject *exc = PyTuple_GET_ITEM(right, i); + is_subclass = PyObject_IsSubclass(exc, PyExc_BaseExceptionGroup); + if (is_subclass < 0) { + return -1; } - else { - _PyErr_Clear(tstate); - } - break; - } - if (!PyUnicode_Check(name)) { - PyObject *modname = _PyObject_GetAttrId(v, &PyId___name__); - if (modname == NULL) { - Py_DECREF(name); - err = -1; + if (is_subclass) { break; } - if (!PyUnicode_Check(modname)) { - _PyErr_Format(tstate, PyExc_TypeError, - "module __name__ must be a string, not %.100s", - Py_TYPE(modname)->tp_name); - } - else { - _PyErr_Format(tstate, PyExc_TypeError, - "%s in %U.%s must be str, not %.100s", - skip_leading_underscores ? "Key" : "Item", - modname, - skip_leading_underscores ? "__dict__" : "__all__", - Py_TYPE(name)->tp_name); - } - Py_DECREF(modname); - Py_DECREF(name); - err = -1; - break; } - if (skip_leading_underscores) { - if (PyUnicode_READY(name) == -1) { - Py_DECREF(name); - err = -1; - break; - } - if (PyUnicode_READ_CHAR(name, 0) == '_') { - Py_DECREF(name); - continue; - } - } - value = PyObject_GetAttr(v, name); - if (value == NULL) - err = -1; - else if (PyDict_CheckExact(locals)) - err = PyDict_SetItem(locals, name, value); - else - err = PyObject_SetItem(locals, name, value); - Py_DECREF(name); - Py_XDECREF(value); - if (err != 0) - break; } - Py_DECREF(all); - return err; + else { + is_subclass = PyObject_IsSubclass(right, PyExc_BaseExceptionGroup); + if (is_subclass < 0) { + return -1; + } + } + if (is_subclass) { + _PyErr_SetString(tstate, PyExc_TypeError, + CANNOT_EXCEPT_STAR_EG); + return -1; + } + return 0; } static int @@ -6973,14 +2945,16 @@ format_exc_check_arg(PyThreadState *tstate, PyObject *exc, if (exc == PyExc_NameError) { // Include the name in the NameError exceptions to offer suggestions later. - _Py_IDENTIFIER(name); PyObject *type, *value, *traceback; PyErr_Fetch(&type, &value, &traceback); PyErr_NormalizeException(&type, &value, &traceback); if (PyErr_GivenExceptionMatches(value, PyExc_NameError)) { - // We do not care if this fails because we are going to restore the - // NameError anyway. - (void)_PyObject_SetAttrId(value, &PyId_name, obj); + PyNameErrorObject* exc = (PyNameErrorObject*) value; + if (exc->name == NULL) { + // We do not care if this fails because we are going to restore the + // NameError anyway. + (void)PyObject_SetAttr(value, &_Py_ID(name), obj); + } } PyErr_Restore(type, value, traceback); } @@ -6994,7 +2968,7 @@ format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg) if (_PyErr_Occurred(tstate)) return; name = PyTuple_GET_ITEM(co->co_localsplusnames, oparg); - if (oparg < co->co_nplaincellvars + co->co_nlocals) { + if (oparg < PyCode_GetFirstFree(co)) { format_exc_check_arg(tstate, PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, name); } else { @@ -7004,16 +2978,16 @@ format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg) } static void -format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int prevprevopcode, int prevopcode) +format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int oparg) { if (type->tp_as_async == NULL || type->tp_as_async->am_await == NULL) { - if (prevopcode == BEFORE_ASYNC_WITH) { + if (oparg == 1) { _PyErr_Format(tstate, PyExc_TypeError, "'async with' received an object from __aenter__ " "that does not implement __await__: %.100s", type->tp_name); } - else if (prevopcode == WITH_EXCEPT_START || (prevopcode == CALL_FUNCTION && prevprevopcode == DUP_TOP)) { + else if (oparg == 2) { _PyErr_Format(tstate, PyExc_TypeError, "'async with' received an object from __aexit__ " "that does not implement __await__: %.100s", @@ -7022,49 +2996,6 @@ format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int prevprevop } } -#ifdef DYNAMIC_EXECUTION_PROFILE - -static PyObject * -getarray(long a[256]) -{ - int i; - PyObject *l = PyList_New(256); - if (l == NULL) return NULL; - for (i = 0; i < 256; i++) { - PyObject *x = PyLong_FromLong(a[i]); - if (x == NULL) { - Py_DECREF(l); - return NULL; - } - PyList_SET_ITEM(l, i, x); - } - for (i = 0; i < 256; i++) - a[i] = 0; - return l; -} - -PyObject * -_Py_GetDXProfile(PyObject *self, PyObject *args) -{ -#ifndef DXPAIRS - return getarray(dxp); -#else - int i; - PyObject *l = PyList_New(257); - if (l == NULL) return NULL; - for (i = 0; i < 257; i++) { - PyObject *x = getarray(dxpairs[i]); - if (x == NULL) { - Py_DECREF(l); - return NULL; - } - PyList_SET_ITEM(l, i, x); - } - return l; -#endif -} - -#endif Py_ssize_t _PyEval_RequestCodeExtraIndex(freefunc free) @@ -7081,7 +3012,7 @@ _PyEval_RequestCodeExtraIndex(freefunc free) } static void -dtrace_function_entry(InterpreterFrame *frame) +dtrace_function_entry(_PyInterpreterFrame *frame) { const char *filename; const char *funcname; @@ -7090,13 +3021,13 @@ dtrace_function_entry(InterpreterFrame *frame) PyCodeObject *code = frame->f_code; filename = PyUnicode_AsUTF8(code->co_filename); funcname = PyUnicode_AsUTF8(code->co_name); - lineno = PyCode_Addr2Line(frame->f_code, frame->f_lasti*sizeof(_Py_CODEUNIT)); + lineno = _PyInterpreterFrame_GetLine(frame); PyDTrace_FUNCTION_ENTRY(filename, funcname, lineno); } static void -dtrace_function_return(InterpreterFrame *frame) +dtrace_function_return(_PyInterpreterFrame *frame) { const char *filename; const char *funcname; @@ -7105,14 +3036,14 @@ dtrace_function_return(InterpreterFrame *frame) PyCodeObject *code = frame->f_code; filename = PyUnicode_AsUTF8(code->co_filename); funcname = PyUnicode_AsUTF8(code->co_name); - lineno = PyCode_Addr2Line(frame->f_code, frame->f_lasti*sizeof(_Py_CODEUNIT)); + lineno = _PyInterpreterFrame_GetLine(frame); PyDTrace_FUNCTION_RETURN(filename, funcname, lineno); } /* DTrace equivalent of maybe_call_line_trace. */ static void -maybe_dtrace_line(InterpreterFrame *frame, +maybe_dtrace_line(_PyInterpreterFrame *frame, PyTraceInfo *trace_info, int instr_prev) { @@ -7123,11 +3054,12 @@ maybe_dtrace_line(InterpreterFrame *frame, */ initialize_trace_info(trace_info, frame); int lastline = _PyCode_CheckLineNumber(instr_prev*sizeof(_Py_CODEUNIT), &trace_info->bounds); - int line = _PyCode_CheckLineNumber(frame->f_lasti*sizeof(_Py_CODEUNIT), &trace_info->bounds); + int addr = _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT); + int line = _PyCode_CheckLineNumber(addr, &trace_info->bounds); if (line != -1) { /* Trace backward edges or first instruction of a new line */ - if (frame->f_lasti < instr_prev || - (line != lastline && frame->f_lasti*sizeof(_Py_CODEUNIT) == (unsigned int)trace_info->bounds.ar_start)) + if (_PyInterpreterFrame_LASTI(frame) < instr_prev || + (line != lastline && addr == trace_info->bounds.ar_start)) { co_filename = PyUnicode_AsUTF8(frame->f_code->co_filename); if (!co_filename) { @@ -7149,12 +3081,12 @@ maybe_dtrace_line(InterpreterFrame *frame, int Py_EnterRecursiveCall(const char *where) { - return _Py_EnterRecursiveCall_inline(where); + return _Py_EnterRecursiveCall(where); } #undef Py_LeaveRecursiveCall void Py_LeaveRecursiveCall(void) { - _Py_LeaveRecursiveCall_inline(); + _Py_LeaveRecursiveCall(); } diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c new file mode 100644 index 00000000000..73d412ba4d7 --- /dev/null +++ b/Python/ceval_gil.c @@ -0,0 +1,1004 @@ + +#include "Python.h" +#include "pycore_atomic.h" // _Py_atomic_int +#include "pycore_ceval.h" // _PyEval_SignalReceived() +#include "pycore_pyerrors.h" // _PyErr_Fetch() +#include "pycore_pylifecycle.h" // _PyErr_Print() +#include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_interp.h" // _Py_RunGC() +#include "pycore_pymem.h" // _PyMem_IsPtrFreed() + +/* + Notes about the implementation: + + - The GIL is just a boolean variable (locked) whose access is protected + by a mutex (gil_mutex), and whose changes are signalled by a condition + variable (gil_cond). gil_mutex is taken for short periods of time, + and therefore mostly uncontended. + + - In the GIL-holding thread, the main loop (PyEval_EvalFrameEx) must be + able to release the GIL on demand by another thread. A volatile boolean + variable (gil_drop_request) is used for that purpose, which is checked + at every turn of the eval loop. That variable is set after a wait of + `interval` microseconds on `gil_cond` has timed out. + + [Actually, another volatile boolean variable (eval_breaker) is used + which ORs several conditions into one. Volatile booleans are + sufficient as inter-thread signalling means since Python is run + on cache-coherent architectures only.] + + - A thread wanting to take the GIL will first let pass a given amount of + time (`interval` microseconds) before setting gil_drop_request. This + encourages a defined switching period, but doesn't enforce it since + opcodes can take an arbitrary time to execute. + + The `interval` value is available for the user to read and modify + using the Python API `sys.{get,set}switchinterval()`. + + - When a thread releases the GIL and gil_drop_request is set, that thread + ensures that another GIL-awaiting thread gets scheduled. + It does so by waiting on a condition variable (switch_cond) until + the value of last_holder is changed to something else than its + own thread state pointer, indicating that another thread was able to + take the GIL. + + This is meant to prohibit the latency-adverse behaviour on multi-core + machines where one thread would speculatively release the GIL, but still + run and end up being the first to re-acquire it, making the "timeslices" + much longer than expected. + (Note: this mechanism is enabled with FORCE_SWITCHING above) +*/ + +// GH-89279: Force inlining by using a macro. +#if defined(_MSC_VER) && SIZEOF_INT == 4 +#define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) (assert(sizeof((ATOMIC_VAL)->_value) == 4), *((volatile int*)&((ATOMIC_VAL)->_value))) +#else +#define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) _Py_atomic_load_relaxed(ATOMIC_VAL) +#endif + +/* This can set eval_breaker to 0 even though gil_drop_request became + 1. We believe this is all right because the eval loop will release + the GIL eventually anyway. */ +static inline void +COMPUTE_EVAL_BREAKER(PyInterpreterState *interp, + struct _ceval_runtime_state *ceval, + struct _ceval_state *ceval2) +{ + _Py_atomic_store_relaxed(&ceval2->eval_breaker, + _Py_atomic_load_relaxed_int32(&ceval2->gil_drop_request) + | (_Py_atomic_load_relaxed_int32(&ceval->signals_pending) + && _Py_ThreadCanHandleSignals(interp)) + | (_Py_atomic_load_relaxed_int32(&ceval2->pending.calls_to_do) + && _Py_ThreadCanHandlePendingCalls()) + | ceval2->pending.async_exc + | _Py_atomic_load_relaxed_int32(&ceval2->gc_scheduled)); +} + + +static inline void +SET_GIL_DROP_REQUEST(PyInterpreterState *interp) +{ + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 1); + _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); +} + + +static inline void +RESET_GIL_DROP_REQUEST(PyInterpreterState *interp) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 0); + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); +} + + +static inline void +SIGNAL_PENDING_CALLS(PyInterpreterState *interp) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&ceval2->pending.calls_to_do, 1); + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); +} + + +static inline void +UNSIGNAL_PENDING_CALLS(PyInterpreterState *interp) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&ceval2->pending.calls_to_do, 0); + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); +} + + +static inline void +SIGNAL_PENDING_SIGNALS(PyInterpreterState *interp, int force) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&ceval->signals_pending, 1); + if (force) { + _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); + } + else { + /* eval_breaker is not set to 1 if thread_can_handle_signals() is false */ + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); + } +} + + +static inline void +UNSIGNAL_PENDING_SIGNALS(PyInterpreterState *interp) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&ceval->signals_pending, 0); + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); +} + + +static inline void +SIGNAL_ASYNC_EXC(PyInterpreterState *interp) +{ + struct _ceval_state *ceval2 = &interp->ceval; + ceval2->pending.async_exc = 1; + _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); +} + + +static inline void +UNSIGNAL_ASYNC_EXC(PyInterpreterState *interp) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + ceval2->pending.async_exc = 0; + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); +} + +#ifndef NDEBUG +/* Ensure that tstate is valid */ +static int +is_tstate_valid(PyThreadState *tstate) +{ + assert(!_PyMem_IsPtrFreed(tstate)); + assert(!_PyMem_IsPtrFreed(tstate->interp)); + return 1; +} +#endif + +/* + * Implementation of the Global Interpreter Lock (GIL). + */ + +#include +#include + +#include "pycore_atomic.h" + + +#include "condvar.h" + +#define MUTEX_INIT(mut) \ + if (PyMUTEX_INIT(&(mut))) { \ + Py_FatalError("PyMUTEX_INIT(" #mut ") failed"); }; +#define MUTEX_FINI(mut) \ + if (PyMUTEX_FINI(&(mut))) { \ + Py_FatalError("PyMUTEX_FINI(" #mut ") failed"); }; +#define MUTEX_LOCK(mut) \ + if (PyMUTEX_LOCK(&(mut))) { \ + Py_FatalError("PyMUTEX_LOCK(" #mut ") failed"); }; +#define MUTEX_UNLOCK(mut) \ + if (PyMUTEX_UNLOCK(&(mut))) { \ + Py_FatalError("PyMUTEX_UNLOCK(" #mut ") failed"); }; + +#define COND_INIT(cond) \ + if (PyCOND_INIT(&(cond))) { \ + Py_FatalError("PyCOND_INIT(" #cond ") failed"); }; +#define COND_FINI(cond) \ + if (PyCOND_FINI(&(cond))) { \ + Py_FatalError("PyCOND_FINI(" #cond ") failed"); }; +#define COND_SIGNAL(cond) \ + if (PyCOND_SIGNAL(&(cond))) { \ + Py_FatalError("PyCOND_SIGNAL(" #cond ") failed"); }; +#define COND_WAIT(cond, mut) \ + if (PyCOND_WAIT(&(cond), &(mut))) { \ + Py_FatalError("PyCOND_WAIT(" #cond ") failed"); }; +#define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \ + { \ + int r = PyCOND_TIMEDWAIT(&(cond), &(mut), (microseconds)); \ + if (r < 0) \ + Py_FatalError("PyCOND_WAIT(" #cond ") failed"); \ + if (r) /* 1 == timeout, 2 == impl. can't say, so assume timeout */ \ + timeout_result = 1; \ + else \ + timeout_result = 0; \ + } \ + + +#define DEFAULT_INTERVAL 5000 + +static void _gil_initialize(struct _gil_runtime_state *gil) +{ + _Py_atomic_int uninitialized = {-1}; + gil->locked = uninitialized; + gil->interval = DEFAULT_INTERVAL; +} + +static int gil_created(struct _gil_runtime_state *gil) +{ + return (_Py_atomic_load_explicit(&gil->locked, _Py_memory_order_acquire) >= 0); +} + +static void create_gil(struct _gil_runtime_state *gil) +{ + MUTEX_INIT(gil->mutex); +#ifdef FORCE_SWITCHING + MUTEX_INIT(gil->switch_mutex); +#endif + COND_INIT(gil->cond); +#ifdef FORCE_SWITCHING + COND_INIT(gil->switch_cond); +#endif + _Py_atomic_store_relaxed(&gil->last_holder, 0); + _Py_ANNOTATE_RWLOCK_CREATE(&gil->locked); + _Py_atomic_store_explicit(&gil->locked, 0, _Py_memory_order_release); +} + +static void destroy_gil(struct _gil_runtime_state *gil) +{ + /* some pthread-like implementations tie the mutex to the cond + * and must have the cond destroyed first. + */ + COND_FINI(gil->cond); + MUTEX_FINI(gil->mutex); +#ifdef FORCE_SWITCHING + COND_FINI(gil->switch_cond); + MUTEX_FINI(gil->switch_mutex); +#endif + _Py_atomic_store_explicit(&gil->locked, -1, + _Py_memory_order_release); + _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); +} + +#ifdef HAVE_FORK +static void recreate_gil(struct _gil_runtime_state *gil) +{ + _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); + /* XXX should we destroy the old OS resources here? */ + create_gil(gil); +} +#endif + +static void +drop_gil(struct _ceval_runtime_state *ceval, struct _ceval_state *ceval2, + PyThreadState *tstate) +{ + struct _gil_runtime_state *gil = &ceval->gil; + if (!_Py_atomic_load_relaxed(&gil->locked)) { + Py_FatalError("drop_gil: GIL is not locked"); + } + + /* tstate is allowed to be NULL (early interpreter init) */ + if (tstate != NULL) { + /* Sub-interpreter support: threads might have been switched + under our feet using PyThreadState_Swap(). Fix the GIL last + holder variable so that our heuristics work. */ + _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); + } + + MUTEX_LOCK(gil->mutex); + _Py_ANNOTATE_RWLOCK_RELEASED(&gil->locked, /*is_write=*/1); + _Py_atomic_store_relaxed(&gil->locked, 0); + COND_SIGNAL(gil->cond); + MUTEX_UNLOCK(gil->mutex); + +#ifdef FORCE_SWITCHING + if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request) && tstate != NULL) { + MUTEX_LOCK(gil->switch_mutex); + /* Not switched yet => wait */ + if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) == tstate) + { + assert(is_tstate_valid(tstate)); + RESET_GIL_DROP_REQUEST(tstate->interp); + /* NOTE: if COND_WAIT does not atomically start waiting when + releasing the mutex, another thread can run through, take + the GIL and drop it again, and reset the condition + before we even had a chance to wait for it. */ + COND_WAIT(gil->switch_cond, gil->switch_mutex); + } + MUTEX_UNLOCK(gil->switch_mutex); + } +#endif +} + + +/* Check if a Python thread must exit immediately, rather than taking the GIL + if Py_Finalize() has been called. + + When this function is called by a daemon thread after Py_Finalize() has been + called, the GIL does no longer exist. + + tstate must be non-NULL. */ +static inline int +tstate_must_exit(PyThreadState *tstate) +{ + /* bpo-39877: Access _PyRuntime directly rather than using + tstate->interp->runtime to support calls from Python daemon threads. + After Py_Finalize() has been called, tstate can be a dangling pointer: + point to PyThreadState freed memory. */ + PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(&_PyRuntime); + return (finalizing != NULL && finalizing != tstate); +} + + +/* Take the GIL. + + The function saves errno at entry and restores its value at exit. + + tstate must be non-NULL. */ +static void +take_gil(PyThreadState *tstate) +{ + int err = errno; + + assert(tstate != NULL); + + if (tstate_must_exit(tstate)) { + /* bpo-39877: If Py_Finalize() has been called and tstate is not the + thread which called Py_Finalize(), exit immediately the thread. + + This code path can be reached by a daemon thread after Py_Finalize() + completes. In this case, tstate is a dangling pointer: points to + PyThreadState freed memory. */ + PyThread_exit_thread(); + } + + assert(is_tstate_valid(tstate)); + PyInterpreterState *interp = tstate->interp; + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + struct _gil_runtime_state *gil = &ceval->gil; + + /* Check that _PyEval_InitThreads() was called to create the lock */ + assert(gil_created(gil)); + + MUTEX_LOCK(gil->mutex); + + if (!_Py_atomic_load_relaxed(&gil->locked)) { + goto _ready; + } + + int drop_requested = 0; + while (_Py_atomic_load_relaxed(&gil->locked)) { + unsigned long saved_switchnum = gil->switch_number; + + unsigned long interval = (gil->interval >= 1 ? gil->interval : 1); + int timed_out = 0; + COND_TIMED_WAIT(gil->cond, gil->mutex, interval, timed_out); + + /* If we timed out and no switch occurred in the meantime, it is time + to ask the GIL-holding thread to drop it. */ + if (timed_out && + _Py_atomic_load_relaxed(&gil->locked) && + gil->switch_number == saved_switchnum) + { + if (tstate_must_exit(tstate)) { + MUTEX_UNLOCK(gil->mutex); + // gh-96387: If the loop requested a drop request in a previous + // iteration, reset the request. Otherwise, drop_gil() can + // block forever waiting for the thread which exited. Drop + // requests made by other threads are also reset: these threads + // may have to request again a drop request (iterate one more + // time). + if (drop_requested) { + RESET_GIL_DROP_REQUEST(interp); + } + PyThread_exit_thread(); + } + assert(is_tstate_valid(tstate)); + + SET_GIL_DROP_REQUEST(interp); + drop_requested = 1; + } + } + +_ready: +#ifdef FORCE_SWITCHING + /* This mutex must be taken before modifying gil->last_holder: + see drop_gil(). */ + MUTEX_LOCK(gil->switch_mutex); +#endif + /* We now hold the GIL */ + _Py_atomic_store_relaxed(&gil->locked, 1); + _Py_ANNOTATE_RWLOCK_ACQUIRED(&gil->locked, /*is_write=*/1); + + if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) { + _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); + ++gil->switch_number; + } + +#ifdef FORCE_SWITCHING + COND_SIGNAL(gil->switch_cond); + MUTEX_UNLOCK(gil->switch_mutex); +#endif + + if (tstate_must_exit(tstate)) { + /* bpo-36475: If Py_Finalize() has been called and tstate is not + the thread which called Py_Finalize(), exit immediately the + thread. + + This code path can be reached by a daemon thread which was waiting + in take_gil() while the main thread called + wait_for_thread_shutdown() from Py_Finalize(). */ + MUTEX_UNLOCK(gil->mutex); + drop_gil(ceval, ceval2, tstate); + PyThread_exit_thread(); + } + assert(is_tstate_valid(tstate)); + + if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request)) { + RESET_GIL_DROP_REQUEST(interp); + } + else { + /* bpo-40010: eval_breaker should be recomputed to be set to 1 if there + is a pending signal: signal received by another thread which cannot + handle signals. + + Note: RESET_GIL_DROP_REQUEST() calls COMPUTE_EVAL_BREAKER(). */ + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); + } + + /* Don't access tstate if the thread must exit */ + if (tstate->async_exc != NULL) { + _PyEval_SignalAsyncExc(tstate->interp); + } + + MUTEX_UNLOCK(gil->mutex); + + errno = err; +} + +void _PyEval_SetSwitchInterval(unsigned long microseconds) +{ + struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil; + gil->interval = microseconds; +} + +unsigned long _PyEval_GetSwitchInterval() +{ + struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil; + return gil->interval; +} + + +int +_PyEval_ThreadsInitialized(_PyRuntimeState *runtime) +{ + return gil_created(&runtime->ceval.gil); +} + +int +PyEval_ThreadsInitialized(void) +{ + _PyRuntimeState *runtime = &_PyRuntime; + return _PyEval_ThreadsInitialized(runtime); +} + +PyStatus +_PyEval_InitGIL(PyThreadState *tstate) +{ + if (!_Py_IsMainInterpreter(tstate->interp)) { + /* Currently, the GIL is shared by all interpreters, + and only the main interpreter is responsible to create + and destroy it. */ + return _PyStatus_OK(); + } + + struct _gil_runtime_state *gil = &tstate->interp->runtime->ceval.gil; + assert(!gil_created(gil)); + + PyThread_init_thread(); + create_gil(gil); + + take_gil(tstate); + + assert(gil_created(gil)); + return _PyStatus_OK(); +} + +void +_PyEval_FiniGIL(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + /* Currently, the GIL is shared by all interpreters, + and only the main interpreter is responsible to create + and destroy it. */ + return; + } + + struct _gil_runtime_state *gil = &interp->runtime->ceval.gil; + if (!gil_created(gil)) { + /* First Py_InitializeFromConfig() call: the GIL doesn't exist + yet: do nothing. */ + return; + } + + destroy_gil(gil); + assert(!gil_created(gil)); +} + +void +PyEval_InitThreads(void) +{ + /* Do nothing: kept for backward compatibility */ +} + +void +_PyEval_Fini(void) +{ +#ifdef Py_STATS + _Py_PrintSpecializationStats(1); +#endif +} +void +PyEval_AcquireLock(void) +{ + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + _Py_EnsureTstateNotNULL(tstate); + + take_gil(tstate); +} + +void +PyEval_ReleaseLock(void) +{ + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + /* This function must succeed when the current thread state is NULL. + We therefore avoid PyThreadState_Get() which dumps a fatal error + in debug mode. */ + struct _ceval_runtime_state *ceval = &runtime->ceval; + struct _ceval_state *ceval2 = &tstate->interp->ceval; + drop_gil(ceval, ceval2, tstate); +} + +void +_PyEval_ReleaseLock(PyThreadState *tstate) +{ + struct _ceval_runtime_state *ceval = &tstate->interp->runtime->ceval; + struct _ceval_state *ceval2 = &tstate->interp->ceval; + drop_gil(ceval, ceval2, tstate); +} + +void +PyEval_AcquireThread(PyThreadState *tstate) +{ + _Py_EnsureTstateNotNULL(tstate); + + take_gil(tstate); + + if (_PyThreadState_Swap(tstate->interp->runtime, tstate) != NULL) { + Py_FatalError("non-NULL old thread state"); + } +} + +void +PyEval_ReleaseThread(PyThreadState *tstate) +{ + assert(is_tstate_valid(tstate)); + + _PyRuntimeState *runtime = tstate->interp->runtime; + PyThreadState *new_tstate = _PyThreadState_Swap(runtime, NULL); + if (new_tstate != tstate) { + Py_FatalError("wrong thread state"); + } + struct _ceval_runtime_state *ceval = &runtime->ceval; + struct _ceval_state *ceval2 = &tstate->interp->ceval; + drop_gil(ceval, ceval2, tstate); +} + +#ifdef HAVE_FORK +/* This function is called from PyOS_AfterFork_Child to destroy all threads + which are not running in the child process, and clear internal locks + which might be held by those threads. */ +PyStatus +_PyEval_ReInitThreads(PyThreadState *tstate) +{ + _PyRuntimeState *runtime = tstate->interp->runtime; + + struct _gil_runtime_state *gil = &runtime->ceval.gil; + if (!gil_created(gil)) { + return _PyStatus_OK(); + } + recreate_gil(gil); + + take_gil(tstate); + + struct _pending_calls *pending = &tstate->interp->ceval.pending; + if (_PyThread_at_fork_reinit(&pending->lock) < 0) { + return _PyStatus_ERR("Can't reinitialize pending calls lock"); + } + + /* Destroy all threads except the current one */ + _PyThreadState_DeleteExcept(runtime, tstate); + return _PyStatus_OK(); +} +#endif + +/* This function is used to signal that async exceptions are waiting to be + raised. */ + +void +_PyEval_SignalAsyncExc(PyInterpreterState *interp) +{ + SIGNAL_ASYNC_EXC(interp); +} + +PyThreadState * +PyEval_SaveThread(void) +{ + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyThreadState_Swap(runtime, NULL); + _Py_EnsureTstateNotNULL(tstate); + + struct _ceval_runtime_state *ceval = &runtime->ceval; + struct _ceval_state *ceval2 = &tstate->interp->ceval; + assert(gil_created(&ceval->gil)); + drop_gil(ceval, ceval2, tstate); + return tstate; +} + +void +PyEval_RestoreThread(PyThreadState *tstate) +{ + _Py_EnsureTstateNotNULL(tstate); + + take_gil(tstate); + + _PyThreadState_Swap(tstate->interp->runtime, tstate); +} + + +/* Mechanism whereby asynchronously executing callbacks (e.g. UNIX + signal handlers or Mac I/O completion routines) can schedule calls + to a function to be called synchronously. + The synchronous function is called with one void* argument. + It should return 0 for success or -1 for failure -- failure should + be accompanied by an exception. + + If registry succeeds, the registry function returns 0; if it fails + (e.g. due to too many pending calls) it returns -1 (without setting + an exception condition). + + Note that because registry may occur from within signal handlers, + or other asynchronous events, calling malloc() is unsafe! + + Any thread can schedule pending calls, but only the main thread + will execute them. + There is no facility to schedule calls to a particular thread, but + that should be easy to change, should that ever be required. In + that case, the static variables here should go into the python + threadstate. +*/ + +void +_PyEval_SignalReceived(PyInterpreterState *interp) +{ +#ifdef MS_WINDOWS + // bpo-42296: On Windows, _PyEval_SignalReceived() is called from a signal + // handler which can run in a thread different than the Python thread, in + // which case _Py_ThreadCanHandleSignals() is wrong. Ignore + // _Py_ThreadCanHandleSignals() and always set eval_breaker to 1. + // + // The next eval_frame_handle_pending() call will call + // _Py_ThreadCanHandleSignals() to recompute eval_breaker. + int force = 1; +#else + int force = 0; +#endif + /* bpo-30703: Function called when the C signal handler of Python gets a + signal. We cannot queue a callback using _PyEval_AddPendingCall() since + that function is not async-signal-safe. */ + SIGNAL_PENDING_SIGNALS(interp, force); +} + +/* Push one item onto the queue while holding the lock. */ +static int +_push_pending_call(struct _pending_calls *pending, + int (*func)(void *), void *arg) +{ + int i = pending->last; + int j = (i + 1) % NPENDINGCALLS; + if (j == pending->first) { + return -1; /* Queue full */ + } + pending->calls[i].func = func; + pending->calls[i].arg = arg; + pending->last = j; + return 0; +} + +/* Pop one item off the queue while holding the lock. */ +static void +_pop_pending_call(struct _pending_calls *pending, + int (**func)(void *), void **arg) +{ + int i = pending->first; + if (i == pending->last) { + return; /* Queue empty */ + } + + *func = pending->calls[i].func; + *arg = pending->calls[i].arg; + pending->first = (i + 1) % NPENDINGCALLS; +} + +/* This implementation is thread-safe. It allows + scheduling to be made from any thread, and even from an executing + callback. + */ + +int +_PyEval_AddPendingCall(PyInterpreterState *interp, + int (*func)(void *), void *arg) +{ + struct _pending_calls *pending = &interp->ceval.pending; + /* Ensure that _PyEval_InitState() was called + and that _PyEval_FiniState() is not called yet. */ + assert(pending->lock != NULL); + + PyThread_acquire_lock(pending->lock, WAIT_LOCK); + int result = _push_pending_call(pending, func, arg); + PyThread_release_lock(pending->lock); + + /* signal main loop */ + SIGNAL_PENDING_CALLS(interp); + return result; +} + +int +Py_AddPendingCall(int (*func)(void *), void *arg) +{ + /* Best-effort to support subinterpreters and calls with the GIL released. + + First attempt _PyThreadState_GET() since it supports subinterpreters. + + If the GIL is released, _PyThreadState_GET() returns NULL . In this + case, use PyGILState_GetThisThreadState() which works even if the GIL + is released. + + Sadly, PyGILState_GetThisThreadState() doesn't support subinterpreters: + see bpo-10915 and bpo-15751. + + Py_AddPendingCall() doesn't require the caller to hold the GIL. */ + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate == NULL) { + tstate = PyGILState_GetThisThreadState(); + } + + PyInterpreterState *interp; + if (tstate != NULL) { + interp = tstate->interp; + } + else { + /* Last resort: use the main interpreter */ + interp = _PyInterpreterState_Main(); + } + return _PyEval_AddPendingCall(interp, func, arg); +} + +static int +handle_signals(PyThreadState *tstate) +{ + assert(is_tstate_valid(tstate)); + if (!_Py_ThreadCanHandleSignals(tstate->interp)) { + return 0; + } + + UNSIGNAL_PENDING_SIGNALS(tstate->interp); + if (_PyErr_CheckSignalsTstate(tstate) < 0) { + /* On failure, re-schedule a call to handle_signals(). */ + SIGNAL_PENDING_SIGNALS(tstate->interp, 0); + return -1; + } + return 0; +} + +static int +make_pending_calls(PyInterpreterState *interp) +{ + /* only execute pending calls on main thread */ + if (!_Py_ThreadCanHandlePendingCalls()) { + return 0; + } + + /* don't perform recursive pending calls */ + if (interp->ceval.pending.busy) { + return 0; + } + interp->ceval.pending.busy = 1; + + /* unsignal before starting to call callbacks, so that any callback + added in-between re-signals */ + UNSIGNAL_PENDING_CALLS(interp); + int res = 0; + + /* perform a bounded number of calls, in case of recursion */ + struct _pending_calls *pending = &interp->ceval.pending; + for (int i=0; ilock, WAIT_LOCK); + _pop_pending_call(pending, &func, &arg); + PyThread_release_lock(pending->lock); + + /* having released the lock, perform the callback */ + if (func == NULL) { + break; + } + res = func(arg); + if (res) { + goto error; + } + } + + interp->ceval.pending.busy = 0; + return res; + +error: + interp->ceval.pending.busy = 0; + SIGNAL_PENDING_CALLS(interp); + return res; +} + +void +_Py_FinishPendingCalls(PyThreadState *tstate) +{ + assert(PyGILState_Check()); + assert(is_tstate_valid(tstate)); + + struct _pending_calls *pending = &tstate->interp->ceval.pending; + + if (!_Py_atomic_load_relaxed_int32(&(pending->calls_to_do))) { + return; + } + + if (make_pending_calls(tstate->interp) < 0) { + PyObject *exc, *val, *tb; + _PyErr_Fetch(tstate, &exc, &val, &tb); + PyErr_BadInternalCall(); + _PyErr_ChainExceptions(exc, val, tb); + _PyErr_Print(tstate); + } +} + +/* Py_MakePendingCalls() is a simple wrapper for the sake + of backward-compatibility. */ +int +Py_MakePendingCalls(void) +{ + assert(PyGILState_Check()); + + PyThreadState *tstate = _PyThreadState_GET(); + assert(is_tstate_valid(tstate)); + + /* Python signal handler doesn't really queue a callback: it only signals + that a signal was received, see _PyEval_SignalReceived(). */ + int res = handle_signals(tstate); + if (res != 0) { + return res; + } + + res = make_pending_calls(tstate->interp); + if (res != 0) { + return res; + } + + return 0; +} + +/* The interpreter's recursion limit */ + +void +_PyEval_InitRuntimeState(struct _ceval_runtime_state *ceval) +{ + _gil_initialize(&ceval->gil); +} + +void +_PyEval_InitState(struct _ceval_state *ceval, PyThread_type_lock pending_lock) +{ + struct _pending_calls *pending = &ceval->pending; + assert(pending->lock == NULL); + + pending->lock = pending_lock; +} + +void +_PyEval_FiniState(struct _ceval_state *ceval) +{ + struct _pending_calls *pending = &ceval->pending; + if (pending->lock != NULL) { + PyThread_free_lock(pending->lock); + pending->lock = NULL; + } +} + +/* Handle signals, pending calls, GIL drop request + and asynchronous exception */ +int +_Py_HandlePending(PyThreadState *tstate) +{ + _PyRuntimeState * const runtime = &_PyRuntime; + struct _ceval_runtime_state *ceval = &runtime->ceval; + struct _ceval_state *interp_ceval_state = &tstate->interp->ceval; + + /* Pending signals */ + if (_Py_atomic_load_relaxed_int32(&ceval->signals_pending)) { + if (handle_signals(tstate) != 0) { + return -1; + } + } + + /* Pending calls */ + if (_Py_atomic_load_relaxed_int32(&interp_ceval_state->pending.calls_to_do)) { + if (make_pending_calls(tstate->interp) != 0) { + return -1; + } + } + + /* GC scheduled to run */ + if (_Py_atomic_load_relaxed_int32(&interp_ceval_state->gc_scheduled)) { + _Py_atomic_store_relaxed(&interp_ceval_state->gc_scheduled, 0); + COMPUTE_EVAL_BREAKER(tstate->interp, ceval, interp_ceval_state); + _Py_RunGC(tstate); + } + + /* GIL drop request */ + if (_Py_atomic_load_relaxed_int32(&interp_ceval_state->gil_drop_request)) { + /* Give another thread a chance */ + if (_PyThreadState_Swap(runtime, NULL) != tstate) { + Py_FatalError("tstate mix-up"); + } + drop_gil(ceval, interp_ceval_state, tstate); + + /* Other threads may run now */ + + take_gil(tstate); + + if (_PyThreadState_Swap(runtime, tstate) != NULL) { + Py_FatalError("orphan tstate"); + } + } + + /* Check for asynchronous exception. */ + if (tstate->async_exc != NULL) { + PyObject *exc = tstate->async_exc; + tstate->async_exc = NULL; + UNSIGNAL_ASYNC_EXC(tstate->interp); + _PyErr_SetNone(tstate, exc); + Py_DECREF(exc); + return -1; + } + + + // It is possible that some of the conditions that trigger the eval breaker + // are called in a different thread than the Python thread. An example of + // this is bpo-42296: On Windows, _PyEval_SignalReceived() can be called in + // a different thread than the Python thread, in which case + // _Py_ThreadCanHandleSignals() is wrong. Recompute eval_breaker in the + // current Python thread with the correct _Py_ThreadCanHandleSignals() + // value. It prevents to interrupt the eval loop at every instruction if + // the current Python thread cannot handle signals (if + // _Py_ThreadCanHandleSignals() is false). + COMPUTE_EVAL_BREAKER(tstate->interp, ceval, interp_ceval_state); + + return 0; +} + diff --git a/Python/ceval_gil.h b/Python/ceval_gil.h deleted file mode 100644 index 9b8b43253f0..00000000000 --- a/Python/ceval_gil.h +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Implementation of the Global Interpreter Lock (GIL). - */ - -#include -#include - -#include "pycore_atomic.h" - - -/* - Notes about the implementation: - - - The GIL is just a boolean variable (locked) whose access is protected - by a mutex (gil_mutex), and whose changes are signalled by a condition - variable (gil_cond). gil_mutex is taken for short periods of time, - and therefore mostly uncontended. - - - In the GIL-holding thread, the main loop (PyEval_EvalFrameEx) must be - able to release the GIL on demand by another thread. A volatile boolean - variable (gil_drop_request) is used for that purpose, which is checked - at every turn of the eval loop. That variable is set after a wait of - `interval` microseconds on `gil_cond` has timed out. - - [Actually, another volatile boolean variable (eval_breaker) is used - which ORs several conditions into one. Volatile booleans are - sufficient as inter-thread signalling means since Python is run - on cache-coherent architectures only.] - - - A thread wanting to take the GIL will first let pass a given amount of - time (`interval` microseconds) before setting gil_drop_request. This - encourages a defined switching period, but doesn't enforce it since - opcodes can take an arbitrary time to execute. - - The `interval` value is available for the user to read and modify - using the Python API `sys.{get,set}switchinterval()`. - - - When a thread releases the GIL and gil_drop_request is set, that thread - ensures that another GIL-awaiting thread gets scheduled. - It does so by waiting on a condition variable (switch_cond) until - the value of last_holder is changed to something else than its - own thread state pointer, indicating that another thread was able to - take the GIL. - - This is meant to prohibit the latency-adverse behaviour on multi-core - machines where one thread would speculatively release the GIL, but still - run and end up being the first to re-acquire it, making the "timeslices" - much longer than expected. - (Note: this mechanism is enabled with FORCE_SWITCHING above) -*/ - -#include "condvar.h" - -#define MUTEX_INIT(mut) \ - if (PyMUTEX_INIT(&(mut))) { \ - Py_FatalError("PyMUTEX_INIT(" #mut ") failed"); }; -#define MUTEX_FINI(mut) \ - if (PyMUTEX_FINI(&(mut))) { \ - Py_FatalError("PyMUTEX_FINI(" #mut ") failed"); }; -#define MUTEX_LOCK(mut) \ - if (PyMUTEX_LOCK(&(mut))) { \ - Py_FatalError("PyMUTEX_LOCK(" #mut ") failed"); }; -#define MUTEX_UNLOCK(mut) \ - if (PyMUTEX_UNLOCK(&(mut))) { \ - Py_FatalError("PyMUTEX_UNLOCK(" #mut ") failed"); }; - -#define COND_INIT(cond) \ - if (PyCOND_INIT(&(cond))) { \ - Py_FatalError("PyCOND_INIT(" #cond ") failed"); }; -#define COND_FINI(cond) \ - if (PyCOND_FINI(&(cond))) { \ - Py_FatalError("PyCOND_FINI(" #cond ") failed"); }; -#define COND_SIGNAL(cond) \ - if (PyCOND_SIGNAL(&(cond))) { \ - Py_FatalError("PyCOND_SIGNAL(" #cond ") failed"); }; -#define COND_WAIT(cond, mut) \ - if (PyCOND_WAIT(&(cond), &(mut))) { \ - Py_FatalError("PyCOND_WAIT(" #cond ") failed"); }; -#define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \ - { \ - int r = PyCOND_TIMEDWAIT(&(cond), &(mut), (microseconds)); \ - if (r < 0) \ - Py_FatalError("PyCOND_WAIT(" #cond ") failed"); \ - if (r) /* 1 == timeout, 2 == impl. can't say, so assume timeout */ \ - timeout_result = 1; \ - else \ - timeout_result = 0; \ - } \ - - -#define DEFAULT_INTERVAL 5000 - -static void _gil_initialize(struct _gil_runtime_state *gil) -{ - _Py_atomic_int uninitialized = {-1}; - gil->locked = uninitialized; - gil->interval = DEFAULT_INTERVAL; -} - -static int gil_created(struct _gil_runtime_state *gil) -{ - return (_Py_atomic_load_explicit(&gil->locked, _Py_memory_order_acquire) >= 0); -} - -static void create_gil(struct _gil_runtime_state *gil) -{ - MUTEX_INIT(gil->mutex); -#ifdef FORCE_SWITCHING - MUTEX_INIT(gil->switch_mutex); -#endif - COND_INIT(gil->cond); -#ifdef FORCE_SWITCHING - COND_INIT(gil->switch_cond); -#endif - _Py_atomic_store_relaxed(&gil->last_holder, 0); - _Py_ANNOTATE_RWLOCK_CREATE(&gil->locked); - _Py_atomic_store_explicit(&gil->locked, 0, _Py_memory_order_release); -} - -static void destroy_gil(struct _gil_runtime_state *gil) -{ - /* some pthread-like implementations tie the mutex to the cond - * and must have the cond destroyed first. - */ - COND_FINI(gil->cond); - MUTEX_FINI(gil->mutex); -#ifdef FORCE_SWITCHING - COND_FINI(gil->switch_cond); - MUTEX_FINI(gil->switch_mutex); -#endif - _Py_atomic_store_explicit(&gil->locked, -1, - _Py_memory_order_release); - _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); -} - -static void recreate_gil(struct _gil_runtime_state *gil) -{ - _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); - /* XXX should we destroy the old OS resources here? */ - create_gil(gil); -} - -static void -drop_gil(struct _ceval_runtime_state *ceval, struct _ceval_state *ceval2, - PyThreadState *tstate) -{ -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - struct _gil_runtime_state *gil = &ceval2->gil; -#else - struct _gil_runtime_state *gil = &ceval->gil; -#endif - if (!_Py_atomic_load_relaxed(&gil->locked)) { - Py_FatalError("drop_gil: GIL is not locked"); - } - - /* tstate is allowed to be NULL (early interpreter init) */ - if (tstate != NULL) { - /* Sub-interpreter support: threads might have been switched - under our feet using PyThreadState_Swap(). Fix the GIL last - holder variable so that our heuristics work. */ - _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); - } - - MUTEX_LOCK(gil->mutex); - _Py_ANNOTATE_RWLOCK_RELEASED(&gil->locked, /*is_write=*/1); - _Py_atomic_store_relaxed(&gil->locked, 0); - COND_SIGNAL(gil->cond); - MUTEX_UNLOCK(gil->mutex); - -#ifdef FORCE_SWITCHING - if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request) && tstate != NULL) { - MUTEX_LOCK(gil->switch_mutex); - /* Not switched yet => wait */ - if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) == tstate) - { - assert(is_tstate_valid(tstate)); - RESET_GIL_DROP_REQUEST(tstate->interp); - /* NOTE: if COND_WAIT does not atomically start waiting when - releasing the mutex, another thread can run through, take - the GIL and drop it again, and reset the condition - before we even had a chance to wait for it. */ - COND_WAIT(gil->switch_cond, gil->switch_mutex); - } - MUTEX_UNLOCK(gil->switch_mutex); - } -#endif -} - - -/* Check if a Python thread must exit immediately, rather than taking the GIL - if Py_Finalize() has been called. - - When this function is called by a daemon thread after Py_Finalize() has been - called, the GIL does no longer exist. - - tstate must be non-NULL. */ -static inline int -tstate_must_exit(PyThreadState *tstate) -{ - /* bpo-39877: Access _PyRuntime directly rather than using - tstate->interp->runtime to support calls from Python daemon threads. - After Py_Finalize() has been called, tstate can be a dangling pointer: - point to PyThreadState freed memory. */ - PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(&_PyRuntime); - return (finalizing != NULL && finalizing != tstate); -} - - -/* Take the GIL. - - The function saves errno at entry and restores its value at exit. - - tstate must be non-NULL. */ -static void -take_gil(PyThreadState *tstate) -{ - int err = errno; - - assert(tstate != NULL); - - if (tstate_must_exit(tstate)) { - /* bpo-39877: If Py_Finalize() has been called and tstate is not the - thread which called Py_Finalize(), exit immediately the thread. - - This code path can be reached by a daemon thread after Py_Finalize() - completes. In this case, tstate is a dangling pointer: points to - PyThreadState freed memory. */ - PyThread_exit_thread(); - } - - assert(is_tstate_valid(tstate)); - PyInterpreterState *interp = tstate->interp; - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - struct _gil_runtime_state *gil = &ceval2->gil; -#else - struct _gil_runtime_state *gil = &ceval->gil; -#endif - - /* Check that _PyEval_InitThreads() was called to create the lock */ - assert(gil_created(gil)); - - MUTEX_LOCK(gil->mutex); - - if (!_Py_atomic_load_relaxed(&gil->locked)) { - goto _ready; - } - - while (_Py_atomic_load_relaxed(&gil->locked)) { - unsigned long saved_switchnum = gil->switch_number; - - unsigned long interval = (gil->interval >= 1 ? gil->interval : 1); - int timed_out = 0; - COND_TIMED_WAIT(gil->cond, gil->mutex, interval, timed_out); - - /* If we timed out and no switch occurred in the meantime, it is time - to ask the GIL-holding thread to drop it. */ - if (timed_out && - _Py_atomic_load_relaxed(&gil->locked) && - gil->switch_number == saved_switchnum) - { - if (tstate_must_exit(tstate)) { - MUTEX_UNLOCK(gil->mutex); - PyThread_exit_thread(); - } - assert(is_tstate_valid(tstate)); - - SET_GIL_DROP_REQUEST(interp); - } - } - -_ready: -#ifdef FORCE_SWITCHING - /* This mutex must be taken before modifying gil->last_holder: - see drop_gil(). */ - MUTEX_LOCK(gil->switch_mutex); -#endif - /* We now hold the GIL */ - _Py_atomic_store_relaxed(&gil->locked, 1); - _Py_ANNOTATE_RWLOCK_ACQUIRED(&gil->locked, /*is_write=*/1); - - if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) { - _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); - ++gil->switch_number; - } - -#ifdef FORCE_SWITCHING - COND_SIGNAL(gil->switch_cond); - MUTEX_UNLOCK(gil->switch_mutex); -#endif - - if (tstate_must_exit(tstate)) { - /* bpo-36475: If Py_Finalize() has been called and tstate is not - the thread which called Py_Finalize(), exit immediately the - thread. - - This code path can be reached by a daemon thread which was waiting - in take_gil() while the main thread called - wait_for_thread_shutdown() from Py_Finalize(). */ - MUTEX_UNLOCK(gil->mutex); - drop_gil(ceval, ceval2, tstate); - PyThread_exit_thread(); - } - assert(is_tstate_valid(tstate)); - - if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request)) { - RESET_GIL_DROP_REQUEST(interp); - } - else { - /* bpo-40010: eval_breaker should be recomputed to be set to 1 if there - is a pending signal: signal received by another thread which cannot - handle signals. - - Note: RESET_GIL_DROP_REQUEST() calls COMPUTE_EVAL_BREAKER(). */ - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); - } - - /* Don't access tstate if the thread must exit */ - if (tstate->async_exc != NULL) { - _PyEval_SignalAsyncExc(tstate->interp); - } - - MUTEX_UNLOCK(gil->mutex); - - errno = err; -} - -void _PyEval_SetSwitchInterval(unsigned long microseconds) -{ -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - PyInterpreterState *interp = PyInterpreterState_Get(); - struct _gil_runtime_state *gil = &interp->ceval.gil; -#else - struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil; -#endif - gil->interval = microseconds; -} - -unsigned long _PyEval_GetSwitchInterval() -{ -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - PyInterpreterState *interp = PyInterpreterState_Get(); - struct _gil_runtime_state *gil = &interp->ceval.gil; -#else - struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil; -#endif - return gil->interval; -} diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h new file mode 100644 index 00000000000..d7a8f0beeec --- /dev/null +++ b/Python/ceval_macros.h @@ -0,0 +1,349 @@ +// Macros needed by ceval.c and bytecodes.c + +/* Computed GOTOs, or + the-optimization-commonly-but-improperly-known-as-"threaded code" + using gcc's labels-as-values extension + (http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html). + + The traditional bytecode evaluation loop uses a "switch" statement, which + decent compilers will optimize as a single indirect branch instruction + combined with a lookup table of jump addresses. However, since the + indirect jump instruction is shared by all opcodes, the CPU will have a + hard time making the right prediction for where to jump next (actually, + it will be always wrong except in the uncommon case of a sequence of + several identical opcodes). + + "Threaded code" in contrast, uses an explicit jump table and an explicit + indirect jump instruction at the end of each opcode. Since the jump + instruction is at a different address for each opcode, the CPU will make a + separate prediction for each of these instructions, which is equivalent to + predicting the second opcode of each opcode pair. These predictions have + a much better chance to turn out valid, especially in small bytecode loops. + + A mispredicted branch on a modern CPU flushes the whole pipeline and + can cost several CPU cycles (depending on the pipeline depth), + and potentially many more instructions (depending on the pipeline width). + A correctly predicted branch, however, is nearly free. + + At the time of this writing, the "threaded code" version is up to 15-20% + faster than the normal "switch" version, depending on the compiler and the + CPU architecture. + + NOTE: care must be taken that the compiler doesn't try to "optimize" the + indirect jumps by sharing them between all opcodes. Such optimizations + can be disabled on gcc by using the -fno-gcse flag (or possibly + -fno-crossjumping). +*/ + +/* Use macros rather than inline functions, to make it as clear as possible + * to the C compiler that the tracing check is a simple test then branch. + * We want to be sure that the compiler knows this before it generates + * the CFG. + */ + +#ifdef WITH_DTRACE +#define OR_DTRACE_LINE | (PyDTrace_LINE_ENABLED() ? 255 : 0) +#else +#define OR_DTRACE_LINE +#endif + +#ifdef HAVE_COMPUTED_GOTOS + #ifndef USE_COMPUTED_GOTOS + #define USE_COMPUTED_GOTOS 1 + #endif +#else + #if defined(USE_COMPUTED_GOTOS) && USE_COMPUTED_GOTOS + #error "Computed gotos are not supported on this compiler." + #endif + #undef USE_COMPUTED_GOTOS + #define USE_COMPUTED_GOTOS 0 +#endif + +#ifdef Py_STATS +#define INSTRUCTION_START(op) \ + do { \ + frame->prev_instr = next_instr++; \ + OPCODE_EXE_INC(op); \ + if (_py_stats) _py_stats->opcode_stats[lastopcode].pair_count[op]++; \ + lastopcode = op; \ + } while (0) +#else +#define INSTRUCTION_START(op) (frame->prev_instr = next_instr++) +#endif + +#if USE_COMPUTED_GOTOS +# define TARGET(op) TARGET_##op: INSTRUCTION_START(op); +# define DISPATCH_GOTO() goto *opcode_targets[opcode] +#else +# define TARGET(op) case op: TARGET_##op: INSTRUCTION_START(op); +# define DISPATCH_GOTO() goto dispatch_opcode +#endif + +/* PRE_DISPATCH_GOTO() does lltrace if enabled. Normally a no-op */ +#ifdef LLTRACE +#define PRE_DISPATCH_GOTO() if (lltrace) { \ + lltrace_instruction(frame, stack_pointer, next_instr); } +#else +#define PRE_DISPATCH_GOTO() ((void)0) +#endif + + +/* Do interpreter dispatch accounting for tracing and instrumentation */ +#define DISPATCH() \ + { \ + NEXTOPARG(); \ + PRE_DISPATCH_GOTO(); \ + assert(cframe.use_tracing == 0 || cframe.use_tracing == 255); \ + opcode |= cframe.use_tracing OR_DTRACE_LINE; \ + DISPATCH_GOTO(); \ + } + +#define DISPATCH_SAME_OPARG() \ + { \ + opcode = _Py_OPCODE(*next_instr); \ + PRE_DISPATCH_GOTO(); \ + opcode |= cframe.use_tracing OR_DTRACE_LINE; \ + DISPATCH_GOTO(); \ + } + +#define DISPATCH_INLINED(NEW_FRAME) \ + do { \ + _PyFrame_SetStackPointer(frame, stack_pointer); \ + frame->prev_instr = next_instr - 1; \ + (NEW_FRAME)->previous = frame; \ + frame = cframe.current_frame = (NEW_FRAME); \ + CALL_STAT_INC(inlined_py_calls); \ + goto start_frame; \ + } while (0) + +#define CHECK_EVAL_BREAKER() \ + _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); \ + if (_Py_atomic_load_relaxed_int32(eval_breaker)) { \ + goto handle_eval_breaker; \ + } + + +/* Tuple access macros */ + +#ifndef Py_DEBUG +#define GETITEM(v, i) PyTuple_GET_ITEM((v), (i)) +#else +static inline PyObject * +GETITEM(PyObject *v, Py_ssize_t i) { + assert(PyTuple_Check(v)); + assert(i >= 0); + assert(i < PyTuple_GET_SIZE(v)); + return PyTuple_GET_ITEM(v, i); +} +#endif + +/* Code access macros */ + +/* The integer overflow is checked by an assertion below. */ +#define INSTR_OFFSET() ((int)(next_instr - _PyCode_CODE(frame->f_code))) +#define NEXTOPARG() do { \ + _Py_CODEUNIT word = *next_instr; \ + opcode = _Py_OPCODE(word); \ + oparg = _Py_OPARG(word); \ + } while (0) +#define JUMPTO(x) (next_instr = _PyCode_CODE(frame->f_code) + (x)) +#define JUMPBY(x) (next_instr += (x)) + +/* OpCode prediction macros + Some opcodes tend to come in pairs thus making it possible to + predict the second code when the first is run. For example, + COMPARE_OP is often followed by POP_JUMP_IF_FALSE or POP_JUMP_IF_TRUE. + + Verifying the prediction costs a single high-speed test of a register + variable against a constant. If the pairing was good, then the + processor's own internal branch predication has a high likelihood of + success, resulting in a nearly zero-overhead transition to the + next opcode. A successful prediction saves a trip through the eval-loop + including its unpredictable switch-case branch. Combined with the + processor's internal branch prediction, a successful PREDICT has the + effect of making the two opcodes run as if they were a single new opcode + with the bodies combined. + + If collecting opcode statistics, your choices are to either keep the + predictions turned-on and interpret the results as if some opcodes + had been combined or turn-off predictions so that the opcode frequency + counter updates for both opcodes. + + Opcode prediction is disabled with threaded code, since the latter allows + the CPU to record separate branch prediction information for each + opcode. + +*/ + +#define PREDICT_ID(op) PRED_##op + +#if USE_COMPUTED_GOTOS +#define PREDICT(op) if (0) goto PREDICT_ID(op) +#else +#define PREDICT(op) \ + do { \ + _Py_CODEUNIT word = *next_instr; \ + opcode = _Py_OPCODE(word) | cframe.use_tracing OR_DTRACE_LINE; \ + if (opcode == op) { \ + oparg = _Py_OPARG(word); \ + INSTRUCTION_START(op); \ + goto PREDICT_ID(op); \ + } \ + } while(0) +#endif +#define PREDICTED(op) PREDICT_ID(op): + + +/* Stack manipulation macros */ + +/* The stack can grow at most MAXINT deep, as co_nlocals and + co_stacksize are ints. */ +#define STACK_LEVEL() ((int)(stack_pointer - _PyFrame_Stackbase(frame))) +#define STACK_SIZE() (frame->f_code->co_stacksize) +#define EMPTY() (STACK_LEVEL() == 0) +#define TOP() (stack_pointer[-1]) +#define SECOND() (stack_pointer[-2]) +#define THIRD() (stack_pointer[-3]) +#define FOURTH() (stack_pointer[-4]) +#define PEEK(n) (stack_pointer[-(n)]) +#define POKE(n, v) (stack_pointer[-(n)] = (v)) +#define SET_TOP(v) (stack_pointer[-1] = (v)) +#define SET_SECOND(v) (stack_pointer[-2] = (v)) +#define BASIC_STACKADJ(n) (stack_pointer += n) +#define BASIC_PUSH(v) (*stack_pointer++ = (v)) +#define BASIC_POP() (*--stack_pointer) + +#ifdef Py_DEBUG +#define PUSH(v) do { \ + BASIC_PUSH(v); \ + assert(STACK_LEVEL() <= STACK_SIZE()); \ + } while (0) +#define POP() (assert(STACK_LEVEL() > 0), BASIC_POP()) +#define STACK_GROW(n) do { \ + assert(n >= 0); \ + BASIC_STACKADJ(n); \ + assert(STACK_LEVEL() <= STACK_SIZE()); \ + } while (0) +#define STACK_SHRINK(n) do { \ + assert(n >= 0); \ + assert(STACK_LEVEL() >= n); \ + BASIC_STACKADJ(-(n)); \ + } while (0) +#else +#define PUSH(v) BASIC_PUSH(v) +#define POP() BASIC_POP() +#define STACK_GROW(n) BASIC_STACKADJ(n) +#define STACK_SHRINK(n) BASIC_STACKADJ(-(n)) +#endif + +/* Local variable macros */ + +#define GETLOCAL(i) (frame->localsplus[i]) + +/* The SETLOCAL() macro must not DECREF the local variable in-place and + then store the new value; it must copy the old value to a temporary + value, then store the new value, and then DECREF the temporary value. + This is because it is possible that during the DECREF the frame is + accessed by other code (e.g. a __del__ method or gc.collect()) and the + variable would be pointing to already-freed memory. */ +#define SETLOCAL(i, value) do { PyObject *tmp = GETLOCAL(i); \ + GETLOCAL(i) = value; \ + Py_XDECREF(tmp); } while (0) + +#define GO_TO_INSTRUCTION(op) goto PREDICT_ID(op) + +#ifdef Py_STATS +#define UPDATE_MISS_STATS(INSTNAME) \ + do { \ + STAT_INC(opcode, miss); \ + STAT_INC((INSTNAME), miss); \ + /* The counter is always the first cache entry: */ \ + if (ADAPTIVE_COUNTER_IS_ZERO(next_instr->cache)) { \ + STAT_INC((INSTNAME), deopt); \ + } \ + else { \ + /* This is about to be (incorrectly) incremented: */ \ + STAT_DEC((INSTNAME), deferred); \ + } \ + } while (0) +#else +#define UPDATE_MISS_STATS(INSTNAME) ((void)0) +#endif + +#define DEOPT_IF(COND, INSTNAME) \ + if ((COND)) { \ + /* This is only a single jump on release builds! */ \ + UPDATE_MISS_STATS((INSTNAME)); \ + assert(_PyOpcode_Deopt[opcode] == (INSTNAME)); \ + GO_TO_INSTRUCTION(INSTNAME); \ + } + + +#define GLOBALS() frame->f_globals +#define BUILTINS() frame->f_builtins +#define LOCALS() frame->f_locals + +/* Shared opcode macros */ + +#define TRACE_FUNCTION_EXIT() \ + if (cframe.use_tracing) { \ + if (trace_function_exit(tstate, frame, retval)) { \ + Py_DECREF(retval); \ + goto exit_unwind; \ + } \ + } + +#define DTRACE_FUNCTION_EXIT() \ + if (PyDTrace_FUNCTION_RETURN_ENABLED()) { \ + dtrace_function_return(frame); \ + } + +#define TRACE_FUNCTION_UNWIND() \ + if (cframe.use_tracing) { \ + /* Since we are already unwinding, \ + * we don't care if this raises */ \ + trace_function_exit(tstate, frame, NULL); \ + } + +#define TRACE_FUNCTION_ENTRY() \ + if (cframe.use_tracing) { \ + _PyFrame_SetStackPointer(frame, stack_pointer); \ + int err = trace_function_entry(tstate, frame); \ + stack_pointer = _PyFrame_GetStackPointer(frame); \ + if (err) { \ + goto error; \ + } \ + } + +#define TRACE_FUNCTION_THROW_ENTRY() \ + if (cframe.use_tracing) { \ + assert(frame->stacktop >= 0); \ + if (trace_function_entry(tstate, frame)) { \ + goto exit_unwind; \ + } \ + } + +#define DTRACE_FUNCTION_ENTRY() \ + if (PyDTrace_FUNCTION_ENTRY_ENABLED()) { \ + dtrace_function_entry(frame); \ + } + +#define ADAPTIVE_COUNTER_IS_ZERO(COUNTER) \ + (((COUNTER) >> ADAPTIVE_BACKOFF_BITS) == 0) + +#define ADAPTIVE_COUNTER_IS_MAX(COUNTER) \ + (((COUNTER) >> ADAPTIVE_BACKOFF_BITS) == ((1 << MAX_BACKOFF_VALUE) - 1)) + +#define DECREMENT_ADAPTIVE_COUNTER(COUNTER) \ + do { \ + assert(!ADAPTIVE_COUNTER_IS_ZERO((COUNTER))); \ + (COUNTER) -= (1 << ADAPTIVE_BACKOFF_BITS); \ + } while (0); + +#define INCREMENT_ADAPTIVE_COUNTER(COUNTER) \ + do { \ + assert(!ADAPTIVE_COUNTER_IS_MAX((COUNTER))); \ + (COUNTER) += (1 << ADAPTIVE_BACKOFF_BITS); \ + } while (0); + +#define NAME_ERROR_MSG "name '%.200s' is not defined" diff --git a/Python/clinic/Python-tokenize.c.h b/Python/clinic/Python-tokenize.c.h index 050b4d49448..6af93743f40 100644 --- a/Python/clinic/Python-tokenize.c.h +++ b/Python/clinic/Python-tokenize.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * tokenizeriter_new_impl(PyTypeObject *type, const char *source); @@ -9,8 +15,31 @@ static PyObject * tokenizeriter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(source), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"source", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "tokenizeriter", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "tokenizeriter", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -38,4 +67,4 @@ tokenizeriter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=dfcd64774e01bfe6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8c2c09f651961986 input=a9049054013a1b77]*/ diff --git a/Python/clinic/_warnings.c.h b/Python/clinic/_warnings.c.h index ad6b9a8e242..432e554af85 100644 --- a/Python/clinic/_warnings.c.h +++ b/Python/clinic/_warnings.c.h @@ -2,31 +2,76 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(warnings_warn__doc__, -"warn($module, /, message, category=None, stacklevel=1, source=None)\n" +"warn($module, /, message, category=None, stacklevel=1, source=None, *,\n" +" skip_file_prefixes=)\n" "--\n" "\n" -"Issue a warning, or maybe ignore it or raise an exception."); +"Issue a warning, or maybe ignore it or raise an exception.\n" +"\n" +" message\n" +" Text of the warning message.\n" +" category\n" +" The Warning category subclass. Defaults to UserWarning.\n" +" stacklevel\n" +" How far up the call stack to make this warning appear. A value of 2 for\n" +" example attributes the warning to the caller of the code calling warn().\n" +" source\n" +" If supplied, the destroyed object which emitted a ResourceWarning\n" +" skip_file_prefixes\n" +" An optional tuple of module filename prefixes indicating frames to skip\n" +" during stacklevel computations for stack frame attribution."); #define WARNINGS_WARN_METHODDEF \ - {"warn", (PyCFunction)(void(*)(void))warnings_warn, METH_FASTCALL|METH_KEYWORDS, warnings_warn__doc__}, + {"warn", _PyCFunction_CAST(warnings_warn), METH_FASTCALL|METH_KEYWORDS, warnings_warn__doc__}, static PyObject * warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category, - Py_ssize_t stacklevel, PyObject *source); + Py_ssize_t stacklevel, PyObject *source, + PyTupleObject *skip_file_prefixes); static PyObject * warnings_warn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"message", "category", "stacklevel", "source", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "warn", 0}; - PyObject *argsbuf[4]; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(message), &_Py_ID(category), &_Py_ID(stacklevel), &_Py_ID(source), &_Py_ID(skip_file_prefixes), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"message", "category", "stacklevel", "source", "skip_file_prefixes", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "warn", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *message; PyObject *category = Py_None; Py_ssize_t stacklevel = 1; PyObject *source = Py_None; + PyTupleObject *skip_file_prefixes = NULL; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 4, 0, argsbuf); if (!args) { @@ -59,11 +104,146 @@ warnings_warn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec goto skip_optional_pos; } } - source = args[3]; + if (args[3]) { + source = args[3]; + if (!--noptargs) { + goto skip_optional_pos; + } + } skip_optional_pos: - return_value = warnings_warn_impl(module, message, category, stacklevel, source); + if (!noptargs) { + goto skip_optional_kwonly; + } + if (!PyTuple_Check(args[4])) { + _PyArg_BadArgument("warn", "argument 'skip_file_prefixes'", "tuple", args[4]); + goto exit; + } + skip_file_prefixes = (PyTupleObject *)args[4]; +skip_optional_kwonly: + return_value = warnings_warn_impl(module, message, category, stacklevel, source, skip_file_prefixes); exit: return return_value; } -/*[clinic end generated code: output=eb9997fa998fdbad input=a9049054013a1b77]*/ + +PyDoc_STRVAR(warnings_warn_explicit__doc__, +"warn_explicit($module, /, message, category, filename, lineno,\n" +" module=, registry=None,\n" +" module_globals=None, source=None)\n" +"--\n" +"\n" +"Issue a warning, or maybe ignore it or raise an exception."); + +#define WARNINGS_WARN_EXPLICIT_METHODDEF \ + {"warn_explicit", _PyCFunction_CAST(warnings_warn_explicit), METH_FASTCALL|METH_KEYWORDS, warnings_warn_explicit__doc__}, + +static PyObject * +warnings_warn_explicit_impl(PyObject *module, PyObject *message, + PyObject *category, PyObject *filename, + int lineno, PyObject *mod, PyObject *registry, + PyObject *module_globals, PyObject *sourceobj); + +static PyObject * +warnings_warn_explicit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 8 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(message), &_Py_ID(category), &_Py_ID(filename), &_Py_ID(lineno), &_Py_ID(module), &_Py_ID(registry), &_Py_ID(module_globals), &_Py_ID(source), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"message", "category", "filename", "lineno", "module", "registry", "module_globals", "source", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "warn_explicit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[8]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; + PyObject *message; + PyObject *category; + PyObject *filename; + int lineno; + PyObject *mod = NULL; + PyObject *registry = Py_None; + PyObject *module_globals = Py_None; + PyObject *sourceobj = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 4, 8, 0, argsbuf); + if (!args) { + goto exit; + } + message = args[0]; + category = args[1]; + if (!PyUnicode_Check(args[2])) { + _PyArg_BadArgument("warn_explicit", "argument 'filename'", "str", args[2]); + goto exit; + } + if (PyUnicode_READY(args[2]) == -1) { + goto exit; + } + filename = args[2]; + lineno = _PyLong_AsInt(args[3]); + if (lineno == -1 && PyErr_Occurred()) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[4]) { + mod = args[4]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[5]) { + registry = args[5]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[6]) { + module_globals = args[6]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + sourceobj = args[7]; +skip_optional_pos: + return_value = warnings_warn_explicit_impl(module, message, category, filename, lineno, mod, registry, module_globals, sourceobj); + +exit: + return return_value; +} + +PyDoc_STRVAR(warnings_filters_mutated__doc__, +"_filters_mutated($module, /)\n" +"--\n" +"\n"); + +#define WARNINGS_FILTERS_MUTATED_METHODDEF \ + {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS, warnings_filters_mutated__doc__}, + +static PyObject * +warnings_filters_mutated_impl(PyObject *module); + +static PyObject * +warnings_filters_mutated(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return warnings_filters_mutated_impl(module); +} +/*[clinic end generated code: output=20429719d7223bdc input=a9049054013a1b77]*/ diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h index 1fade994f40..b77b4a1e4b4 100644 --- a/Python/clinic/bltinmodule.c.h +++ b/Python/clinic/bltinmodule.c.h @@ -2,6 +2,114 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(builtin___import____doc__, +"__import__($module, /, name, globals=None, locals=None, fromlist=(),\n" +" level=0)\n" +"--\n" +"\n" +"Import a module.\n" +"\n" +"Because this function is meant for use by the Python\n" +"interpreter and not for general use, it is better to use\n" +"importlib.import_module() to programmatically import a module.\n" +"\n" +"The globals argument is only used to determine the context;\n" +"they are not modified. The locals argument is unused. The fromlist\n" +"should be a list of names to emulate ``from name import ...``, or an\n" +"empty list to emulate ``import name``.\n" +"When importing a module from a package, note that __import__(\'A.B\', ...)\n" +"returns package A when fromlist is empty, but its submodule B when\n" +"fromlist is not empty. The level argument is used to determine whether to\n" +"perform absolute or relative imports: 0 is absolute, while a positive number\n" +"is the number of parent directories to search relative to the current module."); + +#define BUILTIN___IMPORT___METHODDEF \ + {"__import__", _PyCFunction_CAST(builtin___import__), METH_FASTCALL|METH_KEYWORDS, builtin___import____doc__}, + +static PyObject * +builtin___import___impl(PyObject *module, PyObject *name, PyObject *globals, + PyObject *locals, PyObject *fromlist, int level); + +static PyObject * +builtin___import__(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(globals), &_Py_ID(locals), &_Py_ID(fromlist), &_Py_ID(level), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"name", "globals", "locals", "fromlist", "level", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__import__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[5]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *name; + PyObject *globals = NULL; + PyObject *locals = NULL; + PyObject *fromlist = NULL; + int level = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 5, 0, argsbuf); + if (!args) { + goto exit; + } + name = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + globals = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[2]) { + locals = args[2]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[3]) { + fromlist = args[3]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + level = _PyLong_AsInt(args[4]); + if (level == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = builtin___import___impl(module, name, globals, locals, fromlist, level); + +exit: + return return_value; +} + PyDoc_STRVAR(builtin_abs__doc__, "abs($module, x, /)\n" "--\n" @@ -75,14 +183,17 @@ PyDoc_STRVAR(builtin_format__doc__, "format($module, value, format_spec=\'\', /)\n" "--\n" "\n" -"Return value.__format__(format_spec)\n" +"Return type(value).__format__(value, format_spec)\n" "\n" -"format_spec defaults to the empty string.\n" -"See the Format Specification Mini-Language section of help(\'FORMATTING\') for\n" -"details."); +"Many built-in types implement format_spec according to the\n" +"Format Specification Mini-language. See help(\'FORMATTING\').\n" +"\n" +"If type(value) does not supply a method named __format__\n" +"and format_spec is empty, then str(value) is returned.\n" +"See also help(\'SPECIALMETHODS\')."); #define BUILTIN_FORMAT_METHODDEF \ - {"format", (PyCFunction)(void(*)(void))builtin_format, METH_FASTCALL, builtin_format__doc__}, + {"format", _PyCFunction_CAST(builtin_format), METH_FASTCALL, builtin_format__doc__}, static PyObject * builtin_format_impl(PyObject *module, PyObject *value, PyObject *format_spec); @@ -163,7 +274,7 @@ PyDoc_STRVAR(builtin_compile__doc__, "in addition to any features explicitly specified."); #define BUILTIN_COMPILE_METHODDEF \ - {"compile", (PyCFunction)(void(*)(void))builtin_compile, METH_FASTCALL|METH_KEYWORDS, builtin_compile__doc__}, + {"compile", _PyCFunction_CAST(builtin_compile), METH_FASTCALL|METH_KEYWORDS, builtin_compile__doc__}, static PyObject * builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, @@ -174,8 +285,31 @@ static PyObject * builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 7 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(source), &_Py_ID(filename), &_Py_ID(mode), &_Py_ID(flags), &_Py_ID(dont_inherit), &_Py_ID(optimize), &_Py_ID(_feature_version), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"source", "filename", "mode", "flags", "dont_inherit", "optimize", "_feature_version", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[7]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; PyObject *source; @@ -220,8 +354,8 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } } if (args[4]) { - dont_inherit = _PyLong_AsInt(args[4]); - if (dont_inherit == -1 && PyErr_Occurred()) { + dont_inherit = PyObject_IsTrue(args[4]); + if (dont_inherit < 0) { goto exit; } if (!--noptargs) { @@ -252,6 +386,49 @@ exit: return return_value; } +PyDoc_STRVAR(builtin_dir__doc__, +"dir($module, arg=, /)\n" +"--\n" +"\n" +"Show attributes of an object.\n" +"\n" +"If called without an argument, return the names in the current scope.\n" +"Else, return an alphabetized list of names comprising (some of) the attributes\n" +"of the given object, and of attributes reachable from it.\n" +"If the object supplies a method named __dir__, it will be used; otherwise\n" +"the default dir() logic is used and returns:\n" +" for a module object: the module\'s attributes.\n" +" for a class object: its attributes, and recursively the attributes\n" +" of its bases.\n" +" for any other object: its attributes, its class\'s attributes, and\n" +" recursively the attributes of its class\'s base classes."); + +#define BUILTIN_DIR_METHODDEF \ + {"dir", _PyCFunction_CAST(builtin_dir), METH_FASTCALL, builtin_dir__doc__}, + +static PyObject * +builtin_dir_impl(PyObject *module, PyObject *arg); + +static PyObject * +builtin_dir(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *arg = NULL; + + if (!_PyArg_CheckPositional("dir", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + arg = args[0]; +skip_optional: + return_value = builtin_dir_impl(module, arg); + +exit: + return return_value; +} + PyDoc_STRVAR(builtin_divmod__doc__, "divmod($module, x, y, /)\n" "--\n" @@ -259,7 +436,7 @@ PyDoc_STRVAR(builtin_divmod__doc__, "Return the tuple (x//y, x%y). Invariant: div*y + mod == x."); #define BUILTIN_DIVMOD_METHODDEF \ - {"divmod", (PyCFunction)(void(*)(void))builtin_divmod, METH_FASTCALL, builtin_divmod__doc__}, + {"divmod", _PyCFunction_CAST(builtin_divmod), METH_FASTCALL, builtin_divmod__doc__}, static PyObject * builtin_divmod_impl(PyObject *module, PyObject *x, PyObject *y); @@ -295,7 +472,7 @@ PyDoc_STRVAR(builtin_eval__doc__, "If only globals is given, locals defaults to it."); #define BUILTIN_EVAL_METHODDEF \ - {"eval", (PyCFunction)(void(*)(void))builtin_eval, METH_FASTCALL, builtin_eval__doc__}, + {"eval", _PyCFunction_CAST(builtin_eval), METH_FASTCALL, builtin_eval__doc__}, static PyObject * builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, @@ -329,7 +506,7 @@ exit: } PyDoc_STRVAR(builtin_exec__doc__, -"exec($module, source, globals=None, locals=None, /)\n" +"exec($module, source, globals=None, locals=None, /, *, closure=None)\n" "--\n" "\n" "Execute the given source in the context of globals and locals.\n" @@ -338,37 +515,116 @@ PyDoc_STRVAR(builtin_exec__doc__, "or a code object as returned by compile().\n" "The globals must be a dictionary and locals can be any mapping,\n" "defaulting to the current globals and locals.\n" -"If only globals is given, locals defaults to it."); +"If only globals is given, locals defaults to it.\n" +"The closure must be a tuple of cellvars, and can only be used\n" +"when source is a code object requiring exactly that many cellvars."); #define BUILTIN_EXEC_METHODDEF \ - {"exec", (PyCFunction)(void(*)(void))builtin_exec, METH_FASTCALL, builtin_exec__doc__}, + {"exec", _PyCFunction_CAST(builtin_exec), METH_FASTCALL|METH_KEYWORDS, builtin_exec__doc__}, static PyObject * builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, - PyObject *locals); + PyObject *locals, PyObject *closure); static PyObject * -builtin_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +builtin_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(closure), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "", "", "closure", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "exec", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *source; PyObject *globals = Py_None; PyObject *locals = Py_None; + PyObject *closure = NULL; - if (!_PyArg_CheckPositional("exec", nargs, 1, 3)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { goto exit; } source = args[0]; if (nargs < 2) { - goto skip_optional; + goto skip_optional_posonly; } + noptargs--; globals = args[1]; + if (nargs < 3) { + goto skip_optional_posonly; + } + noptargs--; + locals = args[2]; +skip_optional_posonly: + if (!noptargs) { + goto skip_optional_kwonly; + } + closure = args[3]; +skip_optional_kwonly: + return_value = builtin_exec_impl(module, source, globals, locals, closure); + +exit: + return return_value; +} + +PyDoc_STRVAR(builtin_getattr__doc__, +"getattr($module, object, name, default=, /)\n" +"--\n" +"\n" +"Get a named attribute from an object.\n" +"\n" +"getattr(x, \'y\') is equivalent to x.y\n" +"When a default argument is given, it is returned when the attribute doesn\'t\n" +"exist; without it, an exception is raised in that case."); + +#define BUILTIN_GETATTR_METHODDEF \ + {"getattr", _PyCFunction_CAST(builtin_getattr), METH_FASTCALL, builtin_getattr__doc__}, + +static PyObject * +builtin_getattr_impl(PyObject *module, PyObject *object, PyObject *name, + PyObject *default_value); + +static PyObject * +builtin_getattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *object; + PyObject *name; + PyObject *default_value = NULL; + + if (!_PyArg_CheckPositional("getattr", nargs, 2, 3)) { + goto exit; + } + object = args[0]; + name = args[1]; if (nargs < 3) { goto skip_optional; } - locals = args[2]; + default_value = args[2]; skip_optional: - return_value = builtin_exec_impl(module, source, globals, locals); + return_value = builtin_getattr_impl(module, object, name, default_value); exit: return return_value; @@ -404,7 +660,7 @@ PyDoc_STRVAR(builtin_hasattr__doc__, "This is done by calling getattr(obj, name) and catching AttributeError."); #define BUILTIN_HASATTR_METHODDEF \ - {"hasattr", (PyCFunction)(void(*)(void))builtin_hasattr, METH_FASTCALL, builtin_hasattr__doc__}, + {"hasattr", _PyCFunction_CAST(builtin_hasattr), METH_FASTCALL, builtin_hasattr__doc__}, static PyObject * builtin_hasattr_impl(PyObject *module, PyObject *obj, PyObject *name); @@ -439,16 +695,54 @@ PyDoc_STRVAR(builtin_id__doc__, #define BUILTIN_ID_METHODDEF \ {"id", (PyCFunction)builtin_id, METH_O, builtin_id__doc__}, +PyDoc_STRVAR(builtin_next__doc__, +"next($module, iterator, default=, /)\n" +"--\n" +"\n" +"Return the next item from the iterator.\n" +"\n" +"If default is given and the iterator is exhausted,\n" +"it is returned instead of raising StopIteration."); + +#define BUILTIN_NEXT_METHODDEF \ + {"next", _PyCFunction_CAST(builtin_next), METH_FASTCALL, builtin_next__doc__}, + +static PyObject * +builtin_next_impl(PyObject *module, PyObject *iterator, + PyObject *default_value); + +static PyObject * +builtin_next(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *iterator; + PyObject *default_value = NULL; + + if (!_PyArg_CheckPositional("next", nargs, 1, 2)) { + goto exit; + } + iterator = args[0]; + if (nargs < 2) { + goto skip_optional; + } + default_value = args[1]; +skip_optional: + return_value = builtin_next_impl(module, iterator, default_value); + +exit: + return return_value; +} + PyDoc_STRVAR(builtin_setattr__doc__, "setattr($module, obj, name, value, /)\n" "--\n" "\n" "Sets the named attribute on the given object to the specified value.\n" "\n" -"setattr(x, \'y\', v) is equivalent to ``x.y = v\'\'"); +"setattr(x, \'y\', v) is equivalent to ``x.y = v``"); #define BUILTIN_SETATTR_METHODDEF \ - {"setattr", (PyCFunction)(void(*)(void))builtin_setattr, METH_FASTCALL, builtin_setattr__doc__}, + {"setattr", _PyCFunction_CAST(builtin_setattr), METH_FASTCALL, builtin_setattr__doc__}, static PyObject * builtin_setattr_impl(PyObject *module, PyObject *obj, PyObject *name, @@ -480,10 +774,10 @@ PyDoc_STRVAR(builtin_delattr__doc__, "\n" "Deletes the named attribute from the given object.\n" "\n" -"delattr(x, \'y\') is equivalent to ``del x.y\'\'"); +"delattr(x, \'y\') is equivalent to ``del x.y``"); #define BUILTIN_DELATTR_METHODDEF \ - {"delattr", (PyCFunction)(void(*)(void))builtin_delattr, METH_FASTCALL, builtin_delattr__doc__}, + {"delattr", _PyCFunction_CAST(builtin_delattr), METH_FASTCALL, builtin_delattr__doc__}, static PyObject * builtin_delattr_impl(PyObject *module, PyObject *obj, PyObject *name); @@ -530,6 +824,43 @@ PyDoc_STRVAR(builtin_hex__doc__, #define BUILTIN_HEX_METHODDEF \ {"hex", (PyCFunction)builtin_hex, METH_O, builtin_hex__doc__}, +PyDoc_STRVAR(builtin_iter__doc__, +"iter($module, object, sentinel=, /)\n" +"--\n" +"\n" +"Get an iterator from an object.\n" +"\n" +"In the first form, the argument must supply its own iterator, or be a sequence.\n" +"In the second form, the callable is called until it returns the sentinel."); + +#define BUILTIN_ITER_METHODDEF \ + {"iter", _PyCFunction_CAST(builtin_iter), METH_FASTCALL, builtin_iter__doc__}, + +static PyObject * +builtin_iter_impl(PyObject *module, PyObject *object, PyObject *sentinel); + +static PyObject * +builtin_iter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *object; + PyObject *sentinel = NULL; + + if (!_PyArg_CheckPositional("iter", nargs, 1, 2)) { + goto exit; + } + object = args[0]; + if (nargs < 2) { + goto skip_optional; + } + sentinel = args[1]; +skip_optional: + return_value = builtin_iter_impl(module, object, sentinel); + +exit: + return return_value; +} + PyDoc_STRVAR(builtin_aiter__doc__, "aiter($module, async_iterable, /)\n" "--\n" @@ -549,7 +880,7 @@ PyDoc_STRVAR(builtin_anext__doc__, "iterator is exhausted, it is returned instead of raising StopAsyncIteration."); #define BUILTIN_ANEXT_METHODDEF \ - {"anext", (PyCFunction)(void(*)(void))builtin_anext, METH_FASTCALL, builtin_anext__doc__}, + {"anext", _PyCFunction_CAST(builtin_anext), METH_FASTCALL, builtin_anext__doc__}, static PyObject * builtin_anext_impl(PyObject *module, PyObject *aiterator, @@ -639,7 +970,7 @@ PyDoc_STRVAR(builtin_pow__doc__, "invoked using the three argument form."); #define BUILTIN_POW_METHODDEF \ - {"pow", (PyCFunction)(void(*)(void))builtin_pow, METH_FASTCALL|METH_KEYWORDS, builtin_pow__doc__}, + {"pow", _PyCFunction_CAST(builtin_pow), METH_FASTCALL|METH_KEYWORDS, builtin_pow__doc__}, static PyObject * builtin_pow_impl(PyObject *module, PyObject *base, PyObject *exp, @@ -649,8 +980,31 @@ static PyObject * builtin_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(base), &_Py_ID(exp), &_Py_ID(mod), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"base", "exp", "mod", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "pow", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "pow", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *base; @@ -690,7 +1044,7 @@ PyDoc_STRVAR(builtin_print__doc__, " whether to forcibly flush the stream."); #define BUILTIN_PRINT_METHODDEF \ - {"print", (PyCFunction)(void(*)(void))builtin_print, METH_FASTCALL|METH_KEYWORDS, builtin_print__doc__}, + {"print", _PyCFunction_CAST(builtin_print), METH_FASTCALL|METH_KEYWORDS, builtin_print__doc__}, static PyObject * builtin_print_impl(PyObject *module, PyObject *args, PyObject *sep, @@ -700,8 +1054,31 @@ static PyObject * builtin_print(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(end), &_Py_ID(file), &_Py_ID(flush), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "end", "file", "flush", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "print", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "print", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *__clinic_args = NULL; @@ -749,7 +1126,7 @@ exit: } PyDoc_STRVAR(builtin_input__doc__, -"input($module, prompt=None, /)\n" +"input($module, prompt=\'\', /)\n" "--\n" "\n" "Read a string from standard input. The trailing newline is stripped.\n" @@ -761,7 +1138,7 @@ PyDoc_STRVAR(builtin_input__doc__, "On *nix systems, readline is used if available."); #define BUILTIN_INPUT_METHODDEF \ - {"input", (PyCFunction)(void(*)(void))builtin_input, METH_FASTCALL, builtin_input__doc__}, + {"input", _PyCFunction_CAST(builtin_input), METH_FASTCALL, builtin_input__doc__}, static PyObject * builtin_input_impl(PyObject *module, PyObject *prompt); @@ -807,7 +1184,7 @@ PyDoc_STRVAR(builtin_round__doc__, "the return value has the same type as the number. ndigits may be negative."); #define BUILTIN_ROUND_METHODDEF \ - {"round", (PyCFunction)(void(*)(void))builtin_round, METH_FASTCALL|METH_KEYWORDS, builtin_round__doc__}, + {"round", _PyCFunction_CAST(builtin_round), METH_FASTCALL|METH_KEYWORDS, builtin_round__doc__}, static PyObject * builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits); @@ -816,8 +1193,31 @@ static PyObject * builtin_round(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(number), &_Py_ID(ndigits), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"number", "ndigits", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "round", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "round", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *number; @@ -839,6 +1239,41 @@ exit: return return_value; } +PyDoc_STRVAR(builtin_vars__doc__, +"vars($module, object=, /)\n" +"--\n" +"\n" +"Show vars.\n" +"\n" +"Without arguments, equivalent to locals().\n" +"With an argument, equivalent to object.__dict__."); + +#define BUILTIN_VARS_METHODDEF \ + {"vars", _PyCFunction_CAST(builtin_vars), METH_FASTCALL, builtin_vars__doc__}, + +static PyObject * +builtin_vars_impl(PyObject *module, PyObject *object); + +static PyObject * +builtin_vars(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *object = NULL; + + if (!_PyArg_CheckPositional("vars", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + object = args[0]; +skip_optional: + return_value = builtin_vars_impl(module, object); + +exit: + return return_value; +} + PyDoc_STRVAR(builtin_sum__doc__, "sum($module, iterable, /, start=0)\n" "--\n" @@ -850,7 +1285,7 @@ PyDoc_STRVAR(builtin_sum__doc__, "reject non-numeric types."); #define BUILTIN_SUM_METHODDEF \ - {"sum", (PyCFunction)(void(*)(void))builtin_sum, METH_FASTCALL|METH_KEYWORDS, builtin_sum__doc__}, + {"sum", _PyCFunction_CAST(builtin_sum), METH_FASTCALL|METH_KEYWORDS, builtin_sum__doc__}, static PyObject * builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start); @@ -859,8 +1294,31 @@ static PyObject * builtin_sum(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(start), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "start", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sum", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sum", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *iterable; @@ -893,7 +1351,7 @@ PyDoc_STRVAR(builtin_isinstance__doc__, "or ...`` etc."); #define BUILTIN_ISINSTANCE_METHODDEF \ - {"isinstance", (PyCFunction)(void(*)(void))builtin_isinstance, METH_FASTCALL, builtin_isinstance__doc__}, + {"isinstance", _PyCFunction_CAST(builtin_isinstance), METH_FASTCALL, builtin_isinstance__doc__}, static PyObject * builtin_isinstance_impl(PyObject *module, PyObject *obj, @@ -928,7 +1386,7 @@ PyDoc_STRVAR(builtin_issubclass__doc__, "or ...``."); #define BUILTIN_ISSUBCLASS_METHODDEF \ - {"issubclass", (PyCFunction)(void(*)(void))builtin_issubclass, METH_FASTCALL, builtin_issubclass__doc__}, + {"issubclass", _PyCFunction_CAST(builtin_issubclass), METH_FASTCALL, builtin_issubclass__doc__}, static PyObject * builtin_issubclass_impl(PyObject *module, PyObject *cls, @@ -951,4 +1409,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=77ace832b3fb38e0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=84a04e7446debf58 input=a9049054013a1b77]*/ diff --git a/Python/clinic/context.c.h b/Python/clinic/context.c.h index 2ac8bf7c0b8..27c375717bf 100644 --- a/Python/clinic/context.c.h +++ b/Python/clinic/context.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_contextvars_Context_get__doc__, "get($self, key, default=None, /)\n" "--\n" @@ -12,7 +18,7 @@ PyDoc_STRVAR(_contextvars_Context_get__doc__, "return None."); #define _CONTEXTVARS_CONTEXT_GET_METHODDEF \ - {"get", (PyCFunction)(void(*)(void))_contextvars_Context_get, METH_FASTCALL, _contextvars_Context_get__doc__}, + {"get", _PyCFunction_CAST(_contextvars_Context_get), METH_FASTCALL, _contextvars_Context_get__doc__}, static PyObject * _contextvars_Context_get_impl(PyContext *self, PyObject *key, @@ -127,7 +133,7 @@ PyDoc_STRVAR(_contextvars_ContextVar_get__doc__, " * raise a LookupError."); #define _CONTEXTVARS_CONTEXTVAR_GET_METHODDEF \ - {"get", (PyCFunction)(void(*)(void))_contextvars_ContextVar_get, METH_FASTCALL, _contextvars_ContextVar_get__doc__}, + {"get", _PyCFunction_CAST(_contextvars_ContextVar_get), METH_FASTCALL, _contextvars_ContextVar_get__doc__}, static PyObject * _contextvars_ContextVar_get_impl(PyContextVar *self, PyObject *default_value); @@ -177,4 +183,4 @@ PyDoc_STRVAR(_contextvars_ContextVar_reset__doc__, #define _CONTEXTVARS_CONTEXTVAR_RESET_METHODDEF \ {"reset", (PyCFunction)_contextvars_ContextVar_reset, METH_O, _contextvars_ContextVar_reset__doc__}, -/*[clinic end generated code: output=f2e42f34e358e179 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0c94d4b919500438 input=a9049054013a1b77]*/ diff --git a/Python/clinic/import.c.h b/Python/clinic/import.c.h index 6052316cdd8..819fb1c75c1 100644 --- a/Python/clinic/import.c.h +++ b/Python/clinic/import.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_imp_lock_held__doc__, "lock_held($module, /)\n" "--\n" @@ -75,7 +81,7 @@ PyDoc_STRVAR(_imp__fix_co_filename__doc__, " File path to use."); #define _IMP__FIX_CO_FILENAME_METHODDEF \ - {"_fix_co_filename", (PyCFunction)(void(*)(void))_imp__fix_co_filename, METH_FASTCALL, _imp__fix_co_filename__doc__}, + {"_fix_co_filename", _PyCFunction_CAST(_imp__fix_co_filename), METH_FASTCALL, _imp__fix_co_filename__doc__}, static PyObject * _imp__fix_co_filename_impl(PyObject *module, PyCodeObject *code, @@ -184,7 +190,7 @@ PyDoc_STRVAR(_imp_find_frozen__doc__, " the module\'s current name)"); #define _IMP_FIND_FROZEN_METHODDEF \ - {"find_frozen", (PyCFunction)(void(*)(void))_imp_find_frozen, METH_FASTCALL|METH_KEYWORDS, _imp_find_frozen__doc__}, + {"find_frozen", _PyCFunction_CAST(_imp_find_frozen), METH_FASTCALL|METH_KEYWORDS, _imp_find_frozen__doc__}, static PyObject * _imp_find_frozen_impl(PyObject *module, PyObject *name, int withdata); @@ -193,8 +199,31 @@ static PyObject * _imp_find_frozen(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(withdata), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "withdata", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "find_frozen", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "find_frozen", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *name; @@ -233,7 +262,7 @@ PyDoc_STRVAR(_imp_get_frozen_object__doc__, "Create a code object for a frozen module."); #define _IMP_GET_FROZEN_OBJECT_METHODDEF \ - {"get_frozen_object", (PyCFunction)(void(*)(void))_imp_get_frozen_object, METH_FASTCALL, _imp_get_frozen_object__doc__}, + {"get_frozen_object", _PyCFunction_CAST(_imp_get_frozen_object), METH_FASTCALL, _imp_get_frozen_object__doc__}, static PyObject * _imp_get_frozen_object_impl(PyObject *module, PyObject *name, @@ -422,7 +451,7 @@ PyDoc_STRVAR(_imp_create_dynamic__doc__, "Create an extension module."); #define _IMP_CREATE_DYNAMIC_METHODDEF \ - {"create_dynamic", (PyCFunction)(void(*)(void))_imp_create_dynamic, METH_FASTCALL, _imp_create_dynamic__doc__}, + {"create_dynamic", _PyCFunction_CAST(_imp_create_dynamic), METH_FASTCALL, _imp_create_dynamic__doc__}, static PyObject * _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file); @@ -517,7 +546,7 @@ PyDoc_STRVAR(_imp_source_hash__doc__, "\n"); #define _IMP_SOURCE_HASH_METHODDEF \ - {"source_hash", (PyCFunction)(void(*)(void))_imp_source_hash, METH_FASTCALL|METH_KEYWORDS, _imp_source_hash__doc__}, + {"source_hash", _PyCFunction_CAST(_imp_source_hash), METH_FASTCALL|METH_KEYWORDS, _imp_source_hash__doc__}, static PyObject * _imp_source_hash_impl(PyObject *module, long key, Py_buffer *source); @@ -526,8 +555,31 @@ static PyObject * _imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(source), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "source", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "source_hash", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "source_hash", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; long key; Py_buffer source = {NULL, NULL}; @@ -565,4 +617,4 @@ exit: #ifndef _IMP_EXEC_DYNAMIC_METHODDEF #define _IMP_EXEC_DYNAMIC_METHODDEF #endif /* !defined(_IMP_EXEC_DYNAMIC_METHODDEF) */ -/*[clinic end generated code: output=adcf787969a11353 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=806352838c3f7008 input=a9049054013a1b77]*/ diff --git a/Python/clinic/marshal.c.h b/Python/clinic/marshal.c.h index f80d5ef31f2..a593b980544 100644 --- a/Python/clinic/marshal.c.h +++ b/Python/clinic/marshal.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(marshal_dump__doc__, "dump($module, value, file, version=version, /)\n" "--\n" @@ -20,7 +26,7 @@ PyDoc_STRVAR(marshal_dump__doc__, "to the file. The object will not be properly read back by load()."); #define MARSHAL_DUMP_METHODDEF \ - {"dump", (PyCFunction)(void(*)(void))marshal_dump, METH_FASTCALL, marshal_dump__doc__}, + {"dump", _PyCFunction_CAST(marshal_dump), METH_FASTCALL, marshal_dump__doc__}, static PyObject * marshal_dump_impl(PyObject *module, PyObject *value, PyObject *file, @@ -87,7 +93,7 @@ PyDoc_STRVAR(marshal_dumps__doc__, "unsupported type."); #define MARSHAL_DUMPS_METHODDEF \ - {"dumps", (PyCFunction)(void(*)(void))marshal_dumps, METH_FASTCALL, marshal_dumps__doc__}, + {"dumps", _PyCFunction_CAST(marshal_dumps), METH_FASTCALL, marshal_dumps__doc__}, static PyObject * marshal_dumps_impl(PyObject *module, PyObject *value, int version); @@ -155,4 +161,4 @@ exit: return return_value; } -/*[clinic end generated code: output=68b78f38bfe0c06d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=12082d61d2942473 input=a9049054013a1b77]*/ diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index 8350fbf9856..46252dd4043 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(sys_addaudithook__doc__, "addaudithook($module, /, hook)\n" "--\n" @@ -9,7 +15,7 @@ PyDoc_STRVAR(sys_addaudithook__doc__, "Adds a new audit hook callback."); #define SYS_ADDAUDITHOOK_METHODDEF \ - {"addaudithook", (PyCFunction)(void(*)(void))sys_addaudithook, METH_FASTCALL|METH_KEYWORDS, sys_addaudithook__doc__}, + {"addaudithook", _PyCFunction_CAST(sys_addaudithook), METH_FASTCALL|METH_KEYWORDS, sys_addaudithook__doc__}, static PyObject * sys_addaudithook_impl(PyObject *module, PyObject *hook); @@ -18,8 +24,31 @@ static PyObject * sys_addaudithook(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(hook), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"hook", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "addaudithook", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "addaudithook", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *hook; @@ -50,7 +79,7 @@ PyDoc_STRVAR(sys_excepthook__doc__, "Handle an exception by displaying it with a traceback on sys.stderr."); #define SYS_EXCEPTHOOK_METHODDEF \ - {"excepthook", (PyCFunction)(void(*)(void))sys_excepthook, METH_FASTCALL, sys_excepthook__doc__}, + {"excepthook", _PyCFunction_CAST(sys_excepthook), METH_FASTCALL, sys_excepthook__doc__}, static PyObject * sys_excepthook_impl(PyObject *module, PyObject *exctype, PyObject *value, @@ -76,6 +105,28 @@ exit: return return_value; } +PyDoc_STRVAR(sys_exception__doc__, +"exception($module, /)\n" +"--\n" +"\n" +"Return the current exception.\n" +"\n" +"Return the most recent exception caught by an except clause\n" +"in the current stack frame or in an older stack frame, or None\n" +"if no such exception exists."); + +#define SYS_EXCEPTION_METHODDEF \ + {"exception", (PyCFunction)sys_exception, METH_NOARGS, sys_exception__doc__}, + +static PyObject * +sys_exception_impl(PyObject *module); + +static PyObject * +sys_exception(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_exception_impl(module); +} + PyDoc_STRVAR(sys_exc_info__doc__, "exc_info($module, /)\n" "--\n" @@ -126,7 +177,7 @@ PyDoc_STRVAR(sys_exit__doc__, "exit status will be one (i.e., failure)."); #define SYS_EXIT_METHODDEF \ - {"exit", (PyCFunction)(void(*)(void))sys_exit, METH_FASTCALL, sys_exit__doc__}, + {"exit", _PyCFunction_CAST(sys_exit), METH_FASTCALL, sys_exit__doc__}, static PyObject * sys_exit_impl(PyObject *module, PyObject *status); @@ -241,6 +292,18 @@ exit: return return_value; } +PyDoc_STRVAR(sys__settraceallthreads__doc__, +"_settraceallthreads($module, arg, /)\n" +"--\n" +"\n" +"Set the global debug tracing function in all running threads belonging to the current interpreter.\n" +"\n" +"It will be called on each function call. See the debugger chapter\n" +"in the library manual."); + +#define SYS__SETTRACEALLTHREADS_METHODDEF \ + {"_settraceallthreads", (PyCFunction)sys__settraceallthreads, METH_O, sys__settraceallthreads__doc__}, + PyDoc_STRVAR(sys_gettrace__doc__, "gettrace($module, /)\n" "--\n" @@ -261,6 +324,18 @@ sys_gettrace(PyObject *module, PyObject *Py_UNUSED(ignored)) return sys_gettrace_impl(module); } +PyDoc_STRVAR(sys__setprofileallthreads__doc__, +"_setprofileallthreads($module, arg, /)\n" +"--\n" +"\n" +"Set the profiling function in all running threads belonging to the current interpreter.\n" +"\n" +"It will be called on each function call and return. See the profiler chapter\n" +"in the library manual."); + +#define SYS__SETPROFILEALLTHREADS_METHODDEF \ + {"_setprofileallthreads", (PyCFunction)sys__setprofileallthreads, METH_O, sys__setprofileallthreads__doc__}, + PyDoc_STRVAR(sys_getprofile__doc__, "getprofile($module, /)\n" "--\n" @@ -394,7 +469,7 @@ PyDoc_STRVAR(sys_set_coroutine_origin_tracking_depth__doc__, "Set a depth of 0 to disable."); #define SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF \ - {"set_coroutine_origin_tracking_depth", (PyCFunction)(void(*)(void))sys_set_coroutine_origin_tracking_depth, METH_FASTCALL|METH_KEYWORDS, sys_set_coroutine_origin_tracking_depth__doc__}, + {"set_coroutine_origin_tracking_depth", _PyCFunction_CAST(sys_set_coroutine_origin_tracking_depth), METH_FASTCALL|METH_KEYWORDS, sys_set_coroutine_origin_tracking_depth__doc__}, static PyObject * sys_set_coroutine_origin_tracking_depth_impl(PyObject *module, int depth); @@ -403,8 +478,31 @@ static PyObject * sys_set_coroutine_origin_tracking_depth(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(depth), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"depth", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "set_coroutine_origin_tracking_depth", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_coroutine_origin_tracking_depth", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int depth; @@ -647,6 +745,82 @@ exit: #endif /* defined(USE_MALLOPT) */ +PyDoc_STRVAR(sys_get_int_max_str_digits__doc__, +"get_int_max_str_digits($module, /)\n" +"--\n" +"\n" +"Return the maximum string digits limit for non-binary int<->str conversions."); + +#define SYS_GET_INT_MAX_STR_DIGITS_METHODDEF \ + {"get_int_max_str_digits", (PyCFunction)sys_get_int_max_str_digits, METH_NOARGS, sys_get_int_max_str_digits__doc__}, + +static PyObject * +sys_get_int_max_str_digits_impl(PyObject *module); + +static PyObject * +sys_get_int_max_str_digits(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_get_int_max_str_digits_impl(module); +} + +PyDoc_STRVAR(sys_set_int_max_str_digits__doc__, +"set_int_max_str_digits($module, /, maxdigits)\n" +"--\n" +"\n" +"Set the maximum string digits limit for non-binary int<->str conversions."); + +#define SYS_SET_INT_MAX_STR_DIGITS_METHODDEF \ + {"set_int_max_str_digits", _PyCFunction_CAST(sys_set_int_max_str_digits), METH_FASTCALL|METH_KEYWORDS, sys_set_int_max_str_digits__doc__}, + +static PyObject * +sys_set_int_max_str_digits_impl(PyObject *module, int maxdigits); + +static PyObject * +sys_set_int_max_str_digits(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(maxdigits), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"maxdigits", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_int_max_str_digits", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + int maxdigits; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + maxdigits = _PyLong_AsInt(args[0]); + if (maxdigits == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = sys_set_int_max_str_digits_impl(module, maxdigits); + +exit: + return return_value; +} + PyDoc_STRVAR(sys_getrefcount__doc__, "getrefcount($module, object, /)\n" "--\n" @@ -710,33 +884,6 @@ exit: #endif /* defined(Py_REF_DEBUG) */ -PyDoc_STRVAR(sys__getquickenedcount__doc__, -"_getquickenedcount($module, /)\n" -"--\n" -"\n"); - -#define SYS__GETQUICKENEDCOUNT_METHODDEF \ - {"_getquickenedcount", (PyCFunction)sys__getquickenedcount, METH_NOARGS, sys__getquickenedcount__doc__}, - -static Py_ssize_t -sys__getquickenedcount_impl(PyObject *module); - -static PyObject * -sys__getquickenedcount(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - PyObject *return_value = NULL; - Py_ssize_t _return_value; - - _return_value = sys__getquickenedcount_impl(module); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromSsize_t(_return_value); - -exit: - return return_value; -} - PyDoc_STRVAR(sys_getallocatedblocks__doc__, "getallocatedblocks($module, /)\n" "--\n" @@ -780,7 +927,7 @@ PyDoc_STRVAR(sys__getframe__doc__, "only."); #define SYS__GETFRAME_METHODDEF \ - {"_getframe", (PyCFunction)(void(*)(void))sys__getframe, METH_FASTCALL, sys__getframe__doc__}, + {"_getframe", _PyCFunction_CAST(sys__getframe), METH_FASTCALL, sys__getframe__doc__}, static PyObject * sys__getframe_impl(PyObject *module, int depth); @@ -859,7 +1006,7 @@ PyDoc_STRVAR(sys_call_tracing__doc__, "some other code."); #define SYS_CALL_TRACING_METHODDEF \ - {"call_tracing", (PyCFunction)(void(*)(void))sys_call_tracing, METH_FASTCALL, sys_call_tracing__doc__}, + {"call_tracing", _PyCFunction_CAST(sys_call_tracing), METH_FASTCALL, sys_call_tracing__doc__}, static PyObject * sys_call_tracing_impl(PyObject *module, PyObject *func, PyObject *funcargs); @@ -943,6 +1090,94 @@ sys_is_finalizing(PyObject *module, PyObject *Py_UNUSED(ignored)) return sys_is_finalizing_impl(module); } +#if defined(Py_STATS) + +PyDoc_STRVAR(sys__stats_on__doc__, +"_stats_on($module, /)\n" +"--\n" +"\n" +"Turns on stats gathering (stats gathering is on by default)."); + +#define SYS__STATS_ON_METHODDEF \ + {"_stats_on", (PyCFunction)sys__stats_on, METH_NOARGS, sys__stats_on__doc__}, + +static PyObject * +sys__stats_on_impl(PyObject *module); + +static PyObject * +sys__stats_on(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys__stats_on_impl(module); +} + +#endif /* defined(Py_STATS) */ + +#if defined(Py_STATS) + +PyDoc_STRVAR(sys__stats_off__doc__, +"_stats_off($module, /)\n" +"--\n" +"\n" +"Turns off stats gathering (stats gathering is on by default)."); + +#define SYS__STATS_OFF_METHODDEF \ + {"_stats_off", (PyCFunction)sys__stats_off, METH_NOARGS, sys__stats_off__doc__}, + +static PyObject * +sys__stats_off_impl(PyObject *module); + +static PyObject * +sys__stats_off(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys__stats_off_impl(module); +} + +#endif /* defined(Py_STATS) */ + +#if defined(Py_STATS) + +PyDoc_STRVAR(sys__stats_clear__doc__, +"_stats_clear($module, /)\n" +"--\n" +"\n" +"Clears the stats."); + +#define SYS__STATS_CLEAR_METHODDEF \ + {"_stats_clear", (PyCFunction)sys__stats_clear, METH_NOARGS, sys__stats_clear__doc__}, + +static PyObject * +sys__stats_clear_impl(PyObject *module); + +static PyObject * +sys__stats_clear(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys__stats_clear_impl(module); +} + +#endif /* defined(Py_STATS) */ + +#if defined(Py_STATS) + +PyDoc_STRVAR(sys__stats_dump__doc__, +"_stats_dump($module, /)\n" +"--\n" +"\n" +"Dump stats to file, and clears the stats."); + +#define SYS__STATS_DUMP_METHODDEF \ + {"_stats_dump", (PyCFunction)sys__stats_dump, METH_NOARGS, sys__stats_dump__doc__}, + +static PyObject * +sys__stats_dump_impl(PyObject *module); + +static PyObject * +sys__stats_dump(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys__stats_dump_impl(module); +} + +#endif /* defined(Py_STATS) */ + #if defined(ANDROID_API_LEVEL) PyDoc_STRVAR(sys_getandroidapilevel__doc__, @@ -965,6 +1200,150 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #endif /* defined(ANDROID_API_LEVEL) */ +PyDoc_STRVAR(sys_activate_stack_trampoline__doc__, +"activate_stack_trampoline($module, backend, /)\n" +"--\n" +"\n" +"Activate stack profiler trampoline *backend*."); + +#define SYS_ACTIVATE_STACK_TRAMPOLINE_METHODDEF \ + {"activate_stack_trampoline", (PyCFunction)sys_activate_stack_trampoline, METH_O, sys_activate_stack_trampoline__doc__}, + +static PyObject * +sys_activate_stack_trampoline_impl(PyObject *module, const char *backend); + +static PyObject * +sys_activate_stack_trampoline(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *backend; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("activate_stack_trampoline", "argument", "str", arg); + goto exit; + } + Py_ssize_t backend_length; + backend = PyUnicode_AsUTF8AndSize(arg, &backend_length); + if (backend == NULL) { + goto exit; + } + if (strlen(backend) != (size_t)backend_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = sys_activate_stack_trampoline_impl(module, backend); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys_deactivate_stack_trampoline__doc__, +"deactivate_stack_trampoline($module, /)\n" +"--\n" +"\n" +"Deactivate the current stack profiler trampoline backend.\n" +"\n" +"If no stack profiler is activated, this function has no effect."); + +#define SYS_DEACTIVATE_STACK_TRAMPOLINE_METHODDEF \ + {"deactivate_stack_trampoline", (PyCFunction)sys_deactivate_stack_trampoline, METH_NOARGS, sys_deactivate_stack_trampoline__doc__}, + +static PyObject * +sys_deactivate_stack_trampoline_impl(PyObject *module); + +static PyObject * +sys_deactivate_stack_trampoline(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_deactivate_stack_trampoline_impl(module); +} + +PyDoc_STRVAR(sys_is_stack_trampoline_active__doc__, +"is_stack_trampoline_active($module, /)\n" +"--\n" +"\n" +"Return *True* if a stack profiler trampoline is active."); + +#define SYS_IS_STACK_TRAMPOLINE_ACTIVE_METHODDEF \ + {"is_stack_trampoline_active", (PyCFunction)sys_is_stack_trampoline_active, METH_NOARGS, sys_is_stack_trampoline_active__doc__}, + +static PyObject * +sys_is_stack_trampoline_active_impl(PyObject *module); + +static PyObject * +sys_is_stack_trampoline_active(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_is_stack_trampoline_active_impl(module); +} + +PyDoc_STRVAR(sys__getframemodulename__doc__, +"_getframemodulename($module, /, depth=0)\n" +"--\n" +"\n" +"Return the name of the module for a calling frame.\n" +"\n" +"The default depth returns the module containing the call to this API.\n" +"A more typical use in a library will pass a depth of 1 to get the user\'s\n" +"module rather than the library module.\n" +"\n" +"If no frame, module, or name can be found, returns None."); + +#define SYS__GETFRAMEMODULENAME_METHODDEF \ + {"_getframemodulename", _PyCFunction_CAST(sys__getframemodulename), METH_FASTCALL|METH_KEYWORDS, sys__getframemodulename__doc__}, + +static PyObject * +sys__getframemodulename_impl(PyObject *module, int depth); + +static PyObject * +sys__getframemodulename(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(depth), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"depth", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_getframemodulename", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int depth = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + depth = _PyLong_AsInt(args[0]); + if (depth == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = sys__getframemodulename_impl(module, depth); + +exit: + return return_value; +} + #ifndef SYS_GETWINDOWSVERSION_METHODDEF #define SYS_GETWINDOWSVERSION_METHODDEF #endif /* !defined(SYS_GETWINDOWSVERSION_METHODDEF) */ @@ -989,7 +1368,23 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #define SYS_GETTOTALREFCOUNT_METHODDEF #endif /* !defined(SYS_GETTOTALREFCOUNT_METHODDEF) */ +#ifndef SYS__STATS_ON_METHODDEF + #define SYS__STATS_ON_METHODDEF +#endif /* !defined(SYS__STATS_ON_METHODDEF) */ + +#ifndef SYS__STATS_OFF_METHODDEF + #define SYS__STATS_OFF_METHODDEF +#endif /* !defined(SYS__STATS_OFF_METHODDEF) */ + +#ifndef SYS__STATS_CLEAR_METHODDEF + #define SYS__STATS_CLEAR_METHODDEF +#endif /* !defined(SYS__STATS_CLEAR_METHODDEF) */ + +#ifndef SYS__STATS_DUMP_METHODDEF + #define SYS__STATS_DUMP_METHODDEF +#endif /* !defined(SYS__STATS_DUMP_METHODDEF) */ + #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=855fc93b2347710b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5c761f14326ced54 input=a9049054013a1b77]*/ diff --git a/Python/clinic/traceback.c.h b/Python/clinic/traceback.c.h index 404a0c416d3..3c344934971 100644 --- a/Python/clinic/traceback.c.h +++ b/Python/clinic/traceback.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(tb_new__doc__, "TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno)\n" "--\n" @@ -16,8 +22,31 @@ static PyObject * tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tb_next), &_Py_ID(tb_frame), &_Py_ID(tb_lasti), &_Py_ID(tb_lineno), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"tb_next", "tb_frame", "tb_lasti", "tb_lineno", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "TracebackType", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "TracebackType", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -49,4 +78,4 @@ tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=403778d7af5ebef9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7bc9927e362fdfb7 input=a9049054013a1b77]*/ diff --git a/Python/codecs.c b/Python/codecs.c index b7c8db7e8b6..b2087b499df 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -235,8 +235,7 @@ PyObject *args_tuple(PyObject *object, args = PyTuple_New(1 + (errors != NULL)); if (args == NULL) return NULL; - Py_INCREF(object); - PyTuple_SET_ITEM(args,0,object); + PyTuple_SET_ITEM(args, 0, Py_NewRef(object)); if (errors) { PyObject *v; @@ -263,8 +262,7 @@ PyObject *codec_getitem(const char *encoding, int index) return NULL; v = PyTuple_GET_ITEM(codecs, index); Py_DECREF(codecs); - Py_INCREF(v); - return v; + return Py_NewRef(v); } /* Helper functions to create an incremental codec. */ @@ -430,8 +428,7 @@ _PyCodec_EncodeInternal(PyObject *object, "encoder must return a tuple (object, integer)"); goto onError; } - v = PyTuple_GET_ITEM(result,0); - Py_INCREF(v); + v = Py_NewRef(PyTuple_GET_ITEM(result,0)); /* We don't check or use the second (integer) entry. */ Py_DECREF(args); @@ -475,8 +472,7 @@ _PyCodec_DecodeInternal(PyObject *object, "decoder must return a tuple (object,integer)"); goto onError; } - v = PyTuple_GET_ITEM(result,0); - Py_INCREF(v); + v = Py_NewRef(PyTuple_GET_ITEM(result,0)); /* We don't check or use the second (integer) entry. */ Py_DECREF(args); @@ -522,7 +518,6 @@ PyObject *PyCodec_Decode(PyObject *object, PyObject * _PyCodec_LookupTextEncoding(const char *encoding, const char *alternate_command) { - _Py_IDENTIFIER(_is_text_encoding); PyObject *codec; PyObject *attr; int is_text_codec; @@ -536,7 +531,7 @@ PyObject * _PyCodec_LookupTextEncoding(const char *encoding, * attribute. */ if (!PyTuple_CheckExact(codec)) { - if (_PyObject_LookupAttrId(codec, &PyId__is_text_encoding, &attr) < 0) { + if (_PyObject_LookupAttr(codec, &_Py_ID(_is_text_encoding), &attr) < 0) { Py_DECREF(codec); return NULL; } @@ -572,8 +567,7 @@ PyObject *codec_getitem_checked(const char *encoding, if (codec == NULL) return NULL; - v = PyTuple_GET_ITEM(codec, index); - Py_INCREF(v); + v = Py_NewRef(PyTuple_GET_ITEM(codec, index)); Py_DECREF(codec); return v; } @@ -1527,7 +1521,7 @@ static int _PyCodecRegistry_Init(void) } } - mod = PyImport_ImportModuleNoBlock("encodings"); + mod = PyImport_ImportModule("encodings"); if (mod == NULL) { return -1; } diff --git a/Python/compile.c b/Python/compile.c index 40bd1fde0a9..c31f08c0a17 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -23,21 +23,23 @@ #include +// Need _PyOpcode_RelativeJump of pycore_opcode.h +#define NEED_OPCODE_TABLES + #include "Python.h" #include "pycore_ast.h" // _PyAST_GetDocString() -#include "pycore_compile.h" // _PyFuture_FromAST() #include "pycore_code.h" // _PyCode_New() -#include "pycore_pymem.h" // _PyMem_IsPtrFreed() +#include "pycore_compile.h" // _PyFuture_FromAST() +#include "pycore_intrinsics.h" #include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_opcode.h" // _PyOpcode_Caches +#include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_symtable.h" // PySTEntryObject -#define NEED_OPCODE_JUMP_TABLES -#include "opcode.h" // EXTENDED_ARG -#include "wordcode_helpers.h" // instrsize() +#include "opcode_metadata.h" // _PyOpcode_opcode_metadata, _PyOpcode_num_popped/pushed #define DEFAULT_BLOCK_SIZE 16 -#define DEFAULT_BLOCKS 8 #define DEFAULT_CODE_SIZE 128 #define DEFAULT_LNOTAB_SIZE 16 #define DEFAULT_CNOTAB_SIZE 32 @@ -56,6 +58,16 @@ */ #define STACK_USE_GUIDELINE 30 +#undef SUCCESS +#undef ERROR +#define SUCCESS 0 +#define ERROR -1 + +#define RETURN_IF_ERROR(X) \ + if ((X) == -1) { \ + return ERROR; \ + } + /* If we exceed this limit, it should * be considered a compiler bug. * Currently it should be impossible @@ -72,34 +84,132 @@ #define MAX_ALLOWED_STACK_USE (STACK_USE_GUIDELINE * 100) -/* Pseudo-instructions used in the compiler, - * but turned into NOPs by the assembler. */ -#define SETUP_FINALLY 255 -#define SETUP_CLEANUP 254 -#define SETUP_WITH 253 -#define POP_BLOCK 252 +#define MAX_REAL_OPCODE 254 -#define IS_TOP_LEVEL_AWAIT(c) ( \ - (c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) \ - && (c->u->u_ste->ste_type == ModuleBlock)) +#define IS_WITHIN_OPCODE_RANGE(opcode) \ + (((opcode) >= 0 && (opcode) <= MAX_REAL_OPCODE) || \ + IS_PSEUDO_OPCODE(opcode)) + +#define IS_JUMP_OPCODE(opcode) \ + is_bit_set_in_table(_PyOpcode_Jump, opcode) + +#define IS_BLOCK_PUSH_OPCODE(opcode) \ + ((opcode) == SETUP_FINALLY || \ + (opcode) == SETUP_WITH || \ + (opcode) == SETUP_CLEANUP) + +#define HAS_TARGET(opcode) \ + (IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode)) + +/* opcodes that must be last in the basicblock */ +#define IS_TERMINATOR_OPCODE(opcode) \ + (IS_JUMP_OPCODE(opcode) || IS_SCOPE_EXIT_OPCODE(opcode)) + +/* opcodes which are not emitted in codegen stage, only by the assembler */ +#define IS_ASSEMBLER_OPCODE(opcode) \ + ((opcode) == JUMP_FORWARD || \ + (opcode) == JUMP_BACKWARD || \ + (opcode) == JUMP_BACKWARD_NO_INTERRUPT) + +#define IS_BACKWARDS_JUMP_OPCODE(opcode) \ + ((opcode) == JUMP_BACKWARD || \ + (opcode) == JUMP_BACKWARD_NO_INTERRUPT) + +#define IS_UNCONDITIONAL_JUMP_OPCODE(opcode) \ + ((opcode) == JUMP || \ + (opcode) == JUMP_NO_INTERRUPT || \ + (opcode) == JUMP_FORWARD || \ + (opcode) == JUMP_BACKWARD || \ + (opcode) == JUMP_BACKWARD_NO_INTERRUPT) + +#define IS_SCOPE_EXIT_OPCODE(opcode) \ + ((opcode) == RETURN_VALUE || \ + (opcode) == RAISE_VARARGS || \ + (opcode) == RERAISE) + +#define IS_SUPERINSTRUCTION_OPCODE(opcode) \ + ((opcode) == LOAD_FAST__LOAD_FAST || \ + (opcode) == LOAD_FAST__LOAD_CONST || \ + (opcode) == LOAD_CONST__LOAD_FAST || \ + (opcode) == STORE_FAST__LOAD_FAST || \ + (opcode) == STORE_FAST__STORE_FAST) + +#define IS_TOP_LEVEL_AWAIT(C) ( \ + ((C)->c_flags.cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) \ + && ((C)->u->u_ste->ste_type == ModuleBlock)) + +typedef _PyCompilerSrcLocation location; + +#define LOCATION(LNO, END_LNO, COL, END_COL) \ + ((const location){(LNO), (END_LNO), (COL), (END_COL)}) + +static location NO_LOCATION = {-1, -1, -1, -1}; + +/* Return true if loc1 starts after loc2 ends. */ +static inline bool +location_is_after(location loc1, location loc2) { + return (loc1.lineno > loc2.end_lineno) || + ((loc1.lineno == loc2.end_lineno) && + (loc1.col_offset > loc2.end_col_offset)); +} + +static inline bool +same_location(location a, location b) +{ + return a.lineno == b.lineno && + a.end_lineno == b.end_lineno && + a.col_offset == b.col_offset && + a.end_col_offset == b.end_col_offset; +} + +#define LOC(x) SRC_LOCATION_FROM_AST(x) + +typedef struct jump_target_label_ { + int id; +} jump_target_label; + +static struct jump_target_label_ NO_LABEL = {-1}; + +#define SAME_LABEL(L1, L2) ((L1).id == (L2).id) +#define IS_LABEL(L) (!SAME_LABEL((L), (NO_LABEL))) + +#define NEW_JUMP_TARGET_LABEL(C, NAME) \ + jump_target_label NAME = cfg_new_label(CFG_BUILDER(C)); \ + if (!IS_LABEL(NAME)) { \ + return 0; \ + } + +#define USE_LABEL(C, LBL) \ + if (cfg_builder_use_label(CFG_BUILDER(C), LBL) < 0) { \ + return 0; \ + } struct instr { - unsigned char i_opcode; + int i_opcode; int i_oparg; - /* target block (if jump instruction) */ - struct basicblock_ *i_target; - /* target block when exception is raised, should not be set by front-end. */ - struct basicblock_ *i_except; - int i_lineno; - int i_end_lineno; - int i_col_offset; - int i_end_col_offset; + location i_loc; + /* The following fields should not be set by the front-end: */ + struct basicblock_ *i_target; /* target block (if jump instruction) */ + struct basicblock_ *i_except; /* target block when exception is raised */ }; -typedef struct excepthandler { - struct instr *setup; - int offset; -} ExceptHandler; +/* One arg*/ +#define INSTR_SET_OP1(I, OP, ARG) \ + do { \ + assert(HAS_ARG(OP)); \ + struct instr *_instr__ptr_ = (I); \ + _instr__ptr_->i_opcode = (OP); \ + _instr__ptr_->i_oparg = (ARG); \ + } while (0); + +/* No args*/ +#define INSTR_SET_OP0(I, OP) \ + do { \ + assert(!HAS_ARG(OP)); \ + struct instr *_instr__ptr_ = (I); \ + _instr__ptr_->i_opcode = (OP); \ + _instr__ptr_->i_oparg = 0; \ + } while (0); typedef struct exceptstack { struct basicblock_ *handlers[CO_MAXBLOCKS+1]; @@ -110,14 +220,19 @@ typedef struct exceptstack { #define MASK_LOW_LOG_BITS 31 static inline int -is_bit_set_in_table(uint32_t *table, int bitindex) { +is_bit_set_in_table(const uint32_t *table, int bitindex) { /* Is the relevant bit set in the relevant word? */ - /* 256 bits fit into 8 32-bits words. + /* 512 bits fit into 9 32-bits words. * Word is indexed by (bitindex>>ln(size of int in bits)). * Bit within word is the low bits of bitindex. */ - uint32_t word = table[bitindex >> LOG_BITS_PER_INT]; - return (word >> (bitindex & MASK_LOW_LOG_BITS)) & 1; + if (bitindex >= 0 && bitindex < 512) { + uint32_t word = table[bitindex >> LOG_BITS_PER_INT]; + return (word >> (bitindex & MASK_LOW_LOG_BITS)) & 1; + } + else { + return 0; + } } static inline int @@ -126,10 +241,67 @@ is_relative_jump(struct instr *i) return is_bit_set_in_table(_PyOpcode_RelativeJump, i->i_opcode); } +static inline int +is_block_push(struct instr *i) +{ + return IS_BLOCK_PUSH_OPCODE(i->i_opcode); +} + static inline int is_jump(struct instr *i) { - return i->i_opcode >= SETUP_WITH || is_bit_set_in_table(_PyOpcode_Jump, i->i_opcode); + return IS_JUMP_OPCODE(i->i_opcode); +} + +static int +instr_size(struct instr *instruction) +{ + int opcode = instruction->i_opcode; + assert(!IS_PSEUDO_OPCODE(opcode)); + int oparg = instruction->i_oparg; + assert(HAS_ARG(opcode) || oparg == 0); + int extended_args = (0xFFFFFF < oparg) + (0xFFFF < oparg) + (0xFF < oparg); + int caches = _PyOpcode_Caches[opcode]; + return extended_args + 1 + caches; +} + +static void +write_instr(_Py_CODEUNIT *codestr, struct instr *instruction, int ilen) +{ + int opcode = instruction->i_opcode; + assert(!IS_PSEUDO_OPCODE(opcode)); + int oparg = instruction->i_oparg; + assert(HAS_ARG(opcode) || oparg == 0); + int caches = _PyOpcode_Caches[opcode]; + switch (ilen - caches) { + case 4: + codestr->opcode = EXTENDED_ARG; + codestr->oparg = (oparg >> 24) & 0xFF; + codestr++; + /* fall through */ + case 3: + codestr->opcode = EXTENDED_ARG; + codestr->oparg = (oparg >> 16) & 0xFF; + codestr++; + /* fall through */ + case 2: + codestr->opcode = EXTENDED_ARG; + codestr->oparg = (oparg >> 8) & 0xFF; + codestr++; + /* fall through */ + case 1: + codestr->opcode = opcode; + codestr->oparg = oparg & 0xFF; + codestr++; + break; + default: + Py_UNREACHABLE(); + } + while (caches--) { + codestr->opcode = CACHE; + codestr->oparg = 0; + codestr++; + } } typedef struct basicblock_ { @@ -137,35 +309,73 @@ typedef struct basicblock_ { reverse order that the block are allocated. b_list points to the next block, not to be confused with b_next, which is next by control flow. */ struct basicblock_ *b_list; - /* number of instructions used */ - int b_iused; - /* length of instruction array (b_instr) */ - int b_ialloc; + /* The label of this block if it is a jump target, -1 otherwise */ + int b_label; + /* Exception stack at start of block, used by assembler to create the exception handling table */ + ExceptStack *b_exceptstack; /* pointer to an array of instructions, initially NULL */ struct instr *b_instr; /* If b_next is non-NULL, it is a pointer to the next block reached by normal control flow. */ struct basicblock_ *b_next; - /* b_return is true if a RETURN_VALUE opcode is inserted. */ - unsigned b_return : 1; - /* Number of predecssors that a block has. */ + /* number of instructions used */ + int b_iused; + /* length of instruction array (b_instr) */ + int b_ialloc; + /* Used by add_checks_for_loads_of_unknown_variables */ + uint64_t b_unsafe_locals_mask; + /* Number of predecessors that a block has. */ int b_predecessors; - /* Basic block has no fall through (it ends with a return, raise or jump) */ - unsigned b_nofallthrough : 1; - /* Basic block is an exception handler that preserves lasti */ - unsigned b_preserve_lasti : 1; - /* Used by compiler passes to mark whether they have visited a basic block. */ - unsigned b_visited : 1; - /* Basic block exits scope (it ends with a return or raise) */ - unsigned b_exit : 1; /* depth of stack upon entry of block, computed by stackdepth() */ int b_startdepth; /* instruction offset for block, computed by assemble_jump_offsets() */ int b_offset; - /* Exception stack at start of block, used by assembler to create the exception handling table */ - ExceptStack *b_exceptstack; + /* Basic block is an exception handler that preserves lasti */ + unsigned b_preserve_lasti : 1; + /* Used by compiler passes to mark whether they have visited a basic block. */ + unsigned b_visited : 1; + /* b_except_handler is used by the cold-detection algorithm to mark exception targets */ + unsigned b_except_handler : 1; + /* b_cold is true if this block is not perf critical (like an exception handler) */ + unsigned b_cold : 1; + /* b_warm is used by the cold-detection algorithm to mark blocks which are definitely not cold */ + unsigned b_warm : 1; } basicblock; + +static struct instr * +basicblock_last_instr(const basicblock *b) { + assert(b->b_iused >= 0); + if (b->b_iused > 0) { + assert(b->b_instr != NULL); + return &b->b_instr[b->b_iused - 1]; + } + return NULL; +} + +static inline int +basicblock_returns(const basicblock *b) { + struct instr *last = basicblock_last_instr(b); + return last && last->i_opcode == RETURN_VALUE; +} + +static inline int +basicblock_exits_scope(const basicblock *b) { + struct instr *last = basicblock_last_instr(b); + return last && IS_SCOPE_EXIT_OPCODE(last->i_opcode); +} + +static inline int +basicblock_nofallthrough(const basicblock *b) { + struct instr *last = basicblock_last_instr(b); + return (last && + (IS_SCOPE_EXIT_OPCODE(last->i_opcode) || + IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode))); +} + +#define BB_NO_FALLTHROUGH(B) (basicblock_nofallthrough(B)) +#define BB_HAS_FALLTHROUGH(B) (!basicblock_nofallthrough(B)) + /* fblockinfo tracks the current frame block. A frame block is used to handle loops, try/except, and try/finally. @@ -175,13 +385,13 @@ compiler IR. enum fblocktype { WHILE_LOOP, FOR_LOOP, TRY_EXCEPT, FINALLY_TRY, FINALLY_END, WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE, EXCEPTION_HANDLER, - ASYNC_COMPREHENSION_GENERATOR }; + EXCEPTION_GROUP_HANDLER, ASYNC_COMPREHENSION_GENERATOR }; struct fblockinfo { enum fblocktype fb_type; - basicblock *fb_block; + jump_target_label fb_block; /* (optional) type-specific exit or cleanup block */ - basicblock *fb_exit; + jump_target_label fb_exit; /* (optional) additional information required for unwinding */ void *fb_datum; }; @@ -195,6 +405,21 @@ enum { COMPILER_SCOPE_COMPREHENSION, }; +typedef struct cfg_builder_ { + /* The entryblock, at which control flow begins. All blocks of the + CFG are reachable through the b_next links */ + basicblock *g_entryblock; + /* Pointer to the most recently allocated block. By following + b_list links, you can reach all allocated blocks. */ + basicblock *g_block_list; + /* pointer to the block currently being constructed */ + basicblock *g_curblock; + /* label for the next instruction to be placed */ + jump_target_label g_current_label; + /* next free label id */ + int g_next_free_label; +} cfg_builder; + /* The following items change on entry and exit of code blocks. They must be saved and restored when returning to a block. */ @@ -220,19 +445,13 @@ struct compiler_unit { Py_ssize_t u_argcount; /* number of arguments for block */ Py_ssize_t u_posonlyargcount; /* number of positional only arguments for block */ Py_ssize_t u_kwonlyargcount; /* number of keyword only arguments for block */ - /* Pointer to the most recently allocated block. By following b_list - members, you can reach all early allocated blocks. */ - basicblock *u_blocks; - basicblock *u_curblock; /* pointer to current block */ + + cfg_builder u_cfg_builder; /* The control flow graph */ int u_nfblocks; struct fblockinfo u_fblock[CO_MAXBLOCKS]; int u_firstlineno; /* the first lineno of the block */ - int u_lineno; /* the lineno for the current stmt */ - int u_col_offset; /* the offset of the current stmt */ - int u_end_lineno; /* the end line of the current stmt */ - int u_end_col_offset; /* the end offset of the current stmt */ }; /* This struct captures the global state of a compilation. @@ -250,8 +469,8 @@ handled by the symbol analysis pass. struct compiler { PyObject *c_filename; struct symtable *c_st; - PyFutureFeatures *c_future; /* pointer to module's __future__ */ - PyCompilerFlags *c_flags; + PyFutureFeatures c_future; /* module's __future__ */ + PyCompilerFlags c_flags; int c_optimize; /* optimization level */ int c_interactive; /* true if in interactive mode */ @@ -263,6 +482,9 @@ struct compiler { PyArena *c_arena; /* pointer to memory allocation arena */ }; +#define CFG_BUILDER(C) (&((C)->u->u_cfg_builder)) + + typedef struct { // A list of strings corresponding to name captures. It is used to track: // - Repeated name assignments in the same pattern. @@ -279,7 +501,7 @@ typedef struct { // fail_pop[2]: POP_TOP // fail_pop[1]: POP_TOP // fail_pop[0]: NOP - basicblock **fail_pop; + jump_target_label *fail_pop; // The current length of fail_pop. Py_ssize_t fail_pop_size; // The number of items on top of the stack that need to *stay* on top of the @@ -288,17 +510,16 @@ typedef struct { Py_ssize_t on_top; } pattern_context; -static int compiler_enter_scope(struct compiler *, identifier, int, void *, int); +static int basicblock_next_instr(basicblock *); + +static basicblock *cfg_builder_new_block(cfg_builder *g); +static int cfg_builder_maybe_start_new_block(cfg_builder *g); +static int cfg_builder_addop_i(cfg_builder *g, int opcode, Py_ssize_t oparg, location loc); + static void compiler_free(struct compiler *); -static basicblock *compiler_new_block(struct compiler *); -static int compiler_next_instr(basicblock *); -static int compiler_addop(struct compiler *, int); -static int compiler_addop_i(struct compiler *, int, Py_ssize_t); -static int compiler_addop_j(struct compiler *, int, basicblock *); -static int compiler_addop_j_noline(struct compiler *, int, basicblock *); -static int compiler_error(struct compiler *, const char *, ...); -static int compiler_warn(struct compiler *, const char *, ...); -static int compiler_nameop(struct compiler *, identifier, expr_context_ty); +static int compiler_error(struct compiler *, location loc, const char *, ...); +static int compiler_warn(struct compiler *, location loc, const char *, ...); +static int compiler_nameop(struct compiler *, location, identifier, expr_context_ty); static PyCodeObject *compiler_mod(struct compiler *, mod_ty); static int compiler_visit_stmt(struct compiler *, stmt_ty); @@ -309,40 +530,41 @@ static int compiler_annassign(struct compiler *, stmt_ty); static int compiler_subscript(struct compiler *, expr_ty); static int compiler_slice(struct compiler *, expr_ty); -static int are_all_items_const(asdl_expr_seq *, Py_ssize_t, Py_ssize_t); +static bool are_all_items_const(asdl_expr_seq *, Py_ssize_t, Py_ssize_t); static int compiler_with(struct compiler *, stmt_ty, int); static int compiler_async_with(struct compiler *, stmt_ty, int); static int compiler_async_for(struct compiler *, stmt_ty); -static int validate_keywords(struct compiler *c, asdl_keyword_seq *keywords); static int compiler_call_simple_kw_helper(struct compiler *c, + location loc, asdl_keyword_seq *keywords, Py_ssize_t nkwelts); -static int compiler_call_helper(struct compiler *c, int n, - asdl_expr_seq *args, +static int compiler_call_helper(struct compiler *c, location loc, + int n, asdl_expr_seq *args, asdl_keyword_seq *keywords); static int compiler_try_except(struct compiler *, stmt_ty); +static int compiler_try_star_except(struct compiler *, stmt_ty); static int compiler_set_qualname(struct compiler *); static int compiler_sync_comprehension_generator( - struct compiler *c, + struct compiler *c, location loc, asdl_comprehension_seq *generators, int gen_index, int depth, expr_ty elt, expr_ty val, int type); static int compiler_async_comprehension_generator( - struct compiler *c, + struct compiler *c, location loc, asdl_comprehension_seq *generators, int gen_index, int depth, expr_ty elt, expr_ty val, int type); static int compiler_pattern(struct compiler *, pattern_ty, pattern_context *); static int compiler_match(struct compiler *, stmt_ty); -static int compiler_pattern_subpattern(struct compiler *, pattern_ty, - pattern_context *); +static int compiler_pattern_subpattern(struct compiler *, + pattern_ty, pattern_context *); -static void clean_basic_block(basicblock *bb); +static int remove_redundant_nops(basicblock *bb); static PyCodeObject *assemble(struct compiler *, int addNone); @@ -359,8 +581,7 @@ _Py_Mangle(PyObject *privateobj, PyObject *ident) if (privateobj == NULL || !PyUnicode_Check(privateobj) || PyUnicode_READ_CHAR(ident, 0) != '_' || PyUnicode_READ_CHAR(ident, 1) != '_') { - Py_INCREF(ident); - return ident; + return Py_NewRef(ident); } nlen = PyUnicode_GET_LENGTH(ident); plen = PyUnicode_GET_LENGTH(privateobj); @@ -376,16 +597,14 @@ _Py_Mangle(PyObject *privateobj, PyObject *ident) if ((PyUnicode_READ_CHAR(ident, nlen-1) == '_' && PyUnicode_READ_CHAR(ident, nlen-2) == '_') || PyUnicode_FindChar(ident, '.', 0, nlen, 1) != -1) { - Py_INCREF(ident); - return ident; /* Don't mangle __whatever__ */ + return Py_NewRef(ident); /* Don't mangle __whatever__ */ } /* Strip leading underscores from class name */ ipriv = 0; while (PyUnicode_READ_CHAR(privateobj, ipriv) == '_') ipriv++; if (ipriv == plen) { - Py_INCREF(ident); - return ident; /* Don't mangle if class is just underscores */ + return Py_NewRef(ident); /* Don't mangle if class is just underscores */ } plen -= ipriv; @@ -416,70 +635,77 @@ _Py_Mangle(PyObject *privateobj, PyObject *ident) return result; } -static int -compiler_init(struct compiler *c) -{ - memset(c, 0, sizeof(struct compiler)); +static int +compiler_setup(struct compiler *c, mod_ty mod, PyObject *filename, + PyCompilerFlags flags, int optimize, PyArena *arena) +{ c->c_const_cache = PyDict_New(); if (!c->c_const_cache) { - return 0; + return ERROR; } c->c_stack = PyList_New(0); if (!c->c_stack) { - Py_CLEAR(c->c_const_cache); - return 0; + return ERROR; } - return 1; -} - -PyCodeObject * -_PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, - int optimize, PyArena *arena) -{ - struct compiler c; - PyCodeObject *co = NULL; - PyCompilerFlags local_flags = _PyCompilerFlags_INIT; - int merged; - if (!compiler_init(&c)) - return NULL; - Py_INCREF(filename); - c.c_filename = filename; - c.c_arena = arena; - c.c_future = _PyFuture_FromAST(mod, filename); - if (c.c_future == NULL) - goto finally; - if (!flags) { - flags = &local_flags; + c->c_filename = Py_NewRef(filename); + c->c_arena = arena; + if (!_PyFuture_FromAST(mod, filename, &c->c_future)) { + return ERROR; } - merged = c.c_future->ff_features | flags->cf_flags; - c.c_future->ff_features = merged; - flags->cf_flags = merged; - c.c_flags = flags; - c.c_optimize = (optimize == -1) ? _Py_GetConfig()->optimization_level : optimize; - c.c_nestlevel = 0; + int merged = c->c_future.ff_features | flags.cf_flags; + c->c_future.ff_features = merged; + flags.cf_flags = merged; + c->c_flags = flags; + c->c_optimize = (optimize == -1) ? _Py_GetConfig()->optimization_level : optimize; + c->c_nestlevel = 0; _PyASTOptimizeState state; - state.optimize = c.c_optimize; + state.optimize = c->c_optimize; state.ff_features = merged; if (!_PyAST_Optimize(mod, arena, &state)) { - goto finally; + return ERROR; } - - c.c_st = _PySymtable_Build(mod, filename, c.c_future); - if (c.c_st == NULL) { - if (!PyErr_Occurred()) + c->c_st = _PySymtable_Build(mod, filename, &c->c_future); + if (c->c_st == NULL) { + if (!PyErr_Occurred()) { PyErr_SetString(PyExc_SystemError, "no symtable"); - goto finally; + } + return ERROR; + } + return SUCCESS; +} + +static struct compiler* +new_compiler(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags, + int optimize, PyArena *arena) +{ + PyCompilerFlags flags = pflags ? *pflags : _PyCompilerFlags_INIT; + struct compiler *c = PyMem_Calloc(1, sizeof(struct compiler)); + if (c == NULL) { + return NULL; + } + if (compiler_setup(c, mod, filename, flags, optimize, arena) < 0) { + compiler_free(c); + return NULL; + } + return c; +} + +PyCodeObject * +_PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags, + int optimize, PyArena *arena) +{ + struct compiler *c = new_compiler(mod, filename, pflags, optimize, arena); + if (c == NULL) { + return NULL; } - co = compiler_mod(&c, mod); - - finally: - compiler_free(&c); + PyCodeObject *co = compiler_mod(c, mod); + compiler_free(c); assert(co || PyErr_Occurred()); return co; } @@ -489,11 +715,10 @@ compiler_free(struct compiler *c) { if (c->c_st) _PySymtable_Free(c->c_st); - if (c->c_future) - PyObject_Free(c->c_future); Py_XDECREF(c->c_filename); - Py_DECREF(c->c_const_cache); - Py_DECREF(c->c_stack); + Py_XDECREF(c->c_const_cache); + Py_XDECREF(c->c_stack); + PyMem_Free(c); } static PyObject * @@ -586,10 +811,9 @@ dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset) } static void -compiler_unit_check(struct compiler_unit *u) +cfg_builder_check(cfg_builder *g) { - basicblock *block; - for (block = u->u_blocks; block != NULL; block = block->b_list) { + for (basicblock *block = g->g_block_list; block != NULL; block = block->b_list) { assert(!_PyMem_IsPtrFreed(block)); if (block->b_instr != NULL) { assert(block->b_ialloc > 0); @@ -603,20 +827,38 @@ compiler_unit_check(struct compiler_unit *u) } } -static void -compiler_unit_free(struct compiler_unit *u) +static int +cfg_builder_init(cfg_builder *g) { - basicblock *b, *next; + g->g_block_list = NULL; + basicblock *block = cfg_builder_new_block(g); + if (block == NULL) { + return ERROR; + } + g->g_curblock = g->g_entryblock = block; + g->g_current_label = NO_LABEL; + return SUCCESS; +} - compiler_unit_check(u); - b = u->u_blocks; +static void +cfg_builder_fini(cfg_builder* g) +{ + cfg_builder_check(g); + basicblock *b = g->g_block_list; while (b != NULL) { - if (b->b_instr) + if (b->b_instr) { PyObject_Free((void *)b->b_instr); - next = b->b_list; + } + basicblock *next = b->b_list; PyObject_Free((void *)b); b = next; } +} + +static void +compiler_unit_free(struct compiler_unit *u) +{ + cfg_builder_fini(&u->u_cfg_builder); Py_CLEAR(u->u_ste); Py_CLEAR(u->u_name); Py_CLEAR(u->u_qualname); @@ -629,148 +871,12 @@ compiler_unit_free(struct compiler_unit *u) PyObject_Free(u); } -static int -compiler_enter_scope(struct compiler *c, identifier name, - int scope_type, void *key, int lineno) -{ - struct compiler_unit *u; - basicblock *block; - - u = (struct compiler_unit *)PyObject_Calloc(1, sizeof( - struct compiler_unit)); - if (!u) { - PyErr_NoMemory(); - return 0; - } - u->u_scope_type = scope_type; - u->u_argcount = 0; - u->u_posonlyargcount = 0; - u->u_kwonlyargcount = 0; - u->u_ste = PySymtable_Lookup(c->c_st, key); - if (!u->u_ste) { - compiler_unit_free(u); - return 0; - } - Py_INCREF(name); - u->u_name = name; - u->u_varnames = list2dict(u->u_ste->ste_varnames); - u->u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, 0, 0); - if (!u->u_varnames || !u->u_cellvars) { - compiler_unit_free(u); - return 0; - } - if (u->u_ste->ste_needs_class_closure) { - /* Cook up an implicit __class__ cell. */ - _Py_IDENTIFIER(__class__); - PyObject *name; - int res; - assert(u->u_scope_type == COMPILER_SCOPE_CLASS); - assert(PyDict_GET_SIZE(u->u_cellvars) == 0); - name = _PyUnicode_FromId(&PyId___class__); - if (!name) { - compiler_unit_free(u); - return 0; - } - res = PyDict_SetItem(u->u_cellvars, name, _PyLong_GetZero()); - if (res < 0) { - compiler_unit_free(u); - return 0; - } - } - - u->u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS, - PyDict_GET_SIZE(u->u_cellvars)); - if (!u->u_freevars) { - compiler_unit_free(u); - return 0; - } - - u->u_blocks = NULL; - u->u_nfblocks = 0; - u->u_firstlineno = lineno; - u->u_lineno = 0; - u->u_col_offset = 0; - u->u_end_lineno = 0; - u->u_end_col_offset = 0; - u->u_consts = PyDict_New(); - if (!u->u_consts) { - compiler_unit_free(u); - return 0; - } - u->u_names = PyDict_New(); - if (!u->u_names) { - compiler_unit_free(u); - return 0; - } - - u->u_private = NULL; - - /* Push the old compiler_unit on the stack. */ - if (c->u) { - PyObject *capsule = PyCapsule_New(c->u, CAPSULE_NAME, NULL); - if (!capsule || PyList_Append(c->c_stack, capsule) < 0) { - Py_XDECREF(capsule); - compiler_unit_free(u); - return 0; - } - Py_DECREF(capsule); - u->u_private = c->u->u_private; - Py_XINCREF(u->u_private); - } - c->u = u; - - c->c_nestlevel++; - - block = compiler_new_block(c); - if (block == NULL) - return 0; - c->u->u_curblock = block; - - if (u->u_scope_type != COMPILER_SCOPE_MODULE) { - if (!compiler_set_qualname(c)) - return 0; - } - - return 1; -} - -static void -compiler_exit_scope(struct compiler *c) -{ - // Don't call PySequence_DelItem() with an exception raised - PyObject *exc_type, *exc_val, *exc_tb; - PyErr_Fetch(&exc_type, &exc_val, &exc_tb); - - c->c_nestlevel--; - compiler_unit_free(c->u); - /* Restore c->u to the parent unit. */ - Py_ssize_t n = PyList_GET_SIZE(c->c_stack) - 1; - if (n >= 0) { - PyObject *capsule = PyList_GET_ITEM(c->c_stack, n); - c->u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME); - assert(c->u); - /* we are deleting from a list so this really shouldn't fail */ - if (PySequence_DelItem(c->c_stack, n) < 0) { - _PyErr_WriteUnraisableMsg("on removing the last compiler " - "stack item", NULL); - } - compiler_unit_check(c->u); - } - else { - c->u = NULL; - } - - PyErr_Restore(exc_type, exc_val, exc_tb); -} - static int compiler_set_qualname(struct compiler *c) { - _Py_static_string(dot, "."); - _Py_static_string(dot_locals, "."); Py_ssize_t stack_size; struct compiler_unit *u = c->u; - PyObject *name, *base, *dot_str, *dot_locals_str; + PyObject *name, *base; base = NULL; stack_size = PyList_GET_SIZE(c->c_stack); @@ -789,8 +895,10 @@ compiler_set_qualname(struct compiler *c) || u->u_scope_type == COMPILER_SCOPE_CLASS) { assert(u->u_name); mangled = _Py_Mangle(parent->u_private, u->u_name); - if (!mangled) - return 0; + if (!mangled) { + return ERROR; + } + scope = _PyST_GetScope(parent->u_ste, mangled); Py_DECREF(mangled); assert(scope != GLOBAL_IMPLICIT); @@ -801,107 +909,109 @@ compiler_set_qualname(struct compiler *c) if (!force_global) { if (parent->u_scope_type == COMPILER_SCOPE_FUNCTION || parent->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION - || parent->u_scope_type == COMPILER_SCOPE_LAMBDA) { - dot_locals_str = _PyUnicode_FromId(&dot_locals); - if (dot_locals_str == NULL) - return 0; - base = PyUnicode_Concat(parent->u_qualname, dot_locals_str); - if (base == NULL) - return 0; + || parent->u_scope_type == COMPILER_SCOPE_LAMBDA) + { + _Py_DECLARE_STR(dot_locals, "."); + base = PyUnicode_Concat(parent->u_qualname, + &_Py_STR(dot_locals)); + if (base == NULL) { + return ERROR; + } } else { - Py_INCREF(parent->u_qualname); - base = parent->u_qualname; + base = Py_NewRef(parent->u_qualname); } } } if (base != NULL) { - dot_str = _PyUnicode_FromId(&dot); - if (dot_str == NULL) { - Py_DECREF(base); - return 0; - } - name = PyUnicode_Concat(base, dot_str); + _Py_DECLARE_STR(dot, "."); + name = PyUnicode_Concat(base, &_Py_STR(dot)); Py_DECREF(base); - if (name == NULL) - return 0; + if (name == NULL) { + return ERROR; + } PyUnicode_Append(&name, u->u_name); - if (name == NULL) - return 0; + if (name == NULL) { + return ERROR; + } } else { - Py_INCREF(u->u_name); - name = u->u_name; + name = Py_NewRef(u->u_name); } u->u_qualname = name; - return 1; + return SUCCESS; } +static jump_target_label +cfg_new_label(cfg_builder *g) +{ + jump_target_label lbl = {g->g_next_free_label++}; + return lbl; +} /* Allocate a new block and return a pointer to it. Returns NULL on error. */ - static basicblock * -compiler_new_block(struct compiler *c) +cfg_builder_new_block(cfg_builder *g) { - basicblock *b; - struct compiler_unit *u; - - u = c->u; - b = (basicblock *)PyObject_Calloc(1, sizeof(basicblock)); + basicblock *b = (basicblock *)PyObject_Calloc(1, sizeof(basicblock)); if (b == NULL) { PyErr_NoMemory(); return NULL; } /* Extend the singly linked list of blocks with new block. */ - b->b_list = u->u_blocks; - u->u_blocks = b; + b->b_list = g->g_block_list; + g->g_block_list = b; + b->b_label = -1; return b; } static basicblock * -compiler_next_block(struct compiler *c) -{ - basicblock *block = compiler_new_block(c); - if (block == NULL) - return NULL; - c->u->u_curblock->b_next = block; - c->u->u_curblock = block; - return block; -} - -static basicblock * -compiler_use_next_block(struct compiler *c, basicblock *block) +cfg_builder_use_next_block(cfg_builder *g, basicblock *block) { assert(block != NULL); - c->u->u_curblock->b_next = block; - c->u->u_curblock = block; + g->g_curblock->b_next = block; + g->g_curblock = block; return block; } +static int +cfg_builder_use_label(cfg_builder *g, jump_target_label lbl) +{ + g->g_current_label = lbl; + return cfg_builder_maybe_start_new_block(g); +} + +static inline int +basicblock_append_instructions(basicblock *target, basicblock *source) +{ + for (int i = 0; i < source->b_iused; i++) { + int n = basicblock_next_instr(target); + if (n < 0) { + return -1; + } + target->b_instr[n] = source->b_instr[i]; + } + return 0; +} + static basicblock * -compiler_copy_block(struct compiler *c, basicblock *block) +copy_basicblock(cfg_builder *g, basicblock *block) { /* Cannot copy a block if it has a fallthrough, since * a block can only have one fallthrough predecessor. */ - assert(block->b_nofallthrough); - basicblock *result = compiler_new_block(c); + assert(BB_NO_FALLTHROUGH(block)); + basicblock *result = cfg_builder_new_block(g); if (result == NULL) { return NULL; } - for (int i = 0; i < block->b_iused; i++) { - int n = compiler_next_instr(result); - if (n < 0) { - return NULL; - } - result->b_instr[n] = block->b_instr[i]; + if (basicblock_append_instructions(result, block) < 0) { + return NULL; } - result->b_exit = block->b_exit; - result->b_nofallthrough = 1; return result; } @@ -911,7 +1021,7 @@ compiler_copy_block(struct compiler *c, basicblock *block) */ static int -compiler_next_instr(basicblock *b) +basicblock_next_instr(basicblock *b) { assert(b != NULL); if (b->b_instr == NULL) { @@ -951,33 +1061,6 @@ compiler_next_instr(basicblock *b) return b->b_iused++; } -/* Set the line number and column offset for the following instructions. - - The line number is reset in the following cases: - - when entering a new scope - - on each statement - - on each expression and sub-expression - - before the "except" and "finally" clauses -*/ - -#define SET_LOC(c, x) \ - (c)->u->u_lineno = (x)->lineno; \ - (c)->u->u_col_offset = (x)->col_offset; \ - (c)->u->u_end_lineno = (x)->end_lineno; \ - (c)->u->u_end_col_offset = (x)->end_col_offset; - -// Artificial instructions -#define UNSET_LOC(c) \ - (c)->u->u_lineno = -1; \ - (c)->u->u_col_offset = -1; \ - (c)->u->u_end_lineno = -1; \ - (c)->u->u_end_col_offset = -1; - -#define COPY_INSTR_LOC(old, new) \ - (new).i_lineno = (old).i_lineno; \ - (new).i_col_offset = (old).i_col_offset; \ - (new).i_end_lineno = (old).i_end_lineno; \ - (new).i_end_col_offset = (old).i_end_col_offset; /* Return the stack effect of opcode with argument oparg. @@ -994,22 +1077,19 @@ stack_effect(int opcode, int oparg, int jump) switch (opcode) { case NOP: case EXTENDED_ARG: + case RESUME: + case CACHE: return 0; /* Stack manipulation */ case POP_TOP: return -1; - case ROT_TWO: - case ROT_THREE: - case ROT_FOUR: + case SWAP: return 0; - case DUP_TOP: - return 1; - case DUP_TOP_TWO: - return 2; + case END_FOR: + return -2; /* Unary operators */ - case UNARY_POSITIVE: case UNARY_NEGATIVE: case UNARY_NOT: case UNARY_INVERT: @@ -1023,35 +1103,31 @@ stack_effect(int opcode, int oparg, int jump) case BINARY_SUBSCR: return -1; + case BINARY_SLICE: + return -2; case STORE_SUBSCR: return -3; + case STORE_SLICE: + return -4; case DELETE_SUBSCR: return -2; case GET_ITER: return 0; - case PRINT_EXPR: - return -1; case LOAD_BUILD_CLASS: return 1; case RETURN_VALUE: return -1; - case IMPORT_STAR: - return -1; case SETUP_ANNOTATIONS: return 0; case YIELD_VALUE: return 0; - case YIELD_FROM: - return -1; case POP_BLOCK: return 0; case POP_EXCEPT: - return -3; - case POP_EXCEPT_AND_RERAISE: - return -7; + return -1; case STORE_NAME: return -1; @@ -1062,9 +1138,9 @@ stack_effect(int opcode, int oparg, int jump) case UNPACK_EX: return (oparg&0xFF) + (oparg>>8); case FOR_ITER: - /* -1 at end of iterator, 1 if continue iterating. */ - return jump > 0 ? -1 : 1; - + return 1; + case SEND: + return jump > 0 ? -1 : 0; case STORE_ATTR: return -2; case DELETE_ATTR: @@ -1087,13 +1163,15 @@ stack_effect(int opcode, int oparg, int jump) case BUILD_CONST_KEY_MAP: return -oparg; case LOAD_ATTR: - return 0; + return (oparg & 1); case COMPARE_OP: case IS_OP: case CONTAINS_OP: return -1; - case JUMP_IF_NOT_EXC_MATCH: - return -1; + case CHECK_EXC_MATCH: + return 0; + case CHECK_EG_MATCH: + return 0; case IMPORT_NAME: return -1; case IMPORT_FROM: @@ -1101,65 +1179,76 @@ stack_effect(int opcode, int oparg, int jump) /* Jumps */ case JUMP_FORWARD: - case JUMP_ABSOLUTE: + case JUMP_BACKWARD: + case JUMP: + case JUMP_BACKWARD_NO_INTERRUPT: + case JUMP_NO_INTERRUPT: return 0; case JUMP_IF_TRUE_OR_POP: case JUMP_IF_FALSE_OR_POP: return jump ? 0 : -1; + case POP_JUMP_IF_NONE: + case POP_JUMP_IF_NOT_NONE: case POP_JUMP_IF_FALSE: case POP_JUMP_IF_TRUE: return -1; + case COMPARE_AND_BRANCH: + return -2; + case LOAD_GLOBAL: - return 1; + return (oparg & 1) + 1; /* Exception handling pseudo-instructions */ case SETUP_FINALLY: /* 0 in the normal flow. - * Restore the stack position and push 3 values before jumping to + * Restore the stack position and push 1 value before jumping to * the handler if an exception be raised. */ - return jump ? 3 : 0; + return jump ? 1 : 0; case SETUP_CLEANUP: /* As SETUP_FINALLY, but pushes lasti as well */ - return jump ? 4 : 0; + return jump ? 2 : 0; case SETUP_WITH: /* 0 in the normal flow. * Restore the stack position to the position before the result - * of __(a)enter__ and push 4 values before jumping to the handler + * of __(a)enter__ and push 2 values before jumping to the handler * if an exception be raised. */ - return jump ? -1 + 4 : 0; - + return jump ? 1 : 0; + case PREP_RERAISE_STAR: + return -1; case RERAISE: - return -3; + return -1; case PUSH_EXC_INFO: - return 3; + return 1; case WITH_EXCEPT_START: return 1; case LOAD_FAST: + case LOAD_FAST_CHECK: return 1; case STORE_FAST: return -1; case DELETE_FAST: return 0; + case RETURN_GENERATOR: + return 0; + case RAISE_VARARGS: return -oparg; /* Functions and calls */ - case CALL_FUNCTION: - return -oparg; - case CALL_METHOD: - return -oparg-1; - case CALL_METHOD_KW: - return -oparg-2; - case CALL_FUNCTION_KW: - return -oparg-1; + case KW_NAMES: + return 0; + case CALL: + return -1-oparg; + case CALL_INTRINSIC_1: + return 0; case CALL_FUNCTION_EX: - return -1 - ((oparg & 0x01) != 0); + return -2 - ((oparg & 0x01) != 0); case MAKE_FUNCTION: return 0 - ((oparg & 0x01) != 0) - ((oparg & 0x02) != 0) - ((oparg & 0x04) != 0) - ((oparg & 0x08) != 0); @@ -1171,6 +1260,7 @@ stack_effect(int opcode, int oparg, int jump) /* Closures */ case MAKE_CELL: + case COPY_FREE_VARS: return 0; case LOAD_CLOSURE: return 1; @@ -1196,7 +1286,9 @@ stack_effect(int opcode, int oparg, int jump) case GET_YIELD_FROM_ITER: return 0; case END_ASYNC_FOR: - return -4; + return -2; + case CLEANUP_THROW: + return -2; case FORMAT_VALUE: /* If there's a fmt_spec on the stack, we go from 2->1, else 1->1. */ @@ -1205,10 +1297,6 @@ stack_effect(int opcode, int oparg, int jump) return 1; case LOAD_ASSERTION_ERROR: return 1; - case LIST_TO_TUPLE: - return 0; - case GEN_START: - return -1; case LIST_EXTEND: case SET_UPDATE: case DICT_MERGE: @@ -1221,12 +1309,13 @@ stack_effect(int opcode, int oparg, int jump) case MATCH_SEQUENCE: case MATCH_KEYS: return 1; - case ROT_N: - return 0; case COPY: + case PUSH_NULL: return 1; case BINARY_OP: return -1; + case INTERPRETER_EXIT: + return -1; default: return PY_INVALID_STACK_EFFECT; } @@ -1245,50 +1334,70 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) return stack_effect(opcode, oparg, -1); } -/* Add an opcode with no argument. - Returns 0 on failure, 1 on success. -*/ - static int -compiler_addop_line(struct compiler *c, int opcode, int line, - int end_line, int col_offset, int end_col_offset) +basicblock_addop(basicblock *b, int opcode, int oparg, location loc) { - basicblock *b; - struct instr *i; - int off; - assert(!HAS_ARG(opcode) || IS_ARTIFICIAL(opcode)); - off = compiler_next_instr(c->u->u_curblock); - if (off < 0) - return 0; - b = c->u->u_curblock; - i = &b->b_instr[off]; + assert(IS_WITHIN_OPCODE_RANGE(opcode)); + assert(!IS_ASSEMBLER_OPCODE(opcode)); + assert(HAS_ARG(opcode) || HAS_TARGET(opcode) || oparg == 0); + assert(0 <= oparg && oparg < (1 << 30)); + + int off = basicblock_next_instr(b); + if (off < 0) { + return ERROR; + } + struct instr *i = &b->b_instr[off]; i->i_opcode = opcode; - i->i_oparg = 0; - if (opcode == RETURN_VALUE) - b->b_return = 1; - i->i_lineno = line; - i->i_end_lineno = end_line; - i->i_col_offset = col_offset; - i->i_end_col_offset = end_col_offset; - return 1; + i->i_oparg = oparg; + i->i_target = NULL; + i->i_loc = loc; + + return SUCCESS; +} + +static bool +cfg_builder_current_block_is_terminated(cfg_builder *g) +{ + if (IS_LABEL(g->g_current_label)) { + return true; + } + struct instr *last = basicblock_last_instr(g->g_curblock); + return last && IS_TERMINATOR_OPCODE(last->i_opcode); } static int -compiler_addop(struct compiler *c, int opcode) +cfg_builder_maybe_start_new_block(cfg_builder *g) { - return compiler_addop_line(c, opcode, c->u->u_lineno, c->u->u_end_lineno, - c->u->u_col_offset, c->u->u_end_col_offset); + if (cfg_builder_current_block_is_terminated(g)) { + basicblock *b = cfg_builder_new_block(g); + if (b == NULL) { + return -1; + } + b->b_label = g->g_current_label.id; + g->g_current_label = NO_LABEL; + cfg_builder_use_next_block(g, b); + } + return 0; } static int -compiler_addop_noline(struct compiler *c, int opcode) +cfg_builder_addop(cfg_builder *g, int opcode, int oparg, location loc) { - return compiler_addop_line(c, opcode, -1, 0, 0, 0); + if (cfg_builder_maybe_start_new_block(g) != 0) { + return -1; + } + return basicblock_addop(g->g_curblock, opcode, oparg, loc); } +static int +cfg_builder_addop_noarg(cfg_builder *g, int opcode, location loc) +{ + assert(!HAS_ARG(opcode)); + return cfg_builder_addop(g, opcode, 0, loc); +} static Py_ssize_t -compiler_add_o(PyObject *dict, PyObject *o) +dict_add_o(PyObject *dict, PyObject *o) { PyObject *v; Py_ssize_t arg; @@ -1316,13 +1425,13 @@ compiler_add_o(PyObject *dict, PyObject *o) // Merge const *o* recursively and return constant key object. static PyObject* -merge_consts_recursive(struct compiler *c, PyObject *o) +merge_consts_recursive(PyObject *const_cache, PyObject *o) { + assert(PyDict_CheckExact(const_cache)); // None and Ellipsis are singleton, and key is the singleton. // No need to merge object and key. if (o == Py_None || o == Py_Ellipsis) { - Py_INCREF(o); - return o; + return Py_NewRef(o); } PyObject *key = _PyCode_ConstantKey(o); @@ -1331,22 +1440,22 @@ merge_consts_recursive(struct compiler *c, PyObject *o) } // t is borrowed reference - PyObject *t = PyDict_SetDefault(c->c_const_cache, key, key); + PyObject *t = PyDict_SetDefault(const_cache, key, key); if (t != key) { - // o is registered in c_const_cache. Just use it. + // o is registered in const_cache. Just use it. Py_XINCREF(t); Py_DECREF(key); return t; } - // We registered o in c_const_cache. + // We registered o in const_cache. // When o is a tuple or frozenset, we want to merge its // items too. if (PyTuple_CheckExact(o)) { Py_ssize_t len = PyTuple_GET_SIZE(o); for (Py_ssize_t i = 0; i < len; i++) { PyObject *item = PyTuple_GET_ITEM(o, i); - PyObject *u = merge_consts_recursive(c, item); + PyObject *u = merge_consts_recursive(const_cache, item); if (u == NULL) { Py_DECREF(key); return NULL; @@ -1361,8 +1470,7 @@ merge_consts_recursive(struct compiler *c, PyObject *o) v = u; } if (v != item) { - Py_INCREF(v); - PyTuple_SET_ITEM(o, i, v); + PyTuple_SET_ITEM(o, i, Py_NewRef(v)); Py_DECREF(item); } @@ -1389,7 +1497,7 @@ merge_consts_recursive(struct compiler *c, PyObject *o) PyObject *item; Py_hash_t hash; while (_PySet_NextEntry(o, &pos, &item, &hash)) { - PyObject *k = merge_consts_recursive(c, item); + PyObject *k = merge_consts_recursive(const_cache, item); if (k == NULL) { Py_DECREF(tuple); Py_DECREF(key); @@ -1397,8 +1505,7 @@ merge_consts_recursive(struct compiler *c, PyObject *o) } PyObject *u; if (PyTuple_CheckExact(k)) { - u = PyTuple_GET_ITEM(k, 1); - Py_INCREF(u); + u = Py_NewRef(PyTuple_GET_ITEM(k, 1)); Py_DECREF(k); } else { @@ -1427,63 +1534,67 @@ merge_consts_recursive(struct compiler *c, PyObject *o) static Py_ssize_t compiler_add_const(struct compiler *c, PyObject *o) { - PyObject *key = merge_consts_recursive(c, o); + PyObject *key = merge_consts_recursive(c->c_const_cache, o); if (key == NULL) { return -1; } - Py_ssize_t arg = compiler_add_o(c->u->u_consts, key); + Py_ssize_t arg = dict_add_o(c->u->u_consts, key); Py_DECREF(key); return arg; } static int -compiler_addop_load_const(struct compiler *c, PyObject *o) +compiler_addop_load_const(struct compiler *c, location loc, PyObject *o) { Py_ssize_t arg = compiler_add_const(c, o); - if (arg < 0) - return 0; - return compiler_addop_i(c, LOAD_CONST, arg); + if (arg < 0) { + return ERROR; + } + return cfg_builder_addop_i(CFG_BUILDER(c), LOAD_CONST, arg, loc); } static int -compiler_addop_o(struct compiler *c, int opcode, PyObject *dict, - PyObject *o) +compiler_addop_o(struct compiler *c, location loc, + int opcode, PyObject *dict, PyObject *o) { - Py_ssize_t arg = compiler_add_o(dict, o); - if (arg < 0) - return 0; - return compiler_addop_i(c, opcode, arg); + Py_ssize_t arg = dict_add_o(dict, o); + if (arg < 0) { + return ERROR; + } + return cfg_builder_addop_i(CFG_BUILDER(c), opcode, arg, loc); } static int -compiler_addop_name(struct compiler *c, int opcode, PyObject *dict, - PyObject *o) +compiler_addop_name(struct compiler *c, location loc, + int opcode, PyObject *dict, PyObject *o) { Py_ssize_t arg; PyObject *mangled = _Py_Mangle(c->u->u_private, o); - if (!mangled) - return 0; - arg = compiler_add_o(dict, mangled); + if (!mangled) { + return ERROR; + } + arg = dict_add_o(dict, mangled); Py_DECREF(mangled); - if (arg < 0) - return 0; - return compiler_addop_i(c, opcode, arg); + if (arg < 0) { + return ERROR; + } + if (opcode == LOAD_ATTR) { + arg <<= 1; + } + if (opcode == LOAD_METHOD) { + opcode = LOAD_ATTR; + arg <<= 1; + arg |= 1; + } + return cfg_builder_addop_i(CFG_BUILDER(c), opcode, arg, loc); } -/* Add an opcode with an integer argument. - Returns 0 on failure, 1 on success. -*/ - +/* Add an opcode with an integer argument */ static int -compiler_addop_i_line(struct compiler *c, int opcode, Py_ssize_t oparg, - int lineno, int end_lineno, - int col_offset, int end_col_offset) +cfg_builder_addop_i(cfg_builder *g, int opcode, Py_ssize_t oparg, location loc) { - struct instr *i; - int off; - /* oparg value is unsigned, but a signed C int is usually used to store it in the C code (like Python/ceval.c). @@ -1491,202 +1602,103 @@ compiler_addop_i_line(struct compiler *c, int opcode, Py_ssize_t oparg, The argument of a concrete bytecode instruction is limited to 8-bit. EXTENDED_ARG is used for 16, 24, and 32-bit arguments. */ - assert(HAS_ARG(opcode)); - assert(0 <= oparg && oparg <= 2147483647); - off = compiler_next_instr(c->u->u_curblock); - if (off < 0) - return 0; - i = &c->u->u_curblock->b_instr[off]; - i->i_opcode = opcode; - i->i_oparg = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int); - i->i_lineno = lineno; - i->i_end_lineno = end_lineno; - i->i_col_offset = col_offset; - i->i_end_col_offset = end_col_offset; - return 1; + int oparg_ = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int); + return cfg_builder_addop(g, opcode, oparg_, loc); } static int -compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg) +cfg_builder_addop_j(cfg_builder *g, location loc, + int opcode, jump_target_label target) { - return compiler_addop_i_line(c, opcode, oparg, - c->u->u_lineno, c->u->u_end_lineno, - c->u->u_col_offset, c->u->u_end_col_offset); + assert(IS_LABEL(target)); + assert(IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode)); + return cfg_builder_addop(g, opcode, target.id, loc); } -static int -compiler_addop_i_noline(struct compiler *c, int opcode, Py_ssize_t oparg) -{ - return compiler_addop_i_line(c, opcode, oparg, -1, 0, 0, 0); -} +#define ADDOP(C, LOC, OP) \ + RETURN_IF_ERROR(cfg_builder_addop_noarg(CFG_BUILDER(C), (OP), (LOC))) -static int add_jump_to_block(basicblock *b, int opcode, - int lineno, int end_lineno, - int col_offset, int end_col_offset, - basicblock *target) -{ - assert(HAS_ARG(opcode)); - assert(b != NULL); - assert(target != NULL); - - int off = compiler_next_instr(b); - struct instr *i = &b->b_instr[off]; - if (off < 0) { - return 0; - } - i->i_opcode = opcode; - i->i_target = target; - i->i_lineno = lineno; - i->i_end_lineno = end_lineno; - i->i_col_offset = col_offset; - i->i_end_col_offset = end_col_offset; - return 1; -} - -static int -compiler_addop_j(struct compiler *c, int opcode, basicblock *b) -{ - return add_jump_to_block(c->u->u_curblock, opcode, c->u->u_lineno, - c->u->u_end_lineno, c->u->u_col_offset, - c->u->u_end_col_offset, b); -} - -static int -compiler_addop_j_noline(struct compiler *c, int opcode, basicblock *b) -{ - return add_jump_to_block(c->u->u_curblock, opcode, -1, 0, 0, 0, b); -} - -/* NEXT_BLOCK() creates an implicit jump from the current block - to the new block. - - The returns inside this macro make it impossible to decref objects - created in the local function. Local objects should use the arena. -*/ -#define NEXT_BLOCK(C) { \ - if (compiler_next_block((C)) == NULL) \ - return 0; \ -} - -#define ADDOP(C, OP) { \ - if (!compiler_addop((C), (OP))) \ - return 0; \ -} - -#define ADDOP_NOLINE(C, OP) { \ - if (!compiler_addop_noline((C), (OP))) \ - return 0; \ -} - -#define ADDOP_IN_SCOPE(C, OP) { \ - if (!compiler_addop((C), (OP))) { \ - compiler_exit_scope(c); \ - return 0; \ +#define ADDOP_IN_SCOPE(C, LOC, OP) { \ + if (cfg_builder_addop_noarg(CFG_BUILDER(C), (OP), (LOC)) < 0) { \ + compiler_exit_scope(C); \ + return -1; \ } \ } -#define ADDOP_LOAD_CONST(C, O) { \ - if (!compiler_addop_load_const((C), (O))) \ - return 0; \ -} +#define ADDOP_LOAD_CONST(C, LOC, O) \ + RETURN_IF_ERROR(compiler_addop_load_const((C), (LOC), (O))) /* Same as ADDOP_LOAD_CONST, but steals a reference. */ -#define ADDOP_LOAD_CONST_NEW(C, O) { \ +#define ADDOP_LOAD_CONST_NEW(C, LOC, O) { \ PyObject *__new_const = (O); \ if (__new_const == NULL) { \ - return 0; \ + return ERROR; \ } \ - if (!compiler_addop_load_const((C), __new_const)) { \ + if (compiler_addop_load_const((C), (LOC), __new_const) < 0) { \ Py_DECREF(__new_const); \ - return 0; \ + return ERROR; \ } \ Py_DECREF(__new_const); \ } -#define ADDOP_O(C, OP, O, TYPE) { \ - assert(!HAS_CONST(OP)); /* use ADDOP_LOAD_CONST */ \ - if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) \ - return 0; \ -} - -/* Same as ADDOP_O, but steals a reference. */ -#define ADDOP_N(C, OP, O, TYPE) { \ +#define ADDOP_N(C, LOC, OP, O, TYPE) { \ assert(!HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */ \ - if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) { \ + if (compiler_addop_o((C), (LOC), (OP), (C)->u->u_ ## TYPE, (O)) < 0) { \ Py_DECREF((O)); \ - return 0; \ + return ERROR; \ } \ Py_DECREF((O)); \ } -#define ADDOP_NAME(C, OP, O, TYPE) { \ - if (!compiler_addop_name((C), (OP), (C)->u->u_ ## TYPE, (O))) \ - return 0; \ -} +#define ADDOP_NAME(C, LOC, OP, O, TYPE) \ + RETURN_IF_ERROR(compiler_addop_name((C), (LOC), (OP), (C)->u->u_ ## TYPE, (O))) -#define ADDOP_I(C, OP, O) { \ - if (!compiler_addop_i((C), (OP), (O))) \ - return 0; \ -} +#define ADDOP_I(C, LOC, OP, O) \ + RETURN_IF_ERROR(cfg_builder_addop_i(CFG_BUILDER(C), (OP), (O), (LOC))) -#define ADDOP_I_NOLINE(C, OP, O) { \ - if (!compiler_addop_i_noline((C), (OP), (O))) \ - return 0; \ -} +#define ADDOP_JUMP(C, LOC, OP, O) \ + RETURN_IF_ERROR(cfg_builder_addop_j(CFG_BUILDER(C), (LOC), (OP), (O))) -#define ADDOP_JUMP(C, OP, O) { \ - if (!compiler_addop_j((C), (OP), (O))) \ - return 0; \ -} +#define ADDOP_COMPARE(C, LOC, CMP) \ + RETURN_IF_ERROR(compiler_addcompare((C), (LOC), (cmpop_ty)(CMP))) -/* Add a jump with no line number. - * Used for artificial jumps that have no corresponding - * token in the source code. */ -#define ADDOP_JUMP_NOLINE(C, OP, O) { \ - if (!compiler_addop_j_noline((C), (OP), (O))) \ - return 0; \ -} +#define ADDOP_BINARY(C, LOC, BINOP) \ + RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), false)) -#define ADDOP_COMPARE(C, CMP) { \ - if (!compiler_addcompare((C), (cmpop_ty)(CMP))) \ - return 0; \ -} +#define ADDOP_INPLACE(C, LOC, BINOP) \ + RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), true)) -#define ADDOP_BINARY(C, BINOP) \ - RETURN_IF_FALSE(addop_binary((C), (BINOP), false)) +#define ADD_YIELD_FROM(C, LOC, await) \ + RETURN_IF_ERROR(compiler_add_yield_from((C), (LOC), (await))) -#define ADDOP_INPLACE(C, BINOP) \ - RETURN_IF_FALSE(addop_binary((C), (BINOP), true)) +#define POP_EXCEPT_AND_RERAISE(C, LOC) \ + RETURN_IF_ERROR(compiler_pop_except_and_reraise((C), (LOC))) + +#define ADDOP_YIELD(C, LOC) \ + RETURN_IF_ERROR(addop_yield((C), (LOC))) /* VISIT and VISIT_SEQ takes an ASDL type as their second argument. They use the ASDL name to synthesize the name of the C type and the visit function. */ -#define VISIT(C, TYPE, V) {\ - if (!compiler_visit_ ## TYPE((C), (V))) \ - return 0; \ -} +#define VISIT(C, TYPE, V) \ + RETURN_IF_ERROR(compiler_visit_ ## TYPE((C), (V))); #define VISIT_IN_SCOPE(C, TYPE, V) {\ - if (!compiler_visit_ ## TYPE((C), (V))) { \ - compiler_exit_scope(c); \ - return 0; \ + if (compiler_visit_ ## TYPE((C), (V)) < 0) { \ + compiler_exit_scope(C); \ + return ERROR; \ } \ } -#define VISIT_SLICE(C, V, CTX) {\ - if (!compiler_visit_slice((C), (V), (CTX))) \ - return 0; \ -} - #define VISIT_SEQ(C, TYPE, SEQ) { \ int _i; \ asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \ - if (!compiler_visit_ ## TYPE((C), elt)) \ - return 0; \ + if (compiler_visit_ ## TYPE((C), elt) < 0) \ + return ERROR; \ } \ } @@ -1695,21 +1707,143 @@ compiler_addop_j_noline(struct compiler *c, int opcode, basicblock *b) asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \ - if (!compiler_visit_ ## TYPE((C), elt)) { \ - compiler_exit_scope(c); \ - return 0; \ + if (compiler_visit_ ## TYPE((C), elt) < 0) { \ + compiler_exit_scope(C); \ + return ERROR; \ } \ } \ } -#define RETURN_IF_FALSE(X) \ - if (!(X)) { \ - return 0; \ + +static int +compiler_enter_scope(struct compiler *c, identifier name, + int scope_type, void *key, int lineno) +{ + location loc = LOCATION(lineno, lineno, 0, 0); + + struct compiler_unit *u; + + u = (struct compiler_unit *)PyObject_Calloc(1, sizeof( + struct compiler_unit)); + if (!u) { + PyErr_NoMemory(); + return ERROR; } + u->u_scope_type = scope_type; + u->u_argcount = 0; + u->u_posonlyargcount = 0; + u->u_kwonlyargcount = 0; + u->u_ste = PySymtable_Lookup(c->c_st, key); + if (!u->u_ste) { + compiler_unit_free(u); + return ERROR; + } + u->u_name = Py_NewRef(name); + u->u_varnames = list2dict(u->u_ste->ste_varnames); + u->u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, 0, 0); + if (!u->u_varnames || !u->u_cellvars) { + compiler_unit_free(u); + return ERROR; + } + if (u->u_ste->ste_needs_class_closure) { + /* Cook up an implicit __class__ cell. */ + int res; + assert(u->u_scope_type == COMPILER_SCOPE_CLASS); + assert(PyDict_GET_SIZE(u->u_cellvars) == 0); + res = PyDict_SetItem(u->u_cellvars, &_Py_ID(__class__), + _PyLong_GetZero()); + if (res < 0) { + compiler_unit_free(u); + return ERROR; + } + } + + u->u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS, + PyDict_GET_SIZE(u->u_cellvars)); + if (!u->u_freevars) { + compiler_unit_free(u); + return ERROR; + } + + u->u_nfblocks = 0; + u->u_firstlineno = lineno; + u->u_consts = PyDict_New(); + if (!u->u_consts) { + compiler_unit_free(u); + return ERROR; + } + u->u_names = PyDict_New(); + if (!u->u_names) { + compiler_unit_free(u); + return ERROR; + } + + u->u_private = NULL; + + /* Push the old compiler_unit on the stack. */ + if (c->u) { + PyObject *capsule = PyCapsule_New(c->u, CAPSULE_NAME, NULL); + if (!capsule || PyList_Append(c->c_stack, capsule) < 0) { + Py_XDECREF(capsule); + compiler_unit_free(u); + return ERROR; + } + Py_DECREF(capsule); + u->u_private = Py_XNewRef(c->u->u_private); + } + c->u = u; + + c->c_nestlevel++; + + cfg_builder *g = CFG_BUILDER(c); + RETURN_IF_ERROR(cfg_builder_init(g)); + + if (u->u_scope_type == COMPILER_SCOPE_MODULE) { + loc.lineno = 0; + } + else { + RETURN_IF_ERROR(compiler_set_qualname(c)); + } + ADDOP_I(c, loc, RESUME, 0); + + if (u->u_scope_type == COMPILER_SCOPE_MODULE) { + loc.lineno = -1; + } + return SUCCESS; +} + +static void +compiler_exit_scope(struct compiler *c) +{ + // Don't call PySequence_DelItem() with an exception raised + PyObject *exc_type, *exc_val, *exc_tb; + PyErr_Fetch(&exc_type, &exc_val, &exc_tb); + + c->c_nestlevel--; + compiler_unit_free(c->u); + /* Restore c->u to the parent unit. */ + Py_ssize_t n = PyList_GET_SIZE(c->c_stack) - 1; + if (n >= 0) { + PyObject *capsule = PyList_GET_ITEM(c->c_stack, n); + c->u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME); + assert(c->u); + /* we are deleting from a list so this really shouldn't fail */ + if (PySequence_DelItem(c->c_stack, n) < 0) { + _PyErr_WriteUnraisableMsg("on removing the last compiler " + "stack item", NULL); + } + cfg_builder_check(CFG_BUILDER(c)); + } + else { + c->u = NULL; + } + + PyErr_Restore(exc_type, exc_val, exc_tb); +} /* Search if variable annotations are present statically in a block. */ -static int +static bool find_ann(asdl_stmt_seq *stmts) { int i, j, res = 0; @@ -1719,7 +1853,7 @@ find_ann(asdl_stmt_seq *stmts) st = (stmt_ty)asdl_seq_GET(stmts, i); switch (st->kind) { case AnnAssign_kind: - return 1; + return true; case For_kind: res = find_ann(st->v.For.body) || find_ann(st->v.For.orelse); @@ -1747,15 +1881,27 @@ find_ann(asdl_stmt_seq *stmts) excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( st->v.Try.handlers, j); if (find_ann(handler->v.ExceptHandler.body)) { - return 1; + return true; } } res = find_ann(st->v.Try.body) || find_ann(st->v.Try.finalbody) || find_ann(st->v.Try.orelse); break; + case TryStar_kind: + for (j = 0; j < asdl_seq_LEN(st->v.TryStar.handlers); j++) { + excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( + st->v.TryStar.handlers, j); + if (find_ann(handler->v.ExceptHandler.body)) { + return true; + } + } + res = find_ann(st->v.TryStar.body) || + find_ann(st->v.TryStar.finalbody) || + find_ann(st->v.TryStar.orelse); + break; default: - res = 0; + res = false; } if (res) { break; @@ -1769,38 +1915,80 @@ find_ann(asdl_stmt_seq *stmts) */ static int -compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b, - basicblock *exit, void *datum) +compiler_push_fblock(struct compiler *c, location loc, + enum fblocktype t, jump_target_label block_label, + jump_target_label exit, void *datum) { struct fblockinfo *f; if (c->u->u_nfblocks >= CO_MAXBLOCKS) { - return compiler_error(c, "too many statically nested blocks"); + return compiler_error(c, loc, "too many statically nested blocks"); } f = &c->u->u_fblock[c->u->u_nfblocks++]; f->fb_type = t; - f->fb_block = b; + f->fb_block = block_label; f->fb_exit = exit; f->fb_datum = datum; - return 1; + return SUCCESS; } static void -compiler_pop_fblock(struct compiler *c, enum fblocktype t, basicblock *b) +compiler_pop_fblock(struct compiler *c, enum fblocktype t, jump_target_label block_label) { struct compiler_unit *u = c->u; assert(u->u_nfblocks > 0); u->u_nfblocks--; assert(u->u_fblock[u->u_nfblocks].fb_type == t); - assert(u->u_fblock[u->u_nfblocks].fb_block == b); + assert(SAME_LABEL(u->u_fblock[u->u_nfblocks].fb_block, block_label)); } static int -compiler_call_exit_with_nones(struct compiler *c) { - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, DUP_TOP); - ADDOP(c, DUP_TOP); - ADDOP_I(c, CALL_FUNCTION, 3); - return 1; +compiler_call_exit_with_nones(struct compiler *c, location loc) +{ + ADDOP_LOAD_CONST(c, loc, Py_None); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADDOP_I(c, loc, CALL, 2); + return SUCCESS; +} + +static int +compiler_add_yield_from(struct compiler *c, location loc, int await) +{ + NEW_JUMP_TARGET_LABEL(c, send); + NEW_JUMP_TARGET_LABEL(c, fail); + NEW_JUMP_TARGET_LABEL(c, exit); + + USE_LABEL(c, send); + ADDOP_JUMP(c, loc, SEND, exit); + // Set up a virtual try/except to handle when StopIteration is raised during + // a close or throw call. The only way YIELD_VALUE raises if they do! + ADDOP_JUMP(c, loc, SETUP_FINALLY, fail); + ADDOP_I(c, loc, YIELD_VALUE, 0); + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP_I(c, loc, RESUME, await ? 3 : 2); + ADDOP_JUMP(c, loc, JUMP_NO_INTERRUPT, send); + + USE_LABEL(c, fail); + ADDOP(c, loc, CLEANUP_THROW); + + USE_LABEL(c, exit); + return SUCCESS; +} + +static int +compiler_pop_except_and_reraise(struct compiler *c, location loc) +{ + /* Stack contents + * [exc_info, lasti, exc] COPY 3 + * [exc_info, lasti, exc, exc_info] POP_EXCEPT + * [exc_info, lasti, exc] RERAISE 1 + * (exception_unwind clears the stack) + */ + + ADDOP_I(c, loc, COPY, 3); + ADDOP(c, loc, POP_EXCEPT); + ADDOP_I(c, loc, RERAISE, 1); + return SUCCESS; } /* Unwind a frame block. If preserve_tos is true, the TOS before @@ -1809,146 +1997,140 @@ compiler_call_exit_with_nones(struct compiler *c) { * be popped. */ static int -compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, - int preserve_tos) +compiler_unwind_fblock(struct compiler *c, location *ploc, + struct fblockinfo *info, int preserve_tos) { switch (info->fb_type) { case WHILE_LOOP: case EXCEPTION_HANDLER: + case EXCEPTION_GROUP_HANDLER: case ASYNC_COMPREHENSION_GENERATOR: - return 1; + return SUCCESS; case FOR_LOOP: /* Pop the iterator */ if (preserve_tos) { - ADDOP(c, ROT_TWO); + ADDOP_I(c, *ploc, SWAP, 2); } - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, *ploc, POP_TOP); + return SUCCESS; case TRY_EXCEPT: - ADDOP(c, POP_BLOCK); - return 1; + ADDOP(c, *ploc, POP_BLOCK); + return SUCCESS; case FINALLY_TRY: /* This POP_BLOCK gets the line number of the unwinding statement */ - ADDOP(c, POP_BLOCK); + ADDOP(c, *ploc, POP_BLOCK); if (preserve_tos) { - if (!compiler_push_fblock(c, POP_VALUE, NULL, NULL, NULL)) { - return 0; - } + RETURN_IF_ERROR( + compiler_push_fblock(c, *ploc, POP_VALUE, NO_LABEL, NO_LABEL, NULL)); } /* Emit the finally block */ VISIT_SEQ(c, stmt, info->fb_datum); if (preserve_tos) { - compiler_pop_fblock(c, POP_VALUE, NULL); + compiler_pop_fblock(c, POP_VALUE, NO_LABEL); } /* The finally block should appear to execute after the * statement causing the unwinding, so make the unwinding * instruction artificial */ - UNSET_LOC(c); - return 1; + *ploc = NO_LOCATION; + return SUCCESS; case FINALLY_END: if (preserve_tos) { - ADDOP(c, ROT_FOUR); + ADDOP_I(c, *ploc, SWAP, 2); } - ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); + ADDOP(c, *ploc, POP_TOP); /* exc_value */ if (preserve_tos) { - ADDOP(c, ROT_FOUR); + ADDOP_I(c, *ploc, SWAP, 2); } - ADDOP(c, POP_BLOCK); - ADDOP(c, POP_EXCEPT); - return 1; + ADDOP(c, *ploc, POP_BLOCK); + ADDOP(c, *ploc, POP_EXCEPT); + return SUCCESS; case WITH: case ASYNC_WITH: - SET_LOC(c, (stmt_ty)info->fb_datum); - ADDOP(c, POP_BLOCK); + *ploc = LOC((stmt_ty)info->fb_datum); + ADDOP(c, *ploc, POP_BLOCK); if (preserve_tos) { - ADDOP(c, ROT_TWO); - } - if(!compiler_call_exit_with_nones(c)) { - return 0; + ADDOP_I(c, *ploc, SWAP, 2); } + RETURN_IF_ERROR(compiler_call_exit_with_nones(c, *ploc)); if (info->fb_type == ASYNC_WITH) { - ADDOP(c, GET_AWAITABLE); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); + ADDOP_I(c, *ploc, GET_AWAITABLE, 2); + ADDOP_LOAD_CONST(c, *ploc, Py_None); + ADD_YIELD_FROM(c, *ploc, 1); } - ADDOP(c, POP_TOP); + ADDOP(c, *ploc, POP_TOP); /* The exit block should appear to execute after the * statement causing the unwinding, so make the unwinding * instruction artificial */ - UNSET_LOC(c); - return 1; + *ploc = NO_LOCATION; + return SUCCESS; - case HANDLER_CLEANUP: + case HANDLER_CLEANUP: { if (info->fb_datum) { - ADDOP(c, POP_BLOCK); + ADDOP(c, *ploc, POP_BLOCK); } if (preserve_tos) { - ADDOP(c, ROT_FOUR); + ADDOP_I(c, *ploc, SWAP, 2); } - ADDOP(c, POP_BLOCK); - ADDOP(c, POP_EXCEPT); + ADDOP(c, *ploc, POP_BLOCK); + ADDOP(c, *ploc, POP_EXCEPT); if (info->fb_datum) { - ADDOP_LOAD_CONST(c, Py_None); - compiler_nameop(c, info->fb_datum, Store); - compiler_nameop(c, info->fb_datum, Del); + ADDOP_LOAD_CONST(c, *ploc, Py_None); + RETURN_IF_ERROR(compiler_nameop(c, *ploc, info->fb_datum, Store)); + RETURN_IF_ERROR(compiler_nameop(c, *ploc, info->fb_datum, Del)); } - return 1; - - case POP_VALUE: + return SUCCESS; + } + case POP_VALUE: { if (preserve_tos) { - ADDOP(c, ROT_TWO); + ADDOP_I(c, *ploc, SWAP, 2); } - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, *ploc, POP_TOP); + return SUCCESS; + } } Py_UNREACHABLE(); } /** Unwind block stack. If loop is not NULL, then stop when the first loop is encountered. */ static int -compiler_unwind_fblock_stack(struct compiler *c, int preserve_tos, struct fblockinfo **loop) { +compiler_unwind_fblock_stack(struct compiler *c, location *ploc, + int preserve_tos, struct fblockinfo **loop) +{ if (c->u->u_nfblocks == 0) { - return 1; + return SUCCESS; } struct fblockinfo *top = &c->u->u_fblock[c->u->u_nfblocks-1]; + if (top->fb_type == EXCEPTION_GROUP_HANDLER) { + return compiler_error( + c, *ploc, "'break', 'continue' and 'return' cannot appear in an except* block"); + } if (loop != NULL && (top->fb_type == WHILE_LOOP || top->fb_type == FOR_LOOP)) { *loop = top; - return 1; + return SUCCESS; } struct fblockinfo copy = *top; c->u->u_nfblocks--; - if (!compiler_unwind_fblock(c, ©, preserve_tos)) { - return 0; - } - if (!compiler_unwind_fblock_stack(c, preserve_tos, loop)) { - return 0; - } + RETURN_IF_ERROR(compiler_unwind_fblock(c, ploc, ©, preserve_tos)); + RETURN_IF_ERROR(compiler_unwind_fblock_stack(c, ploc, preserve_tos, loop)); c->u->u_fblock[c->u->u_nfblocks] = copy; c->u->u_nfblocks++; - return 1; + return SUCCESS; } /* Compile a sequence of statements, checking for a docstring and for annotations. */ static int -compiler_body(struct compiler *c, asdl_stmt_seq *stmts) +compiler_body(struct compiler *c, location loc, asdl_stmt_seq *stmts) { int i = 0; stmt_ty st; PyObject *docstring; - _Py_IDENTIFIER(__doc__); - PyObject *__doc__ = _PyUnicode_FromId(&PyId___doc__); /* borrowed ref*/ - if (__doc__ == NULL) { - return 0; - } /* Set current line number to the line number of first statement. This way line number for SETUP_ANNOTATIONS will always @@ -1956,14 +2138,15 @@ compiler_body(struct compiler *c, asdl_stmt_seq *stmts) If body is empty, then lineno will be set later in assemble. */ if (c->u->u_scope_type == COMPILER_SCOPE_MODULE && asdl_seq_LEN(stmts)) { st = (stmt_ty)asdl_seq_GET(stmts, 0); - SET_LOC(c, st); + loc = LOC(st); } /* Every annotated class and module should have __annotations__. */ if (find_ann(stmts)) { - ADDOP(c, SETUP_ANNOTATIONS); + ADDOP(c, loc, SETUP_ANNOTATIONS); + } + if (!asdl_seq_LEN(stmts)) { + return SUCCESS; } - if (!asdl_seq_LEN(stmts)) - return 1; /* if not -OO mode, set docstring */ if (c->c_optimize < 2) { docstring = _PyAST_GetDocString(stmts); @@ -1972,53 +2155,58 @@ compiler_body(struct compiler *c, asdl_stmt_seq *stmts) st = (stmt_ty)asdl_seq_GET(stmts, 0); assert(st->kind == Expr_kind); VISIT(c, expr, st->v.Expr.value); - if (!compiler_nameop(c, __doc__, Store)) - return 0; + RETURN_IF_ERROR(compiler_nameop(c, NO_LOCATION, &_Py_ID(__doc__), Store)); } } - for (; i < asdl_seq_LEN(stmts); i++) + for (; i < asdl_seq_LEN(stmts); i++) { VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i)); - return 1; + } + return SUCCESS; } -static PyCodeObject * -compiler_mod(struct compiler *c, mod_ty mod) +static int +compiler_codegen(struct compiler *c, mod_ty mod) { - PyCodeObject *co; - int addNone = 1; - _Py_static_string(PyId__module, ""); - PyObject *module = _PyUnicode_FromId(&PyId__module); /* borrowed ref */ - if (module == NULL) { - return 0; - } - /* Use 0 for firstlineno initially, will fixup in assemble(). */ - if (!compiler_enter_scope(c, module, COMPILER_SCOPE_MODULE, mod, 1)) - return NULL; + _Py_DECLARE_STR(anon_module, ""); + RETURN_IF_ERROR( + compiler_enter_scope(c, &_Py_STR(anon_module), COMPILER_SCOPE_MODULE, + mod, 1)); + + location loc = LOCATION(1, 1, 0, 0); switch (mod->kind) { case Module_kind: - if (!compiler_body(c, mod->v.Module.body)) { + if (compiler_body(c, loc, mod->v.Module.body) < 0) { compiler_exit_scope(c); - return 0; + return ERROR; } break; case Interactive_kind: if (find_ann(mod->v.Interactive.body)) { - ADDOP(c, SETUP_ANNOTATIONS); + ADDOP(c, loc, SETUP_ANNOTATIONS); } c->c_interactive = 1; VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Interactive.body); break; case Expression_kind: VISIT_IN_SCOPE(c, expr, mod->v.Expression.body); - addNone = 0; break; default: PyErr_Format(PyExc_SystemError, "module kind %d should not be possible", mod->kind); - return 0; + return ERROR; } - co = assemble(c, addNone); + return SUCCESS; +} + +static PyCodeObject * +compiler_mod(struct compiler *c, mod_ty mod) +{ + int addNone = mod->kind != Expression_kind; + if (compiler_codegen(c, mod) < 0) { + return NULL; + } + PyCodeObject *co = assemble(c, addNone); compiler_exit_scope(c); return co; } @@ -2060,14 +2248,11 @@ compiler_lookup_arg(PyObject *dict, PyObject *name) } static int -compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, - PyObject *qualname) +compiler_make_closure(struct compiler *c, location loc, + PyCodeObject *co, Py_ssize_t flags) { - if (qualname == NULL) - qualname = co->co_name; - if (co->co_nfreevars) { - int i = co->co_nlocals + co->co_nplaincellvars; + int i = PyCode_GetFirstFree(co); for (; i < co->co_nlocalsplus; ++i) { /* Bypass com_addop_varname because it will generate LOAD_DEREF but LOAD_CLOSURE is needed. @@ -2082,7 +2267,7 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, */ int reftype = get_ref_type(c, name); if (reftype == -1) { - return 0; + return ERROR; } int arg; if (reftype == CELL) { @@ -2105,39 +2290,52 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, co->co_name, freevars); Py_DECREF(freevars); - return 0; + return ERROR; } - ADDOP_I(c, LOAD_CLOSURE, arg); + ADDOP_I(c, loc, LOAD_CLOSURE, arg); } flags |= 0x08; - ADDOP_I(c, BUILD_TUPLE, co->co_nfreevars); + ADDOP_I(c, loc, BUILD_TUPLE, co->co_nfreevars); } - ADDOP_LOAD_CONST(c, (PyObject*)co); - ADDOP_I(c, MAKE_FUNCTION, flags); - return 1; + ADDOP_LOAD_CONST(c, loc, (PyObject*)co); + ADDOP_I(c, loc, MAKE_FUNCTION, flags); + return SUCCESS; } static int compiler_decorators(struct compiler *c, asdl_expr_seq* decos) { - int i; + if (!decos) { + return SUCCESS; + } - if (!decos) - return 1; - - for (i = 0; i < asdl_seq_LEN(decos); i++) { + for (Py_ssize_t i = 0; i < asdl_seq_LEN(decos); i++) { VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i)); } - return 1; + return SUCCESS; } static int -compiler_visit_kwonlydefaults(struct compiler *c, asdl_arg_seq *kwonlyargs, - asdl_expr_seq *kw_defaults) +compiler_apply_decorators(struct compiler *c, asdl_expr_seq* decos) +{ + if (!decos) { + return SUCCESS; + } + + for (Py_ssize_t i = asdl_seq_LEN(decos) - 1; i > -1; i--) { + location loc = LOC((expr_ty)asdl_seq_GET(decos, i)); + ADDOP_I(c, loc, CALL, 0); + } + return SUCCESS; +} + +static int +compiler_visit_kwonlydefaults(struct compiler *c, location loc, + asdl_arg_seq *kwonlyargs, asdl_expr_seq *kw_defaults) { /* Push a dict of keyword-only default values. - Return 0 on error, -1 if no dict pushed, 1 if a dict is pushed. + Return -1 on error, 0 if no dict pushed, 1 if a dict is pushed. */ int i; PyObject *keys = NULL; @@ -2154,7 +2352,7 @@ compiler_visit_kwonlydefaults(struct compiler *c, asdl_arg_seq *kwonlyargs, keys = PyList_New(1); if (keys == NULL) { Py_DECREF(mangled); - return 0; + return ERROR; } PyList_SET_ITEM(keys, 0, mangled); } @@ -2165,7 +2363,7 @@ compiler_visit_kwonlydefaults(struct compiler *c, asdl_arg_seq *kwonlyargs, goto error; } } - if (!compiler_visit_expr(c, default_)) { + if (compiler_visit_expr(c, default_) < 0) { goto error; } } @@ -2174,165 +2372,177 @@ compiler_visit_kwonlydefaults(struct compiler *c, asdl_arg_seq *kwonlyargs, Py_ssize_t default_count = PyList_GET_SIZE(keys); PyObject *keys_tuple = PyList_AsTuple(keys); Py_DECREF(keys); - ADDOP_LOAD_CONST_NEW(c, keys_tuple); - ADDOP_I(c, BUILD_CONST_KEY_MAP, default_count); + ADDOP_LOAD_CONST_NEW(c, loc, keys_tuple); + ADDOP_I(c, loc, BUILD_CONST_KEY_MAP, default_count); assert(default_count > 0); return 1; } else { - return -1; + return 0; } error: Py_XDECREF(keys); - return 0; + return ERROR; } static int compiler_visit_annexpr(struct compiler *c, expr_ty annotation) { - ADDOP_LOAD_CONST_NEW(c, _PyAST_ExprAsUnicode(annotation)); - return 1; + location loc = LOC(annotation); + ADDOP_LOAD_CONST_NEW(c, loc, _PyAST_ExprAsUnicode(annotation)); + return SUCCESS; } static int compiler_visit_argannotation(struct compiler *c, identifier id, - expr_ty annotation, Py_ssize_t *annotations_len) + expr_ty annotation, Py_ssize_t *annotations_len, location loc) { if (!annotation) { - return 1; + return SUCCESS; } - PyObject *mangled = _Py_Mangle(c->u->u_private, id); if (!mangled) { - return 0; + return ERROR; } - ADDOP_LOAD_CONST(c, mangled); + ADDOP_LOAD_CONST(c, loc, mangled); Py_DECREF(mangled); - if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) { - VISIT(c, annexpr, annotation) + if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) { + VISIT(c, annexpr, annotation); } else { - VISIT(c, expr, annotation); + if (annotation->kind == Starred_kind) { + // *args: *Ts (where Ts is a TypeVarTuple). + // Do [annotation_value] = [*Ts]. + // (Note that in theory we could end up here even for an argument + // other than *args, but in practice the grammar doesn't allow it.) + VISIT(c, expr, annotation->v.Starred.value); + ADDOP_I(c, loc, UNPACK_SEQUENCE, (Py_ssize_t) 1); + } + else { + VISIT(c, expr, annotation); + } } *annotations_len += 2; - return 1; + return SUCCESS; } static int compiler_visit_argannotations(struct compiler *c, asdl_arg_seq* args, - Py_ssize_t *annotations_len) + Py_ssize_t *annotations_len, location loc) { int i; for (i = 0; i < asdl_seq_LEN(args); i++) { arg_ty arg = (arg_ty)asdl_seq_GET(args, i); - if (!compiler_visit_argannotation( + RETURN_IF_ERROR( + compiler_visit_argannotation( c, arg->arg, arg->annotation, - annotations_len)) - return 0; + annotations_len, + loc)); } - return 1; + return SUCCESS; } static int -compiler_visit_annotations(struct compiler *c, arguments_ty args, - expr_ty returns) +compiler_visit_annotations(struct compiler *c, location loc, + arguments_ty args, expr_ty returns) { /* Push arg annotation names and values. The expressions are evaluated out-of-order wrt the source code. - Return 0 on error, -1 if no annotations pushed, 1 if a annotations is pushed. + Return -1 on error, 0 if no annotations pushed, 1 if a annotations is pushed. */ - _Py_IDENTIFIER(return); Py_ssize_t annotations_len = 0; - if (!compiler_visit_argannotations(c, args->args, &annotations_len)) - return 0; - if (!compiler_visit_argannotations(c, args->posonlyargs, &annotations_len)) - return 0; - if (args->vararg && args->vararg->annotation && - !compiler_visit_argannotation(c, args->vararg->arg, - args->vararg->annotation, &annotations_len)) - return 0; - if (!compiler_visit_argannotations(c, args->kwonlyargs, &annotations_len)) - return 0; - if (args->kwarg && args->kwarg->annotation && - !compiler_visit_argannotation(c, args->kwarg->arg, - args->kwarg->annotation, &annotations_len)) - return 0; + RETURN_IF_ERROR( + compiler_visit_argannotations(c, args->args, &annotations_len, loc)); - identifier return_str = _PyUnicode_FromId(&PyId_return); /* borrowed ref */ - if (return_str == NULL) { - return 0; + RETURN_IF_ERROR( + compiler_visit_argannotations(c, args->posonlyargs, &annotations_len, loc)); + + if (args->vararg && args->vararg->annotation) { + RETURN_IF_ERROR( + compiler_visit_argannotation(c, args->vararg->arg, + args->vararg->annotation, &annotations_len, loc)); } - if (!compiler_visit_argannotation(c, return_str, returns, &annotations_len)) { - return 0; + + RETURN_IF_ERROR( + compiler_visit_argannotations(c, args->kwonlyargs, &annotations_len, loc)); + + if (args->kwarg && args->kwarg->annotation) { + RETURN_IF_ERROR( + compiler_visit_argannotation(c, args->kwarg->arg, + args->kwarg->annotation, &annotations_len, loc)); } + RETURN_IF_ERROR( + compiler_visit_argannotation(c, &_Py_ID(return), returns, &annotations_len, loc)); + if (annotations_len) { - ADDOP_I(c, BUILD_TUPLE, annotations_len); + ADDOP_I(c, loc, BUILD_TUPLE, annotations_len); return 1; } - return -1; + return 0; } static int -compiler_visit_defaults(struct compiler *c, arguments_ty args) +compiler_visit_defaults(struct compiler *c, arguments_ty args, + location loc) { VISIT_SEQ(c, expr, args->defaults); - ADDOP_I(c, BUILD_TUPLE, asdl_seq_LEN(args->defaults)); - return 1; + ADDOP_I(c, loc, BUILD_TUPLE, asdl_seq_LEN(args->defaults)); + return SUCCESS; } static Py_ssize_t -compiler_default_arguments(struct compiler *c, arguments_ty args) +compiler_default_arguments(struct compiler *c, location loc, + arguments_ty args) { Py_ssize_t funcflags = 0; if (args->defaults && asdl_seq_LEN(args->defaults) > 0) { - if (!compiler_visit_defaults(c, args)) - return -1; + RETURN_IF_ERROR(compiler_visit_defaults(c, args, loc)); funcflags |= 0x01; } if (args->kwonlyargs) { - int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs, + int res = compiler_visit_kwonlydefaults(c, loc, + args->kwonlyargs, args->kw_defaults); - if (res == 0) { - return -1; - } - else if (res > 0) { + RETURN_IF_ERROR(res); + if (res > 0) { funcflags |= 0x02; } } return funcflags; } -static int -forbidden_name(struct compiler *c, identifier name, expr_context_ty ctx) +static bool +forbidden_name(struct compiler *c, location loc, identifier name, + expr_context_ty ctx) { - if (ctx == Store && _PyUnicode_EqualToASCIIString(name, "__debug__")) { - compiler_error(c, "cannot assign to __debug__"); - return 1; + compiler_error(c, loc, "cannot assign to __debug__"); + return true; } if (ctx == Del && _PyUnicode_EqualToASCIIString(name, "__debug__")) { - compiler_error(c, "cannot delete __debug__"); - return 1; + compiler_error(c, loc, "cannot delete __debug__"); + return true; } - return 0; + return false; } static int compiler_check_debug_one_arg(struct compiler *c, arg_ty arg) { if (arg != NULL) { - if (forbidden_name(c, arg->arg, Store)) - return 0; + if (forbidden_name(c, LOC(arg), arg->arg, Store)) { + return ERROR; + } } - return 1; + return SUCCESS; } static int @@ -2340,34 +2550,62 @@ compiler_check_debug_args_seq(struct compiler *c, asdl_arg_seq *args) { if (args != NULL) { for (Py_ssize_t i = 0, n = asdl_seq_LEN(args); i < n; i++) { - if (!compiler_check_debug_one_arg(c, asdl_seq_GET(args, i))) - return 0; + RETURN_IF_ERROR( + compiler_check_debug_one_arg(c, asdl_seq_GET(args, i))); } } - return 1; + return SUCCESS; } static int compiler_check_debug_args(struct compiler *c, arguments_ty args) { - if (!compiler_check_debug_args_seq(c, args->posonlyargs)) - return 0; - if (!compiler_check_debug_args_seq(c, args->args)) - return 0; - if (!compiler_check_debug_one_arg(c, args->vararg)) - return 0; - if (!compiler_check_debug_args_seq(c, args->kwonlyargs)) - return 0; - if (!compiler_check_debug_one_arg(c, args->kwarg)) - return 0; - return 1; + RETURN_IF_ERROR(compiler_check_debug_args_seq(c, args->posonlyargs)); + RETURN_IF_ERROR(compiler_check_debug_args_seq(c, args->args)); + RETURN_IF_ERROR(compiler_check_debug_one_arg(c, args->vararg)); + RETURN_IF_ERROR(compiler_check_debug_args_seq(c, args->kwonlyargs)); + RETURN_IF_ERROR(compiler_check_debug_one_arg(c, args->kwarg)); + return SUCCESS; +} + +static inline int +insert_instruction(basicblock *block, int pos, struct instr *instr) { + RETURN_IF_ERROR(basicblock_next_instr(block)); + for (int i = block->b_iused - 1; i > pos; i--) { + block->b_instr[i] = block->b_instr[i-1]; + } + block->b_instr[pos] = *instr; + return SUCCESS; +} + +static int +wrap_in_stopiteration_handler(struct compiler *c) +{ + NEW_JUMP_TARGET_LABEL(c, handler); + + /* Insert SETUP_CLEANUP at start */ + struct instr setup = { + .i_opcode = SETUP_CLEANUP, + .i_oparg = handler.id, + .i_loc = NO_LOCATION, + .i_target = NULL, + }; + RETURN_IF_ERROR( + insert_instruction(c->u->u_cfg_builder.g_entryblock, 0, &setup)); + + ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + ADDOP(c, NO_LOCATION, RETURN_VALUE); + USE_LABEL(c, handler); + ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_1, INTRINSIC_STOPITERATION_ERROR); + ADDOP_I(c, NO_LOCATION, RERAISE, 1); + return SUCCESS; } static int compiler_function(struct compiler *c, stmt_ty s, int is_async) { PyCodeObject *co; - PyObject *qualname, *docstring = NULL; + PyObject *docstring = NULL; arguments_ty args; expr_ty returns; identifier name; @@ -2400,33 +2638,27 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) scope_type = COMPILER_SCOPE_FUNCTION; } - if (!compiler_check_debug_args(c, args)) - return 0; - - if (!compiler_decorators(c, decos)) - return 0; + RETURN_IF_ERROR(compiler_check_debug_args(c, args)); + RETURN_IF_ERROR(compiler_decorators(c, decos)); firstlineno = s->lineno; if (asdl_seq_LEN(decos)) { firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno; } - funcflags = compiler_default_arguments(c, args); + location loc = LOC(s); + funcflags = compiler_default_arguments(c, loc, args); if (funcflags == -1) { - return 0; + return ERROR; } - - annotations = compiler_visit_annotations(c, args, returns); - if (annotations == 0) { - return 0; - } - else if (annotations > 0) { + annotations = compiler_visit_annotations(c, loc, args, returns); + RETURN_IF_ERROR(annotations); + if (annotations > 0) { funcflags |= 0x04; } - if (!compiler_enter_scope(c, name, scope_type, (void *)s, firstlineno)) { - return 0; - } + RETURN_IF_ERROR( + compiler_enter_scope(c, name, scope_type, (void *)s, firstlineno)); /* if not -OO mode, add docstring */ if (c->c_optimize < 2) { @@ -2434,7 +2666,7 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) } if (compiler_add_const(c, docstring ? docstring : Py_None) < 0) { compiler_exit_scope(c); - return 0; + return ERROR; } c->u->u_argcount = asdl_seq_LEN(args->args); @@ -2443,42 +2675,36 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) for (i = docstring ? 1 : 0; i < asdl_seq_LEN(body); i++) { VISIT_IN_SCOPE(c, stmt, (stmt_ty)asdl_seq_GET(body, i)); } + if (c->u->u_ste->ste_coroutine || c->u->u_ste->ste_generator) { + if (wrap_in_stopiteration_handler(c) < 0) { + compiler_exit_scope(c); + return ERROR; + } + } co = assemble(c, 1); - qualname = c->u->u_qualname; - Py_INCREF(qualname); compiler_exit_scope(c); if (co == NULL) { - Py_XDECREF(qualname); Py_XDECREF(co); - return 0; + return ERROR; } - - if (!compiler_make_closure(c, co, funcflags, qualname)) { - Py_DECREF(qualname); + if (compiler_make_closure(c, loc, co, funcflags) < 0) { Py_DECREF(co); - return 0; + return ERROR; } - Py_DECREF(qualname); Py_DECREF(co); - /* decorators */ - for (i = 0; i < asdl_seq_LEN(decos); i++) { - ADDOP_I(c, CALL_FUNCTION, 1); - } - - return compiler_nameop(c, name, Store); + RETURN_IF_ERROR(compiler_apply_decorators(c, decos)); + return compiler_nameop(c, loc, name, Store); } static int compiler_class(struct compiler *c, stmt_ty s) { PyCodeObject *co; - PyObject *str; int i, firstlineno; asdl_expr_seq *decos = s->v.ClassDef.decorator_list; - if (!compiler_decorators(c, decos)) - return 0; + RETURN_IF_ERROR(compiler_decorators(c, decos)); firstlineno = s->lineno; if (asdl_seq_LEN(decos)) { @@ -2488,131 +2714,111 @@ compiler_class(struct compiler *c, stmt_ty s) /* ultimately generate code for: = __build_class__(, , *, **) where: - is a function/closure created from the class body; - it has a single argument (__locals__) where the dict - (or MutableSequence) representing the locals is passed + is a zero arg function/closure created from the class body. + It mutates its locals to build the class namespace. is the class name is the positional arguments and *varargs argument is the keyword arguments and **kwds argument This borrows from compiler_call. */ - /* 1. compile the class body into a code object */ - if (!compiler_enter_scope(c, s->v.ClassDef.name, - COMPILER_SCOPE_CLASS, (void *)s, firstlineno)) - return 0; + RETURN_IF_ERROR( + compiler_enter_scope(c, s->v.ClassDef.name, + COMPILER_SCOPE_CLASS, (void *)s, firstlineno)); + /* this block represents what we do in the new scope */ { + location loc = LOCATION(firstlineno, firstlineno, 0, 0); /* use the class name for name mangling */ - Py_INCREF(s->v.ClassDef.name); - Py_XSETREF(c->u->u_private, s->v.ClassDef.name); + Py_XSETREF(c->u->u_private, Py_NewRef(s->v.ClassDef.name)); /* load (global) __name__ ... */ - str = PyUnicode_InternFromString("__name__"); - if (!str || !compiler_nameop(c, str, Load)) { - Py_XDECREF(str); + if (compiler_nameop(c, loc, &_Py_ID(__name__), Load) < 0) { compiler_exit_scope(c); - return 0; + return ERROR; } - Py_DECREF(str); /* ... and store it as __module__ */ - str = PyUnicode_InternFromString("__module__"); - if (!str || !compiler_nameop(c, str, Store)) { - Py_XDECREF(str); + if (compiler_nameop(c, loc, &_Py_ID(__module__), Store) < 0) { compiler_exit_scope(c); - return 0; + return ERROR; } - Py_DECREF(str); assert(c->u->u_qualname); - ADDOP_LOAD_CONST(c, c->u->u_qualname); - str = PyUnicode_InternFromString("__qualname__"); - if (!str || !compiler_nameop(c, str, Store)) { - Py_XDECREF(str); + ADDOP_LOAD_CONST(c, loc, c->u->u_qualname); + if (compiler_nameop(c, loc, &_Py_ID(__qualname__), Store) < 0) { compiler_exit_scope(c); - return 0; + return ERROR; } - Py_DECREF(str); /* compile the body proper */ - if (!compiler_body(c, s->v.ClassDef.body)) { + if (compiler_body(c, loc, s->v.ClassDef.body) < 0) { compiler_exit_scope(c); - return 0; + return ERROR; } /* The following code is artificial */ - UNSET_LOC(c); /* Return __classcell__ if it is referenced, otherwise return None */ if (c->u->u_ste->ste_needs_class_closure) { /* Store __classcell__ into class namespace & return it */ - str = PyUnicode_InternFromString("__class__"); - if (str == NULL) { - compiler_exit_scope(c); - return 0; - } - i = compiler_lookup_arg(c->u->u_cellvars, str); - Py_DECREF(str); + i = compiler_lookup_arg(c->u->u_cellvars, &_Py_ID(__class__)); if (i < 0) { compiler_exit_scope(c); - return 0; + return ERROR; } assert(i == 0); - - ADDOP_I(c, LOAD_CLOSURE, i); - ADDOP(c, DUP_TOP); - str = PyUnicode_InternFromString("__classcell__"); - if (!str || !compiler_nameop(c, str, Store)) { - Py_XDECREF(str); + ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i); + ADDOP_I(c, NO_LOCATION, COPY, 1); + if (compiler_nameop(c, NO_LOCATION, &_Py_ID(__classcell__), Store) < 0) { compiler_exit_scope(c); - return 0; + return ERROR; } - Py_DECREF(str); } else { /* No methods referenced __class__, so just return None */ assert(PyDict_GET_SIZE(c->u->u_cellvars) == 0); - ADDOP_LOAD_CONST(c, Py_None); + ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); } - ADDOP_IN_SCOPE(c, RETURN_VALUE); + ADDOP_IN_SCOPE(c, NO_LOCATION, RETURN_VALUE); /* create the code object */ co = assemble(c, 1); } /* leave the new scope */ compiler_exit_scope(c); - if (co == NULL) - return 0; + if (co == NULL) { + return ERROR; + } + location loc = LOC(s); /* 2. load the 'build_class' function */ - ADDOP(c, LOAD_BUILD_CLASS); + ADDOP(c, loc, PUSH_NULL); + ADDOP(c, loc, LOAD_BUILD_CLASS); /* 3. load a function (or closure) made from the code object */ - if (!compiler_make_closure(c, co, 0, NULL)) { + if (compiler_make_closure(c, loc, co, 0) < 0) { Py_DECREF(co); - return 0; + return ERROR; } Py_DECREF(co); /* 4. load class name */ - ADDOP_LOAD_CONST(c, s->v.ClassDef.name); + ADDOP_LOAD_CONST(c, loc, s->v.ClassDef.name); /* 5. generate the rest of the code for the call */ - if (!compiler_call_helper(c, 2, s->v.ClassDef.bases, s->v.ClassDef.keywords)) - return 0; + RETURN_IF_ERROR(compiler_call_helper(c, loc, 2, + s->v.ClassDef.bases, + s->v.ClassDef.keywords)); /* 6. apply decorators */ - for (i = 0; i < asdl_seq_LEN(decos); i++) { - ADDOP_I(c, CALL_FUNCTION, 1); - } + RETURN_IF_ERROR(compiler_apply_decorators(c, decos)); /* 7. store into */ - if (!compiler_nameop(c, s->v.ClassDef.name, Store)) - return 0; - return 1; + RETURN_IF_ERROR(compiler_nameop(c, loc, s->v.ClassDef.name, Store)); + return SUCCESS; } -/* Return 0 if the expression is a constant value except named singletons. - Return 1 otherwise. */ -static int +/* Return false if the expression is a constant value except named singletons. + Return true otherwise. */ +static bool check_is_arg(expr_ty e) { if (e->kind != Constant_kind) { - return 1; + return true; } PyObject *value = e->v.Constant.value; return (value == Py_None @@ -2621,33 +2827,33 @@ check_is_arg(expr_ty e) || value == Py_Ellipsis); } -/* Check operands of identity chacks ("is" and "is not"). +/* Check operands of identity checks ("is" and "is not"). Emit a warning if any operand is a constant except named singletons. - Return 0 on error. */ static int check_compare(struct compiler *c, expr_ty e) { Py_ssize_t i, n; - int left = check_is_arg(e->v.Compare.left); + bool left = check_is_arg(e->v.Compare.left); n = asdl_seq_LEN(e->v.Compare.ops); for (i = 0; i < n; i++) { cmpop_ty op = (cmpop_ty)asdl_seq_GET(e->v.Compare.ops, i); - int right = check_is_arg((expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); + bool right = check_is_arg((expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); if (op == Is || op == IsNot) { if (!right || !left) { const char *msg = (op == Is) ? "\"is\" with a literal. Did you mean \"==\"?" : "\"is not\" with a literal. Did you mean \"!=\"?"; - return compiler_warn(c, msg); + return compiler_warn(c, LOC(e), msg); } } left = right; } - return 1; + return SUCCESS; } -static int compiler_addcompare(struct compiler *c, cmpop_ty op) +static int compiler_addcompare(struct compiler *c, location loc, + cmpop_ty op) { int cmp; switch (op) { @@ -2670,33 +2876,37 @@ static int compiler_addcompare(struct compiler *c, cmpop_ty op) cmp = Py_GE; break; case Is: - ADDOP_I(c, IS_OP, 0); - return 1; + ADDOP_I(c, loc, IS_OP, 0); + return SUCCESS; case IsNot: - ADDOP_I(c, IS_OP, 1); - return 1; + ADDOP_I(c, loc, IS_OP, 1); + return SUCCESS; case In: - ADDOP_I(c, CONTAINS_OP, 0); - return 1; + ADDOP_I(c, loc, CONTAINS_OP, 0); + return SUCCESS; case NotIn: - ADDOP_I(c, CONTAINS_OP, 1); - return 1; + ADDOP_I(c, loc, CONTAINS_OP, 1); + return SUCCESS; default: Py_UNREACHABLE(); } - ADDOP_I(c, COMPARE_OP, cmp); - return 1; + /* cmp goes in top bits of the oparg, while the low bits are used by quickened + * versions of this opcode to store the comparison mask. */ + ADDOP_I(c, loc, COMPARE_OP, cmp << 4); + return SUCCESS; } static int -compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) +compiler_jump_if(struct compiler *c, location loc, + expr_ty e, jump_target_label next, int cond) { switch (e->kind) { case UnaryOp_kind: - if (e->v.UnaryOp.op == Not) - return compiler_jump_if(c, e->v.UnaryOp.operand, next, !cond); + if (e->v.UnaryOp.op == Not) { + return compiler_jump_if(c, loc, e->v.UnaryOp.operand, next, !cond); + } /* fallback to general implementation */ break; case BoolOp_kind: { @@ -2704,75 +2914,66 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) Py_ssize_t i, n = asdl_seq_LEN(s) - 1; assert(n >= 0); int cond2 = e->v.BoolOp.op == Or; - basicblock *next2 = next; + jump_target_label next2 = next; if (!cond2 != !cond) { - next2 = compiler_new_block(c); - if (next2 == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, new_next2); + next2 = new_next2; } for (i = 0; i < n; ++i) { - if (!compiler_jump_if(c, (expr_ty)asdl_seq_GET(s, i), next2, cond2)) - return 0; + RETURN_IF_ERROR( + compiler_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, i), next2, cond2)); } - if (!compiler_jump_if(c, (expr_ty)asdl_seq_GET(s, n), next, cond)) - return 0; - if (next2 != next) - compiler_use_next_block(c, next2); - return 1; + RETURN_IF_ERROR( + compiler_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, n), next, cond)); + if (!SAME_LABEL(next2, next)) { + USE_LABEL(c, next2); + } + return SUCCESS; } case IfExp_kind: { - basicblock *end, *next2; - end = compiler_new_block(c); - if (end == NULL) - return 0; - next2 = compiler_new_block(c); - if (next2 == NULL) - return 0; - if (!compiler_jump_if(c, e->v.IfExp.test, next2, 0)) - return 0; - if (!compiler_jump_if(c, e->v.IfExp.body, next, cond)) - return 0; - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); - compiler_use_next_block(c, next2); - if (!compiler_jump_if(c, e->v.IfExp.orelse, next, cond)) - return 0; - compiler_use_next_block(c, end); - return 1; + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, next2); + RETURN_IF_ERROR( + compiler_jump_if(c, loc, e->v.IfExp.test, next2, 0)); + RETURN_IF_ERROR( + compiler_jump_if(c, loc, e->v.IfExp.body, next, cond)); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); + + USE_LABEL(c, next2); + RETURN_IF_ERROR( + compiler_jump_if(c, loc, e->v.IfExp.orelse, next, cond)); + + USE_LABEL(c, end); + return SUCCESS; } case Compare_kind: { - Py_ssize_t i, n = asdl_seq_LEN(e->v.Compare.ops) - 1; + Py_ssize_t n = asdl_seq_LEN(e->v.Compare.ops) - 1; if (n > 0) { - if (!check_compare(c, e)) { - return 0; - } - basicblock *cleanup = compiler_new_block(c); - if (cleanup == NULL) - return 0; + RETURN_IF_ERROR(check_compare(c, e)); + NEW_JUMP_TARGET_LABEL(c, cleanup); VISIT(c, expr, e->v.Compare.left); - for (i = 0; i < n; i++) { + for (Py_ssize_t i = 0; i < n; i++) { VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); - ADDOP(c, DUP_TOP); - ADDOP(c, ROT_THREE); - ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i)); - ADDOP_JUMP(c, POP_JUMP_IF_FALSE, cleanup); - NEXT_BLOCK(c); + ADDOP_I(c, LOC(e), SWAP, 2); + ADDOP_I(c, LOC(e), COPY, 2); + ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, i)); + ADDOP_JUMP(c, LOC(e), POP_JUMP_IF_FALSE, cleanup); } VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); - ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, n)); - ADDOP_JUMP(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); - NEXT_BLOCK(c); - basicblock *end = compiler_new_block(c); - if (end == NULL) - return 0; - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); - compiler_use_next_block(c, cleanup); - ADDOP(c, POP_TOP); + ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, n)); + ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); + NEW_JUMP_TARGET_LABEL(c, end); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); + + USE_LABEL(c, cleanup); + ADDOP(c, LOC(e), POP_TOP); if (!cond) { - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, next); + ADDOP_JUMP(c, NO_LOCATION, JUMP, next); } - compiler_use_next_block(c, end); - return 1; + + USE_LABEL(c, end); + return SUCCESS; } /* fallback to general implementation */ break; @@ -2784,65 +2985,54 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) /* general implementation */ VISIT(c, expr, e); - ADDOP_JUMP(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); - NEXT_BLOCK(c); - return 1; + ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); + return SUCCESS; } static int compiler_ifexp(struct compiler *c, expr_ty e) { - basicblock *end, *next; - assert(e->kind == IfExp_kind); - end = compiler_new_block(c); - if (end == NULL) - return 0; - next = compiler_new_block(c); - if (next == NULL) - return 0; - if (!compiler_jump_if(c, e->v.IfExp.test, next, 0)) - return 0; + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, next); + + RETURN_IF_ERROR( + compiler_jump_if(c, LOC(e), e->v.IfExp.test, next, 0)); + VISIT(c, expr, e->v.IfExp.body); - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); - compiler_use_next_block(c, next); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); + + USE_LABEL(c, next); VISIT(c, expr, e->v.IfExp.orelse); - compiler_use_next_block(c, end); - return 1; + + USE_LABEL(c, end); + return SUCCESS; } static int compiler_lambda(struct compiler *c, expr_ty e) { PyCodeObject *co; - PyObject *qualname; - identifier name; Py_ssize_t funcflags; arguments_ty args = e->v.Lambda.args; assert(e->kind == Lambda_kind); - if (!compiler_check_debug_args(c, args)) - return 0; + RETURN_IF_ERROR(compiler_check_debug_args(c, args)); - _Py_static_string(PyId_lambda, ""); - name = _PyUnicode_FromId(&PyId_lambda); /* borrowed ref */ - if (name == NULL) { - return 0; - } - - funcflags = compiler_default_arguments(c, args); + location loc = LOC(e); + funcflags = compiler_default_arguments(c, loc, args); if (funcflags == -1) { return 0; } - if (!compiler_enter_scope(c, name, COMPILER_SCOPE_LAMBDA, - (void *)e, e->lineno)) - return 0; + _Py_DECLARE_STR(anon_lambda, ""); + RETURN_IF_ERROR( + compiler_enter_scope(c, &_Py_STR(anon_lambda), COMPILER_SCOPE_LAMBDA, + (void *)e, e->lineno)); /* Make None the first constant, so the lambda can't have a docstring. */ - if (compiler_add_const(c, Py_None) < 0) - return 0; + RETURN_IF_ERROR(compiler_add_const(c, Py_None)); c->u->u_argcount = asdl_seq_LEN(args->args); c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs); @@ -2852,264 +3042,248 @@ compiler_lambda(struct compiler *c, expr_ty e) co = assemble(c, 0); } else { - ADDOP_IN_SCOPE(c, RETURN_VALUE); + location loc = LOCATION(e->lineno, e->lineno, 0, 0); + ADDOP_IN_SCOPE(c, loc, RETURN_VALUE); co = assemble(c, 1); } - qualname = c->u->u_qualname; - Py_INCREF(qualname); compiler_exit_scope(c); if (co == NULL) { - Py_DECREF(qualname); - return 0; + return ERROR; } - if (!compiler_make_closure(c, co, funcflags, qualname)) { - Py_DECREF(qualname); + if (compiler_make_closure(c, loc, co, funcflags) < 0) { Py_DECREF(co); - return 0; + return ERROR; } - Py_DECREF(qualname); Py_DECREF(co); - return 1; + return SUCCESS; } static int compiler_if(struct compiler *c, stmt_ty s) { - basicblock *end, *next; + jump_target_label next; assert(s->kind == If_kind); - end = compiler_new_block(c); - if (end == NULL) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, end); if (asdl_seq_LEN(s->v.If.orelse)) { - next = compiler_new_block(c); - if (next == NULL) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, orelse); + next = orelse; } else { next = end; } - if (!compiler_jump_if(c, s->v.If.test, next, 0)) { - return 0; - } + RETURN_IF_ERROR( + compiler_jump_if(c, LOC(s), s->v.If.test, next, 0)); + VISIT_SEQ(c, stmt, s->v.If.body); if (asdl_seq_LEN(s->v.If.orelse)) { - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); - compiler_use_next_block(c, next); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); + + USE_LABEL(c, next); VISIT_SEQ(c, stmt, s->v.If.orelse); } - compiler_use_next_block(c, end); - return 1; + + USE_LABEL(c, end); + return SUCCESS; } static int compiler_for(struct compiler *c, stmt_ty s) { - basicblock *start, *body, *cleanup, *end; + location loc = LOC(s); + NEW_JUMP_TARGET_LABEL(c, start); + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, cleanup); + NEW_JUMP_TARGET_LABEL(c, end); + + RETURN_IF_ERROR(compiler_push_fblock(c, loc, FOR_LOOP, start, end, NULL)); - start = compiler_new_block(c); - body = compiler_new_block(c); - cleanup = compiler_new_block(c); - end = compiler_new_block(c); - if (start == NULL || body == NULL || end == NULL || cleanup == NULL) { - return 0; - } - if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) { - return 0; - } VISIT(c, expr, s->v.For.iter); - ADDOP(c, GET_ITER); - compiler_use_next_block(c, start); - ADDOP_JUMP(c, FOR_ITER, cleanup); - compiler_use_next_block(c, body); + ADDOP(c, loc, GET_ITER); + + USE_LABEL(c, start); + ADDOP_JUMP(c, loc, FOR_ITER, cleanup); + + USE_LABEL(c, body); VISIT(c, expr, s->v.For.target); VISIT_SEQ(c, stmt, s->v.For.body); /* Mark jump as artificial */ - UNSET_LOC(c); - ADDOP_JUMP(c, JUMP_ABSOLUTE, start); - compiler_use_next_block(c, cleanup); + ADDOP_JUMP(c, NO_LOCATION, JUMP, start); + + USE_LABEL(c, cleanup); + ADDOP(c, NO_LOCATION, END_FOR); compiler_pop_fblock(c, FOR_LOOP, start); VISIT_SEQ(c, stmt, s->v.For.orelse); - compiler_use_next_block(c, end); - return 1; + + USE_LABEL(c, end); + return SUCCESS; } static int compiler_async_for(struct compiler *c, stmt_ty s) { - basicblock *start, *except, *end; + location loc = LOC(s); if (IS_TOP_LEVEL_AWAIT(c)){ c->u->u_ste->ste_coroutine = 1; } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) { - return compiler_error(c, "'async for' outside async function"); + return compiler_error(c, loc, "'async for' outside async function"); } - start = compiler_new_block(c); - except = compiler_new_block(c); - end = compiler_new_block(c); + NEW_JUMP_TARGET_LABEL(c, start); + NEW_JUMP_TARGET_LABEL(c, except); + NEW_JUMP_TARGET_LABEL(c, end); - if (start == NULL || except == NULL || end == NULL) { - return 0; - } VISIT(c, expr, s->v.AsyncFor.iter); - ADDOP(c, GET_AITER); + ADDOP(c, loc, GET_AITER); + + USE_LABEL(c, start); + RETURN_IF_ERROR(compiler_push_fblock(c, loc, FOR_LOOP, start, end, NULL)); - compiler_use_next_block(c, start); - if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) { - return 0; - } /* SETUP_FINALLY to guard the __anext__ call */ - ADDOP_JUMP(c, SETUP_FINALLY, except); - ADDOP(c, GET_ANEXT); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); - ADDOP(c, POP_BLOCK); /* for SETUP_FINALLY */ + ADDOP_JUMP(c, loc, SETUP_FINALLY, except); + ADDOP(c, loc, GET_ANEXT); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADD_YIELD_FROM(c, loc, 1); + ADDOP(c, loc, POP_BLOCK); /* for SETUP_FINALLY */ /* Success block for __anext__ */ VISIT(c, expr, s->v.AsyncFor.target); VISIT_SEQ(c, stmt, s->v.AsyncFor.body); - ADDOP_JUMP(c, JUMP_ABSOLUTE, start); + /* Mark jump as artificial */ + ADDOP_JUMP(c, NO_LOCATION, JUMP, start); compiler_pop_fblock(c, FOR_LOOP, start); /* Except block for __anext__ */ - compiler_use_next_block(c, except); + USE_LABEL(c, except); /* Use same line number as the iterator, * as the END_ASYNC_FOR succeeds the `for`, not the body. */ - SET_LOC(c, s->v.AsyncFor.iter); - ADDOP(c, END_ASYNC_FOR); + loc = LOC(s->v.AsyncFor.iter); + ADDOP(c, loc, END_ASYNC_FOR); /* `else` block */ VISIT_SEQ(c, stmt, s->v.For.orelse); - compiler_use_next_block(c, end); - - return 1; + USE_LABEL(c, end); + return SUCCESS; } static int compiler_while(struct compiler *c, stmt_ty s) { - basicblock *loop, *body, *end, *anchor = NULL; - loop = compiler_new_block(c); - body = compiler_new_block(c); - anchor = compiler_new_block(c); - end = compiler_new_block(c); - if (loop == NULL || body == NULL || anchor == NULL || end == NULL) { - return 0; - } - compiler_use_next_block(c, loop); - if (!compiler_push_fblock(c, WHILE_LOOP, loop, end, NULL)) { - return 0; - } - if (!compiler_jump_if(c, s->v.While.test, anchor, 0)) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, loop); + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, anchor); - compiler_use_next_block(c, body); + USE_LABEL(c, loop); + + RETURN_IF_ERROR(compiler_push_fblock(c, LOC(s), WHILE_LOOP, loop, end, NULL)); + RETURN_IF_ERROR(compiler_jump_if(c, LOC(s), s->v.While.test, anchor, 0)); + + USE_LABEL(c, body); VISIT_SEQ(c, stmt, s->v.While.body); - SET_LOC(c, s); - if (!compiler_jump_if(c, s->v.While.test, body, 1)) { - return 0; - } + RETURN_IF_ERROR(compiler_jump_if(c, LOC(s), s->v.While.test, body, 1)); compiler_pop_fblock(c, WHILE_LOOP, loop); - compiler_use_next_block(c, anchor); + USE_LABEL(c, anchor); if (s->v.While.orelse) { VISIT_SEQ(c, stmt, s->v.While.orelse); } - compiler_use_next_block(c, end); - return 1; + USE_LABEL(c, end); + return SUCCESS; } static int compiler_return(struct compiler *c, stmt_ty s) { + location loc = LOC(s); int preserve_tos = ((s->v.Return.value != NULL) && (s->v.Return.value->kind != Constant_kind)); - if (c->u->u_ste->ste_type != FunctionBlock) - return compiler_error(c, "'return' outside function"); + if (c->u->u_ste->ste_type != FunctionBlock) { + return compiler_error(c, loc, "'return' outside function"); + } if (s->v.Return.value != NULL && c->u->u_ste->ste_coroutine && c->u->u_ste->ste_generator) { - return compiler_error( - c, "'return' with value in async generator"); + return compiler_error(c, loc, "'return' with value in async generator"); } + if (preserve_tos) { VISIT(c, expr, s->v.Return.value); } else { /* Emit instruction with line number for return value */ if (s->v.Return.value != NULL) { - SET_LOC(c, s->v.Return.value); - ADDOP(c, NOP); + loc = LOC(s->v.Return.value); + ADDOP(c, loc, NOP); } } if (s->v.Return.value == NULL || s->v.Return.value->lineno != s->lineno) { - SET_LOC(c, s); - ADDOP(c, NOP); + loc = LOC(s); + ADDOP(c, loc, NOP); } - if (!compiler_unwind_fblock_stack(c, preserve_tos, NULL)) - return 0; + RETURN_IF_ERROR(compiler_unwind_fblock_stack(c, &loc, preserve_tos, NULL)); if (s->v.Return.value == NULL) { - ADDOP_LOAD_CONST(c, Py_None); + ADDOP_LOAD_CONST(c, loc, Py_None); } else if (!preserve_tos) { - ADDOP_LOAD_CONST(c, s->v.Return.value->v.Constant.value); + ADDOP_LOAD_CONST(c, loc, s->v.Return.value->v.Constant.value); } - ADDOP(c, RETURN_VALUE); - NEXT_BLOCK(c); + ADDOP(c, loc, RETURN_VALUE); - return 1; + return SUCCESS; } static int -compiler_break(struct compiler *c) +compiler_break(struct compiler *c, location loc) { struct fblockinfo *loop = NULL; /* Emit instruction with line number */ - ADDOP(c, NOP); - if (!compiler_unwind_fblock_stack(c, 0, &loop)) { - return 0; - } + ADDOP(c, loc, NOP); + RETURN_IF_ERROR(compiler_unwind_fblock_stack(c, &loc, 0, &loop)); if (loop == NULL) { - return compiler_error(c, "'break' outside loop"); + return compiler_error(c, loc, "'break' outside loop"); } - if (!compiler_unwind_fblock(c, loop, 0)) { - return 0; - } - ADDOP_JUMP(c, JUMP_ABSOLUTE, loop->fb_exit); - NEXT_BLOCK(c); - return 1; + RETURN_IF_ERROR(compiler_unwind_fblock(c, &loc, loop, 0)); + ADDOP_JUMP(c, loc, JUMP, loop->fb_exit); + return SUCCESS; } static int -compiler_continue(struct compiler *c) +compiler_continue(struct compiler *c, location loc) { struct fblockinfo *loop = NULL; /* Emit instruction with line number */ - ADDOP(c, NOP); - if (!compiler_unwind_fblock_stack(c, 0, &loop)) { - return 0; - } + ADDOP(c, loc, NOP); + RETURN_IF_ERROR(compiler_unwind_fblock_stack(c, &loc, 0, &loop)); if (loop == NULL) { - return compiler_error(c, "'continue' not properly in loop"); + return compiler_error(c, loc, "'continue' not properly in loop"); } - ADDOP_JUMP(c, JUMP_ABSOLUTE, loop->fb_block); - NEXT_BLOCK(c) - return 1; + ADDOP_JUMP(c, loc, JUMP, loop->fb_block); + return SUCCESS; } +static location +location_of_last_executing_statement(asdl_stmt_seq *stmts) +{ + for (Py_ssize_t i = asdl_seq_LEN(stmts) - 1; i >= 0; i++) { + location loc = LOC((stmt_ty)asdl_seq_GET(stmts, i)); + if (loc.lineno > 0) { + return loc; + } + } + return NO_LOCATION; +} + /* Code generated for "try: finally: " is as follows: SETUP_FINALLY L @@ -3142,48 +3316,106 @@ compiler_continue(struct compiler *c) static int compiler_try_finally(struct compiler *c, stmt_ty s) { - basicblock *body, *end, *exit, *cleanup; + location loc = LOC(s); + + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, exit); + NEW_JUMP_TARGET_LABEL(c, cleanup); - body = compiler_new_block(c); - end = compiler_new_block(c); - exit = compiler_new_block(c); - cleanup = compiler_new_block(c); - if (body == NULL || end == NULL || exit == NULL || cleanup == NULL) { - return 0; - } /* `try` block */ - ADDOP_JUMP(c, SETUP_FINALLY, end); - compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, FINALLY_TRY, body, end, s->v.Try.finalbody)) - return 0; + ADDOP_JUMP(c, loc, SETUP_FINALLY, end); + + USE_LABEL(c, body); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, FINALLY_TRY, body, end, + s->v.Try.finalbody)); + if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) { - if (!compiler_try_except(c, s)) - return 0; + RETURN_IF_ERROR(compiler_try_except(c, s)); } else { VISIT_SEQ(c, stmt, s->v.Try.body); } - ADDOP_NOLINE(c, POP_BLOCK); + ADDOP(c, NO_LOCATION, POP_BLOCK); compiler_pop_fblock(c, FINALLY_TRY, body); VISIT_SEQ(c, stmt, s->v.Try.finalbody); - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, exit); - /* `finally` block */ - compiler_use_next_block(c, end); - UNSET_LOC(c); - ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); - ADDOP(c, PUSH_EXC_INFO); - if (!compiler_push_fblock(c, FINALLY_END, end, NULL, NULL)) - return 0; + ADDOP_JUMP(c, NO_LOCATION, JUMP, exit); + /* `finally` block */ + + USE_LABEL(c, end); + + loc = NO_LOCATION; + ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup); + ADDOP(c, loc, PUSH_EXC_INFO); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, FINALLY_END, end, NO_LABEL, NULL)); VISIT_SEQ(c, stmt, s->v.Try.finalbody); + loc = location_of_last_executing_statement(s->v.Try.finalbody); compiler_pop_fblock(c, FINALLY_END, end); - ADDOP_I(c, RERAISE, 0); - compiler_use_next_block(c, cleanup); - ADDOP(c, POP_EXCEPT_AND_RERAISE); - compiler_use_next_block(c, exit); - return 1; + + ADDOP_I(c, loc, RERAISE, 0); + + USE_LABEL(c, cleanup); + POP_EXCEPT_AND_RERAISE(c, loc); + + USE_LABEL(c, exit); + return SUCCESS; } +static int +compiler_try_star_finally(struct compiler *c, stmt_ty s) +{ + location loc = LOC(s); + + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, exit); + NEW_JUMP_TARGET_LABEL(c, cleanup); + /* `try` block */ + ADDOP_JUMP(c, loc, SETUP_FINALLY, end); + + USE_LABEL(c, body); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, FINALLY_TRY, body, end, + s->v.TryStar.finalbody)); + + if (s->v.TryStar.handlers && asdl_seq_LEN(s->v.TryStar.handlers)) { + RETURN_IF_ERROR(compiler_try_star_except(c, s)); + } + else { + VISIT_SEQ(c, stmt, s->v.TryStar.body); + } + ADDOP(c, NO_LOCATION, POP_BLOCK); + compiler_pop_fblock(c, FINALLY_TRY, body); + VISIT_SEQ(c, stmt, s->v.TryStar.finalbody); + + ADDOP_JUMP(c, NO_LOCATION, JUMP, exit); + + /* `finally` block */ + USE_LABEL(c, end); + + loc = NO_LOCATION; + ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup); + ADDOP(c, loc, PUSH_EXC_INFO); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, FINALLY_END, end, NO_LABEL, NULL)); + + VISIT_SEQ(c, stmt, s->v.TryStar.finalbody); + loc = location_of_last_executing_statement(s->v.Try.finalbody); + + compiler_pop_fblock(c, FINALLY_END, end); + ADDOP_I(c, loc, RERAISE, 0); + + USE_LABEL(c, cleanup); + POP_EXCEPT_AND_RERAISE(c, loc); + + USE_LABEL(c, exit); + return SUCCESS; +} + + /* Code generated for "try: S except E1 as V1: S1 except E2 as V2: S2 ...": (The contents of the value stack is shown in [], with the top @@ -3194,20 +3426,19 @@ compiler_try_finally(struct compiler *c, stmt_ty s) [] SETUP_FINALLY L1 [] [] POP_BLOCK - [] JUMP_FORWARD L0 + [] JUMP L0 - [tb, val, exc] L1: ) - [tb, val, exc, E1] JUMP_IF_NOT_EXC_MATCH L2 ) only if E1 - [tb, val, exc] POP - [tb, val] (or POP if no V1) - [tb] POP + [exc] L1: ) + [exc, E1] CHECK_EXC_MATCH ) + [exc, bool] POP_JUMP_IF_FALSE L2 ) only if E1 + [exc] (or POP if no V1) [] - JUMP_FORWARD L0 + JUMP L0 - [tb, val, exc] L2: + [exc] L2: .............................etc....................... - [tb, val, exc] Ln+1: RERAISE # re-raise exception + [exc] Ln+1: RERAISE # re-raise exception [] L0: @@ -3216,60 +3447,57 @@ compiler_try_finally(struct compiler *c, stmt_ty s) static int compiler_try_except(struct compiler *c, stmt_ty s) { - basicblock *body, *orelse, *except, *end, *cleanup; + location loc = LOC(s); Py_ssize_t i, n; - body = compiler_new_block(c); - except = compiler_new_block(c); - orelse = compiler_new_block(c); - end = compiler_new_block(c); - cleanup = compiler_new_block(c); - if (body == NULL || except == NULL || orelse == NULL || end == NULL || cleanup == NULL) - return 0; - ADDOP_JUMP(c, SETUP_FINALLY, except); - compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, TRY_EXCEPT, body, NULL, NULL)) - return 0; + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, except); + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, cleanup); + + ADDOP_JUMP(c, loc, SETUP_FINALLY, except); + + USE_LABEL(c, body); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, TRY_EXCEPT, body, NO_LABEL, NULL)); VISIT_SEQ(c, stmt, s->v.Try.body); compiler_pop_fblock(c, TRY_EXCEPT, body); - ADDOP_NOLINE(c, POP_BLOCK); - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, orelse); + ADDOP(c, NO_LOCATION, POP_BLOCK); + if (s->v.Try.orelse && asdl_seq_LEN(s->v.Try.orelse)) { + VISIT_SEQ(c, stmt, s->v.Try.orelse); + } + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); n = asdl_seq_LEN(s->v.Try.handlers); - compiler_use_next_block(c, except); - UNSET_LOC(c); - ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); - ADDOP(c, PUSH_EXC_INFO); + USE_LABEL(c, except); + + ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup); + ADDOP(c, NO_LOCATION, PUSH_EXC_INFO); + /* Runtime will push a block here, so we need to account for that */ - if (!compiler_push_fblock(c, EXCEPTION_HANDLER, NULL, NULL, NULL)) - return 0; + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, EXCEPTION_HANDLER, NO_LABEL, NO_LABEL, NULL)); + for (i = 0; i < n; i++) { excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( s->v.Try.handlers, i); - SET_LOC(c, handler); + location loc = LOC(handler); if (!handler->v.ExceptHandler.type && i < n-1) { - return compiler_error(c, "default 'except:' must be last"); + return compiler_error(c, loc, "default 'except:' must be last"); } - except = compiler_new_block(c); - if (except == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, next_except); + except = next_except; if (handler->v.ExceptHandler.type) { VISIT(c, expr, handler->v.ExceptHandler.type); - ADDOP_JUMP(c, JUMP_IF_NOT_EXC_MATCH, except); - NEXT_BLOCK(c); + ADDOP(c, loc, CHECK_EXC_MATCH); + ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, except); } - ADDOP(c, POP_TOP); if (handler->v.ExceptHandler.name) { - basicblock *cleanup_end, *cleanup_body; + NEW_JUMP_TARGET_LABEL(c, cleanup_end); + NEW_JUMP_TARGET_LABEL(c, cleanup_body); - cleanup_end = compiler_new_block(c); - cleanup_body = compiler_new_block(c); - if (cleanup_end == NULL || cleanup_body == NULL) { - return 0; - } - - compiler_nameop(c, handler->v.ExceptHandler.name, Store); - ADDOP(c, POP_TOP); + RETURN_IF_ERROR( + compiler_nameop(c, loc, handler->v.ExceptHandler.name, Store)); /* try: @@ -3283,67 +3511,278 @@ compiler_try_except(struct compiler *c, stmt_ty s) */ /* second try: */ - ADDOP_JUMP(c, SETUP_CLEANUP, cleanup_end); - compiler_use_next_block(c, cleanup_body); - if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, handler->v.ExceptHandler.name)) - return 0; + ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end); + + USE_LABEL(c, cleanup_body); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, HANDLER_CLEANUP, cleanup_body, + NO_LABEL, handler->v.ExceptHandler.name)); /* second # body */ VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); /* name = None; del name; # Mark as artificial */ - UNSET_LOC(c); - ADDOP(c, POP_BLOCK); - ADDOP(c, POP_BLOCK); - ADDOP(c, POP_EXCEPT); - ADDOP_LOAD_CONST(c, Py_None); - compiler_nameop(c, handler->v.ExceptHandler.name, Store); - compiler_nameop(c, handler->v.ExceptHandler.name, Del); - ADDOP_JUMP(c, JUMP_FORWARD, end); + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP(c, NO_LOCATION, POP_EXCEPT); + ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + RETURN_IF_ERROR( + compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store)); + RETURN_IF_ERROR( + compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del)); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); /* except: */ - compiler_use_next_block(c, cleanup_end); + USE_LABEL(c, cleanup_end); - /* name = None; del name; # Mark as artificial */ - UNSET_LOC(c); + /* name = None; del name; # artificial */ + ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + RETURN_IF_ERROR( + compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store)); + RETURN_IF_ERROR( + compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del)); - ADDOP_LOAD_CONST(c, Py_None); - compiler_nameop(c, handler->v.ExceptHandler.name, Store); - compiler_nameop(c, handler->v.ExceptHandler.name, Del); - - ADDOP_I(c, RERAISE, 1); + ADDOP_I(c, NO_LOCATION, RERAISE, 1); } else { - basicblock *cleanup_body; + NEW_JUMP_TARGET_LABEL(c, cleanup_body); - cleanup_body = compiler_new_block(c); - if (!cleanup_body) - return 0; + ADDOP(c, loc, POP_TOP); /* exc_value */ + + USE_LABEL(c, cleanup_body); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, HANDLER_CLEANUP, cleanup_body, + NO_LABEL, NULL)); - ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); - compiler_use_next_block(c, cleanup_body); - if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, NULL)) - return 0; VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); - UNSET_LOC(c); - ADDOP(c, POP_BLOCK); - ADDOP(c, POP_EXCEPT); - ADDOP_JUMP(c, JUMP_FORWARD, end); + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP(c, NO_LOCATION, POP_EXCEPT); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); } - compiler_use_next_block(c, except); + + USE_LABEL(c, except); } - /* Mark as artificial */ - UNSET_LOC(c); - compiler_pop_fblock(c, EXCEPTION_HANDLER, NULL); - ADDOP_I(c, RERAISE, 0); - compiler_use_next_block(c, cleanup); - ADDOP(c, POP_EXCEPT_AND_RERAISE); - compiler_use_next_block(c, orelse); - VISIT_SEQ(c, stmt, s->v.Try.orelse); - compiler_use_next_block(c, end); - return 1; + /* artificial */ + compiler_pop_fblock(c, EXCEPTION_HANDLER, NO_LABEL); + ADDOP_I(c, NO_LOCATION, RERAISE, 0); + + USE_LABEL(c, cleanup); + POP_EXCEPT_AND_RERAISE(c, NO_LOCATION); + + USE_LABEL(c, end); + return SUCCESS; +} + +/* + Code generated for "try: S except* E1 as V1: S1 except* E2 as V2: S2 ...": + (The contents of the value stack is shown in [], with the top + at the right; 'tb' is trace-back info, 'val' the exception instance, + and 'typ' the exception's type.) + + Value stack Label Instruction Argument + [] SETUP_FINALLY L1 + [] + [] POP_BLOCK + [] JUMP L0 + + [exc] L1: BUILD_LIST ) list for raised/reraised excs ("result") + [orig, res] COPY 2 ) make a copy of the original EG + + [orig, res, exc] + [orig, res, exc, E1] CHECK_EG_MATCH + [orig, res, rest/exc, match?] COPY 1 + [orig, res, rest/exc, match?, match?] POP_JUMP_IF_NOT_NONE H1 + [orig, res, exc, None] POP_TOP + [orig, res, exc] JUMP L2 + + [orig, res, rest, match] H1: (or POP if no V1) + + [orig, res, rest] SETUP_FINALLY R1 + [orig, res, rest] + [orig, res, rest] JUMP L2 + + [orig, res, rest, i, v] R1: LIST_APPEND 3 ) exc raised in except* body - add to res + [orig, res, rest, i] POP + + [orig, res, rest] L2: + .............................etc....................... + + [orig, res, rest] Ln+1: LIST_APPEND 1 ) add unhandled exc to res (could be None) + + [orig, res] PREP_RERAISE_STAR + [exc] COPY 1 + [exc, exc] POP_JUMP_IF_NOT_NONE RER + [exc] POP_TOP + [] JUMP L0 + + [exc] RER: SWAP 2 + [exc, prev_exc_info] POP_EXCEPT + [exc] RERAISE 0 + + [] L0: +*/ +static int +compiler_try_star_except(struct compiler *c, stmt_ty s) +{ + location loc = LOC(s); + + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, except); + NEW_JUMP_TARGET_LABEL(c, orelse); + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, cleanup); + NEW_JUMP_TARGET_LABEL(c, reraise_star); + + ADDOP_JUMP(c, loc, SETUP_FINALLY, except); + + USE_LABEL(c, body); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, TRY_EXCEPT, body, NO_LABEL, NULL)); + VISIT_SEQ(c, stmt, s->v.TryStar.body); + compiler_pop_fblock(c, TRY_EXCEPT, body); + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP_JUMP(c, NO_LOCATION, JUMP, orelse); + Py_ssize_t n = asdl_seq_LEN(s->v.TryStar.handlers); + + USE_LABEL(c, except); + + ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup); + ADDOP(c, NO_LOCATION, PUSH_EXC_INFO); + + /* Runtime will push a block here, so we need to account for that */ + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, EXCEPTION_GROUP_HANDLER, + NO_LABEL, NO_LABEL, "except handler")); + + for (Py_ssize_t i = 0; i < n; i++) { + excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( + s->v.TryStar.handlers, i); + location loc = LOC(handler); + NEW_JUMP_TARGET_LABEL(c, next_except); + except = next_except; + NEW_JUMP_TARGET_LABEL(c, handle_match); + if (i == 0) { + /* create empty list for exceptions raised/reraise in the except* blocks */ + /* + [orig] BUILD_LIST + */ + /* Create a copy of the original EG */ + /* + [orig, []] COPY 2 + [orig, [], exc] + */ + ADDOP_I(c, loc, BUILD_LIST, 0); + ADDOP_I(c, loc, COPY, 2); + } + if (handler->v.ExceptHandler.type) { + VISIT(c, expr, handler->v.ExceptHandler.type); + ADDOP(c, loc, CHECK_EG_MATCH); + ADDOP_I(c, loc, COPY, 1); + ADDOP_JUMP(c, loc, POP_JUMP_IF_NOT_NONE, handle_match); + ADDOP(c, loc, POP_TOP); // match + ADDOP_JUMP(c, loc, JUMP, except); + } + + USE_LABEL(c, handle_match); + + NEW_JUMP_TARGET_LABEL(c, cleanup_end); + NEW_JUMP_TARGET_LABEL(c, cleanup_body); + + if (handler->v.ExceptHandler.name) { + RETURN_IF_ERROR( + compiler_nameop(c, loc, handler->v.ExceptHandler.name, Store)); + } + else { + ADDOP(c, loc, POP_TOP); // match + } + + /* + try: + # body + except type as name: + try: + # body + finally: + name = None # in case body contains "del name" + del name + */ + /* second try: */ + ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end); + + USE_LABEL(c, cleanup_body); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, HANDLER_CLEANUP, cleanup_body, + NO_LABEL, handler->v.ExceptHandler.name)); + + /* second # body */ + VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); + compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); + /* name = None; del name; # artificial */ + ADDOP(c, NO_LOCATION, POP_BLOCK); + if (handler->v.ExceptHandler.name) { + ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + RETURN_IF_ERROR( + compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store)); + RETURN_IF_ERROR( + compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del)); + } + ADDOP_JUMP(c, NO_LOCATION, JUMP, except); + + /* except: */ + USE_LABEL(c, cleanup_end); + + /* name = None; del name; # artificial */ + if (handler->v.ExceptHandler.name) { + ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + RETURN_IF_ERROR( + compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store)); + RETURN_IF_ERROR( + compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del)); + } + + /* add exception raised to the res list */ + ADDOP_I(c, NO_LOCATION, LIST_APPEND, 3); // exc + ADDOP(c, NO_LOCATION, POP_TOP); // lasti + ADDOP_JUMP(c, NO_LOCATION, JUMP, except); + + USE_LABEL(c, except); + + if (i == n - 1) { + /* Add exc to the list (if not None it's the unhandled part of the EG) */ + ADDOP_I(c, NO_LOCATION, LIST_APPEND, 1); + ADDOP_JUMP(c, NO_LOCATION, JUMP, reraise_star); + } + } + /* artificial */ + compiler_pop_fblock(c, EXCEPTION_GROUP_HANDLER, NO_LABEL); + NEW_JUMP_TARGET_LABEL(c, reraise); + + USE_LABEL(c, reraise_star); + ADDOP(c, NO_LOCATION, PREP_RERAISE_STAR); + ADDOP_I(c, NO_LOCATION, COPY, 1); + ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_NOT_NONE, reraise); + + /* Nothing to reraise */ + ADDOP(c, NO_LOCATION, POP_TOP); + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP(c, NO_LOCATION, POP_EXCEPT); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); + + USE_LABEL(c, reraise); + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP_I(c, NO_LOCATION, SWAP, 2); + ADDOP(c, NO_LOCATION, POP_EXCEPT); + ADDOP_I(c, NO_LOCATION, RERAISE, 0); + + USE_LABEL(c, cleanup); + POP_EXCEPT_AND_RERAISE(c, NO_LOCATION); + + USE_LABEL(c, orelse); + VISIT_SEQ(c, stmt, s->v.TryStar.orelse); + + USE_LABEL(c, end); + return SUCCESS; } static int @@ -3354,9 +3793,20 @@ compiler_try(struct compiler *c, stmt_ty s) { return compiler_try_except(c, s); } +static int +compiler_try_star(struct compiler *c, stmt_ty s) +{ + if (s->v.TryStar.finalbody && asdl_seq_LEN(s->v.TryStar.finalbody)) { + return compiler_try_star_finally(c, s); + } + else { + return compiler_try_star_except(c, s); + } +} static int -compiler_import_as(struct compiler *c, identifier name, identifier asname) +compiler_import_as(struct compiler *c, location loc, + identifier name, identifier asname) { /* The IMPORT_NAME opcode was already generated. This function merely needs to bind the result to a name. @@ -3366,38 +3816,40 @@ compiler_import_as(struct compiler *c, identifier name, identifier asname) */ Py_ssize_t len = PyUnicode_GET_LENGTH(name); Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, len, 1); - if (dot == -2) - return 0; + if (dot == -2) { + return ERROR; + } if (dot != -1) { /* Consume the base module name to get the first attribute */ while (1) { Py_ssize_t pos = dot + 1; PyObject *attr; dot = PyUnicode_FindChar(name, '.', pos, len, 1); - if (dot == -2) - return 0; + if (dot == -2) { + return ERROR; + } attr = PyUnicode_Substring(name, pos, (dot != -1) ? dot : len); - if (!attr) - return 0; - ADDOP_N(c, IMPORT_FROM, attr, names); + if (!attr) { + return ERROR; + } + ADDOP_N(c, loc, IMPORT_FROM, attr, names); if (dot == -1) { break; } - ADDOP(c, ROT_TWO); - ADDOP(c, POP_TOP); + ADDOP_I(c, loc, SWAP, 2); + ADDOP(c, loc, POP_TOP); } - if (!compiler_nameop(c, asname, Store)) { - return 0; - } - ADDOP(c, POP_TOP); - return 1; + RETURN_IF_ERROR(compiler_nameop(c, loc, asname, Store)); + ADDOP(c, loc, POP_TOP); + return SUCCESS; } - return compiler_nameop(c, asname, Store); + return compiler_nameop(c, loc, asname, Store); } static int compiler_import(struct compiler *c, stmt_ty s) { + location loc = LOC(s); /* The Import node stores a module name like a.b.c as a single string. This is convenient for all cases except import a.b.c as d @@ -3412,14 +3864,13 @@ compiler_import(struct compiler *c, stmt_ty s) alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i); int r; - ADDOP_LOAD_CONST(c, zero); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP_NAME(c, IMPORT_NAME, alias->name, names); + ADDOP_LOAD_CONST(c, loc, zero); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADDOP_NAME(c, loc, IMPORT_NAME, alias->name, names); if (alias->asname) { - r = compiler_import_as(c, alias->name, alias->asname); - if (!r) - return r; + r = compiler_import_as(c, loc, alias->name, alias->asname); + RETURN_IF_ERROR(r); } else { identifier tmp = alias->name; @@ -3427,88 +3878,82 @@ compiler_import(struct compiler *c, stmt_ty s) alias->name, '.', 0, PyUnicode_GET_LENGTH(alias->name), 1); if (dot != -1) { tmp = PyUnicode_Substring(alias->name, 0, dot); - if (tmp == NULL) - return 0; + if (tmp == NULL) { + return ERROR; + } } - r = compiler_nameop(c, tmp, Store); + r = compiler_nameop(c, loc, tmp, Store); if (dot != -1) { Py_DECREF(tmp); } - if (!r) - return r; + RETURN_IF_ERROR(r); } } - return 1; + return SUCCESS; } static int compiler_from_import(struct compiler *c, stmt_ty s) { - Py_ssize_t i, n = asdl_seq_LEN(s->v.ImportFrom.names); - PyObject *names; - _Py_static_string(PyId_empty_string, ""); - PyObject *empty_string = _PyUnicode_FromId(&PyId_empty_string); /* borrowed ref */ + Py_ssize_t n = asdl_seq_LEN(s->v.ImportFrom.names); - if (empty_string == NULL) { - return 0; + ADDOP_LOAD_CONST_NEW(c, LOC(s), PyLong_FromLong(s->v.ImportFrom.level)); + + PyObject *names = PyTuple_New(n); + if (!names) { + return ERROR; } - ADDOP_LOAD_CONST_NEW(c, PyLong_FromLong(s->v.ImportFrom.level)); - - names = PyTuple_New(n); - if (!names) - return 0; - /* build up the names */ - for (i = 0; i < n; i++) { + for (Py_ssize_t i = 0; i < n; i++) { alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i); - Py_INCREF(alias->name); - PyTuple_SET_ITEM(names, i, alias->name); + PyTuple_SET_ITEM(names, i, Py_NewRef(alias->name)); } - if (s->lineno > c->c_future->ff_lineno && s->v.ImportFrom.module && - _PyUnicode_EqualToASCIIString(s->v.ImportFrom.module, "__future__")) { + if (location_is_after(LOC(s), c->c_future.ff_location) && + s->v.ImportFrom.module && + _PyUnicode_EqualToASCIIString(s->v.ImportFrom.module, "__future__")) + { Py_DECREF(names); - return compiler_error(c, "from __future__ imports must occur " + return compiler_error(c, LOC(s), "from __future__ imports must occur " "at the beginning of the file"); } - ADDOP_LOAD_CONST_NEW(c, names); + ADDOP_LOAD_CONST_NEW(c, LOC(s), names); if (s->v.ImportFrom.module) { - ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names); + ADDOP_NAME(c, LOC(s), IMPORT_NAME, s->v.ImportFrom.module, names); } else { - ADDOP_NAME(c, IMPORT_NAME, empty_string, names); + _Py_DECLARE_STR(empty, ""); + ADDOP_NAME(c, LOC(s), IMPORT_NAME, &_Py_STR(empty), names); } - for (i = 0; i < n; i++) { + for (Py_ssize_t i = 0; i < n; i++) { alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i); identifier store_name; if (i == 0 && PyUnicode_READ_CHAR(alias->name, 0) == '*') { assert(n == 1); - ADDOP(c, IMPORT_STAR); - return 1; + ADDOP_I(c, LOC(s), CALL_INTRINSIC_1, INTRINSIC_IMPORT_STAR); + ADDOP(c, NO_LOCATION, POP_TOP); + return SUCCESS; } - ADDOP_NAME(c, IMPORT_FROM, alias->name, names); + ADDOP_NAME(c, LOC(s), IMPORT_FROM, alias->name, names); store_name = alias->name; - if (alias->asname) + if (alias->asname) { store_name = alias->asname; - - if (!compiler_nameop(c, store_name, Store)) { - return 0; } + + RETURN_IF_ERROR(compiler_nameop(c, LOC(s), store_name, Store)); } /* remove imported module */ - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, LOC(s), POP_TOP); + return SUCCESS; } static int compiler_assert(struct compiler *c, stmt_ty s) { - basicblock *end; - /* Always emit a warning if the test is a non-zero length tuple */ if ((s->v.Assert.test->kind == Tuple_kind && asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) || @@ -3516,58 +3961,50 @@ compiler_assert(struct compiler *c, stmt_ty s) PyTuple_Check(s->v.Assert.test->v.Constant.value) && PyTuple_Size(s->v.Assert.test->v.Constant.value) > 0)) { - if (!compiler_warn(c, "assertion is always true, " - "perhaps remove parentheses?")) - { - return 0; - } + RETURN_IF_ERROR( + compiler_warn(c, LOC(s), "assertion is always true, " + "perhaps remove parentheses?")); } - if (c->c_optimize) - return 1; - end = compiler_new_block(c); - if (end == NULL) - return 0; - if (!compiler_jump_if(c, s->v.Assert.test, end, 1)) - return 0; - ADDOP(c, LOAD_ASSERTION_ERROR); + if (c->c_optimize) { + return SUCCESS; + } + NEW_JUMP_TARGET_LABEL(c, end); + RETURN_IF_ERROR(compiler_jump_if(c, LOC(s), s->v.Assert.test, end, 1)); + ADDOP(c, LOC(s), LOAD_ASSERTION_ERROR); if (s->v.Assert.msg) { VISIT(c, expr, s->v.Assert.msg); - ADDOP_I(c, CALL_FUNCTION, 1); + ADDOP_I(c, LOC(s), CALL, 0); } - ADDOP_I(c, RAISE_VARARGS, 1); - compiler_use_next_block(c, end); - return 1; + ADDOP_I(c, LOC(s), RAISE_VARARGS, 1); + + USE_LABEL(c, end); + return SUCCESS; } static int -compiler_visit_stmt_expr(struct compiler *c, expr_ty value) +compiler_stmt_expr(struct compiler *c, location loc, expr_ty value) { if (c->c_interactive && c->c_nestlevel <= 1) { VISIT(c, expr, value); - ADDOP(c, PRINT_EXPR); - return 1; + ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_PRINT); + ADDOP(c, NO_LOCATION, POP_TOP); + return SUCCESS; } if (value->kind == Constant_kind) { /* ignore constant statement */ - ADDOP(c, NOP); - return 1; + ADDOP(c, loc, NOP); + return SUCCESS; } VISIT(c, expr, value); - /* Mark POP_TOP as artificial */ - UNSET_LOC(c); - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, NO_LOCATION, POP_TOP); /* artificial */ + return SUCCESS; } static int compiler_visit_stmt(struct compiler *c, stmt_ty s) { - Py_ssize_t i, n; - - /* Always assign a lineno to the next instruction for a stmt. */ - SET_LOC(c, s); switch (s->kind) { case FunctionDef_kind: @@ -3580,15 +4017,18 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) VISIT_SEQ(c, expr, s->v.Delete.targets) break; case Assign_kind: - n = asdl_seq_LEN(s->v.Assign.targets); + { + Py_ssize_t n = asdl_seq_LEN(s->v.Assign.targets); VISIT(c, expr, s->v.Assign.value); - for (i = 0; i < n; i++) { - if (i < n - 1) - ADDOP(c, DUP_TOP); + for (Py_ssize_t i = 0; i < n; i++) { + if (i < n - 1) { + ADDOP_I(c, LOC(s), COPY, 1); + } VISIT(c, expr, (expr_ty)asdl_seq_GET(s->v.Assign.targets, i)); } break; + } case AugAssign_kind: return compiler_augassign(c, s); case AnnAssign_kind: @@ -3602,7 +4042,8 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) case Match_kind: return compiler_match(c, s); case Raise_kind: - n = 0; + { + Py_ssize_t n = 0; if (s->v.Raise.exc) { VISIT(c, expr, s->v.Raise.exc); n++; @@ -3611,11 +4052,13 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) n++; } } - ADDOP_I(c, RAISE_VARARGS, (int)n); - NEXT_BLOCK(c); + ADDOP_I(c, LOC(s), RAISE_VARARGS, (int)n); break; + } case Try_kind: return compiler_try(c, s); + case TryStar_kind: + return compiler_try_star(c, s); case Assert_kind: return compiler_assert(c, s); case Import_kind: @@ -3626,14 +4069,22 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) case Nonlocal_kind: break; case Expr_kind: - return compiler_visit_stmt_expr(c, s->v.Expr.value); + { + return compiler_stmt_expr(c, LOC(s), s->v.Expr.value); + } case Pass_kind: - ADDOP(c, NOP); + { + ADDOP(c, LOC(s), NOP); break; + } case Break_kind: - return compiler_break(c); + { + return compiler_break(c, LOC(s)); + } case Continue_kind: - return compiler_continue(c); + { + return compiler_continue(c, LOC(s)); + } case With_kind: return compiler_with(c, s, 0); case AsyncFunctionDef_kind: @@ -3644,7 +4095,7 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) return compiler_async_for(c, s); } - return 1; + return SUCCESS; } static int @@ -3655,8 +4106,6 @@ unaryop(unaryop_ty op) return UNARY_INVERT; case Not: return UNARY_NOT; - case UAdd: - return UNARY_POSITIVE; case USub: return UNARY_NEGATIVE; default: @@ -3667,7 +4116,8 @@ unaryop(unaryop_ty op) } static int -addop_binary(struct compiler *c, operator_ty binop, bool inplace) +addop_binary(struct compiler *c, location loc, operator_ty binop, + bool inplace) { int oparg; switch (binop) { @@ -3713,14 +4163,26 @@ addop_binary(struct compiler *c, operator_ty binop, bool inplace) default: PyErr_Format(PyExc_SystemError, "%s op %d should not be possible", inplace ? "inplace" : "binary", binop); - return 0; + return ERROR; } - ADDOP_I(c, BINARY_OP, oparg); - return 1; + ADDOP_I(c, loc, BINARY_OP, oparg); + return SUCCESS; +} + + +static int +addop_yield(struct compiler *c, location loc) { + if (c->u->u_ste->ste_generator && c->u->u_ste->ste_coroutine) { + ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_ASYNC_GEN_WRAP); + } + ADDOP_I(c, loc, YIELD_VALUE, 0); + ADDOP_I(c, loc, RESUME, 1); + return SUCCESS; } static int -compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) +compiler_nameop(struct compiler *c, location loc, + identifier name, expr_context_ty ctx) { int op, scope; Py_ssize_t arg; @@ -3733,12 +4195,14 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) !_PyUnicode_EqualToASCIIString(name, "True") && !_PyUnicode_EqualToASCIIString(name, "False")); - if (forbidden_name(c, name, ctx)) - return 0; + if (forbidden_name(c, loc, name, ctx)) { + return ERROR; + } mangled = _Py_Mangle(c->u->u_private, name); - if (!mangled) - return 0; + if (!mangled) { + return ERROR; + } op = 0; optype = OP_NAME; @@ -3787,8 +4251,8 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) case Store: op = STORE_FAST; break; case Del: op = DELETE_FAST; break; } - ADDOP_N(c, op, mangled, varnames); - return 1; + ADDOP_N(c, loc, op, mangled, varnames); + return SUCCESS; case OP_GLOBAL: switch (ctx) { case Load: op = LOAD_GLOBAL; break; @@ -3806,76 +4270,80 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) } assert(op); - arg = compiler_add_o(dict, mangled); + arg = dict_add_o(dict, mangled); Py_DECREF(mangled); - if (arg < 0) - return 0; - return compiler_addop_i(c, op, arg); + if (arg < 0) { + return ERROR; + } + if (op == LOAD_GLOBAL) { + arg <<= 1; + } + return cfg_builder_addop_i(CFG_BUILDER(c), op, arg, loc); } static int compiler_boolop(struct compiler *c, expr_ty e) { - basicblock *end; int jumpi; Py_ssize_t i, n; asdl_expr_seq *s; + location loc = LOC(e); assert(e->kind == BoolOp_kind); if (e->v.BoolOp.op == And) jumpi = JUMP_IF_FALSE_OR_POP; else jumpi = JUMP_IF_TRUE_OR_POP; - end = compiler_new_block(c); - if (end == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, end); s = e->v.BoolOp.values; n = asdl_seq_LEN(s) - 1; assert(n >= 0); for (i = 0; i < n; ++i) { VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i)); - ADDOP_JUMP(c, jumpi, end); - basicblock *next = compiler_new_block(c); - if (next == NULL) { - return 0; - } - compiler_use_next_block(c, next); + ADDOP_JUMP(c, loc, jumpi, end); + NEW_JUMP_TARGET_LABEL(c, next); + + USE_LABEL(c, next); } VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n)); - compiler_use_next_block(c, end); - return 1; + + USE_LABEL(c, end); + return SUCCESS; } static int -starunpack_helper(struct compiler *c, asdl_expr_seq *elts, int pushed, +starunpack_helper(struct compiler *c, location loc, + asdl_expr_seq *elts, int pushed, int build, int add, int extend, int tuple) { Py_ssize_t n = asdl_seq_LEN(elts); if (n > 2 && are_all_items_const(elts, 0, n)) { PyObject *folded = PyTuple_New(n); if (folded == NULL) { - return 0; + return ERROR; } PyObject *val; for (Py_ssize_t i = 0; i < n; i++) { val = ((expr_ty)asdl_seq_GET(elts, i))->v.Constant.value; - Py_INCREF(val); - PyTuple_SET_ITEM(folded, i, val); + PyTuple_SET_ITEM(folded, i, Py_NewRef(val)); } - if (tuple) { - ADDOP_LOAD_CONST_NEW(c, folded); + if (tuple && !pushed) { + ADDOP_LOAD_CONST_NEW(c, loc, folded); } else { if (add == SET_ADD) { Py_SETREF(folded, PyFrozenSet_New(folded)); if (folded == NULL) { - return 0; + return ERROR; } } - ADDOP_I(c, build, pushed); - ADDOP_LOAD_CONST_NEW(c, folded); - ADDOP_I(c, extend, 1); + ADDOP_I(c, loc, build, pushed); + ADDOP_LOAD_CONST_NEW(c, loc, folded); + ADDOP_I(c, loc, extend, 1); + if (tuple) { + ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE); + } } - return 1; + return SUCCESS; } int big = n+pushed > STACK_USE_GUIDELINE; @@ -3884,6 +4352,7 @@ starunpack_helper(struct compiler *c, asdl_expr_seq *elts, int pushed, expr_ty elt = asdl_seq_GET(elts, i); if (elt->kind == Starred_kind) { seen_star = 1; + break; } } if (!seen_star && !big) { @@ -3892,43 +4361,43 @@ starunpack_helper(struct compiler *c, asdl_expr_seq *elts, int pushed, VISIT(c, expr, elt); } if (tuple) { - ADDOP_I(c, BUILD_TUPLE, n+pushed); + ADDOP_I(c, loc, BUILD_TUPLE, n+pushed); } else { - ADDOP_I(c, build, n+pushed); + ADDOP_I(c, loc, build, n+pushed); } - return 1; + return SUCCESS; } int sequence_built = 0; if (big) { - ADDOP_I(c, build, pushed); + ADDOP_I(c, loc, build, pushed); sequence_built = 1; } for (Py_ssize_t i = 0; i < n; i++) { expr_ty elt = asdl_seq_GET(elts, i); if (elt->kind == Starred_kind) { if (sequence_built == 0) { - ADDOP_I(c, build, i+pushed); + ADDOP_I(c, loc, build, i+pushed); sequence_built = 1; } VISIT(c, expr, elt->v.Starred.value); - ADDOP_I(c, extend, 1); + ADDOP_I(c, loc, extend, 1); } else { VISIT(c, expr, elt); if (sequence_built) { - ADDOP_I(c, add, 1); + ADDOP_I(c, loc, add, 1); } } } assert(sequence_built); if (tuple) { - ADDOP(c, LIST_TO_TUPLE); + ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE); } - return 1; + return SUCCESS; } static int -unpack_helper(struct compiler *c, asdl_expr_seq *elts) +unpack_helper(struct compiler *c, location loc, asdl_expr_seq *elts) { Py_ssize_t n = asdl_seq_LEN(elts); int seen_star = 0; @@ -3936,85 +4405,91 @@ unpack_helper(struct compiler *c, asdl_expr_seq *elts) expr_ty elt = asdl_seq_GET(elts, i); if (elt->kind == Starred_kind && !seen_star) { if ((i >= (1 << 8)) || - (n-i-1 >= (INT_MAX >> 8))) - return compiler_error(c, + (n-i-1 >= (INT_MAX >> 8))) { + return compiler_error(c, loc, "too many expressions in " "star-unpacking assignment"); - ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8))); + } + ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8))); seen_star = 1; } else if (elt->kind == Starred_kind) { - return compiler_error(c, + return compiler_error(c, loc, "multiple starred expressions in assignment"); } } if (!seen_star) { - ADDOP_I(c, UNPACK_SEQUENCE, n); + ADDOP_I(c, loc, UNPACK_SEQUENCE, n); } - return 1; + return SUCCESS; } static int -assignment_helper(struct compiler *c, asdl_expr_seq *elts) +assignment_helper(struct compiler *c, location loc, asdl_expr_seq *elts) { Py_ssize_t n = asdl_seq_LEN(elts); - RETURN_IF_FALSE(unpack_helper(c, elts)); + RETURN_IF_ERROR(unpack_helper(c, loc, elts)); for (Py_ssize_t i = 0; i < n; i++) { expr_ty elt = asdl_seq_GET(elts, i); VISIT(c, expr, elt->kind != Starred_kind ? elt : elt->v.Starred.value); } - return 1; + return SUCCESS; } static int compiler_list(struct compiler *c, expr_ty e) { + location loc = LOC(e); asdl_expr_seq *elts = e->v.List.elts; if (e->v.List.ctx == Store) { - return assignment_helper(c, elts); + return assignment_helper(c, loc, elts); } else if (e->v.List.ctx == Load) { - return starunpack_helper(c, elts, 0, BUILD_LIST, - LIST_APPEND, LIST_EXTEND, 0); + return starunpack_helper(c, loc, elts, 0, + BUILD_LIST, LIST_APPEND, LIST_EXTEND, 0); } - else + else { VISIT_SEQ(c, expr, elts); - return 1; + } + return SUCCESS; } static int compiler_tuple(struct compiler *c, expr_ty e) { + location loc = LOC(e); asdl_expr_seq *elts = e->v.Tuple.elts; if (e->v.Tuple.ctx == Store) { - return assignment_helper(c, elts); + return assignment_helper(c, loc, elts); } else if (e->v.Tuple.ctx == Load) { - return starunpack_helper(c, elts, 0, BUILD_LIST, - LIST_APPEND, LIST_EXTEND, 1); + return starunpack_helper(c, loc, elts, 0, + BUILD_LIST, LIST_APPEND, LIST_EXTEND, 1); } - else + else { VISIT_SEQ(c, expr, elts); - return 1; + } + return SUCCESS; } static int compiler_set(struct compiler *c, expr_ty e) { - return starunpack_helper(c, e->v.Set.elts, 0, BUILD_SET, - SET_ADD, SET_UPDATE, 0); + location loc = LOC(e); + return starunpack_helper(c, loc, e->v.Set.elts, 0, + BUILD_SET, SET_ADD, SET_UPDATE, 0); } -static int +static bool are_all_items_const(asdl_expr_seq *seq, Py_ssize_t begin, Py_ssize_t end) { - Py_ssize_t i; - for (i = begin; i < end; i++) { + for (Py_ssize_t i = begin; i < end; i++) { expr_ty key = (expr_ty)asdl_seq_GET(seq, i); - if (key == NULL || key->kind != Constant_kind) - return 0; + if (key == NULL || key->kind != Constant_kind) { + return false; + } } - return 1; + return true; } static int @@ -4023,42 +4498,43 @@ compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end Py_ssize_t i, n = end - begin; PyObject *keys, *key; int big = n*2 > STACK_USE_GUIDELINE; + location loc = LOC(e); if (n > 1 && !big && are_all_items_const(e->v.Dict.keys, begin, end)) { for (i = begin; i < end; i++) { VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); } keys = PyTuple_New(n); if (keys == NULL) { - return 0; + return SUCCESS; } for (i = begin; i < end; i++) { key = ((expr_ty)asdl_seq_GET(e->v.Dict.keys, i))->v.Constant.value; - Py_INCREF(key); - PyTuple_SET_ITEM(keys, i - begin, key); + PyTuple_SET_ITEM(keys, i - begin, Py_NewRef(key)); } - ADDOP_LOAD_CONST_NEW(c, keys); - ADDOP_I(c, BUILD_CONST_KEY_MAP, n); - return 1; + ADDOP_LOAD_CONST_NEW(c, loc, keys); + ADDOP_I(c, loc, BUILD_CONST_KEY_MAP, n); + return SUCCESS; } if (big) { - ADDOP_I(c, BUILD_MAP, 0); + ADDOP_I(c, loc, BUILD_MAP, 0); } for (i = begin; i < end; i++) { VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i)); VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); if (big) { - ADDOP_I(c, MAP_ADD, 1); + ADDOP_I(c, loc, MAP_ADD, 1); } } if (!big) { - ADDOP_I(c, BUILD_MAP, n); + ADDOP_I(c, loc, BUILD_MAP, n); } - return 1; + return SUCCESS; } static int compiler_dict(struct compiler *c, expr_ty e) { + location loc = LOC(e); Py_ssize_t i, n, elements; int have_dict; int is_unpacking = 0; @@ -4069,29 +4545,25 @@ compiler_dict(struct compiler *c, expr_ty e) is_unpacking = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i) == NULL; if (is_unpacking) { if (elements) { - if (!compiler_subdict(c, e, i - elements, i)) { - return 0; - } + RETURN_IF_ERROR(compiler_subdict(c, e, i - elements, i)); if (have_dict) { - ADDOP_I(c, DICT_UPDATE, 1); + ADDOP_I(c, loc, DICT_UPDATE, 1); } have_dict = 1; elements = 0; } if (have_dict == 0) { - ADDOP_I(c, BUILD_MAP, 0); + ADDOP_I(c, loc, BUILD_MAP, 0); have_dict = 1; } VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); - ADDOP_I(c, DICT_UPDATE, 1); + ADDOP_I(c, loc, DICT_UPDATE, 1); } else { if (elements*2 > STACK_USE_GUIDELINE) { - if (!compiler_subdict(c, e, i - elements, i + 1)) { - return 0; - } + RETURN_IF_ERROR(compiler_subdict(c, e, i - elements, i + 1)); if (have_dict) { - ADDOP_I(c, DICT_UPDATE, 1); + ADDOP_I(c, loc, DICT_UPDATE, 1); } have_dict = 1; elements = 0; @@ -4102,60 +4574,54 @@ compiler_dict(struct compiler *c, expr_ty e) } } if (elements) { - if (!compiler_subdict(c, e, n - elements, n)) { - return 0; - } + RETURN_IF_ERROR(compiler_subdict(c, e, n - elements, n)); if (have_dict) { - ADDOP_I(c, DICT_UPDATE, 1); + ADDOP_I(c, loc, DICT_UPDATE, 1); } have_dict = 1; } if (!have_dict) { - ADDOP_I(c, BUILD_MAP, 0); + ADDOP_I(c, loc, BUILD_MAP, 0); } - return 1; + return SUCCESS; } static int compiler_compare(struct compiler *c, expr_ty e) { + location loc = LOC(e); Py_ssize_t i, n; - if (!check_compare(c, e)) { - return 0; - } + RETURN_IF_ERROR(check_compare(c, e)); VISIT(c, expr, e->v.Compare.left); assert(asdl_seq_LEN(e->v.Compare.ops) > 0); n = asdl_seq_LEN(e->v.Compare.ops) - 1; if (n == 0) { VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0)); - ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, 0)); + ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, 0)); } else { - basicblock *cleanup = compiler_new_block(c); - if (cleanup == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, cleanup); for (i = 0; i < n; i++) { VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); - ADDOP(c, DUP_TOP); - ADDOP(c, ROT_THREE); - ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i)); - ADDOP_JUMP(c, JUMP_IF_FALSE_OR_POP, cleanup); - NEXT_BLOCK(c); + ADDOP_I(c, loc, SWAP, 2); + ADDOP_I(c, loc, COPY, 2); + ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, i)); + ADDOP_JUMP(c, loc, JUMP_IF_FALSE_OR_POP, cleanup); } VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); - ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, n)); - basicblock *end = compiler_new_block(c); - if (end == NULL) - return 0; - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); - compiler_use_next_block(c, cleanup); - ADDOP(c, ROT_TWO); - ADDOP(c, POP_TOP); - compiler_use_next_block(c, end); + ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, n)); + NEW_JUMP_TARGET_LABEL(c, end); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); + + USE_LABEL(c, cleanup); + ADDOP_I(c, loc, SWAP, 2); + ADDOP(c, loc, POP_TOP); + + USE_LABEL(c, end); } - return 1; + return SUCCESS; } static PyTypeObject * @@ -4201,12 +4667,14 @@ check_caller(struct compiler *c, expr_ty e) case SetComp_kind: case GeneratorExp_kind: case JoinedStr_kind: - case FormattedValue_kind: - return compiler_warn(c, "'%.200s' object is not callable; " - "perhaps you missed a comma?", - infer_type(e)->tp_name); + case FormattedValue_kind: { + location loc = LOC(e); + return compiler_warn(c, loc, "'%.200s' object is not callable; " + "perhaps you missed a comma?", + infer_type(e)->tp_name); + } default: - return 1; + return SUCCESS; } } @@ -4222,18 +4690,20 @@ check_subscripter(struct compiler *c, expr_ty e) PyLong_Check(v) || PyFloat_Check(v) || PyComplex_Check(v) || PyAnySet_Check(v))) { - return 1; + return SUCCESS; } /* fall through */ case Set_kind: case SetComp_kind: case GeneratorExp_kind: - case Lambda_kind: - return compiler_warn(c, "'%.200s' object is not subscriptable; " - "perhaps you missed a comma?", - infer_type(e)->tp_name); + case Lambda_kind: { + location loc = LOC(e); + return compiler_warn(c, loc, "'%.200s' object is not subscriptable; " + "perhaps you missed a comma?", + infer_type(e)->tp_name); + } default: - return 1; + return SUCCESS; } } @@ -4246,28 +4716,30 @@ check_index(struct compiler *c, expr_ty e, expr_ty s) if (index_type == NULL || PyType_FastSubclass(index_type, Py_TPFLAGS_LONG_SUBCLASS) || index_type == &PySlice_Type) { - return 1; + return SUCCESS; } switch (e->kind) { case Constant_kind: v = e->v.Constant.value; if (!(PyUnicode_Check(v) || PyBytes_Check(v) || PyTuple_Check(v))) { - return 1; + return SUCCESS; } /* fall through */ case Tuple_kind: case List_kind: case ListComp_kind: case JoinedStr_kind: - case FormattedValue_kind: - return compiler_warn(c, "%.200s indices must be integers or slices, " - "not %.200s; " - "perhaps you missed a comma?", - infer_type(e)->tp_name, - index_type->tp_name); + case FormattedValue_kind: { + location loc = LOC(e); + return compiler_warn(c, loc, "%.200s indices must be integers " + "or slices, not %.200s; " + "perhaps you missed a comma?", + infer_type(e)->tp_name, + index_type->tp_name); + } default: - return 1; + return SUCCESS; } } @@ -4288,7 +4760,35 @@ is_import_originated(struct compiler *c, expr_ty e) return flags & DEF_IMPORT; } -// Return 1 if the method call was optimized, -1 if not, and 0 on error. +// If an attribute access spans multiple lines, update the current start +// location to point to the attribute name. +static location +update_start_location_to_match_attr(struct compiler *c, location loc, + expr_ty attr) +{ + assert(attr->kind == Attribute_kind); + if (loc.lineno != attr->end_lineno) { + loc.lineno = attr->end_lineno; + int len = (int)PyUnicode_GET_LENGTH(attr->v.Attribute.attr); + if (len <= attr->end_col_offset) { + loc.col_offset = attr->end_col_offset - len; + } + else { + // GH-94694: Somebody's compiling weird ASTs. Just drop the columns: + loc.col_offset = -1; + loc.end_col_offset = -1; + } + // Make sure the end position still follows the start position, even for + // weird ASTs: + loc.end_lineno = Py_MAX(loc.lineno, loc.end_lineno); + if (loc.lineno == loc.end_lineno) { + loc.end_col_offset = Py_MAX(loc.col_offset, loc.end_col_offset); + } + } + return loc; +} + +// Return 1 if the method call was optimized, 0 if not, and -1 on error. static int maybe_optimize_method_call(struct compiler *c, expr_ty e) { @@ -4299,51 +4799,48 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e) /* Check that the call node is an attribute access */ if (meth->kind != Attribute_kind || meth->v.Attribute.ctx != Load) { - return -1; + return 0; } /* Check that the base object is not something that is imported */ if (is_import_originated(c, meth->v.Attribute.value)) { - return -1; + return 0; } /* Check that there aren't too many arguments */ argsl = asdl_seq_LEN(args); kwdsl = asdl_seq_LEN(kwds); if (argsl + kwdsl + (kwdsl != 0) >= STACK_USE_GUIDELINE) { - return -1; + return 0; } /* Check that there are no *varargs types of arguments. */ for (i = 0; i < argsl; i++) { expr_ty elt = asdl_seq_GET(args, i); if (elt->kind == Starred_kind) { - return -1; + return 0; } } for (i = 0; i < kwdsl; i++) { keyword_ty kw = asdl_seq_GET(kwds, i); if (kw->arg == NULL) { - return -1; + return 0; } } /* Alright, we can optimize the code. */ VISIT(c, expr, meth->v.Attribute.value); - int old_lineno = c->u->u_lineno; - c->u->u_lineno = meth->end_lineno; - ADDOP_NAME(c, LOAD_METHOD, meth->v.Attribute.attr, names); + location loc = LOC(meth); + loc = update_start_location_to_match_attr(c, loc, meth); + ADDOP_NAME(c, loc, LOAD_METHOD, meth->v.Attribute.attr, names); VISIT_SEQ(c, expr, e->v.Call.args); if (kwdsl) { - if (!compiler_call_simple_kw_helper(c, kwds, kwdsl)) { - return 0; - }; - ADDOP_I(c, CALL_METHOD_KW, argsl + kwdsl); + VISIT_SEQ(c, keyword, kwds); + RETURN_IF_ERROR( + compiler_call_simple_kw_helper(c, loc, kwds, kwdsl)); } - else { - ADDOP_I(c, CALL_METHOD, argsl); - } - c->u->u_lineno = old_lineno; + loc = update_start_location_to_match_attr(c, LOC(e), meth); + ADDOP_I(c, loc, CALL, argsl + kwdsl); return 1; } @@ -4356,36 +4853,38 @@ validate_keywords(struct compiler *c, asdl_keyword_seq *keywords) if (key->arg == NULL) { continue; } - if (forbidden_name(c, key->arg, Store)) { - return -1; + location loc = LOC(key); + if (forbidden_name(c, loc, key->arg, Store)) { + return ERROR; } for (Py_ssize_t j = i + 1; j < nkeywords; j++) { keyword_ty other = ((keyword_ty)asdl_seq_GET(keywords, j)); if (other->arg && !PyUnicode_Compare(key->arg, other->arg)) { - SET_LOC(c, other); - compiler_error(c, "keyword argument repeated: %U", key->arg); - return -1; + compiler_error(c, LOC(other), "keyword argument repeated: %U", key->arg); + return ERROR; } } } - return 0; + return SUCCESS; } static int compiler_call(struct compiler *c, expr_ty e) { - if (validate_keywords(c, e->v.Call.keywords) == -1) { - return 0; - } + RETURN_IF_ERROR(validate_keywords(c, e->v.Call.keywords)); int ret = maybe_optimize_method_call(c, e); - if (ret >= 0) { - return ret; + if (ret < 0) { + return ERROR; } - if (!check_caller(c, e->v.Call.func)) { - return 0; + if (ret == 1) { + return SUCCESS; } + RETURN_IF_ERROR(check_caller(c, e->v.Call.func)); + location loc = LOC(e->v.Call.func); + ADDOP(c, loc, PUSH_NULL); VISIT(c, expr, e->v.Call.func); - return compiler_call_helper(c, 0, + loc = LOC(e); + return compiler_call_helper(c, loc, 0, e->v.Call.args, e->v.Call.keywords); } @@ -4393,30 +4892,26 @@ compiler_call(struct compiler *c, expr_ty e) static int compiler_joined_str(struct compiler *c, expr_ty e) { - + location loc = LOC(e); Py_ssize_t value_count = asdl_seq_LEN(e->v.JoinedStr.values); if (value_count > STACK_USE_GUIDELINE) { - ADDOP_LOAD_CONST_NEW(c, _PyUnicode_FromASCII("", 0)); - PyObject *join = _PyUnicode_FromASCII("join", 4); - if (join == NULL) { - return 0; - } - ADDOP_NAME(c, LOAD_METHOD, join, names); - Py_DECREF(join); - ADDOP_I(c, BUILD_LIST, 0); + _Py_DECLARE_STR(empty, ""); + ADDOP_LOAD_CONST_NEW(c, loc, Py_NewRef(&_Py_STR(empty))); + ADDOP_NAME(c, loc, LOAD_METHOD, &_Py_ID(join), names); + ADDOP_I(c, loc, BUILD_LIST, 0); for (Py_ssize_t i = 0; i < asdl_seq_LEN(e->v.JoinedStr.values); i++) { VISIT(c, expr, asdl_seq_GET(e->v.JoinedStr.values, i)); - ADDOP_I(c, LIST_APPEND, 1); + ADDOP_I(c, loc, LIST_APPEND, 1); } - ADDOP_I(c, CALL_METHOD, 1); + ADDOP_I(c, loc, CALL, 1); } else { VISIT_SEQ(c, expr, e->v.JoinedStr.values); if (asdl_seq_LEN(e->v.JoinedStr.values) != 1) { - ADDOP_I(c, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values)); + ADDOP_I(c, loc, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values)); } } - return 1; + return SUCCESS; } /* Used to implement f-strings. Format a single value. */ @@ -4451,7 +4946,7 @@ compiler_formatted_value(struct compiler *c, expr_ty e) default: PyErr_Format(PyExc_SystemError, "Unrecognized conversion character %d", conversion); - return 0; + return ERROR; } if (e->v.FormattedValue.format_spec) { /* Evaluate the format spec, and update our opcode arg. */ @@ -4460,13 +4955,16 @@ compiler_formatted_value(struct compiler *c, expr_ty e) } /* And push our opcode and oparg */ - ADDOP_I(c, FORMAT_VALUE, oparg); + location loc = LOC(e); + ADDOP_I(c, loc, FORMAT_VALUE, oparg); - return 1; + return SUCCESS; } static int -compiler_subkwargs(struct compiler *c, asdl_keyword_seq *keywords, Py_ssize_t begin, Py_ssize_t end) +compiler_subkwargs(struct compiler *c, location loc, + asdl_keyword_seq *keywords, + Py_ssize_t begin, Py_ssize_t end) { Py_ssize_t i, n = end - begin; keyword_ty kw; @@ -4480,76 +4978,69 @@ compiler_subkwargs(struct compiler *c, asdl_keyword_seq *keywords, Py_ssize_t be } keys = PyTuple_New(n); if (keys == NULL) { - return 0; + return ERROR; } for (i = begin; i < end; i++) { key = ((keyword_ty) asdl_seq_GET(keywords, i))->arg; - Py_INCREF(key); - PyTuple_SET_ITEM(keys, i - begin, key); + PyTuple_SET_ITEM(keys, i - begin, Py_NewRef(key)); } - ADDOP_LOAD_CONST_NEW(c, keys); - ADDOP_I(c, BUILD_CONST_KEY_MAP, n); - return 1; + ADDOP_LOAD_CONST_NEW(c, loc, keys); + ADDOP_I(c, loc, BUILD_CONST_KEY_MAP, n); + return SUCCESS; } if (big) { - ADDOP_I_NOLINE(c, BUILD_MAP, 0); + ADDOP_I(c, NO_LOCATION, BUILD_MAP, 0); } for (i = begin; i < end; i++) { kw = asdl_seq_GET(keywords, i); - ADDOP_LOAD_CONST(c, kw->arg); + ADDOP_LOAD_CONST(c, loc, kw->arg); VISIT(c, expr, kw->value); if (big) { - ADDOP_I_NOLINE(c, MAP_ADD, 1); + ADDOP_I(c, NO_LOCATION, MAP_ADD, 1); } } if (!big) { - ADDOP_I(c, BUILD_MAP, n); + ADDOP_I(c, loc, BUILD_MAP, n); } - return 1; + return SUCCESS; } /* Used by compiler_call_helper and maybe_optimize_method_call to emit -LOAD_CONST kw1 -LOAD_CONST kw2 -... -LOAD_CONST -before a CALL_(FUNCTION|METHOD)_KW. - -Returns 1 on success, 0 on error. -*/ + * KW_NAMES before CALL. + */ static int -compiler_call_simple_kw_helper(struct compiler *c, - asdl_keyword_seq *keywords, - Py_ssize_t nkwelts) +compiler_call_simple_kw_helper(struct compiler *c, location loc, + asdl_keyword_seq *keywords, Py_ssize_t nkwelts) { PyObject *names; - VISIT_SEQ(c, keyword, keywords); names = PyTuple_New(nkwelts); if (names == NULL) { - return 0; + return ERROR; } for (int i = 0; i < nkwelts; i++) { keyword_ty kw = asdl_seq_GET(keywords, i); - Py_INCREF(kw->arg); - PyTuple_SET_ITEM(names, i, kw->arg); + PyTuple_SET_ITEM(names, i, Py_NewRef(kw->arg)); } - ADDOP_LOAD_CONST_NEW(c, names); - return 1; + Py_ssize_t arg = compiler_add_const(c, names); + if (arg < 0) { + return ERROR; + } + Py_DECREF(names); + ADDOP_I(c, loc, KW_NAMES, arg); + return SUCCESS; } /* shared code between compiler_call and compiler_class */ static int -compiler_call_helper(struct compiler *c, +compiler_call_helper(struct compiler *c, location loc, int n, /* Args already pushed */ asdl_expr_seq *args, asdl_keyword_seq *keywords) { Py_ssize_t i, nseen, nelts, nkwelts; - if (validate_keywords(c, keywords) == -1) { - return 0; - } + RETURN_IF_ERROR(validate_keywords(c, keywords)); nelts = asdl_seq_LEN(args); nkwelts = asdl_seq_LEN(keywords); @@ -4577,16 +5068,12 @@ compiler_call_helper(struct compiler *c, VISIT(c, expr, elt); } if (nkwelts) { - if (!compiler_call_simple_kw_helper(c, keywords, nkwelts)) { - return 0; - }; - ADDOP_I(c, CALL_FUNCTION_KW, n + nelts + nkwelts); - return 1; - } - else { - ADDOP_I(c, CALL_FUNCTION, n + nelts); - return 1; + VISIT_SEQ(c, keyword, keywords); + RETURN_IF_ERROR( + compiler_call_simple_kw_helper(c, loc, keywords, nkwelts)); } + ADDOP_I(c, loc, CALL, n + nelts + nkwelts); + return SUCCESS; ex_call: @@ -4594,9 +5081,9 @@ ex_call: if (n ==0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) { VISIT(c, expr, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value); } - else if (starunpack_helper(c, args, n, BUILD_LIST, - LIST_APPEND, LIST_EXTEND, 1) == 0) { - return 0; + else if (starunpack_helper(c, loc, args, n, BUILD_LIST, + LIST_APPEND, LIST_EXTEND, 1) < 0) { + return ERROR; } /* Then keyword arguments */ if (nkwelts) { @@ -4609,21 +5096,19 @@ ex_call: if (kw->arg == NULL) { /* A keyword argument unpacking. */ if (nseen) { - if (!compiler_subkwargs(c, keywords, i - nseen, i)) { - return 0; - } + RETURN_IF_ERROR(compiler_subkwargs(c, loc, keywords, i - nseen, i)); if (have_dict) { - ADDOP_I(c, DICT_MERGE, 1); + ADDOP_I(c, loc, DICT_MERGE, 1); } have_dict = 1; nseen = 0; } if (!have_dict) { - ADDOP_I(c, BUILD_MAP, 0); + ADDOP_I(c, loc, BUILD_MAP, 0); have_dict = 1; } VISIT(c, expr, kw->value); - ADDOP_I(c, DICT_MERGE, 1); + ADDOP_I(c, loc, DICT_MERGE, 1); } else { nseen++; @@ -4631,18 +5116,16 @@ ex_call: } if (nseen) { /* Pack up any trailing keyword arguments. */ - if (!compiler_subkwargs(c, keywords, nkwelts - nseen, nkwelts)) { - return 0; - } + RETURN_IF_ERROR(compiler_subkwargs(c, loc, keywords, nkwelts - nseen, nkwelts)); if (have_dict) { - ADDOP_I(c, DICT_MERGE, 1); + ADDOP_I(c, loc, DICT_MERGE, 1); } have_dict = 1; } assert(have_dict); } - ADDOP_I(c, CALL_FUNCTION_EX, nkwelts > 0); - return 1; + ADDOP_I(c, loc, CALL_FUNCTION_EX, nkwelts > 0); + return SUCCESS; } @@ -4661,7 +5144,7 @@ ex_call: static int -compiler_comprehension_generator(struct compiler *c, +compiler_comprehension_generator(struct compiler *c, location loc, asdl_comprehension_seq *generators, int gen_index, int depth, expr_ty elt, expr_ty val, int type) @@ -4670,41 +5153,33 @@ compiler_comprehension_generator(struct compiler *c, gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); if (gen->is_async) { return compiler_async_comprehension_generator( - c, generators, gen_index, depth, elt, val, type); + c, loc, generators, gen_index, depth, elt, val, type); } else { return compiler_sync_comprehension_generator( - c, generators, gen_index, depth, elt, val, type); + c, loc, generators, gen_index, depth, elt, val, type); } } static int -compiler_sync_comprehension_generator(struct compiler *c, - asdl_comprehension_seq *generators, int gen_index, - int depth, +compiler_sync_comprehension_generator(struct compiler *c, location loc, + asdl_comprehension_seq *generators, + int gen_index, int depth, expr_ty elt, expr_ty val, int type) { /* generate code for the iterator, then each of the ifs, and then write to the element */ - comprehension_ty gen; - basicblock *start, *anchor, *skip, *if_cleanup; - Py_ssize_t i, n; + NEW_JUMP_TARGET_LABEL(c, start); + NEW_JUMP_TARGET_LABEL(c, if_cleanup); + NEW_JUMP_TARGET_LABEL(c, anchor); - start = compiler_new_block(c); - skip = compiler_new_block(c); - if_cleanup = compiler_new_block(c); - anchor = compiler_new_block(c); - - if (start == NULL || skip == NULL || if_cleanup == NULL || - anchor == NULL) - return 0; - - gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); + comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators, + gen_index); if (gen_index == 0) { /* Receive outermost iter as an implicit argument */ c->u->u_argcount = 1; - ADDOP_I(c, LOAD_FAST, 0); + ADDOP_I(c, loc, LOAD_FAST, 0); } else { /* Sub-iter - calculate on the fly */ @@ -4726,36 +5201,36 @@ compiler_sync_comprehension_generator(struct compiler *c, expr_ty elt = asdl_seq_GET(elts, 0); if (elt->kind != Starred_kind) { VISIT(c, expr, elt); - start = NULL; + start = NO_LABEL; } } - if (start) { + if (IS_LABEL(start)) { VISIT(c, expr, gen->iter); - ADDOP(c, GET_ITER); + ADDOP(c, loc, GET_ITER); } } - if (start) { + if (IS_LABEL(start)) { depth++; - compiler_use_next_block(c, start); - ADDOP_JUMP(c, FOR_ITER, anchor); - NEXT_BLOCK(c); + USE_LABEL(c, start); + ADDOP_JUMP(c, loc, FOR_ITER, anchor); } VISIT(c, expr, gen->target); /* XXX this needs to be cleaned up...a lot! */ - n = asdl_seq_LEN(gen->ifs); - for (i = 0; i < n; i++) { + Py_ssize_t n = asdl_seq_LEN(gen->ifs); + for (Py_ssize_t i = 0; i < n; i++) { expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i); - if (!compiler_jump_if(c, e, if_cleanup, 0)) - return 0; - NEXT_BLOCK(c); + RETURN_IF_ERROR(compiler_jump_if(c, loc, e, if_cleanup, 0)); } - if (++gen_index < asdl_seq_LEN(generators)) - if (!compiler_comprehension_generator(c, - generators, gen_index, depth, - elt, val, type)) - return 0; + if (++gen_index < asdl_seq_LEN(generators)) { + RETURN_IF_ERROR( + compiler_comprehension_generator(c, loc, + generators, gen_index, depth, + elt, val, type)); + } + + location elt_loc = LOC(elt); /* only append after the last for generator */ if (gen_index >= asdl_seq_LEN(generators)) { @@ -4763,137 +5238,139 @@ compiler_sync_comprehension_generator(struct compiler *c, switch (type) { case COMP_GENEXP: VISIT(c, expr, elt); - ADDOP(c, YIELD_VALUE); - ADDOP(c, POP_TOP); + ADDOP_YIELD(c, elt_loc); + ADDOP(c, elt_loc, POP_TOP); break; case COMP_LISTCOMP: VISIT(c, expr, elt); - ADDOP_I(c, LIST_APPEND, depth + 1); + ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1); break; case COMP_SETCOMP: VISIT(c, expr, elt); - ADDOP_I(c, SET_ADD, depth + 1); + ADDOP_I(c, elt_loc, SET_ADD, depth + 1); break; case COMP_DICTCOMP: /* With '{k: v}', k is evaluated before v, so we do the same. */ VISIT(c, expr, elt); VISIT(c, expr, val); - ADDOP_I(c, MAP_ADD, depth + 1); + elt_loc = LOCATION(elt->lineno, + val->end_lineno, + elt->col_offset, + val->end_col_offset); + ADDOP_I(c, elt_loc, MAP_ADD, depth + 1); break; default: - return 0; + return ERROR; } - - compiler_use_next_block(c, skip); - } - compiler_use_next_block(c, if_cleanup); - if (start) { - ADDOP_JUMP(c, JUMP_ABSOLUTE, start); - compiler_use_next_block(c, anchor); } - return 1; + USE_LABEL(c, if_cleanup); + if (IS_LABEL(start)) { + ADDOP_JUMP(c, elt_loc, JUMP, start); + + USE_LABEL(c, anchor); + ADDOP(c, NO_LOCATION, END_FOR); + } + + return SUCCESS; } static int -compiler_async_comprehension_generator(struct compiler *c, - asdl_comprehension_seq *generators, int gen_index, - int depth, +compiler_async_comprehension_generator(struct compiler *c, location loc, + asdl_comprehension_seq *generators, + int gen_index, int depth, expr_ty elt, expr_ty val, int type) { - comprehension_ty gen; - basicblock *start, *if_cleanup, *except; - Py_ssize_t i, n; - start = compiler_new_block(c); - except = compiler_new_block(c); - if_cleanup = compiler_new_block(c); + NEW_JUMP_TARGET_LABEL(c, start); + NEW_JUMP_TARGET_LABEL(c, except); + NEW_JUMP_TARGET_LABEL(c, if_cleanup); - if (start == NULL || if_cleanup == NULL || except == NULL) { - return 0; - } - - gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); + comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators, + gen_index); if (gen_index == 0) { /* Receive outermost iter as an implicit argument */ c->u->u_argcount = 1; - ADDOP_I(c, LOAD_FAST, 0); + ADDOP_I(c, loc, LOAD_FAST, 0); } else { /* Sub-iter - calculate on the fly */ VISIT(c, expr, gen->iter); - ADDOP(c, GET_AITER); + ADDOP(c, loc, GET_AITER); } - compiler_use_next_block(c, start); + USE_LABEL(c, start); /* Runtime will push a block here, so we need to account for that */ - if (!compiler_push_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start, - NULL, NULL)) { - return 0; - } + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, ASYNC_COMPREHENSION_GENERATOR, + start, NO_LABEL, NULL)); - ADDOP_JUMP(c, SETUP_FINALLY, except); - ADDOP(c, GET_ANEXT); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); - ADDOP(c, POP_BLOCK); + ADDOP_JUMP(c, loc, SETUP_FINALLY, except); + ADDOP(c, loc, GET_ANEXT); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADD_YIELD_FROM(c, loc, 1); + ADDOP(c, loc, POP_BLOCK); VISIT(c, expr, gen->target); - n = asdl_seq_LEN(gen->ifs); - for (i = 0; i < n; i++) { + Py_ssize_t n = asdl_seq_LEN(gen->ifs); + for (Py_ssize_t i = 0; i < n; i++) { expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i); - if (!compiler_jump_if(c, e, if_cleanup, 0)) - return 0; - NEXT_BLOCK(c); + RETURN_IF_ERROR(compiler_jump_if(c, loc, e, if_cleanup, 0)); } depth++; - if (++gen_index < asdl_seq_LEN(generators)) - if (!compiler_comprehension_generator(c, - generators, gen_index, depth, - elt, val, type)) - return 0; + if (++gen_index < asdl_seq_LEN(generators)) { + RETURN_IF_ERROR( + compiler_comprehension_generator(c, loc, + generators, gen_index, depth, + elt, val, type)); + } + location elt_loc = LOC(elt); /* only append after the last for generator */ if (gen_index >= asdl_seq_LEN(generators)) { /* comprehension specific code */ switch (type) { case COMP_GENEXP: VISIT(c, expr, elt); - ADDOP(c, YIELD_VALUE); - ADDOP(c, POP_TOP); + ADDOP_YIELD(c, elt_loc); + ADDOP(c, elt_loc, POP_TOP); break; case COMP_LISTCOMP: VISIT(c, expr, elt); - ADDOP_I(c, LIST_APPEND, depth + 1); + ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1); break; case COMP_SETCOMP: VISIT(c, expr, elt); - ADDOP_I(c, SET_ADD, depth + 1); + ADDOP_I(c, elt_loc, SET_ADD, depth + 1); break; case COMP_DICTCOMP: /* With '{k: v}', k is evaluated before v, so we do the same. */ VISIT(c, expr, elt); VISIT(c, expr, val); - ADDOP_I(c, MAP_ADD, depth + 1); + elt_loc = LOCATION(elt->lineno, + val->end_lineno, + elt->col_offset, + val->end_col_offset); + ADDOP_I(c, elt_loc, MAP_ADD, depth + 1); break; default: - return 0; + return ERROR; } } - compiler_use_next_block(c, if_cleanup); - ADDOP_JUMP(c, JUMP_ABSOLUTE, start); + + USE_LABEL(c, if_cleanup); + ADDOP_JUMP(c, elt_loc, JUMP, start); compiler_pop_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start); - compiler_use_next_block(c, except); - //UNSET_LOC(c); + USE_LABEL(c, except); - ADDOP(c, END_ASYNC_FOR); + ADDOP(c, loc, END_ASYNC_FOR); - return 1; + return SUCCESS; } static int @@ -4903,18 +5380,17 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, { PyCodeObject *co = NULL; comprehension_ty outermost; - PyObject *qualname = NULL; int scope_type = c->u->u_scope_type; int is_async_generator = 0; int is_top_level_await = IS_TOP_LEVEL_AWAIT(c); outermost = (comprehension_ty) asdl_seq_GET(generators, 0); - if (!compiler_enter_scope(c, name, COMPILER_SCOPE_COMPREHENSION, - (void *)e, e->lineno)) + if (compiler_enter_scope(c, name, COMPILER_SCOPE_COMPREHENSION, + (void *)e, e->lineno) < 0) { goto error; } - SET_LOC(c, e); + location loc = LOC(e); is_async_generator = c->u->u_ste->ste_coroutine; @@ -4923,8 +5399,8 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, scope_type != COMPILER_SCOPE_COMPREHENSION && !is_top_level_await) { - compiler_error(c, "asynchronous comprehension outside of " - "an asynchronous function"); + compiler_error(c, loc, "asynchronous comprehension outside of " + "an asynchronous function"); goto error_in_scope; } @@ -4946,68 +5422,69 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, goto error_in_scope; } - ADDOP_I(c, op, 0); + ADDOP_I(c, loc, op, 0); } - if (!compiler_comprehension_generator(c, generators, 0, 0, elt, - val, type)) + if (compiler_comprehension_generator(c, loc, generators, 0, 0, + elt, val, type) < 0) { goto error_in_scope; + } if (type != COMP_GENEXP) { - ADDOP(c, RETURN_VALUE); + ADDOP(c, LOC(e), RETURN_VALUE); + } + if (type == COMP_GENEXP) { + if (wrap_in_stopiteration_handler(c) < 0) { + goto error_in_scope; + } } co = assemble(c, 1); - qualname = c->u->u_qualname; - Py_INCREF(qualname); compiler_exit_scope(c); if (is_top_level_await && is_async_generator){ c->u->u_ste->ste_coroutine = 1; } - if (co == NULL) - goto error; - - if (!compiler_make_closure(c, co, 0, qualname)) { + if (co == NULL) { + goto error; + } + + loc = LOC(e); + if (compiler_make_closure(c, loc, co, 0) < 0) { goto error; } - Py_DECREF(qualname); Py_DECREF(co); VISIT(c, expr, outermost->iter); + loc = LOC(e); if (outermost->is_async) { - ADDOP(c, GET_AITER); + ADDOP(c, loc, GET_AITER); } else { - ADDOP(c, GET_ITER); + ADDOP(c, loc, GET_ITER); } - ADDOP_I(c, CALL_FUNCTION, 1); + ADDOP_I(c, loc, CALL, 0); if (is_async_generator && type != COMP_GENEXP) { - ADDOP(c, GET_AWAITABLE); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); + ADDOP_I(c, loc, GET_AWAITABLE, 0); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADD_YIELD_FROM(c, loc, 1); } - return 1; + return SUCCESS; error_in_scope: compiler_exit_scope(c); error: - Py_XDECREF(qualname); Py_XDECREF(co); - return 0; + return ERROR; } static int compiler_genexp(struct compiler *c, expr_ty e) { - _Py_static_string(PyId_genexpr, ""); - identifier name = _PyUnicode_FromId(&PyId_genexpr); /* borrowed ref */ - if (name == NULL) { - return 0; - } assert(e->kind == GeneratorExp_kind); - return compiler_comprehension(c, e, COMP_GENEXP, name, + _Py_DECLARE_STR(anon_genexpr, ""); + return compiler_comprehension(c, e, COMP_GENEXP, &_Py_STR(anon_genexpr), e->v.GeneratorExp.generators, e->v.GeneratorExp.elt, NULL); } @@ -5015,13 +5492,9 @@ compiler_genexp(struct compiler *c, expr_ty e) static int compiler_listcomp(struct compiler *c, expr_ty e) { - _Py_static_string(PyId_listcomp, ""); - identifier name = _PyUnicode_FromId(&PyId_listcomp); /* borrowed ref */ - if (name == NULL) { - return 0; - } assert(e->kind == ListComp_kind); - return compiler_comprehension(c, e, COMP_LISTCOMP, name, + _Py_DECLARE_STR(anon_listcomp, ""); + return compiler_comprehension(c, e, COMP_LISTCOMP, &_Py_STR(anon_listcomp), e->v.ListComp.generators, e->v.ListComp.elt, NULL); } @@ -5029,13 +5502,9 @@ compiler_listcomp(struct compiler *c, expr_ty e) static int compiler_setcomp(struct compiler *c, expr_ty e) { - _Py_static_string(PyId_setcomp, ""); - identifier name = _PyUnicode_FromId(&PyId_setcomp); /* borrowed ref */ - if (name == NULL) { - return 0; - } assert(e->kind == SetComp_kind); - return compiler_comprehension(c, e, COMP_SETCOMP, name, + _Py_DECLARE_STR(anon_setcomp, ""); + return compiler_comprehension(c, e, COMP_SETCOMP, &_Py_STR(anon_setcomp), e->v.SetComp.generators, e->v.SetComp.elt, NULL); } @@ -5044,13 +5513,9 @@ compiler_setcomp(struct compiler *c, expr_ty e) static int compiler_dictcomp(struct compiler *c, expr_ty e) { - _Py_static_string(PyId_dictcomp, ""); - identifier name = _PyUnicode_FromId(&PyId_dictcomp); /* borrowed ref */ - if (name == NULL) { - return 0; - } assert(e->kind == DictComp_kind); - return compiler_comprehension(c, e, COMP_DICTCOMP, name, + _Py_DECLARE_STR(anon_dictcomp, ""); + return compiler_comprehension(c, e, COMP_DICTCOMP, &_Py_STR(anon_dictcomp), e->v.DictComp.generators, e->v.DictComp.key, e->v.DictComp.value); } @@ -5060,36 +5525,30 @@ static int compiler_visit_keyword(struct compiler *c, keyword_ty k) { VISIT(c, expr, k->value); - return 1; + return SUCCESS; } -/* Test whether expression is constant. For constants, report - whether they are true or false. - - Return values: 1 for true, 0 for false, -1 for non-constant. - */ static int -compiler_with_except_finish(struct compiler *c, basicblock * cleanup) { - UNSET_LOC(c); - basicblock *exit; - exit = compiler_new_block(c); - if (exit == NULL) - return 0; - ADDOP_JUMP(c, POP_JUMP_IF_TRUE, exit); - NEXT_BLOCK(c); - ADDOP_I(c, RERAISE, 4); - compiler_use_next_block(c, cleanup); - ADDOP(c, POP_EXCEPT_AND_RERAISE); - compiler_use_next_block(c, exit); - ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); - ADDOP(c, POP_BLOCK); - ADDOP(c, POP_EXCEPT); - ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); - return 1; +compiler_with_except_finish(struct compiler *c, jump_target_label cleanup) { + NEW_JUMP_TARGET_LABEL(c, suppress); + ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_TRUE, suppress); + ADDOP_I(c, NO_LOCATION, RERAISE, 2); + + USE_LABEL(c, suppress); + ADDOP(c, NO_LOCATION, POP_TOP); /* exc_value */ + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP(c, NO_LOCATION, POP_EXCEPT); + ADDOP(c, NO_LOCATION, POP_TOP); + ADDOP(c, NO_LOCATION, POP_TOP); + NEW_JUMP_TARGET_LABEL(c, exit); + ADDOP_JUMP(c, NO_LOCATION, JUMP, exit); + + USE_LABEL(c, cleanup); + POP_EXCEPT_AND_RERAISE(c, NO_LOCATION); + + USE_LABEL(c, exit); + return SUCCESS; } /* @@ -5119,85 +5578,82 @@ compiler_with_except_finish(struct compiler *c, basicblock * cleanup) { static int compiler_async_with(struct compiler *c, stmt_ty s, int pos) { - basicblock *block, *final, *exit, *cleanup; + location loc = LOC(s); withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos); assert(s->kind == AsyncWith_kind); if (IS_TOP_LEVEL_AWAIT(c)){ c->u->u_ste->ste_coroutine = 1; } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION){ - return compiler_error(c, "'async with' outside async function"); + return compiler_error(c, loc, "'async with' outside async function"); } - block = compiler_new_block(c); - final = compiler_new_block(c); - exit = compiler_new_block(c); - cleanup = compiler_new_block(c); - if (!block || !final || !exit || !cleanup) - return 0; + NEW_JUMP_TARGET_LABEL(c, block); + NEW_JUMP_TARGET_LABEL(c, final); + NEW_JUMP_TARGET_LABEL(c, exit); + NEW_JUMP_TARGET_LABEL(c, cleanup); /* Evaluate EXPR */ VISIT(c, expr, item->context_expr); - ADDOP(c, BEFORE_ASYNC_WITH); - ADDOP(c, GET_AWAITABLE); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); + ADDOP(c, loc, BEFORE_ASYNC_WITH); + ADDOP_I(c, loc, GET_AWAITABLE, 1); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADD_YIELD_FROM(c, loc, 1); - ADDOP_JUMP(c, SETUP_WITH, final); + ADDOP_JUMP(c, loc, SETUP_WITH, final); /* SETUP_WITH pushes a finally block. */ - compiler_use_next_block(c, block); - if (!compiler_push_fblock(c, ASYNC_WITH, block, final, s)) { - return 0; - } + USE_LABEL(c, block); + RETURN_IF_ERROR(compiler_push_fblock(c, loc, ASYNC_WITH, block, final, s)); if (item->optional_vars) { VISIT(c, expr, item->optional_vars); } else { - /* Discard result from context.__aenter__() */ - ADDOP(c, POP_TOP); + /* Discard result from context.__aenter__() */ + ADDOP(c, loc, POP_TOP); } pos++; - if (pos == asdl_seq_LEN(s->v.AsyncWith.items)) + if (pos == asdl_seq_LEN(s->v.AsyncWith.items)) { /* BLOCK code */ VISIT_SEQ(c, stmt, s->v.AsyncWith.body) - else if (!compiler_async_with(c, s, pos)) - return 0; + } + else { + RETURN_IF_ERROR(compiler_async_with(c, s, pos)); + } compiler_pop_fblock(c, ASYNC_WITH, block); - ADDOP(c, POP_BLOCK); + + ADDOP(c, loc, POP_BLOCK); /* End of body; start the cleanup */ /* For successful outcome: * call __exit__(None, None, None) */ - SET_LOC(c, s); - if(!compiler_call_exit_with_nones(c)) - return 0; - ADDOP(c, GET_AWAITABLE); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); + RETURN_IF_ERROR(compiler_call_exit_with_nones(c, loc)); + ADDOP_I(c, loc, GET_AWAITABLE, 2); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADD_YIELD_FROM(c, loc, 1); - ADDOP(c, POP_TOP); + ADDOP(c, loc, POP_TOP); - ADDOP_JUMP(c, JUMP_ABSOLUTE, exit); + ADDOP_JUMP(c, loc, JUMP, exit); /* For exceptional outcome: */ - compiler_use_next_block(c, final); + USE_LABEL(c, final); - ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); - ADDOP(c, PUSH_EXC_INFO); - ADDOP(c, WITH_EXCEPT_START); - ADDOP(c, GET_AWAITABLE); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); - compiler_with_except_finish(c, cleanup); + ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup); + ADDOP(c, loc, PUSH_EXC_INFO); + ADDOP(c, loc, WITH_EXCEPT_START); + ADDOP_I(c, loc, GET_AWAITABLE, 2); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADD_YIELD_FROM(c, loc, 1); + RETURN_IF_ERROR(compiler_with_except_finish(c, cleanup)); - compiler_use_next_block(c, exit); - return 1; + USE_LABEL(c, exit); + return SUCCESS; } @@ -5212,11 +5668,11 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) LOAD_CONST (None, None, None) CALL_FUNCTION_EX 0 - JUMP_FORWARD EXIT + JUMP EXIT E: WITH_EXCEPT_START (calls EXPR.__exit__) POP_JUMP_IF_TRUE T: RERAISE - T: POP_TOP * 3 (remove exception from stack) + T: POP_TOP (remove exception from stack) POP_EXCEPT POP_TOP EXIT: @@ -5225,49 +5681,44 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) static int compiler_with(struct compiler *c, stmt_ty s, int pos) { - basicblock *block, *final, *exit, *cleanup; withitem_ty item = asdl_seq_GET(s->v.With.items, pos); assert(s->kind == With_kind); - block = compiler_new_block(c); - final = compiler_new_block(c); - exit = compiler_new_block(c); - cleanup = compiler_new_block(c); - if (!block || !final || !exit || !cleanup) - return 0; + NEW_JUMP_TARGET_LABEL(c, block); + NEW_JUMP_TARGET_LABEL(c, final); + NEW_JUMP_TARGET_LABEL(c, exit); + NEW_JUMP_TARGET_LABEL(c, cleanup); /* Evaluate EXPR */ VISIT(c, expr, item->context_expr); /* Will push bound __exit__ */ - ADDOP(c, BEFORE_WITH); - ADDOP_JUMP(c, SETUP_WITH, final); + location loc = LOC(s); + ADDOP(c, loc, BEFORE_WITH); + ADDOP_JUMP(c, loc, SETUP_WITH, final); /* SETUP_WITH pushes a finally block. */ - compiler_use_next_block(c, block); - if (!compiler_push_fblock(c, WITH, block, final, s)) { - return 0; - } + USE_LABEL(c, block); + RETURN_IF_ERROR(compiler_push_fblock(c, loc, WITH, block, final, s)); if (item->optional_vars) { VISIT(c, expr, item->optional_vars); } else { /* Discard result from context.__enter__() */ - ADDOP(c, POP_TOP); + ADDOP(c, loc, POP_TOP); } pos++; - if (pos == asdl_seq_LEN(s->v.With.items)) + if (pos == asdl_seq_LEN(s->v.With.items)) { /* BLOCK code */ VISIT_SEQ(c, stmt, s->v.With.body) - else if (!compiler_with(c, s, pos)) - return 0; + } + else { + RETURN_IF_ERROR(compiler_with(c, s, pos)); + } - - /* Mark all following code as artificial */ - UNSET_LOC(c); - ADDOP(c, POP_BLOCK); + ADDOP(c, NO_LOCATION, POP_BLOCK); compiler_pop_fblock(c, WITH, block); /* End of body; start the cleanup. */ @@ -5275,31 +5726,31 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) /* For successful outcome: * call __exit__(None, None, None) */ - SET_LOC(c, s); - if (!compiler_call_exit_with_nones(c)) - return 0; - ADDOP(c, POP_TOP); - ADDOP_JUMP(c, JUMP_FORWARD, exit); + loc = LOC(s); + RETURN_IF_ERROR(compiler_call_exit_with_nones(c, loc)); + ADDOP(c, loc, POP_TOP); + ADDOP_JUMP(c, loc, JUMP, exit); /* For exceptional outcome: */ - compiler_use_next_block(c, final); + USE_LABEL(c, final); - ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); - ADDOP(c, PUSH_EXC_INFO); - ADDOP(c, WITH_EXCEPT_START); - compiler_with_except_finish(c, cleanup); + ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup); + ADDOP(c, loc, PUSH_EXC_INFO); + ADDOP(c, loc, WITH_EXCEPT_START); + RETURN_IF_ERROR(compiler_with_except_finish(c, cleanup)); - compiler_use_next_block(c, exit); - return 1; + USE_LABEL(c, exit); + return SUCCESS; } static int compiler_visit_expr1(struct compiler *c, expr_ty e) { + location loc = LOC(e); switch (e->kind) { case NamedExpr_kind: VISIT(c, expr, e->v.NamedExpr.value); - ADDOP(c, DUP_TOP); + ADDOP_I(c, loc, COPY, 1); VISIT(c, expr, e->v.NamedExpr.target); break; case BoolOp_kind: @@ -5307,11 +5758,16 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) case BinOp_kind: VISIT(c, expr, e->v.BinOp.left); VISIT(c, expr, e->v.BinOp.right); - ADDOP_BINARY(c, e->v.BinOp.op); + ADDOP_BINARY(c, loc, e->v.BinOp.op); break; case UnaryOp_kind: VISIT(c, expr, e->v.UnaryOp.operand); - ADDOP(c, unaryop(e->v.UnaryOp.op)); + if (e->v.UnaryOp.op == UAdd) { + ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_UNARY_POSITIVE); + } + else { + ADDOP(c, loc, unaryop(e->v.UnaryOp.op)); + } break; case Lambda_kind: return compiler_lambda(c, e); @@ -5330,51 +5786,52 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) case DictComp_kind: return compiler_dictcomp(c, e); case Yield_kind: - if (c->u->u_ste->ste_type != FunctionBlock) - return compiler_error(c, "'yield' outside function"); + if (c->u->u_ste->ste_type != FunctionBlock) { + return compiler_error(c, loc, "'yield' outside function"); + } if (e->v.Yield.value) { VISIT(c, expr, e->v.Yield.value); } else { - ADDOP_LOAD_CONST(c, Py_None); + ADDOP_LOAD_CONST(c, loc, Py_None); } - ADDOP(c, YIELD_VALUE); + ADDOP_YIELD(c, loc); break; case YieldFrom_kind: - if (c->u->u_ste->ste_type != FunctionBlock) - return compiler_error(c, "'yield' outside function"); - - if (c->u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION) - return compiler_error(c, "'yield from' inside async function"); - + if (c->u->u_ste->ste_type != FunctionBlock) { + return compiler_error(c, loc, "'yield' outside function"); + } + if (c->u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION) { + return compiler_error(c, loc, "'yield from' inside async function"); + } VISIT(c, expr, e->v.YieldFrom.value); - ADDOP(c, GET_YIELD_FROM_ITER); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); + ADDOP(c, loc, GET_YIELD_FROM_ITER); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADD_YIELD_FROM(c, loc, 0); break; case Await_kind: if (!IS_TOP_LEVEL_AWAIT(c)){ if (c->u->u_ste->ste_type != FunctionBlock){ - return compiler_error(c, "'await' outside function"); + return compiler_error(c, loc, "'await' outside function"); } if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION && - c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION){ - return compiler_error(c, "'await' outside async function"); + c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION) { + return compiler_error(c, loc, "'await' outside async function"); } } VISIT(c, expr, e->v.Await.value); - ADDOP(c, GET_AWAITABLE); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, YIELD_FROM); + ADDOP_I(c, loc, GET_AWAITABLE, 0); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADD_YIELD_FROM(c, loc, 1); break; case Compare_kind: return compiler_compare(c, e); case Call_kind: return compiler_call(c, e); case Constant_kind: - ADDOP_LOAD_CONST(c, e->v.Constant.value); + ADDOP_LOAD_CONST(c, loc, e->v.Constant.value); break; case JoinedStr_kind: return compiler_joined_str(c, e); @@ -5383,26 +5840,20 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) /* The following exprs can be assignment targets. */ case Attribute_kind: VISIT(c, expr, e->v.Attribute.value); + loc = LOC(e); + loc = update_start_location_to_match_attr(c, loc, e); switch (e->v.Attribute.ctx) { case Load: - { - int old_lineno = c->u->u_lineno; - c->u->u_lineno = e->end_lineno; - ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names); - c->u->u_lineno = old_lineno; + ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names); break; - } case Store: - if (forbidden_name(c, e->v.Attribute.attr, e->v.Attribute.ctx)) { - return 0; + if (forbidden_name(c, loc, e->v.Attribute.attr, e->v.Attribute.ctx)) { + return ERROR; } - int old_lineno = c->u->u_lineno; - c->u->u_lineno = e->end_lineno; - ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names); - c->u->u_lineno = old_lineno; + ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names); break; case Del: - ADDOP_NAME(c, DELETE_ATTR, e->v.Attribute.attr, names); + ADDOP_NAME(c, loc, DELETE_ATTR, e->v.Attribute.attr, names); break; } break; @@ -5413,114 +5864,126 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) case Store: /* In all legitimate cases, the Starred node was already replaced * by compiler_list/compiler_tuple. XXX: is that okay? */ - return compiler_error(c, + return compiler_error(c, loc, "starred assignment target must be in a list or tuple"); default: - return compiler_error(c, + return compiler_error(c, loc, "can't use starred expression here"); } break; case Slice_kind: - return compiler_slice(c, e); + { + int n = compiler_slice(c, e); + RETURN_IF_ERROR(n); + ADDOP_I(c, loc, BUILD_SLICE, n); + break; + } case Name_kind: - return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx); + return compiler_nameop(c, loc, e->v.Name.id, e->v.Name.ctx); /* child nodes of List and Tuple will have expr_context set */ case List_kind: return compiler_list(c, e); case Tuple_kind: return compiler_tuple(c, e); } - return 1; + return SUCCESS; } static int compiler_visit_expr(struct compiler *c, expr_ty e) { - int old_lineno = c->u->u_lineno; - int old_end_lineno = c->u->u_end_lineno; - int old_col_offset = c->u->u_col_offset; - int old_end_col_offset = c->u->u_end_col_offset; - SET_LOC(c, e); int res = compiler_visit_expr1(c, e); - c->u->u_lineno = old_lineno; - c->u->u_end_lineno = old_end_lineno; - c->u->u_col_offset = old_col_offset; - c->u->u_end_col_offset = old_end_col_offset; return res; } +static bool +is_two_element_slice(expr_ty s) +{ + return s->kind == Slice_kind && + s->v.Slice.step == NULL; +} + static int compiler_augassign(struct compiler *c, stmt_ty s) { assert(s->kind == AugAssign_kind); expr_ty e = s->v.AugAssign.target; - int old_lineno = c->u->u_lineno; - int old_end_lineno = c->u->u_end_lineno; - int old_col_offset = c->u->u_col_offset; - int old_end_col_offset = c->u->u_end_col_offset; - SET_LOC(c, e); + location loc = LOC(e); switch (e->kind) { case Attribute_kind: VISIT(c, expr, e->v.Attribute.value); - ADDOP(c, DUP_TOP); - int old_lineno = c->u->u_lineno; - c->u->u_lineno = e->end_lineno; - ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names); - c->u->u_lineno = old_lineno; + ADDOP_I(c, loc, COPY, 1); + loc = update_start_location_to_match_attr(c, loc, e); + ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names); break; case Subscript_kind: VISIT(c, expr, e->v.Subscript.value); - VISIT(c, expr, e->v.Subscript.slice); - ADDOP(c, DUP_TOP_TWO); - ADDOP(c, BINARY_SUBSCR); + if (is_two_element_slice(e->v.Subscript.slice)) { + RETURN_IF_ERROR(compiler_slice(c, e->v.Subscript.slice)); + ADDOP_I(c, loc, COPY, 3); + ADDOP_I(c, loc, COPY, 3); + ADDOP_I(c, loc, COPY, 3); + ADDOP(c, loc, BINARY_SLICE); + } + else { + VISIT(c, expr, e->v.Subscript.slice); + ADDOP_I(c, loc, COPY, 2); + ADDOP_I(c, loc, COPY, 2); + ADDOP(c, loc, BINARY_SUBSCR); + } break; case Name_kind: - if (!compiler_nameop(c, e->v.Name.id, Load)) - return 0; + RETURN_IF_ERROR(compiler_nameop(c, loc, e->v.Name.id, Load)); break; default: PyErr_Format(PyExc_SystemError, "invalid node type (%d) for augmented assignment", e->kind); - return 0; + return ERROR; } - c->u->u_lineno = old_lineno; - c->u->u_end_lineno = old_end_lineno; - c->u->u_col_offset = old_col_offset; - c->u->u_end_col_offset = old_end_col_offset; + loc = LOC(s); VISIT(c, expr, s->v.AugAssign.value); - ADDOP_INPLACE(c, s->v.AugAssign.op); + ADDOP_INPLACE(c, loc, s->v.AugAssign.op); - SET_LOC(c, e); + loc = LOC(e); switch (e->kind) { case Attribute_kind: - c->u->u_lineno = e->end_lineno; - ADDOP(c, ROT_TWO); - ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names); + loc = update_start_location_to_match_attr(c, loc, e); + ADDOP_I(c, loc, SWAP, 2); + ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names); break; case Subscript_kind: - ADDOP(c, ROT_THREE); - ADDOP(c, STORE_SUBSCR); + if (is_two_element_slice(e->v.Subscript.slice)) { + ADDOP_I(c, loc, SWAP, 4); + ADDOP_I(c, loc, SWAP, 3); + ADDOP_I(c, loc, SWAP, 2); + ADDOP(c, loc, STORE_SLICE); + } + else { + ADDOP_I(c, loc, SWAP, 3); + ADDOP_I(c, loc, SWAP, 2); + ADDOP(c, loc, STORE_SUBSCR); + } break; case Name_kind: - return compiler_nameop(c, e->v.Name.id, Store); + return compiler_nameop(c, loc, e->v.Name.id, Store); default: Py_UNREACHABLE(); } - return 1; + return SUCCESS; } static int check_ann_expr(struct compiler *c, expr_ty e) { VISIT(c, expr, e); - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, LOC(e), POP_TOP); + return SUCCESS; } static int @@ -5528,8 +5991,8 @@ check_annotation(struct compiler *c, stmt_ty s) { /* Annotations of complex targets does not produce anything under annotations future */ - if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) { - return 1; + if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) { + return SUCCESS; } /* Annotations are only evaluated in a module or class. */ @@ -5537,7 +6000,7 @@ check_annotation(struct compiler *c, stmt_ty s) c->u->u_scope_type == COMPILER_SCOPE_CLASS) { return check_ann_expr(c, s->v.AnnAssign.annotation); } - return 1; + return SUCCESS; } static int @@ -5546,26 +6009,24 @@ check_ann_subscr(struct compiler *c, expr_ty e) /* We check that everything in a subscript is defined at runtime. */ switch (e->kind) { case Slice_kind: - if (e->v.Slice.lower && !check_ann_expr(c, e->v.Slice.lower)) { - return 0; + if (e->v.Slice.lower && check_ann_expr(c, e->v.Slice.lower) < 0) { + return ERROR; } - if (e->v.Slice.upper && !check_ann_expr(c, e->v.Slice.upper)) { - return 0; + if (e->v.Slice.upper && check_ann_expr(c, e->v.Slice.upper) < 0) { + return ERROR; } - if (e->v.Slice.step && !check_ann_expr(c, e->v.Slice.step)) { - return 0; + if (e->v.Slice.step && check_ann_expr(c, e->v.Slice.step) < 0) { + return ERROR; } - return 1; + return SUCCESS; case Tuple_kind: { /* extended slice */ asdl_expr_seq *elts = e->v.Tuple.elts; Py_ssize_t i, n = asdl_seq_LEN(elts); for (i = 0; i < n; i++) { - if (!check_ann_subscr(c, asdl_seq_GET(elts, i))) { - return 0; - } + RETURN_IF_ERROR(check_ann_subscr(c, asdl_seq_GET(elts, i))); } - return 1; + return SUCCESS; } default: return check_ann_expr(c, e); @@ -5575,14 +6036,9 @@ check_ann_subscr(struct compiler *c, expr_ty e) static int compiler_annassign(struct compiler *c, stmt_ty s) { + location loc = LOC(s); expr_ty targ = s->v.AnnAssign.target; PyObject* mangled; - _Py_IDENTIFIER(__annotations__); - /* borrowed ref*/ - PyObject *__annotations__ = _PyUnicode_FromId(&PyId___annotations__); - if (__annotations__ == NULL) { - return 0; - } assert(s->kind == AnnAssign_kind); @@ -5593,50 +6049,52 @@ compiler_annassign(struct compiler *c, stmt_ty s) } switch (targ->kind) { case Name_kind: - if (forbidden_name(c, targ->v.Name.id, Store)) - return 0; + if (forbidden_name(c, loc, targ->v.Name.id, Store)) { + return ERROR; + } /* If we have a simple name in a module or class, store annotation. */ if (s->v.AnnAssign.simple && (c->u->u_scope_type == COMPILER_SCOPE_MODULE || c->u->u_scope_type == COMPILER_SCOPE_CLASS)) { - if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) { + if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) { VISIT(c, annexpr, s->v.AnnAssign.annotation) } else { VISIT(c, expr, s->v.AnnAssign.annotation); } - ADDOP_NAME(c, LOAD_NAME, __annotations__, names); + ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__annotations__), names); mangled = _Py_Mangle(c->u->u_private, targ->v.Name.id); - ADDOP_LOAD_CONST_NEW(c, mangled); - ADDOP(c, STORE_SUBSCR); + ADDOP_LOAD_CONST_NEW(c, loc, mangled); + ADDOP(c, loc, STORE_SUBSCR); } break; case Attribute_kind: - if (forbidden_name(c, targ->v.Attribute.attr, Store)) - return 0; + if (forbidden_name(c, loc, targ->v.Attribute.attr, Store)) { + return ERROR; + } if (!s->v.AnnAssign.value && - !check_ann_expr(c, targ->v.Attribute.value)) { - return 0; + check_ann_expr(c, targ->v.Attribute.value) < 0) { + return ERROR; } break; case Subscript_kind: if (!s->v.AnnAssign.value && - (!check_ann_expr(c, targ->v.Subscript.value) || - !check_ann_subscr(c, targ->v.Subscript.slice))) { - return 0; + (check_ann_expr(c, targ->v.Subscript.value) < 0 || + check_ann_subscr(c, targ->v.Subscript.slice) < 0)) { + return ERROR; } break; default: PyErr_Format(PyExc_SystemError, "invalid node type (%d) for annotated assignment", targ->kind); - return 0; + return ERROR; } /* Annotation is evaluated last. */ - if (!s->v.AnnAssign.simple && !check_annotation(c, s)) { - return 0; + if (!s->v.AnnAssign.simple && check_annotation(c, s) < 0) { + return ERROR; } - return 1; + return SUCCESS; } /* Raises a SyntaxError and returns 0. @@ -5644,36 +6102,32 @@ compiler_annassign(struct compiler *c, stmt_ty s) */ static int -compiler_error(struct compiler *c, const char *format, ...) +compiler_error(struct compiler *c, location loc, + const char *format, ...) { va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif PyObject *msg = PyUnicode_FromFormatV(format, vargs); va_end(vargs); if (msg == NULL) { - return 0; + return ERROR; } - PyObject *loc = PyErr_ProgramTextObject(c->c_filename, c->u->u_lineno); - if (loc == NULL) { - Py_INCREF(Py_None); - loc = Py_None; + PyObject *loc_obj = PyErr_ProgramTextObject(c->c_filename, loc.lineno); + if (loc_obj == NULL) { + loc_obj = Py_NewRef(Py_None); } PyObject *args = Py_BuildValue("O(OiiOii)", msg, c->c_filename, - c->u->u_lineno, c->u->u_col_offset + 1, loc, - c->u->u_end_lineno, c->u->u_end_col_offset + 1); + loc.lineno, loc.col_offset + 1, loc_obj, + loc.end_lineno, loc.end_col_offset + 1); Py_DECREF(msg); if (args == NULL) { goto exit; } PyErr_SetObject(PyExc_SyntaxError, args); exit: - Py_DECREF(loc); + Py_DECREF(loc_obj); Py_XDECREF(args); - return 0; + return ERROR; } /* Emits a SyntaxWarning and returns 1 on success. @@ -5681,63 +6135,71 @@ compiler_error(struct compiler *c, const char *format, ...) and returns 0. */ static int -compiler_warn(struct compiler *c, const char *format, ...) +compiler_warn(struct compiler *c, location loc, + const char *format, ...) { va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif PyObject *msg = PyUnicode_FromFormatV(format, vargs); va_end(vargs); if (msg == NULL) { - return 0; + return ERROR; } if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, c->c_filename, - c->u->u_lineno, NULL, NULL) < 0) + loc.lineno, NULL, NULL) < 0) { if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) { /* Replace the SyntaxWarning exception with a SyntaxError to get a more accurate error report */ PyErr_Clear(); assert(PyUnicode_AsUTF8(msg) != NULL); - compiler_error(c, PyUnicode_AsUTF8(msg)); + compiler_error(c, loc, PyUnicode_AsUTF8(msg)); } Py_DECREF(msg); - return 0; + return ERROR; } Py_DECREF(msg); - return 1; + return SUCCESS; } static int compiler_subscript(struct compiler *c, expr_ty e) { + location loc = LOC(e); expr_context_ty ctx = e->v.Subscript.ctx; int op = 0; if (ctx == Load) { - if (!check_subscripter(c, e->v.Subscript.value)) { - return 0; - } - if (!check_index(c, e->v.Subscript.value, e->v.Subscript.slice)) { - return 0; - } + RETURN_IF_ERROR(check_subscripter(c, e->v.Subscript.value)); + RETURN_IF_ERROR(check_index(c, e->v.Subscript.value, e->v.Subscript.slice)); } - switch (ctx) { - case Load: op = BINARY_SUBSCR; break; - case Store: op = STORE_SUBSCR; break; - case Del: op = DELETE_SUBSCR; break; - } - assert(op); VISIT(c, expr, e->v.Subscript.value); - VISIT(c, expr, e->v.Subscript.slice); - ADDOP(c, op); - return 1; + if (is_two_element_slice(e->v.Subscript.slice) && ctx != Del) { + RETURN_IF_ERROR(compiler_slice(c, e->v.Subscript.slice)); + if (ctx == Load) { + ADDOP(c, loc, BINARY_SLICE); + } + else { + assert(ctx == Store); + ADDOP(c, loc, STORE_SLICE); + } + } + else { + VISIT(c, expr, e->v.Subscript.slice); + switch (ctx) { + case Load: op = BINARY_SUBSCR; break; + case Store: op = STORE_SUBSCR; break; + case Del: op = DELETE_SUBSCR; break; + } + assert(op); + ADDOP(c, loc, op); + } + return SUCCESS; } +/* Returns the number of the values emitted, + * thus are needed to build the slice, or -1 if there is an error. */ static int compiler_slice(struct compiler *c, expr_ty s) { @@ -5749,22 +6211,21 @@ compiler_slice(struct compiler *c, expr_ty s) VISIT(c, expr, s->v.Slice.lower); } else { - ADDOP_LOAD_CONST(c, Py_None); + ADDOP_LOAD_CONST(c, LOC(s), Py_None); } if (s->v.Slice.upper) { VISIT(c, expr, s->v.Slice.upper); } else { - ADDOP_LOAD_CONST(c, Py_None); + ADDOP_LOAD_CONST(c, LOC(s), Py_None); } if (s->v.Slice.step) { n++; VISIT(c, expr, s->v.Slice.step); } - ADDOP_I(c, BUILD_SLICE, n); - return 1; + return n; } @@ -5796,92 +6257,104 @@ ensure_fail_pop(struct compiler *c, pattern_context *pc, Py_ssize_t n) { Py_ssize_t size = n + 1; if (size <= pc->fail_pop_size) { - return 1; + return SUCCESS; } - Py_ssize_t needed = sizeof(basicblock*) * size; - basicblock **resized = PyObject_Realloc(pc->fail_pop, needed); + Py_ssize_t needed = sizeof(jump_target_label) * size; + jump_target_label *resized = PyObject_Realloc(pc->fail_pop, needed); if (resized == NULL) { PyErr_NoMemory(); - return 0; + return ERROR; } pc->fail_pop = resized; while (pc->fail_pop_size < size) { - basicblock *new_block; - RETURN_IF_FALSE(new_block = compiler_new_block(c)); + NEW_JUMP_TARGET_LABEL(c, new_block); pc->fail_pop[pc->fail_pop_size++] = new_block; } - return 1; + return SUCCESS; } // Use op to jump to the correct fail_pop block. static int -jump_to_fail_pop(struct compiler *c, pattern_context *pc, int op) +jump_to_fail_pop(struct compiler *c, location loc, + pattern_context *pc, int op) { // Pop any items on the top of the stack, plus any objects we were going to // capture on success: Py_ssize_t pops = pc->on_top + PyList_GET_SIZE(pc->stores); - RETURN_IF_FALSE(ensure_fail_pop(c, pc, pops)); - ADDOP_JUMP(c, op, pc->fail_pop[pops]); - NEXT_BLOCK(c); - return 1; + RETURN_IF_ERROR(ensure_fail_pop(c, pc, pops)); + ADDOP_JUMP(c, loc, op, pc->fail_pop[pops]); + return SUCCESS; } // Build all of the fail_pop blocks and reset fail_pop. static int -emit_and_reset_fail_pop(struct compiler *c, pattern_context *pc) +emit_and_reset_fail_pop(struct compiler *c, location loc, + pattern_context *pc) { if (!pc->fail_pop_size) { assert(pc->fail_pop == NULL); - NEXT_BLOCK(c); - return 1; + return SUCCESS; } while (--pc->fail_pop_size) { - compiler_use_next_block(c, pc->fail_pop[pc->fail_pop_size]); - if (!compiler_addop(c, POP_TOP)) { + USE_LABEL(c, pc->fail_pop[pc->fail_pop_size]); + if (cfg_builder_addop_noarg(CFG_BUILDER(c), POP_TOP, loc) < 0) { pc->fail_pop_size = 0; PyObject_Free(pc->fail_pop); pc->fail_pop = NULL; - return 0; + return ERROR; } } - compiler_use_next_block(c, pc->fail_pop[0]); + USE_LABEL(c, pc->fail_pop[0]); PyObject_Free(pc->fail_pop); pc->fail_pop = NULL; - return 1; + return SUCCESS; } static int -compiler_error_duplicate_store(struct compiler *c, identifier n) +compiler_error_duplicate_store(struct compiler *c, location loc, identifier n) { - return compiler_error(c, "multiple assignments to name %R in pattern", n); + return compiler_error(c, loc, + "multiple assignments to name %R in pattern", n); +} + +// Duplicate the effect of 3.10's ROT_* instructions using SWAPs. +static int +pattern_helper_rotate(struct compiler *c, location loc, Py_ssize_t count) +{ + while (1 < count) { + ADDOP_I(c, loc, SWAP, count--); + } + return SUCCESS; } static int -pattern_helper_store_name(struct compiler *c, identifier n, pattern_context *pc) +pattern_helper_store_name(struct compiler *c, location loc, + identifier n, pattern_context *pc) { if (n == NULL) { - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, loc, POP_TOP); + return SUCCESS; } - if (forbidden_name(c, n, Store)) { - return 0; + if (forbidden_name(c, loc, n, Store)) { + return ERROR; } // Can't assign to the same name twice: int duplicate = PySequence_Contains(pc->stores, n); - if (duplicate < 0) { - return 0; - } + RETURN_IF_ERROR(duplicate); if (duplicate) { - return compiler_error_duplicate_store(c, n); + return compiler_error_duplicate_store(c, loc, n); } // Rotate this object underneath any items we need to preserve: - ADDOP_I(c, ROT_N, pc->on_top + PyList_GET_SIZE(pc->stores) + 1); - return !PyList_Append(pc->stores, n); + Py_ssize_t rotations = pc->on_top + PyList_GET_SIZE(pc->stores) + 1; + RETURN_IF_ERROR(pattern_helper_rotate(c, loc, rotations)); + RETURN_IF_ERROR(PyList_Append(pc->stores, n)); + return SUCCESS; } static int -pattern_unpack_helper(struct compiler *c, asdl_pattern_seq *elts) +pattern_unpack_helper(struct compiler *c, location loc, + asdl_pattern_seq *elts) { Py_ssize_t n = asdl_seq_LEN(elts); int seen_star = 0; @@ -5889,29 +6362,31 @@ pattern_unpack_helper(struct compiler *c, asdl_pattern_seq *elts) pattern_ty elt = asdl_seq_GET(elts, i); if (elt->kind == MatchStar_kind && !seen_star) { if ((i >= (1 << 8)) || - (n-i-1 >= (INT_MAX >> 8))) - return compiler_error(c, + (n-i-1 >= (INT_MAX >> 8))) { + return compiler_error(c, loc, "too many expressions in " "star-unpacking sequence pattern"); - ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8))); + } + ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8))); seen_star = 1; } else if (elt->kind == MatchStar_kind) { - return compiler_error(c, + return compiler_error(c, loc, "multiple starred expressions in sequence pattern"); } } if (!seen_star) { - ADDOP_I(c, UNPACK_SEQUENCE, n); + ADDOP_I(c, loc, UNPACK_SEQUENCE, n); } - return 1; + return SUCCESS; } static int -pattern_helper_sequence_unpack(struct compiler *c, asdl_pattern_seq *patterns, - Py_ssize_t star, pattern_context *pc) +pattern_helper_sequence_unpack(struct compiler *c, location loc, + asdl_pattern_seq *patterns, Py_ssize_t star, + pattern_context *pc) { - RETURN_IF_FALSE(pattern_unpack_helper(c, patterns)); + RETURN_IF_ERROR(pattern_unpack_helper(c, loc, patterns)); Py_ssize_t size = asdl_seq_LEN(patterns); // We've now got a bunch of new subjects on the stack. They need to remain // there after each subpattern match: @@ -5920,17 +6395,18 @@ pattern_helper_sequence_unpack(struct compiler *c, asdl_pattern_seq *patterns, // One less item to keep track of each time we loop through: pc->on_top--; pattern_ty pattern = asdl_seq_GET(patterns, i); - RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); + RETURN_IF_ERROR(compiler_pattern_subpattern(c, pattern, pc)); } - return 1; + return SUCCESS; } // Like pattern_helper_sequence_unpack, but uses BINARY_SUBSCR instead of // UNPACK_SEQUENCE / UNPACK_EX. This is more efficient for patterns with a // starred wildcard like [first, *_] / [first, *_, last] / [*_, last] / etc. static int -pattern_helper_sequence_subscr(struct compiler *c, asdl_pattern_seq *patterns, - Py_ssize_t star, pattern_context *pc) +pattern_helper_sequence_subscr(struct compiler *c, location loc, + asdl_pattern_seq *patterns, Py_ssize_t star, + pattern_context *pc) { // We need to keep the subject around for extracting elements: pc->on_top++; @@ -5944,35 +6420,36 @@ pattern_helper_sequence_subscr(struct compiler *c, asdl_pattern_seq *patterns, assert(WILDCARD_STAR_CHECK(pattern)); continue; } - ADDOP(c, DUP_TOP); + ADDOP_I(c, loc, COPY, 1); if (i < star) { - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(i)); + ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(i)); } else { // The subject may not support negative indexing! Compute a // nonnegative index: - ADDOP(c, GET_LEN); - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size - i)); - ADDOP_BINARY(c, Sub); + ADDOP(c, loc, GET_LEN); + ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(size - i)); + ADDOP_BINARY(c, loc, Sub); } - ADDOP(c, BINARY_SUBSCR); - RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); + ADDOP(c, loc, BINARY_SUBSCR); + RETURN_IF_ERROR(compiler_pattern_subpattern(c, pattern, pc)); } // Pop the subject, we're done with it: pc->on_top--; - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, loc, POP_TOP); + return SUCCESS; } // Like compiler_pattern, but turn off checks for irrefutability. static int -compiler_pattern_subpattern(struct compiler *c, pattern_ty p, pattern_context *pc) +compiler_pattern_subpattern(struct compiler *c, + pattern_ty p, pattern_context *pc) { int allow_irrefutable = pc->allow_irrefutable; pc->allow_irrefutable = 1; - RETURN_IF_FALSE(compiler_pattern(c, p, pc)); + RETURN_IF_ERROR(compiler_pattern(c, p, pc)); pc->allow_irrefutable = allow_irrefutable; - return 1; + return SUCCESS; } static int @@ -5984,29 +6461,30 @@ compiler_pattern_as(struct compiler *c, pattern_ty p, pattern_context *pc) if (!pc->allow_irrefutable) { if (p->v.MatchAs.name) { const char *e = "name capture %R makes remaining patterns unreachable"; - return compiler_error(c, e, p->v.MatchAs.name); + return compiler_error(c, LOC(p), e, p->v.MatchAs.name); } const char *e = "wildcard makes remaining patterns unreachable"; - return compiler_error(c, e); + return compiler_error(c, LOC(p), e); } - return pattern_helper_store_name(c, p->v.MatchAs.name, pc); + return pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc); } // Need to make a copy for (possibly) storing later: pc->on_top++; - ADDOP(c, DUP_TOP); - RETURN_IF_FALSE(compiler_pattern(c, p->v.MatchAs.pattern, pc)); + ADDOP_I(c, LOC(p), COPY, 1); + RETURN_IF_ERROR(compiler_pattern(c, p->v.MatchAs.pattern, pc)); // Success! Store it: pc->on_top--; - RETURN_IF_FALSE(pattern_helper_store_name(c, p->v.MatchAs.name, pc)); - return 1; + RETURN_IF_ERROR(pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc)); + return SUCCESS; } static int compiler_pattern_star(struct compiler *c, pattern_ty p, pattern_context *pc) { assert(p->kind == MatchStar_kind); - RETURN_IF_FALSE(pattern_helper_store_name(c, p->v.MatchStar.name, pc)); - return 1; + RETURN_IF_ERROR( + pattern_helper_store_name(c, LOC(p), p->v.MatchStar.name, pc)); + return SUCCESS; } static int @@ -6017,20 +6495,20 @@ validate_kwd_attrs(struct compiler *c, asdl_identifier_seq *attrs, asdl_pattern_ Py_ssize_t nattrs = asdl_seq_LEN(attrs); for (Py_ssize_t i = 0; i < nattrs; i++) { identifier attr = ((identifier)asdl_seq_GET(attrs, i)); - SET_LOC(c, ((pattern_ty) asdl_seq_GET(patterns, i))); - if (forbidden_name(c, attr, Store)) { - return -1; + location loc = LOC((pattern_ty) asdl_seq_GET(patterns, i)); + if (forbidden_name(c, loc, attr, Store)) { + return ERROR; } for (Py_ssize_t j = i + 1; j < nattrs; j++) { identifier other = ((identifier)asdl_seq_GET(attrs, j)); if (!PyUnicode_Compare(attr, other)) { - SET_LOC(c, ((pattern_ty) asdl_seq_GET(patterns, j))); - compiler_error(c, "attribute name repeated in class pattern: %U", attr); - return -1; + location loc = LOC((pattern_ty) asdl_seq_GET(patterns, j)); + compiler_error(c, loc, "attribute name repeated in class pattern: %U", attr); + return ERROR; } } } - return 0; + return SUCCESS; } static int @@ -6047,34 +6525,34 @@ compiler_pattern_class(struct compiler *c, pattern_ty p, pattern_context *pc) // AST validator shouldn't let this happen, but if it does, // just fail, don't crash out of the interpreter const char * e = "kwd_attrs (%d) / kwd_patterns (%d) length mismatch in class pattern"; - return compiler_error(c, e, nattrs, nkwd_patterns); + return compiler_error(c, LOC(p), e, nattrs, nkwd_patterns); } if (INT_MAX < nargs || INT_MAX < nargs + nattrs - 1) { const char *e = "too many sub-patterns in class pattern %R"; - return compiler_error(c, e, p->v.MatchClass.cls); + return compiler_error(c, LOC(p), e, p->v.MatchClass.cls); } if (nattrs) { - RETURN_IF_FALSE(!validate_kwd_attrs(c, kwd_attrs, kwd_patterns)); - SET_LOC(c, p); + RETURN_IF_ERROR(validate_kwd_attrs(c, kwd_attrs, kwd_patterns)); } VISIT(c, expr, p->v.MatchClass.cls); - PyObject *attr_names; - RETURN_IF_FALSE(attr_names = PyTuple_New(nattrs)); + PyObject *attr_names = PyTuple_New(nattrs); + if (attr_names == NULL) { + return ERROR; + } Py_ssize_t i; for (i = 0; i < nattrs; i++) { PyObject *name = asdl_seq_GET(kwd_attrs, i); - Py_INCREF(name); - PyTuple_SET_ITEM(attr_names, i, name); + PyTuple_SET_ITEM(attr_names, i, Py_NewRef(name)); } - ADDOP_LOAD_CONST_NEW(c, attr_names); - ADDOP_I(c, MATCH_CLASS, nargs); - ADDOP(c, DUP_TOP); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP_I(c, IS_OP, 1); + ADDOP_LOAD_CONST_NEW(c, LOC(p), attr_names); + ADDOP_I(c, LOC(p), MATCH_CLASS, nargs); + ADDOP_I(c, LOC(p), COPY, 1); + ADDOP_LOAD_CONST(c, LOC(p), Py_None); + ADDOP_I(c, LOC(p), IS_OP, 1); // TOS is now a tuple of (nargs + nattrs) attributes (or None): pc->on_top++; - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); - ADDOP_I(c, UNPACK_SEQUENCE, nargs + nattrs); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); + ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, nargs + nattrs); pc->on_top += nargs + nattrs - 1; for (i = 0; i < nargs + nattrs; i++) { pc->on_top--; @@ -6088,17 +6566,18 @@ compiler_pattern_class(struct compiler *c, pattern_ty p, pattern_context *pc) pattern = asdl_seq_GET(kwd_patterns, i - nargs); } if (WILDCARD_CHECK(pattern)) { - ADDOP(c, POP_TOP); + ADDOP(c, LOC(p), POP_TOP); continue; } - RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); + RETURN_IF_ERROR(compiler_pattern_subpattern(c, pattern, pc)); } // Success! Pop the tuple of attributes: - return 1; + return SUCCESS; } static int -compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) +compiler_pattern_mapping(struct compiler *c, pattern_ty p, + pattern_context *pc) { assert(p->kind == MatchMapping_kind); asdl_expr_seq *keys = p->v.MatchMapping.keys; @@ -6109,29 +6588,29 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) // AST validator shouldn't let this happen, but if it does, // just fail, don't crash out of the interpreter const char * e = "keys (%d) / patterns (%d) length mismatch in mapping pattern"; - return compiler_error(c, e, size, npatterns); + return compiler_error(c, LOC(p), e, size, npatterns); } // We have a double-star target if "rest" is set PyObject *star_target = p->v.MatchMapping.rest; // We need to keep the subject on top during the mapping and length checks: pc->on_top++; - ADDOP(c, MATCH_MAPPING); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); + ADDOP(c, LOC(p), MATCH_MAPPING); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); if (!size && !star_target) { // If the pattern is just "{}", we're done! Pop the subject: pc->on_top--; - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, LOC(p), POP_TOP); + return SUCCESS; } if (size) { // If the pattern has any keys in it, perform a length check: - ADDOP(c, GET_LEN); - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size)); - ADDOP_COMPARE(c, GtE); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); + ADDOP(c, LOC(p), GET_LEN); + ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size)); + ADDOP_COMPARE(c, LOC(p), GtE); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); } if (INT_MAX < size - 1) { - return compiler_error(c, "too many sub-patterns in mapping pattern"); + return compiler_error(c, LOC(p), "too many sub-patterns in mapping pattern"); } // Collect all of the keys into a tuple for MATCH_KEYS and // **rest. They can either be dotted names or literals: @@ -6140,7 +6619,7 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) // SyntaxError in the case of duplicates. PyObject *seen = PySet_New(NULL); if (seen == NULL) { - return 0; + return ERROR; } // NOTE: goto error on failure in the loop below to avoid leaking `seen` @@ -6149,8 +6628,8 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) if (key == NULL) { const char *e = "can't use NULL keys in MatchMapping " "(set 'rest' parameter instead)"; - SET_LOC(c, ((pattern_ty) asdl_seq_GET(patterns, i))); - compiler_error(c, e); + location loc = LOC((pattern_ty) asdl_seq_GET(patterns, i)); + compiler_error(c, loc, e); goto error; } @@ -6161,7 +6640,7 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) } if (in_seen) { const char *e = "mapping pattern checks duplicate key (%R)"; - compiler_error(c, e, key->v.Constant.value); + compiler_error(c, LOC(p), e, key->v.Constant.value); goto error; } if (PySet_Add(seen, key->v.Constant.value)) { @@ -6171,10 +6650,10 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) else if (key->kind != Attribute_kind) { const char *e = "mapping pattern keys may only match literals and attribute lookups"; - compiler_error(c, e); + compiler_error(c, LOC(p), e); goto error; } - if (!compiler_visit_expr(c, key)) { + if (compiler_visit_expr(c, key) < 0) { goto error; } } @@ -6182,22 +6661,22 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) // all keys have been checked; there are no duplicates Py_DECREF(seen); - ADDOP_I(c, BUILD_TUPLE, size); - ADDOP(c, MATCH_KEYS); + ADDOP_I(c, LOC(p), BUILD_TUPLE, size); + ADDOP(c, LOC(p), MATCH_KEYS); // There's now a tuple of keys and a tuple of values on top of the subject: pc->on_top += 2; - ADDOP(c, DUP_TOP); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP_I(c, IS_OP, 1); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); + ADDOP_I(c, LOC(p), COPY, 1); + ADDOP_LOAD_CONST(c, LOC(p), Py_None); + ADDOP_I(c, LOC(p), IS_OP, 1); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); // So far so good. Use that tuple of values on the stack to match // sub-patterns against: - ADDOP_I(c, UNPACK_SEQUENCE, size); + ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, size); pc->on_top += size - 1; for (Py_ssize_t i = 0; i < size; i++) { pc->on_top--; pattern_ty pattern = asdl_seq_GET(patterns, i); - RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); + RETURN_IF_ERROR(compiler_pattern_subpattern(c, pattern, pc)); } // If we get this far, it's a match! Whatever happens next should consume // the tuple of keys and the subject: @@ -6209,35 +6688,33 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) // rest = dict(TOS1) // for key in TOS: // del rest[key] - ADDOP_I(c, BUILD_MAP, 0); // [subject, keys, empty] - ADDOP(c, ROT_THREE); // [empty, subject, keys] - ADDOP(c, ROT_TWO); // [empty, keys, subject] - ADDOP_I(c, DICT_UPDATE, 2); // [copy, keys] - ADDOP_I(c, UNPACK_SEQUENCE, size); // [copy, keys...] + ADDOP_I(c, LOC(p), BUILD_MAP, 0); // [subject, keys, empty] + ADDOP_I(c, LOC(p), SWAP, 3); // [empty, keys, subject] + ADDOP_I(c, LOC(p), DICT_UPDATE, 2); // [copy, keys] + ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, size); // [copy, keys...] while (size) { - ADDOP_I(c, COPY, 1 + size--); // [copy, keys..., copy] - ADDOP(c, ROT_TWO); // [copy, keys..., copy, key] - ADDOP(c, DELETE_SUBSCR); // [copy, keys...] + ADDOP_I(c, LOC(p), COPY, 1 + size--); // [copy, keys..., copy] + ADDOP_I(c, LOC(p), SWAP, 2); // [copy, keys..., copy, key] + ADDOP(c, LOC(p), DELETE_SUBSCR); // [copy, keys...] } - RETURN_IF_FALSE(pattern_helper_store_name(c, star_target, pc)); + RETURN_IF_ERROR(pattern_helper_store_name(c, LOC(p), star_target, pc)); } else { - ADDOP(c, POP_TOP); // Tuple of keys. - ADDOP(c, POP_TOP); // Subject. + ADDOP(c, LOC(p), POP_TOP); // Tuple of keys. + ADDOP(c, LOC(p), POP_TOP); // Subject. } - return 1; + return SUCCESS; error: Py_DECREF(seen); - return 0; + return ERROR; } static int compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) { assert(p->kind == MatchOr_kind); - basicblock *end; - RETURN_IF_FALSE(end = compiler_new_block(c)); + NEW_JUMP_TARGET_LABEL(c, end); Py_ssize_t size = asdl_seq_LEN(p->v.MatchOr.patterns); assert(size > 1); // We're going to be messing with pc. Keep the original info handy: @@ -6250,7 +6727,6 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) // NOTE: We can't use returning macros anymore! goto error on error. for (Py_ssize_t i = 0; i < size; i++) { pattern_ty alt = asdl_seq_GET(p->v.MatchOr.patterns, i); - SET_LOC(c, alt); PyObject *pc_stores = PyList_New(0); if (pc_stores == NULL) { goto error; @@ -6261,7 +6737,8 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) pc->fail_pop = NULL; pc->fail_pop_size = 0; pc->on_top = 0; - if (!compiler_addop(c, DUP_TOP) || !compiler_pattern(c, alt, pc)) { + if (cfg_builder_addop_i(CFG_BUILDER(c), COPY, 1, LOC(alt)) < 0 || + compiler_pattern(c, alt, pc) < 0) { goto error; } // Success! @@ -6271,8 +6748,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) // for the others (they can't bind a different set of names, and // might need to be reordered): assert(control == NULL); - control = pc->stores; - Py_INCREF(control); + control = Py_NewRef(pc->stores); } else if (nstores != PyList_GET_SIZE(control)) { goto diff; @@ -6293,7 +6769,8 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) // this; the current solution is potentially very // inefficient when each alternative subpattern binds lots // of names in different orders. It's fine for reasonable - // cases, though. + // cases, though, and the peephole optimizer will ensure + // that the final code is as efficient as possible. assert(istores < icontrol); Py_ssize_t rotations = istores + 1; // Perform the same rotation on pc->stores: @@ -6312,9 +6789,10 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) // rotated = pc_stores[:rotations] // del pc_stores[:rotations] // pc_stores[icontrol-istores:icontrol-istores] = rotated - // Do the same thing to the stack, using several ROT_Ns: + // Do the same thing to the stack, using several + // rotations: while (rotations--) { - if (!compiler_addop_i(c, ROT_N, icontrol + 1)) { + if (pattern_helper_rotate(c, LOC(alt), icontrol + 1) < 0) { goto error; } } @@ -6322,9 +6800,8 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) } } assert(control); - if (!compiler_addop_j(c, JUMP_FORWARD, end) || - !compiler_next_block(c) || - !emit_and_reset_fail_pop(c, pc)) + if (cfg_builder_addop_j(CFG_BUILDER(c), LOC(alt), JUMP, end) < 0 || + emit_and_reset_fail_pop(c, LOC(alt), pc) < 0) { goto error; } @@ -6335,12 +6812,14 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) // Need to NULL this for the PyObject_Free call in the error block. old_pc.fail_pop = NULL; // No match. Pop the remaining copy of the subject and fail: - if (!compiler_addop(c, POP_TOP) || !jump_to_fail_pop(c, pc, JUMP_FORWARD)) { + if (cfg_builder_addop_noarg(CFG_BUILDER(c), POP_TOP, LOC(p)) < 0 || + jump_to_fail_pop(c, LOC(p), pc, JUMP) < 0) { goto error; } - compiler_use_next_block(c, end); + + USE_LABEL(c, end); Py_ssize_t nstores = PyList_GET_SIZE(control); - // There's a bunch of stuff on the stack between any where the new stores + // There's a bunch of stuff on the stack between where the new stores // are and where they need to be: // - The other stores. // - A copy of the subject. @@ -6349,7 +6828,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) Py_ssize_t nrots = nstores + 1 + pc->on_top + PyList_GET_SIZE(pc->stores); for (Py_ssize_t i = 0; i < nstores; i++) { // Rotate this capture to its proper place on the stack: - if (!compiler_addop_i(c, ROT_N, nrots)) { + if (pattern_helper_rotate(c, LOC(p), nrots) < 0) { goto error; } // Update the list of previous stores with this new name, checking for @@ -6360,7 +6839,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) goto error; } if (dupe) { - compiler_error_duplicate_store(c, name); + compiler_error_duplicate_store(c, LOC(p), name); goto error; } if (PyList_Append(pc->stores, name)) { @@ -6371,20 +6850,21 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) Py_DECREF(control); // NOTE: Returning macros are safe again. // Pop the copy of the subject: - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, LOC(p), POP_TOP); + return SUCCESS; diff: - compiler_error(c, "alternative patterns bind different names"); + compiler_error(c, LOC(p), "alternative patterns bind different names"); error: PyObject_Free(old_pc.fail_pop); Py_DECREF(old_pc.stores); Py_XDECREF(control); - return 0; + return ERROR; } static int -compiler_pattern_sequence(struct compiler *c, pattern_ty p, pattern_context *pc) +compiler_pattern_sequence(struct compiler *c, pattern_ty p, + pattern_context *pc) { assert(p->kind == MatchSequence_kind); asdl_pattern_seq *patterns = p->v.MatchSequence.patterns; @@ -6398,7 +6878,7 @@ compiler_pattern_sequence(struct compiler *c, pattern_ty p, pattern_context *pc) if (pattern->kind == MatchStar_kind) { if (star >= 0) { const char *e = "multiple starred names in sequence pattern"; - return compiler_error(c, e); + return compiler_error(c, LOC(p), e); } star_wildcard = WILDCARD_STAR_CHECK(pattern); only_wildcard &= star_wildcard; @@ -6409,35 +6889,35 @@ compiler_pattern_sequence(struct compiler *c, pattern_ty p, pattern_context *pc) } // We need to keep the subject on top during the sequence and length checks: pc->on_top++; - ADDOP(c, MATCH_SEQUENCE); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); + ADDOP(c, LOC(p), MATCH_SEQUENCE); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); if (star < 0) { // No star: len(subject) == size - ADDOP(c, GET_LEN); - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size)); - ADDOP_COMPARE(c, Eq); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); + ADDOP(c, LOC(p), GET_LEN); + ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size)); + ADDOP_COMPARE(c, LOC(p), Eq); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); } else if (size > 1) { // Star: len(subject) >= size - 1 - ADDOP(c, GET_LEN); - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size - 1)); - ADDOP_COMPARE(c, GtE); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); + ADDOP(c, LOC(p), GET_LEN); + ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size - 1)); + ADDOP_COMPARE(c, LOC(p), GtE); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); } // Whatever comes next should consume the subject: pc->on_top--; if (only_wildcard) { // Patterns like: [] / [_] / [_, _] / [*_] / [_, *_] / [_, _, *_] / etc. - ADDOP(c, POP_TOP); + ADDOP(c, LOC(p), POP_TOP); } else if (star_wildcard) { - RETURN_IF_FALSE(pattern_helper_sequence_subscr(c, patterns, star, pc)); + RETURN_IF_ERROR(pattern_helper_sequence_subscr(c, LOC(p), patterns, star, pc)); } else { - RETURN_IF_FALSE(pattern_helper_sequence_unpack(c, patterns, star, pc)); + RETURN_IF_ERROR(pattern_helper_sequence_unpack(c, LOC(p), patterns, star, pc)); } - return 1; + return SUCCESS; } static int @@ -6447,28 +6927,27 @@ compiler_pattern_value(struct compiler *c, pattern_ty p, pattern_context *pc) expr_ty value = p->v.MatchValue.value; if (!MATCH_VALUE_EXPR(value)) { const char *e = "patterns may only match literals and attribute lookups"; - return compiler_error(c, e); + return compiler_error(c, LOC(p), e); } VISIT(c, expr, value); - ADDOP_COMPARE(c, Eq); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); - return 1; + ADDOP_COMPARE(c, LOC(p), Eq); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); + return SUCCESS; } static int compiler_pattern_singleton(struct compiler *c, pattern_ty p, pattern_context *pc) { assert(p->kind == MatchSingleton_kind); - ADDOP_LOAD_CONST(c, p->v.MatchSingleton.value); - ADDOP_COMPARE(c, Is); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); - return 1; + ADDOP_LOAD_CONST(c, LOC(p), p->v.MatchSingleton.value); + ADDOP_COMPARE(c, LOC(p), Is); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); + return SUCCESS; } static int compiler_pattern(struct compiler *c, pattern_ty p, pattern_context *pc) { - SET_LOC(c, p); switch (p->kind) { case MatchValue_kind: return compiler_pattern_value(c, p, pc); @@ -6490,85 +6969,84 @@ compiler_pattern(struct compiler *c, pattern_ty p, pattern_context *pc) // AST validator shouldn't let this happen, but if it does, // just fail, don't crash out of the interpreter const char *e = "invalid match pattern node in AST (kind=%d)"; - return compiler_error(c, e, p->kind); + return compiler_error(c, LOC(p), e, p->kind); } static int compiler_match_inner(struct compiler *c, stmt_ty s, pattern_context *pc) { VISIT(c, expr, s->v.Match.subject); - basicblock *end; - RETURN_IF_FALSE(end = compiler_new_block(c)); + NEW_JUMP_TARGET_LABEL(c, end); Py_ssize_t cases = asdl_seq_LEN(s->v.Match.cases); assert(cases > 0); match_case_ty m = asdl_seq_GET(s->v.Match.cases, cases - 1); int has_default = WILDCARD_CHECK(m->pattern) && 1 < cases; for (Py_ssize_t i = 0; i < cases - has_default; i++) { m = asdl_seq_GET(s->v.Match.cases, i); - SET_LOC(c, m->pattern); // Only copy the subject if we're *not* on the last case: if (i != cases - has_default - 1) { - ADDOP(c, DUP_TOP); + ADDOP_I(c, LOC(m->pattern), COPY, 1); + } + pc->stores = PyList_New(0); + if (pc->stores == NULL) { + return ERROR; } - RETURN_IF_FALSE(pc->stores = PyList_New(0)); // Irrefutable cases must be either guarded, last, or both: pc->allow_irrefutable = m->guard != NULL || i == cases - 1; pc->fail_pop = NULL; pc->fail_pop_size = 0; pc->on_top = 0; // NOTE: Can't use returning macros here (they'll leak pc->stores)! - if (!compiler_pattern(c, m->pattern, pc)) { + if (compiler_pattern(c, m->pattern, pc) < 0) { Py_DECREF(pc->stores); - return 0; + return ERROR; } assert(!pc->on_top); // It's a match! Store all of the captured names (they're on the stack). Py_ssize_t nstores = PyList_GET_SIZE(pc->stores); for (Py_ssize_t n = 0; n < nstores; n++) { PyObject *name = PyList_GET_ITEM(pc->stores, n); - if (!compiler_nameop(c, name, Store)) { + if (compiler_nameop(c, LOC(m->pattern), name, Store) < 0) { Py_DECREF(pc->stores); - return 0; + return ERROR; } } Py_DECREF(pc->stores); // NOTE: Returning macros are safe again. if (m->guard) { - RETURN_IF_FALSE(ensure_fail_pop(c, pc, 0)); - RETURN_IF_FALSE(compiler_jump_if(c, m->guard, pc->fail_pop[0], 0)); + RETURN_IF_ERROR(ensure_fail_pop(c, pc, 0)); + RETURN_IF_ERROR(compiler_jump_if(c, LOC(m->pattern), m->guard, pc->fail_pop[0], 0)); } // Success! Pop the subject off, we're done with it: if (i != cases - has_default - 1) { - ADDOP(c, POP_TOP); + ADDOP(c, LOC(m->pattern), POP_TOP); } VISIT_SEQ(c, stmt, m->body); - ADDOP_JUMP(c, JUMP_FORWARD, end); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); // If the pattern fails to match, we want the line number of the // cleanup to be associated with the failed pattern, not the last line // of the body - SET_LOC(c, m->pattern); - RETURN_IF_FALSE(emit_and_reset_fail_pop(c, pc)); + RETURN_IF_ERROR(emit_and_reset_fail_pop(c, LOC(m->pattern), pc)); } if (has_default) { // A trailing "case _" is common, and lets us save a bit of redundant // pushing and popping in the loop above: m = asdl_seq_GET(s->v.Match.cases, cases - 1); - SET_LOC(c, m->pattern); if (cases == 1) { // No matches. Done with the subject: - ADDOP(c, POP_TOP); + ADDOP(c, LOC(m->pattern), POP_TOP); } else { // Show line coverage for default case (it doesn't create bytecode) - ADDOP(c, NOP); + ADDOP(c, LOC(m->pattern), NOP); } if (m->guard) { - RETURN_IF_FALSE(compiler_jump_if(c, m->guard, end, 0)); + RETURN_IF_ERROR(compiler_jump_if(c, LOC(m->pattern), m->guard, end, 0)); } VISIT_SEQ(c, stmt, m->body); } - compiler_use_next_block(c, end); - return 1; + USE_LABEL(c, end); + return SUCCESS; } static int @@ -6584,35 +7062,35 @@ compiler_match(struct compiler *c, stmt_ty s) #undef WILDCARD_CHECK #undef WILDCARD_STAR_CHECK + /* End of the compiler section, beginning of the assembler section */ -/* do depth-first search of basic block graph, starting with block. - post records the block indices in post-order. - - XXX must handle implicit jumps from one block to next -*/ struct assembler { PyObject *a_bytecode; /* bytes containing bytecode */ int a_offset; /* offset into bytecode */ - int a_nblocks; /* number of reachable blocks */ - PyObject *a_lnotab; /* bytes containing lnotab */ - PyObject* a_enotab; /* bytes containing enotab */ - PyObject* a_cnotab; /* bytes containing cnotab */ - int a_lnotab_off; /* offset into lnotab */ - int a_enotab_off; /* offset into enotab */ - int a_cnotab_off; /* offset into cnotab */ PyObject *a_except_table; /* bytes containing exception table */ int a_except_table_off; /* offset into exception table */ - int a_prevlineno; /* lineno of last emitted line in line table */ - int a_prev_end_lineno; /* end_lineno of last emitted line in line table */ + /* Location Info */ int a_lineno; /* lineno of last emitted instruction */ - int a_end_lineno; /* end_lineno of last emitted instruction */ - int a_lineno_start; /* bytecode start offset of current lineno */ - int a_end_lineno_start; /* bytecode start offset of current end_lineno */ - basicblock *a_entry; + PyObject* a_linetable; /* bytes containing location info */ + int a_location_off; /* offset of last written location info frame */ }; +static basicblock** +make_cfg_traversal_stack(basicblock *entryblock) { + int nblocks = 0; + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + b->b_visited = 0; + nblocks++; + } + basicblock **stack = (basicblock **)PyMem_Malloc(sizeof(basicblock *) * nblocks); + if (!stack) { + PyErr_NoMemory(); + } + return stack; +} + Py_LOCAL_INLINE(void) stackdepth_push(basicblock ***sp, basicblock *b, int depth) { @@ -6628,31 +7106,26 @@ stackdepth_push(basicblock ***sp, basicblock *b, int depth) * cycles in the flow graph have no net effect on the stack depth. */ static int -stackdepth(struct compiler *c) +stackdepth(basicblock *entryblock, int code_flags) { - basicblock *b, *entryblock = NULL; - basicblock **stack, **sp; - int nblocks = 0, maxdepth = 0; - for (b = c->u->u_blocks; b != NULL; b = b->b_list) { + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { b->b_startdepth = INT_MIN; - entryblock = b; - nblocks++; } - assert(entryblock!= NULL); - stack = (basicblock **)PyObject_Malloc(sizeof(basicblock *) * nblocks); + basicblock **stack = make_cfg_traversal_stack(entryblock); if (!stack) { - PyErr_NoMemory(); return -1; } - sp = stack; - if (c->u->u_ste->ste_generator || c->u->u_ste->ste_coroutine) { + int maxdepth = 0; + basicblock **sp = stack; + if (code_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) { stackdepth_push(&sp, entryblock, 1); } else { stackdepth_push(&sp, entryblock, 0); } + while (sp != stack) { - b = *--sp; + basicblock *b = *--sp; int depth = b->b_startdepth; assert(depth >= 0); basicblock *next = b->b_next; @@ -6666,27 +7139,24 @@ stackdepth(struct compiler *c) return -1; } int new_depth = depth + effect; + assert(new_depth >= 0); /* invalid code or bug in stackdepth() */ if (new_depth > maxdepth) { maxdepth = new_depth; } - assert(depth >= 0); /* invalid code or bug in stackdepth() */ - if (is_jump(instr)) { + if (HAS_TARGET(instr->i_opcode)) { effect = stack_effect(instr->i_opcode, instr->i_oparg, 1); assert(effect != PY_INVALID_STACK_EFFECT); int target_depth = depth + effect; + assert(target_depth >= 0); /* invalid code or bug in stackdepth() */ if (target_depth > maxdepth) { maxdepth = target_depth; } - assert(target_depth >= 0); /* invalid code or bug in stackdepth() */ stackdepth_push(&sp, instr->i_target, target_depth); } depth = new_depth; - if (instr->i_opcode == JUMP_ABSOLUTE || - instr->i_opcode == JUMP_FORWARD || - instr->i_opcode == RETURN_VALUE || - instr->i_opcode == RAISE_VARARGS || - instr->i_opcode == RERAISE || - instr->i_opcode == POP_EXCEPT_AND_RERAISE) + assert(!IS_ASSEMBLER_OPCODE(instr->i_opcode)); + if (IS_UNCONDITIONAL_JUMP_OPCODE(instr->i_opcode) || + IS_SCOPE_EXIT_OPCODE(instr->i_opcode)) { /* remaining code is dead */ next = NULL; @@ -6694,104 +7164,58 @@ stackdepth(struct compiler *c) } } if (next != NULL) { - assert(b->b_nofallthrough == 0); + assert(BB_HAS_FALLTHROUGH(b)); stackdepth_push(&sp, next, depth); } } - PyObject_Free(stack); + PyMem_Free(stack); return maxdepth; } static int -assemble_init(struct assembler *a, int nblocks, int firstlineno) +assemble_init(struct assembler *a, int firstlineno) { memset(a, 0, sizeof(struct assembler)); - a->a_prevlineno = a->a_lineno = firstlineno; - a->a_prev_end_lineno = a->a_end_lineno = firstlineno; - a->a_lnotab = NULL; - a->a_enotab = NULL; - a->a_cnotab = NULL; - a->a_cnotab_off = 0; + a->a_lineno = firstlineno; + a->a_linetable = NULL; + a->a_location_off = 0; a->a_except_table = NULL; a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE); if (a->a_bytecode == NULL) { goto error; } - a->a_lnotab = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); - if (a->a_lnotab == NULL) { - goto error; - } - a->a_enotab = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); - if (a->a_enotab == NULL) { - goto error; - } - a->a_cnotab = PyBytes_FromStringAndSize(NULL, DEFAULT_CNOTAB_SIZE); - if (a->a_cnotab == NULL) { + a->a_linetable = PyBytes_FromStringAndSize(NULL, DEFAULT_CNOTAB_SIZE); + if (a->a_linetable == NULL) { goto error; } a->a_except_table = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); if (a->a_except_table == NULL) { goto error; } - if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) { - PyErr_NoMemory(); - goto error; - } - return 1; + return 0; error: Py_XDECREF(a->a_bytecode); - Py_XDECREF(a->a_lnotab); - Py_XDECREF(a->a_enotab); - Py_XDECREF(a->a_cnotab); + Py_XDECREF(a->a_linetable); Py_XDECREF(a->a_except_table); - return 0; + return -1; } static void assemble_free(struct assembler *a) { Py_XDECREF(a->a_bytecode); - Py_XDECREF(a->a_lnotab); - Py_XDECREF(a->a_enotab); - Py_XDECREF(a->a_cnotab); + Py_XDECREF(a->a_linetable); Py_XDECREF(a->a_except_table); } static int blocksize(basicblock *b) { - int i; int size = 0; - - for (i = 0; i < b->b_iused; i++) - size += instrsize(b->b_instr[i].i_oparg); - return size; -} - -static int -assemble_emit_table_pair(struct assembler* a, PyObject** table, int* offset, - int left, int right) -{ - Py_ssize_t len = PyBytes_GET_SIZE(*table); - if (*offset + 2 >= len) { - if (_PyBytes_Resize(table, len * 2) < 0) - return 0; + for (int i = 0; i < b->b_iused; i++) { + size += instr_size(&b->b_instr[i]); } - unsigned char* table_entry = (unsigned char*)PyBytes_AS_STRING(*table); - - table_entry += *offset; - *offset += 2; - - *table_entry++ = left; - *table_entry++ = right; - return 1; -} - -static int -is_block_push(struct instr *instr) -{ - int opcode = instr->i_opcode; - return opcode == SETUP_FINALLY || opcode == SETUP_WITH || opcode == SETUP_CLEANUP; + return size; } static basicblock * @@ -6841,15 +7265,9 @@ copy_except_stack(ExceptStack *stack) { } static int -label_exception_targets(basicblock *entry) { - int nblocks = 0; - for (basicblock *b = entry; b != NULL; b = b->b_next) { - b->b_visited = 0; - nblocks++; - } - basicblock **todo_stack = PyMem_Malloc(sizeof(basicblock *)*nblocks); +label_exception_targets(basicblock *entryblock) { + basicblock **todo_stack = make_cfg_traversal_stack(entryblock); if (todo_stack == NULL) { - PyErr_NoMemory(); return -1; } ExceptStack *except_stack = make_except_stack(); @@ -6859,9 +7277,9 @@ label_exception_targets(basicblock *entry) { return -1; } except_stack->depth = 0; - todo_stack[0] = entry; - entry->b_visited = 1; - entry->b_exceptstack = except_stack; + todo_stack[0] = entryblock; + entryblock->b_visited = 1; + entryblock->b_exceptstack = except_stack; basicblock **todo = &todo_stack[1]; basicblock *handler = NULL; while (todo > todo_stack) { @@ -6894,7 +7312,7 @@ label_exception_targets(basicblock *entry) { instr->i_except = handler; assert(i == b->b_iused -1); if (!instr->i_target->b_visited) { - if (b->b_nofallthrough == 0) { + if (BB_HAS_FALLTHROUGH(b)) { ExceptStack *copy = copy_except_stack(except_stack); if (copy == NULL) { goto error; @@ -6911,10 +7329,13 @@ label_exception_targets(basicblock *entry) { } } else { + if (instr->i_opcode == YIELD_VALUE) { + instr->i_oparg = except_stack->depth; + } instr->i_except = handler; } } - if (b->b_nofallthrough == 0 && !b->b_next->b_visited) { + if (BB_HAS_FALLTHROUGH(b) && !b->b_next->b_visited) { assert(except_stack != NULL); b->b_next->b_exceptstack = except_stack; todo[0] = b->b_next; @@ -6926,7 +7347,7 @@ label_exception_targets(basicblock *entry) { } } #ifdef Py_DEBUG - for (basicblock *b = entry; b != NULL; b = b->b_next) { + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { assert(b->b_exceptstack == NULL); } #endif @@ -6939,16 +7360,198 @@ error: } +static int +mark_except_handlers(basicblock *entryblock) { +#ifndef NDEBUG + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + assert(!b->b_except_handler); + } +#endif + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (int i=0; i < b->b_iused; i++) { + struct instr *instr = &b->b_instr[i]; + if (is_block_push(instr)) { + instr->i_target->b_except_handler = 1; + } + } + } + return 0; +} + +static int +mark_warm(basicblock *entryblock) { + basicblock **stack = make_cfg_traversal_stack(entryblock); + if (stack == NULL) { + return -1; + } + basicblock **sp = stack; + + *sp++ = entryblock; + entryblock->b_visited = 1; + while (sp > stack) { + basicblock *b = *(--sp); + assert(!b->b_except_handler); + b->b_warm = 1; + basicblock *next = b->b_next; + if (next && BB_HAS_FALLTHROUGH(b) && !next->b_visited) { + *sp++ = next; + next->b_visited = 1; + } + for (int i=0; i < b->b_iused; i++) { + struct instr *instr = &b->b_instr[i]; + if (is_jump(instr) && !instr->i_target->b_visited) { + *sp++ = instr->i_target; + instr->i_target->b_visited = 1; + } + } + } + PyMem_Free(stack); + return 0; +} + +static int +mark_cold(basicblock *entryblock) { + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + assert(!b->b_cold && !b->b_warm); + } + if (mark_warm(entryblock) < 0) { + return -1; + } + + basicblock **stack = make_cfg_traversal_stack(entryblock); + if (stack == NULL) { + return -1; + } + + basicblock **sp = stack; + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + if (b->b_except_handler) { + assert(!b->b_warm); + *sp++ = b; + b->b_visited = 1; + } + } + + while (sp > stack) { + basicblock *b = *(--sp); + b->b_cold = 1; + basicblock *next = b->b_next; + if (next && BB_HAS_FALLTHROUGH(b)) { + if (!next->b_warm && !next->b_visited) { + *sp++ = next; + next->b_visited = 1; + } + } + for (int i = 0; i < b->b_iused; i++) { + struct instr *instr = &b->b_instr[i]; + if (is_jump(instr)) { + assert(i == b->b_iused - 1); + basicblock *target = b->b_instr[i].i_target; + if (!target->b_warm && !target->b_visited) { + *sp++ = target; + target->b_visited = 1; + } + } + } + } + PyMem_Free(stack); + return 0; +} + +static int +remove_redundant_jumps(cfg_builder *g); + +static int +push_cold_blocks_to_end(cfg_builder *g, int code_flags) { + basicblock *entryblock = g->g_entryblock; + if (entryblock->b_next == NULL) { + /* single basicblock, no need to reorder */ + return 0; + } + if (mark_cold(entryblock) < 0) { + return -1; + } + + /* If we have a cold block with fallthrough to a warm block, add */ + /* an explicit jump instead of fallthrough */ + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + if (b->b_cold && BB_HAS_FALLTHROUGH(b) && b->b_next && b->b_next->b_warm) { + basicblock *explicit_jump = cfg_builder_new_block(g); + if (explicit_jump == NULL) { + return -1; + } + basicblock_addop(explicit_jump, JUMP, b->b_next->b_label, NO_LOCATION); + explicit_jump->b_cold = 1; + explicit_jump->b_next = b->b_next; + b->b_next = explicit_jump; + + /* set target */ + struct instr *last = basicblock_last_instr(explicit_jump); + last->i_target = explicit_jump->b_next; + } + } + + assert(!entryblock->b_cold); /* First block can't be cold */ + basicblock *cold_blocks = NULL; + basicblock *cold_blocks_tail = NULL; + + basicblock *b = entryblock; + while(b->b_next) { + assert(!b->b_cold); + while (b->b_next && !b->b_next->b_cold) { + b = b->b_next; + } + if (b->b_next == NULL) { + /* no more cold blocks */ + break; + } + + /* b->b_next is the beginning of a cold streak */ + assert(!b->b_cold && b->b_next->b_cold); + + basicblock *b_end = b->b_next; + while (b_end->b_next && b_end->b_next->b_cold) { + b_end = b_end->b_next; + } + + /* b_end is the end of the cold streak */ + assert(b_end && b_end->b_cold); + assert(b_end->b_next == NULL || !b_end->b_next->b_cold); + + if (cold_blocks == NULL) { + cold_blocks = b->b_next; + } + else { + cold_blocks_tail->b_next = b->b_next; + } + cold_blocks_tail = b_end; + b->b_next = b_end->b_next; + b_end->b_next = NULL; + } + assert(b != NULL && b->b_next == NULL); + b->b_next = cold_blocks; + + if (cold_blocks != NULL) { + if (remove_redundant_jumps(g) < 0) { + return -1; + } + } + return 0; +} + static void -convert_exception_handlers_to_nops(basicblock *entry) { - for (basicblock *b = entry; b != NULL; b = b->b_next) { +convert_exception_handlers_to_nops(basicblock *entryblock) { + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { for (int i = 0; i < b->b_iused; i++) { struct instr *instr = &b->b_instr[i]; if (is_block_push(instr) || instr->i_opcode == POP_BLOCK) { - instr->i_opcode = NOP; + INSTR_SET_OP0(instr, NOP); } } } + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + remove_redundant_nops(b); + } } static inline void @@ -6991,160 +7594,206 @@ assemble_emit_exception_table_entry(struct assembler *a, int start, int end, bas { Py_ssize_t len = PyBytes_GET_SIZE(a->a_except_table); if (a->a_except_table_off + MAX_SIZE_OF_ENTRY >= len) { - if (_PyBytes_Resize(&a->a_except_table, len * 2) < 0) - return 0; + if (_PyBytes_Resize(&a->a_except_table, len * 2) < 0) { + return -1; + } } int size = end-start; assert(end > start); int target = handler->b_offset; - int depth = handler->b_preserve_lasti ? handler->b_startdepth-4 : handler->b_startdepth-3; + int depth = handler->b_startdepth - 1; + if (handler->b_preserve_lasti) { + depth -= 1; + } assert(depth >= 0); int depth_lasti = (depth<<1) | handler->b_preserve_lasti; assemble_emit_exception_table_item(a, start, (1<<7)); assemble_emit_exception_table_item(a, size, 0); assemble_emit_exception_table_item(a, target, 0); assemble_emit_exception_table_item(a, depth_lasti, 0); - return 1; + return 0; } static int -assemble_exception_table(struct assembler *a) +assemble_exception_table(struct assembler *a, basicblock *entryblock) { basicblock *b; int ioffset = 0; basicblock *handler = NULL; int start = -1; - for (b = a->a_entry; b != NULL; b = b->b_next) { + for (b = entryblock; b != NULL; b = b->b_next) { ioffset = b->b_offset; for (int i = 0; i < b->b_iused; i++) { struct instr *instr = &b->b_instr[i]; if (instr->i_except != handler) { if (handler != NULL) { - RETURN_IF_FALSE(assemble_emit_exception_table_entry(a, start, ioffset, handler)); + if (assemble_emit_exception_table_entry(a, start, ioffset, handler) < 0) { + return -1; + } } start = ioffset; handler = instr->i_except; } - ioffset += instrsize(instr->i_oparg); + ioffset += instr_size(instr); } } if (handler != NULL) { - RETURN_IF_FALSE(assemble_emit_exception_table_entry(a, start, ioffset, handler)); - } - return 1; -} - -/* Appends a range to the end of the line number table. See - * Objects/lnotab_notes.txt for the description of the line number table. */ - -static int -assemble_line_range(struct assembler* a, int current, PyObject** table, - int* prev, int* start, int* offset) -{ - int ldelta, bdelta; - bdelta = (a->a_offset - *start) * sizeof(_Py_CODEUNIT); - if (bdelta == 0) { - return 1; - } - if (current < 0) { - ldelta = -128; - } - else { - ldelta = current - *prev; - *prev = current; - while (ldelta > 127) { - if (!assemble_emit_table_pair(a, table, offset, 0, 127)) { - return 0; - } - ldelta -= 127; - } - while (ldelta < -127) { - if (!assemble_emit_table_pair(a, table, offset, 0, -127)) { - return 0; - } - ldelta += 127; + if (assemble_emit_exception_table_entry(a, start, ioffset, handler) < 0) { + return -1; } } - assert(-128 <= ldelta && ldelta < 128); - while (bdelta > 254) { - if (!assemble_emit_table_pair(a, table, offset, 254, ldelta)) { - return 0; + return 0; +} + +/* Code location emitting code. See locations.md for a description of the format. */ + +#define MSB 0x80 + +static void +write_location_byte(struct assembler* a, int val) +{ + PyBytes_AS_STRING(a->a_linetable)[a->a_location_off] = val&255; + a->a_location_off++; +} + + +static uint8_t * +location_pointer(struct assembler* a) +{ + return (uint8_t *)PyBytes_AS_STRING(a->a_linetable) + + a->a_location_off; +} + +static void +write_location_first_byte(struct assembler* a, int code, int length) +{ + a->a_location_off += write_location_entry_start( + location_pointer(a), code, length); +} + +static void +write_location_varint(struct assembler* a, unsigned int val) +{ + uint8_t *ptr = location_pointer(a); + a->a_location_off += write_varint(ptr, val); +} + + +static void +write_location_signed_varint(struct assembler* a, int val) +{ + uint8_t *ptr = location_pointer(a); + a->a_location_off += write_signed_varint(ptr, val); +} + +static void +write_location_info_short_form(struct assembler* a, int length, int column, int end_column) +{ + assert(length > 0 && length <= 8); + int column_low_bits = column & 7; + int column_group = column >> 3; + assert(column < 80); + assert(end_column >= column); + assert(end_column - column < 16); + write_location_first_byte(a, PY_CODE_LOCATION_INFO_SHORT0 + column_group, length); + write_location_byte(a, (column_low_bits << 4) | (end_column - column)); +} + +static void +write_location_info_oneline_form(struct assembler* a, int length, int line_delta, int column, int end_column) +{ + assert(length > 0 && length <= 8); + assert(line_delta >= 0 && line_delta < 3); + assert(column < 128); + assert(end_column < 128); + write_location_first_byte(a, PY_CODE_LOCATION_INFO_ONE_LINE0 + line_delta, length); + write_location_byte(a, column); + write_location_byte(a, end_column); +} + +static void +write_location_info_long_form(struct assembler* a, location loc, int length) +{ + assert(length > 0 && length <= 8); + write_location_first_byte(a, PY_CODE_LOCATION_INFO_LONG, length); + write_location_signed_varint(a, loc.lineno - a->a_lineno); + assert(loc.end_lineno >= loc.lineno); + write_location_varint(a, loc.end_lineno - loc.lineno); + write_location_varint(a, loc.col_offset + 1); + write_location_varint(a, loc.end_col_offset + 1); +} + +static void +write_location_info_none(struct assembler* a, int length) +{ + write_location_first_byte(a, PY_CODE_LOCATION_INFO_NONE, length); +} + +static void +write_location_info_no_column(struct assembler* a, int length, int line_delta) +{ + write_location_first_byte(a, PY_CODE_LOCATION_INFO_NO_COLUMNS, length); + write_location_signed_varint(a, line_delta); +} + +#define THEORETICAL_MAX_ENTRY_SIZE 25 /* 1 + 6 + 6 + 6 + 6 */ + +static int +write_location_info_entry(struct assembler* a, location loc, int isize) +{ + Py_ssize_t len = PyBytes_GET_SIZE(a->a_linetable); + if (a->a_location_off + THEORETICAL_MAX_ENTRY_SIZE >= len) { + assert(len > THEORETICAL_MAX_ENTRY_SIZE); + if (_PyBytes_Resize(&a->a_linetable, len*2) < 0) { + return -1; } - ldelta = current < 0 ? -128 : 0; - bdelta -= 254; } - if (!assemble_emit_table_pair(a, table, offset, bdelta, ldelta)) { + if (loc.lineno < 0) { + write_location_info_none(a, isize); return 0; } - *start = a->a_offset; - return 1; -} - -static int -assemble_start_line_range(struct assembler* a) { - return assemble_line_range(a, a->a_lineno, &a->a_lnotab, - &a->a_prevlineno, &a->a_lineno_start, &a->a_lnotab_off); -} - -static int -assemble_end_line_range(struct assembler* a) { - return assemble_line_range(a, a->a_end_lineno, &a->a_enotab, - &a->a_prev_end_lineno, &a->a_end_lineno_start, &a->a_enotab_off); -} - -static int -assemble_lnotab(struct assembler* a, struct instr* i) -{ - if (i->i_lineno == a->a_lineno) { - return 1; - } - if (!assemble_start_line_range(a)) { - return 0; - } - a->a_lineno = i->i_lineno; - return 1; -} - -static int -assemble_enotab(struct assembler* a, struct instr* i) -{ - if (i->i_end_lineno == a->a_end_lineno) { - return 1; - } - if (!assemble_end_line_range(a)) { - return 0; - } - a->a_end_lineno = i->i_end_lineno; - return 1; -} - -static int -assemble_cnotab(struct assembler* a, struct instr* i, int instr_size) -{ - Py_ssize_t len = PyBytes_GET_SIZE(a->a_cnotab); - int difference = instr_size * 2; - if (a->a_cnotab_off + difference >= len) { - if (_PyBytes_Resize(&a->a_cnotab, difference + (len * 2)) < 0) { + int line_delta = loc.lineno - a->a_lineno; + int column = loc.col_offset; + int end_column = loc.end_col_offset; + assert(column >= -1); + assert(end_column >= -1); + if (column < 0 || end_column < 0) { + if (loc.end_lineno == loc.lineno || loc.end_lineno == -1) { + write_location_info_no_column(a, isize, line_delta); + a->a_lineno = loc.lineno; return 0; } } - - unsigned char* cnotab = (unsigned char*)PyBytes_AS_STRING(a->a_cnotab); - cnotab += a->a_cnotab_off; - a->a_cnotab_off += difference; - - for (int j = 0; j < instr_size; j++) { - if (i->i_col_offset > 255 || i->i_end_col_offset > 255) { - *cnotab++ = 0; - *cnotab++ = 0; - continue; + else if (loc.end_lineno == loc.lineno) { + if (line_delta == 0 && column < 80 && end_column - column < 16 && end_column >= column) { + write_location_info_short_form(a, isize, column, end_column); + return 0; + } + if (line_delta >= 0 && line_delta < 3 && column < 128 && end_column < 128) { + write_location_info_oneline_form(a, isize, line_delta, column, end_column); + a->a_lineno = loc.lineno; + return 0; } - *cnotab++ = i->i_col_offset + 1; - *cnotab++ = i->i_end_col_offset + 1; } - return 1; + write_location_info_long_form(a, loc, isize); + a->a_lineno = loc.lineno; + return 0; } +static int +assemble_emit_location(struct assembler* a, location loc, int isize) +{ + if (isize == 0) { + return 0; + } + while (isize > 8) { + if (write_location_info_entry(a, loc, 8)) { + return -1; + } + isize -= 8; + } + return write_location_info_entry(a, loc, isize); +} /* assemble_emit() Extend the bytecode with a new instruction. @@ -7154,75 +7803,131 @@ assemble_cnotab(struct assembler* a, struct instr* i, int instr_size) static int assemble_emit(struct assembler *a, struct instr *i) { - int size, arg = 0; Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode); _Py_CODEUNIT *code; - arg = i->i_oparg; - size = instrsize(arg); - if (i->i_lineno && !assemble_lnotab(a, i)) { - return 0; - } - if (!assemble_enotab(a, i)) { - return 0; - } - if (!assemble_cnotab(a, i, size)) { - return 0; - } + int size = instr_size(i); if (a->a_offset + size >= len / (int)sizeof(_Py_CODEUNIT)) { - if (len > PY_SSIZE_T_MAX / 2) - return 0; - if (_PyBytes_Resize(&a->a_bytecode, len * 2) < 0) - return 0; + if (len > PY_SSIZE_T_MAX / 2) { + return -1; + } + if (_PyBytes_Resize(&a->a_bytecode, len * 2) < 0) { + return -1; + } } code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset; a->a_offset += size; - write_op_arg(code, i->i_opcode, arg, size); - return 1; + write_instr(code, i, size); + return 0; } -static void -normalize_jumps(struct assembler *a) +static int +normalize_jumps_in_block(cfg_builder *g, basicblock *b) { + struct instr *last = basicblock_last_instr(b); + if (last == NULL || !is_jump(last)) { + return 0; + } + assert(!IS_ASSEMBLER_OPCODE(last->i_opcode)); + bool is_forward = last->i_target->b_visited == 0; + switch(last->i_opcode) { + case JUMP: + last->i_opcode = is_forward ? JUMP_FORWARD : JUMP_BACKWARD; + return 0; + case JUMP_NO_INTERRUPT: + last->i_opcode = is_forward ? + JUMP_FORWARD : JUMP_BACKWARD_NO_INTERRUPT; + return 0; + } + int reversed_opcode = 0; + switch(last->i_opcode) { + case POP_JUMP_IF_NOT_NONE: + reversed_opcode = POP_JUMP_IF_NONE; + break; + case POP_JUMP_IF_NONE: + reversed_opcode = POP_JUMP_IF_NOT_NONE; + break; + case POP_JUMP_IF_FALSE: + reversed_opcode = POP_JUMP_IF_TRUE; + break; + case POP_JUMP_IF_TRUE: + reversed_opcode = POP_JUMP_IF_FALSE; + break; + case JUMP_IF_TRUE_OR_POP: + case JUMP_IF_FALSE_OR_POP: + if (!is_forward) { + /* As far as we can tell, the compiler never emits + * these jumps with a backwards target. If/when this + * exception is raised, we have found a use case for + * a backwards version of this jump (or to replace + * it with the sequence (COPY 1, POP_JUMP_IF_T/F, POP) + */ + PyErr_Format(PyExc_SystemError, + "unexpected %s jumping backwards", + last->i_opcode == JUMP_IF_TRUE_OR_POP ? + "JUMP_IF_TRUE_OR_POP" : "JUMP_IF_FALSE_OR_POP"); + } + return 0; + } + if (is_forward) { + return 0; + } + + /* transform 'conditional jump T' to + * 'reversed_jump b_next' followed by 'jump_backwards T' + */ + + basicblock *target = last->i_target; + basicblock *backwards_jump = cfg_builder_new_block(g); + if (backwards_jump == NULL) { + return -1; + } + basicblock_addop(backwards_jump, JUMP, target->b_label, NO_LOCATION); + backwards_jump->b_instr[0].i_target = target; + last->i_opcode = reversed_opcode; + last->i_target = b->b_next; + + backwards_jump->b_cold = b->b_cold; + backwards_jump->b_next = b->b_next; + b->b_next = backwards_jump; + return 0; +} + +static int +normalize_jumps(cfg_builder *g) { - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { + basicblock *entryblock = g->g_entryblock; + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { b->b_visited = 0; } - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { b->b_visited = 1; - if (b->b_iused == 0) { - continue; - } - struct instr *last = &b->b_instr[b->b_iused-1]; - if (last->i_opcode == JUMP_ABSOLUTE && - last->i_target->b_visited == 0 - ) { - last->i_opcode = JUMP_FORWARD; + if (normalize_jumps_in_block(g, b) < 0) { + return -1; } } + return 0; } static void -assemble_jump_offsets(struct assembler *a, struct compiler *c) +assemble_jump_offsets(basicblock *entryblock) { - basicblock *b; int bsize, totsize, extended_arg_recompile; - int i; /* Compute the size of each block and fixup jump args. Replace block pointer with position in bytecode. */ do { totsize = 0; - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { bsize = blocksize(b); b->b_offset = totsize; totsize += bsize; } extended_arg_recompile = 0; - for (b = c->u->u_blocks; b != NULL; b = b->b_list) { + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { bsize = b->b_offset; - for (i = 0; i < b->b_iused; i++) { + for (int i = 0; i < b->b_iused; i++) { struct instr *instr = &b->b_instr[i]; - int isize = instrsize(instr->i_oparg); + int isize = instr_size(instr); /* Relative jumps are computed relative to the instruction pointer after fetching the jump instruction. @@ -7231,9 +7936,19 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c) if (is_jump(instr)) { instr->i_oparg = instr->i_target->b_offset; if (is_relative_jump(instr)) { - instr->i_oparg -= bsize; + if (instr->i_oparg < bsize) { + assert(IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode)); + instr->i_oparg = bsize - instr->i_oparg; + } + else { + assert(!IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode)); + instr->i_oparg -= bsize; + } } - if (instrsize(instr->i_oparg) != isize) { + else { + assert(!IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode)); + } + if (instr_size(instr) != isize) { extended_arg_recompile = 1; } } @@ -7245,7 +7960,7 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c) with a better solution. The issue is that in the first loop blocksize() is called - which calls instrsize() which requires i_oparg be set + which calls instr_size() which requires i_oparg be set appropriately. There is a bootstrap problem because i_oparg is calculated in the second loop above. @@ -7257,6 +7972,169 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c) } while (extended_arg_recompile); } + +// helper functions for add_checks_for_loads_of_unknown_variables +static inline void +maybe_push(basicblock *b, uint64_t unsafe_mask, basicblock ***sp) +{ + // Push b if the unsafe mask is giving us any new information. + // To avoid overflowing the stack, only allow each block once. + // Use b->b_visited=1 to mean that b is currently on the stack. + uint64_t both = b->b_unsafe_locals_mask | unsafe_mask; + if (b->b_unsafe_locals_mask != both) { + b->b_unsafe_locals_mask = both; + // More work left to do. + if (!b->b_visited) { + // not on the stack, so push it. + *(*sp)++ = b; + b->b_visited = 1; + } + } +} + +static void +scan_block_for_locals(basicblock *b, basicblock ***sp) +{ + // bit i is set if local i is potentially uninitialized + uint64_t unsafe_mask = b->b_unsafe_locals_mask; + for (int i = 0; i < b->b_iused; i++) { + struct instr *instr = &b->b_instr[i]; + assert(instr->i_opcode != EXTENDED_ARG); + assert(!IS_SUPERINSTRUCTION_OPCODE(instr->i_opcode)); + if (instr->i_except != NULL) { + maybe_push(instr->i_except, unsafe_mask, sp); + } + if (instr->i_oparg >= 64) { + continue; + } + assert(instr->i_oparg >= 0); + uint64_t bit = (uint64_t)1 << instr->i_oparg; + switch (instr->i_opcode) { + case DELETE_FAST: + unsafe_mask |= bit; + break; + case STORE_FAST: + unsafe_mask &= ~bit; + break; + case LOAD_FAST_CHECK: + // If this doesn't raise, then the local is defined. + unsafe_mask &= ~bit; + break; + case LOAD_FAST: + if (unsafe_mask & bit) { + instr->i_opcode = LOAD_FAST_CHECK; + } + unsafe_mask &= ~bit; + break; + } + } + if (b->b_next && BB_HAS_FALLTHROUGH(b)) { + maybe_push(b->b_next, unsafe_mask, sp); + } + struct instr *last = basicblock_last_instr(b); + if (last && is_jump(last)) { + assert(last->i_target != NULL); + maybe_push(last->i_target, unsafe_mask, sp); + } +} + +static int +fast_scan_many_locals(basicblock *entryblock, int nlocals) +{ + assert(nlocals > 64); + Py_ssize_t *states = PyMem_Calloc(nlocals - 64, sizeof(Py_ssize_t)); + if (states == NULL) { + PyErr_NoMemory(); + return -1; + } + Py_ssize_t blocknum = 0; + // state[i - 64] == blocknum if local i is guaranteed to + // be initialized, i.e., if it has had a previous LOAD_FAST or + // STORE_FAST within that basicblock (not followed by DELETE_FAST). + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + blocknum++; + for (int i = 0; i < b->b_iused; i++) { + struct instr *instr = &b->b_instr[i]; + assert(instr->i_opcode != EXTENDED_ARG); + assert(!IS_SUPERINSTRUCTION_OPCODE(instr->i_opcode)); + int arg = instr->i_oparg; + if (arg < 64) { + continue; + } + assert(arg >= 0); + switch (instr->i_opcode) { + case DELETE_FAST: + states[arg - 64] = blocknum - 1; + break; + case STORE_FAST: + states[arg - 64] = blocknum; + break; + case LOAD_FAST: + if (states[arg - 64] != blocknum) { + instr->i_opcode = LOAD_FAST_CHECK; + } + states[arg - 64] = blocknum; + break; + case LOAD_FAST_CHECK: + Py_UNREACHABLE(); + } + } + } + PyMem_Free(states); + return 0; +} + +static int +add_checks_for_loads_of_uninitialized_variables(basicblock *entryblock, + struct compiler *c) +{ + int nlocals = (int)PyDict_GET_SIZE(c->u->u_varnames); + if (nlocals == 0) { + return 0; + } + if (nlocals > 64) { + // To avoid O(nlocals**2) compilation, locals beyond the first + // 64 are only analyzed one basicblock at a time: initialization + // info is not passed between basicblocks. + if (fast_scan_many_locals(entryblock, nlocals) < 0) { + return -1; + } + nlocals = 64; + } + basicblock **stack = make_cfg_traversal_stack(entryblock); + if (stack == NULL) { + return -1; + } + basicblock **sp = stack; + + // First origin of being uninitialized: + // The non-parameter locals in the entry block. + int nparams = (int)PyList_GET_SIZE(c->u->u_ste->ste_varnames); + uint64_t start_mask = 0; + for (int i = nparams; i < nlocals; i++) { + start_mask |= (uint64_t)1 << i; + } + maybe_push(entryblock, start_mask, &sp); + + // Second origin of being uninitialized: + // There could be DELETE_FAST somewhere, so + // be sure to scan each basicblock at least once. + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + scan_block_for_locals(b, &sp); + } + + // Now propagate the uncertainty from the origins we found: Use + // LOAD_FAST_CHECK for any LOAD_FAST where the local could be undefined. + while (sp > stack) { + basicblock *b = *--sp; + // mark as no longer on stack + b->b_visited = 0; + scan_block_for_locals(b, &sp); + } + PyMem_Free(stack); + return 0; +} + static PyObject * dict_keys_inorder(PyObject *dict, Py_ssize_t offset) { @@ -7268,10 +8146,9 @@ dict_keys_inorder(PyObject *dict, Py_ssize_t offset) return NULL; while (PyDict_Next(dict, &pos, &k, &v)) { i = PyLong_AS_LONG(v); - Py_INCREF(k); assert((i - offset) < size); assert((i - offset) >= 0); - PyTuple_SET_ITEM(tuple, i - offset, k); + PyTuple_SET_ITEM(tuple, i - offset, Py_NewRef(k)); } return tuple; } @@ -7288,15 +8165,14 @@ consts_dict_keys_inorder(PyObject *dict) while (PyDict_Next(dict, &pos, &k, &v)) { i = PyLong_AS_LONG(v); /* The keys of the dictionary can be tuples wrapping a constant. - * (see compiler_add_o and _PyCode_ConstantKey). In that case + * (see dict_add_o and _PyCode_ConstantKey). In that case * the object we want is always second. */ if (PyTuple_CheckExact(k)) { k = PyTuple_GET_ITEM(k, 1); } - Py_INCREF(k); assert(i < size); assert(i >= 0); - PyList_SET_ITEM(consts, i, k); + PyList_SET_ITEM(consts, i, Py_NewRef(k)); } return consts; } @@ -7323,7 +8199,7 @@ compute_code_flags(struct compiler *c) } /* (Only) inherit compilerflags in PyCF_MASK */ - flags |= (c->c_flags->cf_flags & PyCF_MASK); + flags |= (c->c_flags.cf_flags & PyCF_MASK); if ((IS_TOP_LEVEL_AWAIT(c)) && ste->ste_coroutine && @@ -7337,21 +8213,22 @@ compute_code_flags(struct compiler *c) // Merge *obj* with constant cache. // Unlike merge_consts_recursive(), this function doesn't work recursively. static int -merge_const_one(struct compiler *c, PyObject **obj) +merge_const_one(PyObject *const_cache, PyObject **obj) { + PyDict_CheckExact(const_cache); PyObject *key = _PyCode_ConstantKey(*obj); if (key == NULL) { - return 0; + return -1; } // t is borrowed reference - PyObject *t = PyDict_SetDefault(c->c_const_cache, key, key); + PyObject *t = PyDict_SetDefault(const_cache, key, key); Py_DECREF(key); if (t == NULL) { - return 0; + return -1; } if (t == key) { // obj is new constant. - return 1; + return 0; } if (PyTuple_CheckExact(t)) { @@ -7359,10 +8236,8 @@ merge_const_one(struct compiler *c, PyObject **obj) t = PyTuple_GET_ITEM(t, 1); } - Py_INCREF(t); - Py_DECREF(*obj); - *obj = t; - return 1; + Py_SETREF(*obj, Py_NewRef(t)); + return 0; } // This is in codeobject.c. @@ -7416,7 +8291,7 @@ compute_localsplus_info(struct compiler *c, int nlocalsplus, static PyCodeObject * makecode(struct compiler *c, struct assembler *a, PyObject *constslist, - int maxdepth, int nlocalsplus) + int maxdepth, int nlocalsplus, int code_flags) { PyCodeObject *co = NULL; PyObject *names = NULL; @@ -7428,12 +8303,7 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist, if (!names) { goto error; } - if (!merge_const_one(c, &names)) { - goto error; - } - - int flags = compute_code_flags(c); - if (flags < 0) { + if (merge_const_one(c->c_const_cache, &names) < 0) { goto error; } @@ -7441,7 +8311,7 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist, if (consts == NULL) { goto error; } - if (!merge_const_one(c, &consts)) { + if (merge_const_one(c->c_const_cache, &consts) < 0) { goto error; } @@ -7467,13 +8337,11 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist, .filename = c->c_filename, .name = c->u->u_name, .qualname = c->u->u_qualname ? c->u->u_qualname : c->u->u_name, - .flags = flags, + .flags = code_flags, .code = a->a_bytecode, .firstlineno = c->u->u_firstlineno, - .linetable = a->a_lnotab, - .endlinetable = a->a_enotab, - .columntable = a->a_cnotab, + .linetable = a->a_linetable, .consts = consts, .names = names, @@ -7494,7 +8362,7 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist, goto error; } - if (!merge_const_one(c, &localsplusnames)) { + if (merge_const_one(c->c_const_cache, &localsplusnames) < 0) { goto error; } con.localsplusnames = localsplusnames; @@ -7527,16 +8395,20 @@ dump_instr(struct instr *i) if (HAS_ARG(i->i_opcode)) { sprintf(arg, "arg: %d ", i->i_oparg); } + if (HAS_TARGET(i->i_opcode)) { + sprintf(arg, "target: %p [%d] ", i->i_target, i->i_oparg); + } fprintf(stderr, "line: %d, opcode: %d %s%s%s\n", - i->i_lineno, i->i_opcode, arg, jabs, jrel); + i->i_loc.lineno, i->i_opcode, arg, jabs, jrel); } static void dump_basicblock(const basicblock *b) { - const char *b_return = b->b_return ? "return " : ""; - fprintf(stderr, "used: %d, depth: %d, offset: %d %s\n", - b->b_iused, b->b_startdepth, b->b_offset, b_return); + const char *b_return = basicblock_returns(b) ? "return " : ""; + fprintf(stderr, "%d: [EH=%d CLD=%d WRM=%d NO_FT=%d %p] used: %d, depth: %d, offset: %d %s\n", + b->b_label, b->b_except_handler, b->b_cold, b->b_warm, BB_NO_FALLTHROUGH(b), b, b->b_iused, + b->b_startdepth, b->b_offset, b_return); if (b->b_instr) { int i; for (i = 0; i < b->b_iused; i++) { @@ -7549,20 +8421,17 @@ dump_basicblock(const basicblock *b) static int -normalize_basic_block(basicblock *bb); +translate_jump_labels_to_targets(basicblock *entryblock); static int -optimize_cfg(struct compiler *c, struct assembler *a, PyObject *consts); +optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache); static int -trim_unused_consts(struct compiler *c, struct assembler *a, PyObject *consts); +remove_unused_consts(basicblock *entryblock, PyObject *consts); /* Duplicates exit BBs, so that line numbers can be propagated to them */ static int -duplicate_exits_without_lineno(struct compiler *c); - -static int -extend_block(basicblock *bb); +duplicate_exits_without_lineno(cfg_builder *g); static int * build_cellfixedoffsets(struct compiler *c) @@ -7597,26 +8466,32 @@ build_cellfixedoffsets(struct compiler *c) return fixed; } -static inline int -insert_instruction(basicblock *block, int pos, struct instr *instr) { - if (compiler_next_instr(block) < 0) { - return -1; - } - for (int i = block->b_iused-1; i > pos; i--) { - block->b_instr[i] = block->b_instr[i-1]; - } - block->b_instr[pos] = *instr; - return 0; -} - static int insert_prefix_instructions(struct compiler *c, basicblock *entryblock, - int *fixed) + int *fixed, int nfreevars, int code_flags) { + assert(c->u->u_firstlineno > 0); - int flags = compute_code_flags(c); - if (flags < 0) { - return -1; + /* Add the generator prefix instructions. */ + if (code_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) { + struct instr make_gen = { + .i_opcode = RETURN_GENERATOR, + .i_oparg = 0, + .i_loc = LOCATION(c->u->u_firstlineno, c->u->u_firstlineno, -1, -1), + .i_target = NULL, + }; + if (insert_instruction(entryblock, 0, &make_gen) < 0) { + return -1; + } + struct instr pop_top = { + .i_opcode = POP_TOP, + .i_oparg = 0, + .i_loc = NO_LOCATION, + .i_target = NULL, + }; + if (insert_instruction(entryblock, 1, &pop_top) < 0) { + return -1; + } } /* Set up cells for any variable that escapes, to be put in a closure. */ @@ -7643,10 +8518,7 @@ insert_prefix_instructions(struct compiler *c, basicblock *entryblock, .i_opcode = MAKE_CELL, // This will get fixed in offset_derefs(). .i_oparg = oldindex, - .i_lineno = -1, - .i_col_offset = -1, - .i_end_lineno = -1, - .i_end_col_offset = -1, + .i_loc = NO_LOCATION, .i_target = NULL, }; if (insert_instruction(entryblock, ncellsused, &make_cell) < 0) { @@ -7657,31 +8529,17 @@ insert_prefix_instructions(struct compiler *c, basicblock *entryblock, PyMem_RawFree(sorted); } - /* Add the generator prefix instructions. */ - if (flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) { - int kind; - if (flags & CO_COROUTINE) { - kind = 1; - } - else if (flags & CO_ASYNC_GENERATOR) { - kind = 2; - } - else { - kind = 0; - } - - struct instr gen_start = { - .i_opcode = GEN_START, - .i_oparg = kind, - .i_lineno = -1, - .i_col_offset = -1, - .i_end_lineno = -1, - .i_end_col_offset = -1, + if (nfreevars) { + struct instr copy_frees = { + .i_opcode = COPY_FREE_VARS, + .i_oparg = nfreevars, + .i_loc = NO_LOCATION, .i_target = NULL, }; - if (insert_instruction(entryblock, 0, &gen_start) < 0) { + if (insert_instruction(entryblock, 0, ©_frees) < 0) { return -1; } + } return 0; @@ -7692,25 +8550,25 @@ insert_prefix_instructions(struct compiler *c, basicblock *entryblock, * The resulting line number may not be correct according to PEP 626, * but should be "good enough", and no worse than in older versions. */ static void -guarantee_lineno_for_exits(struct assembler *a, int firstlineno) { +guarantee_lineno_for_exits(basicblock *entryblock, int firstlineno) { int lineno = firstlineno; assert(lineno > 0); - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - if (b->b_iused == 0) { + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + struct instr *last = basicblock_last_instr(b); + if (last == NULL) { continue; } - struct instr *last = &b->b_instr[b->b_iused-1]; - if (last->i_lineno < 0) { + if (last->i_loc.lineno < 0) { if (last->i_opcode == RETURN_VALUE) { for (int i = 0; i < b->b_iused; i++) { - assert(b->b_instr[i].i_lineno < 0); + assert(b->b_instr[i].i_loc.lineno < 0); - b->b_instr[i].i_lineno = lineno; + b->b_instr[i].i_loc.lineno = lineno; } } } else { - lineno = last->i_lineno; + lineno = last->i_loc.lineno; } } } @@ -7761,48 +8619,103 @@ fix_cell_offsets(struct compiler *c, basicblock *entryblock, int *fixedmap) } static void -propagate_line_numbers(struct assembler *a); +propagate_line_numbers(basicblock *entryblock); -static PyCodeObject * -assemble(struct compiler *c, int addNone) -{ - basicblock *b, *entryblock; - struct assembler a; - int j, nblocks; - PyCodeObject *co = NULL; - PyObject *consts = NULL; +#ifndef NDEBUG - /* Make sure every block that falls off the end returns None. - XXX NEXT_BLOCK() isn't quite right, because if the last - block ends with a jump or return b_next shouldn't set. +static bool +no_redundant_nops(cfg_builder *g) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + if (remove_redundant_nops(b) != 0) { + return false; + } + } + return true; +} + +static bool +no_redundant_jumps(cfg_builder *g) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + struct instr *last = basicblock_last_instr(b); + if (last != NULL) { + if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) { + assert(last->i_target != b->b_next); + if (last->i_target == b->b_next) { + return false; + } + } + } + } + return true; +} + +static bool +opcode_metadata_is_sane(cfg_builder *g) { + bool result = true; + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + for (int i = 0; i < b->b_iused; i++) { + struct instr *instr = &b->b_instr[i]; + int opcode = instr->i_opcode; + int oparg = instr->i_oparg; + assert(opcode <= MAX_REAL_OPCODE); + int popped = _PyOpcode_num_popped(opcode, oparg); + int pushed = _PyOpcode_num_pushed(opcode, oparg); + assert((pushed < 0) == (popped < 0)); + if (pushed >= 0) { + assert(_PyOpcode_opcode_metadata[opcode].valid_entry); + int effect = stack_effect(opcode, instr->i_oparg, -1); + if (effect != pushed - popped) { + fprintf(stderr, + "op=%d: stack_effect (%d) != pushed (%d) - popped (%d)\n", + opcode, effect, pushed, popped); + result = false; + } + } + } + } + return result; +} + +static bool +no_empty_basic_blocks(cfg_builder *g) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + if (b->b_iused == 0) { + return false; + } + } + return true; +} +#endif + +static int +remove_redundant_jumps(cfg_builder *g) { + /* If a non-empty block ends with a jump instruction, check if the next + * non-empty block reached through normal flow control is the target + * of that jump. If it is, then the jump instruction is redundant and + * can be deleted. */ - if (!c->u->u_curblock->b_return) { - UNSET_LOC(c); - if (addNone) - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, RETURN_VALUE); - } - - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - if (normalize_basic_block(b)) { - return NULL; + assert(no_empty_basic_blocks(g)); + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + struct instr *last = basicblock_last_instr(b); + assert(last != NULL); + assert(!IS_ASSEMBLER_OPCODE(last->i_opcode)); + if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) { + if (last->i_target == NULL) { + PyErr_SetString(PyExc_SystemError, "jump with NULL target"); + return -1; + } + if (last->i_target == b->b_next) { + assert(b->b_next->b_iused); + INSTR_SET_OP0(last, NOP); + } } } + return 0; +} - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - if (extend_block(b)) { - return NULL; - } - } - - nblocks = 0; - entryblock = NULL; - for (b = c->u->u_blocks; b != NULL; b = b->b_list) { - nblocks++; - entryblock = b; - } - assert(entryblock != NULL); - +static int +prepare_localsplus(struct compiler* c, int code_flags) +{ assert(PyDict_GET_SIZE(c->u->u_varnames) < INT_MAX); assert(PyDict_GET_SIZE(c->u->u_cellvars) < INT_MAX); assert(PyDict_GET_SIZE(c->u->u_freevars) < INT_MAX); @@ -7812,126 +8725,207 @@ assemble(struct compiler *c, int addNone) assert(INT_MAX - nlocals - ncellvars > 0); assert(INT_MAX - nlocals - ncellvars - nfreevars > 0); int nlocalsplus = nlocals + ncellvars + nfreevars; - int *cellfixedoffsets = build_cellfixedoffsets(c); + int* cellfixedoffsets = build_cellfixedoffsets(c); if (cellfixedoffsets == NULL) { - goto error; + return -1; } + cfg_builder* g = CFG_BUILDER(c); + // This must be called before fix_cell_offsets(). - if (insert_prefix_instructions(c, entryblock, cellfixedoffsets)) { - goto error; + if (insert_prefix_instructions(c, g->g_entryblock, cellfixedoffsets, nfreevars, code_flags)) { + PyMem_Free(cellfixedoffsets); + return -1; } - /* Set firstlineno if it wasn't explicitly set. */ - if (!c->u->u_firstlineno) { - if (entryblock->b_instr && entryblock->b_instr->i_lineno) - c->u->u_firstlineno = entryblock->b_instr->i_lineno; - else - c->u->u_firstlineno = 1; - } - - if (!assemble_init(&a, nblocks, c->u->u_firstlineno)) - goto error; - a.a_entry = entryblock; - a.a_nblocks = nblocks; - - int numdropped = fix_cell_offsets(c, entryblock, cellfixedoffsets); + int numdropped = fix_cell_offsets(c, g->g_entryblock, cellfixedoffsets); PyMem_Free(cellfixedoffsets); // At this point we're done with it. cellfixedoffsets = NULL; if (numdropped < 0) { - goto error; + return -1; } nlocalsplus -= numdropped; + return nlocalsplus; +} +static int +add_return_at_end_of_block(struct compiler *c, int addNone) +{ + /* Make sure every block that falls off the end returns None. */ + if (!basicblock_returns(CFG_BUILDER(c)->g_curblock)) { + if (addNone) { + ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + } + ADDOP(c, NO_LOCATION, RETURN_VALUE); + } + return SUCCESS; +} + +static PyCodeObject * +assemble(struct compiler *c, int addNone) +{ + PyCodeObject *co = NULL; + PyObject *consts = NULL; + struct assembler a; + memset(&a, 0, sizeof(struct assembler)); + + int code_flags = compute_code_flags(c); + if (code_flags < 0) { + return NULL; + } + + if (add_return_at_end_of_block(c, addNone) < 0) { + return NULL; + } + + int nblocks = 0; + for (basicblock *b = CFG_BUILDER(c)->g_block_list; b != NULL; b = b->b_list) { + nblocks++; + } + if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) { + PyErr_NoMemory(); + goto error; + } + + cfg_builder *g = CFG_BUILDER(c); + assert(g->g_entryblock != NULL); + + /* Set firstlineno if it wasn't explicitly set. */ + if (!c->u->u_firstlineno) { + if (g->g_entryblock->b_instr && g->g_entryblock->b_instr->i_loc.lineno) { + c->u->u_firstlineno = g->g_entryblock->b_instr->i_loc.lineno; + } + else { + c->u->u_firstlineno = 1; + } + } + + /** Preprocessing **/ + /* Map labels to targets and mark exception handlers */ + if (translate_jump_labels_to_targets(g->g_entryblock)) { + goto error; + } + if (mark_except_handlers(g->g_entryblock) < 0) { + goto error; + } + if (label_exception_targets(g->g_entryblock)) { + goto error; + } + + /** Optimization **/ consts = consts_dict_keys_inorder(c->u->u_consts); if (consts == NULL) { goto error; } + if (optimize_cfg(g, consts, c->c_const_cache)) { + goto error; + } + if (add_checks_for_loads_of_uninitialized_variables(g->g_entryblock, c) < 0) { + goto error; + } + if (remove_unused_consts(g->g_entryblock, consts)) { + goto error; + } - if (optimize_cfg(c, &a, consts)) { + /** line numbers (TODO: move this before optimization stage) */ + if (duplicate_exits_without_lineno(g) < 0) { goto error; } - if (duplicate_exits_without_lineno(c)) { - return NULL; - } - if (trim_unused_consts(c, &a, consts)) { + propagate_line_numbers(g->g_entryblock); + guarantee_lineno_for_exits(g->g_entryblock, c->u->u_firstlineno); + + if (push_cold_blocks_to_end(g, code_flags) < 0) { goto error; } - propagate_line_numbers(&a); - guarantee_lineno_for_exits(&a, c->u->u_firstlineno); - int maxdepth = stackdepth(c); + + /** Assembly **/ + + int nlocalsplus = prepare_localsplus(c, code_flags); + if (nlocalsplus < 0) { + goto error; + } + + int maxdepth = stackdepth(g->g_entryblock, code_flags); if (maxdepth < 0) { goto error; } - if (maxdepth > MAX_ALLOWED_STACK_USE) { - PyErr_Format(PyExc_SystemError, - "excessive stack use: stack is %d deep", - maxdepth); - goto error; - } + /* TO DO -- For 3.12, make sure that `maxdepth <= MAX_ALLOWED_STACK_USE` */ - if (label_exception_targets(entryblock)) { - goto error; - } - convert_exception_handlers_to_nops(entryblock); - for (basicblock *b = a.a_entry; b != NULL; b = b->b_next) { - clean_basic_block(b); - } + convert_exception_handlers_to_nops(g->g_entryblock); /* Order of basic blocks must have been determined by now */ - normalize_jumps(&a); - - /* Can't modify the bytecode after computing jump offsets. */ - assemble_jump_offsets(&a, c); - - /* Emit code. */ - for(b = entryblock; b != NULL; b = b->b_next) { - for (j = 0; j < b->b_iused; j++) - if (!assemble_emit(&a, &b->b_instr[j])) - goto error; + if (normalize_jumps(g) < 0) { + goto error; } - if (!assemble_exception_table(&a)) { + assert(no_redundant_jumps(g)); + assert(opcode_metadata_is_sane(g)); + + /* Can't modify the bytecode after computing jump offsets. */ + assemble_jump_offsets(g->g_entryblock); + + /* Create assembler */ + if (assemble_init(&a, c->u->u_firstlineno) < 0) { + goto error; + } + + /* Emit code. */ + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + for (int j = 0; j < b->b_iused; j++) { + if (assemble_emit(&a, &b->b_instr[j]) < 0) { + goto error; + } + } + } + + /* Emit location info */ + a.a_lineno = c->u->u_firstlineno; + location loc = NO_LOCATION; + int size = 0; + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + for (int j = 0; j < b->b_iused; j++) { + if (!same_location(loc, b->b_instr[j].i_loc)) { + if (assemble_emit_location(&a, loc, size)) { + goto error; + } + loc = b->b_instr[j].i_loc; + size = 0; + } + size += instr_size(&b->b_instr[j]); + } + } + if (assemble_emit_location(&a, loc, size)) { + goto error; + } + + if (assemble_exception_table(&a, g->g_entryblock) < 0) { goto error; } if (_PyBytes_Resize(&a.a_except_table, a.a_except_table_off) < 0) { goto error; } - if (!assemble_start_line_range(&a)) { - return 0; - } - if (_PyBytes_Resize(&a.a_lnotab, a.a_lnotab_off) < 0) { - goto error; - } - if (!merge_const_one(c, &a.a_lnotab)) { - goto error; - } - if (!assemble_end_line_range(&a)) { - return 0; - } - if (_PyBytes_Resize(&a.a_enotab, a.a_enotab_off) < 0) { - goto error; - } - if (!merge_const_one(c, &a.a_enotab)) { - goto error; - } - if (_PyBytes_Resize(&a.a_cnotab, a.a_cnotab_off) < 0) { - goto error; - } - if (_PyBytes_Resize(&a.a_bytecode, a.a_offset * sizeof(_Py_CODEUNIT)) < 0) { - goto error; - } - if (!merge_const_one(c, &a.a_bytecode)) { + if (merge_const_one(c->c_const_cache, &a.a_except_table) < 0) { goto error; } - co = makecode(c, &a, consts, maxdepth, nlocalsplus); + if (_PyBytes_Resize(&a.a_linetable, a.a_location_off) < 0) { + goto error; + } + if (merge_const_one(c->c_const_cache, &a.a_linetable) < 0) { + goto error; + } + + if (_PyBytes_Resize(&a.a_bytecode, a.a_offset * sizeof(_Py_CODEUNIT)) < 0) { + goto error; + } + if (merge_const_one(c->c_const_cache, &a.a_bytecode) < 0) { + goto error; + } + + co = makecode(c, &a, consts, maxdepth, nlocalsplus, code_flags); error: Py_XDECREF(consts); assemble_free(&a); - if (cellfixedoffsets != NULL) { - PyMem_Free(cellfixedoffsets); - } return co; } @@ -7949,8 +8943,7 @@ get_const_value(int opcode, int oparg, PyObject *co_consts) "Internal error: failed to get value of a constant"); return NULL; } - Py_INCREF(constant); - return constant; + return Py_NewRef(constant); } /* Replace LOAD_CONST c1, LOAD_CONST c2 ... LOAD_CONST cn, BUILD_TUPLE n @@ -7960,11 +8953,12 @@ get_const_value(int opcode, int oparg, PyObject *co_consts) Called with codestr pointing to the first LOAD_CONST. */ static int -fold_tuple_on_constants(struct compiler *c, +fold_tuple_on_constants(PyObject *const_cache, struct instr *inst, int n, PyObject *consts) { /* Pre-conditions */ + assert(PyDict_CheckExact(const_cache)); assert(PyList_CheckExact(consts)); assert(inst[n].i_opcode == BUILD_TUPLE); assert(inst[n].i_oparg == n); @@ -7989,7 +8983,7 @@ fold_tuple_on_constants(struct compiler *c, } PyTuple_SET_ITEM(newconst, i, constant); } - if (merge_const_one(c, &newconst) == 0) { + if (merge_const_one(const_cache, &newconst) < 0) { Py_DECREF(newconst); return -1; } @@ -8013,42 +9007,175 @@ fold_tuple_on_constants(struct compiler *c, } Py_DECREF(newconst); for (int i = 0; i < n; i++) { - inst[i].i_opcode = NOP; + INSTR_SET_OP0(&inst[i], NOP); } - inst[n].i_opcode = LOAD_CONST; - inst[n].i_oparg = (int)index; + INSTR_SET_OP1(&inst[n], LOAD_CONST, (int)index); return 0; } +#define VISITED (-1) -// Eliminate n * ROT_N(n). -static void -fold_rotations(struct instr *inst, int n) +// Replace an arbitrary run of SWAPs and NOPs with an optimal one that has the +// same effect. +static int +swaptimize(basicblock *block, int *ix) { - for (int i = 0; i < n; i++) { - int rot; - switch (inst[i].i_opcode) { - case ROT_N: - rot = inst[i].i_oparg; - break; - case ROT_FOUR: - rot = 4; - break; - case ROT_THREE: - rot = 3; - break; - case ROT_TWO: - rot = 2; - break; - default: - return; + // NOTE: "./python -m test test_patma" serves as a good, quick stress test + // for this function. Make sure to blow away cached *.pyc files first! + assert(*ix < block->b_iused); + struct instr *instructions = &block->b_instr[*ix]; + // Find the length of the current sequence of SWAPs and NOPs, and record the + // maximum depth of the stack manipulations: + assert(instructions[0].i_opcode == SWAP); + int depth = instructions[0].i_oparg; + int len = 0; + int more = false; + int limit = block->b_iused - *ix; + while (++len < limit) { + int opcode = instructions[len].i_opcode; + if (opcode == SWAP) { + depth = Py_MAX(depth, instructions[len].i_oparg); + more = true; } - if (rot != n) { - return; + else if (opcode != NOP) { + break; } } - for (int i = 0; i < n; i++) { - inst[i].i_opcode = NOP; + // It's already optimal if there's only one SWAP: + if (!more) { + return 0; + } + // Create an array with elements {0, 1, 2, ..., depth - 1}: + int *stack = PyMem_Malloc(depth * sizeof(int)); + if (stack == NULL) { + PyErr_NoMemory(); + return -1; + } + for (int i = 0; i < depth; i++) { + stack[i] = i; + } + // Simulate the combined effect of these instructions by "running" them on + // our "stack": + for (int i = 0; i < len; i++) { + if (instructions[i].i_opcode == SWAP) { + int oparg = instructions[i].i_oparg; + int top = stack[0]; + // SWAPs are 1-indexed: + stack[0] = stack[oparg - 1]; + stack[oparg - 1] = top; + } + } + // Now we can begin! Our approach here is based on a solution to a closely + // related problem (https://cs.stackexchange.com/a/13938). It's easiest to + // think of this algorithm as determining the steps needed to efficiently + // "un-shuffle" our stack. By performing the moves in *reverse* order, + // though, we can efficiently *shuffle* it! For this reason, we will be + // replacing instructions starting from the *end* of the run. Since the + // solution is optimal, we don't need to worry about running out of space: + int current = len - 1; + for (int i = 0; i < depth; i++) { + // Skip items that have already been visited, or just happen to be in + // the correct location: + if (stack[i] == VISITED || stack[i] == i) { + continue; + } + // Okay, we've found an item that hasn't been visited. It forms a cycle + // with other items; traversing the cycle and swapping each item with + // the next will put them all in the correct place. The weird + // loop-and-a-half is necessary to insert 0 into every cycle, since we + // can only swap from that position: + int j = i; + while (true) { + // Skip the actual swap if our item is zero, since swapping the top + // item with itself is pointless: + if (j) { + assert(0 <= current); + // SWAPs are 1-indexed: + instructions[current].i_opcode = SWAP; + instructions[current--].i_oparg = j + 1; + } + if (stack[j] == VISITED) { + // Completed the cycle: + assert(j == i); + break; + } + int next_j = stack[j]; + stack[j] = VISITED; + j = next_j; + } + } + // NOP out any unused instructions: + while (0 <= current) { + INSTR_SET_OP0(&instructions[current--], NOP); + } + PyMem_Free(stack); + *ix += len - 1; + return 0; +} + +// This list is pretty small, since it's only okay to reorder opcodes that: +// - can't affect control flow (like jumping or raising exceptions) +// - can't invoke arbitrary code (besides finalizers) +// - only touch the TOS (and pop it when finished) +#define SWAPPABLE(opcode) \ + ((opcode) == STORE_FAST || (opcode) == POP_TOP) + +static int +next_swappable_instruction(basicblock *block, int i, int lineno) +{ + while (++i < block->b_iused) { + struct instr *instruction = &block->b_instr[i]; + if (0 <= lineno && instruction->i_loc.lineno != lineno) { + // Optimizing across this instruction could cause user-visible + // changes in the names bound between line tracing events! + return -1; + } + if (instruction->i_opcode == NOP) { + continue; + } + if (SWAPPABLE(instruction->i_opcode)) { + return i; + } + return -1; + } + return -1; +} + +// Attempt to apply SWAPs statically by swapping *instructions* rather than +// stack items. For example, we can replace SWAP(2), POP_TOP, STORE_FAST(42) +// with the more efficient NOP, STORE_FAST(42), POP_TOP. +static void +apply_static_swaps(basicblock *block, int i) +{ + // SWAPs are to our left, and potential swaperands are to our right: + for (; 0 <= i; i--) { + assert(i < block->b_iused); + struct instr *swap = &block->b_instr[i]; + if (swap->i_opcode != SWAP) { + if (swap->i_opcode == NOP || SWAPPABLE(swap->i_opcode)) { + // Nope, but we know how to handle these. Keep looking: + continue; + } + // We can't reason about what this instruction does. Bail: + return; + } + int j = next_swappable_instruction(block, i, -1); + if (j < 0) { + return; + } + int k = j; + int lineno = block->b_instr[j].i_loc.lineno; + for (int count = swap->i_oparg - 1; 0 < count; count--) { + k = next_swappable_instruction(block, k, lineno); + if (k < 0) { + return; + } + } + // Success! + INSTR_SET_OP0(swap, NOP); + struct instr temp = block->b_instr[j]; + block->b_instr[j] = block->b_instr[k]; + block->b_instr[k] = temp; } } @@ -8062,7 +9189,7 @@ jump_thread(struct instr *inst, struct instr *target, int opcode) assert(is_jump(target)); // bpo-45773: If inst->i_target == target->i_target, then nothing actually // changes (and we fall into an infinite loop): - if (inst->i_lineno == target->i_lineno && + if ((inst->i_loc.lineno == target->i_loc.lineno || target->i_loc.lineno == -1) && inst->i_target != target->i_target) { inst->i_target = target->i_target; @@ -8077,26 +9204,26 @@ jump_thread(struct instr *inst, struct instr *target, int opcode) /* Optimization */ static int -optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) +optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts) { + assert(PyDict_CheckExact(const_cache)); assert(PyList_CheckExact(consts)); struct instr nop; - nop.i_opcode = NOP; + INSTR_SET_OP0(&nop, NOP); struct instr *target; for (int i = 0; i < bb->b_iused; i++) { struct instr *inst = &bb->b_instr[i]; int oparg = inst->i_oparg; int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0; - if (is_jump(inst)) { - /* Skip over empty basic blocks. */ - while (inst->i_target->b_iused == 0) { - inst->i_target = inst->i_target->b_next; - } + if (HAS_TARGET(inst->i_opcode)) { + assert(inst->i_target->b_iused > 0); target = &inst->i_target->b_instr[0]; + assert(!IS_ASSEMBLER_OPCODE(target->i_opcode)); } else { target = &nop; } + assert(!IS_ASSEMBLER_OPCODE(inst->i_opcode)); switch (inst->i_opcode) { /* Remove LOAD_CONST const; conditional jump */ case LOAD_CONST: @@ -8116,14 +9243,13 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) if (is_true == -1) { goto error; } - inst->i_opcode = NOP; + INSTR_SET_OP0(inst, NOP); jump_if_true = nextop == POP_JUMP_IF_TRUE; if (is_true == jump_if_true) { - bb->b_instr[i+1].i_opcode = JUMP_ABSOLUTE; - bb->b_nofallthrough = 1; + bb->b_instr[i+1].i_opcode = JUMP; } else { - bb->b_instr[i+1].i_opcode = NOP; + INSTR_SET_OP0(&bb->b_instr[i + 1], NOP); } break; case JUMP_IF_FALSE_OR_POP: @@ -8139,41 +9265,52 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) } jump_if_true = nextop == JUMP_IF_TRUE_OR_POP; if (is_true == jump_if_true) { - bb->b_instr[i+1].i_opcode = JUMP_ABSOLUTE; - bb->b_nofallthrough = 1; + bb->b_instr[i+1].i_opcode = JUMP; } else { - inst->i_opcode = NOP; - bb->b_instr[i+1].i_opcode = NOP; + INSTR_SET_OP0(inst, NOP); + INSTR_SET_OP0(&bb->b_instr[i + 1], NOP); } break; + case IS_OP: + cnt = get_const_value(inst->i_opcode, oparg, consts); + if (cnt == NULL) { + goto error; + } + int jump_op = i+2 < bb->b_iused ? bb->b_instr[i+2].i_opcode : 0; + if (Py_IsNone(cnt) && (jump_op == POP_JUMP_IF_FALSE || jump_op == POP_JUMP_IF_TRUE)) { + unsigned char nextarg = bb->b_instr[i+1].i_oparg; + INSTR_SET_OP0(inst, NOP); + INSTR_SET_OP0(&bb->b_instr[i + 1], NOP); + bb->b_instr[i+2].i_opcode = nextarg ^ (jump_op == POP_JUMP_IF_FALSE) ? + POP_JUMP_IF_NOT_NONE : POP_JUMP_IF_NONE; + } + Py_DECREF(cnt); + break; } break; } /* Try to fold tuples of constants. - Skip over BUILD_SEQN 1 UNPACK_SEQN 1. - Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2. - Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */ + Skip over BUILD_TUPLE(1) UNPACK_SEQUENCE(1). + Replace BUILD_TUPLE(2) UNPACK_SEQUENCE(2) with SWAP(2). + Replace BUILD_TUPLE(3) UNPACK_SEQUENCE(3) with SWAP(3). */ case BUILD_TUPLE: if (nextop == UNPACK_SEQUENCE && oparg == bb->b_instr[i+1].i_oparg) { switch(oparg) { case 1: - inst->i_opcode = NOP; - bb->b_instr[i+1].i_opcode = NOP; - break; + INSTR_SET_OP0(inst, NOP); + INSTR_SET_OP0(&bb->b_instr[i + 1], NOP); + continue; case 2: - inst->i_opcode = ROT_TWO; - bb->b_instr[i+1].i_opcode = NOP; - break; case 3: - inst->i_opcode = ROT_THREE; - bb->b_instr[i+1].i_opcode = ROT_TWO; + INSTR_SET_OP0(inst, NOP); + bb->b_instr[i+1].i_opcode = SWAP; + continue; } - break; } if (i >= oparg) { - if (fold_tuple_on_constants(c, inst-oparg, oparg, consts)) { + if (fold_tuple_on_constants(const_cache, inst-oparg, oparg, consts)) { goto error; } } @@ -8198,14 +9335,13 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) case POP_JUMP_IF_FALSE: i -= jump_thread(inst, target, POP_JUMP_IF_FALSE); break; - case JUMP_ABSOLUTE: - case JUMP_FORWARD: + case JUMP: case JUMP_IF_FALSE_OR_POP: i -= jump_thread(inst, target, JUMP_IF_FALSE_OR_POP); break; case JUMP_IF_TRUE_OR_POP: case POP_JUMP_IF_TRUE: - if (inst->i_lineno == target->i_lineno) { + if (inst->i_loc.lineno == target->i_loc.lineno) { // We don't need to bother checking for loops here, // since a block's b_next cannot point to itself: assert(inst->i_target != inst->i_target->b_next); @@ -8221,14 +9357,13 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) case POP_JUMP_IF_TRUE: i -= jump_thread(inst, target, POP_JUMP_IF_TRUE); break; - case JUMP_ABSOLUTE: - case JUMP_FORWARD: + case JUMP: case JUMP_IF_TRUE_OR_POP: i -= jump_thread(inst, target, JUMP_IF_TRUE_OR_POP); break; case JUMP_IF_FALSE_OR_POP: case POP_JUMP_IF_FALSE: - if (inst->i_lineno == target->i_lineno) { + if (inst->i_loc.lineno == target->i_loc.lineno) { // We don't need to bother checking for loops here, // since a block's b_next cannot point to itself: assert(inst->i_target != inst->i_target->b_next); @@ -8239,58 +9374,59 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) break; } break; + case POP_JUMP_IF_NOT_NONE: + case POP_JUMP_IF_NONE: + switch (target->i_opcode) { + case JUMP: + i -= jump_thread(inst, target, inst->i_opcode); + } + break; case POP_JUMP_IF_FALSE: switch (target->i_opcode) { - case JUMP_ABSOLUTE: - case JUMP_FORWARD: - case JUMP_IF_FALSE_OR_POP: + case JUMP: i -= jump_thread(inst, target, POP_JUMP_IF_FALSE); } break; case POP_JUMP_IF_TRUE: switch (target->i_opcode) { - case JUMP_ABSOLUTE: - case JUMP_FORWARD: - case JUMP_IF_TRUE_OR_POP: + case JUMP: i -= jump_thread(inst, target, POP_JUMP_IF_TRUE); } break; - case JUMP_ABSOLUTE: - case JUMP_FORWARD: + case JUMP: switch (target->i_opcode) { - case JUMP_ABSOLUTE: - case JUMP_FORWARD: - i -= jump_thread(inst, target, JUMP_ABSOLUTE); + case JUMP: + i -= jump_thread(inst, target, JUMP); } break; case FOR_ITER: - if (target->i_opcode == JUMP_FORWARD) { + if (target->i_opcode == JUMP) { + /* This will not work now because the jump (at target) could + * be forward or backward and FOR_ITER only jumps forward. We + * can re-enable this if ever we implement a backward version + * of FOR_ITER. + */ + /* i -= jump_thread(inst, target, FOR_ITER); + */ } break; - case ROT_N: - switch (oparg) { - case 0: - case 1: - inst->i_opcode = NOP; - continue; - case 2: - inst->i_opcode = ROT_TWO; - break; - case 3: - inst->i_opcode = ROT_THREE; - break; - case 4: - inst->i_opcode = ROT_FOUR; - break; - } - if (i >= oparg - 1) { - fold_rotations(inst - oparg + 1, oparg); - } - break; - case COPY: + case SWAP: if (oparg == 1) { - inst->i_opcode = DUP_TOP; + INSTR_SET_OP0(inst, NOP); + break; + } + if (swaptimize(bb, &i)) { + goto error; + } + apply_static_swaps(bb, i); + break; + case KW_NAMES: + break; + case PUSH_NULL: + if (nextop == LOAD_GLOBAL && (inst[1].i_opcode & 1) == 0) { + INSTR_SET_OP0(inst, NOP); + inst[1].i_oparg |= 1; } break; default: @@ -8303,40 +9439,37 @@ error: return -1; } -/* If this block ends with an unconditional jump to an exit block, - * then remove the jump and extend this block with the target. +/* If this block ends with an unconditional jump to a small exit block, then + * remove the jump and extend this block with the target. + * Returns 1 if extended, 0 if no change, and -1 on error. */ static int -extend_block(basicblock *bb) { - if (bb->b_iused == 0) { +inline_small_exit_blocks(basicblock *bb) { + struct instr *last = basicblock_last_instr(bb); + if (last == NULL) { return 0; } - struct instr *last = &bb->b_instr[bb->b_iused-1]; - if (last->i_opcode != JUMP_ABSOLUTE && last->i_opcode != JUMP_FORWARD) { + if (!IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) { return 0; } - if (last->i_target->b_exit && last->i_target->b_iused <= MAX_COPY_SIZE) { - basicblock *to_copy = last->i_target; - last->i_opcode = NOP; - for (int i = 0; i < to_copy->b_iused; i++) { - int index = compiler_next_instr(bb); - if (index < 0) { - return -1; - } - bb->b_instr[index] = to_copy->b_instr[i]; + basicblock *target = last->i_target; + if (basicblock_exits_scope(target) && target->b_iused <= MAX_COPY_SIZE) { + INSTR_SET_OP0(last, NOP); + if (basicblock_append_instructions(bb, target) < 0) { + return -1; } - bb->b_exit = 1; + return 1; } return 0; } -static void -clean_basic_block(basicblock *bb) { +static int +remove_redundant_nops(basicblock *bb) { /* Remove NOPs when legal to do so. */ int dest = 0; int prev_lineno = -1; for (int src = 0; src < bb->b_iused; src++) { - int lineno = bb->b_instr[src].i_lineno; + int lineno = bb->b_instr[src].i_loc.lineno; if (bb->b_instr[src].i_opcode == NOP) { /* Eliminate no-op if it doesn't have a line number */ if (lineno < 0) { @@ -8348,9 +9481,12 @@ clean_basic_block(basicblock *bb) { } /* or, if the next instruction has same line number or no line number */ if (src < bb->b_iused - 1) { - int next_lineno = bb->b_instr[src+1].i_lineno; - if (next_lineno < 0 || next_lineno == lineno) { - COPY_INSTR_LOC(bb->b_instr[src], bb->b_instr[src+1]); + int next_lineno = bb->b_instr[src+1].i_loc.lineno; + if (next_lineno == lineno) { + continue; + } + if (next_lineno < 0) { + bb->b_instr[src+1].i_loc = bb->b_instr[src].i_loc; continue; } } @@ -8361,7 +9497,7 @@ clean_basic_block(basicblock *bb) { } /* or if last instruction in BB and next BB has same line number */ if (next) { - if (lineno == next->b_instr[0].i_lineno) { + if (lineno == next->b_instr[0].i_loc.lineno) { continue; } } @@ -8375,99 +9511,90 @@ clean_basic_block(basicblock *bb) { prev_lineno = lineno; } assert(dest <= bb->b_iused); + int num_removed = bb->b_iused - dest; bb->b_iused = dest; + return num_removed; } static int -normalize_basic_block(basicblock *bb) { - /* Mark blocks as exit and/or nofallthrough. - Raise SystemError if CFG is malformed. */ - for (int i = 0; i < bb->b_iused; i++) { - switch(bb->b_instr[i].i_opcode) { - case RETURN_VALUE: - case RAISE_VARARGS: - case RERAISE: - case POP_EXCEPT_AND_RERAISE: - bb->b_exit = 1; - bb->b_nofallthrough = 1; - break; - case JUMP_ABSOLUTE: - case JUMP_FORWARD: - bb->b_nofallthrough = 1; - /* fall through */ - case POP_JUMP_IF_FALSE: - case POP_JUMP_IF_TRUE: - case JUMP_IF_FALSE_OR_POP: - case JUMP_IF_TRUE_OR_POP: - case FOR_ITER: - if (i != bb->b_iused-1) { +check_cfg(cfg_builder *g) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + /* Raise SystemError if jump or exit is not last instruction in the block. */ + for (int i = 0; i < b->b_iused; i++) { + int opcode = b->b_instr[i].i_opcode; + assert(!IS_ASSEMBLER_OPCODE(opcode)); + if (IS_TERMINATOR_OPCODE(opcode)) { + if (i != b->b_iused - 1) { PyErr_SetString(PyExc_SystemError, "malformed control flow graph."); return -1; } - /* Skip over empty basic blocks. */ - while (bb->b_instr[i].i_target->b_iused == 0) { - bb->b_instr[i].i_target = bb->b_instr[i].i_target->b_next; - } - + } } } return 0; } static int -mark_reachable(struct assembler *a) { - basicblock **stack, **sp; - sp = stack = (basicblock **)PyObject_Malloc(sizeof(basicblock *) * a->a_nblocks); +mark_reachable(basicblock *entryblock) { + basicblock **stack = make_cfg_traversal_stack(entryblock); if (stack == NULL) { return -1; } - a->a_entry->b_predecessors = 1; - *sp++ = a->a_entry; + basicblock **sp = stack; + entryblock->b_predecessors = 1; + *sp++ = entryblock; while (sp > stack) { basicblock *b = *(--sp); - if (b->b_next && !b->b_nofallthrough) { - if (b->b_next->b_predecessors == 0) { + b->b_visited = 1; + if (b->b_next && BB_HAS_FALLTHROUGH(b)) { + if (!b->b_next->b_visited) { + assert(b->b_next->b_predecessors == 0); *sp++ = b->b_next; } b->b_next->b_predecessors++; } for (int i = 0; i < b->b_iused; i++) { basicblock *target; - if (is_jump(&b->b_instr[i])) { - target = b->b_instr[i].i_target; - if (target->b_predecessors == 0) { + struct instr *instr = &b->b_instr[i]; + if (is_jump(instr) || is_block_push(instr)) { + target = instr->i_target; + if (!target->b_visited) { + assert(target->b_predecessors == 0 || target == b->b_next); *sp++ = target; } target->b_predecessors++; } } } - PyObject_Free(stack); + PyMem_Free(stack); return 0; } static void -eliminate_empty_basic_blocks(basicblock *entry) { +eliminate_empty_basic_blocks(cfg_builder *g) { /* Eliminate empty blocks */ - for (basicblock *b = entry; b != NULL; b = b->b_next) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { basicblock *next = b->b_next; - if (next) { - while (next->b_iused == 0 && next->b_next) { - next = next->b_next; - } - b->b_next = next; + while (next && next->b_iused == 0) { + next = next->b_next; } + b->b_next = next; } - for (basicblock *b = entry; b != NULL; b = b->b_next) { - if (b->b_iused == 0) { - continue; - } - if (is_jump(&b->b_instr[b->b_iused-1])) { - basicblock *target = b->b_instr[b->b_iused-1].i_target; - while (target->b_iused == 0) { - target = target->b_next; + while(g->g_entryblock && g->g_entryblock->b_iused == 0) { + g->g_entryblock = g->g_entryblock->b_next; + } + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + assert(b->b_iused > 0); + for (int i = 0; i < b->b_iused; i++) { + struct instr *instr = &b->b_instr[i]; + if (HAS_TARGET(instr->i_opcode)) { + basicblock *target = instr->i_target; + while (target->b_iused == 0) { + target = target->b_next; + } + instr->i_target = target; + assert(instr->i_target && instr->i_target->b_iused > 0); } - b->b_instr[b->b_iused-1].i_target = target; } } } @@ -8481,146 +9608,246 @@ eliminate_empty_basic_blocks(basicblock *entry) { * but has no impact on the generated line number events. */ static void -propagate_line_numbers(struct assembler *a) { - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - if (b->b_iused == 0) { +propagate_line_numbers(basicblock *entryblock) { + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + struct instr *last = basicblock_last_instr(b); + if (last == NULL) { continue; } - // Not a real instruction, only to store positions - // from previous instructions and propagate them. - struct instr prev_instr = { - .i_lineno = -1, - .i_col_offset = -1, - .i_end_lineno = -1, - .i_end_col_offset = -1, - }; + location prev_location = NO_LOCATION; for (int i = 0; i < b->b_iused; i++) { - if (b->b_instr[i].i_lineno < 0) { - COPY_INSTR_LOC(prev_instr, b->b_instr[i]); + if (b->b_instr[i].i_loc.lineno < 0) { + b->b_instr[i].i_loc = prev_location; } else { - COPY_INSTR_LOC(b->b_instr[i], prev_instr); + prev_location = b->b_instr[i].i_loc; } } - if (!b->b_nofallthrough && b->b_next->b_predecessors == 1) { + if (BB_HAS_FALLTHROUGH(b) && b->b_next->b_predecessors == 1) { assert(b->b_next->b_iused); - if (b->b_next->b_instr[0].i_lineno < 0) { - COPY_INSTR_LOC(prev_instr, b->b_next->b_instr[0]); + if (b->b_next->b_instr[0].i_loc.lineno < 0) { + b->b_next->b_instr[0].i_loc = prev_location; } } - if (is_jump(&b->b_instr[b->b_iused-1])) { - switch (b->b_instr[b->b_iused-1].i_opcode) { - /* Note: Only actual jumps, not exception handlers */ - case SETUP_WITH: - case SETUP_FINALLY: - case SETUP_CLEANUP: - continue; - } - basicblock *target = b->b_instr[b->b_iused-1].i_target; + if (is_jump(last)) { + basicblock *target = last->i_target; if (target->b_predecessors == 1) { - if (target->b_instr[0].i_lineno < 0) { - COPY_INSTR_LOC(prev_instr, target->b_instr[0]); + if (target->b_instr[0].i_loc.lineno < 0) { + target->b_instr[0].i_loc = prev_location; } } } } } + +/* Calculate the actual jump target from the target_label */ +static int +translate_jump_labels_to_targets(basicblock *entryblock) +{ + int max_label = -1; + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + if (b->b_label > max_label) { + max_label = b->b_label; + } + } + size_t mapsize = sizeof(basicblock *) * (max_label + 1); + basicblock **label2block = (basicblock **)PyMem_Malloc(mapsize); + if (!label2block) { + PyErr_NoMemory(); + return -1; + } + memset(label2block, 0, mapsize); + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + if (b->b_label >= 0) { + label2block[b->b_label] = b; + } + } + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (int i = 0; i < b->b_iused; i++) { + struct instr *instr = &b->b_instr[i]; + assert(instr->i_target == NULL); + if (HAS_TARGET(instr->i_opcode)) { + int lbl = instr->i_oparg; + assert(lbl >= 0 && lbl <= max_label); + instr->i_target = label2block[lbl]; + assert(instr->i_target != NULL); + assert(instr->i_target->b_label == lbl); + } + } + } + PyMem_Free(label2block); + return 0; +} + /* Perform optimizations on a control flow graph. The consts object should still be in list form to allow new constants to be appended. - All transformations keep the code size the same or smaller. - For those that reduce size, the gaps are initially filled with + Code trasnformations that reduce code size initially fill the gaps with NOPs. Later those NOPs are removed. */ static int -optimize_cfg(struct compiler *c, struct assembler *a, PyObject *consts) +optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache) { - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - if (optimize_basic_block(c, b, consts)) { + assert(PyDict_CheckExact(const_cache)); + if (check_cfg(g) < 0) { + return -1; + } + eliminate_empty_basic_blocks(g); + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + if (inline_small_exit_blocks(b) < 0) { return -1; } - clean_basic_block(b); + } + assert(no_empty_basic_blocks(g)); + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + if (optimize_basic_block(const_cache, b, consts)) { + return -1; + } + remove_redundant_nops(b); assert(b->b_predecessors == 0); } - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - if (extend_block(b)) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + if (inline_small_exit_blocks(b) < 0) { return -1; } } - if (mark_reachable(a)) { + if (mark_reachable(g->g_entryblock)) { return -1; } /* Delete unreachable instructions */ - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { if (b->b_predecessors == 0) { b->b_iused = 0; - b->b_nofallthrough = 0; } } - eliminate_empty_basic_blocks(a->a_entry); - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - clean_basic_block(b); + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + remove_redundant_nops(b); } - /* Delete jump instructions made redundant by previous step. If a non-empty - block ends with a jump instruction, check if the next non-empty block - reached through normal flow control is the target of that jump. If it - is, then the jump instruction is redundant and can be deleted. - */ - int maybe_empty_blocks = 0; - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - if (b->b_iused > 0) { - struct instr *b_last_instr = &b->b_instr[b->b_iused - 1]; - if (b_last_instr->i_opcode == JUMP_ABSOLUTE || - b_last_instr->i_opcode == JUMP_FORWARD) { - if (b_last_instr->i_target == b->b_next) { - assert(b->b_next->b_iused); - b->b_nofallthrough = 0; - b_last_instr->i_opcode = NOP; - maybe_empty_blocks = 1; - } - } - } - } - if (maybe_empty_blocks) { - eliminate_empty_basic_blocks(a->a_entry); + eliminate_empty_basic_blocks(g); + assert(no_redundant_nops(g)); + if (remove_redundant_jumps(g) < 0) { + return -1; } return 0; } -// Remove trailing unused constants. + static int -trim_unused_consts(struct compiler *c, struct assembler *a, PyObject *consts) +remove_unused_consts(basicblock *entryblock, PyObject *consts) { assert(PyList_CheckExact(consts)); + Py_ssize_t nconsts = PyList_GET_SIZE(consts); + if (nconsts == 0) { + return 0; /* nothing to do */ + } + Py_ssize_t *index_map = NULL; + Py_ssize_t *reverse_index_map = NULL; + int err = 1; + + index_map = PyMem_Malloc(nconsts * sizeof(Py_ssize_t)); + if (index_map == NULL) { + goto end; + } + for (Py_ssize_t i = 1; i < nconsts; i++) { + index_map[i] = -1; + } // The first constant may be docstring; keep it always. - int max_const_index = 0; - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { + index_map[0] = 0; + + /* mark used consts */ + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { for (int i = 0; i < b->b_iused; i++) { - if (b->b_instr[i].i_opcode == LOAD_CONST && - b->b_instr[i].i_oparg > max_const_index) { - max_const_index = b->b_instr[i].i_oparg; + if (b->b_instr[i].i_opcode == LOAD_CONST || + b->b_instr[i].i_opcode == KW_NAMES) { + + int index = b->b_instr[i].i_oparg; + index_map[index] = index; } } } - if (max_const_index+1 < PyList_GET_SIZE(consts)) { - //fprintf(stderr, "removing trailing consts: max=%d, size=%d\n", - // max_const_index, (int)PyList_GET_SIZE(consts)); - if (PyList_SetSlice(consts, max_const_index+1, - PyList_GET_SIZE(consts), NULL) < 0) { - return 1; + /* now index_map[i] == i if consts[i] is used, -1 otherwise */ + + /* condense consts */ + Py_ssize_t n_used_consts = 0; + for (int i = 0; i < nconsts; i++) { + if (index_map[i] != -1) { + assert(index_map[i] == i); + index_map[n_used_consts++] = index_map[i]; } } - return 0; + if (n_used_consts == nconsts) { + /* nothing to do */ + err = 0; + goto end; + } + + /* move all used consts to the beginning of the consts list */ + assert(n_used_consts < nconsts); + for (Py_ssize_t i = 0; i < n_used_consts; i++) { + Py_ssize_t old_index = index_map[i]; + assert(i <= old_index && old_index < nconsts); + if (i != old_index) { + PyObject *value = PyList_GET_ITEM(consts, index_map[i]); + assert(value != NULL); + PyList_SetItem(consts, i, Py_NewRef(value)); + } + } + + /* truncate the consts list at its new size */ + if (PyList_SetSlice(consts, n_used_consts, nconsts, NULL) < 0) { + goto end; + } + + /* adjust const indices in the bytecode */ + reverse_index_map = PyMem_Malloc(nconsts * sizeof(Py_ssize_t)); + if (reverse_index_map == NULL) { + goto end; + } + for (Py_ssize_t i = 0; i < nconsts; i++) { + reverse_index_map[i] = -1; + } + for (Py_ssize_t i = 0; i < n_used_consts; i++) { + assert(index_map[i] != -1); + assert(reverse_index_map[index_map[i]] == -1); + reverse_index_map[index_map[i]] = i; + } + + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (int i = 0; i < b->b_iused; i++) { + if (b->b_instr[i].i_opcode == LOAD_CONST || + b->b_instr[i].i_opcode == KW_NAMES) { + + int index = b->b_instr[i].i_oparg; + assert(reverse_index_map[index] >= 0); + assert(reverse_index_map[index] < n_used_consts); + b->b_instr[i].i_oparg = (int)reverse_index_map[index]; + } + } + } + + err = 0; +end: + PyMem_Free(index_map); + PyMem_Free(reverse_index_map); + return err; } -static inline int +static inline bool is_exit_without_lineno(basicblock *b) { - return b->b_exit && b->b_instr[0].i_lineno < 0; + if (!basicblock_exits_scope(b)) { + return false; + } + for (int i = 0; i < b->b_iused; i++) { + if (b->b_instr[i].i_loc.lineno >= 0) { + return false; + } + } + return true; } /* PEP 626 mandates that the f_lineno of a frame is correct @@ -8633,27 +9860,24 @@ is_exit_without_lineno(basicblock *b) { * copy the line number from the sole predecessor block. */ static int -duplicate_exits_without_lineno(struct compiler *c) +duplicate_exits_without_lineno(cfg_builder *g) { + assert(no_empty_basic_blocks(g)); /* Copy all exit blocks without line number that are targets of a jump. */ - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - if (b->b_iused > 0 && is_jump(&b->b_instr[b->b_iused-1])) { - switch (b->b_instr[b->b_iused-1].i_opcode) { - /* Note: Only actual jumps, not exception handlers */ - case SETUP_WITH: - case SETUP_FINALLY: - case SETUP_CLEANUP: - continue; - } - basicblock *target = b->b_instr[b->b_iused-1].i_target; + basicblock *entryblock = g->g_entryblock; + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + struct instr *last = basicblock_last_instr(b); + assert(last != NULL); + if (is_jump(last)) { + basicblock *target = last->i_target; if (is_exit_without_lineno(target) && target->b_predecessors > 1) { - basicblock *new_target = compiler_copy_block(c, target); + basicblock *new_target = copy_basicblock(g, target); if (new_target == NULL) { return -1; } - COPY_INSTR_LOC(b->b_instr[b->b_iused-1], new_target->b_instr[0]); - b->b_instr[b->b_iused-1].i_target = new_target; + new_target->b_instr[0].i_loc = last->i_loc; + last->i_target = new_target; target->b_predecessors--; new_target->b_predecessors = 1; new_target->b_next = target->b_next; @@ -8661,19 +9885,15 @@ duplicate_exits_without_lineno(struct compiler *c) } } } - /* Eliminate empty blocks */ - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - while (b->b_next && b->b_next->b_iused == 0) { - b->b_next = b->b_next->b_next; - } - } + /* Any remaining reachable exit blocks without line number can only be reached by * fall through, and thus can only have a single predecessor */ - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - if (!b->b_nofallthrough && b->b_next && b->b_iused > 0) { + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + if (BB_HAS_FALLTHROUGH(b) && b->b_next && b->b_iused > 0) { if (is_exit_without_lineno(b->b_next)) { - assert(b->b_next->b_iused > 0); - COPY_INSTR_LOC(b->b_instr[b->b_iused-1], b->b_next->b_instr[0]); + struct instr *last = basicblock_last_instr(b); + assert(last != NULL); + b->b_next->b_instr[0].i_loc = last->i_loc; } } } @@ -8681,6 +9901,208 @@ duplicate_exits_without_lineno(struct compiler *c) } +/* Access to compiler optimizations for unit tests. + * + * _PyCompile_CodeGen takes and AST, applies code-gen and + * returns the unoptimized CFG as an instruction list. + * + * _PyCompile_OptimizeCfg takes an instruction list, constructs + * a CFG, optimizes it and converts back to an instruction list. + * + * An instruction list is a PyList where each item is either + * a tuple describing a single instruction: + * (opcode, oparg, lineno, end_lineno, col, end_col), or + * a jump target label marking the beginning of a basic block. + */ + +static int +instructions_to_cfg(PyObject *instructions, cfg_builder *g) +{ + assert(PyList_Check(instructions)); + + Py_ssize_t instr_size = PyList_GET_SIZE(instructions); + for (Py_ssize_t i = 0; i < instr_size; i++) { + PyObject *item = PyList_GET_ITEM(instructions, i); + if (PyLong_Check(item)) { + int lbl_id = PyLong_AsLong(item); + if (PyErr_Occurred()) { + return -1; + } + if (lbl_id <= 0 || lbl_id > instr_size) { + /* expect label in a reasonable range */ + PyErr_SetString(PyExc_ValueError, "label out of range"); + return -1; + } + jump_target_label lbl = {lbl_id}; + if (cfg_builder_use_label(g, lbl) < 0) { + return -1; + } + } + else { + if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 6) { + PyErr_SetString(PyExc_ValueError, "expected a 6-tuple"); + return -1; + } + int opcode = PyLong_AsLong(PyTuple_GET_ITEM(item, 0)); + if (PyErr_Occurred()) { + return -1; + } + int oparg = PyLong_AsLong(PyTuple_GET_ITEM(item, 1)); + if (PyErr_Occurred()) { + return -1; + } + location loc; + loc.lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 2)); + if (PyErr_Occurred()) { + return -1; + } + loc.end_lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 3)); + if (PyErr_Occurred()) { + return -1; + } + loc.col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 4)); + if (PyErr_Occurred()) { + return -1; + } + loc.end_col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 5)); + if (PyErr_Occurred()) { + return -1; + } + if (cfg_builder_addop(g, opcode, oparg, loc) < 0) { + return -1; + } + } + } + return 0; +} + +static PyObject * +cfg_to_instructions(cfg_builder *g) +{ + PyObject *instructions = PyList_New(0); + if (instructions == NULL) { + return NULL; + } + int lbl = 1; + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + b->b_label = lbl++; + } + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + PyObject *lbl = PyLong_FromLong(b->b_label); + if (lbl == NULL) { + goto error; + } + if (PyList_Append(instructions, lbl) != 0) { + Py_DECREF(lbl); + goto error; + } + Py_DECREF(lbl); + for (int i = 0; i < b->b_iused; i++) { + struct instr *instr = &b->b_instr[i]; + location loc = instr->i_loc; + int arg = HAS_TARGET(instr->i_opcode) ? + instr->i_target->b_label : instr->i_oparg; + + PyObject *inst_tuple = Py_BuildValue( + "(iiiiii)", instr->i_opcode, arg, + loc.lineno, loc.end_lineno, + loc.col_offset, loc.end_col_offset); + if (inst_tuple == NULL) { + goto error; + } + + if (PyList_Append(instructions, inst_tuple) != 0) { + Py_DECREF(inst_tuple); + goto error; + } + Py_DECREF(inst_tuple); + } + } + + return instructions; +error: + Py_DECREF(instructions); + return NULL; +} + +PyObject * +_PyCompile_CodeGen(PyObject *ast, PyObject *filename, PyCompilerFlags *pflags, + int optimize) +{ + PyObject *res = NULL; + + if (!PyAST_Check(ast)) { + PyErr_SetString(PyExc_TypeError, "expected an AST"); + return NULL; + } + + PyArena *arena = _PyArena_New(); + if (arena == NULL) { + return NULL; + } + + mod_ty mod = PyAST_obj2mod(ast, arena, 0 /* exec */); + if (mod == NULL || !_PyAST_Validate(mod)) { + _PyArena_Free(arena); + return NULL; + } + + struct compiler *c = new_compiler(mod, filename, pflags, optimize, arena); + if (c == NULL) { + _PyArena_Free(arena); + return NULL; + } + + if (compiler_codegen(c, mod) < 0) { + goto finally; + } + + cfg_builder *g = CFG_BUILDER(c); + + if (translate_jump_labels_to_targets(g->g_entryblock) < 0) { + goto finally; + } + + res = cfg_to_instructions(g); + +finally: + compiler_exit_scope(c); + compiler_free(c); + _PyArena_Free(arena); + return res; +} + +PyObject * +_PyCompile_OptimizeCfg(PyObject *instructions, PyObject *consts) +{ + PyObject *res = NULL; + PyObject *const_cache = NULL; + cfg_builder g; + memset(&g, 0, sizeof(cfg_builder)); + if (cfg_builder_init(&g) < 0) { + goto error; + } + if (instructions_to_cfg(instructions, &g) < 0) { + goto error; + } + const_cache = PyDict_New(); + if (const_cache == NULL) { + goto error; + } + if (translate_jump_labels_to_targets(g.g_entryblock)) { + goto error; + } + if (optimize_cfg(&g, consts, const_cache) < 0) { + goto error; + } + res = cfg_to_instructions(&g); +error: + Py_XDECREF(const_cache); + cfg_builder_fini(&g); + return res; +} + + /* Retained for API compatibility. * Optimization is now done in optimize_cfg */ @@ -8688,6 +10110,5 @@ PyObject * PyCode_Optimize(PyObject *code, PyObject* Py_UNUSED(consts), PyObject *Py_UNUSED(names), PyObject *Py_UNUSED(lnotab_obj)) { - Py_INCREF(code); - return code; + return Py_NewRef(code); } diff --git a/Python/condvar.h b/Python/condvar.h index e5df7ff1328..4ddc5311cf8 100644 --- a/Python/condvar.h +++ b/Python/condvar.h @@ -68,9 +68,9 @@ void _PyThread_cond_after(long long us, struct timespec *abs); Py_LOCAL_INLINE(int) PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long long us) { - struct timespec abs; - _PyThread_cond_after(us, &abs); - int ret = pthread_cond_timedwait(cond, mut, &abs); + struct timespec abs_timeout; + _PyThread_cond_after(us, &abs_timeout); + int ret = pthread_cond_timedwait(cond, mut, &abs_timeout); if (ret == ETIMEDOUT) { return 1; } diff --git a/Python/context.c b/Python/context.c index a20ec712373..5d385508405 100644 --- a/Python/context.c +++ b/Python/context.c @@ -3,6 +3,7 @@ #include "pycore_context.h" #include "pycore_gc.h" // _PyObject_GC_MAY_BE_TRACKED() #include "pycore_hamt.h" +#include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_object.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" // _PyThreadState_GET() @@ -123,8 +124,7 @@ _PyContext_Enter(PyThreadState *ts, PyObject *octx) ctx->ctx_prev = (PyContext *)ts->context; /* borrow */ ctx->ctx_entered = 1; - Py_INCREF(ctx); - ts->context = (PyObject *)ctx; + ts->context = Py_NewRef(ctx); ts->context_ver++; return 0; @@ -350,6 +350,7 @@ _context_alloc(void) state->numfree--; ctx = state->freelist; state->freelist = (PyContext *)ctx->ctx_weakreflist; + OBJECT_STAT_INC(from_freelist); ctx->ctx_weakreflist = NULL; _Py_NewReference((PyObject *)ctx); } @@ -398,8 +399,7 @@ context_new_from_vars(PyHamtObject *vars) return NULL; } - Py_INCREF(vars); - ctx->ctx_vars = vars; + ctx->ctx_vars = (PyHamtObject*)Py_NewRef(vars); _PyObject_GC_TRACK(ctx); return ctx; @@ -481,6 +481,7 @@ context_tp_dealloc(PyContext *self) state->numfree++; self->ctx_weakreflist = (PyObject *)state->freelist; state->freelist = self; + OBJECT_STAT_INC(to_freelist); } else #endif @@ -543,8 +544,7 @@ context_tp_subscript(PyContext *self, PyObject *key) PyErr_SetObject(PyExc_KeyError, key); return NULL; } - Py_INCREF(val); - return val; + return Py_NewRef(val); } static int @@ -585,11 +585,9 @@ _contextvars_Context_get_impl(PyContext *self, PyObject *key, return NULL; } if (found == 0) { - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } - Py_INCREF(val); - return val; + return Py_NewRef(val); } @@ -684,7 +682,7 @@ static PyMethodDef PyContext_methods[] = { _CONTEXTVARS_CONTEXT_KEYS_METHODDEF _CONTEXTVARS_CONTEXT_VALUES_METHODDEF _CONTEXTVARS_CONTEXT_COPY_METHODDEF - {"run", (PyCFunction)(void(*)(void))context_run, METH_FASTCALL | METH_KEYWORDS, NULL}, + {"run", _PyCFunction_CAST(context_run), METH_FASTCALL | METH_KEYWORDS, NULL}, {NULL, NULL} }; @@ -828,11 +826,9 @@ contextvar_new(PyObject *name, PyObject *def) return NULL; } - Py_INCREF(name); - var->var_name = name; + var->var_name = Py_NewRef(name); - Py_XINCREF(def); - var->var_default = def; + var->var_default = Py_XNewRef(def); var->var_cached = NULL; var->var_cached_tsid = 0; @@ -1173,8 +1169,7 @@ error: static PyObject * token_get_var(PyContextToken *self, void *Py_UNUSED(ignored)) { - Py_INCREF(self->tok_var); - return (PyObject *)self->tok_var; + return Py_NewRef(self->tok_var);; } static PyObject * @@ -1184,8 +1179,7 @@ token_get_old_value(PyContextToken *self, void *Py_UNUSED(ignored)) return get_token_missing(); } - Py_INCREF(self->tok_oldval); - return self->tok_oldval; + return Py_NewRef(self->tok_oldval); } static PyGetSetDef PyContextTokenType_getsetlist[] = { @@ -1225,14 +1219,11 @@ token_new(PyContext *ctx, PyContextVar *var, PyObject *val) return NULL; } - Py_INCREF(ctx); - tok->tok_ctx = ctx; + tok->tok_ctx = (PyContext*)Py_NewRef(ctx); - Py_INCREF(var); - tok->tok_var = var; + tok->tok_var = (PyContextVar*)Py_NewRef(var); - Py_XINCREF(val); - tok->tok_oldval = val; + tok->tok_oldval = Py_XNewRef(val); tok->tok_used = 0; @@ -1244,25 +1235,29 @@ token_new(PyContext *ctx, PyContextVar *var, PyObject *val) /////////////////////////// Token.MISSING -static PyObject *_token_missing; - - -typedef struct { - PyObject_HEAD -} PyContextTokenMissing; - - static PyObject * context_token_missing_tp_repr(PyObject *self) { return PyUnicode_FromString(""); } +static void +context_token_missing_tp_dealloc(_PyContextTokenMissing *Py_UNUSED(self)) +{ +#ifdef Py_DEBUG + /* The singleton is statically allocated. */ + _Py_FatalRefcountError("deallocating the token missing singleton"); +#else + return; +#endif +} -PyTypeObject PyContextTokenMissing_Type = { + +PyTypeObject _PyContextTokenMissing_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "Token.MISSING", - sizeof(PyContextTokenMissing), + sizeof(_PyContextTokenMissing), + .tp_dealloc = (destructor)context_token_missing_tp_dealloc, .tp_getattro = PyObject_GenericGetAttr, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_repr = context_token_missing_tp_repr, @@ -1272,19 +1267,7 @@ PyTypeObject PyContextTokenMissing_Type = { static PyObject * get_token_missing(void) { - if (_token_missing != NULL) { - Py_INCREF(_token_missing); - return _token_missing; - } - - _token_missing = (PyObject *)PyObject_New( - PyContextTokenMissing, &PyContextTokenMissing_Type); - if (_token_missing == NULL) { - return NULL; - } - - Py_INCREF(_token_missing); - return _token_missing; + return Py_NewRef(&_Py_SINGLETON(context_token_missing)); } @@ -1309,31 +1292,19 @@ _PyContext_ClearFreeList(PyInterpreterState *interp) void _PyContext_Fini(PyInterpreterState *interp) { - if (_Py_IsMainInterpreter(interp)) { - Py_CLEAR(_token_missing); - } _PyContext_ClearFreeList(interp); #if defined(Py_DEBUG) && PyContext_MAXFREELIST > 0 struct _Py_context_state *state = &interp->context; state->numfree = -1; #endif - _PyHamt_Fini(); } -int -_PyContext_Init(void) +PyStatus +_PyContext_Init(PyInterpreterState *interp) { - if (!_PyHamt_Init()) { - return 0; - } - - if ((PyType_Ready(&PyContext_Type) < 0) || - (PyType_Ready(&PyContextVar_Type) < 0) || - (PyType_Ready(&PyContextToken_Type) < 0) || - (PyType_Ready(&PyContextTokenMissing_Type) < 0)) - { - return 0; + if (!_Py_IsMainInterpreter(interp)) { + return _PyStatus_OK(); } PyObject *missing = get_token_missing(); @@ -1341,9 +1312,9 @@ _PyContext_Init(void) PyContextToken_Type.tp_dict, "MISSING", missing)) { Py_DECREF(missing); - return 0; + return _PyStatus_ERR("can't init context types"); } Py_DECREF(missing); - return 1; + return _PyStatus_OK(); } diff --git a/Python/deepfreeze/README.txt b/Python/deepfreeze/README.txt index da55d4e7c74..276ab51143a 100644 --- a/Python/deepfreeze/README.txt +++ b/Python/deepfreeze/README.txt @@ -3,4 +3,4 @@ modules. Python/frozen.c depends on these files. None of these files are committed into the repo. -See Tools/scripts/freeze_modules.py for more info. +See Tools/build/freeze_modules.py for more info. diff --git a/Python/dtoa.c b/Python/dtoa.c index 6c44f689651..cff5f1b0658 100644 --- a/Python/dtoa.c +++ b/Python/dtoa.c @@ -118,12 +118,13 @@ /* Linking of Python's #defines to Gay's #defines starts here. */ #include "Python.h" -#include "pycore_dtoa.h" +#include "pycore_dtoa.h" // _PY_SHORT_FLOAT_REPR +#include "pycore_runtime.h" // _PyRuntime #include // exit() -/* if PY_NO_SHORT_FLOAT_REPR is defined, then don't even try to compile +/* if _PY_SHORT_FLOAT_REPR == 0, then don't even try to compile the following code */ -#ifndef PY_NO_SHORT_FLOAT_REPR +#if _PY_SHORT_FLOAT_REPR == 1 #include "float.h" @@ -156,7 +157,7 @@ #endif -typedef uint32_t ULong; +// ULong is defined in pycore_dtoa.h. typedef int32_t Long; typedef uint64_t ULLong; @@ -171,12 +172,6 @@ typedef uint64_t ULLong; #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} #endif -#ifndef PRIVATE_MEM -#define PRIVATE_MEM 2304 -#endif -#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) -static double private_mem[PRIVATE_mem], *pmem_next = private_mem; - #ifdef __cplusplus extern "C" { #endif @@ -298,8 +293,6 @@ BCinfo { #define FFFFFFFF 0xffffffffUL -#define Kmax 7 - /* struct Bigint is used to represent arbitrary-precision integers. These integers are stored in sign-magnitude format, with the magnitude stored as an array of base 2**32 digits. Bigints are always normalized: if x is a @@ -322,13 +315,7 @@ BCinfo { significant (x[0]) to most significant (x[wds-1]). */ -struct -Bigint { - struct Bigint *next; - int k, maxwds, sign, wds; - ULong x[1]; -}; - +// struct Bigint is defined in pycore_dtoa.h. typedef struct Bigint Bigint; #ifndef Py_USING_MEMORY_DEBUGGER @@ -352,7 +339,9 @@ typedef struct Bigint Bigint; Bfree to PyMem_Free. Investigate whether this has any significant performance on impact. */ -static Bigint *freelist[Kmax+1]; +#define freelist _PyRuntime.dtoa.freelist +#define private_mem _PyRuntime.dtoa.preallocated +#define pmem_next _PyRuntime.dtoa.preallocated_next /* Allocate space for a Bigint with up to 1<next; else { x = 1 << k; len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) /sizeof(double); - if (k <= Kmax && pmem_next - private_mem + len <= (Py_ssize_t)PRIVATE_mem) { + if (k <= Bigint_Kmax && + pmem_next - private_mem + len <= (Py_ssize_t)Bigint_PREALLOC_SIZE + ) { rv = (Bigint*)pmem_next; pmem_next += len; } @@ -391,7 +382,7 @@ static void Bfree(Bigint *v) { if (v) { - if (v->k > Kmax) + if (v->k > Bigint_Kmax) FREE((void*)v); else { v->next = freelist[v->k]; @@ -400,6 +391,10 @@ Bfree(Bigint *v) } } +#undef pmem_next +#undef private_mem +#undef freelist + #else /* Alternative versions of Balloc and Bfree that use PyMem_Malloc and @@ -678,10 +673,6 @@ mult(Bigint *a, Bigint *b) #ifndef Py_USING_MEMORY_DEBUGGER -/* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */ - -static Bigint *p5s; - /* multiply the Bigint b by 5**k. Returns a pointer to the result, or NULL on failure; if the returned pointer is distinct from b then the original Bigint b will have been Bfree'd. Ignores the sign of b. */ @@ -701,7 +692,7 @@ pow5mult(Bigint *b, int k) if (!(k >>= 2)) return b; - p5 = p5s; + p5 = _PyRuntime.dtoa.p5s; if (!p5) { /* first time */ p5 = i2b(625); @@ -709,7 +700,7 @@ pow5mult(Bigint *b, int k) Bfree(b); return NULL; } - p5s = p5; + _PyRuntime.dtoa.p5s = p5; p5->next = 0; } for(;;) { @@ -2857,4 +2848,4 @@ _Py_dg_dtoa(double dd, int mode, int ndigits, } #endif -#endif /* PY_NO_SHORT_FLOAT_REPR */ +#endif // _PY_SHORT_FLOAT_REPR == 1 diff --git a/Python/dup2.c b/Python/dup2.c index 7c6bbfce11d..a1df0492099 100644 --- a/Python/dup2.c +++ b/Python/dup2.c @@ -11,6 +11,7 @@ * Return fd2 if all went well; return BADEXIT otherwise. */ +#include #include #include @@ -20,12 +21,17 @@ int dup2(int fd1, int fd2) { if (fd1 != fd2) { +#ifdef F_DUPFD if (fcntl(fd1, F_GETFL) < 0) return BADEXIT; if (fcntl(fd2, F_GETFL) >= 0) close(fd2); if (fcntl(fd1, F_DUPFD, fd2) < 0) return BADEXIT; +#else + errno = ENOTSUP; + return BADEXIT; +#endif } return fd2; } diff --git a/Python/dynload_win.c b/Python/dynload_win.c index 5702ab2cd71..c03bc5602bf 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -2,6 +2,8 @@ /* Support for dynamic loading of extension modules */ #include "Python.h" +#include "pycore_fileutils.h" // _Py_add_relfile() +#include "pycore_pystate.h" // _PyInterpreterState_GET() #ifdef HAVE_DIRECT_H #include @@ -160,6 +162,60 @@ static char *GetPythonImport (HINSTANCE hModule) return NULL; } +/* Load python3.dll before loading any extension module that might refer + to it. That way, we can be sure that always the python3.dll corresponding + to this python DLL is loaded, not a python3.dll that might be on the path + by chance. + Return whether the DLL was found. +*/ +extern HMODULE PyWin_DLLhModule; +static int +_Py_CheckPython3(void) +{ + static int python3_checked = 0; + static HANDLE hPython3; + #define MAXPATHLEN 512 + wchar_t py3path[MAXPATHLEN+1]; + if (python3_checked) { + return hPython3 != NULL; + } + python3_checked = 1; + + /* If there is a python3.dll next to the python3y.dll, + use that DLL */ + if (PyWin_DLLhModule && GetModuleFileNameW(PyWin_DLLhModule, py3path, MAXPATHLEN)) { + wchar_t *p = wcsrchr(py3path, L'\\'); + if (p) { + wcscpy(p + 1, PY3_DLLNAME); + hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + if (hPython3 != NULL) { + return 1; + } + } + } + + /* If we can locate python3.dll in our application dir, + use that DLL */ + hPython3 = LoadLibraryExW(PY3_DLLNAME, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR); + if (hPython3 != NULL) { + return 1; + } + + /* For back-compat, also search {sys.prefix}\DLLs, though + that has not been a normal install layout for a while */ + PyInterpreterState *interp = _PyInterpreterState_GET(); + PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp); + assert(config->prefix); + if (config->prefix) { + wcscpy_s(py3path, MAXPATHLEN, config->prefix); + if (py3path[0] && _Py_add_relfile(py3path, L"DLLs\\" PY3_DLLNAME, MAXPATHLEN) >= 0) { + hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + } + } + return hPython3 != NULL; + #undef MAXPATHLEN +} + dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, const char *shortname, PyObject *pathname, FILE *fp) @@ -169,11 +225,7 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, _Py_CheckPython3(); -#if USE_UNICODE_WCHAR_CACHE - const wchar_t *wpathname = _PyUnicode_AsUnicode(pathname); -#else /* USE_UNICODE_WCHAR_CACHE */ wchar_t *wpathname = PyUnicode_AsWideCharString(pathname, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (wpathname == NULL) return NULL; @@ -195,9 +247,7 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); Py_END_ALLOW_THREADS -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(wpathname); -#endif /* USE_UNICODE_WCHAR_CACHE */ /* restore old error mode settings */ SetErrorMode(old_mode); diff --git a/Python/emscripten_signal.c b/Python/emscripten_signal.c new file mode 100644 index 00000000000..d617ddfeb37 --- /dev/null +++ b/Python/emscripten_signal.c @@ -0,0 +1,56 @@ +// To enable signal handling, the embedder should: +// 1. set Module.Py_EmscriptenSignalBuffer = some_shared_array_buffer; +// 2. set the Py_EMSCRIPTEN_SIGNAL_HANDLING flag to 1 as follows: +// Module.HEAP8[Module._Py_EMSCRIPTEN_SIGNAL_HANDLING] = 1 +// +// The address &Py_EMSCRIPTEN_SIGNAL_HANDLING is exported as +// Module._Py_EMSCRIPTEN_SIGNAL_HANDLING. +#include +#include "Python.h" + +EM_JS(int, _Py_CheckEmscriptenSignals_Helper, (void), { + if (!Module.Py_EmscriptenSignalBuffer) { + return 0; + } + try { + let result = Module.Py_EmscriptenSignalBuffer[0]; + Module.Py_EmscriptenSignalBuffer[0] = 0; + return result; + } catch(e) { +#if !defined(NDEBUG) + console.warn("Error occurred while trying to read signal buffer:", e); +#endif + return 0; + } +}); + +EMSCRIPTEN_KEEPALIVE int Py_EMSCRIPTEN_SIGNAL_HANDLING = 0; + +void +_Py_CheckEmscriptenSignals(void) +{ + if (!Py_EMSCRIPTEN_SIGNAL_HANDLING) { + return; + } + int signal = _Py_CheckEmscriptenSignals_Helper(); + if (signal) { + PyErr_SetInterruptEx(signal); + } +} + + +#define PY_EMSCRIPTEN_SIGNAL_INTERVAL 50 +static int emscripten_signal_clock = PY_EMSCRIPTEN_SIGNAL_INTERVAL; + +void +_Py_CheckEmscriptenSignalsPeriodically(void) +{ + if (!Py_EMSCRIPTEN_SIGNAL_HANDLING) { + return; + } + emscripten_signal_clock--; + if (emscripten_signal_clock == 0) { + emscripten_signal_clock = PY_EMSCRIPTEN_SIGNAL_INTERVAL; + _Py_CheckEmscriptenSignals(); + } +} diff --git a/Python/errors.c b/Python/errors.c index cb3938d2085..05ef62246ec 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -6,15 +6,10 @@ #include "pycore_initconfig.h" // _PyStatus_ERR() #include "pycore_pyerrors.h" // _PyErr_Format() #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_structseq.h" // _PyStructSequence_FiniType() #include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_traceback.h" // _PyTraceBack_FromFrame() -#ifndef __STDC__ -#ifndef MS_WINDOWS -extern char *strerror(int); -#endif -#endif - #include #ifdef MS_WINDOWS # include @@ -27,12 +22,6 @@ extern char *strerror(int); extern "C" { #endif -_Py_IDENTIFIER(__main__); -_Py_IDENTIFIER(__module__); -_Py_IDENTIFIER(builtins); -_Py_IDENTIFIER(stderr); -_Py_IDENTIFIER(flush); - /* Forward declarations */ static PyObject * _PyErr_FormatV(PyThreadState *tstate, PyObject *exception, @@ -48,8 +37,7 @@ _PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value, if (traceback != NULL && !PyTraceBack_Check(traceback)) { /* XXX Should never happen -- fatal error instead? */ /* Well, it could be None. */ - Py_DECREF(traceback); - traceback = NULL; + Py_SETREF(traceback, NULL); } /* Save these in locals to safeguard against recursive @@ -79,7 +67,9 @@ _PyErr_StackItem * _PyErr_GetTopmostException(PyThreadState *tstate) { _PyErr_StackItem *exc_info = tstate->exc_info; - while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && + assert(exc_info); + + while ((exc_info->exc_value == NULL || exc_info->exc_value == Py_None) && exc_info->previous_item != NULL) { exc_info = exc_info->previous_item; @@ -187,8 +177,7 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) } if (value != NULL && PyExceptionInstance_Check(value)) tb = PyException_GetTraceback(value); - Py_XINCREF(exception); - _PyErr_Restore(tstate, exception, value, tb); + _PyErr_Restore(tstate, Py_XNewRef(exception), value, tb); } void @@ -335,8 +324,7 @@ _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, set to NULL. */ if (!value) { - value = Py_None; - Py_INCREF(value); + value = Py_NewRef(Py_None); } /* Normalize the exception so that if the type is a class, the @@ -364,16 +352,13 @@ _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, if (fixed_value == NULL) { goto error; } - Py_DECREF(value); - value = fixed_value; + Py_SETREF(value, fixed_value); } /* If the class of the instance doesn't exactly match the class of the type, believe the instance. */ else if (inclass != type) { - Py_INCREF(inclass); - Py_DECREF(type); - type = inclass; + Py_SETREF(type, Py_NewRef(inclass)); } } *exc = type; @@ -465,21 +450,75 @@ PyErr_Clear(void) _PyErr_Clear(tstate); } +static PyObject* +get_exc_type(PyObject *exc_value) /* returns a borrowed ref */ +{ + if (exc_value == NULL || exc_value == Py_None) { + return Py_None; + } + else { + assert(PyExceptionInstance_Check(exc_value)); + PyObject *type = PyExceptionInstance_Class(exc_value); + assert(type != NULL); + return type; + } +} + +static PyObject* +get_exc_traceback(PyObject *exc_value) /* returns a borrowed ref */ +{ + if (exc_value == NULL || exc_value == Py_None) { + return Py_None; + } + else { + assert(PyExceptionInstance_Check(exc_value)); + PyObject *tb = PyException_GetTraceback(exc_value); + Py_XDECREF(tb); + return tb ? tb : Py_None; + } +} void _PyErr_GetExcInfo(PyThreadState *tstate, PyObject **p_type, PyObject **p_value, PyObject **p_traceback) { _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate); - *p_type = exc_info->exc_type; - *p_value = exc_info->exc_value; - *p_traceback = exc_info->exc_traceback; - Py_XINCREF(*p_type); - Py_XINCREF(*p_value); - Py_XINCREF(*p_traceback); + *p_type = Py_XNewRef(get_exc_type(exc_info->exc_value)); + *p_value = Py_XNewRef(exc_info->exc_value); + *p_traceback = Py_XNewRef(get_exc_traceback(exc_info->exc_value)); } +PyObject* +_PyErr_GetHandledException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate); + PyObject *exc = exc_info->exc_value; + if (exc == NULL || exc == Py_None) { + return NULL; + } + return Py_NewRef(exc); +} + +PyObject* +PyErr_GetHandledException(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyErr_GetHandledException(tstate); +} + +void +_PyErr_SetHandledException(PyThreadState *tstate, PyObject *exc) +{ + Py_XSETREF(tstate->exc_info->exc_value, Py_XNewRef(exc)); +} + +void +PyErr_SetHandledException(PyObject *exc) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetHandledException(tstate, exc); +} void PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) @@ -489,60 +528,72 @@ PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) } void -PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback) +PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback) { - PyObject *oldtype, *oldvalue, *oldtraceback; - PyThreadState *tstate = _PyThreadState_GET(); - - oldtype = tstate->exc_info->exc_type; - oldvalue = tstate->exc_info->exc_value; - oldtraceback = tstate->exc_info->exc_traceback; - - tstate->exc_info->exc_type = p_type; - tstate->exc_info->exc_value = p_value; - tstate->exc_info->exc_traceback = p_traceback; - - Py_XDECREF(oldtype); - Py_XDECREF(oldvalue); - Py_XDECREF(oldtraceback); + PyErr_SetHandledException(value); + Py_XDECREF(value); + /* These args are no longer used, but we still need to steal a ref */ + Py_XDECREF(type); + Py_XDECREF(traceback); } + +PyObject* +_PyErr_StackItemToExcInfoTuple(_PyErr_StackItem *err_info) +{ + PyObject *exc_value = err_info->exc_value; + + assert(exc_value == NULL || + exc_value == Py_None || + PyExceptionInstance_Check(exc_value)); + + PyObject *exc_type = get_exc_type(exc_value); + PyObject *exc_traceback = get_exc_traceback(exc_value); + + return Py_BuildValue( + "(OOO)", + exc_type ? exc_type : Py_None, + exc_value ? exc_value : Py_None, + exc_traceback ? exc_traceback : Py_None); +} + + /* Like PyErr_Restore(), but if an exception is already set, set the context associated with it. The caller is responsible for ensuring that this call won't create any cycles in the exception context chain. */ void -_PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb) +_PyErr_ChainExceptions(PyObject *typ, PyObject *val, PyObject *tb) { - if (exc == NULL) + if (typ == NULL) return; PyThreadState *tstate = _PyThreadState_GET(); - if (!PyExceptionClass_Check(exc)) { + if (!PyExceptionClass_Check(typ)) { _PyErr_Format(tstate, PyExc_SystemError, "_PyErr_ChainExceptions: " "exception %R is not a BaseException subclass", - exc); + typ); return; } if (_PyErr_Occurred(tstate)) { - PyObject *exc2, *val2, *tb2; - _PyErr_Fetch(tstate, &exc2, &val2, &tb2); - _PyErr_NormalizeException(tstate, &exc, &val, &tb); + PyObject *typ2, *val2, *tb2; + _PyErr_Fetch(tstate, &typ2, &val2, &tb2); + _PyErr_NormalizeException(tstate, &typ, &val, &tb); if (tb != NULL) { PyException_SetTraceback(val, tb); Py_DECREF(tb); } - Py_DECREF(exc); - _PyErr_NormalizeException(tstate, &exc2, &val2, &tb2); + Py_DECREF(typ); + _PyErr_NormalizeException(tstate, &typ2, &val2, &tb2); PyException_SetContext(val2, val); - _PyErr_Restore(tstate, exc2, val2, tb2); + _PyErr_Restore(tstate, typ2, val2, tb2); } else { - _PyErr_Restore(tstate, exc, val, tb); + _PyErr_Restore(tstate, typ, val, tb); } } @@ -567,7 +618,8 @@ _PyErr_ChainStackItem(_PyErr_StackItem *exc_info) } else { exc_info_given = 1; } - if (exc_info->exc_type == NULL || exc_info->exc_type == Py_None) { + + if (exc_info->exc_value == NULL || exc_info->exc_value == Py_None) { return; } @@ -579,21 +631,12 @@ _PyErr_ChainStackItem(_PyErr_StackItem *exc_info) tstate->exc_info = exc_info; } - PyObject *exc, *val, *tb; - _PyErr_Fetch(tstate, &exc, &val, &tb); - - PyObject *exc2, *val2, *tb2; - exc2 = exc_info->exc_type; - val2 = exc_info->exc_value; - tb2 = exc_info->exc_traceback; - _PyErr_NormalizeException(tstate, &exc2, &val2, &tb2); - if (tb2 != NULL) { - PyException_SetTraceback(val2, tb2); - } + PyObject *typ, *val, *tb; + _PyErr_Fetch(tstate, &typ, &val, &tb); /* _PyErr_SetObject sets the context from PyThreadState. */ - _PyErr_SetObject(tstate, exc, val); - Py_DECREF(exc); // since _PyErr_Occurred was true + _PyErr_SetObject(tstate, typ, val); + Py_DECREF(typ); // since _PyErr_Occurred was true Py_XDECREF(val); Py_XDECREF(tb); @@ -622,9 +665,9 @@ _PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception, _PyErr_Fetch(tstate, &exc, &val2, &tb); _PyErr_NormalizeException(tstate, &exc, &val2, &tb); - Py_INCREF(val); - PyException_SetCause(val2, val); - PyException_SetContext(val2, val); + PyException_SetCause(val2, Py_NewRef(val)); + PyException_SetContext(val2, Py_NewRef(val)); + Py_DECREF(val); _PyErr_Restore(tstate, exc, val2, tb); return NULL; @@ -635,11 +678,7 @@ _PyErr_FormatFromCauseTstate(PyThreadState *tstate, PyObject *exception, const char *format, ...) { va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif _PyErr_FormatVFromCause(tstate, exception, format, vargs); va_end(vargs); return NULL; @@ -650,11 +689,7 @@ _PyErr_FormatFromCause(PyObject *exception, const char *format, ...) { PyThreadState *tstate = _PyThreadState_GET(); va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif _PyErr_FormatVFromCause(tstate, exception, format, vargs); va_end(vargs); return NULL; @@ -930,9 +965,10 @@ PyObject *PyErr_SetFromWindowsErrWithFilename( #endif /* MS_WINDOWS */ -PyObject * -PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, - PyObject *name, PyObject *path) +static PyObject * +_PyErr_SetImportErrorSubclassWithNameFrom( + PyObject *exception, PyObject *msg, + PyObject *name, PyObject *path, PyObject* from_name) { PyThreadState *tstate = _PyThreadState_GET(); int issubclass; @@ -960,6 +996,10 @@ PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, if (path == NULL) { path = Py_None; } + if (from_name == NULL) { + from_name = Py_None; + } + kwargs = PyDict_New(); if (kwargs == NULL) { @@ -971,6 +1011,9 @@ PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, if (PyDict_SetItemString(kwargs, "path", path) < 0) { goto done; } + if (PyDict_SetItemString(kwargs, "name_from", from_name) < 0) { + goto done; + } error = PyObject_VectorcallDict(exception, &msg, 1, kwargs); if (error != NULL) { @@ -983,6 +1026,20 @@ done: return NULL; } + +PyObject * +PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, + PyObject *name, PyObject *path) +{ + return _PyErr_SetImportErrorSubclassWithNameFrom(exception, msg, name, path, NULL); +} + +PyObject * +_PyErr_SetImportErrorWithNameFrom(PyObject *msg, PyObject *name, PyObject *path, PyObject* from_name) +{ + return _PyErr_SetImportErrorSubclassWithNameFrom(PyExc_ImportError, msg, name, path, from_name); +} + PyObject * PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) { @@ -1043,11 +1100,7 @@ _PyErr_Format(PyThreadState *tstate, PyObject *exception, const char *format, ...) { va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif _PyErr_FormatV(tstate, exception, format, vargs); va_end(vargs); return NULL; @@ -1059,11 +1112,7 @@ PyErr_Format(PyObject *exception, const char *format, ...) { PyThreadState *tstate = _PyThreadState_GET(); va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif _PyErr_FormatV(tstate, exception, format, vargs); va_end(vargs); return NULL; @@ -1094,7 +1143,7 @@ PyErr_NewException(const char *name, PyObject *base, PyObject *dict) goto failure; } - int r = _PyDict_ContainsId(dict, &PyId___module__); + int r = PyDict_Contains(dict, &_Py_ID(__module__)); if (r < 0) { goto failure; } @@ -1103,13 +1152,11 @@ PyErr_NewException(const char *name, PyObject *base, PyObject *dict) (Py_ssize_t)(dot-name)); if (modulename == NULL) goto failure; - if (_PyDict_SetItemId(dict, &PyId___module__, modulename) != 0) + if (PyDict_SetItem(dict, &_Py_ID(__module__), modulename) != 0) goto failure; } if (PyTuple_Check(base)) { - bases = base; - /* INCREF as we create a new ref in the else branch */ - Py_INCREF(bases); + bases = Py_NewRef(base); } else { bases = PyTuple_Pack(1, base); if (bases == NULL) @@ -1185,11 +1232,15 @@ static PyStructSequence_Desc UnraisableHookArgs_desc = { PyStatus -_PyErr_InitTypes(void) +_PyErr_InitTypes(PyInterpreterState *interp) { + if (!_Py_IsMainInterpreter(interp)) { + return _PyStatus_OK(); + } + if (UnraisableHookArgsType.tp_name == NULL) { - if (PyStructSequence_InitType2(&UnraisableHookArgsType, - &UnraisableHookArgs_desc) < 0) { + if (_PyStructSequence_InitBuiltin(&UnraisableHookArgsType, + &UnraisableHookArgs_desc) < 0) { return _PyStatus_ERR("failed to initialize UnraisableHookArgs type"); } } @@ -1197,6 +1248,17 @@ _PyErr_InitTypes(void) } +void +_PyErr_FiniTypes(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + return; + } + + _PyStructSequence_FiniType(&UnraisableHookArgsType); +} + + static PyObject * make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type, PyObject *exc_value, PyObject *exc_tb, @@ -1213,8 +1275,7 @@ make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type, if (exc_type == NULL) { \ exc_type = Py_None; \ } \ - Py_INCREF(exc_type); \ - PyStructSequence_SET_ITEM(args, pos++, exc_type); \ + PyStructSequence_SET_ITEM(args, pos++, Py_NewRef(exc_type)); \ } while (0) @@ -1291,7 +1352,7 @@ write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type, assert(PyExceptionClass_Check(exc_type)); - PyObject *modulename = _PyObject_GetAttrId(exc_type, &PyId___module__); + PyObject *modulename = PyObject_GetAttr(exc_type, &_Py_ID(__module__)); if (modulename == NULL || !PyUnicode_Check(modulename)) { Py_XDECREF(modulename); _PyErr_Clear(tstate); @@ -1300,8 +1361,8 @@ write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type, } } else { - if (!_PyUnicode_EqualToASCIIId(modulename, &PyId_builtins) && - !_PyUnicode_EqualToASCIIId(modulename, &PyId___main__)) { + if (!_PyUnicode_Equal(modulename, &_Py_ID(builtins)) && + !_PyUnicode_Equal(modulename, &_Py_ID(__main__))) { if (PyFile_WriteObject(modulename, file, Py_PRINT_RAW) < 0) { Py_DECREF(modulename); return -1; @@ -1349,7 +1410,7 @@ write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type, } /* Explicitly call file.flush() */ - PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush); + PyObject *res = _PyObject_CallMethodNoArgs(file, &_Py_ID(flush)); if (!res) { return -1; } @@ -1364,7 +1425,7 @@ write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type, PyObject *exc_value, PyObject *exc_tb, PyObject *err_msg, PyObject *obj) { - PyObject *file = _PySys_GetObjectId(&PyId_stderr); + PyObject *file = _PySys_GetAttr(tstate, &_Py_ID(stderr)); if (file == NULL || file == Py_None) { return 0; } @@ -1468,8 +1529,7 @@ _PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj) goto error; } - _Py_IDENTIFIER(unraisablehook); - PyObject *hook = _PySys_GetObjectId(&PyId_unraisablehook); + PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(unraisablehook)); if (hook == NULL) { Py_DECREF(hook_args); goto default_hook; @@ -1544,14 +1604,6 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, int end_lineno, int end_col_offset) { PyObject *exc, *v, *tb, *tmp; - _Py_IDENTIFIER(filename); - _Py_IDENTIFIER(lineno); - _Py_IDENTIFIER(end_lineno); - _Py_IDENTIFIER(msg); - _Py_IDENTIFIER(offset); - _Py_IDENTIFIER(end_offset); - _Py_IDENTIFIER(print_file_and_line); - _Py_IDENTIFIER(text); PyThreadState *tstate = _PyThreadState_GET(); /* add attributes for the line number and filename for the error */ @@ -1563,7 +1615,7 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, if (tmp == NULL) _PyErr_Clear(tstate); else { - if (_PyObject_SetAttrId(v, &PyId_lineno, tmp)) { + if (PyObject_SetAttr(v, &_Py_ID(lineno), tmp)) { _PyErr_Clear(tstate); } Py_DECREF(tmp); @@ -1575,7 +1627,7 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, _PyErr_Clear(tstate); } } - if (_PyObject_SetAttrId(v, &PyId_offset, tmp ? tmp : Py_None)) { + if (PyObject_SetAttr(v, &_Py_ID(offset), tmp ? tmp : Py_None)) { _PyErr_Clear(tstate); } Py_XDECREF(tmp); @@ -1587,7 +1639,7 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, _PyErr_Clear(tstate); } } - if (_PyObject_SetAttrId(v, &PyId_end_lineno, tmp ? tmp : Py_None)) { + if (PyObject_SetAttr(v, &_Py_ID(end_lineno), tmp ? tmp : Py_None)) { _PyErr_Clear(tstate); } Py_XDECREF(tmp); @@ -1599,20 +1651,20 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, _PyErr_Clear(tstate); } } - if (_PyObject_SetAttrId(v, &PyId_end_offset, tmp ? tmp : Py_None)) { + if (PyObject_SetAttr(v, &_Py_ID(end_offset), tmp ? tmp : Py_None)) { _PyErr_Clear(tstate); } Py_XDECREF(tmp); tmp = NULL; if (filename != NULL) { - if (_PyObject_SetAttrId(v, &PyId_filename, filename)) { + if (PyObject_SetAttr(v, &_Py_ID(filename), filename)) { _PyErr_Clear(tstate); } tmp = PyErr_ProgramTextObject(filename, lineno); if (tmp) { - if (_PyObject_SetAttrId(v, &PyId_text, tmp)) { + if (PyObject_SetAttr(v, &_Py_ID(text), tmp)) { _PyErr_Clear(tstate); } Py_DECREF(tmp); @@ -1622,7 +1674,7 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, } } if (exc != PyExc_SyntaxError) { - if (_PyObject_LookupAttrId(v, &PyId_msg, &tmp) < 0) { + if (_PyObject_LookupAttr(v, &_Py_ID(msg), &tmp) < 0) { _PyErr_Clear(tstate); } else if (tmp) { @@ -1631,7 +1683,7 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, else { tmp = PyObject_Str(v); if (tmp) { - if (_PyObject_SetAttrId(v, &PyId_msg, tmp)) { + if (PyObject_SetAttr(v, &_Py_ID(msg), tmp)) { _PyErr_Clear(tstate); } Py_DECREF(tmp); @@ -1640,15 +1692,15 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, _PyErr_Clear(tstate); } } - if (_PyObject_LookupAttrId(v, &PyId_print_file_and_line, &tmp) < 0) { + + if (_PyObject_LookupAttr(v, &_Py_ID(print_file_and_line), &tmp) < 0) { _PyErr_Clear(tstate); } else if (tmp) { Py_DECREF(tmp); } else { - if (_PyObject_SetAttrId(v, &PyId_print_file_and_line, - Py_None)) { + if (PyObject_SetAttr(v, &_Py_ID(print_file_and_line), Py_None)) { _PyErr_Clear(tstate); } } diff --git a/Python/fileutils.c b/Python/fileutils.c index ac0046cdac3..244bd899b3b 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -93,6 +93,10 @@ _Py_device_encoding(int fd) return PyUnicode_FromFormat("cp%u", (unsigned int)cp); #else + if (_PyRuntime.preconfig.utf8_mode) { + _Py_DECLARE_STR(utf_8, "utf-8"); + return Py_NewRef(&_Py_STR(utf_8)); + } return _Py_GetLocaleEncodingObject(); #endif } @@ -187,7 +191,7 @@ extern int _Py_normalize_encoding(const char *, char *, size_t); Py_DecodeLocale() uses mbstowcs() -1: unknown, need to call check_force_ascii() to get the value */ -static int force_ascii = -1; +#define force_ascii (_PyRuntime.fileutils.force_ascii) static int check_force_ascii(void) @@ -599,9 +603,9 @@ _Py_DecodeLocaleEx(const char* arg, wchar_t **wstr, size_t *wlen, return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason, errors); #else - int use_utf8 = (Py_UTF8Mode == 1); + int use_utf8 = (_PyRuntime.preconfig.utf8_mode >= 1); #ifdef MS_WINDOWS - use_utf8 |= !Py_LegacyWindowsFSEncodingFlag; + use_utf8 |= (_PyRuntime.preconfig.legacy_windows_fs_encoding == 0); #endif if (use_utf8) { return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason, @@ -791,9 +795,9 @@ encode_locale_ex(const wchar_t *text, char **str, size_t *error_pos, return _Py_EncodeUTF8Ex(text, str, error_pos, reason, raw_malloc, errors); #else - int use_utf8 = (Py_UTF8Mode == 1); + int use_utf8 = (_PyRuntime.preconfig.utf8_mode >= 1); #ifdef MS_WINDOWS - use_utf8 |= !Py_LegacyWindowsFSEncodingFlag; + use_utf8 |= (_PyRuntime.preconfig.legacy_windows_fs_encoding == 0); #endif if (use_utf8) { return _Py_EncodeUTF8Ex(text, str, error_pos, reason, @@ -873,10 +877,10 @@ _Py_EncodeLocaleEx(const wchar_t *text, char **str, // Get the current locale encoding name: // -// - Return "UTF-8" if _Py_FORCE_UTF8_LOCALE macro is defined (ex: on Android) -// - Return "UTF-8" if the UTF-8 Mode is enabled +// - Return "utf-8" if _Py_FORCE_UTF8_LOCALE macro is defined (ex: on Android) +// - Return "utf-8" if the UTF-8 Mode is enabled // - On Windows, return the ANSI code page (ex: "cp1250") -// - Return "UTF-8" if nl_langinfo(CODESET) returns an empty string. +// - Return "utf-8" if nl_langinfo(CODESET) returns an empty string. // - Otherwise, return nl_langinfo(CODESET). // // Return NULL on memory allocation failure. @@ -888,12 +892,8 @@ _Py_GetLocaleEncoding(void) #ifdef _Py_FORCE_UTF8_LOCALE // On Android langinfo.h and CODESET are missing, // and UTF-8 is always used in mbstowcs() and wcstombs(). - return _PyMem_RawWcsdup(L"UTF-8"); + return _PyMem_RawWcsdup(L"utf-8"); #else - const PyPreConfig *preconfig = &_PyRuntime.preconfig; - if (preconfig->utf8_mode) { - return _PyMem_RawWcsdup(L"UTF-8"); - } #ifdef MS_WINDOWS wchar_t encoding[23]; @@ -906,7 +906,7 @@ _Py_GetLocaleEncoding(void) if (!encoding || encoding[0] == '\0') { // Use UTF-8 if nl_langinfo() returns an empty string. It can happen on // macOS if the LC_CTYPE locale is not supported. - return _PyMem_RawWcsdup(L"UTF-8"); + return _PyMem_RawWcsdup(L"utf-8"); } wchar_t *wstr; @@ -956,7 +956,7 @@ static wchar_t * _Py_ConvertWCharForm(const wchar_t *source, Py_ssize_t size, const char *tocode, const char *fromcode) { - Py_BUILD_ASSERT(sizeof(wchar_t) == 4); + static_assert(sizeof(wchar_t) == 4, "wchar_t must be 32-bit"); /* Ensure we won't overflow the size. */ if (size > (PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(wchar_t))) { @@ -1244,18 +1244,12 @@ _Py_stat(PyObject *path, struct stat *statbuf) #ifdef MS_WINDOWS int err; -#if USE_UNICODE_WCHAR_CACHE - const wchar_t *wpath = _PyUnicode_AsUnicode(path); -#else /* USE_UNICODE_WCHAR_CACHE */ wchar_t *wpath = PyUnicode_AsWideCharString(path, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (wpath == NULL) return -2; err = _Py_wstat(wpath, statbuf); -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(wpath); -#endif /* USE_UNICODE_WCHAR_CACHE */ return err; #else int ret; @@ -1663,11 +1657,8 @@ _Py_fopen_obj(PyObject *path, const char *mode) Py_TYPE(path)); return NULL; } -#if USE_UNICODE_WCHAR_CACHE - const wchar_t *wpath = _PyUnicode_AsUnicode(path); -#else /* USE_UNICODE_WCHAR_CACHE */ + wchar_t *wpath = PyUnicode_AsWideCharString(path, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (wpath == NULL) return NULL; @@ -1675,9 +1666,7 @@ _Py_fopen_obj(PyObject *path, const char *mode) wmode, Py_ARRAY_LENGTH(wmode)); if (usize == 0) { PyErr_SetFromWindowsErr(0); -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(wpath); -#endif /* USE_UNICODE_WCHAR_CACHE */ return NULL; } @@ -1687,9 +1676,7 @@ _Py_fopen_obj(PyObject *path, const char *mode) Py_END_ALLOW_THREADS } while (f == NULL && errno == EINTR && !(async_err = PyErr_CheckSignals())); -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(wpath); -#endif /* USE_UNICODE_WCHAR_CACHE */ #else PyObject *bytes; const char *path_bytes; @@ -2000,13 +1987,28 @@ _Py_wrealpath(const wchar_t *path, #endif -#ifndef MS_WINDOWS int _Py_isabs(const wchar_t *path) { +#ifdef MS_WINDOWS + const wchar_t *tail; + HRESULT hr = PathCchSkipRoot(path, &tail); + if (FAILED(hr) || path == tail) { + return 0; + } + if (tail == &path[1] && (path[0] == SEP || path[0] == ALTSEP)) { + // Exclude paths with leading SEP + return 0; + } + if (tail == &path[2] && path[1] == L':') { + // Exclude drive-relative paths (e.g. C:filename.ext) + return 0; + } + return 1; +#else return (path[0] == SEP); -} #endif +} /* Get an absolute path. @@ -2017,49 +2019,25 @@ _Py_isabs(const wchar_t *path) int _Py_abspath(const wchar_t *path, wchar_t **abspath_p) { -#ifdef MS_WINDOWS - wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf; - DWORD result; - - result = GetFullPathNameW(path, - Py_ARRAY_LENGTH(woutbuf), woutbuf, - NULL); - if (!result) { - return -1; - } - - if (result > Py_ARRAY_LENGTH(woutbuf)) { - if ((size_t)result <= (size_t)PY_SSIZE_T_MAX / sizeof(wchar_t)) { - woutbufp = PyMem_RawMalloc((size_t)result * sizeof(wchar_t)); - } - else { - woutbufp = NULL; - } - if (!woutbufp) { - *abspath_p = NULL; - return 0; - } - - result = GetFullPathNameW(path, result, woutbufp, NULL); - if (!result) { - PyMem_RawFree(woutbufp); + if (path[0] == '\0' || !wcscmp(path, L".")) { + wchar_t cwd[MAXPATHLEN + 1]; + cwd[Py_ARRAY_LENGTH(cwd) - 1] = 0; + if (!_Py_wgetcwd(cwd, Py_ARRAY_LENGTH(cwd) - 1)) { + /* unable to get the current directory */ return -1; } - } - - if (woutbufp != woutbuf) { - *abspath_p = woutbufp; + *abspath_p = _PyMem_RawWcsdup(cwd); return 0; } - *abspath_p = _PyMem_RawWcsdup(woutbufp); - return 0; -#else if (_Py_isabs(path)) { *abspath_p = _PyMem_RawWcsdup(path); return 0; } +#ifdef MS_WINDOWS + return _PyOS_getfullpathname(path, abspath_p); +#else wchar_t cwd[MAXPATHLEN + 1]; cwd[Py_ARRAY_LENGTH(cwd) - 1] = 0; if (!_Py_wgetcwd(cwd, Py_ARRAY_LENGTH(cwd) - 1)) { @@ -2102,7 +2080,8 @@ join_relfile(wchar_t *buffer, size_t bufsize, const wchar_t *dirname, const wchar_t *relfile) { #ifdef MS_WINDOWS - if (FAILED(PathCchCombineEx(buffer, bufsize, dirname, relfile, 0))) { + if (FAILED(PathCchCombineEx(buffer, bufsize, dirname, relfile, + PATHCCH_ALLOW_LONG_PATHS))) { return -1; } #else @@ -2180,99 +2159,132 @@ _Py_find_basename(const wchar_t *filename) return 0; } - -/* Remove navigation elements such as "." and "..". - - This is mostly a C implementation of posixpath.normpath(). - Return 0 on success. Return -1 if "orig" is too big for the buffer. */ -int -_Py_normalize_path(const wchar_t *path, wchar_t *buf, const size_t buf_len) +/* In-place path normalisation. Returns the start of the normalized + path, which will be within the original buffer. Guaranteed to not + make the path longer, and will not fail. 'size' is the length of + the path, if known. If -1, the first null character will be assumed + to be the end of the path. */ +wchar_t * +_Py_normpath(wchar_t *path, Py_ssize_t size) { - assert(path && *path != L'\0'); - assert(*path == SEP); // an absolute path - if (wcslen(path) + 1 >= buf_len) { - return -1; + if (!path[0] || size == 0) { + return path; } + wchar_t *pEnd = size >= 0 ? &path[size] : NULL; + wchar_t *p1 = path; // sequentially scanned address in the path + wchar_t *p2 = path; // destination of a scanned character to be ljusted + wchar_t *minP2 = path; // the beginning of the destination range + wchar_t lastC = L'\0'; // the last ljusted character, p2[-1] in most cases - int dots = -1; - int check_leading = 1; - const wchar_t *buf_start = buf; - wchar_t *buf_next = buf; - // The resulting filename will never be longer than path. - for (const wchar_t *remainder = path; *remainder != L'\0'; remainder++) { - wchar_t c = *remainder; - buf_next[0] = c; - buf_next++; - if (c == SEP) { - assert(dots <= 2); - if (dots == 2) { - // Turn "/x/y/../z" into "/x/z". - buf_next -= 4; // "/../" - assert(*buf_next == SEP); - // We cap it off at the root, so "/../spam" becomes "/spam". - if (buf_next == buf_start) { - buf_next++; - } - else { - // Move to the previous SEP in the buffer. - while (*(buf_next - 1) != SEP) { - assert(buf_next != buf_start); - buf_next--; - } - } - } - else if (dots == 1) { - // Turn "/./" into "/". - buf_next -= 2; // "./" - assert(*(buf_next - 1) == SEP); - } - else if (dots == 0) { - // Turn "//" into "/". - buf_next--; - assert(*(buf_next - 1) == SEP); - if (check_leading) { - if (buf_next - 1 == buf && *(remainder + 1) != SEP) { - // Leave a leading "//" alone, unless "///...". - buf_next++; - buf_start++; - } - check_leading = 0; - } - } - dots = 0; +#define IS_END(x) (pEnd ? (x) == pEnd : !*(x)) +#ifdef ALTSEP +#define IS_SEP(x) (*(x) == SEP || *(x) == ALTSEP) +#else +#define IS_SEP(x) (*(x) == SEP) +#endif +#define SEP_OR_END(x) (IS_SEP(x) || IS_END(x)) + + // Skip leading '.\' + if (p1[0] == L'.' && IS_SEP(&p1[1])) { + path = &path[2]; + while (IS_SEP(path) && !IS_END(path)) { + path++; } - else { - check_leading = 0; - if (dots >= 0) { - if (c == L'.' && dots < 2) { - dots++; - } - else { - dots = -1; - } + p1 = p2 = minP2 = path; + lastC = SEP; + } +#ifdef MS_WINDOWS + // Skip past drive segment and update minP2 + else if (p1[0] && p1[1] == L':') { + *p2++ = *p1++; + *p2++ = *p1++; + minP2 = p2; + lastC = L':'; + } + // Skip past all \\-prefixed paths, including \\?\, \\.\, + // and network paths, including the first segment. + else if (IS_SEP(&p1[0]) && IS_SEP(&p1[1])) { + int sepCount = 2; + *p2++ = SEP; + *p2++ = SEP; + p1 += 2; + for (; !IS_END(p1) && sepCount; ++p1) { + if (IS_SEP(p1)) { + --sepCount; + *p2++ = lastC = SEP; + } else { + *p2++ = lastC = *p1; } } + if (sepCount) { + minP2 = p2; // Invalid path + } else { + minP2 = p2 - 1; // Absolute path has SEP at minP2 + } } - if (dots >= 0) { - // Strip any trailing dots and trailing slash. - buf_next -= dots + 1; // "/" or "/." or "/.." - assert(*buf_next == SEP); - if (buf_next == buf_start) { - // Leave the leading slash for root. - buf_next++; +#else + // Skip past two leading SEPs + else if (IS_SEP(&p1[0]) && IS_SEP(&p1[1]) && !IS_SEP(&p1[2])) { + *p2++ = *p1++; + *p2++ = *p1++; + minP2 = p2 - 1; // Absolute path has SEP at minP2 + lastC = SEP; + } +#endif /* MS_WINDOWS */ + + /* if pEnd is specified, check that. Else, check for null terminator */ + for (; !IS_END(p1); ++p1) { + wchar_t c = *p1; +#ifdef ALTSEP + if (c == ALTSEP) { + c = SEP; } - else { - if (dots == 2) { - // Move to the previous SEP in the buffer. - do { - assert(buf_next != buf_start); - buf_next--; - } while (*(buf_next) != SEP); +#endif + if (lastC == SEP) { + if (c == L'.') { + int sep_at_1 = SEP_OR_END(&p1[1]); + int sep_at_2 = !sep_at_1 && SEP_OR_END(&p1[2]); + if (sep_at_2 && p1[1] == L'.') { + wchar_t *p3 = p2; + while (p3 != minP2 && *--p3 == SEP) { } + while (p3 != minP2 && *(p3 - 1) != SEP) { --p3; } + if (p2 == minP2 + || (p3[0] == L'.' && p3[1] == L'.' && IS_SEP(&p3[2]))) + { + // Previous segment is also ../, so append instead. + // Relative path does not absorb ../ at minP2 as well. + *p2++ = L'.'; + *p2++ = L'.'; + lastC = L'.'; + } else if (p3[0] == SEP) { + // Absolute path, so absorb segment + p2 = p3 + 1; + } else { + p2 = p3; + } + p1 += 1; + } else if (sep_at_1) { + } else { + *p2++ = lastC = c; + } + } else if (c == SEP) { + } else { + *p2++ = lastC = c; } + } else { + *p2++ = lastC = c; } } - *buf_next = L'\0'; - return 0; + *p2 = L'\0'; + if (p2 != minP2) { + while (--p2 != minP2 && *p2 == SEP) { + *p2 = L'\0'; + } + } +#undef SEP_OR_END +#undef IS_SEP +#undef IS_END + return path; } @@ -2354,7 +2366,7 @@ _Py_dup(int fd) return -1; } -#else +#elif HAVE_DUP Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH fd = dup(fd); @@ -2371,6 +2383,10 @@ _Py_dup(int fd) _Py_END_SUPPRESS_IPH return -1; } +#else + errno = ENOTSUP; + PyErr_SetFromErrno(PyExc_OSError); + return -1; #endif return fd; } @@ -2599,10 +2615,11 @@ _Py_closerange(int first, int last) first = Py_MAX(first, 0); _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_CLOSE_RANGE - if (close_range(first, last, 0) == 0 || errno != ENOSYS) { - /* Any errors encountered while closing file descriptors are ignored; - * ENOSYS means no kernel support, though, - * so we'll fallback to the other methods. */ + if (close_range(first, last, 0) == 0) { + /* close_range() ignores errors when it closes file descriptors. + * Possible reasons of an error return are lack of kernel support + * or denial of the underlying syscall by a seccomp sandbox on Linux. + * Fallback to other methods in case of any error. */ } else #endif /* HAVE_CLOSE_RANGE */ diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index 0c21301fb9e..38e5f69bfb4 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -130,6 +130,7 @@ typedef struct { Py_UCS4 fill_char; Py_UCS4 align; int alternate; + int no_neg_0; Py_UCS4 sign; Py_ssize_t width; enum LocaleType thousands_separators; @@ -137,24 +138,6 @@ typedef struct { Py_UCS4 type; } InternalFormatSpec; -#if 0 -/* Occasionally useful for debugging. Should normally be commented out. */ -static void -DEBUG_PRINT_FORMAT_SPEC(InternalFormatSpec *format) -{ - printf("internal format spec: fill_char %d\n", format->fill_char); - printf("internal format spec: align %d\n", format->align); - printf("internal format spec: alternate %d\n", format->alternate); - printf("internal format spec: sign %d\n", format->sign); - printf("internal format spec: width %zd\n", format->width); - printf("internal format spec: thousands_separators %d\n", - format->thousands_separators); - printf("internal format spec: precision %zd\n", format->precision); - printf("internal format spec: type %c\n", format->type); - printf("\n"); -} -#endif - /* ptr points to the start of the format_spec, end points just past its end. @@ -184,6 +167,7 @@ parse_internal_render_format_spec(PyObject *obj, format->fill_char = ' '; format->align = default_align; format->alternate = 0; + format->no_neg_0 = 0; format->sign = '\0'; format->width = -1; format->thousands_separators = LT_NO_LOCALE; @@ -211,6 +195,13 @@ parse_internal_render_format_spec(PyObject *obj, ++pos; } + /* If the next character is z, request coercion of negative 0. + Applies only to floats. */ + if (end-pos >= 1 && READ_spec(pos) == 'z') { + format->no_neg_0 = 1; + ++pos; + } + /* If the next character is #, we're in alternate mode. This only applies to integers. */ if (end-pos >= 1 && READ_spec(pos) == '#') { @@ -617,7 +608,7 @@ fill_number(_PyUnicodeWriter *writer, const NumberFieldWidths *spec, { /* Used to keep track of digits, decimal, and remainder. */ Py_ssize_t d_pos = d_start; - const unsigned int kind = writer->kind; + const int kind = writer->kind; const void *data = writer->data; Py_ssize_t r; @@ -797,6 +788,14 @@ format_string_internal(PyObject *value, const InternalFormatSpec *format, goto done; } + /* negative 0 coercion is not allowed on strings */ + if (format->no_neg_0) { + PyErr_SetString(PyExc_ValueError, + "Negative zero coercion (z) not allowed in string format " + "specifier"); + goto done; + } + /* alternate is not allowed on strings */ if (format->alternate) { PyErr_SetString(PyExc_ValueError, @@ -890,6 +889,13 @@ format_long_internal(PyObject *value, const InternalFormatSpec *format, "Precision not allowed in integer format specifier"); goto done; } + /* no negative zero coercion on integers */ + if (format->no_neg_0) { + PyErr_SetString(PyExc_ValueError, + "Negative zero coercion (z) not allowed in integer" + " format specifier"); + goto done; + } /* special case for character formatting */ if (format->type == 'c') { @@ -1067,6 +1073,8 @@ format_float_internal(PyObject *value, if (format->alternate) flags |= Py_DTSF_ALT; + if (format->no_neg_0) + flags |= Py_DTSF_NO_NEG_0; if (type == '\0') { /* Omitted type specifier. Behaves in the same way as repr(x) @@ -1207,7 +1215,7 @@ format_complex_internal(PyObject *value, int flags = 0; int result = -1; Py_UCS4 maxchar = 127; - enum PyUnicode_Kind rkind; + int rkind; void *rdata; Py_UCS4 re_sign_char = '\0'; Py_UCS4 im_sign_char = '\0'; @@ -1256,6 +1264,8 @@ format_complex_internal(PyObject *value, if (format->alternate) flags |= Py_DTSF_ALT; + if (format->no_neg_0) + flags |= Py_DTSF_NO_NEG_0; if (type == '\0') { /* Omitted type specifier. Should be like str(self). */ diff --git a/Python/frame.c b/Python/frame.c index 3d2415fee70..6a287d47240 100644 --- a/Python/frame.c +++ b/Python/frame.c @@ -1,16 +1,19 @@ +#define _PY_INTERPRETER + #include "Python.h" #include "frameobject.h" +#include "pycore_code.h" // stats #include "pycore_frame.h" #include "pycore_object.h" // _PyObject_GC_UNTRACK() +#include "opcode.h" int -_PyFrame_Traverse(InterpreterFrame *frame, visitproc visit, void *arg) +_PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg) { Py_VISIT(frame->frame_obj); - Py_VISIT(frame->f_globals); - Py_VISIT(frame->f_builtins); Py_VISIT(frame->f_locals); + Py_VISIT(frame->f_funcobj); Py_VISIT(frame->f_code); /* locals */ PyObject **locals = _PyFrame_GetLocalsArray(frame); @@ -23,105 +26,130 @@ _PyFrame_Traverse(InterpreterFrame *frame, visitproc visit, void *arg) } PyFrameObject * -_PyFrame_MakeAndSetFrameObject(InterpreterFrame *frame) +_PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame) { assert(frame->frame_obj == NULL); PyObject *error_type, *error_value, *error_traceback; PyErr_Fetch(&error_type, &error_value, &error_traceback); - PyFrameObject *f = _PyFrame_New_NoTrack(frame, 0); + + PyFrameObject *f = _PyFrame_New_NoTrack(frame->f_code); if (f == NULL) { Py_XDECREF(error_type); Py_XDECREF(error_value); Py_XDECREF(error_traceback); + return NULL; } - else { - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_Restore(error_type, error_value, error_traceback); + if (frame->frame_obj) { + // GH-97002: How did we get into this horrible situation? Most likely, + // allocating f triggered a GC collection, which ran some code that + // *also* created the same frame... while we were in the middle of + // creating it! See test_sneaky_frame_object in test_frame.py for a + // concrete example. + // + // Regardless, just throw f away and use that frame instead, since it's + // already been exposed to user code. It's actually a bit tricky to do + // this, since we aren't backed by a real _PyInterpreterFrame anymore. + // Just pretend that we have an owned, cleared frame so frame_dealloc + // doesn't make the situation worse: + f->f_frame = (_PyInterpreterFrame *)f->_f_frame_data; + f->f_frame->owner = FRAME_CLEARED; + f->f_frame->frame_obj = f; + Py_DECREF(f); + return frame->frame_obj; } + assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT); + assert(frame->owner != FRAME_CLEARED); + f->f_frame = frame; frame->frame_obj = f; return f; } - -static InterpreterFrame * -copy_frame_to_heap(InterpreterFrame *frame) +void +_PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest) { - assert(frame->stacktop >= frame->f_code->co_nlocalsplus); - Py_ssize_t size = ((char*)&frame->localsplus[frame->stacktop]) - (char *)frame; - InterpreterFrame *copy = PyMem_Malloc(size); - if (copy == NULL) { - PyErr_NoMemory(); - return NULL; - } - memcpy(copy, frame, size); - return copy; + assert(src->stacktop >= src->f_code->co_nlocalsplus); + Py_ssize_t size = ((char*)&src->localsplus[src->stacktop]) - (char *)src; + memcpy(dest, src, size); + // Don't leave a dangling pointer to the old frame when creating generators + // and coroutines: + dest->previous = NULL; } -static inline void -clear_specials(InterpreterFrame *frame) -{ - frame->generator = NULL; - Py_XDECREF(frame->frame_obj); - Py_XDECREF(frame->f_locals); - Py_DECREF(frame->f_globals); - Py_DECREF(frame->f_builtins); - Py_DECREF(frame->f_code); -} static void -take_ownership(PyFrameObject *f, InterpreterFrame *frame) +take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame) { - assert(f->f_own_locals_memory == 0); - assert(frame->frame_obj == NULL); - - f->f_own_locals_memory = 1; + assert(frame->owner != FRAME_OWNED_BY_CSTACK); + assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT); + assert(frame->owner != FRAME_CLEARED); + Py_ssize_t size = ((char*)&frame->localsplus[frame->stacktop]) - (char *)frame; + memcpy((_PyInterpreterFrame *)f->_f_frame_data, frame, size); + frame = (_PyInterpreterFrame *)f->_f_frame_data; f->f_frame = frame; + frame->owner = FRAME_OWNED_BY_FRAME_OBJECT; + if (_PyFrame_IsIncomplete(frame)) { + // This may be a newly-created generator or coroutine frame. Since it's + // dead anyways, just pretend that the first RESUME ran: + PyCodeObject *code = frame->f_code; + frame->prev_instr = _PyCode_CODE(code) + code->_co_firsttraceable; + } + assert(!_PyFrame_IsIncomplete(frame)); assert(f->f_back == NULL); - if (frame->previous != NULL) { - /* Link PyFrameObjects.f_back and remove link through InterpreterFrame.previous */ - PyFrameObject *back = _PyFrame_GetFrameObject(frame->previous); + _PyInterpreterFrame *prev = _PyFrame_GetFirstComplete(frame->previous); + frame->previous = NULL; + if (prev) { + assert(prev->owner != FRAME_OWNED_BY_CSTACK); + /* Link PyFrameObjects.f_back and remove link through _PyInterpreterFrame.previous */ + PyFrameObject *back = _PyFrame_GetFrameObject(prev); if (back == NULL) { /* Memory error here. */ assert(PyErr_ExceptionMatches(PyExc_MemoryError)); /* Nothing we can do about it */ PyErr_Clear(); - _PyErr_WriteUnraisableMsg("Out of memory lazily allocating frame->f_back", NULL); } else { f->f_back = (PyFrameObject *)Py_NewRef(back); } - frame->previous = NULL; } if (!_PyObject_GC_IS_TRACKED((PyObject *)f)) { _PyObject_GC_TRACK((PyObject *)f); } } -int -_PyFrame_Clear(InterpreterFrame * frame, int take) +void +_PyFrame_Clear(_PyInterpreterFrame *frame) { + /* It is the responsibility of the owning generator/coroutine + * to have cleared the enclosing generator, if any. */ + assert(frame->owner != FRAME_OWNED_BY_GENERATOR || + _PyFrame_GetGenerator(frame)->gi_frame_state == FRAME_CLEARED); + // GH-99729: Clearing this frame can expose the stack (via finalizers). It's + // crucial that this frame has been unlinked, and is no longer visible: + assert(_PyThreadState_GET()->cframe->current_frame != frame); if (frame->frame_obj) { PyFrameObject *f = frame->frame_obj; frame->frame_obj = NULL; if (Py_REFCNT(f) > 1) { - if (!take) { - frame = copy_frame_to_heap(frame); - if (frame == NULL) { - return -1; - } - } take_ownership(f, frame); Py_DECREF(f); - return 0; + return; } Py_DECREF(f); } - assert(_PyFrame_GetStackPointer(frame) >= _PyFrame_Stackbase(frame)); + assert(frame->stacktop >= 0); for (int i = 0; i < frame->stacktop; i++) { Py_XDECREF(frame->localsplus[i]); } - clear_specials(frame); - if (take) { - PyMem_Free(frame); - } - return 0; + Py_XDECREF(frame->frame_obj); + Py_XDECREF(frame->f_locals); + Py_DECREF(frame->f_funcobj); + Py_DECREF(frame->f_code); +} + +int +_PyInterpreterFrame_GetLine(_PyInterpreterFrame *frame) +{ + int addr = _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT); + return PyCode_Addr2Line(frame->f_code, addr); } diff --git a/Python/frozen.c b/Python/frozen.c index 1565c9a3d73..48b429519b6 100644 --- a/Python/frozen.c +++ b/Python/frozen.c @@ -8,7 +8,7 @@ * These files must be regenerated any time the corresponding .pyc * file would change (including with changes to the compiler, bytecode * format, marshal format). This can be done with "make regen-frozen". - * That make target just runs Tools/scripts/freeze_modules.py. + * That make target just runs Tools/build/freeze_modules.py. * * The freeze_modules.py script also determines which modules get * frozen. Update the list at the top of the script to add, remove, @@ -38,35 +38,12 @@ #include "Python.h" #include "pycore_import.h" +#include + /* Includes for frozen modules: */ -#include "frozen_modules/importlib._bootstrap.h" -#include "frozen_modules/importlib._bootstrap_external.h" -#include "frozen_modules/zipimport.h" -#include "frozen_modules/abc.h" -#include "frozen_modules/codecs.h" -#include "frozen_modules/io.h" -#include "frozen_modules/_collections_abc.h" -#include "frozen_modules/_sitebuiltins.h" -#include "frozen_modules/genericpath.h" -#include "frozen_modules/ntpath.h" -#include "frozen_modules/posixpath.h" -#include "frozen_modules/os.h" -#include "frozen_modules/site.h" -#include "frozen_modules/stat.h" -#include "frozen_modules/__hello__.h" -#include "frozen_modules/__phello__.h" -#include "frozen_modules/__phello__.ham.h" -#include "frozen_modules/__phello__.ham.eggs.h" -#include "frozen_modules/__phello__.spam.h" -#include "frozen_modules/frozen_only.h" /* End includes */ -#ifdef MS_WINDOWS -/* Deepfreeze isn't supported on Windows yet. */ -#define GET_CODE(name) NULL -#else #define GET_CODE(name) _Py_get_##name##_toplevel -#endif /* Start extern declarations */ extern PyObject *_Py_get_importlib__bootstrap_toplevel(void); @@ -84,6 +61,9 @@ extern PyObject *_Py_get_posixpath_toplevel(void); extern PyObject *_Py_get_os_toplevel(void); extern PyObject *_Py_get_site_toplevel(void); extern PyObject *_Py_get_stat_toplevel(void); +extern PyObject *_Py_get_importlib_util_toplevel(void); +extern PyObject *_Py_get_importlib_machinery_toplevel(void); +extern PyObject *_Py_get_runpy_toplevel(void); extern PyObject *_Py_get___hello___toplevel(void); extern PyObject *_Py_get___hello___toplevel(void); extern PyObject *_Py_get___hello___toplevel(void); @@ -97,44 +77,47 @@ extern PyObject *_Py_get___phello___spam_toplevel(void); extern PyObject *_Py_get_frozen_only_toplevel(void); /* End extern declarations */ -/* Note that a negative size indicates a package. */ - static const struct _frozen bootstrap_modules[] = { - {"_frozen_importlib", _Py_M__importlib__bootstrap, (int)sizeof(_Py_M__importlib__bootstrap), GET_CODE(importlib__bootstrap)}, - {"_frozen_importlib_external", _Py_M__importlib__bootstrap_external, (int)sizeof(_Py_M__importlib__bootstrap_external), GET_CODE(importlib__bootstrap_external)}, - {"zipimport", _Py_M__zipimport, (int)sizeof(_Py_M__zipimport), GET_CODE(zipimport)}, + {"_frozen_importlib", NULL, 0, false, GET_CODE(importlib__bootstrap)}, + {"_frozen_importlib_external", NULL, 0, false, GET_CODE(importlib__bootstrap_external)}, + {"zipimport", NULL, 0, false, GET_CODE(zipimport)}, {0, 0, 0} /* bootstrap sentinel */ }; static const struct _frozen stdlib_modules[] = { /* stdlib - startup, without site (python -S) */ - {"abc", _Py_M__abc, (int)sizeof(_Py_M__abc), GET_CODE(abc)}, - {"codecs", _Py_M__codecs, (int)sizeof(_Py_M__codecs), GET_CODE(codecs)}, - {"io", _Py_M__io, (int)sizeof(_Py_M__io), GET_CODE(io)}, + {"abc", NULL, 0, false, GET_CODE(abc)}, + {"codecs", NULL, 0, false, GET_CODE(codecs)}, + {"io", NULL, 0, false, GET_CODE(io)}, /* stdlib - startup, with site */ - {"_collections_abc", _Py_M___collections_abc, (int)sizeof(_Py_M___collections_abc), GET_CODE(_collections_abc)}, - {"_sitebuiltins", _Py_M___sitebuiltins, (int)sizeof(_Py_M___sitebuiltins), GET_CODE(_sitebuiltins)}, - {"genericpath", _Py_M__genericpath, (int)sizeof(_Py_M__genericpath), GET_CODE(genericpath)}, - {"ntpath", _Py_M__ntpath, (int)sizeof(_Py_M__ntpath), GET_CODE(ntpath)}, - {"posixpath", _Py_M__posixpath, (int)sizeof(_Py_M__posixpath), GET_CODE(posixpath)}, - {"os.path", _Py_M__posixpath, (int)sizeof(_Py_M__posixpath), GET_CODE(posixpath)}, - {"os", _Py_M__os, (int)sizeof(_Py_M__os), GET_CODE(os)}, - {"site", _Py_M__site, (int)sizeof(_Py_M__site), GET_CODE(site)}, - {"stat", _Py_M__stat, (int)sizeof(_Py_M__stat), GET_CODE(stat)}, + {"_collections_abc", NULL, 0, false, GET_CODE(_collections_abc)}, + {"_sitebuiltins", NULL, 0, false, GET_CODE(_sitebuiltins)}, + {"genericpath", NULL, 0, false, GET_CODE(genericpath)}, + {"ntpath", NULL, 0, false, GET_CODE(ntpath)}, + {"posixpath", NULL, 0, false, GET_CODE(posixpath)}, + {"os.path", NULL, 0, false, GET_CODE(posixpath)}, + {"os", NULL, 0, false, GET_CODE(os)}, + {"site", NULL, 0, false, GET_CODE(site)}, + {"stat", NULL, 0, false, GET_CODE(stat)}, + + /* runpy - run module with -m */ + {"importlib.util", NULL, 0, false, GET_CODE(importlib_util)}, + {"importlib.machinery", NULL, 0, false, GET_CODE(importlib_machinery)}, + {"runpy", NULL, 0, false, GET_CODE(runpy)}, {0, 0, 0} /* stdlib sentinel */ }; static const struct _frozen test_modules[] = { - {"__hello__", _Py_M____hello__, (int)sizeof(_Py_M____hello__), GET_CODE(__hello__)}, - {"__hello_alias__", _Py_M____hello__, (int)sizeof(_Py_M____hello__), GET_CODE(__hello__)}, - {"__phello_alias__", _Py_M____hello__, -(int)sizeof(_Py_M____hello__), GET_CODE(__hello__)}, - {"__phello_alias__.spam", _Py_M____hello__, (int)sizeof(_Py_M____hello__), GET_CODE(__hello__)}, - {"__phello__", _Py_M____phello__, -(int)sizeof(_Py_M____phello__), GET_CODE(__phello__)}, - {"__phello__.__init__", _Py_M____phello__, (int)sizeof(_Py_M____phello__), GET_CODE(__phello__)}, - {"__phello__.ham", _Py_M____phello___ham, -(int)sizeof(_Py_M____phello___ham), GET_CODE(__phello___ham)}, - {"__phello__.ham.__init__", _Py_M____phello___ham, (int)sizeof(_Py_M____phello___ham), GET_CODE(__phello___ham)}, - {"__phello__.ham.eggs", _Py_M____phello___ham_eggs, (int)sizeof(_Py_M____phello___ham_eggs), GET_CODE(__phello___ham_eggs)}, - {"__phello__.spam", _Py_M____phello___spam, (int)sizeof(_Py_M____phello___spam), GET_CODE(__phello___spam)}, - {"__hello_only__", _Py_M__frozen_only, (int)sizeof(_Py_M__frozen_only), GET_CODE(frozen_only)}, + {"__hello__", NULL, 0, false, GET_CODE(__hello__)}, + {"__hello_alias__", NULL, 0, false, GET_CODE(__hello__)}, + {"__phello_alias__", NULL, 0, true, GET_CODE(__hello__)}, + {"__phello_alias__.spam", NULL, 0, false, GET_CODE(__hello__)}, + {"__phello__", NULL, 0, true, GET_CODE(__phello__)}, + {"__phello__.__init__", NULL, 0, false, GET_CODE(__phello__)}, + {"__phello__.ham", NULL, 0, true, GET_CODE(__phello___ham)}, + {"__phello__.ham.__init__", NULL, 0, false, GET_CODE(__phello___ham)}, + {"__phello__.ham.eggs", NULL, 0, false, GET_CODE(__phello___ham_eggs)}, + {"__phello__.spam", NULL, 0, false, GET_CODE(__phello___spam)}, + {"__hello_only__", NULL, 0, false, GET_CODE(frozen_only)}, {0, 0, 0} /* test sentinel */ }; const struct _frozen *_PyImport_FrozenBootstrap = bootstrap_modules; diff --git a/Python/frozen_modules/README.txt b/Python/frozen_modules/README.txt index 444167cc496..795bb0efad3 100644 --- a/Python/frozen_modules/README.txt +++ b/Python/frozen_modules/README.txt @@ -4,4 +4,4 @@ modules. Python/frozen.c depends on these files. Note that, other than the required frozen modules, none of these files are committed into the repo. -See Tools/scripts/freeze_modules.py for more info. +See Tools/build/freeze_modules.py for more info. diff --git a/Python/frozenmain.c b/Python/frozenmain.c index 8743e082b4f..f8be165f767 100644 --- a/Python/frozenmain.c +++ b/Python/frozenmain.c @@ -53,7 +53,7 @@ Py_FrozenMain(int argc, char **argv) PyWinFreeze_ExeInit(); #endif - if (Py_VerboseFlag) { + if (_Py_GetConfig()->verbose) { fprintf(stderr, "Python %s\n%s\n", Py_GetVersion(), Py_GetCopyright()); } diff --git a/Python/future.c b/Python/future.c index d465608ca45..d56f7330964 100644 --- a/Python/future.c +++ b/Python/future.c @@ -2,8 +2,6 @@ #include "pycore_ast.h" // _PyAST_GetDocString() #define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined" -#define ERR_LATE_FUTURE \ -"from __future__ imports must occur at the beginning of the file" static int future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) @@ -56,81 +54,56 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) static int future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename) { - int i, done = 0, prev_line = 0; - - if (!(mod->kind == Module_kind || mod->kind == Interactive_kind)) + if (!(mod->kind == Module_kind || mod->kind == Interactive_kind)) { return 1; + } - if (asdl_seq_LEN(mod->v.Module.body) == 0) + Py_ssize_t n = asdl_seq_LEN(mod->v.Module.body); + if (n == 0) { return 1; + } - /* A subsequent pass will detect future imports that don't - appear at the beginning of the file. There's one case, - however, that is easier to handle here: A series of imports - joined by semi-colons, where the first import is a future - statement but some subsequent import has the future form - but is preceded by a regular import. - */ - - i = 0; - if (_PyAST_GetDocString(mod->v.Module.body) != NULL) + Py_ssize_t i = 0; + if (_PyAST_GetDocString(mod->v.Module.body) != NULL) { i++; + } - for (; i < asdl_seq_LEN(mod->v.Module.body); i++) { + for (; i < n; i++) { stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i); - if (done && s->lineno > prev_line) - return 1; - prev_line = s->lineno; - - /* The tests below will return from this function unless it is - still possible to find a future statement. The only things - that can precede a future statement are another future - statement and a doc string. - */ + /* The only things that can precede a future statement + * are another future statement and a doc string. + */ if (s->kind == ImportFrom_kind) { identifier modname = s->v.ImportFrom.module; if (modname && _PyUnicode_EqualToASCIIString(modname, "__future__")) { - if (done) { - PyErr_SetString(PyExc_SyntaxError, - ERR_LATE_FUTURE); - PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset); + if (!future_check_features(ff, s, filename)) { return 0; } - if (!future_check_features(ff, s, filename)) - return 0; - ff->ff_lineno = s->lineno; + ff->ff_location = SRC_LOCATION_FROM_AST(s); } else { - done = 1; + return 1; } } else { - done = 1; + return 1; } } return 1; } -PyFutureFeatures * -_PyFuture_FromAST(mod_ty mod, PyObject *filename) +int +_PyFuture_FromAST(mod_ty mod, PyObject *filename, PyFutureFeatures *ff) { - PyFutureFeatures *ff; - - ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures)); - if (ff == NULL) { - PyErr_NoMemory(); - return NULL; - } ff->ff_features = 0; - ff->ff_lineno = -1; + ff->ff_location = (_PyCompilerSrcLocation){-1, -1, -1, -1}; if (!future_parse(ff, mod, filename)) { - PyObject_Free(ff); - return NULL; + return 0; } - return ff; + return 1; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h new file mode 100644 index 00000000000..b5decf804ca --- /dev/null +++ b/Python/generated_cases.c.h @@ -0,0 +1,3702 @@ +// This file is generated by Tools/cases_generator/generate_cases.py +// from Python/bytecodes.c +// Do not edit! + + TARGET(NOP) { + DISPATCH(); + } + + TARGET(RESUME) { + assert(tstate->cframe == &cframe); + assert(frame == cframe.current_frame); + if (_Py_atomic_load_relaxed_int32(eval_breaker) && oparg < 2) { + goto handle_eval_breaker; + } + DISPATCH(); + } + + TARGET(LOAD_CLOSURE) { + PyObject *value; + /* We keep LOAD_CLOSURE so that the bytecode stays more readable. */ + value = GETLOCAL(oparg); + if (value == NULL) goto unbound_local_error; + Py_INCREF(value); + STACK_GROW(1); + POKE(1, value); + DISPATCH(); + } + + TARGET(LOAD_FAST_CHECK) { + PyObject *value; + value = GETLOCAL(oparg); + if (value == NULL) goto unbound_local_error; + Py_INCREF(value); + STACK_GROW(1); + POKE(1, value); + DISPATCH(); + } + + TARGET(LOAD_FAST) { + PyObject *value; + value = GETLOCAL(oparg); + assert(value != NULL); + Py_INCREF(value); + STACK_GROW(1); + POKE(1, value); + DISPATCH(); + } + + TARGET(LOAD_CONST) { + PREDICTED(LOAD_CONST); + PyObject *value; + value = GETITEM(consts, oparg); + Py_INCREF(value); + STACK_GROW(1); + POKE(1, value); + DISPATCH(); + } + + TARGET(STORE_FAST) { + PyObject *value = PEEK(1); + SETLOCAL(oparg, value); + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(LOAD_FAST__LOAD_FAST) { + PyObject *_tmp_1; + PyObject *_tmp_2; + { + PyObject *value; + value = GETLOCAL(oparg); + assert(value != NULL); + Py_INCREF(value); + _tmp_2 = value; + } + NEXTOPARG(); + JUMPBY(1); + { + PyObject *value; + value = GETLOCAL(oparg); + assert(value != NULL); + Py_INCREF(value); + _tmp_1 = value; + } + STACK_GROW(2); + POKE(1, _tmp_1); + POKE(2, _tmp_2); + DISPATCH(); + } + + TARGET(LOAD_FAST__LOAD_CONST) { + PyObject *_tmp_1; + PyObject *_tmp_2; + { + PyObject *value; + value = GETLOCAL(oparg); + assert(value != NULL); + Py_INCREF(value); + _tmp_2 = value; + } + NEXTOPARG(); + JUMPBY(1); + { + PyObject *value; + value = GETITEM(consts, oparg); + Py_INCREF(value); + _tmp_1 = value; + } + STACK_GROW(2); + POKE(1, _tmp_1); + POKE(2, _tmp_2); + DISPATCH(); + } + + TARGET(STORE_FAST__LOAD_FAST) { + PyObject *_tmp_1 = PEEK(1); + { + PyObject *value = _tmp_1; + SETLOCAL(oparg, value); + } + NEXTOPARG(); + JUMPBY(1); + { + PyObject *value; + value = GETLOCAL(oparg); + assert(value != NULL); + Py_INCREF(value); + _tmp_1 = value; + } + POKE(1, _tmp_1); + DISPATCH(); + } + + TARGET(STORE_FAST__STORE_FAST) { + PyObject *_tmp_1 = PEEK(1); + PyObject *_tmp_2 = PEEK(2); + { + PyObject *value = _tmp_1; + SETLOCAL(oparg, value); + } + NEXTOPARG(); + JUMPBY(1); + { + PyObject *value = _tmp_2; + SETLOCAL(oparg, value); + } + STACK_SHRINK(2); + DISPATCH(); + } + + TARGET(LOAD_CONST__LOAD_FAST) { + PyObject *_tmp_1; + PyObject *_tmp_2; + { + PyObject *value; + value = GETITEM(consts, oparg); + Py_INCREF(value); + _tmp_2 = value; + } + NEXTOPARG(); + JUMPBY(1); + { + PyObject *value; + value = GETLOCAL(oparg); + assert(value != NULL); + Py_INCREF(value); + _tmp_1 = value; + } + STACK_GROW(2); + POKE(1, _tmp_1); + POKE(2, _tmp_2); + DISPATCH(); + } + + TARGET(POP_TOP) { + PyObject *value = PEEK(1); + Py_DECREF(value); + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(PUSH_NULL) { + PyObject *res; + res = NULL; + STACK_GROW(1); + POKE(1, res); + DISPATCH(); + } + + TARGET(END_FOR) { + PyObject *_tmp_1 = PEEK(1); + PyObject *_tmp_2 = PEEK(2); + { + PyObject *value = _tmp_1; + Py_DECREF(value); + } + { + PyObject *value = _tmp_2; + Py_DECREF(value); + } + STACK_SHRINK(2); + DISPATCH(); + } + + TARGET(UNARY_NEGATIVE) { + PyObject *value = PEEK(1); + PyObject *res; + res = PyNumber_Negative(value); + Py_DECREF(value); + if (res == NULL) goto pop_1_error; + POKE(1, res); + DISPATCH(); + } + + TARGET(UNARY_NOT) { + PyObject *value = PEEK(1); + PyObject *res; + int err = PyObject_IsTrue(value); + Py_DECREF(value); + if (err < 0) goto pop_1_error; + if (err == 0) { + res = Py_True; + } + else { + res = Py_False; + } + Py_INCREF(res); + POKE(1, res); + DISPATCH(); + } + + TARGET(UNARY_INVERT) { + PyObject *value = PEEK(1); + PyObject *res; + res = PyNumber_Invert(value); + Py_DECREF(value); + if (res == NULL) goto pop_1_error; + POKE(1, res); + DISPATCH(); + } + + TARGET(BINARY_OP_MULTIPLY_INT) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + PyObject *prod; + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); + prod = _PyLong_Multiply((PyLongObject *)left, (PyLongObject *)right); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + if (prod == NULL) goto pop_2_error; + STACK_SHRINK(1); + POKE(1, prod); + JUMPBY(1); + DISPATCH(); + } + + TARGET(BINARY_OP_MULTIPLY_FLOAT) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + PyObject *prod; + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); + double dprod = ((PyFloatObject *)left)->ob_fval * + ((PyFloatObject *)right)->ob_fval; + prod = PyFloat_FromDouble(dprod); + _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); + _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); + if (prod == NULL) goto pop_2_error; + STACK_SHRINK(1); + POKE(1, prod); + JUMPBY(1); + DISPATCH(); + } + + TARGET(BINARY_OP_SUBTRACT_INT) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + PyObject *sub; + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); + sub = _PyLong_Subtract((PyLongObject *)left, (PyLongObject *)right); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + if (sub == NULL) goto pop_2_error; + STACK_SHRINK(1); + POKE(1, sub); + JUMPBY(1); + DISPATCH(); + } + + TARGET(BINARY_OP_SUBTRACT_FLOAT) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + PyObject *sub; + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); + double dsub = ((PyFloatObject *)left)->ob_fval - ((PyFloatObject *)right)->ob_fval; + sub = PyFloat_FromDouble(dsub); + _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); + _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); + if (sub == NULL) goto pop_2_error; + STACK_SHRINK(1); + POKE(1, sub); + JUMPBY(1); + DISPATCH(); + } + + TARGET(BINARY_OP_ADD_UNICODE) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + PyObject *res; + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + STAT_INC(BINARY_OP, hit); + res = PyUnicode_Concat(left, right); + _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); + _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); + if (res == NULL) goto pop_2_error; + STACK_SHRINK(1); + POKE(1, res); + JUMPBY(1); + DISPATCH(); + } + + TARGET(BINARY_OP_INPLACE_ADD_UNICODE) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + _Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP]; + assert(_Py_OPCODE(true_next) == STORE_FAST || + _Py_OPCODE(true_next) == STORE_FAST__LOAD_FAST); + PyObject **target_local = &GETLOCAL(_Py_OPARG(true_next)); + DEOPT_IF(*target_local != left, BINARY_OP); + STAT_INC(BINARY_OP, hit); + /* Handle `left = left + right` or `left += right` for str. + * + * When possible, extend `left` in place rather than + * allocating a new PyUnicodeObject. This attempts to avoid + * quadratic behavior when one neglects to use str.join(). + * + * If `left` has only two references remaining (one from + * the stack, one in the locals), DECREFing `left` leaves + * only the locals reference, so PyUnicode_Append knows + * that the string is safe to mutate. + */ + assert(Py_REFCNT(left) >= 2); + _Py_DECREF_NO_DEALLOC(left); + PyUnicode_Append(target_local, right); + _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); + if (*target_local == NULL) goto pop_2_error; + // The STORE_FAST is already done. + JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP + 1); + STACK_SHRINK(2); + DISPATCH(); + } + + TARGET(BINARY_OP_ADD_FLOAT) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + PyObject *sum; + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + STAT_INC(BINARY_OP, hit); + double dsum = ((PyFloatObject *)left)->ob_fval + + ((PyFloatObject *)right)->ob_fval; + sum = PyFloat_FromDouble(dsum); + _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); + _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); + if (sum == NULL) goto pop_2_error; + STACK_SHRINK(1); + POKE(1, sum); + JUMPBY(1); + DISPATCH(); + } + + TARGET(BINARY_OP_ADD_INT) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + PyObject *sum; + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + STAT_INC(BINARY_OP, hit); + sum = _PyLong_Add((PyLongObject *)left, (PyLongObject *)right); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + if (sum == NULL) goto pop_2_error; + STACK_SHRINK(1); + POKE(1, sum); + JUMPBY(1); + DISPATCH(); + } + + TARGET(BINARY_SUBSCR) { + PREDICTED(BINARY_SUBSCR); + static_assert(INLINE_CACHE_ENTRIES_BINARY_SUBSCR == 4, "incorrect cache size"); + PyObject *sub = PEEK(1); + PyObject *container = PEEK(2); + PyObject *res; + #if ENABLE_SPECIALIZATION + _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + assert(cframe.use_tracing == 0); + next_instr--; + _Py_Specialize_BinarySubscr(container, sub, next_instr); + DISPATCH_SAME_OPARG(); + } + STAT_INC(BINARY_SUBSCR, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + res = PyObject_GetItem(container, sub); + Py_DECREF(container); + Py_DECREF(sub); + if (res == NULL) goto pop_2_error; + STACK_SHRINK(1); + POKE(1, res); + JUMPBY(4); + DISPATCH(); + } + + TARGET(BINARY_SLICE) { + PyObject *stop = PEEK(1); + PyObject *start = PEEK(2); + PyObject *container = PEEK(3); + PyObject *res; + PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop); + // Can't use ERROR_IF() here, because we haven't + // DECREF'ed container yet, and we still own slice. + if (slice == NULL) { + res = NULL; + } + else { + res = PyObject_GetItem(container, slice); + Py_DECREF(slice); + } + Py_DECREF(container); + if (res == NULL) goto pop_3_error; + STACK_SHRINK(2); + POKE(1, res); + DISPATCH(); + } + + TARGET(STORE_SLICE) { + PyObject *stop = PEEK(1); + PyObject *start = PEEK(2); + PyObject *container = PEEK(3); + PyObject *v = PEEK(4); + PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop); + int err; + if (slice == NULL) { + err = 1; + } + else { + err = PyObject_SetItem(container, slice, v); + Py_DECREF(slice); + } + Py_DECREF(v); + Py_DECREF(container); + if (err) goto pop_4_error; + STACK_SHRINK(4); + DISPATCH(); + } + + TARGET(BINARY_SUBSCR_LIST_INT) { + PyObject *sub = PEEK(1); + PyObject *list = PEEK(2); + PyObject *res; + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); + DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR); + + // Deopt unless 0 <= sub < PyList_Size(list) + DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR); + assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0); + Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; + DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + res = PyList_GET_ITEM(list, index); + assert(res != NULL); + Py_INCREF(res); + _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + Py_DECREF(list); + STACK_SHRINK(1); + POKE(1, res); + JUMPBY(4); + DISPATCH(); + } + + TARGET(BINARY_SUBSCR_TUPLE_INT) { + PyObject *sub = PEEK(1); + PyObject *tuple = PEEK(2); + PyObject *res; + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); + DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR); + + // Deopt unless 0 <= sub < PyTuple_Size(list) + DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), BINARY_SUBSCR); + assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0); + Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; + DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + res = PyTuple_GET_ITEM(tuple, index); + assert(res != NULL); + Py_INCREF(res); + _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + Py_DECREF(tuple); + STACK_SHRINK(1); + POKE(1, res); + JUMPBY(4); + DISPATCH(); + } + + TARGET(BINARY_SUBSCR_DICT) { + PyObject *sub = PEEK(1); + PyObject *dict = PEEK(2); + PyObject *res; + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyDict_CheckExact(dict), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + res = PyDict_GetItemWithError(dict, sub); + if (res == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetKeyError(sub); + } + Py_DECREF(dict); + Py_DECREF(sub); + if (true) goto pop_2_error; + } + Py_INCREF(res); // Do this before DECREF'ing dict, sub + Py_DECREF(dict); + Py_DECREF(sub); + STACK_SHRINK(1); + POKE(1, res); + JUMPBY(4); + DISPATCH(); + } + + TARGET(BINARY_SUBSCR_GETITEM) { + PyObject *sub = PEEK(1); + PyObject *container = PEEK(2); + uint32_t type_version = read_u32(&next_instr[1].cache); + uint16_t func_version = read_u16(&next_instr[3].cache); + PyTypeObject *tp = Py_TYPE(container); + DEOPT_IF(tp->tp_version_tag != type_version, BINARY_SUBSCR); + assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE); + PyObject *cached = ((PyHeapTypeObject *)tp)->_spec_cache.getitem; + assert(PyFunction_Check(cached)); + PyFunctionObject *getitem = (PyFunctionObject *)cached; + DEOPT_IF(getitem->func_version != func_version, BINARY_SUBSCR); + PyCodeObject *code = (PyCodeObject *)getitem->func_code; + assert(code->co_argcount == 2); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + Py_INCREF(getitem); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2); + STACK_SHRINK(2); + new_frame->localsplus[0] = container; + new_frame->localsplus[1] = sub; + JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); + DISPATCH_INLINED(new_frame); + } + + TARGET(LIST_APPEND) { + PyObject *v = PEEK(1); + PyObject *list = PEEK(2 + (oparg-1)); + if (_PyList_AppendTakeRef((PyListObject *)list, v) < 0) goto pop_1_error; + STACK_SHRINK(1); + PREDICT(JUMP_BACKWARD); + DISPATCH(); + } + + TARGET(SET_ADD) { + PyObject *v = PEEK(1); + PyObject *set = PEEK(2 + (oparg-1)); + int err = PySet_Add(set, v); + Py_DECREF(v); + if (err) goto pop_1_error; + STACK_SHRINK(1); + PREDICT(JUMP_BACKWARD); + DISPATCH(); + } + + TARGET(STORE_SUBSCR) { + PREDICTED(STORE_SUBSCR); + PyObject *sub = PEEK(1); + PyObject *container = PEEK(2); + PyObject *v = PEEK(3); + uint16_t counter = read_u16(&next_instr[0].cache); + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + assert(cframe.use_tracing == 0); + next_instr--; + _Py_Specialize_StoreSubscr(container, sub, next_instr); + DISPATCH_SAME_OPARG(); + } + STAT_INC(STORE_SUBSCR, deferred); + _PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr; + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #else + (void)counter; // Unused. + #endif /* ENABLE_SPECIALIZATION */ + /* container[sub] = v */ + int err = PyObject_SetItem(container, sub, v); + Py_DECREF(v); + Py_DECREF(container); + Py_DECREF(sub); + if (err) goto pop_3_error; + STACK_SHRINK(3); + JUMPBY(1); + DISPATCH(); + } + + TARGET(STORE_SUBSCR_LIST_INT) { + PyObject *sub = PEEK(1); + PyObject *list = PEEK(2); + PyObject *value = PEEK(3); + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyLong_CheckExact(sub), STORE_SUBSCR); + DEOPT_IF(!PyList_CheckExact(list), STORE_SUBSCR); + + // Ensure nonnegative, zero-or-one-digit ints. + DEOPT_IF(!_PyLong_IsPositiveSingleDigit(sub), STORE_SUBSCR); + Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; + // Ensure index < len(list) + DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR); + STAT_INC(STORE_SUBSCR, hit); + + PyObject *old_value = PyList_GET_ITEM(list, index); + PyList_SET_ITEM(list, index, value); + assert(old_value != NULL); + Py_DECREF(old_value); + _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + Py_DECREF(list); + STACK_SHRINK(3); + JUMPBY(1); + DISPATCH(); + } + + TARGET(STORE_SUBSCR_DICT) { + PyObject *sub = PEEK(1); + PyObject *dict = PEEK(2); + PyObject *value = PEEK(3); + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyDict_CheckExact(dict), STORE_SUBSCR); + STAT_INC(STORE_SUBSCR, hit); + int err = _PyDict_SetItem_Take2((PyDictObject *)dict, sub, value); + Py_DECREF(dict); + if (err) goto pop_3_error; + STACK_SHRINK(3); + JUMPBY(1); + DISPATCH(); + } + + TARGET(DELETE_SUBSCR) { + PyObject *sub = PEEK(1); + PyObject *container = PEEK(2); + /* del container[sub] */ + int err = PyObject_DelItem(container, sub); + Py_DECREF(container); + Py_DECREF(sub); + if (err) goto pop_2_error; + STACK_SHRINK(2); + DISPATCH(); + } + + TARGET(CALL_INTRINSIC_1) { + PyObject *value = PEEK(1); + PyObject *res; + assert(oparg <= MAX_INTRINSIC_1); + res = _PyIntrinsics_UnaryFunctions[oparg](tstate, value); + Py_DECREF(value); + if (res == NULL) goto pop_1_error; + POKE(1, res); + DISPATCH(); + } + + TARGET(RAISE_VARARGS) { + PyObject **args = &PEEK(oparg); + PyObject *cause = NULL, *exc = NULL; + switch (oparg) { + case 2: + cause = args[1]; + /* fall through */ + case 1: + exc = args[0]; + /* fall through */ + case 0: + if (do_raise(tstate, exc, cause)) { STACK_SHRINK(oparg); goto exception_unwind; } + break; + default: + _PyErr_SetString(tstate, PyExc_SystemError, + "bad RAISE_VARARGS oparg"); + break; + } + if (true) { STACK_SHRINK(oparg); goto error; } + } + + TARGET(INTERPRETER_EXIT) { + PyObject *retval = PEEK(1); + assert(frame == &entry_frame); + assert(_PyFrame_IsIncomplete(frame)); + STACK_SHRINK(1); // Since we're not going to DISPATCH() + assert(EMPTY()); + /* Restore previous cframe and return. */ + tstate->cframe = cframe.previous; + tstate->cframe->use_tracing = cframe.use_tracing; + assert(tstate->cframe->current_frame == frame->previous); + assert(!_PyErr_Occurred(tstate)); + _Py_LeaveRecursiveCallTstate(tstate); + return retval; + } + + TARGET(RETURN_VALUE) { + PyObject *retval = PEEK(1); + STACK_SHRINK(1); + assert(EMPTY()); + _PyFrame_SetStackPointer(frame, stack_pointer); + TRACE_FUNCTION_EXIT(); + DTRACE_FUNCTION_EXIT(); + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = cframe.current_frame = dying->previous; + _PyEvalFrameClearAndPop(tstate, dying); + _PyFrame_StackPush(frame, retval); + goto resume_frame; + } + + TARGET(GET_AITER) { + PyObject *obj = PEEK(1); + PyObject *iter; + unaryfunc getter = NULL; + PyTypeObject *type = Py_TYPE(obj); + + if (type->tp_as_async != NULL) { + getter = type->tp_as_async->am_aiter; + } + + if (getter == NULL) { + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' requires an object with " + "__aiter__ method, got %.100s", + type->tp_name); + Py_DECREF(obj); + if (true) goto pop_1_error; + } + + iter = (*getter)(obj); + Py_DECREF(obj); + if (iter == NULL) goto pop_1_error; + + if (Py_TYPE(iter)->tp_as_async == NULL || + Py_TYPE(iter)->tp_as_async->am_anext == NULL) { + + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' received an object from __aiter__ " + "that does not implement __anext__: %.100s", + Py_TYPE(iter)->tp_name); + Py_DECREF(iter); + if (true) goto pop_1_error; + } + POKE(1, iter); + DISPATCH(); + } + + TARGET(GET_ANEXT) { + PyObject *aiter = PEEK(1); + PyObject *awaitable; + unaryfunc getter = NULL; + PyObject *next_iter = NULL; + PyTypeObject *type = Py_TYPE(aiter); + + if (PyAsyncGen_CheckExact(aiter)) { + awaitable = type->tp_as_async->am_anext(aiter); + if (awaitable == NULL) { + goto error; + } + } else { + if (type->tp_as_async != NULL){ + getter = type->tp_as_async->am_anext; + } + + if (getter != NULL) { + next_iter = (*getter)(aiter); + if (next_iter == NULL) { + goto error; + } + } + else { + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' requires an iterator with " + "__anext__ method, got %.100s", + type->tp_name); + goto error; + } + + awaitable = _PyCoro_GetAwaitableIter(next_iter); + if (awaitable == NULL) { + _PyErr_FormatFromCause( + PyExc_TypeError, + "'async for' received an invalid object " + "from __anext__: %.100s", + Py_TYPE(next_iter)->tp_name); + + Py_DECREF(next_iter); + goto error; + } else { + Py_DECREF(next_iter); + } + } + + STACK_GROW(1); + POKE(1, awaitable); + PREDICT(LOAD_CONST); + DISPATCH(); + } + + TARGET(GET_AWAITABLE) { + PREDICTED(GET_AWAITABLE); + PyObject *iterable = PEEK(1); + PyObject *iter; + iter = _PyCoro_GetAwaitableIter(iterable); + + if (iter == NULL) { + format_awaitable_error(tstate, Py_TYPE(iterable), oparg); + } + + Py_DECREF(iterable); + + if (iter != NULL && PyCoro_CheckExact(iter)) { + PyObject *yf = _PyGen_yf((PyGenObject*)iter); + if (yf != NULL) { + /* `iter` is a coroutine object that is being + awaited, `yf` is a pointer to the current awaitable + being awaited on. */ + Py_DECREF(yf); + Py_CLEAR(iter); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "coroutine is being awaited already"); + /* The code below jumps to `error` if `iter` is NULL. */ + } + } + + if (iter == NULL) goto pop_1_error; + + POKE(1, iter); + PREDICT(LOAD_CONST); + DISPATCH(); + } + + TARGET(SEND) { + assert(frame != &entry_frame); + assert(STACK_LEVEL() >= 2); + PyObject *v = POP(); + PyObject *receiver = TOP(); + PySendResult gen_status; + PyObject *retval; + if (tstate->c_tracefunc == NULL) { + gen_status = PyIter_Send(receiver, v, &retval); + } else { + if (Py_IsNone(v) && PyIter_Check(receiver)) { + retval = Py_TYPE(receiver)->tp_iternext(receiver); + } + else { + retval = PyObject_CallMethodOneArg(receiver, &_Py_ID(send), v); + } + if (retval == NULL) { + if (tstate->c_tracefunc != NULL + && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) + call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, frame); + if (_PyGen_FetchStopIterationValue(&retval) == 0) { + gen_status = PYGEN_RETURN; + } + else { + gen_status = PYGEN_ERROR; + } + } + else { + gen_status = PYGEN_NEXT; + } + } + Py_DECREF(v); + if (gen_status == PYGEN_ERROR) { + assert(retval == NULL); + goto error; + } + if (gen_status == PYGEN_RETURN) { + assert(retval != NULL); + Py_DECREF(receiver); + SET_TOP(retval); + JUMPBY(oparg); + } + else { + assert(gen_status == PYGEN_NEXT); + assert(retval != NULL); + PUSH(retval); + } + DISPATCH(); + } + + TARGET(YIELD_VALUE) { + PyObject *retval = PEEK(1); + // NOTE: It's important that YIELD_VALUE never raises an exception! + // The compiler treats any exception raised here as a failed close() + // or throw() call. + assert(frame != &entry_frame); + PyGenObject *gen = _PyFrame_GetGenerator(frame); + gen->gi_frame_state = FRAME_SUSPENDED; + _PyFrame_SetStackPointer(frame, stack_pointer - 1); + TRACE_FUNCTION_EXIT(); + DTRACE_FUNCTION_EXIT(); + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *gen_frame = frame; + frame = cframe.current_frame = frame->previous; + gen_frame->previous = NULL; + frame->prev_instr -= frame->yield_offset; + _PyFrame_StackPush(frame, retval); + goto resume_frame; + } + + TARGET(POP_EXCEPT) { + PyObject *exc_value = PEEK(1); + _PyErr_StackItem *exc_info = tstate->exc_info; + Py_XSETREF(exc_info->exc_value, exc_value); + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(RERAISE) { + if (oparg) { + PyObject *lasti = PEEK(oparg + 1); + if (PyLong_Check(lasti)) { + frame->prev_instr = _PyCode_CODE(frame->f_code) + PyLong_AsLong(lasti); + assert(!_PyErr_Occurred(tstate)); + } + else { + assert(PyLong_Check(lasti)); + _PyErr_SetString(tstate, PyExc_SystemError, "lasti is not an int"); + goto error; + } + } + PyObject *val = POP(); + assert(val && PyExceptionInstance_Check(val)); + PyObject *exc = Py_NewRef(PyExceptionInstance_Class(val)); + PyObject *tb = PyException_GetTraceback(val); + _PyErr_Restore(tstate, exc, val, tb); + goto exception_unwind; + } + + TARGET(PREP_RERAISE_STAR) { + PyObject *excs = PEEK(1); + PyObject *orig = PEEK(2); + PyObject *val; + assert(PyList_Check(excs)); + + val = _PyExc_PrepReraiseStar(orig, excs); + Py_DECREF(orig); + Py_DECREF(excs); + + if (val == NULL) goto pop_2_error; + STACK_SHRINK(1); + POKE(1, val); + DISPATCH(); + } + + TARGET(END_ASYNC_FOR) { + PyObject *val = POP(); + assert(val && PyExceptionInstance_Check(val)); + if (PyErr_GivenExceptionMatches(val, PyExc_StopAsyncIteration)) { + Py_DECREF(val); + Py_DECREF(POP()); + } + else { + PyObject *exc = Py_NewRef(PyExceptionInstance_Class(val)); + PyObject *tb = PyException_GetTraceback(val); + _PyErr_Restore(tstate, exc, val, tb); + goto exception_unwind; + } + DISPATCH(); + } + + TARGET(CLEANUP_THROW) { + assert(throwflag); + PyObject *exc_value = TOP(); + assert(exc_value && PyExceptionInstance_Check(exc_value)); + if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) { + PyObject *value = ((PyStopIterationObject *)exc_value)->value; + Py_INCREF(value); + Py_DECREF(POP()); // The StopIteration. + Py_DECREF(POP()); // The last sent value. + Py_DECREF(POP()); // The delegated sub-iterator. + PUSH(value); + } + else { + PyObject *exc_type = Py_NewRef(Py_TYPE(exc_value)); + PyObject *exc_traceback = PyException_GetTraceback(exc_value); + _PyErr_Restore(tstate, exc_type, Py_NewRef(exc_value), exc_traceback); + goto exception_unwind; + } + DISPATCH(); + } + + TARGET(LOAD_ASSERTION_ERROR) { + PyObject *value; + value = Py_NewRef(PyExc_AssertionError); + STACK_GROW(1); + POKE(1, value); + DISPATCH(); + } + + TARGET(LOAD_BUILD_CLASS) { + PyObject *bc; + if (PyDict_CheckExact(BUILTINS())) { + bc = _PyDict_GetItemWithError(BUILTINS(), + &_Py_ID(__build_class__)); + if (bc == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_NameError, + "__build_class__ not found"); + } + if (true) goto error; + } + Py_INCREF(bc); + } + else { + bc = PyObject_GetItem(BUILTINS(), &_Py_ID(__build_class__)); + if (bc == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) + _PyErr_SetString(tstate, PyExc_NameError, + "__build_class__ not found"); + if (true) goto error; + } + } + STACK_GROW(1); + POKE(1, bc); + DISPATCH(); + } + + TARGET(STORE_NAME) { + PyObject *v = PEEK(1); + PyObject *name = GETITEM(names, oparg); + PyObject *ns = LOCALS(); + int err; + if (ns == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals found when storing %R", name); + Py_DECREF(v); + if (true) goto pop_1_error; + } + if (PyDict_CheckExact(ns)) + err = PyDict_SetItem(ns, name, v); + else + err = PyObject_SetItem(ns, name, v); + Py_DECREF(v); + if (err) goto pop_1_error; + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(DELETE_NAME) { + PyObject *name = GETITEM(names, oparg); + PyObject *ns = LOCALS(); + int err; + if (ns == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals when deleting %R", name); + goto error; + } + err = PyObject_DelItem(ns, name); + // Can't use ERROR_IF here. + if (err != 0) { + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, + name); + goto error; + } + DISPATCH(); + } + + TARGET(UNPACK_SEQUENCE) { + PREDICTED(UNPACK_SEQUENCE); + #if ENABLE_SPECIALIZATION + _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + assert(cframe.use_tracing == 0); + PyObject *seq = TOP(); + next_instr--; + _Py_Specialize_UnpackSequence(seq, next_instr, oparg); + DISPATCH_SAME_OPARG(); + } + STAT_INC(UNPACK_SEQUENCE, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + PyObject *seq = POP(); + PyObject **top = stack_pointer + oparg; + if (!unpack_iterable(tstate, seq, oparg, -1, top)) { + Py_DECREF(seq); + goto error; + } + STACK_GROW(oparg); + Py_DECREF(seq); + JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); + DISPATCH(); + } + + TARGET(UNPACK_SEQUENCE_TWO_TUPLE) { + PyObject *seq = TOP(); + DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); + DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE); + STAT_INC(UNPACK_SEQUENCE, hit); + SET_TOP(Py_NewRef(PyTuple_GET_ITEM(seq, 1))); + PUSH(Py_NewRef(PyTuple_GET_ITEM(seq, 0))); + Py_DECREF(seq); + JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); + DISPATCH(); + } + + TARGET(UNPACK_SEQUENCE_TUPLE) { + PyObject *seq = TOP(); + DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); + DEOPT_IF(PyTuple_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); + STAT_INC(UNPACK_SEQUENCE, hit); + STACK_SHRINK(1); + PyObject **items = _PyTuple_ITEMS(seq); + while (oparg--) { + PUSH(Py_NewRef(items[oparg])); + } + Py_DECREF(seq); + JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); + DISPATCH(); + } + + TARGET(UNPACK_SEQUENCE_LIST) { + PyObject *seq = TOP(); + DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE); + DEOPT_IF(PyList_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); + STAT_INC(UNPACK_SEQUENCE, hit); + STACK_SHRINK(1); + PyObject **items = _PyList_ITEMS(seq); + while (oparg--) { + PUSH(Py_NewRef(items[oparg])); + } + Py_DECREF(seq); + JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); + DISPATCH(); + } + + TARGET(UNPACK_EX) { + int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); + PyObject *seq = POP(); + PyObject **top = stack_pointer + totalargs; + if (!unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, top)) { + Py_DECREF(seq); + goto error; + } + STACK_GROW(totalargs); + Py_DECREF(seq); + DISPATCH(); + } + + TARGET(STORE_ATTR) { + PREDICTED(STORE_ATTR); + PyObject *owner = PEEK(1); + PyObject *v = PEEK(2); + uint16_t counter = read_u16(&next_instr[0].cache); + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + assert(cframe.use_tracing == 0); + PyObject *name = GETITEM(names, oparg); + next_instr--; + _Py_Specialize_StoreAttr(owner, next_instr, name); + DISPATCH_SAME_OPARG(); + } + STAT_INC(STORE_ATTR, deferred); + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #else + (void)counter; // Unused. + #endif /* ENABLE_SPECIALIZATION */ + PyObject *name = GETITEM(names, oparg); + int err = PyObject_SetAttr(owner, name, v); + Py_DECREF(v); + Py_DECREF(owner); + if (err) goto pop_2_error; + STACK_SHRINK(2); + JUMPBY(4); + DISPATCH(); + } + + TARGET(DELETE_ATTR) { + PyObject *owner = PEEK(1); + PyObject *name = GETITEM(names, oparg); + int err = PyObject_SetAttr(owner, name, (PyObject *)NULL); + Py_DECREF(owner); + if (err) goto pop_1_error; + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(STORE_GLOBAL) { + PyObject *v = PEEK(1); + PyObject *name = GETITEM(names, oparg); + int err = PyDict_SetItem(GLOBALS(), name, v); + Py_DECREF(v); + if (err) goto pop_1_error; + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(DELETE_GLOBAL) { + PyObject *name = GETITEM(names, oparg); + int err; + err = PyDict_DelItem(GLOBALS(), name); + // Can't use ERROR_IF here. + if (err != 0) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + DISPATCH(); + } + + TARGET(LOAD_NAME) { + PyObject *v; + PyObject *name = GETITEM(names, oparg); + PyObject *locals = LOCALS(); + if (locals == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals when loading %R", name); + goto error; + } + if (PyDict_CheckExact(locals)) { + v = PyDict_GetItemWithError(locals, name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + } + else { + v = PyObject_GetItem(locals, name); + if (v == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) + goto error; + _PyErr_Clear(tstate); + } + } + if (v == NULL) { + v = PyDict_GetItemWithError(GLOBALS(), name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + else { + if (PyDict_CheckExact(BUILTINS())) { + v = PyDict_GetItemWithError(BUILTINS(), name); + if (v == NULL) { + if (!_PyErr_Occurred(tstate)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + Py_INCREF(v); + } + else { + v = PyObject_GetItem(BUILTINS(), name); + if (v == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + } + } + } + STACK_GROW(1); + POKE(1, v); + DISPATCH(); + } + + TARGET(LOAD_GLOBAL) { + PREDICTED(LOAD_GLOBAL); + #if ENABLE_SPECIALIZATION + _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + assert(cframe.use_tracing == 0); + PyObject *name = GETITEM(names, oparg>>1); + next_instr--; + _Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name); + DISPATCH_SAME_OPARG(); + } + STAT_INC(LOAD_GLOBAL, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + int push_null = oparg & 1; + PEEK(0) = NULL; + PyObject *name = GETITEM(names, oparg>>1); + PyObject *v; + if (PyDict_CheckExact(GLOBALS()) + && PyDict_CheckExact(BUILTINS())) + { + v = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(), + (PyDictObject *)BUILTINS(), + name); + if (v == NULL) { + if (!_PyErr_Occurred(tstate)) { + /* _PyDict_LoadGlobal() returns NULL without raising + * an exception if the key doesn't exist */ + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + Py_INCREF(v); + } + else { + /* Slow-path if globals or builtins is not a dict */ + + /* namespace 1: globals */ + v = PyObject_GetItem(GLOBALS(), name); + if (v == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + goto error; + } + _PyErr_Clear(tstate); + + /* namespace 2: builtins */ + v = PyObject_GetItem(BUILTINS(), name); + if (v == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + } + } + /* Skip over inline cache */ + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); + STACK_GROW(push_null); + PUSH(v); + DISPATCH(); + } + + TARGET(LOAD_GLOBAL_MODULE) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); + PyDictObject *dict = (PyDictObject *)GLOBALS(); + _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; + uint32_t version = read_u32(cache->module_keys_version); + DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); + assert(DK_IS_UNICODE(dict->ma_keys)); + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); + PyObject *res = entries[cache->index].me_value; + DEOPT_IF(res == NULL, LOAD_GLOBAL); + int push_null = oparg & 1; + PEEK(0) = NULL; + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); + STAT_INC(LOAD_GLOBAL, hit); + STACK_GROW(push_null+1); + SET_TOP(Py_NewRef(res)); + DISPATCH(); + } + + TARGET(LOAD_GLOBAL_BUILTIN) { + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); + DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL); + PyDictObject *mdict = (PyDictObject *)GLOBALS(); + PyDictObject *bdict = (PyDictObject *)BUILTINS(); + _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; + uint32_t mod_version = read_u32(cache->module_keys_version); + uint16_t bltn_version = cache->builtin_keys_version; + DEOPT_IF(mdict->ma_keys->dk_version != mod_version, LOAD_GLOBAL); + DEOPT_IF(bdict->ma_keys->dk_version != bltn_version, LOAD_GLOBAL); + assert(DK_IS_UNICODE(bdict->ma_keys)); + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); + PyObject *res = entries[cache->index].me_value; + DEOPT_IF(res == NULL, LOAD_GLOBAL); + int push_null = oparg & 1; + PEEK(0) = NULL; + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); + STAT_INC(LOAD_GLOBAL, hit); + STACK_GROW(push_null+1); + SET_TOP(Py_NewRef(res)); + DISPATCH(); + } + + TARGET(DELETE_FAST) { + PyObject *v = GETLOCAL(oparg); + if (v == NULL) goto unbound_local_error; + SETLOCAL(oparg, NULL); + DISPATCH(); + } + + TARGET(MAKE_CELL) { + // "initial" is probably NULL but not if it's an arg (or set + // via PyFrame_LocalsToFast() before MAKE_CELL has run). + PyObject *initial = GETLOCAL(oparg); + PyObject *cell = PyCell_New(initial); + if (cell == NULL) { + goto resume_with_error; + } + SETLOCAL(oparg, cell); + DISPATCH(); + } + + TARGET(DELETE_DEREF) { + PyObject *cell = GETLOCAL(oparg); + PyObject *oldobj = PyCell_GET(cell); + // Can't use ERROR_IF here. + // Fortunately we don't need its superpower. + if (oldobj == NULL) { + format_exc_unbound(tstate, frame->f_code, oparg); + goto error; + } + PyCell_SET(cell, NULL); + Py_DECREF(oldobj); + DISPATCH(); + } + + TARGET(LOAD_CLASSDEREF) { + PyObject *value; + PyObject *name, *locals = LOCALS(); + assert(locals); + assert(oparg >= 0 && oparg < frame->f_code->co_nlocalsplus); + name = PyTuple_GET_ITEM(frame->f_code->co_localsplusnames, oparg); + if (PyDict_CheckExact(locals)) { + value = PyDict_GetItemWithError(locals, name); + if (value != NULL) { + Py_INCREF(value); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + } + else { + value = PyObject_GetItem(locals, name); + if (value == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + goto error; + } + _PyErr_Clear(tstate); + } + } + if (!value) { + PyObject *cell = GETLOCAL(oparg); + value = PyCell_GET(cell); + if (value == NULL) { + format_exc_unbound(tstate, frame->f_code, oparg); + goto error; + } + Py_INCREF(value); + } + STACK_GROW(1); + POKE(1, value); + DISPATCH(); + } + + TARGET(LOAD_DEREF) { + PyObject *value; + PyObject *cell = GETLOCAL(oparg); + value = PyCell_GET(cell); + if (value == NULL) { + format_exc_unbound(tstate, frame->f_code, oparg); + if (true) goto error; + } + Py_INCREF(value); + STACK_GROW(1); + POKE(1, value); + DISPATCH(); + } + + TARGET(STORE_DEREF) { + PyObject *v = PEEK(1); + PyObject *cell = GETLOCAL(oparg); + PyObject *oldobj = PyCell_GET(cell); + PyCell_SET(cell, v); + Py_XDECREF(oldobj); + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(COPY_FREE_VARS) { + /* Copy closure variables to free variables */ + PyCodeObject *co = frame->f_code; + assert(PyFunction_Check(frame->f_funcobj)); + PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure; + assert(oparg == co->co_nfreevars); + int offset = co->co_nlocalsplus - oparg; + for (int i = 0; i < oparg; ++i) { + PyObject *o = PyTuple_GET_ITEM(closure, i); + frame->localsplus[offset + i] = Py_NewRef(o); + } + DISPATCH(); + } + + TARGET(BUILD_STRING) { + PyObject **pieces = &PEEK(oparg); + PyObject *str; + str = _PyUnicode_JoinArray(&_Py_STR(empty), pieces, oparg); + for (int i = 0; i < oparg; i++) { + Py_DECREF(pieces[i]); + } + if (str == NULL) { STACK_SHRINK(oparg); goto error; } + STACK_SHRINK(oparg); + STACK_GROW(1); + POKE(1, str); + DISPATCH(); + } + + TARGET(BUILD_TUPLE) { + PyObject **values = &PEEK(oparg); + PyObject *tup; + tup = _PyTuple_FromArraySteal(values, oparg); + if (tup == NULL) { STACK_SHRINK(oparg); goto error; } + STACK_SHRINK(oparg); + STACK_GROW(1); + POKE(1, tup); + DISPATCH(); + } + + TARGET(BUILD_LIST) { + PyObject **values = &PEEK(oparg); + PyObject *list; + list = _PyList_FromArraySteal(values, oparg); + if (list == NULL) { STACK_SHRINK(oparg); goto error; } + STACK_SHRINK(oparg); + STACK_GROW(1); + POKE(1, list); + DISPATCH(); + } + + TARGET(LIST_EXTEND) { + PyObject *iterable = PEEK(1); + PyObject *list = PEEK(2 + (oparg-1)); + PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); + if (none_val == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && + (Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable))) + { + _PyErr_Clear(tstate); + _PyErr_Format(tstate, PyExc_TypeError, + "Value after * must be an iterable, not %.200s", + Py_TYPE(iterable)->tp_name); + } + Py_DECREF(iterable); + if (true) goto pop_1_error; + } + Py_DECREF(none_val); + Py_DECREF(iterable); + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(SET_UPDATE) { + PyObject *iterable = PEEK(1); + PyObject *set = PEEK(2 + (oparg-1)); + int err = _PySet_Update(set, iterable); + Py_DECREF(iterable); + if (err < 0) goto pop_1_error; + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(BUILD_SET) { + PyObject **values = &PEEK(oparg); + PyObject *set; + set = PySet_New(NULL); + int err = 0; + for (int i = 0; i < oparg; i++) { + PyObject *item = values[i]; + if (err == 0) + err = PySet_Add(set, item); + Py_DECREF(item); + } + if (err != 0) { + Py_DECREF(set); + if (true) { STACK_SHRINK(oparg); goto error; } + } + STACK_SHRINK(oparg); + STACK_GROW(1); + POKE(1, set); + DISPATCH(); + } + + TARGET(BUILD_MAP) { + PyObject **values = &PEEK(oparg*2); + PyObject *map; + map = _PyDict_FromItems( + values, 2, + values+1, 2, + oparg); + if (map == NULL) + goto error; + + for (int i = 0; i < oparg; i++) { + Py_DECREF(values[i*2]); + Py_DECREF(values[i*2+1]); + } + if (map == NULL) { STACK_SHRINK(oparg*2); goto error; } + STACK_SHRINK(oparg*2); + STACK_GROW(1); + POKE(1, map); + DISPATCH(); + } + + TARGET(SETUP_ANNOTATIONS) { + int err; + PyObject *ann_dict; + if (LOCALS() == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals found when setting up annotations"); + if (true) goto error; + } + /* check if __annotations__ in locals()... */ + if (PyDict_CheckExact(LOCALS())) { + ann_dict = _PyDict_GetItemWithError(LOCALS(), + &_Py_ID(__annotations__)); + if (ann_dict == NULL) { + if (_PyErr_Occurred(tstate)) goto error; + /* ...if not, create a new one */ + ann_dict = PyDict_New(); + if (ann_dict == NULL) goto error; + err = PyDict_SetItem(LOCALS(), &_Py_ID(__annotations__), + ann_dict); + Py_DECREF(ann_dict); + if (err) goto error; + } + } + else { + /* do the same if locals() is not a dict */ + ann_dict = PyObject_GetItem(LOCALS(), &_Py_ID(__annotations__)); + if (ann_dict == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) goto error; + _PyErr_Clear(tstate); + ann_dict = PyDict_New(); + if (ann_dict == NULL) goto error; + err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__), + ann_dict); + Py_DECREF(ann_dict); + if (err) goto error; + } + else { + Py_DECREF(ann_dict); + } + } + DISPATCH(); + } + + TARGET(BUILD_CONST_KEY_MAP) { + PyObject *keys = PEEK(1); + PyObject **values = &PEEK(1 + oparg); + PyObject *map; + if (!PyTuple_CheckExact(keys) || + PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { + _PyErr_SetString(tstate, PyExc_SystemError, + "bad BUILD_CONST_KEY_MAP keys argument"); + goto error; // Pop the keys and values. + } + map = _PyDict_FromItems( + &PyTuple_GET_ITEM(keys, 0), 1, + values, 1, oparg); + Py_DECREF(keys); + for (int i = 0; i < oparg; i++) { + Py_DECREF(values[i]); + } + if (map == NULL) { STACK_SHRINK(oparg); goto pop_1_error; } + STACK_SHRINK(oparg); + POKE(1, map); + DISPATCH(); + } + + TARGET(DICT_UPDATE) { + PyObject *update = PEEK(1); + PyObject *dict = PEEK(oparg + 1); // update is still on the stack + if (PyDict_Update(dict, update) < 0) { + if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object is not a mapping", + Py_TYPE(update)->tp_name); + } + Py_DECREF(update); + if (true) goto pop_1_error; + } + Py_DECREF(update); + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(DICT_MERGE) { + PyObject *update = PEEK(1); + PyObject *dict = PEEK(oparg + 1); // update is still on the stack + + if (_PyDict_MergeEx(dict, update, 2) < 0) { + format_kwargs_error(tstate, PEEK(3 + oparg), update); + Py_DECREF(update); + if (true) goto pop_1_error; + } + Py_DECREF(update); + STACK_SHRINK(1); + PREDICT(CALL_FUNCTION_EX); + DISPATCH(); + } + + TARGET(MAP_ADD) { + PyObject *value = PEEK(1); + PyObject *key = PEEK(2); + PyObject *dict = PEEK(oparg + 2); // key, value are still on the stack + assert(PyDict_CheckExact(dict)); + /* dict[key] = value */ + // Do not DECREF INPUTS because the function steals the references + if (_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0) goto pop_2_error; + STACK_SHRINK(2); + PREDICT(JUMP_BACKWARD); + DISPATCH(); + } + + TARGET(LOAD_ATTR) { + PREDICTED(LOAD_ATTR); + PyObject *owner = PEEK(1); + PyObject *res2 = NULL; + PyObject *res; + #if ENABLE_SPECIALIZATION + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + assert(cframe.use_tracing == 0); + PyObject *name = GETITEM(names, oparg>>1); + next_instr--; + _Py_Specialize_LoadAttr(owner, next_instr, name); + DISPATCH_SAME_OPARG(); + } + STAT_INC(LOAD_ATTR, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + PyObject *name = GETITEM(names, oparg >> 1); + if (oparg & 1) { + /* Designed to work in tandem with CALL, pushes two values. */ + PyObject* meth = NULL; + if (_PyObject_GetMethod(owner, name, &meth)) { + /* We can bypass temporary bound method object. + meth is unbound method and obj is self. + + meth | self | arg1 | ... | argN + */ + assert(meth != NULL); // No errors on this branch + res2 = meth; + res = owner; // Transfer ownership + } + else { + /* meth is not an unbound method (but a regular attr, or + something was returned by a descriptor protocol). Set + the second element of the stack to NULL, to signal + CALL that it's not a method call. + + NULL | meth | arg1 | ... | argN + */ + Py_DECREF(owner); + if (meth == NULL) goto pop_1_error; + res2 = NULL; + res = meth; + } + } + else { + /* Classic, pushes one value. */ + res = PyObject_GetAttr(owner, name); + Py_DECREF(owner); + if (res == NULL) goto pop_1_error; + } + STACK_GROW(((oparg & 1) ? 1 : 0)); + POKE(1, res); + if (oparg & 1) { POKE(1 + ((oparg & 1) ? 1 : 0), res2); } + JUMPBY(9); + DISPATCH(); + } + + TARGET(LOAD_ATTR_INSTANCE_VALUE) { + assert(cframe.use_tracing == 0); + PyObject *owner = TOP(); + PyObject *res; + PyTypeObject *tp = Py_TYPE(owner); + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + uint32_t type_version = read_u32(cache->version); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + assert(tp->tp_dictoffset < 0); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + res = _PyDictOrValues_GetValues(dorv)->values[cache->index]; + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + SET_TOP(NULL); + STACK_GROW((oparg & 1)); + SET_TOP(res); + Py_DECREF(owner); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + DISPATCH(); + } + + TARGET(LOAD_ATTR_MODULE) { + assert(cframe.use_tracing == 0); + PyObject *owner = TOP(); + PyObject *res; + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR); + PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; + assert(dict != NULL); + DEOPT_IF(dict->ma_keys->dk_version != read_u32(cache->version), + LOAD_ATTR); + assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); + assert(cache->index < dict->ma_keys->dk_nentries); + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + cache->index; + res = ep->me_value; + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + SET_TOP(NULL); + STACK_GROW((oparg & 1)); + SET_TOP(res); + Py_DECREF(owner); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + DISPATCH(); + } + + TARGET(LOAD_ATTR_WITH_HINT) { + assert(cframe.use_tracing == 0); + PyObject *owner = TOP(); + PyObject *res; + PyTypeObject *tp = Py_TYPE(owner); + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + uint32_t type_version = read_u32(cache->version); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + DEOPT_IF(dict == NULL, LOAD_ATTR); + assert(PyDict_CheckExact((PyObject *)dict)); + PyObject *name = GETITEM(names, oparg>>1); + uint16_t hint = cache->index; + DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR); + if (DK_IS_UNICODE(dict->ma_keys)) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, LOAD_ATTR); + res = ep->me_value; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, LOAD_ATTR); + res = ep->me_value; + } + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + SET_TOP(NULL); + STACK_GROW((oparg & 1)); + SET_TOP(res); + Py_DECREF(owner); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + DISPATCH(); + } + + TARGET(LOAD_ATTR_SLOT) { + assert(cframe.use_tracing == 0); + PyObject *owner = TOP(); + PyObject *res; + PyTypeObject *tp = Py_TYPE(owner); + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + uint32_t type_version = read_u32(cache->version); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + char *addr = (char *)owner + cache->index; + res = *(PyObject **)addr; + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + SET_TOP(NULL); + STACK_GROW((oparg & 1)); + SET_TOP(res); + Py_DECREF(owner); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + DISPATCH(); + } + + TARGET(LOAD_ATTR_CLASS) { + assert(cframe.use_tracing == 0); + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; + + PyObject *cls = TOP(); + DEOPT_IF(!PyType_Check(cls), LOAD_ATTR); + uint32_t type_version = read_u32(cache->type_version); + DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != type_version, + LOAD_ATTR); + assert(type_version != 0); + + STAT_INC(LOAD_ATTR, hit); + PyObject *res = read_obj(cache->descr); + assert(res != NULL); + Py_INCREF(res); + SET_TOP(NULL); + STACK_GROW((oparg & 1)); + SET_TOP(res); + Py_DECREF(cls); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + DISPATCH(); + } + + TARGET(LOAD_ATTR_PROPERTY) { + assert(cframe.use_tracing == 0); + DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; + + PyObject *owner = TOP(); + PyTypeObject *cls = Py_TYPE(owner); + uint32_t type_version = read_u32(cache->type_version); + DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); + assert(type_version != 0); + PyObject *fget = read_obj(cache->descr); + assert(Py_IS_TYPE(fget, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)fget; + uint32_t func_version = read_u32(cache->keys_version); + assert(func_version != 0); + DEOPT_IF(f->func_version != func_version, LOAD_ATTR); + PyCodeObject *code = (PyCodeObject *)f->func_code; + assert(code->co_argcount == 1); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(fget); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 1); + SET_TOP(NULL); + int shrink_stack = !(oparg & 1); + STACK_SHRINK(shrink_stack); + new_frame->localsplus[0] = owner; + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + DISPATCH_INLINED(new_frame); + } + + TARGET(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN) { + assert(cframe.use_tracing == 0); + DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; + PyObject *owner = TOP(); + PyTypeObject *cls = Py_TYPE(owner); + uint32_t type_version = read_u32(cache->type_version); + DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); + assert(type_version != 0); + PyObject *getattribute = read_obj(cache->descr); + assert(Py_IS_TYPE(getattribute, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)getattribute; + uint32_t func_version = read_u32(cache->keys_version); + assert(func_version != 0); + DEOPT_IF(f->func_version != func_version, LOAD_ATTR); + PyCodeObject *code = (PyCodeObject *)f->func_code; + assert(code->co_argcount == 2); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + + PyObject *name = GETITEM(names, oparg >> 1); + Py_INCREF(f); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 2); + SET_TOP(NULL); + int shrink_stack = !(oparg & 1); + STACK_SHRINK(shrink_stack); + new_frame->localsplus[0] = owner; + new_frame->localsplus[1] = Py_NewRef(name); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + DISPATCH_INLINED(new_frame); + } + + TARGET(STORE_ATTR_INSTANCE_VALUE) { + PyObject *owner = PEEK(1); + PyObject *value = PEEK(2); + uint32_t type_version = read_u32(&next_instr[1].cache); + uint16_t index = read_u16(&next_instr[3].cache); + assert(cframe.use_tracing == 0); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), STORE_ATTR); + STAT_INC(STORE_ATTR, hit); + PyDictValues *values = _PyDictOrValues_GetValues(dorv); + PyObject *old_value = values->values[index]; + values->values[index] = value; + if (old_value == NULL) { + _PyDictValues_AddToInsertionOrder(values, index); + } + else { + Py_DECREF(old_value); + } + Py_DECREF(owner); + STACK_SHRINK(2); + JUMPBY(4); + DISPATCH(); + } + + TARGET(STORE_ATTR_WITH_HINT) { + PyObject *owner = PEEK(1); + PyObject *value = PEEK(2); + uint32_t type_version = read_u32(&next_instr[1].cache); + uint16_t hint = read_u16(&next_instr[3].cache); + assert(cframe.use_tracing == 0); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(_PyDictOrValues_IsValues(dorv), STORE_ATTR); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + DEOPT_IF(dict == NULL, STORE_ATTR); + assert(PyDict_CheckExact((PyObject *)dict)); + PyObject *name = GETITEM(names, oparg); + DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, STORE_ATTR); + PyObject *old_value; + uint64_t new_version; + if (DK_IS_UNICODE(dict->ma_keys)) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, STORE_ATTR); + old_value = ep->me_value; + DEOPT_IF(old_value == NULL, STORE_ATTR); + new_version = _PyDict_NotifyEvent(PyDict_EVENT_MODIFIED, dict, name, value); + ep->me_value = value; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, STORE_ATTR); + old_value = ep->me_value; + DEOPT_IF(old_value == NULL, STORE_ATTR); + new_version = _PyDict_NotifyEvent(PyDict_EVENT_MODIFIED, dict, name, value); + ep->me_value = value; + } + Py_DECREF(old_value); + STAT_INC(STORE_ATTR, hit); + /* Ensure dict is GC tracked if it needs to be */ + if (!_PyObject_GC_IS_TRACKED(dict) && _PyObject_GC_MAY_BE_TRACKED(value)) { + _PyObject_GC_TRACK(dict); + } + /* PEP 509 */ + dict->ma_version_tag = new_version; + Py_DECREF(owner); + STACK_SHRINK(2); + JUMPBY(4); + DISPATCH(); + } + + TARGET(STORE_ATTR_SLOT) { + PyObject *owner = PEEK(1); + PyObject *value = PEEK(2); + uint32_t type_version = read_u32(&next_instr[1].cache); + uint16_t index = read_u16(&next_instr[3].cache); + assert(cframe.use_tracing == 0); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + char *addr = (char *)owner + index; + STAT_INC(STORE_ATTR, hit); + PyObject *old_value = *(PyObject **)addr; + *(PyObject **)addr = value; + Py_XDECREF(old_value); + Py_DECREF(owner); + STACK_SHRINK(2); + JUMPBY(4); + DISPATCH(); + } + + TARGET(COMPARE_OP) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + PyObject *res; + STAT_INC(COMPARE_OP, deferred); + assert((oparg >> 4) <= Py_GE); + res = PyObject_RichCompare(left, right, oparg>>4); + Py_DECREF(left); + Py_DECREF(right); + if (res == NULL) goto pop_2_error; + STACK_SHRINK(1); + POKE(1, res); + JUMPBY(1); + DISPATCH(); + } + + TARGET(COMPARE_AND_BRANCH) { + PREDICTED(COMPARE_AND_BRANCH); + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + #if ENABLE_SPECIALIZATION + _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + assert(cframe.use_tracing == 0); + next_instr--; + _Py_Specialize_CompareAndBranch(left, right, next_instr, oparg); + DISPATCH_SAME_OPARG(); + } + STAT_INC(COMPARE_AND_BRANCH, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + assert((oparg >> 4) <= Py_GE); + PyObject *cond = PyObject_RichCompare(left, right, oparg>>4); + Py_DECREF(left); + Py_DECREF(right); + if (cond == NULL) goto pop_2_error; + assert(_Py_OPCODE(next_instr[1]) == POP_JUMP_IF_FALSE || + _Py_OPCODE(next_instr[1]) == POP_JUMP_IF_TRUE); + bool jump_on_true = _Py_OPCODE(next_instr[1]) == POP_JUMP_IF_TRUE; + int offset = _Py_OPARG(next_instr[1]); + int err = PyObject_IsTrue(cond); + Py_DECREF(cond); + if (err < 0) { + goto error; + } + if (jump_on_true == (err != 0)) { + JUMPBY(offset); + } + STACK_SHRINK(2); + JUMPBY(2); + DISPATCH(); + } + + TARGET(COMPARE_AND_BRANCH_FLOAT) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_AND_BRANCH); + DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_AND_BRANCH); + STAT_INC(COMPARE_AND_BRANCH, hit); + double dleft = PyFloat_AS_DOUBLE(left); + double dright = PyFloat_AS_DOUBLE(right); + // 1 if NaN, 2 if <, 4 if >, 8 if ==; this matches low four bits of the oparg + int sign_ish = COMPARISON_BIT(dleft, dright); + _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); + _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); + if (sign_ish & oparg) { + int offset = _Py_OPARG(next_instr[1]); + JUMPBY(offset); + } + STACK_SHRINK(2); + JUMPBY(2); + DISPATCH(); + } + + TARGET(COMPARE_AND_BRANCH_INT) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyLong_CheckExact(left), COMPARE_AND_BRANCH); + DEOPT_IF(!PyLong_CheckExact(right), COMPARE_AND_BRANCH); + DEOPT_IF((size_t)(Py_SIZE(left) + 1) > 2, COMPARE_AND_BRANCH); + DEOPT_IF((size_t)(Py_SIZE(right) + 1) > 2, COMPARE_AND_BRANCH); + STAT_INC(COMPARE_AND_BRANCH, hit); + assert(Py_ABS(Py_SIZE(left)) <= 1 && Py_ABS(Py_SIZE(right)) <= 1); + Py_ssize_t ileft = Py_SIZE(left) * ((PyLongObject *)left)->ob_digit[0]; + Py_ssize_t iright = Py_SIZE(right) * ((PyLongObject *)right)->ob_digit[0]; + // 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg + int sign_ish = COMPARISON_BIT(ileft, iright); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + if (sign_ish & oparg) { + int offset = _Py_OPARG(next_instr[1]); + JUMPBY(offset); + } + STACK_SHRINK(2); + JUMPBY(2); + DISPATCH(); + } + + TARGET(COMPARE_AND_BRANCH_STR) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + assert(cframe.use_tracing == 0); + DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_AND_BRANCH); + DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_AND_BRANCH); + STAT_INC(COMPARE_AND_BRANCH, hit); + int res = _PyUnicode_Equal(left, right); + assert((oparg >>4) == Py_EQ || (oparg >>4) == Py_NE); + _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); + _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); + assert(res == 0 || res == 1); + assert((oparg & 0xf) == COMPARISON_NOT_EQUALS || (oparg & 0xf) == COMPARISON_EQUALS); + assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS); + if ((res + COMPARISON_NOT_EQUALS) & oparg) { + int offset = _Py_OPARG(next_instr[1]); + JUMPBY(offset); + } + STACK_SHRINK(2); + JUMPBY(2); + DISPATCH(); + } + + TARGET(IS_OP) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + PyObject *b; + int res = Py_Is(left, right) ^ oparg; + Py_DECREF(left); + Py_DECREF(right); + b = Py_NewRef(res ? Py_True : Py_False); + STACK_SHRINK(1); + POKE(1, b); + DISPATCH(); + } + + TARGET(CONTAINS_OP) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + PyObject *b; + int res = PySequence_Contains(right, left); + Py_DECREF(left); + Py_DECREF(right); + if (res < 0) goto pop_2_error; + b = Py_NewRef((res^oparg) ? Py_True : Py_False); + STACK_SHRINK(1); + POKE(1, b); + DISPATCH(); + } + + TARGET(CHECK_EG_MATCH) { + PyObject *match_type = PEEK(1); + PyObject *exc_value = PEEK(2); + PyObject *rest; + PyObject *match; + if (check_except_star_type_valid(tstate, match_type) < 0) { + Py_DECREF(exc_value); + Py_DECREF(match_type); + if (true) goto pop_2_error; + } + + match = NULL; + rest = NULL; + int res = exception_group_match(exc_value, match_type, + &match, &rest); + Py_DECREF(exc_value); + Py_DECREF(match_type); + if (res < 0) goto pop_2_error; + + assert((match == NULL) == (rest == NULL)); + if (match == NULL) goto pop_2_error; + + if (!Py_IsNone(match)) { + PyErr_SetExcInfo(NULL, Py_NewRef(match), NULL); + } + POKE(1, match); + POKE(2, rest); + DISPATCH(); + } + + TARGET(CHECK_EXC_MATCH) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + PyObject *b; + assert(PyExceptionInstance_Check(left)); + if (check_except_type_valid(tstate, right) < 0) { + Py_DECREF(right); + if (true) goto pop_1_error; + } + + int res = PyErr_GivenExceptionMatches(left, right); + Py_DECREF(right); + b = Py_NewRef(res ? Py_True : Py_False); + POKE(1, b); + DISPATCH(); + } + + TARGET(IMPORT_NAME) { + PyObject *fromlist = PEEK(1); + PyObject *level = PEEK(2); + PyObject *res; + PyObject *name = GETITEM(names, oparg); + res = import_name(tstate, frame, name, fromlist, level); + Py_DECREF(level); + Py_DECREF(fromlist); + if (res == NULL) goto pop_2_error; + STACK_SHRINK(1); + POKE(1, res); + DISPATCH(); + } + + TARGET(IMPORT_FROM) { + PyObject *from = PEEK(1); + PyObject *res; + PyObject *name = GETITEM(names, oparg); + res = import_from(tstate, from, name); + if (res == NULL) goto error; + STACK_GROW(1); + POKE(1, res); + DISPATCH(); + } + + TARGET(JUMP_FORWARD) { + JUMPBY(oparg); + DISPATCH(); + } + + TARGET(JUMP_BACKWARD) { + PREDICTED(JUMP_BACKWARD); + assert(oparg < INSTR_OFFSET()); + JUMPBY(-oparg); + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(POP_JUMP_IF_FALSE) { + PREDICTED(POP_JUMP_IF_FALSE); + PyObject *cond = POP(); + if (Py_IsTrue(cond)) { + _Py_DECREF_NO_DEALLOC(cond); + } + else if (Py_IsFalse(cond)) { + _Py_DECREF_NO_DEALLOC(cond); + JUMPBY(oparg); + } + else { + int err = PyObject_IsTrue(cond); + Py_DECREF(cond); + if (err > 0) + ; + else if (err == 0) { + JUMPBY(oparg); + } + else + goto error; + } + DISPATCH(); + } + + TARGET(POP_JUMP_IF_TRUE) { + PyObject *cond = POP(); + if (Py_IsFalse(cond)) { + _Py_DECREF_NO_DEALLOC(cond); + } + else if (Py_IsTrue(cond)) { + _Py_DECREF_NO_DEALLOC(cond); + JUMPBY(oparg); + } + else { + int err = PyObject_IsTrue(cond); + Py_DECREF(cond); + if (err > 0) { + JUMPBY(oparg); + } + else if (err == 0) + ; + else + goto error; + } + DISPATCH(); + } + + TARGET(POP_JUMP_IF_NOT_NONE) { + PyObject *value = POP(); + if (!Py_IsNone(value)) { + JUMPBY(oparg); + } + Py_DECREF(value); + DISPATCH(); + } + + TARGET(POP_JUMP_IF_NONE) { + PyObject *value = POP(); + if (Py_IsNone(value)) { + _Py_DECREF_NO_DEALLOC(value); + JUMPBY(oparg); + } + else { + Py_DECREF(value); + } + DISPATCH(); + } + + TARGET(JUMP_IF_FALSE_OR_POP) { + PyObject *cond = TOP(); + int err; + if (Py_IsTrue(cond)) { + STACK_SHRINK(1); + _Py_DECREF_NO_DEALLOC(cond); + } + else if (Py_IsFalse(cond)) { + JUMPBY(oparg); + } + else { + err = PyObject_IsTrue(cond); + if (err > 0) { + STACK_SHRINK(1); + Py_DECREF(cond); + } + else if (err == 0) { + JUMPBY(oparg); + } + else { + goto error; + } + } + DISPATCH(); + } + + TARGET(JUMP_IF_TRUE_OR_POP) { + PyObject *cond = TOP(); + int err; + if (Py_IsFalse(cond)) { + STACK_SHRINK(1); + _Py_DECREF_NO_DEALLOC(cond); + } + else if (Py_IsTrue(cond)) { + JUMPBY(oparg); + } + else { + err = PyObject_IsTrue(cond); + if (err > 0) { + JUMPBY(oparg); + } + else if (err == 0) { + STACK_SHRINK(1); + Py_DECREF(cond); + } + else { + goto error; + } + } + DISPATCH(); + } + + TARGET(JUMP_BACKWARD_NO_INTERRUPT) { + /* This bytecode is used in the `yield from` or `await` loop. + * If there is an interrupt, we want it handled in the innermost + * generator or coroutine, so we deliberately do not check it here. + * (see bpo-30039). + */ + JUMPBY(-oparg); + DISPATCH(); + } + + TARGET(GET_LEN) { + // PUSH(len(TOS)) + Py_ssize_t len_i = PyObject_Length(TOP()); + if (len_i < 0) { + goto error; + } + PyObject *len_o = PyLong_FromSsize_t(len_i); + if (len_o == NULL) { + goto error; + } + PUSH(len_o); + DISPATCH(); + } + + TARGET(MATCH_CLASS) { + PyObject *names = PEEK(1); + PyObject *type = PEEK(2); + PyObject *subject = PEEK(3); + PyObject *attrs; + // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or + // None on failure. + assert(PyTuple_CheckExact(names)); + attrs = match_class(tstate, subject, type, oparg, names); + Py_DECREF(subject); + Py_DECREF(type); + Py_DECREF(names); + if (attrs) { + assert(PyTuple_CheckExact(attrs)); // Success! + } + else { + if (_PyErr_Occurred(tstate)) goto pop_3_error; + attrs = Py_NewRef(Py_None); // Failure! + } + STACK_SHRINK(2); + POKE(1, attrs); + DISPATCH(); + } + + TARGET(MATCH_MAPPING) { + PyObject *subject = PEEK(1); + PyObject *res; + int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; + res = Py_NewRef(match ? Py_True : Py_False); + STACK_GROW(1); + POKE(1, res); + PREDICT(POP_JUMP_IF_FALSE); + DISPATCH(); + } + + TARGET(MATCH_SEQUENCE) { + PyObject *subject = PEEK(1); + PyObject *res; + int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; + res = Py_NewRef(match ? Py_True : Py_False); + STACK_GROW(1); + POKE(1, res); + PREDICT(POP_JUMP_IF_FALSE); + DISPATCH(); + } + + TARGET(MATCH_KEYS) { + PyObject *keys = PEEK(1); + PyObject *subject = PEEK(2); + PyObject *values_or_none; + // On successful match, PUSH(values). Otherwise, PUSH(None). + values_or_none = match_keys(tstate, subject, keys); + if (values_or_none == NULL) goto error; + STACK_GROW(1); + POKE(1, values_or_none); + DISPATCH(); + } + + TARGET(GET_ITER) { + /* before: [obj]; after [getiter(obj)] */ + PyObject *iterable = TOP(); + PyObject *iter = PyObject_GetIter(iterable); + Py_DECREF(iterable); + SET_TOP(iter); + if (iter == NULL) + goto error; + DISPATCH(); + } + + TARGET(GET_YIELD_FROM_ITER) { + /* before: [obj]; after [getiter(obj)] */ + PyObject *iterable = TOP(); + PyObject *iter; + if (PyCoro_CheckExact(iterable)) { + /* `iterable` is a coroutine */ + if (!(frame->f_code->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) { + /* and it is used in a 'yield from' expression of a + regular generator. */ + Py_DECREF(iterable); + SET_TOP(NULL); + _PyErr_SetString(tstate, PyExc_TypeError, + "cannot 'yield from' a coroutine object " + "in a non-coroutine generator"); + goto error; + } + } + else if (!PyGen_CheckExact(iterable)) { + /* `iterable` is not a generator. */ + iter = PyObject_GetIter(iterable); + Py_DECREF(iterable); + SET_TOP(iter); + if (iter == NULL) + goto error; + } + PREDICT(LOAD_CONST); + DISPATCH(); + } + + TARGET(FOR_ITER) { + PREDICTED(FOR_ITER); + #if ENABLE_SPECIALIZATION + _PyForIterCache *cache = (_PyForIterCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + assert(cframe.use_tracing == 0); + next_instr--; + _Py_Specialize_ForIter(TOP(), next_instr, oparg); + DISPATCH_SAME_OPARG(); + } + STAT_INC(FOR_ITER, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + /* before: [iter]; after: [iter, iter()] *or* [] */ + PyObject *iter = TOP(); + PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter); + if (next != NULL) { + PUSH(next); + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER); + } + else { + if (_PyErr_Occurred(tstate)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + goto error; + } + else if (tstate->c_tracefunc != NULL) { + call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, frame); + } + _PyErr_Clear(tstate); + } + /* iterator ended normally */ + assert(_Py_OPCODE(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg]) == END_FOR); + STACK_SHRINK(1); + Py_DECREF(iter); + /* Skip END_FOR */ + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + } + DISPATCH(); + } + + TARGET(FOR_ITER_LIST) { + assert(cframe.use_tracing == 0); + _PyListIterObject *it = (_PyListIterObject *)TOP(); + DEOPT_IF(Py_TYPE(it) != &PyListIter_Type, FOR_ITER); + STAT_INC(FOR_ITER, hit); + PyListObject *seq = it->it_seq; + if (seq) { + if (it->it_index < PyList_GET_SIZE(seq)) { + PyObject *next = PyList_GET_ITEM(seq, it->it_index++); + PUSH(Py_NewRef(next)); + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER); + goto end_for_iter_list; // End of this instruction + } + it->it_seq = NULL; + Py_DECREF(seq); + } + STACK_SHRINK(1); + Py_DECREF(it); + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + end_for_iter_list: + DISPATCH(); + } + + TARGET(FOR_ITER_TUPLE) { + assert(cframe.use_tracing == 0); + _PyTupleIterObject *it = (_PyTupleIterObject *)TOP(); + DEOPT_IF(Py_TYPE(it) != &PyTupleIter_Type, FOR_ITER); + STAT_INC(FOR_ITER, hit); + PyTupleObject *seq = it->it_seq; + if (seq) { + if (it->it_index < PyTuple_GET_SIZE(seq)) { + PyObject *next = PyTuple_GET_ITEM(seq, it->it_index++); + PUSH(Py_NewRef(next)); + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER); + goto end_for_iter_tuple; // End of this instruction + } + it->it_seq = NULL; + Py_DECREF(seq); + } + STACK_SHRINK(1); + Py_DECREF(it); + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + end_for_iter_tuple: + DISPATCH(); + } + + TARGET(FOR_ITER_RANGE) { + assert(cframe.use_tracing == 0); + _PyRangeIterObject *r = (_PyRangeIterObject *)TOP(); + DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); + STAT_INC(FOR_ITER, hit); + _Py_CODEUNIT next = next_instr[INLINE_CACHE_ENTRIES_FOR_ITER]; + assert(_PyOpcode_Deopt[_Py_OPCODE(next)] == STORE_FAST); + if (r->len <= 0) { + STACK_SHRINK(1); + Py_DECREF(r); + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + } + else { + long value = r->start; + r->start = value + r->step; + r->len--; + if (_PyLong_AssignValue(&GETLOCAL(_Py_OPARG(next)), value) < 0) { + goto error; + } + // The STORE_FAST is already done. + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + 1); + } + DISPATCH(); + } + + TARGET(FOR_ITER_GEN) { + assert(cframe.use_tracing == 0); + PyGenObject *gen = (PyGenObject *)TOP(); + DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER); + DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, FOR_ITER); + STAT_INC(FOR_ITER, hit); + _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + frame->yield_offset = oparg; + _PyFrame_StackPush(gen_frame, Py_NewRef(Py_None)); + gen->gi_frame_state = FRAME_EXECUTING; + gen->gi_exc_state.previous_item = tstate->exc_info; + tstate->exc_info = &gen->gi_exc_state; + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg); + assert(_Py_OPCODE(*next_instr) == END_FOR); + DISPATCH_INLINED(gen_frame); + } + + TARGET(BEFORE_ASYNC_WITH) { + PyObject *mgr = TOP(); + PyObject *res; + PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__)); + if (enter == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "asynchronous context manager protocol", + Py_TYPE(mgr)->tp_name); + } + goto error; + } + PyObject *exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__aexit__)); + if (exit == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "asynchronous context manager protocol " + "(missed __aexit__ method)", + Py_TYPE(mgr)->tp_name); + } + Py_DECREF(enter); + goto error; + } + SET_TOP(exit); + Py_DECREF(mgr); + res = _PyObject_CallNoArgs(enter); + Py_DECREF(enter); + if (res == NULL) + goto error; + PUSH(res); + PREDICT(GET_AWAITABLE); + DISPATCH(); + } + + TARGET(BEFORE_WITH) { + PyObject *mgr = TOP(); + PyObject *res; + PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__enter__)); + if (enter == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "context manager protocol", + Py_TYPE(mgr)->tp_name); + } + goto error; + } + PyObject *exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__)); + if (exit == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "context manager protocol " + "(missed __exit__ method)", + Py_TYPE(mgr)->tp_name); + } + Py_DECREF(enter); + goto error; + } + SET_TOP(exit); + Py_DECREF(mgr); + res = _PyObject_CallNoArgs(enter); + Py_DECREF(enter); + if (res == NULL) { + goto error; + } + PUSH(res); + DISPATCH(); + } + + TARGET(WITH_EXCEPT_START) { + PyObject *val = PEEK(1); + PyObject *lasti = PEEK(3); + PyObject *exit_func = PEEK(4); + PyObject *res; + /* At the top of the stack are 4 values: + - val: TOP = exc_info() + - unused: SECOND = previous exception + - lasti: THIRD = lasti of exception in exc_info() + - exit_func: FOURTH = the context.__exit__ bound method + We call FOURTH(type(TOP), TOP, GetTraceback(TOP)). + Then we push the __exit__ return value. + */ + PyObject *exc, *tb; + + assert(val && PyExceptionInstance_Check(val)); + exc = PyExceptionInstance_Class(val); + tb = PyException_GetTraceback(val); + Py_XDECREF(tb); + assert(PyLong_Check(lasti)); + (void)lasti; // Shut up compiler warning if asserts are off + PyObject *stack[4] = {NULL, exc, val, tb}; + res = PyObject_Vectorcall(exit_func, stack + 1, + 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + if (res == NULL) goto error; + STACK_GROW(1); + POKE(1, res); + DISPATCH(); + } + + TARGET(PUSH_EXC_INFO) { + PyObject *value = TOP(); + + _PyErr_StackItem *exc_info = tstate->exc_info; + if (exc_info->exc_value != NULL) { + SET_TOP(exc_info->exc_value); + } + else { + SET_TOP(Py_NewRef(Py_None)); + } + + PUSH(Py_NewRef(value)); + assert(PyExceptionInstance_Check(value)); + exc_info->exc_value = value; + DISPATCH(); + } + + TARGET(LOAD_ATTR_METHOD_WITH_VALUES) { + /* Cached method object */ + assert(cframe.use_tracing == 0); + PyObject *self = TOP(); + PyTypeObject *self_cls = Py_TYPE(self); + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; + uint32_t type_version = read_u32(cache->type_version); + assert(type_version != 0); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); + assert(self_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + PyHeapTypeObject *self_heap_type = (PyHeapTypeObject *)self_cls; + DEOPT_IF(self_heap_type->ht_cached_keys->dk_version != + read_u32(cache->keys_version), LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + PyObject *res = read_obj(cache->descr); + assert(res != NULL); + assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); + SET_TOP(Py_NewRef(res)); + PUSH(self); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + DISPATCH(); + } + + TARGET(LOAD_ATTR_METHOD_NO_DICT) { + assert(cframe.use_tracing == 0); + PyObject *self = TOP(); + PyTypeObject *self_cls = Py_TYPE(self); + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; + uint32_t type_version = read_u32(cache->type_version); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); + assert(self_cls->tp_dictoffset == 0); + STAT_INC(LOAD_ATTR, hit); + PyObject *res = read_obj(cache->descr); + assert(res != NULL); + assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); + SET_TOP(Py_NewRef(res)); + PUSH(self); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + DISPATCH(); + } + + TARGET(LOAD_ATTR_METHOD_LAZY_DICT) { + assert(cframe.use_tracing == 0); + PyObject *self = TOP(); + PyTypeObject *self_cls = Py_TYPE(self); + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; + uint32_t type_version = read_u32(cache->type_version); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); + Py_ssize_t dictoffset = self_cls->tp_dictoffset; + assert(dictoffset > 0); + PyObject *dict = *(PyObject **)((char *)self + dictoffset); + /* This object has a __dict__, just not yet created */ + DEOPT_IF(dict != NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + PyObject *res = read_obj(cache->descr); + assert(res != NULL); + assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); + SET_TOP(Py_NewRef(res)); + PUSH(self); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + DISPATCH(); + } + + TARGET(CALL_BOUND_METHOD_EXACT_ARGS) { + DEOPT_IF(is_method(stack_pointer, oparg), CALL); + PyObject *function = PEEK(oparg + 1); + DEOPT_IF(Py_TYPE(function) != &PyMethod_Type, CALL); + STAT_INC(CALL, hit); + PyObject *self = ((PyMethodObject *)function)->im_self; + PEEK(oparg + 1) = Py_NewRef(self); + PyObject *meth = ((PyMethodObject *)function)->im_func; + PEEK(oparg + 2) = Py_NewRef(meth); + Py_DECREF(function); + GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS); + } + + TARGET(KW_NAMES) { + assert(kwnames == NULL); + assert(oparg < PyTuple_GET_SIZE(consts)); + kwnames = GETITEM(consts, oparg); + DISPATCH(); + } + + TARGET(CALL) { + PREDICTED(CALL); + #if ENABLE_SPECIALIZATION + _PyCallCache *cache = (_PyCallCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + assert(cframe.use_tracing == 0); + int is_meth = is_method(stack_pointer, oparg); + int nargs = oparg + is_meth; + PyObject *callable = PEEK(nargs + 1); + next_instr--; + _Py_Specialize_Call(callable, next_instr, nargs, kwnames); + DISPATCH_SAME_OPARG(); + } + STAT_INC(CALL, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + int total_args, is_meth; + is_meth = is_method(stack_pointer, oparg); + PyObject *function = PEEK(oparg + 1); + if (!is_meth && Py_TYPE(function) == &PyMethod_Type) { + PyObject *self = ((PyMethodObject *)function)->im_self; + PEEK(oparg+1) = Py_NewRef(self); + PyObject *meth = ((PyMethodObject *)function)->im_func; + PEEK(oparg+2) = Py_NewRef(meth); + Py_DECREF(function); + is_meth = 1; + } + total_args = oparg + is_meth; + function = PEEK(total_args + 1); + int positional_args = total_args - KWNAMES_LEN(); + // Check if the call can be inlined or not + if (Py_TYPE(function) == &PyFunction_Type && + tstate->interp->eval_frame == NULL && + ((PyFunctionObject *)function)->vectorcall == _PyFunction_Vectorcall) + { + int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(function))->co_flags; + PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(function)); + STACK_SHRINK(total_args); + _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit( + tstate, (PyFunctionObject *)function, locals, + stack_pointer, positional_args, kwnames + ); + kwnames = NULL; + STACK_SHRINK(2-is_meth); + // The frame has stolen all the arguments from the stack, + // so there is no need to clean them up. + if (new_frame == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + DISPATCH_INLINED(new_frame); + } + /* Callable is not a normal Python function */ + PyObject *res; + if (cframe.use_tracing) { + res = trace_call_function( + tstate, function, stack_pointer-total_args, + positional_args, kwnames); + } + else { + res = PyObject_Vectorcall( + function, stack_pointer-total_args, + positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET, + kwnames); + } + kwnames = NULL; + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(function); + /* Clear the stack */ + STACK_SHRINK(total_args); + for (int i = 0; i < total_args; i++) { + Py_DECREF(stack_pointer[i]); + } + STACK_SHRINK(2-is_meth); + PUSH(res); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_PY_EXACT_ARGS) { + PREDICTED(CALL_PY_EXACT_ARGS); + assert(kwnames == NULL); + DEOPT_IF(tstate->interp->eval_frame, CALL); + _PyCallCache *cache = (_PyCallCache *)next_instr; + int is_meth = is_method(stack_pointer, oparg); + int argcount = oparg + is_meth; + PyObject *callable = PEEK(argcount + 1); + DEOPT_IF(!PyFunction_Check(callable), CALL); + PyFunctionObject *func = (PyFunctionObject *)callable; + DEOPT_IF(func->func_version != read_u32(cache->func_version), CALL); + PyCodeObject *code = (PyCodeObject *)func->func_code; + DEOPT_IF(code->co_argcount != argcount, CALL); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); + STAT_INC(CALL, hit); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, argcount); + STACK_SHRINK(argcount); + for (int i = 0; i < argcount; i++) { + new_frame->localsplus[i] = stack_pointer[i]; + } + STACK_SHRINK(2-is_meth); + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + DISPATCH_INLINED(new_frame); + } + + TARGET(CALL_PY_WITH_DEFAULTS) { + assert(kwnames == NULL); + DEOPT_IF(tstate->interp->eval_frame, CALL); + _PyCallCache *cache = (_PyCallCache *)next_instr; + int is_meth = is_method(stack_pointer, oparg); + int argcount = oparg + is_meth; + PyObject *callable = PEEK(argcount + 1); + DEOPT_IF(!PyFunction_Check(callable), CALL); + PyFunctionObject *func = (PyFunctionObject *)callable; + DEOPT_IF(func->func_version != read_u32(cache->func_version), CALL); + PyCodeObject *code = (PyCodeObject *)func->func_code; + DEOPT_IF(argcount > code->co_argcount, CALL); + int minargs = cache->min_args; + DEOPT_IF(argcount < minargs, CALL); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); + STAT_INC(CALL, hit); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, code->co_argcount); + STACK_SHRINK(argcount); + for (int i = 0; i < argcount; i++) { + new_frame->localsplus[i] = stack_pointer[i]; + } + for (int i = argcount; i < code->co_argcount; i++) { + PyObject *def = PyTuple_GET_ITEM(func->func_defaults, + i - minargs); + new_frame->localsplus[i] = Py_NewRef(def); + } + STACK_SHRINK(2-is_meth); + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + DISPATCH_INLINED(new_frame); + } + + TARGET(CALL_NO_KW_TYPE_1) { + assert(kwnames == NULL); + assert(cframe.use_tracing == 0); + assert(oparg == 1); + DEOPT_IF(is_method(stack_pointer, 1), CALL); + PyObject *obj = TOP(); + PyObject *callable = SECOND(); + DEOPT_IF(callable != (PyObject *)&PyType_Type, CALL); + STAT_INC(CALL, hit); + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + PyObject *res = Py_NewRef(Py_TYPE(obj)); + Py_DECREF(callable); + Py_DECREF(obj); + STACK_SHRINK(2); + SET_TOP(res); + DISPATCH(); + } + + TARGET(CALL_NO_KW_STR_1) { + assert(kwnames == NULL); + assert(cframe.use_tracing == 0); + assert(oparg == 1); + DEOPT_IF(is_method(stack_pointer, 1), CALL); + PyObject *callable = PEEK(2); + DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL); + STAT_INC(CALL, hit); + PyObject *arg = TOP(); + PyObject *res = PyObject_Str(arg); + Py_DECREF(arg); + Py_DECREF(&PyUnicode_Type); + STACK_SHRINK(2); + SET_TOP(res); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_NO_KW_TUPLE_1) { + assert(kwnames == NULL); + assert(oparg == 1); + DEOPT_IF(is_method(stack_pointer, 1), CALL); + PyObject *callable = PEEK(2); + DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL); + STAT_INC(CALL, hit); + PyObject *arg = TOP(); + PyObject *res = PySequence_Tuple(arg); + Py_DECREF(arg); + Py_DECREF(&PyTuple_Type); + STACK_SHRINK(2); + SET_TOP(res); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_BUILTIN_CLASS) { + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + int kwnames_len = KWNAMES_LEN(); + PyObject *callable = PEEK(total_args + 1); + DEOPT_IF(!PyType_Check(callable), CALL); + PyTypeObject *tp = (PyTypeObject *)callable; + DEOPT_IF(tp->tp_vectorcall == NULL, CALL); + STAT_INC(CALL, hit); + STACK_SHRINK(total_args); + PyObject *res = tp->tp_vectorcall((PyObject *)tp, stack_pointer, + total_args-kwnames_len, kwnames); + kwnames = NULL; + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(stack_pointer[i]); + } + Py_DECREF(tp); + STACK_SHRINK(1-is_meth); + SET_TOP(res); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_NO_KW_BUILTIN_O) { + assert(cframe.use_tracing == 0); + /* Builtin METH_O functions */ + assert(kwnames == NULL); + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + DEOPT_IF(total_args != 1, CALL); + PyObject *callable = PEEK(total_args + 1); + DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_O, CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); + // This is slower but CPython promises to check all non-vectorcall + // function calls. + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { + goto error; + } + PyObject *arg = TOP(); + PyObject *res = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable), arg); + _Py_LeaveRecursiveCallTstate(tstate); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + Py_DECREF(arg); + Py_DECREF(callable); + STACK_SHRINK(2-is_meth); + SET_TOP(res); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_NO_KW_BUILTIN_FAST) { + assert(cframe.use_tracing == 0); + /* Builtin METH_FASTCALL functions, without keywords */ + assert(kwnames == NULL); + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + PyObject *callable = PEEK(total_args + 1); + DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_FASTCALL, + CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); + STACK_SHRINK(total_args); + /* res = func(self, args, nargs) */ + PyObject *res = ((_PyCFunctionFast)(void(*)(void))cfunc)( + PyCFunction_GET_SELF(callable), + stack_pointer, + total_args); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(stack_pointer[i]); + } + STACK_SHRINK(2-is_meth); + PUSH(res); + Py_DECREF(callable); + if (res == NULL) { + /* Not deopting because this doesn't mean our optimization was + wrong. `res` can be NULL for valid reasons. Eg. getattr(x, + 'invalid'). In those cases an exception is set, so we must + handle it. + */ + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_BUILTIN_FAST_WITH_KEYWORDS) { + assert(cframe.use_tracing == 0); + /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + PyObject *callable = PEEK(total_args + 1); + DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != + (METH_FASTCALL | METH_KEYWORDS), CALL); + STAT_INC(CALL, hit); + STACK_SHRINK(total_args); + /* res = func(self, args, nargs, kwnames) */ + _PyCFunctionFastWithKeywords cfunc = + (_PyCFunctionFastWithKeywords)(void(*)(void)) + PyCFunction_GET_FUNCTION(callable); + PyObject *res = cfunc( + PyCFunction_GET_SELF(callable), + stack_pointer, + total_args - KWNAMES_LEN(), + kwnames + ); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + kwnames = NULL; + + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(stack_pointer[i]); + } + STACK_SHRINK(2-is_meth); + PUSH(res); + Py_DECREF(callable); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_NO_KW_LEN) { + assert(cframe.use_tracing == 0); + assert(kwnames == NULL); + /* len(o) */ + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + DEOPT_IF(total_args != 1, CALL); + PyObject *callable = PEEK(total_args + 1); + PyInterpreterState *interp = _PyInterpreterState_GET(); + DEOPT_IF(callable != interp->callable_cache.len, CALL); + STAT_INC(CALL, hit); + PyObject *arg = TOP(); + Py_ssize_t len_i = PyObject_Length(arg); + if (len_i < 0) { + goto error; + } + PyObject *res = PyLong_FromSsize_t(len_i); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + STACK_SHRINK(2-is_meth); + SET_TOP(res); + Py_DECREF(callable); + Py_DECREF(arg); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + DISPATCH(); + } + + TARGET(CALL_NO_KW_ISINSTANCE) { + assert(cframe.use_tracing == 0); + assert(kwnames == NULL); + /* isinstance(o, o2) */ + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + PyObject *callable = PEEK(total_args + 1); + DEOPT_IF(total_args != 2, CALL); + PyInterpreterState *interp = _PyInterpreterState_GET(); + DEOPT_IF(callable != interp->callable_cache.isinstance, CALL); + STAT_INC(CALL, hit); + PyObject *cls = POP(); + PyObject *inst = TOP(); + int retval = PyObject_IsInstance(inst, cls); + if (retval < 0) { + Py_DECREF(cls); + goto error; + } + PyObject *res = PyBool_FromLong(retval); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + STACK_SHRINK(2-is_meth); + SET_TOP(res); + Py_DECREF(inst); + Py_DECREF(cls); + Py_DECREF(callable); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + DISPATCH(); + } + + TARGET(CALL_NO_KW_LIST_APPEND) { + assert(cframe.use_tracing == 0); + assert(kwnames == NULL); + assert(oparg == 1); + PyObject *callable = PEEK(3); + PyInterpreterState *interp = _PyInterpreterState_GET(); + DEOPT_IF(callable != interp->callable_cache.list_append, CALL); + PyObject *list = SECOND(); + DEOPT_IF(!PyList_Check(list), CALL); + STAT_INC(CALL, hit); + PyObject *arg = POP(); + if (_PyList_AppendTakeRef((PyListObject *)list, arg) < 0) { + goto error; + } + STACK_SHRINK(2); + Py_DECREF(list); + Py_DECREF(callable); + // CALL + POP_TOP + JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1); + assert(_Py_OPCODE(next_instr[-1]) == POP_TOP); + DISPATCH(); + } + + TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) { + assert(kwnames == NULL); + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + PyMethodDescrObject *callable = + (PyMethodDescrObject *)PEEK(total_args + 1); + DEOPT_IF(total_args != 2, CALL); + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = callable->d_method; + DEOPT_IF(meth->ml_flags != METH_O, CALL); + PyObject *arg = TOP(); + PyObject *self = SECOND(); + DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = meth->ml_meth; + // This is slower but CPython promises to check all non-vectorcall + // function calls. + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { + goto error; + } + PyObject *res = _PyCFunction_TrampolineCall(cfunc, self, arg); + _Py_LeaveRecursiveCallTstate(tstate); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(self); + Py_DECREF(arg); + STACK_SHRINK(oparg + 1); + SET_TOP(res); + Py_DECREF(callable); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS) { + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + PyMethodDescrObject *callable = + (PyMethodDescrObject *)PEEK(total_args + 1); + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = callable->d_method; + DEOPT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS), CALL); + PyTypeObject *d_type = callable->d_common.d_type; + PyObject *self = PEEK(total_args); + DEOPT_IF(!Py_IS_TYPE(self, d_type), CALL); + STAT_INC(CALL, hit); + int nargs = total_args-1; + STACK_SHRINK(nargs); + _PyCFunctionFastWithKeywords cfunc = + (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; + PyObject *res = cfunc(self, stack_pointer, nargs - KWNAMES_LEN(), + kwnames); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + kwnames = NULL; + + /* Free the arguments. */ + for (int i = 0; i < nargs; i++) { + Py_DECREF(stack_pointer[i]); + } + Py_DECREF(self); + STACK_SHRINK(2-is_meth); + SET_TOP(res); + Py_DECREF(callable); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS) { + assert(kwnames == NULL); + assert(oparg == 0 || oparg == 1); + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + DEOPT_IF(total_args != 1, CALL); + PyMethodDescrObject *callable = (PyMethodDescrObject *)SECOND(); + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = callable->d_method; + PyObject *self = TOP(); + DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + DEOPT_IF(meth->ml_flags != METH_NOARGS, CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = meth->ml_meth; + // This is slower but CPython promises to check all non-vectorcall + // function calls. + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { + goto error; + } + PyObject *res = _PyCFunction_TrampolineCall(cfunc, self, NULL); + _Py_LeaveRecursiveCallTstate(tstate); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(self); + STACK_SHRINK(oparg + 1); + SET_TOP(res); + Py_DECREF(callable); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_FAST) { + assert(kwnames == NULL); + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + PyMethodDescrObject *callable = + (PyMethodDescrObject *)PEEK(total_args + 1); + /* Builtin METH_FASTCALL methods, without keywords */ + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = callable->d_method; + DEOPT_IF(meth->ml_flags != METH_FASTCALL, CALL); + PyObject *self = PEEK(total_args); + DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + STAT_INC(CALL, hit); + _PyCFunctionFast cfunc = + (_PyCFunctionFast)(void(*)(void))meth->ml_meth; + int nargs = total_args-1; + STACK_SHRINK(nargs); + PyObject *res = cfunc(self, stack_pointer, nargs); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + /* Clear the stack of the arguments. */ + for (int i = 0; i < nargs; i++) { + Py_DECREF(stack_pointer[i]); + } + Py_DECREF(self); + STACK_SHRINK(2-is_meth); + SET_TOP(res); + Py_DECREF(callable); + if (res == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_FUNCTION_EX) { + PREDICTED(CALL_FUNCTION_EX); + PyObject *func, *callargs, *kwargs = NULL, *result; + if (oparg & 0x01) { + kwargs = POP(); + // DICT_MERGE is called before this opcode if there are kwargs. + // It converts all dict subtypes in kwargs into regular dicts. + assert(PyDict_CheckExact(kwargs)); + } + callargs = POP(); + func = TOP(); + if (!PyTuple_CheckExact(callargs)) { + if (check_args_iterable(tstate, func, callargs) < 0) { + Py_DECREF(callargs); + goto error; + } + Py_SETREF(callargs, PySequence_Tuple(callargs)); + if (callargs == NULL) { + goto error; + } + } + assert(PyTuple_CheckExact(callargs)); + + result = do_call_core(tstate, func, callargs, kwargs, cframe.use_tracing); + Py_DECREF(func); + Py_DECREF(callargs); + Py_XDECREF(kwargs); + + STACK_SHRINK(1); + assert(TOP() == NULL); + SET_TOP(result); + if (result == NULL) { + goto error; + } + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(MAKE_FUNCTION) { + PyObject *codeobj = POP(); + PyFunctionObject *func = (PyFunctionObject *) + PyFunction_New(codeobj, GLOBALS()); + + Py_DECREF(codeobj); + if (func == NULL) { + goto error; + } + + if (oparg & 0x08) { + assert(PyTuple_CheckExact(TOP())); + func->func_closure = POP(); + } + if (oparg & 0x04) { + assert(PyTuple_CheckExact(TOP())); + func->func_annotations = POP(); + } + if (oparg & 0x02) { + assert(PyDict_CheckExact(TOP())); + func->func_kwdefaults = POP(); + } + if (oparg & 0x01) { + assert(PyTuple_CheckExact(TOP())); + func->func_defaults = POP(); + } + + func->func_version = ((PyCodeObject *)codeobj)->co_version; + PUSH((PyObject *)func); + DISPATCH(); + } + + TARGET(RETURN_GENERATOR) { + assert(PyFunction_Check(frame->f_funcobj)); + PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; + PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); + if (gen == NULL) { + goto error; + } + assert(EMPTY()); + _PyFrame_SetStackPointer(frame, stack_pointer); + _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + _PyFrame_Copy(frame, gen_frame); + assert(frame->frame_obj == NULL); + gen->gi_frame_state = FRAME_CREATED; + gen_frame->owner = FRAME_OWNED_BY_GENERATOR; + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + _PyInterpreterFrame *prev = frame->previous; + _PyThreadState_PopFrame(tstate, frame); + frame = cframe.current_frame = prev; + _PyFrame_StackPush(frame, (PyObject *)gen); + goto resume_frame; + } + + TARGET(BUILD_SLICE) { + PyObject *start, *stop, *step, *slice; + if (oparg == 3) + step = POP(); + else + step = NULL; + stop = POP(); + start = TOP(); + slice = PySlice_New(start, stop, step); + Py_DECREF(start); + Py_DECREF(stop); + Py_XDECREF(step); + SET_TOP(slice); + if (slice == NULL) + goto error; + DISPATCH(); + } + + TARGET(FORMAT_VALUE) { + /* Handles f-string value formatting. */ + PyObject *result; + PyObject *fmt_spec; + PyObject *value; + PyObject *(*conv_fn)(PyObject *); + int which_conversion = oparg & FVC_MASK; + int have_fmt_spec = (oparg & FVS_MASK) == FVS_HAVE_SPEC; + + fmt_spec = have_fmt_spec ? POP() : NULL; + value = POP(); + + /* See if any conversion is specified. */ + switch (which_conversion) { + case FVC_NONE: conv_fn = NULL; break; + case FVC_STR: conv_fn = PyObject_Str; break; + case FVC_REPR: conv_fn = PyObject_Repr; break; + case FVC_ASCII: conv_fn = PyObject_ASCII; break; + default: + _PyErr_Format(tstate, PyExc_SystemError, + "unexpected conversion flag %d", + which_conversion); + goto error; + } + + /* If there's a conversion function, call it and replace + value with that result. Otherwise, just use value, + without conversion. */ + if (conv_fn != NULL) { + result = conv_fn(value); + Py_DECREF(value); + if (result == NULL) { + Py_XDECREF(fmt_spec); + goto error; + } + value = result; + } + + /* If value is a unicode object, and there's no fmt_spec, + then we know the result of format(value) is value + itself. In that case, skip calling format(). I plan to + move this optimization in to PyObject_Format() + itself. */ + if (PyUnicode_CheckExact(value) && fmt_spec == NULL) { + /* Do nothing, just transfer ownership to result. */ + result = value; + } else { + /* Actually call format(). */ + result = PyObject_Format(value, fmt_spec); + Py_DECREF(value); + Py_XDECREF(fmt_spec); + if (result == NULL) { + goto error; + } + } + + PUSH(result); + DISPATCH(); + } + + TARGET(COPY) { + assert(oparg != 0); + PyObject *peek = PEEK(oparg); + PUSH(Py_NewRef(peek)); + DISPATCH(); + } + + TARGET(BINARY_OP) { + PREDICTED(BINARY_OP); + static_assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1, "incorrect cache size"); + PyObject *rhs = PEEK(1); + PyObject *lhs = PEEK(2); + PyObject *res; + #if ENABLE_SPECIALIZATION + _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + assert(cframe.use_tracing == 0); + next_instr--; + _Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, &GETLOCAL(0)); + DISPATCH_SAME_OPARG(); + } + STAT_INC(BINARY_OP, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + assert(0 <= oparg); + assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); + assert(binary_ops[oparg]); + res = binary_ops[oparg](lhs, rhs); + Py_DECREF(lhs); + Py_DECREF(rhs); + if (res == NULL) goto pop_2_error; + STACK_SHRINK(1); + POKE(1, res); + JUMPBY(1); + DISPATCH(); + } + + TARGET(SWAP) { + assert(oparg != 0); + PyObject *top = TOP(); + SET_TOP(PEEK(oparg)); + PEEK(oparg) = top; + DISPATCH(); + } + + TARGET(EXTENDED_ARG) { + assert(oparg); + assert(cframe.use_tracing == 0); + opcode = _Py_OPCODE(*next_instr); + oparg = oparg << 8 | _Py_OPARG(*next_instr); + PRE_DISPATCH_GOTO(); + DISPATCH_GOTO(); + } + + TARGET(CACHE) { + Py_UNREACHABLE(); + } diff --git a/Python/getargs.c b/Python/getargs.c index 3fab3b5efef..66dd90877fe 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_tuple.h" // _PyTuple_ITEMS() +#include "pycore_pylifecycle.h" // _PyArg_Fini #include #include @@ -201,9 +202,9 @@ _PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va) static int cleanup_ptr(PyObject *self, void *ptr) { - if (ptr) { - PyMem_Free(ptr); - } + void **pptr = (void **)ptr; + PyMem_Free(*pptr); + *pptr = NULL; return 0; } @@ -1011,58 +1012,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, break; } - case 'u': /* raw unicode buffer (Py_UNICODE *) */ - case 'Z': /* raw unicode buffer or None */ - { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "getargs: The '%c' format is deprecated. Use 'U' instead.", c)) { - return NULL; - } -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); - - if (*format == '#') { - /* "u#" or "Z#" */ - REQUIRE_PY_SSIZE_T_CLEAN; - Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); - - if (c == 'Z' && arg == Py_None) { - *p = NULL; - *psize = 0; - } - else if (PyUnicode_Check(arg)) { - Py_ssize_t len; - *p = PyUnicode_AsUnicodeAndSize(arg, &len); - if (*p == NULL) - RETURN_ERR_OCCURRED; - *psize = len; - } - else - return converterr(c == 'Z' ? "str or None" : "str", - arg, msgbuf, bufsize); - format++; - } else { - /* "u" or "Z" */ - if (c == 'Z' && arg == Py_None) - *p = NULL; - else if (PyUnicode_Check(arg)) { - Py_ssize_t len; - *p = PyUnicode_AsUnicodeAndSize(arg, &len); - if (*p == NULL) - RETURN_ERR_OCCURRED; - if (wcslen(*p) != (size_t)len) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - RETURN_ERR_OCCURRED; - } - } else - return converterr(c == 'Z' ? "str or None" : "str", - arg, msgbuf, bufsize); - } - break; -_Py_COMP_DIAG_POP - } - case 'e': {/* encoded string */ char **buffer; const char *encoding; @@ -1097,8 +1046,7 @@ _Py_COMP_DIAG_POP /* Encode object */ if (!recode_strings && (PyBytes_Check(arg) || PyByteArray_Check(arg))) { - s = arg; - Py_INCREF(s); + s = Py_NewRef(arg); if (PyBytes_Check(arg)) { size = PyBytes_GET_SIZE(s); ptr = PyBytes_AS_STRING(s); @@ -1168,7 +1116,7 @@ _Py_COMP_DIAG_POP PyErr_NoMemory(); RETURN_ERR_OCCURRED; } - if (addcleanup(*buffer, freelist, cleanup_ptr)) { + if (addcleanup(buffer, freelist, cleanup_ptr)) { Py_DECREF(s); return converterr( "(cleanup problem)", @@ -1214,7 +1162,7 @@ _Py_COMP_DIAG_POP PyErr_NoMemory(); RETURN_ERR_OCCURRED; } - if (addcleanup(*buffer, freelist, cleanup_ptr)) { + if (addcleanup(buffer, freelist, cleanup_ptr)) { Py_DECREF(s); return converterr("(cleanup problem)", arg, msgbuf, bufsize); @@ -1553,6 +1501,50 @@ _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords, return retval; } +static void +error_unexpected_keyword_arg(PyObject *kwargs, PyObject *kwnames, PyObject *kwtuple, const char *fname) +{ + /* make sure there are no extraneous keyword arguments */ + Py_ssize_t j = 0; + while (1) { + PyObject *keyword; + if (kwargs != NULL) { + if (!PyDict_Next(kwargs, &j, &keyword, NULL)) + break; + } + else { + if (j >= PyTuple_GET_SIZE(kwnames)) + break; + keyword = PyTuple_GET_ITEM(kwnames, j); + j++; + } + if (!PyUnicode_Check(keyword)) { + PyErr_SetString(PyExc_TypeError, + "keywords must be strings"); + return; + } + + int match = PySequence_Contains(kwtuple, keyword); + if (match <= 0) { + if (!match) { + PyErr_Format(PyExc_TypeError, + "'%S' is an invalid keyword " + "argument for %.200s%s", + keyword, + (fname == NULL) ? "this function" : fname, + (fname == NULL) ? "" : "()"); + } + return; + } + } + /* Something wrong happened. There are extraneous keyword arguments, + * but we don't know what. And we don't bother. */ + PyErr_Format(PyExc_TypeError, + "invalid keyword argument for %.200s%s", + (fname == NULL) ? "this function" : fname, + (fname == NULL) ? "" : "()"); +} + int PyArg_ValidateKeywordArguments(PyObject *kwargs) { @@ -1841,139 +1833,227 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, return cleanreturn(0, &freelist); } } + /* Something wrong happened. There are extraneous keyword arguments, + * but we don't know what. And we don't bother. */ + PyErr_Format(PyExc_TypeError, + "invalid keyword argument for %.200s%s", + (fname == NULL) ? "this function" : fname, + (fname == NULL) ? "" : "()"); + return cleanreturn(0, &freelist); } return cleanreturn(1, &freelist); } -/* List of static parsers. */ -static struct _PyArg_Parser *static_arg_parsers = NULL; - static int -parser_init(struct _PyArg_Parser *parser) +scan_keywords(const char * const *keywords, int *ptotal, int *pposonly) { - const char * const *keywords; - const char *format, *msg; - int i, len, min, max, nkw; - PyObject *kwtuple; - - assert(parser->keywords != NULL); - if (parser->kwtuple != NULL) { - return 1; - } - - keywords = parser->keywords; /* scan keywords and count the number of positional-only parameters */ + int i; for (i = 0; keywords[i] && !*keywords[i]; i++) { } - parser->pos = i; + *pposonly = i; + /* scan keywords and get greatest possible nbr of args */ for (; keywords[i]; i++) { if (!*keywords[i]) { PyErr_SetString(PyExc_SystemError, "Empty keyword parameter name"); - return 0; + return -1; } } - len = i; + *ptotal = i; + return 0; +} - format = parser->format; - if (format) { - /* grab the function name or custom error msg first (mutually exclusive) */ - parser->fname = strchr(parser->format, ':'); - if (parser->fname) { - parser->fname++; - parser->custom_msg = NULL; +static int +parse_format(const char *format, int total, int npos, + const char **pfname, const char **pcustommsg, + int *pmin, int *pmax) +{ + /* grab the function name or custom error msg first (mutually exclusive) */ + const char *custommsg; + const char *fname = strchr(format, ':'); + if (fname) { + fname++; + custommsg = NULL; + } + else { + custommsg = strchr(format,';'); + if (custommsg) { + custommsg++; } - else { - parser->custom_msg = strchr(parser->format,';'); - if (parser->custom_msg) - parser->custom_msg++; + } + + int min = INT_MAX; + int max = INT_MAX; + for (int i = 0; i < total; i++) { + if (*format == '|') { + if (min != INT_MAX) { + PyErr_SetString(PyExc_SystemError, + "Invalid format string (| specified twice)"); + return -1; + } + if (max != INT_MAX) { + PyErr_SetString(PyExc_SystemError, + "Invalid format string ($ before |)"); + return -1; + } + min = i; + format++; } - - min = max = INT_MAX; - for (i = 0; i < len; i++) { - if (*format == '|') { - if (min != INT_MAX) { - PyErr_SetString(PyExc_SystemError, - "Invalid format string (| specified twice)"); - return 0; - } - if (max != INT_MAX) { - PyErr_SetString(PyExc_SystemError, - "Invalid format string ($ before |)"); - return 0; - } - min = i; - format++; + if (*format == '$') { + if (max != INT_MAX) { + PyErr_SetString(PyExc_SystemError, + "Invalid format string ($ specified twice)"); + return -1; } - if (*format == '$') { - if (max != INT_MAX) { - PyErr_SetString(PyExc_SystemError, - "Invalid format string ($ specified twice)"); - return 0; - } - if (i < parser->pos) { - PyErr_SetString(PyExc_SystemError, - "Empty parameter name after $"); - return 0; - } - max = i; - format++; - } - if (IS_END_OF_FORMAT(*format)) { - PyErr_Format(PyExc_SystemError, - "More keyword list entries (%d) than " - "format specifiers (%d)", len, i); - return 0; - } - - msg = skipitem(&format, NULL, 0); - if (msg) { - PyErr_Format(PyExc_SystemError, "%s: '%s'", msg, - format); - return 0; + if (i < npos) { + PyErr_SetString(PyExc_SystemError, + "Empty parameter name after $"); + return -1; } + max = i; + format++; } - parser->min = Py_MIN(min, len); - parser->max = Py_MIN(max, len); - - if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) { + if (IS_END_OF_FORMAT(*format)) { PyErr_Format(PyExc_SystemError, - "more argument specifiers than keyword list entries " - "(remaining format:'%s')", format); - return 0; + "More keyword list entries (%d) than " + "format specifiers (%d)", total, i); + return -1; + } + + const char *msg = skipitem(&format, NULL, 0); + if (msg) { + PyErr_Format(PyExc_SystemError, "%s: '%s'", msg, + format); + return -1; } } + min = Py_MIN(min, total); + max = Py_MIN(max, total); - nkw = len - parser->pos; - kwtuple = PyTuple_New(nkw); - if (kwtuple == NULL) { - return 0; + if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) { + PyErr_Format(PyExc_SystemError, + "more argument specifiers than keyword list entries " + "(remaining format:'%s')", format); + return -1; } - keywords = parser->keywords + parser->pos; - for (i = 0; i < nkw; i++) { + + *pfname = fname; + *pcustommsg = custommsg; + *pmin = min; + *pmax = max; + return 0; +} + +static PyObject * +new_kwtuple(const char * const *keywords, int total, int pos) +{ + int nkw = total - pos; + PyObject *kwtuple = PyTuple_New(nkw); + if (kwtuple == NULL) { + return NULL; + } + keywords += pos; + for (int i = 0; i < nkw; i++) { PyObject *str = PyUnicode_FromString(keywords[i]); if (str == NULL) { Py_DECREF(kwtuple); - return 0; + return NULL; } PyUnicode_InternInPlace(&str); PyTuple_SET_ITEM(kwtuple, i, str); } + return kwtuple; +} + +static int +_parser_init(struct _PyArg_Parser *parser) +{ + const char * const *keywords = parser->keywords; + assert(keywords != NULL); + assert(parser->pos == 0 && + (parser->format == NULL || parser->fname == NULL) && + parser->custom_msg == NULL && + parser->min == 0 && + parser->max == 0); + + int len, pos; + if (scan_keywords(keywords, &len, &pos) < 0) { + return 0; + } + + const char *fname, *custommsg = NULL; + int min = 0, max = 0; + if (parser->format) { + assert(parser->fname == NULL); + if (parse_format(parser->format, len, pos, + &fname, &custommsg, &min, &max) < 0) { + return 0; + } + } + else { + assert(parser->fname != NULL); + fname = parser->fname; + } + + int owned; + PyObject *kwtuple = parser->kwtuple; + if (kwtuple == NULL) { + kwtuple = new_kwtuple(keywords, len, pos); + if (kwtuple == NULL) { + return 0; + } + owned = 1; + } + else { + owned = 0; + } + + parser->pos = pos; + parser->fname = fname; + parser->custom_msg = custommsg; + parser->min = min; + parser->max = max; parser->kwtuple = kwtuple; + parser->initialized = owned ? 1 : -1; assert(parser->next == NULL); - parser->next = static_arg_parsers; - static_arg_parsers = parser; + parser->next = _PyRuntime.getargs.static_parsers; + _PyRuntime.getargs.static_parsers = parser; return 1; } +static int +parser_init(struct _PyArg_Parser *parser) +{ + // volatile as it can be modified by other threads + // and should not be optimized or reordered by compiler + if (*((volatile int *)&parser->initialized)) { + assert(parser->kwtuple != NULL); + return 1; + } + PyThread_acquire_lock(_PyRuntime.getargs.mutex, WAIT_LOCK); + // Check again if another thread initialized the parser + // while we were waiting for the lock. + if (*((volatile int *)&parser->initialized)) { + assert(parser->kwtuple != NULL); + PyThread_release_lock(_PyRuntime.getargs.mutex); + return 1; + } + int ret = _parser_init(parser); + PyThread_release_lock(_PyRuntime.getargs.mutex); + return ret; +} + static void parser_clear(struct _PyArg_Parser *parser) { - Py_CLEAR(parser->kwtuple); + if (parser->initialized == 1) { + Py_CLEAR(parser->kwtuple); + } } static PyObject* @@ -2100,6 +2180,7 @@ vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, } format = parser->format; + assert(format != NULL || len == 0); /* convert tuple args and keyword args in same loop, using kwtuple to drive process */ for (i = 0; i < len; i++) { if (*format == '|') { @@ -2183,7 +2264,6 @@ vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, assert(IS_END_OF_FORMAT(*format) || (*format == '|') || (*format == '$')); if (nkwargs > 0) { - Py_ssize_t j; /* make sure there are no arguments given by name and position */ for (i = pos; i < nargs; i++) { keyword = PyTuple_GET_ITEM(kwtuple, i - pos); @@ -2207,34 +2287,9 @@ vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, return cleanreturn(0, &freelist); } } - /* make sure there are no extraneous keyword arguments */ - j = 0; - while (1) { - int match; - if (kwargs != NULL) { - if (!PyDict_Next(kwargs, &j, &keyword, NULL)) - break; - } - else { - if (j >= PyTuple_GET_SIZE(kwnames)) - break; - keyword = PyTuple_GET_ITEM(kwnames, j); - j++; - } - match = PySequence_Contains(kwtuple, keyword); - if (match <= 0) { - if (!match) { - PyErr_Format(PyExc_TypeError, - "'%S' is an invalid keyword " - "argument for %.200s%s", - keyword, - (parser->fname == NULL) ? "this function" : parser->fname, - (parser->fname == NULL) ? "" : "()"); - } - return cleanreturn(0, &freelist); - } - } + error_unexpected_keyword_arg(kwargs, kwnames, kwtuple, parser->fname); + return cleanreturn(0, &freelist); } return cleanreturn(1, &freelist); @@ -2408,7 +2463,6 @@ _PyArg_UnpackKeywords(PyObject *const *args, Py_ssize_t nargs, } if (nkwargs > 0) { - Py_ssize_t j; /* make sure there are no arguments given by name and position */ for (i = posonly; i < nargs; i++) { keyword = PyTuple_GET_ITEM(kwtuple, i - posonly); @@ -2432,34 +2486,9 @@ _PyArg_UnpackKeywords(PyObject *const *args, Py_ssize_t nargs, return NULL; } } - /* make sure there are no extraneous keyword arguments */ - j = 0; - while (1) { - int match; - if (kwargs != NULL) { - if (!PyDict_Next(kwargs, &j, &keyword, NULL)) - break; - } - else { - if (j >= PyTuple_GET_SIZE(kwnames)) - break; - keyword = PyTuple_GET_ITEM(kwnames, j); - j++; - } - match = PySequence_Contains(kwtuple, keyword); - if (match <= 0) { - if (!match) { - PyErr_Format(PyExc_TypeError, - "'%S' is an invalid keyword " - "argument for %.200s%s", - keyword, - (parser->fname == NULL) ? "this function" : parser->fname, - (parser->fname == NULL) ? "" : "()"); - } - return NULL; - } - } + error_unexpected_keyword_arg(kwargs, kwnames, kwtuple, parser->fname); + return NULL; } return buf; @@ -2542,8 +2571,7 @@ _PyArg_UnpackKeywordsWithVararg(PyObject *const *args, Py_ssize_t nargs, /* copy tuple args */ for (i = 0; i < nargs; i++) { if (i >= vararg) { - Py_INCREF(args[i]); - PyTuple_SET_ITEM(buf[vararg], i - vararg, args[i]); + PyTuple_SET_ITEM(buf[vararg], i - vararg, Py_NewRef(args[i])); continue; } else { @@ -2570,7 +2598,25 @@ _PyArg_UnpackKeywordsWithVararg(PyObject *const *args, Py_ssize_t nargs, current_arg = NULL; } - buf[i + vararg + 1] = current_arg; + /* If an arguments is passed in as a keyword argument, + * it should be placed before `buf[vararg]`. + * + * For example: + * def f(a, /, b, *args): + * pass + * f(1, b=2) + * + * This `buf` array should be: [1, 2, NULL]. + * In this case, nargs < vararg. + * + * Otherwise, we leave a place at `buf[vararg]` for vararg tuple + * so the index is `i + 1`. */ + if (nargs < vararg) { + buf[i] = current_arg; + } + else { + buf[i + 1] = current_arg; + } if (current_arg) { --nkwargs; @@ -2588,35 +2634,8 @@ _PyArg_UnpackKeywordsWithVararg(PyObject *const *args, Py_ssize_t nargs, } if (nkwargs > 0) { - Py_ssize_t j; - /* make sure there are no extraneous keyword arguments */ - j = 0; - while (1) { - int match; - if (kwargs != NULL) { - if (!PyDict_Next(kwargs, &j, &keyword, NULL)) - break; - } - else { - if (j >= PyTuple_GET_SIZE(kwnames)) - break; - keyword = PyTuple_GET_ITEM(kwnames, j); - j++; - } - - match = PySequence_Contains(kwtuple, keyword); - if (match <= 0) { - if (!match) { - PyErr_Format(PyExc_TypeError, - "'%S' is an invalid keyword " - "argument for %.200s%s", - keyword, - (parser->fname == NULL) ? "this function" : parser->fname, - (parser->fname == NULL) ? "" : "()"); - } - goto exit; - } - } + error_unexpected_keyword_arg(kwargs, kwnames, kwtuple, parser->fname); + goto exit; } return buf; @@ -2684,8 +2703,6 @@ skipitem(const char **p_format, va_list *p_va, int flags) case 's': /* string */ case 'z': /* string or None */ case 'y': /* bytes */ - case 'u': /* unicode string */ - case 'Z': /* unicode string or None */ case 'w': /* buffer, read-write */ { if (p_va != NULL) { @@ -2694,9 +2711,7 @@ skipitem(const char **p_format, va_list *p_va, int flags) if (*format == '#') { if (p_va != NULL) { if (!(flags & FLAG_SIZE_T)) { - PyErr_SetString(PyExc_SystemError, - "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); - return NULL; + return "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"; } (void) va_arg(*p_va, Py_ssize_t *); } @@ -2845,11 +2860,7 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m stack = _PyTuple_ITEMS(args); nargs = PyTuple_GET_SIZE(args); -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, max); -#else - va_start(vargs); -#endif retval = unpack_stack(stack, nargs, name, min, max, vargs); va_end(vargs); return retval; @@ -2862,11 +2873,7 @@ _PyArg_UnpackStack(PyObject *const *args, Py_ssize_t nargs, const char *name, int retval; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, max); -#else - va_start(vargs); -#endif retval = unpack_stack(args, nargs, name, min, max, vargs); va_end(vargs); return retval; @@ -2938,14 +2945,14 @@ _PyArg_NoKwnames(const char *funcname, PyObject *kwnames) void _PyArg_Fini(void) { - struct _PyArg_Parser *tmp, *s = static_arg_parsers; + struct _PyArg_Parser *tmp, *s = _PyRuntime.getargs.static_parsers; while (s) { tmp = s->next; s->next = NULL; parser_clear(s); s = tmp; } - static_arg_parsers = NULL; + _PyRuntime.getargs.static_parsers = NULL; } #ifdef __cplusplus diff --git a/Python/getcopyright.c b/Python/getcopyright.c index 7fdeb314d52..c1f1aad9b84 100644 --- a/Python/getcopyright.c +++ b/Python/getcopyright.c @@ -4,7 +4,7 @@ static const char cprt[] = "\ -Copyright (c) 2001-2021 Python Software Foundation.\n\ +Copyright (c) 2001-2023 Python Software Foundation.\n\ All Rights Reserved.\n\ \n\ Copyright (c) 2000 BeOpen.com.\n\ diff --git a/Python/getopt.c b/Python/getopt.c index 2e3891aae2d..4135bf1446e 100644 --- a/Python/getopt.c +++ b/Python/getopt.c @@ -41,11 +41,15 @@ static const wchar_t *opt_ptr = L""; /* Python command line short and long options */ -#define SHORT_OPTS L"bBc:dEhiIJm:OqRsStuvVW:xX:?" +#define SHORT_OPTS L"bBc:dEhiIJm:OPqRsStuvVW:xX:?" static const _PyOS_LongOption longopts[] = { + /* name, has_arg, val (used in switch in initconfig.c) */ {L"check-hash-based-pycs", 1, 0}, - {NULL, 0, 0}, + {L"help-all", 0, 1}, + {L"help-env", 0, 2}, + {L"help-xoptions", 0, 3}, + {NULL, 0, -1}, /* sentinel */ }; diff --git a/Python/getversion.c b/Python/getversion.c index c32b6f9d60d..5db836ab4bf 100644 --- a/Python/getversion.c +++ b/Python/getversion.c @@ -5,11 +5,25 @@ #include "patchlevel.h" +static int initialized = 0; +static char version[250]; + +void _Py_InitVersion(void) +{ + if (initialized) { + return; + } + initialized = 1; + PyOS_snprintf(version, sizeof(version), "%.80s (%.80s) %.80s", + PY_VERSION, Py_GetBuildInfo(), Py_GetCompiler()); +} + const char * Py_GetVersion(void) { - static char version[250]; - PyOS_snprintf(version, sizeof(version), "%.80s (%.80s) %.80s", - PY_VERSION, Py_GetBuildInfo(), Py_GetCompiler()); + _Py_InitVersion(); return version; } + +// Export the Python hex version as a constant. +const unsigned long Py_Version = PY_VERSION_HEX; diff --git a/Python/hamt.c b/Python/hamt.c index e272e8808fd..8cb94641bef 100644 --- a/Python/hamt.c +++ b/Python/hamt.c @@ -2,6 +2,7 @@ #include "pycore_bitutils.h" // _Py_popcount32 #include "pycore_hamt.h" +#include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_object.h" // _PyObject_GC_TRACK() #include // offsetof() @@ -318,13 +319,6 @@ typedef struct { } PyHamtNode_Array; -typedef struct { - PyObject_VAR_HEAD - uint32_t b_bitmap; - PyObject *b_array[1]; -} PyHamtNode_Bitmap; - - typedef struct { PyObject_VAR_HEAD int32_t c_hash; @@ -332,10 +326,6 @@ typedef struct { } PyHamtNode_Collision; -static PyHamtNode_Bitmap *_empty_bitmap_node; -static PyHamtObject *_empty_hamt; - - static PyHamtObject * hamt_alloc(void); @@ -408,14 +398,22 @@ hamt_hash(PyObject *o) return -1; } - /* While it's suboptimal to reduce Python's 64 bit hash to + /* While it's somewhat suboptimal to reduce Python's 64 bit hash to 32 bits via XOR, it seems that the resulting hash function is good enough (this is also how Long type is hashed in Java.) Storing 10, 100, 1000 Python strings results in a relatively shallow and uniform tree structure. - Please don't change this hashing algorithm, as there are many - tests that test some exact tree shape to cover all code paths. + Also it's worth noting that it would be possible to adapt the tree + structure to 64 bit hashes, but that would increase memory pressure + and provide little to no performance benefits for collections with + fewer than billions of key/value pairs. + + Important: do not change this hash reducing function. There are many + tests that need an exact tree shape to cover all code paths and + we do that by specifying concrete values for test data's `__hash__`. + If this function is changed most of the regression tests would + become useless. */ int32_t xored = (int32_t)(hash & 0xffffffffl) ^ (int32_t)(hash >> 32); return xored == -1 ? -2 : xored; @@ -487,11 +485,7 @@ _hamt_dump_format(_PyUnicodeWriter *writer, const char *format, ...) int ret; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif msg = PyUnicode_FromFormatV(format, vargs); va_end(vargs); @@ -516,14 +510,16 @@ hamt_node_bitmap_new(Py_ssize_t size) PyHamtNode_Bitmap *node; Py_ssize_t i; + if (size == 0) { + /* Since bitmap nodes are immutable, we can cache the instance + for size=0 and reuse it whenever we need an empty bitmap node. + */ + return (PyHamtNode *)Py_NewRef(&_Py_SINGLETON(hamt_bitmap_node_empty)); + } + assert(size >= 0); assert(size % 2 == 0); - if (size == 0 && _empty_bitmap_node != NULL) { - Py_INCREF(_empty_bitmap_node); - return (PyHamtNode *)_empty_bitmap_node; - } - /* No freelist; allocate a new bitmap node */ node = PyObject_GC_NewVar( PyHamtNode_Bitmap, &_PyHamt_BitmapNode_Type, size); @@ -541,14 +537,6 @@ hamt_node_bitmap_new(Py_ssize_t size) _PyObject_GC_TRACK(node); - if (size == 0 && _empty_bitmap_node == NULL) { - /* Since bitmap nodes are immutable, we can cache the instance - for size=0 and reuse it whenever we need an empty bitmap node. - */ - _empty_bitmap_node = node; - Py_INCREF(_empty_bitmap_node); - } - return (PyHamtNode *)node; } @@ -572,8 +560,7 @@ hamt_node_bitmap_clone(PyHamtNode_Bitmap *node) } for (i = 0; i < Py_SIZE(node); i++) { - Py_XINCREF(node->b_array[i]); - clone->b_array[i] = node->b_array[i]; + clone->b_array[i] = Py_XNewRef(node->b_array[i]); } clone->b_bitmap = node->b_bitmap; @@ -598,14 +585,12 @@ hamt_node_bitmap_clone_without(PyHamtNode_Bitmap *o, uint32_t bit) uint32_t i; for (i = 0; i < key_idx; i++) { - Py_XINCREF(o->b_array[i]); - new->b_array[i] = o->b_array[i]; + new->b_array[i] = Py_XNewRef(o->b_array[i]); } assert(Py_SIZE(o) >= 0 && Py_SIZE(o) <= 32); for (i = val_idx + 1; i < (uint32_t)Py_SIZE(o); i++) { - Py_XINCREF(o->b_array[i]); - new->b_array[i - 2] = o->b_array[i]; + new->b_array[i - 2] = Py_XNewRef(o->b_array[i]); } new->b_bitmap = o->b_bitmap & ~bit; @@ -638,15 +623,11 @@ hamt_node_new_bitmap_or_collision(uint32_t shift, return NULL; } - Py_INCREF(key1); - n->c_array[0] = key1; - Py_INCREF(val1); - n->c_array[1] = val1; + n->c_array[0] = Py_NewRef(key1); + n->c_array[1] = Py_NewRef(val1); - Py_INCREF(key2); - n->c_array[2] = key2; - Py_INCREF(val2); - n->c_array[3] = val2; + n->c_array[2] = Py_NewRef(key2); + n->c_array[3] = Py_NewRef(val2); return (PyHamtNode *)n; } @@ -731,8 +712,7 @@ hamt_node_bitmap_assoc(PyHamtNode_Bitmap *self, if (val_or_node == (PyObject *)sub_node) { Py_DECREF(sub_node); - Py_INCREF(self); - return (PyHamtNode *)self; + return (PyHamtNode *)Py_NewRef(self); } PyHamtNode_Bitmap *ret = hamt_node_bitmap_clone(self); @@ -754,8 +734,7 @@ hamt_node_bitmap_assoc(PyHamtNode_Bitmap *self, if (comp_err == 1) { /* key == key_or_null */ if (val == val_or_node) { /* we already have the same key/val pair; return self. */ - Py_INCREF(self); - return (PyHamtNode *)self; + return (PyHamtNode *)Py_NewRef(self); } /* We're setting a new value for the key we had before. @@ -764,8 +743,7 @@ hamt_node_bitmap_assoc(PyHamtNode_Bitmap *self, if (ret == NULL) { return NULL; } - Py_INCREF(val); - Py_SETREF(ret->b_array[val_idx], val); + Py_SETREF(ret->b_array[val_idx], Py_NewRef(val)); return (PyHamtNode *)ret; } @@ -860,8 +838,7 @@ hamt_node_bitmap_assoc(PyHamtNode_Bitmap *self, if (self->b_array[j] == NULL) { new_node->a_array[i] = - (PyHamtNode *)self->b_array[j + 1]; - Py_INCREF(new_node->a_array[i]); + (PyHamtNode *)Py_NewRef(self->b_array[j + 1]); } else { int32_t rehash = hamt_hash(self->b_array[j]); @@ -918,22 +895,18 @@ hamt_node_bitmap_assoc(PyHamtNode_Bitmap *self, /* Copy all keys/values that will be before the new key/value we are adding. */ for (i = 0; i < key_idx; i++) { - Py_XINCREF(self->b_array[i]); - new_node->b_array[i] = self->b_array[i]; + new_node->b_array[i] = Py_XNewRef(self->b_array[i]); } /* Set the new key/value to the new Bitmap node. */ - Py_INCREF(key); - new_node->b_array[key_idx] = key; - Py_INCREF(val); - new_node->b_array[val_idx] = val; + new_node->b_array[key_idx] = Py_NewRef(key); + new_node->b_array[val_idx] = Py_NewRef(val); /* Copy all keys/values that will be after the new key/value we are adding. */ assert(Py_SIZE(self) >= 0 && Py_SIZE(self) <= 32); for (i = key_idx; i < (uint32_t)Py_SIZE(self); i++) { - Py_XINCREF(self->b_array[i]); - new_node->b_array[i + 2] = self->b_array[i]; + new_node->b_array[i + 2] = Py_XNewRef(self->b_array[i]); } new_node->b_bitmap = self->b_bitmap | bit; @@ -1014,10 +987,8 @@ hamt_node_bitmap_without(PyHamtNode_Bitmap *self, PyObject *key = sub_tree->b_array[0]; PyObject *val = sub_tree->b_array[1]; - Py_INCREF(key); - Py_XSETREF(clone->b_array[key_idx], key); - Py_INCREF(val); - Py_SETREF(clone->b_array[val_idx], val); + Py_XSETREF(clone->b_array[key_idx], Py_NewRef(key)); + Py_SETREF(clone->b_array[val_idx], Py_NewRef(val)); Py_DECREF(sub_tree); @@ -1155,6 +1126,16 @@ hamt_node_bitmap_dealloc(PyHamtNode_Bitmap *self) Py_ssize_t len = Py_SIZE(self); Py_ssize_t i; + if (Py_SIZE(self) == 0) { + /* The empty node is statically allocated. */ + assert(self == &_Py_SINGLETON(hamt_bitmap_node_empty)); +#ifdef Py_DEBUG + _Py_FatalRefcountError("deallocating the empty hamt node bitmap singleton"); +#else + return; +#endif + } + PyObject_GC_UnTrack(self); Py_TRASHCAN_BEGIN(self, hamt_node_bitmap_dealloc) @@ -1338,14 +1319,11 @@ hamt_node_collision_assoc(PyHamtNode_Collision *self, } for (i = 0; i < Py_SIZE(self); i++) { - Py_INCREF(self->c_array[i]); - new_node->c_array[i] = self->c_array[i]; + new_node->c_array[i] = Py_NewRef(self->c_array[i]); } - Py_INCREF(key); - new_node->c_array[i] = key; - Py_INCREF(val); - new_node->c_array[i + 1] = val; + new_node->c_array[i] = Py_NewRef(key); + new_node->c_array[i + 1] = Py_NewRef(val); *added_leaf = 1; return (PyHamtNode *)new_node; @@ -1359,8 +1337,7 @@ hamt_node_collision_assoc(PyHamtNode_Collision *self, if (self->c_array[val_idx] == val) { /* We're setting a key/value pair that's already set. */ - Py_INCREF(self); - return (PyHamtNode *)self; + return (PyHamtNode *)Py_NewRef(self); } /* We need to replace old value for the key @@ -1373,14 +1350,11 @@ hamt_node_collision_assoc(PyHamtNode_Collision *self, /* Copy all elements of the old node to the new one. */ for (i = 0; i < Py_SIZE(self); i++) { - Py_INCREF(self->c_array[i]); - new_node->c_array[i] = self->c_array[i]; + new_node->c_array[i] = Py_NewRef(self->c_array[i]); } /* Replace the old value with the new value for the our key. */ - Py_DECREF(new_node->c_array[val_idx]); - Py_INCREF(val); - new_node->c_array[val_idx] = val; + Py_SETREF(new_node->c_array[val_idx], Py_NewRef(val)); return (PyHamtNode *)new_node; @@ -1405,8 +1379,7 @@ hamt_node_collision_assoc(PyHamtNode_Collision *self, return NULL; } new_node->b_bitmap = hamt_bitpos(self->c_hash, shift); - Py_INCREF(self); - new_node->b_array[1] = (PyObject*) self; + new_node->b_array[1] = Py_NewRef(self); assoc_res = hamt_node_bitmap_assoc( new_node, shift, hash, key, val, added_leaf); @@ -1468,17 +1441,13 @@ hamt_node_collision_without(PyHamtNode_Collision *self, } if (key_idx == 0) { - Py_INCREF(self->c_array[2]); - node->b_array[0] = self->c_array[2]; - Py_INCREF(self->c_array[3]); - node->b_array[1] = self->c_array[3]; + node->b_array[0] = Py_NewRef(self->c_array[2]); + node->b_array[1] = Py_NewRef(self->c_array[3]); } else { assert(key_idx == 2); - Py_INCREF(self->c_array[0]); - node->b_array[0] = self->c_array[0]; - Py_INCREF(self->c_array[1]); - node->b_array[1] = self->c_array[1]; + node->b_array[0] = Py_NewRef(self->c_array[0]); + node->b_array[1] = Py_NewRef(self->c_array[1]); } node->b_bitmap = hamt_bitpos(hash, shift); @@ -1499,12 +1468,10 @@ hamt_node_collision_without(PyHamtNode_Collision *self, /* Copy all other keys from `self` to `new` */ Py_ssize_t i; for (i = 0; i < key_idx; i++) { - Py_INCREF(self->c_array[i]); - new->c_array[i] = self->c_array[i]; + new->c_array[i] = Py_NewRef(self->c_array[i]); } for (i = key_idx + 2; i < Py_SIZE(self); i++) { - Py_INCREF(self->c_array[i]); - new->c_array[i - 2] = self->c_array[i]; + new->c_array[i - 2] = Py_NewRef(self->c_array[i]); } *new_node = (PyHamtNode*)new; @@ -1656,8 +1623,7 @@ hamt_node_array_clone(PyHamtNode_Array *node) /* Copy all elements from the current Array node to the new one. */ for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { - Py_XINCREF(node->a_array[i]); - clone->a_array[i] = node->a_array[i]; + clone->a_array[i] = (PyHamtNode*)Py_XNewRef(node->a_array[i]); } VALIDATE_ARRAY_NODE(clone) @@ -1714,8 +1680,7 @@ hamt_node_array_assoc(PyHamtNode_Array *self, /* Copy all elements from the current Array node to the new one. */ for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { - Py_XINCREF(self->a_array[i]); - new_node->a_array[i] = self->a_array[i]; + new_node->a_array[i] = (PyHamtNode*)Py_XNewRef(self->a_array[i]); } assert(new_node->a_array[idx] == NULL); @@ -1863,15 +1828,12 @@ hamt_node_array_without(PyHamtNode_Array *self, PyObject *key = child->b_array[0]; PyObject *val = child->b_array[1]; - Py_INCREF(key); - new->b_array[new_i] = key; - Py_INCREF(val); - new->b_array[new_i + 1] = val; + new->b_array[new_i] = Py_NewRef(key); + new->b_array[new_i + 1] = Py_NewRef(val); } else { new->b_array[new_i] = NULL; - Py_INCREF(node); - new->b_array[new_i + 1] = (PyObject*)node; + new->b_array[new_i + 1] = Py_NewRef(node); } } else { @@ -1889,8 +1851,7 @@ hamt_node_array_without(PyHamtNode_Array *self, /* Just copy the node into our new Bitmap */ new->b_array[new_i] = NULL; - Py_INCREF(node); - new->b_array[new_i + 1] = (PyObject*)node; + new->b_array[new_i + 1] = Py_NewRef(node); } new_i += 2; @@ -2306,8 +2267,7 @@ _PyHamt_Assoc(PyHamtObject *o, PyObject *key, PyObject *val) if (new_root == o->h_root) { Py_DECREF(new_root); - Py_INCREF(o); - return o; + return (PyHamtObject*)Py_NewRef(o); } new_o = hamt_alloc(); @@ -2343,8 +2303,7 @@ _PyHamt_Without(PyHamtObject *o, PyObject *key) case W_EMPTY: return _PyHamt_New(); case W_NOT_FOUND: - Py_INCREF(o); - return o; + return (PyHamtObject*)Py_NewRef(o); case W_NEWNODE: { assert(new_root != NULL); @@ -2465,35 +2424,15 @@ hamt_alloc(void) return o; } +#define _empty_hamt \ + (&_Py_INTERP_SINGLETON(_PyInterpreterState_Get(), hamt_empty)) + PyHamtObject * _PyHamt_New(void) { - if (_empty_hamt != NULL) { - /* HAMT is an immutable object so we can easily cache an - empty instance. */ - Py_INCREF(_empty_hamt); - return _empty_hamt; - } - - PyHamtObject *o = hamt_alloc(); - if (o == NULL) { - return NULL; - } - - o->h_root = hamt_node_bitmap_new(0); - if (o->h_root == NULL) { - Py_DECREF(o); - return NULL; - } - - o->h_count = 0; - - if (_empty_hamt == NULL) { - Py_INCREF(o); - _empty_hamt = o; - } - - return o; + /* HAMT is an immutable object so we can easily cache an + empty instance. */ + return (PyHamtObject*)Py_NewRef(_empty_hamt); } #ifdef Py_DEBUG @@ -2586,8 +2525,7 @@ hamt_baseiter_new(PyTypeObject *type, binaryfunc yield, PyHamtObject *o) return NULL; } - Py_INCREF(o); - it->hi_obj = o; + it->hi_obj = (PyHamtObject*)Py_NewRef(o); it->hi_yield = yield; hamt_iterator_init(&it->hi_iter, o->h_root); @@ -2643,8 +2581,7 @@ PyTypeObject _PyHamtKeys_Type = { static PyObject * hamt_iter_yield_keys(PyObject *key, PyObject *val) { - Py_INCREF(key); - return key; + return Py_NewRef(key); } PyObject * @@ -2667,8 +2604,7 @@ PyTypeObject _PyHamtValues_Type = { static PyObject * hamt_iter_yield_values(PyObject *key, PyObject *val) { - Py_INCREF(val); - return val; + return Py_NewRef(val); } PyObject * @@ -2712,6 +2648,15 @@ hamt_tp_traverse(PyHamtObject *self, visitproc visit, void *arg) static void hamt_tp_dealloc(PyHamtObject *self) { + if (self == _empty_hamt) { + /* The empty one is statically allocated. */ +#ifdef Py_DEBUG + _Py_FatalRefcountError("deallocating the empty hamt singleton"); +#else + return; +#endif + } + PyObject_GC_UnTrack(self); if (self->h_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject*)self); @@ -2761,8 +2706,7 @@ hamt_tp_subscript(PyHamtObject *self, PyObject *key) case F_ERROR: return NULL; case F_FOUND: - Py_INCREF(val); - return val; + return Py_NewRef(val); case F_NOT_FOUND: PyErr_SetObject(PyExc_KeyError, key); return NULL; @@ -2812,14 +2756,12 @@ hamt_py_get(PyHamtObject *self, PyObject *args) case F_ERROR: return NULL; case F_FOUND: - Py_INCREF(val); - return val; + return Py_NewRef(val); case F_NOT_FOUND: if (def == NULL) { Py_RETURN_NONE; } - Py_INCREF(def); - return def; + return Py_NewRef(def); default: Py_UNREACHABLE(); } @@ -2844,14 +2786,14 @@ hamt_py_values(PyHamtObject *self, PyObject *args) } static PyObject * -hamt_py_keys(PyHamtObject *self, PyObject *args) +hamt_py_keys(PyHamtObject *self, PyObject *Py_UNUSED(args)) { return _PyHamt_NewIterKeys(self); } #ifdef Py_DEBUG static PyObject * -hamt_py_dump(PyHamtObject *self, PyObject *args) +hamt_py_dump(PyHamtObject *self, PyObject *Py_UNUSED(args)) { return hamt_dump(self); } @@ -2859,14 +2801,14 @@ hamt_py_dump(PyHamtObject *self, PyObject *args) static PyMethodDef PyHamt_methods[] = { - {"set", (PyCFunction)hamt_py_set, METH_VARARGS, NULL}, - {"get", (PyCFunction)hamt_py_get, METH_VARARGS, NULL}, - {"delete", (PyCFunction)hamt_py_delete, METH_O, NULL}, - {"items", (PyCFunction)hamt_py_items, METH_NOARGS, NULL}, - {"keys", (PyCFunction)hamt_py_keys, METH_NOARGS, NULL}, - {"values", (PyCFunction)hamt_py_values, METH_NOARGS, NULL}, + {"set", _PyCFunction_CAST(hamt_py_set), METH_VARARGS, NULL}, + {"get", _PyCFunction_CAST(hamt_py_get), METH_VARARGS, NULL}, + {"delete", _PyCFunction_CAST(hamt_py_delete), METH_O, NULL}, + {"items", _PyCFunction_CAST(hamt_py_items), METH_NOARGS, NULL}, + {"keys", _PyCFunction_CAST(hamt_py_keys), METH_NOARGS, NULL}, + {"values", _PyCFunction_CAST(hamt_py_values), METH_NOARGS, NULL}, #ifdef Py_DEBUG - {"__dump__", (PyCFunction)hamt_py_dump, METH_NOARGS, NULL}, + {"__dump__", _PyCFunction_CAST(hamt_py_dump), METH_NOARGS, NULL}, #endif {NULL, NULL} }; @@ -2950,28 +2892,3 @@ PyTypeObject _PyHamt_CollisionNode_Type = { .tp_free = PyObject_GC_Del, .tp_hash = PyObject_HashNotImplemented, }; - - -int -_PyHamt_Init(void) -{ - if ((PyType_Ready(&_PyHamt_Type) < 0) || - (PyType_Ready(&_PyHamt_ArrayNode_Type) < 0) || - (PyType_Ready(&_PyHamt_BitmapNode_Type) < 0) || - (PyType_Ready(&_PyHamt_CollisionNode_Type) < 0) || - (PyType_Ready(&_PyHamtKeys_Type) < 0) || - (PyType_Ready(&_PyHamtValues_Type) < 0) || - (PyType_Ready(&_PyHamtItems_Type) < 0)) - { - return 0; - } - - return 1; -} - -void -_PyHamt_Fini(void) -{ - Py_CLEAR(_empty_hamt); - Py_CLEAR(_empty_bitmap_node); -} diff --git a/Python/import.c b/Python/import.c index 225fbf43a30..da6c15c5fd4 100644 --- a/Python/import.c +++ b/Python/import.c @@ -24,23 +24,19 @@ extern "C" { #endif -#define CACHEDIR "__pycache__" - /* Forward references */ static PyObject *import_add_module(PyThreadState *tstate, PyObject *name); -/* See _PyImport_FixupExtensionObject() below */ -static PyObject *extensions = NULL; - /* This table is defined in config.c: */ extern struct _inittab _PyImport_Inittab[]; +// This is not used after Py_Initialize() is called. +// (See _PyRuntimeState.imports.inittab.) struct _inittab *PyImport_Inittab = _PyImport_Inittab; +// When we dynamically allocate a larger table for PyImport_ExtendInittab(), +// we track the pointer here so we can deallocate it during finalization. static struct _inittab *inittab_copy = NULL; -_Py_IDENTIFIER(__path__); -_Py_IDENTIFIER(__spec__); - /*[clinic input] module _imp [clinic start generated code]*/ @@ -53,7 +49,7 @@ module _imp PyStatus _PyImportZip_Init(PyThreadState *tstate) { - PyObject *path_hooks, *zipimport; + PyObject *path_hooks; int err = 0; path_hooks = PySys_GetObject("path_hooks"); @@ -68,34 +64,22 @@ _PyImportZip_Init(PyThreadState *tstate) PySys_WriteStderr("# installing zipimport hook\n"); } - zipimport = PyImport_ImportModule("zipimport"); - if (zipimport == NULL) { - _PyErr_Clear(tstate); /* No zip import module -- okay */ + PyObject *zipimporter = _PyImport_GetModuleAttrString("zipimport", "zipimporter"); + if (zipimporter == NULL) { + _PyErr_Clear(tstate); /* No zipimporter object -- okay */ if (verbose) { - PySys_WriteStderr("# can't import zipimport\n"); + PySys_WriteStderr("# can't import zipimport.zipimporter\n"); } } else { - _Py_IDENTIFIER(zipimporter); - PyObject *zipimporter = _PyObject_GetAttrId(zipimport, - &PyId_zipimporter); - Py_DECREF(zipimport); - if (zipimporter == NULL) { - _PyErr_Clear(tstate); /* No zipimporter object -- okay */ - if (verbose) { - PySys_WriteStderr("# can't import zipimport.zipimporter\n"); - } + /* sys.path_hooks.insert(0, zipimporter) */ + err = PyList_Insert(path_hooks, 0, zipimporter); + Py_DECREF(zipimporter); + if (err < 0) { + goto error; } - else { - /* sys.path_hooks.insert(0, zipimporter) */ - err = PyList_Insert(path_hooks, 0, zipimporter); - Py_DECREF(zipimporter); - if (err < 0) { - goto error; - } - if (verbose) { - PySys_WriteStderr("# installed zipimport hook\n"); - } + if (verbose) { + PySys_WriteStderr("# installed zipimport hook\n"); } } @@ -110,9 +94,9 @@ _PyImportZip_Init(PyThreadState *tstate) in different threads to return with a partially loaded module. These calls are serialized by the global interpreter lock. */ -static PyThread_type_lock import_lock = NULL; -static unsigned long import_lock_thread = PYTHREAD_INVALID_THREAD_ID; -static int import_lock_level = 0; +#define import_lock _PyRuntime.imports.lock.mutex +#define import_lock_thread _PyRuntime.imports.lock.thread +#define import_lock_level _PyRuntime.imports.lock.level void _PyImport_AcquireLock(void) @@ -238,14 +222,59 @@ _imp_release_lock_impl(PyObject *module) Py_RETURN_NONE; } +PyStatus +_PyImport_Init(void) +{ + if (_PyRuntime.imports.inittab != NULL) { + return _PyStatus_ERR("global import state already initialized"); + } + PyStatus status = _PyStatus_OK(); + + size_t size; + for (size = 0; PyImport_Inittab[size].name != NULL; size++) + ; + size++; + + /* Force default raw memory allocator to get a known allocator to be able + to release the memory in _PyImport_Fini() */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + /* Make the copy. */ + struct _inittab *copied = PyMem_RawMalloc(size * sizeof(struct _inittab)); + if (copied == NULL) { + status = PyStatus_NoMemory(); + goto done; + } + memcpy(copied, PyImport_Inittab, size * sizeof(struct _inittab)); + _PyRuntime.imports.inittab = copied; + +done: + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + return status; +} + +static inline void _extensions_cache_clear(void); + void _PyImport_Fini(void) { - Py_CLEAR(extensions); + _extensions_cache_clear(); if (import_lock != NULL) { PyThread_free_lock(import_lock); import_lock = NULL; } + + /* Use the same memory allocator as _PyImport_Init(). */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + /* Free memory allocated by _PyImport_Init() */ + struct _inittab *inittab = _PyRuntime.imports.inittab; + _PyRuntime.imports.inittab = NULL; + PyMem_RawFree(inittab); + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); } void @@ -290,7 +319,7 @@ _PyImport_IsInitialized(PyInterpreterState *interp) } PyObject * -_PyImport_GetModuleId(struct _Py_Identifier *nameid) +_PyImport_GetModuleId(_Py_Identifier *nameid) { PyObject *name = _PyUnicode_FromId(nameid); /* borrowed */ if (name == NULL) { @@ -347,20 +376,18 @@ import_ensure_initialized(PyInterpreterState *interp, PyObject *mod, PyObject *n { PyObject *spec; - _Py_IDENTIFIER(_lock_unlock_module); - /* Optimization: only call _bootstrap._lock_unlock_module() if __spec__._initializing is true. NOTE: because of this, initializing must be set *before* stuffing the new module in sys.modules. */ - spec = _PyObject_GetAttrId(mod, &PyId___spec__); + spec = PyObject_GetAttr(mod, &_Py_ID(__spec__)); int busy = _PyModuleSpec_IsInitializing(spec); Py_XDECREF(spec); if (busy) { /* Wait until module is done importing. */ - PyObject *value = _PyObject_CallMethodIdOneArg( - interp->importlib, &PyId__lock_unlock_module, name); + PyObject *value = _PyObject_CallMethodOneArg( + interp->importlib, &_Py_ID(_lock_unlock_module), name); if (value == NULL) { return -1; } @@ -417,6 +444,51 @@ PyImport_GetMagicTag(void) dictionary, to avoid loading shared libraries twice. */ +static PyModuleDef * +_extensions_cache_get(PyObject *filename, PyObject *name) +{ + PyObject *extensions = _PyRuntime.imports.extensions; + if (extensions == NULL) { + return NULL; + } + PyObject *key = PyTuple_Pack(2, filename, name); + if (key == NULL) { + return NULL; + } + PyModuleDef *def = (PyModuleDef *)PyDict_GetItemWithError(extensions, key); + Py_DECREF(key); + return def; +} + +static int +_extensions_cache_set(PyObject *filename, PyObject *name, PyModuleDef *def) +{ + PyObject *extensions = _PyRuntime.imports.extensions; + if (extensions == NULL) { + extensions = PyDict_New(); + if (extensions == NULL) { + return -1; + } + _PyRuntime.imports.extensions = extensions; + } + PyObject *key = PyTuple_Pack(2, filename, name); + if (key == NULL) { + return -1; + } + int res = PyDict_SetItem(extensions, key, (PyObject *)def); + Py_DECREF(key); + if (res < 0) { + return -1; + } + return 0; +} + +static void +_extensions_cache_clear(void) +{ + Py_CLEAR(_PyRuntime.imports.extensions); +} + int _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, PyObject *filename, PyObject *modules) @@ -461,20 +533,7 @@ _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, } } - if (extensions == NULL) { - extensions = PyDict_New(); - if (extensions == NULL) { - return -1; - } - } - - PyObject *key = PyTuple_Pack(2, filename, name); - if (key == NULL) { - return -1; - } - int res = PyDict_SetItem(extensions, key, (PyObject *)def); - Py_DECREF(key); - if (res < 0) { + if (_extensions_cache_set(filename, name, def) < 0) { return -1; } } @@ -499,16 +558,7 @@ static PyObject * import_find_extension(PyThreadState *tstate, PyObject *name, PyObject *filename) { - if (extensions == NULL) { - return NULL; - } - - PyObject *key = PyTuple_Pack(2, filename, name); - if (key == NULL) { - return NULL; - } - PyModuleDef* def = (PyModuleDef *)PyDict_GetItemWithError(extensions, key); - Py_DECREF(key); + PyModuleDef *def = _extensions_cache_get(filename, name); if (def == NULL) { return NULL; } @@ -536,7 +586,7 @@ import_find_extension(PyThreadState *tstate, PyObject *name, else { if (def->m_base.m_init == NULL) return NULL; - mod = def->m_base.m_init(); + mod = _PyImport_InitFunc_TrampolineCall(def->m_base.m_init); if (mod == NULL) return NULL; if (PyObject_SetItem(modules, name, mod) == -1) { @@ -575,8 +625,7 @@ import_add_module(PyThreadState *tstate, PyObject *name) PyObject *m; if (PyDict_CheckExact(modules)) { - m = PyDict_GetItemWithError(modules, name); - Py_XINCREF(m); + m = Py_XNewRef(PyDict_GetItemWithError(modules, name)); } else { m = PyObject_GetItem(modules, name); @@ -712,7 +761,6 @@ PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, } else if (cpathobj != NULL) { PyInterpreterState *interp = _PyInterpreterState_GET(); - _Py_IDENTIFIER(_get_sourcefile); if (interp == NULL) { Py_FatalError("no current interpreter"); @@ -721,8 +769,8 @@ PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, external= PyObject_GetAttrString(interp->importlib, "_bootstrap_external"); if (external != NULL) { - pathobj = _PyObject_CallMethodIdOneArg( - external, &PyId__get_sourcefile, cpathobj); + pathobj = _PyObject_CallMethodOneArg( + external, &_Py_ID(_get_sourcefile), cpathobj); Py_DECREF(external); } if (pathobj == NULL) @@ -742,7 +790,6 @@ error: static PyObject * module_dict_for_exec(PyThreadState *tstate, PyObject *name) { - _Py_IDENTIFIER(__builtins__); PyObject *m, *d; m = import_add_module(tstate, name); @@ -751,10 +798,9 @@ module_dict_for_exec(PyThreadState *tstate, PyObject *name) /* If the module is being reloaded, we get the old module back and re-use its dict to exec the new code. */ d = PyModule_GetDict(m); - int r = _PyDict_ContainsId(d, &PyId___builtins__); + int r = PyDict_Contains(d, &_Py_ID(__builtins__)); if (r == 0) { - r = _PyDict_SetItemId(d, &PyId___builtins__, - PyEval_GetBuiltins()); + r = PyDict_SetItem(d, &_Py_ID(__builtins__), PyEval_GetBuiltins()); } if (r < 0) { remove_module(tstate, name); @@ -796,7 +842,6 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, { PyThreadState *tstate = _PyThreadState_GET(); PyObject *d, *external, *res; - _Py_IDENTIFIER(_fix_up_module); d = module_dict_for_exec(tstate, name); if (d == NULL) { @@ -812,9 +857,8 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, Py_DECREF(d); return NULL; } - res = _PyObject_CallMethodIdObjArgs(external, - &PyId__fix_up_module, - d, name, pathname, cpathname, NULL); + res = PyObject_CallMethodObjArgs(external, &_Py_ID(_fix_up_module), + d, name, pathname, cpathname, NULL); Py_DECREF(external); if (res != NULL) { Py_DECREF(res); @@ -834,8 +878,7 @@ update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname) if (PyUnicode_Compare(co->co_filename, oldname)) return; - Py_INCREF(newname); - Py_XSETREF(co->co_filename, newname); + Py_XSETREF(co->co_filename, Py_NewRef(newname)); constants = co->co_consts; n = PyTuple_GET_SIZE(constants); @@ -892,9 +935,10 @@ static int is_builtin(PyObject *name) { int i; - for (i = 0; PyImport_Inittab[i].name != NULL; i++) { - if (_PyUnicode_EqualToASCIIString(name, PyImport_Inittab[i].name)) { - if (PyImport_Inittab[i].initfunc == NULL) + struct _inittab *inittab = _PyRuntime.imports.inittab; + for (i = 0; inittab[i].name != NULL; i++) { + if (_PyUnicode_EqualToASCIIString(name, inittab[i].name)) { + if (inittab[i].initfunc == NULL) return -1; else return 1; @@ -929,8 +973,7 @@ get_path_importer(PyThreadState *tstate, PyObject *path_importer_cache, importer = PyDict_GetItemWithError(path_importer_cache, p); if (importer != NULL || _PyErr_Occurred(tstate)) { - Py_XINCREF(importer); - return importer; + return Py_XNewRef(importer); } /* set path_importer_cache[p] to None to avoid recursion */ @@ -972,6 +1015,13 @@ PyImport_GetImporter(PyObject *path) return get_path_importer(tstate, path_importer_cache, path_hooks, path); } +#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) +#include +EM_JS(PyObject*, _PyImport_InitFunc_TrampolineCall, (PyModInitFunction func), { + return wasmTable.get(func)(); +}); +#endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE + static PyObject* create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec) { @@ -981,14 +1031,14 @@ create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec) } PyObject *modules = tstate->interp->modules; - for (struct _inittab *p = PyImport_Inittab; p->name != NULL; p++) { + for (struct _inittab *p = _PyRuntime.imports.inittab; p->name != NULL; p++) { if (_PyUnicode_EqualToASCIIString(name, p->name)) { if (p->initfunc == NULL) { /* Cannot re-init internal module ("sys" or "builtins") */ - return PyImport_AddModuleObject(name); + mod = PyImport_AddModuleObject(name); + return Py_XNewRef(mod); } - - mod = (*p->initfunc)(); + mod = _PyImport_InitFunc_TrampolineCall(*p->initfunc); if (mod == NULL) { return NULL; } @@ -1039,6 +1089,14 @@ _imp_create_builtin(PyObject *module, PyObject *spec) return NULL; } + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, + "name must be string, not %.200s", + Py_TYPE(name)->tp_name); + Py_DECREF(name); + return NULL; + } + PyObject *mod = create_builtin(tstate, name, spec); Py_DECREF(name); return mod; @@ -1087,7 +1145,7 @@ use_frozen(void) } static PyObject * -list_frozen_module_names() +list_frozen_module_names(void) { PyObject *names = PyList_New(0); if (names == NULL) { @@ -1297,13 +1355,21 @@ find_frozen(PyObject *nameobj, struct frozen_info *info) info->nameobj = nameobj; // borrowed info->data = (const char *)p->code; info->get_code = p->get_code; - info->size = p->size < 0 ? -(p->size) : p->size; - info->is_package = p->size < 0 ? true : false; + info->size = p->size; + info->is_package = p->is_package; + if (p->size < 0) { + // backward compatibility with negative size values + info->size = -(p->size); + info->is_package = true; + } info->origname = name; info->is_alias = resolve_module_alias(name, _PyImport_FrozenAliases, &info->origname); } - + if (p->code == NULL && p->size == 0 && p->get_code != NULL) { + /* It is only deepfrozen. */ + return FROZEN_OKAY; + } if (p->code == NULL) { /* It is frozen but marked as un-importable. */ return FROZEN_EXCLUDED; @@ -1405,8 +1471,7 @@ PyImport_ImportFrozenModuleObject(PyObject *name) } } else { - Py_INCREF(Py_None); - origname = Py_None; + origname = Py_NewRef(Py_None); } err = PyDict_SetItemString(d, "__origname__", origname); Py_DECREF(origname); @@ -1518,8 +1583,7 @@ remove_importlib_frames(PyThreadState *tstate) if (in_importlib && (always_trim || _PyUnicode_EqualToASCIIString(code->co_name, remove_frames))) { - Py_XINCREF(next); - Py_XSETREF(*outer_link, next); + Py_XSETREF(*outer_link, Py_XNewRef(next)); prev_link = outer_link; } else { @@ -1536,9 +1600,6 @@ done: static PyObject * resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level) { - _Py_IDENTIFIER(__package__); - _Py_IDENTIFIER(__name__); - _Py_IDENTIFIER(parent); PyObject *abs_name; PyObject *package = NULL; PyObject *spec; @@ -1554,14 +1615,14 @@ resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level _PyErr_SetString(tstate, PyExc_TypeError, "globals must be a dict"); goto error; } - package = _PyDict_GetItemIdWithError(globals, &PyId___package__); + package = PyDict_GetItemWithError(globals, &_Py_ID(__package__)); if (package == Py_None) { package = NULL; } else if (package == NULL && _PyErr_Occurred(tstate)) { goto error; } - spec = _PyDict_GetItemIdWithError(globals, &PyId___spec__); + spec = PyDict_GetItemWithError(globals, &_Py_ID(__spec__)); if (spec == NULL && _PyErr_Occurred(tstate)) { goto error; } @@ -1575,7 +1636,7 @@ resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level } else if (spec != NULL && spec != Py_None) { int equal; - PyObject *parent = _PyObject_GetAttrId(spec, &PyId_parent); + PyObject *parent = PyObject_GetAttr(spec, &_Py_ID(parent)); if (parent == NULL) { goto error; } @@ -1586,7 +1647,7 @@ resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level goto error; } else if (equal == 0) { - if (PyErr_WarnEx(PyExc_ImportWarning, + if (PyErr_WarnEx(PyExc_DeprecationWarning, "__package__ != __spec__.parent", 1) < 0) { goto error; } @@ -1594,7 +1655,7 @@ resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level } } else if (spec != NULL && spec != Py_None) { - package = _PyObject_GetAttrId(spec, &PyId_parent); + package = PyObject_GetAttr(spec, &_Py_ID(parent)); if (package == NULL) { goto error; } @@ -1611,7 +1672,7 @@ resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level goto error; } - package = _PyDict_GetItemIdWithError(globals, &PyId___name__); + package = PyDict_GetItemWithError(globals, &_Py_ID(__name__)); if (package == NULL) { if (!_PyErr_Occurred(tstate)) { _PyErr_SetString(tstate, PyExc_KeyError, @@ -1627,7 +1688,7 @@ resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level goto error; } - int haspath = _PyDict_ContainsId(globals, &PyId___path__); + int haspath = PyDict_Contains(globals, &_Py_ID(__path__)); if (haspath < 0) { goto error; } @@ -1695,12 +1756,11 @@ resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level static PyObject * import_find_and_load(PyThreadState *tstate, PyObject *abs_name) { - _Py_IDENTIFIER(_find_and_load); PyObject *mod = NULL; PyInterpreterState *interp = tstate->interp; int import_time = _PyInterpreterState_GetConfig(interp)->import_time; - static int import_level; - static _PyTime_t accumulated; +#define import_level _PyRuntime.imports.find_and_load.import_level +#define accumulated _PyRuntime.imports.find_and_load.accumulated _PyTime_t t1 = 0, accumulated_copy = accumulated; @@ -1721,12 +1781,13 @@ import_find_and_load(PyThreadState *tstate, PyObject *abs_name) * _PyDict_GetItemIdWithError(). */ if (import_time) { - static int header = 1; +#define header _PyRuntime.imports.find_and_load.header if (header) { fputs("import time: self [us] | cumulative | imported package\n", stderr); header = 0; } +#undef header import_level++; t1 = _PyTime_GetPerfCounter(); @@ -1736,9 +1797,8 @@ import_find_and_load(PyThreadState *tstate, PyObject *abs_name) if (PyDTrace_IMPORT_FIND_LOAD_START_ENABLED()) PyDTrace_IMPORT_FIND_LOAD_START(PyUnicode_AsUTF8(abs_name)); - mod = _PyObject_CallMethodIdObjArgs(interp->importlib, - &PyId__find_and_load, abs_name, - interp->import_func, NULL); + mod = PyObject_CallMethodObjArgs(interp->importlib, &_Py_ID(_find_and_load), + abs_name, interp->import_func, NULL); if (PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED()) PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name), @@ -1757,6 +1817,8 @@ import_find_and_load(PyThreadState *tstate, PyObject *abs_name) } return mod; +#undef import_level +#undef accumulated } PyObject * @@ -1782,7 +1844,6 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, int level) { PyThreadState *tstate = _PyThreadState_GET(); - _Py_IDENTIFIER(_handle_fromlist); PyObject *abs_name = NULL; PyObject *final_mod = NULL; PyObject *mod = NULL; @@ -1821,8 +1882,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name"); goto error; } - abs_name = name; - Py_INCREF(abs_name); + abs_name = Py_NewRef(name); } mod = import_get_module(tstate, abs_name); @@ -1861,8 +1921,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, if (dot == -1) { /* No dot in module name, simple exit */ - final_mod = mod; - Py_INCREF(mod); + final_mod = Py_NewRef(mod); goto error; } @@ -1897,24 +1956,22 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, } } else { - final_mod = mod; - Py_INCREF(mod); + final_mod = Py_NewRef(mod); } } else { PyObject *path; - if (_PyObject_LookupAttrId(mod, &PyId___path__, &path) < 0) { + if (_PyObject_LookupAttr(mod, &_Py_ID(__path__), &path) < 0) { goto error; } if (path) { Py_DECREF(path); - final_mod = _PyObject_CallMethodIdObjArgs( - interp->importlib, &PyId__handle_fromlist, + final_mod = PyObject_CallMethodObjArgs( + interp->importlib, &_Py_ID(_handle_fromlist), mod, fromlist, interp->import_func, NULL); } else { - final_mod = mod; - Py_INCREF(mod); + final_mod = Py_NewRef(mod); } } @@ -1949,10 +2006,8 @@ PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals PyObject * PyImport_ReloadModule(PyObject *m) { - _Py_IDENTIFIER(importlib); - _Py_IDENTIFIER(reload); PyObject *reloaded_module = NULL; - PyObject *importlib = _PyImport_GetModuleId(&PyId_importlib); + PyObject *importlib = PyImport_GetModule(&_Py_ID(importlib)); if (importlib == NULL) { if (PyErr_Occurred()) { return NULL; @@ -1964,7 +2019,7 @@ PyImport_ReloadModule(PyObject *m) } } - reloaded_module = _PyObject_CallMethodIdOneArg(importlib, &PyId_reload, m); + reloaded_module = PyObject_CallMethodOneArg(importlib, &_Py_ID(reload), m); Py_DECREF(importlib); return reloaded_module; } @@ -1982,26 +2037,12 @@ PyImport_ReloadModule(PyObject *m) PyObject * PyImport_Import(PyObject *module_name) { - _Py_IDENTIFIER(__import__); - _Py_IDENTIFIER(__builtins__); - PyThreadState *tstate = _PyThreadState_GET(); PyObject *globals = NULL; PyObject *import = NULL; PyObject *builtins = NULL; PyObject *r = NULL; - /* Initialize constant string objects */ - PyObject *import_str = _PyUnicode_FromId(&PyId___import__); // borrowed ref - if (import_str == NULL) { - return NULL; - } - - PyObject *builtins_str = _PyUnicode_FromId(&PyId___builtins__); // borrowed ref - if (builtins_str == NULL) { - return NULL; - } - PyObject *from_list = PyList_New(0); if (from_list == NULL) { goto err; @@ -2011,7 +2052,7 @@ PyImport_Import(PyObject *module_name) globals = PyEval_GetGlobals(); if (globals != NULL) { Py_INCREF(globals); - builtins = PyObject_GetItem(globals, builtins_str); + builtins = PyObject_GetItem(globals, &_Py_ID(__builtins__)); if (builtins == NULL) goto err; } @@ -2022,20 +2063,20 @@ PyImport_Import(PyObject *module_name) if (builtins == NULL) { goto err; } - globals = Py_BuildValue("{OO}", builtins_str, builtins); + globals = Py_BuildValue("{OO}", &_Py_ID(__builtins__), builtins); if (globals == NULL) goto err; } /* Get the __import__ function from the builtins */ if (PyDict_Check(builtins)) { - import = PyObject_GetItem(builtins, import_str); + import = PyObject_GetItem(builtins, &_Py_ID(__import__)); if (import == NULL) { - _PyErr_SetObject(tstate, PyExc_KeyError, import_str); + _PyErr_SetObject(tstate, PyExc_KeyError, &_Py_ID(__import__)); } } else - import = PyObject_GetAttr(builtins, import_str); + import = PyObject_GetAttr(builtins, &_Py_ID(__import__)); if (import == NULL) goto err; @@ -2224,7 +2265,7 @@ _imp_get_frozen_object_impl(PyObject *module, PyObject *name, if (info.nameobj == NULL) { info.nameobj = name; } - if (info.size == 0) { + if (info.size == 0 && info.get_code == NULL) { /* Does not contain executable code. */ set_frozen_error(FROZEN_INVALID, name); return NULL; @@ -2602,6 +2643,10 @@ PyImport_ExtendInittab(struct _inittab *newtab) size_t i, n; int res = 0; + if (_PyRuntime.imports.inittab != NULL) { + Py_FatalError("PyImport_ExtendInittab() may be be called after Py_Initialize()"); + } + /* Count the number of entries in both tables */ for (n = 0; newtab[n].name != NULL; n++) ; @@ -2646,6 +2691,10 @@ PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) { struct _inittab newtab[2]; + if (_PyRuntime.imports.inittab != NULL) { + Py_FatalError("PyImport_AppendInittab() may be be called after Py_Initialize()"); + } + memset(newtab, '\0', sizeof newtab); newtab[0].name = name; @@ -2654,6 +2703,37 @@ PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) return PyImport_ExtendInittab(newtab); } + +PyObject * +_PyImport_GetModuleAttr(PyObject *modname, PyObject *attrname) +{ + PyObject *mod = PyImport_Import(modname); + if (mod == NULL) { + return NULL; + } + PyObject *result = PyObject_GetAttr(mod, attrname); + Py_DECREF(mod); + return result; +} + +PyObject * +_PyImport_GetModuleAttrString(const char *modname, const char *attrname) +{ + PyObject *pmodname = PyUnicode_FromString(modname); + if (pmodname == NULL) { + return NULL; + } + PyObject *pattrname = PyUnicode_FromString(attrname); + if (pattrname == NULL) { + Py_DECREF(pmodname); + return NULL; + } + PyObject *result = _PyImport_GetModuleAttr(pmodname, pattrname); + Py_DECREF(pattrname); + Py_DECREF(pmodname); + return result; +} + #ifdef __cplusplus } #endif diff --git a/Python/importdl.c b/Python/importdl.c index 6d2554741f9..91fa06f49c2 100644 --- a/Python/importdl.c +++ b/Python/importdl.c @@ -2,6 +2,9 @@ /* Support for dynamic loading of extension modules */ #include "Python.h" +#include "pycore_call.h" +#include "pycore_pystate.h" +#include "pycore_runtime.h" /* ./configure sets HAVE_DYNAMIC_LOADING if dynamic loading of modules is supported on this platform. configure will then compile and link in one @@ -38,7 +41,6 @@ get_encoded_name(PyObject *name, const char **hook_prefix) { PyObject *encoded = NULL; PyObject *modname = NULL; Py_ssize_t name_len, lastdot; - _Py_IDENTIFIER(replace); /* Get the short name (substring after last dot) */ name_len = PyUnicode_GetLength(name); @@ -76,7 +78,7 @@ get_encoded_name(PyObject *name, const char **hook_prefix) { } /* Replace '-' by '_' */ - modname = _PyObject_CallMethodId(encoded, &PyId_replace, "cc", '-', '_'); + modname = _PyObject_CallMethod(encoded, &_Py_ID(replace), "cc", '-', '_'); if (modname == NULL) goto error; @@ -100,7 +102,7 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) const char *oldcontext; dl_funcptr exportfunc; PyModuleDef *def; - PyObject *(*p0)(void); + PyModInitFunction p0; name_unicode = PyObject_GetAttrString(spec, "name"); if (name_unicode == NULL) { @@ -155,17 +157,19 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) goto error; } - p0 = (PyObject *(*)(void))exportfunc; + p0 = (PyModInitFunction)exportfunc; /* Package context is needed for single-phase init */ +#define _Py_PackageContext (_PyRuntime.imports.pkgcontext) oldcontext = _Py_PackageContext; _Py_PackageContext = PyUnicode_AsUTF8(name_unicode); if (_Py_PackageContext == NULL) { _Py_PackageContext = oldcontext; goto error; } - m = p0(); + m = _PyImport_InitFunc_TrampolineCall(p0); _Py_PackageContext = oldcontext; +#undef _Py_PackageContext if (m == NULL) { if (!PyErr_Occurred()) { @@ -176,8 +180,7 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) } goto error; } else if (PyErr_Occurred()) { - PyErr_Clear(); - PyErr_Format( + _PyErr_FormatFromCause( PyExc_SystemError, "initialization of %s raised unreported exception", name_buf); diff --git a/Python/importdl.h b/Python/importdl.h index 9847652b1f1..26d18b626df 100644 --- a/Python/importdl.h +++ b/Python/importdl.h @@ -10,6 +10,14 @@ extern const char *_PyImport_DynLoadFiletab[]; extern PyObject *_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *); +typedef PyObject *(*PyModInitFunction)(void); + +#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) +extern PyObject *_PyImport_InitFunc_TrampolineCall(PyModInitFunction func); +#else +#define _PyImport_InitFunc_TrampolineCall(func) (func)() +#endif + /* Max length of module suffix searched for -- accommodates "module.slb" */ #define MAXSUFFIXSIZE 12 diff --git a/Python/importlib.h b/Python/importlib.h new file mode 100644 index 00000000000..586f3b21f46 --- /dev/null +++ b/Python/importlib.h @@ -0,0 +1,1783 @@ +/* Auto-generated by Programs/_freeze_importlib.c */ +const unsigned char _Py_M__importlib_bootstrap[] = { + 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,64,0,0,0,115,194,1,0,0,100,0, + 90,0,100,1,97,1,100,2,100,3,132,0,90,2,100,4, + 100,5,132,0,90,3,105,0,90,4,105,0,90,5,71,0, + 100,6,100,7,132,0,100,7,101,6,131,3,90,7,71,0, + 100,8,100,9,132,0,100,9,131,2,90,8,71,0,100,10, + 100,11,132,0,100,11,131,2,90,9,71,0,100,12,100,13, + 132,0,100,13,131,2,90,10,100,14,100,15,132,0,90,11, + 100,16,100,17,132,0,90,12,100,18,100,19,132,0,90,13, + 100,20,100,21,156,1,100,22,100,23,132,2,90,14,100,24, + 100,25,132,0,90,15,100,26,100,27,132,0,90,16,100,28, + 100,29,132,0,90,17,100,30,100,31,132,0,90,18,71,0, + 100,32,100,33,132,0,100,33,131,2,90,19,100,1,100,1, + 100,34,156,2,100,35,100,36,132,2,90,20,100,94,100,37, + 100,38,132,1,90,21,100,39,100,40,156,1,100,41,100,42, + 132,2,90,22,100,43,100,44,132,0,90,23,100,45,100,46, + 132,0,90,24,100,47,100,48,132,0,90,25,100,49,100,50, + 132,0,90,26,100,51,100,52,132,0,90,27,100,53,100,54, + 132,0,90,28,71,0,100,55,100,56,132,0,100,56,131,2, + 90,29,71,0,100,57,100,58,132,0,100,58,131,2,90,30, + 71,0,100,59,100,60,132,0,100,60,131,2,90,31,100,61, + 100,62,132,0,90,32,100,63,100,64,132,0,90,33,100,95, + 100,65,100,66,132,1,90,34,100,67,100,68,132,0,90,35, + 100,69,90,36,101,36,100,70,23,0,90,37,100,71,100,72, + 132,0,90,38,101,39,131,0,90,40,100,73,100,74,132,0, + 90,41,100,96,100,76,100,77,132,1,90,42,100,39,100,78, + 156,1,100,79,100,80,132,2,90,43,100,81,100,82,132,0, + 90,44,100,97,100,84,100,85,132,1,90,45,100,86,100,87, + 132,0,90,46,100,88,100,89,132,0,90,47,100,90,100,91, + 132,0,90,48,100,92,100,93,132,0,90,49,100,1,83,0, + 41,98,97,83,1,0,0,67,111,114,101,32,105,109,112,108, + 101,109,101,110,116,97,116,105,111,110,32,111,102,32,105,109, + 112,111,114,116,46,10,10,84,104,105,115,32,109,111,100,117, + 108,101,32,105,115,32,78,79,84,32,109,101,97,110,116,32, + 116,111,32,98,101,32,100,105,114,101,99,116,108,121,32,105, + 109,112,111,114,116,101,100,33,32,73,116,32,104,97,115,32, + 98,101,101,110,32,100,101,115,105,103,110,101,100,32,115,117, + 99,104,10,116,104,97,116,32,105,116,32,99,97,110,32,98, + 101,32,98,111,111,116,115,116,114,97,112,112,101,100,32,105, + 110,116,111,32,80,121,116,104,111,110,32,97,115,32,116,104, + 101,32,105,109,112,108,101,109,101,110,116,97,116,105,111,110, + 32,111,102,32,105,109,112,111,114,116,46,32,65,115,10,115, + 117,99,104,32,105,116,32,114,101,113,117,105,114,101,115,32, + 116,104,101,32,105,110,106,101,99,116,105,111,110,32,111,102, + 32,115,112,101,99,105,102,105,99,32,109,111,100,117,108,101, + 115,32,97,110,100,32,97,116,116,114,105,98,117,116,101,115, + 32,105,110,32,111,114,100,101,114,32,116,111,10,119,111,114, + 107,46,32,79,110,101,32,115,104,111,117,108,100,32,117,115, + 101,32,105,109,112,111,114,116,108,105,98,32,97,115,32,116, + 104,101,32,112,117,98,108,105,99,45,102,97,99,105,110,103, + 32,118,101,114,115,105,111,110,32,111,102,32,116,104,105,115, + 32,109,111,100,117,108,101,46,10,10,78,99,2,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,7,0,0,0, + 67,0,0,0,115,56,0,0,0,100,1,68,0,93,32,125, + 2,116,0,124,1,124,2,131,2,114,4,116,1,124,0,124, + 2,116,2,124,1,124,2,131,2,131,3,1,0,113,4,124, + 0,106,3,160,4,124,1,106,3,161,1,1,0,100,2,83, + 0,41,3,122,47,83,105,109,112,108,101,32,115,117,98,115, + 116,105,116,117,116,101,32,102,111,114,32,102,117,110,99,116, + 111,111,108,115,46,117,112,100,97,116,101,95,119,114,97,112, + 112,101,114,46,41,4,218,10,95,95,109,111,100,117,108,101, + 95,95,218,8,95,95,110,97,109,101,95,95,218,12,95,95, + 113,117,97,108,110,97,109,101,95,95,218,7,95,95,100,111, + 99,95,95,78,41,5,218,7,104,97,115,97,116,116,114,218, + 7,115,101,116,97,116,116,114,218,7,103,101,116,97,116,116, + 114,218,8,95,95,100,105,99,116,95,95,218,6,117,112,100, + 97,116,101,41,3,90,3,110,101,119,90,3,111,108,100,218, + 7,114,101,112,108,97,99,101,169,0,114,10,0,0,0,250, + 29,60,102,114,111,122,101,110,32,105,109,112,111,114,116,108, + 105,98,46,95,98,111,111,116,115,116,114,97,112,62,218,5, + 95,119,114,97,112,27,0,0,0,115,8,0,0,0,0,2, + 8,1,10,1,20,1,114,12,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0, + 67,0,0,0,115,12,0,0,0,116,0,116,1,131,1,124, + 0,131,1,83,0,169,1,78,41,2,218,4,116,121,112,101, + 218,3,115,121,115,169,1,218,4,110,97,109,101,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,11,95,110, + 101,119,95,109,111,100,117,108,101,35,0,0,0,115,2,0, + 0,0,0,1,114,18,0,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,64,0, + 0,0,115,12,0,0,0,101,0,90,1,100,0,90,2,100, + 1,83,0,41,2,218,14,95,68,101,97,100,108,111,99,107, + 69,114,114,111,114,78,41,3,114,1,0,0,0,114,0,0, + 0,0,114,2,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,19,0,0,0, + 48,0,0,0,115,2,0,0,0,8,1,114,19,0,0,0, + 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,64,0,0,0,115,56,0,0,0,101,0, + 90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,0, + 90,4,100,4,100,5,132,0,90,5,100,6,100,7,132,0, + 90,6,100,8,100,9,132,0,90,7,100,10,100,11,132,0, + 90,8,100,12,83,0,41,13,218,11,95,77,111,100,117,108, + 101,76,111,99,107,122,169,65,32,114,101,99,117,114,115,105, + 118,101,32,108,111,99,107,32,105,109,112,108,101,109,101,110, + 116,97,116,105,111,110,32,119,104,105,99,104,32,105,115,32, + 97,98,108,101,32,116,111,32,100,101,116,101,99,116,32,100, + 101,97,100,108,111,99,107,115,10,32,32,32,32,40,101,46, + 103,46,32,116,104,114,101,97,100,32,49,32,116,114,121,105, + 110,103,32,116,111,32,116,97,107,101,32,108,111,99,107,115, + 32,65,32,116,104,101,110,32,66,44,32,97,110,100,32,116, + 104,114,101,97,100,32,50,32,116,114,121,105,110,103,32,116, + 111,10,32,32,32,32,116,97,107,101,32,108,111,99,107,115, + 32,66,32,116,104,101,110,32,65,41,46,10,32,32,32,32, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,2,0,0,0,67,0,0,0,115,48,0,0,0,116,0, + 160,1,161,0,124,0,95,2,116,0,160,1,161,0,124,0, + 95,3,124,1,124,0,95,4,100,0,124,0,95,5,100,1, + 124,0,95,6,100,1,124,0,95,7,100,0,83,0,169,2, + 78,233,0,0,0,0,41,8,218,7,95,116,104,114,101,97, + 100,90,13,97,108,108,111,99,97,116,101,95,108,111,99,107, + 218,4,108,111,99,107,218,6,119,97,107,101,117,112,114,17, + 0,0,0,218,5,111,119,110,101,114,218,5,99,111,117,110, + 116,218,7,119,97,105,116,101,114,115,169,2,218,4,115,101, + 108,102,114,17,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,218,8,95,95,105,110,105,116,95,95, + 58,0,0,0,115,12,0,0,0,0,1,10,1,10,1,6, + 1,6,1,6,1,122,20,95,77,111,100,117,108,101,76,111, + 99,107,46,95,95,105,110,105,116,95,95,99,1,0,0,0, + 0,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0, + 67,0,0,0,115,60,0,0,0,116,0,160,1,161,0,125, + 1,124,0,106,2,125,2,116,3,160,4,124,2,161,1,125, + 3,124,3,100,0,107,8,114,36,100,1,83,0,124,3,106, + 2,125,2,124,2,124,1,107,2,114,14,100,2,83,0,113, + 14,100,0,83,0,41,3,78,70,84,41,5,114,23,0,0, + 0,218,9,103,101,116,95,105,100,101,110,116,114,26,0,0, + 0,218,12,95,98,108,111,99,107,105,110,103,95,111,110,218, + 3,103,101,116,41,4,114,30,0,0,0,90,2,109,101,218, + 3,116,105,100,114,24,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,12,104,97,115,95,100,101, + 97,100,108,111,99,107,66,0,0,0,115,16,0,0,0,0, + 2,8,1,6,2,10,1,8,1,4,1,6,1,8,1,122, + 24,95,77,111,100,117,108,101,76,111,99,107,46,104,97,115, + 95,100,101,97,100,108,111,99,107,99,1,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,9,0,0,0,67,0, + 0,0,115,178,0,0,0,116,0,160,1,161,0,125,1,124, + 0,116,2,124,1,60,0,122,148,124,0,106,3,143,110,1, + 0,124,0,106,4,100,1,107,2,115,46,124,0,106,5,124, + 1,107,2,114,84,124,1,124,0,95,5,124,0,4,0,106, + 4,100,2,55,0,2,0,95,4,87,0,53,0,81,0,82, + 0,163,0,87,0,162,86,100,3,83,0,124,0,160,6,161, + 0,114,104,116,7,100,4,124,0,22,0,131,1,130,1,124, + 0,106,8,160,9,100,5,161,1,114,130,124,0,4,0,106, + 10,100,2,55,0,2,0,95,10,87,0,53,0,81,0,82, + 0,88,0,124,0,106,8,160,9,161,0,1,0,124,0,106, + 8,160,11,161,0,1,0,113,18,87,0,53,0,116,2,124, + 1,61,0,88,0,100,6,83,0,41,7,122,185,10,32,32, + 32,32,32,32,32,32,65,99,113,117,105,114,101,32,116,104, + 101,32,109,111,100,117,108,101,32,108,111,99,107,46,32,32, + 73,102,32,97,32,112,111,116,101,110,116,105,97,108,32,100, + 101,97,100,108,111,99,107,32,105,115,32,100,101,116,101,99, + 116,101,100,44,10,32,32,32,32,32,32,32,32,97,32,95, + 68,101,97,100,108,111,99,107,69,114,114,111,114,32,105,115, + 32,114,97,105,115,101,100,46,10,32,32,32,32,32,32,32, + 32,79,116,104,101,114,119,105,115,101,44,32,116,104,101,32, + 108,111,99,107,32,105,115,32,97,108,119,97,121,115,32,97, + 99,113,117,105,114,101,100,32,97,110,100,32,84,114,117,101, + 32,105,115,32,114,101,116,117,114,110,101,100,46,10,32,32, + 32,32,32,32,32,32,114,22,0,0,0,233,1,0,0,0, + 84,122,23,100,101,97,100,108,111,99,107,32,100,101,116,101, + 99,116,101,100,32,98,121,32,37,114,70,78,41,12,114,23, + 0,0,0,114,32,0,0,0,114,33,0,0,0,114,24,0, + 0,0,114,27,0,0,0,114,26,0,0,0,114,36,0,0, + 0,114,19,0,0,0,114,25,0,0,0,218,7,97,99,113, + 117,105,114,101,114,28,0,0,0,218,7,114,101,108,101,97, + 115,101,169,2,114,30,0,0,0,114,35,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,38,0, + 0,0,78,0,0,0,115,30,0,0,0,0,6,8,1,8, + 1,2,2,8,1,20,1,6,1,14,1,18,1,8,1,12, + 1,12,1,24,2,10,1,16,2,122,19,95,77,111,100,117, + 108,101,76,111,99,107,46,97,99,113,117,105,114,101,99,1, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,9, + 0,0,0,67,0,0,0,115,122,0,0,0,116,0,160,1, + 161,0,125,1,124,0,106,2,143,98,1,0,124,0,106,3, + 124,1,107,3,114,34,116,4,100,1,131,1,130,1,124,0, + 106,5,100,2,107,4,115,48,74,0,130,1,124,0,4,0, + 106,5,100,3,56,0,2,0,95,5,124,0,106,5,100,2, + 107,2,114,108,100,0,124,0,95,3,124,0,106,6,114,108, + 124,0,4,0,106,6,100,3,56,0,2,0,95,6,124,0, + 106,7,160,8,161,0,1,0,87,0,53,0,81,0,82,0, + 88,0,100,0,83,0,41,4,78,250,31,99,97,110,110,111, + 116,32,114,101,108,101,97,115,101,32,117,110,45,97,99,113, + 117,105,114,101,100,32,108,111,99,107,114,22,0,0,0,114, + 37,0,0,0,41,9,114,23,0,0,0,114,32,0,0,0, + 114,24,0,0,0,114,26,0,0,0,218,12,82,117,110,116, + 105,109,101,69,114,114,111,114,114,27,0,0,0,114,28,0, + 0,0,114,25,0,0,0,114,39,0,0,0,114,40,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,39,0,0,0,103,0,0,0,115,22,0,0,0,0,1, + 8,1,8,1,10,1,8,1,14,1,14,1,10,1,6,1, + 6,1,14,1,122,19,95,77,111,100,117,108,101,76,111,99, + 107,46,114,101,108,101,97,115,101,99,1,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,5,0,0,0,67,0, + 0,0,115,22,0,0,0,100,1,124,0,106,0,155,2,100, + 2,116,1,124,0,131,1,155,0,157,4,83,0,41,3,78, + 122,12,95,77,111,100,117,108,101,76,111,99,107,40,250,5, + 41,32,97,116,32,169,2,114,17,0,0,0,218,2,105,100, + 169,1,114,30,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,218,8,95,95,114,101,112,114,95,95, + 116,0,0,0,115,2,0,0,0,0,1,122,20,95,77,111, + 100,117,108,101,76,111,99,107,46,95,95,114,101,112,114,95, + 95,78,41,9,114,1,0,0,0,114,0,0,0,0,114,2, + 0,0,0,114,3,0,0,0,114,31,0,0,0,114,36,0, + 0,0,114,38,0,0,0,114,39,0,0,0,114,47,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,20,0,0,0,52,0,0,0,115,12, + 0,0,0,8,1,4,5,8,8,8,12,8,25,8,13,114, + 20,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,64,0,0,0,115,48,0, + 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, + 100,3,132,0,90,4,100,4,100,5,132,0,90,5,100,6, + 100,7,132,0,90,6,100,8,100,9,132,0,90,7,100,10, + 83,0,41,11,218,16,95,68,117,109,109,121,77,111,100,117, + 108,101,76,111,99,107,122,86,65,32,115,105,109,112,108,101, + 32,95,77,111,100,117,108,101,76,111,99,107,32,101,113,117, + 105,118,97,108,101,110,116,32,102,111,114,32,80,121,116,104, + 111,110,32,98,117,105,108,100,115,32,119,105,116,104,111,117, + 116,10,32,32,32,32,109,117,108,116,105,45,116,104,114,101, + 97,100,105,110,103,32,115,117,112,112,111,114,116,46,99,2, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2, + 0,0,0,67,0,0,0,115,16,0,0,0,124,1,124,0, + 95,0,100,1,124,0,95,1,100,0,83,0,114,21,0,0, + 0,41,2,114,17,0,0,0,114,27,0,0,0,114,29,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,31,0,0,0,124,0,0,0,115,4,0,0,0,0, + 1,6,1,122,25,95,68,117,109,109,121,77,111,100,117,108, + 101,76,111,99,107,46,95,95,105,110,105,116,95,95,99,1, + 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3, + 0,0,0,67,0,0,0,115,18,0,0,0,124,0,4,0, + 106,0,100,1,55,0,2,0,95,0,100,2,83,0,41,3, + 78,114,37,0,0,0,84,41,1,114,27,0,0,0,114,46, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,38,0,0,0,128,0,0,0,115,4,0,0,0, + 0,1,14,1,122,24,95,68,117,109,109,121,77,111,100,117, + 108,101,76,111,99,107,46,97,99,113,117,105,114,101,99,1, + 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3, + 0,0,0,67,0,0,0,115,36,0,0,0,124,0,106,0, + 100,1,107,2,114,18,116,1,100,2,131,1,130,1,124,0, + 4,0,106,0,100,3,56,0,2,0,95,0,100,0,83,0, + 41,4,78,114,22,0,0,0,114,41,0,0,0,114,37,0, + 0,0,41,2,114,27,0,0,0,114,42,0,0,0,114,46, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,39,0,0,0,132,0,0,0,115,6,0,0,0, + 0,1,10,1,8,1,122,24,95,68,117,109,109,121,77,111, + 100,117,108,101,76,111,99,107,46,114,101,108,101,97,115,101, + 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, + 0,5,0,0,0,67,0,0,0,115,22,0,0,0,100,1, + 124,0,106,0,155,2,100,2,116,1,124,0,131,1,155,0, + 157,4,83,0,41,3,78,122,17,95,68,117,109,109,121,77, + 111,100,117,108,101,76,111,99,107,40,114,43,0,0,0,114, + 44,0,0,0,114,46,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,47,0,0,0,137,0,0, + 0,115,2,0,0,0,0,1,122,25,95,68,117,109,109,121, + 77,111,100,117,108,101,76,111,99,107,46,95,95,114,101,112, + 114,95,95,78,41,8,114,1,0,0,0,114,0,0,0,0, + 114,2,0,0,0,114,3,0,0,0,114,31,0,0,0,114, + 38,0,0,0,114,39,0,0,0,114,47,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,48,0,0,0,120,0,0,0,115,10,0,0,0, + 8,1,4,3,8,4,8,4,8,5,114,48,0,0,0,99, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,64,0,0,0,115,36,0,0,0,101,0,90, + 1,100,0,90,2,100,1,100,2,132,0,90,3,100,3,100, + 4,132,0,90,4,100,5,100,6,132,0,90,5,100,7,83, + 0,41,8,218,18,95,77,111,100,117,108,101,76,111,99,107, + 77,97,110,97,103,101,114,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,0, + 115,16,0,0,0,124,1,124,0,95,0,100,0,124,0,95, + 1,100,0,83,0,114,13,0,0,0,41,2,218,5,95,110, + 97,109,101,218,5,95,108,111,99,107,114,29,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,31, + 0,0,0,143,0,0,0,115,4,0,0,0,0,1,6,1, + 122,27,95,77,111,100,117,108,101,76,111,99,107,77,97,110, + 97,103,101,114,46,95,95,105,110,105,116,95,95,99,1,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0, + 0,0,67,0,0,0,115,26,0,0,0,116,0,124,0,106, + 1,131,1,124,0,95,2,124,0,106,2,160,3,161,0,1, + 0,100,0,83,0,114,13,0,0,0,41,4,218,16,95,103, + 101,116,95,109,111,100,117,108,101,95,108,111,99,107,114,50, + 0,0,0,114,51,0,0,0,114,38,0,0,0,114,46,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,218,9,95,95,101,110,116,101,114,95,95,147,0,0,0, + 115,4,0,0,0,0,1,12,1,122,28,95,77,111,100,117, + 108,101,76,111,99,107,77,97,110,97,103,101,114,46,95,95, + 101,110,116,101,114,95,95,99,1,0,0,0,0,0,0,0, + 0,0,0,0,3,0,0,0,2,0,0,0,79,0,0,0, + 115,14,0,0,0,124,0,106,0,160,1,161,0,1,0,100, + 0,83,0,114,13,0,0,0,41,2,114,51,0,0,0,114, + 39,0,0,0,41,3,114,30,0,0,0,218,4,97,114,103, + 115,90,6,107,119,97,114,103,115,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,8,95,95,101,120,105,116, + 95,95,151,0,0,0,115,2,0,0,0,0,1,122,27,95, + 77,111,100,117,108,101,76,111,99,107,77,97,110,97,103,101, + 114,46,95,95,101,120,105,116,95,95,78,41,6,114,1,0, + 0,0,114,0,0,0,0,114,2,0,0,0,114,31,0,0, + 0,114,53,0,0,0,114,55,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 49,0,0,0,141,0,0,0,115,6,0,0,0,8,2,8, + 4,8,4,114,49,0,0,0,99,1,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,8,0,0,0,67,0,0, + 0,115,130,0,0,0,116,0,160,1,161,0,1,0,122,106, + 122,14,116,3,124,0,25,0,131,0,125,1,87,0,110,24, + 4,0,116,4,107,10,114,48,1,0,1,0,1,0,100,1, + 125,1,89,0,110,2,88,0,124,1,100,1,107,8,114,112, + 116,5,100,1,107,8,114,76,116,6,124,0,131,1,125,1, + 110,8,116,7,124,0,131,1,125,1,124,0,102,1,100,2, + 100,3,132,1,125,2,116,8,160,9,124,1,124,2,161,2, + 116,3,124,0,60,0,87,0,53,0,116,0,160,2,161,0, + 1,0,88,0,124,1,83,0,41,4,122,139,71,101,116,32, + 111,114,32,99,114,101,97,116,101,32,116,104,101,32,109,111, + 100,117,108,101,32,108,111,99,107,32,102,111,114,32,97,32, + 103,105,118,101,110,32,109,111,100,117,108,101,32,110,97,109, + 101,46,10,10,32,32,32,32,65,99,113,117,105,114,101,47, + 114,101,108,101,97,115,101,32,105,110,116,101,114,110,97,108, + 108,121,32,116,104,101,32,103,108,111,98,97,108,32,105,109, + 112,111,114,116,32,108,111,99,107,32,116,111,32,112,114,111, + 116,101,99,116,10,32,32,32,32,95,109,111,100,117,108,101, + 95,108,111,99,107,115,46,78,99,2,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,8,0,0,0,83,0,0, + 0,115,48,0,0,0,116,0,160,1,161,0,1,0,122,24, + 116,3,160,4,124,1,161,1,124,0,107,8,114,30,116,3, + 124,1,61,0,87,0,53,0,116,0,160,2,161,0,1,0, + 88,0,100,0,83,0,114,13,0,0,0,41,5,218,4,95, + 105,109,112,218,12,97,99,113,117,105,114,101,95,108,111,99, + 107,218,12,114,101,108,101,97,115,101,95,108,111,99,107,218, + 13,95,109,111,100,117,108,101,95,108,111,99,107,115,114,34, + 0,0,0,41,2,218,3,114,101,102,114,17,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,2, + 99,98,176,0,0,0,115,10,0,0,0,0,1,8,1,2, + 4,14,1,10,2,122,28,95,103,101,116,95,109,111,100,117, + 108,101,95,108,111,99,107,46,60,108,111,99,97,108,115,62, + 46,99,98,41,10,114,56,0,0,0,114,57,0,0,0,114, + 58,0,0,0,114,59,0,0,0,218,8,75,101,121,69,114, + 114,111,114,114,23,0,0,0,114,48,0,0,0,114,20,0, + 0,0,218,8,95,119,101,97,107,114,101,102,114,60,0,0, + 0,41,3,114,17,0,0,0,114,24,0,0,0,114,61,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,52,0,0,0,157,0,0,0,115,28,0,0,0,0, + 6,8,1,2,1,2,1,14,1,14,1,10,2,8,1,8, + 1,10,2,8,2,12,11,20,2,10,2,114,52,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,8,0,0,0,67,0,0,0,115,54,0,0,0,116,0, + 124,0,131,1,125,1,122,12,124,1,160,1,161,0,1,0, + 87,0,110,20,4,0,116,2,107,10,114,40,1,0,1,0, + 1,0,89,0,110,10,88,0,124,1,160,3,161,0,1,0, + 100,1,83,0,41,2,122,189,65,99,113,117,105,114,101,115, + 32,116,104,101,110,32,114,101,108,101,97,115,101,115,32,116, + 104,101,32,109,111,100,117,108,101,32,108,111,99,107,32,102, + 111,114,32,97,32,103,105,118,101,110,32,109,111,100,117,108, + 101,32,110,97,109,101,46,10,10,32,32,32,32,84,104,105, + 115,32,105,115,32,117,115,101,100,32,116,111,32,101,110,115, + 117,114,101,32,97,32,109,111,100,117,108,101,32,105,115,32, + 99,111,109,112,108,101,116,101,108,121,32,105,110,105,116,105, + 97,108,105,122,101,100,44,32,105,110,32,116,104,101,10,32, + 32,32,32,101,118,101,110,116,32,105,116,32,105,115,32,98, + 101,105,110,103,32,105,109,112,111,114,116,101,100,32,98,121, + 32,97,110,111,116,104,101,114,32,116,104,114,101,97,100,46, + 10,32,32,32,32,78,41,4,114,52,0,0,0,114,38,0, + 0,0,114,19,0,0,0,114,39,0,0,0,41,2,114,17, + 0,0,0,114,24,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,19,95,108,111,99,107,95,117, + 110,108,111,99,107,95,109,111,100,117,108,101,194,0,0,0, + 115,12,0,0,0,0,6,8,1,2,1,12,1,14,3,6, + 2,114,64,0,0,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,3,0,0,0,79,0,0,0,115, + 10,0,0,0,124,0,124,1,124,2,142,1,83,0,41,1, + 97,46,1,0,0,114,101,109,111,118,101,95,105,109,112,111, + 114,116,108,105,98,95,102,114,97,109,101,115,32,105,110,32, + 105,109,112,111,114,116,46,99,32,119,105,108,108,32,97,108, + 119,97,121,115,32,114,101,109,111,118,101,32,115,101,113,117, + 101,110,99,101,115,10,32,32,32,32,111,102,32,105,109,112, + 111,114,116,108,105,98,32,102,114,97,109,101,115,32,116,104, + 97,116,32,101,110,100,32,119,105,116,104,32,97,32,99,97, + 108,108,32,116,111,32,116,104,105,115,32,102,117,110,99,116, + 105,111,110,10,10,32,32,32,32,85,115,101,32,105,116,32, + 105,110,115,116,101,97,100,32,111,102,32,97,32,110,111,114, + 109,97,108,32,99,97,108,108,32,105,110,32,112,108,97,99, + 101,115,32,119,104,101,114,101,32,105,110,99,108,117,100,105, + 110,103,32,116,104,101,32,105,109,112,111,114,116,108,105,98, + 10,32,32,32,32,102,114,97,109,101,115,32,105,110,116,114, + 111,100,117,99,101,115,32,117,110,119,97,110,116,101,100,32, + 110,111,105,115,101,32,105,110,116,111,32,116,104,101,32,116, + 114,97,99,101,98,97,99,107,32,40,101,46,103,46,32,119, + 104,101,110,32,101,120,101,99,117,116,105,110,103,10,32,32, + 32,32,109,111,100,117,108,101,32,99,111,100,101,41,10,32, + 32,32,32,114,10,0,0,0,41,3,218,1,102,114,54,0, + 0,0,90,4,107,119,100,115,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,25,95,99,97,108,108,95,119, + 105,116,104,95,102,114,97,109,101,115,95,114,101,109,111,118, + 101,100,211,0,0,0,115,2,0,0,0,0,8,114,66,0, + 0,0,114,37,0,0,0,41,1,218,9,118,101,114,98,111, + 115,105,116,121,99,1,0,0,0,0,0,0,0,1,0,0, + 0,3,0,0,0,4,0,0,0,71,0,0,0,115,54,0, + 0,0,116,0,106,1,106,2,124,1,107,5,114,50,124,0, + 160,3,100,1,161,1,115,30,100,2,124,0,23,0,125,0, + 116,4,124,0,106,5,124,2,142,0,116,0,106,6,100,3, + 141,2,1,0,100,4,83,0,41,5,122,61,80,114,105,110, + 116,32,116,104,101,32,109,101,115,115,97,103,101,32,116,111, + 32,115,116,100,101,114,114,32,105,102,32,45,118,47,80,89, + 84,72,79,78,86,69,82,66,79,83,69,32,105,115,32,116, + 117,114,110,101,100,32,111,110,46,41,2,250,1,35,122,7, + 105,109,112,111,114,116,32,122,2,35,32,41,1,90,4,102, + 105,108,101,78,41,7,114,15,0,0,0,218,5,102,108,97, + 103,115,218,7,118,101,114,98,111,115,101,218,10,115,116,97, + 114,116,115,119,105,116,104,218,5,112,114,105,110,116,218,6, + 102,111,114,109,97,116,218,6,115,116,100,101,114,114,41,3, + 218,7,109,101,115,115,97,103,101,114,67,0,0,0,114,54, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,16,95,118,101,114,98,111,115,101,95,109,101,115, + 115,97,103,101,222,0,0,0,115,8,0,0,0,0,2,12, + 1,10,1,8,1,114,76,0,0,0,99,1,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,3, + 0,0,0,115,26,0,0,0,135,0,102,1,100,1,100,2, + 132,8,125,1,116,0,124,1,136,0,131,2,1,0,124,1, + 83,0,41,3,122,49,68,101,99,111,114,97,116,111,114,32, + 116,111,32,118,101,114,105,102,121,32,116,104,101,32,110,97, + 109,101,100,32,109,111,100,117,108,101,32,105,115,32,98,117, + 105,108,116,45,105,110,46,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,4,0,0,0,19,0,0,0, + 115,38,0,0,0,124,1,116,0,106,1,107,7,114,28,116, + 2,124,1,155,2,100,1,157,2,124,1,100,2,141,2,130, + 1,136,0,124,0,124,1,131,2,83,0,41,3,78,250,25, + 32,105,115,32,110,111,116,32,97,32,98,117,105,108,116,45, + 105,110,32,109,111,100,117,108,101,114,16,0,0,0,41,3, + 114,15,0,0,0,218,20,98,117,105,108,116,105,110,95,109, + 111,100,117,108,101,95,110,97,109,101,115,218,11,73,109,112, + 111,114,116,69,114,114,111,114,169,2,114,30,0,0,0,218, + 8,102,117,108,108,110,97,109,101,169,1,218,3,102,120,110, + 114,10,0,0,0,114,11,0,0,0,218,25,95,114,101,113, + 117,105,114,101,115,95,98,117,105,108,116,105,110,95,119,114, + 97,112,112,101,114,232,0,0,0,115,10,0,0,0,0,1, + 10,1,10,1,2,255,6,2,122,52,95,114,101,113,117,105, + 114,101,115,95,98,117,105,108,116,105,110,46,60,108,111,99, + 97,108,115,62,46,95,114,101,113,117,105,114,101,115,95,98, + 117,105,108,116,105,110,95,119,114,97,112,112,101,114,169,1, + 114,12,0,0,0,41,2,114,83,0,0,0,114,84,0,0, + 0,114,10,0,0,0,114,82,0,0,0,114,11,0,0,0, + 218,17,95,114,101,113,117,105,114,101,115,95,98,117,105,108, + 116,105,110,230,0,0,0,115,6,0,0,0,0,2,12,5, + 10,1,114,86,0,0,0,99,1,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,3,0,0,0,3,0,0,0, + 115,26,0,0,0,135,0,102,1,100,1,100,2,132,8,125, + 1,116,0,124,1,136,0,131,2,1,0,124,1,83,0,41, + 3,122,47,68,101,99,111,114,97,116,111,114,32,116,111,32, + 118,101,114,105,102,121,32,116,104,101,32,110,97,109,101,100, + 32,109,111,100,117,108,101,32,105,115,32,102,114,111,122,101, + 110,46,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,4,0,0,0,19,0,0,0,115,38,0,0,0, + 116,0,160,1,124,1,161,1,115,28,116,2,124,1,155,2, + 100,1,157,2,124,1,100,2,141,2,130,1,136,0,124,0, + 124,1,131,2,83,0,169,3,78,122,23,32,105,115,32,110, + 111,116,32,97,32,102,114,111,122,101,110,32,109,111,100,117, + 108,101,114,16,0,0,0,41,3,114,56,0,0,0,218,9, + 105,115,95,102,114,111,122,101,110,114,79,0,0,0,114,80, + 0,0,0,114,82,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,24,95,114,101,113,117,105,114,101,115,95,102,114, + 111,122,101,110,95,119,114,97,112,112,101,114,243,0,0,0, + 115,10,0,0,0,0,1,10,1,10,1,2,255,6,2,122, + 50,95,114,101,113,117,105,114,101,115,95,102,114,111,122,101, + 110,46,60,108,111,99,97,108,115,62,46,95,114,101,113,117, + 105,114,101,115,95,102,114,111,122,101,110,95,119,114,97,112, + 112,101,114,114,85,0,0,0,41,2,114,83,0,0,0,114, + 89,0,0,0,114,10,0,0,0,114,82,0,0,0,114,11, + 0,0,0,218,16,95,114,101,113,117,105,114,101,115,95,102, + 114,111,122,101,110,241,0,0,0,115,6,0,0,0,0,2, + 12,5,10,1,114,90,0,0,0,99,2,0,0,0,0,0, + 0,0,0,0,0,0,4,0,0,0,3,0,0,0,67,0, + 0,0,115,62,0,0,0,116,0,124,1,124,0,131,2,125, + 2,124,1,116,1,106,2,107,6,114,50,116,1,106,2,124, + 1,25,0,125,3,116,3,124,2,124,3,131,2,1,0,116, + 1,106,2,124,1,25,0,83,0,116,4,124,2,131,1,83, + 0,100,1,83,0,41,2,122,128,76,111,97,100,32,116,104, + 101,32,115,112,101,99,105,102,105,101,100,32,109,111,100,117, + 108,101,32,105,110,116,111,32,115,121,115,46,109,111,100,117, + 108,101,115,32,97,110,100,32,114,101,116,117,114,110,32,105, + 116,46,10,10,32,32,32,32,84,104,105,115,32,109,101,116, + 104,111,100,32,105,115,32,100,101,112,114,101,99,97,116,101, + 100,46,32,32,85,115,101,32,108,111,97,100,101,114,46,101, + 120,101,99,95,109,111,100,117,108,101,32,105,110,115,116,101, + 97,100,46,10,10,32,32,32,32,78,41,5,218,16,115,112, + 101,99,95,102,114,111,109,95,108,111,97,100,101,114,114,15, + 0,0,0,218,7,109,111,100,117,108,101,115,218,5,95,101, + 120,101,99,218,5,95,108,111,97,100,41,4,114,30,0,0, + 0,114,81,0,0,0,218,4,115,112,101,99,218,6,109,111, + 100,117,108,101,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,218,17,95,108,111,97,100,95,109,111,100,117,108, + 101,95,115,104,105,109,253,0,0,0,115,12,0,0,0,0, + 6,10,1,10,1,10,1,10,1,10,2,114,97,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,5,0,0, + 0,8,0,0,0,67,0,0,0,115,240,0,0,0,116,0, + 124,0,100,1,100,0,131,3,125,1,116,1,124,1,100,2, + 131,2,114,56,122,12,124,1,160,2,124,0,161,1,87,0, + 83,0,4,0,116,3,107,10,114,54,1,0,1,0,1,0, + 89,0,110,2,88,0,122,10,124,0,106,4,125,2,87,0, + 110,20,4,0,116,5,107,10,114,86,1,0,1,0,1,0, + 89,0,110,18,88,0,124,2,100,0,107,9,114,104,116,6, + 124,2,131,1,83,0,122,10,124,0,106,7,125,3,87,0, + 110,24,4,0,116,5,107,10,114,138,1,0,1,0,1,0, + 100,3,125,3,89,0,110,2,88,0,122,10,124,0,106,8, + 125,4,87,0,110,66,4,0,116,5,107,10,114,216,1,0, + 1,0,1,0,124,1,100,0,107,8,114,190,100,4,124,3, + 155,2,100,5,157,3,6,0,89,0,83,0,100,4,124,3, + 155,2,100,6,124,1,155,2,100,7,157,5,6,0,89,0, + 83,0,89,0,110,20,88,0,100,4,124,3,155,2,100,8, + 124,4,155,2,100,5,157,5,83,0,100,0,83,0,41,9, + 78,218,10,95,95,108,111,97,100,101,114,95,95,218,11,109, + 111,100,117,108,101,95,114,101,112,114,250,1,63,250,8,60, + 109,111,100,117,108,101,32,250,1,62,250,2,32,40,250,2, + 41,62,250,6,32,102,114,111,109,32,41,9,114,6,0,0, + 0,114,4,0,0,0,114,99,0,0,0,218,9,69,120,99, + 101,112,116,105,111,110,218,8,95,95,115,112,101,99,95,95, + 218,14,65,116,116,114,105,98,117,116,101,69,114,114,111,114, + 218,22,95,109,111,100,117,108,101,95,114,101,112,114,95,102, + 114,111,109,95,115,112,101,99,114,1,0,0,0,218,8,95, + 95,102,105,108,101,95,95,41,5,114,96,0,0,0,218,6, + 108,111,97,100,101,114,114,95,0,0,0,114,17,0,0,0, + 218,8,102,105,108,101,110,97,109,101,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,218,12,95,109,111,100,117, + 108,101,95,114,101,112,114,13,1,0,0,115,46,0,0,0, + 0,2,12,1,10,4,2,1,12,1,14,1,6,1,2,1, + 10,1,14,1,6,2,8,1,8,4,2,1,10,1,14,1, + 10,1,2,1,10,1,14,1,8,1,16,2,28,2,114,113, + 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,4,0,0,0,64,0,0,0,115,114,0,0, + 0,101,0,90,1,100,0,90,2,100,1,90,3,100,2,100, + 2,100,2,100,3,156,3,100,4,100,5,132,2,90,4,100, + 6,100,7,132,0,90,5,100,8,100,9,132,0,90,6,101, + 7,100,10,100,11,132,0,131,1,90,8,101,8,106,9,100, + 12,100,11,132,0,131,1,90,8,101,7,100,13,100,14,132, + 0,131,1,90,10,101,7,100,15,100,16,132,0,131,1,90, + 11,101,11,106,9,100,17,100,16,132,0,131,1,90,11,100, + 2,83,0,41,18,218,10,77,111,100,117,108,101,83,112,101, + 99,97,208,5,0,0,84,104,101,32,115,112,101,99,105,102, + 105,99,97,116,105,111,110,32,102,111,114,32,97,32,109,111, + 100,117,108,101,44,32,117,115,101,100,32,102,111,114,32,108, + 111,97,100,105,110,103,46,10,10,32,32,32,32,65,32,109, + 111,100,117,108,101,39,115,32,115,112,101,99,32,105,115,32, + 116,104,101,32,115,111,117,114,99,101,32,102,111,114,32,105, + 110,102,111,114,109,97,116,105,111,110,32,97,98,111,117,116, + 32,116,104,101,32,109,111,100,117,108,101,46,32,32,70,111, + 114,10,32,32,32,32,100,97,116,97,32,97,115,115,111,99, + 105,97,116,101,100,32,119,105,116,104,32,116,104,101,32,109, + 111,100,117,108,101,44,32,105,110,99,108,117,100,105,110,103, + 32,115,111,117,114,99,101,44,32,117,115,101,32,116,104,101, + 32,115,112,101,99,39,115,10,32,32,32,32,108,111,97,100, + 101,114,46,10,10,32,32,32,32,96,110,97,109,101,96,32, + 105,115,32,116,104,101,32,97,98,115,111,108,117,116,101,32, + 110,97,109,101,32,111,102,32,116,104,101,32,109,111,100,117, + 108,101,46,32,32,96,108,111,97,100,101,114,96,32,105,115, + 32,116,104,101,32,108,111,97,100,101,114,10,32,32,32,32, + 116,111,32,117,115,101,32,119,104,101,110,32,108,111,97,100, + 105,110,103,32,116,104,101,32,109,111,100,117,108,101,46,32, + 32,96,112,97,114,101,110,116,96,32,105,115,32,116,104,101, + 32,110,97,109,101,32,111,102,32,116,104,101,10,32,32,32, + 32,112,97,99,107,97,103,101,32,116,104,101,32,109,111,100, + 117,108,101,32,105,115,32,105,110,46,32,32,84,104,101,32, + 112,97,114,101,110,116,32,105,115,32,100,101,114,105,118,101, + 100,32,102,114,111,109,32,116,104,101,32,110,97,109,101,46, + 10,10,32,32,32,32,96,105,115,95,112,97,99,107,97,103, + 101,96,32,100,101,116,101,114,109,105,110,101,115,32,105,102, + 32,116,104,101,32,109,111,100,117,108,101,32,105,115,32,99, + 111,110,115,105,100,101,114,101,100,32,97,32,112,97,99,107, + 97,103,101,32,111,114,10,32,32,32,32,110,111,116,46,32, + 32,79,110,32,109,111,100,117,108,101,115,32,116,104,105,115, + 32,105,115,32,114,101,102,108,101,99,116,101,100,32,98,121, + 32,116,104,101,32,96,95,95,112,97,116,104,95,95,96,32, + 97,116,116,114,105,98,117,116,101,46,10,10,32,32,32,32, + 96,111,114,105,103,105,110,96,32,105,115,32,116,104,101,32, + 115,112,101,99,105,102,105,99,32,108,111,99,97,116,105,111, + 110,32,117,115,101,100,32,98,121,32,116,104,101,32,108,111, + 97,100,101,114,32,102,114,111,109,32,119,104,105,99,104,32, + 116,111,10,32,32,32,32,108,111,97,100,32,116,104,101,32, + 109,111,100,117,108,101,44,32,105,102,32,116,104,97,116,32, + 105,110,102,111,114,109,97,116,105,111,110,32,105,115,32,97, + 118,97,105,108,97,98,108,101,46,32,32,87,104,101,110,32, + 102,105,108,101,110,97,109,101,32,105,115,10,32,32,32,32, + 115,101,116,44,32,111,114,105,103,105,110,32,119,105,108,108, + 32,109,97,116,99,104,46,10,10,32,32,32,32,96,104,97, + 115,95,108,111,99,97,116,105,111,110,96,32,105,110,100,105, + 99,97,116,101,115,32,116,104,97,116,32,97,32,115,112,101, + 99,39,115,32,34,111,114,105,103,105,110,34,32,114,101,102, + 108,101,99,116,115,32,97,32,108,111,99,97,116,105,111,110, + 46,10,32,32,32,32,87,104,101,110,32,116,104,105,115,32, + 105,115,32,84,114,117,101,44,32,96,95,95,102,105,108,101, + 95,95,96,32,97,116,116,114,105,98,117,116,101,32,111,102, + 32,116,104,101,32,109,111,100,117,108,101,32,105,115,32,115, + 101,116,46,10,10,32,32,32,32,96,99,97,99,104,101,100, + 96,32,105,115,32,116,104,101,32,108,111,99,97,116,105,111, + 110,32,111,102,32,116,104,101,32,99,97,99,104,101,100,32, + 98,121,116,101,99,111,100,101,32,102,105,108,101,44,32,105, + 102,32,97,110,121,46,32,32,73,116,10,32,32,32,32,99, + 111,114,114,101,115,112,111,110,100,115,32,116,111,32,116,104, + 101,32,96,95,95,99,97,99,104,101,100,95,95,96,32,97, + 116,116,114,105,98,117,116,101,46,10,10,32,32,32,32,96, + 115,117,98,109,111,100,117,108,101,95,115,101,97,114,99,104, + 95,108,111,99,97,116,105,111,110,115,96,32,105,115,32,116, + 104,101,32,115,101,113,117,101,110,99,101,32,111,102,32,112, + 97,116,104,32,101,110,116,114,105,101,115,32,116,111,10,32, + 32,32,32,115,101,97,114,99,104,32,119,104,101,110,32,105, + 109,112,111,114,116,105,110,103,32,115,117,98,109,111,100,117, + 108,101,115,46,32,32,73,102,32,115,101,116,44,32,105,115, + 95,112,97,99,107,97,103,101,32,115,104,111,117,108,100,32, + 98,101,10,32,32,32,32,84,114,117,101,45,45,97,110,100, + 32,70,97,108,115,101,32,111,116,104,101,114,119,105,115,101, + 46,10,10,32,32,32,32,80,97,99,107,97,103,101,115,32, + 97,114,101,32,115,105,109,112,108,121,32,109,111,100,117,108, + 101,115,32,116,104,97,116,32,40,109,97,121,41,32,104,97, + 118,101,32,115,117,98,109,111,100,117,108,101,115,46,32,32, + 73,102,32,97,32,115,112,101,99,10,32,32,32,32,104,97, + 115,32,97,32,110,111,110,45,78,111,110,101,32,118,97,108, + 117,101,32,105,110,32,96,115,117,98,109,111,100,117,108,101, + 95,115,101,97,114,99,104,95,108,111,99,97,116,105,111,110, + 115,96,44,32,116,104,101,32,105,109,112,111,114,116,10,32, + 32,32,32,115,121,115,116,101,109,32,119,105,108,108,32,99, + 111,110,115,105,100,101,114,32,109,111,100,117,108,101,115,32, + 108,111,97,100,101,100,32,102,114,111,109,32,116,104,101,32, + 115,112,101,99,32,97,115,32,112,97,99,107,97,103,101,115, + 46,10,10,32,32,32,32,79,110,108,121,32,102,105,110,100, + 101,114,115,32,40,115,101,101,32,105,109,112,111,114,116,108, + 105,98,46,97,98,99,46,77,101,116,97,80,97,116,104,70, + 105,110,100,101,114,32,97,110,100,10,32,32,32,32,105,109, + 112,111,114,116,108,105,98,46,97,98,99,46,80,97,116,104, + 69,110,116,114,121,70,105,110,100,101,114,41,32,115,104,111, + 117,108,100,32,109,111,100,105,102,121,32,77,111,100,117,108, + 101,83,112,101,99,32,105,110,115,116,97,110,99,101,115,46, + 10,10,32,32,32,32,78,41,3,218,6,111,114,105,103,105, + 110,218,12,108,111,97,100,101,114,95,115,116,97,116,101,218, + 10,105,115,95,112,97,99,107,97,103,101,99,3,0,0,0, + 0,0,0,0,3,0,0,0,6,0,0,0,2,0,0,0, + 67,0,0,0,115,54,0,0,0,124,1,124,0,95,0,124, + 2,124,0,95,1,124,3,124,0,95,2,124,4,124,0,95, + 3,124,5,114,32,103,0,110,2,100,0,124,0,95,4,100, + 1,124,0,95,5,100,0,124,0,95,6,100,0,83,0,41, + 2,78,70,41,7,114,17,0,0,0,114,111,0,0,0,114, + 115,0,0,0,114,116,0,0,0,218,26,115,117,98,109,111, + 100,117,108,101,95,115,101,97,114,99,104,95,108,111,99,97, + 116,105,111,110,115,218,13,95,115,101,116,95,102,105,108,101, + 97,116,116,114,218,7,95,99,97,99,104,101,100,41,6,114, + 30,0,0,0,114,17,0,0,0,114,111,0,0,0,114,115, + 0,0,0,114,116,0,0,0,114,117,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,114,31,0,0, + 0,86,1,0,0,115,14,0,0,0,0,2,6,1,6,1, + 6,1,6,1,14,3,6,1,122,19,77,111,100,117,108,101, + 83,112,101,99,46,95,95,105,110,105,116,95,95,99,1,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,5,0, + 0,0,67,0,0,0,115,106,0,0,0,100,1,124,0,106, + 0,155,2,157,2,100,2,124,0,106,1,155,2,157,2,103, + 2,125,1,124,0,106,2,100,0,107,9,114,52,124,1,160, + 3,100,3,124,0,106,2,155,2,157,2,161,1,1,0,124, + 0,106,4,100,0,107,9,114,80,124,1,160,3,100,4,124, + 0,106,4,155,0,157,2,161,1,1,0,124,0,106,5,106, + 6,155,0,100,5,100,6,160,7,124,1,161,1,155,0,100, + 7,157,4,83,0,41,8,78,122,5,110,97,109,101,61,122, + 7,108,111,97,100,101,114,61,122,7,111,114,105,103,105,110, + 61,122,27,115,117,98,109,111,100,117,108,101,95,115,101,97, + 114,99,104,95,108,111,99,97,116,105,111,110,115,61,250,1, + 40,122,2,44,32,250,1,41,41,8,114,17,0,0,0,114, + 111,0,0,0,114,115,0,0,0,218,6,97,112,112,101,110, + 100,114,118,0,0,0,218,9,95,95,99,108,97,115,115,95, + 95,114,1,0,0,0,218,4,106,111,105,110,41,2,114,30, + 0,0,0,114,54,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,47,0,0,0,98,1,0,0, + 115,16,0,0,0,0,1,10,1,10,255,4,2,10,1,18, + 1,10,1,18,1,122,19,77,111,100,117,108,101,83,112,101, + 99,46,95,95,114,101,112,114,95,95,99,2,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,8,0,0,0,67, + 0,0,0,115,108,0,0,0,124,0,106,0,125,2,122,72, + 124,0,106,1,124,1,106,1,107,2,111,76,124,0,106,2, + 124,1,106,2,107,2,111,76,124,0,106,3,124,1,106,3, + 107,2,111,76,124,2,124,1,106,0,107,2,111,76,124,0, + 106,4,124,1,106,4,107,2,111,76,124,0,106,5,124,1, + 106,5,107,2,87,0,83,0,4,0,116,6,107,10,114,102, + 1,0,1,0,1,0,116,7,6,0,89,0,83,0,88,0, + 100,0,83,0,114,13,0,0,0,41,8,114,118,0,0,0, + 114,17,0,0,0,114,111,0,0,0,114,115,0,0,0,218, + 6,99,97,99,104,101,100,218,12,104,97,115,95,108,111,99, + 97,116,105,111,110,114,108,0,0,0,218,14,78,111,116,73, + 109,112,108,101,109,101,110,116,101,100,41,3,114,30,0,0, + 0,90,5,111,116,104,101,114,90,4,115,109,115,108,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,218,6,95, + 95,101,113,95,95,107,1,0,0,115,30,0,0,0,0,1, + 6,1,2,1,12,1,10,255,2,2,10,254,2,3,8,253, + 2,4,10,252,2,5,10,251,4,6,14,1,122,17,77,111, + 100,117,108,101,83,112,101,99,46,95,95,101,113,95,95,99, + 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 3,0,0,0,67,0,0,0,115,58,0,0,0,124,0,106, + 0,100,0,107,8,114,52,124,0,106,1,100,0,107,9,114, + 52,124,0,106,2,114,52,116,3,100,0,107,8,114,38,116, + 4,130,1,116,3,160,5,124,0,106,1,161,1,124,0,95, + 0,124,0,106,0,83,0,114,13,0,0,0,41,6,114,120, + 0,0,0,114,115,0,0,0,114,119,0,0,0,218,19,95, + 98,111,111,116,115,116,114,97,112,95,101,120,116,101,114,110, + 97,108,218,19,78,111,116,73,109,112,108,101,109,101,110,116, + 101,100,69,114,114,111,114,90,11,95,103,101,116,95,99,97, + 99,104,101,100,114,46,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,126,0,0,0,119,1,0, + 0,115,12,0,0,0,0,2,10,1,16,1,8,1,4,1, + 14,1,122,17,77,111,100,117,108,101,83,112,101,99,46,99, + 97,99,104,101,100,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,2,0,0,0,67,0,0,0,115,10, + 0,0,0,124,1,124,0,95,0,100,0,83,0,114,13,0, + 0,0,41,1,114,120,0,0,0,41,2,114,30,0,0,0, + 114,126,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,114,126,0,0,0,128,1,0,0,115,2,0, + 0,0,0,2,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,3,0,0,0,67,0,0,0,115,36,0, + 0,0,124,0,106,0,100,1,107,8,114,26,124,0,106,1, + 160,2,100,2,161,1,100,3,25,0,83,0,124,0,106,1, + 83,0,100,1,83,0,41,4,122,32,84,104,101,32,110,97, + 109,101,32,111,102,32,116,104,101,32,109,111,100,117,108,101, + 39,115,32,112,97,114,101,110,116,46,78,218,1,46,114,22, + 0,0,0,41,3,114,118,0,0,0,114,17,0,0,0,218, + 10,114,112,97,114,116,105,116,105,111,110,114,46,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 6,112,97,114,101,110,116,132,1,0,0,115,6,0,0,0, + 0,3,10,1,16,2,122,17,77,111,100,117,108,101,83,112, + 101,99,46,112,97,114,101,110,116,99,1,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,1,0,0,0,67,0, + 0,0,115,6,0,0,0,124,0,106,0,83,0,114,13,0, + 0,0,41,1,114,119,0,0,0,114,46,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,127,0, + 0,0,140,1,0,0,115,2,0,0,0,0,2,122,23,77, + 111,100,117,108,101,83,112,101,99,46,104,97,115,95,108,111, + 99,97,116,105,111,110,99,2,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,2,0,0,0,67,0,0,0,115, + 14,0,0,0,116,0,124,1,131,1,124,0,95,1,100,0, + 83,0,114,13,0,0,0,41,2,218,4,98,111,111,108,114, + 119,0,0,0,41,2,114,30,0,0,0,218,5,118,97,108, + 117,101,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,127,0,0,0,144,1,0,0,115,2,0,0,0,0, + 2,41,12,114,1,0,0,0,114,0,0,0,0,114,2,0, + 0,0,114,3,0,0,0,114,31,0,0,0,114,47,0,0, + 0,114,129,0,0,0,218,8,112,114,111,112,101,114,116,121, + 114,126,0,0,0,218,6,115,101,116,116,101,114,114,134,0, + 0,0,114,127,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,114,0,0,0, + 49,1,0,0,115,32,0,0,0,8,1,4,36,4,1,2, + 255,12,12,8,9,8,12,2,1,10,8,4,1,10,3,2, + 1,10,7,2,1,10,3,4,1,114,114,0,0,0,169,2, + 114,115,0,0,0,114,117,0,0,0,99,2,0,0,0,0, + 0,0,0,2,0,0,0,6,0,0,0,8,0,0,0,67, + 0,0,0,115,154,0,0,0,116,0,124,1,100,1,131,2, + 114,74,116,1,100,2,107,8,114,22,116,2,130,1,116,1, + 106,3,125,4,124,3,100,2,107,8,114,48,124,4,124,0, + 124,1,100,3,141,2,83,0,124,3,114,56,103,0,110,2, + 100,2,125,5,124,4,124,0,124,1,124,5,100,4,141,3, + 83,0,124,3,100,2,107,8,114,138,116,0,124,1,100,5, + 131,2,114,134,122,14,124,1,160,4,124,0,161,1,125,3, + 87,0,113,138,4,0,116,5,107,10,114,130,1,0,1,0, + 1,0,100,2,125,3,89,0,113,138,88,0,110,4,100,6, + 125,3,116,6,124,0,124,1,124,2,124,3,100,7,141,4, + 83,0,41,8,122,53,82,101,116,117,114,110,32,97,32,109, + 111,100,117,108,101,32,115,112,101,99,32,98,97,115,101,100, + 32,111,110,32,118,97,114,105,111,117,115,32,108,111,97,100, + 101,114,32,109,101,116,104,111,100,115,46,90,12,103,101,116, + 95,102,105,108,101,110,97,109,101,78,41,1,114,111,0,0, + 0,41,2,114,111,0,0,0,114,118,0,0,0,114,117,0, + 0,0,70,114,139,0,0,0,41,7,114,4,0,0,0,114, + 130,0,0,0,114,131,0,0,0,218,23,115,112,101,99,95, + 102,114,111,109,95,102,105,108,101,95,108,111,99,97,116,105, + 111,110,114,117,0,0,0,114,79,0,0,0,114,114,0,0, + 0,41,6,114,17,0,0,0,114,111,0,0,0,114,115,0, + 0,0,114,117,0,0,0,114,140,0,0,0,90,6,115,101, + 97,114,99,104,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,91,0,0,0,149,1,0,0,115,36,0,0, + 0,0,2,10,1,8,1,4,1,6,2,8,1,12,1,12, + 1,6,1,2,255,6,3,8,1,10,1,2,1,14,1,14, + 1,12,3,4,2,114,91,0,0,0,99,3,0,0,0,0, + 0,0,0,0,0,0,0,8,0,0,0,8,0,0,0,67, + 0,0,0,115,56,1,0,0,122,10,124,0,106,0,125,3, + 87,0,110,20,4,0,116,1,107,10,114,30,1,0,1,0, + 1,0,89,0,110,14,88,0,124,3,100,0,107,9,114,44, + 124,3,83,0,124,0,106,2,125,4,124,1,100,0,107,8, + 114,90,122,10,124,0,106,3,125,1,87,0,110,20,4,0, + 116,1,107,10,114,88,1,0,1,0,1,0,89,0,110,2, + 88,0,122,10,124,0,106,4,125,5,87,0,110,24,4,0, + 116,1,107,10,114,124,1,0,1,0,1,0,100,0,125,5, + 89,0,110,2,88,0,124,2,100,0,107,8,114,184,124,5, + 100,0,107,8,114,180,122,10,124,1,106,5,125,2,87,0, + 113,184,4,0,116,1,107,10,114,176,1,0,1,0,1,0, + 100,0,125,2,89,0,113,184,88,0,110,4,124,5,125,2, + 122,10,124,0,106,6,125,6,87,0,110,24,4,0,116,1, + 107,10,114,218,1,0,1,0,1,0,100,0,125,6,89,0, + 110,2,88,0,122,14,116,7,124,0,106,8,131,1,125,7, + 87,0,110,26,4,0,116,1,107,10,144,1,114,4,1,0, + 1,0,1,0,100,0,125,7,89,0,110,2,88,0,116,9, + 124,4,124,1,124,2,100,1,141,3,125,3,124,5,100,0, + 107,8,144,1,114,34,100,2,110,2,100,3,124,3,95,10, + 124,6,124,3,95,11,124,7,124,3,95,12,124,3,83,0, + 41,4,78,169,1,114,115,0,0,0,70,84,41,13,114,107, + 0,0,0,114,108,0,0,0,114,1,0,0,0,114,98,0, + 0,0,114,110,0,0,0,218,7,95,79,82,73,71,73,78, + 218,10,95,95,99,97,99,104,101,100,95,95,218,4,108,105, + 115,116,218,8,95,95,112,97,116,104,95,95,114,114,0,0, + 0,114,119,0,0,0,114,126,0,0,0,114,118,0,0,0, + 41,8,114,96,0,0,0,114,111,0,0,0,114,115,0,0, + 0,114,95,0,0,0,114,17,0,0,0,90,8,108,111,99, + 97,116,105,111,110,114,126,0,0,0,114,118,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,17, + 95,115,112,101,99,95,102,114,111,109,95,109,111,100,117,108, + 101,175,1,0,0,115,72,0,0,0,0,2,2,1,10,1, + 14,1,6,2,8,1,4,2,6,1,8,1,2,1,10,1, + 14,2,6,1,2,1,10,1,14,1,10,1,8,1,8,1, + 2,1,10,1,14,1,12,2,4,1,2,1,10,1,14,1, + 10,1,2,1,14,1,16,1,10,2,14,1,20,1,6,1, + 6,1,114,146,0,0,0,70,169,1,218,8,111,118,101,114, + 114,105,100,101,99,2,0,0,0,0,0,0,0,1,0,0, + 0,5,0,0,0,8,0,0,0,67,0,0,0,115,226,1, + 0,0,124,2,115,20,116,0,124,1,100,1,100,0,131,3, + 100,0,107,8,114,54,122,12,124,0,106,1,124,1,95,2, + 87,0,110,20,4,0,116,3,107,10,114,52,1,0,1,0, + 1,0,89,0,110,2,88,0,124,2,115,74,116,0,124,1, + 100,2,100,0,131,3,100,0,107,8,114,178,124,0,106,4, + 125,3,124,3,100,0,107,8,114,146,124,0,106,5,100,0, + 107,9,114,146,116,6,100,0,107,8,114,110,116,7,130,1, + 116,6,106,8,125,4,124,4,160,9,124,4,161,1,125,3, + 124,0,106,5,124,3,95,10,124,3,124,0,95,4,100,0, + 124,1,95,11,122,10,124,3,124,1,95,12,87,0,110,20, + 4,0,116,3,107,10,114,176,1,0,1,0,1,0,89,0, + 110,2,88,0,124,2,115,198,116,0,124,1,100,3,100,0, + 131,3,100,0,107,8,114,232,122,12,124,0,106,13,124,1, + 95,14,87,0,110,20,4,0,116,3,107,10,114,230,1,0, + 1,0,1,0,89,0,110,2,88,0,122,10,124,0,124,1, + 95,15,87,0,110,22,4,0,116,3,107,10,144,1,114,8, + 1,0,1,0,1,0,89,0,110,2,88,0,124,2,144,1, + 115,34,116,0,124,1,100,4,100,0,131,3,100,0,107,8, + 144,1,114,82,124,0,106,5,100,0,107,9,144,1,114,82, + 122,12,124,0,106,5,124,1,95,16,87,0,110,22,4,0, + 116,3,107,10,144,1,114,80,1,0,1,0,1,0,89,0, + 110,2,88,0,124,0,106,17,144,1,114,222,124,2,144,1, + 115,114,116,0,124,1,100,5,100,0,131,3,100,0,107,8, + 144,1,114,150,122,12,124,0,106,18,124,1,95,11,87,0, + 110,22,4,0,116,3,107,10,144,1,114,148,1,0,1,0, + 1,0,89,0,110,2,88,0,124,2,144,1,115,174,116,0, + 124,1,100,6,100,0,131,3,100,0,107,8,144,1,114,222, + 124,0,106,19,100,0,107,9,144,1,114,222,122,12,124,0, + 106,19,124,1,95,20,87,0,110,22,4,0,116,3,107,10, + 144,1,114,220,1,0,1,0,1,0,89,0,110,2,88,0, + 124,1,83,0,41,7,78,114,1,0,0,0,114,98,0,0, + 0,218,11,95,95,112,97,99,107,97,103,101,95,95,114,145, + 0,0,0,114,110,0,0,0,114,143,0,0,0,41,21,114, + 6,0,0,0,114,17,0,0,0,114,1,0,0,0,114,108, + 0,0,0,114,111,0,0,0,114,118,0,0,0,114,130,0, + 0,0,114,131,0,0,0,218,16,95,78,97,109,101,115,112, + 97,99,101,76,111,97,100,101,114,218,7,95,95,110,101,119, + 95,95,90,5,95,112,97,116,104,114,110,0,0,0,114,98, + 0,0,0,114,134,0,0,0,114,149,0,0,0,114,107,0, + 0,0,114,145,0,0,0,114,127,0,0,0,114,115,0,0, + 0,114,126,0,0,0,114,143,0,0,0,41,5,114,95,0, + 0,0,114,96,0,0,0,114,148,0,0,0,114,111,0,0, + 0,114,150,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,18,95,105,110,105,116,95,109,111,100, + 117,108,101,95,97,116,116,114,115,220,1,0,0,115,96,0, + 0,0,0,4,20,1,2,1,12,1,14,1,6,2,20,1, + 6,1,8,2,10,1,8,1,4,1,6,2,10,1,8,1, + 6,11,6,1,2,1,10,1,14,1,6,2,20,1,2,1, + 12,1,14,1,6,2,2,1,10,1,16,1,6,2,24,1, + 12,1,2,1,12,1,16,1,6,2,8,1,24,1,2,1, + 12,1,16,1,6,2,24,1,12,1,2,1,12,1,16,1, + 6,1,114,152,0,0,0,99,1,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,3,0,0,0,67,0,0,0, + 115,82,0,0,0,100,1,125,1,116,0,124,0,106,1,100, + 2,131,2,114,30,124,0,106,1,160,2,124,0,161,1,125, + 1,110,20,116,0,124,0,106,1,100,3,131,2,114,50,116, + 3,100,4,131,1,130,1,124,1,100,1,107,8,114,68,116, + 4,124,0,106,5,131,1,125,1,116,6,124,0,124,1,131, + 2,1,0,124,1,83,0,41,5,122,43,67,114,101,97,116, + 101,32,97,32,109,111,100,117,108,101,32,98,97,115,101,100, + 32,111,110,32,116,104,101,32,112,114,111,118,105,100,101,100, + 32,115,112,101,99,46,78,218,13,99,114,101,97,116,101,95, + 109,111,100,117,108,101,218,11,101,120,101,99,95,109,111,100, + 117,108,101,122,66,108,111,97,100,101,114,115,32,116,104,97, + 116,32,100,101,102,105,110,101,32,101,120,101,99,95,109,111, + 100,117,108,101,40,41,32,109,117,115,116,32,97,108,115,111, + 32,100,101,102,105,110,101,32,99,114,101,97,116,101,95,109, + 111,100,117,108,101,40,41,41,7,114,4,0,0,0,114,111, + 0,0,0,114,153,0,0,0,114,79,0,0,0,114,18,0, + 0,0,114,17,0,0,0,114,152,0,0,0,169,2,114,95, + 0,0,0,114,96,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,16,109,111,100,117,108,101,95, + 102,114,111,109,95,115,112,101,99,36,2,0,0,115,18,0, + 0,0,0,3,4,1,12,3,14,1,12,1,8,2,8,1, + 10,1,10,1,114,156,0,0,0,99,1,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,5,0,0,0,67,0, + 0,0,115,126,0,0,0,124,0,106,0,100,1,107,8,114, + 14,100,2,110,4,124,0,106,0,125,1,124,0,106,1,100, + 1,107,8,114,74,124,0,106,2,100,1,107,8,114,52,100, + 3,124,1,155,2,100,4,157,3,83,0,100,3,124,1,155, + 2,100,5,124,0,106,2,155,2,100,6,157,5,83,0,110, + 48,124,0,106,3,114,100,100,3,124,1,155,2,100,7,124, + 0,106,1,155,2,100,4,157,5,83,0,100,3,124,0,106, + 0,155,2,100,5,124,0,106,1,155,0,100,6,157,5,83, + 0,100,1,83,0,41,8,122,38,82,101,116,117,114,110,32, + 116,104,101,32,114,101,112,114,32,116,111,32,117,115,101,32, + 102,111,114,32,116,104,101,32,109,111,100,117,108,101,46,78, + 114,100,0,0,0,114,101,0,0,0,114,102,0,0,0,114, + 103,0,0,0,114,104,0,0,0,114,105,0,0,0,41,4, + 114,17,0,0,0,114,115,0,0,0,114,111,0,0,0,114, + 127,0,0,0,41,2,114,95,0,0,0,114,17,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 109,0,0,0,53,2,0,0,115,16,0,0,0,0,3,20, + 1,10,1,10,1,12,2,22,2,6,1,20,2,114,109,0, + 0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,10,0,0,0,67,0,0,0,115,206,0,0,0, + 124,0,106,0,125,2,116,1,124,2,131,1,143,182,1,0, + 116,2,106,3,160,4,124,2,161,1,124,1,107,9,114,56, + 100,1,124,2,155,2,100,2,157,3,125,3,116,5,124,3, + 124,2,100,3,141,2,130,1,122,106,124,0,106,7,100,4, + 107,8,114,108,124,0,106,8,100,4,107,8,114,92,116,5, + 100,5,124,0,106,0,100,3,141,2,130,1,116,9,124,0, + 124,1,100,6,100,7,141,3,1,0,110,52,116,9,124,0, + 124,1,100,6,100,7,141,3,1,0,116,10,124,0,106,7, + 100,8,131,2,115,148,124,0,106,7,160,11,124,2,161,1, + 1,0,110,12,124,0,106,7,160,12,124,1,161,1,1,0, + 87,0,53,0,116,2,106,3,160,6,124,0,106,0,161,1, + 125,1,124,1,116,2,106,3,124,0,106,0,60,0,88,0, + 87,0,53,0,81,0,82,0,88,0,124,1,83,0,41,9, + 122,70,69,120,101,99,117,116,101,32,116,104,101,32,115,112, + 101,99,39,115,32,115,112,101,99,105,102,105,101,100,32,109, + 111,100,117,108,101,32,105,110,32,97,110,32,101,120,105,115, + 116,105,110,103,32,109,111,100,117,108,101,39,115,32,110,97, + 109,101,115,112,97,99,101,46,122,7,109,111,100,117,108,101, + 32,122,19,32,110,111,116,32,105,110,32,115,121,115,46,109, + 111,100,117,108,101,115,114,16,0,0,0,78,250,14,109,105, + 115,115,105,110,103,32,108,111,97,100,101,114,84,114,147,0, + 0,0,114,154,0,0,0,41,13,114,17,0,0,0,114,49, + 0,0,0,114,15,0,0,0,114,92,0,0,0,114,34,0, + 0,0,114,79,0,0,0,218,3,112,111,112,114,111,0,0, + 0,114,118,0,0,0,114,152,0,0,0,114,4,0,0,0, + 218,11,108,111,97,100,95,109,111,100,117,108,101,114,154,0, + 0,0,41,4,114,95,0,0,0,114,96,0,0,0,114,17, + 0,0,0,218,3,109,115,103,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,93,0,0,0,70,2,0,0, + 115,34,0,0,0,0,2,6,1,10,1,16,1,12,1,12, + 1,2,1,10,1,10,1,14,2,16,2,14,1,12,4,14, + 2,16,4,14,1,24,1,114,93,0,0,0,99,1,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,8,0,0, + 0,67,0,0,0,115,26,1,0,0,122,18,124,0,106,0, + 160,1,124,0,106,2,161,1,1,0,87,0,110,52,1,0, + 1,0,1,0,124,0,106,2,116,3,106,4,107,6,114,64, + 116,3,106,4,160,5,124,0,106,2,161,1,125,1,124,1, + 116,3,106,4,124,0,106,2,60,0,130,0,89,0,110,2, + 88,0,116,3,106,4,160,5,124,0,106,2,161,1,125,1, + 124,1,116,3,106,4,124,0,106,2,60,0,116,6,124,1, + 100,1,100,0,131,3,100,0,107,8,114,148,122,12,124,0, + 106,0,124,1,95,7,87,0,110,20,4,0,116,8,107,10, + 114,146,1,0,1,0,1,0,89,0,110,2,88,0,116,6, + 124,1,100,2,100,0,131,3,100,0,107,8,114,226,122,40, + 124,1,106,9,124,1,95,10,116,11,124,1,100,3,131,2, + 115,202,124,0,106,2,160,12,100,4,161,1,100,5,25,0, + 124,1,95,10,87,0,110,20,4,0,116,8,107,10,114,224, + 1,0,1,0,1,0,89,0,110,2,88,0,116,6,124,1, + 100,6,100,0,131,3,100,0,107,8,144,1,114,22,122,10, + 124,0,124,1,95,13,87,0,110,22,4,0,116,8,107,10, + 144,1,114,20,1,0,1,0,1,0,89,0,110,2,88,0, + 124,1,83,0,41,7,78,114,98,0,0,0,114,149,0,0, + 0,114,145,0,0,0,114,132,0,0,0,114,22,0,0,0, + 114,107,0,0,0,41,14,114,111,0,0,0,114,159,0,0, + 0,114,17,0,0,0,114,15,0,0,0,114,92,0,0,0, + 114,158,0,0,0,114,6,0,0,0,114,98,0,0,0,114, + 108,0,0,0,114,1,0,0,0,114,149,0,0,0,114,4, + 0,0,0,114,133,0,0,0,114,107,0,0,0,114,155,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,218,25,95,108,111,97,100,95,98,97,99,107,119,97,114, + 100,95,99,111,109,112,97,116,105,98,108,101,100,2,0,0, + 115,54,0,0,0,0,4,2,1,18,1,6,1,12,1,14, + 1,12,1,8,3,14,1,12,1,16,1,2,1,12,1,14, + 1,6,1,16,1,2,4,8,1,10,1,22,1,14,1,6, + 1,18,1,2,1,10,1,16,1,6,1,114,161,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,11,0,0,0,67,0,0,0,115,220,0,0,0,124,0, + 106,0,100,0,107,9,114,30,116,1,124,0,106,0,100,1, + 131,2,115,30,116,2,124,0,131,1,83,0,116,3,124,0, + 131,1,125,1,100,2,124,0,95,4,122,162,124,1,116,5, + 106,6,124,0,106,7,60,0,122,52,124,0,106,0,100,0, + 107,8,114,96,124,0,106,8,100,0,107,8,114,108,116,9, + 100,4,124,0,106,7,100,5,141,2,130,1,110,12,124,0, + 106,0,160,10,124,1,161,1,1,0,87,0,110,50,1,0, + 1,0,1,0,122,14,116,5,106,6,124,0,106,7,61,0, + 87,0,110,20,4,0,116,11,107,10,114,152,1,0,1,0, + 1,0,89,0,110,2,88,0,130,0,89,0,110,2,88,0, + 116,5,106,6,160,12,124,0,106,7,161,1,125,1,124,1, + 116,5,106,6,124,0,106,7,60,0,116,13,100,6,124,0, + 106,7,124,0,106,0,131,3,1,0,87,0,53,0,100,3, + 124,0,95,4,88,0,124,1,83,0,41,7,78,114,154,0, + 0,0,84,70,114,157,0,0,0,114,16,0,0,0,122,18, + 105,109,112,111,114,116,32,123,33,114,125,32,35,32,123,33, + 114,125,41,14,114,111,0,0,0,114,4,0,0,0,114,161, + 0,0,0,114,156,0,0,0,90,13,95,105,110,105,116,105, + 97,108,105,122,105,110,103,114,15,0,0,0,114,92,0,0, + 0,114,17,0,0,0,114,118,0,0,0,114,79,0,0,0, + 114,154,0,0,0,114,62,0,0,0,114,158,0,0,0,114, + 76,0,0,0,114,155,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,14,95,108,111,97,100,95, + 117,110,108,111,99,107,101,100,137,2,0,0,115,46,0,0, + 0,0,2,10,2,12,1,8,2,8,5,6,1,2,1,12, + 1,2,1,10,1,10,1,16,3,16,1,6,1,2,1,14, + 1,14,1,6,1,8,5,14,1,12,1,20,2,8,2,114, + 162,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,10,0,0,0,67,0,0,0,115,42,0, + 0,0,116,0,124,0,106,1,131,1,143,22,1,0,116,2, + 124,0,131,1,87,0,2,0,53,0,81,0,82,0,163,0, + 83,0,81,0,82,0,88,0,100,1,83,0,41,2,122,191, + 82,101,116,117,114,110,32,97,32,110,101,119,32,109,111,100, + 117,108,101,32,111,98,106,101,99,116,44,32,108,111,97,100, + 101,100,32,98,121,32,116,104,101,32,115,112,101,99,39,115, + 32,108,111,97,100,101,114,46,10,10,32,32,32,32,84,104, + 101,32,109,111,100,117,108,101,32,105,115,32,110,111,116,32, + 97,100,100,101,100,32,116,111,32,105,116,115,32,112,97,114, + 101,110,116,46,10,10,32,32,32,32,73,102,32,97,32,109, + 111,100,117,108,101,32,105,115,32,97,108,114,101,97,100,121, + 32,105,110,32,115,121,115,46,109,111,100,117,108,101,115,44, + 32,116,104,97,116,32,101,120,105,115,116,105,110,103,32,109, + 111,100,117,108,101,32,103,101,116,115,10,32,32,32,32,99, + 108,111,98,98,101,114,101,100,46,10,10,32,32,32,32,78, + 41,3,114,49,0,0,0,114,17,0,0,0,114,162,0,0, + 0,41,1,114,95,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,94,0,0,0,179,2,0,0, + 115,4,0,0,0,0,9,12,1,114,94,0,0,0,99,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,64,0,0,0,115,140,0,0,0,101,0,90,1, + 100,0,90,2,100,1,90,3,100,2,90,4,101,5,100,3, + 100,4,132,0,131,1,90,6,101,7,100,20,100,6,100,7, + 132,1,131,1,90,8,101,7,100,21,100,8,100,9,132,1, + 131,1,90,9,101,7,100,10,100,11,132,0,131,1,90,10, + 101,7,100,12,100,13,132,0,131,1,90,11,101,7,101,12, + 100,14,100,15,132,0,131,1,131,1,90,13,101,7,101,12, + 100,16,100,17,132,0,131,1,131,1,90,14,101,7,101,12, + 100,18,100,19,132,0,131,1,131,1,90,15,101,7,101,16, + 131,1,90,17,100,5,83,0,41,22,218,15,66,117,105,108, + 116,105,110,73,109,112,111,114,116,101,114,122,144,77,101,116, + 97,32,112,97,116,104,32,105,109,112,111,114,116,32,102,111, + 114,32,98,117,105,108,116,45,105,110,32,109,111,100,117,108, + 101,115,46,10,10,32,32,32,32,65,108,108,32,109,101,116, + 104,111,100,115,32,97,114,101,32,101,105,116,104,101,114,32, + 99,108,97,115,115,32,111,114,32,115,116,97,116,105,99,32, + 109,101,116,104,111,100,115,32,116,111,32,97,118,111,105,100, + 32,116,104,101,32,110,101,101,100,32,116,111,10,32,32,32, + 32,105,110,115,116,97,110,116,105,97,116,101,32,116,104,101, + 32,99,108,97,115,115,46,10,10,32,32,32,32,122,8,98, + 117,105,108,116,45,105,110,99,1,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,5,0,0,0,67,0,0,0, + 115,22,0,0,0,100,1,124,0,106,0,155,2,100,2,116, + 1,106,2,155,0,100,3,157,5,83,0,169,4,122,115,82, + 101,116,117,114,110,32,114,101,112,114,32,102,111,114,32,116, + 104,101,32,109,111,100,117,108,101,46,10,10,32,32,32,32, + 32,32,32,32,84,104,101,32,109,101,116,104,111,100,32,105, + 115,32,100,101,112,114,101,99,97,116,101,100,46,32,32,84, + 104,101,32,105,109,112,111,114,116,32,109,97,99,104,105,110, + 101,114,121,32,100,111,101,115,32,116,104,101,32,106,111,98, + 32,105,116,115,101,108,102,46,10,10,32,32,32,32,32,32, + 32,32,114,101,0,0,0,114,103,0,0,0,114,104,0,0, + 0,41,3,114,1,0,0,0,114,163,0,0,0,114,142,0, + 0,0,41,1,114,96,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,99,0,0,0,205,2,0, + 0,115,2,0,0,0,0,7,122,27,66,117,105,108,116,105, + 110,73,109,112,111,114,116,101,114,46,109,111,100,117,108,101, + 95,114,101,112,114,78,99,4,0,0,0,0,0,0,0,0, + 0,0,0,4,0,0,0,5,0,0,0,67,0,0,0,115, + 46,0,0,0,124,2,100,0,107,9,114,12,100,0,83,0, + 116,0,160,1,124,1,161,1,114,38,116,2,124,1,124,0, + 124,0,106,3,100,1,141,3,83,0,100,0,83,0,100,0, + 83,0,169,2,78,114,141,0,0,0,41,4,114,56,0,0, + 0,90,10,105,115,95,98,117,105,108,116,105,110,114,91,0, + 0,0,114,142,0,0,0,169,4,218,3,99,108,115,114,81, + 0,0,0,218,4,112,97,116,104,218,6,116,97,114,103,101, + 116,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 218,9,102,105,110,100,95,115,112,101,99,214,2,0,0,115, + 10,0,0,0,0,2,8,1,4,1,10,1,16,2,122,25, + 66,117,105,108,116,105,110,73,109,112,111,114,116,101,114,46, + 102,105,110,100,95,115,112,101,99,99,3,0,0,0,0,0, + 0,0,0,0,0,0,4,0,0,0,4,0,0,0,67,0, + 0,0,115,30,0,0,0,124,0,160,0,124,1,124,2,161, + 2,125,3,124,3,100,1,107,9,114,26,124,3,106,1,83, + 0,100,1,83,0,41,2,122,175,70,105,110,100,32,116,104, + 101,32,98,117,105,108,116,45,105,110,32,109,111,100,117,108, + 101,46,10,10,32,32,32,32,32,32,32,32,73,102,32,39, + 112,97,116,104,39,32,105,115,32,101,118,101,114,32,115,112, + 101,99,105,102,105,101,100,32,116,104,101,110,32,116,104,101, + 32,115,101,97,114,99,104,32,105,115,32,99,111,110,115,105, + 100,101,114,101,100,32,97,32,102,97,105,108,117,114,101,46, + 10,10,32,32,32,32,32,32,32,32,84,104,105,115,32,109, + 101,116,104,111,100,32,105,115,32,100,101,112,114,101,99,97, + 116,101,100,46,32,32,85,115,101,32,102,105,110,100,95,115, + 112,101,99,40,41,32,105,110,115,116,101,97,100,46,10,10, + 32,32,32,32,32,32,32,32,78,41,2,114,170,0,0,0, + 114,111,0,0,0,41,4,114,167,0,0,0,114,81,0,0, + 0,114,168,0,0,0,114,95,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,11,102,105,110,100, + 95,109,111,100,117,108,101,223,2,0,0,115,4,0,0,0, + 0,9,12,1,122,27,66,117,105,108,116,105,110,73,109,112, + 111,114,116,101,114,46,102,105,110,100,95,109,111,100,117,108, + 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,4,0,0,0,67,0,0,0,115,46,0,0,0,124, + 1,106,0,116,1,106,2,107,7,114,34,116,3,124,1,106, + 0,155,2,100,1,157,2,124,1,106,0,100,2,141,2,130, + 1,116,4,116,5,106,6,124,1,131,2,83,0,41,3,122, + 24,67,114,101,97,116,101,32,97,32,98,117,105,108,116,45, + 105,110,32,109,111,100,117,108,101,114,77,0,0,0,114,16, + 0,0,0,41,7,114,17,0,0,0,114,15,0,0,0,114, + 78,0,0,0,114,79,0,0,0,114,66,0,0,0,114,56, + 0,0,0,90,14,99,114,101,97,116,101,95,98,117,105,108, + 116,105,110,41,2,114,30,0,0,0,114,95,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,153, + 0,0,0,235,2,0,0,115,10,0,0,0,0,3,12,1, + 12,1,4,255,6,2,122,29,66,117,105,108,116,105,110,73, + 109,112,111,114,116,101,114,46,99,114,101,97,116,101,95,109, + 111,100,117,108,101,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,16, + 0,0,0,116,0,116,1,106,2,124,1,131,2,1,0,100, + 1,83,0,41,2,122,22,69,120,101,99,32,97,32,98,117, + 105,108,116,45,105,110,32,109,111,100,117,108,101,78,41,3, + 114,66,0,0,0,114,56,0,0,0,90,12,101,120,101,99, + 95,98,117,105,108,116,105,110,41,2,114,30,0,0,0,114, + 96,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,154,0,0,0,243,2,0,0,115,2,0,0, + 0,0,3,122,27,66,117,105,108,116,105,110,73,109,112,111, + 114,116,101,114,46,101,120,101,99,95,109,111,100,117,108,101, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,1, + 83,0,41,2,122,57,82,101,116,117,114,110,32,78,111,110, + 101,32,97,115,32,98,117,105,108,116,45,105,110,32,109,111, + 100,117,108,101,115,32,100,111,32,110,111,116,32,104,97,118, + 101,32,99,111,100,101,32,111,98,106,101,99,116,115,46,78, + 114,10,0,0,0,169,2,114,167,0,0,0,114,81,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 218,8,103,101,116,95,99,111,100,101,248,2,0,0,115,2, + 0,0,0,0,4,122,24,66,117,105,108,116,105,110,73,109, + 112,111,114,116,101,114,46,103,101,116,95,99,111,100,101,99, + 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,83, + 0,41,2,122,56,82,101,116,117,114,110,32,78,111,110,101, + 32,97,115,32,98,117,105,108,116,45,105,110,32,109,111,100, + 117,108,101,115,32,100,111,32,110,111,116,32,104,97,118,101, + 32,115,111,117,114,99,101,32,99,111,100,101,46,78,114,10, + 0,0,0,114,172,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,10,103,101,116,95,115,111,117, + 114,99,101,254,2,0,0,115,2,0,0,0,0,4,122,26, + 66,117,105,108,116,105,110,73,109,112,111,114,116,101,114,46, + 103,101,116,95,115,111,117,114,99,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, + 0,0,0,115,4,0,0,0,100,1,83,0,41,2,122,52, + 82,101,116,117,114,110,32,70,97,108,115,101,32,97,115,32, + 98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,115, + 32,97,114,101,32,110,101,118,101,114,32,112,97,99,107,97, + 103,101,115,46,70,114,10,0,0,0,114,172,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,117, + 0,0,0,4,3,0,0,115,2,0,0,0,0,4,122,26, + 66,117,105,108,116,105,110,73,109,112,111,114,116,101,114,46, + 105,115,95,112,97,99,107,97,103,101,41,2,78,78,41,1, + 78,41,18,114,1,0,0,0,114,0,0,0,0,114,2,0, + 0,0,114,3,0,0,0,114,142,0,0,0,218,12,115,116, + 97,116,105,99,109,101,116,104,111,100,114,99,0,0,0,218, + 11,99,108,97,115,115,109,101,116,104,111,100,114,170,0,0, + 0,114,171,0,0,0,114,153,0,0,0,114,154,0,0,0, + 114,86,0,0,0,114,173,0,0,0,114,174,0,0,0,114, + 117,0,0,0,114,97,0,0,0,114,159,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,163,0,0,0,194,2,0,0,115,44,0,0,0, + 8,2,4,7,4,2,2,1,10,8,2,1,12,8,2,1, + 12,11,2,1,10,7,2,1,10,4,2,1,2,1,12,4, + 2,1,2,1,12,4,2,1,2,1,12,4,114,163,0,0, + 0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,4,0,0,0,64,0,0,0,115,144,0,0,0,101, + 0,90,1,100,0,90,2,100,1,90,3,100,2,90,4,101, + 5,100,3,100,4,132,0,131,1,90,6,101,7,100,22,100, + 6,100,7,132,1,131,1,90,8,101,7,100,23,100,8,100, + 9,132,1,131,1,90,9,101,7,100,10,100,11,132,0,131, + 1,90,10,101,5,100,12,100,13,132,0,131,1,90,11,101, + 7,100,14,100,15,132,0,131,1,90,12,101,7,101,13,100, + 16,100,17,132,0,131,1,131,1,90,14,101,7,101,13,100, + 18,100,19,132,0,131,1,131,1,90,15,101,7,101,13,100, + 20,100,21,132,0,131,1,131,1,90,16,100,5,83,0,41, + 24,218,14,70,114,111,122,101,110,73,109,112,111,114,116,101, + 114,122,142,77,101,116,97,32,112,97,116,104,32,105,109,112, + 111,114,116,32,102,111,114,32,102,114,111,122,101,110,32,109, + 111,100,117,108,101,115,46,10,10,32,32,32,32,65,108,108, + 32,109,101,116,104,111,100,115,32,97,114,101,32,101,105,116, + 104,101,114,32,99,108,97,115,115,32,111,114,32,115,116,97, + 116,105,99,32,109,101,116,104,111,100,115,32,116,111,32,97, + 118,111,105,100,32,116,104,101,32,110,101,101,100,32,116,111, + 10,32,32,32,32,105,110,115,116,97,110,116,105,97,116,101, + 32,116,104,101,32,99,108,97,115,115,46,10,10,32,32,32, + 32,90,6,102,114,111,122,101,110,99,1,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,5,0,0,0,67,0, + 0,0,115,22,0,0,0,100,1,124,0,106,0,155,2,100, + 2,116,1,106,2,155,0,100,3,157,5,83,0,114,164,0, + 0,0,41,3,114,1,0,0,0,114,177,0,0,0,114,142, + 0,0,0,41,1,218,1,109,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,99,0,0,0,24,3,0,0, + 115,2,0,0,0,0,7,122,26,70,114,111,122,101,110,73, + 109,112,111,114,116,101,114,46,109,111,100,117,108,101,95,114, + 101,112,114,78,99,4,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,5,0,0,0,67,0,0,0,115,34,0, + 0,0,116,0,160,1,124,1,161,1,114,26,116,2,124,1, + 124,0,124,0,106,3,100,1,141,3,83,0,100,0,83,0, + 100,0,83,0,114,165,0,0,0,41,4,114,56,0,0,0, + 114,88,0,0,0,114,91,0,0,0,114,142,0,0,0,114, + 166,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,170,0,0,0,33,3,0,0,115,6,0,0, + 0,0,2,10,1,16,2,122,24,70,114,111,122,101,110,73, + 109,112,111,114,116,101,114,46,102,105,110,100,95,115,112,101, + 99,99,3,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,3,0,0,0,67,0,0,0,115,18,0,0,0,116, + 0,160,1,124,1,161,1,114,14,124,0,83,0,100,1,83, + 0,41,2,122,93,70,105,110,100,32,97,32,102,114,111,122, + 101,110,32,109,111,100,117,108,101,46,10,10,32,32,32,32, + 32,32,32,32,84,104,105,115,32,109,101,116,104,111,100,32, + 105,115,32,100,101,112,114,101,99,97,116,101,100,46,32,32, + 85,115,101,32,102,105,110,100,95,115,112,101,99,40,41,32, + 105,110,115,116,101,97,100,46,10,10,32,32,32,32,32,32, + 32,32,78,41,2,114,56,0,0,0,114,88,0,0,0,41, + 3,114,167,0,0,0,114,81,0,0,0,114,168,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 171,0,0,0,40,3,0,0,115,2,0,0,0,0,7,122, + 26,70,114,111,122,101,110,73,109,112,111,114,116,101,114,46, + 102,105,110,100,95,109,111,100,117,108,101,99,2,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, + 67,0,0,0,115,4,0,0,0,100,1,83,0,41,2,122, + 42,85,115,101,32,100,101,102,97,117,108,116,32,115,101,109, + 97,110,116,105,99,115,32,102,111,114,32,109,111,100,117,108, + 101,32,99,114,101,97,116,105,111,110,46,78,114,10,0,0, + 0,41,2,114,167,0,0,0,114,95,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,114,153,0,0, + 0,49,3,0,0,115,2,0,0,0,0,2,122,28,70,114, + 111,122,101,110,73,109,112,111,114,116,101,114,46,99,114,101, + 97,116,101,95,109,111,100,117,108,101,99,1,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,4,0,0,0,67, + 0,0,0,115,64,0,0,0,124,0,106,0,106,1,125,1, + 116,2,160,3,124,1,161,1,115,36,116,4,124,1,155,2, + 100,1,157,2,124,1,100,2,141,2,130,1,116,5,116,2, + 106,6,124,1,131,2,125,2,116,7,124,2,124,0,106,8, + 131,2,1,0,100,0,83,0,114,87,0,0,0,41,9,114, + 107,0,0,0,114,17,0,0,0,114,56,0,0,0,114,88, + 0,0,0,114,79,0,0,0,114,66,0,0,0,218,17,103, + 101,116,95,102,114,111,122,101,110,95,111,98,106,101,99,116, + 218,4,101,120,101,99,114,7,0,0,0,41,3,114,96,0, + 0,0,114,17,0,0,0,218,4,99,111,100,101,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,114,154,0,0, + 0,53,3,0,0,115,10,0,0,0,0,2,8,1,10,1, + 18,1,12,1,122,26,70,114,111,122,101,110,73,109,112,111, + 114,116,101,114,46,101,120,101,99,95,109,111,100,117,108,101, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,3,0,0,0,67,0,0,0,115,10,0,0,0,116,0, + 124,0,124,1,131,2,83,0,41,1,122,95,76,111,97,100, + 32,97,32,102,114,111,122,101,110,32,109,111,100,117,108,101, + 46,10,10,32,32,32,32,32,32,32,32,84,104,105,115,32, + 109,101,116,104,111,100,32,105,115,32,100,101,112,114,101,99, + 97,116,101,100,46,32,32,85,115,101,32,101,120,101,99,95, + 109,111,100,117,108,101,40,41,32,105,110,115,116,101,97,100, + 46,10,10,32,32,32,32,32,32,32,32,41,1,114,97,0, + 0,0,114,172,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,159,0,0,0,61,3,0,0,115, + 2,0,0,0,0,7,122,26,70,114,111,122,101,110,73,109, + 112,111,114,116,101,114,46,108,111,97,100,95,109,111,100,117, + 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,3,0,0,0,67,0,0,0,115,10,0,0,0, + 116,0,160,1,124,1,161,1,83,0,41,1,122,45,82,101, + 116,117,114,110,32,116,104,101,32,99,111,100,101,32,111,98, + 106,101,99,116,32,102,111,114,32,116,104,101,32,102,114,111, + 122,101,110,32,109,111,100,117,108,101,46,41,2,114,56,0, + 0,0,114,179,0,0,0,114,172,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,173,0,0,0, + 70,3,0,0,115,2,0,0,0,0,4,122,23,70,114,111, + 122,101,110,73,109,112,111,114,116,101,114,46,103,101,116,95, + 99,111,100,101,99,2,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0, + 0,0,100,1,83,0,41,2,122,54,82,101,116,117,114,110, + 32,78,111,110,101,32,97,115,32,102,114,111,122,101,110,32, + 109,111,100,117,108,101,115,32,100,111,32,110,111,116,32,104, + 97,118,101,32,115,111,117,114,99,101,32,99,111,100,101,46, + 78,114,10,0,0,0,114,172,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,174,0,0,0,76, + 3,0,0,115,2,0,0,0,0,4,122,25,70,114,111,122, + 101,110,73,109,112,111,114,116,101,114,46,103,101,116,95,115, + 111,117,114,99,101,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,10, + 0,0,0,116,0,160,1,124,1,161,1,83,0,41,1,122, + 46,82,101,116,117,114,110,32,84,114,117,101,32,105,102,32, + 116,104,101,32,102,114,111,122,101,110,32,109,111,100,117,108, + 101,32,105,115,32,97,32,112,97,99,107,97,103,101,46,41, + 2,114,56,0,0,0,90,17,105,115,95,102,114,111,122,101, + 110,95,112,97,99,107,97,103,101,114,172,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,117,0, + 0,0,82,3,0,0,115,2,0,0,0,0,4,122,25,70, + 114,111,122,101,110,73,109,112,111,114,116,101,114,46,105,115, + 95,112,97,99,107,97,103,101,41,2,78,78,41,1,78,41, + 17,114,1,0,0,0,114,0,0,0,0,114,2,0,0,0, + 114,3,0,0,0,114,142,0,0,0,114,175,0,0,0,114, + 99,0,0,0,114,176,0,0,0,114,170,0,0,0,114,171, + 0,0,0,114,153,0,0,0,114,154,0,0,0,114,159,0, + 0,0,114,90,0,0,0,114,173,0,0,0,114,174,0,0, + 0,114,117,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,177,0,0,0,13, + 3,0,0,115,46,0,0,0,8,2,4,7,4,2,2,1, + 10,8,2,1,12,6,2,1,12,8,2,1,10,3,2,1, + 10,7,2,1,10,8,2,1,2,1,12,4,2,1,2,1, + 12,4,2,1,2,1,114,177,0,0,0,99,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 64,0,0,0,115,32,0,0,0,101,0,90,1,100,0,90, + 2,100,1,90,3,100,2,100,3,132,0,90,4,100,4,100, + 5,132,0,90,5,100,6,83,0,41,7,218,18,95,73,109, + 112,111,114,116,76,111,99,107,67,111,110,116,101,120,116,122, + 36,67,111,110,116,101,120,116,32,109,97,110,97,103,101,114, + 32,102,111,114,32,116,104,101,32,105,109,112,111,114,116,32, + 108,111,99,107,46,99,1,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,2,0,0,0,67,0,0,0,115,12, + 0,0,0,116,0,160,1,161,0,1,0,100,1,83,0,41, + 2,122,24,65,99,113,117,105,114,101,32,116,104,101,32,105, + 109,112,111,114,116,32,108,111,99,107,46,78,41,2,114,56, + 0,0,0,114,57,0,0,0,114,46,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,114,53,0,0, + 0,95,3,0,0,115,2,0,0,0,0,2,122,28,95,73, + 109,112,111,114,116,76,111,99,107,67,111,110,116,101,120,116, + 46,95,95,101,110,116,101,114,95,95,99,4,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,67, + 0,0,0,115,12,0,0,0,116,0,160,1,161,0,1,0, + 100,1,83,0,41,2,122,60,82,101,108,101,97,115,101,32, + 116,104,101,32,105,109,112,111,114,116,32,108,111,99,107,32, + 114,101,103,97,114,100,108,101,115,115,32,111,102,32,97,110, + 121,32,114,97,105,115,101,100,32,101,120,99,101,112,116,105, + 111,110,115,46,78,41,2,114,56,0,0,0,114,58,0,0, + 0,41,4,114,30,0,0,0,218,8,101,120,99,95,116,121, + 112,101,218,9,101,120,99,95,118,97,108,117,101,218,13,101, + 120,99,95,116,114,97,99,101,98,97,99,107,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,55,0,0,0, + 99,3,0,0,115,2,0,0,0,0,2,122,27,95,73,109, + 112,111,114,116,76,111,99,107,67,111,110,116,101,120,116,46, + 95,95,101,120,105,116,95,95,78,41,6,114,1,0,0,0, + 114,0,0,0,0,114,2,0,0,0,114,3,0,0,0,114, + 53,0,0,0,114,55,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,182,0, + 0,0,91,3,0,0,115,6,0,0,0,8,2,4,2,8, + 4,114,182,0,0,0,99,3,0,0,0,0,0,0,0,0, + 0,0,0,5,0,0,0,5,0,0,0,67,0,0,0,115, + 66,0,0,0,124,1,160,0,100,1,124,2,100,2,24,0, + 161,2,125,3,116,1,124,3,131,1,124,2,107,0,114,36, + 116,2,100,3,131,1,130,1,124,3,100,4,25,0,125,4, + 124,0,114,62,124,4,155,0,100,1,124,0,155,0,157,3, + 83,0,124,4,83,0,41,5,122,50,82,101,115,111,108,118, + 101,32,97,32,114,101,108,97,116,105,118,101,32,109,111,100, + 117,108,101,32,110,97,109,101,32,116,111,32,97,110,32,97, + 98,115,111,108,117,116,101,32,111,110,101,46,114,132,0,0, + 0,114,37,0,0,0,122,50,97,116,116,101,109,112,116,101, + 100,32,114,101,108,97,116,105,118,101,32,105,109,112,111,114, + 116,32,98,101,121,111,110,100,32,116,111,112,45,108,101,118, + 101,108,32,112,97,99,107,97,103,101,114,22,0,0,0,41, + 3,218,6,114,115,112,108,105,116,218,3,108,101,110,114,79, + 0,0,0,41,5,114,17,0,0,0,218,7,112,97,99,107, + 97,103,101,218,5,108,101,118,101,108,90,4,98,105,116,115, + 90,4,98,97,115,101,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,13,95,114,101,115,111,108,118,101,95, + 110,97,109,101,104,3,0,0,115,10,0,0,0,0,2,16, + 1,12,1,8,1,8,1,114,190,0,0,0,99,3,0,0, + 0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0, + 0,67,0,0,0,115,34,0,0,0,124,0,160,0,124,1, + 124,2,161,2,125,3,124,3,100,0,107,8,114,24,100,0, + 83,0,116,1,124,1,124,3,131,2,83,0,114,13,0,0, + 0,41,2,114,171,0,0,0,114,91,0,0,0,41,4,218, + 6,102,105,110,100,101,114,114,17,0,0,0,114,168,0,0, + 0,114,111,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,17,95,102,105,110,100,95,115,112,101, + 99,95,108,101,103,97,99,121,113,3,0,0,115,8,0,0, + 0,0,3,12,1,8,1,4,1,114,192,0,0,0,99,3, + 0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,10, + 0,0,0,67,0,0,0,115,12,1,0,0,116,0,106,1, + 125,3,124,3,100,1,107,8,114,22,116,2,100,2,131,1, + 130,1,124,3,115,38,116,3,160,4,100,3,116,5,161,2, + 1,0,124,0,116,0,106,6,107,6,125,4,124,3,68,0, + 93,210,125,5,116,7,131,0,143,84,1,0,122,10,124,5, + 106,8,125,6,87,0,110,54,4,0,116,9,107,10,114,128, + 1,0,1,0,1,0,116,10,124,5,124,0,124,1,131,3, + 125,7,124,7,100,1,107,8,114,124,89,0,87,0,53,0, + 81,0,82,0,163,0,113,52,89,0,110,14,88,0,124,6, + 124,0,124,1,124,2,131,3,125,7,87,0,53,0,81,0, + 82,0,88,0,124,7,100,1,107,9,114,52,124,4,144,0, + 115,254,124,0,116,0,106,6,107,6,144,0,114,254,116,0, + 106,6,124,0,25,0,125,8,122,10,124,8,106,11,125,9, + 87,0,110,28,4,0,116,9,107,10,114,226,1,0,1,0, + 1,0,124,7,6,0,89,0,2,0,1,0,83,0,88,0, + 124,9,100,1,107,8,114,244,124,7,2,0,1,0,83,0, + 124,9,2,0,1,0,83,0,113,52,124,7,2,0,1,0, + 83,0,113,52,100,1,83,0,41,4,122,21,70,105,110,100, + 32,97,32,109,111,100,117,108,101,39,115,32,115,112,101,99, + 46,78,122,53,115,121,115,46,109,101,116,97,95,112,97,116, + 104,32,105,115,32,78,111,110,101,44,32,80,121,116,104,111, + 110,32,105,115,32,108,105,107,101,108,121,32,115,104,117,116, + 116,105,110,103,32,100,111,119,110,122,22,115,121,115,46,109, + 101,116,97,95,112,97,116,104,32,105,115,32,101,109,112,116, + 121,41,12,114,15,0,0,0,218,9,109,101,116,97,95,112, + 97,116,104,114,79,0,0,0,218,9,95,119,97,114,110,105, + 110,103,115,218,4,119,97,114,110,218,13,73,109,112,111,114, + 116,87,97,114,110,105,110,103,114,92,0,0,0,114,182,0, + 0,0,114,170,0,0,0,114,108,0,0,0,114,192,0,0, + 0,114,107,0,0,0,41,10,114,17,0,0,0,114,168,0, + 0,0,114,169,0,0,0,114,193,0,0,0,90,9,105,115, + 95,114,101,108,111,97,100,114,191,0,0,0,114,170,0,0, + 0,114,95,0,0,0,114,96,0,0,0,114,107,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 10,95,102,105,110,100,95,115,112,101,99,122,3,0,0,115, + 54,0,0,0,0,2,6,1,8,2,8,3,4,1,12,5, + 10,1,8,1,8,1,2,1,10,1,14,1,12,1,8,1, + 20,2,22,1,8,2,18,1,10,1,2,1,10,1,14,4, + 14,2,8,1,8,2,10,2,10,2,114,197,0,0,0,99, + 3,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, + 4,0,0,0,67,0,0,0,115,108,0,0,0,116,0,124, + 0,116,1,131,2,115,28,116,2,100,1,116,3,124,0,131, + 1,155,0,157,2,131,1,130,1,124,2,100,2,107,0,114, + 44,116,4,100,3,131,1,130,1,124,2,100,2,107,4,114, + 84,116,0,124,1,116,1,131,2,115,72,116,2,100,4,131, + 1,130,1,110,12,124,1,115,84,116,5,100,5,131,1,130, + 1,124,0,115,104,124,2,100,2,107,2,114,104,116,4,100, + 6,131,1,130,1,100,7,83,0,41,8,122,28,86,101,114, + 105,102,121,32,97,114,103,117,109,101,110,116,115,32,97,114, + 101,32,34,115,97,110,101,34,46,122,29,109,111,100,117,108, + 101,32,110,97,109,101,32,109,117,115,116,32,98,101,32,115, + 116,114,44,32,110,111,116,32,114,22,0,0,0,122,18,108, + 101,118,101,108,32,109,117,115,116,32,98,101,32,62,61,32, + 48,122,31,95,95,112,97,99,107,97,103,101,95,95,32,110, + 111,116,32,115,101,116,32,116,111,32,97,32,115,116,114,105, + 110,103,122,54,97,116,116,101,109,112,116,101,100,32,114,101, + 108,97,116,105,118,101,32,105,109,112,111,114,116,32,119,105, + 116,104,32,110,111,32,107,110,111,119,110,32,112,97,114,101, + 110,116,32,112,97,99,107,97,103,101,122,17,69,109,112,116, + 121,32,109,111,100,117,108,101,32,110,97,109,101,78,41,6, + 218,10,105,115,105,110,115,116,97,110,99,101,218,3,115,116, + 114,218,9,84,121,112,101,69,114,114,111,114,114,14,0,0, + 0,218,10,86,97,108,117,101,69,114,114,111,114,114,79,0, + 0,0,169,3,114,17,0,0,0,114,188,0,0,0,114,189, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,13,95,115,97,110,105,116,121,95,99,104,101,99, + 107,169,3,0,0,115,22,0,0,0,0,2,10,1,18,1, + 8,1,8,1,8,1,10,1,10,1,4,1,8,2,12,1, + 114,203,0,0,0,250,16,78,111,32,109,111,100,117,108,101, + 32,110,97,109,101,100,32,122,4,123,33,114,125,99,2,0, + 0,0,0,0,0,0,0,0,0,0,8,0,0,0,8,0, + 0,0,67,0,0,0,115,222,0,0,0,100,0,125,2,124, + 0,160,0,100,1,161,1,100,2,25,0,125,3,124,3,114, + 136,124,3,116,1,106,2,107,7,114,42,116,3,124,1,124, + 3,131,2,1,0,124,0,116,1,106,2,107,6,114,62,116, + 1,106,2,124,0,25,0,83,0,116,1,106,2,124,3,25, + 0,125,4,122,10,124,4,106,4,125,2,87,0,110,52,4, + 0,116,5,107,10,114,134,1,0,1,0,1,0,100,3,124, + 0,155,2,100,4,124,3,155,2,100,5,157,5,125,5,116, + 6,124,5,124,0,100,6,141,2,100,0,130,2,89,0,110, + 2,88,0,116,7,124,0,124,2,131,2,125,6,124,6,100, + 0,107,8,114,174,116,6,100,3,124,0,155,2,157,2,124, + 0,100,6,141,2,130,1,110,8,116,8,124,6,131,1,125, + 7,124,3,114,218,116,1,106,2,124,3,25,0,125,4,116, + 9,124,4,124,0,160,0,100,1,161,1,100,7,25,0,124, + 7,131,3,1,0,124,7,83,0,41,8,78,114,132,0,0, + 0,114,22,0,0,0,114,204,0,0,0,122,2,59,32,122, + 17,32,105,115,32,110,111,116,32,97,32,112,97,99,107,97, + 103,101,114,16,0,0,0,233,2,0,0,0,41,10,114,133, + 0,0,0,114,15,0,0,0,114,92,0,0,0,114,66,0, + 0,0,114,145,0,0,0,114,108,0,0,0,218,19,77,111, + 100,117,108,101,78,111,116,70,111,117,110,100,69,114,114,111, + 114,114,197,0,0,0,114,162,0,0,0,114,5,0,0,0, + 41,8,114,17,0,0,0,218,7,105,109,112,111,114,116,95, + 114,168,0,0,0,114,134,0,0,0,90,13,112,97,114,101, + 110,116,95,109,111,100,117,108,101,114,160,0,0,0,114,95, + 0,0,0,114,96,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,23,95,102,105,110,100,95,97, + 110,100,95,108,111,97,100,95,117,110,108,111,99,107,101,100, + 188,3,0,0,115,42,0,0,0,0,1,4,1,14,1,4, + 1,10,1,10,2,10,1,10,1,10,1,2,1,10,1,14, + 1,18,1,20,1,10,1,8,1,20,2,8,1,4,2,10, + 1,22,1,114,208,0,0,0,99,2,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,10,0,0,0,67,0,0, + 0,115,108,0,0,0,116,0,124,0,131,1,143,50,1,0, + 116,1,106,2,160,3,124,0,116,4,161,2,125,2,124,2, + 116,4,107,8,114,54,116,5,124,0,124,1,131,2,87,0, + 2,0,53,0,81,0,82,0,163,0,83,0,87,0,53,0, + 81,0,82,0,88,0,124,2,100,1,107,8,114,96,100,2, + 124,0,155,0,100,3,157,3,125,3,116,6,124,3,124,0, + 100,4,141,2,130,1,116,7,124,0,131,1,1,0,124,2, + 83,0,41,5,122,25,70,105,110,100,32,97,110,100,32,108, + 111,97,100,32,116,104,101,32,109,111,100,117,108,101,46,78, + 122,10,105,109,112,111,114,116,32,111,102,32,122,28,32,104, + 97,108,116,101,100,59,32,78,111,110,101,32,105,110,32,115, + 121,115,46,109,111,100,117,108,101,115,114,16,0,0,0,41, + 8,114,49,0,0,0,114,15,0,0,0,114,92,0,0,0, + 114,34,0,0,0,218,14,95,78,69,69,68,83,95,76,79, + 65,68,73,78,71,114,208,0,0,0,114,206,0,0,0,114, + 64,0,0,0,41,4,114,17,0,0,0,114,207,0,0,0, + 114,96,0,0,0,114,75,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,218,14,95,102,105,110,100, + 95,97,110,100,95,108,111,97,100,218,3,0,0,115,18,0, + 0,0,0,2,10,1,14,1,8,1,32,2,8,1,12,2, + 12,2,8,1,114,210,0,0,0,114,22,0,0,0,99,3, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,4, + 0,0,0,67,0,0,0,115,42,0,0,0,116,0,124,0, + 124,1,124,2,131,3,1,0,124,2,100,1,107,4,114,32, + 116,1,124,0,124,1,124,2,131,3,125,0,116,2,124,0, + 116,3,131,2,83,0,41,2,97,50,1,0,0,73,109,112, + 111,114,116,32,97,110,100,32,114,101,116,117,114,110,32,116, + 104,101,32,109,111,100,117,108,101,32,98,97,115,101,100,32, + 111,110,32,105,116,115,32,110,97,109,101,44,32,116,104,101, + 32,112,97,99,107,97,103,101,32,116,104,101,32,99,97,108, + 108,32,105,115,10,32,32,32,32,98,101,105,110,103,32,109, + 97,100,101,32,102,114,111,109,44,32,97,110,100,32,116,104, + 101,32,108,101,118,101,108,32,97,100,106,117,115,116,109,101, + 110,116,46,10,10,32,32,32,32,84,104,105,115,32,102,117, + 110,99,116,105,111,110,32,114,101,112,114,101,115,101,110,116, + 115,32,116,104,101,32,103,114,101,97,116,101,115,116,32,99, + 111,109,109,111,110,32,100,101,110,111,109,105,110,97,116,111, + 114,32,111,102,32,102,117,110,99,116,105,111,110,97,108,105, + 116,121,10,32,32,32,32,98,101,116,119,101,101,110,32,105, + 109,112,111,114,116,95,109,111,100,117,108,101,32,97,110,100, + 32,95,95,105,109,112,111,114,116,95,95,46,32,84,104,105, + 115,32,105,110,99,108,117,100,101,115,32,115,101,116,116,105, + 110,103,32,95,95,112,97,99,107,97,103,101,95,95,32,105, + 102,10,32,32,32,32,116,104,101,32,108,111,97,100,101,114, + 32,100,105,100,32,110,111,116,46,10,10,32,32,32,32,114, + 22,0,0,0,41,4,114,203,0,0,0,114,190,0,0,0, + 114,210,0,0,0,218,11,95,103,99,100,95,105,109,112,111, + 114,116,114,202,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,211,0,0,0,234,3,0,0,115, + 8,0,0,0,0,9,12,1,8,1,12,1,114,211,0,0, + 0,169,1,218,9,114,101,99,117,114,115,105,118,101,99,3, + 0,0,0,0,0,0,0,1,0,0,0,8,0,0,0,11, + 0,0,0,67,0,0,0,115,228,0,0,0,124,1,68,0, + 93,218,125,4,116,0,124,4,116,1,131,2,115,66,124,3, + 114,34,124,0,106,2,100,1,23,0,125,5,110,4,100,2, + 125,5,116,3,100,3,124,5,155,0,100,4,116,4,124,4, + 131,1,106,2,155,0,157,4,131,1,130,1,113,4,124,4, + 100,5,107,2,114,108,124,3,115,222,116,5,124,0,100,6, + 131,2,114,222,116,6,124,0,124,0,106,7,124,2,100,7, + 100,8,141,4,1,0,113,4,116,5,124,0,124,4,131,2, + 115,4,124,0,106,2,155,0,100,9,124,4,155,0,157,3, + 125,6,122,14,116,8,124,2,124,6,131,2,1,0,87,0, + 113,4,4,0,116,9,107,10,114,220,1,0,125,7,1,0, + 122,42,124,7,106,10,124,6,107,2,114,202,116,11,106,12, + 160,13,124,6,116,14,161,2,100,10,107,9,114,202,87,0, + 89,0,162,8,113,4,130,0,87,0,53,0,100,10,125,7, + 126,7,88,0,89,0,113,4,88,0,113,4,124,0,83,0, + 41,11,122,238,70,105,103,117,114,101,32,111,117,116,32,119, + 104,97,116,32,95,95,105,109,112,111,114,116,95,95,32,115, + 104,111,117,108,100,32,114,101,116,117,114,110,46,10,10,32, + 32,32,32,84,104,101,32,105,109,112,111,114,116,95,32,112, + 97,114,97,109,101,116,101,114,32,105,115,32,97,32,99,97, + 108,108,97,98,108,101,32,119,104,105,99,104,32,116,97,107, + 101,115,32,116,104,101,32,110,97,109,101,32,111,102,32,109, + 111,100,117,108,101,32,116,111,10,32,32,32,32,105,109,112, + 111,114,116,46,32,73,116,32,105,115,32,114,101,113,117,105, + 114,101,100,32,116,111,32,100,101,99,111,117,112,108,101,32, + 116,104,101,32,102,117,110,99,116,105,111,110,32,102,114,111, + 109,32,97,115,115,117,109,105,110,103,32,105,109,112,111,114, + 116,108,105,98,39,115,10,32,32,32,32,105,109,112,111,114, + 116,32,105,109,112,108,101,109,101,110,116,97,116,105,111,110, + 32,105,115,32,100,101,115,105,114,101,100,46,10,10,32,32, + 32,32,122,8,46,95,95,97,108,108,95,95,122,13,96,96, + 102,114,111,109,32,108,105,115,116,39,39,122,8,73,116,101, + 109,32,105,110,32,122,18,32,109,117,115,116,32,98,101,32, + 115,116,114,44,32,110,111,116,32,250,1,42,218,7,95,95, + 97,108,108,95,95,84,114,212,0,0,0,114,132,0,0,0, + 78,41,15,114,198,0,0,0,114,199,0,0,0,114,1,0, + 0,0,114,200,0,0,0,114,14,0,0,0,114,4,0,0, + 0,218,16,95,104,97,110,100,108,101,95,102,114,111,109,108, + 105,115,116,114,215,0,0,0,114,66,0,0,0,114,206,0, + 0,0,114,17,0,0,0,114,15,0,0,0,114,92,0,0, + 0,114,34,0,0,0,114,209,0,0,0,41,8,114,96,0, + 0,0,218,8,102,114,111,109,108,105,115,116,114,207,0,0, + 0,114,213,0,0,0,218,1,120,90,5,119,104,101,114,101, + 90,9,102,114,111,109,95,110,97,109,101,90,3,101,120,99, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 216,0,0,0,249,3,0,0,115,44,0,0,0,0,10,8, + 1,10,1,4,1,12,2,4,1,28,2,8,1,14,1,10, + 1,2,255,8,2,10,1,16,1,2,1,14,1,16,4,10, + 1,16,255,2,2,8,1,22,1,114,216,0,0,0,99,1, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,6, + 0,0,0,67,0,0,0,115,146,0,0,0,124,0,160,0, + 100,1,161,1,125,1,124,0,160,0,100,2,161,1,125,2, + 124,1,100,3,107,9,114,82,124,2,100,3,107,9,114,78, + 124,1,124,2,106,1,107,3,114,78,116,2,106,3,100,4, + 124,1,155,2,100,5,124,2,106,1,155,2,100,6,157,5, + 116,4,100,7,100,8,141,3,1,0,124,1,83,0,124,2, + 100,3,107,9,114,96,124,2,106,1,83,0,116,2,106,3, + 100,9,116,4,100,7,100,8,141,3,1,0,124,0,100,10, + 25,0,125,1,100,11,124,0,107,7,114,142,124,1,160,5, + 100,12,161,1,100,13,25,0,125,1,124,1,83,0,41,14, + 122,167,67,97,108,99,117,108,97,116,101,32,119,104,97,116, + 32,95,95,112,97,99,107,97,103,101,95,95,32,115,104,111, + 117,108,100,32,98,101,46,10,10,32,32,32,32,95,95,112, + 97,99,107,97,103,101,95,95,32,105,115,32,110,111,116,32, + 103,117,97,114,97,110,116,101,101,100,32,116,111,32,98,101, + 32,100,101,102,105,110,101,100,32,111,114,32,99,111,117,108, + 100,32,98,101,32,115,101,116,32,116,111,32,78,111,110,101, + 10,32,32,32,32,116,111,32,114,101,112,114,101,115,101,110, + 116,32,116,104,97,116,32,105,116,115,32,112,114,111,112,101, + 114,32,118,97,108,117,101,32,105,115,32,117,110,107,110,111, + 119,110,46,10,10,32,32,32,32,114,149,0,0,0,114,107, + 0,0,0,78,122,32,95,95,112,97,99,107,97,103,101,95, + 95,32,33,61,32,95,95,115,112,101,99,95,95,46,112,97, + 114,101,110,116,32,40,122,4,32,33,61,32,114,122,0,0, + 0,233,3,0,0,0,41,1,90,10,115,116,97,99,107,108, + 101,118,101,108,122,89,99,97,110,39,116,32,114,101,115,111, + 108,118,101,32,112,97,99,107,97,103,101,32,102,114,111,109, + 32,95,95,115,112,101,99,95,95,32,111,114,32,95,95,112, + 97,99,107,97,103,101,95,95,44,32,102,97,108,108,105,110, + 103,32,98,97,99,107,32,111,110,32,95,95,110,97,109,101, + 95,95,32,97,110,100,32,95,95,112,97,116,104,95,95,114, + 1,0,0,0,114,145,0,0,0,114,132,0,0,0,114,22, + 0,0,0,41,6,114,34,0,0,0,114,134,0,0,0,114, + 194,0,0,0,114,195,0,0,0,114,196,0,0,0,114,133, + 0,0,0,41,3,218,7,103,108,111,98,97,108,115,114,188, + 0,0,0,114,95,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,17,95,99,97,108,99,95,95, + 95,112,97,99,107,97,103,101,95,95,30,4,0,0,115,38, + 0,0,0,0,7,10,1,10,1,8,1,18,1,22,2,2, + 0,2,254,6,3,4,1,8,1,6,2,6,2,2,0,2, + 254,6,3,8,1,8,1,14,1,114,221,0,0,0,114,10, + 0,0,0,99,5,0,0,0,0,0,0,0,0,0,0,0, + 9,0,0,0,5,0,0,0,67,0,0,0,115,180,0,0, + 0,124,4,100,1,107,2,114,18,116,0,124,0,131,1,125, + 5,110,36,124,1,100,2,107,9,114,30,124,1,110,2,105, + 0,125,6,116,1,124,6,131,1,125,7,116,0,124,0,124, + 7,124,4,131,3,125,5,124,3,115,150,124,4,100,1,107, + 2,114,84,116,0,124,0,160,2,100,3,161,1,100,1,25, + 0,131,1,83,0,124,0,115,92,124,5,83,0,116,3,124, + 0,131,1,116,3,124,0,160,2,100,3,161,1,100,1,25, + 0,131,1,24,0,125,8,116,4,106,5,124,5,106,6,100, + 2,116,3,124,5,106,6,131,1,124,8,24,0,133,2,25, + 0,25,0,83,0,110,26,116,7,124,5,100,4,131,2,114, + 172,116,8,124,5,124,3,116,0,131,3,83,0,124,5,83, + 0,100,2,83,0,41,5,97,215,1,0,0,73,109,112,111, + 114,116,32,97,32,109,111,100,117,108,101,46,10,10,32,32, + 32,32,84,104,101,32,39,103,108,111,98,97,108,115,39,32, + 97,114,103,117,109,101,110,116,32,105,115,32,117,115,101,100, + 32,116,111,32,105,110,102,101,114,32,119,104,101,114,101,32, + 116,104,101,32,105,109,112,111,114,116,32,105,115,32,111,99, + 99,117,114,114,105,110,103,32,102,114,111,109,10,32,32,32, + 32,116,111,32,104,97,110,100,108,101,32,114,101,108,97,116, + 105,118,101,32,105,109,112,111,114,116,115,46,32,84,104,101, + 32,39,108,111,99,97,108,115,39,32,97,114,103,117,109,101, + 110,116,32,105,115,32,105,103,110,111,114,101,100,46,32,84, + 104,101,10,32,32,32,32,39,102,114,111,109,108,105,115,116, + 39,32,97,114,103,117,109,101,110,116,32,115,112,101,99,105, + 102,105,101,115,32,119,104,97,116,32,115,104,111,117,108,100, + 32,101,120,105,115,116,32,97,115,32,97,116,116,114,105,98, + 117,116,101,115,32,111,110,32,116,104,101,32,109,111,100,117, + 108,101,10,32,32,32,32,98,101,105,110,103,32,105,109,112, + 111,114,116,101,100,32,40,101,46,103,46,32,96,96,102,114, + 111,109,32,109,111,100,117,108,101,32,105,109,112,111,114,116, + 32,60,102,114,111,109,108,105,115,116,62,96,96,41,46,32, + 32,84,104,101,32,39,108,101,118,101,108,39,10,32,32,32, + 32,97,114,103,117,109,101,110,116,32,114,101,112,114,101,115, + 101,110,116,115,32,116,104,101,32,112,97,99,107,97,103,101, + 32,108,111,99,97,116,105,111,110,32,116,111,32,105,109,112, + 111,114,116,32,102,114,111,109,32,105,110,32,97,32,114,101, + 108,97,116,105,118,101,10,32,32,32,32,105,109,112,111,114, + 116,32,40,101,46,103,46,32,96,96,102,114,111,109,32,46, + 46,112,107,103,32,105,109,112,111,114,116,32,109,111,100,96, + 96,32,119,111,117,108,100,32,104,97,118,101,32,97,32,39, + 108,101,118,101,108,39,32,111,102,32,50,41,46,10,10,32, + 32,32,32,114,22,0,0,0,78,114,132,0,0,0,114,145, + 0,0,0,41,9,114,211,0,0,0,114,221,0,0,0,218, + 9,112,97,114,116,105,116,105,111,110,114,187,0,0,0,114, + 15,0,0,0,114,92,0,0,0,114,1,0,0,0,114,4, + 0,0,0,114,216,0,0,0,41,9,114,17,0,0,0,114, + 220,0,0,0,218,6,108,111,99,97,108,115,114,217,0,0, + 0,114,189,0,0,0,114,96,0,0,0,90,8,103,108,111, + 98,97,108,115,95,114,188,0,0,0,90,7,99,117,116,95, + 111,102,102,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,10,95,95,105,109,112,111,114,116,95,95,57,4, + 0,0,115,30,0,0,0,0,11,8,1,10,2,16,1,8, + 1,12,1,4,3,8,1,18,1,4,1,4,4,26,3,32, + 1,10,1,12,2,114,224,0,0,0,99,1,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, + 0,0,0,115,38,0,0,0,116,0,160,1,124,0,161,1, + 125,1,124,1,100,0,107,8,114,30,116,2,100,1,124,0, + 23,0,131,1,130,1,116,3,124,1,131,1,83,0,41,2, + 78,122,25,110,111,32,98,117,105,108,116,45,105,110,32,109, + 111,100,117,108,101,32,110,97,109,101,100,32,41,4,114,163, + 0,0,0,114,170,0,0,0,114,79,0,0,0,114,162,0, + 0,0,41,2,114,17,0,0,0,114,95,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,218,18,95, + 98,117,105,108,116,105,110,95,102,114,111,109,95,110,97,109, + 101,94,4,0,0,115,8,0,0,0,0,1,10,1,8,1, + 12,1,114,225,0,0,0,99,2,0,0,0,0,0,0,0, + 0,0,0,0,10,0,0,0,5,0,0,0,67,0,0,0, + 115,166,0,0,0,124,1,97,0,124,0,97,1,116,2,116, + 1,131,1,125,2,116,1,106,3,160,4,161,0,68,0,93, + 72,92,2,125,3,125,4,116,5,124,4,124,2,131,2,114, + 26,124,3,116,1,106,6,107,6,114,60,116,7,125,5,110, + 18,116,0,160,8,124,3,161,1,114,26,116,9,125,5,110, + 2,113,26,116,10,124,4,124,5,131,2,125,6,116,11,124, + 6,124,4,131,2,1,0,113,26,116,1,106,3,116,12,25, + 0,125,7,100,1,68,0,93,46,125,8,124,8,116,1,106, + 3,107,7,114,138,116,13,124,8,131,1,125,9,110,10,116, + 1,106,3,124,8,25,0,125,9,116,14,124,7,124,8,124, + 9,131,3,1,0,113,114,100,2,83,0,41,3,122,250,83, + 101,116,117,112,32,105,109,112,111,114,116,108,105,98,32,98, + 121,32,105,109,112,111,114,116,105,110,103,32,110,101,101,100, + 101,100,32,98,117,105,108,116,45,105,110,32,109,111,100,117, + 108,101,115,32,97,110,100,32,105,110,106,101,99,116,105,110, + 103,32,116,104,101,109,10,32,32,32,32,105,110,116,111,32, + 116,104,101,32,103,108,111,98,97,108,32,110,97,109,101,115, + 112,97,99,101,46,10,10,32,32,32,32,65,115,32,115,121, + 115,32,105,115,32,110,101,101,100,101,100,32,102,111,114,32, + 115,121,115,46,109,111,100,117,108,101,115,32,97,99,99,101, + 115,115,32,97,110,100,32,95,105,109,112,32,105,115,32,110, + 101,101,100,101,100,32,116,111,32,108,111,97,100,32,98,117, + 105,108,116,45,105,110,10,32,32,32,32,109,111,100,117,108, + 101,115,44,32,116,104,111,115,101,32,116,119,111,32,109,111, + 100,117,108,101,115,32,109,117,115,116,32,98,101,32,101,120, + 112,108,105,99,105,116,108,121,32,112,97,115,115,101,100,32, + 105,110,46,10,10,32,32,32,32,41,3,114,23,0,0,0, + 114,194,0,0,0,114,63,0,0,0,78,41,15,114,56,0, + 0,0,114,15,0,0,0,114,14,0,0,0,114,92,0,0, + 0,218,5,105,116,101,109,115,114,198,0,0,0,114,78,0, + 0,0,114,163,0,0,0,114,88,0,0,0,114,177,0,0, + 0,114,146,0,0,0,114,152,0,0,0,114,1,0,0,0, + 114,225,0,0,0,114,5,0,0,0,41,10,218,10,115,121, + 115,95,109,111,100,117,108,101,218,11,95,105,109,112,95,109, + 111,100,117,108,101,90,11,109,111,100,117,108,101,95,116,121, + 112,101,114,17,0,0,0,114,96,0,0,0,114,111,0,0, + 0,114,95,0,0,0,90,11,115,101,108,102,95,109,111,100, + 117,108,101,90,12,98,117,105,108,116,105,110,95,110,97,109, + 101,90,14,98,117,105,108,116,105,110,95,109,111,100,117,108, + 101,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 218,6,95,115,101,116,117,112,101,4,0,0,115,36,0,0, + 0,0,9,4,1,4,3,8,1,18,1,10,1,10,1,6, + 1,10,1,6,2,2,1,10,1,12,3,10,1,8,1,10, + 1,10,2,10,1,114,229,0,0,0,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, + 0,0,0,115,38,0,0,0,116,0,124,0,124,1,131,2, + 1,0,116,1,106,2,160,3,116,4,161,1,1,0,116,1, + 106,2,160,3,116,5,161,1,1,0,100,1,83,0,41,2, + 122,48,73,110,115,116,97,108,108,32,105,109,112,111,114,116, + 101,114,115,32,102,111,114,32,98,117,105,108,116,105,110,32, + 97,110,100,32,102,114,111,122,101,110,32,109,111,100,117,108, + 101,115,78,41,6,114,229,0,0,0,114,15,0,0,0,114, + 193,0,0,0,114,123,0,0,0,114,163,0,0,0,114,177, + 0,0,0,41,2,114,227,0,0,0,114,228,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8, + 95,105,110,115,116,97,108,108,136,4,0,0,115,6,0,0, + 0,0,2,10,2,12,1,114,230,0,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0, + 0,67,0,0,0,115,32,0,0,0,100,1,100,2,108,0, + 125,0,124,0,97,1,124,0,160,2,116,3,106,4,116,5, + 25,0,161,1,1,0,100,2,83,0,41,3,122,57,73,110, + 115,116,97,108,108,32,105,109,112,111,114,116,101,114,115,32, + 116,104,97,116,32,114,101,113,117,105,114,101,32,101,120,116, + 101,114,110,97,108,32,102,105,108,101,115,121,115,116,101,109, + 32,97,99,99,101,115,115,114,22,0,0,0,78,41,6,218, + 26,95,102,114,111,122,101,110,95,105,109,112,111,114,116,108, + 105,98,95,101,120,116,101,114,110,97,108,114,130,0,0,0, + 114,230,0,0,0,114,15,0,0,0,114,92,0,0,0,114, + 1,0,0,0,41,1,114,231,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,27,95,105,110,115, + 116,97,108,108,95,101,120,116,101,114,110,97,108,95,105,109, + 112,111,114,116,101,114,115,144,4,0,0,115,6,0,0,0, + 0,3,8,1,4,1,114,232,0,0,0,41,2,78,78,41, + 1,78,41,2,78,114,22,0,0,0,41,4,78,78,114,10, + 0,0,0,114,22,0,0,0,41,50,114,3,0,0,0,114, + 130,0,0,0,114,12,0,0,0,114,18,0,0,0,114,59, + 0,0,0,114,33,0,0,0,114,42,0,0,0,114,19,0, + 0,0,114,20,0,0,0,114,48,0,0,0,114,49,0,0, + 0,114,52,0,0,0,114,64,0,0,0,114,66,0,0,0, + 114,76,0,0,0,114,86,0,0,0,114,90,0,0,0,114, + 97,0,0,0,114,113,0,0,0,114,114,0,0,0,114,91, + 0,0,0,114,146,0,0,0,114,152,0,0,0,114,156,0, + 0,0,114,109,0,0,0,114,93,0,0,0,114,161,0,0, + 0,114,162,0,0,0,114,94,0,0,0,114,163,0,0,0, + 114,177,0,0,0,114,182,0,0,0,114,190,0,0,0,114, + 192,0,0,0,114,197,0,0,0,114,203,0,0,0,90,15, + 95,69,82,82,95,77,83,71,95,80,82,69,70,73,88,90, + 8,95,69,82,82,95,77,83,71,114,208,0,0,0,218,6, + 111,98,106,101,99,116,114,209,0,0,0,114,210,0,0,0, + 114,211,0,0,0,114,216,0,0,0,114,221,0,0,0,114, + 224,0,0,0,114,225,0,0,0,114,229,0,0,0,114,230, + 0,0,0,114,232,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,8,60,109, + 111,100,117,108,101,62,1,0,0,0,115,94,0,0,0,4, + 24,4,2,8,8,8,8,4,2,4,3,16,4,14,68,14, + 21,14,16,8,37,8,17,8,11,14,8,8,11,8,12,8, + 16,8,36,14,100,16,26,10,45,14,72,8,17,8,17,8, + 30,8,37,8,42,8,15,14,75,14,78,14,13,8,9,8, + 9,10,47,8,16,4,1,8,2,8,27,6,3,8,16,10, + 15,14,37,8,27,10,37,8,7,8,35,8,8, +}; diff --git a/Python/initconfig.c b/Python/initconfig.c index c916e2f7c07..d7b2dc4a297 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -3,6 +3,7 @@ #include "pycore_getopt.h" // _PyOS_GetOpt() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_interp.h" // _PyInterpreterState.runtime +#include "pycore_long.h" // _PY_LONG_MAX_STR_DIGITS_THRESHOLD #include "pycore_pathconfig.h" // _Py_path_config #include "pycore_pyerrors.h" // _PyErr_Fetch() #include "pycore_pylifecycle.h" // _Py_PreInitializeFromConfig() @@ -22,20 +23,16 @@ # endif #endif -#ifndef PLATLIBDIR -# error "PLATLIBDIR macro must be defined" -#endif - - /* --- Command line options --------------------------------------- */ /* Short usage message (with %s for argv0) */ static const char usage_line[] = "usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n"; -/* Long usage message, split into parts < 512 bytes */ -static const char usage_1[] = "\ -Options and arguments (and corresponding environment variables):\n\ +/* Long help message */ +/* Lines sorted by option name; keep in sync with usage_envvars* below */ +static const char usage_help[] = "\ +Options (and corresponding environment variables):\n\ -b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\ and comparing bytes/bytearray with str. (-bb: issue errors)\n\ -B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\ @@ -43,9 +40,7 @@ Options and arguments (and corresponding environment variables):\n\ -d : turn on parser debugging output (for experts only, only works on\n\ debug builds); also PYTHONDEBUG=x\n\ -E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\ --h : print this help message and exit (also --help)\n\ -"; -static const char usage_2[] = "\ +-h : print this help message and exit (also -? or --help)\n\ -i : inspect interactively after running script; forces a prompt even\n\ if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\ -I : isolate Python from the user's environment (implies -E and -s)\n\ @@ -54,11 +49,10 @@ static const char usage_2[] = "\ .pyc extension; also PYTHONOPTIMIZE=x\n\ -OO : do -O changes and also discard docstrings; add .opt-2 before\n\ .pyc extension\n\ +-P : don't prepend a potentially unsafe path to sys.path\n\ -q : don't print version and copyright messages on interactive startup\n\ -s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\ -S : don't imply 'import site' on initialization\n\ -"; -static const char usage_3[] = "\ -u : force the stdout and stderr streams to be unbuffered;\n\ this option has no effect on stdin; also PYTHONUNBUFFERED=x\n\ -v : verbose (trace import statements); also PYTHONVERBOSE=x\n\ @@ -68,68 +62,104 @@ static const char usage_3[] = "\ -W arg : warning control; arg is action:message:category:module:lineno\n\ also PYTHONWARNINGS=arg\n\ -x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\ --X opt : set implementation-specific option. The following options are available:\n\ -\n\ - -X faulthandler: enable faulthandler\n\ - -X showrefcount: output the total reference count and number of used\n\ - memory blocks when the program finishes or after each statement in the\n\ - interactive interpreter. This only works on debug builds\n\ - -X tracemalloc: start tracing Python memory allocations using the\n\ - tracemalloc module. By default, only the most recent frame is stored in a\n\ - traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\ - traceback limit of NFRAME frames\n\ - -X importtime: show how long each import takes. It shows module name,\n\ - cumulative time (including nested imports) and self time (excluding\n\ - nested imports). Note that its output may be broken in multi-threaded\n\ - application. Typical usage is python3 -X importtime -c 'import asyncio'\n\ - -X dev: enable CPython's \"development mode\", introducing additional runtime\n\ - checks which are too expensive to be enabled by default. Effect of the\n\ - developer mode:\n\ - * Add default warning filter, as -W default\n\ - * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function\n\ - * Enable the faulthandler module to dump the Python traceback on a crash\n\ - * Enable asyncio debug mode\n\ - * Set the dev_mode attribute of sys.flags to True\n\ - * io.IOBase destructor logs close() exceptions\n\ - -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\ - locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\ - otherwise activate automatically)\n\ - -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\ - given directory instead of to the code tree\n\ - -X warn_default_encoding: enable opt-in EncodingWarning for 'encoding=None'\n\ - -X no_debug_ranges: disable the inclusion of the tables mapping extra location \n\ - information (end line, start column offset and end column offset) to every \n\ - instruction in code objects. This is useful when smaller code objects and pyc \n\ - files are desired as well as suppressing the extra visual location indicators \n\ - when the interpreter displays tracebacks.\n\ - -X frozen_modules=[on|off]: whether or not frozen modules should be used.\n\ - The default is \"on\" (or \"off\" if you are running a local build).\n\ -\n\ +-X opt : set implementation-specific option\n\ --check-hash-based-pycs always|default|never:\n\ - control how Python invalidates hash-based .pyc files\n\ -"; -static const char usage_4[] = "\ + control how Python invalidates hash-based .pyc files\n\ +--help-env : print help about Python environment variables and exit\n\ +--help-xoptions : print help about implementation-specific -X options and exit\n\ +--help-all : print complete help information and exit\n\ +Arguments:\n\ file : program read from script file\n\ - : program read from stdin (default; interactive mode if a tty)\n\ -arg ...: arguments passed to program in sys.argv[1:]\n\n\ -Other environment variables:\n\ -PYTHONSTARTUP: file executed on interactive startup (no default)\n\ -PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\ - default module search path. The result is sys.path.\n\ +arg ...: arguments passed to program in sys.argv[1:]\n\ "; -static const char usage_5[] = + +static const char usage_xoptions[] = "\ +The following implementation-specific options are available:\n\ +\n\ +-X faulthandler: enable faulthandler\n\ +\n\ +-X showrefcount: output the total reference count and number of used\n\ + memory blocks when the program finishes or after each statement in the\n\ + interactive interpreter. This only works on debug builds\n\ +\n\ +-X tracemalloc: start tracing Python memory allocations using the\n\ + tracemalloc module. By default, only the most recent frame is stored in a\n\ + traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a\n\ + traceback limit of NFRAME frames\n\ +\n\ +-X importtime: show how long each import takes. It shows module name,\n\ + cumulative time (including nested imports) and self time (excluding\n\ + nested imports). Note that its output may be broken in multi-threaded\n\ + application. Typical usage is python3 -X importtime -c 'import asyncio'\n\ +\n\ +-X dev: enable CPython's \"development mode\", introducing additional runtime\n\ + checks which are too expensive to be enabled by default. Effect of the\n\ + developer mode:\n\ + * Add default warning filter, as -W default\n\ + * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks()\n\ + C function\n\ + * Enable the faulthandler module to dump the Python traceback on a crash\n\ + * Enable asyncio debug mode\n\ + * Set the dev_mode attribute of sys.flags to True\n\ + * io.IOBase destructor logs close() exceptions\n\ +\n\ +-X utf8: enable UTF-8 mode for operating system interfaces, overriding the default\n\ + locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would\n\ + otherwise activate automatically)\n\ +\n\ +-X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the\n\ + given directory instead of to the code tree\n\ +\n\ +-X warn_default_encoding: enable opt-in EncodingWarning for 'encoding=None'\n\ +\n\ +-X no_debug_ranges: disable the inclusion of the tables mapping extra location \n\ + information (end line, start column offset and end column offset) to every \n\ + instruction in code objects. This is useful when smaller code objects and pyc \n\ + files are desired as well as suppressing the extra visual location indicators \n\ + when the interpreter displays tracebacks.\n\ +\n\ +-X perf: activate support for the Linux \"perf\" profiler by activating the \"perf\"\n\ + trampoline. When this option is activated, the Linux \"perf\" profiler will be \n\ + able to report Python calls. This option is only available on some platforms and will \n\ + do nothing if is not supported on the current system. The default value is \"off\".\n\ +\n\ +-X frozen_modules=[on|off]: whether or not frozen modules should be used.\n\ + The default is \"on\" (or \"off\" if you are running a local build).\n\ +\n\ +-X int_max_str_digits=number: limit the size of int<->str conversions.\n\ + This helps avoid denial of service attacks when parsing untrusted data.\n\ + The default is sys.int_info.default_max_str_digits. 0 disables." + +#ifdef Py_STATS +"\n\ +\n\ +-X pystats: Enable pystats collection at startup." +#endif +; + +/* Envvars that don't have equivalent command-line options are listed first */ +static const char usage_envvars[] = +"Environment variables that change behavior:\n" +"PYTHONSTARTUP: file executed on interactive startup (no default)\n" +"PYTHONPATH : '%lc'-separated list of directories prefixed to the\n" +" default module search path. The result is sys.path.\n" +"PYTHONSAFEPATH: don't prepend a potentially unsafe path to sys.path.\n" "PYTHONHOME : alternate directory (or %lc).\n" " The default module search path uses %s.\n" "PYTHONPLATLIBDIR : override sys.platlibdir.\n" "PYTHONCASEOK : ignore case in 'import' statements (Windows).\n" "PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n" "PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n" -"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n"; -static const char usage_6[] = +"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n" "PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n" " to seed the hashes of str and bytes objects. It can also be set to an\n" " integer in the range [0,4294967295] to get hash values with a\n" " predictable seed.\n" +"PYTHONINTMAXSTRDIGITS: limits the maximum digit characters in an int value\n" +" when converting from a string and when converting an int back to a str.\n" +" A value of 0 disables the limit. Conversions to or from bases 2, 4, 8,\n" +" 16, and 32 are never limited.\n" "PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n" " on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n" " hooks.\n" @@ -144,8 +174,19 @@ static const char usage_6[] = "PYTHONNODEBUGRANGES: If this variable is set, it disables the inclusion of the \n" " tables mapping extra location information (end line, start column offset \n" " and end column offset) to every instruction in code objects. This is useful \n" -" when smaller cothe de objects and pyc files are desired as well as suppressing the \n" -" extra visual location indicators when the interpreter displays tracebacks.\n"; +" when smaller code objects and pyc files are desired as well as suppressing the \n" +" extra visual location indicators when the interpreter displays tracebacks.\n" +"These variables have equivalent command-line parameters (see --help for details):\n" +"PYTHONDEBUG : enable parser debug mode (-d)\n" +"PYTHONDONTWRITEBYTECODE : don't write .pyc files (-B)\n" +"PYTHONINSPECT : inspect interactively after running script (-i)\n" +"PYTHONINTMAXSTRDIGITS : limit max digit characters in an int value\n" +" (-X int_max_str_digits=number)\n" +"PYTHONNOUSERSITE : disable user site directory (-s)\n" +"PYTHONOPTIMIZE : enable level 1 optimizations (-O)\n" +"PYTHONUNBUFFERED : disable stdout/stderr buffering (-u)\n" +"PYTHONVERBOSE : trace import statements (-v)\n" +"PYTHONWARNINGS=arg : warning control (-W arg)\n"; #if defined(MS_WINDOWS) # define PYTHONHOMEHELP "\\python{major}{minor}" @@ -162,7 +203,7 @@ int Py_UTF8Mode = 0; int Py_DebugFlag = 0; /* Needed by parser.c */ int Py_VerboseFlag = 0; /* Needed by import.c */ int Py_QuietFlag = 0; /* Needed by sysmodule.c */ -int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */ +int Py_InteractiveFlag = 0; /* Previously, was used by Py_FdIsInteractive() */ int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */ int Py_OptimizeFlag = 0; /* Needed by compile.c */ int Py_NoSiteFlag = 0; /* Suppress 'import site' */ @@ -183,6 +224,8 @@ int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */ static PyObject * _Py_GetGlobalVariablesAsDict(void) { +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS PyObject *dict, *obj; dict = PyDict_New(); @@ -207,7 +250,7 @@ _Py_GetGlobalVariablesAsDict(void) #define FROM_STRING(STR) \ ((STR != NULL) ? \ PyUnicode_FromString(STR) \ - : (Py_INCREF(Py_None), Py_None)) + : Py_NewRef(Py_None)) #define SET_ITEM_STR(VAR) \ SET_ITEM(#VAR, FROM_STRING(VAR)) @@ -249,15 +292,19 @@ fail: #undef SET_ITEM #undef SET_ITEM_INT #undef SET_ITEM_STR +_Py_COMP_DIAG_POP } char* Py_GETENV(const char *name) { +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS if (Py_IgnoreEnvironmentFlag) { return NULL; } return getenv(name); +_Py_COMP_DIAG_POP } /* --- PyStatus ----------------------------------------------- */ @@ -519,8 +566,11 @@ Py_SetStandardStreamEncoding(const char *encoding, const char *errors) } #ifdef MS_WINDOWS if (_Py_StandardStreamEncoding) { +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS /* Overriding the stream encoding implies legacy streams */ Py_LegacyWindowsStdioFlag = 1; +_Py_COMP_DIAG_POP } #endif @@ -554,17 +604,13 @@ _Py_ClearStandardStreamEncoding(void) /* --- Py_GetArgcArgv() ------------------------------------------- */ -/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */ -static PyWideStringList orig_argv = {.length = 0, .items = NULL}; - - void _Py_ClearArgcArgv(void) { PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - _PyWideStringList_Clear(&orig_argv); + _PyWideStringList_Clear(&_PyRuntime.orig_argv); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); } @@ -579,7 +625,9 @@ _Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv) PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - res = _PyWideStringList_Copy(&orig_argv, &argv_list); + // XXX _PyRuntime.orig_argv only gets cleared by Py_Main(), + // so it it currently leaks for embedders. + res = _PyWideStringList_Copy(&_PyRuntime.orig_argv, &argv_list); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); return res; @@ -590,8 +638,8 @@ _Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv) void Py_GetArgcArgv(int *argc, wchar_t ***argv) { - *argc = (int)orig_argv.length; - *argv = orig_argv.items; + *argc = (int)_PyRuntime.orig_argv.length; + *argv = _PyRuntime.orig_argv.items; } @@ -614,7 +662,7 @@ config_check_consistency(const PyConfig *config) assert(config->faulthandler >= 0); assert(config->tracemalloc >= 0); assert(config->import_time >= 0); - assert(config->no_debug_ranges >= 0); + assert(config->code_debug_ranges >= 0); assert(config->show_ref_count >= 0); assert(config->dump_refs >= 0); assert(config->malloc_stats >= 0); @@ -632,7 +680,6 @@ config_check_consistency(const PyConfig *config) assert(config->parse_argv >= 0); assert(config->configure_c_stdio >= 0); assert(config->buffered_stdio >= 0); - assert(config->program_name != NULL); assert(_PyWideStringList_CheckConsistency(&config->orig_argv)); assert(_PyWideStringList_CheckConsistency(&config->argv)); /* sys.argv must be non-empty: empty argv is replaced with [''] */ @@ -641,7 +688,6 @@ config_check_consistency(const PyConfig *config) assert(_PyWideStringList_CheckConsistency(&config->warnoptions)); assert(_PyWideStringList_CheckConsistency(&config->module_search_paths)); assert(config->module_search_paths_set >= 0); - assert(config->platlibdir != NULL); assert(config->filesystem_encoding != NULL); assert(config->filesystem_errors != NULL); assert(config->stdio_encoding != NULL); @@ -654,6 +700,11 @@ config_check_consistency(const PyConfig *config) assert(config->check_hash_pycs_mode != NULL); assert(config->_install_importlib >= 0); assert(config->pathconfig_warnings >= 0); + assert(config->_is_python_build >= 0); + assert(config->safe_path >= 0); + assert(config->int_max_str_digits >= 0); + // config->use_frozen_modules is initialized later + // by _PyConfig_InitImportConfig(). return 1; } #endif @@ -716,6 +767,7 @@ _PyConfig_InitCompatConfig(PyConfig *config) config->use_hash_seed = -1; config->faulthandler = -1; config->tracemalloc = -1; + config->perf_profiling = -1; config->module_search_paths_set = 0; config->parse_argv = 0; config->site_import = -1; @@ -735,11 +787,18 @@ _PyConfig_InitCompatConfig(PyConfig *config) config->check_hash_pycs_mode = NULL; config->pathconfig_warnings = -1; config->_init_main = 1; - config->_isolated_interpreter = 0; #ifdef MS_WINDOWS config->legacy_windows_stdio = -1; #endif - config->use_frozen_modules = -1; +#ifdef Py_DEBUG + config->use_frozen_modules = 0; +#else + config->use_frozen_modules = 1; +#endif + config->safe_path = 0; + config->int_max_str_digits = -1; + config->_is_python_build = 0; + config->code_debug_ranges = 1; } @@ -793,6 +852,9 @@ PyConfig_InitIsolatedConfig(PyConfig *config) config->use_hash_seed = 0; config->faulthandler = 0; config->tracemalloc = 0; + config->perf_profiling = 0; + config->int_max_str_digits = _PY_LONG_DEFAULT_MAX_STR_DIGITS; + config->safe_path = 1; config->pathconfig_warnings = 0; #ifdef MS_WINDOWS config->legacy_windows_stdio = 0; @@ -903,8 +965,9 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2) COPY_ATTR(_install_importlib); COPY_ATTR(faulthandler); COPY_ATTR(tracemalloc); + COPY_ATTR(perf_profiling); COPY_ATTR(import_time); - COPY_ATTR(no_debug_ranges); + COPY_ATTR(code_debug_ranges); COPY_ATTR(show_ref_count); COPY_ATTR(dump_refs); COPY_ATTR(dump_refs_file); @@ -958,9 +1021,11 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2) COPY_WSTR_ATTR(check_hash_pycs_mode); COPY_ATTR(pathconfig_warnings); COPY_ATTR(_init_main); - COPY_ATTR(_isolated_interpreter); COPY_ATTR(use_frozen_modules); + COPY_ATTR(safe_path); COPY_WSTRLIST(orig_argv); + COPY_ATTR(_is_python_build); + COPY_ATTR(int_max_str_digits); #undef COPY_ATTR #undef COPY_WSTR_ATTR @@ -996,7 +1061,7 @@ _PyConfig_AsDict(const PyConfig *config) #define FROM_WSTRING(STR) \ ((STR != NULL) ? \ PyUnicode_FromWideChar(STR, -1) \ - : (Py_INCREF(Py_None), Py_None)) + : Py_NewRef(Py_None)) #define SET_ITEM_WSTR(ATTR) \ SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR)) #define SET_ITEM_WSTRLIST(LIST) \ @@ -1011,8 +1076,9 @@ _PyConfig_AsDict(const PyConfig *config) SET_ITEM_UINT(hash_seed); SET_ITEM_INT(faulthandler); SET_ITEM_INT(tracemalloc); + SET_ITEM_INT(perf_profiling); SET_ITEM_INT(import_time); - SET_ITEM_INT(no_debug_ranges); + SET_ITEM_INT(code_debug_ranges); SET_ITEM_INT(show_ref_count); SET_ITEM_INT(dump_refs); SET_ITEM_INT(malloc_stats); @@ -1062,9 +1128,11 @@ _PyConfig_AsDict(const PyConfig *config) SET_ITEM_WSTR(check_hash_pycs_mode); SET_ITEM_INT(pathconfig_warnings); SET_ITEM_INT(_init_main); - SET_ITEM_INT(_isolated_interpreter); SET_ITEM_WSTRLIST(orig_argv); SET_ITEM_INT(use_frozen_modules); + SET_ITEM_INT(safe_path); + SET_ITEM_INT(_is_python_build); + SET_ITEM_INT(int_max_str_digits); return dict; @@ -1254,6 +1322,12 @@ _PyConfig_FromDict(PyConfig *config, PyObject *dict) } \ CHECK_VALUE(#KEY, config->KEY >= 0); \ } while (0) +#define GET_INT(KEY) \ + do { \ + if (config_dict_get_int(dict, #KEY, &config->KEY) < 0) { \ + return -1; \ + } \ + } while (0) #define GET_WSTR(KEY) \ do { \ if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \ @@ -1290,8 +1364,9 @@ _PyConfig_FromDict(PyConfig *config, PyObject *dict) CHECK_VALUE("hash_seed", config->hash_seed <= MAX_HASH_SEED); GET_UINT(faulthandler); GET_UINT(tracemalloc); + GET_UINT(perf_profiling); GET_UINT(import_time); - GET_UINT(no_debug_ranges); + GET_UINT(code_debug_ranges); GET_UINT(show_ref_count); GET_UINT(dump_refs); GET_UINT(malloc_stats); @@ -1347,11 +1422,14 @@ _PyConfig_FromDict(PyConfig *config, PyObject *dict) GET_UINT(_install_importlib); GET_UINT(_init_main); - GET_UINT(_isolated_interpreter); GET_UINT(use_frozen_modules); + GET_UINT(safe_path); + GET_UINT(_is_python_build); + GET_INT(int_max_str_digits); #undef CHECK_VALUE #undef GET_UINT +#undef GET_INT #undef GET_WSTR #undef GET_WSTR_OPT return 0; @@ -1409,6 +1487,8 @@ config_get_env_dup(PyConfig *config, static void config_get_global_vars(PyConfig *config) { +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS if (config->_config_init != _PyConfig_INIT_COMPAT) { /* Python and Isolated configuration ignore global variables */ return; @@ -1444,6 +1524,7 @@ config_get_global_vars(PyConfig *config) #undef COPY_FLAG #undef COPY_NOT_FLAG +_Py_COMP_DIAG_POP } @@ -1451,6 +1532,8 @@ config_get_global_vars(PyConfig *config) static void config_set_global_vars(const PyConfig *config) { +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS #define COPY_FLAG(ATTR, VAR) \ if (config->ATTR != -1) { \ VAR = config->ATTR; \ @@ -1485,117 +1568,7 @@ config_set_global_vars(const PyConfig *config) #undef COPY_FLAG #undef COPY_NOT_FLAG -} - - -/* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__ - environment variables on macOS if available. */ -static PyStatus -config_init_program_name(PyConfig *config) -{ - PyStatus status; - - /* If Py_SetProgramName() was called, use its value */ - const wchar_t *program_name = _Py_path_config.program_name; - if (program_name != NULL) { - config->program_name = _PyMem_RawWcsdup(program_name); - if (config->program_name == NULL) { - return _PyStatus_NO_MEMORY(); - } - return _PyStatus_OK(); - } - -#ifdef __APPLE__ - /* On MacOS X, when the Python interpreter is embedded in an - application bundle, it gets executed by a bootstrapping script - that does os.execve() with an argv[0] that's different from the - actual Python executable. This is needed to keep the Finder happy, - or rather, to work around Apple's overly strict requirements of - the process name. However, we still need a usable sys.executable, - so the actual executable path is passed in an environment variable. - See Lib/plat-mac/bundlebuilder.py for details about the bootstrap - script. */ - const char *p = config_get_env(config, "PYTHONEXECUTABLE"); - if (p != NULL) { - status = CONFIG_SET_BYTES_STR(config, &config->program_name, p, - "PYTHONEXECUTABLE environment variable"); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - return _PyStatus_OK(); - } -#ifdef WITH_NEXT_FRAMEWORK - else { - const char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__"); - if (pyvenv_launcher && *pyvenv_launcher) { - /* Used by Mac/Tools/pythonw.c to forward - * the argv0 of the stub executable - */ - status = CONFIG_SET_BYTES_STR(config, - &config->program_name, - pyvenv_launcher, - "__PYVENV_LAUNCHER__ environment variable"); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - /* - * This environment variable is used to communicate between - * the stub launcher and the real interpreter and isn't needed - * beyond this point. - * - * Clean up to avoid problems when launching other programs - * later on. - */ - (void)unsetenv("__PYVENV_LAUNCHER__"); - - return _PyStatus_OK(); - } - } -#endif /* WITH_NEXT_FRAMEWORK */ -#endif /* __APPLE__ */ - - /* Use argv[0] if available and non-empty */ - const PyWideStringList *argv = &config->argv; - if (argv->length >= 1 && argv->items[0][0] != L'\0') { - config->program_name = _PyMem_RawWcsdup(argv->items[0]); - if (config->program_name == NULL) { - return _PyStatus_NO_MEMORY(); - } - return _PyStatus_OK(); - } - - /* Last fall back: hardcoded name */ -#ifdef MS_WINDOWS - const wchar_t *default_program_name = L"python"; -#else - const wchar_t *default_program_name = L"python3"; -#endif - status = PyConfig_SetString(config, &config->program_name, - default_program_name); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - return _PyStatus_OK(); -} - -static PyStatus -config_init_executable(PyConfig *config) -{ - assert(config->executable == NULL); - - /* If Py_SetProgramFullPath() was called, use its value */ - const wchar_t *program_full_path = _Py_path_config.program_full_path; - if (program_full_path != NULL) { - PyStatus status = PyConfig_SetString(config, - &config->executable, - program_full_path); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - return _PyStatus_OK(); - } - return _PyStatus_OK(); +_Py_COMP_DIAG_POP } @@ -1617,31 +1590,14 @@ config_get_xoption_value(const PyConfig *config, wchar_t *name) } -static PyStatus -config_init_home(PyConfig *config) -{ - assert(config->home == NULL); - - /* If Py_SetPythonHome() was called, use its value */ - wchar_t *home = _Py_path_config.home; - if (home) { - PyStatus status = PyConfig_SetString(config, &config->home, home); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - return _PyStatus_OK(); - } - - return CONFIG_GET_ENV_DUP(config, &config->home, - L"PYTHONHOME", "PYTHONHOME"); -} - static PyStatus config_init_hash_seed(PyConfig *config) { + static_assert(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc), + "_Py_HashSecret_t has wrong size"); + const char *seed_text = config_get_env(config, "PYTHONHASHSEED"); - Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc)); /* Convert a text seed to a numeric one */ if (seed_text && strcmp(seed_text, "random") != 0) { const char *endptr = seed_text; @@ -1759,9 +1715,33 @@ config_read_env_vars(PyConfig *config) } } + if (config_get_env(config, "PYTHONSAFEPATH")) { + config->safe_path = 1; + } + return _PyStatus_OK(); } +static PyStatus +config_init_perf_profiling(PyConfig *config) +{ + int active = 0; + const char *env = config_get_env(config, "PYTHONPERFSUPPORT"); + if (env) { + if (_Py_str_to_int(env, &active) != 0) { + active = 0; + } + if (active) { + config->perf_profiling = 1; + } + } + const wchar_t *xoption = config_get_xoption(config, L"perf"); + if (xoption) { + config->perf_profiling = 1; + } + return _PyStatus_OK(); + +} static PyStatus config_init_tracemalloc(PyConfig *config) @@ -1807,6 +1787,52 @@ config_init_tracemalloc(PyConfig *config) return _PyStatus_OK(); } +static PyStatus +config_init_int_max_str_digits(PyConfig *config) +{ + int maxdigits; + + const char *env = config_get_env(config, "PYTHONINTMAXSTRDIGITS"); + if (env) { + bool valid = 0; + if (!_Py_str_to_int(env, &maxdigits)) { + valid = ((maxdigits == 0) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD)); + } + if (!valid) { +#define STRINGIFY(VAL) _STRINGIFY(VAL) +#define _STRINGIFY(VAL) #VAL + return _PyStatus_ERR( + "PYTHONINTMAXSTRDIGITS: invalid limit; must be >= " + STRINGIFY(_PY_LONG_MAX_STR_DIGITS_THRESHOLD) + " or 0 for unlimited."); + } + config->int_max_str_digits = maxdigits; + } + + const wchar_t *xoption = config_get_xoption(config, L"int_max_str_digits"); + if (xoption) { + const wchar_t *sep = wcschr(xoption, L'='); + bool valid = 0; + if (sep) { + if (!config_wstr_to_int(sep + 1, &maxdigits)) { + valid = ((maxdigits == 0) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD)); + } + } + if (!valid) { + return _PyStatus_ERR( + "-X int_max_str_digits: invalid limit; must be >= " + STRINGIFY(_PY_LONG_MAX_STR_DIGITS_THRESHOLD) + " or 0 for unlimited."); +#undef _STRINGIFY +#undef STRINGIFY + } + config->int_max_str_digits = maxdigits; + } + if (config->int_max_str_digits < 0) { + config->int_max_str_digits = _PY_LONG_DEFAULT_MAX_STR_DIGITS; + } + return _PyStatus_OK(); +} static PyStatus config_init_pycache_prefix(PyConfig *config) @@ -1853,7 +1879,7 @@ config_read_complex_options(PyConfig *config) if (config_get_env(config, "PYTHONNODEBUGRANGES") || config_get_xoption(config, L"no_debug_ranges")) { - config->no_debug_ranges = 1; + config->code_debug_ranges = 0; } PyStatus status; @@ -1864,6 +1890,20 @@ config_read_complex_options(PyConfig *config) } } + if (config->perf_profiling < 0) { + status = config_init_perf_profiling(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + if (config->int_max_str_digits < 0) { + status = config_init_int_max_str_digits(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + if (config->pycache_prefix == NULL) { status = config_init_pycache_prefix(config); if (_PyStatus_EXCEPTION(status)) { @@ -1911,7 +1951,13 @@ static PyStatus config_get_locale_encoding(PyConfig *config, const PyPreConfig *preconfig, wchar_t **locale_encoding) { - wchar_t *encoding = _Py_GetLocaleEncoding(); + wchar_t *encoding; + if (preconfig->utf8_mode) { + encoding = _PyMem_RawWcsdup(L"utf-8"); + } + else { + encoding = _Py_GetLocaleEncoding(); + } if (encoding == NULL) { return _PyStatus_NO_MEMORY(); } @@ -2091,44 +2137,6 @@ config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig) } -/* Determine if the current build is a "development" build (e.g. running - out of the source tree) or not. - - A return value of -1 indicates that we do not know. - */ -static int -is_dev_env(PyConfig *config) -{ - // This should only ever get called early in runtime initialization, - // before the global path config is written. Otherwise we would - // use Py_GetProgramFullPath() and _Py_GetStdlibDir(). - assert(config != NULL); - - const wchar_t *executable = config->executable; - const wchar_t *stdlib = config->stdlib_dir; - if (executable == NULL || *executable == L'\0' || - stdlib == NULL || *stdlib == L'\0') { - // _PyPathConfig_Calculate() hasn't run yet. - return -1; - } - size_t len = _Py_find_basename(executable); - if (wcscmp(executable + len, L"python") != 0 && - wcscmp(executable + len, L"python.exe") != 0) { - return 0; - } - /* If dirname() is the same for both then it is a dev build. */ - if (len != _Py_find_basename(stdlib)) { - return 0; - } - // We do not bother normalizing the two filenames first since - // for config_init_import() is does the right thing as-is. - if (wcsncmp(stdlib, executable, len) != 0) { - return 0; - } - return 1; -} - - static PyStatus config_init_import(PyConfig *config, int compute_path_config) { @@ -2140,30 +2148,25 @@ config_init_import(PyConfig *config, int compute_path_config) } /* -X frozen_modules=[on|off] */ - if (config->use_frozen_modules < 0) { - const wchar_t *value = config_get_xoption_value(config, L"frozen_modules"); - if (value == NULL) { - int isdev = is_dev_env(config); - if (isdev >= 0) { - config->use_frozen_modules = !isdev; - } - } - else if (wcscmp(value, L"on") == 0) { - config->use_frozen_modules = 1; - } - else if (wcscmp(value, L"off") == 0) { - config->use_frozen_modules = 0; - } - else if (wcslen(value) == 0) { - // "-X frozen_modules" and "-X frozen_modules=" both imply "on". - config->use_frozen_modules = 1; - } - else { - return PyStatus_Error("bad value for option -X frozen_modules " - "(expected \"on\" or \"off\")"); - } + const wchar_t *value = config_get_xoption_value(config, L"frozen_modules"); + if (value == NULL) { + } + else if (wcscmp(value, L"on") == 0) { + config->use_frozen_modules = 1; + } + else if (wcscmp(value, L"off") == 0) { + config->use_frozen_modules = 0; + } + else if (wcslen(value) == 0) { + // "-X frozen_modules" and "-X frozen_modules=" both imply "on". + config->use_frozen_modules = 1; + } + else { + return PyStatus_Error("bad value for option -X frozen_modules " + "(expected \"on\" or \"off\")"); } + assert(config->use_frozen_modules >= 0); return _PyStatus_OK(); } @@ -2173,49 +2176,6 @@ _PyConfig_InitImportConfig(PyConfig *config) return config_init_import(config, 1); } -// List of known xoptions to validate against the provided ones. Note that all -// options are listed, even if they are only available if a specific macro is -// set, like -X showrefcount which requires a debug build. In this case unknown -// options are silently ignored. -const wchar_t* known_xoptions[] = { - L"faulthandler", - L"showrefcount", - L"tracemalloc", - L"importtime", - L"dev", - L"utf8", - L"pycache_prefix", - L"warn_default_encoding", - L"no_debug_ranges", - L"frozen_modules", - NULL, -}; - -static const wchar_t* -_Py_check_xoptions(const PyWideStringList *xoptions, const wchar_t **names) -{ - for (Py_ssize_t i=0; i < xoptions->length; i++) { - const wchar_t *option = xoptions->items[i]; - size_t len; - wchar_t *sep = wcschr(option, L'='); - if (sep != NULL) { - len = (sep - option); - } - else { - len = wcslen(option); - } - int found = 0; - for (const wchar_t** name = names; *name != NULL; name++) { - if (wcsncmp(option, *name, len) == 0 && (*name)[len] == L'\0') { - found = 1; - } - } - if (found == 0) { - return option; - } - } - return NULL; -} static PyStatus config_read(PyConfig *config, int compute_path_config) @@ -2231,42 +2191,21 @@ config_read(PyConfig *config, int compute_path_config) } /* -X options */ - const wchar_t* option = _Py_check_xoptions(&config->xoptions, known_xoptions); - if (option != NULL) { - return PyStatus_Error("Unknown value for option -X"); - } - if (config_get_xoption(config, L"showrefcount")) { config->show_ref_count = 1; } +#ifdef Py_STATS + if (config_get_xoption(config, L"pystats")) { + _py_stats = &_py_stats_struct; + } +#endif + status = config_read_complex_options(config); if (_PyStatus_EXCEPTION(status)) { return status; } - if (config->home == NULL) { - status = config_init_home(config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (config->executable == NULL) { - status = config_init_executable(config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if(config->platlibdir == NULL) { - status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR, - "PLATLIBDIR macro"); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - if (config->_install_importlib) { status = config_init_import(config, compute_path_config); if (_PyStatus_EXCEPTION(status)) { @@ -2286,6 +2225,9 @@ config_read(PyConfig *config, int compute_path_config) if (config->tracemalloc < 0) { config->tracemalloc = 0; } + if (config->perf_profiling < 0) { + config->perf_profiling = 0; + } if (config->use_hash_seed < 0) { config->use_hash_seed = 0; config->hash_seed = 0; @@ -2408,15 +2350,32 @@ config_usage(int error, const wchar_t* program) if (error) fprintf(f, "Try `python -h' for more information.\n"); else { - fputs(usage_1, f); - fputs(usage_2, f); - fputs(usage_3, f); - fprintf(f, usage_4, (wint_t)DELIM); - fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP); - fputs(usage_6, f); + fputs(usage_help, f); } } +static void +config_envvars_usage() +{ + printf(usage_envvars, (wint_t)DELIM, (wint_t)DELIM, PYTHONHOMEHELP); +} + +static void +config_xoptions_usage() +{ + puts(usage_xoptions); +} + +static void +config_complete_usage(const wchar_t* program) +{ + config_usage(0, program); + puts("\n"); + config_envvars_usage(); + puts("\n"); + config_xoptions_usage(); +} + /* Parse the command line arguments */ static PyStatus @@ -2427,6 +2386,9 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, const PyWideStringList *argv = &config->argv; int print_version = 0; const wchar_t* program = config->program_name; + if (!program && argv->length >= 1) { + program = argv->items[0]; + } _PyOS_ResetGetOpt(); do { @@ -2468,9 +2430,9 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, } switch (c) { + // Integers represent long options, see Python/getopt.c case 0: - // Handle long option. - assert(longindex == 0); // Only one long option now. + // check-hash-based-pycs if (wcscmp(_PyOS_optarg, L"always") == 0 || wcscmp(_PyOS_optarg, L"never") == 0 || wcscmp(_PyOS_optarg, L"default") == 0) @@ -2488,6 +2450,21 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, } break; + case 1: + // help-all + config_complete_usage(program); + return _PyStatus_EXIT(0); + + case 2: + // help-env + config_envvars_usage(); + return _PyStatus_EXIT(0); + + case 3: + // help-xoptions + config_xoptions_usage(); + return _PyStatus_EXIT(0); + case 'b': config->bytes_warning++; break; @@ -2513,6 +2490,10 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, config->optimization_level++; break; + case 'P': + config->safe_path = 1; + break; + case 'B': config->write_bytecode = 0; break; @@ -2889,13 +2870,6 @@ config_read_cmdline(PyConfig *config) config->parse_argv = 1; } - if (config->program_name == NULL) { - status = config_init_program_name(config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - if (config->parse_argv == 1) { Py_ssize_t opt_index; status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index); @@ -3042,6 +3016,7 @@ _PyConfig_Read(PyConfig *config, int compute_path_config) assert(config->isolated >= 0); if (config->isolated) { + config->safe_path = 1; config->use_environment = 0; config->user_site_directory = 0; } @@ -3075,7 +3050,7 @@ done: PyStatus PyConfig_Read(PyConfig *config) { - return _PyConfig_Read(config, 1); + return _PyConfig_Read(config, 0); } @@ -3123,16 +3098,6 @@ _Py_GetConfigsAsDict(void) } Py_CLEAR(dict); - /* path config */ - dict = _PyPathConfig_AsDict(); - if (dict == NULL) { - goto error; - } - if (PyDict_SetItemString(result, "path_config", dict) < 0) { - goto error; - } - Py_CLEAR(dict); - return result; error: @@ -3197,7 +3162,9 @@ _Py_DumpPathConfig(PyThreadState *tstate) PySys_WriteStderr(" isolated = %i\n", config->isolated); PySys_WriteStderr(" environment = %i\n", config->use_environment); PySys_WriteStderr(" user site = %i\n", config->user_site_directory); + PySys_WriteStderr(" safe_path = %i\n", config->safe_path); PySys_WriteStderr(" import site = %i\n", config->site_import); + PySys_WriteStderr(" is in build tree = %i\n", config->_is_python_build); DUMP_CONFIG("stdlib dir", stdlib_dir); #undef DUMP_CONFIG diff --git a/Python/intrinsics.c b/Python/intrinsics.c new file mode 100644 index 00000000000..ae1775862d9 --- /dev/null +++ b/Python/intrinsics.c @@ -0,0 +1,210 @@ + +#define _PY_INTERPRETER + +#include "Python.h" +#include "pycore_frame.h" +#include "pycore_runtime.h" +#include "pycore_global_objects.h" +#include "pycore_intrinsics.h" +#include "pycore_pyerrors.h" + + + +static PyObject * +no_intrinsic(PyThreadState* tstate, PyObject *unused) +{ + _PyErr_SetString(tstate, PyExc_SystemError, "invalid intrinsic function"); + return NULL; +} + +static PyObject * +print_expr(PyThreadState* tstate, PyObject *value) +{ + PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(displayhook)); + // Can't use ERROR_IF here. + if (hook == NULL) { + _PyErr_SetString(tstate, PyExc_RuntimeError, + "lost sys.displayhook"); + return NULL; + } + return PyObject_CallOneArg(hook, value); +} + +static int +import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v) +{ + PyObject *all, *dict, *name, *value; + int skip_leading_underscores = 0; + int pos, err; + + if (_PyObject_LookupAttr(v, &_Py_ID(__all__), &all) < 0) { + return -1; /* Unexpected error */ + } + if (all == NULL) { + if (_PyObject_LookupAttr(v, &_Py_ID(__dict__), &dict) < 0) { + return -1; + } + if (dict == NULL) { + _PyErr_SetString(tstate, PyExc_ImportError, + "from-import-* object has no __dict__ and no __all__"); + return -1; + } + all = PyMapping_Keys(dict); + Py_DECREF(dict); + if (all == NULL) + return -1; + skip_leading_underscores = 1; + } + + for (pos = 0, err = 0; ; pos++) { + name = PySequence_GetItem(all, pos); + if (name == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_IndexError)) { + err = -1; + } + else { + _PyErr_Clear(tstate); + } + break; + } + if (!PyUnicode_Check(name)) { + PyObject *modname = PyObject_GetAttr(v, &_Py_ID(__name__)); + if (modname == NULL) { + Py_DECREF(name); + err = -1; + break; + } + if (!PyUnicode_Check(modname)) { + _PyErr_Format(tstate, PyExc_TypeError, + "module __name__ must be a string, not %.100s", + Py_TYPE(modname)->tp_name); + } + else { + _PyErr_Format(tstate, PyExc_TypeError, + "%s in %U.%s must be str, not %.100s", + skip_leading_underscores ? "Key" : "Item", + modname, + skip_leading_underscores ? "__dict__" : "__all__", + Py_TYPE(name)->tp_name); + } + Py_DECREF(modname); + Py_DECREF(name); + err = -1; + break; + } + if (skip_leading_underscores) { + if (PyUnicode_READY(name) == -1) { + Py_DECREF(name); + err = -1; + break; + } + if (PyUnicode_READ_CHAR(name, 0) == '_') { + Py_DECREF(name); + continue; + } + } + value = PyObject_GetAttr(v, name); + if (value == NULL) + err = -1; + else if (PyDict_CheckExact(locals)) + err = PyDict_SetItem(locals, name, value); + else + err = PyObject_SetItem(locals, name, value); + Py_DECREF(name); + Py_XDECREF(value); + if (err < 0) + break; + } + Py_DECREF(all); + return err; +} + +static PyObject * +import_star(PyThreadState* tstate, PyObject *from) +{ + _PyInterpreterFrame *frame = tstate->cframe->current_frame; + if (_PyFrame_FastToLocalsWithError(frame) < 0) { + return NULL; + } + + PyObject *locals = frame->f_locals; + if (locals == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found during 'import *'"); + return NULL; + } + int err = import_all_from(tstate, locals, from); + _PyFrame_LocalsToFast(frame, 0); + if (err < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +stopiteration_error(PyThreadState* tstate, PyObject *exc) +{ + _PyInterpreterFrame *frame = tstate->cframe->current_frame; + assert(frame->owner == FRAME_OWNED_BY_GENERATOR); + assert(PyExceptionInstance_Check(exc)); + const char *msg = NULL; + if (PyErr_GivenExceptionMatches(exc, PyExc_StopIteration)) { + msg = "generator raised StopIteration"; + if (frame->f_code->co_flags & CO_ASYNC_GENERATOR) { + msg = "async generator raised StopIteration"; + } + else if (frame->f_code->co_flags & CO_COROUTINE) { + msg = "coroutine raised StopIteration"; + } + } + else if ((frame->f_code->co_flags & CO_ASYNC_GENERATOR) && + PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) + { + /* code in `gen` raised a StopAsyncIteration error: + raise a RuntimeError. + */ + msg = "async generator raised StopAsyncIteration"; + } + if (msg != NULL) { + PyObject *message = _PyUnicode_FromASCII(msg, strlen(msg)); + if (message == NULL) { + return NULL; + } + PyObject *error = PyObject_CallOneArg(PyExc_RuntimeError, message); + if (error == NULL) { + Py_DECREF(message); + return NULL; + } + assert(PyExceptionInstance_Check(error)); + PyException_SetCause(error, Py_NewRef(exc)); + // Steal exc reference, rather than Py_NewRef+Py_DECREF + PyException_SetContext(error, Py_NewRef(exc)); + Py_DECREF(message); + return error; + } + return Py_NewRef(exc); +} + +static PyObject * +unary_pos(PyThreadState* unused, PyObject *value) +{ + return PyNumber_Positive(value); +} + +static PyObject * +list_to_tuple(PyThreadState* unused, PyObject *v) +{ + assert(PyList_Check(v)); + return _PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v)); +} + +instrinsic_func1 +_PyIntrinsics_UnaryFunctions[] = { + [0] = no_intrinsic, + [INTRINSIC_PRINT] = print_expr, + [INTRINSIC_IMPORT_STAR] = import_star, + [INTRINSIC_STOPITERATION_ERROR] = stopiteration_error, + [INTRINSIC_ASYNC_GEN_WRAP] = _PyAsyncGenValueWrapperNew, + [INTRINSIC_UNARY_POSITIVE] = unary_pos, + [INTRINSIC_LIST_TO_TUPLE] = list_to_tuple, +}; diff --git a/Python/makeopcodetargets.py b/Python/makeopcodetargets.py index 3bf2e35ccb6..33a4b4a76a1 100755 --- a/Python/makeopcodetargets.py +++ b/Python/makeopcodetargets.py @@ -34,7 +34,8 @@ def write_contents(f): targets = ['_unknown_opcode'] * 256 targets[255] = "TARGET_DO_TRACING" for opname, op in opcode.opmap.items(): - targets[op] = "TARGET_%s" % opname + if not opcode.is_pseudo(op): + targets[op] = "TARGET_%s" % opname next_op = 1 for opname in opcode._specialized_instructions: while targets[next_op] != '_unknown_opcode': diff --git a/Python/marshal.c b/Python/marshal.c index 51c77555d9e..5f392d9e1ec 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -11,9 +11,7 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_code.h" // _PyCode_New() -#include "pycore_floatobject.h" // _PyFloat_Pack8() #include "pycore_hashtable.h" // _Py_hashtable_t -#include "code.h" #include "marshal.h" // Py_MARSHAL_VERSION /*[clinic input] @@ -36,6 +34,8 @@ module marshal */ #if defined(MS_WINDOWS) #define MAX_MARSHAL_STACK_DEPTH 1000 +#elif defined(__wasi__) +#define MAX_MARSHAL_STACK_DEPTH 1500 #else #define MAX_MARSHAL_STACK_DEPTH 2000 #endif @@ -271,8 +271,8 @@ w_PyLong(const PyLongObject *ob, char flag, WFILE *p) static void w_float_bin(double v, WFILE *p) { - unsigned char buf[8]; - if (_PyFloat_Pack8(v, buf, 1) < 0) { + char buf[8]; + if (PyFloat_Pack8(v, buf, 1) < 0) { p->error = WFERR_UNMARSHALLABLE; return; } @@ -300,9 +300,14 @@ w_ref(PyObject *v, char *flag, WFILE *p) if (p->version < 3 || p->hashtable == NULL) return 0; /* not writing object references */ - /* if it has only one reference, it definitely isn't shared */ - if (Py_REFCNT(v) == 1) + /* If it has only one reference, it definitely isn't shared. + * But we use TYPE_REF always for interned string, to PYC file stable + * as possible. + */ + if (Py_REFCNT(v) == 1 && + !(PyUnicode_CheckExact(v) && PyUnicode_CHECK_INTERNED(v))) { return 0; + } entry = _Py_hashtable_get_entry(p->hashtable, v); if (entry != NULL) { @@ -321,8 +326,8 @@ w_ref(PyObject *v, char *flag, WFILE *p) goto err; } w = (int)s; - Py_INCREF(v); - if (_Py_hashtable_set(p->hashtable, v, (void *)(uintptr_t)w) < 0) { + if (_Py_hashtable_set(p->hashtable, Py_NewRef(v), + (void *)(uintptr_t)w) < 0) { Py_DECREF(v); goto err; } @@ -545,13 +550,18 @@ w_complex_object(PyObject *v, char flag, WFILE *p) } else if (PyCode_Check(v)) { PyCodeObject *co = (PyCodeObject *)v; + PyObject *co_code = _PyCode_GetCode(co); + if (co_code == NULL) { + p->error = WFERR_NOMEMORY; + return; + } W_TYPE(TYPE_CODE, p); w_long(co->co_argcount, p); w_long(co->co_posonlyargcount, p); w_long(co->co_kwonlyargcount, p); w_long(co->co_stacksize, p); w_long(co->co_flags, p); - w_object(co->co_code, p); + w_object(co_code, p); w_object(co->co_consts, p); w_object(co->co_names, p); w_object(co->co_localsplusnames, p); @@ -561,9 +571,8 @@ w_complex_object(PyObject *v, char flag, WFILE *p) w_object(co->co_qualname, p); w_long(co->co_firstlineno, p); w_object(co->co_linetable, p); - w_object(co->co_endlinetable, p); - w_object(co->co_columntable, p); w_object(co->co_exceptiontable, p); + Py_DECREF(co_code); } else if (PyObject_CheckBuffer(v)) { /* Write unknown bytes-like objects as a bytes object */ @@ -703,7 +712,6 @@ r_string(Py_ssize_t n, RFILE *p) read = fread(p->buf, 1, n, p->fp); } else { - _Py_IDENTIFIER(readinto); PyObject *res, *mview; Py_buffer buf; @@ -713,7 +721,7 @@ r_string(Py_ssize_t n, RFILE *p) if (mview == NULL) return NULL; - res = _PyObject_CallMethodId(p->readable, &PyId_readinto, "N", mview); + res = _PyObject_CallMethod(p->readable, &_Py_ID(readinto), "N", mview); if (res != NULL) { read = PyNumber_AsSsize_t(res, PyExc_ValueError); Py_DECREF(res); @@ -884,10 +892,10 @@ r_PyLong(RFILE *p) static double r_float_bin(RFILE *p) { - const unsigned char *buf = (const unsigned char *) r_string(8, p); + const char *buf = r_string(8, p); if (buf == NULL) return -1; - return _PyFloat_Unpack8(buf, 1); + return PyFloat_Unpack8(buf, 1); } /* Issue #33720: Disable inlining for reducing the C stack consumption @@ -943,8 +951,7 @@ r_ref_insert(PyObject *o, Py_ssize_t idx, int flag, RFILE *p) { if (o != NULL && flag) { /* currently only FLAG_REF is defined */ PyObject *tmp = PyList_GET_ITEM(p->refs, idx); - Py_INCREF(o); - PyList_SET_ITEM(p->refs, idx, o); + PyList_SET_ITEM(p->refs, idx, Py_NewRef(o)); Py_DECREF(tmp); } return o; @@ -1007,28 +1014,23 @@ r_object(RFILE *p) break; case TYPE_NONE: - Py_INCREF(Py_None); - retval = Py_None; + retval = Py_NewRef(Py_None); break; case TYPE_STOPITER: - Py_INCREF(PyExc_StopIteration); - retval = PyExc_StopIteration; + retval = Py_NewRef(PyExc_StopIteration); break; case TYPE_ELLIPSIS: - Py_INCREF(Py_Ellipsis); - retval = Py_Ellipsis; + retval = Py_NewRef(Py_Ellipsis); break; case TYPE_FALSE: - Py_INCREF(Py_False); - retval = Py_False; + retval = Py_NewRef(Py_False); break; case TYPE_TRUE: - Py_INCREF(Py_True); - retval = Py_True; + retval = Py_NewRef(Py_True); break; case TYPE_INT: @@ -1215,8 +1217,7 @@ r_object(RFILE *p) if (!PyErr_Occurred()) PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for tuple"); - Py_DECREF(v); - v = NULL; + Py_SETREF(v, NULL); break; } PyTuple_SET_ITEM(v, i, v2); @@ -1242,8 +1243,7 @@ r_object(RFILE *p) if (!PyErr_Occurred()) PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for list"); - Py_DECREF(v); - v = NULL; + Py_SETREF(v, NULL); break; } PyList_SET_ITEM(v, i, v2); @@ -1275,8 +1275,7 @@ r_object(RFILE *p) Py_DECREF(val); } if (PyErr_Occurred()) { - Py_DECREF(v); - v = NULL; + Py_SETREF(v, NULL); } retval = v; break; @@ -1320,8 +1319,7 @@ r_object(RFILE *p) if (!PyErr_Occurred()) PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for set"); - Py_DECREF(v); - v = NULL; + Py_SETREF(v, NULL); break; } if (PySet_Add(v, v2) == -1) { @@ -1354,9 +1352,7 @@ r_object(RFILE *p) PyObject *name = NULL; PyObject *qualname = NULL; int firstlineno; - PyObject *linetable = NULL; - PyObject* endlinetable = NULL; - PyObject* columntable = NULL; + PyObject* linetable = NULL; PyObject *exceptiontable = NULL; idx = r_ref_reserve(flag, p); @@ -1412,12 +1408,6 @@ r_object(RFILE *p) linetable = r_object(p); if (linetable == NULL) goto code_error; - endlinetable = r_object(p); - if (endlinetable == NULL) - goto code_error; - columntable = r_object(p); - if (columntable == NULL) - goto code_error; exceptiontable = r_object(p); if (exceptiontable == NULL) goto code_error; @@ -1431,8 +1421,6 @@ r_object(RFILE *p) .code = code, .firstlineno = firstlineno, .linetable = linetable, - .endlinetable = endlinetable, - .columntable = columntable, .consts = consts, .names = names, @@ -1470,8 +1458,6 @@ r_object(RFILE *p) Py_XDECREF(name); Py_XDECREF(qualname); Py_XDECREF(linetable); - Py_XDECREF(endlinetable); - Py_XDECREF(columntable); Py_XDECREF(exceptiontable); } retval = v; @@ -1490,8 +1476,7 @@ r_object(RFILE *p) PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)"); break; } - Py_INCREF(v); - retval = v; + retval = Py_NewRef(v); break; default: @@ -1713,12 +1698,11 @@ marshal_dump_impl(PyObject *module, PyObject *value, PyObject *file, /* XXX Quick hack -- need to do this differently */ PyObject *s; PyObject *res; - _Py_IDENTIFIER(write); s = PyMarshal_WriteObjectToString(value, version); if (s == NULL) return NULL; - res = _PyObject_CallMethodIdOneArg(file, &PyId_write, s); + res = _PyObject_CallMethodOneArg(file, &_Py_ID(write), s); Py_DECREF(s); return res; } @@ -1745,7 +1729,6 @@ marshal_load(PyObject *module, PyObject *file) /*[clinic end generated code: output=f8e5c33233566344 input=c85c2b594cd8124a]*/ { PyObject *data, *result; - _Py_IDENTIFIER(read); RFILE rf; /* @@ -1755,7 +1738,7 @@ marshal_load(PyObject *module, PyObject *file) * This can be removed if we guarantee good error handling * for r_string() */ - data = _PyObject_CallMethodId(file, &PyId_read, "i", 0); + data = _PyObject_CallMethod(file, &_Py_ID(read), "i", 0); if (data == NULL) return NULL; if (!PyBytes_Check(data)) { diff --git a/Python/modsupport.c b/Python/modsupport.c index 8655daa1fc5..b9a10dc157e 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -10,9 +10,6 @@ typedef double va_double; static PyObject *va_build_value(const char *, va_list, int); static PyObject **va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, const char *, va_list, int, Py_ssize_t*); -/* Package context -- the full module name for package imports */ -const char *_Py_PackageContext = NULL; - int _Py_convert_optional_to_ssize_t(PyObject *obj, void *result) @@ -359,8 +356,7 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) else n = -1; if (u == NULL) { - v = Py_None; - Py_INCREF(v); + v = Py_NewRef(Py_None); } else { if (n < 0) @@ -410,8 +406,7 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) else n = -1; if (str == NULL) { - v = Py_None; - Py_INCREF(v); + v = Py_NewRef(Py_None); } else { if (n < 0) { @@ -446,8 +441,7 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) else n = -1; if (str == NULL) { - v = Py_None; - Py_INCREF(v); + v = Py_NewRef(Py_None); } else { if (n < 0) { diff --git a/Python/mysnprintf.c b/Python/mysnprintf.c index cd69198011e..2a505d14f82 100644 --- a/Python/mysnprintf.c +++ b/Python/mysnprintf.c @@ -9,6 +9,7 @@ would have been written had the buffer not been too small, and to set the last byte of the buffer to \0. At least MS _vsnprintf returns a negative value instead, and fills the entire buffer with non-\0 data. + Unlike C99, our wrappers do not support passing a null buffer. The wrappers ensure that str[size-1] is always \0 upon return. diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h new file mode 100644 index 00000000000..e76ddda2f02 --- /dev/null +++ b/Python/opcode_metadata.h @@ -0,0 +1,873 @@ +// This file is generated by Tools/cases_generator/generate_cases.py --metadata +// from Python/bytecodes.c +// Do not edit! + +#ifndef NDEBUG +static int +_PyOpcode_num_popped(int opcode, int oparg) { + switch(opcode) { + case NOP: + return 0; + case RESUME: + return 0; + case LOAD_CLOSURE: + return 0; + case LOAD_FAST_CHECK: + return 0; + case LOAD_FAST: + return 0; + case LOAD_CONST: + return 0; + case STORE_FAST: + return 1; + case LOAD_FAST__LOAD_FAST: + return 0+0; + case LOAD_FAST__LOAD_CONST: + return 0+0; + case STORE_FAST__LOAD_FAST: + return 1+0; + case STORE_FAST__STORE_FAST: + return 1+1; + case LOAD_CONST__LOAD_FAST: + return 0+0; + case POP_TOP: + return 1; + case PUSH_NULL: + return 0; + case END_FOR: + return 1+1; + case UNARY_NEGATIVE: + return 1; + case UNARY_NOT: + return 1; + case UNARY_INVERT: + return 1; + case BINARY_OP_MULTIPLY_INT: + return 2; + case BINARY_OP_MULTIPLY_FLOAT: + return 2; + case BINARY_OP_SUBTRACT_INT: + return 2; + case BINARY_OP_SUBTRACT_FLOAT: + return 2; + case BINARY_OP_ADD_UNICODE: + return 2; + case BINARY_OP_INPLACE_ADD_UNICODE: + return 2; + case BINARY_OP_ADD_FLOAT: + return 2; + case BINARY_OP_ADD_INT: + return 2; + case BINARY_SUBSCR: + return 2; + case BINARY_SLICE: + return 3; + case STORE_SLICE: + return 4; + case BINARY_SUBSCR_LIST_INT: + return 2; + case BINARY_SUBSCR_TUPLE_INT: + return 2; + case BINARY_SUBSCR_DICT: + return 2; + case BINARY_SUBSCR_GETITEM: + return 2; + case LIST_APPEND: + return (oparg-1) + 2; + case SET_ADD: + return (oparg-1) + 2; + case STORE_SUBSCR: + return 3; + case STORE_SUBSCR_LIST_INT: + return 3; + case STORE_SUBSCR_DICT: + return 3; + case DELETE_SUBSCR: + return 2; + case CALL_INTRINSIC_1: + return 1; + case RAISE_VARARGS: + return oparg; + case INTERPRETER_EXIT: + return 1; + case RETURN_VALUE: + return 1; + case GET_AITER: + return 1; + case GET_ANEXT: + return 1; + case GET_AWAITABLE: + return 1; + case SEND: + return -1; + case YIELD_VALUE: + return 1; + case POP_EXCEPT: + return 1; + case RERAISE: + return -1; + case PREP_RERAISE_STAR: + return 2; + case END_ASYNC_FOR: + return -1; + case CLEANUP_THROW: + return -1; + case LOAD_ASSERTION_ERROR: + return 0; + case LOAD_BUILD_CLASS: + return 0; + case STORE_NAME: + return 1; + case DELETE_NAME: + return 0; + case UNPACK_SEQUENCE: + return -1; + case UNPACK_SEQUENCE_TWO_TUPLE: + return -1; + case UNPACK_SEQUENCE_TUPLE: + return -1; + case UNPACK_SEQUENCE_LIST: + return -1; + case UNPACK_EX: + return -1; + case STORE_ATTR: + return 2; + case DELETE_ATTR: + return 1; + case STORE_GLOBAL: + return 1; + case DELETE_GLOBAL: + return 0; + case LOAD_NAME: + return 0; + case LOAD_GLOBAL: + return -1; + case LOAD_GLOBAL_MODULE: + return -1; + case LOAD_GLOBAL_BUILTIN: + return -1; + case DELETE_FAST: + return 0; + case MAKE_CELL: + return 0; + case DELETE_DEREF: + return 0; + case LOAD_CLASSDEREF: + return 0; + case LOAD_DEREF: + return 0; + case STORE_DEREF: + return 1; + case COPY_FREE_VARS: + return 0; + case BUILD_STRING: + return oparg; + case BUILD_TUPLE: + return oparg; + case BUILD_LIST: + return oparg; + case LIST_EXTEND: + return (oparg-1) + 2; + case SET_UPDATE: + return (oparg-1) + 2; + case BUILD_SET: + return oparg; + case BUILD_MAP: + return oparg*2; + case SETUP_ANNOTATIONS: + return 0; + case BUILD_CONST_KEY_MAP: + return oparg + 1; + case DICT_UPDATE: + return 1; + case DICT_MERGE: + return 1; + case MAP_ADD: + return 2; + case LOAD_ATTR: + return 1; + case LOAD_ATTR_INSTANCE_VALUE: + return -1; + case LOAD_ATTR_MODULE: + return -1; + case LOAD_ATTR_WITH_HINT: + return -1; + case LOAD_ATTR_SLOT: + return -1; + case LOAD_ATTR_CLASS: + return -1; + case LOAD_ATTR_PROPERTY: + return -1; + case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN: + return -1; + case STORE_ATTR_INSTANCE_VALUE: + return 2; + case STORE_ATTR_WITH_HINT: + return 2; + case STORE_ATTR_SLOT: + return 2; + case COMPARE_OP: + return 2; + case COMPARE_AND_BRANCH: + return 2; + case COMPARE_AND_BRANCH_FLOAT: + return 2; + case COMPARE_AND_BRANCH_INT: + return 2; + case COMPARE_AND_BRANCH_STR: + return 2; + case IS_OP: + return 2; + case CONTAINS_OP: + return 2; + case CHECK_EG_MATCH: + return 2; + case CHECK_EXC_MATCH: + return 2; + case IMPORT_NAME: + return 2; + case IMPORT_FROM: + return 1; + case JUMP_FORWARD: + return 0; + case JUMP_BACKWARD: + return 0; + case POP_JUMP_IF_FALSE: + return -1; + case POP_JUMP_IF_TRUE: + return -1; + case POP_JUMP_IF_NOT_NONE: + return -1; + case POP_JUMP_IF_NONE: + return -1; + case JUMP_IF_FALSE_OR_POP: + return -1; + case JUMP_IF_TRUE_OR_POP: + return -1; + case JUMP_BACKWARD_NO_INTERRUPT: + return -1; + case GET_LEN: + return -1; + case MATCH_CLASS: + return 3; + case MATCH_MAPPING: + return 1; + case MATCH_SEQUENCE: + return 1; + case MATCH_KEYS: + return 2; + case GET_ITER: + return -1; + case GET_YIELD_FROM_ITER: + return -1; + case FOR_ITER: + return -1; + case FOR_ITER_LIST: + return -1; + case FOR_ITER_TUPLE: + return -1; + case FOR_ITER_RANGE: + return -1; + case FOR_ITER_GEN: + return -1; + case BEFORE_ASYNC_WITH: + return -1; + case BEFORE_WITH: + return -1; + case WITH_EXCEPT_START: + return 4; + case PUSH_EXC_INFO: + return -1; + case LOAD_ATTR_METHOD_WITH_VALUES: + return -1; + case LOAD_ATTR_METHOD_NO_DICT: + return -1; + case LOAD_ATTR_METHOD_LAZY_DICT: + return -1; + case CALL_BOUND_METHOD_EXACT_ARGS: + return -1; + case KW_NAMES: + return -1; + case CALL: + return -1; + case CALL_PY_EXACT_ARGS: + return -1; + case CALL_PY_WITH_DEFAULTS: + return -1; + case CALL_NO_KW_TYPE_1: + return -1; + case CALL_NO_KW_STR_1: + return -1; + case CALL_NO_KW_TUPLE_1: + return -1; + case CALL_BUILTIN_CLASS: + return -1; + case CALL_NO_KW_BUILTIN_O: + return -1; + case CALL_NO_KW_BUILTIN_FAST: + return -1; + case CALL_BUILTIN_FAST_WITH_KEYWORDS: + return -1; + case CALL_NO_KW_LEN: + return -1; + case CALL_NO_KW_ISINSTANCE: + return -1; + case CALL_NO_KW_LIST_APPEND: + return -1; + case CALL_NO_KW_METHOD_DESCRIPTOR_O: + return -1; + case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: + return -1; + case CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS: + return -1; + case CALL_NO_KW_METHOD_DESCRIPTOR_FAST: + return -1; + case CALL_FUNCTION_EX: + return -1; + case MAKE_FUNCTION: + return -1; + case RETURN_GENERATOR: + return -1; + case BUILD_SLICE: + return -1; + case FORMAT_VALUE: + return -1; + case COPY: + return -1; + case BINARY_OP: + return 2; + case SWAP: + return -1; + case EXTENDED_ARG: + return -1; + case CACHE: + return -1; + default: + Py_UNREACHABLE(); + } +} +#endif + +#ifndef NDEBUG +static int +_PyOpcode_num_pushed(int opcode, int oparg) { + switch(opcode) { + case NOP: + return 0; + case RESUME: + return 0; + case LOAD_CLOSURE: + return 1; + case LOAD_FAST_CHECK: + return 1; + case LOAD_FAST: + return 1; + case LOAD_CONST: + return 1; + case STORE_FAST: + return 0; + case LOAD_FAST__LOAD_FAST: + return 1+1; + case LOAD_FAST__LOAD_CONST: + return 1+1; + case STORE_FAST__LOAD_FAST: + return 0+1; + case STORE_FAST__STORE_FAST: + return 0+0; + case LOAD_CONST__LOAD_FAST: + return 1+1; + case POP_TOP: + return 0; + case PUSH_NULL: + return 1; + case END_FOR: + return 0+0; + case UNARY_NEGATIVE: + return 1; + case UNARY_NOT: + return 1; + case UNARY_INVERT: + return 1; + case BINARY_OP_MULTIPLY_INT: + return 1; + case BINARY_OP_MULTIPLY_FLOAT: + return 1; + case BINARY_OP_SUBTRACT_INT: + return 1; + case BINARY_OP_SUBTRACT_FLOAT: + return 1; + case BINARY_OP_ADD_UNICODE: + return 1; + case BINARY_OP_INPLACE_ADD_UNICODE: + return 0; + case BINARY_OP_ADD_FLOAT: + return 1; + case BINARY_OP_ADD_INT: + return 1; + case BINARY_SUBSCR: + return 1; + case BINARY_SLICE: + return 1; + case STORE_SLICE: + return 0; + case BINARY_SUBSCR_LIST_INT: + return 1; + case BINARY_SUBSCR_TUPLE_INT: + return 1; + case BINARY_SUBSCR_DICT: + return 1; + case BINARY_SUBSCR_GETITEM: + return 1; + case LIST_APPEND: + return (oparg-1) + 1; + case SET_ADD: + return (oparg-1) + 1; + case STORE_SUBSCR: + return 0; + case STORE_SUBSCR_LIST_INT: + return 0; + case STORE_SUBSCR_DICT: + return 0; + case DELETE_SUBSCR: + return 0; + case CALL_INTRINSIC_1: + return 1; + case RAISE_VARARGS: + return 0; + case INTERPRETER_EXIT: + return 0; + case RETURN_VALUE: + return 0; + case GET_AITER: + return 1; + case GET_ANEXT: + return 2; + case GET_AWAITABLE: + return 1; + case SEND: + return -1; + case YIELD_VALUE: + return 1; + case POP_EXCEPT: + return 0; + case RERAISE: + return -1; + case PREP_RERAISE_STAR: + return 1; + case END_ASYNC_FOR: + return -1; + case CLEANUP_THROW: + return -1; + case LOAD_ASSERTION_ERROR: + return 1; + case LOAD_BUILD_CLASS: + return 1; + case STORE_NAME: + return 0; + case DELETE_NAME: + return 0; + case UNPACK_SEQUENCE: + return -1; + case UNPACK_SEQUENCE_TWO_TUPLE: + return -1; + case UNPACK_SEQUENCE_TUPLE: + return -1; + case UNPACK_SEQUENCE_LIST: + return -1; + case UNPACK_EX: + return -1; + case STORE_ATTR: + return 0; + case DELETE_ATTR: + return 0; + case STORE_GLOBAL: + return 0; + case DELETE_GLOBAL: + return 0; + case LOAD_NAME: + return 1; + case LOAD_GLOBAL: + return -1; + case LOAD_GLOBAL_MODULE: + return -1; + case LOAD_GLOBAL_BUILTIN: + return -1; + case DELETE_FAST: + return 0; + case MAKE_CELL: + return 0; + case DELETE_DEREF: + return 0; + case LOAD_CLASSDEREF: + return 1; + case LOAD_DEREF: + return 1; + case STORE_DEREF: + return 0; + case COPY_FREE_VARS: + return 0; + case BUILD_STRING: + return 1; + case BUILD_TUPLE: + return 1; + case BUILD_LIST: + return 1; + case LIST_EXTEND: + return (oparg-1) + 1; + case SET_UPDATE: + return (oparg-1) + 1; + case BUILD_SET: + return 1; + case BUILD_MAP: + return 1; + case SETUP_ANNOTATIONS: + return 0; + case BUILD_CONST_KEY_MAP: + return 1; + case DICT_UPDATE: + return 0; + case DICT_MERGE: + return 0; + case MAP_ADD: + return 0; + case LOAD_ATTR: + return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_ATTR_INSTANCE_VALUE: + return -1; + case LOAD_ATTR_MODULE: + return -1; + case LOAD_ATTR_WITH_HINT: + return -1; + case LOAD_ATTR_SLOT: + return -1; + case LOAD_ATTR_CLASS: + return -1; + case LOAD_ATTR_PROPERTY: + return -1; + case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN: + return -1; + case STORE_ATTR_INSTANCE_VALUE: + return 0; + case STORE_ATTR_WITH_HINT: + return 0; + case STORE_ATTR_SLOT: + return 0; + case COMPARE_OP: + return 1; + case COMPARE_AND_BRANCH: + return 0; + case COMPARE_AND_BRANCH_FLOAT: + return 0; + case COMPARE_AND_BRANCH_INT: + return 0; + case COMPARE_AND_BRANCH_STR: + return 0; + case IS_OP: + return 1; + case CONTAINS_OP: + return 1; + case CHECK_EG_MATCH: + return 2; + case CHECK_EXC_MATCH: + return 2; + case IMPORT_NAME: + return 1; + case IMPORT_FROM: + return 2; + case JUMP_FORWARD: + return 0; + case JUMP_BACKWARD: + return 0; + case POP_JUMP_IF_FALSE: + return -1; + case POP_JUMP_IF_TRUE: + return -1; + case POP_JUMP_IF_NOT_NONE: + return -1; + case POP_JUMP_IF_NONE: + return -1; + case JUMP_IF_FALSE_OR_POP: + return -1; + case JUMP_IF_TRUE_OR_POP: + return -1; + case JUMP_BACKWARD_NO_INTERRUPT: + return -1; + case GET_LEN: + return -1; + case MATCH_CLASS: + return 1; + case MATCH_MAPPING: + return 2; + case MATCH_SEQUENCE: + return 2; + case MATCH_KEYS: + return 3; + case GET_ITER: + return -1; + case GET_YIELD_FROM_ITER: + return -1; + case FOR_ITER: + return -1; + case FOR_ITER_LIST: + return -1; + case FOR_ITER_TUPLE: + return -1; + case FOR_ITER_RANGE: + return -1; + case FOR_ITER_GEN: + return -1; + case BEFORE_ASYNC_WITH: + return -1; + case BEFORE_WITH: + return -1; + case WITH_EXCEPT_START: + return 5; + case PUSH_EXC_INFO: + return -1; + case LOAD_ATTR_METHOD_WITH_VALUES: + return -1; + case LOAD_ATTR_METHOD_NO_DICT: + return -1; + case LOAD_ATTR_METHOD_LAZY_DICT: + return -1; + case CALL_BOUND_METHOD_EXACT_ARGS: + return -1; + case KW_NAMES: + return -1; + case CALL: + return -1; + case CALL_PY_EXACT_ARGS: + return -1; + case CALL_PY_WITH_DEFAULTS: + return -1; + case CALL_NO_KW_TYPE_1: + return -1; + case CALL_NO_KW_STR_1: + return -1; + case CALL_NO_KW_TUPLE_1: + return -1; + case CALL_BUILTIN_CLASS: + return -1; + case CALL_NO_KW_BUILTIN_O: + return -1; + case CALL_NO_KW_BUILTIN_FAST: + return -1; + case CALL_BUILTIN_FAST_WITH_KEYWORDS: + return -1; + case CALL_NO_KW_LEN: + return -1; + case CALL_NO_KW_ISINSTANCE: + return -1; + case CALL_NO_KW_LIST_APPEND: + return -1; + case CALL_NO_KW_METHOD_DESCRIPTOR_O: + return -1; + case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: + return -1; + case CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS: + return -1; + case CALL_NO_KW_METHOD_DESCRIPTOR_FAST: + return -1; + case CALL_FUNCTION_EX: + return -1; + case MAKE_FUNCTION: + return -1; + case RETURN_GENERATOR: + return -1; + case BUILD_SLICE: + return -1; + case FORMAT_VALUE: + return -1; + case COPY: + return -1; + case BINARY_OP: + return 1; + case SWAP: + return -1; + case EXTENDED_ARG: + return -1; + case CACHE: + return -1; + default: + Py_UNREACHABLE(); + } +} +#endif +enum Direction { DIR_NONE, DIR_READ, DIR_WRITE }; +enum InstructionFormat { INSTR_FMT_IB, INSTR_FMT_IBC, INSTR_FMT_IBC0, INSTR_FMT_IBC000, INSTR_FMT_IBC00000000, INSTR_FMT_IBIB, INSTR_FMT_IX, INSTR_FMT_IXC, INSTR_FMT_IXC000 }; +struct opcode_metadata { + enum Direction dir_op1; + enum Direction dir_op2; + enum Direction dir_op3; + bool valid_entry; + enum InstructionFormat instr_format; +} _PyOpcode_opcode_metadata[256] = { + [NOP] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [RESUME] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_CLOSURE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_FAST_CHECK] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_CONST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [STORE_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_FAST__LOAD_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBIB }, + [LOAD_FAST__LOAD_CONST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBIB }, + [STORE_FAST__LOAD_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBIB }, + [STORE_FAST__STORE_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBIB }, + [LOAD_CONST__LOAD_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBIB }, + [POP_TOP] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [PUSH_NULL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [END_FOR] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [UNARY_NEGATIVE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [UNARY_NOT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [UNARY_INVERT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [BINARY_OP_MULTIPLY_INT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC }, + [BINARY_OP_MULTIPLY_FLOAT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC }, + [BINARY_OP_SUBTRACT_INT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC }, + [BINARY_OP_SUBTRACT_FLOAT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC }, + [BINARY_OP_ADD_UNICODE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC }, + [BINARY_OP_INPLACE_ADD_UNICODE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [BINARY_OP_ADD_FLOAT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC }, + [BINARY_OP_ADD_INT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC }, + [BINARY_SUBSCR] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC000 }, + [BINARY_SLICE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [STORE_SLICE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [BINARY_SUBSCR_LIST_INT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC000 }, + [BINARY_SUBSCR_TUPLE_INT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC000 }, + [BINARY_SUBSCR_DICT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC000 }, + [BINARY_SUBSCR_GETITEM] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC000 }, + [LIST_APPEND] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [SET_ADD] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [STORE_SUBSCR] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC }, + [STORE_SUBSCR_LIST_INT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC }, + [STORE_SUBSCR_DICT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC }, + [DELETE_SUBSCR] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [CALL_INTRINSIC_1] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [RAISE_VARARGS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [INTERPRETER_EXIT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [RETURN_VALUE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [GET_AITER] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [GET_ANEXT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [GET_AWAITABLE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [SEND] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [YIELD_VALUE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [POP_EXCEPT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [RERAISE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [PREP_RERAISE_STAR] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [END_ASYNC_FOR] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [CLEANUP_THROW] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [LOAD_ASSERTION_ERROR] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [LOAD_BUILD_CLASS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [STORE_NAME] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [DELETE_NAME] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [UNPACK_SEQUENCE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [UNPACK_SEQUENCE_TWO_TUPLE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [UNPACK_SEQUENCE_TUPLE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [UNPACK_SEQUENCE_LIST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [UNPACK_EX] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [STORE_ATTR] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC000 }, + [DELETE_ATTR] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [STORE_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [DELETE_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_NAME] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_GLOBAL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_GLOBAL_MODULE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_GLOBAL_BUILTIN] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [DELETE_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [MAKE_CELL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [DELETE_DEREF] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_CLASSDEREF] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_DEREF] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [STORE_DEREF] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [COPY_FREE_VARS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [BUILD_STRING] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [BUILD_TUPLE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [BUILD_LIST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LIST_EXTEND] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [SET_UPDATE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [BUILD_SET] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [BUILD_MAP] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [SETUP_ANNOTATIONS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [BUILD_CONST_KEY_MAP] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [DICT_UPDATE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [DICT_MERGE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [MAP_ADD] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_ATTR] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC00000000 }, + [LOAD_ATTR_INSTANCE_VALUE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_ATTR_MODULE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_ATTR_WITH_HINT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_ATTR_SLOT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_ATTR_CLASS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_ATTR_PROPERTY] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [STORE_ATTR_INSTANCE_VALUE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC000 }, + [STORE_ATTR_WITH_HINT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC000 }, + [STORE_ATTR_SLOT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IXC000 }, + [COMPARE_OP] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC }, + [COMPARE_AND_BRANCH] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0 }, + [COMPARE_AND_BRANCH_FLOAT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0 }, + [COMPARE_AND_BRANCH_INT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0 }, + [COMPARE_AND_BRANCH_STR] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC0 }, + [IS_OP] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CONTAINS_OP] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CHECK_EG_MATCH] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [CHECK_EXC_MATCH] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [IMPORT_NAME] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [IMPORT_FROM] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [JUMP_FORWARD] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [JUMP_BACKWARD] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [POP_JUMP_IF_FALSE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [POP_JUMP_IF_TRUE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [POP_JUMP_IF_NOT_NONE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [POP_JUMP_IF_NONE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [JUMP_IF_FALSE_OR_POP] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [JUMP_IF_TRUE_OR_POP] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [JUMP_BACKWARD_NO_INTERRUPT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [GET_LEN] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [MATCH_CLASS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [MATCH_MAPPING] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [MATCH_SEQUENCE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [MATCH_KEYS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [GET_ITER] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [GET_YIELD_FROM_ITER] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [FOR_ITER] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [FOR_ITER_LIST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [FOR_ITER_TUPLE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [FOR_ITER_RANGE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [FOR_ITER_GEN] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [BEFORE_ASYNC_WITH] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [BEFORE_WITH] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [WITH_EXCEPT_START] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [PUSH_EXC_INFO] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [LOAD_ATTR_METHOD_WITH_VALUES] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [LOAD_ATTR_METHOD_NO_DICT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [LOAD_ATTR_METHOD_LAZY_DICT] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [CALL_BOUND_METHOD_EXACT_ARGS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [KW_NAMES] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_PY_EXACT_ARGS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_PY_WITH_DEFAULTS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_NO_KW_TYPE_1] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_NO_KW_STR_1] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_NO_KW_TUPLE_1] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_BUILTIN_CLASS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_NO_KW_BUILTIN_O] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_NO_KW_BUILTIN_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_NO_KW_LEN] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_NO_KW_ISINSTANCE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_NO_KW_LIST_APPEND] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_NO_KW_METHOD_DESCRIPTOR_O] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CALL_FUNCTION_EX] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [MAKE_FUNCTION] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [RETURN_GENERATOR] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, + [BUILD_SLICE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [FORMAT_VALUE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [COPY] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [BINARY_OP] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IBC }, + [SWAP] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [EXTENDED_ARG] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IB }, + [CACHE] = { DIR_NONE, DIR_NONE, DIR_NONE, true, INSTR_FMT_IX }, +}; diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 903b967c3a5..f1c3f3e0c4e 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -1,93 +1,93 @@ static void *opcode_targets[256] = { - &&_unknown_opcode, + &&TARGET_CACHE, &&TARGET_POP_TOP, - &&TARGET_ROT_TWO, - &&TARGET_ROT_THREE, - &&TARGET_DUP_TOP, - &&TARGET_DUP_TOP_TWO, - &&TARGET_ROT_FOUR, - &&TARGET_BINARY_OP_ADAPTIVE, + &&TARGET_PUSH_NULL, + &&TARGET_INTERPRETER_EXIT, + &&TARGET_END_FOR, + &&TARGET_BINARY_OP_ADD_FLOAT, &&TARGET_BINARY_OP_ADD_INT, + &&TARGET_BINARY_OP_ADD_UNICODE, + &&TARGET_BINARY_OP_INPLACE_ADD_UNICODE, &&TARGET_NOP, - &&TARGET_UNARY_POSITIVE, + &&TARGET_BINARY_OP_MULTIPLY_FLOAT, &&TARGET_UNARY_NEGATIVE, &&TARGET_UNARY_NOT, - &&TARGET_BINARY_OP_ADD_FLOAT, - &&TARGET_BINARY_OP_ADD_UNICODE, - &&TARGET_UNARY_INVERT, - &&TARGET_BINARY_OP_INPLACE_ADD_UNICODE, &&TARGET_BINARY_OP_MULTIPLY_INT, - &&TARGET_BINARY_OP_MULTIPLY_FLOAT, - &&TARGET_BINARY_OP_SUBTRACT_INT, &&TARGET_BINARY_OP_SUBTRACT_FLOAT, - &&TARGET_BINARY_SUBSCR_ADAPTIVE, + &&TARGET_UNARY_INVERT, + &&TARGET_BINARY_OP_SUBTRACT_INT, + &&TARGET_BINARY_SUBSCR_DICT, &&TARGET_BINARY_SUBSCR_GETITEM, &&TARGET_BINARY_SUBSCR_LIST_INT, &&TARGET_BINARY_SUBSCR_TUPLE_INT, + &&TARGET_CALL_PY_EXACT_ARGS, + &&TARGET_CALL_PY_WITH_DEFAULTS, + &&TARGET_CALL_BOUND_METHOD_EXACT_ARGS, + &&TARGET_CALL_BUILTIN_CLASS, &&TARGET_BINARY_SUBSCR, - &&TARGET_BINARY_SUBSCR_DICT, - &&TARGET_STORE_SUBSCR_ADAPTIVE, - &&TARGET_STORE_SUBSCR_LIST_INT, - &&TARGET_STORE_SUBSCR_DICT, + &&TARGET_BINARY_SLICE, + &&TARGET_STORE_SLICE, + &&TARGET_CALL_BUILTIN_FAST_WITH_KEYWORDS, + &&TARGET_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, &&TARGET_GET_LEN, &&TARGET_MATCH_MAPPING, &&TARGET_MATCH_SEQUENCE, &&TARGET_MATCH_KEYS, - &&TARGET_CALL_FUNCTION_ADAPTIVE, + &&TARGET_CALL_NO_KW_BUILTIN_FAST, &&TARGET_PUSH_EXC_INFO, - &&TARGET_CALL_FUNCTION_BUILTIN_O, - &&TARGET_POP_EXCEPT_AND_RERAISE, - &&TARGET_CALL_FUNCTION_BUILTIN_FAST, - &&TARGET_CALL_FUNCTION_LEN, - &&TARGET_CALL_FUNCTION_ISINSTANCE, - &&TARGET_CALL_FUNCTION_PY_SIMPLE, - &&TARGET_JUMP_ABSOLUTE_QUICK, - &&TARGET_LOAD_ATTR_ADAPTIVE, - &&TARGET_LOAD_ATTR_INSTANCE_VALUE, - &&TARGET_LOAD_ATTR_WITH_HINT, - &&TARGET_LOAD_ATTR_SLOT, - &&TARGET_LOAD_ATTR_MODULE, - &&TARGET_LOAD_GLOBAL_ADAPTIVE, + &&TARGET_CHECK_EXC_MATCH, + &&TARGET_CHECK_EG_MATCH, + &&TARGET_CALL_NO_KW_BUILTIN_O, + &&TARGET_CALL_NO_KW_ISINSTANCE, + &&TARGET_CALL_NO_KW_LEN, + &&TARGET_CALL_NO_KW_LIST_APPEND, + &&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_FAST, + &&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, + &&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_O, + &&TARGET_CALL_NO_KW_STR_1, + &&TARGET_CALL_NO_KW_TUPLE_1, + &&TARGET_CALL_NO_KW_TYPE_1, + &&TARGET_COMPARE_AND_BRANCH_FLOAT, &&TARGET_WITH_EXCEPT_START, &&TARGET_GET_AITER, &&TARGET_GET_ANEXT, &&TARGET_BEFORE_ASYNC_WITH, &&TARGET_BEFORE_WITH, &&TARGET_END_ASYNC_FOR, - &&TARGET_LOAD_GLOBAL_MODULE, - &&TARGET_LOAD_GLOBAL_BUILTIN, - &&TARGET_LOAD_METHOD_ADAPTIVE, - &&TARGET_LOAD_METHOD_CACHED, - &&TARGET_LOAD_METHOD_CLASS, + &&TARGET_CLEANUP_THROW, + &&TARGET_COMPARE_AND_BRANCH_INT, + &&TARGET_COMPARE_AND_BRANCH_STR, + &&TARGET_FOR_ITER_LIST, + &&TARGET_FOR_ITER_TUPLE, &&TARGET_STORE_SUBSCR, &&TARGET_DELETE_SUBSCR, - &&TARGET_LOAD_METHOD_MODULE, - &&TARGET_LOAD_METHOD_NO_DICT, - &&TARGET_STORE_ATTR_ADAPTIVE, - &&TARGET_STORE_ATTR_INSTANCE_VALUE, - &&TARGET_STORE_ATTR_SLOT, - &&TARGET_STORE_ATTR_WITH_HINT, + &&TARGET_FOR_ITER_RANGE, + &&TARGET_FOR_ITER_GEN, + &&TARGET_LOAD_ATTR_CLASS, + &&TARGET_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, + &&TARGET_LOAD_ATTR_INSTANCE_VALUE, + &&TARGET_LOAD_ATTR_MODULE, &&TARGET_GET_ITER, &&TARGET_GET_YIELD_FROM_ITER, - &&TARGET_PRINT_EXPR, + &&TARGET_LOAD_ATTR_PROPERTY, &&TARGET_LOAD_BUILD_CLASS, - &&TARGET_YIELD_FROM, - &&TARGET_GET_AWAITABLE, + &&TARGET_LOAD_ATTR_SLOT, + &&TARGET_LOAD_ATTR_WITH_HINT, &&TARGET_LOAD_ASSERTION_ERROR, - &&TARGET_LOAD_FAST__LOAD_FAST, - &&TARGET_STORE_FAST__LOAD_FAST, - &&TARGET_LOAD_FAST__LOAD_CONST, + &&TARGET_RETURN_GENERATOR, + &&TARGET_LOAD_ATTR_METHOD_LAZY_DICT, + &&TARGET_LOAD_ATTR_METHOD_NO_DICT, + &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES, &&TARGET_LOAD_CONST__LOAD_FAST, - &&TARGET_STORE_FAST__STORE_FAST, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_LIST_TO_TUPLE, + &&TARGET_LOAD_FAST__LOAD_CONST, + &&TARGET_LOAD_FAST__LOAD_FAST, + &&TARGET_LOAD_GLOBAL_BUILTIN, &&TARGET_RETURN_VALUE, - &&TARGET_IMPORT_STAR, + &&TARGET_LOAD_GLOBAL_MODULE, &&TARGET_SETUP_ANNOTATIONS, - &&TARGET_YIELD_VALUE, - &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_STORE_ATTR_INSTANCE_VALUE, + &&TARGET_STORE_ATTR_SLOT, + &&TARGET_PREP_RERAISE_STAR, &&TARGET_POP_EXCEPT, &&TARGET_STORE_NAME, &&TARGET_DELETE_NAME, @@ -98,7 +98,7 @@ static void *opcode_targets[256] = { &&TARGET_DELETE_ATTR, &&TARGET_STORE_GLOBAL, &&TARGET_DELETE_GLOBAL, - &&TARGET_ROT_N, + &&TARGET_SWAP, &&TARGET_LOAD_CONST, &&TARGET_LOAD_NAME, &&TARGET_BUILD_TUPLE, @@ -112,7 +112,7 @@ static void *opcode_targets[256] = { &&TARGET_JUMP_FORWARD, &&TARGET_JUMP_IF_FALSE_OR_POP, &&TARGET_JUMP_IF_TRUE_OR_POP, - &&TARGET_JUMP_ABSOLUTE, + &&TARGET_STORE_ATTR_WITH_HINT, &&TARGET_POP_JUMP_IF_FALSE, &&TARGET_POP_JUMP_IF_TRUE, &&TARGET_LOAD_GLOBAL, @@ -120,59 +120,59 @@ static void *opcode_targets[256] = { &&TARGET_CONTAINS_OP, &&TARGET_RERAISE, &&TARGET_COPY, - &&TARGET_JUMP_IF_NOT_EXC_MATCH, + &&TARGET_STORE_FAST__LOAD_FAST, &&TARGET_BINARY_OP, - &&_unknown_opcode, + &&TARGET_SEND, &&TARGET_LOAD_FAST, &&TARGET_STORE_FAST, &&TARGET_DELETE_FAST, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_GEN_START, + &&TARGET_LOAD_FAST_CHECK, + &&TARGET_POP_JUMP_IF_NOT_NONE, + &&TARGET_POP_JUMP_IF_NONE, &&TARGET_RAISE_VARARGS, - &&TARGET_CALL_FUNCTION, + &&TARGET_GET_AWAITABLE, &&TARGET_MAKE_FUNCTION, &&TARGET_BUILD_SLICE, - &&_unknown_opcode, + &&TARGET_JUMP_BACKWARD_NO_INTERRUPT, &&TARGET_MAKE_CELL, &&TARGET_LOAD_CLOSURE, &&TARGET_LOAD_DEREF, &&TARGET_STORE_DEREF, &&TARGET_DELETE_DEREF, - &&_unknown_opcode, - &&TARGET_CALL_FUNCTION_KW, + &&TARGET_JUMP_BACKWARD, + &&TARGET_COMPARE_AND_BRANCH, &&TARGET_CALL_FUNCTION_EX, - &&_unknown_opcode, + &&TARGET_STORE_FAST__STORE_FAST, &&TARGET_EXTENDED_ARG, &&TARGET_LIST_APPEND, &&TARGET_SET_ADD, &&TARGET_MAP_ADD, &&TARGET_LOAD_CLASSDEREF, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_COPY_FREE_VARS, + &&TARGET_YIELD_VALUE, + &&TARGET_RESUME, &&TARGET_MATCH_CLASS, - &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_STORE_SUBSCR_DICT, + &&TARGET_STORE_SUBSCR_LIST_INT, &&TARGET_FORMAT_VALUE, &&TARGET_BUILD_CONST_KEY_MAP, &&TARGET_BUILD_STRING, + &&TARGET_UNPACK_SEQUENCE_LIST, + &&TARGET_UNPACK_SEQUENCE_TUPLE, + &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE, &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_LOAD_METHOD, - &&TARGET_CALL_METHOD, &&TARGET_LIST_EXTEND, &&TARGET_SET_UPDATE, &&TARGET_DICT_MERGE, &&TARGET_DICT_UPDATE, - &&TARGET_CALL_METHOD_KW, - &&_unknown_opcode, - &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, + &&TARGET_CALL, + &&TARGET_KW_NAMES, + &&TARGET_CALL_INTRINSIC_1, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, diff --git a/Python/pathconfig.c b/Python/pathconfig.c index ad22222e000..be0f97c4b20 100644 --- a/Python/pathconfig.c +++ b/Python/pathconfig.c @@ -1,6 +1,7 @@ /* Path configuration like module_search_path (sys.path) */ #include "Python.h" +#include "marshal.h" // PyMarshal_ReadObjectFromString #include "osdefs.h" // DELIM #include "pycore_initconfig.h" #include "pycore_fileutils.h" @@ -9,6 +10,8 @@ #include #ifdef MS_WINDOWS # include // GetFullPathNameW(), MAX_PATH +# include +# include #endif #ifdef __cplusplus @@ -16,86 +19,37 @@ extern "C" { #endif +/* External interface */ + +/* Stored values set by C API functions */ +typedef struct _PyPathConfig { + /* Full path to the Python program */ + wchar_t *program_full_path; + wchar_t *prefix; + wchar_t *exec_prefix; + wchar_t *stdlib_dir; + /* Set by Py_SetPath */ + wchar_t *module_search_path; + /* Set by _PyPathConfig_UpdateGlobal */ + wchar_t *calculated_module_search_path; + /* Python program name */ + wchar_t *program_name; + /* Set by Py_SetPythonHome() or PYTHONHOME environment variable */ + wchar_t *home; + int _is_python_build; +} _PyPathConfig; + +# define _PyPathConfig_INIT \ + {.module_search_path = NULL, ._is_python_build = 0} + + _PyPathConfig _Py_path_config = _PyPathConfig_INIT; -static int -copy_wstr(wchar_t **dst, const wchar_t *src) +const wchar_t * +_PyPathConfig_GetGlobalModuleSearchPath(void) { - assert(*dst == NULL); - if (src != NULL) { - *dst = _PyMem_RawWcsdup(src); - if (*dst == NULL) { - return -1; - } - } - else { - *dst = NULL; - } - return 0; -} - - -static void -pathconfig_clear(_PyPathConfig *config) -{ - /* _PyMem_SetDefaultAllocator() is needed to get a known memory allocator, - since Py_SetPath(), Py_SetPythonHome() and Py_SetProgramName() can be - called before Py_Initialize() which can changes the memory allocator. */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - -#define CLEAR(ATTR) \ - do { \ - PyMem_RawFree(ATTR); \ - ATTR = NULL; \ - } while (0) - - CLEAR(config->program_full_path); - CLEAR(config->prefix); - CLEAR(config->exec_prefix); - CLEAR(config->stdlib_dir); - CLEAR(config->module_search_path); - CLEAR(config->program_name); - CLEAR(config->home); -#ifdef MS_WINDOWS - CLEAR(config->base_executable); -#endif - -#undef CLEAR - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); -} - - -static PyStatus -pathconfig_copy(_PyPathConfig *config, const _PyPathConfig *config2) -{ - pathconfig_clear(config); - -#define COPY_ATTR(ATTR) \ - do { \ - if (copy_wstr(&config->ATTR, config2->ATTR) < 0) { \ - return _PyStatus_NO_MEMORY(); \ - } \ - } while (0) - - COPY_ATTR(program_full_path); - COPY_ATTR(prefix); - COPY_ATTR(exec_prefix); - COPY_ATTR(module_search_path); - COPY_ATTR(stdlib_dir); - COPY_ATTR(program_name); - COPY_ATTR(home); -#ifdef MS_WINDOWS - config->isolated = config2->isolated; - config->site_import = config2->site_import; - COPY_ATTR(base_executable); -#endif - -#undef COPY_ATTR - - return _PyStatus_OK(); + return _Py_path_config.module_search_path; } @@ -105,374 +59,152 @@ _PyPathConfig_ClearGlobal(void) PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - pathconfig_clear(&_Py_path_config); +#define CLEAR(ATTR) \ + do { \ + PyMem_RawFree(_Py_path_config.ATTR); \ + _Py_path_config.ATTR = NULL; \ + } while (0) + + CLEAR(program_full_path); + CLEAR(prefix); + CLEAR(exec_prefix); + CLEAR(stdlib_dir); + CLEAR(module_search_path); + CLEAR(calculated_module_search_path); + CLEAR(program_name); + CLEAR(home); + _Py_path_config._is_python_build = 0; + +#undef CLEAR PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); } - -static wchar_t* -_PyWideStringList_Join(const PyWideStringList *list, wchar_t sep) +PyStatus +_PyPathConfig_ReadGlobal(PyConfig *config) { - size_t len = 1; /* NUL terminator */ - for (Py_ssize_t i=0; i < list->length; i++) { - if (i != 0) { - len++; - } - len += wcslen(list->items[i]); - } + PyStatus status = _PyStatus_OK(); - wchar_t *text = PyMem_RawMalloc(len * sizeof(wchar_t)); - if (text == NULL) { - return NULL; - } - wchar_t *str = text; - for (Py_ssize_t i=0; i < list->length; i++) { - wchar_t *path = list->items[i]; - if (i != 0) { - *str++ = sep; - } - len = wcslen(path); - memcpy(str, path, len * sizeof(wchar_t)); - str += len; - } - *str = L'\0'; +#define COPY(ATTR) \ + do { \ + if (_Py_path_config.ATTR && !config->ATTR) { \ + status = PyConfig_SetString(config, &config->ATTR, _Py_path_config.ATTR); \ + if (_PyStatus_EXCEPTION(status)) goto done; \ + } \ + } while (0) - return text; +#define COPY2(ATTR, SRCATTR) \ + do { \ + if (_Py_path_config.SRCATTR && !config->ATTR) { \ + status = PyConfig_SetString(config, &config->ATTR, _Py_path_config.SRCATTR); \ + if (_PyStatus_EXCEPTION(status)) goto done; \ + } \ + } while (0) + +#define COPY_INT(ATTR) \ + do { \ + assert(_Py_path_config.ATTR >= 0); \ + if ((_Py_path_config.ATTR >= 0) && (config->ATTR <= 0)) { \ + config->ATTR = _Py_path_config.ATTR; \ + } \ + } while (0) + + COPY(prefix); + COPY(exec_prefix); + COPY(stdlib_dir); + COPY(program_name); + COPY(home); + COPY2(executable, program_full_path); + COPY_INT(_is_python_build); + // module_search_path must be initialised - not read +#undef COPY +#undef COPY2 +#undef COPY_INT + +done: + return status; } - -static PyStatus -pathconfig_set_from_config(_PyPathConfig *pathconfig, const PyConfig *config) +PyStatus +_PyPathConfig_UpdateGlobal(const PyConfig *config) { - PyStatus status; PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - if (config->module_search_paths_set) { - PyMem_RawFree(pathconfig->module_search_path); - pathconfig->module_search_path = _PyWideStringList_Join(&config->module_search_paths, DELIM); - if (pathconfig->module_search_path == NULL) { - goto no_memory; - } - } +#define COPY(ATTR) \ + do { \ + if (config->ATTR) { \ + PyMem_RawFree(_Py_path_config.ATTR); \ + _Py_path_config.ATTR = _PyMem_RawWcsdup(config->ATTR); \ + if (!_Py_path_config.ATTR) goto error; \ + } \ + } while (0) -#define COPY_CONFIG(PATH_ATTR, CONFIG_ATTR) \ - if (config->CONFIG_ATTR) { \ - PyMem_RawFree(pathconfig->PATH_ATTR); \ - pathconfig->PATH_ATTR = NULL; \ - if (copy_wstr(&pathconfig->PATH_ATTR, config->CONFIG_ATTR) < 0) { \ - goto no_memory; \ - } \ +#define COPY2(ATTR, SRCATTR) \ + do { \ + if (config->SRCATTR) { \ + PyMem_RawFree(_Py_path_config.ATTR); \ + _Py_path_config.ATTR = _PyMem_RawWcsdup(config->SRCATTR); \ + if (!_Py_path_config.ATTR) goto error; \ + } \ + } while (0) + +#define COPY_INT(ATTR) \ + do { \ + if (config->ATTR > 0) { \ + _Py_path_config.ATTR = config->ATTR; \ + } \ + } while (0) + + COPY(prefix); + COPY(exec_prefix); + COPY(stdlib_dir); + COPY(program_name); + COPY(home); + COPY2(program_full_path, executable); + COPY_INT(_is_python_build); +#undef COPY +#undef COPY2 +#undef COPY_INT + + PyMem_RawFree(_Py_path_config.module_search_path); + _Py_path_config.module_search_path = NULL; + PyMem_RawFree(_Py_path_config.calculated_module_search_path); + _Py_path_config.calculated_module_search_path = NULL; + + do { + size_t cch = 1; + for (Py_ssize_t i = 0; i < config->module_search_paths.length; ++i) { + cch += 1 + wcslen(config->module_search_paths.items[i]); } - COPY_CONFIG(program_full_path, executable); - COPY_CONFIG(prefix, prefix); - COPY_CONFIG(exec_prefix, exec_prefix); - COPY_CONFIG(stdlib_dir, stdlib_dir); - COPY_CONFIG(program_name, program_name); - COPY_CONFIG(home, home); -#ifdef MS_WINDOWS - COPY_CONFIG(base_executable, base_executable); -#endif + wchar_t *path = (wchar_t*)PyMem_RawMalloc(sizeof(wchar_t) * cch); + if (!path) { + goto error; + } + wchar_t *p = path; + for (Py_ssize_t i = 0; i < config->module_search_paths.length; ++i) { + wcscpy(p, config->module_search_paths.items[i]); + p = wcschr(p, L'\0'); + *p++ = DELIM; + *p = L'\0'; + } -#undef COPY_CONFIG + do { + *p = L'\0'; + } while (p != path && *--p == DELIM); + _Py_path_config.calculated_module_search_path = path; + } while (0); - status = _PyStatus_OK(); - goto done; - -no_memory: - status = _PyStatus_NO_MEMORY(); - -done: PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return status; -} - -PyObject * -_PyPathConfig_AsDict(void) -{ - PyObject *dict = PyDict_New(); - if (dict == NULL) { - return NULL; - } - -#define SET_ITEM(KEY, EXPR) \ - do { \ - PyObject *obj = (EXPR); \ - if (obj == NULL) { \ - goto fail; \ - } \ - int res = PyDict_SetItemString(dict, KEY, obj); \ - Py_DECREF(obj); \ - if (res < 0) { \ - goto fail; \ - } \ - } while (0) -#define SET_ITEM_STR(KEY) \ - SET_ITEM(#KEY, \ - (_Py_path_config.KEY \ - ? PyUnicode_FromWideChar(_Py_path_config.KEY, -1) \ - : (Py_INCREF(Py_None), Py_None))) -#define SET_ITEM_INT(KEY) \ - SET_ITEM(#KEY, PyLong_FromLong(_Py_path_config.KEY)) - - SET_ITEM_STR(program_full_path); - SET_ITEM_STR(prefix); - SET_ITEM_STR(exec_prefix); - SET_ITEM_STR(module_search_path); - SET_ITEM_STR(stdlib_dir); - SET_ITEM_STR(program_name); - SET_ITEM_STR(home); -#ifdef MS_WINDOWS - SET_ITEM_INT(isolated); - SET_ITEM_INT(site_import); - SET_ITEM_STR(base_executable); - - { - wchar_t py3path[MAX_PATH]; - HMODULE hPython3 = GetModuleHandleW(PY3_DLLNAME); - PyObject *obj; - if (hPython3 - && GetModuleFileNameW(hPython3, py3path, Py_ARRAY_LENGTH(py3path))) - { - obj = PyUnicode_FromWideChar(py3path, -1); - if (obj == NULL) { - goto fail; - } - } - else { - obj = Py_None; - Py_INCREF(obj); - } - if (PyDict_SetItemString(dict, "python3_dll", obj) < 0) { - Py_DECREF(obj); - goto fail; - } - Py_DECREF(obj); - } -#endif - -#undef SET_ITEM -#undef SET_ITEM_STR -#undef SET_ITEM_INT - - return dict; - -fail: - Py_DECREF(dict); - return NULL; -} - - -PyStatus -_PyConfig_WritePathConfig(const PyConfig *config) -{ - return pathconfig_set_from_config(&_Py_path_config, config); -} - - -static PyStatus -config_init_module_search_paths(PyConfig *config, _PyPathConfig *pathconfig) -{ - assert(!config->module_search_paths_set); - - _PyWideStringList_Clear(&config->module_search_paths); - - const wchar_t *sys_path = pathconfig->module_search_path; - const wchar_t delim = DELIM; - while (1) { - const wchar_t *p = wcschr(sys_path, delim); - if (p == NULL) { - p = sys_path + wcslen(sys_path); /* End of string */ - } - - size_t path_len = (p - sys_path); - wchar_t *path = PyMem_RawMalloc((path_len + 1) * sizeof(wchar_t)); - if (path == NULL) { - return _PyStatus_NO_MEMORY(); - } - memcpy(path, sys_path, path_len * sizeof(wchar_t)); - path[path_len] = L'\0'; - - PyStatus status = PyWideStringList_Append(&config->module_search_paths, path); - PyMem_RawFree(path); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (*p == '\0') { - break; - } - sys_path = p + 1; - } - config->module_search_paths_set = 1; return _PyStatus_OK(); -} - -/* Calculate the path configuration: - - - exec_prefix - - module_search_path - - stdlib_dir - - prefix - - program_full_path - - On Windows, more fields are calculated: - - - base_executable - - isolated - - site_import - - On other platforms, isolated and site_import are left unchanged, and - _PyConfig_InitPathConfig() copies executable to base_executable (if it's not - set). - - Priority, highest to lowest: - - - PyConfig - - _Py_path_config: set by Py_SetPath(), Py_SetPythonHome() - and Py_SetProgramName() - - _PyPathConfig_Calculate() -*/ -static PyStatus -pathconfig_init(_PyPathConfig *pathconfig, const PyConfig *config, - int compute_path_config) -{ - PyStatus status; - - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - status = pathconfig_copy(pathconfig, &_Py_path_config); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - status = pathconfig_set_from_config(pathconfig, config); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - if (compute_path_config) { - status = _PyPathConfig_Calculate(pathconfig, config); - } - -done: +error: PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return status; + return _PyStatus_NO_MEMORY(); } -static PyStatus -config_init_pathconfig(PyConfig *config, int compute_path_config) -{ - _PyPathConfig pathconfig = _PyPathConfig_INIT; - PyStatus status; - - status = pathconfig_init(&pathconfig, config, compute_path_config); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - if (!config->module_search_paths_set - && pathconfig.module_search_path != NULL) - { - status = config_init_module_search_paths(config, &pathconfig); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - } - -#define COPY_ATTR(PATH_ATTR, CONFIG_ATTR) \ - if (config->CONFIG_ATTR == NULL && pathconfig.PATH_ATTR != NULL) { \ - if (copy_wstr(&config->CONFIG_ATTR, pathconfig.PATH_ATTR) < 0) { \ - goto no_memory; \ - } \ - } - -#ifdef MS_WINDOWS - if (config->executable != NULL && config->base_executable == NULL) { - /* If executable is set explicitly in the configuration, - ignore calculated base_executable: _PyConfig_InitPathConfig() - will copy executable to base_executable */ - } - else { - COPY_ATTR(base_executable, base_executable); - } -#endif - - COPY_ATTR(program_full_path, executable); - COPY_ATTR(prefix, prefix); - COPY_ATTR(exec_prefix, exec_prefix); - COPY_ATTR(stdlib_dir, stdlib_dir); - -#undef COPY_ATTR - -#ifdef MS_WINDOWS - /* If a ._pth file is found: isolated and site_import are overridden */ - if (pathconfig.isolated != -1) { - config->isolated = pathconfig.isolated; - } - if (pathconfig.site_import != -1) { - config->site_import = pathconfig.site_import; - } -#endif - - status = _PyStatus_OK(); - goto done; - -no_memory: - status = _PyStatus_NO_MEMORY(); - -done: - pathconfig_clear(&pathconfig); - return status; -} - - -PyStatus -_PyConfig_InitPathConfig(PyConfig *config, int compute_path_config) -{ - /* Do we need to calculate the path? */ - if (!config->module_search_paths_set - || config->executable == NULL - || config->prefix == NULL - || config->exec_prefix == NULL) - { - PyStatus status = config_init_pathconfig(config, compute_path_config); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (config->base_prefix == NULL && config->prefix != NULL) { - if (copy_wstr(&config->base_prefix, config->prefix) < 0) { - return _PyStatus_NO_MEMORY(); - } - } - - if (config->base_exec_prefix == NULL && config->exec_prefix != NULL) { - if (copy_wstr(&config->base_exec_prefix, - config->exec_prefix) < 0) { - return _PyStatus_NO_MEMORY(); - } - } - - if (config->base_executable == NULL && config->executable != NULL) { - if (copy_wstr(&config->base_executable, - config->executable) < 0) { - return _PyStatus_NO_MEMORY(); - } - } - - return _PyStatus_OK(); -} - - -/* External interface */ - static void _Py_NO_RETURN path_out_of_memory(const char *func) { @@ -483,7 +215,7 @@ void Py_SetPath(const wchar_t *path) { if (path == NULL) { - pathconfig_clear(&_Py_path_config); + _PyPathConfig_ClearGlobal(); return; } @@ -494,6 +226,7 @@ Py_SetPath(const wchar_t *path) PyMem_RawFree(_Py_path_config.exec_prefix); PyMem_RawFree(_Py_path_config.stdlib_dir); PyMem_RawFree(_Py_path_config.module_search_path); + PyMem_RawFree(_Py_path_config.calculated_module_search_path); _Py_path_config.prefix = _PyMem_RawWcsdup(L""); _Py_path_config.exec_prefix = _PyMem_RawWcsdup(L""); @@ -505,6 +238,7 @@ Py_SetPath(const wchar_t *path) _Py_path_config.stdlib_dir = _PyMem_RawWcsdup(L""); } _Py_path_config.module_search_path = _PyMem_RawWcsdup(path); + _Py_path_config.calculated_module_search_path = NULL; PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); @@ -521,19 +255,21 @@ Py_SetPath(const wchar_t *path) void Py_SetPythonHome(const wchar_t *home) { - if (home == NULL) { - return; - } + int has_value = home && home[0]; PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); PyMem_RawFree(_Py_path_config.home); - _Py_path_config.home = _PyMem_RawWcsdup(home); + _Py_path_config.home = NULL; + + if (has_value) { + _Py_path_config.home = _PyMem_RawWcsdup(home); + } PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - if (_Py_path_config.home == NULL) { + if (has_value && _Py_path_config.home == NULL) { path_out_of_memory(__func__); } } @@ -542,19 +278,21 @@ Py_SetPythonHome(const wchar_t *home) void Py_SetProgramName(const wchar_t *program_name) { - if (program_name == NULL || program_name[0] == L'\0') { - return; - } + int has_value = program_name && program_name[0]; PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); PyMem_RawFree(_Py_path_config.program_name); - _Py_path_config.program_name = _PyMem_RawWcsdup(program_name); + _Py_path_config.program_name = NULL; + + if (has_value) { + _Py_path_config.program_name = _PyMem_RawWcsdup(program_name); + } PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - if (_Py_path_config.program_name == NULL) { + if (has_value && _Py_path_config.program_name == NULL) { path_out_of_memory(__func__); } } @@ -562,19 +300,21 @@ Py_SetProgramName(const wchar_t *program_name) void _Py_SetProgramFullPath(const wchar_t *program_full_path) { - if (program_full_path == NULL || program_full_path[0] == L'\0') { - return; - } + int has_value = program_full_path && program_full_path[0]; PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); PyMem_RawFree(_Py_path_config.program_full_path); - _Py_path_config.program_full_path = _PyMem_RawWcsdup(program_full_path); + _Py_path_config.program_full_path = NULL; + + if (has_value) { + _Py_path_config.program_full_path = _PyMem_RawWcsdup(program_full_path); + } PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - if (_Py_path_config.program_full_path == NULL) { + if (has_value && _Py_path_config.program_full_path == NULL) { path_out_of_memory(__func__); } } @@ -583,7 +323,12 @@ _Py_SetProgramFullPath(const wchar_t *program_full_path) wchar_t * Py_GetPath(void) { - return _Py_path_config.module_search_path; + /* If the user has provided a path, return that */ + if (_Py_path_config.module_search_path) { + return _Py_path_config.module_search_path; + } + /* If we have already done calculations, return the calculated path */ + return _Py_path_config.calculated_module_search_path; } @@ -632,6 +377,8 @@ Py_GetProgramName(void) return _Py_path_config.program_name; } + + /* Compute module search path from argv[0] or the current working directory ("-m module" case) which will be prepended to sys.argv: sys.path[0]. @@ -772,73 +519,6 @@ _PyPathConfig_ComputeSysPath0(const PyWideStringList *argv, PyObject **path0_p) } -#ifdef MS_WINDOWS -#define WCSTOK wcstok_s -#else -#define WCSTOK wcstok -#endif - -/* Search for a prefix value in an environment file (pyvenv.cfg). - - - If found, copy it into *value_p: string which must be freed by - PyMem_RawFree(). - - If not found, *value_p is set to NULL. -*/ -PyStatus -_Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key, - wchar_t **value_p) -{ - *value_p = NULL; - - char buffer[MAXPATHLEN * 2 + 1]; /* allow extra for key, '=', etc. */ - buffer[Py_ARRAY_LENGTH(buffer)-1] = '\0'; - - while (!feof(env_file)) { - char * p = fgets(buffer, Py_ARRAY_LENGTH(buffer) - 1, env_file); - - if (p == NULL) { - break; - } - - size_t n = strlen(p); - if (p[n - 1] != '\n') { - /* line has overflowed - bail */ - break; - } - if (p[0] == '#') { - /* Comment - skip */ - continue; - } - - wchar_t *tmpbuffer = _Py_DecodeUTF8_surrogateescape(buffer, n, NULL); - if (tmpbuffer) { - wchar_t * state; - wchar_t * tok = WCSTOK(tmpbuffer, L" \t\r\n", &state); - if ((tok != NULL) && !wcscmp(tok, key)) { - tok = WCSTOK(NULL, L" \t", &state); - if ((tok != NULL) && !wcscmp(tok, L"=")) { - tok = WCSTOK(NULL, L"\r\n", &state); - if (tok != NULL) { - *value_p = _PyMem_RawWcsdup(tok); - PyMem_RawFree(tmpbuffer); - - if (*value_p == NULL) { - return _PyStatus_NO_MEMORY(); - } - - /* found */ - return _PyStatus_OK(); - } - } - } - PyMem_RawFree(tmpbuffer); - } - } - - /* not found */ - return _PyStatus_OK(); -} - #ifdef __cplusplus } #endif diff --git a/Python/perf_trampoline.c b/Python/perf_trampoline.c new file mode 100644 index 00000000000..1957ab82c33 --- /dev/null +++ b/Python/perf_trampoline.c @@ -0,0 +1,515 @@ +/* + +Perf trampoline instrumentation +=============================== + +This file contains instrumentation to allow to associate +calls to the CPython eval loop back to the names of the Python +functions and filename being executed. + +Many native performance profilers like the Linux perf tools are +only available to 'see' the C stack when sampling from the profiled +process. This means that if we have the following python code: + + import time + def foo(n): + # Some CPU intensive code + + def bar(n): + foo(n) + + def baz(n): + bar(n) + + baz(10000000) + +A performance profiler that is only able to see native frames will +produce the following backtrace when sampling from foo(): + + _PyEval_EvalFrameDefault -----> Evaluation frame of foo() + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + _PyEval_EvalFrameDefault ------> Evaluation frame of bar() + _PyEval_EvalFrame + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + _PyEval_EvalFrameDefault -------> Evaluation frame of baz() + _PyEval_EvalFrame + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + ... + + Py_RunMain + +Because the profiler is only able to see the native frames and the native +function that runs the evaluation loop is the same (_PyEval_EvalFrameDefault) +then the profiler and any reporter generated by it will not be able to +associate the names of the Python functions and the filenames associated with +those calls, rendering the results useless in the Python world. + +To fix this problem, we introduce the concept of a trampoline frame. A +trampoline frame is a piece of code that is unique per Python code object that +is executed before entering the CPython eval loop. This piece of code just +calls the original Python evaluation function (_PyEval_EvalFrameDefault) and +forwards all the arguments received. In this way, when a profiler samples +frames from the previous example it will see; + + _PyEval_EvalFrameDefault -----> Evaluation frame of foo() + [Jit compiled code 3] + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + _PyEval_EvalFrameDefault ------> Evaluation frame of bar() + [Jit compiled code 2] + _PyEval_EvalFrame + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + _PyEval_EvalFrameDefault -------> Evaluation frame of baz() + [Jit compiled code 1] + _PyEval_EvalFrame + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + ... + + Py_RunMain + +When we generate every unique copy of the trampoline (what here we called "[Jit +compiled code N]") we write the relationship between the compiled code and the +Python function that is associated with it. Every profiler requires this +information in a different format. For example, the Linux "perf" profiler +requires a file in "/tmp/perf-PID.map" (name and location not configurable) +with the following format: + + + +If this file is available when "perf" generates reports, it will automatically +associate every trampoline with the Python function that it is associated with +allowing it to generate reports that include Python information. These reports +then can also be filtered in a way that *only* Python information appears. + +Notice that for this to work, there must be a unique copied of the trampoline +per Python code object even if the code in the trampoline is the same. To +achieve this we have a assembly template in Objects/asm_trampiline.S that is +compiled into the Python executable/shared library. This template generates a +symbol that maps the start of the assembly code and another that marks the end +of the assembly code for the trampoline. Then, every time we need a unique +trampoline for a Python code object, we copy the assembly code into a mmaped +area that has executable permissions and we return the start of that area as +our trampoline function. + +Asking for a mmap-ed memory area for trampoline is very wasteful so we +allocate big arenas of memory in a single mmap call, we populate the entire +arena with copies of the trampoline (this allows us to now have to invalidate +the icache for the instructions in the page) and then we return the next +available chunk every time someone asks for a new trampoline. We keep a linked +list of arenas in case the current memory arena is exhausted and another one is +needed. + +For the best results, Python should be compiled with +CFLAGS="-fno-omit-frame-pointer -mno-omit-leaf-frame-pointer" as this allows +profilers to unwind using only the frame pointer and not on DWARF debug +information (note that as trampilines are dynamically generated there won't be +any DWARF information available for them). +*/ + +#include "Python.h" +#include "pycore_ceval.h" +#include "pycore_frame.h" +#include "pycore_interp.h" + + +#ifdef PY_HAVE_PERF_TRAMPOLINE + +#include +#include +#include +#include +#include +#include + +#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) +#define PY_HAVE_INVALIDATE_ICACHE + +#if defined(__clang__) || defined(__GNUC__) +extern void __clear_cache(void *, void*); +#endif + +static void invalidate_icache(char* begin, char*end) { +#if defined(__clang__) || defined(__GNUC__) + return __clear_cache(begin, end); +#else + return; +#endif +} +#endif + +/* The function pointer is passed as last argument. The other three arguments + * are passed in the same order as the function requires. This results in + * shorter, more efficient ASM code for trampoline. + */ +typedef PyObject *(*py_evaluator)(PyThreadState *, _PyInterpreterFrame *, + int throwflag); +typedef PyObject *(*py_trampoline)(PyThreadState *, _PyInterpreterFrame *, int, + py_evaluator); + +extern void *_Py_trampoline_func_start; // Start of the template of the + // assembly trampoline +extern void * + _Py_trampoline_func_end; // End of the template of the assembly trampoline + +struct code_arena_st { + char *start_addr; // Start of the memory arena + char *current_addr; // Address of the current trampoline within the arena + size_t size; // Size of the memory arena + size_t size_left; // Remaining size of the memory arena + size_t code_size; // Size of the code of every trampoline in the arena + struct code_arena_st + *prev; // Pointer to the arena or NULL if this is the first arena. +}; + +typedef struct code_arena_st code_arena_t; +typedef struct trampoline_api_st trampoline_api_t; + +#define perf_status _PyRuntime.ceval.perf.status +#define extra_code_index _PyRuntime.ceval.perf.extra_code_index +#define perf_code_arena _PyRuntime.ceval.perf.code_arena +#define trampoline_api _PyRuntime.ceval.perf.trampoline_api +#define perf_map_file _PyRuntime.ceval.perf.map_file + +static void * +perf_map_get_file(void) +{ + if (perf_map_file) { + return perf_map_file; + } + char filename[100]; + pid_t pid = getpid(); + // Location and file name of perf map is hard-coded in perf tool. + // Use exclusive create flag wit nofollow to prevent symlink attacks. + int flags = O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC; + snprintf(filename, sizeof(filename) - 1, "/tmp/perf-%jd.map", + (intmax_t)pid); + int fd = open(filename, flags, 0600); + if (fd == -1) { + perf_status = PERF_STATUS_FAILED; + PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename); + return NULL; + } + perf_map_file = fdopen(fd, "w"); + if (!perf_map_file) { + perf_status = PERF_STATUS_FAILED; + PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename); + close(fd); + return NULL; + } + return perf_map_file; +} + +static int +perf_map_close(void *state) +{ + FILE *fp = (FILE *)state; + int ret = 0; + if (fp) { + ret = fclose(fp); + } + perf_map_file = NULL; + perf_status = PERF_STATUS_NO_INIT; + return ret; +} + +static void +perf_map_write_entry(void *state, const void *code_addr, + unsigned int code_size, PyCodeObject *co) +{ + assert(state != NULL); + FILE *method_file = (FILE *)state; + const char *entry = PyUnicode_AsUTF8(co->co_qualname); + if (entry == NULL) { + _PyErr_WriteUnraisableMsg("Failed to get qualname from code object", + NULL); + return; + } + const char *filename = PyUnicode_AsUTF8(co->co_filename); + if (filename == NULL) { + _PyErr_WriteUnraisableMsg("Failed to get filename from code object", + NULL); + return; + } + fprintf(method_file, "%p %x py::%s:%s\n", code_addr, code_size, entry, + filename); + fflush(method_file); +} + +_PyPerf_Callbacks _Py_perfmap_callbacks = { + &perf_map_get_file, + &perf_map_write_entry, + &perf_map_close +}; + +static int +new_code_arena(void) +{ + // non-trivial programs typically need 64 to 256 kiB. + size_t mem_size = 4096 * 16; + assert(mem_size % sysconf(_SC_PAGESIZE) == 0); + char *memory = + mmap(NULL, // address + mem_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, + -1, // fd (not used here) + 0); // offset (not used here) + if (!memory) { + PyErr_SetFromErrno(PyExc_OSError); + _PyErr_WriteUnraisableMsg( + "Failed to create new mmap for perf trampoline", NULL); + perf_status = PERF_STATUS_FAILED; + return -1; + } + void *start = &_Py_trampoline_func_start; + void *end = &_Py_trampoline_func_end; + size_t code_size = end - start; + // TODO: Check the effect of alignment of the code chunks. Initial investigation + // showed that this has no effect on performance in x86-64 or aarch64 and the current + // version has the advantage that the unwinder in GDB can unwind across JIT-ed code. + // + // We should check the values in the future and see if there is a + // measurable performance improvement by rounding trampolines up to 32-bit + // or 64-bit alignment. + + size_t n_copies = mem_size / code_size; + for (size_t i = 0; i < n_copies; i++) { + memcpy(memory + i * code_size, start, code_size * sizeof(char)); + } + // Some systems may prevent us from creating executable code on the fly. + int res = mprotect(memory, mem_size, PROT_READ | PROT_EXEC); + if (res == -1) { + PyErr_SetFromErrno(PyExc_OSError); + munmap(memory, mem_size); + _PyErr_WriteUnraisableMsg( + "Failed to set mmap for perf trampoline to PROT_READ | PROT_EXEC", + NULL); + return -1; + } + +#ifdef PY_HAVE_INVALIDATE_ICACHE + // Before the JIT can run a block of code that has been emitted it must invalidate + // the instruction cache on some platforms like arm and aarch64. + invalidate_icache(memory, memory + mem_size); +#endif + + code_arena_t *new_arena = PyMem_RawCalloc(1, sizeof(code_arena_t)); + if (new_arena == NULL) { + PyErr_NoMemory(); + munmap(memory, mem_size); + _PyErr_WriteUnraisableMsg("Failed to allocate new code arena struct", + NULL); + return -1; + } + + new_arena->start_addr = memory; + new_arena->current_addr = memory; + new_arena->size = mem_size; + new_arena->size_left = mem_size; + new_arena->code_size = code_size; + new_arena->prev = perf_code_arena; + perf_code_arena = new_arena; + return 0; +} + +static void +free_code_arenas(void) +{ + code_arena_t *cur = perf_code_arena; + code_arena_t *prev; + perf_code_arena = NULL; // invalid static pointer + while (cur) { + munmap(cur->start_addr, cur->size); + prev = cur->prev; + PyMem_RawFree(cur); + cur = prev; + } +} + +static inline py_trampoline +code_arena_new_code(code_arena_t *code_arena) +{ + py_trampoline trampoline = (py_trampoline)code_arena->current_addr; + code_arena->size_left -= code_arena->code_size; + code_arena->current_addr += code_arena->code_size; + return trampoline; +} + +static inline py_trampoline +compile_trampoline(void) +{ + if ((perf_code_arena == NULL) || + (perf_code_arena->size_left <= perf_code_arena->code_size)) { + if (new_code_arena() < 0) { + return NULL; + } + } + assert(perf_code_arena->size_left <= perf_code_arena->size); + return code_arena_new_code(perf_code_arena); +} + +static PyObject * +py_trampoline_evaluator(PyThreadState *ts, _PyInterpreterFrame *frame, + int throw) +{ + if (perf_status == PERF_STATUS_FAILED || + perf_status == PERF_STATUS_NO_INIT) { + goto default_eval; + } + PyCodeObject *co = frame->f_code; + py_trampoline f = NULL; + assert(extra_code_index != -1); + int ret = _PyCode_GetExtra((PyObject *)co, extra_code_index, (void **)&f); + if (ret != 0 || f == NULL) { + // This is the first time we see this code object so we need + // to compile a trampoline for it. + py_trampoline new_trampoline = compile_trampoline(); + if (new_trampoline == NULL) { + goto default_eval; + } + trampoline_api.write_state(trampoline_api.state, new_trampoline, + perf_code_arena->code_size, co); + _PyCode_SetExtra((PyObject *)co, extra_code_index, + (void *)new_trampoline); + f = new_trampoline; + } + assert(f != NULL); + return f(ts, frame, throw, _PyEval_EvalFrameDefault); +default_eval: + // Something failed, fall back to the default evaluator. + return _PyEval_EvalFrameDefault(ts, frame, throw); +} +#endif // PY_HAVE_PERF_TRAMPOLINE + +int +_PyIsPerfTrampolineActive(void) +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + PyThreadState *tstate = _PyThreadState_GET(); + return tstate->interp->eval_frame == py_trampoline_evaluator; +#endif + return 0; +} + +void +_PyPerfTrampoline_GetCallbacks(_PyPerf_Callbacks *callbacks) +{ + if (callbacks == NULL) { + return; + } +#ifdef PY_HAVE_PERF_TRAMPOLINE + callbacks->init_state = trampoline_api.init_state; + callbacks->write_state = trampoline_api.write_state; + callbacks->free_state = trampoline_api.free_state; +#endif + return; +} + +int +_PyPerfTrampoline_SetCallbacks(_PyPerf_Callbacks *callbacks) +{ + if (callbacks == NULL) { + return -1; + } +#ifdef PY_HAVE_PERF_TRAMPOLINE + if (trampoline_api.state) { + _PyPerfTrampoline_Fini(); + } + trampoline_api.init_state = callbacks->init_state; + trampoline_api.write_state = callbacks->write_state; + trampoline_api.free_state = callbacks->free_state; + trampoline_api.state = NULL; + perf_status = PERF_STATUS_OK; +#endif + return 0; +} + +int +_PyPerfTrampoline_Init(int activate) +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate->interp->eval_frame && + tstate->interp->eval_frame != py_trampoline_evaluator) { + PyErr_SetString(PyExc_RuntimeError, + "Trampoline cannot be initialized as a custom eval " + "frame is already present"); + return -1; + } + if (!activate) { + tstate->interp->eval_frame = NULL; + } + else { + tstate->interp->eval_frame = py_trampoline_evaluator; + if (new_code_arena() < 0) { + return -1; + } + if (trampoline_api.state == NULL) { + void *state = trampoline_api.init_state(); + if (state == NULL) { + return -1; + } + trampoline_api.state = state; + } + extra_code_index = _PyEval_RequestCodeExtraIndex(NULL); + if (extra_code_index == -1) { + return -1; + } + perf_status = PERF_STATUS_OK; + } +#endif + return 0; +} + +int +_PyPerfTrampoline_Fini(void) +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate->interp->eval_frame == py_trampoline_evaluator) { + tstate->interp->eval_frame = NULL; + } + free_code_arenas(); + if (trampoline_api.state != NULL) { + trampoline_api.free_state(trampoline_api.state); + trampoline_api.state = NULL; + } + extra_code_index = -1; +#endif + return 0; +} + +PyStatus +_PyPerfTrampoline_AfterFork_Child(void) +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + // Restart trampoline in file in child. + int was_active = _PyIsPerfTrampolineActive(); + _PyPerfTrampoline_Fini(); + if (was_active) { + _PyPerfTrampoline_Init(1); + } +#endif + return PyStatus_Ok(); +} diff --git a/Python/preconfig.c b/Python/preconfig.c index afa16cccf32..77a86d651eb 100644 --- a/Python/preconfig.c +++ b/Python/preconfig.c @@ -24,6 +24,8 @@ int _Py_HasFileSystemDefaultEncodeErrors = 0; void _Py_ClearFileSystemEncoding(void) { +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { PyMem_RawFree((char*)Py_FileSystemDefaultEncoding); Py_FileSystemDefaultEncoding = NULL; @@ -32,6 +34,7 @@ _Py_ClearFileSystemEncoding(void) PyMem_RawFree((char*)Py_FileSystemDefaultEncodeErrors); Py_FileSystemDefaultEncodeErrors = NULL; } +_Py_COMP_DIAG_POP } @@ -56,11 +59,14 @@ _Py_SetFileSystemEncoding(const char *encoding, const char *errors) _Py_ClearFileSystemEncoding(); +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS Py_FileSystemDefaultEncoding = encoding2; Py_HasFileSystemDefaultEncoding = 0; Py_FileSystemDefaultEncodeErrors = errors2; _Py_HasFileSystemDefaultEncodeErrors = 0; +_Py_COMP_DIAG_POP return 0; } @@ -294,17 +300,7 @@ _PyPreConfig_InitCompatConfig(PyPreConfig *config) config->coerce_c_locale_warn = 0; config->dev_mode = -1; -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - /* bpo-40512: pymalloc is not compatible with subinterpreters, - force usage of libc malloc() which is thread-safe. */ -#ifdef Py_DEBUG - config->allocator = PYMEM_ALLOCATOR_MALLOC_DEBUG; -#else - config->allocator = PYMEM_ALLOCATOR_MALLOC; -#endif -#else config->allocator = PYMEM_ALLOCATOR_NOT_SET; -#endif #ifdef MS_WINDOWS config->legacy_windows_fs_encoding = -1; #endif @@ -482,6 +478,8 @@ preconfig_get_global_vars(PyPreConfig *config) config->ATTR = !(VALUE); \ } +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS COPY_FLAG(isolated, Py_IsolatedFlag); COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); if (Py_UTF8Mode > 0) { @@ -490,6 +488,7 @@ preconfig_get_global_vars(PyPreConfig *config) #ifdef MS_WINDOWS COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag); #endif +_Py_COMP_DIAG_POP #undef COPY_FLAG #undef COPY_NOT_FLAG @@ -508,12 +507,15 @@ preconfig_set_global_vars(const PyPreConfig *config) VAR = !config->ATTR; \ } +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS COPY_FLAG(isolated, Py_IsolatedFlag); COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); #ifdef MS_WINDOWS COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag); #endif COPY_FLAG(utf8_mode, Py_UTF8Mode); +_Py_COMP_DIAG_POP #undef COPY_FLAG #undef COPY_NOT_FLAG @@ -826,12 +828,10 @@ _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args) _Py_SetLocaleFromEnv(LC_CTYPE); } - _PyPreCmdline cmdline = _PyPreCmdline_INIT; - int init_utf8_mode = Py_UTF8Mode; -#ifdef MS_WINDOWS - int init_legacy_encoding = Py_LegacyWindowsFSEncodingFlag; -#endif + PyPreConfig save_runtime_config; + preconfig_copy(&save_runtime_config, &_PyRuntime.preconfig); + _PyPreCmdline cmdline = _PyPreCmdline_INIT; int locale_coerced = 0; int loops = 0; @@ -847,11 +847,9 @@ _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args) } /* bpo-34207: Py_DecodeLocale() and Py_EncodeLocale() depend - on Py_UTF8Mode and Py_LegacyWindowsFSEncodingFlag. */ - Py_UTF8Mode = config->utf8_mode; -#ifdef MS_WINDOWS - Py_LegacyWindowsFSEncodingFlag = config->legacy_windows_fs_encoding; -#endif + on the utf8_mode and legacy_windows_fs_encoding members + of _PyRuntime.preconfig. */ + preconfig_copy(&_PyRuntime.preconfig, config); if (args) { // Set command line arguments at each iteration. If they are bytes @@ -914,14 +912,10 @@ _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args) status = _PyStatus_OK(); done: - if (init_ctype_locale != NULL) { - setlocale(LC_CTYPE, init_ctype_locale); - PyMem_RawFree(init_ctype_locale); - } - Py_UTF8Mode = init_utf8_mode ; -#ifdef MS_WINDOWS - Py_LegacyWindowsFSEncodingFlag = init_legacy_encoding; -#endif + // Revert side effects + setlocale(LC_CTYPE, init_ctype_locale); + PyMem_RawFree(init_ctype_locale); + preconfig_copy(&_PyRuntime.preconfig, &save_runtime_config); _PyPreCmdline_Clear(&cmdline); return status; } diff --git a/Python/pyfpe.c b/Python/pyfpe.c index 31ef5d73b70..9b1260f687a 100644 --- a/Python/pyfpe.c +++ b/Python/pyfpe.c @@ -3,9 +3,12 @@ * though, because they may be referenced by extensions using the stable ABI. */ -#include "setjmp.h" +#ifdef HAVE_SETJMP_H +#include jmp_buf PyFPE_jbuf; +#endif + int PyFPE_counter; double diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 7e6060e4ebc..5ef2d3f6aa7 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -2,18 +2,36 @@ #include "Python.h" +#include "pycore_bytesobject.h" // _PyBytes_InitTypes() #include "pycore_ceval.h" // _PyEval_FiniGIL() #include "pycore_context.h" // _PyContext_Init() +#include "pycore_exceptions.h" // _PyExc_InitTypes() +#include "pycore_dict.h" // _PyDict_Fini() #include "pycore_fileutils.h" // _Py_ResetForceASCII() +#include "pycore_floatobject.h" // _PyFloat_InitTypes() +#include "pycore_genobject.h" // _PyAsyncGen_Fini() +#include "pycore_global_objects_fini_generated.h" // "_PyStaticObjects_CheckRefcnt() #include "pycore_import.h" // _PyImport_BootstrapImp() #include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_list.h" // _PyList_Fini() +#include "pycore_long.h" // _PyLong_InitTypes() #include "pycore_object.h" // _PyDebug_PrintTotalRefs() #include "pycore_pathconfig.h" // _PyConfig_WritePathConfig() #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pylifecycle.h" // _PyErr_Print() +#include "pycore_pymem.h" // _PyObject_DebugMallocStats() #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_runtime.h" // _Py_ID() +#include "pycore_runtime_init.h" // _PyRuntimeState_INIT +#include "pycore_sliceobject.h" // _PySlice_Fini() #include "pycore_sysmodule.h" // _PySys_ClearAuditHooks() #include "pycore_traceback.h" // _Py_DumpTracebackThreads() +#include "pycore_tuple.h" // _PyTuple_InitTypes() +#include "pycore_typeobject.h" // _PyTypes_InitTypes() +#include "pycore_unicodeobject.h" // _PyUnicode_InitTypes() +#include "opcode.h" + +extern void _PyIO_Fini(void); #include // setlocale() #include // getenv() @@ -30,9 +48,12 @@ # include // nl_langinfo(CODESET) #endif +#ifdef HAVE_FCNTL_H +# include // F_GETFD +#endif + #ifdef MS_WINDOWS # undef BYTE -# include "windows.h" extern PyTypeObject PyWindowsConsoleIO_Type; # define PyWindowsConsoleIO_Check(op) \ @@ -42,13 +63,6 @@ #define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) -_Py_IDENTIFIER(flush); -_Py_IDENTIFIER(name); -_Py_IDENTIFIER(stdin); -_Py_IDENTIFIER(stdout); -_Py_IDENTIFIER(stderr); -_Py_IDENTIFIER(threading); - #ifdef __cplusplus extern "C" { #endif @@ -62,13 +76,15 @@ static PyStatus init_sys_streams(PyThreadState *tstate); static void wait_for_thread_shutdown(PyThreadState *tstate); static void call_ll_exitfuncs(_PyRuntimeState *runtime); -int _Py_UnhandledKeyboardInterrupt = 0; - /* The following places the `_PyRuntime` structure in a location that can be * found without any external information. This is meant to ease access to the * interpreter state for various runtime debugging tools, but is *not* an * officially supported feature */ +/* Suppress deprecation warning for PyBytesObject.ob_shash */ +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS + #if defined(MS_WINDOWS) #pragma section("PyRuntime", read, write) @@ -86,7 +102,9 @@ _PyRuntimeState _PyRuntime #if defined(__linux__) && (defined(__GNUC__) || defined(__clang__)) __attribute__ ((section (".PyRuntime"))) #endif -= _PyRuntimeState_INIT; += _PyRuntimeState_INIT(_PyRuntime); +_Py_COMP_DIAG_POP + static int runtime_initialized = 0; PyStatus @@ -455,13 +473,15 @@ interpreter_update_config(PyThreadState *tstate, int only_update_path_config) } if (_Py_IsMainInterpreter(tstate->interp)) { - PyStatus status = _PyConfig_WritePathConfig(config); + PyStatus status = _PyPathConfig_UpdateGlobal(config); if (_PyStatus_EXCEPTION(status)) { _PyErr_SetFromPyStatus(status); return -1; } } + tstate->interp->long_state.max_str_digits = config->int_max_str_digits; + // Update the sys module for the new configuration if (_PySys_UpdateConfig(tstate) < 0) { return -1; @@ -484,7 +504,7 @@ _PyInterpreterState_SetConfig(const PyConfig *src_config) goto done; } - status = PyConfig_Read(&config); + status = _PyConfig_Read(&config, 1); if (_PyStatus_EXCEPTION(status)) { _PyErr_SetFromPyStatus(status); goto done; @@ -545,7 +565,7 @@ pyinit_core_reconfigure(_PyRuntimeState *runtime, config = _PyInterpreterState_GetConfig(interp); if (config->_install_importlib) { - status = _PyConfig_WritePathConfig(config); + status = _PyPathConfig_UpdateGlobal(config); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -578,11 +598,23 @@ pycore_init_runtime(_PyRuntimeState *runtime, */ _PyRuntimeState_SetFinalizing(runtime, NULL); + _Py_InitVersion(); + status = _Py_HashRandomization_Init(config); if (_PyStatus_EXCEPTION(status)) { return status; } + status = _PyTime_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyImport_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + status = _PyInterpreterState_Enable(runtime); if (_PyStatus_EXCEPTION(status)) { return status; @@ -591,6 +623,28 @@ pycore_init_runtime(_PyRuntimeState *runtime, } +static void +init_interp_settings(PyInterpreterState *interp, const _PyInterpreterConfig *config) +{ + assert(interp->feature_flags == 0); + + if (config->allow_fork) { + interp->feature_flags |= Py_RTFLAGS_FORK; + } + if (config->allow_exec) { + interp->feature_flags |= Py_RTFLAGS_EXEC; + } + // Note that fork+exec is always allowed. + + if (config->allow_threads) { + interp->feature_flags |= Py_RTFLAGS_THREADS; + } + if (config->allow_daemon_threads) { + interp->feature_flags |= Py_RTFLAGS_DAEMON_THREADS; + } +} + + static PyStatus init_interp_create_gil(PyThreadState *tstate) { @@ -618,26 +672,30 @@ init_interp_create_gil(PyThreadState *tstate) static PyStatus pycore_create_interpreter(_PyRuntimeState *runtime, - const PyConfig *config, + const PyConfig *src_config, PyThreadState **tstate_p) { - /* Auto-thread-state API */ - PyStatus status = _PyGILState_Init(runtime); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - + PyStatus status; PyInterpreterState *interp = PyInterpreterState_New(); if (interp == NULL) { return _PyStatus_ERR("can't make main interpreter"); } assert(_Py_IsMainInterpreter(interp)); - status = _PyConfig_Copy(&interp->config, config); + status = _PyConfig_Copy(&interp->config, src_config); if (_PyStatus_EXCEPTION(status)) { return status; } + /* Auto-thread-state API */ + status = _PyGILState_Init(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + const _PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT; + init_interp_settings(interp, &config); + PyThreadState *tstate = PyThreadState_New(interp); if (tstate == NULL) { return _PyStatus_ERR("can't make first thread"); @@ -655,30 +713,18 @@ pycore_create_interpreter(_PyRuntimeState *runtime, static PyStatus -pycore_init_singletons(PyInterpreterState *interp) +pycore_init_global_objects(PyInterpreterState *interp) { PyStatus status; - _PyLong_Init(interp); + _PyFloat_InitState(interp); - if (_Py_IsMainInterpreter(interp)) { - _PyFloat_Init(); - } - - status = _PyBytes_Init(interp); + status = _PyUnicode_InitGlobalObjects(interp); if (_PyStatus_EXCEPTION(status)) { return status; } - status = _PyUnicode_Init(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = _PyTuple_Init(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } + _PyUnicode_InitState(interp); return _PyStatus_OK(); } @@ -688,53 +734,78 @@ static PyStatus pycore_init_types(PyInterpreterState *interp) { PyStatus status; - int is_main_interp = _Py_IsMainInterpreter(interp); - if (is_main_interp) { - if (_PyStructSequence_Init() < 0) { - return _PyStatus_ERR("can't initialize structseq"); - } - - status = _PyTypes_Init(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (_PyLong_InitTypes() < 0) { - return _PyStatus_ERR("can't init int type"); - } - - status = _PyUnicode_InitTypes(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - } - - if (is_main_interp) { - if (_PyFloat_InitTypes() < 0) { - return _PyStatus_ERR("can't init float"); - } - } - - status = _PyExc_Init(interp); + status = _PyTypes_InitTypes(interp); if (_PyStatus_EXCEPTION(status)) { return status; } - status = _PyErr_InitTypes(); + status = _PyBytes_InitTypes(interp); if (_PyStatus_EXCEPTION(status)) { return status; } - if (is_main_interp) { - if (!_PyContext_Init()) { - return _PyStatus_ERR("can't init context"); - } + status = _PyLong_InitTypes(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } + status = _PyUnicode_InitTypes(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyFloat_InitTypes(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyTuple_InitTypes(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (_PyExc_InitTypes(interp) < 0) { + return _PyStatus_ERR("failed to initialize an exception type"); + } + + status = _PyExc_InitGlobalObjects(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyExc_InitState(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyErr_InitTypes(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyContext_Init(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } return _PyStatus_OK(); } +static const uint8_t INTERPRETER_TRAMPOLINE_INSTRUCTIONS[] = { + /* Put a NOP at the start, so that the IP points into + * the code, rather than before it */ + NOP, 0, + INTERPRETER_EXIT, 0, + /* RESUME at end makes sure that the frame appears incomplete */ + RESUME, 0 +}; + +static const _PyShimCodeDef INTERPRETER_TRAMPOLINE_CODEDEF = { + INTERPRETER_TRAMPOLINE_INSTRUCTIONS, + sizeof(INTERPRETER_TRAMPOLINE_INSTRUCTIONS), + 1, + "" +}; static PyStatus pycore_init_builtins(PyThreadState *tstate) @@ -754,12 +825,26 @@ pycore_init_builtins(PyThreadState *tstate) if (builtins_dict == NULL) { goto error; } - Py_INCREF(builtins_dict); - interp->builtins = builtins_dict; + interp->builtins = Py_NewRef(builtins_dict); - PyStatus status = _PyBuiltins_AddExceptions(bimod); - if (_PyStatus_EXCEPTION(status)) { - return status; + PyObject *isinstance = PyDict_GetItem(builtins_dict, &_Py_ID(isinstance)); + assert(isinstance); + interp->callable_cache.isinstance = isinstance; + PyObject *len = PyDict_GetItem(builtins_dict, &_Py_ID(len)); + assert(len); + interp->callable_cache.len = len; + PyObject *list_append = _PyType_Lookup(&PyList_Type, &_Py_ID(append)); + assert(list_append); + interp->callable_cache.list_append = list_append; + PyObject *object__getattribute__ = _PyType_Lookup(&PyBaseObject_Type, &_Py_ID(__getattribute__)); + assert(object__getattribute__); + interp->callable_cache.object__getattribute__ = object__getattribute__; + interp->interpreter_trampoline = _Py_MakeShimCode(&INTERPRETER_TRAMPOLINE_CODEDEF); + if (interp->interpreter_trampoline == NULL) { + return _PyStatus_ERR("failed to create interpreter trampoline."); + } + if (_PyBuiltins_AddExceptions(bimod) < 0) { + return _PyStatus_ERR("failed to add exceptions to builtins"); } interp->builtins_copy = PyDict_Copy(interp->builtins); @@ -795,7 +880,7 @@ pycore_interp_init(PyThreadState *tstate) // Create singletons before the first PyType_Ready() call, since // PyType_Ready() uses singletons like the Unicode empty string (tp_doc) // and the empty tuple singletons (tp_bases). - status = pycore_init_singletons(interp); + status = pycore_init_global_objects(interp); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -805,6 +890,11 @@ pycore_interp_init(PyThreadState *tstate) if (_PyStatus_EXCEPTION(status)) { return status; } + // Intern strings in deep-frozen modules first so that others + // can use it instead of creating a heap allocated string. + if (_Py_Deepfreeze_Init() < 0) { + return _PyStatus_ERR("failed to initialize deep-frozen modules"); + } status = pycore_init_types(interp); if (_PyStatus_EXCEPTION(status)) { @@ -1056,8 +1146,6 @@ pyinit_main_reconfigure(PyThreadState *tstate) static PyStatus init_interp_main(PyThreadState *tstate) { - extern void _PyThread_debug_deprecation(void); - assert(!_PyErr_Occurred(tstate)); PyStatus status; @@ -1113,6 +1201,16 @@ init_interp_main(PyThreadState *tstate) if (_PyTraceMalloc_Init(config->tracemalloc) < 0) { return _PyStatus_ERR("can't initialize tracemalloc"); } + + +#ifdef PY_HAVE_PERF_TRAMPOLINE + if (config->perf_profiling) { + if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_callbacks) < 0 || + _PyPerfTrampoline_Init(config->perf_profiling) < 0) { + return _PyStatus_ERR("can't initialize the perf trampoline"); + } + } +#endif } status = init_sys_streams(tstate); @@ -1159,9 +1257,6 @@ init_interp_main(PyThreadState *tstate) #endif } - // Warn about PYTHONTHREADDEBUG deprecation - _PyThread_debug_deprecation(); - assert(!_PyErr_Occurred(tstate)); return _PyStatus_OK(); @@ -1254,6 +1349,7 @@ Py_InitializeEx(int install_sigs) config.install_signal_handlers = install_sigs; status = Py_InitializeFromConfig(&config); + PyConfig_Clear(&config); if (_PyStatus_EXCEPTION(status)) { Py_ExitStatusException(status); } @@ -1415,8 +1511,7 @@ finalize_clear_modules_dict(PyObject *modules) PyDict_Clear(modules); } else { - _Py_IDENTIFIER(clear); - if (_PyObject_CallMethodIdNoArgs(modules, &PyId_clear) == NULL) { + if (PyObject_CallMethodNoArgs(modules, &_Py_ID(clear)) == NULL) { PyErr_WriteUnraisable(NULL); } } @@ -1433,7 +1528,7 @@ finalize_restore_builtins(PyThreadState *tstate) } PyDict_Clear(interp->builtins); if (PyDict_Update(interp->builtins, interp->builtins_copy)) { - _PyErr_Clear(tstate); + PyErr_WriteUnraisable(NULL); } Py_XDECREF(dict); } @@ -1587,13 +1682,14 @@ file_is_closed(PyObject *fobj) static int flush_std_files(void) { - PyObject *fout = _PySys_GetObjectId(&PyId_stdout); - PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *fout = _PySys_GetAttr(tstate, &_Py_ID(stdout)); + PyObject *ferr = _PySys_GetAttr(tstate, &_Py_ID(stderr)); PyObject *tmp; int status = 0; if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { - tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_flush); + tmp = PyObject_CallMethodNoArgs(fout, &_Py_ID(flush)); if (tmp == NULL) { PyErr_WriteUnraisable(fout); status = -1; @@ -1603,7 +1699,7 @@ flush_std_files(void) } if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) { - tmp = _PyObject_CallMethodIdNoArgs(ferr, &PyId_flush); + tmp = PyObject_CallMethodNoArgs(ferr, &_Py_ID(flush)); if (tmp == NULL) { PyErr_Clear(); status = -1; @@ -1633,11 +1729,19 @@ flush_std_files(void) static void finalize_interp_types(PyInterpreterState *interp) { + _PyUnicode_FiniTypes(interp); + _PySys_Fini(interp); _PyExc_Fini(interp); - _PyFrame_Fini(interp); _PyAsyncGen_Fini(interp); _PyContext_Fini(interp); - _PyType_Fini(interp); + _PyFloat_FiniType(interp); + _PyLong_FiniTypes(interp); + _PyThread_FiniType(interp); + _PyErr_FiniTypes(interp); + _PyTypes_FiniTypes(interp); + + _PyTypes_Fini(interp); + // Call _PyUnicode_ClearInterned() before _PyDict_Fini() since it uses // a dict internally. _PyUnicode_ClearInterned(interp); @@ -1648,10 +1752,11 @@ finalize_interp_types(PyInterpreterState *interp) _PySlice_Fini(interp); - _PyBytes_Fini(interp); _PyUnicode_Fini(interp); _PyFloat_Fini(interp); - _PyLong_Fini(interp); +#ifdef Py_DEBUG + _PyStaticObjects_CheckRefcnt(interp); +#endif } @@ -1665,6 +1770,10 @@ finalize_interp_clear(PyThreadState *tstate) /* Clear interpreter state and all thread states */ _PyInterpreterState_Clear(tstate); + if (is_main_interp) { + _PyIO_Fini(); + } + /* Clear all loghooks */ /* Both _PySys_Audit function and users still need PyObject, such as tuple. Call _PySys_ClearAuditHooks when PyObject available. */ @@ -1676,6 +1785,8 @@ finalize_interp_clear(PyThreadState *tstate) _Py_HashRandomization_Fini(); _PyArg_Fini(); _Py_ClearFileSystemEncoding(); + _Py_Deepfreeze_Fini(); + _PyPerfTrampoline_Fini(); } finalize_interp_types(tstate->interp); @@ -1685,10 +1796,8 @@ finalize_interp_clear(PyThreadState *tstate) static void finalize_interp_delete(PyInterpreterState *interp) { - if (_Py_IsMainInterpreter(interp)) { - /* Cleanup auto-thread-state */ - _PyGILState_Fini(interp); - } + /* Cleanup auto-thread-state */ + _PyGILState_Fini(interp); /* We can't call _PyEval_FiniGIL() here because destroying the GIL lock can fail when it is being awaited by another running daemon thread (see @@ -1825,12 +1934,6 @@ Py_FinalizeEx(void) /* dump hash stats */ _PyHash_Fini(); -#ifdef Py_REF_DEBUG - if (show_ref_count) { - _PyDebug_PrintTotalRefs(); - } -#endif - #ifdef Py_TRACE_REFS /* Display all objects still alive -- this can invoke arbitrary * __repr__ overrides, so requires a mostly-intact interpreter. @@ -1858,6 +1961,12 @@ Py_FinalizeEx(void) finalize_interp_clear(tstate); finalize_interp_delete(tstate->interp); +#ifdef Py_REF_DEBUG + if (show_ref_count) { + _PyDebug_PrintTotalRefs(); + } +#endif + #ifdef Py_TRACE_REFS /* Display addresses (& refcnts) of all objects still alive. * An address can be used to find the repr of the object, printed @@ -1906,7 +2015,7 @@ Py_Finalize(void) */ static PyStatus -new_interpreter(PyThreadState **tstate_p, int isolated_subinterpreter) +new_interpreter(PyThreadState **tstate_p, const _PyInterpreterConfig *config) { PyStatus status; @@ -1940,25 +2049,23 @@ new_interpreter(PyThreadState **tstate_p, int isolated_subinterpreter) PyThreadState *save_tstate = PyThreadState_Swap(tstate); /* Copy the current interpreter config into the new interpreter */ - const PyConfig *config; -#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS + const PyConfig *src_config; if (save_tstate != NULL) { - config = _PyInterpreterState_GetConfig(save_tstate->interp); + src_config = _PyInterpreterState_GetConfig(save_tstate->interp); } else -#endif { /* No current thread state, copy from the main interpreter */ - PyInterpreterState *main_interp = PyInterpreterState_Main(); - config = _PyInterpreterState_GetConfig(main_interp); + PyInterpreterState *main_interp = _PyInterpreterState_Main(); + src_config = _PyInterpreterState_GetConfig(main_interp); } - - status = _PyConfig_Copy(&interp->config, config); + status = _PyConfig_Copy(&interp->config, src_config); if (_PyStatus_EXCEPTION(status)) { goto error; } - interp->config._isolated_interpreter = isolated_subinterpreter; + + init_interp_settings(interp, config); status = init_interp_create_gil(tstate); if (_PyStatus_EXCEPTION(status)) { @@ -1992,21 +2099,21 @@ error: } PyThreadState * -_Py_NewInterpreter(int isolated_subinterpreter) +_Py_NewInterpreterFromConfig(const _PyInterpreterConfig *config) { PyThreadState *tstate = NULL; - PyStatus status = new_interpreter(&tstate, isolated_subinterpreter); + PyStatus status = new_interpreter(&tstate, config); if (_PyStatus_EXCEPTION(status)) { Py_ExitStatusException(status); } return tstate; - } PyThreadState * Py_NewInterpreter(void) { - return _Py_NewInterpreter(0); + const _PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT; + return _Py_NewInterpreterFromConfig(&config); } /* Delete an interpreter and its last thread. This requires that the @@ -2039,7 +2146,7 @@ Py_EndInterpreter(PyThreadState *tstate) _PyAtExit_Call(tstate->interp); - if (tstate != interp->tstate_head || tstate->next != NULL) { + if (tstate != interp->threads.head || tstate->next != NULL) { Py_FatalError("not the last thread"); } @@ -2129,26 +2236,38 @@ is_valid_fd(int fd) startup. Problem: dup() doesn't check if the file descriptor is valid on some platforms. + fcntl(fd, F_GETFD) is even faster, because it only checks the process table. + It is preferred over dup() when available, since it cannot fail with the + "too many open files" error (EMFILE). + bpo-30225: On macOS Tiger, when stdout is redirected to a pipe and the other side of the pipe is closed, dup(1) succeed, whereas fstat(1, &st) fails with EBADF. FreeBSD has similar issue (bpo-32849). - Only use dup() on platforms where dup() is enough to detect invalid FD in - corner cases: on Linux and Windows (bpo-32849). */ -#if defined(__linux__) || defined(MS_WINDOWS) + Only use dup() on Linux where dup() is enough to detect invalid FD + (bpo-32849). +*/ if (fd < 0) { return 0; } - int fd2; - - _Py_BEGIN_SUPPRESS_IPH - fd2 = dup(fd); +#if defined(F_GETFD) && ( \ + defined(__linux__) || \ + defined(__APPLE__) || \ + defined(__wasm__)) + return fcntl(fd, F_GETFD) >= 0; +#elif defined(__linux__) + int fd2 = dup(fd); if (fd2 >= 0) { close(fd2); } - _Py_END_SUPPRESS_IPH - return (fd2 >= 0); +#elif defined(MS_WINDOWS) + HANDLE hfile; + _Py_BEGIN_SUPPRESS_IPH + hfile = (HANDLE)_get_osfhandle(fd); + _Py_END_SUPPRESS_IPH + return (hfile != INVALID_HANDLE_VALUE + && GetFileType(hfile) != FILE_TYPE_UNKNOWN); #else struct stat st; return (fstat(fd, &st) == 0); @@ -2166,10 +2285,6 @@ create_stdio(const PyConfig *config, PyObject* io, const char* newline; PyObject *line_buffering, *write_through; int buffering, isatty; - _Py_IDENTIFIER(open); - _Py_IDENTIFIER(isatty); - _Py_IDENTIFIER(TextIOWrapper); - _Py_IDENTIFIER(mode); const int buffered_stdio = config->buffered_stdio; if (!is_valid_fd(fd)) @@ -2188,22 +2303,20 @@ create_stdio(const PyConfig *config, PyObject* io, mode = "wb"; else mode = "rb"; - buf = _PyObject_CallMethodId(io, &PyId_open, "isiOOOO", - fd, mode, buffering, - Py_None, Py_None, /* encoding, errors */ - Py_None, Py_False); /* newline, closefd */ + buf = _PyObject_CallMethod(io, &_Py_ID(open), "isiOOOO", + fd, mode, buffering, + Py_None, Py_None, /* encoding, errors */ + Py_None, Py_False); /* newline, closefd */ if (buf == NULL) goto error; if (buffering) { - _Py_IDENTIFIER(raw); - raw = _PyObject_GetAttrId(buf, &PyId_raw); + raw = PyObject_GetAttr(buf, &_Py_ID(raw)); if (raw == NULL) goto error; } else { - raw = buf; - Py_INCREF(raw); + raw = Py_NewRef(buf); } #ifdef MS_WINDOWS @@ -2213,9 +2326,9 @@ create_stdio(const PyConfig *config, PyObject* io, #endif text = PyUnicode_FromString(name); - if (text == NULL || _PyObject_SetAttrId(raw, &PyId_name, text) < 0) + if (text == NULL || PyObject_SetAttr(raw, &_Py_ID(name), text) < 0) goto error; - res = _PyObject_CallMethodIdNoArgs(raw, &PyId_isatty); + res = PyObject_CallMethodNoArgs(raw, &_Py_ID(isatty)); if (res == NULL) goto error; isatty = PyObject_IsTrue(res); @@ -2258,9 +2371,9 @@ create_stdio(const PyConfig *config, PyObject* io, goto error; } - stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OOOsOO", - buf, encoding_str, errors_str, - newline, line_buffering, write_through); + stream = _PyObject_CallMethod(io, &_Py_ID(TextIOWrapper), "OOOsOO", + buf, encoding_str, errors_str, + newline, line_buffering, write_through); Py_CLEAR(buf); Py_CLEAR(encoding_str); Py_CLEAR(errors_str); @@ -2272,7 +2385,7 @@ create_stdio(const PyConfig *config, PyObject* io, else mode = "r"; text = PyUnicode_FromString(mode); - if (!text || _PyObject_SetAttrId(stream, &PyId_mode, text) < 0) + if (!text || PyObject_SetAttr(stream, &_Py_ID(mode), text) < 0) goto error; Py_CLEAR(text); return stream; @@ -2297,19 +2410,15 @@ error: static PyStatus init_set_builtins_open(void) { - PyObject *iomod = NULL, *wrapper; + PyObject *wrapper; PyObject *bimod = NULL; PyStatus res = _PyStatus_OK(); - if (!(iomod = PyImport_ImportModule("io"))) { - goto error; - } - if (!(bimod = PyImport_ImportModule("builtins"))) { goto error; } - if (!(wrapper = PyObject_GetAttrString(iomod, "open"))) { + if (!(wrapper = _PyImport_GetModuleAttrString("io", "open"))) { goto error; } @@ -2326,7 +2435,6 @@ error: done: Py_XDECREF(bimod); - Py_XDECREF(iomod); return res; } @@ -2371,7 +2479,7 @@ init_sys_streams(PyThreadState *tstate) if (std == NULL) goto error; PySys_SetObject("__stdin__", std); - _PySys_SetObjectId(&PyId_stdin, std); + _PySys_SetAttr(&_Py_ID(stdin), std); Py_DECREF(std); /* Set sys.stdout */ @@ -2382,7 +2490,7 @@ init_sys_streams(PyThreadState *tstate) if (std == NULL) goto error; PySys_SetObject("__stdout__", std); - _PySys_SetObjectId(&PyId_stdout, std); + _PySys_SetAttr(&_Py_ID(stdout), std); Py_DECREF(std); #if 1 /* Disable this if you have trouble debugging bootstrap stuff */ @@ -2411,7 +2519,7 @@ init_sys_streams(PyThreadState *tstate) Py_DECREF(std); goto error; } - if (_PySys_SetObjectId(&PyId_stderr, std) < 0) { + if (_PySys_SetAttr(&_Py_ID(stderr), std) < 0) { Py_DECREF(std); goto error; } @@ -2461,7 +2569,7 @@ _Py_FatalError_PrintExc(PyThreadState *tstate) return 0; } - ferr = _PySys_GetObjectId(&PyId_stderr); + ferr = _PySys_GetAttr(tstate, &_Py_ID(stderr)); if (ferr == NULL || ferr == Py_None) { /* sys.stderr is not set yet or set to None, no need to try to display the exception */ @@ -2470,8 +2578,7 @@ _Py_FatalError_PrintExc(PyThreadState *tstate) _PyErr_NormalizeException(tstate, &exception, &v, &tb); if (tb == NULL) { - tb = Py_None; - Py_INCREF(tb); + tb = Py_NewRef(Py_None); } PyException_SetTraceback(v, tb); if (exception == NULL) { @@ -2486,7 +2593,7 @@ _Py_FatalError_PrintExc(PyThreadState *tstate) Py_XDECREF(tb); /* sys.stderr may be buffered: call sys.stderr.flush() */ - res = _PyObject_CallMethodIdNoArgs(ferr, &PyId_flush); + res = PyObject_CallMethodNoArgs(ferr, &_Py_ID(flush)); if (res == NULL) { _PyErr_Clear(tstate); } @@ -2791,11 +2898,7 @@ _Py_FatalErrorFormat(const char *func, const char *format, ...) } va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif vfprintf(stream, format, vargs); va_end(vargs); @@ -2838,9 +2941,8 @@ Py_ExitStatusException(PyStatus status) static void wait_for_thread_shutdown(PyThreadState *tstate) { - _Py_IDENTIFIER(_shutdown); PyObject *result; - PyObject *threading = _PyImport_GetModuleId(&PyId_threading); + PyObject *threading = PyImport_GetModule(&_Py_ID(threading)); if (threading == NULL) { if (_PyErr_Occurred(tstate)) { PyErr_WriteUnraisable(NULL); @@ -2848,7 +2950,7 @@ wait_for_thread_shutdown(PyThreadState *tstate) /* else: threading not imported */ return; } - result = _PyObject_CallMethodIdNoArgs(threading, &PyId__shutdown); + result = PyObject_CallMethodNoArgs(threading, &_Py_ID(_shutdown)); if (result == NULL) { PyErr_WriteUnraisable(threading); } @@ -2903,28 +3005,30 @@ Py_Exit(int sts) int Py_FdIsInteractive(FILE *fp, const char *filename) { - if (isatty((int)fileno(fp))) + if (isatty(fileno(fp))) { return 1; - if (!Py_InteractiveFlag) + } + if (!_Py_GetConfig()->interactive) { return 0; - return (filename == NULL) || - (strcmp(filename, "") == 0) || - (strcmp(filename, "???") == 0); + } + return ((filename == NULL) + || (strcmp(filename, "") == 0) + || (strcmp(filename, "???") == 0)); } int _Py_FdIsInteractive(FILE *fp, PyObject *filename) { - if (isatty((int)fileno(fp))) { + if (isatty(fileno(fp))) { return 1; } - if (!Py_InteractiveFlag) { + if (!_Py_GetConfig()->interactive) { return 0; } - return (filename == NULL) || - (PyUnicode_CompareWithASCIIString(filename, "") == 0) || - (PyUnicode_CompareWithASCIIString(filename, "???") == 0); + return ((filename == NULL) + || (PyUnicode_CompareWithASCIIString(filename, "") == 0) + || (PyUnicode_CompareWithASCIIString(filename, "???") == 0)); } diff --git a/Python/pystate.c b/Python/pystate.c index 273982b4bd2..bf7688fd321 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -3,13 +3,15 @@ #include "Python.h" #include "pycore_ceval.h" +#include "pycore_code.h" // stats #include "pycore_frame.h" #include "pycore_initconfig.h" #include "pycore_object.h" // _PyType_InitCache() #include "pycore_pyerrors.h" #include "pycore_pylifecycle.h" #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() -#include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_pystate.h" +#include "pycore_runtime_init.h" // _PyRuntimeState_INIT #include "pycore_sysmodule.h" /* -------------------------------------------------------------------------- @@ -35,31 +37,315 @@ to avoid the expense of doing their own locking). extern "C" { #endif -#define _PyRuntimeGILState_GetThreadState(gilstate) \ - ((PyThreadState*)_Py_atomic_load_relaxed(&(gilstate)->tstate_current)) -#define _PyRuntimeGILState_SetThreadState(gilstate, value) \ - _Py_atomic_store_relaxed(&(gilstate)->tstate_current, \ - (uintptr_t)(value)) - /* Forward declarations */ -static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate); static void _PyThreadState_Delete(PyThreadState *tstate, int check_current); -static PyStatus -_PyRuntimeState_Init_impl(_PyRuntimeState *runtime) -{ - /* We preserve the hook across init, because there is - currently no public API to set it between runtime - initialization and interpreter initialization. */ - void *open_code_hook = runtime->open_code_hook; - void *open_code_userdata = runtime->open_code_userdata; - _Py_AuditHookEntry *audit_hook_head = runtime->audit_hook_head; - // bpo-42882: Preserve next_index value if Py_Initialize()/Py_Finalize() - // is called multiple times. - Py_ssize_t unicode_next_index = runtime->unicode_ids.next_index; +/****************************************/ +/* helpers for the current thread state */ +/****************************************/ - memset(runtime, 0, sizeof(*runtime)); +// API for the current thread state is further down. + +/* "current" means one of: + - bound to the current OS thread + - holds the GIL + */ + +//------------------------------------------------- +// a highly efficient lookup for the current thread +//------------------------------------------------- + +/* + The stored thread state is set by PyThreadState_Swap(). + + For each of these functions, the GIL must be held by the current thread. + */ + +static inline PyThreadState * +current_fast_get(_PyRuntimeState *runtime) +{ + return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->tstate_current); +} + +static inline void +current_fast_set(_PyRuntimeState *runtime, PyThreadState *tstate) +{ + assert(tstate != NULL); + _Py_atomic_store_relaxed(&runtime->tstate_current, (uintptr_t)tstate); +} + +static inline void +current_fast_clear(_PyRuntimeState *runtime) +{ + _Py_atomic_store_relaxed(&runtime->tstate_current, (uintptr_t)NULL); +} + + +//------------------------------------------------ +// the thread state bound to the current OS thread +//------------------------------------------------ + +/* + The stored thread state is set by bind_tstate() (AKA PyThreadState_Bind(). + + The GIL does no need to be held for these. + */ + +static int +current_tss_initialized(_PyRuntimeState *runtime) +{ + return PyThread_tss_is_created(&runtime->autoTSSkey); +} + +static PyStatus +current_tss_init(_PyRuntimeState *runtime) +{ + assert(!current_tss_initialized(runtime)); + if (PyThread_tss_create(&runtime->autoTSSkey) != 0) { + return _PyStatus_NO_MEMORY(); + } + return _PyStatus_OK(); +} + +static void +current_tss_fini(_PyRuntimeState *runtime) +{ + assert(current_tss_initialized(runtime)); + PyThread_tss_delete(&runtime->autoTSSkey); +} + +static inline PyThreadState * +current_tss_get(_PyRuntimeState *runtime) +{ + assert(current_tss_initialized(runtime)); + return (PyThreadState *)PyThread_tss_get(&runtime->autoTSSkey); +} + +static inline int +_current_tss_set(_PyRuntimeState *runtime, PyThreadState *tstate) +{ + assert(tstate != NULL); + assert(current_tss_initialized(runtime)); + return PyThread_tss_set(&runtime->autoTSSkey, (void *)tstate); +} +static inline void +current_tss_set(_PyRuntimeState *runtime, PyThreadState *tstate) +{ + if (_current_tss_set(runtime, tstate) != 0) { + Py_FatalError("failed to set current tstate (TSS)"); + } +} + +static inline void +current_tss_clear(_PyRuntimeState *runtime) +{ + assert(current_tss_initialized(runtime)); + if (PyThread_tss_set(&runtime->autoTSSkey, NULL) != 0) { + Py_FatalError("failed to clear current tstate (TSS)"); + } +} + +#ifdef HAVE_FORK +/* Reset the TSS key - called by PyOS_AfterFork_Child(). + * This should not be necessary, but some - buggy - pthread implementations + * don't reset TSS upon fork(), see issue #10517. + */ +static PyStatus +current_tss_reinit(_PyRuntimeState *runtime) +{ + if (!current_tss_initialized(runtime)) { + return _PyStatus_OK(); + } + PyThreadState *tstate = current_tss_get(runtime); + + current_tss_fini(runtime); + PyStatus status = current_tss_init(runtime); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + /* If the thread had an associated auto thread state, reassociate it with + * the new key. */ + if (tstate && _current_tss_set(runtime, tstate) != 0) { + return _PyStatus_ERR("failed to set autoTSSkey"); + } + return _PyStatus_OK(); +} +#endif + + +static void +bind_tstate(PyThreadState *tstate) +{ + assert(tstate != NULL); + assert(tstate->_status == PyThreadState_INITIALIZED); + assert(tstate->thread_id == 0); + assert(tstate->native_thread_id == 0); + _PyRuntimeState *runtime = tstate->interp->runtime; + + /* Stick the thread state for this thread in thread specific storage. + + The only situation where you can legitimately have more than one + thread state for an OS level thread is when there are multiple + interpreters. + + You shouldn't really be using the PyGILState_ APIs anyway (see issues + #10915 and #15751). + + The first thread state created for that given OS level thread will + "win", which seems reasonable behaviour. + */ + /* When a thread state is created for a thread by some mechanism + other than PyGILState_Ensure(), it's important that the GILState + machinery knows about it so it doesn't try to create another + thread state for the thread. + (This is a better fix for SF bug #1010677 than the first one attempted.) + */ + // XXX Skipping like this does not play nice with multiple interpreters. + if (current_tss_get(runtime) == NULL) { + current_tss_set(runtime, tstate); + } + + tstate->thread_id = PyThread_get_thread_ident(); +#ifdef PY_HAVE_THREAD_NATIVE_ID + tstate->native_thread_id = PyThread_get_thread_native_id(); +#endif + + tstate->_status = PyThreadState_BOUND; +} + +static void +unbind_tstate(PyThreadState *tstate) +{ + assert(tstate != NULL); + assert(tstate->_status == PyThreadState_BOUND); + assert(tstate->thread_id > 0); +#ifdef PY_HAVE_THREAD_NATIVE_ID + assert(tstate->native_thread_id > 0); +#endif + _PyRuntimeState *runtime = tstate->interp->runtime; + + if (current_tss_initialized(runtime) && + tstate == current_tss_get(runtime)) + { + current_tss_clear(runtime); + } + + // We leave thread_id and native_thread_id alone + // since they can be useful for debugging. + // Check the `_status` field to know if these values + // are still valid. + + tstate->_status = PyThreadState_UNBOUND; +} + + +//---------------------------------------------- +// the thread state that currently holds the GIL +//---------------------------------------------- + +/* This is not exported, as it is not reliable! It can only + ever be compared to the state for the *current* thread. + * If not equal, then it doesn't matter that the actual + value may change immediately after comparison, as it can't + possibly change to the current thread's state. + * If equal, then the current thread holds the lock, so the value can't + change until we yield the lock. +*/ +static int +holds_gil(PyThreadState *tstate) +{ + // XXX Fall back to tstate->interp->runtime->ceval.gil.last_holder + // (and tstate->interp->runtime->ceval.gil.locked). + assert(tstate != NULL); + _PyRuntimeState *runtime = tstate->interp->runtime; + /* Must be the tstate for this thread */ + assert(tstate == current_tss_get(runtime)); + return tstate == current_fast_get(runtime); +} + + +/****************************/ +/* the global runtime state */ +/****************************/ + +//---------- +// lifecycle +//---------- + +/* Suppress deprecation warning for PyBytesObject.ob_shash */ +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS +/* We use "initial" if the runtime gets re-used + (e.g. Py_Finalize() followed by Py_Initialize(). + Note that we initialize "initial" relative to _PyRuntime, + to ensure pre-initialized pointers point to the active + runtime state (and not "initial"). */ +static const _PyRuntimeState initial = _PyRuntimeState_INIT(_PyRuntime); +_Py_COMP_DIAG_POP + +static int +alloc_for_runtime(PyThread_type_lock *plock1, PyThread_type_lock *plock2, + PyThread_type_lock *plock3, PyThread_type_lock *plock4) +{ + /* Force default allocator, since _PyRuntimeState_Fini() must + use the same allocator than this function. */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + PyThread_type_lock lock1 = PyThread_allocate_lock(); + if (lock1 == NULL) { + return -1; + } + + PyThread_type_lock lock2 = PyThread_allocate_lock(); + if (lock2 == NULL) { + PyThread_free_lock(lock1); + return -1; + } + + PyThread_type_lock lock3 = PyThread_allocate_lock(); + if (lock3 == NULL) { + PyThread_free_lock(lock1); + PyThread_free_lock(lock2); + return -1; + } + + PyThread_type_lock lock4 = PyThread_allocate_lock(); + if (lock4 == NULL) { + PyThread_free_lock(lock1); + PyThread_free_lock(lock2); + PyThread_free_lock(lock3); + return -1; + } + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + *plock1 = lock1; + *plock2 = lock2; + *plock3 = lock3; + *plock4 = lock4; + return 0; +} + +static void +init_runtime(_PyRuntimeState *runtime, + void *open_code_hook, void *open_code_userdata, + _Py_AuditHookEntry *audit_hook_head, + Py_ssize_t unicode_next_index, + PyThread_type_lock unicode_ids_mutex, + PyThread_type_lock interpreters_mutex, + PyThread_type_lock xidregistry_mutex, + PyThread_type_lock getargs_mutex) +{ + if (runtime->_initialized) { + Py_FatalError("runtime already initialized"); + } + assert(!runtime->preinitializing && + !runtime->preinitialized && + !runtime->core_initialized && + !runtime->initialized); runtime->open_code_hook = open_code_hook; runtime->open_code_userdata = open_code_userdata; @@ -69,53 +355,73 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime) PyPreConfig_InitPythonConfig(&runtime->preconfig); - runtime->gilstate.check_enabled = 1; + runtime->interpreters.mutex = interpreters_mutex; - /* A TSS key must be initialized with Py_tss_NEEDS_INIT - in accordance with the specification. */ - Py_tss_t initial = Py_tss_NEEDS_INIT; - runtime->gilstate.autoTSSkey = initial; + runtime->xidregistry.mutex = xidregistry_mutex; - runtime->interpreters.mutex = PyThread_allocate_lock(); - if (runtime->interpreters.mutex == NULL) { - return _PyStatus_NO_MEMORY(); - } - runtime->interpreters.next_id = -1; - - runtime->xidregistry.mutex = PyThread_allocate_lock(); - if (runtime->xidregistry.mutex == NULL) { - return _PyStatus_NO_MEMORY(); - } + runtime->getargs.mutex = getargs_mutex; // Set it to the ID of the main thread of the main interpreter. runtime->main_thread = PyThread_get_thread_ident(); - runtime->unicode_ids.lock = PyThread_allocate_lock(); - if (runtime->unicode_ids.lock == NULL) { - return _PyStatus_NO_MEMORY(); - } - runtime->unicode_ids.next_index = unicode_next_index; + runtime->unicode_state.ids.next_index = unicode_next_index; + runtime->unicode_state.ids.lock = unicode_ids_mutex; - return _PyStatus_OK(); + runtime->_initialized = 1; } PyStatus _PyRuntimeState_Init(_PyRuntimeState *runtime) { - /* Force default allocator, since _PyRuntimeState_Fini() must - use the same allocator than this function. */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + /* We preserve the hook across init, because there is + currently no public API to set it between runtime + initialization and interpreter initialization. */ + void *open_code_hook = runtime->open_code_hook; + void *open_code_userdata = runtime->open_code_userdata; + _Py_AuditHookEntry *audit_hook_head = runtime->audit_hook_head; + // bpo-42882: Preserve next_index value if Py_Initialize()/Py_Finalize() + // is called multiple times. + Py_ssize_t unicode_next_index = runtime->unicode_state.ids.next_index; - PyStatus status = _PyRuntimeState_Init_impl(runtime); + PyThread_type_lock lock1, lock2, lock3, lock4; + if (alloc_for_runtime(&lock1, &lock2, &lock3, &lock4) != 0) { + return _PyStatus_NO_MEMORY(); + } - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return status; + if (runtime->_initialized) { + // Py_Initialize() must be running again. + // Reset to _PyRuntimeState_INIT. + memcpy(runtime, &initial, sizeof(*runtime)); + } + + PyStatus status = current_tss_init(runtime); + if (_PyStatus_EXCEPTION(status)) { + _PyRuntimeState_Fini(runtime); + return status; + } + + if (PyThread_tss_create(&runtime->trashTSSkey) != 0) { + _PyRuntimeState_Fini(runtime); + return _PyStatus_NO_MEMORY(); + } + + init_runtime(runtime, open_code_hook, open_code_userdata, audit_hook_head, + unicode_next_index, lock1, lock2, lock3, lock4); + + return _PyStatus_OK(); } void _PyRuntimeState_Fini(_PyRuntimeState *runtime) { + if (current_tss_initialized(runtime)) { + current_tss_fini(runtime); + } + + if (PyThread_tss_is_created(&runtime->trashTSSkey)) { + PyThread_tss_delete(&runtime->trashTSSkey); + } + /* Force the allocator used by _PyRuntimeState_Init(). */ PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); @@ -127,7 +433,8 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime) FREE_LOCK(runtime->interpreters.mutex); FREE_LOCK(runtime->xidregistry.mutex); - FREE_LOCK(runtime->unicode_ids.lock); + FREE_LOCK(runtime->unicode_state.ids.lock); + FREE_LOCK(runtime->getargs.mutex); #undef FREE_LOCK PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); @@ -149,7 +456,8 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) int reinit_interp = _PyThread_at_fork_reinit(&runtime->interpreters.mutex); int reinit_xidregistry = _PyThread_at_fork_reinit(&runtime->xidregistry.mutex); - int reinit_unicode_ids = _PyThread_at_fork_reinit(&runtime->unicode_ids.lock); + int reinit_unicode_ids = _PyThread_at_fork_reinit(&runtime->unicode_state.ids.lock); + int reinit_getargs = _PyThread_at_fork_reinit(&runtime->getargs.mutex); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); @@ -160,23 +468,39 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) if (reinit_interp < 0 || reinit_main_id < 0 || reinit_xidregistry < 0 - || reinit_unicode_ids < 0) + || reinit_unicode_ids < 0 + || reinit_getargs < 0) { return _PyStatus_ERR("Failed to reinitialize runtime locks"); } + + PyStatus status = current_tss_reinit(runtime); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + if (PyThread_tss_is_created(&runtime->trashTSSkey)) { + PyThread_tss_delete(&runtime->trashTSSkey); + } + if (PyThread_tss_create(&runtime->trashTSSkey) != 0) { + return _PyStatus_NO_MEMORY(); + } + return _PyStatus_OK(); } #endif -#define HEAD_LOCK(runtime) \ - PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK) -#define HEAD_UNLOCK(runtime) \ - PyThread_release_lock((runtime)->interpreters.mutex) -/* Forward declaration */ -static void _PyGILState_NoteThreadState( - struct _gilstate_runtime_state *gilstate, PyThreadState* tstate); +/*************************************/ +/* the per-interpreter runtime state */ +/*************************************/ + +//---------- +// lifecycle +//---------- + +/* Calling this indicates that the runtime is ready to create interpreters. */ PyStatus _PyInterpreterState_Enable(_PyRuntimeState *runtime) @@ -204,83 +528,140 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime) return _PyStatus_OK(); } + +static PyInterpreterState * +alloc_interpreter(void) +{ + return PyMem_RawCalloc(1, sizeof(PyInterpreterState)); +} + +static void +free_interpreter(PyInterpreterState *interp) +{ + // The main interpreter is statically allocated so + // should not be freed. + if (interp != &_PyRuntime._main_interpreter) { + PyMem_RawFree(interp); + } +} + +/* Get the interpreter state to a minimal consistent state. + Further init happens in pylifecycle.c before it can be used. + All fields not initialized here are expected to be zeroed out, + e.g. by PyMem_RawCalloc() or memset(), or otherwise pre-initialized. + The runtime state is not manipulated. Instead it is assumed that + the interpreter is getting added to the runtime. + */ + +static void +init_interpreter(PyInterpreterState *interp, + _PyRuntimeState *runtime, int64_t id, + PyInterpreterState *next, + PyThread_type_lock pending_lock) +{ + if (interp->_initialized) { + Py_FatalError("interpreter already initialized"); + } + + assert(runtime != NULL); + interp->runtime = runtime; + + assert(id > 0 || (id == 0 && interp == runtime->interpreters.main)); + interp->id = id; + + assert(runtime->interpreters.head == interp); + assert(next != NULL || (interp == runtime->interpreters.main)); + interp->next = next; + + _PyEval_InitState(&interp->ceval, pending_lock); + _PyGC_InitState(&interp->gc); + PyConfig_InitPythonConfig(&interp->config); + _PyType_InitCache(interp); + + interp->_initialized = 1; +} + PyInterpreterState * PyInterpreterState_New(void) { - PyThreadState *tstate = _PyThreadState_GET(); + PyInterpreterState *interp; + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = current_fast_get(runtime); + /* tstate is NULL when Py_InitializeFromConfig() calls PyInterpreterState_New() to create the main interpreter. */ if (_PySys_Audit(tstate, "cpython.PyInterpreterState_New", NULL) < 0) { return NULL; } - PyInterpreterState *interp = PyMem_RawCalloc(1, sizeof(PyInterpreterState)); - if (interp == NULL) { + PyThread_type_lock pending_lock = PyThread_allocate_lock(); + if (pending_lock == NULL) { + if (tstate != NULL) { + _PyErr_NoMemory(tstate); + } return NULL; } - interp->id_refcount = -1; - - /* Don't get runtime from tstate since tstate can be NULL */ - _PyRuntimeState *runtime = &_PyRuntime; - interp->runtime = runtime; - - if (_PyEval_InitState(&interp->ceval) < 0) { - goto out_of_memory; - } - - _PyGC_InitState(&interp->gc); - PyConfig_InitPythonConfig(&interp->config); - _PyType_InitCache(interp); - - interp->eval_frame = NULL; -#ifdef HAVE_DLOPEN -#if HAVE_DECL_RTLD_NOW - interp->dlopenflags = RTLD_NOW; -#else - interp->dlopenflags = RTLD_LAZY; -#endif -#endif - + /* Don't get runtime from tstate since tstate can be NULL. */ struct pyinterpreters *interpreters = &runtime->interpreters; + /* We completely serialize creation of multiple interpreters, since + it simplifies things here and blocking concurrent calls isn't a problem. + Regardless, we must fully block subinterpreter creation until + after the main interpreter is created. */ HEAD_LOCK(runtime); - if (interpreters->next_id < 0) { - /* overflow or Py_Initialize() not called! */ - if (tstate != NULL) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "failed to get an interpreter ID"); - } - PyMem_RawFree(interp); - interp = NULL; + + int64_t id = interpreters->next_id; + interpreters->next_id += 1; + + // Allocate the interpreter and add it to the runtime state. + PyInterpreterState *old_head = interpreters->head; + if (old_head == NULL) { + // We are creating the main interpreter. + assert(interpreters->main == NULL); + assert(id == 0); + + interp = &runtime->_main_interpreter; + assert(interp->id == 0); + assert(interp->next == NULL); + + interpreters->main = interp; } else { - interp->id = interpreters->next_id; - interpreters->next_id += 1; - interp->next = interpreters->head; - if (interpreters->main == NULL) { - interpreters->main = interp; + assert(interpreters->main != NULL); + assert(id != 0); + + interp = alloc_interpreter(); + if (interp == NULL) { + goto error; + } + // Set to _PyInterpreterState_INIT. + memcpy(interp, &initial._main_interpreter, + sizeof(*interp)); + + if (id < 0) { + /* overflow or Py_Initialize() not called yet! */ + if (tstate != NULL) { + _PyErr_SetString(tstate, PyExc_RuntimeError, + "failed to get an interpreter ID"); + } + goto error; } - interpreters->head = interp; } + interpreters->head = interp; + + init_interpreter(interp, runtime, id, old_head, pending_lock); + HEAD_UNLOCK(runtime); - - if (interp == NULL) { - return NULL; - } - - interp->tstate_next_unique_id = 0; - - interp->audit_hooks = NULL; - return interp; -out_of_memory: - if (tstate != NULL) { - _PyErr_NoMemory(tstate); - } +error: + HEAD_UNLOCK(runtime); - PyMem_RawFree(interp); + PyThread_free_lock(pending_lock); + if (interp != NULL) { + free_interpreter(interp); + } return NULL; } @@ -295,7 +676,7 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) } HEAD_LOCK(runtime); - for (PyThreadState *p = interp->tstate_head; p != NULL; p = p->next) { + for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) { PyThreadState_Clear(p); } HEAD_UNLOCK(runtime); @@ -337,6 +718,25 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) PyDict_Clear(interp->builtins); Py_CLEAR(interp->sysdict); Py_CLEAR(interp->builtins); + Py_CLEAR(interp->interpreter_trampoline); + + for (int i=0; i < DICT_MAX_WATCHERS; i++) { + interp->dict_state.watchers[i] = NULL; + } + + for (int i=0; i < TYPE_MAX_WATCHERS; i++) { + interp->type_watchers[i] = NULL; + } + + for (int i=0; i < FUNC_MAX_WATCHERS; i++) { + interp->func_watchers[i] = NULL; + } + interp->active_func_watchers = 0; + + for (int i=0; i < CODE_MAX_WATCHERS; i++) { + interp->code_watchers[i] = NULL; + } + interp->active_code_watchers = 0; // XXX Once we have one allocator per interpreter (i.e. // per-interpreter GC) we must ensure that all of the interpreter's @@ -350,7 +750,7 @@ PyInterpreterState_Clear(PyInterpreterState *interp) // Use the current Python thread state to call audit hooks and to collect // garbage. It can be different than the current Python thread state // of 'interp'. - PyThreadState *current_tstate = _PyThreadState_GET(); + PyThreadState *current_tstate = current_fast_get(interp->runtime); interpreter_clear(interp, current_tstate); } @@ -369,7 +769,7 @@ zapthreads(PyInterpreterState *interp, int check_current) PyThreadState *tstate; /* No need to lock the mutex here because this should only happen when the threads are all really dead (XXX famous last words). */ - while ((tstate = interp->tstate_head) != NULL) { + while ((tstate = interp->threads.head) != NULL) { _PyThreadState_Delete(tstate, check_current); } } @@ -385,7 +785,7 @@ PyInterpreterState_Delete(PyInterpreterState *interp) _PyEval_FiniState(&interp->ceval); /* Delete current thread. After this, many C API calls become crashy. */ - _PyThreadState_Swap(&runtime->gilstate, NULL); + _PyThreadState_Swap(runtime, NULL); HEAD_LOCK(runtime); PyInterpreterState **p; @@ -397,7 +797,7 @@ PyInterpreterState_Delete(PyInterpreterState *interp) break; } } - if (interp->tstate_head != NULL) { + if (interp->threads.head != NULL) { Py_FatalError("remaining threads"); } *p = interp->next; @@ -413,7 +813,7 @@ PyInterpreterState_Delete(PyInterpreterState *interp) if (interp->id_mutex != NULL) { PyThread_free_lock(interp->id_mutex); } - PyMem_RawFree(interp); + free_interpreter(interp); } @@ -425,10 +825,9 @@ PyInterpreterState_Delete(PyInterpreterState *interp) PyStatus _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) { - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; struct pyinterpreters *interpreters = &runtime->interpreters; - PyThreadState *tstate = _PyThreadState_Swap(gilstate, NULL); + PyThreadState *tstate = _PyThreadState_Swap(runtime, NULL); if (tstate != NULL && tstate->interp != interpreters->main) { return _PyStatus_ERR("not main interpreter"); } @@ -451,32 +850,53 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) } PyInterpreterState *prev_interp = interp; interp = interp->next; - PyMem_RawFree(prev_interp); + free_interpreter(prev_interp); } HEAD_UNLOCK(runtime); if (interpreters->head == NULL) { return _PyStatus_ERR("missing main interpreter"); } - _PyThreadState_Swap(gilstate, tstate); + _PyThreadState_Swap(runtime, tstate); return _PyStatus_OK(); } #endif -PyInterpreterState * -PyInterpreterState_Get(void) +// Used by finalize_modules() +void +_PyInterpreterState_ClearModules(PyInterpreterState *interp) { - PyThreadState *tstate = _PyThreadState_GET(); - _Py_EnsureTstateNotNULL(tstate); - PyInterpreterState *interp = tstate->interp; - if (interp == NULL) { - Py_FatalError("no current interpreter"); + if (!interp->modules_by_index) { + return; + } + + Py_ssize_t i; + for (i = 0; i < PyList_GET_SIZE(interp->modules_by_index); i++) { + PyObject *m = PyList_GET_ITEM(interp->modules_by_index, i); + if (PyModule_Check(m)) { + /* cleanup the saved copy of module dicts */ + PyModuleDef *md = PyModule_GetDef(m); + if (md) { + Py_CLEAR(md->m_base.m_copy); + } + } + } + + /* Setting modules_by_index to NULL could be dangerous, so we + clear the list instead. */ + if (PyList_SetSlice(interp->modules_by_index, + 0, PyList_GET_SIZE(interp->modules_by_index), + NULL)) { + PyErr_WriteUnraisable(interp->modules_by_index); } - return interp; } +//---------- +// accessors +//---------- + int64_t PyInterpreterState_GetID(PyInterpreterState *interp) { @@ -488,41 +908,6 @@ PyInterpreterState_GetID(PyInterpreterState *interp) } -static PyInterpreterState * -interp_look_up_id(_PyRuntimeState *runtime, int64_t requested_id) -{ - PyInterpreterState *interp = runtime->interpreters.head; - while (interp != NULL) { - int64_t id = PyInterpreterState_GetID(interp); - if (id < 0) { - return NULL; - } - if (requested_id == id) { - return interp; - } - interp = PyInterpreterState_Next(interp); - } - return NULL; -} - -PyInterpreterState * -_PyInterpreterState_LookUpID(int64_t requested_id) -{ - PyInterpreterState *interp = NULL; - if (requested_id >= 0) { - _PyRuntimeState *runtime = &_PyRuntime; - HEAD_LOCK(runtime); - interp = interp_look_up_id(runtime, requested_id); - HEAD_UNLOCK(runtime); - } - if (interp == NULL && !PyErr_Occurred()) { - PyErr_Format(PyExc_RuntimeError, - "unrecognized interpreter ID %lld", requested_id); - } - return interp; -} - - int _PyInterpreterState_IDInitref(PyInterpreterState *interp) { @@ -558,8 +943,8 @@ void _PyInterpreterState_IDDecref(PyInterpreterState *interp) { assert(interp->id_mutex != NULL); + _PyRuntimeState *runtime = interp->runtime; - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); assert(interp->id_refcount != 0); interp->id_refcount -= 1; @@ -570,9 +955,9 @@ _PyInterpreterState_IDDecref(PyInterpreterState *interp) // XXX Using the "head" thread isn't strictly correct. PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); // XXX Possible GILState issues? - PyThreadState *save_tstate = _PyThreadState_Swap(gilstate, tstate); + PyThreadState *save_tstate = _PyThreadState_Swap(runtime, tstate); Py_EndInterpreter(tstate); - _PyThreadState_Swap(gilstate, save_tstate); + _PyThreadState_Swap(runtime, save_tstate); } } @@ -611,6 +996,76 @@ PyInterpreterState_GetDict(PyInterpreterState *interp) return interp->dict; } + +//----------------------------- +// look up an interpreter state +//----------------------------- + +/* Return the interpreter associated with the current OS thread. + + The GIL must be held. + */ + +PyInterpreterState * +PyInterpreterState_Get(void) +{ + PyThreadState *tstate = current_fast_get(&_PyRuntime); + _Py_EnsureTstateNotNULL(tstate); + PyInterpreterState *interp = tstate->interp; + if (interp == NULL) { + Py_FatalError("no current interpreter"); + } + return interp; +} + + +static PyInterpreterState * +interp_look_up_id(_PyRuntimeState *runtime, int64_t requested_id) +{ + PyInterpreterState *interp = runtime->interpreters.head; + while (interp != NULL) { + int64_t id = PyInterpreterState_GetID(interp); + if (id < 0) { + return NULL; + } + if (requested_id == id) { + return interp; + } + interp = PyInterpreterState_Next(interp); + } + return NULL; +} + +/* Return the interpreter state with the given ID. + + Fail with RuntimeError if the interpreter is not found. */ + +PyInterpreterState * +_PyInterpreterState_LookUpID(int64_t requested_id) +{ + PyInterpreterState *interp = NULL; + if (requested_id >= 0) { + _PyRuntimeState *runtime = &_PyRuntime; + HEAD_LOCK(runtime); + interp = interp_look_up_id(runtime, requested_id); + HEAD_UNLOCK(runtime); + } + if (interp == NULL && !PyErr_Occurred()) { + PyErr_Format(PyExc_RuntimeError, + "unrecognized interpreter ID %lld", requested_id); + } + return interp; +} + + +/********************************/ +/* the per-thread runtime state */ +/********************************/ + +//---------- +// lifecycle +//---------- + /* Minimum size of data stack chunk */ #define DATA_STACK_CHUNK_SIZE (16*1024) @@ -629,234 +1084,147 @@ allocate_chunk(int size_in_bytes, _PyStackChunk* previous) } static PyThreadState * -new_threadstate(PyInterpreterState *interp, int init) +alloc_threadstate(void) { - _PyRuntimeState *runtime = interp->runtime; - PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState)); - if (tstate == NULL) { - return NULL; + return PyMem_RawCalloc(1, sizeof(PyThreadState)); +} + +static void +free_threadstate(PyThreadState *tstate) +{ + // The initial thread state of the interpreter is allocated + // as part of the interpreter state so should not be freed. + if (tstate != &tstate->interp->_initial_thread) { + PyMem_RawFree(tstate); + } +} + +/* Get the thread state to a minimal consistent state. + Further init happens in pylifecycle.c before it can be used. + All fields not initialized here are expected to be zeroed out, + e.g. by PyMem_RawCalloc() or memset(), or otherwise pre-initialized. + The interpreter state is not manipulated. Instead it is assumed that + the thread is getting added to the interpreter. + */ + +static void +init_threadstate(PyThreadState *tstate, + PyInterpreterState *interp, uint64_t id, + PyThreadState *next) +{ + if (tstate->_status != PyThreadState_UNINITIALIZED) { + Py_FatalError("thread state already initialized"); } + assert(interp != NULL); tstate->interp = interp; - tstate->recursion_limit = interp->ceval.recursion_limit; - tstate->recursion_remaining = interp->ceval.recursion_limit; - tstate->recursion_headroom = 0; - tstate->tracing = 0; - tstate->root_cframe.use_tracing = 0; - tstate->root_cframe.current_frame = NULL; - tstate->cframe = &tstate->root_cframe; - tstate->gilstate_counter = 0; - tstate->async_exc = NULL; - tstate->thread_id = PyThread_get_thread_ident(); -#ifdef PY_HAVE_THREAD_NATIVE_ID - tstate->native_thread_id = PyThread_get_thread_native_id(); -#else - tstate->native_thread_id = 0; -#endif + assert(id > 0); + tstate->id = id; - tstate->dict = NULL; + assert(interp->threads.head == tstate); + assert((next != NULL && id != 1) || (next == NULL && id == 1)); + if (next != NULL) { + assert(next->prev == NULL || next->prev == tstate); + next->prev = tstate; + } + tstate->next = next; + assert(tstate->prev == NULL); - tstate->curexc_type = NULL; - tstate->curexc_value = NULL; - tstate->curexc_traceback = NULL; + // thread_id and native_thread_id are set in bind_tstate(). + + tstate->py_recursion_limit = interp->ceval.recursion_limit, + tstate->py_recursion_remaining = interp->ceval.recursion_limit, + tstate->c_recursion_remaining = C_RECURSION_LIMIT; - tstate->exc_state.exc_type = NULL; - tstate->exc_state.exc_value = NULL; - tstate->exc_state.exc_traceback = NULL; - tstate->exc_state.previous_item = NULL; tstate->exc_info = &tstate->exc_state; - tstate->c_profilefunc = NULL; - tstate->c_tracefunc = NULL; - tstate->c_profileobj = NULL; - tstate->c_traceobj = NULL; + // PyGILState_Release must not try to delete this thread state. + // This is cleared when PyGILState_Ensure() creates the thread state. + tstate->gilstate_counter = 1; - tstate->trash_delete_nesting = 0; - tstate->trash_delete_later = NULL; - tstate->on_delete = NULL; - tstate->on_delete_data = NULL; + tstate->cframe = &tstate->root_cframe; + tstate->datastack_chunk = NULL; + tstate->datastack_top = NULL; + tstate->datastack_limit = NULL; - tstate->coroutine_origin_tracking_depth = 0; + tstate->_status = PyThreadState_INITIALIZED; +} - tstate->async_gen_firstiter = NULL; - tstate->async_gen_finalizer = NULL; - - tstate->context = NULL; - tstate->context_ver = 1; - tstate->datastack_chunk = allocate_chunk(DATA_STACK_CHUNK_SIZE, NULL); - if (tstate->datastack_chunk == NULL) { - PyMem_RawFree(tstate); +static PyThreadState * +new_threadstate(PyInterpreterState *interp) +{ + PyThreadState *tstate; + _PyRuntimeState *runtime = interp->runtime; + // We don't need to allocate a thread state for the main interpreter + // (the common case), but doing it later for the other case revealed a + // reentrancy problem (deadlock). So for now we always allocate before + // taking the interpreters lock. See GH-96071. + PyThreadState *new_tstate = alloc_threadstate(); + int used_newtstate; + if (new_tstate == NULL) { return NULL; } - /* If top points to entry 0, then _PyThreadState_PopFrame will try to pop this chunk */ - tstate->datastack_top = &tstate->datastack_chunk->data[1]; - tstate->datastack_limit = (PyObject **)(((char *)tstate->datastack_chunk) + DATA_STACK_CHUNK_SIZE); - /* Mark trace_info as uninitialized */ - tstate->trace_info.code = NULL; - - if (init) { - _PyThreadState_Init(tstate); - } - + /* We serialize concurrent creation to protect global state. */ HEAD_LOCK(runtime); - tstate->id = ++interp->tstate_next_unique_id; - tstate->prev = NULL; - tstate->next = interp->tstate_head; - if (tstate->next) - tstate->next->prev = tstate; - interp->tstate_head = tstate; - HEAD_UNLOCK(runtime); + interp->threads.next_unique_id += 1; + uint64_t id = interp->threads.next_unique_id; + + // Allocate the thread state and add it to the interpreter. + PyThreadState *old_head = interp->threads.head; + if (old_head == NULL) { + // It's the interpreter's initial thread state. + assert(id == 1); + used_newtstate = 0; + tstate = &interp->_initial_thread; + } + else { + // Every valid interpreter must have at least one thread. + assert(id > 1); + assert(old_head->prev == NULL); + used_newtstate = 1; + tstate = new_tstate; + // Set to _PyThreadState_INIT. + memcpy(tstate, + &initial._main_interpreter._initial_thread, + sizeof(*tstate)); + } + interp->threads.head = tstate; + + init_threadstate(tstate, interp, id, old_head); + + HEAD_UNLOCK(runtime); + if (!used_newtstate) { + // Must be called with lock unlocked to avoid re-entrancy deadlock. + PyMem_RawFree(new_tstate); + } return tstate; } PyThreadState * PyThreadState_New(PyInterpreterState *interp) { - return new_threadstate(interp, 1); + PyThreadState *tstate = new_threadstate(interp); + if (tstate) { + bind_tstate(tstate); + } + return tstate; } +// This must be followed by a call to _PyThreadState_Bind(); PyThreadState * _PyThreadState_Prealloc(PyInterpreterState *interp) { - return new_threadstate(interp, 0); + return new_threadstate(interp); } +// We keep this around for (accidental) stable ABI compatibility. +// Realistically, no extensions are using it. void _PyThreadState_Init(PyThreadState *tstate) { - _PyGILState_NoteThreadState(&tstate->interp->runtime->gilstate, tstate); -} - -PyObject* -PyState_FindModule(struct PyModuleDef* module) -{ - Py_ssize_t index = module->m_base.m_index; - PyInterpreterState *state = _PyInterpreterState_GET(); - PyObject *res; - if (module->m_slots) { - return NULL; - } - if (index == 0) - return NULL; - if (state->modules_by_index == NULL) - return NULL; - if (index >= PyList_GET_SIZE(state->modules_by_index)) - return NULL; - res = PyList_GET_ITEM(state->modules_by_index, index); - return res==Py_None ? NULL : res; -} - -int -_PyState_AddModule(PyThreadState *tstate, PyObject* module, struct PyModuleDef* def) -{ - if (!def) { - assert(_PyErr_Occurred(tstate)); - return -1; - } - if (def->m_slots) { - _PyErr_SetString(tstate, - PyExc_SystemError, - "PyState_AddModule called on module with slots"); - return -1; - } - - PyInterpreterState *interp = tstate->interp; - if (!interp->modules_by_index) { - interp->modules_by_index = PyList_New(0); - if (!interp->modules_by_index) { - return -1; - } - } - - while (PyList_GET_SIZE(interp->modules_by_index) <= def->m_base.m_index) { - if (PyList_Append(interp->modules_by_index, Py_None) < 0) { - return -1; - } - } - - Py_INCREF(module); - return PyList_SetItem(interp->modules_by_index, - def->m_base.m_index, module); -} - -int -PyState_AddModule(PyObject* module, struct PyModuleDef* def) -{ - if (!def) { - Py_FatalError("module definition is NULL"); - return -1; - } - - PyThreadState *tstate = _PyThreadState_GET(); - PyInterpreterState *interp = tstate->interp; - Py_ssize_t index = def->m_base.m_index; - if (interp->modules_by_index && - index < PyList_GET_SIZE(interp->modules_by_index) && - module == PyList_GET_ITEM(interp->modules_by_index, index)) - { - _Py_FatalErrorFormat(__func__, "module %p already added", module); - return -1; - } - return _PyState_AddModule(tstate, module, def); -} - -int -PyState_RemoveModule(struct PyModuleDef* def) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyInterpreterState *interp = tstate->interp; - - if (def->m_slots) { - _PyErr_SetString(tstate, - PyExc_SystemError, - "PyState_RemoveModule called on module with slots"); - return -1; - } - - Py_ssize_t index = def->m_base.m_index; - if (index == 0) { - Py_FatalError("invalid module index"); - } - if (interp->modules_by_index == NULL) { - Py_FatalError("Interpreters module-list not accessible."); - } - if (index > PyList_GET_SIZE(interp->modules_by_index)) { - Py_FatalError("Module index out of bounds."); - } - - Py_INCREF(Py_None); - return PyList_SetItem(interp->modules_by_index, index, Py_None); -} - -// Used by finalize_modules() -void -_PyInterpreterState_ClearModules(PyInterpreterState *interp) -{ - if (!interp->modules_by_index) { - return; - } - - Py_ssize_t i; - for (i = 0; i < PyList_GET_SIZE(interp->modules_by_index); i++) { - PyObject *m = PyList_GET_ITEM(interp->modules_by_index, i); - if (PyModule_Check(m)) { - /* cleanup the saved copy of module dicts */ - PyModuleDef *md = PyModule_GetDef(m); - if (md) { - Py_CLEAR(md->m_base.m_copy); - } - } - } - - /* Setting modules_by_index to NULL could be dangerous, so we - clear the list instead. */ - if (PyList_SetSlice(interp->modules_by_index, - 0, PyList_GET_SIZE(interp->modules_by_index), - NULL)) { - PyErr_WriteUnraisable(interp->modules_by_index); - } + Py_FatalError("_PyThreadState_Init() is for internal use only"); } void @@ -885,9 +1253,7 @@ PyThreadState_Clear(PyThreadState *tstate) Py_CLEAR(tstate->curexc_value); Py_CLEAR(tstate->curexc_traceback); - Py_CLEAR(tstate->exc_state.exc_type); Py_CLEAR(tstate->exc_state.exc_value); - Py_CLEAR(tstate->exc_state.exc_traceback); /* The stack of exception states should contain just this thread. */ if (verbose && tstate->exc_info != &tstate->exc_state) { @@ -913,8 +1279,7 @@ PyThreadState_Clear(PyThreadState *tstate) /* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */ static void -tstate_delete_common(PyThreadState *tstate, - struct _gilstate_runtime_state *gilstate) +tstate_delete_common(PyThreadState *tstate) { _Py_EnsureTstateNotNULL(tstate); PyInterpreterState *interp = tstate->interp; @@ -928,18 +1293,17 @@ tstate_delete_common(PyThreadState *tstate, tstate->prev->next = tstate->next; } else { - interp->tstate_head = tstate->next; + interp->threads.head = tstate->next; } if (tstate->next) { tstate->next->prev = tstate->prev; } HEAD_UNLOCK(runtime); - if (gilstate->autoInterpreterState && - PyThread_tss_get(&gilstate->autoTSSkey) == tstate) - { - PyThread_tss_set(&gilstate->autoTSSkey, NULL); - } + // XXX Do this in PyThreadState_Swap() (and assert not-equal here)? + unbind_tstate(tstate); + + // XXX Move to PyThreadState_Clear()? _PyStackChunk *chunk = tstate->datastack_chunk; tstate->datastack_chunk = NULL; while (chunk != NULL) { @@ -952,14 +1316,13 @@ tstate_delete_common(PyThreadState *tstate, static void _PyThreadState_Delete(PyThreadState *tstate, int check_current) { - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; if (check_current) { - if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) { + if (tstate == current_fast_get(tstate->interp->runtime)) { _Py_FatalErrorFormat(__func__, "tstate %p is still current", tstate); } } - tstate_delete_common(tstate, gilstate); - PyMem_RawFree(tstate); + tstate_delete_common(tstate); + free_threadstate(tstate); } @@ -974,18 +1337,16 @@ void _PyThreadState_DeleteCurrent(PyThreadState *tstate) { _Py_EnsureTstateNotNULL(tstate); - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; - tstate_delete_common(tstate, gilstate); - _PyRuntimeGILState_SetThreadState(gilstate, NULL); + tstate_delete_common(tstate); + current_fast_clear(tstate->interp->runtime); _PyEval_ReleaseLock(tstate); - PyMem_RawFree(tstate); + free_threadstate(tstate); } void PyThreadState_DeleteCurrent(void) { - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; - PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate); + PyThreadState *tstate = current_fast_get(&_PyRuntime); _PyThreadState_DeleteCurrent(tstate); } @@ -1006,7 +1367,7 @@ _PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate) /* Remove all thread states, except tstate, from the linked list of thread states. This will allow calling PyThreadState_Clear() without holding the lock. */ - PyThreadState *list = interp->tstate_head; + PyThreadState *list = interp->threads.head; if (list == tstate) { list = tstate->next; } @@ -1017,7 +1378,7 @@ _PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate) tstate->next->prev = tstate->prev; } tstate->prev = tstate->next = NULL; - interp->tstate_head = tstate; + interp->threads.head = tstate; HEAD_UNLOCK(runtime); /* Clear and deallocate all stale thread states. Even if this @@ -1027,72 +1388,14 @@ _PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate) for (p = list; p; p = next) { next = p->next; PyThreadState_Clear(p); - PyMem_RawFree(p); + free_threadstate(p); } } -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS -PyThreadState* -_PyThreadState_GetTSS(void) { - return PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey); -} -#endif - - -PyThreadState * -_PyThreadState_UncheckedGet(void) -{ - return _PyThreadState_GET(); -} - - -PyThreadState * -PyThreadState_Get(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _Py_EnsureTstateNotNULL(tstate); - return tstate; -} - - -PyThreadState * -_PyThreadState_Swap(struct _gilstate_runtime_state *gilstate, PyThreadState *newts) -{ -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - PyThreadState *oldts = _PyThreadState_GetTSS(); -#else - PyThreadState *oldts = _PyRuntimeGILState_GetThreadState(gilstate); -#endif - - _PyRuntimeGILState_SetThreadState(gilstate, newts); - /* It should not be possible for more than one thread state - to be used for a thread. Check this the best we can in debug - builds. - */ -#if defined(Py_DEBUG) - if (newts) { - /* This can be called from PyEval_RestoreThread(). Similar - to it, we need to ensure errno doesn't change. - */ - int err = errno; - PyThreadState *check = _PyGILState_GetThisThreadState(gilstate); - if (check && check->interp == newts->interp && check != newts) - Py_FatalError("Invalid thread state for this thread"); - errno = err; - } -#endif -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - PyThread_tss_set(&gilstate->autoTSSkey, newts); -#endif - return oldts; -} - -PyThreadState * -PyThreadState_Swap(PyThreadState *newts) -{ - return _PyThreadState_Swap(&_PyRuntime.gilstate, newts); -} +//---------- +// accessors +//---------- /* An extension mechanism to store arbitrary additional per-thread state. PyThreadState_GetDict() returns a dictionary that can be used to hold such @@ -1117,7 +1420,7 @@ _PyThreadState_GetDict(PyThreadState *tstate) PyObject * PyThreadState_GetDict(void) { - PyThreadState *tstate = _PyThreadState_GET(); + PyThreadState *tstate = current_fast_get(&_PyRuntime); if (tstate == NULL) { return NULL; } @@ -1137,15 +1440,15 @@ PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate) { assert(tstate != NULL); - if (tstate->cframe->current_frame == NULL) { + _PyInterpreterFrame *f = _PyThreadState_GetFrame(tstate); + if (f == NULL) { return NULL; } - PyFrameObject *frame = _PyFrame_GetFrameObject(tstate->cframe->current_frame); + PyFrameObject *frame = _PyFrame_GetFrameObject(f); if (frame == NULL) { PyErr_Clear(); } - Py_XINCREF(frame); - return frame; + return (PyFrameObject*)Py_XNewRef(frame); } @@ -1157,6 +1460,10 @@ PyThreadState_GetID(PyThreadState *tstate) } +//---------- +// other API +//---------- + /* Asynchronously raise an exception in a thread. Requested by Just van Rossum and Alex Martelli. To prevent naive misuse, you must write your own extension @@ -1165,6 +1472,8 @@ PyThreadState_GetID(PyThreadState *tstate) match any known thread id). Can be called with exc=NULL to clear an existing async exception. This raises no exceptions. */ +// XXX Move this to Python/ceval_gil.c? +// XXX Deprecate this. int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) { @@ -1178,7 +1487,7 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) * head_mutex for the duration. */ HEAD_LOCK(runtime); - for (PyThreadState *tstate = interp->tstate_head; tstate != NULL; tstate = tstate->next) { + for (PyThreadState *tstate = interp->threads.head; tstate != NULL; tstate = tstate->next) { if (tstate->thread_id != id) { continue; } @@ -1191,8 +1500,7 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) * the decref. */ PyObject *old_exc = tstate->async_exc; - Py_XINCREF(exc); - tstate->async_exc = exc; + tstate->async_exc = Py_XNewRef(exc); HEAD_UNLOCK(runtime); Py_XDECREF(old_exc); @@ -1204,24 +1512,78 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) } -void -PyThreadState_EnterTracing(PyThreadState *tstate) -{ - tstate->tracing++; - _PyThreadState_PauseTracing(tstate); -} +//--------------------------------- +// API for the current thread state +//--------------------------------- -void -PyThreadState_LeaveTracing(PyThreadState *tstate) +PyThreadState * +_PyThreadState_UncheckedGet(void) { - tstate->tracing--; - _PyThreadState_ResumeTracing(tstate); + return current_fast_get(&_PyRuntime); } +PyThreadState * +PyThreadState_Get(void) +{ + PyThreadState *tstate = current_fast_get(&_PyRuntime); + _Py_EnsureTstateNotNULL(tstate); + return tstate; +} -/* Routines for advanced debuggers, requested by David Beazley. - Don't use unless you know what you are doing! */ + +PyThreadState * +_PyThreadState_Swap(_PyRuntimeState *runtime, PyThreadState *newts) +{ + PyThreadState *oldts = current_fast_get(runtime); + + if (newts == NULL) { + current_fast_clear(runtime); + } + else { + current_fast_set(runtime, newts); + } + /* It should not be possible for more than one thread state + to be used for a thread. Check this the best we can in debug + builds. + */ + // XXX The above isn't true when multiple interpreters are involved. +#if defined(Py_DEBUG) + if (newts && current_tss_initialized(runtime)) { + /* This can be called from PyEval_RestoreThread(). Similar + to it, we need to ensure errno doesn't change. + */ + int err = errno; + PyThreadState *check = current_tss_get(runtime); + if (check && check->interp == newts->interp && check != newts) { + Py_FatalError("Invalid thread state for this thread"); + } + errno = err; + } +#endif + return oldts; +} + +PyThreadState * +PyThreadState_Swap(PyThreadState *newts) +{ + return _PyThreadState_Swap(&_PyRuntime, newts); +} + + +void +_PyThreadState_Bind(PyThreadState *tstate) +{ + bind_tstate(tstate); +} + + +/***********************************/ +/* routines for advanced debuggers */ +/***********************************/ + +// (requested by David Beazley) +// Don't use unless you know what you are doing! PyInterpreterState * PyInterpreterState_Head(void) @@ -1232,7 +1594,7 @@ PyInterpreterState_Head(void) PyInterpreterState * PyInterpreterState_Main(void) { - return _PyRuntime.interpreters.main; + return _PyInterpreterState_Main(); } PyInterpreterState * @@ -1242,7 +1604,7 @@ PyInterpreterState_Next(PyInterpreterState *interp) { PyThreadState * PyInterpreterState_ThreadHead(PyInterpreterState *interp) { - return interp->tstate_head; + return interp->threads.head; } PyThreadState * @@ -1250,6 +1612,11 @@ PyThreadState_Next(PyThreadState *tstate) { return tstate->next; } + +/********************************************/ +/* reporting execution state of all threads */ +/********************************************/ + /* The implementation of sys._current_frames(). This is intended to be called with the GIL held, as it will be when called via sys._current_frames(). It's possible it would work fine even without @@ -1258,7 +1625,8 @@ PyThreadState_Next(PyThreadState *tstate) { PyObject * _PyThread_CurrentFrames(void) { - PyThreadState *tstate = _PyThreadState_GET(); + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = current_fast_get(runtime); if (_PySys_Audit(tstate, "sys._current_frames", NULL) < 0) { return NULL; } @@ -1274,13 +1642,13 @@ _PyThread_CurrentFrames(void) * Because these lists can mutate even when the GIL is held, we * need to grab head_mutex for the duration. */ - _PyRuntimeState *runtime = tstate->interp->runtime; HEAD_LOCK(runtime); PyInterpreterState *i; for (i = runtime->interpreters.head; i != NULL; i = i->next) { PyThreadState *t; - for (t = i->tstate_head; t != NULL; t = t->next) { - InterpreterFrame *frame = t->cframe->current_frame; + for (t = i->threads.head; t != NULL; t = t->next) { + _PyInterpreterFrame *frame = t->cframe->current_frame; + frame = _PyFrame_GetFirstComplete(frame); if (frame == NULL) { continue; } @@ -1288,7 +1656,12 @@ _PyThread_CurrentFrames(void) if (id == NULL) { goto fail; } - int stat = PyDict_SetItem(result, id, (PyObject *)_PyFrame_GetFrameObject(frame)); + PyObject *frameobj = (PyObject *)_PyFrame_GetFrameObject(frame); + if (frameobj == NULL) { + Py_DECREF(id); + goto fail; + } + int stat = PyDict_SetItem(result, id, frameobj); Py_DECREF(id); if (stat < 0) { goto fail; @@ -1305,10 +1678,16 @@ done: return result; } +/* The implementation of sys._current_exceptions(). This is intended to be + called with the GIL held, as it will be when called via + sys._current_exceptions(). It's possible it would work fine even without + the GIL held, but haven't thought enough about that. +*/ PyObject * _PyThread_CurrentExceptions(void) { - PyThreadState *tstate = _PyThreadState_GET(); + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = current_fast_get(runtime); _Py_EnsureTstateNotNULL(tstate); @@ -1327,12 +1706,11 @@ _PyThread_CurrentExceptions(void) * Because these lists can mutate even when the GIL is held, we * need to grab head_mutex for the duration. */ - _PyRuntimeState *runtime = tstate->interp->runtime; HEAD_LOCK(runtime); PyInterpreterState *i; for (i = runtime->interpreters.head; i != NULL; i = i->next) { PyThreadState *t; - for (t = i->tstate_head; t != NULL; t = t->next) { + for (t = i->threads.head; t != NULL; t = t->next) { _PyErr_StackItem *err_info = _PyErr_GetTopmostException(t); if (err_info == NULL) { continue; @@ -1341,11 +1719,7 @@ _PyThread_CurrentExceptions(void) if (id == NULL) { goto fail; } - PyObject *exc_info = PyTuple_Pack( - 3, - err_info->exc_type != NULL ? err_info->exc_type : Py_None, - err_info->exc_value != NULL ? err_info->exc_value : Py_None, - err_info->exc_traceback != NULL ? err_info->exc_traceback : Py_None); + PyObject *exc_info = _PyErr_StackItemToExcInfoTuple(err_info); if (exc_info == NULL) { Py_DECREF(id); goto fail; @@ -1368,62 +1742,167 @@ done: return result; } -/* Python "auto thread state" API. */ -/* Keep this as a static, as it is not reliable! It can only - ever be compared to the state for the *current* thread. - * If not equal, then it doesn't matter that the actual - value may change immediately after comparison, as it can't - possibly change to the current thread's state. - * If equal, then the current thread holds the lock, so the value can't - change until we yield the lock. -*/ -static int -PyThreadState_IsCurrent(PyThreadState *tstate) +/****************/ +/* module state */ +/****************/ + +PyObject* +PyState_FindModule(PyModuleDef* module) { - /* Must be the tstate for this thread */ - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; - assert(_PyGILState_GetThisThreadState(gilstate) == tstate); - return tstate == _PyRuntimeGILState_GetThreadState(gilstate); + Py_ssize_t index = module->m_base.m_index; + PyInterpreterState *state = _PyInterpreterState_GET(); + PyObject *res; + if (module->m_slots) { + return NULL; + } + if (index == 0) + return NULL; + if (state->modules_by_index == NULL) + return NULL; + if (index >= PyList_GET_SIZE(state->modules_by_index)) + return NULL; + res = PyList_GET_ITEM(state->modules_by_index, index); + return res==Py_None ? NULL : res; } +int +_PyState_AddModule(PyThreadState *tstate, PyObject* module, PyModuleDef* def) +{ + if (!def) { + assert(_PyErr_Occurred(tstate)); + return -1; + } + if (def->m_slots) { + _PyErr_SetString(tstate, + PyExc_SystemError, + "PyState_AddModule called on module with slots"); + return -1; + } + + PyInterpreterState *interp = tstate->interp; + if (!interp->modules_by_index) { + interp->modules_by_index = PyList_New(0); + if (!interp->modules_by_index) { + return -1; + } + } + + while (PyList_GET_SIZE(interp->modules_by_index) <= def->m_base.m_index) { + if (PyList_Append(interp->modules_by_index, Py_None) < 0) { + return -1; + } + } + + return PyList_SetItem(interp->modules_by_index, + def->m_base.m_index, Py_NewRef(module)); +} + +int +PyState_AddModule(PyObject* module, PyModuleDef* def) +{ + if (!def) { + Py_FatalError("module definition is NULL"); + return -1; + } + + PyThreadState *tstate = current_fast_get(&_PyRuntime); + PyInterpreterState *interp = tstate->interp; + Py_ssize_t index = def->m_base.m_index; + if (interp->modules_by_index && + index < PyList_GET_SIZE(interp->modules_by_index) && + module == PyList_GET_ITEM(interp->modules_by_index, index)) + { + _Py_FatalErrorFormat(__func__, "module %p already added", module); + return -1; + } + return _PyState_AddModule(tstate, module, def); +} + +int +PyState_RemoveModule(PyModuleDef* def) +{ + PyThreadState *tstate = current_fast_get(&_PyRuntime); + PyInterpreterState *interp = tstate->interp; + + if (def->m_slots) { + _PyErr_SetString(tstate, + PyExc_SystemError, + "PyState_RemoveModule called on module with slots"); + return -1; + } + + Py_ssize_t index = def->m_base.m_index; + if (index == 0) { + Py_FatalError("invalid module index"); + } + if (interp->modules_by_index == NULL) { + Py_FatalError("Interpreters module-list not accessible."); + } + if (index > PyList_GET_SIZE(interp->modules_by_index)) { + Py_FatalError("Module index out of bounds."); + } + + return PyList_SetItem(interp->modules_by_index, index, Py_NewRef(Py_None)); +} + + +/***********************************/ +/* Python "auto thread state" API. */ +/***********************************/ + /* Internal initialization/finalization functions called by Py_Initialize/Py_FinalizeEx */ PyStatus -_PyGILState_Init(_PyRuntimeState *runtime) +_PyGILState_Init(PyInterpreterState *interp) { - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; - if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { - return _PyStatus_NO_MEMORY(); + if (!_Py_IsMainInterpreter(interp)) { + /* Currently, PyGILState is shared by all interpreters. The main + * interpreter is responsible to initialize it. */ + return _PyStatus_OK(); } - // PyThreadState_New() calls _PyGILState_NoteThreadState() which does - // nothing before autoInterpreterState is set. - assert(gilstate->autoInterpreterState == NULL); + _PyRuntimeState *runtime = interp->runtime; + assert(current_tss_get(runtime) == NULL); + assert(runtime->gilstate.autoInterpreterState == NULL); + runtime->gilstate.autoInterpreterState = interp; return _PyStatus_OK(); } +void +_PyGILState_Fini(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + /* Currently, PyGILState is shared by all interpreters. The main + * interpreter is responsible to initialize it. */ + return; + } + interp->runtime->gilstate.autoInterpreterState = NULL; +} + +// XXX Drop this. PyStatus _PyGILState_SetTstate(PyThreadState *tstate) { + /* must init with valid states */ + assert(tstate != NULL); + assert(tstate->interp != NULL); + if (!_Py_IsMainInterpreter(tstate->interp)) { /* Currently, PyGILState is shared by all interpreters. The main * interpreter is responsible to initialize it. */ return _PyStatus_OK(); } - /* must init with valid states */ - assert(tstate != NULL); - assert(tstate->interp != NULL); +#ifndef NDEBUG + _PyRuntimeState *runtime = tstate->interp->runtime; - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; + assert(runtime->gilstate.autoInterpreterState == tstate->interp); + assert(current_tss_get(runtime) == tstate); + assert(tstate->gilstate_counter == 1); +#endif - gilstate->autoInterpreterState = tstate->interp; - assert(PyThread_tss_get(&gilstate->autoTSSkey) == NULL); - assert(tstate->gilstate_counter == 0); - - _PyGILState_NoteThreadState(gilstate, tstate); return _PyStatus_OK(); } @@ -1433,118 +1912,42 @@ _PyGILState_GetInterpreterStateUnsafe(void) return _PyRuntime.gilstate.autoInterpreterState; } -void -_PyGILState_Fini(PyInterpreterState *interp) -{ - struct _gilstate_runtime_state *gilstate = &interp->runtime->gilstate; - PyThread_tss_delete(&gilstate->autoTSSkey); - gilstate->autoInterpreterState = NULL; -} - -#ifdef HAVE_FORK -/* Reset the TSS key - called by PyOS_AfterFork_Child(). - * This should not be necessary, but some - buggy - pthread implementations - * don't reset TSS upon fork(), see issue #10517. - */ -PyStatus -_PyGILState_Reinit(_PyRuntimeState *runtime) -{ - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; - PyThreadState *tstate = _PyGILState_GetThisThreadState(gilstate); - - PyThread_tss_delete(&gilstate->autoTSSkey); - if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { - return _PyStatus_NO_MEMORY(); - } - - /* If the thread had an associated auto thread state, reassociate it with - * the new key. */ - if (tstate && - PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate) != 0) - { - return _PyStatus_ERR("failed to set autoTSSkey"); - } - return _PyStatus_OK(); -} -#endif - -/* When a thread state is created for a thread by some mechanism other than - PyGILState_Ensure, it's important that the GILState machinery knows about - it so it doesn't try to create another thread state for the thread (this is - a better fix for SF bug #1010677 than the first one attempted). -*/ -static void -_PyGILState_NoteThreadState(struct _gilstate_runtime_state *gilstate, PyThreadState* tstate) -{ - /* If autoTSSkey isn't initialized, this must be the very first - threadstate created in Py_Initialize(). Don't do anything for now - (we'll be back here when _PyGILState_Init is called). */ - if (!gilstate->autoInterpreterState) { - return; - } - - /* Stick the thread state for this thread in thread specific storage. - - The only situation where you can legitimately have more than one - thread state for an OS level thread is when there are multiple - interpreters. - - You shouldn't really be using the PyGILState_ APIs anyway (see issues - #10915 and #15751). - - The first thread state created for that given OS level thread will - "win", which seems reasonable behaviour. - */ - if (PyThread_tss_get(&gilstate->autoTSSkey) == NULL) { - if ((PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate)) != 0) { - Py_FatalError("Couldn't create autoTSSkey mapping"); - } - } - - /* PyGILState_Release must not try to delete this thread state. */ - tstate->gilstate_counter = 1; -} - /* The public functions */ -static PyThreadState * -_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate) -{ - if (gilstate->autoInterpreterState == NULL) - return NULL; - return (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey); -} PyThreadState * PyGILState_GetThisThreadState(void) { - return _PyGILState_GetThisThreadState(&_PyRuntime.gilstate); + _PyRuntimeState *runtime = &_PyRuntime; + if (!current_tss_initialized(runtime)) { + return NULL; + } + return current_tss_get(runtime); } int PyGILState_Check(void) { - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; - if (!gilstate->check_enabled) { + _PyRuntimeState *runtime = &_PyRuntime; + if (!runtime->gilstate.check_enabled) { return 1; } - if (!PyThread_tss_is_created(&gilstate->autoTSSkey)) { + if (!current_tss_initialized(runtime)) { return 1; } - PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate); + PyThreadState *tstate = current_fast_get(runtime); if (tstate == NULL) { return 0; } - return (tstate == _PyGILState_GetThisThreadState(gilstate)); + return (tstate == current_tss_get(runtime)); } PyGILState_STATE PyGILState_Ensure(void) { _PyRuntimeState *runtime = &_PyRuntime; - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; /* Note that we do not auto-init Python here - apart from potential races with 2 threads auto-initializing, pep-311 @@ -1553,30 +1956,30 @@ PyGILState_Ensure(void) /* Ensure that _PyEval_InitThreads() and _PyGILState_Init() have been called by Py_Initialize() */ -#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS assert(_PyEval_ThreadsInitialized(runtime)); -#endif - assert(gilstate->autoInterpreterState); + assert(current_tss_initialized(runtime)); + assert(runtime->gilstate.autoInterpreterState != NULL); - PyThreadState *tcur = (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey); - int current; + PyThreadState *tcur = current_tss_get(runtime); + int has_gil; if (tcur == NULL) { /* Create a new Python thread state for this thread */ - tcur = PyThreadState_New(gilstate->autoInterpreterState); + tcur = PyThreadState_New(runtime->gilstate.autoInterpreterState); if (tcur == NULL) { Py_FatalError("Couldn't create thread-state for new thread"); } /* This is our thread state! We'll need to delete it in the matching call to PyGILState_Release(). */ + assert(tcur->gilstate_counter == 1); tcur->gilstate_counter = 0; - current = 0; /* new thread state is never current */ + has_gil = 0; /* new thread state is never current */ } else { - current = PyThreadState_IsCurrent(tcur); + has_gil = holds_gil(tcur); } - if (current == 0) { + if (!has_gil) { PyEval_RestoreThread(tcur); } @@ -1587,14 +1990,14 @@ PyGILState_Ensure(void) */ ++tcur->gilstate_counter; - return current ? PyGILState_LOCKED : PyGILState_UNLOCKED; + return has_gil ? PyGILState_LOCKED : PyGILState_UNLOCKED; } void PyGILState_Release(PyGILState_STATE oldstate) { _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = PyThread_tss_get(&runtime->gilstate.autoTSSkey); + PyThreadState *tstate = current_tss_get(runtime); if (tstate == NULL) { Py_FatalError("auto-releasing thread-state, " "but no thread-state for this thread"); @@ -1605,12 +2008,12 @@ PyGILState_Release(PyGILState_STATE oldstate) but while this is very new (April 2003), the extra check by release-only users can't hurt. */ - if (!PyThreadState_IsCurrent(tstate)) { + if (!holds_gil(tstate)) { _Py_FatalErrorFormat(__func__, "thread state %p must be current when releasing", tstate); } - assert(PyThreadState_IsCurrent(tstate)); + assert(holds_gil(tstate)); --tstate->gilstate_counter; assert(tstate->gilstate_counter >= 0); /* illegal counter value */ @@ -1626,12 +2029,13 @@ PyGILState_Release(PyGILState_STATE oldstate) * races; see bugs 225673 and 1061968 (that nasty bug has a * habit of coming back). */ - assert(_PyRuntimeGILState_GetThreadState(&runtime->gilstate) == tstate); + assert(current_fast_get(runtime) == tstate); _PyThreadState_DeleteCurrent(tstate); } /* Release the lock if necessary */ - else if (oldstate == PyGILState_UNLOCKED) + else if (oldstate == PyGILState_UNLOCKED) { PyEval_SaveThread(); + } } @@ -1641,6 +2045,100 @@ PyGILState_Release(PyGILState_STATE oldstate) /* cross-interpreter data */ +static inline void +_xidata_init(_PyCrossInterpreterData *data) +{ + // If the value is being reused + // then _xidata_clear() should have been called already. + assert(data->data == NULL); + assert(data->obj == NULL); + *data = (_PyCrossInterpreterData){0}; + data->interp = -1; +} + +static inline void +_xidata_clear(_PyCrossInterpreterData *data) +{ + if (data->free != NULL) { + data->free(data->data); + } + data->data = NULL; + Py_CLEAR(data->obj); +} + +void +_PyCrossInterpreterData_Init(_PyCrossInterpreterData *data, + PyInterpreterState *interp, + void *shared, PyObject *obj, + xid_newobjectfunc new_object) +{ + assert(data != NULL); + assert(new_object != NULL); + _xidata_init(data); + data->data = shared; + if (obj != NULL) { + assert(interp != NULL); + // released in _PyCrossInterpreterData_Clear() + data->obj = Py_NewRef(obj); + } + // Ideally every object would know its owning interpreter. + // Until then, we have to rely on the caller to identify it + // (but we don't need it in all cases). + data->interp = (interp != NULL) ? interp->id : -1; + data->new_object = new_object; +} + +int +_PyCrossInterpreterData_InitWithSize(_PyCrossInterpreterData *data, + PyInterpreterState *interp, + const size_t size, PyObject *obj, + xid_newobjectfunc new_object) +{ + assert(size > 0); + // For now we always free the shared data in the same interpreter + // where it was allocated, so the interpreter is required. + assert(interp != NULL); + _PyCrossInterpreterData_Init(data, interp, NULL, obj, new_object); + data->data = PyMem_Malloc(size); + if (data->data == NULL) { + return -1; + } + data->free = PyMem_Free; + return 0; +} + +void +_PyCrossInterpreterData_Clear(PyInterpreterState *interp, + _PyCrossInterpreterData *data) +{ + assert(data != NULL); + // This must be called in the owning interpreter. + assert(interp == NULL || data->interp == interp->id); + _xidata_clear(data); +} + +static int +_check_xidata(PyThreadState *tstate, _PyCrossInterpreterData *data) +{ + // data->data can be anything, including NULL, so we don't check it. + + // data->obj may be NULL, so we don't check it. + + if (data->interp < 0) { + _PyErr_SetString(tstate, PyExc_SystemError, "missing interp"); + return -1; + } + + if (data->new_object == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, "missing new_object func"); + return -1; + } + + // data->free may be NULL, so we don't check it. + + return 0; +} + crossinterpdatafunc _PyCrossInterpreterData_Lookup(PyObject *); /* This is a separate func from _PyCrossInterpreterData_Lookup in order @@ -1665,32 +2163,11 @@ _PyObject_CheckCrossInterpreterData(PyObject *obj) return 0; } -static int -_check_xidata(PyThreadState *tstate, _PyCrossInterpreterData *data) -{ - // data->data can be anything, including NULL, so we don't check it. - - // data->obj may be NULL, so we don't check it. - - if (data->interp < 0) { - _PyErr_SetString(tstate, PyExc_SystemError, "missing interp"); - return -1; - } - - if (data->new_object == NULL) { - _PyErr_SetString(tstate, PyExc_SystemError, "missing new_object func"); - return -1; - } - - // data->free may be NULL, so we don't check it. - - return 0; -} - int _PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) { - PyThreadState *tstate = _PyThreadState_GET(); + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = current_fast_get(runtime); #ifdef Py_DEBUG // The caller must hold the GIL _Py_EnsureTstateNotNULL(tstate); @@ -1699,7 +2176,7 @@ _PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) // Reset data before re-populating. *data = (_PyCrossInterpreterData){0}; - data->free = PyMem_RawFree; // Set a default that may be overridden. + data->interp = -1; // Call the "getdata" func for the object. Py_INCREF(obj); @@ -1708,7 +2185,7 @@ _PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) Py_DECREF(obj); return -1; } - int res = getdata(obj, data); + int res = getdata(tstate, obj, data); Py_DECREF(obj); if (res != 0) { return -1; @@ -1717,75 +2194,70 @@ _PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) // Fill in the blanks and validate the result. data->interp = interp->id; if (_check_xidata(tstate, data) != 0) { - _PyCrossInterpreterData_Release(data); + (void)_PyCrossInterpreterData_Release(data); return -1; } return 0; } -static void -_release_xidata(void *arg) +PyObject * +_PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *data) { - _PyCrossInterpreterData *data = (_PyCrossInterpreterData *)arg; - if (data->free != NULL) { - data->free(data->data); - } - Py_XDECREF(data->obj); + return data->new_object(data); } +typedef void (*releasefunc)(PyInterpreterState *, void *); + static void -_call_in_interpreter(struct _gilstate_runtime_state *gilstate, - PyInterpreterState *interp, - void (*func)(void *), void *arg) +_call_in_interpreter(PyInterpreterState *interp, releasefunc func, void *arg) { /* We would use Py_AddPendingCall() if it weren't specific to the * main interpreter (see bpo-33608). In the meantime we take a * naive approach. */ + _PyRuntimeState *runtime = interp->runtime; PyThreadState *save_tstate = NULL; - if (interp != _PyRuntimeGILState_GetThreadState(gilstate)->interp) { + if (interp != current_fast_get(runtime)->interp) { // XXX Using the "head" thread isn't strictly correct. PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); // XXX Possible GILState issues? - save_tstate = _PyThreadState_Swap(gilstate, tstate); + save_tstate = _PyThreadState_Swap(runtime, tstate); } - func(arg); + // XXX Once the GIL is per-interpreter, this should be called with the + // calling interpreter's GIL released and the target interpreter's held. + func(interp, arg); // Switch back. if (save_tstate != NULL) { - _PyThreadState_Swap(gilstate, save_tstate); + _PyThreadState_Swap(runtime, save_tstate); } } -void +int _PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) { - if (data->data == NULL && data->obj == NULL) { + if (data->free == NULL && data->obj == NULL) { // Nothing to release! - return; + data->data = NULL; + return 0; } // Switch to the original interpreter. PyInterpreterState *interp = _PyInterpreterState_LookUpID(data->interp); if (interp == NULL) { // The interpreter was already destroyed. - if (data->free != NULL) { - // XXX Someone leaked some memory... - } - return; + // This function shouldn't have been called. + // XXX Someone leaked some memory... + assert(PyErr_Occurred()); + return -1; } // "Release" the data and/or the object. - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; - _call_in_interpreter(gilstate, interp, _release_xidata, data); -} - -PyObject * -_PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *data) -{ - return data->new_object(data); + _call_in_interpreter(interp, + (releasefunc)_PyCrossInterpreterData_Clear, data); + return 0; } /* registry of {type -> crossinterpdatafunc} */ @@ -1795,21 +2267,73 @@ _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *data) crossinterpdatafunc. It would be simpler and more efficient. */ static int -_register_xidata(struct _xidregistry *xidregistry, PyTypeObject *cls, +_xidregistry_add_type(struct _xidregistry *xidregistry, PyTypeObject *cls, crossinterpdatafunc getdata) { // Note that we effectively replace already registered classes // rather than failing. struct _xidregitem *newhead = PyMem_RawMalloc(sizeof(struct _xidregitem)); - if (newhead == NULL) + if (newhead == NULL) { return -1; - newhead->cls = cls; + } + // XXX Assign a callback to clear the entry from the registry? + newhead->cls = PyWeakref_NewRef((PyObject *)cls, NULL); + if (newhead->cls == NULL) { + PyMem_RawFree(newhead); + return -1; + } newhead->getdata = getdata; + newhead->prev = NULL; newhead->next = xidregistry->head; + if (newhead->next != NULL) { + newhead->next->prev = newhead; + } xidregistry->head = newhead; return 0; } +static struct _xidregitem * +_xidregistry_remove_entry(struct _xidregistry *xidregistry, + struct _xidregitem *entry) +{ + struct _xidregitem *next = entry->next; + if (entry->prev != NULL) { + assert(entry->prev->next == entry); + entry->prev->next = next; + } + else { + assert(xidregistry->head == entry); + xidregistry->head = next; + } + if (next != NULL) { + next->prev = entry->prev; + } + Py_DECREF(entry->cls); + PyMem_RawFree(entry); + return next; +} + +static struct _xidregitem * +_xidregistry_find_type(struct _xidregistry *xidregistry, PyTypeObject *cls) +{ + struct _xidregitem *cur = xidregistry->head; + while (cur != NULL) { + PyObject *registered = PyWeakref_GetObject(cur->cls); + if (registered == Py_None) { + // The weakly ref'ed object was freed. + cur = _xidregistry_remove_entry(xidregistry, cur); + } + else { + assert(PyType_Check(registered)); + if (registered == (PyObject *)cls) { + return cur; + } + cur = cur->next; + } + } + return NULL; +} + static void _register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry); int @@ -1825,19 +2349,32 @@ _PyCrossInterpreterData_RegisterClass(PyTypeObject *cls, return -1; } - // Make sure the class isn't ever deallocated. - Py_INCREF((PyObject *)cls); - struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); if (xidregistry->head == NULL) { _register_builtins_for_crossinterpreter_data(xidregistry); } - int res = _register_xidata(xidregistry, cls, getdata); + int res = _xidregistry_add_type(xidregistry, cls, getdata); PyThread_release_lock(xidregistry->mutex); return res; } +int +_PyCrossInterpreterData_UnregisterClass(PyTypeObject *cls) +{ + int res = 0; + struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; + PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); + struct _xidregitem *matched = _xidregistry_find_type(xidregistry, cls); + if (matched != NULL) { + (void)_xidregistry_remove_entry(xidregistry, matched); + res = 1; + } + PyThread_release_lock(xidregistry->mutex); + return res; +} + + /* Cross-interpreter objects are looked up by exact match on the class. We can reassess this policy when we move from a global registry to a tp_* slot. */ @@ -1847,22 +2384,15 @@ _PyCrossInterpreterData_Lookup(PyObject *obj) { struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; PyObject *cls = PyObject_Type(obj); - crossinterpdatafunc getdata = NULL; PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); - struct _xidregitem *cur = xidregistry->head; - if (cur == NULL) { + if (xidregistry->head == NULL) { _register_builtins_for_crossinterpreter_data(xidregistry); - cur = xidregistry->head; - } - for(; cur != NULL; cur = cur->next) { - if (cur->cls == (PyTypeObject *)cls) { - getdata = cur->getdata; - break; - } } + struct _xidregitem *matched = _xidregistry_find_type(xidregistry, + (PyTypeObject *)cls); Py_DECREF(cls); PyThread_release_lock(xidregistry->mutex); - return getdata; + return matched != NULL ? matched->getdata : NULL; } /* cross-interpreter data for builtin types */ @@ -1880,17 +2410,21 @@ _new_bytes_object(_PyCrossInterpreterData *data) } static int -_bytes_shared(PyObject *obj, _PyCrossInterpreterData *data) +_bytes_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) { - struct _shared_bytes_data *shared = PyMem_NEW(struct _shared_bytes_data, 1); - if (PyBytes_AsStringAndSize(obj, &shared->bytes, &shared->len) < 0) { + if (_PyCrossInterpreterData_InitWithSize( + data, tstate->interp, sizeof(struct _shared_bytes_data), obj, + _new_bytes_object + ) < 0) + { + return -1; + } + struct _shared_bytes_data *shared = (struct _shared_bytes_data *)data->data; + if (PyBytes_AsStringAndSize(obj, &shared->bytes, &shared->len) < 0) { + _PyCrossInterpreterData_Clear(tstate->interp, data); return -1; } - data->data = (void *)shared; - Py_INCREF(obj); - data->obj = obj; // Will be "released" (decref'ed) when data released. - data->new_object = _new_bytes_object; - data->free = PyMem_Free; return 0; } @@ -1908,17 +2442,20 @@ _new_str_object(_PyCrossInterpreterData *data) } static int -_str_shared(PyObject *obj, _PyCrossInterpreterData *data) +_str_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) { - struct _shared_str_data *shared = PyMem_NEW(struct _shared_str_data, 1); + if (_PyCrossInterpreterData_InitWithSize( + data, tstate->interp, sizeof(struct _shared_str_data), obj, + _new_str_object + ) < 0) + { + return -1; + } + struct _shared_str_data *shared = (struct _shared_str_data *)data->data; shared->kind = PyUnicode_KIND(obj); shared->buffer = PyUnicode_DATA(obj); shared->len = PyUnicode_GET_LENGTH(obj); - data->data = (void *)shared; - Py_INCREF(obj); - data->obj = obj; // Will be "released" (decref'ed) when data released. - data->new_object = _new_str_object; - data->free = PyMem_Free; return 0; } @@ -1929,7 +2466,8 @@ _new_long_object(_PyCrossInterpreterData *data) } static int -_long_shared(PyObject *obj, _PyCrossInterpreterData *data) +_long_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) { /* Note that this means the size of shareable ints is bounded by * sys.maxsize. Hence on 32-bit architectures that is half the @@ -1942,10 +2480,9 @@ _long_shared(PyObject *obj, _PyCrossInterpreterData *data) } return -1; } - data->data = (void *)value; - data->obj = NULL; - data->new_object = _new_long_object; - data->free = NULL; + _PyCrossInterpreterData_Init(data, tstate->interp, (void *)value, NULL, + _new_long_object); + // data->obj and data->free remain NULL return 0; } @@ -1953,17 +2490,16 @@ static PyObject * _new_none_object(_PyCrossInterpreterData *data) { // XXX Singleton refcounts are problematic across interpreters... - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } static int -_none_shared(PyObject *obj, _PyCrossInterpreterData *data) +_none_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) { - data->data = NULL; - // data->obj remains NULL - data->new_object = _new_none_object; - data->free = NULL; // There is nothing to free. + _PyCrossInterpreterData_Init(data, tstate->interp, NULL, NULL, + _new_none_object); + // data->data, data->obj and data->free remain NULL return 0; } @@ -1971,22 +2507,22 @@ static void _register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry) { // None - if (_register_xidata(xidregistry, (PyTypeObject *)PyObject_Type(Py_None), _none_shared) != 0) { + if (_xidregistry_add_type(xidregistry, (PyTypeObject *)PyObject_Type(Py_None), _none_shared) != 0) { Py_FatalError("could not register None for cross-interpreter sharing"); } // int - if (_register_xidata(xidregistry, &PyLong_Type, _long_shared) != 0) { + if (_xidregistry_add_type(xidregistry, &PyLong_Type, _long_shared) != 0) { Py_FatalError("could not register int for cross-interpreter sharing"); } // bytes - if (_register_xidata(xidregistry, &PyBytes_Type, _bytes_shared) != 0) { + if (_xidregistry_add_type(xidregistry, &PyBytes_Type, _bytes_shared) != 0) { Py_FatalError("could not register bytes for cross-interpreter sharing"); } // str - if (_register_xidata(xidregistry, &PyUnicode_Type, _str_shared) != 0) { + if (_xidregistry_add_type(xidregistry, &PyUnicode_Type, _str_shared) != 0) { Py_FatalError("could not register str for cross-interpreter sharing"); } } @@ -2039,18 +2575,26 @@ _PyInterpreterState_GetConfigCopy(PyConfig *config) const PyConfig* _Py_GetConfig(void) { + _PyRuntimeState *runtime = &_PyRuntime; assert(PyGILState_Check()); - PyThreadState *tstate = _PyThreadState_GET(); + PyThreadState *tstate = current_fast_get(runtime); + _Py_EnsureTstateNotNULL(tstate); return _PyInterpreterState_GetConfig(tstate->interp); } + +int +_PyInterpreterState_HasFeature(PyInterpreterState *interp, unsigned long feature) +{ + return ((interp->feature_flags & feature) != 0); +} + + #define MINIMUM_OVERHEAD 1000 static PyObject ** push_chunk(PyThreadState *tstate, int size) { - assert(tstate->datastack_top + size >= tstate->datastack_limit); - int allocate_size = DATA_STACK_CHUNK_SIZE; while (allocate_size < (int)sizeof(PyObject*)*(size + MINIMUM_OVERHEAD)) { allocate_size *= 2; @@ -2059,64 +2603,49 @@ push_chunk(PyThreadState *tstate, int size) if (new == NULL) { return NULL; } - tstate->datastack_chunk->top = tstate->datastack_top - &tstate->datastack_chunk->data[0]; + if (tstate->datastack_chunk) { + tstate->datastack_chunk->top = tstate->datastack_top - + &tstate->datastack_chunk->data[0]; + } tstate->datastack_chunk = new; tstate->datastack_limit = (PyObject **)(((char *)new) + allocate_size); - PyObject **res = &new->data[0]; + // When new is the "root" chunk (i.e. new->previous == NULL), we can keep + // _PyThreadState_PopFrame from freeing it later by "skipping" over the + // first element: + PyObject **res = &new->data[new->previous == NULL]; tstate->datastack_top = res + size; return res; } -InterpreterFrame * -_PyThreadState_BumpFramePointerSlow(PyThreadState *tstate, size_t size) +_PyInterpreterFrame * +_PyThreadState_PushFrame(PyThreadState *tstate, size_t size) { assert(size < INT_MAX/sizeof(PyObject *)); - PyObject **base = tstate->datastack_top; - PyObject **top = base + size; - if (top >= tstate->datastack_limit) { - base = push_chunk(tstate, (int)size); - if (base == NULL) { - return NULL; - } + if (_PyThreadState_HasStackSpace(tstate, (int)size)) { + _PyInterpreterFrame *res = (_PyInterpreterFrame *)tstate->datastack_top; + tstate->datastack_top += size; + return res; } - else { - tstate->datastack_top = top; - } - return (InterpreterFrame *)base; -} - - -InterpreterFrame * -_PyThreadState_PushFrame(PyThreadState *tstate, PyFrameConstructor *con, PyObject *locals) -{ - PyCodeObject *code = (PyCodeObject *)con->fc_code; - int nlocalsplus = code->co_nlocalsplus; - size_t size = nlocalsplus + code->co_stacksize + - FRAME_SPECIALS_SIZE; - InterpreterFrame *frame = _PyThreadState_BumpFramePointer(tstate, size); - if (frame == NULL) { - return NULL; - } - _PyFrame_InitializeSpecials(frame, con, locals, nlocalsplus); - for (int i=0; i < nlocalsplus; i++) { - frame->localsplus[i] = NULL; - } - return frame; + return (_PyInterpreterFrame *)push_chunk(tstate, (int)size); } void -_PyThreadState_PopFrame(PyThreadState *tstate, InterpreterFrame * frame) +_PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame * frame) { + assert(tstate->datastack_chunk); PyObject **base = (PyObject **)frame; if (base == &tstate->datastack_chunk->data[0]) { _PyStackChunk *chunk = tstate->datastack_chunk; _PyStackChunk *previous = chunk->previous; + // push_chunk ensures that the root chunk is never popped: + assert(previous); tstate->datastack_top = &previous->data[previous->top]; tstate->datastack_chunk = previous; _PyObject_VirtualFree(chunk, chunk->size); tstate->datastack_limit = (PyObject **)(((char *)previous) + previous->size); } else { + assert(tstate->datastack_top); assert(tstate->datastack_top >= base); tstate->datastack_top = base; } diff --git a/Python/pystrhex.c b/Python/pystrhex.c index 880af44ea0e..e4f06d76639 100644 --- a/Python/pystrhex.c +++ b/Python/pystrhex.c @@ -5,7 +5,7 @@ #include // abs() static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen, - const PyObject* sep, int bytes_per_sep_group, + PyObject* sep, int bytes_per_sep_group, const int return_bytes) { assert(arglen >= 0); @@ -152,21 +152,23 @@ PyObject * _Py_strhex(const char* argbuf, const Py_ssize_t arglen) /* Same as above but returns a bytes() instead of str() to avoid the * need to decode the str() when bytes are needed. */ -PyObject * _Py_strhex_bytes(const char* argbuf, const Py_ssize_t arglen) +PyObject* _Py_strhex_bytes(const char* argbuf, const Py_ssize_t arglen) { return _Py_strhex_impl(argbuf, arglen, NULL, 0, 1); } /* These variants include support for a separator between every N bytes: */ -PyObject * _Py_strhex_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group) +PyObject* _Py_strhex_with_sep(const char* argbuf, const Py_ssize_t arglen, + PyObject* sep, const int bytes_per_group) { return _Py_strhex_impl(argbuf, arglen, sep, bytes_per_group, 0); } /* Same as above but returns a bytes() instead of str() to avoid the * need to decode the str() when bytes are needed. */ -PyObject * _Py_strhex_bytes_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group) +PyObject* _Py_strhex_bytes_with_sep(const char* argbuf, const Py_ssize_t arglen, + PyObject* sep, const int bytes_per_group) { return _Py_strhex_impl(argbuf, arglen, sep, bytes_per_group, 1); } diff --git a/Python/pystrtod.c b/Python/pystrtod.c index ab5814de21b..d77b846f040 100644 --- a/Python/pystrtod.c +++ b/Python/pystrtod.c @@ -1,8 +1,8 @@ /* -*- Mode: C; c-file-style: "python" -*- */ #include -#include "pycore_dtoa.h" -#include "pycore_pymath.h" // _Py_SET_53BIT_PRECISION_START +#include "pycore_dtoa.h" // _Py_dg_strtod() +#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR #include /* Case-insensitive string match used for nan and inf detection; t should be @@ -24,7 +24,7 @@ case_insensitive_match(const char *s, const char *t) the successfully parsed portion of the string. On failure, return -1.0 and set *endptr to point to the start of the string. */ -#ifndef PY_NO_SHORT_FLOAT_REPR +#if _PY_SHORT_FLOAT_REPR == 1 double _Py_parse_inf_or_nan(const char *p, char **endptr) @@ -82,12 +82,10 @@ _Py_parse_inf_or_nan(const char *p, char **endptr) s += 5; retval = negate ? -Py_HUGE_VAL : Py_HUGE_VAL; } -#ifdef Py_NAN else if (case_insensitive_match(s, "nan")) { s += 3; retval = negate ? -Py_NAN : Py_NAN; } -#endif else { s = p; retval = -1.0; @@ -127,7 +125,7 @@ _Py_parse_inf_or_nan(const char *p, char **endptr) * Return value: the #gdouble value. **/ -#ifndef PY_NO_SHORT_FLOAT_REPR +#if _PY_SHORT_FLOAT_REPR == 1 static double _PyOS_ascii_strtod(const char *nptr, char **endptr) @@ -441,7 +439,7 @@ _Py_string_to_number_with_underscores( return NULL; } -#ifdef PY_NO_SHORT_FLOAT_REPR +#if _PY_SHORT_FLOAT_REPR == 0 /* Given a string that may have a decimal point in the current locale, change it back to a dot. Since the string cannot get @@ -918,6 +916,18 @@ char * PyOS_double_to_string(double val, (flags & Py_DTSF_ALT ? "#" : ""), precision, format_code); _PyOS_ascii_formatd(buf, bufsize, format, val, precision); + + if (flags & Py_DTSF_NO_NEG_0 && buf[0] == '-') { + char *buf2 = buf + 1; + while (*buf2 == '0' || *buf2 == '.') { + ++buf2; + } + if (*buf2 == 0 || *buf2 == 'e') { + size_t len = buf2 - buf + strlen(buf2); + assert(buf[len] == 0); + memmove(buf, buf+1, len); + } + } } /* Add sign when requested. It's convenient (esp. when formatting @@ -942,7 +952,7 @@ char * PyOS_double_to_string(double val, return buf; } -#else +#else // _PY_SHORT_FLOAT_REPR == 1 /* _Py_dg_dtoa is available. */ @@ -997,8 +1007,8 @@ static char * format_float_short(double d, char format_code, int mode, int precision, int always_add_sign, int add_dot_0_if_integer, - int use_alt_formatting, const char * const *float_strings, - int *type) + int use_alt_formatting, int no_negative_zero, + const char * const *float_strings, int *type) { char *buf = NULL; char *p = NULL; @@ -1024,6 +1034,11 @@ format_float_short(double d, char format_code, assert(digits_end != NULL && digits_end >= digits); digits_len = digits_end - digits; + if (no_negative_zero && sign == 1 && + (digits_len == 0 || (digits_len == 1 && digits[0] == '0'))) { + sign = 0; + } + if (digits_len && !Py_ISDIGIT(digits[0])) { /* Infinities and nans here; adapt Gay's output, so convert Infinity to inf and NaN to nan, and @@ -1303,6 +1318,7 @@ char * PyOS_double_to_string(double val, flags & Py_DTSF_SIGN, flags & Py_DTSF_ADD_DOT_0, flags & Py_DTSF_ALT, + flags & Py_DTSF_NO_NEG_0, float_strings, type); } -#endif /* ifdef PY_NO_SHORT_FLOAT_REPR */ +#endif // _PY_SHORT_FLOAT_REPR == 1 diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 2c0950ee17e..35292b6478a 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -13,6 +13,7 @@ #include "Python.h" #include "pycore_ast.h" // PyAST_mod2obj +#include "pycore_ceval.h" // _Py_EnterRecursiveCall #include "pycore_compile.h" // _PyAST_Compile() #include "pycore_interp.h" // PyInterpreterState.importlib #include "pycore_object.h" // _PyDebug_PrintTotalRefs() @@ -23,9 +24,7 @@ #include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_traceback.h" // _PyTraceBack_Print_Indented() -#include "token.h" // INDENT #include "errcode.h" // E_EOF -#include "code.h" // PyCodeObject #include "marshal.h" // PyMarshal_ReadLongFromFile() #ifdef MS_WINDOWS @@ -38,20 +37,6 @@ #endif -_Py_IDENTIFIER(__main__); -_Py_IDENTIFIER(builtins); -_Py_IDENTIFIER(excepthook); -_Py_IDENTIFIER(flush); -_Py_IDENTIFIER(last_traceback); -_Py_IDENTIFIER(last_type); -_Py_IDENTIFIER(last_value); -_Py_IDENTIFIER(ps1); -_Py_IDENTIFIER(ps2); -_Py_IDENTIFIER(stdin); -_Py_IDENTIFIER(stdout); -_Py_IDENTIFIER(stderr); -_Py_static_string(PyId_string, ""); - #ifdef __cplusplus extern "C" { #endif @@ -130,14 +115,15 @@ _PyRun_InteractiveLoopObject(FILE *fp, PyObject *filename, PyCompilerFlags *flag flags = &local_flags; } - PyObject *v = _PySys_GetObjectId(&PyId_ps1); + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *v = _PySys_GetAttr(tstate, &_Py_ID(ps1)); if (v == NULL) { - _PySys_SetObjectId(&PyId_ps1, v = PyUnicode_FromString(">>> ")); + _PySys_SetAttr(&_Py_ID(ps1), v = PyUnicode_FromString(">>> ")); Py_XDECREF(v); } - v = _PySys_GetObjectId(&PyId_ps2); + v = _PySys_GetAttr(tstate, &_Py_ID(ps2)); if (v == NULL) { - _PySys_SetObjectId(&PyId_ps2, v = PyUnicode_FromString("... ")); + _PySys_SetAttr(&_Py_ID(ps2), v = PyUnicode_FromString("... ")); Py_XDECREF(v); } @@ -199,31 +185,25 @@ static int PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, PyCompilerFlags *flags) { - PyObject *m, *d, *v, *w, *oenc = NULL, *mod_name; + PyObject *m, *d, *v, *w, *oenc = NULL; mod_ty mod; PyArena *arena; const char *ps1 = "", *ps2 = "", *enc = NULL; int errcode = 0; - _Py_IDENTIFIER(encoding); - _Py_IDENTIFIER(__main__); - - mod_name = _PyUnicode_FromId(&PyId___main__); /* borrowed */ - if (mod_name == NULL) { - return -1; - } + PyThreadState *tstate = _PyThreadState_GET(); if (fp == stdin) { /* Fetch encoding from sys.stdin if possible. */ - v = _PySys_GetObjectId(&PyId_stdin); + v = _PySys_GetAttr(tstate, &_Py_ID(stdin)); if (v && v != Py_None) { - oenc = _PyObject_GetAttrId(v, &PyId_encoding); + oenc = PyObject_GetAttr(v, &_Py_ID(encoding)); if (oenc) enc = PyUnicode_AsUTF8(oenc); if (!enc) PyErr_Clear(); } } - v = _PySys_GetObjectId(&PyId_ps1); + v = _PySys_GetAttr(tstate, &_Py_ID(ps1)); if (v != NULL) { v = PyObject_Str(v); if (v == NULL) @@ -236,7 +216,7 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, } } } - w = _PySys_GetObjectId(&PyId_ps2); + w = _PySys_GetAttr(tstate, &_Py_ID(ps2)); if (w != NULL) { w = PyObject_Str(w); if (w == NULL) @@ -271,7 +251,7 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, } return -1; } - m = PyImport_AddModuleObject(mod_name); + m = PyImport_AddModuleObject(&_Py_ID(__main__)); if (m == NULL) { _PyArena_Free(arena); return -1; @@ -520,37 +500,28 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, { Py_ssize_t hold; PyObject *v; - _Py_IDENTIFIER(msg); - _Py_IDENTIFIER(filename); - _Py_IDENTIFIER(lineno); - _Py_IDENTIFIER(offset); - _Py_IDENTIFIER(end_lineno); - _Py_IDENTIFIER(end_offset); - _Py_IDENTIFIER(text); *message = NULL; *filename = NULL; /* new style errors. `err' is an instance */ - *message = _PyObject_GetAttrId(err, &PyId_msg); + *message = PyObject_GetAttr(err, &_Py_ID(msg)); if (!*message) goto finally; - v = _PyObject_GetAttrId(err, &PyId_filename); + v = PyObject_GetAttr(err, &_Py_ID(filename)); if (!v) goto finally; if (v == Py_None) { Py_DECREF(v); - *filename = _PyUnicode_FromId(&PyId_string); - if (*filename == NULL) - goto finally; - Py_INCREF(*filename); + _Py_DECLARE_STR(anon_string, ""); + *filename = Py_NewRef(&_Py_STR(anon_string)); } else { *filename = v; } - v = _PyObject_GetAttrId(err, &PyId_lineno); + v = PyObject_GetAttr(err, &_Py_ID(lineno)); if (!v) goto finally; hold = PyLong_AsSsize_t(v); @@ -559,7 +530,7 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, goto finally; *lineno = hold; - v = _PyObject_GetAttrId(err, &PyId_offset); + v = PyObject_GetAttr(err, &_Py_ID(offset)); if (!v) goto finally; if (v == Py_None) { @@ -574,7 +545,7 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, } if (Py_TYPE(err) == (PyTypeObject*)PyExc_SyntaxError) { - v = _PyObject_GetAttrId(err, &PyId_end_lineno); + v = PyObject_GetAttr(err, &_Py_ID(end_lineno)); if (!v) { PyErr_Clear(); *end_lineno = *lineno; @@ -590,7 +561,7 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, *end_lineno = hold; } - v = _PyObject_GetAttrId(err, &PyId_end_offset); + v = PyObject_GetAttr(err, &_Py_ID(end_offset)); if (!v) { PyErr_Clear(); *end_offset = -1; @@ -611,7 +582,7 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, *end_offset = -1; } - v = _PyObject_GetAttrId(err, &PyId_text); + v = PyObject_GetAttr(err, &_Py_ID(text)); if (!v) goto finally; if (v == Py_None) { @@ -629,14 +600,18 @@ finally: return 0; } -static void -print_error_text(PyObject *f, Py_ssize_t offset, Py_ssize_t end_offset, PyObject *text_obj) +static int +print_error_text(PyObject *f, Py_ssize_t offset, Py_ssize_t end_offset, + PyObject *text_obj) { - size_t caret_repetitions = (end_offset > 0 && end_offset > offset) ? end_offset - offset : 1; + size_t caret_repetitions = (end_offset > 0 && end_offset > offset) ? + end_offset - offset : 1; + /* Convert text to a char pointer; return if error */ const char *text = PyUnicode_AsUTF8(text_obj); - if (text == NULL) - return; + if (text == NULL) { + return -1; + } /* Convert offset from 1-based to 0-based */ offset--; @@ -675,27 +650,43 @@ print_error_text(PyObject *f, Py_ssize_t offset, Py_ssize_t end_offset, PyObject } /* Print text */ - PyFile_WriteString(" ", f); - PyFile_WriteString(text, f); + if (PyFile_WriteString(" ", f) < 0) { + return -1; + } + if (PyFile_WriteString(text, f) < 0) { + return -1; + } /* Make sure there's a newline at the end */ if (text[len] != '\n') { - PyFile_WriteString("\n", f); + if (PyFile_WriteString("\n", f) < 0) { + return -1; + } } /* Don't print caret if it points to the left of the text */ - if (offset < 0) - return; + if (offset < 0) { + return 0; + } /* Write caret line */ - PyFile_WriteString(" ", f); + if (PyFile_WriteString(" ", f) < 0) { + return -1; + } while (--offset >= 0) { - PyFile_WriteString(" ", f); + if (PyFile_WriteString(" ", f) < 0) { + return -1; + } } for (size_t caret_iter=0; caret_iter < caret_repetitions ; caret_iter++) { - PyFile_WriteString("^", f); + if (PyFile_WriteString("^", f) < 0) { + return -1; + } } - PyFile_WriteString("\n", f); + if (PyFile_WriteString("\n", f) < 0) { + return -1; + } + return 0; } @@ -725,11 +716,9 @@ _Py_HandleSystemExit(int *exitcode_p) if (PyExceptionInstance_Check(value)) { /* The error code should be in the `code' attribute. */ - _Py_IDENTIFIER(code); - PyObject *code = _PyObject_GetAttrId(value, &PyId_code); + PyObject *code = PyObject_GetAttr(value, &_Py_ID(code)); if (code) { - Py_DECREF(value); - value = code; + Py_SETREF(value, code); if (value == Py_None) goto done; } @@ -741,7 +730,8 @@ _Py_HandleSystemExit(int *exitcode_p) exitcode = (int)PyLong_AsLong(value); } else { - PyObject *sys_stderr = _PySys_GetObjectId(&PyId_stderr); + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *sys_stderr = _PySys_GetAttr(tstate, &_Py_ID(stderr)); /* We clear the exception here to avoid triggering the assertion * in PyObject_Str that ensures it won't silently lose exception * details. @@ -794,8 +784,7 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars) _PyErr_NormalizeException(tstate, &exception, &v, &tb); if (tb == NULL) { - tb = Py_None; - Py_INCREF(tb); + tb = Py_NewRef(Py_None); } PyException_SetTraceback(v, tb); if (exception == NULL) { @@ -804,17 +793,17 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars) /* Now we know v != NULL too */ if (set_sys_last_vars) { - if (_PySys_SetObjectId(&PyId_last_type, exception) < 0) { + if (_PySys_SetAttr(&_Py_ID(last_type), exception) < 0) { _PyErr_Clear(tstate); } - if (_PySys_SetObjectId(&PyId_last_value, v) < 0) { + if (_PySys_SetAttr(&_Py_ID(last_value), v) < 0) { _PyErr_Clear(tstate); } - if (_PySys_SetObjectId(&PyId_last_traceback, tb) < 0) { + if (_PySys_SetAttr(&_Py_ID(last_traceback), tb) < 0) { _PyErr_Clear(tstate); } } - hook = _PySys_GetObjectId(&PyId_excepthook); + hook = _PySys_GetAttr(tstate, &_Py_ID(excepthook)); if (_PySys_Audit(tstate, "sys.excepthook", "OOOO", hook ? hook : Py_None, exception, v, tb) < 0) { if (PyErr_ExceptionMatches(PyExc_RuntimeError)) { @@ -841,12 +830,10 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars) to be NULL. However PyErr_Display() can't tolerate NULLs, so just be safe. */ if (exception2 == NULL) { - exception2 = Py_None; - Py_INCREF(exception2); + exception2 = Py_NewRef(Py_None); } if (v2 == NULL) { - v2 = Py_None; - Py_INCREF(v2); + v2 = Py_NewRef(Py_None); } fflush(stdout); PySys_WriteStderr("Error in sys.excepthook:\n"); @@ -908,38 +895,35 @@ write_indented_margin(struct exception_print_context *ctx, PyObject *f) return _Py_WriteIndentedMargin(EXC_INDENT(ctx), EXC_MARGIN(ctx), f); } -static void -print_exception(struct exception_print_context *ctx, PyObject *value) +static int +print_exception_invalid_type(struct exception_print_context *ctx, + PyObject *value) { - int err = 0; - PyObject *type, *tb, *tmp; PyObject *f = ctx->file; - - _Py_IDENTIFIER(print_file_and_line); - - if (!PyExceptionInstance_Check(value)) { - if (err == 0) { - err = _Py_WriteIndent(EXC_INDENT(ctx), f); - } - if (err == 0) { - err = PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f); - } - if (err == 0) { - err = PyFile_WriteString(Py_TYPE(value)->tp_name, f); - } - if (err == 0) { - err = PyFile_WriteString(" found\n", f); - } - if (err != 0) { - PyErr_Clear(); - } - return; + if (_Py_WriteIndent(EXC_INDENT(ctx), f) < 0) { + return -1; } + const char *const msg = "TypeError: print_exception(): Exception expected " + "for value, "; + if (PyFile_WriteString(msg, f) < 0) { + return -1; + } + if (PyFile_WriteString(Py_TYPE(value)->tp_name, f) < 0) { + return -1; + } + if (PyFile_WriteString(" found\n", f) < 0) { + return -1; + } + return 0; +} - Py_INCREF(value); - fflush(stdout); - type = (PyObject *) Py_TYPE(value); - tb = PyException_GetTraceback(value); +static int +print_exception_traceback(struct exception_print_context *ctx, PyObject *value) +{ + PyObject *f = ctx->file; + int err = 0; + + PyObject *tb = PyException_GetTraceback(value); if (tb && tb != Py_None) { const char *header = EXCEPTION_TB_HEADER; const char *header_margin = EXC_MARGIN(ctx); @@ -952,143 +936,307 @@ print_exception(struct exception_print_context *ctx, PyObject *value) err = _PyTraceBack_Print_Indented( tb, EXC_INDENT(ctx), EXC_MARGIN(ctx), header_margin, header, f); } - if (err == 0 && - (err = _PyObject_LookupAttrId(value, &PyId_print_file_and_line, &tmp)) > 0) - { - PyObject *message, *filename, *text; - Py_ssize_t lineno, offset, end_lineno, end_offset; - err = 0; - Py_DECREF(tmp); - if (!parse_syntax_error(value, &message, &filename, - &lineno, &offset, - &end_lineno, &end_offset, &text)) { + Py_XDECREF(tb); + return err; +} + +static int +print_exception_file_and_line(struct exception_print_context *ctx, + PyObject **value_p) +{ + PyObject *f = ctx->file; + + PyObject *tmp; + int res = _PyObject_LookupAttr(*value_p, &_Py_ID(print_file_and_line), &tmp); + if (res <= 0) { + if (res < 0) { PyErr_Clear(); } - else { - PyObject *line; - - Py_DECREF(value); - value = message; - - line = PyUnicode_FromFormat(" File \"%S\", line %zd\n", - filename, lineno); - Py_DECREF(filename); - if (line != NULL) { - err = write_indented_margin(ctx, f); - if (err == 0) { - err = PyFile_WriteObject(line, f, Py_PRINT_RAW); - } - Py_DECREF(line); - } - - if (text != NULL) { - Py_ssize_t line_size; - const char* error_line = PyUnicode_AsUTF8AndSize(text, &line_size); - // If the location of the error spawn multiple lines, we want - // to just print the first one and highlight everything until - // the end of that one since we don't support multi-line error - // messages. - if (end_lineno > lineno) { - end_offset = (error_line != NULL) ? line_size : -1; - } - // Limit the amount of '^' that we can display to - // the size of the text in the source line. - if (error_line != NULL && end_offset > line_size + 1) { - end_offset = line_size + 1; - } - print_error_text(f, offset, end_offset, text); - Py_DECREF(text); - } - - /* Can't be bothered to check all those - PyFile_WriteString() calls */ - if (PyErr_Occurred()) - err = -1; - } + return 0; } - if (err != 0) { - /* Don't do anything else */ + Py_DECREF(tmp); + + PyObject *message, *filename, *text; + Py_ssize_t lineno, offset, end_lineno, end_offset; + if (!parse_syntax_error(*value_p, &message, &filename, + &lineno, &offset, + &end_lineno, &end_offset, &text)) { + PyErr_Clear(); + return 0; + } + + Py_SETREF(*value_p, message); + + PyObject *line = PyUnicode_FromFormat(" File \"%S\", line %zd\n", + filename, lineno); + Py_DECREF(filename); + if (line == NULL) { + goto error; + } + if (write_indented_margin(ctx, f) < 0) { + goto error; + } + if (PyFile_WriteObject(line, f, Py_PRINT_RAW) < 0) { + goto error; + } + Py_CLEAR(line); + + if (text != NULL) { + Py_ssize_t line_size; + const char *error_line = PyUnicode_AsUTF8AndSize(text, &line_size); + // If the location of the error spawn multiple lines, we want + // to just print the first one and highlight everything until + // the end of that one since we don't support multi-line error + // messages. + if (end_lineno > lineno) { + end_offset = (error_line != NULL) ? line_size : -1; + } + // Limit the amount of '^' that we can display to + // the size of the text in the source line. + if (error_line != NULL && end_offset > line_size + 1) { + end_offset = line_size + 1; + } + if (print_error_text(f, offset, end_offset, text) < 0) { + goto error; + } + Py_DECREF(text); + } + assert(!PyErr_Occurred()); + return 0; + +error: + Py_XDECREF(line); + Py_XDECREF(text); + return -1; +} + +/* Prints the message line: module.qualname[: str(exc)] */ +static int +print_exception_message(struct exception_print_context *ctx, PyObject *type, + PyObject *value) +{ + PyObject *f = ctx->file; + + assert(PyExceptionClass_Check(type)); + + if (write_indented_margin(ctx, f) < 0) { + return -1; + } + PyObject *modulename = PyObject_GetAttr(type, &_Py_ID(__module__)); + if (modulename == NULL || !PyUnicode_Check(modulename)) { + Py_XDECREF(modulename); + PyErr_Clear(); + if (PyFile_WriteString(".", f) < 0) { + return -1; + } } else { - PyObject* modulename; - - _Py_IDENTIFIER(__module__); - assert(PyExceptionClass_Check(type)); - - err = write_indented_margin(ctx, f); - if (err == 0) { - modulename = _PyObject_GetAttrId(type, &PyId___module__); - if (modulename == NULL || !PyUnicode_Check(modulename)) - { - Py_XDECREF(modulename); - PyErr_Clear(); - err = PyFile_WriteString("", f); + if (!_PyUnicode_Equal(modulename, &_Py_ID(builtins)) && + !_PyUnicode_Equal(modulename, &_Py_ID(__main__))) + { + int res = PyFile_WriteObject(modulename, f, Py_PRINT_RAW); + Py_DECREF(modulename); + if (res < 0) { + return -1; } - else { - if (!_PyUnicode_EqualToASCIIId(modulename, &PyId_builtins) && - !_PyUnicode_EqualToASCIIId(modulename, &PyId___main__)) - { - err = PyFile_WriteObject(modulename, f, Py_PRINT_RAW); - if (err == 0) { - err = PyFile_WriteString(".", f); - } - } - Py_DECREF(modulename); + if (PyFile_WriteString(".", f) < 0) { + return -1; } } - if (err == 0) { - PyObject* qualname = PyType_GetQualName((PyTypeObject *)type); - if (qualname == NULL || !PyUnicode_Check(qualname)) { - Py_XDECREF(qualname); - PyErr_Clear(); - err = PyFile_WriteString("", f); - } - else { - err = PyFile_WriteObject(qualname, f, Py_PRINT_RAW); - Py_DECREF(qualname); - } + else { + Py_DECREF(modulename); } } - if (err == 0 && (value != Py_None)) { - PyObject *s = PyObject_Str(value); + + PyObject *qualname = PyType_GetQualName((PyTypeObject *)type); + if (qualname == NULL || !PyUnicode_Check(qualname)) { + Py_XDECREF(qualname); + PyErr_Clear(); + if (PyFile_WriteString("", f) < 0) { + return -1; + } + } + else { + int res = PyFile_WriteObject(qualname, f, Py_PRINT_RAW); + Py_DECREF(qualname); + if (res < 0) { + return -1; + } + } + + if (Py_IsNone(value)) { + return 0; + } + + PyObject *s = PyObject_Str(value); + if (s == NULL) { + PyErr_Clear(); + if (PyFile_WriteString(": ", f) < 0) { + return -1; + } + } + else { /* only print colon if the str() of the object is not the empty string */ - if (s == NULL) { - PyErr_Clear(); - err = -1; - PyFile_WriteString(": ", f); + if (!PyUnicode_Check(s) || PyUnicode_GetLength(s) != 0) { + if (PyFile_WriteString(": ", f) < 0) { + Py_DECREF(s); + return -1; + } + } + int res = PyFile_WriteObject(s, f, Py_PRINT_RAW); + Py_DECREF(s); + if (res < 0) { + return -1; } - else if (!PyUnicode_Check(s) || - PyUnicode_GetLength(s) != 0) - err = PyFile_WriteString(": ", f); - if (err == 0) - err = PyFile_WriteObject(s, f, Py_PRINT_RAW); - Py_XDECREF(s); } - /* try to write a newline in any case */ - if (err < 0) { - PyErr_Clear(); - } - PyObject* suggestions = _Py_Offer_Suggestions(value); + + return 0; +} + +static int +print_exception_suggestions(struct exception_print_context *ctx, + PyObject *value) +{ + PyObject *f = ctx->file; + PyObject *suggestions = _Py_Offer_Suggestions(value); if (suggestions) { - // Add a trailer ". Did you mean: (...)?" - err = PyFile_WriteString(". Did you mean: '", f); - if (err == 0) { - err = PyFile_WriteObject(suggestions, f, Py_PRINT_RAW); - err += PyFile_WriteString("'?", f); + if (PyFile_WriteObject(suggestions, f, Py_PRINT_RAW) < 0) { + goto error; } Py_DECREF(suggestions); - } else if (PyErr_Occurred()) { + } + else if (PyErr_Occurred()) { PyErr_Clear(); } - err += PyFile_WriteString("\n", f); - Py_XDECREF(tb); + return 0; +error: + Py_XDECREF(suggestions); + return -1; +} + +static int +print_exception_notes(struct exception_print_context *ctx, PyObject *value) +{ + PyObject *f = ctx->file; + + if (!PyExceptionInstance_Check(value)) { + return 0; + } + + if (!PyObject_HasAttr(value, &_Py_ID(__notes__))) { + return 0; + } + PyObject *notes = PyObject_GetAttr(value, &_Py_ID(__notes__)); + if (notes == NULL) { + return -1; + } + if (!PySequence_Check(notes)) { + int res = 0; + if (write_indented_margin(ctx, f) < 0) { + res = -1; + } + PyObject *s = PyObject_Repr(notes); + if (s == NULL) { + PyErr_Clear(); + res = PyFile_WriteString("<__notes__ repr() failed>", f); + } + else { + res = PyFile_WriteObject(s, f, Py_PRINT_RAW); + Py_DECREF(s); + } + Py_DECREF(notes); + return res; + } + Py_ssize_t num_notes = PySequence_Length(notes); + PyObject *lines = NULL; + for (Py_ssize_t ni = 0; ni < num_notes; ni++) { + PyObject *note = PySequence_GetItem(notes, ni); + PyObject *note_str = PyObject_Str(note); + Py_DECREF(note); + + if (note_str == NULL) { + PyErr_Clear(); + if (PyFile_WriteString("", f) < 0) { + goto error; + } + } + else { + lines = PyUnicode_Splitlines(note_str, 1); + Py_DECREF(note_str); + + if (lines == NULL) { + goto error; + } + + Py_ssize_t n = PyList_GET_SIZE(lines); + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *line = PyList_GET_ITEM(lines, i); + assert(PyUnicode_Check(line)); + if (write_indented_margin(ctx, f) < 0) { + goto error; + } + if (PyFile_WriteObject(line, f, Py_PRINT_RAW) < 0) { + goto error; + } + } + Py_CLEAR(lines); + } + if (PyFile_WriteString("\n", f) < 0) { + goto error; + } + } + + Py_DECREF(notes); + return 0; +error: + Py_XDECREF(lines); + Py_DECREF(notes); + return -1; +} + +static int +print_exception(struct exception_print_context *ctx, PyObject *value) +{ + PyObject *f = ctx->file; + + if (!PyExceptionInstance_Check(value)) { + return print_exception_invalid_type(ctx, value); + } + + Py_INCREF(value); + fflush(stdout); + + if (print_exception_traceback(ctx, value) < 0) { + goto error; + } + + /* grab the type now because value can change below */ + PyObject *type = (PyObject *) Py_TYPE(value); + + if (print_exception_file_and_line(ctx, &value) < 0) { + goto error; + } + if (print_exception_message(ctx, type, value) < 0) { + goto error; + } + if (print_exception_suggestions(ctx, value) < 0) { + goto error; + } + if (PyFile_WriteString("\n", f) < 0) { + goto error; + } + if (print_exception_notes(ctx, value) < 0) { + goto error; + } + Py_DECREF(value); - /* If an error happened here, don't show it. - XXX This is wrong, but too many callers rely on this behavior. */ - if (err != 0) - PyErr_Clear(); + assert(!PyErr_Occurred()); + return 0; +error: + Py_DECREF(value); + return -1; } static const char cause_message[] = @@ -1099,7 +1247,7 @@ static const char context_message[] = "During handling of the above exception, " "another exception occurred:\n"; -static void +static int print_exception_recursive(struct exception_print_context*, PyObject*); static int @@ -1107,219 +1255,253 @@ print_chained(struct exception_print_context* ctx, PyObject *value, const char * message, const char *tag) { PyObject *f = ctx->file; + + if (_Py_EnterRecursiveCall(" in print_chained") < 0) { + return -1; + } bool need_close = ctx->need_close; - - int err = Py_EnterRecursiveCall(" in print_chained"); - if (err == 0) { - print_exception_recursive(ctx, value); - Py_LeaveRecursiveCall(); - - if (err == 0) { - err = write_indented_margin(ctx, f); - } - if (err == 0) { - err = PyFile_WriteString("\n", f); - } - if (err == 0) { - err = write_indented_margin(ctx, f); - } - if (err == 0) { - err = PyFile_WriteString(message, f); - } - if (err == 0) { - err = write_indented_margin(ctx, f); - } - if (err == 0) { - err = PyFile_WriteString("\n", f); - } + int res = print_exception_recursive(ctx, value); + ctx->need_close = need_close; + _Py_LeaveRecursiveCall(); + if (res < 0) { + return -1; } - ctx->need_close = need_close; - - return err; + if (write_indented_margin(ctx, f) < 0) { + return -1; + } + if (PyFile_WriteString("\n", f) < 0) { + return -1; + } + if (write_indented_margin(ctx, f) < 0) { + return -1; + } + if (PyFile_WriteString(message, f) < 0) { + return -1; + } + if (write_indented_margin(ctx, f) < 0) { + return -1; + } + if (PyFile_WriteString("\n", f) < 0) { + return -1; + } + return 0; } -static void -print_exception_recursive(struct exception_print_context* ctx, PyObject *value) +/* Return true if value is in seen or there was a lookup error. + * Return false if lookup succeeded and the item was not found. + * We suppress errors because this makes us err on the side of + * under-printing which is better than over-printing irregular + * exceptions (e.g., unhashable ones). + */ +static bool +print_exception_seen_lookup(struct exception_print_context *ctx, + PyObject *value) { - int err = 0, res; - PyObject *cause, *context; + PyObject *check_id = PyLong_FromVoidPtr(value); + if (check_id == NULL) { + PyErr_Clear(); + return true; + } - if (ctx->seen != NULL) { - /* Exception chaining */ - PyObject *value_id = PyLong_FromVoidPtr(value); - if (value_id == NULL || PySet_Add(ctx->seen, value_id) == -1) - PyErr_Clear(); - else if (PyExceptionInstance_Check(value)) { - PyObject *check_id = NULL; + int in_seen = PySet_Contains(ctx->seen, check_id); + Py_DECREF(check_id); + if (in_seen == -1) { + PyErr_Clear(); + return true; + } - cause = PyException_GetCause(value); - context = PyException_GetContext(value); - if (cause) { - check_id = PyLong_FromVoidPtr(cause); - if (check_id == NULL) { - res = -1; - } else { - res = PySet_Contains(ctx->seen, check_id); - Py_DECREF(check_id); - } - if (res == -1) - PyErr_Clear(); - if (res == 0) { - err = print_chained(ctx, cause, cause_message, "cause"); - } - } - else if (context && - !((PyBaseExceptionObject *)value)->suppress_context) { - check_id = PyLong_FromVoidPtr(context); - if (check_id == NULL) { - res = -1; - } else { - res = PySet_Contains(ctx->seen, check_id); - Py_DECREF(check_id); - } - if (res == -1) - PyErr_Clear(); - if (res == 0) { - err = print_chained(ctx, context, context_message, "context"); - } - } - Py_XDECREF(context); - Py_XDECREF(cause); - } + if (in_seen == 1) { + /* value is in seen */ + return true; + } + return false; +} + +static int +print_exception_cause_and_context(struct exception_print_context *ctx, + PyObject *value) +{ + PyObject *value_id = PyLong_FromVoidPtr(value); + if (value_id == NULL || PySet_Add(ctx->seen, value_id) == -1) { + PyErr_Clear(); Py_XDECREF(value_id); + return 0; } - if (err) { - /* don't do anything else */ - } - else if (!_PyBaseExceptionGroup_Check(value)) { - print_exception(ctx, value); - } - else if (ctx->exception_group_depth > ctx->max_group_depth) { - /* exception group but depth exceeds limit */ + Py_DECREF(value_id); - PyObject *line = PyUnicode_FromFormat( - "... (max_group_depth is %d)\n", ctx->max_group_depth); + if (!PyExceptionInstance_Check(value)) { + return 0; + } - if (line) { - PyObject *f = ctx->file; - if (err == 0) { - err = write_indented_margin(ctx, f); - } - if (err == 0) { - err = PyFile_WriteObject(line, f, Py_PRINT_RAW); - } - Py_DECREF(line); + PyObject *cause = PyException_GetCause(value); + if (cause) { + int err = 0; + if (!print_exception_seen_lookup(ctx, cause)) { + err = print_chained(ctx, cause, cause_message, "cause"); } - else { - err = -1; + Py_DECREF(cause); + return err; + } + if (((PyBaseExceptionObject *)value)->suppress_context) { + return 0; + } + PyObject *context = PyException_GetContext(value); + if (context) { + int err = 0; + if (!print_exception_seen_lookup(ctx, context)) { + err = print_chained(ctx, context, context_message, "context"); } + Py_DECREF(context); + return err; + } + return 0; +} + +static int +print_exception_group(struct exception_print_context *ctx, PyObject *value) +{ + PyObject *f = ctx->file; + + if (ctx->exception_group_depth > ctx->max_group_depth) { + /* depth exceeds limit */ + + if (write_indented_margin(ctx, f) < 0) { + return -1; + } + + PyObject *line = PyUnicode_FromFormat("... (max_group_depth is %d)\n", + ctx->max_group_depth); + if (line == NULL) { + return -1; + } + int err = PyFile_WriteObject(line, f, Py_PRINT_RAW); + Py_DECREF(line); + return err; + } + + if (ctx->exception_group_depth == 0) { + ctx->exception_group_depth += 1; + } + print_exception(ctx, value); + + PyObject *excs = ((PyBaseExceptionGroupObject *)value)->excs; + assert(excs && PyTuple_Check(excs)); + Py_ssize_t num_excs = PyTuple_GET_SIZE(excs); + assert(num_excs > 0); + Py_ssize_t n; + if (num_excs <= ctx->max_group_width) { + n = num_excs; } else { - /* format exception group */ + n = ctx->max_group_width + 1; + } - if (ctx->exception_group_depth == 0) { - ctx->exception_group_depth += 1; + ctx->need_close = false; + for (Py_ssize_t i = 0; i < n; i++) { + bool last_exc = (i == n - 1); + if (last_exc) { + // The closing frame may be added in a recursive call + ctx->need_close = true; } - print_exception(ctx, value); - PyObject *excs = ((PyBaseExceptionGroupObject *)value)->excs; - assert(excs && PyTuple_Check(excs)); - Py_ssize_t num_excs = PyTuple_GET_SIZE(excs); - assert(num_excs > 0); - Py_ssize_t n; - if (num_excs <= ctx->max_group_width) { - n = num_excs; + if (_Py_WriteIndent(EXC_INDENT(ctx), f) < 0) { + return -1; + } + bool truncated = (i >= ctx->max_group_width); + PyObject *line; + if (!truncated) { + line = PyUnicode_FromFormat( + "%s+---------------- %zd ----------------\n", + (i == 0) ? "+-" : " ", i + 1); } else { - n = ctx->max_group_width + 1; + line = PyUnicode_FromFormat( + "%s+---------------- ... ----------------\n", + (i == 0) ? "+-" : " "); + } + if (line == NULL) { + return -1; + } + int err = PyFile_WriteObject(line, f, Py_PRINT_RAW); + Py_DECREF(line); + if (err < 0) { + return -1; } - PyObject *f = ctx->file; + ctx->exception_group_depth += 1; + PyObject *exc = PyTuple_GET_ITEM(excs, i); - ctx->need_close = false; - for (Py_ssize_t i = 0; i < n; i++) { - int last_exc = (i == n - 1); - if (last_exc) { - // The closing frame may be added in a recursive call - ctx->need_close = true; + if (!truncated) { + if (_Py_EnterRecursiveCall(" in print_exception_group") != 0) { + return -1; } - PyObject *line; - bool truncated = (i >= ctx->max_group_width); - if (!truncated) { - line = PyUnicode_FromFormat( - "%s+---------------- %zd ----------------\n", - (i == 0) ? "+-" : " ", i + 1); - } - else { - line = PyUnicode_FromFormat( - "%s+---------------- ... ----------------\n", - (i == 0) ? "+-" : " "); - } - - if (line) { - if (err == 0) { - err = _Py_WriteIndent(EXC_INDENT(ctx), f); - } - if (err == 0) { - err = PyFile_WriteObject(line, f, Py_PRINT_RAW); - } - Py_DECREF(line); - } - else { - err = -1; - } - - if (err == 0) { - ctx->exception_group_depth += 1; - PyObject *exc = PyTuple_GET_ITEM(excs, i); - - if (!truncated) { - if (!Py_EnterRecursiveCall(" in print_exception_recursive")) { - print_exception_recursive(ctx, exc); - Py_LeaveRecursiveCall(); - } - else { - err = -1; - } - } - else { - Py_ssize_t excs_remaining = num_excs - ctx->max_group_width; - PyObject *line = PyUnicode_FromFormat( - "and %zd more exception%s\n", - excs_remaining, excs_remaining > 1 ? "s" : ""); - - if (line) { - if (err == 0) { - err = write_indented_margin(ctx, f); - } - if (err == 0) { - err = PyFile_WriteObject(line, f, Py_PRINT_RAW); - } - Py_DECREF(line); - } - else { - err = -1; - } - } - - if (err == 0 && last_exc && ctx->need_close) { - err = _Py_WriteIndent(EXC_INDENT(ctx), f); - if (err == 0) { - err = PyFile_WriteString( - "+------------------------------------\n", f); - } - ctx->need_close = false; - } - ctx->exception_group_depth -= 1; + int res = print_exception_recursive(ctx, exc); + _Py_LeaveRecursiveCall(); + if (res < 0) { + return -1; } } - if (ctx->exception_group_depth == 1) { - ctx->exception_group_depth -= 1; + else { + Py_ssize_t excs_remaining = num_excs - ctx->max_group_width; + + if (write_indented_margin(ctx, f) < 0) { + return -1; + } + + PyObject *line = PyUnicode_FromFormat( + "and %zd more exception%s\n", + excs_remaining, excs_remaining > 1 ? "s" : ""); + + if (line == NULL) { + return -1; + } + + int err = PyFile_WriteObject(line, f, Py_PRINT_RAW); + Py_DECREF(line); + if (err < 0) { + return -1; + } + } + + if (last_exc && ctx->need_close) { + if (_Py_WriteIndent(EXC_INDENT(ctx), f) < 0) { + return -1; + } + if (PyFile_WriteString( + "+------------------------------------\n", f) < 0) { + return -1; + } + ctx->need_close = false; + } + ctx->exception_group_depth -= 1; + } + + if (ctx->exception_group_depth == 1) { + ctx->exception_group_depth -= 1; + } + return 0; +} + +static int +print_exception_recursive(struct exception_print_context *ctx, PyObject *value) +{ + if (ctx->seen != NULL) { + /* Exception chaining */ + if (print_exception_cause_and_context(ctx, value) < 0) { + return -1; } } - if (err != 0) - PyErr_Clear(); + if (!_PyBaseExceptionGroup_Check(value)) { + if (print_exception(ctx, value) < 0) { + return -1; + } + } + else if (print_exception_group(ctx, value) < 0) { + return -1; + } + assert(!PyErr_Occurred()); + return 0; } #define PyErr_MAX_GROUP_WIDTH 15 @@ -1343,6 +1525,7 @@ _PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *t struct exception_print_context ctx; ctx.file = file; ctx.exception_group_depth = 0; + ctx.need_close = false; ctx.max_group_width = PyErr_MAX_GROUP_WIDTH; ctx.max_group_depth = PyErr_MAX_GROUP_DEPTH; @@ -1353,11 +1536,15 @@ _PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *t if (ctx.seen == NULL) { PyErr_Clear(); } - print_exception_recursive(&ctx, value); + if (print_exception_recursive(&ctx, value) < 0) { + PyErr_Clear(); + _PyObject_Dump(value); + fprintf(stderr, "lost sys.stderr\n"); + } Py_XDECREF(ctx.seen); /* Call file.flush() */ - PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush); + PyObject *res = _PyObject_CallMethodNoArgs(file, &_Py_ID(flush)); if (!res) { /* Silently ignore file.flush() error */ PyErr_Clear(); @@ -1370,7 +1557,8 @@ _PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *t void PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) { - PyObject *file = _PySys_GetObjectId(&PyId_stderr); + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *file = _PySys_GetAttr(tstate, &_Py_ID(stderr)); if (file == NULL) { _PyObject_Dump(value); fprintf(stderr, "lost sys.stderr\n"); @@ -1391,20 +1579,17 @@ PyRun_StringFlags(const char *str, int start, PyObject *globals, PyObject *ret = NULL; mod_ty mod; PyArena *arena; - PyObject *filename; - - filename = _PyUnicode_FromId(&PyId_string); /* borrowed */ - if (filename == NULL) - return NULL; arena = _PyArena_New(); if (arena == NULL) return NULL; - mod = _PyParser_ASTFromString(str, filename, start, flags, arena); + _Py_DECLARE_STR(anon_string, ""); + mod = _PyParser_ASTFromString( + str, &_Py_STR(anon_string), start, flags, arena); if (mod != NULL) - ret = run_mod(mod, filename, globals, locals, flags, arena); + ret = run_mod(mod, &_Py_STR(anon_string), globals, locals, flags, arena); _PyArena_Free(arena); return ret; } @@ -1466,17 +1651,18 @@ flush_io(void) /* Save the current exception */ PyErr_Fetch(&type, &value, &traceback); - f = _PySys_GetObjectId(&PyId_stderr); + PyThreadState *tstate = _PyThreadState_GET(); + f = _PySys_GetAttr(tstate, &_Py_ID(stderr)); if (f != NULL) { - r = _PyObject_CallMethodIdNoArgs(f, &PyId_flush); + r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush)); if (r) Py_DECREF(r); else PyErr_Clear(); } - f = _PySys_GetObjectId(&PyId_stdout); + f = _PySys_GetAttr(tstate, &_Py_ID(stdout)); if (f != NULL) { - r = _PyObject_CallMethodIdNoArgs(f, &PyId_flush); + r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush)); if (r) Py_DECREF(r); else @@ -1500,7 +1686,8 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py * uncaught exception to trigger an unexplained signal exit from a future * Py_Main() based one. */ - _Py_UnhandledKeyboardInterrupt = 0; + // XXX Isn't this dealt with by the move to _PyRuntimeState? + _PyRuntime.signals.unhandled_keyboard_interrupt = 0; /* Set globals['__builtins__'] if it doesn't exist */ if (globals != NULL && _PyDict_GetItemStringWithError(globals, "__builtins__") == NULL) { @@ -1514,7 +1701,7 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py v = PyEval_EvalCode((PyObject*)co, globals, locals); if (!v && _PyErr_Occurred(tstate) == PyExc_KeyboardInterrupt) { - _Py_UnhandledKeyboardInterrupt = 1; + _PyRuntime.signals.unhandled_keyboard_interrupt = 1; } return v; } @@ -1660,7 +1847,7 @@ _Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyComp } if (strlen(str) != (size_t)size) { - PyErr_SetString(PyExc_ValueError, + PyErr_SetString(PyExc_SyntaxError, "source code string cannot contain null bytes"); Py_CLEAR(*cmd_copy); return NULL; diff --git a/Python/pytime.c b/Python/pytime.c index 9653662b0fb..01c07da0747 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -162,12 +162,11 @@ time_t _PyLong_AsTime_t(PyObject *obj) { #if SIZEOF_TIME_T == SIZEOF_LONG_LONG - long long val; - val = PyLong_AsLongLong(obj); + long long val = PyLong_AsLongLong(obj); +#elif SIZEOF_TIME_T <= SIZEOF_LONG + long val = PyLong_AsLong(obj); #else - long val; - Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long)); - val = PyLong_AsLong(obj); +# error "unsupported time_t size" #endif if (val == -1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) { @@ -184,9 +183,10 @@ _PyLong_FromTime_t(time_t t) { #if SIZEOF_TIME_T == SIZEOF_LONG_LONG return PyLong_FromLongLong((long long)t); -#else - Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long)); +#elif SIZEOF_TIME_T <= SIZEOF_LONG return PyLong_FromLong((long)t); +#else +# error "unsupported time_t size" #endif } @@ -386,10 +386,10 @@ _PyTime_t _PyTime_FromSeconds(int seconds) { /* ensure that integer overflow cannot happen, int type should have 32 - bits, whereas _PyTime_t type has at least 64 bits (SEC_TO_MS takes 30 + bits, whereas _PyTime_t type has at least 64 bits (SEC_TO_NS takes 30 bits). */ - Py_BUILD_ASSERT(INT_MAX <= _PyTime_MAX / SEC_TO_NS); - Py_BUILD_ASSERT(INT_MIN >= _PyTime_MIN / SEC_TO_NS); + static_assert(INT_MAX <= _PyTime_MAX / SEC_TO_NS, "_PyTime_t overflow"); + static_assert(INT_MIN >= _PyTime_MIN / SEC_TO_NS, "_PyTime_t underflow"); _PyTime_t t = (_PyTime_t)seconds; assert((t >= 0 && t <= _PyTime_MAX / SEC_TO_NS) @@ -406,6 +406,14 @@ _PyTime_FromNanoseconds(_PyTime_t ns) } +_PyTime_t +_PyTime_FromMicrosecondsClamp(_PyTime_t us) +{ + _PyTime_t ns = _PyTime_Mul(us, US_TO_NS); + return pytime_from_nanoseconds(ns); +} + + int _PyTime_FromNanosecondsObject(_PyTime_t *tp, PyObject *obj) { @@ -416,7 +424,8 @@ _PyTime_FromNanosecondsObject(_PyTime_t *tp, PyObject *obj) return -1; } - Py_BUILD_ASSERT(sizeof(long long) == sizeof(_PyTime_t)); + static_assert(sizeof(long long) == sizeof(_PyTime_t), + "_PyTime_t is not long long"); long long nsec = PyLong_AsLongLong(obj); if (nsec == -1 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) { @@ -437,7 +446,8 @@ pytime_fromtimespec(_PyTime_t *tp, struct timespec *ts, int raise_exc) { _PyTime_t t, tv_nsec; - Py_BUILD_ASSERT(sizeof(ts->tv_sec) <= sizeof(_PyTime_t)); + static_assert(sizeof(ts->tv_sec) <= sizeof(_PyTime_t), + "timespec.tv_sec is larger than _PyTime_t"); t = (_PyTime_t)ts->tv_sec; int res1 = pytime_mul(&t, SEC_TO_NS); @@ -466,7 +476,8 @@ _PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts) static int pytime_fromtimeval(_PyTime_t *tp, struct timeval *tv, int raise_exc) { - Py_BUILD_ASSERT(sizeof(tv->tv_sec) <= sizeof(_PyTime_t)); + static_assert(sizeof(tv->tv_sec) <= sizeof(_PyTime_t), + "timeval.tv_sec is larger than _PyTime_t"); _PyTime_t t = (_PyTime_t)tv->tv_sec; int res1 = pytime_mul(&t, SEC_TO_NS); @@ -537,7 +548,8 @@ pytime_from_object(_PyTime_t *tp, PyObject *obj, _PyTime_round_t round, return -1; } - Py_BUILD_ASSERT(sizeof(long long) <= sizeof(_PyTime_t)); + static_assert(sizeof(long long) <= sizeof(_PyTime_t), + "_PyTime_t is smaller than long long"); _PyTime_t ns = (_PyTime_t)sec; if (pytime_mul(&ns, unit_to_ns) < 0) { pytime_overflow(); @@ -589,7 +601,8 @@ PyObject * _PyTime_AsNanosecondsObject(_PyTime_t t) { _PyTime_t ns = pytime_as_nanoseconds(t); - Py_BUILD_ASSERT(sizeof(long long) >= sizeof(_PyTime_t)); + static_assert(sizeof(long long) >= sizeof(_PyTime_t), + "_PyTime_t is larger than long long"); return PyLong_FromLongLong((long long)ns); } @@ -962,7 +975,7 @@ _PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info) } -#if __APPLE__ +#ifdef __APPLE__ static int py_mach_timebase_info(_PyTime_t *pnumer, _PyTime_t *pdenom, int raise) { @@ -984,15 +997,17 @@ py_mach_timebase_info(_PyTime_t *pnumer, _PyTime_t *pdenom, int raise) _PyTime_t. In practice, timebase uses uint32_t, so casting cannot overflow. At the end, only make sure that the type is uint32_t (_PyTime_t is 64-bit long). */ - Py_BUILD_ASSERT(sizeof(timebase.numer) < sizeof(_PyTime_t)); - Py_BUILD_ASSERT(sizeof(timebase.denom) < sizeof(_PyTime_t)); + static_assert(sizeof(timebase.numer) <= sizeof(_PyTime_t), + "timebase.numer is larger than _PyTime_t"); + static_assert(sizeof(timebase.denom) <= sizeof(_PyTime_t), + "timebase.denom is larger than _PyTime_t"); - /* Make sure that (ticks * timebase.numer) cannot overflow in - _PyTime_MulDiv(), with ticks < timebase.denom. + /* Make sure that _PyTime_MulDiv(ticks, timebase_numer, timebase_denom) + cannot overflow. Known time bases: - * always (1, 1) on Intel + * (1, 1) on Intel * (1000000000, 33333335) or (1000000000, 25000000) on PowerPC None of these time bases can overflow with 64-bit _PyTime_t, but @@ -1019,8 +1034,17 @@ py_get_monotonic_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc) #if defined(MS_WINDOWS) ULONGLONG ticks = GetTickCount64(); - Py_BUILD_ASSERT(sizeof(ticks) <= sizeof(_PyTime_t)); - _PyTime_t t = (_PyTime_t)ticks; + static_assert(sizeof(ticks) <= sizeof(_PyTime_t), + "ULONGLONG is larger than _PyTime_t"); + _PyTime_t t; + if (ticks <= (ULONGLONG)_PyTime_MAX) { + t = (_PyTime_t)ticks; + } + else { + // GetTickCount64() maximum is larger than _PyTime_t maximum: + // ULONGLONG is unsigned, whereas _PyTime_t is signed. + t = _PyTime_MAX; + } int res = pytime_mul(&t, MS_TO_NS); *tp = t; @@ -1211,7 +1235,8 @@ py_get_win_perf_counter(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc) /* Make sure that casting LONGLONG to _PyTime_t cannot overflow, both types are signed */ _PyTime_t ticks; - Py_BUILD_ASSERT(sizeof(ticksll) <= sizeof(ticks)); + static_assert(sizeof(ticksll) <= sizeof(ticks), + "LONGLONG is larger than _PyTime_t"); ticks = (_PyTime_t)ticksll; _PyTime_t ns = _PyTime_MulDiv(ticks, SEC_TO_NS, (_PyTime_t)frequency); diff --git a/Python/specialize.c b/Python/specialize.c index 130da008ad8..84784b2d149 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1,11 +1,14 @@ #include "Python.h" #include "pycore_code.h" #include "pycore_dict.h" +#include "pycore_function.h" // _PyFunction_GetVersionForCurrentState() +#include "pycore_global_strings.h" // _Py_ID() #include "pycore_long.h" #include "pycore_moduleobject.h" #include "pycore_object.h" -#include "opcode.h" +#include "pycore_opcode.h" // _PyOpcode_Caches #include "structmember.h" // struct PyMemberDef, T_OFFSET_EX +#include "pycore_descrobject.h" #include // rand() @@ -13,34 +16,9 @@ * ./adaptive.md */ - -/* We layout the quickened data as a bi-directional array: - * Instructions upwards, cache entries downwards. - * first_instr is aligned to a SpecializedCacheEntry. - * The nth instruction is located at first_instr[n] - * The nth cache is located at ((SpecializedCacheEntry *)first_instr)[-1-n] - * The first (index 0) cache entry is reserved for the count, to enable finding - * the first instruction from the base pointer. - * The cache_count argument must include space for the count. - * We use the SpecializedCacheOrInstruction union to refer to the data - * to avoid type punning. - - Layout of quickened data, each line 8 bytes for M cache entries and N instructions: - - <---- co->co_quickened - - - ... - - <--- co->co_first_instr - - ... - -*/ - -Py_ssize_t _Py_QuickenedCount = 0; -#if COLLECT_SPECIALIZATION_STATS -SpecializationStats _specialization_stats[256] = { 0 }; +#ifdef Py_STATS +PyStats _py_stats_struct = { 0 }; +PyStats *_py_stats = NULL; #define ADD_STAT_TO_DICT(res, field) \ do { \ @@ -64,21 +42,19 @@ stats_to_dict(SpecializationStats *stats) if (res == NULL) { return NULL; } - ADD_STAT_TO_DICT(res, specialization_success); - ADD_STAT_TO_DICT(res, specialization_failure); + ADD_STAT_TO_DICT(res, success); + ADD_STAT_TO_DICT(res, failure); ADD_STAT_TO_DICT(res, hit); ADD_STAT_TO_DICT(res, deferred); ADD_STAT_TO_DICT(res, miss); ADD_STAT_TO_DICT(res, deopt); - ADD_STAT_TO_DICT(res, unquickened); -#if COLLECT_SPECIALIZATION_STATS_DETAILED PyObject *failure_kinds = PyTuple_New(SPECIALIZATION_FAILURE_KINDS); if (failure_kinds == NULL) { Py_DECREF(res); return NULL; } for (int i = 0; i < SPECIALIZATION_FAILURE_KINDS; i++) { - PyObject *stat = PyLong_FromUnsignedLongLong(stats->specialization_failure_kinds[i]); + PyObject *stat = PyLong_FromUnsignedLongLong(stats->failure_kinds[i]); if (stat == NULL) { Py_DECREF(res); Py_DECREF(failure_kinds); @@ -86,13 +62,12 @@ stats_to_dict(SpecializationStats *stats) } PyTuple_SET_ITEM(failure_kinds, i, stat); } - if (PyDict_SetItemString(res, "specialization_failure_kinds", failure_kinds)) { + if (PyDict_SetItemString(res, "failure_kinds", failure_kinds)) { Py_DECREF(res); Py_DECREF(failure_kinds); return NULL; } Py_DECREF(failure_kinds); -#endif return res; } #undef ADD_STAT_TO_DICT @@ -103,7 +78,7 @@ add_stat_dict( int opcode, const char *name) { - SpecializationStats *stats = &_specialization_stats[opcode]; + SpecializationStats *stats = &_py_stats_struct.opcode_stats[opcode].specialization; PyObject *d = stats_to_dict(stats); if (d == NULL) { return -1; @@ -113,7 +88,7 @@ add_stat_dict( return err; } -#if COLLECT_SPECIALIZATION_STATS +#ifdef Py_STATS PyObject* _Py_GetSpecializationStats(void) { PyObject *stats = PyDict_New(); @@ -123,12 +98,14 @@ _Py_GetSpecializationStats(void) { int err = 0; err += add_stat_dict(stats, LOAD_ATTR, "load_attr"); err += add_stat_dict(stats, LOAD_GLOBAL, "load_global"); - err += add_stat_dict(stats, LOAD_METHOD, "load_method"); err += add_stat_dict(stats, BINARY_SUBSCR, "binary_subscr"); err += add_stat_dict(stats, STORE_SUBSCR, "store_subscr"); err += add_stat_dict(stats, STORE_ATTR, "store_attr"); - err += add_stat_dict(stats, CALL_FUNCTION, "call_function"); + err += add_stat_dict(stats, CALL, "call"); err += add_stat_dict(stats, BINARY_OP, "binary_op"); + err += add_stat_dict(stats, COMPARE_OP, "compare_op"); + err += add_stat_dict(stats, UNPACK_SEQUENCE, "unpack_sequence"); + err += add_stat_dict(stats, FOR_ITER, "for_iter"); if (err < 0) { Py_DECREF(stats); return NULL; @@ -138,64 +115,146 @@ _Py_GetSpecializationStats(void) { #endif -#define PRINT_STAT(name, field) fprintf(out, " %s." #field " : %" PRIu64 "\n", name, stats->field); +#define PRINT_STAT(i, field) \ + if (stats[i].field) { \ + fprintf(out, " opcode[%d]." #field " : %" PRIu64 "\n", i, stats[i].field); \ + } static void -print_stats(FILE *out, SpecializationStats *stats, const char *name) +print_spec_stats(FILE *out, OpcodeStats *stats) { - PRINT_STAT(name, specialization_success); - PRINT_STAT(name, specialization_failure); - PRINT_STAT(name, hit); - PRINT_STAT(name, deferred); - PRINT_STAT(name, miss); - PRINT_STAT(name, deopt); - PRINT_STAT(name, unquickened); -#if PRINT_SPECIALIZATION_STATS_DETAILED - for (int i = 0; i < SPECIALIZATION_FAILURE_KINDS; i++) { - fprintf(out, " %s.specialization_failure_kinds[%d] : %" PRIu64 "\n", - name, i, stats->specialization_failure_kinds[i]); + /* Mark some opcodes as specializable for stats, + * even though we don't specialize them yet. */ + fprintf(out, "opcode[%d].specializable : 1\n", BINARY_SLICE); + fprintf(out, "opcode[%d].specializable : 1\n", COMPARE_OP); + fprintf(out, "opcode[%d].specializable : 1\n", STORE_SLICE); + for (int i = 0; i < 256; i++) { + if (_PyOpcode_Caches[i]) { + fprintf(out, "opcode[%d].specializable : 1\n", i); + } + PRINT_STAT(i, specialization.success); + PRINT_STAT(i, specialization.failure); + PRINT_STAT(i, specialization.hit); + PRINT_STAT(i, specialization.deferred); + PRINT_STAT(i, specialization.miss); + PRINT_STAT(i, specialization.deopt); + PRINT_STAT(i, execution_count); + for (int j = 0; j < SPECIALIZATION_FAILURE_KINDS; j++) { + uint64_t val = stats[i].specialization.failure_kinds[j]; + if (val) { + fprintf(out, " opcode[%d].specialization.failure_kinds[%d] : %" + PRIu64 "\n", i, j, val); + } + } + for(int j = 0; j < 256; j++) { + if (stats[i].pair_count[j]) { + fprintf(out, "opcode[%d].pair_count[%d] : %" PRIu64 "\n", + i, j, stats[i].pair_count[j]); + } + } } -#endif } #undef PRINT_STAT + +static void +print_call_stats(FILE *out, CallStats *stats) +{ + fprintf(out, "Calls to PyEval_EvalDefault: %" PRIu64 "\n", stats->pyeval_calls); + fprintf(out, "Calls to Python functions inlined: %" PRIu64 "\n", stats->inlined_py_calls); + fprintf(out, "Frames pushed: %" PRIu64 "\n", stats->frames_pushed); + fprintf(out, "Frame objects created: %" PRIu64 "\n", stats->frame_objects_created); + for (int i = 0; i < EVAL_CALL_KINDS; i++) { + fprintf(out, "Calls via PyEval_EvalFrame[%d] : %" PRIu64 "\n", i, stats->eval_calls[i]); + } +} + +static void +print_object_stats(FILE *out, ObjectStats *stats) +{ + fprintf(out, "Object allocations from freelist: %" PRIu64 "\n", stats->from_freelist); + fprintf(out, "Object frees to freelist: %" PRIu64 "\n", stats->to_freelist); + fprintf(out, "Object allocations: %" PRIu64 "\n", stats->allocations); + fprintf(out, "Object allocations to 512 bytes: %" PRIu64 "\n", stats->allocations512); + fprintf(out, "Object allocations to 4 kbytes: %" PRIu64 "\n", stats->allocations4k); + fprintf(out, "Object allocations over 4 kbytes: %" PRIu64 "\n", stats->allocations_big); + fprintf(out, "Object frees: %" PRIu64 "\n", stats->frees); + fprintf(out, "Object new values: %" PRIu64 "\n", stats->new_values); + fprintf(out, "Object interpreter increfs: %" PRIu64 "\n", stats->interpreter_increfs); + fprintf(out, "Object interpreter decrefs: %" PRIu64 "\n", stats->interpreter_decrefs); + fprintf(out, "Object increfs: %" PRIu64 "\n", stats->increfs); + fprintf(out, "Object decrefs: %" PRIu64 "\n", stats->decrefs); + fprintf(out, "Object materialize dict (on request): %" PRIu64 "\n", stats->dict_materialized_on_request); + fprintf(out, "Object materialize dict (new key): %" PRIu64 "\n", stats->dict_materialized_new_key); + fprintf(out, "Object materialize dict (too big): %" PRIu64 "\n", stats->dict_materialized_too_big); + fprintf(out, "Object materialize dict (str subclass): %" PRIu64 "\n", stats->dict_materialized_str_subclass); + fprintf(out, "Object method cache hits: %" PRIu64 "\n", stats->type_cache_hits); + fprintf(out, "Object method cache misses: %" PRIu64 "\n", stats->type_cache_misses); + fprintf(out, "Object method cache collisions: %" PRIu64 "\n", stats->type_cache_collisions); + fprintf(out, "Object method cache dunder hits: %" PRIu64 "\n", stats->type_cache_dunder_hits); + fprintf(out, "Object method cache dunder misses: %" PRIu64 "\n", stats->type_cache_dunder_misses); +} + +static void +print_stats(FILE *out, PyStats *stats) { + print_spec_stats(out, stats->opcode_stats); + print_call_stats(out, &stats->call_stats); + print_object_stats(out, &stats->object_stats); +} + void -_Py_PrintSpecializationStats(void) +_Py_StatsClear(void) +{ + _py_stats_struct = (PyStats) { 0 }; +} + +void +_Py_PrintSpecializationStats(int to_file) { FILE *out = stderr; -#if PRINT_SPECIALIZATION_STATS_TO_FILE - /* Write to a file instead of stderr. */ + if (to_file) { + /* Write to a file instead of stderr. */ # ifdef MS_WINDOWS - const char *dirname = "c:\\temp\\py_stats\\"; + const char *dirname = "c:\\temp\\py_stats\\"; # else - const char *dirname = "/tmp/py_stats/"; + const char *dirname = "/tmp/py_stats/"; # endif - char buf[48]; - sprintf(buf, "%s%u_%u.txt", dirname, (unsigned)clock(), (unsigned)rand()); - FILE *fout = fopen(buf, "w"); - if (fout) { - out = fout; + /* Use random 160 bit number as file name, + * to avoid both accidental collisions and + * symlink attacks. */ + unsigned char rand[20]; + char hex_name[41]; + _PyOS_URandomNonblock(rand, 20); + for (int i = 0; i < 20; i++) { + hex_name[2*i] = "0123456789abcdef"[rand[i]&15]; + hex_name[2*i+1] = "0123456789abcdef"[(rand[i]>>4)&15]; + } + hex_name[40] = '\0'; + char buf[64]; + assert(strlen(dirname) + 40 + strlen(".txt") < 64); + sprintf(buf, "%s%s.txt", dirname, hex_name); + FILE *fout = fopen(buf, "w"); + if (fout) { + out = fout; + } } -#else - fprintf(out, "Specialization stats:\n"); -#endif - print_stats(out, &_specialization_stats[LOAD_ATTR], "load_attr"); - print_stats(out, &_specialization_stats[LOAD_GLOBAL], "load_global"); - print_stats(out, &_specialization_stats[LOAD_METHOD], "load_method"); - print_stats(out, &_specialization_stats[BINARY_SUBSCR], "binary_subscr"); - print_stats(out, &_specialization_stats[STORE_SUBSCR], "store_subscr"); - print_stats(out, &_specialization_stats[STORE_ATTR], "store_attr"); - print_stats(out, &_specialization_stats[CALL_FUNCTION], "call_function"); - print_stats(out, &_specialization_stats[BINARY_OP], "binary_op"); + else { + fprintf(out, "Specialization stats:\n"); + } + print_stats(out, &_py_stats_struct); if (out != stderr) { fclose(out); } } -#if COLLECT_SPECIALIZATION_STATS_DETAILED - -#define SPECIALIZATION_FAIL(opcode, kind) _specialization_stats[opcode].specialization_failure_kinds[kind]++ +#ifdef Py_STATS +#define SPECIALIZATION_FAIL(opcode, kind) \ +do { \ + if (_py_stats) { \ + _py_stats->opcode_stats[opcode].specialization.failure_kinds[kind]++; \ + } \ +} while (0) #endif #endif @@ -204,226 +263,66 @@ _Py_PrintSpecializationStats(void) #define SPECIALIZATION_FAIL(opcode, kind) ((void)0) #endif -static SpecializedCacheOrInstruction * -allocate(int cache_count, int instruction_count) -{ - assert(sizeof(SpecializedCacheOrInstruction) == 2*sizeof(int32_t)); - assert(sizeof(SpecializedCacheEntry) == 2*sizeof(int32_t)); - assert(cache_count > 0); - assert(instruction_count > 0); - int count = cache_count + (instruction_count + INSTRUCTIONS_PER_ENTRY -1)/INSTRUCTIONS_PER_ENTRY; - SpecializedCacheOrInstruction *array = (SpecializedCacheOrInstruction *) - PyMem_Malloc(sizeof(SpecializedCacheOrInstruction) * count); - if (array == NULL) { - PyErr_NoMemory(); - return NULL; - } - _Py_QuickenedCount++; - array[0].entry.zero.cache_count = cache_count; - return array; -} - -static int -get_cache_count(SpecializedCacheOrInstruction *quickened) { - return quickened[0].entry.zero.cache_count; -} - -/* Map from opcode to adaptive opcode. - Values of zero are ignored. */ -static uint8_t adaptive_opcodes[256] = { - [LOAD_ATTR] = LOAD_ATTR_ADAPTIVE, - [LOAD_GLOBAL] = LOAD_GLOBAL_ADAPTIVE, - [LOAD_METHOD] = LOAD_METHOD_ADAPTIVE, - [BINARY_SUBSCR] = BINARY_SUBSCR_ADAPTIVE, - [STORE_SUBSCR] = STORE_SUBSCR_ADAPTIVE, - [CALL_FUNCTION] = CALL_FUNCTION_ADAPTIVE, - [STORE_ATTR] = STORE_ATTR_ADAPTIVE, - [BINARY_OP] = BINARY_OP_ADAPTIVE, +static int compare_masks[] = { + [Py_LT] = COMPARISON_LESS_THAN, + [Py_LE] = COMPARISON_LESS_THAN | COMPARISON_EQUALS, + [Py_EQ] = COMPARISON_EQUALS, + [Py_NE] = COMPARISON_NOT_EQUALS, + [Py_GT] = COMPARISON_GREATER_THAN, + [Py_GE] = COMPARISON_GREATER_THAN | COMPARISON_EQUALS, }; -/* The number of cache entries required for a "family" of instructions. */ -static uint8_t cache_requirements[256] = { - [LOAD_ATTR] = 2, /* _PyAdaptiveEntry and _PyAttrCache */ - [LOAD_GLOBAL] = 2, /* _PyAdaptiveEntry and _PyLoadGlobalCache */ - [LOAD_METHOD] = 3, /* _PyAdaptiveEntry, _PyAttrCache and _PyObjectCache */ - [BINARY_SUBSCR] = 2, /* _PyAdaptiveEntry, _PyObjectCache */ - [STORE_SUBSCR] = 0, - [CALL_FUNCTION] = 2, /* _PyAdaptiveEntry and _PyObjectCache/_PyCallCache */ - [STORE_ATTR] = 2, /* _PyAdaptiveEntry and _PyAttrCache */ - [BINARY_OP] = 1, // _PyAdaptiveEntry -}; - -/* Return the oparg for the cache_offset and instruction index. - * - * If no cache is needed then return the original oparg. - * If a cache is needed, but cannot be accessed because - * oparg would be too large, then return -1. - * - * Also updates the cache_offset, as it may need to be incremented by - * more than the cache requirements, if many instructions do not need caches. - * - * See pycore_code.h for details of how the cache offset, - * instruction index and oparg are related */ -static int -oparg_from_instruction_and_update_offset(int index, int opcode, int original_oparg, int *cache_offset) { - /* The instruction pointer in the interpreter points to the next - * instruction, so we compute the offset using nexti (index + 1) */ - int nexti = index + 1; - uint8_t need = cache_requirements[opcode]; - if (need == 0) { - return original_oparg; - } - assert(adaptive_opcodes[opcode] != 0); - int oparg = oparg_from_offset_and_nexti(*cache_offset, nexti); - assert(*cache_offset == offset_from_oparg_and_nexti(oparg, nexti)); - /* Some cache space is wasted here as the minimum possible offset is (nexti>>1) */ - if (oparg < 0) { - oparg = 0; - *cache_offset = offset_from_oparg_and_nexti(oparg, nexti); - } - else if (oparg > 255) { - return -1; - } - *cache_offset += need; - return oparg; -} - -static int -entries_needed(const _Py_CODEUNIT *code, int len) +// Initialize warmup counters and insert superinstructions. This cannot fail. +void +_PyCode_Quicken(PyCodeObject *code) { - int cache_offset = 0; - int previous_opcode = -1; - for (int i = 0; i < len; i++) { - uint8_t opcode = _Py_OPCODE(code[i]); - if (previous_opcode != EXTENDED_ARG) { - oparg_from_instruction_and_update_offset(i, opcode, 0, &cache_offset); + #if ENABLE_SPECIALIZATION + int opcode = 0; + _Py_CODEUNIT *instructions = _PyCode_CODE(code); + for (int i = 0; i < Py_SIZE(code); i++) { + int previous_opcode = opcode; + opcode = _PyOpcode_Deopt[_Py_OPCODE(instructions[i])]; + int caches = _PyOpcode_Caches[opcode]; + if (caches) { + instructions[i + 1].cache = adaptive_counter_warmup(); + i += caches; + continue; } - previous_opcode = opcode; - } - return cache_offset + 1; // One extra for the count entry -} - -static inline _Py_CODEUNIT * -first_instruction(SpecializedCacheOrInstruction *quickened) -{ - return &quickened[get_cache_count(quickened)].code[0]; -} - -/** Insert adaptive instructions and superinstructions. - * - * Skip instruction preceded by EXTENDED_ARG for adaptive - * instructions as those are both very rare and tricky - * to handle. - */ -static void -optimize(SpecializedCacheOrInstruction *quickened, int len) -{ - _Py_CODEUNIT *instructions = first_instruction(quickened); - int cache_offset = 0; - int previous_opcode = -1; - int previous_oparg = 0; - for(int i = 0; i < len; i++) { - int opcode = _Py_OPCODE(instructions[i]); - int oparg = _Py_OPARG(instructions[i]); - uint8_t adaptive_opcode = adaptive_opcodes[opcode]; - if (adaptive_opcode && previous_opcode != EXTENDED_ARG) { - int new_oparg = oparg_from_instruction_and_update_offset( - i, opcode, oparg, &cache_offset - ); - if (new_oparg < 0) { - /* Not possible to allocate a cache for this instruction */ - previous_opcode = opcode; - continue; + switch (previous_opcode << 8 | opcode) { + case LOAD_CONST << 8 | LOAD_FAST: + instructions[i - 1].opcode = LOAD_CONST__LOAD_FAST; + break; + case LOAD_FAST << 8 | LOAD_CONST: + instructions[i - 1].opcode = LOAD_FAST__LOAD_CONST; + break; + case LOAD_FAST << 8 | LOAD_FAST: + instructions[i - 1].opcode = LOAD_FAST__LOAD_FAST; + break; + case STORE_FAST << 8 | LOAD_FAST: + instructions[i - 1].opcode = STORE_FAST__LOAD_FAST; + break; + case STORE_FAST << 8 | STORE_FAST: + instructions[i - 1].opcode = STORE_FAST__STORE_FAST; + break; + case COMPARE_OP << 8 | POP_JUMP_IF_TRUE: + case COMPARE_OP << 8 | POP_JUMP_IF_FALSE: + { + int oparg = instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP].oparg; + assert((oparg >> 4) <= Py_GE); + int mask = compare_masks[oparg >> 4]; + if (opcode == POP_JUMP_IF_FALSE) { + mask = mask ^ 0xf; + } + instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP].opcode = COMPARE_AND_BRANCH; + instructions[i - 1 - INLINE_CACHE_ENTRIES_COMPARE_OP].oparg = (oparg & 0xf0) | mask; + break; } - previous_opcode = adaptive_opcode; - int entries_needed = cache_requirements[opcode]; - if (entries_needed) { - /* Initialize the adpative cache entry */ - int cache0_offset = cache_offset-entries_needed; - SpecializedCacheEntry *cache = - _GetSpecializedCacheEntry(instructions, cache0_offset); - cache->adaptive.original_oparg = oparg; - cache->adaptive.counter = 0; - } else { - // oparg is the adaptive cache counter - new_oparg = 0; - } - instructions[i] = _Py_MAKECODEUNIT(adaptive_opcode, new_oparg); - } - else { - /* Super instructions don't use the cache, - * so no need to update the offset. */ - switch (opcode) { - case JUMP_ABSOLUTE: - instructions[i] = _Py_MAKECODEUNIT(JUMP_ABSOLUTE_QUICK, oparg); - break; - case LOAD_FAST: - switch(previous_opcode) { - case LOAD_FAST: - instructions[i-1] = _Py_MAKECODEUNIT(LOAD_FAST__LOAD_FAST, previous_oparg); - break; - case STORE_FAST: - instructions[i-1] = _Py_MAKECODEUNIT(STORE_FAST__LOAD_FAST, previous_oparg); - break; - case LOAD_CONST: - instructions[i-1] = _Py_MAKECODEUNIT(LOAD_CONST__LOAD_FAST, previous_oparg); - break; - } - break; - case STORE_FAST: - if (previous_opcode == STORE_FAST) { - instructions[i-1] = _Py_MAKECODEUNIT(STORE_FAST__STORE_FAST, previous_oparg); - } - break; - case LOAD_CONST: - if (previous_opcode == LOAD_FAST) { - instructions[i-1] = _Py_MAKECODEUNIT(LOAD_FAST__LOAD_CONST, previous_oparg); - } - break; - } - previous_opcode = opcode; - previous_oparg = oparg; } } - assert(cache_offset+1 == get_cache_count(quickened)); + #endif /* ENABLE_SPECIALIZATION */ } -int -_Py_Quicken(PyCodeObject *code) { - if (code->co_quickened) { - return 0; - } - Py_ssize_t size = PyBytes_GET_SIZE(code->co_code); - int instr_count = (int)(size/sizeof(_Py_CODEUNIT)); - if (instr_count > MAX_SIZE_TO_QUICKEN) { - code->co_warmup = QUICKENING_WARMUP_COLDEST; - return 0; - } - int entry_count = entries_needed(code->co_firstinstr, instr_count); - SpecializedCacheOrInstruction *quickened = allocate(entry_count, instr_count); - if (quickened == NULL) { - return -1; - } - _Py_CODEUNIT *new_instructions = first_instruction(quickened); - memcpy(new_instructions, code->co_firstinstr, size); - optimize(quickened, instr_count); - code->co_quickened = quickened; - code->co_firstinstr = new_instructions; - return 0; -} - -static inline int -initial_counter_value(void) { - /* Starting value for the counter. - * This value needs to be not too low, otherwise - * it would cause excessive de-optimization. - * Neither should it be too high, or that would delay - * de-optimization excessively when it is needed. - * A value around 50 seems to work, and we choose a - * prime number to avoid artifacts. - */ - return 53; -} +#define SIMPLE_FUNCTION 0 /* Common */ @@ -433,107 +332,193 @@ initial_counter_value(void) { #define SPEC_FAIL_OUT_OF_VERSIONS 3 #define SPEC_FAIL_OUT_OF_RANGE 4 #define SPEC_FAIL_EXPECTED_ERROR 5 +#define SPEC_FAIL_WRONG_NUMBER_ARGUMENTS 6 +#define SPEC_FAIL_CODE_COMPLEX_PARAMETERS 7 +#define SPEC_FAIL_CODE_NOT_OPTIMIZED 8 + + +#define SPEC_FAIL_LOAD_GLOBAL_NON_DICT 17 +#define SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT 18 /* Attributes */ -#define SPEC_FAIL_NON_STRING_OR_SPLIT 6 -#define SPEC_FAIL_MODULE_ATTR_NOT_FOUND 7 -#define SPEC_FAIL_OVERRIDING_DESCRIPTOR 8 -#define SPEC_FAIL_NON_OVERRIDING_DESCRIPTOR 9 -#define SPEC_FAIL_NOT_DESCRIPTOR 10 -#define SPEC_FAIL_METHOD 11 -#define SPEC_FAIL_MUTABLE_CLASS 12 -#define SPEC_FAIL_PROPERTY 13 -#define SPEC_FAIL_NON_OBJECT_SLOT 14 -#define SPEC_FAIL_READ_ONLY 15 -#define SPEC_FAIL_AUDITED_SLOT 16 +#define SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR 9 +#define SPEC_FAIL_ATTR_NON_OVERRIDING_DESCRIPTOR 10 +#define SPEC_FAIL_ATTR_NOT_DESCRIPTOR 11 +#define SPEC_FAIL_ATTR_METHOD 12 +#define SPEC_FAIL_ATTR_MUTABLE_CLASS 13 +#define SPEC_FAIL_ATTR_PROPERTY 14 +#define SPEC_FAIL_ATTR_NON_OBJECT_SLOT 15 +#define SPEC_FAIL_ATTR_READ_ONLY 16 +#define SPEC_FAIL_ATTR_AUDITED_SLOT 17 +#define SPEC_FAIL_ATTR_NOT_MANAGED_DICT 18 +#define SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT 19 +#define SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND 20 -/* Methods */ +#define SPEC_FAIL_ATTR_SHADOWED 21 +#define SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD 22 +#define SPEC_FAIL_ATTR_CLASS_METHOD_OBJ 23 +#define SPEC_FAIL_ATTR_OBJECT_SLOT 24 +#define SPEC_FAIL_ATTR_HAS_MANAGED_DICT 25 +#define SPEC_FAIL_ATTR_INSTANCE_ATTRIBUTE 26 +#define SPEC_FAIL_ATTR_METACLASS_ATTRIBUTE 27 +#define SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION 28 +#define SPEC_FAIL_ATTR_NOT_IN_KEYS 29 +#define SPEC_FAIL_ATTR_NOT_IN_DICT 30 +#define SPEC_FAIL_ATTR_CLASS_ATTR_SIMPLE 31 +#define SPEC_FAIL_ATTR_CLASS_ATTR_DESCRIPTOR 32 +#define SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD_OBJ 33 -#define SPEC_FAIL_IS_ATTR 15 -#define SPEC_FAIL_DICT_SUBCLASS 16 -#define SPEC_FAIL_BUILTIN_CLASS_METHOD 17 -#define SPEC_FAIL_CLASS_METHOD_OBJ 18 -#define SPEC_FAIL_OBJECT_SLOT 19 +/* Binary subscr and store subscr */ -/* Binary subscr */ +#define SPEC_FAIL_SUBSCR_ARRAY_INT 9 +#define SPEC_FAIL_SUBSCR_ARRAY_SLICE 10 +#define SPEC_FAIL_SUBSCR_LIST_SLICE 11 +#define SPEC_FAIL_SUBSCR_TUPLE_SLICE 12 +#define SPEC_FAIL_SUBSCR_STRING_INT 13 +#define SPEC_FAIL_SUBSCR_STRING_SLICE 14 +#define SPEC_FAIL_SUBSCR_BUFFER_INT 15 +#define SPEC_FAIL_SUBSCR_BUFFER_SLICE 16 +#define SPEC_FAIL_SUBSCR_SEQUENCE_INT 17 -#define SPEC_FAIL_ARRAY_INT 8 -#define SPEC_FAIL_ARRAY_SLICE 9 -#define SPEC_FAIL_LIST_SLICE 10 -#define SPEC_FAIL_TUPLE_SLICE 11 -#define SPEC_FAIL_STRING_INT 12 -#define SPEC_FAIL_STRING_SLICE 13 -#define SPEC_FAIL_BUFFER_INT 15 -#define SPEC_FAIL_BUFFER_SLICE 16 -#define SPEC_FAIL_SEQUENCE_INT 17 +/* Store subscr */ +#define SPEC_FAIL_SUBSCR_BYTEARRAY_INT 18 +#define SPEC_FAIL_SUBSCR_BYTEARRAY_SLICE 19 +#define SPEC_FAIL_SUBSCR_PY_SIMPLE 20 +#define SPEC_FAIL_SUBSCR_PY_OTHER 21 +#define SPEC_FAIL_SUBSCR_DICT_SUBCLASS_NO_OVERRIDE 22 +#define SPEC_FAIL_SUBSCR_NOT_HEAP_TYPE 23 -/* Binary add */ +/* Binary op */ -#define SPEC_FAIL_NON_FUNCTION_SCOPE 11 -#define SPEC_FAIL_DIFFERENT_TYPES 12 +#define SPEC_FAIL_BINARY_OP_ADD_DIFFERENT_TYPES 9 +#define SPEC_FAIL_BINARY_OP_ADD_OTHER 10 +#define SPEC_FAIL_BINARY_OP_AND_DIFFERENT_TYPES 11 +#define SPEC_FAIL_BINARY_OP_AND_INT 12 +#define SPEC_FAIL_BINARY_OP_AND_OTHER 13 +#define SPEC_FAIL_BINARY_OP_FLOOR_DIVIDE 14 +#define SPEC_FAIL_BINARY_OP_LSHIFT 15 +#define SPEC_FAIL_BINARY_OP_MATRIX_MULTIPLY 16 +#define SPEC_FAIL_BINARY_OP_MULTIPLY_DIFFERENT_TYPES 17 +#define SPEC_FAIL_BINARY_OP_MULTIPLY_OTHER 18 +#define SPEC_FAIL_BINARY_OP_OR 19 +#define SPEC_FAIL_BINARY_OP_POWER 20 +#define SPEC_FAIL_BINARY_OP_REMAINDER 21 +#define SPEC_FAIL_BINARY_OP_RSHIFT 22 +#define SPEC_FAIL_BINARY_OP_SUBTRACT_DIFFERENT_TYPES 23 +#define SPEC_FAIL_BINARY_OP_SUBTRACT_OTHER 24 +#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_DIFFERENT_TYPES 25 +#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_FLOAT 26 +#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_OTHER 27 +#define SPEC_FAIL_BINARY_OP_XOR 28 /* Calls */ -#define SPEC_FAIL_GENERATOR 7 -#define SPEC_FAIL_COMPLEX_PARAMETERS 8 -#define SPEC_FAIL_WRONG_NUMBER_ARGUMENTS 9 -#define SPEC_FAIL_CO_NOT_OPTIMIZED 10 -/* SPEC_FAIL_METHOD defined as 11 above */ -#define SPEC_FAIL_FREE_VARS 12 -#define SPEC_FAIL_PYCFUNCTION 13 -#define SPEC_FAIL_PYCFUNCTION_WITH_KEYWORDS 14 -#define SPEC_FAIL_PYCFUNCTION_FAST_WITH_KEYWORDS 15 -#define SPEC_FAIL_PYCFUNCTION_NOARGS 16 -#define SPEC_FAIL_BAD_CALL_FLAGS 17 -#define SPEC_FAIL_CLASS 18 +#define SPEC_FAIL_CALL_INSTANCE_METHOD 11 +#define SPEC_FAIL_CALL_CMETHOD 12 +#define SPEC_FAIL_CALL_CFUNC_VARARGS 13 +#define SPEC_FAIL_CALL_CFUNC_VARARGS_KEYWORDS 14 +#define SPEC_FAIL_CALL_CFUNC_NOARGS 15 +#define SPEC_FAIL_CALL_CFUNC_METHOD_FASTCALL_KEYWORDS 16 +#define SPEC_FAIL_CALL_METH_DESCR_VARARGS 17 +#define SPEC_FAIL_CALL_METH_DESCR_VARARGS_KEYWORDS 18 +#define SPEC_FAIL_CALL_METH_DESCR_METHOD_FASTCALL_KEYWORDS 19 +#define SPEC_FAIL_CALL_BAD_CALL_FLAGS 20 +#define SPEC_FAIL_CALL_PYTHON_CLASS 21 +#define SPEC_FAIL_CALL_PEP_523 22 +#define SPEC_FAIL_CALL_BOUND_METHOD 23 +#define SPEC_FAIL_CALL_STR 24 +#define SPEC_FAIL_CALL_CLASS_NO_VECTORCALL 25 +#define SPEC_FAIL_CALL_CLASS_MUTABLE 26 +#define SPEC_FAIL_CALL_KWNAMES 27 +#define SPEC_FAIL_CALL_METHOD_WRAPPER 28 +#define SPEC_FAIL_CALL_OPERATOR_WRAPPER 29 + +/* COMPARE_OP */ +#define SPEC_FAIL_COMPARE_DIFFERENT_TYPES 12 +#define SPEC_FAIL_COMPARE_STRING 13 +#define SPEC_FAIL_COMPARE_NOT_FOLLOWED_BY_COND_JUMP 14 +#define SPEC_FAIL_COMPARE_BIG_INT 15 +#define SPEC_FAIL_COMPARE_BYTES 16 +#define SPEC_FAIL_COMPARE_TUPLE 17 +#define SPEC_FAIL_COMPARE_LIST 18 +#define SPEC_FAIL_COMPARE_SET 19 +#define SPEC_FAIL_COMPARE_BOOL 20 +#define SPEC_FAIL_COMPARE_BASEOBJECT 21 +#define SPEC_FAIL_COMPARE_FLOAT_LONG 22 +#define SPEC_FAIL_COMPARE_LONG_FLOAT 23 +#define SPEC_FAIL_COMPARE_EXTENDED_ARG 24 + +/* FOR_ITER */ +#define SPEC_FAIL_FOR_ITER_GENERATOR 10 +#define SPEC_FAIL_FOR_ITER_COROUTINE 11 +#define SPEC_FAIL_FOR_ITER_ASYNC_GENERATOR 12 +#define SPEC_FAIL_FOR_ITER_LIST 13 +#define SPEC_FAIL_FOR_ITER_TUPLE 14 +#define SPEC_FAIL_FOR_ITER_SET 15 +#define SPEC_FAIL_FOR_ITER_STRING 16 +#define SPEC_FAIL_FOR_ITER_BYTES 17 +#define SPEC_FAIL_FOR_ITER_RANGE 18 +#define SPEC_FAIL_FOR_ITER_ITERTOOLS 19 +#define SPEC_FAIL_FOR_ITER_DICT_KEYS 20 +#define SPEC_FAIL_FOR_ITER_DICT_ITEMS 21 +#define SPEC_FAIL_FOR_ITER_DICT_VALUES 22 +#define SPEC_FAIL_FOR_ITER_ENUMERATE 23 +#define SPEC_FAIL_FOR_ITER_MAP 24 +#define SPEC_FAIL_FOR_ITER_ZIP 25 +#define SPEC_FAIL_FOR_ITER_SEQ_ITER 26 +#define SPEC_FAIL_FOR_ITER_REVERSED_LIST 27 +#define SPEC_FAIL_FOR_ITER_CALLABLE 28 +#define SPEC_FAIL_FOR_ITER_ASCII_STRING 29 + +// UNPACK_SEQUENCE + +#define SPEC_FAIL_UNPACK_SEQUENCE_ITERATOR 9 +#define SPEC_FAIL_UNPACK_SEQUENCE_SEQUENCE 10 + +static int function_kind(PyCodeObject *code); +static bool function_check_args(PyObject *o, int expected_argcount, int opcode); +static uint32_t function_get_version(PyObject *o, int opcode); static int specialize_module_load_attr( - PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, - _PyAdaptiveEntry *cache0, _PyAttrCache *cache1, int opcode, - int opcode_module) -{ + PyObject *owner, _Py_CODEUNIT *instr, PyObject *name +) { + _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); PyModuleObject *m = (PyModuleObject *)owner; - PyObject *value = NULL; - PyObject *getattr; - _Py_IDENTIFIER(__getattr__); - assert(owner->ob_type->tp_inline_values_offset == 0); + assert((owner->ob_type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); PyDictObject *dict = (PyDictObject *)m->md_dict; if (dict == NULL) { - SPECIALIZATION_FAIL(opcode, SPEC_FAIL_NO_DICT); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_NO_DICT); return -1; } if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) { - SPECIALIZATION_FAIL(opcode, SPEC_FAIL_NON_STRING_OR_SPLIT); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT); return -1; } - getattr = _PyUnicode_FromId(&PyId___getattr__); /* borrowed */ - if (getattr == NULL) { - SPECIALIZATION_FAIL(opcode, SPEC_FAIL_OVERRIDDEN); - PyErr_Clear(); - return -1; - } - Py_ssize_t index = _PyDict_GetItemHint(dict, getattr, -1, &value); + Py_ssize_t index = _PyDict_LookupIndex(dict, &_Py_ID(__getattr__)); assert(index != DKIX_ERROR); if (index != DKIX_EMPTY) { - SPECIALIZATION_FAIL(opcode, SPEC_FAIL_MODULE_ATTR_NOT_FOUND); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND); return -1; } - index = _PyDict_GetItemHint(dict, name, -1, &value); + index = _PyDict_LookupIndex(dict, name); assert (index != DKIX_ERROR); if (index != (uint16_t)index) { - SPECIALIZATION_FAIL(opcode, SPEC_FAIL_OUT_OF_RANGE); + SPECIALIZATION_FAIL(LOAD_ATTR, + index == DKIX_EMPTY ? + SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND : + SPEC_FAIL_OUT_OF_RANGE); return -1; } uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState(dict->ma_keys); if (keys_version == 0) { - SPECIALIZATION_FAIL(opcode, SPEC_FAIL_OUT_OF_VERSIONS); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS); return -1; } - cache1->dk_version_or_hint = keys_version; - cache0->index = (uint16_t)index; - *instr = _Py_MAKECODEUNIT(opcode_module, _Py_OPARG(*instr)); + write_u32(cache->version, keys_version); + cache->index = (uint16_t)index; + _py_set_opcode(instr, LOAD_ATTR_MODULE); return 0; } @@ -554,13 +539,15 @@ typedef enum { MUTABLE, /* Instance of a mutable class; might, or might not, be a descriptor */ ABSENT, /* Attribute is not present on the class */ DUNDER_CLASS, /* __class__ attribute */ - GETSET_OVERRIDDEN /* __getattribute__ or __setattr__ has been overridden */ -} DesciptorClassification; + GETSET_OVERRIDDEN, /* __getattribute__ or __setattr__ has been overridden */ + GETATTRIBUTE_IS_PYTHON_FUNCTION /* Descriptor requires calling a Python __getattribute__ */ +} DescriptorClassification; -static DesciptorClassification +static DescriptorClassification analyze_descriptor(PyTypeObject *type, PyObject *name, PyObject **descr, int store) { + bool has_getattr = false; if (store) { if (type->tp_setattro != PyObject_GenericSetAttr) { *descr = NULL; @@ -568,7 +555,42 @@ analyze_descriptor(PyTypeObject *type, PyObject *name, PyObject **descr, int sto } } else { - if (type->tp_getattro != PyObject_GenericGetAttr) { + getattrofunc getattro_slot = type->tp_getattro; + if (getattro_slot == PyObject_GenericGetAttr) { + /* Normal attribute lookup; */ + has_getattr = false; + } + else if (getattro_slot == _Py_slot_tp_getattr_hook || + getattro_slot == _Py_slot_tp_getattro) { + /* One or both of __getattribute__ or __getattr__ may have been + overridden See typeobject.c for why these functions are special. */ + PyObject *getattribute = _PyType_Lookup(type, + &_Py_ID(__getattribute__)); + PyInterpreterState *interp = _PyInterpreterState_GET(); + bool has_custom_getattribute = getattribute != NULL && + getattribute != interp->callable_cache.object__getattribute__; + has_getattr = _PyType_Lookup(type, &_Py_ID(__getattr__)) != NULL; + if (has_custom_getattribute) { + if (getattro_slot == _Py_slot_tp_getattro && + !has_getattr && + Py_IS_TYPE(getattribute, &PyFunction_Type)) { + *descr = getattribute; + return GETATTRIBUTE_IS_PYTHON_FUNCTION; + } + /* Potentially both __getattr__ and __getattribute__ are set. + Too complicated */ + *descr = NULL; + return GETSET_OVERRIDDEN; + } + /* Potentially has __getattr__ but no custom __getattribute__. + Fall through to usual descriptor analysis. + Usual attribute lookup should only be allowed at runtime + if we can guarantee that there is no way an exception can be + raised. This means some specializations, e.g. specializing + for property() isn't safe. + */ + } + else { *descr = NULL; return GETSET_OVERRIDDEN; } @@ -592,14 +614,19 @@ analyze_descriptor(PyTypeObject *type, PyObject *name, PyObject **descr, int sto return OTHER_SLOT; } if (desc_cls == &PyProperty_Type) { - return PROPERTY; + /* We can't detect at runtime whether an attribute exists + with property. So that means we may have to call + __getattr__. */ + return has_getattr ? GETSET_OVERRIDDEN : PROPERTY; } if (PyUnicode_CompareWithASCIIString(name, "__class__") == 0) { if (descriptor == _PyType_Lookup(&PyBaseObject_Type, name)) { return DUNDER_CLASS; } } - return OVERRIDING; + if (store) { + return OVERRIDING; + } } if (desc_cls->tp_descr_get) { if (desc_cls->tp_flags & Py_TPFLAGS_METHOD_DESCRIPTOR) { @@ -619,113 +646,148 @@ analyze_descriptor(PyTypeObject *type, PyObject *name, PyObject **descr, int sto static int specialize_dict_access( PyObject *owner, _Py_CODEUNIT *instr, PyTypeObject *type, - DesciptorClassification kind, PyObject *name, - _PyAdaptiveEntry *cache0, _PyAttrCache *cache1, + DescriptorClassification kind, PyObject *name, int base_op, int values_op, int hint_op) { assert(kind == NON_OVERRIDING || kind == NON_DESCRIPTOR || kind == ABSENT || kind == BUILTIN_CLASSMETHOD || kind == PYTHON_CLASSMETHOD); // No descriptor, or non overriding. - if (type->tp_dictoffset < 0) { - SPECIALIZATION_FAIL(base_op, SPEC_FAIL_OUT_OF_RANGE); + if ((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { + SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_NOT_MANAGED_DICT); return 0; } - if (type->tp_dictoffset > 0) { - PyObject **dictptr = (PyObject **) ((char *)owner + type->tp_dictoffset); - PyDictObject *dict = (PyDictObject *)*dictptr; - if (type->tp_inline_values_offset && dict == NULL) { - // Virtual dictionary - PyDictKeysObject *keys = ((PyHeapTypeObject *)type)->ht_cached_keys; - assert(type->tp_inline_values_offset > 0); - assert(PyUnicode_CheckExact(name)); - Py_ssize_t index = _PyDictKeys_StringLookup(keys, name); - assert (index != DKIX_ERROR); - if (index != (uint16_t)index) { - SPECIALIZATION_FAIL(base_op, SPEC_FAIL_OUT_OF_RANGE); - return 0; - } - cache1->tp_version = type->tp_version_tag; - cache0->index = (uint16_t)index; - *instr = _Py_MAKECODEUNIT(values_op, _Py_OPARG(*instr)); + _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + if (_PyDictOrValues_IsValues(dorv)) { + // Virtual dictionary + PyDictKeysObject *keys = ((PyHeapTypeObject *)type)->ht_cached_keys; + assert(PyUnicode_CheckExact(name)); + Py_ssize_t index = _PyDictKeys_StringLookup(keys, name); + assert (index != DKIX_ERROR); + if (index != (uint16_t)index) { + SPECIALIZATION_FAIL(base_op, + index == DKIX_EMPTY ? + SPEC_FAIL_ATTR_NOT_IN_KEYS : + SPEC_FAIL_OUT_OF_RANGE); return 0; } - else { - if (dict == NULL || !PyDict_CheckExact(dict)) { - SPECIALIZATION_FAIL(base_op, SPEC_FAIL_NO_DICT); - return 0; - } - // We found an instance with a __dict__. - PyObject *value = NULL; - Py_ssize_t hint = - _PyDict_GetItemHint(dict, name, -1, &value); - if (hint != (uint32_t)hint) { - SPECIALIZATION_FAIL(base_op, SPEC_FAIL_OUT_OF_RANGE); - return 0; - } - cache1->dk_version_or_hint = (uint32_t)hint; - cache1->tp_version = type->tp_version_tag; - *instr = _Py_MAKECODEUNIT(hint_op, _Py_OPARG(*instr)); - return 1; + write_u32(cache->version, type->tp_version_tag); + cache->index = (uint16_t)index; + _py_set_opcode(instr, values_op); + } + else { + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + if (dict == NULL || !PyDict_CheckExact(dict)) { + SPECIALIZATION_FAIL(base_op, SPEC_FAIL_NO_DICT); + return 0; } + // We found an instance with a __dict__. + Py_ssize_t index = + _PyDict_LookupIndex(dict, name); + if (index != (uint16_t)index) { + SPECIALIZATION_FAIL(base_op, + index == DKIX_EMPTY ? + SPEC_FAIL_ATTR_NOT_IN_DICT : + SPEC_FAIL_OUT_OF_RANGE); + return 0; + } + cache->index = (uint16_t)index; + write_u32(cache->version, type->tp_version_tag); + _py_set_opcode(instr, hint_op); } - assert(type->tp_dictoffset == 0); - /* No attribute in instance dictionary */ - switch(kind) { - case NON_OVERRIDING: - case BUILTIN_CLASSMETHOD: - case PYTHON_CLASSMETHOD: - SPECIALIZATION_FAIL(base_op, SPEC_FAIL_NON_OVERRIDING_DESCRIPTOR); - return 0; - case NON_DESCRIPTOR: - /* To do -- Optimize this case */ - SPECIALIZATION_FAIL(base_op, SPEC_FAIL_NOT_DESCRIPTOR); - return 0; - case ABSENT: - SPECIALIZATION_FAIL(base_op, SPEC_FAIL_EXPECTED_ERROR); - return 0; - default: - Py_UNREACHABLE(); - } + return 1; } -int -_Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache) +static int specialize_attr_loadmethod(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name, + PyObject* descr, DescriptorClassification kind); +static int specialize_class_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name); + +void +_Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) { - _PyAdaptiveEntry *cache0 = &cache->adaptive; - _PyAttrCache *cache1 = &cache[-1].attr; + assert(ENABLE_SPECIALIZATION); + assert(_PyOpcode_Caches[LOAD_ATTR] == INLINE_CACHE_ENTRIES_LOAD_ATTR); + _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); + PyTypeObject *type = Py_TYPE(owner); + if (!_PyType_IsReady(type)) { + // We *might* not really need this check, but we inherited it from + // PyObject_GenericGetAttr and friends... and this way we still do the + // right thing if someone forgets to call PyType_Ready(type): + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OTHER); + goto fail; + } if (PyModule_CheckExact(owner)) { - int err = specialize_module_load_attr(owner, instr, name, cache0, cache1, - LOAD_ATTR, LOAD_ATTR_MODULE); - if (err) { + if (specialize_module_load_attr(owner, instr, name)) + { goto fail; } goto success; } - PyTypeObject *type = Py_TYPE(owner); - if (type->tp_dict == NULL) { - if (PyType_Ready(type) < 0) { - return -1; + if (PyType_Check(owner)) { + if (specialize_class_load_attr(owner, instr, name)) { + goto fail; } + goto success; } - PyObject *descr; - DesciptorClassification kind = analyze_descriptor(type, name, &descr, 0); + PyObject *descr = NULL; + DescriptorClassification kind = analyze_descriptor(type, name, &descr, 0); + assert(descr != NULL || kind == ABSENT || kind == GETSET_OVERRIDDEN); switch(kind) { case OVERRIDING: - SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OVERRIDING_DESCRIPTOR); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR); goto fail; case METHOD: - SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_METHOD); + { + int oparg = _Py_OPARG(*instr); + if (oparg & 1) { + if (specialize_attr_loadmethod(owner, instr, name, descr, kind)) { + goto success; + } + } + else { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD); + } goto fail; + } case PROPERTY: - SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_PROPERTY); - goto fail; + { + _PyLoadMethodCache *lm_cache = (_PyLoadMethodCache *)(instr + 1); + assert(Py_TYPE(descr) == &PyProperty_Type); + PyObject *fget = ((_PyPropertyObject *)descr)->prop_get; + if (fget == NULL) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR); + goto fail; + } + if (!Py_IS_TYPE(fget, &PyFunction_Type)) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION); + goto fail; + } + if (!function_check_args(fget, 1, LOAD_ATTR)) { + goto fail; + } + uint32_t version = function_get_version(fget, LOAD_ATTR); + if (version == 0) { + goto fail; + } + write_u32(lm_cache->keys_version, version); + assert(type->tp_version_tag != 0); + write_u32(lm_cache->type_version, type->tp_version_tag); + /* borrowed */ + write_obj(lm_cache->descr, fget); + _py_set_opcode(instr, LOAD_ATTR_PROPERTY); + goto success; + } case OBJECT_SLOT: { PyMemberDescrObject *member = (PyMemberDescrObject *)descr; struct PyMemberDef *dmem = member->d_member; Py_ssize_t offset = dmem->offset; + if (!PyObject_TypeCheck(owner, member->d_common.d_type)) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR); + goto fail; + } if (dmem->flags & PY_AUDIT_READ) { - SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_AUDITED_SLOT); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_AUDITED_SLOT); goto fail; } if (offset != (uint16_t)offset) { @@ -734,87 +796,126 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, Sp } assert(dmem->type == T_OBJECT_EX); assert(offset > 0); - cache0->index = (uint16_t)offset; - cache1->tp_version = type->tp_version_tag; - *instr = _Py_MAKECODEUNIT(LOAD_ATTR_SLOT, _Py_OPARG(*instr)); + cache->index = (uint16_t)offset; + write_u32(cache->version, type->tp_version_tag); + _py_set_opcode(instr, LOAD_ATTR_SLOT); goto success; } case DUNDER_CLASS: { Py_ssize_t offset = offsetof(PyObject, ob_type); assert(offset == (uint16_t)offset); - cache0->index = (uint16_t)offset; - cache1->tp_version = type->tp_version_tag; - *instr = _Py_MAKECODEUNIT(LOAD_ATTR_SLOT, _Py_OPARG(*instr)); + cache->index = (uint16_t)offset; + write_u32(cache->version, type->tp_version_tag); + _py_set_opcode(instr, LOAD_ATTR_SLOT); goto success; } case OTHER_SLOT: - SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_NON_OBJECT_SLOT); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NON_OBJECT_SLOT); goto fail; case MUTABLE: - SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_MUTABLE_CLASS); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_MUTABLE_CLASS); goto fail; case GETSET_OVERRIDDEN: SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OVERRIDDEN); goto fail; + case GETATTRIBUTE_IS_PYTHON_FUNCTION: + { + assert(type->tp_getattro == _Py_slot_tp_getattro); + assert(Py_IS_TYPE(descr, &PyFunction_Type)); + _PyLoadMethodCache *lm_cache = (_PyLoadMethodCache *)(instr + 1); + if (!function_check_args(descr, 2, LOAD_ATTR)) { + goto fail; + } + uint32_t version = function_get_version(descr, LOAD_ATTR); + if (version == 0) { + goto fail; + } + write_u32(lm_cache->keys_version, version); + /* borrowed */ + write_obj(lm_cache->descr, descr); + write_u32(lm_cache->type_version, type->tp_version_tag); + _py_set_opcode(instr, LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN); + goto success; + } case BUILTIN_CLASSMETHOD: + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD_OBJ); + goto fail; case PYTHON_CLASSMETHOD: + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_CLASS_METHOD_OBJ); + goto fail; case NON_OVERRIDING: + SPECIALIZATION_FAIL(LOAD_ATTR, + (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) ? + SPEC_FAIL_ATTR_CLASS_ATTR_DESCRIPTOR : + SPEC_FAIL_ATTR_NOT_MANAGED_DICT); + goto fail; case NON_DESCRIPTOR: + SPECIALIZATION_FAIL(LOAD_ATTR, + (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) ? + SPEC_FAIL_ATTR_CLASS_ATTR_SIMPLE : + SPEC_FAIL_ATTR_NOT_MANAGED_DICT); + goto fail; case ABSENT: - break; - } - int err = specialize_dict_access( - owner, instr, type, kind, name, cache0, cache1, - LOAD_ATTR, LOAD_ATTR_INSTANCE_VALUE, LOAD_ATTR_WITH_HINT - ); - if (err < 0) { - return -1; - } - if (err) { - goto success; + if (specialize_dict_access(owner, instr, type, kind, name, LOAD_ATTR, + LOAD_ATTR_INSTANCE_VALUE, LOAD_ATTR_WITH_HINT)) + { + goto success; + } } fail: - STAT_INC(LOAD_ATTR, specialization_failure); + STAT_INC(LOAD_ATTR, failure); assert(!PyErr_Occurred()); - cache_backoff(cache0); - return 0; + _py_set_opcode(instr, LOAD_ATTR); + cache->counter = adaptive_counter_backoff(cache->counter); + return; success: - STAT_INC(LOAD_ATTR, specialization_success); + STAT_INC(LOAD_ATTR, success); assert(!PyErr_Occurred()); - cache0->counter = initial_counter_value(); - return 0; + cache->counter = adaptive_counter_cooldown(); } -int -_Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache) +void +_Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) { - _PyAdaptiveEntry *cache0 = &cache->adaptive; - _PyAttrCache *cache1 = &cache[-1].attr; + assert(ENABLE_SPECIALIZATION); + assert(_PyOpcode_Caches[STORE_ATTR] == INLINE_CACHE_ENTRIES_STORE_ATTR); + _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); PyTypeObject *type = Py_TYPE(owner); + if (!_PyType_IsReady(type)) { + // We *might* not really need this check, but we inherited it from + // PyObject_GenericSetAttr and friends... and this way we still do the + // right thing if someone forgets to call PyType_Ready(type): + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_OTHER); + goto fail; + } if (PyModule_CheckExact(owner)) { SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_OVERRIDDEN); goto fail; } PyObject *descr; - DesciptorClassification kind = analyze_descriptor(type, name, &descr, 1); + DescriptorClassification kind = analyze_descriptor(type, name, &descr, 1); switch(kind) { case OVERRIDING: - SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_OVERRIDING_DESCRIPTOR); + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR); goto fail; case METHOD: - SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_METHOD); + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_METHOD); goto fail; case PROPERTY: - SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_PROPERTY); + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_PROPERTY); goto fail; case OBJECT_SLOT: { PyMemberDescrObject *member = (PyMemberDescrObject *)descr; struct PyMemberDef *dmem = member->d_member; Py_ssize_t offset = dmem->offset; + if (!PyObject_TypeCheck(owner, member->d_common.d_type)) { + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_EXPECTED_ERROR); + goto fail; + } if (dmem->flags & READONLY) { - SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_READ_ONLY); + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_READ_ONLY); goto fail; } if (offset != (uint16_t)offset) { @@ -823,184 +924,205 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, S } assert(dmem->type == T_OBJECT_EX); assert(offset > 0); - cache0->index = (uint16_t)offset; - cache1->tp_version = type->tp_version_tag; - *instr = _Py_MAKECODEUNIT(STORE_ATTR_SLOT, _Py_OPARG(*instr)); + cache->index = (uint16_t)offset; + write_u32(cache->version, type->tp_version_tag); + _py_set_opcode(instr, STORE_ATTR_SLOT); goto success; } case DUNDER_CLASS: case OTHER_SLOT: - SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_NON_OBJECT_SLOT); + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_NON_OBJECT_SLOT); goto fail; case MUTABLE: - SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_MUTABLE_CLASS); + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_MUTABLE_CLASS); goto fail; + case GETATTRIBUTE_IS_PYTHON_FUNCTION: case GETSET_OVERRIDDEN: SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_OVERRIDDEN); goto fail; case BUILTIN_CLASSMETHOD: + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD_OBJ); + goto fail; case PYTHON_CLASSMETHOD: + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_CLASS_METHOD_OBJ); + goto fail; case NON_OVERRIDING: + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_CLASS_ATTR_DESCRIPTOR); + goto fail; case NON_DESCRIPTOR: + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_CLASS_ATTR_SIMPLE); + goto fail; case ABSENT: - break; - } - - int err = specialize_dict_access( - owner, instr, type, kind, name, cache0, cache1, - STORE_ATTR, STORE_ATTR_INSTANCE_VALUE, STORE_ATTR_WITH_HINT - ); - if (err < 0) { - return -1; - } - if (err) { - goto success; + if (specialize_dict_access(owner, instr, type, kind, name, STORE_ATTR, + STORE_ATTR_INSTANCE_VALUE, STORE_ATTR_WITH_HINT)) + { + goto success; + } } fail: - STAT_INC(STORE_ATTR, specialization_failure); + STAT_INC(STORE_ATTR, failure); assert(!PyErr_Occurred()); - cache_backoff(cache0); - return 0; + _py_set_opcode(instr, STORE_ATTR); + cache->counter = adaptive_counter_backoff(cache->counter); + return; success: - STAT_INC(STORE_ATTR, specialization_success); + STAT_INC(STORE_ATTR, success); assert(!PyErr_Occurred()); - cache0->counter = initial_counter_value(); - return 0; + cache->counter = adaptive_counter_cooldown(); } -#if COLLECT_SPECIALIZATION_STATS_DETAILED +#ifdef Py_STATS static int -load_method_fail_kind(DesciptorClassification kind) +load_attr_fail_kind(DescriptorClassification kind) { switch (kind) { case OVERRIDING: - return SPEC_FAIL_OVERRIDING_DESCRIPTOR; + return SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR; case METHOD: - return SPEC_FAIL_METHOD; + return SPEC_FAIL_ATTR_METHOD; case PROPERTY: - return SPEC_FAIL_PROPERTY; + return SPEC_FAIL_ATTR_PROPERTY; case OBJECT_SLOT: - return SPEC_FAIL_OBJECT_SLOT; + return SPEC_FAIL_ATTR_OBJECT_SLOT; case OTHER_SLOT: - return SPEC_FAIL_NON_OBJECT_SLOT; + return SPEC_FAIL_ATTR_NON_OBJECT_SLOT; case DUNDER_CLASS: return SPEC_FAIL_OTHER; case MUTABLE: - return SPEC_FAIL_MUTABLE_CLASS; + return SPEC_FAIL_ATTR_MUTABLE_CLASS; case GETSET_OVERRIDDEN: + case GETATTRIBUTE_IS_PYTHON_FUNCTION: return SPEC_FAIL_OVERRIDDEN; case BUILTIN_CLASSMETHOD: - return SPEC_FAIL_BUILTIN_CLASS_METHOD; + return SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD; case PYTHON_CLASSMETHOD: - return SPEC_FAIL_CLASS_METHOD_OBJ; + return SPEC_FAIL_ATTR_CLASS_METHOD_OBJ; case NON_OVERRIDING: - return SPEC_FAIL_NON_OVERRIDING_DESCRIPTOR; + return SPEC_FAIL_ATTR_NON_OVERRIDING_DESCRIPTOR; case NON_DESCRIPTOR: - return SPEC_FAIL_NOT_DESCRIPTOR; + return SPEC_FAIL_ATTR_NOT_DESCRIPTOR; case ABSENT: - return SPEC_FAIL_EXPECTED_ERROR; + return SPEC_FAIL_ATTR_INSTANCE_ATTRIBUTE; } Py_UNREACHABLE(); } #endif static int -specialize_class_load_method(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, - _PyAttrCache *cache1, _PyObjectCache *cache2) +specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr, + PyObject *name) { - + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)(instr + 1); + if (!PyType_CheckExact(owner) || _PyType_Lookup(Py_TYPE(owner), name)) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METACLASS_ATTRIBUTE); + return -1; + } PyObject *descr = NULL; - DesciptorClassification kind = 0; + DescriptorClassification kind = 0; kind = analyze_descriptor((PyTypeObject *)owner, name, &descr, 0); switch (kind) { case METHOD: case NON_DESCRIPTOR: - cache1->tp_version = ((PyTypeObject *)owner)->tp_version_tag; - cache2->obj = descr; - *instr = _Py_MAKECODEUNIT(LOAD_METHOD_CLASS, _Py_OPARG(*instr)); + write_u32(cache->type_version, ((PyTypeObject *)owner)->tp_version_tag); + write_obj(cache->descr, descr); + _py_set_opcode(instr, LOAD_ATTR_CLASS); return 0; +#ifdef Py_STATS + case ABSENT: + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR); + return -1; +#endif default: - SPECIALIZATION_FAIL(LOAD_METHOD, load_method_fail_kind(kind)); + SPECIALIZATION_FAIL(LOAD_ATTR, load_attr_fail_kind(kind)); return -1; } } +typedef enum { + MANAGED_VALUES = 1, + MANAGED_DICT = 2, + OFFSET_DICT = 3, + NO_DICT = 4, + LAZY_DICT = 5, +} ObjectDictKind; + // Please collect stats carefully before and after modifying. A subtle change // can cause a significant drop in cache hits. A possible test is // python.exe -m test_typing test_re test_dis test_zlib. -int -_Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache) +static int +specialize_attr_loadmethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, +PyObject *descr, DescriptorClassification kind) { - _PyAdaptiveEntry *cache0 = &cache->adaptive; - _PyAttrCache *cache1 = &cache[-1].attr; - _PyObjectCache *cache2 = &cache[-2].obj; - + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)(instr + 1); PyTypeObject *owner_cls = Py_TYPE(owner); - if (PyModule_CheckExact(owner)) { - int err = specialize_module_load_attr(owner, instr, name, cache0, cache1, - LOAD_METHOD, LOAD_METHOD_MODULE); - if (err) { - goto fail; - } - goto success; - } - if (owner_cls->tp_dict == NULL) { - if (PyType_Ready(owner_cls) < 0) { - return -1; - } - } - if (PyType_Check(owner)) { - int err = specialize_class_load_method(owner, instr, name, cache1, cache2); - if (err) { - goto fail; - } - goto success; - } - // Technically this is fine for bound method calls, but it's uncommon and - // slightly slower at runtime to get dict. - if (owner_cls->tp_dictoffset < 0) { - SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OUT_OF_RANGE); - goto fail; - } - PyObject *descr = NULL; - DesciptorClassification kind = 0; - kind = analyze_descriptor(owner_cls, name, &descr, 0); - assert(descr != NULL || kind == ABSENT || kind == GETSET_OVERRIDDEN); - if (kind != METHOD) { - SPECIALIZATION_FAIL(LOAD_METHOD, load_method_fail_kind(kind)); - goto fail; + assert(kind == METHOD && descr != NULL); + ObjectDictKind dictkind; + PyDictKeysObject *keys; + if (owner_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + keys = ((PyHeapTypeObject *)owner_cls)->ht_cached_keys; + if (_PyDictOrValues_IsValues(dorv)) { + dictkind = MANAGED_VALUES; + } + else { + dictkind = MANAGED_DICT; + } } - if (owner_cls->tp_inline_values_offset) { - PyObject **owner_dictptr = _PyObject_DictPointer(owner); - assert(owner_dictptr); - if (*owner_dictptr) { - SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_IS_ATTR); + else { + Py_ssize_t dictoffset = owner_cls->tp_dictoffset; + if (dictoffset < 0 || dictoffset > INT16_MAX) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_RANGE); goto fail; } - PyDictKeysObject *keys = ((PyHeapTypeObject *)owner_cls)->ht_cached_keys; + if (dictoffset == 0) { + dictkind = NO_DICT; + keys = NULL; + } + else { + PyObject *dict = *(PyObject **) ((char *)owner + dictoffset); + if (dict == NULL) { + // This object will have a dict if user access __dict__ + dictkind = LAZY_DICT; + keys = NULL; + } + else { + keys = ((PyDictObject *)dict)->ma_keys; + dictkind = OFFSET_DICT; + } + } + } + if (dictkind == MANAGED_VALUES || dictkind == OFFSET_DICT) { Py_ssize_t index = _PyDictKeys_StringLookup(keys, name); if (index != DKIX_EMPTY) { - SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_IS_ATTR); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_SHADOWED); goto fail; } uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState(keys); if (keys_version == 0) { - SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OUT_OF_VERSIONS); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS); goto fail; } - cache1->dk_version_or_hint = keys_version; - *instr = _Py_MAKECODEUNIT(LOAD_METHOD_CACHED, _Py_OPARG(*instr)); + write_u32(cache->keys_version, keys_version); } - else { - if (owner_cls->tp_dictoffset == 0) { - *instr = _Py_MAKECODEUNIT(LOAD_METHOD_NO_DICT, _Py_OPARG(*instr)); - } - else { - SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_IS_ATTR); + switch(dictkind) { + case NO_DICT: + _py_set_opcode(instr, LOAD_ATTR_METHOD_NO_DICT); + break; + case MANAGED_VALUES: + _py_set_opcode(instr, LOAD_ATTR_METHOD_WITH_VALUES); + break; + case MANAGED_DICT: + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_HAS_MANAGED_DICT); goto fail; - } + case OFFSET_DICT: + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NOT_MANAGED_DICT); + goto fail; + case LAZY_DICT: + assert(owner_cls->tp_dictoffset > 0 && owner_cls->tp_dictoffset <= INT16_MAX); + _py_set_opcode(instr, LOAD_ATTR_METHOD_LAZY_DICT); + break; } /* `descr` is borrowed. This is safe for methods (even inherited ones from * super classes!) as long as tp_version_tag is validated for two main reasons: @@ -1016,63 +1138,68 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, * PyType_Modified usages in typeobject.c). The MCACHE has been * working since Python 2.6 and it's battle-tested. */ - cache1->tp_version = owner_cls->tp_version_tag; - cache2->obj = descr; - // Fall through. -success: - STAT_INC(LOAD_METHOD, specialization_success); - assert(!PyErr_Occurred()); - cache0->counter = initial_counter_value(); - return 0; + write_u32(cache->type_version, owner_cls->tp_version_tag); + write_obj(cache->descr, descr); + return 1; fail: - STAT_INC(LOAD_METHOD, specialization_failure); - assert(!PyErr_Occurred()); - cache_backoff(cache0); return 0; - } -int +void _Py_Specialize_LoadGlobal( PyObject *globals, PyObject *builtins, - _Py_CODEUNIT *instr, PyObject *name, - SpecializedCacheEntry *cache) + _Py_CODEUNIT *instr, PyObject *name) { - _PyAdaptiveEntry *cache0 = &cache->adaptive; - _PyLoadGlobalCache *cache1 = &cache[-1].load_global; + assert(ENABLE_SPECIALIZATION); + assert(_PyOpcode_Caches[LOAD_GLOBAL] == INLINE_CACHE_ENTRIES_LOAD_GLOBAL); + /* Use inline cache */ + _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)(instr + 1); assert(PyUnicode_CheckExact(name)); if (!PyDict_CheckExact(globals)) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_DICT); goto fail; } PyDictKeysObject * globals_keys = ((PyDictObject *)globals)->ma_keys; + if (!DK_IS_UNICODE(globals_keys)) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT); + goto fail; + } Py_ssize_t index = _PyDictKeys_StringLookup(globals_keys, name); if (index == DKIX_ERROR) { - SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_NON_STRING_OR_SPLIT); + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_EXPECTED_ERROR); goto fail; } if (index != DKIX_EMPTY) { if (index != (uint16_t)index) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE); goto fail; } uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState(globals_keys); if (keys_version == 0) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS); goto fail; } - cache1->module_keys_version = keys_version; - cache0->index = (uint16_t)index; - *instr = _Py_MAKECODEUNIT(LOAD_GLOBAL_MODULE, _Py_OPARG(*instr)); + cache->index = (uint16_t)index; + write_u32(cache->module_keys_version, keys_version); + _py_set_opcode(instr, LOAD_GLOBAL_MODULE); goto success; } if (!PyDict_CheckExact(builtins)) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_DICT); goto fail; } PyDictKeysObject * builtin_keys = ((PyDictObject *)builtins)->ma_keys; + if (!DK_IS_UNICODE(builtin_keys)) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT); + goto fail; + } index = _PyDictKeys_StringLookup(builtin_keys, name); if (index == DKIX_ERROR) { - SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_NON_STRING_OR_SPLIT); + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_EXPECTED_ERROR); goto fail; } if (index != (uint16_t)index) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE); goto fail; } uint32_t globals_version = _PyDictKeys_GetVersionForCurrentState(globals_keys); @@ -1085,164 +1212,208 @@ _Py_Specialize_LoadGlobal( SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS); goto fail; } - cache1->module_keys_version = globals_version; - cache1->builtin_keys_version = builtins_version; - cache0->index = (uint16_t)index; - *instr = _Py_MAKECODEUNIT(LOAD_GLOBAL_BUILTIN, _Py_OPARG(*instr)); + if (builtins_version > UINT16_MAX) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE); + goto fail; + } + cache->index = (uint16_t)index; + write_u32(cache->module_keys_version, globals_version); + cache->builtin_keys_version = (uint16_t)builtins_version; + _py_set_opcode(instr, LOAD_GLOBAL_BUILTIN); goto success; fail: - STAT_INC(LOAD_GLOBAL, specialization_failure); + STAT_INC(LOAD_GLOBAL, failure); assert(!PyErr_Occurred()); - cache_backoff(cache0); - return 0; + _py_set_opcode(instr, LOAD_GLOBAL); + cache->counter = adaptive_counter_backoff(cache->counter); + return; success: - STAT_INC(LOAD_GLOBAL, specialization_success); + STAT_INC(LOAD_GLOBAL, success); assert(!PyErr_Occurred()); - cache0->counter = initial_counter_value(); - return 0; + cache->counter = adaptive_counter_cooldown(); } -#if COLLECT_SPECIALIZATION_STATS_DETAILED +#ifdef Py_STATS static int binary_subscr_fail_kind(PyTypeObject *container_type, PyObject *sub) { if (container_type == &PyUnicode_Type) { if (PyLong_CheckExact(sub)) { - return SPEC_FAIL_STRING_INT; + return SPEC_FAIL_SUBSCR_STRING_INT; } if (PySlice_Check(sub)) { - return SPEC_FAIL_STRING_SLICE; + return SPEC_FAIL_SUBSCR_STRING_SLICE; } return SPEC_FAIL_OTHER; } else if (strcmp(container_type->tp_name, "array.array") == 0) { if (PyLong_CheckExact(sub)) { - return SPEC_FAIL_ARRAY_INT; + return SPEC_FAIL_SUBSCR_ARRAY_INT; } if (PySlice_Check(sub)) { - return SPEC_FAIL_ARRAY_SLICE; + return SPEC_FAIL_SUBSCR_ARRAY_SLICE; } return SPEC_FAIL_OTHER; } else if (container_type->tp_as_buffer) { if (PyLong_CheckExact(sub)) { - return SPEC_FAIL_BUFFER_INT; + return SPEC_FAIL_SUBSCR_BUFFER_INT; } if (PySlice_Check(sub)) { - return SPEC_FAIL_BUFFER_SLICE; + return SPEC_FAIL_SUBSCR_BUFFER_SLICE; } return SPEC_FAIL_OTHER; } else if (container_type->tp_as_sequence) { if (PyLong_CheckExact(sub) && container_type->tp_as_sequence->sq_item) { - return SPEC_FAIL_SEQUENCE_INT; + return SPEC_FAIL_SUBSCR_SEQUENCE_INT; } } return SPEC_FAIL_OTHER; } #endif -_Py_IDENTIFIER(__getitem__); - -#define SIMPLE_FUNCTION 0 - static int function_kind(PyCodeObject *code) { int flags = code->co_flags; - if (flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) { - return SPEC_FAIL_GENERATOR; - } if ((flags & (CO_VARKEYWORDS | CO_VARARGS)) || code->co_kwonlyargcount) { - return SPEC_FAIL_COMPLEX_PARAMETERS; + return SPEC_FAIL_CODE_COMPLEX_PARAMETERS; } if ((flags & CO_OPTIMIZED) == 0) { - return SPEC_FAIL_CO_NOT_OPTIMIZED; - } - if (code->co_nfreevars) { - return SPEC_FAIL_FREE_VARS; + return SPEC_FAIL_CODE_NOT_OPTIMIZED; } return SIMPLE_FUNCTION; } -int -_Py_Specialize_BinarySubscr( - PyObject *container, PyObject *sub, _Py_CODEUNIT *instr, SpecializedCacheEntry *cache) +/* Returning false indicates a failure. */ +static bool +function_check_args(PyObject *o, int expected_argcount, int opcode) { - _PyAdaptiveEntry *cache0 = &cache->adaptive; + assert(Py_IS_TYPE(o, &PyFunction_Type)); + PyFunctionObject *func = (PyFunctionObject *)o; + PyCodeObject *fcode = (PyCodeObject *)func->func_code; + int kind = function_kind(fcode); + if (kind != SIMPLE_FUNCTION) { + SPECIALIZATION_FAIL(opcode, kind); + return false; + } + if (fcode->co_argcount != expected_argcount) { + SPECIALIZATION_FAIL(opcode, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); + return false; + } + return true; +} + +/* Returning 0 indicates a failure. */ +static uint32_t +function_get_version(PyObject *o, int opcode) +{ + assert(Py_IS_TYPE(o, &PyFunction_Type)); + PyFunctionObject *func = (PyFunctionObject *)o; + uint32_t version = _PyFunction_GetVersionForCurrentState(func); + if (version == 0) { + SPECIALIZATION_FAIL(opcode, SPEC_FAIL_OUT_OF_VERSIONS); + return 0; + } + return version; +} + +void +_Py_Specialize_BinarySubscr( + PyObject *container, PyObject *sub, _Py_CODEUNIT *instr) +{ + assert(ENABLE_SPECIALIZATION); + assert(_PyOpcode_Caches[BINARY_SUBSCR] == + INLINE_CACHE_ENTRIES_BINARY_SUBSCR); + _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)(instr + 1); PyTypeObject *container_type = Py_TYPE(container); if (container_type == &PyList_Type) { if (PyLong_CheckExact(sub)) { - *instr = _Py_MAKECODEUNIT(BINARY_SUBSCR_LIST_INT, _Py_OPARG(*instr)); - goto success; + if (Py_SIZE(sub) == 0 || Py_SIZE(sub) == 1) { + _py_set_opcode(instr, BINARY_SUBSCR_LIST_INT); + goto success; + } + SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_RANGE); + goto fail; } SPECIALIZATION_FAIL(BINARY_SUBSCR, - PySlice_Check(sub) ? SPEC_FAIL_LIST_SLICE : SPEC_FAIL_OTHER); + PySlice_Check(sub) ? SPEC_FAIL_SUBSCR_LIST_SLICE : SPEC_FAIL_OTHER); goto fail; } if (container_type == &PyTuple_Type) { if (PyLong_CheckExact(sub)) { - *instr = _Py_MAKECODEUNIT(BINARY_SUBSCR_TUPLE_INT, _Py_OPARG(*instr)); - goto success; + if (Py_SIZE(sub) == 0 || Py_SIZE(sub) == 1) { + _py_set_opcode(instr, BINARY_SUBSCR_TUPLE_INT); + goto success; + } + SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_RANGE); + goto fail; } SPECIALIZATION_FAIL(BINARY_SUBSCR, - PySlice_Check(sub) ? SPEC_FAIL_TUPLE_SLICE : SPEC_FAIL_OTHER); + PySlice_Check(sub) ? SPEC_FAIL_SUBSCR_TUPLE_SLICE : SPEC_FAIL_OTHER); goto fail; } if (container_type == &PyDict_Type) { - *instr = _Py_MAKECODEUNIT(BINARY_SUBSCR_DICT, _Py_OPARG(*instr)); + _py_set_opcode(instr, BINARY_SUBSCR_DICT); goto success; } PyTypeObject *cls = Py_TYPE(container); - PyObject *descriptor = _PyType_LookupId(cls, &PyId___getitem__); + PyObject *descriptor = _PyType_Lookup(cls, &_Py_ID(__getitem__)); if (descriptor && Py_TYPE(descriptor) == &PyFunction_Type) { + if (!(container_type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_SUBSCR_NOT_HEAP_TYPE); + goto fail; + } PyFunctionObject *func = (PyFunctionObject *)descriptor; - PyCodeObject *code = (PyCodeObject *)func->func_code; - int kind = function_kind(code); + PyCodeObject *fcode = (PyCodeObject *)func->func_code; + int kind = function_kind(fcode); if (kind != SIMPLE_FUNCTION) { SPECIALIZATION_FAIL(BINARY_SUBSCR, kind); goto fail; } - if (code->co_argcount != 2) { + if (fcode->co_argcount != 2) { SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); goto fail; } assert(cls->tp_version_tag != 0); - cache0->version = cls->tp_version_tag; + write_u32(cache->type_version, cls->tp_version_tag); int version = _PyFunction_GetVersionForCurrentState(func); - if (version == 0) { - SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_VERSIONS); + if (version == 0 || version != (uint16_t)version) { + SPECIALIZATION_FAIL(BINARY_SUBSCR, version == 0 ? + SPEC_FAIL_OUT_OF_VERSIONS : SPEC_FAIL_OUT_OF_RANGE); goto fail; } - cache0->index = version; - cache[-1].obj.obj = descriptor; - *instr = _Py_MAKECODEUNIT(BINARY_SUBSCR_GETITEM, _Py_OPARG(*instr)); + cache->func_version = version; + ((PyHeapTypeObject *)container_type)->_spec_cache.getitem = descriptor; + _py_set_opcode(instr, BINARY_SUBSCR_GETITEM); goto success; } SPECIALIZATION_FAIL(BINARY_SUBSCR, binary_subscr_fail_kind(container_type, sub)); fail: - STAT_INC(BINARY_SUBSCR, specialization_failure); + STAT_INC(BINARY_SUBSCR, failure); assert(!PyErr_Occurred()); - cache_backoff(cache0); - return 0; + _py_set_opcode(instr, BINARY_SUBSCR); + cache->counter = adaptive_counter_backoff(cache->counter); + return; success: - STAT_INC(BINARY_SUBSCR, specialization_success); + STAT_INC(BINARY_SUBSCR, success); assert(!PyErr_Occurred()); - cache0->counter = initial_counter_value(); - return 0; + cache->counter = adaptive_counter_cooldown(); } -int +void _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *instr) { + assert(ENABLE_SPECIALIZATION); + _PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)(instr + 1); PyTypeObject *container_type = Py_TYPE(container); if (container_type == &PyList_Type) { if (PyLong_CheckExact(sub)) { if ((Py_SIZE(sub) == 0 || Py_SIZE(sub) == 1) - && ((PyLongObject *)sub)->ob_digit[0] < PyList_GET_SIZE(container)) + && ((PyLongObject *)sub)->ob_digit[0] < (size_t)PyList_GET_SIZE(container)) { - *instr = _Py_MAKECODEUNIT(STORE_SUBSCR_LIST_INT, - initial_counter_value()); + _py_set_opcode(instr, STORE_SUBSCR_LIST_INT); goto success; } else { @@ -1251,7 +1422,7 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins } } else if (PySlice_Check(sub)) { - SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_LIST_SLICE); + SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_SUBSCR_LIST_SLICE); goto fail; } else { @@ -1259,45 +1430,235 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins goto fail; } } - else if (container_type == &PyDict_Type) { - *instr = _Py_MAKECODEUNIT(STORE_SUBSCR_DICT, - initial_counter_value()); + if (container_type == &PyDict_Type) { + _py_set_opcode(instr, STORE_SUBSCR_DICT); goto success; } - else { - SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_OTHER); +#ifdef Py_STATS + PyMappingMethods *as_mapping = container_type->tp_as_mapping; + if (as_mapping && (as_mapping->mp_ass_subscript + == PyDict_Type.tp_as_mapping->mp_ass_subscript)) { + SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_SUBSCR_DICT_SUBCLASS_NO_OVERRIDE); goto fail; } + if (PyObject_CheckBuffer(container)) { + if (PyLong_CheckExact(sub) && (((size_t)Py_SIZE(sub)) > 1)) { + SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_OUT_OF_RANGE); + } + else if (strcmp(container_type->tp_name, "array.array") == 0) { + if (PyLong_CheckExact(sub)) { + SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_SUBSCR_ARRAY_INT); + } + else if (PySlice_Check(sub)) { + SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_SUBSCR_ARRAY_SLICE); + } + else { + SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_OTHER); + } + } + else if (PyByteArray_CheckExact(container)) { + if (PyLong_CheckExact(sub)) { + SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_SUBSCR_BYTEARRAY_INT); + } + else if (PySlice_Check(sub)) { + SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_SUBSCR_BYTEARRAY_SLICE); + } + else { + SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_OTHER); + } + } + else { + if (PyLong_CheckExact(sub)) { + SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_SUBSCR_BUFFER_INT); + } + else if (PySlice_Check(sub)) { + SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_SUBSCR_BUFFER_SLICE); + } + else { + SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_OTHER); + } + } + goto fail; + } + PyObject *descriptor = _PyType_Lookup(container_type, &_Py_ID(__setitem__)); + if (descriptor && Py_TYPE(descriptor) == &PyFunction_Type) { + PyFunctionObject *func = (PyFunctionObject *)descriptor; + PyCodeObject *code = (PyCodeObject *)func->func_code; + int kind = function_kind(code); + if (kind == SIMPLE_FUNCTION) { + SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_SUBSCR_PY_SIMPLE); + } + else { + SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_SUBSCR_PY_OTHER); + } + goto fail; + } +#endif + SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_OTHER); fail: - STAT_INC(STORE_SUBSCR, specialization_failure); + STAT_INC(STORE_SUBSCR, failure); assert(!PyErr_Occurred()); - *instr = _Py_MAKECODEUNIT(_Py_OPCODE(*instr), ADAPTIVE_CACHE_BACKOFF); - return 0; + _py_set_opcode(instr, STORE_SUBSCR); + cache->counter = adaptive_counter_backoff(cache->counter); + return; success: - STAT_INC(STORE_SUBSCR, specialization_success); + STAT_INC(STORE_SUBSCR, success); assert(!PyErr_Occurred()); - return 0; + cache->counter = adaptive_counter_cooldown(); } static int -specialize_class_call( - PyObject *callable, _Py_CODEUNIT *instr, - int nargs, SpecializedCacheEntry *cache) +specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, + PyObject *kwnames) { - SPECIALIZATION_FAIL(CALL_FUNCTION, SPEC_FAIL_CLASS); + PyTypeObject *tp = _PyType_CAST(callable); + if (tp->tp_new == PyBaseObject_Type.tp_new) { + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_PYTHON_CLASS); + return -1; + } + if (tp->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { + int oparg = _Py_OPARG(*instr); + if (nargs == 1 && kwnames == NULL && oparg == 1) { + if (tp == &PyUnicode_Type) { + _py_set_opcode(instr, CALL_NO_KW_STR_1); + return 0; + } + else if (tp == &PyType_Type) { + _py_set_opcode(instr, CALL_NO_KW_TYPE_1); + return 0; + } + else if (tp == &PyTuple_Type) { + _py_set_opcode(instr, CALL_NO_KW_TUPLE_1); + return 0; + } + } + if (tp->tp_vectorcall != NULL) { + _py_set_opcode(instr, CALL_BUILTIN_CLASS); + return 0; + } + SPECIALIZATION_FAIL(CALL, tp == &PyUnicode_Type ? + SPEC_FAIL_CALL_STR : SPEC_FAIL_CALL_CLASS_NO_VECTORCALL); + return -1; + } + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_CLASS_MUTABLE); + return -1; +} + +#ifdef Py_STATS +static int +builtin_call_fail_kind(int ml_flags) +{ + switch (ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | + METH_KEYWORDS | METH_METHOD)) { + case METH_VARARGS: + return SPEC_FAIL_CALL_CFUNC_VARARGS; + case METH_VARARGS | METH_KEYWORDS: + return SPEC_FAIL_CALL_CFUNC_VARARGS_KEYWORDS; + case METH_NOARGS: + return SPEC_FAIL_CALL_CFUNC_NOARGS; + case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + return SPEC_FAIL_CALL_CFUNC_METHOD_FASTCALL_KEYWORDS; + /* These cases should be optimized, but return "other" just in case */ + case METH_O: + case METH_FASTCALL: + case METH_FASTCALL | METH_KEYWORDS: + return SPEC_FAIL_OTHER; + default: + return SPEC_FAIL_CALL_BAD_CALL_FLAGS; + } +} + +static int +meth_descr_call_fail_kind(int ml_flags) +{ + switch (ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | + METH_KEYWORDS | METH_METHOD)) { + case METH_VARARGS: + return SPEC_FAIL_CALL_METH_DESCR_VARARGS; + case METH_VARARGS | METH_KEYWORDS: + return SPEC_FAIL_CALL_METH_DESCR_VARARGS_KEYWORDS; + case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + return SPEC_FAIL_CALL_METH_DESCR_METHOD_FASTCALL_KEYWORDS; + /* These cases should be optimized, but return "other" just in case */ + case METH_NOARGS: + case METH_O: + case METH_FASTCALL: + case METH_FASTCALL | METH_KEYWORDS: + return SPEC_FAIL_OTHER; + default: + return SPEC_FAIL_CALL_BAD_CALL_FLAGS; + } +} +#endif + +static int +specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr, + int nargs, PyObject *kwnames) +{ + if (kwnames) { + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES); + return -1; + } + + switch (descr->d_method->ml_flags & + (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | + METH_KEYWORDS | METH_METHOD)) { + case METH_NOARGS: { + if (nargs != 1) { + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); + return -1; + } + _py_set_opcode(instr, CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS); + return 0; + } + case METH_O: { + if (nargs != 2) { + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); + return -1; + } + PyInterpreterState *interp = _PyInterpreterState_GET(); + PyObject *list_append = interp->callable_cache.list_append; + _Py_CODEUNIT next = instr[INLINE_CACHE_ENTRIES_CALL + 1]; + bool pop = (_Py_OPCODE(next) == POP_TOP); + int oparg = _Py_OPARG(*instr); + if ((PyObject *)descr == list_append && oparg == 1 && pop) { + _py_set_opcode(instr, CALL_NO_KW_LIST_APPEND); + return 0; + } + _py_set_opcode(instr, CALL_NO_KW_METHOD_DESCRIPTOR_O); + return 0; + } + case METH_FASTCALL: { + _py_set_opcode(instr, CALL_NO_KW_METHOD_DESCRIPTOR_FAST); + return 0; + } + case METH_FASTCALL | METH_KEYWORDS: { + _py_set_opcode(instr, CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS); + return 0; + } + } + SPECIALIZATION_FAIL(CALL, meth_descr_call_fail_kind(descr->d_method->ml_flags)); return -1; } static int -specialize_py_call( - PyFunctionObject *func, _Py_CODEUNIT *instr, - int nargs, SpecializedCacheEntry *cache) +specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs, + PyObject *kwnames, bool bound_method) { - _PyCallCache *cache1 = &cache[-1].call; + _PyCallCache *cache = (_PyCallCache *)(instr + 1); PyCodeObject *code = (PyCodeObject *)func->func_code; int kind = function_kind(code); + /* Don't specialize if PEP 523 is active */ + if (_PyInterpreterState_GET()->eval_frame) { + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_PEP_523); + return -1; + } + if (kwnames) { + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES); + return -1; + } if (kind != SIMPLE_FUNCTION) { - SPECIALIZATION_FAIL(CALL_FUNCTION, kind); + SPECIALIZATION_FAIL(CALL, kind); return -1; } int argcount = code->co_argcount; @@ -1305,59 +1666,40 @@ specialize_py_call( assert(defcount <= argcount); int min_args = argcount-defcount; if (nargs > argcount || nargs < min_args) { - SPECIALIZATION_FAIL(CALL_FUNCTION, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); return -1; } assert(nargs <= argcount && nargs >= min_args); - int defstart = nargs - min_args; - int deflen = argcount - nargs; - assert(defstart >= 0 && deflen >= 0); - assert(deflen == 0 || func->func_defaults != NULL); - if (defstart > 0xffff || deflen > 0xffff) { - SPECIALIZATION_FAIL(CALL_FUNCTION, SPEC_FAIL_OUT_OF_RANGE); + assert(min_args >= 0 && defcount >= 0); + assert(defcount == 0 || func->func_defaults != NULL); + if (min_args > 0xffff) { + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_OUT_OF_RANGE); return -1; } int version = _PyFunction_GetVersionForCurrentState(func); if (version == 0) { - SPECIALIZATION_FAIL(CALL_FUNCTION, SPEC_FAIL_OUT_OF_VERSIONS); + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_OUT_OF_VERSIONS); return -1; } - cache1->func_version = version; - cache1->defaults_start = defstart; - cache1->defaults_len = deflen; - *instr = _Py_MAKECODEUNIT(CALL_FUNCTION_PY_SIMPLE, _Py_OPARG(*instr)); + write_u32(cache->func_version, version); + cache->min_args = min_args; + if (argcount == nargs) { + _py_set_opcode(instr, bound_method ? CALL_BOUND_METHOD_EXACT_ARGS : CALL_PY_EXACT_ARGS); + } + else if (bound_method) { + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_BOUND_METHOD); + return -1; + } + else { + _py_set_opcode(instr, CALL_PY_WITH_DEFAULTS); + } return 0; } -#if COLLECT_SPECIALIZATION_STATS_DETAILED -static int -builtin_call_fail_kind(int ml_flags) -{ - switch (ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | - METH_KEYWORDS | METH_METHOD)) { - case METH_VARARGS: - return SPEC_FAIL_PYCFUNCTION; - case METH_VARARGS | METH_KEYWORDS: - return SPEC_FAIL_PYCFUNCTION_WITH_KEYWORDS; - case METH_FASTCALL | METH_KEYWORDS: - return SPEC_FAIL_PYCFUNCTION_FAST_WITH_KEYWORDS; - case METH_NOARGS: - return SPEC_FAIL_PYCFUNCTION_NOARGS; - /* This case should never happen with PyCFunctionObject -- only - PyMethodObject. See zlib.compressobj()'s methods for an example. - */ - case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: - default: - return SPEC_FAIL_BAD_CALL_FLAGS; - } -} -#endif - static int specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, - SpecializedCacheEntry *cache, PyObject *builtins) + PyObject *kwnames) { - _PyObjectCache *cache1 = &cache[-1].obj; if (PyCFunction_GET_FUNCTION(callable) == NULL) { return 1; } @@ -1365,177 +1707,515 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { case METH_O: { + if (kwnames) { + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES); + return -1; + } if (nargs != 1) { - SPECIALIZATION_FAIL(CALL_FUNCTION, SPEC_FAIL_OUT_OF_RANGE); + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); return 1; } /* len(o) */ - PyObject *builtin_len = PyDict_GetItemString(builtins, "len"); - if (callable == builtin_len) { - cache1->obj = builtin_len; // borrowed - *instr = _Py_MAKECODEUNIT(CALL_FUNCTION_LEN, - _Py_OPARG(*instr)); + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (callable == interp->callable_cache.len) { + _py_set_opcode(instr, CALL_NO_KW_LEN); return 0; } - *instr = _Py_MAKECODEUNIT(CALL_FUNCTION_BUILTIN_O, - _Py_OPARG(*instr)); + _py_set_opcode(instr, CALL_NO_KW_BUILTIN_O); return 0; } case METH_FASTCALL: { + if (kwnames) { + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES); + return -1; + } if (nargs == 2) { /* isinstance(o1, o2) */ - PyObject *builtin_isinstance = PyDict_GetItemString( - builtins, "isinstance"); - if (callable == builtin_isinstance) { - cache1->obj = builtin_isinstance; // borrowed - *instr = _Py_MAKECODEUNIT(CALL_FUNCTION_ISINSTANCE, - _Py_OPARG(*instr)); + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (callable == interp->callable_cache.isinstance) { + _py_set_opcode(instr, CALL_NO_KW_ISINSTANCE); return 0; } } - *instr = _Py_MAKECODEUNIT(CALL_FUNCTION_BUILTIN_FAST, - _Py_OPARG(*instr)); + _py_set_opcode(instr, CALL_NO_KW_BUILTIN_FAST); + return 0; + } + case METH_FASTCALL | METH_KEYWORDS: { + _py_set_opcode(instr, CALL_BUILTIN_FAST_WITH_KEYWORDS); return 0; } default: - SPECIALIZATION_FAIL(CALL_FUNCTION, + SPECIALIZATION_FAIL(CALL, builtin_call_fail_kind(PyCFunction_GET_FLAGS(callable))); return 1; } } -#if COLLECT_SPECIALIZATION_STATS_DETAILED +#ifdef Py_STATS static int call_fail_kind(PyObject *callable) { + assert(!PyCFunction_CheckExact(callable)); + assert(!PyFunction_Check(callable)); + assert(!PyType_Check(callable)); + assert(!Py_IS_TYPE(callable, &PyMethodDescr_Type)); + assert(!PyMethod_Check(callable)); if (PyInstanceMethod_Check(callable)) { - return SPEC_FAIL_METHOD; - } - else if (PyMethod_Check(callable)) { - return SPEC_FAIL_METHOD; + return SPEC_FAIL_CALL_INSTANCE_METHOD; } // builtin method else if (PyCMethod_Check(callable)) { - return SPEC_FAIL_METHOD; + return SPEC_FAIL_CALL_CMETHOD; } - else if (PyType_Check(callable)) { - return SPEC_FAIL_CLASS; + else if (Py_TYPE(callable) == &PyWrapperDescr_Type) { + return SPEC_FAIL_CALL_OPERATOR_WRAPPER; + } + else if (Py_TYPE(callable) == &_PyMethodWrapper_Type) { + return SPEC_FAIL_CALL_METHOD_WRAPPER; } return SPEC_FAIL_OTHER; } #endif + /* TODO: - Specialize calling classes. */ -int -_Py_Specialize_CallFunction( - PyObject *callable, _Py_CODEUNIT *instr, - int nargs, SpecializedCacheEntry *cache, - PyObject *builtins) +void +_Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, + PyObject *kwnames) { + assert(ENABLE_SPECIALIZATION); + assert(_PyOpcode_Caches[CALL] == INLINE_CACHE_ENTRIES_CALL); + _PyCallCache *cache = (_PyCallCache *)(instr + 1); int fail; if (PyCFunction_CheckExact(callable)) { - fail = specialize_c_call(callable, instr, nargs, cache, builtins); + fail = specialize_c_call(callable, instr, nargs, kwnames); } else if (PyFunction_Check(callable)) { - fail = specialize_py_call((PyFunctionObject *)callable, instr, nargs, cache); + fail = specialize_py_call((PyFunctionObject *)callable, instr, nargs, + kwnames, false); } else if (PyType_Check(callable)) { - fail = specialize_class_call(callable, instr, nargs, cache); + fail = specialize_class_call(callable, instr, nargs, kwnames); + } + else if (Py_IS_TYPE(callable, &PyMethodDescr_Type)) { + fail = specialize_method_descriptor((PyMethodDescrObject *)callable, + instr, nargs, kwnames); + } + else if (PyMethod_Check(callable)) { + PyObject *func = ((PyMethodObject *)callable)->im_func; + if (PyFunction_Check(func)) { + fail = specialize_py_call((PyFunctionObject *)func, + instr, nargs+1, kwnames, true); + } else { + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_BOUND_METHOD); + fail = -1; + } } else { - SPECIALIZATION_FAIL(CALL_FUNCTION, call_fail_kind(callable)); + SPECIALIZATION_FAIL(CALL, call_fail_kind(callable)); fail = -1; } - _PyAdaptiveEntry *cache0 = &cache->adaptive; if (fail) { - STAT_INC(CALL_FUNCTION, specialization_failure); + STAT_INC(CALL, failure); assert(!PyErr_Occurred()); - cache_backoff(cache0); + _py_set_opcode(instr, CALL); + cache->counter = adaptive_counter_backoff(cache->counter); } else { - STAT_INC(CALL_FUNCTION, specialization_success); + STAT_INC(CALL, success); assert(!PyErr_Occurred()); - cache0->counter = initial_counter_value(); + cache->counter = adaptive_counter_cooldown(); } - return 0; } -void -_Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, - SpecializedCacheEntry *cache) +#ifdef Py_STATS +static int +binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs) { - _PyAdaptiveEntry *adaptive = &cache->adaptive; - switch (adaptive->original_oparg) { + switch (oparg) { case NB_ADD: case NB_INPLACE_ADD: if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) { - SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_DIFFERENT_TYPES); - goto failure; + return SPEC_FAIL_BINARY_OP_ADD_DIFFERENT_TYPES; + } + return SPEC_FAIL_BINARY_OP_ADD_OTHER; + case NB_AND: + case NB_INPLACE_AND: + if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) { + return SPEC_FAIL_BINARY_OP_AND_DIFFERENT_TYPES; + } + if (PyLong_CheckExact(lhs)) { + return SPEC_FAIL_BINARY_OP_AND_INT; + } + return SPEC_FAIL_BINARY_OP_AND_OTHER; + case NB_FLOOR_DIVIDE: + case NB_INPLACE_FLOOR_DIVIDE: + return SPEC_FAIL_BINARY_OP_FLOOR_DIVIDE; + case NB_LSHIFT: + case NB_INPLACE_LSHIFT: + return SPEC_FAIL_BINARY_OP_LSHIFT; + case NB_MATRIX_MULTIPLY: + case NB_INPLACE_MATRIX_MULTIPLY: + return SPEC_FAIL_BINARY_OP_MATRIX_MULTIPLY; + case NB_MULTIPLY: + case NB_INPLACE_MULTIPLY: + if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) { + return SPEC_FAIL_BINARY_OP_MULTIPLY_DIFFERENT_TYPES; + } + return SPEC_FAIL_BINARY_OP_MULTIPLY_OTHER; + case NB_OR: + case NB_INPLACE_OR: + return SPEC_FAIL_BINARY_OP_OR; + case NB_POWER: + case NB_INPLACE_POWER: + return SPEC_FAIL_BINARY_OP_POWER; + case NB_REMAINDER: + case NB_INPLACE_REMAINDER: + return SPEC_FAIL_BINARY_OP_REMAINDER; + case NB_RSHIFT: + case NB_INPLACE_RSHIFT: + return SPEC_FAIL_BINARY_OP_RSHIFT; + case NB_SUBTRACT: + case NB_INPLACE_SUBTRACT: + if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) { + return SPEC_FAIL_BINARY_OP_SUBTRACT_DIFFERENT_TYPES; + } + return SPEC_FAIL_BINARY_OP_SUBTRACT_OTHER; + case NB_TRUE_DIVIDE: + case NB_INPLACE_TRUE_DIVIDE: + if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) { + return SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_DIFFERENT_TYPES; + } + if (PyFloat_CheckExact(lhs)) { + return SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_FLOAT; + } + return SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_OTHER; + case NB_XOR: + case NB_INPLACE_XOR: + return SPEC_FAIL_BINARY_OP_XOR; + } + Py_UNREACHABLE(); +} +#endif + +void +_Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, + int oparg, PyObject **locals) +{ + assert(ENABLE_SPECIALIZATION); + assert(_PyOpcode_Caches[BINARY_OP] == INLINE_CACHE_ENTRIES_BINARY_OP); + _PyBinaryOpCache *cache = (_PyBinaryOpCache *)(instr + 1); + switch (oparg) { + case NB_ADD: + case NB_INPLACE_ADD: + if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) { + break; } if (PyUnicode_CheckExact(lhs)) { - if (_Py_OPCODE(instr[1]) == STORE_FAST && Py_REFCNT(lhs) == 2) { - *instr = _Py_MAKECODEUNIT(BINARY_OP_INPLACE_ADD_UNICODE, - _Py_OPARG(*instr)); + _Py_CODEUNIT next = instr[INLINE_CACHE_ENTRIES_BINARY_OP + 1]; + bool to_store = (_Py_OPCODE(next) == STORE_FAST || + _Py_OPCODE(next) == STORE_FAST__LOAD_FAST); + if (to_store && locals[_Py_OPARG(next)] == lhs) { + _py_set_opcode(instr, BINARY_OP_INPLACE_ADD_UNICODE); goto success; } - *instr = _Py_MAKECODEUNIT(BINARY_OP_ADD_UNICODE, - _Py_OPARG(*instr)); + _py_set_opcode(instr, BINARY_OP_ADD_UNICODE); goto success; } if (PyLong_CheckExact(lhs)) { - *instr = _Py_MAKECODEUNIT(BINARY_OP_ADD_INT, _Py_OPARG(*instr)); + _py_set_opcode(instr, BINARY_OP_ADD_INT); goto success; } if (PyFloat_CheckExact(lhs)) { - *instr = _Py_MAKECODEUNIT(BINARY_OP_ADD_FLOAT, - _Py_OPARG(*instr)); + _py_set_opcode(instr, BINARY_OP_ADD_FLOAT); goto success; } break; case NB_MULTIPLY: case NB_INPLACE_MULTIPLY: if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) { - SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_DIFFERENT_TYPES); - goto failure; + break; } if (PyLong_CheckExact(lhs)) { - *instr = _Py_MAKECODEUNIT(BINARY_OP_MULTIPLY_INT, - _Py_OPARG(*instr)); + _py_set_opcode(instr, BINARY_OP_MULTIPLY_INT); goto success; } if (PyFloat_CheckExact(lhs)) { - *instr = _Py_MAKECODEUNIT(BINARY_OP_MULTIPLY_FLOAT, - _Py_OPARG(*instr)); + _py_set_opcode(instr, BINARY_OP_MULTIPLY_FLOAT); goto success; } break; case NB_SUBTRACT: case NB_INPLACE_SUBTRACT: + if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) { + break; + } if (PyLong_CheckExact(lhs)) { - *instr = _Py_MAKECODEUNIT(BINARY_OP_SUBTRACT_INT, - _Py_OPARG(*instr)); + _py_set_opcode(instr, BINARY_OP_SUBTRACT_INT); goto success; } if (PyFloat_CheckExact(lhs)) { - *instr = _Py_MAKECODEUNIT(BINARY_OP_SUBTRACT_FLOAT, - _Py_OPARG(*instr)); + _py_set_opcode(instr, BINARY_OP_SUBTRACT_FLOAT); goto success; } break; - default: - // These operators don't have any available specializations. Rather - // than repeatedly attempting to specialize them, just convert them - // back to BINARY_OP (while still recording a failure, of course)! - *instr = _Py_MAKECODEUNIT(BINARY_OP, adaptive->original_oparg); } - SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_OTHER); -failure: - STAT_INC(BINARY_OP, specialization_failure); - cache_backoff(adaptive); + SPECIALIZATION_FAIL(BINARY_OP, binary_op_fail_kind(oparg, lhs, rhs)); + STAT_INC(BINARY_OP, failure); + _py_set_opcode(instr, BINARY_OP); + cache->counter = adaptive_counter_backoff(cache->counter); return; success: - STAT_INC(BINARY_OP, specialization_success); - adaptive->counter = initial_counter_value(); + STAT_INC(BINARY_OP, success); + cache->counter = adaptive_counter_cooldown(); +} + + +#ifdef Py_STATS +static int +compare_op_fail_kind(PyObject *lhs, PyObject *rhs) +{ + if (Py_TYPE(lhs) != Py_TYPE(rhs)) { + if (PyFloat_CheckExact(lhs) && PyLong_CheckExact(rhs)) { + return SPEC_FAIL_COMPARE_FLOAT_LONG; + } + if (PyLong_CheckExact(lhs) && PyFloat_CheckExact(rhs)) { + return SPEC_FAIL_COMPARE_LONG_FLOAT; + } + return SPEC_FAIL_COMPARE_DIFFERENT_TYPES; + } + if (PyBytes_CheckExact(lhs)) { + return SPEC_FAIL_COMPARE_BYTES; + } + if (PyTuple_CheckExact(lhs)) { + return SPEC_FAIL_COMPARE_TUPLE; + } + if (PyList_CheckExact(lhs)) { + return SPEC_FAIL_COMPARE_LIST; + } + if (PySet_CheckExact(lhs) || PyFrozenSet_CheckExact(lhs)) { + return SPEC_FAIL_COMPARE_SET; + } + if (PyBool_Check(lhs)) { + return SPEC_FAIL_COMPARE_BOOL; + } + if (Py_TYPE(lhs)->tp_richcompare == PyBaseObject_Type.tp_richcompare) { + return SPEC_FAIL_COMPARE_BASEOBJECT; + } + return SPEC_FAIL_OTHER; +} +#endif + +void +_Py_Specialize_CompareAndBranch(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, + int oparg) +{ + assert(ENABLE_SPECIALIZATION); + assert(_PyOpcode_Caches[COMPARE_AND_BRANCH] == INLINE_CACHE_ENTRIES_COMPARE_OP); + _PyCompareOpCache *cache = (_PyCompareOpCache *)(instr + 1); +#ifndef NDEBUG + int next_opcode = _Py_OPCODE(instr[INLINE_CACHE_ENTRIES_COMPARE_OP + 1]); + assert(next_opcode == POP_JUMP_IF_FALSE || next_opcode == POP_JUMP_IF_TRUE); +#endif + if (Py_TYPE(lhs) != Py_TYPE(rhs)) { + SPECIALIZATION_FAIL(COMPARE_AND_BRANCH, compare_op_fail_kind(lhs, rhs)); + goto failure; + } + if (PyFloat_CheckExact(lhs)) { + _py_set_opcode(instr, COMPARE_AND_BRANCH_FLOAT); + goto success; + } + if (PyLong_CheckExact(lhs)) { + if (Py_ABS(Py_SIZE(lhs)) <= 1 && Py_ABS(Py_SIZE(rhs)) <= 1) { + _py_set_opcode(instr, COMPARE_AND_BRANCH_INT); + goto success; + } + else { + SPECIALIZATION_FAIL(COMPARE_AND_BRANCH, SPEC_FAIL_COMPARE_BIG_INT); + goto failure; + } + } + if (PyUnicode_CheckExact(lhs)) { + int cmp = oparg >> 4; + if (cmp != Py_EQ && cmp != Py_NE) { + SPECIALIZATION_FAIL(COMPARE_AND_BRANCH, SPEC_FAIL_COMPARE_STRING); + goto failure; + } + else { + _py_set_opcode(instr, COMPARE_AND_BRANCH_STR); + goto success; + } + } + SPECIALIZATION_FAIL(COMPARE_AND_BRANCH, compare_op_fail_kind(lhs, rhs)); +failure: + STAT_INC(COMPARE_AND_BRANCH, failure); + _py_set_opcode(instr, COMPARE_AND_BRANCH); + cache->counter = adaptive_counter_backoff(cache->counter); + return; +success: + STAT_INC(COMPARE_AND_BRANCH, success); + cache->counter = adaptive_counter_cooldown(); +} + +#ifdef Py_STATS +static int +unpack_sequence_fail_kind(PyObject *seq) +{ + if (PySequence_Check(seq)) { + return SPEC_FAIL_UNPACK_SEQUENCE_SEQUENCE; + } + if (PyIter_Check(seq)) { + return SPEC_FAIL_UNPACK_SEQUENCE_ITERATOR; + } + return SPEC_FAIL_OTHER; +} +#endif + +void +_Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg) +{ + assert(ENABLE_SPECIALIZATION); + assert(_PyOpcode_Caches[UNPACK_SEQUENCE] == + INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); + _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)(instr + 1); + if (PyTuple_CheckExact(seq)) { + if (PyTuple_GET_SIZE(seq) != oparg) { + SPECIALIZATION_FAIL(UNPACK_SEQUENCE, SPEC_FAIL_EXPECTED_ERROR); + goto failure; + } + if (PyTuple_GET_SIZE(seq) == 2) { + _py_set_opcode(instr, UNPACK_SEQUENCE_TWO_TUPLE); + goto success; + } + _py_set_opcode(instr, UNPACK_SEQUENCE_TUPLE); + goto success; + } + if (PyList_CheckExact(seq)) { + if (PyList_GET_SIZE(seq) != oparg) { + SPECIALIZATION_FAIL(UNPACK_SEQUENCE, SPEC_FAIL_EXPECTED_ERROR); + goto failure; + } + _py_set_opcode(instr, UNPACK_SEQUENCE_LIST); + goto success; + } + SPECIALIZATION_FAIL(UNPACK_SEQUENCE, unpack_sequence_fail_kind(seq)); +failure: + STAT_INC(UNPACK_SEQUENCE, failure); + _py_set_opcode(instr, UNPACK_SEQUENCE); + cache->counter = adaptive_counter_backoff(cache->counter); + return; +success: + STAT_INC(UNPACK_SEQUENCE, success); + cache->counter = adaptive_counter_cooldown(); +} + +#ifdef Py_STATS + +int + _PySpecialization_ClassifyIterator(PyObject *iter) +{ + if (PyGen_CheckExact(iter)) { + return SPEC_FAIL_FOR_ITER_GENERATOR; + } + if (PyCoro_CheckExact(iter)) { + return SPEC_FAIL_FOR_ITER_COROUTINE; + } + if (PyAsyncGen_CheckExact(iter)) { + return SPEC_FAIL_FOR_ITER_ASYNC_GENERATOR; + } + PyTypeObject *t = Py_TYPE(iter); + if (t == &PyListIter_Type) { + return SPEC_FAIL_FOR_ITER_LIST; + } + if (t == &PyTupleIter_Type) { + return SPEC_FAIL_FOR_ITER_TUPLE; + } + if (t == &PyDictIterKey_Type) { + return SPEC_FAIL_FOR_ITER_DICT_KEYS; + } + if (t == &PyDictIterValue_Type) { + return SPEC_FAIL_FOR_ITER_DICT_VALUES; + } + if (t == &PyDictIterItem_Type) { + return SPEC_FAIL_FOR_ITER_DICT_ITEMS; + } + if (t == &PySetIter_Type) { + return SPEC_FAIL_FOR_ITER_SET; + } + if (t == &PyUnicodeIter_Type) { + return SPEC_FAIL_FOR_ITER_STRING; + } + if (t == &PyBytesIter_Type) { + return SPEC_FAIL_FOR_ITER_BYTES; + } + if (t == &PyRangeIter_Type) { + return SPEC_FAIL_FOR_ITER_RANGE; + } + if (t == &PyEnum_Type) { + return SPEC_FAIL_FOR_ITER_ENUMERATE; + } + if (t == &PyMap_Type) { + return SPEC_FAIL_FOR_ITER_MAP; + } + if (t == &PyZip_Type) { + return SPEC_FAIL_FOR_ITER_ZIP; + } + if (t == &PySeqIter_Type) { + return SPEC_FAIL_FOR_ITER_SEQ_ITER; + } + if (t == &PyListRevIter_Type) { + return SPEC_FAIL_FOR_ITER_REVERSED_LIST; + } + if (t == &_PyUnicodeASCIIIter_Type) { + return SPEC_FAIL_FOR_ITER_ASCII_STRING; + } + const char *name = t->tp_name; + if (strncmp(name, "itertools", 9) == 0) { + return SPEC_FAIL_FOR_ITER_ITERTOOLS; + } + if (strncmp(name, "callable_iterator", 17) == 0) { + return SPEC_FAIL_FOR_ITER_CALLABLE; + } + return SPEC_FAIL_OTHER; +} + +#endif + +void +_Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr, int oparg) +{ + assert(ENABLE_SPECIALIZATION); + assert(_PyOpcode_Caches[FOR_ITER] == INLINE_CACHE_ENTRIES_FOR_ITER); + _PyForIterCache *cache = (_PyForIterCache *)(instr + 1); + PyTypeObject *tp = Py_TYPE(iter); + _Py_CODEUNIT next = instr[1+INLINE_CACHE_ENTRIES_FOR_ITER]; + int next_op = _PyOpcode_Deopt[_Py_OPCODE(next)]; + if (tp == &PyListIter_Type) { + _py_set_opcode(instr, FOR_ITER_LIST); + goto success; + } + else if (tp == &PyTupleIter_Type) { + _py_set_opcode(instr, FOR_ITER_TUPLE); + goto success; + } + else if (tp == &PyRangeIter_Type && next_op == STORE_FAST) { + _py_set_opcode(instr, FOR_ITER_RANGE); + goto success; + } + else if (tp == &PyGen_Type && oparg <= SHRT_MAX) { + assert(_Py_OPCODE(instr[oparg + INLINE_CACHE_ENTRIES_FOR_ITER + 1]) == END_FOR); + _py_set_opcode(instr, FOR_ITER_GEN); + goto success; + } + SPECIALIZATION_FAIL(FOR_ITER, + _PySpecialization_ClassifyIterator(iter)); + STAT_INC(FOR_ITER, failure); + _py_set_opcode(instr, FOR_ITER); + cache->counter = adaptive_counter_backoff(cache->counter); + return; +success: + STAT_INC(FOR_ITER, success); + cache->counter = adaptive_counter_cooldown(); } diff --git a/Python/stdlib_module_names.h b/Python/stdlib_module_names.h index 7d421081b2a..4e7dfb14d19 100644 --- a/Python/stdlib_module_names.h +++ b/Python/stdlib_module_names.h @@ -1,4 +1,4 @@ -// Auto-generated by Tools/scripts/generate_stdlib_module_names.py. +// Auto-generated by Tools/build/generate_stdlib_module_names.py. // List used to create sys.stdlib_module_names. static const char* _Py_stdlib_module_names[] = { @@ -9,7 +9,6 @@ static const char* _Py_stdlib_module_names[] = { "_asyncio", "_bisect", "_blake2", -"_bootsubprocess", "_bz2", "_codecs", "_codecs_cn", @@ -59,6 +58,7 @@ static const char* _Py_stdlib_module_names[] = { "_py_abc", "_pydecimal", "_pyio", +"_pylong", "_queue", "_random", "_scproxy", @@ -134,7 +134,6 @@ static const char* _Py_stdlib_module_names[] = { "decimal", "difflib", "dis", -"distutils", "doctest", "email", "encodings", @@ -274,6 +273,7 @@ static const char* _Py_stdlib_module_names[] = { "tkinter", "token", "tokenize", +"tomllib", "trace", "traceback", "tracemalloc", diff --git a/Python/structmember.c b/Python/structmember.c index c7e318811d8..1b8be28dcf2 100644 --- a/Python/structmember.c +++ b/Python/structmember.c @@ -49,8 +49,7 @@ PyMember_GetOne(const char *obj_addr, PyMemberDef *l) break; case T_STRING: if (*(char**)addr == NULL) { - Py_INCREF(Py_None); - v = Py_None; + v = Py_NewRef(Py_None); } else v = PyUnicode_FromString(*(char**)addr); @@ -75,7 +74,7 @@ PyMember_GetOne(const char *obj_addr, PyMemberDef *l) PyErr_Format(PyExc_AttributeError, "'%.200s' object has no attribute '%s'", tp->tp_name, l->name); - } + } Py_XINCREF(v); break; case T_LONGLONG: @@ -85,8 +84,7 @@ PyMember_GetOne(const char *obj_addr, PyMemberDef *l) v = PyLong_FromUnsignedLongLong(*(unsigned long long *)addr); break; case T_NONE: - v = Py_None; - Py_INCREF(v); + v = Py_NewRef(Py_None); break; default: PyErr_SetString(PyExc_SystemError, "bad memberdescr type"); @@ -247,9 +245,8 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) break; case T_OBJECT: case T_OBJECT_EX: - Py_XINCREF(v); oldv = *(PyObject **)addr; - *(PyObject **)addr = v; + *(PyObject **)addr = Py_XNewRef(v); Py_XDECREF(oldv); break; case T_CHAR: { diff --git a/Python/suggestions.c b/Python/suggestions.c index d9e69fa7e0d..f2c018ef2c4 100644 --- a/Python/suggestions.c +++ b/Python/suggestions.c @@ -1,9 +1,11 @@ #include "Python.h" -#include "frameobject.h" #include "pycore_frame.h" +#include "pycore_runtime.h" // _PyRuntime +#include "pycore_global_objects.h" // _Py_ID() #include "pycore_pyerrors.h" #include "pycore_code.h" // _PyCode_GetVarnames() +#include "stdlib_module_names.h" // _Py_stdlib_module_names #define MAX_CANDIDATE_ITEMS 750 #define MAX_STRING_SIZE 40 @@ -39,10 +41,8 @@ substitution_cost(char a, char b) static Py_ssize_t levenshtein_distance(const char *a, size_t a_size, const char *b, size_t b_size, - size_t max_cost) + size_t max_cost, size_t *buffer) { - static size_t buffer[MAX_STRING_SIZE]; - // Both strings are the same (by identity) if (a == b) { return 0; @@ -78,9 +78,11 @@ levenshtein_distance(const char *a, size_t a_size, // Instead of producing the whole traditional len(a)-by-len(b) // matrix, we can update just one row in place. // Initialize the buffer row + size_t tmp = MOVE_COST; for (size_t i = 0; i < a_size; i++) { // cost from b[:0] to a[:i+1] - buffer[i] = (i + 1) * MOVE_COST; + buffer[i] = tmp; + tmp += MOVE_COST; } size_t result = 0; @@ -143,12 +145,16 @@ calculate_suggestions(PyObject *dir, if (name_str == NULL) { return NULL; } - + size_t *buffer = PyMem_New(size_t, MAX_STRING_SIZE); + if (buffer == NULL) { + return PyErr_NoMemory(); + } for (int i = 0; i < dir_size; ++i) { PyObject *item = PyList_GET_ITEM(dir, i); Py_ssize_t item_size; const char *item_str = PyUnicode_AsUTF8AndSize(item, &item_size); if (item_str == NULL) { + PyMem_Free(buffer); return NULL; } if (PyUnicode_CompareWithASCIIString(name, item_str) == 0) { @@ -159,8 +165,8 @@ calculate_suggestions(PyObject *dir, // Don't take matches we've already beaten. max_distance = Py_MIN(max_distance, suggestion_distance - 1); Py_ssize_t current_distance = - levenshtein_distance(name_str, name_size, - item_str, item_size, max_distance); + levenshtein_distance(name_str, name_size, item_str, + item_size, max_distance, buffer); if (current_distance > max_distance) { continue; } @@ -169,12 +175,12 @@ calculate_suggestions(PyObject *dir, suggestion_distance = current_distance; } } - Py_XINCREF(suggestion); - return suggestion; + PyMem_Free(buffer); + return Py_XNewRef(suggestion); } static PyObject * -offer_suggestions_for_attribute_error(PyAttributeErrorObject *exc) +get_suggestions_for_attribute_error(PyAttributeErrorObject *exc) { PyObject *name = exc->name; // borrowed reference PyObject *obj = exc->obj; // borrowed reference @@ -194,6 +200,96 @@ offer_suggestions_for_attribute_error(PyAttributeErrorObject *exc) return suggestions; } +static PyObject * +offer_suggestions_for_attribute_error(PyAttributeErrorObject *exc) +{ + PyObject* suggestion = get_suggestions_for_attribute_error(exc); + if (suggestion == NULL) { + return NULL; + } + // Add a trailer ". Did you mean: (...)?" + PyObject* result = PyUnicode_FromFormat(". Did you mean: %R?", suggestion); + Py_DECREF(suggestion); + return result; +} + +static PyObject * +get_suggestions_for_name_error(PyObject* name, PyFrameObject* frame) +{ + PyCodeObject *code = PyFrame_GetCode(frame); + assert(code != NULL && code->co_localsplusnames != NULL); + + PyObject *varnames = _PyCode_GetVarnames(code); + if (varnames == NULL) { + return NULL; + } + PyObject *dir = PySequence_List(varnames); + Py_DECREF(varnames); + Py_DECREF(code); + if (dir == NULL) { + return NULL; + } + + // Are we inside a method and the instance has an attribute called 'name'? + if (PySequence_Contains(dir, &_Py_ID(self)) > 0) { + PyObject* locals = PyFrame_GetLocals(frame); + if (!locals) { + goto error; + } + PyObject* self = PyDict_GetItem(locals, &_Py_ID(self)); /* borrowed */ + Py_DECREF(locals); + if (!self) { + goto error; + } + + if (PyObject_HasAttr(self, name)) { + Py_DECREF(dir); + return PyUnicode_FromFormat("self.%S", name); + } + } + + PyObject *suggestions = calculate_suggestions(dir, name); + Py_DECREF(dir); + if (suggestions != NULL) { + return suggestions; + } + + dir = PySequence_List(frame->f_frame->f_globals); + if (dir == NULL) { + return NULL; + } + suggestions = calculate_suggestions(dir, name); + Py_DECREF(dir); + if (suggestions != NULL) { + return suggestions; + } + + dir = PySequence_List(frame->f_frame->f_builtins); + if (dir == NULL) { + return NULL; + } + suggestions = calculate_suggestions(dir, name); + Py_DECREF(dir); + + return suggestions; + +error: + Py_DECREF(dir); + return NULL; +} + +static bool +is_name_stdlib_module(PyObject* name) +{ + const char* the_name = PyUnicode_AsUTF8(name); + Py_ssize_t len = Py_ARRAY_LENGTH(_Py_stdlib_module_names); + for (Py_ssize_t i = 0; i < len; i++) { + if (strcmp(the_name, _Py_stdlib_module_names[i]) == 0) { + return 1; + } + } + return 0; +} static PyObject * offer_suggestions_for_name_error(PyNameErrorObject *exc) @@ -221,43 +317,57 @@ offer_suggestions_for_name_error(PyNameErrorObject *exc) PyFrameObject *frame = traceback->tb_frame; assert(frame != NULL); - PyCodeObject *code = PyFrame_GetCode(frame); - assert(code != NULL && code->co_localsplusnames != NULL); - PyObject *varnames = _PyCode_GetVarnames(code); - if (varnames == NULL) { + + PyObject* suggestion = get_suggestions_for_name_error(name, frame); + bool is_stdlib_module = is_name_stdlib_module(name); + + if (suggestion == NULL && !is_stdlib_module) { return NULL; } - PyObject *dir = PySequence_List(varnames); - Py_DECREF(varnames); - Py_DECREF(code); + + // Add a trailer ". Did you mean: (...)?" + PyObject* result = NULL; + if (!is_stdlib_module) { + result = PyUnicode_FromFormat(". Did you mean: %R?", suggestion); + } else if (suggestion == NULL) { + result = PyUnicode_FromFormat(". Did you forget to import %R?", name); + } else { + result = PyUnicode_FromFormat(". Did you mean: %R? Or did you forget to import %R?", suggestion, name); + } + Py_XDECREF(suggestion); + return result; +} + +static PyObject * +offer_suggestions_for_import_error(PyImportErrorObject *exc) +{ + PyObject *mod_name = exc->name; // borrowed reference + PyObject *name = exc->name_from; // borrowed reference + if (name == NULL || mod_name == NULL || name == Py_None || + !PyUnicode_CheckExact(name) || !PyUnicode_CheckExact(mod_name)) { + return NULL; + } + + PyObject* mod = PyImport_GetModule(mod_name); + if (mod == NULL) { + return NULL; + } + + PyObject *dir = PyObject_Dir(mod); + Py_DECREF(mod); if (dir == NULL) { return NULL; } - PyObject *suggestions = calculate_suggestions(dir, name); + PyObject *suggestion = calculate_suggestions(dir, name); Py_DECREF(dir); - if (suggestions != NULL) { - return suggestions; - } - - dir = PySequence_List(frame->f_frame->f_globals); - if (dir == NULL) { + if (!suggestion) { return NULL; } - suggestions = calculate_suggestions(dir, name); - Py_DECREF(dir); - if (suggestions != NULL) { - return suggestions; - } - dir = PySequence_List(frame->f_frame->f_builtins); - if (dir == NULL) { - return NULL; - } - suggestions = calculate_suggestions(dir, name); - Py_DECREF(dir); - - return suggestions; + PyObject* result = PyUnicode_FromFormat(". Did you mean: %R?", suggestion); + Py_DECREF(suggestion); + return result; } // Offer suggestions for a given exception. Returns a python string object containing the @@ -272,6 +382,8 @@ _Py_Offer_Suggestions(PyObject *exception) result = offer_suggestions_for_attribute_error((PyAttributeErrorObject *) exception); } else if (Py_IS_TYPE(exception, (PyTypeObject*)PyExc_NameError)) { result = offer_suggestions_for_name_error((PyNameErrorObject *) exception); + } else if (Py_IS_TYPE(exception, (PyTypeObject*)PyExc_ImportError)) { + result = offer_suggestions_for_import_error((PyImportErrorObject *) exception); } return result; } @@ -292,6 +404,14 @@ _Py_UTF8_Edit_Cost(PyObject *a, PyObject *b, Py_ssize_t max_cost) if (max_cost == -1) { max_cost = MOVE_COST * Py_MAX(size_a, size_b); } - return levenshtein_distance(utf8_a, size_a, utf8_b, size_b, max_cost); + size_t *buffer = PyMem_New(size_t, MAX_STRING_SIZE); + if (buffer == NULL) { + PyErr_NoMemory(); + return -1; + } + Py_ssize_t res = levenshtein_distance(utf8_a, size_a, + utf8_b, size_b, max_cost, buffer); + PyMem_Free(buffer); + return res; } diff --git a/Python/symtable.c b/Python/symtable.c index dc5426cf3b4..89a2bc437df 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -49,6 +49,12 @@ "'%s' can not be used within an annotation" +#define LOCATION(x) \ + (x)->lineno, (x)->col_offset, (x)->end_lineno, (x)->end_col_offset + +#define ST_LOCATION(x) \ + (x)->ste_lineno, (x)->ste_col_offset, (x)->ste_end_lineno, (x)->ste_end_col_offset + static PySTEntryObject * ste_new(struct symtable *st, identifier name, _Py_block_ty block, void *key, int lineno, int col_offset, @@ -68,8 +74,7 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block, ste->ste_table = st; ste->ste_id = k; /* ste owns reference to k */ - Py_INCREF(name); - ste->ste_name = name; + ste->ste_name = Py_NewRef(name); ste->ste_symbols = NULL; ste->ste_varnames = NULL; @@ -96,7 +101,7 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block, ste->ste_child_free = 0; ste->ste_generator = 0; ste->ste_coroutine = 0; - ste->ste_comprehension = 0; + ste->ste_comprehension = NoComprehension; ste->ste_returns_value = 0; ste->ste_needs_class_closure = 0; ste->ste_comp_iter_target = 0; @@ -221,15 +226,9 @@ static int symtable_visit_withitem(struct symtable *st, withitem_ty item); static int symtable_visit_match_case(struct symtable *st, match_case_ty m); static int symtable_visit_pattern(struct symtable *st, pattern_ty s); static int symtable_raise_if_annotation_block(struct symtable *st, const char *, expr_ty); +static int symtable_raise_if_comprehension_block(struct symtable *st, expr_ty); -static identifier top = NULL, lambda = NULL, genexpr = NULL, - listcomp = NULL, setcomp = NULL, dictcomp = NULL, - __class__ = NULL, _annotation = NULL; - -#define GET_IDENTIFIER(VAR) \ - ((VAR) ? (VAR) : ((VAR) = PyUnicode_InternFromString(# VAR))) - #define DUPLICATE_ARGUMENT \ "duplicate argument '%U' in function definition" @@ -278,7 +277,6 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future) asdl_stmt_seq *seq; int i; PyThreadState *tstate; - int recursion_limit = Py_GetRecursionLimit(); int starting_recursion_depth; if (st == NULL) @@ -287,8 +285,7 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future) _PySymtable_Free(st); return NULL; } - Py_INCREF(filename); - st->st_filename = filename; + st->st_filename = Py_NewRef(filename); st->st_future = future; /* Setup recursion depth check counters */ @@ -298,16 +295,13 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future) return NULL; } /* Be careful here to prevent overflow. */ - int recursion_depth = tstate->recursion_limit - tstate->recursion_remaining; - starting_recursion_depth = (recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_depth * COMPILER_STACK_FRAME_SCALE : recursion_depth; + int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining; + starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE; st->recursion_depth = starting_recursion_depth; - st->recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit; + st->recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; /* Make the initial symbol information gathering pass */ - if (!GET_IDENTIFIER(top) || - !symtable_enter_block(st, top, ModuleBlock, (void *)mod, 0, 0, 0, 0)) { + if (!symtable_enter_block(st, &_Py_ID(top), ModuleBlock, (void *)mod, 0, 0, 0, 0)) { _PySymtable_Free(st); return NULL; } @@ -379,17 +373,17 @@ PySymtable_Lookup(struct symtable *st, void *key) if (k == NULL) return NULL; v = PyDict_GetItemWithError(st->st_blocks, k); + Py_DECREF(k); + if (v) { assert(PySTEntry_Check(v)); - Py_INCREF(v); } else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_KeyError, "unknown symbol table entry"); } - Py_DECREF(k); - return (PySTEntryObject *)v; + return (PySTEntryObject *)Py_XNewRef(v); } long @@ -612,9 +606,7 @@ static int drop_class_free(PySTEntryObject *ste, PyObject *free) { int res; - if (!GET_IDENTIFIER(__class__)) - return 0; - res = PySet_Discard(free, __class__); + res = PySet_Discard(free, &_Py_ID(__class__)); if (res < 0) return 0; if (res) @@ -827,9 +819,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, } else { /* Special-case __class__ */ - if (!GET_IDENTIFIER(__class__)) - goto error; - if (PySet_Add(newbound, __class__) < 0) + if (PySet_Add(newbound, &_Py_ID(__class__)) < 0) goto error; } @@ -1025,7 +1015,8 @@ symtable_lookup(struct symtable *st, PyObject *name) } static int -symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _symtable_entry *ste) +symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _symtable_entry *ste, + int lineno, int col_offset, int end_lineno, int end_col_offset) { PyObject *o; PyObject *dict; @@ -1042,10 +1033,8 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s /* Is it better to use 'mangled' or 'name' here? */ PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT, name); PyErr_RangedSyntaxLocationObject(st->st_filename, - ste->ste_lineno, - ste->ste_col_offset + 1, - ste->ste_end_lineno, - ste->ste_end_col_offset + 1); + lineno, col_offset + 1, + end_lineno, end_col_offset + 1); goto error; } val |= flag; @@ -1066,10 +1055,8 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_INNER_LOOP_CONFLICT, name); PyErr_RangedSyntaxLocationObject(st->st_filename, - ste->ste_lineno, - ste->ste_col_offset + 1, - ste->ste_end_lineno, - ste->ste_end_col_offset + 1); + lineno, col_offset + 1, + end_lineno, end_col_offset + 1); goto error; } val |= DEF_COMP_ITER; @@ -1114,8 +1101,11 @@ error: } static int -symtable_add_def(struct symtable *st, PyObject *name, int flag) { - return symtable_add_def_helper(st, name, flag, st->st_cur); +symtable_add_def(struct symtable *st, PyObject *name, int flag, + int lineno, int col_offset, int end_lineno, int end_col_offset) +{ + return symtable_add_def_helper(st, name, flag, st->st_cur, + lineno, col_offset, end_lineno, end_col_offset); } /* VISIT, VISIT_SEQ and VIST_SEQ_TAIL take an ASDL type as their second argument. @@ -1200,7 +1190,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) } switch (s->kind) { case FunctionDef_kind: - if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL)) + if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL, LOCATION(s))) VISIT_QUIT(st, 0); if (s->v.FunctionDef.args->defaults) VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults); @@ -1213,8 +1203,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_SEQ(st, expr, s->v.FunctionDef.decorator_list); if (!symtable_enter_block(st, s->v.FunctionDef.name, FunctionBlock, (void *)s, - s->lineno, s->col_offset, - s->end_lineno, s->end_col_offset)) + LOCATION(s))) VISIT_QUIT(st, 0); VISIT(st, arguments, s->v.FunctionDef.args); VISIT_SEQ(st, stmt, s->v.FunctionDef.body); @@ -1223,7 +1212,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) break; case ClassDef_kind: { PyObject *tmp; - if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL)) + if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL, LOCATION(s))) VISIT_QUIT(st, 0); VISIT_SEQ(st, expr, s->v.ClassDef.bases); VISIT_SEQ(st, keyword, s->v.ClassDef.keywords); @@ -1276,12 +1265,12 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) } if (s->v.AnnAssign.simple && !symtable_add_def(st, e_name->v.Name.id, - DEF_ANNOT | DEF_LOCAL)) { + DEF_ANNOT | DEF_LOCAL, LOCATION(e_name))) { VISIT_QUIT(st, 0); } else { if (s->v.AnnAssign.value - && !symtable_add_def(st, e_name->v.Name.id, DEF_LOCAL)) { + && !symtable_add_def(st, e_name->v.Name.id, DEF_LOCAL, LOCATION(e_name))) { VISIT_QUIT(st, 0); } } @@ -1339,6 +1328,12 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_SEQ(st, excepthandler, s->v.Try.handlers); VISIT_SEQ(st, stmt, s->v.Try.finalbody); break; + case TryStar_kind: + VISIT_SEQ(st, stmt, s->v.TryStar.body); + VISIT_SEQ(st, stmt, s->v.TryStar.orelse); + VISIT_SEQ(st, excepthandler, s->v.TryStar.handlers); + VISIT_SEQ(st, stmt, s->v.TryStar.finalbody); + break; case Assert_kind: VISIT(st, expr, s->v.Assert.test); if (s->v.Assert.msg) @@ -1378,7 +1373,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) s->end_col_offset + 1); VISIT_QUIT(st, 0); } - if (!symtable_add_def(st, name, DEF_GLOBAL)) + if (!symtable_add_def(st, name, DEF_GLOBAL, LOCATION(s))) VISIT_QUIT(st, 0); if (!symtable_record_directive(st, name, s->lineno, s->col_offset, s->end_lineno, s->end_col_offset)) @@ -1413,7 +1408,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) s->end_col_offset + 1); VISIT_QUIT(st, 0); } - if (!symtable_add_def(st, name, DEF_NONLOCAL)) + if (!symtable_add_def(st, name, DEF_NONLOCAL, LOCATION(s))) VISIT_QUIT(st, 0); if (!symtable_record_directive(st, name, s->lineno, s->col_offset, s->end_lineno, s->end_col_offset)) @@ -1434,7 +1429,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_SEQ(st, stmt, s->v.With.body); break; case AsyncFunctionDef_kind: - if (!symtable_add_def(st, s->v.AsyncFunctionDef.name, DEF_LOCAL)) + if (!symtable_add_def(st, s->v.AsyncFunctionDef.name, DEF_LOCAL, LOCATION(s))) VISIT_QUIT(st, 0); if (s->v.AsyncFunctionDef.args->defaults) VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.args->defaults); @@ -1493,7 +1488,8 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) */ if (ste->ste_comprehension) { long target_in_scope = _PyST_GetSymbol(ste, target_name); - if (target_in_scope & DEF_COMP_ITER) { + if ((target_in_scope & DEF_COMP_ITER) && + (target_in_scope & DEF_LOCAL)) { PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_CONFLICT, target_name); PyErr_RangedSyntaxLocationObject(st->st_filename, e->lineno, @@ -1509,27 +1505,25 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) if (ste->ste_type == FunctionBlock) { long target_in_scope = _PyST_GetSymbol(ste, target_name); if (target_in_scope & DEF_GLOBAL) { - if (!symtable_add_def(st, target_name, DEF_GLOBAL)) + if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e))) VISIT_QUIT(st, 0); } else { - if (!symtable_add_def(st, target_name, DEF_NONLOCAL)) + if (!symtable_add_def(st, target_name, DEF_NONLOCAL, LOCATION(e))) VISIT_QUIT(st, 0); } - if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset, - e->end_lineno, e->end_col_offset)) + if (!symtable_record_directive(st, target_name, LOCATION(e))) VISIT_QUIT(st, 0); - return symtable_add_def_helper(st, target_name, DEF_LOCAL, ste); + return symtable_add_def_helper(st, target_name, DEF_LOCAL, ste, LOCATION(e)); } /* If we find a ModuleBlock entry, add as GLOBAL */ if (ste->ste_type == ModuleBlock) { - if (!symtable_add_def(st, target_name, DEF_GLOBAL)) + if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e))) VISIT_QUIT(st, 0); - if (!symtable_record_directive(st, target_name, e->lineno, e->col_offset, - e->end_lineno, e->end_col_offset)) + if (!symtable_record_directive(st, target_name, LOCATION(e))) VISIT_QUIT(st, 0); - return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste); + return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste, LOCATION(e)); } /* Disallow usage in ClassBlock */ if (ste->ste_type == ClassBlock) { @@ -1546,7 +1540,7 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) /* We should always find either a FunctionBlock, ModuleBlock or ClassBlock and should never fall to this case */ - assert(0); + Py_UNREACHABLE(); return 0; } @@ -1600,13 +1594,11 @@ symtable_visit_expr(struct symtable *st, expr_ty e) VISIT(st, expr, e->v.UnaryOp.operand); break; case Lambda_kind: { - if (!GET_IDENTIFIER(lambda)) - VISIT_QUIT(st, 0); if (e->v.Lambda.args->defaults) VISIT_SEQ(st, expr, e->v.Lambda.args->defaults); if (e->v.Lambda.args->kw_defaults) VISIT_SEQ_WITH_NULL(st, expr, e->v.Lambda.args->kw_defaults); - if (!symtable_enter_block(st, lambda, + if (!symtable_enter_block(st, &_Py_ID(lambda), FunctionBlock, (void *)e, e->lineno, e->col_offset, e->end_lineno, e->end_col_offset)) @@ -1652,6 +1644,9 @@ symtable_visit_expr(struct symtable *st, expr_ty e) if (e->v.Yield.value) VISIT(st, expr, e->v.Yield.value); st->st_cur->ste_generator = 1; + if (st->st_cur->ste_comprehension) { + return symtable_raise_if_comprehension_block(st, e); + } break; case YieldFrom_kind: if (!symtable_raise_if_annotation_block(st, "yield expression", e)) { @@ -1659,6 +1654,9 @@ symtable_visit_expr(struct symtable *st, expr_ty e) } VISIT(st, expr, e->v.YieldFrom.value); st->st_cur->ste_generator = 1; + if (st->st_cur->ste_comprehension) { + return symtable_raise_if_comprehension_block(st, e); + } break; case Await_kind: if (!symtable_raise_if_annotation_block(st, "await expression", e)) { @@ -1708,14 +1706,13 @@ symtable_visit_expr(struct symtable *st, expr_ty e) break; case Name_kind: if (!symtable_add_def(st, e->v.Name.id, - e->v.Name.ctx == Load ? USE : DEF_LOCAL)) + e->v.Name.ctx == Load ? USE : DEF_LOCAL, LOCATION(e))) VISIT_QUIT(st, 0); /* Special-case super: it counts as a use of __class__ */ if (e->v.Name.ctx == Load && st->st_cur->ste_type == FunctionBlock && _PyUnicode_EqualToASCIIString(e->v.Name.id, "super")) { - if (!GET_IDENTIFIER(__class__) || - !symtable_add_def(st, __class__, USE)) + if (!symtable_add_def(st, &_Py_ID(__class__), USE, LOCATION(e))) VISIT_QUIT(st, 0); } break; @@ -1750,14 +1747,14 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p) break; case MatchStar_kind: if (p->v.MatchStar.name) { - symtable_add_def(st, p->v.MatchStar.name, DEF_LOCAL); + symtable_add_def(st, p->v.MatchStar.name, DEF_LOCAL, LOCATION(p)); } break; case MatchMapping_kind: VISIT_SEQ(st, expr, p->v.MatchMapping.keys); VISIT_SEQ(st, pattern, p->v.MatchMapping.patterns); if (p->v.MatchMapping.rest) { - symtable_add_def(st, p->v.MatchMapping.rest, DEF_LOCAL); + symtable_add_def(st, p->v.MatchMapping.rest, DEF_LOCAL, LOCATION(p)); } break; case MatchClass_kind: @@ -1770,7 +1767,7 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p) VISIT(st, pattern, p->v.MatchAs.pattern); } if (p->v.MatchAs.name) { - symtable_add_def(st, p->v.MatchAs.name, DEF_LOCAL); + symtable_add_def(st, p->v.MatchAs.name, DEF_LOCAL, LOCATION(p)); } break; case MatchOr_kind: @@ -1786,7 +1783,7 @@ symtable_implicit_arg(struct symtable *st, int pos) PyObject *id = PyUnicode_FromFormat(".%d", pos); if (id == NULL) return 0; - if (!symtable_add_def(st, id, DEF_PARAM)) { + if (!symtable_add_def(st, id, DEF_PARAM, ST_LOCATION(st->st_cur))) { Py_DECREF(id); return 0; } @@ -1804,7 +1801,7 @@ symtable_visit_params(struct symtable *st, asdl_arg_seq *args) for (i = 0; i < asdl_seq_LEN(args); i++) { arg_ty arg = (arg_ty)asdl_seq_GET(args, i); - if (!symtable_add_def(st, arg->arg, DEF_PARAM)) + if (!symtable_add_def(st, arg->arg, DEF_PARAM, LOCATION(arg))) return 0; } @@ -1816,7 +1813,7 @@ symtable_visit_annotation(struct symtable *st, expr_ty annotation) { int future_annotations = st->st_future->ff_features & CO_FUTURE_ANNOTATIONS; if (future_annotations && - !symtable_enter_block(st, GET_IDENTIFIER(_annotation), AnnotationBlock, + !symtable_enter_block(st, &_Py_ID(_annotation), AnnotationBlock, (void *)annotation, annotation->lineno, annotation->col_offset, annotation->end_lineno, annotation->end_col_offset)) { @@ -1851,7 +1848,7 @@ symtable_visit_annotations(struct symtable *st, stmt_ty o, arguments_ty a, expr_ { int future_annotations = st->st_future->ff_features & CO_FUTURE_ANNOTATIONS; if (future_annotations && - !symtable_enter_block(st, GET_IDENTIFIER(_annotation), AnnotationBlock, + !symtable_enter_block(st, &_Py_ID(_annotation), AnnotationBlock, (void *)o, o->lineno, o->col_offset, o->end_lineno, o->end_col_offset)) { VISIT_QUIT(st, 0); @@ -1888,12 +1885,12 @@ symtable_visit_arguments(struct symtable *st, arguments_ty a) if (a->kwonlyargs && !symtable_visit_params(st, a->kwonlyargs)) return 0; if (a->vararg) { - if (!symtable_add_def(st, a->vararg->arg, DEF_PARAM)) + if (!symtable_add_def(st, a->vararg->arg, DEF_PARAM, LOCATION(a->vararg))) return 0; st->st_cur->ste_varargs = 1; } if (a->kwarg) { - if (!symtable_add_def(st, a->kwarg->arg, DEF_PARAM)) + if (!symtable_add_def(st, a->kwarg->arg, DEF_PARAM, LOCATION(a->kwarg))) return 0; st->st_cur->ste_varkeywords = 1; } @@ -1907,7 +1904,7 @@ symtable_visit_excepthandler(struct symtable *st, excepthandler_ty eh) if (eh->v.ExceptHandler.type) VISIT(st, expr, eh->v.ExceptHandler.type); if (eh->v.ExceptHandler.name) - if (!symtable_add_def(st, eh->v.ExceptHandler.name, DEF_LOCAL)) + if (!symtable_add_def(st, eh->v.ExceptHandler.name, DEF_LOCAL, LOCATION(eh))) return 0; VISIT_SEQ(st, stmt, eh->v.ExceptHandler.body); return 1; @@ -1951,20 +1948,19 @@ symtable_visit_alias(struct symtable *st, alias_ty a) return 0; } else { - store_name = name; - Py_INCREF(store_name); + store_name = Py_NewRef(name); } if (!_PyUnicode_EqualToASCIIString(name, "*")) { - int r = symtable_add_def(st, store_name, DEF_IMPORT); + int r = symtable_add_def(st, store_name, DEF_IMPORT, LOCATION(a)); Py_DECREF(store_name); return r; } else { if (st->st_cur->ste_type != ModuleBlock) { - int lineno = st->st_cur->ste_lineno; - int col_offset = st->st_cur->ste_col_offset; - int end_lineno = st->st_cur->ste_end_lineno; - int end_col_offset = st->st_cur->ste_end_col_offset; + int lineno = a->lineno; + int col_offset = a->col_offset; + int end_lineno = a->end_lineno; + int end_col_offset = a->end_col_offset; PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING); PyErr_RangedSyntaxLocationObject(st->st_filename, lineno, col_offset + 1, @@ -2022,10 +2018,23 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e, e->end_lineno, e->end_col_offset)) { return 0; } + switch(e->kind) { + case ListComp_kind: + st->st_cur->ste_comprehension = ListComprehension; + break; + case SetComp_kind: + st->st_cur->ste_comprehension = SetComprehension; + break; + case DictComp_kind: + st->st_cur->ste_comprehension = DictComprehension; + break; + default: + st->st_cur->ste_comprehension = GeneratorExpression; + break; + } if (outermost->is_async) { st->st_cur->ste_coroutine = 1; } - st->st_cur->ste_comprehension = 1; /* Outermost iter is received as an argument */ if (!symtable_implicit_arg(st, 0)) { @@ -2042,20 +2051,6 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e, if (value) VISIT(st, expr, value); VISIT(st, expr, elt); - if (st->st_cur->ste_generator) { - PyErr_SetString(PyExc_SyntaxError, - (e->kind == ListComp_kind) ? "'yield' inside list comprehension" : - (e->kind == SetComp_kind) ? "'yield' inside set comprehension" : - (e->kind == DictComp_kind) ? "'yield' inside dict comprehension" : - "'yield' inside generator expression"); - PyErr_RangedSyntaxLocationObject(st->st_filename, - st->st_cur->ste_lineno, - st->st_cur->ste_col_offset + 1, - st->st_cur->ste_end_lineno, - st->st_cur->ste_end_col_offset + 1); - symtable_exit_block(st); - return 0; - } st->st_cur->ste_generator = is_generator; int is_async = st->st_cur->ste_coroutine && !is_generator; if (!symtable_exit_block(st)) { @@ -2070,7 +2065,7 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e, static int symtable_visit_genexp(struct symtable *st, expr_ty e) { - return symtable_handle_comprehension(st, e, GET_IDENTIFIER(genexpr), + return symtable_handle_comprehension(st, e, &_Py_ID(genexpr), e->v.GeneratorExp.generators, e->v.GeneratorExp.elt, NULL); } @@ -2078,7 +2073,7 @@ symtable_visit_genexp(struct symtable *st, expr_ty e) static int symtable_visit_listcomp(struct symtable *st, expr_ty e) { - return symtable_handle_comprehension(st, e, GET_IDENTIFIER(listcomp), + return symtable_handle_comprehension(st, e, &_Py_ID(listcomp), e->v.ListComp.generators, e->v.ListComp.elt, NULL); } @@ -2086,7 +2081,7 @@ symtable_visit_listcomp(struct symtable *st, expr_ty e) static int symtable_visit_setcomp(struct symtable *st, expr_ty e) { - return symtable_handle_comprehension(st, e, GET_IDENTIFIER(setcomp), + return symtable_handle_comprehension(st, e, &_Py_ID(setcomp), e->v.SetComp.generators, e->v.SetComp.elt, NULL); } @@ -2094,7 +2089,7 @@ symtable_visit_setcomp(struct symtable *st, expr_ty e) static int symtable_visit_dictcomp(struct symtable *st, expr_ty e) { - return symtable_handle_comprehension(st, e, GET_IDENTIFIER(dictcomp), + return symtable_handle_comprehension(st, e, &_Py_ID(dictcomp), e->v.DictComp.generators, e->v.DictComp.key, e->v.DictComp.value); @@ -2116,6 +2111,20 @@ symtable_raise_if_annotation_block(struct symtable *st, const char *name, expr_t return 0; } +static int +symtable_raise_if_comprehension_block(struct symtable *st, expr_ty e) { + _Py_comprehension_ty type = st->st_cur->ste_comprehension; + PyErr_SetString(PyExc_SyntaxError, + (type == ListComprehension) ? "'yield' inside list comprehension" : + (type == SetComprehension) ? "'yield' inside set comprehension" : + (type == DictComprehension) ? "'yield' inside dict comprehension" : + "'yield' inside generator expression"); + PyErr_RangedSyntaxLocationObject(st->st_filename, + e->lineno, e->col_offset + 1, + e->end_lineno, e->end_col_offset + 1); + VISIT_QUIT(st, 0); +} + struct symtable * _Py_SymtableStringObjectFlags(const char *str, PyObject *filename, int start, PyCompilerFlags *flags) @@ -2133,14 +2142,13 @@ _Py_SymtableStringObjectFlags(const char *str, PyObject *filename, _PyArena_Free(arena); return NULL; } - PyFutureFeatures *future = _PyFuture_FromAST(mod, filename); - if (future == NULL) { + PyFutureFeatures future; + if (!_PyFuture_FromAST(mod, filename, &future)) { _PyArena_Free(arena); return NULL; } - future->ff_features |= flags->cf_flags; - st = _PySymtable_Build(mod, filename, future); - PyObject_Free((void *)future); + future.ff_features |= flags->cf_flags; + st = _PySymtable_Build(mod, filename, &future); _PyArena_Free(arena); return st; } diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 3e2091e70ab..f9f766a94d1 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -16,22 +16,22 @@ Data members: #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() -#include "pycore_ceval.h" // _Py_RecursionLimitLowerWaterMark() -#include "pycore_code.h" // _Py_QuickenedCount -#include "pycore_frame.h" // InterpreterFrame +#include "pycore_ceval.h" // _PyEval_SetAsyncGenFinalizer() +#include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_initconfig.h" // _PyStatus_EXCEPTION() +#include "pycore_long.h" // _PY_LONG_MAX_STR_DIGITS_THRESHOLD #include "pycore_namespace.h" // _PyNamespace_New() #include "pycore_object.h" // _PyObject_IS_GC() #include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0() #include "pycore_pyerrors.h" // _PyErr_Fetch() #include "pycore_pylifecycle.h" // _PyErr_WriteUnraisableDefaultHook() +#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() #include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_structseq.h" // PyStructSequence_InitType() +#include "pycore_structseq.h" // _PyStructSequence_InitBuiltinWithFlags() #include "pycore_tuple.h" // _PyTuple_FromArray() -#include "code.h" -#include "frameobject.h" // PyFrame_GetBack() +#include "frameobject.h" // PyFrame_FastToLocalsWithError() #include "pydtrace.h" #include "osdefs.h" // DELIM #include "stdlib_module_names.h" // _Py_stdlib_module_names @@ -48,6 +48,10 @@ extern void *PyWin_DLLhModule; extern const char *PyWin_DLLVersionString; #endif +#ifdef __EMSCRIPTEN__ +#include +#endif + /*[clinic input] module sys [clinic start generated code]*/ @@ -55,20 +59,8 @@ module sys #include "clinic/sysmodule.c.h" -_Py_IDENTIFIER(_); -_Py_IDENTIFIER(__sizeof__); -_Py_IDENTIFIER(_xoptions); -_Py_IDENTIFIER(buffer); -_Py_IDENTIFIER(builtins); -_Py_IDENTIFIER(encoding); -_Py_IDENTIFIER(path); -_Py_IDENTIFIER(stdout); -_Py_IDENTIFIER(stderr); -_Py_IDENTIFIER(warnoptions); -_Py_IDENTIFIER(write); - -static PyObject * -sys_get_object_id(PyThreadState *tstate, _Py_Identifier *key) +PyObject * +_PySys_GetAttr(PyThreadState *tstate, PyObject *name) { PyObject *sd = tstate->interp->sysdict; if (sd == NULL) { @@ -76,20 +68,13 @@ sys_get_object_id(PyThreadState *tstate, _Py_Identifier *key) } PyObject *exc_type, *exc_value, *exc_tb; _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); - PyObject *value = _PyDict_GetItemIdWithError(sd, key); /* XXX Suppress a new exception if it was raised and restore * the old one. */ + PyObject *value = _PyDict_GetItemWithError(sd, name); _PyErr_Restore(tstate, exc_type, exc_value, exc_tb); return value; } -PyObject * -_PySys_GetObjectId(_Py_Identifier *key) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return sys_get_object_id(tstate, key); -} - static PyObject * _PySys_GetObject(PyInterpreterState *interp, const char *name) { @@ -134,17 +119,11 @@ sys_set_object(PyInterpreterState *interp, PyObject *key, PyObject *v) } } -static int -sys_set_object_id(PyInterpreterState *interp, _Py_Identifier *key, PyObject *v) -{ - return sys_set_object(interp, _PyUnicode_FromId(key), v); -} - int -_PySys_SetObjectId(_Py_Identifier *key, PyObject *v) +_PySys_SetAttr(PyObject *key, PyObject *v) { PyInterpreterState *interp = _PyInterpreterState_GET(); - return sys_set_object_id(interp, key, v); + return sys_set_object(interp, key, v); } static int @@ -219,8 +198,7 @@ sys_audit_tstate(PyThreadState *ts, const char *event, eventArgs = _Py_VaBuildValue_SizeT(argFormat, vargs); if (eventArgs && !PyTuple_Check(eventArgs)) { PyObject *argTuple = PyTuple_Pack(1, eventArgs); - Py_DECREF(eventArgs); - eventArgs = argTuple; + Py_SETREF(eventArgs, argTuple); } } else { @@ -258,9 +236,8 @@ sys_audit_tstate(PyThreadState *ts, const char *event, /* Disallow tracing in hooks unless explicitly enabled */ PyThreadState_EnterTracing(ts); while ((hook = PyIter_Next(hooks)) != NULL) { - _Py_IDENTIFIER(__cantrace__); PyObject *o; - int canTrace = _PyObject_LookupAttrId(hook, &PyId___cantrace__, &o); + int canTrace = _PyObject_LookupAttr(hook, &_Py_ID(__cantrace__), &o); if (o) { canTrace = PyObject_IsTrue(o); Py_DECREF(o); @@ -314,11 +291,7 @@ _PySys_Audit(PyThreadState *tstate, const char *event, const char *argFormat, ...) { va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, argFormat); -#else - va_start(vargs); -#endif int res = sys_audit_tstate(tstate, event, argFormat, vargs); va_end(vargs); return res; @@ -329,11 +302,7 @@ PySys_Audit(const char *event, const char *argFormat, ...) { PyThreadState *tstate = _PyThreadState_GET(); va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, argFormat); -#else - va_start(vargs); -#endif int res = sys_audit_tstate(tstate, event, argFormat, vargs); va_end(vargs); return res; @@ -461,6 +430,8 @@ sys_addaudithook_impl(PyObject *module, PyObject *hook) if (interp->audit_hooks == NULL) { return NULL; } + /* Avoid having our list of hooks show up in the GC module */ + PyObject_GC_UnTrack(interp->audit_hooks); } if (PyList_Append(interp->audit_hooks, hook) < 0) { @@ -631,7 +602,7 @@ sys_displayhook_unencodable(PyObject *outf, PyObject *o) const char *stdout_encoding_str; int ret; - stdout_encoding = _PyObject_GetAttrId(outf, &PyId_encoding); + stdout_encoding = PyObject_GetAttr(outf, &_Py_ID(encoding)); if (stdout_encoding == NULL) goto error; stdout_encoding_str = PyUnicode_AsUTF8(stdout_encoding); @@ -648,12 +619,12 @@ sys_displayhook_unencodable(PyObject *outf, PyObject *o) if (encoded == NULL) goto error; - if (_PyObject_LookupAttrId(outf, &PyId_buffer, &buffer) < 0) { + if (_PyObject_LookupAttr(outf, &_Py_ID(buffer), &buffer) < 0) { Py_DECREF(encoded); goto error; } if (buffer) { - result = _PyObject_CallMethodIdOneArg(buffer, &PyId_write, encoded); + result = PyObject_CallMethodOneArg(buffer, &_Py_ID(write), encoded); Py_DECREF(buffer); Py_DECREF(encoded); if (result == NULL) @@ -696,10 +667,9 @@ sys_displayhook(PyObject *module, PyObject *o) { PyObject *outf; PyObject *builtins; - static PyObject *newline = NULL; PyThreadState *tstate = _PyThreadState_GET(); - builtins = _PyImport_GetModuleId(&PyId_builtins); + builtins = PyImport_GetModule(&_Py_ID(builtins)); if (builtins == NULL) { if (!_PyErr_Occurred(tstate)) { _PyErr_SetString(tstate, PyExc_RuntimeError, @@ -715,9 +685,9 @@ sys_displayhook(PyObject *module, PyObject *o) if (o == Py_None) { Py_RETURN_NONE; } - if (_PyObject_SetAttrId(builtins, &PyId__, Py_None) != 0) + if (PyObject_SetAttr(builtins, &_Py_ID(_), Py_None) != 0) return NULL; - outf = sys_get_object_id(tstate, &PyId_stdout); + outf = _PySys_GetAttr(tstate, &_Py_ID(stdout)); if (outf == NULL || outf == Py_None) { _PyErr_SetString(tstate, PyExc_RuntimeError, "lost sys.stdout"); return NULL; @@ -737,14 +707,10 @@ sys_displayhook(PyObject *module, PyObject *o) return NULL; } } - if (newline == NULL) { - newline = PyUnicode_FromString("\n"); - if (newline == NULL) - return NULL; - } - if (PyFile_WriteObject(newline, outf, Py_PRINT_RAW) != 0) + _Py_DECLARE_STR(newline, "\n"); + if (PyFile_WriteObject(&_Py_STR(newline), outf, Py_PRINT_RAW) != 0) return NULL; - if (_PyObject_SetAttrId(builtins, &PyId__, o) != 0) + if (PyObject_SetAttr(builtins, &_Py_ID(_), o) != 0) return NULL; Py_RETURN_NONE; } @@ -771,6 +737,28 @@ sys_excepthook_impl(PyObject *module, PyObject *exctype, PyObject *value, } +/*[clinic input] +sys.exception + +Return the current exception. + +Return the most recent exception caught by an except clause +in the current stack frame or in an older stack frame, or None +if no such exception exists. +[clinic start generated code]*/ + +static PyObject * +sys_exception_impl(PyObject *module) +/*[clinic end generated code: output=2381ee2f25953e40 input=c88fbb94b6287431]*/ +{ + _PyErr_StackItem *err_info = _PyErr_GetTopmostException(_PyThreadState_GET()); + if (err_info->exc_value != NULL) { + return Py_NewRef(err_info->exc_value); + } + Py_RETURN_NONE; +} + + /*[clinic input] sys.exc_info @@ -785,12 +773,7 @@ sys_exc_info_impl(PyObject *module) /*[clinic end generated code: output=3afd0940cf3a4d30 input=b5c5bf077788a3e5]*/ { _PyErr_StackItem *err_info = _PyErr_GetTopmostException(_PyThreadState_GET()); - return Py_BuildValue( - "(OOO)", - err_info->exc_type != NULL ? err_info->exc_type : Py_None, - err_info->exc_value != NULL ? err_info->exc_value : Py_None, - err_info->exc_traceback != NULL ? - err_info->exc_traceback : Py_None); + return _PyErr_StackItemToExcInfoTuple(err_info); } @@ -854,7 +837,9 @@ static PyObject * sys_getdefaultencoding_impl(PyObject *module) /*[clinic end generated code: output=256d19dfcc0711e6 input=d416856ddbef6909]*/ { - return PyUnicode_FromString(PyUnicode_GetDefaultEncoding()); + _Py_DECLARE_STR(utf_8, "utf-8"); + PyObject *ret = &_Py_STR(utf_8); + return Py_NewRef(ret); } /*[clinic input] @@ -919,45 +904,37 @@ sys_intern_impl(PyObject *module, PyObject *s) /* * Cached interned string objects used for calling the profile and - * trace functions. Initialized by trace_init(). + * trace functions. */ -static PyObject *whatstrings[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; - -static int -trace_init(void) -{ - static const char * const whatnames[8] = { - "call", "exception", "line", "return", - "c_call", "c_exception", "c_return", - "opcode" - }; - PyObject *name; - int i; - for (i = 0; i < 8; ++i) { - if (whatstrings[i] == NULL) { - name = PyUnicode_InternFromString(whatnames[i]); - if (name == NULL) - return -1; - whatstrings[i] = name; - } - } - return 0; -} +static PyObject *whatstrings[8] = { + &_Py_ID(call), + &_Py_ID(exception), + &_Py_ID(line), + &_Py_ID(return), + &_Py_ID(c_call), + &_Py_ID(c_exception), + &_Py_ID(c_return), + &_Py_ID(opcode), +}; static PyObject * call_trampoline(PyThreadState *tstate, PyObject* callback, PyFrameObject *frame, int what, PyObject *arg) { - if (PyFrame_FastToLocalsWithError(frame) < 0) { - return NULL; - } PyObject *stack[3]; stack[0] = (PyObject *)frame; stack[1] = whatstrings[what]; stack[2] = (arg != NULL) ? arg : Py_None; + /* Discard any previous modifications the frame's fast locals */ + if (frame->f_fast_as_locals) { + if (PyFrame_FastToLocalsWithError(frame) < 0) { + return NULL; + } + } + /* call the Python-level function */ PyObject *result = _PyObject_FastCallTstate(tstate, callback, stack, 3); @@ -973,10 +950,6 @@ static int profile_trampoline(PyObject *self, PyFrameObject *frame, int what, PyObject *arg) { - if (arg == NULL) { - arg = Py_None; - } - PyThreadState *tstate = _PyThreadState_GET(); PyObject *result = call_trampoline(tstate, self, frame, what, arg); if (result == NULL) { @@ -1023,10 +996,6 @@ trace_trampoline(PyObject *self, PyFrameObject *frame, static PyObject * sys_settrace(PyObject *self, PyObject *args) { - if (trace_init() == -1) { - return NULL; - } - PyThreadState *tstate = _PyThreadState_GET(); if (args == Py_None) { if (_PyEval_SetTrace(tstate, NULL, NULL) < 0) { @@ -1048,6 +1017,36 @@ Set the global debug tracing function. It will be called on each\n\ function call. See the debugger chapter in the library manual." ); +/*[clinic input] +sys._settraceallthreads + + arg: object + / + +Set the global debug tracing function in all running threads belonging to the current interpreter. + +It will be called on each function call. See the debugger chapter +in the library manual. +[clinic start generated code]*/ + +static PyObject * +sys__settraceallthreads(PyObject *module, PyObject *arg) +/*[clinic end generated code: output=161cca30207bf3ca input=5906aa1485a50289]*/ +{ + PyObject* argument = NULL; + Py_tracefunc func = NULL; + + if (arg != Py_None) { + func = trace_trampoline; + argument = arg; + } + + + PyEval_SetTraceAllThreads(func, argument); + + Py_RETURN_NONE; +} + /*[clinic input] sys.gettrace @@ -1065,17 +1064,12 @@ sys_gettrace_impl(PyObject *module) if (temp == NULL) temp = Py_None; - Py_INCREF(temp); - return temp; + return Py_NewRef(temp); } static PyObject * sys_setprofile(PyObject *self, PyObject *args) { - if (trace_init() == -1) { - return NULL; - } - PyThreadState *tstate = _PyThreadState_GET(); if (args == Py_None) { if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) { @@ -1097,6 +1091,35 @@ Set the profiling function. It will be called on each function call\n\ and return. See the profiler chapter in the library manual." ); +/*[clinic input] +sys._setprofileallthreads + + arg: object + / + +Set the profiling function in all running threads belonging to the current interpreter. + +It will be called on each function call and return. See the profiler chapter +in the library manual. +[clinic start generated code]*/ + +static PyObject * +sys__setprofileallthreads(PyObject *module, PyObject *arg) +/*[clinic end generated code: output=2d61319e27b309fe input=d1a356d3f4f9060a]*/ +{ + PyObject* argument = NULL; + Py_tracefunc func = NULL; + + if (arg != Py_None) { + func = profile_trampoline; + argument = arg; + } + + PyEval_SetProfileAllThreads(func, argument); + + Py_RETURN_NONE; +} + /*[clinic input] sys.getprofile @@ -1114,8 +1137,7 @@ sys_getprofile_impl(PyObject *module) if (temp == NULL) temp = Py_None; - Py_INCREF(temp); - return temp; + return Py_NewRef(temp); } @@ -1189,7 +1211,7 @@ sys_setrecursionlimit_impl(PyObject *module, int new_limit) /* Reject too low new limit if the current recursion depth is higher than the new low-water mark. */ - int depth = tstate->recursion_limit - tstate->recursion_remaining; + int depth = tstate->py_recursion_limit - tstate->py_recursion_remaining; if (depth >= new_limit) { _PyErr_Format(tstate, PyExc_RecursionError, "cannot set the recursion limit to %i at " @@ -1219,12 +1241,9 @@ static PyObject * sys_set_coroutine_origin_tracking_depth_impl(PyObject *module, int depth) /*[clinic end generated code: output=0a2123c1cc6759c5 input=a1d0a05f89d2c426]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - if (depth < 0) { - _PyErr_SetString(tstate, PyExc_ValueError, "depth must be >= 0"); + if (_PyEval_SetCoroutineOriginTrackingDepth(depth) < 0) { return NULL; } - _PyEval_SetCoroutineOriginTrackingDepth(tstate, depth); Py_RETURN_NONE; } @@ -1343,11 +1362,8 @@ sys_get_asyncgen_hooks_impl(PyObject *module) finalizer = Py_None; } - Py_INCREF(firstiter); - PyStructSequence_SET_ITEM(res, 0, firstiter); - - Py_INCREF(finalizer); - PyStructSequence_SET_ITEM(res, 1, finalizer); + PyStructSequence_SET_ITEM(res, 0, Py_NewRef(firstiter)); + PyStructSequence_SET_ITEM(res, 1, Py_NewRef(finalizer)); return res; } @@ -1461,6 +1477,44 @@ static PyStructSequence_Desc windows_version_desc = { via indexing, the rest are name only */ }; +static PyObject * +_sys_getwindowsversion_from_kernel32() +{ + HANDLE hKernel32; + wchar_t kernel32_path[MAX_PATH]; + LPVOID verblock; + DWORD verblock_size; + VS_FIXEDFILEINFO *ffi; + UINT ffi_len; + DWORD realMajor, realMinor, realBuild; + + Py_BEGIN_ALLOW_THREADS + hKernel32 = GetModuleHandleW(L"kernel32.dll"); + Py_END_ALLOW_THREADS + if (!hKernel32 || !GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH)) { + PyErr_SetFromWindowsErr(0); + return NULL; + } + verblock_size = GetFileVersionInfoSizeW(kernel32_path, NULL); + if (!verblock_size) { + PyErr_SetFromWindowsErr(0); + return NULL; + } + verblock = PyMem_RawMalloc(verblock_size); + if (!verblock || + !GetFileVersionInfoW(kernel32_path, 0, verblock_size, verblock) || + !VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) { + PyErr_SetFromWindowsErr(0); + return NULL; + } + + realMajor = HIWORD(ffi->dwProductVersionMS); + realMinor = LOWORD(ffi->dwProductVersionMS); + realBuild = HIWORD(ffi->dwProductVersionLS); + PyMem_RawFree(verblock); + return Py_BuildValue("(kkk)", realMajor, realMinor, realBuild); +} + /* Disable deprecation warnings about GetVersionEx as the result is being passed straight through to the caller, who is responsible for using it correctly. */ @@ -1490,11 +1544,13 @@ sys_getwindowsversion_impl(PyObject *module) PyObject *version; int pos = 0; OSVERSIONINFOEXW ver; - DWORD realMajor, realMinor, realBuild; - HANDLE hKernel32; - wchar_t kernel32_path[MAX_PATH]; - LPVOID verblock; - DWORD verblock_size; + + version = PyObject_GetAttrString(module, "_cached_windows_version"); + if (version && PyObject_TypeCheck(version, &WindowsVersionType)) { + return version; + } + Py_XDECREF(version); + PyErr_Clear(); ver.dwOSVersionInfoSize = sizeof(ver); if (!GetVersionExW((OSVERSIONINFOW*) &ver)) @@ -1514,41 +1570,34 @@ sys_getwindowsversion_impl(PyObject *module) PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wSuiteMask)); PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wProductType)); - realMajor = ver.dwMajorVersion; - realMinor = ver.dwMinorVersion; - realBuild = ver.dwBuildNumber; - // GetVersion will lie if we are running in a compatibility mode. // We need to read the version info from a system file resource // to accurately identify the OS version. If we fail for any reason, // just return whatever GetVersion said. - Py_BEGIN_ALLOW_THREADS - hKernel32 = GetModuleHandleW(L"kernel32.dll"); - Py_END_ALLOW_THREADS - if (hKernel32 && GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH) && - (verblock_size = GetFileVersionInfoSizeW(kernel32_path, NULL)) && - (verblock = PyMem_RawMalloc(verblock_size))) { - VS_FIXEDFILEINFO *ffi; - UINT ffi_len; - - if (GetFileVersionInfoW(kernel32_path, 0, verblock_size, verblock) && - VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) { - realMajor = HIWORD(ffi->dwProductVersionMS); - realMinor = LOWORD(ffi->dwProductVersionMS); - realBuild = HIWORD(ffi->dwProductVersionLS); - } - PyMem_RawFree(verblock); + PyObject *realVersion = _sys_getwindowsversion_from_kernel32(); + if (!realVersion) { + PyErr_Clear(); + realVersion = Py_BuildValue("(kkk)", + ver.dwMajorVersion, + ver.dwMinorVersion, + ver.dwBuildNumber + ); + } + + if (realVersion) { + PyStructSequence_SET_ITEM(version, pos++, realVersion); } - PyStructSequence_SET_ITEM(version, pos++, Py_BuildValue("(kkk)", - realMajor, - realMinor, - realBuild - )); if (PyErr_Occurred()) { Py_DECREF(version); return NULL; } + + if (PyObject_SetAttrString(module, "_cached_windows_version", version) < 0) { + Py_DECREF(version); + return NULL; + } + return version; } @@ -1646,6 +1695,45 @@ sys_mdebug_impl(PyObject *module, int flag) } #endif /* USE_MALLOPT */ + +/*[clinic input] +sys.get_int_max_str_digits + +Return the maximum string digits limit for non-binary int<->str conversions. +[clinic start generated code]*/ + +static PyObject * +sys_get_int_max_str_digits_impl(PyObject *module) +/*[clinic end generated code: output=0042f5e8ae0e8631 input=61bf9f99bc8b112d]*/ +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return PyLong_FromLong(interp->long_state.max_str_digits); +} + +/*[clinic input] +sys.set_int_max_str_digits + + maxdigits: int + +Set the maximum string digits limit for non-binary int<->str conversions. +[clinic start generated code]*/ + +static PyObject * +sys_set_int_max_str_digits_impl(PyObject *module, int maxdigits) +/*[clinic end generated code: output=734d4c2511f2a56d input=d7e3f325db6910c5]*/ +{ + PyThreadState *tstate = _PyThreadState_GET(); + if ((!maxdigits) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD)) { + tstate->interp->long_state.max_str_digits = maxdigits; + Py_RETURN_NONE; + } else { + PyErr_Format( + PyExc_ValueError, "maxdigits must be 0 or larger than %d", + _PY_LONG_MAX_STR_DIGITS_THRESHOLD); + return NULL; + } +} + size_t _PySys_GetSizeOf(PyObject *o) { @@ -1659,7 +1747,7 @@ _PySys_GetSizeOf(PyObject *o) return (size_t)-1; } - method = _PyObject_LookupSpecial(o, &PyId___sizeof__); + method = _PyObject_LookupSpecial(o, &_Py_ID(__sizeof__)); if (method == NULL) { if (!_PyErr_Occurred(tstate)) { _PyErr_Format(tstate, PyExc_TypeError, @@ -1686,10 +1774,7 @@ _PySys_GetSizeOf(PyObject *o) return (size_t)-1; } - /* add gc_head size */ - if (_PyObject_IS_GC(o)) - return ((size_t)size) + sizeof(PyGC_Head); - return (size_t)size; + return (size_t)size + _PyType_PreHeaderSize(Py_TYPE(o)); } static PyObject * @@ -1711,8 +1796,7 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds) /* Has a default value been given */ if (dflt != NULL && _PyErr_ExceptionMatches(tstate, PyExc_TypeError)) { _PyErr_Clear(tstate); - Py_INCREF(dflt); - return dflt; + return Py_NewRef(dflt); } else return NULL; @@ -1760,17 +1844,6 @@ sys_gettotalrefcount_impl(PyObject *module) #endif /* Py_REF_DEBUG */ -/*[clinic input] -sys._getquickenedcount -> Py_ssize_t -[clinic start generated code]*/ - -static Py_ssize_t -sys__getquickenedcount_impl(PyObject *module) -/*[clinic end generated code: output=1ab259e7f91248a2 input=249d448159eca912]*/ -{ - return _Py_QuickenedCount; -} - /*[clinic input] sys.getallocatedblocks -> Py_ssize_t @@ -1807,22 +1880,29 @@ sys__getframe_impl(PyObject *module, int depth) /*[clinic end generated code: output=d438776c04d59804 input=c1be8a6464b11ee5]*/ { PyThreadState *tstate = _PyThreadState_GET(); - InterpreterFrame *frame = tstate->cframe->current_frame; + _PyInterpreterFrame *frame = tstate->cframe->current_frame; - if (_PySys_Audit(tstate, "sys._getframe", NULL) < 0) { - return NULL; - } - - while (depth > 0 && frame != NULL) { - frame = frame->previous; - --depth; + if (frame != NULL) { + while (depth > 0) { + frame = _PyFrame_GetFirstComplete(frame->previous); + if (frame == NULL) { + break; + } + --depth; + } } if (frame == NULL) { _PyErr_SetString(tstate, PyExc_ValueError, "call stack is not deep enough"); return NULL; } - return _Py_XNewRef((PyObject *)_PyFrame_GetFrameObject(frame)); + + PyObject *pyFrame = Py_XNewRef((PyObject *)_PyFrame_GetFrameObject(frame)); + if (pyFrame && _PySys_Audit(tstate, "sys._getframe", "(O)", pyFrame) < 0) { + Py_DECREF(pyFrame); + return NULL; + } + return pyFrame; } /*[clinic input] @@ -1909,11 +1989,6 @@ sys__debugmallocstats_impl(PyObject *module) extern PyObject *_Py_GetObjects(PyObject *, PyObject *); #endif -#ifdef DYNAMIC_EXECUTION_PROFILE -/* Defined in ceval.c because it uses static globals in that file */ -extern PyObject *_Py_GetDXProfile(PyObject *, PyObject *); -#endif - #ifdef __cplusplus } #endif @@ -1946,6 +2021,66 @@ sys_is_finalizing_impl(PyObject *module) return PyBool_FromLong(_Py_IsFinalizing()); } +#ifdef Py_STATS +/*[clinic input] +sys._stats_on + +Turns on stats gathering (stats gathering is on by default). +[clinic start generated code]*/ + +static PyObject * +sys__stats_on_impl(PyObject *module) +/*[clinic end generated code: output=aca53eafcbb4d9fe input=8ddc6df94e484f3a]*/ +{ + _py_stats = &_py_stats_struct; + Py_RETURN_NONE; +} + +/*[clinic input] +sys._stats_off + +Turns off stats gathering (stats gathering is on by default). +[clinic start generated code]*/ + +static PyObject * +sys__stats_off_impl(PyObject *module) +/*[clinic end generated code: output=1534c1ee63812214 input=b3e50e71ecf29f66]*/ +{ + _py_stats = NULL; + Py_RETURN_NONE; +} + +/*[clinic input] +sys._stats_clear + +Clears the stats. +[clinic start generated code]*/ + +static PyObject * +sys__stats_clear_impl(PyObject *module) +/*[clinic end generated code: output=fb65a2525ee50604 input=3e03f2654f44da96]*/ +{ + _Py_StatsClear(); + Py_RETURN_NONE; +} + +/*[clinic input] +sys._stats_dump + +Dump stats to file, and clears the stats. +[clinic start generated code]*/ + +static PyObject * +sys__stats_dump_impl(PyObject *module) +/*[clinic end generated code: output=79f796fb2b4ddf05 input=92346f16d64f6f95]*/ +{ + _Py_PrintSpecializationStats(1); + _Py_StatsClear(); + Py_RETURN_NONE; +} + +#endif + #ifdef ANDROID_API_LEVEL /*[clinic input] sys.getandroidapilevel @@ -1961,37 +2096,148 @@ sys_getandroidapilevel_impl(PyObject *module) } #endif /* ANDROID_API_LEVEL */ +/*[clinic input] +sys.activate_stack_trampoline + + backend: str + / + +Activate stack profiler trampoline *backend*. +[clinic start generated code]*/ + +static PyObject * +sys_activate_stack_trampoline_impl(PyObject *module, const char *backend) +/*[clinic end generated code: output=5783cdeb51874b43 input=a12df928758a82b4]*/ +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + if (strcmp(backend, "perf") == 0) { + _PyPerf_Callbacks cur_cb; + _PyPerfTrampoline_GetCallbacks(&cur_cb); + if (cur_cb.init_state != _Py_perfmap_callbacks.init_state) { + if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_callbacks) < 0 ) { + PyErr_SetString(PyExc_ValueError, "can't activate perf trampoline"); + return NULL; + } + } + } + else { + PyErr_Format(PyExc_ValueError, "invalid backend: %s", backend); + return NULL; + } + if (_PyPerfTrampoline_Init(1) < 0) { + return NULL; + } + Py_RETURN_NONE; +#else + PyErr_SetString(PyExc_ValueError, "perf trampoline not available"); + return NULL; +#endif +} + + +/*[clinic input] +sys.deactivate_stack_trampoline + +Deactivate the current stack profiler trampoline backend. + +If no stack profiler is activated, this function has no effect. +[clinic start generated code]*/ + +static PyObject * +sys_deactivate_stack_trampoline_impl(PyObject *module) +/*[clinic end generated code: output=b50da25465df0ef1 input=9f629a6be9fe7fc8]*/ +{ + if (_PyPerfTrampoline_Init(0) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +/*[clinic input] +sys.is_stack_trampoline_active + +Return *True* if a stack profiler trampoline is active. +[clinic start generated code]*/ + +static PyObject * +sys_is_stack_trampoline_active_impl(PyObject *module) +/*[clinic end generated code: output=ab2746de0ad9d293 input=29616b7bf6a0b703]*/ +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + if (_PyIsPerfTrampolineActive()) { + Py_RETURN_TRUE; + } +#endif + Py_RETURN_FALSE; +} + + +/*[clinic input] +sys._getframemodulename + + depth: int = 0 + +Return the name of the module for a calling frame. + +The default depth returns the module containing the call to this API. +A more typical use in a library will pass a depth of 1 to get the user's +module rather than the library module. + +If no frame, module, or name can be found, returns None. +[clinic start generated code]*/ + +static PyObject * +sys__getframemodulename_impl(PyObject *module, int depth) +/*[clinic end generated code: output=1d70ef691f09d2db input=d4f1a8ed43b8fb46]*/ +{ + if (PySys_Audit("sys._getframemodulename", "i", depth) < 0) { + return NULL; + } + _PyInterpreterFrame *f = _PyThreadState_GET()->cframe->current_frame; + while (f && (_PyFrame_IsIncomplete(f) || depth-- > 0)) { + f = f->previous; + } + if (f == NULL || f->f_funcobj == NULL) { + Py_RETURN_NONE; + } + PyObject *r = PyFunction_GetModule(f->f_funcobj); + if (!r) { + PyErr_Clear(); + r = Py_None; + } + return Py_NewRef(r); +} + + static PyMethodDef sys_methods[] = { /* Might as well keep this in alphabetic order */ SYS_ADDAUDITHOOK_METHODDEF - {"audit", (PyCFunction)(void(*)(void))sys_audit, METH_FASTCALL, audit_doc }, - {"breakpointhook", (PyCFunction)(void(*)(void))sys_breakpointhook, + {"audit", _PyCFunction_CAST(sys_audit), METH_FASTCALL, audit_doc }, + {"breakpointhook", _PyCFunction_CAST(sys_breakpointhook), METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc}, SYS__CLEAR_TYPE_CACHE_METHODDEF SYS__CURRENT_FRAMES_METHODDEF SYS__CURRENT_EXCEPTIONS_METHODDEF SYS_DISPLAYHOOK_METHODDEF + SYS_EXCEPTION_METHODDEF SYS_EXC_INFO_METHODDEF SYS_EXCEPTHOOK_METHODDEF SYS_EXIT_METHODDEF SYS_GETDEFAULTENCODING_METHODDEF SYS_GETDLOPENFLAGS_METHODDEF SYS_GETALLOCATEDBLOCKS_METHODDEF -#ifdef DYNAMIC_EXECUTION_PROFILE - {"getdxp", _Py_GetDXProfile, METH_VARARGS}, -#endif SYS_GETFILESYSTEMENCODING_METHODDEF SYS_GETFILESYSTEMENCODEERRORS_METHODDEF - SYS__GETQUICKENEDCOUNT_METHODDEF #ifdef Py_TRACE_REFS - {"getobjects", _Py_GetObjects, METH_VARARGS}, + {"getobjects", _Py_GetObjects, METH_VARARGS}, #endif SYS_GETTOTALREFCOUNT_METHODDEF SYS_GETREFCOUNT_METHODDEF SYS_GETRECURSIONLIMIT_METHODDEF - {"getsizeof", (PyCFunction)(void(*)(void))sys_getsizeof, + {"getsizeof", _PyCFunction_CAST(sys_getsizeof), METH_VARARGS | METH_KEYWORDS, getsizeof_doc}, SYS__GETFRAME_METHODDEF + SYS__GETFRAMEMODULENAME_METHODDEF SYS_GETWINDOWSVERSION_METHODDEF SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF SYS_INTERN_METHODDEF @@ -2000,21 +2246,34 @@ static PyMethodDef sys_methods[] = { SYS_SETSWITCHINTERVAL_METHODDEF SYS_GETSWITCHINTERVAL_METHODDEF SYS_SETDLOPENFLAGS_METHODDEF - {"setprofile", sys_setprofile, METH_O, setprofile_doc}, + {"setprofile", sys_setprofile, METH_O, setprofile_doc}, + SYS__SETPROFILEALLTHREADS_METHODDEF SYS_GETPROFILE_METHODDEF SYS_SETRECURSIONLIMIT_METHODDEF - {"settrace", sys_settrace, METH_O, settrace_doc}, + {"settrace", sys_settrace, METH_O, settrace_doc}, + SYS__SETTRACEALLTHREADS_METHODDEF SYS_GETTRACE_METHODDEF SYS_CALL_TRACING_METHODDEF SYS__DEBUGMALLOCSTATS_METHODDEF SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF SYS_GET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF - {"set_asyncgen_hooks", (PyCFunction)(void(*)(void))sys_set_asyncgen_hooks, + {"set_asyncgen_hooks", _PyCFunction_CAST(sys_set_asyncgen_hooks), METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc}, SYS_GET_ASYNCGEN_HOOKS_METHODDEF SYS_GETANDROIDAPILEVEL_METHODDEF + SYS_ACTIVATE_STACK_TRAMPOLINE_METHODDEF + SYS_DEACTIVATE_STACK_TRAMPOLINE_METHODDEF + SYS_IS_STACK_TRAMPOLINE_ACTIVE_METHODDEF SYS_UNRAISABLEHOOK_METHODDEF - {NULL, NULL} /* sentinel */ + SYS_GET_INT_MAX_STR_DIGITS_METHODDEF + SYS_SET_INT_MAX_STR_DIGITS_METHODDEF +#ifdef Py_STATS + SYS__STATS_ON_METHODDEF + SYS__STATS_OFF_METHODDEF + SYS__STATS_CLEAR_METHODDEF + SYS__STATS_DUMP_METHODDEF +#endif + {NULL, NULL} // sentinel }; @@ -2025,8 +2284,9 @@ list_builtin_module_names(void) if (list == NULL) { return NULL; } - for (Py_ssize_t i = 0; PyImport_Inittab[i].name != NULL; i++) { - PyObject *name = PyUnicode_FromString(PyImport_Inittab[i].name); + struct _inittab *inittab = _PyRuntime.imports.inittab; + for (Py_ssize_t i = 0; inittab[i].name != NULL; i++) { + PyObject *name = PyUnicode_FromString(inittab[i].name); if (name == NULL) { goto error; } @@ -2203,7 +2463,7 @@ _PySys_ReadPreinitXOptions(PyConfig *config) static PyObject * get_warnoptions(PyThreadState *tstate) { - PyObject *warnoptions = sys_get_object_id(tstate, &PyId_warnoptions); + PyObject *warnoptions = _PySys_GetAttr(tstate, &_Py_ID(warnoptions)); if (warnoptions == NULL || !PyList_Check(warnoptions)) { /* PEP432 TODO: we can reach this if warnoptions is NULL in the main * interpreter config. When that happens, we need to properly set @@ -2219,7 +2479,7 @@ get_warnoptions(PyThreadState *tstate) if (warnoptions == NULL) { return NULL; } - if (sys_set_object_id(tstate->interp, &PyId_warnoptions, warnoptions)) { + if (sys_set_object(tstate->interp, &_Py_ID(warnoptions), warnoptions)) { Py_DECREF(warnoptions); return NULL; } @@ -2237,7 +2497,7 @@ PySys_ResetWarnOptions(void) return; } - PyObject *warnoptions = sys_get_object_id(tstate, &PyId_warnoptions); + PyObject *warnoptions = _PySys_GetAttr(tstate, &_Py_ID(warnoptions)); if (warnoptions == NULL || !PyList_Check(warnoptions)) return; PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL); @@ -2291,7 +2551,7 @@ int PySys_HasWarnOptions(void) { PyThreadState *tstate = _PyThreadState_GET(); - PyObject *warnoptions = sys_get_object_id(tstate, &PyId_warnoptions); + PyObject *warnoptions = _PySys_GetAttr(tstate, &_Py_ID(warnoptions)); return (warnoptions != NULL && PyList_Check(warnoptions) && PyList_GET_SIZE(warnoptions) > 0); } @@ -2299,7 +2559,7 @@ PySys_HasWarnOptions(void) static PyObject * get_xoptions(PyThreadState *tstate) { - PyObject *xoptions = sys_get_object_id(tstate, &PyId__xoptions); + PyObject *xoptions = _PySys_GetAttr(tstate, &_Py_ID(_xoptions)); if (xoptions == NULL || !PyDict_Check(xoptions)) { /* PEP432 TODO: we can reach this if xoptions is NULL in the main * interpreter config. When that happens, we need to properly set @@ -2315,7 +2575,7 @@ get_xoptions(PyThreadState *tstate) if (xoptions == NULL) { return NULL; } - if (sys_set_object_id(tstate->interp, &PyId__xoptions, xoptions)) { + if (sys_set_object(tstate->interp, &_Py_ID(_xoptions), xoptions)) { Py_DECREF(xoptions); return NULL; } @@ -2338,8 +2598,7 @@ _PySys_AddXOptionWithError(const wchar_t *s) const wchar_t *name_end = wcschr(s, L'='); if (!name_end) { name = PyUnicode_FromWideChar(s, -1); - value = Py_True; - Py_INCREF(value); + value = Py_NewRef(Py_True); } else { name = PyUnicode_FromWideChar(s, name_end - s); @@ -2465,7 +2724,8 @@ Functions:\n\ \n\ displayhook() -- print an object to the screen, and save it in builtins._\n\ excepthook() -- print an exception and its traceback to sys.stderr\n\ -exc_info() -- return thread-safe information about the current exception\n\ +exception() -- return the current thread's active exception\n\ +exc_info() -- return information about the current thread's active exception\n\ exit() -- exit the interpreter by raising SystemExit\n\ getdlopenflags() -- returns flags to be used for dlopen() calls\n\ getprofile() -- get the global profiling function\n\ @@ -2506,6 +2766,8 @@ static PyStructSequence_Field flags_fields[] = { {"dev_mode", "-X dev"}, {"utf8_mode", "-X utf8"}, {"warn_default_encoding", "-X warn_default_encoding"}, + {"safe_path", "-P"}, + {"int_max_str_digits", "-X int_max_str_digits"}, {0} }; @@ -2513,7 +2775,7 @@ static PyStructSequence_Desc flags_desc = { "sys.flags", /* name */ flags__doc__, /* doc */ flags_fields, /* fields */ - 16 + 18 }; static int @@ -2553,6 +2815,8 @@ set_flags_from_config(PyInterpreterState *interp, PyObject *flags) SetFlagObj(PyBool_FromLong(config->dev_mode)); SetFlag(preconfig->utf8_mode); SetFlag(config->warn_default_encoding); + SetFlagObj(PyBool_FromLong(config->safe_path)); + SetFlag(config->int_max_str_digits); #undef SetFlagObj #undef SetFlag return 0; @@ -2717,6 +2981,110 @@ error: return NULL; } +#ifdef __EMSCRIPTEN__ + +PyDoc_STRVAR(emscripten_info__doc__, +"sys._emscripten_info\n\ +\n\ +WebAssembly Emscripten platform information."); + +static PyTypeObject *EmscriptenInfoType; + +static PyStructSequence_Field emscripten_info_fields[] = { + {"emscripten_version", "Emscripten version (major, minor, micro)"}, + {"runtime", "Runtime (Node.JS version, browser user agent)"}, + {"pthreads", "pthread support"}, + {"shared_memory", "shared memory support"}, + {0} +}; + +static PyStructSequence_Desc emscripten_info_desc = { + "sys._emscripten_info", /* name */ + emscripten_info__doc__ , /* doc */ + emscripten_info_fields, /* fields */ + 4 +}; + +EM_JS(char *, _Py_emscripten_runtime, (void), { + var info; + if (typeof navigator == 'object') { + info = navigator.userAgent; + } else if (typeof process == 'object') { + info = "Node.js ".concat(process.version); + } else { + info = "UNKNOWN"; + } + var len = lengthBytesUTF8(info) + 1; + var res = _malloc(len); + if (res) stringToUTF8(info, res, len); +#if __wasm64__ + return BigInt(res); +#else + return res; +#endif +}); + +static PyObject * +make_emscripten_info(void) +{ + PyObject *emscripten_info = NULL; + PyObject *version = NULL; + char *ua; + int pos = 0; + + emscripten_info = PyStructSequence_New(EmscriptenInfoType); + if (emscripten_info == NULL) { + return NULL; + } + + version = Py_BuildValue("(iii)", + __EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__); + if (version == NULL) { + goto error; + } + PyStructSequence_SET_ITEM(emscripten_info, pos++, version); + + ua = _Py_emscripten_runtime(); + if (ua != NULL) { + PyObject *oua = PyUnicode_DecodeUTF8(ua, strlen(ua), "strict"); + free(ua); + if (oua == NULL) { + goto error; + } + PyStructSequence_SET_ITEM(emscripten_info, pos++, oua); + } else { + PyStructSequence_SET_ITEM(emscripten_info, pos++, Py_NewRef(Py_None)); + } + +#define SetBoolItem(flag) \ + PyStructSequence_SET_ITEM(emscripten_info, pos++, PyBool_FromLong(flag)) + +#ifdef __EMSCRIPTEN_PTHREADS__ + SetBoolItem(1); +#else + SetBoolItem(0); +#endif + +#ifdef __EMSCRIPTEN_SHARED_MEMORY__ + SetBoolItem(1); +#else + SetBoolItem(0); +#endif + +#undef SetBoolItem + + if (PyErr_Occurred()) { + goto error; + } + return emscripten_info; + + error: + Py_CLEAR(emscripten_info); + return NULL; +} + +#endif // __EMSCRIPTEN__ + static struct PyModuleDef sysmodule = { PyModuleDef_HEAD_INIT, "sys", @@ -2777,7 +3145,7 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) SET_SYS("int_info", PyLong_GetInfo()); /* initialize hash_info */ if (Hash_InfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0) { + if (_PyStructSequence_InitBuiltin(&Hash_InfoType, &hash_info_desc) < 0) { goto type_init_failed; } } @@ -2799,14 +3167,18 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) SET_SYS_FROM_STRING("abiflags", ABIFLAGS); #endif +#define ENSURE_INFO_TYPE(TYPE, DESC) \ + do { \ + if (TYPE.tp_name == NULL) { \ + if (_PyStructSequence_InitBuiltinWithFlags( \ + &TYPE, &DESC, Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { \ + goto type_init_failed; \ + } \ + } \ + } while (0) + /* version_info */ - if (VersionInfoType.tp_name == NULL) { - if (_PyStructSequence_InitType(&VersionInfoType, - &version_info_desc, - Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { - goto type_init_failed; - } - } + ENSURE_INFO_TYPE(VersionInfoType, version_info_desc); version_info = make_version_info(tstate); SET_SYS("version_info", version_info); @@ -2814,27 +3186,20 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) SET_SYS("implementation", make_impl_info(version_info)); // sys.flags: updated in-place later by _PySys_UpdateConfig() - if (FlagsType.tp_name == 0) { - if (_PyStructSequence_InitType(&FlagsType, &flags_desc, - Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { - goto type_init_failed; - } - } + ENSURE_INFO_TYPE(FlagsType, flags_desc); SET_SYS("flags", make_flags(tstate->interp)); #if defined(MS_WINDOWS) /* getwindowsversion */ - if (WindowsVersionType.tp_name == 0) { - if (_PyStructSequence_InitType(&WindowsVersionType, - &windows_version_desc, - Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { - goto type_init_failed; - } - } + ENSURE_INFO_TYPE(WindowsVersionType, windows_version_desc); + + SET_SYS_FROM_STRING("_vpath", VPATH); #endif +#undef ENSURE_INFO_TYPE + /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */ -#ifndef PY_NO_SHORT_FLOAT_REPR +#if _PY_SHORT_FLOAT_REPR == 1 SET_SYS_FROM_STRING("float_repr_style", "short"); #else SET_SYS_FROM_STRING("float_repr_style", "legacy"); @@ -2844,12 +3209,22 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) /* initialize asyncgen_hooks */ if (AsyncGenHooksType.tp_name == NULL) { - if (PyStructSequence_InitType2( + if (_PyStructSequence_InitBuiltin( &AsyncGenHooksType, &asyncgen_hooks_desc) < 0) { goto type_init_failed; } } +#ifdef __EMSCRIPTEN__ + if (EmscriptenInfoType == NULL) { + EmscriptenInfoType = PyStructSequence_NewType(&emscripten_info_desc); + if (EmscriptenInfoType == NULL) { + goto type_init_failed; + } + } + SET_SYS("_emscripten_info", make_emscripten_info()); +#endif + /* adding sys.path_hooks and sys.path_importer_cache */ SET_SYS("meta_path", PyList_New(0)); SET_SYS("path_importer_cache", PyDict_New()); @@ -2875,8 +3250,7 @@ sys_add_xoption(PyObject *opts, const wchar_t *s) const wchar_t *name_end = wcschr(s, L'='); if (!name_end) { name = PyUnicode_FromWideChar(s, -1); - value = Py_True; - Py_INCREF(value); + value = Py_NewRef(Py_True); } else { name = PyUnicode_FromWideChar(s, name_end - s); @@ -3014,7 +3388,7 @@ _PySys_SetPreliminaryStderr(PyObject *sysdict) if (pstderr == NULL) { goto error; } - if (_PyDict_SetItemId(sysdict, &PyId_stderr, pstderr) < 0) { + if (PyDict_SetItem(sysdict, &_Py_ID(stderr), pstderr) < 0) { goto error; } if (PyDict_SetItemString(sysdict, "__stderr__", pstderr) < 0) { @@ -3053,8 +3427,7 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p) if (sysdict == NULL) { goto error; } - Py_INCREF(sysdict); - interp->sysdict = sysdict; + interp->sysdict = Py_NewRef(sysdict); if (PyDict_SetItemString(sysdict, "modules", interp->modules) < 0) { goto error; @@ -3084,6 +3457,24 @@ error: } +void +_PySys_Fini(PyInterpreterState *interp) +{ + if (_Py_IsMainInterpreter(interp)) { + _PyStructSequence_FiniType(&VersionInfoType); + _PyStructSequence_FiniType(&FlagsType); +#if defined(MS_WINDOWS) + _PyStructSequence_FiniType(&WindowsVersionType); +#endif + _PyStructSequence_FiniType(&Hash_InfoType); + _PyStructSequence_FiniType(&AsyncGenHooksType); +#ifdef __EMSCRIPTEN__ + Py_CLEAR(EmscriptenInfoType); +#endif + } +} + + static PyObject * makepathobject(const wchar_t *path, wchar_t delim) { @@ -3124,7 +3515,7 @@ PySys_SetPath(const wchar_t *path) if ((v = makepathobject(path, DELIM)) == NULL) Py_FatalError("can't create sys.path"); PyInterpreterState *interp = _PyInterpreterState_GET(); - if (sys_set_object_id(interp, &PyId_path, v) != 0) { + if (sys_set_object(interp, &_Py_ID(path), v) != 0) { Py_FatalError("can't assign sys.path"); } Py_DECREF(v); @@ -3181,7 +3572,7 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) Py_FatalError("can't compute path0 from argv"); } - PyObject *sys_path = sys_get_object_id(tstate, &PyId_path); + PyObject *sys_path = _PySys_GetAttr(tstate, &_Py_ID(path)); if (sys_path != NULL) { if (PyList_Insert(sys_path, 0, path0) < 0) { Py_DECREF(path0); @@ -3196,7 +3587,10 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) void PySys_SetArgv(int argc, wchar_t **argv) { +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS PySys_SetArgvEx(argc, argv, Py_IsolatedFlag == 0); +_Py_COMP_DIAG_POP } /* Reimplementation of PyFile_WriteString() no calling indirectly @@ -3208,7 +3602,7 @@ sys_pyfile_write_unicode(PyObject *unicode, PyObject *file) if (file == NULL) return -1; assert(unicode != NULL); - PyObject *result = _PyObject_CallMethodIdOneArg(file, &PyId_write, unicode); + PyObject *result = _PyObject_CallMethodOneArg(file, &_Py_ID(write), unicode); if (result == NULL) { return -1; } @@ -3263,7 +3657,7 @@ sys_pyfile_write(const char *text, PyObject *file) */ static void -sys_write(_Py_Identifier *key, FILE *fp, const char *format, va_list va) +sys_write(PyObject *key, FILE *fp, const char *format, va_list va) { PyObject *file; PyObject *error_type, *error_value, *error_traceback; @@ -3272,7 +3666,7 @@ sys_write(_Py_Identifier *key, FILE *fp, const char *format, va_list va) PyThreadState *tstate = _PyThreadState_GET(); _PyErr_Fetch(tstate, &error_type, &error_value, &error_traceback); - file = sys_get_object_id(tstate, key); + file = _PySys_GetAttr(tstate, key); written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va); if (sys_pyfile_write(buffer, file) != 0) { _PyErr_Clear(tstate); @@ -3292,7 +3686,7 @@ PySys_WriteStdout(const char *format, ...) va_list va; va_start(va, format); - sys_write(&PyId_stdout, stdout, format, va); + sys_write(&_Py_ID(stdout), stdout, format, va); va_end(va); } @@ -3302,12 +3696,12 @@ PySys_WriteStderr(const char *format, ...) va_list va; va_start(va, format); - sys_write(&PyId_stderr, stderr, format, va); + sys_write(&_Py_ID(stderr), stderr, format, va); va_end(va); } static void -sys_format(_Py_Identifier *key, FILE *fp, const char *format, va_list va) +sys_format(PyObject *key, FILE *fp, const char *format, va_list va) { PyObject *file, *message; PyObject *error_type, *error_value, *error_traceback; @@ -3315,7 +3709,7 @@ sys_format(_Py_Identifier *key, FILE *fp, const char *format, va_list va) PyThreadState *tstate = _PyThreadState_GET(); _PyErr_Fetch(tstate, &error_type, &error_value, &error_traceback); - file = sys_get_object_id(tstate, key); + file = _PySys_GetAttr(tstate, key); message = PyUnicode_FromFormatV(format, va); if (message != NULL) { if (sys_pyfile_write_unicode(message, file) != 0) { @@ -3335,7 +3729,7 @@ PySys_FormatStdout(const char *format, ...) va_list va; va_start(va, format); - sys_format(&PyId_stdout, stdout, format, va); + sys_format(&_Py_ID(stdout), stdout, format, va); va_end(va); } @@ -3345,6 +3739,6 @@ PySys_FormatStderr(const char *format, ...) va_list va; va_start(va, format); - sys_format(&PyId_stderr, stderr, format, va); + sys_format(&_Py_ID(stderr), stderr, format, va); va_end(va); } diff --git a/Python/thread.c b/Python/thread.c index dfe28b6bdb6..4581f1af043 100644 --- a/Python/thread.c +++ b/Python/thread.c @@ -6,16 +6,9 @@ Stuff shared by all thread_*.h files is collected here. */ #include "Python.h" -#include "pycore_pystate.h" // _PyInterpreterState_GET() - -#ifndef _POSIX_THREADS -/* This means pthreads are not implemented in libc headers, hence the macro - not present in unistd.h. But they still can be implemented as an external - library (e.g. gnu pth in pthread emulation) */ -# ifdef HAVE_PTHREAD_H -# include /* _POSIX_THREADS */ -# endif -#endif +#include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_structseq.h" // _PyStructSequence_FiniType() +#include "pycore_pythread.h" #ifndef DONT_HAVE_STDIO_H #include @@ -23,79 +16,30 @@ #include -#ifndef _POSIX_THREADS - -/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then - enough of the Posix threads package is implemented to support python - threads. - - This is valid for HP-UX 11.23 running on an ia64 system. If needed, add - a check of __ia64 to verify that we're running on an ia64 system instead - of a pa-risc system. -*/ -#ifdef __hpux -#ifdef _SC_THREADS -#define _POSIX_THREADS -#endif -#endif - -#endif /* _POSIX_THREADS */ - - -#ifdef Py_DEBUG -static int thread_debug = 0; -#define dprintf(args) (void)((thread_debug & 1) && printf args) -#define d2printf(args) ((thread_debug & 8) && printf args) -#else -#define dprintf(args) -#define d2printf(args) -#endif - -static int initialized; static void PyThread__init_thread(void); /* Forward */ +#define initialized _PyRuntime.threads.initialized + void PyThread_init_thread(void) { -#ifdef Py_DEBUG - const char *p = Py_GETENV("PYTHONTHREADDEBUG"); - - if (p) { - if (*p) - thread_debug = atoi(p); - else - thread_debug = 1; - } -#endif /* Py_DEBUG */ - if (initialized) + if (initialized) { return; + } initialized = 1; - dprintf(("PyThread_init_thread called\n")); PyThread__init_thread(); } -void -_PyThread_debug_deprecation(void) -{ -#ifdef Py_DEBUG - if (thread_debug) { - // Flush previous dprintf() logs - fflush(stdout); - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "The threading debug (PYTHONTHREADDEBUG environment " - "variable) is deprecated and will be removed " - "in Python 3.12", - 0)) - { - _PyErr_WriteUnraisableMsg("at Python startup", NULL); - } - } -#endif -} - -#if defined(_POSIX_THREADS) -# define PYTHREAD_NAME "pthread" +#if defined(HAVE_PTHREAD_STUBS) +# define PYTHREAD_NAME "pthread-stubs" +# include "thread_pthread_stubs.h" +#elif defined(_USE_PTHREADS) /* AKA _PTHREADS */ +# if defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__) +# define PYTHREAD_NAME "pthread-stubs" +# else +# define PYTHREAD_NAME "pthread" +# endif # include "thread_pthread.h" #elif defined(NT_THREADS) # define PYTHREAD_NAME "nt" @@ -109,7 +53,7 @@ _PyThread_debug_deprecation(void) size_t PyThread_get_stacksize(void) { - return _PyInterpreterState_GET()->pythread_stacksize; + return _PyInterpreterState_GET()->threads.stacksize; } /* Only platforms defining a THREAD_SET_STACKSIZE() macro @@ -194,7 +138,8 @@ PyThread_GetInfo(void) #endif if (ThreadInfoType.tp_name == 0) { - if (PyStructSequence_InitType2(&ThreadInfoType, &threadinfo_desc) < 0) + if (_PyStructSequence_InitBuiltin(&ThreadInfoType, + &threadinfo_desc) < 0) return NULL; } @@ -209,7 +154,9 @@ PyThread_GetInfo(void) } PyStructSequence_SET_ITEM(threadinfo, pos++, value); -#ifdef _POSIX_THREADS +#ifdef HAVE_PTHREAD_STUBS + value = Py_NewRef(Py_None); +#elif defined(_POSIX_THREADS) #ifdef USE_SEMAPHORES value = PyUnicode_FromString("semaphore"); #else @@ -220,8 +167,7 @@ PyThread_GetInfo(void) return NULL; } #else - Py_INCREF(Py_None); - value = Py_None; + value = Py_NewRef(Py_None); #endif PyStructSequence_SET_ITEM(threadinfo, pos++, value); @@ -237,9 +183,19 @@ PyThread_GetInfo(void) if (value == NULL) #endif { - Py_INCREF(Py_None); - value = Py_None; + value = Py_NewRef(Py_None); } PyStructSequence_SET_ITEM(threadinfo, pos++, value); return threadinfo; } + + +void +_PyThread_FiniType(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + return; + } + + _PyStructSequence_FiniType(&ThreadInfoType); +} diff --git a/Python/thread_nt.h b/Python/thread_nt.h index 0dde1a04097..26f441bd6d3 100644 --- a/Python/thread_nt.h +++ b/Python/thread_nt.h @@ -1,4 +1,4 @@ -#include "pycore_interp.h" // _PyInterpreterState.pythread_stacksize +#include "pycore_interp.h" // _PyInterpreterState.threads.stacksize /* This code implemented by Dag.Gruneau@elsa.preseco.comm.se */ /* Fast NonRecursiveMutex support by Yakov Markovitch, markovitch@iso.ru */ @@ -152,11 +152,12 @@ unsigned long PyThread_get_thread_native_id(void); #endif /* - * Initialization of the C package, should not be needed. + * Initialization for the current runtime. */ static void PyThread__init_thread(void) { + // Initialization of the C package should not be needed. } /* @@ -188,8 +189,6 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) unsigned threadID; callobj *obj; - dprintf(("%lu: PyThread_start_new_thread called\n", - PyThread_get_thread_ident())); if (!initialized) PyThread_init_thread(); @@ -199,7 +198,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) obj->func = func; obj->arg = arg; PyThreadState *tstate = _PyThreadState_GET(); - size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0; + size_t stacksize = tstate ? tstate->interp->threads.stacksize : 0; hThread = (HANDLE)_beginthreadex(0, Py_SAFE_DOWNCAST(stacksize, Py_ssize_t, unsigned int), bootstrap, obj, @@ -209,14 +208,10 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) * too many threads". */ int e = errno; - dprintf(("%lu: PyThread_start_new_thread failed, errno %d\n", - PyThread_get_thread_ident(), e)); threadID = (unsigned)-1; HeapFree(GetProcessHeap(), 0, obj); } else { - dprintf(("%lu: PyThread_start_new_thread succeeded: %p\n", - PyThread_get_thread_ident(), (void*)hThread)); CloseHandle(hThread); } return threadID; @@ -257,7 +252,6 @@ PyThread_get_thread_native_id(void) void _Py_NO_RETURN PyThread_exit_thread(void) { - dprintf(("%lu: PyThread_exit_thread called\n", PyThread_get_thread_ident())); if (!initialized) exit(0); _endthreadex(0); @@ -271,24 +265,22 @@ PyThread_exit_thread(void) PyThread_type_lock PyThread_allocate_lock(void) { - PNRMUTEX aLock; + PNRMUTEX mutex; - dprintf(("PyThread_allocate_lock called\n")); if (!initialized) PyThread_init_thread(); - aLock = AllocNonRecursiveMutex() ; + mutex = AllocNonRecursiveMutex() ; - dprintf(("%lu: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock)); + PyThread_type_lock aLock = (PyThread_type_lock) mutex; + assert(aLock); - return (PyThread_type_lock) aLock; + return aLock; } void PyThread_free_lock(PyThread_type_lock aLock) { - dprintf(("%lu: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); - FreeNonRecursiveMutex(aLock) ; } @@ -307,6 +299,8 @@ PyLockStatus PyThread_acquire_lock_timed(PyThread_type_lock aLock, PY_TIMEOUT_T microseconds, int intr_flag) { + assert(aLock); + /* Fow now, intr_flag does nothing on Windows, and lock acquires are * uninterruptible. */ PyLockStatus success; @@ -333,20 +327,14 @@ PyThread_acquire_lock_timed(PyThread_type_lock aLock, milliseconds = INFINITE; } - dprintf(("%lu: PyThread_acquire_lock_timed(%p, %lld) called\n", - PyThread_get_thread_ident(), aLock, microseconds)); - - if (aLock && EnterNonRecursiveMutex((PNRMUTEX)aLock, - (DWORD)milliseconds) == WAIT_OBJECT_0) { + if (EnterNonRecursiveMutex((PNRMUTEX)aLock, + (DWORD)milliseconds) == WAIT_OBJECT_0) { success = PY_LOCK_ACQUIRED; } else { success = PY_LOCK_FAILURE; } - dprintf(("%lu: PyThread_acquire_lock(%p, %lld) -> %d\n", - PyThread_get_thread_ident(), aLock, microseconds, success)); - return success; } int @@ -358,10 +346,8 @@ PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag) void PyThread_release_lock(PyThread_type_lock aLock) { - dprintf(("%lu: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); - - if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock))) - dprintf(("%lu: Could not PyThread_release_lock(%p) error: %ld\n", PyThread_get_thread_ident(), aLock, GetLastError())); + assert(aLock); + (void)LeaveNonRecursiveMutex((PNRMUTEX) aLock); } /* minimum/maximum thread stack sizes supported */ @@ -376,13 +362,13 @@ _pythread_nt_set_stacksize(size_t size) { /* set to default */ if (size == 0) { - _PyInterpreterState_GET()->pythread_stacksize = 0; + _PyInterpreterState_GET()->threads.stacksize = 0; return 0; } /* valid range? */ if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) { - _PyInterpreterState_GET()->pythread_stacksize = size; + _PyInterpreterState_GET()->threads.stacksize = size; return 0; } diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index 12dad7e9e44..76d6f3bcdf9 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -1,4 +1,4 @@ -#include "pycore_interp.h" // _PyInterpreterState.pythread_stacksize +#include "pycore_interp.h" // _PyInterpreterState.threads.stacksize /* Posix threads interface */ @@ -7,7 +7,9 @@ #if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR) #define destructor xxdestructor #endif -#include +#ifndef HAVE_PTHREAD_STUBS +# include +#endif #if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR) #undef destructor #endif @@ -23,6 +25,8 @@ # include /* thread_self() */ #elif defined(__NetBSD__) # include /* _lwp_self() */ +#elif defined(__DragonFly__) +# include /* lwp_gettid() */ #endif /* The POSIX spec requires that use of pthread_attr_setstacksize @@ -111,41 +115,25 @@ #endif -#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \ -do { \ - struct timeval tv; \ - gettimeofday(&tv, NULL); \ - tv.tv_usec += microseconds % 1000000; \ - tv.tv_sec += microseconds / 1000000; \ - tv.tv_sec += tv.tv_usec / 1000000; \ - tv.tv_usec %= 1000000; \ - ts.tv_sec = tv.tv_sec; \ - ts.tv_nsec = tv.tv_usec * 1000; \ -} while(0) - - /* * pthread_cond support */ -#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) -// monotonic is supported statically. It doesn't mean it works on runtime. -#define CONDATTR_MONOTONIC -#endif - -// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported. -static pthread_condattr_t *condattr_monotonic = NULL; +#define condattr_monotonic _PyRuntime.threads._condattr_monotonic.ptr static void init_condattr(void) { #ifdef CONDATTR_MONOTONIC - static pthread_condattr_t ca; +# define ca _PyRuntime.threads._condattr_monotonic.val + // XXX We need to check the return code? pthread_condattr_init(&ca); + // XXX We need to run pthread_condattr_destroy() during runtime fini. if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) { condattr_monotonic = &ca; // Use monotonic clock } -#endif +# undef ca +#endif // CONDATTR_MONOTONIC } int @@ -154,23 +142,23 @@ _PyThread_cond_init(PyCOND_T *cond) return pthread_cond_init(cond, condattr_monotonic); } + void _PyThread_cond_after(long long us, struct timespec *abs) { + _PyTime_t timeout = _PyTime_FromMicrosecondsClamp(us); + _PyTime_t t; #ifdef CONDATTR_MONOTONIC if (condattr_monotonic) { - clock_gettime(CLOCK_MONOTONIC, abs); - abs->tv_sec += us / 1000000; - abs->tv_nsec += (us % 1000000) * 1000; - abs->tv_sec += abs->tv_nsec / 1000000000; - abs->tv_nsec %= 1000000000; - return; + t = _PyTime_GetMonotonicClock(); } + else #endif - - struct timespec ts; - MICROSECONDS_TO_TIMESPEC(us, ts); - *abs = ts; + { + t = _PyTime_GetSystemClock(); + } + t = _PyTime_Add(t, timeout); + _PyTime_AsTimespec_clamp(t, abs); } @@ -201,15 +189,21 @@ typedef struct { "%s: %s\n", name, strerror(status)); error = 1; } /* - * Initialization. + * Initialization for the current runtime. */ static void PyThread__init_thread(void) { + // The library is only initialized once in the process, + // regardless of how many times the Python runtime is initialized. + static int lib_initialized = 0; + if (!lib_initialized) { + lib_initialized = 1; #if defined(_AIX) && defined(__GNUC__) - extern void pthread_init(void); - pthread_init(); + extern void pthread_init(void); + pthread_init(); #endif + } init_condattr(); } @@ -252,7 +246,6 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) size_t tss; #endif - dprintf(("PyThread_start_new_thread called\n")); if (!initialized) PyThread_init_thread(); @@ -262,7 +255,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) #endif #if defined(THREAD_STACK_SIZE) PyThreadState *tstate = _PyThreadState_GET(); - size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0; + size_t stacksize = tstate ? tstate->interp->threads.stacksize : 0; tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE; if (tss != 0) { if (pthread_attr_setstacksize(&attrs, tss) != 0) { @@ -350,6 +343,9 @@ PyThread_get_thread_native_id(void) #elif defined(__NetBSD__) lwpid_t native_id; native_id = _lwp_self(); +#elif defined(__DragonFly__) + lwpid_t native_id; + native_id = lwp_gettid(); #endif return (unsigned long) native_id; } @@ -358,7 +354,6 @@ PyThread_get_thread_native_id(void) void _Py_NO_RETURN PyThread_exit_thread(void) { - dprintf(("PyThread_exit_thread called\n")); if (!initialized) exit(0); pthread_exit(0); @@ -376,7 +371,6 @@ PyThread_allocate_lock(void) sem_t *lock; int status, error = 0; - dprintf(("PyThread_allocate_lock called\n")); if (!initialized) PyThread_init_thread(); @@ -392,7 +386,6 @@ PyThread_allocate_lock(void) } } - dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock)); return (PyThread_type_lock)lock; } @@ -403,7 +396,6 @@ PyThread_free_lock(PyThread_type_lock lock) int status, error = 0; (void) error; /* silence unused-but-set-variable warning */ - dprintf(("PyThread_free_lock(%p) called\n", lock)); if (!thelock) return; @@ -435,27 +427,18 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, int status, error = 0; (void) error; /* silence unused-but-set-variable warning */ - dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n", - lock, microseconds, intr_flag)); _PyTime_t timeout; // relative timeout if (microseconds >= 0) { - _PyTime_t ns; - if (microseconds <= _PyTime_MAX / 1000) { - ns = microseconds * 1000; - } - else { - // bpo-41710: PyThread_acquire_lock_timed() cannot report timeout - // overflow to the caller, so clamp the timeout to - // [_PyTime_MIN, _PyTime_MAX]. - // - // _PyTime_MAX nanoseconds is around 292.3 years. - // - // _thread.Lock.acquire() and _thread.RLock.acquire() raise an - // OverflowError if microseconds is greater than PY_TIMEOUT_MAX. - ns = _PyTime_MAX; - } - timeout = _PyTime_FromNanoseconds(ns); + // bpo-41710: PyThread_acquire_lock_timed() cannot report timeout + // overflow to the caller, so clamp the timeout to + // [_PyTime_MIN, _PyTime_MAX]. + // + // _PyTime_MAX nanoseconds is around 292.3 years. + // + // _thread.Lock.acquire() and _thread.RLock.acquire() raise an + // OverflowError if microseconds is greater than PY_TIMEOUT_MAX. + timeout = _PyTime_FromMicrosecondsClamp(microseconds); } else { timeout = _PyTime_FromNanoseconds(-1); @@ -506,7 +489,7 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, #ifndef HAVE_SEM_CLOCKWAIT if (timeout > 0) { /* wait interrupted by a signal (EINTR): recompute the timeout */ - _PyTime_t timeout = _PyDeadline_Get(deadline); + timeout = _PyDeadline_Get(deadline); if (timeout < 0) { status = ETIMEDOUT; break; @@ -544,8 +527,6 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, success = PY_LOCK_FAILURE; } - dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n", - lock, microseconds, intr_flag, success)); return success; } @@ -556,7 +537,6 @@ PyThread_release_lock(PyThread_type_lock lock) int status, error = 0; (void) error; /* silence unused-but-set-variable warning */ - dprintf(("PyThread_release_lock(%p) called\n", lock)); status = sem_post(thelock); CHECK_STATUS("sem_post"); @@ -573,7 +553,6 @@ PyThread_allocate_lock(void) pthread_lock *lock; int status, error = 0; - dprintf(("PyThread_allocate_lock called\n")); if (!initialized) PyThread_init_thread(); @@ -599,7 +578,6 @@ PyThread_allocate_lock(void) } } - dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock)); return (PyThread_type_lock) lock; } @@ -610,7 +588,6 @@ PyThread_free_lock(PyThread_type_lock lock) int status, error = 0; (void) error; /* silence unused-but-set-variable warning */ - dprintf(("PyThread_free_lock(%p) called\n", lock)); /* some pthread-like implementations tie the mutex to the cond * and must have the cond destroyed first. @@ -632,70 +609,81 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, pthread_lock *thelock = (pthread_lock *)lock; int status, error = 0; - dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n", - lock, microseconds, intr_flag)); - if (microseconds == 0) { status = pthread_mutex_trylock( &thelock->mut ); - if (status != EBUSY) + if (status != EBUSY) { CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]"); + } } else { status = pthread_mutex_lock( &thelock->mut ); CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]"); } - if (status == 0) { - if (thelock->locked == 0) { - success = PY_LOCK_ACQUIRED; - } - else if (microseconds != 0) { - struct timespec abs; - if (microseconds > 0) { - _PyThread_cond_after(microseconds, &abs); - } - /* continue trying until we get the lock */ - - /* mut must be locked by me -- part of the condition - * protocol */ - while (success == PY_LOCK_FAILURE) { - if (microseconds > 0) { - status = pthread_cond_timedwait( - &thelock->lock_released, - &thelock->mut, &abs); - if (status == 1) { - break; - } - if (status == ETIMEDOUT) - break; - CHECK_STATUS_PTHREAD("pthread_cond_timedwait"); - } - else { - status = pthread_cond_wait( - &thelock->lock_released, - &thelock->mut); - CHECK_STATUS_PTHREAD("pthread_cond_wait"); - } - - if (intr_flag && status == 0 && thelock->locked) { - /* We were woken up, but didn't get the lock. We probably received - * a signal. Return PY_LOCK_INTR to allow the caller to handle - * it and retry. */ - success = PY_LOCK_INTR; - break; - } - else if (status == 0 && !thelock->locked) { - success = PY_LOCK_ACQUIRED; - } - } - } - if (success == PY_LOCK_ACQUIRED) thelock->locked = 1; - status = pthread_mutex_unlock( &thelock->mut ); - CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]"); + if (status != 0) { + goto done; } - if (error) success = PY_LOCK_FAILURE; - dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n", - lock, microseconds, intr_flag, success)); + if (thelock->locked == 0) { + success = PY_LOCK_ACQUIRED; + goto unlock; + } + if (microseconds == 0) { + goto unlock; + } + + struct timespec abs_timeout; + if (microseconds > 0) { + _PyThread_cond_after(microseconds, &abs_timeout); + } + // Continue trying until we get the lock + + // mut must be locked by me -- part of the condition protocol + while (1) { + if (microseconds > 0) { + status = pthread_cond_timedwait(&thelock->lock_released, + &thelock->mut, &abs_timeout); + if (status == 1) { + break; + } + if (status == ETIMEDOUT) { + break; + } + CHECK_STATUS_PTHREAD("pthread_cond_timedwait"); + } + else { + status = pthread_cond_wait( + &thelock->lock_released, + &thelock->mut); + CHECK_STATUS_PTHREAD("pthread_cond_wait"); + } + + if (intr_flag && status == 0 && thelock->locked) { + // We were woken up, but didn't get the lock. We probably received + // a signal. Return PY_LOCK_INTR to allow the caller to handle + // it and retry. + success = PY_LOCK_INTR; + break; + } + + if (status == 0 && !thelock->locked) { + success = PY_LOCK_ACQUIRED; + break; + } + + // Wait got interrupted by a signal: retry + } + +unlock: + if (success == PY_LOCK_ACQUIRED) { + thelock->locked = 1; + } + status = pthread_mutex_unlock( &thelock->mut ); + CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]"); + +done: + if (error) { + success = PY_LOCK_FAILURE; + } return success; } @@ -706,7 +694,6 @@ PyThread_release_lock(PyThread_type_lock lock) int status, error = 0; (void) error; /* silence unused-but-set-variable warning */ - dprintf(("PyThread_release_lock(%p) called\n", lock)); status = pthread_mutex_lock( &thelock->mut ); CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]"); @@ -764,7 +751,7 @@ _pythread_pthread_set_stacksize(size_t size) /* set to default */ if (size == 0) { - _PyInterpreterState_GET()->pythread_stacksize = 0; + _PyInterpreterState_GET()->threads.stacksize = 0; return 0; } @@ -781,7 +768,7 @@ _pythread_pthread_set_stacksize(size_t size) rc = pthread_attr_setstacksize(&attrs, size); pthread_attr_destroy(&attrs); if (rc == 0) { - _PyInterpreterState_GET()->pythread_stacksize = size; + _PyInterpreterState_GET()->threads.stacksize = size; return 0; } } diff --git a/Python/thread_pthread_stubs.h b/Python/thread_pthread_stubs.h new file mode 100644 index 00000000000..56e5b614192 --- /dev/null +++ b/Python/thread_pthread_stubs.h @@ -0,0 +1,182 @@ +#include "cpython/pthread_stubs.h" + +// mutex +int +pthread_mutex_init(pthread_mutex_t *restrict mutex, + const pthread_mutexattr_t *restrict attr) +{ + return 0; +} + +int +pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + return 0; +} + +int +pthread_mutex_trylock(pthread_mutex_t *mutex) +{ + return 0; +} + +int +pthread_mutex_lock(pthread_mutex_t *mutex) +{ + return 0; +} + +int +pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + return 0; +} + +// condition +int +pthread_cond_init(pthread_cond_t *restrict cond, + const pthread_condattr_t *restrict attr) +{ + return 0; +} + +PyAPI_FUNC(int)pthread_cond_destroy(pthread_cond_t *cond) +{ + return 0; +} + +int +pthread_cond_wait(pthread_cond_t *restrict cond, + pthread_mutex_t *restrict mutex) +{ + return 0; +} + +int +pthread_cond_timedwait(pthread_cond_t *restrict cond, + pthread_mutex_t *restrict mutex, + const struct timespec *restrict abstime) +{ + return 0; +} + +int +pthread_cond_signal(pthread_cond_t *cond) +{ + return 0; +} + +int +pthread_condattr_init(pthread_condattr_t *attr) +{ + return 0; +} + +int +pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id) +{ + return 0; +} + +// pthread +int +pthread_create(pthread_t *restrict thread, + const pthread_attr_t *restrict attr, + void *(*start_routine)(void *), + void *restrict arg) +{ + return EAGAIN; +} + +int +pthread_detach(pthread_t thread) +{ + return 0; +} + +PyAPI_FUNC(pthread_t) pthread_self(void) +{ + return 0; +} + +int +pthread_exit(void *retval) +{ + exit(0); +} + +int +pthread_attr_init(pthread_attr_t *attr) +{ + return 0; +} + +int +pthread_attr_setstacksize( + pthread_attr_t *attr, size_t stacksize) +{ + return 0; +} + +int +pthread_attr_destroy(pthread_attr_t *attr) +{ + return 0; +} + + +typedef struct py_stub_tls_entry py_tls_entry; + +#define py_tls_entries (_PyRuntime.threads.stubs.tls_entries) + +int +pthread_key_create(pthread_key_t *key, void (*destr_function)(void *)) +{ + if (!key) { + return EINVAL; + } + if (destr_function != NULL) { + Py_FatalError("pthread_key_create destructor is not supported"); + } + for (pthread_key_t idx = 0; idx < PTHREAD_KEYS_MAX; idx++) { + if (!py_tls_entries[idx].in_use) { + py_tls_entries[idx].in_use = true; + *key = idx; + return 0; + } + } + return EAGAIN; +} + +int +pthread_key_delete(pthread_key_t key) +{ + if (key < 0 || key >= PTHREAD_KEYS_MAX || !py_tls_entries[key].in_use) { + return EINVAL; + } + py_tls_entries[key].in_use = false; + py_tls_entries[key].value = NULL; + return 0; +} + + +void * +pthread_getspecific(pthread_key_t key) { + if (key < 0 || key >= PTHREAD_KEYS_MAX || !py_tls_entries[key].in_use) { + return NULL; + } + return py_tls_entries[key].value; +} + +int +pthread_setspecific(pthread_key_t key, const void *value) +{ + if (key < 0 || key >= PTHREAD_KEYS_MAX || !py_tls_entries[key].in_use) { + return EINVAL; + } + py_tls_entries[key].value = (void *)value; + return 0; +} + +// let thread_pthread define the Python API +#include "thread_pthread.h" diff --git a/Python/traceback.c b/Python/traceback.c index 8aef3d810d3..da26c9b260a 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -3,9 +3,8 @@ #include "Python.h" -#include "code.h" // PyCode_Addr2Line etc -#include "frameobject.h" // PyFrame_GetBack() #include "pycore_ast.h" // asdl_seq_* +#include "pycore_call.h" // _PyObject_CallMethodFormat() #include "pycore_compile.h" // _PyAST_Optimize #include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH #include "pycore_frame.h" // _PyFrame_GetCode() @@ -15,7 +14,9 @@ #include "pycore_pyerrors.h" // _PyErr_Fetch() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_traceback.h" // EXCEPTION_TB_HEADER + #include "../Parser/pegen.h" // _PyPegen_byte_offset_to_character_offset() +#include "frameobject.h" // PyFrame_New() #include "structmember.h" // PyMemberDef #include "osdefs.h" // SEP #ifdef HAVE_FCNTL_H @@ -32,11 +33,6 @@ /* Function from Parser/tokenizer.c */ extern char* _PyTokenizer_FindEncodingFilename(int, PyObject *); -_Py_IDENTIFIER(TextIOWrapper); -_Py_IDENTIFIER(close); -_Py_IDENTIFIER(open); -_Py_IDENTIFIER(path); - /*[clinic input] class TracebackType "PyTracebackObject *" "&PyTraceback_Type" [clinic start generated code]*/ @@ -56,10 +52,8 @@ tb_create_raw(PyTracebackObject *next, PyFrameObject *frame, int lasti, } tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type); if (tb != NULL) { - Py_XINCREF(next); - tb->tb_next = next; - Py_XINCREF(frame); - tb->tb_frame = frame; + tb->tb_next = (PyTracebackObject*)Py_XNewRef(next); + tb->tb_frame = (PyFrameObject*)Py_XNewRef(frame); tb->tb_lasti = lasti; tb->tb_lineno = lineno; PyObject_GC_Track(tb); @@ -110,8 +104,7 @@ tb_next_get(PyTracebackObject *self, void *Py_UNUSED(_)) if (!ret) { ret = Py_None; } - Py_INCREF(ret); - return ret; + return Py_NewRef(ret); } static int @@ -143,17 +136,14 @@ tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_)) cursor = cursor->tb_next; } - PyObject *old_next = (PyObject*)self->tb_next; - Py_XINCREF(new_next); - self->tb_next = (PyTracebackObject *)new_next; - Py_XDECREF(old_next); + Py_XSETREF(self->tb_next, (PyTracebackObject *)Py_XNewRef(new_next)); return 0; } static PyMethodDef tb_methods[] = { - {"__dir__", (PyCFunction)tb_dir, METH_NOARGS}, + {"__dir__", _PyCFunction_CAST(tb_dir), METH_NOARGS}, {NULL, NULL, 0, NULL}, }; @@ -243,8 +233,8 @@ _PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame) { assert(tb_next == NULL || PyTraceBack_Check(tb_next)); assert(frame != NULL); - - return tb_create_raw((PyTracebackObject *)tb_next, frame, frame->f_frame->f_lasti*sizeof(_Py_CODEUNIT), + int addr = _PyInterpreterFrame_LASTI(frame->f_frame) * sizeof(_Py_CODEUNIT); + return tb_create_raw((PyTracebackObject *)tb_next, frame, addr, PyFrame_GetLineNumber(frame)); } @@ -317,6 +307,7 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject * const char* filepath; Py_ssize_t len; PyObject* result; + PyObject *open = NULL; filebytes = PyUnicode_EncodeFSDefault(filename); if (filebytes == NULL) { @@ -333,11 +324,13 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject * tail++; taillen = strlen(tail); - syspath = _PySys_GetObjectId(&PyId_path); + PyThreadState *tstate = _PyThreadState_GET(); + syspath = _PySys_GetAttr(tstate, &_Py_ID(path)); if (syspath == NULL || !PyList_Check(syspath)) goto error; npath = PyList_Size(syspath); + open = PyObject_GetAttr(io, &_Py_ID(open)); for (i = 0; i < npath; i++) { v = PyList_GetItem(syspath, i); if (v == NULL) { @@ -364,7 +357,7 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject * namebuf[len++] = SEP; strcpy(namebuf+len, tail); - binary = _PyObject_CallMethodId(io, &PyId_open, "ss", namebuf, "rb"); + binary = _PyObject_CallMethodFormat(tstate, open, "ss", namebuf, "rb"); if (binary != NULL) { result = binary; goto finally; @@ -376,6 +369,7 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject * error: result = NULL; finally: + Py_XDECREF(open); Py_DECREF(filebytes); return result; } @@ -385,16 +379,14 @@ finally: int _Py_WriteIndent(int indent, PyObject *f) { - int err = 0; char buf[11] = " "; assert(strlen(buf) == 10); while (indent > 0) { if (indent < 10) { buf[indent] = '\0'; } - err = PyFile_WriteString(buf, f); - if (err != 0) { - return err; + if (PyFile_WriteString(buf, f) < 0) { + return -1; } indent -= 10; } @@ -407,11 +399,15 @@ _Py_WriteIndent(int indent, PyObject *f) int _Py_WriteIndentedMargin(int indent, const char *margin, PyObject *f) { - int err = _Py_WriteIndent(indent, f); - if (err == 0 && margin) { - err = PyFile_WriteString(margin, f); + if (_Py_WriteIndent(indent, f) < 0) { + return -1; } - return err; + if (margin) { + if (PyFile_WriteString(margin, f) < 0) { + return -1; + } + } + return 0; } static int @@ -419,7 +415,6 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int int margin_indent, const char *margin, int *truncation, PyObject **line) { - int err = 0; int fd; int i; char *found_encoding; @@ -446,11 +441,12 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int } } - io = PyImport_ImportModuleNoBlock("io"); - if (io == NULL) + io = PyImport_ImportModule("io"); + if (io == NULL) { return -1; - binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb"); + } + binary = _PyObject_CallMethod(io, &_Py_ID(open), "Os", filename, "rb"); if (binary == NULL) { PyErr_Clear(); @@ -479,14 +475,15 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int PyMem_Free(found_encoding); return 0; } - fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding); + fob = _PyObject_CallMethod(io, &_Py_ID(TextIOWrapper), + "Os", binary, encoding); Py_DECREF(io); PyMem_Free(found_encoding); if (fob == NULL) { PyErr_Clear(); - res = _PyObject_CallMethodIdNoArgs(binary, &PyId_close); + res = PyObject_CallMethodNoArgs(binary, &_Py_ID(close)); Py_DECREF(binary); if (res) Py_DECREF(res); @@ -502,24 +499,24 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int lineobj = PyFile_GetLine(fob, -1); if (!lineobj) { PyErr_Clear(); - err = -1; break; } } - res = _PyObject_CallMethodIdNoArgs(fob, &PyId_close); - if (res) + res = PyObject_CallMethodNoArgs(fob, &_Py_ID(close)); + if (res) { Py_DECREF(res); - else + } + else { PyErr_Clear(); + } Py_DECREF(fob); if (!lineobj || !PyUnicode_Check(lineobj)) { Py_XDECREF(lineobj); - return err; + return -1; } if (line) { - Py_INCREF(lineobj); - *line = lineobj; + *line = Py_NewRef(lineobj); } /* remove the indentation of the line */ @@ -534,8 +531,7 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int PyObject *truncated; truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj)); if (truncated) { - Py_DECREF(lineobj); - lineobj = truncated; + Py_SETREF(lineobj, truncated); } else { PyErr_Clear(); } @@ -545,23 +541,29 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int *truncation = i - indent; } - if (err == 0) { - err = _Py_WriteIndentedMargin(margin_indent, margin, f); + if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) { + goto error; } + /* Write some spaces before the line */ - if (err == 0) { - err = _Py_WriteIndent(indent, f); + if (_Py_WriteIndent(indent, f) < 0) { + goto error; } /* finally display the line */ - if (err == 0) { - err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW); + if (PyFile_WriteObject(lineobj, f, Py_PRINT_RAW) < 0) { + goto error; } + + if (PyFile_WriteString("\n", f) < 0) { + goto error; + } + Py_DECREF(lineobj); - if (err == 0) { - err = PyFile_WriteString("\n", f); - } - return err; + return 0; +error: + Py_DECREF(lineobj); + return -1; } int @@ -582,7 +584,6 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent, * Traceback (most recent call last): * File "/home/isidentical/cpython/cpython/t.py", line 10, in * add_values(1, 2, 'x', 3, 4) - * ^^^^^^^^^^^^^^^^^^^^^^^^^^^ * File "/home/isidentical/cpython/cpython/t.py", line 2, in add_values * return a + b + c + d + e * ~~~~~~^~~ @@ -696,8 +697,13 @@ extract_anchors_from_line(PyObject *filename, PyObject *line, done: if (res > 0) { - *left_anchor += start_offset; - *right_anchor += start_offset; + // Normalize the AST offsets to byte offsets and adjust them with the + // start of the actual line (instead of the source code segment). + assert(segment != NULL); + assert(*left_anchor >= 0); + assert(*right_anchor >= 0); + *left_anchor = _PyPegen_byte_offset_to_character_offset(segment, *left_anchor) + start_offset; + *right_anchor = _PyPegen_byte_offset_to_character_offset(segment, *right_anchor) + start_offset; } Py_XDECREF(segment); if (arena) { @@ -723,41 +729,51 @@ static inline int print_error_location_carets(PyObject *f, int offset, Py_ssize_t start_offset, Py_ssize_t end_offset, Py_ssize_t right_start_offset, Py_ssize_t left_end_offset, const char *primary, const char *secondary) { - int err = 0; int special_chars = (left_end_offset != -1 || right_start_offset != -1); + const char *str; while (++offset <= end_offset) { - if (offset <= start_offset || offset > end_offset) { - err = PyFile_WriteString(" ", f); + if (offset <= start_offset) { + str = " "; } else if (special_chars && left_end_offset < offset && offset <= right_start_offset) { - err = PyFile_WriteString(secondary, f); + str = secondary; } else { - err = PyFile_WriteString(primary, f); + str = primary; + } + if (PyFile_WriteString(str, f) < 0) { + return -1; } } - err = PyFile_WriteString("\n", f); - return err; + if (PyFile_WriteString("\n", f) < 0) { + return -1; + } + return 0; } static int tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int lineno, PyFrameObject *frame, PyObject *name, int margin_indent, const char *margin) { - int err; - PyObject *line; - - if (filename == NULL || name == NULL) + if (filename == NULL || name == NULL) { return -1; - line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n", - filename, lineno, name); - if (line == NULL) - return -1; - err = _Py_WriteIndentedMargin(margin_indent, margin, f); - if (err == 0) { - err = PyFile_WriteObject(line, f, Py_PRINT_RAW); } + + if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) { + return -1; + } + + PyObject *line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n", + filename, lineno, name); + if (line == NULL) { + return -1; + } + + int res = PyFile_WriteObject(line, f, Py_PRINT_RAW); Py_DECREF(line); - if (err != 0) - return err; + if (res < 0) { + return -1; + } + + int err = 0; int truncation = _TRACEBACK_SOURCE_LINE_INDENT; PyObject* source_line = NULL; @@ -772,6 +788,7 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen int code_offset = tb->tb_lasti; PyCodeObject* code = frame->f_frame->f_code; + const Py_ssize_t source_line_len = PyUnicode_GET_LENGTH(source_line); int start_line; int end_line; @@ -793,7 +810,7 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen // // ERROR LINE ERROR LINE ERROR LINE ERROR LINE ERROR LINE ERROR LINE ERROR LINE // ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^~~~~~~~~~~~~~~~~~~~ - // | |-> left_end_offset | |-> left_offset + // | |-> left_end_offset | |-> end_offset // |-> start_offset |-> right_start_offset // // In general we will only have (start_offset, end_offset) but we can gather more information @@ -802,6 +819,9 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen // the different ranges (primary_error_char and secondary_error_char). If we cannot obtain the // AST information or we cannot identify special ranges within it, then left_end_offset and // right_end_offset will be set to -1. + // + // To keep the column indicators pertinent, they are not shown when the primary character + // spans the whole line. // Convert the utf-8 byte offset to the actual character offset so we print the right number of carets. assert(source_line); @@ -839,7 +859,7 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen goto done; } - Py_ssize_t i = PyUnicode_GET_LENGTH(source_line); + Py_ssize_t i = source_line_len; while (--i >= 0) { if (!IS_WHITESPACE(source_line_str[i])) { break; @@ -849,11 +869,23 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen end_offset = i + 1; } - err = _Py_WriteIndentedMargin(margin_indent, margin, f); - if (err == 0) { - err = print_error_location_carets(f, truncation, start_offset, end_offset, - right_start_offset, left_end_offset, - primary_error_char, secondary_error_char); + // Elide indicators if primary char spans the frame line + Py_ssize_t stripped_line_len = source_line_len - truncation - _TRACEBACK_SOURCE_LINE_INDENT; + bool has_secondary_ranges = (left_end_offset != -1 || right_start_offset != -1); + if (end_offset - start_offset == stripped_line_len && !has_secondary_ranges) { + goto done; + } + + if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) { + err = -1; + goto done; + } + + if (print_error_location_carets(f, truncation, start_offset, end_offset, + right_start_offset, left_end_offset, + primary_error_char, secondary_error_char) < 0) { + err = -1; + goto done; } done: @@ -884,7 +916,7 @@ static int tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit, int indent, const char *margin) { - int err = 0; + PyCodeObject *code = NULL; Py_ssize_t depth = 0; PyObject *last_file = NULL; int last_line = -1; @@ -899,14 +931,16 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit, depth--; tb = tb->tb_next; } - while (tb != NULL && err == 0) { - PyCodeObject *code = PyFrame_GetCode(tb->tb_frame); + while (tb != NULL) { + code = PyFrame_GetCode(tb->tb_frame); if (last_file == NULL || code->co_filename != last_file || last_line == -1 || tb->tb_lineno != last_line || last_name == NULL || code->co_name != last_name) { if (cnt > TB_RECURSIVE_CUTOFF) { - err = tb_print_line_repeated(f, cnt); + if (tb_print_line_repeated(f, cnt) < 0) { + goto error; + } } last_file = code->co_filename; last_line = tb->tb_lineno; @@ -914,20 +948,28 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit, cnt = 0; } cnt++; - if (err == 0 && cnt <= TB_RECURSIVE_CUTOFF) { - err = tb_displayline(tb, f, code->co_filename, tb->tb_lineno, - tb->tb_frame, code->co_name, indent, margin); - if (err == 0) { - err = PyErr_CheckSignals(); + if (cnt <= TB_RECURSIVE_CUTOFF) { + if (tb_displayline(tb, f, code->co_filename, tb->tb_lineno, + tb->tb_frame, code->co_name, indent, margin) < 0) { + goto error; + } + + if (PyErr_CheckSignals() < 0) { + goto error; } } - Py_DECREF(code); + Py_CLEAR(code); tb = tb->tb_next; } - if (err == 0 && cnt > TB_RECURSIVE_CUTOFF) { - err = tb_print_line_repeated(f, cnt); + if (cnt > TB_RECURSIVE_CUTOFF) { + if (tb_print_line_repeated(f, cnt) < 0) { + goto error; + } } - return err; + return 0; +error: + Py_XDECREF(code); + return -1; } #define PyTraceBack_LIMIT 1000 @@ -936,12 +978,12 @@ int _PyTraceBack_Print_Indented(PyObject *v, int indent, const char *margin, const char *header_margin, const char *header, PyObject *f) { - int err; PyObject *limitv; long limit = PyTraceBack_LIMIT; - if (v == NULL) + if (v == NULL) { return 0; + } if (!PyTraceBack_Check(v)) { PyErr_BadInternalCall(); return -1; @@ -957,14 +999,19 @@ _PyTraceBack_Print_Indented(PyObject *v, int indent, const char *margin, return 0; } } - err = _Py_WriteIndentedMargin(indent, header_margin, f); - if (err == 0) { - err = PyFile_WriteString(header, f); + if (_Py_WriteIndentedMargin(indent, header_margin, f) < 0) { + return -1; } - if (err == 0) { - err = tb_printinternal((PyTracebackObject *)v, f, limit, indent, margin); + + if (PyFile_WriteString(header, f) < 0) { + return -1; } - return err; + + if (tb_printinternal((PyTracebackObject *)v, f, limit, indent, margin) < 0) { + return -1; + } + + return 0; } int @@ -1033,12 +1080,11 @@ _Py_DumpHexadecimal(int fd, uintptr_t value, Py_ssize_t width) void _Py_DumpASCII(int fd, PyObject *text) { - PyASCIIObject *ascii = (PyASCIIObject *)text; + PyASCIIObject *ascii = _PyASCIIObject_CAST(text); Py_ssize_t i, size; int truncated; int kind; void *data = NULL; - wchar_t *wstr = NULL; Py_UCS4 ch; if (!PyUnicode_Check(text)) @@ -1046,20 +1092,14 @@ _Py_DumpASCII(int fd, PyObject *text) size = ascii->length; kind = ascii->state.kind; - if (kind == PyUnicode_WCHAR_KIND) { - wstr = ((PyASCIIObject *)text)->wstr; - if (wstr == NULL) - return; - size = ((PyCompactUnicodeObject *)text)->wstr_length; - } - else if (ascii->state.compact) { + if (ascii->state.compact) { if (ascii->state.ascii) - data = ((PyASCIIObject*)text) + 1; + data = ascii + 1; else - data = ((PyCompactUnicodeObject*)text) + 1; + data = _PyCompactUnicodeObject_CAST(text) + 1; } else { - data = ((PyUnicodeObject *)text)->data.any; + data = _PyUnicodeObject_CAST(text)->data.any; if (data == NULL) return; } @@ -1093,10 +1133,7 @@ _Py_DumpASCII(int fd, PyObject *text) } for (i=0; i < size; i++) { - if (kind != PyUnicode_WCHAR_KIND) - ch = PyUnicode_READ(kind, data, i); - else - ch = wstr[i]; + ch = PyUnicode_READ(kind, data, i); if (' ' <= ch && ch <= 126) { /* printable ASCII character */ char c = (char)ch; @@ -1127,7 +1164,7 @@ done: This function is signal safe. */ static void -dump_frame(int fd, InterpreterFrame *frame) +dump_frame(int fd, _PyInterpreterFrame *frame) { PyCodeObject *code = frame->f_code; PUTS(fd, " File "); @@ -1141,7 +1178,7 @@ dump_frame(int fd, InterpreterFrame *frame) PUTS(fd, "???"); } - int lineno = PyCode_Addr2Line(code, frame->f_lasti*sizeof(_Py_CODEUNIT)); + int lineno = _PyInterpreterFrame_GetLine(frame); PUTS(fd, ", line "); if (lineno >= 0) { _Py_DumpDecimal(fd, (size_t)lineno); @@ -1165,7 +1202,7 @@ dump_frame(int fd, InterpreterFrame *frame) static void dump_traceback(int fd, PyThreadState *tstate, int write_header) { - InterpreterFrame *frame; + _PyInterpreterFrame *frame; unsigned int depth; if (write_header) { @@ -1189,6 +1226,15 @@ dump_traceback(int fd, PyThreadState *tstate, int write_header) if (frame == NULL) { break; } + if (frame->owner == FRAME_OWNED_BY_CSTACK) { + /* Trampoline frame */ + frame = frame->previous; + } + if (frame == NULL) { + break; + } + /* Can't have more than one shim frame in a row */ + assert(frame->owner != FRAME_OWNED_BY_CSTACK); depth++; } } diff --git a/Python/wordcode_helpers.h b/Python/wordcode_helpers.h deleted file mode 100644 index c8f7a0f41f9..00000000000 --- a/Python/wordcode_helpers.h +++ /dev/null @@ -1,44 +0,0 @@ -/* This file contains code shared by the compiler and the peephole - optimizer. - */ - -#ifdef WORDS_BIGENDIAN -# define PACKOPARG(opcode, oparg) ((_Py_CODEUNIT)(((opcode) << 8) | (oparg))) -#else -# define PACKOPARG(opcode, oparg) ((_Py_CODEUNIT)(((oparg) << 8) | (opcode))) -#endif - -/* Minimum number of code units necessary to encode instruction with - EXTENDED_ARGs */ -static int -instrsize(unsigned int oparg) -{ - return oparg <= 0xff ? 1 : - oparg <= 0xffff ? 2 : - oparg <= 0xffffff ? 3 : - 4; -} - -/* Spits out op/oparg pair using ilen bytes. codestr should be pointed at the - desired location of the first EXTENDED_ARG */ -static void -write_op_arg(_Py_CODEUNIT *codestr, unsigned char opcode, - unsigned int oparg, int ilen) -{ - switch (ilen) { - case 4: - *codestr++ = PACKOPARG(EXTENDED_ARG, (oparg >> 24) & 0xff); - /* fall through */ - case 3: - *codestr++ = PACKOPARG(EXTENDED_ARG, (oparg >> 16) & 0xff); - /* fall through */ - case 2: - *codestr++ = PACKOPARG(EXTENDED_ARG, (oparg >> 8) & 0xff); - /* fall through */ - case 1: - *codestr++ = PACKOPARG(opcode, oparg & 0xff); - break; - default: - Py_UNREACHABLE(); - } -} diff --git a/README.rst b/README.rst index d43f6fabae3..814efef83a3 100644 --- a/README.rst +++ b/README.rst @@ -1,10 +1,6 @@ -This is Python version 3.11.0 alpha 2 +This is Python version 3.12.0 alpha 4 ===================================== -.. image:: https://travis-ci.com/python/cpython.svg?branch=main - :alt: CPython build status on Travis CI - :target: https://travis-ci.com/python/cpython - .. image:: https://github.com/python/cpython/workflows/Tests/badge.svg :alt: CPython build status on GitHub Actions :target: https://github.com/python/cpython/actions @@ -18,7 +14,7 @@ This is Python version 3.11.0 alpha 2 :target: https://discuss.python.org/ -Copyright (c) 2001-2021 Python Software Foundation. All rights reserved. +Copyright © 2001-2023 Python Software Foundation. All rights reserved. See the end of this file for further copyright and license information. @@ -29,7 +25,7 @@ General Information - Website: https://www.python.org - Source code: https://github.com/python/cpython -- Issue tracker: https://bugs.python.org +- Issue tracker: https://github.com/python/cpython/issues - Documentation: https://docs.python.org - Developer's Guide: https://devguide.python.org/ @@ -69,7 +65,7 @@ Building a complete Python installation requires the use of various additional third-party libraries, depending on your build platform and configure options. Not all standard library modules are buildable or useable on all platforms. Refer to the -`Install dependencies `_ +`Install dependencies `_ section of the `Developer Guide`_ for current detailed information on dependencies for various Linux distributions and macOS. @@ -137,9 +133,9 @@ What's New ---------- We have a comprehensive overview of the changes in the `What's New in Python -3.10 `_ document. For a more +3.12 `_ document. For a more detailed change log, read `Misc/NEWS -`_, but a full +`_, but a full accounting of changes can only be gleaned from the `commit history `_. @@ -150,7 +146,7 @@ entitled "Installing multiple versions". Documentation ------------- -`Documentation for Python 3.10 `_ is online, +`Documentation for Python 3.12 `_ is online, updated daily. It can also be downloaded in many formats for faster access. The documentation @@ -189,10 +185,11 @@ example, if ``test_os`` and ``test_gdb`` failed, you can run:: make test TESTOPTS="-v test_os test_gdb" If the failure persists and appears to be a problem with Python rather than -your environment, you can `file a bug report `_ and -include relevant output from that command to show the issue. +your environment, you can `file a bug report +`_ and include relevant output from +that command to show the issue. -See `Running & Writing Tests `_ +See `Running & Writing Tests `_ for more on running tests. Installing multiple versions @@ -204,22 +201,22 @@ script) you must take care that your primary python executable is not overwritten by the installation of a different version. All files and directories installed using ``make altinstall`` contain the major and minor version and can thus live side-by-side. ``make install`` also creates -``${prefix}/bin/python3`` which refers to ``${prefix}/bin/pythonX.Y``. If you +``${prefix}/bin/python3`` which refers to ``${prefix}/bin/python3.X``. If you intend to install multiple versions using the same prefix you must decide which version (if any) is your "primary" version. Install that version using ``make install``. Install all other versions using ``make altinstall``. -For example, if you want to install Python 2.7, 3.6, and 3.10 with 3.10 being the -primary version, you would execute ``make install`` in your 3.10 build directory +For example, if you want to install Python 2.7, 3.6, and 3.12 with 3.12 being the +primary version, you would execute ``make install`` in your 3.12 build directory and ``make altinstall`` in the others. Issue Tracker and Mailing List ------------------------------ -Bug reports are welcome! You can use the `issue tracker -`_ to report bugs, and/or submit pull requests `on -GitHub `_. +Bug reports are welcome! You can use Github to `report bugs +`_, and/or `submit pull requests +`_. You can also follow development discussion on the `python-dev mailing list `_. @@ -232,7 +229,7 @@ If you have a proposal to change Python, you may want to send an email to the `comp.lang.python`_ or `python-ideas`_ mailing lists for initial feedback. A Python Enhancement Proposal (PEP) may be submitted if your idea gains ground. All current PEPs, as well as guidelines for submitting a new PEP, are listed at -`python.org/dev/peps/ `_. +`peps.python.org `_. .. _python-ideas: https://mail.python.org/mailman/listinfo/python-ideas/ .. _comp.lang.python: https://mail.python.org/mailman/listinfo/python-list @@ -241,20 +238,21 @@ All current PEPs, as well as guidelines for submitting a new PEP, are listed at Release Schedule ---------------- -See :pep:`664` for Python 3.11 release details. +See :pep:`693` for Python 3.12 release details. Copyright and License Information --------------------------------- -Copyright (c) 2001-2021 Python Software Foundation. All rights reserved. -Copyright (c) 2000 BeOpen.com. All rights reserved. +Copyright © 2001-2023 Python Software Foundation. All rights reserved. -Copyright (c) 1995-2001 Corporation for National Research Initiatives. All +Copyright © 2000 BeOpen.com. All rights reserved. + +Copyright © 1995-2001 Corporation for National Research Initiatives. All rights reserved. -Copyright (c) 1991-1995 Stichting Mathematisch Centrum. All rights reserved. +Copyright © 1991-1995 Stichting Mathematisch Centrum. All rights reserved. See the `LICENSE `_ for information on the history of this software, terms & conditions for usage, and a diff --git a/Tools/README b/Tools/README index 1f9d927fb61..04612b8013d 100644 --- a/Tools/README +++ b/Tools/README @@ -5,8 +5,6 @@ buildbot Batchfiles for running on Windows buildbot workers. ccbench A Python threads-based concurrency benchmark. (*) -demo Several Python programming demos. - freeze Create a stand-alone executable from a Python program. gdb Python code to be run inside gdb, to make it easier to @@ -25,8 +23,6 @@ parser Un-parsing tool to generate code from an AST. peg_generator PEG-based parser generator (pegen) used for new parser. -pynche A Tkinter-based color editor. - scripts A number of useful single-file programs, e.g. tabnanny.py by Tim Peters, which checks for inconsistent mixing of tabs and spaces, and 2to3, which converts Python 2 code @@ -44,3 +40,5 @@ unittestgui A Tkinter based GUI test runner for unittest, with test (*) A generic benchmark suite is maintained separately at https://github.com/python/performance + +Note: The pynche color editor has moved to https://gitlab.com/warsaw/pynche diff --git a/Tools/build/check_extension_modules.py b/Tools/build/check_extension_modules.py new file mode 100644 index 00000000000..59239c62e2e --- /dev/null +++ b/Tools/build/check_extension_modules.py @@ -0,0 +1,484 @@ +"""Check extension modules + +The script checks shared and built-in extension modules. It verifies that the +modules have been built and that they can be imported successfully. Missing +modules and failed imports are reported to the user. Shared extension +files are renamed on failed import. + +Module information is parsed from several sources: + +- core modules hard-coded in Modules/config.c.in +- Windows-specific modules that are hard-coded in PC/config.c +- MODULE_{name}_STATE entries in Makefile (provided through sysconfig) +- Various makesetup files: + - $(srcdir)/Modules/Setup + - Modules/Setup.[local|bootstrap|stdlib] files, which are generated + from $(srcdir)/Modules/Setup.*.in files + +See --help for more information +""" +import argparse +import collections +import enum +import logging +import os +import pathlib +import re +import sys +import sysconfig +import warnings + +from importlib._bootstrap import _load as bootstrap_load +from importlib.machinery import BuiltinImporter, ExtensionFileLoader, ModuleSpec +from importlib.util import spec_from_file_location, spec_from_loader +from typing import Iterable + +SRC_DIR = pathlib.Path(__file__).parent.parent.parent + +# core modules, hard-coded in Modules/config.h.in +CORE_MODULES = { + "_ast", + "_imp", + "_string", + "_tokenize", + "_warnings", + "builtins", + "gc", + "marshal", + "sys", +} + +# Windows-only modules +WINDOWS_MODULES = { + "_msi", + "_overlapped", + "_testconsole", + "_winapi", + "msvcrt", + "nt", + "winreg", + "winsound", +} + + +logger = logging.getLogger(__name__) + +parser = argparse.ArgumentParser( + prog="check_extension_modules", + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter, +) + +parser.add_argument( + "--verbose", + action="store_true", + help="Verbose, report builtin, shared, and unavailable modules", +) + +parser.add_argument( + "--debug", + action="store_true", + help="Enable debug logging", +) + +parser.add_argument( + "--strict", + action=argparse.BooleanOptionalAction, + help=( + "Strict check, fail when a module is missing or fails to import" + "(default: no, unless env var PYTHONSTRICTEXTENSIONBUILD is set)" + ), + default=bool(os.environ.get("PYTHONSTRICTEXTENSIONBUILD")), +) + +parser.add_argument( + "--cross-compiling", + action=argparse.BooleanOptionalAction, + help=( + "Use cross-compiling checks " + "(default: no, unless env var _PYTHON_HOST_PLATFORM is set)." + ), + default="_PYTHON_HOST_PLATFORM" in os.environ, +) + +parser.add_argument( + "--list-module-names", + action="store_true", + help="Print a list of module names to stdout and exit", +) + + +class ModuleState(enum.Enum): + # Makefile state "yes" + BUILTIN = "builtin" + SHARED = "shared" + + DISABLED = "disabled" + MISSING = "missing" + NA = "n/a" + # disabled by Setup / makesetup rule + DISABLED_SETUP = "disabled_setup" + + def __bool__(self): + return self.value in {"builtin", "shared"} + + +ModuleInfo = collections.namedtuple("ModuleInfo", "name state") + + +class ModuleChecker: + pybuilddir_txt = "pybuilddir.txt" + + setup_files = ( + # see end of configure.ac + "Modules/Setup.local", + "Modules/Setup.stdlib", + "Modules/Setup.bootstrap", + SRC_DIR / "Modules/Setup", + ) + + def __init__(self, cross_compiling: bool = False, strict: bool = False): + self.cross_compiling = cross_compiling + self.strict_extensions_build = strict + self.ext_suffix = sysconfig.get_config_var("EXT_SUFFIX") + self.platform = sysconfig.get_platform() + self.builddir = self.get_builddir() + self.modules = self.get_modules() + + self.builtin_ok = [] + self.shared_ok = [] + self.failed_on_import = [] + self.missing = [] + self.disabled_configure = [] + self.disabled_setup = [] + self.notavailable = [] + + def check(self): + for modinfo in self.modules: + logger.debug("Checking '%s' (%s)", modinfo.name, self.get_location(modinfo)) + if modinfo.state == ModuleState.DISABLED: + self.disabled_configure.append(modinfo) + elif modinfo.state == ModuleState.DISABLED_SETUP: + self.disabled_setup.append(modinfo) + elif modinfo.state == ModuleState.MISSING: + self.missing.append(modinfo) + elif modinfo.state == ModuleState.NA: + self.notavailable.append(modinfo) + else: + try: + if self.cross_compiling: + self.check_module_cross(modinfo) + else: + self.check_module_import(modinfo) + except (ImportError, FileNotFoundError): + self.rename_module(modinfo) + self.failed_on_import.append(modinfo) + else: + if modinfo.state == ModuleState.BUILTIN: + self.builtin_ok.append(modinfo) + else: + assert modinfo.state == ModuleState.SHARED + self.shared_ok.append(modinfo) + + def summary(self, *, verbose: bool = False): + longest = max([len(e.name) for e in self.modules], default=0) + + def print_three_column(modinfos: list[ModuleInfo]): + names = [modinfo.name for modinfo in modinfos] + names.sort(key=str.lower) + # guarantee zip() doesn't drop anything + while len(names) % 3: + names.append("") + for l, m, r in zip(names[::3], names[1::3], names[2::3]): + print("%-*s %-*s %-*s" % (longest, l, longest, m, longest, r)) + + if verbose and self.builtin_ok: + print("The following *built-in* modules have been successfully built:") + print_three_column(self.builtin_ok) + print() + + if verbose and self.shared_ok: + print("The following *shared* modules have been successfully built:") + print_three_column(self.shared_ok) + print() + + if self.disabled_configure: + print("The following modules are *disabled* in configure script:") + print_three_column(self.disabled_configure) + print() + + if self.disabled_setup: + print("The following modules are *disabled* in Modules/Setup files:") + print_three_column(self.disabled_setup) + print() + + if verbose and self.notavailable: + print( + f"The following modules are not available on platform '{self.platform}':" + ) + print_three_column(self.notavailable) + print() + + if self.missing: + print("The necessary bits to build these optional modules were not found:") + print_three_column(self.missing) + print("To find the necessary bits, look in configure.ac and config.log.") + print() + + if self.failed_on_import: + print( + "Following modules built successfully " + "but were removed because they could not be imported:" + ) + print_three_column(self.failed_on_import) + print() + + if any( + modinfo.name == "_ssl" for modinfo in self.missing + self.failed_on_import + ): + print("Could not build the ssl module!") + print("Python requires a OpenSSL 1.1.1 or newer") + if sysconfig.get_config_var("OPENSSL_LDFLAGS"): + print("Custom linker flags may require --with-openssl-rpath=auto") + print() + + disabled = len(self.disabled_configure) + len(self.disabled_setup) + print( + f"Checked {len(self.modules)} modules (" + f"{len(self.builtin_ok)} built-in, " + f"{len(self.shared_ok)} shared, " + f"{len(self.notavailable)} n/a on {self.platform}, " + f"{disabled} disabled, " + f"{len(self.missing)} missing, " + f"{len(self.failed_on_import)} failed on import)" + ) + + def check_strict_build(self): + """Fail if modules are missing and it's a strict build""" + if self.strict_extensions_build and (self.failed_on_import or self.missing): + raise RuntimeError("Failed to build some stdlib modules") + + def list_module_names(self, *, all: bool = False) -> set: + names = {modinfo.name for modinfo in self.modules} + if all: + names.update(WINDOWS_MODULES) + return names + + def get_builddir(self) -> pathlib.Path: + try: + with open(self.pybuilddir_txt, encoding="utf-8") as f: + builddir = f.read() + except FileNotFoundError: + logger.error("%s must be run from the top build directory", __file__) + raise + builddir = pathlib.Path(builddir) + logger.debug("%s: %s", self.pybuilddir_txt, builddir) + return builddir + + def get_modules(self) -> list[ModuleInfo]: + """Get module info from sysconfig and Modules/Setup* files""" + seen = set() + modules = [] + # parsing order is important, first entry wins + for modinfo in self.get_core_modules(): + modules.append(modinfo) + seen.add(modinfo.name) + for setup_file in self.setup_files: + for modinfo in self.parse_setup_file(setup_file): + if modinfo.name not in seen: + modules.append(modinfo) + seen.add(modinfo.name) + for modinfo in self.get_sysconfig_modules(): + if modinfo.name not in seen: + modules.append(modinfo) + seen.add(modinfo.name) + logger.debug("Found %i modules in total", len(modules)) + modules.sort() + return modules + + def get_core_modules(self) -> Iterable[ModuleInfo]: + """Get hard-coded core modules""" + for name in CORE_MODULES: + modinfo = ModuleInfo(name, ModuleState.BUILTIN) + logger.debug("Found core module %s", modinfo) + yield modinfo + + def get_sysconfig_modules(self) -> Iterable[ModuleInfo]: + """Get modules defined in Makefile through sysconfig + + MODBUILT_NAMES: modules in *static* block + MODSHARED_NAMES: modules in *shared* block + MODDISABLED_NAMES: modules in *disabled* block + """ + moddisabled = set(sysconfig.get_config_var("MODDISABLED_NAMES").split()) + if self.cross_compiling: + modbuiltin = set(sysconfig.get_config_var("MODBUILT_NAMES").split()) + else: + modbuiltin = set(sys.builtin_module_names) + + for key, value in sysconfig.get_config_vars().items(): + if not key.startswith("MODULE_") or not key.endswith("_STATE"): + continue + if value not in {"yes", "disabled", "missing", "n/a"}: + raise ValueError(f"Unsupported value '{value}' for {key}") + + modname = key[7:-6].lower() + if modname in moddisabled: + # Setup "*disabled*" rule + state = ModuleState.DISABLED_SETUP + elif value in {"disabled", "missing", "n/a"}: + state = ModuleState(value) + elif modname in modbuiltin: + assert value == "yes" + state = ModuleState.BUILTIN + else: + assert value == "yes" + state = ModuleState.SHARED + + modinfo = ModuleInfo(modname, state) + logger.debug("Found %s in Makefile", modinfo) + yield modinfo + + def parse_setup_file(self, setup_file: pathlib.Path) -> Iterable[ModuleInfo]: + """Parse a Modules/Setup file""" + assign_var = re.compile(r"^\w+=") # EGG_SPAM=foo + # default to static module + state = ModuleState.BUILTIN + logger.debug("Parsing Setup file %s", setup_file) + with open(setup_file, encoding="utf-8") as f: + for line in f: + line = line.strip() + if not line or line.startswith("#") or assign_var.match(line): + continue + match line.split(): + case ["*shared*"]: + state = ModuleState.SHARED + case ["*static*"]: + state = ModuleState.BUILTIN + case ["*disabled*"]: + state = ModuleState.DISABLED + case ["*noconfig*"]: + state = None + case [*items]: + if state == ModuleState.DISABLED: + # *disabled* can disable multiple modules per line + for item in items: + modinfo = ModuleInfo(item, state) + logger.debug("Found %s in %s", modinfo, setup_file) + yield modinfo + elif state in {ModuleState.SHARED, ModuleState.BUILTIN}: + # *shared* and *static*, first item is the name of the module. + modinfo = ModuleInfo(items[0], state) + logger.debug("Found %s in %s", modinfo, setup_file) + yield modinfo + + def get_spec(self, modinfo: ModuleInfo) -> ModuleSpec: + """Get ModuleSpec for builtin or extension module""" + if modinfo.state == ModuleState.SHARED: + location = os.fspath(self.get_location(modinfo)) + loader = ExtensionFileLoader(modinfo.name, location) + return spec_from_file_location(modinfo.name, location, loader=loader) + elif modinfo.state == ModuleState.BUILTIN: + return spec_from_loader(modinfo.name, loader=BuiltinImporter) + else: + raise ValueError(modinfo) + + def get_location(self, modinfo: ModuleInfo) -> pathlib.Path: + """Get shared library location in build directory""" + if modinfo.state == ModuleState.SHARED: + return self.builddir / f"{modinfo.name}{self.ext_suffix}" + else: + return None + + def _check_file(self, modinfo: ModuleInfo, spec: ModuleSpec): + """Check that the module file is present and not empty""" + if spec.loader is BuiltinImporter: + return + try: + st = os.stat(spec.origin) + except FileNotFoundError: + logger.error("%s (%s) is missing", modinfo.name, spec.origin) + raise + if not st.st_size: + raise ImportError(f"{spec.origin} is an empty file") + + def check_module_import(self, modinfo: ModuleInfo): + """Attempt to import module and report errors""" + spec = self.get_spec(modinfo) + self._check_file(modinfo, spec) + try: + with warnings.catch_warnings(): + # ignore deprecation warning from deprecated modules + warnings.simplefilter("ignore", DeprecationWarning) + bootstrap_load(spec) + except ImportError as e: + logger.error("%s failed to import: %s", modinfo.name, e) + raise + except Exception as e: + logger.exception("Importing extension '%s' failed!", modinfo.name) + raise + + def check_module_cross(self, modinfo: ModuleInfo): + """Sanity check for cross compiling""" + spec = self.get_spec(modinfo) + self._check_file(modinfo, spec) + + def rename_module(self, modinfo: ModuleInfo) -> None: + """Rename module file""" + if modinfo.state == ModuleState.BUILTIN: + logger.error("Cannot mark builtin module '%s' as failed!", modinfo.name) + return + + failed_name = f"{modinfo.name}_failed{self.ext_suffix}" + builddir_path = self.get_location(modinfo) + if builddir_path.is_symlink(): + symlink = builddir_path + module_path = builddir_path.resolve().relative_to(os.getcwd()) + failed_path = module_path.parent / failed_name + else: + symlink = None + module_path = builddir_path + failed_path = self.builddir / failed_name + + # remove old failed file + failed_path.unlink(missing_ok=True) + # remove symlink + if symlink is not None: + symlink.unlink(missing_ok=True) + # rename shared extension file + try: + module_path.rename(failed_path) + except FileNotFoundError: + logger.debug("Shared extension file '%s' does not exist.", module_path) + else: + logger.debug("Rename '%s' -> '%s'", module_path, failed_path) + + +def main(): + args = parser.parse_args() + if args.debug: + args.verbose = True + logging.basicConfig( + level=logging.DEBUG if args.debug else logging.INFO, + format="[%(levelname)s] %(message)s", + ) + + checker = ModuleChecker( + cross_compiling=args.cross_compiling, + strict=args.strict, + ) + if args.list_module_names: + names = checker.list_module_names(all=True) + for name in sorted(names): + print(name) + else: + checker.check() + checker.summary(verbose=args.verbose) + try: + checker.check_strict_build() + except RuntimeError as e: + parser.exit(1, f"\nError: {e}\n") + + +if __name__ == "__main__": + main() diff --git a/Tools/scripts/deepfreeze.py b/Tools/build/deepfreeze.py similarity index 58% rename from Tools/scripts/deepfreeze.py rename to Tools/build/deepfreeze.py index 074127f9492..511b26a5ce3 100644 --- a/Tools/scripts/deepfreeze.py +++ b/Tools/build/deepfreeze.py @@ -1,19 +1,37 @@ +"""Deep freeze + +The script may be executed by _bootstrap_python interpreter. +Shared library extension modules are not available in that case. +On Windows, and in cross-compilation cases, it is executed +by Python 3.10, and 3.11 features are not available. +""" import argparse +import ast import builtins import collections import contextlib import os -import sys +import re import time import types -import typing +from typing import Dict, FrozenSet, TextIO, Tuple + +import umarshal +from generate_global_objects import get_identifiers_and_strings verbose = False +identifiers, strings = get_identifiers_and_strings() + +# This must be kept in sync with opcode.py +RESUME = 151 + +def isprintable(b: bytes) -> bool: + return all(0x20 <= c < 0x7f for c in b) def make_string_literal(b: bytes) -> str: res = ['"'] - if b.isascii() and b.decode("ascii").isprintable(): + if isprintable(b): res.append(b.decode("ascii").replace("\\", "\\\\").replace("\"", "\\\"")) else: for i in b: @@ -26,6 +44,7 @@ CO_FAST_LOCAL = 0x20 CO_FAST_CELL = 0x40 CO_FAST_FREE = 0x80 +next_code_version = 1 def get_localsplus(code: types.CodeType): a = collections.defaultdict(int) @@ -39,27 +58,26 @@ def get_localsplus(code: types.CodeType): def get_localsplus_counts(code: types.CodeType, - names: tuple[str, ...], - kinds: bytes) -> tuple[int, int, int, int]: + names: Tuple[str, ...], + kinds: bytes) -> Tuple[int, int, int, int]: nlocals = 0 - nplaincellvars = 0 ncellvars = 0 nfreevars = 0 - for name, kind in zip(names, kinds, strict=True): + assert len(names) == len(kinds) + for name, kind in zip(names, kinds): if kind & CO_FAST_LOCAL: nlocals += 1 if kind & CO_FAST_CELL: ncellvars += 1 elif kind & CO_FAST_CELL: ncellvars += 1 - nplaincellvars += 1 elif kind & CO_FAST_FREE: nfreevars += 1 - assert nlocals == len(code.co_varnames) == code.co_nlocals + assert nlocals == len(code.co_varnames) == code.co_nlocals, \ + (nlocals, len(code.co_varnames), code.co_nlocals) assert ncellvars == len(code.co_cellvars) assert nfreevars == len(code.co_freevars) - assert len(names) == nlocals + nplaincellvars + nfreevars - return nlocals, nplaincellvars, ncellvars, nfreevars + return nlocals, ncellvars, nfreevars PyUnicode_1BYTE_KIND = 1 @@ -67,7 +85,7 @@ PyUnicode_2BYTE_KIND = 2 PyUnicode_4BYTE_KIND = 4 -def analyze_character_width(s: str) -> tuple[int, bool]: +def analyze_character_width(s: str) -> Tuple[int, bool]: maxchar = ' ' for c in s: maxchar = max(maxchar, c) @@ -82,17 +100,25 @@ def analyze_character_width(s: str) -> tuple[int, bool]: return kind, ascii +def removesuffix(base: str, suffix: str) -> str: + if base.endswith(suffix): + return base[:len(base) - len(suffix)] + return base + class Printer: - def __init__(self, file: typing.TextIO): + def __init__(self, file: TextIO) -> None: self.level = 0 self.file = file - self.cache: dict[tuple[type, object], str] = {} + self.cache: Dict[tuple[type, object, str], str] = {} self.hits, self.misses = 0, 0 - self.patchups: list[str] = [] + self.finis: list[str] = [] + self.inits: list[str] = [] self.write('#include "Python.h"') self.write('#include "internal/pycore_gc.h"') self.write('#include "internal/pycore_code.h"') + self.write('#include "internal/pycore_frame.h"') + self.write('#include "internal/pycore_long.h"') self.write("") @contextlib.contextmanager @@ -128,6 +154,10 @@ class Printer: self.write(f".{name} = {getattr(obj, name)},") def generate_bytes(self, name: str, b: bytes) -> str: + if b == b"": + return "(PyObject *)&_Py_SINGLETON(bytes_empty)" + if len(b) == 1: + return f"(PyObject *)&_Py_SINGLETON(bytes_characters[{b[0]}])" self.write("static") with self.indent(): with self.block("struct"): @@ -141,6 +171,12 @@ class Printer: return f"& {name}.ob_base.ob_base" def generate_unicode(self, name: str, s: str) -> str: + if s in strings: + return f"&_Py_STR({strings[s]})" + if s in identifiers: + return f"&_Py_ID({s})" + if re.match(r'\A[A-Za-z0-9_]+\Z', s): + name = f"const_str_{s}" kind, ascii = analyze_character_width(s) if kind == PyUnicode_1BYTE_KIND: datatype = "uint8_t" @@ -166,7 +202,6 @@ class Printer: self.write(".kind = 1,") self.write(".compact = 1,") self.write(".ascii = 1,") - self.write(".ready = 1,") self.write(f"._data = {make_string_literal(s.encode('ascii'))},") return f"& {name}._ascii.ob_base" else: @@ -179,83 +214,82 @@ class Printer: self.write(f".kind = {kind},") self.write(".compact = 1,") self.write(".ascii = 0,") - self.write(".ready = 1,") + utf8 = s.encode('utf-8') + self.write(f'.utf8 = {make_string_literal(utf8)},') + self.write(f'.utf8_length = {len(utf8)},') with self.block(f"._data =", ","): for i in range(0, len(s), 16): data = s[i:i+16] self.write(", ".join(map(str, map(ord, data))) + ",") - if kind == PyUnicode_2BYTE_KIND: - self.patchups.append("if (sizeof(wchar_t) == 2) {") - self.patchups.append(f" {name}._compact._base.wstr = (wchar_t *) {name}._data;") - self.patchups.append(f" {name}._compact.wstr_length = {len(s)};") - self.patchups.append("}") - if kind == PyUnicode_4BYTE_KIND: - self.patchups.append("if (sizeof(wchar_t) == 4) {") - self.patchups.append(f" {name}._compact._base.wstr = (wchar_t *) {name}._data;") - self.patchups.append(f" {name}._compact.wstr_length = {len(s)};") - self.patchups.append("}") return f"& {name}._compact._base.ob_base" def generate_code(self, name: str, code: types.CodeType) -> str: + global next_code_version # The ordering here matches PyCode_NewWithPosOnlyArgs() # (but see below). - co_code = self.generate(name + "_code", code.co_code) co_consts = self.generate(name + "_consts", code.co_consts) co_names = self.generate(name + "_names", code.co_names) - co_varnames = self.generate(name + "_varnames", code.co_varnames) - co_freevars = self.generate(name + "_freevars", code.co_freevars) - co_cellvars = self.generate(name + "_cellvars", code.co_cellvars) co_filename = self.generate(name + "_filename", code.co_filename) co_name = self.generate(name + "_name", code.co_name) co_qualname = self.generate(name + "_qualname", code.co_qualname) co_linetable = self.generate(name + "_linetable", code.co_linetable) - co_endlinetable = self.generate(name + "_endlinetable", code.co_endlinetable) - co_columntable = self.generate(name + "_columntable", code.co_columntable) co_exceptiontable = self.generate(name + "_exceptiontable", code.co_exceptiontable) # These fields are not directly accessible localsplusnames, localspluskinds = get_localsplus(code) co_localsplusnames = self.generate(name + "_localsplusnames", localsplusnames) co_localspluskinds = self.generate(name + "_localspluskinds", localspluskinds) # Derived values - nlocals, nplaincellvars, ncellvars, nfreevars = \ + nlocals, ncellvars, nfreevars = \ get_localsplus_counts(code, localsplusnames, localspluskinds) - with self.block(f"static struct PyCodeObject {name} =", ";"): - self.object_head("PyCode_Type") + co_code_adaptive = make_string_literal(code.co_code) + self.write("static") + with self.indent(): + self.write(f"struct _PyCode_DEF({len(code.co_code)})") + with self.block(f"{name} =", ";"): + self.object_var_head("PyCode_Type", len(code.co_code) // 2) # But the ordering here must match that in cpython/code.h # (which is a pain because we tend to reorder those for perf) # otherwise MSVC doesn't like it. self.write(f".co_consts = {co_consts},") self.write(f".co_names = {co_names},") - self.write(f".co_firstinstr = (_Py_CODEUNIT *) {co_code.removesuffix('.ob_base.ob_base')}.ob_sval,") self.write(f".co_exceptiontable = {co_exceptiontable},") self.field(code, "co_flags") - self.write(".co_warmup = QUICKENING_INITIAL_WARMUP_VALUE,") + self.write("._co_linearray_entry_size = 0,") self.field(code, "co_argcount") self.field(code, "co_posonlyargcount") self.field(code, "co_kwonlyargcount") + # The following should remain in sync with _PyFrame_NumSlotsForCodeObject + self.write(f".co_framesize = {code.co_stacksize + len(localsplusnames)} + FRAME_SPECIALS_SIZE,") self.field(code, "co_stacksize") self.field(code, "co_firstlineno") - self.write(f".co_code = {co_code},") + self.write(f".co_nlocalsplus = {len(localsplusnames)},") + self.field(code, "co_nlocals") + self.write(f".co_ncellvars = {ncellvars},") + self.write(f".co_nfreevars = {nfreevars},") + self.write(f".co_version = {next_code_version},") + next_code_version += 1 self.write(f".co_localsplusnames = {co_localsplusnames},") self.write(f".co_localspluskinds = {co_localspluskinds},") self.write(f".co_filename = {co_filename},") self.write(f".co_name = {co_name},") self.write(f".co_qualname = {co_qualname},") self.write(f".co_linetable = {co_linetable},") - self.write(f".co_endlinetable = {co_endlinetable},") - self.write(f".co_columntable = {co_columntable},") - self.write(f".co_nlocalsplus = {len(localsplusnames)},") - self.field(code, "co_nlocals") - self.write(f".co_nplaincellvars = {nplaincellvars},") - self.write(f".co_ncellvars = {ncellvars},") - self.write(f".co_nfreevars = {nfreevars},") - self.write(f".co_varnames = {co_varnames},") - self.write(f".co_cellvars = {co_cellvars},") - self.write(f".co_freevars = {co_freevars},") - return f"& {name}.ob_base" + self.write(f"._co_cached = NULL,") + self.write("._co_linearray = NULL,") + self.write(f".co_code_adaptive = {co_code_adaptive},") + for i, op in enumerate(code.co_code[::2]): + if op == RESUME: + self.write(f"._co_firsttraceable = {i},") + break + name_as_code = f"(PyCodeObject *)&{name}" + self.finis.append(f"_PyStaticCode_Fini({name_as_code});") + self.inits.append(f"_PyStaticCode_Init({name_as_code})") + return f"& {name}.ob_base.ob_base" - def generate_tuple(self, name: str, t: tuple[object, ...]) -> str: + def generate_tuple(self, name: str, t: Tuple[object, ...]) -> str: + if len(t) == 0: + return f"(PyObject *)& _Py_SINGLETON(tuple_empty)" items = [self.generate(f"{name}_{i}", it) for i, it in enumerate(t)] self.write("static") with self.indent(): @@ -274,14 +308,7 @@ class Printer: self.write(item + ",") return f"& {name}._object.ob_base.ob_base" - def generate_int(self, name: str, i: int) -> str: - maxint = sys.maxsize - if maxint == 2**31 - 1: - digit = 2**15 - elif maxint == 2**63 - 1: - digit = 2**30 - else: - assert False, f"What int size is this system?!? {maxint=}" + def _generate_int_for_bits(self, name: str, i: int, digit: int) -> None: sign = -1 if i < 0 else 0 if i == 0 else +1 i = abs(i) digits: list[int] = [] @@ -298,6 +325,26 @@ class Printer: if digits: ds = ", ".join(map(str, digits)) self.write(f".ob_digit = {{ {ds} }},") + + def generate_int(self, name: str, i: int) -> str: + if -5 <= i <= 256: + return f"(PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + {i}]" + if i >= 0: + name = f"const_int_{i}" + else: + name = f"const_int_negative_{abs(i)}" + if abs(i) < 2**15: + self._generate_int_for_bits(name, i, 2**15) + else: + connective = "if" + for bits_in_digit in 15, 30: + self.write(f"#{connective} PYLONG_BITS_IN_DIGIT == {bits_in_digit}") + self._generate_int_for_bits(name, i, 2**bits_in_digit) + connective = "elif" + self.write("#else") + self.write('#error "PYLONG_BITS_IN_DIGIT should be 15 or 30"') + self.write("#endif") + # If neither clause applies, it won't compile return f"& {name}.ob_base.ob_base" def generate_float(self, name: str, x: float) -> str: @@ -312,11 +359,21 @@ class Printer: self.write(f".cval = {{ {z.real}, {z.imag} }},") return f"&{name}.ob_base" - def generate_frozenset(self, name: str, fs: frozenset[object]) -> str: - ret = self.generate_tuple(name, tuple(sorted(fs))) + def generate_frozenset(self, name: str, fs: FrozenSet[object]) -> str: + try: + fs = sorted(fs) + except TypeError: + # frozen set with incompatible types, fallback to repr() + fs = sorted(fs, key=repr) + ret = self.generate_tuple(name, tuple(fs)) self.write("// TODO: The above tuple should be a frozenset") return ret + def generate_file(self, module: str, code: object)-> None: + module = module.replace(".", "_") + self.generate(f"{module}_toplevel", code) + self.write(EPILOGUE.format(name=module)) + def generate(self, name: str, obj: object) -> str: # Use repr() in the key to distinguish -0.0 from +0.0 key = (type(obj), obj, repr(obj)) @@ -325,34 +382,33 @@ class Printer: # print(f"Cache hit {key!r:.40}: {self.cache[key]!r:.40}") return self.cache[key] self.misses += 1 - match obj: - case types.CodeType() as code: - val = self.generate_code(name, code) - case tuple(t): - val = self.generate_tuple(name, t) - case str(s): - val = self.generate_unicode(name, s) - case bytes(b): - val = self.generate_bytes(name, b) - case True: - return "Py_True" - case False: - return "Py_False" - case int(i): - val = self.generate_int(name, i) - case float(x): - val = self.generate_float(name, x) - case complex() as z: - val = self.generate_complex(name, z) - case frozenset(fs): - val = self.generate_frozenset(name, fs) - case builtins.Ellipsis: - return "Py_Ellipsis" - case None: - return "Py_None" - case _: - raise TypeError( - f"Cannot generate code for {type(obj).__name__} object") + if isinstance(obj, (types.CodeType, umarshal.Code)) : + val = self.generate_code(name, obj) + elif isinstance(obj, tuple): + val = self.generate_tuple(name, obj) + elif isinstance(obj, str): + val = self.generate_unicode(name, obj) + elif isinstance(obj, bytes): + val = self.generate_bytes(name, obj) + elif obj is True: + return "Py_True" + elif obj is False: + return "Py_False" + elif isinstance(obj, int): + val = self.generate_int(name, obj) + elif isinstance(obj, float): + val = self.generate_float(name, obj) + elif isinstance(obj, complex): + val = self.generate_complex(name, obj) + elif isinstance(obj, frozenset): + val = self.generate_frozenset(name, obj) + elif obj is builtins.Ellipsis: + return "Py_Ellipsis" + elif obj is None: + return "Py_None" + else: + raise TypeError( + f"Cannot generate code for {type(obj).__name__} object") # print(f"Cache store {key!r:.40}: {val!r:.40}") self.cache[key] = val return val @@ -360,33 +416,61 @@ class Printer: EPILOGUE = """ PyObject * -_Py_get_%%NAME%%_toplevel(void) -{ - do_patchups(); - return (PyObject *) &toplevel; -} +_Py_get_{name}_toplevel(void) +{{ + return Py_NewRef((PyObject *) &{name}_toplevel); +}} """ -def generate(source: str, filename: str, modname: str, file: typing.TextIO) -> None: - code = compile(source, filename, "exec") - printer = Printer(file) - printer.generate("toplevel", code) - printer.write("") - with printer.block("static void do_patchups()"): - for p in printer.patchups: +FROZEN_COMMENT_C = "/* Auto-generated by Programs/_freeze_module.c */" +FROZEN_COMMENT_PY = "/* Auto-generated by Programs/_freeze_module.py */" + +FROZEN_DATA_LINE = r"\s*(\d+,\s*)+\s*" + + +def is_frozen_header(source: str) -> bool: + return source.startswith((FROZEN_COMMENT_C, FROZEN_COMMENT_PY)) + + +def decode_frozen_data(source: str) -> types.CodeType: + lines = source.splitlines() + while lines and re.match(FROZEN_DATA_LINE, lines[0]) is None: + del lines[0] + while lines and re.match(FROZEN_DATA_LINE, lines[-1]) is None: + del lines[-1] + values: Tuple[int, ...] = ast.literal_eval("".join(lines).strip()) + data = bytes(values) + return umarshal.loads(data) + + +def generate(args: list[str], output: TextIO) -> None: + printer = Printer(output) + for arg in args: + file, modname = arg.rsplit(':', 1) + with open(file, "r", encoding="utf8") as fd: + source = fd.read() + if is_frozen_header(source): + code = decode_frozen_data(source) + else: + code = compile(fd.read(), f"", "exec") + printer.generate_file(modname, code) + with printer.block(f"void\n_Py_Deepfreeze_Fini(void)"): + for p in printer.finis: printer.write(p) - here = os.path.dirname(__file__) - printer.write(EPILOGUE.replace("%%NAME%%", modname.replace(".", "_"))) + with printer.block(f"int\n_Py_Deepfreeze_Init(void)"): + for p in printer.inits: + with printer.block(f"if ({p} < 0)"): + printer.write("return -1;") + printer.write("return 0;") + printer.write(f"\nuint32_t _Py_next_func_version = {next_code_version};\n") if verbose: print(f"Cache hits: {printer.hits}, misses: {printer.misses}") parser = argparse.ArgumentParser() -parser.add_argument("-m", "--module", help="Defaults to basename(file)") -parser.add_argument("-o", "--output", help="Defaults to MODULE.c") +parser.add_argument("-o", "--output", help="Defaults to deepfreeze.c", default="deepfreeze.c") parser.add_argument("-v", "--verbose", action="store_true", help="Print diagnostics") -parser.add_argument("file", help="Input file (required)") - +parser.add_argument('args', nargs="+", help="Input file and module name (required) in file:modname format") @contextlib.contextmanager def report_time(label: str): @@ -403,13 +487,10 @@ def main() -> None: global verbose args = parser.parse_args() verbose = args.verbose - with open(args.file, encoding="utf-8") as f: - source = f.read() - modname = args.module or os.path.basename(args.file).removesuffix(".py") - output = args.output or modname + ".c" + output = args.output with open(output, "w", encoding="utf-8") as file: with report_time("generate"): - generate(source, f"", modname, file) + generate(args.args, file) if verbose: print(f"Wrote {os.path.getsize(output)} bytes to {output}") diff --git a/Tools/scripts/freeze_modules.py b/Tools/build/freeze_modules.py similarity index 75% rename from Tools/scripts/freeze_modules.py rename to Tools/build/freeze_modules.py index ccea4e11ab6..ee4dd2f8682 100644 --- a/Tools/scripts/freeze_modules.py +++ b/Tools/build/freeze_modules.py @@ -8,13 +8,8 @@ import hashlib import os import ntpath import posixpath -import platform -import subprocess -import sys -import textwrap -import time - -from update_file import updating_file_with_tmpfile, update_file_with_tmpfile +import argparse +from update_file import updating_file_with_tmpfile ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) @@ -22,44 +17,24 @@ ROOT_DIR = os.path.abspath(ROOT_DIR) FROZEN_ONLY = os.path.join(ROOT_DIR, 'Tools', 'freeze', 'flag.py') STDLIB_DIR = os.path.join(ROOT_DIR, 'Lib') -# If MODULES_DIR is changed then the .gitattributes and .gitignore files -# need to be updated. -MODULES_DIR = os.path.join(ROOT_DIR, 'Python', 'frozen_modules') +# If FROZEN_MODULES_DIR or DEEPFROZEN_MODULES_DIR is changed then the +# .gitattributes and .gitignore files needs to be updated. +FROZEN_MODULES_DIR = os.path.join(ROOT_DIR, 'Python', 'frozen_modules') +DEEPFROZEN_MODULES_DIR = os.path.join(ROOT_DIR, 'Python', 'deepfreeze') -if sys.platform != "win32": - TOOL = os.path.join(ROOT_DIR, 'Programs', '_freeze_module') - if not os.path.isfile(TOOL): - # When building out of the source tree, get the tool from directory - # of the Python executable - TOOL = os.path.dirname(sys.executable) - TOOL = os.path.join(TOOL, 'Programs', '_freeze_module') - TOOL = os.path.abspath(TOOL) - if not os.path.isfile(TOOL): - sys.exit("ERROR: missing _freeze_module") -else: - def find_tool(): - archs = ['amd64', 'win32'] - if platform.machine() == "ARM64": - archs.append('arm64') - for arch in archs: - for exe in ['_freeze_module.exe', '_freeze_module_d.exe']: - tool = os.path.join(ROOT_DIR, 'PCbuild', arch, exe) - if os.path.isfile(tool): - return tool - sys.exit("ERROR: missing _freeze_module.exe; you need to run PCbuild/build.bat") - TOOL = find_tool() - del find_tool - -MANIFEST = os.path.join(MODULES_DIR, 'MANIFEST') FROZEN_FILE = os.path.join(ROOT_DIR, 'Python', 'frozen.c') MAKEFILE = os.path.join(ROOT_DIR, 'Makefile.pre.in') PCBUILD_PROJECT = os.path.join(ROOT_DIR, 'PCbuild', '_freeze_module.vcxproj') PCBUILD_FILTERS = os.path.join(ROOT_DIR, 'PCbuild', '_freeze_module.vcxproj.filters') +PCBUILD_PYTHONCORE = os.path.join(ROOT_DIR, 'PCbuild', 'pythoncore.vcxproj') OS_PATH = 'ntpath' if os.name == 'nt' else 'posixpath' # These are modules that get frozen. +# If you're debugging new bytecode instructions, +# you can delete all sections except 'import system'. +# This also speeds up building somewhat. TESTS_SECTION = 'Test module' FROZEN = [ # See parse_frozen_spec() for the format. @@ -73,6 +48,7 @@ FROZEN = [ # on a builtin zip file instead of a filesystem. 'zipimport', ]), + # (You can delete entries from here down to the end of the list.) ('stdlib - startup, without site (python -S)', [ 'abc', 'codecs', @@ -95,6 +71,11 @@ FROZEN = [ 'site', 'stat', ]), + ('runpy - run module with -m', [ + "importlib.util", + "importlib.machinery", + "runpy", + ]), (TESTS_SECTION, [ '__hello__', '__hello__ : __hello_alias__', @@ -103,6 +84,7 @@ FROZEN = [ '<__phello__.**.*>', f'frozen_only : __hello_only__ = {FROZEN_ONLY}', ]), + # (End of stuff you could delete.) ] BOOTSTRAP = { 'importlib._bootstrap', @@ -136,16 +118,16 @@ else: ####################################### # specs -def parse_frozen_specs(sectionalspecs=FROZEN, destdir=None): +def parse_frozen_specs(): seen = {} - for section, specs in sectionalspecs: + for section, specs in FROZEN: parsed = _parse_specs(specs, section, seen) for item in parsed: frozenid, pyfile, modname, ispkg, section = item try: source = seen[frozenid] except KeyError: - source = FrozenSource.from_id(frozenid, pyfile, destdir) + source = FrozenSource.from_id(frozenid, pyfile) seen[frozenid] = source else: assert not pyfile or pyfile == source.pyfile, item @@ -250,15 +232,16 @@ def _parse_spec(spec, knownids=None, section=None): ####################################### # frozen source files -class FrozenSource(namedtuple('FrozenSource', 'id pyfile frozenfile')): +class FrozenSource(namedtuple('FrozenSource', 'id pyfile frozenfile deepfreezefile')): @classmethod - def from_id(cls, frozenid, pyfile=None, destdir=MODULES_DIR): + def from_id(cls, frozenid, pyfile=None): if not pyfile: pyfile = os.path.join(STDLIB_DIR, *frozenid.split('.')) + '.py' #assert os.path.exists(pyfile), (frozenid, pyfile) - frozenfile = resolve_frozen_file(frozenid, destdir) - return cls(frozenid, pyfile, frozenfile) + frozenfile = resolve_frozen_file(frozenid, FROZEN_MODULES_DIR) + deepfreezefile = resolve_frozen_file(frozenid, DEEPFROZEN_MODULES_DIR) + return cls(frozenid, pyfile, frozenfile, deepfreezefile) @property def frozenid(self): @@ -285,8 +268,12 @@ class FrozenSource(namedtuple('FrozenSource', 'id pyfile frozenfile')): else: return os.path.basename(self.pyfile) == '__init__.py' + @property + def isbootstrap(self): + return self.id in BOOTSTRAP -def resolve_frozen_file(frozenid, destdir=MODULES_DIR): + +def resolve_frozen_file(frozenid, destdir): """Return the filename corresponding to the given frozen ID. For stdlib modules the ID will always be the full name @@ -480,53 +467,15 @@ def replace_block(lines, start_marker, end_marker, replacements, file): return lines[:start_pos + 1] + replacements + lines[end_pos:] -def regen_manifest(modules): - header = 'module ispkg source frozen checksum'.split() - widths = [5] * len(header) - rows = [] - for mod in modules: - info = mod.summarize() - row = [] - for i, col in enumerate(header): - value = info[col] - if col == 'checksum': - value = value[:12] - elif col == 'ispkg': - value = 'YES' if value else 'no' - widths[i] = max(widths[i], len(value)) - row.append(value or '-') - rows.append(row) - - modlines = [ - '# The list of frozen modules with key information.', - '# Note that the "check_generated_files" CI job will identify', - '# when source files were changed but regen-frozen wasn\'t run.', - '# This file is auto-generated by Tools/scripts/freeze_modules.py.', - ' '.join(c.center(w) for c, w in zip(header, widths)).rstrip(), - ' '.join('-' * w for w in widths), - ] - for row in rows: - for i, w in enumerate(widths): - if header[i] == 'ispkg': - row[i] = row[i].center(w) - else: - row[i] = row[i].ljust(w) - modlines.append(' '.join(row).rstrip()) - - print(f'# Updating {os.path.relpath(MANIFEST)}') - with open(MANIFEST, 'w', encoding="utf-8") as outfile: - lines = (l + '\n' for l in modlines) - outfile.writelines(lines) - - -def regen_frozen(modules): +def regen_frozen(modules, frozen_modules: bool): headerlines = [] parentdir = os.path.dirname(FROZEN_FILE) - for src in _iter_sources(modules): - # Adding a comment to separate sections here doesn't add much, - # so we don't. - header = relpath_for_posix_display(src.frozenfile, parentdir) - headerlines.append(f'#include "{header}"') + if frozen_modules: + for src in _iter_sources(modules): + # Adding a comment to separate sections here doesn't add much, + # so we don't. + header = relpath_for_posix_display(src.frozenfile, parentdir) + headerlines.append(f'#include "{header}"') externlines = [] bootstraplines = [] @@ -536,7 +485,7 @@ def regen_frozen(modules): indent = ' ' lastsection = None for mod in modules: - if mod.frozenid in BOOTSTRAP: + if mod.isbootstrap: lines = bootstraplines elif mod.section == TESTS_SECTION: lines = testlines @@ -556,9 +505,13 @@ def regen_frozen(modules): externlines.append("extern PyObject *%s(void);" % get_code_name) symbol = mod.symbol - pkg = '-' if mod.ispkg else '' - line = ('{"%s", %s, %s(int)sizeof(%s), GET_CODE(%s)},' - ) % (mod.name, symbol, pkg, symbol, code_name) + pkg = 'true' if mod.ispkg else 'false' + if not frozen_modules: + line = ('{"%s", NULL, 0, %s, GET_CODE(%s)},' + ) % (mod.name, pkg, code_name) + else: + line = ('{"%s", %s, (int)sizeof(%s), %s, GET_CODE(%s)},' + ) % (mod.name, symbol, symbol, pkg, code_name) lines.append(line) if mod.isalias: @@ -572,7 +525,7 @@ def regen_frozen(modules): for lines in (bootstraplines, stdliblines, testlines): # TODO: Is this necessary any more? - if not lines[0]: + if lines and not lines[0]: del lines[0] for i, line in enumerate(lines): if line: @@ -631,47 +584,34 @@ def regen_frozen(modules): def regen_makefile(modules): pyfiles = [] frozenfiles = [] - deepfreezefiles = [] rules = [''] - deepfreezerules = [''] - - # TODO: Merge the two loops + deepfreezerules = ["Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS)", + "\t$(PYTHON_FOR_FREEZE) $(srcdir)/Tools/build/deepfreeze.py \\"] for src in _iter_sources(modules): - header = relpath_for_posix_display(src.frozenfile, ROOT_DIR) - relfile = header.replace('\\', '/') - _pyfile = relpath_for_posix_display(src.pyfile, ROOT_DIR) - - # TODO: This is a bit hackish - xfile = relfile.replace("/frozen_modules/", "/deepfreeze/") - cfile = xfile[:-2] + ".c" - ofile = xfile[:-2] + ".o" - deepfreezefiles.append(f"\t\t{ofile} \\") - - # Also add a deepfreeze rule. - deepfreezerules.append(f'{cfile}: $(srcdir)/{_pyfile} $(DEEPFREEZE_DEPS)') - deepfreezerules.append(f'\t@echo "Deepfreezing {cfile} from {_pyfile}"') - deepfreezerules.append(f"\t@./$(BOOTSTRAP) \\") - deepfreezerules.append(f"\t\t$(srcdir)/Tools/scripts/deepfreeze.py \\") - deepfreezerules.append(f"\t\t$(srcdir)/{_pyfile} -m {src.frozenid} -o {cfile}") - deepfreezerules.append('') - - for src in _iter_sources(modules): - header = relpath_for_posix_display(src.frozenfile, ROOT_DIR) - frozenfiles.append(f'\t\t{header} \\') + frozen_header = relpath_for_posix_display(src.frozenfile, ROOT_DIR) + frozenfiles.append(f'\t\t{frozen_header} \\') pyfile = relpath_for_posix_display(src.pyfile, ROOT_DIR) pyfiles.append(f'\t\t{pyfile} \\') - freeze = (f'Programs/_freeze_module {src.frozenid} ' - f'$(srcdir)/{pyfile} $(srcdir)/{header}') + if src.isbootstrap: + freezecmd = '$(FREEZE_MODULE_BOOTSTRAP)' + freezedep = '$(FREEZE_MODULE_BOOTSTRAP_DEPS)' + else: + freezecmd = '$(FREEZE_MODULE)' + freezedep = '$(FREEZE_MODULE_DEPS)' + + freeze = (f'{freezecmd} {src.frozenid} ' + f'$(srcdir)/{pyfile} {frozen_header}') rules.extend([ - f'{header}: Programs/_freeze_module {pyfile}', + f'{frozen_header}: {pyfile} {freezedep}', f'\t{freeze}', '', ]) + deepfreezerules.append(f"\t{frozen_header}:{src.frozenid} \\") + deepfreezerules.append('\t-o Python/deepfreeze/deepfreeze.c') pyfiles[-1] = pyfiles[-1].rstrip(" \\") frozenfiles[-1] = frozenfiles[-1].rstrip(" \\") - deepfreezefiles[-1] = deepfreezefiles[-1].rstrip(" \\") print(f'# Updating {os.path.relpath(MAKEFILE)}') with updating_file_with_tmpfile(MAKEFILE) as (infile, outfile): @@ -690,13 +630,6 @@ def regen_makefile(modules): frozenfiles, MAKEFILE, ) - lines = replace_block( - lines, - "DEEPFREEZE_OBJS =", - "# End DEEPFREEZE_OBJS", - deepfreezefiles, - MAKEFILE, - ) lines = replace_block( lines, "# BEGIN: freezing modules", @@ -717,6 +650,8 @@ def regen_makefile(modules): def regen_pcbuild(modules): projlines = [] filterlines = [] + corelines = [] + deepfreezerules = ['\t') filterlines.append(' Python Files') filterlines.append(' ') + deepfreezerules.append(f'\t\t "$(PySourcePath){header}:{src.frozenid}" ^') + deepfreezerules.append('\t\t "-o" "$(PySourcePath)Python\\deepfreeze\\deepfreeze.c"\'/>' ) + + corelines.append(f' ') print(f'# Updating {os.path.relpath(PCBUILD_PROJECT)}') with updating_file_with_tmpfile(PCBUILD_PROJECT) as (infile, outfile): @@ -742,6 +681,16 @@ def regen_pcbuild(modules): PCBUILD_PROJECT, ) outfile.writelines(lines) + with updating_file_with_tmpfile(PCBUILD_PROJECT) as (infile, outfile): + lines = infile.readlines() + lines = replace_block( + lines, + '', + '', + deepfreezerules, + PCBUILD_PROJECT, + ) + outfile.writelines(lines) print(f'# Updating {os.path.relpath(PCBUILD_FILTERS)}') with updating_file_with_tmpfile(PCBUILD_FILTERS) as (infile, outfile): lines = infile.readlines() @@ -753,57 +702,37 @@ def regen_pcbuild(modules): PCBUILD_FILTERS, ) outfile.writelines(lines) - - -####################################### -# freezing modules - -def freeze_module(modname, pyfile=None, destdir=MODULES_DIR): - """Generate the frozen module .h file for the given module.""" - tmpsuffix = f'.{int(time.time())}' - for modname, pyfile, ispkg in resolve_modules(modname, pyfile): - frozenfile = resolve_frozen_file(modname, destdir) - _freeze_module(modname, pyfile, frozenfile, tmpsuffix) - - -def _freeze_module(frozenid, pyfile, frozenfile, tmpsuffix): - tmpfile = f'{frozenfile}.{int(time.time())}' - - argv = [TOOL, frozenid, pyfile, tmpfile] - print('#', ' '.join(os.path.relpath(a) for a in argv), flush=True) - try: - subprocess.run(argv, check=True) - except (FileNotFoundError, subprocess.CalledProcessError): - if not os.path.exists(TOOL): - sys.exit(f'ERROR: missing {TOOL}; you need to run "make regen-frozen"') - raise # re-raise - - update_file_with_tmpfile(frozenfile, tmpfile, create=True) + print(f'# Updating {os.path.relpath(PCBUILD_PYTHONCORE)}') + with updating_file_with_tmpfile(PCBUILD_PYTHONCORE) as (infile, outfile): + lines = infile.readlines() + lines = replace_block( + lines, + '', + '', + corelines, + PCBUILD_FILTERS, + ) + outfile.writelines(lines) ####################################### # the script +parser = argparse.ArgumentParser() +parser.add_argument("--frozen-modules", action="store_true", + help="Use both frozen and deepfrozen modules. (default: uses only deepfrozen modules)") + def main(): + args = parser.parse_args() + frozen_modules: bool = args.frozen_modules # Expand the raw specs, preserving order. - modules = list(parse_frozen_specs(destdir=MODULES_DIR)) + modules = list(parse_frozen_specs()) # Regen build-related files. regen_makefile(modules) regen_pcbuild(modules) - - # Freeze the target modules. - tmpsuffix = f'.{int(time.time())}' - for src in _iter_sources(modules): - _freeze_module(src.frozenid, src.pyfile, src.frozenfile, tmpsuffix) - - # Regen files dependent of frozen file details. - regen_frozen(modules) - regen_manifest(modules) + regen_frozen(modules, frozen_modules) if __name__ == '__main__': - argv = sys.argv[1:] - if argv: - sys.exit('ERROR: got unexpected args {argv}') main() diff --git a/Tools/build/generate_global_objects.py b/Tools/build/generate_global_objects.py new file mode 100644 index 00000000000..9ceae89878c --- /dev/null +++ b/Tools/build/generate_global_objects.py @@ -0,0 +1,431 @@ +import contextlib +import io +import os.path +import re + +SCRIPT_NAME = 'Tools/build/generate_global_objects.py' +__file__ = os.path.abspath(__file__) +ROOT = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) +INTERNAL = os.path.join(ROOT, 'Include', 'internal') + + +IGNORED = { + 'ACTION', # Python/_warnings.c + 'ATTR', # Python/_warnings.c and Objects/funcobject.c + 'DUNDER', # Objects/typeobject.c + 'RDUNDER', # Objects/typeobject.c + 'SPECIAL', # Objects/weakrefobject.c + 'NAME', # Objects/typeobject.c +} +IDENTIFIERS = [ + # from ADD() Python/_warnings.c + 'default', + 'ignore', + + # from GET_WARNINGS_ATTR() in Python/_warnings.c + 'WarningMessage', + '_showwarnmsg', + '_warn_unawaited_coroutine', + 'defaultaction', + 'filters', + 'onceregistry', + + # from WRAP_METHOD() in Objects/weakrefobject.c + '__bytes__', + '__reversed__', + + # from COPY_ATTR() in Objects/funcobject.c + '__module__', + '__name__', + '__qualname__', + '__doc__', + '__annotations__', + + # from SLOT* in Objects/typeobject.c + '__abs__', + '__add__', + '__aiter__', + '__and__', + '__anext__', + '__await__', + '__bool__', + '__call__', + '__contains__', + '__del__', + '__delattr__', + '__delete__', + '__delitem__', + '__eq__', + '__float__', + '__floordiv__', + '__ge__', + '__get__', + '__getattr__', + '__getattribute__', + '__getitem__', + '__gt__', + '__hash__', + '__iadd__', + '__iand__', + '__ifloordiv__', + '__ilshift__', + '__imatmul__', + '__imod__', + '__imul__', + '__index__', + '__init__', + '__int__', + '__invert__', + '__ior__', + '__ipow__', + '__irshift__', + '__isub__', + '__iter__', + '__itruediv__', + '__ixor__', + '__le__', + '__len__', + '__lshift__', + '__lt__', + '__matmul__', + '__mod__', + '__mul__', + '__ne__', + '__neg__', + '__new__', + '__next__', + '__or__', + '__pos__', + '__pow__', + '__radd__', + '__rand__', + '__repr__', + '__rfloordiv__', + '__rlshift__', + '__rmatmul__', + '__rmod__', + '__rmul__', + '__ror__', + '__rpow__', + '__rrshift__', + '__rshift__', + '__rsub__', + '__rtruediv__', + '__rxor__', + '__set__', + '__setattr__', + '__setitem__', + '__str__', + '__sub__', + '__truediv__', + '__xor__', + '__divmod__', + '__rdivmod__', +] + +NON_GENERATED_IMMORTAL_OBJECTS = [ + # The generated ones come from generate_runtime_init(). + '(PyObject *)&_Py_SINGLETON(bytes_empty)', + '(PyObject *)&_Py_SINGLETON(tuple_empty)', + '(PyObject *)&_Py_SINGLETON(hamt_bitmap_node_empty)', + '(PyObject *)&_Py_INTERP_SINGLETON(interp, hamt_empty)', + '(PyObject *)&_Py_SINGLETON(context_token_missing)', +] + + +####################################### +# helpers + +def iter_files(): + for name in ('Modules', 'Objects', 'Parser', 'PC', 'Programs', 'Python'): + root = os.path.join(ROOT, name) + for dirname, _, files in os.walk(root): + for name in files: + if not name.endswith(('.c', '.h')): + continue + yield os.path.join(dirname, name) + + +def iter_global_strings(): + id_regex = re.compile(r'\b_Py_ID\((\w+)\)') + str_regex = re.compile(r'\b_Py_DECLARE_STR\((\w+), "(.*?)"\)') + for filename in iter_files(): + try: + infile = open(filename, encoding='utf-8') + except FileNotFoundError: + # The file must have been a temporary file. + continue + with infile: + for lno, line in enumerate(infile, 1): + for m in id_regex.finditer(line): + identifier, = m.groups() + yield identifier, None, filename, lno, line + for m in str_regex.finditer(line): + varname, string = m.groups() + yield varname, string, filename, lno, line + + +def iter_to_marker(lines, marker): + for line in lines: + if line.rstrip() == marker: + break + yield line + + +class Printer: + + def __init__(self, file): + self.level = 0 + self.file = file + self.continuation = [False] + + @contextlib.contextmanager + def indent(self): + save_level = self.level + try: + self.level += 1 + yield + finally: + self.level = save_level + + def write(self, arg): + eol = '\n' + if self.continuation[-1]: + eol = f' \\{eol}' if arg else f'\\{eol}' + self.file.writelines((" "*self.level, arg, eol)) + + @contextlib.contextmanager + def block(self, prefix, suffix="", *, continuation=None): + if continuation is None: + continuation = self.continuation[-1] + self.continuation.append(continuation) + + self.write(prefix + " {") + with self.indent(): + yield + self.continuation.pop() + self.write("}" + suffix) + + +@contextlib.contextmanager +def open_for_changes(filename, orig): + """Like open() but only write to the file if it changed.""" + outfile = io.StringIO() + yield outfile + text = outfile.getvalue() + if text != orig: + with open(filename, 'w', encoding='utf-8') as outfile: + outfile.write(text) + else: + print(f'# not changed: {filename}') + + +####################################### +# the global objects + +START = f'/* The following is auto-generated by {SCRIPT_NAME}. */' +END = '/* End auto-generated code */' + + +def generate_global_strings(identifiers, strings): + filename = os.path.join(INTERNAL, 'pycore_global_strings.h') + + # Read the non-generated part of the file. + with open(filename) as infile: + orig = infile.read() + lines = iter(orig.rstrip().splitlines()) + before = '\n'.join(iter_to_marker(lines, START)) + for _ in iter_to_marker(lines, END): + pass + after = '\n'.join(lines) + + # Generate the file. + with open_for_changes(filename, orig) as outfile: + printer = Printer(outfile) + printer.write(before) + printer.write(START) + with printer.block('struct _Py_global_strings', ';'): + with printer.block('struct', ' literals;'): + for literal, name in sorted(strings.items(), key=lambda x: x[1]): + printer.write(f'STRUCT_FOR_STR({name}, "{literal}")') + outfile.write('\n') + with printer.block('struct', ' identifiers;'): + for name in sorted(identifiers): + assert name.isidentifier(), name + printer.write(f'STRUCT_FOR_ID({name})') + with printer.block('struct', ' ascii[128];'): + printer.write("PyASCIIObject _ascii;") + printer.write("uint8_t _data[2];") + with printer.block('struct', ' latin1[128];'): + printer.write("PyCompactUnicodeObject _latin1;") + printer.write("uint8_t _data[2];") + printer.write(END) + printer.write(after) + + +def generate_runtime_init(identifiers, strings): + # First get some info from the declarations. + nsmallposints = None + nsmallnegints = None + with open(os.path.join(INTERNAL, 'pycore_global_objects.h')) as infile: + for line in infile: + if line.startswith('#define _PY_NSMALLPOSINTS'): + nsmallposints = int(line.split()[-1]) + elif line.startswith('#define _PY_NSMALLNEGINTS'): + nsmallnegints = int(line.split()[-1]) + break + else: + raise NotImplementedError + assert nsmallposints and nsmallnegints + + # Then target the runtime initializer. + filename = os.path.join(INTERNAL, 'pycore_runtime_init_generated.h') + + # Read the non-generated part of the file. + with open(filename) as infile: + orig = infile.read() + lines = iter(orig.rstrip().splitlines()) + before = '\n'.join(iter_to_marker(lines, START)) + for _ in iter_to_marker(lines, END): + pass + after = '\n'.join(lines) + + # Generate the file. + with open_for_changes(filename, orig) as outfile: + immortal_objects = [] + printer = Printer(outfile) + printer.write(before) + printer.write(START) + with printer.block('#define _Py_small_ints_INIT', continuation=True): + for i in range(-nsmallnegints, nsmallposints): + printer.write(f'_PyLong_DIGIT_INIT({i}),') + immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + {i}]') + printer.write('') + with printer.block('#define _Py_bytes_characters_INIT', continuation=True): + for i in range(256): + printer.write(f'_PyBytes_CHAR_INIT({i}),') + immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(bytes_characters)[{i}]') + printer.write('') + with printer.block('#define _Py_str_literals_INIT', continuation=True): + for literal, name in sorted(strings.items(), key=lambda x: x[1]): + printer.write(f'INIT_STR({name}, "{literal}"),') + immortal_objects.append(f'(PyObject *)&_Py_STR({name})') + printer.write('') + with printer.block('#define _Py_str_identifiers_INIT', continuation=True): + for name in sorted(identifiers): + assert name.isidentifier(), name + printer.write(f'INIT_ID({name}),') + immortal_objects.append(f'(PyObject *)&_Py_ID({name})') + printer.write('') + with printer.block('#define _Py_str_ascii_INIT', continuation=True): + for i in range(128): + printer.write(f'_PyASCIIObject_INIT("\\x{i:02x}"),') + immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(strings).ascii[{i}]') + printer.write('') + with printer.block('#define _Py_str_latin1_INIT', continuation=True): + for i in range(128, 256): + utf8 = ['"'] + for c in chr(i).encode('utf-8'): + utf8.append(f"\\x{c:02x}") + utf8.append('"') + printer.write(f'_PyUnicode_LATIN1_INIT("\\x{i:02x}", {"".join(utf8)}),') + immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(strings).latin1[{i} - 128]') + printer.write(END) + printer.write(after) + return immortal_objects + + +def generate_static_strings_initializer(identifiers, strings): + # Target the runtime initializer. + filename = os.path.join(INTERNAL, 'pycore_unicodeobject_generated.h') + + # Read the non-generated part of the file. + with open(filename) as infile: + orig = infile.read() + lines = iter(orig.rstrip().splitlines()) + before = '\n'.join(iter_to_marker(lines, START)) + for _ in iter_to_marker(lines, END): + pass + after = '\n'.join(lines) + + # Generate the file. + with open_for_changes(filename, orig) as outfile: + printer = Printer(outfile) + printer.write(before) + printer.write(START) + printer.write("static inline void") + with printer.block("_PyUnicode_InitStaticStrings(void)"): + printer.write(f'PyObject *string;') + for i in sorted(identifiers): + # This use of _Py_ID() is ignored by iter_global_strings() + # since iter_files() ignores .h files. + printer.write(f'string = &_Py_ID({i});') + printer.write(f'PyUnicode_InternInPlace(&string);') + # XXX What about "strings"? + printer.write(END) + printer.write(after) + + +def generate_global_object_finalizers(generated_immortal_objects): + # Target the runtime initializer. + filename = os.path.join(INTERNAL, 'pycore_global_objects_fini_generated.h') + + # Read the non-generated part of the file. + with open(filename) as infile: + orig = infile.read() + lines = iter(orig.rstrip().splitlines()) + before = '\n'.join(iter_to_marker(lines, START)) + for _ in iter_to_marker(lines, END): + pass + after = '\n'.join(lines) + + # Generate the file. + with open_for_changes(filename, orig) as outfile: + printer = Printer(outfile) + printer.write(before) + printer.write(START) + printer.write('#ifdef Py_DEBUG') + printer.write("static inline void") + with printer.block( + "_PyStaticObjects_CheckRefcnt(PyInterpreterState *interp)"): + printer.write('/* generated runtime-global */') + printer.write('// (see pycore_runtime_init_generated.h)') + for ref in generated_immortal_objects: + printer.write(f'_PyStaticObject_CheckRefcnt({ref});') + printer.write('/* non-generated */') + for ref in NON_GENERATED_IMMORTAL_OBJECTS: + printer.write(f'_PyStaticObject_CheckRefcnt({ref});') + printer.write('#endif // Py_DEBUG') + printer.write(END) + printer.write(after) + + +def get_identifiers_and_strings() -> 'tuple[set[str], dict[str, str]]': + identifiers = set(IDENTIFIERS) + strings = {} + for name, string, *_ in iter_global_strings(): + if string is None: + if name not in IGNORED: + identifiers.add(name) + else: + if string not in strings: + strings[string] = name + elif name != strings[string]: + raise ValueError(f'string mismatch for {name!r} ({string!r} != {strings[name]!r}') + return identifiers, strings + + +####################################### +# the script + +def main() -> None: + identifiers, strings = get_identifiers_and_strings() + + generate_global_strings(identifiers, strings) + generated_immortal_objects = generate_runtime_init(identifiers, strings) + generate_static_strings_initializer(identifiers, strings) + generate_global_object_finalizers(generated_immortal_objects) + + +if __name__ == '__main__': + main() diff --git a/Tools/build/generate_levenshtein_examples.py b/Tools/build/generate_levenshtein_examples.py new file mode 100644 index 00000000000..778eb458c54 --- /dev/null +++ b/Tools/build/generate_levenshtein_examples.py @@ -0,0 +1,70 @@ +"""Generate 10,000 unique examples for the Levenshtein short-circuit tests.""" + +import argparse +from functools import lru_cache +import json +import os.path +from random import choices, randrange + + +# This should be in sync with Lib/traceback.py. It's not importing those values +# because this script is being executed by PYTHON_FOR_REGEN and not by the in-tree +# build of Python. +_MOVE_COST = 2 +_CASE_COST = 1 + + +def _substitution_cost(ch_a, ch_b): + if ch_a == ch_b: + return 0 + if ch_a.lower() == ch_b.lower(): + return _CASE_COST + return _MOVE_COST + + +@lru_cache(None) +def levenshtein(a, b): + if not a or not b: + return (len(a) + len(b)) * _MOVE_COST + option1 = levenshtein(a[:-1], b[:-1]) + _substitution_cost(a[-1], b[-1]) + option2 = levenshtein(a[:-1], b) + _MOVE_COST + option3 = levenshtein(a, b[:-1]) + _MOVE_COST + return min(option1, option2, option3) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('output_path', metavar='FILE', type=str) + parser.add_argument('--overwrite', dest='overwrite', action='store_const', + const=True, default=False, + help='overwrite an existing test file') + + args = parser.parse_args() + output_path = os.path.realpath(args.output_path) + if not args.overwrite and os.path.isfile(output_path): + print(f"{output_path} already exists, skipping regeneration.") + print( + "To force, add --overwrite to the invocation of this tool or" + " delete the existing file." + ) + return + + examples = set() + # Create a lot of non-empty examples, which should end up with a Gauss-like + # distribution for even costs (moves) and odd costs (case substitutions). + while len(examples) < 9990: + a = ''.join(choices("abcABC", k=randrange(1, 10))) + b = ''.join(choices("abcABC", k=randrange(1, 10))) + expected = levenshtein(a, b) + examples.add((a, b, expected)) + # Create one empty case each for strings between 0 and 9 in length. + for i in range(10): + b = ''.join(choices("abcABC", k=i)) + expected = levenshtein("", b) + examples.add(("", b, expected)) + with open(output_path, "w") as f: + json.dump(sorted(examples), f, indent=2) + + +if __name__ == "__main__": + main() diff --git a/Tools/build/generate_opcode_h.py b/Tools/build/generate_opcode_h.py new file mode 100644 index 00000000000..9b2112f7f5f --- /dev/null +++ b/Tools/build/generate_opcode_h.py @@ -0,0 +1,204 @@ +# This script generates the opcode.h header file. + +import sys +import tokenize + +SCRIPT_NAME = "Tools/build/generate_opcode_h.py" +PYTHON_OPCODE = "Lib/opcode.py" + +header = f""" +// Auto-generated by {SCRIPT_NAME} from {PYTHON_OPCODE} + +#ifndef Py_OPCODE_H +#define Py_OPCODE_H +#ifdef __cplusplus +extern "C" {{ +#endif + + +/* Instruction opcodes for compiled code */ +""".lstrip() + +footer = """ + +#define IS_PSEUDO_OPCODE(op) (((op) >= MIN_PSEUDO_OPCODE) && ((op) <= MAX_PSEUDO_OPCODE)) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OPCODE_H */ +""" + +internal_header = f""" +// Auto-generated by {SCRIPT_NAME} from {PYTHON_OPCODE} + +#ifndef Py_INTERNAL_OPCODE_H +#define Py_INTERNAL_OPCODE_H +#ifdef __cplusplus +extern "C" {{ +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "opcode.h" +""".lstrip() + +internal_footer = """ +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_OPCODE_H +""" + +DEFINE = "#define {:<38} {:>3}\n" + +UINT32_MASK = (1<<32)-1 + +def write_int_array_from_ops(name, ops, out): + bits = 0 + for op in ops: + bits |= 1<>= 32 + assert bits == 0 + out.write(f"}};\n") + +def main(opcode_py, outfile='Include/opcode.h', internaloutfile='Include/internal/pycore_opcode.h'): + opcode = {} + if hasattr(tokenize, 'open'): + fp = tokenize.open(opcode_py) # Python 3.2+ + else: + fp = open(opcode_py) # Python 2.7 + with fp: + code = fp.read() + exec(code, opcode) + opmap = opcode['opmap'] + opname = opcode['opname'] + hasarg = opcode['hasarg'] + hasconst = opcode['hasconst'] + hasjrel = opcode['hasjrel'] + hasjabs = opcode['hasjabs'] + is_pseudo = opcode['is_pseudo'] + _pseudo_ops = opcode['_pseudo_ops'] + + ENABLE_SPECIALIZATION = opcode["ENABLE_SPECIALIZATION"] + HAVE_ARGUMENT = opcode["HAVE_ARGUMENT"] + MIN_PSEUDO_OPCODE = opcode["MIN_PSEUDO_OPCODE"] + MAX_PSEUDO_OPCODE = opcode["MAX_PSEUDO_OPCODE"] + + NUM_OPCODES = len(opname) + used = [ False ] * len(opname) + next_op = 1 + + for name, op in opmap.items(): + used[op] = True + + specialized_opmap = {} + opname_including_specialized = opname.copy() + for name in opcode['_specialized_instructions']: + while used[next_op]: + next_op += 1 + specialized_opmap[name] = next_op + opname_including_specialized[next_op] = name + used[next_op] = True + specialized_opmap['DO_TRACING'] = 255 + opname_including_specialized[255] = 'DO_TRACING' + used[255] = True + + with open(outfile, 'w') as fobj, open(internaloutfile, 'w') as iobj: + fobj.write(header) + iobj.write(internal_header) + + for name in opname: + if name in opmap: + op = opmap[name] + if op == HAVE_ARGUMENT: + fobj.write(DEFINE.format("HAVE_ARGUMENT", HAVE_ARGUMENT)) + if op == MIN_PSEUDO_OPCODE: + fobj.write(DEFINE.format("MIN_PSEUDO_OPCODE", MIN_PSEUDO_OPCODE)) + + fobj.write(DEFINE.format(name, op)) + + if op == MAX_PSEUDO_OPCODE: + fobj.write(DEFINE.format("MAX_PSEUDO_OPCODE", MAX_PSEUDO_OPCODE)) + + + for name, op in specialized_opmap.items(): + fobj.write(DEFINE.format(name, op)) + + iobj.write("\nextern const uint8_t _PyOpcode_Caches[256];\n") + iobj.write("\nextern const uint8_t _PyOpcode_Deopt[256];\n") + iobj.write("\n#ifdef NEED_OPCODE_TABLES\n") + write_int_array_from_ops("_PyOpcode_RelativeJump", opcode['hasjrel'], iobj) + write_int_array_from_ops("_PyOpcode_Jump", opcode['hasjrel'] + opcode['hasjabs'], iobj) + + iobj.write("\nconst uint8_t _PyOpcode_Caches[256] = {\n") + for i, entries in enumerate(opcode["_inline_cache_entries"]): + if entries: + iobj.write(f" [{opname[i]}] = {entries},\n") + iobj.write("};\n") + + deoptcodes = {} + for basic, op in opmap.items(): + if not is_pseudo(op): + deoptcodes[basic] = basic + for basic, family in opcode["_specializations"].items(): + for specialized in family: + deoptcodes[specialized] = basic + iobj.write("\nconst uint8_t _PyOpcode_Deopt[256] = {\n") + for opt, deopt in sorted(deoptcodes.items()): + iobj.write(f" [{opt}] = {deopt},\n") + iobj.write("};\n") + iobj.write("#endif // NEED_OPCODE_TABLES\n") + + fobj.write("\n") + fobj.write("#define HAS_ARG(op) ((((op) >= HAVE_ARGUMENT) && (!IS_PSEUDO_OPCODE(op)))\\") + for op in _pseudo_ops: + if opmap[op] in hasarg: + fobj.write(f"\n || ((op) == {op}) \\") + fobj.write("\n )\n") + + fobj.write("\n") + fobj.write("#define HAS_CONST(op) (false\\") + for op in hasconst: + fobj.write(f"\n || ((op) == {opname[op]}) \\") + fobj.write("\n )\n") + + fobj.write("\n") + for i, (op, _) in enumerate(opcode["_nb_ops"]): + fobj.write(DEFINE.format(op, i)) + + fobj.write("\n") + fobj.write("/* Defined in Lib/opcode.py */\n") + fobj.write(f"#define ENABLE_SPECIALIZATION {int(ENABLE_SPECIALIZATION)}") + + iobj.write("\n") + iobj.write("#ifdef Py_DEBUG\n") + iobj.write(f"static const char *const _PyOpcode_OpName[{NUM_OPCODES}] = {{\n") + for op, name in enumerate(opname_including_specialized): + if name[0] != "<": + op = name + iobj.write(f''' [{op}] = "{name}",\n''') + iobj.write("};\n") + iobj.write("#endif\n") + + iobj.write("\n") + iobj.write("#define EXTRA_CASES \\\n") + for i, flag in enumerate(used): + if not flag: + iobj.write(f" case {i}: \\\n") + iobj.write(" ;\n") + + fobj.write(footer) + iobj.write(internal_footer) + + + print(f"{outfile} regenerated from {opcode_py}") + + +if __name__ == '__main__': + main(sys.argv[1], sys.argv[2], sys.argv[3]) diff --git a/Tools/build/generate_re_casefix.py b/Tools/build/generate_re_casefix.py new file mode 100755 index 00000000000..b57ac07426c --- /dev/null +++ b/Tools/build/generate_re_casefix.py @@ -0,0 +1,96 @@ +#! /usr/bin/env python3 +# This script generates Lib/re/_casefix.py. + +import collections +import sys +import unicodedata + +SCRIPT_NAME = 'Tools/build/generate_re_casefix.py' + +def update_file(file, content): + try: + with open(file, 'r', encoding='utf-8') as fobj: + if fobj.read() == content: + return False + except (OSError, ValueError): + pass + with open(file, 'w', encoding='utf-8') as fobj: + fobj.write(content) + return True + +re_casefix_template = f"""\ +# Auto-generated by {SCRIPT_NAME}. + +# Maps the code of lowercased character to codes of different lowercased +# characters which have the same uppercase. +_EXTRA_CASES = { +%s +} +""" + +def uname(i): + return unicodedata.name(chr(i), r'U+%04X' % i) + +class hexint(int): + def __repr__(self): + return '%#06x' % self + +def alpha(i): + c = chr(i) + return c if c.isalpha() else ascii(c)[1:-1] + + +def main(outfile='Lib/re/_casefix.py'): + # Find sets of characters which have the same uppercase. + equivalent_chars = collections.defaultdict(str) + for c in map(chr, range(sys.maxunicode + 1)): + equivalent_chars[c.upper()] += c + equivalent_chars = [t for t in equivalent_chars.values() if len(t) > 1] + + # List of codes of lowercased characters which have the same uppercase. + equivalent_lower_codes = [sorted(t) + for s in equivalent_chars + for t in [set(ord(c.lower()) for c in s)] + if len(t) > 1] + + bad_codes = [] + for t in equivalent_lower_codes: + for i in t: + if i > 0xffff: + bad_codes.extend(t) + try: + bad_codes.append(ord(chr(i).upper())) + except (ValueError, TypeError): + pass + break + if bad_codes: + print('Case-insensitive matching may not work correctly for character:', + file=sys.stderr) + for i in sorted(bad_codes): + print(" '%s' (U+%04x, %s)" % (alpha(i), i, uname(i)), + file=sys.stderr) + sys.exit(1) + + mapping = {i: tuple(j for j in t if i != j) + for t in equivalent_lower_codes + for i in t} + + items = [] + for i, t in sorted(mapping.items()): + items.append(' # %s: %s' % ( + uname(i), + ', '.join(map(uname, t)), + )) + items.append(" %r: %r, # '%s': '%s'" % ( + hexint(i), + tuple(map(hexint, t)), + alpha(i), + ''.join(map(alpha, t)), + )) + + update_file(outfile, re_casefix_template % '\n'.join(items)) + + +if __name__ == '__main__': + import sys + main(*sys.argv[1:]) diff --git a/Tools/build/generate_sre_constants.py b/Tools/build/generate_sre_constants.py new file mode 100755 index 00000000000..abea069c8bc --- /dev/null +++ b/Tools/build/generate_sre_constants.py @@ -0,0 +1,80 @@ +#! /usr/bin/env python3 +# This script generates Modules/_sre/sre_constants.h from Lib/re/_constants.py. + +SCRIPT_NAME = 'Tools/build/generate_sre_constants.py' + + +def update_file(file, content): + try: + with open(file, 'r') as fobj: + if fobj.read() == content: + return False + except (OSError, ValueError): + pass + with open(file, 'w') as fobj: + fobj.write(content) + return True + +sre_constants_header = f"""\ +/* + * Secret Labs' Regular Expression Engine + * + * regular expression matching engine + * + * Auto-generated by {SCRIPT_NAME} from + * Lib/re/_constants.py. + * + * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. + * + * See the sre.c file for information on usage and redistribution. + */ + +""" + +def main( + infile="Lib/re/_constants.py", + outfile_constants="Modules/_sre/sre_constants.h", + outfile_targets="Modules/_sre/sre_targets.h", +): + ns = {} + with open(infile) as fp: + code = fp.read() + exec(code, ns) + + def dump(d, prefix): + items = sorted(d) + for item in items: + yield "#define %s_%s %d\n" % (prefix, item, item) + + def dump2(d, prefix): + items = [(value, name) for name, value in d.items() + if name.startswith(prefix)] + for value, name in sorted(items): + yield "#define %s %d\n" % (name, value) + + def dump_gotos(d, prefix): + for i, item in enumerate(sorted(d)): + assert i == item + yield f" &&{prefix}_{item},\n" + + content = [sre_constants_header] + content.append("#define SRE_MAGIC %d\n" % ns["MAGIC"]) + content.extend(dump(ns["OPCODES"], "SRE_OP")) + content.extend(dump(ns["ATCODES"], "SRE")) + content.extend(dump(ns["CHCODES"], "SRE")) + content.extend(dump2(ns, "SRE_FLAG_")) + content.extend(dump2(ns, "SRE_INFO_")) + + update_file(outfile_constants, ''.join(content)) + + content = [sre_constants_header] + content.append(f"static void *sre_targets[{len(ns['OPCODES'])}] = {{\n") + content.extend(dump_gotos(ns["OPCODES"], "TARGET_SRE_OP")) + content.append("};\n") + + update_file(outfile_targets, ''.join(content)) + + +if __name__ == '__main__': + import sys + main(*sys.argv[1:]) diff --git a/Tools/scripts/generate_stdlib_module_names.py b/Tools/build/generate_stdlib_module_names.py similarity index 60% rename from Tools/scripts/generate_stdlib_module_names.py rename to Tools/build/generate_stdlib_module_names.py index 3e896ba7375..c8a23f41fdd 100644 --- a/Tools/scripts/generate_stdlib_module_names.py +++ b/Tools/build/generate_stdlib_module_names.py @@ -1,17 +1,19 @@ # This script lists the names of standard library modules # to update Python/stdlib_mod_names.h +import _imp import os.path import re import subprocess import sys import sysconfig +from check_extension_modules import ModuleChecker + + +SCRIPT_NAME = 'Tools/build/generate_stdlib_module_names.py' SRC_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) STDLIB_PATH = os.path.join(SRC_DIR, 'Lib') -MODULES_SETUP = os.path.join(SRC_DIR, 'Modules', 'Setup') -SETUP_PY = os.path.join(SRC_DIR, 'setup.py') -TEST_EMBED = os.path.join(SRC_DIR, 'Programs', '_testembed') IGNORE = { '__init__', @@ -27,38 +29,21 @@ IGNORE = { '_ctypes_test', '_testbuffer', '_testcapi', + '_testclinic', '_testconsole', '_testimportmultiple', '_testinternalcapi', '_testmultiphase', + '_testsinglephase', '_xxsubinterpreters', '_xxtestfuzz', - 'distutils.tests', 'idlelib.idle_test', - 'lib2to3.tests', 'test', 'xxlimited', 'xxlimited_35', 'xxsubtype', } -# Windows extension modules -WINDOWS_MODULES = ( - '_msi', - '_overlapped', - '_testconsole', - '_winapi', - 'msvcrt', - 'nt', - 'winreg', - 'winsound' -) - -# macOS extension modules -MACOS_MODULES = ( - '_scproxy', -) - # Pure Python modules (Lib/*.py) def list_python_modules(names): for filename in os.listdir(STDLIB_PATH): @@ -81,52 +66,21 @@ def list_packages(names): names.add(name) -# Extension modules built by setup.py -def list_setup_extensions(names): - cmd = [sys.executable, SETUP_PY, "-q", "build", "--list-module-names"] - output = subprocess.check_output(cmd) - output = output.decode("utf8") - extensions = output.splitlines() - names |= set(extensions) - - -# Built-in and extension modules built by Modules/Setup +# Built-in and extension modules built by Modules/Setup* +# includes Windows and macOS extensions. def list_modules_setup_extensions(names): - assign_var = re.compile("^[A-Z]+=") - - with open(MODULES_SETUP, encoding="utf-8") as modules_fp: - for line in modules_fp: - # Strip comment - line = line.partition("#")[0] - line = line.rstrip() - if not line: - continue - if assign_var.match(line): - # Ignore "VAR=VALUE" - continue - if line in ("*disabled*", "*shared*"): - continue - parts = line.split() - if len(parts) < 2: - continue - # "errno errnomodule.c" => write "errno" - name = parts[0] - names.add(name) + checker = ModuleChecker() + names.update(checker.list_module_names(all=True)) # List frozen modules of the PyImport_FrozenModules list (Python/frozen.c). # Use the "./Programs/_testembed list_frozen" command. def list_frozen(names): - args = [TEST_EMBED, 'list_frozen'] - proc = subprocess.run(args, stdout=subprocess.PIPE, text=True) - exitcode = proc.returncode - if exitcode: - cmd = ' '.join(args) - print(f"{cmd} failed with exitcode {exitcode}") - sys.exit(exitcode) submodules = set() - for line in proc.stdout.splitlines(): - name = line.strip() + for name in _imp._frozen_module_names(): + # To skip __hello__, __hello_alias__ and etc. + if name.startswith('__'): + continue if '.' in name: submodules.add(name) else: @@ -140,9 +94,8 @@ def list_frozen(names): def list_modules(): - names = set(sys.builtin_module_names) | set(WINDOWS_MODULES) | set(MACOS_MODULES) + names = set(sys.builtin_module_names) list_modules_setup_extensions(names) - list_setup_extensions(names) list_packages(names) list_python_modules(names) list_frozen(names) @@ -162,7 +115,7 @@ def list_modules(): def write_modules(fp, names): - print("// Auto-generated by Tools/scripts/generate_stdlib_module_names.py.", + print(f"// Auto-generated by {SCRIPT_NAME}.", file=fp) print("// List used to create sys.stdlib_module_names.", file=fp) print(file=fp) diff --git a/Tools/scripts/generate_token.py b/Tools/build/generate_token.py similarity index 86% rename from Tools/scripts/generate_token.py rename to Tools/build/generate_token.py index 77bb5bd5eca..fc12835b776 100755 --- a/Tools/scripts/generate_token.py +++ b/Tools/build/generate_token.py @@ -7,6 +7,8 @@ # Lib/token.py +SCRIPT_NAME = 'Tools/build/generate_token.py' +AUTO_GENERATED_BY_SCRIPT = f'Auto-generated by {SCRIPT_NAME}' NT_OFFSET = 256 def load_tokens(path): @@ -47,17 +49,22 @@ def update_file(file, content): return True -token_h_template = """\ -/* Auto-generated by Tools/scripts/generate_token.py */ +token_h_template = f"""\ +/* {AUTO_GENERATED_BY_SCRIPT} */ +""" +token_h_template += """\ /* Token types */ -#ifndef Py_LIMITED_API -#ifndef Py_TOKEN_H -#define Py_TOKEN_H +#ifndef Py_INTERNAL_TOKEN_H +#define Py_INTERNAL_TOKEN_H #ifdef __cplusplus extern "C" { #endif +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + #undef TILDE /* Prevent clash of our definition with system macro. Ex AIX, ioctl.h */ %s\ @@ -75,19 +82,19 @@ extern "C" { (x) == DEDENT) +// Symbols exported for test_peg_generator PyAPI_DATA(const char * const) _PyParser_TokenNames[]; /* Token names */ -PyAPI_FUNC(int) PyToken_OneChar(int); -PyAPI_FUNC(int) PyToken_TwoChars(int, int); -PyAPI_FUNC(int) PyToken_ThreeChars(int, int, int); +PyAPI_FUNC(int) _PyToken_OneChar(int); +PyAPI_FUNC(int) _PyToken_TwoChars(int, int); +PyAPI_FUNC(int) _PyToken_ThreeChars(int, int, int); #ifdef __cplusplus } #endif -#endif /* !Py_TOKEN_H */ -#endif /* Py_LIMITED_API */ +#endif // !Py_INTERNAL_TOKEN_H """ -def make_h(infile, outfile='Include/token.h'): +def make_h(infile, outfile='Include/internal/pycore_token.h'): tok_names, ERRORTOKEN, string_to_tok = load_tokens(infile) defines = [] @@ -102,11 +109,13 @@ def make_h(infile, outfile='Include/token.h'): print("%s regenerated from %s" % (outfile, infile)) -token_c_template = """\ -/* Auto-generated by Tools/scripts/generate_token.py */ +token_c_template = f"""\ +/* {AUTO_GENERATED_BY_SCRIPT} */ +""" +token_c_template += """\ #include "Python.h" -#include "token.h" +#include "pycore_token.h" /* Token names */ @@ -117,21 +126,21 @@ const char * const _PyParser_TokenNames[] = { /* Return the token corresponding to a single character */ int -PyToken_OneChar(int c1) +_PyToken_OneChar(int c1) { %s\ return OP; } int -PyToken_TwoChars(int c1, int c2) +_PyToken_TwoChars(int c1, int c2) { %s\ return OP; } int -PyToken_ThreeChars(int c1, int c2, int c3) +_PyToken_ThreeChars(int c1, int c2, int c3) { %s\ return OP; @@ -186,8 +195,8 @@ def make_c(infile, outfile='Parser/token.c'): print("%s regenerated from %s" % (outfile, infile)) -token_inc_template = """\ -.. Auto-generated by Tools/scripts/generate_token.py +token_inc_template = f"""\ +.. {AUTO_GENERATED_BY_SCRIPT} %s .. data:: N_TOKENS @@ -210,10 +219,11 @@ def make_rst(infile, outfile='Doc/library/token-list.inc'): print("%s regenerated from %s" % (outfile, infile)) -token_py_template = '''\ +token_py_template = f'''\ """Token constants.""" -# Auto-generated by Tools/scripts/generate_token.py - +# {AUTO_GENERATED_BY_SCRIPT} +''' +token_py_template += ''' __all__ = ['tok_name', 'ISTERMINAL', 'ISNONTERMINAL', 'ISEOF'] %s diff --git a/Tools/scripts/parse_html5_entities.py b/Tools/build/parse_html5_entities.py similarity index 79% rename from Tools/scripts/parse_html5_entities.py rename to Tools/build/parse_html5_entities.py index c011328b010..d2bf2909103 100755 --- a/Tools/scripts/parse_html5_entities.py +++ b/Tools/build/parse_html5_entities.py @@ -2,10 +2,14 @@ """ Utility for parsing HTML5 entity definitions available from: - http://dev.w3.org/html5/spec/entities.json + https://html.spec.whatwg.org/entities.json + https://html.spec.whatwg.org/multipage/named-characters.html + +The page now contains the following note: + + "This list is static and will not be expanded or changed in the future." Written by Ezio Melotti and Iuliia Proskurnia. - """ import os @@ -14,7 +18,10 @@ import json from urllib.request import urlopen from html.entities import html5 -entities_url = 'http://dev.w3.org/html5/spec/entities.json' +SCRIPT_NAME = 'Tools/build/parse_html5_entities.py' +PAGE_URL = 'https://html.spec.whatwg.org/multipage/named-characters.html' +ENTITIES_URL = 'https://html.spec.whatwg.org/entities.json' +HTML5_SECTION_START = '# HTML5 named character references' def get_json(url): """Download the json file from the url and returns a decoded object.""" @@ -62,9 +69,15 @@ def write_items(entities, file=sys.stdout): # be before their equivalent lowercase version. keys = sorted(entities.keys()) keys = sorted(keys, key=str.lower) + print(HTML5_SECTION_START, file=file) + print(f'# Generated by {SCRIPT_NAME}\n' + f'# from {ENTITIES_URL} and\n' + f'# {PAGE_URL}.\n' + f'# Map HTML5 named character references to the ' + f'equivalent Unicode character(s).', file=file) print('html5 = {', file=file) for name in keys: - print(' {!r}: {!a},'.format(name, entities[name]), file=file) + print(f' {name!r}: {entities[name]!a},', file=file) print('}', file=file) @@ -72,11 +85,8 @@ if __name__ == '__main__': # without args print a diff between html.entities.html5 and new_html5 # with --create print the new html5 dict # with --patch patch the Lib/html/entities.py file - new_html5 = create_dict(get_json(entities_url)) + new_html5 = create_dict(get_json(ENTITIES_URL)) if '--create' in sys.argv: - print('# map the HTML5 named character references to the ' - 'equivalent Unicode character(s)') - print('# Generated by {}. Do not edit manually.'.format(__file__)) write_items(new_html5) elif '--patch' in sys.argv: fname = 'Lib/html/entities.py' @@ -84,7 +94,7 @@ if __name__ == '__main__': with open(fname) as f1, open(temp_fname, 'w') as f2: skip = False for line in f1: - if line.startswith('html5 = {'): + if line.startswith(HTML5_SECTION_START): write_items(new_html5, file=f2) skip = True continue diff --git a/Tools/scripts/smelly.py b/Tools/build/smelly.py similarity index 93% rename from Tools/scripts/smelly.py rename to Tools/build/smelly.py index fb01660dea3..276a5ab2cc8 100755 --- a/Tools/scripts/smelly.py +++ b/Tools/build/smelly.py @@ -108,8 +108,11 @@ def check_library(library, dynamic=False): def check_extensions(): print(__file__) - srcdir = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) - filename = os.path.join(srcdir, "pybuilddir.txt") + # This assumes pybuilddir.txt is in same directory as pyconfig.h. + # In the case of out-of-tree builds, we can't assume pybuilddir.txt is + # in the source folder. + config_dir = os.path.dirname(sysconfig.get_config_h_filename()) + filename = os.path.join(config_dir, "pybuilddir.txt") try: with open(filename, encoding="utf-8") as fp: pybuilddir = fp.readline() @@ -118,7 +121,7 @@ def check_extensions(): return True print(f"Check extension modules from {pybuilddir} directory") - builddir = os.path.join(srcdir, pybuilddir) + builddir = os.path.join(config_dir, pybuilddir) nsymbol = 0 for name in os.listdir(builddir): if not name.endswith(".so"): diff --git a/Tools/scripts/stable_abi.py b/Tools/build/stable_abi.py old mode 100755 new mode 100644 similarity index 73% rename from Tools/scripts/stable_abi.py rename to Tools/build/stable_abi.py index 0179f3c12fc..88db93e935e --- a/Tools/scripts/stable_abi.py +++ b/Tools/build/stable_abi.py @@ -14,8 +14,9 @@ import subprocess import sysconfig import argparse import textwrap +import tomllib import difflib -import shutil +import pprint import sys import os import os.path @@ -23,6 +24,7 @@ import io import re import csv +SCRIPT_NAME = 'Tools/build/stable_abi.py' MISSING = object() EXCLUDED_HEADERS = { @@ -45,23 +47,16 @@ EXCLUDED_HEADERS = { MACOS = (sys.platform == "darwin") UNIXY = MACOS or (sys.platform == "linux") # XXX should this be "not Windows"? -IFDEF_DOC_NOTES = { - 'MS_WINDOWS': 'on Windows', - 'HAVE_FORK': 'on platforms with fork()', - 'USE_STACKCHECK': 'on platforms with USE_STACKCHECK', -} -# The stable ABI manifest (Misc/stable_abi.txt) exists only to fill the +# The stable ABI manifest (Misc/stable_abi.toml) exists only to fill the # following dataclasses. # Feel free to change its syntax (and the `parse_manifest` function) # to better serve that purpose (while keeping it human-readable). -@dataclasses.dataclass class Manifest: """Collection of `ABIItem`s forming the stable ABI/limited API.""" - - kind = 'manifest' - contents: dict = dataclasses.field(default_factory=dict) + def __init__(self): + self.contents = dict() def add(self, item): if item.name in self.contents: @@ -70,14 +65,6 @@ class Manifest: raise ValueError(f'duplicate ABI item {item.name}') self.contents[item.name] = item - @property - def feature_defines(self): - """Return all feature defines which affect what's available - - These are e.g. HAVE_FORK and MS_WINDOWS. - """ - return set(item.ifdef for item in self.contents.values()) - {None} - def select(self, kinds, *, include_abi_only=True, ifdef=None): """Yield selected items of the manifest @@ -86,7 +73,7 @@ class Manifest: stable ABI. If False, include only items from the limited API (i.e. items people should use today) - ifdef: set of feature defines (e.g. {'HAVE_FORK', 'MS_WINDOWS'}). + ifdef: set of feature macros (e.g. {'HAVE_FORK', 'MS_WINDOWS'}). If None (default), items are not filtered by this. (This is different from the empty set, which filters out all such conditional items.) @@ -104,77 +91,75 @@ class Manifest: def dump(self): """Yield lines to recreate the manifest file (sans comments/newlines)""" - # Recursive in preparation for struct member & function argument nodes for item in self.contents.values(): - yield from item.dump(indent=0) + fields = dataclasses.fields(item) + yield f"[{item.kind}.{item.name}]" + for field in fields: + if field.name in {'name', 'value', 'kind'}: + continue + value = getattr(item, field.name) + if value == field.default: + pass + elif value is True: + yield f" {field.name} = true" + elif value: + yield f" {field.name} = {value!r}" + +itemclasses = {} +def itemclass(kind): + """Register the decorated class in `itemclasses`""" + def decorator(cls): + itemclasses[kind] = cls + return cls + return decorator + +@itemclass('function') +@itemclass('macro') +@itemclass('data') +@itemclass('const') +@itemclass('typedef') @dataclasses.dataclass class ABIItem: """Information on one item (function, macro, struct, etc.)""" - kind: str name: str + kind: str added: str = None - contents: list = dataclasses.field(default_factory=list) abi_only: bool = False ifdef: str = None - KINDS = frozenset({ - 'struct', 'function', 'macro', 'data', 'const', 'typedef', - }) +@itemclass('feature_macro') +@dataclasses.dataclass(kw_only=True) +class FeatureMacro(ABIItem): + name: str + doc: str + windows: bool = False + abi_only: bool = True + +@itemclass('struct') +@dataclasses.dataclass(kw_only=True) +class Struct(ABIItem): + struct_abi_kind: str + members: list = None - def dump(self, indent=0): - yield f"{' ' * indent}{self.kind} {self.name}" - if self.added: - yield f"{' ' * (indent+1)}added {self.added}" - if self.ifdef: - yield f"{' ' * (indent+1)}ifdef {self.ifdef}" - if self.abi_only: - yield f"{' ' * (indent+1)}abi_only" def parse_manifest(file): """Parse the given file (iterable of lines) to a Manifest""" - LINE_RE = re.compile('(?P[ ]*)(?P[^ ]+)[ ]*(?P.*)') manifest = Manifest() - # parents of currently processed line, each with its indentation level - levels = [(manifest, -1)] + data = tomllib.load(file) - def raise_error(msg): - raise SyntaxError(f'line {lineno}: {msg}') + for kind, itemclass in itemclasses.items(): + for name, item_data in data[kind].items(): + try: + item = itemclass(name=name, kind=kind, **item_data) + manifest.add(item) + except BaseException as exc: + exc.add_note(f'in {kind} {name}') + raise - for lineno, line in enumerate(file, start=1): - line, sep, comment = line.partition('#') - line = line.rstrip() - if not line: - continue - match = LINE_RE.fullmatch(line) - if not match: - raise_error(f'invalid syntax: {line}') - level = len(match['indent']) - kind = match['kind'] - content = match['content'] - while level <= levels[-1][1]: - levels.pop() - parent = levels[-1][0] - entry = None - if kind in ABIItem.KINDS: - if parent.kind not in {'manifest'}: - raise_error(f'{kind} cannot go in {parent.kind}') - entry = ABIItem(kind, content) - parent.add(entry) - elif kind in {'added', 'ifdef'}: - if parent.kind not in ABIItem.KINDS: - raise_error(f'{kind} cannot go in {parent.kind}') - setattr(parent, kind, content) - elif kind in {'abi_only'}: - if parent.kind not in {'function', 'data'}: - raise_error(f'{kind} cannot go in {parent.kind}') - parent.abi_only = True - else: - raise_error(f"unknown kind {kind!r}") - levels.append((entry, level)) return manifest # The tool can run individual "actions". @@ -198,11 +183,12 @@ def generator(var_name, default_path): def gen_python3dll(manifest, args, outfile): """Generate/check the source for the Windows stable ABI library""" write = partial(print, file=outfile) - write(textwrap.dedent(r""" + content = f""" /* Re-export stable Python ABI */ - /* Generated by Tools/scripts/stable_abi.py */ - + /* Generated by {SCRIPT_NAME} */ + """ + content += r""" #ifdef _M_IX86 #define DECORATE "_" #else @@ -213,14 +199,20 @@ def gen_python3dll(manifest, args, outfile): __pragma(comment(linker, "/EXPORT:" DECORATE #name "=" PYTHON_DLL_NAME "." #name)) #define EXPORT_DATA(name) \ __pragma(comment(linker, "/EXPORT:" DECORATE #name "=" PYTHON_DLL_NAME "." #name ",DATA")) - """)) + """ + write(textwrap.dedent(content)) def sort_key(item): return item.name.lower() + windows_feature_macros = { + item.name for item in manifest.select({'feature_macro'}) if item.windows + } for item in sorted( manifest.select( - {'function'}, include_abi_only=True, ifdef={'MS_WINDOWS'}), + {'function'}, + include_abi_only=True, + ifdef=windows_feature_macros), key=sort_key): write(f'EXPORT_FUNC({item.name})') @@ -228,7 +220,9 @@ def gen_python3dll(manifest, args, outfile): for item in sorted( manifest.select( - {'data'}, include_abi_only=True, ifdef={'MS_WINDOWS'}), + {'data'}, + include_abi_only=True, + ifdef=windows_feature_macros), key=sort_key): write(f'EXPORT_DATA({item.name})') @@ -245,18 +239,29 @@ REST_ROLES = { def gen_doc_annotations(manifest, args, outfile): """Generate/check the stable ABI list for documentation annotations""" writer = csv.DictWriter( - outfile, ['role', 'name', 'added', 'ifdef_note'], lineterminator='\n') + outfile, + ['role', 'name', 'added', 'ifdef_note', 'struct_abi_kind'], + lineterminator='\n') writer.writeheader() for item in manifest.select(REST_ROLES.keys(), include_abi_only=False): if item.ifdef: - ifdef_note = IFDEF_DOC_NOTES[item.ifdef] + ifdef_note = manifest.contents[item.ifdef].doc else: ifdef_note = None - writer.writerow({ + row = { 'role': REST_ROLES[item.kind], 'name': item.name, 'added': item.added, - 'ifdef_note': ifdef_note}) + 'ifdef_note': ifdef_note} + rows = [row] + if item.kind == 'struct': + row['struct_abi_kind'] = item.struct_abi_kind + for member_name in item.members or (): + rows.append({ + 'role': 'member', + 'name': f'{item.name}.{member_name}', + 'added': item.added}) + writer.writerows(rows) @generator("ctypes_test", 'Lib/test/test_stable_abi_ctypes.py') def gen_ctypes_test(manifest, args, outfile): @@ -268,23 +273,43 @@ def gen_ctypes_test(manifest, args, outfile): """Test that all symbols of the Stable ABI are accessible using ctypes """ + import sys import unittest from test.support.import_helper import import_module + from _testcapi import get_feature_macros + feature_macros = get_feature_macros() ctypes_test = import_module('ctypes') class TestStableABIAvailability(unittest.TestCase): def test_available_symbols(self): + for symbol_name in SYMBOL_NAMES: with self.subTest(symbol_name): ctypes_test.pythonapi[symbol_name] + def test_feature_macros(self): + self.assertEqual( + set(get_feature_macros()), EXPECTED_FEATURE_MACROS) + + # The feature macros for Windows are used in creating the DLL + # definition, so they must be known on all platforms. + # If we are on Windows, we check that the hardcoded data matches + # the reality. + @unittest.skipIf(sys.platform != "win32", "Windows specific test") + def test_windows_feature_macros(self): + for name, value in WINDOWS_FEATURE_MACROS.items(): + if value != 'maybe': + with self.subTest(name): + self.assertEqual(feature_macros[name], value) + SYMBOL_NAMES = ( ''')) items = manifest.select( {'function', 'data'}, include_abi_only=True, - ifdef=set()) + ) + optional_items = {} for item in items: if item.name in ( # Some symbols aren't exported on all platforms. @@ -292,8 +317,45 @@ def gen_ctypes_test(manifest, args, outfile): 'PyModule_Create2', 'PyModule_FromDefAndSpec2', ): continue - write(f' "{item.name}",') + if item.ifdef: + optional_items.setdefault(item.ifdef, []).append(item.name) + else: + write(f' "{item.name}",') write(")") + for ifdef, names in optional_items.items(): + write(f"if feature_macros[{ifdef!r}]:") + write(f" SYMBOL_NAMES += (") + for name in names: + write(f" {name!r},") + write(" )") + write("") + feature_macros = list(manifest.select({'feature_macro'})) + feature_names = sorted(m.name for m in feature_macros) + write(f"EXPECTED_FEATURE_MACROS = set({pprint.pformat(feature_names)})") + + windows_feature_macros = {m.name: m.windows for m in feature_macros} + write(f"WINDOWS_FEATURE_MACROS = {pprint.pformat(windows_feature_macros)}") + + +@generator("testcapi_feature_macros", 'Modules/_testcapi_feature_macros.inc') +def gen_testcapi_feature_macros(manifest, args, outfile): + """Generate/check the stable ABI list for documentation annotations""" + write = partial(print, file=outfile) + write('// Generated by Tools/scripts/stable_abi.py') + write() + write('// Add an entry in dict `result` for each Stable ABI feature macro.') + write() + for macro in manifest.select({'feature_macro'}): + name = macro.name + write(f'#ifdef {name}') + write(f' res = PyDict_SetItemString(result, "{name}", Py_True);') + write('#else') + write(f' res = PyDict_SetItemString(result, "{name}", Py_False);') + write('#endif') + write('if (res) {') + write(' Py_DECREF(result); return NULL;') + write('}') + write() def generate_or_check(manifest, args, path, func): @@ -330,7 +392,8 @@ def do_unixy_check(manifest, args): # Get all macros first: we'll need feature macros like HAVE_FORK and # MS_WINDOWS for everything else present_macros = gcc_get_limited_api_macros(['Include/Python.h']) - feature_defines = manifest.feature_defines & present_macros + feature_macros = set(m.name for m in manifest.select({'feature_macro'})) + feature_macros &= present_macros # Check that we have all needed macros expected_macros = set( @@ -343,7 +406,7 @@ def do_unixy_check(manifest, args): + 'with Py_LIMITED_API:') expected_symbols = set(item.name for item in manifest.select( - {'function', 'data'}, include_abi_only=True, ifdef=feature_defines, + {'function', 'data'}, include_abi_only=True, ifdef=feature_macros, )) # Check the static library (*.a) @@ -363,7 +426,7 @@ def do_unixy_check(manifest, args): # Check definitions in the header files expected_defs = set(item.name for item in manifest.select( - {'function', 'data'}, include_abi_only=False, ifdef=feature_defines, + {'function', 'data'}, include_abi_only=False, ifdef=feature_macros, )) found_defs = gcc_get_limited_api_definitions(['Include/Python.h']) missing_defs = expected_defs - found_defs @@ -540,6 +603,28 @@ def check_private_names(manifest): f'`{name}` is private (underscore-prefixed) and should be ' + 'removed from the stable ABI list or or marked `abi_only`') +def check_dump(manifest, filename): + """Check that manifest.dump() corresponds to the data. + + Mainly useful when debugging this script. + """ + dumped = tomllib.loads('\n'.join(manifest.dump())) + with filename.open('rb') as file: + from_file = tomllib.load(file) + if dumped != from_file: + print(f'Dump differs from loaded data!', file=sys.stderr) + diff = difflib.unified_diff( + pprint.pformat(dumped).splitlines(), + pprint.pformat(from_file).splitlines(), + '', str(filename), + lineterm='', + ) + for line in diff: + print(line, file=sys.stderr) + return False + else: + return True + def main(): parser = argparse.ArgumentParser( description=__doc__, @@ -601,7 +686,16 @@ def main(): run_all_generators = True args.unixy_check = True - with args.file.open() as file: + try: + file = args.file.open('rb') + except FileNotFoundError as err: + if args.file.suffix == '.txt': + # Provide a better error message + suggestion = args.file.with_suffix('.toml') + raise FileNotFoundError( + f'{args.file} not found. Did you mean {suggestion} ?') from err + raise + with file: manifest = parse_manifest(file) check_private_names(manifest) @@ -614,7 +708,7 @@ def main(): if args.dump: for line in manifest.dump(): print(line) - results['dump'] = True + results['dump'] = check_dump(manifest, args.file) for gen in generators: filename = getattr(args, gen.var_name) @@ -655,7 +749,7 @@ def main(): And in PEP 384: - https://www.python.org/dev/peps/pep-0384/ + https://peps.python.org/pep-0384/ """) diff --git a/Tools/build/umarshal.py b/Tools/build/umarshal.py new file mode 100644 index 00000000000..f61570cbaff --- /dev/null +++ b/Tools/build/umarshal.py @@ -0,0 +1,325 @@ +# Implementat marshal.loads() in pure Python + +import ast + +from typing import Any, Tuple + + +class Type: + # Adapted from marshal.c + NULL = ord('0') + NONE = ord('N') + FALSE = ord('F') + TRUE = ord('T') + STOPITER = ord('S') + ELLIPSIS = ord('.') + INT = ord('i') + INT64 = ord('I') + FLOAT = ord('f') + BINARY_FLOAT = ord('g') + COMPLEX = ord('x') + BINARY_COMPLEX = ord('y') + LONG = ord('l') + STRING = ord('s') + INTERNED = ord('t') + REF = ord('r') + TUPLE = ord('(') + LIST = ord('[') + DICT = ord('{') + CODE = ord('c') + UNICODE = ord('u') + UNKNOWN = ord('?') + SET = ord('<') + FROZENSET = ord('>') + ASCII = ord('a') + ASCII_INTERNED = ord('A') + SMALL_TUPLE = ord(')') + SHORT_ASCII = ord('z') + SHORT_ASCII_INTERNED = ord('Z') + + +FLAG_REF = 0x80 # with a type, add obj to index + +NULL = object() # marker + +# Cell kinds +CO_FAST_LOCAL = 0x20 +CO_FAST_CELL = 0x40 +CO_FAST_FREE = 0x80 + + +class Code: + def __init__(self, **kwds: Any): + self.__dict__.update(kwds) + + def __repr__(self) -> str: + return f"Code(**{self.__dict__})" + + co_localsplusnames: Tuple[str] + co_localspluskinds: Tuple[int] + + def get_localsplus_names(self, select_kind: int) -> Tuple[str, ...]: + varnames: list[str] = [] + for name, kind in zip(self.co_localsplusnames, + self.co_localspluskinds): + if kind & select_kind: + varnames.append(name) + return tuple(varnames) + + @property + def co_varnames(self) -> Tuple[str, ...]: + return self.get_localsplus_names(CO_FAST_LOCAL) + + @property + def co_cellvars(self) -> Tuple[str, ...]: + return self.get_localsplus_names(CO_FAST_CELL) + + @property + def co_freevars(self) -> Tuple[str, ...]: + return self.get_localsplus_names(CO_FAST_FREE) + + @property + def co_nlocals(self) -> int: + return len(self.co_varnames) + + +class Reader: + # A fairly literal translation of the marshal reader. + + def __init__(self, data: bytes): + self.data: bytes = data + self.end: int = len(self.data) + self.pos: int = 0 + self.refs: list[Any] = [] + self.level: int = 0 + + def r_string(self, n: int) -> bytes: + assert 0 <= n <= self.end - self.pos + buf = self.data[self.pos : self.pos + n] + self.pos += n + return buf + + def r_byte(self) -> int: + buf = self.r_string(1) + return buf[0] + + def r_short(self) -> int: + buf = self.r_string(2) + x = buf[0] + x |= buf[1] << 8 + x |= -(x & (1<<15)) # Sign-extend + return x + + def r_long(self) -> int: + buf = self.r_string(4) + x = buf[0] + x |= buf[1] << 8 + x |= buf[2] << 16 + x |= buf[3] << 24 + x |= -(x & (1<<31)) # Sign-extend + return x + + def r_long64(self) -> int: + buf = self.r_string(8) + x = buf[0] + x |= buf[1] << 8 + x |= buf[2] << 16 + x |= buf[3] << 24 + x |= buf[1] << 32 + x |= buf[1] << 40 + x |= buf[1] << 48 + x |= buf[1] << 56 + x |= -(x & (1<<63)) # Sign-extend + return x + + def r_PyLong(self) -> int: + n = self.r_long() + size = abs(n) + x = 0 + # Pray this is right + for i in range(size): + x |= self.r_short() << i*15 + if n < 0: + x = -x + return x + + def r_float_bin(self) -> float: + buf = self.r_string(8) + import struct # Lazy import to avoid breaking UNIX build + return struct.unpack("d", buf)[0] + + def r_float_str(self) -> float: + n = self.r_byte() + buf = self.r_string(n) + return ast.literal_eval(buf.decode("ascii")) + + def r_ref_reserve(self, flag: int) -> int: + if flag: + idx = len(self.refs) + self.refs.append(None) + return idx + else: + return 0 + + def r_ref_insert(self, obj: Any, idx: int, flag: int) -> Any: + if flag: + self.refs[idx] = obj + return obj + + def r_ref(self, obj: Any, flag: int) -> Any: + assert flag & FLAG_REF + self.refs.append(obj) + return obj + + def r_object(self) -> Any: + old_level = self.level + try: + return self._r_object() + finally: + self.level = old_level + + def _r_object(self) -> Any: + code = self.r_byte() + flag = code & FLAG_REF + type = code & ~FLAG_REF + # print(" "*self.level + f"{code} {flag} {type} {chr(type)!r}") + self.level += 1 + + def R_REF(obj: Any) -> Any: + if flag: + obj = self.r_ref(obj, flag) + return obj + + if type == Type.NULL: + return NULL + elif type == Type.NONE: + return None + elif type == Type.ELLIPSIS: + return Ellipsis + elif type == Type.FALSE: + return False + elif type == Type.TRUE: + return True + elif type == Type.INT: + return R_REF(self.r_long()) + elif type == Type.INT64: + return R_REF(self.r_long64()) + elif type == Type.LONG: + return R_REF(self.r_PyLong()) + elif type == Type.FLOAT: + return R_REF(self.r_float_str()) + elif type == Type.BINARY_FLOAT: + return R_REF(self.r_float_bin()) + elif type == Type.COMPLEX: + return R_REF(complex(self.r_float_str(), + self.r_float_str())) + elif type == Type.BINARY_COMPLEX: + return R_REF(complex(self.r_float_bin(), + self.r_float_bin())) + elif type == Type.STRING: + n = self.r_long() + return R_REF(self.r_string(n)) + elif type == Type.ASCII_INTERNED or type == Type.ASCII: + n = self.r_long() + return R_REF(self.r_string(n).decode("ascii")) + elif type == Type.SHORT_ASCII_INTERNED or type == Type.SHORT_ASCII: + n = self.r_byte() + return R_REF(self.r_string(n).decode("ascii")) + elif type == Type.INTERNED or type == Type.UNICODE: + n = self.r_long() + return R_REF(self.r_string(n).decode("utf8", "surrogatepass")) + elif type == Type.SMALL_TUPLE: + n = self.r_byte() + idx = self.r_ref_reserve(flag) + retval: Any = tuple(self.r_object() for _ in range(n)) + self.r_ref_insert(retval, idx, flag) + return retval + elif type == Type.TUPLE: + n = self.r_long() + idx = self.r_ref_reserve(flag) + retval = tuple(self.r_object() for _ in range(n)) + self.r_ref_insert(retval, idx, flag) + return retval + elif type == Type.LIST: + n = self.r_long() + retval = R_REF([]) + for _ in range(n): + retval.append(self.r_object()) + return retval + elif type == Type.DICT: + retval = R_REF({}) + while True: + key = self.r_object() + if key == NULL: + break + val = self.r_object() + retval[key] = val + return retval + elif type == Type.SET: + n = self.r_long() + retval = R_REF(set()) + for _ in range(n): + v = self.r_object() + retval.add(v) + return retval + elif type == Type.FROZENSET: + n = self.r_long() + s: set[Any] = set() + idx = self.r_ref_reserve(flag) + for _ in range(n): + v = self.r_object() + s.add(v) + retval = frozenset(s) + self.r_ref_insert(retval, idx, flag) + return retval + elif type == Type.CODE: + retval = R_REF(Code()) + retval.co_argcount = self.r_long() + retval.co_posonlyargcount = self.r_long() + retval.co_kwonlyargcount = self.r_long() + retval.co_stacksize = self.r_long() + retval.co_flags = self.r_long() + retval.co_code = self.r_object() + retval.co_consts = self.r_object() + retval.co_names = self.r_object() + retval.co_localsplusnames = self.r_object() + retval.co_localspluskinds = self.r_object() + retval.co_filename = self.r_object() + retval.co_name = self.r_object() + retval.co_qualname = self.r_object() + retval.co_firstlineno = self.r_long() + retval.co_linetable = self.r_object() + retval.co_exceptiontable = self.r_object() + return retval + elif type == Type.REF: + n = self.r_long() + retval = self.refs[n] + assert retval is not None + return retval + else: + breakpoint() + raise AssertionError(f"Unknown type {type} {chr(type)!r}") + + +def loads(data: bytes) -> Any: + assert isinstance(data, bytes) + r = Reader(data) + return r.r_object() + + +def main(): + # Test + import marshal, pprint + sample = {'foo': {(42, "bar", 3.14)}} + data = marshal.dumps(sample) + retval = loads(data) + assert retval == sample, retval + sample = main.__code__ + data = marshal.dumps(sample) + retval = loads(data) + assert isinstance(retval, Code), retval + pprint.pprint(retval.__dict__) + + +if __name__ == "__main__": + main() diff --git a/Tools/scripts/update_file.py b/Tools/build/update_file.py similarity index 100% rename from Tools/scripts/update_file.py rename to Tools/build/update_file.py diff --git a/Tools/build/verify_ensurepip_wheels.py b/Tools/build/verify_ensurepip_wheels.py new file mode 100755 index 00000000000..044d1fd6b3c --- /dev/null +++ b/Tools/build/verify_ensurepip_wheels.py @@ -0,0 +1,98 @@ +#! /usr/bin/env python3 + +""" +Compare checksums for wheels in :mod:`ensurepip` against the Cheeseshop. + +When GitHub Actions executes the script, output is formatted accordingly. +https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-a-notice-message +""" + +import hashlib +import json +import os +import re +from pathlib import Path +from urllib.request import urlopen + +PACKAGE_NAMES = ("pip", "setuptools") +ENSURE_PIP_ROOT = Path(__file__).parent.parent.parent / "Lib/ensurepip" +WHEEL_DIR = ENSURE_PIP_ROOT / "_bundled" +ENSURE_PIP_INIT_PY_TEXT = (ENSURE_PIP_ROOT / "__init__.py").read_text(encoding="utf-8") +GITHUB_ACTIONS = os.getenv("GITHUB_ACTIONS") == "true" + + +def print_notice(file_path: str, message: str) -> None: + if GITHUB_ACTIONS: + message = f"::notice file={file_path}::{message}" + print(message, end="\n\n") + + +def print_error(file_path: str, message: str) -> None: + if GITHUB_ACTIONS: + message = f"::error file={file_path}::{message}" + print(message, end="\n\n") + + +def verify_wheel(package_name: str) -> bool: + # Find the package on disk + package_path = next(WHEEL_DIR.glob(f"{package_name}*.whl"), None) + if not package_path: + print_error("", f"Could not find a {package_name} wheel on disk.") + return False + + print(f"Verifying checksum for {package_path}.") + + # Find the version of the package used by ensurepip + package_version_match = re.search( + f'_{package_name.upper()}_VERSION = "([^"]+)', ENSURE_PIP_INIT_PY_TEXT + ) + if not package_version_match: + print_error( + package_path, + f"No {package_name} version found in Lib/ensurepip/__init__.py.", + ) + return False + package_version = package_version_match[1] + + # Get the SHA 256 digest from the Cheeseshop + try: + raw_text = urlopen(f"https://pypi.org/pypi/{package_name}/json").read() + except (OSError, ValueError): + print_error(package_path, f"Could not fetch JSON metadata for {package_name}.") + return False + + release_files = json.loads(raw_text)["releases"][package_version] + for release_info in release_files: + if package_path.name != release_info["filename"]: + continue + expected_digest = release_info["digests"].get("sha256", "") + break + else: + print_error(package_path, f"No digest for {package_name} found from PyPI.") + return False + + # Compute the SHA 256 digest of the wheel on disk + actual_digest = hashlib.sha256(package_path.read_bytes()).hexdigest() + + print(f"Expected digest: {expected_digest}") + print(f"Actual digest: {actual_digest}") + + if actual_digest != expected_digest: + print_error( + package_path, f"Failed to verify the checksum of the {package_name} wheel." + ) + return False + + print_notice( + package_path, + f"Successfully verified the checksum of the {package_name} wheel.", + ) + return True + + +if __name__ == "__main__": + exit_status = 0 + for package_name in PACKAGE_NAMES: + if not verify_wheel(package_name): + exit_status = 1 + raise SystemExit(exit_status) diff --git a/Tools/c-analyzer/TODO b/Tools/c-analyzer/TODO index 1fd8052268b..43760369b19 100644 --- a/Tools/c-analyzer/TODO +++ b/Tools/c-analyzer/TODO @@ -1,3 +1,11 @@ +# For up-to-date results, run: +# ./python Tools/c-analyzer/c-analyzer.py check --format summary +# or +# ./python Tools/c-analyzer/c-analyzer.py analyze + + +####################################### +# non-PyObject (61) # allocator (16) Objects/obmalloc.c:_PyMem static PyMemAllocatorEx _PyMem @@ -32,12 +40,7 @@ Objects/dictobject.c:empty_keys_struct static PyDictKe Python/fileutils.c:_Py_open_cloexec_works int _Py_open_cloexec_works -# freelists -Objects/dictobject.c:keys_free_list static PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST] -Objects/dictobject.c:numfreekeys static int numfreekeys - - -# other non-object (43) +# other non-object (40) Modules/_tracemalloc.c:allocators static struct { PyMemAllocatorEx mem; PyMemAllocatorEx raw; PyMemAllocatorEx obj; } allocators Modules/_tracemalloc.c:tables_lock static PyThread_type_lock tables_lock Modules/_tracemalloc.c:tracemalloc_filenames static _Py_hashtable_t *tracemalloc_filenames @@ -81,30 +84,7 @@ Python/pylifecycle.c:fatal_error():reentrant static int reen ####################################### -# PyObject (960) - -# freelists (10 + 10) -Modules/_collectionsmodule.c:freeblocks static block *freeblocks[MAXFREEBLOCKS] -Modules/_collectionsmodule.c:numfreeblocks static Py_ssize_t numfreeblocks -Objects/dictobject.c:free_list static PyDictObject *free_list[PyDict_MAXFREELIST] -Objects/dictobject.c:numfree static int numfree -Objects/exceptions.c:memerrors_freelist static PyBaseExceptionObject *memerrors_freelist -Objects/exceptions.c:memerrors_numfree static int memerrors_numfree -Objects/floatobject.c:free_list static PyFloatObject *free_list -Objects/floatobject.c:numfree static int numfree -Objects/frameobject.c:free_list static PyFrameObject *free_list -Objects/frameobject.c:numfree static int numfree -Objects/genobject.c:ag_asend_freelist static PyAsyncGenASend *ag_asend_freelist[_PyAsyncGen_MAXFREELIST] -Objects/genobject.c:ag_asend_freelist_free static int ag_asend_freelist_free -Objects/genobject.c:ag_value_freelist static _PyAsyncGenWrappedValue *ag_value_freelist[_PyAsyncGen_MAXFREELIST] -Objects/genobject.c:ag_value_freelist_free static int ag_value_freelist_free -Objects/listobject.c:free_list static PyListObject *free_list[PyList_MAXFREELIST] -Objects/listobject.c:numfree static int numfree -Objects/tupleobject.c:free_list static PyTupleObject *free_list[PyTuple_MAXSAVESIZE] -Objects/tupleobject.c:numfree static int numfree[PyTuple_MAXSAVESIZE] -Python/context.c:ctx_freelist static PyContext *ctx_freelist -Python/context.c:ctx_freelist_len static int ctx_freelist_len - +# PyObject (919) # singletons (7) Objects/boolobject.c:_Py_FalseStruct static struct _longobject _Py_FalseStruct @@ -116,16 +96,8 @@ Objects/object.c:_Py_NotImplementedStruct PyObject _Py_No Objects/sliceobject.c:_Py_EllipsisObject PyObject _Py_EllipsisObject -# module vars (9) -Modules/_functoolsmodule.c:kwd_mark static PyObject *kwd_mark -Modules/_localemodule.c:Error static PyObject *Error -Modules/_threadmodule.c:ThreadError static PyObject *ThreadError +# module vars (1) Modules/_tracemalloc.c:unknown_filename static PyObject *unknown_filename -Modules/signalmodule.c:DefaultHandler static PyObject *DefaultHandler -Modules/signalmodule.c:IgnoreHandler static PyObject *IgnoreHandler -Modules/signalmodule.c:IntHandler static PyObject *IntHandler -Modules/signalmodule.c:ItimerError static PyObject *ItimerError -Objects/exceptions.c:errnomap static PyObject *errnomap # other (non-cache) (5) @@ -136,26 +108,15 @@ Modules/signalmodule.c:Handlers static volatile Objects/setobject.c:_dummy_struct static PyObject _dummy_struct -# caches (5) -Modules/posixmodule.c:posix_putenv_garbage static PyObject *posix_putenv_garbage -Objects/sliceobject.c:slice_cache static PySliceObject *slice_cache -Objects/typeobject.c:method_cache static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP] -Objects/unicodeobject.c:interned static PyObject *interned +# caches (1) Python/import.c:extensions static PyObject *extensions -# cached constants - non-str (15) +# cached constants - non-str (6) Modules/_io/_iomodule.c:_PyIO_empty_bytes PyObject *_PyIO_empty_bytes Modules/_io/bufferedio.c:_PyIO_trap_eintr():eintr_int static PyObject *eintr_int -Modules/posixmodule.c:billion static PyObject *billion -Modules/posixmodule.c:wait_helper():struct_rusage static PyObject *struct_rusage -Objects/bytesobject.c:characters static PyBytesObject *characters[UCHAR_MAX + 1] -Objects/bytesobject.c:nullstring static PyBytesObject *nullstring -Objects/codeobject.c:PyCode_NewEmpty():nulltuple static PyObject *nulltuple -Objects/dictobject.c:empty_values static PyObject *empty_values[1] +Objects/dictobject.c:empty_values_struct static PyDictValues Objects/listobject.c:indexerr static PyObject *indexerr -Objects/longobject.c:small_ints static PyLongObject small_ints[NSMALLNEGINTS + NSMALLPOSINTS] -Objects/setobject.c:emptyfrozenset static PyObject *emptyfrozenset Python/context.c:_token_missing static PyObject *_token_missing Python/hamt.c:_empty_hamt static PyHamtObject *_empty_hamt @@ -195,8 +156,6 @@ Objects/codeobject.c:PyCode_NewEmpty():emptystring static PyObject Objects/exceptions.c:_check_for_legacy_statements():exec_prefix static PyObject *exec_prefix Objects/exceptions.c:_check_for_legacy_statements():print_prefix static PyObject *print_prefix Objects/funcobject.c:PyFunction_NewWithQualName():__name__ static PyObject *__name__ -Objects/typeobject.c:object___reduce_ex___impl():objreduce static PyObject *objreduce -Objects/typeobject.c:resolve_slotdups():pname static PyObject *pname Objects/unicodeobject.c:unicode_empty static PyObject *unicode_empty Objects/unicodeobject.c:unicode_latin1 static PyObject *unicode_latin1[256] Python/_warnings.c:is_internal_frame():bootstrap_string static PyObject *bootstrap_string @@ -292,7 +251,6 @@ Modules/_io/textio.c:PyId_close _Py_IDENTIFIER( Modules/_io/textio.c:PyId_decode _Py_IDENTIFIER(decode) Modules/_io/textio.c:PyId_fileno _Py_IDENTIFIER(fileno) Modules/_io/textio.c:PyId_flush _Py_IDENTIFIER(flush) -Modules/_io/textio.c:PyId_getpreferredencoding _Py_IDENTIFIER(getpreferredencoding) Modules/_io/textio.c:PyId_isatty _Py_IDENTIFIER(isatty) Modules/_io/textio.c:PyId_mode _Py_IDENTIFIER(mode) Modules/_io/textio.c:PyId_name _Py_IDENTIFIER(name) @@ -510,7 +468,6 @@ Python/ceval.c:_PyEval_EvalFrameDefault():PyId___annotations__ _Py_IDENTIFIER( Python/ceval.c:_PyEval_EvalFrameDefault():PyId___build_class__ _Py_IDENTIFIER(__build_class__) Python/ceval.c:_PyEval_EvalFrameDefault():PyId___enter__ _Py_IDENTIFIER(__enter__) Python/ceval.c:_PyEval_EvalFrameDefault():PyId___exit__ _Py_IDENTIFIER(__exit__) -Python/ceval.c:_PyEval_EvalFrameDefault():PyId___ltrace__ _Py_IDENTIFIER(__ltrace__) Python/ceval.c:_PyEval_EvalFrameDefault():PyId_displayhook _Py_IDENTIFIER(displayhook) Python/ceval.c:_PyEval_EvalFrameDefault():PyId_send _Py_IDENTIFIER(send) Python/ceval.c:import_all_from():PyId___all__ _Py_IDENTIFIER(__all__) @@ -662,15 +619,6 @@ Modules/itertoolsmodule.c:takewhile_type static PyTypeOb Modules/itertoolsmodule.c:tee_type static PyTypeObject tee_type Modules/itertoolsmodule.c:teedataobject_type static PyTypeObject teedataobject_type Modules/itertoolsmodule.c:ziplongest_type static PyTypeObject ziplongest_type -Modules/posixmodule.c:DirEntryType static PyTypeObject DirEntryType -Modules/posixmodule.c:ScandirIteratorType static PyTypeObject ScandirIteratorType -Modules/posixmodule.c:SchedParamType static PyTypeObject* SchedParamType -Modules/posixmodule.c:StatResultType static PyTypeObject* StatResultType -Modules/posixmodule.c:StatVFSResultType static PyTypeObject* StatVFSResultType -Modules/posixmodule.c:TerminalSizeType static PyTypeObject* TerminalSizeType -Modules/posixmodule.c:TimesResultType static PyTypeObject* TimesResultType -Modules/posixmodule.c:UnameResultType static PyTypeObject* UnameResultType -Modules/posixmodule.c:WaitidResultType static PyTypeObject* WaitidResultType Modules/signalmodule.c:SiginfoType static PyTypeObject SiginfoType Modules/timemodule.c:StructTimeType static PyTypeObject StructTimeType Modules/xxsubtype.c:spamdict_type static PyTypeObject spamdict_type diff --git a/Tools/c-analyzer/c_common/fsutil.py b/Tools/c-analyzer/c_common/fsutil.py index 120a140288f..a8cf8d0537e 100644 --- a/Tools/c-analyzer/c_common/fsutil.py +++ b/Tools/c-analyzer/c_common/fsutil.py @@ -104,6 +104,25 @@ def format_filename(filename, relroot=USE_CWD, *, return filename +def match_path_tail(path1, path2): + """Return True if one path ends the other.""" + if path1 == path2: + return True + if os.path.isabs(path1): + if os.path.isabs(path2): + return False + return _match_tail(path1, path2) + elif os.path.isabs(path2): + return _match_tail(path2, path1) + else: + return _match_tail(path1, path2) or _match_tail(path2, path1) + + +def _match_tail(path, tail): + assert not os.path.isabs(tail), repr(tail) + return path.endswith(os.path.sep + tail) + + ################################## # find files diff --git a/Tools/c-analyzer/c_common/tables.py b/Tools/c-analyzer/c_common/tables.py index 130be6beba5..fe8e8cf473d 100644 --- a/Tools/c-analyzer/c_common/tables.py +++ b/Tools/c-analyzer/c_common/tables.py @@ -1,3 +1,4 @@ +from collections import namedtuple import csv import re import textwrap @@ -225,7 +226,11 @@ WIDTH = 20 def resolve_columns(specs): if isinstance(specs, str): specs = specs.replace(',', ' ').strip().split() - return _resolve_colspecs(specs) + resolved = [] + for raw in specs: + column = ColumnSpec.from_raw(raw) + resolved.append(column) + return resolved def build_table(specs, *, sep=' ', defaultwidth=None): @@ -233,37 +238,145 @@ def build_table(specs, *, sep=' ', defaultwidth=None): return _build_table(columns, sep=sep, defaultwidth=defaultwidth) -_COLSPEC_RE = re.compile(textwrap.dedent(r''' - ^ - (?: - \[ - ( - (?: [^\s\]] [^\]]* )? - [^\s\]] - ) # - python$(MajorVersionNumber)$(MinorVersionNumber)$(MicroVersionNumber)$(ReleaseLevelName).chm - false - true - - - $(DefineConstants);DocFilename=$(DocFilename); + $(PySourcePath)Doc\build\html\ + $(DocHtmlPath)\ + + doc_html + - - - + + + $(DocHtmlPath) + !(bindpath.doc_html) + $(DocHtmlPath)..\ + Doc_ + doc_html + + + \ No newline at end of file diff --git a/Tools/msi/doc/doc.wxs b/Tools/msi/doc/doc.wxs index cd1a68cc260..49798c75263 100644 --- a/Tools/msi/doc/doc.wxs +++ b/Tools/msi/doc/doc.wxs @@ -1,41 +1,43 @@  - + + - - - - 1 - - - + + + + + + + + + + + + - + - - - - diff --git a/Tools/msi/doc/doc_files.wxs b/Tools/msi/doc/doc_files.wxs deleted file mode 100644 index fe09afe4d3c..00000000000 --- a/Tools/msi/doc/doc_files.wxs +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/Tools/msi/doc/doc_no_files.wxs b/Tools/msi/doc/doc_no_files.wxs deleted file mode 100644 index 7ab7c269068..00000000000 --- a/Tools/msi/doc/doc_no_files.wxs +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - diff --git a/Tools/msi/exe/exe.wixproj b/Tools/msi/exe/exe.wixproj index be44f442f7c..592c8d2f65a 100644 --- a/Tools/msi/exe/exe.wixproj +++ b/Tools/msi/exe/exe.wixproj @@ -32,18 +32,9 @@ - - - - - - - - @(HostPython) - $(HostPython.Remove($(HostPython.IndexOf(';')))) - - - + + + diff --git a/Tools/msi/exe/exe.wxs b/Tools/msi/exe/exe.wxs index 98d31b3a77b..05a8d775193 100644 --- a/Tools/msi/exe/exe.wxs +++ b/Tools/msi/exe/exe.wxs @@ -1,7 +1,7 @@  - + diff --git a/Tools/msi/exe/exe_d.wxs b/Tools/msi/exe/exe_d.wxs index eedb6bb640e..3b327bc26d7 100644 --- a/Tools/msi/exe/exe_d.wxs +++ b/Tools/msi/exe/exe_d.wxs @@ -1,7 +1,7 @@  - + diff --git a/Tools/msi/exe/exe_pdb.wxs b/Tools/msi/exe/exe_pdb.wxs index f25094f8281..f706cf3b0e0 100644 --- a/Tools/msi/exe/exe_pdb.wxs +++ b/Tools/msi/exe/exe_pdb.wxs @@ -1,7 +1,7 @@  - + diff --git a/Tools/msi/get_externals.bat b/Tools/msi/get_externals.bat index d66781d7c42..f6602ce9588 100644 --- a/Tools/msi/get_externals.bat +++ b/Tools/msi/get_externals.bat @@ -56,7 +56,7 @@ set binaries=%binaries% gpg set binaries=%binaries% htmlhelp set binaries=%binaries% nuget set binaries=%binaries% redist-1 -set binaries=%binaries% wix +set binaries=%binaries% wix-314 for %%b in (%binaries%) do ( if exist "%EXTERNALS_DIR%\%%b" ( diff --git a/Tools/msi/launcher/launcher.wixproj b/Tools/msi/launcher/launcher.wixproj index 7ff169029e4..de770bdd300 100644 --- a/Tools/msi/launcher/launcher.wixproj +++ b/Tools/msi/launcher/launcher.wixproj @@ -8,6 +8,7 @@ UpgradeCode=1B68A0EC-4DD3-5134-840E-73854B0863F1;SuppressUpgradeTable=1;$(DefineConstants) true ICE80 + <_Rebuild>Build @@ -18,18 +19,27 @@ - - - + + + + <_Rebuild>Rebuild + - - + + + - - + + - - + + + + + + + + diff --git a/Tools/msi/launcher/launcher.wxs b/Tools/msi/launcher/launcher.wxs index 7de131a3edb..b83058c63bf 100644 --- a/Tools/msi/launcher/launcher.wxs +++ b/Tools/msi/launcher/launcher.wxs @@ -1,15 +1,20 @@  - + - + + + + + @@ -17,14 +22,14 @@ - + - + - + NOT Installed AND NOT ALLUSERS=1 NOT Installed AND ALLUSERS=1 diff --git a/Tools/msi/launcher/launcher_files.wxs b/Tools/msi/launcher/launcher_files.wxs index 5b79d76bdfe..d9a230e2d35 100644 --- a/Tools/msi/launcher/launcher_files.wxs +++ b/Tools/msi/launcher/launcher_files.wxs @@ -22,17 +22,23 @@ - VersionNT64 + VersionNT64 AND NOT ARM64_SHELLEXT - NOT VersionNT64 + NOT VersionNT64 AND NOT ARM64_SHELLEXT + + ARM64_SHELLEXT + + + + diff --git a/Tools/msi/lib/lib.wxs b/Tools/msi/lib/lib.wxs index 2a3b9ecfeef..e417e31b337 100644 --- a/Tools/msi/lib/lib.wxs +++ b/Tools/msi/lib/lib.wxs @@ -1,9 +1,10 @@  - + + diff --git a/Tools/msi/lib/lib_d.wxs b/Tools/msi/lib/lib_d.wxs index 8a8a530d41a..7968d179743 100644 --- a/Tools/msi/lib/lib_d.wxs +++ b/Tools/msi/lib/lib_d.wxs @@ -1,7 +1,7 @@  - + diff --git a/Tools/msi/lib/lib_files.wxs b/Tools/msi/lib/lib_files.wxs index 64c046e6dd9..73c0231352f 100644 --- a/Tools/msi/lib/lib_files.wxs +++ b/Tools/msi/lib/lib_files.wxs @@ -1,6 +1,6 @@  - + diff --git a/Tools/msi/lib/lib_pdb.wxs b/Tools/msi/lib/lib_pdb.wxs index 8839e8a429f..7918893a9a2 100644 --- a/Tools/msi/lib/lib_pdb.wxs +++ b/Tools/msi/lib/lib_pdb.wxs @@ -1,7 +1,7 @@  - + diff --git a/Tools/msi/msi.props b/Tools/msi/msi.props index cb9221fddf8..06aa0b8bbca 100644 --- a/Tools/msi/msi.props +++ b/Tools/msi/msi.props @@ -12,9 +12,11 @@ x86 perUser <_MakeCatCommand Condition="'$(_MakeCatCommand)' == ''">makecat + true + @@ -71,8 +73,10 @@ 32-bit 64-bit + ARM64 32bit 64bit + ARM64 $(DefineConstants); Version=$(InstallerVersion); @@ -88,17 +92,12 @@ PyArchExt=$(PyArchExt); PyTestExt=$(PyTestExt); OptionalFeatureName=$(OutputName); - ssltag=-1_1; + ssltag=$(OpenSSLDLLSuffix); + Suffix32=$(PyArchExt); $(DefineConstants);CRTRedist=$(CRTRedist); - - $(DefineConstants);Suffix32=-32; - - - $(DefineConstants);Suffix32=; - @@ -116,9 +115,6 @@ - - - src @@ -134,10 +130,14 @@ build64 + + buildarm64 + - + @@ -166,13 +166,16 @@ registry/$(OutputName) - + <_Uuids>@(_Uuid->'("%(Identity)", "$(MajorVersionNumber).$(MinorVersionNumber)/%(Uri)")',',') <_GenerateCommand>import uuid; print('\n'.join('{}={}'.format(i, uuid.uuid5(uuid.UUID('c8d9733e-a70c-43ff-ab0c-e26456f11083'), '$(ReleaseUri.Replace(`{arch}`, `$(ArchName)`))' + j)) for i,j in [$(_Uuids.Replace(`"`,`'`))])) - diff --git a/Tools/msi/msi.targets b/Tools/msi/msi.targets index 4788a637a5d..99d1de4d9d8 100644 --- a/Tools/msi/msi.targets +++ b/Tools/msi/msi.targets @@ -1,7 +1,10 @@ - + <_FileListTarget>$(IntermediateOutputPath)$(MSBuildProjectName).g.csv <_InstallFilesTarget>$(IntermediateOutputPath)$(MSBuildProjectName).g.wxs @@ -17,7 +20,7 @@ - diff --git a/Tools/msi/path/path.wxs b/Tools/msi/path/path.wxs index 8b37936cc93..32854392e8b 100644 --- a/Tools/msi/path/path.wxs +++ b/Tools/msi/path/path.wxs @@ -1,8 +1,9 @@  - - + + + diff --git a/Tools/msi/pip/pip.wxs b/Tools/msi/pip/pip.wxs index 19e9f5fd208..1d8083cad91 100644 --- a/Tools/msi/pip/pip.wxs +++ b/Tools/msi/pip/pip.wxs @@ -1,7 +1,7 @@  - + diff --git a/Tools/msi/purge.py b/Tools/msi/purge.py index 41be06939ab..de9fdc95202 100644 --- a/Tools/msi/purge.py +++ b/Tools/msi/purge.py @@ -65,9 +65,15 @@ PATHS = [ "python-{}-webinstall.exe".format(m.group(0)), "python-{}-amd64.exe".format(m.group(0)), "python-{}-amd64-webinstall.exe".format(m.group(0)), + "python-{}-arm64.exe".format(m.group(0)), + "python-{}-arm64-webinstall.exe".format(m.group(0)), "python-{}-embed-amd64.zip".format(m.group(0)), "python-{}-embed-win32.zip".format(m.group(0)), -] + ["win32{}/{}".format(REL, f) for f in FILES] + ["amd64{}/{}".format(REL, f) for f in FILES] + "python-{}-embed-arm64.zip".format(m.group(0)), + *["win32{}/{}".format(REL, f) for f in FILES], + *["amd64{}/{}".format(REL, f) for f in FILES], + *["arm64{}/{}".format(REL, f) for f in FILES], +] PATHS = PATHS + [p + ".asc" for p in PATHS] print('Purged:') diff --git a/Tools/msi/tcltk/tcltk.wxs b/Tools/msi/tcltk/tcltk.wxs index eeae8e8b0df..bad56d55cce 100644 --- a/Tools/msi/tcltk/tcltk.wxs +++ b/Tools/msi/tcltk/tcltk.wxs @@ -1,9 +1,10 @@  - + + diff --git a/Tools/msi/tcltk/tcltk_d.wxs b/Tools/msi/tcltk/tcltk_d.wxs index 391b3af5713..38aacd92999 100644 --- a/Tools/msi/tcltk/tcltk_d.wxs +++ b/Tools/msi/tcltk/tcltk_d.wxs @@ -1,7 +1,7 @@  - + diff --git a/Tools/msi/tcltk/tcltk_files.wxs b/Tools/msi/tcltk/tcltk_files.wxs index 11945107809..5dad7c98d4f 100644 --- a/Tools/msi/tcltk/tcltk_files.wxs +++ b/Tools/msi/tcltk/tcltk_files.wxs @@ -16,6 +16,9 @@ + + + diff --git a/Tools/msi/tcltk/tcltk_pdb.wxs b/Tools/msi/tcltk/tcltk_pdb.wxs index 04454f3849f..55f20916255 100644 --- a/Tools/msi/tcltk/tcltk_pdb.wxs +++ b/Tools/msi/tcltk/tcltk_pdb.wxs @@ -1,7 +1,7 @@  - + diff --git a/Tools/msi/test/test.wxs b/Tools/msi/test/test.wxs index f2ed64f07bf..9e497e73a94 100644 --- a/Tools/msi/test/test.wxs +++ b/Tools/msi/test/test.wxs @@ -1,9 +1,10 @@  - + + diff --git a/Tools/msi/test/test_d.wxs b/Tools/msi/test/test_d.wxs index a954876755c..9b26ff6a4bf 100644 --- a/Tools/msi/test/test_d.wxs +++ b/Tools/msi/test/test_d.wxs @@ -1,7 +1,7 @@  - + diff --git a/Tools/msi/test/test_files.wxs b/Tools/msi/test/test_files.wxs index 9127ce89481..b5f68faef30 100644 --- a/Tools/msi/test/test_files.wxs +++ b/Tools/msi/test/test_files.wxs @@ -1,6 +1,6 @@ - + diff --git a/Tools/msi/test/test_pdb.wxs b/Tools/msi/test/test_pdb.wxs index de634a390ba..5a2ef366840 100644 --- a/Tools/msi/test/test_pdb.wxs +++ b/Tools/msi/test/test_pdb.wxs @@ -1,7 +1,7 @@  - + diff --git a/Tools/msi/tools/tools.wixproj b/Tools/msi/tools/tools.wixproj deleted file mode 100644 index b7fc41ee92e..00000000000 --- a/Tools/msi/tools/tools.wixproj +++ /dev/null @@ -1,44 +0,0 @@ - - - - {24CBEB95-BC1E-4EA9-AEA9-33834BCCD0EC} - 2.0 - tools - Package - - - - - - - - - - - - - - - $(PySourcePath) - !(bindpath.src) - $(PySourcePath) - - tools_py - true - - - - - \ No newline at end of file diff --git a/Tools/msi/tools/tools.wxs b/Tools/msi/tools/tools.wxs deleted file mode 100644 index 7a805d0612e..00000000000 --- a/Tools/msi/tools/tools.wxs +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/Tools/msi/tools/tools_en-US.wxl b/Tools/msi/tools/tools_en-US.wxl deleted file mode 100644 index a1384177ea2..00000000000 --- a/Tools/msi/tools/tools_en-US.wxl +++ /dev/null @@ -1,5 +0,0 @@ - - - Utility Scripts - tools - diff --git a/Tools/msi/tools/tools_files.wxs b/Tools/msi/tools/tools_files.wxs deleted file mode 100644 index 3de6c9291cf..00000000000 --- a/Tools/msi/tools/tools_files.wxs +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/msi/ucrt/ucrt.wxs b/Tools/msi/ucrt/ucrt.wxs index 76e56820c53..e9e2a9a9045 100644 --- a/Tools/msi/ucrt/ucrt.wxs +++ b/Tools/msi/ucrt/ucrt.wxs @@ -1,9 +1,10 @@  - + + diff --git a/Tools/msi/uploadrelease.ps1 b/Tools/msi/uploadrelease.ps1 index 7c825c443f2..a8669e5d65e 100644 --- a/Tools/msi/uploadrelease.ps1 +++ b/Tools/msi/uploadrelease.ps1 @@ -80,19 +80,19 @@ if (-not $skipupload) { "" if ($doc_htmlhelp) { - pushd $doc_htmlhelp + $chm = gci -EA 0 $doc_htmlhelp\python*.chm, $doc_htmlhelp\python*.chm.asc } else { - pushd $build + $chm = gci -EA 0 $build\python*.chm, $build\python*.chm.asc } - $chm = gci python*.chm, python*.chm.asc - popd $d = "$target/$($p[0])/" & $plink -batch $user@$server mkdir $d & $plink -batch $user@$server chgrp downloads $d & $plink -batch $user@$server chmod o+rx $d - & $pscp -batch $chm.FullName "$user@${server}:$d" - if (-not $?) { throw "Failed to upload $chm" } + if ($chm) { + & $pscp -batch $chm.FullName "$user@${server}:$d" + if (-not $?) { throw "Failed to upload $chm" } + } $dirs = gci "$build" -Directory if ($embed) { diff --git a/Tools/msi/wix.props b/Tools/msi/wix.props index 7269d34c030..d8ced317d0c 100644 --- a/Tools/msi/wix.props +++ b/Tools/msi/wix.props @@ -4,7 +4,7 @@ $(MSBuildThisFileDirectory)\Wix\ - $(ExternalsDir)\windows-installer\wix\ + $(ExternalsDir)\windows-installer\wix-314\ $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Installer XML\3.10@InstallRoot) $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows Installer XML\3.10@InstallRoot) $(WixInstallPath)\Wix.targets diff --git a/Tools/scripts/patchcheck.py b/Tools/patchcheck/patchcheck.py similarity index 96% rename from Tools/scripts/patchcheck.py rename to Tools/patchcheck/patchcheck.py index 8e59c78a4c5..6dcf6120661 100755 --- a/Tools/scripts/patchcheck.py +++ b/Tools/patchcheck/patchcheck.py @@ -13,11 +13,11 @@ import untabify # Excluded directories which are copies of external libraries: # don't check their coding style -EXCLUDE_DIRS = [os.path.join('Modules', '_ctypes', 'libffi_osx'), - os.path.join('Modules', '_ctypes', 'libffi_msvc'), - os.path.join('Modules', '_decimal', 'libmpdec'), - os.path.join('Modules', 'expat'), - os.path.join('Modules', 'zlib')] +EXCLUDE_DIRS = [ + os.path.join('Modules', '_decimal', 'libmpdec'), + os.path.join('Modules', 'expat'), + os.path.join('Modules', 'zlib'), + ] SRCDIR = sysconfig.get_config_var('srcdir') @@ -130,6 +130,8 @@ def changed_files(base_branch=None): with subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, cwd=SRCDIR) as st: + if st.wait() != 0: + sys.exit(f'error running {cmd}') for line in st.stdout: line = line.decode().rstrip() status_text, filename = line.split(maxsplit=1) @@ -245,7 +247,7 @@ def regenerated_pyconfig_h_in(file_paths): else: return "not needed" -def travis(pull_request): +def ci(pull_request): if pull_request == 'false': print('Not a pull request; skipping') return @@ -301,10 +303,10 @@ def main(): if __name__ == '__main__': import argparse parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument('--travis', + parser.add_argument('--ci', help='Perform pass/fail checks') args = parser.parse_args() - if args.travis: - travis(args.travis) + if args.ci: + ci(args.ci) else: main() diff --git a/Tools/scripts/reindent.py b/Tools/patchcheck/reindent.py similarity index 100% rename from Tools/scripts/reindent.py rename to Tools/patchcheck/reindent.py diff --git a/Tools/scripts/untabify.py b/Tools/patchcheck/untabify.py similarity index 100% rename from Tools/scripts/untabify.py rename to Tools/patchcheck/untabify.py diff --git a/Tools/peg_generator/Makefile b/Tools/peg_generator/Makefile index d010f19d588..084da154919 100644 --- a/Tools/peg_generator/Makefile +++ b/Tools/peg_generator/Makefile @@ -88,7 +88,7 @@ time_stdlib: $(CPYTHON) venv -d $(CPYTHON) \ $(TESTFLAGS) \ --exclude "*/bad*" \ - --exclude "*/lib2to3/tests/data/*" + --exclude "*/test/test_lib2to3/data/*" mypy: regen-metaparser $(MYPY) # For list of files, see mypy.ini diff --git a/Tools/peg_generator/peg_extension/peg_extension.c b/Tools/peg_generator/peg_extension/peg_extension.c index bb4c1b0178c..7df134b5ade 100644 --- a/Tools/peg_generator/peg_extension/peg_extension.c +++ b/Tools/peg_generator/peg_extension/peg_extension.c @@ -12,8 +12,7 @@ _build_return_object(mod_ty module, int mode, PyObject *filename_ob, PyArena *ar } else if (mode == 1) { result = PyAST_mod2obj(module); } else { - result = Py_None; - Py_INCREF(result); + result = Py_NewRef(Py_None); } return result; @@ -151,8 +150,8 @@ dump_memo_stats(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored)) } static PyMethodDef ParseMethods[] = { - {"parse_file", (PyCFunction)(void(*)(void))parse_file, METH_VARARGS|METH_KEYWORDS, "Parse a file."}, - {"parse_string", (PyCFunction)(void(*)(void))parse_string, METH_VARARGS|METH_KEYWORDS, "Parse a string."}, + {"parse_file", _PyCFunction_CAST(parse_file), METH_VARARGS|METH_KEYWORDS, "Parse a file."}, + {"parse_string", _PyCFunction_CAST(parse_string), METH_VARARGS|METH_KEYWORDS, "Parse a string."}, {"clear_memo_stats", clear_memo_stats, METH_NOARGS}, {"dump_memo_stats", dump_memo_stats, METH_NOARGS}, {"get_memo_stats", get_memo_stats, METH_NOARGS}, diff --git a/Tools/peg_generator/pegen/build.py b/Tools/peg_generator/pegen/build.py index c69e5c9a5f2..5805ff63717 100644 --- a/Tools/peg_generator/pegen/build.py +++ b/Tools/peg_generator/pegen/build.py @@ -1,6 +1,6 @@ import itertools import pathlib -import shutil +import sys import sysconfig import tempfile import tokenize @@ -32,6 +32,8 @@ def compile_c_extension( build_dir: Optional[str] = None, verbose: bool = False, keep_asserts: bool = True, + disable_optimization: bool = False, + library_dir: Optional[str] = None, ) -> str: """Compile the generated source for a parser generator into an extension module. @@ -42,15 +44,21 @@ def compile_c_extension( If *build_dir* is provided, that path will be used as the temporary build directory of distutils (this is useful in case you want to use a temporary directory). + + If *library_dir* is provided, that path will be used as the directory for a + static library of the common parser sources (this is useful in case you are + creating multiple extensions). """ import distutils.log - from distutils.command.build_ext import build_ext # type: ignore - from distutils.command.clean import clean # type: ignore from distutils.core import Distribution, Extension from distutils.tests.support import fixup_build_ext # type: ignore + from distutils.ccompiler import new_compiler + from distutils.dep_util import newer_group + from distutils.sysconfig import customize_compiler + if verbose: - distutils.log.set_verbosity(distutils.log.DEBUG) + distutils.log.set_threshold(distutils.log.DEBUG) source_file_path = pathlib.Path(generated_source_path) extension_name = source_file_path.stem @@ -61,46 +69,100 @@ def compile_c_extension( extra_link_args = get_extra_flags("LDFLAGS", "PY_LDFLAGS_NODIST") if keep_asserts: extra_compile_args.append("-UNDEBUG") - extension = [ - Extension( - extension_name, - sources=[ - str(MOD_DIR.parent.parent.parent / "Python" / "Python-ast.c"), - str(MOD_DIR.parent.parent.parent / "Python" / "asdl.c"), - str(MOD_DIR.parent.parent.parent / "Parser" / "tokenizer.c"), - str(MOD_DIR.parent.parent.parent / "Parser" / "pegen.c"), - str(MOD_DIR.parent.parent.parent / "Parser" / "pegen_errors.c"), - str(MOD_DIR.parent.parent.parent / "Parser" / "action_helpers.c"), - str(MOD_DIR.parent.parent.parent / "Parser" / "string_parser.c"), - str(MOD_DIR.parent / "peg_extension" / "peg_extension.c"), - generated_source_path, - ], - include_dirs=[ - str(MOD_DIR.parent.parent.parent / "Include" / "internal"), - str(MOD_DIR.parent.parent.parent / "Parser"), - ], - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - ) + if disable_optimization: + if sys.platform == 'win32': + extra_compile_args.append("/Od") + extra_link_args.append("/LTCG:OFF") + else: + extra_compile_args.append("-O0") + if sysconfig.get_config_var("GNULD") == "yes": + extra_link_args.append("-fno-lto") + + common_sources = [ + str(MOD_DIR.parent.parent.parent / "Python" / "Python-ast.c"), + str(MOD_DIR.parent.parent.parent / "Python" / "asdl.c"), + str(MOD_DIR.parent.parent.parent / "Parser" / "tokenizer.c"), + str(MOD_DIR.parent.parent.parent / "Parser" / "pegen.c"), + str(MOD_DIR.parent.parent.parent / "Parser" / "pegen_errors.c"), + str(MOD_DIR.parent.parent.parent / "Parser" / "action_helpers.c"), + str(MOD_DIR.parent.parent.parent / "Parser" / "string_parser.c"), + str(MOD_DIR.parent / "peg_extension" / "peg_extension.c"), ] - dist = Distribution({"name": extension_name, "ext_modules": extension}) - cmd = build_ext(dist) + include_dirs = [ + str(MOD_DIR.parent.parent.parent / "Include" / "internal"), + str(MOD_DIR.parent.parent.parent / "Parser"), + ] + extension = Extension( + extension_name, + sources=[generated_source_path], + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + ) + dist = Distribution({"name": extension_name, "ext_modules": [extension]}) + cmd = dist.get_command_obj("build_ext") fixup_build_ext(cmd) - cmd.inplace = True + cmd.build_lib = str(source_file_path.parent) + cmd.include_dirs = include_dirs if build_dir: cmd.build_temp = build_dir - cmd.build_lib = build_dir cmd.ensure_finalized() - cmd.run() - extension_path = source_file_path.parent / cmd.get_ext_filename(extension_name) - shutil.move(cmd.get_ext_fullpath(extension_name), extension_path) + compiler = new_compiler() + customize_compiler(compiler) + compiler.set_include_dirs(cmd.include_dirs) + compiler.set_library_dirs(cmd.library_dirs) + # build static lib + if library_dir: + library_filename = compiler.library_filename(extension_name, + output_dir=library_dir) + if newer_group(common_sources, library_filename, 'newer'): + if sys.platform == 'win32': + pdb = compiler.static_lib_format % (extension_name, '.pdb') + compile_opts = [f"/Fd{library_dir}\\{pdb}"] + compile_opts.extend(extra_compile_args) + else: + compile_opts = extra_compile_args + objects = compiler.compile(common_sources, + output_dir=library_dir, + debug=cmd.debug, + extra_postargs=compile_opts) + compiler.create_static_lib(objects, extension_name, + output_dir=library_dir, + debug=cmd.debug) + if sys.platform == 'win32': + compiler.add_library_dir(library_dir) + extension.libraries = [extension_name] + elif sys.platform == 'darwin': + compiler.set_link_objects([ + '-Wl,-force_load', library_filename, + ]) + else: + compiler.set_link_objects([ + '-Wl,--whole-archive', library_filename, '-Wl,--no-whole-archive', + ]) + else: + extension.sources[0:0] = common_sources - cmd = clean(dist) - cmd.finalize_options() - cmd.run() + # Compile the source code to object files. + ext_path = cmd.get_ext_fullpath(extension_name) + if newer_group(extension.sources, ext_path, 'newer'): + objects = compiler.compile(extension.sources, + output_dir=cmd.build_temp, + debug=cmd.debug, + extra_postargs=extra_compile_args) + else: + objects = compiler.object_filenames(extension.sources, + output_dir=cmd.build_temp) + # Now link the object files together into a "shared object" + compiler.link_shared_object( + objects, ext_path, + libraries=cmd.get_libraries(extension), + extra_postargs=extra_link_args, + export_symbols=cmd.get_export_symbols(extension), + debug=cmd.debug, + build_temp=cmd.build_temp) - return extension_path + return pathlib.Path(ext_path) def build_parser( diff --git a/Tools/peg_generator/pegen/c_generator.py b/Tools/peg_generator/pegen/c_generator.py index 10dc94b04fe..c41d87b74d1 100644 --- a/Tools/peg_generator/pegen/c_generator.py +++ b/Tools/peg_generator/pegen/c_generator.py @@ -1,4 +1,5 @@ import ast +import os.path import re from dataclasses import dataclass, field from enum import Enum @@ -31,11 +32,17 @@ EXTENSION_PREFIX = """\ #include "pegen.h" #if defined(Py_DEBUG) && defined(Py_BUILD_CORE) -# define D(x) if (Py_DebugFlag) x; +# define D(x) if (p->debug) { x; } #else # define D(x) #endif +#ifdef __wasi__ +# define MAXSTACK 4000 +#else +# define MAXSTACK 6000 +#endif + """ @@ -119,6 +126,7 @@ class CCallMakerVisitor(GrammarVisitor): self.exact_tokens = exact_tokens self.non_exact_tokens = non_exact_tokens self.cache: Dict[Any, FunctionCall] = {} + self.cleanup_statements: List[str] = [] def keyword_helper(self, keyword: str) -> FunctionCall: return FunctionCall( @@ -361,14 +369,21 @@ class CParserGenerator(ParserGenerator, GrammarVisitor): self._varname_counter = 0 self.debug = debug self.skip_actions = skip_actions + self.cleanup_statements: List[str] = [] def add_level(self) -> None: - self.print("D(p->level++);") + self.print("if (p->level++ == MAXSTACK) {") + with self.indent(): + self.print("p->error_indicator = 1;") + self.print("PyErr_NoMemory();") + self.print("}") def remove_level(self) -> None: - self.print("D(p->level--);") + self.print("p->level--;") def add_return(self, ret_val: str) -> None: + for stmt in self.cleanup_statements: + self.print(stmt) self.remove_level() self.print(f"return {ret_val};") @@ -416,7 +431,8 @@ class CParserGenerator(ParserGenerator, GrammarVisitor): def generate(self, filename: str) -> None: self.collect_rules() - self.print(f"// @generated by pegen from {filename}") + basename = os.path.basename(filename) + self.print(f"// @generated by pegen from {basename}") header = self.grammar.metas.get("header", EXTENSION_PREFIX) if header: self.print(header.rstrip("\n")) @@ -539,12 +555,11 @@ class CParserGenerator(ParserGenerator, GrammarVisitor): f"_PyPegen_update_memo(p, _mark, {node.name}_type, _res)", "_res" ) self.print("p->mark = _mark;") - self.print("p->in_raw_rule++;") self.print(f"void *_raw = {node.name}_raw(p);") - self.print("p->in_raw_rule--;") - self.print("if (p->error_indicator)") + self.print("if (p->error_indicator) {") with self.indent(): - self.print("return NULL;") + self.add_return("NULL") + self.print("}") self.print("if (_raw == NULL || p->mark <= _resmark)") with self.indent(): self.print("break;") @@ -654,10 +669,21 @@ class CParserGenerator(ParserGenerator, GrammarVisitor): self._set_up_rule_memoization(node, result_type) self.print("{") + + if node.name.endswith("without_invalid"): + with self.indent(): + self.print("int _prev_call_invalid = p->call_invalid_rules;") + self.print("p->call_invalid_rules = 0;") + self.cleanup_statements.append("p->call_invalid_rules = _prev_call_invalid;") + if is_loop: self._handle_loop_rule_body(node, rhs) else: self._handle_default_rule_body(node, rhs, result_type) + + if node.name.endswith("without_invalid"): + self.cleanup_statements.pop() + self.print("}") def visit_NamedItem(self, node: NamedItem) -> None: @@ -775,7 +801,7 @@ class CParserGenerator(ParserGenerator, GrammarVisitor): self.print( "void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));" ) - self.out_of_memory_return(f"!_new_children") + self.out_of_memory_return(f"!_new_children", cleanup_code="PyMem_Free(_children);") self.print("_children = _new_children;") self.print("}") self.print("_children[_n++] = _res;") diff --git a/Tools/peg_generator/pegen/grammar.py b/Tools/peg_generator/pegen/grammar.py index fa47b98201c..03d60d01026 100644 --- a/Tools/peg_generator/pegen/grammar.py +++ b/Tools/peg_generator/pegen/grammar.py @@ -1,23 +1,16 @@ from __future__ import annotations -from abc import abstractmethod from typing import ( - TYPE_CHECKING, AbstractSet, Any, - Dict, Iterable, Iterator, List, Optional, - Set, Tuple, Union, ) -if TYPE_CHECKING: - from pegen.parser_generator import ParserGenerator - class GrammarError(Exception): pass diff --git a/Tools/peg_generator/pegen/grammar_parser.py b/Tools/peg_generator/pegen/grammar_parser.py index 6e9f7d3d11d..bf31fe53263 100644 --- a/Tools/peg_generator/pegen/grammar_parser.py +++ b/Tools/peg_generator/pegen/grammar_parser.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3.8 -# @generated by pegen from ./Tools/peg_generator/pegen/metagrammar.gram +# @generated by pegen from metagrammar.gram import ast import sys diff --git a/Tools/peg_generator/pegen/python_generator.py b/Tools/peg_generator/pegen/python_generator.py index 25a48bfab5d..5329d0ebe5e 100644 --- a/Tools/peg_generator/pegen/python_generator.py +++ b/Tools/peg_generator/pegen/python_generator.py @@ -1,3 +1,4 @@ +import os.path import token from typing import IO, Any, Dict, Optional, Sequence, Set, Text, Tuple @@ -212,7 +213,8 @@ class PythonParserGenerator(ParserGenerator, GrammarVisitor): self.collect_rules() header = self.grammar.metas.get("header", MODULE_PREFIX) if header is not None: - self.print(header.rstrip("\n").format(filename=filename)) + basename = os.path.basename(filename) + self.print(header.rstrip("\n").format(filename=basename)) subheader = self.grammar.metas.get("subheader", "") if subheader: self.print(subheader) diff --git a/Tools/peg_generator/pegen/testutil.py b/Tools/peg_generator/pegen/testutil.py index 8e5dbc5cdbb..473d208a786 100644 --- a/Tools/peg_generator/pegen/testutil.py +++ b/Tools/peg_generator/pegen/testutil.py @@ -6,7 +6,7 @@ import sys import textwrap import token import tokenize -from typing import IO, Any, Dict, Final, Type, cast +from typing import IO, Any, Dict, Final, Optional, Type, cast from pegen.build import compile_c_extension from pegen.c_generator import CParserGenerator @@ -83,7 +83,8 @@ def generate_c_parser_source(grammar: Grammar) -> str: def generate_parser_c_extension( - grammar: Grammar, path: pathlib.PurePath, debug: bool = False + grammar: Grammar, path: pathlib.PurePath, debug: bool = False, + library_dir: Optional[str] = None, ) -> Any: """Generate a parser c extension for the given grammar in the given path @@ -101,7 +102,13 @@ def generate_parser_c_extension( grammar, ALL_TOKENS, EXACT_TOKENS, NON_EXACT_TOKENS, file, debug=debug ) genr.generate("parse.c") - compile_c_extension(str(source), build_dir=str(path)) + compile_c_extension( + str(source), + build_dir=str(path), + # Significant test_peg_generator speedups + disable_optimization=True, + library_dir=library_dir, + ) def print_memstats() -> bool: diff --git a/Tools/peg_generator/scripts/benchmark.py b/Tools/peg_generator/scripts/benchmark.py index 4a063bf1003..053f8ef06d4 100644 --- a/Tools/peg_generator/scripts/benchmark.py +++ b/Tools/peg_generator/scripts/benchmark.py @@ -78,7 +78,7 @@ def run_benchmark_stdlib(subcommand): verbose=False, excluded_files=[ "*/bad*", - "*/lib2to3/tests/data/*", + "*/test/test_lib2to3/data/*", ], short=True, mode=modes[subcommand], diff --git a/Tools/peg_generator/scripts/grammar_grapher.py b/Tools/peg_generator/scripts/grammar_grapher.py index 4d771239c29..e5271a0e481 100755 --- a/Tools/peg_generator/scripts/grammar_grapher.py +++ b/Tools/peg_generator/scripts/grammar_grapher.py @@ -29,7 +29,7 @@ from pegen.build import build_parser from pegen.grammar import ( Alt, Cut, - Grammar, + Forced, Group, Leaf, Lookahead, @@ -60,6 +60,8 @@ def references_for_item(item: Any) -> List[Any]: return [_ref for _item in item.items for _ref in references_for_item(_item)] elif isinstance(item, Cut): return [] + elif isinstance(item, Forced): + return references_for_item(item.node) elif isinstance(item, Group): return references_for_item(item.rhs) elif isinstance(item, Lookahead): diff --git a/Tools/peg_generator/scripts/test_parse_directory.py b/Tools/peg_generator/scripts/test_parse_directory.py index a5e26f0a0fe..f5cf198be8d 100755 --- a/Tools/peg_generator/scripts/test_parse_directory.py +++ b/Tools/peg_generator/scripts/test_parse_directory.py @@ -5,7 +5,6 @@ import ast import os import sys import time -import traceback import tokenize from glob import glob, escape from pathlib import PurePath @@ -13,7 +12,6 @@ from pathlib import PurePath from typing import List, Optional, Any, Tuple sys.path.insert(0, os.getcwd()) -from pegen.ast_dump import ast_dump from pegen.testutil import print_memstats SUCCESS = "\033[92m" diff --git a/Tools/peg_generator/scripts/test_pypi_packages.py b/Tools/peg_generator/scripts/test_pypi_packages.py index e2eaef9de26..01ccc3d21ef 100755 --- a/Tools/peg_generator/scripts/test_pypi_packages.py +++ b/Tools/peg_generator/scripts/test_pypi_packages.py @@ -9,11 +9,10 @@ import shutil import pathlib import sys -from typing import Generator, Any +from typing import Generator sys.path.insert(0, ".") -from pegen import build from scripts import test_parse_directory HERE = pathlib.Path(__file__).resolve().parent diff --git a/Tools/pynche/ChipViewer.py b/Tools/pynche/ChipViewer.py deleted file mode 100644 index 78139f8f2da..00000000000 --- a/Tools/pynche/ChipViewer.py +++ /dev/null @@ -1,130 +0,0 @@ -"""Chip viewer and widget. - -In the lower left corner of the main Pynche window, you will see two -ChipWidgets, one for the selected color and one for the nearest color. The -selected color is the actual RGB value expressed as an X11 #COLOR name. The -nearest color is the named color from the X11 database that is closest to the -selected color in 3D space. There may be other colors equally close, but the -nearest one is the first one found. - -Clicking on the nearest color chip selects that named color. - -The ChipViewer class includes the entire lower left quandrant; i.e. both the -selected and nearest ChipWidgets. -""" - -from tkinter import * -import ColorDB - - -class ChipWidget: - _WIDTH = 150 - _HEIGHT = 80 - - def __init__(self, - master = None, - width = _WIDTH, - height = _HEIGHT, - text = 'Color', - initialcolor = 'blue', - presscmd = None, - releasecmd = None): - # create the text label - self.__label = Label(master, text=text) - self.__label.grid(row=0, column=0) - # create the color chip, implemented as a frame - self.__chip = Frame(master, relief=RAISED, borderwidth=2, - width=width, - height=height, - background=initialcolor) - self.__chip.grid(row=1, column=0) - # create the color name - self.__namevar = StringVar() - self.__namevar.set(initialcolor) - self.__name = Entry(master, textvariable=self.__namevar, - relief=FLAT, justify=CENTER, state=DISABLED, - font=self.__label['font']) - self.__name.grid(row=2, column=0) - # create the message area - self.__msgvar = StringVar() - self.__name = Entry(master, textvariable=self.__msgvar, - relief=FLAT, justify=CENTER, state=DISABLED, - font=self.__label['font']) - self.__name.grid(row=3, column=0) - # set bindings - if presscmd: - self.__chip.bind('', presscmd) - if releasecmd: - self.__chip.bind('', releasecmd) - - def set_color(self, color): - self.__chip.config(background=color) - - def get_color(self): - return self.__chip['background'] - - def set_name(self, colorname): - self.__namevar.set(colorname) - - def set_message(self, message): - self.__msgvar.set(message) - - def press(self): - self.__chip.configure(relief=SUNKEN) - - def release(self): - self.__chip.configure(relief=RAISED) - - - -class ChipViewer: - def __init__(self, switchboard, master=None): - self.__sb = switchboard - self.__frame = Frame(master, relief=RAISED, borderwidth=1) - self.__frame.grid(row=3, column=0, ipadx=5, sticky='NSEW') - # create the chip that will display the currently selected color - # exactly - self.__sframe = Frame(self.__frame) - self.__sframe.grid(row=0, column=0) - self.__selected = ChipWidget(self.__sframe, text='Selected') - # create the chip that will display the nearest real X11 color - # database color name - self.__nframe = Frame(self.__frame) - self.__nframe.grid(row=0, column=1) - self.__nearest = ChipWidget(self.__nframe, text='Nearest', - presscmd = self.__buttonpress, - releasecmd = self.__buttonrelease) - - def update_yourself(self, red, green, blue): - # Selected always shows the #rrggbb name of the color, nearest always - # shows the name of the nearest color in the database. BAW: should - # an exact match be indicated in some way? - # - # Always use the #rrggbb style to actually set the color, since we may - # not be using X color names (e.g. "web-safe" names) - colordb = self.__sb.colordb() - rgbtuple = (red, green, blue) - rrggbb = ColorDB.triplet_to_rrggbb(rgbtuple) - # find the nearest - nearest = colordb.nearest(red, green, blue) - nearest_tuple = colordb.find_byname(nearest) - nearest_rrggbb = ColorDB.triplet_to_rrggbb(nearest_tuple) - self.__selected.set_color(rrggbb) - self.__nearest.set_color(nearest_rrggbb) - # set the name and messages areas - self.__selected.set_name(rrggbb) - if rrggbb == nearest_rrggbb: - self.__selected.set_message(nearest) - else: - self.__selected.set_message('') - self.__nearest.set_name(nearest_rrggbb) - self.__nearest.set_message(nearest) - - def __buttonpress(self, event=None): - self.__nearest.press() - - def __buttonrelease(self, event=None): - self.__nearest.release() - rrggbb = self.__nearest.get_color() - red, green, blue = ColorDB.rrggbb_to_triplet(rrggbb) - self.__sb.update_views(red, green, blue) diff --git a/Tools/pynche/ColorDB.py b/Tools/pynche/ColorDB.py deleted file mode 100644 index c013a608969..00000000000 --- a/Tools/pynche/ColorDB.py +++ /dev/null @@ -1,271 +0,0 @@ -"""Color Database. - -This file contains one class, called ColorDB, and several utility functions. -The class must be instantiated by the get_colordb() function in this file, -passing it a filename to read a database out of. - -The get_colordb() function will try to examine the file to figure out what the -format of the file is. If it can't figure out the file format, or it has -trouble reading the file, None is returned. You can pass get_colordb() an -optional filetype argument. - -Supported file types are: - - X_RGB_TXT -- X Consortium rgb.txt format files. Three columns of numbers - from 0 .. 255 separated by whitespace. Arbitrary trailing - columns used as the color name. - -The utility functions are useful for converting between the various expected -color formats, and for calculating other color values. - -""" - -import sys -import re -from types import * - -class BadColor(Exception): - pass - -DEFAULT_DB = None -SPACE = ' ' -COMMASPACE = ', ' - - - -# generic class -class ColorDB: - def __init__(self, fp): - lineno = 2 - self.__name = fp.name - # Maintain several dictionaries for indexing into the color database. - # Note that while Tk supports RGB intensities of 4, 8, 12, or 16 bits, - # for now we only support 8 bit intensities. At least on OpenWindows, - # all intensities in the /usr/openwin/lib/rgb.txt file are 8-bit - # - # key is (red, green, blue) tuple, value is (name, [aliases]) - self.__byrgb = {} - # key is name, value is (red, green, blue) - self.__byname = {} - # all unique names (non-aliases). built-on demand - self.__allnames = None - for line in fp: - # get this compiled regular expression from derived class - mo = self._re.match(line) - if not mo: - print('Error in', fp.name, ' line', lineno, file=sys.stderr) - lineno += 1 - continue - # extract the red, green, blue, and name - red, green, blue = self._extractrgb(mo) - name = self._extractname(mo) - keyname = name.lower() - # BAW: for now the `name' is just the first named color with the - # rgb values we find. Later, we might want to make the two word - # version the `name', or the CapitalizedVersion, etc. - key = (red, green, blue) - foundname, aliases = self.__byrgb.get(key, (name, [])) - if foundname != name and foundname not in aliases: - aliases.append(name) - self.__byrgb[key] = (foundname, aliases) - # add to byname lookup - self.__byname[keyname] = key - lineno = lineno + 1 - - # override in derived classes - def _extractrgb(self, mo): - return [int(x) for x in mo.group('red', 'green', 'blue')] - - def _extractname(self, mo): - return mo.group('name') - - def filename(self): - return self.__name - - def find_byrgb(self, rgbtuple): - """Return name for rgbtuple""" - try: - return self.__byrgb[rgbtuple] - except KeyError: - raise BadColor(rgbtuple) from None - - def find_byname(self, name): - """Return (red, green, blue) for name""" - name = name.lower() - try: - return self.__byname[name] - except KeyError: - raise BadColor(name) from None - - def nearest(self, red, green, blue): - """Return the name of color nearest (red, green, blue)""" - # BAW: should we use Voronoi diagrams, Delaunay triangulation, or - # octree for speeding up the locating of nearest point? Exhaustive - # search is inefficient, but seems fast enough. - nearest = -1 - nearest_name = '' - for name, aliases in self.__byrgb.values(): - r, g, b = self.__byname[name.lower()] - rdelta = red - r - gdelta = green - g - bdelta = blue - b - distance = rdelta * rdelta + gdelta * gdelta + bdelta * bdelta - if nearest == -1 or distance < nearest: - nearest = distance - nearest_name = name - return nearest_name - - def unique_names(self): - # sorted - if not self.__allnames: - self.__allnames = [] - for name, aliases in self.__byrgb.values(): - self.__allnames.append(name) - self.__allnames.sort(key=str.lower) - return self.__allnames - - def aliases_of(self, red, green, blue): - try: - name, aliases = self.__byrgb[(red, green, blue)] - except KeyError: - raise BadColor((red, green, blue)) from None - return [name] + aliases - - -class RGBColorDB(ColorDB): - _re = re.compile( - r'\s*(?P\d+)\s+(?P\d+)\s+(?P\d+)\s+(?P.*)') - - -class HTML40DB(ColorDB): - _re = re.compile(r'(?P\S+)\s+(?P#[0-9a-fA-F]{6})') - - def _extractrgb(self, mo): - return rrggbb_to_triplet(mo.group('hexrgb')) - -class LightlinkDB(HTML40DB): - _re = re.compile(r'(?P(.+))\s+(?P#[0-9a-fA-F]{6})') - - def _extractname(self, mo): - return mo.group('name').strip() - -class WebsafeDB(ColorDB): - _re = re.compile('(?P#[0-9a-fA-F]{6})') - - def _extractrgb(self, mo): - return rrggbb_to_triplet(mo.group('hexrgb')) - - def _extractname(self, mo): - return mo.group('hexrgb').upper() - - - -# format is a tuple (RE, SCANLINES, CLASS) where RE is a compiled regular -# expression, SCANLINES is the number of header lines to scan, and CLASS is -# the class to instantiate if a match is found - -FILETYPES = [ - (re.compile('Xorg'), RGBColorDB), - (re.compile('XConsortium'), RGBColorDB), - (re.compile('HTML'), HTML40DB), - (re.compile('lightlink'), LightlinkDB), - (re.compile('Websafe'), WebsafeDB), - ] - -def get_colordb(file, filetype=None): - colordb = None - fp = open(file) - try: - line = fp.readline() - if not line: - return None - # try to determine the type of RGB file it is - if filetype is None: - filetypes = FILETYPES - else: - filetypes = [filetype] - for typere, class_ in filetypes: - mo = typere.search(line) - if mo: - break - else: - # no matching type - return None - # we know the type and the class to grok the type, so suck it in - colordb = class_(fp) - finally: - fp.close() - # save a global copy - global DEFAULT_DB - DEFAULT_DB = colordb - return colordb - - - -_namedict = {} - -def rrggbb_to_triplet(color): - """Converts a #rrggbb color to the tuple (red, green, blue).""" - rgbtuple = _namedict.get(color) - if rgbtuple is None: - if color[0] != '#': - raise BadColor(color) - red = color[1:3] - green = color[3:5] - blue = color[5:7] - rgbtuple = int(red, 16), int(green, 16), int(blue, 16) - _namedict[color] = rgbtuple - return rgbtuple - - -_tripdict = {} -def triplet_to_rrggbb(rgbtuple): - """Converts a (red, green, blue) tuple to #rrggbb.""" - global _tripdict - hexname = _tripdict.get(rgbtuple) - if hexname is None: - hexname = '#%02x%02x%02x' % rgbtuple - _tripdict[rgbtuple] = hexname - return hexname - - -def triplet_to_fractional_rgb(rgbtuple): - return [x / 256 for x in rgbtuple] - - -def triplet_to_brightness(rgbtuple): - # return the brightness (grey level) along the scale 0.0==black to - # 1.0==white - r = 0.299 - g = 0.587 - b = 0.114 - return r*rgbtuple[0] + g*rgbtuple[1] + b*rgbtuple[2] - - - -if __name__ == '__main__': - colordb = get_colordb('/usr/openwin/lib/rgb.txt') - if not colordb: - print('No parseable color database found') - sys.exit(1) - # on my system, this color matches exactly - target = 'navy' - red, green, blue = rgbtuple = colordb.find_byname(target) - print(target, ':', red, green, blue, triplet_to_rrggbb(rgbtuple)) - name, aliases = colordb.find_byrgb(rgbtuple) - print('name:', name, 'aliases:', COMMASPACE.join(aliases)) - r, g, b = (1, 1, 128) # nearest to navy - r, g, b = (145, 238, 144) # nearest to lightgreen - r, g, b = (255, 251, 250) # snow - print('finding nearest to', target, '...') - import time - t0 = time.time() - nearest = colordb.nearest(r, g, b) - t1 = time.time() - print('found nearest color', nearest, 'in', t1-t0, 'seconds') - # dump the database - for n in colordb.unique_names(): - r, g, b = colordb.find_byname(n) - aliases = colordb.aliases_of(r, g, b) - print('%20s: (%3d/%3d/%3d) == %s' % (n, r, g, b, - SPACE.join(aliases[1:]))) diff --git a/Tools/pynche/DetailsViewer.py b/Tools/pynche/DetailsViewer.py deleted file mode 100644 index bed11f4f4ef..00000000000 --- a/Tools/pynche/DetailsViewer.py +++ /dev/null @@ -1,273 +0,0 @@ -"""DetailsViewer class. - -This class implements a pure input window which allows you to meticulously -edit the current color. You have both mouse control of the color (via the -buttons along the bottom row), and there are keyboard bindings for each of the -increment/decrement buttons. - -The top three check buttons allow you to specify which of the three color -variations are tied together when incrementing and decrementing. Red, green, -and blue are self evident. By tying together red and green, you can modify -the yellow level of the color. By tying together red and blue, you can modify -the magenta level of the color. By tying together green and blue, you can -modify the cyan level, and by tying all three together, you can modify the -grey level. - -The behavior at the boundaries (0 and 255) are defined by the `At boundary' -option menu: - - Stop - When the increment or decrement would send any of the tied variations - out of bounds, the entire delta is discarded. - - Wrap Around - When the increment or decrement would send any of the tied variations - out of bounds, the out of bounds variation is wrapped around to the - other side. Thus if red were at 238 and 25 were added to it, red - would have the value 7. - - Preserve Distance - When the increment or decrement would send any of the tied variations - out of bounds, all tied variations are wrapped as one, so as to - preserve the distance between them. Thus if green and blue were tied, - and green was at 238 while blue was at 223, and an increment of 25 - were applied, green would be at 15 and blue would be at 0. - - Squash - When the increment or decrement would send any of the tied variations - out of bounds, the out of bounds variation is set to the ceiling of - 255 or floor of 0, as appropriate. In this way, all tied variations - are squashed to one edge or the other. - -The following key bindings can be used as accelerators. Note that Pynche can -fall behind if you hold the key down as a key repeat: - -Left arrow == -1 -Right arrow == +1 - -Control + Left == -10 -Control + Right == 10 - -Shift + Left == -25 -Shift + Right == +25 -""" - -from tkinter import * - -STOP = 'Stop' -WRAP = 'Wrap Around' -RATIO = 'Preserve Distance' -GRAV = 'Squash' - -ADDTOVIEW = 'Details Window...' - - -class DetailsViewer: - def __init__(self, switchboard, master=None): - self.__sb = switchboard - optiondb = switchboard.optiondb() - self.__red, self.__green, self.__blue = switchboard.current_rgb() - # GUI - root = self.__root = Toplevel(master, class_='Pynche') - root.protocol('WM_DELETE_WINDOW', self.withdraw) - root.title('Pynche Details Window') - root.iconname('Pynche Details Window') - root.bind('', self.__quit) - root.bind('', self.__quit) - root.bind('', self.withdraw) - root.bind('', self.withdraw) - # accelerators - root.bind('', self.__minus1) - root.bind('', self.__plus1) - root.bind('', self.__minus10) - root.bind('', self.__plus10) - root.bind('', self.__minus25) - root.bind('', self.__plus25) - # - # color ties - frame = self.__frame = Frame(root) - frame.pack(expand=YES, fill=X) - self.__l1 = Label(frame, text='Move Sliders:') - self.__l1.grid(row=1, column=0, sticky=E) - self.__rvar = IntVar() - self.__rvar.set(optiondb.get('RSLIDER', 4)) - self.__radio1 = Checkbutton(frame, text='Red', - variable=self.__rvar, - command=self.__effect, - onvalue=4, offvalue=0) - self.__radio1.grid(row=1, column=1, sticky=W) - self.__gvar = IntVar() - self.__gvar.set(optiondb.get('GSLIDER', 2)) - self.__radio2 = Checkbutton(frame, text='Green', - variable=self.__gvar, - command=self.__effect, - onvalue=2, offvalue=0) - self.__radio2.grid(row=2, column=1, sticky=W) - self.__bvar = IntVar() - self.__bvar.set(optiondb.get('BSLIDER', 1)) - self.__radio3 = Checkbutton(frame, text='Blue', - variable=self.__bvar, - command=self.__effect, - onvalue=1, offvalue=0) - self.__radio3.grid(row=3, column=1, sticky=W) - self.__l2 = Label(frame) - self.__l2.grid(row=4, column=1, sticky=W) - self.__effect() - # - # Boundary behavior - self.__l3 = Label(frame, text='At boundary:') - self.__l3.grid(row=5, column=0, sticky=E) - self.__boundvar = StringVar() - self.__boundvar.set(optiondb.get('ATBOUND', STOP)) - self.__omenu = OptionMenu(frame, self.__boundvar, - STOP, WRAP, RATIO, GRAV) - self.__omenu.grid(row=5, column=1, sticky=W) - self.__omenu.configure(width=17) - # - # Buttons - frame = self.__btnframe = Frame(frame) - frame.grid(row=0, column=0, columnspan=2, sticky='EW') - self.__down25 = Button(frame, text='-25', - command=self.__minus25) - self.__down10 = Button(frame, text='-10', - command=self.__minus10) - self.__down1 = Button(frame, text='-1', - command=self.__minus1) - self.__up1 = Button(frame, text='+1', - command=self.__plus1) - self.__up10 = Button(frame, text='+10', - command=self.__plus10) - self.__up25 = Button(frame, text='+25', - command=self.__plus25) - self.__down25.pack(expand=YES, fill=X, side=LEFT) - self.__down10.pack(expand=YES, fill=X, side=LEFT) - self.__down1.pack(expand=YES, fill=X, side=LEFT) - self.__up1.pack(expand=YES, fill=X, side=LEFT) - self.__up10.pack(expand=YES, fill=X, side=LEFT) - self.__up25.pack(expand=YES, fill=X, side=LEFT) - - def __effect(self, event=None): - tie = self.__rvar.get() + self.__gvar.get() + self.__bvar.get() - if tie in (0, 1, 2, 4): - text = '' - else: - text = '(= %s Level)' % {3: 'Cyan', - 5: 'Magenta', - 6: 'Yellow', - 7: 'Grey'}[tie] - self.__l2.configure(text=text) - - def __quit(self, event=None): - self.__root.quit() - - def withdraw(self, event=None): - self.__root.withdraw() - - def deiconify(self, event=None): - self.__root.deiconify() - - def __minus25(self, event=None): - self.__delta(-25) - - def __minus10(self, event=None): - self.__delta(-10) - - def __minus1(self, event=None): - self.__delta(-1) - - def __plus1(self, event=None): - self.__delta(1) - - def __plus10(self, event=None): - self.__delta(10) - - def __plus25(self, event=None): - self.__delta(25) - - def __delta(self, delta): - tie = [] - if self.__rvar.get(): - red = self.__red + delta - tie.append(red) - else: - red = self.__red - if self.__gvar.get(): - green = self.__green + delta - tie.append(green) - else: - green = self.__green - if self.__bvar.get(): - blue = self.__blue + delta - tie.append(blue) - else: - blue = self.__blue - # now apply at boundary behavior - atbound = self.__boundvar.get() - if atbound == STOP: - if red < 0 or green < 0 or blue < 0 or \ - red > 255 or green > 255 or blue > 255: - # then - red, green, blue = self.__red, self.__green, self.__blue - elif atbound == WRAP or (atbound == RATIO and len(tie) < 2): - if red < 0: - red += 256 - if green < 0: - green += 256 - if blue < 0: - blue += 256 - if red > 255: - red -= 256 - if green > 255: - green -= 256 - if blue > 255: - blue -= 256 - elif atbound == RATIO: - # for when 2 or 3 colors are tied together - dir = 0 - for c in tie: - if c < 0: - dir = -1 - elif c > 255: - dir = 1 - if dir == -1: - delta = max(tie) - if self.__rvar.get(): - red = red + 255 - delta - if self.__gvar.get(): - green = green + 255 - delta - if self.__bvar.get(): - blue = blue + 255 - delta - elif dir == 1: - delta = min(tie) - if self.__rvar.get(): - red = red - delta - if self.__gvar.get(): - green = green - delta - if self.__bvar.get(): - blue = blue - delta - elif atbound == GRAV: - if red < 0: - red = 0 - if green < 0: - green = 0 - if blue < 0: - blue = 0 - if red > 255: - red = 255 - if green > 255: - green = 255 - if blue > 255: - blue = 255 - self.__sb.update_views(red, green, blue) - self.__root.update_idletasks() - - def update_yourself(self, red, green, blue): - self.__red = red - self.__green = green - self.__blue = blue - - def save_options(self, optiondb): - optiondb['RSLIDER'] = self.__rvar.get() - optiondb['GSLIDER'] = self.__gvar.get() - optiondb['BSLIDER'] = self.__bvar.get() - optiondb['ATBOUND'] = self.__boundvar.get() diff --git a/Tools/pynche/ListViewer.py b/Tools/pynche/ListViewer.py deleted file mode 100644 index b18784453c3..00000000000 --- a/Tools/pynche/ListViewer.py +++ /dev/null @@ -1,175 +0,0 @@ -"""ListViewer class. - -This class implements an input/output view on the color model. It lists every -unique color (e.g. unique r/g/b value) found in the color database. Each -color is shown by small swatch and primary color name. Some colors have -aliases -- more than one name for the same r/g/b value. These aliases are -displayed in the small listbox at the bottom of the screen. - -Clicking on a color name or swatch selects that color and updates all other -windows. When a color is selected in a different viewer, the color list is -scrolled to the selected color and it is highlighted. If the selected color -is an r/g/b value without a name, no scrolling occurs. - -You can turn off Update On Click if all you want to see is the alias for a -given name, without selecting the color. -""" - -from tkinter import * -import ColorDB - -ADDTOVIEW = 'Color %List Window...' - -class ListViewer: - def __init__(self, switchboard, master=None): - self.__sb = switchboard - optiondb = switchboard.optiondb() - self.__lastbox = None - self.__dontcenter = 0 - # GUI - root = self.__root = Toplevel(master, class_='Pynche') - root.protocol('WM_DELETE_WINDOW', self.withdraw) - root.title('Pynche Color List') - root.iconname('Pynche Color List') - root.bind('', self.__quit) - root.bind('', self.__quit) - root.bind('', self.withdraw) - root.bind('', self.withdraw) - # - # create the canvas which holds everything, and its scrollbar - # - frame = self.__frame = Frame(root) - frame.pack() - canvas = self.__canvas = Canvas(frame, width=160, height=300, - borderwidth=2, relief=SUNKEN) - self.__scrollbar = Scrollbar(frame) - self.__scrollbar.pack(fill=Y, side=RIGHT) - canvas.pack(fill=BOTH, expand=1) - canvas.configure(yscrollcommand=(self.__scrollbar, 'set')) - self.__scrollbar.configure(command=(canvas, 'yview')) - self.__populate() - # - # Update on click - self.__uoc = BooleanVar() - self.__uoc.set(optiondb.get('UPONCLICK', 1)) - self.__uocbtn = Checkbutton(root, - text='Update on Click', - variable=self.__uoc, - command=self.__toggleupdate) - self.__uocbtn.pack(expand=1, fill=BOTH) - # - # alias list - self.__alabel = Label(root, text='Aliases:') - self.__alabel.pack() - self.__aliases = Listbox(root, height=5, - selectmode=BROWSE) - self.__aliases.pack(expand=1, fill=BOTH) - - def __populate(self): - # - # create all the buttons - colordb = self.__sb.colordb() - canvas = self.__canvas - row = 0 - widest = 0 - bboxes = self.__bboxes = [] - for name in colordb.unique_names(): - exactcolor = ColorDB.triplet_to_rrggbb(colordb.find_byname(name)) - canvas.create_rectangle(5, row*20 + 5, - 20, row*20 + 20, - fill=exactcolor) - textid = canvas.create_text(25, row*20 + 13, - text=name, - anchor=W) - x1, y1, textend, y2 = canvas.bbox(textid) - boxid = canvas.create_rectangle(3, row*20+3, - textend+3, row*20 + 23, - outline='', - tags=(exactcolor, 'all')) - canvas.bind('', self.__onrelease) - bboxes.append(boxid) - if textend+3 > widest: - widest = textend+3 - row += 1 - canvheight = (row-1)*20 + 25 - canvas.config(scrollregion=(0, 0, 150, canvheight)) - for box in bboxes: - x1, y1, x2, y2 = canvas.coords(box) - canvas.coords(box, x1, y1, widest, y2) - - def __onrelease(self, event=None): - canvas = self.__canvas - # find the current box - x = canvas.canvasx(event.x) - y = canvas.canvasy(event.y) - ids = canvas.find_overlapping(x, y, x, y) - for boxid in ids: - if boxid in self.__bboxes: - break - else: -## print 'No box found!' - return - tags = self.__canvas.gettags(boxid) - for t in tags: - if t[0] == '#': - break - else: -## print 'No color tag found!' - return - red, green, blue = ColorDB.rrggbb_to_triplet(t) - self.__dontcenter = 1 - if self.__uoc.get(): - self.__sb.update_views(red, green, blue) - else: - self.update_yourself(red, green, blue) - self.__red, self.__green, self.__blue = red, green, blue - - def __toggleupdate(self, event=None): - if self.__uoc.get(): - self.__sb.update_views(self.__red, self.__green, self.__blue) - - def __quit(self, event=None): - self.__root.quit() - - def withdraw(self, event=None): - self.__root.withdraw() - - def deiconify(self, event=None): - self.__root.deiconify() - - def update_yourself(self, red, green, blue): - canvas = self.__canvas - # turn off the last box - if self.__lastbox: - canvas.itemconfigure(self.__lastbox, outline='') - # turn on the current box - colortag = ColorDB.triplet_to_rrggbb((red, green, blue)) - canvas.itemconfigure(colortag, outline='black') - self.__lastbox = colortag - # fill the aliases - self.__aliases.delete(0, END) - try: - aliases = self.__sb.colordb().aliases_of(red, green, blue)[1:] - except ColorDB.BadColor: - self.__aliases.insert(END, '') - return - if not aliases: - self.__aliases.insert(END, '') - else: - for name in aliases: - self.__aliases.insert(END, name) - # maybe scroll the canvas so that the item is visible - if self.__dontcenter: - self.__dontcenter = 0 - else: - ig, ig, ig, y1 = canvas.coords(colortag) - ig, ig, ig, y2 = canvas.coords(self.__bboxes[-1]) - h = int(canvas['height']) * 0.5 - canvas.yview('moveto', (y1-h) / y2) - - def save_options(self, optiondb): - optiondb['UPONCLICK'] = self.__uoc.get() - - def colordb_changed(self, colordb): - self.__canvas.delete('all') - self.__populate() diff --git a/Tools/pynche/Main.py b/Tools/pynche/Main.py deleted file mode 100644 index 4db560b5681..00000000000 --- a/Tools/pynche/Main.py +++ /dev/null @@ -1,229 +0,0 @@ -"""Pynche -- The PYthon Natural Color and Hue Editor. - -Contact: %(AUTHNAME)s -Email: %(AUTHEMAIL)s -Version: %(__version__)s - -Pynche is based largely on a similar color editor I wrote years ago for the -SunView window system. That editor was called ICE: the Interactive Color -Editor. I'd always wanted to port the editor to X but didn't feel like -hacking X and C code to do it. Fast forward many years, to where Python + -Tkinter provides such a nice programming environment, with enough power, that -I finally buckled down and implemented it. I changed the name because these -days, too many other systems have the acronym `ICE'. - -This program currently requires Python 2.2 with Tkinter. - -Usage: %(PROGRAM)s [-d file] [-i file] [-X] [-v] [-h] [initialcolor] - -Where: - --database file - -d file - Alternate location of a color database file - - --initfile file - -i file - Alternate location of the initialization file. This file contains a - persistent database of the current Pynche options and color. This - means that Pynche restores its option settings and current color when - it restarts, using this file (unless the -X option is used). The - default is ~/.pynche - - --ignore - -X - Ignore the initialization file when starting up. Pynche will still - write the current option settings to this file when it quits. - - --version - -v - print the version number and exit - - --help - -h - print this message - - initialcolor - initial color, as a color name or #RRGGBB format -""" - -__version__ = '1.4.1' - -import sys -import os -import getopt -import ColorDB - -from PyncheWidget import PyncheWidget -from Switchboard import Switchboard -from StripViewer import StripViewer -from ChipViewer import ChipViewer -from TypeinViewer import TypeinViewer - - - -PROGRAM = sys.argv[0] -AUTHNAME = 'Barry Warsaw' -AUTHEMAIL = 'barry@python.org' - -# Default locations of rgb.txt or other textual color database -RGB_TXT = [ - # Solaris OpenWindows - '/usr/openwin/lib/rgb.txt', - # Linux - '/usr/lib/X11/rgb.txt', - # The X11R6.4 rgb.txt file - os.path.join(sys.path[0], 'X/rgb.txt'), - # add more here - ] - - - -# Do this because PyncheWidget.py wants to get at the interpolated docstring -# too, for its Help menu. -def docstring(): - return __doc__ % globals() - - -def usage(code, msg=''): - print(docstring()) - if msg: - print(msg) - sys.exit(code) - - - -def initial_color(s, colordb): - # function called on every color - def scan_color(s, colordb=colordb): - try: - r, g, b = colordb.find_byname(s) - except ColorDB.BadColor: - try: - r, g, b = ColorDB.rrggbb_to_triplet(s) - except ColorDB.BadColor: - return None, None, None - return r, g, b - # - # First try the passed in color - r, g, b = scan_color(s) - if r is None: - # try the same color with '#' prepended, since some shells require - # this to be escaped, which is a pain - r, g, b = scan_color('#' + s) - if r is None: - print('Bad initial color, using gray50:', s) - r, g, b = scan_color('gray50') - if r is None: - usage(1, 'Cannot find an initial color to use') - # does not return - return r, g, b - - - -def build(master=None, initialcolor=None, initfile=None, ignore=None, - dbfile=None): - # create all output widgets - s = Switchboard(not ignore and initfile) - # defer to the command line chosen color database, falling back to the one - # in the .pynche file. - if dbfile is None: - dbfile = s.optiondb().get('DBFILE') - # find a parseable color database - colordb = None - files = RGB_TXT[:] - if dbfile is None: - dbfile = files.pop() - while colordb is None: - try: - colordb = ColorDB.get_colordb(dbfile) - except (KeyError, IOError): - pass - if colordb is None: - if not files: - break - dbfile = files.pop(0) - if not colordb: - usage(1, 'No color database file found, see the -d option.') - s.set_colordb(colordb) - - # create the application window decorations - app = PyncheWidget(__version__, s, master=master) - w = app.window() - - # these built-in viewers live inside the main Pynche window - s.add_view(StripViewer(s, w)) - s.add_view(ChipViewer(s, w)) - s.add_view(TypeinViewer(s, w)) - - # get the initial color as components and set the color on all views. if - # there was no initial color given on the command line, use the one that's - # stored in the option database - if initialcolor is None: - optiondb = s.optiondb() - red = optiondb.get('RED') - green = optiondb.get('GREEN') - blue = optiondb.get('BLUE') - # but if there wasn't any stored in the database, use grey50 - if red is None or blue is None or green is None: - red, green, blue = initial_color('grey50', colordb) - else: - red, green, blue = initial_color(initialcolor, colordb) - s.update_views(red, green, blue) - return app, s - - -def run(app, s): - try: - app.start() - except KeyboardInterrupt: - pass - - - -def main(): - try: - opts, args = getopt.getopt( - sys.argv[1:], - 'hd:i:Xv', - ['database=', 'initfile=', 'ignore', 'help', 'version']) - except getopt.error as msg: - usage(1, msg) - - if len(args) == 0: - initialcolor = None - elif len(args) == 1: - initialcolor = args[0] - else: - usage(1) - - ignore = False - dbfile = None - initfile = os.path.expanduser('~/.pynche') - for opt, arg in opts: - if opt in ('-h', '--help'): - usage(0) - elif opt in ('-v', '--version'): - print("""\ -Pynche -- The PYthon Natural Color and Hue Editor. -Contact: %(AUTHNAME)s -Email: %(AUTHEMAIL)s -Version: %(__version__)s""" % globals()) - sys.exit(0) - elif opt in ('-d', '--database'): - dbfile = arg - elif opt in ('-X', '--ignore'): - ignore = True - elif opt in ('-i', '--initfile'): - initfile = arg - - app, sb = build(initialcolor=initialcolor, - initfile=initfile, - ignore=ignore, - dbfile=dbfile) - run(app, sb) - sb.save_views() - - - -if __name__ == '__main__': - main() diff --git a/Tools/pynche/PyncheWidget.py b/Tools/pynche/PyncheWidget.py deleted file mode 100644 index ea456e577e1..00000000000 --- a/Tools/pynche/PyncheWidget.py +++ /dev/null @@ -1,313 +0,0 @@ -"""Main Pynche (Pythonically Natural Color and Hue Editor) widget. - -This window provides the basic decorations, primarily including the menubar. -It is used to bring up other windows. -""" - -import sys -import os -from tkinter import * -from tkinter import messagebox, filedialog -import ColorDB - -# Milliseconds between interrupt checks -KEEPALIVE_TIMER = 500 - - - -class PyncheWidget: - def __init__(self, version, switchboard, master=None, extrapath=[]): - self.__sb = switchboard - self.__version = version - self.__textwin = None - self.__listwin = None - self.__detailswin = None - self.__helpwin = None - self.__dialogstate = {} - modal = self.__modal = not not master - # If a master was given, we are running as a modal dialog servant to - # some other application. We rearrange our UI in this case (there's - # no File menu and we get `Okay' and `Cancel' buttons), and we do a - # grab_set() to make ourselves modal - if modal: - self.__tkroot = tkroot = Toplevel(master, class_='Pynche') - tkroot.grab_set() - tkroot.withdraw() - else: - # Is there already a default root for Tk, say because we're - # running under Guido's IDE? :-) Two conditions say no, either the - # _default_root is None or it is unset. - tkroot = getattr(tkinter, '_default_root', None) - if not tkroot: - tkroot = Tk(className='Pynche') - self.__tkroot = tkroot - # but this isn't our top level widget, so make it invisible - tkroot.withdraw() - # create the menubar - menubar = self.__menubar = Menu(tkroot) - # - # File menu - # - filemenu = self.__filemenu = Menu(menubar, tearoff=0) - filemenu.add_command(label='Load palette...', - command=self.__load, - underline=0) - if not modal: - filemenu.add_command(label='Quit', - command=self.__quit, - accelerator='Alt-Q', - underline=0) - # - # View menu - # - views = make_view_popups(self.__sb, self.__tkroot, extrapath) - viewmenu = Menu(menubar, tearoff=0) - for v in views: - viewmenu.add_command(label=v.menutext(), - command=v.popup, - underline=v.underline()) - # - # Help menu - # - helpmenu = Menu(menubar, name='help', tearoff=0) - helpmenu.add_command(label='About Pynche...', - command=self.__popup_about, - underline=0) - helpmenu.add_command(label='Help...', - command=self.__popup_usage, - underline=0) - # - # Tie them all together - # - menubar.add_cascade(label='File', - menu=filemenu, - underline=0) - menubar.add_cascade(label='View', - menu=viewmenu, - underline=0) - menubar.add_cascade(label='Help', - menu=helpmenu, - underline=0) - - # now create the top level window - root = self.__root = Toplevel(tkroot, class_='Pynche', menu=menubar) - root.protocol('WM_DELETE_WINDOW', - modal and self.__bell or self.__quit) - root.title('Pynche %s' % version) - root.iconname('Pynche') - # Only bind accelerators for the File->Quit menu item if running as a - # standalone app - if not modal: - root.bind('', self.__quit) - root.bind('', self.__quit) - else: - # We're a modal dialog so we have a new row of buttons - bframe = Frame(root, borderwidth=1, relief=RAISED) - bframe.grid(row=4, column=0, columnspan=2, - sticky='EW', - ipady=5) - okay = Button(bframe, - text='Okay', - command=self.__okay) - okay.pack(side=LEFT, expand=1) - cancel = Button(bframe, - text='Cancel', - command=self.__cancel) - cancel.pack(side=LEFT, expand=1) - - def __quit(self, event=None): - self.__tkroot.quit() - - def __bell(self, event=None): - self.__tkroot.bell() - - def __okay(self, event=None): - self.__sb.withdraw_views() - self.__tkroot.grab_release() - self.__quit() - - def __cancel(self, event=None): - self.__sb.canceled() - self.__okay() - - def __keepalive(self): - # Exercise the Python interpreter regularly so keyboard interrupts get - # through. - self.__tkroot.tk.createtimerhandler(KEEPALIVE_TIMER, self.__keepalive) - - def start(self): - if not self.__modal: - self.__keepalive() - self.__tkroot.mainloop() - - def window(self): - return self.__root - - def __popup_about(self, event=None): - from Main import __version__ - messagebox.showinfo('About Pynche ' + __version__, - '''\ -Pynche %s -The PYthonically Natural -Color and Hue Editor - -For information -contact: Barry A. Warsaw -email: bwarsaw@python.org''' % __version__) - - def __popup_usage(self, event=None): - if not self.__helpwin: - self.__helpwin = Helpwin(self.__root, self.__quit) - self.__helpwin.deiconify() - - def __load(self, event=None): - while 1: - idir, ifile = os.path.split(self.__sb.colordb().filename()) - file = filedialog.askopenfilename( - filetypes=[('Text files', '*.txt'), - ('All files', '*'), - ], - initialdir=idir, - initialfile=ifile) - if not file: - # cancel button - return - try: - colordb = ColorDB.get_colordb(file) - except IOError: - messagebox.showerror('Read error', '''\ -Could not open file for reading: -%s''' % file) - continue - if colordb is None: - messagebox.showerror('Unrecognized color file type', '''\ -Unrecognized color file type in file: -%s''' % file) - continue - break - self.__sb.set_colordb(colordb) - - def withdraw(self): - self.__root.withdraw() - - def deiconify(self): - self.__root.deiconify() - - - -class Helpwin: - def __init__(self, master, quitfunc): - from Main import docstring - self.__root = root = Toplevel(master, class_='Pynche') - root.protocol('WM_DELETE_WINDOW', self.__withdraw) - root.title('Pynche Help Window') - root.iconname('Pynche Help Window') - root.bind('', quitfunc) - root.bind('', quitfunc) - root.bind('', self.__withdraw) - root.bind('', self.__withdraw) - - # more elaborate help is available in the README file - readmefile = os.path.join(sys.path[0], 'README') - try: - fp = None - try: - fp = open(readmefile) - contents = fp.read() - # wax the last page, it contains Emacs cruft - i = contents.rfind('\f') - if i > 0: - contents = contents[:i].rstrip() - finally: - if fp: - fp.close() - except IOError: - sys.stderr.write("Couldn't open Pynche's README, " - 'using docstring instead.\n') - contents = docstring() - - self.__text = text = Text(root, relief=SUNKEN, - width=80, height=24) - self.__text.focus_set() - text.insert(0.0, contents) - scrollbar = Scrollbar(root) - scrollbar.pack(fill=Y, side=RIGHT) - text.pack(fill=BOTH, expand=YES) - text.configure(yscrollcommand=(scrollbar, 'set')) - scrollbar.configure(command=(text, 'yview')) - - def __withdraw(self, event=None): - self.__root.withdraw() - - def deiconify(self): - self.__root.deiconify() - - - -import functools -@functools.total_ordering -class PopupViewer: - def __init__(self, module, name, switchboard, root): - self.__m = module - self.__name = name - self.__sb = switchboard - self.__root = root - self.__menutext = module.ADDTOVIEW - # find the underline character - underline = module.ADDTOVIEW.find('%') - if underline == -1: - underline = 0 - else: - self.__menutext = module.ADDTOVIEW.replace('%', '', 1) - self.__underline = underline - self.__window = None - - def menutext(self): - return self.__menutext - - def underline(self): - return self.__underline - - def popup(self, event=None): - if not self.__window: - # class and module must have the same name - class_ = getattr(self.__m, self.__name) - self.__window = class_(self.__sb, self.__root) - self.__sb.add_view(self.__window) - self.__window.deiconify() - - def __eq__(self, other): - if isinstance(self, PopupViewer): - return self.__menutext == other.__menutext - return NotImplemented - - def __lt__(self, other): - if isinstance(self, PopupViewer): - return self.__menutext < other.__menutext - return NotImplemented - - -def make_view_popups(switchboard, root, extrapath): - viewers = [] - # where we are in the file system - dirs = [os.path.dirname(__file__)] + extrapath - for dir in dirs: - if dir == '': - dir = '.' - for file in os.listdir(dir): - if file[-9:] == 'Viewer.py': - name = file[:-3] - try: - module = __import__(name) - except ImportError: - # Pynche is running from inside a package, so get the - # module using the explicit path. - pkg = __import__('pynche.'+name) - module = getattr(pkg, name) - if hasattr(module, 'ADDTOVIEW') and module.ADDTOVIEW: - # this is an external viewer - v = PopupViewer(module, name, switchboard, root) - viewers.append(v) - # sort alphabetically - viewers.sort() - return viewers diff --git a/Tools/pynche/README b/Tools/pynche/README deleted file mode 100644 index ae8183f2a71..00000000000 --- a/Tools/pynche/README +++ /dev/null @@ -1,398 +0,0 @@ -Pynche - The PYthonically Natural Color and Hue Editor - -Contact: Barry A. Warsaw -Email: bwarsaw@python.org -Version: 1.3 - -Introduction - - Pynche is a color editor based largely on a similar program that I - originally wrote back in 1987 for the Sunview window system. That - editor was called ICE, the Interactive Color Editor. I'd always - wanted to port this program to X but didn't feel like hacking X - and C code to do it. Fast forward many years, to where Python + - Tkinter provides such a nice programming environment, with enough - power, that I finally buckled down and re-implemented it. I - changed the name because these days, too many other systems have - the acronym `ICE'. - - Pynche should work with any variant of Python after 1.5.2 - (e.g. 2.0.1 and 2.1.1), using Tk 8.0.x. It's been tested on - Solaris 2.6, Windows NT 4, and various Linux distros. You'll want - to be sure to have at least Tk 8.0.3 for Windows. Also, Pynche is - very colormap intensive, so it doesn't work very well on 8-bit - graphics cards; 24bit+ graphics cards are so cheap these days, - I'll probably never "fix" that. - - Pynche must find a text database of colors names in order to - provide `nearest' color matching. Pynche is distributed with an - rgb.txt file from the X11R6.4 distribution for this reason, along - with other "web related" database (see below). You can use a - different file with the -d option. The file xlicense.txt contains - the license only for rgb.txt and both files are in the X/ - subdirectory. - - Pynche is pronounced: Pin'-chee - - -Running Standalone - - On Unix, start it by running the `pynche' script. On Windows, run - pynche.pyw to inhibit the console window. When run from the - command line, the following options are recognized: - - --database file - -d file - Alternate location of the color database file. Without this - option, the first valid file found will be used (see below). - - --initfile file - -i file - Alternate location of the persistent initialization file. See - the section on Persistency below. - - --ignore - -X - Ignore the persistent initialization file when starting up. - Pynche will still write the current option settings to the - persistent init file when it quits. - - --help - -h - Print the help message. - - initialcolor - a Tk color name or #rrggbb color spec to be used as the - initially selected color. This overrides any color saved in - the persistent init file. Since `#' needs to be escaped in - many shells, it is optional in the spec (e.g. #45dd1f is the - same as 45dd1f). - - -Running as a Modal Dialog - - Pynche can be run as a modal dialog, inside another application, - say as a general color chooser. In fact, Grail 0.6 uses Pynche - and a future version of IDLE may as well. Pynche supports the API - implemented by the Tkinter standard tkColorChooser module, with a - few changes as described below. By importing pyColorChooser from - the Pynche package, you can run - - pyColorChooser.askcolor() - - which will popup Pynche as a modal dialog, and return the selected - color. - - There are some UI differences when running as a modal - vs. standalone. When running as a modal, there is no "Quit" menu - item under the "File" menu. Instead there are "Okay" and "Cancel" - buttons. - - When "Okay" is hit, askcolor() returns the tuple - - ((r, g, b), "name") - - where r, g, and b are red, green, and blue color values - respectively (in the range 0 to 255). "name" will be a color name - from the color database if there is an exact match, otherwise it - will be an X11 color spec of the form "#rrggbb". Note that this - is different than tkColorChooser, which doesn't know anything - about color names. - - askcolor() supports the following optional keyword arguments: - - color - the color to set as the initial selected color - - master[*] - the master window to use as the parent of the modal - dialog. Without this argument, pyColorChooser will create - its own Tkinter.Tk instance as the master. This may not - be what you want. - - databasefile - similar to the --database option, the value must be a - file name - - initfile[*] - similar to the --initfile option, the value must be a - file name - - ignore[*] - similar to the --ignore flag, the value is a boolean - - wantspec - When this is true, the "name" field in the return tuple - will always be a color spec of the form "#rrggbb". It - will not return a color name even if there is a match; - this is so pyColorChooser can exactly match the API of - tkColorChooser. - - [*] these arguments must be specified the first time - askcolor() is used and cannot be changed on subsequent calls. - - -The Colorstrip Window - - The top part of the main Pynche window contains the "variation - strips". Each strip contains a number of "color chips". The - strips always indicate the currently selected color by a highlight - rectangle around the selected color chip, with an arrow pointing - to the chip. Each arrow has an associated number giving you the - color value along the variation's axis. Each variation strip - shows you the colors that are reachable from the selected color by - varying just one axis of the color solid. - - For example, when the selected color is (in Red/Green/Blue - notation) 127/127/127, the Red Variations strip shows you every - color in the range 0/127/127 to 255/127/127. Similarly for the - green and blue axes. You can select any color by clicking on its - chip. This will update the highlight rectangle and the arrow, as - well as other displays in Pynche. - - Click on "Update while dragging" if you want Pynche to update the - selected color while you drag along any variation strip (this will - be a bit slower). Click on "Hexadecimal" to display the arrow - numbers in hex. - - There are also two shortcut buttons in this window, which - auto-select Black (0/0/0) and White (255/255/255). - - -The Proof Window - - In the lower left corner of the main window you see two larger - color chips. The Selected chip shows you a larger version of the - color selected in the variation strips, along with its X11 color - specification. The Nearest chip shows you the closest color in - the X11 database to the selected color, giving its X11 color - specification, and below that, its X11 color name. When the - Selected chip color exactly matches the Nearest chip color, you - will see the color name appear below the color specification for - the Selected chip. - - Clicking on the Nearest color chip selects that color. Color - distance is calculated in the 3D space of the RGB color solid and - if more than one color name is the same distance from the selected - color, the first one found will be chosen. - - Note that there may be more than one X11 color name for the same - RGB value. In that case, the first one found in the text database - is designated the "primary" name, and this is shown under the - Nearest chip. The other names are "aliases" and they are visible - in the Color List Window (see below). - - Both the color specifications and color names are selectable for - copying and pasting into another window. - - -The Type-in Window - - At the lower right of the main window are three entry fields. - Here you can type numeric values for any of the three color axes. - Legal values are between 0 and 255, and these fields do not allow - you to enter illegal values. You must hit Enter or Tab to select - the new color. - - Click on "Update while typing" if you want Pynche to select the - color on every keystroke (well, every one that produces a legal - value!) Click on "Hexadecimal" to display and enter color values - in hex. - - -Other Views - - There are three secondary windows which are not displayed by - default. You can bring these up via the "View" menu on the main - Pynche window. - - -The Text Window - - The "Text Window" allows you to see what effects various colors - have on the standard Tk text widget elements. In the upper part - of the window is a plain Tk text widget and here you can edit the - text, select a region of text, etc. Below this is a button "Track - color changes". When this is turned on, any colors selected in - the other windows will change the text widget element specified in - the radio buttons below. When this is turned off, text widget - elements are not affected by color selection. - - You can choose which element gets changed by color selection by - clicking on one of the radio buttons in the bottom part of this - window. Text foreground and background affect the text in the - upper part of the window. Selection foreground and background - affect the colors of the primary selection which is what you see - when you click the middle button (depending on window system) and - drag it through some text. - - The Insertion is the insertion cursor in the text window, where - new text will be inserted as you type. The insertion cursor only - has a background. - - -The Color List Window - - The "Color List" window shows every named color in the color name - database (this window may take a while to come up). In the upper - part of the window you see a scrolling list of all the color names - in the database, in alphabetical order. Click on any color to - select it. In the bottom part of the window is displayed any - aliases for the selected color (those color names that have the - same RGB value, but were found later in the text database). For - example, find the color "Black" and you'll see that its aliases - are "gray0" and "grey0". - - If the color has no aliases you'll see "" here. If you - just want to see if a color has an alias, and do not want to select a - color when you click on it, turn off "Update on Click". - - Note that the color list is always updated when a color is selected - from the main window. There's no way to turn this feature off. If - the selected color has no matching color name you'll see - "" in the Aliases window. - - -The Details Window - - The "Details" window gives you more control over color selection - than just clicking on a color chip in the main window. The row of - buttons along the top apply the specified increment and decrement - amounts to the selected color. These delta amounts are applied to - the variation strips specified by the check boxes labeled "Move - Sliders". Thus if just Red and Green are selected, hitting -10 - will subtract 10 from the color value along the red and green - variation only. Note the message under the checkboxes; this - indicates the primary color level being changed when more than one - slider is tied together. For example, if Red and Green are - selected, you will be changing the Yellow level of the selected - color. - - The "At Boundary" behavior determines what happens when any color - variation hits either the lower or upper boundaries (0 or 255) as - a result of clicking on the top row buttons: - - Stop - When the increment or decrement would send any of the tied - variations out of bounds, the entire delta is discarded. - - Wrap Around - When the increment or decrement would send any of the tied - variations out of bounds, the out of bounds value is wrapped - around to the other side. Thus if red were at 238 and +25 - were clicked, red would have the value 7. - - Preserve Distance - When the increment or decrement would send any of the tied - variations out of bounds, all tied variations are wrapped as - one, so as to preserve the distance between them. Thus if - green and blue were tied, and green was at 238 while blue was - at 223, and +25 were clicked, green would be at 15 and blue - would be at 0. - - Squash - When the increment or decrement would send any of the tied - variations out of bounds, the out of bounds variation is set - to the ceiling of 255 or floor of 0, as appropriate. In this - way, all tied variations are squashed to one edge or the - other. - - The top row buttons have the following keyboard accelerators: - - -25 == Shift Left Arrow - -10 == Control Left Arrow - -1 == Left Arrow - +1 == Right Arrow - +10 == Control Right Arrow - +25 == Shift Right Arrow - - -Keyboard Accelerators - - Alt-w in any secondary window dismisses the window. In the main - window it exits Pynche (except when running as a modal). - - Alt-q in any window exits Pynche (except when running as a modal). - - -Persistency - - Pynche remembers various settings of options and colors between - invocations, storing these values in a `persistent initialization - file'. The actual location of this file is specified by the - --initfile option (see above), and defaults to ~/.pynche. - - When Pynche exits, it saves these values in the init file, and - re-reads them when it starts up. There is no locking on this - file, so if you run multiple instances of Pynche at a time, you - may clobber the init file. - - The actual options stored include - - - the currently selected color - - - all settings of checkbox and radio button options in all windows - - - the contents of the text window, the current text selection and - insertion point, and all current text widget element color - settings. - - - the name of the color database file (but not its contents) - - You can inhibit Pynche from reading the init file by supplying the - --ignore option on the command line. However, you cannot suppress - the storing of the settings in the init file on Pynche exit. If - you really want to do this, use /dev/null as the init file, using - --initfile. - - -Color Name Database Files - - Pynche uses a color name database file to calculate the nearest - color to the selected color, and to display in the Color List - view. Several files are distributed with Pynche, described - below. By default, the X11 color name database file is selected. - Other files: - - html40colors.txt -- the HTML 4.0 guaranteed color names - - websafe.txt -- the 216 "web-safe" colors that Netscape and MSIE - guarantee will not be dithered. These are specified in #rrggbb - format for both values and names - - webcolors.txt -- The 140 color names that Tim Peters and his - sister say NS and MSIE both understand (with some controversy over - AliceBlue). - - namedcolors.txt -- an alternative set of Netscape colors. - - You can switch between files by choosing "Load palette..." from - the "File" menu. This brings up a standard Tk file dialog. - Choose the file you want and then click "Ok". If Pynche - understands the format in this file, it will load the database and - update the appropriate windows. If not, it will bring up an error - dialog. - - -To Do - - Here's a brief list of things I want to do (some mythical day): - - - Better support for resizing the top level windows - - - More output views, e.g. color solids - - - Have the notion of a `last color selected'; this may require a - new output view - - - Support setting the font in the text view - - - Support distutils setup.py for installation - - I'm open to suggestions! - - - -Local Variables: -indent-tabs-mode: nil -End: diff --git a/Tools/pynche/StripViewer.py b/Tools/pynche/StripViewer.py deleted file mode 100644 index 6914ca94b2b..00000000000 --- a/Tools/pynche/StripViewer.py +++ /dev/null @@ -1,397 +0,0 @@ -"""Strip viewer and related widgets. - -The classes in this file implement the StripViewer shown in the top two thirds -of the main Pynche window. It consists of three StripWidgets which display -the variations in red, green, and blue respectively of the currently selected -r/g/b color value. - -Each StripWidget shows the color variations that are reachable by varying an -axis of the currently selected color. So for example, if the color is - - (R,G,B)=(127,163,196) - -then the Red variations show colors from (0,163,196) to (255,163,196), the -Green variations show colors from (127,0,196) to (127,255,196), and the Blue -variations show colors from (127,163,0) to (127,163,255). - -The selected color is always visible in all three StripWidgets, and in fact -each StripWidget highlights the selected color, and has an arrow pointing to -the selected chip, which includes the value along that particular axis. - -Clicking on any chip in any StripWidget selects that color, and updates all -arrows and other windows. By toggling on Update while dragging, Pynche will -select the color under the cursor while you drag it, but be forewarned that -this can be slow. -""" - -from tkinter import * -import ColorDB - -# Load this script into the Tcl interpreter and call it in -# StripWidget.set_color(). This is about as fast as it can be with the -# current _tkinter.c interface, which doesn't support Tcl Objects. -TCLPROC = '''\ -proc setcolor {canv colors} { - set i 1 - foreach c $colors { - $canv itemconfigure $i -fill $c -outline $c - incr i - } -} -''' - -# Tcl event types -BTNDOWN = 4 -BTNUP = 5 -BTNDRAG = 6 - -SPACE = ' ' - - - -def constant(numchips): - step = 255.0 / (numchips - 1) - start = 0.0 - seq = [] - while numchips > 0: - seq.append(int(start)) - start = start + step - numchips = numchips - 1 - return seq - -# red variations, green+blue = cyan constant -def constant_red_generator(numchips, red, green, blue): - seq = constant(numchips) - return list(zip([red] * numchips, seq, seq)) - -# green variations, red+blue = magenta constant -def constant_green_generator(numchips, red, green, blue): - seq = constant(numchips) - return list(zip(seq, [green] * numchips, seq)) - -# blue variations, red+green = yellow constant -def constant_blue_generator(numchips, red, green, blue): - seq = constant(numchips) - return list(zip(seq, seq, [blue] * numchips)) - -# red variations, green+blue = cyan constant -def constant_cyan_generator(numchips, red, green, blue): - seq = constant(numchips) - return list(zip(seq, [green] * numchips, [blue] * numchips)) - -# green variations, red+blue = magenta constant -def constant_magenta_generator(numchips, red, green, blue): - seq = constant(numchips) - return list(zip([red] * numchips, seq, [blue] * numchips)) - -# blue variations, red+green = yellow constant -def constant_yellow_generator(numchips, red, green, blue): - seq = constant(numchips) - return list(zip([red] * numchips, [green] * numchips, seq)) - - - -class LeftArrow: - _ARROWWIDTH = 30 - _ARROWHEIGHT = 15 - _YOFFSET = 13 - _TEXTYOFFSET = 1 - _TAG = ('leftarrow',) - - def __init__(self, canvas, x): - self._canvas = canvas - self.__arrow, self.__text = self._create(x) - self.move_to(x) - - def _create(self, x): - arrow = self._canvas.create_line( - x, self._ARROWHEIGHT + self._YOFFSET, - x, self._YOFFSET, - x + self._ARROWWIDTH, self._YOFFSET, - arrow='first', - width=3.0, - tags=self._TAG) - text = self._canvas.create_text( - x + self._ARROWWIDTH + 13, - self._ARROWHEIGHT - self._TEXTYOFFSET, - tags=self._TAG, - text='128') - return arrow, text - - def _x(self): - coords = list(self._canvas.coords(self._TAG)) - assert coords - return coords[0] - - def move_to(self, x): - deltax = x - self._x() - self._canvas.move(self._TAG, deltax, 0) - - def set_text(self, text): - self._canvas.itemconfigure(self.__text, text=text) - - -class RightArrow(LeftArrow): - _TAG = ('rightarrow',) - - def _create(self, x): - arrow = self._canvas.create_line( - x, self._YOFFSET, - x + self._ARROWWIDTH, self._YOFFSET, - x + self._ARROWWIDTH, self._ARROWHEIGHT + self._YOFFSET, - arrow='last', - width=3.0, - tags=self._TAG) - text = self._canvas.create_text( - x - self._ARROWWIDTH + 15, # BAW: kludge - self._ARROWHEIGHT - self._TEXTYOFFSET, - justify=RIGHT, - text='128', - tags=self._TAG) - return arrow, text - - def _x(self): - coords = list(self._canvas.coords(self._TAG)) - assert coords - return coords[0] + self._ARROWWIDTH - - - -class StripWidget: - _CHIPHEIGHT = 50 - _CHIPWIDTH = 10 - _NUMCHIPS = 40 - - def __init__(self, switchboard, - master = None, - chipwidth = _CHIPWIDTH, - chipheight = _CHIPHEIGHT, - numchips = _NUMCHIPS, - generator = None, - axis = None, - label = '', - uwdvar = None, - hexvar = None): - # instance variables - self.__generator = generator - self.__axis = axis - self.__numchips = numchips - assert self.__axis in (0, 1, 2) - self.__uwd = uwdvar - self.__hexp = hexvar - # the last chip selected - self.__lastchip = None - self.__sb = switchboard - - canvaswidth = numchips * (chipwidth + 1) - canvasheight = chipheight + 43 # BAW: Kludge - - # create the canvas and pack it - canvas = self.__canvas = Canvas(master, - width=canvaswidth, - height=canvasheight, -## borderwidth=2, -## relief=GROOVE - ) - - canvas.pack() - canvas.bind('', self.__select_chip) - canvas.bind('', self.__select_chip) - canvas.bind('', self.__select_chip) - - # Load a proc into the Tcl interpreter. This is used in the - # set_color() method to speed up setting the chip colors. - canvas.tk.eval(TCLPROC) - - # create the color strip - chips = self.__chips = [] - x = 1 - y = 30 - tags = ('chip',) - for c in range(self.__numchips): - color = 'grey' - canvas.create_rectangle( - x, y, x+chipwidth, y+chipheight, - fill=color, outline=color, - tags=tags) - x = x + chipwidth + 1 # for outline - chips.append(color) - - # create the strip label - self.__label = canvas.create_text( - 3, y + chipheight + 8, - text=label, - anchor=W) - - # create the arrow and text item - chipx = self.__arrow_x(0) - self.__leftarrow = LeftArrow(canvas, chipx) - - chipx = self.__arrow_x(len(chips) - 1) - self.__rightarrow = RightArrow(canvas, chipx) - - def __arrow_x(self, chipnum): - coords = self.__canvas.coords(chipnum+1) - assert coords - x0, y0, x1, y1 = coords - return (x1 + x0) / 2.0 - - # Invoked when one of the chips is clicked. This should just tell the - # switchboard to set the color on all the output components - def __select_chip(self, event=None): - x = event.x - y = event.y - canvas = self.__canvas - chip = canvas.find_overlapping(x, y, x, y) - if chip and (1 <= chip[0] <= self.__numchips): - color = self.__chips[chip[0]-1] - red, green, blue = ColorDB.rrggbb_to_triplet(color) - etype = int(event.type) - if (etype == BTNUP or self.__uwd.get()): - # update everyone - self.__sb.update_views(red, green, blue) - else: - # just track the arrows - self.__trackarrow(chip[0], (red, green, blue)) - - def __trackarrow(self, chip, rgbtuple): - # invert the last chip - if self.__lastchip is not None: - color = self.__canvas.itemcget(self.__lastchip, 'fill') - self.__canvas.itemconfigure(self.__lastchip, outline=color) - self.__lastchip = chip - # get the arrow's text - coloraxis = rgbtuple[self.__axis] - if self.__hexp.get(): - # hex - text = hex(coloraxis) - else: - # decimal - text = repr(coloraxis) - # move the arrow, and set its text - if coloraxis <= 128: - # use the left arrow - self.__leftarrow.set_text(text) - self.__leftarrow.move_to(self.__arrow_x(chip-1)) - self.__rightarrow.move_to(-100) - else: - # use the right arrow - self.__rightarrow.set_text(text) - self.__rightarrow.move_to(self.__arrow_x(chip-1)) - self.__leftarrow.move_to(-100) - # and set the chip's outline - brightness = ColorDB.triplet_to_brightness(rgbtuple) - if brightness <= 128: - outline = 'white' - else: - outline = 'black' - self.__canvas.itemconfigure(chip, outline=outline) - - - def update_yourself(self, red, green, blue): - assert self.__generator - i = 1 - chip = 0 - chips = self.__chips = [] - tk = self.__canvas.tk - # get the red, green, and blue components for all chips - for t in self.__generator(self.__numchips, red, green, blue): - rrggbb = ColorDB.triplet_to_rrggbb(t) - chips.append(rrggbb) - tred, tgreen, tblue = t - if tred <= red and tgreen <= green and tblue <= blue: - chip = i - i = i + 1 - # call the raw tcl script - colors = SPACE.join(chips) - tk.eval('setcolor %s {%s}' % (self.__canvas._w, colors)) - # move the arrows around - self.__trackarrow(chip, (red, green, blue)) - - def set(self, label, generator): - self.__canvas.itemconfigure(self.__label, text=label) - self.__generator = generator - - -class StripViewer: - def __init__(self, switchboard, master=None): - self.__sb = switchboard - optiondb = switchboard.optiondb() - # create a frame inside the master. - frame = Frame(master, relief=RAISED, borderwidth=1) - frame.grid(row=1, column=0, columnspan=2, sticky='NSEW') - # create the options to be used later - uwd = self.__uwdvar = BooleanVar() - uwd.set(optiondb.get('UPWHILEDRAG', 0)) - hexp = self.__hexpvar = BooleanVar() - hexp.set(optiondb.get('HEXSTRIP', 0)) - # create the red, green, blue strips inside their own frame - frame1 = Frame(frame) - frame1.pack(expand=YES, fill=BOTH) - self.__reds = StripWidget(switchboard, frame1, - generator=constant_cyan_generator, - axis=0, - label='Red Variations', - uwdvar=uwd, hexvar=hexp) - - self.__greens = StripWidget(switchboard, frame1, - generator=constant_magenta_generator, - axis=1, - label='Green Variations', - uwdvar=uwd, hexvar=hexp) - - self.__blues = StripWidget(switchboard, frame1, - generator=constant_yellow_generator, - axis=2, - label='Blue Variations', - uwdvar=uwd, hexvar=hexp) - - # create a frame to contain the controls - frame2 = Frame(frame) - frame2.pack(expand=YES, fill=BOTH) - frame2.columnconfigure(0, weight=20) - frame2.columnconfigure(2, weight=20) - - padx = 8 - - # create the black button - blackbtn = Button(frame2, - text='Black', - command=self.__toblack) - blackbtn.grid(row=0, column=0, rowspan=2, sticky=W, padx=padx) - - # create the controls - uwdbtn = Checkbutton(frame2, - text='Update while dragging', - variable=uwd) - uwdbtn.grid(row=0, column=1, sticky=W) - hexbtn = Checkbutton(frame2, - text='Hexadecimal', - variable=hexp, - command=self.__togglehex) - hexbtn.grid(row=1, column=1, sticky=W) - - # create the white button - whitebtn = Button(frame2, - text='White', - command=self.__towhite) - whitebtn.grid(row=0, column=2, rowspan=2, sticky=E, padx=padx) - - def update_yourself(self, red, green, blue): - self.__reds.update_yourself(red, green, blue) - self.__greens.update_yourself(red, green, blue) - self.__blues.update_yourself(red, green, blue) - - def __togglehex(self, event=None): - red, green, blue = self.__sb.current_rgb() - self.update_yourself(red, green, blue) - - def __toblack(self, event=None): - self.__sb.update_views(0, 0, 0) - - def __towhite(self, event=None): - self.__sb.update_views(255, 255, 255) - - def save_options(self, optiondb): - optiondb['UPWHILEDRAG'] = self.__uwdvar.get() - optiondb['HEXSTRIP'] = self.__hexpvar.get() diff --git a/Tools/pynche/Switchboard.py b/Tools/pynche/Switchboard.py deleted file mode 100644 index 013bb013891..00000000000 --- a/Tools/pynche/Switchboard.py +++ /dev/null @@ -1,138 +0,0 @@ -"""Switchboard class. - -This class is used to coordinate updates among all Viewers. Every Viewer must -conform to the following interface: - - - it must include a method called update_yourself() which takes three - arguments; the red, green, and blue values of the selected color. - - - When a Viewer selects a color and wishes to update all other Views, it - should call update_views() on the Switchboard object. Note that the - Viewer typically does *not* update itself before calling update_views(), - since this would cause it to get updated twice. - -Optionally, Viewers can also implement: - - - save_options() which takes an optiondb (a dictionary). Store into this - dictionary any values the Viewer wants to save in the persistent - ~/.pynche file. This dictionary is saved using marshal. The namespace - for the keys is ad-hoc; make sure you don't clobber some other Viewer's - keys! - - - withdraw() which takes no arguments. This is called when Pynche is - unmapped. All Viewers should implement this. - - - colordb_changed() which takes a single argument, an instance of - ColorDB. This is called whenever the color name database is changed and - gives a chance for the Viewers to do something on those events. See - ListViewer for details. - -External Viewers are found dynamically. Viewer modules should have names such -as FooViewer.py. If such a named module has a module global variable called -ADDTOVIEW and this variable is true, the Viewer will be added dynamically to -the `View' menu. ADDTOVIEW contains a string which is used as the menu item -to display the Viewer (one kludge: if the string contains a `%', this is used -to indicate that the next character will get an underline in the menu, -otherwise the first character is underlined). - -FooViewer.py should contain a class called FooViewer, and its constructor -should take two arguments, an instance of Switchboard, and optionally a Tk -master window. - -""" - -import sys -import marshal - - - -class Switchboard: - def __init__(self, initfile): - self.__initfile = initfile - self.__colordb = None - self.__optiondb = {} - self.__views = [] - self.__red = 0 - self.__green = 0 - self.__blue = 0 - self.__canceled = 0 - # read the initialization file - fp = None - if initfile: - try: - try: - fp = open(initfile, 'rb') - self.__optiondb = marshal.load(fp) - if not isinstance(self.__optiondb, dict): - print('Problem reading options from file:', initfile, - file=sys.stderr) - self.__optiondb = {} - except (IOError, EOFError, ValueError): - pass - finally: - if fp: - fp.close() - - def add_view(self, view): - self.__views.append(view) - - def update_views(self, red, green, blue): - self.__red = red - self.__green = green - self.__blue = blue - for v in self.__views: - v.update_yourself(red, green, blue) - - def update_views_current(self): - self.update_views(self.__red, self.__green, self.__blue) - - def current_rgb(self): - return self.__red, self.__green, self.__blue - - def colordb(self): - return self.__colordb - - def set_colordb(self, colordb): - self.__colordb = colordb - for v in self.__views: - if hasattr(v, 'colordb_changed'): - v.colordb_changed(colordb) - self.update_views_current() - - def optiondb(self): - return self.__optiondb - - def save_views(self): - # save the current color - self.__optiondb['RED'] = self.__red - self.__optiondb['GREEN'] = self.__green - self.__optiondb['BLUE'] = self.__blue - for v in self.__views: - if hasattr(v, 'save_options'): - v.save_options(self.__optiondb) - # save the name of the file used for the color database. we'll try to - # load this first. - self.__optiondb['DBFILE'] = self.__colordb.filename() - fp = None - try: - try: - fp = open(self.__initfile, 'wb') - except IOError: - print('Cannot write options to file:', \ - self.__initfile, file=sys.stderr) - else: - marshal.dump(self.__optiondb, fp) - finally: - if fp: - fp.close() - - def withdraw_views(self): - for v in self.__views: - if hasattr(v, 'withdraw'): - v.withdraw() - - def canceled(self, flag=1): - self.__canceled = flag - - def canceled_p(self): - return self.__canceled diff --git a/Tools/pynche/TextViewer.py b/Tools/pynche/TextViewer.py deleted file mode 100644 index baa1e62ca76..00000000000 --- a/Tools/pynche/TextViewer.py +++ /dev/null @@ -1,188 +0,0 @@ -"""TextViewer class. - -The TextViewer allows you to see how the selected color would affect various -characteristics of a Tk text widget. This is an output viewer only. - -In the top part of the window is a standard text widget with some sample text -in it. You are free to edit this text in any way you want (BAW: allow you to -change font characteristics). If you want changes in other viewers to update -text characteristics, turn on Track color changes. - -To select which characteristic tracks the change, select one of the radio -buttons in the window below. Text foreground and background affect the text -in the window above. The Selection is what you see when you click the middle -button and drag it through some text. The Insertion is the insertion cursor -in the text window (which only has a background). -""" - -from tkinter import * -import ColorDB - -ADDTOVIEW = 'Text Window...' - - - -class TextViewer: - def __init__(self, switchboard, master=None): - self.__sb = switchboard - optiondb = switchboard.optiondb() - root = self.__root = Toplevel(master, class_='Pynche') - root.protocol('WM_DELETE_WINDOW', self.withdraw) - root.title('Pynche Text Window') - root.iconname('Pynche Text Window') - root.bind('', self.__quit) - root.bind('', self.__quit) - root.bind('', self.withdraw) - root.bind('', self.withdraw) - # - # create the text widget - # - self.__text = Text(root, relief=SUNKEN, - background=optiondb.get('TEXTBG', 'black'), - foreground=optiondb.get('TEXTFG', 'white'), - width=35, height=15) - sfg = optiondb.get('TEXT_SFG') - if sfg: - self.__text.configure(selectforeground=sfg) - sbg = optiondb.get('TEXT_SBG') - if sbg: - self.__text.configure(selectbackground=sbg) - ibg = optiondb.get('TEXT_IBG') - if ibg: - self.__text.configure(insertbackground=ibg) - self.__text.pack() - self.__text.insert(0.0, optiondb.get('TEXT', '''\ -Insert some stuff here and play -with the buttons below to see -how the colors interact in -textual displays. - -See how the selection can also -be affected by tickling the buttons -and choosing a color.''')) - insert = optiondb.get('TEXTINS') - if insert: - self.__text.mark_set(INSERT, insert) - try: - start, end = optiondb.get('TEXTSEL', (6.0, END)) - self.__text.tag_add(SEL, start, end) - except ValueError: - # selection wasn't set - pass - self.__text.focus_set() - # - # variables - self.__trackp = BooleanVar() - self.__trackp.set(optiondb.get('TRACKP', 0)) - self.__which = IntVar() - self.__which.set(optiondb.get('WHICH', 0)) - # - # track toggle - self.__t = Checkbutton(root, text='Track color changes', - variable=self.__trackp, - relief=GROOVE, - command=self.__toggletrack) - self.__t.pack(fill=X, expand=YES) - frame = self.__frame = Frame(root) - frame.pack() - # - # labels - self.__labels = [] - row = 2 - for text in ('Text:', 'Selection:', 'Insertion:'): - l = Label(frame, text=text) - l.grid(row=row, column=0, sticky=E) - self.__labels.append(l) - row += 1 - col = 1 - for text in ('Foreground', 'Background'): - l = Label(frame, text=text) - l.grid(row=1, column=col) - self.__labels.append(l) - col += 1 - # - # radios - self.__radios = [] - for col in (1, 2): - for row in (2, 3, 4): - # there is no insertforeground option - if row==4 and col==1: - continue - r = Radiobutton(frame, variable=self.__which, - value=(row-2)*2 + col-1, - command=self.__set_color) - r.grid(row=row, column=col) - self.__radios.append(r) - self.__toggletrack() - - def __quit(self, event=None): - self.__root.quit() - - def withdraw(self, event=None): - self.__root.withdraw() - - def deiconify(self, event=None): - self.__root.deiconify() - - def __forceupdate(self, event=None): - self.__sb.update_views_current() - - def __toggletrack(self, event=None): - if self.__trackp.get(): - state = NORMAL - fg = self.__radios[0]['foreground'] - else: - state = DISABLED - fg = self.__radios[0]['disabledforeground'] - for r in self.__radios: - r.configure(state=state) - for l in self.__labels: - l.configure(foreground=fg) - - def __set_color(self, event=None): - which = self.__which.get() - text = self.__text - if which == 0: - color = text['foreground'] - elif which == 1: - color = text['background'] - elif which == 2: - color = text['selectforeground'] - elif which == 3: - color = text['selectbackground'] - elif which == 5: - color = text['insertbackground'] - try: - red, green, blue = ColorDB.rrggbb_to_triplet(color) - except ColorDB.BadColor: - # must have been a color name - red, green, blue = self.__sb.colordb().find_byname(color) - self.__sb.update_views(red, green, blue) - - def update_yourself(self, red, green, blue): - if self.__trackp.get(): - colorname = ColorDB.triplet_to_rrggbb((red, green, blue)) - which = self.__which.get() - text = self.__text - if which == 0: - text.configure(foreground=colorname) - elif which == 1: - text.configure(background=colorname) - elif which == 2: - text.configure(selectforeground=colorname) - elif which == 3: - text.configure(selectbackground=colorname) - elif which == 5: - text.configure(insertbackground=colorname) - - def save_options(self, optiondb): - optiondb['TRACKP'] = self.__trackp.get() - optiondb['WHICH'] = self.__which.get() - optiondb['TEXT'] = self.__text.get(0.0, 'end - 1c') - optiondb['TEXTSEL'] = self.__text.tag_ranges(SEL)[0:2] - optiondb['TEXTINS'] = self.__text.index(INSERT) - optiondb['TEXTFG'] = self.__text['foreground'] - optiondb['TEXTBG'] = self.__text['background'] - optiondb['TEXT_SFG'] = self.__text['selectforeground'] - optiondb['TEXT_SBG'] = self.__text['selectbackground'] - optiondb['TEXT_IBG'] = self.__text['insertbackground'] diff --git a/Tools/pynche/TypeinViewer.py b/Tools/pynche/TypeinViewer.py deleted file mode 100644 index 2f93e6b44f4..00000000000 --- a/Tools/pynche/TypeinViewer.py +++ /dev/null @@ -1,161 +0,0 @@ -"""TypeinViewer class. - -The TypeinViewer is what you see at the lower right of the main Pynche -widget. It contains three text entry fields, one each for red, green, blue. -Input into these windows is highly constrained; it only allows you to enter -values that are legal for a color axis. This usually means 0-255 for decimal -input and 0x0 - 0xff for hex input. - -You can toggle whether you want to view and input the values in either decimal -or hex by clicking on Hexadecimal. By clicking on Update while typing, the -color selection will be made on every change to the text field. Otherwise, -you must hit Return or Tab to select the color. -""" - -from tkinter import * - - - -class TypeinViewer: - def __init__(self, switchboard, master=None): - # non-gui ivars - self.__sb = switchboard - optiondb = switchboard.optiondb() - self.__hexp = BooleanVar() - self.__hexp.set(optiondb.get('HEXTYPE', 0)) - self.__uwtyping = BooleanVar() - self.__uwtyping.set(optiondb.get('UPWHILETYPE', 0)) - # create the gui - self.__frame = Frame(master, relief=RAISED, borderwidth=1) - self.__frame.grid(row=3, column=1, sticky='NSEW') - # Red - self.__xl = Label(self.__frame, text='Red:') - self.__xl.grid(row=0, column=0, sticky=E) - subframe = Frame(self.__frame) - subframe.grid(row=0, column=1) - self.__xox = Label(subframe, text='0x') - self.__xox.grid(row=0, column=0, sticky=E) - self.__xox['font'] = 'courier' - self.__x = Entry(subframe, width=3) - self.__x.grid(row=0, column=1) - self.__x.bindtags(self.__x.bindtags() + ('Normalize', 'Update')) - self.__x.bind_class('Normalize', '', self.__normalize) - self.__x.bind_class('Update' , '', self.__maybeupdate) - # Green - self.__yl = Label(self.__frame, text='Green:') - self.__yl.grid(row=1, column=0, sticky=E) - subframe = Frame(self.__frame) - subframe.grid(row=1, column=1) - self.__yox = Label(subframe, text='0x') - self.__yox.grid(row=0, column=0, sticky=E) - self.__yox['font'] = 'courier' - self.__y = Entry(subframe, width=3) - self.__y.grid(row=0, column=1) - self.__y.bindtags(self.__y.bindtags() + ('Normalize', 'Update')) - # Blue - self.__zl = Label(self.__frame, text='Blue:') - self.__zl.grid(row=2, column=0, sticky=E) - subframe = Frame(self.__frame) - subframe.grid(row=2, column=1) - self.__zox = Label(subframe, text='0x') - self.__zox.grid(row=0, column=0, sticky=E) - self.__zox['font'] = 'courier' - self.__z = Entry(subframe, width=3) - self.__z.grid(row=0, column=1) - self.__z.bindtags(self.__z.bindtags() + ('Normalize', 'Update')) - # Update while typing? - self.__uwt = Checkbutton(self.__frame, - text='Update while typing', - variable=self.__uwtyping) - self.__uwt.grid(row=3, column=0, columnspan=2, sticky=W) - # Hex/Dec - self.__hex = Checkbutton(self.__frame, - text='Hexadecimal', - variable=self.__hexp, - command=self.__togglehex) - self.__hex.grid(row=4, column=0, columnspan=2, sticky=W) - - def __togglehex(self, event=None): - red, green, blue = self.__sb.current_rgb() - if self.__hexp.get(): - label = '0x' - else: - label = ' ' - self.__xox['text'] = label - self.__yox['text'] = label - self.__zox['text'] = label - self.update_yourself(red, green, blue) - - def __normalize(self, event=None): - ew = event.widget - contents = ew.get() - icursor = ew.index(INSERT) - if contents and contents[0] in 'xX' and self.__hexp.get(): - contents = '0' + contents - # Figure out the contents in the current base. - try: - if self.__hexp.get(): - v = int(contents, 16) - else: - v = int(contents) - except ValueError: - v = None - # If value is not legal, or empty, delete the last character inserted - # and ring the bell. Don't ring the bell if the field is empty (it'll - # just equal zero. - if v is None: - pass - elif v < 0 or v > 255: - i = ew.index(INSERT) - if event.char: - contents = contents[:i-1] + contents[i:] - icursor -= 1 - ew.bell() - elif self.__hexp.get(): - contents = hex(v)[2:] - else: - contents = int(v) - ew.delete(0, END) - ew.insert(0, contents) - ew.icursor(icursor) - - def __maybeupdate(self, event=None): - if self.__uwtyping.get() or event.keysym in ('Return', 'Tab'): - self.__update(event) - - def __update(self, event=None): - redstr = self.__x.get() or '0' - greenstr = self.__y.get() or '0' - bluestr = self.__z.get() or '0' - if self.__hexp.get(): - base = 16 - else: - base = 10 - red, green, blue = [int(x, base) for x in (redstr, greenstr, bluestr)] - self.__sb.update_views(red, green, blue) - - def update_yourself(self, red, green, blue): - if self.__hexp.get(): - sred, sgreen, sblue = [hex(x)[2:] for x in (red, green, blue)] - else: - sred, sgreen, sblue = red, green, blue - x, y, z = self.__x, self.__y, self.__z - xicursor = x.index(INSERT) - yicursor = y.index(INSERT) - zicursor = z.index(INSERT) - x.delete(0, END) - y.delete(0, END) - z.delete(0, END) - x.insert(0, sred) - y.insert(0, sgreen) - z.insert(0, sblue) - x.icursor(xicursor) - y.icursor(yicursor) - z.icursor(zicursor) - - def hexp_var(self): - return self.__hexp - - def save_options(self, optiondb): - optiondb['HEXTYPE'] = self.__hexp.get() - optiondb['UPWHILETYPE'] = self.__uwtyping.get() diff --git a/Tools/pynche/X/rgb.txt b/Tools/pynche/X/rgb.txt deleted file mode 100644 index b11ffd058cb..00000000000 --- a/Tools/pynche/X/rgb.txt +++ /dev/null @@ -1,753 +0,0 @@ -! $XConsortium: rgb.txt,v 10.41 94/02/20 18:39:36 rws Exp $ -255 250 250 snow -248 248 255 ghost white -248 248 255 GhostWhite -245 245 245 white smoke -245 245 245 WhiteSmoke -220 220 220 gainsboro -255 250 240 floral white -255 250 240 FloralWhite -253 245 230 old lace -253 245 230 OldLace -250 240 230 linen -250 235 215 antique white -250 235 215 AntiqueWhite -255 239 213 papaya whip -255 239 213 PapayaWhip -255 235 205 blanched almond -255 235 205 BlanchedAlmond -255 228 196 bisque -255 218 185 peach puff -255 218 185 PeachPuff -255 222 173 navajo white -255 222 173 NavajoWhite -255 228 181 moccasin -255 248 220 cornsilk -255 255 240 ivory -255 250 205 lemon chiffon -255 250 205 LemonChiffon -255 245 238 seashell -240 255 240 honeydew -245 255 250 mint cream -245 255 250 MintCream -240 255 255 azure -240 248 255 alice blue -240 248 255 AliceBlue -230 230 250 lavender -255 240 245 lavender blush -255 240 245 LavenderBlush -255 228 225 misty rose -255 228 225 MistyRose -255 255 255 white - 0 0 0 black - 47 79 79 dark slate gray - 47 79 79 DarkSlateGray - 47 79 79 dark slate grey - 47 79 79 DarkSlateGrey -105 105 105 dim gray -105 105 105 DimGray -105 105 105 dim grey -105 105 105 DimGrey -112 128 144 slate gray -112 128 144 SlateGray -112 128 144 slate grey -112 128 144 SlateGrey -119 136 153 light slate gray -119 136 153 LightSlateGray -119 136 153 light slate grey -119 136 153 LightSlateGrey -190 190 190 gray -190 190 190 grey -211 211 211 light grey -211 211 211 LightGrey -211 211 211 light gray -211 211 211 LightGray - 25 25 112 midnight blue - 25 25 112 MidnightBlue - 0 0 128 navy - 0 0 128 navy blue - 0 0 128 NavyBlue -100 149 237 cornflower blue -100 149 237 CornflowerBlue - 72 61 139 dark slate blue - 72 61 139 DarkSlateBlue -106 90 205 slate blue -106 90 205 SlateBlue -123 104 238 medium slate blue -123 104 238 MediumSlateBlue -132 112 255 light slate blue -132 112 255 LightSlateBlue - 0 0 205 medium blue - 0 0 205 MediumBlue - 65 105 225 royal blue - 65 105 225 RoyalBlue - 0 0 255 blue - 30 144 255 dodger blue - 30 144 255 DodgerBlue - 0 191 255 deep sky blue - 0 191 255 DeepSkyBlue -135 206 235 sky blue -135 206 235 SkyBlue -135 206 250 light sky blue -135 206 250 LightSkyBlue - 70 130 180 steel blue - 70 130 180 SteelBlue -176 196 222 light steel blue -176 196 222 LightSteelBlue -173 216 230 light blue -173 216 230 LightBlue -176 224 230 powder blue -176 224 230 PowderBlue -175 238 238 pale turquoise -175 238 238 PaleTurquoise - 0 206 209 dark turquoise - 0 206 209 DarkTurquoise - 72 209 204 medium turquoise - 72 209 204 MediumTurquoise - 64 224 208 turquoise - 0 255 255 cyan -224 255 255 light cyan -224 255 255 LightCyan - 95 158 160 cadet blue - 95 158 160 CadetBlue -102 205 170 medium aquamarine -102 205 170 MediumAquamarine -127 255 212 aquamarine - 0 100 0 dark green - 0 100 0 DarkGreen - 85 107 47 dark olive green - 85 107 47 DarkOliveGreen -143 188 143 dark sea green -143 188 143 DarkSeaGreen - 46 139 87 sea green - 46 139 87 SeaGreen - 60 179 113 medium sea green - 60 179 113 MediumSeaGreen - 32 178 170 light sea green - 32 178 170 LightSeaGreen -152 251 152 pale green -152 251 152 PaleGreen - 0 255 127 spring green - 0 255 127 SpringGreen -124 252 0 lawn green -124 252 0 LawnGreen - 0 255 0 green -127 255 0 chartreuse - 0 250 154 medium spring green - 0 250 154 MediumSpringGreen -173 255 47 green yellow -173 255 47 GreenYellow - 50 205 50 lime green - 50 205 50 LimeGreen -154 205 50 yellow green -154 205 50 YellowGreen - 34 139 34 forest green - 34 139 34 ForestGreen -107 142 35 olive drab -107 142 35 OliveDrab -189 183 107 dark khaki -189 183 107 DarkKhaki -240 230 140 khaki -238 232 170 pale goldenrod -238 232 170 PaleGoldenrod -250 250 210 light goldenrod yellow -250 250 210 LightGoldenrodYellow -255 255 224 light yellow -255 255 224 LightYellow -255 255 0 yellow -255 215 0 gold -238 221 130 light goldenrod -238 221 130 LightGoldenrod -218 165 32 goldenrod -184 134 11 dark goldenrod -184 134 11 DarkGoldenrod -188 143 143 rosy brown -188 143 143 RosyBrown -205 92 92 indian red -205 92 92 IndianRed -139 69 19 saddle brown -139 69 19 SaddleBrown -160 82 45 sienna -205 133 63 peru -222 184 135 burlywood -245 245 220 beige -245 222 179 wheat -244 164 96 sandy brown -244 164 96 SandyBrown -210 180 140 tan -210 105 30 chocolate -178 34 34 firebrick -165 42 42 brown -233 150 122 dark salmon -233 150 122 DarkSalmon -250 128 114 salmon -255 160 122 light salmon -255 160 122 LightSalmon -255 165 0 orange -255 140 0 dark orange -255 140 0 DarkOrange -255 127 80 coral -240 128 128 light coral -240 128 128 LightCoral -255 99 71 tomato -255 69 0 orange red -255 69 0 OrangeRed -255 0 0 red -255 105 180 hot pink -255 105 180 HotPink -255 20 147 deep pink -255 20 147 DeepPink -255 192 203 pink -255 182 193 light pink -255 182 193 LightPink -219 112 147 pale violet red -219 112 147 PaleVioletRed -176 48 96 maroon -199 21 133 medium violet red -199 21 133 MediumVioletRed -208 32 144 violet red -208 32 144 VioletRed -255 0 255 magenta -238 130 238 violet -221 160 221 plum -218 112 214 orchid -186 85 211 medium orchid -186 85 211 MediumOrchid -153 50 204 dark orchid -153 50 204 DarkOrchid -148 0 211 dark violet -148 0 211 DarkViolet -138 43 226 blue violet -138 43 226 BlueViolet -160 32 240 purple -147 112 219 medium purple -147 112 219 MediumPurple -216 191 216 thistle -255 250 250 snow1 -238 233 233 snow2 -205 201 201 snow3 -139 137 137 snow4 -255 245 238 seashell1 -238 229 222 seashell2 -205 197 191 seashell3 -139 134 130 seashell4 -255 239 219 AntiqueWhite1 -238 223 204 AntiqueWhite2 -205 192 176 AntiqueWhite3 -139 131 120 AntiqueWhite4 -255 228 196 bisque1 -238 213 183 bisque2 -205 183 158 bisque3 -139 125 107 bisque4 -255 218 185 PeachPuff1 -238 203 173 PeachPuff2 -205 175 149 PeachPuff3 -139 119 101 PeachPuff4 -255 222 173 NavajoWhite1 -238 207 161 NavajoWhite2 -205 179 139 NavajoWhite3 -139 121 94 NavajoWhite4 -255 250 205 LemonChiffon1 -238 233 191 LemonChiffon2 -205 201 165 LemonChiffon3 -139 137 112 LemonChiffon4 -255 248 220 cornsilk1 -238 232 205 cornsilk2 -205 200 177 cornsilk3 -139 136 120 cornsilk4 -255 255 240 ivory1 -238 238 224 ivory2 -205 205 193 ivory3 -139 139 131 ivory4 -240 255 240 honeydew1 -224 238 224 honeydew2 -193 205 193 honeydew3 -131 139 131 honeydew4 -255 240 245 LavenderBlush1 -238 224 229 LavenderBlush2 -205 193 197 LavenderBlush3 -139 131 134 LavenderBlush4 -255 228 225 MistyRose1 -238 213 210 MistyRose2 -205 183 181 MistyRose3 -139 125 123 MistyRose4 -240 255 255 azure1 -224 238 238 azure2 -193 205 205 azure3 -131 139 139 azure4 -131 111 255 SlateBlue1 -122 103 238 SlateBlue2 -105 89 205 SlateBlue3 - 71 60 139 SlateBlue4 - 72 118 255 RoyalBlue1 - 67 110 238 RoyalBlue2 - 58 95 205 RoyalBlue3 - 39 64 139 RoyalBlue4 - 0 0 255 blue1 - 0 0 238 blue2 - 0 0 205 blue3 - 0 0 139 blue4 - 30 144 255 DodgerBlue1 - 28 134 238 DodgerBlue2 - 24 116 205 DodgerBlue3 - 16 78 139 DodgerBlue4 - 99 184 255 SteelBlue1 - 92 172 238 SteelBlue2 - 79 148 205 SteelBlue3 - 54 100 139 SteelBlue4 - 0 191 255 DeepSkyBlue1 - 0 178 238 DeepSkyBlue2 - 0 154 205 DeepSkyBlue3 - 0 104 139 DeepSkyBlue4 -135 206 255 SkyBlue1 -126 192 238 SkyBlue2 -108 166 205 SkyBlue3 - 74 112 139 SkyBlue4 -176 226 255 LightSkyBlue1 -164 211 238 LightSkyBlue2 -141 182 205 LightSkyBlue3 - 96 123 139 LightSkyBlue4 -198 226 255 SlateGray1 -185 211 238 SlateGray2 -159 182 205 SlateGray3 -108 123 139 SlateGray4 -202 225 255 LightSteelBlue1 -188 210 238 LightSteelBlue2 -162 181 205 LightSteelBlue3 -110 123 139 LightSteelBlue4 -191 239 255 LightBlue1 -178 223 238 LightBlue2 -154 192 205 LightBlue3 -104 131 139 LightBlue4 -224 255 255 LightCyan1 -209 238 238 LightCyan2 -180 205 205 LightCyan3 -122 139 139 LightCyan4 -187 255 255 PaleTurquoise1 -174 238 238 PaleTurquoise2 -150 205 205 PaleTurquoise3 -102 139 139 PaleTurquoise4 -152 245 255 CadetBlue1 -142 229 238 CadetBlue2 -122 197 205 CadetBlue3 - 83 134 139 CadetBlue4 - 0 245 255 turquoise1 - 0 229 238 turquoise2 - 0 197 205 turquoise3 - 0 134 139 turquoise4 - 0 255 255 cyan1 - 0 238 238 cyan2 - 0 205 205 cyan3 - 0 139 139 cyan4 -151 255 255 DarkSlateGray1 -141 238 238 DarkSlateGray2 -121 205 205 DarkSlateGray3 - 82 139 139 DarkSlateGray4 -127 255 212 aquamarine1 -118 238 198 aquamarine2 -102 205 170 aquamarine3 - 69 139 116 aquamarine4 -193 255 193 DarkSeaGreen1 -180 238 180 DarkSeaGreen2 -155 205 155 DarkSeaGreen3 -105 139 105 DarkSeaGreen4 - 84 255 159 SeaGreen1 - 78 238 148 SeaGreen2 - 67 205 128 SeaGreen3 - 46 139 87 SeaGreen4 -154 255 154 PaleGreen1 -144 238 144 PaleGreen2 -124 205 124 PaleGreen3 - 84 139 84 PaleGreen4 - 0 255 127 SpringGreen1 - 0 238 118 SpringGreen2 - 0 205 102 SpringGreen3 - 0 139 69 SpringGreen4 - 0 255 0 green1 - 0 238 0 green2 - 0 205 0 green3 - 0 139 0 green4 -127 255 0 chartreuse1 -118 238 0 chartreuse2 -102 205 0 chartreuse3 - 69 139 0 chartreuse4 -192 255 62 OliveDrab1 -179 238 58 OliveDrab2 -154 205 50 OliveDrab3 -105 139 34 OliveDrab4 -202 255 112 DarkOliveGreen1 -188 238 104 DarkOliveGreen2 -162 205 90 DarkOliveGreen3 -110 139 61 DarkOliveGreen4 -255 246 143 khaki1 -238 230 133 khaki2 -205 198 115 khaki3 -139 134 78 khaki4 -255 236 139 LightGoldenrod1 -238 220 130 LightGoldenrod2 -205 190 112 LightGoldenrod3 -139 129 76 LightGoldenrod4 -255 255 224 LightYellow1 -238 238 209 LightYellow2 -205 205 180 LightYellow3 -139 139 122 LightYellow4 -255 255 0 yellow1 -238 238 0 yellow2 -205 205 0 yellow3 -139 139 0 yellow4 -255 215 0 gold1 -238 201 0 gold2 -205 173 0 gold3 -139 117 0 gold4 -255 193 37 goldenrod1 -238 180 34 goldenrod2 -205 155 29 goldenrod3 -139 105 20 goldenrod4 -255 185 15 DarkGoldenrod1 -238 173 14 DarkGoldenrod2 -205 149 12 DarkGoldenrod3 -139 101 8 DarkGoldenrod4 -255 193 193 RosyBrown1 -238 180 180 RosyBrown2 -205 155 155 RosyBrown3 -139 105 105 RosyBrown4 -255 106 106 IndianRed1 -238 99 99 IndianRed2 -205 85 85 IndianRed3 -139 58 58 IndianRed4 -255 130 71 sienna1 -238 121 66 sienna2 -205 104 57 sienna3 -139 71 38 sienna4 -255 211 155 burlywood1 -238 197 145 burlywood2 -205 170 125 burlywood3 -139 115 85 burlywood4 -255 231 186 wheat1 -238 216 174 wheat2 -205 186 150 wheat3 -139 126 102 wheat4 -255 165 79 tan1 -238 154 73 tan2 -205 133 63 tan3 -139 90 43 tan4 -255 127 36 chocolate1 -238 118 33 chocolate2 -205 102 29 chocolate3 -139 69 19 chocolate4 -255 48 48 firebrick1 -238 44 44 firebrick2 -205 38 38 firebrick3 -139 26 26 firebrick4 -255 64 64 brown1 -238 59 59 brown2 -205 51 51 brown3 -139 35 35 brown4 -255 140 105 salmon1 -238 130 98 salmon2 -205 112 84 salmon3 -139 76 57 salmon4 -255 160 122 LightSalmon1 -238 149 114 LightSalmon2 -205 129 98 LightSalmon3 -139 87 66 LightSalmon4 -255 165 0 orange1 -238 154 0 orange2 -205 133 0 orange3 -139 90 0 orange4 -255 127 0 DarkOrange1 -238 118 0 DarkOrange2 -205 102 0 DarkOrange3 -139 69 0 DarkOrange4 -255 114 86 coral1 -238 106 80 coral2 -205 91 69 coral3 -139 62 47 coral4 -255 99 71 tomato1 -238 92 66 tomato2 -205 79 57 tomato3 -139 54 38 tomato4 -255 69 0 OrangeRed1 -238 64 0 OrangeRed2 -205 55 0 OrangeRed3 -139 37 0 OrangeRed4 -255 0 0 red1 -238 0 0 red2 -205 0 0 red3 -139 0 0 red4 -255 20 147 DeepPink1 -238 18 137 DeepPink2 -205 16 118 DeepPink3 -139 10 80 DeepPink4 -255 110 180 HotPink1 -238 106 167 HotPink2 -205 96 144 HotPink3 -139 58 98 HotPink4 -255 181 197 pink1 -238 169 184 pink2 -205 145 158 pink3 -139 99 108 pink4 -255 174 185 LightPink1 -238 162 173 LightPink2 -205 140 149 LightPink3 -139 95 101 LightPink4 -255 130 171 PaleVioletRed1 -238 121 159 PaleVioletRed2 -205 104 137 PaleVioletRed3 -139 71 93 PaleVioletRed4 -255 52 179 maroon1 -238 48 167 maroon2 -205 41 144 maroon3 -139 28 98 maroon4 -255 62 150 VioletRed1 -238 58 140 VioletRed2 -205 50 120 VioletRed3 -139 34 82 VioletRed4 -255 0 255 magenta1 -238 0 238 magenta2 -205 0 205 magenta3 -139 0 139 magenta4 -255 131 250 orchid1 -238 122 233 orchid2 -205 105 201 orchid3 -139 71 137 orchid4 -255 187 255 plum1 -238 174 238 plum2 -205 150 205 plum3 -139 102 139 plum4 -224 102 255 MediumOrchid1 -209 95 238 MediumOrchid2 -180 82 205 MediumOrchid3 -122 55 139 MediumOrchid4 -191 62 255 DarkOrchid1 -178 58 238 DarkOrchid2 -154 50 205 DarkOrchid3 -104 34 139 DarkOrchid4 -155 48 255 purple1 -145 44 238 purple2 -125 38 205 purple3 - 85 26 139 purple4 -171 130 255 MediumPurple1 -159 121 238 MediumPurple2 -137 104 205 MediumPurple3 - 93 71 139 MediumPurple4 -255 225 255 thistle1 -238 210 238 thistle2 -205 181 205 thistle3 -139 123 139 thistle4 - 0 0 0 gray0 - 0 0 0 grey0 - 3 3 3 gray1 - 3 3 3 grey1 - 5 5 5 gray2 - 5 5 5 grey2 - 8 8 8 gray3 - 8 8 8 grey3 - 10 10 10 gray4 - 10 10 10 grey4 - 13 13 13 gray5 - 13 13 13 grey5 - 15 15 15 gray6 - 15 15 15 grey6 - 18 18 18 gray7 - 18 18 18 grey7 - 20 20 20 gray8 - 20 20 20 grey8 - 23 23 23 gray9 - 23 23 23 grey9 - 26 26 26 gray10 - 26 26 26 grey10 - 28 28 28 gray11 - 28 28 28 grey11 - 31 31 31 gray12 - 31 31 31 grey12 - 33 33 33 gray13 - 33 33 33 grey13 - 36 36 36 gray14 - 36 36 36 grey14 - 38 38 38 gray15 - 38 38 38 grey15 - 41 41 41 gray16 - 41 41 41 grey16 - 43 43 43 gray17 - 43 43 43 grey17 - 46 46 46 gray18 - 46 46 46 grey18 - 48 48 48 gray19 - 48 48 48 grey19 - 51 51 51 gray20 - 51 51 51 grey20 - 54 54 54 gray21 - 54 54 54 grey21 - 56 56 56 gray22 - 56 56 56 grey22 - 59 59 59 gray23 - 59 59 59 grey23 - 61 61 61 gray24 - 61 61 61 grey24 - 64 64 64 gray25 - 64 64 64 grey25 - 66 66 66 gray26 - 66 66 66 grey26 - 69 69 69 gray27 - 69 69 69 grey27 - 71 71 71 gray28 - 71 71 71 grey28 - 74 74 74 gray29 - 74 74 74 grey29 - 77 77 77 gray30 - 77 77 77 grey30 - 79 79 79 gray31 - 79 79 79 grey31 - 82 82 82 gray32 - 82 82 82 grey32 - 84 84 84 gray33 - 84 84 84 grey33 - 87 87 87 gray34 - 87 87 87 grey34 - 89 89 89 gray35 - 89 89 89 grey35 - 92 92 92 gray36 - 92 92 92 grey36 - 94 94 94 gray37 - 94 94 94 grey37 - 97 97 97 gray38 - 97 97 97 grey38 - 99 99 99 gray39 - 99 99 99 grey39 -102 102 102 gray40 -102 102 102 grey40 -105 105 105 gray41 -105 105 105 grey41 -107 107 107 gray42 -107 107 107 grey42 -110 110 110 gray43 -110 110 110 grey43 -112 112 112 gray44 -112 112 112 grey44 -115 115 115 gray45 -115 115 115 grey45 -117 117 117 gray46 -117 117 117 grey46 -120 120 120 gray47 -120 120 120 grey47 -122 122 122 gray48 -122 122 122 grey48 -125 125 125 gray49 -125 125 125 grey49 -127 127 127 gray50 -127 127 127 grey50 -130 130 130 gray51 -130 130 130 grey51 -133 133 133 gray52 -133 133 133 grey52 -135 135 135 gray53 -135 135 135 grey53 -138 138 138 gray54 -138 138 138 grey54 -140 140 140 gray55 -140 140 140 grey55 -143 143 143 gray56 -143 143 143 grey56 -145 145 145 gray57 -145 145 145 grey57 -148 148 148 gray58 -148 148 148 grey58 -150 150 150 gray59 -150 150 150 grey59 -153 153 153 gray60 -153 153 153 grey60 -156 156 156 gray61 -156 156 156 grey61 -158 158 158 gray62 -158 158 158 grey62 -161 161 161 gray63 -161 161 161 grey63 -163 163 163 gray64 -163 163 163 grey64 -166 166 166 gray65 -166 166 166 grey65 -168 168 168 gray66 -168 168 168 grey66 -171 171 171 gray67 -171 171 171 grey67 -173 173 173 gray68 -173 173 173 grey68 -176 176 176 gray69 -176 176 176 grey69 -179 179 179 gray70 -179 179 179 grey70 -181 181 181 gray71 -181 181 181 grey71 -184 184 184 gray72 -184 184 184 grey72 -186 186 186 gray73 -186 186 186 grey73 -189 189 189 gray74 -189 189 189 grey74 -191 191 191 gray75 -191 191 191 grey75 -194 194 194 gray76 -194 194 194 grey76 -196 196 196 gray77 -196 196 196 grey77 -199 199 199 gray78 -199 199 199 grey78 -201 201 201 gray79 -201 201 201 grey79 -204 204 204 gray80 -204 204 204 grey80 -207 207 207 gray81 -207 207 207 grey81 -209 209 209 gray82 -209 209 209 grey82 -212 212 212 gray83 -212 212 212 grey83 -214 214 214 gray84 -214 214 214 grey84 -217 217 217 gray85 -217 217 217 grey85 -219 219 219 gray86 -219 219 219 grey86 -222 222 222 gray87 -222 222 222 grey87 -224 224 224 gray88 -224 224 224 grey88 -227 227 227 gray89 -227 227 227 grey89 -229 229 229 gray90 -229 229 229 grey90 -232 232 232 gray91 -232 232 232 grey91 -235 235 235 gray92 -235 235 235 grey92 -237 237 237 gray93 -237 237 237 grey93 -240 240 240 gray94 -240 240 240 grey94 -242 242 242 gray95 -242 242 242 grey95 -245 245 245 gray96 -245 245 245 grey96 -247 247 247 gray97 -247 247 247 grey97 -250 250 250 gray98 -250 250 250 grey98 -252 252 252 gray99 -252 252 252 grey99 -255 255 255 gray100 -255 255 255 grey100 -169 169 169 dark grey -169 169 169 DarkGrey -169 169 169 dark gray -169 169 169 DarkGray -0 0 139 dark blue -0 0 139 DarkBlue -0 139 139 dark cyan -0 139 139 DarkCyan -139 0 139 dark magenta -139 0 139 DarkMagenta -139 0 0 dark red -139 0 0 DarkRed -144 238 144 light green -144 238 144 LightGreen diff --git a/Tools/pynche/X/xlicense.txt b/Tools/pynche/X/xlicense.txt deleted file mode 100644 index b4471db6753..00000000000 --- a/Tools/pynche/X/xlicense.txt +++ /dev/null @@ -1,29 +0,0 @@ -X Window System License - X11R6.4 - -Copyright (c) 1998 The Open Group - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - -X Window System is a trademark of The Open Group diff --git a/Tools/pynche/__init__.py b/Tools/pynche/__init__.py deleted file mode 100644 index b93054b3ecf..00000000000 --- a/Tools/pynche/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# Dummy file to make this directory a package. diff --git a/Tools/pynche/html40colors.txt b/Tools/pynche/html40colors.txt deleted file mode 100644 index 3eeb0a10a89..00000000000 --- a/Tools/pynche/html40colors.txt +++ /dev/null @@ -1,17 +0,0 @@ -# HTML 4.0 color names -Black #000000 -Silver #c0c0c0 -Gray #808080 -White #ffffff -Maroon #800000 -Red #ff0000 -Purple #800080 -Fuchsia #ff00ff -Green #008000 -Lime #00ff00 -Olive #808000 -Yellow #ffff00 -Navy #000080 -Blue #0000ff -Teal #008080 -Aqua #00ffff diff --git a/Tools/pynche/namedcolors.txt b/Tools/pynche/namedcolors.txt deleted file mode 100644 index 3658e85f256..00000000000 --- a/Tools/pynche/namedcolors.txt +++ /dev/null @@ -1,100 +0,0 @@ -# named colors from http://www.lightlink.com/xine/bells/namedcolors.html -White #FFFFFF -Red #FF0000 -Green #00FF00 -Blue #0000FF -Magenta #FF00FF -Cyan #00FFFF -Yellow #FFFF00 -Black #000000 -Aquamarine #70DB93 -Baker's Chocolate #5C3317 -Blue Violet #9F5F9F -Brass #B5A642 -Bright Gold #D9D919 -Brown #A62A2A -Bronze #8C7853 -Bronze II #A67D3D -Cadet Blue #5F9F9F -Cool Copper #D98719 -Copper #B87333 -Coral #FF7F00 -Corn Flower Blue #42426F -Dark Brown #5C4033 -Dark Green #2F4F2F -Dark Green Copper #4A766E -Dark Olive Green #4F4F2F -Dark Orchid #9932CD -Dark Purple #871F78 -Dark Slate Blue #6B238E -Dark Slate Grey #2F4F4F -Dark Tan #97694F -Dark Turquoise #7093DB -Dark Wood #855E42 -Dim Grey #545454 -Dusty Rose #856363 -Feldspar #D19275 -Firebrick #8E2323 -Forest Green #238E23 -Gold #CD7F32 -Goldenrod #DBDB70 -Grey #C0C0C0 -Green Copper #527F76 -Green Yellow #93DB70 -Hunter Green #215E21 -Indian Red #4E2F2F -Khaki #9F9F5F -Light Blue #C0D9D9 -Light Grey #A8A8A8 -Light Steel Blue #8F8FBD -Light Wood #E9C2A6 -Lime Green #32CD32 -Mandarian Orange #E47833 -Maroon #8E236B -Medium Aquamarine #32CD99 -Medium Blue #3232CD -Medium Forest Green #6B8E23 -Medium Goldenrod #EAEAAE -Medium Orchid #9370DB -Medium Sea Green #426F42 -Medium Slate Blue #7F00FF -Medium Spring Green #7FFF00 -Medium Turquoise #70DBDB -Medium Violet Red #DB7093 -Medium Wood #A68064 -Midnight Blue #2F2F4F -Navy Blue #23238E -Neon Blue #4D4DFF -Neon Pink #FF6EC7 -New Midnight Blue #00009C -New Tan #EBC79E -Old Gold #CFB53B -Orange #FF7F00 -Orange Red #FF2400 -Orchid #DB70DB -Pale Green #8FBC8F -Pink #BC8F8F -Plum #EAADEA -Quartz #D9D9F3 -Rich Blue #5959AB -Salmon #6F4242 -Scarlet #8C1717 -Sea Green #238E68 -Semi-Sweet Chocolate #6B4226 -Sienna #8E6B23 -Silver #E6E8FA -Sky Blue #3299CC -Slate Blue #007FFF -Spicy Pink #FF1CAE -Spring Green #00FF7F -Steel Blue #236B8E -Summer Sky #38B0DE -Tan #DB9370 -Thistle #D8BFD8 -Turquoise #ADEAEA -Very Dark Brown #5C4033 -Very Light Grey #CDCDCD -Violet #4F2F4F -Violet Red #CC3299 -Wheat #D8D8BF -Yellow Green #99CC32 diff --git a/Tools/pynche/pyColorChooser.py b/Tools/pynche/pyColorChooser.py deleted file mode 100644 index 3286047a5fc..00000000000 --- a/Tools/pynche/pyColorChooser.py +++ /dev/null @@ -1,125 +0,0 @@ -"""Color chooser implementing (almost) the tkColorColor interface -""" - -import os -import Main -import ColorDB - - - -class Chooser: - """Ask for a color""" - def __init__(self, - master = None, - databasefile = None, - initfile = None, - ignore = None, - wantspec = None): - self.__master = master - self.__databasefile = databasefile - self.__initfile = initfile or os.path.expanduser('~/.pynche') - self.__ignore = ignore - self.__pw = None - self.__wantspec = wantspec - - def show(self, color, options): - # scan for options that can override the ctor options - self.__wantspec = options.get('wantspec', self.__wantspec) - dbfile = options.get('databasefile', self.__databasefile) - # load the database file - colordb = None - if dbfile != self.__databasefile: - colordb = ColorDB.get_colordb(dbfile) - if not self.__master: - from tkinter import Tk - self.__master = Tk() - if not self.__pw: - self.__pw, self.__sb = \ - Main.build(master = self.__master, - initfile = self.__initfile, - ignore = self.__ignore) - else: - self.__pw.deiconify() - # convert color - if colordb: - self.__sb.set_colordb(colordb) - else: - colordb = self.__sb.colordb() - if color: - r, g, b = Main.initial_color(color, colordb) - self.__sb.update_views(r, g, b) - # reset the canceled flag and run it - self.__sb.canceled(0) - Main.run(self.__pw, self.__sb) - rgbtuple = self.__sb.current_rgb() - self.__pw.withdraw() - # check to see if the cancel button was pushed - if self.__sb.canceled_p(): - return None, None - # Try to return the color name from the database if there is an exact - # match, otherwise use the "#rrggbb" spec. BAW: Forget about color - # aliases for now, maybe later we should return these too. - name = None - if not self.__wantspec: - try: - name = colordb.find_byrgb(rgbtuple)[0] - except ColorDB.BadColor: - pass - if name is None: - name = ColorDB.triplet_to_rrggbb(rgbtuple) - return rgbtuple, name - - def save(self): - if self.__sb: - self.__sb.save_views() - - -# convenience stuff -_chooser = None - -def askcolor(color = None, **options): - """Ask for a color""" - global _chooser - if not _chooser: - _chooser = Chooser(**options) - return _chooser.show(color, options) - -def save(): - global _chooser - if _chooser: - _chooser.save() - - -# test stuff -if __name__ == '__main__': - from tkinter import * - - class Tester: - def __init__(self): - self.__root = tk = Tk() - b = Button(tk, text='Choose Color...', command=self.__choose) - b.pack() - self.__l = Label(tk) - self.__l.pack() - q = Button(tk, text='Quit', command=self.__quit) - q.pack() - - def __choose(self, event=None): - rgb, name = askcolor(master=self.__root) - if rgb is None: - text = 'You hit CANCEL!' - else: - r, g, b = rgb - text = 'You picked %s (%3d/%3d/%3d)' % (name, r, g, b) - self.__l.configure(text=text) - - def __quit(self, event=None): - self.__root.quit() - - def run(self): - self.__root.mainloop() - t = Tester() - t.run() - # simpler -## print 'color:', askcolor() -## print 'color:', askcolor() diff --git a/Tools/pynche/pynche b/Tools/pynche/pynche deleted file mode 100755 index 64bf70335db..00000000000 --- a/Tools/pynche/pynche +++ /dev/null @@ -1,7 +0,0 @@ -#! /usr/bin/env python - -"""Run this file under Unix, or when debugging under Windows. -Run the file pynche.pyw under Windows to inhibit the console window. -""" -import Main -Main.main() diff --git a/Tools/pynche/pynche.pyw b/Tools/pynche/pynche.pyw deleted file mode 100755 index 6dfc8fed715..00000000000 --- a/Tools/pynche/pynche.pyw +++ /dev/null @@ -1,7 +0,0 @@ -#! /usr/bin/env python - -"""Run this file under Windows to inhibit the console window. -Run the file pynche.py under Unix or when debugging under Windows. -""" -import Main -Main.main() diff --git a/Tools/pynche/webcolors.txt b/Tools/pynche/webcolors.txt deleted file mode 100644 index f645c1e6106..00000000000 --- a/Tools/pynche/webcolors.txt +++ /dev/null @@ -1,141 +0,0 @@ -# De-facto NS & MSIE recognized HTML color names -AliceBlue #f0f8ff -AntiqueWhite #faebd7 -Aqua #00ffff -Aquamarine #7fffd4 -Azure #f0ffff -Beige #f5f5dc -Bisque #ffe4c4 -Black #000000 -BlanchedAlmond #ffebcd -Blue #0000ff -BlueViolet #8a2be2 -Brown #a52a2a -BurlyWood #deb887 -CadetBlue #5f9ea0 -Chartreuse #7fff00 -Chocolate #d2691e -Coral #ff7f50 -CornflowerBlue #6495ed -Cornsilk #fff8dc -Crimson #dc143c -Cyan #00ffff -DarkBlue #00008b -DarkCyan #008b8b -DarkGoldenrod #b8860b -DarkGray #a9a9a9 -DarkGreen #006400 -DarkKhaki #bdb76b -DarkMagenta #8b008b -DarkOliveGreen #556b2f -DarkOrange #ff8c00 -DarkOrchid #9932cc -DarkRed #8b0000 -DarkSalmon #e9967a -DarkSeaGreen #8fbc8f -DarkSlateBlue #483d8b -DarkSlateGray #2f4f4f -DarkTurquoise #00ced1 -DarkViolet #9400d3 -DeepPink #ff1493 -DeepSkyBlue #00bfff -DimGray #696969 -DodgerBlue #1e90ff -FireBrick #b22222 -FloralWhite #fffaf0 -ForestGreen #228b22 -Fuchsia #ff00ff -Gainsboro #dcdcdc -GhostWhite #f8f8ff -Gold #ffd700 -Goldenrod #daa520 -Gray #808080 -Green #008000 -GreenYellow #adff2f -Honeydew #f0fff0 -HotPink #ff69b4 -IndianRed #cd5c5c -Indigo #4b0082 -Ivory #fffff0 -Khaki #f0e68c -Lavender #e6e6fa -LavenderBlush #fff0f5 -LawnGreen #7cfc00 -LemonChiffon #fffacd -LightBlue #add8e6 -LightCoral #f08080 -LightCyan #e0ffff -LightGoldenrodYellow #fafad2 -LightGreen #90ee90 -LightGrey #d3d3d3 -LightPink #ffb6c1 -LightSalmon #ffa07a -LightSeaGreen #20b2aa -LightSkyBlue #87cefa -LightSlateGray #778899 -LightSteelBlue #b0c4de -LightYellow #ffffe0 -Lime #00ff00 -LimeGreen #32cd32 -Linen #faf0e6 -Magenta #ff00ff -Maroon #800000 -MediumAquamarine #66cdaa -MediumBlue #0000cd -MediumOrchid #ba55d3 -MediumPurple #9370db -MediumSeaGreen #3cb371 -MediumSlateBlue #7b68ee -MediumSpringGreen #00fa9a -MediumTurquoise #48d1cc -MediumVioletRed #c71585 -MidnightBlue #191970 -MintCream #f5fffa -MistyRose #ffe4e1 -Moccasin #ffe4b5 -NavajoWhite #ffdead -Navy #000080 -OldLace #fdf5e6 -Olive #808000 -OliveDrab #6b8e23 -Orange #ffa500 -OrangeRed #ff4500 -Orchid #da70d6 -PaleGoldenrod #eee8aa -PaleGreen #98fb98 -PaleTurquoise #afeeee -PaleVioletRed #db7093 -PapayaWhip #ffefd5 -PeachPuff #ffdab9 -Peru #cd853f -Pink #ffc0cb -Plum #dda0dd -PowderBlue #b0e0e6 -Purple #800080 -Red #ff0000 -RosyBrown #bc8f8f -RoyalBlue #4169e1 -SaddleBrown #8b4513 -Salmon #fa8072 -SandyBrown #f4a460 -SeaGreen #2e8b57 -Seashell #fff5ee -Sienna #a0522d -Silver #c0c0c0 -SkyBlue #87ceeb -SlateBlue #6a5acd -SlateGray #708090 -Snow #fffafa -SpringGreen #00ff7f -SteelBlue #4682b4 -Tan #d2b48c -Teal #008080 -Thistle #d8bfd8 -Tomato #ff6347 -Turquoise #40e0d0 -Violet #ee82ee -Wheat #f5deb3 -White #ffffff -WhiteSmoke #f5f5f5 -Yellow #ffff00 -YellowGreen #9acd32 diff --git a/Tools/pynche/websafe.txt b/Tools/pynche/websafe.txt deleted file mode 100644 index 70ed51e6832..00000000000 --- a/Tools/pynche/websafe.txt +++ /dev/null @@ -1,217 +0,0 @@ -# Websafe RGB values -#000000 -#000033 -#000066 -#000099 -#0000cc -#0000ff -#003300 -#003333 -#003366 -#003399 -#0033cc -#0033ff -#006600 -#006633 -#006666 -#006699 -#0066cc -#0066ff -#009900 -#009933 -#009966 -#009999 -#0099cc -#0099ff -#00cc00 -#00cc33 -#00cc66 -#00cc99 -#00cccc -#00ccff -#00ff00 -#00ff33 -#00ff66 -#00ff99 -#00ffcc -#00ffff -#330000 -#330033 -#330066 -#330099 -#3300cc -#3300ff -#333300 -#333333 -#333366 -#333399 -#3333cc -#3333ff -#336600 -#336633 -#336666 -#336699 -#3366cc -#3366ff -#339900 -#339933 -#339966 -#339999 -#3399cc -#3399ff -#33cc00 -#33cc33 -#33cc66 -#33cc99 -#33cccc -#33ccff -#33ff00 -#33ff33 -#33ff66 -#33ff99 -#33ffcc -#33ffff -#660000 -#660033 -#660066 -#660099 -#6600cc -#6600ff -#663300 -#663333 -#663366 -#663399 -#6633cc -#6633ff -#666600 -#666633 -#666666 -#666699 -#6666cc -#6666ff -#669900 -#669933 -#669966 -#669999 -#6699cc -#6699ff -#66cc00 -#66cc33 -#66cc66 -#66cc99 -#66cccc -#66ccff -#66ff00 -#66ff33 -#66ff66 -#66ff99 -#66ffcc -#66ffff -#990000 -#990033 -#990066 -#990099 -#9900cc -#9900ff -#993300 -#993333 -#993366 -#993399 -#9933cc -#9933ff -#996600 -#996633 -#996666 -#996699 -#9966cc -#9966ff -#999900 -#999933 -#999966 -#999999 -#9999cc -#9999ff -#99cc00 -#99cc33 -#99cc66 -#99cc99 -#99cccc -#99ccff -#99ff00 -#99ff33 -#99ff66 -#99ff99 -#99ffcc -#99ffff -#cc0000 -#cc0033 -#cc0066 -#cc0099 -#cc00cc -#cc00ff -#cc3300 -#cc3333 -#cc3366 -#cc3399 -#cc33cc -#cc33ff -#cc6600 -#cc6633 -#cc6666 -#cc6699 -#cc66cc -#cc66ff -#cc9900 -#cc9933 -#cc9966 -#cc9999 -#cc99cc -#cc99ff -#cccc00 -#cccc33 -#cccc66 -#cccc99 -#cccccc -#ccccff -#ccff00 -#ccff33 -#ccff66 -#ccff99 -#ccffcc -#ccffff -#ff0000 -#ff0033 -#ff0066 -#ff0099 -#ff00cc -#ff00ff -#ff3300 -#ff3333 -#ff3366 -#ff3399 -#ff33cc -#ff33ff -#ff6600 -#ff6633 -#ff6666 -#ff6699 -#ff66cc -#ff66ff -#ff9900 -#ff9933 -#ff9966 -#ff9999 -#ff99cc -#ff99ff -#ffcc00 -#ffcc33 -#ffcc66 -#ffcc99 -#ffcccc -#ffccff -#ffff00 -#ffff33 -#ffff66 -#ffff99 -#ffffcc -#ffffff diff --git a/Tools/scripts/2to3 b/Tools/scripts/2to3 index fbd4aa6b838..f27d18ecf67 100755 --- a/Tools/scripts/2to3 +++ b/Tools/scripts/2to3 @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import sys from lib2to3.main import main diff --git a/Tools/scripts/README b/Tools/scripts/README index ba0f662c45f..b9522681595 100644 --- a/Tools/scripts/README +++ b/Tools/scripts/README @@ -1,66 +1,10 @@ This directory contains a collection of executable Python scripts that are -useful while building, extending or managing Python. Some (e.g., dutree or lll) -are also generally useful UNIX tools. +useful while building, extending or managing Python. 2to3 Main script for running the 2to3 conversion tool -abitype.py Converts a C file to use the PEP 384 type definition API -analyze_dxp.py Analyzes the result of sys.getdxp() -byext.py Print lines/words/chars stats of files by extension -byteyears.py Print product of a file's size and age -cleanfuture.py Fix redundant Python __future__ statements combinerefs.py A helper for analyzing PYTHONDUMPREFS output -copytime.py Copy one file's atime and mtime to another -crlf.py Change CRLF line endings to LF (Windows to Unix) -db2pickle.py Dump a database file to a pickle -diff.py Print file diffs in context, unified, or ndiff formats -dutree.py Format du(1) output as a tree sorted by size -eptags.py Create Emacs TAGS file for Python modules -finddiv.py A grep-like tool that looks for division operators -findlinksto.py Recursively find symbolic links to a given path prefix -findnocoding.py Find source files which need an encoding declaration -find_recursionlimit.py Find the maximum recursion limit on this machine -find-uname.py Look for the given arguments in the sets of all Unicode names -fixcid.py Massive identifier substitution on C source files -fixdiv.py Tool to fix division operators. -fixheader.py Add some cpp magic to a C include file -fixnotice.py Fix the copyright notice in source files -fixps.py Fix Python scripts' first line (if #!) -ftpmirror.py FTP mirror script -get-remote-certificate.py Fetch the certificate that the server(s) are providing in PEM form -google.py Open a webbrowser with Google -gprof2html.py Transform gprof(1) output into useful HTML -highlight.py Python syntax highlighting with HTML output idle3 Main program to start IDLE -ifdef.py Remove #if(n)def groups from C sources -import_diagnostics.py Miscellaneous diagnostics for the import system -lfcr.py Change LF line endings to CRLF (Unix to Windows) -linktree.py Make a copy of a tree with links to original files -lll.py Find and list symbolic links in current directory -mailerdaemon.py Parse error messages from mailer daemons (Sjoerd&Jack) -make_ctype.py Generate ctype.h replacement in stringobject.c -md5sum.py Print MD5 checksums of argument files -mkreal.py Turn a symbolic link into a real file or directory -ndiff.py Intelligent diff between text files (Tim Peters) -nm2def.py Create a template for PC/python_nt.def (Marc Lemburg) -objgraph.py Print object graph from nm output on a library -parseentities.py Utility for parsing HTML entity definitions parse_html5_entities.py Utility for parsing HTML5 entity definitions -patchcheck.py Perform common checks and cleanup before committing -pathfix.py Change #!/usr/local/bin/python into something else -pdeps.py Print dependencies between Python modules -pickle2db.py Load a pickle generated by db2pickle.py to a database -pindent.py Indent Python code, giving block-closing comments -ptags.py Create vi tags file for Python modules pydoc3 Python documentation browser -pysource.py Find Python source files -reindent.py Change .py files to use 4-space indents -reindent-rst.py Fix-up reStructuredText file whitespace -rgrep.py Reverse grep through a file (useful for big logfiles) run_tests.py Run the test suite with more sensible default options -serve.py Small wsgiref-based web server, used in make serve in Doc stable_abi.py Stable ABI checks and file generators. -suff.py Sort a list of files by suffix -texi2html.py Convert GNU texinfo files into HTML -untabify.py Replace tabs with spaces in argument files -which.py Find a program in $PATH -win_add2path.py Add Python to the search path on Windows diff --git a/Tools/scripts/abitype.py b/Tools/scripts/abitype.py deleted file mode 100755 index d6a74a1fe64..00000000000 --- a/Tools/scripts/abitype.py +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env python3 -# This script converts a C file to use the PEP 384 type definition API -# Usage: abitype.py < old_code > new_code -import re, sys - -###### Replacement of PyTypeObject static instances ############## - -# classify each token, giving it a one-letter code: -# S: static -# T: PyTypeObject -# I: ident -# W: whitespace -# =, {, }, ; : themselves -def classify(): - res = [] - for t,v in tokens: - if t == 'other' and v in "={};": - res.append(v) - elif t == 'ident': - if v == 'PyTypeObject': - res.append('T') - elif v == 'static': - res.append('S') - else: - res.append('I') - elif t == 'ws': - res.append('W') - else: - res.append('.') - return ''.join(res) - -# Obtain a list of fields of a PyTypeObject, in declaration order, -# skipping ob_base -# All comments are dropped from the variable (which are typically -# just the slot names, anyway), and information is discarded whether -# the original type was static. -def get_fields(start, real_end): - pos = start - # static? - if tokens[pos][1] == 'static': - pos += 2 - # PyTypeObject - pos += 2 - # name - name = tokens[pos][1] - pos += 1 - while tokens[pos][1] != '{': - pos += 1 - pos += 1 - # PyVarObject_HEAD_INIT - while tokens[pos][0] in ('ws', 'comment'): - pos += 1 - if tokens[pos][1] != 'PyVarObject_HEAD_INIT': - raise Exception('%s has no PyVarObject_HEAD_INIT' % name) - while tokens[pos][1] != ')': - pos += 1 - pos += 1 - # field definitions: various tokens, comma-separated - fields = [] - while True: - while tokens[pos][0] in ('ws', 'comment'): - pos += 1 - end = pos - while tokens[end][1] not in ',}': - if tokens[end][1] == '(': - nesting = 1 - while nesting: - end += 1 - if tokens[end][1] == '(': nesting+=1 - if tokens[end][1] == ')': nesting-=1 - end += 1 - assert end < real_end - # join field, excluding separator and trailing ws - end1 = end-1 - while tokens[end1][0] in ('ws', 'comment'): - end1 -= 1 - fields.append(''.join(t[1] for t in tokens[pos:end1+1])) - if tokens[end][1] == '}': - break - pos = end+1 - return name, fields - -# List of type slots as of Python 3.2, omitting ob_base -typeslots = [ - 'tp_name', - 'tp_basicsize', - 'tp_itemsize', - 'tp_dealloc', - 'tp_print', - 'tp_getattr', - 'tp_setattr', - 'tp_reserved', - 'tp_repr', - 'tp_as_number', - 'tp_as_sequence', - 'tp_as_mapping', - 'tp_hash', - 'tp_call', - 'tp_str', - 'tp_getattro', - 'tp_setattro', - 'tp_as_buffer', - 'tp_flags', - 'tp_doc', - 'tp_traverse', - 'tp_clear', - 'tp_richcompare', - 'tp_weaklistoffset', - 'tp_iter', - 'iternextfunc', - 'tp_methods', - 'tp_members', - 'tp_getset', - 'tp_base', - 'tp_dict', - 'tp_descr_get', - 'tp_descr_set', - 'tp_dictoffset', - 'tp_init', - 'tp_alloc', - 'tp_new', - 'tp_free', - 'tp_is_gc', - 'tp_bases', - 'tp_mro', - 'tp_cache', - 'tp_subclasses', - 'tp_weaklist', - 'tp_del', - 'tp_version_tag', -] - -# Generate a PyType_Spec definition -def make_slots(name, fields): - res = [] - res.append('static PyType_Slot %s_slots[] = {' % name) - # defaults for spec - spec = { 'tp_itemsize':'0' } - for i, val in enumerate(fields): - if val.endswith('0'): - continue - if typeslots[i] in ('tp_name', 'tp_doc', 'tp_basicsize', - 'tp_itemsize', 'tp_flags'): - spec[typeslots[i]] = val - continue - res.append(' {Py_%s, %s},' % (typeslots[i], val)) - res.append('};') - res.append('static PyType_Spec %s_spec = {' % name) - res.append(' %s,' % spec['tp_name']) - res.append(' %s,' % spec['tp_basicsize']) - res.append(' %s,' % spec['tp_itemsize']) - res.append(' %s,' % spec['tp_flags']) - res.append(' %s_slots,' % name) - res.append('};\n') - return '\n'.join(res) - - -if __name__ == '__main__': - - ############ Simplistic C scanner ################################## - tokenizer = re.compile( - r"(?P#.*\n)" - r"|(?P/\*.*?\*/)" - r"|(?P[a-zA-Z_][a-zA-Z0-9_]*)" - r"|(?P[ \t\n]+)" - r"|(?P.)", - re.MULTILINE) - - tokens = [] - source = sys.stdin.read() - pos = 0 - while pos != len(source): - m = tokenizer.match(source, pos) - tokens.append([m.lastgroup, m.group()]) - pos += len(tokens[-1][1]) - if tokens[-1][0] == 'preproc': - # continuation lines are considered - # only in preprocess statements - while tokens[-1][1].endswith('\\\n'): - nl = source.find('\n', pos) - if nl == -1: - line = source[pos:] - else: - line = source[pos:nl+1] - tokens[-1][1] += line - pos += len(line) - - # Main loop: replace all static PyTypeObjects until - # there are none left. - while 1: - c = classify() - m = re.search('(SW)?TWIW?=W?{.*?};', c) - if not m: - break - start = m.start() - end = m.end() - name, fields = get_fields(start, end) - tokens[start:end] = [('',make_slots(name, fields))] - - # Output result to stdout - for t, v in tokens: - sys.stdout.write(v) diff --git a/Tools/scripts/analyze_dxp.py b/Tools/scripts/analyze_dxp.py deleted file mode 100644 index bde931e7503..00000000000 --- a/Tools/scripts/analyze_dxp.py +++ /dev/null @@ -1,129 +0,0 @@ -""" -Some helper functions to analyze the output of sys.getdxp() (which is -only available if Python was built with -DDYNAMIC_EXECUTION_PROFILE). -These will tell you which opcodes have been executed most frequently -in the current process, and, if Python was also built with -DDXPAIRS, -will tell you which instruction _pairs_ were executed most frequently, -which may help in choosing new instructions. - -If Python was built without -DDYNAMIC_EXECUTION_PROFILE, importing -this module will raise a RuntimeError. - -If you're running a script you want to profile, a simple way to get -the common pairs is: - -$ PYTHONPATH=$PYTHONPATH:/Tools/scripts \ -./python -i -O the_script.py --args -... -> from analyze_dxp import * -> s = render_common_pairs() -> open('/tmp/some_file', 'w').write(s) -""" - -import copy -import opcode -import operator -import sys -import threading - -if not hasattr(sys, "getdxp"): - raise RuntimeError("Can't import analyze_dxp: Python built without" - " -DDYNAMIC_EXECUTION_PROFILE.") - - -_profile_lock = threading.RLock() -_cumulative_profile = sys.getdxp() - -# If Python was built with -DDXPAIRS, sys.getdxp() returns a list of -# lists of ints. Otherwise it returns just a list of ints. -def has_pairs(profile): - """Returns True if the Python that produced the argument profile - was built with -DDXPAIRS.""" - - return len(profile) > 0 and isinstance(profile[0], list) - - -def reset_profile(): - """Forgets any execution profile that has been gathered so far.""" - with _profile_lock: - sys.getdxp() # Resets the internal profile - global _cumulative_profile - _cumulative_profile = sys.getdxp() # 0s out our copy. - - -def merge_profile(): - """Reads sys.getdxp() and merges it into this module's cached copy. - - We need this because sys.getdxp() 0s itself every time it's called.""" - - with _profile_lock: - new_profile = sys.getdxp() - if has_pairs(new_profile): - for first_inst in range(len(_cumulative_profile)): - for second_inst in range(len(_cumulative_profile[first_inst])): - _cumulative_profile[first_inst][second_inst] += ( - new_profile[first_inst][second_inst]) - else: - for inst in range(len(_cumulative_profile)): - _cumulative_profile[inst] += new_profile[inst] - - -def snapshot_profile(): - """Returns the cumulative execution profile until this call.""" - with _profile_lock: - merge_profile() - return copy.deepcopy(_cumulative_profile) - - -def common_instructions(profile): - """Returns the most common opcodes in order of descending frequency. - - The result is a list of tuples of the form - (opcode, opname, # of occurrences) - - """ - if has_pairs(profile) and profile: - inst_list = profile[-1] - else: - inst_list = profile - result = [(op, opcode.opname[op], count) - for op, count in enumerate(inst_list) - if count > 0] - result.sort(key=operator.itemgetter(2), reverse=True) - return result - - -def common_pairs(profile): - """Returns the most common opcode pairs in order of descending frequency. - - The result is a list of tuples of the form - ((1st opcode, 2nd opcode), - (1st opname, 2nd opname), - # of occurrences of the pair) - - """ - if not has_pairs(profile): - return [] - result = [((op1, op2), (opcode.opname[op1], opcode.opname[op2]), count) - # Drop the row of single-op profiles with [:-1] - for op1, op1profile in enumerate(profile[:-1]) - for op2, count in enumerate(op1profile) - if count > 0] - result.sort(key=operator.itemgetter(2), reverse=True) - return result - - -def render_common_pairs(profile=None): - """Renders the most common opcode pairs to a string in order of - descending frequency. - - The result is a series of lines of the form: - # of occurrences: ('1st opname', '2nd opname') - - """ - if profile is None: - profile = snapshot_profile() - def seq(): - for _, ops, count in common_pairs(profile): - yield "%s: %s\n" % (count, ops) - return ''.join(seq()) diff --git a/Tools/scripts/byext.py b/Tools/scripts/byext.py deleted file mode 100755 index a4b2f7ff6d8..00000000000 --- a/Tools/scripts/byext.py +++ /dev/null @@ -1,132 +0,0 @@ -#! /usr/bin/env python3 - -"""Show file statistics by extension.""" - -import os -import sys - - -class Stats: - - def __init__(self): - self.stats = {} - - def statargs(self, args): - for arg in args: - if os.path.isdir(arg): - self.statdir(arg) - elif os.path.isfile(arg): - self.statfile(arg) - else: - sys.stderr.write("Can't find %s\n" % arg) - self.addstats("", "unknown", 1) - - def statdir(self, dir): - self.addstats("", "dirs", 1) - try: - names = os.listdir(dir) - except OSError as err: - sys.stderr.write("Can't list %s: %s\n" % (dir, err)) - self.addstats("", "unlistable", 1) - return - for name in sorted(names): - if name.startswith(".#"): - continue # Skip CVS temp files - if name.endswith("~"): - continue # Skip Emacs backup files - full = os.path.join(dir, name) - if os.path.islink(full): - self.addstats("", "links", 1) - elif os.path.isdir(full): - self.statdir(full) - else: - self.statfile(full) - - def statfile(self, filename): - head, ext = os.path.splitext(filename) - head, base = os.path.split(filename) - if ext == base: - ext = "" # E.g. .cvsignore is deemed not to have an extension - ext = os.path.normcase(ext) - if not ext: - ext = "" - self.addstats(ext, "files", 1) - try: - with open(filename, "rb") as f: - data = f.read() - except IOError as err: - sys.stderr.write("Can't open %s: %s\n" % (filename, err)) - self.addstats(ext, "unopenable", 1) - return - self.addstats(ext, "bytes", len(data)) - if b'\0' in data: - self.addstats(ext, "binary", 1) - return - if not data: - self.addstats(ext, "empty", 1) - # self.addstats(ext, "chars", len(data)) - lines = str(data, "latin-1").splitlines() - self.addstats(ext, "lines", len(lines)) - del lines - words = data.split() - self.addstats(ext, "words", len(words)) - - def addstats(self, ext, key, n): - d = self.stats.setdefault(ext, {}) - d[key] = d.get(key, 0) + n - - def report(self): - exts = sorted(self.stats) - # Get the column keys - columns = {} - for ext in exts: - columns.update(self.stats[ext]) - cols = sorted(columns) - colwidth = {} - colwidth["ext"] = max(map(len, exts)) - minwidth = 6 - self.stats["TOTAL"] = {} - for col in cols: - total = 0 - cw = max(minwidth, len(col)) - for ext in exts: - value = self.stats[ext].get(col) - if value is None: - w = 0 - else: - w = len("%d" % value) - total += value - cw = max(cw, w) - cw = max(cw, len(str(total))) - colwidth[col] = cw - self.stats["TOTAL"][col] = total - exts.append("TOTAL") - for ext in exts: - self.stats[ext]["ext"] = ext - cols.insert(0, "ext") - - def printheader(): - for col in cols: - print("%*s" % (colwidth[col], col), end=' ') - print() - - printheader() - for ext in exts: - for col in cols: - value = self.stats[ext].get(col, "") - print("%*s" % (colwidth[col], value), end=' ') - print() - printheader() # Another header at the bottom - - -def main(): - args = sys.argv[1:] - if not args: - args = [os.curdir] - s = Stats() - s.statargs(args) - s.report() - - -if __name__ == "__main__": - main() diff --git a/Tools/scripts/byteyears.py b/Tools/scripts/byteyears.py deleted file mode 100755 index f58c34608fa..00000000000 --- a/Tools/scripts/byteyears.py +++ /dev/null @@ -1,61 +0,0 @@ -#! /usr/bin/env python3 - -# Print the product of age and size of each file, in suitable units. -# -# Usage: byteyears [ -a | -m | -c ] file ... -# -# Options -[amc] select atime, mtime (default) or ctime as age. - -import sys, os, time -from stat import * - -def main(): - - # Use lstat() to stat files if it exists, else stat() - try: - statfunc = os.lstat - except AttributeError: - statfunc = os.stat - - # Parse options - if sys.argv[1] == '-m': - itime = ST_MTIME - del sys.argv[1] - elif sys.argv[1] == '-c': - itime = ST_CTIME - del sys.argv[1] - elif sys.argv[1] == '-a': - itime = ST_CTIME - del sys.argv[1] - else: - itime = ST_MTIME - - secs_per_year = 365.0 * 24.0 * 3600.0 # Scale factor - now = time.time() # Current time, for age computations - status = 0 # Exit status, set to 1 on errors - - # Compute max file name length - maxlen = 1 - for filename in sys.argv[1:]: - maxlen = max(maxlen, len(filename)) - - # Process each argument in turn - for filename in sys.argv[1:]: - try: - st = statfunc(filename) - except OSError as msg: - sys.stderr.write("can't stat %r: %r\n" % (filename, msg)) - status = 1 - st = () - if st: - anytime = st[itime] - size = st[ST_SIZE] - age = now - anytime - byteyears = float(size) * float(age) / secs_per_year - print(filename.ljust(maxlen), end=' ') - print(repr(int(byteyears)).rjust(8)) - - sys.exit(status) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/cleanfuture.py b/Tools/scripts/cleanfuture.py deleted file mode 100755 index 94f69126321..00000000000 --- a/Tools/scripts/cleanfuture.py +++ /dev/null @@ -1,275 +0,0 @@ -#! /usr/bin/env python3 - -"""cleanfuture [-d][-r][-v] path ... - --d Dry run. Analyze, but don't make any changes to, files. --r Recurse. Search for all .py files in subdirectories too. --v Verbose. Print informative msgs. - -Search Python (.py) files for future statements, and remove the features -from such statements that are already mandatory in the version of Python -you're using. - -Pass one or more file and/or directory paths. When a directory path, all -.py files within the directory will be examined, and, if the -r option is -given, likewise recursively for subdirectories. - -Overwrites files in place, renaming the originals with a .bak extension. If -cleanfuture finds nothing to change, the file is left alone. If cleanfuture -does change a file, the changed file is a fixed-point (i.e., running -cleanfuture on the resulting .py file won't change it again, at least not -until you try it again with a later Python release). - -Limitations: You can do these things, but this tool won't help you then: - -+ A future statement cannot be mixed with any other statement on the same - physical line (separated by semicolon). - -+ A future statement cannot contain an "as" clause. - -Example: Assuming you're using Python 2.2, if a file containing - -from __future__ import nested_scopes, generators - -is analyzed by cleanfuture, the line is rewritten to - -from __future__ import generators - -because nested_scopes is no longer optional in 2.2 but generators is. -""" - -import __future__ -import tokenize -import os -import sys - -dryrun = 0 -recurse = 0 -verbose = 0 - -def errprint(*args): - strings = map(str, args) - msg = ' '.join(strings) - if msg[-1:] != '\n': - msg += '\n' - sys.stderr.write(msg) - -def main(): - import getopt - global verbose, recurse, dryrun - try: - opts, args = getopt.getopt(sys.argv[1:], "drv") - except getopt.error as msg: - errprint(msg) - return - for o, a in opts: - if o == '-d': - dryrun += 1 - elif o == '-r': - recurse += 1 - elif o == '-v': - verbose += 1 - if not args: - errprint("Usage:", __doc__) - return - for arg in args: - check(arg) - -def check(file): - if os.path.isdir(file) and not os.path.islink(file): - if verbose: - print("listing directory", file) - names = os.listdir(file) - for name in names: - fullname = os.path.join(file, name) - if ((recurse and os.path.isdir(fullname) and - not os.path.islink(fullname)) - or name.lower().endswith(".py")): - check(fullname) - return - - if verbose: - print("checking", file, "...", end=' ') - try: - f = open(file) - except IOError as msg: - errprint("%r: I/O Error: %s" % (file, str(msg))) - return - - with f: - ff = FutureFinder(f, file) - changed = ff.run() - if changed: - ff.gettherest() - if changed: - if verbose: - print("changed.") - if dryrun: - print("But this is a dry run, so leaving it alone.") - for s, e, line in changed: - print("%r lines %d-%d" % (file, s+1, e+1)) - for i in range(s, e+1): - print(ff.lines[i], end=' ') - if line is None: - print("-- deleted") - else: - print("-- change to:") - print(line, end=' ') - if not dryrun: - bak = file + ".bak" - if os.path.exists(bak): - os.remove(bak) - os.rename(file, bak) - if verbose: - print("renamed", file, "to", bak) - with open(file, "w") as g: - ff.write(g) - if verbose: - print("wrote new", file) - else: - if verbose: - print("unchanged.") - -class FutureFinder: - - def __init__(self, f, fname): - self.f = f - self.fname = fname - self.ateof = 0 - self.lines = [] # raw file lines - - # List of (start_index, end_index, new_line) triples. - self.changed = [] - - # Line-getter for tokenize. - def getline(self): - if self.ateof: - return "" - line = self.f.readline() - if line == "": - self.ateof = 1 - else: - self.lines.append(line) - return line - - def run(self): - STRING = tokenize.STRING - NL = tokenize.NL - NEWLINE = tokenize.NEWLINE - COMMENT = tokenize.COMMENT - NAME = tokenize.NAME - OP = tokenize.OP - - changed = self.changed - get = tokenize.generate_tokens(self.getline).__next__ - type, token, (srow, scol), (erow, ecol), line = get() - - # Chew up initial comments and blank lines (if any). - while type in (COMMENT, NL, NEWLINE): - type, token, (srow, scol), (erow, ecol), line = get() - - # Chew up docstring (if any -- and it may be implicitly catenated!). - while type is STRING: - type, token, (srow, scol), (erow, ecol), line = get() - - # Analyze the future stmts. - while 1: - # Chew up comments and blank lines (if any). - while type in (COMMENT, NL, NEWLINE): - type, token, (srow, scol), (erow, ecol), line = get() - - if not (type is NAME and token == "from"): - break - startline = srow - 1 # tokenize is one-based - type, token, (srow, scol), (erow, ecol), line = get() - - if not (type is NAME and token == "__future__"): - break - type, token, (srow, scol), (erow, ecol), line = get() - - if not (type is NAME and token == "import"): - break - type, token, (srow, scol), (erow, ecol), line = get() - - # Get the list of features. - features = [] - while type is NAME: - features.append(token) - type, token, (srow, scol), (erow, ecol), line = get() - - if not (type is OP and token == ','): - break - type, token, (srow, scol), (erow, ecol), line = get() - - # A trailing comment? - comment = None - if type is COMMENT: - comment = token - type, token, (srow, scol), (erow, ecol), line = get() - - if type is not NEWLINE: - errprint("Skipping file %r; can't parse line %d:\n%s" % - (self.fname, srow, line)) - return [] - - endline = srow - 1 - - # Check for obsolete features. - okfeatures = [] - for f in features: - object = getattr(__future__, f, None) - if object is None: - # A feature we don't know about yet -- leave it in. - # They'll get a compile-time error when they compile - # this program, but that's not our job to sort out. - okfeatures.append(f) - else: - released = object.getMandatoryRelease() - if released is None or released <= sys.version_info: - # Withdrawn or obsolete. - pass - else: - okfeatures.append(f) - - # Rewrite the line if at least one future-feature is obsolete. - if len(okfeatures) < len(features): - if len(okfeatures) == 0: - line = None - else: - line = "from __future__ import " - line += ', '.join(okfeatures) - if comment is not None: - line += ' ' + comment - line += '\n' - changed.append((startline, endline, line)) - - # Loop back for more future statements. - - return changed - - def gettherest(self): - if self.ateof: - self.therest = '' - else: - self.therest = self.f.read() - - def write(self, f): - changed = self.changed - assert changed - # Prevent calling this again. - self.changed = [] - # Apply changes in reverse order. - changed.reverse() - for s, e, line in changed: - if line is None: - # pure deletion - del self.lines[s:e+1] - else: - self.lines[s:e+1] = [line] - f.writelines(self.lines) - # Copy over the remainder of the file. - if self.therest: - f.write(self.therest) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/copytime.py b/Tools/scripts/copytime.py deleted file mode 100755 index 715683f1255..00000000000 --- a/Tools/scripts/copytime.py +++ /dev/null @@ -1,26 +0,0 @@ -#! /usr/bin/env python3 - -# Copy one file's atime and mtime to another - -import sys -import os -from stat import ST_ATIME, ST_MTIME # Really constants 7 and 8 - -def main(): - if len(sys.argv) != 3: - sys.stderr.write('usage: copytime source destination\n') - sys.exit(2) - file1, file2 = sys.argv[1], sys.argv[2] - try: - stat1 = os.stat(file1) - except OSError: - sys.stderr.write(file1 + ': cannot stat\n') - sys.exit(1) - try: - os.utime(file2, (stat1[ST_ATIME], stat1[ST_MTIME])) - except OSError: - sys.stderr.write(file2 + ': cannot change time\n') - sys.exit(2) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/crlf.py b/Tools/scripts/crlf.py deleted file mode 100755 index f231d292ceb..00000000000 --- a/Tools/scripts/crlf.py +++ /dev/null @@ -1,23 +0,0 @@ -#! /usr/bin/env python3 -"Replace CRLF with LF in argument files. Print names of changed files." - -import sys, os - -def main(): - for filename in sys.argv[1:]: - if os.path.isdir(filename): - print(filename, "Directory!") - continue - with open(filename, "rb") as f: - data = f.read() - if b'\0' in data: - print(filename, "Binary!") - continue - newdata = data.replace(b"\r\n", b"\n") - if newdata != data: - print(filename) - with open(filename, "wb") as f: - f.write(newdata) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/db2pickle.py b/Tools/scripts/db2pickle.py deleted file mode 100755 index a5532a8f3a4..00000000000 --- a/Tools/scripts/db2pickle.py +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env python3 - -""" -Synopsis: %(prog)s [-h|-g|-b|-r|-a] dbfile [ picklefile ] - -Convert the database file given on the command line to a pickle -representation. The optional flags indicate the type of the database: - - -a - open using dbm (any supported format) - -b - open as bsddb btree file - -d - open as dbm file - -g - open as gdbm file - -h - open as bsddb hash file - -r - open as bsddb recno file - -The default is hash. If a pickle file is named it is opened for write -access (deleting any existing data). If no pickle file is named, the pickle -output is written to standard output. - -""" - -import getopt -try: - import bsddb -except ImportError: - bsddb = None -try: - import dbm.ndbm as dbm -except ImportError: - dbm = None -try: - import dbm.gnu as gdbm -except ImportError: - gdbm = None -try: - import dbm.ndbm as anydbm -except ImportError: - anydbm = None -import sys -try: - import pickle as pickle -except ImportError: - import pickle - -prog = sys.argv[0] - -def usage(): - sys.stderr.write(__doc__ % globals()) - -def main(args): - try: - opts, args = getopt.getopt(args, "hbrdag", - ["hash", "btree", "recno", "dbm", - "gdbm", "anydbm"]) - except getopt.error: - usage() - return 1 - - if len(args) == 0 or len(args) > 2: - usage() - return 1 - elif len(args) == 1: - dbfile = args[0] - pfile = sys.stdout - else: - dbfile = args[0] - try: - pfile = open(args[1], 'wb') - except IOError: - sys.stderr.write("Unable to open %s\n" % args[1]) - return 1 - - dbopen = None - for opt, arg in opts: - if opt in ("-h", "--hash"): - try: - dbopen = bsddb.hashopen - except AttributeError: - sys.stderr.write("bsddb module unavailable.\n") - return 1 - elif opt in ("-b", "--btree"): - try: - dbopen = bsddb.btopen - except AttributeError: - sys.stderr.write("bsddb module unavailable.\n") - return 1 - elif opt in ("-r", "--recno"): - try: - dbopen = bsddb.rnopen - except AttributeError: - sys.stderr.write("bsddb module unavailable.\n") - return 1 - elif opt in ("-a", "--anydbm"): - try: - dbopen = anydbm.open - except AttributeError: - sys.stderr.write("dbm module unavailable.\n") - return 1 - elif opt in ("-g", "--gdbm"): - try: - dbopen = gdbm.open - except AttributeError: - sys.stderr.write("dbm.gnu module unavailable.\n") - return 1 - elif opt in ("-d", "--dbm"): - try: - dbopen = dbm.open - except AttributeError: - sys.stderr.write("dbm.ndbm module unavailable.\n") - return 1 - if dbopen is None: - if bsddb is None: - sys.stderr.write("bsddb module unavailable - ") - sys.stderr.write("must specify dbtype.\n") - return 1 - else: - dbopen = bsddb.hashopen - - try: - db = dbopen(dbfile, 'r') - except bsddb.error: - sys.stderr.write("Unable to open %s. " % dbfile) - sys.stderr.write("Check for format or version mismatch.\n") - return 1 - - for k in db.keys(): - pickle.dump((k, db[k]), pfile, 1==1) - - db.close() - pfile.close() - - return 0 - -if __name__ == "__main__": - sys.exit(main(sys.argv[1:])) diff --git a/Tools/scripts/divmod_threshold.py b/Tools/scripts/divmod_threshold.py new file mode 100644 index 00000000000..69819fe3098 --- /dev/null +++ b/Tools/scripts/divmod_threshold.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# +# Determine threshold for switching from longobject.c divmod to +# _pylong.int_divmod(). + +from random import randrange +from time import perf_counter as now +from _pylong import int_divmod as divmod_fast + +BITS_PER_DIGIT = 30 + + +def rand_digits(n): + top = 1 << (n * BITS_PER_DIGIT) + return randrange(top >> 1, top) + + +def probe_den(nd): + den = rand_digits(nd) + count = 0 + for nn in range(nd, nd + 3000): + num = rand_digits(nn) + t0 = now() + e1, e2 = divmod(num, den) + t1 = now() + f1, f2 = divmod_fast(num, den) + t2 = now() + s1 = t1 - t0 + s2 = t2 - t1 + assert e1 == f1 + assert e2 == f2 + if s2 < s1: + count += 1 + if count >= 3: + print( + "for", + nd, + "denom digits,", + nn - nd, + "extra num digits is enough", + ) + break + else: + count = 0 + else: + print("for", nd, "denom digits, no num seems big enough") + + +def main(): + for nd in range(30): + nd = (nd + 1) * 100 + probe_den(nd) + + +if __name__ == '__main__': + main() diff --git a/Tools/scripts/dutree.doc b/Tools/scripts/dutree.doc deleted file mode 100644 index 490126b0182..00000000000 --- a/Tools/scripts/dutree.doc +++ /dev/null @@ -1,54 +0,0 @@ -Path: cwi.nl!sun4nl!mcsun!uunet!cs.utexas.edu!convex!usenet -From: tchrist@convex.COM (Tom Christiansen) -Newsgroups: comp.lang.perl -Subject: Re: The problems of Perl (Re: Question (silly?)) -Message-ID: <1992Jan17.053115.4220@convex.com> -Date: 17 Jan 92 05:31:15 GMT -References: <17458@ector.cs.purdue.edu> <1992Jan16.165347.25583@cherokee.uswest.com> <=#Hues+4@cs.psu.edu> -Sender: usenet@convex.com (news access account) -Reply-To: tchrist@convex.COM (Tom Christiansen) -Organization: CONVEX Realtime Development, Colorado Springs, CO -Lines: 83 -Nntp-Posting-Host: pixel.convex.com - -From the keyboard of flee@cs.psu.edu (Felix Lee): -:And Perl is definitely awkward with data types. I haven't yet found a -:pleasant way of shoving non-trivial data types into Perl's grammar. - -Yes, it's pretty awful at that, alright. Sometimes I write perl programs -that need them, and sometimes it just takes a little creativity. But -sometimes it's not worth it. I actually wrote a C program the other day -(gasp) because I didn't want to deal with a game matrix with six links per node. - -:Here's a very simple problem that's tricky to express in Perl: process -:the output of "du" to produce output that's indented to reflect the -:tree structure, and with each subtree sorted by size. Something like: -: 434 /etc -: | 344 . -: | 50 install -: | 35 uucp -: | 3 nserve -: | | 2 . -: | | 1 auth.info -: | 1 sm -: | 1 sm.bak - -At first I thought I could just keep one local list around -at once, but this seems inherently recursive. Which means -I need an real recursive data structure. Maybe you could -do it with one of the %assoc arrays Larry uses in the begat -programs, but I broke down and got dirty. I think the hardest -part was matching Felix's desired output exactly. It's not -blazingly fast: I should probably inline the &childof routine, -but it *was* faster to write than I could have written the -equivalent C program. - - ---tom - --- -"GUIs normally make it simple to accomplish simple actions and impossible -to accomplish complex actions." --Doug Gwyn (22/Jun/91 in comp.unix.wizards) - - Tom Christiansen tchrist@convex.com convex!tchrist - diff --git a/Tools/scripts/dutree.py b/Tools/scripts/dutree.py deleted file mode 100755 index d25cf72b707..00000000000 --- a/Tools/scripts/dutree.py +++ /dev/null @@ -1,60 +0,0 @@ -#! /usr/bin/env python3 -# Format du output in a tree shape - -import os, sys, errno - -def main(): - total, d = None, {} - with os.popen('du ' + ' '.join(sys.argv[1:])) as p: - for line in p: - i = 0 - while line[i] in '0123456789': i = i+1 - size = eval(line[:i]) - while line[i] in ' \t': i = i+1 - filename = line[i:-1] - comps = filename.split('/') - if comps[0] == '': comps[0] = '/' - if comps[len(comps)-1] == '': del comps[len(comps)-1] - total, d = store(size, comps, total, d) - try: - display(total, d) - except IOError as e: - if e.errno != errno.EPIPE: - raise - -def store(size, comps, total, d): - if comps == []: - return size, d - if comps[0] not in d: - d[comps[0]] = None, {} - t1, d1 = d[comps[0]] - d[comps[0]] = store(size, comps[1:], t1, d1) - return total, d - -def display(total, d): - show(total, d, '') - -def show(total, d, prefix): - if not d: return - list = [] - sum = 0 - for key in d.keys(): - tsub, dsub = d[key] - list.append((tsub, key)) - if tsub is not None: sum = sum + tsub -## if sum < total: -## list.append((total - sum, os.curdir)) - list.sort() - list.reverse() - width = len(repr(list[0][0])) - for tsub, key in list: - if tsub is None: - psub = prefix - else: - print(prefix + repr(tsub).rjust(width) + ' ' + key) - psub = prefix + ' '*(width-1) + '|' + ' '*(len(key)+1) - if key in d: - show(tsub, d[key][1], psub) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/eptags.py b/Tools/scripts/eptags.py deleted file mode 100755 index 7f8059ba71a..00000000000 --- a/Tools/scripts/eptags.py +++ /dev/null @@ -1,57 +0,0 @@ -#! /usr/bin/env python3 -"""Create a TAGS file for Python programs, usable with GNU Emacs. - -usage: eptags pyfiles... - -The output TAGS file is usable with Emacs version 18, 19, 20. -Tagged are: - - functions (even inside other defs or classes) - - classes - -eptags warns about files it cannot open. -eptags will not give warnings about duplicate tags. - -BUGS: - Because of tag duplication (methods with the same name in different - classes), TAGS files are not very useful for most object-oriented - python projects. -""" -import sys,re - -expr = r'^[ \t]*(def|class)[ \t]+([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*[:\(]' -matcher = re.compile(expr) - -def treat_file(filename, outfp): - """Append tags found in file named 'filename' to the open file 'outfp'""" - try: - fp = open(filename, 'r') - except OSError: - sys.stderr.write('Cannot open %s\n'%filename) - return - with fp: - charno = 0 - lineno = 0 - tags = [] - size = 0 - while 1: - line = fp.readline() - if not line: - break - lineno = lineno + 1 - m = matcher.search(line) - if m: - tag = m.group(0) + '\177%d,%d\n' % (lineno, charno) - tags.append(tag) - size = size + len(tag) - charno = charno + len(line) - outfp.write('\f\n%s,%d\n' % (filename,size)) - for tag in tags: - outfp.write(tag) - -def main(): - with open('TAGS', 'w') as outfp: - for filename in sys.argv[1:]: - treat_file(filename, outfp) - -if __name__=="__main__": - main() diff --git a/Tools/scripts/find-uname.py b/Tools/scripts/find-uname.py deleted file mode 100755 index b6ec1b6d790..00000000000 --- a/Tools/scripts/find-uname.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python3 - -""" -For each argument on the command line, look for it in the set of all Unicode -names. Arguments are treated as case-insensitive regular expressions, e.g.: - - % find-uname 'small letter a$' 'horizontal line' - *** small letter a$ matches *** - LATIN SMALL LETTER A (97) - COMBINING LATIN SMALL LETTER A (867) - CYRILLIC SMALL LETTER A (1072) - PARENTHESIZED LATIN SMALL LETTER A (9372) - CIRCLED LATIN SMALL LETTER A (9424) - FULLWIDTH LATIN SMALL LETTER A (65345) - *** horizontal line matches *** - HORIZONTAL LINE EXTENSION (9135) -""" - -import unicodedata -import sys -import re - -def main(args): - unicode_names = [] - for ix in range(sys.maxunicode+1): - try: - unicode_names.append((ix, unicodedata.name(chr(ix)))) - except ValueError: # no name for the character - pass - for arg in args: - pat = re.compile(arg, re.I) - matches = [(y,x) for (x,y) in unicode_names - if pat.search(y) is not None] - if matches: - print("***", arg, "matches", "***") - for match in matches: - print("%s (%d)" % match) - -if __name__ == "__main__": - main(sys.argv[1:]) diff --git a/Tools/scripts/find_recursionlimit.py b/Tools/scripts/find_recursionlimit.py deleted file mode 100755 index b2842a62efd..00000000000 --- a/Tools/scripts/find_recursionlimit.py +++ /dev/null @@ -1,128 +0,0 @@ -#! /usr/bin/env python3 -"""Find the maximum recursion limit that prevents interpreter termination. - -This script finds the maximum safe recursion limit on a particular -platform. If you need to change the recursion limit on your system, -this script will tell you a safe upper bound. To use the new limit, -call sys.setrecursionlimit(). - -This module implements several ways to create infinite recursion in -Python. Different implementations end up pushing different numbers of -C stack frames, depending on how many calls through Python's abstract -C API occur. - -After each round of tests, it prints a message: -"Limit of NNNN is fine". - -The highest printed value of "NNNN" is therefore the highest potentially -safe limit for your system (which depends on the OS, architecture, but also -the compilation flags). Please note that it is practically impossible to -test all possible recursion paths in the interpreter, so the results of -this test should not be trusted blindly -- although they give a good hint -of which values are reasonable. - -NOTE: When the C stack space allocated by your system is exceeded due -to excessive recursion, exact behaviour depends on the platform, although -the interpreter will always fail in a likely brutal way: either a -segmentation fault, a MemoryError, or just a silent abort. - -NB: A program that does not use __methods__ can set a higher limit. -""" - -import sys -import itertools - -class RecursiveBlowup1: - def __init__(self): - self.__init__() - -def test_init(): - return RecursiveBlowup1() - -class RecursiveBlowup2: - def __repr__(self): - return repr(self) - -def test_repr(): - return repr(RecursiveBlowup2()) - -class RecursiveBlowup4: - def __add__(self, x): - return x + self - -def test_add(): - return RecursiveBlowup4() + RecursiveBlowup4() - -class RecursiveBlowup5: - def __getattr__(self, attr): - return getattr(self, attr) - -def test_getattr(): - return RecursiveBlowup5().attr - -class RecursiveBlowup6: - def __getitem__(self, item): - return self[item - 2] + self[item - 1] - -def test_getitem(): - return RecursiveBlowup6()[5] - -def test_recurse(): - return test_recurse() - -def test_cpickle(_cache={}): - import io - try: - import _pickle - except ImportError: - print("cannot import _pickle, skipped!") - return - k, l = None, None - for n in itertools.count(): - try: - l = _cache[n] - continue # Already tried and it works, let's save some time - except KeyError: - for i in range(100): - l = [k, l] - k = {i: l} - _pickle.Pickler(io.BytesIO(), protocol=-1).dump(l) - _cache[n] = l - -def test_compiler_recursion(): - # The compiler uses a scaling factor to support additional levels - # of recursion. This is a sanity check of that scaling to ensure - # it still raises RecursionError even at higher recursion limits - compile("()" * (10 * sys.getrecursionlimit()), "", "single") - -def check_limit(n, test_func_name): - sys.setrecursionlimit(n) - if test_func_name.startswith("test_"): - print(test_func_name[5:]) - else: - print(test_func_name) - test_func = globals()[test_func_name] - try: - test_func() - # AttributeError can be raised because of the way e.g. PyDict_GetItem() - # silences all exceptions and returns NULL, which is usually interpreted - # as "missing attribute". - except (RecursionError, AttributeError): - pass - else: - print("Yikes!") - -if __name__ == '__main__': - - limit = 1000 - while 1: - check_limit(limit, "test_recurse") - check_limit(limit, "test_add") - check_limit(limit, "test_repr") - check_limit(limit, "test_init") - check_limit(limit, "test_getattr") - check_limit(limit, "test_getitem") - check_limit(limit, "test_cpickle") - check_limit(limit, "test_compiler_recursion") - print("Limit of %d is fine" % limit) - limit = limit + 100 diff --git a/Tools/scripts/finddiv.py b/Tools/scripts/finddiv.py deleted file mode 100755 index d21253cf1c8..00000000000 --- a/Tools/scripts/finddiv.py +++ /dev/null @@ -1,89 +0,0 @@ -#! /usr/bin/env python3 - -"""finddiv - a grep-like tool that looks for division operators. - -Usage: finddiv [-l] file_or_directory ... - -For directory arguments, all files in the directory whose name ends in -.py are processed, and subdirectories are processed recursively. - -This actually tokenizes the files to avoid false hits in comments or -strings literals. - -By default, this prints all lines containing a / or /= operator, in -grep -n style. With the -l option specified, it prints the filename -of files that contain at least one / or /= operator. -""" - -import os -import sys -import getopt -import tokenize - -def main(): - try: - opts, args = getopt.getopt(sys.argv[1:], "lh") - except getopt.error as msg: - usage(msg) - return 2 - if not args: - usage("at least one file argument is required") - return 2 - listnames = 0 - for o, a in opts: - if o == "-h": - print(__doc__) - return - if o == "-l": - listnames = 1 - exit = None - for filename in args: - x = process(filename, listnames) - exit = exit or x - return exit - -def usage(msg): - sys.stderr.write("%s: %s\n" % (sys.argv[0], msg)) - sys.stderr.write("Usage: %s [-l] file ...\n" % sys.argv[0]) - sys.stderr.write("Try `%s -h' for more information.\n" % sys.argv[0]) - -def process(filename, listnames): - if os.path.isdir(filename): - return processdir(filename, listnames) - try: - fp = open(filename) - except IOError as msg: - sys.stderr.write("Can't open: %s\n" % msg) - return 1 - with fp: - g = tokenize.generate_tokens(fp.readline) - lastrow = None - for type, token, (row, col), end, line in g: - if token in ("/", "/="): - if listnames: - print(filename) - break - if row != lastrow: - lastrow = row - print("%s:%d:%s" % (filename, row, line), end=' ') - -def processdir(dir, listnames): - try: - names = os.listdir(dir) - except OSError as msg: - sys.stderr.write("Can't list directory: %s\n" % dir) - return 1 - files = [] - for name in names: - fn = os.path.join(dir, name) - if os.path.normcase(fn).endswith(".py") or os.path.isdir(fn): - files.append(fn) - files.sort(key=os.path.normcase) - exit = None - for fn in files: - x = process(fn, listnames) - exit = exit or x - return exit - -if __name__ == "__main__": - sys.exit(main()) diff --git a/Tools/scripts/findlinksto.py b/Tools/scripts/findlinksto.py deleted file mode 100755 index b924f27b095..00000000000 --- a/Tools/scripts/findlinksto.py +++ /dev/null @@ -1,43 +0,0 @@ -#! /usr/bin/env python3 - -# findlinksto -# -# find symbolic links to a path matching a regular expression - -import os -import sys -import re -import getopt - -def main(): - try: - opts, args = getopt.getopt(sys.argv[1:], '') - if len(args) < 2: - raise getopt.GetoptError('not enough arguments', None) - except getopt.GetoptError as msg: - sys.stdout = sys.stderr - print(msg) - print('usage: findlinksto pattern directory ...') - sys.exit(2) - pat, dirs = args[0], args[1:] - prog = re.compile(pat) - for dirname in dirs: - os.walk(dirname, visit, prog) - -def visit(prog, dirname, names): - if os.path.islink(dirname): - names[:] = [] - return - if os.path.ismount(dirname): - print('descend into', dirname) - for name in names: - name = os.path.join(dirname, name) - try: - linkto = os.readlink(name) - if prog.search(linkto) is not None: - print(name, '->', linkto) - except OSError: - pass - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/findnocoding.py b/Tools/scripts/findnocoding.py deleted file mode 100755 index 6c16b1ce151..00000000000 --- a/Tools/scripts/findnocoding.py +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/env python3 - -"""List all those Python files that require a coding directive - -Usage: findnocoding.py dir1 [dir2...] -""" - -__author__ = "Oleg Broytmann, Georg Brandl" - -import sys, os, re, getopt - -# our pysource module finds Python source files -try: - import pysource -except ImportError: - # emulate the module with a simple os.walk - class pysource: - has_python_ext = looks_like_python = can_be_compiled = None - def walk_python_files(self, paths, *args, **kwargs): - for path in paths: - if os.path.isfile(path): - yield path.endswith(".py") - elif os.path.isdir(path): - for root, dirs, files in os.walk(path): - for filename in files: - if filename.endswith(".py"): - yield os.path.join(root, filename) - pysource = pysource() - - - print("The pysource module is not available; " - "no sophisticated Python source file search will be done.", file=sys.stderr) - - -decl_re = re.compile(rb'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)') -blank_re = re.compile(rb'^[ \t\f]*(?:[#\r\n]|$)') - -def get_declaration(line): - match = decl_re.match(line) - if match: - return match.group(1) - return b'' - -def has_correct_encoding(text, codec): - try: - str(text, codec) - except UnicodeDecodeError: - return False - else: - return True - -def needs_declaration(fullpath): - try: - infile = open(fullpath, 'rb') - except IOError: # Oops, the file was removed - ignore it - return None - - with infile: - line1 = infile.readline() - line2 = infile.readline() - - if (get_declaration(line1) or - blank_re.match(line1) and get_declaration(line2)): - # the file does have an encoding declaration, so trust it - return False - - # check the whole file for non utf-8 characters - rest = infile.read() - - if has_correct_encoding(line1+line2+rest, "utf-8"): - return False - - return True - - -usage = """Usage: %s [-cd] paths... - -c: recognize Python source files trying to compile them - -d: debug output""" % sys.argv[0] - -if __name__ == '__main__': - - try: - opts, args = getopt.getopt(sys.argv[1:], 'cd') - except getopt.error as msg: - print(msg, file=sys.stderr) - print(usage, file=sys.stderr) - sys.exit(1) - - is_python = pysource.looks_like_python - debug = False - - for o, a in opts: - if o == '-c': - is_python = pysource.can_be_compiled - elif o == '-d': - debug = True - - if not args: - print(usage, file=sys.stderr) - sys.exit(1) - - for fullpath in pysource.walk_python_files(args, is_python): - if debug: - print("Testing for coding: %s" % fullpath) - result = needs_declaration(fullpath) - if result: - print(fullpath) diff --git a/Tools/scripts/fixcid.py b/Tools/scripts/fixcid.py deleted file mode 100755 index 8f35eaeeb4f..00000000000 --- a/Tools/scripts/fixcid.py +++ /dev/null @@ -1,316 +0,0 @@ -#! /usr/bin/env python3 - -# Perform massive identifier substitution on C source files. -# This actually tokenizes the files (to some extent) so it can -# avoid making substitutions inside strings or comments. -# Inside strings, substitutions are never made; inside comments, -# it is a user option (off by default). -# -# The substitutions are read from one or more files whose lines, -# when not empty, after stripping comments starting with #, -# must contain exactly two words separated by whitespace: the -# old identifier and its replacement. -# -# The option -r reverses the sense of the substitutions (this may be -# useful to undo a particular substitution). -# -# If the old identifier is prefixed with a '*' (with no intervening -# whitespace), then it will not be substituted inside comments. -# -# Command line arguments are files or directories to be processed. -# Directories are searched recursively for files whose name looks -# like a C file (ends in .h or .c). The special filename '-' means -# operate in filter mode: read stdin, write stdout. -# -# Symbolic links are always ignored (except as explicit directory -# arguments). -# -# The original files are kept as back-up with a "~" suffix. -# -# Changes made are reported to stdout in a diff-like format. -# -# NB: by changing only the function fixline() you can turn this -# into a program for different changes to C source files; by -# changing the function wanted() you can make a different selection of -# files. - -import sys -import re -import os -from stat import * -import getopt - -err = sys.stderr.write -dbg = err -rep = sys.stdout.write - -def usage(): - progname = sys.argv[0] - err('Usage: ' + progname + - ' [-c] [-r] [-s file] ... file-or-directory ...\n') - err('\n') - err('-c : substitute inside comments\n') - err('-r : reverse direction for following -s options\n') - err('-s substfile : add a file of substitutions\n') - err('\n') - err('Each non-empty non-comment line in a substitution file must\n') - err('contain exactly two words: an identifier and its replacement.\n') - err('Comments start with a # character and end at end of line.\n') - err('If an identifier is preceded with a *, it is not substituted\n') - err('inside a comment even when -c is specified.\n') - -def main(): - try: - opts, args = getopt.getopt(sys.argv[1:], 'crs:') - except getopt.error as msg: - err('Options error: ' + str(msg) + '\n') - usage() - sys.exit(2) - bad = 0 - if not args: # No arguments - usage() - sys.exit(2) - for opt, arg in opts: - if opt == '-c': - setdocomments() - if opt == '-r': - setreverse() - if opt == '-s': - addsubst(arg) - for arg in args: - if os.path.isdir(arg): - if recursedown(arg): bad = 1 - elif os.path.islink(arg): - err(arg + ': will not process symbolic links\n') - bad = 1 - else: - if fix(arg): bad = 1 - sys.exit(bad) - -# Change this regular expression to select a different set of files -Wanted = r'^[a-zA-Z0-9_]+\.[ch]$' -def wanted(name): - return re.match(Wanted, name) - -def recursedown(dirname): - dbg('recursedown(%r)\n' % (dirname,)) - bad = 0 - try: - names = os.listdir(dirname) - except OSError as msg: - err(dirname + ': cannot list directory: ' + str(msg) + '\n') - return 1 - names.sort() - subdirs = [] - for name in names: - if name in (os.curdir, os.pardir): continue - fullname = os.path.join(dirname, name) - if os.path.islink(fullname): pass - elif os.path.isdir(fullname): - subdirs.append(fullname) - elif wanted(name): - if fix(fullname): bad = 1 - for fullname in subdirs: - if recursedown(fullname): bad = 1 - return bad - -def fix(filename): -## dbg('fix(%r)\n' % (filename,)) - if filename == '-': - # Filter mode - f = sys.stdin - g = sys.stdout - else: - # File replacement mode - try: - f = open(filename, 'r') - except IOError as msg: - err(filename + ': cannot open: ' + str(msg) + '\n') - return 1 - head, tail = os.path.split(filename) - tempname = os.path.join(head, '@' + tail) - g = None - # If we find a match, we rewind the file and start over but - # now copy everything to a temp file. - lineno = 0 - initfixline() - while 1: - line = f.readline() - if not line: break - lineno = lineno + 1 - while line[-2:] == '\\\n': - nextline = f.readline() - if not nextline: break - line = line + nextline - lineno = lineno + 1 - newline = fixline(line) - if newline != line: - if g is None: - try: - g = open(tempname, 'w') - except IOError as msg: - f.close() - err(tempname+': cannot create: '+ - str(msg)+'\n') - return 1 - f.seek(0) - lineno = 0 - initfixline() - rep(filename + ':\n') - continue # restart from the beginning - rep(repr(lineno) + '\n') - rep('< ' + line) - rep('> ' + newline) - if g is not None: - g.write(newline) - - # End of file - if filename == '-': return 0 # Done in filter mode - f.close() - if not g: return 0 # No changes - g.close() - - # Finishing touch -- move files - - # First copy the file's mode to the temp file - try: - statbuf = os.stat(filename) - os.chmod(tempname, statbuf[ST_MODE] & 0o7777) - except OSError as msg: - err(tempname + ': warning: chmod failed (' + str(msg) + ')\n') - # Then make a backup of the original file as filename~ - try: - os.rename(filename, filename + '~') - except OSError as msg: - err(filename + ': warning: backup failed (' + str(msg) + ')\n') - # Now move the temp file to the original file - try: - os.rename(tempname, filename) - except OSError as msg: - err(filename + ': rename failed (' + str(msg) + ')\n') - return 1 - # Return success - return 0 - -# Tokenizing ANSI C (partly) - -Identifier = '(struct )?[a-zA-Z_][a-zA-Z0-9_]+' -String = r'"([^\n\\"]|\\.)*"' -Char = r"'([^\n\\']|\\.)*'" -CommentStart = r'/\*' -CommentEnd = r'\*/' - -Hexnumber = '0[xX][0-9a-fA-F]*[uUlL]*' -Octnumber = '0[0-7]*[uUlL]*' -Decnumber = '[1-9][0-9]*[uUlL]*' -Intnumber = Hexnumber + '|' + Octnumber + '|' + Decnumber -Exponent = '[eE][-+]?[0-9]+' -Pointfloat = r'([0-9]+\.[0-9]*|\.[0-9]+)(' + Exponent + r')?' -Expfloat = '[0-9]+' + Exponent -Floatnumber = Pointfloat + '|' + Expfloat -Number = Floatnumber + '|' + Intnumber - -# Anything else is an operator -- don't list this explicitly because of '/*' - -OutsideComment = (Identifier, Number, String, Char, CommentStart) -OutsideCommentPattern = '(' + '|'.join(OutsideComment) + ')' -OutsideCommentProgram = re.compile(OutsideCommentPattern) - -InsideComment = (Identifier, Number, CommentEnd) -InsideCommentPattern = '(' + '|'.join(InsideComment) + ')' -InsideCommentProgram = re.compile(InsideCommentPattern) - -def initfixline(): - global Program - Program = OutsideCommentProgram - -def fixline(line): - global Program -## print('-->', repr(line)) - i = 0 - while i < len(line): - match = Program.search(line, i) - if match is None: break - i = match.start() - found = match.group(0) -## if Program is InsideCommentProgram: print(end='... ') -## else: print(end=' ') -## print(found) - if len(found) == 2: - if found == '/*': - Program = InsideCommentProgram - elif found == '*/': - Program = OutsideCommentProgram - n = len(found) - if found in Dict: - subst = Dict[found] - if Program is InsideCommentProgram: - if not Docomments: - print('Found in comment:', found) - i = i + n - continue - if found in NotInComment: -## print(end='Ignored in comment: ') -## print(found, '-->', subst) -## print('Line:', line, end='') - subst = found -## else: -## print(end='Substituting in comment: ') -## print(found, '-->', subst) -## print('Line:', line, end='') - line = line[:i] + subst + line[i+n:] - n = len(subst) - i = i + n - return line - -Docomments = 0 -def setdocomments(): - global Docomments - Docomments = 1 - -Reverse = 0 -def setreverse(): - global Reverse - Reverse = (not Reverse) - -Dict = {} -NotInComment = {} -def addsubst(substfile): - try: - fp = open(substfile, 'r') - except IOError as msg: - err(substfile + ': cannot read substfile: ' + str(msg) + '\n') - sys.exit(1) - with fp: - lineno = 0 - while 1: - line = fp.readline() - if not line: break - lineno = lineno + 1 - try: - i = line.index('#') - except ValueError: - i = -1 # Happens to delete trailing \n - words = line[:i].split() - if not words: continue - if len(words) == 3 and words[0] == 'struct': - words[:2] = [words[0] + ' ' + words[1]] - elif len(words) != 2: - err(substfile + '%s:%r: warning: bad line: %r' % (substfile, lineno, line)) - continue - if Reverse: - [value, key] = words - else: - [key, value] = words - if value[0] == '*': - value = value[1:] - if key[0] == '*': - key = key[1:] - NotInComment[key] = value - if key in Dict: - err('%s:%r: warning: overriding: %r %r\n' % (substfile, lineno, key, value)) - err('%s:%r: warning: previous: %r\n' % (substfile, lineno, Dict[key])) - Dict[key] = value - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/fixdiv.py b/Tools/scripts/fixdiv.py deleted file mode 100755 index df7c481aa22..00000000000 --- a/Tools/scripts/fixdiv.py +++ /dev/null @@ -1,378 +0,0 @@ -#! /usr/bin/env python3 - -"""fixdiv - tool to fix division operators. - -To use this tool, first run `python -Qwarnall yourscript.py 2>warnings'. -This runs the script `yourscript.py' while writing warning messages -about all uses of the classic division operator to the file -`warnings'. The warnings look like this: - - :: DeprecationWarning: classic division - -The warnings are written to stderr, so you must use `2>' for the I/O -redirect. I know of no way to redirect stderr on Windows in a DOS -box, so you will have to modify the script to set sys.stderr to some -kind of log file if you want to do this on Windows. - -The warnings are not limited to the script; modules imported by the -script may also trigger warnings. In fact a useful technique is to -write a test script specifically intended to exercise all code in a -particular module or set of modules. - -Then run `python fixdiv.py warnings'. This first reads the warnings, -looking for classic division warnings, and sorts them by file name and -line number. Then, for each file that received at least one warning, -it parses the file and tries to match the warnings up to the division -operators found in the source code. If it is successful, it writes -its findings to stdout, preceded by a line of dashes and a line of the -form: - - Index: - -If the only findings found are suggestions to change a / operator into -a // operator, the output is acceptable input for the Unix 'patch' -program. - -Here are the possible messages on stdout (N stands for a line number): - -- A plain-diff-style change ('NcN', a line marked by '<', a line - containing '---', and a line marked by '>'): - - A / operator was found that should be changed to //. This is the - recommendation when only int and/or long arguments were seen. - -- 'True division / operator at line N' and a line marked by '=': - - A / operator was found that can remain unchanged. This is the - recommendation when only float and/or complex arguments were seen. - -- 'Ambiguous / operator (..., ...) at line N', line marked by '?': - - A / operator was found for which int or long as well as float or - complex arguments were seen. This is highly unlikely; if it occurs, - you may have to restructure the code to keep the classic semantics, - or maybe you don't care about the classic semantics. - -- 'No conclusive evidence on line N', line marked by '*': - - A / operator was found for which no warnings were seen. This could - be code that was never executed, or code that was only executed - with user-defined objects as arguments. You will have to - investigate further. Note that // can be overloaded separately from - /, using __floordiv__. True division can also be separately - overloaded, using __truediv__. Classic division should be the same - as either of those. (XXX should I add a warning for division on - user-defined objects, to disambiguate this case from code that was - never executed?) - -- 'Phantom ... warnings for line N', line marked by '*': - - A warning was seen for a line not containing a / operator. The most - likely cause is a warning about code executed by 'exec' or eval() - (see note below), or an indirect invocation of the / operator, for - example via the div() function in the operator module. It could - also be caused by a change to the file between the time the test - script was run to collect warnings and the time fixdiv was run. - -- 'More than one / operator in line N'; or - 'More than one / operator per statement in lines N-N': - - The scanner found more than one / operator on a single line, or in a - statement split across multiple lines. Because the warnings - framework doesn't (and can't) show the offset within the line, and - the code generator doesn't always give the correct line number for - operations in a multi-line statement, we can't be sure whether all - operators in the statement were executed. To be on the safe side, - by default a warning is issued about this case. In practice, these - cases are usually safe, and the -m option suppresses these warning. - -- 'Can't find the / operator in line N', line marked by '*': - - This really shouldn't happen. It means that the tokenize module - reported a '/' operator but the line it returns didn't contain a '/' - character at the indicated position. - -- 'Bad warning for line N: XYZ', line marked by '*': - - This really shouldn't happen. It means that a 'classic XYZ - division' warning was read with XYZ being something other than - 'int', 'long', 'float', or 'complex'. - -Notes: - -- The augmented assignment operator /= is handled the same way as the - / operator. - -- This tool never looks at the // operator; no warnings are ever - generated for use of this operator. - -- This tool never looks at the / operator when a future division - statement is in effect; no warnings are generated in this case, and - because the tool only looks at files for which at least one classic - division warning was seen, it will never look at files containing a - future division statement. - -- Warnings may be issued for code not read from a file, but executed - using the exec() or eval() functions. These may have - in the filename position, in which case the fixdiv script - will attempt and fail to open a file named '' and issue a - warning about this failure; or these may be reported as 'Phantom' - warnings (see above). You're on your own to deal with these. You - could make all recommended changes and add a future division - statement to all affected files, and then re-run the test script; it - should not issue any warnings. If there are any, and you have a - hard time tracking down where they are generated, you can use the - -Werror option to force an error instead of a first warning, - generating a traceback. - -- The tool should be run from the same directory as that from which - the original script was run, otherwise it won't be able to open - files given by relative pathnames. -""" - -import sys -import getopt -import re -import tokenize - -multi_ok = 0 - -def main(): - try: - opts, args = getopt.getopt(sys.argv[1:], "hm") - except getopt.error as msg: - usage(msg) - return 2 - for o, a in opts: - if o == "-h": - print(__doc__) - return - if o == "-m": - global multi_ok - multi_ok = 1 - if not args: - usage("at least one file argument is required") - return 2 - if args[1:]: - sys.stderr.write("%s: extra file arguments ignored\n", sys.argv[0]) - warnings = readwarnings(args[0]) - if warnings is None: - return 1 - files = list(warnings.keys()) - if not files: - print("No classic division warnings read from", args[0]) - return - files.sort() - exit = None - for filename in files: - x = process(filename, warnings[filename]) - exit = exit or x - return exit - -def usage(msg): - sys.stderr.write("%s: %s\n" % (sys.argv[0], msg)) - sys.stderr.write("Usage: %s [-m] warnings\n" % sys.argv[0]) - sys.stderr.write("Try `%s -h' for more information.\n" % sys.argv[0]) - -PATTERN = (r"^(.+?):(\d+): DeprecationWarning: " - r"classic (int|long|float|complex) division$") - -def readwarnings(warningsfile): - prog = re.compile(PATTERN) - warnings = {} - try: - f = open(warningsfile) - except IOError as msg: - sys.stderr.write("can't open: %s\n" % msg) - return - with f: - while 1: - line = f.readline() - if not line: - break - m = prog.match(line) - if not m: - if line.find("division") >= 0: - sys.stderr.write("Warning: ignored input " + line) - continue - filename, lineno, what = m.groups() - list = warnings.get(filename) - if list is None: - warnings[filename] = list = [] - list.append((int(lineno), sys.intern(what))) - return warnings - -def process(filename, list): - print("-"*70) - assert list # if this fails, readwarnings() is broken - try: - fp = open(filename) - except IOError as msg: - sys.stderr.write("can't open: %s\n" % msg) - return 1 - with fp: - print("Index:", filename) - f = FileContext(fp) - list.sort() - index = 0 # list[:index] has been processed, list[index:] is still to do - g = tokenize.generate_tokens(f.readline) - while 1: - startlineno, endlineno, slashes = lineinfo = scanline(g) - if startlineno is None: - break - assert startlineno <= endlineno is not None - orphans = [] - while index < len(list) and list[index][0] < startlineno: - orphans.append(list[index]) - index += 1 - if orphans: - reportphantomwarnings(orphans, f) - warnings = [] - while index < len(list) and list[index][0] <= endlineno: - warnings.append(list[index]) - index += 1 - if not slashes and not warnings: - pass - elif slashes and not warnings: - report(slashes, "No conclusive evidence") - elif warnings and not slashes: - reportphantomwarnings(warnings, f) - else: - if len(slashes) > 1: - if not multi_ok: - rows = [] - lastrow = None - for (row, col), line in slashes: - if row == lastrow: - continue - rows.append(row) - lastrow = row - assert rows - if len(rows) == 1: - print("*** More than one / operator in line", rows[0]) - else: - print("*** More than one / operator per statement", end=' ') - print("in lines %d-%d" % (rows[0], rows[-1])) - intlong = [] - floatcomplex = [] - bad = [] - for lineno, what in warnings: - if what in ("int", "long"): - intlong.append(what) - elif what in ("float", "complex"): - floatcomplex.append(what) - else: - bad.append(what) - lastrow = None - for (row, col), line in slashes: - if row == lastrow: - continue - lastrow = row - line = chop(line) - if line[col:col+1] != "/": - print("*** Can't find the / operator in line %d:" % row) - print("*", line) - continue - if bad: - print("*** Bad warning for line %d:" % row, bad) - print("*", line) - elif intlong and not floatcomplex: - print("%dc%d" % (row, row)) - print("<", line) - print("---") - print(">", line[:col] + "/" + line[col:]) - elif floatcomplex and not intlong: - print("True division / operator at line %d:" % row) - print("=", line) - elif intlong and floatcomplex: - print("*** Ambiguous / operator (%s, %s) at line %d:" % - ("|".join(intlong), "|".join(floatcomplex), row)) - print("?", line) - -def reportphantomwarnings(warnings, f): - blocks = [] - lastrow = None - lastblock = None - for row, what in warnings: - if row != lastrow: - lastblock = [row] - blocks.append(lastblock) - lastblock.append(what) - for block in blocks: - row = block[0] - whats = "/".join(block[1:]) - print("*** Phantom %s warnings for line %d:" % (whats, row)) - f.report(row, mark="*") - -def report(slashes, message): - lastrow = None - for (row, col), line in slashes: - if row != lastrow: - print("*** %s on line %d:" % (message, row)) - print("*", chop(line)) - lastrow = row - -class FileContext: - def __init__(self, fp, window=5, lineno=1): - self.fp = fp - self.window = 5 - self.lineno = 1 - self.eoflookahead = 0 - self.lookahead = [] - self.buffer = [] - def fill(self): - while len(self.lookahead) < self.window and not self.eoflookahead: - line = self.fp.readline() - if not line: - self.eoflookahead = 1 - break - self.lookahead.append(line) - def readline(self): - self.fill() - if not self.lookahead: - return "" - line = self.lookahead.pop(0) - self.buffer.append(line) - self.lineno += 1 - return line - def __getitem__(self, index): - self.fill() - bufstart = self.lineno - len(self.buffer) - lookend = self.lineno + len(self.lookahead) - if bufstart <= index < self.lineno: - return self.buffer[index - bufstart] - if self.lineno <= index < lookend: - return self.lookahead[index - self.lineno] - raise KeyError - def report(self, first, last=None, mark="*"): - if last is None: - last = first - for i in range(first, last+1): - try: - line = self[first] - except KeyError: - line = "" - print(mark, chop(line)) - -def scanline(g): - slashes = [] - startlineno = None - endlineno = None - for type, token, start, end, line in g: - endlineno = end[0] - if startlineno is None: - startlineno = endlineno - if token in ("/", "/="): - slashes.append((start, line)) - if type == tokenize.NEWLINE: - break - return startlineno, endlineno, slashes - -def chop(line): - if line.endswith("\n"): - return line[:-1] - else: - return line - -if __name__ == "__main__": - sys.exit(main()) diff --git a/Tools/scripts/fixheader.py b/Tools/scripts/fixheader.py deleted file mode 100755 index c834eec1e20..00000000000 --- a/Tools/scripts/fixheader.py +++ /dev/null @@ -1,49 +0,0 @@ -#! /usr/bin/env python3 - -# Add some standard cpp magic to a header file - -import sys - -def main(): - args = sys.argv[1:] - for filename in args: - process(filename) - -def process(filename): - try: - f = open(filename, 'r') - except IOError as msg: - sys.stderr.write('%s: can\'t open: %s\n' % (filename, str(msg))) - return - with f: - data = f.read() - if data[:2] != '/*': - sys.stderr.write('%s does not begin with C comment\n' % filename) - return - try: - f = open(filename, 'w') - except IOError as msg: - sys.stderr.write('%s: can\'t write: %s\n' % (filename, str(msg))) - return - with f: - sys.stderr.write('Processing %s ...\n' % filename) - magic = 'Py_' - for c in filename: - if ord(c)<=0x80 and c.isalnum(): - magic = magic + c.upper() - else: magic = magic + '_' - print('#ifndef', magic, file=f) - print('#define', magic, file=f) - print('#ifdef __cplusplus', file=f) - print('extern "C" {', file=f) - print('#endif', file=f) - print(file=f) - f.write(data) - print(file=f) - print('#ifdef __cplusplus', file=f) - print('}', file=f) - print('#endif', file=f) - print('#endif /*', '!'+magic, '*/', file=f) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/fixnotice.py b/Tools/scripts/fixnotice.py deleted file mode 100755 index 317051dd82f..00000000000 --- a/Tools/scripts/fixnotice.py +++ /dev/null @@ -1,109 +0,0 @@ -#! /usr/bin/env python3 - -"""(Ostensibly) fix copyright notices in files. - -Actually, this script will simply replace a block of text in a file from one -string to another. It will only do this once though, i.e. not globally -throughout the file. It writes a backup file and then does an os.rename() -dance for atomicity. - -Usage: fixnotices.py [options] [filenames] -Options: - -h / --help - Print this message and exit - - --oldnotice=file - Use the notice in the file as the old (to be replaced) string, instead - of the hard coded value in the script. - - --newnotice=file - Use the notice in the file as the new (replacement) string, instead of - the hard coded value in the script. - - --dry-run - Don't actually make the changes, but print out the list of files that - would change. When used with -v, a status will be printed for every - file. - - -v / --verbose - Print a message for every file looked at, indicating whether the file - is changed or not. -""" - -OLD_NOTICE = """/*********************************************************** -Copyright (c) 2000, BeOpen.com. -Copyright (c) 1995-2000, Corporation for National Research Initiatives. -Copyright (c) 1990-1995, Stichting Mathematisch Centrum. -All rights reserved. - -See the file "Misc/COPYRIGHT" for information on usage and -redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. -******************************************************************/ -""" -import os -import sys -import getopt - -NEW_NOTICE = "" -DRYRUN = 0 -VERBOSE = 0 - - -def usage(code, msg=''): - print(__doc__ % globals()) - if msg: - print(msg) - sys.exit(code) - - -def main(): - global DRYRUN, OLD_NOTICE, NEW_NOTICE, VERBOSE - try: - opts, args = getopt.getopt(sys.argv[1:], 'hv', - ['help', 'oldnotice=', 'newnotice=', - 'dry-run', 'verbose']) - except getopt.error as msg: - usage(1, msg) - - for opt, arg in opts: - if opt in ('-h', '--help'): - usage(0) - elif opt in ('-v', '--verbose'): - VERBOSE = 1 - elif opt == '--dry-run': - DRYRUN = 1 - elif opt == '--oldnotice': - with open(arg) as fp: - OLD_NOTICE = fp.read() - elif opt == '--newnotice': - with open(arg) as fp: - NEW_NOTICE = fp.read() - - for arg in args: - process(arg) - - -def process(file): - with open(file) as f: - data = f.read() - i = data.find(OLD_NOTICE) - if i < 0: - if VERBOSE: - print('no change:', file) - return - elif DRYRUN or VERBOSE: - print(' change:', file) - if DRYRUN: - # Don't actually change the file - return - data = data[:i] + NEW_NOTICE + data[i+len(OLD_NOTICE):] - new = file + ".new" - backup = file + ".bak" - with open(new, "w") as f: - f.write(data) - os.rename(file, backup) - os.rename(new, file) - - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/fixps.py b/Tools/scripts/fixps.py deleted file mode 100755 index 725300e56a2..00000000000 --- a/Tools/scripts/fixps.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 - -# Fix Python script(s) to reference the interpreter via /usr/bin/env python. -# Warning: this overwrites the file without making a backup. - -import sys -import re - - -def main(): - for filename in sys.argv[1:]: - try: - f = open(filename, 'r') - except IOError as msg: - print(filename, ': can\'t open :', msg) - continue - with f: - line = f.readline() - if not re.match('^#! */usr/local/bin/python', line): - print(filename, ': not a /usr/local/bin/python script') - continue - rest = f.read() - line = re.sub('/usr/local/bin/python', - '/usr/bin/env python', line) - print(filename, ':', repr(line)) - with open(filename, "w") as f: - f.write(line) - f.write(rest) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/generate_opcode_h.py b/Tools/scripts/generate_opcode_h.py deleted file mode 100644 index 0ee4b95bbfd..00000000000 --- a/Tools/scripts/generate_opcode_h.py +++ /dev/null @@ -1,99 +0,0 @@ -# This script generates the opcode.h header file. - -import sys -import tokenize - -header = """ -/* Auto-generated by Tools/scripts/generate_opcode_h.py from Lib/opcode.py */ -#ifndef Py_OPCODE_H -#define Py_OPCODE_H -#ifdef __cplusplus -extern "C" { -#endif - - -/* Instruction opcodes for compiled code */ -""".lstrip() - -footer = """ -#define HAS_ARG(op) ((op) >= HAVE_ARGUMENT) - -/* Reserve some bytecodes for internal use in the compiler. - * The value of 240 is arbitrary. */ -#define IS_ARTIFICIAL(op) ((op) > 240) - -#ifdef __cplusplus -} -#endif -#endif /* !Py_OPCODE_H */ -""" - -DEFINE = "#define {:<31} {:>3}\n" - -UINT32_MASK = (1<<32)-1 - -def write_int_array_from_ops(name, ops, out): - bits = 0 - for op in ops: - bits |= 1<>= 32 - assert bits == 0 - out.write(f"}};\n") - -def main(opcode_py, outfile='Include/opcode.h'): - opcode = {} - if hasattr(tokenize, 'open'): - fp = tokenize.open(opcode_py) # Python 3.2+ - else: - fp = open(opcode_py) # Python 2.7 - with fp: - code = fp.read() - exec(code, opcode) - opmap = opcode['opmap'] - hasconst = opcode['hasconst'] - hasjrel = opcode['hasjrel'] - hasjabs = opcode['hasjabs'] - used = [ False ] * 256 - next_op = 1 - for name, op in opmap.items(): - used[op] = True - with open(outfile, 'w') as fobj: - fobj.write(header) - for name in opcode['opname']: - if name in opmap: - fobj.write(DEFINE.format(name, opmap[name])) - if name == 'POP_EXCEPT': # Special entry for HAVE_ARGUMENT - fobj.write(DEFINE.format("HAVE_ARGUMENT", opcode["HAVE_ARGUMENT"])) - - for name in opcode['_specialized_instructions']: - while used[next_op]: - next_op += 1 - fobj.write(DEFINE.format(name, next_op)) - used[next_op] = True - fobj.write(DEFINE.format('DO_TRACING', 255)) - fobj.write("#ifdef NEED_OPCODE_JUMP_TABLES\n") - write_int_array_from_ops("_PyOpcode_RelativeJump", opcode['hasjrel'], fobj) - write_int_array_from_ops("_PyOpcode_Jump", opcode['hasjrel'] + opcode['hasjabs'], fobj) - fobj.write("#endif /* OPCODE_TABLES */\n") - - fobj.write("\n") - fobj.write("#define HAS_CONST(op) (false\\") - for op in hasconst: - fobj.write(f"\n || ((op) == {op}) \\") - fobj.write("\n )\n") - - fobj.write("\n") - for i, (op, _) in enumerate(opcode["_nb_ops"]): - fobj.write(DEFINE.format(op, i)) - - fobj.write(footer) - - - print(f"{outfile} regenerated from {opcode_py}") - - -if __name__ == '__main__': - main(sys.argv[1], sys.argv[2]) diff --git a/Tools/scripts/get-remote-certificate.py b/Tools/scripts/get-remote-certificate.py deleted file mode 100755 index 38901286e19..00000000000 --- a/Tools/scripts/get-remote-certificate.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python3 -# -# fetch the certificate that the server(s) are providing in PEM form -# -# args are HOST:PORT [, HOST:PORT...] -# -# By Bill Janssen. - -import re -import os -import sys -import tempfile - - -def fetch_server_certificate (host, port): - - def subproc(cmd): - from subprocess import Popen, PIPE, STDOUT - proc = Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True) - status = proc.wait() - output = proc.stdout.read() - return status, output - - def strip_to_x509_cert(certfile_contents, outfile=None): - m = re.search(br"^([-]+BEGIN CERTIFICATE[-]+[\r]*\n" - br".*[\r]*^[-]+END CERTIFICATE[-]+)$", - certfile_contents, re.MULTILINE | re.DOTALL) - if not m: - return None - else: - tn = tempfile.mktemp() - with open(tn, "wb") as fp: - fp.write(m.group(1) + b"\n") - try: - tn2 = (outfile or tempfile.mktemp()) - status, output = subproc(r'openssl x509 -in "%s" -out "%s"' % - (tn, tn2)) - if status != 0: - raise RuntimeError('OpenSSL x509 failed with status %s and ' - 'output: %r' % (status, output)) - with open(tn2, 'rb') as fp: - data = fp.read() - os.unlink(tn2) - return data - finally: - os.unlink(tn) - - if sys.platform.startswith("win"): - tfile = tempfile.mktemp() - with open(tfile, "w") as fp: - fp.write("quit\n") - try: - status, output = subproc( - 'openssl s_client -connect "%s:%s" -showcerts < "%s"' % - (host, port, tfile)) - finally: - os.unlink(tfile) - else: - status, output = subproc( - 'openssl s_client -connect "%s:%s" -showcerts < /dev/null' % - (host, port)) - if status != 0: - raise RuntimeError('OpenSSL connect failed with status %s and ' - 'output: %r' % (status, output)) - certtext = strip_to_x509_cert(output) - if not certtext: - raise ValueError("Invalid response received from server at %s:%s" % - (host, port)) - return certtext - - -if __name__ == "__main__": - if len(sys.argv) < 2: - sys.stderr.write( - "Usage: %s HOSTNAME:PORTNUMBER [, HOSTNAME:PORTNUMBER...]\n" % - sys.argv[0]) - sys.exit(1) - for arg in sys.argv[1:]: - host, port = arg.split(":") - sys.stdout.buffer.write(fetch_server_certificate(host, int(port))) - sys.exit(0) diff --git a/Tools/scripts/google.py b/Tools/scripts/google.py deleted file mode 100755 index 82fb2871885..00000000000 --- a/Tools/scripts/google.py +++ /dev/null @@ -1,25 +0,0 @@ -#! /usr/bin/env python3 - -"""Script to search with Google - -Usage: - python3 google.py [search terms] -""" - -import sys -import urllib.parse -import webbrowser - - -def main(args): - def quote(arg): - if ' ' in arg: - arg = '"%s"' % arg - return urllib.parse.quote_plus(arg) - - qstring = '+'.join(quote(arg) for arg in args) - url = urllib.parse.urljoin('https://www.google.com/search', '?q=' + qstring) - webbrowser.open(url) - -if __name__ == '__main__': - main(sys.argv[1:]) diff --git a/Tools/scripts/gprof2html.py b/Tools/scripts/gprof2html.py deleted file mode 100755 index bf0530ef3e4..00000000000 --- a/Tools/scripts/gprof2html.py +++ /dev/null @@ -1,87 +0,0 @@ -#! /usr/bin/env python3 - -"""Transform gprof(1) output into useful HTML.""" - -import html -import os -import re -import sys -import webbrowser - -header = """\ - - - gprof output (%s) - - -
    -"""
    -
    -trailer = """\
    -
    - - -""" - -def add_escapes(filename): - with open(filename, encoding="utf-8") as fp: - for line in fp: - yield html.escape(line) - -def gprof2html(input, output, filename): - output.write(header % filename) - for line in input: - output.write(line) - if line.startswith(" time"): - break - labels = {} - for line in input: - m = re.match(r"(.* )(\w+)\n", line) - if not m: - output.write(line) - break - stuff, fname = m.group(1, 2) - labels[fname] = fname - output.write('%s%s\n' % - (stuff, fname, fname, fname)) - for line in input: - output.write(line) - if line.startswith("index % time"): - break - for line in input: - m = re.match(r"(.* )(\w+)(( <cycle.*>)? \[\d+\])\n", line) - if not m: - output.write(line) - if line.startswith("Index by function name"): - break - continue - prefix, fname, suffix = m.group(1, 2, 3) - if fname not in labels: - output.write(line) - continue - if line.startswith("["): - output.write('%s%s%s\n' % - (prefix, fname, fname, fname, suffix)) - else: - output.write('%s%s%s\n' % - (prefix, fname, fname, suffix)) - for line in input: - for part in re.findall(r"(\w+(?:\.c)?|\W+)", line): - if part in labels: - part = '%s' % (part, part) - output.write(part) - output.write(trailer) - - -def main(): - filename = "gprof.out" - if sys.argv[1:]: - filename = sys.argv[1] - outputfilename = filename + ".html" - input = add_escapes(filename) - with open(outputfilename, "w", encoding="utf-8") as output: - gprof2html(input, output, filename) - webbrowser.open("file:" + os.path.abspath(outputfilename)) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/highlight.py b/Tools/scripts/highlight.py deleted file mode 100755 index 9272fee4ee3..00000000000 --- a/Tools/scripts/highlight.py +++ /dev/null @@ -1,265 +0,0 @@ -#!/usr/bin/env python3 -'''Add syntax highlighting to Python source code''' - -__author__ = 'Raymond Hettinger' - -import builtins -import functools -import html as html_module -import keyword -import re -import tokenize - -#### Analyze Python Source ################################# - -def is_builtin(s): - 'Return True if s is the name of a builtin' - return hasattr(builtins, s) - -def combine_range(lines, start, end): - 'Join content from a range of lines between start and end' - (srow, scol), (erow, ecol) = start, end - if srow == erow: - return lines[srow-1][scol:ecol], end - rows = [lines[srow-1][scol:]] + lines[srow: erow-1] + [lines[erow-1][:ecol]] - return ''.join(rows), end - -def analyze_python(source): - '''Generate and classify chunks of Python for syntax highlighting. - Yields tuples in the form: (category, categorized_text). - ''' - lines = source.splitlines(True) - lines.append('') - readline = functools.partial(next, iter(lines), '') - kind = tok_str = '' - tok_type = tokenize.COMMENT - written = (1, 0) - for tok in tokenize.generate_tokens(readline): - prev_tok_type, prev_tok_str = tok_type, tok_str - tok_type, tok_str, (srow, scol), (erow, ecol), logical_lineno = tok - kind = '' - if tok_type == tokenize.COMMENT: - kind = 'comment' - elif tok_type == tokenize.OP and tok_str[:1] not in '{}[](),.:;@': - kind = 'operator' - elif tok_type == tokenize.STRING: - kind = 'string' - if prev_tok_type == tokenize.INDENT or scol==0: - kind = 'docstring' - elif tok_type == tokenize.NAME: - if tok_str in ('def', 'class', 'import', 'from'): - kind = 'definition' - elif prev_tok_str in ('def', 'class'): - kind = 'defname' - elif keyword.iskeyword(tok_str): - kind = 'keyword' - elif is_builtin(tok_str) and prev_tok_str != '.': - kind = 'builtin' - if kind: - text, written = combine_range(lines, written, (srow, scol)) - yield '', text - text, written = tok_str, (erow, ecol) - yield kind, text - line_upto_token, written = combine_range(lines, written, (erow, ecol)) - yield '', line_upto_token - -#### Raw Output ########################################### - -def raw_highlight(classified_text): - 'Straight text display of text classifications' - result = [] - for kind, text in classified_text: - result.append('%15s: %r\n' % (kind or 'plain', text)) - return ''.join(result) - -#### ANSI Output ########################################### - -default_ansi = { - 'comment': ('\033[0;31m', '\033[0m'), - 'string': ('\033[0;32m', '\033[0m'), - 'docstring': ('\033[0;32m', '\033[0m'), - 'keyword': ('\033[0;33m', '\033[0m'), - 'builtin': ('\033[0;35m', '\033[0m'), - 'definition': ('\033[0;33m', '\033[0m'), - 'defname': ('\033[0;34m', '\033[0m'), - 'operator': ('\033[0;33m', '\033[0m'), -} - -def ansi_highlight(classified_text, colors=default_ansi): - 'Add syntax highlighting to source code using ANSI escape sequences' - # http://en.wikipedia.org/wiki/ANSI_escape_code - result = [] - for kind, text in classified_text: - opener, closer = colors.get(kind, ('', '')) - result += [opener, text, closer] - return ''.join(result) - -#### HTML Output ########################################### - -def html_highlight(classified_text,opener='
    \n', closer='
    \n'): - 'Convert classified text to an HTML fragment' - result = [opener] - for kind, text in classified_text: - if kind: - result.append('' % kind) - result.append(html_module.escape(text)) - if kind: - result.append('') - result.append(closer) - return ''.join(result) - -default_css = { - '.comment': '{color: crimson;}', - '.string': '{color: forestgreen;}', - '.docstring': '{color: forestgreen; font-style:italic;}', - '.keyword': '{color: darkorange;}', - '.builtin': '{color: purple;}', - '.definition': '{color: darkorange; font-weight:bold;}', - '.defname': '{color: blue;}', - '.operator': '{color: brown;}', -} - -default_html = '''\ - - - - - {title} - - - -{body} - - -''' - -def build_html_page(classified_text, title='python', - css=default_css, html=default_html): - 'Create a complete HTML page with colorized source code' - css_str = '\n'.join(['%s %s' % item for item in css.items()]) - result = html_highlight(classified_text) - title = html_module.escape(title) - return html.format(title=title, css=css_str, body=result) - -#### LaTeX Output ########################################## - -default_latex_commands = { - 'comment': r'{\color{red}#1}', - 'string': r'{\color{ForestGreen}#1}', - 'docstring': r'{\emph{\color{ForestGreen}#1}}', - 'keyword': r'{\color{orange}#1}', - 'builtin': r'{\color{purple}#1}', - 'definition': r'{\color{orange}#1}', - 'defname': r'{\color{blue}#1}', - 'operator': r'{\color{brown}#1}', -} - -default_latex_document = r''' -\documentclass{article} -\usepackage{alltt} -\usepackage{upquote} -\usepackage{color} -\usepackage[usenames,dvipsnames]{xcolor} -\usepackage[cm]{fullpage} -%(macros)s -\begin{document} -\center{\LARGE{%(title)s}} -\begin{alltt} -%(body)s -\end{alltt} -\end{document} -''' - -def alltt_escape(s): - 'Replace backslash and braces with their escaped equivalents' - xlat = {'{': r'\{', '}': r'\}', '\\': r'\textbackslash{}'} - return re.sub(r'[\\{}]', lambda mo: xlat[mo.group()], s) - -def latex_highlight(classified_text, title = 'python', - commands = default_latex_commands, - document = default_latex_document): - 'Create a complete LaTeX document with colorized source code' - macros = '\n'.join(r'\newcommand{\py%s}[1]{%s}' % c for c in commands.items()) - result = [] - for kind, text in classified_text: - if kind: - result.append(r'\py%s{' % kind) - result.append(alltt_escape(text)) - if kind: - result.append('}') - return default_latex_document % dict(title=title, macros=macros, body=''.join(result)) - - -if __name__ == '__main__': - import argparse - import os.path - import sys - import textwrap - import webbrowser - - parser = argparse.ArgumentParser( - description = 'Add syntax highlighting to Python source code', - formatter_class=argparse.RawDescriptionHelpFormatter, - epilog = textwrap.dedent(''' - examples: - - # Show syntax highlighted code in the terminal window - $ ./highlight.py myfile.py - - # Colorize myfile.py and display in a browser - $ ./highlight.py -b myfile.py - - # Create an HTML section to embed in an existing webpage - ./highlight.py -s myfile.py - - # Create a complete HTML file - $ ./highlight.py -c myfile.py > myfile.html - - # Create a PDF using LaTeX - $ ./highlight.py -l myfile.py | pdflatex - - ''')) - parser.add_argument('sourcefile', metavar = 'SOURCEFILE', - help = 'file containing Python sourcecode') - parser.add_argument('-b', '--browser', action = 'store_true', - help = 'launch a browser to show results') - parser.add_argument('-c', '--complete', action = 'store_true', - help = 'build a complete html webpage') - parser.add_argument('-l', '--latex', action = 'store_true', - help = 'build a LaTeX document') - parser.add_argument('-r', '--raw', action = 'store_true', - help = 'raw parse of categorized text') - parser.add_argument('-s', '--section', action = 'store_true', - help = 'show an HTML section rather than a complete webpage') - args = parser.parse_args() - - if args.section and (args.browser or args.complete): - parser.error('The -s/--section option is incompatible with ' - 'the -b/--browser or -c/--complete options') - - sourcefile = args.sourcefile - with open(sourcefile) as f: - source = f.read() - classified_text = analyze_python(source) - - if args.raw: - encoded = raw_highlight(classified_text) - elif args.complete or args.browser: - encoded = build_html_page(classified_text, title=sourcefile) - elif args.section: - encoded = html_highlight(classified_text) - elif args.latex: - encoded = latex_highlight(classified_text, title=sourcefile) - else: - encoded = ansi_highlight(classified_text) - - if args.browser: - htmlfile = os.path.splitext(os.path.basename(sourcefile))[0] + '.html' - with open(htmlfile, 'w') as f: - f.write(encoded) - webbrowser.open('file://' + os.path.abspath(htmlfile)) - else: - sys.stdout.write(encoded) diff --git a/Tools/scripts/idle3 b/Tools/scripts/idle3 index d7332bca48b..2b4f1b5c957 100755 --- a/Tools/scripts/idle3 +++ b/Tools/scripts/idle3 @@ -1,4 +1,4 @@ -#! /usr/bin/env python3 +#!/usr/bin/env python3 from idlelib.pyshell import main if __name__ == '__main__': diff --git a/Tools/scripts/ifdef.py b/Tools/scripts/ifdef.py deleted file mode 100755 index 22249b2d0af..00000000000 --- a/Tools/scripts/ifdef.py +++ /dev/null @@ -1,111 +0,0 @@ -#! /usr/bin/env python3 - -# Selectively preprocess #ifdef / #ifndef statements. -# Usage: -# ifdef [-Dname] ... [-Uname] ... [file] ... -# -# This scans the file(s), looking for #ifdef and #ifndef preprocessor -# commands that test for one of the names mentioned in the -D and -U -# options. On standard output it writes a copy of the input file(s) -# minus those code sections that are suppressed by the selected -# combination of defined/undefined symbols. The #if(n)def/#else/#else -# lines themselves (if the #if(n)def tests for one of the mentioned -# names) are removed as well. - -# Features: Arbitrary nesting of recognized and unrecognized -# preprocessor statements works correctly. Unrecognized #if* commands -# are left in place, so it will never remove too much, only too -# little. It does accept whitespace around the '#' character. - -# Restrictions: There should be no comments or other symbols on the -# #if(n)def lines. The effect of #define/#undef commands in the input -# file or in included files is not taken into account. Tests using -# #if and the defined() pseudo function are not recognized. The #elif -# command is not recognized. Improperly nesting is not detected. -# Lines that look like preprocessor commands but which are actually -# part of comments or string literals will be mistaken for -# preprocessor commands. - -import sys -import getopt - -defs = [] -undefs = [] - -def main(): - opts, args = getopt.getopt(sys.argv[1:], 'D:U:') - for o, a in opts: - if o == '-D': - defs.append(a) - if o == '-U': - undefs.append(a) - if not args: - args = ['-'] - for filename in args: - if filename == '-': - process(sys.stdin, sys.stdout) - else: - with open(filename) as f: - process(f, sys.stdout) - -def process(fpi, fpo): - keywords = ('if', 'ifdef', 'ifndef', 'else', 'endif') - ok = 1 - stack = [] - while 1: - line = fpi.readline() - if not line: break - while line[-2:] == '\\\n': - nextline = fpi.readline() - if not nextline: break - line = line + nextline - tmp = line.strip() - if tmp[:1] != '#': - if ok: fpo.write(line) - continue - tmp = tmp[1:].strip() - words = tmp.split() - keyword = words[0] - if keyword not in keywords: - if ok: fpo.write(line) - continue - if keyword in ('ifdef', 'ifndef') and len(words) == 2: - if keyword == 'ifdef': - ko = 1 - else: - ko = 0 - word = words[1] - if word in defs: - stack.append((ok, ko, word)) - if not ko: ok = 0 - elif word in undefs: - stack.append((ok, not ko, word)) - if ko: ok = 0 - else: - stack.append((ok, -1, word)) - if ok: fpo.write(line) - elif keyword == 'if': - stack.append((ok, -1, '')) - if ok: fpo.write(line) - elif keyword == 'else' and stack: - s_ok, s_ko, s_word = stack[-1] - if s_ko < 0: - if ok: fpo.write(line) - else: - s_ko = not s_ko - ok = s_ok - if not s_ko: ok = 0 - stack[-1] = s_ok, s_ko, s_word - elif keyword == 'endif' and stack: - s_ok, s_ko, s_word = stack[-1] - if s_ko < 0: - if ok: fpo.write(line) - del stack[-1] - ok = s_ok - else: - sys.stderr.write('Unknown keyword %s\n' % keyword) - if stack: - sys.stderr.write('stack: %s\n' % stack) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/import_diagnostics.py b/Tools/scripts/import_diagnostics.py deleted file mode 100755 index c907221d049..00000000000 --- a/Tools/scripts/import_diagnostics.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python3 -"""Miscellaneous diagnostics for the import system""" - -import sys -import argparse -from pprint import pprint - -def _dump_state(args): - print(sys.version) - for name in args.attributes: - print("sys.{}:".format(name)) - pprint(getattr(sys, name)) - -def _add_dump_args(cmd): - cmd.add_argument("attributes", metavar="ATTR", nargs="+", - help="sys module attribute to display") - -COMMANDS = ( - ("dump", "Dump import state", _dump_state, _add_dump_args), -) - -def _make_parser(): - parser = argparse.ArgumentParser() - sub = parser.add_subparsers(title="Commands") - for name, description, implementation, add_args in COMMANDS: - cmd = sub.add_parser(name, help=description) - cmd.set_defaults(command=implementation) - add_args(cmd) - return parser - -def main(args): - parser = _make_parser() - args = parser.parse_args(args) - return args.command(args) - -if __name__ == "__main__": - sys.exit(main(sys.argv[1:])) diff --git a/Tools/scripts/lfcr.py b/Tools/scripts/lfcr.py deleted file mode 100755 index bf8fe1c245e..00000000000 --- a/Tools/scripts/lfcr.py +++ /dev/null @@ -1,24 +0,0 @@ -#! /usr/bin/env python3 - -"Replace LF with CRLF in argument files. Print names of changed files." - -import sys, re, os - -def main(): - for filename in sys.argv[1:]: - if os.path.isdir(filename): - print(filename, "Directory!") - continue - with open(filename, "rb") as f: - data = f.read() - if b'\0' in data: - print(filename, "Binary!") - continue - newdata = re.sub(b"\r?\n", b"\r\n", data) - if newdata != data: - print(filename) - with open(filename, "wb") as f: - f.write(newdata) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/linktree.py b/Tools/scripts/linktree.py deleted file mode 100755 index e83f198593a..00000000000 --- a/Tools/scripts/linktree.py +++ /dev/null @@ -1,80 +0,0 @@ -#! /usr/bin/env python3 - -# linktree -# -# Make a copy of a directory tree with symbolic links to all files in the -# original tree. -# All symbolic links go to a special symbolic link at the top, so you -# can easily fix things if the original source tree moves. -# See also "mkreal". -# -# usage: mklinks oldtree newtree - -import sys, os - -LINK = '.LINK' # Name of special symlink at the top. - -debug = 0 - -def main(): - if not 3 <= len(sys.argv) <= 4: - print('usage:', sys.argv[0], 'oldtree newtree [linkto]') - return 2 - oldtree, newtree = sys.argv[1], sys.argv[2] - if len(sys.argv) > 3: - link = sys.argv[3] - link_may_fail = 1 - else: - link = LINK - link_may_fail = 0 - if not os.path.isdir(oldtree): - print(oldtree + ': not a directory') - return 1 - try: - os.mkdir(newtree, 0o777) - except OSError as msg: - print(newtree + ': cannot mkdir:', msg) - return 1 - linkname = os.path.join(newtree, link) - try: - os.symlink(os.path.join(os.pardir, oldtree), linkname) - except OSError as msg: - if not link_may_fail: - print(linkname + ': cannot symlink:', msg) - return 1 - else: - print(linkname + ': warning: cannot symlink:', msg) - linknames(oldtree, newtree, link) - return 0 - -def linknames(old, new, link): - if debug: print('linknames', (old, new, link)) - try: - names = os.listdir(old) - except OSError as msg: - print(old + ': warning: cannot listdir:', msg) - return - for name in names: - if name not in (os.curdir, os.pardir): - oldname = os.path.join(old, name) - linkname = os.path.join(link, name) - newname = os.path.join(new, name) - if debug > 1: print(oldname, newname, linkname) - if os.path.isdir(oldname) and \ - not os.path.islink(oldname): - try: - os.mkdir(newname, 0o777) - ok = 1 - except: - print(newname + \ - ': warning: cannot mkdir:', msg) - ok = 0 - if ok: - linkname = os.path.join(os.pardir, - linkname) - linknames(oldname, newname, linkname) - else: - os.symlink(linkname, newname) - -if __name__ == '__main__': - sys.exit(main()) diff --git a/Tools/scripts/lll.py b/Tools/scripts/lll.py deleted file mode 100755 index 1b48eac8aad..00000000000 --- a/Tools/scripts/lll.py +++ /dev/null @@ -1,27 +0,0 @@ -#! /usr/bin/env python3 - -# Find symbolic links and show where they point to. -# Arguments are directories to search; default is current directory. -# No recursion. -# (This is a totally different program from "findsymlinks.py"!) - -import sys, os - -def lll(dirname): - for name in os.listdir(dirname): - if name not in (os.curdir, os.pardir): - full = os.path.join(dirname, name) - if os.path.islink(full): - print(name, '->', os.readlink(full)) -def main(args): - if not args: args = [os.curdir] - first = 1 - for arg in args: - if len(args) > 1: - if not first: print() - first = 0 - print(arg + ':') - lll(arg) - -if __name__ == '__main__': - main(sys.argv[1:]) diff --git a/Tools/scripts/mailerdaemon.py b/Tools/scripts/mailerdaemon.py deleted file mode 100755 index 635e5482e63..00000000000 --- a/Tools/scripts/mailerdaemon.py +++ /dev/null @@ -1,246 +0,0 @@ -#!/usr/bin/env python3 -"""Classes to parse mailer-daemon messages.""" - -import calendar -import email.message -import re -import os -import sys - - -class Unparseable(Exception): - pass - - -class ErrorMessage(email.message.Message): - def __init__(self): - email.message.Message.__init__(self) - self.sub = '' - - def is_warning(self): - sub = self.get('Subject') - if not sub: - return 0 - sub = sub.lower() - if sub.startswith('waiting mail'): - return 1 - if 'warning' in sub: - return 1 - self.sub = sub - return 0 - - def get_errors(self): - for p in EMPARSERS: - self.rewindbody() - try: - return p(self.fp, self.sub) - except Unparseable: - pass - raise Unparseable - -# List of re's or tuples of re's. -# If a re, it should contain at least a group (?P...) which -# should refer to the email address. The re can also contain a group -# (?P...) which should refer to the reason (error message). -# If no reason is present, the emparse_list_reason list is used to -# find a reason. -# If a tuple, the tuple should contain 2 re's. The first re finds a -# location, the second re is repeated one or more times to find -# multiple email addresses. The second re is matched (not searched) -# where the previous match ended. -# The re's are compiled using the re module. -emparse_list_list = [ - 'error: (?Punresolvable): (?P.+)', - ('----- The following addresses had permanent fatal errors -----\n', - '(?P[^ \n].*)\n( .*\n)?'), - 'remote execution.*\n.*rmail (?P.+)', - ('The following recipients did not receive your message:\n\n', - ' +(?P.*)\n(The following recipients did not receive your message:\n\n)?'), - '------- Failure Reasons --------\n\n(?P.*)\n(?P.*)', - '^<(?P.*)>:\n(?P.*)', - '^(?PUser mailbox exceeds allowed size): (?P.+)', - '^5\\d{2} <(?P[^\n>]+)>\\.\\.\\. (?P.+)', - '^Original-Recipient: rfc822;(?P.*)', - '^did not reach the following recipient\\(s\\):\n\n(?P.*) on .*\n +(?P.*)', - '^ <(?P[^\n>]+)> \\.\\.\\. (?P.*)', - '^Report on your message to: (?P.*)\nReason: (?P.*)', - '^Your message was not delivered to +(?P.*)\n +for the following reason:\n +(?P.*)', - '^ was not +(?P[^ \n].*?) *\n.*\n.*\n.*\n because:.*\n +(?P[^ \n].*?) *\n', - ] -# compile the re's in the list and store them in-place. -for i in range(len(emparse_list_list)): - x = emparse_list_list[i] - if type(x) is type(''): - x = re.compile(x, re.MULTILINE) - else: - xl = [] - for x in x: - xl.append(re.compile(x, re.MULTILINE)) - x = tuple(xl) - del xl - emparse_list_list[i] = x - del x -del i - -# list of re's used to find reasons (error messages). -# if a string, "<>" is replaced by a copy of the email address. -# The expressions are searched for in order. After the first match, -# no more expressions are searched for. So, order is important. -emparse_list_reason = [ - r'^5\d{2} <>\.\.\. (?P.*)', - r'<>\.\.\. (?P.*)', - re.compile(r'^<<< 5\d{2} (?P.*)', re.MULTILINE), - re.compile('===== stderr was =====\nrmail: (?P.*)'), - re.compile('^Diagnostic-Code: (?P.*)', re.MULTILINE), - ] -emparse_list_from = re.compile('^From:', re.IGNORECASE|re.MULTILINE) -def emparse_list(fp, sub): - data = fp.read() - res = emparse_list_from.search(data) - if res is None: - from_index = len(data) - else: - from_index = res.start(0) - errors = [] - emails = [] - reason = None - for regexp in emparse_list_list: - if type(regexp) is type(()): - res = regexp[0].search(data, 0, from_index) - if res is not None: - try: - reason = res.group('reason') - except IndexError: - pass - while 1: - res = regexp[1].match(data, res.end(0), from_index) - if res is None: - break - emails.append(res.group('email')) - break - else: - res = regexp.search(data, 0, from_index) - if res is not None: - emails.append(res.group('email')) - try: - reason = res.group('reason') - except IndexError: - pass - break - if not emails: - raise Unparseable - if not reason: - reason = sub - if reason[:15] == 'returned mail: ': - reason = reason[15:] - for regexp in emparse_list_reason: - if type(regexp) is type(''): - for i in range(len(emails)-1,-1,-1): - email = emails[i] - exp = re.compile(re.escape(email).join(regexp.split('<>')), re.MULTILINE) - res = exp.search(data) - if res is not None: - errors.append(' '.join((email.strip()+': '+res.group('reason')).split())) - del emails[i] - continue - res = regexp.search(data) - if res is not None: - reason = res.group('reason') - break - for email in emails: - errors.append(' '.join((email.strip()+': '+reason).split())) - return errors - -EMPARSERS = [emparse_list] - -def sort_numeric(a, b): - a = int(a) - b = int(b) - if a < b: - return -1 - elif a > b: - return 1 - else: - return 0 - -def parsedir(dir, modify): - os.chdir(dir) - pat = re.compile('^[0-9]*$') - errordict = {} - errorfirst = {} - errorlast = {} - nok = nwarn = nbad = 0 - - # find all numeric file names and sort them - files = list(filter(lambda fn, pat=pat: pat.match(fn) is not None, os.listdir('.'))) - files.sort(sort_numeric) - - for fn in files: - # Lets try to parse the file. - fp = open(fn) - m = email.message_from_file(fp, _class=ErrorMessage) - sender = m.getaddr('From') - print('%s\t%-40s\t'%(fn, sender[1]), end=' ') - - if m.is_warning(): - fp.close() - print('warning only') - nwarn = nwarn + 1 - if modify: - os.rename(fn, ','+fn) -## os.unlink(fn) - continue - - try: - errors = m.get_errors() - except Unparseable: - print('** Not parseable') - nbad = nbad + 1 - fp.close() - continue - print(len(errors), 'errors') - - # Remember them - for e in errors: - try: - mm, dd = m.getdate('date')[1:1+2] - date = '%s %02d' % (calendar.month_abbr[mm], dd) - except: - date = '??????' - if e not in errordict: - errordict[e] = 1 - errorfirst[e] = '%s (%s)' % (fn, date) - else: - errordict[e] = errordict[e] + 1 - errorlast[e] = '%s (%s)' % (fn, date) - - fp.close() - nok = nok + 1 - if modify: - os.rename(fn, ','+fn) -## os.unlink(fn) - - print('--------------') - print(nok, 'files parsed,',nwarn,'files warning-only,', end=' ') - print(nbad,'files unparseable') - print('--------------') - list = [] - for e in errordict.keys(): - list.append((errordict[e], errorfirst[e], errorlast[e], e)) - list.sort() - for num, first, last, e in list: - print('%d %s - %s\t%s' % (num, first, last, e)) - -def main(): - modify = 0 - if len(sys.argv) > 1 and sys.argv[1] == '-d': - modify = 1 - del sys.argv[1] - if len(sys.argv) > 1: - for folder in sys.argv[1:]: - parsedir(folder, modify) - else: - parsedir('/ufs/jack/Mail/errorsinbox', modify) - -if __name__ == '__main__' or sys.argv[0] == __name__: - main() diff --git a/Tools/scripts/make_ctype.py b/Tools/scripts/make_ctype.py deleted file mode 100755 index afee1c58333..00000000000 --- a/Tools/scripts/make_ctype.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env python3 -"""Script that generates the ctype.h-replacement in stringobject.c.""" - -NAMES = ("LOWER", "UPPER", "ALPHA", "DIGIT", "XDIGIT", "ALNUM", "SPACE") - -print(""" -#define FLAG_LOWER 0x01 -#define FLAG_UPPER 0x02 -#define FLAG_ALPHA (FLAG_LOWER|FLAG_UPPER) -#define FLAG_DIGIT 0x04 -#define FLAG_ALNUM (FLAG_ALPHA|FLAG_DIGIT) -#define FLAG_SPACE 0x08 -#define FLAG_XDIGIT 0x10 - -static unsigned int ctype_table[256] = {""") - -for i in range(128): - c = chr(i) - flags = [] - for name in NAMES: - if name in ("ALPHA", "ALNUM"): - continue - if name == "XDIGIT": - method = lambda: c.isdigit() or c.upper() in "ABCDEF" - else: - method = getattr(c, "is" + name.lower()) - if method(): - flags.append("FLAG_" + name) - rc = repr(c) - if c == '\v': - rc = "'\\v'" - elif c == '\f': - rc = "'\\f'" - if not flags: - print(" 0, /* 0x%x %s */" % (i, rc)) - else: - print(" %s, /* 0x%x %s */" % ("|".join(flags), i, rc)) - -for i in range(128, 256, 16): - print(" %s," % ", ".join(16*["0"])) - -print("};") -print("") - -for name in NAMES: - print("#define IS%s(c) (ctype_table[Py_CHARMASK(c)] & FLAG_%s)" % - (name, name)) - -print("") - -for name in NAMES: - name = "is" + name.lower() - print("#undef %s" % name) - print("#define %s(c) undefined_%s(c)" % (name, name)) - -print(""" -static unsigned char ctype_tolower[256] = {""") - -for i in range(0, 256, 8): - values = [] - for i in range(i, i+8): - if i < 128: - c = chr(i) - if c.isupper(): - i = ord(c.lower()) - values.append("0x%02x" % i) - print(" %s," % ", ".join(values)) - -print("};") - -print(""" -static unsigned char ctype_toupper[256] = {""") - -for i in range(0, 256, 8): - values = [] - for i in range(i, i+8): - if i < 128: - c = chr(i) - if c.islower(): - i = ord(c.upper()) - values.append("0x%02x" % i) - print(" %s," % ", ".join(values)) - -print("};") - -print(""" -#define TOLOWER(c) (ctype_tolower[Py_CHARMASK(c)]) -#define TOUPPER(c) (ctype_toupper[Py_CHARMASK(c)]) - -#undef tolower -#define tolower(c) undefined_tolower(c) -#undef toupper -#define toupper(c) undefined_toupper(c) -""") diff --git a/Tools/scripts/md5sum.py b/Tools/scripts/md5sum.py deleted file mode 100755 index f910576377a..00000000000 --- a/Tools/scripts/md5sum.py +++ /dev/null @@ -1,93 +0,0 @@ -#! /usr/bin/env python3 - -"""Python utility to print MD5 checksums of argument files. -""" - - -bufsize = 8096 -fnfilter = None -rmode = 'rb' - -usage = """ -usage: md5sum.py [-b] [-t] [-l] [-s bufsize] [file ...] --b : read files in binary mode (default) --t : read files in text mode (you almost certainly don't want this!) --l : print last pathname component only --s bufsize: read buffer size (default %d) -file ... : files to sum; '-' or no files means stdin -""" % bufsize - -import io -import sys -import os -import getopt -from hashlib import md5 - -def sum(*files): - sts = 0 - if files and isinstance(files[-1], io.IOBase): - out, files = files[-1], files[:-1] - else: - out = sys.stdout - if len(files) == 1 and not isinstance(files[0], str): - files = files[0] - for f in files: - if isinstance(f, str): - if f == '-': - sts = printsumfp(sys.stdin, '', out) or sts - else: - sts = printsum(f, out) or sts - else: - sts = sum(f, out) or sts - return sts - -def printsum(filename, out=sys.stdout): - try: - fp = open(filename, rmode) - except IOError as msg: - sys.stderr.write('%s: Can\'t open: %s\n' % (filename, msg)) - return 1 - with fp: - if fnfilter: - filename = fnfilter(filename) - sts = printsumfp(fp, filename, out) - return sts - -def printsumfp(fp, filename, out=sys.stdout): - m = md5() - try: - while 1: - data = fp.read(bufsize) - if not data: - break - if isinstance(data, str): - data = data.encode(fp.encoding) - m.update(data) - except IOError as msg: - sys.stderr.write('%s: I/O error: %s\n' % (filename, msg)) - return 1 - out.write('%s %s\n' % (m.hexdigest(), filename)) - return 0 - -def main(args = sys.argv[1:], out=sys.stdout): - global fnfilter, rmode, bufsize - try: - opts, args = getopt.getopt(args, 'blts:') - except getopt.error as msg: - sys.stderr.write('%s: %s\n%s' % (sys.argv[0], msg, usage)) - return 2 - for o, a in opts: - if o == '-l': - fnfilter = os.path.basename - elif o == '-b': - rmode = 'rb' - elif o == '-t': - rmode = 'r' - elif o == '-s': - bufsize = int(a) - if not args: - args = ['-'] - return sum(args, out) - -if __name__ == '__main__' or __name__ == sys.argv[0]: - sys.exit(main(sys.argv[1:], sys.stdout)) diff --git a/Tools/scripts/mkreal.py b/Tools/scripts/mkreal.py deleted file mode 100755 index f169da43fe1..00000000000 --- a/Tools/scripts/mkreal.py +++ /dev/null @@ -1,65 +0,0 @@ -#! /usr/bin/env python3 - -# mkreal -# -# turn a symlink to a directory into a real directory - -import sys -import os -from stat import * - -join = os.path.join - -error = 'mkreal error' - -BUFSIZE = 32*1024 - -def mkrealfile(name): - st = os.stat(name) # Get the mode - mode = S_IMODE(st[ST_MODE]) - linkto = os.readlink(name) # Make sure again it's a symlink - with open(name, 'rb') as f_in: # This ensures it's a file - os.unlink(name) - with open(name, 'wb') as f_out: - while 1: - buf = f_in.read(BUFSIZE) - if not buf: break - f_out.write(buf) - os.chmod(name, mode) - -def mkrealdir(name): - st = os.stat(name) # Get the mode - mode = S_IMODE(st[ST_MODE]) - linkto = os.readlink(name) - files = os.listdir(name) - os.unlink(name) - os.mkdir(name, mode) - os.chmod(name, mode) - linkto = join(os.pardir, linkto) - # - for filename in files: - if filename not in (os.curdir, os.pardir): - os.symlink(join(linkto, filename), join(name, filename)) - -def main(): - sys.stdout = sys.stderr - progname = os.path.basename(sys.argv[0]) - if progname == '-c': progname = 'mkreal' - args = sys.argv[1:] - if not args: - print('usage:', progname, 'path ...') - sys.exit(2) - status = 0 - for name in args: - if not os.path.islink(name): - print(progname+':', name+':', 'not a symlink') - status = 1 - else: - if os.path.isdir(name): - mkrealdir(name) - else: - mkrealfile(name) - sys.exit(status) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/nm2def.py b/Tools/scripts/nm2def.py deleted file mode 100755 index a885ebd6fec..00000000000 --- a/Tools/scripts/nm2def.py +++ /dev/null @@ -1,104 +0,0 @@ -#! /usr/bin/env python3 -"""nm2def.py - -Helpers to extract symbols from Unix libs and auto-generate -Windows definition files from them. Depends on nm(1). Tested -on Linux and Solaris only (-p option to nm is for Solaris only). - -By Marc-Andre Lemburg, Aug 1998. - -Additional notes: the output of nm is supposed to look like this: - -acceler.o: -000001fd T PyGrammar_AddAccelerators - U PyGrammar_FindDFA -00000237 T PyGrammar_RemoveAccelerators - U _IO_stderr_ - U exit - U fprintf - U free - U malloc - U printf - -grammar1.o: -00000000 T PyGrammar_FindDFA -00000034 T PyGrammar_LabelRepr - U _PyParser_TokenNames - U abort - U printf - U sprintf - -... - -Even if this isn't the default output of your nm, there is generally an -option to produce this format (since it is the original v7 Unix format). - -""" -import os, sys - -PYTHONLIB = 'libpython%d.%d.a' % sys.version_info[:2] -PC_PYTHONLIB = 'Python%d%d.dll' % sys.version_info[:2] -NM = 'nm -p -g %s' # For Linux, use "nm -g %s" - -def symbols(lib=PYTHONLIB,types=('T','C','D')): - - with os.popen(NM % lib) as pipe: - lines = pipe.readlines() - lines = [s.strip() for s in lines] - symbols = {} - for line in lines: - if len(line) == 0 or ':' in line: - continue - items = line.split() - if len(items) != 3: - continue - address, type, name = items - if type not in types: - continue - symbols[name] = address,type - return symbols - -def export_list(symbols): - - data = [] - code = [] - for name,(addr,type) in symbols.items(): - if type in ('C','D'): - data.append('\t'+name) - else: - code.append('\t'+name) - data.sort() - data.append('') - code.sort() - return ' DATA\n'.join(data)+'\n'+'\n'.join(code) - -# Definition file template -DEF_TEMPLATE = """\ -EXPORTS -%s -""" - -# Special symbols that have to be included even though they don't -# pass the filter -SPECIALS = ( - ) - -def filter_Python(symbols,specials=SPECIALS): - - for name in list(symbols.keys()): - if name[:2] == 'Py' or name[:3] == '_Py': - pass - elif name not in specials: - del symbols[name] - -def main(): - - s = symbols(PYTHONLIB) - filter_Python(s) - exports = export_list(s) - f = sys.stdout # open('PC/python_nt.def','w') - f.write(DEF_TEMPLATE % (exports)) - # f.close() - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/objgraph.py b/Tools/scripts/objgraph.py deleted file mode 100755 index add41e692c0..00000000000 --- a/Tools/scripts/objgraph.py +++ /dev/null @@ -1,211 +0,0 @@ -#! /usr/bin/env python3 - -# objgraph -# -# Read "nm -o" input of a set of libraries or modules and print various -# interesting listings, such as: -# -# - which names are used but not defined in the set (and used where), -# - which names are defined in the set (and where), -# - which modules use which other modules, -# - which modules are used by which other modules. -# -# Usage: objgraph [-cdu] [file] ... -# -c: print callers per objectfile -# -d: print callees per objectfile -# -u: print usage of undefined symbols -# If none of -cdu is specified, all are assumed. -# Use "nm -o" to generate the input -# e.g.: nm -o /lib/libc.a | objgraph - - -import sys -import os -import getopt -import re - -# Types of symbols. -# -definitions = 'TRGDSBAEC' -externals = 'UV' -ignore = 'Nntrgdsbavuc' - -# Regular expression to parse "nm -o" output. -# -matcher = re.compile('(.*):\t?........ (.) (.*)$') - -# Store "item" in "dict" under "key". -# The dictionary maps keys to lists of items. -# If there is no list for the key yet, it is created. -# -def store(dict, key, item): - if key in dict: - dict[key].append(item) - else: - dict[key] = [item] - -# Return a flattened version of a list of strings: the concatenation -# of its elements with intervening spaces. -# -def flat(list): - s = '' - for item in list: - s = s + ' ' + item - return s[1:] - -# Global variables mapping defined/undefined names to files and back. -# -file2undef = {} -def2file = {} -file2def = {} -undef2file = {} - -# Read one input file and merge the data into the tables. -# Argument is an open file. -# -def readinput(fp): - while 1: - s = fp.readline() - if not s: - break - # If you get any output from this line, - # it is probably caused by an unexpected input line: - if matcher.search(s) < 0: s; continue # Shouldn't happen - (ra, rb), (r1a, r1b), (r2a, r2b), (r3a, r3b) = matcher.regs[:4] - fn, name, type = s[r1a:r1b], s[r3a:r3b], s[r2a:r2b] - if type in definitions: - store(def2file, name, fn) - store(file2def, fn, name) - elif type in externals: - store(file2undef, fn, name) - store(undef2file, name, fn) - elif not type in ignore: - print(fn + ':' + name + ': unknown type ' + type) - -# Print all names that were undefined in some module and where they are -# defined. -# -def printcallee(): - flist = sorted(file2undef.keys()) - for filename in flist: - print(filename + ':') - elist = file2undef[filename] - elist.sort() - for ext in elist: - if len(ext) >= 8: - tabs = '\t' - else: - tabs = '\t\t' - if ext not in def2file: - print('\t' + ext + tabs + ' *undefined') - else: - print('\t' + ext + tabs + flat(def2file[ext])) - -# Print for each module the names of the other modules that use it. -# -def printcaller(): - files = sorted(file2def.keys()) - for filename in files: - callers = [] - for label in file2def[filename]: - if label in undef2file: - callers = callers + undef2file[label] - if callers: - callers.sort() - print(filename + ':') - lastfn = '' - for fn in callers: - if fn != lastfn: - print('\t' + fn) - lastfn = fn - else: - print(filename + ': unused') - -# Print undefined names and where they are used. -# -def printundef(): - undefs = {} - for filename in list(file2undef.keys()): - for ext in file2undef[filename]: - if ext not in def2file: - store(undefs, ext, filename) - elist = sorted(undefs.keys()) - for ext in elist: - print(ext + ':') - flist = sorted(undefs[ext]) - for filename in flist: - print('\t' + filename) - -# Print warning messages about names defined in more than one file. -# -def warndups(): - savestdout = sys.stdout - sys.stdout = sys.stderr - names = sorted(def2file.keys()) - for name in names: - if len(def2file[name]) > 1: - print('warning:', name, 'multiply defined:', end=' ') - print(flat(def2file[name])) - sys.stdout = savestdout - -# Main program -# -def main(): - try: - optlist, args = getopt.getopt(sys.argv[1:], 'cdu') - except getopt.error: - sys.stdout = sys.stderr - print('Usage:', os.path.basename(sys.argv[0]), end=' ') - print('[-cdu] [file] ...') - print('-c: print callers per objectfile') - print('-d: print callees per objectfile') - print('-u: print usage of undefined symbols') - print('If none of -cdu is specified, all are assumed.') - print('Use "nm -o" to generate the input') - print('e.g.: nm -o /lib/libc.a | objgraph') - return 1 - optu = optc = optd = 0 - for opt, void in optlist: - if opt == '-u': - optu = 1 - elif opt == '-c': - optc = 1 - elif opt == '-d': - optd = 1 - if optu == optc == optd == 0: - optu = optc = optd = 1 - if not args: - args = ['-'] - for filename in args: - if filename == '-': - readinput(sys.stdin) - else: - with open(filename) as f: - readinput(f) - # - warndups() - # - more = (optu + optc + optd > 1) - if optd: - if more: - print('---------------All callees------------------') - printcallee() - if optu: - if more: - print('---------------Undefined callees------------') - printundef() - if optc: - if more: - print('---------------All Callers------------------') - printcaller() - return 0 - -# Call the main program. -# Use its return value as exit status. -# Catch interrupts to avoid stack trace. -# -if __name__ == '__main__': - try: - sys.exit(main()) - except KeyboardInterrupt: - sys.exit(1) diff --git a/Tools/scripts/parseentities.py b/Tools/scripts/parseentities.py deleted file mode 100755 index 0229d3af86b..00000000000 --- a/Tools/scripts/parseentities.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python3 -""" Utility for parsing HTML entity definitions available from: - - http://www.w3.org/ as e.g. - http://www.w3.org/TR/REC-html40/HTMLlat1.ent - - Input is read from stdin, output is written to stdout in form of a - Python snippet defining a dictionary "entitydefs" mapping literal - entity name to character or numeric entity. - - Marc-Andre Lemburg, mal@lemburg.com, 1999. - Use as you like. NO WARRANTIES. - -""" -import re,sys - -entityRE = re.compile(r'') - -def parse(text,pos=0,endpos=None): - - pos = 0 - if endpos is None: - endpos = len(text) - d = {} - while 1: - m = entityRE.search(text,pos,endpos) - if not m: - break - name,charcode,comment = m.groups() - d[name] = charcode,comment - pos = m.end() - return d - -def writefile(f,defs): - - f.write("entitydefs = {\n") - items = sorted(defs.items()) - for name, (charcode,comment) in items: - if charcode[:2] == '&#': - code = int(charcode[2:-1]) - if code < 256: - charcode = r"'\%o'" % code - else: - charcode = repr(charcode) - else: - charcode = repr(charcode) - comment = ' '.join(comment.split()) - f.write(" '%s':\t%s, \t# %s\n" % (name,charcode,comment)) - f.write('\n}\n') - -if __name__ == '__main__': - if len(sys.argv) > 1: - with open(sys.argv[1]) as infile: - text = infile.read() - else: - text = sys.stdin.read() - - defs = parse(text) - - if len(sys.argv) > 2: - with open(sys.argv[2],'w') as outfile: - writefile(outfile, defs) - else: - writefile(sys.stdout, defs) diff --git a/Tools/scripts/pathfix.py b/Tools/scripts/pathfix.py deleted file mode 100755 index d252321a21a..00000000000 --- a/Tools/scripts/pathfix.py +++ /dev/null @@ -1,226 +0,0 @@ -#!/usr/bin/env python3 - -# Change the #! line (shebang) occurring in Python scripts. The new interpreter -# pathname must be given with a -i option. -# -# Command line arguments are files or directories to be processed. -# Directories are searched recursively for files whose name looks -# like a python module. -# Symbolic links are always ignored (except as explicit directory -# arguments). -# The original file is kept as a back-up (with a "~" attached to its name), -# -n flag can be used to disable this. - -# Sometimes you may find shebangs with flags such as `#! /usr/bin/env python -si`. -# Normally, pathfix overwrites the entire line, including the flags. -# To change interpreter and keep flags from the original shebang line, use -k. -# If you want to keep flags and add to them one single literal flag, use option -a. - - -# Undoubtedly you can do this using find and sed or perl, but this is -# a nice example of Python code that recurses down a directory tree -# and uses regular expressions. Also note several subtleties like -# preserving the file's mode and avoiding to even write a temp file -# when no changes are needed for a file. -# -# NB: by changing only the function fixfile() you can turn this -# into a program for a different change to Python programs... - -import sys -import re -import os -from stat import * -import getopt - -err = sys.stderr.write -dbg = err -rep = sys.stdout.write - -new_interpreter = None -preserve_timestamps = False -create_backup = True -keep_flags = False -add_flags = b'' - - -def main(): - global new_interpreter - global preserve_timestamps - global create_backup - global keep_flags - global add_flags - - usage = ('usage: %s -i /interpreter -p -n -k -a file-or-directory ...\n' % - sys.argv[0]) - try: - opts, args = getopt.getopt(sys.argv[1:], 'i:a:kpn') - except getopt.error as msg: - err(str(msg) + '\n') - err(usage) - sys.exit(2) - for o, a in opts: - if o == '-i': - new_interpreter = a.encode() - if o == '-p': - preserve_timestamps = True - if o == '-n': - create_backup = False - if o == '-k': - keep_flags = True - if o == '-a': - add_flags = a.encode() - if b' ' in add_flags: - err("-a option doesn't support whitespaces") - sys.exit(2) - if not new_interpreter or not new_interpreter.startswith(b'/') or \ - not args: - err('-i option or file-or-directory missing\n') - err(usage) - sys.exit(2) - bad = 0 - for arg in args: - if os.path.isdir(arg): - if recursedown(arg): bad = 1 - elif os.path.islink(arg): - err(arg + ': will not process symbolic links\n') - bad = 1 - else: - if fix(arg): bad = 1 - sys.exit(bad) - - -def ispython(name): - return name.endswith('.py') - - -def recursedown(dirname): - dbg('recursedown(%r)\n' % (dirname,)) - bad = 0 - try: - names = os.listdir(dirname) - except OSError as msg: - err('%s: cannot list directory: %r\n' % (dirname, msg)) - return 1 - names.sort() - subdirs = [] - for name in names: - if name in (os.curdir, os.pardir): continue - fullname = os.path.join(dirname, name) - if os.path.islink(fullname): pass - elif os.path.isdir(fullname): - subdirs.append(fullname) - elif ispython(name): - if fix(fullname): bad = 1 - for fullname in subdirs: - if recursedown(fullname): bad = 1 - return bad - - -def fix(filename): -## dbg('fix(%r)\n' % (filename,)) - try: - f = open(filename, 'rb') - except IOError as msg: - err('%s: cannot open: %r\n' % (filename, msg)) - return 1 - with f: - line = f.readline() - fixed = fixline(line) - if line == fixed: - rep(filename+': no change\n') - return - head, tail = os.path.split(filename) - tempname = os.path.join(head, '@' + tail) - try: - g = open(tempname, 'wb') - except IOError as msg: - err('%s: cannot create: %r\n' % (tempname, msg)) - return 1 - with g: - rep(filename + ': updating\n') - g.write(fixed) - BUFSIZE = 8*1024 - while 1: - buf = f.read(BUFSIZE) - if not buf: break - g.write(buf) - - # Finishing touch -- move files - - mtime = None - atime = None - # First copy the file's mode to the temp file - try: - statbuf = os.stat(filename) - mtime = statbuf.st_mtime - atime = statbuf.st_atime - os.chmod(tempname, statbuf[ST_MODE] & 0o7777) - except OSError as msg: - err('%s: warning: chmod failed (%r)\n' % (tempname, msg)) - # Then make a backup of the original file as filename~ - if create_backup: - try: - os.rename(filename, filename + '~') - except OSError as msg: - err('%s: warning: backup failed (%r)\n' % (filename, msg)) - else: - try: - os.remove(filename) - except OSError as msg: - err('%s: warning: removing failed (%r)\n' % (filename, msg)) - # Now move the temp file to the original file - try: - os.rename(tempname, filename) - except OSError as msg: - err('%s: rename failed (%r)\n' % (filename, msg)) - return 1 - if preserve_timestamps: - if atime and mtime: - try: - os.utime(filename, (atime, mtime)) - except OSError as msg: - err('%s: reset of timestamp failed (%r)\n' % (filename, msg)) - return 1 - # Return success - return 0 - - -def parse_shebang(shebangline): - shebangline = shebangline.rstrip(b'\n') - start = shebangline.find(b' -') - if start == -1: - return b'' - return shebangline[start:] - - -def populate_flags(shebangline): - old_flags = b'' - if keep_flags: - old_flags = parse_shebang(shebangline) - if old_flags: - old_flags = old_flags[2:] - if not (old_flags or add_flags): - return b'' - # On Linux, the entire string following the interpreter name - # is passed as a single argument to the interpreter. - # e.g. "#! /usr/bin/python3 -W Error -s" runs "/usr/bin/python3 "-W Error -s" - # so shebang should have single '-' where flags are given and - # flag might need argument for that reasons adding new flags is - # between '-' and original flags - # e.g. #! /usr/bin/python3 -sW Error - return b' -' + add_flags + old_flags - - -def fixline(line): - if not line.startswith(b'#!'): - return line - - if b"python" not in line: - return line - - flags = populate_flags(line) - return b'#! ' + new_interpreter + flags + b'\n' - - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/pdeps.py b/Tools/scripts/pdeps.py deleted file mode 100755 index ab0040f48e2..00000000000 --- a/Tools/scripts/pdeps.py +++ /dev/null @@ -1,164 +0,0 @@ -#! /usr/bin/env python3 - -# pdeps -# -# Find dependencies between a bunch of Python modules. -# -# Usage: -# pdeps file1.py file2.py ... -# -# Output: -# Four tables separated by lines like '--- Closure ---': -# 1) Direct dependencies, listing which module imports which other modules -# 2) The inverse of (1) -# 3) Indirect dependencies, or the closure of the above -# 4) The inverse of (3) -# -# To do: -# - command line options to select output type -# - option to automatically scan the Python library for referenced modules -# - option to limit output to particular modules - - -import sys -import re -import os - - -# Main program -# -def main(): - args = sys.argv[1:] - if not args: - print('usage: pdeps file.py file.py ...') - return 2 - # - table = {} - for arg in args: - process(arg, table) - # - print('--- Uses ---') - printresults(table) - # - print('--- Used By ---') - inv = inverse(table) - printresults(inv) - # - print('--- Closure of Uses ---') - reach = closure(table) - printresults(reach) - # - print('--- Closure of Used By ---') - invreach = inverse(reach) - printresults(invreach) - # - return 0 - - -# Compiled regular expressions to search for import statements -# -m_import = re.compile('^[ \t]*from[ \t]+([^ \t]+)[ \t]+') -m_from = re.compile('^[ \t]*import[ \t]+([^#]+)') - - -# Collect data from one file -# -def process(filename, table): - with open(filename, encoding='utf-8') as fp: - mod = os.path.basename(filename) - if mod[-3:] == '.py': - mod = mod[:-3] - table[mod] = list = [] - while 1: - line = fp.readline() - if not line: break - while line[-1:] == '\\': - nextline = fp.readline() - if not nextline: break - line = line[:-1] + nextline - m_found = m_import.match(line) or m_from.match(line) - if m_found: - (a, b), (a1, b1) = m_found.regs[:2] - else: continue - words = line[a1:b1].split(',') - # print '#', line, words - for word in words: - word = word.strip() - if word not in list: - list.append(word) - - -# Compute closure (this is in fact totally general) -# -def closure(table): - modules = list(table.keys()) - # - # Initialize reach with a copy of table - # - reach = {} - for mod in modules: - reach[mod] = table[mod][:] - # - # Iterate until no more change - # - change = 1 - while change: - change = 0 - for mod in modules: - for mo in reach[mod]: - if mo in modules: - for m in reach[mo]: - if m not in reach[mod]: - reach[mod].append(m) - change = 1 - # - return reach - - -# Invert a table (this is again totally general). -# All keys of the original table are made keys of the inverse, -# so there may be empty lists in the inverse. -# -def inverse(table): - inv = {} - for key in table.keys(): - if key not in inv: - inv[key] = [] - for item in table[key]: - store(inv, item, key) - return inv - - -# Store "item" in "dict" under "key". -# The dictionary maps keys to lists of items. -# If there is no list for the key yet, it is created. -# -def store(dict, key, item): - if key in dict: - dict[key].append(item) - else: - dict[key] = [item] - - -# Tabulate results neatly -# -def printresults(table): - modules = sorted(table.keys()) - maxlen = 0 - for mod in modules: maxlen = max(maxlen, len(mod)) - for mod in modules: - list = sorted(table[mod]) - print(mod.ljust(maxlen), ':', end=' ') - if mod in list: - print('(*)', end=' ') - for ref in list: - print(ref, end=' ') - print() - - -# Call main and honor exit status -if __name__ == '__main__': - try: - sys.exit(main()) - except KeyboardInterrupt: - sys.exit(1) diff --git a/Tools/scripts/pep384_macrocheck.py b/Tools/scripts/pep384_macrocheck.py deleted file mode 100644 index ab9dd7c972a..00000000000 --- a/Tools/scripts/pep384_macrocheck.py +++ /dev/null @@ -1,148 +0,0 @@ -""" -pep384_macrocheck.py - -This program tries to locate errors in the relevant Python header -files where macros access type fields when they are reachable from -the limited API. - -The idea is to search macros with the string "->tp_" in it. -When the macro name does not begin with an underscore, -then we have found a dormant error. - -Christian Tismer -2018-06-02 -""" - -import sys -import os -import re - - -DEBUG = False - -def dprint(*args, **kw): - if DEBUG: - print(*args, **kw) - -def parse_headerfiles(startpath): - """ - Scan all header files which are reachable fronm Python.h - """ - search = "Python.h" - name = os.path.join(startpath, search) - if not os.path.exists(name): - raise ValueError("file {} was not found in {}\n" - "Please give the path to Python's include directory." - .format(search, startpath)) - errors = 0 - with open(name) as python_h: - while True: - line = python_h.readline() - if not line: - break - found = re.match(r'^\s*#\s*include\s*"(\w+\.h)"', line) - if not found: - continue - include = found.group(1) - dprint("Scanning", include) - name = os.path.join(startpath, include) - if not os.path.exists(name): - name = os.path.join(startpath, "../PC", include) - errors += parse_file(name) - return errors - -def ifdef_level_gen(): - """ - Scan lines for #ifdef and track the level. - """ - level = 0 - ifdef_pattern = r"^\s*#\s*if" # covers ifdef and ifndef as well - endif_pattern = r"^\s*#\s*endif" - while True: - line = yield level - if re.match(ifdef_pattern, line): - level += 1 - elif re.match(endif_pattern, line): - level -= 1 - -def limited_gen(): - """ - Scan lines for Py_LIMITED_API yes(1) no(-1) or nothing (0) - """ - limited = [0] # nothing - unlimited_pattern = r"^\s*#\s*ifndef\s+Py_LIMITED_API" - limited_pattern = "|".join([ - r"^\s*#\s*ifdef\s+Py_LIMITED_API", - r"^\s*#\s*(el)?if\s+!\s*defined\s*\(\s*Py_LIMITED_API\s*\)\s*\|\|", - r"^\s*#\s*(el)?if\s+defined\s*\(\s*Py_LIMITED_API" - ]) - else_pattern = r"^\s*#\s*else" - ifdef_level = ifdef_level_gen() - status = next(ifdef_level) - wait_for = -1 - while True: - line = yield limited[-1] - new_status = ifdef_level.send(line) - dir = new_status - status - status = new_status - if dir == 1: - if re.match(unlimited_pattern, line): - limited.append(-1) - wait_for = status - 1 - elif re.match(limited_pattern, line): - limited.append(1) - wait_for = status - 1 - elif dir == -1: - # this must have been an endif - if status == wait_for: - limited.pop() - wait_for = -1 - else: - # it could be that we have an elif - if re.match(limited_pattern, line): - limited.append(1) - wait_for = status - 1 - elif re.match(else_pattern, line): - limited.append(-limited.pop()) # negate top - -def parse_file(fname): - errors = 0 - with open(fname) as f: - lines = f.readlines() - type_pattern = r"^.*?->\s*tp_" - define_pattern = r"^\s*#\s*define\s+(\w+)" - limited = limited_gen() - status = next(limited) - for nr, line in enumerate(lines): - status = limited.send(line) - line = line.rstrip() - dprint(fname, nr, status, line) - if status != -1: - if re.match(define_pattern, line): - name = re.match(define_pattern, line).group(1) - if not name.startswith("_"): - # found a candidate, check it! - macro = line + "\n" - idx = nr - while line.endswith("\\"): - idx += 1 - line = lines[idx].rstrip() - macro += line + "\n" - if re.match(type_pattern, macro, re.DOTALL): - # this type field can reach the limited API - report(fname, nr + 1, macro) - errors += 1 - return errors - -def report(fname, nr, macro): - f = sys.stderr - print(fname + ":" + str(nr), file=f) - print(macro, file=f) - -if __name__ == "__main__": - p = sys.argv[1] if sys.argv[1:] else "../../Include" - errors = parse_headerfiles(p) - if errors: - # somehow it makes sense to raise a TypeError :-) - raise TypeError("These {} locations contradict the limited API." - .format(errors)) diff --git a/Tools/scripts/pickle2db.py b/Tools/scripts/pickle2db.py deleted file mode 100755 index b5b65718632..00000000000 --- a/Tools/scripts/pickle2db.py +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/env python3 - -""" -Synopsis: %(prog)s [-h|-b|-g|-r|-a|-d] [ picklefile ] dbfile - -Read the given picklefile as a series of key/value pairs and write to a new -database. If the database already exists, any contents are deleted. The -optional flags indicate the type of the output database: - - -a - open using dbm (open any supported format) - -b - open as bsddb btree file - -d - open as dbm.ndbm file - -g - open as dbm.gnu file - -h - open as bsddb hash file - -r - open as bsddb recno file - -The default is hash. If a pickle file is named it is opened for read -access. If no pickle file is named, the pickle input is read from standard -input. - -Note that recno databases can only contain integer keys, so you can't dump a -hash or btree database using db2pickle.py and reconstitute it to a recno -database with %(prog)s unless your keys are integers. - -""" - -import getopt -try: - import bsddb -except ImportError: - bsddb = None -try: - import dbm.ndbm as dbm -except ImportError: - dbm = None -try: - import dbm.gnu as gdbm -except ImportError: - gdbm = None -try: - import dbm.ndbm as anydbm -except ImportError: - anydbm = None -import sys -try: - import pickle as pickle -except ImportError: - import pickle - -prog = sys.argv[0] - -def usage(): - sys.stderr.write(__doc__ % globals()) - -def main(args): - try: - opts, args = getopt.getopt(args, "hbrdag", - ["hash", "btree", "recno", "dbm", "anydbm", - "gdbm"]) - except getopt.error: - usage() - return 1 - - if len(args) == 0 or len(args) > 2: - usage() - return 1 - elif len(args) == 1: - pfile = sys.stdin - dbfile = args[0] - else: - try: - pfile = open(args[0], 'rb') - except IOError: - sys.stderr.write("Unable to open %s\n" % args[0]) - return 1 - dbfile = args[1] - - dbopen = None - for opt, arg in opts: - if opt in ("-h", "--hash"): - try: - dbopen = bsddb.hashopen - except AttributeError: - sys.stderr.write("bsddb module unavailable.\n") - return 1 - elif opt in ("-b", "--btree"): - try: - dbopen = bsddb.btopen - except AttributeError: - sys.stderr.write("bsddb module unavailable.\n") - return 1 - elif opt in ("-r", "--recno"): - try: - dbopen = bsddb.rnopen - except AttributeError: - sys.stderr.write("bsddb module unavailable.\n") - return 1 - elif opt in ("-a", "--anydbm"): - try: - dbopen = anydbm.open - except AttributeError: - sys.stderr.write("dbm module unavailable.\n") - return 1 - elif opt in ("-g", "--gdbm"): - try: - dbopen = gdbm.open - except AttributeError: - sys.stderr.write("dbm.gnu module unavailable.\n") - return 1 - elif opt in ("-d", "--dbm"): - try: - dbopen = dbm.open - except AttributeError: - sys.stderr.write("dbm.ndbm module unavailable.\n") - return 1 - if dbopen is None: - if bsddb is None: - sys.stderr.write("bsddb module unavailable - ") - sys.stderr.write("must specify dbtype.\n") - return 1 - else: - dbopen = bsddb.hashopen - - try: - db = dbopen(dbfile, 'c') - except bsddb.error: - sys.stderr.write("Unable to open %s. " % dbfile) - sys.stderr.write("Check for format or version mismatch.\n") - return 1 - else: - for k in list(db.keys()): - del db[k] - - while 1: - try: - (key, val) = pickle.load(pfile) - except EOFError: - break - db[key] = val - - db.close() - pfile.close() - - return 0 - -if __name__ == "__main__": - sys.exit(main(sys.argv[1:])) diff --git a/Tools/scripts/pindent.py b/Tools/scripts/pindent.py deleted file mode 100755 index 33334204a4d..00000000000 --- a/Tools/scripts/pindent.py +++ /dev/null @@ -1,506 +0,0 @@ -#! /usr/bin/env python3 - -# This file contains a class and a main program that perform three -# related (though complimentary) formatting operations on Python -# programs. When called as "pindent -c", it takes a valid Python -# program as input and outputs a version augmented with block-closing -# comments. When called as "pindent -d", it assumes its input is a -# Python program with block-closing comments and outputs a commentless -# version. When called as "pindent -r" it assumes its input is a -# Python program with block-closing comments but with its indentation -# messed up, and outputs a properly indented version. - -# A "block-closing comment" is a comment of the form '# end ' -# where is the keyword that opened the block. If the -# opening keyword is 'def' or 'class', the function or class name may -# be repeated in the block-closing comment as well. Here is an -# example of a program fully augmented with block-closing comments: - -# def foobar(a, b): -# if a == b: -# a = a+1 -# elif a < b: -# b = b-1 -# if b > a: a = a-1 -# # end if -# else: -# print 'oops!' -# # end if -# # end def foobar - -# Note that only the last part of an if...elif...else... block needs a -# block-closing comment; the same is true for other compound -# statements (e.g. try...except). Also note that "short-form" blocks -# like the second 'if' in the example must be closed as well; -# otherwise the 'else' in the example would be ambiguous (remember -# that indentation is not significant when interpreting block-closing -# comments). - -# The operations are idempotent (i.e. applied to their own output -# they yield an identical result). Running first "pindent -c" and -# then "pindent -r" on a valid Python program produces a program that -# is semantically identical to the input (though its indentation may -# be different). Running "pindent -e" on that output produces a -# program that only differs from the original in indentation. - -# Other options: -# -s stepsize: set the indentation step size (default 8) -# -t tabsize : set the number of spaces a tab character is worth (default 8) -# -e : expand TABs into spaces -# file ... : input file(s) (default standard input) -# The results always go to standard output - -# Caveats: -# - comments ending in a backslash will be mistaken for continued lines -# - continuations using backslash are always left unchanged -# - continuations inside parentheses are not extra indented by -r -# but must be indented for -c to work correctly (this breaks -# idempotency!) -# - continued lines inside triple-quoted strings are totally garbled - -# Secret feature: -# - On input, a block may also be closed with an "end statement" -- -# this is a block-closing comment without the '#' sign. - -# Possible improvements: -# - check syntax based on transitions in 'next' table -# - better error reporting -# - better error recovery -# - check identifier after class/def - -# The following wishes need a more complete tokenization of the source: -# - Don't get fooled by comments ending in backslash -# - reindent continuation lines indicated by backslash -# - handle continuation lines inside parentheses/braces/brackets -# - handle triple quoted strings spanning lines -# - realign comments -# - optionally do much more thorough reformatting, a la C indent - -# Defaults -STEPSIZE = 8 -TABSIZE = 8 -EXPANDTABS = False - -import io -import re -import sys - -next = {} -next['if'] = next['elif'] = 'elif', 'else', 'end' -next['while'] = next['for'] = 'else', 'end' -next['try'] = 'except', 'finally' -next['except'] = 'except', 'else', 'finally', 'end' -next['else'] = next['finally'] = next['with'] = \ - next['def'] = next['class'] = 'end' -next['end'] = () -start = 'if', 'while', 'for', 'try', 'with', 'def', 'class' - -class PythonIndenter: - - def __init__(self, fpi = sys.stdin, fpo = sys.stdout, - indentsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - self.fpi = fpi - self.fpo = fpo - self.indentsize = indentsize - self.tabsize = tabsize - self.lineno = 0 - self.expandtabs = expandtabs - self._write = fpo.write - self.kwprog = re.compile( - r'^(?:\s|\\\n)*(?P[a-z]+)' - r'((?:\s|\\\n)+(?P[a-zA-Z_]\w*))?' - r'[^\w]') - self.endprog = re.compile( - r'^(?:\s|\\\n)*#?\s*end\s+(?P[a-z]+)' - r'(\s+(?P[a-zA-Z_]\w*))?' - r'[^\w]') - self.wsprog = re.compile(r'^[ \t]*') - # end def __init__ - - def write(self, line): - if self.expandtabs: - self._write(line.expandtabs(self.tabsize)) - else: - self._write(line) - # end if - # end def write - - def readline(self): - line = self.fpi.readline() - if line: self.lineno += 1 - # end if - return line - # end def readline - - def error(self, fmt, *args): - if args: fmt = fmt % args - # end if - sys.stderr.write('Error at line %d: %s\n' % (self.lineno, fmt)) - self.write('### %s ###\n' % fmt) - # end def error - - def getline(self): - line = self.readline() - while line[-2:] == '\\\n': - line2 = self.readline() - if not line2: break - # end if - line += line2 - # end while - return line - # end def getline - - def putline(self, line, indent): - tabs, spaces = divmod(indent*self.indentsize, self.tabsize) - i = self.wsprog.match(line).end() - line = line[i:] - if line[:1] not in ('\n', '\r', ''): - line = '\t'*tabs + ' '*spaces + line - # end if - self.write(line) - # end def putline - - def reformat(self): - stack = [] - while True: - line = self.getline() - if not line: break # EOF - # end if - m = self.endprog.match(line) - if m: - kw = 'end' - kw2 = m.group('kw') - if not stack: - self.error('unexpected end') - elif stack.pop()[0] != kw2: - self.error('unmatched end') - # end if - self.putline(line, len(stack)) - continue - # end if - m = self.kwprog.match(line) - if m: - kw = m.group('kw') - if kw in start: - self.putline(line, len(stack)) - stack.append((kw, kw)) - continue - # end if - if kw in next and stack: - self.putline(line, len(stack)-1) - kwa, kwb = stack[-1] - stack[-1] = kwa, kw - continue - # end if - # end if - self.putline(line, len(stack)) - # end while - if stack: - self.error('unterminated keywords') - for kwa, kwb in stack: - self.write('\t%s\n' % kwa) - # end for - # end if - # end def reformat - - def delete(self): - begin_counter = 0 - end_counter = 0 - while True: - line = self.getline() - if not line: break # EOF - # end if - m = self.endprog.match(line) - if m: - end_counter += 1 - continue - # end if - m = self.kwprog.match(line) - if m: - kw = m.group('kw') - if kw in start: - begin_counter += 1 - # end if - # end if - self.write(line) - # end while - if begin_counter - end_counter < 0: - sys.stderr.write('Warning: input contained more end tags than expected\n') - elif begin_counter - end_counter > 0: - sys.stderr.write('Warning: input contained less end tags than expected\n') - # end if - # end def delete - - def complete(self): - stack = [] - todo = [] - currentws = thisid = firstkw = lastkw = topid = '' - while True: - line = self.getline() - i = self.wsprog.match(line).end() - m = self.endprog.match(line) - if m: - thiskw = 'end' - endkw = m.group('kw') - thisid = m.group('id') - else: - m = self.kwprog.match(line) - if m: - thiskw = m.group('kw') - if thiskw not in next: - thiskw = '' - # end if - if thiskw in ('def', 'class'): - thisid = m.group('id') - else: - thisid = '' - # end if - elif line[i:i+1] in ('\n', '#'): - todo.append(line) - continue - else: - thiskw = '' - # end if - # end if - indentws = line[:i] - indent = len(indentws.expandtabs(self.tabsize)) - current = len(currentws.expandtabs(self.tabsize)) - while indent < current: - if firstkw: - if topid: - s = '# end %s %s\n' % ( - firstkw, topid) - else: - s = '# end %s\n' % firstkw - # end if - self.write(currentws + s) - firstkw = lastkw = '' - # end if - currentws, firstkw, lastkw, topid = stack.pop() - current = len(currentws.expandtabs(self.tabsize)) - # end while - if indent == current and firstkw: - if thiskw == 'end': - if endkw != firstkw: - self.error('mismatched end') - # end if - firstkw = lastkw = '' - elif not thiskw or thiskw in start: - if topid: - s = '# end %s %s\n' % ( - firstkw, topid) - else: - s = '# end %s\n' % firstkw - # end if - self.write(currentws + s) - firstkw = lastkw = topid = '' - # end if - # end if - if indent > current: - stack.append((currentws, firstkw, lastkw, topid)) - if thiskw and thiskw not in start: - # error - thiskw = '' - # end if - currentws, firstkw, lastkw, topid = \ - indentws, thiskw, thiskw, thisid - # end if - if thiskw: - if thiskw in start: - firstkw = lastkw = thiskw - topid = thisid - else: - lastkw = thiskw - # end if - # end if - for l in todo: self.write(l) - # end for - todo = [] - if not line: break - # end if - self.write(line) - # end while - # end def complete -# end class PythonIndenter - -# Simplified user interface -# - xxx_filter(input, output): read and write file objects -# - xxx_string(s): take and return string object -# - xxx_file(filename): process file in place, return true iff changed - -def complete_filter(input = sys.stdin, output = sys.stdout, - stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) - pi.complete() -# end def complete_filter - -def delete_filter(input= sys.stdin, output = sys.stdout, - stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) - pi.delete() -# end def delete_filter - -def reformat_filter(input = sys.stdin, output = sys.stdout, - stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) - pi.reformat() -# end def reformat_filter - -def complete_string(source, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - input = io.StringIO(source) - output = io.StringIO() - pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) - pi.complete() - return output.getvalue() -# end def complete_string - -def delete_string(source, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - input = io.StringIO(source) - output = io.StringIO() - pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) - pi.delete() - return output.getvalue() -# end def delete_string - -def reformat_string(source, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - input = io.StringIO(source) - output = io.StringIO() - pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) - pi.reformat() - return output.getvalue() -# end def reformat_string - -def make_backup(filename): - import os, os.path - backup = filename + '~' - if os.path.lexists(backup): - try: - os.remove(backup) - except OSError: - print("Can't remove backup %r" % (backup,), file=sys.stderr) - # end try - # end if - try: - os.rename(filename, backup) - except OSError: - print("Can't rename %r to %r" % (filename, backup), file=sys.stderr) - # end try -# end def make_backup - -def complete_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - with open(filename, 'r') as f: - source = f.read() - # end with - result = complete_string(source, stepsize, tabsize, expandtabs) - if source == result: return 0 - # end if - make_backup(filename) - with open(filename, 'w') as f: - f.write(result) - # end with - return 1 -# end def complete_file - -def delete_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - with open(filename, 'r') as f: - source = f.read() - # end with - result = delete_string(source, stepsize, tabsize, expandtabs) - if source == result: return 0 - # end if - make_backup(filename) - with open(filename, 'w') as f: - f.write(result) - # end with - return 1 -# end def delete_file - -def reformat_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - with open(filename, 'r') as f: - source = f.read() - # end with - result = reformat_string(source, stepsize, tabsize, expandtabs) - if source == result: return 0 - # end if - make_backup(filename) - with open(filename, 'w') as f: - f.write(result) - # end with - return 1 -# end def reformat_file - -# Test program when called as a script - -usage = """ -usage: pindent (-c|-d|-r) [-s stepsize] [-t tabsize] [-e] [file] ... --c : complete a correctly indented program (add #end directives) --d : delete #end directives --r : reformat a completed program (use #end directives) --s stepsize: indentation step (default %(STEPSIZE)d) --t tabsize : the worth in spaces of a tab (default %(TABSIZE)d) --e : expand TABs into spaces (default OFF) -[file] ... : files are changed in place, with backups in file~ -If no files are specified or a single - is given, -the program acts as a filter (reads stdin, writes stdout). -""" % vars() - -def error_both(op1, op2): - sys.stderr.write('Error: You can not specify both '+op1+' and -'+op2[0]+' at the same time\n') - sys.stderr.write(usage) - sys.exit(2) -# end def error_both - -def test(): - import getopt - try: - opts, args = getopt.getopt(sys.argv[1:], 'cdrs:t:e') - except getopt.error as msg: - sys.stderr.write('Error: %s\n' % msg) - sys.stderr.write(usage) - sys.exit(2) - # end try - action = None - stepsize = STEPSIZE - tabsize = TABSIZE - expandtabs = EXPANDTABS - for o, a in opts: - if o == '-c': - if action: error_both(o, action) - # end if - action = 'complete' - elif o == '-d': - if action: error_both(o, action) - # end if - action = 'delete' - elif o == '-r': - if action: error_both(o, action) - # end if - action = 'reformat' - elif o == '-s': - stepsize = int(a) - elif o == '-t': - tabsize = int(a) - elif o == '-e': - expandtabs = True - # end if - # end for - if not action: - sys.stderr.write( - 'You must specify -c(omplete), -d(elete) or -r(eformat)\n') - sys.stderr.write(usage) - sys.exit(2) - # end if - if not args or args == ['-']: - action = eval(action + '_filter') - action(sys.stdin, sys.stdout, stepsize, tabsize, expandtabs) - else: - action = eval(action + '_file') - for filename in args: - action(filename, stepsize, tabsize, expandtabs) - # end for - # end if -# end def test - -if __name__ == '__main__': - test() -# end if diff --git a/Tools/scripts/ptags.py b/Tools/scripts/ptags.py deleted file mode 100755 index eedd411702c..00000000000 --- a/Tools/scripts/ptags.py +++ /dev/null @@ -1,54 +0,0 @@ -#! /usr/bin/env python3 - -# ptags -# -# Create a tags file for Python programs, usable with vi. -# Tagged are: -# - functions (even inside other defs or classes) -# - classes -# - filenames -# Warns about files it cannot open. -# No warnings about duplicate tags. - -import sys, re, os - -tags = [] # Modified global variable! - -def main(): - args = sys.argv[1:] - for filename in args: - treat_file(filename) - if tags: - with open('tags', 'w') as fp: - tags.sort() - for s in tags: fp.write(s) - - -expr = r'^[ \t]*(def|class)[ \t]+([a-zA-Z0-9_]+)[ \t]*[:\(]' -matcher = re.compile(expr) - -def treat_file(filename): - try: - fp = open(filename, 'r') - except: - sys.stderr.write('Cannot open %s\n' % filename) - return - with fp: - base = os.path.basename(filename) - if base[-3:] == '.py': - base = base[:-3] - s = base + '\t' + filename + '\t' + '1\n' - tags.append(s) - while 1: - line = fp.readline() - if not line: - break - m = matcher.match(line) - if m: - content = m.group(0) - name = m.group(2) - s = name + '\t' + filename + '\t/^' + content + '/\n' - tags.append(s) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/pysource.py b/Tools/scripts/pysource.py deleted file mode 100755 index 69e8e0df4ff..00000000000 --- a/Tools/scripts/pysource.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python3 - -"""\ -List python source files. - -There are three functions to check whether a file is a Python source, listed -here with increasing complexity: - -- has_python_ext() checks whether a file name ends in '.py[w]'. -- look_like_python() checks whether the file is not binary and either has - the '.py[w]' extension or the first line contains the word 'python'. -- can_be_compiled() checks whether the file can be compiled by compile(). - -The file also must be of appropriate size - not bigger than a megabyte. - -walk_python_files() recursively lists all Python files under the given directories. -""" -__author__ = "Oleg Broytmann, Georg Brandl" - -__all__ = ["has_python_ext", "looks_like_python", "can_be_compiled", "walk_python_files"] - - -import os, re - -binary_re = re.compile(br'[\x00-\x08\x0E-\x1F\x7F]') - -debug = False - -def print_debug(msg): - if debug: print(msg) - - -def _open(fullpath): - try: - size = os.stat(fullpath).st_size - except OSError as err: # Permission denied - ignore the file - print_debug("%s: permission denied: %s" % (fullpath, err)) - return None - - if size > 1024*1024: # too big - print_debug("%s: the file is too big: %d bytes" % (fullpath, size)) - return None - - try: - return open(fullpath, "rb") - except IOError as err: # Access denied, or a special file - ignore it - print_debug("%s: access denied: %s" % (fullpath, err)) - return None - -def has_python_ext(fullpath): - return fullpath.endswith(".py") or fullpath.endswith(".pyw") - -def looks_like_python(fullpath): - infile = _open(fullpath) - if infile is None: - return False - - with infile: - line = infile.readline() - - if binary_re.search(line): - # file appears to be binary - print_debug("%s: appears to be binary" % fullpath) - return False - - if fullpath.endswith(".py") or fullpath.endswith(".pyw"): - return True - elif b"python" in line: - # disguised Python script (e.g. CGI) - return True - - return False - -def can_be_compiled(fullpath): - infile = _open(fullpath) - if infile is None: - return False - - with infile: - code = infile.read() - - try: - compile(code, fullpath, "exec") - except Exception as err: - print_debug("%s: cannot compile: %s" % (fullpath, err)) - return False - - return True - - -def walk_python_files(paths, is_python=looks_like_python, exclude_dirs=None): - """\ - Recursively yield all Python source files below the given paths. - - paths: a list of files and/or directories to be checked. - is_python: a function that takes a file name and checks whether it is a - Python source file - exclude_dirs: a list of directory base names that should be excluded in - the search - """ - if exclude_dirs is None: - exclude_dirs=[] - - for path in paths: - print_debug("testing: %s" % path) - if os.path.isfile(path): - if is_python(path): - yield path - elif os.path.isdir(path): - print_debug(" it is a directory") - for dirpath, dirnames, filenames in os.walk(path): - for exclude in exclude_dirs: - if exclude in dirnames: - dirnames.remove(exclude) - for filename in filenames: - fullpath = os.path.join(dirpath, filename) - print_debug("testing: %s" % fullpath) - if is_python(fullpath): - yield fullpath - else: - print_debug(" unknown type") - - -if __name__ == "__main__": - # Two simple examples/tests - for fullpath in walk_python_files(['.']): - print(fullpath) - print("----------") - for fullpath in walk_python_files(['.'], is_python=can_be_compiled): - print(fullpath) diff --git a/Tools/scripts/reindent-rst.py b/Tools/scripts/reindent-rst.py deleted file mode 100755 index 25608af66ac..00000000000 --- a/Tools/scripts/reindent-rst.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python3 - -# Make a reST file compliant to our pre-commit hook. -# Currently just remove trailing whitespace. - -import sys - -import patchcheck - -def main(argv=sys.argv): - patchcheck.normalize_docs_whitespace(argv[1:]) - -if __name__ == '__main__': - sys.exit(main()) diff --git a/Tools/scripts/rgrep.py b/Tools/scripts/rgrep.py deleted file mode 100755 index c39bf93aad3..00000000000 --- a/Tools/scripts/rgrep.py +++ /dev/null @@ -1,67 +0,0 @@ -#! /usr/bin/env python3 - -"""Reverse grep. - -Usage: rgrep [-i] pattern file -""" - -import sys -import re -import getopt - - -def main(): - bufsize = 64 * 1024 - reflags = 0 - opts, args = getopt.getopt(sys.argv[1:], "i") - for o, a in opts: - if o == '-i': - reflags = reflags | re.IGNORECASE - if len(args) < 2: - usage("not enough arguments") - if len(args) > 2: - usage("exactly one file argument required") - pattern, filename = args - try: - prog = re.compile(pattern, reflags) - except re.error as msg: - usage("error in regular expression: %s" % msg) - try: - f = open(filename) - except IOError as msg: - usage("can't open %r: %s" % (filename, msg), 1) - with f: - f.seek(0, 2) - pos = f.tell() - leftover = None - while pos > 0: - size = min(pos, bufsize) - pos = pos - size - f.seek(pos) - buffer = f.read(size) - lines = buffer.split("\n") - del buffer - if leftover is None: - if not lines[-1]: - del lines[-1] - else: - lines[-1] = lines[-1] + leftover - if pos > 0: - leftover = lines[0] - del lines[0] - else: - leftover = None - for line in reversed(lines): - if prog.search(line): - print(line) - - -def usage(msg, code=2): - sys.stdout = sys.stderr - print(msg) - print(__doc__) - sys.exit(code) - - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/run_tests.py b/Tools/scripts/run_tests.py index 48feb3f778e..445a34ae3e8 100644 --- a/Tools/scripts/run_tests.py +++ b/Tools/scripts/run_tests.py @@ -8,7 +8,9 @@ simply passing a -u option to this script. """ import os +import shlex import sys +import sysconfig import test.support @@ -19,15 +21,37 @@ def is_multiprocess_flag(arg): def is_resource_use_flag(arg): return arg.startswith('-u') or arg.startswith('--use') +def is_python_flag(arg): + return arg.startswith('-p') or arg.startswith('--python') + def main(regrtest_args): args = [sys.executable, '-u', # Unbuffered stdout and stderr '-W', 'default', # Warnings set to 'default' '-bb', # Warnings about bytes/bytearray - '-E', # Ignore environment variables ] + cross_compile = '_PYTHON_HOST_PLATFORM' in os.environ + if (hostrunner := os.environ.get("_PYTHON_HOSTRUNNER")) is None: + hostrunner = sysconfig.get_config_var("HOSTRUNNER") + if cross_compile: + # emulate -E, but keep PYTHONPATH + cross compile env vars, so + # test executable can load correct sysconfigdata file. + keep = { + '_PYTHON_PROJECT_BASE', + '_PYTHON_HOST_PLATFORM', + '_PYTHON_SYSCONFIGDATA_NAME', + 'PYTHONPATH' + } + environ = { + name: value for name, value in os.environ.items() + if not name.startswith(('PYTHON', '_PYTHON')) or name in keep + } + else: + environ = os.environ.copy() + args.append("-E") + # Allow user-specified interpreter options to override our defaults. args.extend(test.support.args_from_interpreter_flags()) @@ -38,16 +62,30 @@ def main(regrtest_args): if sys.platform == 'win32': args.append('-n') # Silence alerts under Windows if not any(is_multiprocess_flag(arg) for arg in regrtest_args): - args.extend(['-j', '0']) # Use all CPU cores + if cross_compile and hostrunner: + # For now use only two cores for cross-compiled builds; + # hostrunner can be expensive. + args.extend(['-j', '2']) + else: + args.extend(['-j', '0']) # Use all CPU cores if not any(is_resource_use_flag(arg) for arg in regrtest_args): args.extend(['-u', 'all,-largefile,-audio,-gui']) + + if cross_compile and hostrunner: + # If HOSTRUNNER is set and -p/--python option is not given, then + # use hostrunner to execute python binary for tests. + if not any(is_python_flag(arg) for arg in regrtest_args): + buildpython = sysconfig.get_config_var("BUILDPYTHON") + args.extend(["--python", f"{hostrunner} {buildpython}"]) + args.extend(regrtest_args) - print(' '.join(args)) + + print(shlex.join(args)) if sys.platform == 'win32': from subprocess import call sys.exit(call(args)) else: - os.execv(sys.executable, args) + os.execve(sys.executable, args, environ) if __name__ == '__main__': diff --git a/Tools/scripts/serve.py b/Tools/scripts/serve.py deleted file mode 100755 index 7ac9c105078..00000000000 --- a/Tools/scripts/serve.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python3 -''' -Small wsgiref based web server. Takes a path to serve from and an -optional port number (defaults to 8000), then tries to serve files. -Mime types are guessed from the file names, 404 errors are raised -if the file is not found. Used for the make serve target in Doc. -''' -import sys -import os -import mimetypes -from wsgiref import simple_server, util - -def app(environ, respond): - - fn = os.path.join(path, environ['PATH_INFO'][1:]) - if '.' not in fn.split(os.path.sep)[-1]: - fn = os.path.join(fn, 'index.html') - type = mimetypes.guess_type(fn)[0] - - if os.path.exists(fn): - respond('200 OK', [('Content-Type', type)]) - return util.FileWrapper(open(fn, "rb")) - else: - respond('404 Not Found', [('Content-Type', 'text/plain')]) - return [b'not found'] - -if __name__ == '__main__': - path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd() - port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000 - httpd = simple_server.make_server('', port, app) - print("Serving {} on port {}, control-C to stop".format(path, port)) - try: - httpd.serve_forever() - except KeyboardInterrupt: - print("Shutting down.") - httpd.server_close() diff --git a/Tools/scripts/suff.py b/Tools/scripts/suff.py deleted file mode 100755 index 0eea0d75486..00000000000 --- a/Tools/scripts/suff.py +++ /dev/null @@ -1,26 +0,0 @@ -#! /usr/bin/env python3 - -# suff -# -# show different suffixes amongst arguments - -import sys - - -def main(): - files = sys.argv[1:] - suffixes = {} - for filename in files: - suff = getsuffix(filename) - suffixes.setdefault(suff, []).append(filename) - for suff, filenames in sorted(suffixes.items()): - print(repr(suff), len(filenames)) - - -def getsuffix(filename): - name, sep, suff = filename.rpartition('.') - return sep + suff if sep else '' - - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/summarize_specialization_stats.py b/Tools/scripts/summarize_specialization_stats.py deleted file mode 100644 index cc3ef85933c..00000000000 --- a/Tools/scripts/summarize_specialization_stats.py +++ /dev/null @@ -1,53 +0,0 @@ -"""Print a summary of specialization stats for all files in the -default stats folders. -""" - -import collections -import os.path - -if os.name == "nt": - DEFAULT_DIR = "c:\\temp\\py_stats\\" -else: - DEFAULT_DIR = "/tmp/py_stats/" - - -TOTAL = "deferred", "hit", "miss", "unquickened" - -def print_stats(name, family_stats): - total = sum(family_stats[kind] for kind in TOTAL) - if total == 0: - return - print(name+":") - for key in sorted(family_stats): - if not key.startswith("specialization"): - print(f"{key:>12}:{family_stats[key]:>12} {100*family_stats[key]/total:0.1f}%") - for key in ("specialization_success", "specialization_failure"): - print(f" {key}:{family_stats[key]:>12}") - total_failures = family_stats["specialization_failure"] - failure_kinds = [ 0 ] * 20 - for key in family_stats: - if not key.startswith("specialization_failure_kind"): - continue - _, index = key[:-1].split("[") - index = int(index) - failure_kinds[index] = family_stats[key] - for index, value in enumerate(failure_kinds): - if not value: - continue - print(f" kind {index:>2}: {value:>8} {100*value/total_failures:0.1f}%") - -def main(): - stats = collections.defaultdict(collections.Counter) - for filename in os.listdir(DEFAULT_DIR): - for line in open(os.path.join(DEFAULT_DIR, filename)): - key, value = line.split(":") - key = key.strip() - family, stat = key.split(".") - value = int(value.strip()) - stats[family][stat] += value - - for name in sorted(stats): - print_stats(name, stats[name]) - -if __name__ == "__main__": - main() diff --git a/Tools/scripts/summarize_stats.py b/Tools/scripts/summarize_stats.py new file mode 100644 index 00000000000..7789c4d3a17 --- /dev/null +++ b/Tools/scripts/summarize_stats.py @@ -0,0 +1,650 @@ +"""Print a summary of specialization stats for all files in the +default stats folders. +""" + +import argparse +import collections +import json +import os.path +import opcode +from datetime import date +import itertools +import sys + +if os.name == "nt": + DEFAULT_DIR = "c:\\temp\\py_stats\\" +else: + DEFAULT_DIR = "/tmp/py_stats/" + +#Create list of all instruction names +specialized = iter(opcode._specialized_instructions) +opname = ["<0>"] +for name in opcode.opname[1:]: + if name.startswith("<"): + try: + name = next(specialized) + except StopIteration: + pass + opname.append(name) + +# opcode_name --> opcode +# Sort alphabetically. +opmap = {name: i for i, name in enumerate(opname)} +opmap = dict(sorted(opmap.items())) + +TOTAL = "specialization.hit", "specialization.miss", "execution_count" + +def format_ratio(num, den): + """ + Format a ratio as a percentage. When the denominator is 0, returns the empty + string. + """ + if den == 0: + return "" + else: + return f"{num/den:.01%}" + +def join_rows(a_rows, b_rows): + """ + Joins two tables together, side-by-side, where the first column in each is a + common key. + """ + if len(a_rows) == 0 and len(b_rows) == 0: + return [] + + if len(a_rows): + a_ncols = list(set(len(x) for x in a_rows)) + if len(a_ncols) != 1: + raise ValueError("Table a is ragged") + + if len(b_rows): + b_ncols = list(set(len(x) for x in b_rows)) + if len(b_ncols) != 1: + raise ValueError("Table b is ragged") + + if len(a_rows) and len(b_rows) and a_ncols[0] != b_ncols[0]: + raise ValueError("Tables have different widths") + + if len(a_rows): + ncols = a_ncols[0] + else: + ncols = b_ncols[0] + + default = [""] * (ncols - 1) + a_data = {x[0]: x[1:] for x in a_rows} + b_data = {x[0]: x[1:] for x in b_rows} + + if len(a_data) != len(a_rows) or len(b_data) != len(b_rows): + raise ValueError("Duplicate keys") + + # To preserve ordering, use A's keys as is and then add any in B that aren't + # in A + keys = list(a_data.keys()) + [k for k in b_data.keys() if k not in a_data] + return [(k, *a_data.get(k, default), *b_data.get(k, default)) for k in keys] + +def calculate_specialization_stats(family_stats, total): + rows = [] + for key in sorted(family_stats): + if key.startswith("specialization.failure_kinds"): + continue + if key in ("specialization.hit", "specialization.miss"): + label = key[len("specialization."):] + elif key == "execution_count": + continue + elif key in ("specialization.success", "specialization.failure", "specializable"): + continue + elif key.startswith("pair"): + continue + else: + label = key + rows.append((f"{label:>12}", f"{family_stats[key]:>12}", format_ratio(family_stats[key], total))) + return rows + +def calculate_specialization_success_failure(family_stats): + total_attempts = 0 + for key in ("specialization.success", "specialization.failure"): + total_attempts += family_stats.get(key, 0) + rows = [] + if total_attempts: + for key in ("specialization.success", "specialization.failure"): + label = key[len("specialization."):] + label = label[0].upper() + label[1:] + val = family_stats.get(key, 0) + rows.append((label, val, format_ratio(val, total_attempts))) + return rows + +def calculate_specialization_failure_kinds(name, family_stats, defines): + total_failures = family_stats.get("specialization.failure", 0) + failure_kinds = [ 0 ] * 40 + for key in family_stats: + if not key.startswith("specialization.failure_kind"): + continue + _, index = key[:-1].split("[") + index = int(index) + failure_kinds[index] = family_stats[key] + failures = [(value, index) for (index, value) in enumerate(failure_kinds)] + failures.sort(reverse=True) + rows = [] + for value, index in failures: + if not value: + continue + rows.append((kind_to_text(index, defines, name), value, format_ratio(value, total_failures))) + return rows + +def print_specialization_stats(name, family_stats, defines): + if "specializable" not in family_stats: + return + total = sum(family_stats.get(kind, 0) for kind in TOTAL) + if total == 0: + return + with Section(name, 3, f"specialization stats for {name} family"): + rows = calculate_specialization_stats(family_stats, total) + emit_table(("Kind", "Count", "Ratio"), rows) + rows = calculate_specialization_success_failure(family_stats) + if rows: + print_title("Specialization attempts", 4) + emit_table(("", "Count:", "Ratio:"), rows) + rows = calculate_specialization_failure_kinds(name, family_stats, defines) + emit_table(("Failure kind", "Count:", "Ratio:"), rows) + +def print_comparative_specialization_stats(name, base_family_stats, head_family_stats, defines): + if "specializable" not in base_family_stats: + return + + base_total = sum(base_family_stats.get(kind, 0) for kind in TOTAL) + head_total = sum(head_family_stats.get(kind, 0) for kind in TOTAL) + if base_total + head_total == 0: + return + with Section(name, 3, f"specialization stats for {name} family"): + base_rows = calculate_specialization_stats(base_family_stats, base_total) + head_rows = calculate_specialization_stats(head_family_stats, head_total) + emit_table( + ("Kind", "Base Count", "Base Ratio", "Head Count", "Head Ratio"), + join_rows(base_rows, head_rows) + ) + base_rows = calculate_specialization_success_failure(base_family_stats) + head_rows = calculate_specialization_success_failure(head_family_stats) + rows = join_rows(base_rows, head_rows) + if rows: + print_title("Specialization attempts", 4) + emit_table(("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), rows) + base_rows = calculate_specialization_failure_kinds(name, base_family_stats, defines) + head_rows = calculate_specialization_failure_kinds(name, head_family_stats, defines) + emit_table( + ("Failure kind", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), + join_rows(base_rows, head_rows) + ) + +def gather_stats(input): + # Note the output of this function must be JSON-serializable + + if os.path.isfile(input): + with open(input, "r") as fd: + return json.load(fd) + elif os.path.isdir(input): + stats = collections.Counter() + for filename in os.listdir(input): + with open(os.path.join(input, filename)) as fd: + for line in fd: + try: + key, value = line.split(":") + except ValueError: + print(f"Unparsable line: '{line.strip()}' in {filename}", file=sys.stderr) + continue + key = key.strip() + value = int(value) + stats[key] += value + stats['__nfiles__'] += 1 + return stats + else: + raise ValueError(f"{input:r} is not a file or directory path") + +def extract_opcode_stats(stats): + opcode_stats = [ {} for _ in range(256) ] + for key, value in stats.items(): + if not key.startswith("opcode"): + continue + n, _, rest = key[7:].partition("]") + opcode_stats[int(n)][rest.strip(".")] = value + return opcode_stats + +def parse_kinds(spec_src, prefix="SPEC_FAIL"): + defines = collections.defaultdict(list) + start = "#define " + prefix + "_" + for line in spec_src: + line = line.strip() + if not line.startswith(start): + continue + line = line[len(start):] + name, val = line.split() + defines[int(val.strip())].append(name.strip()) + return defines + +def pretty(defname): + return defname.replace("_", " ").lower() + +def kind_to_text(kind, defines, opname): + if kind <= 8: + return pretty(defines[kind][0]) + if opname.endswith("ATTR"): + opname = "ATTR" + if opname in ("COMPARE_OP", "COMPARE_AND_BRANCH"): + opname = "COMPARE" + if opname.endswith("SUBSCR"): + opname = "SUBSCR" + for name in defines[kind]: + if name.startswith(opname): + return pretty(name[len(opname)+1:]) + return "kind " + str(kind) + +def categorized_counts(opcode_stats): + basic = 0 + specialized = 0 + not_specialized = 0 + specialized_instructions = { + op for op in opcode._specialized_instructions + if "__" not in op} + for i, opcode_stat in enumerate(opcode_stats): + if "execution_count" not in opcode_stat: + continue + count = opcode_stat['execution_count'] + name = opname[i] + if "specializable" in opcode_stat: + not_specialized += count + elif name in specialized_instructions: + miss = opcode_stat.get("specialization.miss", 0) + not_specialized += miss + specialized += count - miss + else: + basic += count + return basic, not_specialized, specialized + +def print_title(name, level=2): + print("#"*level, name) + print() + +class Section: + + def __init__(self, title, level=2, summary=None): + self.title = title + self.level = level + if summary is None: + self.summary = title.lower() + else: + self.summary = summary + + def __enter__(self): + print_title(self.title, self.level) + print("
    ") + print("", self.summary, "") + print() + return self + + def __exit__(*args): + print() + print("
    ") + print() + +def to_str(x): + if isinstance(x, int): + return format(x, ",d") + else: + return str(x) + +def emit_table(header, rows): + width = len(header) + header_line = "|" + under_line = "|" + for item in header: + under = "---" + if item.endswith(":"): + item = item[:-1] + under += ":" + header_line += item + " | " + under_line += under + "|" + print(header_line) + print(under_line) + for row in rows: + if width is not None and len(row) != width: + raise ValueError("Wrong number of elements in row '" + str(row) + "'") + print("|", " | ".join(to_str(i) for i in row), "|") + print() + +def calculate_execution_counts(opcode_stats, total): + counts = [] + for i, opcode_stat in enumerate(opcode_stats): + if "execution_count" in opcode_stat: + count = opcode_stat['execution_count'] + miss = 0 + if "specializable" not in opcode_stat: + miss = opcode_stat.get("specialization.miss") + counts.append((count, opname[i], miss)) + counts.sort(reverse=True) + cumulative = 0 + rows = [] + for (count, name, miss) in counts: + cumulative += count + if miss: + miss = format_ratio(miss, count) + else: + miss = "" + rows.append((name, count, format_ratio(count, total), + format_ratio(cumulative, total), miss)) + return rows + +def emit_execution_counts(opcode_stats, total): + with Section("Execution counts", summary="execution counts for all instructions"): + rows = calculate_execution_counts(opcode_stats, total) + emit_table( + ("Name", "Count:", "Self:", "Cumulative:", "Miss ratio:"), + rows + ) + +def emit_comparative_execution_counts( + base_opcode_stats, base_total, head_opcode_stats, head_total +): + with Section("Execution counts", summary="execution counts for all instructions"): + base_rows = calculate_execution_counts(base_opcode_stats, base_total) + head_rows = calculate_execution_counts(head_opcode_stats, head_total) + base_data = dict((x[0], x[1:]) for x in base_rows) + head_data = dict((x[0], x[1:]) for x in head_rows) + opcodes = set(base_data.keys()) | set(head_data.keys()) + + rows = [] + default = [0, "0.0%", "0.0%", 0] + for opcode in opcodes: + base_entry = base_data.get(opcode, default) + head_entry = head_data.get(opcode, default) + if base_entry[0] == 0: + change = 1 + else: + change = (head_entry[0] - base_entry[0]) / base_entry[0] + rows.append( + (opcode, base_entry[0], head_entry[0], + f"{100*change:0.1f}%")) + + rows.sort(key=lambda x: -abs(float(x[-1][:-1]))) + + emit_table( + ("Name", "Base Count:", "Head Count:", "Change:"), + rows + ) + +def get_defines(): + spec_path = os.path.join(os.path.dirname(__file__), "../../Python/specialize.c") + with open(spec_path) as spec_src: + defines = parse_kinds(spec_src) + return defines + +def emit_specialization_stats(opcode_stats): + defines = get_defines() + with Section("Specialization stats", summary="specialization stats by family"): + for i, opcode_stat in enumerate(opcode_stats): + name = opname[i] + print_specialization_stats(name, opcode_stat, defines) + +def emit_comparative_specialization_stats(base_opcode_stats, head_opcode_stats): + defines = get_defines() + with Section("Specialization stats", summary="specialization stats by family"): + for i, (base_opcode_stat, head_opcode_stat) in enumerate(zip(base_opcode_stats, head_opcode_stats)): + name = opname[i] + print_comparative_specialization_stats(name, base_opcode_stat, head_opcode_stat, defines) + +def calculate_specialization_effectiveness(opcode_stats, total): + basic, not_specialized, specialized = categorized_counts(opcode_stats) + return [ + ("Basic", basic, format_ratio(basic, total)), + ("Not specialized", not_specialized, format_ratio(not_specialized, total)), + ("Specialized", specialized, format_ratio(specialized, total)), + ] + +def emit_specialization_overview(opcode_stats, total): + with Section("Specialization effectiveness"): + rows = calculate_specialization_effectiveness(opcode_stats, total) + emit_table(("Instructions", "Count:", "Ratio:"), rows) + for title, field in (("Deferred", "specialization.deferred"), ("Misses", "specialization.miss")): + total = 0 + counts = [] + for i, opcode_stat in enumerate(opcode_stats): + # Avoid double counting misses + if title == "Misses" and "specializable" in opcode_stat: + continue + value = opcode_stat.get(field, 0) + counts.append((value, opname[i])) + total += value + counts.sort(reverse=True) + if total: + with Section(f"{title} by instruction", 3): + rows = [ (name, count, format_ratio(count, total)) for (count, name) in counts[:10] ] + emit_table(("Name", "Count:", "Ratio:"), rows) + +def emit_comparative_specialization_overview(base_opcode_stats, base_total, head_opcode_stats, head_total): + with Section("Specialization effectiveness"): + base_rows = calculate_specialization_effectiveness(base_opcode_stats, base_total) + head_rows = calculate_specialization_effectiveness(head_opcode_stats, head_total) + emit_table( + ("Instructions", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), + join_rows(base_rows, head_rows) + ) + +def get_stats_defines(): + stats_path = os.path.join(os.path.dirname(__file__), "../../Include/pystats.h") + with open(stats_path) as stats_src: + defines = parse_kinds(stats_src, prefix="EVAL_CALL") + return defines + +def calculate_call_stats(stats): + defines = get_stats_defines() + total = 0 + for key, value in stats.items(): + if "Calls to" in key: + total += value + rows = [] + for key, value in stats.items(): + if "Calls to" in key: + rows.append((key, value, format_ratio(value, total))) + elif key.startswith("Calls "): + name, index = key[:-1].split("[") + index = int(index) + label = name + " (" + pretty(defines[index][0]) + ")" + rows.append((label, value, format_ratio(value, total))) + for key, value in stats.items(): + if key.startswith("Frame"): + rows.append((key, value, format_ratio(value, total))) + return rows + +def emit_call_stats(stats): + with Section("Call stats", summary="Inlined calls and frame stats"): + rows = calculate_call_stats(stats) + emit_table(("", "Count:", "Ratio:"), rows) + +def emit_comparative_call_stats(base_stats, head_stats): + with Section("Call stats", summary="Inlined calls and frame stats"): + base_rows = calculate_call_stats(base_stats) + head_rows = calculate_call_stats(head_stats) + rows = join_rows(base_rows, head_rows) + rows.sort(key=lambda x: -float(x[-1][:-1])) + emit_table( + ("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), + rows + ) + +def calculate_object_stats(stats): + total_materializations = stats.get("Object new values") + total_allocations = stats.get("Object allocations") + stats.get("Object allocations from freelist") + total_increfs = stats.get("Object interpreter increfs") + stats.get("Object increfs") + total_decrefs = stats.get("Object interpreter decrefs") + stats.get("Object decrefs") + rows = [] + for key, value in stats.items(): + if key.startswith("Object"): + if "materialize" in key: + ratio = format_ratio(value, total_materializations) + elif "allocations" in key: + ratio = format_ratio(value, total_allocations) + elif "increfs" in key: + ratio = format_ratio(value, total_increfs) + elif "decrefs" in key: + ratio = format_ratio(value, total_decrefs) + else: + ratio = "" + label = key[6:].strip() + label = label[0].upper() + label[1:] + rows.append((label, value, ratio)) + return rows + +def emit_object_stats(stats): + with Section("Object stats", summary="allocations, frees and dict materializatons"): + rows = calculate_object_stats(stats) + emit_table(("", "Count:", "Ratio:"), rows) + +def emit_comparative_object_stats(base_stats, head_stats): + with Section("Object stats", summary="allocations, frees and dict materializatons"): + base_rows = calculate_object_stats(base_stats) + head_rows = calculate_object_stats(head_stats) + emit_table(("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), join_rows(base_rows, head_rows)) + +def get_total(opcode_stats): + total = 0 + for opcode_stat in opcode_stats: + if "execution_count" in opcode_stat: + total += opcode_stat['execution_count'] + return total + +def emit_pair_counts(opcode_stats, total): + pair_counts = [] + for i, opcode_stat in enumerate(opcode_stats): + if i == 0: + continue + for key, value in opcode_stat.items(): + if key.startswith("pair_count"): + x, _, _ = key[11:].partition("]") + if value: + pair_counts.append((value, (i, int(x)))) + with Section("Pair counts", summary="Pair counts for top 100 pairs"): + pair_counts.sort(reverse=True) + cumulative = 0 + rows = [] + for (count, pair) in itertools.islice(pair_counts, 100): + i, j = pair + cumulative += count + rows.append((opname[i] + " " + opname[j], count, format_ratio(count, total), + format_ratio(cumulative, total))) + emit_table(("Pair", "Count:", "Self:", "Cumulative:"), + rows + ) + with Section("Predecessor/Successor Pairs", summary="Top 5 predecessors and successors of each opcode"): + predecessors = collections.defaultdict(collections.Counter) + successors = collections.defaultdict(collections.Counter) + total_predecessors = collections.Counter() + total_successors = collections.Counter() + for count, (first, second) in pair_counts: + if count: + predecessors[second][first] = count + successors[first][second] = count + total_predecessors[second] += count + total_successors[first] += count + for name, i in opmap.items(): + total1 = total_predecessors[i] + total2 = total_successors[i] + if total1 == 0 and total2 == 0: + continue + pred_rows = succ_rows = () + if total1: + pred_rows = [(opname[pred], count, f"{count/total1:.1%}") + for (pred, count) in predecessors[i].most_common(5)] + if total2: + succ_rows = [(opname[succ], count, f"{count/total2:.1%}") + for (succ, count) in successors[i].most_common(5)] + with Section(name, 3, f"Successors and predecessors for {name}"): + emit_table(("Predecessors", "Count:", "Percentage:"), + pred_rows + ) + emit_table(("Successors", "Count:", "Percentage:"), + succ_rows + ) + +def output_single_stats(stats): + opcode_stats = extract_opcode_stats(stats) + total = get_total(opcode_stats) + emit_execution_counts(opcode_stats, total) + emit_pair_counts(opcode_stats, total) + emit_specialization_stats(opcode_stats) + emit_specialization_overview(opcode_stats, total) + emit_call_stats(stats) + emit_object_stats(stats) + with Section("Meta stats", summary="Meta statistics"): + emit_table(("", "Count:"), [('Number of data files', stats['__nfiles__'])]) + + +def output_comparative_stats(base_stats, head_stats): + base_opcode_stats = extract_opcode_stats(base_stats) + base_total = get_total(base_opcode_stats) + + head_opcode_stats = extract_opcode_stats(head_stats) + head_total = get_total(head_opcode_stats) + + emit_comparative_execution_counts( + base_opcode_stats, base_total, head_opcode_stats, head_total + ) + emit_comparative_specialization_stats( + base_opcode_stats, head_opcode_stats + ) + emit_comparative_specialization_overview( + base_opcode_stats, base_total, head_opcode_stats, head_total + ) + emit_comparative_call_stats(base_stats, head_stats) + emit_comparative_object_stats(base_stats, head_stats) + +def output_stats(inputs, json_output=None): + if len(inputs) == 1: + stats = gather_stats(inputs[0]) + if json_output is not None: + json.dump(stats, json_output) + output_single_stats(stats) + elif len(inputs) == 2: + if json_output is not None: + raise ValueError( + "Can not output to JSON when there are multiple inputs" + ) + + base_stats = gather_stats(inputs[0]) + head_stats = gather_stats(inputs[1]) + output_comparative_stats(base_stats, head_stats) + + print("---") + print("Stats gathered on:", date.today()) + +def main(): + parser = argparse.ArgumentParser(description="Summarize pystats results") + + parser.add_argument( + "inputs", + nargs="*", + type=str, + default=[DEFAULT_DIR], + help=f""" + Input source(s). + For each entry, if a .json file, the output provided by --json-output from a previous run; + if a directory, a directory containing raw pystats .txt files. + If one source is provided, its stats are printed. + If two sources are provided, comparative stats are printed. + Default is {DEFAULT_DIR}. + """ + ) + + parser.add_argument( + "--json-output", + nargs="?", + type=argparse.FileType("w"), + help="Output complete raw results to the given JSON file." + ) + + args = parser.parse_args() + + if len(args.inputs) > 2: + raise ValueError("0-2 arguments may be provided.") + + output_stats(args.inputs, json_output=args.json_output) + +if __name__ == "__main__": + main() diff --git a/Tools/scripts/texi2html.py b/Tools/scripts/texi2html.py deleted file mode 100755 index c06d812ab3f..00000000000 --- a/Tools/scripts/texi2html.py +++ /dev/null @@ -1,2071 +0,0 @@ -#! /usr/bin/env python3 - -# Convert GNU texinfo files into HTML, one file per node. -# Based on Texinfo 2.14. -# Usage: texi2html [-d] [-d] [-c] inputfile outputdirectory -# The input file must be a complete texinfo file, e.g. emacs.texi. -# This creates many files (one per info node) in the output directory, -# overwriting existing files of the same name. All files created have -# ".html" as their extension. - - -# XXX To do: -# - handle @comment*** correctly -# - handle @xref {some words} correctly -# - handle @ftable correctly (items aren't indexed?) -# - handle @itemx properly -# - handle @exdent properly -# - add links directly to the proper line from indices -# - check against the definitive list of @-cmds; we still miss (among others): -# - @defindex (hard) -# - @c(omment) in the middle of a line (rarely used) -# - @this* (not really needed, only used in headers anyway) -# - @today{} (ever used outside title page?) - -# More consistent handling of chapters/sections/etc. -# Lots of documentation -# Many more options: -# -top designate top node -# -links customize which types of links are included -# -split split at chapters or sections instead of nodes -# -name Allow different types of filename handling. Non unix systems -# will have problems with long node names -# ... -# Support the most recent texinfo version and take a good look at HTML 3.0 -# More debugging output (customizable) and more flexible error handling -# How about icons ? - -# rpyron 2002-05-07 -# Robert Pyron -# 1. BUGFIX: In function makefile(), strip blanks from the nodename. -# This is necessary to match the behavior of parser.makeref() and -# parser.do_node(). -# 2. BUGFIX fixed KeyError in end_ifset (well, I may have just made -# it go away, rather than fix it) -# 3. BUGFIX allow @menu and menu items inside @ifset or @ifclear -# 4. Support added for: -# @uref URL reference -# @image image file reference (see note below) -# @multitable output an HTML table -# @vtable -# 5. Partial support for accents, to match MAKEINFO output -# 6. I added a new command-line option, '-H basename', to specify -# HTML Help output. This will cause three files to be created -# in the current directory: -# `basename`.hhp HTML Help Workshop project file -# `basename`.hhc Contents file for the project -# `basename`.hhk Index file for the project -# When fed into HTML Help Workshop, the resulting file will be -# named `basename`.chm. -# 7. A new class, HTMLHelp, to accomplish item 6. -# 8. Various calls to HTMLHelp functions. -# A NOTE ON IMAGES: Just as 'outputdirectory' must exist before -# running this program, all referenced images must already exist -# in outputdirectory. - -import os -import sys -import string -import re - -MAGIC = '\\input texinfo' - -cmprog = re.compile('^@([a-z]+)([ \t]|$)') # Command (line-oriented) -blprog = re.compile('^[ \t]*$') # Blank line -kwprog = re.compile('@[a-z]+') # Keyword (embedded, usually - # with {} args) -spprog = re.compile('[\n@{}&<>]') # Special characters in - # running text - # - # menu item (Yuck!) -miprog = re.compile(r'^\* ([^:]*):(:|[ \t]*([^\t,\n.]+)([^ \t\n]*))[ \t\n]*') -# 0 1 1 2 3 34 42 0 -# ----- ---------- --------- -# -|----------------------------- -# ----------------------------------------------------- - - - - -class HTMLNode: - """Some of the parser's functionality is separated into this class. - - A Node accumulates its contents, takes care of links to other Nodes - and saves itself when it is finished and all links are resolved. - """ - - DOCTYPE = '' - - type = 0 - cont = '' - epilogue = '\n' - - def __init__(self, dir, name, topname, title, next, prev, up): - self.dirname = dir - self.name = name - if topname: - self.topname = topname - else: - self.topname = name - self.title = title - self.next = next - self.prev = prev - self.up = up - self.lines = [] - - def write(self, *lines): - for line in lines: - self.lines.append(line) - - def flush(self): - with open(self.dirname + '/' + makefile(self.name), 'w') as fp: - fp.write(self.prologue) - fp.write(self.text) - fp.write(self.epilogue) - - def link(self, label, nodename, rel=None, rev=None): - if nodename: - if nodename.lower() == '(dir)': - addr = '../dir.html' - title = '' - else: - addr = makefile(nodename) - title = ' TITLE="%s"' % nodename - self.write(label, ': ', nodename, ' \n') - - def finalize(self): - length = len(self.lines) - self.text = ''.join(self.lines) - self.lines = [] - self.open_links() - self.output_links() - self.close_links() - links = ''.join(self.lines) - self.lines = [] - self.prologue = ( - self.DOCTYPE + - '\n\n' - ' \n' - ' ' + self.title + '\n' - ' \n' - ' \n' - ' \n' - '\n' + - links) - if length > 20: - self.epilogue = '

    \n%s\n' % links - - def open_links(self): - self.write('


    \n') - - def close_links(self): - self.write('
    \n') - - def output_links(self): - if self.cont != self.next: - self.link(' Cont', self.cont) - self.link(' Next', self.next, rel='Next') - self.link(' Prev', self.prev, rel='Previous') - self.link(' Up', self.up, rel='Up') - if self.name != self.topname: - self.link(' Top', self.topname) - - -class HTML3Node(HTMLNode): - - DOCTYPE = '' - - def open_links(self): - self.write('\n') - - -class TexinfoParser: - - COPYRIGHT_SYMBOL = "©" - FN_ID_PATTERN = "(%(id)s)" - FN_SOURCE_PATTERN = '' \ - + FN_ID_PATTERN + '' - FN_TARGET_PATTERN = '' \ - + FN_ID_PATTERN + '\n%(text)s

    \n' - FN_HEADER = '\n

    \n


    \n' \ - 'Footnotes\n

    ' - - - Node = HTMLNode - - # Initialize an instance - def __init__(self): - self.unknown = {} # statistics about unknown @-commands - self.filenames = {} # Check for identical filenames - self.debugging = 0 # larger values produce more output - self.print_headers = 0 # always print headers? - self.nodefp = None # open file we're writing to - self.nodelineno = 0 # Linenumber relative to node - self.links = None # Links from current node - self.savetext = None # If not None, save text head instead - self.savestack = [] # If not None, save text head instead - self.htmlhelp = None # html help data - self.dirname = 'tmp' # directory where files are created - self.includedir = '.' # directory to search @include files - self.nodename = '' # name of current node - self.topname = '' # name of top node (first node seen) - self.title = '' # title of this whole Texinfo tree - self.resetindex() # Reset all indices - self.contents = [] # Reset table of contents - self.numbering = [] # Reset section numbering counters - self.nofill = 0 # Normal operation: fill paragraphs - self.values={'html': 1} # Names that should be parsed in ifset - self.stackinfo={} # Keep track of state in the stack - # XXX The following should be reset per node?! - self.footnotes = [] # Reset list of footnotes - self.itemarg = None # Reset command used by @item - self.itemnumber = None # Reset number for @item in @enumerate - self.itemindex = None # Reset item index name - self.node = None - self.nodestack = [] - self.cont = 0 - self.includedepth = 0 - - # Set htmlhelp helper class - def sethtmlhelp(self, htmlhelp): - self.htmlhelp = htmlhelp - - # Set (output) directory name - def setdirname(self, dirname): - self.dirname = dirname - - # Set include directory name - def setincludedir(self, includedir): - self.includedir = includedir - - # Parse the contents of an entire file - def parse(self, fp): - line = fp.readline() - lineno = 1 - while line and (line[0] == '%' or blprog.match(line)): - line = fp.readline() - lineno = lineno + 1 - if line[:len(MAGIC)] != MAGIC: - raise SyntaxError('file does not begin with %r' % (MAGIC,)) - self.parserest(fp, lineno) - - # Parse the contents of a file, not expecting a MAGIC header - def parserest(self, fp, initial_lineno): - lineno = initial_lineno - self.done = 0 - self.skip = 0 - self.stack = [] - accu = [] - while not self.done: - line = fp.readline() - self.nodelineno = self.nodelineno + 1 - if not line: - if accu: - if not self.skip: self.process(accu) - accu = [] - if initial_lineno > 0: - print('*** EOF before @bye') - break - lineno = lineno + 1 - mo = cmprog.match(line) - if mo: - a, b = mo.span(1) - cmd = line[a:b] - if cmd in ('noindent', 'refill'): - accu.append(line) - else: - if accu: - if not self.skip: - self.process(accu) - accu = [] - self.command(line, mo) - elif blprog.match(line) and \ - 'format' not in self.stack and \ - 'example' not in self.stack: - if accu: - if not self.skip: - self.process(accu) - if self.nofill: - self.write('\n') - else: - self.write('

    \n') - accu = [] - else: - # Append the line including trailing \n! - accu.append(line) - # - if self.skip: - print('*** Still skipping at the end') - if self.stack: - print('*** Stack not empty at the end') - print('***', self.stack) - if self.includedepth == 0: - while self.nodestack: - self.nodestack[-1].finalize() - self.nodestack[-1].flush() - del self.nodestack[-1] - - # Start saving text in a buffer instead of writing it to a file - def startsaving(self): - if self.savetext is not None: - self.savestack.append(self.savetext) - # print '*** Recursively saving text, expect trouble' - self.savetext = '' - - # Return the text saved so far and start writing to file again - def collectsavings(self): - savetext = self.savetext - if len(self.savestack) > 0: - self.savetext = self.savestack[-1] - del self.savestack[-1] - else: - self.savetext = None - return savetext or '' - - # Write text to file, or save it in a buffer, or ignore it - def write(self, *args): - try: - text = ''.join(args) - except: - print(args) - raise TypeError - if self.savetext is not None: - self.savetext = self.savetext + text - elif self.nodefp: - self.nodefp.write(text) - elif self.node: - self.node.write(text) - - # Complete the current node -- write footnotes and close file - def endnode(self): - if self.savetext is not None: - print('*** Still saving text at end of node') - dummy = self.collectsavings() - if self.footnotes: - self.writefootnotes() - if self.nodefp: - if self.nodelineno > 20: - self.write('


    \n') - [name, next, prev, up] = self.nodelinks[:4] - self.link('Next', next) - self.link('Prev', prev) - self.link('Up', up) - if self.nodename != self.topname: - self.link('Top', self.topname) - self.write('
    \n') - self.write('\n') - self.nodefp.close() - self.nodefp = None - elif self.node: - if not self.cont and \ - (not self.node.type or \ - (self.node.next and self.node.prev and self.node.up)): - self.node.finalize() - self.node.flush() - else: - self.nodestack.append(self.node) - self.node = None - self.nodename = '' - - # Process a list of lines, expanding embedded @-commands - # This mostly distinguishes between menus and normal text - def process(self, accu): - if self.debugging > 1: - print('!'*self.debugging, 'process:', self.skip, self.stack, end=' ') - if accu: print(accu[0][:30], end=' ') - if accu[0][30:] or accu[1:]: print('...', end=' ') - print() - if self.inmenu(): - # XXX should be done differently - for line in accu: - mo = miprog.match(line) - if not mo: - line = line.strip() + '\n' - self.expand(line) - continue - bgn, end = mo.span(0) - a, b = mo.span(1) - c, d = mo.span(2) - e, f = mo.span(3) - g, h = mo.span(4) - label = line[a:b] - nodename = line[c:d] - if nodename[0] == ':': nodename = label - else: nodename = line[e:f] - punct = line[g:h] - self.write('
  • ', nodename, - '', punct, '\n') - self.htmlhelp.menuitem(nodename) - self.expand(line[end:]) - else: - text = ''.join(accu) - self.expand(text) - - # find 'menu' (we might be inside 'ifset' or 'ifclear') - def inmenu(self): - #if 'menu' in self.stack: - # print 'inmenu :', self.skip, self.stack, self.stackinfo - stack = self.stack - while stack and stack[-1] in ('ifset','ifclear'): - try: - if self.stackinfo[len(stack)]: - return 0 - except KeyError: - pass - stack = stack[:-1] - return (stack and stack[-1] == 'menu') - - # Write a string, expanding embedded @-commands - def expand(self, text): - stack = [] - i = 0 - n = len(text) - while i < n: - start = i - mo = spprog.search(text, i) - if mo: - i = mo.start() - else: - self.write(text[start:]) - break - self.write(text[start:i]) - c = text[i] - i = i+1 - if c == '\n': - self.write('\n') - continue - if c == '<': - self.write('<') - continue - if c == '>': - self.write('>') - continue - if c == '&': - self.write('&') - continue - if c == '{': - stack.append('') - continue - if c == '}': - if not stack: - print('*** Unmatched }') - self.write('}') - continue - cmd = stack[-1] - del stack[-1] - try: - method = getattr(self, 'close_' + cmd) - except AttributeError: - self.unknown_close(cmd) - continue - method() - continue - if c != '@': - # Cannot happen unless spprog is changed - raise RuntimeError('unexpected funny %r' % c) - start = i - while i < n and text[i] in string.ascii_letters: i = i+1 - if i == start: - # @ plus non-letter: literal next character - i = i+1 - c = text[start:i] - if c == ':': - # `@:' means no extra space after - # preceding `.', `?', `!' or `:' - pass - else: - # `@.' means a sentence-ending period; - # `@@', `@{', `@}' quote `@', `{', `}' - self.write(c) - continue - cmd = text[start:i] - if i < n and text[i] == '{': - i = i+1 - stack.append(cmd) - try: - method = getattr(self, 'open_' + cmd) - except AttributeError: - self.unknown_open(cmd) - continue - method() - continue - try: - method = getattr(self, 'handle_' + cmd) - except AttributeError: - self.unknown_handle(cmd) - continue - method() - if stack: - print('*** Stack not empty at para:', stack) - - # --- Handle unknown embedded @-commands --- - - def unknown_open(self, cmd): - print('*** No open func for @' + cmd + '{...}') - cmd = cmd + '{' - self.write('@', cmd) - if cmd not in self.unknown: - self.unknown[cmd] = 1 - else: - self.unknown[cmd] = self.unknown[cmd] + 1 - - def unknown_close(self, cmd): - print('*** No close func for @' + cmd + '{...}') - cmd = '}' + cmd - self.write('}') - if cmd not in self.unknown: - self.unknown[cmd] = 1 - else: - self.unknown[cmd] = self.unknown[cmd] + 1 - - def unknown_handle(self, cmd): - print('*** No handler for @' + cmd) - self.write('@', cmd) - if cmd not in self.unknown: - self.unknown[cmd] = 1 - else: - self.unknown[cmd] = self.unknown[cmd] + 1 - - # XXX The following sections should be ordered as the texinfo docs - - # --- Embedded @-commands without {} argument list -- - - def handle_noindent(self): pass - - def handle_refill(self): pass - - # --- Include file handling --- - - def do_include(self, args): - file = args - file = os.path.join(self.includedir, file) - try: - fp = open(file, 'r') - except IOError as msg: - print('*** Can\'t open include file', repr(file)) - return - with fp: - print('!'*self.debugging, '--> file', repr(file)) - save_done = self.done - save_skip = self.skip - save_stack = self.stack - self.includedepth = self.includedepth + 1 - self.parserest(fp, 0) - self.includedepth = self.includedepth - 1 - self.done = save_done - self.skip = save_skip - self.stack = save_stack - print('!'*self.debugging, '<-- file', repr(file)) - - # --- Special Insertions --- - - def open_dmn(self): pass - def close_dmn(self): pass - - def open_dots(self): self.write('...') - def close_dots(self): pass - - def open_bullet(self): pass - def close_bullet(self): pass - - def open_TeX(self): self.write('TeX') - def close_TeX(self): pass - - def handle_copyright(self): self.write(self.COPYRIGHT_SYMBOL) - def open_copyright(self): self.write(self.COPYRIGHT_SYMBOL) - def close_copyright(self): pass - - def open_minus(self): self.write('-') - def close_minus(self): pass - - # --- Accents --- - - # rpyron 2002-05-07 - # I would like to do at least as well as makeinfo when - # it is producing HTML output: - # - # input output - # @"o @"o umlaut accent - # @'o 'o acute accent - # @,{c} @,{c} cedilla accent - # @=o @=o macron/overbar accent - # @^o @^o circumflex accent - # @`o `o grave accent - # @~o @~o tilde accent - # @dotaccent{o} @dotaccent{o} overdot accent - # @H{o} @H{o} long Hungarian umlaut - # @ringaccent{o} @ringaccent{o} ring accent - # @tieaccent{oo} @tieaccent{oo} tie-after accent - # @u{o} @u{o} breve accent - # @ubaraccent{o} @ubaraccent{o} underbar accent - # @udotaccent{o} @udotaccent{o} underdot accent - # @v{o} @v{o} hacek or check accent - # @exclamdown{} ¡ upside-down ! - # @questiondown{} ¿ upside-down ? - # @aa{},@AA{} å,Å a,A with circle - # @ae{},@AE{} æ,Æ ae,AE ligatures - # @dotless{i} @dotless{i} dotless i - # @dotless{j} @dotless{j} dotless j - # @l{},@L{} l/,L/ suppressed-L,l - # @o{},@O{} ø,Ø O,o with slash - # @oe{},@OE{} oe,OE oe,OE ligatures - # @ss{} ß es-zet or sharp S - # - # The following character codes and approximations have been - # copied from makeinfo's HTML output. - - def open_exclamdown(self): self.write('¡') # upside-down ! - def close_exclamdown(self): pass - def open_questiondown(self): self.write('¿') # upside-down ? - def close_questiondown(self): pass - def open_aa(self): self.write('å') # a with circle - def close_aa(self): pass - def open_AA(self): self.write('Å') # A with circle - def close_AA(self): pass - def open_ae(self): self.write('æ') # ae ligatures - def close_ae(self): pass - def open_AE(self): self.write('Æ') # AE ligatures - def close_AE(self): pass - def open_o(self): self.write('ø') # o with slash - def close_o(self): pass - def open_O(self): self.write('Ø') # O with slash - def close_O(self): pass - def open_ss(self): self.write('ß') # es-zet or sharp S - def close_ss(self): pass - def open_oe(self): self.write('oe') # oe ligatures - def close_oe(self): pass - def open_OE(self): self.write('OE') # OE ligatures - def close_OE(self): pass - def open_l(self): self.write('l/') # suppressed-l - def close_l(self): pass - def open_L(self): self.write('L/') # suppressed-L - def close_L(self): pass - - # --- Special Glyphs for Examples --- - - def open_result(self): self.write('=>') - def close_result(self): pass - - def open_expansion(self): self.write('==>') - def close_expansion(self): pass - - def open_print(self): self.write('-|') - def close_print(self): pass - - def open_error(self): self.write('error-->') - def close_error(self): pass - - def open_equiv(self): self.write('==') - def close_equiv(self): pass - - def open_point(self): self.write('-!-') - def close_point(self): pass - - # --- Cross References --- - - def open_pxref(self): - self.write('see ') - self.startsaving() - def close_pxref(self): - self.makeref() - - def open_xref(self): - self.write('See ') - self.startsaving() - def close_xref(self): - self.makeref() - - def open_ref(self): - self.startsaving() - def close_ref(self): - self.makeref() - - def open_inforef(self): - self.write('See info file ') - self.startsaving() - def close_inforef(self): - text = self.collectsavings() - args = [s.strip() for s in text.split(',')] - while len(args) < 3: args.append('') - node = args[0] - file = args[2] - self.write('`', file, '\', node `', node, '\'') - - def makeref(self): - text = self.collectsavings() - args = [s.strip() for s in text.split(',')] - while len(args) < 5: args.append('') - nodename = label = args[0] - if args[2]: label = args[2] - file = args[3] - title = args[4] - href = makefile(nodename) - if file: - href = '../' + file + '/' + href - self.write('', label, '') - - # rpyron 2002-05-07 uref support - def open_uref(self): - self.startsaving() - def close_uref(self): - text = self.collectsavings() - args = [s.strip() for s in text.split(',')] - while len(args) < 2: args.append('') - href = args[0] - label = args[1] - if not label: label = href - self.write('', label, '') - - # rpyron 2002-05-07 image support - # GNU makeinfo producing HTML output tries `filename.png'; if - # that does not exist, it tries `filename.jpg'. If that does - # not exist either, it complains. GNU makeinfo does not handle - # GIF files; however, I include GIF support here because - # MySQL documentation uses GIF files. - - def open_image(self): - self.startsaving() - def close_image(self): - self.makeimage() - def makeimage(self): - text = self.collectsavings() - args = [s.strip() for s in text.split(',')] - while len(args) < 5: args.append('') - filename = args[0] - width = args[1] - height = args[2] - alt = args[3] - ext = args[4] - - # The HTML output will have a reference to the image - # that is relative to the HTML output directory, - # which is what 'filename' gives us. However, we need - # to find it relative to our own current directory, - # so we construct 'imagename'. - imagelocation = self.dirname + '/' + filename - - if os.path.exists(imagelocation+'.png'): - filename += '.png' - elif os.path.exists(imagelocation+'.jpg'): - filename += '.jpg' - elif os.path.exists(imagelocation+'.gif'): # MySQL uses GIF files - filename += '.gif' - else: - print("*** Cannot find image " + imagelocation) - #TODO: what is 'ext'? - self.write('' ) - self.htmlhelp.addimage(imagelocation) - - - # --- Marking Words and Phrases --- - - # --- Other @xxx{...} commands --- - - def open_(self): pass # Used by {text enclosed in braces} - def close_(self): pass - - open_asis = open_ - close_asis = close_ - - def open_cite(self): self.write('') - def close_cite(self): self.write('') - - def open_code(self): self.write('') - def close_code(self): self.write('') - - def open_t(self): self.write('') - def close_t(self): self.write('') - - def open_dfn(self): self.write('') - def close_dfn(self): self.write('') - - def open_emph(self): self.write('') - def close_emph(self): self.write('') - - def open_i(self): self.write('') - def close_i(self): self.write('') - - def open_footnote(self): - # if self.savetext is not None: - # print '*** Recursive footnote -- expect weirdness' - id = len(self.footnotes) + 1 - self.write(self.FN_SOURCE_PATTERN % {'id': repr(id)}) - self.startsaving() - - def close_footnote(self): - id = len(self.footnotes) + 1 - self.footnotes.append((id, self.collectsavings())) - - def writefootnotes(self): - self.write(self.FN_HEADER) - for id, text in self.footnotes: - self.write(self.FN_TARGET_PATTERN - % {'id': repr(id), 'text': text}) - self.footnotes = [] - - def open_file(self): self.write('') - def close_file(self): self.write('') - - def open_kbd(self): self.write('') - def close_kbd(self): self.write('') - - def open_key(self): self.write('') - def close_key(self): self.write('') - - def open_r(self): self.write('') - def close_r(self): self.write('') - - def open_samp(self): self.write('`') - def close_samp(self): self.write('\'') - - def open_sc(self): self.write('') - def close_sc(self): self.write('') - - def open_strong(self): self.write('') - def close_strong(self): self.write('') - - def open_b(self): self.write('') - def close_b(self): self.write('') - - def open_var(self): self.write('') - def close_var(self): self.write('') - - def open_w(self): self.write('') - def close_w(self): self.write('') - - def open_url(self): self.startsaving() - def close_url(self): - text = self.collectsavings() - self.write('', text, '') - - def open_email(self): self.startsaving() - def close_email(self): - text = self.collectsavings() - self.write('', text, '') - - open_titlefont = open_ - close_titlefont = close_ - - def open_small(self): pass - def close_small(self): pass - - def command(self, line, mo): - a, b = mo.span(1) - cmd = line[a:b] - args = line[b:].strip() - if self.debugging > 1: - print('!'*self.debugging, 'command:', self.skip, self.stack, \ - '@' + cmd, args) - try: - func = getattr(self, 'do_' + cmd) - except AttributeError: - try: - func = getattr(self, 'bgn_' + cmd) - except AttributeError: - # don't complain if we are skipping anyway - if not self.skip: - self.unknown_cmd(cmd, args) - return - self.stack.append(cmd) - func(args) - return - if not self.skip or cmd == 'end': - func(args) - - def unknown_cmd(self, cmd, args): - print('*** unknown', '@' + cmd, args) - if cmd not in self.unknown: - self.unknown[cmd] = 1 - else: - self.unknown[cmd] = self.unknown[cmd] + 1 - - def do_end(self, args): - words = args.split() - if not words: - print('*** @end w/o args') - else: - cmd = words[0] - if not self.stack or self.stack[-1] != cmd: - print('*** @end', cmd, 'unexpected') - else: - del self.stack[-1] - try: - func = getattr(self, 'end_' + cmd) - except AttributeError: - self.unknown_end(cmd) - return - func() - - def unknown_end(self, cmd): - cmd = 'end ' + cmd - print('*** unknown', '@' + cmd) - if cmd not in self.unknown: - self.unknown[cmd] = 1 - else: - self.unknown[cmd] = self.unknown[cmd] + 1 - - # --- Comments --- - - def do_comment(self, args): pass - do_c = do_comment - - # --- Conditional processing --- - - def bgn_ifinfo(self, args): pass - def end_ifinfo(self): pass - - def bgn_iftex(self, args): self.skip = self.skip + 1 - def end_iftex(self): self.skip = self.skip - 1 - - def bgn_ignore(self, args): self.skip = self.skip + 1 - def end_ignore(self): self.skip = self.skip - 1 - - def bgn_tex(self, args): self.skip = self.skip + 1 - def end_tex(self): self.skip = self.skip - 1 - - def do_set(self, args): - fields = args.split(' ') - key = fields[0] - if len(fields) == 1: - value = 1 - else: - value = ' '.join(fields[1:]) - self.values[key] = value - - def do_clear(self, args): - self.values[args] = None - - def bgn_ifset(self, args): - if args not in self.values or self.values[args] is None: - self.skip = self.skip + 1 - self.stackinfo[len(self.stack)] = 1 - else: - self.stackinfo[len(self.stack)] = 0 - def end_ifset(self): - try: - if self.stackinfo[len(self.stack) + 1]: - self.skip = self.skip - 1 - del self.stackinfo[len(self.stack) + 1] - except KeyError: - print('*** end_ifset: KeyError :', len(self.stack) + 1) - - def bgn_ifclear(self, args): - if args in self.values and self.values[args] is not None: - self.skip = self.skip + 1 - self.stackinfo[len(self.stack)] = 1 - else: - self.stackinfo[len(self.stack)] = 0 - def end_ifclear(self): - try: - if self.stackinfo[len(self.stack) + 1]: - self.skip = self.skip - 1 - del self.stackinfo[len(self.stack) + 1] - except KeyError: - print('*** end_ifclear: KeyError :', len(self.stack) + 1) - - def open_value(self): - self.startsaving() - - def close_value(self): - key = self.collectsavings() - if key in self.values: - self.write(self.values[key]) - else: - print('*** Undefined value: ', key) - - # --- Beginning a file --- - - do_finalout = do_comment - do_setchapternewpage = do_comment - do_setfilename = do_comment - - def do_settitle(self, args): - self.startsaving() - self.expand(args) - self.title = self.collectsavings() - def do_parskip(self, args): pass - - # --- Ending a file --- - - def do_bye(self, args): - self.endnode() - self.done = 1 - - # --- Title page --- - - def bgn_titlepage(self, args): self.skip = self.skip + 1 - def end_titlepage(self): self.skip = self.skip - 1 - def do_shorttitlepage(self, args): pass - - def do_center(self, args): - # Actually not used outside title page... - self.write('

    ') - self.expand(args) - self.write('

    \n') - do_title = do_center - do_subtitle = do_center - do_author = do_center - - do_vskip = do_comment - do_vfill = do_comment - do_smallbook = do_comment - - do_paragraphindent = do_comment - do_setchapternewpage = do_comment - do_headings = do_comment - do_footnotestyle = do_comment - - do_evenheading = do_comment - do_evenfooting = do_comment - do_oddheading = do_comment - do_oddfooting = do_comment - do_everyheading = do_comment - do_everyfooting = do_comment - - # --- Nodes --- - - def do_node(self, args): - self.endnode() - self.nodelineno = 0 - parts = [s.strip() for s in args.split(',')] - while len(parts) < 4: parts.append('') - self.nodelinks = parts - [name, next, prev, up] = parts[:4] - file = self.dirname + '/' + makefile(name) - if file in self.filenames: - print('*** Filename already in use: ', file) - else: - if self.debugging: print('!'*self.debugging, '--- writing', file) - self.filenames[file] = 1 - # self.nodefp = open(file, 'w') - self.nodename = name - if self.cont and self.nodestack: - self.nodestack[-1].cont = self.nodename - if not self.topname: self.topname = name - title = name - if self.title: title = title + ' -- ' + self.title - self.node = self.Node(self.dirname, self.nodename, self.topname, - title, next, prev, up) - self.htmlhelp.addnode(self.nodename,next,prev,up,file) - - def link(self, label, nodename): - if nodename: - if nodename.lower() == '(dir)': - addr = '../dir.html' - else: - addr = makefile(nodename) - self.write(label, ': ', nodename, ' \n') - - # --- Sectioning commands --- - - def popstack(self, type): - if (self.node): - self.node.type = type - while self.nodestack: - if self.nodestack[-1].type > type: - self.nodestack[-1].finalize() - self.nodestack[-1].flush() - del self.nodestack[-1] - elif self.nodestack[-1].type == type: - if not self.nodestack[-1].next: - self.nodestack[-1].next = self.node.name - if not self.node.prev: - self.node.prev = self.nodestack[-1].name - self.nodestack[-1].finalize() - self.nodestack[-1].flush() - del self.nodestack[-1] - else: - if type > 1 and not self.node.up: - self.node.up = self.nodestack[-1].name - break - - def do_chapter(self, args): - self.heading('H1', args, 0) - self.popstack(1) - - def do_unnumbered(self, args): - self.heading('H1', args, -1) - self.popstack(1) - def do_appendix(self, args): - self.heading('H1', args, -1) - self.popstack(1) - def do_top(self, args): - self.heading('H1', args, -1) - def do_chapheading(self, args): - self.heading('H1', args, -1) - def do_majorheading(self, args): - self.heading('H1', args, -1) - - def do_section(self, args): - self.heading('H1', args, 1) - self.popstack(2) - - def do_unnumberedsec(self, args): - self.heading('H1', args, -1) - self.popstack(2) - def do_appendixsec(self, args): - self.heading('H1', args, -1) - self.popstack(2) - do_appendixsection = do_appendixsec - def do_heading(self, args): - self.heading('H1', args, -1) - - def do_subsection(self, args): - self.heading('H2', args, 2) - self.popstack(3) - def do_unnumberedsubsec(self, args): - self.heading('H2', args, -1) - self.popstack(3) - def do_appendixsubsec(self, args): - self.heading('H2', args, -1) - self.popstack(3) - def do_subheading(self, args): - self.heading('H2', args, -1) - - def do_subsubsection(self, args): - self.heading('H3', args, 3) - self.popstack(4) - def do_unnumberedsubsubsec(self, args): - self.heading('H3', args, -1) - self.popstack(4) - def do_appendixsubsubsec(self, args): - self.heading('H3', args, -1) - self.popstack(4) - def do_subsubheading(self, args): - self.heading('H3', args, -1) - - def heading(self, type, args, level): - if level >= 0: - while len(self.numbering) <= level: - self.numbering.append(0) - del self.numbering[level+1:] - self.numbering[level] = self.numbering[level] + 1 - x = '' - for i in self.numbering: - x = x + repr(i) + '.' - args = x + ' ' + args - self.contents.append((level, args, self.nodename)) - self.write('<', type, '>') - self.expand(args) - self.write('\n') - if self.debugging or self.print_headers: - print('---', args) - - def do_contents(self, args): - # pass - self.listcontents('Table of Contents', 999) - - def do_shortcontents(self, args): - pass - # self.listcontents('Short Contents', 0) - do_summarycontents = do_shortcontents - - def listcontents(self, title, maxlevel): - self.write('

    ', title, '

    \n
      \n') - prevlevels = [0] - for level, title, node in self.contents: - if level > maxlevel: - continue - if level > prevlevels[-1]: - # can only advance one level at a time - self.write(' '*prevlevels[-1], '
        \n') - prevlevels.append(level) - elif level < prevlevels[-1]: - # might drop back multiple levels - while level < prevlevels[-1]: - del prevlevels[-1] - self.write(' '*prevlevels[-1], - '
      \n') - self.write(' '*level, '
    • ') - self.expand(title) - self.write('\n') - self.write('
    \n' * len(prevlevels)) - - # --- Page lay-out --- - - # These commands are only meaningful in printed text - - def do_page(self, args): pass - - def do_need(self, args): pass - - def bgn_group(self, args): pass - def end_group(self): pass - - # --- Line lay-out --- - - def do_sp(self, args): - if self.nofill: - self.write('\n') - else: - self.write('

    \n') - - def do_hline(self, args): - self.write('


    ') - - # --- Function and variable definitions --- - - def bgn_deffn(self, args): - self.write('
    ') - self.do_deffnx(args) - - def end_deffn(self): - self.write('
    \n') - - def do_deffnx(self, args): - self.write('
    ') - words = splitwords(args, 2) - [category, name], rest = words[:2], words[2:] - self.expand('@b{%s}' % name) - for word in rest: self.expand(' ' + makevar(word)) - #self.expand(' -- ' + category) - self.write('\n
    ') - self.index('fn', name) - - def bgn_defun(self, args): self.bgn_deffn('Function ' + args) - end_defun = end_deffn - def do_defunx(self, args): self.do_deffnx('Function ' + args) - - def bgn_defmac(self, args): self.bgn_deffn('Macro ' + args) - end_defmac = end_deffn - def do_defmacx(self, args): self.do_deffnx('Macro ' + args) - - def bgn_defspec(self, args): self.bgn_deffn('{Special Form} ' + args) - end_defspec = end_deffn - def do_defspecx(self, args): self.do_deffnx('{Special Form} ' + args) - - def bgn_defvr(self, args): - self.write('
    ') - self.do_defvrx(args) - - end_defvr = end_deffn - - def do_defvrx(self, args): - self.write('
    ') - words = splitwords(args, 2) - [category, name], rest = words[:2], words[2:] - self.expand('@code{%s}' % name) - # If there are too many arguments, show them - for word in rest: self.expand(' ' + word) - #self.expand(' -- ' + category) - self.write('\n
    ') - self.index('vr', name) - - def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args) - end_defvar = end_defvr - def do_defvarx(self, args): self.do_defvrx('Variable ' + args) - - def bgn_defopt(self, args): self.bgn_defvr('{User Option} ' + args) - end_defopt = end_defvr - def do_defoptx(self, args): self.do_defvrx('{User Option} ' + args) - - # --- Ditto for typed languages --- - - def bgn_deftypefn(self, args): - self.write('
    ') - self.do_deftypefnx(args) - - end_deftypefn = end_deffn - - def do_deftypefnx(self, args): - self.write('
    ') - words = splitwords(args, 3) - [category, datatype, name], rest = words[:3], words[3:] - self.expand('@code{%s} @b{%s}' % (datatype, name)) - for word in rest: self.expand(' ' + makevar(word)) - #self.expand(' -- ' + category) - self.write('\n
    ') - self.index('fn', name) - - - def bgn_deftypefun(self, args): self.bgn_deftypefn('Function ' + args) - end_deftypefun = end_deftypefn - def do_deftypefunx(self, args): self.do_deftypefnx('Function ' + args) - - def bgn_deftypevr(self, args): - self.write('
    ') - self.do_deftypevrx(args) - - end_deftypevr = end_deftypefn - - def do_deftypevrx(self, args): - self.write('
    ') - words = splitwords(args, 3) - [category, datatype, name], rest = words[:3], words[3:] - self.expand('@code{%s} @b{%s}' % (datatype, name)) - # If there are too many arguments, show them - for word in rest: self.expand(' ' + word) - #self.expand(' -- ' + category) - self.write('\n
    ') - self.index('fn', name) - - def bgn_deftypevar(self, args): - self.bgn_deftypevr('Variable ' + args) - end_deftypevar = end_deftypevr - def do_deftypevarx(self, args): - self.do_deftypevrx('Variable ' + args) - - # --- Ditto for object-oriented languages --- - - def bgn_defcv(self, args): - self.write('
    ') - self.do_defcvx(args) - - end_defcv = end_deftypevr - - def do_defcvx(self, args): - self.write('
    ') - words = splitwords(args, 3) - [category, classname, name], rest = words[:3], words[3:] - self.expand('@b{%s}' % name) - # If there are too many arguments, show them - for word in rest: self.expand(' ' + word) - #self.expand(' -- %s of @code{%s}' % (category, classname)) - self.write('\n
    ') - self.index('vr', '%s @r{on %s}' % (name, classname)) - - def bgn_defivar(self, args): - self.bgn_defcv('{Instance Variable} ' + args) - end_defivar = end_defcv - def do_defivarx(self, args): - self.do_defcvx('{Instance Variable} ' + args) - - def bgn_defop(self, args): - self.write('
    ') - self.do_defopx(args) - - end_defop = end_defcv - - def do_defopx(self, args): - self.write('
    ') - words = splitwords(args, 3) - [category, classname, name], rest = words[:3], words[3:] - self.expand('@b{%s}' % name) - for word in rest: self.expand(' ' + makevar(word)) - #self.expand(' -- %s of @code{%s}' % (category, classname)) - self.write('\n
    ') - self.index('fn', '%s @r{on %s}' % (name, classname)) - - def bgn_defmethod(self, args): - self.bgn_defop('Method ' + args) - end_defmethod = end_defop - def do_defmethodx(self, args): - self.do_defopx('Method ' + args) - - # --- Ditto for data types --- - - def bgn_deftp(self, args): - self.write('
    ') - self.do_deftpx(args) - - end_deftp = end_defcv - - def do_deftpx(self, args): - self.write('
    ') - words = splitwords(args, 2) - [category, name], rest = words[:2], words[2:] - self.expand('@b{%s}' % name) - for word in rest: self.expand(' ' + word) - #self.expand(' -- ' + category) - self.write('\n
    ') - self.index('tp', name) - - # --- Making Lists and Tables - - def bgn_enumerate(self, args): - if not args: - self.write('
      \n') - self.stackinfo[len(self.stack)] = '
    \n' - else: - self.itemnumber = args - self.write('
      \n') - self.stackinfo[len(self.stack)] = '
    \n' - def end_enumerate(self): - self.itemnumber = None - self.write(self.stackinfo[len(self.stack) + 1]) - del self.stackinfo[len(self.stack) + 1] - - def bgn_itemize(self, args): - self.itemarg = args - self.write('
      \n') - def end_itemize(self): - self.itemarg = None - self.write('
    \n') - - def bgn_table(self, args): - self.itemarg = args - self.write('
    \n') - def end_table(self): - self.itemarg = None - self.write('
    \n') - - def bgn_ftable(self, args): - self.itemindex = 'fn' - self.bgn_table(args) - def end_ftable(self): - self.itemindex = None - self.end_table() - - def bgn_vtable(self, args): - self.itemindex = 'vr' - self.bgn_table(args) - def end_vtable(self): - self.itemindex = None - self.end_table() - - def do_item(self, args): - if self.itemindex: self.index(self.itemindex, args) - if self.itemarg: - if self.itemarg[0] == '@' and self.itemarg[1] and \ - self.itemarg[1] in string.ascii_letters: - args = self.itemarg + '{' + args + '}' - else: - # some other character, e.g. '-' - args = self.itemarg + ' ' + args - if self.itemnumber is not None: - args = self.itemnumber + '. ' + args - self.itemnumber = increment(self.itemnumber) - if self.stack and self.stack[-1] == 'table': - self.write('
    ') - self.expand(args) - self.write('\n
    ') - elif self.stack and self.stack[-1] == 'multitable': - self.write('') - self.expand(args) - self.write('\n\n') - else: - self.write('
  • ') - self.expand(args) - self.write(' ') - do_itemx = do_item # XXX Should suppress leading blank line - - # rpyron 2002-05-07 multitable support - def bgn_multitable(self, args): - self.itemarg = None # should be handled by columnfractions - self.write('\n') - def end_multitable(self): - self.itemarg = None - self.write('
    \n
    \n') - def handle_columnfractions(self): - # It would be better to handle this, but for now it's in the way... - self.itemarg = None - def handle_tab(self): - self.write('\n ') - - # --- Enumerations, displays, quotations --- - # XXX Most of these should increase the indentation somehow - - def bgn_quotation(self, args): self.write('
    ') - def end_quotation(self): self.write('
    \n') - - def bgn_example(self, args): - self.nofill = self.nofill + 1 - self.write('
    ')
    -    def end_example(self):
    -        self.write('
    \n') - self.nofill = self.nofill - 1 - - bgn_lisp = bgn_example # Synonym when contents are executable lisp code - end_lisp = end_example - - bgn_smallexample = bgn_example # XXX Should use smaller font - end_smallexample = end_example - - bgn_smalllisp = bgn_lisp # Ditto - end_smalllisp = end_lisp - - bgn_display = bgn_example - end_display = end_example - - bgn_format = bgn_display - end_format = end_display - - def do_exdent(self, args): self.expand(args + '\n') - # XXX Should really mess with indentation - - def bgn_flushleft(self, args): - self.nofill = self.nofill + 1 - self.write('
    \n')
    -    def end_flushleft(self):
    -        self.write('
    \n') - self.nofill = self.nofill - 1 - - def bgn_flushright(self, args): - self.nofill = self.nofill + 1 - self.write('
    \n') - def end_flushright(self): - self.write('
    \n') - self.nofill = self.nofill - 1 - - def bgn_menu(self, args): - self.write('\n') - self.write(' Menu

    \n') - self.htmlhelp.beginmenu() - def end_menu(self): - self.write('

    \n') - self.htmlhelp.endmenu() - - def bgn_cartouche(self, args): pass - def end_cartouche(self): pass - - # --- Indices --- - - def resetindex(self): - self.noncodeindices = ['cp'] - self.indextitle = {} - self.indextitle['cp'] = 'Concept' - self.indextitle['fn'] = 'Function' - self.indextitle['ky'] = 'Keyword' - self.indextitle['pg'] = 'Program' - self.indextitle['tp'] = 'Type' - self.indextitle['vr'] = 'Variable' - # - self.whichindex = {} - for name in self.indextitle: - self.whichindex[name] = [] - - def user_index(self, name, args): - if name in self.whichindex: - self.index(name, args) - else: - print('*** No index named', repr(name)) - - def do_cindex(self, args): self.index('cp', args) - def do_findex(self, args): self.index('fn', args) - def do_kindex(self, args): self.index('ky', args) - def do_pindex(self, args): self.index('pg', args) - def do_tindex(self, args): self.index('tp', args) - def do_vindex(self, args): self.index('vr', args) - - def index(self, name, args): - self.whichindex[name].append((args, self.nodename)) - self.htmlhelp.index(args, self.nodename) - - def do_synindex(self, args): - words = args.split() - if len(words) != 2: - print('*** bad @synindex', args) - return - [old, new] = words - if old not in self.whichindex or \ - new not in self.whichindex: - print('*** bad key(s) in @synindex', args) - return - if old != new and \ - self.whichindex[old] is not self.whichindex[new]: - inew = self.whichindex[new] - inew[len(inew):] = self.whichindex[old] - self.whichindex[old] = inew - do_syncodeindex = do_synindex # XXX Should use code font - - def do_printindex(self, args): - words = args.split() - for name in words: - if name in self.whichindex: - self.prindex(name) - else: - print('*** No index named', repr(name)) - - def prindex(self, name): - iscodeindex = (name not in self.noncodeindices) - index = self.whichindex[name] - if not index: return - if self.debugging: - print('!'*self.debugging, '--- Generating', \ - self.indextitle[name], 'index') - # The node already provides a title - index1 = [] - junkprog = re.compile('^(@[a-z]+)?{') - for key, node in index: - sortkey = key.lower() - # Remove leading `@cmd{' from sort key - # -- don't bother about the matching `}' - oldsortkey = sortkey - while 1: - mo = junkprog.match(sortkey) - if not mo: - break - i = mo.end() - sortkey = sortkey[i:] - index1.append((sortkey, key, node)) - del index[:] - index1.sort() - self.write('
    \n') - prevkey = prevnode = None - for sortkey, key, node in index1: - if (key, node) == (prevkey, prevnode): - continue - if self.debugging > 1: print('!'*self.debugging, key, ':', node) - self.write('
    ') - if iscodeindex: key = '@code{' + key + '}' - if key != prevkey: - self.expand(key) - self.write('\n
    %s\n' % (makefile(node), node)) - prevkey, prevnode = key, node - self.write('
    \n') - - # --- Final error reports --- - - def report(self): - if self.unknown: - print('--- Unrecognized commands ---') - cmds = sorted(self.unknown.keys()) - for cmd in cmds: - print(cmd.ljust(20), self.unknown[cmd]) - - -class TexinfoParserHTML3(TexinfoParser): - - COPYRIGHT_SYMBOL = "©" - FN_ID_PATTERN = "[%(id)s]" - FN_SOURCE_PATTERN = '' + FN_ID_PATTERN + '' - FN_TARGET_PATTERN = '\n' \ - '

    ' + FN_ID_PATTERN \ - + '\n%(text)s

    \n' - FN_HEADER = '
    \n
    \n' \ - ' Footnotes\n

    \n' - - Node = HTML3Node - - def bgn_quotation(self, args): self.write('') - def end_quotation(self): self.write('\n') - - def bgn_example(self, args): - # this use of would not be legal in HTML 2.0, - # but is in more recent DTDs. - self.nofill = self.nofill + 1 - self.write('

    ')
    -    def end_example(self):
    -        self.write("
    \n") - self.nofill = self.nofill - 1 - - def bgn_flushleft(self, args): - self.nofill = self.nofill + 1 - self.write('
    \n')
    -
    -    def bgn_flushright(self, args):
    -        self.nofill = self.nofill + 1
    -        self.write('
    \n') - def end_flushright(self): - self.write('
    \n') - self.nofill = self.nofill - 1 - - def bgn_menu(self, args): - self.write('\n') - - -# rpyron 2002-05-07 -class HTMLHelp: - """ - This class encapsulates support for HTML Help. Node names, - file names, menu items, index items, and image file names are - accumulated until a call to finalize(). At that time, three - output files are created in the current directory: - - `helpbase`.hhp is a HTML Help Workshop project file. - It contains various information, some of - which I do not understand; I just copied - the default project info from a fresh - installation. - `helpbase`.hhc is the Contents file for the project. - `helpbase`.hhk is the Index file for the project. - - When these files are used as input to HTML Help Workshop, - the resulting file will be named: - - `helpbase`.chm - - If none of the defaults in `helpbase`.hhp are changed, - the .CHM file will have Contents, Index, Search, and - Favorites tabs. - """ - - codeprog = re.compile('@code{(.*?)}') - - def __init__(self,helpbase,dirname): - self.helpbase = helpbase - self.dirname = dirname - self.projectfile = None - self.contentfile = None - self.indexfile = None - self.nodelist = [] - self.nodenames = {} # nodename : index - self.nodeindex = {} - self.filenames = {} # filename : filename - self.indexlist = [] # (args,nodename) == (key,location) - self.current = '' - self.menudict = {} - self.dumped = {} - - - def addnode(self,name,next,prev,up,filename): - node = (name,next,prev,up,filename) - # add this file to dict - # retrieve list with self.filenames.values() - self.filenames[filename] = filename - # add this node to nodelist - self.nodeindex[name] = len(self.nodelist) - self.nodelist.append(node) - # set 'current' for menu items - self.current = name - self.menudict[self.current] = [] - - def menuitem(self,nodename): - menu = self.menudict[self.current] - menu.append(nodename) - - - def addimage(self,imagename): - self.filenames[imagename] = imagename - - def index(self, args, nodename): - self.indexlist.append((args,nodename)) - - def beginmenu(self): - pass - - def endmenu(self): - pass - - def finalize(self): - if not self.helpbase: - return - - # generate interesting filenames - resultfile = self.helpbase + '.chm' - projectfile = self.helpbase + '.hhp' - contentfile = self.helpbase + '.hhc' - indexfile = self.helpbase + '.hhk' - - # generate a reasonable title - title = self.helpbase - - # get the default topic file - (topname,topnext,topprev,topup,topfile) = self.nodelist[0] - defaulttopic = topfile - - # PROJECT FILE - try: - with open(projectfile, 'w') as fp: - print('[OPTIONS]', file=fp) - print('Auto Index=Yes', file=fp) - print('Binary TOC=No', file=fp) - print('Binary Index=Yes', file=fp) - print('Compatibility=1.1', file=fp) - print('Compiled file=' + resultfile + '', file=fp) - print('Contents file=' + contentfile + '', file=fp) - print('Default topic=' + defaulttopic + '', file=fp) - print('Error log file=ErrorLog.log', file=fp) - print('Index file=' + indexfile + '', file=fp) - print('Title=' + title + '', file=fp) - print('Display compile progress=Yes', file=fp) - print('Full-text search=Yes', file=fp) - print('Default window=main', file=fp) - print('', file=fp) - print('[WINDOWS]', file=fp) - print('main=,"' + contentfile + '","' + indexfile - + '","","",,,,,0x23520,222,0x1046,[10,10,780,560],' - '0xB0000,,,,,,0', file=fp) - print('', file=fp) - print('[FILES]', file=fp) - print('', file=fp) - self.dumpfiles(fp) - except IOError as msg: - print(projectfile, ':', msg) - sys.exit(1) - - # CONTENT FILE - try: - with open(contentfile, 'w') as fp: - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print(' ', file=fp) - print(' ', file=fp) - print(' ', file=fp) - print(' ', file=fp) - print(' ', file=fp) - self.dumpnodes(fp) - print('', file=fp) - print('', file=fp) - except IOError as msg: - print(contentfile, ':', msg) - sys.exit(1) - - # INDEX FILE - try: - with open(indexfile, 'w') as fp: - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - self.dumpindex(fp) - print('', file=fp) - print('', file=fp) - except IOError as msg: - print(indexfile , ':', msg) - sys.exit(1) - - def dumpfiles(self, outfile=sys.stdout): - filelist = sorted(self.filenames.values()) - for filename in filelist: - print(filename, file=outfile) - - def dumpnodes(self, outfile=sys.stdout): - self.dumped = {} - if self.nodelist: - nodename, dummy, dummy, dummy, dummy = self.nodelist[0] - self.topnode = nodename - - print('
      ', file=outfile) - for node in self.nodelist: - self.dumpnode(node,0,outfile) - print('
    ', file=outfile) - - def dumpnode(self, node, indent=0, outfile=sys.stdout): - if node: - # Retrieve info for this node - (nodename,next,prev,up,filename) = node - self.current = nodename - - # Have we been dumped already? - if nodename in self.dumped: - return - self.dumped[nodename] = 1 - - # Print info for this node - print(' '*indent, end=' ', file=outfile) - print('
  • ', end=' ', file=outfile) - print('', end=' ', file=outfile) - print('', end=' ', file=outfile) - print('', file=outfile) - - # Does this node have menu items? - try: - menu = self.menudict[nodename] - self.dumpmenu(menu,indent+2,outfile) - except KeyError: - pass - - def dumpmenu(self, menu, indent=0, outfile=sys.stdout): - if menu: - currentnode = self.current - if currentnode != self.topnode: # XXX this is a hack - print(' '*indent + '
      ', file=outfile) - indent += 2 - for item in menu: - menunode = self.getnode(item) - self.dumpnode(menunode,indent,outfile) - if currentnode != self.topnode: # XXX this is a hack - print(' '*indent + '
    ', file=outfile) - indent -= 2 - - def getnode(self, nodename): - try: - index = self.nodeindex[nodename] - return self.nodelist[index] - except KeyError: - return None - except IndexError: - return None - - # (args,nodename) == (key,location) - def dumpindex(self, outfile=sys.stdout): - print('
      ', file=outfile) - for (key,location) in self.indexlist: - key = self.codeexpand(key) - location = makefile(location) - location = self.dirname + '/' + location - print('
    • ', end=' ', file=outfile) - print('', end=' ', file=outfile) - print('', end=' ', file=outfile) - print('', file=outfile) - print('
    ', file=outfile) - - def codeexpand(self, line): - co = self.codeprog.match(line) - if not co: - return line - bgn, end = co.span(0) - a, b = co.span(1) - line = line[:bgn] + line[a:b] + line[end:] - return line - - -# Put @var{} around alphabetic substrings -def makevar(str): - return '@var{'+str+'}' - - -# Split a string in "words" according to findwordend -def splitwords(str, minlength): - words = [] - i = 0 - n = len(str) - while i < n: - while i < n and str[i] in ' \t\n': i = i+1 - if i >= n: break - start = i - i = findwordend(str, i, n) - words.append(str[start:i]) - while len(words) < minlength: words.append('') - return words - - -# Find the end of a "word", matching braces and interpreting @@ @{ @} -fwprog = re.compile('[@{} ]') -def findwordend(str, i, n): - level = 0 - while i < n: - mo = fwprog.search(str, i) - if not mo: - break - i = mo.start() - c = str[i]; i = i+1 - if c == '@': i = i+1 # Next character is not special - elif c == '{': level = level+1 - elif c == '}': level = level-1 - elif c == ' ' and level <= 0: return i-1 - return n - - -# Convert a node name into a file name -def makefile(nodename): - nodename = nodename.strip() - return fixfunnychars(nodename) + '.html' - - -# Characters that are perfectly safe in filenames and hyperlinks -goodchars = string.ascii_letters + string.digits + '!@-=+.' - -# Replace characters that aren't perfectly safe by dashes -# Underscores are bad since Cern HTTPD treats them as delimiters for -# encoding times, so you get mismatches if you compress your files: -# a.html.gz will map to a_b.html.gz -def fixfunnychars(addr): - i = 0 - while i < len(addr): - c = addr[i] - if c not in goodchars: - c = '-' - addr = addr[:i] + c + addr[i+1:] - i = i + len(c) - return addr - - -# Increment a string used as an enumeration -def increment(s): - if not s: - return '1' - for sequence in string.digits, string.ascii_lowercase, string.ascii_uppercase: - lastc = s[-1] - if lastc in sequence: - i = sequence.index(lastc) + 1 - if i >= len(sequence): - if len(s) == 1: - s = sequence[0]*2 - if s == '00': - s = '10' - else: - s = increment(s[:-1]) + sequence[0] - else: - s = s[:-1] + sequence[i] - return s - return s # Don't increment - - -def test(): - import sys - debugging = 0 - print_headers = 0 - cont = 0 - html3 = 0 - htmlhelp = '' - - while sys.argv[1] == ['-d']: - debugging = debugging + 1 - del sys.argv[1] - if sys.argv[1] == '-p': - print_headers = 1 - del sys.argv[1] - if sys.argv[1] == '-c': - cont = 1 - del sys.argv[1] - if sys.argv[1] == '-3': - html3 = 1 - del sys.argv[1] - if sys.argv[1] == '-H': - helpbase = sys.argv[2] - del sys.argv[1:3] - if len(sys.argv) != 3: - print('usage: texi2hh [-d [-d]] [-p] [-c] [-3] [-H htmlhelp]', \ - 'inputfile outputdirectory') - sys.exit(2) - - if html3: - parser = TexinfoParserHTML3() - else: - parser = TexinfoParser() - parser.cont = cont - parser.debugging = debugging - parser.print_headers = print_headers - - file = sys.argv[1] - dirname = sys.argv[2] - parser.setdirname(dirname) - parser.setincludedir(os.path.dirname(file)) - - htmlhelp = HTMLHelp(helpbase, dirname) - parser.sethtmlhelp(htmlhelp) - - try: - fp = open(file, 'r') - except IOError as msg: - print(file, ':', msg) - sys.exit(1) - - with fp: - parser.parse(fp) - parser.report() - - htmlhelp.finalize() - - -if __name__ == "__main__": - test() diff --git a/Tools/scripts/which.py b/Tools/scripts/which.py deleted file mode 100755 index b42e07c74ec..00000000000 --- a/Tools/scripts/which.py +++ /dev/null @@ -1,61 +0,0 @@ -#! /usr/bin/env python3 - -# Variant of "which". -# On stderr, near and total misses are reported. -# '-l' argument adds ls -l of each file found. - -import sys -if sys.path[0] in (".", ""): del sys.path[0] - -import sys, os -from stat import * - -def msg(str): - sys.stderr.write(str + '\n') - -def main(): - pathlist = os.environ['PATH'].split(os.pathsep) - - sts = 0 - longlist = '' - - if sys.argv[1:] and sys.argv[1][:2] == '-l': - longlist = sys.argv[1] - del sys.argv[1] - - for prog in sys.argv[1:]: - ident = () - for dir in pathlist: - filename = os.path.join(dir, prog) - try: - st = os.stat(filename) - except OSError: - continue - if not S_ISREG(st[ST_MODE]): - msg(filename + ': not a disk file') - else: - mode = S_IMODE(st[ST_MODE]) - if mode & 0o111: - if not ident: - print(filename) - ident = st[:3] - else: - if st[:3] == ident: - s = 'same as: ' - else: - s = 'also: ' - msg(s + filename) - else: - msg(filename + ': not executable') - if longlist: - sts = os.system('ls ' + longlist + ' ' + filename) - sts = os.waitstatus_to_exitcode(sts) - if sts: msg('"ls -l" exit status: ' + repr(sts)) - if not ident: - msg(prog + ': not found') - sts = 1 - - sys.exit(sts) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/win_add2path.py b/Tools/scripts/win_add2path.py deleted file mode 100644 index 1c9aedc5ed8..00000000000 --- a/Tools/scripts/win_add2path.py +++ /dev/null @@ -1,58 +0,0 @@ -"""Add Python to the search path on Windows - -This is a simple script to add Python to the Windows search path. It -modifies the current user (HKCU) tree of the registry. - -Copyright (c) 2008 by Christian Heimes -Licensed to PSF under a Contributor Agreement. -""" - -import sys -import site -import os -import winreg - -HKCU = winreg.HKEY_CURRENT_USER -ENV = "Environment" -PATH = "PATH" -DEFAULT = "%PATH%" - -def modify(): - pythonpath = os.path.dirname(os.path.normpath(sys.executable)) - scripts = os.path.join(pythonpath, "Scripts") - appdata = os.environ["APPDATA"] - if hasattr(site, "USER_SITE"): - usersite = site.USER_SITE.replace(appdata, "%APPDATA%") - userpath = os.path.dirname(usersite) - userscripts = os.path.join(userpath, "Scripts") - else: - userscripts = None - - with winreg.CreateKey(HKCU, ENV) as key: - try: - envpath = winreg.QueryValueEx(key, PATH)[0] - except OSError: - envpath = DEFAULT - - paths = [envpath] - for path in (pythonpath, scripts, userscripts): - if path and path not in envpath and os.path.isdir(path): - paths.append(path) - - envpath = os.pathsep.join(paths) - winreg.SetValueEx(key, PATH, 0, winreg.REG_EXPAND_SZ, envpath) - return paths, envpath - -def main(): - paths, envpath = modify() - if len(paths) > 1: - print("Path(s) added:") - print('\n'.join(paths[1:])) - else: - print("No path was added") - print("\nPATH is now:\n%s\n" % envpath) - print("Expanded:") - print(winreg.ExpandEnvironmentStrings(envpath)) - -if __name__ == '__main__': - main() diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index ba2663e9a39..5ad597c8347 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -35,7 +35,6 @@ except ImportError: from urllib2 import urlopen, HTTPError import re import shutil -import string import subprocess import sys import tarfile @@ -47,8 +46,8 @@ OPENSSL_OLD_VERSIONS = [ ] OPENSSL_RECENT_VERSIONS = [ - "1.1.1l", - "3.0.0" + "1.1.1s", + "3.0.7" ] LIBRESSL_OLD_VERSIONS = [ @@ -359,7 +358,7 @@ class AbstractBuilder(object): env["LD_RUN_PATH"] = self.lib_dir log.info("Rebuilding Python modules") - cmd = [sys.executable, os.path.join(PYTHONROOT, "setup.py"), "build"] + cmd = ["make", "sharedmods", "checksharedmods"] self._subprocess_call(cmd, env=env) self.check_imports() @@ -403,15 +402,15 @@ class BuildOpenSSL(AbstractBuilder): depend_target = 'depend' def _post_install(self): - if self.version.startswith("3.0"): - self._post_install_300() + if self.version.startswith("3."): + self._post_install_3xx() def _build_src(self, config_args=()): - if self.version.startswith("3.0"): + if self.version.startswith("3."): config_args += ("enable-fips",) super()._build_src(config_args) - def _post_install_300(self): + def _post_install_3xx(self): # create ssl/ subdir with example configs # Install FIPS module self._subprocess_call( @@ -473,7 +472,7 @@ def main(): start = datetime.now() if args.steps in {'modules', 'tests'}: - for name in ['setup.py', 'Modules/_ssl.c']: + for name in ['Makefile.pre.in', 'Modules/_ssl.c']: if not os.path.isfile(os.path.join(PYTHONROOT, name)): parser.error( "Must be executed from CPython build dir" diff --git a/Tools/unicode/genmap_tchinese.py b/Tools/unicode/genmap_tchinese.py new file mode 100644 index 00000000000..a416cf3d1fa --- /dev/null +++ b/Tools/unicode/genmap_tchinese.py @@ -0,0 +1,239 @@ +# +# genmap_tchinese.py: Traditional Chinese Codecs Map Generator +# +# Original Author: Hye-Shik Chang +# +import os + +from genmap_support import * + + +# ranges for (lead byte, follower byte) +BIG5_C1 = (0xa1, 0xfe) +BIG5_C2 = (0x40, 0xfe) +BIG5HKSCS_C1 = (0x87, 0xfe) +BIG5HKSCS_C2 = (0x40, 0xfe) + +MAPPINGS_BIG5 = 'https://unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT' +MAPPINGS_CP950 = 'https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT' + +HKSCS_VERSION = '2004' +# The files for HKSCS mappings are available under a restrictive license. +# Users of the script need to download the files from the HKSARG CCLI website: +MAPPINGS_HKSCS = f'https://www.ccli.gov.hk/en/archive/terms_hkscs-{HKSCS_VERSION}-big5-iso.html' + + +def bh2s(code): + return ((code >> 8) - 0x87) * (0xfe - 0x40 + 1) + ((code & 0xff) - 0x40) + + +def split_bytes(code): + """Split 0xABCD into 0xAB, 0xCD""" + return code >> 8, code & 0xff + + +def parse_hkscs_map(fo): + fo.seek(0, 0) + table = [] + for line in fo: + line = line.split('#', 1)[0].strip() + # We expect 4 columns in supported HKSCS files: + # [1999]: unsupported + # [2001]: unsupported + # [2004]: Big-5; iso10646-1:1993; iso10646-1:2000; iso10646:2003+amd1 + # [2008]: Big-5; iso10646-1:1993; iso10646-1:2000; iso10646:2003+amd6 + # [2016]: not supported here--uses a json file instead + # + # In both supported cases, we only need the first and last column: + # * Big-5 is a hex string (always 4 digits) + # * iso10646:2003 is either a hex string (4 or 5 digits) or a sequence + # of hex strings like: `` + try: + hkscs_col, _, _, uni_col = line.split() + hkscs = int(hkscs_col, 16) + seq = tuple(int(cp, 16) for cp in uni_col.strip('<>').split(',')) + except ValueError: + continue + table.append((hkscs, seq)) + return table + + +def make_hkscs_map(table): + decode_map = {} + encode_map_bmp, encode_map_notbmp = {}, {} + is_bmp_map = {} + sequences = [] + beginnings = {} + single_cp_table = [] + # Determine multi-codepoint sequences, and sequence beginnings that encode + # multiple multibyte (i.e. Big-5) codes. + for mbcode, cp_seq in table: + cp, *_ = cp_seq + if len(cp_seq) == 1: + single_cp_table.append((mbcode, cp)) + else: + sequences.append((mbcode, cp_seq)) + beginnings.setdefault(cp, []).append(mbcode) + # Decode table only cares about single code points (no sequences) currently + for mbcode, cp in single_cp_table: + b1, b2 = split_bytes(mbcode) + decode_map.setdefault(b1, {}) + decode_map[b1][b2] = cp & 0xffff + # Encode table needs to mark code points beginning a sequence as tuples. + for cp, mbcodes in beginnings.items(): + plane = cp >> 16 + if plane == 0: + encode_map = encode_map_bmp + elif plane == 2: + encode_map = encode_map_notbmp + is_bmp_map[bh2s(mbcodes[0])] = 1 + else: + assert False, 'only plane 0 (BMP) and plane 2 (SIP) allowed' + if len(mbcodes) == 1: + encode_value = mbcodes[0] + else: + encode_value = tuple(mbcodes) + uni_b1, uni_b2 = split_bytes(cp & 0xffff) + encode_map.setdefault(uni_b1, {}) + encode_map[uni_b1][uni_b2] = encode_value + + return decode_map, encode_map_bmp, encode_map_notbmp, is_bmp_map + + +def load_big5_map(): + mapfile = open_mapping_file('python-mappings/BIG5.txt', MAPPINGS_BIG5) + with mapfile: + big5decmap = loadmap(mapfile) + # big5 mapping fix: use the cp950 mapping for these characters as the file + # provided by unicode.org doesn't define a mapping. See notes in BIG5.txt. + # Since U+5341, U+5345, U+FF0F, U+FF3C already have a big5 mapping, no + # roundtrip compatibility is guaranteed for those. + for m in """\ + 0xA15A 0x2574 + 0xA1C3 0xFFE3 + 0xA1C5 0x02CD + 0xA1FE 0xFF0F + 0xA240 0xFF3C + 0xA2CC 0x5341 + 0xA2CE 0x5345""".splitlines(): + bcode, ucode = list(map(eval, m.split())) + big5decmap[bcode >> 8][bcode & 0xff] = ucode + # encoding map + big5encmap = {} + for c1, m in list(big5decmap.items()): + for c2, code in list(m.items()): + big5encmap.setdefault(code >> 8, {}) + if code & 0xff not in big5encmap[code >> 8]: + big5encmap[code >> 8][code & 0xff] = c1 << 8 | c2 + # fix unicode->big5 priority for the above-mentioned duplicate characters + big5encmap[0xFF][0x0F] = 0xA241 + big5encmap[0xFF][0x3C] = 0xA242 + big5encmap[0x53][0x41] = 0xA451 + big5encmap[0x53][0x45] = 0xA4CA + + return big5decmap, big5encmap + + +def load_cp950_map(): + mapfile = open_mapping_file('python-mappings/CP950.TXT', MAPPINGS_CP950) + with mapfile: + cp950decmap = loadmap(mapfile) + cp950encmap = {} + for c1, m in list(cp950decmap.items()): + for c2, code in list(m.items()): + cp950encmap.setdefault(code >> 8, {}) + if code & 0xff not in cp950encmap[code >> 8]: + cp950encmap[code >> 8][code & 0xff] = c1 << 8 | c2 + # fix unicode->big5 duplicated mapping priority + cp950encmap[0x53][0x41] = 0xA451 + cp950encmap[0x53][0x45] = 0xA4CA + return cp950decmap, cp950encmap + + +def main_tw(): + big5decmap, big5encmap = load_big5_map() + cp950decmap, cp950encmap = load_cp950_map() + + # CP950 extends Big5, and the codec can use the Big5 lookup tables + # for most entries. So the CP950 tables should only include entries + # that are not in Big5: + for c1, m in list(cp950encmap.items()): + for c2, code in list(m.items()): + if (c1 in big5encmap and c2 in big5encmap[c1] + and big5encmap[c1][c2] == code): + del cp950encmap[c1][c2] + for c1, m in list(cp950decmap.items()): + for c2, code in list(m.items()): + if (c1 in big5decmap and c2 in big5decmap[c1] + and big5decmap[c1][c2] == code): + del cp950decmap[c1][c2] + + with open('mappings_tw.h', 'w') as fp: + print_autogen(fp, os.path.basename(__file__)) + write_big5_maps(fp, 'BIG5', 'big5', big5decmap, big5encmap) + write_big5_maps(fp, 'CP950', 'cp950ext', cp950decmap, cp950encmap) + + +def write_big5_maps(fp, display_name, table_name, decode_map, encode_map): + print(f'Generating {display_name} decode map...') + writer = DecodeMapWriter(fp, table_name, decode_map) + writer.update_decode_map(BIG5_C1, BIG5_C2) + writer.generate() + print(f'Generating {display_name} encode map...') + writer = EncodeMapWriter(fp, table_name, encode_map) + writer.generate() + + +class HintsWriter: + filler_class = BufferedFiller + + def __init__(self, fp, prefix, isbmpmap): + self.fp = fp + self.prefix = prefix + self.isbmpmap = isbmpmap + self.filler = self.filler_class() + + def fillhints(self, hintfrom, hintto): + name = f'{self.prefix}_phint_{hintfrom}' + self.fp.write(f'static const unsigned char {name}[] = {{\n') + for msbcode in range(hintfrom, hintto+1, 8): + v = 0 + for c in range(msbcode, msbcode+8): + v |= self.isbmpmap.get(c, 0) << (c - msbcode) + self.filler.write('%d,' % v) + self.filler.printout(self.fp) + self.fp.write('};\n\n') + + +def main_hkscs(): + filename = f'python-mappings/hkscs-{HKSCS_VERSION}-big5-iso.txt' + with open_mapping_file(filename, MAPPINGS_HKSCS) as f: + table = parse_hkscs_map(f) + hkscsdecmap, hkscsencmap_bmp, hkscsencmap_nonbmp, isbmpmap = ( + make_hkscs_map(table) + ) + with open('mappings_hk.h', 'w') as fp: + print('Generating BIG5HKSCS decode map...') + print_autogen(fp, os.path.basename(__file__)) + writer = DecodeMapWriter(fp, 'big5hkscs', hkscsdecmap) + writer.update_decode_map(BIG5HKSCS_C1, BIG5HKSCS_C2) + writer.generate() + + print('Generating BIG5HKSCS decode map Unicode plane hints...') + writer = HintsWriter(fp, 'big5hkscs', isbmpmap) + writer.fillhints(bh2s(0x8740), bh2s(0xa0fe)) + writer.fillhints(bh2s(0xc6a1), bh2s(0xc8fe)) + writer.fillhints(bh2s(0xf9d6), bh2s(0xfefe)) + + print('Generating BIG5HKSCS encode map (BMP)...') + writer = EncodeMapWriter(fp, 'big5hkscs_bmp', hkscsencmap_bmp) + writer.generate() + + print('Generating BIG5HKSCS encode map (non-BMP)...') + writer = EncodeMapWriter(fp, 'big5hkscs_nonbmp', hkscsencmap_nonbmp) + writer.generate() + + +if __name__ == '__main__': + main_tw() + main_hkscs() diff --git a/Tools/unicode/makeunicodedata.py b/Tools/unicode/makeunicodedata.py index 489484443aa..034642db06e 100644 --- a/Tools/unicode/makeunicodedata.py +++ b/Tools/unicode/makeunicodedata.py @@ -44,7 +44,7 @@ VERSION = "3.3" # * Doc/library/stdtypes.rst, and # * Doc/library/unicodedata.rst # * Doc/reference/lexical_analysis.rst (two occurrences) -UNIDATA_VERSION = "14.0.0" +UNIDATA_VERSION = "15.0.0" UNICODE_DATA = "UnicodeData%s.txt" COMPOSITION_EXCLUSIONS = "CompositionExclusions%s.txt" EASTASIAN_WIDTH = "EastAsianWidth%s.txt" @@ -77,7 +77,8 @@ BIDIRECTIONAL_NAMES = [ "", "L", "LRE", "LRO", "R", "AL", "RLE", "RLO", "PDF", "EN", "ES", "ET", "AN", "CS", "NSM", "BN", "B", "S", "WS", "ON", "LRI", "RLI", "FSI", "PDI" ] -EASTASIANWIDTH_NAMES = [ "F", "H", "W", "Na", "A", "N" ] +# "N" needs to be the first entry, see the comment in makeunicodedata +EASTASIANWIDTH_NAMES = [ "N", "H", "W", "Na", "A", "F" ] MANDATORY_LINE_BREAKS = [ "BK", "CR", "LF", "NL" ] @@ -103,11 +104,12 @@ cjk_ranges = [ ('3400', '4DBF'), ('4E00', '9FFF'), ('20000', '2A6DF'), - ('2A700', '2B738'), + ('2A700', '2B739'), ('2B740', '2B81D'), ('2B820', '2CEA1'), ('2CEB0', '2EBE0'), ('30000', '3134A'), + ('31350', '323AF'), ] @@ -135,6 +137,14 @@ def maketables(trace=0): def makeunicodedata(unicode, trace): + # the default value of east_asian_width is "N", for unassigned code points + # not mentioned in EastAsianWidth.txt + # in addition there are some reserved but unassigned code points in CJK + # ranges that are classified as "W". code points in private use areas + # have a width of "A". both of these have entries in + # EastAsianWidth.txt + # see https://unicode.org/reports/tr11/#Unassigned + assert EASTASIANWIDTH_NAMES[0] == "N" dummy = (0, 0, 0, 0, 0, 0) table = [dummy] cache = {0: dummy} @@ -160,15 +170,24 @@ def makeunicodedata(unicode, trace): category, combining, bidirectional, mirrored, eastasianwidth, normalizationquickcheck ) - # add entry to index and item tables - i = cache.get(item) - if i is None: - cache[item] = i = len(table) - table.append(item) - index[char] = i + elif unicode.widths[char] is not None: + # an unassigned but reserved character, with a known + # east_asian_width + eastasianwidth = EASTASIANWIDTH_NAMES.index(unicode.widths[char]) + item = (0, 0, 0, 0, eastasianwidth, 0) + else: + continue + + # add entry to index and item tables + i = cache.get(item) + if i is None: + cache[item] = i = len(table) + table.append(item) + index[char] = i # 2) decomposition data + decomp_data_cache = {} decomp_data = [0] decomp_prefix = [""] decomp_index = [0] * len(unicode.chars) @@ -207,12 +226,15 @@ def makeunicodedata(unicode, trace): comp_first[l] = 1 comp_last[r] = 1 comp_pairs.append((l,r,char)) - try: - i = decomp_data.index(decomp) - except ValueError: + key = tuple(decomp) + i = decomp_data_cache.get(key, -1) + if i == -1: i = len(decomp_data) decomp_data.extend(decomp) decomp_size = decomp_size + len(decomp) * 2 + decomp_data_cache[key] = i + else: + assert decomp_data[i:i+len(decomp)] == decomp else: i = 0 decomp_index[char] = i @@ -395,7 +417,7 @@ def makeunicodetype(unicode, trace): # extract unicode types dummy = (0, 0, 0, 0, 0, 0) table = [dummy] - cache = {0: dummy} + cache = {dummy: 0} index = [0] * len(unicode.chars) numeric = {} spaces = [] @@ -1081,6 +1103,7 @@ class UnicodeData: for i in range(0, 0x110000): if table[i] is not None: table[i].east_asian_width = widths[i] + self.widths = widths for char, (p,) in UcdFile(DERIVED_CORE_PROPERTIES, version).expanded(): if table[char]: diff --git a/Tools/wasm/.editorconfig b/Tools/wasm/.editorconfig new file mode 100644 index 00000000000..da1aa6acacc --- /dev/null +++ b/Tools/wasm/.editorconfig @@ -0,0 +1,7 @@ +root = false # This extends the root .editorconfig + +[*.{html,js}] +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 4 diff --git a/Tools/wasm/README.md b/Tools/wasm/README.md new file mode 100644 index 00000000000..8874f9b7e35 --- /dev/null +++ b/Tools/wasm/README.md @@ -0,0 +1,504 @@ +# Python WebAssembly (WASM) build + +**WARNING: WASM support is work-in-progress! Lots of features are not working yet.** + +This directory contains configuration and helpers to facilitate cross +compilation of CPython to WebAssembly (WASM). Python supports Emscripten +(*wasm32-emscripten*) and WASI (*wasm32-wasi*) targets. Emscripten builds +run in modern browsers and JavaScript runtimes like *Node.js*. WASI builds +use WASM runtimes such as *wasmtime*. + +Users and developers are encouraged to use the script +`Tools/wasm/wasm_build.py`. The tool automates the build process and provides +assistance with installation of SDKs. + +## wasm32-emscripten build + +For now the build system has two target flavors. The ``Emscripten/browser`` +target (``--with-emscripten-target=browser``) is optimized for browsers. +It comes with a reduced and preloaded stdlib without tests and threading +support. The ``Emscripten/node`` target has threading enabled and can +access the file system directly. + +Cross compiling to the wasm32-emscripten platform needs the +[Emscripten](https://emscripten.org/) SDK and a build Python interpreter. +Emscripten 3.1.19 or newer are recommended. All commands below are relative +to a repository checkout. + +Christian Heimes maintains a container image with Emscripten SDK, Python +build dependencies, WASI-SDK, wasmtime, and several additional tools. + +From within your local CPython repo clone, run one of the following commands: + +``` +# Fedora, RHEL, CentOS +podman run --rm -ti -v $(pwd):/python-wasm/cpython:Z -w /python-wasm/cpython quay.io/tiran/cpythonbuild:emsdk3 + +# other +docker run --rm -ti -v $(pwd):/python-wasm/cpython -w /python-wasm/cpython quay.io/tiran/cpythonbuild:emsdk3 +``` + +### Compile a build Python interpreter + +From within the container, run the following command: + +```shell +./Tools/wasm/wasm_build.py build +``` + +The command is roughly equivalent to: + +```shell +mkdir -p builddir/build +pushd builddir/build +../../configure -C +make -j$(nproc) +popd +``` + +### Cross-compile to wasm32-emscripten for browser + +```shell +./Tools/wasm/wasm_build.py emscripten-browser +``` + +The command is roughly equivalent to: + +```shell +mkdir -p builddir/emscripten-browser +pushd builddir/emscripten-browser + +CONFIG_SITE=../../Tools/wasm/config.site-wasm32-emscripten \ + emconfigure ../../configure -C \ + --host=wasm32-unknown-emscripten \ + --build=$(../../config.guess) \ + --with-emscripten-target=browser \ + --with-build-python=$(pwd)/../build/python + +emmake make -j$(nproc) +popd +``` + +Serve `python.html` with a local webserver and open the file in a browser. +Python comes with a minimal web server script that sets necessary HTTP +headers like COOP, COEP, and mimetypes. Run the script outside the container +and from the root of the CPython checkout. + +```shell +./Tools/wasm/wasm_webserver.py +``` + +and open http://localhost:8000/builddir/emscripten-browser/python.html . This +directory structure enables the *C/C++ DevTools Support (DWARF)* to load C +and header files with debug builds. + + +### Cross compile to wasm32-emscripten for node + +```shell +./Tools/wasm/wasm_build.py emscripten-browser-dl +``` + +The command is roughly equivalent to: + +```shell +mkdir -p builddir/emscripten-node-dl +pushd builddir/emscripten-node-dl + +CONFIG_SITE=../../Tools/wasm/config.site-wasm32-emscripten \ + emconfigure ../../configure -C \ + --host=wasm32-unknown-emscripten \ + --build=$(../../config.guess) \ + --with-emscripten-target=node \ + --enable-wasm-dynamic-linking \ + --with-build-python=$(pwd)/../build/python + +emmake make -j$(nproc) +popd +``` + +```shell +node --experimental-wasm-threads --experimental-wasm-bulk-memory --experimental-wasm-bigint builddir/emscripten-node-dl/python.js +``` + +(``--experimental-wasm-bigint`` is not needed with recent NodeJS versions) + +# wasm32-emscripten limitations and issues + +Emscripten before 3.1.8 has known bugs that can cause memory corruption and +resource leaks. 3.1.8 contains several fixes for bugs in date and time +functions. + +## Network stack + +- Python's socket module does not work with Emscripten's emulated POSIX + sockets yet. Network modules like ``asyncio``, ``urllib``, ``selectors``, + etc. are not available. +- Only ``AF_INET`` and ``AF_INET6`` with ``SOCK_STREAM`` (TCP) or + ``SOCK_DGRAM`` (UDP) are available. ``AF_UNIX`` is not supported. +- ``socketpair`` does not work. +- Blocking sockets are not available and non-blocking sockets don't work + correctly, e.g. ``socket.accept`` crashes the runtime. ``gethostbyname`` + does not resolve to a real IP address. IPv6 is not available. +- The ``select`` module is limited. ``select.select()`` crashes the runtime + due to lack of exectfd support. + +## processes, signals + +- Processes are not supported. System calls like fork, popen, and subprocess + fail with ``ENOSYS`` or ``ENOSUP``. +- Signal support is limited. ``signal.alarm``, ``itimer``, ``sigaction`` + are not available or do not work correctly. ``SIGTERM`` exits the runtime. +- Keyboard interrupt (CTRL+C) handling is not implemented yet. +- Resource-related functions like ``os.nice`` and most functions of the + ``resource`` module are not available. + +## threading + +- Threading is disabled by default. The ``configure`` option + ``--enable-wasm-pthreads`` adds compiler flag ``-pthread`` and + linker flags ``-sUSE_PTHREADS -sPROXY_TO_PTHREAD``. +- pthread support requires WASM threads and SharedArrayBuffer (bulk memory). + The Node.JS runtime keeps a pool of web workers around. Each web worker + uses several file descriptors (eventfd, epoll, pipe). +- It's not advised to enable threading when building for browsers or with + dynamic linking support; there are performance and stability issues. + +## file system + +- Most user, group, and permission related function and modules are not + supported or don't work as expected, e.g.``pwd`` module, ``grp`` module, + ``os.setgroups``, ``os.chown``, and so on. ``lchown`` and ``lchmod`` are + not available. +- ``umask`` is a no-op. +- hard links (``os.link``) are not supported. +- Offset and iovec I/O functions (e.g. ``os.pread``, ``os.preadv``) are not + available. +- ``os.mknod`` and ``os.mkfifo`` + [don't work](https://github.com/emscripten-core/emscripten/issues/16158) + and are disabled. +- Large file support crashes the runtime and is disabled. +- ``mmap`` module is unstable. flush (``msync``) can crash the runtime. + +## Misc + +- Heap memory and stack size are limited. Recursion or extensive memory + consumption can crash Python. +- Most stdlib modules with a dependency on external libraries are missing, + e.g. ``ctypes``, ``readline``, ``ssl``, and more. +- Shared extension modules are not implemented yet. All extension modules + are statically linked into the main binary. The experimental configure + option ``--enable-wasm-dynamic-linking`` enables dynamic extensions + supports. It's currently known to crash in combination with threading. +- glibc extensions for date and time formatting are not available. +- ``locales`` module is affected by musl libc issues, + [gh-90548](https://github.com/python/cpython/issues/90548). +- Python's object allocator ``obmalloc`` is disabled by default. +- ``ensurepip`` is not available. +- Some ``ctypes`` features like ``c_longlong`` and ``c_longdouble`` may need + NodeJS option ``--experimental-wasm-bigint``. + +## wasm32-emscripten in browsers + +- The interactive shell does not handle copy 'n paste and unicode support + well. +- The bundled stdlib is limited. Network-related modules, + multiprocessing, dbm, tests and similar modules + are not shipped. All other modules are bundled as pre-compiled + ``pyc`` files. +- In-memory file system (MEMFS) is not persistent and limited. +- Test modules are disabled by default. Use ``--enable-test-modules`` build + test modules like ``_testcapi``. + +## wasm32-emscripten in node + +Node builds use ``NODERAWFS``. + +- Node RawFS allows direct access to the host file system without need to + perform ``FS.mount()`` call. + +## wasm64-emscripten + +- wasm64 requires recent NodeJS and ``--experimental-wasm-memory64``. +- ``EM_JS`` functions must return ``BigInt()``. +- ``Py_BuildValue()`` format strings must match size of types. Confusing 32 + and 64 bits types leads to memory corruption, see + [gh-95876](https://github.com/python/cpython/issues/95876) and + [gh-95878](https://github.com/python/cpython/issues/95878). + +# Hosting Python WASM builds + +The simple REPL terminal uses SharedArrayBuffer. For security reasons +browsers only provide the feature in secure environents with cross-origin +isolation. The webserver must send cross-origin headers and correct MIME types +for the JavaScript and WASM files. Otherwise the terminal will fail to load +with an error message like ``Browsers disable shared array buffer``. + +## Apache HTTP .htaccess + +Place a ``.htaccess`` file in the same directory as ``python.wasm``. + +``` +# .htaccess +Header set Cross-Origin-Opener-Policy same-origin +Header set Cross-Origin-Embedder-Policy require-corp + +AddType application/javascript js +AddType application/wasm wasm + + + AddOutputFilterByType DEFLATE text/html application/javascript application/wasm + +``` + +# WASI (wasm32-wasi) + +WASI builds require [WASI SDK](https://github.com/WebAssembly/wasi-sdk) 16.0+. + +## Cross-compile to wasm32-wasi + +The script ``wasi-env`` sets necessary compiler and linker flags as well as +``pkg-config`` overrides. The script assumes that WASI-SDK is installed in +``/opt/wasi-sdk`` or ``$WASI_SDK_PATH``. + +```shell +./Tools/wasm/wasm_build.py wasi +``` + +The command is roughly equivalent to: + +```shell +mkdir -p builddir/wasi +pushd builddir/wasi + +CONFIG_SITE=../../Tools/wasm/config.site-wasm32-wasi \ + ../../Tools/wasm/wasi-env ../../configure -C \ + --host=wasm32-unknown-wasi \ + --build=$(../../config.guess) \ + --with-build-python=$(pwd)/../build/python + +make -j$(nproc) +popd +``` + +## WASI limitations and issues (WASI SDK 15.0) + +A lot of Emscripten limitations also apply to WASI. Noticeable restrictions +are: + +- Call stack size is limited. Default recursion limit and parser stack size + are smaller than in regular Python builds. +- ``socket(2)`` cannot create new socket file descriptors. WASI programs can + call read/write/accept on a file descriptor that is passed into the process. +- ``socket.gethostname()`` and host name resolution APIs like + ``socket.gethostbyname()`` are not implemented and always fail. +- ``open(2)`` checks flags more strictly. Caller must pass either + ``O_RDONLY``, ``O_RDWR``, or ``O_WDONLY`` to ``os.open``. Directory file + descriptors must be created with flags ``O_RDONLY | O_DIRECTORY``. +- ``chmod(2)`` is not available. It's not possible to modify file permissions, + yet. A future version of WASI may provide a limited ``set_permissions`` API. +- User/group related features like ``os.chown()``, ``os.getuid``, etc. are + stubs or fail with ``ENOTSUP``. +- File locking (``fcntl``) is not available. +- ``os.pipe()``, ``os.mkfifo()``, and ``os.mknod()`` are not supported. +- ``process_time`` does not work as expected because it's implemented using + wall clock. +- ``os.umask()`` is a stub. +- ``sys.executable`` is empty. +- ``/dev/null`` / ``os.devnull`` may not be available. +- ``os.utime*()`` is buggy in WASM SDK 15.0, see + [utimensat() with timespec=NULL sets wrong time](https://github.com/bytecodealliance/wasmtime/issues/4184) +- ``os.symlink()`` fails with ``PermissionError`` when attempting to create a + symlink with an absolute path with wasmtime 0.36.0. The wasmtime runtime + uses ``openat2(2)`` syscall with flag ``RESOLVE_BENEATH`` to open files. + The flag causes the syscall to reject symlinks with absolute paths. +- ``os.curdir`` (aka ``.``) seems to behave differently, which breaks some + ``importlib`` tests that add ``.`` to ``sys.path`` and indirectly + ``sys.path_importer_cache``. +- WASI runtime environments may not provide a dedicated temp directory. + + +# Detect WebAssembly builds + +## Python code + +```python +import os, sys + +if sys.platform == "emscripten": + # Python on Emscripten +if sys.platform == "wasi": + # Python on WASI + +if os.name == "posix": + # WASM platforms identify as POSIX-like. + # Windows does not provide os.uname(). + machine = os.uname().machine + if machine.startswith("wasm"): + # WebAssembly (wasm32, wasm64 in the future) +``` + +```python +>>> import os, sys +>>> os.uname() +posix.uname_result( + sysname='Emscripten', + nodename='emscripten', + release='3.1.19', + version='#1', + machine='wasm32' +) +>>> os.name +'posix' +>>> sys.platform +'emscripten' +>>> sys._emscripten_info +sys._emscripten_info( + emscripten_version=(3, 1, 10), + runtime='Mozilla/5.0 (X11; Linux x86_64; rv:104.0) Gecko/20100101 Firefox/104.0', + pthreads=False, + shared_memory=False +) +``` + +```python +>>> sys._emscripten_info +sys._emscripten_info( + emscripten_version=(3, 1, 19), + runtime='Node.js v14.18.2', + pthreads=True, + shared_memory=True +) +``` + +```python +>>> import os, sys +>>> os.uname() +posix.uname_result( + sysname='wasi', + nodename='(none)', + release='0.0.0', + version='0.0.0', + machine='wasm32' +) +>>> os.name +'posix' +>>> sys.platform +'wasi' +``` + +## C code + +Emscripten SDK and WASI SDK define several built-in macros. You can dump a +full list of built-ins with ``emcc -dM -E - < /dev/null`` and +``/path/to/wasi-sdk/bin/clang -dM -E - < /dev/null``. + +```C +#ifdef __EMSCRIPTEN__ + // Python on Emscripten +#endif +``` + +* WebAssembly ``__wasm__`` (also ``__wasm``) +* wasm32 ``__wasm32__`` (also ``__wasm32``) +* wasm64 ``__wasm64__`` +* Emscripten ``__EMSCRIPTEN__`` (also ``EMSCRIPTEN``) +* Emscripten version ``__EMSCRIPTEN_major__``, ``__EMSCRIPTEN_minor__``, ``__EMSCRIPTEN_tiny__`` +* WASI ``__wasi__`` + +Feature detection flags: + +* ``__EMSCRIPTEN_PTHREADS__`` +* ``__EMSCRIPTEN_SHARED_MEMORY__`` +* ``__wasm_simd128__`` +* ``__wasm_sign_ext__`` +* ``__wasm_bulk_memory__`` +* ``__wasm_atomics__`` +* ``__wasm_mutable_globals__`` + +## Install SDKs and dependencies manually + +In some cases (e.g. build bots) you may prefer to install build dependencies +directly on the system instead of using the container image. Total disk size +of SDKs and cached libraries is about 1.6 GB. + +### Install OS dependencies + +```shell +# Debian/Ubuntu +apt update +apt install -y git make xz-utils bzip2 curl python3-minimal ccache +``` + +```shell +# Fedora +dnf install -y git make xz bzip2 which ccache +``` + +### Install [Emscripten SDK](https://emscripten.org/docs/getting_started/downloads.html) + +**NOTE**: Follow the on-screen instructions how to add the SDK to ``PATH``. + +```shell +git clone https://github.com/emscripten-core/emsdk.git /opt/emsdk +/opt/emsdk/emsdk install latest +/opt/emsdk/emsdk activate latest +``` + +### Optionally: enable ccache for EMSDK + +The ``EM_COMPILER_WRAPPER`` must be set after the EMSDK environment is +sourced. Otherwise the source script removes the environment variable. + +``` +. /opt/emsdk/emsdk_env.sh +EM_COMPILER_WRAPPER=ccache +``` + +### Optionally: pre-build and cache static libraries + +Emscripten SDK provides static builds of core libraries without PIC +(position-independent code). Python builds with ``dlopen`` support require +PIC. To populate the build cache, run: + +```shell +. /opt/emsdk/emsdk_env.sh +embuilder build zlib bzip2 MINIMAL_PIC +embuilder build --pic zlib bzip2 MINIMAL_PIC +``` + +### Install [WASI-SDK](https://github.com/WebAssembly/wasi-sdk) + +**NOTE**: WASI-SDK's clang may show a warning on Fedora: +``/lib64/libtinfo.so.6: no version information available``, +[RHBZ#1875587](https://bugzilla.redhat.com/show_bug.cgi?id=1875587). The +warning can be ignored. + +```shell +export WASI_VERSION=16 +export WASI_VERSION_FULL=${WASI_VERSION}.0 +curl -sSf -L -O https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_VERSION}/wasi-sdk-${WASI_VERSION_FULL}-linux.tar.gz +mkdir -p /opt/wasi-sdk +tar --strip-components=1 -C /opt/wasi-sdk -xvf wasi-sdk-${WASI_VERSION_FULL}-linux.tar.gz +rm -f wasi-sdk-${WASI_VERSION_FULL}-linux.tar.gz +``` + +### Install [wasmtime](https://github.com/bytecodealliance/wasmtime) WASI runtime + +wasmtime 0.38 or newer is required. + +```shell +curl -sSf -L -o ~/install-wasmtime.sh https://wasmtime.dev/install.sh +chmod +x ~/install-wasmtime.sh +~/install-wasmtime.sh --version v0.38.0 +ln -srf -t /usr/local/bin/ ~/.wasmtime/bin/wasmtime +``` + + +### WASI debugging + +* ``wasmtime run -g`` generates debugging symbols for gdb and lldb. The + feature is currently broken, see + https://github.com/bytecodealliance/wasmtime/issues/4669 . +* The environment variable ``RUST_LOG=wasi_common`` enables debug and + trace logging. diff --git a/Tools/wasm/Setup.local.example b/Tools/wasm/Setup.local.example new file mode 100644 index 00000000000..ad58c31a2ef --- /dev/null +++ b/Tools/wasm/Setup.local.example @@ -0,0 +1,15 @@ +# Module/Setup.local with reduced stdlib +*disabled* +_asyncio +audioop +_bz2 +_crypt +_decimal +_pickle +pyexpat _elementtree +_sha3 _blake2 +_zoneinfo +xxsubtype + +# cjk codecs +#_multibytecodec _codecs_cn _codecs_hk _codecs_iso2022 _codecs_jp _codecs_kr _codecs_tw diff --git a/Tools/wasm/config.site-wasm32-emscripten b/Tools/wasm/config.site-wasm32-emscripten new file mode 100644 index 00000000000..1471546a5ee --- /dev/null +++ b/Tools/wasm/config.site-wasm32-emscripten @@ -0,0 +1,104 @@ +# config.site override for cross compiling to wasm32-emscripten platform +# +# CONFIG_SITE=Tools/wasm/config.site-wasm32-emscripten \ +# emconfigure ./configure --host=wasm32-unknown-emscripten --build=... +# +# Written by Christian Heimes +# Partly based on pyodide's pyconfig.undefs.h file. +# + +# cannot be detected in cross builds +ac_cv_buggy_getaddrinfo=no + +# Emscripten has no /dev/pt* +ac_cv_file__dev_ptmx=no +ac_cv_file__dev_ptc=no + +# new undefined symbols / unsupported features +ac_cv_func_posix_spawn=no +ac_cv_func_posix_spawnp=no +ac_cv_func_eventfd=no +ac_cv_func_memfd_create=no +ac_cv_func_prlimit=no + +# unsupported syscall, https://github.com/emscripten-core/emscripten/issues/13393 +ac_cv_func_shutdown=no + +# The rest is based on pyodide +# https://github.com/pyodide/pyodide/blob/main/cpython/pyconfig.undefs.h + +ac_cv_func_epoll_create=no +ac_cv_func_epoll_create1=no +ac_cv_header_linux_vm_sockets_h=no +ac_cv_func_socketpair=no +ac_cv_func_sigaction=no + +# symlinkat is implemented, but fails +ac_cv_func_symlinkat=no + +# lchmod/lchown are implemented, but fail with ENOTSUP. +ac_cv_func_lchmod=no +ac_cv_func_lchown=no + +# geteuid / getegid are stubs and always return 0 (root). The stub breaks +# code that assume effective user root has special permissions. +ac_cv_func_geteuid=no +ac_cv_func_getegid=no +ac_cv_func_seteuid=no +ac_cv_func_setegid=no +ac_cv_func_getresuid=no +ac_cv_func_getresgid=no +ac_cv_func_setresuid=no +ac_cv_func_setresgid=no + +# Syscalls not implemented in emscripten +# [Errno 52] Function not implemented +ac_cv_func_preadv2=no +ac_cv_func_preadv=no +ac_cv_func_pwritev2=no +ac_cv_func_pwritev=no +ac_cv_func_pipe2=no +ac_cv_func_nice=no +ac_cv_func_setpriority=no +ac_cv_func_setitimer=no +# unsupported syscall: __syscall_prlimit64 +ac_cv_func_prlimit=no +# unsupported syscall: __syscall_getrusage +ac_cv_func_getrusage=no +ac_cv_func_posix_fallocate=no + +# Syscalls that resulted in a segfault +ac_cv_func_utimensat=no +ac_cv_header_sys_ioctl_h=no + +# sockets are supported, but only AF_INET / AF_INET6 in non-blocking mode. +# Disable AF_UNIX and AF_PACKET support, see socketmodule.h. +ac_cv_header_sys_un_h=no +ac_cv_header_netpacket_packet_h=no + +# aborts with bad ioctl +ac_cv_func_openpty=no +ac_cv_func_forkpty=no + +# mkfifo and mknod are broken, create regular file +ac_cv_func_mkfifo=no +ac_cv_func_mkfifoat=no +ac_cv_func_mknod=no +ac_cv_func_mknodat=no + +# always fails with permission or not implemented error +ac_cv_func_getgroups=no +ac_cv_func_setgroups=no +ac_cv_func_setresuid=no +ac_cv_func_setresgid=no + +# Emscripten does not support hard links, always fails with errno 34 +# "Too many links". See emscripten_syscall_stubs.c +ac_cv_func_link=no +ac_cv_func_linkat=no + +# Emscripten's faccessat does not accept AT_* flags. +ac_cv_func_faccessat=no + +# alarm signal is not delivered, may need a callback into the event loop? +ac_cv_func_alarm=no diff --git a/Tools/wasm/config.site-wasm32-wasi b/Tools/wasm/config.site-wasm32-wasi new file mode 100644 index 00000000000..5e98775400f --- /dev/null +++ b/Tools/wasm/config.site-wasm32-wasi @@ -0,0 +1,42 @@ +# config.site override for cross compiling to wasm32-wasi platform +# +# Written by Christian Heimes + +# cannot be detected in cross builds +ac_cv_buggy_getaddrinfo=no + +# WASI has no /dev/pt* +ac_cv_file__dev_ptmx=no +ac_cv_file__dev_ptc=no + +# get/setrlimit are not supported +ac_cv_header_sys_resource_h=no + +# undefined symbols / unsupported features +ac_cv_func_eventfd=no + +# WASI SDK 15.0 has no pipe syscall. +ac_cv_func_pipe=no + +# WASI SDK 15.0 cannot create fifos and special files. +ac_cv_func_mkfifo=no +ac_cv_func_mkfifoat=no +ac_cv_func_mknod=no +ac_cv_func_mknodat=no +ac_cv_func_makedev=no + +# fdopendir() fails on SDK 15.0, +# OSError: [Errno 28] Invalid argument: '.' +ac_cv_func_fdopendir=no + +# WASI sockets are limited to operations on given socket fd and inet sockets. +# Disable AF_UNIX and AF_PACKET support, see socketmodule.h. +ac_cv_header_sys_un_h=no +ac_cv_header_netpacket_packet_h=no + +# disable accept for WASM runtimes without sock_accept +#ac_cv_func_accept=no +#ac_cv_func_accept4=no + +# Disable int-conversion for wask-sdk as it triggers an error from version 17. +ac_cv_disable_int_conversion=yes diff --git a/Tools/wasm/python.html b/Tools/wasm/python.html new file mode 100644 index 00000000000..17ffa0ea8bf --- /dev/null +++ b/Tools/wasm/python.html @@ -0,0 +1,316 @@ + + + + + + + + + wasm-python terminal + + + + + + +

    Simple REPL for Python WASM

    +
    +
    + + +
    +
    + The simple REPL provides a limited Python experience in the browser. + + Tools/wasm/README.md contains a list of known limitations and + issues. Networking, subprocesses, and threading are not available. +
    + + diff --git a/Tools/wasm/python.worker.js b/Tools/wasm/python.worker.js new file mode 100644 index 00000000000..1b794608fff --- /dev/null +++ b/Tools/wasm/python.worker.js @@ -0,0 +1,83 @@ +class StdinBuffer { + constructor() { + this.sab = new SharedArrayBuffer(128 * Int32Array.BYTES_PER_ELEMENT) + this.buffer = new Int32Array(this.sab) + this.readIndex = 1; + this.numberOfCharacters = 0; + this.sentNull = true + } + + prompt() { + this.readIndex = 1 + Atomics.store(this.buffer, 0, -1) + postMessage({ + type: 'stdin', + buffer: this.sab + }) + Atomics.wait(this.buffer, 0, -1) + this.numberOfCharacters = this.buffer[0] + } + + stdin = () => { + if (this.numberOfCharacters + 1 === this.readIndex) { + if (!this.sentNull) { + // Must return null once to indicate we're done for now. + this.sentNull = true + return null + } + this.sentNull = false + this.prompt() + } + const char = this.buffer[this.readIndex] + this.readIndex += 1 + // How do I send an EOF?? + return char + } +} + +const stdout = (charCode) => { + if (charCode) { + postMessage({ + type: 'stdout', + stdout: charCode, + }) + } else { + console.log(typeof charCode, charCode) + } +} + +const stderr = (charCode) => { + if (charCode) { + postMessage({ + type: 'stderr', + stderr: charCode, + }) + } else { + console.log(typeof charCode, charCode) + } +} + +const stdinBuffer = new StdinBuffer() + +var Module = { + noInitialRun: true, + stdin: stdinBuffer.stdin, + stdout: stdout, + stderr: stderr, + onRuntimeInitialized: () => { + postMessage({type: 'ready', stdinBuffer: stdinBuffer.sab}) + } +} + +onmessage = (event) => { + if (event.data.type === 'run') { + // TODO: Set up files from event.data.files + const ret = callMain(event.data.args) + postMessage({ + type: 'finished', + returnCode: ret + }) + } +} + +importScripts('python.js') diff --git a/Tools/wasm/wasi-env b/Tools/wasm/wasi-env new file mode 100755 index 00000000000..48908b02e60 --- /dev/null +++ b/Tools/wasm/wasi-env @@ -0,0 +1,76 @@ +#!/bin/sh +set -e + +# function +usage() { + echo "wasi-env - Run command with WASI-SDK" + echo "" + echo "wasi-env is a helper to set various environment variables to" + echo "run configure and make with WASI-SDK. A WASI-SDK must be either" + echo "installed at /opt/wasi-sdk or the env var 'WASI_SDK_PATH' must" + echo "set to the root of a WASI-SDK." + echo "" + echo "Usage: wasi-env command [...]" + echo "" + echo " -h --help display this help and exit" + echo "" +} + +case $1 in + -h|--help) + usage + exit + ;; +esac + +if test -z "$1"; then + echo "ERROR: command required" >&2 + usage + exit 1 +fi + +WASI_SDK_PATH="${WASI_SDK_PATH:-/opt/wasi-sdk}" +WASI_SYSROOT="${WASI_SDK_PATH}/share/wasi-sysroot" + +if ! test -x "${WASI_SDK_PATH}/bin/clang"; then + echo "Error: ${WASI_SDK_PATH}/bin/clang does not exist." >&2 + exit 2 +fi + +CC="${WASI_SDK_PATH}/bin/clang" +CPP="${WASI_SDK_PATH}/bin/clang-cpp" +CXX="${WASI_SDK_PATH}/bin/clang++" + +# --sysroot is required if WASI-SDK is not installed in /opt/wasi-sdk. +if test "${WASI_SDK_PATH}" != "/opt/wasi-sdk"; then + CC="${CC} --sysroot=${WASI_SYSROOT}" + CPP="${CPP} --sysroot=${WASI_SYSROOT}" + CXX="${CXX} --sysroot=${WASI_SYSROOT}" +fi + +# use ccache if available +if command -v ccache >/dev/null 2>&1; then + CC="ccache ${CC}" + CPP="ccache ${CPP}" + CXX="ccache ${CXX}" +fi + +LDSHARED="${WASI_SDK_PATH}/bin/wasm-ld" +AR="${WASI_SDK_PATH}/bin/llvm-ar" +RANLIB="${WASI_SDK_PATH}/bin/ranlib" + +# instruct pkg-config to use sysroot +PKG_CONFIG_PATH="" +PKG_CONFIG_LIBDIR="${WASI_SYSROOT}/lib/pkgconfig:${WASI_SYSROOT}/share/pkgconfig" +PKG_CONFIG_SYSROOT_DIR="${WASI_SYSROOT}" + +PATH="${WASI_SDK_PATH}/bin:${PATH}" + +export WASI_SDK_PATH WASI_SYSROOT +export CC CPP CXX LDSHARED AR RANLIB +export CFLAGS LDFLAGS +export PKG_CONFIG_PATH PKG_CONFIG_LIBDIR PKG_CONFIG_SYSROOT_DIR +export PATH + +# no exec, it makes arvg[0] path absolute. +"$@" diff --git a/Tools/wasm/wasm_assets.py b/Tools/wasm/wasm_assets.py new file mode 100755 index 00000000000..9dc8bda4017 --- /dev/null +++ b/Tools/wasm/wasm_assets.py @@ -0,0 +1,256 @@ +#!/usr/bin/env python +"""Create a WASM asset bundle directory structure. + +The WASM asset bundles are pre-loaded by the final WASM build. The bundle +contains: + +- a stripped down, pyc-only stdlib zip file, e.g. {PREFIX}/lib/python311.zip +- os.py as marker module {PREFIX}/lib/python3.11/os.py +- empty lib-dynload directory, to make sure it is copied into the bundle {PREFIX}/lib/python3.11/lib-dynload/.empty +""" + +import argparse +import pathlib +import shutil +import sys +import sysconfig +import zipfile + +# source directory +SRCDIR = pathlib.Path(__file__).parent.parent.parent.absolute() +SRCDIR_LIB = SRCDIR / "Lib" + + +# Library directory relative to $(prefix). +WASM_LIB = pathlib.PurePath("lib") +WASM_STDLIB_ZIP = ( + WASM_LIB / f"python{sys.version_info.major}{sys.version_info.minor}.zip" +) +WASM_STDLIB = ( + WASM_LIB / f"python{sys.version_info.major}.{sys.version_info.minor}" +) +WASM_DYNLOAD = WASM_STDLIB / "lib-dynload" + + +# Don't ship large files / packages that are not particularly useful at +# the moment. +OMIT_FILES = ( + # regression tests + "test/", + # package management + "ensurepip/", + "venv/", + # build system + "lib2to3/", + # deprecated + "uu.py", + "xdrlib.py", + # other platforms + "_aix_support.py", + "_osx_support.py", + # webbrowser + "antigravity.py", + "webbrowser.py", + # Pure Python implementations of C extensions + "_pydecimal.py", + "_pyio.py", + # concurrent threading + "concurrent/futures/thread.py", + # Misc unused or large files + "pydoc_data/", + "msilib/", +) + +# Synchronous network I/O and protocols are not supported; for example, +# socket.create_connection() raises an exception: +# "BlockingIOError: [Errno 26] Operation in progress". +OMIT_NETWORKING_FILES = ( + "cgi.py", + "cgitb.py", + "email/", + "ftplib.py", + "http/", + "imaplib.py", + "mailbox.py", + "mailcap.py", + "nntplib.py", + "poplib.py", + "smtplib.py", + "socketserver.py", + "telnetlib.py", + # keep urllib.parse for pydoc + "urllib/error.py", + "urllib/request.py", + "urllib/response.py", + "urllib/robotparser.py", + "wsgiref/", +) + +OMIT_MODULE_FILES = { + "_asyncio": ["asyncio/"], + "audioop": ["aifc.py", "sunau.py", "wave.py"], + "_crypt": ["crypt.py"], + "_curses": ["curses/"], + "_ctypes": ["ctypes/"], + "_decimal": ["decimal.py"], + "_dbm": ["dbm/ndbm.py"], + "_gdbm": ["dbm/gnu.py"], + "_json": ["json/"], + "_multiprocessing": ["concurrent/futures/process.py", "multiprocessing/"], + "pyexpat": ["xml/", "xmlrpc/"], + "readline": ["rlcompleter.py"], + "_sqlite3": ["sqlite3/"], + "_ssl": ["ssl.py"], + "_tkinter": ["idlelib/", "tkinter/", "turtle.py", "turtledemo/"], + "_zoneinfo": ["zoneinfo/"], +} + +SYSCONFIG_NAMES = ( + "_sysconfigdata__emscripten_wasm32-emscripten", + "_sysconfigdata__emscripten_wasm32-emscripten", + "_sysconfigdata__wasi_wasm32-wasi", + "_sysconfigdata__wasi_wasm64-wasi", +) + + +def get_builddir(args: argparse.Namespace) -> pathlib.Path: + """Get builddir path from pybuilddir.txt""" + with open("pybuilddir.txt", encoding="utf-8") as f: + builddir = f.read() + return pathlib.Path(builddir) + + +def get_sysconfigdata(args: argparse.Namespace) -> pathlib.Path: + """Get path to sysconfigdata relative to build root""" + data_name = sysconfig._get_sysconfigdata_name() + if not data_name.startswith(SYSCONFIG_NAMES): + raise ValueError( + f"Invalid sysconfig data name '{data_name}'.", SYSCONFIG_NAMES + ) + filename = data_name + ".py" + return args.builddir / filename + + +def create_stdlib_zip( + args: argparse.Namespace, + *, + optimize: int = 0, +) -> None: + def filterfunc(filename: str) -> bool: + pathname = pathlib.Path(filename).resolve() + return pathname not in args.omit_files_absolute + + with zipfile.PyZipFile( + args.wasm_stdlib_zip, + mode="w", + compression=args.compression, + optimize=optimize, + ) as pzf: + if args.compresslevel is not None: + pzf.compresslevel = args.compresslevel + pzf.writepy(args.sysconfig_data) + for entry in sorted(args.srcdir_lib.iterdir()): + entry = entry.resolve() + if entry.name == "__pycache__": + continue + if entry.name.endswith(".py") or entry.is_dir(): + # writepy() writes .pyc files (bytecode). + pzf.writepy(entry, filterfunc=filterfunc) + + +def detect_extension_modules(args: argparse.Namespace): + modules = {} + + # disabled by Modules/Setup.local ? + with open(args.buildroot / "Makefile") as f: + for line in f: + if line.startswith("MODDISABLED_NAMES="): + disabled = line.split("=", 1)[1].strip().split() + for modname in disabled: + modules[modname] = False + break + + # disabled by configure? + with open(args.sysconfig_data) as f: + data = f.read() + loc = {} + exec(data, globals(), loc) + + for key, value in loc["build_time_vars"].items(): + if not key.startswith("MODULE_") or not key.endswith("_STATE"): + continue + if value not in {"yes", "disabled", "missing", "n/a"}: + raise ValueError(f"Unsupported value '{value}' for {key}") + + modname = key[7:-6].lower() + if modname not in modules: + modules[modname] = value == "yes" + return modules + + +def path(val: str) -> pathlib.Path: + return pathlib.Path(val).absolute() + + +parser = argparse.ArgumentParser() +parser.add_argument( + "--buildroot", + help="absolute path to build root", + default=pathlib.Path(".").absolute(), + type=path, +) +parser.add_argument( + "--prefix", + help="install prefix", + default=pathlib.Path("/usr/local"), + type=path, +) + + +def main(): + args = parser.parse_args() + + relative_prefix = args.prefix.relative_to(pathlib.Path("/")) + args.srcdir = SRCDIR + args.srcdir_lib = SRCDIR_LIB + args.wasm_root = args.buildroot / relative_prefix + args.wasm_stdlib_zip = args.wasm_root / WASM_STDLIB_ZIP + args.wasm_stdlib = args.wasm_root / WASM_STDLIB + args.wasm_dynload = args.wasm_root / WASM_DYNLOAD + + # bpo-17004: zipimport supports only zlib compression. + # Emscripten ZIP_STORED + -sLZ4=1 linker flags results in larger file. + args.compression = zipfile.ZIP_DEFLATED + args.compresslevel = 9 + + args.builddir = get_builddir(args) + args.sysconfig_data = get_sysconfigdata(args) + if not args.sysconfig_data.is_file(): + raise ValueError(f"sysconfigdata file {args.sysconfig_data} missing.") + + extmods = detect_extension_modules(args) + omit_files = list(OMIT_FILES) + if sysconfig.get_platform().startswith("emscripten"): + omit_files.extend(OMIT_NETWORKING_FILES) + for modname, modfiles in OMIT_MODULE_FILES.items(): + if not extmods.get(modname): + omit_files.extend(modfiles) + + args.omit_files_absolute = { + (args.srcdir_lib / name).resolve() for name in omit_files + } + + # Empty, unused directory for dynamic libs, but required for site initialization. + args.wasm_dynload.mkdir(parents=True, exist_ok=True) + marker = args.wasm_dynload / ".empty" + marker.touch() + # os.py is a marker for finding the correct lib directory. + shutil.copy(args.srcdir_lib / "os.py", args.wasm_stdlib) + # The rest of stdlib that's useful in a WASM context. + create_stdlib_zip(args) + size = round(args.wasm_stdlib_zip.stat().st_size / 1024**2, 2) + parser.exit(0, f"Created {args.wasm_stdlib_zip} ({size} MiB)\n") + + +if __name__ == "__main__": + main() diff --git a/Tools/wasm/wasm_build.py b/Tools/wasm/wasm_build.py new file mode 100755 index 00000000000..493682c5b13 --- /dev/null +++ b/Tools/wasm/wasm_build.py @@ -0,0 +1,907 @@ +#!/usr/bin/env python3 +"""Build script for Python on WebAssembly platforms. + + $ ./Tools/wasm/wasm_builder.py emscripten-browser build repl + $ ./Tools/wasm/wasm_builder.py emscripten-node-dl build test + $ ./Tools/wasm/wasm_builder.py wasi build test + +Primary build targets are "emscripten-node-dl" (NodeJS, dynamic linking), +"emscripten-browser", and "wasi". + +Emscripten builds require a recent Emscripten SDK. The tools looks for an +activated EMSDK environment (". /path/to/emsdk_env.sh"). System packages +(Debian, Homebrew) are not supported. + +WASI builds require WASI SDK and wasmtime. The tool looks for 'WASI_SDK_PATH' +and falls back to /opt/wasi-sdk. + +The 'build' Python interpreter must be rebuilt every time Python's byte code +changes. + + ./Tools/wasm/wasm_builder.py --clean build build + +""" +import argparse +import enum +import dataclasses +import logging +import os +import pathlib +import re +import shlex +import shutil +import socket +import subprocess +import sys +import sysconfig +import tempfile +import time +import warnings +import webbrowser + +# for Python 3.8 +from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union + +logger = logging.getLogger("wasm_build") + +SRCDIR = pathlib.Path(__file__).parent.parent.parent.absolute() +WASMTOOLS = SRCDIR / "Tools" / "wasm" +BUILDDIR = SRCDIR / "builddir" +CONFIGURE = SRCDIR / "configure" +SETUP_LOCAL = SRCDIR / "Modules" / "Setup.local" + +HAS_CCACHE = shutil.which("ccache") is not None + +# path to WASI-SDK root +WASI_SDK_PATH = pathlib.Path(os.environ.get("WASI_SDK_PATH", "/opt/wasi-sdk")) + +# path to Emscripten SDK config file. +# auto-detect's EMSDK in /opt/emsdk without ". emsdk_env.sh". +EM_CONFIG = pathlib.Path(os.environ.setdefault("EM_CONFIG", "/opt/emsdk/.emscripten")) +EMSDK_MIN_VERSION = (3, 1, 19) +EMSDK_BROKEN_VERSION = { + (3, 1, 14): "https://github.com/emscripten-core/emscripten/issues/17338", + (3, 1, 16): "https://github.com/emscripten-core/emscripten/issues/17393", + (3, 1, 20): "https://github.com/emscripten-core/emscripten/issues/17720", +} +_MISSING = pathlib.PurePath("MISSING") + +WASM_WEBSERVER = WASMTOOLS / "wasm_webserver.py" + +CLEAN_SRCDIR = f""" +Builds require a clean source directory. Please use a clean checkout or +run "make clean -C '{SRCDIR}'". +""" + +INSTALL_NATIVE = f""" +Builds require a C compiler (gcc, clang), make, pkg-config, and development +headers for dependencies like zlib. + +Debian/Ubuntu: sudo apt install build-essential git curl pkg-config zlib1g-dev +Fedora/CentOS: sudo dnf install gcc make git-core curl pkgconfig zlib-devel +""" + +INSTALL_EMSDK = """ +wasm32-emscripten builds need Emscripten SDK. Please follow instructions at +https://emscripten.org/docs/getting_started/downloads.html how to install +Emscripten and how to activate the SDK with "emsdk_env.sh". + + git clone https://github.com/emscripten-core/emsdk.git /path/to/emsdk + cd /path/to/emsdk + ./emsdk install latest + ./emsdk activate latest + source /path/to/emsdk_env.sh +""" + +INSTALL_WASI_SDK = """ +wasm32-wasi builds need WASI SDK. Please fetch the latest SDK from +https://github.com/WebAssembly/wasi-sdk/releases and install it to +"/opt/wasi-sdk". Alternatively you can install the SDK in a different location +and point the environment variable WASI_SDK_PATH to the root directory +of the SDK. The SDK is available for Linux x86_64, macOS x86_64, and MinGW. +""" + +INSTALL_WASMTIME = """ +wasm32-wasi tests require wasmtime on PATH. Please follow instructions at +https://wasmtime.dev/ to install wasmtime. +""" + + +def parse_emconfig( + emconfig: pathlib.Path = EM_CONFIG, +) -> Tuple[pathlib.PurePath, pathlib.PurePath]: + """Parse EM_CONFIG file and lookup EMSCRIPTEN_ROOT and NODE_JS. + + The ".emscripten" config file is a Python snippet that uses "EM_CONFIG" + environment variable. EMSCRIPTEN_ROOT is the "upstream/emscripten" + subdirectory with tools like "emconfigure". + """ + if not emconfig.exists(): + return _MISSING, _MISSING + with open(emconfig, encoding="utf-8") as f: + code = f.read() + # EM_CONFIG file is a Python snippet + local: Dict[str, Any] = {} + exec(code, globals(), local) + emscripten_root = pathlib.Path(local["EMSCRIPTEN_ROOT"]) + node_js = pathlib.Path(local["NODE_JS"]) + return emscripten_root, node_js + + +EMSCRIPTEN_ROOT, NODE_JS = parse_emconfig() + + +def read_python_version(configure: pathlib.Path = CONFIGURE) -> str: + """Read PACKAGE_VERSION from configure script + + configure and configure.ac are the canonical source for major and + minor version number. + """ + version_re = re.compile(r"^PACKAGE_VERSION='(\d\.\d+)'") + with configure.open(encoding="utf-8") as f: + for line in f: + mo = version_re.match(line) + if mo: + return mo.group(1) + raise ValueError(f"PACKAGE_VERSION not found in {configure}") + + +PYTHON_VERSION = read_python_version() + + +class ConditionError(ValueError): + def __init__(self, info: str, text: str): + self.info = info + self.text = text + + def __str__(self): + return f"{type(self).__name__}: '{self.info}'\n{self.text}" + + +class MissingDependency(ConditionError): + pass + + +class DirtySourceDirectory(ConditionError): + pass + + +@dataclasses.dataclass +class Platform: + """Platform-specific settings + + - CONFIG_SITE override + - configure wrapper (e.g. emconfigure) + - make wrapper (e.g. emmake) + - additional environment variables + - check function to verify SDK + """ + + name: str + pythonexe: str + config_site: Optional[pathlib.PurePath] + configure_wrapper: Optional[pathlib.PurePath] + make_wrapper: Optional[pathlib.PurePath] + environ: dict + check: Callable[[], None] + # Used for build_emports(). + ports: Optional[pathlib.PurePath] + cc: Optional[pathlib.PurePath] + + def getenv(self, profile: "BuildProfile") -> dict: + return self.environ.copy() + + +def _check_clean_src(): + candidates = [ + SRCDIR / "Programs" / "python.o", + SRCDIR / "Python" / "frozen_modules" / "importlib._bootstrap.h", + ] + for candidate in candidates: + if candidate.exists(): + raise DirtySourceDirectory(os.fspath(candidate), CLEAN_SRCDIR) + + +def _check_native(): + if not any(shutil.which(cc) for cc in ["cc", "gcc", "clang"]): + raise MissingDependency("cc", INSTALL_NATIVE) + if not shutil.which("make"): + raise MissingDependency("make", INSTALL_NATIVE) + if sys.platform == "linux": + # skip pkg-config check on macOS + if not shutil.which("pkg-config"): + raise MissingDependency("pkg-config", INSTALL_NATIVE) + # zlib is needed to create zip files + for devel in ["zlib"]: + try: + subprocess.check_call(["pkg-config", "--exists", devel]) + except subprocess.CalledProcessError: + raise MissingDependency(devel, INSTALL_NATIVE) from None + _check_clean_src() + + +NATIVE = Platform( + "native", + # macOS has python.exe + pythonexe=sysconfig.get_config_var("BUILDPYTHON") or "python", + config_site=None, + configure_wrapper=None, + ports=None, + cc=None, + make_wrapper=None, + environ={}, + check=_check_native, +) + + +def _check_emscripten(): + if EMSCRIPTEN_ROOT is _MISSING: + raise MissingDependency("Emscripten SDK EM_CONFIG", INSTALL_EMSDK) + # sanity check + emconfigure = EMSCRIPTEN.configure_wrapper + if not emconfigure.exists(): + raise MissingDependency(os.fspath(emconfigure), INSTALL_EMSDK) + # version check + version_txt = EMSCRIPTEN_ROOT / "emscripten-version.txt" + if not version_txt.exists(): + raise MissingDependency(os.fspath(version_txt), INSTALL_EMSDK) + with open(version_txt) as f: + version = f.read().strip().strip('"') + if version.endswith("-git"): + # git / upstream / tot-upstream installation + version = version[:-4] + version_tuple = tuple(int(v) for v in version.split(".")) + if version_tuple < EMSDK_MIN_VERSION: + raise ConditionError( + os.fspath(version_txt), + f"Emscripten SDK {version} in '{EMSCRIPTEN_ROOT}' is older than " + "minimum required version " + f"{'.'.join(str(v) for v in EMSDK_MIN_VERSION)}.", + ) + broken = EMSDK_BROKEN_VERSION.get(version_tuple) + if broken is not None: + raise ConditionError( + os.fspath(version_txt), + ( + f"Emscripten SDK {version} in '{EMSCRIPTEN_ROOT}' has known " + f"bugs, see {broken}." + ), + ) + if os.environ.get("PKG_CONFIG_PATH"): + warnings.warn( + "PKG_CONFIG_PATH is set and not empty. emconfigure overrides " + "this environment variable. Use EM_PKG_CONFIG_PATH instead." + ) + _check_clean_src() + + +EMSCRIPTEN = Platform( + "emscripten", + pythonexe="python.js", + config_site=WASMTOOLS / "config.site-wasm32-emscripten", + configure_wrapper=EMSCRIPTEN_ROOT / "emconfigure", + ports=EMSCRIPTEN_ROOT / "embuilder", + cc=EMSCRIPTEN_ROOT / "emcc", + make_wrapper=EMSCRIPTEN_ROOT / "emmake", + environ={ + # workaround for https://github.com/emscripten-core/emscripten/issues/17635 + "TZ": "UTC", + "EM_COMPILER_WRAPPER": "ccache" if HAS_CCACHE else None, + "PATH": [EMSCRIPTEN_ROOT, os.environ["PATH"]], + }, + check=_check_emscripten, +) + + +def _check_wasi(): + wasm_ld = WASI_SDK_PATH / "bin" / "wasm-ld" + if not wasm_ld.exists(): + raise MissingDependency(os.fspath(wasm_ld), INSTALL_WASI_SDK) + wasmtime = shutil.which("wasmtime") + if wasmtime is None: + raise MissingDependency("wasmtime", INSTALL_WASMTIME) + _check_clean_src() + + +WASI = Platform( + "wasi", + pythonexe="python.wasm", + config_site=WASMTOOLS / "config.site-wasm32-wasi", + configure_wrapper=WASMTOOLS / "wasi-env", + ports=None, + cc=WASI_SDK_PATH / "bin" / "clang", + make_wrapper=None, + environ={ + "WASI_SDK_PATH": WASI_SDK_PATH, + # workaround for https://github.com/python/cpython/issues/95952 + "HOSTRUNNER": ( + "wasmtime run " + "--env PYTHONPATH=/{relbuilddir}/build/lib.wasi-wasm32-{version}:/Lib " + "--mapdir /::{srcdir} --" + ), + "PATH": [WASI_SDK_PATH / "bin", os.environ["PATH"]], + }, + check=_check_wasi, +) + + +class Host(enum.Enum): + """Target host triplet""" + + wasm32_emscripten = "wasm32-unknown-emscripten" + wasm64_emscripten = "wasm64-unknown-emscripten" + wasm32_wasi = "wasm32-unknown-wasi" + wasm64_wasi = "wasm64-unknown-wasi" + # current platform + build = sysconfig.get_config_var("BUILD_GNU_TYPE") + + @property + def platform(self) -> Platform: + if self.is_emscripten: + return EMSCRIPTEN + elif self.is_wasi: + return WASI + else: + return NATIVE + + @property + def is_emscripten(self) -> bool: + cls = type(self) + return self in {cls.wasm32_emscripten, cls.wasm64_emscripten} + + @property + def is_wasi(self) -> bool: + cls = type(self) + return self in {cls.wasm32_wasi, cls.wasm64_wasi} + + def get_extra_paths(self) -> Iterable[pathlib.PurePath]: + """Host-specific os.environ["PATH"] entries. + + Emscripten's Node version 14.x works well for wasm32-emscripten. + wasm64-emscripten requires more recent v8 version, e.g. node 16.x. + Attempt to use system's node command. + """ + cls = type(self) + if self == cls.wasm32_emscripten: + return [NODE_JS.parent] + elif self == cls.wasm64_emscripten: + # TODO: look for recent node + return [] + else: + return [] + + @property + def emport_args(self) -> List[str]: + """Host-specific port args (Emscripten).""" + cls = type(self) + if self is cls.wasm64_emscripten: + return ["-sMEMORY64=1"] + elif self is cls.wasm32_emscripten: + return ["-sMEMORY64=0"] + else: + return [] + + @property + def embuilder_args(self) -> List[str]: + """Host-specific embuilder args (Emscripten).""" + cls = type(self) + if self is cls.wasm64_emscripten: + return ["--wasm64"] + else: + return [] + + +class EmscriptenTarget(enum.Enum): + """Emscripten-specific targets (--with-emscripten-target)""" + + browser = "browser" + browser_debug = "browser-debug" + node = "node" + node_debug = "node-debug" + + @property + def is_browser(self): + cls = type(self) + return self in {cls.browser, cls.browser_debug} + + @property + def emport_args(self) -> List[str]: + """Target-specific port args.""" + cls = type(self) + if self in {cls.browser_debug, cls.node_debug}: + # some libs come in debug and non-debug builds + return ["-O0"] + else: + return ["-O2"] + + +class SupportLevel(enum.Enum): + supported = "tier 3, supported" + working = "working, unsupported" + experimental = "experimental, may be broken" + broken = "broken / unavailable" + + def __bool__(self): + cls = type(self) + return self in {cls.supported, cls.working} + + +@dataclasses.dataclass +class BuildProfile: + name: str + support_level: SupportLevel + host: Host + target: Union[EmscriptenTarget, None] = None + dynamic_linking: Union[bool, None] = None + pthreads: Union[bool, None] = None + default_testopts: str = "-j2" + + @property + def is_browser(self) -> bool: + """Is this a browser build?""" + return self.target is not None and self.target.is_browser + + @property + def builddir(self) -> pathlib.Path: + """Path to build directory""" + return BUILDDIR / self.name + + @property + def python_cmd(self) -> pathlib.Path: + """Path to python executable""" + return self.builddir / self.host.platform.pythonexe + + @property + def makefile(self) -> pathlib.Path: + """Path to Makefile""" + return self.builddir / "Makefile" + + @property + def configure_cmd(self) -> List[str]: + """Generate configure command""" + # use relative path, so WASI tests can find lib prefix. + # pathlib.Path.relative_to() does not work here. + configure = os.path.relpath(CONFIGURE, self.builddir) + cmd = [configure, "-C"] + platform = self.host.platform + if platform.configure_wrapper: + cmd.insert(0, os.fspath(platform.configure_wrapper)) + + cmd.append(f"--host={self.host.value}") + cmd.append(f"--build={Host.build.value}") + + if self.target is not None: + assert self.host.is_emscripten + cmd.append(f"--with-emscripten-target={self.target.value}") + + if self.dynamic_linking is not None: + assert self.host.is_emscripten + opt = "enable" if self.dynamic_linking else "disable" + cmd.append(f"--{opt}-wasm-dynamic-linking") + + if self.pthreads is not None: + assert self.host.is_emscripten + opt = "enable" if self.pthreads else "disable" + cmd.append(f"--{opt}-wasm-pthreads") + + if self.host != Host.build: + cmd.append(f"--with-build-python={BUILD.python_cmd}") + + if platform.config_site is not None: + cmd.append(f"CONFIG_SITE={platform.config_site}") + + return cmd + + @property + def make_cmd(self) -> List[str]: + """Generate make command""" + cmd = ["make"] + platform = self.host.platform + if platform.make_wrapper: + cmd.insert(0, os.fspath(platform.make_wrapper)) + return cmd + + def getenv(self) -> dict: + """Generate environ dict for platform""" + env = os.environ.copy() + env.setdefault("MAKEFLAGS", f"-j{os.cpu_count()}") + platenv = self.host.platform.getenv(self) + for key, value in platenv.items(): + if value is None: + env.pop(key, None) + elif key == "PATH": + # list of path items, prefix with extra paths + new_path: List[pathlib.PurePath] = [] + new_path.extend(self.host.get_extra_paths()) + new_path.extend(value) + env[key] = os.pathsep.join(os.fspath(p) for p in new_path) + elif isinstance(value, str): + env[key] = value.format( + relbuilddir=self.builddir.relative_to(SRCDIR), + srcdir=SRCDIR, + version=PYTHON_VERSION, + ) + else: + env[key] = value + return env + + def _run_cmd( + self, + cmd: Iterable[str], + args: Iterable[str] = (), + cwd: Optional[pathlib.Path] = None, + ): + cmd = list(cmd) + cmd.extend(args) + if cwd is None: + cwd = self.builddir + logger.info('Running "%s" in "%s"', shlex.join(cmd), cwd) + return subprocess.check_call( + cmd, + cwd=os.fspath(cwd), + env=self.getenv(), + ) + + def _check_execute(self): + if self.is_browser: + raise ValueError(f"Cannot execute on {self.target}") + + def run_build(self, *args): + """Run configure (if necessary) and make""" + if not self.makefile.exists(): + logger.info("Makefile not found, running configure") + self.run_configure(*args) + self.run_make("all", *args) + + def run_configure(self, *args): + """Run configure script to generate Makefile""" + os.makedirs(self.builddir, exist_ok=True) + return self._run_cmd(self.configure_cmd, args) + + def run_make(self, *args): + """Run make (defaults to build all)""" + return self._run_cmd(self.make_cmd, args) + + def run_pythoninfo(self, *args): + """Run 'make pythoninfo'""" + self._check_execute() + return self.run_make("pythoninfo", *args) + + def run_test(self, target: str, testopts: Optional[str] = None): + """Run buildbottests""" + self._check_execute() + if testopts is None: + testopts = self.default_testopts + return self.run_make(target, f"TESTOPTS={testopts}") + + def run_py(self, *args): + """Run Python with hostrunner""" + self._check_execute() + self.run_make( + "--eval", f"run: all; $(HOSTRUNNER) ./$(PYTHON) {shlex.join(args)}", "run" + ) + + def run_browser(self, bind="127.0.0.1", port=8000): + """Run WASM webserver and open build in browser""" + relbuilddir = self.builddir.relative_to(SRCDIR) + url = f"http://{bind}:{port}/{relbuilddir}/python.html" + args = [ + sys.executable, + os.fspath(WASM_WEBSERVER), + "--bind", + bind, + "--port", + str(port), + ] + srv = subprocess.Popen(args, cwd=SRCDIR) + # wait for server + end = time.monotonic() + 3.0 + while time.monotonic() < end and srv.returncode is None: + try: + with socket.create_connection((bind, port), timeout=0.1) as s: + pass + except OSError: + time.sleep(0.01) + else: + break + + webbrowser.open(url) + + try: + srv.wait() + except KeyboardInterrupt: + pass + + def clean(self, all: bool = False): + """Clean build directory""" + if all: + if self.builddir.exists(): + shutil.rmtree(self.builddir) + elif self.makefile.exists(): + self.run_make("clean") + + def build_emports(self, force: bool = False): + """Pre-build emscripten ports.""" + platform = self.host.platform + if platform.ports is None or platform.cc is None: + raise ValueError("Need ports and CC command") + + embuilder_cmd = [os.fspath(platform.ports)] + embuilder_cmd.extend(self.host.embuilder_args) + if force: + embuilder_cmd.append("--force") + + ports_cmd = [os.fspath(platform.cc)] + ports_cmd.extend(self.host.emport_args) + if self.target: + ports_cmd.extend(self.target.emport_args) + + if self.dynamic_linking: + # Trigger PIC build. + ports_cmd.append("-sMAIN_MODULE") + embuilder_cmd.append("--pic") + + if self.pthreads: + # Trigger multi-threaded build. + ports_cmd.append("-sUSE_PTHREADS") + + # Pre-build libbz2, libsqlite3, libz, and some system libs. + ports_cmd.extend(["-sUSE_ZLIB", "-sUSE_BZIP2", "-sUSE_SQLITE3"]) + # Multi-threaded sqlite3 has different suffix + embuilder_cmd.extend( + ["build", "bzip2", "sqlite3-mt" if self.pthreads else "sqlite3", "zlib"] + ) + + self._run_cmd(embuilder_cmd, cwd=SRCDIR) + + with tempfile.TemporaryDirectory(suffix="-py-emport") as tmpdir: + tmppath = pathlib.Path(tmpdir) + main_c = tmppath / "main.c" + main_js = tmppath / "main.js" + with main_c.open("w") as f: + f.write("int main(void) { return 0; }\n") + args = [ + os.fspath(main_c), + "-o", + os.fspath(main_js), + ] + self._run_cmd(ports_cmd, args, cwd=tmppath) + + +# native build (build Python) +BUILD = BuildProfile( + "build", + support_level=SupportLevel.working, + host=Host.build, +) + +_profiles = [ + BUILD, + # wasm32-emscripten + BuildProfile( + "emscripten-browser", + support_level=SupportLevel.supported, + host=Host.wasm32_emscripten, + target=EmscriptenTarget.browser, + dynamic_linking=True, + ), + BuildProfile( + "emscripten-browser-debug", + support_level=SupportLevel.working, + host=Host.wasm32_emscripten, + target=EmscriptenTarget.browser_debug, + dynamic_linking=True, + ), + BuildProfile( + "emscripten-node-dl", + support_level=SupportLevel.supported, + host=Host.wasm32_emscripten, + target=EmscriptenTarget.node, + dynamic_linking=True, + ), + BuildProfile( + "emscripten-node-dl-debug", + support_level=SupportLevel.working, + host=Host.wasm32_emscripten, + target=EmscriptenTarget.node_debug, + dynamic_linking=True, + ), + BuildProfile( + "emscripten-node-pthreads", + support_level=SupportLevel.supported, + host=Host.wasm32_emscripten, + target=EmscriptenTarget.node, + pthreads=True, + ), + BuildProfile( + "emscripten-node-pthreads-debug", + support_level=SupportLevel.working, + host=Host.wasm32_emscripten, + target=EmscriptenTarget.node_debug, + pthreads=True, + ), + # Emscripten build with both pthreads and dynamic linking is crashing. + BuildProfile( + "emscripten-node-dl-pthreads-debug", + support_level=SupportLevel.broken, + host=Host.wasm32_emscripten, + target=EmscriptenTarget.node_debug, + dynamic_linking=True, + pthreads=True, + ), + # wasm64-emscripten (requires Emscripten >= 3.1.21) + BuildProfile( + "wasm64-emscripten-node-debug", + support_level=SupportLevel.experimental, + host=Host.wasm64_emscripten, + target=EmscriptenTarget.node_debug, + # MEMORY64 is not compatible with dynamic linking + dynamic_linking=False, + pthreads=False, + ), + # wasm32-wasi + BuildProfile( + "wasi", + support_level=SupportLevel.supported, + host=Host.wasm32_wasi, + ), + # no SDK available yet + # BuildProfile( + # "wasm64-wasi", + # support_level=SupportLevel.broken, + # host=Host.wasm64_wasi, + # ), +] + +PROFILES = {p.name: p for p in _profiles} + +parser = argparse.ArgumentParser( + "wasm_build.py", + description=__doc__, + formatter_class=argparse.RawTextHelpFormatter, +) + +parser.add_argument( + "--clean", + "-c", + help="Clean build directories first", + action="store_true", +) + +parser.add_argument( + "--verbose", + "-v", + help="Verbose logging", + action="store_true", +) + +parser.add_argument( + "--silent", + help="Run configure and make in silent mode", + action="store_true", +) + +parser.add_argument( + "--testopts", + help=( + "Additional test options for 'test' and 'hostrunnertest', e.g. " + "--testopts='-v test_os'." + ), + default=None, +) + +# Don't list broken and experimental variants in help +platforms_choices = list(p.name for p in _profiles) + ["cleanall"] +platforms_help = list(p.name for p in _profiles if p.support_level) + ["cleanall"] +parser.add_argument( + "platform", + metavar="PLATFORM", + help=f"Build platform: {', '.join(platforms_help)}", + choices=platforms_choices, +) + +ops = dict( + build="auto build (build 'build' Python, emports, configure, compile)", + configure="run ./configure", + compile="run 'make all'", + pythoninfo="run 'make pythoninfo'", + test="run 'make buildbottest TESTOPTS=...' (supports parallel tests)", + hostrunnertest="run 'make hostrunnertest TESTOPTS=...'", + repl="start interactive REPL / webserver + browser session", + clean="run 'make clean'", + cleanall="remove all build directories", + emports="build Emscripten port with embuilder (only Emscripten)", +) +ops_help = "\n".join(f"{op:16s} {help}" for op, help in ops.items()) +parser.add_argument( + "ops", + metavar="OP", + help=f"operation (default: build)\n\n{ops_help}", + choices=tuple(ops), + default="build", + nargs="*", +) + + +def main(): + args = parser.parse_args() + logging.basicConfig( + level=logging.INFO if args.verbose else logging.ERROR, + format="%(message)s", + ) + + if args.platform == "cleanall": + for builder in PROFILES.values(): + builder.clean(all=True) + parser.exit(0) + + # additional configure and make args + cm_args = ("--silent",) if args.silent else () + + # nargs=* with default quirk + if args.ops == "build": + args.ops = ["build"] + + builder = PROFILES[args.platform] + try: + builder.host.platform.check() + except ConditionError as e: + parser.error(str(e)) + + if args.clean: + builder.clean(all=False) + + # hack for WASI + if builder.host.is_wasi and not SETUP_LOCAL.exists(): + SETUP_LOCAL.touch() + + # auto-build + if "build" in args.ops: + # check and create build Python + if builder is not BUILD: + logger.info("Auto-building 'build' Python.") + try: + BUILD.host.platform.check() + except ConditionError as e: + parser.error(str(e)) + if args.clean: + BUILD.clean(all=False) + BUILD.run_build(*cm_args) + # build Emscripten ports with embuilder + if builder.host.is_emscripten and "emports" not in args.ops: + builder.build_emports() + + for op in args.ops: + logger.info("\n*** %s %s", args.platform, op) + if op == "build": + builder.run_build(*cm_args) + elif op == "configure": + builder.run_configure(*cm_args) + elif op == "compile": + builder.run_make("all", *cm_args) + elif op == "pythoninfo": + builder.run_pythoninfo(*cm_args) + elif op == "repl": + if builder.is_browser: + builder.run_browser() + else: + builder.run_py() + elif op == "test": + builder.run_test("buildbottest", testopts=args.testopts) + elif op == "hostrunnertest": + builder.run_test("hostrunnertest", testopts=args.testopts) + elif op == "clean": + builder.clean(all=False) + elif op == "cleanall": + builder.clean(all=True) + elif op == "emports": + builder.build_emports(force=args.clean) + else: + raise ValueError(op) + + print(builder.builddir) + parser.exit(0) + + +if __name__ == "__main__": + main() diff --git a/Tools/wasm/wasm_webserver.py b/Tools/wasm/wasm_webserver.py new file mode 100755 index 00000000000..186bd57fc20 --- /dev/null +++ b/Tools/wasm/wasm_webserver.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +import argparse +from http import server + +parser = argparse.ArgumentParser( + description="Start a local webserver with a Python terminal." +) +parser.add_argument( + "--port", type=int, default=8000, help="port for the http server to listen on" +) +parser.add_argument( + "--bind", type=str, default="127.0.0.1", help="Bind address (empty for all)" +) + + +class MyHTTPRequestHandler(server.SimpleHTTPRequestHandler): + extensions_map = server.SimpleHTTPRequestHandler.extensions_map.copy() + extensions_map.update( + { + ".wasm": "application/wasm", + } + ) + + def end_headers(self): + self.send_my_headers() + super().end_headers() + + def send_my_headers(self): + self.send_header("Cross-Origin-Opener-Policy", "same-origin") + self.send_header("Cross-Origin-Embedder-Policy", "require-corp") + + +def main(): + args = parser.parse_args() + if not args.bind: + args.bind = None + + server.test( + HandlerClass=MyHTTPRequestHandler, + protocol="HTTP/1.1", + port=args.port, + bind=args.bind, + ) + +if __name__ == "__main__": + main() diff --git a/config.guess b/config.guess index 1972fda8eb0..e81d3ae7c21 100755 --- a/config.guess +++ b/config.guess @@ -2,7 +2,9 @@ # Attempt to guess a canonical system name. # Copyright 1992-2021 Free Software Foundation, Inc. -timestamp='2021-01-25' +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2021-06-03' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -32,7 +34,15 @@ timestamp='2021-01-25' # Please send patches to . -me=$(echo "$0" | sed -e 's,.*/,,') +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + + +me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] @@ -84,6 +94,9 @@ if test $# != 0; then exit 1 fi +# Just in case it came from the environment. +GUESS= + # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a @@ -102,8 +115,8 @@ set_cc_for_build() { # prevent multiple calls if $tmp is already set test "$tmp" && return 0 : "${TMPDIR=/tmp}" - # shellcheck disable=SC2039 - { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } || + # shellcheck disable=SC2039,SC3028 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } @@ -112,7 +125,7 @@ set_cc_for_build() { ,,) echo "int x;" > "$dummy.c" for driver in cc gcc c89 c99 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then - CC_FOR_BUILD="$driver" + CC_FOR_BUILD=$driver break fi done @@ -131,12 +144,12 @@ if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi -UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown -UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown -UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown -UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -case "$UNAME_SYSTEM" in +case $UNAME_SYSTEM in Linux|GNU|GNU/*) LIBC=unknown @@ -157,7 +170,8 @@ Linux|GNU|GNU/*) #endif #endif EOF - eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')" + cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "$cc_set_libc" # Second heuristic to detect musl libc. if [ "$LIBC" = unknown ] && @@ -176,7 +190,7 @@ esac # Note: order is significant - the case branches are not exclusive. -case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in +case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, @@ -188,11 +202,11 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". - UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \ + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ - echo unknown)) - case "$UNAME_MACHINE_ARCH" in + echo unknown)` + case $UNAME_MACHINE_ARCH in aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; @@ -200,15 +214,15 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) - arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,') - endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p') - machine="${arch}${endian}"-unknown + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown ;; - *) machine="$UNAME_MACHINE_ARCH"-unknown ;; + *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. - case "$UNAME_MACHINE_ARCH" in + case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; @@ -229,10 +243,10 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in ;; esac # Determine ABI tags. - case "$UNAME_MACHINE_ARCH" in + case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr") + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release @@ -240,76 +254,82 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "$UNAME_VERSION" in + case $UNAME_VERSION in Debian*) release='-gnu' ;; *) - release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2) + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "$machine-${os}${release}${abi-}" - exit ;; + GUESS=$machine-${os}${release}${abi-} + ;; *:Bitrig:*:*) - UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//') - echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" - exit ;; + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE + ;; *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//') - echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" - exit ;; + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE + ;; + *:SecBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE + ;; *:LibertyBSD:*:*) - UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//') - echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" - exit ;; + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE + ;; *:MidnightBSD:*:*) - echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE + ;; *:ekkoBSD:*:*) - echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE + ;; *:SolidBSD:*:*) - echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE + ;; *:OS108:*:*) - echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE + ;; macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd"$UNAME_RELEASE" - exit ;; + GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE + ;; *:MirBSD:*:*) - echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE + ;; *:Sortix:*:*) - echo "$UNAME_MACHINE"-unknown-sortix - exit ;; + GUESS=$UNAME_MACHINE-unknown-sortix + ;; *:Twizzler:*:*) - echo "$UNAME_MACHINE"-unknown-twizzler - exit ;; + GUESS=$UNAME_MACHINE-unknown-twizzler + ;; *:Redox:*:*) - echo "$UNAME_MACHINE"-unknown-redox - exit ;; + GUESS=$UNAME_MACHINE-unknown-redox + ;; mips:OSF1:*.*) - echo mips-dec-osf1 - exit ;; + GUESS=mips-dec-osf1 + ;; alpha:OSF1:*:*) + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + trap '' 0 case $UNAME_RELEASE in *4.0) - UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}') + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) - UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}') + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1) - case "$ALPHA_CPU_TYPE" in + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case $ALPHA_CPU_TYPE in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") @@ -346,68 +366,69 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo "$UNAME_MACHINE"-dec-osf"$(echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)" - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; + OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + GUESS=$UNAME_MACHINE-dec-osf$OSF_REL + ;; Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; + GUESS=m68k-unknown-sysv4 + ;; *:[Aa]miga[Oo][Ss]:*:*) - echo "$UNAME_MACHINE"-unknown-amigaos - exit ;; + GUESS=$UNAME_MACHINE-unknown-amigaos + ;; *:[Mm]orph[Oo][Ss]:*:*) - echo "$UNAME_MACHINE"-unknown-morphos - exit ;; + GUESS=$UNAME_MACHINE-unknown-morphos + ;; *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; + GUESS=i370-ibm-openedition + ;; *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; + GUESS=s390-ibm-zvmoe + ;; *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; + GUESS=powerpc-ibm-os400 + ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix"$UNAME_RELEASE" - exit ;; + GUESS=arm-acorn-riscix$UNAME_RELEASE + ;; arm*:riscos:*:*|arm*:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; + GUESS=arm-unknown-riscos + ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; + GUESS=hppa1.1-hitachi-hiuxmpp + ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "$( (/bin/universe) 2>/dev/null)" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; + case `(/bin/universe) 2>/dev/null` in + att) GUESS=pyramid-pyramid-sysv3 ;; + *) GUESS=pyramid-pyramid-bsd ;; + esac + ;; NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; + GUESS=pyramid-pyramid-svr4 + ;; DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; + GUESS=sparc-icl-nx6 + ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case $(/usr/bin/uname -p) in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; + case `/usr/bin/uname -p` in + sparc) GUESS=sparc-icl-nx7 ;; + esac + ;; s390x:SunOS:*:*) - echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL + ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-hal-solaris2$SUN_REL + ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris2$SUN_REL + ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux"$UNAME_RELEASE" - exit ;; + GUESS=i386-pc-auroraux$UNAME_RELEASE + ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) set_cc_for_build SUN_ARCH=i386 @@ -422,41 +443,44 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in SUN_ARCH=x86_64 fi fi - echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$SUN_ARCH-pc-solaris2$SUN_REL + ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris3$SUN_REL + ;; sun4*:SunOS:*:*) - case "$(/usr/bin/arch -k)" in + case `/usr/bin/arch -k` in Series*|S4*) - UNAME_RELEASE=$(uname -v) + UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')" - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` + GUESS=sparc-sun-sunos$SUN_REL + ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos"$UNAME_RELEASE" - exit ;; + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; sun*:*:4.2BSD:*) - UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 - case "$(/bin/arch)" in + case `/bin/arch` in sun3) - echo m68k-sun-sunos"$UNAME_RELEASE" + GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) - echo sparc-sun-sunos"$UNAME_RELEASE" + GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac - exit ;; + ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos"$UNAME_RELEASE" - exit ;; + GUESS=sparc-auspex-sunos$UNAME_RELEASE + ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor @@ -466,41 +490,41 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint"$UNAME_RELEASE" - exit ;; + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint"$UNAME_RELEASE" - exit ;; + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint"$UNAME_RELEASE" - exit ;; + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint"$UNAME_RELEASE" - exit ;; + GUESS=m68k-milan-mint$UNAME_RELEASE + ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint"$UNAME_RELEASE" - exit ;; + GUESS=m68k-hades-mint$UNAME_RELEASE + ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint"$UNAME_RELEASE" - exit ;; + GUESS=m68k-unknown-mint$UNAME_RELEASE + ;; m68k:machten:*:*) - echo m68k-apple-machten"$UNAME_RELEASE" - exit ;; + GUESS=m68k-apple-machten$UNAME_RELEASE + ;; powerpc:machten:*:*) - echo powerpc-apple-machten"$UNAME_RELEASE" - exit ;; + GUESS=powerpc-apple-machten$UNAME_RELEASE + ;; RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; + GUESS=mips-dec-mach_bsd4.3 + ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix"$UNAME_RELEASE" - exit ;; + GUESS=mips-dec-ultrix$UNAME_RELEASE + ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix"$UNAME_RELEASE" - exit ;; + GUESS=vax-dec-ultrix$UNAME_RELEASE + ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix"$UNAME_RELEASE" - exit ;; + GUESS=clipper-intergraph-clix$UNAME_RELEASE + ;; mips:*:*:UMIPS | mips:*:*:RISCos) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" @@ -525,78 +549,79 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && - dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') && - SYSTEM_NAME=$("$dummy" "$dummyarg") && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos"$UNAME_RELEASE" - exit ;; + GUESS=mips-mips-riscos$UNAME_RELEASE + ;; Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; + GUESS=powerpc-motorola-powermax + ;; Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; + GUESS=powerpc-harris-powermax + ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; + GUESS=powerpc-harris-powermax + ;; Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; + GUESS=powerpc-harris-powerunix + ;; m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; + GUESS=m88k-harris-cxux7 + ;; m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; + GUESS=m88k-motorola-sysv4 + ;; m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; + GUESS=m88k-motorola-sysv3 + ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=$(/usr/bin/uname -p) + UNAME_PROCESSOR=`/usr/bin/uname -p` if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ test "$TARGET_BINARY_INTERFACE"x = x then - echo m88k-dg-dgux"$UNAME_RELEASE" + GUESS=m88k-dg-dgux$UNAME_RELEASE else - echo m88k-dg-dguxbcs"$UNAME_RELEASE" + GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else - echo i586-dg-dgux"$UNAME_RELEASE" + GUESS=i586-dg-dgux$UNAME_RELEASE fi - exit ;; + ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; + GUESS=m88k-dolphin-sysv3 + ;; M88*:*:R3*:*) # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; + GUESS=m88k-motorola-sysv3 + ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; + GUESS=m88k-tektronix-sysv3 + ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; + GUESS=m68k-tektronix-bsd + ;; *:IRIX*:*:*) - echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')" - exit ;; + IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` + GUESS=mips-sgi-irix$IRIX_REL + ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'$(uname -s)'" gives 'AIX ' + GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id + ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; + GUESS=i386-ibm-aix + ;; ia64:AIX:*:*) if test -x /usr/bin/oslevel ; then - IBM_REV=$(/usr/bin/oslevel) + IBM_REV=`/usr/bin/oslevel` else - IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi - echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" - exit ;; + GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV + ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then set_cc_for_build @@ -611,68 +636,68 @@ EOF exit(0); } EOF - if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then - echo "$SYSTEM_NAME" + GUESS=$SYSTEM_NAME else - echo rs6000-ibm-aix3.2.5 + GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 + GUESS=rs6000-ibm-aix3.2.4 else - echo rs6000-ibm-aix3.2 + GUESS=rs6000-ibm-aix3.2 fi - exit ;; + ;; *:AIX:*:[4567]) - IBM_CPU_ID=$(/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }') + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if test -x /usr/bin/lslpp ; then - IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc | - awk -F: '{ print $3 }' | sed s/[0-9]*$/0/) + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else - IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi - echo "$IBM_ARCH"-ibm-aix"$IBM_REV" - exit ;; + GUESS=$IBM_ARCH-ibm-aix$IBM_REV + ;; *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; + GUESS=rs6000-ibm-aix + ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) - echo romp-ibm-bsd4.4 - exit ;; + GUESS=romp-ibm-bsd4.4 + ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 + GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to + ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; + GUESS=rs6000-bull-bosx + ;; DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; + GUESS=m68k-bull-sysv3 + ;; 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; + GUESS=m68k-hp-bsd + ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; + GUESS=m68k-hp-bsd4.4 + ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') - case "$UNAME_MACHINE" in + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + case $UNAME_MACHINE in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if test -x /usr/bin/getconf; then - sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null) - sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null) - case "$sc_cpu_version" in + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case $sc_cpu_version in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "$sc_kernel_bits" in + case $sc_kernel_bits in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 @@ -714,7 +739,7 @@ EOF exit (0); } EOF - (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy") + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac @@ -739,12 +764,12 @@ EOF HP_ARCH=hppa64 fi fi - echo "$HP_ARCH"-hp-hpux"$HPUX_REV" - exit ;; + GUESS=$HP_ARCH-hp-hpux$HPUX_REV + ;; ia64:HP-UX:*:*) - HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') - echo ia64-hp-hpux"$HPUX_REV" - exit ;; + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + GUESS=ia64-hp-hpux$HPUX_REV + ;; 3050*:HI-UX:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" @@ -772,38 +797,38 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; + GUESS=unknown-hitachi-hiuxwe2 + ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) - echo hppa1.1-hp-bsd - exit ;; + GUESS=hppa1.1-hp-bsd + ;; 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; + GUESS=hppa1.0-hp-bsd + ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; + GUESS=hppa1.0-hp-mpeix + ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) - echo hppa1.1-hp-osf - exit ;; + GUESS=hppa1.1-hp-osf + ;; hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; + GUESS=hppa1.0-hp-osf + ;; i*86:OSF1:*:*) if test -x /usr/sbin/sysversion ; then - echo "$UNAME_MACHINE"-unknown-osf1mk + GUESS=$UNAME_MACHINE-unknown-osf1mk else - echo "$UNAME_MACHINE"-unknown-osf1 + GUESS=$UNAME_MACHINE-unknown-osf1 fi - exit ;; + ;; parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; + GUESS=hppa1.1-hp-lites + ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; + GUESS=c1-convex-bsd + ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd @@ -811,17 +836,18 @@ EOF fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; + GUESS=c34-convex-bsd + ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; + GUESS=c38-convex-bsd + ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; + GUESS=c4-convex-bsd + ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=ymp-cray-unicos$CRAY_REL + ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ @@ -829,114 +855,126 @@ EOF -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=t90-cray-unicos$CRAY_REL + ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=alphaev5-cray-unicosmk$CRAY_REL + ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=sv1-cray-unicos$CRAY_REL + ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=craynv-cray-unicosmp$CRAY_REL + ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz) - FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///') - FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/') - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///') - FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/') - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE + ;; sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi"$UNAME_RELEASE" - exit ;; + GUESS=sparc-unknown-bsdi$UNAME_RELEASE + ;; *:BSD/OS:*:*) - echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE + ;; arm:FreeBSD:*:*) - UNAME_PROCESSOR=$(uname -p) + UNAME_PROCESSOR=`uname -p` set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi else - echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf fi - exit ;; + ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=$(/usr/bin/uname -p) - case "$UNAME_PROCESSOR" in + UNAME_PROCESSOR=`/usr/bin/uname -p` + case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac - echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" - exit ;; + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL + ;; i*:CYGWIN*:*) - echo "$UNAME_MACHINE"-pc-cygwin - exit ;; + GUESS=$UNAME_MACHINE-pc-cygwin + ;; *:MINGW64*:*) - echo "$UNAME_MACHINE"-pc-mingw64 - exit ;; + GUESS=$UNAME_MACHINE-pc-mingw64 + ;; *:MINGW*:*) - echo "$UNAME_MACHINE"-pc-mingw32 - exit ;; + GUESS=$UNAME_MACHINE-pc-mingw32 + ;; *:MSYS*:*) - echo "$UNAME_MACHINE"-pc-msys - exit ;; + GUESS=$UNAME_MACHINE-pc-msys + ;; i*:PW*:*) - echo "$UNAME_MACHINE"-pc-pw32 - exit ;; + GUESS=$UNAME_MACHINE-pc-pw32 + ;; *:Interix*:*) - case "$UNAME_MACHINE" in + case $UNAME_MACHINE in x86) - echo i586-pc-interix"$UNAME_RELEASE" - exit ;; + GUESS=i586-pc-interix$UNAME_RELEASE + ;; authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix"$UNAME_RELEASE" - exit ;; + GUESS=x86_64-unknown-interix$UNAME_RELEASE + ;; IA64) - echo ia64-unknown-interix"$UNAME_RELEASE" - exit ;; + GUESS=ia64-unknown-interix$UNAME_RELEASE + ;; esac ;; i*:UWIN*:*) - echo "$UNAME_MACHINE"-pc-uwin - exit ;; + GUESS=$UNAME_MACHINE-pc-uwin + ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-pc-cygwin - exit ;; + GUESS=x86_64-pc-cygwin + ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=powerpcle-unknown-solaris2$SUN_REL + ;; *:GNU:*:*) # the GNU system - echo "$(echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,')-unknown-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')" - exit ;; + GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` + GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL + ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC" - exit ;; + GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC + ;; *:Minix:*:*) - echo "$UNAME_MACHINE"-unknown-minix - exit ;; + GUESS=$UNAME_MACHINE-unknown-minix + ;; aarch64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; alpha:Linux:*:*) - case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; @@ -947,63 +985,63 @@ EOF esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; - arc:Linux:*:* | arceb:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; arm*:Linux:*:*) set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi - exit ;; + ;; avr32*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; cris:Linux:*:*) - echo "$UNAME_MACHINE"-axis-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; crisv32:Linux:*:*) - echo "$UNAME_MACHINE"-axis-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; e2k:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; frv:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; hexagon:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; i*86:Linux:*:*) - echo "$UNAME_MACHINE"-pc-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-pc-linux-$LIBC + ;; ia64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; k1om:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; m32r*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; m68*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; mips:Linux:*:* | mips64:Linux:*:*) set_cc_for_build IS_GLIBC=0 @@ -1048,65 +1086,66 @@ EOF #endif #endif EOF - eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')" + cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` + eval "$cc_set_vars" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; openrisc*:Linux:*:*) - echo or1k-unknown-linux-"$LIBC" - exit ;; + GUESS=or1k-unknown-linux-$LIBC + ;; or32:Linux:*:* | or1k*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; padre:Linux:*:*) - echo sparc-unknown-linux-"$LIBC" - exit ;; + GUESS=sparc-unknown-linux-$LIBC + ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-"$LIBC" - exit ;; + GUESS=hppa64-unknown-linux-$LIBC + ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level - case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in - PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; - PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; - *) echo hppa-unknown-linux-"$LIBC" ;; + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; + PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; + *) GUESS=hppa-unknown-linux-$LIBC ;; esac - exit ;; + ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-"$LIBC" - exit ;; + GUESS=powerpc64-unknown-linux-$LIBC + ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-"$LIBC" - exit ;; + GUESS=powerpc-unknown-linux-$LIBC + ;; ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-"$LIBC" - exit ;; + GUESS=powerpc64le-unknown-linux-$LIBC + ;; ppcle:Linux:*:*) - echo powerpcle-unknown-linux-"$LIBC" - exit ;; + GUESS=powerpcle-unknown-linux-$LIBC + ;; riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; s390:Linux:*:* | s390x:Linux:*:*) - echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-ibm-linux-$LIBC + ;; sh64*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; sh*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; tile*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; vax:Linux:*:*) - echo "$UNAME_MACHINE"-dec-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-dec-linux-$LIBC + ;; x86_64:Linux:*:*) set_cc_for_build LIBCABI=$LIBC @@ -1115,71 +1154,71 @@ EOF (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_X32 >/dev/null then - LIBCABI="$LIBC"x32 + LIBCABI=${LIBC}x32 fi fi - echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI" - exit ;; + GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI + ;; xtensa*:Linux:*:*) - echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; + GUESS=i386-sequent-sysv4 + ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. - echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" - exit ;; + GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION + ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo "$UNAME_MACHINE"-pc-os2-emx - exit ;; + GUESS=$UNAME_MACHINE-pc-os2-emx + ;; i*86:XTS-300:*:STOP) - echo "$UNAME_MACHINE"-unknown-stop - exit ;; + GUESS=$UNAME_MACHINE-unknown-stop + ;; i*86:atheos:*:*) - echo "$UNAME_MACHINE"-unknown-atheos - exit ;; + GUESS=$UNAME_MACHINE-unknown-atheos + ;; i*86:syllable:*:*) - echo "$UNAME_MACHINE"-pc-syllable - exit ;; + GUESS=$UNAME_MACHINE-pc-syllable + ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos"$UNAME_RELEASE" - exit ;; + GUESS=i386-unknown-lynxos$UNAME_RELEASE + ;; i*86:*DOS:*:*) - echo "$UNAME_MACHINE"-pc-msdosdjgpp - exit ;; + GUESS=$UNAME_MACHINE-pc-msdosdjgpp + ;; i*86:*:4.*:*) - UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//') + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" + GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else - echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" + GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi - exit ;; + ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. - case $(/bin/uname -X | grep "^Machine") in + case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}" - exit ;; + GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then - UNAME_REL=$(sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //')) + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 @@ -1187,11 +1226,11 @@ EOF && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" + GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else - echo "$UNAME_MACHINE"-pc-sysv32 + GUESS=$UNAME_MACHINE-pc-sysv32 fi - exit ;; + ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about @@ -1199,37 +1238,37 @@ EOF # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; + GUESS=i586-pc-msdosdjgpp + ;; Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; + GUESS=i386-pc-mach3 + ;; paragon:*:*:*) - echo i860-intel-osf1 - exit ;; + GUESS=i860-intel-osf1 + ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 + GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 + GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi - exit ;; + ;; mini*:CTIX:SYS*5:*) # "miniframe" - echo m68010-convergent-sysv - exit ;; + GUESS=m68010-convergent-sysv + ;; mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; + GUESS=m68k-convergent-sysv + ;; M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; + GUESS=m68k-diab-dnix + ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ - && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid) + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ @@ -1240,7 +1279,7 @@ EOF NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ - && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid) + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ @@ -1248,118 +1287,118 @@ EOF /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos"$UNAME_RELEASE" - exit ;; + GUESS=m68k-unknown-lynxos$UNAME_RELEASE + ;; mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; + GUESS=m68k-atari-sysv4 + ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos"$UNAME_RELEASE" - exit ;; + GUESS=sparc-unknown-lynxos$UNAME_RELEASE + ;; rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos"$UNAME_RELEASE" - exit ;; + GUESS=rs6000-unknown-lynxos$UNAME_RELEASE + ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos"$UNAME_RELEASE" - exit ;; + GUESS=powerpc-unknown-lynxos$UNAME_RELEASE + ;; SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv"$UNAME_RELEASE" - exit ;; + GUESS=mips-dde-sysv$UNAME_RELEASE + ;; RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; + GUESS=mips-sni-sysv4 + ;; RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; + GUESS=mips-sni-sysv4 + ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=$( (uname -p) 2>/dev/null) - echo "$UNAME_MACHINE"-sni-sysv4 + UNAME_MACHINE=`(uname -p) 2>/dev/null` + GUESS=$UNAME_MACHINE-sni-sysv4 else - echo ns32k-sni-sysv + GUESS=ns32k-sni-sysv fi - exit ;; + ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says - echo i586-unisys-sysv4 - exit ;; + GUESS=i586-unisys-sysv4 + ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; + GUESS=hppa1.1-stratus-sysv4 + ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; + GUESS=i860-stratus-sysv4 + ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. - echo "$UNAME_MACHINE"-stratus-vos - exit ;; + GUESS=$UNAME_MACHINE-stratus-vos + ;; *:VOS:*:*) # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; + GUESS=hppa1.1-stratus-vos + ;; mc68*:A/UX:*:*) - echo m68k-apple-aux"$UNAME_RELEASE" - exit ;; + GUESS=m68k-apple-aux$UNAME_RELEASE + ;; news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; + GUESS=mips-sony-newsos6 + ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if test -d /usr/nec; then - echo mips-nec-sysv"$UNAME_RELEASE" + GUESS=mips-nec-sysv$UNAME_RELEASE else - echo mips-unknown-sysv"$UNAME_RELEASE" + GUESS=mips-unknown-sysv$UNAME_RELEASE fi - exit ;; + ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; + GUESS=powerpc-be-beos + ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; + GUESS=powerpc-apple-beos + ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; + GUESS=i586-pc-beos + ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; + GUESS=i586-pc-haiku + ;; x86_64:Haiku:*:*) - echo x86_64-unknown-haiku - exit ;; + GUESS=x86_64-unknown-haiku + ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux"$UNAME_RELEASE" - exit ;; + GUESS=sx4-nec-superux$UNAME_RELEASE + ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux"$UNAME_RELEASE" - exit ;; + GUESS=sx5-nec-superux$UNAME_RELEASE + ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux"$UNAME_RELEASE" - exit ;; + GUESS=sx6-nec-superux$UNAME_RELEASE + ;; SX-7:SUPER-UX:*:*) - echo sx7-nec-superux"$UNAME_RELEASE" - exit ;; + GUESS=sx7-nec-superux$UNAME_RELEASE + ;; SX-8:SUPER-UX:*:*) - echo sx8-nec-superux"$UNAME_RELEASE" - exit ;; + GUESS=sx8-nec-superux$UNAME_RELEASE + ;; SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux"$UNAME_RELEASE" - exit ;; + GUESS=sx8r-nec-superux$UNAME_RELEASE + ;; SX-ACE:SUPER-UX:*:*) - echo sxace-nec-superux"$UNAME_RELEASE" - exit ;; + GUESS=sxace-nec-superux$UNAME_RELEASE + ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody"$UNAME_RELEASE" - exit ;; + GUESS=powerpc-apple-rhapsody$UNAME_RELEASE + ;; *:Rhapsody:*:*) - echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE + ;; arm64:Darwin:*:*) - echo aarch64-apple-darwin"$UNAME_RELEASE" - exit ;; + GUESS=aarch64-apple-darwin$UNAME_RELEASE + ;; *:Darwin:*:*) - UNAME_PROCESSOR=$(uname -p) + UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac @@ -1393,109 +1432,116 @@ EOF # uname -m returns i386 or x86_64 UNAME_PROCESSOR=$UNAME_MACHINE fi - echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE + ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=$(uname -p) + UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE + ;; *:QNX:*:4*) - echo i386-pc-qnx - exit ;; + GUESS=i386-pc-qnx + ;; NEO-*:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk"$UNAME_RELEASE" - exit ;; + GUESS=neo-tandem-nsk$UNAME_RELEASE + ;; NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk"$UNAME_RELEASE" - exit ;; + GUESS=nse-tandem-nsk$UNAME_RELEASE + ;; NSR-*:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk"$UNAME_RELEASE" - exit ;; + GUESS=nsr-tandem-nsk$UNAME_RELEASE + ;; NSV-*:NONSTOP_KERNEL:*:*) - echo nsv-tandem-nsk"$UNAME_RELEASE" - exit ;; + GUESS=nsv-tandem-nsk$UNAME_RELEASE + ;; NSX-*:NONSTOP_KERNEL:*:*) - echo nsx-tandem-nsk"$UNAME_RELEASE" - exit ;; + GUESS=nsx-tandem-nsk$UNAME_RELEASE + ;; *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; + GUESS=mips-compaq-nonstopux + ;; BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; + GUESS=bs2000-siemens-sysv + ;; DS/*:UNIX_System_V:*:*) - echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE + ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - # shellcheck disable=SC2154 - if test "$cputype" = 386; then + if test "${cputype-}" = 386; then UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" + elif test "x${cputype-}" != x; then + UNAME_MACHINE=$cputype fi - echo "$UNAME_MACHINE"-unknown-plan9 - exit ;; + GUESS=$UNAME_MACHINE-unknown-plan9 + ;; *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; + GUESS=pdp10-unknown-tops10 + ;; *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; + GUESS=pdp10-unknown-tenex + ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; + GUESS=pdp10-dec-tops20 + ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; + GUESS=pdp10-xkl-tops20 + ;; *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; + GUESS=pdp10-unknown-tops20 + ;; *:ITS:*:*) - echo pdp10-unknown-its - exit ;; + GUESS=pdp10-unknown-its + ;; SEI:*:*:SEIUX) - echo mips-sei-seiux"$UNAME_RELEASE" - exit ;; + GUESS=mips-sei-seiux$UNAME_RELEASE + ;; *:DragonFly:*:*) - echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" - exit ;; + DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL + ;; *:*VMS:*:*) - UNAME_MACHINE=$( (uname -p) 2>/dev/null) - case "$UNAME_MACHINE" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case $UNAME_MACHINE in + A*) GUESS=alpha-dec-vms ;; + I*) GUESS=ia64-dec-vms ;; + V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; + GUESS=i386-pc-xenix + ;; i*86:skyos:*:*) - echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')" - exit ;; + SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` + GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL + ;; i*86:rdos:*:*) - echo "$UNAME_MACHINE"-pc-rdos - exit ;; + GUESS=$UNAME_MACHINE-pc-rdos + ;; *:AROS:*:*) - echo "$UNAME_MACHINE"-unknown-aros - exit ;; + GUESS=$UNAME_MACHINE-unknown-aros + ;; x86_64:VMkernel:*:*) - echo "$UNAME_MACHINE"-unknown-esx - exit ;; + GUESS=$UNAME_MACHINE-unknown-esx + ;; amd64:Isilon\ OneFS:*:*) - echo x86_64-unknown-onefs - exit ;; + GUESS=x86_64-unknown-onefs + ;; *:Unleashed:*:*) - echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" - exit ;; + GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE + ;; esac +# Do we have a guess based on uname results? +if test "x$GUESS" != x; then + echo "$GUESS" + exit +fi + # No uname command or uname output not recognized. set_cc_for_build cat > "$dummy.c" </dev/null); + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else @@ -1627,7 +1673,7 @@ main () } EOF -$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) && +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. @@ -1635,7 +1681,7 @@ test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } echo "$0: unable to guess system type" >&2 -case "$UNAME_MACHINE:$UNAME_SYSTEM" in +case $UNAME_MACHINE:$UNAME_SYSTEM in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 </dev/null || echo unknown) -uname -r = $( (uname -r) 2>/dev/null || echo unknown) -uname -s = $( (uname -s) 2>/dev/null || echo unknown) -uname -v = $( (uname -v) 2>/dev/null || echo unknown) +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` -/usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null) -/bin/uname -X = $( (/bin/uname -X) 2>/dev/null) +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` -hostinfo = $( (hostinfo) 2>/dev/null) -/bin/universe = $( (/bin/universe) 2>/dev/null) -/usr/bin/arch -k = $( (/usr/bin/arch -k) 2>/dev/null) -/bin/arch = $( (/bin/arch) 2>/dev/null) -/usr/bin/oslevel = $( (/usr/bin/oslevel) 2>/dev/null) -/usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null) +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" diff --git a/config.sub b/config.sub index 63c1f1c8b5e..d74fb6deac9 100755 --- a/config.sub +++ b/config.sub @@ -2,7 +2,9 @@ # Configuration validation subroutine script. # Copyright 1992-2021 Free Software Foundation, Inc. -timestamp='2021-01-08' +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2021-08-14' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -50,7 +52,14 @@ timestamp='2021-01-08' # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. -me=$(echo "$0" | sed -e 's,.*/,,') +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + +me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS @@ -112,9 +121,11 @@ esac # Split fields of configuration type # shellcheck disable=SC2162 +saved_IFS=$IFS IFS="-" read field1 field2 field3 field4 <&2 diff --git a/configure b/configure index 2cdc899082b..8b707cda621 100755 --- a/configure +++ b/configure @@ -1,8 +1,8 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for python 3.11. +# Generated by GNU Autoconf 2.69 for python 3.12. # -# Report bugs to . +# Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -267,10 +267,10 @@ fi $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and -$0: https://bugs.python.org/ about your system, including -$0: any error possibly output before this message. Then -$0: install a modern shell, or manually run the script -$0: under such a shell if you do have one." +$0: https://github.com/python/cpython/issues/ about your +$0: system, including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." fi exit 1 fi @@ -580,9 +580,9 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='python' PACKAGE_TARNAME='python' -PACKAGE_VERSION='3.11' -PACKAGE_STRING='python 3.11' -PACKAGE_BUGREPORT='https://bugs.python.org/' +PACKAGE_VERSION='3.12' +PACKAGE_STRING='python 3.12' +PACKAGE_BUGREPORT='https://github.com/python/cpython/issues/' PACKAGE_URL='' ac_unique_file="Include/object.h" @@ -624,10 +624,16 @@ ac_includes_default="\ ac_subst_vars='LTLIBOBJS MODULE_BLOCK +MODULE_XXLIMITED_35_FALSE +MODULE_XXLIMITED_35_TRUE +MODULE_XXLIMITED_FALSE +MODULE_XXLIMITED_TRUE MODULE__CTYPES_TEST_FALSE MODULE__CTYPES_TEST_TRUE MODULE__XXTESTFUZZ_FALSE MODULE__XXTESTFUZZ_TRUE +MODULE_XXSUBTYPE_FALSE +MODULE_XXSUBTYPE_TRUE MODULE__TESTMULTIPHASE_FALSE MODULE__TESTMULTIPHASE_TRUE MODULE__TESTIMPORTMULTIPLE_FALSE @@ -636,12 +642,46 @@ MODULE__TESTBUFFER_FALSE MODULE__TESTBUFFER_TRUE MODULE__TESTINTERNALCAPI_FALSE MODULE__TESTINTERNALCAPI_TRUE +MODULE__TESTCLINIC_FALSE +MODULE__TESTCLINIC_TRUE MODULE__TESTCAPI_FALSE MODULE__TESTCAPI_TRUE +MODULE__HASHLIB_FALSE +MODULE__HASHLIB_TRUE +MODULE__SSL_FALSE +MODULE__SSL_TRUE +MODULE__LZMA_FALSE +MODULE__LZMA_TRUE +MODULE__BZ2_FALSE +MODULE__BZ2_TRUE +MODULE_BINASCII_FALSE +MODULE_BINASCII_TRUE +MODULE_ZLIB_FALSE +MODULE_ZLIB_TRUE +MODULE__UUID_FALSE +MODULE__UUID_TRUE +MODULE__TKINTER_FALSE +MODULE__TKINTER_TRUE MODULE__SQLITE3_FALSE MODULE__SQLITE3_TRUE +MODULE_READLINE_FALSE +MODULE_READLINE_TRUE +MODULE_NIS_FALSE +MODULE_NIS_TRUE +MODULE__GDBM_FALSE +MODULE__GDBM_TRUE +MODULE__DBM_FALSE +MODULE__DBM_TRUE MODULE__DECIMAL_FALSE MODULE__DECIMAL_TRUE +MODULE__CURSES_PANEL_FALSE +MODULE__CURSES_PANEL_TRUE +MODULE__CURSES_FALSE +MODULE__CURSES_TRUE +MODULE__CTYPES_FALSE +MODULE__CTYPES_TRUE +MODULE__CRYPT_FALSE +MODULE__CRYPT_TRUE MODULE__BLAKE2_FALSE MODULE__BLAKE2_TRUE MODULE__SHA3_FALSE @@ -684,10 +724,18 @@ MODULE__SCPROXY_FALSE MODULE__SCPROXY_TRUE MODULE_RESOURCE_FALSE MODULE_RESOURCE_TRUE +MODULE_PWD_FALSE +MODULE_PWD_TRUE MODULE_OSSAUDIODEV_FALSE MODULE_OSSAUDIODEV_TRUE MODULE_GRP_FALSE MODULE_GRP_TRUE +MODULE__SOCKET_FALSE +MODULE__SOCKET_TRUE +MODULE_MMAP_FALSE +MODULE_MMAP_TRUE +MODULE_FCNTL_FALSE +MODULE_FCNTL_TRUE MODULE__DATETIME_FALSE MODULE__DATETIME_TRUE MODULE_MATH_FALSE @@ -696,14 +744,28 @@ MODULE_CMATH_FALSE MODULE_CMATH_TRUE MODULE__STATISTICS_FALSE MODULE__STATISTICS_TRUE +MODULE_AUDIOOP_FALSE +MODULE_AUDIOOP_TRUE +MODULE__POSIXSHMEM_FALSE +MODULE__POSIXSHMEM_TRUE +MODULE__MULTIPROCESSING_FALSE +MODULE__MULTIPROCESSING_TRUE MODULE__ZONEINFO_FALSE MODULE__ZONEINFO_TRUE +MODULE__XXSUBINTERPRETERS_FALSE +MODULE__XXSUBINTERPRETERS_TRUE MODULE__TYPING_FALSE MODULE__TYPING_TRUE +MODULE__STRUCT_FALSE +MODULE__STRUCT_TRUE +MODULE_SELECT_FALSE +MODULE_SELECT_TRUE MODULE__RANDOM_FALSE MODULE__RANDOM_TRUE MODULE__QUEUE_FALSE MODULE__QUEUE_TRUE +MODULE__POSIXSUBPROCESS_FALSE +MODULE__POSIXSUBPROCESS_TRUE MODULE__PICKLE_FALSE MODULE__PICKLE_TRUE MODULE__OPCODE_FALSE @@ -714,6 +776,8 @@ MODULE__JSON_FALSE MODULE__JSON_TRUE MODULE__HEAPQ_FALSE MODULE__HEAPQ_TRUE +MODULE__CSV_FALSE +MODULE__CSV_TRUE MODULE__CONTEXTVARS_FALSE MODULE__CONTEXTVARS_TRUE MODULE__BISECT_FALSE @@ -726,16 +790,24 @@ MODULE_TIME_FALSE MODULE_TIME_TRUE MODULE__IO_FALSE MODULE__IO_TRUE +MODULE_BUILDTYPE TEST_MODULES -LIBRARY_DEPS -STATIC_LIBPYTHON -OPENSSL_RPATH +LIBB2_LIBS +LIBB2_CFLAGS OPENSSL_LDFLAGS OPENSSL_LIBS OPENSSL_INCLUDES ENSUREPIP SRCDIRS THREADHEADERS +PANEL_LIBS +PANEL_CFLAGS +CURSES_LIBS +CURSES_CFLAGS +LIBEDIT_LIBS +LIBEDIT_CFLAGS +LIBREADLINE_LIBS +LIBREADLINE_CFLAGS WHEEL_PKG_DIR LIBPL PY_ENABLE_SHARED @@ -752,27 +824,46 @@ HAVE_GETHOSTBYNAME_R HAVE_GETHOSTBYNAME_R_3_ARG HAVE_GETHOSTBYNAME_R_5_ARG HAVE_GETHOSTBYNAME_R_6_ARG +LIBCRYPT_LIBS +LIBCRYPT_CFLAGS LIBOBJS +LIBLZMA_LIBS +LIBLZMA_CFLAGS +BZIP2_LIBS +BZIP2_CFLAGS +ZLIB_LIBS +ZLIB_CFLAGS TRUE MACHDEP_OBJS DYNLOADFILE DLINCLDIR +PLATFORM_OBJS +PLATFORM_HEADERS DTRACE_OBJS DTRACE_HEADERS DFLAGS DTRACE +GDBM_LIBS +GDBM_CFLAGS +X11_LIBS +X11_CFLAGS TCLTK_LIBS -TCLTK_INCLUDES +TCLTK_CFLAGS LIBSQLITE3_LIBS LIBSQLITE3_CFLAGS +LIBNSL_LIBS +LIBNSL_CFLAGS LIBMPDEC_INTERNAL -LIBMPDEC_LDFLAGS LIBMPDEC_CFLAGS -LIBFFI_INCLUDEDIR +MODULE__CTYPES_MALLOC_CLOSURE +LIBFFI_LIBS +LIBFFI_CFLAGS LIBEXPAT_INTERNAL -LIBEXPAT_LDFLAGS LIBEXPAT_CFLAGS TZPATH +LIBUUID_LIBS +LIBUUID_CFLAGS +PERF_TRAMPOLINE_OBJ SHLIBS CFLAGSFORSHARED LINKFORSHARED @@ -781,9 +872,12 @@ BLDSHARED LDCXXSHARED LDSHARED SHLIB_SUFFIX -LIBTOOL_CRUFT -OTHER_LIBTOOL_OPT +DSYMUTIL_PATH +DSYMUTIL UNIVERSAL_ARCH_FLAGS +WASM_STDLIB +WASM_ASSETS_DIR +LDFLAGS_NOLTO LDFLAGS_NODIST CFLAGS_NODIST BASECFLAGS @@ -796,6 +890,9 @@ LLVM_PROF_FILE LLVM_PROF_MERGER PGO_PROF_USE_FLAG PGO_PROF_GEN_FLAG +MERGE_FDATA +LLVM_BOLT +PREBOLT_RULE LLVM_AR_FOUND LLVM_AR PROFILE_TASK @@ -807,11 +904,15 @@ MKDIR_P INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM -ac_ct_READELF -READELF ARFLAGS ac_ct_AR AR +LINK_PYTHON_OBJS +LINK_PYTHON_DEPS +LIBRARY_DEPS +NODE +HOSTRUNNER +STATIC_LIBPYTHON GNULD EXPORTSFROM EXPORTSYMS @@ -831,7 +932,6 @@ MULTIARCH_CPPFLAGS PLATFORM_TRIPLET MULTIARCH ac_ct_CXX -MAINCC CXX EGREP SED @@ -844,6 +944,7 @@ CPPFLAGS LDFLAGS CFLAGS CC +HAS_XCRUN EXPORT_MACOSX_DEPLOYMENT_TARGET CONFIGURE_MACOSX_DEPLOYMENT_TARGET _PYTHON_HOST_PLATFORM @@ -870,8 +971,14 @@ PKG_CONFIG CONFIG_ARGS SOVERSION VERSION -PYTHON_FOR_BUILD PYTHON_FOR_REGEN +PYTHON_FOR_BUILD_DEPS +FREEZE_MODULE_DEPS +FREEZE_MODULE +FREEZE_MODULE_BOOTSTRAP_DEPS +FREEZE_MODULE_BOOTSTRAP +PYTHON_FOR_FREEZE +PYTHON_FOR_BUILD host_os host_vendor host_cpu @@ -927,20 +1034,27 @@ SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking +with_build_python with_pkg_config enable_universalsdk with_universal_archs with_framework_name enable_framework -with_cxx_main +with_emscripten_target +enable_wasm_dynamic_linking +enable_wasm_pthreads with_suffix enable_shared +with_static_libpython enable_profiling with_pydebug with_trace_refs +enable_pystats with_assertions enable_optimizations with_lto +enable_bolt +with_dsymutil with_address_sanitizer with_memory_sanitizer with_undefined_behavior_sanitizer @@ -948,12 +1062,9 @@ with_hash_algorithm with_tzpath with_libs with_system_expat -with_system_ffi with_system_libmpdec with_decimal_contextvar enable_loadable_sqlite_extensions -with_tcltk_includes -with_tcltk_libs with_dbmliborder enable_ipv6 with_doc_strings @@ -974,8 +1085,6 @@ with_openssl with_openssl_rpath with_ssl_default_suites with_builtin_hashlib_hashes -with_experimental_isolated_subinterpreters -with_static_libpython enable_test_modules ' ac_precious_vars='build_alias @@ -991,9 +1100,40 @@ LDFLAGS LIBS CPPFLAGS CPP +HOSTRUNNER PROFILE_TASK +LIBUUID_CFLAGS +LIBUUID_LIBS +LIBFFI_CFLAGS +LIBFFI_LIBS +LIBNSL_CFLAGS +LIBNSL_LIBS LIBSQLITE3_CFLAGS -LIBSQLITE3_LIBS' +LIBSQLITE3_LIBS +TCLTK_CFLAGS +TCLTK_LIBS +X11_CFLAGS +X11_LIBS +GDBM_CFLAGS +GDBM_LIBS +ZLIB_CFLAGS +ZLIB_LIBS +BZIP2_CFLAGS +BZIP2_LIBS +LIBLZMA_CFLAGS +LIBLZMA_LIBS +LIBCRYPT_CFLAGS +LIBCRYPT_LIBS +LIBREADLINE_CFLAGS +LIBREADLINE_LIBS +LIBEDIT_CFLAGS +LIBEDIT_LIBS +CURSES_CFLAGS +CURSES_LIBS +PANEL_CFLAGS +PANEL_LIBS +LIBB2_CFLAGS +LIBB2_LIBS' # Initialize some variables set by options. @@ -1544,7 +1684,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures python 3.11 to adapt to many kinds of systems. +\`configure' configures python 3.12 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1610,7 +1750,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of python 3.11:";; + short | recursive ) echo "Configuration of python 3.12:";; esac cat <<\_ACEOF @@ -1627,25 +1767,36 @@ Optional Features: Unix install. optional INSTALLDIR specifies the installation path. see Mac/README.rst (default is no) + --enable-wasm-dynamic-linking + Enable dynamic linking support for WebAssembly + (default is no) + --enable-wasm-pthreads Enable pthread emulation for WebAssembly (default is + no) --enable-shared enable building a shared Python library (default is no) --enable-profiling enable C-level code profiling with gprof (default is no) + --enable-pystats enable internal statistics gathering (default is no) --enable-optimizations enable expensive, stable optimizations (PGO, etc.) (default is no) + --enable-bolt enable usage of the llvm-bolt post-link optimizer + (default is no) --enable-loadable-sqlite-extensions - support loadable extensions in _sqlite module, see - Doc/library/sqlite3.rst (default is no) + support loadable extensions in the sqlite3 module, + see Doc/library/sqlite3.rst (default is no) --enable-ipv6 enable ipv6 (with ipv4) support, see Doc/library/socket.rst (default is yes if supported) --enable-big-digits[=15|30] use big digits (30 or 15 bits) for Python longs - (default is system-dependent)] + (default is 30)] --disable-test-modules don't build nor install test modules Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-build-python=python3.12 + path to build python binary for cross compiling + (default: _bootstrap_python or python3.12) --with-pkg-config=[yes|no|check] use pkg-config to detect build options (default is check) @@ -1660,10 +1811,13 @@ Optional Packages: specify the name for the python framework on macOS only valid when --enable-framework is set. see Mac/README.rst (default is 'Python') - --with-cxx-main[=COMPILER] - compile main() and link Python executable with C++ - compiler specified in COMPILER (default is $CXX) - --with-suffix=SUFFIX set executable suffix to SUFFIX (default is '.exe') + --with-emscripten-target=[browser|node] + Emscripten platform + --with-suffix=SUFFIX set executable suffix to SUFFIX (default is empty, + yes is mapped to '.exe') + --without-static-libpython + do not build libpythonMAJOR.MINOR.a and do not + install python.o (default is yes) --with-pydebug build with Py_DEBUG defined (default is no) --with-trace-refs enable tracing references for debugging purpose (default is no) @@ -1671,6 +1825,8 @@ Optional Packages: --with-lto=[full|thin|no|yes] enable Link-Time-Optimization in any build (default is no) + --with-dsymutil link debug information into final executable with + dsymutil in macOS (default is no) --with-address-sanitizer enable AddressSanitizer memory error detector, 'asan' (default is no) @@ -1688,18 +1844,11 @@ Optional Packages: --with-libs='lib1 ...' link against additional libs (default is no) --with-system-expat build pyexpat module using an installed expat library, see Doc/library/pyexpat.rst (default is no) - --with-system-ffi build _ctypes module using an installed ffi library, - see Doc/library/ctypes.rst (default is - system-dependent) --with-system-libmpdec build _decimal module using an installed libmpdec library, see Doc/library/decimal.rst (default is no) --with-decimal-contextvar build _decimal module using a coroutine-local rather than a thread-local context (default is yes) - --with-tcltk-includes='-I...' - override search for Tcl and Tk include files - --with-tcltk-libs='-L...' - override search for Tcl and Tk libs --with-dbmliborder=db1:db2:... override order to check db backends for dbm; a valid value is a colon separated string with the backend @@ -1721,8 +1870,8 @@ Optional Packages: --with-wheel-pkg-dir=PATH Directory of wheel packages used by ensurepip (default: none) - --with(out)-readline[=editline] - use Editline for backend or disable readline module + --with(out)-readline[=editline|readline|no] + use libedit for backend or disable readline module --with-computed-gotos enable computed gotos in evaluation loop (enabled by default on supported compilers) --with-ensurepip[=install|upgrade|no] @@ -1743,12 +1892,6 @@ Optional Packages: --with-builtin-hashlib-hashes=md5,sha1,sha256,sha512,sha3,blake2 builtin hash modules, md5, sha1, sha256, sha512, sha3 (with shake), blake2 - --with-experimental-isolated-subinterpreters - better isolate subinterpreters, experimental build - mode (default is no) - --without-static-libpython - do not build libpythonMAJOR.MINOR.a and do not - install python.o (default is yes) Some influential environment variables: PKG_CONFIG path to pkg-config utility @@ -1765,17 +1908,65 @@ Some influential environment variables: CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor + HOSTRUNNER Program to run CPython for the host platform PROFILE_TASK Python args for PGO generation task + LIBUUID_CFLAGS + C compiler flags for LIBUUID, overriding pkg-config + LIBUUID_LIBS + linker flags for LIBUUID, overriding pkg-config + LIBFFI_CFLAGS + C compiler flags for LIBFFI, overriding pkg-config + LIBFFI_LIBS linker flags for LIBFFI, overriding pkg-config + LIBNSL_CFLAGS + C compiler flags for LIBNSL, overriding pkg-config + LIBNSL_LIBS linker flags for LIBNSL, overriding pkg-config LIBSQLITE3_CFLAGS C compiler flags for LIBSQLITE3, overriding pkg-config LIBSQLITE3_LIBS linker flags for LIBSQLITE3, overriding pkg-config + TCLTK_CFLAGS + C compiler flags for TCLTK, overriding pkg-config + TCLTK_LIBS linker flags for TCLTK, overriding pkg-config + X11_CFLAGS C compiler flags for X11, overriding pkg-config + X11_LIBS linker flags for X11, overriding pkg-config + GDBM_CFLAGS C compiler flags for gdbm + GDBM_LIBS additional linker flags for gdbm + ZLIB_CFLAGS C compiler flags for ZLIB, overriding pkg-config + ZLIB_LIBS linker flags for ZLIB, overriding pkg-config + BZIP2_CFLAGS + C compiler flags for BZIP2, overriding pkg-config + BZIP2_LIBS linker flags for BZIP2, overriding pkg-config + LIBLZMA_CFLAGS + C compiler flags for LIBLZMA, overriding pkg-config + LIBLZMA_LIBS + linker flags for LIBLZMA, overriding pkg-config + LIBCRYPT_CFLAGS + C compiler flags for LIBCRYPT, overriding pkg-config + LIBCRYPT_LIBS + linker flags for LIBCRYPT, overriding pkg-config + LIBREADLINE_CFLAGS + C compiler flags for LIBREADLINE, overriding pkg-config + LIBREADLINE_LIBS + linker flags for LIBREADLINE, overriding pkg-config + LIBEDIT_CFLAGS + C compiler flags for LIBEDIT, overriding pkg-config + LIBEDIT_LIBS + linker flags for LIBEDIT, overriding pkg-config + CURSES_CFLAGS + C compiler flags for CURSES, overriding pkg-config + CURSES_LIBS linker flags for CURSES, overriding pkg-config + PANEL_CFLAGS + C compiler flags for PANEL, overriding pkg-config + PANEL_LIBS linker flags for PANEL, overriding pkg-config + LIBB2_CFLAGS + C compiler flags for LIBB2, overriding pkg-config + LIBB2_LIBS linker flags for LIBB2, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to . +Report bugs to . _ACEOF ac_status=$? fi @@ -1838,7 +2029,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -python configure 3.11 +python configure 3.12 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1997,9 +2188,9 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## --------------------------------------- ## -## Report this to https://bugs.python.org/ ## -## --------------------------------------- ##" +( $as_echo "## -------------------------------------------------------- ## +## Report this to https://github.com/python/cpython/issues/ ## +## -------------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac @@ -2547,7 +2738,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by python $as_me 3.11, which was +It was created by python $as_me 3.12, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2899,6 +3090,12 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + if test "$srcdir" != . -a "$srcdir" != "$(pwd)"; then # If we're building out-of-tree, we need to make sure the following # resources get picked up before their $srcdir counterparts. @@ -3079,10 +3276,86 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac +if test "x$cross_compiling" = xmaybe; then : + as_fn_error $? "Cross compiling required --host=HOST-TUPLE and --build=ARCH" "$LINENO" 5 + +fi + # pybuilddir.txt will be created by --generate-posix-vars in the Makefile rm -f pybuilddir.txt -for ac_prog in python$PACKAGE_VERSION python3 python + +# Check whether --with-build-python was given. +if test "${with_build_python+set}" = set; then : + withval=$with_build_python; + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-build-python" >&5 +$as_echo_n "checking for --with-build-python... " >&6; } + + if test "x$with_build_python" = xyes; then : + with_build_python=python$PACKAGE_VERSION +fi + if test "x$with_build_python" = xno; then : + as_fn_error $? "invalid --with-build-python option: expected path or \"yes\", not \"no\"" "$LINENO" 5 +fi + + if ! $(command -v "$with_build_python" >/dev/null 2>&1); then + as_fn_error $? "invalid or missing build python binary \"$with_build_python\"" "$LINENO" 5 + fi + build_python_ver=$($with_build_python -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')") + if test "$build_python_ver" != "$PACKAGE_VERSION"; then + as_fn_error $? "\"$with_build_python\" has incompatible version $build_python_ver (expected: $PACKAGE_VERSION)" "$LINENO" 5 + fi + ac_cv_prog_PYTHON_FOR_REGEN=$with_build_python + PYTHON_FOR_FREEZE="$with_build_python" + PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`:)$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) '$with_build_python + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_build_python" >&5 +$as_echo "$with_build_python" >&6; } + +else + + if test "x$cross_compiling" = xyes; then : + as_fn_error $? "Cross compiling requires --with-build-python" "$LINENO" 5 + +fi + PYTHON_FOR_BUILD='./$(BUILDPYTHON) -E' + PYTHON_FOR_FREEZE="./_bootstrap_python" + + +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python interpreter freezing" >&5 +$as_echo_n "checking for Python interpreter freezing... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_FOR_FREEZE" >&5 +$as_echo "$PYTHON_FOR_FREEZE" >&6; } + + +if test "x$cross_compiling" = xyes; then : + + FREEZE_MODULE_BOOTSTRAP='$(PYTHON_FOR_FREEZE) $(srcdir)/Programs/_freeze_module.py' + FREEZE_MODULE_BOOTSTRAP_DEPS='$(srcdir)/Programs/_freeze_module.py' + FREEZE_MODULE='$(FREEZE_MODULE_BOOTSTRAP)' + FREEZE_MODULE_DEPS='$(FREEZE_MODULE_BOOTSTRAP_DEPS)' + PYTHON_FOR_BUILD_DEPS='' + +else + + FREEZE_MODULE_BOOTSTRAP='./Programs/_freeze_module' + FREEZE_MODULE_BOOTSTRAP_DEPS="Programs/_freeze_module" + FREEZE_MODULE='$(PYTHON_FOR_FREEZE) $(srcdir)/Programs/_freeze_module.py' + FREEZE_MODULE_DEPS="_bootstrap_python \$(srcdir)/Programs/_freeze_module.py" + PYTHON_FOR_BUILD_DEPS='$(BUILDPYTHON)' + + +fi + + + + + + +for ac_prog in python$PACKAGE_VERSION python3.11 python3.10 python3.9 python3.8 python3.7 python3.6 python3 python do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -3127,32 +3400,17 @@ test -n "$PYTHON_FOR_REGEN" || PYTHON_FOR_REGEN="python3" -if test "$cross_compiling" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for python interpreter for cross build" >&5 -$as_echo_n "checking for python interpreter for cross build... " >&6; } - if test -z "$PYTHON_FOR_BUILD"; then - for interp in python$PACKAGE_VERSION python3 python; do - which $interp >/dev/null 2>&1 || continue - if $interp -c "import sys;sys.exit(not '.'.join(str(n) for n in sys.version_info[:2]) == '$PACKAGE_VERSION')"; then - break - fi - interp= - done - if test x$interp = x; then - as_fn_error $? "python$PACKAGE_VERSION interpreter not found" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $interp" >&5 -$as_echo "$interp" >&6; } - PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`:)$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) '$interp - fi -elif test "$cross_compiling" = maybe; then - as_fn_error $? "Cross compiling required --host=HOST-TUPLE and --build=ARCH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Python for regen version" >&5 +$as_echo_n "checking Python for regen version... " >&6; } +if command -v "$PYTHON_FOR_REGEN" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $($PYTHON_FOR_REGEN -V 2>/dev/null)" >&5 +$as_echo "$($PYTHON_FOR_REGEN -V 2>/dev/null)" >&6; } else - PYTHON_FOR_BUILD='./$(BUILDPYTHON) -E' + { $as_echo "$as_me:${as_lineno-$LINENO}: result: missing" >&5 +$as_echo "missing" >&6; } fi - if test "$prefix" != "/"; then prefix=`echo "$prefix" | sed -e 's/\/$//g'` fi @@ -3167,7 +3425,7 @@ rm confdefs.h mv confdefs.h.new confdefs.h -VERSION=3.11 +VERSION=3.12 # Version number of Python's own shared library file. @@ -3613,6 +3871,12 @@ then *-*-vxworks*) ac_sys_system=VxWorks ;; + *-*-emscripten) + ac_sys_system=Emscripten + ;; + *-*-wasi) + ac_sys_system=WASI + ;; *) # for now, limit cross builds to known configurations MACHDEP="unknown" @@ -3663,6 +3927,9 @@ if test "$cross_compiling" = yes; then *-*-vxworks*) _host_cpu=$host_cpu ;; + wasm32-*-* | wasm64-*-*) + _host_cpu=$host_cpu + ;; *) # for now, limit cross builds to known configurations MACHDEP="unknown" @@ -3819,8 +4086,68 @@ if test -z "$CFLAGS"; then CFLAGS= fi +case $host in #( + wasm64-*-emscripten) : + + as_fn_append CFLAGS " -sMEMORY64=1" + as_fn_append LDFLAGS " -sMEMORY64=1" + ;; #( + *) : + ;; +esac + if test "$ac_sys_system" = "Darwin" then + # Extract the first word of "xcrun", so it can be a program name with args. +set dummy xcrun; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_HAS_XCRUN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$HAS_XCRUN"; then + ac_cv_prog_HAS_XCRUN="$HAS_XCRUN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_HAS_XCRUN="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_HAS_XCRUN" && ac_cv_prog_HAS_XCRUN="missing" +fi +fi +HAS_XCRUN=$ac_cv_prog_HAS_XCRUN +if test -n "$HAS_XCRUN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAS_XCRUN" >&5 +$as_echo "$HAS_XCRUN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking macOS SDKROOT" >&5 +$as_echo_n "checking macOS SDKROOT... " >&6; } + if test -z "$SDKROOT"; then + if test "$HAS_XCRUN" = "yes"; then + SDKROOT=$(xcrun --show-sdk-path) + else + SDKROOT="/" + fi + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SDKROOT" >&5 +$as_echo "$SDKROOT" >&6; } + # Compiler selection on MacOSX is more complicated than # AC_PROG_CC can handle, see Mac/README for more # information @@ -5004,6 +5331,39 @@ $as_echo "$ac_cv_path_EGREP" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CC compiler name" >&5 +$as_echo_n "checking for CC compiler name... " >&6; } +if ${ac_cv_cc_name+:} false; then : + $as_echo_n "(cached) " >&6 +else + +cat > conftest.c <conftest.out 2>/dev/null; then + ac_cv_cc_name=`grep -v '^#' conftest.out | grep -v '^ *$' | tr -d ' '` +else + ac_cv_cc_name="unknown" +fi +rm -f conftest.c conftest.out + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cc_name" >&5 +$as_echo "$ac_cv_cc_name" >&6; } + # checks for UNIX variants that set C preprocessor variables # may set _GNU_SOURCE, __EXTENSIONS__, _POSIX_PTHREAD_SEMANTICS, # _POSIX_SOURCE, _POSIX_1_SOURCE, and more @@ -5202,35 +5562,6 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-cxx-main=" >&5 -$as_echo_n "checking for --with-cxx-main=... " >&6; } - -# Check whether --with-cxx_main was given. -if test "${with_cxx_main+set}" = set; then : - withval=$with_cxx_main; - - case $withval in - no) with_cxx_main=no - MAINCC='$(CC)';; - yes) with_cxx_main=yes - MAINCC='$(CXX)';; - *) with_cxx_main=yes - MAINCC=$withval - if test -z "$CXX" - then - CXX=$withval - fi;; - esac -else - - with_cxx_main=no - MAINCC='$(CC)' - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_cxx_main" >&5 -$as_echo "$with_cxx_main" >&6; } - preset_cxx="$CXX" if test -z "$CXX" then @@ -5757,7 +6088,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the platform triplet based on compiler characteristics" >&5 $as_echo_n "checking for the platform triplet based on compiler characteristics... " >&6; } -cat >> conftest.c < conftest.c <> conftest.c <conftest.out 2>/dev/null; then PLATFORM_TRIPLET=`grep -v '^#' conftest.out | grep -v '^ *$' | tr -d ' '` + case "$build_os" in + linux-musl*) + PLATFORM_TRIPLET=`echo "$PLATFORM_TRIPLET" | sed 's/linux-gnu/linux-musl/'` + ;; + esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PLATFORM_TRIPLET" >&5 $as_echo "$PLATFORM_TRIPLET" >&6; } else @@ -5913,10 +6265,20 @@ $as_echo "none" >&6; } fi rm -f conftest.c conftest.out -if test x$PLATFORM_TRIPLET != xdarwin; then - MULTIARCH=$($CC --print-multiarch 2>/dev/null) -fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for multiarch" >&5 +$as_echo_n "checking for multiarch... " >&6; } +case $ac_sys_system in #( + Darwin*) : + MULTIARCH="" ;; #( + FreeBSD*) : + MULTIARCH="" ;; #( + *) : + MULTIARCH=$($CC --print-multiarch 2>/dev/null) + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MULTIARCH" >&5 +$as_echo "$MULTIARCH" >&6; } if test x$PLATFORM_TRIPLET != x && test x$MULTIARCH != x; then if test x$PLATFORM_TRIPLET != x$MULTIARCH; then @@ -5926,11 +6288,76 @@ elif test x$PLATFORM_TRIPLET != x && test x$MULTIARCH = x; then MULTIARCH=$PLATFORM_TRIPLET fi + if test x$MULTIARCH != x; then MULTIARCH_CPPFLAGS="-DMULTIARCH=\\\"$MULTIARCH\\\"" fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PEP 11 support tier" >&5 +$as_echo_n "checking for PEP 11 support tier... " >&6; } +case $host/$ac_cv_cc_name in #( + x86_64-*-linux-gnu/gcc) : + PY_SUPPORT_TIER=1 ;; #( + x86_64-apple-darwin*/clang) : + PY_SUPPORT_TIER=1 ;; #( + i686-pc-windows-msvc/msvc) : + PY_SUPPORT_TIER=1 ;; #( + x86_64-pc-windows-msvc/msvc) : + PY_SUPPORT_TIER=1 ;; #( + + aarch64-apple-darwin*/clang) : + PY_SUPPORT_TIER=2 ;; #( + aarch64-*-linux-gnu/gcc) : + PY_SUPPORT_TIER=2 ;; #( + aarch64-*-linux-gnu/clang) : + PY_SUPPORT_TIER=2 ;; #( + powerpc64le-*-linux-gnu/gcc) : + PY_SUPPORT_TIER=2 ;; #( + x86_64-*-linux-gnu/clang) : + PY_SUPPORT_TIER=2 ;; #( + + aarch64-pc-windows-msvc/msvc) : + PY_SUPPORT_TIER=3 ;; #( + armv7l-*-linux-gnueabihf/gcc) : + PY_SUPPORT_TIER=3 ;; #( + powerpc64le-*-linux-gnu/clang) : + PY_SUPPORT_TIER=3 ;; #( + s390x-*-linux-gnu/gcc) : + PY_SUPPORT_TIER=3 ;; #( + wasm32-unknown-emscripten/clang) : + PY_SUPPORT_TIER=3 ;; #( + wasm32-unknown-wasi/clang) : + PY_SUPPORT_TIER=3 ;; #( + x86_64-*-freebsd*/clang) : + PY_SUPPORT_TIER=3 ;; #( + *) : + PY_SUPPORT_TIER=0 + ;; +esac + +case $PY_SUPPORT_TIER in #( + 1) : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $host/$ac_cv_cc_name has tier 1 (supported)" >&5 +$as_echo "$host/$ac_cv_cc_name has tier 1 (supported)" >&6; } ;; #( + 2) : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $host/$ac_cv_cc_name has tier 2 (supported)" >&5 +$as_echo "$host/$ac_cv_cc_name has tier 2 (supported)" >&6; } ;; #( + 3) : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $host/$ac_cv_cc_name has tier 3 (partially supported)" >&5 +$as_echo "$host/$ac_cv_cc_name has tier 3 (partially supported)" >&6; } ;; #( + *) : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $host/$ac_cv_cc_name is not supported" >&5 +$as_echo "$as_me: WARNING: $host/$ac_cv_cc_name is not supported" >&2;} + ;; +esac + + +cat >>confdefs.h <<_ACEOF +#define PY_SUPPORT_TIER $PY_SUPPORT_TIER +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wl,--no-as-needed" >&5 $as_echo_n "checking for -Wl,--no-as-needed... " >&6; } if ${ac_cv_wl_no_as_needed+:} false; then : @@ -5938,7 +6365,7 @@ if ${ac_cv_wl_no_as_needed+:} false; then : else save_LDFLAGS="$LDFLAGS" - as_fn_append LDFLAGS -Wl,--no-as-needed + as_fn_append LDFLAGS " -Wl,--no-as-needed" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -5968,7 +6395,7 @@ $as_echo "$ac_cv_wl_no_as_needed" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Android API level" >&5 $as_echo_n "checking for the Android API level... " >&6; } -cat >> conftest.c < conftest.c <conftest.out 2>/dev/null; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ANDROID_API_LEVEL" >&5 $as_echo "$ANDROID_API_LEVEL" >&6; } if test -z "$ANDROID_API_LEVEL"; then - echo 'Fatal: you must define __ANDROID_API__' - exit 1 + as_fn_error $? "Fatal: you must define __ANDROID_API__" "$LINENO" 5 fi cat >>confdefs.h <<_ACEOF @@ -6007,24 +6433,133 @@ fi rm -f conftest.c conftest.out # Check for unsupported systems -case $ac_sys_system/$ac_sys_release in -atheos*|Linux*/1*) - echo This system \($ac_sys_system/$ac_sys_release\) is no longer supported. - echo See README for details. - exit 1;; +case $ac_sys_system/$ac_sys_release in #( + atheos*|Linux*/1*) : + + as_fn_error $? "This system \($ac_sys_system/$ac_sys_release\) is no longer supported. See README for details." "$LINENO" 5 + + ;; #( + *) : + ;; esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-emscripten-target" >&5 +$as_echo_n "checking for --with-emscripten-target... " >&6; } + +# Check whether --with-emscripten-target was given. +if test "${with_emscripten_target+set}" = set; then : + withval=$with_emscripten_target; + if test "x$ac_sys_system" = xEmscripten; then : + + case $with_emscripten_target in #( + browser) : + ac_sys_emscripten_target=browser ;; #( + node) : + ac_sys_emscripten_target=node ;; #( + browser-debug) : + ac_sys_emscripten_target=browser-debug ;; #( + node-debug) : + ac_sys_emscripten_target=node-debug ;; #( + *) : + as_fn_error $? "Invalid argument: --with-emscripten-target=browser|node" "$LINENO" 5 + ;; +esac + +else + + as_fn_error $? "--with-emscripten-target only applies to Emscripten" "$LINENO" 5 + +fi + +else + + if test "x$ac_sys_system" = xEmscripten; then : + ac_sys_emscripten_target=browser +fi + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_sys_emscripten_target" >&5 +$as_echo "$ac_sys_emscripten_target" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-wasm-dynamic-linking" >&5 +$as_echo_n "checking for --enable-wasm-dynamic-linking... " >&6; } +# Check whether --enable-wasm-dynamic-linking was given. +if test "${enable_wasm_dynamic_linking+set}" = set; then : + enableval=$enable_wasm_dynamic_linking; + case $ac_sys_system in #( + Emscripten) : + ;; #( + WASI) : + as_fn_error $? "WASI dynamic linking is not implemented yet." "$LINENO" 5 ;; #( + *) : + as_fn_error $? "--enable-wasm-dynamic-linking only applies to Emscripten and WASI" "$LINENO" 5 + ;; +esac + +else + + enable_wasm_dynamic_linking=missing + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_wasm_dynamic_linking" >&5 +$as_echo "$enable_wasm_dynamic_linking" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-wasm-pthreads" >&5 +$as_echo_n "checking for --enable-wasm-pthreads... " >&6; } +# Check whether --enable-wasm-pthreads was given. +if test "${enable_wasm_pthreads+set}" = set; then : + enableval=$enable_wasm_pthreads; + case $ac_sys_system in #( + Emscripten) : + ;; #( + WASI) : + as_fn_error $? "WASI threading is not implemented yet." "$LINENO" 5 ;; #( + *) : + as_fn_error $? "--enable-wasm-pthreads only applies to Emscripten and WASI" "$LINENO" 5 + ;; +esac + +else + + enable_wasm_pthreads=missing + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_wasm_pthreads" >&5 +$as_echo "$enable_wasm_pthreads" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-suffix" >&5 $as_echo_n "checking for --with-suffix... " >&6; } # Check whether --with-suffix was given. if test "${with_suffix+set}" = set; then : withval=$with_suffix; - case $withval in - no) EXEEXT=;; - yes) EXEEXT=.exe;; - *) EXEEXT=$withval;; - esac + case $with_suffix in #( + no) : + EXEEXT= ;; #( + yes) : + EXEEXT=.exe ;; #( + *) : + EXEEXT=$with_suffix + ;; +esac + +else + + case $ac_sys_system/$ac_sys_emscripten_target in #( + Emscripten/browser*) : + EXEEXT=.js ;; #( + Emscripten/node*) : + EXEEXT=.js ;; #( + WASI/*) : + EXEEXT=.wasm ;; #( + *) : + EXEEXT= + ;; +esac + fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $EXEEXT" >&5 @@ -6039,7 +6574,7 @@ if test ! -d CaseSensitiveTestDir; then mkdir CaseSensitiveTestDir fi -if test -d casesensitivetestdir +if test -d casesensitivetestdir && test -z "$EXEEXT" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -6109,7 +6644,7 @@ LDVERSION="$VERSION" $as_echo_n "checking LINKCC... " >&6; } if test -z "$LINKCC" then - LINKCC='$(PURIFY) $(MAINCC)' + LINKCC='$(PURIFY) $(CC)' case $ac_sys_system in QNX*) # qcc must be used because the other compilers do not @@ -6141,7 +6676,7 @@ $as_echo "$EXPORTSYMS" >&6; } # make sure we default having it set to "no": this is used by # distutils.unixccompiler to know if it should add --enable-new-dtags # to linker command lines, and failing to detect GNU ld simply results -# in the same bahaviour as before. +# in the same behaviour as before. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } @@ -6178,6 +6713,30 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } +# --with-static-libpython +STATIC_LIBPYTHON=1 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-static-libpython" >&5 +$as_echo_n "checking for --with-static-libpython... " >&6; } + +# Check whether --with-static-libpython was given. +if test "${with_static_libpython+set}" = set; then : + withval=$with_static_libpython; +if test "$withval" = no +then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; }; + STATIC_LIBPYTHON=0 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; +fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-profiling" >&5 $as_echo_n "checking for --enable-profiling... " >&6; } # Check whether --enable-profiling was given. @@ -6190,7 +6749,7 @@ if test "x$enable_profiling" = xyes; then CC="$CC -pg" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int main() { return 0; } +int main(void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : @@ -6297,9 +6856,216 @@ if test "$cross_compiling" = yes; then RUNSHARED= fi + +if test -z "$HOSTRUNNER" +then + case $ac_sys_system/$ac_sys_emscripten_target in #( + Emscripten/node*) : + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}node", so it can be a program name with args. +set dummy ${ac_tool_prefix}node; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_NODE+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $NODE in + [\\/]* | ?:[\\/]*) + ac_cv_path_NODE="$NODE" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_NODE="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +NODE=$ac_cv_path_NODE +if test -n "$NODE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NODE" >&5 +$as_echo "$NODE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_NODE"; then + ac_pt_NODE=$NODE + # Extract the first word of "node", so it can be a program name with args. +set dummy node; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_NODE+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_NODE in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_NODE="$ac_pt_NODE" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_NODE="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_NODE=$ac_cv_path_ac_pt_NODE +if test -n "$ac_pt_NODE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_NODE" >&5 +$as_echo "$ac_pt_NODE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_NODE" = x; then + NODE="node" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NODE=$ac_pt_NODE + fi +else + NODE="$ac_cv_path_NODE" +fi + + HOSTRUNNER="$NODE" + # bigint for ctypes c_longlong, c_longdouble + # no longer available in Node 16 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for node --experimental-wasm-bigint" >&5 +$as_echo_n "checking for node --experimental-wasm-bigint... " >&6; } +if ${ac_cv_tool_node_wasm_bigint+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if $NODE -v --experimental-wasm-bigint > /dev/null 2>&1; then + ac_cv_tool_node_wasm_bigint=yes + else + ac_cv_tool_node_wasm_bigint=no + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_tool_node_wasm_bigint" >&5 +$as_echo "$ac_cv_tool_node_wasm_bigint" >&6; } + if test "x$ac_cv_tool_node_wasm_bigint" = xyes; then : + + as_fn_append HOSTRUNNER " --experimental-wasm-bigint" + +fi + + if test "x$enable_wasm_pthreads" = xyes; then : + + as_fn_append HOSTRUNNER " --experimental-wasm-threads" + # no longer available in Node 16 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for node --experimental-wasm-bulk-memory" >&5 +$as_echo_n "checking for node --experimental-wasm-bulk-memory... " >&6; } +if ${ac_cv_tool_node_wasm_bulk_memory+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if $NODE -v --experimental-wasm-bulk-memory > /dev/null 2>&1; then + ac_cv_tool_node_wasm_bulk_memory=yes + else + ac_cv_tool_node_wasm_bulk_memory=no + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_tool_node_wasm_bulk_memory" >&5 +$as_echo "$ac_cv_tool_node_wasm_bulk_memory" >&6; } + if test "x$ac_cv_tool_node_wasm_bulk_memory" = xyes; then : + + as_fn_append HOSTRUNNER " --experimental-wasm-bulk-memory" + +fi + +fi + + if test "x$host_cpu" = xwasm64; then : + as_fn_append HOSTRUNNER " --experimental-wasm-memory64" +fi + ;; #( + WASI/*) : + HOSTRUNNER='wasmtime run --env PYTHONPATH=/$(shell realpath --relative-to $(abs_srcdir) $(abs_builddir))/$(shell cat pybuilddir.txt):/Lib --mapdir /::$(srcdir) --' ;; #( + *) : + HOSTRUNNER='' + ;; +esac +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking HOSTRUNNER" >&5 +$as_echo_n "checking HOSTRUNNER... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HOSTRUNNER" >&5 +$as_echo "$HOSTRUNNER" >&6; } + +if test -n "$HOSTRUNNER"; then + PYTHON_FOR_BUILD="_PYTHON_HOSTRUNNER='$HOSTRUNNER' $PYTHON_FOR_BUILD" +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDLIBRARY" >&5 $as_echo "$LDLIBRARY" >&6; } +# LIBRARY_DEPS, LINK_PYTHON_OBJS and LINK_PYTHON_DEPS variable +case $ac_sys_system/$ac_sys_emscripten_target in #( + Emscripten/browser*) : + LIBRARY_DEPS='$(PY3LIBRARY) $(WASM_STDLIB) python.html python.worker.js' ;; #( + *) : + LIBRARY_DEPS='$(PY3LIBRARY) $(EXPORTSYMS)' + ;; +esac +LINK_PYTHON_DEPS='$(LIBRARY_DEPS)' +if test "$PY_ENABLE_SHARED" = 1 || test "$enable_framework" ; then + LIBRARY_DEPS="\$(LDLIBRARY) $LIBRARY_DEPS" + if test "$STATIC_LIBPYTHON" = 1; then + LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS" + fi + # Link Python program to the shared library + LINK_PYTHON_OBJS='$(BLDLIBRARY)' +else + if test "$STATIC_LIBPYTHON" = 0; then + # Build Python needs object files but don't need to build + # Python static library + LINK_PYTHON_DEPS="$LIBRARY_DEPS \$(LIBRARY_OBJS)" + fi + LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS" + # Link Python program to object files + LINK_PYTHON_OBJS='$(LIBRARY_OBJS)' +fi + + + + +# ar program if test -n "$ac_tool_prefix"; then for ac_prog in ar aal @@ -6409,116 +7175,6 @@ then ARFLAGS="rcs" fi -if test -n "$ac_tool_prefix"; then - for ac_prog in readelf - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_READELF+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$READELF"; then - ac_cv_prog_READELF="$READELF" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_READELF="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -READELF=$ac_cv_prog_READELF -if test -n "$READELF"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $READELF" >&5 -$as_echo "$READELF" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$READELF" && break - done -fi -if test -z "$READELF"; then - ac_ct_READELF=$READELF - for ac_prog in readelf -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_READELF+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_READELF"; then - ac_cv_prog_ac_ct_READELF="$ac_ct_READELF" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_READELF="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_READELF=$ac_cv_prog_ac_ct_READELF -if test -n "$ac_ct_READELF"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_READELF" >&5 -$as_echo "$ac_ct_READELF" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_READELF" && break -done - - if test "x$ac_ct_READELF" = x; then - READELF=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - READELF=$ac_ct_READELF - fi -fi - -if test "$cross_compiling" = yes; then - case "$READELF" in - readelf|:) - as_fn_error $? "readelf for the host is required for cross builds" "$LINENO" 5 - ;; - esac -fi - - - case $MACHDEP in hp*|HP*) # install -d does not work on HP-UX @@ -6721,6 +7377,29 @@ then $as_echo "#define Py_TRACE_REFS 1" >>confdefs.h +fi + + +# Check for --enable-pystats +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-pystats" >&5 +$as_echo_n "checking for --enable-pystats... " >&6; } +# Check whether --enable-pystats was given. +if test "${enable_pystats+set}" = set; then : + enableval=$enable_pystats; +else + enable_pystats=no + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_pystats" >&5 +$as_echo "$enable_pystats" >&6; } + +if test "x$enable_pystats" = xyes; then : + + +$as_echo "#define Py_STATS 1" >>confdefs.h + + fi # Check for --with-assertions. @@ -6774,6 +7453,7 @@ else $as_echo "no" >&6; } fi + if test "$Py_OPT" = 'true' ; then # Intentionally not forcing Py_LTO='true' here. Too many toolchains do not # compile working code using it and both test_distutils and test_gdb are @@ -6824,8 +7504,10 @@ fi ;; esac - - +elif test "$ac_sys_system" = "Emscripten" -o "$ac_sys_system" = "WASI"; then + DEF_MAKE_ALL_RULE="build_wasm" + REQUIRE_PGO="no" + DEF_MAKE_RULE="all" else DEF_MAKE_ALL_RULE="build_all" REQUIRE_PGO="no" @@ -6842,7 +7524,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PROFILE_TASK" >&5 $as_echo "$PROFILE_TASK" >&6; } -# Make llvm-relatec checks work on systems where llvm tools are not installed with their +# Make llvm-related checks work on systems where llvm tools are not installed with their # normal names in the default $PATH (ie: Ubuntu). They exist under the # non-suffixed name in their versioned llvm directory. @@ -6907,6 +7589,42 @@ fi if test "$Py_LTO" = 'true' ; then case $CC in *clang*) + LDFLAGS_NOLTO="-fno-lto" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -flto=thin" >&5 +$as_echo_n "checking whether C compiler accepts -flto=thin... " >&6; } +if ${ax_cv_check_cflags___flto_thin+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -flto=thin" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ax_cv_check_cflags___flto_thin=yes +else + ax_cv_check_cflags___flto_thin=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___flto_thin" >&5 +$as_echo "$ax_cv_check_cflags___flto_thin" >&6; } +if test "x$ax_cv_check_cflags___flto_thin" = xyes; then : + LDFLAGS_NOLTO="-flto=thin" +else + LDFLAGS_NOLTO="-flto" +fi + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}llvm-ar", so it can be a program name with args. @@ -7038,31 +7756,115 @@ $as_echo "$as_me: llvm-ar found via xcrun: ${LLVM_AR}" >&6;} # Any changes made here should be reflected in the GCC+Darwin case below if test $Py_LTO_POLICY = default then - LTOFLAGS="-flto -Wl,-export_dynamic" - LTOCFLAGS="-flto" + # Check that ThinLTO is accepted. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -flto=thin" >&5 +$as_echo_n "checking whether C compiler accepts -flto=thin... " >&6; } +if ${ax_cv_check_cflags___flto_thin+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -flto=thin" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ax_cv_check_cflags___flto_thin=yes +else + ax_cv_check_cflags___flto_thin=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___flto_thin" >&5 +$as_echo "$ax_cv_check_cflags___flto_thin" >&6; } +if test "x$ax_cv_check_cflags___flto_thin" = xyes; then : + + LTOFLAGS="-flto=thin -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" + LTOCFLAGS="-flto=thin" + +else + + LTOFLAGS="-flto -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" + LTOCFLAGS="-flto" + + +fi + else - LTOFLAGS="-flto=${Py_LTO_POLICY} -Wl,-export_dynamic" + LTOFLAGS="-flto=${Py_LTO_POLICY} -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" LTOCFLAGS="-flto=${Py_LTO_POLICY}" fi ;; *) if test $Py_LTO_POLICY = default then - LTOFLAGS="-flto" + # Check that ThinLTO is accepted + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -flto=thin" >&5 +$as_echo_n "checking whether C compiler accepts -flto=thin... " >&6; } +if ${ax_cv_check_cflags___flto_thin+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -flto=thin" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ax_cv_check_cflags___flto_thin=yes +else + ax_cv_check_cflags___flto_thin=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___flto_thin" >&5 +$as_echo "$ax_cv_check_cflags___flto_thin" >&6; } +if test "x$ax_cv_check_cflags___flto_thin" = xyes; then : + LTOFLAGS="-flto=thin" +else + LTOFLAGS="-flto" +fi + else LTOFLAGS="-flto=${Py_LTO_POLICY}" fi ;; esac ;; + *emcc*) + if test "$Py_LTO_POLICY" != "default"; then + as_fn_error $? "emcc supports only default lto." "$LINENO" 5 + fi + LTOFLAGS="-flto" + LTOCFLAGS="-flto" + ;; *gcc*) if test $Py_LTO_POLICY = thin then as_fn_error $? "thin lto is not supported under gcc compiler." "$LINENO" 5 fi + LDFLAGS_NOLTO="-fno-lto" case $ac_sys_system in Darwin*) - LTOFLAGS="-flto -Wl,-export_dynamic" + LTOFLAGS="-flto -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" LTOCFLAGS="-flto" ;; *) @@ -7083,6 +7885,297 @@ $as_echo "$as_me: llvm-ar found via xcrun: ${LLVM_AR}" >&6;} LDFLAGS_NODIST="$LDFLAGS_NODIST $LTOFLAGS" fi +# Enable bolt flags +Py_BOLT='false' +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-bolt" >&5 +$as_echo_n "checking for --enable-bolt... " >&6; } +# Check whether --enable-bolt was given. +if test "${enable_bolt+set}" = set; then : + enableval=$enable_bolt; +if test "$enableval" != no +then + Py_BOLT='true' + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; +else + Py_BOLT='false' + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; }; +fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +if test "$Py_BOLT" = 'true' ; then + PREBOLT_RULE="${DEF_MAKE_ALL_RULE}" + DEF_MAKE_ALL_RULE="bolt-opt" + DEF_MAKE_RULE="build_all" + + # -fno-reorder-blocks-and-partition is required for bolt to work. + # Possibly GCC only. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fno-reorder-blocks-and-partition" >&5 +$as_echo_n "checking whether C compiler accepts -fno-reorder-blocks-and-partition... " >&6; } +if ${ax_cv_check_cflags___fno_reorder_blocks_and_partition+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -fno-reorder-blocks-and-partition" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ax_cv_check_cflags___fno_reorder_blocks_and_partition=yes +else + ax_cv_check_cflags___fno_reorder_blocks_and_partition=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fno_reorder_blocks_and_partition" >&5 +$as_echo "$ax_cv_check_cflags___fno_reorder_blocks_and_partition" >&6; } +if test "x$ax_cv_check_cflags___fno_reorder_blocks_and_partition" = xyes; then : + + CFLAGS_NODIST="$CFLAGS_NODIST -fno-reorder-blocks-and-partition" + +else + : +fi + + + # These flags are required for bolt to work: + LDFLAGS_NODIST="$LDFLAGS_NODIST -Wl,--emit-relocs" + + # These flags are required to get good performance from bolt: + CFLAGS_NODIST="$CFLAGS_NODIST -fno-pie" + # We want to add these no-pie flags to linking executables but not shared libraries: + LINKCC="$LINKCC -fno-pie -no-pie" + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}llvm-bolt", so it can be a program name with args. +set dummy ${ac_tool_prefix}llvm-bolt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_LLVM_BOLT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $LLVM_BOLT in + [\\/]* | ?:[\\/]*) + ac_cv_path_LLVM_BOLT="$LLVM_BOLT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_LLVM_BOLT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +LLVM_BOLT=$ac_cv_path_LLVM_BOLT +if test -n "$LLVM_BOLT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LLVM_BOLT" >&5 +$as_echo "$LLVM_BOLT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_LLVM_BOLT"; then + ac_pt_LLVM_BOLT=$LLVM_BOLT + # Extract the first word of "llvm-bolt", so it can be a program name with args. +set dummy llvm-bolt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_LLVM_BOLT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_LLVM_BOLT in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_LLVM_BOLT="$ac_pt_LLVM_BOLT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_LLVM_BOLT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_LLVM_BOLT=$ac_cv_path_ac_pt_LLVM_BOLT +if test -n "$ac_pt_LLVM_BOLT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LLVM_BOLT" >&5 +$as_echo "$ac_pt_LLVM_BOLT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_LLVM_BOLT" = x; then + LLVM_BOLT="''" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LLVM_BOLT=$ac_pt_LLVM_BOLT + fi +else + LLVM_BOLT="$ac_cv_path_LLVM_BOLT" +fi + + if test -n "${LLVM_BOLT}" -a -x "${LLVM_BOLT}" + then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"Found llvm-bolt\"" >&5 +$as_echo "\"Found llvm-bolt\"" >&6; } + else + as_fn_error $? "llvm-bolt is required for a --enable-bolt build but could not be found." "$LINENO" 5 + fi + + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}merge-fdata", so it can be a program name with args. +set dummy ${ac_tool_prefix}merge-fdata; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MERGE_FDATA+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MERGE_FDATA in + [\\/]* | ?:[\\/]*) + ac_cv_path_MERGE_FDATA="$MERGE_FDATA" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_MERGE_FDATA="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +MERGE_FDATA=$ac_cv_path_MERGE_FDATA +if test -n "$MERGE_FDATA"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MERGE_FDATA" >&5 +$as_echo "$MERGE_FDATA" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_MERGE_FDATA"; then + ac_pt_MERGE_FDATA=$MERGE_FDATA + # Extract the first word of "merge-fdata", so it can be a program name with args. +set dummy merge-fdata; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_MERGE_FDATA+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_MERGE_FDATA in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_MERGE_FDATA="$ac_pt_MERGE_FDATA" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_MERGE_FDATA="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_MERGE_FDATA=$ac_cv_path_ac_pt_MERGE_FDATA +if test -n "$ac_pt_MERGE_FDATA"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_MERGE_FDATA" >&5 +$as_echo "$ac_pt_MERGE_FDATA" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_MERGE_FDATA" = x; then + MERGE_FDATA="''" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MERGE_FDATA=$ac_pt_MERGE_FDATA + fi +else + MERGE_FDATA="$ac_cv_path_MERGE_FDATA" +fi + + if test -n "${MERGE_FDATA}" -a -x "${MERGE_FDATA}" + then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"Found merge-fdata\"" >&5 +$as_echo "\"Found merge-fdata\"" >&6; } + else + as_fn_error $? "merge-fdata is required for a --enable-bolt build but could not be found." "$LINENO" 5 + fi +fi + # Enable PGO flags. @@ -7283,6 +8376,50 @@ case $CC in fi esac +# Check if CC supports -Og optimization level +save_CFLAGS=$CFLAGS +CFLAGS="-Og" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Og optimization level" >&5 +$as_echo_n "checking if $CC supports -Og optimization level... " >&6; } +if ${ac_cv_cc_supports_og+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + ac_cv_cc_supports_og=yes + +else + + ac_cv_cc_supports_og=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cc_supports_og" >&5 +$as_echo "$ac_cv_cc_supports_og" >&6; } +CFLAGS=$save_CFLAGS + +# Optimization messes up debuggers, so turn it off for +# debug builds. +PYDEBUG_CFLAGS="-O0" +if test "x$ac_cv_cc_supports_og" = xyes; then : + PYDEBUG_CFLAGS="-Og" +fi + # tweak OPT based on compiler and platform, only if the user didn't set # it on the command line @@ -7308,13 +8445,7 @@ then case $ac_cv_prog_cc_g in yes) if test "$Py_DEBUG" = 'true' ; then - # Optimization messes up debuggers, so turn it off for - # debug builds. - if "$CC" -v --help 2>/dev/null |grep -- -Og > /dev/null; then - OPT="-g -Og -Wall" - else - OPT="-g -O0 -Wall" - fi + OPT="-g $PYDEBUG_CFLAGS -Wall" else OPT="-g $WRAP -O3 -Wall" fi @@ -7336,6 +8467,108 @@ then esac fi +# WASM flags +case $ac_sys_system in #( + Emscripten) : + + if test "x$Py_DEBUG" = xyes; then : + wasm_debug=yes +else + wasm_debug=no +fi + + as_fn_append LDFLAGS_NODIST " -sALLOW_MEMORY_GROWTH -sTOTAL_MEMORY=20971520" + + as_fn_append LDFLAGS_NODIST " -sWASM_BIGINT" + + as_fn_append LDFLAGS_NODIST " -sFORCE_FILESYSTEM -lidbfs.js -lnodefs.js -lproxyfs.js -lworkerfs.js" + + if test "x$enable_wasm_dynamic_linking" = xyes; then : + + as_fn_append LINKFORSHARED " -sMAIN_MODULE" + +fi + + if test "x$enable_wasm_pthreads" = xyes; then : + + as_fn_append CFLAGS_NODIST " -pthread" + as_fn_append LDFLAGS_NODIST " -sUSE_PTHREADS" + as_fn_append LINKFORSHARED " -sPROXY_TO_PTHREAD" + +fi + + case $ac_sys_emscripten_target in #( + browser*) : + + if test "x$ac_sys_emscripten_target" = xbrowser-debug; then : + wasm_debug=yes +fi + as_fn_append LINKFORSHARED " --preload-file=\$(WASM_ASSETS_DIR)" + WASM_ASSETS_DIR=".\$(prefix)" + WASM_STDLIB="\$(WASM_ASSETS_DIR)/local/lib/python\$(VERSION)/os.py" + WASM_LINKFORSHARED_DEBUG="-gsource-map --emit-symbol-map" + ;; #( + node*) : + + if test "x$ac_sys_emscripten_target" = xnode-debug; then : + wasm_debug=yes +fi + as_fn_append LDFLAGS_NODIST " -sALLOW_MEMORY_GROWTH -sNODERAWFS" + as_fn_append LINKFORSHARED " -sEXIT_RUNTIME" + WASM_LINKFORSHARED_DEBUG="-gseparate-dwarf --emit-symbol-map" + + ;; #( + *) : + ;; +esac + + if test "x$wasm_debug" = xyes; then : + + as_fn_append LDFLAGS_NODIST " -sASSERTIONS" + as_fn_append LINKFORSHARED " $WASM_LINKFORSHARED_DEBUG" + +else + + as_fn_append LINKFORSHARED " -O2 -g0" + +fi + ;; #( + WASI) : + + +$as_echo "#define _WASI_EMULATED_SIGNAL 1" >>confdefs.h + + +$as_echo "#define _WASI_EMULATED_GETPID 1" >>confdefs.h + + +$as_echo "#define _WASI_EMULATED_PROCESS_CLOCKS 1" >>confdefs.h + + LIBS="$LIBS -lwasi-emulated-signal -lwasi-emulated-getpid -lwasi-emulated-process-clocks" + echo "#define _WASI_EMULATED_SIGNAL 1" >> confdefs.h + + as_fn_append LDFLAGS_NODIST " -z stack-size=524288 -Wl,--stack-first -Wl,--initial-memory=10485760" + + ;; #( + *) : + ;; +esac + +case $enable_wasm_dynamic_linking in #( + yes) : + ac_cv_func_dlopen=yes ;; #( + no) : + ac_cv_func_dlopen=no ;; #( + missing) : + + ;; #( + *) : + ;; +esac + + + + @@ -7349,7 +8582,7 @@ UNIVERSAL_ARCH_FLAGS= # tweak BASECFLAGS based on compiler and platform case $GCC in yes) - CFLAGS_NODIST="$CFLAGS_NODIST -std=c99" + CFLAGS_NODIST="$CFLAGS_NODIST -std=c11" @@ -7544,6 +8777,44 @@ fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can disable $CC int-conversion warning" >&5 +$as_echo_n "checking if we can disable $CC int-conversion warning... " >&6; } +if ${ac_cv_disable_int_conversion_warning+:} false; then : + $as_echo_n "(cached) " >&6 +else + + py_cflags=$CFLAGS + as_fn_append CFLAGS "-Wint-conversion -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_disable_int_conversion_warning=yes +else + ac_cv_disable_int_conversion_warning=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$py_cflags + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_disable_int_conversion_warning" >&5 +$as_echo "$ac_cv_disable_int_conversion_warning" >&6; } + + + if test "x$ac_cv_disable_int_conversion" = xyes; then : + CFLAGS_NODIST="$CFLAGS_NODIST -Wno-int-conversion" +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can disable $CC missing-field-initializers warning" >&5 $as_echo_n "checking if we can disable $CC missing-field-initializers warning... " >&6; } if ${ac_cv_disable_missing_field_initializers_warning+:} false; then : @@ -8017,7 +9288,7 @@ else void* routine(void* p){return NULL;} -int main(){ +int main(void){ pthread_t p; if(pthread_create(&p,NULL,routine,NULL)!=0) return 1; @@ -8072,7 +9343,7 @@ else void* routine(void* p){return NULL;} -int main(){ +int main(void){ pthread_t p; if(pthread_create(&p,NULL,routine,NULL)!=0) return 1; @@ -8121,7 +9392,7 @@ else void* routine(void* p){return NULL;} -int main(){ +int main(void){ pthread_t p; if(pthread_create(&p,NULL,routine,NULL)!=0) return 1; @@ -8170,7 +9441,7 @@ else void* routine(void* p){return NULL;} -int main(){ +int main(void){ pthread_t p; if(pthread_create(&p,NULL,routine,NULL)!=0) return 1; @@ -8196,12 +9467,14 @@ fi # If we have set a CC compiler flag for thread support then # check if it works for CXX, too. -ac_cv_cxx_thread=no if test ! -z "$CXX" then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX also accepts flags for thread support" >&5 $as_echo_n "checking whether $CXX also accepts flags for thread support... " >&6; } -ac_save_cxx="$CXX" +if ${ac_cv_cxx_thread+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx="$CXX" if test "$ac_cv_kpthread" = "yes" then @@ -8215,6 +9488,8 @@ elif test "$ac_cv_pthread" = "yes" then CXX="$CXX -pthread" ac_cv_cxx_thread=yes +else + ac_cv_cxx_thread=no fi if test $ac_cv_cxx_thread = yes @@ -8230,10 +9505,13 @@ then fi rm -fr conftest* fi +CXX="$ac_save_cxx" +fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_thread" >&5 $as_echo "$ac_cv_cxx_thread" >&6; } +else + ac_cv_cxx_thread=no fi -CXX="$ac_save_cxx" @@ -8241,21 +9519,19 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h # checks for header files -for ac_header in asm/types.h crypt.h conio.h direct.h dlfcn.h errno.h \ -fcntl.h grp.h \ -ieeefp.h io.h langinfo.h libintl.h process.h pthread.h \ -sched.h shadow.h signal.h stropts.h termios.h \ -utime.h \ -poll.h sys/devpoll.h sys/epoll.h sys/poll.h \ -sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h sys/ioctl.h \ -sys/kern_control.h sys/loadavg.h sys/lock.h sys/mkdev.h sys/modem.h \ -sys/param.h sys/random.h sys/select.h sys/sendfile.h sys/socket.h sys/statvfs.h \ -sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ -sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ -libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ -linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \ -sys/endian.h sys/sysmacros.h linux/memfd.h linux/wait.h sys/memfd.h \ -sys/mman.h sys/eventfd.h linux/soundcard.h sys/soundcard.h syslog.h +for ac_header in \ + alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ + ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/fs.h linux/memfd.h \ + linux/random.h linux/soundcard.h \ + linux/tipc.h linux/wait.h netdb.h net/ethernet.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ + sched.h setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ + sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \ + sys/loadavg.h sys/lock.h sys/memfd.h sys/mkdev.h sys/mman.h sys/modem.h sys/param.h sys/poll.h \ + sys/random.h sys/resource.h sys/select.h sys/sendfile.h sys/socket.h sys/soundcard.h sys/stat.h \ + sys/statvfs.h sys/sys_domain.h sys/syscall.h sys/sysmacros.h sys/termio.h sys/time.h sys/times.h \ + sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h sys/xattr.h sysexits.h syslog.h \ + termios.h util.h utime.h utmp.h \ + do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -8579,7 +9855,8 @@ done # On Linux, can.h, can/bcm.h, can/j1939.h, can/raw.h require sys/socket.h -for ac_header in linux/can.h linux/can/bcm.h linux/can/j1939.h linux/can/raw.h +# On NetBSD, netcan/can.h requires sys/socket.h +for ac_header in linux/can.h linux/can/bcm.h linux/can/j1939.h linux/can/raw.h netcan/can.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" " @@ -9439,14 +10716,30 @@ _ACEOF $as_echo_n "checking whether to enable large file support... " >&6; } if test "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ "$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then + have_largefile_support="yes" +else + have_largefile_support="no" +fi +case $ac_sys_system in #( + Emscripten) : + have_largefile_support="no" + ;; #( + *) : + ;; +esac +if test "x$have_largefile_support" = xyes; then : + $as_echo "#define HAVE_LARGEFILE_SUPPORT 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } + fi # The cast to long int works around a bug in the HP C Compiler @@ -9651,97 +10944,6 @@ fi CC="$ac_save_cc" - -case $ac_sys_system/$ac_sys_release in - Darwin/[01567]\..*) - OTHER_LIBTOOL_OPT="-prebind -seg1addr 0x10000000" - ;; - Darwin/*) - OTHER_LIBTOOL_OPT="" - ;; -esac - - - -case $ac_sys_system/$ac_sys_release in - Darwin/[01567]\..*) - LIBTOOL_CRUFT="-framework System -lcc_dynamic" - if test "${enable_universalsdk}"; then - : - else - LIBTOOL_CRUFT="${LIBTOOL_CRUFT} -arch_only `/usr/bin/arch`" - fi - LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -install_name $(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' - LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';; - Darwin/*) - gcc_version=`gcc -dumpversion` - if test ${gcc_version} '<' 4.0 - then - LIBTOOL_CRUFT="-lcc_dynamic" - else - LIBTOOL_CRUFT="" - fi - if test "$cross_compiling" = yes; then : - ac_osx_32bit=yes -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - int main(int argc, char*argv[]) - { - if (sizeof(long) == 4) { - return 0; - } else { - return 1; - } - } - -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_osx_32bit=yes -else - ac_osx_32bit=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - - if test "${ac_osx_32bit}" = "yes"; then - case `/usr/bin/arch` in - i386) - MACOSX_DEFAULT_ARCH="i386" - ;; - ppc) - MACOSX_DEFAULT_ARCH="ppc" - ;; - *) - as_fn_error $? "Unexpected output of 'arch' on macOS" "$LINENO" 5 - ;; - esac - else - case `/usr/bin/arch` in - i386) - MACOSX_DEFAULT_ARCH="x86_64" - ;; - ppc) - MACOSX_DEFAULT_ARCH="ppc64" - ;; - arm64) - MACOSX_DEFAULT_ARCH="arm64" - ;; - *) - as_fn_error $? "Unexpected output of 'arch' on macOS" "$LINENO" 5 - ;; - esac - - fi - - LIBTOOL_CRUFT=$LIBTOOL_CRUFT" -lSystem -lSystemStubs -arch_only ${MACOSX_DEFAULT_ARCH}" - LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -install_name $(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' - LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';; -esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-framework" >&5 $as_echo_n "checking for --enable-framework... " >&6; } if test "$enable_framework" @@ -9763,6 +10965,81 @@ else $as_echo "no" >&6; } fi +# Check for --with-dsymutil + + +DSYMUTIL= +DSYMUTIL_PATH= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-dsymutil" >&5 +$as_echo_n "checking for --with-dsymutil... " >&6; } + +# Check whether --with-dsymutil was given. +if test "${with_dsymutil+set}" = set; then : + withval=$with_dsymutil; +if test "$withval" != no +then + if test "$MACHDEP" != "darwin"; then + as_fn_error $? "dsymutil debug linking is only available in macOS." "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; + DSYMUTIL='true' +else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; }; DSYMUTIL= +fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test "$DSYMUTIL"; then + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_DSYMUTIL_PATH+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $DSYMUTIL_PATH in + [\\/]* | ?:[\\/]*) + ac_cv_path_DSYMUTIL_PATH="$DSYMUTIL_PATH" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_DSYMUTIL_PATH="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_DSYMUTIL_PATH" && ac_cv_path_DSYMUTIL_PATH="not found" + ;; +esac +fi +DSYMUTIL_PATH=$ac_cv_path_DSYMUTIL_PATH +if test -n "$DSYMUTIL_PATH"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL_PATH" >&5 +$as_echo "$DSYMUTIL_PATH" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "$DSYMUTIL_PATH" = "not found"; then + as_fn_error $? "dsymutil command not found on \$PATH" "$LINENO" 5 + fi +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dyld" >&5 $as_echo_n "checking for dyld... " >&6; } case $ac_sys_system/$ac_sys_release in @@ -9806,8 +11083,44 @@ if test "${with_memory_sanitizer+set}" = set; then : withval=$with_memory_sanitizer; { $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 $as_echo "$withval" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fsanitize=memory" >&5 +$as_echo_n "checking whether C compiler accepts -fsanitize=memory... " >&6; } +if ${ax_cv_check_cflags___fsanitize_memory+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -fsanitize=memory" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ax_cv_check_cflags___fsanitize_memory=yes +else + ax_cv_check_cflags___fsanitize_memory=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fsanitize_memory" >&5 +$as_echo "$ax_cv_check_cflags___fsanitize_memory" >&6; } +if test "x$ax_cv_check_cflags___fsanitize_memory" = xyes; then : + BASECFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer $BASECFLAGS" LDFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 $LDFLAGS" + +else + as_fn_error $? "The selected compiler doesn't support memory sanitizer" "$LINENO" 5 +fi + # MSan works by controlling memory allocation, our own malloc interferes. with_pymalloc="no" @@ -9941,6 +11254,9 @@ then BLDSHARED="$LDSHARED" fi ;; + Emscripten|WASI) + LDSHARED='$(CC) -shared' + LDCXXSHARED='$(CXX) -shared';; Linux*|GNU*|QNX*|VxWorks*|Haiku*) LDSHARED='$(CC) -shared' LDCXXSHARED='$(CXX) -shared';; @@ -9982,16 +11298,32 @@ then SCO_SV*) LDSHARED='$(CC) -Wl,-G,-Bexport' LDCXXSHARED='$(CXX) -Wl,-G,-Bexport';; + WASI*) + if test "x$enable_wasm_dynamic_linking" = xyes; then : + + +fi;; CYGWIN*) LDSHARED="gcc -shared -Wl,--enable-auto-image-base" LDCXXSHARED="g++ -shared -Wl,--enable-auto-image-base";; *) LDSHARED="ld";; esac fi + +if test "$enable_wasm_dynamic_linking" = "yes" -a "$ac_sys_system" = "Emscripten"; then + BLDSHARED='$(CC) -shared -sSIDE_MODULE=1' +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDSHARED" >&5 $as_echo "$LDSHARED" >&6; } LDCXXSHARED=${LDCXXSHARED-$LDSHARED} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking BLDSHARED flags" >&5 +$as_echo_n "checking BLDSHARED flags... " >&6; } BLDSHARED=${BLDSHARED-$LDSHARED} +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BLDSHARED" >&5 +$as_echo "$BLDSHARED" >&6; } + # CCSHARED are the C *flags* used to create objects to go into a shared # library (module) -- this is only needed for a few systems { $as_echo "$as_me:${as_lineno-$LINENO}: checking CCSHARED" >&5 @@ -10011,6 +11343,12 @@ then fi;; Linux-android*) ;; Linux*|GNU*) CCSHARED="-fPIC";; + Emscripten*|WASI*) + if test "x$enable_wasm_dynamic_linking" = xyes; then : + + CCSHARED="-fPIC" + +fi;; FreeBSD*|NetBSD*|OpenBSD*|DragonFly*) CCSHARED="-fPIC";; Haiku*) CCSHARED="-fPIC";; OpenUNIX*|UnixWare*) @@ -10050,7 +11388,7 @@ then # small for the default recursion limit. Increase the stack size # to ensure that tests don't crash stack_size="1000000" # 16 MB - if test "$with_ubsan" == "yes" + if test "$with_ubsan" = "yes" then # Undefined behavior sanitizer requires an even deeper stack stack_size="4000000" # 64 MB @@ -10118,6 +11456,13 @@ then CFLAGSFORSHARED='$(CCSHARED)' esac fi + +if test "x$enable_wasm_dynamic_linking" = xyes; then : + + CFLAGSFORSHARED='$(CCSHARED)' + +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CFLAGSFORSHARED" >&5 $as_echo "$CFLAGSFORSHARED" >&6; } @@ -10139,6 +11484,35 @@ esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SHLIBS" >&5 $as_echo "$SHLIBS" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking perf trampoline" >&5 +$as_echo_n "checking perf trampoline... " >&6; } +case $PLATFORM_TRIPLET in #( + x86_64-linux-gnu) : + perf_trampoline=yes ;; #( + aarch64-linux-gnu) : + perf_trampoline=yes ;; #( + *) : + perf_trampoline=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $perf_trampoline" >&5 +$as_echo "$perf_trampoline" >&6; } + +if test "x$perf_trampoline" = xyes; then : + + +$as_echo "#define PY_HAVE_PERF_TRAMPOLINE 1" >>confdefs.h + + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline.o + + if test "x$Py_DEBUG" = xtrue; then : + + as_fn_append BASECFLAGS " -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer" + +fi + +fi + # checks for libraries { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sendfile in -lsendfile" >&5 @@ -10277,62 +11651,121 @@ _ACEOF fi # Dynamic linking for HP-UX -# checks for uuid.h location -for ac_header in uuid/uuid.h uuid.h + + + + +have_uuid=missing + +for ac_header in uuid.h do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + ac_fn_c_check_header_mongrel "$LINENO" "uuid.h" "ac_cv_header_uuid_h" "$ac_includes_default" +if test "x$ac_cv_header_uuid_h" = xyes; then : cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +#define HAVE_UUID_H 1 _ACEOF + for ac_func in uuid_create uuid_enc_be +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + + have_uuid=yes + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-""} + +fi +done + + fi done -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time_safe" >&5 -$as_echo_n "checking for uuid_generate_time_safe... " >&6; } -if ${ac_cv_lib_uuid_uuid_generate_time_safe+:} false; then : - $as_echo_n "(cached) " >&6 +if test "x$have_uuid" = xmissing; then : + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBUUID" >&5 +$as_echo_n "checking for LIBUUID... " >&6; } + +if test -n "$LIBUUID_CFLAGS"; then + pkg_cv_LIBUUID_CFLAGS="$LIBUUID_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"uuid >= 2.20\""; } >&5 + ($PKG_CONFIG --exists --print-errors "uuid >= 2.20") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBUUID_CFLAGS=`$PKG_CONFIG --cflags "uuid >= 2.20" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ - -#ifndef uuid_generate_time_safe -void *x = uuid_generate_time_safe -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_lib_uuid_uuid_generate_time_safe=yes + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBUUID_LIBS"; then + pkg_cv_LIBUUID_LIBS="$LIBUUID_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"uuid >= 2.20\""; } >&5 + ($PKG_CONFIG --exists --print-errors "uuid >= 2.20") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBUUID_LIBS=`$PKG_CONFIG --libs "uuid >= 2.20" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - ac_cv_lib_uuid_uuid_generate_time_safe=no + pkg_failed=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time_safe" >&5 -$as_echo "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; } -if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes; then : - - -$as_echo "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h - - + else + pkg_failed=untried fi -# check for libuuid from util-linux + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBUUID_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "uuid >= 2.20" 2>&1` + else + LIBUUID_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "uuid >= 2.20" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBUUID_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBUUID_CFLAGS" + LDFLAGS="$LDFLAGS $LIBUUID_LIBS" + for ac_header in uuid/uuid.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default" +if test "x$ac_cv_header_uuid_uuid_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_UUID_UUID_H 1 +_ACEOF + + py_check_lib_save_LIBS=$LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5 $as_echo_n "checking for uuid_generate_time in -luuid... " >&6; } if ${ac_cv_lib_uuid_uuid_generate_time+:} false; then : @@ -10370,32 +11803,252 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time" >&5 $as_echo "$ac_cv_lib_uuid_uuid_generate_time" >&6; } if test "x$ac_cv_lib_uuid_uuid_generate_time" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBUUID 1 -_ACEOF + have_uuid=yes +fi + +LIBS=$py_check_lib_save_LIBS + + py_check_lib_save_LIBS=$LIBS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time_safe in -luuid" >&5 +$as_echo_n "checking for uuid_generate_time_safe in -luuid... " >&6; } +if ${ac_cv_lib_uuid_uuid_generate_time_safe+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-luuid $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char uuid_generate_time_safe (); +int +main () +{ +return uuid_generate_time_safe (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_uuid_uuid_generate_time_safe=yes +else + ac_cv_lib_uuid_uuid_generate_time_safe=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time_safe" >&5 +$as_echo "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; } +if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes; then : + have_uuid=yes + $as_echo "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h - LIBS="-luuid $LIBS" fi -LIBS=$save_LIBS +LIBS=$py_check_lib_save_LIBS -# AIX provides support for RFC4122 (uuid) in libc.a starting with AIX 6.1 (anno 2007) -# FreeBSD and OpenBSD provides support in libc as well. -# Little-endian FreeBSD, OpenBSD and NetBSD needs encoding into an octet -# stream in big-endian byte-order -for ac_func in uuid_create uuid_enc_be -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF fi + done + if test "x$have_uuid" = xyes; then : + + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-"-luuid"} + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBUUID_CFLAGS" + LDFLAGS="$LDFLAGS $LIBUUID_LIBS" + for ac_header in uuid/uuid.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default" +if test "x$ac_cv_header_uuid_uuid_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_UUID_UUID_H 1 +_ACEOF + + py_check_lib_save_LIBS=$LIBS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5 +$as_echo_n "checking for uuid_generate_time in -luuid... " >&6; } +if ${ac_cv_lib_uuid_uuid_generate_time+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-luuid $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char uuid_generate_time (); +int +main () +{ +return uuid_generate_time (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_uuid_uuid_generate_time=yes +else + ac_cv_lib_uuid_uuid_generate_time=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time" >&5 +$as_echo "$ac_cv_lib_uuid_uuid_generate_time" >&6; } +if test "x$ac_cv_lib_uuid_uuid_generate_time" = xyes; then : + have_uuid=yes +fi + +LIBS=$py_check_lib_save_LIBS + + py_check_lib_save_LIBS=$LIBS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time_safe in -luuid" >&5 +$as_echo_n "checking for uuid_generate_time_safe in -luuid... " >&6; } +if ${ac_cv_lib_uuid_uuid_generate_time_safe+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-luuid $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char uuid_generate_time_safe (); +int +main () +{ +return uuid_generate_time_safe (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_uuid_uuid_generate_time_safe=yes +else + ac_cv_lib_uuid_uuid_generate_time_safe=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time_safe" >&5 +$as_echo "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; } +if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes; then : + have_uuid=yes + $as_echo "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h + + +fi + +LIBS=$py_check_lib_save_LIBS + + +fi + +done + + if test "x$have_uuid" = xyes; then : + + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-"-luuid"} + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + + +else + LIBUUID_CFLAGS=$pkg_cv_LIBUUID_CFLAGS + LIBUUID_LIBS=$pkg_cv_LIBUUID_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + have_uuid=yes + $as_echo "#define HAVE_UUID_H 1" >>confdefs.h + + $as_echo "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h + + +fi + +fi + +if test "x$have_uuid" = xmissing; then : + + for ac_header in uuid/uuid.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default" +if test "x$ac_cv_header_uuid_uuid_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_UUID_UUID_H 1 +_ACEOF + + ac_fn_c_check_func "$LINENO" "uuid_generate_time" "ac_cv_func_uuid_generate_time" +if test "x$ac_cv_func_uuid_generate_time" = xyes; then : + + have_uuid=yes + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-""} + +fi + + +fi + +done + + +fi + +if test "x$have_uuid" = xmissing; then : + have_uuid=no +fi # 'Real Time' functions on Solaris # posix4 on Solaris 2.6 @@ -10564,7 +12217,7 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int main() +int main(void) { char s[16]; int i, *p1, *p2; @@ -10832,64 +12485,458 @@ $as_echo "$with_system_expat" >&6; } if test "x$with_system_expat" = xyes; then : - LIBEXPAT_CFLAGS="" - LIBEXPAT_LDFLAGS="-lexpat" + LIBEXPAT_CFLAGS=${LIBEXPAT_CFLAGS-""} + LIBEXPAT_LDFLAGS=${LIBEXPAT_LDFLAGS-"-lexpat"} LIBEXPAT_INTERNAL= else LIBEXPAT_CFLAGS="-I\$(srcdir)/Modules/expat" LIBEXPAT_LDFLAGS="-lm \$(LIBEXPAT_A)" - LIBEXPAT_INTERNAL="\$(LIBEXPAT_A)" + LIBEXPAT_INTERNAL="\$(LIBEXPAT_HEADERS) \$(LIBEXPAT_A)" fi +have_libffi=missing +if test "x$ac_sys_system" = xDarwin; then : -# Check for use of the system libffi library -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-system-ffi" >&5 -$as_echo_n "checking for --with-system-ffi... " >&6; } - -# Check whether --with-system_ffi was given. -if test "${with_system_ffi+set}" = set; then : - withval=$with_system_ffi; -fi + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS -if test "$ac_sys_system" = "Darwin" -then - case "$with_system_ffi" in - "") - with_system_ffi="no" - ;; - yes|no) - ;; - *) - as_fn_error $? "--with-system-ffi accepts no arguments" "$LINENO" 5 - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_system_ffi" >&5 -$as_echo "$with_system_ffi" >&6; } + CFLAGS="-I${SDKROOT}/usr/include/ffi $CFLAGS" + ac_fn_c_check_header_mongrel "$LINENO" "ffi.h" "ac_cv_header_ffi_h" "$ac_includes_default" +if test "x$ac_cv_header_ffi_h" = xyes; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ffi_call in -lffi" >&5 +$as_echo_n "checking for ffi_call in -lffi... " >&6; } +if ${ac_cv_lib_ffi_ffi_call+:} false; then : + $as_echo_n "(cached) " >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + ac_check_lib_save_LIBS=$LIBS +LIBS="-lffi $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ffi_call (); +int +main () +{ +return ffi_call (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ffi_ffi_call=yes +else + ac_cv_lib_ffi_ffi_call=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ffi_ffi_call" >&5 +$as_echo "$ac_cv_lib_ffi_ffi_call" >&6; } +if test "x$ac_cv_lib_ffi_ffi_call" = xyes; then : + + have_libffi=yes + LIBFFI_CFLAGS="-I${SDKROOT}/usr/include/ffi -DUSING_APPLE_OS_LIBFFI=1" + LIBFFI_LIBS="-lffi" + +fi + + +fi + + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +fi +if test "x$have_libffi" = xmissing; then : + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBFFI" >&5 +$as_echo_n "checking for LIBFFI... " >&6; } + +if test -n "$LIBFFI_CFLAGS"; then + pkg_cv_LIBFFI_CFLAGS="$LIBFFI_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libffi\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libffi") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBFFI_CFLAGS=`$PKG_CONFIG --cflags "libffi" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBFFI_LIBS"; then + pkg_cv_LIBFFI_LIBS="$LIBFFI_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libffi\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libffi") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBFFI_LIBS=`$PKG_CONFIG --libs "libffi" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBFFI_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libffi" 2>&1` + else + LIBFFI_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libffi" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBFFI_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBFFI_CFLAGS" + LDFLAGS="$LDFLAGS $LIBFFI_LIBS" + ac_fn_c_check_header_mongrel "$LINENO" "ffi.h" "ac_cv_header_ffi_h" "$ac_includes_default" +if test "x$ac_cv_header_ffi_h" = xyes; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ffi_call in -lffi" >&5 +$as_echo_n "checking for ffi_call in -lffi... " >&6; } +if ${ac_cv_lib_ffi_ffi_call+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lffi $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ffi_call (); +int +main () +{ +return ffi_call (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ffi_ffi_call=yes +else + ac_cv_lib_ffi_ffi_call=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ffi_ffi_call" >&5 +$as_echo "$ac_cv_lib_ffi_ffi_call" >&6; } +if test "x$ac_cv_lib_ffi_ffi_call" = xyes; then : + + have_libffi=yes + LIBFFI_CFLAGS=${LIBFFI_CFLAGS-""} + LIBFFI_LIBS=${LIBFFI_LIBS-"-lffi"} + +else + have_libffi=no +fi + + +fi + + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBFFI_CFLAGS" + LDFLAGS="$LDFLAGS $LIBFFI_LIBS" + ac_fn_c_check_header_mongrel "$LINENO" "ffi.h" "ac_cv_header_ffi_h" "$ac_includes_default" +if test "x$ac_cv_header_ffi_h" = xyes; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ffi_call in -lffi" >&5 +$as_echo_n "checking for ffi_call in -lffi... " >&6; } +if ${ac_cv_lib_ffi_ffi_call+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lffi $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ffi_call (); +int +main () +{ +return ffi_call (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ffi_ffi_call=yes +else + ac_cv_lib_ffi_ffi_call=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ffi_ffi_call" >&5 +$as_echo "$ac_cv_lib_ffi_ffi_call" >&6; } +if test "x$ac_cv_lib_ffi_ffi_call" = xyes; then : + + have_libffi=yes + LIBFFI_CFLAGS=${LIBFFI_CFLAGS-""} + LIBFFI_LIBS=${LIBFFI_LIBS-"-lffi"} + +else + have_libffi=no +fi + + +fi + + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + LIBFFI_CFLAGS=$pkg_cv_LIBFFI_CFLAGS + LIBFFI_LIBS=$pkg_cv_LIBFFI_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - if test "$with_system_ffi" != "" - then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with(out)-system-ffi is ignored on this platform" >&5 -$as_echo "$as_me: WARNING: --with(out)-system-ffi is ignored on this platform" >&2;} - fi - with_system_ffi="yes" + have_libffi=yes fi -if test "$with_system_ffi" = "yes" && test -n "$PKG_CONFIG"; then - LIBFFI_INCLUDEDIR="`"$PKG_CONFIG" libffi --cflags-only-I 2>/dev/null | sed -e 's/^-I//;s/ *$//'`" +fi + +if test "x$have_libffi" = xyes; then : + + ctypes_malloc_closure=no + case $ac_sys_system in #( + Darwin) : + + ctypes_malloc_closure=yes + ;; #( + sunos5) : + as_fn_append LIBFFI_LIBS " -mimpure-text" + ;; #( + *) : + ;; +esac + if test "x$ctypes_malloc_closure" = xyes; then : + + MODULE__CTYPES_MALLOC_CLOSURE=_ctypes/malloc_closure.c + as_fn_append LIBFFI_CFLAGS " -DUSING_MALLOC_CLOSURE_DOT_C=1" + +fi + + + if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + as_fn_append LIBFFI_LIBS " -ldl" +fi + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CFLAGS="$LIBFFI_CFLAGS $CFLAGS" + LDFLAGS="$LIBFFI_LIBS $LDFLAGS" + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ffi_prep_cif_var" >&5 +$as_echo_n "checking for ffi_prep_cif_var... " >&6; } +if ${ac_cv_func_ffi_prep_cif_var+:} false; then : + $as_echo_n "(cached) " >&6 else - LIBFFI_INCLUDEDIR="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +void *x=ffi_prep_cif_var + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_ffi_prep_cif_var=yes +else + ac_cv_func_ffi_prep_cif_var=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_ffi_prep_cif_var" >&5 +$as_echo "$ac_cv_func_ffi_prep_cif_var" >&6; } + if test "x$ac_cv_func_ffi_prep_cif_var" = xyes; then : + +$as_echo "#define HAVE_FFI_PREP_CIF_VAR 1" >>confdefs.h + fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ffi_prep_closure_loc" >&5 +$as_echo_n "checking for ffi_prep_closure_loc... " >&6; } +if ${ac_cv_func_ffi_prep_closure_loc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +void *x=ffi_prep_closure_loc + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_ffi_prep_closure_loc=yes +else + ac_cv_func_ffi_prep_closure_loc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_ffi_prep_closure_loc" >&5 +$as_echo "$ac_cv_func_ffi_prep_closure_loc" >&6; } + if test "x$ac_cv_func_ffi_prep_closure_loc" = xyes; then : + +$as_echo "#define HAVE_FFI_PREP_CLOSURE_LOC 1" >>confdefs.h + +fi + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ffi_closure_alloc" >&5 +$as_echo_n "checking for ffi_closure_alloc... " >&6; } +if ${ac_cv_func_ffi_closure_alloc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +void *x=ffi_closure_alloc + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_ffi_closure_alloc=yes +else + ac_cv_func_ffi_closure_alloc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_ffi_closure_alloc" >&5 +$as_echo "$ac_cv_func_ffi_closure_alloc" >&6; } + if test "x$ac_cv_func_ffi_closure_alloc" = xyes; then : + +$as_echo "#define HAVE_FFI_CLOSURE_ALLOC 1" >>confdefs.h + +fi + + + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +fi + # Check for use of the system libmpdec library { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-system-libmpdec" >&5 $as_echo_n "checking for --with-system-libmpdec... " >&6; } @@ -10906,18 +12953,23 @@ $as_echo "$with_system_libmpdec" >&6; } if test "x$with_system_libmpdec" = xyes; then : - LIBMPDEC_CFLAGS="" - LIBMPDEC_LDFLAGS="-lmpdec" + LIBMPDEC_CFLAGS=${LIBMPDEC_CFLAGS-""} + LIBMPDEC_LDFLAGS=${LIBMPDEC_LDFLAGS-"-lmpdec"} LIBMPDEC_INTERNAL= else LIBMPDEC_CFLAGS="-I\$(srcdir)/Modules/_decimal/libmpdec" LIBMPDEC_LDFLAGS="-lm \$(LIBMPDEC_A)" - LIBMPDEC_INTERNAL="\$(LIBMPDEC_A)" + LIBMPDEC_INTERNAL="\$(LIBMPDEC_HEADERS) \$(LIBMPDEC_A)" + + if test "x$with_pydebug" = xyes; then : + + as_fn_append LIBMPDEC_CFLAGS " -DTEST_COVERAGE" fi +fi @@ -10959,21 +13011,9 @@ esac libmpdec_machine=unknown if test "$libmpdec_system" = Darwin; then - case $MACOSX_DEFAULT_ARCH in #( - i386) : - libmpdec_machine=ansi32 ;; #( - ppc) : - libmpdec_machine=ansi32 ;; #( - x86_64) : - libmpdec_machine=x64 ;; #( - ppc64) : - libmpdec_machine=ansi64 ;; #( - arm64) : - libmpdec_machine=ansi64 ;; #( - *) : + # universal here means: build libmpdec with the same arch options + # the python interpreter was built with libmpdec_machine=universal - ;; -esac elif test $ac_cv_sizeof_size_t -eq 8; then if test "$ac_cv_gcc_asm_for_x64" = yes; then libmpdec_machine=x64 @@ -11034,6 +13074,297 @@ if test "$have_glibc_memmove_bug" = yes; then fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBNSL" >&5 +$as_echo_n "checking for LIBNSL... " >&6; } + +if test -n "$LIBNSL_CFLAGS"; then + pkg_cv_LIBNSL_CFLAGS="$LIBNSL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnsl\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libnsl") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBNSL_CFLAGS=`$PKG_CONFIG --cflags "libnsl" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBNSL_LIBS"; then + pkg_cv_LIBNSL_LIBS="$LIBNSL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnsl\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libnsl") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBNSL_LIBS=`$PKG_CONFIG --libs "libnsl" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBNSL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libnsl" 2>&1` + else + LIBNSL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libnsl" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBNSL_PKG_ERRORS" >&5 + + + LIBNSL_CFLAGS=${LIBNSL_CFLAGS-""} + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing yp_match" >&5 +$as_echo_n "checking for library containing yp_match... " >&6; } +if ${ac_cv_search_yp_match+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char yp_match (); +int +main () +{ +return yp_match (); + ; + return 0; +} +_ACEOF +for ac_lib in '' nsl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_yp_match=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_yp_match+:} false; then : + break +fi +done +if ${ac_cv_search_yp_match+:} false; then : + +else + ac_cv_search_yp_match=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_yp_match" >&5 +$as_echo "$ac_cv_search_yp_match" >&6; } +ac_res=$ac_cv_search_yp_match +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + have_nis=yes +else + have_nis=no +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + case $ac_cv_search_yp_match in #( + no) : + libnsl="" ;; #( + "none required") : + libnsl="" ;; #( + *) : + libnsl="$ac_cv_search_yp_match" + ;; +esac + LIBNSL_LIBS=${LIBNSL_LIBS-$libnsl} + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + LIBNSL_CFLAGS=${LIBNSL_CFLAGS-""} + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing yp_match" >&5 +$as_echo_n "checking for library containing yp_match... " >&6; } +if ${ac_cv_search_yp_match+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char yp_match (); +int +main () +{ +return yp_match (); + ; + return 0; +} +_ACEOF +for ac_lib in '' nsl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_yp_match=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_yp_match+:} false; then : + break +fi +done +if ${ac_cv_search_yp_match+:} false; then : + +else + ac_cv_search_yp_match=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_yp_match" >&5 +$as_echo "$ac_cv_search_yp_match" >&6; } +ac_res=$ac_cv_search_yp_match +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + have_nis=yes +else + have_nis=no +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + case $ac_cv_search_yp_match in #( + no) : + libnsl="" ;; #( + "none required") : + libnsl="" ;; #( + *) : + libnsl="$ac_cv_search_yp_match" + ;; +esac + LIBNSL_LIBS=${LIBNSL_LIBS-$libnsl} + +else + LIBNSL_CFLAGS=$pkg_cv_LIBNSL_CFLAGS + LIBNSL_LIBS=$pkg_cv_LIBNSL_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + have_nis=yes +fi + +if test "x$have_nis" = xyes; then : + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBNSL_CFLAGS" + for ac_header in rpc/rpc.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "rpc/rpc.h" "ac_cv_header_rpc_rpc_h" "$ac_includes_default" +if test "x$ac_cv_header_rpc_rpc_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_RPC_RPC_H 1 +_ACEOF + +fi + +done + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +fi + +case $ac_sys_system in #( + NetBSD*) : + OSSAUDIODEV_LIBS="-lossaudio" ;; #( + *) : + OSSAUDIODEV_LIBS="" + ;; +esac + + + + + if test "$ac_sys_system" = "Emscripten" -a -z "$LIBSQLITE3_CFLAGS" -a -z "$LIBSQLITE3_LIBS"; then : + + LIBSQLITE3_CFLAGS="-sUSE_SQLITE3" + LIBSQLITE3_LIBS="-sUSE_SQLITE3" + +fi + + + + + pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBSQLITE3" >&5 $as_echo_n "checking for LIBSQLITE3... " >&6; } @@ -11093,16 +13424,16 @@ fi echo "$LIBSQLITE3_PKG_ERRORS" >&5 - LIBSQLITE3_LIBS="-lsqlite3" - LIBSQLITE3_CFLAGS= + LIBSQLITE3_CFLAGS=${LIBSQLITE3_CFLAGS-""} + LIBSQLITE3_LIBS=${LIBSQLITE3_LIBS-"-lsqlite3"} elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - LIBSQLITE3_LIBS="-lsqlite3" - LIBSQLITE3_CFLAGS= + LIBSQLITE3_CFLAGS=${LIBSQLITE3_CFLAGS-""} + LIBSQLITE3_LIBS=${LIBSQLITE3_LIBS-"-lsqlite3"} else @@ -11114,20 +13445,47 @@ $as_echo "yes" >&6; } fi as_fn_append LIBSQLITE3_CFLAGS ' -I$(srcdir)/Modules/_sqlite' + + save_CFLAGS=$CFLAGS save_CPPFLAGS=$CPPFLAGS save_LDFLAGS=$LDFLAGS save_LIBS=$LIBS - CPPFLAGS="$LIBSQLITE3_CFLAGS $CFLAGS" + + CPPFLAGS="$CPPFLAGS $LIBSQLITE3_CFLAGS" LDFLAGS="$LIBSQLITE3_LIBS $LDFLAGS" ac_fn_c_check_header_mongrel "$LINENO" "sqlite3.h" "ac_cv_header_sqlite3_h" "$ac_includes_default" if test "x$ac_cv_header_sqlite3_h" = xyes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_open_v2 in -lsqlite3" >&5 -$as_echo_n "checking for sqlite3_open_v2 in -lsqlite3... " >&6; } -if ${ac_cv_lib_sqlite3_sqlite3_open_v2+:} false; then : + have_sqlite3=yes + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include + #if SQLITE_VERSION_NUMBER < 3007015 + # error "SQLite 3.7.15 or higher required" + #endif + +int +main () +{ + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + have_supported_sqlite3=yes + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_bind_double in -lsqlite3" >&5 +$as_echo_n "checking for sqlite3_bind_double in -lsqlite3... " >&6; } +if ${ac_cv_lib_sqlite3_sqlite3_bind_double+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -11141,59 +13499,552 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char sqlite3_open_v2 (); +char sqlite3_bind_double (); int main () { -return sqlite3_open_v2 (); +return sqlite3_bind_double (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_sqlite3_sqlite3_open_v2=yes + ac_cv_lib_sqlite3_sqlite3_bind_double=yes else - ac_cv_lib_sqlite3_sqlite3_open_v2=no + ac_cv_lib_sqlite3_sqlite3_bind_double=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_open_v2" >&5 -$as_echo "$ac_cv_lib_sqlite3_sqlite3_open_v2" >&6; } -if test "x$ac_cv_lib_sqlite3_sqlite3_open_v2" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_bind_double" >&5 +$as_echo "$ac_cv_lib_sqlite3_sqlite3_bind_double" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_bind_double" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSQLITE3 1 +_ACEOF - have_sqlite3=yes - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + LIBS="-lsqlite3 $LIBS" + +else + + have_supported_sqlite3=no + +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_column_decltype in -lsqlite3" >&5 +$as_echo_n "checking for sqlite3_column_decltype in -lsqlite3... " >&6; } +if ${ac_cv_lib_sqlite3_sqlite3_column_decltype+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - - #include - #if SQLITE_VERSION_NUMBER < 3007015 - # error "SQLite 3.7.15 or higher required" - #endif - +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_column_decltype (); int main () { - +return sqlite3_column_decltype (); ; return 0; } - _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - have_supported_sqlite3=yes +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_sqlite3_sqlite3_column_decltype=yes else - have_supported_sqlite3=no + ac_cv_lib_sqlite3_sqlite3_column_decltype=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_column_decltype" >&5 +$as_echo "$ac_cv_lib_sqlite3_sqlite3_column_decltype" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_column_decltype" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSQLITE3 1 +_ACEOF + + LIBS="-lsqlite3 $LIBS" else - have_sqlite3=no + + have_supported_sqlite3=no + fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_load_extension in -lsqlite3" >&5 + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_column_double in -lsqlite3" >&5 +$as_echo_n "checking for sqlite3_column_double in -lsqlite3... " >&6; } +if ${ac_cv_lib_sqlite3_sqlite3_column_double+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_column_double (); +int +main () +{ +return sqlite3_column_double (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_sqlite3_sqlite3_column_double=yes +else + ac_cv_lib_sqlite3_sqlite3_column_double=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_column_double" >&5 +$as_echo "$ac_cv_lib_sqlite3_sqlite3_column_double" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_column_double" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSQLITE3 1 +_ACEOF + + LIBS="-lsqlite3 $LIBS" + +else + + have_supported_sqlite3=no + +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_complete in -lsqlite3" >&5 +$as_echo_n "checking for sqlite3_complete in -lsqlite3... " >&6; } +if ${ac_cv_lib_sqlite3_sqlite3_complete+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_complete (); +int +main () +{ +return sqlite3_complete (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_sqlite3_sqlite3_complete=yes +else + ac_cv_lib_sqlite3_sqlite3_complete=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_complete" >&5 +$as_echo "$ac_cv_lib_sqlite3_sqlite3_complete" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_complete" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSQLITE3 1 +_ACEOF + + LIBS="-lsqlite3 $LIBS" + +else + + have_supported_sqlite3=no + +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_enable_shared_cache in -lsqlite3" >&5 +$as_echo_n "checking for sqlite3_enable_shared_cache in -lsqlite3... " >&6; } +if ${ac_cv_lib_sqlite3_sqlite3_enable_shared_cache+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_enable_shared_cache (); +int +main () +{ +return sqlite3_enable_shared_cache (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_sqlite3_sqlite3_enable_shared_cache=yes +else + ac_cv_lib_sqlite3_sqlite3_enable_shared_cache=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_enable_shared_cache" >&5 +$as_echo "$ac_cv_lib_sqlite3_sqlite3_enable_shared_cache" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_enable_shared_cache" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSQLITE3 1 +_ACEOF + + LIBS="-lsqlite3 $LIBS" + +else + + have_supported_sqlite3=no + +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_progress_handler in -lsqlite3" >&5 +$as_echo_n "checking for sqlite3_progress_handler in -lsqlite3... " >&6; } +if ${ac_cv_lib_sqlite3_sqlite3_progress_handler+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_progress_handler (); +int +main () +{ +return sqlite3_progress_handler (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_sqlite3_sqlite3_progress_handler=yes +else + ac_cv_lib_sqlite3_sqlite3_progress_handler=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_progress_handler" >&5 +$as_echo "$ac_cv_lib_sqlite3_sqlite3_progress_handler" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_progress_handler" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSQLITE3 1 +_ACEOF + + LIBS="-lsqlite3 $LIBS" + +else + + have_supported_sqlite3=no + +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_result_double in -lsqlite3" >&5 +$as_echo_n "checking for sqlite3_result_double in -lsqlite3... " >&6; } +if ${ac_cv_lib_sqlite3_sqlite3_result_double+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_result_double (); +int +main () +{ +return sqlite3_result_double (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_sqlite3_sqlite3_result_double=yes +else + ac_cv_lib_sqlite3_sqlite3_result_double=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_result_double" >&5 +$as_echo "$ac_cv_lib_sqlite3_sqlite3_result_double" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_result_double" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSQLITE3 1 +_ACEOF + + LIBS="-lsqlite3 $LIBS" + +else + + have_supported_sqlite3=no + +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_set_authorizer in -lsqlite3" >&5 +$as_echo_n "checking for sqlite3_set_authorizer in -lsqlite3... " >&6; } +if ${ac_cv_lib_sqlite3_sqlite3_set_authorizer+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_set_authorizer (); +int +main () +{ +return sqlite3_set_authorizer (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_sqlite3_sqlite3_set_authorizer=yes +else + ac_cv_lib_sqlite3_sqlite3_set_authorizer=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_set_authorizer" >&5 +$as_echo "$ac_cv_lib_sqlite3_sqlite3_set_authorizer" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_set_authorizer" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSQLITE3 1 +_ACEOF + + LIBS="-lsqlite3 $LIBS" + +else + + have_supported_sqlite3=no + +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_trace_v2 in -lsqlite3" >&5 +$as_echo_n "checking for sqlite3_trace_v2 in -lsqlite3... " >&6; } +if ${ac_cv_lib_sqlite3_sqlite3_trace_v2+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_trace_v2 (); +int +main () +{ +return sqlite3_trace_v2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_sqlite3_sqlite3_trace_v2=yes +else + ac_cv_lib_sqlite3_sqlite3_trace_v2=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_trace_v2" >&5 +$as_echo "$ac_cv_lib_sqlite3_sqlite3_trace_v2" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_trace_v2" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSQLITE3 1 +_ACEOF + + LIBS="-lsqlite3 $LIBS" + +else + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_trace in -lsqlite3" >&5 +$as_echo_n "checking for sqlite3_trace in -lsqlite3... " >&6; } +if ${ac_cv_lib_sqlite3_sqlite3_trace+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_trace (); +int +main () +{ +return sqlite3_trace (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_sqlite3_sqlite3_trace=yes +else + ac_cv_lib_sqlite3_sqlite3_trace=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_trace" >&5 +$as_echo "$ac_cv_lib_sqlite3_sqlite3_trace" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_trace" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSQLITE3 1 +_ACEOF + + LIBS="-lsqlite3 $LIBS" + +else + + have_supported_sqlite3=no + +fi + + + + +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_value_double in -lsqlite3" >&5 +$as_echo_n "checking for sqlite3_value_double in -lsqlite3... " >&6; } +if ${ac_cv_lib_sqlite3_sqlite3_value_double+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_value_double (); +int +main () +{ +return sqlite3_value_double (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_sqlite3_sqlite3_value_double=yes +else + ac_cv_lib_sqlite3_sqlite3_value_double=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_value_double" >&5 +$as_echo "$ac_cv_lib_sqlite3_sqlite3_value_double" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_value_double" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSQLITE3 1 +_ACEOF + + LIBS="-lsqlite3 $LIBS" + +else + + have_supported_sqlite3=no + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_load_extension in -lsqlite3" >&5 $as_echo_n "checking for sqlite3_load_extension in -lsqlite3... " >&6; } if ${ac_cv_lib_sqlite3_sqlite3_load_extension+:} false; then : $as_echo_n "(cached) " >&6 @@ -11233,8 +14084,60 @@ if test "x$ac_cv_lib_sqlite3_sqlite3_load_extension" = xyes; then : have_sqlite3_load_extension=yes else have_sqlite3_load_extension=no + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_serialize in -lsqlite3" >&5 +$as_echo_n "checking for sqlite3_serialize in -lsqlite3... " >&6; } +if ${ac_cv_lib_sqlite3_sqlite3_serialize+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsqlite3 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char sqlite3_serialize (); +int +main () +{ +return sqlite3_serialize (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_sqlite3_sqlite3_serialize=yes +else + ac_cv_lib_sqlite3_sqlite3_serialize=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_serialize" >&5 +$as_echo "$ac_cv_lib_sqlite3_sqlite3_serialize" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_serialize" = xyes; then : + + +$as_echo "#define PY_SQLITE_HAVE_SERIALIZE 1" >>confdefs.h + + +fi + + +else + + have_supported_sqlite3=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi @@ -11247,77 +14150,323 @@ LIBS=$save_LIBS -# Check for support for loadable sqlite extensions { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-loadable-sqlite-extensions" >&5 $as_echo_n "checking for --enable-loadable-sqlite-extensions... " >&6; } # Check whether --enable-loadable-sqlite-extensions was given. if test "${enable_loadable_sqlite_extensions+set}" = set; then : - enableval=$enable_loadable_sqlite_extensions; if test "x$have_sqlite3_load_extension" = xno; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Your version of SQLite does not support loadable extensions" >&5 + enableval=$enable_loadable_sqlite_extensions; + if test "x$have_sqlite3_load_extension" = xno; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: n/a" >&5 +$as_echo "n/a" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Your version of SQLite does not support loadable extensions" >&5 $as_echo "$as_me: WARNING: Your version of SQLite does not support loadable extensions" >&2;} -fi + else - enable_loadable_sqlite_extensions=no -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_loadable_sqlite_extensions" >&5 -$as_echo "$enable_loadable_sqlite_extensions" >&6; } - -if test "x$enable_loadable_sqlite_extensions" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } $as_echo "#define PY_SQLITE_ENABLE_LOAD_EXTENSION 1" >>confdefs.h fi -# Check for --with-tcltk-includes=path and --with-tcltk-libs=path - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-tcltk-includes" >&5 -$as_echo_n "checking for --with-tcltk-includes... " >&6; } - -# Check whether --with-tcltk-includes was given. -if test "${with_tcltk_includes+set}" = set; then : - withval=$with_tcltk_includes; else - with_tcltk_includes="default" + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_tcltk_includes" >&5 -$as_echo "$with_tcltk_includes" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-tcltk-libs" >&5 -$as_echo_n "checking for --with-tcltk-libs... " >&6; } -# Check whether --with-tcltk-libs was given. -if test "${with_tcltk_libs+set}" = set; then : - withval=$with_tcltk_libs; +found_tcltk=no +for _QUERY in \ + "tcl >= 8.5.12 tk >= 8.5.12" \ + "tcl8.6 tk8.6" \ + "tcl86 tk86" \ + "tcl8.5 >= 8.5.12 tk8.5 >= 8.5.12" \ + "tcl85 >= 8.5.12 tk85 >= 8.5.12" \ +; do + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$_QUERY\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$_QUERY") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for TCLTK" >&5 +$as_echo_n "checking for TCLTK... " >&6; } + +if test -n "$TCLTK_CFLAGS"; then + pkg_cv_TCLTK_CFLAGS="$TCLTK_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$_QUERY\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$_QUERY") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_TCLTK_CFLAGS=`$PKG_CONFIG --cflags "$_QUERY" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - with_tcltk_libs="default" + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$TCLTK_LIBS"; then + pkg_cv_TCLTK_LIBS="$TCLTK_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$_QUERY\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$_QUERY") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_TCLTK_LIBS=`$PKG_CONFIG --libs "$_QUERY" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_tcltk_libs" >&5 -$as_echo "$with_tcltk_libs" >&6; } -if test "x$with_tcltk_includes" = xdefault || test "x$with_tcltk_libs" = xdefault -then - if test "x$with_tcltk_includes" != "x$with_tcltk_libs" - then - as_fn_error $? "use both --with-tcltk-includes='...' and --with-tcltk-libs='...' or neither" "$LINENO" 5 - fi - if test -n "$PKG_CONFIG" && "$PKG_CONFIG" --exists tcl tk; then - TCLTK_INCLUDES="`"$PKG_CONFIG" tcl tk --cflags-only-I 2>/dev/null`" - TCLTK_LIBS="`"$PKG_CONFIG" tcl tk --libs 2>/dev/null`" - else - TCLTK_INCLUDES="" - TCLTK_LIBS="" - fi + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes else - TCLTK_INCLUDES="$with_tcltk_includes" - TCLTK_LIBS="$with_tcltk_libs" + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + TCLTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$_QUERY" 2>&1` + else + TCLTK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$_QUERY" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$TCLTK_PKG_ERRORS" >&5 + + found_tcltk=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + found_tcltk=no +else + TCLTK_CFLAGS=$pkg_cv_TCLTK_CFLAGS + TCLTK_LIBS=$pkg_cv_TCLTK_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + found_tcltk=yes fi -# check for _gdbmmodulec dependencies -for ac_header in gdbm.h +fi + if test "x$found_tcltk" = xyes; then : + break +fi +done + +if test "x$found_tcltk" = xno; then : + + TCLTK_CFLAGS=${TCLTK_CFLAGS-""} + TCLTK_LIBS=${TCLTK_LIBS-""} + +fi + +case $ac_sys_system in #( + FreeBSD*) : + + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 + ($PKG_CONFIG --exists --print-errors "x11") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11" >&5 +$as_echo_n "checking for X11... " >&6; } + +if test -n "$X11_CFLAGS"; then + pkg_cv_X11_CFLAGS="$X11_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 + ($PKG_CONFIG --exists --print-errors "x11") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_X11_CFLAGS=`$PKG_CONFIG --cflags "x11" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$X11_LIBS"; then + pkg_cv_X11_LIBS="$X11_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 + ($PKG_CONFIG --exists --print-errors "x11") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_X11_LIBS=`$PKG_CONFIG --libs "x11" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + X11_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "x11" 2>&1` + else + X11_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "x11" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$X11_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (x11) were not met: + +$X11_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables X11_CFLAGS +and X11_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables X11_CFLAGS +and X11_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + X11_CFLAGS=$pkg_cv_X11_CFLAGS + X11_LIBS=$pkg_cv_X11_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + TCLTK_CFLAGS="$TCLTK_CFLAGS $X11_CFLAGS" + TCLTK_LIBS="$TCLTK_LIBS $X11_LIBS" + +fi + +fi + + ;; #( + *) : + ;; +esac + +save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $TCLTK_CFLAGS" + LIBS="$TCLTK_LIBS $LDFLAGS" + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include + #include + #if defined(TK_HEX_VERSION) + # if TK_HEX_VERSION < 0x0805020c + # error "Tk older than 8.5.12 not supported" + # endif + #endif + #if (TCL_MAJOR_VERSION < 8) || \ + ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 5)) || \ + ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION == 5) && (TCL_RELEASE_SERIAL < 12)) + # error "Tcl older than 8.5.12 not supported" + #endif + #if (TK_MAJOR_VERSION < 8) || \ + ((TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION < 5)) || \ + ((TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION == 5) && (TK_RELEASE_SERIAL < 12)) + # error "Tk older than 8.5.12 not supported" + #endif + +int +main () +{ + + void *x1 = Tcl_Init; + void *x2 = Tk_Init; + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + have_tcltk=yes + as_fn_append TCLTK_CFLAGS " -Wno-strict-prototypes -DWITH_APPINIT=1" + +else + + have_tcltk=no + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + + + +save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $GDBM_CFLAGS" + LDFLAGS="$GDBM_LIBS $LDFLAGS" + for ac_header in gdbm.h do : ac_fn_c_check_header_mongrel "$LINENO" "gdbm.h" "ac_cv_header_gdbm_h" "$ac_includes_default" if test "x$ac_cv_header_gdbm_h" = xyes; then : @@ -11325,8 +14474,7 @@ if test "x$ac_cv_header_gdbm_h" = xyes; then : #define HAVE_GDBM_H 1 _ACEOF - LIBS_SAVE=$LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gdbm_open in -lgdbm" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gdbm_open in -lgdbm" >&5 $as_echo_n "checking for gdbm_open in -lgdbm... " >&6; } if ${ac_cv_lib_gdbm_gdbm_open+:} false; then : $as_echo_n "(cached) " >&6 @@ -11363,22 +14511,29 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gdbm_gdbm_open" >&5 $as_echo "$ac_cv_lib_gdbm_gdbm_open" >&6; } if test "x$ac_cv_lib_gdbm_gdbm_open" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBGDBM 1 -_ACEOF - LIBS="-lgdbm $LIBS" + have_gdbm=yes + GDBM_LIBS=${GDBM_LIBS-"-lgdbm"} +else + have_gdbm=no fi - LIBS=$LIBS_SAVE +else + have_gdbm=no fi done -# check for _dbmmodule.c dependencies +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + for ac_header in ndbm.h do : ac_fn_c_check_header_mongrel "$LINENO" "ndbm.h" "ac_cv_header_ndbm_h" "$ac_includes_default" @@ -11387,14 +14542,18 @@ if test "x$ac_cv_header_ndbm_h" = xyes; then : #define HAVE_NDBM_H 1 _ACEOF - LIBS_SAVE="$LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dbm_open in -lndbm" >&5 -$as_echo_n "checking for dbm_open in -lndbm... " >&6; } -if ${ac_cv_lib_ndbm_dbm_open+:} false; then : + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dbm_open" >&5 +$as_echo_n "checking for library containing dbm_open... " >&6; } +if ${ac_cv_search_dbm_open+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lndbm $LIBS" + ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -11413,81 +14572,73 @@ return dbm_open (); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ndbm_dbm_open=yes -else - ac_cv_lib_ndbm_dbm_open=no +for ac_lib in '' ndbm gdbm_compat; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_dbm_open=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + conftest$ac_exeext + if ${ac_cv_search_dbm_open+:} false; then : + break fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ndbm_dbm_open" >&5 -$as_echo "$ac_cv_lib_ndbm_dbm_open" >&6; } -if test "x$ac_cv_lib_ndbm_dbm_open" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBNDBM 1 -_ACEOF +done +if ${ac_cv_search_dbm_open+:} false; then : - LIBS="-lndbm $LIBS" - -fi - - LIBS="$LIBS_SAVE" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dbm_open in -lgdbm_compat" >&5 -$as_echo_n "checking for dbm_open in -lgdbm_compat... " >&6; } -if ${ac_cv_lib_gdbm_compat_dbm_open+:} false; then : - $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lgdbm_compat $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dbm_open (); -int -main () -{ -return dbm_open (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_gdbm_compat_dbm_open=yes -else - ac_cv_lib_gdbm_compat_dbm_open=no + ac_cv_search_dbm_open=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gdbm_compat_dbm_open" >&5 -$as_echo "$ac_cv_lib_gdbm_compat_dbm_open" >&6; } -if test "x$ac_cv_lib_gdbm_compat_dbm_open" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBGDBM_COMPAT 1 -_ACEOF - - LIBS="-lgdbm_compat $LIBS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dbm_open" >&5 +$as_echo "$ac_cv_search_dbm_open" >&6; } +ac_res=$ac_cv_search_dbm_open +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi - LIBS="$LIBS_SAVE" + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + fi done -# "gdbm-ndbm.h" and "gdbm/ndbm.h" are both normalized to "gdbm_ndbm_h" -# unset ac_cv_header_gdbm_ndbm_h to prevent false positive cache hits. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ndbm presence and linker args" >&5 +$as_echo_n "checking for ndbm presence and linker args... " >&6; } +case $ac_cv_search_dbm_open in #( + *ndbm*|*gdbm_compat*) : + + dbm_ndbm="$ac_cv_search_dbm_open" + have_ndbm=yes + ;; #( + none*) : + + dbm_ndbm="" + have_ndbm=yes + ;; #( + no) : + have_ndbm=no + ;; #( + *) : + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_ndbm ($dbm_ndbm)" >&5 +$as_echo "$have_ndbm ($dbm_ndbm)" >&6; } + { ac_cv_header_gdbm_ndbm_h=; unset ac_cv_header_gdbm_ndbm_h;} if ${ac_cv_header_gdbm_slash_ndbm_h+:} false; then : $as_echo_n "(cached) " >&6 @@ -11540,14 +14691,19 @@ fi { ac_cv_header_gdbm_ndbm_h=; unset ac_cv_header_gdbm_ndbm_h;} if test "$ac_cv_header_gdbm_slash_ndbm_h" = yes -o "$ac_cv_header_gdbm_dash_ndbm_h" = yes; then - LIBS_SAVE="$LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dbm_open in -lgdbm_compat" >&5 -$as_echo_n "checking for dbm_open in -lgdbm_compat... " >&6; } -if ${ac_cv_lib_gdbm_compat_dbm_open+:} false; then : + { ac_cv_search_dbm_open=; unset ac_cv_search_dbm_open;} + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dbm_open" >&5 +$as_echo_n "checking for library containing dbm_open... " >&6; } +if ${ac_cv_search_dbm_open+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lgdbm_compat $LIBS" + ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -11566,27 +14722,47 @@ return dbm_open (); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_gdbm_compat_dbm_open=yes -else - ac_cv_lib_gdbm_compat_dbm_open=no +for ac_lib in '' gdbm_compat; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_dbm_open=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + conftest$ac_exeext + if ${ac_cv_search_dbm_open+:} false; then : + break fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gdbm_compat_dbm_open" >&5 -$as_echo "$ac_cv_lib_gdbm_compat_dbm_open" >&6; } -if test "x$ac_cv_lib_gdbm_compat_dbm_open" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBGDBM_COMPAT 1 -_ACEOF - - LIBS="-lgdbm_compat $LIBS" +done +if ${ac_cv_search_dbm_open+:} false; then : +else + ac_cv_search_dbm_open=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dbm_open" >&5 +$as_echo "$ac_cv_search_dbm_open" >&6; } +ac_res=$ac_cv_search_dbm_open +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + have_gdbm_compat=yes +else + have_gdbm_compat=no fi - LIBS="$LIBS_SAVE" + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + fi # Check for libdb >= 5 with dbm_open() @@ -11605,16 +14781,21 @@ if ${ac_cv_have_libdb+:} false; then : $as_echo_n "(cached) " >&6 else - LIBS_SAVE="$LIBS" - LIBS="$LIBS -ldb" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + LIBS="$LIBS -ldb" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #define DB_DBM_HSEARCH 1 - #include - #if DB_VERSION_MAJOR < 5 - #error "dh.h: DB_VERSION_MAJOR < 5 is not supported." - #endif + #define DB_DBM_HSEARCH 1 + #include + #if DB_VERSION_MAJOR < 5 + #error "dh.h: DB_VERSION_MAJOR < 5 is not supported." + #endif int main () @@ -11632,7 +14813,13 @@ else fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext - LIBS="$LIBS_SAVE" + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_libdb" >&5 @@ -11657,25 +14844,73 @@ $as_echo_n "checking for --with-dbmliborder... " >&6; } # Check whether --with-dbmliborder was given. if test "${with_dbmliborder+set}" = set; then : withval=$with_dbmliborder; -if test x$with_dbmliborder = xyes -then -as_fn_error $? "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5 else - as_save_IFS=$IFS - IFS=: - for db in $with_dbmliborder; do - if test x$db != xndbm && test x$db != xgdbm && test x$db != xbdb - then - as_fn_error $? "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5 - fi - done - IFS=$as_save_IFS -fi + with_dbmliborder=gdbm:ndbm:bdb fi + +have_gdbm_dbmliborder=no +as_save_IFS=$IFS +IFS=: +for db in $with_dbmliborder; do + case $db in #( + ndbm) : + ;; #( + gdbm) : + have_gdbm_dbmliborder=yes ;; #( + bdb) : + ;; #( + *) : + with_dbmliborder=error + ;; +esac +done +IFS=$as_save_IFS +if test "x$with_dbmliborder" = xerror; then : + + as_fn_error $? "proper usage is --with-dbmliborder=db1:db2:... (gdbm:ndbm:bdb)" "$LINENO" 5 + +fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_dbmliborder" >&5 $as_echo "$with_dbmliborder" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _dbm module CFLAGS and LIBS" >&5 +$as_echo_n "checking for _dbm module CFLAGS and LIBS... " >&6; } +have_dbm=no +as_save_IFS=$IFS +IFS=: +for db in $with_dbmliborder; do + case "$db" in + ndbm) + if test "$have_ndbm" = yes; then + DBM_CFLAGS="-DUSE_NDBM" + DBM_LIBS="$dbm_ndbm" + have_dbm=yes + break + fi + ;; + gdbm) + if test "$have_gdbm_compat" = yes; then + DBM_CFLAGS="-DUSE_GDBM_COMPAT" + DBM_LIBS="-lgdbm_compat" + have_dbm=yes + break + fi + ;; + bdb) + if test "$ac_cv_have_libdb" = yes; then + DBM_CFLAGS="-DUSE_BERKDB" + DBM_LIBS="-ldb" + have_dbm=yes + break + fi + ;; + esac +done +IFS=$as_save_IFS +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $DBM_CFLAGS $DBM_LIBS" >&5 +$as_echo "$DBM_CFLAGS $DBM_LIBS" >&6; } + # Templates for things AC_DEFINEd more than once. # For a single AC_DEFINE, no template is needed. @@ -11753,6 +14988,7 @@ $as_echo_n "checking for pthread_create in -lpthread... " >&6; } /* end confdefs.h. */ #include +#include #include void * start_routine (void *arg) { exit (0); } @@ -11953,11 +15189,16 @@ if test "x$ac_cv_lib_cma_pthread_create" = xyes; then : else + case $ac_sys_system in #( + WASI) : + posix_threads=stub ;; #( + *) : as_fn_error $? "could not find pthreads on your system" "$LINENO" 5 + ;; +esac fi - fi fi @@ -12035,6 +15276,10 @@ $as_echo "#define HAVE_BROKEN_POSIX_SEMAPHORES 1" >>confdefs.h AIX/*) $as_echo "#define HAVE_BROKEN_POSIX_SEMAPHORES 1" >>confdefs.h + ;; + NetBSD/*) +$as_echo "#define HAVE_BROKEN_POSIX_SEMAPHORES 1" >>confdefs.h + ;; esac @@ -12054,7 +15299,7 @@ else void *foo(void *parm) { return NULL; } - main() { + int main(void) { pthread_attr_t attr; pthread_t id; if (pthread_attr_init(&attr)) return (-1); @@ -12111,6 +15356,13 @@ done fi +if test "x$posix_threads" = xstub; then : + + +$as_echo "#define HAVE_PTHREAD_STUBS 1" >>confdefs.h + + +fi # Check for enable-ipv6 @@ -12148,19 +15400,26 @@ int domain = AF_INET6; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } ipv6=yes else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } ipv6=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +case $ac_sys_system in #( + WASI) : + ipv6=no + ;; #( + *) : + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ipv6" >&5 +$as_echo "$ipv6" >&6; } + if test "$ipv6" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if RFC2553 API is available" >&5 $as_echo_n "checking if RFC2553 API is available... " >&6; } @@ -12348,16 +15607,19 @@ fi if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then if test -d $ipv6libdir -a -f $ipv6libdir/lib$ipv6lib.a; then LIBS="-L$ipv6libdir -l$ipv6lib $LIBS" - echo "using lib$ipv6lib" + { $as_echo "$as_me:${as_lineno-$LINENO}: using lib$ipv6lib" >&5 +$as_echo "$as_me: using lib$ipv6lib" >&6;} else - if test $ipv6trylibc = "yes"; then - echo "using libc" - else - echo 'Fatal: no $ipv6lib library found. cannot continue.' - echo "You need to fetch lib$ipv6lib.a from appropriate" - echo 'ipv6 kit and compile beforehand.' - exit 1 - fi + if test "x$ipv6trylibc" = xyes; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: using libc" >&5 +$as_echo "$as_me: using libc" >&6;} + +else + + as_fn_error $? "No $ipv6lib library found; cannot continue. You need to fetch lib$ipv6lib.a from appropriate ipv6 kit and compile beforehand." "$LINENO" 5 + +fi fi fi @@ -12468,7 +15730,15 @@ fi if test -z "$with_pymalloc" then + case $ac_sys_system in #( + Emscripten) : + with_pymalloc="no" ;; #( + WASI) : + with_pymalloc="no" ;; #( + *) : with_pymalloc="yes" + ;; +esac fi if test "$with_pymalloc" != "no" then @@ -12649,6 +15919,21 @@ $as_echo "$ac_cv_dtrace_link" >&6; } fi fi +PLATFORM_HEADERS= +PLATFORM_OBJS= + +case $ac_sys_system in #( + Emscripten) : + + as_fn_append PLATFORM_OBJS ' Python/emscripten_signal.o' + as_fn_append PLATFORM_HEADERS ' $(srcdir)/Include/internal/pycore_emscripten_signal.h' + ;; #( + *) : + ;; +esac + + + # -I${DLINCLDIR} is added to the compile rule for importdl.o DLINCLDIR=. @@ -12715,31 +16000,32 @@ $as_echo "$MACHDEP_OBJS" >&6; } fi # checks for library functions -for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ - clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \ - explicit_memset faccessat fchmod fchmodat fchown fchownat \ - fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \ - futimens futimes gai_strerror getentropy \ - getgrgid getgrgid_r getgrnam_r \ - getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \ - getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \ - if_nameindex \ - initgroups kill killpg lchown lockf linkat lstat lutimes mmap \ - memrchr mbrtowc mkdirat mkfifo \ - madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ - posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \ - pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \ - readlink readlinkat readv realpath renameat \ - sem_open sem_timedwait sem_clockwait sem_getvalue sem_unlink sendfile setegid seteuid \ - setgid sethostname \ - setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \ - sched_get_priority_max sched_setaffinity sched_setscheduler sched_setparam \ - sched_rr_get_interval \ - sigaction sigaltstack sigfillset siginterrupt sigpending sigrelse \ - sigtimedwait sigwait sigwaitinfo snprintf splice strftime strlcpy strsignal symlinkat sync \ - sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ - truncate uname unlinkat utimensat utimes vfork waitid waitpid wait3 wait4 \ - wcscoll wcsftime wcsxfrm wmemcmp writev _getpty rtpSpawn +for ac_func in \ + accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \ + copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \ + faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \ + fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \ + gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \ + getgrnam_r getgrouplist getgroups gethostname getitimer getloadavg getlogin \ + getpeername getpgid getpid getppid getpriority _getpty \ + getpwent getpwnam_r getpwuid getpwuid_r getresgid getresuid getrusage getsid getspent \ + getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \ + lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \ + mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \ + pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \ + pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \ + pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \ + rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \ + sched_setparam sched_setscheduler sem_clockwait sem_getvalue sem_open \ + sem_timedwait sem_unlink sendfile setegid seteuid setgid sethostname \ + setitimer setlocale setpgid setpgrp setpriority setregid setresgid \ + setresuid setreuid setsid setuid setvbuf shutdown sigaction sigaltstack \ + sigfillset siginterrupt sigpending sigrelse sigtimedwait sigwait \ + sigwaitinfo snprintf splice strftime strlcpy strsignal symlinkat sync \ + sysconf system tcgetpgrp tcsetpgrp tempnam timegm times tmpfile \ + tmpnam tmpnam_r truncate ttyname umask uname unlinkat utimensat utimes vfork \ + wait wait3 wait4 waitid waitpid wcscoll wcsftime wcsxfrm wmemcmp writev \ + do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -12779,8 +16065,6 @@ $as_echo "#define HAVE_DIRFD 1" >>confdefs.h fi - - # For some functions, having a definition is not sufficient, since # we want to take their address. @@ -13001,9 +16285,9 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for epoll" >&5 -$as_echo_n "checking for epoll... " >&6; } -if ${ac_cv_func_epoll+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for epoll_create" >&5 +$as_echo_n "checking for epoll_create... " >&6; } +if ${ac_cv_func_epoll_create+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13012,22 +16296,22 @@ else int main () { -void *x=epoll +void *x=epoll_create ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_epoll=yes + ac_cv_func_epoll_create=yes else - ac_cv_func_epoll=no + ac_cv_func_epoll_create=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_epoll" >&5 -$as_echo "$ac_cv_func_epoll" >&6; } - if test "x$ac_cv_func_epoll" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_epoll_create" >&5 +$as_echo "$ac_cv_func_epoll_create" >&6; } + if test "x$ac_cv_func_epoll_create" = xyes; then : $as_echo "#define HAVE_EPOLL 1" >>confdefs.h @@ -13343,7 +16627,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_flock_decl" >&5 $as_echo "$ac_cv_flock_decl" >&6; } -if test "x${ac_cv_flock_decl}" = xyes; then +if test "x$ac_cv_flock_decl" = xyes; then : for ac_func in flock do : ac_fn_c_check_func "$LINENO" "flock" "ac_cv_func_flock" @@ -13352,7 +16636,9 @@ if test "x$ac_cv_func_flock" = xyes; then : #define HAVE_FLOCK 1 _ACEOF -else +fi +done + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock in -lbsd" >&5 $as_echo_n "checking for flock in -lbsd... " >&6; } if ${ac_cv_lib_bsd_flock+:} false; then : @@ -13390,18 +16676,10 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_flock" >&5 $as_echo "$ac_cv_lib_bsd_flock" >&6; } if test "x$ac_cv_lib_bsd_flock" = xyes; then : - $as_echo "#define HAVE_FLOCK 1" >>confdefs.h - - -$as_echo "#define FLOCK_NEEDS_LIBBSD 1" >>confdefs.h - - + FCNTL_LIBS="-lbsd" fi -fi -done - fi @@ -13623,7 +16901,7 @@ else #include #include -int main(int argc, char*argv[]) +int main(int argc, char *argv[]) { if(chflags(argv[0], 0) != 0) return 1; @@ -13672,7 +16950,7 @@ else #include #include -int main(int argc, char*argv[]) +int main(int argc, char *argv[]) { if(lchflags(argv[0], 0) != 0) return 1; @@ -13708,7 +16986,90 @@ $as_echo "#define HAVE_LCHFLAGS 1" >>confdefs.h fi -for ac_header in zlib.h + + + + + + if test "$ac_sys_system" = "Emscripten" -a -z "$ZLIB_CFLAGS" -a -z "$ZLIB_LIBS"; then : + + ZLIB_CFLAGS="-sUSE_ZLIB" + ZLIB_LIBS="-sUSE_ZLIB" + +fi + + + + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ZLIB" >&5 +$as_echo_n "checking for ZLIB... " >&6; } + +if test -n "$ZLIB_CFLAGS"; then + pkg_cv_ZLIB_CFLAGS="$ZLIB_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_ZLIB_CFLAGS=`$PKG_CONFIG --cflags "zlib >= 1.2.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$ZLIB_LIBS"; then + pkg_cv_ZLIB_LIBS="$ZLIB_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_ZLIB_LIBS=`$PKG_CONFIG --libs "zlib >= 1.2.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "zlib >= 1.2.0" 2>&1` + else + ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "zlib >= 1.2.0" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$ZLIB_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" + LDFLAGS="$LDFLAGS $ZLIB_LIBS" + for ac_header in zlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" if test "x$ac_cv_header_zlib_h" = xyes; then : @@ -13716,8 +17077,8 @@ if test "x$ac_cv_header_zlib_h" = xyes; then : #define HAVE_ZLIB_H 1 _ACEOF - save_LIBS="$LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 + py_check_lib_save_LIBS=$LIBS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 $as_echo_n "checking for gzread in -lz... " >&6; } if ${ac_cv_lib_z_gzread+:} false; then : $as_echo_n "(cached) " >&6 @@ -13754,16 +17115,26 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzread" >&5 $as_echo "$ac_cv_lib_z_gzread" >&6; } if test "x$ac_cv_lib_z_gzread" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBZ 1 -_ACEOF - - LIBS="-lz $LIBS" - + have_zlib=yes +else + have_zlib=no fi - LIBS="$save_LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -lz" >&5 +LIBS=$py_check_lib_save_LIBS + + +else + have_zlib=no +fi + +done + + if test "x$have_zlib" = xyes; then : + + ZLIB_CFLAGS=${ZLIB_CFLAGS-""} + ZLIB_LIBS=${ZLIB_LIBS-"-lz"} + py_check_lib_save_LIBS=$LIBS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -lz" >&5 $as_echo_n "checking for inflateCopy in -lz... " >&6; } if ${ac_cv_lib_z_inflateCopy+:} false; then : $as_echo_n "(cached) " >&6 @@ -13800,19 +17171,253 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflateCopy" >&5 $as_echo "$ac_cv_lib_z_inflateCopy" >&6; } if test "x$ac_cv_lib_z_inflateCopy" = xyes; then : - -$as_echo "#define HAVE_ZLIB_COPY 1" >>confdefs.h + $as_echo "#define HAVE_ZLIB_COPY 1" >>confdefs.h fi - LIBS="$save_LIBS" +LIBS=$py_check_lib_save_LIBS + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" + LDFLAGS="$LDFLAGS $ZLIB_LIBS" + for ac_header in zlib.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" +if test "x$ac_cv_header_zlib_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ZLIB_H 1 +_ACEOF + + py_check_lib_save_LIBS=$LIBS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 +$as_echo_n "checking for gzread in -lz... " >&6; } +if ${ac_cv_lib_z_gzread+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gzread (); +int +main () +{ +return gzread (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_z_gzread=yes +else + ac_cv_lib_z_gzread=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzread" >&5 +$as_echo "$ac_cv_lib_z_gzread" >&6; } +if test "x$ac_cv_lib_z_gzread" = xyes; then : + have_zlib=yes +else + have_zlib=no +fi + +LIBS=$py_check_lib_save_LIBS + + +else + have_zlib=no fi done + if test "x$have_zlib" = xyes; then : -for ac_header in bzlib.h + ZLIB_CFLAGS=${ZLIB_CFLAGS-""} + ZLIB_LIBS=${ZLIB_LIBS-"-lz"} + py_check_lib_save_LIBS=$LIBS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -lz" >&5 +$as_echo_n "checking for inflateCopy in -lz... " >&6; } +if ${ac_cv_lib_z_inflateCopy+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char inflateCopy (); +int +main () +{ +return inflateCopy (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_z_inflateCopy=yes +else + ac_cv_lib_z_inflateCopy=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflateCopy" >&5 +$as_echo "$ac_cv_lib_z_inflateCopy" >&6; } +if test "x$ac_cv_lib_z_inflateCopy" = xyes; then : + $as_echo "#define HAVE_ZLIB_COPY 1" >>confdefs.h + +fi + +LIBS=$py_check_lib_save_LIBS + + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + ZLIB_CFLAGS=$pkg_cv_ZLIB_CFLAGS + ZLIB_LIBS=$pkg_cv_ZLIB_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + have_zlib=yes + $as_echo "#define HAVE_ZLIB_COPY 1" >>confdefs.h + + +fi + +if test "x$have_zlib" = xyes; then : + + BINASCII_CFLAGS="-DUSE_ZLIB_CRC32 $ZLIB_CFLAGS" + BINASCII_LIBS="$ZLIB_LIBS" + +fi + + + + + if test "$ac_sys_system" = "Emscripten" -a -z "$BZIP2_CFLAGS" -a -z "$BZIP2_LIBS"; then : + + BZIP2_CFLAGS="-sUSE_BZIP2" + BZIP2_LIBS="-sUSE_BZIP2" + +fi + + + + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BZIP2" >&5 +$as_echo_n "checking for BZIP2... " >&6; } + +if test -n "$BZIP2_CFLAGS"; then + pkg_cv_BZIP2_CFLAGS="$BZIP2_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"bzip2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "bzip2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_BZIP2_CFLAGS=`$PKG_CONFIG --cflags "bzip2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$BZIP2_LIBS"; then + pkg_cv_BZIP2_LIBS="$BZIP2_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"bzip2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "bzip2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_BZIP2_LIBS=`$PKG_CONFIG --libs "bzip2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + BZIP2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "bzip2" 2>&1` + else + BZIP2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "bzip2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$BZIP2_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $BZIP2_CFLAGS" + LDFLAGS="$LDFLAGS $BZIP2_LIBS" + for ac_header in bzlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default" if test "x$ac_cv_header_bzlib_h" = xyes; then : @@ -13820,8 +17425,7 @@ if test "x$ac_cv_header_bzlib_h" = xyes; then : #define HAVE_BZLIB_H 1 _ACEOF - save_LIBS="$LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -lbz2" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -lbz2" >&5 $as_echo_n "checking for BZ2_bzCompress in -lbz2... " >&6; } if ${ac_cv_lib_bz2_BZ2_bzCompress+:} false; then : $as_echo_n "(cached) " >&6 @@ -13858,22 +17462,192 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzCompress" >&5 $as_echo "$ac_cv_lib_bz2_BZ2_bzCompress" >&6; } if test "x$ac_cv_lib_bz2_BZ2_bzCompress" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBBZ2 1 -_ACEOF - - LIBS="-lbz2 $LIBS" - + have_bzip2=yes +else + have_bzip2=no fi - LIBS="$save_LIBS" +else + have_bzip2=no fi done + if test "x$have_bzip2" = xyes; then : -for ac_header in lzma.h + BZIP2_CFLAGS=${BZIP2_CFLAGS-""} + BZIP2_LIBS=${BZIP2_LIBS-"-lbz2"} + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $BZIP2_CFLAGS" + LDFLAGS="$LDFLAGS $BZIP2_LIBS" + for ac_header in bzlib.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default" +if test "x$ac_cv_header_bzlib_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_BZLIB_H 1 +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -lbz2" >&5 +$as_echo_n "checking for BZ2_bzCompress in -lbz2... " >&6; } +if ${ac_cv_lib_bz2_BZ2_bzCompress+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbz2 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char BZ2_bzCompress (); +int +main () +{ +return BZ2_bzCompress (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_bz2_BZ2_bzCompress=yes +else + ac_cv_lib_bz2_BZ2_bzCompress=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzCompress" >&5 +$as_echo "$ac_cv_lib_bz2_BZ2_bzCompress" >&6; } +if test "x$ac_cv_lib_bz2_BZ2_bzCompress" = xyes; then : + have_bzip2=yes +else + have_bzip2=no +fi + + +else + have_bzip2=no +fi + +done + + if test "x$have_bzip2" = xyes; then : + + BZIP2_CFLAGS=${BZIP2_CFLAGS-""} + BZIP2_LIBS=${BZIP2_LIBS-"-lbz2"} + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + BZIP2_CFLAGS=$pkg_cv_BZIP2_CFLAGS + BZIP2_LIBS=$pkg_cv_BZIP2_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + have_bzip2=yes +fi + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBLZMA" >&5 +$as_echo_n "checking for LIBLZMA... " >&6; } + +if test -n "$LIBLZMA_CFLAGS"; then + pkg_cv_LIBLZMA_CFLAGS="$LIBLZMA_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblzma\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblzma") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBLZMA_CFLAGS=`$PKG_CONFIG --cflags "liblzma" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBLZMA_LIBS"; then + pkg_cv_LIBLZMA_LIBS="$LIBLZMA_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblzma\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblzma") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBLZMA_LIBS=`$PKG_CONFIG --libs "liblzma" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBLZMA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblzma" 2>&1` + else + LIBLZMA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblzma" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBLZMA_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBLZMA_CFLAGS" + LDFLAGS="$LDFLAGS $LIBLZMA_LIBS" + for ac_header in lzma.h do : ac_fn_c_check_header_mongrel "$LINENO" "lzma.h" "ac_cv_header_lzma_h" "$ac_includes_default" if test "x$ac_cv_header_lzma_h" = xyes; then : @@ -13881,8 +17655,7 @@ if test "x$ac_cv_header_lzma_h" = xyes; then : #define HAVE_LZMA_H 1 _ACEOF - save_LIBS="$LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzma_easy_encoder in -llzma" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzma_easy_encoder in -llzma" >&5 $as_echo_n "checking for lzma_easy_encoder in -llzma... " >&6; } if ${ac_cv_lib_lzma_lzma_easy_encoder+:} false; then : $as_echo_n "(cached) " >&6 @@ -13919,20 +17692,124 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lzma_lzma_easy_encoder" >&5 $as_echo "$ac_cv_lib_lzma_lzma_easy_encoder" >&6; } if test "x$ac_cv_lib_lzma_lzma_easy_encoder" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLZMA 1 -_ACEOF - - LIBS="-llzma $LIBS" - + have_liblzma=yes +else + have_liblzma=no fi - LIBS="$save_LIBS" +else + have_liblzma=no fi done + if test "x$have_liblzma" = xyes; then : + + LIBLZMA_CFLAGS=${LIBLZMA_CFLAGS-""} + LIBLZMA_LIBS=${LIBLZMA_LIBS-"-llzma"} + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBLZMA_CFLAGS" + LDFLAGS="$LDFLAGS $LIBLZMA_LIBS" + for ac_header in lzma.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "lzma.h" "ac_cv_header_lzma_h" "$ac_includes_default" +if test "x$ac_cv_header_lzma_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LZMA_H 1 +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzma_easy_encoder in -llzma" >&5 +$as_echo_n "checking for lzma_easy_encoder in -llzma... " >&6; } +if ${ac_cv_lib_lzma_lzma_easy_encoder+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-llzma $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char lzma_easy_encoder (); +int +main () +{ +return lzma_easy_encoder (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_lzma_lzma_easy_encoder=yes +else + ac_cv_lib_lzma_lzma_easy_encoder=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lzma_lzma_easy_encoder" >&5 +$as_echo "$ac_cv_lib_lzma_lzma_easy_encoder" >&6; } +if test "x$ac_cv_lib_lzma_lzma_easy_encoder" = xyes; then : + have_liblzma=yes +else + have_liblzma=no +fi + + +else + have_liblzma=no +fi + +done + + if test "x$have_liblzma" = xyes; then : + + LIBLZMA_CFLAGS=${LIBLZMA_CFLAGS-""} + LIBLZMA_LIBS=${LIBLZMA_LIBS-"-llzma"} + +fi + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + LIBLZMA_CFLAGS=$pkg_cv_LIBLZMA_CFLAGS + LIBLZMA_LIBS=$pkg_cv_LIBLZMA_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + have_liblzma=yes +fi + + @@ -13972,6 +17849,188 @@ fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getservbyname" >&5 +$as_echo_n "checking for getservbyname... " >&6; } +if ${ac_cv_func_getservbyname+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +void *x=getservbyname + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_getservbyname=yes +else + ac_cv_func_getservbyname=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getservbyname" >&5 +$as_echo "$ac_cv_func_getservbyname" >&6; } + if test "x$ac_cv_func_getservbyname" = xyes; then : + +$as_echo "#define HAVE_GETSERVBYNAME 1" >>confdefs.h + +fi + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getservbyport" >&5 +$as_echo_n "checking for getservbyport... " >&6; } +if ${ac_cv_func_getservbyport+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +void *x=getservbyport + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_getservbyport=yes +else + ac_cv_func_getservbyport=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getservbyport" >&5 +$as_echo "$ac_cv_func_getservbyport" >&6; } + if test "x$ac_cv_func_getservbyport" = xyes; then : + +$as_echo "#define HAVE_GETSERVBYPORT 1" >>confdefs.h + +fi + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname" >&5 +$as_echo_n "checking for gethostbyname... " >&6; } +if ${ac_cv_func_gethostbyname+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +void *x=gethostbyname + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_gethostbyname=yes +else + ac_cv_func_gethostbyname=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_gethostbyname" >&5 +$as_echo "$ac_cv_func_gethostbyname" >&6; } + if test "x$ac_cv_func_gethostbyname" = xyes; then : + +$as_echo "#define HAVE_GETHOSTBYNAME 1" >>confdefs.h + +fi + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyaddr" >&5 +$as_echo_n "checking for gethostbyaddr... " >&6; } +if ${ac_cv_func_gethostbyaddr+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +void *x=gethostbyaddr + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_gethostbyaddr=yes +else + ac_cv_func_gethostbyaddr=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_gethostbyaddr" >&5 +$as_echo "$ac_cv_func_gethostbyaddr" >&6; } + if test "x$ac_cv_func_gethostbyaddr" = xyes; then : + +$as_echo "#define HAVE_GETHOSTBYADDR 1" >>confdefs.h + +fi + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getprotobyname" >&5 +$as_echo_n "checking for getprotobyname... " >&6; } +if ${ac_cv_func_getprotobyname+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +void *x=getprotobyname + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_getprotobyname=yes +else + ac_cv_func_getprotobyname=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getprotobyname" >&5 +$as_echo "$ac_cv_func_getprotobyname" >&6; } + if test "x$ac_cv_func_getprotobyname" = xyes; then : + +$as_echo "#define HAVE_GETPROTOBYNAME 1" >>confdefs.h + +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_aton" >&5 $as_echo_n "checking for inet_aton... " >&6; } @@ -14014,6 +18073,46 @@ fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa" >&5 +$as_echo_n "checking for inet_ntoa... " >&6; } +if ${ac_cv_func_inet_ntoa+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include + +int +main () +{ +void *x=inet_ntoa + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_inet_ntoa=yes +else + ac_cv_func_inet_ntoa=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_inet_ntoa" >&5 +$as_echo "$ac_cv_func_inet_ntoa" >&6; } + if test "x$ac_cv_func_inet_ntoa" = xyes; then : + +$as_echo "#define HAVE_INET_NTOA 1" >>confdefs.h + +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_pton" >&5 $as_echo_n "checking for inet_pton... " >&6; } @@ -14055,6 +18154,416 @@ fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpeername" >&5 +$as_echo_n "checking for getpeername... " >&6; } +if ${ac_cv_func_getpeername+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include + +int +main () +{ +void *x=getpeername + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_getpeername=yes +else + ac_cv_func_getpeername=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getpeername" >&5 +$as_echo "$ac_cv_func_getpeername" >&6; } + if test "x$ac_cv_func_getpeername" = xyes; then : + +$as_echo "#define HAVE_GETPEERNAME 1" >>confdefs.h + +fi + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getsockname" >&5 +$as_echo_n "checking for getsockname... " >&6; } +if ${ac_cv_func_getsockname+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include + +int +main () +{ +void *x=getsockname + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_getsockname=yes +else + ac_cv_func_getsockname=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getsockname" >&5 +$as_echo "$ac_cv_func_getsockname" >&6; } + if test "x$ac_cv_func_getsockname" = xyes; then : + +$as_echo "#define HAVE_GETSOCKNAME 1" >>confdefs.h + +fi + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for accept" >&5 +$as_echo_n "checking for accept... " >&6; } +if ${ac_cv_func_accept+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include + +int +main () +{ +void *x=accept + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_accept=yes +else + ac_cv_func_accept=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_accept" >&5 +$as_echo "$ac_cv_func_accept" >&6; } + if test "x$ac_cv_func_accept" = xyes; then : + +$as_echo "#define HAVE_ACCEPT 1" >>confdefs.h + +fi + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bind" >&5 +$as_echo_n "checking for bind... " >&6; } +if ${ac_cv_func_bind+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include + +int +main () +{ +void *x=bind + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_bind=yes +else + ac_cv_func_bind=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_bind" >&5 +$as_echo "$ac_cv_func_bind" >&6; } + if test "x$ac_cv_func_bind" = xyes; then : + +$as_echo "#define HAVE_BIND 1" >>confdefs.h + +fi + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect" >&5 +$as_echo_n "checking for connect... " >&6; } +if ${ac_cv_func_connect+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include + +int +main () +{ +void *x=connect + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_connect=yes +else + ac_cv_func_connect=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_connect" >&5 +$as_echo "$ac_cv_func_connect" >&6; } + if test "x$ac_cv_func_connect" = xyes; then : + +$as_echo "#define HAVE_CONNECT 1" >>confdefs.h + +fi + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for listen" >&5 +$as_echo_n "checking for listen... " >&6; } +if ${ac_cv_func_listen+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include + +int +main () +{ +void *x=listen + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_listen=yes +else + ac_cv_func_listen=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_listen" >&5 +$as_echo "$ac_cv_func_listen" >&6; } + if test "x$ac_cv_func_listen" = xyes; then : + +$as_echo "#define HAVE_LISTEN 1" >>confdefs.h + +fi + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for recvfrom" >&5 +$as_echo_n "checking for recvfrom... " >&6; } +if ${ac_cv_func_recvfrom+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include + +int +main () +{ +void *x=recvfrom + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_recvfrom=yes +else + ac_cv_func_recvfrom=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_recvfrom" >&5 +$as_echo "$ac_cv_func_recvfrom" >&6; } + if test "x$ac_cv_func_recvfrom" = xyes; then : + +$as_echo "#define HAVE_RECVFROM 1" >>confdefs.h + +fi + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sendto" >&5 +$as_echo_n "checking for sendto... " >&6; } +if ${ac_cv_func_sendto+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include + +int +main () +{ +void *x=sendto + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_sendto=yes +else + ac_cv_func_sendto=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_sendto" >&5 +$as_echo "$ac_cv_func_sendto" >&6; } + if test "x$ac_cv_func_sendto" = xyes; then : + +$as_echo "#define HAVE_SENDTO 1" >>confdefs.h + +fi + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt" >&5 +$as_echo_n "checking for setsockopt... " >&6; } +if ${ac_cv_func_setsockopt+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include + +int +main () +{ +void *x=setsockopt + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_setsockopt=yes +else + ac_cv_func_setsockopt=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_setsockopt" >&5 +$as_echo "$ac_cv_func_setsockopt" >&6; } + if test "x$ac_cv_func_setsockopt" = xyes; then : + +$as_echo "#define HAVE_SETSOCKOPT 1" >>confdefs.h + +fi + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket" >&5 +$as_echo_n "checking for socket... " >&6; } +if ${ac_cv_func_socket+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include + +int +main () +{ +void *x=socket + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_socket=yes +else + ac_cv_func_socket=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_socket" >&5 +$as_echo "$ac_cv_func_socket" >&6; } + if test "x$ac_cv_func_socket" = xyes; then : + +$as_echo "#define HAVE_SOCKET 1" >>confdefs.h + +fi + + + + # On some systems, setgroups is in unistd.h, on others, in grp.h @@ -14098,7 +18607,7 @@ fi -# check for openpty and forkpty +# check for openpty, login_tty, and forkpty for ac_func in openpty do : @@ -14197,6 +18706,65 @@ fi fi done +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing login_tty" >&5 +$as_echo_n "checking for library containing login_tty... " >&6; } +if ${ac_cv_search_login_tty+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char login_tty (); +int +main () +{ +return login_tty (); + ; + return 0; +} +_ACEOF +for ac_lib in '' util; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_login_tty=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_login_tty+:} false; then : + break +fi +done +if ${ac_cv_search_login_tty+:} false; then : + +else + ac_cv_search_login_tty=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_login_tty" >&5 +$as_echo "$ac_cv_search_login_tty" >&6; } +ac_res=$ac_cv_search_login_tty +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define HAVE_LOGIN_TTY 1" >>confdefs.h + + +fi + for ac_func in forkpty do : ac_fn_c_check_func "$LINENO" "forkpty" "ac_cv_func_forkpty" @@ -14380,11 +18948,89 @@ fi done -# We search for both crypt and crypt_r as one or the other may be defined -# This gets us our -lcrypt in LIBS when required on the target platform. -# Save/restore LIBS to avoid linking libpython with libcrypt. -LIBS_SAVE=$LIBS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt_r" >&5 +# check for namespace functions +for ac_func in setns unshare +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBCRYPT" >&5 +$as_echo_n "checking for LIBCRYPT... " >&6; } + +if test -n "$LIBCRYPT_CFLAGS"; then + pkg_cv_LIBCRYPT_CFLAGS="$LIBCRYPT_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxcrypt >= 3.1.1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libxcrypt >= 3.1.1") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBCRYPT_CFLAGS=`$PKG_CONFIG --cflags "libxcrypt >= 3.1.1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBCRYPT_LIBS"; then + pkg_cv_LIBCRYPT_LIBS="$LIBCRYPT_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxcrypt >= 3.1.1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libxcrypt >= 3.1.1") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBCRYPT_LIBS=`$PKG_CONFIG --libs "libxcrypt >= 3.1.1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBCRYPT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libxcrypt >= 3.1.1" 2>&1` + else + LIBCRYPT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libxcrypt >= 3.1.1" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBCRYPT_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt_r" >&5 $as_echo_n "checking for library containing crypt_r... " >&6; } if ${ac_cv_search_crypt_r+:} false; then : $as_echo_n "(cached) " >&6 @@ -14438,12 +19084,38 @@ ac_res=$ac_cv_search_crypt_r if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + $as_echo "#define HAVE_CRYPT_R 1" >>confdefs.h + + if test "$ac_cv_search_crypt_r" = "none required"; then + libcrypt= + else + libcrypt="$ac_cv_search_crypt_r" + fi + LIBCRYPT_LIBS=${LIBCRYPT_LIBS-$libcrypt} + fi -LIBS="$LIBS_SAVE" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt" >&5 -$as_echo_n "checking for library containing crypt... " >&6; } -if ${ac_cv_search_crypt+:} false; then : + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt_r" >&5 +$as_echo_n "checking for library containing crypt_r... " >&6; } +if ${ac_cv_search_crypt_r+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS @@ -14456,11 +19128,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char crypt (); +char crypt_r (); int main () { -return crypt (); +return crypt_r (); ; return 0; } @@ -14473,59 +19145,113 @@ for ac_lib in '' crypt; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_crypt=$ac_res + ac_cv_search_crypt_r=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext - if ${ac_cv_search_crypt+:} false; then : + if ${ac_cv_search_crypt_r+:} false; then : break fi done -if ${ac_cv_search_crypt+:} false; then : +if ${ac_cv_search_crypt_r+:} false; then : else - ac_cv_search_crypt=no + ac_cv_search_crypt_r=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt" >&5 -$as_echo "$ac_cv_search_crypt" >&6; } -ac_res=$ac_cv_search_crypt +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt_r" >&5 +$as_echo "$ac_cv_search_crypt_r" >&6; } +ac_res=$ac_cv_search_crypt_r if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + $as_echo "#define HAVE_CRYPT_R 1" >>confdefs.h + + if test "$ac_cv_search_crypt_r" = "none required"; then + libcrypt= + else + libcrypt="$ac_cv_search_crypt_r" + fi + LIBCRYPT_LIBS=${LIBCRYPT_LIBS-$libcrypt} + fi -ac_fn_c_check_func "$LINENO" "crypt_r" "ac_cv_func_crypt_r" -if test "x$ac_cv_func_crypt_r" = xyes; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + LIBCRYPT_CFLAGS=$pkg_cv_LIBCRYPT_CFLAGS + LIBCRYPT_LIBS=$pkg_cv_LIBCRYPT_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + $as_echo "#define HAVE_CRYPT_R 1" >>confdefs.h + + +fi + +save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBCRYPT_CFLAGS" + LIBS="$LIBCRYPT_LIBS $LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt or crypt_r" >&5 +$as_echo_n "checking for crypt or crypt_r... " >&6; } +if ${ac_cv_crypt_crypt+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include + #ifdef HAVE_CRYPT_H + #include + #endif + #include int main () { -struct crypt_data d; -char *r = crypt_r("", "", &d); + #ifdef HAVE_CRYPT_R + void *x = crypt_r; + #else + void *x = crypt; + #endif ; return 0; } + _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -$as_echo "#define HAVE_CRYPT_R 1" >>confdefs.h +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_crypt_crypt=yes +else + ac_cv_crypt_crypt=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_crypt_crypt" >&5 +$as_echo "$ac_cv_crypt_crypt" >&6; } + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS -fi -LIBS=$LIBS_SAVE for ac_func in clock_gettime do : @@ -14932,7 +19658,7 @@ else #include #include -int main() +int main(void) { int passive, gaierr, inet4 = 0, inet6 = 0; struct addrinfo hints, *ai, *aitop; @@ -15033,12 +19759,11 @@ fi if test "$ac_cv_func_getaddrinfo" = no -o "$ac_cv_buggy_getaddrinfo" = yes then - if test $ipv6 = yes - then - echo 'Fatal: You must get working getaddrinfo() function.' - echo ' or you can specify "--disable-ipv6"'. - exit 1 - fi + if test "x$ipv6" = xyes; then : + + as_fn_error $? "You must get working getaddrinfo() function or pass the \"--disable-ipv6\" option to configure." "$LINENO" 5 + +fi else $as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h @@ -15401,39 +20126,6 @@ fi # checks for compiler characteristics -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether char is unsigned" >&5 -$as_echo_n "checking whether char is unsigned... " >&6; } -if ${ac_cv_c_char_unsigned+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((char) -1) < 0)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_char_unsigned=no -else - ac_cv_c_char_unsigned=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_char_unsigned" >&5 -$as_echo "$ac_cv_c_char_unsigned" >&6; } -if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then - $as_echo "#define __CHAR_UNSIGNED__ 1" >>confdefs.h - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : @@ -15584,52 +20276,6 @@ if test "x$ac_cv_function_prototypes" = xyes; then : $as_echo "#define HAVE_PROTOTYPES 1" >>confdefs.h -fi - -works=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for variable length prototypes and stdarg.h" >&5 -$as_echo_n "checking for variable length prototypes and stdarg.h... " >&6; } -if ${ac_cv_stdarg_prototypes+:} false; then : - $as_echo_n "(cached) " >&6 -else - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -int foo(int x, ...) { - va_list va; - va_start(va, x); - va_arg(va, int); - va_arg(va, char *); - va_arg(va, double); - return 0; -} - -int -main () -{ -return foo(10, "", 3.14); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_stdarg_prototypes=yes -else - ac_cv_stdarg_prototypes=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_stdarg_prototypes" >&5 -$as_echo "$ac_cv_stdarg_prototypes" >&6; } -if test "x$ac_cv_stdarg_prototypes" = xyes; then : - - -$as_echo "#define HAVE_STDARG_PROTOTYPES 1" >>confdefs.h - - fi @@ -16191,7 +20837,7 @@ fi # rounding issues. The result of this test has little meaning on non # IEEE 754 platforms. On IEEE 754, test should return 1 if rounding # mode is round-to-nearest and double rounding issues are present, and -# 0 otherwise. See http://bugs.python.org/issue2937 for more info. +# 0 otherwise. See https://github.com/python/cpython/issues/47186 for more info. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for x87-style double rounding" >&5 $as_echo_n "checking for x87-style double rounding... " >&6; } if ${ac_cv_x87_double_rounding+:} false; then : @@ -16209,7 +20855,7 @@ else #include #include -int main() { +int main(void) { volatile double x, y, z; /* 1./(1-2**-53) -> 1+2**-52 (correct), 1.0 (double rounding) */ x = 0.99999999999999989; /* 1-2**-53 */ @@ -16274,11 +20920,6 @@ done LIBS=$LIBS_SAVE -# For multiprocessing module, check that sem_open -# actually works. For FreeBSD versions <= 7.2, -# the kernel module that provides POSIX semaphores -# isn't loaded by default, so an attempt to call -# sem_open results in a 'Signal 12' error. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether POSIX semaphores are enabled" >&5 $as_echo_n "checking whether POSIX semaphores are enabled... " >&6; } if ${ac_cv_posix_semaphores_enabled+:} false; then : @@ -16290,22 +20931,24 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -#include -#include -#include -int main(void) { - sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); - if (a == SEM_FAILED) { - perror("sem_open"); - return 1; - } - sem_close(a); - sem_unlink("/autoconf"); - return 0; -} + #include + #include + #include + #include + #include + + int main(void) { + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + if (a == SEM_FAILED) { + perror("sem_open"); + return 1; + } + sem_close(a); + sem_unlink("/autoconf"); + return 0; + } + _ACEOF if ac_fn_c_try_run "$LINENO"; then : @@ -16321,14 +20964,14 @@ fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_posix_semaphores_enabled" >&5 $as_echo "$ac_cv_posix_semaphores_enabled" >&6; } -if test $ac_cv_posix_semaphores_enabled = no -then +if test "x$ac_cv_posix_semaphores_enabled" = xno; then : + $as_echo "#define POSIX_SEMAPHORES_NOT_ENABLED 1" >>confdefs.h + fi -# Multiprocessing check for broken sem_getvalue { $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken sem_getvalue" >&5 $as_echo_n "checking for broken sem_getvalue... " >&6; } if ${ac_cv_broken_sem_getvalue+:} false; then : @@ -16340,26 +20983,28 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -#include -#include -#include -int main(void){ - sem_t *a = sem_open("/autocftw", O_CREAT, S_IRUSR|S_IWUSR, 0); - int count; - int res; - if(a==SEM_FAILED){ - perror("sem_open"); - return 1; + #include + #include + #include + #include + #include + + int main(void){ + sem_t *a = sem_open("/autocftw", O_CREAT, S_IRUSR|S_IWUSR, 0); + int count; + int res; + if(a==SEM_FAILED){ + perror("sem_open"); + return 1; + + } + res = sem_getvalue(a, &count); + sem_close(a); + sem_unlink("/autocftw"); + return res==-1 ? 1 : 0; + } - } - res = sem_getvalue(a, &count); - sem_close(a); - sem_unlink("/autocftw"); - return res==-1 ? 1 : 0; -} _ACEOF if ac_fn_c_try_run "$LINENO"; then : @@ -16375,11 +21020,12 @@ fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_sem_getvalue" >&5 $as_echo "$ac_cv_broken_sem_getvalue" >&6; } -if test $ac_cv_broken_sem_getvalue = yes -then +if test "x$ac_cv_broken_sem_getvalue" = xyes; then : + $as_echo "#define HAVE_BROKEN_SEM_GETVALUE 1" >>confdefs.h + fi ac_fn_c_check_decl "$LINENO" "RTLD_LAZY" "ac_cv_have_decl_RTLD_LAZY" "#include @@ -16556,36 +21202,6 @@ _ACEOF fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for UCS-4 tcl" >&5 -$as_echo_n "checking for UCS-4 tcl... " >&6; } -have_ucs4_tcl=no -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#if TCL_UTF_MAX != 6 -# error "NOT UCS4_TCL" -#endif -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - -$as_echo "#define HAVE_UCS4_TCL 1" >>confdefs.h - - have_ucs4_tcl=yes - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_ucs4_tcl" >&5 -$as_echo "$have_ucs4_tcl" >&6; } - # check whether wchar_t is signed or not if test "$wchar_h" = yes then @@ -17018,7 +21634,7 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int main() +int main(void) { return (((-1)>>3 == -1) ? 0 : 1); } @@ -17084,48 +21700,116 @@ $as_echo "#define HAVE_GETC_UNLOCKED 1" >>confdefs.h fi + + + # Check whether --with-readline was given. if test "${with_readline+set}" = set; then : withval=$with_readline; + case $with_readline in #( + editline|edit) : + with_readline=edit ;; #( + yes|readline) : + with_readline=readline ;; #( + no) : + ;; #( + *) : + as_fn_error $? "proper usage is --with(out)-readline[=editline|readline|no]" "$LINENO" 5 + ;; +esac + else - with_readline=yes + with_readline=readline + fi -# check where readline lives -py_cv_lib_readline=no -# save the value of LIBS so we don't actually link Python with readline -LIBS_no_readline=$LIBS +if test "x$with_readline" = xreadline; then : -if test "$with_readline" != no; then - case "$with_readline" in - editline|edit) - LIBREADLINE=edit -$as_echo "#define WITH_EDITLINE 1" >>confdefs.h +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBREADLINE" >&5 +$as_echo_n "checking for LIBREADLINE... " >&6; } - ;; - yes|readline) - LIBREADLINE=readline - ;; - *) - as_fn_error $? "proper usage is --with(out)-readline[=editline]" "$LINENO" 5 - ;; - esac +if test -n "$LIBREADLINE_CFLAGS"; then + pkg_cv_LIBREADLINE_CFLAGS="$LIBREADLINE_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"readline\""; } >&5 + ($PKG_CONFIG --exists --print-errors "readline") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBREADLINE_CFLAGS=`$PKG_CONFIG --cflags "readline" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBREADLINE_LIBS"; then + pkg_cv_LIBREADLINE_LIBS="$LIBREADLINE_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"readline\""; } >&5 + ($PKG_CONFIG --exists --print-errors "readline") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBREADLINE_LIBS=`$PKG_CONFIG --libs "readline" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi - # On some systems we need to link readline to a termcap compatible - # library. NOTE: Keep the precedence of listed libraries synchronised - # with setup.py. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link readline libs" >&5 -$as_echo_n "checking how to link readline libs... " >&6; } - for py_libtermcap in "" tinfo ncursesw ncurses curses termcap; do - if test -z "$py_libtermcap"; then - READLINE_LIBS="-l$LIBREADLINE" - else - READLINE_LIBS="-l$LIBREADLINE -l$py_libtermcap" - fi - LIBS="$READLINE_LIBS $LIBS_no_readline" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBREADLINE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "readline" 2>&1` + else + LIBREADLINE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "readline" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBREADLINE_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBREADLINE_CFLAGS" + LDFLAGS="$LDFLAGS $LIBREADLINE_LIBS" + for ac_header in readline/readline.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_readline_readline_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_READLINE_READLINE_H 1 +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +$as_echo_n "checking for readline in -lreadline... " >&6; } +if ${ac_cv_lib_readline_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. @@ -17144,311 +21828,699 @@ return readline (); } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - py_cv_lib_readline=yes + ac_cv_lib_readline_readline=yes +else + ac_cv_lib_readline_readline=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext - if test $py_cv_lib_readline = yes; then - break - fi - done +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +$as_echo "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes; then : - # Uncomment this line if you want to use READLINE_LIBS in Makefile or scripts - #AC_SUBST([READLINE_LIBS]) - if test $py_cv_lib_readline = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 -$as_echo "none" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $READLINE_LIBS" >&5 -$as_echo "$READLINE_LIBS" >&6; } + LIBREADLINE=readline + READLINE_CFLAGS=${LIBREADLINE_CFLAGS-""} + READLINE_LIBS=${LIBREADLINE_LIBS-"-lreadline"} -$as_echo "#define HAVE_LIBREADLINE 1" >>confdefs.h - - fi +else + with_readline=no fi -if test "$py_cv_lib_readline" = yes; then - # check for readline 2.2 - ac_fn_c_check_decl "$LINENO" "rl_completion_append_character" "ac_cv_have_decl_rl_completion_append_character" " -#include /* Must be first for Gnu Readline */ -#ifdef WITH_EDITLINE -# include -#else -# include + +else + with_readline=no +fi + +done + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBREADLINE_CFLAGS" + LDFLAGS="$LDFLAGS $LIBREADLINE_LIBS" + for ac_header in readline/readline.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_readline_readline_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_READLINE_READLINE_H 1 +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +$as_echo_n "checking for readline in -lreadline... " >&6; } +if ${ac_cv_lib_readline_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" #endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_readline_readline=yes +else + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +$as_echo "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes; then : + + LIBREADLINE=readline + READLINE_CFLAGS=${LIBREADLINE_CFLAGS-""} + READLINE_LIBS=${LIBREADLINE_LIBS-"-lreadline"} + +else + with_readline=no +fi + + +else + with_readline=no +fi + +done + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + LIBREADLINE_CFLAGS=$pkg_cv_LIBREADLINE_CFLAGS + LIBREADLINE_LIBS=$pkg_cv_LIBREADLINE_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + LIBREADLINE=readline + READLINE_CFLAGS=$LIBREADLINE_CFLAGS + READLINE_LIBS=$LIBREADLINE_LIBS + +fi + +fi + +if test "x$with_readline" = xedit; then : + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBEDIT" >&5 +$as_echo_n "checking for LIBEDIT... " >&6; } + +if test -n "$LIBEDIT_CFLAGS"; then + pkg_cv_LIBEDIT_CFLAGS="$LIBEDIT_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libedit\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libedit") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBEDIT_CFLAGS=`$PKG_CONFIG --cflags "libedit" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBEDIT_LIBS"; then + pkg_cv_LIBEDIT_LIBS="$LIBEDIT_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libedit\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libedit") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBEDIT_LIBS=`$PKG_CONFIG --libs "libedit" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBEDIT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libedit" 2>&1` + else + LIBEDIT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libedit" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBEDIT_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBEDIT_CFLAGS" + LDFLAGS="$LDFLAGS $LIBEDIT_LIBS" + for ac_header in editline/readline.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "editline/readline.h" "ac_cv_header_editline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_editline_readline_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_EDITLINE_READLINE_H 1 +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -ledit" >&5 +$as_echo_n "checking for readline in -ledit... " >&6; } +if ${ac_cv_lib_edit_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ledit $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_edit_readline=yes +else + ac_cv_lib_edit_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_edit_readline" >&5 +$as_echo "$ac_cv_lib_edit_readline" >&6; } +if test "x$ac_cv_lib_edit_readline" = xyes; then : + + LIBREADLINE=edit + $as_echo "#define WITH_EDITLINE 1" >>confdefs.h + + READLINE_CFLAGS=${LIBEDIT_CFLAGS-""} + READLINE_LIBS=${LIBEDIT_LIBS-"-ledit"} + +else + with_readline=no +fi + + +else + with_readline=no +fi + +done + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBEDIT_CFLAGS" + LDFLAGS="$LDFLAGS $LIBEDIT_LIBS" + for ac_header in editline/readline.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "editline/readline.h" "ac_cv_header_editline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_editline_readline_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_EDITLINE_READLINE_H 1 +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -ledit" >&5 +$as_echo_n "checking for readline in -ledit... " >&6; } +if ${ac_cv_lib_edit_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ledit $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_edit_readline=yes +else + ac_cv_lib_edit_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_edit_readline" >&5 +$as_echo "$ac_cv_lib_edit_readline" >&6; } +if test "x$ac_cv_lib_edit_readline" = xyes; then : + + LIBREADLINE=edit + $as_echo "#define WITH_EDITLINE 1" >>confdefs.h + + READLINE_CFLAGS=${LIBEDIT_CFLAGS-""} + READLINE_LIBS=${LIBEDIT_LIBS-"-ledit"} + +else + with_readline=no +fi + + +else + with_readline=no +fi + +done + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + LIBEDIT_CFLAGS=$pkg_cv_LIBEDIT_CFLAGS + LIBEDIT_LIBS=$pkg_cv_LIBEDIT_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + $as_echo "#define WITH_EDITLINE 1" >>confdefs.h + + LIBREADLINE=edit + READLINE_CFLAGS=$LIBEDIT_CFLAGS + READLINE_LIBS=$LIBEDIT_LIBS + +fi + +fi + +READLINE_CFLAGS=$(echo $READLINE_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link readline" >&5 +$as_echo_n "checking how to link readline... " >&6; } +if test "x$with_readline" = xno; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_readline (CFLAGS: $READLINE_CFLAGS, LIBS: $READLINE_LIBS)" >&5 +$as_echo "$with_readline (CFLAGS: $READLINE_CFLAGS, LIBS: $READLINE_LIBS)" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $READLINE_CFLAGS" + LIBS="$READLINE_LIBS $LIBS" + LIBS_SAVE=$LIBS + + + + # check for readline 2.2 + ac_fn_c_check_decl "$LINENO" "rl_completion_append_character" "ac_cv_have_decl_rl_completion_append_character" " + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif " if test "x$ac_cv_have_decl_rl_completion_append_character" = xyes; then : + $as_echo "#define HAVE_RL_COMPLETION_APPEND_CHARACTER 1" >>confdefs.h + fi - ac_fn_c_check_decl "$LINENO" "rl_completion_suppress_append" "ac_cv_have_decl_rl_completion_suppress_append" " -#include /* Must be first for Gnu Readline */ -#ifdef WITH_EDITLINE -# include -#else -# include -#endif + + ac_fn_c_check_decl "$LINENO" "rl_completion_suppress_append" "ac_cv_have_decl_rl_completion_suppress_append" " + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif " if test "x$ac_cv_have_decl_rl_completion_suppress_append" = xyes; then : + $as_echo "#define HAVE_RL_COMPLETION_SUPPRESS_APPEND 1" >>confdefs.h + fi - # check for readline 4.0 - as_ac_Lib=`$as_echo "ac_cv_lib_$LIBREADLINE''_rl_pre_input_hook" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_pre_input_hook in -l$LIBREADLINE" >&5 + # check for readline 4.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_pre_input_hook in -l$LIBREADLINE" >&5 $as_echo_n "checking for rl_pre_input_hook in -l$LIBREADLINE... " >&6; } -if eval \${$as_ac_Lib+:} false; then : +if ${ac_cv_readline_rl_pre_input_hook+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-l$LIBREADLINE $READLINE_LIBS $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char rl_pre_input_hook (); + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif + int main () { -return rl_pre_input_hook (); +void *x = rl_pre_input_hook ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - eval "$as_ac_Lib=yes" + ac_cv_readline_rl_pre_input_hook=yes else - eval "$as_ac_Lib=no" + ac_cv_readline_rl_pre_input_hook=no + fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + fi -eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_rl_pre_input_hook" >&5 +$as_echo "$ac_cv_readline_rl_pre_input_hook" >&6; } + if test "x$ac_cv_readline_rl_pre_input_hook" = xyes; then : + $as_echo "#define HAVE_RL_PRE_INPUT_HOOK 1" >>confdefs.h + fi - - # also in 4.0 - as_ac_Lib=`$as_echo "ac_cv_lib_$LIBREADLINE''_rl_completion_display_matches_hook" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_completion_display_matches_hook in -l$LIBREADLINE" >&5 + # also in 4.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_completion_display_matches_hook in -l$LIBREADLINE" >&5 $as_echo_n "checking for rl_completion_display_matches_hook in -l$LIBREADLINE... " >&6; } -if eval \${$as_ac_Lib+:} false; then : +if ${ac_cv_readline_rl_completion_display_matches_hook+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-l$LIBREADLINE $READLINE_LIBS $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char rl_completion_display_matches_hook (); + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif + int main () { -return rl_completion_display_matches_hook (); +void *x = rl_completion_display_matches_hook ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - eval "$as_ac_Lib=yes" + ac_cv_readline_rl_completion_display_matches_hook=yes else - eval "$as_ac_Lib=no" + ac_cv_readline_rl_completion_display_matches_hook=no + fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + fi -eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_rl_completion_display_matches_hook" >&5 +$as_echo "$ac_cv_readline_rl_completion_display_matches_hook" >&6; } + if test "x$ac_cv_readline_rl_completion_display_matches_hook" = xyes; then : + $as_echo "#define HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK 1" >>confdefs.h + fi - - # also in 4.0, but not in editline - as_ac_Lib=`$as_echo "ac_cv_lib_$LIBREADLINE''_rl_resize_terminal" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_resize_terminal in -l$LIBREADLINE" >&5 + # also in 4.0, but not in editline + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_resize_terminal in -l$LIBREADLINE" >&5 $as_echo_n "checking for rl_resize_terminal in -l$LIBREADLINE... " >&6; } -if eval \${$as_ac_Lib+:} false; then : +if ${ac_cv_readline_rl_resize_terminal+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-l$LIBREADLINE $READLINE_LIBS $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char rl_resize_terminal (); + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif + int main () { -return rl_resize_terminal (); +void *x = rl_resize_terminal ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - eval "$as_ac_Lib=yes" + ac_cv_readline_rl_resize_terminal=yes else - eval "$as_ac_Lib=no" + ac_cv_readline_rl_resize_terminal=no + fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + fi -eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_rl_resize_terminal" >&5 +$as_echo "$ac_cv_readline_rl_resize_terminal" >&6; } + if test "x$ac_cv_readline_rl_resize_terminal" = xyes; then : + $as_echo "#define HAVE_RL_RESIZE_TERMINAL 1" >>confdefs.h + fi - - # check for readline 4.2 - as_ac_Lib=`$as_echo "ac_cv_lib_$LIBREADLINE''_rl_completion_matches" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_completion_matches in -l$LIBREADLINE" >&5 + # check for readline 4.2 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_completion_matches in -l$LIBREADLINE" >&5 $as_echo_n "checking for rl_completion_matches in -l$LIBREADLINE... " >&6; } -if eval \${$as_ac_Lib+:} false; then : +if ${ac_cv_readline_rl_completion_matches+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-l$LIBREADLINE $READLINE_LIBS $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char rl_completion_matches (); + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif + int main () { -return rl_completion_matches (); +void *x = rl_completion_matches ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - eval "$as_ac_Lib=yes" + ac_cv_readline_rl_completion_matches=yes else - eval "$as_ac_Lib=no" + ac_cv_readline_rl_completion_matches=no + fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + fi -eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_rl_completion_matches" >&5 +$as_echo "$ac_cv_readline_rl_completion_matches" >&6; } + if test "x$ac_cv_readline_rl_completion_matches" = xyes; then : + $as_echo "#define HAVE_RL_COMPLETION_MATCHES 1" >>confdefs.h + fi - - # also in readline 4.2 - ac_fn_c_check_decl "$LINENO" "rl_catch_signals" "ac_cv_have_decl_rl_catch_signals" " -#include /* Must be first for Gnu Readline */ -#ifdef WITH_EDITLINE -# include -#else -# include -#endif + # also in readline 4.2 + ac_fn_c_check_decl "$LINENO" "rl_catch_signals" "ac_cv_have_decl_rl_catch_signals" " + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif " if test "x$ac_cv_have_decl_rl_catch_signals" = xyes; then : + $as_echo "#define HAVE_RL_CATCH_SIGNAL 1" >>confdefs.h + fi - as_ac_Lib=`$as_echo "ac_cv_lib_$LIBREADLINE''_append_history" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for append_history in -l$LIBREADLINE" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for append_history in -l$LIBREADLINE" >&5 $as_echo_n "checking for append_history in -l$LIBREADLINE... " >&6; } -if eval \${$as_ac_Lib+:} false; then : +if ${ac_cv_readline_append_history+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-l$LIBREADLINE $READLINE_LIBS $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char append_history (); + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif + int main () { -return append_history (); +void *x = append_history ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - eval "$as_ac_Lib=yes" + ac_cv_readline_append_history=yes else - eval "$as_ac_Lib=no" + ac_cv_readline_append_history=no + fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + fi -eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_append_history" >&5 +$as_echo "$ac_cv_readline_append_history" >&6; } + if test "x$ac_cv_readline_append_history" = xyes; then : + $as_echo "#define HAVE_RL_APPEND_HISTORY 1" >>confdefs.h -fi fi -# End of readline checks: restore LIBS -LIBS=$LIBS_no_readline + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + +fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken nice()" >&5 $as_echo_n "checking for broken nice()... " >&6; } @@ -17464,7 +22536,7 @@ else #include #include -int main() +int main(void) { int val1 = nice(1); if (val1 != -1 && val1 == nice(2)) @@ -17506,7 +22578,7 @@ else #include #include -int main() +int main(void) { struct pollfd poll_struct = { 42, POLLIN|POLLPRI|POLLOUT, 0 }; int poll_test; @@ -17563,7 +22635,7 @@ else extern char *tzname[]; #endif -int main() +int main(void) { /* Note that we need to ensure that not only does tzset(3) do 'something' with localtime, but it works as documented @@ -17710,11 +22782,9 @@ $as_echo "#define HAVE_STAT_TV_NSEC2 1" >>confdefs.h fi -# first curses header check -ac_save_cppflags="$CPPFLAGS" -if test "$cross_compiling" = no; then - CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw" -fi +have_curses=no +have_panel=no + for ac_header in curses.h ncurses.h do : @@ -17730,6 +22800,856 @@ fi done +if test "x$ac_cv_header_ncurses_h" = xyes; then : + + if test "$ac_sys_system" != "Darwin"; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CURSES" >&5 +$as_echo_n "checking for CURSES... " >&6; } + +if test -n "$CURSES_CFLAGS"; then + pkg_cv_CURSES_CFLAGS="$CURSES_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncursesw\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ncursesw") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CURSES_CFLAGS=`$PKG_CONFIG --cflags "ncursesw" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$CURSES_LIBS"; then + pkg_cv_CURSES_LIBS="$CURSES_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncursesw\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ncursesw") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CURSES_LIBS=`$PKG_CONFIG --libs "ncursesw" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + CURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncursesw" 2>&1` + else + CURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncursesw" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$CURSES_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncursesw" >&5 +$as_echo_n "checking for initscr in -lncursesw... " >&6; } +if ${ac_cv_lib_ncursesw_initscr+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lncursesw $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char initscr (); +int +main () +{ +return initscr (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ncursesw_initscr=yes +else + ac_cv_lib_ncursesw_initscr=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncursesw_initscr" >&5 +$as_echo "$ac_cv_lib_ncursesw_initscr" >&6; } +if test "x$ac_cv_lib_ncursesw_initscr" = xyes; then : + + $as_echo "#define HAVE_NCURSESW 1" >>confdefs.h + + have_curses=ncursesw + CURSES_CFLAGS=${CURSES_CFLAGS-""} + CURSES_LIBS=${CURSES_LIBS-"-lncursesw"} + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncursesw" >&5 +$as_echo_n "checking for initscr in -lncursesw... " >&6; } +if ${ac_cv_lib_ncursesw_initscr+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lncursesw $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char initscr (); +int +main () +{ +return initscr (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ncursesw_initscr=yes +else + ac_cv_lib_ncursesw_initscr=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncursesw_initscr" >&5 +$as_echo "$ac_cv_lib_ncursesw_initscr" >&6; } +if test "x$ac_cv_lib_ncursesw_initscr" = xyes; then : + + $as_echo "#define HAVE_NCURSESW 1" >>confdefs.h + + have_curses=ncursesw + CURSES_CFLAGS=${CURSES_CFLAGS-""} + CURSES_LIBS=${CURSES_LIBS-"-lncursesw"} + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS + CURSES_LIBS=$pkg_cv_CURSES_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + $as_echo "#define HAVE_NCURSESW 1" >>confdefs.h + + have_curses=ncursesw + +fi + fi + + if test "x$have_curses" = xno; then : + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CURSES" >&5 +$as_echo_n "checking for CURSES... " >&6; } + +if test -n "$CURSES_CFLAGS"; then + pkg_cv_CURSES_CFLAGS="$CURSES_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncurses\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ncurses") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CURSES_CFLAGS=`$PKG_CONFIG --cflags "ncurses" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$CURSES_LIBS"; then + pkg_cv_CURSES_LIBS="$CURSES_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncurses\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ncurses") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CURSES_LIBS=`$PKG_CONFIG --libs "ncurses" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + CURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncurses" 2>&1` + else + CURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncurses" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$CURSES_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncurses" >&5 +$as_echo_n "checking for initscr in -lncurses... " >&6; } +if ${ac_cv_lib_ncurses_initscr+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lncurses $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char initscr (); +int +main () +{ +return initscr (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ncurses_initscr=yes +else + ac_cv_lib_ncurses_initscr=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_initscr" >&5 +$as_echo "$ac_cv_lib_ncurses_initscr" >&6; } +if test "x$ac_cv_lib_ncurses_initscr" = xyes; then : + + have_curses=ncurses + CURSES_CFLAGS=${CURSES_CFLAGS-""} + CURSES_LIBS=${CURSES_LIBS-"-lncurses"} + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncurses" >&5 +$as_echo_n "checking for initscr in -lncurses... " >&6; } +if ${ac_cv_lib_ncurses_initscr+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lncurses $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char initscr (); +int +main () +{ +return initscr (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ncurses_initscr=yes +else + ac_cv_lib_ncurses_initscr=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_initscr" >&5 +$as_echo "$ac_cv_lib_ncurses_initscr" >&6; } +if test "x$ac_cv_lib_ncurses_initscr" = xyes; then : + + have_curses=ncurses + CURSES_CFLAGS=${CURSES_CFLAGS-""} + CURSES_LIBS=${CURSES_LIBS-"-lncurses"} + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS + CURSES_LIBS=$pkg_cv_CURSES_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + have_curses=ncurses + +fi + +fi + + +fi +CURSES_CFLAGS=$(echo $CURSES_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') + +if test "$have_curses" = no -a "$ac_sys_system" = "Darwin"; then + + as_fn_append CURSES_CFLAGS " -D_XOPEN_SOURCE_EXTENDED=1" + $as_echo "#define HAVE_NCURSESW 1" >>confdefs.h + +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking curses module flags" >&5 +$as_echo_n "checking curses module flags... " >&6; } +if test "x$have_curses" = xno; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_curses (CFLAGS: $CURSES_CFLAGS, LIBS: $CURSES_LIBS)" >&5 +$as_echo "$have_curses (CFLAGS: $CURSES_CFLAGS, LIBS: $CURSES_LIBS)" >&6; } + +fi + +for ac_header in panel.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "panel.h" "ac_cv_header_panel_h" "$ac_includes_default" +if test "x$ac_cv_header_panel_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_PANEL_H 1 +_ACEOF + +fi + +done + + +if test "x$ac_cv_header_panel_h" = xyes; then : + + + if test "$ac_sys_system" != "Darwin"; then + if test "x$have_curses" = xncursesw; then : + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PANEL" >&5 +$as_echo_n "checking for PANEL... " >&6; } + +if test -n "$PANEL_CFLAGS"; then + pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panelw\""; } >&5 + ($PKG_CONFIG --exists --print-errors "panelw") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "panelw" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PANEL_LIBS"; then + pkg_cv_PANEL_LIBS="$PANEL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panelw\""; } >&5 + ($PKG_CONFIG --exists --print-errors "panelw") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "panelw" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "panelw" 2>&1` + else + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "panelw" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for update_panels in -lpanelw" >&5 +$as_echo_n "checking for update_panels in -lpanelw... " >&6; } +if ${ac_cv_lib_panelw_update_panels+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpanelw $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char update_panels (); +int +main () +{ +return update_panels (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_panelw_update_panels=yes +else + ac_cv_lib_panelw_update_panels=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_panelw_update_panels" >&5 +$as_echo "$ac_cv_lib_panelw_update_panels" >&6; } +if test "x$ac_cv_lib_panelw_update_panels" = xyes; then : + + have_panel=panelw + PANEL_CFLAGS=${PANEL_CFLAGS-""} + PANEL_LIBS=${PANEL_LIBS-"-lpanelw"} + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for update_panels in -lpanelw" >&5 +$as_echo_n "checking for update_panels in -lpanelw... " >&6; } +if ${ac_cv_lib_panelw_update_panels+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpanelw $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char update_panels (); +int +main () +{ +return update_panels (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_panelw_update_panels=yes +else + ac_cv_lib_panelw_update_panels=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_panelw_update_panels" >&5 +$as_echo "$ac_cv_lib_panelw_update_panels" >&6; } +if test "x$ac_cv_lib_panelw_update_panels" = xyes; then : + + have_panel=panelw + PANEL_CFLAGS=${PANEL_CFLAGS-""} + PANEL_LIBS=${PANEL_LIBS-"-lpanelw"} + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + have_panel=panelw + +fi + +fi + fi + + if test "x$have_curses" = xncurses; then : + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PANEL" >&5 +$as_echo_n "checking for PANEL... " >&6; } + +if test -n "$PANEL_CFLAGS"; then + pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "panel") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "panel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PANEL_LIBS"; then + pkg_cv_PANEL_LIBS="$PANEL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "panel") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "panel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "panel" 2>&1` + else + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "panel" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for update_panels in -lpanel" >&5 +$as_echo_n "checking for update_panels in -lpanel... " >&6; } +if ${ac_cv_lib_panel_update_panels+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpanel $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char update_panels (); +int +main () +{ +return update_panels (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_panel_update_panels=yes +else + ac_cv_lib_panel_update_panels=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_panel_update_panels" >&5 +$as_echo "$ac_cv_lib_panel_update_panels" >&6; } +if test "x$ac_cv_lib_panel_update_panels" = xyes; then : + + have_panel=panel + PANEL_CFLAGS=${PANEL_CFLAGS-""} + PANEL_LIBS=${PANEL_LIBS-"-lpanel"} + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for update_panels in -lpanel" >&5 +$as_echo_n "checking for update_panels in -lpanel... " >&6; } +if ${ac_cv_lib_panel_update_panels+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpanel $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char update_panels (); +int +main () +{ +return update_panels (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_panel_update_panels=yes +else + ac_cv_lib_panel_update_panels=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_panel_update_panels" >&5 +$as_echo "$ac_cv_lib_panel_update_panels" >&6; } +if test "x$ac_cv_lib_panel_update_panels" = xyes; then : + + have_panel=panel + PANEL_CFLAGS=${PANEL_CFLAGS-""} + PANEL_LIBS=${PANEL_LIBS-"-lpanel"} + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + have_panel=panel + +fi + +fi + + +fi +PANEL_CFLAGS=$(echo $PANEL_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking panel flags" >&5 +$as_echo_n "checking panel flags... " >&6; } +if test "x$have_panel" = xno; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_panel (CFLAGS: $PANEL_CFLAGS, LIBS: $PANEL_LIBS)" >&5 +$as_echo "$have_panel (CFLAGS: $PANEL_CFLAGS, LIBS: $PANEL_LIBS)" >&6; } + +fi + +# first curses header check +ac_save_cppflags="$CPPFLAGS" +if test "$cross_compiling" = no; then + CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw" +fi + # On Solaris, term.h requires curses.h for ac_header in term.h do : @@ -18348,72 +24268,6 @@ then LIBS="$LIBS -framework CoreFoundation" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for %zd printf() format support" >&5 -$as_echo_n "checking for %zd printf() format support... " >&6; } -if ${ac_cv_have_size_t_format+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_have_size_t_format="cross -- assuming yes" - -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include -#include - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_SSIZE_T -typedef ssize_t Py_ssize_t; -#elif SIZEOF_VOID_P == SIZEOF_LONG -typedef long Py_ssize_t; -#else -typedef int Py_ssize_t; -#endif - -int main() -{ - char buffer[256]; - - if(sprintf(buffer, "%zd", (size_t)123) < 0) - return 1; - - if (strcmp(buffer, "123")) - return 1; - - if (sprintf(buffer, "%zd", (Py_ssize_t)-123) < 0) - return 1; - - if (strcmp(buffer, "-123")) - return 1; - - return 0; -} - -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_have_size_t_format=yes -else - ac_cv_have_size_t_format=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_size_t_format" >&5 -$as_echo "$ac_cv_have_size_t_format" >&6; } -if test "$ac_cv_have_size_t_format" != no ; then - -$as_echo "#define PY_FORMAT_SIZE_T \"z\"" >>confdefs.h - -fi - ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" " #ifdef HAVE_SYS_TYPES_H #include @@ -18443,9 +24297,10 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#include #include -#include -int main() { +#include +int main(void) { size_t len = -1; const char *str = "text"; len = mbstowcs(NULL, str, 0); @@ -18573,6 +24428,8 @@ SRCDIRS="\ Modules/_multiprocessing \ Modules/_sha3 \ Modules/_sqlite \ + Modules/_sre \ + Modules/_testcapi \ Modules/_xxtestfuzz \ Modules/cjkcodecs \ Modules/expat \ @@ -18580,6 +24437,7 @@ SRCDIRS="\ Parser \ Programs \ Python \ + Python/frozen_modules \ Python/deepfreeze" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build directories" >&5 $as_echo_n "checking for build directories... " >&6; } @@ -18642,7 +24500,7 @@ else #include #include void foo(void *p, void *q) { memmove(p, q, 19); } -int main() { +int main(void) { char a[32] = "123456789000000000"; foo(&a[9], a); if (strcmp(a, "123456789123456789000000000") != 0) @@ -18697,7 +24555,7 @@ else ); return r; } - int main() { + int main(void) { int p = 8; if ((foo(&p) ? : p) != 6) return 1; @@ -18740,7 +24598,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #include atomic_int int_var; atomic_uintptr_t uintptr_var; - int main() { + int main(void) { atomic_store_explicit(&int_var, 5, memory_order_relaxed); atomic_store_explicit(&uintptr_var, 0, memory_order_relaxed); int loaded_value = atomic_load_explicit(&int_var, memory_order_seq_cst); @@ -18781,7 +24639,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext int val; - int main() { + int main(void) { __atomic_store_n(&val, 1, __ATOMIC_SEQ_CST); (void)__atomic_load_n(&val, __ATOMIC_SEQ_CST); return 0; @@ -18817,7 +24675,17 @@ $as_echo_n "checking for ensurepip... " >&6; } if test "${with_ensurepip+set}" = set; then : withval=$with_ensurepip; else - with_ensurepip=upgrade + + case $ac_sys_system in #( + Emscripten) : + with_ensurepip=no ;; #( + WASI) : + with_ensurepip=no ;; #( + *) : + with_ensurepip=upgrade + ;; +esac + fi case $with_ensurepip in #( @@ -18847,7 +24715,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #include - int main() { + int main(void) { struct dirent entry; return entry.d_type == DT_UNKNOWN; } @@ -18885,11 +24753,12 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ + #include #include #include #include - int main() { + int main(void) { char buffer[1]; const size_t buflen = sizeof(buffer); const int flags = GRND_NONBLOCK; @@ -18932,9 +24801,10 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ + #include #include - int main() { + int main(void) { char buffer[1]; const size_t buflen = sizeof(buffer); const int flags = 0; @@ -18967,9 +24837,14 @@ fi # checks for POSIX shared memory, used by Modules/_multiprocessing/posixshmem.c # shm_* may only be available if linking against librt -save_LIBS="$LIBS" -save_includes_default="$ac_includes_default" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing shm_open" >&5 +POSIXSHMEM_CFLAGS='-I$(srcdir)/Modules/_multiprocessing' +save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing shm_open" >&5 $as_echo_n "checking for library containing shm_open... " >&6; } if ${ac_cv_search_shm_open+:} false; then : $as_echo_n "(cached) " >&6 @@ -19025,33 +24900,20 @@ if test "$ac_res" != no; then : fi -if test "$ac_cv_search_shm_open" = "-lrt"; then - -$as_echo "#define SHM_NEEDS_LIBRT 1" >>confdefs.h - -fi -for ac_header in sys/mman.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_mman_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SYS_MMAN_H 1 -_ACEOF - + if test "x$ac_cv_search_shm_open" = x-lrt; then : + POSIXSHMEM_LIBS="-lrt" fi -done - -# temporarily override ac_includes_default for AC_CHECK_FUNCS below -ac_includes_default="\ -${ac_includes_default} -#ifndef __cplusplus -# ifdef HAVE_SYS_MMAN_H -# include -# endif -#endif -" -for ac_func in shm_open shm_unlink + save_ac_includes_default=$ac_includes_default + ac_includes_default="\ + ${ac_includes_default} + #ifndef __cplusplus + # ifdef HAVE_SYS_MMAN_H + # include + # endif + #endif + " + for ac_func in shm_open shm_unlink do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -19059,13 +24921,20 @@ if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF - + have_posix_shmem=yes +else + have_posix_shmem=no fi done -# we don't want to link with librt always, restore LIBS -LIBS="$save_LIBS" -ac_includes_default="$save_includes_default" + ac_includes_default=$save_ac_includes_default + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + # Check for usable OpenSSL @@ -19273,6 +25142,16 @@ rm -f core conftest.err conftest.$ac_objext \ # rpath to libssl and libcrypto +if test "x$GNULD" = xyes; then : + + rpath_arg="-Wl,--enable-new-dtags,-rpath=" + +else + + rpath_arg="-Wl,-rpath=" + +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-openssl-rpath" >&5 $as_echo_n "checking for --with-openssl-rpath... " >&6; } @@ -19286,12 +25165,26 @@ fi case $with_openssl_rpath in #( auto|yes) : - OPENSSL_RPATH=auto ;; #( + + OPENSSL_RPATH=auto + for arg in "$OPENSSL_LDFLAGS"; do + case $arg in #( + -L*) : + OPENSSL_LDFLAGS_RPATH="$OPENSSL_LDFLAGS_RPATH ${rpath_arg}$(echo $arg | cut -c3-)" + ;; #( + *) : + ;; +esac + done + ;; #( no) : OPENSSL_RPATH= ;; #( *) : if test -d "$with_openssl_rpath"; then : - OPENSSL_RPATH="$with_openssl_rpath" + + OPENSSL_RPATH="$with_openssl_rpath" + OPENSSL_LDFLAGS_RPATH="${rpath_arg}$with_openssl_rpath" + else as_fn_error $? "--with-openssl-rpath \"$with_openssl_rpath\" is not a directory" "$LINENO" 5 fi @@ -19301,72 +25194,163 @@ esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OPENSSL_RPATH" >&5 $as_echo "$OPENSSL_RPATH" >&6; } +# This static linking is NOT OFFICIALLY SUPPORTED and not advertised. +# Requires static OpenSSL build with position-independent code. Some features +# like DSO engines or external OSSL providers don't work. Only tested with GCC +# and clang on X86_64. +if test "x$PY_UNSUPPORTED_OPENSSL_BUILD" = xstatic; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsupported static openssl build" >&5 +$as_echo_n "checking for unsupported static openssl build... " >&6; } + new_OPENSSL_LIBS= + for arg in $OPENSSL_LIBS; do + case $arg in #( + -l*) : + + libname=$(echo $arg | cut -c3-) + new_OPENSSL_LIBS="$new_OPENSSL_LIBS -l:lib${libname}.a -Wl,--exclude-libs,lib${libname}.a" + ;; #( + *) : + new_OPENSSL_LIBS="$new_OPENSSL_LIBS $arg" + ;; +esac + done + OPENSSL_LIBS="$new_OPENSSL_LIBS $ZLIB_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OPENSSL_LIBS" >&5 +$as_echo "$OPENSSL_LIBS" >&6; } + +fi + +LIBCRYPTO_LIBS= +for arg in $OPENSSL_LIBS; do + case $arg in #( + -l*ssl*|-Wl*ssl*) : + ;; #( + *) : + LIBCRYPTO_LIBS="$LIBCRYPTO_LIBS $arg" + ;; +esac +done # check if OpenSSL libraries work as expected -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL provides required APIs" >&5 -$as_echo_n "checking whether OpenSSL provides required APIs... " >&6; } -if ${ac_cv_working_openssl+:} false; then : +save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + LIBS="$LIBS $OPENSSL_LIBS" + CFLAGS="$CFLAGS $OPENSSL_INCLUDES" + LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL provides required ssl module APIs" >&5 +$as_echo_n "checking whether OpenSSL provides required ssl module APIs... " >&6; } +if ${ac_cv_working_openssl_ssl+:} false; then : $as_echo_n "(cached) " >&6 else -save_LIBS="$LIBS" -save_CFLAGS="$CFLAGS" -save_LDFLAGS="$LDFLAGS" -LIBS="$LIBS $OPENSSL_LIBS" -CFLAGS="$CFLAGS_NODIST $OPENSSL_INCLUDES" -LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS" - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -#include - -#if OPENSSL_VERSION_NUMBER < 0x10101000L -#error "OpenSSL >= 1.1.1 is required" -#endif - -static void keylog_cb(const SSL *ssl, const char *line) {} + #include + #include + #if OPENSSL_VERSION_NUMBER < 0x10101000L + #error "OpenSSL >= 1.1.1 is required" + #endif + static void keylog_cb(const SSL *ssl, const char *line) {} int main () { -/* SSL APIs */ -SSL_CTX *ctx = SSL_CTX_new(TLS_client_method()); -SSL_CTX_set_keylog_callback(ctx, keylog_cb); -SSL *ssl = SSL_new(ctx); -X509_VERIFY_PARAM *param = SSL_get0_param(ssl); -X509_VERIFY_PARAM_set1_host(param, "python.org", 0); -SSL_free(ssl); -SSL_CTX_free(ctx); - -/* hashlib APIs */ -OBJ_nid2sn(NID_md5); -OBJ_nid2sn(NID_sha1); -OBJ_nid2sn(NID_sha3_512); -OBJ_nid2sn(NID_blake2b512); -EVP_PBE_scrypt(NULL, 0, NULL, 0, 2, 8, 1, 0, NULL, 0); + SSL_CTX *ctx = SSL_CTX_new(TLS_client_method()); + SSL_CTX_set_keylog_callback(ctx, keylog_cb); + SSL *ssl = SSL_new(ctx); + X509_VERIFY_PARAM *param = SSL_get0_param(ssl); + X509_VERIFY_PARAM_set1_host(param, "python.org", 0); + SSL_free(ssl); + SSL_CTX_free(ctx); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_working_openssl=yes + ac_cv_working_openssl_ssl=yes else - ac_cv_working_openssl=no + ac_cv_working_openssl_ssl=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -LIBS="$save_LIBS" -CFLAGS="$save_CFLAGS" -LDFLAGS="$save_LDFLAGS" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_openssl" >&5 -$as_echo "$ac_cv_working_openssl" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_openssl_ssl" >&5 +$as_echo "$ac_cv_working_openssl_ssl" >&6; } + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + LIBS="$LIBS $LIBCRYPTO_LIBS" + CFLAGS="$CFLAGS $OPENSSL_INCLUDES" + LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL provides required hashlib module APIs" >&5 +$as_echo_n "checking whether OpenSSL provides required hashlib module APIs... " >&6; } +if ${ac_cv_working_openssl_hashlib+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + #if OPENSSL_VERSION_NUMBER < 0x10101000L + #error "OpenSSL >= 1.1.1 is required" + #endif + +int +main () +{ + + OBJ_nid2sn(NID_md5); + OBJ_nid2sn(NID_sha1); + OBJ_nid2sn(NID_sha3_512); + OBJ_nid2sn(NID_blake2b512); + EVP_PBE_scrypt(NULL, 0, NULL, 0, 2, 8, 1, 0, NULL, 0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_working_openssl_hashlib=yes +else + ac_cv_working_openssl_hashlib=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_openssl_hashlib" >&5 +$as_echo "$ac_cv_working_openssl_hashlib" >&6; } + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + # ssl module default cipher suite string @@ -19465,64 +25449,87 @@ esac done IFS=$as_save_IFS -# --with-experimental-isolated-subinterpreters +if test "x$with_builtin_blake2" = xyes; then : -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-experimental-isolated-subinterpreters" >&5 -$as_echo_n "checking for --with-experimental-isolated-subinterpreters... " >&6; } -# Check whether --with-experimental-isolated-subinterpreters was given. -if test "${with_experimental_isolated_subinterpreters+set}" = set; then : - withval=$with_experimental_isolated_subinterpreters; -if test "$withval" != no -then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; }; - $as_echo "#define EXPERIMENTAL_ISOLATED_SUBINTERPRETERS 1" >>confdefs.h +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBB2" >&5 +$as_echo_n "checking for LIBB2... " >&6; } +if test -n "$LIBB2_CFLAGS"; then + pkg_cv_LIBB2_CFLAGS="$LIBB2_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libb2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libb2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBB2_CFLAGS=`$PKG_CONFIG --cflags "libb2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; }; + pkg_failed=yes fi + else + pkg_failed=untried +fi +if test -n "$LIBB2_LIBS"; then + pkg_cv_LIBB2_LIBS="$LIBB2_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libb2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libb2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBB2_LIBS=`$PKG_CONFIG --libs "libb2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } -fi - -# --with-static-libpython -STATIC_LIBPYTHON=1 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-static-libpython" >&5 -$as_echo_n "checking for --with-static-libpython... " >&6; } - -# Check whether --with-static-libpython was given. -if test "${with_static_libpython+set}" = set; then : - withval=$with_static_libpython; -if test "$withval" = no -then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; }; - STATIC_LIBPYTHON=0 +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; }; + _pkg_short_errors_supported=no fi + if test $_pkg_short_errors_supported = yes; then + LIBB2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libb2" 2>&1` + else + LIBB2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libb2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBB2_PKG_ERRORS" >&5 + + have_libb2=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + have_libb2=no else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + LIBB2_CFLAGS=$pkg_cv_LIBB2_CFLAGS + LIBB2_LIBS=$pkg_cv_LIBB2_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } + + have_libb2=yes + +$as_echo "#define HAVE_LIBB2 1" >>confdefs.h + + fi -LIBRARY_DEPS='$(PY3LIBRARY) $(EXPORTSYMS)' -if test "$PY_ENABLE_SHARED" = 1 || test "$enable_framework" ; then - LIBRARY_DEPS="\$(LDLIBRARY) $LIBRARY_DEPS" - if test "$STATIC_LIBPYTHON" = 1; then - LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS" - fi -else - LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS" fi - - # Check whether to disable test modules. Once set, setup.py will not build # test extension modules and "make install" will not install test suites. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --disable-test-modules" >&5 @@ -19530,38 +25537,141 @@ $as_echo_n "checking for --disable-test-modules... " >&6; } # Check whether --enable-test-modules was given. if test "${enable_test_modules+set}" = set; then : enableval=$enable_test_modules; -fi - -if test "$enable_test_modules" = no; then - TEST_MODULES=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + if test "x$enable_test_modules" = xyes; then : + TEST_MODULES=yes else - TEST_MODULES=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + TEST_MODULES=no fi +else + case $ac_sys_system/$ac_sys_emscripten_target in #( + Emscripten/browser*) : + TEST_MODULES=no ;; #( + *) : + TEST_MODULES=yes + ;; +esac + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEST_MODULES" >&5 +$as_echo "$TEST_MODULES" >&6; } + + + + +# stdlib not available case $ac_sys_system in #( AIX) : - py_stdlib_not_available="_scproxy spwd" ;; #( + + + py_cv_module__scproxy=n/a + py_cv_module_spwd=n/a + ;; #( VxWorks*) : - py_stdlib_not_available="_scproxy _crypt termios grp" ;; #( + + + py_cv_module__scproxy=n/a + py_cv_module__crypt=n/a + py_cv_module_termios=n/a + py_cv_module_grp=n/a + ;; #( Darwin) : - py_stdlib_not_available="ossaudiodev spwd" ;; #( + + + py_cv_module_ossaudiodev=n/a + py_cv_module_spwd=n/a + ;; #( CYGWIN*) : - py_stdlib_not_available="_scproxy nis" ;; #( + + + py_cv_module__scproxy=n/a + py_cv_module_nis=n/a + ;; #( QNX*) : - py_stdlib_not_available="_scproxy nis" ;; #( + + + py_cv_module__scproxy=n/a + py_cv_module_nis=n/a + ;; #( FreeBSD*) : - py_stdlib_not_available="_scproxy spwd" ;; #( + + + py_cv_module__scproxy=n/a + py_cv_module_spwd=n/a + ;; #( + Emscripten|WASI) : + + + + py_cv_module__curses=n/a + py_cv_module__curses_panel=n/a + py_cv_module__dbm=n/a + py_cv_module__gdbm=n/a + py_cv_module__multiprocessing=n/a + py_cv_module__posixshmem=n/a + py_cv_module__posixsubprocess=n/a + py_cv_module__scproxy=n/a + py_cv_module__tkinter=n/a + py_cv_module__xxsubinterpreters=n/a + py_cv_module_grp=n/a + py_cv_module_nis=n/a + py_cv_module_ossaudiodev=n/a + py_cv_module_pwd=n/a + py_cv_module_resource=n/a + py_cv_module_spwd=n/a + py_cv_module_syslog=n/a + py_cv_module_=n/a + + case $ac_sys_system/$ac_sys_emscripten_target in #( + Emscripten/browser*) : + + + + py_cv_module_fcntl=n/a + py_cv_module_readline=n/a + py_cv_module_termios=n/a + py_cv_module_=n/a + + ;; #( + Emscripten/node*) : + ;; #( + WASI/*) : + + + + py_cv_module__ctypes_test=n/a + py_cv_module_fcntl=n/a + py_cv_module_mmap=n/a + py_cv_module_termios=n/a + py_cv_module_=n/a + + + ;; #( *) : - py_stdlib_not_available="_scproxy" + ;; +esac + ;; #( + *) : + + + py_cv_module__scproxy=n/a + ;; esac +case $host_cpu in #( + wasm32|wasm64) : + MODULE_BUILDTYPE=static ;; #( + *) : + MODULE_BUILDTYPE=${MODULE_BUILDTYPE:-shared} + ;; +esac + + + MODULE_BLOCK= @@ -19569,7 +25679,10 @@ MODULE_BLOCK= - if true; then + if test "$py_cv_module__io" != "n/a"; then : + py_cv_module__io=yes +fi + if test "$py_cv_module__io" = yes; then MODULE__IO_TRUE= MODULE__IO_FALSE='#' else @@ -19577,13 +25690,19 @@ else MODULE__IO_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__IO_STATE=$py_cv_module__io$as_nl" + if test "x$py_cv_module__io" = xyes; then : as_fn_append MODULE_BLOCK "MODULE__IO_CFLAGS=-I\$(srcdir)/Modules/_io$as_nl" +fi - if true; then + if test "$py_cv_module_time" != "n/a"; then : + py_cv_module_time=yes +fi + if test "$py_cv_module_time" = yes; then MODULE_TIME_TRUE= MODULE_TIME_FALSE='#' else @@ -19591,14 +25710,20 @@ else MODULE_TIME_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE_TIME_STATE=$py_cv_module_time$as_nl" + if test "x$py_cv_module_time" = xyes; then : as_fn_append MODULE_BLOCK "MODULE_TIME_LDFLAGS=$TIMEMODULE_LIB$as_nl" +fi - if true; then + if test "$py_cv_module_array" != "n/a"; then : + py_cv_module_array=yes +fi + if test "$py_cv_module_array" = yes; then MODULE_ARRAY_TRUE= MODULE_ARRAY_FALSE='#' else @@ -19606,11 +25731,19 @@ else MODULE_ARRAY_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE_ARRAY_STATE=$py_cv_module_array$as_nl" + if test "x$py_cv_module_array" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__asyncio" != "n/a"; then : + py_cv_module__asyncio=yes +fi + if test "$py_cv_module__asyncio" = yes; then MODULE__ASYNCIO_TRUE= MODULE__ASYNCIO_FALSE='#' else @@ -19618,11 +25751,19 @@ else MODULE__ASYNCIO_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__ASYNCIO_STATE=$py_cv_module__asyncio$as_nl" + if test "x$py_cv_module__asyncio" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__bisect" != "n/a"; then : + py_cv_module__bisect=yes +fi + if test "$py_cv_module__bisect" = yes; then MODULE__BISECT_TRUE= MODULE__BISECT_FALSE='#' else @@ -19630,11 +25771,19 @@ else MODULE__BISECT_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__BISECT_STATE=$py_cv_module__bisect$as_nl" + if test "x$py_cv_module__bisect" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__contextvars" != "n/a"; then : + py_cv_module__contextvars=yes +fi + if test "$py_cv_module__contextvars" = yes; then MODULE__CONTEXTVARS_TRUE= MODULE__CONTEXTVARS_FALSE='#' else @@ -19642,11 +25791,39 @@ else MODULE__CONTEXTVARS_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__CONTEXTVARS_STATE=$py_cv_module__contextvars$as_nl" + if test "x$py_cv_module__contextvars" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__csv" != "n/a"; then : + py_cv_module__csv=yes +fi + if test "$py_cv_module__csv" = yes; then + MODULE__CSV_TRUE= + MODULE__CSV_FALSE='#' +else + MODULE__CSV_TRUE='#' + MODULE__CSV_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__CSV_STATE=$py_cv_module__csv$as_nl" + if test "x$py_cv_module__csv" = xyes; then : + + + + +fi + + + if test "$py_cv_module__heapq" != "n/a"; then : + py_cv_module__heapq=yes +fi + if test "$py_cv_module__heapq" = yes; then MODULE__HEAPQ_TRUE= MODULE__HEAPQ_FALSE='#' else @@ -19654,11 +25831,19 @@ else MODULE__HEAPQ_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__HEAPQ_STATE=$py_cv_module__heapq$as_nl" + if test "x$py_cv_module__heapq" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__json" != "n/a"; then : + py_cv_module__json=yes +fi + if test "$py_cv_module__json" = yes; then MODULE__JSON_TRUE= MODULE__JSON_FALSE='#' else @@ -19666,11 +25851,19 @@ else MODULE__JSON_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__JSON_STATE=$py_cv_module__json$as_nl" + if test "x$py_cv_module__json" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__lsprof" != "n/a"; then : + py_cv_module__lsprof=yes +fi + if test "$py_cv_module__lsprof" = yes; then MODULE__LSPROF_TRUE= MODULE__LSPROF_FALSE='#' else @@ -19678,11 +25871,19 @@ else MODULE__LSPROF_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__LSPROF_STATE=$py_cv_module__lsprof$as_nl" + if test "x$py_cv_module__lsprof" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__opcode" != "n/a"; then : + py_cv_module__opcode=yes +fi + if test "$py_cv_module__opcode" = yes; then MODULE__OPCODE_TRUE= MODULE__OPCODE_FALSE='#' else @@ -19690,11 +25891,19 @@ else MODULE__OPCODE_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__OPCODE_STATE=$py_cv_module__opcode$as_nl" + if test "x$py_cv_module__opcode" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__pickle" != "n/a"; then : + py_cv_module__pickle=yes +fi + if test "$py_cv_module__pickle" = yes; then MODULE__PICKLE_TRUE= MODULE__PICKLE_FALSE='#' else @@ -19702,11 +25911,39 @@ else MODULE__PICKLE_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__PICKLE_STATE=$py_cv_module__pickle$as_nl" + if test "x$py_cv_module__pickle" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__posixsubprocess" != "n/a"; then : + py_cv_module__posixsubprocess=yes +fi + if test "$py_cv_module__posixsubprocess" = yes; then + MODULE__POSIXSUBPROCESS_TRUE= + MODULE__POSIXSUBPROCESS_FALSE='#' +else + MODULE__POSIXSUBPROCESS_TRUE='#' + MODULE__POSIXSUBPROCESS_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__POSIXSUBPROCESS_STATE=$py_cv_module__posixsubprocess$as_nl" + if test "x$py_cv_module__posixsubprocess" = xyes; then : + + + + +fi + + + if test "$py_cv_module__queue" != "n/a"; then : + py_cv_module__queue=yes +fi + if test "$py_cv_module__queue" = yes; then MODULE__QUEUE_TRUE= MODULE__QUEUE_FALSE='#' else @@ -19714,11 +25951,19 @@ else MODULE__QUEUE_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__QUEUE_STATE=$py_cv_module__queue$as_nl" + if test "x$py_cv_module__queue" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__random" != "n/a"; then : + py_cv_module__random=yes +fi + if test "$py_cv_module__random" = yes; then MODULE__RANDOM_TRUE= MODULE__RANDOM_FALSE='#' else @@ -19726,11 +25971,59 @@ else MODULE__RANDOM_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__RANDOM_STATE=$py_cv_module__random$as_nl" + if test "x$py_cv_module__random" = xyes; then : - if true; then +fi + + + if test "$py_cv_module_select" != "n/a"; then : + py_cv_module_select=yes +fi + if test "$py_cv_module_select" = yes; then + MODULE_SELECT_TRUE= + MODULE_SELECT_FALSE='#' +else + MODULE_SELECT_TRUE='#' + MODULE_SELECT_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE_SELECT_STATE=$py_cv_module_select$as_nl" + if test "x$py_cv_module_select" = xyes; then : + + + + +fi + + + if test "$py_cv_module__struct" != "n/a"; then : + py_cv_module__struct=yes +fi + if test "$py_cv_module__struct" = yes; then + MODULE__STRUCT_TRUE= + MODULE__STRUCT_FALSE='#' +else + MODULE__STRUCT_TRUE='#' + MODULE__STRUCT_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__STRUCT_STATE=$py_cv_module__struct$as_nl" + if test "x$py_cv_module__struct" = xyes; then : + + + + +fi + + + if test "$py_cv_module__typing" != "n/a"; then : + py_cv_module__typing=yes +fi + if test "$py_cv_module__typing" = yes; then MODULE__TYPING_TRUE= MODULE__TYPING_FALSE='#' else @@ -19738,11 +26031,39 @@ else MODULE__TYPING_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__TYPING_STATE=$py_cv_module__typing$as_nl" + if test "x$py_cv_module__typing" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__xxsubinterpreters" != "n/a"; then : + py_cv_module__xxsubinterpreters=yes +fi + if test "$py_cv_module__xxsubinterpreters" = yes; then + MODULE__XXSUBINTERPRETERS_TRUE= + MODULE__XXSUBINTERPRETERS_FALSE='#' +else + MODULE__XXSUBINTERPRETERS_TRUE='#' + MODULE__XXSUBINTERPRETERS_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__XXSUBINTERPRETERS_STATE=$py_cv_module__xxsubinterpreters$as_nl" + if test "x$py_cv_module__xxsubinterpreters" = xyes; then : + + + + +fi + + + if test "$py_cv_module__zoneinfo" != "n/a"; then : + py_cv_module__zoneinfo=yes +fi + if test "$py_cv_module__zoneinfo" = yes; then MODULE__ZONEINFO_TRUE= MODULE__ZONEINFO_FALSE='#' else @@ -19750,12 +26071,109 @@ else MODULE__ZONEINFO_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__ZONEINFO_STATE=$py_cv_module__zoneinfo$as_nl" + if test "x$py_cv_module__zoneinfo" = xyes; then : +fi - if true; then + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _multiprocessing" >&5 +$as_echo_n "checking for stdlib extension module _multiprocessing... " >&6; } + if test "$py_cv_module__multiprocessing" != "n/a"; then : + + if true; then : + if test "$ac_cv_func_sem_unlink" = "yes"; then : + py_cv_module__multiprocessing=yes +else + py_cv_module__multiprocessing=missing +fi +else + py_cv_module__multiprocessing=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__MULTIPROCESSING_STATE=$py_cv_module__multiprocessing$as_nl" + if test "x$py_cv_module__multiprocessing" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE__MULTIPROCESSING_CFLAGS=-I\$(srcdir)/Modules/_multiprocessing$as_nl" + + +fi + if test "$py_cv_module__multiprocessing" = yes; then + MODULE__MULTIPROCESSING_TRUE= + MODULE__MULTIPROCESSING_FALSE='#' +else + MODULE__MULTIPROCESSING_TRUE='#' + MODULE__MULTIPROCESSING_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__multiprocessing" >&5 +$as_echo "$py_cv_module__multiprocessing" >&6; } + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _posixshmem" >&5 +$as_echo_n "checking for stdlib extension module _posixshmem... " >&6; } + if test "$py_cv_module__posixshmem" != "n/a"; then : + + if true; then : + if test "$have_posix_shmem" = "yes"; then : + py_cv_module__posixshmem=yes +else + py_cv_module__posixshmem=missing +fi +else + py_cv_module__posixshmem=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__POSIXSHMEM_STATE=$py_cv_module__posixshmem$as_nl" + if test "x$py_cv_module__posixshmem" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE__POSIXSHMEM_CFLAGS=$POSIXSHMEM_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__POSIXSHMEM_LDFLAGS=$POSIXSHMEM_LIBS$as_nl" + +fi + if test "$py_cv_module__posixshmem" = yes; then + MODULE__POSIXSHMEM_TRUE= + MODULE__POSIXSHMEM_FALSE='#' +else + MODULE__POSIXSHMEM_TRUE='#' + MODULE__POSIXSHMEM_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__posixshmem" >&5 +$as_echo "$py_cv_module__posixshmem" >&6; } + + + + if test "$py_cv_module_audioop" != "n/a"; then : + py_cv_module_audioop=yes +fi + if test "$py_cv_module_audioop" = yes; then + MODULE_AUDIOOP_TRUE= + MODULE_AUDIOOP_FALSE='#' +else + MODULE_AUDIOOP_TRUE='#' + MODULE_AUDIOOP_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE_AUDIOOP_STATE=$py_cv_module_audioop$as_nl" + if test "x$py_cv_module_audioop" = xyes; then : + + + as_fn_append MODULE_BLOCK "MODULE_AUDIOOP_LDFLAGS=$LIBM$as_nl" + +fi + + + if test "$py_cv_module__statistics" != "n/a"; then : + py_cv_module__statistics=yes +fi + if test "$py_cv_module__statistics" = yes; then MODULE__STATISTICS_TRUE= MODULE__STATISTICS_FALSE='#' else @@ -19763,13 +26181,19 @@ else MODULE__STATISTICS_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__STATISTICS_STATE=$py_cv_module__statistics$as_nl" + if test "x$py_cv_module__statistics" = xyes; then : as_fn_append MODULE_BLOCK "MODULE__STATISTICS_LDFLAGS=$LIBM$as_nl" +fi - if true; then + if test "$py_cv_module_cmath" != "n/a"; then : + py_cv_module_cmath=yes +fi + if test "$py_cv_module_cmath" = yes; then MODULE_CMATH_TRUE= MODULE_CMATH_FALSE='#' else @@ -19777,13 +26201,19 @@ else MODULE_CMATH_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE_CMATH_STATE=$py_cv_module_cmath$as_nl" + if test "x$py_cv_module_cmath" = xyes; then : as_fn_append MODULE_BLOCK "MODULE_CMATH_LDFLAGS=$LIBM$as_nl" +fi - if true; then + if test "$py_cv_module_math" != "n/a"; then : + py_cv_module_math=yes +fi + if test "$py_cv_module_math" = yes; then MODULE_MATH_TRUE= MODULE_MATH_FALSE='#' else @@ -19791,14 +26221,20 @@ else MODULE_MATH_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE_MATH_STATE=$py_cv_module_math$as_nl" + if test "x$py_cv_module_math" = xyes; then : as_fn_append MODULE_BLOCK "MODULE_MATH_LDFLAGS=$LIBM$as_nl" +fi - if true; then + if test "$py_cv_module__datetime" != "n/a"; then : + py_cv_module__datetime=yes +fi + if test "$py_cv_module__datetime" = yes; then MODULE__DATETIME_TRUE= MODULE__DATETIME_FALSE='#' else @@ -19806,21 +26242,124 @@ else MODULE__DATETIME_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__DATETIME_STATE=$py_cv_module__datetime$as_nl" + if test "x$py_cv_module__datetime" = xyes; then : as_fn_append MODULE_BLOCK "MODULE__DATETIME_LDFLAGS=$TIMEMODULE_LIB $LIBM$as_nl" +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module fcntl" >&5 +$as_echo_n "checking for stdlib extension module fcntl... " >&6; } + if test "$py_cv_module_fcntl" != "n/a"; then : + + if true; then : + if test "$ac_cv_header_sys_ioctl_h" = "yes" -a "$ac_cv_header_fcntl_h" = "yes"; then : + py_cv_module_fcntl=yes +else + py_cv_module_fcntl=missing +fi +else + py_cv_module_fcntl=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_FCNTL_STATE=$py_cv_module_fcntl$as_nl" + if test "x$py_cv_module_fcntl" = xyes; then : + + + as_fn_append MODULE_BLOCK "MODULE_FCNTL_LDFLAGS=$FCNTL_LIBS$as_nl" + +fi + if test "$py_cv_module_fcntl" = yes; then + MODULE_FCNTL_TRUE= + MODULE_FCNTL_FALSE='#' +else + MODULE_FCNTL_TRUE='#' + MODULE_FCNTL_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_fcntl" >&5 +$as_echo "$py_cv_module_fcntl" >&6; } + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module mmap" >&5 +$as_echo_n "checking for stdlib extension module mmap... " >&6; } + if test "$py_cv_module_mmap" != "n/a"; then : + + if true; then : + if test "$ac_cv_header_sys_mman_h" = "yes" -a "$ac_cv_header_sys_stat_h" = "yes"; then : + py_cv_module_mmap=yes +else + py_cv_module_mmap=missing +fi +else + py_cv_module_mmap=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_MMAP_STATE=$py_cv_module_mmap$as_nl" + if test "x$py_cv_module_mmap" = xyes; then : + + + + +fi + if test "$py_cv_module_mmap" = yes; then + MODULE_MMAP_TRUE= + MODULE_MMAP_FALSE='#' +else + MODULE_MMAP_TRUE='#' + MODULE_MMAP_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_mmap" >&5 +$as_echo "$py_cv_module_mmap" >&6; } + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _socket" >&5 +$as_echo_n "checking for stdlib extension module _socket... " >&6; } + if test "$py_cv_module__socket" != "n/a"; then : + + if true; then : + if test "$ac_cv_header_sys_socket_h" = "yes" -a "$ac_cv_header_sys_types_h" = "yes" -a "$ac_cv_header_netinet_in_h" = "yes"; then : + py_cv_module__socket=yes +else + py_cv_module__socket=missing +fi +else + py_cv_module__socket=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__SOCKET_STATE=$py_cv_module__socket$as_nl" + if test "x$py_cv_module__socket" = xyes; then : + + + + +fi + if test "$py_cv_module__socket" = yes; then + MODULE__SOCKET_TRUE= + MODULE__SOCKET_FALSE='#' +else + MODULE__SOCKET_TRUE='#' + MODULE__SOCKET_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__socket" >&5 +$as_echo "$py_cv_module__socket" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module grp" >&5 $as_echo_n "checking for stdlib extension module grp... " >&6; } - case $py_stdlib_not_available in #( - *grp*) : - py_cv_module_grp=n/a ;; #( - *) : + if test "$py_cv_module_grp" != "n/a"; then : - if true; then : + if true; then : if test "$ac_cv_func_getgrgid" = yes -o "$ac_cv_func_getgrgid_r" = yes; then : py_cv_module_grp=yes else @@ -19828,12 +26367,10 @@ else fi else py_cv_module_grp=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE_GRP=$py_cv_module_grp$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE_GRP_STATE=$py_cv_module_grp$as_nl" if test "x$py_cv_module_grp" = xyes; then : @@ -19854,12 +26391,9 @@ $as_echo "$py_cv_module_grp" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module ossaudiodev" >&5 $as_echo_n "checking for stdlib extension module ossaudiodev... " >&6; } - case $py_stdlib_not_available in #( - *ossaudiodev*) : - py_cv_module_ossaudiodev=n/a ;; #( - *) : + if test "$py_cv_module_ossaudiodev" != "n/a"; then : - if true; then : + if true; then : if test "$ac_cv_header_linux_soundcard_h" = yes -o "$ac_cv_header_sys_soundcard_h" = yes; then : py_cv_module_ossaudiodev=yes else @@ -19867,16 +26401,14 @@ else fi else py_cv_module_ossaudiodev=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE_OSSAUDIODEV=$py_cv_module_ossaudiodev$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE_OSSAUDIODEV_STATE=$py_cv_module_ossaudiodev$as_nl" if test "x$py_cv_module_ossaudiodev" = xyes; then : - + as_fn_append MODULE_BLOCK "MODULE_OSSAUDIODEV_LDFLAGS=$OSSAUDIODEV_LIBS$as_nl" fi if test "$py_cv_module_ossaudiodev" = yes; then @@ -19891,14 +26423,45 @@ fi $as_echo "$py_cv_module_ossaudiodev" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module pwd" >&5 +$as_echo_n "checking for stdlib extension module pwd... " >&6; } + if test "$py_cv_module_pwd" != "n/a"; then : + + if true; then : + if test "$ac_cv_func_getpwuid" = yes -o "$ac_cv_func_getpwuid_r" = yes; then : + py_cv_module_pwd=yes +else + py_cv_module_pwd=missing +fi +else + py_cv_module_pwd=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_PWD_STATE=$py_cv_module_pwd$as_nl" + if test "x$py_cv_module_pwd" = xyes; then : + + + + +fi + if test "$py_cv_module_pwd" = yes; then + MODULE_PWD_TRUE= + MODULE_PWD_FALSE='#' +else + MODULE_PWD_TRUE='#' + MODULE_PWD_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_pwd" >&5 +$as_echo "$py_cv_module_pwd" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module resource" >&5 $as_echo_n "checking for stdlib extension module resource... " >&6; } - case $py_stdlib_not_available in #( - *resource*) : - py_cv_module_resource=n/a ;; #( - *) : + if test "$py_cv_module_resource" != "n/a"; then : - if true; then : + if true; then : if test "$ac_cv_header_sys_resource_h" = yes; then : py_cv_module_resource=yes else @@ -19906,12 +26469,10 @@ else fi else py_cv_module_resource=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE_RESOURCE=$py_cv_module_resource$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE_RESOURCE_STATE=$py_cv_module_resource$as_nl" if test "x$py_cv_module_resource" = xyes; then : @@ -19932,12 +26493,9 @@ $as_echo "$py_cv_module_resource" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _scproxy" >&5 $as_echo_n "checking for stdlib extension module _scproxy... " >&6; } - case $py_stdlib_not_available in #( - *_scproxy*) : - py_cv_module__scproxy=n/a ;; #( - *) : + if test "$py_cv_module__scproxy" != "n/a"; then : - if test "$ac_sys_system" = "Darwin"; then : + if test "$ac_sys_system" = "Darwin"; then : if true; then : py_cv_module__scproxy=yes else @@ -19945,12 +26503,10 @@ else fi else py_cv_module__scproxy=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__SCPROXY=$py_cv_module__scproxy$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__SCPROXY_STATE=$py_cv_module__scproxy$as_nl" if test "x$py_cv_module__scproxy" = xyes; then : @@ -19971,12 +26527,9 @@ $as_echo "$py_cv_module__scproxy" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module spwd" >&5 $as_echo_n "checking for stdlib extension module spwd... " >&6; } - case $py_stdlib_not_available in #( - *spwd*) : - py_cv_module_spwd=n/a ;; #( - *) : + if test "$py_cv_module_spwd" != "n/a"; then : - if true; then : + if true; then : if test "$ac_cv_func_getspent" = yes -o "$ac_cv_func_getspnam" = yes; then : py_cv_module_spwd=yes else @@ -19984,12 +26537,10 @@ else fi else py_cv_module_spwd=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE_SPWD=$py_cv_module_spwd$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE_SPWD_STATE=$py_cv_module_spwd$as_nl" if test "x$py_cv_module_spwd" = xyes; then : @@ -20010,12 +26561,9 @@ $as_echo "$py_cv_module_spwd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module syslog" >&5 $as_echo_n "checking for stdlib extension module syslog... " >&6; } - case $py_stdlib_not_available in #( - *syslog*) : - py_cv_module_syslog=n/a ;; #( - *) : + if test "$py_cv_module_syslog" != "n/a"; then : - if true; then : + if true; then : if test "$ac_cv_header_syslog_h" = yes; then : py_cv_module_syslog=yes else @@ -20023,12 +26571,10 @@ else fi else py_cv_module_syslog=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE_SYSLOG=$py_cv_module_syslog$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE_SYSLOG_STATE=$py_cv_module_syslog$as_nl" if test "x$py_cv_module_syslog" = xyes; then : @@ -20049,12 +26595,9 @@ $as_echo "$py_cv_module_syslog" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module termios" >&5 $as_echo_n "checking for stdlib extension module termios... " >&6; } - case $py_stdlib_not_available in #( - *termios*) : - py_cv_module_termios=n/a ;; #( - *) : + if test "$py_cv_module_termios" != "n/a"; then : - if true; then : + if true; then : if test "$ac_cv_header_termios_h" = yes; then : py_cv_module_termios=yes else @@ -20062,12 +26605,10 @@ else fi else py_cv_module_termios=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE_TERMIOS=$py_cv_module_termios$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE_TERMIOS_STATE=$py_cv_module_termios$as_nl" if test "x$py_cv_module_termios" = xyes; then : @@ -20089,12 +26630,9 @@ $as_echo "$py_cv_module_termios" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module pyexpat" >&5 $as_echo_n "checking for stdlib extension module pyexpat... " >&6; } - case $py_stdlib_not_available in #( - *pyexpat*) : - py_cv_module_pyexpat=n/a ;; #( - *) : + if test "$py_cv_module_pyexpat" != "n/a"; then : - if true; then : + if true; then : if true; then : py_cv_module_pyexpat=yes else @@ -20102,12 +26640,10 @@ else fi else py_cv_module_pyexpat=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE_PYEXPAT=$py_cv_module_pyexpat$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE_PYEXPAT_STATE=$py_cv_module_pyexpat$as_nl" if test "x$py_cv_module_pyexpat" = xyes; then : as_fn_append MODULE_BLOCK "MODULE_PYEXPAT_CFLAGS=$LIBEXPAT_CFLAGS$as_nl" @@ -20128,12 +26664,9 @@ $as_echo "$py_cv_module_pyexpat" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _elementtree" >&5 $as_echo_n "checking for stdlib extension module _elementtree... " >&6; } - case $py_stdlib_not_available in #( - *_elementtree*) : - py_cv_module__elementtree=n/a ;; #( - *) : + if test "$py_cv_module__elementtree" != "n/a"; then : - if true; then : + if true; then : if true; then : py_cv_module__elementtree=yes else @@ -20141,12 +26674,10 @@ else fi else py_cv_module__elementtree=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__ELEMENTTREE=$py_cv_module__elementtree$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__ELEMENTTREE_STATE=$py_cv_module__elementtree$as_nl" if test "x$py_cv_module__elementtree" = xyes; then : as_fn_append MODULE_BLOCK "MODULE__ELEMENTTREE_CFLAGS=$LIBEXPAT_CFLAGS$as_nl" @@ -20165,7 +26696,10 @@ fi $as_echo "$py_cv_module__elementtree" >&6; } - if true; then + if test "$py_cv_module__codecs_cn" != "n/a"; then : + py_cv_module__codecs_cn=yes +fi + if test "$py_cv_module__codecs_cn" = yes; then MODULE__CODECS_CN_TRUE= MODULE__CODECS_CN_FALSE='#' else @@ -20173,11 +26707,19 @@ else MODULE__CODECS_CN_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__CODECS_CN_STATE=$py_cv_module__codecs_cn$as_nl" + if test "x$py_cv_module__codecs_cn" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__codecs_hk" != "n/a"; then : + py_cv_module__codecs_hk=yes +fi + if test "$py_cv_module__codecs_hk" = yes; then MODULE__CODECS_HK_TRUE= MODULE__CODECS_HK_FALSE='#' else @@ -20185,11 +26727,19 @@ else MODULE__CODECS_HK_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__CODECS_HK_STATE=$py_cv_module__codecs_hk$as_nl" + if test "x$py_cv_module__codecs_hk" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__codecs_iso2022" != "n/a"; then : + py_cv_module__codecs_iso2022=yes +fi + if test "$py_cv_module__codecs_iso2022" = yes; then MODULE__CODECS_ISO2022_TRUE= MODULE__CODECS_ISO2022_FALSE='#' else @@ -20197,11 +26747,19 @@ else MODULE__CODECS_ISO2022_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__CODECS_ISO2022_STATE=$py_cv_module__codecs_iso2022$as_nl" + if test "x$py_cv_module__codecs_iso2022" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__codecs_jp" != "n/a"; then : + py_cv_module__codecs_jp=yes +fi + if test "$py_cv_module__codecs_jp" = yes; then MODULE__CODECS_JP_TRUE= MODULE__CODECS_JP_FALSE='#' else @@ -20209,11 +26767,19 @@ else MODULE__CODECS_JP_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__CODECS_JP_STATE=$py_cv_module__codecs_jp$as_nl" + if test "x$py_cv_module__codecs_jp" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__codecs_kr" != "n/a"; then : + py_cv_module__codecs_kr=yes +fi + if test "$py_cv_module__codecs_kr" = yes; then MODULE__CODECS_KR_TRUE= MODULE__CODECS_KR_FALSE='#' else @@ -20221,11 +26787,19 @@ else MODULE__CODECS_KR_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__CODECS_KR_STATE=$py_cv_module__codecs_kr$as_nl" + if test "x$py_cv_module__codecs_kr" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__codecs_tw" != "n/a"; then : + py_cv_module__codecs_tw=yes +fi + if test "$py_cv_module__codecs_tw" = yes; then MODULE__CODECS_TW_TRUE= MODULE__CODECS_TW_FALSE='#' else @@ -20233,11 +26807,19 @@ else MODULE__CODECS_TW_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__CODECS_TW_STATE=$py_cv_module__codecs_tw$as_nl" + if test "x$py_cv_module__codecs_tw" = xyes; then : - if true; then +fi + + + if test "$py_cv_module__multibytecodec" != "n/a"; then : + py_cv_module__multibytecodec=yes +fi + if test "$py_cv_module__multibytecodec" = yes; then MODULE__MULTIBYTECODEC_TRUE= MODULE__MULTIBYTECODEC_FALSE='#' else @@ -20245,11 +26827,19 @@ else MODULE__MULTIBYTECODEC_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE__MULTIBYTECODEC_STATE=$py_cv_module__multibytecodec$as_nl" + if test "x$py_cv_module__multibytecodec" = xyes; then : - if true; then +fi + + + if test "$py_cv_module_unicodedata" != "n/a"; then : + py_cv_module_unicodedata=yes +fi + if test "$py_cv_module_unicodedata" = yes; then MODULE_UNICODEDATA_TRUE= MODULE_UNICODEDATA_FALSE='#' else @@ -20257,19 +26847,21 @@ else MODULE_UNICODEDATA_FALSE= fi + as_fn_append MODULE_BLOCK "MODULE_UNICODEDATA_STATE=$py_cv_module_unicodedata$as_nl" + if test "x$py_cv_module_unicodedata" = xyes; then : +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _md5" >&5 $as_echo_n "checking for stdlib extension module _md5... " >&6; } - case $py_stdlib_not_available in #( - *_md5*) : - py_cv_module__md5=n/a ;; #( - *) : + if test "$py_cv_module__md5" != "n/a"; then : - if test "$with_builtin_md5" = yes; then : + if test "$with_builtin_md5" = yes; then : if true; then : py_cv_module__md5=yes else @@ -20277,12 +26869,10 @@ else fi else py_cv_module__md5=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__MD5=$py_cv_module__md5$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__MD5_STATE=$py_cv_module__md5$as_nl" if test "x$py_cv_module__md5" = xyes; then : @@ -20303,12 +26893,9 @@ $as_echo "$py_cv_module__md5" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha1" >&5 $as_echo_n "checking for stdlib extension module _sha1... " >&6; } - case $py_stdlib_not_available in #( - *_sha1*) : - py_cv_module__sha1=n/a ;; #( - *) : + if test "$py_cv_module__sha1" != "n/a"; then : - if test "$with_builtin_sha1" = yes; then : + if test "$with_builtin_sha1" = yes; then : if true; then : py_cv_module__sha1=yes else @@ -20316,12 +26903,10 @@ else fi else py_cv_module__sha1=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__SHA1=$py_cv_module__sha1$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__SHA1_STATE=$py_cv_module__sha1$as_nl" if test "x$py_cv_module__sha1" = xyes; then : @@ -20342,12 +26927,9 @@ $as_echo "$py_cv_module__sha1" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha256" >&5 $as_echo_n "checking for stdlib extension module _sha256... " >&6; } - case $py_stdlib_not_available in #( - *_sha256*) : - py_cv_module__sha256=n/a ;; #( - *) : + if test "$py_cv_module__sha256" != "n/a"; then : - if test "$with_builtin_sha256" = yes; then : + if test "$with_builtin_sha256" = yes; then : if true; then : py_cv_module__sha256=yes else @@ -20355,12 +26937,10 @@ else fi else py_cv_module__sha256=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__SHA256=$py_cv_module__sha256$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__SHA256_STATE=$py_cv_module__sha256$as_nl" if test "x$py_cv_module__sha256" = xyes; then : @@ -20381,12 +26961,9 @@ $as_echo "$py_cv_module__sha256" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha512" >&5 $as_echo_n "checking for stdlib extension module _sha512... " >&6; } - case $py_stdlib_not_available in #( - *_sha512*) : - py_cv_module__sha512=n/a ;; #( - *) : + if test "$py_cv_module__sha512" != "n/a"; then : - if test "$with_builtin_sha512" = yes; then : + if test "$with_builtin_sha512" = yes; then : if true; then : py_cv_module__sha512=yes else @@ -20394,12 +26971,10 @@ else fi else py_cv_module__sha512=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__SHA512=$py_cv_module__sha512$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__SHA512_STATE=$py_cv_module__sha512$as_nl" if test "x$py_cv_module__sha512" = xyes; then : @@ -20420,12 +26995,9 @@ $as_echo "$py_cv_module__sha512" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha3" >&5 $as_echo_n "checking for stdlib extension module _sha3... " >&6; } - case $py_stdlib_not_available in #( - *_sha3*) : - py_cv_module__sha3=n/a ;; #( - *) : + if test "$py_cv_module__sha3" != "n/a"; then : - if test "$with_builtin_sha3" = yes; then : + if test "$with_builtin_sha3" = yes; then : if true; then : py_cv_module__sha3=yes else @@ -20433,12 +27005,10 @@ else fi else py_cv_module__sha3=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__SHA3=$py_cv_module__sha3$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__SHA3_STATE=$py_cv_module__sha3$as_nl" if test "x$py_cv_module__sha3" = xyes; then : @@ -20459,12 +27029,9 @@ $as_echo "$py_cv_module__sha3" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _blake2" >&5 $as_echo_n "checking for stdlib extension module _blake2... " >&6; } - case $py_stdlib_not_available in #( - *_blake2*) : - py_cv_module__blake2=n/a ;; #( - *) : + if test "$py_cv_module__blake2" != "n/a"; then : - if test "$with_builtin_blake2" = yes; then : + if test "$with_builtin_blake2" = yes; then : if true; then : py_cv_module__blake2=yes else @@ -20472,16 +27039,14 @@ else fi else py_cv_module__blake2=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__BLAKE2=$py_cv_module__blake2$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__BLAKE2_STATE=$py_cv_module__blake2$as_nl" if test "x$py_cv_module__blake2" = xyes; then : - - + as_fn_append MODULE_BLOCK "MODULE__BLAKE2_CFLAGS=$LIBB2_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__BLAKE2_LDFLAGS=$LIBB2_LIBS$as_nl" fi if test "$py_cv_module__blake2" = yes; then @@ -20497,14 +27062,149 @@ $as_echo "$py_cv_module__blake2" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _crypt" >&5 +$as_echo_n "checking for stdlib extension module _crypt... " >&6; } + if test "$py_cv_module__crypt" != "n/a"; then : + + if true; then : + if test "$ac_cv_crypt_crypt" = yes; then : + py_cv_module__crypt=yes +else + py_cv_module__crypt=missing +fi +else + py_cv_module__crypt=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__CRYPT_STATE=$py_cv_module__crypt$as_nl" + if test "x$py_cv_module__crypt" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE__CRYPT_CFLAGS=$LIBCRYPT_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__CRYPT_LDFLAGS=$LIBCRYPT_LIBS$as_nl" + +fi + if test "$py_cv_module__crypt" = yes; then + MODULE__CRYPT_TRUE= + MODULE__CRYPT_FALSE='#' +else + MODULE__CRYPT_TRUE='#' + MODULE__CRYPT_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__crypt" >&5 +$as_echo "$py_cv_module__crypt" >&6; } + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _ctypes" >&5 +$as_echo_n "checking for stdlib extension module _ctypes... " >&6; } + if test "$py_cv_module__ctypes" != "n/a"; then : + + if true; then : + if test "$have_libffi" = yes; then : + py_cv_module__ctypes=yes +else + py_cv_module__ctypes=missing +fi +else + py_cv_module__ctypes=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__CTYPES_STATE=$py_cv_module__ctypes$as_nl" + if test "x$py_cv_module__ctypes" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE__CTYPES_CFLAGS=$LIBFFI_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__CTYPES_LDFLAGS=$LIBFFI_LIBS$as_nl" + +fi + if test "$py_cv_module__ctypes" = yes; then + MODULE__CTYPES_TRUE= + MODULE__CTYPES_FALSE='#' +else + MODULE__CTYPES_TRUE='#' + MODULE__CTYPES_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__ctypes" >&5 +$as_echo "$py_cv_module__ctypes" >&6; } + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _curses" >&5 +$as_echo_n "checking for stdlib extension module _curses... " >&6; } + if test "$py_cv_module__curses" != "n/a"; then : + + if true; then : + if test "$have_curses" != "no"; then : + py_cv_module__curses=yes +else + py_cv_module__curses=missing +fi +else + py_cv_module__curses=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__CURSES_STATE=$py_cv_module__curses$as_nl" + if test "x$py_cv_module__curses" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE__CURSES_CFLAGS=$CURSES_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__CURSES_LDFLAGS=$CURSES_LIBS +$as_nl" + +fi + if test "$py_cv_module__curses" = yes; then + MODULE__CURSES_TRUE= + MODULE__CURSES_FALSE='#' +else + MODULE__CURSES_TRUE='#' + MODULE__CURSES_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__curses" >&5 +$as_echo "$py_cv_module__curses" >&6; } + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _curses_panel" >&5 +$as_echo_n "checking for stdlib extension module _curses_panel... " >&6; } + if test "$py_cv_module__curses_panel" != "n/a"; then : + + if true; then : + if test "$have_panel" != "no"; then : + py_cv_module__curses_panel=yes +else + py_cv_module__curses_panel=missing +fi +else + py_cv_module__curses_panel=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__CURSES_PANEL_STATE=$py_cv_module__curses_panel$as_nl" + if test "x$py_cv_module__curses_panel" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE__CURSES_PANEL_CFLAGS=$PANEL_CFLAGS $CURSES_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__CURSES_PANEL_LDFLAGS=$PANEL_LIBS $CURSES_LIBS +$as_nl" + +fi + if test "$py_cv_module__curses_panel" = yes; then + MODULE__CURSES_PANEL_TRUE= + MODULE__CURSES_PANEL_FALSE='#' +else + MODULE__CURSES_PANEL_TRUE='#' + MODULE__CURSES_PANEL_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__curses_panel" >&5 +$as_echo "$py_cv_module__curses_panel" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _decimal" >&5 $as_echo_n "checking for stdlib extension module _decimal... " >&6; } - case $py_stdlib_not_available in #( - *_decimal*) : - py_cv_module__decimal=n/a ;; #( - *) : + if test "$py_cv_module__decimal" != "n/a"; then : - if true; then : + if true; then : if true; then : py_cv_module__decimal=yes else @@ -20512,12 +27212,10 @@ else fi else py_cv_module__decimal=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__DECIMAL=$py_cv_module__decimal$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__DECIMAL_STATE=$py_cv_module__decimal$as_nl" if test "x$py_cv_module__decimal" = xyes; then : as_fn_append MODULE_BLOCK "MODULE__DECIMAL_CFLAGS=$LIBMPDEC_CFLAGS$as_nl" @@ -20536,14 +27234,147 @@ fi $as_echo "$py_cv_module__decimal" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _dbm" >&5 +$as_echo_n "checking for stdlib extension module _dbm... " >&6; } + if test "$py_cv_module__dbm" != "n/a"; then : + + if test -n "$with_dbmliborder"; then : + if test "$have_dbm" != "no"; then : + py_cv_module__dbm=yes +else + py_cv_module__dbm=missing +fi +else + py_cv_module__dbm=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__DBM_STATE=$py_cv_module__dbm$as_nl" + if test "x$py_cv_module__dbm" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE__DBM_CFLAGS=$DBM_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__DBM_LDFLAGS=$DBM_LIBS$as_nl" + +fi + if test "$py_cv_module__dbm" = yes; then + MODULE__DBM_TRUE= + MODULE__DBM_FALSE='#' +else + MODULE__DBM_TRUE='#' + MODULE__DBM_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__dbm" >&5 +$as_echo "$py_cv_module__dbm" >&6; } + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _gdbm" >&5 +$as_echo_n "checking for stdlib extension module _gdbm... " >&6; } + if test "$py_cv_module__gdbm" != "n/a"; then : + + if test "$have_gdbm_dbmliborder" = yes; then : + if test "$have_gdbm" = yes; then : + py_cv_module__gdbm=yes +else + py_cv_module__gdbm=missing +fi +else + py_cv_module__gdbm=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__GDBM_STATE=$py_cv_module__gdbm$as_nl" + if test "x$py_cv_module__gdbm" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE__GDBM_CFLAGS=$GDBM_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__GDBM_LDFLAGS=$GDBM_LIBS$as_nl" + +fi + if test "$py_cv_module__gdbm" = yes; then + MODULE__GDBM_TRUE= + MODULE__GDBM_FALSE='#' +else + MODULE__GDBM_TRUE='#' + MODULE__GDBM_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__gdbm" >&5 +$as_echo "$py_cv_module__gdbm" >&6; } + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module nis" >&5 +$as_echo_n "checking for stdlib extension module nis... " >&6; } + if test "$py_cv_module_nis" != "n/a"; then : + + if true; then : + if test "$have_nis" = yes -a "$ac_cv_header_rpc_rpc_h" = yes; then : + py_cv_module_nis=yes +else + py_cv_module_nis=missing +fi +else + py_cv_module_nis=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_NIS_STATE=$py_cv_module_nis$as_nl" + if test "x$py_cv_module_nis" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE_NIS_CFLAGS=$LIBNSL_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE_NIS_LDFLAGS=$LIBNSL_LIBS$as_nl" + +fi + if test "$py_cv_module_nis" = yes; then + MODULE_NIS_TRUE= + MODULE_NIS_FALSE='#' +else + MODULE_NIS_TRUE='#' + MODULE_NIS_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_nis" >&5 +$as_echo "$py_cv_module_nis" >&6; } + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module readline" >&5 +$as_echo_n "checking for stdlib extension module readline... " >&6; } + if test "$py_cv_module_readline" != "n/a"; then : + + if true; then : + if test "$with_readline" != "no"; then : + py_cv_module_readline=yes +else + py_cv_module_readline=missing +fi +else + py_cv_module_readline=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_READLINE_STATE=$py_cv_module_readline$as_nl" + if test "x$py_cv_module_readline" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE_READLINE_CFLAGS=$READLINE_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE_READLINE_LDFLAGS=$READLINE_LIBS$as_nl" + +fi + if test "$py_cv_module_readline" = yes; then + MODULE_READLINE_TRUE= + MODULE_READLINE_FALSE='#' +else + MODULE_READLINE_TRUE='#' + MODULE_READLINE_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_readline" >&5 +$as_echo "$py_cv_module_readline" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sqlite3" >&5 $as_echo_n "checking for stdlib extension module _sqlite3... " >&6; } - case $py_stdlib_not_available in #( - *_sqlite3*) : - py_cv_module__sqlite3=n/a ;; #( - *) : + if test "$py_cv_module__sqlite3" != "n/a"; then : - if test "$have_sqlite3" = "yes"; then : + if test "$have_sqlite3" = "yes"; then : if test "$have_supported_sqlite3" = "yes"; then : py_cv_module__sqlite3=yes else @@ -20551,12 +27382,10 @@ else fi else py_cv_module__sqlite3=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__SQLITE3=$py_cv_module__sqlite3$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__SQLITE3_STATE=$py_cv_module__sqlite3$as_nl" if test "x$py_cv_module__sqlite3" = xyes; then : as_fn_append MODULE_BLOCK "MODULE__SQLITE3_CFLAGS=$LIBSQLITE3_CFLAGS$as_nl" @@ -20575,15 +27404,272 @@ fi $as_echo "$py_cv_module__sqlite3" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _tkinter" >&5 +$as_echo_n "checking for stdlib extension module _tkinter... " >&6; } + if test "$py_cv_module__tkinter" != "n/a"; then : + + if true; then : + if test "$have_tcltk" = "yes"; then : + py_cv_module__tkinter=yes +else + py_cv_module__tkinter=missing +fi +else + py_cv_module__tkinter=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__TKINTER_STATE=$py_cv_module__tkinter$as_nl" + if test "x$py_cv_module__tkinter" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE__TKINTER_CFLAGS=$TCLTK_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__TKINTER_LDFLAGS=$TCLTK_LIBS$as_nl" + +fi + if test "$py_cv_module__tkinter" = yes; then + MODULE__TKINTER_TRUE= + MODULE__TKINTER_FALSE='#' +else + MODULE__TKINTER_TRUE='#' + MODULE__TKINTER_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__tkinter" >&5 +$as_echo "$py_cv_module__tkinter" >&6; } + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _uuid" >&5 +$as_echo_n "checking for stdlib extension module _uuid... " >&6; } + if test "$py_cv_module__uuid" != "n/a"; then : + + if true; then : + if test "$have_uuid" = "yes"; then : + py_cv_module__uuid=yes +else + py_cv_module__uuid=missing +fi +else + py_cv_module__uuid=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__UUID_STATE=$py_cv_module__uuid$as_nl" + if test "x$py_cv_module__uuid" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE__UUID_CFLAGS=$LIBUUID_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__UUID_LDFLAGS=$LIBUUID_LIBS$as_nl" + +fi + if test "$py_cv_module__uuid" = yes; then + MODULE__UUID_TRUE= + MODULE__UUID_FALSE='#' +else + MODULE__UUID_TRUE='#' + MODULE__UUID_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__uuid" >&5 +$as_echo "$py_cv_module__uuid" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module zlib" >&5 +$as_echo_n "checking for stdlib extension module zlib... " >&6; } + if test "$py_cv_module_zlib" != "n/a"; then : + + if true; then : + if test "$have_zlib" = yes; then : + py_cv_module_zlib=yes +else + py_cv_module_zlib=missing +fi +else + py_cv_module_zlib=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_ZLIB_STATE=$py_cv_module_zlib$as_nl" + if test "x$py_cv_module_zlib" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE_ZLIB_CFLAGS=$ZLIB_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE_ZLIB_LDFLAGS=$ZLIB_LIBS$as_nl" + +fi + if test "$py_cv_module_zlib" = yes; then + MODULE_ZLIB_TRUE= + MODULE_ZLIB_FALSE='#' +else + MODULE_ZLIB_TRUE='#' + MODULE_ZLIB_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_zlib" >&5 +$as_echo "$py_cv_module_zlib" >&6; } + + + if test "$py_cv_module_binascii" != "n/a"; then : + py_cv_module_binascii=yes +fi + if test "$py_cv_module_binascii" = yes; then + MODULE_BINASCII_TRUE= + MODULE_BINASCII_FALSE='#' +else + MODULE_BINASCII_TRUE='#' + MODULE_BINASCII_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE_BINASCII_STATE=$py_cv_module_binascii$as_nl" + if test "x$py_cv_module_binascii" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE_BINASCII_CFLAGS=$BINASCII_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE_BINASCII_LDFLAGS=$BINASCII_LIBS$as_nl" + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _bz2" >&5 +$as_echo_n "checking for stdlib extension module _bz2... " >&6; } + if test "$py_cv_module__bz2" != "n/a"; then : + + if true; then : + if test "$have_bzip2" = yes; then : + py_cv_module__bz2=yes +else + py_cv_module__bz2=missing +fi +else + py_cv_module__bz2=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__BZ2_STATE=$py_cv_module__bz2$as_nl" + if test "x$py_cv_module__bz2" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE__BZ2_CFLAGS=$BZIP2_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__BZ2_LDFLAGS=$BZIP2_LIBS$as_nl" + +fi + if test "$py_cv_module__bz2" = yes; then + MODULE__BZ2_TRUE= + MODULE__BZ2_FALSE='#' +else + MODULE__BZ2_TRUE='#' + MODULE__BZ2_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__bz2" >&5 +$as_echo "$py_cv_module__bz2" >&6; } + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _lzma" >&5 +$as_echo_n "checking for stdlib extension module _lzma... " >&6; } + if test "$py_cv_module__lzma" != "n/a"; then : + + if true; then : + if test "$have_liblzma" = yes; then : + py_cv_module__lzma=yes +else + py_cv_module__lzma=missing +fi +else + py_cv_module__lzma=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__LZMA_STATE=$py_cv_module__lzma$as_nl" + if test "x$py_cv_module__lzma" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE__LZMA_CFLAGS=$LIBLZMA_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__LZMA_LDFLAGS=$LIBLZMA_LIBS$as_nl" + +fi + if test "$py_cv_module__lzma" = yes; then + MODULE__LZMA_TRUE= + MODULE__LZMA_FALSE='#' +else + MODULE__LZMA_TRUE='#' + MODULE__LZMA_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__lzma" >&5 +$as_echo "$py_cv_module__lzma" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _ssl" >&5 +$as_echo_n "checking for stdlib extension module _ssl... " >&6; } + if test "$py_cv_module__ssl" != "n/a"; then : + + if true; then : + if test "$ac_cv_working_openssl_ssl" = yes; then : + py_cv_module__ssl=yes +else + py_cv_module__ssl=missing +fi +else + py_cv_module__ssl=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__SSL_STATE=$py_cv_module__ssl$as_nl" + if test "x$py_cv_module__ssl" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE__SSL_CFLAGS=$OPENSSL_INCLUDES$as_nl" + as_fn_append MODULE_BLOCK "MODULE__SSL_LDFLAGS=$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $OPENSSL_LIBS$as_nl" + +fi + if test "$py_cv_module__ssl" = yes; then + MODULE__SSL_TRUE= + MODULE__SSL_FALSE='#' +else + MODULE__SSL_TRUE='#' + MODULE__SSL_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__ssl" >&5 +$as_echo "$py_cv_module__ssl" >&6; } + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _hashlib" >&5 +$as_echo_n "checking for stdlib extension module _hashlib... " >&6; } + if test "$py_cv_module__hashlib" != "n/a"; then : + + if true; then : + if test "$ac_cv_working_openssl_hashlib" = yes; then : + py_cv_module__hashlib=yes +else + py_cv_module__hashlib=missing +fi +else + py_cv_module__hashlib=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__HASHLIB_STATE=$py_cv_module__hashlib$as_nl" + if test "x$py_cv_module__hashlib" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE__HASHLIB_CFLAGS=$OPENSSL_INCLUDES$as_nl" + as_fn_append MODULE_BLOCK "MODULE__HASHLIB_LDFLAGS=$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS$as_nl" + +fi + if test "$py_cv_module__hashlib" = yes; then + MODULE__HASHLIB_TRUE= + MODULE__HASHLIB_FALSE='#' +else + MODULE__HASHLIB_TRUE='#' + MODULE__HASHLIB_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__hashlib" >&5 +$as_echo "$py_cv_module__hashlib" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testcapi" >&5 $as_echo_n "checking for stdlib extension module _testcapi... " >&6; } - case $py_stdlib_not_available in #( - *_testcapi*) : - py_cv_module__testcapi=n/a ;; #( - *) : + if test "$py_cv_module__testcapi" != "n/a"; then : - if test "$TEST_MODULES" = yes; then : + if test "$TEST_MODULES" = yes; then : if true; then : py_cv_module__testcapi=yes else @@ -20591,12 +27677,10 @@ else fi else py_cv_module__testcapi=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__TESTCAPI=$py_cv_module__testcapi$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__TESTCAPI_STATE=$py_cv_module__testcapi$as_nl" if test "x$py_cv_module__testcapi" = xyes; then : @@ -20615,14 +27699,45 @@ fi $as_echo "$py_cv_module__testcapi" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testclinic" >&5 +$as_echo_n "checking for stdlib extension module _testclinic... " >&6; } + if test "$py_cv_module__testclinic" != "n/a"; then : + + if test "$TEST_MODULES" = yes; then : + if true; then : + py_cv_module__testclinic=yes +else + py_cv_module__testclinic=missing +fi +else + py_cv_module__testclinic=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__TESTCLINIC_STATE=$py_cv_module__testclinic$as_nl" + if test "x$py_cv_module__testclinic" = xyes; then : + + + + +fi + if test "$py_cv_module__testclinic" = yes; then + MODULE__TESTCLINIC_TRUE= + MODULE__TESTCLINIC_FALSE='#' +else + MODULE__TESTCLINIC_TRUE='#' + MODULE__TESTCLINIC_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testclinic" >&5 +$as_echo "$py_cv_module__testclinic" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testinternalcapi" >&5 $as_echo_n "checking for stdlib extension module _testinternalcapi... " >&6; } - case $py_stdlib_not_available in #( - *_testinternalcapi*) : - py_cv_module__testinternalcapi=n/a ;; #( - *) : + if test "$py_cv_module__testinternalcapi" != "n/a"; then : - if test "$TEST_MODULES" = yes; then : + if test "$TEST_MODULES" = yes; then : if true; then : py_cv_module__testinternalcapi=yes else @@ -20630,12 +27745,10 @@ else fi else py_cv_module__testinternalcapi=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__TESTINTERNALCAPI=$py_cv_module__testinternalcapi$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__TESTINTERNALCAPI_STATE=$py_cv_module__testinternalcapi$as_nl" if test "x$py_cv_module__testinternalcapi" = xyes; then : @@ -20656,12 +27769,9 @@ $as_echo "$py_cv_module__testinternalcapi" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testbuffer" >&5 $as_echo_n "checking for stdlib extension module _testbuffer... " >&6; } - case $py_stdlib_not_available in #( - *_testbuffer*) : - py_cv_module__testbuffer=n/a ;; #( - *) : + if test "$py_cv_module__testbuffer" != "n/a"; then : - if test "$TEST_MODULES" = yes; then : + if test "$TEST_MODULES" = yes; then : if true; then : py_cv_module__testbuffer=yes else @@ -20669,12 +27779,10 @@ else fi else py_cv_module__testbuffer=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__TESTBUFFER=$py_cv_module__testbuffer$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__TESTBUFFER_STATE=$py_cv_module__testbuffer$as_nl" if test "x$py_cv_module__testbuffer" = xyes; then : @@ -20695,25 +27803,20 @@ $as_echo "$py_cv_module__testbuffer" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testimportmultiple" >&5 $as_echo_n "checking for stdlib extension module _testimportmultiple... " >&6; } - case $py_stdlib_not_available in #( - *_testimportmultiple*) : - py_cv_module__testimportmultiple=n/a ;; #( - *) : + if test "$py_cv_module__testimportmultiple" != "n/a"; then : - if test "$TEST_MODULES" = yes; then : - if true; then : + if test "$TEST_MODULES" = yes; then : + if test "$ac_cv_func_dlopen" = yes; then : py_cv_module__testimportmultiple=yes else py_cv_module__testimportmultiple=missing fi else py_cv_module__testimportmultiple=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__TESTIMPORTMULTIPLE=$py_cv_module__testimportmultiple$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__TESTIMPORTMULTIPLE_STATE=$py_cv_module__testimportmultiple$as_nl" if test "x$py_cv_module__testimportmultiple" = xyes; then : @@ -20734,25 +27837,20 @@ $as_echo "$py_cv_module__testimportmultiple" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testmultiphase" >&5 $as_echo_n "checking for stdlib extension module _testmultiphase... " >&6; } - case $py_stdlib_not_available in #( - *_testmultiphase*) : - py_cv_module__testmultiphase=n/a ;; #( - *) : + if test "$py_cv_module__testmultiphase" != "n/a"; then : - if test "$TEST_MODULES" = yes; then : - if true; then : + if test "$TEST_MODULES" = yes; then : + if test "$ac_cv_func_dlopen" = yes; then : py_cv_module__testmultiphase=yes else py_cv_module__testmultiphase=missing fi else py_cv_module__testmultiphase=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__TESTMULTIPHASE=$py_cv_module__testmultiphase$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__TESTMULTIPHASE_STATE=$py_cv_module__testmultiphase$as_nl" if test "x$py_cv_module__testmultiphase" = xyes; then : @@ -20771,14 +27869,45 @@ fi $as_echo "$py_cv_module__testmultiphase" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module xxsubtype" >&5 +$as_echo_n "checking for stdlib extension module xxsubtype... " >&6; } + if test "$py_cv_module_xxsubtype" != "n/a"; then : + + if test "$TEST_MODULES" = yes; then : + if true; then : + py_cv_module_xxsubtype=yes +else + py_cv_module_xxsubtype=missing +fi +else + py_cv_module_xxsubtype=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_XXSUBTYPE_STATE=$py_cv_module_xxsubtype$as_nl" + if test "x$py_cv_module_xxsubtype" = xyes; then : + + + + +fi + if test "$py_cv_module_xxsubtype" = yes; then + MODULE_XXSUBTYPE_TRUE= + MODULE_XXSUBTYPE_FALSE='#' +else + MODULE_XXSUBTYPE_TRUE='#' + MODULE_XXSUBTYPE_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_xxsubtype" >&5 +$as_echo "$py_cv_module_xxsubtype" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _xxtestfuzz" >&5 $as_echo_n "checking for stdlib extension module _xxtestfuzz... " >&6; } - case $py_stdlib_not_available in #( - *_xxtestfuzz*) : - py_cv_module__xxtestfuzz=n/a ;; #( - *) : + if test "$py_cv_module__xxtestfuzz" != "n/a"; then : - if test "$TEST_MODULES" = yes; then : + if test "$TEST_MODULES" = yes; then : if true; then : py_cv_module__xxtestfuzz=yes else @@ -20786,12 +27915,10 @@ else fi else py_cv_module__xxtestfuzz=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__XXTESTFUZZ=$py_cv_module__xxtestfuzz$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__XXTESTFUZZ_STATE=$py_cv_module__xxtestfuzz$as_nl" if test "x$py_cv_module__xxtestfuzz" = xyes; then : @@ -20812,29 +27939,24 @@ $as_echo "$py_cv_module__xxtestfuzz" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _ctypes_test" >&5 $as_echo_n "checking for stdlib extension module _ctypes_test... " >&6; } - case $py_stdlib_not_available in #( - *_ctypes_test*) : - py_cv_module__ctypes_test=n/a ;; #( - *) : + if test "$py_cv_module__ctypes_test" != "n/a"; then : - if test "$TEST_MODULES" = yes; then : - if true; then : + if test "$TEST_MODULES" = yes; then : + if test "$have_libffi" = yes -a "$ac_cv_func_dlopen" = yes; then : py_cv_module__ctypes_test=yes else py_cv_module__ctypes_test=missing fi else py_cv_module__ctypes_test=disabled - fi - ;; -esac - as_fn_append MODULE_BLOCK "MODULE__CTYPES_TEST=$py_cv_module__ctypes_test$as_nl" +fi + as_fn_append MODULE_BLOCK "MODULE__CTYPES_TEST_STATE=$py_cv_module__ctypes_test$as_nl" if test "x$py_cv_module__ctypes_test" = xyes; then : - as_fn_append MODULE_BLOCK "MODULE__CTYPES_TEST_LDFLAGS=-lm$as_nl" + as_fn_append MODULE_BLOCK "MODULE__CTYPES_TEST_LDFLAGS=$LIBM$as_nl" fi if test "$py_cv_module__ctypes_test" = yes; then @@ -20849,13 +27971,82 @@ fi $as_echo "$py_cv_module__ctypes_test" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module xxlimited" >&5 +$as_echo_n "checking for stdlib extension module xxlimited... " >&6; } + if test "$py_cv_module_xxlimited" != "n/a"; then : + + if test "$with_trace_refs" = "no"; then : + if test "$ac_cv_func_dlopen" = yes; then : + py_cv_module_xxlimited=yes +else + py_cv_module_xxlimited=missing +fi +else + py_cv_module_xxlimited=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_XXLIMITED_STATE=$py_cv_module_xxlimited$as_nl" + if test "x$py_cv_module_xxlimited" = xyes; then : + + + + +fi + if test "$py_cv_module_xxlimited" = yes; then + MODULE_XXLIMITED_TRUE= + MODULE_XXLIMITED_FALSE='#' +else + MODULE_XXLIMITED_TRUE='#' + MODULE_XXLIMITED_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_xxlimited" >&5 +$as_echo "$py_cv_module_xxlimited" >&6; } + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module xxlimited_35" >&5 +$as_echo_n "checking for stdlib extension module xxlimited_35... " >&6; } + if test "$py_cv_module_xxlimited_35" != "n/a"; then : + + if test "$with_trace_refs" = "no"; then : + if test "$ac_cv_func_dlopen" = yes; then : + py_cv_module_xxlimited_35=yes +else + py_cv_module_xxlimited_35=missing +fi +else + py_cv_module_xxlimited_35=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_XXLIMITED_35_STATE=$py_cv_module_xxlimited_35$as_nl" + if test "x$py_cv_module_xxlimited_35" = xyes; then : + + + + +fi + if test "$py_cv_module_xxlimited_35" = yes; then + MODULE_XXLIMITED_35_TRUE= + MODULE_XXLIMITED_35_FALSE='#' +else + MODULE_XXLIMITED_35_TRUE='#' + MODULE_XXLIMITED_35_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_xxlimited_35" >&5 +$as_echo "$py_cv_module_xxlimited_35" >&6; } + + # substitute multiline block, must come after last PY_STDLIB_MOD() # generate output files ac_config_files="$ac_config_files Makefile.pre Misc/python.pc Misc/python-embed.pc Misc/python-config.sh" -ac_config_files="$ac_config_files Modules/Setup.stdlib" +ac_config_files="$ac_config_files Modules/Setup.bootstrap Modules/Setup.stdlib" ac_config_files="$ac_config_files Modules/ld_so_aix" @@ -20993,6 +28184,10 @@ if test -z "${MODULE__CONTEXTVARS_TRUE}" && test -z "${MODULE__CONTEXTVARS_FALSE as_fn_error $? "conditional \"MODULE__CONTEXTVARS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE__CSV_TRUE}" && test -z "${MODULE__CSV_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CSV\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__HEAPQ_TRUE}" && test -z "${MODULE__HEAPQ_FALSE}"; then as_fn_error $? "conditional \"MODULE__HEAPQ\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -21013,6 +28208,10 @@ if test -z "${MODULE__PICKLE_TRUE}" && test -z "${MODULE__PICKLE_FALSE}"; then as_fn_error $? "conditional \"MODULE__PICKLE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE__POSIXSUBPROCESS_TRUE}" && test -z "${MODULE__POSIXSUBPROCESS_FALSE}"; then + as_fn_error $? "conditional \"MODULE__POSIXSUBPROCESS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__QUEUE_TRUE}" && test -z "${MODULE__QUEUE_FALSE}"; then as_fn_error $? "conditional \"MODULE__QUEUE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -21021,14 +28220,38 @@ if test -z "${MODULE__RANDOM_TRUE}" && test -z "${MODULE__RANDOM_FALSE}"; then as_fn_error $? "conditional \"MODULE__RANDOM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE_SELECT_TRUE}" && test -z "${MODULE_SELECT_FALSE}"; then + as_fn_error $? "conditional \"MODULE_SELECT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__STRUCT_TRUE}" && test -z "${MODULE__STRUCT_FALSE}"; then + as_fn_error $? "conditional \"MODULE__STRUCT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__TYPING_TRUE}" && test -z "${MODULE__TYPING_FALSE}"; then as_fn_error $? "conditional \"MODULE__TYPING\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE__XXSUBINTERPRETERS_TRUE}" && test -z "${MODULE__XXSUBINTERPRETERS_FALSE}"; then + as_fn_error $? "conditional \"MODULE__XXSUBINTERPRETERS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__ZONEINFO_TRUE}" && test -z "${MODULE__ZONEINFO_FALSE}"; then as_fn_error $? "conditional \"MODULE__ZONEINFO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE__MULTIPROCESSING_TRUE}" && test -z "${MODULE__MULTIPROCESSING_FALSE}"; then + as_fn_error $? "conditional \"MODULE__MULTIPROCESSING\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__POSIXSHMEM_TRUE}" && test -z "${MODULE__POSIXSHMEM_FALSE}"; then + as_fn_error $? "conditional \"MODULE__POSIXSHMEM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_AUDIOOP_TRUE}" && test -z "${MODULE_AUDIOOP_FALSE}"; then + as_fn_error $? "conditional \"MODULE_AUDIOOP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__STATISTICS_TRUE}" && test -z "${MODULE__STATISTICS_FALSE}"; then as_fn_error $? "conditional \"MODULE__STATISTICS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -21045,6 +28268,18 @@ if test -z "${MODULE__DATETIME_TRUE}" && test -z "${MODULE__DATETIME_FALSE}"; th as_fn_error $? "conditional \"MODULE__DATETIME\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE_FCNTL_TRUE}" && test -z "${MODULE_FCNTL_FALSE}"; then + as_fn_error $? "conditional \"MODULE_FCNTL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_MMAP_TRUE}" && test -z "${MODULE_MMAP_FALSE}"; then + as_fn_error $? "conditional \"MODULE_MMAP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__SOCKET_TRUE}" && test -z "${MODULE__SOCKET_FALSE}"; then + as_fn_error $? "conditional \"MODULE__SOCKET\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE_GRP_TRUE}" && test -z "${MODULE_GRP_FALSE}"; then as_fn_error $? "conditional \"MODULE_GRP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -21053,6 +28288,10 @@ if test -z "${MODULE_OSSAUDIODEV_TRUE}" && test -z "${MODULE_OSSAUDIODEV_FALSE}" as_fn_error $? "conditional \"MODULE_OSSAUDIODEV\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE_PWD_TRUE}" && test -z "${MODULE_PWD_FALSE}"; then + as_fn_error $? "conditional \"MODULE_PWD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE_RESOURCE_TRUE}" && test -z "${MODULE_RESOURCE_FALSE}"; then as_fn_error $? "conditional \"MODULE_RESOURCE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -21137,18 +28376,86 @@ if test -z "${MODULE__BLAKE2_TRUE}" && test -z "${MODULE__BLAKE2_FALSE}"; then as_fn_error $? "conditional \"MODULE__BLAKE2\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE__CRYPT_TRUE}" && test -z "${MODULE__CRYPT_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CRYPT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__CTYPES_TRUE}" && test -z "${MODULE__CTYPES_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CTYPES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__CURSES_TRUE}" && test -z "${MODULE__CURSES_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CURSES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__CURSES_PANEL_TRUE}" && test -z "${MODULE__CURSES_PANEL_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CURSES_PANEL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__DECIMAL_TRUE}" && test -z "${MODULE__DECIMAL_FALSE}"; then as_fn_error $? "conditional \"MODULE__DECIMAL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE__DBM_TRUE}" && test -z "${MODULE__DBM_FALSE}"; then + as_fn_error $? "conditional \"MODULE__DBM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__GDBM_TRUE}" && test -z "${MODULE__GDBM_FALSE}"; then + as_fn_error $? "conditional \"MODULE__GDBM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_NIS_TRUE}" && test -z "${MODULE_NIS_FALSE}"; then + as_fn_error $? "conditional \"MODULE_NIS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_READLINE_TRUE}" && test -z "${MODULE_READLINE_FALSE}"; then + as_fn_error $? "conditional \"MODULE_READLINE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__SQLITE3_TRUE}" && test -z "${MODULE__SQLITE3_FALSE}"; then as_fn_error $? "conditional \"MODULE__SQLITE3\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE__TKINTER_TRUE}" && test -z "${MODULE__TKINTER_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TKINTER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__UUID_TRUE}" && test -z "${MODULE__UUID_FALSE}"; then + as_fn_error $? "conditional \"MODULE__UUID\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_ZLIB_TRUE}" && test -z "${MODULE_ZLIB_FALSE}"; then + as_fn_error $? "conditional \"MODULE_ZLIB\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_BINASCII_TRUE}" && test -z "${MODULE_BINASCII_FALSE}"; then + as_fn_error $? "conditional \"MODULE_BINASCII\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__BZ2_TRUE}" && test -z "${MODULE__BZ2_FALSE}"; then + as_fn_error $? "conditional \"MODULE__BZ2\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__LZMA_TRUE}" && test -z "${MODULE__LZMA_FALSE}"; then + as_fn_error $? "conditional \"MODULE__LZMA\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__SSL_TRUE}" && test -z "${MODULE__SSL_FALSE}"; then + as_fn_error $? "conditional \"MODULE__SSL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__HASHLIB_TRUE}" && test -z "${MODULE__HASHLIB_FALSE}"; then + as_fn_error $? "conditional \"MODULE__HASHLIB\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__TESTCAPI_TRUE}" && test -z "${MODULE__TESTCAPI_FALSE}"; then as_fn_error $? "conditional \"MODULE__TESTCAPI\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE__TESTCLINIC_TRUE}" && test -z "${MODULE__TESTCLINIC_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TESTCLINIC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__TESTINTERNALCAPI_TRUE}" && test -z "${MODULE__TESTINTERNALCAPI_FALSE}"; then as_fn_error $? "conditional \"MODULE__TESTINTERNALCAPI\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -21165,6 +28472,10 @@ if test -z "${MODULE__TESTMULTIPHASE_TRUE}" && test -z "${MODULE__TESTMULTIPHASE as_fn_error $? "conditional \"MODULE__TESTMULTIPHASE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE_XXSUBTYPE_TRUE}" && test -z "${MODULE_XXSUBTYPE_FALSE}"; then + as_fn_error $? "conditional \"MODULE_XXSUBTYPE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__XXTESTFUZZ_TRUE}" && test -z "${MODULE__XXTESTFUZZ_FALSE}"; then as_fn_error $? "conditional \"MODULE__XXTESTFUZZ\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -21173,6 +28484,14 @@ if test -z "${MODULE__CTYPES_TEST_TRUE}" && test -z "${MODULE__CTYPES_TEST_FALSE as_fn_error $? "conditional \"MODULE__CTYPES_TEST\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE_XXLIMITED_TRUE}" && test -z "${MODULE_XXLIMITED_FALSE}"; then + as_fn_error $? "conditional \"MODULE_XXLIMITED\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE_XXLIMITED_35_TRUE}" && test -z "${MODULE_XXLIMITED_35_FALSE}"; then + as_fn_error $? "conditional \"MODULE_XXLIMITED_35\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 @@ -21570,7 +28889,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by python $as_me 3.11, which was +This file was extended by python $as_me 3.12, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -21626,13 +28945,13 @@ $config_files Configuration headers: $config_headers -Report bugs to ." +Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -python config.status 3.11 +python config.status 3.12 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -21764,6 +29083,7 @@ do "Misc/python.pc") CONFIG_FILES="$CONFIG_FILES Misc/python.pc" ;; "Misc/python-embed.pc") CONFIG_FILES="$CONFIG_FILES Misc/python-embed.pc" ;; "Misc/python-config.sh") CONFIG_FILES="$CONFIG_FILES Misc/python-config.sh" ;; + "Modules/Setup.bootstrap") CONFIG_FILES="$CONFIG_FILES Modules/Setup.bootstrap" ;; "Modules/Setup.stdlib") CONFIG_FILES="$CONFIG_FILES Modules/Setup.stdlib" ;; "Modules/ld_so_aix") CONFIG_FILES="$CONFIG_FILES Modules/ld_so_aix" ;; @@ -22364,28 +29684,51 @@ $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi -echo "creating Modules/Setup.local" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating Modules/Setup.local" >&5 +$as_echo "$as_me: creating Modules/Setup.local" >&6;} if test ! -f Modules/Setup.local then echo "# Edit this file for local setup changes" >Modules/Setup.local fi -echo "creating Makefile" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating Makefile" >&5 +$as_echo "$as_me: creating Makefile" >&6;} $SHELL $srcdir/Modules/makesetup -c $srcdir/Modules/config.c.in \ -s Modules \ - Modules/Setup.local $srcdir/Modules/Setup.bootstrap $srcdir/Modules/Setup + Modules/Setup.local Modules/Setup.stdlib Modules/Setup.bootstrap $srcdir/Modules/Setup +if test $? -ne 0; then + as_fn_error $? "makesetup failed" "$LINENO" 5 +fi + mv config.c Modules if test -z "$PKG_CONFIG"; then - echo "" >&6 - echo "pkg-config is missing. Some dependencies may not be detected correctly." >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pkg-config is missing. Some dependencies may not be detected correctly." >&5 +$as_echo "$as_me: WARNING: pkg-config is missing. Some dependencies may not be detected correctly." >&2;} fi if test "$Py_OPT" = 'false' -a "$Py_DEBUG" != 'true'; then - echo "" >&6 - echo "" >&6 - echo "If you want a release build with all stable optimizations active (PGO, etc)," >&6 - echo "please run ./configure --enable-optimizations" >&6 - echo "" >&6 - echo "" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: + +If you want a release build with all stable optimizations active (PGO, etc), +please run ./configure --enable-optimizations +" >&5 +$as_echo "$as_me: + +If you want a release build with all stable optimizations active (PGO, etc), +please run ./configure --enable-optimizations +" >&6;} +fi + +if test "x$PY_SUPPORT_TIER" = x0; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: + +Platform \"$host\" with compiler \"$ac_cv_cc_name\" is not supported by the +CPython core team, see https://peps.python.org/pep-0011/ for more information. +" >&5 +$as_echo "$as_me: WARNING: + +Platform \"$host\" with compiler \"$ac_cv_cc_name\" is not supported by the +CPython core team, see https://peps.python.org/pep-0011/ for more information. +" >&2;} fi diff --git a/configure.ac b/configure.ac index ee379b71417..5eee4586680 100644 --- a/configure.ac +++ b/configure.ac @@ -2,15 +2,15 @@ dnl *************************************************** dnl * Please run autoreconf -if to test your changes! * dnl *************************************************** dnl -dnl Python's configure script requires autoconf 2.69 and autoconf-archive. +dnl Python's configure.ac file requires autoconf 2.69 and autoconf-archive. dnl # Set VERSION so we only need to edit in one place (i.e., here) -m4_define(PYTHON_VERSION, 3.11) +m4_define(PYTHON_VERSION, 3.12) AC_PREREQ([2.69]) -AC_INIT([python],[PYTHON_VERSION],[https://bugs.python.org/]) +AC_INIT([python],[PYTHON_VERSION],[https://github.com/python/cpython/issues/]) m4_ifdef( [AX_C_FLOAT_WORDS_BIGENDIAN], @@ -49,6 +49,48 @@ AC_DEFUN([WITH_SAVE_ENV], [RESTORE_ENV] )dnl +dnl PY_CHECK_FUNC(FUNCTION, [INCLUDES], [AC_DEFINE-VAR]) +AC_DEFUN([PY_CHECK_FUNC], +[ AS_VAR_PUSHDEF([py_var], [ac_cv_func_$1]) + AS_VAR_PUSHDEF([py_define], m4_ifblank([$3], [[HAVE_]m4_toupper($1)], [$3])) + AC_CACHE_CHECK( + [for $1], + [py_var], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([$2], [void *x=$1])], + [AS_VAR_SET([py_var], [yes])], + [AS_VAR_SET([py_var], [no])])] + ) + AS_VAR_IF( + [py_var], + [yes], + [AC_DEFINE([py_define], [1], [Define if you have the '$1' function.])]) + AS_VAR_POPDEF([py_var]) + AS_VAR_POPDEF([py_define]) +]) + +dnl PY_CHECK_LIB(LIBRARY, FUNCTION, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], [OTHER-LIBRARIES]) +dnl Like AC_CHECK_LIB() but does not modify LIBS +AC_DEFUN([PY_CHECK_LIB], +[AS_VAR_COPY([py_check_lib_save_LIBS], [LIBS])] +[AC_CHECK_LIB($1, $2, $3, $4, $5)] +[AS_VAR_COPY([LIBS], [py_check_lib_save_LIBS])] +) + +dnl PY_CHECK_EMSCRIPTEN_PORT(PKG_VAR, [EMPORT_ARGS]) +dnl Use Emscripten port unless user passes ${PKG_VAR}_CFLAGS +dnl or ${PKG_VAR}_LIBS to configure. +AC_DEFUN([PY_CHECK_EMSCRIPTEN_PORT], [ + AS_VAR_PUSHDEF([py_cflags], [$1_CFLAGS]) + AS_VAR_PUSHDEF([py_libs], [$1_LIBS]) + AS_IF([test "$ac_sys_system" = "Emscripten" -a -z "$py_cflags" -a -z "$py_libs"], [ + py_cflags="$2" + py_libs="$2" + ]) + AS_VAR_POPDEF([py_cflags]) + AS_VAR_POPDEF([py_libs]) +]) + AC_SUBST(BASECPPFLAGS) if test "$srcdir" != . -a "$srcdir" != "$(pwd)"; then # If we're building out-of-tree, we need to make sure the following @@ -93,34 +135,84 @@ AC_CANONICAL_HOST AC_SUBST(build) AC_SUBST(host) +AS_VAR_IF([cross_compiling], [maybe], + [AC_MSG_ERROR([Cross compiling required --host=HOST-TUPLE and --build=ARCH])] +) + # pybuilddir.txt will be created by --generate-posix-vars in the Makefile rm -f pybuilddir.txt -AC_CHECK_PROGS(PYTHON_FOR_REGEN, python$PACKAGE_VERSION python3 python, python3) +AC_ARG_WITH( + [build-python], + [AS_HELP_STRING([--with-build-python=python]PYTHON_VERSION, + [path to build python binary for cross compiling (default: _bootstrap_python or python]PYTHON_VERSION[)])], + [ + AC_MSG_CHECKING([for --with-build-python]) + + AS_VAR_IF([with_build_python], [yes], [with_build_python=python$PACKAGE_VERSION]) + AS_VAR_IF([with_build_python], [no], [AC_MSG_ERROR([invalid --with-build-python option: expected path or "yes", not "no"])]) + + if ! $(command -v "$with_build_python" >/dev/null 2>&1); then + AC_MSG_ERROR([invalid or missing build python binary "$with_build_python"]) + fi + build_python_ver=$($with_build_python -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')") + if test "$build_python_ver" != "$PACKAGE_VERSION"; then + AC_MSG_ERROR(["$with_build_python" has incompatible version $build_python_ver (expected: $PACKAGE_VERSION)]) + fi + dnl Build Python interpreter is used for regeneration and freezing. + ac_cv_prog_PYTHON_FOR_REGEN=$with_build_python + PYTHON_FOR_FREEZE="$with_build_python" + PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`:)$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) '$with_build_python + AC_MSG_RESULT([$with_build_python]) + ], [ + AS_VAR_IF([cross_compiling], [yes], + [AC_MSG_ERROR([Cross compiling requires --with-build-python])] + ) + PYTHON_FOR_BUILD='./$(BUILDPYTHON) -E' + PYTHON_FOR_FREEZE="./_bootstrap_python" + ] +) +AC_SUBST([PYTHON_FOR_BUILD]) + +AC_MSG_CHECKING([for Python interpreter freezing]) +AC_MSG_RESULT([$PYTHON_FOR_FREEZE]) +AC_SUBST([PYTHON_FOR_FREEZE]) + +AS_VAR_IF([cross_compiling], [yes], + [ + dnl external build Python, freezing depends on Programs/_freeze_module.py + FREEZE_MODULE_BOOTSTRAP='$(PYTHON_FOR_FREEZE) $(srcdir)/Programs/_freeze_module.py' + FREEZE_MODULE_BOOTSTRAP_DEPS='$(srcdir)/Programs/_freeze_module.py' + FREEZE_MODULE='$(FREEZE_MODULE_BOOTSTRAP)' + FREEZE_MODULE_DEPS='$(FREEZE_MODULE_BOOTSTRAP_DEPS)' + PYTHON_FOR_BUILD_DEPS='' + ], + [ + dnl internal build tools also depend on Programs/_freeze_module and _bootstrap_python. + FREEZE_MODULE_BOOTSTRAP='./Programs/_freeze_module' + FREEZE_MODULE_BOOTSTRAP_DEPS="Programs/_freeze_module" + FREEZE_MODULE='$(PYTHON_FOR_FREEZE) $(srcdir)/Programs/_freeze_module.py' + FREEZE_MODULE_DEPS="_bootstrap_python \$(srcdir)/Programs/_freeze_module.py" + PYTHON_FOR_BUILD_DEPS='$(BUILDPYTHON)' + ] +) +AC_SUBST([FREEZE_MODULE_BOOTSTRAP]) +AC_SUBST([FREEZE_MODULE_BOOTSTRAP_DEPS]) +AC_SUBST([FREEZE_MODULE]) +AC_SUBST([FREEZE_MODULE_DEPS]) +AC_SUBST([PYTHON_FOR_BUILD_DEPS]) + +AC_CHECK_PROGS([PYTHON_FOR_REGEN], + [python$PACKAGE_VERSION python3.11 python3.10 python3.9 python3.8 python3.7 python3.6 python3 python], + [python3]) AC_SUBST(PYTHON_FOR_REGEN) -if test "$cross_compiling" = yes; then - AC_MSG_CHECKING([for python interpreter for cross build]) - if test -z "$PYTHON_FOR_BUILD"; then - for interp in python$PACKAGE_VERSION python3 python; do - which $interp >/dev/null 2>&1 || continue - if $interp -c "import sys;sys.exit(not '.'.join(str(n) for n in sys.version_info@<:@:2@:>@) == '$PACKAGE_VERSION')"; then - break - fi - interp= - done - if test x$interp = x; then - AC_MSG_ERROR([python$PACKAGE_VERSION interpreter not found]) - fi - AC_MSG_RESULT($interp) - PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`:)$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) '$interp - fi -elif test "$cross_compiling" = maybe; then - AC_MSG_ERROR([Cross compiling required --host=HOST-TUPLE and --build=ARCH]) +AC_MSG_CHECKING([Python for regen version]) +if command -v "$PYTHON_FOR_REGEN" >/dev/null 2>&1; then + AC_MSG_RESULT([$($PYTHON_FOR_REGEN -V 2>/dev/null)]) else - PYTHON_FOR_BUILD='./$(BUILDPYTHON) -E' + AC_MSG_RESULT([missing]) fi -AC_SUBST(PYTHON_FOR_BUILD) dnl Ensure that if prefix is specified, it does not end in a slash. If dnl it does, we get path names containing '//' which is both ugly and @@ -456,6 +548,12 @@ then *-*-vxworks*) ac_sys_system=VxWorks ;; + *-*-emscripten) + ac_sys_system=Emscripten + ;; + *-*-wasi) + ac_sys_system=WASI + ;; *) # for now, limit cross builds to known configurations MACHDEP="unknown" @@ -505,6 +603,9 @@ if test "$cross_compiling" = yes; then *-*-vxworks*) _host_cpu=$host_cpu ;; + wasm32-*-* | wasm64-*-*) + _host_cpu=$host_cpu + ;; *) # for now, limit cross builds to known configurations MACHDEP="unknown" @@ -652,8 +753,33 @@ if test -z "$CFLAGS"; then CFLAGS= fi +dnl Emscripten SDK and WASI SDK default to wasm32. +dnl On Emscripten use MEMORY64 setting to build target wasm64-emscripten. +dnl for wasm64. +AS_CASE([$host], + [wasm64-*-emscripten], [ + AS_VAR_APPEND([CFLAGS], [" -sMEMORY64=1"]) + AS_VAR_APPEND([LDFLAGS], [" -sMEMORY64=1"]) + ], +) + if test "$ac_sys_system" = "Darwin" then + dnl look for SDKROOT + AC_CHECK_PROG([HAS_XCRUN], [xcrun], [yes], [missing]) + AC_MSG_CHECKING([macOS SDKROOT]) + if test -z "$SDKROOT"; then + dnl SDKROOT not set + if test "$HAS_XCRUN" = "yes"; then + dnl detect with Xcode + SDKROOT=$(xcrun --show-sdk-path) + else + dnl default to root + SDKROOT="/" + fi + fi + AC_MSG_RESULT([$SDKROOT]) + # Compiler selection on MacOSX is more complicated than # AC_PROG_CC can handle, see Mac/README for more # information @@ -714,35 +840,41 @@ AC_PROG_GREP AC_PROG_SED AC_PROG_EGREP +dnl detect compiler name +dnl check for xlc before clang, newer xlc's can use clang as frontend. +dnl check for GCC last, other compilers set __GNUC__, too. +dnl msvc is listed for completeness. +AC_CACHE_CHECK([for CC compiler name], [ac_cv_cc_name], [ +cat > conftest.c <conftest.out 2>/dev/null; then + ac_cv_cc_name=`grep -v '^#' conftest.out | grep -v '^ *$' | tr -d ' '` +else + ac_cv_cc_name="unknown" +fi +rm -f conftest.c conftest.out +]) + # checks for UNIX variants that set C preprocessor variables # may set _GNU_SOURCE, __EXTENSIONS__, _POSIX_PTHREAD_SEMANTICS, # _POSIX_SOURCE, _POSIX_1_SOURCE, and more AC_USE_SYSTEM_EXTENSIONS AC_SUBST(CXX) -AC_SUBST(MAINCC) -AC_MSG_CHECKING(for --with-cxx-main=) -AC_ARG_WITH(cxx_main, - AS_HELP_STRING([--with-cxx-main@<:@=COMPILER@:>@], - [compile main() and link Python executable with C++ compiler specified in COMPILER (default is $CXX)]), -[ - - case $withval in - no) with_cxx_main=no - MAINCC='$(CC)';; - yes) with_cxx_main=yes - MAINCC='$(CXX)';; - *) with_cxx_main=yes - MAINCC=$withval - if test -z "$CXX" - then - CXX=$withval - fi;; - esac], [ - with_cxx_main=no - MAINCC='$(CC)' -]) -AC_MSG_RESULT($with_cxx_main) preset_cxx="$CXX" if test -z "$CXX" @@ -777,7 +909,7 @@ fi AC_MSG_CHECKING([for the platform triplet based on compiler characteristics]) -cat >> conftest.c < conftest.c <> conftest.c <conftest.out 2>/dev/null; then PLATFORM_TRIPLET=`grep -v '^#' conftest.out | grep -v '^ *$' | tr -d ' '` + case "$build_os" in + linux-musl*) + PLATFORM_TRIPLET=`echo "$PLATFORM_TRIPLET" | sed 's/linux-gnu/linux-musl/'` + ;; + esac AC_MSG_RESULT([$PLATFORM_TRIPLET]) else AC_MSG_RESULT([none]) fi rm -f conftest.c conftest.out -if test x$PLATFORM_TRIPLET != xdarwin; then - MULTIARCH=$($CC --print-multiarch 2>/dev/null) -fi -AC_SUBST(MULTIARCH) +AC_MSG_CHECKING([for multiarch]) +AS_CASE([$ac_sys_system], + [Darwin*], [MULTIARCH=""], + [FreeBSD*], [MULTIARCH=""], + [MULTIARCH=$($CC --print-multiarch 2>/dev/null)] +) +AC_SUBST([MULTIARCH]) +AC_MSG_RESULT([$MULTIARCH]) if test x$PLATFORM_TRIPLET != x && test x$MULTIARCH != x; then if test x$PLATFORM_TRIPLET != x$MULTIARCH; then @@ -944,14 +1101,51 @@ elif test x$PLATFORM_TRIPLET != x && test x$MULTIARCH = x; then MULTIARCH=$PLATFORM_TRIPLET fi AC_SUBST(PLATFORM_TRIPLET) + if test x$MULTIARCH != x; then MULTIARCH_CPPFLAGS="-DMULTIARCH=\\\"$MULTIARCH\\\"" fi AC_SUBST(MULTIARCH_CPPFLAGS) +dnl Support tiers according to https://peps.python.org/pep-0011/ +dnl +dnl NOTE: Windows support tiers are defined in PC/pyconfig.h. +dnl +AC_MSG_CHECKING([for PEP 11 support tier]) +AS_CASE([$host/$ac_cv_cc_name], + [x86_64-*-linux-gnu/gcc], [PY_SUPPORT_TIER=1], dnl Linux on AMD64, any vendor, glibc, gcc + [x86_64-apple-darwin*/clang], [PY_SUPPORT_TIER=1], dnl macOS on Intel, any version + [i686-pc-windows-msvc/msvc], [PY_SUPPORT_TIER=1], dnl 32bit Windows on Intel, MSVC + [x86_64-pc-windows-msvc/msvc], [PY_SUPPORT_TIER=1], dnl 64bit Windows on AMD64, MSVC + + [aarch64-apple-darwin*/clang], [PY_SUPPORT_TIER=2], dnl macOS on M1, any version + [aarch64-*-linux-gnu/gcc], [PY_SUPPORT_TIER=2], dnl Linux ARM64, glibc, gcc+clang + [aarch64-*-linux-gnu/clang], [PY_SUPPORT_TIER=2], + [powerpc64le-*-linux-gnu/gcc], [PY_SUPPORT_TIER=2], dnl Linux on PPC64 little endian, glibc, gcc + [x86_64-*-linux-gnu/clang], [PY_SUPPORT_TIER=2], dnl Linux on AMD64, any vendor, glibc, clang + + [aarch64-pc-windows-msvc/msvc], [PY_SUPPORT_TIER=3], dnl Windows ARM64, MSVC + [armv7l-*-linux-gnueabihf/gcc], [PY_SUPPORT_TIER=3], dnl ARMv7 LE with hardware floats, any vendor, glibc, gcc + [powerpc64le-*-linux-gnu/clang], [PY_SUPPORT_TIER=3], dnl Linux on PPC64 little endian, glibc, clang + [s390x-*-linux-gnu/gcc], [PY_SUPPORT_TIER=3], dnl Linux on 64bit s390x (big endian), glibc, gcc + [wasm32-unknown-emscripten/clang], [PY_SUPPORT_TIER=3], dnl WebAssembly Emscripten + [wasm32-unknown-wasi/clang], [PY_SUPPORT_TIER=3], dnl WebAssembly System Interface + [x86_64-*-freebsd*/clang], [PY_SUPPORT_TIER=3], dnl FreeBSD on AMD64 + [PY_SUPPORT_TIER=0] +) + +AS_CASE([$PY_SUPPORT_TIER], + [1], [AC_MSG_RESULT([$host/$ac_cv_cc_name has tier 1 (supported)])], + [2], [AC_MSG_RESULT([$host/$ac_cv_cc_name has tier 2 (supported)])], + [3], [AC_MSG_RESULT([$host/$ac_cv_cc_name has tier 3 (partially supported)])], + [AC_MSG_WARN([$host/$ac_cv_cc_name is not supported])] +) + +AC_DEFINE_UNQUOTED([PY_SUPPORT_TIER], [$PY_SUPPORT_TIER], [PEP 11 Support tier (1, 2, 3 or 0 for unsupported)]) + AC_CACHE_CHECK([for -Wl,--no-as-needed], [ac_cv_wl_no_as_needed], [ save_LDFLAGS="$LDFLAGS" - AS_VAR_APPEND([LDFLAGS], [-Wl,--no-as-needed]) + AS_VAR_APPEND([LDFLAGS], [" -Wl,--no-as-needed"]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [NO_AS_NEEDED="-Wl,--no-as-needed" ac_cv_wl_no_as_needed=yes], @@ -962,7 +1156,7 @@ AC_CACHE_CHECK([for -Wl,--no-as-needed], [ac_cv_wl_no_as_needed], [ AC_SUBST(NO_AS_NEEDED) AC_MSG_CHECKING([for the Android API level]) -cat >> conftest.c < conftest.c <conftest.out 2>/dev/null; then _arm_arch=`sed -n -e '/__ARM_ARCH/d' -e 's/^arm_arch = //p' conftest.out` AC_MSG_RESULT([$ANDROID_API_LEVEL]) if test -z "$ANDROID_API_LEVEL"; then - echo 'Fatal: you must define __ANDROID_API__' - exit 1 + AC_MSG_ERROR([Fatal: you must define __ANDROID_API__]) fi AC_DEFINE_UNQUOTED(ANDROID_API_LEVEL, $ANDROID_API_LEVEL, [The Android API level.]) @@ -993,23 +1186,91 @@ fi rm -f conftest.c conftest.out # Check for unsupported systems -case $ac_sys_system/$ac_sys_release in -atheos*|Linux*/1*) - echo This system \($ac_sys_system/$ac_sys_release\) is no longer supported. - echo See README for details. - exit 1;; -esac +AS_CASE([$ac_sys_system/$ac_sys_release], + [atheos*|Linux*/1*], [ + AC_MSG_ERROR([m4_normalize([ + This system \($ac_sys_system/$ac_sys_release\) is no longer supported. + See README for details. + ])]) + ] +) -AC_MSG_CHECKING(for --with-suffix) -AC_ARG_WITH(suffix, - AS_HELP_STRING([--with-suffix=SUFFIX], [set executable suffix to SUFFIX (default is '.exe')]), +AC_MSG_CHECKING([for --with-emscripten-target]) +AC_ARG_WITH([emscripten-target], + [AS_HELP_STRING([--with-emscripten-target=@<:@browser|node@:>@], [Emscripten platform])], [ - case $withval in - no) EXEEXT=;; - yes) EXEEXT=.exe;; - *) EXEEXT=$withval;; - esac]) -AC_MSG_RESULT($EXEEXT) + AS_VAR_IF([ac_sys_system], [Emscripten], [ + AS_CASE([$with_emscripten_target], + [browser], [ac_sys_emscripten_target=browser], + [node], [ac_sys_emscripten_target=node], +dnl Debug builds with source map / dwarf symbols. Py_DEBUG builds easily +dnl run out of stack space. Detached sybmols and map prohibit some +dnl optimizations and increase file size. Options are undocumented so we +dnl are free to remove them in the future. + [browser-debug], [ac_sys_emscripten_target=browser-debug], + [node-debug], [ac_sys_emscripten_target=node-debug], + [AC_MSG_ERROR([Invalid argument: --with-emscripten-target=browser|node])] + ) + ], [ + AC_MSG_ERROR([--with-emscripten-target only applies to Emscripten]) + ]) +], [ + AS_VAR_IF([ac_sys_system], [Emscripten], [ac_sys_emscripten_target=browser]) +]) +AC_MSG_RESULT([$ac_sys_emscripten_target]) + +dnl On Emscripten dlopen() requires -s MAIN_MODULE and -fPIC. The flags +dnl disables dead code elimination and increases the size of the WASM module +dnl by about 1.5 to 2MB. MAIN_MODULE defines __wasm_mutable_globals__. +dnl See https://emscripten.org/docs/compiling/Dynamic-Linking.html +AC_MSG_CHECKING([for --enable-wasm-dynamic-linking]) +AC_ARG_ENABLE([wasm-dynamic-linking], + [AS_HELP_STRING([--enable-wasm-dynamic-linking], + [Enable dynamic linking support for WebAssembly (default is no)])], +[ + AS_CASE([$ac_sys_system], + [Emscripten], [], + [WASI], [AC_MSG_ERROR([WASI dynamic linking is not implemented yet.])], + [AC_MSG_ERROR([--enable-wasm-dynamic-linking only applies to Emscripten and WASI])] + ) +], [ + enable_wasm_dynamic_linking=missing +]) +AC_MSG_RESULT([$enable_wasm_dynamic_linking]) + +AC_MSG_CHECKING([for --enable-wasm-pthreads]) +AC_ARG_ENABLE([wasm-pthreads], + [AS_HELP_STRING([--enable-wasm-pthreads], + [Enable pthread emulation for WebAssembly (default is no)])], +[ + AS_CASE([$ac_sys_system], + [Emscripten], [], + [WASI], [AC_MSG_ERROR([WASI threading is not implemented yet.])], + [AC_MSG_ERROR([--enable-wasm-pthreads only applies to Emscripten and WASI])] + ) +], [ + enable_wasm_pthreads=missing +]) +AC_MSG_RESULT([$enable_wasm_pthreads]) + +AC_MSG_CHECKING([for --with-suffix]) +AC_ARG_WITH([suffix], + [AS_HELP_STRING([--with-suffix=SUFFIX], [set executable suffix to SUFFIX (default is empty, yes is mapped to '.exe')])], +[ + AS_CASE([$with_suffix], + [no], [EXEEXT=], + [yes], [EXEEXT=.exe], + [EXEEXT=$with_suffix] + ) +], [ + AS_CASE([$ac_sys_system/$ac_sys_emscripten_target], + [Emscripten/browser*], [EXEEXT=.js], + [Emscripten/node*], [EXEEXT=.js], + [WASI/*], [EXEEXT=.wasm], + [EXEEXT=] + ) +]) +AC_MSG_RESULT([$EXEEXT]) # Test whether we're running on a non-case-sensitive system, in which # case we give a warning if no ext is given @@ -1019,7 +1280,7 @@ if test ! -d CaseSensitiveTestDir; then mkdir CaseSensitiveTestDir fi -if test -d casesensitivetestdir +if test -d casesensitivetestdir && test -z "$EXEEXT" then AC_MSG_RESULT(yes) BUILDEXEEXT=.exe @@ -1084,7 +1345,7 @@ AC_SUBST(LINKCC) AC_MSG_CHECKING(LINKCC) if test -z "$LINKCC" then - LINKCC='$(PURIFY) $(MAINCC)' + LINKCC='$(PURIFY) $(CC)' case $ac_sys_system in QNX*) # qcc must be used because the other compilers do not @@ -1113,7 +1374,7 @@ AC_MSG_RESULT($EXPORTSYMS) # make sure we default having it set to "no": this is used by # distutils.unixccompiler to know if it should add --enable-new-dtags # to linker command lines, and failing to detect GNU ld simply results -# in the same bahaviour as before. +# in the same behaviour as before. AC_SUBST(GNULD) AC_MSG_CHECKING(for GNU ld) ac_prog=ld @@ -1143,13 +1404,30 @@ then fi AC_MSG_RESULT($enable_shared) +# --with-static-libpython +STATIC_LIBPYTHON=1 +AC_MSG_CHECKING(for --with-static-libpython) +AC_ARG_WITH(static-libpython, + AS_HELP_STRING([--without-static-libpython], + [do not build libpythonMAJOR.MINOR.a and do not install python.o (default is yes)]), +[ +if test "$withval" = no +then + AC_MSG_RESULT(no); + STATIC_LIBPYTHON=0 +else + AC_MSG_RESULT(yes); +fi], +[AC_MSG_RESULT(yes)]) +AC_SUBST(STATIC_LIBPYTHON) + AC_MSG_CHECKING(for --enable-profiling) AC_ARG_ENABLE(profiling, AS_HELP_STRING([--enable-profiling], [enable C-level code profiling with gprof (default is no)])) if test "x$enable_profiling" = xyes; then ac_save_cc="$CC" CC="$CC -pg" - AC_LINK_IFELSE([AC_LANG_SOURCE([[int main() { return 0; }]])], + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void) { return 0; }]])], [], [enable_profiling=no]) CC="$ac_save_cc" @@ -1246,8 +1524,89 @@ if test "$cross_compiling" = yes; then RUNSHARED= fi +AC_ARG_VAR([HOSTRUNNER], [Program to run CPython for the host platform]) +if test -z "$HOSTRUNNER" +then + AS_CASE([$ac_sys_system/$ac_sys_emscripten_target], + [Emscripten/node*], [ + AC_PATH_TOOL([NODE], [node], [node]) + HOSTRUNNER="$NODE" + # bigint for ctypes c_longlong, c_longdouble + # no longer available in Node 16 + AC_CACHE_CHECK([for node --experimental-wasm-bigint], [ac_cv_tool_node_wasm_bigint], [ + if $NODE -v --experimental-wasm-bigint > /dev/null 2>&1; then + ac_cv_tool_node_wasm_bigint=yes + else + ac_cv_tool_node_wasm_bigint=no + fi + ]) + AS_VAR_IF([ac_cv_tool_node_wasm_bigint], [yes], [ + AS_VAR_APPEND([HOSTRUNNER], [" --experimental-wasm-bigint"]) + ]) + + AS_VAR_IF([enable_wasm_pthreads], [yes], [ + AS_VAR_APPEND([HOSTRUNNER], [" --experimental-wasm-threads"]) + # no longer available in Node 16 + AC_CACHE_CHECK([for node --experimental-wasm-bulk-memory], [ac_cv_tool_node_wasm_bulk_memory], [ + if $NODE -v --experimental-wasm-bulk-memory > /dev/null 2>&1; then + ac_cv_tool_node_wasm_bulk_memory=yes + else + ac_cv_tool_node_wasm_bulk_memory=no + fi + ]) + AS_VAR_IF([ac_cv_tool_node_wasm_bulk_memory], [yes], [ + AS_VAR_APPEND([HOSTRUNNER], [" --experimental-wasm-bulk-memory"]) + ]) + ]) + + AS_VAR_IF([host_cpu], [wasm64], [AS_VAR_APPEND([HOSTRUNNER], [" --experimental-wasm-memory64"])]) + ], + dnl TODO: support other WASI runtimes + dnl wasmtime starts the proces with "/" as CWD. For OOT builds add the + dnl directory containing _sysconfigdata to PYTHONPATH. + [WASI/*], [HOSTRUNNER='wasmtime run --env PYTHONPATH=/$(shell realpath --relative-to $(abs_srcdir) $(abs_builddir))/$(shell cat pybuilddir.txt):/Lib --mapdir /::$(srcdir) --'], + [HOSTRUNNER=''] + ) +fi +AC_SUBST([HOSTRUNNER]) +AC_MSG_CHECKING([HOSTRUNNER]) +AC_MSG_RESULT([$HOSTRUNNER]) + +if test -n "$HOSTRUNNER"; then + dnl Pass hostrunner variable as env var in order to expand shell expressions. + PYTHON_FOR_BUILD="_PYTHON_HOSTRUNNER='$HOSTRUNNER' $PYTHON_FOR_BUILD" +fi + AC_MSG_RESULT($LDLIBRARY) +# LIBRARY_DEPS, LINK_PYTHON_OBJS and LINK_PYTHON_DEPS variable +AS_CASE([$ac_sys_system/$ac_sys_emscripten_target], + [Emscripten/browser*], [LIBRARY_DEPS='$(PY3LIBRARY) $(WASM_STDLIB) python.html python.worker.js'], + [LIBRARY_DEPS='$(PY3LIBRARY) $(EXPORTSYMS)'] +) +LINK_PYTHON_DEPS='$(LIBRARY_DEPS)' +if test "$PY_ENABLE_SHARED" = 1 || test "$enable_framework" ; then + LIBRARY_DEPS="\$(LDLIBRARY) $LIBRARY_DEPS" + if test "$STATIC_LIBPYTHON" = 1; then + LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS" + fi + # Link Python program to the shared library + LINK_PYTHON_OBJS='$(BLDLIBRARY)' +else + if test "$STATIC_LIBPYTHON" = 0; then + # Build Python needs object files but don't need to build + # Python static library + LINK_PYTHON_DEPS="$LIBRARY_DEPS \$(LIBRARY_OBJS)" + fi + LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS" + # Link Python program to object files + LINK_PYTHON_OBJS='$(LIBRARY_OBJS)' +fi +AC_SUBST(LIBRARY_DEPS) +AC_SUBST(LINK_PYTHON_DEPS) +AC_SUBST(LINK_PYTHON_OBJS) + +# ar program AC_SUBST(AR) AC_CHECK_TOOLS(AR, ar aal, ar) @@ -1258,17 +1617,6 @@ then ARFLAGS="rcs" fi -AC_CHECK_TOOLS([READELF], [readelf], [:]) -if test "$cross_compiling" = yes; then - case "$READELF" in - readelf|:) - AC_MSG_ERROR([readelf for the host is required for cross builds]) - ;; - esac -fi -AC_SUBST(READELF) - - case $MACHDEP in hp*|HP*) # install -d does not work on HP-UX @@ -1324,6 +1672,21 @@ then AC_DEFINE(Py_TRACE_REFS, 1, [Define if you want to enable tracing references for debugging purpose]) fi + +# Check for --enable-pystats +AC_MSG_CHECKING([for --enable-pystats]) +AC_ARG_ENABLE([pystats], + [AS_HELP_STRING( + [--enable-pystats], + [enable internal statistics gathering (default is no)])],, + [enable_pystats=no] +) +AC_MSG_RESULT([$enable_pystats]) + +AS_VAR_IF([enable_pystats], [yes], [ + AC_DEFINE([Py_STATS], [1], [Define if you want to enable internal statistics gathering.]) +]) + # Check for --with-assertions. # This allows enabling assertions without Py_DEBUG. assertions='false' @@ -1363,6 +1726,7 @@ else AC_MSG_RESULT(no); fi], [AC_MSG_RESULT(no)]) + if test "$Py_OPT" = 'true' ; then # Intentionally not forcing Py_LTO='true' here. Too many toolchains do not # compile working code using it and both test_distutils and test_gdb are @@ -1379,8 +1743,12 @@ if test "$Py_OPT" = 'true' ; then ]) ;; esac - - +elif test "$ac_sys_system" = "Emscripten" -o "$ac_sys_system" = "WASI"; then + dnl Emscripten does not support shared extensions yet. Build + dnl "python.[js,wasm]", "pybuilddir.txt", and "platform" files. + DEF_MAKE_ALL_RULE="build_wasm" + REQUIRE_PGO="no" + DEF_MAKE_RULE="all" else DEF_MAKE_ALL_RULE="build_all" REQUIRE_PGO="no" @@ -1395,7 +1763,7 @@ then fi AC_MSG_RESULT($PROFILE_TASK) -# Make llvm-relatec checks work on systems where llvm tools are not installed with their +# Make llvm-related checks work on systems where llvm tools are not installed with their # normal names in the default $PATH (ie: Ubuntu). They exist under the # non-suffixed name in their versioned llvm directory. @@ -1449,6 +1817,10 @@ esac if test "$Py_LTO" = 'true' ; then case $CC in *clang*) + LDFLAGS_NOLTO="-fno-lto" + dnl Clang linker requires -flto in order to link objects with LTO information. + dnl Thin LTO is faster and works for object files with full LTO information, too. + AX_CHECK_COMPILE_FLAG([-flto=thin],[LDFLAGS_NOLTO="-flto=thin"],[LDFLAGS_NOLTO="-flto"]) AC_SUBST(LLVM_AR) AC_PATH_TOOL(LLVM_AR, llvm-ar, '', ${llvm_path}) AC_SUBST(LLVM_AR_FOUND) @@ -1482,31 +1854,48 @@ if test "$Py_LTO" = 'true' ; then # Any changes made here should be reflected in the GCC+Darwin case below if test $Py_LTO_POLICY = default then - LTOFLAGS="-flto -Wl,-export_dynamic" - LTOCFLAGS="-flto" + # Check that ThinLTO is accepted. + AX_CHECK_COMPILE_FLAG([-flto=thin],[ + LTOFLAGS="-flto=thin -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" + LTOCFLAGS="-flto=thin" + ],[ + LTOFLAGS="-flto -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" + LTOCFLAGS="-flto" + ] + ) else - LTOFLAGS="-flto=${Py_LTO_POLICY} -Wl,-export_dynamic" + LTOFLAGS="-flto=${Py_LTO_POLICY} -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" LTOCFLAGS="-flto=${Py_LTO_POLICY}" fi ;; *) if test $Py_LTO_POLICY = default then - LTOFLAGS="-flto" + # Check that ThinLTO is accepted + AX_CHECK_COMPILE_FLAG([-flto=thin],[LTOFLAGS="-flto=thin"],[LTOFLAGS="-flto"]) else LTOFLAGS="-flto=${Py_LTO_POLICY}" fi ;; esac ;; + *emcc*) + if test "$Py_LTO_POLICY" != "default"; then + AC_MSG_ERROR([emcc supports only default lto.]) + fi + LTOFLAGS="-flto" + LTOCFLAGS="-flto" + ;; *gcc*) if test $Py_LTO_POLICY = thin then AC_MSG_ERROR([thin lto is not supported under gcc compiler.]) fi + dnl flag to disable lto during linking + LDFLAGS_NOLTO="-fno-lto" case $ac_sys_system in Darwin*) - LTOFLAGS="-flto -Wl,-export_dynamic" + LTOFLAGS="-flto -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" LTOCFLAGS="-flto" ;; *) @@ -1527,6 +1916,61 @@ if test "$Py_LTO" = 'true' ; then LDFLAGS_NODIST="$LDFLAGS_NODIST $LTOFLAGS" fi +# Enable bolt flags +Py_BOLT='false' +AC_MSG_CHECKING(for --enable-bolt) +AC_ARG_ENABLE(bolt, AS_HELP_STRING( + [--enable-bolt], + [enable usage of the llvm-bolt post-link optimizer (default is no)]), +[ +if test "$enableval" != no +then + Py_BOLT='true' + AC_MSG_RESULT(yes); +else + Py_BOLT='false' + AC_MSG_RESULT(no); +fi], +[AC_MSG_RESULT(no)]) + +AC_SUBST(PREBOLT_RULE) +if test "$Py_BOLT" = 'true' ; then + PREBOLT_RULE="${DEF_MAKE_ALL_RULE}" + DEF_MAKE_ALL_RULE="bolt-opt" + DEF_MAKE_RULE="build_all" + + # -fno-reorder-blocks-and-partition is required for bolt to work. + # Possibly GCC only. + AX_CHECK_COMPILE_FLAG([-fno-reorder-blocks-and-partition],[ + CFLAGS_NODIST="$CFLAGS_NODIST -fno-reorder-blocks-and-partition" + ]) + + # These flags are required for bolt to work: + LDFLAGS_NODIST="$LDFLAGS_NODIST -Wl,--emit-relocs" + + # These flags are required to get good performance from bolt: + CFLAGS_NODIST="$CFLAGS_NODIST -fno-pie" + # We want to add these no-pie flags to linking executables but not shared libraries: + LINKCC="$LINKCC -fno-pie -no-pie" + AC_SUBST(LLVM_BOLT) + AC_PATH_TOOL(LLVM_BOLT, llvm-bolt, '', ${llvm_path}) + if test -n "${LLVM_BOLT}" -a -x "${LLVM_BOLT}" + then + AC_MSG_RESULT("Found llvm-bolt") + else + AC_MSG_ERROR([llvm-bolt is required for a --enable-bolt build but could not be found.]) + fi + + AC_SUBST(MERGE_FDATA) + AC_PATH_TOOL(MERGE_FDATA, merge-fdata, '', ${llvm_path}) + if test -n "${MERGE_FDATA}" -a -x "${MERGE_FDATA}" + then + AC_MSG_RESULT("Found merge-fdata") + else + AC_MSG_ERROR([merge-fdata is required for a --enable-bolt build but could not be found.]) + fi +fi + # Enable PGO flags. AC_SUBST(PGO_PROF_GEN_FLAG) AC_SUBST(PGO_PROF_USE_FLAG) @@ -1629,6 +2073,28 @@ case $CC in fi esac +# Check if CC supports -Og optimization level +_SAVE_VAR([CFLAGS]) +CFLAGS="-Og" +AC_CACHE_CHECK([if $CC supports -Og optimization level], + [ac_cv_cc_supports_og], + AC_COMPILE_IFELSE( + [ + AC_LANG_PROGRAM([[]], [[]]) + ],[ + ac_cv_cc_supports_og=yes + ],[ + ac_cv_cc_supports_og=no + ]) +) +_RESTORE_VAR([CFLAGS]) + +# Optimization messes up debuggers, so turn it off for +# debug builds. +PYDEBUG_CFLAGS="-O0" +AS_VAR_IF([ac_cv_cc_supports_og], [yes], + [PYDEBUG_CFLAGS="-Og"]) + # tweak OPT based on compiler and platform, only if the user didn't set # it on the command line AC_SUBST(OPT) @@ -1654,13 +2120,7 @@ then case $ac_cv_prog_cc_g in yes) if test "$Py_DEBUG" = 'true' ; then - # Optimization messes up debuggers, so turn it off for - # debug builds. - if "$CC" -v --help 2>/dev/null |grep -- -Og > /dev/null; then - OPT="-g -Og -Wall" - else - OPT="-g -O0 -Wall" - fi + OPT="-g $PYDEBUG_CFLAGS -Wall" else OPT="-g $WRAP -O3 -Wall" fi @@ -1682,9 +2142,81 @@ then esac fi +# WASM flags +AS_CASE([$ac_sys_system], + [Emscripten], [ + dnl build with WASM debug info if either Py_DEBUG is set or the target is + dnl node-debug or browser-debug. + AS_VAR_IF([Py_DEBUG], [yes], [wasm_debug=yes], [wasm_debug=no]) + + dnl Start with 20 MB and allow to grow + AS_VAR_APPEND([LDFLAGS_NODIST], [" -sALLOW_MEMORY_GROWTH -sTOTAL_MEMORY=20971520"]) + + dnl map int64_t and uint64_t to JS bigint + AS_VAR_APPEND([LDFLAGS_NODIST], [" -sWASM_BIGINT"]) + + dnl Include file system support + AS_VAR_APPEND([LDFLAGS_NODIST], [" -sFORCE_FILESYSTEM -lidbfs.js -lnodefs.js -lproxyfs.js -lworkerfs.js"]) + + AS_VAR_IF([enable_wasm_dynamic_linking], [yes], [ + AS_VAR_APPEND([LINKFORSHARED], [" -sMAIN_MODULE"]) + ]) + + AS_VAR_IF([enable_wasm_pthreads], [yes], [ + AS_VAR_APPEND([CFLAGS_NODIST], [" -pthread"]) + AS_VAR_APPEND([LDFLAGS_NODIST], [" -sUSE_PTHREADS"]) + AS_VAR_APPEND([LINKFORSHARED], [" -sPROXY_TO_PTHREAD"]) + ]) + + AS_CASE([$ac_sys_emscripten_target], + [browser*], [ + AS_VAR_IF([ac_sys_emscripten_target], [browser-debug], [wasm_debug=yes]) + AS_VAR_APPEND([LINKFORSHARED], [" --preload-file=\$(WASM_ASSETS_DIR)"]) + WASM_ASSETS_DIR=".\$(prefix)" + WASM_STDLIB="\$(WASM_ASSETS_DIR)/local/lib/python\$(VERSION)/os.py" + dnl separate-dwarf does not seem to work in Chrome DevTools Support. + WASM_LINKFORSHARED_DEBUG="-gsource-map --emit-symbol-map" + ], + [node*], [ + AS_VAR_IF([ac_sys_emscripten_target], [node-debug], [wasm_debug=yes]) + AS_VAR_APPEND([LDFLAGS_NODIST], [" -sALLOW_MEMORY_GROWTH -sNODERAWFS"]) + AS_VAR_APPEND([LINKFORSHARED], [" -sEXIT_RUNTIME"]) + WASM_LINKFORSHARED_DEBUG="-gseparate-dwarf --emit-symbol-map" + ] + ) + + AS_VAR_IF([wasm_debug], [yes], [ + AS_VAR_APPEND([LDFLAGS_NODIST], [" -sASSERTIONS"]) + AS_VAR_APPEND([LINKFORSHARED], [" $WASM_LINKFORSHARED_DEBUG"]) + ], [ + AS_VAR_APPEND([LINKFORSHARED], [" -O2 -g0"]) + ]) + ], + [WASI], [ + AC_DEFINE([_WASI_EMULATED_SIGNAL], [1], [Define to 1 if you want to emulate signals on WASI]) + AC_DEFINE([_WASI_EMULATED_GETPID], [1], [Define to 1 if you want to emulate getpid() on WASI]) + AC_DEFINE([_WASI_EMULATED_PROCESS_CLOCKS], [1], [Define to 1 if you want to emulate process clocks on WASI]) + LIBS="$LIBS -lwasi-emulated-signal -lwasi-emulated-getpid -lwasi-emulated-process-clocks" + echo "#define _WASI_EMULATED_SIGNAL 1" >> confdefs.h + + dnl increase initial memory and stack size, move stack first + dnl https://github.com/WebAssembly/wasi-libc/issues/233 + AS_VAR_APPEND([LDFLAGS_NODIST], [" -z stack-size=524288 -Wl,--stack-first -Wl,--initial-memory=10485760"]) + ] +) + +AS_CASE([$enable_wasm_dynamic_linking], + [yes], [ac_cv_func_dlopen=yes], + [no], [ac_cv_func_dlopen=no], + [missing], [] +) + AC_SUBST(BASECFLAGS) AC_SUBST(CFLAGS_NODIST) AC_SUBST(LDFLAGS_NODIST) +AC_SUBST(LDFLAGS_NOLTO) +AC_SUBST([WASM_ASSETS_DIR]) +AC_SUBST([WASM_STDLIB]) # The -arch flags for universal builds on macOS UNIVERSAL_ARCH_FLAGS= @@ -1707,7 +2239,7 @@ AC_DEFUN([PY_CHECK_CC_WARNING], [ # tweak BASECFLAGS based on compiler and platform case $GCC in yes) - CFLAGS_NODIST="$CFLAGS_NODIST -std=c99" + CFLAGS_NODIST="$CFLAGS_NODIST -std=c11" PY_CHECK_CC_WARNING([enable], [extra], [if we can add -Wextra]) AS_VAR_IF([ac_cv_enable_extra_warning], [yes], @@ -1758,6 +2290,10 @@ yes) AS_VAR_IF([ac_cv_disable_unused_parameter_warning], [yes], [CFLAGS_NODIST="$CFLAGS_NODIST -Wno-unused-parameter"]) + PY_CHECK_CC_WARNING([disable], [int-conversion]) + AS_VAR_IF([ac_cv_disable_int_conversion], [yes], + [CFLAGS_NODIST="$CFLAGS_NODIST -Wno-int-conversion"]) + PY_CHECK_CC_WARNING([disable], [missing-field-initializers]) AS_VAR_IF([ac_cv_disable_missing_field_initializers_warning], [yes], [CFLAGS_NODIST="$CFLAGS_NODIST -Wno-missing-field-initializers"]) @@ -2023,7 +2559,7 @@ AC_CACHE_CHECK([whether pthreads are available without options], void* routine(void* p){return NULL;} -int main(){ +int main(void){ pthread_t p; if(pthread_create(&p,NULL,routine,NULL)!=0) return 1; @@ -2056,7 +2592,7 @@ AC_RUN_IFELSE([AC_LANG_SOURCE([[ void* routine(void* p){return NULL;} -int main(){ +int main(void){ pthread_t p; if(pthread_create(&p,NULL,routine,NULL)!=0) return 1; @@ -2083,7 +2619,7 @@ AC_RUN_IFELSE([AC_LANG_SOURCE([[ void* routine(void* p){return NULL;} -int main(){ +int main(void){ pthread_t p; if(pthread_create(&p,NULL,routine,NULL)!=0) return 1; @@ -2110,7 +2646,7 @@ AC_RUN_IFELSE([AC_LANG_SOURCE([[ void* routine(void* p){return NULL;} -int main(){ +int main(void){ pthread_t p; if(pthread_create(&p,NULL,routine,NULL)!=0) return 1; @@ -2123,11 +2659,10 @@ fi # If we have set a CC compiler flag for thread support then # check if it works for CXX, too. -ac_cv_cxx_thread=no if test ! -z "$CXX" then -AC_MSG_CHECKING(whether $CXX also accepts flags for thread support) -ac_save_cxx="$CXX" +AC_CACHE_CHECK([whether $CXX also accepts flags for thread support], [ac_cv_cxx_thread], +[ac_save_cxx="$CXX" if test "$ac_cv_kpthread" = "yes" then @@ -2141,6 +2676,8 @@ elif test "$ac_cv_pthread" = "yes" then CXX="$CXX -pthread" ac_cv_cxx_thread=yes +else + ac_cv_cxx_thread=no fi if test $ac_cv_cxx_thread = yes @@ -2156,9 +2693,10 @@ then fi rm -fr conftest* fi -AC_MSG_RESULT($ac_cv_cxx_thread) +CXX="$ac_save_cxx"]) +else + ac_cv_cxx_thread=no fi -CXX="$ac_save_cxx" dnl # check for ANSI or K&R ("traditional") preprocessor dnl AC_MSG_CHECKING(for C preprocessor type) @@ -2174,21 +2712,19 @@ dnl assume C99 compilers provide ANSI C headers AC_DEFINE(STDC_HEADERS, 1, [Define to 1 if you have the ANSI C header files.]) # checks for header files -AC_CHECK_HEADERS(asm/types.h crypt.h conio.h direct.h dlfcn.h errno.h \ -fcntl.h grp.h \ -ieeefp.h io.h langinfo.h libintl.h process.h pthread.h \ -sched.h shadow.h signal.h stropts.h termios.h \ -utime.h \ -poll.h sys/devpoll.h sys/epoll.h sys/poll.h \ -sys/audioio.h sys/xattr.h sys/bsdtty.h sys/event.h sys/file.h sys/ioctl.h \ -sys/kern_control.h sys/loadavg.h sys/lock.h sys/mkdev.h sys/modem.h \ -sys/param.h sys/random.h sys/select.h sys/sendfile.h sys/socket.h sys/statvfs.h \ -sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ -sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ -libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ -linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \ -sys/endian.h sys/sysmacros.h linux/memfd.h linux/wait.h sys/memfd.h \ -sys/mman.h sys/eventfd.h linux/soundcard.h sys/soundcard.h syslog.h) +AC_CHECK_HEADERS([ \ + alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ + ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/fs.h linux/memfd.h \ + linux/random.h linux/soundcard.h \ + linux/tipc.h linux/wait.h netdb.h net/ethernet.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ + sched.h setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ + sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \ + sys/loadavg.h sys/lock.h sys/memfd.h sys/mkdev.h sys/mman.h sys/modem.h sys/param.h sys/poll.h \ + sys/random.h sys/resource.h sys/select.h sys/sendfile.h sys/socket.h sys/soundcard.h sys/stat.h \ + sys/statvfs.h sys/sys_domain.h sys/syscall.h sys/sysmacros.h sys/termio.h sys/time.h sys/times.h \ + sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h sys/xattr.h sysexits.h syslog.h \ + termios.h util.h utime.h utmp.h \ +]) AC_HEADER_DIRENT AC_HEADER_MAJOR @@ -2236,7 +2772,8 @@ AC_CHECK_HEADERS(linux/vm_sockets.h,,,[ ]) # On Linux, can.h, can/bcm.h, can/j1939.h, can/raw.h require sys/socket.h -AC_CHECK_HEADERS(linux/can.h linux/can/bcm.h linux/can/j1939.h linux/can/raw.h,,,[ +# On NetBSD, netcan/can.h requires sys/socket.h +AC_CHECK_HEADERS(linux/can.h linux/can/bcm.h linux/can/j1939.h linux/can/raw.h netcan/can.h,,,[ #ifdef HAVE_SYS_SOCKET_H #include #endif @@ -2357,15 +2894,24 @@ AC_CHECK_SIZEOF(off_t, [], [ AC_MSG_CHECKING(whether to enable large file support) if test "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ "$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then + have_largefile_support="yes" +else + have_largefile_support="no" +fi +dnl LFS does not work with Emscripten 3.1 +AS_CASE([$ac_sys_system], + [Emscripten], [have_largefile_support="no"] +) +AS_VAR_IF([have_largefile_support], [yes], [ AC_DEFINE(HAVE_LARGEFILE_SUPPORT, 1, [Defined to enable large file support when an off_t is bigger than a long and long long is at least as big as an off_t. You may need to add some flags for configuration and compilation to enable this mode. (For Solaris and Linux, the necessary defines are already defined.)]) AC_MSG_RESULT(yes) -else +], [ AC_MSG_RESULT(no) -fi +]) AC_CHECK_SIZEOF(time_t, [], [ #ifdef HAVE_SYS_TYPES_H @@ -2420,82 +2966,6 @@ AS_VAR_IF([ac_cv_pthread_key_t_is_arithmetic_type], [yes], [ CC="$ac_save_cc" -AC_SUBST(OTHER_LIBTOOL_OPT) -case $ac_sys_system/$ac_sys_release in - Darwin/@<:@01567@:>@\..*) - OTHER_LIBTOOL_OPT="-prebind -seg1addr 0x10000000" - ;; - Darwin/*) - OTHER_LIBTOOL_OPT="" - ;; -esac - - -AC_SUBST(LIBTOOL_CRUFT) -case $ac_sys_system/$ac_sys_release in - Darwin/@<:@01567@:>@\..*) - LIBTOOL_CRUFT="-framework System -lcc_dynamic" - if test "${enable_universalsdk}"; then - : - else - LIBTOOL_CRUFT="${LIBTOOL_CRUFT} -arch_only `/usr/bin/arch`" - fi - LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -install_name $(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' - LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';; - Darwin/*) - gcc_version=`gcc -dumpversion` - if test ${gcc_version} '<' 4.0 - then - LIBTOOL_CRUFT="-lcc_dynamic" - else - LIBTOOL_CRUFT="" - fi - AC_RUN_IFELSE([AC_LANG_SOURCE([[ - #include - int main(int argc, char*argv[]) - { - if (sizeof(long) == 4) { - return 0; - } else { - return 1; - } - } - ]])],[ac_osx_32bit=yes],[ac_osx_32bit=no],[ac_osx_32bit=yes]) - - if test "${ac_osx_32bit}" = "yes"; then - case `/usr/bin/arch` in - i386) - MACOSX_DEFAULT_ARCH="i386" - ;; - ppc) - MACOSX_DEFAULT_ARCH="ppc" - ;; - *) - AC_MSG_ERROR([Unexpected output of 'arch' on macOS]) - ;; - esac - else - case `/usr/bin/arch` in - i386) - MACOSX_DEFAULT_ARCH="x86_64" - ;; - ppc) - MACOSX_DEFAULT_ARCH="ppc64" - ;; - arm64) - MACOSX_DEFAULT_ARCH="arm64" - ;; - *) - AC_MSG_ERROR([Unexpected output of 'arch' on macOS]) - ;; - esac - - fi - - LIBTOOL_CRUFT=$LIBTOOL_CRUFT" -lSystem -lSystemStubs -arch_only ${MACOSX_DEFAULT_ARCH}" - LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -install_name $(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' - LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';; -esac AC_MSG_CHECKING(for --enable-framework) if test "$enable_framework" then @@ -2514,6 +2984,33 @@ else AC_MSG_RESULT(no) fi +# Check for --with-dsymutil +AC_SUBST(DSYMUTIL) +AC_SUBST(DSYMUTIL_PATH) +DSYMUTIL= +DSYMUTIL_PATH= +AC_MSG_CHECKING(for --with-dsymutil) +AC_ARG_WITH(dsymutil, + AS_HELP_STRING([--with-dsymutil], [link debug information into final executable with dsymutil in macOS (default is no)]), +[ +if test "$withval" != no +then + if test "$MACHDEP" != "darwin"; then + AC_MSG_ERROR([dsymutil debug linking is only available in macOS.]) + fi + AC_MSG_RESULT(yes); + DSYMUTIL='true' +else AC_MSG_RESULT(no); DSYMUTIL= +fi], +[AC_MSG_RESULT(no)]) + +if test "$DSYMUTIL"; then + AC_PATH_PROG(DSYMUTIL_PATH, [dsymutil], [not found]) + if test "$DSYMUTIL_PATH" = "not found"; then + AC_MSG_ERROR([dsymutil command not found on \$PATH]) + fi +fi + AC_MSG_CHECKING(for dyld) case $ac_sys_system/$ac_sys_release in Darwin/*) @@ -2547,8 +3044,10 @@ AC_ARG_WITH(memory_sanitizer, [enable MemorySanitizer allocation error detector, 'msan' (default is no)]), [ AC_MSG_RESULT($withval) +AX_CHECK_COMPILE_FLAG([-fsanitize=memory],[ BASECFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer $BASECFLAGS" LDFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 $LDFLAGS" +],[AC_MSG_ERROR([The selected compiler doesn't support memory sanitizer])]) # MSan works by controlling memory allocation, our own malloc interferes. with_pymalloc="no" ], @@ -2669,6 +3168,9 @@ then BLDSHARED="$LDSHARED" fi ;; + Emscripten|WASI) + LDSHARED='$(CC) -shared' + LDCXXSHARED='$(CXX) -shared';; Linux*|GNU*|QNX*|VxWorks*|Haiku*) LDSHARED='$(CC) -shared' LDCXXSHARED='$(CXX) -shared';; @@ -2710,15 +3212,30 @@ then SCO_SV*) LDSHARED='$(CC) -Wl,-G,-Bexport' LDCXXSHARED='$(CXX) -Wl,-G,-Bexport';; + WASI*) + AS_VAR_IF([enable_wasm_dynamic_linking], [yes], [ + dnl not iplemented yet + ]);; CYGWIN*) LDSHARED="gcc -shared -Wl,--enable-auto-image-base" LDCXXSHARED="g++ -shared -Wl,--enable-auto-image-base";; *) LDSHARED="ld";; esac fi + +dnl Emscripten's emconfigure sets LDSHARED. Set BLDSHARED outside the +dnl test -z $LDSHARED block to configure BLDSHARED for side module support. +if test "$enable_wasm_dynamic_linking" = "yes" -a "$ac_sys_system" = "Emscripten"; then + BLDSHARED='$(CC) -shared -sSIDE_MODULE=1' +fi + AC_MSG_RESULT($LDSHARED) LDCXXSHARED=${LDCXXSHARED-$LDSHARED} + +AC_MSG_CHECKING([BLDSHARED flags]) BLDSHARED=${BLDSHARED-$LDSHARED} +AC_MSG_RESULT([$BLDSHARED]) + # CCSHARED are the C *flags* used to create objects to go into a shared # library (module) -- this is only needed for a few systems AC_MSG_CHECKING(CCSHARED) @@ -2737,6 +3254,10 @@ then fi;; Linux-android*) ;; Linux*|GNU*) CCSHARED="-fPIC";; + Emscripten*|WASI*) + AS_VAR_IF([enable_wasm_dynamic_linking], [yes], [ + CCSHARED="-fPIC" + ]);; FreeBSD*|NetBSD*|OpenBSD*|DragonFly*) CCSHARED="-fPIC";; Haiku*) CCSHARED="-fPIC";; OpenUNIX*|UnixWare*) @@ -2774,7 +3295,7 @@ then # small for the default recursion limit. Increase the stack size # to ensure that tests don't crash stack_size="1000000" # 16 MB - if test "$with_ubsan" == "yes" + if test "$with_ubsan" = "yes" then # Undefined behavior sanitizer requires an even deeper stack stack_size="4000000" # 64 MB @@ -2838,6 +3359,12 @@ then CFLAGSFORSHARED='$(CCSHARED)' esac fi + +dnl WASM dynamic linking requires -fPIC. +AS_VAR_IF([enable_wasm_dynamic_linking], [yes], [ + CFLAGSFORSHARED='$(CCSHARED)' +]) + AC_MSG_RESULT($CFLAGSFORSHARED) # SHLIBS are libraries (except -lc and -lm) to link to the python shared @@ -2856,37 +3383,91 @@ case "$ac_sys_system" in esac AC_MSG_RESULT($SHLIBS) +dnl perf trampoline is Linux specific and requires an arch-specific +dnl trampoline in asssembly. +AC_MSG_CHECKING([perf trampoline]) +AS_CASE([$PLATFORM_TRIPLET], + [x86_64-linux-gnu], [perf_trampoline=yes], + [aarch64-linux-gnu], [perf_trampoline=yes], + [perf_trampoline=no] +) +AC_MSG_RESULT([$perf_trampoline]) + +AS_VAR_IF([perf_trampoline], [yes], [ + AC_DEFINE([PY_HAVE_PERF_TRAMPOLINE], [1], [Define to 1 if you have the perf trampoline.]) + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline.o + + dnl perf needs frame pointers for unwinding, include compiler option in debug builds + AS_VAR_IF([Py_DEBUG], [true], [ + AS_VAR_APPEND([BASECFLAGS], [" -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer"]) + ]) +]) +AC_SUBST([PERF_TRAMPOLINE_OBJ]) # checks for libraries AC_CHECK_LIB(sendfile, sendfile) AC_CHECK_LIB(dl, dlopen) # Dynamic linking for SunOS/Solaris and SYSV AC_CHECK_LIB(dld, shl_load) # Dynamic linking for HP-UX -# checks for uuid.h location -AC_CHECK_HEADERS([uuid/uuid.h uuid.h]) -AC_CACHE_CHECK([for uuid_generate_time_safe], [ac_cv_lib_uuid_uuid_generate_time_safe], [ -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ -#ifndef uuid_generate_time_safe -void *x = uuid_generate_time_safe -#endif -]])], -[ac_cv_lib_uuid_uuid_generate_time_safe=yes], [ac_cv_lib_uuid_uuid_generate_time_safe=no]) -]) -AS_VAR_IF([ac_cv_lib_uuid_uuid_generate_time_safe], [yes], [ - AC_DEFINE(HAVE_UUID_GENERATE_TIME_SAFE, 1, [Define if uuid_generate_time_safe() exists.]) +dnl check for uuid dependencies +AH_TEMPLATE([HAVE_UUID_H], [Define to 1 if you have the header file.]) +AH_TEMPLATE([HAVE_UUID_UUID_H], [Define to 1 if you have the header file.]) +AH_TEMPLATE([HAVE_UUID_GENERATE_TIME_SAFE], [Define if uuid_generate_time_safe() exists.]) +have_uuid=missing + +dnl AIX provides support for RFC4122 (uuid) in libc.a starting with AIX 6.1 +dnl (anno 2007). FreeBSD and OpenBSD provides support in libc as well. +dnl Little-endian FreeBSD, OpenBSD and NetBSD needs encoding into an octet +dnl stream in big-endian byte-order +AC_CHECK_HEADERS([uuid.h], [ + AC_CHECK_FUNCS([uuid_create uuid_enc_be], [ + have_uuid=yes + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-""} + ]) ]) -# check for libuuid from util-linux -save_LIBS=$LIBS -AC_CHECK_LIB([uuid], [uuid_generate_time]) -LIBS=$save_LIBS +AS_VAR_IF([have_uuid], [missing], [ + PKG_CHECK_MODULES( + [LIBUUID], [uuid >= 2.20], [ + dnl linux-util's libuuid has uuid_generate_time_safe() since v2.20 (2011) + dnl and provides . + have_uuid=yes + AC_DEFINE([HAVE_UUID_H], [1]) + AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1]) + ], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBUUID_CFLAGS" + LDFLAGS="$LDFLAGS $LIBUUID_LIBS" + AC_CHECK_HEADERS([uuid/uuid.h], [ + PY_CHECK_LIB([uuid], [uuid_generate_time], [have_uuid=yes]) + PY_CHECK_LIB([uuid], [uuid_generate_time_safe], [ + have_uuid=yes + AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1]) + ]) + ]) + AS_VAR_IF([have_uuid], [yes], [ + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-"-luuid"} + ]) + ]) + ] + ) +]) -# AIX provides support for RFC4122 (uuid) in libc.a starting with AIX 6.1 (anno 2007) -# FreeBSD and OpenBSD provides support in libc as well. -# Little-endian FreeBSD, OpenBSD and NetBSD needs encoding into an octet -# stream in big-endian byte-order -AC_CHECK_FUNCS([uuid_create uuid_enc_be]) +dnl macOS has uuid/uuid.h but uuid_generate_time is in libc +AS_VAR_IF([have_uuid], [missing], [ + AC_CHECK_HEADERS([uuid/uuid.h], [ + AC_CHECK_FUNC([uuid_generate_time], [ + have_uuid=yes + LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} + LIBUUID_LIBS=${LIBUUID_LIBS-""} + ]) + ]) +]) + +AS_VAR_IF([have_uuid], [missing], [have_uuid=no]) # 'Real Time' functions on Solaris # posix4 on Solaris 2.6 @@ -2929,7 +3510,7 @@ esac # check for systems that require aligned memory access AC_CACHE_CHECK([aligned memory access is required], [ac_cv_aligned_required], [AC_RUN_IFELSE([AC_LANG_SOURCE([[ -int main() +int main(void) { char s[16]; int i, *p1, *p2; @@ -3044,52 +3625,76 @@ AC_ARG_WITH(system_expat, AC_MSG_RESULT($with_system_expat) AS_VAR_IF([with_system_expat], [yes], [ - LIBEXPAT_CFLAGS="" - LIBEXPAT_LDFLAGS="-lexpat" + LIBEXPAT_CFLAGS=${LIBEXPAT_CFLAGS-""} + LIBEXPAT_LDFLAGS=${LIBEXPAT_LDFLAGS-"-lexpat"} LIBEXPAT_INTERNAL= ], [ LIBEXPAT_CFLAGS="-I\$(srcdir)/Modules/expat" LIBEXPAT_LDFLAGS="-lm \$(LIBEXPAT_A)" - LIBEXPAT_INTERNAL="\$(LIBEXPAT_A)" + LIBEXPAT_INTERNAL="\$(LIBEXPAT_HEADERS) \$(LIBEXPAT_A)" ]) AC_SUBST([LIBEXPAT_CFLAGS]) -AC_SUBST([LIBEXPAT_LDFLAGS]) AC_SUBST([LIBEXPAT_INTERNAL]) -# Check for use of the system libffi library -AC_MSG_CHECKING(for --with-system-ffi) -AC_ARG_WITH(system_ffi, - AS_HELP_STRING([--with-system-ffi], [build _ctypes module using an installed ffi library, see Doc/library/ctypes.rst (default is system-dependent)]),,,) +dnl detect libffi +have_libffi=missing +AS_VAR_IF([ac_sys_system], [Darwin], [ + WITH_SAVE_ENV([ + CFLAGS="-I${SDKROOT}/usr/include/ffi $CFLAGS" + AC_CHECK_HEADER([ffi.h], [ + AC_CHECK_LIB([ffi], [ffi_call], [ + dnl use ffi from SDK root + have_libffi=yes + LIBFFI_CFLAGS="-I${SDKROOT}/usr/include/ffi -DUSING_APPLE_OS_LIBFFI=1" + LIBFFI_LIBS="-lffi" + ]) + ]) + ]) +]) +AS_VAR_IF([have_libffi], [missing], [ + PKG_CHECK_MODULES([LIBFFI], [libffi], [have_libffi=yes], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBFFI_CFLAGS" + LDFLAGS="$LDFLAGS $LIBFFI_LIBS" + AC_CHECK_HEADER([ffi.h], [ + AC_CHECK_LIB([ffi], [ffi_call], [ + have_libffi=yes + LIBFFI_CFLAGS=${LIBFFI_CFLAGS-""} + LIBFFI_LIBS=${LIBFFI_LIBS-"-lffi"} + ], [have_libffi=no]) + ]) + ]) + ]) +]) -if test "$ac_sys_system" = "Darwin" -then - case "$with_system_ffi" in - "") - with_system_ffi="no" - ;; - yes|no) - ;; - *) - AC_MSG_ERROR([--with-system-ffi accepts no arguments]) - ;; - esac - AC_MSG_RESULT($with_system_ffi) -else - AC_MSG_RESULT(yes) - if test "$with_system_ffi" != "" - then - AC_MSG_WARN([--with(out)-system-ffi is ignored on this platform]) - fi - with_system_ffi="yes" -fi +AS_VAR_IF([have_libffi], [yes], [ + ctypes_malloc_closure=no + AS_CASE([$ac_sys_system], + [Darwin], [ + dnl when do we need USING_APPLE_OS_LIBFFI? + ctypes_malloc_closure=yes + ], + [sunos5], [AS_VAR_APPEND([LIBFFI_LIBS], [" -mimpure-text"])] + ) + AS_VAR_IF([ctypes_malloc_closure], [yes], [ + MODULE__CTYPES_MALLOC_CLOSURE=_ctypes/malloc_closure.c + AS_VAR_APPEND([LIBFFI_CFLAGS], [" -DUSING_MALLOC_CLOSURE_DOT_C=1"]) + ]) + AC_SUBST([MODULE__CTYPES_MALLOC_CLOSURE]) -if test "$with_system_ffi" = "yes" && test -n "$PKG_CONFIG"; then - LIBFFI_INCLUDEDIR="`"$PKG_CONFIG" libffi --cflags-only-I 2>/dev/null | sed -e 's/^-I//;s/ *$//'`" -else - LIBFFI_INCLUDEDIR="" -fi -AC_SUBST(LIBFFI_INCLUDEDIR) + dnl HAVE_LIBDL: for dlopen, see gh-76828 + AS_VAR_IF([ac_cv_lib_dl_dlopen], [yes], [AS_VAR_APPEND([LIBFFI_LIBS], [" -ldl"])]) + + WITH_SAVE_ENV([ + CFLAGS="$LIBFFI_CFLAGS $CFLAGS" + LDFLAGS="$LIBFFI_LIBS $LDFLAGS" + + PY_CHECK_FUNC([ffi_prep_cif_var], [#include ]) + PY_CHECK_FUNC([ffi_prep_closure_loc], [#include ]) + PY_CHECK_FUNC([ffi_closure_alloc], [#include ]) + ]) +]) # Check for use of the system libmpdec library AC_MSG_CHECKING(for --with-system-libmpdec) @@ -3100,17 +3705,21 @@ AC_ARG_WITH(system_libmpdec, AC_MSG_RESULT($with_system_libmpdec) AS_VAR_IF([with_system_libmpdec], [yes], [ - LIBMPDEC_CFLAGS="" - LIBMPDEC_LDFLAGS="-lmpdec" + LIBMPDEC_CFLAGS=${LIBMPDEC_CFLAGS-""} + LIBMPDEC_LDFLAGS=${LIBMPDEC_LDFLAGS-"-lmpdec"} LIBMPDEC_INTERNAL= ], [ LIBMPDEC_CFLAGS="-I\$(srcdir)/Modules/_decimal/libmpdec" LIBMPDEC_LDFLAGS="-lm \$(LIBMPDEC_A)" - LIBMPDEC_INTERNAL="\$(LIBMPDEC_A)" + LIBMPDEC_INTERNAL="\$(LIBMPDEC_HEADERS) \$(LIBMPDEC_A)" + + dnl Disable forced inlining in debug builds, see GH-94847 + AS_VAR_IF([with_pydebug], [yes], [ + AS_VAR_APPEND([LIBMPDEC_CFLAGS], [" -DTEST_COVERAGE"]) + ]) ]) AC_SUBST([LIBMPDEC_CFLAGS]) -AC_SUBST([LIBMPDEC_LDFLAGS]) AC_SUBST([LIBMPDEC_INTERNAL]) # Check whether _decimal should use a coroutine-local or thread-local context @@ -3138,14 +3747,9 @@ AS_CASE([$ac_sys_system], libmpdec_machine=unknown if test "$libmpdec_system" = Darwin; then - AS_CASE([$MACOSX_DEFAULT_ARCH], - [i386], [libmpdec_machine=ansi32], - [ppc], [libmpdec_machine=ansi32], - [x86_64], [libmpdec_machine=x64], - [ppc64], [libmpdec_machine=ansi64], - [arm64], [libmpdec_machine=ansi64], - [libmpdec_machine=universal] - ) + # universal here means: build libmpdec with the same arch options + # the python interpreter was built with + libmpdec_machine=universal elif test $ac_cv_sizeof_size_t -eq 8; then if test "$ac_cv_gcc_asm_for_x64" = yes; then libmpdec_machine=x64 @@ -3191,105 +3795,237 @@ if test "$have_glibc_memmove_bug" = yes; then AS_VAR_APPEND([LIBMPDEC_CFLAGS], [" -U_FORTIFY_SOURCE"]) fi + +dnl check for NIS / libnsl dependencies +dnl libnsl dependencies include tirpc includes and lib +PKG_CHECK_MODULES([LIBNSL], [libnsl], [have_nis=yes], [ + LIBNSL_CFLAGS=${LIBNSL_CFLAGS-""} + WITH_SAVE_ENV([ + AC_SEARCH_LIBS([yp_match], [nsl], [have_nis=yes], [have_nis=no]) + ]) + AS_CASE([$ac_cv_search_yp_match], + [no], [libnsl=""], + ["none required"], [libnsl=""], + [libnsl="$ac_cv_search_yp_match"] + ) + LIBNSL_LIBS=${LIBNSL_LIBS-$libnsl} +]) + +AS_VAR_IF([have_nis], [yes], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBNSL_CFLAGS" + AC_CHECK_HEADERS([rpc/rpc.h]) + ]) +]) + +dnl On NetBSD, when using OSS audio, you need to link against libossaudio +AS_CASE([$ac_sys_system], + [NetBSD*], [OSSAUDIODEV_LIBS="-lossaudio"], + [OSSAUDIODEV_LIBS=""] +) + +dnl detect sqlite3 from Emscripten emport +PY_CHECK_EMSCRIPTEN_PORT([LIBSQLITE3], [-sUSE_SQLITE3]) + dnl Check for SQLite library. Use pkg-config if available. PKG_CHECK_MODULES( [LIBSQLITE3], [sqlite3 >= 3.7.15], [], [ - LIBSQLITE3_LIBS="-lsqlite3" - LIBSQLITE3_CFLAGS= + LIBSQLITE3_CFLAGS=${LIBSQLITE3_CFLAGS-""} + LIBSQLITE3_LIBS=${LIBSQLITE3_LIBS-"-lsqlite3"} ] ) AS_VAR_APPEND([LIBSQLITE3_CFLAGS], [' -I$(srcdir)/Modules/_sqlite']) -WITH_SAVE_ENV( +dnl PY_CHECK_SQLITE_FUNC(FUNCTION, IF-FOUND, IF-NOT-FOUND) +AC_DEFUN([PY_CHECK_SQLITE_FUNC], [ + AC_CHECK_LIB([sqlite3], [$1], [$2], [ + m4_ifblank([$3], [have_supported_sqlite3=no], [$3]) + ]) +]) + +WITH_SAVE_ENV([ dnl bpo-45774/GH-29507: The CPP check in AC_CHECK_HEADER can fail on FreeBSD, dnl hence CPPFLAGS instead of CFLAGS. - CPPFLAGS="$LIBSQLITE3_CFLAGS $CFLAGS" + CPPFLAGS="$CPPFLAGS $LIBSQLITE3_CFLAGS" LDFLAGS="$LIBSQLITE3_LIBS $LDFLAGS" AC_CHECK_HEADER([sqlite3.h], [ - AC_CHECK_LIB([sqlite3], [sqlite3_open_v2], [ - have_sqlite3=yes - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([ - #include - #if SQLITE_VERSION_NUMBER < 3007015 - # error "SQLite 3.7.15 or higher required" - #endif - ], []) - ], [have_supported_sqlite3=yes], [have_supported_sqlite3=no]) - ], [have_sqlite3=no]) - AC_CHECK_LIB([sqlite3], [sqlite3_load_extension], - [have_sqlite3_load_extension=yes], - [have_sqlite3_load_extension=no]) + have_sqlite3=yes + + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([ + #include + #if SQLITE_VERSION_NUMBER < 3007015 + # error "SQLite 3.7.15 or higher required" + #endif + ], []) + ], [ + have_supported_sqlite3=yes + dnl Check that required functions are in place. A lot of stuff may be + dnl omitted with SQLITE_OMIT_* compile time defines. + PY_CHECK_SQLITE_FUNC([sqlite3_bind_double]) + PY_CHECK_SQLITE_FUNC([sqlite3_column_decltype]) + PY_CHECK_SQLITE_FUNC([sqlite3_column_double]) + PY_CHECK_SQLITE_FUNC([sqlite3_complete]) + PY_CHECK_SQLITE_FUNC([sqlite3_enable_shared_cache]) + PY_CHECK_SQLITE_FUNC([sqlite3_progress_handler]) + PY_CHECK_SQLITE_FUNC([sqlite3_result_double]) + PY_CHECK_SQLITE_FUNC([sqlite3_set_authorizer]) + PY_CHECK_SQLITE_FUNC([sqlite3_trace_v2], [], [ + PY_CHECK_SQLITE_FUNC([sqlite3_trace]) + ]) + PY_CHECK_SQLITE_FUNC([sqlite3_value_double]) + AC_CHECK_LIB([sqlite3], [sqlite3_load_extension], + [have_sqlite3_load_extension=yes], + [have_sqlite3_load_extension=no] + ) + AC_CHECK_LIB([sqlite3], [sqlite3_serialize], [ + AC_DEFINE( + [PY_SQLITE_HAVE_SERIALIZE], [1], + [Define if SQLite was compiled with the serialize API] + ) + ]) + ], [ + have_supported_sqlite3=no + ]) ]) +]) + +dnl Check for support for loadable sqlite extensions +AC_MSG_CHECKING([for --enable-loadable-sqlite-extensions]) +AC_ARG_ENABLE([loadable-sqlite-extensions], + AS_HELP_STRING( + [--enable-loadable-sqlite-extensions], [ + support loadable extensions in the sqlite3 module, see + Doc/library/sqlite3.rst (default is no) + ] + ), [ + AS_VAR_IF([have_sqlite3_load_extension], [no], [ + AC_MSG_RESULT([n/a]) + AC_MSG_WARN([Your version of SQLite does not support loadable extensions]) + ], [ + AC_MSG_RESULT([yes]) + AC_DEFINE( + [PY_SQLITE_ENABLE_LOAD_EXTENSION], [1], + [Define to 1 to build the sqlite module with loadable extensions support.] + ) + ]) + ], [ + AC_MSG_RESULT([no]) + ] ) -# Check for support for loadable sqlite extensions -AC_MSG_CHECKING(for --enable-loadable-sqlite-extensions) -AC_ARG_ENABLE(loadable-sqlite-extensions, - AS_HELP_STRING([--enable-loadable-sqlite-extensions], - [support loadable extensions in _sqlite module, see Doc/library/sqlite3.rst (default is no)]), - [AS_VAR_IF([have_sqlite3_load_extension], [no], - [AC_MSG_WARN([Your version of SQLite does not support loadable extensions])])], - [enable_loadable_sqlite_extensions=no]) -AC_MSG_RESULT($enable_loadable_sqlite_extensions) +dnl +dnl Detect Tcl/Tk. Use pkg-config if available. +dnl +found_tcltk=no +for _QUERY in \ + "tcl >= 8.5.12 tk >= 8.5.12" \ + "tcl8.6 tk8.6" \ + "tcl86 tk86" \ + "tcl8.5 >= 8.5.12 tk8.5 >= 8.5.12" \ + "tcl85 >= 8.5.12 tk85 >= 8.5.12" \ +; do + PKG_CHECK_EXISTS([$_QUERY], [ + PKG_CHECK_MODULES([TCLTK], [$_QUERY], [found_tcltk=yes], [found_tcltk=no]) + ]) + AS_VAR_IF([found_tcltk], [yes], [break]) +done -AS_VAR_IF([enable_loadable_sqlite_extensions], [yes], [ - AC_DEFINE(PY_SQLITE_ENABLE_LOAD_EXTENSION, 1, - [Define to 1 to build the sqlite module with loadable extensions support.]) +AS_VAR_IF([found_tcltk], [no], [ + TCLTK_CFLAGS=${TCLTK_CFLAGS-""} + TCLTK_LIBS=${TCLTK_LIBS-""} ]) -# Check for --with-tcltk-includes=path and --with-tcltk-libs=path -AC_SUBST(TCLTK_INCLUDES) -AC_SUBST(TCLTK_LIBS) -AC_MSG_CHECKING(for --with-tcltk-includes) -AC_ARG_WITH(tcltk-includes, - AS_HELP_STRING([--with-tcltk-includes='-I...'], [override search for Tcl and Tk include files]), - [], - [with_tcltk_includes="default"]) -AC_MSG_RESULT($with_tcltk_includes) -AC_MSG_CHECKING(for --with-tcltk-libs) -AC_ARG_WITH(tcltk-libs, - AS_HELP_STRING([--with-tcltk-libs='-L...'], [override search for Tcl and Tk libs]), - [], - [with_tcltk_libs="default"]) -AC_MSG_RESULT($with_tcltk_libs) -if test "x$with_tcltk_includes" = xdefault || test "x$with_tcltk_libs" = xdefault -then - if test "x$with_tcltk_includes" != "x$with_tcltk_libs" - then - AC_MSG_ERROR([use both --with-tcltk-includes='...' and --with-tcltk-libs='...' or neither]) - fi - if test -n "$PKG_CONFIG" && "$PKG_CONFIG" --exists tcl tk; then - TCLTK_INCLUDES="`"$PKG_CONFIG" tcl tk --cflags-only-I 2>/dev/null`" - TCLTK_LIBS="`"$PKG_CONFIG" tcl tk --libs 2>/dev/null`" - else - TCLTK_INCLUDES="" - TCLTK_LIBS="" - fi -else - TCLTK_INCLUDES="$with_tcltk_includes" - TCLTK_LIBS="$with_tcltk_libs" -fi +dnl FreeBSD has an X11 dependency which is not implicitly resolved. +AS_CASE([$ac_sys_system], + [FreeBSD*], [ + PKG_CHECK_EXISTS([x11], [ + PKG_CHECK_MODULES([X11], [x11], [ + TCLTK_CFLAGS="$TCLTK_CFLAGS $X11_CFLAGS" + TCLTK_LIBS="$TCLTK_LIBS $X11_LIBS" + ]) + ]) + ] +) -# check for _gdbmmodulec dependencies -AC_CHECK_HEADERS([gdbm.h], [ - LIBS_SAVE=$LIBS - AC_CHECK_LIB([gdbm], [gdbm_open]) - LIBS=$LIBS_SAVE +WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $TCLTK_CFLAGS" + LIBS="$TCLTK_LIBS $LDFLAGS" + + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([ + #include + #include + #if defined(TK_HEX_VERSION) + # if TK_HEX_VERSION < 0x0805020c + # error "Tk older than 8.5.12 not supported" + # endif + #endif + #if (TCL_MAJOR_VERSION < 8) || \ + ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 5)) || \ + ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION == 5) && (TCL_RELEASE_SERIAL < 12)) + # error "Tcl older than 8.5.12 not supported" + #endif + #if (TK_MAJOR_VERSION < 8) || \ + ((TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION < 5)) || \ + ((TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION == 5) && (TK_RELEASE_SERIAL < 12)) + # error "Tk older than 8.5.12 not supported" + #endif + ], [ + void *x1 = Tcl_Init; + void *x2 = Tk_Init; + ]) + ], [ + have_tcltk=yes + dnl The X11/xlib.h file bundled in the Tk sources can cause function + dnl prototype warnings from the compiler. Since we cannot easily fix + dnl that, suppress the warnings here instead. + AS_VAR_APPEND([TCLTK_CFLAGS], [" -Wno-strict-prototypes -DWITH_APPINIT=1"]) + ], [ + have_tcltk=no + ]) ]) -# check for _dbmmodule.c dependencies +dnl check for _gdbmmodule dependencies +dnl NOTE: gdbm does not provide a pkgconf file. +AC_ARG_VAR([GDBM_CFLAGS], [C compiler flags for gdbm]) +AC_ARG_VAR([GDBM_LIBS], [additional linker flags for gdbm]) +WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $GDBM_CFLAGS" + LDFLAGS="$GDBM_LIBS $LDFLAGS" + AC_CHECK_HEADERS([gdbm.h], [ + AC_CHECK_LIB([gdbm], [gdbm_open], [ + have_gdbm=yes + GDBM_LIBS=${GDBM_LIBS-"-lgdbm"} + ], [have_gdbm=no]) + ], [have_gdbm=no]) +]) + +dnl check for _dbmmodule.c dependencies +dnl ndbm, gdbm_compat, libdb AC_CHECK_HEADERS([ndbm.h], [ - LIBS_SAVE="$LIBS" - AC_CHECK_LIB([ndbm], [dbm_open]) - LIBS="$LIBS_SAVE" - AC_CHECK_LIB([gdbm_compat], [dbm_open]) - LIBS="$LIBS_SAVE" + WITH_SAVE_ENV([ + AC_SEARCH_LIBS([dbm_open], [ndbm gdbm_compat]) + ]) ]) -# "gdbm-ndbm.h" and "gdbm/ndbm.h" are both normalized to "gdbm_ndbm_h" -# unset ac_cv_header_gdbm_ndbm_h to prevent false positive cache hits. +AC_MSG_CHECKING([for ndbm presence and linker args]) +AS_CASE([$ac_cv_search_dbm_open], + [*ndbm*|*gdbm_compat*], [ + dbm_ndbm="$ac_cv_search_dbm_open" + have_ndbm=yes + ], + [none*], [ + dbm_ndbm="" + have_ndbm=yes + ], + [no], [have_ndbm=no] +) +AC_MSG_RESULT([$have_ndbm ($dbm_ndbm)]) + +dnl "gdbm-ndbm.h" and "gdbm/ndbm.h" are both normalized to "gdbm_ndbm_h" +dnl unset ac_cv_header_gdbm_ndbm_h to prevent false positive cache hits. AS_UNSET([ac_cv_header_gdbm_ndbm_h]) AC_CACHE_VAL([ac_cv_header_gdbm_slash_ndbm_h], [ AC_CHECK_HEADER( @@ -3314,26 +4050,27 @@ AS_VAR_IF([ac_cv_header_gdbm_dash_ndbm_h], [yes], [ AS_UNSET([ac_cv_header_gdbm_ndbm_h]) if test "$ac_cv_header_gdbm_slash_ndbm_h" = yes -o "$ac_cv_header_gdbm_dash_ndbm_h" = yes; then - LIBS_SAVE="$LIBS" - AC_CHECK_LIB([gdbm_compat], [dbm_open]) - LIBS="$LIBS_SAVE" + AS_UNSET([ac_cv_search_dbm_open]) + WITH_SAVE_ENV([ + AC_SEARCH_LIBS([dbm_open], [gdbm_compat], [have_gdbm_compat=yes], [have_gdbm_compat=no]) + ]) fi # Check for libdb >= 5 with dbm_open() # db.h re-defines the name of the function AC_CHECK_HEADERS([db.h], [ AC_CACHE_CHECK([for libdb], [ac_cv_have_libdb], [ - LIBS_SAVE="$LIBS" - LIBS="$LIBS -ldb" - AC_LINK_IFELSE([AC_LANG_PROGRAM([ - #define DB_DBM_HSEARCH 1 - #include - #if DB_VERSION_MAJOR < 5 - #error "dh.h: DB_VERSION_MAJOR < 5 is not supported." - #endif - ], [DBM *dbm = dbm_open(NULL, 0, 0)]) - ], [ac_cv_have_libdb=yes], [ac_cv_have_libdb=no]) - LIBS="$LIBS_SAVE" + WITH_SAVE_ENV([ + LIBS="$LIBS -ldb" + AC_LINK_IFELSE([AC_LANG_PROGRAM([ + #define DB_DBM_HSEARCH 1 + #include + #if DB_VERSION_MAJOR < 5 + #error "dh.h: DB_VERSION_MAJOR < 5 is not supported." + #endif + ], [DBM *dbm = dbm_open(NULL, 0, 0)]) + ], [ac_cv_have_libdb=yes], [ac_cv_have_libdb=no]) + ]) ]) AS_VAR_IF([ac_cv_have_libdb], [yes], [ AC_DEFINE([HAVE_LIBDB], [1], [Define to 1 if you have the `db' library (-ldb).]) @@ -3341,25 +4078,62 @@ AC_CHECK_HEADERS([db.h], [ ]) # Check for --with-dbmliborder -AC_MSG_CHECKING(for --with-dbmliborder) +AC_MSG_CHECKING([for --with-dbmliborder]) AC_ARG_WITH(dbmliborder, AS_HELP_STRING([--with-dbmliborder=db1:db2:...], [override order to check db backends for dbm; a valid value is a colon separated string with the backend names `ndbm', `gdbm' and `bdb'.]), -[ -if test x$with_dbmliborder = xyes -then -AC_MSG_ERROR([proper usage is --with-dbmliborder=db1:db2:...]) -else - as_save_IFS=$IFS - IFS=: - for db in $with_dbmliborder; do - if test x$db != xndbm && test x$db != xgdbm && test x$db != xbdb - then - AC_MSG_ERROR([proper usage is --with-dbmliborder=db1:db2:...]) - fi - done - IFS=$as_save_IFS -fi]) -AC_MSG_RESULT($with_dbmliborder) +[], [with_dbmliborder=gdbm:ndbm:bdb]) + +have_gdbm_dbmliborder=no +as_save_IFS=$IFS +IFS=: +for db in $with_dbmliborder; do + AS_CASE([$db], + [ndbm], [], + [gdbm], [have_gdbm_dbmliborder=yes], + [bdb], [], + [with_dbmliborder=error] + ) +done +IFS=$as_save_IFS +AS_VAR_IF([with_dbmliborder], [error], [ + AC_MSG_ERROR([proper usage is --with-dbmliborder=db1:db2:... (gdbm:ndbm:bdb)]) +]) +AC_MSG_RESULT([$with_dbmliborder]) + +AC_MSG_CHECKING([for _dbm module CFLAGS and LIBS]) +have_dbm=no +as_save_IFS=$IFS +IFS=: +for db in $with_dbmliborder; do + case "$db" in + ndbm) + if test "$have_ndbm" = yes; then + DBM_CFLAGS="-DUSE_NDBM" + DBM_LIBS="$dbm_ndbm" + have_dbm=yes + break + fi + ;; + gdbm) + if test "$have_gdbm_compat" = yes; then + DBM_CFLAGS="-DUSE_GDBM_COMPAT" + DBM_LIBS="-lgdbm_compat" + have_dbm=yes + break + fi + ;; + bdb) + if test "$ac_cv_have_libdb" = yes; then + DBM_CFLAGS="-DUSE_BERKDB" + DBM_LIBS="-ldb" + have_dbm=yes + break + fi + ;; + esac +done +IFS=$as_save_IFS +AC_MSG_RESULT([$DBM_CFLAGS $DBM_LIBS]) # Templates for things AC_DEFINEd more than once. # For a single AC_DEFINE, no template is needed. @@ -3422,6 +4196,7 @@ yes AC_MSG_CHECKING([for pthread_create in -lpthread]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include +#include #include void * start_routine (void *arg) { exit (0); }]], [[ @@ -3449,9 +4224,11 @@ pthread_create (NULL, NULL, start_routine, NULL)]])],[ posix_threads=yes LIBS="$LIBS -lcma" ],[ - AC_MSG_ERROR([could not find pthreads on your system]) - ]) - ])])])])]) + AS_CASE([$ac_sys_system], + [WASI], [posix_threads=stub], + [AC_MSG_ERROR([could not find pthreads on your system])] + ) + ])])])])])]) AC_CHECK_LIB(mpc, usconfig, [ LIBS="$LIBS -lmpc" @@ -3477,6 +4254,9 @@ if test "$posix_threads" = "yes"; then AIX/*) AC_DEFINE(HAVE_BROKEN_POSIX_SEMAPHORES, 1, [Define if the Posix semaphores do not work on your system]) ;; + NetBSD/*) AC_DEFINE(HAVE_BROKEN_POSIX_SEMAPHORES, 1, + [Define if the Posix semaphores do not work on your system]) + ;; esac AC_CACHE_CHECK([if PTHREAD_SCOPE_SYSTEM is supported], [ac_cv_pthread_system_supported], @@ -3486,7 +4266,7 @@ if test "$posix_threads" = "yes"; then void *foo(void *parm) { return NULL; } - main() { + int main(void) { pthread_attr_t attr; pthread_t id; if (pthread_attr_init(&attr)) return (-1); @@ -3511,6 +4291,9 @@ if test "$posix_threads" = "yes"; then AC_CHECK_FUNCS(pthread_getcpuclockid) fi +AS_VAR_IF([posix_threads], [stub], [ + AC_DEFINE([HAVE_PTHREAD_STUBS], [1], [Define if platform requires stubbed pthreads support]) +]) # Check for enable-ipv6 AH_TEMPLATE(ENABLE_IPV6, [Define if --enable-ipv6 is specified]) @@ -3535,13 +4318,17 @@ dnl the check does not work on cross compilation case... #include #include ]], [[int domain = AF_INET6;]])],[ - AC_MSG_RESULT(yes) ipv6=yes ],[ - AC_MSG_RESULT(no) ipv6=no ]) +AS_CASE([$ac_sys_system], + [WASI], [ipv6=no] +) + +AC_MSG_RESULT([$ipv6]) + if test "$ipv6" = "yes"; then AC_MSG_CHECKING(if RFC2553 API is available) AC_COMPILE_IFELSE([ @@ -3662,16 +4449,17 @@ fi if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then if test -d $ipv6libdir -a -f $ipv6libdir/lib$ipv6lib.a; then LIBS="-L$ipv6libdir -l$ipv6lib $LIBS" - echo "using lib$ipv6lib" + AC_MSG_NOTICE([using lib$ipv6lib]) else - if test $ipv6trylibc = "yes"; then - echo "using libc" - else - echo 'Fatal: no $ipv6lib library found. cannot continue.' - echo "You need to fetch lib$ipv6lib.a from appropriate" - echo 'ipv6 kit and compile beforehand.' - exit 1 - fi + AS_VAR_IF([ipv6trylibc], [yes], [ + AC_MSG_NOTICE([using libc]) + ], [ + AC_MSG_ERROR([m4_normalize([ + No $ipv6lib library found; cannot continue. + You need to fetch lib$ipv6lib.a from appropriate + ipv6 kit and compile beforehand. + ])]) + ]) fi fi @@ -3720,7 +4508,12 @@ AC_ARG_WITH(pymalloc, if test -z "$with_pymalloc" then - with_pymalloc="yes" + dnl default to yes except for wasm32-emscripten and wasm32-wasi. + AS_CASE([$ac_sys_system], + [Emscripten], [with_pymalloc="no"], + [WASI], [with_pymalloc="no"], + [with_pymalloc="yes"] + ) fi if test "$with_pymalloc" != "no" then @@ -3817,6 +4610,19 @@ then fi fi +dnl Platform-specific C and header files. +PLATFORM_HEADERS= +PLATFORM_OBJS= + +AS_CASE([$ac_sys_system], + [Emscripten], [ + AS_VAR_APPEND([PLATFORM_OBJS], [' Python/emscripten_signal.o']) + AS_VAR_APPEND([PLATFORM_HEADERS], [' $(srcdir)/Include/internal/pycore_emscripten_signal.h']) + ], +) +AC_SUBST([PLATFORM_HEADERS]) +AC_SUBST([PLATFORM_OBJS]) + # -I${DLINCLDIR} is added to the compile rule for importdl.o AC_SUBST(DLINCLDIR) DLINCLDIR=. @@ -3867,31 +4673,32 @@ else fi # checks for library functions -AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ - clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \ - explicit_memset faccessat fchmod fchmodat fchown fchownat \ - fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \ - futimens futimes gai_strerror getentropy \ - getgrgid getgrgid_r getgrnam_r \ - getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \ - getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \ - if_nameindex \ - initgroups kill killpg lchown lockf linkat lstat lutimes mmap \ - memrchr mbrtowc mkdirat mkfifo \ - madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ - posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \ - pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \ - readlink readlinkat readv realpath renameat \ - sem_open sem_timedwait sem_clockwait sem_getvalue sem_unlink sendfile setegid seteuid \ - setgid sethostname \ - setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \ - sched_get_priority_max sched_setaffinity sched_setscheduler sched_setparam \ - sched_rr_get_interval \ - sigaction sigaltstack sigfillset siginterrupt sigpending sigrelse \ - sigtimedwait sigwait sigwaitinfo snprintf splice strftime strlcpy strsignal symlinkat sync \ - sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ - truncate uname unlinkat utimensat utimes vfork waitid waitpid wait3 wait4 \ - wcscoll wcsftime wcsxfrm wmemcmp writev _getpty rtpSpawn) +AC_CHECK_FUNCS([ \ + accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \ + copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \ + faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \ + fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \ + gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \ + getgrnam_r getgrouplist getgroups gethostname getitimer getloadavg getlogin \ + getpeername getpgid getpid getppid getpriority _getpty \ + getpwent getpwnam_r getpwuid getpwuid_r getresgid getresuid getrusage getsid getspent \ + getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \ + lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \ + mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \ + pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \ + pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \ + pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \ + rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \ + sched_setparam sched_setscheduler sem_clockwait sem_getvalue sem_open \ + sem_timedwait sem_unlink sendfile setegid seteuid setgid sethostname \ + setitimer setlocale setpgid setpgrp setpriority setregid setresgid \ + setresuid setreuid setsid setuid setvbuf shutdown sigaction sigaltstack \ + sigfillset siginterrupt sigpending sigrelse sigtimedwait sigwait \ + sigwaitinfo snprintf splice strftime strlcpy strsignal symlinkat sync \ + sysconf system tcgetpgrp tcsetpgrp tempnam timegm times tmpfile \ + tmpnam tmpnam_r truncate ttyname umask uname unlinkat utimensat utimes vfork \ + wait wait3 wait4 waitid waitpid wcscoll wcsftime wcsxfrm wmemcmp writev \ +]) # Force lchmod off for Linux. Linux disallows changing the mode of symbolic # links. Some libc implementations have a stub lchmod implementation that always @@ -3906,26 +4713,6 @@ AC_CHECK_DECL(dirfd, [#include #include ]) -dnl PY_CHECK_FUNC(FUNCTION, [INCLUDES], [AC_DEFINE-VAR]) -AC_DEFUN([PY_CHECK_FUNC], -[ AS_VAR_PUSHDEF([py_var], [ac_cv_func_$1]) - AS_VAR_PUSHDEF([py_define], m4_ifblank([$3], [[HAVE_]m4_toupper($1)], [$3])) - AC_CACHE_CHECK( - [for $1], - [py_var], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([$2], [void *x=$1])], - [AS_VAR_SET([py_var], [yes])], - [AS_VAR_SET([py_var], [no])])] - ) - AS_VAR_IF( - [py_var], - [yes], - [AC_DEFINE([py_define], [1], [Define if you have the '$1' function.])]) - AS_VAR_POPDEF([py_var]) - AS_VAR_POPDEF([py_define]) -]) - # For some functions, having a definition is not sufficient, since # we want to take their address. PY_CHECK_FUNC([chroot], [#include ]) @@ -3934,7 +4721,7 @@ PY_CHECK_FUNC([symlink], [#include ]) PY_CHECK_FUNC([fchdir], [#include ]) PY_CHECK_FUNC([fsync], [#include ]) PY_CHECK_FUNC([fdatasync], [#include ]) -PY_CHECK_FUNC([epoll], [#include ]) +PY_CHECK_FUNC([epoll_create], [#include ], [HAVE_EPOLL]) PY_CHECK_FUNC([epoll_create1], [#include ]) PY_CHECK_FUNC([kqueue],[ #include @@ -3980,14 +4767,11 @@ AC_CACHE_CHECK([for flock declaration], [ac_cv_flock_decl], [ac_cv_flock_decl=no] ) ]) -if test "x${ac_cv_flock_decl}" = xyes; then - AC_CHECK_FUNCS(flock,, - AC_CHECK_LIB(bsd,flock, - [AC_DEFINE(HAVE_FLOCK) - AC_DEFINE(FLOCK_NEEDS_LIBBSD, 1, Define if flock needs to be linked with bsd library.) - ]) - ) -fi +dnl Linking with libbsd may be necessary on AIX for flock function. +AS_VAR_IF([ac_cv_flock_decl], [yes], + AC_CHECK_FUNCS([flock]) + AC_CHECK_LIB([bsd], [flock], [FCNTL_LIBS="-lbsd"]) +) PY_CHECK_FUNC([getpagesize], [#include ]) @@ -4019,7 +4803,7 @@ AC_CACHE_CHECK([for chflags], [ac_cv_have_chflags], [dnl AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include -int main(int argc, char*argv[]) +int main(int argc, char *argv[]) { if(chflags(argv[0], 0) != 0) return 1; @@ -4041,7 +4825,7 @@ AC_CACHE_CHECK([for lchflags], [ac_cv_have_lchflags], [dnl AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include -int main(int argc, char*argv[]) +int main(int argc, char *argv[]) { if(lchflags(argv[0], 0) != 0) return 1; @@ -4057,41 +4841,100 @@ if test "$ac_cv_have_lchflags" = yes ; then fi dnl Check for compression libraries -AC_CHECK_HEADERS([zlib.h], [ - save_LIBS="$LIBS" - AC_CHECK_LIB([z], [gzread]) - LIBS="$save_LIBS" - AC_CHECK_LIB([z], [inflateCopy], [AC_DEFINE(HAVE_ZLIB_COPY, 1, [Define if the zlib library has inflateCopy])]) - LIBS="$save_LIBS" +AH_TEMPLATE([HAVE_ZLIB_COPY], [Define if the zlib library has inflateCopy]) + +dnl detect zlib from Emscripten emport +PY_CHECK_EMSCRIPTEN_PORT([ZLIB], [-sUSE_ZLIB]) + +PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.0], [ + have_zlib=yes + dnl zlib 1.2.0 (2003) added inflateCopy + AC_DEFINE([HAVE_ZLIB_COPY], [1]) +], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" + LDFLAGS="$LDFLAGS $ZLIB_LIBS" + AC_CHECK_HEADERS([zlib.h], [ + PY_CHECK_LIB([z], [gzread], [have_zlib=yes], [have_zlib=no]) + ], [have_zlib=no]) + AS_VAR_IF([have_zlib], [yes], [ + ZLIB_CFLAGS=${ZLIB_CFLAGS-""} + ZLIB_LIBS=${ZLIB_LIBS-"-lz"} + PY_CHECK_LIB([z], [inflateCopy], [AC_DEFINE([HAVE_ZLIB_COPY], [1])]) + ]) + ]) ]) -AC_CHECK_HEADERS([bzlib.h], [ - save_LIBS="$LIBS" - AC_CHECK_LIB([bz2], [BZ2_bzCompress]) - LIBS="$save_LIBS" +dnl binascii can use zlib for optimized crc32. +AS_VAR_IF([have_zlib], [yes], [ + BINASCII_CFLAGS="-DUSE_ZLIB_CRC32 $ZLIB_CFLAGS" + BINASCII_LIBS="$ZLIB_LIBS" ]) -AC_CHECK_HEADERS([lzma.h], [ - save_LIBS="$LIBS" - AC_CHECK_LIB([lzma], [lzma_easy_encoder]) - LIBS="$save_LIBS" +dnl detect bzip2 from Emscripten emport +PY_CHECK_EMSCRIPTEN_PORT([BZIP2], [-sUSE_BZIP2]) + +PKG_CHECK_MODULES([BZIP2], [bzip2], [have_bzip2=yes], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $BZIP2_CFLAGS" + LDFLAGS="$LDFLAGS $BZIP2_LIBS" + AC_CHECK_HEADERS([bzlib.h], [ + AC_CHECK_LIB([bz2], [BZ2_bzCompress], [have_bzip2=yes], [have_bzip2=no]) + ], [have_bzip2=no]) + AS_VAR_IF([have_bzip2], [yes], [ + BZIP2_CFLAGS=${BZIP2_CFLAGS-""} + BZIP2_LIBS=${BZIP2_LIBS-"-lbz2"} + ]) + ]) ]) -PY_CHECK_FUNC([hstrerror], [#include ]) +PKG_CHECK_MODULES([LIBLZMA], [liblzma], [have_liblzma=yes], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBLZMA_CFLAGS" + LDFLAGS="$LDFLAGS $LIBLZMA_LIBS" + AC_CHECK_HEADERS([lzma.h], [ + AC_CHECK_LIB([lzma], [lzma_easy_encoder], [have_liblzma=yes], [have_liblzma=no]) + ], [have_liblzma=no]) + AS_VAR_IF([have_liblzma], [yes], [ + LIBLZMA_CFLAGS=${LIBLZMA_CFLAGS-""} + LIBLZMA_LIBS=${LIBLZMA_LIBS-"-llzma"} + ]) + ]) +]) -PY_CHECK_FUNC([inet_aton], [ +dnl PY_CHECK_NETDB_FUNC(FUNCTION) +AC_DEFUN([PY_CHECK_NETDB_FUNC], [PY_CHECK_FUNC([$1], [#include ])]) + +PY_CHECK_NETDB_FUNC([hstrerror]) +dnl not available in WASI yet +PY_CHECK_NETDB_FUNC([getservbyname]) +PY_CHECK_NETDB_FUNC([getservbyport]) +PY_CHECK_NETDB_FUNC([gethostbyname]) +PY_CHECK_NETDB_FUNC([gethostbyaddr]) +PY_CHECK_NETDB_FUNC([getprotobyname]) + +dnl PY_CHECK_SOCKET_FUNC(FUNCTION) +AC_DEFUN([PY_CHECK_SOCKET_FUNC], [PY_CHECK_FUNC([$1], [ #include #include #include #include -]) +])]) -PY_CHECK_FUNC([inet_pton], [ -#include -#include -#include -#include -]) +PY_CHECK_SOCKET_FUNC([inet_aton]) +PY_CHECK_SOCKET_FUNC([inet_ntoa]) +PY_CHECK_SOCKET_FUNC([inet_pton]) +dnl not available in WASI yet +PY_CHECK_SOCKET_FUNC([getpeername]) +PY_CHECK_SOCKET_FUNC([getsockname]) +PY_CHECK_SOCKET_FUNC([accept]) +PY_CHECK_SOCKET_FUNC([bind]) +PY_CHECK_SOCKET_FUNC([connect]) +PY_CHECK_SOCKET_FUNC([listen]) +PY_CHECK_SOCKET_FUNC([recvfrom]) +PY_CHECK_SOCKET_FUNC([sendto]) +PY_CHECK_SOCKET_FUNC([setsockopt]) +PY_CHECK_SOCKET_FUNC([socket]) # On some systems, setgroups is in unistd.h, on others, in grp.h PY_CHECK_FUNC([setgroups], [ @@ -4101,7 +4944,7 @@ PY_CHECK_FUNC([setgroups], [ #endif ]) -# check for openpty and forkpty +# check for openpty, login_tty, and forkpty AC_CHECK_FUNCS(openpty,, AC_CHECK_LIB(util,openpty, @@ -4109,6 +4952,9 @@ AC_CHECK_FUNCS(openpty,, AC_CHECK_LIB(bsd,openpty, [AC_DEFINE(HAVE_OPENPTY) LIBS="$LIBS -lbsd"]) ) ) +AC_SEARCH_LIBS([login_tty], [util], + [AC_DEFINE([HAVE_LOGIN_TTY], [1], [Define to 1 if you have the `login_tty' function.])] +) AC_CHECK_FUNCS(forkpty,, AC_CHECK_LIB(util,forkpty, [AC_DEFINE(HAVE_FORKPTY) LIBS="$LIBS -lutil"], @@ -4131,25 +4977,50 @@ AC_CHECK_FUNCS(setpgrp, []) ) -# We search for both crypt and crypt_r as one or the other may be defined -# This gets us our -lcrypt in LIBS when required on the target platform. -# Save/restore LIBS to avoid linking libpython with libcrypt. -LIBS_SAVE=$LIBS -AC_SEARCH_LIBS(crypt_r, crypt) -LIBS="$LIBS_SAVE" -AC_SEARCH_LIBS(crypt, crypt) +# check for namespace functions +AC_CHECK_FUNCS([setns unshare]) -AC_CHECK_FUNC(crypt_r, - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include -]], [[ -struct crypt_data d; -char *r = crypt_r("", "", &d); -]])], - [AC_DEFINE(HAVE_CRYPT_R, 1, [Define if you have the crypt_r() function.])], - []) -) -LIBS=$LIBS_SAVE +dnl We search for both crypt and crypt_r as one or the other may be defined +dnl libxcrypt provides and libcrypt with crypt_r() since +dnl at least 3.1.1 from 2015. +dnl FreeBSD defines crypt_r() in +AH_TEMPLATE([HAVE_CRYPT_R], [Define if you have the crypt_r() function.]) + +PKG_CHECK_MODULES([LIBCRYPT], [libxcrypt >= 3.1.1], [ + AC_DEFINE([HAVE_CRYPT_R], [1]) +], [ + WITH_SAVE_ENV([ + AC_SEARCH_LIBS([crypt_r], [crypt], [ + AC_DEFINE([HAVE_CRYPT_R], [1]) + if test "$ac_cv_search_crypt_r" = "none required"; then + libcrypt= + else + libcrypt="$ac_cv_search_crypt_r" + fi + LIBCRYPT_LIBS=${LIBCRYPT_LIBS-$libcrypt} + ]) + ]) +]) + +WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBCRYPT_CFLAGS" + LIBS="$LIBCRYPT_LIBS $LIBS" + AC_CACHE_CHECK([for crypt or crypt_r], [ac_cv_crypt_crypt], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([ + #ifdef HAVE_CRYPT_H + #include + #endif + #include + ], [ + #ifdef HAVE_CRYPT_R + void *x = crypt_r; + #else + void *x = crypt; + #endif + ]) + ], [ac_cv_crypt_crypt=yes], [ac_cv_crypt_crypt=no]) + ]) +]) AC_CHECK_FUNCS(clock_gettime, [], [ AC_CHECK_LIB(rt, clock_gettime, [ @@ -4230,7 +5101,7 @@ AS_VAR_IF([ac_cv_func_getaddrinfo], [yes], [ #include #include -int main() +int main(void) { int passive, gaierr, inet4 = 0, inet6 = 0; struct addrinfo hints, *ai, *aitop; @@ -4326,12 +5197,12 @@ dnl if ac_cv_func_getaddrinfo if test "$ac_cv_func_getaddrinfo" = no -o "$ac_cv_buggy_getaddrinfo" = yes then - if test $ipv6 = yes - then - echo 'Fatal: You must get working getaddrinfo() function.' - echo ' or you can specify "--disable-ipv6"'. - exit 1 - fi + AS_VAR_IF([ipv6], [yes], [ + AC_MSG_ERROR([m4_normalize([ + You must get working getaddrinfo() function + or pass the "--disable-ipv6" option to configure. + ])]) + ]) else AC_DEFINE(HAVE_GETADDRINFO, 1, [Define if you have the getaddrinfo function.]) fi @@ -4400,7 +5271,6 @@ fi # checks for compiler characteristics -AC_C_CHAR_UNSIGNED AC_C_CONST AC_CACHE_CHECK([for working signed char], [ac_cv_working_signed_char_c], [ @@ -4420,27 +5290,6 @@ AS_VAR_IF([ac_cv_function_prototypes], [yes], [ [Define if your compiler supports function prototype]) ]) -works=no -AC_CACHE_CHECK([for variable length prototypes and stdarg.h], [ac_cv_stdarg_prototypes], [ -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include -int foo(int x, ...) { - va_list va; - va_start(va, x); - va_arg(va, int); - va_arg(va, char *); - va_arg(va, double); - return 0; -} -]], [[return foo(10, "", 3.14);]])], - [ac_cv_stdarg_prototypes=yes], [ac_cv_stdarg_prototypes=no]) -]) -AS_VAR_IF([ac_cv_stdarg_prototypes], [yes], [ - AC_DEFINE(HAVE_STDARG_PROTOTYPES, 1, - [Define if your compiler supports variable length function prototypes - (e.g. void fprintf(FILE *, char *, ...);) *and* ]) -]) - # check for socketpair PY_CHECK_FUNC([socketpair], [ @@ -4660,7 +5509,7 @@ AS_VAR_IF([ac_cv_gcc_asm_for_mc68881], [yes], [ # rounding issues. The result of this test has little meaning on non # IEEE 754 platforms. On IEEE 754, test should return 1 if rounding # mode is round-to-nearest and double rounding issues are present, and -# 0 otherwise. See http://bugs.python.org/issue2937 for more info. +# 0 otherwise. See https://github.com/python/cpython/issues/47186 for more info. AC_CACHE_CHECK([for x87-style double rounding], [ac_cv_x87_double_rounding], [ # $BASECFLAGS may affect the result ac_save_cc="$CC" @@ -4668,7 +5517,7 @@ CC="$CC $BASECFLAGS" AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include -int main() { +int main(void) { volatile double x, y, z; /* 1./(1-2**-53) -> 1+2**-52 (correct), 1.0 (double rounding) */ x = 0.99999999999999989; /* 1-2**-53 */ @@ -4710,80 +5559,86 @@ AC_CHECK_FUNCS( ) LIBS=$LIBS_SAVE -# For multiprocessing module, check that sem_open -# actually works. For FreeBSD versions <= 7.2, -# the kernel module that provides POSIX semaphores -# isn't loaded by default, so an attempt to call -# sem_open results in a 'Signal 12' error. +dnl For multiprocessing module, check that sem_open +dnl actually works. For FreeBSD versions <= 7.2, +dnl the kernel module that provides POSIX semaphores +dnl isn't loaded by default, so an attempt to call +dnl sem_open results in a 'Signal 12' error. AC_CACHE_CHECK([whether POSIX semaphores are enabled], [ac_cv_posix_semaphores_enabled], -AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include -#include -#include -#include -#include + AC_RUN_IFELSE([ + AC_LANG_SOURCE([ + #include + #include + #include + #include + #include -int main(void) { - sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); - if (a == SEM_FAILED) { - perror("sem_open"); - return 1; - } - sem_close(a); - sem_unlink("/autoconf"); - return 0; -} -]])], -[ac_cv_posix_semaphores_enabled=yes], -[ac_cv_posix_semaphores_enabled=no], -[ac_cv_posix_semaphores_enabled=yes]) + int main(void) { + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + if (a == SEM_FAILED) { + perror("sem_open"); + return 1; + } + sem_close(a); + sem_unlink("/autoconf"); + return 0; + } + ]) + ], + [ac_cv_posix_semaphores_enabled=yes], + [ac_cv_posix_semaphores_enabled=no], + [ac_cv_posix_semaphores_enabled=yes]) ) -if test $ac_cv_posix_semaphores_enabled = no -then - AC_DEFINE(POSIX_SEMAPHORES_NOT_ENABLED, 1, - [Define if POSIX semaphores aren't enabled on your system]) -fi +AS_VAR_IF([ac_cv_posix_semaphores_enabled], [no], [ + AC_DEFINE( + [POSIX_SEMAPHORES_NOT_ENABLED], [1], + [Define if POSIX semaphores aren't enabled on your system] + ) +]) -# Multiprocessing check for broken sem_getvalue +dnl Multiprocessing check for broken sem_getvalue AC_CACHE_CHECK([for broken sem_getvalue], [ac_cv_broken_sem_getvalue], -AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include -#include -#include -#include -#include + AC_RUN_IFELSE([ + AC_LANG_SOURCE([ + #include + #include + #include + #include + #include -int main(void){ - sem_t *a = sem_open("/autocftw", O_CREAT, S_IRUSR|S_IWUSR, 0); - int count; - int res; - if(a==SEM_FAILED){ - perror("sem_open"); - return 1; + int main(void){ + sem_t *a = sem_open("/autocftw", O_CREAT, S_IRUSR|S_IWUSR, 0); + int count; + int res; + if(a==SEM_FAILED){ + perror("sem_open"); + return 1; - } - res = sem_getvalue(a, &count); - sem_close(a); - sem_unlink("/autocftw"); - return res==-1 ? 1 : 0; -} -]])], -[ac_cv_broken_sem_getvalue=no], -[ac_cv_broken_sem_getvalue=yes], -[ac_cv_broken_sem_getvalue=yes]) + } + res = sem_getvalue(a, &count); + sem_close(a); + sem_unlink("/autocftw"); + return res==-1 ? 1 : 0; + } + ]) + ], + [ac_cv_broken_sem_getvalue=no], + [ac_cv_broken_sem_getvalue=yes], + [ac_cv_broken_sem_getvalue=yes]) ) -if test $ac_cv_broken_sem_getvalue = yes -then - AC_DEFINE(HAVE_BROKEN_SEM_GETVALUE, 1, - [define to 1 if your sem_getvalue is broken.]) -fi +AS_VAR_IF([ac_cv_broken_sem_getvalue], [yes], [ + AC_DEFINE( + [HAVE_BROKEN_SEM_GETVALUE], [1], + [define to 1 if your sem_getvalue is broken.] + ) +]) AC_CHECK_DECLS([RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND, RTLD_MEMBER], [], [], [[#include ]]) # determine what size digit to use for Python's longs AC_MSG_CHECKING([digit size for Python's longs]) AC_ARG_ENABLE(big-digits, -AS_HELP_STRING([--enable-big-digits@<:@=15|30@:>@],[use big digits (30 or 15 bits) for Python longs (default is system-dependent)]]), +AS_HELP_STRING([--enable-big-digits@<:@=15|30@:>@],[use big digits (30 or 15 bits) for Python longs (default is 30)]]), [case $enable_big_digits in yes) enable_big_digits=30 ;; @@ -4814,18 +5669,6 @@ then AC_CHECK_SIZEOF(wchar_t, 4, [#include ]) fi -AC_MSG_CHECKING(for UCS-4 tcl) -have_ucs4_tcl=no -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include -#if TCL_UTF_MAX != 6 -# error "NOT UCS4_TCL" -#endif]], [[]])],[ - AC_DEFINE(HAVE_UCS4_TCL, 1, [Define this if you have tcl and TCL_UTF_MAX==6]) - have_ucs4_tcl=yes -],[]) -AC_MSG_RESULT($have_ucs4_tcl) - # check whether wchar_t is signed or not if test "$wchar_h" = yes then @@ -4981,7 +5824,7 @@ fi], # or fills with zeros (like the Cray J90, according to Tim Peters). AC_CACHE_CHECK([whether right shift extends the sign bit], [ac_cv_rshift_extends_sign], [ AC_RUN_IFELSE([AC_LANG_SOURCE([[ -int main() +int main(void) { return (((-1)>>3 == -1) ? 0 : 1); } @@ -5010,133 +5853,177 @@ then [Define this if you have flockfile(), getc_unlocked(), and funlockfile()]) fi -AC_ARG_WITH([readline], - [AS_HELP_STRING([--with(out)-readline@<:@=editline@:>@], - [use Editline for backend or disable readline module])], - [], - [with_readline=yes]) +dnl Check for libreadline and libedit +dnl - libreadline provides "readline/readline.h" header and "libreadline" +dnl shared library. pkg-config file is readline.pc +dnl - libedit provides "editline/readline.h" header and "libedit" shared +dnl library. pkg-config file ins libedit.pc +dnl - editline is not supported ("readline.h" and "libeditline" shared library) +dnl +dnl NOTE: In the past we checked if readline needs an additional termcap +dnl library (tinfo ncursesw ncurses termcap). We now assume that libreadline +dnl or readline.pc provide correct linker information. -# check where readline lives -py_cv_lib_readline=no -# save the value of LIBS so we don't actually link Python with readline -LIBS_no_readline=$LIBS +AH_TEMPLATE([WITH_EDITLINE], [Define to build the readline module against libedit.]) -if test "$with_readline" != no; then - case "$with_readline" in - editline|edit) - LIBREADLINE=edit - AC_DEFINE(WITH_EDITLINE, 1, - [Define to build the readline module against Editline.]) - ;; - yes|readline) +AC_ARG_WITH( + [readline], + [AS_HELP_STRING([--with(out)-readline@<:@=editline|readline|no@:>@], + [use libedit for backend or disable readline module])], + [ + AS_CASE([$with_readline], + [editline|edit], [with_readline=edit], + [yes|readline], [with_readline=readline], + [no], [], + [AC_MSG_ERROR([proper usage is --with(out)-readline@<:@=editline|readline|no@:>@])] + ) + ], + [with_readline=readline] +) + +AS_VAR_IF([with_readline], [readline], [ + PKG_CHECK_MODULES([LIBREADLINE], [readline], [ LIBREADLINE=readline - ;; - *) - AC_MSG_ERROR([proper usage is --with(out)-readline@<:@=editline@:>@]) - ;; - esac - - # On some systems we need to link readline to a termcap compatible - # library. NOTE: Keep the precedence of listed libraries synchronised - # with setup.py. - AC_MSG_CHECKING([how to link readline libs]) - for py_libtermcap in "" tinfo ncursesw ncurses curses termcap; do - if test -z "$py_libtermcap"; then - READLINE_LIBS="-l$LIBREADLINE" - else - READLINE_LIBS="-l$LIBREADLINE -l$py_libtermcap" - fi - LIBS="$READLINE_LIBS $LIBS_no_readline" - AC_LINK_IFELSE( - [AC_LANG_CALL([],[readline])], - [py_cv_lib_readline=yes]) - if test $py_cv_lib_readline = yes; then - break - fi - done - - # Uncomment this line if you want to use READLINE_LIBS in Makefile or scripts - #AC_SUBST([READLINE_LIBS]) - if test $py_cv_lib_readline = no; then - AC_MSG_RESULT([none]) - else - AC_MSG_RESULT([$READLINE_LIBS]) - AC_DEFINE(HAVE_LIBREADLINE, 1, - [Define to build the readline module.]) - fi -fi - -if test "$py_cv_lib_readline" = yes; then - # check for readline 2.2 - AC_CHECK_DECL(rl_completion_append_character, - AC_DEFINE(HAVE_RL_COMPLETION_APPEND_CHARACTER, 1, - [Define if you have readline 2.2]),, - [ -#include /* Must be first for Gnu Readline */ -#ifdef WITH_EDITLINE -# include -#else -# include -#endif + READLINE_CFLAGS=$LIBREADLINE_CFLAGS + READLINE_LIBS=$LIBREADLINE_LIBS + ], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBREADLINE_CFLAGS" + LDFLAGS="$LDFLAGS $LIBREADLINE_LIBS" + AC_CHECK_HEADERS([readline/readline.h], [ + AC_CHECK_LIB([readline], [readline], [ + LIBREADLINE=readline + READLINE_CFLAGS=${LIBREADLINE_CFLAGS-""} + READLINE_LIBS=${LIBREADLINE_LIBS-"-lreadline"} + ], [with_readline=no]) + ], [with_readline=no]) ]) - AC_CHECK_DECL(rl_completion_suppress_append, - AC_DEFINE(HAVE_RL_COMPLETION_SUPPRESS_APPEND, 1, - [Define if you have rl_completion_suppress_append]),, - [ -#include /* Must be first for Gnu Readline */ -#ifdef WITH_EDITLINE -# include -#else -# include -#endif + ]) +]) + +AS_VAR_IF([with_readline], [edit], [ + PKG_CHECK_MODULES([LIBEDIT], [libedit], [ + AC_DEFINE([WITH_EDITLINE], [1]) + LIBREADLINE=edit + READLINE_CFLAGS=$LIBEDIT_CFLAGS + READLINE_LIBS=$LIBEDIT_LIBS + ], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBEDIT_CFLAGS" + LDFLAGS="$LDFLAGS $LIBEDIT_LIBS" + AC_CHECK_HEADERS([editline/readline.h], [ + AC_CHECK_LIB([edit], [readline], [ + LIBREADLINE=edit + AC_DEFINE([WITH_EDITLINE], [1]) + READLINE_CFLAGS=${LIBEDIT_CFLAGS-""} + READLINE_LIBS=${LIBEDIT_LIBS-"-ledit"} + ], [with_readline=no]) + ], [with_readline=no]) + ]) + ]) +]) + +dnl pyconfig.h defines _XOPEN_SOURCE=700 +READLINE_CFLAGS=$(echo $READLINE_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') + +AC_MSG_CHECKING([how to link readline]) +AS_VAR_IF([with_readline], [no], [ + AC_MSG_RESULT([no]) +], [ + AC_MSG_RESULT([$with_readline (CFLAGS: $READLINE_CFLAGS, LIBS: $READLINE_LIBS)]) + + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $READLINE_CFLAGS" + LIBS="$READLINE_LIBS $LIBS" + LIBS_SAVE=$LIBS + + m4_define([readline_includes], [ + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif ]) - # check for readline 4.0 - AC_CHECK_LIB($LIBREADLINE, rl_pre_input_hook, - AC_DEFINE(HAVE_RL_PRE_INPUT_HOOK, 1, - [Define if you have readline 4.0]),,$READLINE_LIBS) + # check for readline 2.2 + AC_CHECK_DECL([rl_completion_append_character], [ + AC_DEFINE([HAVE_RL_COMPLETION_APPEND_CHARACTER], [1], [Define if you have readline 2.2]) + ], [], [readline_includes]) - # also in 4.0 - AC_CHECK_LIB($LIBREADLINE, rl_completion_display_matches_hook, - AC_DEFINE(HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK, 1, - [Define if you have readline 4.0]),,$READLINE_LIBS) + AC_CHECK_DECL([rl_completion_suppress_append], [ + AC_DEFINE([HAVE_RL_COMPLETION_SUPPRESS_APPEND], [1], [Define if you have rl_completion_suppress_append]) + ], [], [readline_includes]) - # also in 4.0, but not in editline - AC_CHECK_LIB($LIBREADLINE, rl_resize_terminal, - AC_DEFINE(HAVE_RL_RESIZE_TERMINAL, 1, - [Define if you have readline 4.0]),,$READLINE_LIBS) - - # check for readline 4.2 - AC_CHECK_LIB($LIBREADLINE, rl_completion_matches, - AC_DEFINE(HAVE_RL_COMPLETION_MATCHES, 1, - [Define if you have readline 4.2]),,$READLINE_LIBS) - - # also in readline 4.2 - AC_CHECK_DECL(rl_catch_signals, - AC_DEFINE(HAVE_RL_CATCH_SIGNAL, 1, - [Define if you can turn off readline's signal handling.]),, - [ -#include /* Must be first for Gnu Readline */ -#ifdef WITH_EDITLINE -# include -#else -# include -#endif + # check for readline 4.0 + AC_CACHE_CHECK([for rl_pre_input_hook in -l$LIBREADLINE], [ac_cv_readline_rl_pre_input_hook], [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([readline_includes], [void *x = rl_pre_input_hook])], + [ac_cv_readline_rl_pre_input_hook=yes], [ac_cv_readline_rl_pre_input_hook=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_rl_pre_input_hook], [yes], [ + AC_DEFINE([HAVE_RL_PRE_INPUT_HOOK], [1], [Define if you have readline 4.0]) ]) - AC_CHECK_LIB($LIBREADLINE, append_history, - AC_DEFINE(HAVE_RL_APPEND_HISTORY, 1, - [Define if readline supports append_history]),,$READLINE_LIBS) -fi + # also in 4.0 + AC_CACHE_CHECK([for rl_completion_display_matches_hook in -l$LIBREADLINE], [ac_cv_readline_rl_completion_display_matches_hook], [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([readline_includes], [void *x = rl_completion_display_matches_hook])], + [ac_cv_readline_rl_completion_display_matches_hook=yes], [ac_cv_readline_rl_completion_display_matches_hook=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_rl_completion_display_matches_hook], [yes], [ + AC_DEFINE([HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK], [1], [Define if you have readline 4.0]) + ]) -# End of readline checks: restore LIBS -LIBS=$LIBS_no_readline + # also in 4.0, but not in editline + AC_CACHE_CHECK([for rl_resize_terminal in -l$LIBREADLINE], [ac_cv_readline_rl_resize_terminal], [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([readline_includes], [void *x = rl_resize_terminal])], + [ac_cv_readline_rl_resize_terminal=yes], [ac_cv_readline_rl_resize_terminal=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_rl_resize_terminal], [yes], [ + AC_DEFINE([HAVE_RL_RESIZE_TERMINAL], [1], [Define if you have readline 4.0]) + ]) + + # check for readline 4.2 + AC_CACHE_CHECK([for rl_completion_matches in -l$LIBREADLINE], [ac_cv_readline_rl_completion_matches], [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([readline_includes], [void *x = rl_completion_matches])], + [ac_cv_readline_rl_completion_matches=yes], [ac_cv_readline_rl_completion_matches=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_rl_completion_matches], [yes], [ + AC_DEFINE([HAVE_RL_COMPLETION_MATCHES], [1], [Define if you have readline 4.2]) + ]) + + # also in readline 4.2 + AC_CHECK_DECL([rl_catch_signals], [ + AC_DEFINE([HAVE_RL_CATCH_SIGNAL], [1], [Define if you can turn off readline's signal handling.]) + ], [], [readline_includes]) + + AC_CACHE_CHECK([for append_history in -l$LIBREADLINE], [ac_cv_readline_append_history], [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([readline_includes], [void *x = append_history])], + [ac_cv_readline_append_history=yes], [ac_cv_readline_append_history=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_append_history], [yes], [ + AC_DEFINE([HAVE_RL_APPEND_HISTORY], [1], [Define if readline supports append_history]) + ]) + + m4_undefine([readline_includes]) + ])dnl WITH_SAVE_ENV() +]) AC_CACHE_CHECK([for broken nice()], [ac_cv_broken_nice], [ AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include -int main() +int main(void) { int val1 = nice(1); if (val1 != -1 && val1 == nice(2)) @@ -5158,7 +6045,7 @@ AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include -int main() +int main(void) { struct pollfd poll_struct = { 42, POLLIN|POLLPRI|POLLOUT, 0 }; int poll_test; @@ -5194,7 +6081,7 @@ AC_RUN_IFELSE([AC_LANG_SOURCE([[ extern char *tzname[]; #endif -int main() +int main(void) { /* Note that we need to ensure that not only does tzset(3) do 'something' with localtime, but it works as documented @@ -5286,14 +6173,128 @@ then [Define if you have struct stat.st_mtimensec]) fi +dnl check for ncurses/ncursesw and panel/panelw +dnl NOTE: old curses is not detected. +dnl have_curses=[no, ncursesw, ncurses] +dnl have_panel=[no, panelw, panel] +have_curses=no +have_panel=no + +AH_TEMPLATE([HAVE_NCURSESW], [Define to 1 if you have the `ncursesw' library.]) +AC_CHECK_HEADERS([curses.h ncurses.h]) + +AS_VAR_IF([ac_cv_header_ncurses_h], [yes], [ + if test "$ac_sys_system" != "Darwin"; then + dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw. + PKG_CHECK_MODULES([CURSES], [ncursesw], [ + AC_DEFINE([HAVE_NCURSESW], [1]) + have_curses=ncursesw + ], [ + WITH_SAVE_ENV([ + AC_CHECK_LIB([ncursesw], [initscr], [ + AC_DEFINE([HAVE_NCURSESW], [1]) + have_curses=ncursesw + CURSES_CFLAGS=${CURSES_CFLAGS-""} + CURSES_LIBS=${CURSES_LIBS-"-lncursesw"} + ]) + ]) + ]) + fi + + AS_VAR_IF([have_curses], [no], [ + PKG_CHECK_MODULES([CURSES], [ncurses], [ + have_curses=ncurses + ], [ + WITH_SAVE_ENV([ + AC_CHECK_LIB([ncurses], [initscr], [ + have_curses=ncurses + CURSES_CFLAGS=${CURSES_CFLAGS-""} + CURSES_LIBS=${CURSES_LIBS-"-lncurses"} + ]) + ]) + ]) + ]) + +])dnl ac_cv_header_ncurses_h = yes + +dnl remove _XOPEN_SOURCE macro from curses cflags. pyconfig.h sets +dnl the macro to 700. +CURSES_CFLAGS=$(echo $CURSES_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') + +if test "$have_curses" = no -a "$ac_sys_system" = "Darwin"; then + dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw. + dnl If we are here, we found a locally-supplied version of libncursesw. + dnl There should also be a libpanelw. + dnl _XOPEN_SOURCE defines are usually excluded for macOS, but we need + dnl _XOPEN_SOURCE_EXTENDED here for ncurses wide char support. + + AS_VAR_APPEND([CURSES_CFLAGS], [" -D_XOPEN_SOURCE_EXTENDED=1"]) + AC_DEFINE([HAVE_NCURSESW], [1]) +fi + +dnl TODO: detect "curses" and special cases tinfo, terminfo, or termcap + +AC_MSG_CHECKING([curses module flags]) +AS_VAR_IF([have_curses], [no], [ + AC_MSG_RESULT([no]) +], [ + AC_MSG_RESULT([$have_curses (CFLAGS: $CURSES_CFLAGS, LIBS: $CURSES_LIBS)]) +]) + +dnl check for ncurses' panel/panelw library +AC_CHECK_HEADERS([panel.h]) + +AS_VAR_IF([ac_cv_header_panel_h], [yes], [ + + if test "$ac_sys_system" != "Darwin"; then + dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw. + AS_VAR_IF([have_curses], [ncursesw], [ + PKG_CHECK_MODULES([PANEL], [panelw], [ + have_panel=panelw + ], [ + WITH_SAVE_ENV([ + AC_CHECK_LIB([panelw], [update_panels], [ + have_panel=panelw + PANEL_CFLAGS=${PANEL_CFLAGS-""} + PANEL_LIBS=${PANEL_LIBS-"-lpanelw"} + ]) + ]) + ]) + ]) + fi + + AS_VAR_IF([have_curses], [ncurses], [ + PKG_CHECK_MODULES([PANEL], [panel], [ + have_panel=panel + ], [ + WITH_SAVE_ENV([ + AC_CHECK_LIB([panel], [update_panels], [ + have_panel=panel + PANEL_CFLAGS=${PANEL_CFLAGS-""} + PANEL_LIBS=${PANEL_LIBS-"-lpanel"} + ]) + ]) + ]) + ]) + +])dnl ac_cv_header_panel_h = yes + +dnl pyconfig.h defines _XOPEN_SOURCE=700 +PANEL_CFLAGS=$(echo $PANEL_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') + +AC_MSG_CHECKING([panel flags]) +AS_VAR_IF([have_panel], [no], [ + AC_MSG_RESULT([no]) +], [ + AC_MSG_RESULT([$have_panel (CFLAGS: $PANEL_CFLAGS, LIBS: $PANEL_LIBS)]) +]) + # first curses header check ac_save_cppflags="$CPPFLAGS" if test "$cross_compiling" = no; then CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw" fi -AC_CHECK_HEADERS(curses.h ncurses.h) - # On Solaris, term.h requires curses.h AC_CHECK_HEADERS(term.h,,,[ #ifdef HAVE_CURSES_H @@ -5408,52 +6409,6 @@ then LIBS="$LIBS -framework CoreFoundation" fi -AC_CACHE_CHECK([for %zd printf() format support], ac_cv_have_size_t_format, [dnl -AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include -#include -#include - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_SSIZE_T -typedef ssize_t Py_ssize_t; -#elif SIZEOF_VOID_P == SIZEOF_LONG -typedef long Py_ssize_t; -#else -typedef int Py_ssize_t; -#endif - -int main() -{ - char buffer[256]; - - if(sprintf(buffer, "%zd", (size_t)123) < 0) - return 1; - - if (strcmp(buffer, "123")) - return 1; - - if (sprintf(buffer, "%zd", (Py_ssize_t)-123) < 0) - return 1; - - if (strcmp(buffer, "-123")) - return 1; - - return 0; -} -]])], - [ac_cv_have_size_t_format=yes], - [ac_cv_have_size_t_format=no], - [ac_cv_have_size_t_format="cross -- assuming yes" -])]) -if test "$ac_cv_have_size_t_format" != no ; then - AC_DEFINE(PY_FORMAT_SIZE_T, "z", - [Define to printf format modifier for Py_ssize_t]) -fi - AC_CHECK_TYPE(socklen_t,, AC_DEFINE(socklen_t,int, [Define to `int' if does not define.]),[ @@ -5467,9 +6422,10 @@ AC_CHECK_TYPE(socklen_t,, AC_CACHE_CHECK([for broken mbstowcs], [ac_cv_broken_mbstowcs], AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include #include -#include -int main() { +#include +int main(void) { size_t len = -1; const char *str = "text"; len = mbstowcs(NULL, str, 0); @@ -5556,6 +6512,8 @@ SRCDIRS="\ Modules/_multiprocessing \ Modules/_sha3 \ Modules/_sqlite \ + Modules/_sre \ + Modules/_testcapi \ Modules/_xxtestfuzz \ Modules/cjkcodecs \ Modules/expat \ @@ -5563,6 +6521,7 @@ SRCDIRS="\ Parser \ Programs \ Python \ + Python/frozen_modules \ Python/deepfreeze" AC_MSG_CHECKING(for build directories) for dir in $SRCDIRS; do @@ -5593,7 +6552,7 @@ AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include void foo(void *p, void *q) { memmove(p, q, 19); } -int main() { +int main(void) { char a[32] = "123456789000000000"; foo(&a[9], a); if (strcmp(a, "123456789123456789000000000") != 0) @@ -5634,7 +6593,7 @@ if test "$ac_cv_gcc_asm_for_x87" = yes; then ); return r; } - int main() { + int main(void) { int p = 8; if ((foo(&p) ? : p) != 6) return 1; @@ -5662,7 +6621,7 @@ AC_LINK_IFELSE( #include atomic_int int_var; atomic_uintptr_t uintptr_var; - int main() { + int main(void) { atomic_store_explicit(&int_var, 5, memory_order_relaxed); atomic_store_explicit(&uintptr_var, 0, memory_order_relaxed); int loaded_value = atomic_load_explicit(&int_var, memory_order_seq_cst); @@ -5683,7 +6642,7 @@ AC_LINK_IFELSE( [ AC_LANG_SOURCE([[ int val; - int main() { + int main(void) { __atomic_store_n(&val, 1, __ATOMIC_SEQ_CST); (void)__atomic_load_n(&val, __ATOMIC_SEQ_CST); return 0; @@ -5702,7 +6661,13 @@ AC_ARG_WITH(ensurepip, [AS_HELP_STRING([--with-ensurepip@<:@=install|upgrade|no@:>@], ["install" or "upgrade" using bundled pip (default is upgrade)])], [], - [with_ensurepip=upgrade]) + [ + AS_CASE([$ac_sys_system], + [Emscripten], [with_ensurepip=no], + [WASI], [with_ensurepip=no], + [with_ensurepip=upgrade] + ) + ]) AS_CASE($with_ensurepip, [yes|upgrade],[ENSUREPIP=upgrade], [install],[ENSUREPIP=install], @@ -5718,7 +6683,7 @@ AC_LINK_IFELSE( AC_LANG_SOURCE([[ #include - int main() { + int main(void) { struct dirent entry; return entry.d_type == DT_UNKNOWN; } @@ -5736,11 +6701,12 @@ AC_CACHE_CHECK([for the Linux getrandom() syscall], [ac_cv_getrandom_syscall], [ AC_LINK_IFELSE( [ AC_LANG_SOURCE([[ + #include #include #include #include - int main() { + int main(void) { char buffer[1]; const size_t buflen = sizeof(buffer); const int flags = GRND_NONBLOCK; @@ -5763,9 +6729,10 @@ AC_CACHE_CHECK([for the getrandom() function], [ac_cv_func_getrandom], [ AC_LINK_IFELSE( [ AC_LANG_SOURCE([[ + #include #include - int main() { + int main(void) { char buffer[1]; const size_t buflen = sizeof(buffer); const int flags = 0; @@ -5784,32 +6751,35 @@ AS_VAR_IF([ac_cv_func_getrandom], [yes], [ # checks for POSIX shared memory, used by Modules/_multiprocessing/posixshmem.c # shm_* may only be available if linking against librt -save_LIBS="$LIBS" -save_includes_default="$ac_includes_default" -AC_SEARCH_LIBS(shm_open, rt) -if test "$ac_cv_search_shm_open" = "-lrt"; then - AC_DEFINE(SHM_NEEDS_LIBRT, 1, - [Define to 1 if you must link with -lrt for shm_open().]) -fi -AC_CHECK_HEADERS(sys/mman.h) -# temporarily override ac_includes_default for AC_CHECK_FUNCS below -ac_includes_default="\ -${ac_includes_default} -#ifndef __cplusplus -# ifdef HAVE_SYS_MMAN_H -# include -# endif -#endif -" -AC_CHECK_FUNCS([shm_open shm_unlink]) -# we don't want to link with librt always, restore LIBS -LIBS="$save_LIBS" -ac_includes_default="$save_includes_default" +POSIXSHMEM_CFLAGS='-I$(srcdir)/Modules/_multiprocessing' +WITH_SAVE_ENV([ + AC_SEARCH_LIBS([shm_open], [rt]) + AS_VAR_IF([ac_cv_search_shm_open], [-lrt], [POSIXSHMEM_LIBS="-lrt"]) + + dnl Temporarily override ac_includes_default for AC_CHECK_FUNCS below. + _SAVE_VAR([ac_includes_default]) + ac_includes_default="\ + ${ac_includes_default} + #ifndef __cplusplus + # ifdef HAVE_SYS_MMAN_H + # include + # endif + #endif + " + AC_CHECK_FUNCS([shm_open shm_unlink], [have_posix_shmem=yes], [have_posix_shmem=no]) + _RESTORE_VAR([ac_includes_default]) +]) # Check for usable OpenSSL AX_CHECK_OPENSSL([have_openssl=yes],[have_openssl=no]) # rpath to libssl and libcrypto +AS_VAR_IF([GNULD], [yes], [ + rpath_arg="-Wl,--enable-new-dtags,-rpath=" +], [ + rpath_arg="-Wl,-rpath=" +]) + AC_MSG_CHECKING(for --with-openssl-rpath) AC_ARG_WITH(openssl-rpath, AS_HELP_STRING([--with-openssl-rpath=@<:@DIR|auto|no@:>@], @@ -5822,58 +6792,103 @@ AC_ARG_WITH(openssl-rpath, [with_openssl_rpath=no] ) AS_CASE($with_openssl_rpath, - [auto|yes],[OPENSSL_RPATH=auto], - [no],[OPENSSL_RPATH=], + [auto|yes], [ + OPENSSL_RPATH=auto + dnl look for linker directories + for arg in "$OPENSSL_LDFLAGS"; do + AS_CASE([$arg], + [-L*], [OPENSSL_LDFLAGS_RPATH="$OPENSSL_LDFLAGS_RPATH ${rpath_arg}$(echo $arg | cut -c3-)"] + ) + done + ], + [no], [OPENSSL_RPATH=], [AS_IF( [test -d "$with_openssl_rpath"], - [OPENSSL_RPATH="$with_openssl_rpath"], + [ + OPENSSL_RPATH="$with_openssl_rpath" + OPENSSL_LDFLAGS_RPATH="${rpath_arg}$with_openssl_rpath" + ], AC_MSG_ERROR([--with-openssl-rpath "$with_openssl_rpath" is not a directory])) ] ) AC_MSG_RESULT($OPENSSL_RPATH) -AC_SUBST([OPENSSL_RPATH]) + +# This static linking is NOT OFFICIALLY SUPPORTED and not advertised. +# Requires static OpenSSL build with position-independent code. Some features +# like DSO engines or external OSSL providers don't work. Only tested with GCC +# and clang on X86_64. +AS_VAR_IF([PY_UNSUPPORTED_OPENSSL_BUILD], [static], [ + AC_MSG_CHECKING([for unsupported static openssl build]) + new_OPENSSL_LIBS= + for arg in $OPENSSL_LIBS; do + AS_CASE([$arg], + [-l*], [ + libname=$(echo $arg | cut -c3-) + new_OPENSSL_LIBS="$new_OPENSSL_LIBS -l:lib${libname}.a -Wl,--exclude-libs,lib${libname}.a" + ], + [new_OPENSSL_LIBS="$new_OPENSSL_LIBS $arg"] + ) + done + dnl include libz for OpenSSL build flavors with compression support + OPENSSL_LIBS="$new_OPENSSL_LIBS $ZLIB_LIBS" + AC_MSG_RESULT([$OPENSSL_LIBS]) +]) + +dnl AX_CHECK_OPENSSL does not export libcrypto-only libs +LIBCRYPTO_LIBS= +for arg in $OPENSSL_LIBS; do + AS_CASE([$arg], + [-l*ssl*|-Wl*ssl*], [], + [LIBCRYPTO_LIBS="$LIBCRYPTO_LIBS $arg"] + ) +done # check if OpenSSL libraries work as expected -AC_CACHE_CHECK([whether OpenSSL provides required APIs], [ac_cv_working_openssl], [ -save_LIBS="$LIBS" -save_CFLAGS="$CFLAGS" -save_LDFLAGS="$LDFLAGS" -LIBS="$LIBS $OPENSSL_LIBS" -CFLAGS="$CFLAGS_NODIST $OPENSSL_INCLUDES" -LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS" +WITH_SAVE_ENV([ + LIBS="$LIBS $OPENSSL_LIBS" + CFLAGS="$CFLAGS $OPENSSL_INCLUDES" + LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH" -AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -#include -#include -#include + AC_CACHE_CHECK([whether OpenSSL provides required ssl module APIs], [ac_cv_working_openssl_ssl], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([ + #include + #include + #if OPENSSL_VERSION_NUMBER < 0x10101000L + #error "OpenSSL >= 1.1.1 is required" + #endif + static void keylog_cb(const SSL *ssl, const char *line) {} + ], [ + SSL_CTX *ctx = SSL_CTX_new(TLS_client_method()); + SSL_CTX_set_keylog_callback(ctx, keylog_cb); + SSL *ssl = SSL_new(ctx); + X509_VERIFY_PARAM *param = SSL_get0_param(ssl); + X509_VERIFY_PARAM_set1_host(param, "python.org", 0); + SSL_free(ssl); + SSL_CTX_free(ctx); + ])], [ac_cv_working_openssl_ssl=yes], [ac_cv_working_openssl_ssl=no]) + ]) +]) -#if OPENSSL_VERSION_NUMBER < 0x10101000L -#error "OpenSSL >= 1.1.1 is required" -#endif +WITH_SAVE_ENV([ + LIBS="$LIBS $LIBCRYPTO_LIBS" + CFLAGS="$CFLAGS $OPENSSL_INCLUDES" + LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH" -static void keylog_cb(const SSL *ssl, const char *line) {} -]], [[ -/* SSL APIs */ -SSL_CTX *ctx = SSL_CTX_new(TLS_client_method()); -SSL_CTX_set_keylog_callback(ctx, keylog_cb); -SSL *ssl = SSL_new(ctx); -X509_VERIFY_PARAM *param = SSL_get0_param(ssl); -X509_VERIFY_PARAM_set1_host(param, "python.org", 0); -SSL_free(ssl); -SSL_CTX_free(ctx); - -/* hashlib APIs */ -OBJ_nid2sn(NID_md5); -OBJ_nid2sn(NID_sha1); -OBJ_nid2sn(NID_sha3_512); -OBJ_nid2sn(NID_blake2b512); -EVP_PBE_scrypt(NULL, 0, NULL, 0, 2, 8, 1, 0, NULL, 0); -]])], - [ac_cv_working_openssl=yes], - [ac_cv_working_openssl=no]) -LIBS="$save_LIBS" -CFLAGS="$save_CFLAGS" -LDFLAGS="$save_LDFLAGS" + AC_CACHE_CHECK([whether OpenSSL provides required hashlib module APIs], [ac_cv_working_openssl_hashlib], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([ + #include + #include + #if OPENSSL_VERSION_NUMBER < 0x10101000L + #error "OpenSSL >= 1.1.1 is required" + #endif + ], [ + OBJ_nid2sn(NID_md5); + OBJ_nid2sn(NID_sha1); + OBJ_nid2sn(NID_sha3_512); + OBJ_nid2sn(NID_blake2b512); + EVP_PBE_scrypt(NULL, 0, NULL, 0, 2, 8, 1, 0, NULL, 0); + ])], [ac_cv_working_openssl_hashlib=yes], [ac_cv_working_openssl_hashlib=no]) + ]) ]) # ssl module default cipher suite string @@ -5945,77 +6960,104 @@ for builtin_hash in $with_builtin_hashlib_hashes; do done IFS=$as_save_IFS -# --with-experimental-isolated-subinterpreters -AH_TEMPLATE(EXPERIMENTAL_ISOLATED_SUBINTERPRETERS, - [Better isolate subinterpreters, experimental build mode.]) -AC_MSG_CHECKING(for --with-experimental-isolated-subinterpreters) -AC_ARG_WITH(experimental-isolated-subinterpreters, - AS_HELP_STRING([--with-experimental-isolated-subinterpreters], - [better isolate subinterpreters, experimental build mode (default is no)]), -[ -if test "$withval" != no -then - AC_MSG_RESULT(yes); - AC_DEFINE(EXPERIMENTAL_ISOLATED_SUBINTERPRETERS) -else - AC_MSG_RESULT(no); -fi], -[AC_MSG_RESULT(no)]) - -# --with-static-libpython -STATIC_LIBPYTHON=1 -AC_MSG_CHECKING(for --with-static-libpython) -AC_ARG_WITH(static-libpython, - AS_HELP_STRING([--without-static-libpython], - [do not build libpythonMAJOR.MINOR.a and do not install python.o (default is yes)]), -[ -if test "$withval" = no -then - AC_MSG_RESULT(no); - STATIC_LIBPYTHON=0 -else - AC_MSG_RESULT(yes); -fi], -[AC_MSG_RESULT(yes)]) -LIBRARY_DEPS='$(PY3LIBRARY) $(EXPORTSYMS)' -if test "$PY_ENABLE_SHARED" = 1 || test "$enable_framework" ; then - LIBRARY_DEPS="\$(LDLIBRARY) $LIBRARY_DEPS" - if test "$STATIC_LIBPYTHON" = 1; then - LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS" - fi -else - LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS" -fi -AC_SUBST(STATIC_LIBPYTHON) -AC_SUBST(LIBRARY_DEPS) +dnl libb2 for blake2. _blake2 module falls back to vendored copy. +AS_VAR_IF([with_builtin_blake2], [yes], [ + PKG_CHECK_MODULES([LIBB2], [libb2], [ + have_libb2=yes + AC_DEFINE([HAVE_LIBB2], [1], + [Define to 1 if you want to build _blake2 module with libb2]) + ], [have_libb2=no]) +]) # Check whether to disable test modules. Once set, setup.py will not build # test extension modules and "make install" will not install test suites. -AC_MSG_CHECKING(for --disable-test-modules) -AC_ARG_ENABLE(test-modules, - AS_HELP_STRING([--disable-test-modules], [don't build nor install test modules])) -if test "$enable_test_modules" = no; then - TEST_MODULES=no - AC_MSG_RESULT(yes) -else - TEST_MODULES=yes - AC_MSG_RESULT(no) -fi -AC_SUBST(TEST_MODULES) +AC_MSG_CHECKING([for --disable-test-modules]) +AC_ARG_ENABLE([test-modules], + [AS_HELP_STRING([--disable-test-modules], [don't build nor install test modules])], [ + AS_VAR_IF([enable_test_modules], [yes], [TEST_MODULES=yes], [TEST_MODULES=no]) +], [ + AS_CASE([$ac_sys_system/$ac_sys_emscripten_target], + [Emscripten/browser*], [TEST_MODULES=no], + [TEST_MODULES=yes] + ) +]) +AC_MSG_RESULT([$TEST_MODULES]) +AC_SUBST([TEST_MODULES]) +AC_DEFUN([PY_STDLIB_MOD_SET_NA], [ + m4_foreach([mod], [$@], [ + AS_VAR_SET([py_cv_module_]mod, [n/a])]) +]) + +# stdlib not available dnl Modules that are not available on some platforms dnl AIX has shadow passwords, but access is not via getspent() dnl VxWorks does not provide crypt() function AS_CASE([$ac_sys_system], - [AIX], [py_stdlib_not_available="_scproxy spwd"], - [VxWorks*], [py_stdlib_not_available="_scproxy _crypt termios grp"], - [Darwin], [py_stdlib_not_available="ossaudiodev spwd"], - [CYGWIN*], [py_stdlib_not_available="_scproxy nis"], - [QNX*], [py_stdlib_not_available="_scproxy nis"], - [FreeBSD*], [py_stdlib_not_available="_scproxy spwd"], - [py_stdlib_not_available="_scproxy"] + [AIX], [PY_STDLIB_MOD_SET_NA([_scproxy], [spwd])], + [VxWorks*], [PY_STDLIB_MOD_SET_NA([_scproxy], [_crypt], [termios], [grp])], + [Darwin], [PY_STDLIB_MOD_SET_NA([ossaudiodev], [spwd])], + [CYGWIN*], [PY_STDLIB_MOD_SET_NA([_scproxy], [nis])], + [QNX*], [PY_STDLIB_MOD_SET_NA([_scproxy], [nis])], + [FreeBSD*], [PY_STDLIB_MOD_SET_NA([_scproxy], [spwd])], + [Emscripten|WASI], [ + dnl subprocess and multiprocessing are not supported (no fork syscall). + dnl curses and tkinter user interface are not available. + dnl dbm and gdbm aren't available, too. + dnl Emscripten and WASI provide only stubs for pwd, grp APIs. + dnl resource functions (get/setrusage) are stubs, too. + PY_STDLIB_MOD_SET_NA( + [_curses], + [_curses_panel], + [_dbm], + [_gdbm], + [_multiprocessing], + [_posixshmem], + [_posixsubprocess], + [_scproxy], + [_tkinter], + [_xxsubinterpreters], + [grp], + [nis], + [ossaudiodev], + [pwd], + [resource], + [spwd], + [syslog], + ) + AS_CASE([$ac_sys_system/$ac_sys_emscripten_target], + [Emscripten/browser*], [ + dnl These modules are not particularly useful in browsers. + PY_STDLIB_MOD_SET_NA( + [fcntl], + [readline], + [termios], + ) + ], + [Emscripten/node*], [], + [WASI/*], [ + dnl WASI SDK 15.0 does not support file locking, mmap, and more. + PY_STDLIB_MOD_SET_NA( + [_ctypes_test], + [fcntl], + [mmap], + [termios], + ) + ] + ) + ], + [PY_STDLIB_MOD_SET_NA([_scproxy])] ) +dnl AC_MSG_NOTICE([m4_set_list([_PY_STDLIB_MOD_SET_NA])]) + +dnl Default value for Modules/Setup.stdlib build type +AS_CASE([$host_cpu], + [wasm32|wasm64], [MODULE_BUILDTYPE=static], + [MODULE_BUILDTYPE=${MODULE_BUILDTYPE:-shared}] +) +AC_SUBST([MODULE_BUILDTYPE]) + dnl _MODULE_BLOCK_ADD([VAR], [VALUE]) dnl internal: adds $1=quote($2) to MODULE_BLOCK AC_DEFUN([_MODULE_BLOCK_ADD], [AS_VAR_APPEND([MODULE_BLOCK], ["$1=_AS_QUOTE([$2])$as_nl"])]) @@ -6023,10 +7065,10 @@ MODULE_BLOCK= dnl Check for stdlib extension modules dnl PY_STDLIB_MOD([NAME], [ENABLED-TEST], [SUPPORTED-TEST], [CFLAGS], [LDFLAGS]) -dnl sets MODULE_$NAME based on $py_stdlib_not_available, ENABLED-TEST, +dnl sets MODULE_$NAME_STATE based on PY_STDLIB_MOD_SET_NA(), ENABLED-TEST, dnl and SUPPORTED_TEST. ENABLED-TEST and SUPPORTED-TEST default to true if dnl empty. -dnl n/a: $NAME in $py_stdlib_not_available (not available on platform) +dnl n/a: marked unavailable on platform by PY_STDLIB_MOD_SET_NA() dnl yes: enabled and supported dnl missing: enabled and not supported dnl disabled: not enabled @@ -6035,16 +7077,13 @@ AC_DEFUN([PY_STDLIB_MOD], [ AC_MSG_CHECKING([for stdlib extension module $1]) m4_pushdef([modcond], [MODULE_]m4_toupper([$1]))dnl m4_pushdef([modstate], [py_cv_module_$1])dnl - AS_CASE([$py_stdlib_not_available], - [*$1*], [modstate=n/a], - [ - AS_IF(m4_ifblank([$2], [true], [$2]), - [AS_IF([m4_ifblank([$3], [true], [$3])], [modstate=yes], [modstate=missing])], - [modstate=disabled] - ) - ] - ) - _MODULE_BLOCK_ADD(modcond, [$modstate]) + dnl Check if module has been disabled by PY_STDLIB_MOD_SET_NA() + AS_IF([test "$modstate" != "n/a"], [ + AS_IF(m4_ifblank([$2], [true], [$2]), + [AS_IF([m4_ifblank([$3], [true], [$3])], [modstate=yes], [modstate=missing])], + [modstate=disabled]) + ]) + _MODULE_BLOCK_ADD(modcond[_STATE], [$modstate]) AS_VAR_IF([modstate], [yes], [ m4_ifblank([$4], [], [_MODULE_BLOCK_ADD([MODULE_]m4_toupper([$1])[_CFLAGS], [$4])]) m4_ifblank([$5], [], [_MODULE_BLOCK_ADD([MODULE_]m4_toupper([$1])[_LDFLAGS], [$5])]) @@ -6055,19 +7094,23 @@ AC_DEFUN([PY_STDLIB_MOD], [ m4_popdef([modstate])dnl ]) -dnl Define simple, always enabled stdlib extension module +dnl Define simple stdlib extension module +dnl Always enable unless the module is disabled by PY_STDLIB_MOD_SET_NA dnl PY_STDLIB_MOD_SIMPLE([NAME], [CFLAGS], [LDFLAGS]) dnl cflags and ldflags are optional AC_DEFUN([PY_STDLIB_MOD_SIMPLE], [ m4_pushdef([modcond], [MODULE_]m4_toupper([$1]))dnl - AM_CONDITIONAL(modcond, [true]) - m4_ifval([$2], [ - _MODULE_BLOCK_ADD([MODULE_]m4_toupper([$1])[_CFLAGS], [$2]) - ]) - m4_ifval([$3], [ - _MODULE_BLOCK_ADD([MODULE_]m4_toupper([$1])[_LDFLAGS], [$3]) + m4_pushdef([modstate], [py_cv_module_$1])dnl + dnl Check if module has been disabled by PY_STDLIB_MOD_SET_NA() + AS_IF([test "$modstate" != "n/a"], [modstate=yes]) + AM_CONDITIONAL(modcond, [test "$modstate" = yes]) + _MODULE_BLOCK_ADD(modcond[_STATE], [$modstate]) + AS_VAR_IF([modstate], [yes], [ + m4_ifblank([$2], [], [_MODULE_BLOCK_ADD([MODULE_]m4_toupper([$1])[_CFLAGS], [$2])]) + m4_ifblank([$3], [], [_MODULE_BLOCK_ADD([MODULE_]m4_toupper([$1])[_LDFLAGS], [$3])]) ]) m4_popdef([modcond])dnl + m4_popdef([modstate])dnl ]) dnl static modules in Modules/Setup.bootstrap @@ -6079,17 +7122,31 @@ PY_STDLIB_MOD_SIMPLE([array]) PY_STDLIB_MOD_SIMPLE([_asyncio]) PY_STDLIB_MOD_SIMPLE([_bisect]) PY_STDLIB_MOD_SIMPLE([_contextvars]) +PY_STDLIB_MOD_SIMPLE([_csv]) PY_STDLIB_MOD_SIMPLE([_heapq]) PY_STDLIB_MOD_SIMPLE([_json]) PY_STDLIB_MOD_SIMPLE([_lsprof]) PY_STDLIB_MOD_SIMPLE([_opcode]) PY_STDLIB_MOD_SIMPLE([_pickle]) +PY_STDLIB_MOD_SIMPLE([_posixsubprocess]) PY_STDLIB_MOD_SIMPLE([_queue]) PY_STDLIB_MOD_SIMPLE([_random]) +PY_STDLIB_MOD_SIMPLE([select]) +PY_STDLIB_MOD_SIMPLE([_struct]) PY_STDLIB_MOD_SIMPLE([_typing]) +PY_STDLIB_MOD_SIMPLE([_xxsubinterpreters]) PY_STDLIB_MOD_SIMPLE([_zoneinfo]) +dnl multiprocessing modules +PY_STDLIB_MOD([_multiprocessing], + [], [test "$ac_cv_func_sem_unlink" = "yes"], + [-I\$(srcdir)/Modules/_multiprocessing]) +PY_STDLIB_MOD([_posixshmem], + [], [test "$have_posix_shmem" = "yes"], + [$POSIXSHMEM_CFLAGS], [$POSIXSHMEM_LIBS]) + dnl needs libm +PY_STDLIB_MOD_SIMPLE([audioop], [], [$LIBM]) PY_STDLIB_MOD_SIMPLE([_statistics], [], [$LIBM]) PY_STDLIB_MOD_SIMPLE([cmath], [], [$LIBM]) PY_STDLIB_MOD_SIMPLE([math], [], [$LIBM]) @@ -6097,10 +7154,23 @@ PY_STDLIB_MOD_SIMPLE([math], [], [$LIBM]) dnl needs libm and on some platforms librt PY_STDLIB_MOD_SIMPLE([_datetime], [], [$TIMEMODULE_LIB $LIBM]) +dnl modules with some unix dependencies +PY_STDLIB_MOD([fcntl], + [], [test "$ac_cv_header_sys_ioctl_h" = "yes" -a "$ac_cv_header_fcntl_h" = "yes"], + [], [$FCNTL_LIBS]) +PY_STDLIB_MOD([mmap], + [], [test "$ac_cv_header_sys_mman_h" = "yes" -a "$ac_cv_header_sys_stat_h" = "yes"]) +PY_STDLIB_MOD([_socket], + [], m4_flatten([test "$ac_cv_header_sys_socket_h" = "yes" + -a "$ac_cv_header_sys_types_h" = "yes" + -a "$ac_cv_header_netinet_in_h" = "yes"])) + dnl platform specific extensions PY_STDLIB_MOD([grp], [], [test "$ac_cv_func_getgrgid" = yes -o "$ac_cv_func_getgrgid_r" = yes]) PY_STDLIB_MOD([ossaudiodev], - [], [test "$ac_cv_header_linux_soundcard_h" = yes -o "$ac_cv_header_sys_soundcard_h" = yes]) + [], [test "$ac_cv_header_linux_soundcard_h" = yes -o "$ac_cv_header_sys_soundcard_h" = yes], + [], [$OSSAUDIODEV_LIBS]) +PY_STDLIB_MOD([pwd], [], [test "$ac_cv_func_getpwuid" = yes -o "$ac_cv_func_getpwuid_r" = yes]) PY_STDLIB_MOD([resource], [], [test "$ac_cv_header_sys_resource_h" = yes]) PY_STDLIB_MOD([_scproxy], [test "$ac_sys_system" = "Darwin"], [], @@ -6128,54 +7198,122 @@ PY_STDLIB_MOD([_sha1], [test "$with_builtin_sha1" = yes]) PY_STDLIB_MOD([_sha256], [test "$with_builtin_sha256" = yes]) PY_STDLIB_MOD([_sha512], [test "$with_builtin_sha512" = yes]) PY_STDLIB_MOD([_sha3], [test "$with_builtin_sha3" = yes]) -PY_STDLIB_MOD([_blake2], [test "$with_builtin_blake2" = yes]) +PY_STDLIB_MOD([_blake2], + [test "$with_builtin_blake2" = yes], [], + [$LIBB2_CFLAGS], [$LIBB2_LIBS]) +PY_STDLIB_MOD([_crypt], + [], [test "$ac_cv_crypt_crypt" = yes], + [$LIBCRYPT_CFLAGS], [$LIBCRYPT_LIBS]) +PY_STDLIB_MOD([_ctypes], + [], [test "$have_libffi" = yes], + [$LIBFFI_CFLAGS], [$LIBFFI_LIBS]) +PY_STDLIB_MOD([_curses], + [], [test "$have_curses" != "no"], + [$CURSES_CFLAGS], [$CURSES_LIBS] +) +PY_STDLIB_MOD([_curses_panel], + [], [test "$have_panel" != "no"], + [$PANEL_CFLAGS $CURSES_CFLAGS], [$PANEL_LIBS $CURSES_LIBS] +) PY_STDLIB_MOD([_decimal], [], [], [$LIBMPDEC_CFLAGS], [$LIBMPDEC_LDFLAGS]) +PY_STDLIB_MOD([_dbm], + [test -n "$with_dbmliborder"], [test "$have_dbm" != "no"], + [$DBM_CFLAGS], [$DBM_LIBS]) +PY_STDLIB_MOD([_gdbm], + [test "$have_gdbm_dbmliborder" = yes], [test "$have_gdbm" = yes], + [$GDBM_CFLAGS], [$GDBM_LIBS]) +PY_STDLIB_MOD([nis], + [], [test "$have_nis" = yes -a "$ac_cv_header_rpc_rpc_h" = yes], + [$LIBNSL_CFLAGS], [$LIBNSL_LIBS]) + PY_STDLIB_MOD([readline], + [], [test "$with_readline" != "no"], + [$READLINE_CFLAGS], [$READLINE_LIBS]) PY_STDLIB_MOD([_sqlite3], [test "$have_sqlite3" = "yes"], [test "$have_supported_sqlite3" = "yes"], [$LIBSQLITE3_CFLAGS], [$LIBSQLITE3_LIBS]) +PY_STDLIB_MOD([_tkinter], + [], [test "$have_tcltk" = "yes"], + [$TCLTK_CFLAGS], [$TCLTK_LIBS]) +PY_STDLIB_MOD([_uuid], + [], [test "$have_uuid" = "yes"], + [$LIBUUID_CFLAGS], [$LIBUUID_LIBS]) + +dnl compression libs +PY_STDLIB_MOD([zlib], [], [test "$have_zlib" = yes], + [$ZLIB_CFLAGS], [$ZLIB_LIBS]) +dnl binascii can use zlib for optimized crc32. +PY_STDLIB_MOD_SIMPLE([binascii], [$BINASCII_CFLAGS], [$BINASCII_LIBS]) +PY_STDLIB_MOD([_bz2], [], [test "$have_bzip2" = yes], + [$BZIP2_CFLAGS], [$BZIP2_LIBS]) +PY_STDLIB_MOD([_lzma], [], [test "$have_liblzma" = yes], + [$LIBLZMA_CFLAGS], [$LIBLZMA_LIBS]) + +dnl OpenSSL bindings +PY_STDLIB_MOD([_ssl], [], [test "$ac_cv_working_openssl_ssl" = yes], + [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $OPENSSL_LIBS]) +PY_STDLIB_MOD([_hashlib], [], [test "$ac_cv_working_openssl_hashlib" = yes], + [$OPENSSL_INCLUDES], [$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS]) dnl test modules PY_STDLIB_MOD([_testcapi], [test "$TEST_MODULES" = yes]) +PY_STDLIB_MOD([_testclinic], [test "$TEST_MODULES" = yes]) PY_STDLIB_MOD([_testinternalcapi], [test "$TEST_MODULES" = yes]) PY_STDLIB_MOD([_testbuffer], [test "$TEST_MODULES" = yes]) -PY_STDLIB_MOD([_testimportmultiple], [test "$TEST_MODULES" = yes]) -PY_STDLIB_MOD([_testmultiphase], [test "$TEST_MODULES" = yes]) +PY_STDLIB_MOD([_testimportmultiple], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes]) +PY_STDLIB_MOD([_testmultiphase], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes]) +PY_STDLIB_MOD([xxsubtype], [test "$TEST_MODULES" = yes]) PY_STDLIB_MOD([_xxtestfuzz], [test "$TEST_MODULES" = yes]) -PY_STDLIB_MOD([_ctypes_test], [test "$TEST_MODULES" = yes], [], [], [-lm]) +PY_STDLIB_MOD([_ctypes_test], + [test "$TEST_MODULES" = yes], [test "$have_libffi" = yes -a "$ac_cv_func_dlopen" = yes], + [], [$LIBM]) + +dnl Limited API template modules. +dnl The limited C API is not compatible with the Py_TRACE_REFS macro. +dnl Emscripten does not support shared libraries yet. +PY_STDLIB_MOD([xxlimited], [test "$with_trace_refs" = "no"], [test "$ac_cv_func_dlopen" = yes]) +PY_STDLIB_MOD([xxlimited_35], [test "$with_trace_refs" = "no"], [test "$ac_cv_func_dlopen" = yes]) # substitute multiline block, must come after last PY_STDLIB_MOD() AC_SUBST([MODULE_BLOCK]) # generate output files AC_CONFIG_FILES(Makefile.pre Misc/python.pc Misc/python-embed.pc Misc/python-config.sh) -AC_CONFIG_FILES([Modules/Setup.stdlib]) +AC_CONFIG_FILES([Modules/Setup.bootstrap Modules/Setup.stdlib]) AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix]) AC_OUTPUT -echo "creating Modules/Setup.local" >&AS_MESSAGE_FD +AC_MSG_NOTICE([creating Modules/Setup.local]) if test ! -f Modules/Setup.local then echo "# Edit this file for local setup changes" >Modules/Setup.local fi -echo "creating Makefile" >&AS_MESSAGE_FD +AC_MSG_NOTICE([creating Makefile]) $SHELL $srcdir/Modules/makesetup -c $srcdir/Modules/config.c.in \ -s Modules \ - Modules/Setup.local $srcdir/Modules/Setup.bootstrap $srcdir/Modules/Setup + Modules/Setup.local Modules/Setup.stdlib Modules/Setup.bootstrap $srcdir/Modules/Setup +if test $? -ne 0; then + AC_MSG_ERROR([makesetup failed]) +fi + mv config.c Modules if test -z "$PKG_CONFIG"; then - echo "" >&AS_MESSAGE_FD - echo "pkg-config is missing. Some dependencies may not be detected correctly." >&AS_MESSAGE_FD + AC_MSG_WARN([pkg-config is missing. Some dependencies may not be detected correctly.]) fi if test "$Py_OPT" = 'false' -a "$Py_DEBUG" != 'true'; then - echo "" >&AS_MESSAGE_FD - echo "" >&AS_MESSAGE_FD - echo "If you want a release build with all stable optimizations active (PGO, etc)," >&AS_MESSAGE_FD - echo "please run ./configure --enable-optimizations" >&AS_MESSAGE_FD - echo "" >&AS_MESSAGE_FD - echo "" >&AS_MESSAGE_FD + AC_MSG_NOTICE([ + +If you want a release build with all stable optimizations active (PGO, etc), +please run ./configure --enable-optimizations +]) fi + +AS_VAR_IF([PY_SUPPORT_TIER], [0], [AC_MSG_WARN([ + +Platform "$host" with compiler "$ac_cv_cc_name" is not supported by the +CPython core team, see https://peps.python.org/pep-0011/ for more information. +])]) diff --git a/netlify.toml b/netlify.toml index 387c8f954ad..f5790fc5fec 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,4 +1,11 @@ [build] base = "Doc/" command = "make html" - publish = "Doc/build/html" \ No newline at end of file + publish = "build/html" + # Do not trigger netlify builds if docs were not changed. + # Changed files should be in sync with `.github/workflows/doc.yml` + ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF . ../netlify.toml" + +[build.environment] + PYTHON_VERSION = "3.8" + IS_DEPLOYMENT_PREVIEW = "true" diff --git a/pyconfig.h.in b/pyconfig.h.in index afd3ebe35bc..236cee6588d 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -44,19 +44,16 @@ /* Define if --enable-ipv6 is specified */ #undef ENABLE_IPV6 -/* Better isolate subinterpreters, experimental build mode. */ -#undef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS - /* Define to 1 if your system stores words within floats with the most significant word first */ #undef FLOAT_WORDS_BIGENDIAN -/* Define if flock needs to be linked with bsd library. */ -#undef FLOCK_NEEDS_LIBBSD - /* Define if getpgrp() must be called as getpgrp(0). */ #undef GETPGRP_HAVE_ARG +/* Define if you have the 'accept' function. */ +#undef HAVE_ACCEPT + /* Define to 1 if you have the `accept4' function. */ #undef HAVE_ACCEPT4 @@ -87,6 +84,9 @@ /* Define to 1 if you have the `atanh' function. */ #undef HAVE_ATANH +/* Define if you have the 'bind' function. */ +#undef HAVE_BIND + /* Define to 1 if you have the `bind_textdomain_codeset' function. */ #undef HAVE_BIND_TEXTDOMAIN_CODESET @@ -130,6 +130,9 @@ /* Define to 1 if you have the 'chflags' function. */ #undef HAVE_CHFLAGS +/* Define to 1 if you have the `chmod' function. */ +#undef HAVE_CHMOD + /* Define to 1 if you have the `chown' function. */ #undef HAVE_CHOWN @@ -163,6 +166,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_CONIO_H +/* Define if you have the 'connect' function. */ +#undef HAVE_CONNECT + /* Define to 1 if you have the `copy_file_range' function. */ #undef HAVE_COPY_FILE_RANGE @@ -281,6 +287,9 @@ /* Define to 1 if you have the `dlopen' function. */ #undef HAVE_DLOPEN +/* Define to 1 if you have the `dup' function. */ +#undef HAVE_DUP + /* Define to 1 if you have the `dup2' function. */ #undef HAVE_DUP2 @@ -293,10 +302,13 @@ /* Defined when any dynamic module loading is enabled. */ #undef HAVE_DYNAMIC_LOADING +/* Define to 1 if you have the header file. */ +#undef HAVE_EDITLINE_READLINE_H + /* Define to 1 if you have the header file. */ #undef HAVE_ENDIAN_H -/* Define if you have the 'epoll' function. */ +/* Define if you have the 'epoll_create' function. */ #undef HAVE_EPOLL /* Define if you have the 'epoll_create1' function. */ @@ -359,12 +371,24 @@ /* Define to 1 if you have the `fexecve' function. */ #undef HAVE_FEXECVE +/* Define if you have the 'ffi_closure_alloc' function. */ +#undef HAVE_FFI_CLOSURE_ALLOC + +/* Define if you have the 'ffi_prep_cif_var' function. */ +#undef HAVE_FFI_PREP_CIF_VAR + +/* Define if you have the 'ffi_prep_closure_loc' function. */ +#undef HAVE_FFI_PREP_CLOSURE_LOC + /* Define to 1 if you have the `flock' function. */ #undef HAVE_FLOCK /* Define to 1 if you have the `fork' function. */ #undef HAVE_FORK +/* Define to 1 if you have the `fork1' function. */ +#undef HAVE_FORK1 + /* Define to 1 if you have the `forkpty' function. */ #undef HAVE_FORKPTY @@ -438,9 +462,18 @@ /* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */ #undef HAVE_GETC_UNLOCKED +/* Define to 1 if you have the `getegid' function. */ +#undef HAVE_GETEGID + /* Define to 1 if you have the `getentropy' function. */ #undef HAVE_GETENTROPY +/* Define to 1 if you have the `geteuid' function. */ +#undef HAVE_GETEUID + +/* Define to 1 if you have the `getgid' function. */ +#undef HAVE_GETGID + /* Define to 1 if you have the `getgrgid' function. */ #undef HAVE_GETGRGID @@ -456,6 +489,9 @@ /* Define to 1 if you have the `getgroups' function. */ #undef HAVE_GETGROUPS +/* Define if you have the 'gethostbyaddr' function. */ +#undef HAVE_GETHOSTBYADDR + /* Define to 1 if you have the `gethostbyname' function. */ #undef HAVE_GETHOSTBYNAME @@ -471,6 +507,9 @@ /* Define this if you have the 6-arg version of gethostbyname_r(). */ #undef HAVE_GETHOSTBYNAME_R_6_ARG +/* Define to 1 if you have the `gethostname' function. */ +#undef HAVE_GETHOSTNAME + /* Define to 1 if you have the `getitimer' function. */ #undef HAVE_GETITIMER @@ -486,7 +525,7 @@ /* Define if you have the 'getpagesize' function. */ #undef HAVE_GETPAGESIZE -/* Define to 1 if you have the `getpeername' function. */ +/* Define if you have the 'getpeername' function. */ #undef HAVE_GETPEERNAME /* Define to 1 if you have the `getpgid' function. */ @@ -498,15 +537,24 @@ /* Define to 1 if you have the `getpid' function. */ #undef HAVE_GETPID +/* Define to 1 if you have the `getppid' function. */ +#undef HAVE_GETPPID + /* Define to 1 if you have the `getpriority' function. */ #undef HAVE_GETPRIORITY +/* Define if you have the 'getprotobyname' function. */ +#undef HAVE_GETPROTOBYNAME + /* Define to 1 if you have the `getpwent' function. */ #undef HAVE_GETPWENT /* Define to 1 if you have the `getpwnam_r' function. */ #undef HAVE_GETPWNAM_R +/* Define to 1 if you have the `getpwuid' function. */ +#undef HAVE_GETPWUID + /* Define to 1 if you have the `getpwuid_r' function. */ #undef HAVE_GETPWUID_R @@ -522,15 +570,30 @@ /* Define to 1 if you have the `getresuid' function. */ #undef HAVE_GETRESUID +/* Define to 1 if you have the `getrusage' function. */ +#undef HAVE_GETRUSAGE + +/* Define if you have the 'getservbyname' function. */ +#undef HAVE_GETSERVBYNAME + +/* Define if you have the 'getservbyport' function. */ +#undef HAVE_GETSERVBYPORT + /* Define to 1 if you have the `getsid' function. */ #undef HAVE_GETSID +/* Define if you have the 'getsockname' function. */ +#undef HAVE_GETSOCKNAME + /* Define to 1 if you have the `getspent' function. */ #undef HAVE_GETSPENT /* Define to 1 if you have the `getspnam' function. */ #undef HAVE_GETSPNAM +/* Define to 1 if you have the `getuid' function. */ +#undef HAVE_GETUID + /* Define to 1 if you have the `getwd' function. */ #undef HAVE_GETWD @@ -556,6 +619,9 @@ /* Define if you have the 'inet_aton' function. */ #undef HAVE_INET_ATON +/* Define if you have the 'inet_ntoa' function. */ +#undef HAVE_INET_NTOA + /* Define if you have the 'inet_pton' function. */ #undef HAVE_INET_PTON @@ -598,8 +664,8 @@ /* Define to 1 if you have the `lchown' function. */ #undef HAVE_LCHOWN -/* Define to 1 if you have the `bz2' library (-lbz2). */ -#undef HAVE_LIBBZ2 +/* Define to 1 if you want to build _blake2 module with libb2 */ +#undef HAVE_LIBB2 /* Define to 1 if you have the `db' library (-ldb). */ #undef HAVE_LIBDB @@ -610,48 +676,33 @@ /* Define to 1 if you have the `dld' library (-ldld). */ #undef HAVE_LIBDLD -/* Define to 1 if you have the `gdbm' library (-lgdbm). */ -#undef HAVE_LIBGDBM - -/* Define to 1 if you have the `gdbm_compat' library (-lgdbm_compat). */ -#undef HAVE_LIBGDBM_COMPAT - /* Define to 1 if you have the `ieee' library (-lieee). */ #undef HAVE_LIBIEEE /* Define to 1 if you have the header file. */ #undef HAVE_LIBINTL_H -/* Define to 1 if you have the `lzma' library (-llzma). */ -#undef HAVE_LIBLZMA - -/* Define to 1 if you have the `ndbm' library (-lndbm). */ -#undef HAVE_LIBNDBM - -/* Define to build the readline module. */ -#undef HAVE_LIBREADLINE - /* Define to 1 if you have the `resolv' library (-lresolv). */ #undef HAVE_LIBRESOLV /* Define to 1 if you have the `sendfile' library (-lsendfile). */ #undef HAVE_LIBSENDFILE +/* Define to 1 if you have the `sqlite3' library (-lsqlite3). */ +#undef HAVE_LIBSQLITE3 + /* Define to 1 if you have the header file. */ #undef HAVE_LIBUTIL_H -/* Define to 1 if you have the `uuid' library (-luuid). */ -#undef HAVE_LIBUUID - -/* Define to 1 if you have the `z' library (-lz). */ -#undef HAVE_LIBZ - /* Define if you have the 'link' function. */ #undef HAVE_LINK /* Define to 1 if you have the `linkat' function. */ #undef HAVE_LINKAT +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_AUXVEC_H + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_CAN_BCM_H @@ -670,6 +721,9 @@ /* Define if compiling using Linux 4.1 or later. */ #undef HAVE_LINUX_CAN_RAW_JOIN_FILTERS +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_FS_H + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_MEMFD_H @@ -694,6 +748,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_WAIT_H +/* Define if you have the 'listen' function. */ +#undef HAVE_LISTEN + /* Define to 1 if you have the `lockf' function. */ #undef HAVE_LOCKF @@ -703,6 +760,9 @@ /* Define to 1 if you have the `log2' function. */ #undef HAVE_LOG2 +/* Define to 1 if you have the `login_tty' function. */ +#undef HAVE_LOGIN_TTY + /* Define to 1 if the system has the type `long double'. */ #undef HAVE_LONG_DOUBLE @@ -760,6 +820,9 @@ /* Define to 1 if you have the `nanosleep' function. */ #undef HAVE_NANOSLEEP +/* Define to 1 if you have the `ncursesw' library. */ +#undef HAVE_NCURSESW + /* Define to 1 if you have the header file. */ #undef HAVE_NCURSES_H @@ -769,9 +832,21 @@ /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_NDIR_H +/* Define to 1 if you have the header file. */ +#undef HAVE_NETCAN_CAN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + /* Define to 1 if you have the header file. */ #undef HAVE_NETPACKET_PACKET_H +/* Define to 1 if you have the header file. */ +#undef HAVE_NET_ETHERNET_H + /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_H @@ -785,15 +860,24 @@ /* Define to 1 if you have the `openat' function. */ #undef HAVE_OPENAT +/* Define to 1 if you have the `opendir' function. */ +#undef HAVE_OPENDIR + /* Define to 1 if you have the `openpty' function. */ #undef HAVE_OPENPTY +/* Define to 1 if you have the header file. */ +#undef HAVE_PANEL_H + /* Define to 1 if you have the `pathconf' function. */ #undef HAVE_PATHCONF /* Define to 1 if you have the `pause' function. */ #undef HAVE_PAUSE +/* Define to 1 if you have the `pipe' function. */ +#undef HAVE_PIPE + /* Define to 1 if you have the `pipe2' function. */ #undef HAVE_PIPE2 @@ -857,6 +941,9 @@ /* Define to 1 if you have the `pthread_sigmask' function. */ #undef HAVE_PTHREAD_SIGMASK +/* Define if platform requires stubbed pthreads support */ +#undef HAVE_PTHREAD_STUBS + /* Define to 1 if you have the header file. */ #undef HAVE_PTY_H @@ -869,6 +956,9 @@ /* Define to 1 if you have the `pwritev2' function. */ #undef HAVE_PWRITEV2 +/* Define to 1 if you have the header file. */ +#undef HAVE_READLINE_READLINE_H + /* Define to 1 if you have the `readlink' function. */ #undef HAVE_READLINK @@ -881,6 +971,9 @@ /* Define to 1 if you have the `realpath' function. */ #undef HAVE_REALPATH +/* Define if you have the 'recvfrom' function. */ +#undef HAVE_RECVFROM + /* Define to 1 if you have the `renameat' function. */ #undef HAVE_RENAMEAT @@ -908,6 +1001,9 @@ /* Define if you have readline 4.0 */ #undef HAVE_RL_RESIZE_TERMINAL +/* Define to 1 if you have the header file. */ +#undef HAVE_RPC_RPC_H + /* Define to 1 if you have the `rtpSpawn' function. */ #undef HAVE_RTPSPAWN @@ -947,6 +1043,9 @@ /* Define to 1 if you have the `sendfile' function. */ #undef HAVE_SENDFILE +/* Define if you have the 'sendto' function. */ +#undef HAVE_SENDTO + /* Define to 1 if you have the `setegid' function. */ #undef HAVE_SETEGID @@ -965,9 +1064,15 @@ /* Define to 1 if you have the `setitimer' function. */ #undef HAVE_SETITIMER +/* Define to 1 if you have the header file. */ +#undef HAVE_SETJMP_H + /* Define to 1 if you have the `setlocale' function. */ #undef HAVE_SETLOCALE +/* Define to 1 if you have the `setns' function. */ +#undef HAVE_SETNS + /* Define to 1 if you have the `setpgid' function. */ #undef HAVE_SETPGID @@ -992,6 +1097,9 @@ /* Define to 1 if you have the `setsid' function. */ #undef HAVE_SETSID +/* Define if you have the 'setsockopt' function. */ +#undef HAVE_SETSOCKOPT + /* Define to 1 if you have the `setuid' function. */ #undef HAVE_SETUID @@ -1007,6 +1115,9 @@ /* Define to 1 if you have the `shm_unlink' function. */ #undef HAVE_SHM_UNLINK +/* Define to 1 if you have the `shutdown' function. */ +#undef HAVE_SHUTDOWN + /* Define to 1 if you have the `sigaction' function. */ #undef HAVE_SIGACTION @@ -1052,6 +1163,9 @@ /* struct sockaddr_storage (sys/socket.h) */ #undef HAVE_SOCKADDR_STORAGE +/* Define if you have the 'socket' function. */ +#undef HAVE_SOCKET + /* Define if you have the 'socketpair' function. */ #undef HAVE_SOCKETPAIR @@ -1073,10 +1187,6 @@ /* Define if you have struct stat.st_mtimensec */ #undef HAVE_STAT_TV_NSEC2 -/* Define if your compiler supports variable length function prototypes (e.g. - void fprintf(FILE *, char *, ...);) *and* */ -#undef HAVE_STDARG_PROTOTYPES - /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H @@ -1149,9 +1259,15 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYSLOG_H +/* Define to 1 if you have the `system' function. */ +#undef HAVE_SYSTEM + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_AUDIOIO_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_AUXV_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_BSDTTY_H @@ -1308,12 +1424,15 @@ /* Define to 1 if you have the `truncate' function. */ #undef HAVE_TRUNCATE +/* Define to 1 if you have the `ttyname' function. */ +#undef HAVE_TTYNAME + /* Define to 1 if you don't have `tm_zone' but do have the external array `tzname'. */ #undef HAVE_TZNAME -/* Define this if you have tcl and TCL_UTF_MAX==6 */ -#undef HAVE_UCS4_TCL +/* Define to 1 if you have the `umask' function. */ +#undef HAVE_UMASK /* Define to 1 if you have the `uname' function. */ #undef HAVE_UNAME @@ -1324,6 +1443,9 @@ /* Define to 1 if you have the `unlinkat' function. */ #undef HAVE_UNLINKAT +/* Define to 1 if you have the `unshare' function. */ +#undef HAVE_UNSHARE + /* Define if you have a useable wchar_t type defined in wchar.h; useable means wchar_t must be an unsigned type with at least 16 bits. (see Include/unicodeobject.h). */ @@ -1341,6 +1463,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UTIME_H +/* Define to 1 if you have the header file. */ +#undef HAVE_UTMP_H + /* Define to 1 if you have the `uuid_create' function. */ #undef HAVE_UUID_CREATE @@ -1359,6 +1484,9 @@ /* Define to 1 if you have the `vfork' function. */ #undef HAVE_VFORK +/* Define to 1 if you have the `wait' function. */ +#undef HAVE_WAIT + /* Define to 1 if you have the `wait3' function. */ #undef HAVE_WAIT3 @@ -1449,12 +1577,15 @@ /* Define if you want to coerce the C locale to a UTF-8 based locale */ #undef PY_COERCE_C_LOCALE -/* Define to printf format modifier for Py_ssize_t */ -#undef PY_FORMAT_SIZE_T +/* Define to 1 if you have the perf trampoline. */ +#undef PY_HAVE_PERF_TRAMPOLINE /* Define to 1 to build the sqlite module with loadable extensions support. */ #undef PY_SQLITE_ENABLE_LOAD_EXTENSION +/* Define if SQLite was compiled with the serialize API */ +#undef PY_SQLITE_HAVE_SERIALIZE + /* Default cipher suites list for ssl module. 1: Python's preferred selection, 2: leave OpenSSL defaults untouched, 0: custom string */ #undef PY_SSL_DEFAULT_CIPHERS @@ -1462,6 +1593,9 @@ /* Cipher suite string for PY_SSL_DEFAULT_CIPHERS=0 */ #undef PY_SSL_DEFAULT_CIPHER_STRING +/* PEP 11 Support tier (1, 2, 3 or 0 for unsupported) */ +#undef PY_SUPPORT_TIER + /* Define if you want to build an interpreter with many run-time checks. */ #undef Py_DEBUG @@ -1472,6 +1606,9 @@ SipHash13: 3, externally defined: 0 */ #undef Py_HASH_ALGORITHM +/* Define if you want to enable internal statistics gathering. */ +#undef Py_STATS + /* Define if you want to enable tracing references for debugging purpose */ #undef Py_TRACE_REFS @@ -1481,9 +1618,6 @@ /* Define if setpgrp() must be called as setpgrp(0, 0). */ #undef SETPGRP_HAVE_ARG -/* Define to 1 if you must link with -lrt for shm_open(). */ -#undef SHM_NEEDS_LIBRT - /* Define if i>>j for signed int i does not extend the sign bit when i < 0 */ #undef SIGNED_RIGHT_SHIFT_ZERO_FILLS @@ -1603,7 +1737,7 @@ Dyld is necessary to support frameworks. */ #undef WITH_DYLD -/* Define to build the readline module against Editline. */ +/* Define to build the readline module against libedit. */ #undef WITH_EDITLINE /* Define if you want to compile in object freelists optimization */ @@ -1680,6 +1814,15 @@ /* Define to force use of thread-safe errno, h_errno, and other functions */ #undef _REENTRANT +/* Define to 1 if you want to emulate getpid() on WASI */ +#undef _WASI_EMULATED_GETPID + +/* Define to 1 if you want to emulate process clocks on WASI */ +#undef _WASI_EMULATED_PROCESS_CLOCKS + +/* Define to 1 if you want to emulate signals on WASI */ +#undef _WASI_EMULATED_SIGNAL + /* Define to the level of X/Open that your system supports */ #undef _XOPEN_SOURCE @@ -1689,11 +1832,6 @@ /* Define on FreeBSD to activate all library features */ #undef __BSD_VISIBLE -/* Define to 1 if type `char' is unsigned and you are not using gcc. */ -#ifndef __CHAR_UNSIGNED__ -# undef __CHAR_UNSIGNED__ -#endif - /* Define to 'long' if doesn't define. */ #undef clock_t diff --git a/setup.py b/setup.py deleted file mode 100644 index 91040171a49..00000000000 --- a/setup.py +++ /dev/null @@ -1,2187 +0,0 @@ -# Autodetecting setup.py script for building the Python extensions - -import argparse -import importlib._bootstrap -import importlib.machinery -import importlib.util -import logging -import os -import re -import shlex -import sys -import sysconfig -import warnings -from glob import glob, escape -import _osx_support - - -try: - import subprocess - del subprocess - SUBPROCESS_BOOTSTRAP = False -except ImportError: - # Bootstrap Python: distutils.spawn uses subprocess to build C extensions, - # subprocess requires C extensions built by setup.py like _posixsubprocess. - # - # Use _bootsubprocess which only uses the os module. - # - # It is dropped from sys.modules as soon as all C extension modules - # are built. - import _bootsubprocess - sys.modules['subprocess'] = _bootsubprocess - del _bootsubprocess - SUBPROCESS_BOOTSTRAP = True - - -with warnings.catch_warnings(): - # bpo-41282 (PEP 632) deprecated distutils but setup.py still uses it - warnings.filterwarnings( - "ignore", - "The distutils package is deprecated", - DeprecationWarning - ) - warnings.filterwarnings( - "ignore", - "The distutils.sysconfig module is deprecated, use sysconfig instead", - DeprecationWarning - ) - - from distutils.command.build_ext import build_ext - from distutils.command.build_scripts import build_scripts - from distutils.command.install import install - from distutils.command.install_lib import install_lib - from distutils.core import Extension, setup - from distutils.errors import CCompilerError, DistutilsError - from distutils.spawn import find_executable - - -# This global variable is used to hold the list of modules to be disabled. -DISABLED_MODULE_LIST = [] - -# --list-module-names option used by Tools/scripts/generate_module_names.py -LIST_MODULE_NAMES = False - - -logging.basicConfig(format='%(message)s', level=logging.INFO) -log = logging.getLogger('setup') - - -def get_platform(): - # Cross compiling - if "_PYTHON_HOST_PLATFORM" in os.environ: - return os.environ["_PYTHON_HOST_PLATFORM"] - - # Get value of sys.platform - if sys.platform.startswith('osf1'): - return 'osf1' - return sys.platform - - -CROSS_COMPILING = ("_PYTHON_HOST_PLATFORM" in os.environ) -HOST_PLATFORM = get_platform() -MS_WINDOWS = (HOST_PLATFORM == 'win32') -CYGWIN = (HOST_PLATFORM == 'cygwin') -MACOS = (HOST_PLATFORM == 'darwin') -AIX = (HOST_PLATFORM.startswith('aix')) -VXWORKS = ('vxworks' in HOST_PLATFORM) - - -SUMMARY = """ -Python is an interpreted, interactive, object-oriented programming -language. It is often compared to Tcl, Perl, Scheme or Java. - -Python combines remarkable power with very clear syntax. It has -modules, classes, exceptions, very high level dynamic data types, and -dynamic typing. There are interfaces to many system calls and -libraries, as well as to various windowing systems (X11, Motif, Tk, -Mac, MFC). New built-in modules are easily written in C or C++. Python -is also usable as an extension language for applications that need a -programmable interface. - -The Python implementation is portable: it runs on many brands of UNIX, -on Windows, DOS, Mac, Amiga... If your favorite system isn't -listed here, it may still be supported, if there's a C compiler for -it. Ask around on comp.lang.python -- or just try compiling Python -yourself. -""" - -CLASSIFIERS = """ -Development Status :: 6 - Mature -License :: OSI Approved :: Python Software Foundation License -Natural Language :: English -Programming Language :: C -Programming Language :: Python -Topic :: Software Development -""" - - -def run_command(cmd): - status = os.system(cmd) - return os.waitstatus_to_exitcode(status) - - -# Set common compiler and linker flags derived from the Makefile, -# reserved for building the interpreter and the stdlib modules. -# See bpo-21121 and bpo-35257 -def set_compiler_flags(compiler_flags, compiler_py_flags_nodist): - flags = sysconfig.get_config_var(compiler_flags) - py_flags_nodist = sysconfig.get_config_var(compiler_py_flags_nodist) - sysconfig.get_config_vars()[compiler_flags] = flags + ' ' + py_flags_nodist - - -def add_dir_to_list(dirlist, dir): - """Add the directory 'dir' to the list 'dirlist' (after any relative - directories) if: - - 1) 'dir' is not already in 'dirlist' - 2) 'dir' actually exists, and is a directory. - """ - if dir is None or not os.path.isdir(dir) or dir in dirlist: - return - for i, path in enumerate(dirlist): - if not os.path.isabs(path): - dirlist.insert(i + 1, dir) - return - dirlist.insert(0, dir) - - -def sysroot_paths(make_vars, subdirs): - """Get the paths of sysroot sub-directories. - - * make_vars: a sequence of names of variables of the Makefile where - sysroot may be set. - * subdirs: a sequence of names of subdirectories used as the location for - headers or libraries. - """ - - dirs = [] - for var_name in make_vars: - var = sysconfig.get_config_var(var_name) - if var is not None: - m = re.search(r'--sysroot=([^"]\S*|"[^"]+")', var) - if m is not None: - sysroot = m.group(1).strip('"') - for subdir in subdirs: - if os.path.isabs(subdir): - subdir = subdir[1:] - path = os.path.join(sysroot, subdir) - if os.path.isdir(path): - dirs.append(path) - break - return dirs - - -MACOS_SDK_ROOT = None -MACOS_SDK_SPECIFIED = None - -def macosx_sdk_root(): - """Return the directory of the current macOS SDK. - - If no SDK was explicitly configured, call the compiler to find which - include files paths are being searched by default. Use '/' if the - compiler is searching /usr/include (meaning system header files are - installed) or use the root of an SDK if that is being searched. - (The SDK may be supplied via Xcode or via the Command Line Tools). - The SDK paths used by Apple-supplied tool chains depend on the - setting of various variables; see the xcrun man page for more info. - Also sets MACOS_SDK_SPECIFIED for use by macosx_sdk_specified(). - """ - global MACOS_SDK_ROOT, MACOS_SDK_SPECIFIED - - # If already called, return cached result. - if MACOS_SDK_ROOT: - return MACOS_SDK_ROOT - - cflags = sysconfig.get_config_var('CFLAGS') - m = re.search(r'-isysroot\s*(\S+)', cflags) - if m is not None: - MACOS_SDK_ROOT = m.group(1) - MACOS_SDK_SPECIFIED = MACOS_SDK_ROOT != '/' - else: - MACOS_SDK_ROOT = _osx_support._default_sysroot( - sysconfig.get_config_var('CC')) - MACOS_SDK_SPECIFIED = False - - return MACOS_SDK_ROOT - - -def macosx_sdk_specified(): - """Returns true if an SDK was explicitly configured. - - True if an SDK was selected at configure time, either by specifying - --enable-universalsdk=(something other than no or /) or by adding a - -isysroot option to CFLAGS. In some cases, like when making - decisions about macOS Tk framework paths, we need to be able to - know whether the user explicitly asked to build with an SDK versus - the implicit use of an SDK when header files are no longer - installed on a running system by the Command Line Tools. - """ - global MACOS_SDK_SPECIFIED - - # If already called, return cached result. - if MACOS_SDK_SPECIFIED: - return MACOS_SDK_SPECIFIED - - # Find the sdk root and set MACOS_SDK_SPECIFIED - macosx_sdk_root() - return MACOS_SDK_SPECIFIED - - -def is_macosx_sdk_path(path): - """ - Returns True if 'path' can be located in a macOS SDK - """ - return ( (path.startswith('/usr/') and not path.startswith('/usr/local')) - or path.startswith('/System/Library') - or path.startswith('/System/iOSSupport') ) - - -def grep_headers_for(function, headers): - for header in headers: - with open(header, 'r', errors='surrogateescape') as f: - if function in f.read(): - return True - return False - - -def find_file(filename, std_dirs, paths): - """Searches for the directory where a given file is located, - and returns a possibly-empty list of additional directories, or None - if the file couldn't be found at all. - - 'filename' is the name of a file, such as readline.h or libcrypto.a. - 'std_dirs' is the list of standard system directories; if the - file is found in one of them, no additional directives are needed. - 'paths' is a list of additional locations to check; if the file is - found in one of them, the resulting list will contain the directory. - """ - if MACOS: - # Honor the MacOSX SDK setting when one was specified. - # An SDK is a directory with the same structure as a real - # system, but with only header files and libraries. - sysroot = macosx_sdk_root() - - # Check the standard locations - for dir_ in std_dirs: - f = os.path.join(dir_, filename) - - if MACOS and is_macosx_sdk_path(dir_): - f = os.path.join(sysroot, dir_[1:], filename) - - if os.path.exists(f): return [] - - # Check the additional directories - for dir_ in paths: - f = os.path.join(dir_, filename) - - if MACOS and is_macosx_sdk_path(dir_): - f = os.path.join(sysroot, dir_[1:], filename) - - if os.path.exists(f): - return [dir_] - - # Not found anywhere - return None - - -def find_library_file(compiler, libname, std_dirs, paths): - result = compiler.find_library_file(std_dirs + paths, libname) - if result is None: - return None - - if MACOS: - sysroot = macosx_sdk_root() - - # Check whether the found file is in one of the standard directories - dirname = os.path.dirname(result) - for p in std_dirs: - # Ensure path doesn't end with path separator - p = p.rstrip(os.sep) - - if MACOS and is_macosx_sdk_path(p): - # Note that, as of Xcode 7, Apple SDKs may contain textual stub - # libraries with .tbd extensions rather than the normal .dylib - # shared libraries installed in /. The Apple compiler tool - # chain handles this transparently but it can cause problems - # for programs that are being built with an SDK and searching - # for specific libraries. Distutils find_library_file() now - # knows to also search for and return .tbd files. But callers - # of find_library_file need to keep in mind that the base filename - # of the returned SDK library file might have a different extension - # from that of the library file installed on the running system, - # for example: - # /Applications/Xcode.app/Contents/Developer/Platforms/ - # MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/ - # usr/lib/libedit.tbd - # vs - # /usr/lib/libedit.dylib - if os.path.join(sysroot, p[1:]) == dirname: - return [ ] - - if p == dirname: - return [ ] - - # Otherwise, it must have been in one of the additional directories, - # so we have to figure out which one. - for p in paths: - # Ensure path doesn't end with path separator - p = p.rstrip(os.sep) - - if MACOS and is_macosx_sdk_path(p): - if os.path.join(sysroot, p[1:]) == dirname: - return [ p ] - - if p == dirname: - return [p] - else: - assert False, "Internal error: Path not found in std_dirs or paths" - - -def validate_tzpath(): - base_tzpath = sysconfig.get_config_var('TZPATH') - if not base_tzpath: - return - - tzpaths = base_tzpath.split(os.pathsep) - bad_paths = [tzpath for tzpath in tzpaths if not os.path.isabs(tzpath)] - if bad_paths: - raise ValueError('TZPATH must contain only absolute paths, ' - + f'found:\n{tzpaths!r}\nwith invalid paths:\n' - + f'{bad_paths!r}') - - -def find_module_file(module, dirlist): - """Find a module in a set of possible folders. If it is not found - return the unadorned filename""" - dirs = find_file(module, [], dirlist) - if not dirs: - return module - if len(dirs) > 1: - log.info(f"WARNING: multiple copies of {module} found") - return os.path.abspath(os.path.join(dirs[0], module)) - - -class PyBuildExt(build_ext): - - def __init__(self, dist): - build_ext.__init__(self, dist) - self.srcdir = None - self.lib_dirs = None - self.inc_dirs = None - self.config_h_vars = None - self.failed = [] - self.failed_on_import = [] - self.missing = [] - self.disabled_configure = [] - if '-j' in os.environ.get('MAKEFLAGS', ''): - self.parallel = True - - def add(self, ext): - self.extensions.append(ext) - - def addext(self, ext, *, update_flags=True): - """Add extension with Makefile MODULE_{name} support - """ - if update_flags: - self.update_extension_flags(ext) - - state = sysconfig.get_config_var(f"MODULE_{ext.name.upper()}") - if state == "yes": - self.extensions.append(ext) - elif state == "disabled": - self.disabled_configure.append(ext.name) - elif state == "missing": - self.missing.append(ext.name) - elif state == "n/a": - # not available on current platform - pass - else: - # not migrated to MODULE_{name} yet. - self.extensions.append(ext) - - def update_extension_flags(self, ext): - """Update extension flags with module CFLAGS and LDFLAGS - - Reads MODULE_{name}_CFLAGS and _LDFLAGS - - Distutils appends extra args to the compiler arguments. Some flags like - -I must appear earlier, otherwise the pre-processor picks up files - from system inclue directories. - """ - upper_name = ext.name.upper() - # Parse compiler flags (-I, -D, -U, extra args) - cflags = sysconfig.get_config_var(f"MODULE_{upper_name}_CFLAGS") - if cflags: - for token in shlex.split(cflags): - switch = token[0:2] - value = token[2:] - if switch == '-I': - ext.include_dirs.append(value) - elif switch == '-D': - key, _, val = value.partition("=") - if not val: - val = None - ext.define_macros.append((key, val)) - elif switch == '-U': - ext.undef_macros.append(value) - else: - ext.extra_compile_args.append(token) - - # Parse linker flags (-L, -l, extra objects, extra args) - ldflags = sysconfig.get_config_var(f"MODULE_{upper_name}_LDFLAGS") - if ldflags: - for token in shlex.split(ldflags): - switch = token[0:2] - value = token[2:] - if switch == '-L': - ext.library_dirs.append(value) - elif switch == '-l': - ext.libraries.append(value) - elif ( - token[0] != '-' and - token.endswith(('.a', '.o', '.so', '.sl', '.dylib')) - ): - ext.extra_objects.append(token) - else: - ext.extra_link_args.append(token) - - return ext - - def set_srcdir(self): - self.srcdir = sysconfig.get_config_var('srcdir') - if not self.srcdir: - # Maybe running on Windows but not using CYGWIN? - raise ValueError("No source directory; cannot proceed.") - self.srcdir = os.path.abspath(self.srcdir) - - def remove_disabled(self): - # Remove modules that are present on the disabled list - extensions = [ext for ext in self.extensions - if ext.name not in DISABLED_MODULE_LIST] - # move ctypes to the end, it depends on other modules - ext_map = dict((ext.name, i) for i, ext in enumerate(extensions)) - if "_ctypes" in ext_map: - ctypes = extensions.pop(ext_map["_ctypes"]) - extensions.append(ctypes) - self.extensions = extensions - - def update_sources_depends(self): - # Fix up the autodetected modules, prefixing all the source files - # with Modules/. - # Add dependencies from MODULE_{name}_DEPS variable - moddirlist = [ - # files in Modules/ directory - os.path.join(self.srcdir, 'Modules'), - # files relative to build base, e.g. libmpdec.a, libexpat.a - os.getcwd() - ] - - # Fix up the paths for scripts, too - self.distribution.scripts = [os.path.join(self.srcdir, filename) - for filename in self.distribution.scripts] - - # Python header files - include_dir = escape(sysconfig.get_path('include')) - headers = [sysconfig.get_config_h_filename()] - headers.extend(glob(os.path.join(include_dir, "*.h"))) - headers.extend(glob(os.path.join(include_dir, "cpython", "*.h"))) - headers.extend(glob(os.path.join(include_dir, "internal", "*.h"))) - - for ext in self.extensions: - ext.sources = [ find_module_file(filename, moddirlist) - for filename in ext.sources ] - # Update dependencies from Makefile - makedeps = sysconfig.get_config_var(f"MODULE_{ext.name.upper()}_DEPS") - if makedeps: - # remove backslashes from line break continuations - ext.depends.extend( - dep for dep in makedeps.split() if dep != "\\" - ) - ext.depends = [ - find_module_file(filename, moddirlist) for filename in ext.depends - ] - # re-compile extensions if a header file has been changed - ext.depends.extend(headers) - - def handle_configured_extensions(self): - # The sysconfig variables built by makesetup that list the already - # built modules and the disabled modules as configured by the Setup - # files. - sysconf_built = set(sysconfig.get_config_var('MODBUILT_NAMES').split()) - sysconf_shared = set(sysconfig.get_config_var('MODSHARED_NAMES').split()) - sysconf_dis = set(sysconfig.get_config_var('MODDISABLED_NAMES').split()) - - mods_built = [] - mods_disabled = [] - for ext in self.extensions: - # If a module has already been built or has been disabled in the - # Setup files, don't build it here. - if ext.name in sysconf_built: - mods_built.append(ext) - if ext.name in sysconf_dis: - mods_disabled.append(ext) - - mods_configured = mods_built + mods_disabled - if mods_configured: - self.extensions = [x for x in self.extensions if x not in - mods_configured] - # Remove the shared libraries built by a previous build. - for ext in mods_configured: - # Don't remove shared extensions which have been built - # by Modules/Setup - if ext.name in sysconf_shared: - continue - fullpath = self.get_ext_fullpath(ext.name) - if os.path.lexists(fullpath): - os.unlink(fullpath) - - return mods_built, mods_disabled - - def set_compiler_executables(self): - # When you run "make CC=altcc" or something similar, you really want - # those environment variables passed into the setup.py phase. Here's - # a small set of useful ones. - compiler = os.environ.get('CC') - args = {} - # unfortunately, distutils doesn't let us provide separate C and C++ - # compilers - if compiler is not None: - (ccshared,cflags) = sysconfig.get_config_vars('CCSHARED','CFLAGS') - args['compiler_so'] = compiler + ' ' + ccshared + ' ' + cflags - self.compiler.set_executables(**args) - - def build_extensions(self): - self.set_srcdir() - - # Detect which modules should be compiled - self.detect_modules() - - if not LIST_MODULE_NAMES: - self.remove_disabled() - - self.update_sources_depends() - mods_built, mods_disabled = self.handle_configured_extensions() - self.set_compiler_executables() - - if LIST_MODULE_NAMES: - for ext in self.extensions: - print(ext.name) - for name in self.missing: - print(name) - return - - build_ext.build_extensions(self) - - if SUBPROCESS_BOOTSTRAP: - # Drop our custom subprocess module: - # use the newly built subprocess module - del sys.modules['subprocess'] - - for ext in self.extensions: - self.check_extension_import(ext) - - self.summary(mods_built, mods_disabled) - - def summary(self, mods_built, mods_disabled): - longest = max([len(e.name) for e in self.extensions], default=0) - if self.failed or self.failed_on_import: - all_failed = self.failed + self.failed_on_import - longest = max(longest, max([len(name) for name in all_failed])) - - def print_three_column(lst): - lst.sort(key=str.lower) - # guarantee zip() doesn't drop anything - while len(lst) % 3: - lst.append("") - for e, f, g in zip(lst[::3], lst[1::3], lst[2::3]): - print("%-*s %-*s %-*s" % (longest, e, longest, f, - longest, g)) - - if self.missing: - print() - print("Python build finished successfully!") - print("The necessary bits to build these optional modules were not " - "found:") - print_three_column(self.missing) - print("To find the necessary bits, look in setup.py in" - " detect_modules() for the module's name.") - print() - - if mods_built: - print() - print("The following modules found by detect_modules() in" - " setup.py, have been") - print("built by the Makefile instead, as configured by the" - " Setup files:") - print_three_column([ext.name for ext in mods_built]) - print() - - if mods_disabled: - print() - print("The following modules found by detect_modules() in" - " setup.py have not") - print("been built, they are *disabled* in the Setup files:") - print_three_column([ext.name for ext in mods_disabled]) - print() - - if self.disabled_configure: - print() - print("The following modules found by detect_modules() in" - " setup.py have not") - print("been built, they are *disabled* by configure:") - print_three_column(self.disabled_configure) - print() - - if self.failed: - failed = self.failed[:] - print() - print("Failed to build these modules:") - print_three_column(failed) - print() - - if self.failed_on_import: - failed = self.failed_on_import[:] - print() - print("Following modules built successfully" - " but were removed because they could not be imported:") - print_three_column(failed) - print() - - if any('_ssl' in l - for l in (self.missing, self.failed, self.failed_on_import)): - print() - print("Could not build the ssl module!") - print("Python requires a OpenSSL 1.1.1 or newer") - if sysconfig.get_config_var("OPENSSL_LDFLAGS"): - print("Custom linker flags may require --with-openssl-rpath=auto") - print() - - if os.environ.get("PYTHONSTRICTEXTENSIONBUILD") and (self.failed or self.failed_on_import): - raise RuntimeError("Failed to build some stdlib modules") - - def build_extension(self, ext): - - if ext.name == '_ctypes': - if not self.configure_ctypes(ext): - self.failed.append(ext.name) - return - - try: - build_ext.build_extension(self, ext) - except (CCompilerError, DistutilsError) as why: - self.announce('WARNING: building of extension "%s" failed: %s' % - (ext.name, why)) - self.failed.append(ext.name) - return - - def check_extension_import(self, ext): - # Don't try to import an extension that has failed to compile - if ext.name in self.failed: - self.announce( - 'WARNING: skipping import check for failed build "%s"' % - ext.name, level=1) - return - - # Workaround for Mac OS X: The Carbon-based modules cannot be - # reliably imported into a command-line Python - if 'Carbon' in ext.extra_link_args: - self.announce( - 'WARNING: skipping import check for Carbon-based "%s"' % - ext.name) - return - - if MACOS and ( - sys.maxsize > 2**32 and '-arch' in ext.extra_link_args): - # Don't bother doing an import check when an extension was - # build with an explicit '-arch' flag on OSX. That's currently - # only used to build 32-bit only extensions in a 4-way - # universal build and loading 32-bit code into a 64-bit - # process will fail. - self.announce( - 'WARNING: skipping import check for "%s"' % - ext.name) - return - - # Workaround for Cygwin: Cygwin currently has fork issues when many - # modules have been imported - if CYGWIN: - self.announce('WARNING: skipping import check for Cygwin-based "%s"' - % ext.name) - return - ext_filename = os.path.join( - self.build_lib, - self.get_ext_filename(self.get_ext_fullname(ext.name))) - - # If the build directory didn't exist when setup.py was - # started, sys.path_importer_cache has a negative result - # cached. Clear that cache before trying to import. - sys.path_importer_cache.clear() - - # Don't try to load extensions for cross builds - if CROSS_COMPILING: - return - - loader = importlib.machinery.ExtensionFileLoader(ext.name, ext_filename) - spec = importlib.util.spec_from_file_location(ext.name, ext_filename, - loader=loader) - try: - importlib._bootstrap._load(spec) - except ImportError as why: - self.failed_on_import.append(ext.name) - self.announce('*** WARNING: renaming "%s" since importing it' - ' failed: %s' % (ext.name, why), level=3) - assert not self.inplace - basename, tail = os.path.splitext(ext_filename) - newname = basename + "_failed" + tail - if os.path.exists(newname): - os.remove(newname) - os.rename(ext_filename, newname) - - except: - exc_type, why, tb = sys.exc_info() - self.announce('*** WARNING: importing extension "%s" ' - 'failed with %s: %s' % (ext.name, exc_type, why), - level=3) - self.failed.append(ext.name) - - def add_multiarch_paths(self): - # Debian/Ubuntu multiarch support. - # https://wiki.ubuntu.com/MultiarchSpec - cc = sysconfig.get_config_var('CC') - tmpfile = os.path.join(self.build_temp, 'multiarch') - if not os.path.exists(self.build_temp): - os.makedirs(self.build_temp) - ret = run_command( - '%s -print-multiarch > %s 2> /dev/null' % (cc, tmpfile)) - multiarch_path_component = '' - try: - if ret == 0: - with open(tmpfile) as fp: - multiarch_path_component = fp.readline().strip() - finally: - os.unlink(tmpfile) - - if multiarch_path_component != '': - add_dir_to_list(self.compiler.library_dirs, - '/usr/lib/' + multiarch_path_component) - add_dir_to_list(self.compiler.include_dirs, - '/usr/include/' + multiarch_path_component) - return - - if not find_executable('dpkg-architecture'): - return - opt = '' - if CROSS_COMPILING: - opt = '-t' + sysconfig.get_config_var('HOST_GNU_TYPE') - tmpfile = os.path.join(self.build_temp, 'multiarch') - if not os.path.exists(self.build_temp): - os.makedirs(self.build_temp) - ret = run_command( - 'dpkg-architecture %s -qDEB_HOST_MULTIARCH > %s 2> /dev/null' % - (opt, tmpfile)) - try: - if ret == 0: - with open(tmpfile) as fp: - multiarch_path_component = fp.readline().strip() - add_dir_to_list(self.compiler.library_dirs, - '/usr/lib/' + multiarch_path_component) - add_dir_to_list(self.compiler.include_dirs, - '/usr/include/' + multiarch_path_component) - finally: - os.unlink(tmpfile) - - def add_wrcc_search_dirs(self): - # add library search path by wr-cc, the compiler wrapper - - def convert_mixed_path(path): - # convert path like C:\folder1\folder2/folder3/folder4 - # to msys style /c/folder1/folder2/folder3/folder4 - drive = path[0].lower() - left = path[2:].replace("\\", "/") - return "/" + drive + left - - def add_search_path(line): - # On Windows building machine, VxWorks does - # cross builds under msys2 environment. - pathsep = (";" if sys.platform == "msys" else ":") - for d in line.strip().split("=")[1].split(pathsep): - d = d.strip() - if sys.platform == "msys": - # On Windows building machine, compiler - # returns mixed style path like: - # C:\folder1\folder2/folder3/folder4 - d = convert_mixed_path(d) - d = os.path.normpath(d) - add_dir_to_list(self.compiler.library_dirs, d) - - cc = sysconfig.get_config_var('CC') - tmpfile = os.path.join(self.build_temp, 'wrccpaths') - os.makedirs(self.build_temp, exist_ok=True) - try: - ret = run_command('%s --print-search-dirs >%s' % (cc, tmpfile)) - if ret: - return - with open(tmpfile) as fp: - # Parse paths in libraries line. The line is like: - # On Linux, "libraries: = path1:path2:path3" - # On Windows, "libraries: = path1;path2;path3" - for line in fp: - if not line.startswith("libraries"): - continue - add_search_path(line) - finally: - try: - os.unlink(tmpfile) - except OSError: - pass - - def add_cross_compiling_paths(self): - cc = sysconfig.get_config_var('CC') - tmpfile = os.path.join(self.build_temp, 'ccpaths') - if not os.path.exists(self.build_temp): - os.makedirs(self.build_temp) - ret = run_command('%s -E -v - %s 1>/dev/null' % (cc, tmpfile)) - is_gcc = False - is_clang = False - in_incdirs = False - try: - if ret == 0: - with open(tmpfile) as fp: - for line in fp.readlines(): - if line.startswith("gcc version"): - is_gcc = True - elif line.startswith("clang version"): - is_clang = True - elif line.startswith("#include <...>"): - in_incdirs = True - elif line.startswith("End of search list"): - in_incdirs = False - elif (is_gcc or is_clang) and line.startswith("LIBRARY_PATH"): - for d in line.strip().split("=")[1].split(":"): - d = os.path.normpath(d) - if '/gcc/' not in d: - add_dir_to_list(self.compiler.library_dirs, - d) - elif (is_gcc or is_clang) and in_incdirs and '/gcc/' not in line and '/clang/' not in line: - add_dir_to_list(self.compiler.include_dirs, - line.strip()) - finally: - os.unlink(tmpfile) - - if VXWORKS: - self.add_wrcc_search_dirs() - - def add_ldflags_cppflags(self): - # Add paths specified in the environment variables LDFLAGS and - # CPPFLAGS for header and library files. - # We must get the values from the Makefile and not the environment - # directly since an inconsistently reproducible issue comes up where - # the environment variable is not set even though the value were passed - # into configure and stored in the Makefile (issue found on OS X 10.3). - for env_var, arg_name, dir_list in ( - ('LDFLAGS', '-R', self.compiler.runtime_library_dirs), - ('LDFLAGS', '-L', self.compiler.library_dirs), - ('CPPFLAGS', '-I', self.compiler.include_dirs)): - env_val = sysconfig.get_config_var(env_var) - if env_val: - parser = argparse.ArgumentParser() - parser.add_argument(arg_name, dest="dirs", action="append") - - # To prevent argparse from raising an exception about any - # options in env_val that it mistakes for known option, we - # strip out all double dashes and any dashes followed by a - # character that is not for the option we are dealing with. - # - # Please note that order of the regex is important! We must - # strip out double-dashes first so that we don't end up with - # substituting "--Long" to "-Long" and thus lead to "ong" being - # used for a library directory. - env_val = re.sub(r'(^|\s+)-(-|(?!%s))' % arg_name[1], - ' ', env_val) - options, _ = parser.parse_known_args(env_val.split()) - if options.dirs: - for directory in reversed(options.dirs): - add_dir_to_list(dir_list, directory) - - def configure_compiler(self): - # Ensure that /usr/local is always used, but the local build - # directories (i.e. '.' and 'Include') must be first. See issue - # 10520. - if not CROSS_COMPILING: - add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') - add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') - # only change this for cross builds for 3.3, issues on Mageia - if CROSS_COMPILING: - self.add_cross_compiling_paths() - self.add_multiarch_paths() - self.add_ldflags_cppflags() - - def init_inc_lib_dirs(self): - if (not CROSS_COMPILING and - os.path.normpath(sys.base_prefix) != '/usr' and - not sysconfig.get_config_var('PYTHONFRAMEWORK')): - # OSX note: Don't add LIBDIR and INCLUDEDIR to building a framework - # (PYTHONFRAMEWORK is set) to avoid # linking problems when - # building a framework with different architectures than - # the one that is currently installed (issue #7473) - add_dir_to_list(self.compiler.library_dirs, - sysconfig.get_config_var("LIBDIR")) - add_dir_to_list(self.compiler.include_dirs, - sysconfig.get_config_var("INCLUDEDIR")) - - system_lib_dirs = ['/lib64', '/usr/lib64', '/lib', '/usr/lib'] - system_include_dirs = ['/usr/include'] - # lib_dirs and inc_dirs are used to search for files; - # if a file is found in one of those directories, it can - # be assumed that no additional -I,-L directives are needed. - if not CROSS_COMPILING: - self.lib_dirs = self.compiler.library_dirs + system_lib_dirs - self.inc_dirs = self.compiler.include_dirs + system_include_dirs - else: - # Add the sysroot paths. 'sysroot' is a compiler option used to - # set the logical path of the standard system headers and - # libraries. - self.lib_dirs = (self.compiler.library_dirs + - sysroot_paths(('LDFLAGS', 'CC'), system_lib_dirs)) - self.inc_dirs = (self.compiler.include_dirs + - sysroot_paths(('CPPFLAGS', 'CFLAGS', 'CC'), - system_include_dirs)) - - config_h = sysconfig.get_config_h_filename() - with open(config_h) as file: - self.config_h_vars = sysconfig.parse_config_h(file) - - # OSF/1 and Unixware have some stuff in /usr/ccs/lib (like -ldb) - if HOST_PLATFORM in ['osf1', 'unixware7', 'openunix8']: - self.lib_dirs += ['/usr/ccs/lib'] - - # HP-UX11iv3 keeps files in lib/hpux folders. - if HOST_PLATFORM == 'hp-ux11': - self.lib_dirs += ['/usr/lib/hpux64', '/usr/lib/hpux32'] - - if MACOS: - # This should work on any unixy platform ;-) - # If the user has bothered specifying additional -I and -L flags - # in OPT and LDFLAGS we might as well use them here. - # - # NOTE: using shlex.split would technically be more correct, but - # also gives a bootstrap problem. Let's hope nobody uses - # directories with whitespace in the name to store libraries. - cflags, ldflags = sysconfig.get_config_vars( - 'CFLAGS', 'LDFLAGS') - for item in cflags.split(): - if item.startswith('-I'): - self.inc_dirs.append(item[2:]) - - for item in ldflags.split(): - if item.startswith('-L'): - self.lib_dirs.append(item[2:]) - - def detect_simple_extensions(self): - # - # The following modules are all pretty straightforward, and compile - # on pretty much any POSIXish platform. - # - - # array objects - self.addext(Extension('array', ['arraymodule.c'])) - - # Context Variables - self.addext(Extension('_contextvars', ['_contextvarsmodule.c'])) - - # math library functions, e.g. sin() - self.addext(Extension('math', ['mathmodule.c'])) - - # complex math library functions - self.addext(Extension('cmath', ['cmathmodule.c'])) - - # time libraries: librt may be needed for clock_gettime() - time_libs = [] - lib = sysconfig.get_config_var('TIMEMODULE_LIB') - if lib: - time_libs.append(lib) - - # libm is needed by delta_new() that uses round() and by accum() that - # uses modf(). - self.addext(Extension('_datetime', ['_datetimemodule.c'])) - self.addext(Extension('_zoneinfo', ['_zoneinfo.c'])) - # random number generator implemented in C - self.addext(Extension("_random", ["_randommodule.c"])) - self.addext(Extension("_bisect", ["_bisectmodule.c"])) - self.addext(Extension("_heapq", ["_heapqmodule.c"])) - # C-optimized pickle replacement - self.addext(Extension("_pickle", ["_pickle.c"])) - # _json speedups - self.addext(Extension("_json", ["_json.c"])) - - # profiler (_lsprof is for cProfile.py) - self.addext(Extension('_lsprof', ['_lsprof.c', 'rotatingtree.c'])) - # static Unicode character database - self.addext(Extension('unicodedata', ['unicodedata.c'])) - self.addext(Extension('_opcode', ['_opcode.c'])) - - # asyncio speedups - self.addext(Extension("_asyncio", ["_asynciomodule.c"])) - - self.addext(Extension("_queue", ["_queuemodule.c"])) - self.addext(Extension("_statistics", ["_statisticsmodule.c"])) - self.addext(Extension("_typing", ["_typingmodule.c"])) - - # Modules with some UNIX dependencies -- on by default: - # (If you have a really backward UNIX, select and socket may not be - # supported...) - - # fcntl(2) and ioctl(2) - libs = [] - if (self.config_h_vars.get('FLOCK_NEEDS_LIBBSD', False)): - # May be necessary on AIX for flock function - libs = ['bsd'] - self.add(Extension('fcntl', ['fcntlmodule.c'], - libraries=libs)) - # grp(3) - self.addext(Extension('grp', ['grpmodule.c'])) - self.addext(Extension('spwd', ['spwdmodule.c'])) - - # select(2); not on ancient System V - self.add(Extension('select', ['selectmodule.c'])) - - # Memory-mapped files (also works on Win32). - self.add(Extension('mmap', ['mmapmodule.c'])) - - # Lance Ellinghaus's syslog module - # syslog daemon interface - self.addext(Extension('syslog', ['syslogmodule.c'])) - - # Python interface to subinterpreter C-API. - self.add(Extension('_xxsubinterpreters', ['_xxsubinterpretersmodule.c'])) - - # - # Here ends the simple stuff. From here on, modules need certain - # libraries, are platform-specific, or present other surprises. - # - - # Multimedia modules - # These don't work for 64-bit platforms!!! - # These represent audio samples or images as strings: - # - # Operations on audio samples - # According to #993173, this one should actually work fine on - # 64-bit platforms. - # - # audioop needs libm for floor() in multiple functions. - self.add(Extension('audioop', ['audioop.c'], - libraries=['m'])) - - # CSV files - self.add(Extension('_csv', ['_csv.c'])) - - # POSIX subprocess module helper. - self.add(Extension('_posixsubprocess', ['_posixsubprocess.c'])) - - def detect_test_extensions(self): - # Python C API test module - self.addext(Extension('_testcapi', ['_testcapimodule.c'])) - - # Python Internal C API test module - self.addext(Extension('_testinternalcapi', ['_testinternalcapi.c'])) - - # Python PEP-3118 (buffer protocol) test module - self.addext(Extension('_testbuffer', ['_testbuffer.c'])) - - # Test loading multiple modules from one compiled file (https://bugs.python.org/issue16421) - self.addext(Extension('_testimportmultiple', ['_testimportmultiple.c'])) - - # Test multi-phase extension module init (PEP 489) - self.addext(Extension('_testmultiphase', ['_testmultiphase.c'])) - - # Fuzz tests. - self.addext(Extension( - '_xxtestfuzz', - ['_xxtestfuzz/_xxtestfuzz.c', '_xxtestfuzz/fuzzer.c'] - )) - - def detect_readline_curses(self): - # readline - readline_termcap_library = "" - curses_library = "" - # Cannot use os.popen here in py3k. - tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib') - if not os.path.exists(self.build_temp): - os.makedirs(self.build_temp) - # Determine if readline is already linked against curses or tinfo. - if sysconfig.get_config_var('HAVE_LIBREADLINE'): - if sysconfig.get_config_var('WITH_EDITLINE'): - readline_lib = 'edit' - else: - readline_lib = 'readline' - do_readline = self.compiler.find_library_file(self.lib_dirs, - readline_lib) - if CROSS_COMPILING: - ret = run_command("%s -d %s | grep '(NEEDED)' > %s" - % (sysconfig.get_config_var('READELF'), - do_readline, tmpfile)) - elif find_executable('ldd'): - ret = run_command("ldd %s > %s" % (do_readline, tmpfile)) - else: - ret = 1 - if ret == 0: - with open(tmpfile) as fp: - for ln in fp: - if 'curses' in ln: - readline_termcap_library = re.sub( - r'.*lib(n?cursesw?)\.so.*', r'\1', ln - ).rstrip() - break - # termcap interface split out from ncurses - if 'tinfo' in ln: - readline_termcap_library = 'tinfo' - break - if os.path.exists(tmpfile): - os.unlink(tmpfile) - else: - do_readline = False - # Issue 7384: If readline is already linked against curses, - # use the same library for the readline and curses modules. - if 'curses' in readline_termcap_library: - curses_library = readline_termcap_library - elif self.compiler.find_library_file(self.lib_dirs, 'ncursesw'): - curses_library = 'ncursesw' - # Issue 36210: OSS provided ncurses does not link on AIX - # Use IBM supplied 'curses' for successful build of _curses - elif AIX and self.compiler.find_library_file(self.lib_dirs, 'curses'): - curses_library = 'curses' - elif self.compiler.find_library_file(self.lib_dirs, 'ncurses'): - curses_library = 'ncurses' - elif self.compiler.find_library_file(self.lib_dirs, 'curses'): - curses_library = 'curses' - - if MACOS: - os_release = int(os.uname()[2].split('.')[0]) - dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') - if (dep_target and - (tuple(int(n) for n in dep_target.split('.')[0:2]) - < (10, 5) ) ): - os_release = 8 - if os_release < 9: - # MacOSX 10.4 has a broken readline. Don't try to build - # the readline module unless the user has installed a fixed - # readline package - if find_file('readline/rlconf.h', self.inc_dirs, []) is None: - do_readline = False - if do_readline: - readline_libs = [readline_lib] - if readline_termcap_library: - pass # Issue 7384: Already linked against curses or tinfo. - elif curses_library: - readline_libs.append(curses_library) - elif self.compiler.find_library_file(self.lib_dirs + - ['/usr/lib/termcap'], - 'termcap'): - readline_libs.append('termcap') - self.add(Extension('readline', ['readline.c'], - library_dirs=['/usr/lib/termcap'], - libraries=readline_libs)) - else: - self.missing.append('readline') - - # Curses support, requiring the System V version of curses, often - # provided by the ncurses library. - curses_defines = [] - curses_includes = [] - panel_library = 'panel' - if curses_library == 'ncursesw': - curses_defines.append(('HAVE_NCURSESW', '1')) - if not CROSS_COMPILING: - curses_includes.append('/usr/include/ncursesw') - # Bug 1464056: If _curses.so links with ncursesw, - # _curses_panel.so must link with panelw. - panel_library = 'panelw' - if MACOS: - # On OS X, there is no separate /usr/lib/libncursesw nor - # libpanelw. If we are here, we found a locally-supplied - # version of libncursesw. There should also be a - # libpanelw. _XOPEN_SOURCE defines are usually excluded - # for OS X but we need _XOPEN_SOURCE_EXTENDED here for - # ncurses wide char support - curses_defines.append(('_XOPEN_SOURCE_EXTENDED', '1')) - elif MACOS and curses_library == 'ncurses': - # Building with the system-suppied combined libncurses/libpanel - curses_defines.append(('HAVE_NCURSESW', '1')) - curses_defines.append(('_XOPEN_SOURCE_EXTENDED', '1')) - - curses_enabled = True - if curses_library.startswith('ncurses'): - curses_libs = [curses_library] - self.add(Extension('_curses', ['_cursesmodule.c'], - include_dirs=curses_includes, - define_macros=curses_defines, - libraries=curses_libs)) - elif curses_library == 'curses' and not MACOS: - # OSX has an old Berkeley curses, not good enough for - # the _curses module. - if (self.compiler.find_library_file(self.lib_dirs, 'terminfo')): - curses_libs = ['curses', 'terminfo'] - elif (self.compiler.find_library_file(self.lib_dirs, 'termcap')): - curses_libs = ['curses', 'termcap'] - else: - curses_libs = ['curses'] - - self.add(Extension('_curses', ['_cursesmodule.c'], - define_macros=curses_defines, - libraries=curses_libs)) - else: - curses_enabled = False - self.missing.append('_curses') - - # If the curses module is enabled, check for the panel module - # _curses_panel needs some form of ncurses - skip_curses_panel = True if AIX else False - if (curses_enabled and not skip_curses_panel and - self.compiler.find_library_file(self.lib_dirs, panel_library)): - self.add(Extension('_curses_panel', ['_curses_panel.c'], - include_dirs=curses_includes, - define_macros=curses_defines, - libraries=[panel_library, *curses_libs])) - elif not skip_curses_panel: - self.missing.append('_curses_panel') - - def detect_crypt(self): - # crypt module. - if VXWORKS: - # bpo-31904: crypt() function is not provided by VxWorks. - # DES_crypt() OpenSSL provides is too weak to implement - # the encryption. - self.missing.append('_crypt') - return - - if self.compiler.find_library_file(self.lib_dirs, 'crypt'): - libs = ['crypt'] - else: - libs = [] - - self.add(Extension('_crypt', ['_cryptmodule.c'], libraries=libs)) - - def detect_socket(self): - self.add(Extension('_socket', ['socketmodule.c'])) - - def detect_dbm_gdbm(self): - # Modules that provide persistent dictionary-like semantics. You will - # probably want to arrange for at least one of them to be available on - # your machine, though none are defined by default because of library - # dependencies. The Python module dbm/__init__.py provides an - # implementation independent wrapper for these; dbm/dumb.py provides - # similar functionality (but slower of course) implemented in Python. - - dbm_setup_debug = False # verbose debug prints from this script? - dbm_order = ['gdbm'] - - # libdb, gdbm and ndbm headers and libraries - have_ndbm_h = sysconfig.get_config_var("HAVE_NDBM_H") - have_gdbm_h = sysconfig.get_config_var("HAVE_GDBM_H") - have_gdbm_ndbm_h = sysconfig.get_config_var("HAVE_GDBM_NDBM_H") - have_gdbm_dash_ndbm_h = sysconfig.get_config_var("HAVE_GDBM_DASH_NDBM_H") - have_libndbm = sysconfig.get_config_var("HAVE_LIBNDBM") - have_libgdbm = sysconfig.get_config_var("HAVE_LIBGDBM") - have_libgdbm_compat = sysconfig.get_config_var("HAVE_LIBGDBM_COMPAT") - have_libdb = sysconfig.get_config_var("HAVE_LIBDB") - - # The standard Unix dbm module: - if not CYGWIN: - config_args = [arg.strip("'") - for arg in sysconfig.get_config_var("CONFIG_ARGS").split()] - dbm_args = [arg for arg in config_args - if arg.startswith('--with-dbmliborder=')] - if dbm_args: - dbm_order = [arg.split('=')[-1] for arg in dbm_args][-1].split(":") - else: - dbm_order = "ndbm:gdbm:bdb".split(":") - dbmext = None - for cand in dbm_order: - if cand == "ndbm": - if have_ndbm_h: - # Some systems have -lndbm, others have -lgdbm_compat, - # others don't have either - if have_libndbm: - ndbm_libs = ['ndbm'] - elif have_libgdbm_compat: - ndbm_libs = ['gdbm_compat'] - else: - ndbm_libs = [] - if dbm_setup_debug: print("building dbm using ndbm") - dbmext = Extension( - '_dbm', ['_dbmmodule.c'], - define_macros=[('USE_NDBM', None)], - libraries=ndbm_libs - ) - break - elif cand == "gdbm": - # dbm_open() is provided by libgdbm_compat, which wraps libgdbm - if have_libgdbm_compat and (have_gdbm_ndbm_h or have_gdbm_dash_ndbm_h): - if dbm_setup_debug: print("building dbm using gdbm") - dbmext = Extension( - '_dbm', ['_dbmmodule.c'], - define_macros=[('USE_GDBM_COMPAT', None)], - libraries=['gdbm_compat'] - ) - break - elif cand == "bdb": - if have_libdb: - if dbm_setup_debug: print("building dbm using bdb") - dbmext = Extension( - '_dbm', ['_dbmmodule.c'], - define_macros=[('USE_BERKDB', None)], - libraries=['db'] - ) - break - if dbmext is not None: - self.add(dbmext) - else: - self.missing.append('_dbm') - - # Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm: - if 'gdbm' in dbm_order and have_libgdbm: - self.add(Extension('_gdbm', ['_gdbmmodule.c'], - libraries=['gdbm'])) - else: - self.missing.append('_gdbm') - - def detect_sqlite(self): - sources = [ - "_sqlite/connection.c", - "_sqlite/cursor.c", - "_sqlite/microprotocols.c", - "_sqlite/module.c", - "_sqlite/prepare_protocol.c", - "_sqlite/row.c", - "_sqlite/statement.c", - "_sqlite/util.c", - ] - self.addext(Extension("_sqlite3", sources=sources)) - - def detect_platform_specific_exts(self): - # Unix-only modules - # Steen Lumholt's termios module - self.addext(Extension('termios', ['termios.c'])) - # Jeremy Hylton's rlimit interface - self.addext(Extension('resource', ['resource.c'])) - # linux/soundcard.h or sys/soundcard.h - self.addext(Extension('ossaudiodev', ['ossaudiodev.c'])) - - # macOS-only, needs SystemConfiguration and CoreFoundation framework - self.addext(Extension('_scproxy', ['_scproxy.c'])) - - def detect_compress_exts(self): - # Andrew Kuchling's zlib module. - have_zlib = sysconfig.get_config_var("HAVE_LIBZ") - if have_zlib: - self.add(Extension('zlib', ['zlibmodule.c'], - libraries=['z'])) - else: - self.missing.append('zlib') - - # Helper module for various ascii-encoders. Uses zlib for an optimized - # crc32 if we have it. Otherwise binascii uses its own. - if have_zlib: - define_macros = [('USE_ZLIB_CRC32', None)] - libraries = ['z'] - else: - define_macros = None - libraries = [] - self.add(Extension('binascii', ['binascii.c'], - define_macros=define_macros, - libraries=libraries)) - - # Gustavo Niemeyer's bz2 module. - if sysconfig.get_config_var("HAVE_LIBBZ2"): - self.add(Extension('_bz2', ['_bz2module.c'], - libraries=['bz2'])) - else: - self.missing.append('_bz2') - - # LZMA compression support. - if sysconfig.get_config_var("HAVE_LIBLZMA"): - self.add(Extension('_lzma', ['_lzmamodule.c'], - libraries=['lzma'])) - else: - self.missing.append('_lzma') - - def detect_expat_elementtree(self): - # Interface to the Expat XML parser - # - # Expat was written by James Clark and is now maintained by a group of - # developers on SourceForge; see www.libexpat.org for more information. - # The pyexpat module was written by Paul Prescod after a prototype by - # Jack Jansen. The Expat source is included in Modules/expat/. Usage - # of a system shared libexpat.so is possible with --with-system-expat - # configure option. - # - # More information on Expat can be found at www.libexpat.org. - # - self.addext(Extension('pyexpat', sources=['pyexpat.c'])) - - # Fredrik Lundh's cElementTree module. Note that this also - # uses expat (via the CAPI hook in pyexpat). - self.addext(Extension('_elementtree', sources=['_elementtree.c'])) - - def detect_multibytecodecs(self): - # Hye-Shik Chang's CJKCodecs modules. - self.addext(Extension('_multibytecodec', - ['cjkcodecs/multibytecodec.c'])) - for loc in ('kr', 'jp', 'cn', 'tw', 'hk', 'iso2022'): - self.addext(Extension( - f'_codecs_{loc}', [f'cjkcodecs/_codecs_{loc}.c'] - )) - - def detect_multiprocessing(self): - # Richard Oudkerk's multiprocessing module - if MS_WINDOWS: - multiprocessing_srcs = ['_multiprocessing/multiprocessing.c', - '_multiprocessing/semaphore.c'] - else: - multiprocessing_srcs = ['_multiprocessing/multiprocessing.c'] - if (sysconfig.get_config_var('HAVE_SEM_OPEN') and not - sysconfig.get_config_var('POSIX_SEMAPHORES_NOT_ENABLED')): - multiprocessing_srcs.append('_multiprocessing/semaphore.c') - self.add(Extension('_multiprocessing', multiprocessing_srcs, - include_dirs=["Modules/_multiprocessing"])) - - if (not MS_WINDOWS and - sysconfig.get_config_var('HAVE_SHM_OPEN') and - sysconfig.get_config_var('HAVE_SHM_UNLINK')): - posixshmem_srcs = ['_multiprocessing/posixshmem.c'] - libs = [] - if sysconfig.get_config_var('SHM_NEEDS_LIBRT'): - # need to link with librt to get shm_open() - libs.append('rt') - self.add(Extension('_posixshmem', posixshmem_srcs, - define_macros={}, - libraries=libs, - include_dirs=["Modules/_multiprocessing"])) - else: - self.missing.append('_posixshmem') - - def detect_uuid(self): - # Build the _uuid module if possible - uuid_h = sysconfig.get_config_var("HAVE_UUID_H") - uuid_uuid_h = sysconfig.get_config_var("HAVE_UUID_UUID_H") - if uuid_h or uuid_uuid_h: - if sysconfig.get_config_var("HAVE_LIBUUID"): - uuid_libs = ["uuid"] - else: - uuid_libs = [] - self.add(Extension('_uuid', ['_uuidmodule.c'], - libraries=uuid_libs)) - else: - self.missing.append('_uuid') - - def detect_modules(self): - self.configure_compiler() - self.init_inc_lib_dirs() - - # Some C extensions are built by entries in Modules/Setup.bootstrap. - # These are extensions are required to bootstrap the interpreter or - # build process. - self.detect_simple_extensions() - self.detect_test_extensions() - self.detect_readline_curses() - self.detect_crypt() - self.detect_socket() - self.detect_openssl_hashlib() - self.detect_hash_builtins() - self.detect_dbm_gdbm() - self.detect_sqlite() - self.detect_platform_specific_exts() - self.detect_nis() - self.detect_compress_exts() - self.detect_expat_elementtree() - self.detect_multibytecodecs() - self.detect_decimal() - self.detect_ctypes() - self.detect_multiprocessing() - if not self.detect_tkinter(): - self.missing.append('_tkinter') - self.detect_uuid() - -## # Uncomment these lines if you want to play with xxmodule.c -## self.add(Extension('xx', ['xxmodule.c'])) - - # The limited C API is not compatible with the Py_TRACE_REFS macro. - if not sysconfig.get_config_var('Py_TRACE_REFS'): - self.add(Extension('xxlimited', ['xxlimited.c'])) - self.add(Extension('xxlimited_35', ['xxlimited_35.c'])) - - def detect_tkinter_fromenv(self): - # Build _tkinter using the Tcl/Tk locations specified by - # the _TCLTK_INCLUDES and _TCLTK_LIBS environment variables. - # This method is meant to be invoked by detect_tkinter(). - # - # The variables can be set via one of the following ways. - # - # - Automatically, at configuration time, by using pkg-config. - # The tool is called by the configure script. - # Additional pkg-config configuration paths can be set via the - # PKG_CONFIG_PATH environment variable. - # - # PKG_CONFIG_PATH=".../lib/pkgconfig" ./configure ... - # - # - Explicitly, at configuration time by setting both - # --with-tcltk-includes and --with-tcltk-libs. - # - # ./configure ... \ - # --with-tcltk-includes="-I/path/to/tclincludes \ - # -I/path/to/tkincludes" - # --with-tcltk-libs="-L/path/to/tcllibs -ltclm.n \ - # -L/path/to/tklibs -ltkm.n" - # - # - Explicitly, at compile time, by passing TCLTK_INCLUDES and - # TCLTK_LIBS to the make target. - # This will override any configuration-time option. - # - # make TCLTK_INCLUDES="..." TCLTK_LIBS="..." - # - # This can be useful for building and testing tkinter with multiple - # versions of Tcl/Tk. Note that a build of Tk depends on a particular - # build of Tcl so you need to specify both arguments and use care when - # overriding. - - # The _TCLTK variables are created in the Makefile sharedmods target. - tcltk_includes = os.environ.get('_TCLTK_INCLUDES') - tcltk_libs = os.environ.get('_TCLTK_LIBS') - if not (tcltk_includes and tcltk_libs): - # Resume default configuration search. - return False - - extra_compile_args = tcltk_includes.split() - extra_link_args = tcltk_libs.split() - self.add(Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'], - define_macros=[('WITH_APPINIT', 1)], - extra_compile_args = extra_compile_args, - extra_link_args = extra_link_args)) - return True - - def detect_tkinter_darwin(self): - # Build default _tkinter on macOS using Tcl and Tk frameworks. - # This method is meant to be invoked by detect_tkinter(). - # - # The macOS native Tk (AKA Aqua Tk) and Tcl are most commonly - # built and installed as macOS framework bundles. However, - # for several reasons, we cannot take full advantage of the - # Apple-supplied compiler chain's -framework options here. - # Instead, we need to find and pass to the compiler the - # absolute paths of the Tcl and Tk headers files we want to use - # and the absolute path to the directory containing the Tcl - # and Tk frameworks for linking. - # - # We want to handle here two common use cases on macOS: - # 1. Build and link with system-wide third-party or user-built - # Tcl and Tk frameworks installed in /Library/Frameworks. - # 2. Build and link using a user-specified macOS SDK so that the - # built Python can be exported to other systems. In this case, - # search only the SDK's /Library/Frameworks (normally empty) - # and /System/Library/Frameworks. - # - # Any other use cases are handled either by detect_tkinter_fromenv(), - # or detect_tkinter(). The former handles non-standard locations of - # Tcl/Tk, defined via the _TCLTK_INCLUDES and _TCLTK_LIBS environment - # variables. The latter handles any Tcl/Tk versions installed in - # standard Unix directories. - # - # It would be desirable to also handle here the case where - # you want to build and link with a framework build of Tcl and Tk - # that is not in /Library/Frameworks, say, in your private - # $HOME/Library/Frameworks directory or elsewhere. It turns - # out to be difficult to make that work automatically here - # without bringing into play more tools and magic. That case - # can be handled using a recipe with the right arguments - # to detect_tkinter_fromenv(). - # - # Note also that the fallback case here is to try to use the - # Apple-supplied Tcl and Tk frameworks in /System/Library but - # be forewarned that they are deprecated by Apple and typically - # out-of-date and buggy; their use should be avoided if at - # all possible by installing a newer version of Tcl and Tk in - # /Library/Frameworks before building Python without - # an explicit SDK or by configuring build arguments explicitly. - - from os.path import join, exists - - sysroot = macosx_sdk_root() # path to the SDK or '/' - - if macosx_sdk_specified(): - # Use case #2: an SDK other than '/' was specified. - # Only search there. - framework_dirs = [ - join(sysroot, 'Library', 'Frameworks'), - join(sysroot, 'System', 'Library', 'Frameworks'), - ] - else: - # Use case #1: no explicit SDK selected. - # Search the local system-wide /Library/Frameworks, - # not the one in the default SDK, otherwise fall back to - # /System/Library/Frameworks whose header files may be in - # the default SDK or, on older systems, actually installed. - framework_dirs = [ - join('/', 'Library', 'Frameworks'), - join(sysroot, 'System', 'Library', 'Frameworks'), - ] - - # Find the directory that contains the Tcl.framework and - # Tk.framework bundles. - for F in framework_dirs: - # both Tcl.framework and Tk.framework should be present - for fw in 'Tcl', 'Tk': - if not exists(join(F, fw + '.framework')): - break - else: - # ok, F is now directory with both frameworks. Continue - # building - break - else: - # Tk and Tcl frameworks not found. Normal "unix" tkinter search - # will now resume. - return False - - include_dirs = [ - join(F, fw + '.framework', H) - for fw in ('Tcl', 'Tk') - for H in ('Headers',) - ] - - # Add the base framework directory as well - compile_args = ['-F', F] - - # Do not build tkinter for archs that this Tk was not built with. - cflags = sysconfig.get_config_vars('CFLAGS')[0] - archs = re.findall(r'-arch\s+(\w+)', cflags) - - tmpfile = os.path.join(self.build_temp, 'tk.arch') - if not os.path.exists(self.build_temp): - os.makedirs(self.build_temp) - - run_command( - "file {}/Tk.framework/Tk | grep 'for architecture' > {}".format(F, tmpfile) - ) - with open(tmpfile) as fp: - detected_archs = [] - for ln in fp: - a = ln.split()[-1] - if a in archs: - detected_archs.append(ln.split()[-1]) - os.unlink(tmpfile) - - arch_args = [] - for a in detected_archs: - arch_args.append('-arch') - arch_args.append(a) - - compile_args += arch_args - link_args = [','.join(['-Wl', '-F', F, '-framework', 'Tcl', '-framework', 'Tk']), *arch_args] - - # The X11/xlib.h file bundled in the Tk sources can cause function - # prototype warnings from the compiler. Since we cannot easily fix - # that, suppress the warnings here instead. - if '-Wstrict-prototypes' in cflags.split(): - compile_args.append('-Wno-strict-prototypes') - - self.add(Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'], - define_macros=[('WITH_APPINIT', 1)], - include_dirs=include_dirs, - libraries=[], - extra_compile_args=compile_args, - extra_link_args=link_args)) - return True - - def detect_tkinter(self): - # The _tkinter module. - # - # Detection of Tcl/Tk is attempted in the following order: - # - Through environment variables. - # - Platform specific detection of Tcl/Tk (currently only macOS). - # - Search of various standard Unix header/library paths. - # - # Detection stops at the first successful method. - - # Check for Tcl and Tk at the locations indicated by _TCLTK_INCLUDES - # and _TCLTK_LIBS environment variables. - if self.detect_tkinter_fromenv(): - return True - - # Rather than complicate the code below, detecting and building - # AquaTk is a separate method. Only one Tkinter will be built on - # Darwin - either AquaTk, if it is found, or X11 based Tk. - if (MACOS and self.detect_tkinter_darwin()): - return True - - # Assume we haven't found any of the libraries or include files - # The versions with dots are used on Unix, and the versions without - # dots on Windows, for detection by cygwin. - tcllib = tklib = tcl_includes = tk_includes = None - for version in ['8.6', '86', '8.5', '85', '8.4', '84', '8.3', '83', - '8.2', '82', '8.1', '81', '8.0', '80']: - tklib = self.compiler.find_library_file(self.lib_dirs, - 'tk' + version) - tcllib = self.compiler.find_library_file(self.lib_dirs, - 'tcl' + version) - if tklib and tcllib: - # Exit the loop when we've found the Tcl/Tk libraries - break - - # Now check for the header files - if tklib and tcllib: - # Check for the include files on Debian and {Free,Open}BSD, where - # they're put in /usr/include/{tcl,tk}X.Y - dotversion = version - if '.' not in dotversion and "bsd" in HOST_PLATFORM.lower(): - # OpenBSD and FreeBSD use Tcl/Tk library names like libtcl83.a, - # but the include subdirs are named like .../include/tcl8.3. - dotversion = dotversion[:-1] + '.' + dotversion[-1] - tcl_include_sub = [] - tk_include_sub = [] - for dir in self.inc_dirs: - tcl_include_sub += [dir + os.sep + "tcl" + dotversion] - tk_include_sub += [dir + os.sep + "tk" + dotversion] - tk_include_sub += tcl_include_sub - tcl_includes = find_file('tcl.h', self.inc_dirs, tcl_include_sub) - tk_includes = find_file('tk.h', self.inc_dirs, tk_include_sub) - - if (tcllib is None or tklib is None or - tcl_includes is None or tk_includes is None): - self.announce("INFO: Can't locate Tcl/Tk libs and/or headers", 2) - return False - - # OK... everything seems to be present for Tcl/Tk. - - include_dirs = [] - libs = [] - defs = [] - added_lib_dirs = [] - for dir in tcl_includes + tk_includes: - if dir not in include_dirs: - include_dirs.append(dir) - - # Check for various platform-specific directories - if HOST_PLATFORM == 'sunos5': - include_dirs.append('/usr/openwin/include') - added_lib_dirs.append('/usr/openwin/lib') - elif os.path.exists('/usr/X11R6/include'): - include_dirs.append('/usr/X11R6/include') - added_lib_dirs.append('/usr/X11R6/lib64') - added_lib_dirs.append('/usr/X11R6/lib') - elif os.path.exists('/usr/X11R5/include'): - include_dirs.append('/usr/X11R5/include') - added_lib_dirs.append('/usr/X11R5/lib') - else: - # Assume default location for X11 - include_dirs.append('/usr/X11/include') - added_lib_dirs.append('/usr/X11/lib') - - # If Cygwin, then verify that X is installed before proceeding - if CYGWIN: - x11_inc = find_file('X11/Xlib.h', [], include_dirs) - if x11_inc is None: - return False - - # Check for BLT extension - if self.compiler.find_library_file(self.lib_dirs + added_lib_dirs, - 'BLT8.0'): - defs.append( ('WITH_BLT', 1) ) - libs.append('BLT8.0') - elif self.compiler.find_library_file(self.lib_dirs + added_lib_dirs, - 'BLT'): - defs.append( ('WITH_BLT', 1) ) - libs.append('BLT') - - # Add the Tcl/Tk libraries - libs.append('tk'+ version) - libs.append('tcl'+ version) - - # Finally, link with the X11 libraries (not appropriate on cygwin) - if not CYGWIN: - libs.append('X11') - - # XXX handle these, but how to detect? - # *** Uncomment and edit for PIL (TkImaging) extension only: - # -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \ - # *** Uncomment and edit for TOGL extension only: - # -DWITH_TOGL togl.c \ - # *** Uncomment these for TOGL extension only: - # -lGL -lGLU -lXext -lXmu \ - - self.add(Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'], - define_macros=[('WITH_APPINIT', 1)] + defs, - include_dirs=include_dirs, - libraries=libs, - library_dirs=added_lib_dirs)) - return True - - def configure_ctypes(self, ext): - return True - - def detect_ctypes(self): - # Thomas Heller's _ctypes module - - if (not sysconfig.get_config_var("LIBFFI_INCLUDEDIR") and MACOS): - self.use_system_libffi = True - else: - self.use_system_libffi = '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS") - - include_dirs = [] - extra_compile_args = [] - extra_link_args = [] - sources = ['_ctypes/_ctypes.c', - '_ctypes/callbacks.c', - '_ctypes/callproc.c', - '_ctypes/stgdict.c', - '_ctypes/cfield.c'] - - if MACOS: - sources.append('_ctypes/malloc_closure.c') - extra_compile_args.append('-DUSING_MALLOC_CLOSURE_DOT_C=1') - extra_compile_args.append('-DMACOSX') - include_dirs.append('_ctypes/darwin') - - elif HOST_PLATFORM == 'sunos5': - # XXX This shouldn't be necessary; it appears that some - # of the assembler code is non-PIC (i.e. it has relocations - # when it shouldn't. The proper fix would be to rewrite - # the assembler code to be PIC. - # This only works with GCC; the Sun compiler likely refuses - # this option. If you want to compile ctypes with the Sun - # compiler, please research a proper solution, instead of - # finding some -z option for the Sun compiler. - extra_link_args.append('-mimpure-text') - - elif HOST_PLATFORM.startswith('hp-ux'): - extra_link_args.append('-fPIC') - - ext = Extension('_ctypes', - include_dirs=include_dirs, - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - libraries=[], - sources=sources) - self.add(ext) - # function my_sqrt() needs libm for sqrt() - self.addext(Extension('_ctypes_test', ['_ctypes/_ctypes_test.c'])) - - ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR") - ffi_lib = None - - ffi_inc_dirs = self.inc_dirs.copy() - if MACOS: - ffi_in_sdk = os.path.join(macosx_sdk_root(), "usr/include/ffi") - - if not ffi_inc: - if os.path.exists(ffi_in_sdk): - ext.extra_compile_args.append("-DUSING_APPLE_OS_LIBFFI=1") - ffi_inc = ffi_in_sdk - ffi_lib = 'ffi' - else: - # OS X 10.5 comes with libffi.dylib; the include files are - # in /usr/include/ffi - ffi_inc_dirs.append('/usr/include/ffi') - - if not ffi_inc: - found = find_file('ffi.h', [], ffi_inc_dirs) - if found: - ffi_inc = found[0] - if ffi_inc: - ffi_h = ffi_inc + '/ffi.h' - if not os.path.exists(ffi_h): - ffi_inc = None - print('Header file {} does not exist'.format(ffi_h)) - if ffi_lib is None and ffi_inc: - for lib_name in ('ffi', 'ffi_pic'): - if (self.compiler.find_library_file(self.lib_dirs, lib_name)): - ffi_lib = lib_name - break - - if ffi_inc and ffi_lib: - ffi_headers = glob(os.path.join(ffi_inc, '*.h')) - if grep_headers_for('ffi_prep_cif_var', ffi_headers): - ext.extra_compile_args.append("-DHAVE_FFI_PREP_CIF_VAR=1") - if grep_headers_for('ffi_prep_closure_loc', ffi_headers): - ext.extra_compile_args.append("-DHAVE_FFI_PREP_CLOSURE_LOC=1") - if grep_headers_for('ffi_closure_alloc', ffi_headers): - ext.extra_compile_args.append("-DHAVE_FFI_CLOSURE_ALLOC=1") - - ext.include_dirs.append(ffi_inc) - ext.libraries.append(ffi_lib) - self.use_system_libffi = True - - if sysconfig.get_config_var('HAVE_LIBDL'): - # for dlopen, see bpo-32647 - ext.libraries.append('dl') - - def detect_decimal(self): - # Stefan Krah's _decimal module - self.addext( - Extension( - '_decimal', - ['_decimal/_decimal.c'], - # Uncomment for extra functionality: - # define_macros=[('EXTRA_FUNCTIONALITY', 1)] - ) - ) - - def detect_openssl_hashlib(self): - # Detect SSL support for the socket module (via _ssl) - config_vars = sysconfig.get_config_vars() - - def split_var(name, sep): - # poor man's shlex, the re module is not available yet. - value = config_vars.get(name) - if not value: - return () - # This trick works because ax_check_openssl uses --libs-only-L, - # --libs-only-l, and --cflags-only-I. - value = ' ' + value - sep = ' ' + sep - return [v.strip() for v in value.split(sep) if v.strip()] - - openssl_includes = split_var('OPENSSL_INCLUDES', '-I') - openssl_libdirs = split_var('OPENSSL_LDFLAGS', '-L') - openssl_libs = split_var('OPENSSL_LIBS', '-l') - openssl_rpath = config_vars.get('OPENSSL_RPATH') - if not openssl_libs: - # libssl and libcrypto not found - self.missing.extend(['_ssl', '_hashlib']) - return None, None - - # Find OpenSSL includes - ssl_incs = find_file( - 'openssl/ssl.h', self.inc_dirs, openssl_includes - ) - if ssl_incs is None: - self.missing.extend(['_ssl', '_hashlib']) - return None, None - - if openssl_rpath == 'auto': - runtime_library_dirs = openssl_libdirs[:] - elif not openssl_rpath: - runtime_library_dirs = [] - else: - runtime_library_dirs = [openssl_rpath] - - openssl_extension_kwargs = dict( - include_dirs=openssl_includes, - library_dirs=openssl_libdirs, - libraries=openssl_libs, - runtime_library_dirs=runtime_library_dirs, - ) - - # This static linking is NOT OFFICIALLY SUPPORTED. - # Requires static OpenSSL build with position-independent code. Some - # features like DSO engines or external OSSL providers don't work. - # Only tested on GCC and clang on X86_64. - if os.environ.get("PY_UNSUPPORTED_OPENSSL_BUILD") == "static": - extra_linker_args = [] - for lib in openssl_extension_kwargs["libraries"]: - # link statically - extra_linker_args.append(f"-l:lib{lib}.a") - # don't export symbols - extra_linker_args.append(f"-Wl,--exclude-libs,lib{lib}.a") - openssl_extension_kwargs["extra_link_args"] = extra_linker_args - # don't link OpenSSL shared libraries. - # include libz for OpenSSL build flavors with compression support - openssl_extension_kwargs["libraries"] = ["z"] - - self.add( - Extension( - '_ssl', - ['_ssl.c'], - **openssl_extension_kwargs - ) - ) - self.add( - Extension( - '_hashlib', - ['_hashopenssl.c'], - **openssl_extension_kwargs, - ) - ) - - def detect_hash_builtins(self): - # By default we always compile these even when OpenSSL is available - # (issue #14693). It's harmless and the object code is tiny - # (40-50 KiB per module, only loaded when actually used). Modules can - # be disabled via the --with-builtin-hashlib-hashes configure flag. - - self.addext(Extension('_md5', ['md5module.c'])) - self.addext(Extension('_sha1', ['sha1module.c'])) - self.addext(Extension('_sha256', ['sha256module.c'])) - self.addext(Extension('_sha512', ['sha512module.c'])) - self.addext(Extension('_sha3', ['_sha3/sha3module.c'])) - self.addext(Extension('_blake2', - [ - '_blake2/blake2module.c', - '_blake2/blake2b_impl.c', - '_blake2/blake2s_impl.c' - ] - )) - - def detect_nis(self): - if MS_WINDOWS or CYGWIN or HOST_PLATFORM == 'qnx6': - self.missing.append('nis') - return - - libs = [] - library_dirs = [] - includes_dirs = [] - - # bpo-32521: glibc has deprecated Sun RPC for some time. Fedora 28 - # moved headers and libraries to libtirpc and libnsl. The headers - # are in tircp and nsl sub directories. - rpcsvc_inc = find_file( - 'rpcsvc/yp_prot.h', self.inc_dirs, - [os.path.join(inc_dir, 'nsl') for inc_dir in self.inc_dirs] - ) - rpc_inc = find_file( - 'rpc/rpc.h', self.inc_dirs, - [os.path.join(inc_dir, 'tirpc') for inc_dir in self.inc_dirs] - ) - if rpcsvc_inc is None or rpc_inc is None: - # not found - self.missing.append('nis') - return - includes_dirs.extend(rpcsvc_inc) - includes_dirs.extend(rpc_inc) - - if self.compiler.find_library_file(self.lib_dirs, 'nsl'): - libs.append('nsl') - else: - # libnsl-devel: check for libnsl in nsl/ subdirectory - nsl_dirs = [os.path.join(lib_dir, 'nsl') for lib_dir in self.lib_dirs] - libnsl = self.compiler.find_library_file(nsl_dirs, 'nsl') - if libnsl is not None: - library_dirs.append(os.path.dirname(libnsl)) - libs.append('nsl') - - if self.compiler.find_library_file(self.lib_dirs, 'tirpc'): - libs.append('tirpc') - - self.add(Extension('nis', ['nismodule.c'], - libraries=libs, - library_dirs=library_dirs, - include_dirs=includes_dirs)) - - -class PyBuildInstall(install): - # Suppress the warning about installation into the lib_dynload - # directory, which is not in sys.path when running Python during - # installation: - def initialize_options (self): - install.initialize_options(self) - self.warn_dir=0 - - # Customize subcommands to not install an egg-info file for Python - sub_commands = [('install_lib', install.has_lib), - ('install_headers', install.has_headers), - ('install_scripts', install.has_scripts), - ('install_data', install.has_data)] - - -class PyBuildInstallLib(install_lib): - # Do exactly what install_lib does but make sure correct access modes get - # set on installed directories and files. All installed files with get - # mode 644 unless they are a shared library in which case they will get - # mode 755. All installed directories will get mode 755. - - # this is works for EXT_SUFFIX too, which ends with SHLIB_SUFFIX - shlib_suffix = sysconfig.get_config_var("SHLIB_SUFFIX") - - def install(self): - outfiles = install_lib.install(self) - self.set_file_modes(outfiles, 0o644, 0o755) - self.set_dir_modes(self.install_dir, 0o755) - return outfiles - - def set_file_modes(self, files, defaultMode, sharedLibMode): - if not files: return - - for filename in files: - if os.path.islink(filename): continue - mode = defaultMode - if filename.endswith(self.shlib_suffix): mode = sharedLibMode - log.info("changing mode of %s to %o", filename, mode) - if not self.dry_run: os.chmod(filename, mode) - - def set_dir_modes(self, dirname, mode): - for dirpath, dirnames, fnames in os.walk(dirname): - if os.path.islink(dirpath): - continue - log.info("changing mode of %s to %o", dirpath, mode) - if not self.dry_run: os.chmod(dirpath, mode) - - -class PyBuildScripts(build_scripts): - def copy_scripts(self): - outfiles, updated_files = build_scripts.copy_scripts(self) - fullversion = '-{0[0]}.{0[1]}'.format(sys.version_info) - minoronly = '.{0[1]}'.format(sys.version_info) - newoutfiles = [] - newupdated_files = [] - for filename in outfiles: - if filename.endswith('2to3'): - newfilename = filename + fullversion - else: - newfilename = filename + minoronly - log.info(f'renaming {filename} to {newfilename}') - os.rename(filename, newfilename) - newoutfiles.append(newfilename) - if filename in updated_files: - newupdated_files.append(newfilename) - return newoutfiles, newupdated_files - - -def main(): - global LIST_MODULE_NAMES - - if "--list-module-names" in sys.argv: - LIST_MODULE_NAMES = True - sys.argv.remove("--list-module-names") - - set_compiler_flags('CFLAGS', 'PY_CFLAGS_NODIST') - set_compiler_flags('LDFLAGS', 'PY_LDFLAGS_NODIST') - - class DummyProcess: - """Hack for parallel build""" - ProcessPoolExecutor = None - - sys.modules['concurrent.futures.process'] = DummyProcess - validate_tzpath() - - # turn off warnings when deprecated modules are imported - import warnings - warnings.filterwarnings("ignore",category=DeprecationWarning) - setup(# PyPI Metadata (PEP 301) - name = "Python", - version = sys.version.split()[0], - url = "https://www.python.org/%d.%d" % sys.version_info[:2], - maintainer = "Guido van Rossum and the Python community", - maintainer_email = "python-dev@python.org", - description = "A high-level object-oriented programming language", - long_description = SUMMARY.strip(), - license = "PSF license", - classifiers = [x for x in CLASSIFIERS.split("\n") if x], - platforms = ["Many"], - - # Build info - cmdclass = {'build_ext': PyBuildExt, - 'build_scripts': PyBuildScripts, - 'install': PyBuildInstall, - 'install_lib': PyBuildInstallLib}, - # The struct module is defined here, because build_ext won't be - # called unless there's at least one extension module defined. - ext_modules=[Extension('_struct', ['_struct.c'])], - - # If you change the scripts installed here, you also need to - # check the PyBuildScripts command above, and change the links - # created by the bininstall target in Makefile.pre.in - scripts = ["Tools/scripts/pydoc3", "Tools/scripts/idle3", - "Tools/scripts/2to3"] - ) - -# --install-platlib -if __name__ == '__main__': - main()